我正在使用python代码创建ATM,并且需要创建行为类似于ATM的存款和提取功能。另外,充值和提款功能起作用。但是,当我先提款然后存款时,余额不会更新。当我存入然后取出时,也是一样。
感谢您的帮助。
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
counter = 0
while counter <= 2:
while counter == 0:
withdraw = int(input("Enter the amount you want to withdraw: AED "))
counter = counter + 1
while ((int(balance) - int(withdraw)) < 0):
print("Error Amount not available in card.")
withdraw = int(input("Please enter the amount you want to withdraw again: AED "))
continue
while ((float(balance) - float(withdraw)) >= 0):
print("Amount left in your account: AED" + str(balance - withdraw))
return (balance - withdraw)
counter = counter + 1
def deposit():
counter = 0
while counter <= 2:
while counter == 0:
deposit = int(input("Enter amount to be deposited: "))
counter = counter + 1
while ((int(balance) + int(deposit)) >= 0):
print("Amount left in your account: AED" + str(balance + deposit))
return (balance + deposit)
counter = counter + 1
withdraw()
deposit()
如果我提取17,则余额为583。但是,当我存入12时,余额变为612,这是错误的,应该为595。
答案 0 :(得分:4)
您根本没有更改“余额”变量! 您的代码应类似于:
balance = withdraw()
balance = deposit()
但是您的代码还有其他多个问题。 首先,您不应该进行那么多的转换。您必须将用户输入一次转换为数字,然后只计算该类型的所有内容。 您正在使用float和int。如果您想充入货币,则应该使用十进制(https://docs.python.org/2/library/decimal.html),因为在某些特殊情况下(需要四舍五入)浮点运算并不精确,而整数显然不提供浮点运算。>
您的特殊“ while”用法也不符合常见的编码标准,并且使您的代码难以阅读。最好编写一个函数来获取用户输入并将其与提现()和deposit()逻辑分开。
编辑:由于您似乎是一个初学者,所以我将提供一个最小的可行解决方案。
import decimal
balance = 600
def get_user_input(action):
# Get user input and convert it to decimal type
return decimal.Decimal(input("Please enter amount to {} from your account: ".format(action)))
def withdraw():
amount = get_user_input("withdraw")
return balance - amount
def deposit():
amount = get_user_input("deposit")
return balance + amount
print("Your Balance is {} AED".format(balance))
balance = withdraw()
balance = deposit()
print("Your Balance is {} AED".format(balance))
答案 1 :(得分:2)
您只是忘记保存新余额,而只是打印出
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
while True:
withdraw = int(input("Enter amount to be withdrawn: "))
if withdraw > balance:
print("Error Amount not available in card.")
else:
new_balance = balance - withdraw
print("Amount left in your account: AED" + str(new_balance))
return (new_balance)
def deposit():
deposit = int(input("Enter amount to be deposited: "))
new_balance = balance + deposit
print("Amount left in your account: AED" + str(new_balance))
return (new_balance)
# This is the only place you HAVE to change for it to work
balance = withdraw()
balance = deposit()
可以自由更改它,但最重要的是,您应该保存新的余额。
我还建议通过在将整数转换为整数之前检查它是否为整数来使整数转换更安全。
withdraw_string = input("Enter amount to be withdrawn: ")
try:
withdraw_int = int(withdraw_string)
is_int = True
except ValueError:
print("INVALID INPUT")
is_int = False
if is_int == True:
答案 2 :(得分:1)
在deposit()
和widthdraw()
函数中,您从未真正接触过保持平衡的变量,这就是为什么看不到更改的原因。
您已经定义了变量 balance ,但是您从未使用balance = balance - x
更新该值。您仅使用str(balance + deposit)
打印该数学运算的结果,该代码实际上并不会改变您的余额。
要更改您的余额,您需要使用balance += widthdraw
更新该全局变量。但是,如果将该代码放入代码中,则会出现以下错误:
UnboundLocalError:分配前引用了本地变量'balance'
这是因为为了从函数内部更新全局变量,您需要使用 global 关键字,以便可以链接到全局变量。 Docs.
下面的代码现在可以正常工作了,以下两行是重要的:
balance -= withdraw
balance += deposit
这就是您实际上在修改 balance 变量中的值的方法,而不是仅查看数学运算的输出。
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
global balance
counter = 0
while counter <= 2:
while counter == 0:
withdraw = int(input("Enter the amount you want to withdraw: AED "))
counter = counter + 1
while ((int(balance) - int(withdraw)) < 0):
print("Error Amount not available in card.")
withdraw = int(input("Please enter the amount you want to withdraw again: AED "))
continue
while ((float(balance) - float(withdraw)) >= 0):
balance -= withdraw
print("Amount left in your account: AED " + str(balance))
return (balance)
counter = counter + 1
def deposit():
global balance
counter = 0
while counter <= 2:
while counter == 0:
deposit = int(input("Enter amount to be deposited: "))
counter = counter + 1
while ((int(balance) + int(deposit)) >= 0):
balance += deposit
print("Amount left in your account: AED" + str(balance))
return balance
counter = counter + 1
withdraw()
deposit()
免责声明:您绝对可以从提现和存款中删除您的 return语句,因为它们实际上是无用的用这种方式解决问题。为什么没用?因为全局变量 balance 在方法内部被修改。如果您在方法之外修改了余额,则 return语句将很有用。像这样:
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
counter = 0
while counter <= 2:
while counter == 0:
withdraw = int(input("Enter the amount you want to withdraw: AED "))
counter = counter + 1
while ((int(balance) - int(withdraw)) < 0):
print("Error Amount not available in card.")
withdraw = int(input("Please enter the amount you want to withdraw again: AED "))
continue
while ((float(balance) - float(withdraw)) >= 0):
tmp_balance -= withdraw
print("Amount left in your account: AED " + str(tmp_balance))
return tmp_balance
counter = counter + 1
def deposit():
counter = 0
while counter <= 2:
while counter == 0:
deposit = int(input("Enter amount to be deposited: "))
counter = counter + 1
while ((int(balance) + int(deposit)) >= 0):
tmp_balance += deposit
print("Amount left in your account: AED" + str(tmp_balance))
return tmp_balance
counter = counter + 1
balance = withdraw()
balance = deposit()
通过第二种方法,您将根据方法提供给您的回报来操纵 balance 的值。此处的区别在于,当您致电提款或存款时,实际上并没有执行该操作,只有在您使用{{1 }}。这样做有一个很好的好处,那就是确保没有异常发生,并且如果提现或存款完全以100%完成,那么您可以提交更改。
我决定对代码进行进一步介绍,因为您似乎对 int , floats 和while循环进行了很多转换。
下面是一个示例,介绍了如何实现该方法,以防给任何人更多的想法:(请记住,代码没有单一的路径,我们的代码都不同)
balance = withdraw()
字符串格式。现在是代码。
f""
让我们一点一点地经历它。
装饰器是这个。
def exit_on_input_cast_error(func):
def wrapper(arg):
try:
return func(arg)
except ValueError as ex:
print("Exiting, bye.")
exit()
return wrapper
class ATM():
"""A simple atm machine"""
def __init__(self, balance):
self.cash_available = balance
@exit_on_input_cast_error
def withdraw(self):
'''Withdraws entered amount, until user exits'''
continue_withdraw = True
while continue_withdraw:
withdraw_amount = self._get_withdraw_input()
self.cash_available -= withdraw_amount
self.print_balance("left in")
withdraw_again = str(input("Would you like to withdraw another amount? (Y or N)"))
continue_withdraw = withdraw_again.lower() in ['1', 'y', 'yes']
self.print_bye()
@exit_on_input_cast_error
def _get_withdraw_input(self):
input_error = True
while input_error:
withdrawl = int(input("Enter the amount you want to withdraw (Press N to exit): AED "))
if (self.cash_available - withdrawl) < 0:
print("Error Amount not available in machine.")
input_error = True
elif (self.cash_available - withdrawl) > self.cash_available:
print("Error, you can't withdraw a negative amount.")
input_error = True
else:
input_error = False
return withdrawl
@exit_on_input_cast_error
def deposit(self):
input_error = True
while input_error:
depositing = int(input("Please enter the amount you want to deposit (Press N to exit): AED "))
if (self.cash_available + depositing) < self.cash_available:
print("You cannot deposit a negative amount.")
else:
input_error = False
self.cash_available += depositing
self.print_balance("now in")
self.print_bye()
def print_balance(self, custom_insert = 'in'):
print(f"Amount {custom_insert} your account: AED {self.cash_available}")
def print_bye(self):
print("Thank you for using our services today, bye.")
那只是装饰器的语法。重要的部分是 return func(arg)。这就是将要捕获的功能。因此,此装饰器仅负责捕获 ValueError 异常,当您尝试投射类似def exit_on_input_cast_error(func):
def wrapper(arg):
try:
return func(arg)
except ValueError as ex:
print("Exiting, bye.")
exit()
return wrapper
之类的异常时可以抛出该异常。此修饰符旨在防止用户尝试将字符串撤回或存放到atm机中。由于这是您将同时用于提款或存款输入的代码,因此我将其放置为装饰器,以便于调用(Hello DRY原理)。
接下来,我们有了类构造器。我希望您熟悉类,如果您不熟悉它们,可以查找很多链接和文档,以了解类和方法之类的区别你原来有。在这种情况下,最大的优势是您可以拥有多个atm,每个atm拥有不同的现金量。或者,您可以实例化一个ATM类,并为其进行配置,例如语言或硬币类型。这样的东西。
int('a')
用于定义类的就是normal syntax。 “”“简单的atm机”“”是 docstring ,因此,当您调用类 .__ doc __ 时,您会得到回报。
现在有了好东西。
class ATM():
"""A simple atm machine"""
def __init__(self, balance):
self.cash_available = balance
此方法用于处理获取用户的输入。看到它如何装饰为 @exit_on_input_cast_error ?这意味着,如果用户输入'a',则程序退出。这是因为@exit_on_input_cast_error
def _get_withdraw_input(self):
input_error = True
while input_error:
withdrawl = int(input("Enter the amount you want to withdraw (Press N to exit): AED "))
if (self.cash_available - withdrawl) < 0:
print("Error Amount not available in machine.")
input_error = True
elif (self.cash_available - withdrawl) > self.cash_available:
print("Error, you can't withdraw a negative amount.")
input_error = True
else:
input_error = False
return withdrawl
强制转换将引发装饰器捕获的 ValueError 异常。该方法以伪代码执行以下操作:
int(...)
基本上就是这种方法的作用。它一直要求用户输入有效的输入,直到用户输入有效的输入,或者输入“ N”退出。以及为什么当他们输入“ N”时退出。由于“ N”不是 int ,因此,在此行中进行强制转换时:
while there's an error do the following:
Get the user input and cast it as an int.
Make sure the amount user has introduced matches the following criteria:
It is not more than the cash available in the atm.
It is not a negative number.
int()将引发 ValueError ,然后由方便的装饰器 withdrawl = int(input("Enter the amount you want to withdraw (Press N to exit): AED "))
捕获异常。然后打印“再见”并为您退出。酷吧?
接下来是您实际使用的提现方法。现在的区别是只有一个循环会继续询问用户是否希望在操作完成后再次退出。由用户决定退出还是再次退出。
@exit_on_input_cast_error
使用伪代码:
@exit_on_input_cast_error
def withdraw(self):
'''Withdraws entered amount, until user exits'''
continue_withdraw = True
while continue_withdraw:
withdraw_amount = self._get_withdraw_input()
self.cash_available -= withdraw_amount
self.print_balance("left in")
withdraw_again = str(input("Would you like to withdraw another amount? (Y or N)"))
continue_withdraw = withdraw_again.lower() in ['1', 'y', 'yes']
self.print_bye()
从本质上讲,这就是方法的作用。它使用了用于打印消息的新方法。
while the user wants to withdraw:
Get the user input
Check that the withdraw action does not result in 0 or negative number.
Print the balance
Ask the user if they want to withdraw again.
可以调用这些方法并传递消息的自定义部分,例如 print_balance 。它们显示 ATM 类的私有类变量。在提款方法中,我必须指出,您可以提款直至达到0。这台机器将让您尝试继续提款,但由于其中有0现金,它不会让您提款。 。
最后是存款方法。
def print_balance(self, custom_insert = 'in'):
print(f"Amount {custom_insert} your account: AED {self.cash_available}")
def print_bye(self):
print("Thank you for using our services today, bye.")
如您所见,非常简单并且遵循相同的原理。这是调用实际方法的方式:
@exit_on_input_cast_error
def deposit(self):
input_error = True
while input_error:
depositing = int(input("Please enter the amount you want to deposit (Press N to exit): AED "))
if (self.cash_available + depositing) < self.cash_available:
print("You cannot deposit a negative amount.")
else:
input_error = False
self.cash_available += depositing
self.print_balance("now in")
self.print_bye()
这是代码的输出:
atm_a = ATM(600)
atm_a.withdraw()
如果您要提款和存款:
Enter the amount you want to withdraw (Press N to exit): AED 100
Amount left in your account: AED 500
Would you like to withdraw another amount? (Y or N)Y
Enter the amount you want to withdraw (Press N to exit): AED -1
Error, you can't withdraw a negative amount.
Enter the amount you want to withdraw (Press N to exit): AED 501
Error Amount not available in machine.
Enter the amount you want to withdraw (Press N to exit): AED 5
Amount left in your account: AED 495
Would you like to withdraw another amount? (Y or N)yes
Enter the amount you want to withdraw (Press N to exit): AED 5
Amount left in your account: AED 490
Would you like to withdraw another amount? (Y or N)no
Thank you for using our services today, bye.
以下是代码的输出:
atm_a = ATM(600)
atm_a.withdraw()
atm_a.deposit()
请注意,您只能存入一次,然后存入。那是因为我没有实现它,因为我已经为提现做过。任何人都可以根据需要在存款中复制它。
我希望这不是太多,我设法解释了一下。有很多事情无法添加:
答案 3 :(得分:0)
我同意@Chetan Ranpariya的建议,您尚未在代码中同时更改两个函数的balance
变量。您可以使用表达式balance
,balance += <increase amount>
或balance -= <decrease amount>
等来更改balance = balance + <increase amount>
变量。
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
counter = 0
while counter <= 2:
while counter == 0:
withdraw = int(input("Enter the amount you want to withdraw: AED "))
counter = counter + 1
while ((int(balance) - int(withdraw)) < 0):
print("Error Amount not available in card.")
withdraw = int(input("Please enter the amount you want to withdraw again: AED "))
continue
while ((float(balance) - float(withdraw)) >= 0):
print("Amount left in your account: AED" + str(balance - withdraw))
return (balance - withdraw)
counter = counter + 1
def deposit():
counter = 0
while counter <= 2:
while counter == 0:
deposit = int(input("Enter amount to be deposited: "))
counter = counter + 1
while ((int(balance) + int(deposit)) >= 0):
print("Amount left in your account: AED" + str(balance + deposit))
return (balance + deposit)
counter = counter + 1
balance = withdraw()
balance = deposit()
答案 4 :(得分:0)
您没有更改balance
变量,仅返回添加或减少了deposit
或withdraw
的值。
尝试更改您的代码,以便在返回之前保存新的balance
。所以代替:
print("Amount left in your account: AED" + str(balance - withdraw))
return (balance - withdraw)
尝试:
balance = (balance - withdraw)
print("Amount left in your account: AED" + str(balance))
return balance
然后使用deposit
函数进行相同操作。
您的新代码:
balance = 600
def withdraw(): # asks for withdrawal amount, withdraws amount from balance, returns the balance amount
counter = 0
while counter <= 2:
while counter == 0:
withdraw = int(input("Enter the amount you want to withdraw: AED "))
counter = counter + 1
while ((int(balance) - int(withdraw)) < 0):
print("Error Amount not available in card.")
withdraw = int(input("Please enter the amount you want to withdraw again: AED "))
continue
while ((float(balance) - float(withdraw)) >= 0):
balance = (balance - withdraw)
print("Amount left in your account: AED" + str(balance))
return balance
counter = counter + 1
def deposit():
counter = 0
while counter <= 2:
while counter == 0:
deposit = int(input("Enter amount to be deposited: "))
counter = counter + 1
while ((int(balance) + int(deposit)) >= 0):
balance = (balance + deposit)
print("Amount left in your account: AED" + str(balance))
return balance
counter = counter + 1
withdraw()
deposit()