from database import usernames
class names():
def __init__(self, name):
self.name = name
def name_in_use(self):
if self.name in usernames:
print(f"Sorry {self.name} is already taken. Please come up with a different username.")
name = names(input("How should we call you? ").capitalize())
name.name_in_use()
else:
print(f"Welcome, {self.name}!")
def new_user():
user_answer = input("Are you a new user? [y/n] ")
if user_answer == "y":
name = names(input("How should we call you? ").capitalize())
name.name_in_use()
else:
old_user = input("What is your username? ").capitalize()
print(f"Welcome, {old_user}!")
return
new_user()
How do I extract local name variable from class if it goes into else under name_in_use()?
I tried so many different ways but once outside of function python doesn't see it.
If an instance of names is supposed to use a unique name, that is something that should be enforced either in __init__, or better yet, before you call __init__. Use a class method to verify the name first.
class Name:
used_names = {}
def __init__(self, name):
self.name = name
self.used_names.add(name)
#classmethod
def from_unique_name(cls):
while True:
name = input("How should we call you?")
if name not in used_names:
break
print(f"Sorry {name} is already taken. Please come up with a different username.")
return cls(name)
# Returns an instance of Name or None
def new_user():
user_answer = input("Are you a new user? [y/n] ")
if user_answer == "y":
return Name.from_unique_name()
else:
old_user = input("What is your username? ").capitalize()
if old_user in Name.used_names:
print(f"Welcome, {old_user}!")
return Name(old_user)
else:
print("No user by the name of {old_user}")
user = new_user()
A couple of points to keep in mind:
If multiple threads could be creating new users, you should use a lock to make sure only one thread can append to Name.used_names at a time, and that no other thread can read from it while another thread is updating it.
new_user could also be a class method.
I find few problems in your code.
name_in_use function is recursive with no breaking condition
Code is repeating in new_user functions as well as name_in_use function inside the class
Return statements are missing
Here is the code I propose (Not tested but should work fine)
from database import usernames
class names():
def __init__(self, name):
self.name = name
def name_in_use(self):
if self.name in usernames:
print(f"Sorry {self.name} is already taken. Please come up with a different username.")
return None
else:
return self.name
def new_user():
user_answer = input("Are you a new user? [y/n] ")
if user_answer == "y":
while True:
name = names(input("How should we call you? ").capitalize())
new_name = name.name_in_use()
if new_name:
print(f"Welcome, {new_name}!")
break
else:
user_answer1 = input("You want to try again? [y/n] ")
if user_answer1 == "n":
break
else:
old_user = input("What is your username? ").capitalize()
print(f"Welcome, {old_user}!")
return
Related
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()
I am trying to create a program that uses a class to create accounts and then allow users to log in to accounts. It is not meant to be secure in any way, just for me to learn. I have a problem where I would like to create a object of the class with the parameters name, username, and password. I would like the objects name to be the username that is entered by the user when it is being defined. The problem I have is when the user tries to log in to the account it says that the string entered by the user has no relation to the class. I am not sure if this is because of the login function or the register function or both.
class User:
def __init__(self, name, username, password):
self.name = name
self.username = username
self.password = password
self.loggedIn = True
def home():
print("Login, Register")
a = input("What would you like to do: ")
if(a == "register" or a == "Register"):
register()
elif(a == "Login" or a == "login"):
login()
else:
print("Choose a valid option")
home()
def register():
n = input("Name: ")
u = input("Username: ")
p = input("Password: ")
u = User(n, u, p)
print("Welcome, " + u.name)
home()
def login():
l = input("Username: ")
l2 = input("Password")
if(l2 == l.password):
print("Welcome, " + l.name)
else:
print("Incorrect username or password")
login()
home()
home()
I think I have something that will work for you for one go. But I think that because we are creating u = User(n, u, p) in the register function it is a local variable and so when the function gets called again it will replace "u" with a new instance of the class and the old one is erased for lack of better words. So in other words, the class isn't being really being utilized properly. I could be wrong about this though. I know this isn't the best answer but I hope it helps with troubleshooting. (im still learning about classes myself)
class User:
def __init__(self, name, username, password):
self.name = name
self.username = username
self.password = password
self.loggedIn = True
def home(user):
print("Login, Register")
a = input("What would you like to do: ")
if(a == "register" or a == "Register"):
register()
elif(a == "Login" or a == "login"):
login(user)
else:
print("Choose a valid option")
home('')
def register():
n = input("Name: ")
u = input("Username: ")
p = input("Password: ")
u = User(n, u, p)
print("Welcome, " + u.name)
home(u)
def login(user):
l = input("Username: ")
l2 = input("Password")
if(l2 == user.password):
print("Welcome, " + user.name)
else:
print("Incorrect username or password")
login(user)
home('')
home('')
Here is another answer that shows how to do this using a class.
class login:
def __init__(self):
self.credintials = {}
def register(self, username, password):
self.credintials[username] = password
def check(self, user, pas):
print(self.credintials )
if user in self.credintials.keys() and pas == self.credintials[user] :
print("Login success!")
else:
print('Wrong Username or Password')
s = login()
Stop = False
while Stop == False:
tasks = (input('What would you like to do? enter [Register], [Login], or [quit]'))
# Calling functions with that class object
if tasks == 'Register':
Name = (input('Please enter username'))
Pword= (input('Please enter password'))
s.register(Name, Pword)
if tasks == 'Login':
LoginInfoUser = (input('Please enter Username'))
LoginInfoPassword = (input('Please enter Password'))
s.check(LoginInfoUser,LoginInfoPassword)
if tasks == 'quit':
print("See you later!")
Stop =True
I am an absolute beginner in python programming (week 4), and I'm trying to figure this out. I've been going at this for days now but I am truly stuck. I've debugged it to zero errors, but when I run, nothing happens...at all. What am I doing wrong here?
roster =[]
def init_(self, name):
self.name = name
def setName (self,name):
self.name = name
def getName(self):
return self.name
def displayData(self):
print("")
print(" Player's Information")
print("***********************")
print("Player's Name: ", self.name)
def displayMenu():
print("***Selection Menu***")
print("1. View current roster")
print("2. Add a player to the roster")
print("2. Remove a player from the roster")
print("3. Change a player name displayed on the roster")
print("4. Quit")
print()
return int(input("Your Choice?"))
def viewRoster():
print(' '.join(roster))
def addPlayer():
newName = input("Who will bring honor to the squad?:")
roster.append(newName)
def removePlayer ():
removeName = input("Who's off the team?")
if removeName in roster:
del roster[removeName]
else:
print("Sorry", removeName, "is not on this team")
def editPlayer():
oldName = input("What name would you like to change? ")
if oldName in roster:
newName = input("What is the new name? ")
print("Alright,", oldName, "is now called", newName)
else:
print("Sorry,", oldName, "was not found. Are you sure you spelled that right?")
The biggest problem in your code is that though you have defined a lot of functions, you have not called a single one.
Also, the first function should be
def __init__(self, name):
Next up, you need to define a class to encapsulate all your functions and the roster variable. Since it is a class, you add self. in front of your variables like roster.
Then you can import this class elsewhere and call the functions.
I've just started to use classes and i decided to create a quick login program.
the program should setup a user and let them login but i'm getting a NameError whenever I run the program I've checked the spelling and everything seems to be correct. Any help would be appreciated
class User(object):
def __init__(self, name1, name2 , age , username, passw):
self.name1 = name1
self.name2 = name2
self.age = age
self.username = username
self.passw = passw
def user_setup(self):
try:
name1 = str(input("Please enter your first name : "))
try:
name2 = str(input("Please enter your last name : "))
try:
age = int(input("Please enter your age in years"))
except ValueError:
print("Thats not allowed")
except ValueError:
print("Thats not allowed")
except ValueError:
print("Thats not allowed")
self.username = self.name1[0:3] + str(self.age)
return self.username
def login(self):
for i in range(4):
loginUsername = input("Please enter your username : ")
if loginUsername == self.username:
loginPassword = input("Please enter your password : ")
if loginPassword == self.passw:
print("You have loggged in as " + self.username)
else:
print("invalid")
else:
print("invalid")
print("You have entered your username or password incorrectly too many times")
quit()
def main():
menu = int(input("1.new user\n2.login\n-"))
if menu == 1:
user_setup()
login()
elif menu == 2:
login()
print("test")
main()
THE ERROR I GET WHEN I RUN THE PROGRAM:
1.new user
2.login
-1
Traceback (most recent call last):
File "C:\Users\colin\Desktop\Python programs\Password generator.py", line 58, in <module>
main()
File "C:\Users\colin\Desktop\Python programs\Password generator.py", line 50, in main
user_setup()
NameError: name 'user_setup' is not defined
user_setup is a method on the class so you will need to instantiate that first before you can use it:
user = User(name1='foo', name2='bar', age=21, username='foobar', password='secret')
user.user_setup()
user_setup() is a method of User. You need to create a User instance and then call the method like so
user = User(name1, name2, age, username, passw)
user.user_setup()
If you want to call it without instantiating first, make user_setup a classmethod and use like so:
User.user_setup()
Change user_setup() to User.user_setup() in main(), since user_setup() is a method of the User class, python won't find it as a normal function.
You would also want to change login() to User.login()
However, classes are rather used in another way, for example a new user would more often be made by combining your user_setup() and __init__() and then creating a user this way:
user1 = User(...)
You need to create a User instance, then call the appropriate method. Also, in your __init__ you need to give default value for argument name etc.
I'm not sure why it keeps asking to enter a menu choice after I enter one!
When I run it consistently asks me to enter a number, but it doesn't run the functions associated with the numbers
not sure if you needed the class butI included it anyway
import pickle
class Contact:
def __init__(self, name, phone, email):
self.__name = name
self.__phone = phone
self.__email = email
def set_name(self, name):
self.__name = name
def set_phone(self, phone):
self.__phone = phone
def set_email(self, email):
self.__email = email
def get_name(self):
return self.__name
def get_phone(self):
return self.__phone
def get_email(self):
return self.__email
these are the menu options that I have, no matter what number i enter it asks me to enter another number
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
FILENAME = 'contacts.txt'
def main():
mycontacts = load_contacts()
choice = 0
while choice != QUIT:
choice = get_menu_choice()
if choice == LOOK_UP:
look_up(mycontacts)
elif choice == ADD:
add(mycontacts)
elif choice == CHANGE:
change(mycontacts)
elif choice == DELETE:
delete(mycontacts)
save_contacts(mycontacts)
def load_contacts():
try:
input_file = open(FILENAME, 'rb')
contact_dct = pickle.load(input_file)
input_file.close()
except:
contact_dct = {}
return contact_dct
def get_menu_choice():
print()
print('Menu')
print('-------------------')
print('1. Look up an contact')
print('2. Add a new contact')
print('3. Change an existing contact')
print('4. Delet a contsct')
print('5. Quit the program')
print()
choice = int(input('Enter your choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a vaild choice: '))
return choice
def look_up(mycontacts):
name = input('Enter a name: ')
print(mycontacts.get(name, 'That name is not found'))
def add(mycontacts):
name = input('Name: ')
phone = input('Phone: ')
email = input('Email: ')
entry = contact.Contact(name, phone, email)
if name not in mycontacts:
mycontacts[name] = entry
print('The entry has been added.')
else:
print('That name already exists.')
def change(mycontacts):
name = input('Enter a name: ')
if name in mycontacts:
phone = input('Enter the new phone number: ')
email = input('New Email: ')
entry = contact.Contact(name, phone, email)
mycontacts[name] = entry
print('information updated')
else:
print('not found')
def delete(mycontacts):
name = input('Enter a name: ')
if name in mycontacts:
del mycontacts[name]
print('Entry deleted')
else:
print('That name not found')
def save_contacts(mycontacts):
output_file = open(FILENAME, 'wb')
pickle.dump(mycontacts, output_file)
output_file.close()
main()
I believe the problem is in the following function:
def get_menu_choice():
print()
print('Menu')
print('-------------------')
print('1. Look up an contact')
print('2. Add a new contact')
print('3. Change an existing contact')
print('4. Delet a contsct')
print('5. Quit the program')
print()
choice = int(input('Enter your choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a vaild choice: '))
return choice
First issue: If the first choice entered is within bounds, it is never returned from get_menu_choice().
Second issue: If the first choice entered is not within bounds, your while loop just returns the immediate next choice.
How to fix it: Move the return statement outside the while loop in get_menu_choice(). Also, move choice = get_menu_choice() to the bottom of the while loop in main(), and set choice's initial value to get_menu_choice().
Hope this helps.
P.S. What happens if the choice entered by the user is not an integer? What happens if the user enters a character, string, or control character? I would consider additional error-handling for erroneous input.