Python: return variable from class - python

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

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()

How do I create a simple login command-line program using Python classes?

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

What's wrong with this program - nothing happens?

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.

NameError in python but everything is defined (and spelt correctly)

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.

this program never makes it past the menu choices it continuously ask for a menu option??

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.

Categories