python_Day08学习笔记

今日内容大纲介绍

  • 扩展: OS模块
  • 扩展: 练习题
    • 约瑟夫环
    • 1234排列组合
    • 模拟斗地主-发牌
    • 每个字符出现的次数
    • 模拟登陆, 只给3次机会
  • 扩展-递归
  • 扩展-PyMySQL

1.扩展-os模块

"""
os 模块介绍:
    概述:
        全称叫: Operating System, 系统模块, 主要是操作 文件夹, 文件, 路径等的.
        属于第3方的包, 所以我们使用的时候需要导包.
    常用函数:
        getcwd()    获取当前的工作空间目录(即: 你写相对路径时, 参考的路径). current work directory: 当前工作目录
        chdir()     改变工作空间路径.  change directory
        rmdir()     删除文件夹, 必须是空文件夹. remove directory
        mkdir()     制作文件夹.   make directory
        rename()    改名, 文件名 或者 文件夹名均可.
        listdir()   获取指定目录下 所有的子级文件或者文件夹(注意: 不包括子级的子级)
        ......
"""

# 导包
import os

# 演示 os 模块的函数
# getcwd()    获取当前的工作空间目录(即: 你写相对路径时, 参考的路径). current work directory: 当前工作目录
print(os.getcwd())

# chdir()     改变工作空间路径.  change directory
# os.chdir("d:/")
# print(os.getcwd())

# mkdir()     制作文件夹.   make directory
# os.mkdir('aa')      # 创建aa文件夹, 如果存在就报错, 不存在就创建.

# rmdir()     删除文件夹, 必须是空文件夹. remove directory
# os.rmdir('aa')

# rename()    改名, 文件名 或者 文件夹名均可.
# os.rename('aa', 'bb')
# os.rename('1.txt', 'hg.txt')

# listdir()   获取指定目录下 所有的子级文件或者文件夹(注意: 不包括子级的子级)
# file_list = os.listdir('./')
file_list = os.listdir('d:/')
print(file_list)


# 读取文件数据.
# f = open('1.txt', 'r', encoding='utf-8')
# print(f.read())
# f.close()

2.约瑟夫环

"""
约瑟夫环介绍:
    概述:
        它也叫幸运数字, 规则是: 假设有一天你穿越到了古代, 碰巧遇到古代的皇帝在杀人, 不巧的是, 你也在此列.
        规则是: 让所有的"犯人"围成一个圈, 开始数数字, 只要数到3或者3的倍数, 就干掉这个人, 直至剩下最后一人, 她/他站的位置就是: 幸运数字.
        如果可以让你选择自己的站位, 你会站到哪里?
    需求:
        键盘录入1个数字, 表示"犯人"总数, 打印: 幸运数字即可.
    例如:
        10个犯人, 幸运数字是: 4
"""
# 1. 键盘录入参与游戏的总人数, 并接收.
n = int(input('请录入参与游戏的总人数: '))     # 假设: 5

# 2. 根据总人数, 生成对应的 编号列表. 即: [1, 2, 3, 4, 5]
num_list = [i for i in range(1, n + 1)]
# print(num_list)

# 3. 核心细节1: 定义两个变量, num表示当前数到的数字, i表示当前这个人的编号(索引)
num, i = 0, 0

# 4. 具体的游戏过程, 循环操作, 直至列表剩下1个元素.
while len(num_list) != 1:
    # 数数字.
    num += 1

    # 5. 核心细节2: 如果一圈都数完了, 重置 索引为 0, 从头继续数, 下一轮了.
    if i == len(num_list):
        i = 0

    # 6. 如果当前数到的数字是3或者3的倍数, 就从列表中删除这个元素.
    if num % 3 == 0:
        num_list.pop(i)
        # 核心细节3: 删除元素后, 列表长度变化了, 索引要 -1
        i -= 1

    # 7. 当前的人数完后, 下个人开始数数字即可.
    i += 1


