Python上机实验指南(二)

一、实验目的 

实验3:函数与代码复用

  1. 理解函数封装:通过编写函数(如阶乘、斐波那契数列等),学会封装代码,提高复用性和可维护性。

  2. 掌握递归思想:用递归实现斐波那契数列,理解递归原理,学会设置终止条件,避免栈溢出。

  3. 拓展编程能力:通过科赫曲线绘制,引入额外功能(如绘制速度、颜色等),综合运用多种编程知识解决复杂问题。

实验4:列表与字典应用

  1. 熟练操作组合数据类型:通过生日悖论分析、文本词频统计等任务,掌握列表和字典的操作,提升数据处理能力。

  2. 数据处理与分析能力:借助组合数据类型处理数据,如计算概率、统计词频、生成词云,培养数据分析能力。

  3. 文本分析与风格总结:通过分析武侠小说文本,总结写作风格,提升文本处理和分析能力。

二、实验环境

        Python 3.8.1+IDLE 

三、实验内容

实验3 函数与代码复用(2 学时)

提示 :递归函数需注意终止条件,避免栈溢出

实验任务:

3.1. 基础 :编写函数cal_factorial(n)计算阶乘(循环实现)。

实现功能的Python代码: 

def cal_factorial(n):
    if n < 0:
        raise ValueError("n必须是非负整数")
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

if __name__ == "__main__":
    try:
        num = int(input("请输入一个非负整数:"))
        print(f"{num} 的阶乘是:{cal_factorial(num)}")
    except ValueError as e:
        print(e)

代码运行结果图:

 

3.2. 进阶 :用递归实现斐波那契数列(考虑添加缓存优化)。

 实现功能的Python代码:

# 使用字典作为缓存
fib_cache = {}

def fibonacci(n):
    if n in fib_cache:
        return fib_cache[n]  # 如果结果已经缓存,直接返回
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        result = fibonacci(n - 1) + fibonacci(n - 2)
        fib_cache[n] = result  # 将结果存入缓存
        return result

if __name__ == "__main__":
    try:
        num = int(input("请输入一个非负整数:"))
        print(f"斐波那契数列的第 {num} 项是:{fibonacci(num)}")
    except ValueError as e:
        print(e)

 代码运行结果图:

3.3. 拓展 :科赫曲线正向、反向绘制,加入绘制速度、绘制颜色等额外
功能。

实现功能的Python代码: 

import turtle

def koch_curve(t, order, size, direction=1, speed=1, color="black"):
    """
    绘制科赫曲线
    :param t: turtle对象
    :param order: 科赫曲线的阶数
    :param size: 初始线段长度
    :param direction: 绘制方向,1为正向,-1为反向
    :param speed: 绘制速度
    :param color: 绘制颜色
    """
    if order == 0:  # 基础情况:绘制直线
        t.color(color)
        t.speed(speed)
        t.forward(size * direction)
    else:
        # 递归绘制每个部分,统一处理方向
        koch_curve(t, order - 1, size / 3, direction, speed, color)
        t.left(60 * direction)
        koch_curve(t, order - 1, size / 3, direction, speed, color)
        t.right(120 * direction)
        koch_curve(t, order - 1, size / 3, direction, speed, color)
        t.left(60 * direction)
        koch_curve(t, order - 1, size / 3, direction, speed, color)

def draw_koch_curve(order, size, direction=1, speed=1, color="black"):
    """
    初始化并绘制科赫曲线
    :param order: 科赫曲线的阶数
    :param size: 初始线段长度
    :param direction: 绘制方向,1为正向,-1为反向
    :param speed: 绘制速度
    :param color: 绘制颜色
    """
    # 初始化turtle
    window = turtle.Screen()
    window.setup(width=800, height=600)  # 设置窗口大小
    window.bgcolor("white")
    t = turtle.Turtle()
    t.hideturtle()  # 隐藏turtle箭头
    t.penup()

    # 根据方向动态调整起点位置
    if direction == 1:  # 正向绘制,起点在左侧
        t.goto(-size / 2, 0)
    elif direction == -1:  # 反向绘制,起点在右侧
        t.goto(size / 2, 0)

    t.pendown()
    koch_curve(t, order, size, direction, speed, color)
    window.mainloop()

# 示例测试代码
if __name__ == "__main__":
    try:
        order = int(input("请输入科赫曲线的阶数(建议1-6):"))
        size = int(input("请输入初始线段长度(建议600):"))
        direction = int(input("请输入绘制方向(1为正向,-1为反向):"))
        speed = int(input("请输入绘制速度(1-10):"))
        color = input("请输入绘制颜色(如'blue'、'red'等):")
        draw_koch_curve(order, size, direction, speed, color)
    except ValueError as e:
        print("输入无效,请确保输入的是数字。")

代码运行结果图:

正向绘制:

反向绘制:

实验4:列表与字典应用(2 学时)

实验任务:

4.1. 基础:生日悖论分析。如果一个房间有23 人或以上,那么至少有两
个人的生日相同的概率大于50%。编写程序,输出在不同随机样本数
量下,23 个人中至少两个人生日相同的概率。

实现功能的Python代码: 

import random

