Guest User

Untitled

a guest
Oct 14th, 2018
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.36 KB | None | 0 0
  1. # EDU-MARKER - TEACHER MODULE
  2. # DANIEL PERKS - 175038
  3.  
  4. # Requirements:
  5. # nltk.download('all')
  6.  
  7.  
  8. # Imports - Importing required modules
  9. import sqlite3 # Used for database structuring and read
  10. import socket # Used for peer-to-peer connection via LAN
  11. import sys # Used for a few system functions, mainly sys.exit - should remove
  12. import datetime # Used to gather and print the current date/time for log
  13. import threading # Used to thread a function for accepting students
  14. import time # Used for its .sleep function to add pauses to code
  15. import random # Used to randomly generate the port/password for tests
  16. import getpass # Gets the users Windows username
  17. import nltk
  18. from nltk.downloader import Downloader # Used for word analysis
  19. import urllib # Used to parse web URLs
  20. import requests # Used to retrieve a webpages content
  21. import wikipedia # Used to query wikipedia
  22. import threading # Used to thread multiple fucntions at the same time
  23. #from fuzzy import start # The file containing the fuzzy logic marking programm
  24. from bs4 import BeautifulSoup # Used to parse and extract data from website requests
  25. from easygui import * # Used for the GUI
  26. #from fuzzy import mark as fuzzy
  27.  
  28. from tkinter import Tk
  29. from contextlib import contextmanager
  30.  
  31. @contextmanager
  32. def tk(timeout=5):
  33. root = Tk() # default root
  34. root.withdraw() # remove from the screen
  35.  
  36. # destroy all widgets in `timeout` seconds
  37. func_id = root.after(int(1000*timeout), root.quit)
  38. try:
  39. yield root
  40. finally: # cleanup
  41. root.after_cancel(func_id) # cancel callback
  42. root.destroy()
  43.  
  44. class Encoder:
  45.  
  46. @staticmethod
  47. def decoder(string):
  48. try:
  49. newstring = string[1:]
  50. newstring = bytearray.fromhex(newstring).decode()
  51. except (ValueError, TypeError):
  52. newstring = string
  53. return newstring
  54.  
  55.  
  56. @staticmethod
  57. def encoder(string):
  58. string = "T" + (string.encode('utf-8')).hex()
  59. return string
  60.  
  61.  
  62. class Network: # Selection of networking tools
  63. def __init__(self):
  64. self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  65. self.host = str(socket.gethostbyname(socket.gethostname()))
  66. self.port = random.randint(9999, 50000)
  67. self.names = {}
  68. self.server.bind((self.host, self.port))
  69. self.clients = {}
  70. self.users = []
  71. self.portOpen = 1
  72.  
  73. def start(self, test, group): # Starts a server on the local IP with a random port
  74. roomno = self.host.split(".")
  75. roomno = roomno[2] + "." + roomno[3]
  76. #roomno = ".".join(roomno)
  77. msg = "You are running the test named: " + \
  78. test.capitalize() + "\nYou are running this for class: " + \
  79. group + "\n\nStudents should use these login details:" \
  80. "\nRoom Number: " + str(roomno) + "\nPassword: " + str(self.port) + "\n\n\n" \
  81. "Press start to start accepting students..."
  82. # todo Make the live student update
  83. clr()
  84. print("Room Number: " + roomno + " Password: " + str(self.port))
  85. print("Press enter to start the test once all students are connected.")
  86. print("IP: " + str(self.host))
  87. print("\nConnected Students: ")
  88. msgbox(msg, "EduMarker - Starting...", ok_button="Start")
  89. self.server.listen(3)
  90. acceptThread = threading.Thread(target=self.accept)
  91. acceptThread.start()
  92. input()
  93. self.portOpen = 0
  94. questions = []
  95. databasedata = database.read_questions(database.testsDB.cursor(), test)
  96. for question in databasedata:
  97. questions.append(question[1])
  98. send = "startx " + str(questions)
  99. send = send.encode()
  100. for user in self.users:
  101. conn = self.clients[user]
  102. conn.sendall(send)
  103. answers = self.recieveAnswers()
  104. name = str(group) + "-" + str(test)
  105. database.saveAnswers(name,answers)
  106. msgbox("All students have completed the test, and their results have been recorded.\n"
  107. "Please use the 'Mark a Test' option on the main menu to mark this test\n\n"
  108. "You will now be sent back to the main menu",
  109. "EduMarker - Test Complete", "Continue")
  110. main.home()
  111. return
  112.  
  113. def recieveAnswers(self):
  114. clients = self.clients
  115. users = self.users
  116. answers = []
  117. while True:
  118. for user in users:
  119. conn = clients[user]
  120. answer = ""
  121. try:
  122. answer = (conn.recv(1024)).decode()
  123. except ConnectionResetError:
  124. msgbox("Student " + str(self.names[user]) + " has left the room.")
  125. if answer != None and answer != "":
  126. #print("Data: " + str(answer))
  127. answers.append(answer)
  128. # answer = answer[1:-1].split(",")
  129. # user = (answer[0])[1:-1]
  130. # question = (answer[1])[1:-1]
  131. # answer = (answer[2])[1:-1]
  132. # print(user)
  133. # print(question)
  134. # print(answer)
  135. # print("")
  136. else:
  137. clients.pop(user)
  138. users.pop(users.index(user))
  139. if len(users) == 0:
  140. return answers
  141.  
  142.  
  143. def accept(self): # Accepts clients for an open server
  144. conn = ""
  145. add = ""
  146. if self.portOpen == 1:
  147. conn, add = self.server.accept()
  148. if self.portOpen == 1:
  149. user = (conn.recv(1024)).decode()
  150. user = user.split(";")
  151. username = user[0]
  152. fullname = user[1]
  153. statement = ('Student ' + fullname + ' connected from user ' + username)
  154. print(statement)
  155. self.users.append(username)
  156. self.names[username] = fullname
  157. self.clients[username] = conn
  158. conn.sendall(b'Connected')
  159. acceptThread = threading.Thread(target=self.accept)
  160. acceptThread.start()
  161.  
  162.  
  163. class Data: # The tools to send and receive questions and answers
  164. def __init__(self):
  165. self.students = []
  166. self.questions = []
  167. self.answers = []
  168. self.testReg = ""
  169. self.testCon = ""
  170. self.groupNo = 0
  171. try:
  172. self.testsDB = sqlite3.connect('questions.db')
  173. self.resultsDB = sqlite3.connect('results.db')
  174. except sqlite3.DatabaseError:
  175. msg = "Unfortunately, a quiz cannot be started at this time.\n" \
  176. "This is likely because the program is already in use on this computer\n" \
  177. "Please close any programs using the file and try again\nDo you want to try again?"
  178. if ynbox(msg, "EduMarker - Error") is True:
  179. main.home()
  180.  
  181. def commit(self):
  182. self.testsDB.commit()
  183. self.resultsDB.commit()
  184.  
  185. def __del__(self):
  186. self.commit()
  187.  
  188. def read_questions_start(self): # reads the questions from the file
  189. cur = self.testsDB.cursor()
  190. cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
  191. quizoptions = cur.fetchall()
  192. quizoptionsconv = []
  193. for test in quizoptions:
  194. if test != ('sqlite_sequence',):
  195. test = Encoder.decoder(str(test)[2:-3])
  196. quizoptionsconv.append(test)
  197. if not quizoptionsconv:
  198. msgbox("There are no tests available right now.\nMake one from the main menu.")
  199. main.home()
  200. else:
  201. quizoptionsconv.append("\n")
  202. quizoptionsconv.append("Make a new test...")
  203. values = choicebox("What test would you like to start?", "EduMark - Setup", quizoptionsconv)
  204. if values == "\n" or values == None or values.strip() == "":
  205. if ynbox("Would you like to cancel the test?", "EduMarker - Exit") is True:
  206. main.home()
  207. else:
  208. self.read_questions_start()
  209. else:
  210. index = quizoptionsconv.index(values)
  211. values = quizoptions[index][0]
  212. self.testReg = values
  213. self.testCon = Encoder.decoder(self.testReg)
  214. try:
  215. cur = self.testsDB.cursor()
  216. cur.execute("SELECT * FROM " + values)
  217. self.questions = cur.fetchall()
  218. except sqlite3.OperationalError:
  219. msg = "Unfortunately, there is not a test with this name. Please try again..."
  220. msgbox(msg, "EduMarker - Error")
  221. self.read_questions_start()
  222. else:
  223. group = multenterbox("Please enter the class taking this test...", "EduMark - Setup", ["Class"])
  224. if group == None:
  225. if ynbox("Are you sure you want to cancel the test?", "EduMarker - Quit") is True:
  226. main.home()
  227. return
  228. else:
  229. self.read_questions_start()
  230. if any([letter == "-" for letter in group[0]]) is True:
  231. msgbox("You used an invalid character: '-'\nPlease choose a name without this character.")
  232. self.read_questions_start()
  233. return
  234. if group is not None:
  235. return group[0]
  236. else:
  237. if ynbox("Would you like to exit the test creator?", "EduMarker - Exit") is True:
  238. main.home()
  239.  
  240. def read_questions(self, db, test):
  241. cursor = db
  242. test = Encoder.encoder(test)
  243. cursor.execute("SELECT * FROM " + test)
  244. data = cursor.fetchall()
  245. return data
  246.  
  247. def read_tables(self, db):
  248. cursor = db.cursor()
  249. cursor.execute("SELECT name FROM sqlite_master WHERE type is 'table'")
  250. data = cursor.fetchall()
  251. return data
  252.  
  253. def read_data(self, db, table):
  254. cursor = db.cursor()
  255. cursor.execute("SELECT * FROM " + table)
  256. data = cursor.fetchall()
  257. return data
  258.  
  259. def saveAnswers(self,name,answers):
  260. cursor = self.resultsDB.cursor()
  261. print(answers)
  262. data = {}
  263. for k in answers:
  264. k = eval(k)
  265. try:
  266. data[k[0]] += [(int(k[1]), k[2])]
  267. except KeyError:
  268. data[k[0]] = [(int(k[1]), k[2])]
  269. # data = str(data)
  270. name = encoder.encoder(name)
  271. cursor.execute("CREATE TABLE " + name + " (`studName` TEXT,`qNo` INTEGER,`qAns` TEXT,"
  272. "PRIMARY KEY(`studName`,`qNo`));")
  273. for stud in data:
  274. for k in data[stud]:
  275. cursor.execute("INSERT INTO " + str(name) + "('studName', 'qNo', 'qAns') VALUES ("''+ str(stud) + "'," + str(k[0]) + ",'" + str(k[1]) + "');")
  276.  
  277.  
  278. class Editor:
  279. def __init__(self):
  280. self.test = None
  281. self.testid = 0
  282. self.testen = ""
  283.  
  284. def create(self):
  285. cursor = database.testsDB.cursor()
  286. title = "EduMark - Test Creation"
  287. name = (multenterbox("What is the name of this test?", title, ["Test Name"]))
  288. if name is None:
  289. if ynbox("Would you like to exit the test creator?", "EduMarker - Exit") is True:
  290. main.home()
  291. else:
  292. self.create()
  293. sys.exit()
  294. elif name == "":
  295. msgbox("You did not enter a test name\n Try again...")
  296. self.create()
  297. elif any([letter == "-" for letter in name]) is True:
  298. msgbox("You used an invalid character: '-'\nPlease choose a name without this character.")
  299. self.create()
  300. return
  301. else:
  302. name = Encoder.encoder(name[0])
  303. try:
  304. cursor.execute("CREATE TABLE " + name + " (`QID` INTEGER PRIMARY KEY UNIQUE,"
  305. "`Question` TEXT, `Answer` TEXT );")
  306. except sqlite3.OperationalError:
  307. msgbox("This test already exsists.\nPlease use a different name or edit the exsisting test.")
  308. self.create()
  309.  
  310. questions = None
  311. while questions is None:
  312. questions = (multenterbox("How many questions will be in this test?"
  313. "", title, ["Number of Questions"]))[0]
  314. if questions is None:
  315. if ynbox("You did not enter a number of questions.\nDo you want to quit the test creator?",
  316. "EduMarker - Quit") is True:
  317. main.home()
  318. else:
  319. self.create()
  320. if questions.isdigit() is False:
  321. if ynbox("You did not enter a number of questions.\nDo you want to quit the test creator?",
  322. "EduMarker - Quit") is True:
  323. main.home()
  324. else:
  325. self.create()
  326. elif int(questions[0]) < 0:
  327. if ynbox("You did not enter a valid number of questions.\nDo you want to quit the test creator?",
  328. "EduMarker - Quit") is True:
  329. main.home()
  330. else:
  331. self.create()
  332. else:
  333. questions = questions[0].lower()
  334. for questionNo in range(int(questions)):
  335. entry = None
  336. while entry is None:
  337. entry = multenterbox("Enter question " + str(questionNo+1) +
  338. "'s details:", title, ["Question", "Answer(s)"])
  339. if entry is None:
  340. if ynbox("Do you want to quit the test editor?", "EduMarker - Quit") is True:
  341. main.home()
  342. if entry != None: # Does not work with 'is' like suggested
  343. exsisting = database.read_tables(database.testsDB)
  344. if name in exsisting:
  345. msgbox("A test with this name already exsists.\n"
  346. "Please pick a different name or edit the exsisting test.")
  347. self.create()
  348. else:
  349. cursor.execute("INSERT INTO " + name + " ('Question', 'Answer') "
  350. "VALUES ('" + entry[0] + "', '" + entry[1] + "')")
  351. database.commit()
  352. else:
  353. msgbox("You did not enter a question and answer for this test\nPlease try again...")
  354. msgbox("Your test has been made successfully\nYou will now go back to the main menu",
  355. "EduMarker - Test Created", ok_button="Continue")
  356. main.home()
  357.  
  358. def editstart(self):
  359. msg = "Pick which test you want to edit?"
  360. title = "EduMark - Test Editor"
  361. choices = database.read_tables(database.testsDB)
  362. choices_new = []
  363. self.test = None
  364. for loop in range(len(choices)):
  365. choice = choices[loop][0]
  366. if choice != "sqlite_sequence":
  367. choice = encoder.decoder(str(choice))
  368. choices_new.append(choice)
  369. if not choices_new:
  370. msgbox("There are no tests available.\nPlease create one from the main menu", "EduMarker - Error")
  371. main.home()
  372. elif len(choices_new) is 1:
  373. self.test = choices_new[0]
  374. msgbox("There is only one test available now\nTherefore you will now begin editing this test"
  375. "\n\nTest name: " + str(self.test))
  376. else:
  377. self.test = (choicebox(msg, title, choices_new))
  378. if self.test is None:
  379. if ynbox("You did not pick a test.\nDo you want to quit the test editor?",
  380. "EduMarker - Quit") is True:
  381. main.home()
  382. else:
  383. self.editstart()
  384. self.testid = choices_new.index(self.test)
  385. self.edit()
  386.  
  387. def edit(self):
  388. db = database.testsDB.cursor()
  389. questions = database.read_questions(db, self.test)
  390. questions_new = []
  391. for question in questions:
  392. questions_new.append(str(question[1]) + " - " + str(question[2]))
  393. if questions_new is []:
  394. questions_new.append("No questions added, click here to add one!")
  395. if len(questions_new) == 1:
  396. questions_new.extend(["", "Add new question...", "Delete this test..."])
  397. else:
  398. questions_new.extend(["", "Add new question...", "Delete a question...", "Delete this test..."])
  399. question = ""
  400. while question == "":
  401. question = choicebox("Which question would you like to edit?", "EduMarker - Edit Test", questions_new)
  402. if question is None:
  403. if ynbox("Are you sure you want to go back to the main menu?", "EduMarker - Quit") is True:
  404. main.home()
  405. return
  406. else:
  407. self.edit()
  408. return
  409. quest = question.split(" - ")
  410. if question == "Add new question..." or question == "No questions added, click here to add one!":
  411. self.addquestion(self.test)
  412. elif question == "Delete a question...":
  413. self.deleteq(self.test)
  414. elif question == "Delete this test...":
  415. self.deletet(self.test)
  416. else:
  417. sql = None
  418. new_question = multenterbox("Please enter the new question and/or answers...",
  419. "EduMarker - Edit Test", ["Question", "Answer"], [quest[0], quest[1]])
  420. if self.test[0] != "T":
  421. self.testen = Encoder.encoder(self.test)
  422. questid = str(questions[questions_new.index(question)][0])
  423. if new_question is None:
  424. if ynbox("Are you sure you want to leave this unedited?", "EduMarker - Close") is True:
  425. main.home()
  426. return
  427. else:
  428. self.edit()
  429. return
  430. if new_question[0] is quest[0] and new_question[1] is quest[1]:
  431. msgbox("You did not change either the question or answer\n"
  432. "Try again or cancel by closing the window.")
  433. elif new_question[0] is quest[0]:
  434. sql = "UPDATE " + str(self.testen) + " SET answer ='" + \
  435. str(new_question[1]) + "' WHERE QID = " + questid
  436. elif new_question[1] is quest[1]:
  437. sql = "UPDATE " + str(self.testen) + " SET question='" + \
  438. str(new_question[0]) + "' WHERE QID = " + questid
  439. elif new_question[0] is None and new_question[1] is None:
  440. msgbox("Both the question and answer box were empty\n"
  441. "Try again or cancel by closing the window.")
  442. self.edit()
  443. else:
  444. sql = "UPDATE " + str(self.testen) + " SET question='" + \
  445. str(new_question[0]) + "', answer ='" + \
  446. str(new_question[1]) + "' WHERE QID = " + questid
  447. db.execute(sql)
  448. database.commit()
  449. self.edit()
  450.  
  451. def addquestion(self, table):
  452. cursor = database.testsDB.cursor()
  453. entry = multenterbox("Enter a new question:", "EduMarker - Add Question", ["Question", "Answer(s)"])
  454. if entry is None:
  455. if ynbox("You didn't enter anything.\nDid you want to quit?"):
  456. main.home()
  457. return
  458. else:
  459. self.edit()
  460. return
  461.  
  462. table = Encoder.encoder(table)
  463. statement = "INSERT INTO " + table + " ('Question', 'Answer') " \
  464. "VALUES ('" + entry[0] + "', '" + entry[1] + "')"
  465. cursor.execute(statement)
  466. database.commit()
  467. self.edit()
  468.  
  469. def deleteq(self, test):
  470. question = None
  471. while question is None:
  472. db = database.testsDB.cursor()
  473. questions = database.read_questions(db, self.test)
  474. questions_new = []
  475. for item in questions:
  476. item = (item[1] + " - " + item[2])
  477. questions_new.append(item)
  478. question = choicebox("Which question would you like to delete?", "EduMark - Delete Question", questions_new)
  479. if question is None:
  480. if ynbox("You didn't choice a question to delete.\nDo you still want to delete a question?"):
  481. self.deleteq(self.test)
  482. return
  483. else:
  484. main.home()
  485. return
  486. sql = "DELETE FROM " + Encoder.encoder(test) + " WHERE QID='" + \
  487. str(questions[questions_new.index(question)][0]) + "';"
  488. db.execute(sql)
  489. database.commit()
  490. self.edit()
  491.  
  492. def deletet(self, table):
  493. cursor = database.testsDB.cursor()
  494. table = Encoder.encoder(table)
  495. sql = "DROP TABLE IF EXISTS " + table
  496. if ynbox("Are you sure you want to delete this table?", "EduMarker - Confirm Delete"):
  497. cursor.execute(sql)
  498. database.commit()
  499. self.editstart()
  500.  
  501.  
  502. class Marking:
  503.  
  504. def markAnswer(self, results, testname, fullname):
  505. answers = {}
  506. questions = database.read_questions(database.testsDB.cursor(), testname)
  507. for i in results:
  508. try:
  509. answers[i[0]][i[1]] = i[2]
  510. except KeyError:
  511. answers[i[0]] = {i[1]: i[2]}
  512. print(questions)
  513. print(answers)
  514.  
  515. def chooseTest(self):
  516. classes = database.read_tables(database.resultsDB)
  517. newclasses = [encoder.decoder(element[0]) for element in classes]
  518. newclasses = [element.split("-")[0] for element in newclasses]
  519. newclasses = list(set(newclasses))
  520. newclasses.append("")
  521. newclasses.append("Create A New Class")
  522. testClass = choicebox("Choose which Class you want to mark...","EduMarker - Choose Class",newclasses)
  523. while testClass is "":
  524. testClass = choicebox("Choose which Class you want to mark...","EduMarker - Choose Class",newclasses)
  525. if testClass == "Create A New Class":
  526. main.home()
  527. testClass = classes[newclasses.index(testClass)][0]
  528. tests = [element[0] for element in classes]
  529. testsEn = []
  530. testsDe = []
  531. testNamesDe = []
  532. for element in tests:
  533. if testClass in element:
  534. testsEn.append(element)
  535. testsDe.append(Encoder.decoder(element))
  536. testNamesDe.append((Encoder.decoder(element)).split("-")[1])
  537. testsPlus = testNamesDe.copy()
  538. testsPlus.append("")
  539. testsPlus.append("Start or Create A New Test")
  540. test = choicebox("Choose which Test you want to mark...","EduMarker - Choose Test",testsPlus)
  541. while test is "":
  542. test = choicebox("Choose which Test you want to mark...","EduMarker - Choose Test",testsPlus)
  543. if test == "Start or Create A New Test":
  544. main.home()
  545. else:
  546. fullName = testsDe[testNamesDe.index(test)]
  547. testName = test
  548. results = database.read_data(database.resultsDB, testClass)
  549. return results, testName, fullName
  550.  
  551. def getWebResults(self,query,marks,level):
  552. pass
  553.  
  554.  
  555. class MainMenu:
  556. def __init__(self):
  557. self.user = getpass.getuser()
  558.  
  559. def home(self):
  560. log("Main menu accessed")
  561. msg = "Welcome to EduMarker, " + self.user + "!\nWhat would you like to do?"
  562. title = "EduMarker - Main Menu"
  563. choices = ["Start A Test - Begin a existing test for an existing class",
  564. "Mark A Test - Mark a completed test for a class", "",
  565. "Create a Test - Create a new test from scratch",
  566. "Edit a Test - Edit the Questions and Answers of an existing test",
  567. "", "Exit the program"]
  568. choice = choicebox(msg, title, choices)
  569. if choice == choices[0]: # Start a test
  570. log("Test Setup Begun")
  571. group = database.read_questions_start() # Read the Questions
  572. network.start(database.testCon, group) # Start the test
  573. elif choice == choices[1]: # Mark a test
  574. log("Marking Begun")
  575. a, b, c = marking.chooseTest()
  576. marking.markAnswer(a,b,c)
  577. elif choice == choices[3]: # Create a test
  578. log("Test Creation Begun")
  579. editor.create()
  580. elif choice == choices[4]: # Edit a test
  581. log("Test Editing Begun")
  582. editor.editstart()
  583. elif choice == choices[6]: # Exit the program
  584. msg = "Are you sure you want to exit?"
  585. if ynbox(msg, "EduMarker - Close") is True:
  586. log("Program Closed via Main Menu option")
  587. sys.exit()
  588. else:
  589. self.home()
  590. elif choice is None:
  591. log("Program Closed by Close Button")
  592. sys.exit()
  593. elif choice == "":
  594. self.home()
  595. else:
  596. msgbox("Honestly, I have no idea how you got here.\nThis is technically unreachable", "The Impossible Error")
  597.  
  598.  
  599. def clr():
  600. print("\n"*80) # Todo remove if unused at end
  601.  
  602. def log(statement):
  603. logfile = open("log.txt","a")
  604. timeRec = datetime.datetime.now()
  605. string = "\n- " + str(timeRec) + " - " + str(statement)
  606. logfile.write(string)
  607. logfile.close()
  608.  
  609. def startEduMark():
  610. logfile = open("log.txt", "a")
  611. timeRec = datetime.datetime.now()
  612. string = "\n- " + str(timeRec) + " - NEW INSTANCE OF PROGRAM STARTED"
  613. logfile.write(string)
  614. logfile.close()
  615. #marking.chooseTest()
  616. #try:
  617. main.home()
  618. #except Exception as e:
  619. #msgbox("An error occured, please try again...","EduMarker - Error")
  620. #log("ERROR: Crash occured: " + str(e))
  621.  
  622. # TODO PEP8
  623.  
  624. def download():
  625. nltk.download('punkt')
  626. nltk.download('averaged_perceptron_tagger')
  627.  
  628. network = Network()
  629. database = Data()
  630. editor = Editor()
  631. marking = Marking()
  632. encoder = Encoder()
  633. main = MainMenu()
  634. d = Downloader()
  635. if not d.is_installed('punkt') or not d.is_installed('averaged_perceptron_tagger'):
  636. p1 = threading.Thread(target=download, daemon=True)
  637. p1.start()
  638. msgbox(" PERFORMING A ONE TIME INITAL SETUP\n ------------------------------------------------\n\nPlease wait while some packages are downloaded that are required for this program to run.\nThe download should not take more than a few minutes.\n\nYou can close this popupm, the program will start when the download is complete.")
  639. while True:
  640. if p1.is_alive() is False:
  641. startEduMark()
  642. break
  643. else:
  644. startEduMark()
  645.  
  646. # ORDER OF RUNNING #
  647. # Retrieve Q&As
  648. # Start server
  649. # Connect students
  650. # Run test
  651.  
  652. # todo add exits for all easygui
  653. # todo fix missing test when starting one
Add Comment
Please, Sign In to add comment