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

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

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

# 使用一个列表 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 中的每条记录,格式清晰。若无日志则提示“暂无预约记录”。
# 退出系统        结束程序。
# 二、函数设计约束(重点考察部分)
# 必须按以下函数划分来组织代码,每个函数负责明确的功能,主程序仅负责菜单调度与用户交互。
#
# python
# def register_member(members: dict) -> None:
#     """处理注册新会员逻辑,更新 members 字典"""
#     pass
#
# def show_all_members(members: dict) -> None:
#     """打印所有会员信息,若无会员则输出提示"""
#     pass
#
# def query_member(members: dict) -> None:
#     """按手机号查询并打印会员详细信息"""
#     pass
#
# def renew_membership(members: dict) -> None:
#     """处理会员卡续费逻辑,更新剩余天数和积分"""
#     pass
#
# def add_course(courses: dict) -> None:
#     """处理添加新课程逻辑,更新 courses 字典"""
#     pass
#
# def show_all_courses(courses: dict) -> None:
#     """打印所有课程信息,若无课程则输出提示"""
#     pass
#
# def reserve_course(members: dict, courses: dict, reservations: list) -> None:
#     """处理课程预约逻辑,更新课程已约人数、会员积分,并记录预约日志"""
#     pass
#
# def get_statistics(members: dict, courses: dict) -> dict:
#     """
#     返回统计信息字典,包含:
#     - 'total_members': 会员总数
#     - 'type_counts': {'月卡': 人数, '季卡': 人数, '年卡': 人数}
#     - 'top_points_member': (手机号, 姓名, 积分) 或 None
#     - 'top_booking_course': (课程编号, 名称, 预约率) 或 None
#     - 'full_courses': 预约满的课程列表,元素为 (编号, 名称)
#     """
#     pass
#
# def show_statistics(members: dict, courses: dict) -> None:
#     """调用 get_statistics 并格式化打印统计结果"""
#     pass
#
# def show_reservations(reservations: list) -> None:
#     """打印所有预约操作日志"""
#     pass
#
# def main():
#     """主菜单循环"""
#     pass
# 额外要求:
#
# 使用类型注解(如函数签名中所示)增强代码可读性。
#
# 在适当位置使用 if/elif/else 进行条件判断(例如菜单分支、手机号存在性、课程容量判断)。
#
# 在统计信息计算、遍历容器时必须使用循环(如 for 遍历字典的 items())。
#
# 对用户输入的卡类型和容量等进行合法性校验(非数字或超出范围时提示重新输入)。
#
# 日期格式不要求严格校验,但需按字符串正确记录。

text = '''
1. 注册新会员
2. 查看所有会员
3. 查询会员信息
4. 续费会员卡
5. 添加新课程
6. 查看所有课程
7. 预约课程
8. 统计信息
9. 显示预约日志
10. 退出系统
'''
members = {
    "15684675239":{
        "name":"zhangsan",
        "type":"月卡",
        "remain_days":20,
        "points":0

    }
}
courses = {
    "C101":{
        "name":"瑜伽",
        "coach":"lisi",
        "capacity":5,     # capacity:课程容量上限(整数)
        "bokked":0        # booked:当前已预约人数(整数)
    },
    "C102":{
        "name":"拉伸",
        "coach":"wangwu",
        "capacity":7,
        "bokked":0
    }
}
reservations =[]

# 注册新会员   输入手机号、姓名、卡类型(1=月卡/2=季卡/3=年卡)。若手机号已存在则提示错误并重新输入。
# 根据卡类型设置初始剩余天数:月卡30天,季卡90天,年卡365天。初始积分为0。注册成功后显示提示信息。

