Advertisement
Guest User

Untitled

a guest
Dec 6th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.73 KB | None | 0 0
  1. # Declaration of libraries
  2. import sqlite3 # Database
  3. import getpass # Not displaying user input, unfortunately uncontrollable in IDLE's shell
  4. import time # Used to pause the program
  5. from statistics import mean # average score
  6. #### Declaration of variables needed for manipulation of database
  7. db = sqlite3.connect('usernames.db')
  8. c = db.cursor()
  9. ##### Initialise tables if they don't already exist
  10. c.execute("""CREATE TABLE IF NOT EXISTS details(username TEXT, name TEXT, surname TEXT, password TEXT, age INT)""")
  11. c.execute("""CREATE TABLE IF NOT EXISTS questions(subject TEXT, question TEXT, answer1 TEXT, answer2 TEXT, answer3 TEXT, answer4 TEXT, correct TEXT)""")
  12. c.execute("""CREATE TABLE IF NOT EXISTS scores(subject TEXT, username TEXT, score TEXT, totalquestions INT,percentage INT,difficulty TEXT,grade TEXT)""")
  13. db.commit() # Save any changes
  14.  
  15. ######## Functions ##############################
  16. def ADD(data, table):
  17.     #data: list/tuple (HOLDS DATA TO BE ADDED TO THE DATABASE)
  18.     # table: string (USED TO SELECT THE TABLE TO BE ADDED TO)
  19.     if table == "details":
  20.         c.execute("""INSERT INTO details(username, name, surname, password, age) VALUES ('%s','%s','%s','%s','%s')"""%(data[0],data[1],data[2],data[3],data[4]))
  21.         db.commit()  
  22.     if table == "questions":
  23.         c.execute("""INSERT INTO questions(subject, question, answer1, answer2, answer3, answer4, correct) VALUES ('%s','%s','%s','%s','%s','%s','%s')"""%(data[0],data[1],data[2],data[3],data[4],data[5],data[6]))
  24.         db.commit()
  25.     if table == "scores":
  26.         c.execute("""INSERT INTO scores(subject, username, score, totalquestions, percentage, difficulty,grade) VALUES ('%s','%s','%s','%s','%s','%s','%s')"""%(data[0],data[1],data[2],data[3],data[4],data[5],data[6]))
  27.         db.commit()
  28.  
  29. def CHECK(username, password, option):
  30.     # username: string (USERNAME TO BE CHECKED)
  31.     # password: string (PASSWORD TO BE CHECKED FOR OPTION 1 )
  32.     # option: integer (USED TO SELECT EITHER CHECKING FOR ONLY USERNAME (2) OR USERNAME AND PASSWORD
  33.     # RETURNS: bool (whether record exists)
  34.     if option == 1:
  35.         c.execute("""SELECT * FROM DETAILS WHERE username='%s' AND
  36.        password='%s'""" %(username,password))
  37.     if option == 2:
  38.         c.execute("""SELECT * FROM DETAILS WHERE username='%s'"""%(username))
  39.        
  40.     result = c.fetchone() # Returns the first line, it is a list
  41.     if result != None :
  42.         return True
  43.     else:
  44.         return None
  45.  
  46.  
  47. def cAsker(message, check, rangeCheck):
  48.     # message: string (MESSAGE TO BE OUTPUTTED)
  49.     # check: boolean (SET TO TRUE IF NUMBER HAS TO BE IN SPECIFIC RANGE
  50.     # rangeCheck: string (AN EXPRESSION THAT IS EXECUTED, SHOULD CHECK FOR CERTAIN RANGE OF CHOICE)
  51.     # RETURNS: choice
  52.     if check == False:   # Execute this if size of integer doesn't matter
  53.         while True:
  54.             try:
  55.                 choice = int(input(message))
  56.             except ValueError:
  57.                 print("Please enter an integer")
  58.             else:
  59.                 break
  60.     if check == True:
  61.         while True: # Execute this if size of integer does matter
  62.             try:
  63.                 choice = int(input(message))
  64.             except ValueError:
  65.                 print("Please enter an integer")
  66.             else:
  67.                 if not (eval(rangeCheck)): #Inverses rangeCheck, rangeCheck sees if code is not in range
  68.                     break
  69.                 else:
  70.                     print("Please select one of the choices")
  71.     return choice # Function returns the integer
  72.  
  73. def returnGrade(percentage):
  74.     # percentage: integer (PERCENTAGE TO CHECK THE GRADE FOR)
  75.     rounded = round(percentage,-1)
  76.     switcher = {100: "A**", 90: "A*", 80: "A", 70: "B",  60: "C",
  77.                 50: "D",  40: "E",  30: "F",  20: "G", 10: "U",  0: "U-"}
  78.     return switcher.get(rounded,'') #Retrieves the value of the dictionary with the same key as rounded
  79.  
  80.    
  81. #########################################################
  82. #################### SECTION 1 ##########################
  83. # Function that will hold all of the code for the login menu
  84. # RETURNS True if CHECK(username, password, 1) == True OR
  85. #   if username == adminDetails[0] and password == adminDetails[1]
  86. def credentials():
  87.     global ausername # Provides user for scores to be added and retrieved later & admin menu authentication
  88.     #####
  89.     correct = '' # Tracks user input for confirmation
  90.     confirmation = True # Used to keep user in first choice with their consent
  91.     ############### Wipes all variables clean so no previous data gets used #######
  92.     print("======== Start Menu ========")
  93.     option = cAsker("\n1) Register \n2) Login \n>.. ", True,"choice < 1 or choice > 2") # choice option  
  94.  
  95.     if option == 1: # Registration option
  96.             while True: # Presence check on details[0], sname, password
  97.                 details = [input("What is your first name?: "), input("What is your surname?: "),
  98.                            getpass.getpass("What will your password be?: "), cAsker("How old are you?", False,"choice < 0")]
  99.                 if isinstance(details[0], int) == False and isinstance(details[1], int) == False and isinstance(details[2], int) == False:
  100.                     break
  101.             # Carries on with rest of registration only if the user enters inputs
  102.             if correct != "no":
  103.                 # Assigns value of username as normal if there are enough characters
  104.                 if len(details[0]) >= 3:
  105.                     username = (details[0][:3] + str(details)).lower()
  106.                 # Deals with first name being less than 3
  107.                 elif len(details[0]) == 2:
  108.                     username = (details[0] + details[1][0] + str(details)).lower()
  109.                 else:
  110.                     username = (details[0] + details[1][:2] + str(details)).lower()
  111.                
  112.                 data = (username, details[0], details[1], details[2], details[3]) # holds all data to be added to database
  113.                 if CHECK(username, False, 2) == True: # Informs user that username existing
  114.                     print("""Sorry, that username already exists.
  115.                    Please try another name (your middle name?)""")
  116.                 else: # Otherwise add details to the database
  117.                     correct = cAsker(("Username: ",username,"\nFirst name: "+ details[0],"\nSurname: " + details[1] + "Age: ",details[3] + "\n1) Confirm \n2) Decline "), True, "choice < 1 or choice > 3" )
  118.                     if correct == 2: # Leaves option
  119.                         option = 0  
  120.                     elif correct == 1:
  121.                         ADD(data, "details")
  122.                 confirmation = False # Exits this loop.
  123.            
  124.     if option == 2: # Login option
  125.         username = input("What is your username?: ")
  126.         password = getpass.getpass("What is your password?: ")
  127.         print("\n\n")
  128.         print("Authenticating...")
  129.         for x in range(3): # Prints dots for tension and to make it clearer so more user-friendly
  130.             print(".")
  131.             time.sleep(0.5)
  132.         # Checks to see if the username and password are admin credentials, if they are then assign
  133.         # global variable ausername to the current username and return True to move to next loop
  134.         if username == adminDetails[0] and password == adminDetails[1]:
  135.             ausername = username
  136.             return True
  137.        
  138.         if CHECK(username, password, 1) == None: # Code to run if combination not found
  139.             time.sleep(0.5)
  140.             print("That account does not exist. Have you registered?")
  141.             time.sleep(0.5)
  142.         # If username and password exist but are not admin
  143.         elif CHECK(username, password, 1) == True:
  144.             time.sleep(0.5)
  145.             print("Authenticated, welcome back!\n")
  146.             time.sleep(0.5)
  147.             ausername = username
  148.             return True # Move to next loop
  149.            
  150.        
  151. ###########################################################
  152. ################## SECTION 2 ##############################
  153. # Function that will hold all of the code for the main menu
  154. # RETURNS False if choice == 3
  155. def main_menu():
  156.     # Checks if admin credentials have been entered
  157.     if ausername == adminDetails[0]:
  158.         while True:
  159.             choice = admin_menu()
  160.             if choice == 3: # Breaks out of infinite loop if admin menu returns 3
  161.                 break
  162.     else: # Executes if user is not admin
  163.         print("======== Quiz Menu ========")
  164.         choice = cAsker("1) Take a quiz \n2) View your previous quizzes \n3) Log out\n>.. ", True,"choice < 1 or choice > 3")  
  165.     # Option to take a quiz
  166.     if choice == 1:
  167.         print("======== Take a quiz ======")
  168.         choice = cAsker("""1) Music \n2) Computer Science \n>.. """,
  169.                         True,"choice < 1 or choice > 2")  
  170.         difficulty = cAsker("1) Easy \n2) Medium \n3) Hard \n>.. ",
  171.                             True,"choice < 1 or choice > 3")  
  172.         # Sets subjects and informs user of choice
  173.         if choice == 1:
  174.             print("You have chosen to take a Music test.")
  175.             subject = "Music"
  176.         else:
  177.             print("You have chosen to take a Computer Science test.")
  178.             subject = "Computing"
  179.            
  180.         c.execute("SELECT * FROM questions WHERE subject='%s'"%(subject)) # Returns all questions
  181.         confirmation = cAsker("Do you want to continue? \n1) Yes \n2) No \n>..",
  182.                               True, "choice < 1 or choice > 2") # Confirms if user wants to do it
  183.         if confirmation == 1: # Code to execute if user confirmed choices
  184.             totalscore = 0 # Resetting score to 0
  185.             results = c.fetchall() # Stores all questions in variable (2D Array)
  186.             # Changes iteration (number of questions) value depending on
  187.             if difficulty == 3:
  188.                 iterations = len(results)
  189.             elif difficulty == 2:
  190.                 iterations = (len(results) - 5)
  191.             else:
  192.                 iterations = (len(results) - 7)
  193.             for x in range(iterations):
  194.                 print(results[x][1])    
  195.                 for y in range(4):
  196.                     print(results[x][y+2])
  197.                 userAnswer = cAsker(">..", True,"choice > 4 or choice < 1")
  198.                 userAnswer = str(userAnswer)
  199.                 if userAnswer == results[x][6]:
  200.                     totalscore += 1
  201.             percentage = int(round(totalscore / iterations * 100))
  202.             possibleGrade = 100
  203.             if difficulty == 1:
  204.                 possibleGrade = percentage - 20
  205.             elif difficulty == 2:
  206.                 possibleGrade = percentage - 10
  207.  
  208.             userGrade = returnGrade(possibleGrade)
  209.             print("You got: ",totalscore," correct. \n That is ",percentage, "Percent. \n Your Grade is: ",userGrade)
  210.             grades = {1: "Easy",2: "Medium",3:"Hard"}
  211.             difficulty = grades.get(difficulty,'')
  212.             data = (subject,ausername,totalscore,iterations,percentage,difficulty,userGrade)
  213.             ADD(data,"scores")
  214.             choice = 0
  215.         else:
  216.             choice = 0
  217.        
  218.     if choice == 2:
  219.         c.execute("SELECT * FROM scores WHERE username='%s'"%(ausername))
  220.         results = c.fetchall()
  221.         print("======== Scores ===========")
  222.         for x in (results):
  223.             print("\nSubject: ",x[0],"\nDifficulty: ",x[5],"\nScore:" ,x[2],"/",x[3],"\nPercentage: ",round(x[4]),"\nGrade: ",x[6])
  224.         if results == []:
  225.             print("No previous quiz history! \n")
  226.  
  227.     if choice == 3:
  228.         print("\n")
  229.         return False
  230.    
  231. #########################################################
  232. #################### SECTION 3 ##########################
  233.    
  234. def admin_menu():
  235.     print("======== Admin Menu ========")
  236.     choice = cAsker("\n1) Generate report from username \n2) Generate report for topic and difficulty \n3) Logout\n>.. ", True,"choice < 1 or choice > 3")    
  237.     if choice == 1: # Quiz history of a specific user
  238.         username = input("What is the username? \n>.. ")
  239.         c.execute("""SELECT * FROM scores WHERE username='%s'""" %(username))
  240.         results = c.fetchall()
  241.         if results == []: # If there is no quiz history or user doesn't exist
  242.             print("User not found or no previous quizzes have been completed.\n")
  243.         else: # Executes if there are scores
  244.             print("======== Scores ===========")
  245.             for x in results:
  246.                 print("\nSubject: ",x[0],"\nDifficulty: ",x[5],"\nScore:",x[2],"/",x[3],"\nPercentage: ",round(x[4]),"\nGrade: ",x[6])
  247.  
  248.     if choice == 2: # Average score fom a subject & difficulty
  249.         subject = cAsker("Please select a subject to get the average scores from.\n1) Music \n2) Computer Science\n>..", True,"choice < 1 or choice > 2")
  250.         difficulty = cAsker("Please select a difficulty\n1) Easy \n2) Medium \n3) Hard \n>..", True,"choice < 1 or choice > 3")  
  251.         difficulties = {1: "Easy", 2: "Medium", 3: "Hard"}
  252.         difficulty = difficulties.get(difficulty, '')
  253.         # Only returns score column from table
  254.         if subject == 1:
  255.             c.execute("SELECT score FROM scores WHERE subject='Music' AND difficulty='%s'"%(difficulty))
  256.         else:
  257.             c.execute("SELECT score FROM scores WHERE subject='Computing' AND difficulty='%s'"%(difficulty))
  258.         results = c.fetchall()
  259.         # Calculates average score
  260.         if results != []:
  261.             numbers = [int(x) for y in results for x in y]
  262.             average = mean(numbers)
  263.             c.execute('SELECT * FROM scores ORDER BY score DESC')
  264.             results = c.fetchall()
  265.             # Removes all sublists which do not have x[0] == (desired subject)
  266.             if subject == 1:
  267.                 filtered = list(filter(lambda x: x[0] == "Music",results))
  268.             else:
  269.                 filtered = list(filter(lambda x: x[0] == "Computing",results))
  270.             highestScore = filtered[0]
  271.             print("======== Scores ===========")                
  272.             print("Average Score: ",average,"\nHighest Scorer:",highestScore[1],"\nScore: ",highestScore[2],"/",highestScore[3],"\nPercentage: ",round(highestScore[4]),"\nGrade: ",highestScore[6])
  273.                
  274.         else: # Executes if there is no previous history (results == [])
  275.             print("======== Scores ===========")                
  276.             print("No Data available for that!")            
  277.  
  278.     if choice == 3:
  279.         return 3
  280.  
  281.  
  282. ############# Variable Declaration
  283. adminDetails = ["admin","fergus123"]
  284. access = None # Keeps the program inside each section
  285.  
  286.  
  287. ############# Main loop/logic of the code
  288. while True:  
  289.     while access == None:
  290.             access = credentials()
  291.     if main_menu() == False:
  292.         access = None
  293. db.commit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement