{
  "assessmentTests": {
    "python_test": {
      "name": "Pythonテスト",
      "desc": "構文、関数、データ構造、オブジェクトの動作に関する30の実践的な問題——Pythonの実スキルが、求人票にいう「Python習熟度」と一致しているかを判定します。",
      "recommendation": "あなたのPythonスキルプロフィール",
      "results": {
        "beginner": {
          "name": "初級者",
          "desc": "短いスクリプトを読むことはでき、その中の値を変更できますが、あなたが外した問題は、一般的なロジックというより、Pythonの言語仕様そのものの振る舞いに集中しています——デフォルト引数が一度だけ作られて再利用される、is と == が等しく見えるリストで異なる結果を返す、関数内のどこかで代入した瞬間に変数がローカルになる。これらは「プログラミングが下手」という話ではなく、Pythonに特有のルールで、他言語から来た人がビギナーと同じくらい引っかかるものです。仕事で重要なのは、一見正しく見えるコードの中で、こうしたルールがバグの隠れ場所になるからです。",
          "recommendation": "3つのテーマから始めましょう、この順で。ミュータブルなデフォルト引数（なぜ basket=[] が危険か）、is と == の違い、関数内の変数スコープの動き方。Python公式チュートリアル（docs.python.org）は3つすべてを直接カバーしており、「Python gotchas」という検索用語は実例を大量に出します。"
        },
        "intermediate": {
          "name": "中級者",
          "desc": "日常のスクリプティングは快適にこなします——データ構造、制御フロー、ごく普通の関数——既存コードベースの保守作業や小さい機能追加に足を引っ張られることもありません。ここから上級への差は、主としてPythonの便利機能が相互作用する場面です：シャローコピーが入れ子のデータを共有したままにしてしまう、ジェネレータの戻り値が無言で出力に含まれない、デコレータのスタック順が逆になる。こういったバグは、シニアレビュアーなら10秒で見つけますが、その他の人は1時間かけて追うことになります。",
          "recommendation": "オブジェクトとイテレーション内部に焦点を当てましょう：シャローコピー vs ディープコピー、ジェネレータが return で実際に何をしているか、デコレータのスタック順がどう働くか。それから多くのチュートリアルがスキップするクラスの基本——__eq__ なしのデフォルト等値判定、ミュータブルなクラス属性がすべてのインスタンスで共有されるわけ。"
        },
        "advanced": {
          "name": "上級者",
          "desc": "ほぼ全ての求人票が「Pythonが得意」とはこのレベルを指しています。あなたは探さなくても適切な道具を手に取り、どの状態が共有されて変わったのかだけでなく、なぜ変わったのかもわかります。誰かのコードを読んで、その出力を正確に予測できる。このランクと最上位を分ける要素は、仕事の守備面です：2つの正しく見える方法のうち、クラス属性、キーワード限定引数、例外階層に関わる場面でどちらが暴走するかを知ること。",
          "recommendation": "複数人が触れるコードベースを守る側面に進みましょう：キーワード限定引数を構文の奇妙さではなくAPI設計の選択として、例外階層（そのため except 句が唯一のクラスだけでなく、正しいエラーの一族をキャッチする）、コンテキストマネージャーをクリーンアップを保証する標準方法として。Real Python の深掘り記事は3つすべてで次のステップに最適です。"
        },
        "expert": {
          "name": "エキスパート",
          "desc": "あなたはすべてのセクション——コア構文、関数とスコープ、データ構造、オブジェクト指向イディオム——で最高点を取りました。実務上、それは他者のファイルを渡されて、構文が言うべき出力だけでなく、なぜその出力が産まれるのかを説明できるということ。これはより難しく、より価値ある技能です。このレベルでは、生のPythonが仕事の制限になることはほぼありません。制限は通常、コードの周囲にあるシステムの大きさや形です。",
          "recommendation": "リターンは今、ツール化とレビューの側にあります：mypy や pyright による静的型チェック、推測ではなくプロファイリングしてから最適化、他者のプルリクエストをこのカテゴリのバグ——すべてのテストに通り、特定の入力の下でもなお間違った動作をするもの——で読む。スクリーニングロールを受ける場合は、言語機能を名前で列挙するのではなく、こうしたバグを見つけた具体例を説明してください。それは言い回しではなく、推論の力を示します。"
        }
      },
      "questions": [
        {
          "question": "def add_item(item, basket=[]): basket.append(item); return basket と定義して、add_item('a') と add_item('b') を順に呼び出し、どちらも basket 引数を与えないとします。2番目の呼び出しは何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "['b'] ——毎回呼び出すたびデフォルトから新しい空リストが得られる"
            },
            {
              "icon": "",
              "label": "TypeError ——basket 引数を与えなければならない"
            },
            {
              "icon": "",
              "label": "['a', 'b'] ——デフォルトリストは一度作られて呼び出し間で再利用される"
            },
            {
              "icon": "",
              "label": "['a'] のあと ['b'] として、2つの独立した1要素リスト"
            }
          ]
        },
        {
          "question": "a = [1, 2, 3] と b = [1, 2, 3] があります。a == b は何を返し、a is b は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "両方 True ——同じリストは常に同一のオブジェクト"
            },
            {
              "icon": "",
              "label": "== で True、is で False ——内容は等しいが、メモリ上は別のオブジェクト"
            },
            {
              "icon": "",
              "label": "両方 False ——個別のリテラルが Python で等しくなることはない"
            },
            {
              "icon": "",
              "label": "is で True、== で False ——is はリストの値の等値性をチェック"
            }
          ]
        },
        {
          "question": "Python 3 で、7 / 2 は何に評価され、7 // 2 は何に評価されますか？",
          "options": [
            {
              "icon": "",
              "label": "3.5、そして 3 ——/ は常に浮動小数点数を返し、// は結果をフロア処理"
            },
            {
              "icon": "",
              "label": "3、そして 3.5 ——/ は切り捨てて、// は浮動小数点数を返す"
            },
            {
              "icon": "",
              "label": "3.5、そして 3.5 ——両演算子ともPython 3で浮動小数点数を返す"
            },
            {
              "icon": "",
              "label": "3、そして 3 ——両演算子ともPython 3でフロア処理"
            }
          ]
        },
        {
          "question": "s = 'hello' のあと s[0] = 'H' を実行したらどうなりますか？",
          "options": [
            {
              "icon": "",
              "label": "s は 'Hello' になる"
            },
            {
              "icon": "",
              "label": "s は 'Hhello' になる。置換でなく、文字が挿入されるから"
            },
            {
              "icon": "",
              "label": "TypeError ——文字列はイミュータブルで、項目割り当てをサポートしない"
            },
            {
              "icon": "",
              "label": "何もしない——割り当ては無言で無視され、s は 'hello' のまま"
            }
          ]
        },
        {
          "question": "x = [10, 20, 30, 40, 50] のとき、x[1:4] は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "[20, 30, 40, 50]"
            },
            {
              "icon": "",
              "label": "[10, 20, 30, 40]"
            },
            {
              "icon": "",
              "label": "[20, 30, 40]"
            },
            {
              "icon": "",
              "label": "[30, 40]"
            }
          ]
        },
        {
          "question": "name = 'Ana' と age = 30 があります。f'{name} is {age}' は何を作出しますか？",
          "options": [
            {
              "icon": "",
              "label": "{name} is {age}"
            },
            {
              "icon": "",
              "label": "Ana is 30"
            },
            {
              "icon": "",
              "label": "name is age"
            },
            {
              "icon": "",
              "label": "TypeError、f文字列は format() メソッドが必要だから"
            }
          ]
        },
        {
          "question": "1 < 2 < 3 は何に評価されますか？",
          "options": [
            {
              "icon": "",
              "label": "True ——Pythonは比較を (1 < 2) and (2 < 3) として繋ぐ"
            },
            {
              "icon": "",
              "label": "False ——繋がれた比較は左から右へ短絡なく評価され、1 < 2 < 3 -> 1 < True -> False になる"
            },
            {
              "icon": "",
              "label": "SyntaxError ——比較は繋げない"
            },
            {
              "icon": "",
              "label": "3 ——Pythonは繋ぎの最後の値を返す"
            }
          ]
        },
        {
          "question": "bool([]) は何を返し、bool([0]) は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "False、そして False ——偽性値を含むだけのリストはいずれも偽"
            },
            {
              "icon": "",
              "label": "False、そして True ——空リストは偽、1要素を含むリスト（0でも）は真"
            },
            {
              "icon": "",
              "label": "True、そして True ——None 以外のオブジェクトはいつも真"
            },
            {
              "icon": "",
              "label": "True、そして False ——リストは空の時だけ真"
            }
          ]
        },
        {
          "question": "モジュールレベルに count = 0 があります。def increment() の中で count += 1; return count として、increment() を呼び出したらどうなりますか？",
          "options": [
            {
              "icon": "",
              "label": "UnboundLocalError ——関数のどこでも count に代入すれば、ローカル化し、count += 1 は割り当て前のローカル変数を読もうとする"
            },
            {
              "icon": "",
              "label": "1を返し、モジュールレベルの count を1に増やす"
            },
            {
              "icon": "",
              "label": "1を返すが、モジュールレベルの count は0のまま"
            },
            {
              "icon": "",
              "label": "NameError が起き、count が関数内で宣言されなかったから"
            }
          ]
        },
        {
          "question": "def f(*args, **kwargs): return args, kwargs と定義します。f(1, 2, x=3) は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "([1, 2], {'x': 3})"
            },
            {
              "icon": "",
              "label": "((1, 2), {'x': 3})"
            },
            {
              "icon": "",
              "label": "(1, 2, {'x': 3})"
            },
            {
              "icon": "",
              "label": "TypeError ——位置引数とキーワード引数は1つの呼び出しで混ぜられない"
            }
          ]
        },
        {
          "question": "funcs = [lambda: i for i in range(3)] をループで作ります。[f() for f in funcs] は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "[2, 2, 2] ——各ラムダは呼ばれた時に i を見て、そのときループは i が2の状態で終わっている"
            },
            {
              "icon": "",
              "label": "[0, 1, 2] ——各ラムダはそれが作られたときの i の値をキャプチャ"
            },
            {
              "icon": "",
              "label": "[0, 0, 0] ——ラムダは常に最初に代入された変数の値をキャプチャ"
            },
            {
              "icon": "",
              "label": "NameError、ループが終わればもう i は存在しないから"
            }
          ]
        },
        {
          "question": "@a が @b の直上に、@b が def f(): pass の直上にあります。デコレータは f に何の順で適用されますか？",
          "options": [
            {
              "icon": "",
              "label": "b がまず f をラップ、次に a が b の結果をラップ——関数に最も近いデコレータが最初に走る"
            },
            {
              "icon": "",
              "label": "a がまず f をラップ、次に b が結果をラップ——デコレータは上から下へ適用"
            },
            {
              "icon": "",
              "label": "両デコレータが f を独立してラップし、最後に定義されたのだけが効く"
            },
            {
              "icon": "",
              "label": "デコレータがコードで何位にあるかではなく、どう import されたかで決まる"
            }
          ]
        },
        {
          "question": "def f(a, *, b): return a + b と定義します。これらの呼び出しのうち、どれが動きますか？",
          "options": [
            {
              "icon": "",
              "label": "f(1, b=2) ——b はシグネチャの bare * の後ろだからキーワードで与えなければならない"
            },
            {
              "icon": "",
              "label": "f(1, 2) ——位置引数は * にかかわらず左から右へパラメータを埋める"
            },
            {
              "icon": "",
              "label": "f(a=1, 2) ——キーワード引数は最初に来ねばならない"
            },
            {
              "icon": "",
              "label": "f(1) ——b は * の後ろだからオプション"
            }
          ]
        },
        {
          "question": "ジェネレータ関数が1を yield、2を yield、そして return 99 をする。list(the_generator()) は何を含み、99はどうなりますか？",
          "options": [
            {
              "icon": "",
              "label": "[1, 2, 99] ——ジェネレータ内の return は、もう1つの yield のように振る舞う"
            },
            {
              "icon": "",
              "label": "[99] ——return は既に yield された値を直ちに上書き"
            },
            {
              "icon": "",
              "label": "[1, 2] ——ジェネレータの戻り値は、それが raise する StopIteration に付属の値になり、yield されない"
            },
            {
              "icon": "",
              "label": "RuntimeError、ジェネレータは return 文を含めない"
            }
          ]
        },
        {
          "question": "外部関数 outer() で、x = 1 が設定され、入れ子の inner() が nonlocal x; x += 1 を実行し、outer() が inner() を呼ぶ前に x を返す。outer() は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "1 ——inner() は x のローカルコピーで動き、変更は保持されない"
            },
            {
              "icon": "",
              "label": "UnboundLocalError、x は inner() の nonlocal 文の前に宣言されない"
            },
            {
              "icon": "",
              "label": "SyntaxError ——nonlocal はクラスの中だけで使える"
            },
            {
              "icon": "",
              "label": "2 ——nonlocal は inner() が外部関数の x を修正して、新しいローカル変数を作らない"
            }
          ]
        },
        {
          "question": "d = {'a': 1, 'b': 2} があります。d.get('c', 0) は何を返し、'c' を辞書に加えますか？",
          "options": [
            {
              "icon": "",
              "label": "0、加えない ——get() はデフォルトを返すが、キーを挿入しない"
            },
            {
              "icon": "",
              "label": "0、加える ——get() はキーをデフォルト値で挿入"
            },
            {
              "icon": "",
              "label": "KeyError、'c' が存在しないから"
            },
            {
              "icon": "",
              "label": "None、そして yes ——get() はいつも無いキーを None 値で加える"
            }
          ]
        },
        {
          "question": "t = (1, 2, [3, 4]) があります。t[2].append(5) を実行でき、t[0] = 10 を実行できますか？",
          "options": [
            {
              "icon": "",
              "label": "どちらも動く ——リストをタプル内に入れ子にすれば、タプル全体がミュータブルになる"
            },
            {
              "icon": "",
              "label": "どちらも TypeError ——タプルの中の何も変更できない"
            },
            {
              "icon": "",
              "label": "t[2].append(5) は TypeError、t[0] = 10 は動く。タプルは最初の要素の再割り当てを許す"
            },
            {
              "icon": "",
              "label": "t[2].append(5) は動く。リスト内はミュータブル。t[0] = 10 は TypeError、タプル自体がイミュータブル"
            }
          ]
        },
        {
          "question": "メモリ全体を一度に構築する代わりに値を遅延計算するイテレータを返すのは：[x*x for x in range(1000000)] または (x*x for x in range(1000000)) のどちらですか？",
          "options": [
            {
              "icon": "",
              "label": "括弧のある方 (x*x for x in range(1000000)) ——これがジェネレータ式"
            },
            {
              "icon": "",
              "label": "角括弧の方 ——リスト内包表記はPython 3で常に遅延評価"
            },
            {
              "icon": "",
              "label": "どちらも遅延評価 ——唯一の違いは最後に返される型"
            },
            {
              "icon": "",
              "label": "どちらも違う ——両方ともメモリ内に全シーケンスを直ちに構築"
            }
          ]
        },
        {
          "question": "try ブロックがゼロで除算し、except ZeroDivisionError 句が『a』を出力し、finally 句が『b』を出力する。何が出力され、何の順ですか？",
          "options": [
            {
              "icon": "",
              "label": "b のあと a ——finally は常に except 句の前に走る"
            },
            {
              "icon": "",
              "label": "a のあと b ——マッチする except が最初に走り、finally は常にそのあと走る"
            },
            {
              "icon": "",
              "label": "b だけ ——例外は実際にはキャッチされず、『a』は出力されない"
            },
            {
              "icon": "",
              "label": "a だけ ——例外が既に処理されれば、finally はスキップ"
            }
          ]
        },
        {
          "question": "import copy; a = [[1, 2], [3, 4]]; b = copy.copy(a); b[0].append(99) とします。a[0] も変わりますか？",
          "options": [
            {
              "icon": "",
              "label": "いいえ ——copy.copy() は常に入れ子のオブジェクトも複製"
            },
            {
              "icon": "",
              "label": "いいえ ——b[0] に append すれば、b[0] だけのため新しいリストが作られる"
            },
            {
              "icon": "",
              "label": "はい、ただし copy.copy() を deepcopy 引数なしで呼んだから"
            },
            {
              "icon": "",
              "label": "はい ——copy.copy() はシャローコピーを作るので、入れ子のリストは a と b で共有される"
            }
          ]
        },
        {
          "question": "d = {'x': 1, 'y': 2} があります。'x' in d はキー、値、それとも両方に対してチェックしますか？",
          "options": [
            {
              "icon": "",
              "label": "値 ——`in` は1か2が 'x' と等しいかチェック"
            },
            {
              "icon": "",
              "label": "キーと値の両方をチェック"
            },
            {
              "icon": "",
              "label": "どちらも ——辞書に対する `in` は常に TypeError"
            },
            {
              "icon": "",
              "label": "キー ——辞書に対する `in` はそのキーの間でメンバーシップをテスト、値でなく"
            }
          ]
        },
        {
          "question": "names = ['Al', 'Bo'] と scores = [10, 20] があります。list(zip(names, scores)) は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "[('Al', 'Bo'), (10, 20)]"
            },
            {
              "icon": "",
              "label": "['Al', 10, 'Bo', 20]"
            },
            {
              "icon": "",
              "label": "[('Al', 10), ('Bo', 20)]"
            },
            {
              "icon": "",
              "label": "ValueError、zip は3つ以上の引数が必要"
            }
          ]
        },
        {
          "question": "class Dog: tricks = [] はクラスレベルリストを持ち、add_trick は self.tricks に追加する。d1 = Dog() と d2 = Dog() が両方作られ、d1.add_trick('sit') が走る。d2.tricks は何を含みますか？",
          "options": [
            {
              "icon": "",
              "label": "[] ——各インスタンスは tricks の独立したコピーを得る"
            },
            {
              "icon": "",
              "label": "['sit'] ——tricks はクラスレベルリスト。すべてのインスタンスで共有されるので、d1 の変更は d2 からも見える"
            },
            {
              "icon": "",
              "label": "TypeError ——インスタンスはクラス属性に追加できない"
            },
            {
              "icon": "",
              "label": "['sit'] ただし d2 = Dog() が再実行した後だけ"
            }
          ]
        },
        {
          "question": "class A は def greet(self): return 'A' を持つ。class B(A) は def greet(self): return 'B' + super().greet() を持つ。B().greet() は何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "'AB' ——super() は常にサブクラスのコードより先に走る"
            },
            {
              "icon": "",
              "label": "'B' ——super().greet() は無視される。B は既に greet をオーバーライド"
            },
            {
              "icon": "",
              "label": "'BA' ——super().greet() は A のメソッドを呼び、その結果が 'B' に追加される"
            },
            {
              "icon": "",
              "label": "AttributeError、A が B から見える greet メソッドを持たない"
            }
          ]
        },
        {
          "question": "class Point は __init__ で self.x を保存し、他のメソッドを定義しない。p1 = Point(1) と p2 = Point(1) があります。p1 == p2 はデフォルトで何を返しますか？",
          "options": [
            {
              "icon": "",
              "label": "True ——Pythonはデフォルトでマッチする属性をすべて比較"
            },
            {
              "icon": "",
              "label": "False ——カスタム __eq__ がなければ、== は恒等比較にフォール・バック。p1 と p2 は異なるオブジェクト"
            },
            {
              "icon": "",
              "label": "True、ただし両オブジェクトが同じ引数で作られたから"
            },
            {
              "icon": "",
              "label": "TypeError、Point が __eq__ を定義しない"
            }
          ]
        },
        {
          "question": "以下のうち、ZeroDivisionError も例外としてキャッチする except 句はどれですか：except ArithmeticError、except ValueError、または except KeyError？",
          "options": [
            {
              "icon": "",
              "label": "except ValueError ——除算エラーは無効な値として扱われる"
            },
            {
              "icon": "",
              "label": "except KeyError ——特定の型に紐づけられない実行時エラーはすべて KeyError にフォール・バック"
            },
            {
              "icon": "",
              "label": "どれも ——ZeroDivisionError 自体だけがそれをキャッチできる"
            },
            {
              "icon": "",
              "label": "except ArithmeticError ——ZeroDivisionError は ArithmeticError のサブクラス"
            }
          ]
        },
        {
          "question": "open('data.txt') as f: でファイルを開き、ブロック内の読み込み中に例外が起きる。ファイルはまだクローズされていますか？",
          "options": [
            {
              "icon": "",
              "label": "いいえ ——ブロックが通常に終わらなかったから、ファイルは開いたまま"
            },
            {
              "icon": "",
              "label": "ただし with 文を finally 句でも囲めば"
            },
            {
              "icon": "",
              "label": "はい ——with 文はファイルの __exit__ メソッドを呼び、ブロック内で例外が起きても、ファイルをクローズする"
            },
            {
              "icon": "",
              "label": "例外の型で決まる ——他の場所でキャッチされた例外だけがクリーンアップを起動"
            }
          ]
        },
        {
          "question": "x = [3, 1, 2] と y = x.sort() があります。y は何を保有していますか？",
          "options": [
            {
              "icon": "",
              "label": "[1, 2, 3] ——sort() は新しくソートされたリストを返す"
            },
            {
              "icon": "",
              "label": "None ——list.sort() はインプレースでソートして None を返す。x 自体が [1, 2, 3] になる"
            },
            {
              "icon": "",
              "label": "[3, 1, 2] ——sort() は元のソートされていないリストを返し、x の内部順序だけ変わる"
            },
            {
              "icon": "",
              "label": "TypeError、sort() は変数に割り当てられない"
            }
          ]
        },
        {
          "question": "'Score: ' + 42 を実行したら何が起きますか？",
          "options": [
            {
              "icon": "",
              "label": "'Score: 42' ——Pythonは + 式の中で数を自動変換"
            },
            {
              "icon": "",
              "label": "'Score: ' ——数は無言でドロップ"
            },
            {
              "icon": "",
              "label": "42 ——文字列を数に強制変換して加算"
            },
            {
              "icon": "",
              "label": "TypeError ——str と int を直接連結できない。42は str() で変換せねば"
            }
          ]
        },
        {
          "question": "results というリストが空かチェックしたいのです。Pythonic な方法はどれですか：if results == []: 、if len(results) == 0: 、または if not results: ？",
          "options": [
            {
              "icon": "",
              "label": "if results == []: ——これが空のリストを検出する唯一の信頼できる方法"
            },
            {
              "icon": "",
              "label": "if len(results) == 0: ——Python で空のリストは真だから必須"
            },
            {
              "icon": "",
              "label": "3つともほぼ実戦で使われない。標準的アプローチは if results is None:"
            },
            {
              "icon": "",
              "label": "if not results: ——Python イディオムは真性に依存し、空のリストは偽"
            }
          ]
        }
      ],
      "optionOrderVersion": "92945565db6c55da"
    }
  }
}