def register_member(members: dict) -> None:
    while True:
        member_id = input("请输入手机号:").strip()
        if member_id in members:
            print("手机号已存在,请重新输入手机号!")
            return
        else:
            member_name = input("请输入姓名:")
            member_type = int(input("请输入卡类型(1-3):"))
            if member_type == 1:
                card_name = "月卡"
                days = 30
            elif member_type == 2:
                card_name = "季卡"
                days = 90
            elif member_type == 3:
                card_name = "年卡"
                days = 365
            points = 0
            dict1 = {
                "name": member_name,
                "type": card_name,
                "remain_days": days,
                "points": points
            }
            members[member_id] = dict1
            print(
                f"当前注册的会员号:{member_id},姓名:{member_name},类型:{card_name},剩余天数:{days},初始积分为:{points}")
            #f-string里面不可以嵌套双引号,不然会报错
            return

# 查看所有会员        按手机号顺序打印每个会员的手机号、姓名、卡类型、剩余天数、积分。若无会员则提示“暂无会员信息”。
def show_all_members(members: dict) -> None:
    if len(members) == 0:
        print("暂无会员信息")
    else:
        for key,value in members.items():
            print(f"会员手机号:{key},姓名:{value['name']},卡类型:{value['type']},剩余天数:{value['remain_days']},积分:{value['points']}")

# 查询会员信息        输入手机号,若存在则显示该会员的详细信息和当前积分。若不存在则提示“会员不存在”。
def query_member(members: dict) -> None:
    phone_id = input("请输入手机号:")
    if phone_id in members:
        print(
            f"会员手机号:{phone_id},姓名:{members[phone_id]['name']},卡类型:{members[phone_id]['type']},剩余天数:{members[phone_id]['remain_days']},积分:{members[phone_id]['points']}")
    else:
        print("会员不存在!")

# 续费会员卡        输入手机号,若不存在则提示错误;若存在则显示当前卡类型和剩余天数,然后输入续费类型(1/2/3)。
# 续费后叠加对应的天数,并增加积分(月卡+50分,季卡+150分,年卡+600分)。续费成功后显示更新后的信息。
def renew_membership(members: dict) -> None:
    while True:
        phone_input = input("请输入手机号:")
        if phone_input in members:
            print(f"卡号:{phone_input},当前卡类型:{members[phone_input]['type']},剩余天数:{members[phone_input]['remain_days']}")
            xufei = input("请输入续费类型(1/2/3):")
            if xufei == "1":
                members[phone_input]['type'] = "月卡"
                members[phone_input]['remain_days'] += 30
                members[phone_input]['points'] += 50
            elif xufei == "2":
                members[phone_input]['type'] = "季卡"
                members[phone_input]['remain_days'] += 90
                members[phone_input]['points'] += 150
            elif xufei == "3":
                members[phone_input]['type'] = "年卡"
                members[phone_input]['remain_days'] += 365
                members[phone_input]['points'] += 600
            print(
                f"卡号:{phone_input},当前卡类型:{members[phone_input]['type']},更新后的天数:{members[phone_input]['remain_days']}")
            return
        else:
            print("当前手机号不存在,请重新输入:")

# 添加新课程        输入课程编号、课程名称、教练姓名、容量上限。
# 若编号已存在则提示错误并重新输入。容量必须为正整数,初始已预约人数为0。添加成功后显示提示。
def add_course(courses: dict) -> None:
    while True:
        bokked = 0
        course_id = input("请输入课程编号:")
        if course_id in courses:
            print("课程编号已存在,请重新输入:")
            continue
        else:
            course_name = input("请输入课程名:").strip()
            coach_name = input("请输入教练名:").strip()
            while True:
                capacity_num = int(input("请输入课程容量上限:"))
                value = isinstance(capacity_num,int)
                if not value or capacity_num < 0:
                    print("课程容量值必须为正整数,请重新输入:")
                else:
                    break
            dict1 = {
                "name": course_name,
                "coach": coach_name,
                "capacity": capacity_num,
                "bokked": bokked
            }
            courses[course_id] = dict1
            print(f"新增加的课程编号:{course_id},课程名:{course_name},教练名:{coach_name},课程容量:{capacity_num},预定数量:{bokked}")
        return

