Chess grade database controller

Language: Python

Task:

This is part of a group project to create an interface for the chess league, allowing captains to input results on the website and admin to alter data in the databases playerdatabase (a showing all the players and their details), fixturesdatabase (showing the matches between the teams and their dates) and resultsdatabase (showing the results between the teams).

Currently the program has been made up of two classes; Player and Admin. Player allows the access of the player to the features to be controlled (depending on password, username and status) as well as editing players. Admin allows the databases to be edited, entries to be deleted, entries to be added and the databases to be viewed. Player will become a daughter of Admin, allowing certain methods to be inherited and used to prevent duplication of code.

Efficiency and improvement

The areas I would look to improve and expand are:

  1. A way to take incorrectly entered answers (e.g. using try and except)
  2. Changing the Player class to a daughter of Admin
  3. Adding new daughter classes to include viewing fixtures of particular teams
  4. Adding an email method that allows the Admin to create an email
  5. Convert to Java
  6. Use variables that are inputted to methods/classes rather than collecting details through questions. This will allow the details to be collected by other classes that interact with the user by different means (e.g. buttons on a website or GUI)

NB The initial functions are there to create databases that other classes will do in the complete program. Also, end section will be created through other interface classes.

def pairings(pairings_list):
# Shuffles the list so that the first half are lined up next to the second half. This is only used in the first
# round as chess pairings line up the highest graded half against the lowest graded half
temp_list = []
halfway = int(len(pairings_list)/2)
for i in range (0, halfway):
player_one = pairings_list[i]
temp_list.append(player_one)
player_two = pairings_list[i+halfway]
temp_list.append(player_two)
return temp_list# Code to create temporary file for player details
#!!NB incorrect inputs have to be accounted for
def create_player_database():
    import csv
    with open('playersdatabase.csv','w',newline='') as database:
        fieldnames = ['username', 'password', "permission", "grade", "name"]
        writer = csv.DictWriter(database, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerow({'username': 'Hywel862',
                         'password': 'secret',
                         'permission': 'captain',
                        'grade': '1816',
                        'name': 'Hywel Griffiths'})
        writer.writerow({'username': 'Sipho',
                         'password': 'anon',
                         'permission': 'admin',
                         'grade': '1576',
                         'name': 'Sipho Donovan'})
        writer.writerow({'username': 'Travis',
                        'password': 'hello',
                        'permission': 'none',
                         'grade': '850',
                         'name': "Travis O'Sullivan"})
def create_fixture_database():
    import datetime
    import csv
    with open('fixturesdatabase.csv','w',newline='') as database:
        fieldnames = ['home_team','away_team','date']
        writer = csv.DictWriter(database,fieldnames=fieldnames)
        writer.writeheader()
        writer.writerow({'home_team':'Emperors',
                         'away_team':'Morriston A',
                         'date':datetime.datetime(2019,5,13)})
        writer.writerow({'home_team':'University A',
                         'away_team':'Nidum A',
                         'date':datetime.datetime(2019,6,30)})
        writer.writerow({'home_team':'Tribunes',
                         'away_team':'University B',
                         'date':datetime.datetime(2019,4,5)})
def create_results_database():
    #Not actual fields in resultsdatabase
    import csv
    with open('resultsdatabase.csv','w',newline='') as database:
        fieldnames = ['result']
        writer = csv.DictWriter(database,fieldnames=fieldnames)
        writer.writeheader()
        writer.writerow({'result':'win'})
class Player:
    def __init__(self):
        pass
    '''Player class allows information to be extracted from player files'''
    def username_compare(self, username, password):
        import csv
        """method usernameCompare compares username to password to return a boolean. False if the username or
        password is incorrect and true if they match"""
        with open("playersdatabase.csv", "r") as database:
            reader = csv.DictReader(database)
            for row in reader:
                if row['username'] == username:
                    if row['password'] == password:
                        # These print statements will be removed in the actual code
                        print("Permission granted")
                        return True
                    elif row['password'] != password:
                        print("Incorrect password")
                        return False
            print("No such username")
            return False
    def permission_check(self, username, request):
        import csv
        """method to returning a boolean if the requested permission (captain or admin) matches their status"""
        with open("playersdatabase.csv", "r") as database:
            reader = csv.DictReader(database)
            for row in reader:
                if row['username'] == username:
                    if row['permission'] == request:
                        # Two print statements will be removed in actual code
                        print("You have permission to this status")
                        return True
                    print("You do not have permission to this status")
                    return False
            print("No such username")
            return False
    def call(self, username, characteristic):
        import csv
        """method calls any characteristic required"""
        with open("playersdatabase.csv", "r") as database:
            reader = csv.DictReader(database)
            for row in reader:
                if row['username'] == username:
                    return row[characteristic]
            return "No such username"
    def value_editor(self, username, edit, value):
        import csv
        """method to collect a player's name to go up onto the match card"""
        # Open the database file to read
        with open('playersdatabase.csv', 'r') as reader:
            reader = csv.DictReader(reader)
            # Open a temporary file to write
            with open('temp.csv', 'w', newline='') as writer:
                fieldnames = ['username', 'password', "permission", "grade", "name"]
                writer = csv.DictWriter(writer, fieldnames=fieldnames)
                writer.writeheader()
                # Run through the open database lines, writing them in the temp file and testing for the value that
                # need to be changed
                for line in reader:
                    if line['username'] == username and edit == 'grade':
                        writer.writerow({'username': line['username'],
                                         'password': line['password'],
                                         'permission': line['permission'],
                                         'grade': value,
                                         'name': line['name']})
                    # The test code could possibly be reduced by using one piece of code that tested for the required
                    #  value to be changed
                    if line['username'] == username and edit == 'username':
                        writer.writerow({'username': value,
                                         'password': line['password'],
                                         'permission': line['permission'],
                                         'grade': line['grade'],
                                         'name': line['name']})
                    if line['username'] == username and edit == 'password':
                        writer.writerow({'username': line['username'],
                                         'password': value,
                                         'permission': line['permission'],
                                         'grade': line['grade'],
                                         'name': line['name']})
                    if line['username'] == username and edit == 'permission':
                        writer.writerow({'username': line['username'],
                                         'password': line['password'],
                                         'permission': value,
                                         'grade': line['grade'],
                                         'name': line['name']})
                    if line['username'] == username and edit == 'name':
                        writer.writerow({'username': line['username'],
                                         'password': line['password'],
                                         'permission': line['permission'],
                                         'grade': line['grade'],
                                         'name': value})
                    if line['username'] != username:
                        writer.writerow(line)
        with open('temp.csv', 'r') as reader:
            reader = csv.DictReader(reader)
            with open('playersdatabase.csv', 'w', newline='') as writer:
                fieldnames = ['username', 'password', "permission", "grade", "name"]
                writer = csv.DictWriter(writer, fieldnames=fieldnames)
                writer.writeheader()
                for line in reader:
                    writer.writerow(line)
class Admin:
    '''This Class allows administration to interact with the various databases, viewing and editing them'''
    def __init__(self):
        pass
    def check_permission(self):
        #Function to be run when player tries to enter admin interface
        username=input("Please enter your username")
        password=input("Please enter your password")
        if Player.username_compare(self,username,password)== False:
            return False
        if Player.permission_check(self,username,"admin")== False:
            return False
    def view(self, database="all"):
        #Function to view the details of databases. !!!NB This will be edited to view specific entries into a database
        #provided by the daughter classes fixture and stats
        #Uses database_view to show the details of the requested database. 'all' shows them all whilst giving a specific
        #name of a database shows that database. !!!NB This will be handed a specific element to view from other
        #daughter classes.
        if database=="all":
            self.database_view("fixturesdatabase",["home_team","away_team","date"])
            self.database_view("playersdatabase", ["username","password","permission","grade","name"])
            self.database_view("resultsdatabase",["result"])
        else:
            self.database_view(database)
    def create_key_list(self,database):
        if database =="all":
            return
        #Creates a list of the elements. This code is a separate function in order to avoid repeating code for two of the
        #other functions
        if database=="fixturesdatabase":
            key_list = ["home_team","away_team","date"]
        if database=="playersdatabase":
            key_list = ["username","password","permission","grade","name"]
        if database=="resultsdatabase":
            key_list = ["result"]
        return key_list
    def database_view(self,database,key_list=[]):
        #Calls the various lines of the database to view them. !!NB This will be altered to read specific details if
        #called by the daughter classes
        import csv
        #create list of keys
        key_list = self.create_key_list(database)
        #create database name for csv writer
        database_name = database+".csv"
        #print all the database lines
        with open(database_name, 'r') as reader:
            reader = csv.DictReader(reader)
            for line in reader:
                for i in key_list:
                    print (i,line[i],end=" ")
                print("")
    def add_entry(self,database,x = "manual"):
        #Adds an entry to fixtures, results or players. This can be manual (if no third argument is sent) or
        #automatically from the matchcard class is a third argument is provided
        import csv
        #Creates the appropriate list of keywords to go through depending on the database
        key_list = self.create_key_list(database)
        #No third argument has been given so function collects the various required entries
        if x == "manual":
            details_list=[]
            for i in key_list:
                answer = input ("What is the"+i+"?")
                details_list.append(answer)
        #If a third argument has been provided (a list of the details of a result) it uses this as the required
        # details_list
        else:
            details_list=[x]
        #Creates the required database name to be working with
        database_name = database+".csv"
        #Appends the details given
        with open (database_name,'a') as appender:
            writer = csv.writer(appender)
            writer.writerow([])
            writer.writerow (details_list)
    def delete_or_edit(self,function, database):
        #This method allows specific rows to be deleted from the database by creating a temp dictionary and writing over
        #it
        import csv
        #Create the key list
        key_list = self.create_key_list(database)
        #Show the numbered entries in the database
        self.create_numbered_database(key_list,database)
        #Create the database name
        database_name = database+".csv"
        #Create a temporary file according to the function required (deleting or editing a line)
        self.create_temp(function, database_name, key_list)
        #Open the temp csv file to open and write over the old file
        with open(database_name,'w',newline='') as writer_database:
            writer = csv.DictWriter(writer_database,fieldnames=key_list)
            writer.writeheader()
            with open('temp.csv','r') as reader:
                reader = csv.DictReader(reader)
                for row in reader:
                    temp_dict=dict(row)
                    writer.writerow(temp_dict)
    def create_numbered_database(self,key_list,database):
        import csv
        #Show the database with entries
        database_name = database+".csv"
        with open(database_name, 'r') as reader:
            reader = csv.DictReader(reader)
            n=1
            for line in reader:
                for i in key_list:
                    print (n,i,line[i],end=" ")
                print("")
                n+=1
    def create_temp(self,function, database_name, key_list):
        import csv
        #Get the number that the admin wishes to delete
        answer = int(input ("Which entry would you like to" + function + "?"))
        #Opens the database being edited and make a copy of the line
        with open('temp.csv','w', newline='') as writer_database:
            writer=csv.DictWriter(writer_database,fieldnames=key_list)
            writer.writeheader()
            with open(database_name, 'r') as reader:
                reader = csv.DictReader(reader)
                n=1
                for row in reader:
                    #If it is the row chosen and we are deleting it jump the row
                    if n!=answer:
                        temp_dict = dict(row)
                        writer.writerow(temp_dict)
                    if n==answer and function=="edit":
                        key_to_edit = input ("Which category would you like to edit?")
                        new_value = input ("What is the new value?")
                        temp_dict = dict(row)
                        temp_dict[key_to_edit]=new_value
                        writer.writerow(temp_dict)
                    #Otherwise write it into the temporary csv file
                    n+=1
create_fixture_database()
create_player_database()
create_results_database()
class_type = Admin()
while True:
    if class_type.check_permission()!=False:
        while True:
            answer = input ("What would you like to do? View (v), add (a), delete (d), edit (e) or finish (f)")
            if answer == "v":
                database = input ("Which database would you like to see? playersdatabase, fixturesdatabase, resultsdatabase or all")
                print (class_type.view(database))
            if answer == "a":
                database = input ("Which database would you like to add to? playersdatabase, fixturesdatabase or resultsdatabase?")
                class_type.add_entry(database)
            if answer == "d":
                database = input ("Which database would you like to delete from? playersdatabase, fixturesdatabase or resultsdatabase?")
                class_type.delete_or_edit("delete", database)
            if answer == "e":
                database = input("Which database would you like to edit? playersdatabase, fixturesdatabase or resultsdatabase?")
                class_type.delete_or_edit("edit", database)
            if answer == "f":
                break
    else:
        print ("You are not able to enter the interface")