python作业3

题目:健身房会员与课程预约管理系统

一、背景与要求
请编写一个命令行交互程序,实现对健身房会员和团课预约的管理。程序启动后显示菜单,用户输入选项数字执行相应功能,直到选择退出。

数据存储要求:

1.使用一个字典 members 作为会员主数据容器,键为会员手机号(字符串,11位),值为另一个字典,包含:
name:姓名(字符串)
type:卡类型('月卡'、'季卡'、'年卡',字符串)
remain_days:剩余有效天数(整数)
points:积分余额(整数)

2.使用一个字典 courses 作为课程主数据容器,键为课程编号(字符串,格式如 C101),值为另一个字典,包含:
name:课程名称(字符串)
coach:教练姓名(字符串)
capacity:课程容量上限(整数)
booked:当前已预约人数(整数)

3.使用一个列表 reservations 记录每一次预约操作的日志,每条日志为元组,格式为:
('预约', 会员手机号, 会员姓名, 课程编号, 课程名称, 预约日期)
日期统一用字符串表示,如 '2026-04-13'


程序功能菜单:
text
1. 注册新会员
2. 查看所有会员
3. 查询会员信息
4. 续费会员卡
5. 添加新课程
6. 查看所有课程
7. 预约课程
8. 统计信息
9. 显示预约日志
10. 退出系统

功能具体要求:

功能  说明
注册新会员   输入手机号、姓名、卡类型(1=月卡/2=季卡/3=年卡)。若手机号已存在则提示错误并重新输入。根据卡类型设置初始剩余天数:月卡30天,季卡90天,年卡365天。初始积分为0。注册成功后显示提示信息。
查看所有会员  按手机号顺序打印每个会员的手机号、姓名、卡类型、剩余天数、积分。若无会员则提示“暂无会员信息”。
查询会员信息  输入手机号,若存在则显示该会员的详细信息和当前积分。若不存在则提示“会员不存在”。
续费会员卡   输入手机号,若不存在则提示错误;若存在则显示当前卡类型和剩余天数,然后输入续费类型(1/2/3)。续费后叠加对应的天数,并增加积分(月卡+50分,季卡+150分,年卡+600分)。续费成功后显示更新后的信息。
添加新课程   输入课程编号、课程名称、教练姓名、容量上限。若编号已存在则提示错误并重新输入。容量必须为正整数,初始已预约人数为0。添加成功后显示提示。
查看所有课程  按课程编号顺序打印每门课程的编号、名称、教练、容量、已预约人数、剩余名额。若无课程则提示“暂无课程信息”。
预约课程    输入会员手机号,若不存在则提示错误并返回;若存在但剩余天数 ≤ 0 则提示“会员卡已过期,无法预约”;否则继续输入课程编号。若课程不存在则提示错误;若课程已预约人数等于容量则提示“该课程已约满”;否则预约成功:课程已预约人数加1,会员积分增加10分,并记录一条预约日志到 reservations 列表中(日期输入格式 YYYY-MM-DD)。成功后显示“预约成功,积分+10”。

统计信息    输出以下统计内容:
- 会员总数,以及各卡类型(月卡/季卡/年卡)的会员人数
- 积分最高的会员信息(手机号、姓名、积分;若有多人并列则显示第一个)
- 预约率最高的课程信息(课程编号、名称、预约率,即 booked/capacity;若无课程则跳过)
- 剩余名额为0的课程列表(编号、名称;若无则提示“所有课程均有空位”)

显示预约日志  按时间顺序打印 reservations 中的每条记录,格式清晰。若无日志则提示“暂无预约记录”。
退出系统    结束程序。

二、函数设计约束(重点考察部分)
必须按以下函数划分来组织代码,每个函数负责明确的功能,主程序仅负责菜单调度与用户交互。

额外要求:
使用类型注解(如函数签名中所示)增强代码可读性。
在适当位置使用 if/elif/else 进行条件判断(例如菜单分支、手机号存在性、课程容量判断)。
在统计信息计算、遍历容器时必须使用循环(如 for 遍历字典的 items())。

对用户输入的卡类型和容量等进行合法性校验(非数字或超出范围时提示重新输入)。

日期格式不要求严格校验,但需按字符串正确记录。
# python代码
members ={
    "19222167743":{"name":"苏亦昂","type":'季卡',"remain_days":90,"points":0},   
    "16622165490":{"name":"方洪","type":'月卡',"remain_days":30,"points":0},
    
         }

courses ={
    "C101":{"name":"卧推训练课程","coach":'颜回',"capacity":5,"booked":0},
    "C102":{"name":"深蹲训练课程","coach":'仲文',"capacity":8,"booked":0},
         }

