I am trying to create a gradingsystem for a UNI project.
we are told to have 3 global lists:
Emner = ["INFO100","INFO104","INFO110","INFO150","INFO125"]
FagKoder = [["Informasjonsvitenskap","INF"],["Kognitiv vitenskap","KVT"]
Karakterer=[["INFO100","C"],["INFO104","B"],["INFO110","E"]]
With these lists we are suppost to create a way to view the subjects(Emner), with grades from Karakterer, but we should also be able to view subjects without grades. It should be displayed like this:
We should also be able to add new subjects in (Emner) and add new Grades in (Karakterer). All of this should be displayed as in the picture above.
I have been trying all different kind of ways of doing this, but i keep returning to one of two problems. Either im not able to print a subject without a grade, or if i add a new subject(Emne), and want to add a grade(Karakter) i am not able to place it to the right Subject, as it just saves at the first one without a grade.
hope anyone can help me with this, going crazy here!
Code i have so far:
def emneliste():
global Emner
global Karakterer
emne,kar = zip(*Karakterer)
ans = [list(filter(None, i)) for i in itertools.zip_longest(Emner,kar)]
def LeggTilEmne():
global Karakterer
global Emner
nyttEmne = input("Skriv ny emnekode (4Bokstaver + 3 tall): ")
if nyttEmne not in Emner:
while re.match('^[A-Å]{3,4}[0-9]{3}$',nyttEmne):
Emner.append(nyttEmne)
print(nyttEmne + " Er lagt til!")
start()
print("Feil format")
LeggTilEmne()
else:
print("Dette Emnet er allerede i listen din")
start()
def SettKarakter():
global Karakterer
global Emner
VelgEmne = input("Hvilke emne? ")
Emne,Karakter = zip(*Karakterer)
if str(VelgEmne) not in str(Emner):
print("Dette faget er ikke i din liste")
feil = input("om du heller ønsket å opprette fag trykk 2, ellers trykk enter ")
if feil == str(2):
LeggTilEmne()
else:
start()
else:
if str(VelgEmne) in str(Karakterer):
index = Karakterer.index([VelgEmne,"C"])
Karakterer.pop(index)
SettKar = input("Karakter? ")
Emner.append([VelgEmne,SettKar])
print("Karakter " + SettKar + " Er Lagt til i " + VelgEmne)
start()
else:
SettKar = input("Karakter? ")
if str(VelgEmne) in str(Emner):
index = Emner.index(VelgEmne)
print(index)
Emner.pop(index)
Emner.insert(index,[VelgEmne,SettKar])
print("Karakter " + SettKar + " Er Lagt til i " + VelgEmne)
start()
else:
print("Virker Ikke")
start()
You can make Karakterer a dict instead so that you can iterate through the subjects in Emner and efficiently look up if a subject is in Karakterer with the in operator:
Karakterer = dict(Karakterer)
for subject in Emner:
print(*([subject] + ([Karakterer[subject]] if subject in Karakterer else [])))
This outputs:
INFO100 C
INFO104 B
INFO110 E
INFO150
INFO125
Here's an updated GradeHandler class demo. I tried to allow for updating grades, removing subjects, etc.:
__name__ = 'DEMO'
class GradeHandler(object):
EMNER = ["INFO100","INFO104","INFO110","INFO150","INFO125"]
FAGKODER= [["Informasjonsvitenskap","INF"],["Kognitiv vitenskap","KVT"]]
KARAKTERER = [["INFO100","C"],["INFO104","B"],["INFO110","E"]]
def __init__(self):
self.Emner = self.EMNER
self.FagKoder = self.FAGKODER
self.Karakterer = self.KARAKTERER
self.__create_grade_dict()
def remove_subject(self, subject_name):
"""
Remove a subject ot the classes class list variable.
"""
try:
self.Emner = [i for i in self.EMNER if i != subject_name]
self.__create_grade_dict()
except ValueError:
pass
def add_subject(self, subject_name):
"""
Append a subject ot the classes class list variable.
"""
if not subject_name in Emner:
self.Emner.append(subject_name)
self.__create_grade_dict()
def __create_grade_dict(self, grade_dict=None):
"""
Split grades matrix into separate parts; Create and set a dictionary of values.
"""
if grade_dict is None:
self.grade_dict = dict()
sub, grade = zip(*self.Karakterer)
karakterer_dict = {k:v for k, v in list(zip(sub, grade))}
for i in self.Emner:
if i in karakterer_dict.keys():
self.grade_dict[i] = karakterer_dict[i]
else:
self.grade_dict[i] = ''
def update_grade(self, subject_name, grade='A'):
"""
Update a grade in the grade dictionary.
Will also add a subject if not alrady in the dictionary.
"""
try:
self.grade_dict[subject_name] = grade
except (KeyError, ValueError):
pass
def print_grades(self, subject_name=None):
"""
Print dictionary results.
"""
if subject_name is None:
for k, v in self.grade_dict.items():
print('{} {}'.format(k, v))
else:
if subject_name in self.grade_dict.keys():
print('{} {}'.format(subject_name, self.grade_dict[subject_name]))
if __name__ == 'DEMO':
### Create an instance of the GradeHandler and print initial grades.
gh = GradeHandler()
gh.print_grades()
### Append a class
gh.add_subject('GE0124')
gh.print_grades()
### Add grade
gh.update_grade('GE0124', 'B+')
gh.print_grades()
### Update grades
gh.update_grade('GE0124', 'A-')
gh.print_grades()
### Remove subject (will also remove grade.
gh.remove_subject('GE0124')
gh.print_grades()
Related
I would like to make a list that stores all objects of the JoJo class in a list according to the desired amount of users.
Example: If I want to create two users of the JoJo class, the code will allow me to enter the name and stand of these users and print them at the end of the code. The necessary changes for this will be on the main.py page.
jojo.py
class JoJo:
# Construct
def __init__(self):
self.status_stand = False
# Destruct
def __del__(self):
print (f"The user {self.getName()} was deleted by the destruct.")
# Getter
def getName(self): return self.name
def getStand(self): return self.stand
# Setter
def setName(self, noma): self.name = name
def setStand(self, stand): self.stand = stand
# Method activeStand()
def activeStand(self):
if self.status_stand:
print(f"{self.getStand()} is already invoked.")
else:
self.status_stand = True
print(f"{self.getStand()} was invoked.")
# Méthod desactiveStand()
def desactiveStand(self):
if self.status_stand == False:
print(f"{self.getStand()} is already hidden.")
else:
self.status_stand = False
print(f"{self.getStand()} was hidden.")
# Method talk()
def talk(self):
print(f"Name: {self.getName()} | Stand: {self.getStand()}")
print ("Stand status: " + {True: "Active.", False: "Inactive."}[self.status_stand])
self.activeStand() if self.status_stand else self.desactiveStand()
main.py
from jojo import JoJo
jojo = JoJo()
while True:
name = str(input("Enter username: "))
if (len(nome.strip()) <= 0):
print("Username cannot be empty.")
else:
jojo.setNome(name.title())
break
while True:
stand = str(input(f"Enter the name of the {jojo.getName()} stand: "))
if (len(stand.strip()) <= 0):
print(f"The name of {jojo.getNome()} stand cannot be empty.")
else:
jojo.setStand(stand.title())
break
jojo.talk()
del jojo
All you need is a list object. Assuming we accept user names until a blank value tells us to stop:
jojo_list = list()
while True:
name = input("Enter username: ")
if name.strip() == '':
break
jojo = JoJo()
jojo.setName(name.strip().title())
jojo_list.append(jojo)
Now you can simply loop over your list of jojo objects and do things to them:
for jojo in jojo_list:
print(jojo.getName())
Details on list objects: https://docs.python.org/3/tutorial/datastructures.html
I'm looking at this example and I want to figure out how can I search up a name instead of the ID, then display all the information for the name? For example if it has the ID of 1, name: Bob, department: sales, and job title: manager. If we search up "Bob", everything will display. Sorry this is long.
class Employee:
def __init__(self, name, ID, department, job_title):
self.__name = name
self.__ID = ID
self.__dept = department
self.__job = job_title
def set_name(self, name):
self.__name = name
def set_department(self, department):
self.__dept = department
def set_job_title(self, job_title):
self.__job = job_title
def get_name(self):
return self.__name
def get_ID_number(self):
return self.__ID
def get_department(self):
return self.__dept
def get_job_title(self):
return self.__job
def __str__(self):
return 'Name: ' + self.__name + '\n' + \
'ID Number: ' + str(self.__ID) + '\n' + \
'Department: ' + self.__dept + '\n' + \
'Job Title: ' + self.__job
import pickle
def pickle_it(employees):
# Open file in binary write mode
output_file = open('employees.dat', 'wb')
# Write the data to the file
pickle.dump(employees, output_file)
# Close the file
output_file.close()
def unpickle_it():
try:
# Attempt to open file in binary read mode
input_file = open('employees.dat', 'rb')
except IOError:
# If the file doesn't exist, then create it by opening using write
# mode. Then just close and reopen in binary read mode.
file = open('employees.dat', 'wb')
file.close()
input_file = open('employees.dat', 'rb')
# Load the employees dictionary or create an empty dictionary if file is
# empty
try:
employees = pickle.load(input_file)
except:
employees = {}
# Close the file
input_file.close()
# Return the employees dictionary
return employees
import menu_choices
import save_load_dict
# Global constants for menu choices
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def main():
employees = save_load_dict.unpickle_it()
choice = menu_choices.get_menu_choice()
while choice != QUIT:
if choice == LOOK_UP:
menu_choices.look_up(employees)
elif choice == ADD:
menu_choices.add(employees)
elif choice == CHANGE:
menu_choices.change(employees)
elif choice == DELETE:
menu_choices.delete(employees)
choice = menu_choices.get_menu_choice()
save_load_dict.pickle_it(employees)
main()
import employee_class
# Global constants for menu choices
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def get_menu_choice():
print('\n\033[4m' + 'Employee Directory' + '\033[0m')
print('1. Look up an employee')
print('2. Add a new employee')
print('3. Edit an employee\'s information')
print('4. Delete an employee')
print('5. Quit\n')
# Get the user's choice.
choice = int(input('Enter your choice: '))
# Validate the choice.
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a valid choice: '))
# return the user's choice.
return choice
# The look_up function looks up an employee and displays their information.
def look_up(employees):
# Get a name to look up.
ID = input('Enter an employee ID number: ')
# Look it up in the dictionary.
if ID in employees:
print(employees[ID])
else:
print('That ID number is not found.')
# The add function adds a new entry into the dictionary.
def add(employees):
# Get employee information.
name = input('Enter the employee\'s name: ')
ID = input('Enter the employee\'s ID number: ')
department = input('Enter the employee\'s department: ')
job_title = input('Enter the employee\'s job title: ')
# If the name does not exist, add it.
if ID not in employees:
employees[ID] = employee_class.Employee(name, ID, department, \
job_title)
else:
print('An entry with that ID number already exists.')
Your question heading asks for how to search using email while the class Employee has no email attribute.
To search using other attribute like Name:
Though the code snippets you pasted doesn't define what employees object is, it's a dict mapping between id and corresponding Employee object.
If you only need to search by name, you can make the employees dictionary as a mapping between Name and Employee objects (list, as multiple employee can have same name).
If you need a more dynamic solution that lets you search by just about anything, then you need to match with all attributes of each Employee object. And also will need to take care of case insensitivity in search.
def look_up(employees):
# Get any searchtext to lookup
searchtext = input('Enter search query to lookup')
matches = [emp for emp in employees.values()
if searchtext.lower() in [
emp.get_name().lower(),
emp.get_ID_number(), # Add .lower() if needed
emp.get_department().lower(), #.lower() for case insensitive match
emp.get_job_title().lower()
]
]
if not matches:
print(f'No employee matches any attribute for searchtext {searchtext}')
return None
# If there are valid matches
print(matches)
Eliminate any of the above fields if not needed.
You can go more crazier in terms of matching the string with partial matches like doing searchtext in candidate for candidate in [emp.<some_attributes>,..] or use levenshtein distance.
You'll need to take into account that two employees could have the same name. The following code (adapted from your existing look_up function) will return all the employees with the name specified, or a message that there are no employees with that name :
# The look_up function looks up an employee by name and displays their information.
def look_up_by_name(employees):
# Get a name to look up.
name = input('Enter an employee Name: ')
matches = [emp for emp in employees if emp['name'] == name]
if len(matches) == 0:
print('No employees with name "{}" found'.format(name))
else:
for m in matches:
print(m)
Whenever I try to display the Firstname with first initial attached to the end, I get an out of string index range error!
def ForeName():
return raw_input("Please enter your Forename: ")
def MiddleName():
return raw_input("please enter your middle name, if none leave blank: ")
def LastName():
return raw_input("Please enter your last name: ")
def Test():
ForeNameT = ForeName()
MiddleNameT = MiddleName()
LastNameT = LastName()
if not MiddleNameT:
first_username = ForeNameT[0:] + LastNameT[0]
elif ForeNameT:
first_username = ForeNameT[0:][0] #i want to display the first name with the initial of the first name attached to the end of the first name.
else:
first_username = ForeNameT[0:] + MiddleNameT[0]
return first_username
print Test()
You can add an argument to Test function by doing def Test(name_method): and then set if to if name_method == 'without_middlename':.
Try to figure out yourself what you would change print Test() to.
I think i know what you are trying to do, try changing your Test function:
def Test():
ForeNameT = ForeName()
MiddleNameT = MiddleName()
LastNameT = LastName()
if not MiddleNameT:
first_username = ForeNameT + LastNameT
else:
first_username = ForeNameT + MiddleNameT + LastNameT
return first_username
notice the changes to the variable names vs. the function names and the return value so print has something to actually print
This is a smaller portion of the main code I have been writing. Depending on user selection they can add player informationa and then print the information from the dictionary player roster. I want to store the information and then print in this format but I havent been able to figure out how to do this.
Name ****
Phone Number ****
Jersey Number ****
Im new to dictionaries but I have spent hours reading and searching over the past couple of days about dictionaries and have tried several different ways to do this but failed. I have gotten the closest the way I have it setup now but it still doesnt work right. I feel like I am storing the information incorrectly into the dictionary for starters, any help would be greatly appreciated.
player_roster = {}
def display_roster(self): #Print Roster
if len(player_roster) != 0:
for x in player_roster.keys():
print('Name:', x, 'Phone Number:', player_roster[x])
else: #Print No One on Roster
len(player_roster) == []
print('No names have been entered:')
def add_player(self,): #Enter Members Name
name = input('Enter New Players Name:')
phone_number = input('Enter Players Phone Number:')
jersey_number = int(input('Enter Players Jersey Number'))
player_roster[name] = phone_number, 'Jersey Number', jersey_number
#If I input Toby as Name 444-444 as Phone Number and 3 as Jersey number it outputs like this
Name: Toby Phone Number: ('444-4444', 'Jersey Number', 3)
# I would like it to output like
Name: Toby
Phone Number: 444-4444
Jersey Number: 3
There are some things i would change in your code but to keep this close to what you asked for take a look at this:
def display_roster():
if len(player_roster) != 0:
for x in player_roster.keys():
print('Name:', x)
print('Phone Number:', player_roster[x][0])
print('Jersey Number:', player_roster[x][1])
else:
print('Roster is empty.')
return
player_roster = {}
def add_player():
name = input('Enter New Players Name:\t')
phone_number = input('Enter Players Phone Number:\t')
jersey_number = int(input('Enter Players Jersey Number:\t'))
player_roster[name] = [phone_number, jersey_number]
return
add_player()
display_roster()
# PRINTS:
#Name: Toby
#Phone Number: 444-4444
#Jersey Number: 3
Printing in multiple lines gives you the result you want. As stated in the comments this can also be done with a single print() statement but i do not think compact code makes much difference to you yet.
Further, this len(self.player_roster) == [] line does not make sense. This is as good as simply writing True in a line. The "emptiness" of the team is checked by the else:.
Finally, i would slightly change the way players are stored in the "Roster" dictionary and have it like this: {"Toby": ['444-4444', 3], ...}
I would propose that you replace the print statement to this:
print(" Name: %s \n Phone Number: %s \n Jersey Number: %d") % player_roster[x]
You're pretty much there. The below modification would allow you to print as you need (and is slightly more readable):
class PlayerDictionary():
def __init__(self):
pass
player_roster = {}
def display_roster(self): #Print Roster
if len(self.player_roster) != 0:
for key, value in self.player_roster.iteritems():
print(str(key) + ": " + str(value))
else: #Print No One on Roster
len(self.player_roster) == []
print('No names have been entered:')
def add_player(self,):
self.player_roster['Name'] = input('Enter New Players Name:')
self.player_roster['Phone Number'] = input('Enter Players Phone Number:')
self.player_roster['Jersey Number'] = int(input('Enter Players Jersey Number'))
if __name__ == "__main__":
player = PlayerDictionary()
player.add_player()
player.display_roster()
A slightly more maintainable solution would be to create a class for Player. Set the properties on the object and overload the str function e.g.
class Player(object):
def __init__(self):
self.__name = ""
self.__phone_number = ""
self.__jersey_number = ""
#property
def name(self):
return self.__name
#property
def phone_number(self):
return self.__phone_number
#property
def jersey_number(self):
return self.__jersey_number
#name.setter
def name(self, val):
self.__name = val
#phone_number.setter
def phone_number(self, val):
self.__phone_number = val
#jersey_number.setter
def jersey_number(self, val):
self.__jersey_number = val
def __str__(self):
return ("Name: %s\nPhone Number: %s\nJersey Number: %s" % (str(self.__name), str(self.__phone_number), str(self.__jersey_number)))
if __name__ == "__main__":
player = Player()
player.name = input('Enter New Players Name:')
player.phone_number = input('Enter Players Phone Number:')
player.jersey_number = int(input('Enter Players Jersey Number'))
print(player)
I have the following code:
#gets the filename from the user
b= input("Please enter a file name to be opened: ")
a = (b+".txt")
#main data storage and other boolean options
data =[]
result1 =[]
on = True
#File reading in main body with try and except functionality.
try:
check = open(a, 'r')
line =check.readlines()
for items in line:
breakup= items.split()
number, salary, position, first, oname1, oname2, last = breakup
data.append(tuple([last, first + ' ' + oname1 + ' ' + oname2, number, position, salary]))
except IOError as e :
print("Failed to open", fileName)
#Employee creation function, takes the line and stores it in the correct position.
def employee_creation():
result = [((item[0] +", "+ item[1]).ljust(30), int(item[2]), item[3].ljust(15), int(item[4])) for item in data]
for items in result:
result1.append((items[0][0:30], format(items[1], "^5d"), items[2][0:15], "£"+format((items[3]),"<8d")))
return(result)
employee_creation()
print(result)
while on == True:
print("Please select what option you would like to use to search for employees:")
option = int(input("""
1 - Salary (X to X)
2 - Job Titlle
3 - Name, Payroll Number
:"""))
if option == 1:
start = input("What range would you like to start from: ")
end = input("What is the maximum range you would like :")
for items in result:
print(items[3])
if items[3]>start and items[3]<end:
print(items)
else:
print("No employees with this information can be found")
on= False
else:
on= False
However my def employee_creation() doesn't actually return result. I need it to make it a global variable so that I can use it to launch personal querys against the data.
Can anyone see why its not working?
No need to use the evil global variables. You forgot to store the result of your function to another variable.
def employee_creation():
result = [((item[0] +", "+ item[1]).ljust(30), int(item[2]), item[3].ljust(15), int(item[4])) for item in data]
for items in result:
result1.append((items[0][0:30], format(items[1], "^5d"), items[2][0:15], "£"+format((items[3]),"<8d")))
return result # no need for () here
result = employee_creation() # store the return value of your function
print(result)