[実験] ChatGPT4とPySimpleGUIで学習のゲーム化をしたら、AWSの知識をどこまで習得出来るか

# 目論見
エンジニアにとってAWSの知識はあればあるだけ良い。しかし既存の退屈な勉強法に興味が持てない。
なので、モチベーションが上がる仕組みを用意してみようと考えた。
**ChatGPTとGUIを使用したら面倒くさい学習を簡単にゲーム化出来て、「やべえ、楽しい！」ってなりながら自動的に学べるんじゃないか**
という仮説が出てきたので、これを検証していくことにした。

# アプリ画像(暫定版)
![スクリーンショット 2023-04-18 13.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203740/cfc275a8-359b-affb-e198-cee1389a8a2e.png)

# 使用するライブラリ
- PySimpleGUI … 簡単にGUIを作成できる、tkinterのラッパー。
- polars … データの前処理。pandasはもう古くなりそう。
`pip install polars`

# 問題の作成方法
ChatGPT4に作成させる。
ネットで収集とか、AWSの本を見ながら問題を打ち込む、というアナログ作業はしない。
**だって面倒だもん。**

ChatGPTは嘘をつく？
**いや、俺は彼を信じる。**

# 手順
基本の流れは以下。
- ChatGPTに指示してコードを書いてもらう
- ChatGPTに指示して問題を作成してもらう
- エラーを吐いたら、ChatGPTに戻して修正してもらう。
- 3回くらいエラーを戻しても改善される見込みがなかったら、(**面倒だけど**)自分で修正する。

# アプリの処理イメージ
- カテゴリ別の4択問題が出題される。最初は1回10問ごとにするつもりだったが、触ってみて10問はだるいと判明。1回5問とした。
- 質問と回答履歴はcsvに保存する。回答履歴には正解/不正解も記録する。
- 過去の成績閲覧や集計を簡単に行えるようにする。例えば継続日数●日、1日辺りの平均プレイ回数、正解率、得意/苦手なカテゴリをワンポチで見られるようにする(この辺がゲーム要素)。
- 「一夜漬け、短期決戦」ではなく「**数ヶ月単位でダラダラ触って、いつでもそれなりに楽しい**」を目指す。

# 試してみての所感
## ChatGPTでそこそこの行数(50行以上とか)を書かせることについて
- 0 -> 1の部分ではChatGPTは強い。「とりあえず50行程度書いて」とやれば1分程度でそのくらい書いてくれる。
- しかし修正は状況による。50行のコードで一部エラーが出たり、挙動の一部を変えるように指示してもコスパはそれほど良くない。
  - 今まで動いてた部分を動かなくして返してくる(ポンコツ)
  - 同じ箇所で何度も修正作業が発生して、しかも改善されない。例えばpolarsの修正で存在しないメソッドを使ってきて、修正するように言うと、また別の存在しないメソッドを出してくる。polarsの日付関連で多い印象。
  - 全行書き直す時間を待つのがだるいし、途中で途切れることもある。つなぐ際にインデントズレが起きたりする。
  - 部分的に書き直してくる場合、該当箇所を探すのがだるい。
  - 以上から、最初から自分で修正した方が良いこともある。この見極めがまだ難しい。

## アプリの動きについて
- **今のところまぁまぁ**
- 改善点はたくさんあるけれど、とりあえず最低限はできた印象。

