DB values are not in global scope - python

Usage
I am using the replit browser IDE for this project. Also, I am using replit's database for this project.
Problem
So as you can see, in the code below, I am asking the user to log in or Sign up, while saving the user's data of money, deposits, inventory in a key-value pair into the database of replit. It is simple to do that, first I import replit:
from replit import db
And then I assign the key-value pairs to a list like:
username = input("Enter new Username: ")
password = input("Enter new password: ")
db[username] = [password, 300000, [], 500, 0, False]
# the password, money, inventory, allowed deposit, deposited, and boolean for working or not, respectively.
But to actually uses the user's stats saved to their value pair, I have to make the username available in all places in the code. Rather I assigned them to variables:
self.money = db[username][1]
self.inventory = db[username][2]
self.deposit_allowed = db[username][3]
self.deposited = db[username][4]
self.working = db[username][5]
But despite doing that, I get errors that "user name is not defined" and "self.inventory is not defined". I am getting the values using the list as you will see below
The Real Question
My real question is that how can I make the variables, that I have put up, have the values of the list that I have assigned to the value pair of the user's name and make it work globally. Because later in the code, I append to the self.inventory list which is in the value pair list assigned to the user.
Code
Here is a portion of the important code that I am using.
class Game:
def __init__(self, username):
self.money = db[username][1]
self.inventory = db[username][2]
self.deposit_allowed = db[username][3]
self.deposited = db[username][4]
self.working = db[username][5]
def database(self):
enter_game = input("Do you want to [1] Login\n[2] Signup:\n>")
while enter_game == '1' or enter_game == '2':
if enter_game == '1':
username = input("Enter user name: ")
password = input("Enter password: ")
if username in db.keys():
if db[username][0] == password:
print("Loggedd In")
break
else:
print("Invalid Username, Password")
break
if enter_game == '2':
username = input("Enter new Username: ")
password = input("Enter new password: ")
db[username] = [password, 300000, [], 500, 0, False]
break
Also, the project is literally massive, so rather, I have attached a link to go to the real code(The code that is used here is in the gameplay.py file):
Click here to go to the repl with the code.
Or if that doesn't work, click here:
https://replit.com/#OldWizard209/Life-SIMULATOR-In-Development-2#gameplay.py

Related

How do I iterate over every value in a key where the value is the instance of a class?

I want to iterate over every instance i stored as a value to a number stored as a key in a dictionary. Where if I were to make an account named jason, it would be assigned 1, then if I were to make a new one, it would be assigned 2. That part is already done but the iteration part is very confusing for me. Why does it only go through the first key value pair in the dictionary?
Ps: I am new to oop this is my first oop thing where i did not follow any guides so that id would actually learn. Thank you <3
class Bank:
serialnum = 0
username = ""
email = ""
password = ""
bal = 0
def __init__(self,count):
self.serialnum = count
self.username = input("What's your username? \n")
self.email = input("What's your email? \n")
self.password = input("What's your password \n")
self.bal = input("How much balance do you have \n")
def withdraw(money):
self.bal= bal-money
print (bal)
global count
count = 0 #counts and is the serial num
accounts = {} #accounts dictionary
def accountcreate(): #gets called when account does not exist
global count
while True:
serial = int(count)
account = Bank(count)
print("The serial is {}".format(count))
count += 1
accounts[serial] = account
print("Your account has been created, please use the username registered. ")
break
accountaccess()
def accountverify(name):#if accountverify returns false, prompts the accountcreate function
username = ""
start = 0
balance = 0
if 0 in accounts: #essentially means if the first account has been made
for key in accounts: #loops through accounts in accounts dictionary
#sets the keys gotten and sets the un to the username attribute of every key
if hasattr((accounts[key]),"username") == name:
print("logged in as ", name, "Password is \n",
(getattr((accounts[key]), "password")),
"Account balance is ", getattr((accounts[key]), "bal"))
action = input("What do you want to do? \n -Withdraw \n -Deposit \n -Transfer \n -Make another account \n")
if "make" in action:
print("Making another account... \n Please enter your credentials")
makeaccount = accountcreate()
else: #if username does not exist
print("First item in list is ",(getattr((accounts[key]),"username")))
print(accounts)
accountask = input("Account does not exist, make a new account? Yes or No \n").lower()
if accountask == "yes":
makeAccount = accountcreate()
else: #makes first account
ask1 = (input("Account does not exist, would you like to make an account? Yes or No \n")).lower()
if ask1 == "yes":
makeAccount = accountcreate()
def accountaccess(): #accesses account
ask = (input("Do you want to access an account? Yes, or no. "))
if ask == "yes":
getname = (input("What is your username? ")).lower()
ver = accountverify(getname)
loop = False
loop = True
while loop == True: #mainloop
ask = (input("Do you want to access an account? Yes, or no. \n")).lower()
if ask == "yes":
getname = (input("What is your username? ")).lower()
ver = accountverify(getname)
loop = False
The replit link
It would also be helpful to know how to store the username as the name of the value since what is shown there is incredibly cryptic
In this image, every new username registered is a new instance of the Bank class. But the for loop only goes on the first one
The part of your code that is causing the issue is
if hasattr((accounts[key]),"username") == name:
print("logged in as ", name, "Password is \n",
(getattr((accounts[key]), "password")),
"Account balance is ", getattr((accounts[key]), "bal"))
The return from hasattr is a boolean and cannot be compared to name.
Try changing it too
if hasattr(accounts[key],"username"):
if accounts[key].username == name:
....
Also your use of getattr() is incorrect and unnecessary since you can simply access those attributes directly.
For example:
account = accounts[key]
print(account.username)
print(account.password)
print(account.bal)
with all of that in mind your accountsverify function should look more like this:
def accountverify(name):
start = 0
balance = 0
if 0 in accounts:
for key in accounts:
account = accounts[key]
if account.username == name:
print(f"logged in as {name} Password is \n {account.password} \n Account balance is {account.bal}")
action = input("What do you want to do? \n -Withdraw \n -Deposit \n -Transfer \n -Make another account \n")
if "make" in action:
print("Making another account... \n Please enter your credentials")
makeaccount = accountcreate()
else: #if username does not exist
print("First item in list is ",account.username)
print(accounts)
accountask = input("Account does not exist, make a new account? Yes or No \n").lower()
if accountask == "yes":
makeAccount = accountcreate()
As far as making the Bank class print the accounts name you just need to overwrite the __str__ method.
class Bank:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name