# 8. 走到这里, 列表只剩下1个元素了, 它就是幸运数字. 打印即可.
print(f'参与游戏总人数为: {n}, 幸运数字为: {num_list[0]}')

3.排列组合

"""
案例:
    已知有1, 2, 3, 4四个数字, 问: 它们能组合成的四位数有哪些, 并打印到控制台.
需求:
    1. 数字不能重复, 即: 1234, 2134均可, 1122不行.  按照3个一行进行输出.
        1234    1243    1324
        2143...
    2. 在上个需求的基础上, 实现: 数字1和3不能挨着, 即: 1324, 3124不行, 1234可以
    3. 在上个需求的基础上, 实现: 数字4不能开头.
    4. 扩展要求: 代码总行数不能超过 7 行.
解题思路:
    解题思路有很多, 我的这个最简单, int => str, 题目就做出来了.
"""
count = 0  # 计数器
for i in range(1234, 4322):
    s = str(i)  # 1234 => '1234'
    if '1' in s and '2' in s and '3' in s and '4' in s and '13' not in s and '31' not in s and s[0] != '4':
        # 走到这里, 是我们要的数据, 计数器 + 1
        count += 1
        print(i, end='\n' if count % 3 == 0 else '\t')

4.统计每个字符出现的次数

"""
需求:
    键盘录入1个字符串, 并接收, 统计其中每个字符的次数, 并将结果打印到控制台上.
"""

# 1. 键盘录入1个字符串,并接收.
s = input('请录入1个字符串, 我来统计每个字符的次数: ')        # 假设: aaabbc

# 2. 定义字典, 记录每个字符 及其 次数.   字符做键, 次数做值, 例如: 'a':3, 'b':2, 'A':1
# wc_dict = {}        # word count: 单词数量      hello world python sql linux

# 方式1: 分解版
# # 3. 遍历上述的字符串, 获取到每个字符, 充当字典的键.
# for key in s:     # i的值: 'a', 'a', 'a', 'b', 'b', 'c'
#     # 4. 核心: 判断字典中是否有这个键, 有就将其次数 + 1 重新存储.
#     if key in wc_dict:
#         # 例如: 'a': 2 => 'a': 3
#         wc_dict[key] = wc_dict[key] + 1
#     else:
#         # 5. 没有说明这个键是第一次出现, 就将其次数记录为1
#         # 例如: 'b', 1
#         wc_dict[key] = 1

# 方式2: 三元运算符
# 3. 遍历上述的字符串, 获取到每个字符, 充当字典的键.
# for key in s:     # i的值: 'a', 'a', 'a', 'b', 'b', 'c'
#     wc_dict[key] = wc_dict[key] + 1  if key in wc_dict else 1

# 方式3: 字典推导式
wc_dict = {key: s.count(key) for key in s}      # key是字符串中的每个字符.

# 6. 循环结束后, 打印字典即可.
print(wc_dict)

5.模拟登陆

# 需求: 模拟登陆, 只给3次机会.

# 1. 假设初始的账号 和 密码.
username = 'heima'
password = 'ai28'

# 2. 因为只给3次机会, 建议使用 for 循环.
for i in range(3):      # i的值: 0, 1, 2
    # 3. 提示用户录入账号或者密码并接收.
    uname = input('请录入您的账号: ')
    pwd = input('请录入您的密码: ')

    # 4. 判断是否登录成功, 成功则提示, 然后程序结束.
    if uname == username and pwd == password:
        print(f'欢迎您, {uname}!')     # 可以是昵称, nickname
        break   # 记得结束循环.
    else:
        # 5. 不成功, 就判断还有几次登陆机会, 并提示.
        # if i == 2:
        #     print('录入错误次数已达上限, 账号被锁定, 请于管理员联系: 010-123456')
        # else:
        #     print(f'录入有误, 请重新录入, 您还有 {2 - i} 次机会!')     # 2, 1, 0
        print('录入错误次数已达上限, 账号被锁定, 请于管理员联系: 010-123456' if i == 2 else f'录入有误, 请重新录入, 您还有 {2 - i} 次机会!')