reservations =[
    ('预约', '19222167743', '苏亦昂', 'C102', '深蹲训练课程', '2026-05-14'),
    ('预约', '16622165490', '方洪', 'C101', '卧推训练课程', '2026-04-15'),
         ]

""" 
函数功能:注册新会员
参数:有,字典类型
返回值:无

功能完成
"""
def register_member(members: dict) -> None:
    """处理注册新会员逻辑,更新 members 字典"""
    # 注册新会员 输入手机号、姓名、卡类型(1=月卡/2=季卡/3=年卡)。
    # 若手机号已存在则提示错误并重新输入。
    # 根据卡类型设置初始剩余天数:月卡30天,季卡90天,年卡365天。初始积分为0。注册成功后显示提示信息。
    
    phone_num=input("注册新会员,请输入手机号:") 
    # 下面这while,确保,手机号唯一
    while True:  
        #手机号正确,11位,数字
        if len(phone_num) != 11 or not phone_num.isdigit():
            phone_num=input("不是正确的手机号,11位数字,请重新输入:")
            continue
                  
        if phone_num in members:
            # 存在,循环继续
            phone_num=input("手机号已存在,请重新输入:") 
        else:
            # 添加
            name=input("请输入姓名:")
            remain_days=0
            card_type=input("请入卡类型(1=月卡/2=季卡/3=年卡),输数字:")
            # 下面while,确保正确输入卡类型,
            while True:
                if card_type=="1":
                    card_type="月卡"
                    remain_days=30
                    break
                elif card_type=="2":
                    card_type="季卡"
                    remain_days=90
                    break
                elif card_type=="3":
                    card_type="年卡"
                    remain_days=365
                    break
                else:
                    card_type=input("没有这个类型!请重新输入:")
            
            new_dict={"name":name,"type":card_type,"remain_days":remain_days,"points":0}
            members[phone_num]=new_dict 
            
            print(f"""
    注册成功!你注册的信息:
            手机号:{phone_num}
            姓名:{members[phone_num]["name"]}
            类型:{members[phone_num]["type"]}
            剩余天数:{members[phone_num]["remain_days"]}
            积分:{members[phone_num]["points"]}
                """
                  )
            
            # 新成员添加成功,外循环,结束
            break    

# 功能完成
def show_all_members(members: dict) -> None:
    """打印所有会员信息,若无会员则输出提示"""
    # 查看所有会员    按手机号顺序打印每个会员的手机号、姓名、卡类型、剩余天数、积分。若无会员则提示“暂无会员信息”。

    if not members:
        print("暂无会员信息!")
    else:    
        # 手机号,升序
        phone_sorted=sorted(members,key=lambda a:int(a))
        for key in phone_sorted:
            print(f"""
      会员信息:
              手机号:{key}
              姓名:{members[key]["name"]}
              类型:{members[key]["type"]}
              剩余天数:{members[key]["remain_days"]}
              积分:{members[key]["points"]}
              """                    
                    )
    
# 功能完成    
def query_member(members: dict) -> None:
    """按手机号查询并打印会员详细信息"""
    # 查询会员信息    输入手机号,若存在则显示该会员的详细信息和当前积分。若不存在则提示“会员不存在”。
    phone_num=input("请输入要查询的会员手机号:")
    if phone_num in members:
         print(f"""
    查询成功!详细信息:
            手机号:{phone_num}
            姓名:{members[phone_num]["name"]}
            类型:{members[phone_num]["type"]}
            剩余天数:{members[phone_num]["remain_days"]}
            积分:{members[phone_num]["points"]}
                """
                  )
    else:
        print(f"会员不存在!")    

# 功能完成
def renew_membership(members: dict) -> None:
    """处理会员卡续费逻辑,更新剩余天数和积分"""
    # 续费会员卡 输入手机号,若不存在则提示错误;
    # 若存在则显示当前卡类型和剩余天数,然后输入续费类型(1/2/3)。
    # 续费后叠加对应的天数,并增加积分(月卡+50分,季卡+150分,年卡+600分)。续费成功后显示更新后的信息。
    phone_num=input("请输入续费会员的手机号:") 
    if phone_num in members:
        print(f"""
        类型:{members[phone_num]["type"]}
        剩余天数:{members[phone_num]["remain_days"]}
                """)
        # 续费
        card_type=input("请入续费类型(1=月卡/2=季卡/3=年卡),输数字:")
        # 下面while,确保正确输入卡类型,
        while True:
            if card_type=="1":
                members[phone_num]["type"]="月卡"
                members[phone_num]["remain_days"]+=30
                members[phone_num]["points"]+=50
                break
            elif card_type=="2":
                members[phone_num]["type"]="季卡"
                members[phone_num]["remain_days"]+=90
                members[phone_num]["points"]+=150
                break
            elif card_type=="3":
                members[phone_num]["type"]="年卡"
                members[phone_num]["remain_days"]+=365
                members[phone_num]["points"]+=600
                break
            else:
                card_type=input("没有这个类型!请重新输入:")
                
        print(f"""
    续费成功!续费更新后的信息:
            手机号:{phone_num}
            姓名:{members[phone_num]["name"]}
            类型:{members[phone_num]["type"]}
            剩余天数:{members[phone_num]["remain_days"]}
            积分:{members[phone_num]["points"]}
                """
                  )
        
    else:
        print("     续费错误,不存在该会员!")    

