0

メトリクス ファイルの形式がわずかに変更されたため、小さな Python スクリプトを変更する必要があります。私は Python をまったく知らないので、自分で修正するために正直な努力をしようとしました。変更は私には理にかなっていますが、どうやらスクリプトにはまだ 1 つの問題があるようです。それ以外の場合は、他のすべてが機能しています。スクリプトは次のようになります。

import sys
import datetime

##########################################################################

now = datetime.datetime.now();
logFile = now.strftime("%Y%m%d")+'.QE-Metric.log';

underlyingParse = True;
strParse = "UNDERLYING_TICK";
if (len(sys.argv) == 2):
    if sys.argv[1] == '2':
    strParse = "ORDER_SHOOT";
        underlyingParse = False;
elif (len(sys.argv) == 3):
    logFile = sys.argv[2];    
    if sys.argv[1] == '2':
    strParse = "ORDER_SHOOT";
        underlyingParse = False;
else:
    print 'Incorrect number of arguments. Usage: <exec> <mode (1) Underlying (2) OrderShoot> <FileName (optional)>'
    sys.exit()

##########################################################################

# Read the deployment file
FIput = open(logFile, 'r');
FOput = open('ParsedMetrics.txt', 'w');

##########################################################################

def ParseMetrics( file_lines ):

    ii = 0
    tokens = []; 
    for ii in range(len(file_lines)):

        line = file_lines[ii].strip()

        if (line.find(strParse) != -1):

             tokens = line.split(",");
             currentTime = float(tokens[2])

             if (underlyingParse == True and ii != 0):
                 newIndex = ii-1
                 prevLine = file_lines[newIndex].strip()
                 while (prevLine.find("ORDER_SHOOT") != -1 and newIndex > -1):
                     newIndex -= 1;
                     tokens = prevLine.split(",");
                     currentTime -= float(tokens[2]);
                     prevLine = file_lines[newIndex].strip();

         if currentTime > 0:
                 FOput.write(str(currentTime) + '\n')

##########################################################################

file_lines = FIput.readlines()
ParseMetrics( file_lines );

print 'Metrics parsed and written to ParsedMetrics.txt'

最後の UNDERLYING_TICK イベントが発生してから、前の行を逆に繰り返して ORDER_SHOOT の数値を合計するロジックを除いて、すべて正常に動作しています (コード: if (underlyingParse == True and ii != 0):.. .) 次に、現在処理中の UNDERLYING_TICK イベント行からその合計を引きます。解析中のファイルの典型的な行は次のようになります。

08:40:02.039387(+26): UNDERLYING_TICK, 1377, 1499.89

基本的に、マイクロ単位の時間である最後のデータ要素 (1499.89) にのみ関心があります。私はそれが愚かなものでなければならないことを知っています。もう一組の目が必要です。ありがとう!

4

2 に答える 2

0

したがって、コマンド ライン オプションが 2 の場合、関数は出力ファイルを作成します。この出力ファイルには、すべての行に「order_shoot」トークンが含まれる入力ファイルの行の「時間」部分のみが含まれています。

コマンド ライン オプションが 1 の場合、関数は、'underlying_tick' トークンを含む入力ファイルの各行を含む出力ファイルを作成します。先行するunderlying_tick値から(またはこれが最初のものである場合はファイルの先頭から)発生しましたか?

これが正しく、すべての行が一意である (重複がない) 場合は、次のスクリプトを書き直すことをお勧めします。

#### Imports unchanged.

import sys 
import datetime 

#### Changing the error checking to be a little simpler.
#### If the number of args is wrong, or the "mode" arg is
#### not a valid option, it will print the error message
#### and exit.

if len(sys.argv) not in (2,3) or sys.argv[2] not in (1,2):
    print 'Incorrect arguments. Usage: <exec> <mode (1) Underlying (2) OrderShoot> <FileName (optional)>'
    sys.exit()  

#### the default previously specified in the original code.

now = datetime.datetime.now()

#### Using ternary logic to set the input file to either
#### the files specified in argv[2] (if it exists), or to
#### the default previously specified in the original code.

FIput = open((sys.argv[2] if len(sys.argv)==3 
                          else now.strftime("%Y%m%d")+'.QE-Metric.log'), 'r');

#### Output file not changed.

FOput = open('ParsedMetrics.txt', 'w');

#### START RE-WRITTEN FUNCTION

def ParseMetrics(file_lines,mode): 

#### The function now takes two params - the lines from the 
#### input file, and the 'mode' - whichever the user selected
#### at run-time. As you can see from the call down below, this
#### is taken straight from argv[1]. 

    if mode == '1':

#### So if we're doing underlying_tick mode, we want to find each tick,
#### then for each tick, sum the preceding order_shoots since the last
#### tick (or start of file for the first tick).

        ticks = [file_lines.index(line) for line in file_lines \
                                        if 'UNDERLYING_TICK' in line]

