Ein Vokabelprogramm in Python (Ein Vokabelprogramm in Python), Lektion, Seite 724413
https://www.purl.org/stefan_ram/pub/vokabeln_python (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Python-Kurs

Ein Vokabelprogramm in Python 

main.py
# (C) 2019 Stefan Ram, license: GPL
import sqlite3
import collections
import os

from random import random

if True:
try: os.remove('vocab.db')
except FileNotFoundError: pass

con=sqlite3.connect('vocab.db')

class AutoList( collections.UserList ):
def __setitem__( self, i, item ):
while i > len( self.data ):
self.data.append( None )
if i == len( self.data ):
self.data.append( item )
else:
self.data[ i ]= item
def total( self ):
result = 0
for value in self.data:
result += value
return result
def max( self ):
result = -1
for value in self.data:
if value > result: result = value
return result

cached_sum = AutoList()
debug = False
manual = False

try:
con.execute( "CREATE TABLE CARD( ID INTEGER PRIMARY KEY, FRONT, BACK, PROP, SUM )" )
con.commit()
except Exception as inst:
if isinstance( inst, sqlite3.OperationalError )and str( inst )== 'table CARD already exists':
if debug: print( "Table CARD already exists, it was not created anew." )
else:
print( "Unexpected error while trying to create table CARD:" )
print( str(type( inst ))+ ': ' + str( inst ))

if debug:
print( "Initial debug-print of table CARD:" )
for row in con.execute( "SELECT ID, FRONT, BACK, PROP FROM CARD ORDER BY ID" ):
print( f"row[ 0 ]= {row[ 0 ]}, row[ 1 ]= {row[ 1 ]}, row[ 2 ]= {row[ 2 ]}, row[ 3 ]= {row[ 3 ]}, " )

cards=\
[
( 0, 'explanation of: shenanigan', 'dishonest trick', 1, ),
( 1, 'word for: dishonest trick', 'shenanigan', 1, ),

( 2, 'explanation of: subterfuge', 'deception', 1, ),
( 3, 'word for: deception', 'subterfuge', 1, ),

( 4, 'explanation of: pageant', 'show', 1, ),
( 5, 'word for: a show', 'pageant', 1, ),

( 6, 'explanation of: elusive', 'fleeting', 1, ),
( 7, 'word for: fleeting', 'elusive', 1, ),

]

def update_cards():
inserted = 0
updated = 0
for card in cards:
update = False
try:
con.execute( "INSERT INTO CARD(ID,FRONT,BACK,PROP)VALUES(?,?,?,?)", card )
inserted += 1
except Exception as inst:
if isinstance( inst, sqlite3.IntegrityError )and str( inst )== 'UNIQUE constraint failed: CARD.ID':
update = True
else:
print( "Unexpected error while trying to create table CARD:" )
print( str(type( inst ))+ ': ' + str( inst ))
if update:
con.execute( "UPDATE CARD SET FRONT=?,BACK=? WHERE ID=?", (card[1],card[2],card[0],) )
updated += 1
if inserted or updated: con.commit()
print( f"inserted {inserted} and updated {updated} cards." )

def update_sums():
global cached_sum
cached_sum = AutoList()
sum = 0
for row in con.execute( "SELECT ID, PROP FROM CARD ORDER BY ID" ):
id = row[ 0 ]
prop = row[ 1 ]
sum += prop
cached_sum[ id ]= sum

def debug_prints():
for row in con.execute( "SELECT ID, FRONT, BACK, PROP FROM CARD" ):
try:
print(row,cached_sum[ row[ 0 ]])
except:
print(row)
print("cached_sum:" + str(cached_sum))
for i,sum in enumerate(cached_sum):
print( i,sum )

def next_random_offset():
number = random()
max = cached_sum.max()
for row in con.execute( "SELECT ID, SUM FROM CARD ORDER BY ID" ):
id = row[ 0 ]
sum = cached_sum[ id ]
try:
if debug: print( f"sum = {sum}, max = {max}, sum/max = {sum/max}, number = {number}" )
except:
if debug: print( f"sum = {sum}, max = {max}, number = {number}" )
if sum/max > number: return id
return 0

def dialog( id ):
global debug
global manual
for row in con.execute( "SELECT ID, FRONT, BACK, PROP FROM CARD WHERE ID=?", (id,) ):
id = row[ 0 ]
front = row[ 1 ]
back = row[ 2 ]
prop = row[ 3 ]
sum = cached_sum[ id ]
answer = input( front + ' (:h/:q/:s/:d/:m)? ' )
if answer == ":q": return 1
if answer == ":s": return -1
if answer == ":h": return -2
if answer == ":d": debug = not debug
if answer == ":m": manual = not manual
correct = answer==back
print( 'correct.' if correct else ': ' + back )
print()
if debug: print( f'id = {id}, prop = {prop}, sum = {sum}.' )
command = ''
if manual:
looping = True
while looping:
command = input( 'h/k/p/n/d/q? ' )
looping = False
if command == '': prop *=( 0.99 if correct else 1.01 )
elif command == 'k': prop *= 1.00
elif command == 'p': prop *= 1.10
elif command == 'n': prop *= 0.90
elif command == 'd': prop *= 0.00
elif command == 'h':
looping = True
print( 'h = help' )
print( 'k = keep current propensity of this card, do not change it' )
print( 'p = "prst", increase propensity by 10%' )
print( 'n = "nrst", decrease propensity by 10%' )
print( 'd = "delete", set propensity to 0% (no undo so far!)' )
else: looping = True
con.execute( "UPDATE CARD SET PROP=? WHERE ID=?", (prop,id,) )
con.commit()
return 2

def print_main_help():
print( '''
Usually, one is shown the front of a randomly selected card and
then supposed to type in the back side of the card.

If one types in the text exactly as given for the back side,
then the output "correct" will be shown and the "propensity
of the card will be slightly reduced, which means that it will
be shown less often. (However, the effect should be very small,
do not expect to be able to observe it unless you have answered
a card very often - the effect can be increased using manual
control or by editing the source code).)

Otherwise, the back side will be shown and the propensity of the
card will be increased slightly, which means that it will be shown
slightly more often. (The above remarks apply.)

In manual mode one can have more control of the propensity change.

In debug mode some internal details are shown for developers

Special commands are entered as follows:

:h - get this help page
:q - quit this game
:s - show some internal data (for developers only)
:d - toggle debug mode (debug mode is {debug})
:m - toggle manual mode (manual mode is {manual})" )
''' )

update_cards()
print( "enter h for help." )
while True:
update_sums()
r = next_random_offset()
a = 0
while a < 1:
a = dialog( r )
if a == 1: break
elif a == -1: debug_prints()
elif a == -2: print_main_help()
if a == 1: break
print()
print()

con.commit()
con.close()
if debug: print( "connection closed." )
if debug: print( "done." )

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram724413 stefan_ram:724413 Ein Vokabelprogramm in Python Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd724413, slrprddef724413, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/vokabeln_python