Tyto stránky již nejsou udržovány. Obsah je postupně přesouván/aktualizován na adrese chytrosti.marrek.cz.
199/578
Obsah:
Navrhněte a vytvořte aplikaci pro testování žáků prvního stupně ZŠ. Aplikace bude generovat příklady na sčítání, odčítání násobení a dělení (bezezbytku) do sta.
Uživatel si volí, které matematické operace chce cvičit. Např. jen sčítání a dělení. Uživateli je také vypsána statistika úspěšnosti.
Nejprve vytvoříme grafické uživatelské rozhraní pomocí knihovny Tk.
#!/usr/bin/python
# -*- coding: utf8 -*-
from Tkinter import *
##################################################
### Definice funkcí
##################################################
### GUI
mainWin = Tk()
##################################################
## Nekonečná smyčka
mainWin.mainloop()
`--> stáhnout
Do aplikace nejprve umístíme ovládací prvky. Pro umísťování udělátek je použita metoda grid.
# výběr operace
Label(mainWin, text=u"Operace: ").grid(row=0, column=0, columnspan=3)
operaceEntry = Entry(mainWin, width=8)
operaceEntry.grid(row=0, column=3, columnspan=2)
operaceEntry.insert(0,'+-*/')
# Číslo A
cisloAentry=Entry(mainWin, width=4)
cisloAentry.grid(row=1, column=0)
# matematická operace
lblOperace=Label(mainWin,text='?')
lblOperace.grid(row=1, column=1)
# Číslo B
cisloBentry=Entry(mainWin, width=4)
cisloBentry.grid(row=1, column=2)
# rovnítko
Label(mainWin,text='=').grid(row=1, column=3)
# Výsledek
vysledekEntry=Entry(mainWin, width=4)
vysledekEntry.grid(row=1, column=4)
# Hodnocení
lblOK=Label(mainWin,text='?')
lblOK.grid(row=2, column=0)
# Statistika
lblStat=Label(mainWin,text='0/0')
lblStat.grid(row=2, column=4)
`--> stáhnout
Pro začátek vytvoříme dvě funkce, které budou generovat nové příklady
(novyPriklad
) a kontrolovat, zda uživatel zadal správně výsledek
(kontrola
). Pro jednoduchost začne jen s násobením. Tyto funkce spolu
komunikují přes globální proměnou vysledek
.
vysledek=0
def novyPriklad(event=None):
global vysledek
cisloA= random.randint(1,10)
cisloB= random.randint(1,10)
vysledek = cisloA * cisloB
cisloAentry.delete(0, END)
cisloAentry.insert(0, str(cisloA) )
cisloBentry.delete(0, END)
cisloBentry.insert(0, str(cisloB) )
lblOperace.config(text='*')
def kontrola(event):
global vysledek
if vysledek == int( vysledekEntry.get() ):
lblOK.config(text='OK')
else:
lblOK.config(text=':(')
novyPriklad()
`--> stáhnout
A tyto funkce navážeme na události. Událost <Return>
je při stisku Enter.
Událost <Map>
vzniká při umístění udělátka -- v tomto případě tedy při startu
aplikace.
vysledekEntry.bind('<Return>',kontrola)
mainWin.bind('<Map>',novyPriklad)
`--> stáhnout
V dalším kroku přidáme statistiku počtu dobře vyřešených příkladů. Bude potřeba
přidat další dvě globální proměnné dobre
a celkem
. Zároveň přidáme sekci
try
, která ošetří vznik běhových chyb, pokud uživatel
zadá do vstupního pole nečíselné znaky.
dobre = 0
celkem = 0
def kontrola(event):
global vysledek
global dobre
global celkem
try:
if vysledek == int( vysledekEntry.get() ):
lblOK.config(text='OK')
dobre += 1
else:
lblOK.config(text=';-(')
celkem +=1
# vymažu vstupní pole
vysledekEntry.delete(0,END)
# vypíšu statustiku
lblStat.config(text='{0}/{1}'.format(dobre,celkem))
# po tom, co jsem kontroloval generuji nový příklad
novyPriklad()
except:
lblOK.config(text='Zadej číslo')
`--> stáhnout
V tuto chvíli by aplikace měla být funkční pro násobení. Chybí tedy náhodně vybrat matematickou operaci a poté přidat generování příkladů na sčítání, odčítání a dělení.
Uživatel může výběr matematické operace ovlivnit ve vstupním poli
operaceEntry
, proto toto vstupní pole nejprve načtu a poté z něj náhodně
vyberu jeden znak.
# náhodná operace
vyber=operaceEntry.get()
operace=vyber[ random.randint(0,len(vyber)-1) ]
`--> stáhnout
Uživatel ale může do vstupního pole napsat cokoli, proto je třeba řetězec projít a vymazat z něj všechny znaky, které nejsou kódem matematické operace.
# ošetřím zadání chybných znaků do vstupního pole
new=''
for znak in vyber:
if znak in '+-*:/':
new+=znak
vyber = new
# ošetřím zadání prázdného řetězce do vstupního pole
if vyber=='':
vyber='+-*/'
# umístím kontrolovaný řetězec zpět do vstupního pole
operaceEntry.delete(0,END)
operaceEntry.insert(0,vyber)
`--> stáhnout