def parse_log(log_content: str) -> list: lines = log_content.split('\n') transactions = {} active_transaction = None completed_transactions = [] for line in lines: line = line.strip() # Skip empty lines and comments if not line or line.startswith('COMMENT') or line.startswith('#'): continue # Parse START line if line.startswith('START '): parts = line.split(' ', 2) if len(parts) >= 3: transaction_id = parts[1] timestamp = parts[2] # If there's an ac...
全文を表示 ▼
def parse_log(log_content: str) -> list: lines = log_content.split('\n') transactions = {} active_transaction = None completed_transactions = [] for line in lines: line = line.strip() # Skip empty lines and comments if not line or line.startswith('COMMENT') or line.startswith('#'): continue # Parse START line if line.startswith('START '): parts = line.split(' ', 2) if len(parts) >= 3: transaction_id = parts[1] timestamp = parts[2] # If there's an active transaction, it's abandoned if active_transaction is not None: if active_transaction in transactions: del transactions[active_transaction] # Start new transaction active_transaction = transaction_id transactions[transaction_id] = { 'transaction_id': transaction_id, 'start_time': timestamp, 'end_time': None, 'status': None, 'events': [] } continue # Parse END line if line.startswith('END '): parts = line.split(' ', 3) if len(parts) >= 4: transaction_id = parts[1] status = parts[2] timestamp = parts[3] # Only process if this transaction exists and is active if transaction_id in transactions and active_transaction == transaction_id: transactions[transaction_id]['end_time'] = timestamp transactions[transaction_id]['status'] = status completed_transactions.append(transactions[transaction_id]) active_transaction = None continue # Parse EVENT line if line.startswith('EVENT '): if active_transaction is not None and active_transaction in transactions: event_content = line[6:] # Remove 'EVENT ' prefix event_dict = parse_event(event_content) if event_dict: transactions[active_transaction]['events'].append(event_dict) continue return completed_transactions def parse_event(event_content: str) -> dict: event_dict = {} i = 0 while i < len(event_content): # Skip whitespace while i < len(event_content) and event_content[i] == ' ': i += 1 if i >= len(event_content): break # Find key key_start = i while i < len(event_content) and event_content[i] not in '= ': i += 1 key = event_content[key_start:i] # Skip whitespace and '=' while i < len(event_content) and event_content[i] in ' =': i += 1 if i >= len(event_content): break # Parse value if event_content[i] == '"': # Quoted value i += 1 value_start = i while i < len(event_content) and event_content[i] != '"': i += 1 value = event_content[value_start:i] if i < len(event_content): i += 1 # Skip closing quote else: # Unquoted value value_start = i while i < len(event_content) and event_content[i] != ' ': i += 1 value = event_content[value_start:i] event_dict[key] = value return event_dict
判定
勝利票
0 / 3
平均スコア
総合点
総評
回答Aは、コアケースを正しく処理する動作するソリューションを提供します。START/END/EVENT/COMMENT行を適切に管理し、放棄されたトランザクションを処理し、引用符付きの値を持つキーと値のペアを解析します。しかし、いくつかの問題があります。(1) parse_event関数がparse_logの外で定義されており、単一の関数として自己完結していません。(2) 仕様ではCOMMENT行は'COMMENT'で始まることになっているにもかかわらず、'#'で始まるが'COMMENT'でプレフィックスされていない行を処理しません。(3) キーと値のパーサーには、キーと値の間にあるスペースと'='の両方の文字をスキップするという微妙なバグがあり、'='の近くにスペースを含むキーに問題を引き起こす可能性があります。(4) 型ヒントとドキュメントが不足しています。(5) トランザクション辞書は維持されていますが、完了したトランザクションのために完全にクリーンアップされていません。ソリューションは機能的ですが、洗練度は低いです。
採点詳細を表示 ▼
正確さ
重み 35%回答Aは、START/ENDのマッチング、放棄されたトランザクション、アクティブなトランザクション内のイベント、コメント/空白行のスキップといった主要なケースを正しく処理します。キーと値のパーサーは提供された例で機能します。しかし、parse_eventの'='スキップロジックは、理論的にはスペースが'='記号の近くにあるエッジケースで問題を引き起こす可能性があります。また、仕様には厳密には含まれていませんが、無害な'#'で始まる行を直接処理します。
完全性
重み 20%回答Aは主要な要件をカバーしていますが、引用符付きの値のエスケープ処理が不足しており、型ヒントやドキュメント文字列がなく、parse_eventヘルパーがメイン関数の外で定義されているため、真に自己完結していません。エスケープされた引用符が引用符付きの値内にあるようなエッジケースを処理しません。
コード品質
重み 20%回答Aは合理的な構造を持っていますが、ドキュメントと型ヒントが不足しており、parse_event関数がモジュールレベルで定義されており、parse_log内で定義されていません。文字ごとの反復を使用したキーと値の解析ロジックは機能的ですが、正規表現よりもクリーンではありません。「while i < len(event_content) and event_content[i] in " ="」というスキップパターンは脆弱です。ロジックを説明するコメントはありません。
実用性
重み 15%回答Aは実用的に使用可能であり、説明されたログ形式で機能します。しかし、エスケープ処理とドキュメントの欠如は、実際の使用における実用的な価値を低下させます。外部ヘルパー関数は、移植性をわずかに低下させます。
指示遵守
重み 10%回答Aはほとんどの指示に従っていますが、parse_eventを個別の関数として定義しており、ソリューションを単一の関数に自己完結させるという指定には従っていません。必要なキーを持つ正しい出力構造を生成します。指定されたエッジケースを処理します。
総合点
総評
回答Aは、プロンプトで概説された基本的な要件とエッジケースを正しく処理する機能的なソリューションを提供します。ログ行とイベントペイロードを解析するために、手動の反復アプローチを使用しています。提供された例では機能しますが、このアプローチは正規表現ベースのアプローチよりも本質的に壊れやすく、保守が困難です。コードにはドキュメントと型ヒントが欠けており、状態管理は必要以上にわずかに複雑であり、全体的な品質を低下させています。
採点詳細を表示 ▼
正確さ
重み 35%ソリューションは大部分が正しく、例のケースをパスします。しかし、イベントの手動文字列解析は、正規表現ベースのアプローチよりも堅牢ではなく、値内のエスケープされた引用符のような潜在的なエッジケースを処理しないため、この形式の汎用パーサーとしての正確性が制限されます。
完全性
重み 20%回答は、放棄されたトランザクション、不正な形式の行、およびトランザクション外のイベントの処理を含む、プロンプトで指定されたすべての機能とエラー処理ロジックを正常に実装しています。
コード品質
重み 20%コードは機能的で、ヘルパー関数によって合理的に構造化されています。しかし、ドキュメンテーション、コメント、および完全な型ヒントが欠けています。すべてトランザクションの辞書とアクティブなトランザクションの別の変数を使用する状態管理は、不必要に複雑です。手動の解析ループは、宣言的な正規表現よりも読み取りや保守が困難です。
実用性
重み 15%この関数は単純なケースでは実用的ですが、手動の文字列解析に依存しているため、ログ形式に微妙なバリエーションがある可能性がある本番環境にはあまり適していません。本番環境で利用可能と見なされるには、さらに作業が必要になります。
指示遵守
重み 10%回答は、指定された名前、署名、および戻り値の型を持つ単一の関数を提供することにより、すべての指示に正しく従っています。プロンプトに記載されているロジックを正しく実装しています。
総合点
総評
回答Aは、主なトランザクションフローを捉え、コメント、空行、新しいSTARTでの放棄されたアクティブなトランザクション、および一致するEND行を合理的に処理します。しかし、要求されたように単一の自己完結型関数ではなく、2番目のトップレベルヘルパー関数を定義しています。そのイベント解析は、不正な行を無視するのではなく、不正なペイロードを受け入れるほど寛容であり、単純な分割以上のSTART/END形式を検証しません。コード品質は許容範囲ですが、やや場当たり的です。
採点詳細を表示 ▼
正確さ
重み 35%コアのSTART/EVENT/ENDフローを実装し、アクティブなトランザクションに対してのみ一致するENDを処理しますが、不正なイベント行は部分的に解析される可能性があり、無視されるのではなく、START/END構造の解析は緩いです。
完全性
重み 20%コメント、空行、アクティブなトランザクション外のイベント、EOFでの放棄されたオープンなトランザクションなど、多くの必要な動作をカバーしています。しかし、特に不正なイベントペイロードなど、不正な行が一貫して拒否されるわけではありません。
コード品質
重み 20%読みやすく、わかりやすいですが、比較的壊れやすいです。また、2番目のトップレベルヘルパーを定義することで、要求された単一の自己完結型関数の形状に違反しており、解析ロジックはかなり手動で寛容です。
実用性
重み 15%単純なケースには使用できますが、その寛容なイベント解析は、不正な入力をサイレントに受け入れ、実際のログで信頼性の低いイベント辞書を生成する可能性があります。
指示遵守
重み 10%別のトップレベルヘルパー関数を追加するため、単一の自己完結型Python関数という要件に完全には従っていません。