Python - Access and use specific object during runtime - python

I am working on a bank account program where the user logs in with a four digit number (pin).
I want to find a way to access a specific object with all its attributes at runtime after the right pin has been entered.
class Konto(object):
def __init__(self, account_holder, balance , pin):
self.account_holder = account_holder
self.balance = balance
self.pin = pin
I have three different objects defined in a list
kontoList = []
kontoList.append(Konto("Person1", 143541, 1223)),
kontoList.append(Konto("Person2", 6230, 1234)),
kontoList.append(Konto("Person3", 4578, 4321))
The last attribute is the Pin that is entered by the user. When the program checks the pin is '1234' for example it displays a menu where you can get the current balance, account holder etc. In this case it would be 6230 (balance) and Person2 (account holder). So here is some code:
pin = input("PIN: ")
for konto in kontoList:
if konto.pin == pin:
print("Valid PIN")
continue
else:
print("not valid")
break
while True:
print("1: Withdrawal \n"
"2: Deposit \n"
"3: Transfer \n"
"4: Current Balance \n"
"5: Account Holder \n"
"6: Quit \n")`
choice = input("Your Choice: ")
Is there any way to access the specific object during runtime and then go on to work with it? I've looked up getattr() but it does not seem useful in this situation.

You could simply create a list of pins, then check whether the pin you're checking is contained in that list:
kontoPinList = [konto.pin for konto in kontoList]
and then you would check whether your pin is in the kontoPinList with:
pin in kontoPinList
EDIT: If you want to keep working with the konto you do the following:
for konto in kontoList:
if konto.pin == pin:
#do something with the konto here
EDIT nr.2: If you wish to now call functions on the konto, such as account_holder(), you just do account_holder(konto) and that should work.
The reason my first response was to write a getPin() function is because while this will not solve your problem, it is a good idea to "protect" your variables by deciding how you want to return them. (it's more of a java thing than a python thing)
However, as you pointed out, it is a useless function if all you're interested in is simply returning konto.pin .

You could try something like this:
kontos_with_pin = filter((lambda k: k.pin == pin), kontoList)
if len(kontos_with_pin) == 1:
relevant_konto = kontos_with_pin[0]
# Do something with relevant_konto
else:
# handle case where there is no konto with that pin, or more than one, etc.

Related

How do I get my code to run the if statement?

I'm a beginner in Python and I'm writing a code for a school project and ran into an early bug.
For some reason my if function won't run.
import time #imports computer time to program(buit in function)
count= 0
print(" Gymship") # center this
print("--------------------------------------") # this should go across the whole screen
print("Input a level to view the description or InputSign up to begin signing up for a card")
print("--------------------------------------------------------------------------")
print("Bronze")
time.sleep(1) # this wil pause the program for 1 second(for effect)
print("Silver")
time.sleep(1)
print("Gold")
time.sleep(1)
print("Platinum")
time.sleep(2)
print("-----------------------------------------------") # this should go across the whole screen
print("Sign up")
print(" ")
input()
if input == "Bronze":
print("Bronze")
print("--------------------------------------------")
print("You acquire a bronze card when you use two or less gym services")
print("2 Hours limit in the gym")
print("-------------------------------------")
print(input("Back to return to menu screen"))
count = count + 1
This is not correct:
input()
if input == "Bronze":
The way input() works is by returning a value. The name input refers to the function itself, so the function input will never equal the text "Bronze" unless you explicitly do something bad, like input = "Bronze" (it's bad because if you overwrite input, you'll no longer be able to access that function).
Instead, you should be using the returned value:
usr_input = input()
if usr_input == "Bronze":
Also, the line print(input("Back to return to menu screen")) is unnecessarily complicated; the print() will print whatever was returned by input(), but input() will display the "Back to return to menu screen" prompt without wrapping it in an if statement. So, input("Back to return to menu screen") is all you need. If you keep it the way you have it, if someone typed some text and then hit enter, the text would display again, because the print() is printing whatever that text was that the user typed.
You first need to assign a variable to the input and then check if the variable is equal to "Bronze"
Right now you are taking the input, but are not storing it anywhere. So the fixed code would be
user_input = input()
if user_input == "Bronze":

Importing class from module but functions not working

I created two programs, one is an ATM simulator and other is a Virtual Doctor which reads data from excel sheet and on the basis of user input, tells what disease the user might be suffering from.
now I want to connect the atm to virtual doctor such that it withdraws the amount of medicines from the bank account
I imported atm to virtual doctor but the functions don't seem to be working, they do nothing when called and the process exits.
#code for ATM
userpin = ["1234", "2345", "3456", "4567"]
userpass = ["1234", "2345", "3456", "4567"]
username = ["Rishabh", "Siddharth", "Kashish", "Mahima"]
userbalance = [20500, 43567, 45672, 67800]
class Bank:
def __init__(self, bal=0, index=0):
#if __name__ == '__main__':
self.bal = bal
self.index = index
def start(self):
if __name__ == '__main__':
print("\t\t=== Welcome to ATM ===")
inputpin=input("Enter your pin :")
inputpass= input("Enter your password :")
b1.pinpasscheck(inputpin,inputpass)
def pinpasscheck(self,pin,passw):
self.pin=pin
self.passw=passw
inputpin=pin
inputpass=passw
index=0
flag= False
for i in range(0,len(userpin)):
if inputpin==userpin[i]:
index=i
print(index)
if inputpass==userpass[index]:
print("Login Succeeded !")
flag= True
b1.operationlist(index)
if flag==False:
print("Login invalid. Please check username or password")
else:
pass
else:
pass
def operationlist(self,indexval):
self.indexval=indexval
index=indexval
print("\n Hello, ", username[index])
print("""
1) Balance
2) Withdraw
3) Deposit
4) Change password
5) Quit
""")
useroption = int(input("Select an option:"))
if useroption == 1:
print("\nYour current balance is {}".format(userbalance[index]))
b1.operationlist(index)
elif useroption == 2:
amount= int(input("\nEnter amount you want you want to withdraw : Rs"))
b1.withdraw(amount,index)
else:
print("None of the above options selected. Please select any one of the provided options.")
b1.operationlist(index)
def withdraw(self, amt, index):
self.amt= amt
amount = amt
self.index= index
if amount > userbalance[index]:
print("Oops! Insufficient funds.")
b1.operationlist(index)
rembalance = userbalance[index] - amount
userbalance.remove(userbalance[index])
userbalance.insert(index, rembalance)
print("Your remaining balance is: ", userbalance[index])
b1.operationlist(index)
b1 = Bank()
b1.start()
#code for VirtualDoctor
import xlrd
import pandas
from NewATM import Bank
path = "symptoms.xlsx"
book = xlrd.open_workbook(path)
sheet= book.sheet_by_index(0)
b2= Bank()
data= [[sheet.cell_value(r,c) for c in range (sheet.ncols)] for r in range (sheet.nrows)]
diseaselist= []
for i in range (1,sheet.nrows):
diseaselist.append(sheet.cell_value(i,0))
symptoms=[]
for i in range (1, data.__len__()):
tmp= data[i][1:5]
symptoms.append(tmp)
print(symptoms)
inputlist = []
b2.start() #THIS DOES NOT WORKK !!!!!!!!!!!!!!!!!!!!! WHY ???
The virtual doctor program should now go to the atm and then I can move forward with my code, but this doesn't seem to be working.
Your problem is that the code from your ATM class requires data which is set as global variables in the class itself. In terms of OOP, this is bad practice and in your particular case the code just won’t work as the variables are out of scope to the main (virtual doctor).
Either move those variables into the class itself (which is still bad practice) or keep them elsewhere and import the matrix of data when calling the class, and pass it to each individual functions.
Lastly you are creating an instance of bank called b1 to use in the class, which doesn’t make sense in terms of OOP. Change the b1 to self such that your calling the functions like self.function (one edit is changing b1.pinpasscheck() to self.pinpasscheck()).

Bank ATM Program login

I want to make this program that acts as a bank, how do I make sure the correct ID number must be entered with the correct pin and have it depending on the id you entered print hello then their name and prompt how much money they have in the bank.
attempts = 0
store_id = [1057, 2736, 4659, 5691, 1234, 4321]
store_name = ["Jeremy Clarkson", "Suzanne Perry", "Vicki Butler-Henderson", "Jason Plato"]
store_balance = [172.16, 15.62, 23.91, 62.17, 131.90, 231.58]
store_pin = [1057, 2736, 4659, 5691]
start = int(input("Are you a member of the Northern Frock Bank?\n1. Yes\n2. No\n"))
if start == 1:
idguess = ""
pinguess = ""
while (idguess not in store_id) or (pinguess not in store_pin):
idguess = int(input("ID Number: "))
pinguess = int(input("PIN Number: "))
if (idguess not in store_id) or (pinguess not in store_pin):
print("Invalid Login")
attempts = attempts + 1
if attempts == 3:
print("This ATM has been blocked for too many failed attempts.")
break
elif start == 2:
name = str(input("What is your full name?: "))
pin = str(input("Please choose a 4 digit pin number for your bank account: "))
digits = len(pin)
balance = 100
while digits != 4:
print("That Pin is Invalid")
pin = str(input("Please choose a 4 digit pin number for your bank account: "))
digits = len(pin)
store_name.append(name)
store_pin.append(pin)
I'm very impressed by how much you've elaborated on your program. Here's how I would view your solution.
So to create a login simulation, I would instead use a dictionary. That way you can assign an ID to a PIN. For example:
credentials = {
"403703": "121",
"3900": "333",
"39022": "900"
}
Where your ID is on the left side of the colon and the PIN is on the right. You would also have to assign the ID to a name that belongs to that ID using, you guessed it, a dictionary!
bankIDs = {
"403703": "Anna",
"3900": "Jacob",
"39022": "Kendrick"
}
Now that you've done that, you can create your virtual login system using if/else control flow. I've made my code like this:
attempts = 0
try:
while attempts < 3:
id_num = raw_input("Enter your ID: ")
PIN = raw_input("Password: ")
if (id_num in credentials) and (PIN == credentials[id_num]):
print "login success."
login(id_num)
else:
print "Login fail. try again."
attempts += 1
if attempts == 3:
print "You have reached the maximum amount of tries."
except KeyboardInterrupt:
print "Now closing. Goodbye!"
Note the try and except block is really optional. You could use the break operator like you did in your code if you wanted to, instead. I just like to put a little customization in there (Remember to break out of your program is CTRL-C).
Finally, Python has a way of making life easier for people by using functions. Notice I used one where I put login(id_num). Above this while loop you'll want to define your login so that you can display a greeting message for that particular person. Here's what I did:
def login(loginid):
print "Hello, %s!" % bankIDs[loginid]
Simple use of string formatting. And there you have it. The same can be done with displaying that person's balance. Just make the dictionary for it, then print the code in your login definition.
The rest of the code is good as it is. Just make sure you've indented properly your while-loop inside the elif on the bottom of your code, and your last 2 lines as well.
Hope I helped. Cheers!

I'm having issues looping through a tuple

I'm writing a program to simulate a bank scenario. It allows users (once they have logged in) to display their balance, withdraw and deposit money, and will eventually contain a transfer subroutine.
My problem is the login subroutine. I am having trouble getting my code to loop through both accounts in the tuple that saves them. I can log in to the first account and perform all the code's functions with that account but when I try to access the second account, I get the error message telling me that the account is not found. I am very certain that this is to do with the way I have written my loop but I cannot figure out how to fix it.
If someone could provide me with a solution that I can use to fix this error then I would be very grateful. If it is possible, could the solution also stick to the general format of my code and not be one where I have to create new functions and change the entire body of my LogOn function?
Here is the code:
accounts=[
["Luke",'00001','1234',1337],
["Louis",'00002','4321',420],
]
name = ""
x = []
def LogOn():
global name
global x
print ("Welcome to the Bank of Bailey")
accnum = raw_input("-please enter your account number-")
if len(accnum) != 5:
print("That number is not valid, please enter a valid number")
LogOn()
else:
for x in range(0,len(accounts)):
if accnum in accounts[x][1]:
name = accounts[x][0]
print ("Account found")
pin = raw_input("-please enter your pin-")
if pin in accounts[x]:
print ("Pin found")
MainMenu()
else:
print("Pin not found")
print("Please try again")
LogOn()
break
else:
print("Account not found")
print("Please try again")
LogOn()
The problem is:
if accnum in accounts[x][1]:
do something
else:
print("Account not found")
print("Please try again")
LogOn()
The else branch is called already for the first iteration (with x = 0)!
You should check after the while-loop if an account was found and otherwise print your error message.
Instead of recursing to LogOn() you could better use an outer (endless-)while-loop which calls LogOn(). In LogOn then just do a return in error case.
A few observations:
The else branch is called on the first iteration when x=0. You need to finish the for loop, then branch if the account has not been found.
if pin in accounts[x] is a security hole because it allows people to use their name or account number as their pin!
"if accnum in account[1]" should be "if accnum == account[1]"
Hope that helps!
accounts=[
["Luke",'00001','1234',1337],
["Louis",'00002','4321',420],
]
name = ""
x = []
def LogOn():
global name
global x
print ("Welcome to the Bank of Bailey")
accnum = raw_input("-please enter your account number-")
if len(accnum) != 5:
print("That number is not valid, please enter a valid number")
LogOn()
else:
found = False
for account in accounts:
if accnum == account[1]:
found = True
name = account[0]
print ("Account found")
pin = raw_input("-please enter your pin-")
if pin in account[2]:
print ("Pin found")
MainMenu()
else:
print("Pin not found")
print("Please try again")
LogOn()
break
if not found:
print("Account not found")
print("Please try again")
LogOn()
I like #TimSC's answer, but I'll add a few more observations:
LogOn is not a good function name; it should be log_on to match PEP8 naming conventions (LogOn suggests it is a class rather than a function).
You declare name and x as globals, then never use them. Globals are almost always a bad idea, and unused declarations just clutter your code.
As #CTX pointed out, you are using recursion (LogOn calling LogOn calling MainMenu calling LogOn etc) where iteration would make a lot more sense - you should back out on an error, not call again a level deeper.
Mixing input/output code and action code is usually a bad decision; it makes your code less flexible and reusable and often harder to debug as well. You should instead have an input/output function which calls an action function with the values it needs.
Giving separate error messages for bad account number, bad pin number is a security hole; it makes it much easier for would-be attackers to find valid account numbers to attack.
Looking things up in a list is relatively slow (O(n) ie time proportional to the number of items in the list). Use a dict instead (O(1) ie constant time - a quick hash calculation takes you right to the item you are looking for).
Here is a fancied-up version; may it give you things to think about:
import sys
# version compatibility shim
if sys.hexversion < 0x3000000:
inp = raw_input # Python 2.x
else:
inp = input # Python 3.x
class Account:
index = {}
__slots__ = ("accnum", "pin", "name", "balance")
#classmethod
def log_in(cls, accnum, pin):
key = (accnum, pin)
acc = Account.index.get(key, None)
if acc is None:
raise ValueError("No such login (bad account# or PIN)")
else:
return acc
def __init__(self, accnum, pin, name, balance):
# save values
self.accnum = accnum
self.pin = pin
self.name = name
self.balance = balance
# add self to account index
key = (accnum, pin)
Account.index[key] = self
# create accounts
Account('00001', '1234', "Luke", 1337)
Account('00002', '4321', "Louis", 420)
def main():
while True:
print("\nWelcome to the Bank of Bailey")
accnum = inp("Please enter your account number: ").strip()
pin = inp("Please enter your PIN: ").strip()
try:
acc = Account.log_in(accnum, pin)
print("\nYour account has a current balance of ${:0.2f}".format(acc.balance))
print("Thank you for banking with us!")
except ValueError as ve:
print(ve)
if __name__ == "__main__":
main()

Using Python Class to make game- how to update self init?

I am making a text-based game on python using the class system to keep track of main character changes (like its name). I am writing the main code for the game outside of the Main Character Class- inside of the main function.
I am struggling because I need to update self.character_name inside the Main Character class to an input from the user inside the main function. I am unsure how to do this, I have the code written below- however it is not updating the name inside Main Character class. How can I rewrite this?
I'm also worried that I will have this problem when trying to update pets, characters_known. However, I do not seem to have this problem with updating Health or XP....
class Main_Character():
def __init__(self):
self.health=100
self.exp=0
self.level=0
self.character_name=""
self.characters_known={None}
self.pets={None}
self.progression_tracker=0
def __str__(self):
return "Name: "+ str(self.character_name)+" | "+ "Health:"+ str(self.health) + " | " +"XP:"+ str(self.exp) + " | "+ "Level:"+ str(self.level)+" | "+"Pets:"+str(self.pets)
def Char_Name(self,name):
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
else:
self.character_name=name
def Char_Level_Experience(self,exp,b):
self.exp+=exp
b=2
if exp<=0:
exp=1
ans = 1
level=0
while ans<exp:
ans *= b
level += 1
if ans == exp:
self.level=level
print("You have reached level", self.level)
else:
level = int(log(exp, 2))
level = min(level, exp)
if level>=0:
self.level=level
else:
level=0
def healing(self,heal):
if self.health+heal>=100:
self.health=100
else:
self.health+=heal
def other_answers(answer):
if answer=='quit':
raise SystemExit
if answer=='pets':
print("Pets owned:", Main_Character().pets)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
elif Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
if answer=='characters':
print("Characters met:", Main_Character().characters_known)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu:")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
if Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
def start_check():
print("If you understand the game, type 'go' to continue- if not, type 'more information' to receive more information about how to play the game")
begin_game=input("")
if begin_game=="go":
choice1()
if begin_game=='more information':
print("\n","The object of the game is to gain XP [experience points] without dying")
start_check()
else:
other_answers(begin_game)
def choice1():
Main_Character().progression_tracker=1
print("You are a knight in the Kings Guard- the King has asked to meet with you about a very special mission")
print("What would you like to do?")
print(" 1.Go Directly to King","\n", "2. Finish your dinner")
choice=input("1 or 2?")
if choice=="1":
Main_Character().Char_Level_Experience(1,2)
elif choice=="2":
Main_Character().Char_Level_Experience(.5,2)
else:
other_answers(choice)
print(Main_Character())
def main():
print("Welcome!")
unfiltered_name=input("Please enter the name of your character:")
Main_Character().Char_Name(unfiltered_name)
print("Welcome,", Main_Character().character_name,"!", "Here are your current stats!")
print(Main_Character())
start_check()
You haven't quite understood how classes and instances work.
Calling the class is what you do when you need a new character. Every time you call Main_Character(), you get a whole new instance - with the default values as set in __init__. If you had characters for each of your friends, you would call it one time for each one. You then would need to keep each of those instances in a variable, so you can reference them again each time.
So, for instance:
my_character = Main_Character()
unfiltered_name=input("Please enter the name of your character:")
my_character.Char_Name(unfiltered_name)
print("Welcome,", my_character.character_name,"!", "Here are your current stats!")
print(my_character)
You create a new character each time you call Main_Character. Instead, you should call it once:
the_character = Main_Character()
...
the_character.name = "..."

Categories