6.模拟斗地主发牌

# 案例: 模拟斗地主发牌.
import random

# 定义变量, 表示扑克牌.
poker_dict = {}  # 键: 牌的索引, 值: 具体的牌.  规则: 牌越小, 索引越小.
poker_index = []  # 所有的 牌的索引, 我们发的是这个, 看牌是: 排序后, 根据键找值.
p1 = []  # 玩家1
p2 = []  # 玩家2
p3 = []  # 玩家3
dp = []  # 底牌


# 1. 买牌.
def get_poker():
    global poker_dict
    # 1.1 定义 花色列表.
    color_list = ['♠', '♥', '♦', '♣']
    # 1.2 定义 点数列表.
    num_list = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']
    # 1.3 生成 字典, 键: 索引, 值: 牌.   规则: 牌越小, 索引越小.
    # 列表
    poker_list = [color + num for num in num_list for color in color_list]
    # 字典
    poker_dict = {i: poker_list[i] for i in range(len(poker_list))}
    # 添加大小往.
    poker_dict[52] = '小🤡'
    poker_dict[53] = '大🤡'
    # print(poker_dict)


# 2. 洗牌.
def shuffle_poker():
    global poker_index
    # 获取所有牌的索引.
    poker_index = list(poker_dict.keys())
    # print(poker_index)

    # 具体的洗牌动作.
    random.shuffle(poker_index)
    # print(poker_index)


# 3. 发牌
def send_poker():
    global p1, p2, p3, dp
    # 规则: 最后3张做底牌, 其它轮询发送.
    for i in range(len(poker_index)):  # i就是 打乱顺序后的牌的编号的 索引
        # 发送底牌
        if i >= len(poker_index) - 3:
            dp.append(poker_index[i])
        elif i % 3 == 0:
            p1.append(poker_index[i])
        elif i % 3 == 1:
            p2.append(poker_index[i])
        else:
            p3.append(poker_index[i])


# 4. 看牌.
def look_poker(player_name, player_poker_num):
    """
    根据玩家手中 牌的编号, 取 牌盒poker_dict中找 牌.
    :param player_name: 玩家名
    :param player_poker_num: 玩家手中的牌的编号.
    :return:
    """
    # 4.1 排序.
    player_poker_num.sort()
    # 4.2 玩家手中具体的牌.
    player_poker = [poker_dict[i] for i in player_poker_num]
    # 4.3 打印结果
    print(f'{player_name}的牌是: {player_poker}')


# 在main函数中调用.
if __name__ == '__main__':
    # 1. 买牌
    get_poker()
    # 2. 洗牌
    shuffle_poker()
    # 3. 发牌
    send_poker()
    # 看牌
    look_poker('刘亦菲', p1)
    look_poker('赵丽颖', p2)
    look_poker('张小二', p3)
    look_poker('底牌', dp)

7.递归-求阶乘

"""
递归 介绍:
    概述:
        递归指的是 函数自己调用自己的情况.
    细节:
        1. 递归必须要有出口, 否则: 就是死递归, 容易造成 栈内存溢出.
        2. 递归不能调用次数过多, 否则: 容易造成 栈内存溢出.
        3. 递归必须要有 规律, 即: 重复做的事儿.
        4. 总结, 搞定递归很简单, 只要: 分析出 出口 和 规律即可.
    经典案例:
        1. 求阶乘.
        2. 斐波那契数列, 也叫: 不死神兔.


# 需求: 求5的阶乘, 分析流程如下:
    5! = 5 * 4 * 3 * 2 * 1                     ---
         5 * 4!                                 |
             4 * 3!                            规律
                 3 * 2!                         |
                     2 * 1!                    ---
                         1! = 1                 出口

总结:
    出口: 1! = 1
    规律: n! = n * (n - 1)!
"""

