幾個好玩有趣的Python入門例項

NO IMAGE

幾個簡單的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()

level為4的Koch雪花如下:
koch snowflake

分形幾何真有趣!

Koch曲線形成過程(來自Matrix67):
koch

將上述的三角形換為正方形,稍微變換一下。

簡單統計

輸入一組資料,計算均值,方差,中位數,絕對相對誤差。

# -*- 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 '!"#$%&()* ,-./:;<=>[email protected][\\]^_`{|}~\'':
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)為中文空格

結果如下,當然其中類似將軍、英雄、主公、大哥、君這種詞語無法判斷指的是誰,這裡僅統計能夠判斷的,所以這裡只能做一個相對的參考。

    1         劉備         1578      
2         曹操         1485      
3         孔明         1485      
4         關羽          820      
5         張飛          393      
6         呂布          300      
7         趙雲          278      
8         孫權          264      
9         司馬懿         221      
10        周瑜          217      
11        袁紹          191      
12        馬超          185      
13        魏延          180      
14        黃忠          168      
15        姜維          151      
16        馬岱          127      
17        龐德          122      
18        孟獲          122      
19        劉表          120      
20        夏侯惇         116      
21        董卓          114      
22        孫策          108      
23        魯肅          107      
24        徐晃          97       
25        司馬昭         89       
26        夏侯淵         88       
27        王平          88       
28        劉璋          85       
29        袁術          84       
30        呂蒙          83

To be continued …

reference