Using input() in a def function

I am attempting to create a contact list with a def() function to easily loop back to the top later in the code. The issue I am having is that I define "function_question" in the def portion but when I run the code it gives me a NameError saying "function_question" is not defined. Any help or suggestions is appreciated!!
#Created a def so I can easily run back the code to the top.
def user_prompt():
print('Welcome to your contact directory.')
function_question = int(input("What would you like to do? \n1 Add Conctact \n2 Find Contact \n3 Edit Contact \n4 Delete Contact:"))
user_prompt()
#Adding a contact to the contact list.
while function_question == 1:
name = input('What is the persons name? ')
phone_number = input('What is the phone number? ')
email = input('What is your email? ')
address = input('What is the person adress? ')
if len(phone_number) != 10:
phone_number = input("the phone number you provided is not the proper length. Re-enter:")
contact = [] + [name] + [phone_number] + [email] + [address]
contact_list.append(contact)
ans = input('Would you like to add another contact? ')
if ans == 'yes':
continue
if ans == 'no':
user_prompt()
You could simply return the value from the function and save it to a variable outside the function. Like:
def user_prompt():
print('Welcome to your contact directory.')
return int(input("question"))
input_question = user_prompt()
The issue is that the variable function_question is empty.
In your code you defined two variables function_question with the same name but with different memory address; the first is a local variable that works only into the user_prompt() function.
The correct code is:
#Created a def so I can easily run back the code to the top.
def user_prompt():
print('Welcome to your contact directory.')
return int(input("What would you like to do? \n1 Add Conctact \n2 Find Contact \n3 Edit Contact \n4 Delete Contact:"))
function_question = user_prompt()
#Adding a contact to the contact list.
while function_question == 1:
...
I suggest you to search about python scope variable for more details.
The function_question variable is in the scope of the user_prompt function so you cannot use it in the global scope. You need to make it global for it to be acessible
I reccomend reading through this,
https://www.w3schools.com/PYTHON/python_scope.asp

How do I store the values into this dict so that in the next iteration it would work?

I'm not sure how to store the values taken from the user input (to generate new username and password) and store it in the iass dict, so in the next iteration it would work:
iass = {}
class login:
def __init__(self):
pass
def passcheck(self):
for key, value in iass.copy().items():
if self.username == key and self.password == value:
print("Granted Access")
else:
A = str(input("Enter Desired Name: "))
B = str(input("Enter Desired Password: "))
iass[A] = B
A1 = login()
A1.username = str(input("Enter Username: "))
A1.password = str(input("Password: "))
A1.passcheck()
Your usage of a class/object is a little strange. Usually one would create a class for something that represents an object (a noun) in the real world. In your application, this might be User.
Login would be a method in that class.
Your method passcheck is also a bit strangely constructed. As you've just asked for the input of Username and Password, you can reuse these at all times. You don't need to ask them again. I'd recommend you to pass username and password as parameters in the login method, rather than setting them directly as parameters. Your code could look somewhat like this
iass = []
iass.append({'myuser': 'mypwd'})
class User:
def __init__(self):
pass
def login(self, username, password):
for key, value in iass.items():
if username == key and password == value:
print("Granted Access")
return
# User not found, so we're adding him
iass.append({username: password})
A1 = User()
username = str(input("Enter Username: "))
password = str(input("Password: "))
A1.login(username, password)
Note: didn't run this in the python parser. might have some issues :-)
Please run pylint on your code.
It will uncover bugs for you before you run it.
It will improve the code readability. This helps everyone: yourself and others who will read your code.
Code changes:
Remove the iass.copy() call. It was unnecessary; though not creating a bug.
To make the code "work" you need to initialize iass with a key and value:
iass = {"ding": "dong"}
Remove the else: block. That is causing an extra prompt which is only confusing and would be considered a bug.
Now when the user enters a username, password "ding" and "dong" your check will "pass".

