четвер, 21 грудня 2017 р.

PyTest | Про те, як я створюю тести.

Доброго часу доби!
Сьогодні пропоную вам навчитися створювати програми для тестування якості знань на прикладі тесту з теми "Табличні величини".

Ну і почнемо з того, що побудуємо алгоритм даної програми. Тобто розіб'ємо програму на частини та вкажемо, що повинно виконуватися на кожній частині.

1. Вікно реєстрації. Учень вводить своє ім'я та прізвище та клас, в якому навчається. Ці дані будуть додаватися до файлу, щоб вчитель зміг потім дізнатися результат учня.


2. Задання. Створити вікно з списком завдань та варіантами відповідей (радіоточки), або передбачити самостійний ввід відповідей.


3. Підрахунок і виведення результату. Виводиться вікно з діаграмою та результатом (у відсотковому співвідношенні). Також буде виводитися кількість завдань на які учень дав правильну відповідь.


Найголовніше - це зуміти побачити кінцевий результат, який ви очікуєте отримати!
Тож тепер почнемо кодити!

1. Створення вікна реєстрації:

----------

from tkinter import *

f=open("result.csv", "a")

tk=Tk()
tk.title("PyTest | Табличні величини")
tk.geometry("500x425")
tk.resizable(0,0)

canv=Canvas(tk, width=300, height=280)
canv.grid(row=0, column=0)

image=PhotoImage(file='logo.png')
canv.create_image(58, 30, anchor=NW, image=image)
canv.create_text(148, 230, text="Програмування в школі", font="Arial 15 bold")
canv.create_text(142, 260, text="Табличні величини", font="Arial 13 italic")

frame=Frame(tk)
frame.grid(row=2, column=0, pady=20)

Label(frame, text="Введіть ваше прізвище та ім'я:").grid(row=0, column=0, padx=10)
name=Entry(frame)
name.grid(row=1, column=0)

Label(frame, text="Введіть клас:").grid(row=0, column=1, padx=20)
form=Entry(frame, width=6)
form.grid(row=1, column=1)

but=Button(tk, text="Розпочати тестування", bg="dark grey", fg="white", command=test)
but.grid(row=3, column=0)

tk.columnconfigure(0, minsize=500)
tk.mainloop()

----------

Пояснення. Спочатку ми створили основне вікно та налаштували його. Створили нове полотно та додали картинку та розмістили її в полотні. Додали текст. Потім слідує створення рамки і вже в ній розміщуються два написи та два текстових поля. Кнопку для запуску алгоритму створення нового вікна розміщуємо нижче.

2. Створення вікон з завданнями:

----------

def test():
f.write(name.get()+";"+form.get()+";")

tk.destroy()
tk.quit()

global ch1, ch2, ch3, ch4, ent5, ent6, ent7, tkt

tkt=Tk()
tkt.resizable(0, 0)
tkt.geometry("900x680")
tkt.title("Завдання")

frame=Frame(tkt)

Label(frame, text="1. Що не може бути представлене у вигляді табличної величини?").grid(row=0, 
column=0, columnspan=4, sticky="w", pady=7)
ch1=IntVar()
ch1_1=Radiobutton(frame, text="Цілі числа на проміжку [-67; 59]", variable=ch1, value=1)
ch1_1.grid(row=1, column=0, sticky="w")
ch1_2=Radiobutton(frame, text="Літери в слові 'Python'", variable=ch1, value=2)
ch1_2.grid(row=2, column=0, sticky="w")
ch1_3=Radiobutton(frame, text="Декілька функцій створення нового вікна", variable=ch1, value=3)
ch1_3.grid(row=3, column=0, sticky="w")
ch1_4=Radiobutton(frame, text="Покази температур за 2016 рік", variable=ch1, value=4)
ch1_4.grid(row=4, column=0, sticky="w")
ch1_5=Radiobutton(frame, text="Немає правильного варіанта", variable=ch1, value=5)
ch1_5.grid(row=5, column=0, sticky="w")

Label(frame, text="Дано список (завдання 2-4):\na=[4, 6, 7, 3, 8, 9, 2, 7, 10]").grid(row=6, 
column=0, columnspan=4, sticky="we", pady=7)

Label(frame, text="2. Для того, щоб отримати елемент 8 потрібно виконати дію:").grid(row=7, 
column=0, columnspan=4, sticky="w", pady=7)
frame1=Frame(frame)
frame1.grid(row=8, column=0, columnspan=4)
ch2=IntVar()
ch2_1=Radiobutton(frame1, text="a[8]", variable=ch2, value=1)
ch2_1.grid(row=0, column=0, sticky="w")
ch2_2=Radiobutton(frame1, text="a(8)", variable=ch2, value=2)
ch2_2.grid(row=0, column=1, sticky="w")
ch2_3=Radiobutton(frame1, text="a[5]", variable=ch2, value=3)
ch2_3.grid(row=0, column=2, sticky="w")
ch2_4=Radiobutton(frame1, text="a[4]", variable=ch2, value=4)
ch2_4.grid(row=0, column=3, sticky="w")
ch2_5=Radiobutton(frame1, text="a(4)", variable=ch2, value=5)
ch2_5.grid(row=0, column=4, sticky="w")

Label(frame, text="3. Для того, щоб отримати елемент 7 потрібно виконати дію:").grid(row=9, 
column=0, columnspan=4, sticky="w", pady=7)
frame2=Frame(frame)
frame2.grid(row=10, column=0, columnspan=4)
ch3=IntVar()
ch3_1=Radiobutton(frame2, text="a[2]", variable=ch3, value=1)
ch3_1.grid(row=0, column=0, sticky="w")
ch3_2=Radiobutton(frame2, text="a[7]", variable=ch3, value=2)
ch3_2.grid(row=0, column=1, sticky="w")
ch3_3=Radiobutton(frame2, text="a[2] або a[7]", variable=ch3, value=3)
ch3_3.grid(row=0, column=2, sticky="w")
ch3_4=Radiobutton(frame2, text="a[3] або a[7]", variable=ch3, value=4)
ch3_4.grid(row=0, column=3, sticky="w")
ch3_5=Radiobutton(frame2, text="a[3] або a[8]", variable=ch3, value=5)
ch3_5.grid(row=0, column=4, sticky="w")

