File size: 4,315 Bytes
e379257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Rewrite the question texts of a gallery JSONL to the q2 wording (clearer criteria, same gold).



usage: python scripts/make_q2.py in.jsonl out.jsonl

"""
import json, sys

INSTR = {
    "screen": {
        "en": "What is the current screen state? Decide in this order: if an alert, dialog or action sheet is shown, pick its kind; otherwise, if a sheet is presented, pick sheet whatever it contains; otherwise describe the screen underneath. Banners and toasts do not change the answer.",
        "ja": "現在の画面状態はどれか?次の順で判断する。アラート・ダイアログ・アクションシートがあればその種類。なければ、シートが出ていれば中身に関係なくシート。それもなければ下の画面で答える。バナーやトーストは答えを変えない。",
    },
    "has_error": {
        "en": "Is an error or failure message visible (alert, banner, toast, inline validation, or error screen), including an offline / no connection banner?",
        "ja": "エラーや失敗を示すメッセージ(ダイアログ・バナー・トースト・入力エラー・エラー画面)が表示されているか?オフライン・接続なしの表示も含む。",
    },
    "primary_button": {
        "en": "Which is the primary action button? Answer with the button's action even if it is disabled or shows a progress spinner.",
        "ja": "最も目立つ操作ボタンはどれか?押せない状態や処理中の表示でも、そのボタンの操作で答える。",
    },
    "has_modal": {
        "en": "Is a modal (alert, dialog, action sheet, or sheet) presented over the content? A sheet counts at any height.",
        "ja": "コンテンツの上にモーダル(アラート・ダイアログ・アクションシート・シート)が表示されているか?シートは高さに関係なく含む。",
    },
    "has_destructive_action": {
        "en": "Is a destructive action (e.g. a red Delete/Discard button) visible? Cancel and Close do not count.",
        "ja": "破壊的な操作(赤い削除・破棄ボタンなど)が表示されているか?キャンセルや閉じるは含まない。",
    },
    "is_empty": {
        "en": "Does the main content show an empty state (no items or no results)? Loading spinners, skeleton placeholders and empty input fields are not an empty state.",
        "ja": "メインコンテンツが空の状態(項目なし・結果なし)か?読み込み中の表示やスケルトン、未入力の入力欄は空の状態ではない。",
    },
}
SCREEN_CRITERIA = {
    "loading": "The whole content is replaced by a loading spinner, progress or skeleton (a saving button does not count) / 画面全体が読み込み中",
    "offline": "The whole content is replaced by an offline / no connection screen (a banner does not count) / 画面全体がオフライン表示",
    "home": "A normal home/list screen; banners or toasts may be shown on it / 通常のホーム・一覧画面(バナーやトーストがあってもよい)",
    "form": "A full-screen data-entry form (checkout, profile, transfer ...), not inside a sheet / 全画面の入力フォーム",
    "sheet": "A sheet presented over the content, whatever it contains (form, filters ...) / シート(中身がフォームでもシート)",
}

def main(src, dst):
    n = 0
    with open(src, encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as out:
        for line in f:
            if not line.strip():
                continue
            r = json.loads(line)
            lang = "ja" if r["meta"].get("lang") == "ja" else "en"
            for qid, text in INSTR.items():
                if qid in r["questions"]:
                    r["questions"][qid]["instructions"] = text[lang]
            crit = r["questions"]["screen"]["criteria"]
            for k, v in SCREEN_CRITERIA.items():
                if k in crit:
                    crit[k] = v
            r["meta"]["question_version"] = "q2"
            out.write(json.dumps(r, ensure_ascii=False) + "\n")
            n += 1
    print(f"{n} records -> {dst}")

if __name__ == "__main__":
    main(sys.argv[1], sys.argv[2])