第三天主要是先处理第二天布置的作业题ATM机:
例题:用python编写一个ATM存取款机的模拟程序,要求如下:
- 添加如下操作主菜单,并实现菜单中的每个功能。
******************欢迎来到WoniuATM********************
*******************请选择操作菜单*********************
*********1. 注册 2. 登录 3. 查询余额 4. 存款 5. 取款 6.转账 7.取卡 *******
注意:存取款要求只能是100的整数倍。
- 注册时,判断用户名是否已存在,密码长度要大于等于6位,如果输入错误要有相应提示。
登录时,要求用户输入用户名和密码,只有当用户名和密码均正确才能提示用户登录成功,否则提示用户名或密码错误。
注意,不管是注册阶段还是登录阶段,一旦用户输入错误,都将提示用户重新输入,直到正确为止。
用户信息分别包含姓名、密码以及余额,保存格式如下:
user_list = [{‘name’: ‘zhangsan’, ‘password’:‘123’, ‘balance’: 0}, {}, {}, …]
解答:
老师的代码将每个功能模块写成了一个一个的函数,需要使用的时候直接调用。
login_User
其实是一个列表,它的作用是记录当前用户是否已经进行了登录操作,在进行取款,存款功能的时候,会去查验用户的信息,如果没有登录就提示用户登录。
核心思想:
1、在进行 存款,取款,转账的功能的时候都会去查看用户信息,是否登录
2、在while循环里的if条件语句块下使用continue:表示条件符合,继续循环while里的语句块------->>密码小于6位,重新输入
3、如何对输入的username和user _list比较才是关键,首先进行遍历,取出字典类型的数据,然后使用字典查询功能进行比较
while True:
username = input("请输入用户名:")
password = input("请输入密码:")
if len(password) < 6:
print("密码长度必须大于6位!!")
continue
for user_info in user_list:
if username == user_info["name"]:
print("用户名已经存在")
break
else:
# 用户输入满足要求
break
4、将注册信息添加到列表:
user_list.append({'name': username, 'password': password, 'balance': 0})
5、函数方法内部想要改变全局变量,应该在方法内部重新使用global 定义该变量,这样就可以修改了
global 的实例: 在login中,当登录用户经过验证为真的时候,应该记录下登陆的用户,方便后面进行取款操作。。
def login():
global login_User
while True:
username = input("请输入用户名:")
password = input("请输入密码:")
for user_info in user_list:
if username == user_info['name'] and password == user_info['password']:
login_User = username
print(f"{username}登录成功!")
break
f语句(经常用 )使用示例:
print(f"{username}登录成功!")
print(f"{username}的账户余额为{user_info['balance']}")
判断 是否为入口程序
if __name__ == '__main__':
operate_atm()
面向对象编程 OOP(oriented object programmer)
封装 继承 多态
python可以继承多个类,但是python是没有接口这个东西
2.1定义类
class 类名:
类成员
class Student:
'''
学生类
'''
def __init__(self):
#魔法方法,初始化实例的属性,self 表示实例对象,f:field
self.name = None
self.age = 0
2.2使用类创建类的实例对象
类名()
2.3访问类的实例对象的属性
实例名.属性名 = 值,也可以修改属性的值
s1 = Student()
print(s1.name)
s1.name = "zhangsan"
s1.age = 18
print(s1.age)
print(s1.name)
访问一个不存在的属性,相当于添加了一个属性!!!!!!规定!!!!!
s1.dddd = "sss"
print(s1.dddd)
一个完整的类
class XiNanStudent(object):#所有的类都继承object
#学校都是相同的 :swpu
#name
#age
#score 成绩
#exam(考试)
#run
#自我介绍 introduce
school = "swpu" 类属性
def __init__(self,name,age):
self.name = name 实例的属性
self.age = age
self.score = 0
def exam(self):
//实例方法
print(f"{self.school}的学生在努力答题,coding!")
self.score = 90
@classmethod
//添加classmethod 装饰器,声明这个method是一个 类方法
def introduce(cls):
print(f"i am from {cls.school}")
@staticmethod
//添加staticmethod 装饰器,声明这个method是一个静态方法
def run():
#不需要访问属性
print("馒头大汉,爬了5000 米")
student1 = XiNanStudent("王",18)
student2 = XiNanStudent("芭",18)
student3 = XiNanStudent("玨",18)
student1.exam()
student2.introduce()
student3.run()
2.4单继承
简单的例子:Mylist 继承了list 列表
class Mylist(list):
pass
mylist = Mylist()
mylist.append(1)
mylist.append(2)
print(mylist)
[1, 2]
class NewStudent(XiNanStudent):#表示类的继承,添加括号
# 装电脑
# python成绩 score python
def __init__(self,name,age):
self.scorePython = 0
super().__init__(name,age) #super()查找父类实例的对象
def build_up_computer(self):
print(f"{self.name}在组装电脑。。。")
student1 = NewStudent("王八",16)
student1.build_up_computer()
student1.run()
student1.introduce()
多继承
class A(object):
def add(self):
print("A:add")
class B(A):
def add(self):
print("B:add")
super().add()
class C(A):
def add(self):
print("C:add")
super().add()
class D(B,C):
def add(self):
print("D:add")
super().add()#super 按mro 顺序返回的父类对象,去当前类后面的父类对象
# mro
D().add()
# D:add
# B:add
# C:add
# A:add
# 在python 中 多继承通常用来实现 装饰器设计模式
ATM机的完整代码:
user_list = [{'name': 'zhangsan', 'password': '123', 'balance': 1000},
{'name': 'lisi', 'password': '', 'balance':0},
{'name': '', 'password': '', 'balance':0},
]
login_User = None
def operate_atm():
'''
操作 atm 功能,有atm机的所有功能
1.显示操作菜单
2.接收用户输入,选择操作菜单
3.根据选择的菜单 执行对应的功能
4.
:return:1. 注册 2. 登录 3. 查询余额 4. 存款 5. 取款 6.转账 7.取卡
'''
while True:
show_menu()
selection = input("请选择操作")
if selection == '1':
register()
elif selection == '2':
login()
elif selection == '3':#3. 查询余额
check_balances(login_User)
elif selection == '4':#4. 存款
if login_User:
deposit(login_User)
else:
print("请先登录")
elif selection == '5': #5. 取款
if login_User:
withdrawal(login_User)
else:
print("请先登录")
elif selection == '6':
if login_User:
transfer(login_User)
else:
print("请先登录")
elif selection == '7':
if login_User:
transfer(login_User)
else:
print("请先登录")
else:
print("请输入正确的操作")
def show_menu():
'''
显示atm的操作菜单
******************欢迎来到WoniuATM********************
*******************请选择操作菜单*********************
*********1. 注册 2. 登录 3. 查询余额 4. 存款 5. 取款 6.转账 7.取卡 *******
:return:
'''
print(''' 显示atm的操作菜单
******************欢迎来到WoniuATM********************
*******************请选择操作菜单*********************
*********1. 注册 2. 登录 3. 查询余额 4. 存款 5. 取款 6.转账 7.取卡 *******
''')
# 1. 注册 2. 登录 3. 查询余额 4. 存款 5. 取款 6.转账 7.取卡
def register():
'''
完成用户注册的逻辑
1.提示用户输入用户名和密码(接收用户输入)
2.检查用户输入的用户名和密码是否正确(检查输入)
2.1检查用户名是否重复,密码是否大于等于6位
2.2 如果检查通过进行第三步,否则提示错误信息,回到第一步
3.处理注册的业务逻辑:(处理业务逻辑)
3.1把用户名和密码添加到用户信息存储的列表中
:return:
'''
while True:
username = input("请输入用户名:")
password = input("请输入密码:")
if len(password) < 6:
print("密码长度必须大于6位!!")
continue
for user_info in user_list:
if username == user_info["name"]:
print("用户名已经存在")
break
else:
# 用户输入满足要求
break
user_list.append({'name': username, 'password': password, 'balance': 0})
print(f"{username}注册成功")
pass
def login():
'''
完成用户登录
1.提示用户输入用户名和密码(接收用户输入)
2.检查用户输入的用户名和密码是否正确(无)
3.处理业务逻辑
3.1检查用户名和密码是否和存储信息匹配
3.2如果正确,保持登录状态----->>把用户登录信息存起来
3.3错误:提示错误,回到第一步
:param username:
:param password:
:return:
'''
global login_User
while True:
username = input("请输入用户名:")
password = input("请输入密码:")
for user_info in user_list:
if username == user_info['name'] and password == user_info['password']:
login_User = username
print(f"{username}登录成功!")
break
else:
print("用户名或者密码不正确")
continue
# 当用户名密码输入正确,登录成功
break
def check_balances(username):
'''
完成查询指定用户的账户余额的逻辑
1.检查用户是否已经登录
2.如果用户已经登录,从存储用户信息的列表中获取余额信息,打印余额信息
:param username:
:return:
'''
if not username :
print("请登录账户,再查询余额")
return None
for user_info in user_list:
if user_info["name"] == username:
print(f"{username}的账户余额为{user_info['balance']}")
break
pass
def deposit(username):
"""
完成存款的逻辑
1. 接受用户输入,提示输入存款的金额
2. 检查用户输入,检查存款金额是否是 100 的整数倍,如果有错误,重新输入
3. 处理业务逻辑,把存款的金额添加到用户信息存储列表中
:param username: 存款的账户
:return:
"""
count = input_count()
for user_info in user_list:
if user_info['name'] == username:
user_info['balance'] += count
print(f"{username}账户余额为{user_info['balance']}")
pass
def input_count():
while True:
count = input("请输入存款金额")
if len(count) < 3:
print("请输入100的整数倍")
continue
if not '1' <= count[0] <= '9':
print("请输入100的整数倍")
continue
for c in count[1:]:
if not '0' <= c <= '9':
print("请输入100的整数倍")
break
else:
# count 字符可以转换为整数
count = int(count)
if count % 100 != 0:
print("请输入100的整数倍")
continue
else:
break
return count
def withdrawal(username):
"""
完成取款的逻辑
1. 接受用户输入,提示输入取款的金额
2. 检查用户输入,检查取款金额是否是 100 的整数倍,如果有错误,重新输入
3. 处理业务逻辑
3.1 检查取款金额是否大于余额,如果比余额大,提示错误信息,重新输入
3.2 把取款的金额从用户信息存储列表中减掉
:param username: 取款的账户
:return:
"""
while True:
count = input_count()
user_info = find_user_info(username)
if user_info["balance"] < count:
print(f"余额不足{count}")
continue
else:
break
user_info['balance'] -= count
print(f"取款成功,{username}账户余额还剩{user_info['balance']}")
pass
def find_user_info(username):
"""
从用户信息存储列表中查找用户信息存储的字典
:param username:
:return:
"""
for user_info in user_list:
if user_info["name"] == username:
return user_info
else:
return None
def transfer(username):
"""
完成转账的逻辑
1.接受用户输入,输入收款人的账户信息,转账的金额
2.检查用户的输入
2.1 检查收款人的账户是否存在,如果不存在提示错误信息,重新输入
2.2 检查转账的金额是否大于当前账户的余额,如果比余额大,提示错误信息
3.处理转账的业务逻辑
3.1 如果没有问题,从当前账户中扣掉转账的金额
3.2 在收款人的账户中添加上转账的金额
:param username: 转账的账户
:return:
"""
while True:
to_account = input("请输入收款人的账户信息")
to_account_user_info = find_user_info(to_account)
if to_account_user_info is None:
print("收款人账户信息不存在")
continue
else:
break
_pass = True
while _pass:
count = input("请输入转账金额")
try:
count = int(count)
except:
print("转账金额请输入整数")
pass
else:
user_info = find_user_info(username)
if count < user_info["balance"]:
_pass = False
to_account_user_info['balance'] += count
user_info = find_user_info(username)
user_info['balance'] -= count
print(f"{username}的账户余额为{user_info['balance']},"
f"{to_account_user_info['name']}的账户余额为{to_account_user_info['balance']}")
pass
def exit():
"""
取卡,退出操作 atm 机
注销用户登录
:return:
"""
global login_user
login_user = None
pass
if __name__ == '__main__':
operate_atm()