# 查看所有课程        按课程编号顺序打印每门课程的编号、名称、教练、容量、已预约人数、剩余名额。
# 若无课程则提示“暂无课程信息”。
def show_all_courses(courses: dict) -> None:
    if len(courses) == 0:
        print("暂无课程信息")
    else:
        for key,value in courses.items():
            print(f"课程编号:{key},名称:{value['name']},教练:{value['coach']},容量:{value['capacity']},已预约人数:{value['bokked']},剩余名额:{value['capacity']}")
            print()
    return

# 预约课程        输入会员手机号,若不存在则提示错误并返回;若存在但剩余天数 ≤ 0 则提示“会员卡已过期,无法预约”;
# 否则继续输入课程编号。若课程不存在则提示错误;若课程已预约人数等于容量则提示“该课程已约满”;
# 否则预约成功:课程已预约人数加1,会员积分增加10分,并记录一条预约日志到 reservations 列表中(日期输入格式 YYYY-MM-DD)。
# 成功后显示“预约成功,积分+10”。
def reserve_course(members: dict, courses: dict, reservations: list) -> None:
    phone_id = input("请输入会员手机号:")
    if phone_id in members:
        if members[phone_id]['remain_days'] <=0:
            print("会员卡已过期,无法预约!")
        course_id =input("请输入课程编号")
        if course_id in courses:
            if courses[course_id]['bokked'] == courses[course_id]['capacity']:
                print("该课程已经约满!")
        else:
            print("课程编号不存在!")
        courses[course_id]['bokked'] += 1
        members[phone_id]['points'] += 10
        datatime = input("请输入预约课程的日期:(YYYY-MM-DD)")
        list1 = [course_id,datatime,"课程已预约人数加1,会员积分增加10分"]
        reservations.append(list1)
        print("预约成功,积分+10")
        print(list1)
        return
    else:
        print("当前输入的会员手机号不存在!")

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

def reservation_rate(x):

    return courses[x]['bokked']/courses[x]['capacity']

def get_statistics(members: dict, courses: dict) -> dict:
    """
    返回统计信息字典,包含:
    - 'total_members': 会员总数
    - 'type_counts': {'月卡': 人数, '季卡': 人数, '年卡': 人数}
    - 'top_points_member': (手机号, 姓名, 积分) 或 None
    - 'top_booking_course': (课程编号, 名称, 预约率) 或 None
    - 'full_courses': 预约满的课程列表,元素为 (编号, 名称)
    """
    total_members = len(members)
    print(f"会员总数:{total_members}")
    for key,value in members.items():
        month_count=season_count=year_count=0
        if value['type'] == "月卡":
            month_count += 1
        elif value['type'] == "季卡":
            season_count += 1
        elif value['type'] == "年卡":
            year_count +=1
    print(f"月卡:{month_count}人,季卡:{season_count}人,年卡:{year_count}人")
    result = sorted(members,key=lambda a:members[a]['points'],reverse=True)
    print(f"积分最高的会员手机号:{members[result[0]]},\t姓名:{members[result[0]]['name']},\t积分:{members[result[0]]['points']}")
    if len(courses) == 0:
        pass
    else:
        result1 = sorted(courses,key= reservation_rate,reverse=True)
        res_rate = float(courses[result1[0]]['bokked']/courses[result1[0]]['capacity'])
        print(f"预约率最高的课程信息,课程编号:{result1[0]},名称:{courses[result1[0]]['name']},预约率:{res_rate:.2f}")
    have_course = True
    for key,value in courses.items():
        if value['capacity'] == value['bokked']:
            print(f"剩余名额为0的课程编号:{key},课程名称:{value['name']}")
            have_course = False
    if have_course:
        print("所有课程均有空位")

def show_reservations(reservations: list) -> None:
# 显示预约日志        按时间顺序打印 reservations 中的每条记录,格式清晰。若无日志则提示“暂无预约记录”。
    if len(reservations) == 0:
        print("暂无预约记录")
    else:
        print(reservations)

def main():
    while True:
        print(text)
        choose = input("请输入要选择的功能项(1-10)")
        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":
            get_statistics(members, courses)
        elif choose == "9":
            show_reservations(reservations)
        elif choose == "10":
            print("退出此程序!")
            break
main()





Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