python API coding for tidal music

Hi currently a student working on a project for school.
I'm looking to use a music API to work with, and have found TidalAPI. However, my code can't seem to run.
Below is my code:
import tidalapi
def logindetails():
username = input("What is your Tidal username? ")
password = input("What is your Tidal password? ")
session = tidalapi.Session()
session.login(username, password)
def gettingalbum():
logindetails()
album_id = input("What is the album ID? ")
tracks = session.get_album_tracks(album_id)
print("Tracks in this album are:")
x = 0
for track in tracks:
x = x+1
print(x,track.name)
gettingalbum()
NameError: name 'session' is not defined for session.get_album_tracks(album_id)
how can I link my first module with the second?
(It works if I combine both codes into one module, but I have to split them into 2 modules)
I'd suggest making logindetails() return the logged-in session you can then pass into other functions. (The other option would be to make it a global variable.)
I also took the liberty of adding the use of enumerate() for printing the track indexes.
import tidalapi
def logindetails():
"""
Ask for login details and return a logged-in session.
"""
username = input("What is your Tidal username? ")
password = input("What is your Tidal password? ")
session = tidalapi.Session()
session.login(username, password)
return session
def gettingalbum(session):
album_id = input("What is the album ID? ")
tracks = session.get_album_tracks(album_id)
print("Tracks in this album are:")
for x, track in enumerate(tracks, 1):
print(x, track.name)
session = logindetails()
gettingalbum(session)

if x in [list] iterator

def new_user() -> str:
users = []
print("Welcome to The 'Create New User' Interface")
sleep(0.5)
x = input("Enter Name to Use for Account Access\n*Name is Case Sensitive to Access Account*: ")
if x in users:
x = input("That User Already Exists! Enter a New Name: ")
users.append(x)
print("Your Account Access Name is: " + str(x))
else:
users.append(x)
print("Your Account Access Name is: " + str(x))
So I'm not sure how to word this question but I have this block of code and as you can see I want to check if the user inputted name already exists, and if it does it'll prompt for a new name and add it to the list, and if it doesn't already exist, it'll add it to the list, but there's a way around this, if the list already contains a name and the user inputs that same name the if x in users: code will run and when prompted to enter another name, if they enter that same name, it wont recognize that it already exists and add it to the list either way, how can i prevent this?
To get valid user input wrap the request in a loop and when you have valid input break out, e.g.:
print("Enter Name to Use for Account Access")
print("*Name is Case Sensitive to Access Account*")
while True:
x = input("Enter a Name: ")
if x not in users: # Valid input
break
print("That User Already Exists!")
users.append(x)
print("Your Account Access Name is:", x)
Solution
users = []
print("Welcome to The 'Create New User' Interface")
x = input("Enter Name to Use for Account Access\n*Name is Case Sensitive to Access Account*: ")
while x in users:
x = input("That User Already Exists! Enter a New Name: ")
users.append(x)
print("Your Account Access Name is: " + str(x))
Simply just changed your if loop to a while loop that will continue until a unique name is given.
Suggestions
users = []
print("Welcome to The 'Create New User' Interface")
while True:
user_name = '' #now users can not enter a empty user_name
while not user_name:
user_name = input("Enter Name to Use for Account Access: ")
for i in range(0, len(users)): #different loop to enable use of lower()
while user_name.lower() == users[i].lower(): #removes need for unique cases
print("That User Already Exists!")
user_name = '' #again stopping empty fields
while not user_name:
user_name = input("Enter Name to Use for Account Access: ")
users.append(user_name)
print("Your Account Access Name is: " + user_name)
For start we can create a loop that will reject any blank user_name.
Next we can use .lower() when checking to see if user_name exists in users[]. By doing this we can preserve the unique case format the user wants to use to store their name(perhaps for display purposes) but at the same time we can check to see if user_name already exists regardless of case format.
Cleaning it up we can go with something like this:
def ask_user(message=''): #create function to check for blank inputs
user_name = ''
while not user_name:
user_name = input(message)
return user_name
users = []
print("Welcome to The 'Create New User' Interface")
while True:
user_name = ask_user("Enter Name to Use for Account Access: ")
for i in range(0, len(users)):
while user_name.lower() == users[i].lower():
print("\nThat User Already Exists!") #newline for clarity
user_name = ask_user("Enter Name to Use for Account Access: ")
users.append(user_name)
print("\nYour Account Access Name is: " + user_name) #newline for clarity
Here I created ask_user which handles blank inputs. Then added a \n in a few spots to help with readability.
Output
(xenial)vash#localhost:~/pcc/10$ python3 helping.py
Welcome to The 'Create New User' Interface
Enter Name to Use for Account Access:
Enter Name to Use for Account Access: vash
Your Account Access Name is: vash
Enter Name to Use for Account Access: VASH
That User Already Exists!
Enter Name to Use for Account Access:
Enter Name to Use for Account Access: p0seidon
Your Account Access Name is: p0seidon
Enter Name to Use for Account Access: P0SEidoN
That User Already Exists!
Hope this helps!

Categories

Resources