# コード全体(暫定版)
```.main.py
import random
import datetime
import PySimpleGUI as sg
from csv_utils import load_questions_from_csv, save_to_csv
from stats import get_stats
from layout import get_layout
import polars as pl
from polars import col as l

def main():
    all_questions = load_questions_from_csv('questions.csv')
    questions = random.choices(all_questions,k=5)
    results = []
    correct_count = 0
    now_time = datetime.datetime.now()

    for idx, question in enumerate(questions):
        if idx > 0:
            prev_result = "Correct" if results[-1]['is_correct'] == 'Yes' else "Incorrect"
            prev_answer = questions[idx - 1]['answer']
        else:
            prev_result = ""
            prev_answer = ""

        layout = get_layout(question['question'], question['options'], prev_result, prev_answer, idx, len(questions), correct_count)
        window = sg.Window('AWS Quiz', layout)

        while True:
            event, values = window.read()
            if event == sg.WIN_CLOSED or event == 'Abort':
                print('while or', event)
                break
            if event in question['options']:
                print('while true', event)
                selected_option = event
                is_correct = selected_option == question['answer']
                result_icon = "O" if is_correct else "X"

                results.append({
                    'timestamp': now_time,
                    'question': question['question'],
                    'selected_option': selected_option,
                    'is_correct': 'Yes' if is_correct else 'No',
                    'len_questions': len(all_questions),
                    'category': question['category']
                })

                if is_correct:
                    correct_count += 1

                window['RESULT_TEXT'].update(f"Result: {result_icon}")
                break
            elif event == 'CSV_BUTTON':
                try:
                    df = pl.read_csv('quiz_results.csv')
                    gp_correct = df.groupby('is_correct')
                    print('累計の正解数',gp_correct.count())
                    print(gp_correct)
                    df = df.with_columns(l('timestamp').str.slice(0,10).alias('date'))
                    print('日付_正誤数',df.groupby('date','is_correct').count().sort(
                        l('date'),
                        l('is_correct').reverse()
                        ))
                    print('category',df.groupby('category','is_correct').count())
                except FileNotFoundError:
                    print("File not found: quiz_results.csv")

        window.close()
        if event == sg.WIN_CLOSED or event == 'Abort':
            break

    if event != 'Abort':
        save_to_csv(results)

if __name__ == '__main__':
    main()

print('aaa')
```

```layout.py
import PySimpleGUI as sg

def get_layout(question, options, prev_result, prev_answer, idx, question_count, correct_count):
    option_rows = [[sg.Button(option, key=option)] for option in options]
    result_text = sg.Text("", size=(10, 1), key="RESULT_TEXT")

    if idx > 0:
        default_text = f"Previous: {prev_result} (Answer: {prev_answer})"
    else:
        default_text = ""

    prev_result_text = sg.Text(default_text)
    progress_text = sg.Text(f"Question {idx + 1} of {question_count} | Correct: {correct_count}")
    csv_button = sg.Button('Load CSV', key='CSV_BUTTON')

    layout = [
        [sg.Text(question)],
        *option_rows,
        [sg.Output(size=(120, 40), echo_stdout_stderr=True)],
        [sg.Button('Abort')],
        [result_text],
        [prev_result_text],
        [progress_text],
        [csv_button]
    ]

    return layout
```

```stats.py
import polars as pl
import datetime

def get_stats():
    try:
        df = pl.read_csv('quiz_results.csv', infer_schema=True)
        df = df.with_column(df['timestamp'].cast(pl.Date64))
        total_attempts = df.shape[0]
        today_attempts = df.filter(df['timestamp'].dt.day == datetime.date.today().day).shape[0]
        average_score = df['is_correct'].eq('Yes').sum() / total_attempts
        return total_attempts, today_attempts, average_score
    except FileNotFoundError:
        return 0, 0, 0
```

```csv_utils.py
import csv
import os

def load_questions_from_csv(filename):
    questions = []
    with open(filename, 'r', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            question = row['question']
            options = row['options'].split(',')
            answer = row['answer']
            category = row['category']
            questions.append({'question': question, 'options': options, 'answer': answer, 'category': category})
    return questions

def save_to_csv(data):
    print('save', data)
    file_exists = os.path.isfile('quiz_results.csv')
    with open('quiz_results.csv', 'a', newline='') as csvfile:
        fieldnames = ['timestamp', 'question', 'selected_option', 'is_correct', 'len_questions', 'category']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        if not file_exists:
            writer.writeheader()
        for row in data:
            row['timestamp'] = row['timestamp'].isoformat()
            writer.writerow(row)

```

