【Python】マッチ棒クイズ開発 Part4

こんにちは、にわこまです。

今回は、マッチ棒クイズにおける問題と答えを生成するファイルを完成させます。具体的には実際に問題と答えを生成するmain関数を作成します。

 

誤字脱字や分からない点がございましたらご連絡お願いいたします!

メールまたはTwitterのDMまで!!

 

 

 

スポンサードサーチ


main関数

今まで作成してきた関数をmain関数にまとめます。main関数にまとめることで見やすくなります。

生成した問題と答えはjsonファイルに保存します。

 

 

コードの提示

問題と答えを生成するmain関数のソースコードを以下に示します。

import json

def matchstickX(num, sticks):
    # 省略

def makePlusFormula():
    # 省略

def makeMinusFormula():
    # 省略

def checkFml(qfml):
    # 省略

def makeQuestionFml(fml):
    # 省略

def main():
    count = 0
    ans_ques_dict = {}                      # {Answer1:[Question1, Question2, ...], ...}
    formula_list = makePlusFormula()
    for fml in formula_list:
        fml_str = " ".join(fml)             # Answer
        qfml_list = makeQuestionFml(fml)    # Question
        qfml_str_list = [" ".join(l) for l in qfml_list]
        ans_ques_dict[fml_str] = qfml_str_list
        count += len(qfml_list)
    formula_list = makeMinusFormula()
    for fml in formula_list:
        fml_str = " ".join(fml)
        qfml_list = makeQuestionFml(fml)
        qfml_str_list = [" ".join(l) for l in qfml_list]
        ans_ques_dict[fml_str] = qfml_str_list
        count += len(qfml_list)
    print("count = ", count)

    with open("matchstickquiz_QA.json", encoding="utf-8", mode="w") as f:
        json.dump(ans_ques_dict, f, ensure_ascii=False, indent=2)
    pass

if __name__ == '__main__':
    main()

  

上記のコードは以下からダウンロードできます。

  

 

コードの解説

1行目の「import json」は、jsonライブラリをインポートしています。問題と答えをjson形式で保存するため必要となります。

 

18行目から39行目は、main関数です。

 

19行目の「count」は、問題を数えるための変数です。

 

20行目の「ans_ques_dict」は、問題と答えを代入する変数です。初期値として空の辞書を代入しています。答えがkey、問題がvalueとなります。(例:{Answer : [Question1, Question2, …], …})

 

 

21行目から27行目は、足し算の式が答えとなる問題を生成しています。

 

21行目の「formula_list」は、makePlusFormula関数によって生成された式が代入されている変数です。

 

22行目の「for文」は、formula_listの要素数だけ繰り返します。ループ変数はfmlです。

 

23行目の「fml_str」は、fmlを半角スペースでつなぎ合わせた文字列が代入されている変数です。辞書のkeyにリストを設定することができないため、文字列に変換しています。

 

24行目の「qfml_list」は、makeQuestionFml関数によって生成された式が代入されている変数です。

 

25行目の「qfml_str_list」は、qfml_listに代入されているリスト型の式を半角スペースでつなぎ合わせた文字列が代入されている変数です。

 

26行目は、ans_ques_dictにkeyをfml_strとして、valueにqfml_str_listを代入しています。

 

27行目は、問題の数をかぞえています。

 

 

28行目から34行目は、引き算が答えとなる問題を生成しています。

 

28行目の「formula_list」は、makeMinusFormula関数によって生成された式が代入されている変数です。

 

29行目の「for文」は、formula_listの要素数だけ繰り返します。ループ変数はfmlです。

 

30行目の「fml_str」は、fmlを半角スペースでつなぎ合わせた文字列が代入されている変数です。辞書のkeyにリストを設定することができないため、文字列に変換しています。

 

31行目の「qfml_list」は、makeQuestionFml関数によって生成された式が代入されている変数です。

 

32行目の「qfml_str_list」は、qfml_listに代入されているリスト型の式を半角スペースでつなぎ合わせた文字列が代入されている変数です。

 

33行目は、ans_ques_dictにkeyをfml_strとして、valueにqfml_str_listを代入しています。

 

34行目は、問題の数をかぞえています。

 

 

35行目は、問題の数を表示しています。

 

 

37行目の「with文」は、ファイルの読み書きの設定を行っています。

具体的には「matchstickquiz_QA.jsonというファイルに文字コードutf-8で書き込む」という設定を行っています。

 
38行目の「json.dump()」は、ans_ques_dictをファイルに書き込んでいます。

 

 

動作確認

コードを保存したら、コマンドプロンプトを開きファイルを保存したフォルダまで移動します。移動したら、以下のコマンドを入力し実行します。

python matchstickquiz_QA.py

  

以下のように表示されれば動作確認完了です。

count = 736

 

動作確認は完了しましたが懸念点があります。

答えが2つ以上存在する問題があるということです。

 