# 功能完成 
def add_course(courses: dict) -> None:
    """处理添加新课程逻辑,更新 courses 字典"""
    # 添加新课程 输入课程编号、课程名称、教练姓名、容量上限。
    # 若编号已存在则提示错误并重新输入。
    # 容量必须为正整数>0,初始已预约人数为0。添加成功后显示提示。
    course_num=input("请输入添加新课程的编号:")
    while True:
        if course_num in courses:
            course_num=input("编号已存在!请重新输入:")
        else:
            name=input("请输入课程名称:")
            coach=input("请输入教练姓名:")
            
            
            capacity=int(input("请输入容量上限:"))
            # 下面的while,确保容量为正整数>0
            while True:
                if capacity>0:
                    break
                else:
                     capacity=int(input("注意!容量必须为正整数:"))   
                     
            new_dict={"name":name,"coach":coach,"capacity":capacity,"booked":0}
            courses[course_num]=new_dict
            
            print(f"""
    课程添加成功!添加的课程信息:
            课程编号:{course_num}
            课程名称:{courses[course_num]["name"]}
            教练姓名:{courses[course_num]["coach"]}
            容量上限:{courses[course_num]["capacity"]}
            已预约人数:{courses[course_num]["booked"]}
                """
                  )
            
            break

# 功能完成 
def show_all_courses(courses: dict) -> None:
    """打印所有课程信息,若无课程则输出提示"""
    # 查看所有课程    
    # 按课程编号顺序打印每门课程的编号、名称、教练、容量、已预约人数、剩余名额。
    # 若无课程则提示“暂无课程信息”。
    if not courses:
        print("暂无课程信息")
    else:
        # 升序
        sorted_keys=sorted(courses.keys())   
        for course_num in sorted_keys:
            print(f"""
    查看成功!   
            课程编号:{course_num}
            课程名称:{courses[course_num]["name"]}
            教练姓名:{courses[course_num]["coach"]}
            容量上限:{courses[course_num]["capacity"]}
            已预约人数:{courses[course_num]["booked"]}
            剩余名额:{courses[course_num]["capacity"]-courses[course_num]["booked"]}
                """
                  )
    
# 功能完成 
def reserve_course(members: dict, courses: dict, reservations: list) -> None:
    """处理课程预约逻辑,更新课程已约人数、会员积分,并记录预约日志"""
        # 预约课程  输入会员手机号,若不存在则提示错误并返回;
        # 若存在但剩余天数 ≤ 0 则提示“会员卡已过期,无法预约”;
        
        # 否则继续输入课程编号。若课程不存在则提示错误;
        # 若课程已预约人数等于容量则提示“该课程已约满”;
        # 否则预约成功:课程已预约人数加1,会员积分增加10分,并记录一条预约日志到 reservations 列表中(日期输入格式 YYYY-MM-DD)。
        # 成功后显示“预约成功,积分+10”。
    phone_num=input("请输入预约课程的会员手机号:")
    if not phone_num in members:
        print("不存在该会员!")     
        return
    if members[phone_num]["remain_days"]<=0:
        print("会员卡已过期,无法预约!")
        return
    
    # 会员卡还有天数
    course_num=input("请输入你要预约的课程编号:")
    if not course_num in courses:
        # 不在课,错误
        print("错误,课程不存在!")
    else:
        # 存在课
        if courses[course_num]["capacity"]==courses[course_num]["booked"]:    
            print("该课程已约满!")
        else:
            courses[course_num]["booked"]+=1
            members[phone_num]["points"]+=10 
            # 记录一条预约日志到列表中
            
            new_log=('预约',phone_num,members[phone_num]["name"],course_num,courses[course_num]["name"],'2026-04-17')
            reservations.append(new_log)     
            
            print("预约成功,积分+10")
            
            # 我看看对不对
    #         print(f"""
    # 查看成功! 
    #         课程编号:{course_num}
    #         课程名称:{courses[course_num]["name"]}
    #         教练姓名:{courses[course_num]["coach"]}
    #         容量上限:{courses[course_num]["capacity"]}
    #         已预约人数:{courses[course_num]["booked"]}
    #         剩余名额:{courses[course_num]["capacity"]-courses[course_num]["booked"]}
            
    #         手机号:{phone_num}
    #         姓名:{members[phone_num]["name"]}
    #         类型:{members[phone_num]["type"]}
    #         剩余天数:{members[phone_num]["remain_days"]}
    #         积分:{members[phone_num]["points"]}
            
    #         {reservations[-1]}
    #             """
    #               )