Label(frame, text="4. Для того, щоб отримати зріз [4, 7, 8] потрібно виконати дію:").grid(row=11, 
column=0, columnspan=4, sticky="w", pady=7)
frame3=Frame(frame)
frame3.grid(row=12, column=0, columnspan=4)
ch4=IntVar()
ch4_1=Radiobutton(frame3, text="a[::2]", variable=ch4, value=1)
ch4_1.grid(row=0, column=0, sticky="w")
ch4_2=Radiobutton(frame3, text="a[:5:2]", variable=ch4, value=2)
ch4_2.grid(row=0, column=1, sticky="w")
ch4_3=Radiobutton(frame3, text="a[0]+a[2]+a[4]", variable=ch4, value=3)
ch4_3.grid(row=0, column=2, sticky="w")
ch4_4=Radiobutton(frame3, text="a[:5:-2]", variable=ch4, value=4)
ch4_4.grid(row=0, column=3, sticky="w")
ch4_5=Radiobutton(frame3, text="a[1:5:2]", variable=ch4, value=5)
ch4_5.grid(row=0, column=4, sticky="w")

Label(frame, text="Дано 2 списка (завдання 5-7):\na=[3, -6, 9, 12, -15]\nb=[2, 4, 6, -8, 10]").grid(row=13, 
column=0, columnspan=4, sticky="we", pady=7)

Label(frame, text="5. Що ми отримаємо в результаті викоання дії a[1]+b[2]?").grid(row=14, 
column=0, columnspan=4, sticky="w", pady=5)
ent5=Entry(frame)
ent5.grid(row=15, column=0, columnspan=4)

Label(frame, text="6. Що ми отримаємо в результаті викоання дії a[2:4][0]+a[2:4][1]?").grid(row=16, 
column=0, columnspan=4, sticky="w", pady=5)
ent6=Entry(frame)
ent6.grid(row=17, column=0, columnspan=4)

Label(frame, text="7. Що ми отримаємо в результаті викоання дії (a[3:][0]+a[3:][1])*(b[0]-4)?").grid(row=18, 
column=0, columnspan=4, sticky="w", pady=5)
ent7=Entry(frame)
ent7.grid(row=19, column=0, columnspan=4)

frame.pack()

Button(frame, text="Завершити", bg="dark grey", fg="white", font="12", command=check).grid(row=20, column=0, columnspan=4, pady=20)

tkt.mainloop()

----------

Створення самих запитань та варіантів відповіді доволі примітивне і загалом однакове, але найцікавіша частина цього коду на яку я б хотів звернути увагу це:

----------
def test():
f.write(name.get()+";"+form.get()+";")

tk.destroy()
tk.quit()

global ch1, ch2, ch3, ch4, ent5, ent6, ent7, tkt
...
----------
Зверніть увагу! До файлу який ми створили спочатку додаються дані учня, а потім тільки знищується вікно реєстрації. Це тому, що при видаленні вікна видаляються і всі елементи та змінні пов'язані з ним.
Далі нам потрібно оголосити глобальними змінні, пов'язані з радіоточками та полями для введення відповідей, а також вікно. Це потрібно, щоб підрахувати результат:

----------

def check():
res=0
s=0
if ch1.get()==5:
res=res+1
s=s+1
if ch2.get()==4:
res=res+1
s=s+1
if ch3.get()==3:
res=res+1
s=s+1
if ch4.get()==2:
res=res+1
s=s+1
if ent5.get().strip()=="0":
res=res+1
s=s+1
if ent6.get().strip()=="21":
res=res+1
s=s+1
if ent7.get().strip()=="6":
res=res+2
s=s+1
f.write(str(res)+"\n")

tkt.destroy()
tkt.quit()

tktt=Tk()
tktt.title("Результат")
tktt.resizable(0, 0)

canv=Canvas(tktt, width=102, height=102)
canv.grid(row=0, column=0, pady=10, padx=10)

if res==8:
canv.create_oval([1, 1], [101, 101], fill="green")
else:
canv.create_oval([1, 1], [101, 101], fill="red")
canv.create_arc([1, 1], [101, 101], start=90, extent=-res*45, fill="green")

frame=Frame(tktt)
frame.grid(row=0, column=1, pady=10, padx=10)

Label(frame, text="Ваш результат - "+str((res*100)/8)+"%").grid(row=0, column=0)
Label(frame, text="Правильних відповідей - "+str(s)).grid(row=1, column=0)

tktt.mainloop()

----------

Знову ж нічого цікавого, окрім створення діаграми. На справді це просто коло червоного кольору та сектор зеленого :)

Якщо ви бажаєте завантажити цю програму та подивитися, як вона повинна працювати, перейдіть за посиланням: ПОСИЛАННЯ!!! Нам дуже цікаво скільки балів наберете ви!!! Викладайте свої результати в коменти, або постами в фейсбук з хештегом #pytest

А якщо вам здається, що все написане вище дуже складне, то це зовсім не так! Можливо вам стане в пригоді посібник з програмування для 8-го та 9-го класу :)

Немає коментарів:

Дописати коментар

Динамічне програмування мовою Python

Ця тема не входить в шкільний курс інформатики, проте дуже часто представлена на олімпіаді з програмування. Динамічне програмування - це вж...