一. 基础题
1. 集合内元素的三个特征什么是?
"""
1. 集合内元素无序
2. 集合内元素必须为不可变类型
3. 集合内元素唯一
"""
2. 集合的用途是什么?
"""
去重, 关系运算
"""
3. 如何解决python3乱码问题
"""
你使用的编辑器使用什么字符编码存入硬盘的,你就指定文件头 (encoding: 存入硬时的字符编码) 就使用什么编码类型.
# 标准: 指定文件头 # encoding: 与文件存的编码格式一致
"""
4. 控制文件读写内容的模式
"""
t: 文本模式, 只能读取文本文件.
b: bytes模式, 可以读取任意类型的文件. # 补充: b模式也叫二进制模式
"""
5. 控制文件读写操作的模式
"""
r: 只读模式.文件不存在报错,文件存在文件指针在起始位置.
w: 只写模式. 文件不存在创建, 文件存在则清空原文件中的数据.文件指针在起始位置.
a: 只追加模式. 文件不存在创建, 文件存在则在文件末尾追加写内容.文件指针在结束位置.
x: 只写模式. 文件不存在创建, 文件存则报错.文件指针在起始位置.
以下三种模式都是以加号左边的模式为基准来控制文件读写操作:
r+: 可读可写模式.
w+: 可写可读模式.
a+: 可追加写刻度模式.
x+: 可写可读模式.
"""
6. 文件操作的基本操作流程是什么(注意)?
"""
1. 调用open功能让操作系统按照指定的路径去打开文件, 并赋值给一个f句柄对象
2. 当执行到f.read()操作,操作系统按照控制文件读写操作的模式去操作文件
3. 操作系统把文件从硬盘读入内存,按照指定的字符编码解码,加载到内存解码为unicode(等同于字符串)
4. 当执行完毕f.read()操作,文件指针移动到文件的末尾.操作完文件以后执行f.close()操作,回收操作系统资源.
# 标准:
1. 打开文件
2. 读取内容
3. 关闭文件
"""
7. 文件处理with的好处是什么(注意)?
"""
with简称上下文管理: 上, 帮我们操作指定文件的一系列操作 下, 帮我们自动回收操作系统资源(自动调用f.close())
# 标准: with称之为上下文管理, 上文帮你打开文件, 下文帮你关闭文件
"""
8. 为何要用文件?
"""
永久保存数据不丢失 # 详细: 用户或者应用程序可以通过文件, 将数据永久保存到硬盘中
"""
9. 什么是函数?
"""
函数就是执行某一特定功能的工具. # 订正: 函数就是具备某一功能的工具
"""
10. 函数的使用,必须先遵循什么?
"""
先定义 后调用
"""
11. 为何要用函数?
"""
1. 增加程序的可维护性, 可扩展性
2. 减少代码冗余问题 # 订正: 解决代码冗余问题
3. 让程序体结构清晰,功能区分增强了可读性.
"""
12. 定义函数会发生什么事情?
"""
1. 申请内存空间保存函数体代码
2. 将上述内存地址与函数名进行绑定, # 补充: 且函数名最好使用动词
3. 定义函数阶段不执行函数体代码, 只检测语法.
"""
13. 调用函数发生的事情
"""
1. 通过函数名找到对应的函数体代码的内存地址 # 订正: 通过函数名找到函数的内存地址
2. 通过加括号, 触发函数体代码的执行
3. 这个时候开始检测函数体代码内的语法.
"""
14. 定义函数的三种形式分别是什么?
"""
无参:
def func():
print("from func")
有参:
def func(x):
print(x)
空函数:
def func():
pass
"""
15. 函数调用的三种形式分别是什么?
"""
语句形式:
func()
表达式:
赋值表达式
res = func()
print(res)
数学表达式
add(1, 2) * 10
调用结果的返回值作为参数:
add(add(1, 2), 3)
"""
16.函数的返回值是否可以返回多个?是否可以返回所有数据类型?
"""
1. 可以返回多个,每个值以逗号隔开,且返回的是一个元组的格式.
2. 可以返回所有数据类型.
"""
17. 什么是形参?什么是实参?
"""
形参: 定义函数时,函数内定义的形式参数, 简称形参 # 订正: 在函数定义阶段, 定义的形式参数,称之为形参. 形参相当于变量名
实参: 调用函数时,为函数进行传值的实际参数, 简称实参
"""
18. 形参与实参的关系(注意)
"""
形参相当于变量名, 实参相当于变量值. 实参是对形参的一种赋值(引用).
# 订正:
绑定关系: 在调用阶段,实参的值会绑定给形参名
使用范围: 函数这种绑定关系的参数只能在函数体内使用
生效时间: 实参于形参的绑定关系会在函数调用时生效,函数调用结束后绑定关系解除
"""
19. 名称空间的加载顺序是什么?
"""
内置名称空间 > 全局名称空间 > 局部名称空间
"""
20. 名称空间的销毁顺序
"""
局部名称空间 > 全局名称空间 > 内置名称空间
"""
21. 什么是闭包函数(注意)
"""
'闭': 指的是该函数是内嵌函数
'包': 指的是外层函数为该函数提供所需的数据. # 订正: 指的是该函数对外层函数作用域名字的引用(不是全局名称空间)
"""
22. tail -f access.log程序实现(监听名为 access.log 的文件的末尾 是否增加了数据)
import os
import time
def monitor_log(log_path='access.log'):
if os.path.isfile(log_path):
with open(log_path, 'rb') as f:
f.seek(0, 2)
while True:
res = f.readline()
if res:
print(res.decode('utf-8'), end='')
else:
time.sleep(0.3)
# monitor_log()
23. 以下代码的执行结果是什么?为什么?
"""
结果: 报错
为什么: 定义阶段func局部中说我有x,你不要去别的地方找了.调用的时候x却没有定义,这个属于逻辑混乱,语法错误
"""
24. 下述结果为?
# 结果: 1
25. read、readline 和 readlines 的区别?
"""
# 以下读取文件返回值全是字符串类型:
read: 一次性读取
在b模式下read(n),n指的是从文件指针当前位置读取的字节个数.
在t模式下read(n),n指的是从文件指针当前位置读取的字符个数.
read(),从文件指针当前位置读取文件到文件末尾
readline:
以行为单位, 一次读取文件每一行内容.
readlines: 一次性读取
读取文件中的所有内容, 返回一个列表, 列表中的每项元素中的内容都是文件的每一行内容.
"""
26. 以下程序的输出结果是?
"""
5
4
3
2
1
"""
二. 综合题
1. 写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数(3分)
def classified_counting(str1: str):
"""分类计算"""
dic = {
'numbers': 0,
'letters': 0,
'spaces': 0,
'other': 0,
}
for symbol in str1:
if symbol.isdigit():
dic['numbers'] += 1
elif symbol.isalpha():
dic['letters'] += 1
elif symbol.isspace():
dic['spaces'] += 1
else:
dic['other'] += 1
return dic
# print(classified_counting('hfawhuij njf 1uih8if1 y89u1893iofjknjk3 ui13fu89-')) # {'numbers': 14, 'letters': 30, 'spaces': 4, 'other': 1}
2. 写函数,检查获取传入列表或元组对象的所有偶数位索引对应的元素,并将其作为新列表返回给调用者。
def check_list(list_tuple):
return list_tuple[::2]
# print(check_list([1, 2, 3, 4, 5])) # [1, 3, 5]
3. 写函数有大小写字母的字符串,要求是如果字符串中大写字母的数量小于等于小写字母的数量,则把字符串全部变小写,反之则将字符串全部变为大写
# 示例
# solve('coDe')——>>'code'
# solve('CODe')——>>'CODE'
def solve(str1: str):
upper_count = 0
lower_count = 0
for symbol in str1:
if not symbol.isalpha():
continue
if symbol.islower():
lower_count += 1
else:
upper_count += 1
if upper_count <= lower_count:
return str1.lower()
return str1.upper()
4.将字符串"k:1|k1:2|k2:3|k3:4",处理成 Python 字典:
s = "k:1|k1:2|k2:3|k3:4"
li = []
for item in s.split('|'):
li.append(item.split(':'))
print(dict(li))
三. ATM
1.方式一
# 思路分析:
"""
1. 分成2个界面: 第一个界面,用户注册 登录的界面. 第二个界面,用户操作执行功能的界面
第一个界面: 用户不注册后,登录,看不到执行操作功能的界面,就算看到了也没有什么意义.只有登录了用户看到对应属于他的功能的操作.
第二个界面: 用户需要执行他特定的功能,关键点就是用户登录以后,拿到用户名,作为之后用户操作的基本查找条件.
总结: 2个功能. 1个功能负责用户登录 注册的认证功能. 另一个功能负责用户登录成功以后执行相应功能操作的功能.
2. 用户登录及时找到这个用户, 用户操作更具用户名及时拿到用户对应的数据:
把所有用户账户信息加载到内存, 用户登录直接内存中判断. 用户登录以后通过用户名在内存中读取或者修改数据, 不需要每次循环读取打开文件的频繁操作.
不过注意的是, 你在内存中修改了数据, 硬盘中的数据没有变化, 如果用户退出不能及时的保存数据. 所以但凡有用户修改数据的地方, 都需要一个特定把内存中的数据, 及时覆盖写回硬盘的操作, 保证了硬盘与内存数据都是最新的数据
总结: 2个功能. 1个功能负责在程序启动的时候就把所有用户信息读到内存. 另1个功能负责当内存中用户数据修改以后覆盖写回原文件.
# 注意: 文件内容str. 内存用户余额 用户错误次数都需要进行数学运算格式int.
3. 文件保存用户的账户信息的格式:
用户名:密码:用户错误次数:用户余额
4. 内存中用户的账户信息的格式:
字典 = {用户名: [密码, 用户错误次数, 用户余额]}
缺点: 没有使用上装饰器
"""
# -*- encoding: utf-8 -*-
"""
需求: 编写ATM程序实现下述功能,数据来源于文件db.txt
0、注册功能:用户输入账号名、密码、金额,按照固定的格式存入文件db.txt
1、登录功能:用户名不存在,要求必须先注册,用户名存在&输错三次锁定,登录成功后记录下登录状态(提示:可以使用全局变量来记录)
下述操作,要求登录后才能操作:
1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改
2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱
3、提现功能:用户输入提现金额,db.txt中该账号钱数减少
4、查询余额功能:输入账号查询余额
"""
import os
DB_path = r'db.txt'
login_state = set()
accounts_dic = {}
if os.path.isfile(DB_path):
with open(DB_path, 'r', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
username, password, wrong_number, balance = res.split(":")
accounts_dic[username] = [password, int(wrong_number), int(balance)]
def update_accounts():
with open(DB_path, 'w', encoding='utf-8') as f:
for username in accounts_dic:
password, wrong_number, balance = accounts_dic.get(username)
f.write(f'{username}:{password}:{str(wrong_number)}:{str(balance)}\n')
def login():
print("登录".center(50, '-'))
if not os.path.isfile(DB_path):
print('哦吼!你是第一个用户,你先注册去吧!')
return
name = input("用户名>>:").strip()
if name in login_state:
print(f"欢迎[{name}]再次登录!")
return name
if name in accounts_dic:
user_info = accounts_dic.get(name)
if user_info[1] == 3:
print("这个用户之前输入了三次密码.已经被锁定")
return
pwd = input("用户密码>>:").strip()
if pwd == user_info[0]:
print("恭喜登录成功!")
login_state.add(name)
accounts_dic.get(name)[1] = 0
update_accounts()
return name
else:
print("密码输入错误")
accounts_dic.get(name)[1] += 1
update_accounts()
else:
print('用户名不存在')
def register():
print("注册".center(50, '-'))
name = input("用户名>>:").strip()
if not name:
print("用户名不输入不能为空.")
return
if name in accounts_dic:
print('该用户名已经被注册,请重新输入')
return
pwd = input("用户密码>>:").strip()
confirm_pwd = input("确认用户密码>>:").strip()
if pwd == confirm_pwd:
if not pwd:
print("用户密码不能为空")
return
accounts_dic[name] = [pwd, 0, 0]
with open(DB_path, 'a', encoding='utf-8') as f:
f.write(f'{name}:{pwd}:0:0\n')
print("恭喜你注册成功".center(50, '-'))
else:
print("用户密码2次输入不一致")
def check_balance(username):
print("查询余额".center(50, '-'))
print(f"您当前余额[{accounts_dic[username][2]}]元")
def withdraw_deposit(username):
print("提现".center(50, '-'))
get_money = input("请拿钱>>:").strip()
if not get_money.isdigit():
print("请输入数字")
return
get_money = int(get_money)
balance = accounts_dic[username][2]
if get_money <= balance:
accounts_dic[username][2] -= get_money
update_accounts()
print(f"恭喜你提现[{get_money}]元成功".center(50, '-'))
else:
print("钱不够!快去查询以下余额吧!")
def transfer_accounts(username):
print("转账".center(50, '-'))
get_user = input('你想给谁赚钱啊!小伙计>>:').strip()
if get_user not in accounts_dic:
print("人都没有这人,转格各毛线啊!")
return
get_money = input("你要转多少啊!小伙计>>:").strip()
if not get_money.isdigit():
print("请输入数字")
return
get_money = int(get_money)
balance = accounts_dic[username][2]
if get_money <= balance:
print(f'恭喜你给[{get_user}]用户转账成功!'.center(50, '-'))
accounts_dic[username][2] -= get_money
accounts_dic[get_user][2] += get_money
update_accounts()
else:
print("自己的钱都不够,还转给别人,🖊⑩你!")
def recharge(username):
print("充值".center(50, '-'))
add_money = input("你要充多少钱>>:").strip()
if not add_money.isdigit():
print("请输入数字")
return
add_money = int(add_money)
accounts_dic[username][2] += add_money
update_accounts()
print("恭喜你充值成功".center(50, '-'))
def print_info(function_dic, action, username=None):
"""0模式认证, 1模式执行用户功能"""
for key, value in function_dic.items():
print(f'''
{key} {value[0]}
''')
cmd = input("请输入命令编号>>:").strip()
if not cmd.isdigit():
print("请输入数字")
return
if cmd not in function_dic:
print("输入命令编号范围不存在.")
return
if action:
return function_dic[cmd][1](username)
return function_dic[cmd][1]()
auth_dic = {
'0': ('退出', exit),
'1': ('登录', login),
'2': ('注册', register),
}
def auth(discard=None):
print("认证".center(50, '-'))
while True:
username = print_info(auth_dic, 0)
# print('from auth:', username)
if username:
return username
func_dic = {
'0': ('退出', exit),
'1': ('返回上一层', auth),
'2': ('查询余额', check_balance),
'3': ('转账', transfer_accounts),
'4': ('提现', withdraw_deposit),
'5': ('充值', recharge),
}
def run():
username = auth()
while True:
# print('from run:', username)
res = print_info(func_dic, 1, username)
if res:
username = res
if __name__ == '__main__':
run()
2.方式二: 使用装饰器
"""
1. 装饰器在这里的作用:
为用户操作时之前进行登录验证判断, 如果用户没有登陆不然用户执行当前的操作功能.
需要注意的是: 你要判断用户是否登录, 内存中需使用一种方式保存用户登录以后的状态. 如果在全局用不可变类型保存用户的状态, 你在登录功能的函数中就需要使用global进行声明, 不然在函数中会定义它自己局部的相同变量名的变量, 并不能进行修改操作. 如果你使用的是可变类型的对象, 如果程序不退出保留多个用户登录的状态, 那么装饰器就不能使用了.
2. 只有一个界面: 所有功能都在一个界面, 只有用户登录认证成功以后, 才能执行相应的功能操作.
缺点:
不支持保留多个用户当前登录的状态.
"""
# -*- encoding: utf-8 -*-
"""
编写ATM程序实现下述功能,数据来源于文件db.txt
0、注册功能:用户输入账号名、密码、金额,按照固定的格式存入文件db.txt
1、登录功能:用户名不存在,要求必须先注册,用户名存在&输错三次锁定,登录成功后记录下登录状态(提示:可以使用全局变量来记录)
下述操作,要求登录后才能操作:
1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改
2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱
3、提现功能:用户输入提现金额,db.txt中该账号钱数减少
4、查询余额功能:输入账号查询余额
定义用户账户文件为当前目录下的db.txt中,文件中存放格式如下:
用户名:密码:用户错误次数:用户余额
"""
import os
DB_path = r'db.txt'
current_user = None
accounts_dic = {}
if os.path.isfile(DB_path):
with open(DB_path, 'r', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
username, password, wrong_number, balance = res.split(":")
accounts_dic[username] = [password, int(wrong_number), int(balance)]
def auth(func):
def wrapper(*args, **kwargs):
if not current_user:
print("您还没有登录, 请先登录")
else:
return func(*args, **kwargs)
return wrapper
def update_accounts():
with open(DB_path, 'w', encoding='utf-8') as f:
for username in accounts_dic:
password, wrong_number, balance = accounts_dic.get(username)
f.write(f'{username}:{password}:{str(wrong_number)}:{str(balance)}\n')
def login():
print("登录".center(50, '-'))
if not os.path.isfile(DB_path):
print('哦吼!你是第一个用户,你先注册去吧!')
return
name = input("用户名>>:").strip()
if name == current_user:
print(f"欢迎[{name}]再次登录!")
return name
if name in accounts_dic:
user_info = accounts_dic.get(name)
if user_info[1] == 3:
print("这个用户之前输入了三次密码.已经被锁定")
return
pwd = input("用户密码>>:").strip()
if pwd == user_info[0]:
print("恭喜登录成功!")
# 修改全局的不可变类型: 定义global
global current_user
current_user = name
accounts_dic.get(name)[1] = 0
update_accounts()
return name
else:
print("密码输入错误")
accounts_dic.get(name)[1] += 1
update_accounts()
else:
print('用户名不存在')
def register(*args):
print("注册".center(50, '-'))
name = input("用户名>>:").strip()
if not name:
print("用户名不输入不能为空.")
return
if name in accounts_dic:
print('该用户名已经被注册,请重新输入')
return
pwd = input("用户密码>>:").strip()
confirm_pwd = input("确认用户密码>>:").strip()
if pwd == confirm_pwd:
if not pwd:
print("用户密码不能为空")
return
accounts_dic[name] = [pwd, 0, 0]
with open(DB_path, 'a', encoding='utf-8') as f:
f.write(f'{name}:{pwd}:0:0\n')
print("恭喜你注册成功".center(50, '-'))
else:
print("用户密码2次输入不一致")
@auth # check_balance = auth(check_balance)
def check_balance():
print("查询余额".center(50, '-'))
print(f"您当前余额[{accounts_dic[current_user][2]}]元")
@auth
def withdraw_deposit():
print("提现".center(50, '-'))
get_money = input("请拿钱>>:").strip()
if not get_money.isdigit():
print("请输入数字")
return
get_money = int(get_money)
balance = accounts_dic[current_user][2]
if get_money <= balance:
accounts_dic[current_user][2] -= get_money
update_accounts()
print(f"恭喜你提现[{get_money}]元成功".center(50, '-'))
else:
print("钱不够!快去查询以下余额吧!")
@auth
def transfer_accounts():
print("转账".center(50, '-'))
get_user = input('你想给谁赚钱啊!小伙计>>:').strip()
if get_user not in accounts_dic:
print("人都没有这人,转格各毛线啊!")
return
get_money = input("你要转多少啊!小伙计>>:").strip()
if not get_money.isdigit():
print("请输入数字")
return
get_money = int(get_money)
balance = accounts_dic[current_user][2]
if get_money <= balance:
print(f'恭喜你给[{get_user}]用户转账成功!'.center(50, '-'))
accounts_dic[current_user][2] -= get_money
accounts_dic[get_user][2] += get_money
update_accounts()
else:
print("自己的钱都不够,还转给别人,🖊⑩你!")
@auth
def recharge():
print("充值".center(50, '-'))
add_money = input("你要充多少钱>>:").strip()
if not add_money.isdigit():
print("请输入数字")
return
add_money = int(add_money)
accounts_dic[current_user][2] += add_money
update_accounts()
print("恭喜你充值成功".center(50, '-'))
func_dic = {
'0': ('退出', exit),
'1': ('登录', login),
'2': ('注册', register),
'3': ('查询余额', check_balance),
'4': ('转账', transfer_accounts),
'5': ('提现', withdraw_deposit),
'6': ('充值', recharge),
}
def run():
while True:
if current_user:
print(f'当前操作用户: {current_user}'.center(50, '#') )
for key, value in func_dic.items():
print(f'({key}){value[0]} ', end='')
print()
cmd = input("请输入命令编号>>:").strip()
if not cmd.isdigit():
print("请输入数字")
continue
if cmd not in func_dic:
print("输入命令编号范围不存在.")
continue
func_dic[cmd][1]()
if __name__ == '__main__':
run()