問いは以下。現状、60問程度。
```question.csv
question,options,answer,category
AWSの主要なストレージサービスは何ですか？,"Amazon EBS,Amazon S3,Amazon EC2,Amazon RDS",Amazon S3,ストレージ
AWSで仮想サーバーを提供するサービスは何ですか？,"Amazon VPC,Amazon EC2,AWS Lambda,Amazon ECS",Amazon EC2,コンピューティング
サーバーレスコンピューティングサービスは何ですか？,"Amazon EC2,Amazon ECS,Amazon ECR,AWS Lambda",AWS Lambda,コンピューティング
AWSの主要なストレージサービスは何ですか？,"Amazon EBS,Amazon S3,Amazon EC2,Amazon RDS",Amazon S3,ストレージ
AWSで仮想サーバーを提供するサービスは何ですか？,"Amazon VPC,Amazon EC2,AWS Lambda,Amazon ECS",Amazon EC2,コンピューティング
サーバーレスコンピューティングサービスは何ですか？,"Amazon EC2,Amazon ECS,Amazon ECR,AWS Lambda",AWS Lambda,コンピューティング
AWSのデータベース移行サービスは何ですか？,"AWS Database Migration Service,Amazon RDS,Amazon Redshift,Amazon Aurora",AWS Database Migration Service,データベース
AWSでデータ分析用のデータウェアハウスサービスは何ですか？,"Amazon Redshift,Amazon RDS,Amazon Elasticsearch Service,Amazon DynamoDB",Amazon Redshift,分析
Amazon S3バケットポリシーは何のために使われますか？,"バケットの容量を制限する,バケットへのアクセスを制御する,バケットを暗号化する,バケットの所有者を変更する",バケットへのアクセスを制御する,セキュリティ、アイデンティティ、コンプライアンス
AWSでプライベートネットワークを構築するサービスは何ですか？,"Amazon VPC,Amazon EC2,Amazon Connect,Amazon WorkSpaces",Amazon VPC,ネットワーキングとコンテンツ配信
AWSでDNSサービスを提供するのは何ですか？,"Amazon Route 53,Amazon CloudFront,Amazon API Gateway,AWS Direct Connect",Amazon Route 53,ネットワーキングとコンテンツ配信
AWSのコンテンツ配信ネットワーク（CDN）サービスは何ですか？,"Amazon CloudFront,Amazon Route 53,Amazon Connect,Amazon AppStream 2.0",Amazon CloudFront,ネットワーキングとコンテンツ配信
AWSでNoSQLデータベースを提供するサービスは何ですか？,"Amazon RDS,Amazon Redshift,Amazon DynamoDB,Amazon Aurora",Amazon DynamoDB,データベース
AWSでサーバーレスアプリケーションのデプロイをサポートするサービスは何ですか？,"AWS SAM,Amazon EC2,Amazon ECS,Amazon ECR",AWS SAM,コンピューティング
オンプレミスサーバーとAWSを直接接続するサービスは何ですか？,"AWS Direct Connect,Amazon VPC,Amazon Connect,Amazon Route 53",AWS Direct Connect,ネットワーキングとコンテンツ配信
AWSでコンテナ管理サービスを提供するのは何ですか？,"Amazon ECS,Amazon ECR,Amazon EC2,Amazon EKS",Amazon ECS,コンピューティング
AWSでマネージドKubernetesサービスを提供するのは何ですか？,"Amazon ECR,Amazon ECS,Amazon EKS,Amazon EC2",Amazon EKS,コンピューティング
AWSのグローバルアクセラレータはどのようなサービスですか？,"コンテンツ配信ネットワーク,アプリケーションのパフォーマンスを向上させる,データウェアハウス,仮想サーバー",アプリケーションのパフォーマンスを向上させる,ネットワーキングとコンテンツ配信
AWSでスケーラブルな分析用パイプラインを提供するサービスは何ですか？,"AWS Glue,Amazon Kinesis,Amazon S3,Amazon RDS",AWS Glue,分析
AWSでストリーミングデータを取り込むサービスは何ですか？,"Amazon Kinesis,Amazon Redshift,Amazon Elasticsearch Service,Amazon DynamoDB",Amazon Kinesis,分析
AWSでオブジェクトストレージサービスを提供するのは何ですか？,"Amazon S3,Amazon EBS,Amazon RDS,Amazon Glacier",Amazon S3,ストレージ
Amazon RDSはどのようなサービスですか？,"リレーショナルデータベースサービス,データウェアハウスサービス,ストリーミングデータサービス,オブジェクトストレージサービス",リレーショナルデータベースサービス,データベース
AWSで高耐久性の低コストストレージを提供するアーカイブサービスは何ですか？,"Amazon S3 Glacier,Amazon S3,Amazon EBS,Amazon RDS",Amazon S3 Glacier,ストレージ
AWSでマネージドなデータウェアハウスサービスを提供するのは何ですか？,"Amazon Redshift,Amazon RDS,Amazon Elasticsearch Service,Amazon DynamoDB",Amazon Redshift,分析
AWSでデータを暗号化するためのキーマネジメントサービスは何ですか？,"AWS Key Management Service,Amazon GuardDuty,Amazon Macie,Amazon S3",AWS Key Management Service,セキュリティ
AWSでバックアップとリカバリを提供するサービスは何ですか？,"AWS Backup,Amazon S3,Amazon EBS,Amazon EC2",AWS Backup,ストレージ
AWSの仮想プライベートクラウドサービスは何ですか？,"Amazon VPC,Amazon EC2,Amazon RDS,Amazon S3",Amazon VPC,ネットワーキングとコンテンツ配信
AWSでマネージドのNoSQLデータベースサービスは何ですか？,"Amazon DynamoDB,Amazon RDS,Amazon Redshift,Amazon Aurora",Amazon DynamoDB,データベース
AWSでフルマネージドな検索サービスを提供するのは何ですか？,"Amazon Elasticsearch Service,Amazon RDS,Amazon Redshift,Amazon DynamoDB",Amazon Elasticsearch Service,分析
AWSのマネージドなメッセージングサービスは何ですか？,"Amazon SQS,Amazon SNS,Amazon SES,Amazon SWF",Amazon SQS,アプリケーション統合
AWSでサーバーレスワークフローを作成するサービスは何ですか？,"AWS Step Functions,Amazon SWF,Amazon SNS,Amazon SQS",AWS Step Functions,アプリケーション統合
AWSでDNSサービスを提供するのは何ですか？,"Amazon Route 53,Amazon VPC,Amazon Connect,Amazon EC2",Amazon Route 53,ネットワーキングとコンテンツ配信
AWSで自動スケーリング機能を提供するサービスは何ですか？,"AWS Auto Scaling,Amazon EC2,Amazon ECS,Amazon ECR",AWS Auto Scaling,コンピューティング
AWSでマネージドなファイルシステムを提供するのは何ですか？,"Amazon EFS,Amazon S3,Amazon EBS,Amazon RDS",Amazon EFS,ストレージ
AWSでデータ移行サービスを提供するのは何ですか？,"AWS Database Migration Service,Amazon RDS,Amazon S3,Amazon EC2",AWS Database Migration Service,データベース
AWSでマネージドなコンテナオーケストレーションサービスは何ですか？,"Amazon ECS,Amazon ECR,Amazon EC2,Amazon EKS",Amazon ECS,コンピューティング
AWSでマネージドなKubernetesサービスは何ですか？,"Amazon EKS,Amazon ECS,Amazon EC2,Amazon ECR",Amazon EKS,コンピューティング
AWSでクラウドベースのデータウェアハウスサービスは何ですか？,"Amazon Redshift,Amazon RDS,Amazon DynamoDB,Amazon Elasticsearch Service",Amazon Redshift,分析
AWSでクラウドベースのレコメンデーションエンジンを提供するサービスは何ですか？,"Amazon Personalize,Amazon Forecast,Amazon Connect,Amazon Athena",Amazon Personalize,機械学習
AWSでユーザー認証と認可機能を提供するサービスは何ですか？,"Amazon Cognito,Amazon IAM,Amazon AppStream,Amazon Macie",Amazon Cognito,セキュリティ
AWSでマネージドなストリーミングデータプラットフォームは何ですか？,"Amazon Kinesis,Amazon SQS,Amazon SNS,Amazon SWF",Amazon Kinesis,アプリケーション統合
AWSでエッジコンピューティングデバイスを提供するサービスは何ですか？,"AWS Snowball Edge,Amazon Lightsail,Amazon RDS,Amazon Connect",AWS Snowball Edge,ストレージ
AWSでマネージドなグラフデータベースサービスは何ですか？,"Amazon Neptune,Amazon RDS,Amazon Redshift,Amazon DynamoDB",Amazon Neptune,データベース
AWSでデータ分析を行うサービスは何ですか？,"Amazon Athena,Amazon QuickSight,Amazon Redshift,Amazon EMR",Amazon Athena,分析
AWSでマネージドなApache Kafkaサービスは何ですか？,"Amazon MSK,Amazon Kinesis,Amazon SQS,Amazon SNS",Amazon MSK,アプリケーション統合
AWSでクラウドベースのコンテンツ配信ネットワークサービスは何ですか？,"Amazon CloudFront,Amazon S3,Amazon EBS,Amazon FSx",Amazon CloudFront,ネットワーキングとコンテンツ配信
AWSで分散型のキーバリューストアサービスは何ですか？,"Amazon DynamoDB,Amazon RDS,Amazon Redshift,Amazon ElastiCache",Amazon DynamoDB,データベース
AWSでサーバーレスでウェブアプリケーションをデプロイするサービスは何ですか？,"AWS Amplify,Amazon App Runner,Amazon Lightsail,Amazon API Gateway",AWS Amplify,フロントエンドWebとモバイル
AWSでマネージドな機械学習サービスは何ですか？,"Amazon SageMaker,Amazon Comprehend,Amazon Rekognition,Amazon Textract",Amazon SageMaker,機械学習
AWSで分散型のメッセージキューサービスは何ですか？,"Amazon SQS,Amazon SNS,Amazon Kinesis,Amazon MSK",Amazon SQS,アプリケーション統合
AWSで分散型のメッセージ通知サービスは何ですか？,"Amazon SNS,Amazon SQS,Amazon Kinesis,Amazon MSK",Amazon SNS,アプリケーション統合
AWSでクラウドベースの転送加速サービスは何ですか？,"Amazon S3 Transfer Acceleration,Amazon CloudFront,Amazon Direct Connect,Amazon Storage Gateway",Amazon S3 Transfer Acceleration,ストレージ
AWSでオンプレミス環境とAWSクラウドの接続を提供するサービスは何ですか？,"AWS Direct Connect,Amazon VPC,Amazon CloudFront,Amazon Connect",AWS Direct Connect,ネットワーキングとコンテンツ配信
AWSでクラウドベースの監視サービスは何ですか？,"Amazon CloudWatch,Amazon X-Ray,Amazon Inspector,Amazon GuardDuty",Amazon CloudWatch,管理ツール
AWSでクラウドベースのログ解析サービスは何ですか？,"Amazon Elasticsearch Service,Amazon CloudWatch,Amazon Kinesis,Amazon Redshift",Amazon Elasticsearch Service,分析
AWSでデータセンターのスケールアウトを簡素化するサービスは何ですか？,"AWS Outposts,Amazon EC2,Amazon Lightsail,Amazon RDS",AWS Outposts,ハイブリッドクラウド
AWSでクラウドベースの分散トレーシングサービスは何ですか？,"Amazon X-Ray,Amazon CloudWatch,Amazon Inspector,Amazon GuardDuty",Amazon X-Ray,管理ツール
AWSでサーバーレスアプリケーションを構築およびデプロイするためのフレームワークは何ですか？,"AWS Serverless Application Model,Amazon EC2,Amazon ECS,Amazon ECR",AWS Serverless Application Model,コンピューティング
AWSでマネージドなビデオストリーミングサービスは何ですか？,"Amazon Interactive Video Service,Amazon Kinesis,Amazon CloudFront,Amazon S3",Amazon Interactive Video Service,メディアサービス
AWSでクラウドベースの脆弱性評価サービスは何ですか？,"Amazon Inspector,Amazon GuardDuty,Amazon CloudWatch,Amazon X-Ray",Amazon Inspector,セキュリティ、アイデンティティ、およびコンプライアンス
```

# 今後
ダラダラ続けていって、数ヶ月後にAWSについてめっちゃ詳しくなれているかを調べる。
「本気で一生懸命取り組み続けて」ではなく、「**ダラダラ続ける**」これが肝。
何故なら**頑張って続けるという価値観自体が、もはや古いもの**だと思うので。
今後は**吹けば飛んでいく風船みたいなやる気でも、自動的に色々な事が習得出来ていく時代**になっていくと思う。逆にそうなれない人はたぶん、今後どんどん厳しくなっていく。
**脱力大事**。