#### The above list comprehension iterates over file_lines, and creates
#### a list of the indexes to file_lines elements that contain ticks.
#### 
#### Then the following loop iterates over ticks, and for each tick,
#### subtracts the sum of all times for order_shoots that occure prior
#### to the tick, from the time value of the tick itself. Then that
#### value is written to the outfile.

        for tick in ticks:
            sub_time = float(file_lines[tick].split(",")[2]) - \
                       sum([float(line.split(",")[2]) \ 
                       for line in file_lines if "ORDER_SHOOT" in line \
                       and file_lines.index(line) <= tick]
            FOput.write(float(line.split(",")[2]))    

#### if the mode is 2, then it just runs through file_lines and
#### outputs all of the order_shoot time values.

    if mode == '2':
        for line in file_lines:
            if 'ORDER_SHOOT' in line:
                FOput.write(float(line.split(",")[2]))

#### END OF REWRITTEN FUNCTION

#### As you can see immediately below, we pass sys.argv[2] for the
#### mode argument of the ParseMetrics function.

ParseMetrics(FIput.readlines(),sys.argv[2])

print 'Metrics parsed and written to ParsedMetrics.txt' 

そして、それはうまくいくはずです。主な問題は、「UNDERLYING_TICK」を含む行が他のそのような行とまったく同じである場合、これは機能しないことです。正しいインデックスを取得するには、別のロジックを適用する必要があります。

これをもっと良くする方法があると確信していますが、これが私の最初の考えでした。

読みやすくするために、上記のソースに多くのインライン改行を追加したことも注目に値しますが、これをそのまま使用する場合は、それらを引っ張ることができます。

于 2012-07-16T17:02:35.510 に答える
0

出力が表示されておらず、入力を実際に理解できないため、出力の何が問題なのかは不明です。

私は次のことを想定しています:

  1. 行は「absolutetime: TYPE, positiveinteger, float_time_duration_in_ms」としてフォーマットされます。この最後の項目は、処理にかかった時間です。
  2. 行は「絶対時間」でソートされます。結果として、UNDERLYING_TICK に属する ORDER_SHOOT は常に、最後の UNDERLYING_TICK (またはファイルの先頭) 以降の行にあり、それらの行のみです。この仮定が当てはまらない場合は、最初にファイルをソートする必要があります。別のプログラム (例: からのパイプ出力sort) でそれを行うか、bisectモジュールを使用してソートされた行を保存し、関連する行を簡単に抽出することができます。

これらの仮定が両方とも当てはまる場合は、代わりに次のスクリプトを見てください。(比較する大きな入力サンプルまたは出力サンプルがないため、テストされていません。)

これははるかに Python スタイルであり、読みやすく理解しやすく、関数パラメーターとしてグローバル変数を使用しません。それを解析します。

また、コマンド ライン解析のためのargparseモジュールの使用方法も示します。これは必須ではありませんが、コマンドライン Python スクリプトが多数ある場合は、それに慣れておく必要があります。

import sys

VALIDTYPES = ['UNDERLYING_TICK','ORDER_SHOOT']

def parseLine(line):
    # format of `tokens`:
    # 0 = absolute timestamp
    # 1 = event type
    # 2 = ???
    # 3 = timedelta (microseconds)
    tokens = [t.strip(':, \t') for t in line.strip().split()]
    if tokens[1] not in VALIDTYPES:
        return None
    tokens[2] = int(tokens[2])
    tokens[3] = float(tokens[3])
    return tuple(tokens)

def parseMetrics(lines, parsetype):
    """Yield timedelta for each line of specified type

    If parsetype is 'UNDERLYING_TICK', subtract previous ORDER_SHOOT 
    timedeltas from the current UNDERLYING_TICK delta before yielding
    """
    order_shoots_between_ticks = []
    for line in lines:
        tokens = parseLine(line)
        if tokens is None:
            continue # go home early
        if parsetype=='UNDERLYING_TICK':
            if tokens[1]=='ORDER_SHOOT':
                order_shoots_between_ticks.append(tokens)
            elif tokens[1]=='UNDERLYING_TICK':
                adjustedtick = tokens[3] - sum(t[3] for t in order_shoots_between_ticks)
                order_shoots_between_ticks = []
                yield adjustedtick
        elif parsetype==tokens[1]:
            yield tokens[3]

def parseFile(instream, outstream, parsetype):
    printablelines = ("{0:f}\n".format(time) for time in parseMetrics(instream, parsetype))
    outstream.writelines(printablelines)

def main(argv):
    import argparse, datetime
    parser = argparse.ArgumentParser(description='Output timedeltas from a QE-Metric log file')
    parser.add_argument('mode', type=int, choices=range(1, len(VALIDTYPES)+1),
        help="the types to parse. Valid values are: 1 (Underlying), 2 (OrderShoot)")
    parser.add_argument('infile', required=False,
        default='{}.QE-Metric.log'.format(datetime.datetime.now().strftime('%Y%m%d'))
        help="the input file. Defaults to today's file: YYYYMMDD.QE-Metric.log. Use - for stdin.")
    parser.add_argument('outfile', required=False,
        default='ParsedMetrics.txt',
        help="the output file. Defaults to ParsedMetrics.txt. Use - for stdout.")
    parser.add_argument('--verbose', '-v', action='store_true')
    args = parser.parse_args(argv)

    args.mode = VALIDTYPES[args.mode-1]

    if args.infile=='-':
        instream = sys.stdin
    else:
        instream = open(args.infile, 'rb')

    if args.outfile=='-':
        outstream = sys.stdout
    else:
        outstream = open(args.outfile, 'wb')

    parseFile(instream, outstream, args.mode)

    instream.close()
    outstream.close()

    if args.verbose:
        sys.stderr.write('Metrics parsed and written to {0}\n'.format(args.outfile))



if __name__=='__main__':
    main(sys.argv[1:])
于 2012-07-16T16:37:38.363 に答える