例えば「8 + 0 = 0」という問題に対して、「8 – 8 = 0」と「8 – 0 = 8」という答えが存在するということです。

今回はこのような2つ以上答えが存在する問題を削除したいと思います。

 

 

スポンサードサーチ


main関数(重複削除)

2つ以上答えが存在する問題を削除するmain関数を作成します。

2つ以上答えが存在するということは、複数のkey(答え)に対して同じ問題がvalue(問題ら)に含まれるということです。つまり問題が重複しているということです。

 

故に、重複している問題を集めvalue(問題ら)から引くことで重複を削除します。

 

 

コードの提示

問題を答えを生成するmain関数(重複削除)のソースコードを以下に示します。

import json

def matchstickX(num, sticks):
    # 省略

def makePlusFormula():
    # 省略

def makeMinusFormula():
    # 省略

def checkFml(qfml):
    # 省略

def makeQuestionFml(fml):
    # 省略

def main():
    count = 0
    ans_ques_dict = {}                      # {Answer1:[Question1, Question2, ...], ...}
    formula_list = makePlusFormula()
    for fml in formula_list:
        fml_str = " ".join(fml)             # Answer
        qfml_list = makeQuestionFml(fml)    # Question
        qfml_str_list = [" ".join(l) for l in qfml_list]
        ans_ques_dict[fml_str] = qfml_str_list
        count += len(qfml_list)
    formula_list = makeMinusFormula()
    for fml in formula_list:
        fml_str = " ".join(fml)
        qfml_list = makeQuestionFml(fml)
        qfml_str_list = [" ".join(l) for l in qfml_list]
        ans_ques_dict[fml_str] = qfml_str_list
        count += len(qfml_list)
    print("count = ", count)

    # Remove Multiple Answer
    count = 0
    all_qfml_list = []
    for qfml_list in ans_ques_dict.values():
        all_qfml_list += qfml_list
    dup_qfml_set = set([fml for fml in set(all_qfml_list) if all_qfml_list.count(fml) > 1])
    new_ans_ques_dict = {}
    for k, v in ans_ques_dict.items():
        qfml_list = list(set(v) - dup_qfml_set)
        lng = len(qfml_list)
        if(lng >= 1):
            new_ans_ques_dict[k] = qfml_list
        count += lng
    print("count = ", count)

    with open("matchstickquiz_QA.json", encoding="utf-8", mode="w") as f:
        json.dump(new_ans_ques_dict, f, ensure_ascii=False, indent=2)
    pass

if __name__ == '__main__':
    main()

 

上記のコードは以下からダウンロードできます。

 

 

コードの解説

37行目から50行目が重複を削除するコードです。

 

38行目の「count」は、問題数をかぞえる変数です。初期値0をだいにゅうしています。

 

39行目の「all_qfml_list」は、問題を全て代入する変数です。ここではまだ重複ありです。初期値として空のリストを代入しています。

 

40行目の「for文」は、ans_ques_dictの長さだけ繰り返します。ループ変数はqfml_listです。

 

41行目は、all_qfml_listにqfml_listを結合しています。

 
42行目の「dup_qfml_set」は、重複している問題を集めた集合型の変数です。

 

43行目の「new_ans_ques_dict」は、重複無しの問題と答えを代入する変数です。初期値として空の辞書を代入しています。答えがkey、問題がvalueとなります。(例:{Answer : [Question1, Question2, …], …})

 

44行目の「for文」は、ans_ques_dictの長さだけ繰り返します。ループ変数はkとvです。

 

45行目の「qfml_list」は、重複ありの問題の集合から重複している問題の集合を引いた重複なしの問題がリスト型で代入されています。

  

46行目の「lng」は、qfml_listの長さを代入する変数です。

 

47行目の「if文」は、lngが1以上であるかを判別する条件式です。つまり、問題が存在するか確かめています。1つ以上あれば48行目を実行します。

 

48行目は、new_ans_ques_dictにkeyをkとして、valueにqfml_listを代入しています。

 

49行目は、問題の数をかぞえています。

 

50行目は、問題の数を表示しています。

 

 

動作確認

コードを保存したら、コマンドプロンプトを開きファイルを保存したフォルダまで移動します。移動したら、以下のコマンドを入力し実行します。

python matchstickquiz_QA.py

 

以下のように表示されれば動作確認完了です。

count = 736
count = 452

 

 

スポンサードサーチ


まとめ

今回は、問題と答えを生成するファイルを完成させました。問題と答えを生成するにあたり、重複している問題があるという懸念点がありましたが、解決しました。

重複ありの問題数と比べると重複なしの問題数は少ないですが、実際にプレイするときは気にならないと思います。

 

次回Part5では、kivyライブラリを使用してマッチ棒の初期化と表示を行います。

 

  

  

最後までお読みいただきありがとうございます。


スポンサードサーチ