はじめに
以前計算問題をただひたすら読み上げてくれるプログラムを書きました。touch-sp.hatenablog.com
今回は間違えた問題をデータベースに保存することにチャレンジします。
Pythonのリスト型に格納してpickleで保存する方法が最も簡易な方法と思います。
しかし今回はデータベースの学習も兼ねて「SQLAlchemy」を使いました。
「SQLAlchemy」の導入
pipで問題なくインストールできました。pip install sqlalchemy
「SQLAlchemy」の使い方
データベースの作成
以下のスクリプトを「make_database.py」という名前で保存して実行すると「formula」というテーブルを含む「try_again.db」というデータベースが作成されます。from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import create_engine, Column, Integer engine = create_engine('sqlite:///try_again.db', echo = False) Base = declarative_base() class Multiplication(Base): __tablename__ = 'formula' id = Column('account_id', Integer, primary_key=True) q1 = Column('first_number', Integer) q2 = Column('second_number', Integer) Base.metadata.create_all(bind=engine)
データの挿入
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from make_database import Multiplication engine = create_engine('sqlite:///try_again.db') session = sessionmaker(bind=engine)() session.add( Multiplication( q1 = 99, q2 = 99 ) ) session.commit() session.close()
データの一覧表示
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from make_database import Multiplication engine = create_engine('sqlite:///try_again.db') session = sessionmaker(bind=engine)() query_result = session.query(Multiplication) for formula in query_result: print('%d X %d'%(formula.q1, formula.q2)) session.close()
データの削除
テーブル内のデータを全削除するスクリプトです。テーブル自体は削除されません。from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from make_database import Multiplication engine = create_engine('sqlite:///try_again.db') session = sessionmaker(bind=engine)() session.query(Multiplication).delete() session.commit() session.close()
計算アプリのスクリプト
キーボードの「M」を押すとデータベースに現在の問題が保存されるようにしました。間違える度に「M」を押せばどんどんデータが蓄積されます。
import sys import random import win32com.client from PyQt6.QtCore import Qt from PyQt6.QtWidgets import QMainWindow, QApplication, QLabel from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from constructGUI import construct from make_database import Multiplication min_q = 11 max_q = 22 engine = create_engine('sqlite:///try_again.db') class Window(QMainWindow): def __init__(self): super().__init__() self.initUI() self.speaker = win32com.client.Dispatch('SAPI.SpVoice') self.q1 = 0 self.q2 = 0 self.answer = 0 self.playing = False self.session = sessionmaker(bind = engine)() def initUI(self): self.setWindowTitle("かけ算") self.num_label = construct(QLabel(), "settings.yaml", "label_1") self.setCentralWidget(self.num_label) def keyPressEvent(self, e): if e.key() == Qt.Key.Key_N: self.calc_exe() if e.key() == Qt.Key.Key_Q: self.close_Event() if e.key() == Qt.Key.Key_M: self.session.add( Multiplication(q1 = self.q1, q2 = self.q2) ) self.session.commit() def calc_exe(self): if self.playing == False: self.q1 = random.randint(min_q,max_q) self.q2 = random.randint(min_q,max_q) self.num_label.setText('%d x %d'%(self.q1, self.q2)) self.answer = self.q1 * self.q2 self.speaker.Speak('%dかける%d'%(self.q1, self.q2)) self.playing = not self.playing else: self.speaker.Speak('%d'%self.answer) self.playing = not self.playing def close_Event(self): self.session.close() sys.exit() if __name__ == "__main__": app = QApplication([]) ex =Window() ex.show() app.exec()
動作環境
Windows 11
Python 3.9.12
greenlet==1.1.2 PyQt6==6.2.3 PyQt6-Qt6==6.2.4 PyQt6-sip==13.2.1 pywin32==303 PyYAML==6.0 SQLAlchemy==1.4.32
さいごに
保存された問題から出題するスクリプトを書けば間違えた問題を何度も繰り返すことができます。こちらのスクリプトになります。import sys import random import win32com.client from PyQt6.QtCore import Qt from PyQt6.QtWidgets import QMainWindow, QApplication, QLabel from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from constructGUI import construct from make_database import Multiplication engine = create_engine('sqlite:///try_again.db') session = sessionmaker(bind = engine)() question_list = [(x.q1, x.q2) for x in session.query(Multiplication)] session.close() class Window(QMainWindow): def __init__(self): super().__init__() self.initUI() self.speaker = win32com.client.Dispatch('SAPI.SpVoice') self.q1 = 0 self.q2 = 0 self.answer = 0 self.playing = False def initUI(self): self.setWindowTitle("かけ算") self.num_label = construct(QLabel(), "settings.yaml", "label_1") self.setCentralWidget(self.num_label) def keyPressEvent(self, e): if e.key() == Qt.Key.Key_N: self.calc_exe() if e.key() == Qt.Key.Key_Q: self.close_Event() def calc_exe(self): if self.playing == False: self.q1, self.q2 = random.choice(question_list) self.num_label.setText('%d x %d'%(self.q1, self.q2)) self.answer = self.q1 * self.q2 self.speaker.Speak('%dかける%d'%(self.q1, self.q2)) self.playing = not self.playing else: self.speaker.Speak('%d'%self.answer) self.playing = not self.playing def close_Event(self): sys.exit() if __name__ == "__main__": app = QApplication([]) ex =Window() ex.show() app.exec()
反復練習にはうってつけですね(笑)。
記憶を目的としたアプリであれば記憶の定着にかなり効果がありそうです。
touch-sp.hatenablog.com
touch-sp.hatenablog.com