# 需求: 求5的阶乘.   5! = 5 * 4 * 3 * 2 * 1
# 1. 定义函数 factorial(n), 计算: n的阶乘.
def factorial(n):
    # 出口: 1! = 1
    if n == 1:
        return 1

    # 规律: n! = n * (n - 1)!
    return n * factorial(n - 1)



# 2. 调用 factorial()函数.
if __name__ == '__main__':
    print(factorial(5))

8.递归-斐波那契数列

"""
需求:
    传说在很久以前, 有一个意大利青年叫: 斐波那契, 有一天他提出1个非常有意思的问题:
        1. 1对小兔子, 1个月之后会长成1对大兔子.
        2. 1对大兔子, 每个月都会生1对小兔子.
        3. 假设所有兔子都不死的情况下, 问: 1对小兔子, 1年(即: 12个月)之后, 会变成多少对兔子.    144对.

分析思路:
    月份          大兔子对数       小兔子对数       兔子总对数
    1月              0              1               1
    2月              1              0               1
    3月              1              1               2
    4月              2              1               3
    5月              3              2               5
    6月              5              3               8
    ......

总结:
    出口: 前两个月的兔子对数都是 1
    规律: 从第3个月开始, 兔子对数 = 上个月的兔子对数 + 上上个月的兔子对数.
"""


# 1. 定义函数, 计算兔子对数.
def get_rabbit(m):
    """
    根据传入的月份, 计算兔子对数.
    :param m: 月份
    :return: 当月的兔子对数.
    """
    # 出口: 前两个月的兔子对数都是
    # if m == 1 or m == 2:
    if m in [1, 2]:
        return 1

    # 规律: 从第3个月开始, 兔子对数 = 上个月的兔子对数 + 上上个月的兔子对数.
    return get_rabbit(m - 1) + get_rabbit(m - 2)


# 2. 调用函数.
if __name__ == '__main__':
    print(get_rabbit(12))       # 第12个月, 144对

9.pymysql-入门

"""
pymysql 模块解释:
    概述:
        它属于第三方的模块, 用之前需要先安装一下.  它是Python操作MySQL数据库的规范和规则.
        里边定义了一些API(函数), 可以帮助我们实现通过Python操作MySQL, 进行 增删改查的操作.
    安装方式:
        方式1: DOS命令方式, pip install pymysql [-i 镜像地址]
            例如: 清华大学镜像 https://pypi.tuna.tsinghua.edu.cn/simple

        方式2: 导包的时候 安装.
            写完包名后, 按下 alt + enter, 给出建议, 选择: install 包名.
    pymysql的操作步骤:
        1. 获取连接对象.              Python连接MySQL的对象.
        2. 获取游标对象.              可以执行SQL语句的对象.
        3. 执行SQL语句, 获取结果集.
        4. 操作结果集.
        5. 释放资源.

    大白话解释pymysql的步骤:
        1. 找到前台小姐姐.           你(Python) 和 黑马(MySQL)建立了连接, 通过: 前台小姐姐(连接对象)
        2. 前台小姐姐找到 任课老师.    任课老师: 讲解知识点的.
        3. 任课老师给大家(学生)讲课, 获取资料: 视频, 代码, 笔记, 图片, 作业...
        4. 你(学生)操作结果集, 视频: 看, 代码: 敲, 笔记: 整理...
        5. 跟 任课老师, 前台小姐姐 说再见.

细节:
    需要开启MySQL服务, 例如: 小皮.
"""

import pymysql

# 1. 获取连接对象.  6个参数: MySQL所在的主机ip或者主机名, 端口号, 账号, 密码, 库名, 码表
conn = pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123456',
    database='day02',
    charset='utf8'
)

# 2. 获取游标对象.
cus = conn.cursor()

# 3. 执行SQL语句, 获取结果集.
sql = 'select * from hero;'
cus.execute(sql)

