几个好玩有趣的Python入门实例

x33g5p2x  于2021-11-30 转载在 Python  
字(5.9k)|赞(0)|评价(0)|浏览(352)

几个好玩有趣的Python入门实例

几个简单的Python实例,好玩有趣,基础语法。

  • turtle库开始自己的绘画
  • 写一个属于自己的文本进度条
  • 蒙特卡洛方法计算π
  • 分形几何,Koch雪花曲线
  • 输入一组数据,进行简单的统计
  • 小说词频统计,统计三国演义中谁出场率最高
  • 轻松抓住文本主旨:文本词云生成

drawing with turtle

好玩有趣,入门级绘图库turtle,文档在此。
文档中的实例:太阳花。

from turtle import *
color('red', 'yellow')
begin_fill()
while True:
    forward(200)
    left(170)
    if abs(pos()) < 1:
        break
end_fill()
done()

画一个六芒星:

import turtle as t

# size传入最大的圆的半径
def draw_Star(size):
    t.setup(1200, 1000)
    t.speed(11)
    t.pensize(2)
    t.pencolor('grey')
    for r, pen_size in [(size//7, 3), (size*6//7, 4), (size, 4)]:
        t.penup()
        t.goto(0, -r)
        t.pendown()
        t.pensize(pen_size)
        t.circle(r)
        t.penup()
        t.goto(0, 0)
    r = size * 5.5 // 7
    for i in range(6):
        t.pendown()
        t.pensize(3)
        t.seth(i * 60 + 30)
        t.fd(r)
        t.goto(0, 0)
    t.goto(0, r)
    t.seth(-150)
    t.pensize(5)
    for i in range(6):
        t.fd(r)
        t.left(60)
    r = r - size // 50
    t.goto(0, r)
    t.pensize(10)
    t.seth(-120)
    t.pencolor('orange')
    for i in range(3):
        t.fd(r * (3**0.5))
        t.left(120)
    t.penup()
    t.goto(0, 0)
    t.seth(30)
    t.fd(r)
    t.seth(-180)
    t.pendown()
    for i in range(3):
        t.fd(r * (3 ** 0.5))
        t.left(120)
    t.hideturtle()
    t.done()

draw_Star(400)

文本进度条

不停向下打印的版本:

import time

def bar(scale):
    print('===========执行开始============')
    for i in range(scale + 1):
        a = '*' * i
        b = '.' * (scale - i)
        c = (i / scale) * 100
        print('\r{:^3.0f}%[{}->{}]'.format(c, a, b), end = '')
        time.sleep(0.05)
    print('\n===========执行结束============')

单行刷新版本:

import time

def pro_bar(scale):
    print('执行开始'.center(scale // 2, '='))
    start = time.perf_counter()
    for i in range(scale + 1):
        a = '*' * i
        b = '.' * (scale - i)
        c = (i / scale) * 100
        dur = time.perf_counter() - start
        print('\r{:^3.0f}%[{}->{}] {:.2f}s'.format(c, a, b, dur), end = '')
        time.sleep(0.05)
    print('\n' + '执行结束'.center(scale // 2, '='))

pro_bar(50)

单行刷新效果在cmd窗口中运行才有效,IDLE禁\r转义字符。

蒙特卡洛方法计算π

随机数生成使用random库,文档在此。思路即是随机生成点,落在正方形内。计算正方形内的圆内落点与正方形内落点之比,近似为面积之比,随机数越随机,数量越大越准确。

from random import random
from time import perf_counter

def calPI(N = 100):
    hits = 0
    start = perf_counter()
    for i in range(1, N*N+1):
        x, y = random(), random()
        dist = pow(x ** 2 + y ** 2, 0.5)
        if dist <= 1.0:
            hits += 1
    pi = (hits * 4) / (N * N)
    use_time = perf_counter() - start
    return pi, use_time

PI, use_time = calPI(1000)
print('\nuse Monte Carlo method to calculate PI: {}'.format(PI))
print('use time: {} s'.format(use_time))

递归绘制Koch雪花曲线

koch雪花曲线是分形几何中的一个经典曲线。

使用turtle库,简单的递归即可绘制。

import turtle

def koch(size, n):
    if n == 0:
        turtle.fd(size)
    else:
        for angle in [0, 60, -120, 60]:
            turtle.left(angle)
            koch(size/3, n-1)

def main():
    turtle.setup(1200, 1000)
    turtle.speed(11)
    turtle.penup()
    turtle.goto(-300, 200)
    turtle.pendown()
    turtle.pensize(2)
    level = 4
    koch(600, level)  # 3阶科赫曲线
    turtle.right(120)
    koch(600, level)
    turtle.right(120)
    koch(600, level)
    turtle.hideturtle()
    turtle.done()

main()

简单统计

输入一组数据,计算均值,方差,中位数,绝对相对误差

# -*- coding: utf-8 -*-

# 输入数据
def getNum():
    nums = []
    iNumStr = input('please input a sequence of numbers (enter to exit): ')
    while iNumStr != '':
        nums.append(eval(iNumStr))
        iNumStr = input('please input a sequence of numbers (enter to exit): ')
    return nums

# 平均数
def average(numbers):
    return sum(numbers) / len(numbers)

# 标准差
def dev(numbers, average):
    sdev = 0.0
    for num in numbers:
        sdev += (num - average) ** 2
    return pow(sdev / len(numbers), 0.5)

# 中位数
def median(numbers):
    sorted(numbers)
    size = len(numbers)
    if size % 2 == 0:
        return (numbers[size//2-1] + numbers[size//2]) / 2
    else:
        return numbers[size//2]

# 绝对与相对误差
def rel_dev(numbers, average):
    _max = max(abs(max(numbers) - average), abs(min(numbers) - average))
    return _max, _max / average

def main():
    nums = getNum()
    if len(nums) == 0:
        print('no data')
    else:
        ave = average(nums)
        devs = rel_dev(nums, ave)
        print('和:{:.4f},平均数:{:.4f},中位数:{:.4f},方差:{:.4f},绝对误差:{:4f},相对误差:{:.4f}' \
            .format(sum(nums), ave, median(nums), dev(nums, ave), devs[0], devs[1]))

if __name__ == '__main__':
    main()

小说词频统计
策略:

中文小说:使用第三方库jieba切分,统计
英文小说:去掉特殊干扰字符,直接切分为单词,遍历统计
统计莎士比亚经典名著:Hamlet。统计最高出现单词。

def getText():
    txt = open('novels/hamlet.txt', 'r').read()
    txt = txt.lower()   # 去掉大小写干扰
    # 去掉特殊符号干扰
    for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\'':
        txt = txt.replace(ch, ' ')
    return txt

hamletTxt = getText()
words = hamletTxt.split()
counts = {}
for word in words:
    counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
# 将其按照词出现数量按照降序排列
items.sort(key = lambda x : x[1], reverse = True)

for i in range(20):
    word, count = items[i]
    print('{:^10}{:^10}'.format(word, count))

统计名著三国演义中人物名字出现次数:

其中一个jieba库是一个对中文文本依照汉字间关联概率进行词组划分的第三方库,使用简单,且非常好用,文档在此

import jieba

def getWords():
    txt = open('novels/threekingdoms.txt', 'r', encoding = 'utf-8').read()
    words = jieba.lcut(txt)
    counts = {}
    for word in words:
        if len(word) == 1:
            continue
        else:
            counts[word] = counts.get(word, 0) + 1
    word_list = list(counts.items())
    word_list.sort(key = lambda x : x[1], reverse = True)
    return word_list

进行人肉优化,去掉不是人名的词语,并将一些指同一个人物的词合并到一个人物下。

import jieba

def countWords(excludes, merges):
    txt = open('novels/threekingdoms.txt', 'r', encoding = 'utf-8').read()
    words = jieba.lcut(txt)
    counts = {}
    # 取出长度为一的词和符号以及excludes中的词
    for word in words:
        if len(word) == 1 or word in excludes:
            continue
        else:
            counts[word] = counts.get(word, 0) + 1
    # 合并名称相同的人名
    for merge in merges:
        for name in merge[1]:
            counts[merge[0]] += counts.get(name, 0)
            del counts[name]
    word_list = list(counts.items())
    word_list.sort(key = lambda x : x[1], reverse = True)
    return word_list

excludes = {'却说','二人','不可','主公','陛下','汉中','只见','众将','后主','蜀兵','上马','大叫','太守','此人','夫人',
            '先主','后人','背后','城中','天子','一面','何不','大军','忽报','先生','百姓','何故','不能','如此','如何',
            '然后','先锋','不如','赶来','原来','令人','江东','下马','喊声','正是','徐州','忽然','荆州','左右','军马',
            '因此','成都','不见','未知','大败','大事','之后','一军','引军','起兵','军中','接应','引兵','次日','大喜',
            '进兵','大惊','可以','以为','大怒','不得','心中','下文','一声','追赶','粮草','天下','东吴','于是','都督',
            '曹兵','一齐','分解','回报','分付','只得','出马','三千','大将','许都','随后','报知','今日','不敢','魏兵',
            '前面','之兵','且说','众官','洛阳','领兵','商议','军士','星夜','精兵','城上','之计','不肯','相见','其言',
            '一日','而行','文武','襄阳','准备','若何','出战','亲自','必有','一人','人马','不知','何人','此事','之中',
            '伏兵','祁山','乘势','忽见','大笑','樊城','兄弟','首级','立于','西川','传令','当先','五百','一彪','坚守',
            '此时','之间','投降','五千','埋伏','长安','三路','遣使','将军','关兴','军师','朝廷','三军','大王','回见',
            '大将军','必然','将士','是夜','小路' }

merges = [  ('刘备',('玄德','玄德曰','玄德问','刘玄德','玄德大','玄德自','玄德闻','皇叔','刘皇叔')),
            ('关羽',('关公','云长','关云长')),
            ('孔明',('诸葛亮','孔明曰','孔明笑','孔明之','孔明自')),
            ('曹操',('丞相','孟德','曹公','曹孟德')),
            ('张飞',('翼德','张翼德'))
        ]

word_list = countWords(excludes, merges)
for i in range(30):
    word, count = word_list[i]
    print('{0:^10}{1:{3}^10}{2:^15}'.format(i+1, word, count, chr(12288))) # chr(12288)为中文空格

结果如下,当然其中类似将军、英雄、主公、大哥、君这种词语无法判断指的是谁,这里仅统计能够判断的,所以这里只能做一个相对的参考。

让梦想慢慢成长

相关文章