# 功能完成 ,这里要检查一下                
def get_statistics(members: dict, courses: dict) -> dict:
    """
    返回统计信息字典,包含:
    - 'total_members': 会员总数
    - 'type_counts': {'月卡': 人数, '季卡': 人数, '年卡': 人数}
    - 'top_points_member': (手机号, 姓名, 积分) 或 None
    - 'top_booking_course': (课程编号, 名称, 预约率) 或 None
    - 'full_courses': 预约满的课程列表[],元素为 (编号, 名称)
    """
    # 统计信息  输出以下统计内容:
    # - 会员总数,以及各卡类型(月卡/季卡/年卡)的会员人数
    # - 积分最高的会员信息(手机号、姓名、积分;若有多人并列则显示第一个)
    # - 预约率最高的课程信息(课程编号、名称、预约率,即 booked/capacity;若无课程则跳过)
    # - 剩余名额为0的课程列表(编号、名称;若无则提示“所有课程均有空位”)
    total_members=0
    type_counts={'月卡': 0, '季卡': 0, '年卡': 0}
    
    top_points_member=None
    phone_num=""
    
    for key in members:
        total_members+=1
        
        if members[key]["type"]=='月卡':
            type_counts['月卡']+=1
        elif members[key]["type"]=='季卡':  
            type_counts['季卡']+=1
        else:            
            type_counts['年卡']+=1

        top_points=0
        if members[key]["points"]>top_points:
            top_points = members[key]["points"]
            phone_num=key
    
    if phone_num=="":
        top_points_member=None
    else:
        # 元组
        top_points_member=(phone_num,members[phone_num]["name"],members[phone_num]["points"])    

    # - 预约率最高的课程信息(课程编号、名称、预约率,即 booked/capacity;若无课程则跳过)
    # - 剩余名额为0的课程列表(编号、名称;若无则提示“所有课程均有空位”)
    
    max_booked=""
    booked_rate=0
    
    full_courses=[]
    for key in courses:
        capacity=courses[key]["capacity"]
        booked=courses[key]["booked"]
        if capacity-booked==0:
            new_tuple=(key,courses[key]["name"])
            full_courses.append(new_tuple)
            
        if booked/capacity>booked_rate:
            booked_rate=booked/capacity
            max_booked=key
    if max_booked=="":
        top_booking_course="无课程,跳过!"
    else:
        top_booking_course=(max_booked,courses[max_booked]["name"],booked_rate)    
    
    if full_courses==[]:
        full_courses="所有课程均有空位!"
    
    result={
    'total_members': total_members,
    'type_counts': type_counts,
    'top_points_member':top_points_member,
    'top_booking_course': top_booking_course,
    'full_courses':full_courses,
    }
    return result
    
# 功能完成 
def show_statistics(members: dict, courses: dict) -> None:
    """调用 get_statistics 并格式化打印统计结果"""
    result=get_statistics(members,courses)
    for key,val in result.items():
        print(f"{key}:{val}")
        
# 功能完成
def show_reservations(reservations: list) -> None:
    """打印所有预约操作日志"""
    # 显示预约日志    按时间顺序打印 reservations 中的每条记录,格式清晰。
    # 若无日志则提示“暂无预约记录”。
    if not reservations:
        print("暂无预约记录")
    else:
        # 时间顺序,升序
        sorted_date=sorted(reservations,key=lambda a:a[-1])       
        for i in sorted_date:
            print(i)

menu='''
程序功能菜单:
    1. 注册新会员
    2. 查看所有会员
    3. 查询会员信息
    4. 续费会员卡
    5. 添加新课程
    6. 查看所有课程
    7. 预约课程
    8. 统计信息
    9. 显示预约日志
    10. 退出系统
'''

def main():
    """主菜单循环"""
    while True:
        print(menu)
        choose=input("请输入你的选择:")
        if choose=="1":
            register_member(members)
        
        elif choose=="2":
            show_all_members(members)
        
        elif choose=="3":
            query_member(members)
        
        elif choose=="4":
            renew_membership(members)
        
        elif choose=="5":
            add_course(courses)
        
        elif choose=="6":
            show_all_courses(courses)
        
        elif choose=="7":
            reserve_course(members, courses, reservations)
        
        elif choose=="8":
            show_statistics(members,courses)
        
        elif choose=="9":
            show_reservations(reservations)
        
        elif choose=="10":
            print("退出成功!")
            break
        
        else:
            print("没有这个选择!")
    
# 调用主函数,这是入口
main()

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容