def birthday_paradox(num_people, num_simulations):
    same_birthday_count = 0
    for _ in range(num_simulations):
        birthdays = set()
        for _ in range(num_people):
            birthday = random.randint(1, 365)
            if birthday in birthdays:
                same_birthday_count += 1
                break
            birthdays.add(birthday)
    return same_birthday_count / num_simulations

sample_sizes = [20, 23, 25, 30]
num_simulations = 10000

for size in sample_sizes:
    probability = birthday_paradox(size, num_simulations)
    print(f"在{size}个人中,至少有两个人生日相同的概率为:{probability:.4f}")

代码运行结果图: 

4.2. 进阶:统计《一句顶一万句》文本中前10 高频词,生成词云。

实现功能的Python代码:  

import jieba
from wordcloud import WordCloud
from collections import Counter
import re
import matplotlib.pyplot as plt

# 读取文本文件
with open('wenben.txt', 'r', encoding='utf-8') as f:
    text = f.read()

# 预处理文本(去除非中文字符)
text = re.sub(r'[^\u4e00-\u9fa5]', '', text)

# 使用jieba分词
words = jieba.lcut(text)

# 自定义停用词列表(可根据需要补充)
stopwords = {
    '的', '了', '在', '是', '我', '和', '就', '他', '说', '人', '有', '不', '也',
    '这', '着', '一', '上', '等', '你', '我们', '他们', '那', '中', '又', '吗',
    '啊', '吧', '呢', '对', '没', '个', '去', '要', '还', '里', '为', '来', '都'
}

# 过滤停用词和单字词
filtered_words = [word for word in words if len(word) > 1 and word not in stopwords]

# 统计高频词
word_counts = Counter(filtered_words)
top10 = word_counts.most_common(10)
print("前10高频词:")
for word, count in top10:
    print(f"{word}: {count}")

# 生成词云
wc = WordCloud(
    font_path='simhei.ttf',   # 需要中文字体支持
    background_color='white',
    width=800,
    height=600,
    max_words=200
)
wc.generate_from_frequencies(word_counts)

# 显示词云
plt.figure(figsize=(10, 8))
plt.imshow(wc, interpolation='bilinear')
plt.axis('off')  # 关闭坐标轴
plt.show()

代码运行结果图:  

 

词云图: 

4.3. 拓展:金庸、古龙等武侠小说写作风格分析。输出不少于3 个金庸(古
龙)作品的最常用10 个词语,找到其中的相关性,总结其风格。

实现功能的Python代码: 

from collections import Counter
import jieba  # 用于中文分词

# 读取文件内容
def read_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return file.read()

# 分析文本中最常用的词语
def analyze_text(text):
    # 使用jieba进行中文分词
    words = jieba.cut(text)
    # 去除常见的无用词,假设已知常见停用词
    stopwords = set(["的", "了", "在", "是", "和", "也", "有", "就", "不", "人", "这", "但", "上", "到", "他", "与"])
    filtered_words = [word for word in words if word not in stopwords and len(word.strip()) > 1]
    # 统计词频
    return Counter(filtered_words)

# 输出前三本小说的最常用词
novels = ["天龙八部.txt", "倚天屠龙记.txt", "射雕英雄传.txt"]
counters = {}

for novel in novels:
    text = read_file(novel)
    word_counter = analyze_text(text)
    counters[novel] = word_counter.most_common(10)
    print(f"在《{novel}》中,最常用词语前10为:")
    for word, freq in counters[novel]:
        print(f"{word}: {freq}")
    print("")

# 发现其中的相关性和总结风格
common_terms = set(counters[novels[0]]).intersection(set(counters[novels[1]])).intersection(set(counters[novels[2]]))
print("在三本小说中都出现的常用词:", common_terms)

代码运行结果图: 

 

总结金庸风格:

  1. 英雄人物:金庸的小说通常以英雄人物为核心,人物之间的关系和遭遇是推动情节发展的主要因素。所以,常见词语可能包括人物姓名或其称谓。

  2. 江湖义气:友情、正义感以及对"江湖规矩"的遵循是金庸小说的一大特色。这类词语经常出现在他的小说中。

  3. 武学描写:金庸擅长描绘刀光剑影的武侠世界,关于武功招式、练功心法的词汇经常频繁出现。

四、实验心得体会

        通过实验3,我深刻体会到函数封装的便利,它让代码更简洁、易于维护和复用。在用递归实现斐波那契数列时,我理解了递归的逻辑和优化方法,但也意识到需注意终止条件,避免栈溢出。科赫曲线绘制任务则让我综合运用了函数封装、递归和绘图库,提升了综合编程能力。实验4让我熟练掌握了列表和字典的操作,在生日悖论分析和文本词频统计中,我提升了数据处理效率,感受到数据处理与分析的乐趣。在武侠小说风格分析中,通过提取常用词语和分析相关性,我总结了作者风格,提升了文本分析能力。这两个实验让我在编程和数据处理方面都有了很大进步,对相关概念有了更深入的理解。

作者:Auroraꦿ᭄²º²⁴

物联沃分享整理
物联沃-IOTWORD物联网 » Python上机实验指南(二)

发表回复