# 4. 操作结果集.
# 场景1: 从游标对象中, 获取所有的数据. 格式为: 元组嵌套元组, ((1, '鸠摩智', 9), (3, '乔峰', 1)...)
# data = cus.fetchall()

# 场景2: 从游标对象中, 获取第1条数据.
# data = cus.fetchone()

# 场景3: 从游标对象中, 获取n条数据.
data = cus.fetchmany(3)

print(data)

# 5. 释放资源.
cus.close()
conn.close()

10.pymysql-curd

# 案例: 演示PyMySQL操作 MySQL数据库, 进行 CURD 增删改查操作.
import pymysql

# 1. pymysql模块 操作 mysql数据库, 增
def insert_method():
    # 1. 获取连接对象.
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='day02',
                           charset='utf8')
    # 2. 根据连接对象, 获取 游标对象.
    cur = conn.cursor()
    # 3. 执行SQL语句, 获取结果集.
    sql = 'insert into hero values(6, "杨过", 20);'
    n = cur.execute(sql)        # n就是受到影响的行数, 例如: 增了几行, 删了几行, 改了几行.
    # 核心操作: 增, 删, 改属于更新语句, 操作之后必须 commit()提交, 才会保存结果.
    conn.commit()
    # 4. 操作结果集.
    # if n > 0:
    #     print('添加成功!')
    # else:
    #     print('添加失败!')
    print('添加成功' if n > 0 else '添加失败!')
    # 5. 释放资源.
    cur.close()
    conn.close()

# 2. pymysql模块 操作 mysql数据库, 删
def delete_method():
    # 1. 获取连接对象.
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='day02',
                           charset='utf8')
    # 2. 根据连接对象, 获取 游标对象.
    cur = conn.cursor()
    # 3. 执行SQL语句, 获取结果集.
    sql = 'delete from hero where hid > 3;'
    n = cur.execute(sql)  # n就是受到影响的行数, 例如: 增了几行, 删了几行, 改了几行.
    # 核心操作: 增, 删, 改属于更新语句, 操作之后必须 commit()提交, 才会保存结果.
    conn.commit()
    # 4. 操作结果集.
    print('删除成功' if n > 0 else '删除失败!')
    # 5. 释放资源.
    cur.close()
    conn.close()

# 3. pymysql模块 操作 mysql数据库, 改
def update_method():
    # 1. 获取连接对象.
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='day02',
                           charset='utf8')
    # 2. 根据连接对象, 获取 游标对象.
    cur = conn.cursor()
    # 3. 执行SQL语句, 获取结果集.
    sql = 'update hero set hname="神雕侠", kongfu_id=100 where hid=6;'
    n = cur.execute(sql)  # n就是受到影响的行数, 例如: 增了几行, 删了几行, 改了几行.
    # 核心操作: 增, 删, 改属于更新语句, 操作之后必须 commit()提交, 才会保存结果.
    conn.commit()
    # 4. 操作结果集.
    print('修改成功' if n > 0 else '修改失败!')
    # 5. 释放资源.
    cur.close()
    conn.close()

# 4. pymysql模块 操作 mysql数据库, 查
def query_method():
    # 1. 获取连接对象.
    conn =  pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='day02', charset='utf8')
    # 2. 根据连接对象, 获取 游标对象.
    cur = conn.cursor()
    # 3. 执行SQL语句, 获取结果集.
    sql = 'select * from hero;'
    cur.execute(sql)
    # 4. 操作结果集.
    data = cur.fetchall()
    for line in data:
        print(line)
    # 5. 释放资源.
    cur.close()
    conn.close()


# 5. 在main方法中, 测试调用:
if __name__ == '__main__':
    # 添加 表数据
    # insert_method()

    # 修改 表数据
    # update_method()

    # 删除 表数据
    delete_method()

    # 查看 表数据.
    query_method()
posted @ 2025-08-12 22:47  eagle88  阅读(20)  评论(0)    收藏  举报