Trying to write strings in a file using a class function - python

I'm trying to write a simple game and need to write some informations in a file. This is how the code looks like so far:
class Player:
def __init__(self, name, password, file):
with open(file) as inputFile:
self.playerAndPw = inputFile.read()
self.name = name
self.password = password
def add(self, name, password, file):
file.write(name + " | " + password)
def __str__(self):
print("The player's name is called " + self.name + "\n")
print("Welcome to Guess My Number!")
start = input("Press 1 for New Account, 2 for Log In: ")
if start == "1":
player = Player
playerID = input("Enter a name: ")
playerPassword = input("Enter a password: ")
fileName = "PlayerAndPassword.txt"
player.add(playerID, playerPassword, fileName)
In the last line there is an exception at the last bracket: "Parameter 'file' unfilled. So the code can't get the information out of the function I'm using in the last line.
Would be great, if someone could help me! Thank you!

This is my attempt to correct your code as best I could. As pointed out in the comments, you need to set player to an instance of the Player class by instantiating it as player = Player(...).
Because you're passing the player's name, password and the file to store credentials in to the Player constructor, you don't need to pass these as arguments to Player.add, which is why I remove all parameters for that.
I should point out that this implementation is very simple and incomplete, designed only to address your immediate issues. My implementation will result in file handles remaining open after each call to the Player constructor. If you opt for this sort of approach, you may want to read the Python documentation on input and output operations.
class Player:
def __init__(self, name, password, fileName):
self.name = name
self.password = password
self.file = open(fileName, mode='a')
def add(self):
self.file.write(self.name + " | " + self.password + '\n')
def __str__(self):
print("The player's name is called " + self.name + "\n")
print("Welcome to Guess My Number!")
start = input("Press 1 for New Account, 2 for Log In: ")
if start == "1":
playerId = input("Enter a name: ")
playerPassword = input("Enter a password: ")
fileName = "PlayerAndPassword.txt"
player = Player(playerId, playerPassword, fileName)
player.add()
Console Output
Welcome to Guess My Number!
Press 1 for New Account, 2 for Log In: 1
Enter a name: Tom
Enter a password: Foo
Welcome to Guess My Number!
Press 1 for New Account, 2 for Log In: 1
Enter a name: Dick
Enter a password: Bar
Welcome to Guess My Number!
Press 1 for New Account, 2 for Log In: 1
Enter a name: Harry
Enter a password: Baz
PlayersAndPasswords.txt
Tom | Foo
Dick | Bar
Harry | Baz

class Player:
def __init__(self, name, password, file):
self.name = name
self.password = password
self.file = open(file, mode='a') #first assign file to self.file(referring to this file)
def add(self): #need to add those parameters as they are already initialized by constructor
self.file.write(self.name + " | " + self.password)
def __str__(self):
print("The player's name is called " + self.name + "\n")
print("Welcome to Guess My Number!")
start = input("Press 1 for New Account, 2 for Log In: ")
if start == "1":
playerID = input("Enter a name: ")
playerPassword = input("Enter a password: ")
fileName = "PlayerAndPassword.txt"
player = Player(playerID, playerPassword, fileName) #create instance with said values
player.add() #call the add function to add

Related

Trouble with saving and loading dictionary with class instances using pickle

