Global variable Issues with different functions (using Python) - python

I am trying to create a program that allows me to use my list 'users' in a different function in the program.
I have tried parameters, declaring it 'global' (although I've been told it's bad practice to do that) and I've tried researching 'class' and implementing it all to no avail. I have also tried putting users into a text file and then reading from it but it's a nuisance as I need it to be in a list.
Here is my code:
def register():
global username
username = raw_input("Enter a username: ").lower()
firstName = raw_input("Enter your first name: ").lower()
surname = raw_input("Enter your surname: ").lower()
age = raw_input("Enter your age: ")
yearGroup = raw_input("Enter your year group: ")
users =[[firstName, surname, age, yearGroup]]
def resultsFunction():
score = 5
results = [[score, username]]
results.extend(users)
I have tried:
def register():
global username
username = raw_input("Enter a username: ").lower()
firstName = raw_input("Enter your first name: ").lower()
surname = raw_input("Enter your surname: ").lower()
age = raw_input("Enter your age: ")
yearGroup = raw_input("Enter your year group: ")
global users
users =[[firstName, surname, age, yearGroup]]
It throws up the error:
results.extend(userDetails)
NameError: global name 'userDetails' is not defined
The strange thing is, after declaring username 'global' (yes, I know I shouldn't, but it worked), I was able to use the username in the function but when I tried it with the other variables, e.g firstName so I could try to create the list simply in the 'resultsFunction' it wouldn't work.
The register function does not get run all the time if the user decides not to register but I can't change that as I do not want the user to have to always put in their details.
I am so confused and have tried everything I know. I came here as a last resort so I hope that someone can help and that maybe this question can help others having the same difficulties with the local and global variables scopes.

Write global users inside the function to change values in the users variable. Otherwise you can only read it but not change the value inside it.
lis = []
def a():
lis = [1,2]
a()
print(lis)
will print []
where as :
lis = []
def a():
global lis
lis = [1,2]
a()
print(lis)
will print [1,2]
With reference to your program as per my understanding.. this might help..
username = ''
user = []
def register():
global username
global users
username = input("Enter a username: ").lower()
firstName = input("Enter your first name: ").lower()
surname = input("Enter your surname: ").lower()
age = input("Enter your age: ")
yearGroup = input("Enter your year group: ")
users =[[firstName, surname, age, yearGroup]]
def resultsFunction():
score = 5
results = [[score, username]]
results.extend(users)
print(results)
register()
resultsFunction()
will output :-
Enter a username: Foo
Enter your first name: Bar
Enter your surname: Baz
Enter your age: 00
Enter your year group: 00
[[5, 'foo'], ['bar', 'baz', '00', '00']]

Related

how get the value of one particular variable out of a function without actually running it

the code given below is part of a bigger program.
i want to get the value of 'phone' out of the function, without actually running the function
(like only need 'phone' and i dont want 'val' to get printed)
def signup():
n = input('enter name : ')
db = input('enter date of birth : ')
phone = int(input('enter phone number : '))
ad = input('enter address : ')
password = input('enter password : ')
accnt = input('enter account no : ')
val = (accnt, n, password, db, ad, phone)
print(val)
To get password you should call password = input(...) somewhere but you can't run only one specific line of a function without running all the function. However you can refactor your code with two functions to get what you want:
def get_password():
"""Get password from user."""
password = input('enter password : ')
return password
def signup():
"""Ask user to sign up."""
n = input('enter name : ')
db = input('enter date of birth : ')
phone = int(input('enter phone number : '))
ad = input('enter address : ')
password = get_password() # change here
accnt = input('enter account no : ')
val = (accnt, n, password, db, ad, phone)
print(val)
Then call get_password to get password value.

Use values from another function python3

I have this code, but i dont know how to use the "age" from the user in the other function any clue what i have wrong?
def accounts():
yourCode = input("Please enter your user code. \nIf you already have an account, type your account user code. \nOtherwise, enter a new one to create an account: ")
with open("users.txt", "r") as rf:
users = rf.readlines()
for each_user in [user.split(",") for user in users]:
if each_user[0] == yourCode:
print(f"Welcome {each_user[1]}")
age = each_user[2]
xxApp()
return None
with open("users.txt", "a") as af:
name = input("Please enter your name: ")
age = input("Enter your age: ")
af.write(f"{yourCode},{name},{age}\n")
print(f"Thank you {name}, your information has been added.")
xxApp()
def xxApp():
age = each_user[2]
print(age)
Pass it as a parameter
def accounts():
yourCode = input("Please enter your user code. \nIf you already have an account, type your account user code. \nOtherwise, enter a new one to create an account: ")
with open("users.txt", "r") as rf:
users = rf.readlines()
for each_user in [user.split(",") for user in users]:
if each_user[0] == yourCode:
print(f"Welcome {each_user[1]}")
xxApp(each_user)
return None
...
def xxApp(user):
age = user[2]
print(age)
You're defining age = each_user[2], but the each_user variable is only available in the scope of accounts().
You can read about python scopes here
I would modify the xxApp() function to take in a variable as a parameter like this
def xxApp(each_user):
age = each_user[2]
print(age)
then you call xxApp() with the each_user passed as a parameter, so it is available inside the scope of xxApp(), like this xxApp(each_user)

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.

How to create a dictionary that I can access throughout the program?

I'm creating a address book program, and need to have a dictionary that I can add too, edit, and delete, as well as pickle. What would be the best way to create it so it is accessible by all the functions? I currently have the dictionary in the addon function but wouldn't it reset if I were to call the dictionary to another function?
My code so far (not including the menuModule)
def addPerson():
personLastName = input("Enter the last name of "
"the person you want to add: ").lower()
personFirstName = input("Please enter the first name of "
"the person you want to add: ")
localPart = input("Please enter the local part of the email address")
while not localPart.isalnum():
localPart = input("Please enter a valid input, a-z and numbers 0-9: ")
domain = input("Please enter the domain of the email addres: ")
while not domain.isalnum():
domain = input("Please enter a valid input, a-z and numbers 0-9: ")
topLevelDomain = input("Please enter the top level domain, examples: com, net, org: ")
while not topLevelDomain.isalnum() or len(topLevelDomain) > 3:
topLevelDomain = input("Please enter only letters, a-z and not more then 3 characters: ")
personEmail = localPart + "#" + domain + "." + topLevelDomain
personStreetAddress = input("Please enter house number and street of the person you want to add: ")
personCityState = input("Please enter the city, state abbreviation and zipcode of the person you want to add: ")
personPhone = input("Please enter the phone number of the person you want to add: ")
personPhoneStr = personPhone.strip("-")
while not personPhoneStr.isdigit() and not len(personPhoneStr) == 10:
personPhone = input("Error. That is not a valid phone number. Try again: ")
personPhoneStr = personPhone.strip("-")
return personLastName, personFirstName, personEmail, personStreetAddress, personCityState, personPhone
def appendDictionary():
personLastName, personFirstName, personEmail, personStreetAddress, personCityState, personPhone = addPerson()
listX = [personFirstName, personEmail, personStreetAddress, personCityState, personPhone]
addressBook = {personLastName: listX}
print(personFirstName,personLastName, "has been added to the address book!")
print(addressBook)
return addressBook
Try using lists. One list for each of the variables because if you try to store them as a tuple and then add them into a master list you will not be able to or it will be hard to charge them and edit them. Here is an example of storing the data:
nameList.extend(john)
emailList.extend(john#gmail.com.uk)
john_index = len(nameList)
Give each person an index to help you file their information so if our list looked like [jane#live.com, sam#wenston.com, john#gmail.com.uk] johns data is going to be the last in the list because we just entered it in position 3 on the list and the length function returns 3 so you know where johns data is stored and if you were to add more data it would stack up accourdingly.
here is an example of getting it back out of the list and editing it:
print nameList[john_index]
print emailList[john_index]
emailList[john_index] = new_value
I hope you understand :)

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"}

Categories