python API coding for tidal music - python

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)

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

DB values are not in global scope

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

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

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!

Python 3.3 dump and load pickled dictionary

I am working through the chapter exercises in Tony Gaddis's "Starting Out With Python" 3rd edition from a class I have taken previously. I'm in chapter 9 and Exercise 8 requires me to write a program that pickles a dictionary (name:email) to a file when it closes and unpickles that file retaining the data when it is opened. I have read every word in that chapter and I still don't understand how you can do both in the same file. When you use the open function it creates a file which, in my understanding, is a new file with no data. I'm thinking it may be a sequencing issue, as in where to put the dump and load lines of code but that doesn't make sense either. Logic dictates you have to open the file before you can dump to it.
If the 'open' function creates a file object and associates it with a file and this function appears early in the code (as in def main), what keeps it from zeroing out the file each time that line is called?
This is not a homework assignment. I have completed that class. I am doing this for my own edification and would appreciate any explanation which would help me to understand it. I have included my attempt at the solution which is reflected in the code below and will keep gnawing at it until I find the solution. I just thought since the gene pool is deeper here I would save myself some time and frustration. Thank you very much to those that choose to reply and if I am lacking in any pertinent data that would help to clarify this issue, please let me know.
import pickle
#global constants for menu choices
ADDNEW = 1
LOOKUP = 2
CHANGE = 3
DELETE = 4
EXIT = 5
#create the main function
def main():
#open the previously saved file
friends_file = open('friends1.txt', 'rb')
#friends = pickle.load(friends_file)
end_of_file = False
while not end_of_file:
try:
friends = pickle.load(friends_file)
print(friends[name])
except EOFError:
end_of_file = True
friends_file.close()
#initialize variable for user's choice
choice = 0
while choice != EXIT:
choice = get_menu_choice() #get user's menu choice
#process the choice
if choice == LOOKUP:
lookup(friends)
elif choice == ADDNEW:
add(friends)
elif choice == CHANGE:
change(friends)
elif choice == DELETE:
delete(friends)
#menu choice function displays the menu and gets a validated choice from the user
def get_menu_choice():
print()
print('Friends and Their Email Addresses')
print('---------------------------------')
print('1. Add a new email')
print('2. Look up an email')
print('3. Change a email')
print('4. Delete a email')
print('5. Exit the program')
print()
#get the user's choice
choice = int(input('Enter your choice: '))
#validate the choice
while choice < ADDNEW or choice > EXIT:
choice = int(input('Enter a valid choice: '))
#return the user's choice
return choice
#the add function adds a new entry into the dictionary
def add(friends):
#open a file to write to
friends_file = open('friends1.txt', 'wb')
#loop to add data to dictionary
again = 'y'
while again.lower() == 'y':
#get a name and email
name = input('Enter a name: ')
email = input('Enter the email address: ')
#if the name does not exist add it
if name not in friends:
friends[name] = email
else:
print('That entry already exists')
print()
#add more names and emails
again = input('Enter another person? (y/n): ')
#save dictionary to a binary file
pickle.dump(friends, friends1.txt)
friends1.close()
#lookup function looks up a name in the dictionary
def lookup(friends):
#get a name to look up
name = input('Enter a name: ')
#look it up in the dictionary
print(friends.get(name, 'That name was not found.'))
#the change function changes an existing entry in the dictionary
def change(friends):
#get a name to look up
name = input('Enter a name: ')
if name in friends:
#get a new email
email = input('Enter the new email address: ')
#update the entry
friends[name] = email
else:
print('That name is not found.')
#delete an entry from the dictionary
def delete(friends):
#get a name to look up
name = input('Enter a name: ')
#if the name is found delete the entry
if name in friends:
del [name]
else:
print('That name is not found.')
#call the main function
main()
If you open a file for reading with open("my_file","r") it will not change the file. The file must already exist. If you open a file for writing with open("my_file","w") it will create a new file, overwriting the old one if it exists. The first form (reading) is the default so you can omit the second "r" argument if you want. This is documented in the Python standard library docs.
Use open("myfile", 'r+') this allows both read and write functions. (at least in 2.7)

Categories

Resources