New to programming and trying to learn how to store data using pickle. Essentially, what I'm trying to do is create an address book using classes stored in a dictionary. I define the class (Contact). It all worked, but when I tried to introduce pickling to store data from a previous session, I've created 2 errors that I've found so far.
1: If I select to load a previous address book, I cant update or view the class variables. It's almost like there are two different dictionaries.
2: I select not to load a previous address book and add a contact. When I add the contact and try to view the contacts, I'll get an "Unbound Error: local variable 'address book' referenced before assignment"
What am I doing wrong with pickling?
address_book= {}
class Contact:
def __init__(self,first_name,last_name, phone,company):
self.first_name = first_name
self.last_name = last_name
self.phone = phone
self.company = company
def __call__(self):
print("Contact: %s \nPhone #: %s \nCompany: %s" %(self.name,self.phone,self.company))
def erase(entry):
del address_book[entry] # delete address book entry
del entry #delete class instance
def save():
new_file = open("addressBook.pkl", "wb")
saved_address = pickle.dump(address_book, new_file)
new_file.close()
def load():
open_file = open("addressBook.pkl", "rb")
address_book = pickle.load(open_file)
open_file.close()
print(address_book)
return address_book
def add_contact():
first_name = input("Please type the first name of the contact. ")
last_name = input("Please type in the last name of the contact. ")
if " " in first_name or " " in last_name:
print("Please do not add spaces to your first or last name.")
else:
phone = input("Please type the user phone number without hyphens. ")
if not phone.isnumeric():
print("That isn't a valid phone number.")
else:
company = input("Please type the company they work for. ")
contact = Contact(first_name,last_name,phone,company)
address_book[first_name + " " +last_name] = contact #assign key[first and last name] to value[the class instance] in dictionary
def view_contact(entry):
if entry in address_book:
print("First Name: %s" %(address_book[entry].first_name)) #get class variables
print("Last Name: %s" %(address_book[entry].last_name))
print("Phone Number: %s" %(address_book[entry].phone))
print("Company: %s" %(address_book[entry].company))
else:
print("That person isn't in your address book")
def update(entry):
if entry in address_book:
update_choice = input("Would you like to update the first name (f), last name (l), phone (p), or company (c)? ").lower()
if update_choice == "f":
address_book[entry].first_name = input("Please type the updated first name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry] #delete old key
elif update_choice == "l": #update last name
address_book[entry].last_name = input("Please type the updated last name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry]
elif update_choice == "p":
address_book[entry].phone = input("Please type the updated phone number of this contact. ")
elif update_choice == "c":
address_book[entry].company = input("Please type the updated company of this contact. ")
else:
print("That was not valid. Please try again.")
def main():
print("Welcome to your address book!!")
returning_user = input("Would you like to load a previous address book? Y or N ").lower()
if returning_user == "y":
address_book = load()
while True:
choice = input("Please type A:Add, B:View All Contacts, V:View a Contact, D:Delete, U:Update, or X:Exit ").lower()
if choice == "x":
break
elif choice == "a":
add_contact()
elif choice == "b":
if len(address_book) == 0: #error check if no contacts
print("You don't have any friends. PLease go make some and try again later. :(")
else:
for i in address_book:
print(i)
elif choice == "v":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
view = input("Who do you want to view? Please type in their first and last name. ")
view_contact(view)
elif choice == "d":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
contact = input("Please type the first and last name of the person you want to delete ")
if contact in address_book:
erase(contact)
elif choice == "u":
if len(address_book) == 0:
print ("C'mon, you don't know anyone yet. How about you make some friends first?")
else:
choice = input("What is the first and last name of the person you'd like to update? ")
update(choice)
else:
print("That was not valid. Please try again.")
print()
save_book = input("Would you like to save your book? Y or N ").lower()
if save_book == "y":
save()
print("Thanks for using the address book!")
main()

Existing file not appending new record

I am trying to create a file as the header and then open it later to append new records, but it seems I am not doing something correctly, does anyone have an idea?
here is the code below:
I have tried it in several ways to no avail.
file = 'Quizdata5.txt'
users = {}
def header():
headers = ("USERID LOGIN-NAME SURNAME NAME AGE "
" YEAR-GROUP SEX USERNAME\n")
with open(file, 'w') as file1:
file1 .write(headers)
file1.close()
def newUser():
global users
global header
global createLogin
global createPassw
global surname
global name
global age
global y_group
global sex
global z1
createLogin = input("Create login name: ")
if createLogin in users: # check if login name exists
print("\nLogin name already exist, please choose a different name!\n")
else:
createPassw = input("Create password: ")
users[createLogin] = createPassw # add login and password
#return (users[createLogin])
surname = input("Pls enter your surname: ")
name = input("Pls enter ur name: ")
age = input("Pls enter your age: ")
y_group = int(input("Please enter your year group: "))
sex =input("Please enter your sex: ")
print("\nUser created!\n")
print("*********************************")
print(" Your Name is\t" + name, "and it starts with: " + name[0] + "\n")
z1 = createPassw[:3] + age
print(" Your Username is:\t ", z1)
if __name__ =='__main__':
header()
while newUser():
with open(file, 'a') as file2:
rows = ("{:8} {:8} {:8} {:8} {:8} {:8}"
" {:8} {:8} \n".format(createLogin, createPassw,
surname, name, age,
y_group, sex, z1))
file2.write(rows.split())
file2.close()
#enter code here
Working version below. Note that I changed your input statements to raw_input. I'm using Python 2.7. Main things needed:
a choice to exit outside AND inside the while loop
build a list for existing users for the existing username check
fixing your formatting for row
Not splitting your row when you write it
Seems to be working now and ready for more improvements. Build a little and test until working, then build more - saves a ton of time!
file = 'Quizdata5.txt'
users = {}
def header():
headers = "USERID LOGIN-NAME SURNAME NAME AGE YEAR-GROUP SEX USERNAME\n"
with open(file, 'r') as file1:
firstLine = file1.readline()
print firstLine
if firstLine == headers:
print 'Headers present'
return
with open(file, 'w') as file1:
file1.write(headers)
def newUser():
userList = []
with open(file, 'r') as file1:
Lines = file1.readlines()
for line in Lines[1:]:
lineArray = line.split(' ')
userList.append(lineArray[0])
print userList
global users
global header
global createLogin
global createPassw
global surname
global name
global age
global y_group
global sex
global z1
createLogin = raw_input("Create login name or enter 'exit' to quit: ")
if createLogin == 'exit':
return False
while createLogin in userList: # check if login name exists
print("\nLogin name already exist, please choose a different name!\n")
createLogin = raw_input("Create login name or enter 'exit' to quit: ")
createLogin = createLogin.strip()
if createLogin == 'exit':
print('Goodbye for now.')
return False
createPassw = raw_input("Create password: ")
users[createLogin] = createPassw # add login and password
# return (users[createLogin])
surname = raw_input("Pls enter your surname: ")
name = raw_input("Pls enter ur name: ")
age = raw_input("Pls enter your age: ")
y_group = int(raw_input("Please enter your year group: "))
sex = raw_input("Please enter your sex: ")
print("\nUser created!\n")
print("*********************************")
print(" Your Name is\t" + name, "and it starts with: " + name[0] + "\n")
z1 = createPassw[:3] + age
print(" Your Username is:\t ", z1)
return True
if __name__ =='__main__':
header()
while newUser() == True:
with open(file, 'a') as file2:
row ="{a} {b} {c} {d} {e} {f} {g} {h}\n".format(
a=createLogin, b=createPassw, c=surname, d=name, e=age, f=y_group, g=sex, h=z1)
file2.write(row)
Without just rewriting your code outright, your problem is the line
while newUser():
This means call newUser(), and execute the indented code only if the return value of newUser(), evaluated as a boolean, returns True. That is bool(newUser()) is True.
Now the questions are
a) What does newUser() return and,
b) What does bool() mean?
First b: All objects in Python have some "boolean" value associated with it, True or False. For a lot of built-in types their boolean evaluation makes sense. For example the integer 0 is treated as False in a boolean context, while any non-zero integer is treated as True. This is the case in most any programming language with some exceptions.
Similarly an empty list [] is False in a boolean context (which is why we can write things like if not my_list: ... to test if a list is empty) while any non-empty list is treated as True and so on.
As for a:
Your newUser() function doesn't explicitly return and any result, because you don't have a return statement (Tom's solution added some). What you want to do is return a True-ish value when a new user is added, and a False-ish value when no new users are to be added. But since you don't return anything, in fact, the default return value for functions if Python, if you don't explicitly return, is a value called None and it is always False.
So the end result is that the code under your while statement is never run.
If you're ever in doubt about what your code is doing walk through it line by line and see exactly what it's doing--what functions are returning and what values are being assigned to variables--by using the pdb debugger (Google will direct you quickly to some good tutorials). With Python in particular there's no reason to ever be in the dark about what your code is actually doing.

my login method is not being called within my register() and my error in mainError(0 comes up when it's not supposed to

This is my code:
import time
print("Welcome to the quiz")
print("Would you like to login with an existing account or register for a new account?")
def login():
userQ = input("Please enter your username: ")
passQ = input("Please enter your password: ")
#In progress of making...
def register():
print ("Your username will now be created from your first name and age.")
fname = input("Please enter your first name: ")
age = input("Please enter your age: ")
fname2 = fname[:3]
username = fname2 + age
print ("Your username is {}".format(username.upper()))
password = input("Please enter a password for your new account: ")
time.sleep(1.0)
print ("Username: {}".format(username))
print ("Password: {}".format(password))
with open("UserPass.csv", "w") as f:
for line in f:
file = line.split(",")
f.write(username) in file[0]
print ("ACCOUNT CREATED")
login()
class validation(Exception):
def __init__(self, error):
self.error = error
def printError(self):
print ("Error: {} ".format(self.error))
def mainError():
try:
raise validation('Please enter a valid input')
except validation as e:
e.printError()
def Menu():
while True:
options = ["Login", "Register"]
print("Please, choose one of the following options")
num_of_options = len(options)
for i in range(num_of_options):
print("press " + str(i + 1) + " to " + options[i])
try:
uchoice = int(input("? "))
if uchoice == 1:
print("You chose to " + options[uchoice - 1])
login()
break
elif uchoice == 2:
print("You chose to " + options[uchoice - 1])
register()
break
elif (uchoice - 1) > len(options):
mainError()
except ValueError:
mainError()
Menu()
In my code, if the user chooses to register for a new account, it runs the 'register()' method. After the user are their username and password in the method, it writes it to a csv file and then calls the login() method. BUT, instead... it somehow runs the Menu() method instead and ignores my login().
In addition, after the end of the register method is reached, it prints an error message that I made with my 'Class Validation(Exception) and 'mainError()' which I don't want it to - I don't understand why it does this as I have not called mainError().
An example of when I run the code and choose to register:
Welcome to the quiz
Would you like to login with an existing account or register for a new account?
Please, choose one of the following options
press 1 to Login
press 2 to Register
? 2
You chose to Register
Your username will now be created from your first name and age.
Please enter your first name: Siddharth
Please enter your age: 16
Your username is SID16
Please enter a password for your new account: shamrock
Username: Sid16
Password: shamrock
Error: Please enter a valid input
Please, choose one of the following options
press 1 to Login
press 2 to Register
?
As you can see, it goes to the Manu() instead of login() after the registration and before it, prints "Error: Please enter a valid input" when there is no need.
How can I fix this. Thank you!
Change
with open("UserPass.csv", "w") as f:
for line in f:
file = line.split(",")
f.write(username) in file[0]
to
with open('UserPass.csv', 'a') as f:
f.write('whatever text you want to save')

Using a Loop to add objects to a list(python)

I'm trying to use a while loop to add objects to a list.
Here's basically what I want to do:
class x:
pass
choice = raw_input(pick what you want to do)
while(choice!=0):
if(choice==1):
Enter in info for the class:
append object to list (A)
if(choice==2):
print out length of list(A)
if(choice==0):
break
((((other options))))
I can get the object added to the list, but I am stuck at how to add multiple objects to the list in the loop.
Here is the code I have so far:
print "Welcome to the Student Management Program"
class Student:
def __init__ (self, name, age, gender, favclass):
self.name = name
self.age = age
self.gender = gender
self.fac = favclass
choice = int(raw_input("Make a Choice: " ))
while (choice !=0):
if (choice==1):
print("STUDENT")
namer = raw_input("Enter Name: ")
ager = raw_input("Enter Age: ")
sexer = raw_input("Enter Sex: ")
faver = raw_input("Enter Fav: ")
elif(choice==2):
print "TESTING LINE"
elif(choice==3):
print(len(a))
guess=int(raw_input("Make a Choice: "))
s = Student(namer, ager, sexer, faver)
a =[];
a.append(s)
raw_input("Press enter to exit")
Any help would be greatly appreciated!
The problem appears to be that you are reinitializing the list to an empty list in each iteration:
while choice != 0:
...
a = []
a.append(s)
Try moving the initialization above the loop so that it is executed only once.
a = []
while choice != 0:
...
a.append(s)
Auto-incrementing the index in a loop:
myArr[(len(myArr)+1)]={"key":"val"}

Python raw_input into dictionary declared in a class

I am incredibly new to Python and I really need to be able to work this out. I want to be asking the user via raw_input what the module and grade is and then putting this into the dictionary already defined in the Student class as grades. I've got no idea what to do! Thanks in advance!
students = [] # List containing all student objects (the database)
def printMenu():
print "------Main Menu------\n" "1. Add a student\n" "2. Print all students\n" "3. Remove a student\n" "---------------------\n"
class Student:
firstName = ""
lastName = ""
age = 0
studentID = ""
degree = ""
grades = {"Module Name":"","Grade":""}
def setFirstName(self, firstName):
self.firstName = firstName
def getFirstName(self):
return self.firstName
def setLastName(self, lastName):
self.lastName = lastName
def getLastName(self):
return self.lastName
def setDegree(self,degree):
self.degree = degree
def getDegree(self):
return self.degree
def setGrades(self, grades):
self.grades = grades
def getGrades(self):
return self.grades
def setStudentID(self, studentid):
self.studentid = studentid
def getStudentID(self):
return self.studentid
def setAge(self, age):
self.age = age
def getAge(self):
return self.age
def addStudent():
count = 0
firstName = raw_input("Please enter the student's first name: ")
lastName = raw_input("Please enter the student's last name: ")
degree = raw_input("Please enter the student's degree: ")
while count != -1:
student.grades = raw_input("Please enter the student's module name: ")
#student.grades["Grade"] = raw_input("Please enter the grade for %: " % grades)
studentid = raw_input("Please enter the student's ID: ")
age = raw_input("Please enter the student's age: ")
student = Student() # Create a new student object
student.setFirstName(firstName) # Set this student's first name
student.setLastName(lastName)
student.setDegree(degree)
student.setGrades(grades)
student.setStudentID(studentid)
student.setAge(age)
students.append(student) # Add this student to the database
A few things:
Move the initialization of your class attributes into an __init__ method:
Get rid of all the getters and setters as Jeffrey says.
Use a dict that has module names as keys and grades as values:
Some code snippets:
def __init__(self, firstName, lastName, age, studentID, degree):
self.firstName = firstName
self.lastName = lastName
...
self.grades = {}
and:
while True:
module_name = raw_input("Please enter the student's module name: ")
if not module_name:
break
grade = raw_input("Please enter the grade for %s: " % module_name)
student.grades[module_name] = grade

Categories