《Python程序设计与算法基础教程(第二版)》江红 余青松 全部章节的课后习题,上机实践,课后答案,案例研究「建议收藏」(Python.org)
大家好,又見面了,我是你們的朋友風君子。如果您正在找激活碼,請點擊查看最新教程,關注關注公眾號 “全棧程序員社區” 獲取激活教程,可能之前舊版本教程已經失效.最新Idea2022.1教程親測有效,一鍵激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟無欺
(還在更新中…) 這篇博客花費了我的大量時間和精力,從創作到維護;若認可本篇博客,希望給一個點贊、收藏
并且,遇到了什么問題,請在評論區留言,我會及時回復的
這本書對Python的知識點的描述很詳細,而且排版看的很舒服
- 幾個例題: 假裝自己從零開始學,將一些有代表性、有意思的例題抽取出來
- 部分復習題: 遇到有意思的復習題,我會拿出來,并且進行分析
- 上機實踐: 全部上機實踐題的解題思路
第一章 Python概述
幾個例題
一:Python3.7.4下載
python3.7.4下載地址:https://www.python.org/downloads/release/python-374/
頁面最下面:
下載,安裝完python后:出現的四個玩意:Python 3.7 Module Docs,IDLE,Python 3.7 Manuals,Python 3.7(64-bit)
-
Python 3.7 Module Docs(64-bit)
點擊之后,會出現一個網頁(將我下載的Python3.7.4文件夾中包含的模塊都列了出來,頁面不止這么點,還可以往下拉)
-
IDLE(Python 3.7 64-bit)
一個Python編輯器,Python內置的集成開發工具
-
Python 3.7 Manuals(64-bit)
Python 3.7 開發手冊 -
Python 3.7(64-bit)
控制臺中運行Python
二:更新pip和setuptools包,安裝NumPy包,安裝Matplotlib包
以下三個命令都是在控制臺(windows中的cmd)中運行
更新pip和setuptools包
- pip用于安裝和管理Python擴展包
- setuptools用于發布Python包
python -m pip install -U pip setuptools
安裝NumPy
Python擴展模塊NumPy提供了數組和矩陣處理,以及傅立葉變換等高效的數值處理功能
python -m pip install NumPy
安裝Matplotlib包
Matplotlib是Python最著名的繪圖庫之一,提供了一整套和MATLAB相似的命令API,既適合交互式地進行制圖,也可以作為繪圖控件方便地嵌入到GUI應用程序中
python -m pip install Matplotlib
三:使用IDLE打開和執行Python源文件程序
首先:
有一個.py文件test.py
使用IDLE打開.py文件的兩種方式:
- 右鍵test.py—->Edit With IDLE—->Edit With IDLE 3.7(64-bit)
- 打開IDLE,然后File—->Open(或者
ctrl+O)選擇.py文件
運行
Run—->Run Module(或者F5)
就會出現這個界面,執行結果顯示在這個界面中
補充一點:
如果在IDLE中編輯.py文件,記得修改后要保存(ctrl+s),再運行(F5)
四:使用資源管理器運行hello.py
hello.py文件在桌面
import random
print("hello,Python")
print("你今天的隨機數字是:",random.choice(range(10)))#輸出在0-9之間隨機選擇的整數
input()
- 在桌面打開PowerShell(還有兩種輸入方式:
python hello.py或者.\hello.py)
- 或者在桌面打開cmd, 就輸入
hello.py或者python hello.py
補充:上述兩種命令中的hello.py都是相對路徑,因為文件在桌面,而且我是在桌面打開cmd,所以文件路勁可以這么簡簡單單的寫。如果文件存儲位置和cmd打開位置不一樣,請使用絕對路徑
五:命令行參數示例hello_argv.py
hello_argv.py文件在桌面
import sys
print("Hello,",sys.argv[1])
#這樣寫也行:
#print("Hello,"+sys.argv[1])
- 在桌面打開PowerShell(還有兩種輸入方式:
python hello_argv.py 任意輸入或者./hello_argv.py 任意輸入)
- 或者在桌面打開cmd,就輸入
hello_argv.py 任意輸入或者python hello_argv.py 任意輸入
補充:以圖中第一個命令舉例,hello_argv.py即sys.argv[0];Python即sys.argv[1]
第二章 Python語言基礎
選擇題:1、3、7、8
1. 在Python中,以下標識符合法的是
| A. _ | B. 3C | C. it’s | B. str |
|---|
答案:A
- 標識符的第一個字符必須是字母,下劃線(_);其后的字符可以是字母、下劃線或數字。
- 一些特殊的名稱,作為python語言的保留關鍵字,不能作為標識符
- 以雙下劃線開始和結束的名稱通常具有特殊的含義。例如
__init__為類的構造函數,一般應避免使用
B:以數字開頭,錯誤
C:使用了',不是字母、下劃線或數字
D:str是保留關鍵字
3. 在下列Python語句中非法的是
| A. x = y =1 | B. x = (y =1) | C. x,y = y,x | B. x=1;y=1 |
|---|
答案:B,C
7. 為了給整型變量x,y,z賦初值10,下面Python賦值語句正確的是
| A. xyz=10 | B. x=10 y=10 z=10 | C. x=y=z=10 | B. x=10,y=10,z=10 |
|---|
答案:C
- 分號
;用于在一行書寫多個語句- python支持鏈式賦值
A:賦值對象是xyz
B:分號;用于在一行書寫多個語句,而不是' '(即空格)
D:分號;用于在一行書寫多個語句,而不是,
8. 為了給整型變量x,y,z賦初值5,下面Python賦值語句正確的是
| A. x=5;y=5;z=5 | B. xyz=5 | C. x,y,z=10 | B. x=10,y=10,z=10 |
|---|
答案:A
Pytho能支持序列解包賦值,但是變量的個數必須與序列的元素個數一致,否則會報錯
B:賦值對象是xyz
C:序列解包賦值,變量的個數必須與序列的元素個數一致,否則會報錯
D:分號;用于在一行書寫多個語句,而不是,
思考題:9
9.下列Python語句的輸出結果是
def f():pass
print(type(f()))
結果:<class 'NoneType'>
NoneType數據類型包含唯一值None,主要用于表示空值,如沒有返回值的函數的結果
上機實踐:2~6
2. 編寫程序,輸入本金、年利率和年數,計算復利(結果保留兩位小數)
money = int(input("請輸入本金:"))
rate = float(input("請輸入年利率:"))
years = int(input("請輸入年數:"))
amount = money*((1+rate/100)**years)
print(str.format("本金利率和為:{0:2.2f}",amount))
運行:
請輸入本金:1000
請輸入年利率:6.6
請輸入年數:10
本金利率和為:1894.84
3. 編寫程序,輸入球的半徑,計算球的表面積和體積(結果保留兩位小數)
import math
r = float(input("請輸入球的半徑:"))
area = 4 * math.pi * r**2
volume = 4/3*math.pi*r**3
print(str.format("球的表面積為:{0:2.2f},體積為:{1:2.2f}",area,volume))
運行:
請輸入球的半徑:666
球的表面積為:5573889.08,體積為:1237403376.70
4. 編寫程序,聲明函數getValue(b,r,n),根據本金b,年利率r和年數n計算最終收益v
money = int(input("請輸入本金:"))
rate = float(input("請輸入年利率(<1):"))
years = int(input("請輸入年數:"))
def getValue(b,r,n):
return b*(1+r)**n
print(str.format("本金利率和為:{0:2.2f}",getValue(money,rate,years)))
運行:
請輸入本金:10000
請輸入年利率(<1):0.6
請輸入年數:6
本金利率和為:167772.16
5. 編寫程序,求解一元二次方程x2-10x+16=0
from math import sqrt
x = (10+sqrt(10*10-4*16))/2
y = (10-sqrt(10*10-4*16))/2
print(str.format("x*x-10*x+16=0的解為:{0:2.2f},{1:2.2f}",x,y))
運行:
x*x-10*x+16=0的解為:8.00,2.00
6. 編寫程序,提示輸入姓名和出生年份,輸出姓名和年齡
import datetime
sName = str(input("請輸入您的姓名:"))
birthday = int(input("請輸入您的出生年份:"))
age = datetime.date.today().year - birthday
print("您好!{0}。您{1}歲。".format(sName,age))
運行:
請輸入您的姓名:zgh
請輸入您的出生年份:1999
您好!zgh。您20歲。
案例研究:使用Pillow庫處理圖像文件
https://blog.csdn.net/Zhangguohao666/article/details/102060722
通過此案例,進一步了解Python的基本概念:模塊、對象、方法和函數的使用
第三章 程序流程控制
幾個例題
一:編程判斷某一年是否為閏年
閏年:年份能被4整除但不能被100整除,或者可以被400整除。
口訣:四年一閏,百年不閏,四百必閏
代碼一:
y = int(input("請輸入要判斷的年份:"))
if((y % 4 == 0 and y % 100 != 0) or y % 400 == 0):
print("是閏年")
else:
print("不是閏年")
代碼二(使用calendar模塊的isleap()函數來判斷):
from calendar import isleap
y = int(input("請輸入要判斷的年份:"))
if(isleap(y)):print("閏年")
else:print("不是閏年")
二:利用嵌套循環打印九九乘法表
九九乘法表:
for i in range(1,10):
s = ""
for j in range(1,10):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
下三角:
for i in range(1,10):
s = ""
for j in range(1,i+1):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
上三角:
for i in range(1,10):
s = ""
for k in range(1,i):
s += " "
for j in range(i,10):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
三:enumerate()函數和下標元素循環示例
Python語言中的for循環直接迭代對象集合中的元素,如果需要在循環中使用索引下標訪問集合元素,則可以使用內置的enumerate()函數
enumerate()函數用于將一個可遍歷的數據對象(例如列表、元組或字符串)組合為一個索引序列,并返回一個可迭代對象,故在for循環當中可直接迭代下標和元素
seasons = ["Spring","Summer","Autumn","Winter"]
for i,s in enumerate(seasons,start=1): #start默認從0開始
print("第{0}個季節:{1}".format(i,s))
運行:
第1個季節:Spring
第2個季節:Summer
第3個季節:Autumn
第4個季節:Winter
四:zip()函數和并行循環示例
如果需要并行遍歷多個可迭代對象,則可以使用Python的內置函數zip()
zip()函數將多個可迭代對象中對應的元素打包成一個個元組,然后返回一個可迭代對象。如果元素的個數不一致,則返回列表的長度與最短的對象相同。
利用運算符*還可以實現將元組解壓為列表
evens = [0,2,4,6,8]
odds = [1,3,5,7,9]
for e,o in zip(evens,odds):
print("{0} * {1} = {2}".format(e,o,e*o))
運行:
0 * 1 = 0
2 * 3 = 6
4 * 5 = 20
6 * 7 = 42
8 * 9 = 72
五:map()函數和循環示例
如果需要遍歷可迭代對象,并使用指定函數處理對應的元素,則可以使用Python的內置函數map()
map(func,seq1[,seq2,...])
- func作用于seq中的每一個元素,并將所有的調用結果作為可迭代對象返回。
- 如果func為None,該函數的作用等同于zip()函數
計算絕對值:
>>> list(map(abs, [-1, 0, 7, -8]))
[1, 0, 7, 8]
計算乘冪:
>>> list(map(pow, range(5), range(5)))
[1, 1, 4, 27, 256]
計算ASCII碼:
>>> list(map(ord, 'zgh'))
[122, 103, 104]
字符串拼接(使用了匿名函數lambda):
>>> list(map(lambda x, y: x+y, 'zgh', '666'))
['z6', 'g6', 'h6']
選擇題:1、2、3
1. 下面的Python循環體的執行次數與其他不同的是
A.
i = 0
while(i <= 10):
print(i)
i = i + 1
B.
i = 10
while(i > 0):
print(i)
i = i - 1
C.
for i in range(10):
print(i)
D.
for i in range(10,0,-1):
print(i)
答案:A
A:[0,10] 執行11次
B:[10,1] 執行10次
C:[0,9) 執行10次
D:[10,0) 執行10次
2. 執行下列Python語句將產生的結果是
x = 2; y = 2.0
if(x == y): print("Equal")
else: print("Not Equal")
| A. Equal | B. Not Equal | C. 編譯錯誤 | D. 運行時錯誤 |
|---|
答案:A
Python中的自動類型轉換:
- 自動類型轉換注意針對Number數據類型來說的
- 當2個不同類型的數據進行運算的時候,默認向更高精度轉換
- 數據類型精度從低到高:bool int float complex
- 關于bool類型的兩個值:True 轉化成整型是1;False 轉化成整型是0
int類型的2轉化為float類型的2.0
3. 執行下列Python語句將產生的結果是
i= 1
if(i): print(True)
else: print(False)
| A. 輸出1 | B. 輸出True | C. 輸出False | D. 編譯錯誤 |
|---|
答案:B
在Python中,條件表達式最后被評價為bool值True或False。
如果表達式的結果為數值類型(0),空字符串(""),空元組(()),空列表([]),空字典({}),其bool值為False,否則其bool值為True
填空題:6
6. 要使語句for i in range(_,-4,-2)循環執行15次,則循環變量i的初值應當為
答案:26或者25
一開始我給的答案是26,經過評論區 亻的提醒:
>>> a = 0
>>> for i in range(26, -4, -2): a+=1
>>> print(a)
15
>>> a = 0
>>> for i in range(25, -4, -2): a+=1
>>> print(a)
15
這種題目有一個規律:for i in range(x,y,z):
若循環中沒有break或者continue語句,
執行次數的絕對值:result = (x-y)÷z
但實際上沒有這么簡單:
- 如果步長為 -1或者1,那么答案只有一個
- 如果步長為 -2或者2,那么答案有兩個
- 如果步長為 -3或者3,那么答案有三個
- …
通過公式算出 x 之后,
- 如果步長為2,還要計算 (x ± 1) – z × (result-1) 的值,然后再經過瑣碎的判斷即可
- 如果步長為3,還要計算 (x ± 2) – z × (result-1) 的值,…
- …
雖然看著麻煩,但實際上是很好理解的
思考題:3~6
3. 閱讀下面的Python程序,請問程序的功能是什么?
from math import sqrt
n = 0
for m in range(101,201,2):
k = int(sqrt(m))
for i in range(2, k+2):
if m % i == 0:break
if i == k + 1:
if n % 10 == 0:print()
print('%d' % m,end = " ")
n += 1
輸出101到200之間的素數
每行輸出10個,多余換行
運行:
101 103 107 109 113 127 131 137 139 149
151 157 163 167 173 179 181 191 193 197
199
素數(質數)是指在大于1的自然數中,除了1和它本身以外不再有其他因數的自然數。
4. 閱讀下面的Python程序,請問輸出的結果使什么?
n = int(input("請輸入圖形的行數:"))
for i in range(0, n):
for j in range(0, 10 - i):print(" ", end=" ")
for k in range(0, 2 * i + 1):print(" * ", end=" ")
print("\n")
輸出的是一個金字塔
運行:
請輸入圖形的行數:4
*
* * *
* * * * *
* * * * * * *
5. 閱讀下面的Python程序,請問輸出的結果使什么?程序的功能是什么?
for i in range(100,1000):
n1 = i // 100
n2 = i // 10 % 10
n3 = i % 10
if(pow(n1, 3) + pow(n2, 3) + pow(n3, 3) == i):print(i, end=" ")
輸出三位數中所有的水仙花數
運行:
153 370 371 407
水仙花數 是指一個 3 位數,它的每個位上的數字的 3次冪之和等于它本身
6. 閱讀下面的Python程序,請問輸出的結果使什么?程序的功能是什么?
for n in range(1,1001):
total = 0; factors = []
for i in range(1, n):
if(n % i == 0):
factors.append(i)
total += i
if(total == n):print("{0} : {1}".format(n, factors))
輸出1到1000的所有完數,并輸出每個完數的所有因子
運行:
6 : [1, 2, 3]
28 : [1, 2, 4, 7, 14]
496 : [1, 2, 4, 8, 16, 31, 62, 124, 248]
完數 所有的真因子(即除了自身以外的約數)的和(即因子函數),恰好等于它本身
上機實踐:2~14
2. 編寫程序,計算1=2+3+…+100之和
- 使用for循環(遞增):
total = 0
for i in range(101):
total += i
print(total)
- 使用求和公式:
>>> (1 + 100) * 100 /2
5050.0
- 使用累計迭代器itertools.accumulate
>>> import itertools
>>> list(itertools.accumulate(range(1, 101)))[99]
5050
3. 編寫程序,計算10+9+8+…+1之和
- 使用for循環(遞增):
total = 0
for i in range(11):
total += i
print(total)
- 使用for循環(遞減):
total = 0
for i in range(10,0,-1):
total += i
print(total)
- 使用求和公式:
>>> (1 + 10) * 10 / 2
55.0
- 使用累計迭代器itertools.accumulate
>>> import itertools
>>> list(itertools.accumulate(range(1,11)))[9]
55
4. 編寫程序,計算1+3+5+7+…+99之和
- 使用for循環(遞增):
total = 0
for i in range(1,100,2):
total += i
print(total)
- 使用求和公式:
>>> (1 + 99) * 50 /2
2500.0
- 使用累計迭代器itertools.accumulate
>>> import itertools
>>> list(itertools.accumulate(range(1,100,2)))[49]
2500
5. 編寫程序,計算2+4+6+8+…+100之和
- 使用for循環(遞增):
total = 0
for i in range(2,101,2):
total += i
print(total)
- 使用求和公式:
>>> (2 + 100) * 50 / 2
2550.0
- 使用累計迭代器itertools.accumulate
>>> import itertools
>>> x = list(itertools.accumulate(range(2,101,2)))
>>> x[len(x)-1]
2550
6. 編寫程序,使用不同的實現方法輸出2000~3000的所有閏年
代碼一:
for y in range(2000,3001):
if((y % 4 == 0 and y % 100 != 0) or y % 400 == 0):
print(y,end = ' ')
代碼二(使用calendar模塊的isleap()函數來判斷):
from calendar import isleap
for y in range(2000,3001):
if(isleap(y)):print(y,end = " ")
運行:
2000 2004 2008 2012 2016 2020 2024 2028 2032 2036 2040 2044 2048 2052 2056 2060 2064 2068 2072 2076 2080 2084 2088 2092 2096 2104 2108 2112 2116 2120 2124 2128 2132 2136 2140 2144 2148 2152 2156 2160 2164 2168 2172 2176 2180 2184 2188 2192 2196 2204 2208 2212 2216 2220 2224 2228 2232 2236 2240 2244 2248 2252 2256 2260 2264 2268 2272 2276 2280 2284 2288 2292 2296 2304 2308 2312 2316 2320 2324 2328 2332 2336 2340 2344 2348 2352 2356 2360 2364 2368 2372 2376 2380 2384 2388 2392 2396 2400 2404 2408 2412 2416 2420 2424 2428 2432 2436 2440 2444 2448 2452 2456 2460 2464 2468 2472 2476 2480 2484 2488 2492 2496 2504 2508 2512 2516 2520 2524 2528 2532 2536 2540 2544 2548 2552 2556 2560 2564 2568 2572 2576 2580 2584 2588 2592 2596 2604 2608 2612 2616 2620 2624 2628 2632 2636 2640 2644 2648 2652 2656 2660 2664 2668 2672 2676 2680 2684 2688 2692 2696 2704 2708 2712 2716 2720 2724 2728 2732 2736 2740 2744 2748 2752 2756 2760 2764 2768 2772 2776 2780 2784 2788 2792 2796 2800 2804 2808 2812 2816 2820 2824 2828 2832 2836 2840 2844 2848 2852 2856 2860 2864 2868 2872 2876 2880 2884 2888 2892 2896 2904 2908 2912 2916 2920 2924 2928 2932 2936 2940 2944 2948 2952 2956 2960 2964 2968 2972 2976 2980 2984 2988 2992 2996
7. 編寫程序,計算Sn=1-3+5-7+9-11…
代碼一:
n = int(input("項數:"))
total = 0
flag = True
for i in range(1,2*n,2):
if(flag):
total += i
flag = False
else:
total -= i
flag = True
print(total)
代碼二:
n = int(input("項數:"))
total = 0
x = 2
for i in range(1,2*n,2):
total += pow(-1,x)*i
x += 1
print(total)
運行:
項數:10
-10
8. 編寫程序,計算Sn=1+1/2+1/3+…
n = int(input("項數:"))
total = 0.0
for i in range(1,n+1):
total += 1/i
print(total)
運行:
項數:10
2.9289682539682538
9. 編寫程序,打印九九乘法表。要求輸入九九乘法表的各種顯示效果(上三角,下三角,矩形塊等方式)
矩形塊:
for i in range(1,10):
s = ""
for j in range(1,10):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
下三角:
for i in range(1,10):
s = ""
for j in range(1,i+1):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
上三角:
for i in range(1,10):
s = ""
for k in range(1,i):
s += " "
for j in range(i,10):
s += str.format("%d * %d = %02d " %(i, j, i*j))
print(s)
10. 編寫程序,輸入三角形的三條邊,先判斷是否可以構成三角形,如果可以,則進一步求三角形的周長和面積,否則報錯“無法構成三角形!”
from math import sqrt
a = float(input("請輸入三角形的邊長a:"))
b = float(input("請輸入三角形的邊長b:"))
c = float(input("請輸入三角形的邊長c:"))
if(a < b): a,b = b,a
if(a < c): a,c = c,a
if(b < c): b,c = c,b
if(a < 0 or b < 0 or c < 0 or b+c <= a): print("無法構成三角形!")
else:
h = (a+b+c)/2
area = sqrt(h*(h-a)*(h-b)*(h-c))
print("周長:{0},面積:{1}".format(a+b+c,area))
運行:
請輸入三角形的邊長a:4
請輸入三角形的邊長b:3
請輸入三角形的邊長c:5
周長:12.0,面積:6.0
11. 編寫程序,輸入x,根據如下公式計算分段函數y的值。請分別用單分支語句,雙分支語句結構以及條件運算語句等方法實現
y = (x2-3x)/(x+1) + 2π + sinx (x≥0 )
y = ln(-5x) + 6√(|x|+e4) – (x+1)3 (x<0)
單分支語句:
import math
x = float(input("請輸入x:"))
if(x >= 0):
y = (x*x - 3*x)/(x+1) + 2*math.pi + math.sin(x)
if(x < 0):
y = math.log(-5*x) + 6 * math.sqrt(abs(x) + math.exp(4)) - pow(x+1,3)
print(y)
雙分支語句:
import math
x = float(input("請輸入x:"))
if(x >= 0):
y = (x*x - 3*x)/(x+1) + 2*math.pi + math.sin(x)
else:
y = math.log(-5*x) + 6 * math.sqrt(abs(x) + math.exp(4)) - pow(x+1,3)
print(y)
條件運算語句:
import math
x = float(input("請輸入x:"))
y = ((x*x - 3*x)/(x+1) + 2*math.pi + math.sin(x)) if(x >= 0) \
else (math.log(-5*x) + 6 * math.sqrt(abs(x) + math.exp(4)) - pow(x+1,3))
print(y)
運行一:
請輸入x:666
668.2715406628656
運行二:
請輸入x:-666
294079794.1744833
12. 編寫程序,輸入一元二次方程的3個系數a、b、c,求ax2+bx+c=0方程的解
import math
a = float(input("請輸入系數a:"))
b = float(input("請輸入系數b:"))
c = float(input("請輸入系數c:"))
delta = b*b -4*a*c
if(a == 0):
if(b == 0): print("無解")
else: print("有一個實根:",-1*c/b)
elif(delta == 0): print("有兩個相等實根:x1 = x2 = ", (-1*b)/(2*a))
elif(delta > 0): print("有兩個不等實根:x1 = {0},x2 = {1}".format\
((-1*b +math.sqrt(delta))/2*a,(-1*b -math.sqrt(delta))/2*a))
elif(delta < 0): print("有兩個共軛復根:x1 = {0},x2 = {1}".format\
(complex( (-1*b)/(2*a),math.sqrt(delta*-1)/(2*a)),complex( (-1*b)/(2*a),-1*math.sqrt(delta*-1)/(2*a))))
運行一:
請輸入系數a:0
請輸入系數b:0
請輸入系數c:10
無解
運行二:
請輸入系數a:0
請輸入系數b:10
請輸入系數c:5
有一個實根: -0.5
運行三:
請輸入系數a:1
請輸入系數b:8
請輸入系數c:16
有兩個相等實根:x1 = x2 = -4.0
運行四:
請輸入系數a:1
請輸入系數b:-5
請輸入系數c:6
有兩個不等實根:x1 = 3.0,x2 = 2.0
運行五:
請輸入系數a:5
請輸入系數b:2
請輸入系數c:1
有兩個共軛復根:x1 = (-0.2+0.4j),x2 = (-0.2-0.4j)
13. 編寫程序,輸入整數n(n≥0),分別利用for循環和while循環求n!
- for循環
n = int(input("請輸入n:"))
if(n == 0): total = 1
if(n > 0):
total = 1
for i in range(n,0,-1):
total *= i
print(total)
- while循環
n = int(input("請輸入n:"))
if(n == 0): total = 1
if(n > 0):
total = 1
while(n >= 1):
total *= n
n -= 1
print(total)
- 補充一個:使用累計迭代器itertools.accumulate
>>> import itertools, operator
>>> n = int(input('請輸入n:'))
請輸入n:7
>>> x = list(accumulate(range(1, n+1), operator.mul))
>>> x[len(x)-1]
5040
14. 編寫程序,產生兩個0~100(包含0和100)的隨機整數a和b,求這兩個整數的最大公約數和最小公倍數
- 現有知識點解決方法
import random
a = random.randint(0,100)
b = random.randint(0,100)
sum = a*b
print(a) #輸出原來的a,b
print(b)
if(a < b): a,b = b,a
while(a%b != 0):
a,b = b,a%b
print("最大公約數:{0},最小公倍數:{1}".format(b,sum/b))
- 補充:使用生成器(generate)函數:yield
>>> def func(a, b):
if(a < b): a,b = b,a
while(a%b != 0):
a,b = b,a%b
yield b
>>> import random
>>> if __name__ == '__main__':
a = random.randint(0,100)
b = random.randint(0,100)
sum = a*b
print(a,b)
t = list(iter(func(a, b)))
gcd = t[len(t)-1]
print("gcd = {0}, mcm = {1}".format(gcd, sum/gcd))
29 65
gcd = 1, mcm = 1885.0
- 補充:使用math模塊中的
gcd(x,y)函數
>>> import random
>>> import math
>>> if __name__ == '__main__':
a = random.randint(0,100)
b = random.randint(0,100)
sum = a*b
print(a,b)
gcd = math.gcd(a,b)
print("gcd = {0}, mcm = {1}".format(gcd, sum/gcd))
29 48
gcd = 1, mcm = 1392.0
案例研究:使用嵌套循環實現圖像處理算法
https://blog.csdn.net/Zhangguohao666/article/details/103935185
通過圖像處理算法案例,深入了解Python數據結構和基本算法流程
第四章 常用內置數據類型
幾個例題
一:Python內置數據類型概述
Python中一切皆為對象,而每個對象屬于某個數據類型
Python的數據類型包括:
- 內置的數據類型
- 模塊中定義的數據類型
- 用戶自定義的類型
四種內置的數值類型:int,float,bool,complex
- int
與其他計算機語言有精度限制不同,Python中的整數位數可以為任意長度(只受限于計算機內存)。
整型對象是不可變對象。- float
與其他計算機語言中的double和float對應
Python的浮點類型的精度和系統相關- bool
- complex
當數值字符串中包含虛部j(或J)時即復數字面量
序列數據類型:str,tuple,bytes,list,bytearray
序列數據類型表示若干有序數據.
不可變序列數據類型:
- str(字符串)
表示Unicode字符序列,例如:“zgh666”
在Python中沒有獨立的字符數據類型,字符即長度為1的字符串- tuple(元組)
表示任意數據類型的序列,例如:(“z”,“g”,“h”,6,6,6)- bytes(字節序列)
表示字節(8位)序列數據
可變序列數據類型:
- list(列表)
表示可以修改的任意類型數據的序列,比如:[‘z’,‘g’,‘h’,6,6,6]- bytearray(字節數組)
表示可以修改的字節(8位)數組
集合數據類型:set,frozenset
集合數據類型表示若干數據的集合,數據項目沒有順序,且不重復
- set(集)
例如:{1,2,3}- frozenset(不可變集)
字典數據類型:dict
字典數據類型用于表示鍵值對的字典
例如:{1:"zgh", 2:666}
NoneType,NotImplementedType,EllipsisType
- NoneType數據類型包含唯一值None,主要用于表示空值,如沒有返回值的函數的結果
- NotImplementedType數據類型包含唯一值NotImplemented,在進行數值運算和比較運算時,如果對象不支持,則可能返回該值
- EllipsisType數據類型包含唯一值Ellipsis,表示省略字符串符號
...
其他數據類型
Python中一切對象都有一個數據類型,模塊、類、對象、函數都屬于某種數據類型
Python解釋器包含內置類型,
例如:
代碼對象Code objects
框架對象Frame objects
跟蹤對象Traceback objects
切片對象Slice objects
靜態方法對象Static method objects
類方法對象Class method objects
二:整型字面量示例
Python3.7支持使用下劃線作為整數或者浮點數的千分位標記,以增強大數值的可閱讀性。
二進制、八進制、十六進制則使用下劃線區分4位標記
1_000_000_000 #輸出1000000000
0xff_ff_ff_ff #輸出4294967295
0x_FF_FF_FF_FF #輸出4294967295
三:字符串字面量示例
兩個緊鄰的字符串,如果中間只有空格分隔,則自動拼接位一個字符串
'zgh' '666' #輸出'zgh666'
'zgh' + "666" #輸出'zgh666'
四:轉義字符示例
轉義字符后跟Unicode編碼也可以表示字符
\ooo八進制Unicode碼對應的字符\xhh十六進制Unicode碼對應的字符
'1' #輸出'A'
'\x41' #輸出'A'
使用r’‘或者R’’的字符串稱為原始字符串,其中包含的任何字符都不進行轉義
s = r'換\t行\t符\n'
s #輸出:'換\\t行\\t符\\n'
print(s) #輸出:換\\t行\\t符\\n
五:字符串的格式化
一:
"student number:{0},score_average:{1}".format(2,100)
#輸出:'student number:2,score_average:100'
二:
str.format("student number:{0},score_average:{1}",2,100)
#輸出:'student number:2,score_average:100'
三(兼容Python2的格式,不推薦使用):
"student number:%4d,score_average:%2.1f" %(2,100)
#輸出:'student number: 2,score_average:100.0'
六:字符串示例,格式化輸出字符串堆積的三角形
str.center()方法用于字符串兩邊填充str.rjust()方法用于字符串右填充
print("1".center(20)) #一行20個字符,居中對齊
print(format("121","^20")) #一行20個字符,居中對齊
print("1".rjust(20,"*")) #一行20個字符,右對齊,加*
print(format("121","*>20")) #一行20個字符,右對齊,加*
運行:
1
121
*******************1
*****************121
選擇題:11
11. 關于Python字符串,下列說法錯誤的是
A. 字符即長度為1的字符串
B. 字符串以/0標識字符串的結束
C. 用戶既可以用單引號,也可以用雙引號創建字符串
D. 用三引號字符串中可以包含換行回車等特殊字符
答案:B
Python中字符串不是用\0來判斷字符串結尾,
每個字符串都存有字符串的長度,通過計數來判斷是否到達結尾。
雖然在c語言中\0就是來判斷字符串的結尾;
填空題:4、7、8、9、10、13、21
4. Python表達式3 ** 2 ** 3的值為
答案:6561
表達式中,相同優先級的運算,從右往左
7. Python語句print(pow(-3,2),round(18.67,1),round(18.67,-1))的輸出結果是
答案:9 18.7 20.0
pow()冪運算
round()四舍六入,五留雙
8. Python語句print(round(123.84,0),round(123.84,-2),floor(15.5))的輸出結果是
答案:124.0 100.0 15
補充:floor()是math模塊中的方法,向下取整
9. Python語句print(int(‘20’,16),int(‘101’,2))的輸出結果是
答案:32 5
注意:int(x,y)是指將y進制的數值x轉化為10進制數
10. Python語句print(hex(16),bin(10))的輸出結果是
答案:0x10 0b1010
hex(x)將十進制數x轉化為十六進制,以字符串形式輸出
bin(x)將十進制數x轉化為二進制,以字符串形式輸出
13. Python語句print(gcd(12,16),divmod(7,3))的輸出結果是
答案:4 (2,1)
gcd()是math模塊中的函數,求最大公約數
divmod()是內置函數,返回商和余數
21. Python語句序列 x=True;y=False;z=False;print(x or y and z) 的運行結果是
答案:True
and優先級比or高
思考題:5
5. 閱讀下面的Python程序,請問輸出結果是什么?
from decimal import *
ctx = getcontext()
ctx.prec = 2
print(Decimal('1.78'))#1.78
print(Decimal('1.78') + 0)#1.8
ctx.rounding = ROUND_UP
print(Decimal('1.65') + 0)#1.7
print(Decimal('1.62') + 0)#1.7
print(Decimal('-1.45') + 0)#-1.5
print(Decimal('-1.42') + 0)#-1.5
ctx.rounding = ROUND_HALF_UP
print(Decimal('1.65') + 0)#1.7
print(Decimal('1.62') + 0)#1.6
print(Decimal('-1.45') + 0)#-1.5
ctx.rounding = ROUND_HALF_DOWN
print(Decimal('1.65') + 0)#1.6
print(Decimal('-1.45') + 0)#-1.4
上機實踐:2~14
2. 編寫程序,格式化輸出楊輝三角
楊輝三角即二項式定理的系數表,各元素滿足如下條件:第一列及對角線上的元素均為1;其余每個元素等于它上一行同一列元素與前一列元素之和
我使用了一個更加精妙的規律
比如第一行為1
第二行:01 + 10 = 11
第三行:011 + 110 = 121
第四行:0121 + 1210 = 1331
。。。
def generate(numRows):
l1 = [1]
n = 0
while n < numRows:
print(str(l1).center(66))
l1 = [sum(t) for t in zip([0] + l1, l1 + [0])] #利用zip函數算出每一行 如第二行 zip([0,1],[1,0])=[1,1],以此類推
n += 1
a=int(input("請輸入行數"))
generate(a)
運行:
請輸入行數4
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
3. 輸入直角三角形的兩個直角邊,求三角形的周長和面積,以及兩個銳角的度數。結果保留一位小數
import math
a = float(input("請輸入直角三角形的直角邊a:"))
b = float(input("請輸入直角三角形的直角邊b:"))
c = math.sqrt(a*a+b*b)
p = a + b + c
area = 0.5*a*b
print("三角形的周長:{0:1.1f},面積:{1:1.1f}".format(p,area))
sina = a/c
sinb = b/c
a_degree = round(math.asin(sina) * 180 / math.pi,0)
b_degree = round(math.asin(sinb) * 180 / math.pi,0)
print("三角形直角邊a的度數:{0},b的度數:{1}".format(a_degree,b_degree))
運行:
請輸入直角三角形的直角邊a:3
請輸入直角三角形的直角邊b:4
三角形的周長:12.0,面積:6.0
三角形直角邊a的度數:37.0,b的度數:53.0
4. 編程產生0~100(包含0和100)的三個隨機數a、b、c,要求至少使用兩種不同的方法,將三個數按從小到大的順序排序
方法一:
import random
a = random.randint(0, 100)
b = random.randint(0, 100)
c = random.randint(0, 100)
print(str.format("原始值:{0},{1},{2}", a, b, c))
if(a > b): a,b = b,a
if(a > c): a,c = c,a
if(b > c): b,c = c,b
print(str.format("增序:{0},{1},{2}", a, b, c))
方法二(使用內置函數max、min、sum):
import random
a = random.randint(0, 100)
b = random.randint(0, 100)
c = random.randint(0, 100)
print(str.format("原始值:{0},{1},{2}", a, b, c))
maxx = max(a, b, c)
minx = min(a, b, c)
median = sum([a, b, c]) - minx - maxx
print(str.format("增序:{0},{1},{2}", minx, median, maxx))
方法三(使用內置函數sorted):
>>> import random
>>> a = random.randint(0,100)
>>> b = random.randint(0,100)
>>> c = random.randint(0,100)
>>> print("init value: {0} , {1} , {2}".format(a,b,c))
init value: 17 , 6 , 59
>>> sorted([a,b,c])
[6, 17, 59]
5. 編程計算有固定工資收入的黨員每月所繳納的黨費。
工資基數3000元及以下者,交納工資基數的0.5%
工資基數3000~5000元者,交納工資基數的1%
工資基數在5000~10000元者,交納工資基數的1.5%
工資基數超過10000元者,交納工資基數的2%
salary = float(input("請輸入有固定工資收入的黨員的月工資:"))
if salary <= 3000: dues = salary*0.005
elif salary <= 5000: dues = salary*0.01
elif salary <= 10000: dues = salary*0.15
else: dues = salary*0.02
print("交納黨費:",dues)
運行:
請輸入有固定工資收入的黨員的月工資:10001
交納黨費: 200.02
6. 編程實現袖珍計算器,要求輸入兩個操作數和一個操作符(+、-、*、/、%),根據操作符輸出運算結果。注意/和%運算符的零異常問題
a = float(input("請輸入操作數(左):"))
b = float(input("請輸入操作數(右):"))
operator = input("請輸入操作符(+、-、*、/、%):")
if(b == 0 and (operator == '/' or operator == '%')):
print("分母為零,異常!")
else:
if operator == '+': result = a+b
elif operator == '-': result = a-b
elif operator == '*': result = a*b
elif operator == '/': result = a/b
elif operator == '%': result = a%b
print("{0} {1} {2}= {3}:".format(a,operator,b,result))
運行:
請輸入操作數(左):10
請輸入操作數(右):5
請輸入操作符(+、-、*、/、%):+
10.0 + 5.0= 15.0:
7. 輸入三角形的3條邊a、b、c,判斷此3邊是否可以構成三角形。若能,進一步判斷三角形的性質,即為等邊、等腰、直角或其他三角形
a = float(input("請輸入三角形的邊a:"))
b = float(input("請輸入三角形的邊b:"))
c = float(input("請輸入三角形的邊c:"))
if(a > b): a,b = b,a
if(a > c): a,c = c,a
if(b > c): b,c = c,b
result = "三角形"
if(not(a>0 and b>0 and c>0 and a+b>c)):
result = '此三邊無法構成三角形'
else:
if a == b == c: result = '等邊三角形'
elif(a==b or a==c or b==c): result = '等腰三角形'
elif(a*a+b*b == c*c): result = '直角三角形'
print(result)
運行:
請輸入三角形的邊a:3
請輸入三角形的邊b:4
請輸入三角形的邊c:5
直角三角形
8. 編程實現雞兔同籠問題
已知在同一個籠子里共有h只雞和兔,雞和兔的總腳數為f,其中h和f由用戶輸入,求雞和兔各有多少只?要求使用兩種方法:一是求解方程;二是利用循環進行枚舉測試
h = int(input("請輸入總頭數:"))
f = int(input("請輸入總腳數:"))
def fun1(h,f):
rabbits = f/2-h
chicken = h-rabbits
if(chicken < 0 or rabbits < 0): return '無解'
return chicken,rabbits
def fun2(h,f):
for i in range(0,h+1):
if(2*i + 4*(h-i) == f):return i,h-i
return '無解'
if(h>0 and f>0 and f % 2 == 0):
if fun1(h,f)=='無解':
print("無解")
else:
print("方法一:雞:{0},兔:{1}".format(fun1(h,f)[0],fun1(h,f)[1]))
print("方法二:雞:{0},兔:{1}".format(fun2(h,f)[0],fun2(h,f)[1]))
else:
print('輸入的數據無意義')
運行:
請輸入總頭數:100
請輸入總腳數:100
無解
9. 輸入任意實數x,計算ex的近似值,直到最后一項的絕對值小于10-6為止
ex = 1 + x + x2/2 + x3/3! + x4/4! + … + xn/n!
x = int(input("請輸入任意實數:"))
e = 1
i = 1
t = 1
a = 1
while(a >= 10e-6):
t *= i
a = pow(x,i)/t
e += a
i += 1
print(e)
運行:
請輸入任意實數:1
2.7182815255731922
我發現了在Python中10e-6和pow(10,-6)是有差別的,將上述代碼中的10e-6改為pow(10,-6),輸出結果會有細微的差別
運行:
請輸入任意實數:1
2.7182818011463845
10. 輸入任意實數a(a>=0),用迭代法求x=√a,要求計算的相對偏差小于10-6
求平方根的公式:
Xn+1 = 0.5(Xn + a/Xn)
import math
a = int(input("請輸入任意實數a(>=0):"))
x = a / 2
y = (x + a/x) / 2
while(abs(y-x) >= pow(10,-6)):
x = y
y = (x + a/x) / 2
print(y)
運行:
請輸入任意實數a(>=0):2
1.414213562373095
11. 即有一個數,用3除余2,用5除余3,用7除余2,請問0~1000中這樣的數有哪些?
我國古代有位大將,名叫韓信。他每次集合部隊,只要求部下先后按1-3,1-5,1-7報數,然后再報告一下各隊每次報數的余數,他就知道到了多少人。他的這種巧妙算法被人們稱作“鬼谷算”,也叫“隔墻算”,或稱為“韓信點兵”,外國人還稱它為“中國余數定理”。
for i in range(0,1001):
if((i % 3 == 2 )and (i % 5 == 3) and (i % 7 == 2)): print(i, end=" ")
運行:
23 128 233 338 443 548 653 758 863 968
12. 一球從100米的高度自由下落,每次落地后反彈回原高度的一半,再落下。求小球在第10次落地時共經過多少米?第10次反彈多高
規律:
第一次下落時的高度:100
第二次下落時的高度(第一次反彈的高度):50
第三次下落時的高度(第二次反彈的高度):25
…
n = 10
h_down = 100
h_up = 0
sum = 0
for i in range(1,n+1):
sum += h_down+h_up
h_down = h_up = h_down/2
print("小球在第十次落地時共經過:{0}米,第十次反彈高度:{1}米".format(sum,h_up))
運行:
小球在第十次落地時共經過:299.609375米,第十次反彈高度:0.09765625米
13. 猴子吃桃問題
猴子第一天摘下若干個桃子,當天吃掉一半多一個;第二天接著吃了剩下的桃子的一半多一個;以后每天都吃了前一天剩下的桃子的一半多一個。到第八天發現只剩一個桃子了。請問猴子第一天共摘了多少個桃子?
這是一個遞推問題
某天所剩桃子數x
后一天所剩桃子數y = x – (x/2+1) = x/2-1
則x = 2(y+1)
result = 1
for i in range(8,0,-1):
print("第{0}天桃子數:{1}".format(i,result))
result = 2*(result+1)
運行:
第8天桃子數:1
第7天桃子數:4
第6天桃子數:10
第5天桃子數:22
第4天桃子數:46
第3天桃子數:94
第2天桃子數:190
第1天桃子數:382
14. 計算Sn = 1+11+111+…+111…111(最后一項是n個1)。n是一個隨機產生的1~10(包括1和10)中的正整數
import random
n = random.randint(1,10)
x = 1
s = 0
for i in range(1,n+1):
s += x
x = 10*x+1
print("n = {0},sn = {1}".format(n,s))
運行:
n = 6,sn = 123456
random.randint(a, b)
- 生成指定范圍內的整數
- 范圍:[a, b]
案例研究:科學計算和數據分析
https://blog.csdn.net/Zhangguohao666/article/details/103941448
通過Python科學計算和數據分析庫的安裝和基本使用,了解使用Python進行科學計算的基本方法
第五章 序列數據類型
幾個例題
一:Python中內置的序列數據類型
- 元組也稱為定值表,用于存儲固定不變的表
- 列表也稱為表,用于存儲其值可變的表
- 字符串是包括若干字符的序列數據,支持序列數據的基本操作
- 字節序列數據是包括若干字節的序列。Python抓取網頁時返回的頁面通常為utf-8編碼的字節序列。
字節序列和字符串可以直接相互轉換(字節編碼和解碼):
>>> s1 = b'abc'
>>> s1
b'abc'
>>> s1.decode("utf-8")
abc
>>> s2 = "中國"
>>> s2.encode("utf-8")
b'\xe4\xb8\xad\xe5\x9b\xbd'
二:序列的切片操作示例
>>> s = 'zgh666'
>>> s[0]
'z'
>>> s[2]
'h'
>>> s[:3]
'zgh'
>>> s[1:3]
'gh'
>>> s[3:6]
'666'
>>> s[3:55]
'666'
>>> s[::-1]
'666hgz'
>>> s[3:2]
''
>>> s[:]
'zgh666'
>>> s[::2]
'zh6'
三:序列的連接和重復操作
- 通過連接操作符
+可以連接兩個序列,形成一個新的序列對象- 通過重復操作符
*可以重復一個序列n次- 連接操作符和重復操作符也支持復合賦值運算,即:
+=,*=
>>> x = 'zgh'
>>> y = '666'
>>> x + y
'zgh666'
>>> x *2
'zghzgh'
>>> x += y
>>> x
'zgh666'
>>> y *= 3
>>> y
'666666666'
四:序列的成員關系操作
- in
- not in
- s.count(x)
x在s中出現的次數 - s.index(x)
x在s中第一次出現的下標
>>> s = "zgh666"
>>> 'z' in s
True
>>> 'g' not in s
False
>>> s.count('6')
3
>>> s.index('6')
3
五:序列的排序操作
sorted(iterable,key=None,reverse=False)
>>> sorted(s)
[1, 3, 5, 9]
>>> sorted(s,reverse=True)
[9, 5, 3, 1]
>>> s = 'zGhZgH'
>>> sorted(s)
['G', 'H', 'Z', 'g', 'h', 'z']
>>> sorted(s,key=str.lower)
['G', 'g', 'h', 'H', 'z', 'Z']
>>> sorted(s,key=str.lower,reverse=True)
['z', 'Z', 'h', 'H', 'G', 'g']
六:序列的拆分
- 變量個數與序列長度相等
若變量個數與序列的元素個數不一致,將導致ValueError
>>> data = (118,'zgh',(100,100,100))
>>> sid,name,(chinese,english,math) = data
>>> sid
118
>>> name
'zgh'
>>> chinese
100
>>> english
100
>>> math
100
- 變量個數與序列長度不等
如果序列長度未知,可以使用*元組變量,將多個值作為元組賦值給元組變量。在一個賦值語句中,*元組變量只允許出現一次,否則將導致SyntaxError
>>> first,second,third,*middles,last = range(10)
>>> first
0
>>> second
1
>>> third
2
>>> middles
[3, 4, 5, 6, 7, 8]
>>> last
9
>>> first,*middles,last = sorted([58,60,60,100,70,70])
>>> sum(middles)/len(middles)
65.0
- 使用臨時變量
_
如果只需要部分數據,序列的其它位置可以使用臨時變量_
>>> record = ['zgh','858990471@qq.com','17354364147','15272502101']
>>> name,_,*phone = record
>>> name
'zgh'
>>> phone
['17354364147', '15272502101']
七:使用元組字面量,tuple創建元組實例對象的實例
>>> t1 = 1,2,3
>>> t1
(1, 2, 3)
>>> t2 = (4,5,6)
>>> t2
(4, 5, 6)
>>> t3 = (9,)
>>> t3
(9,)
如果元組中只有一個項目,后面的逗號不能省略。
Python解釋器把(1)解釋為整數1,將(1,)解釋為元組
>>> t1 = tuple()
>>> t1
()
>>> t2 = tuple("zgh666")
>>> t2
('z', 'g', 'h', '6', '6', '6')
>>> t3 = tuple(['z','g','h'])
>>> t3
('z', 'g', 'h')
八:使用列表字面量,list創建列表實例對象的實例
>>> l1 = []
>>> l1
[]
>>> l2 = ['zgh666']
>>> l2
['zgh666']
>>> l3 = [(1,2,3)]
>>> l3
[(1, 2, 3)]
>>> l1 = list()
>>> l1
[]
>>> l2 = list(b'zgh666')
>>> l2
[122, 103, 104, 54, 54, 54]
>>> l3 = list(b'aAbBcC')
>>> l3
[97, 65, 98, 66, 99, 67]
補充:列表是可變對象,故用戶可以改變列表對象中元素的值,也可以通過del刪除某元素
九:列表解析表達式示例
使用列表解析表達式可以簡單,高效地處理一個可迭代對象,并生成結果列表
>>> [(i,i**2) for i in range(10)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64), (9, 81)]
>>> [i for i in range(10) if i%2==0]
[0, 2, 4, 6, 8]
>>> [(x,y,x*y) for x in range(1,4) for y in range(1,4) if x>=y]
[(1, 1, 1), (2, 1, 2), (2, 2, 4), (3, 1, 3), (3, 2, 6), (3, 3, 9)]
選擇題:4、5、7、11、12
4. Python語句序列“a = (1,2,3,None,(),[]);print(len(a))”的運行結果是
>>> a = (1,2,3,None,(),[])
>>> len(a)
6
5. Python語句序列“nums = set([1,2,2,3,3,3,4]);print(len(nums))”的運行結果是
>>> nums = set([1,2,2,3,3,3,4])
>>> nums
{
1, 2, 3, 4}
>>> len(nums)
4
7. Python語句序列“s1=[4,5,6];s2=s1;s1[1]=0;print(s2)”的運行結果是
Python中變量(如s1,s2)存儲在棧中,存放的是地址
[4,5,6]存儲在堆中
s1 = [4,5,6]即s1存儲指向堆中[4,5,6]的地址
s2 = s1地址賦值,即s2和s1都指向同一個地址
所以對列表進行修改,兩者的顯示都會發生變化
>>> s1 = [4,5,6]
>>> s2 = s1
>>> s1[1] = 0
>>> s1
[4, 0, 6]
>>> s2
[4, 0, 6]
11. Python語句序列“s={‘a’,1,‘b’,2};print(s[‘b’])”的運行結果是
| A. 語法錯 | B. ‘b’ | C. 1 | D. 2 |
|---|
答案:A
通過值訪問集合是沒有意義的,語法也不支持
>>> s ={
'a',1,'b',2}
>>> print(s['b'])
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
print(s['b'])
TypeError: 'set' object is not subscriptable
補充:集合set是無序不重復的,是無法通過下標訪問的
12. Python語句print(r”\nGood”)的運行結果是
| A. 新行和字符串Good | B. r”\nGood” | C. \nGood | D. 字符r、新行和字符串Good |
|---|
答案:C
>>> print(r"\nGood")
\nGood
r""聲明原始字符串
填空題:1、5、6、12、13、14
1. Python語句序列“fruits = [‘apple’,‘banana’,‘bear’];print(fruits[-1][-1])”的運行結果是
注意:fruit[-1]是字符串’bear’
所以:fruit[-1][-1]即'bear[-1]'
>>> fruits = ['apple','banana','pear']
>>> fruits[-1]
'pear'
>>> fruits[-1][-1]
'r'
5. Python語句 print(’%d%%%d’%(3/2,3%2)) 的運行結果是
>>> print('%d%%%d'%(3/2,3%2))
1%1
6. Python語句序列“s = [1,2,3,4];s.append([5,6]);print(len(s))”的運行結果是
答案:5
注意append()和extend()函數的區別
s.append(x)將對象x追加到s尾部
s.extend(x)將序列x追加到s尾部
append
>>> s = [1,2,3,4]
>>> s.append([5,6])
>>> s
[1, 2, 3, 4, [5, 6]]
>>> len(s)
5
extend
>>> s = [1,2,3,4]
>>> s.extend([5,6])
>>> s
[1, 2, 3, 4, 5, 6]
>>> len(s)
6
12
>>> s =('a','b','c','d','e')
>>> s[2]
'c'
>>> s[2:3]
('c',)
>>> s[2:4]
('c', 'd')
>>> s[1::2]
('b', 'd')
>>> s[-2]
'd'
>>> s[::-1]
('e', 'd', 'c', 'b', 'a')
>>> s[-2:-1]
('d',)
>>> s[-99:-5]
()
>>> s[-99:-3]
('a', 'b')
>>> s[::]
('a', 'b', 'c', 'd', 'e')
>>> s[1:-1]
('b', 'c', 'd')
13
>>> s = [1,2,3,4,5,6]
>>> s[:1] = []
>>> s
[2, 3, 4, 5, 6]
>>> s[:2] = 'a'
>>> s
['a', 4, 5, 6]
>>> s[2:] = 'b'
>>> s
['a', 4, 'b']
>>> s[2:3] = ['x','y']
>>> s
['a', 4, 'x', 'y']
>>> del s[:1]
>>> s
[4, 'x', 'y']
14
>>> s = ['a','b']
>>> s.append([1,2])
>>> s
['a', 'b', [1, 2]]
>>> s.extend('34')
>>> s
['a', 'b', [1, 2], '3', '4']
>>> s.extend([5,6])
>>> s
['a', 'b', [1, 2], '3', '4', 5, 6]
>>> s.insert(1,7)
>>> s
['a', 7, 'b', [1, 2], '3', '4', 5, 6]
>>> s.insert(10,8)
>>> s
['a', 7, 'b', [1, 2], '3', '4', 5, 6, 8]
>>> s
['a', 7, 'b', [1, 2], '3', '4', 5, 6]
>>> s.remove('b')
>>> s
['a', 7, [1, 2], '3', '4', 5, 6]
>>> s[3:] =[]
>>> s
['a', 7, [1, 2]]
>>> s.reverse()
>>> s
[[1, 2], 7, 'a']
>>>
思考題:2、3、5
2. 閱讀下面的Python語句,請問輸出結果是什么?
n = int(input('請輸入圖形的行數:'))
for i in range(n,0,-1):
print(" ".rjust(20-i),end=' ')
for j in range(2*i-1):print(" * ",end=' ')
print('\n')
for i in range(1,n):
print(" ".rjust(19-i),end=' ')
for j in range(2*i+1):print(" * ",end=' ')
print('\n')
運行一:
請輸入圖形的行數:1
*
運行二:
請輸入圖形的行數:2
* * *
*
* * *
運行三:
請輸入圖形的行數:3
* * * * *
* * *
*
* * *
* * * * *
3. 閱讀下面的Python語句,請問輸出結果是什么?
n = int(input('請輸入上(或下)三角行數:'))
for i in range(0,n):
print(" ".rjust(19-i),end=' ')
for j in range(2*i+1):print(" * ",end=' ')
print('\n')
for i in range(n-1,0,-1):
print(" ".rjust(20-i),end=' ')
for j in range(2*i-1):print(" * ",end=' ')
print('\n')
運行:
請輸入上(或下)三角行數:4
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
5. 閱讀下面的Python語句,請問輸出結果是什么?
先看這三句:
>>> names1 = ['Amy','Bob','Charlie','Daling']
>>> names2 = names1
>>> names3 = names1[:]
毫無疑問,此時names1,names2,names3的值都是[‘Amy’,‘Bob’,‘Charlie’,‘Daling’]
但是
>>> id(names1)
2338529391368
>>> id(names2)
2338529391368
>>> id(names3)
2338529391560
names1和names2指向同一個地址
而names3指向另一個地址
然后:
>>> names2[0] = 'Alice'
>>> names3[1] = 'Ben'
>>> names1
['Alice', 'Bob', 'Charlie', 'Daling']
>>> names2
['Alice', 'Bob', 'Charlie', 'Daling']
>>> names3
['Amy', 'Ben', 'Charlie', 'Daling']
最后:
>>> sum = 0
>>> for ls in(names1,names2,names3):
if ls[0] == 'Alice': sum+=1
if ls[1] == 'Ben':sum+=2
>>> print(sum)
4
上機實踐:2~6
2. 統計所輸入字符串中單詞的個數,單詞之間用空格分隔
s = input("請輸入字符串:")
num = 0
for i in s:
if((i >= 'a' and i <= 'z') or (i >= 'A' and i <= 'Z')):
num += 1
print("其中的單詞總數:",num)
運行:
請輸入字符串:zgh666 ZGH6
其中的單詞總數: 6
3. 編寫程序,刪除一個list里面重復元素
方法一:利用set集合不重復的性質(但結果不能保證原來的順序)
l = [1,2,2,3,3,3,4,5,6,6,6]
s = set(l)
l = list(s)
print(l)
運行:
[1, 2, 3, 4, 5, 6]
方法二:既可以去除重復項,又可以保證原來的順序
def unique(items):
items_existed = set()
for item in items:
if item not in items_existed:
yield item
items_existed.add(item)
if __name__ == '__main__':
a = [1, 8, 5, 1, 9, 2, 1, 10]
a1 = unique(a)
print(list(a1))
運行結果:
[1, 8, 5, 9, 2, 10]
對代碼的分析:
- 可以看出,
unique()函數返回的并不是items_existed,而是利用了yield
在函數定義中,如果使用yield語句代替return返回一個值,則定義了一個生成器函數(generator)
生成器函數是一個迭代器,是可迭代對象,支持迭代
a1 = unique(a)這個函數返回的實際上是一個可迭代對象
若print(a1)得到的會是:<generator object unique at 0x0000016E23AF4F48>- 所以,要得到去掉重復后的列表的樣子,需要將可迭代對象a1放在
list()中
運行:
4. 編寫程序,求列表[9,7,8,3,2,1,55,6]中的元素個數、最大值、最小值,以及元素之和、平均值。請思考有幾種實現方法?
內置函數:
s = [9,7,8,3,2,1,55,6]
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(len(s),max(s),min(s),sum(s),sum(s)/len(s)))
直接訪問元素列表(for i in s…):
s = [9,7,8,3,2,1,55,6]
sum = 0
max = s[0]
min = s[0]
length = 0
for i in s:
sum += i
length += 1
if(i > max): max = i
if(i < min): min = i
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(length,max,min,sum,sum/length))
間接訪問列表元素(for i in range(0,len(s))…):
s = [9,7,8,3,2,1,55,6]
sum = 0
max = s[0]
min = s[0]
length = len(s)
for i in range(0,length):
sum += s[i]
if(s[i] > max): max = s[i]
if(s[i] < min): min = s[i]
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(length,max,min,sum,sum/length))
正序訪問(i=0;while i<len(s)…):
s = [9,7,8,3,2,1,55,6]
sum = 0
max = s[0]
min = s[0]
length = len(s)
i = 0
while(i < length):
sum += s[i]
if(s[i] > max): max = s[i]
if(s[i] < min): min = s[i]
i += 1
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(length,max,min,sum,sum/length))
反序訪問(i=len(s)-1;while i>=0…):
s = [9,7,8,3,2,1,55,6]
sum = 0
max = s[0]
min = s[0]
length = len(s)
i = length-1
while(i >= 0):
sum += s[i]
if(s[i] > max): max = s[i]
if(s[i] < min): min = s[i]
i -= 1
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(length,max,min,sum,sum/length))
while True:…break
s = [9,7,8,3,2,1,55,6]
sum = 0
max = s[0]
min = s[0]
length = len(s)
i = 0
while(True):
if(i > length-1): break
sum += s[i]
if(s[i] > max): max = s[i]
if(s[i] < min): min = s[i]
i += 1
print("元素個數:{0},最大值:{1},最小值:{2},和:{3},平均值:{4}".\
format(length,max,min,sum,sum/length))
運行:
元素個數:8,最大值:55,最小值:1,和:91,平均值:11.375
5. 編寫程序,將列表[9,7,8,3,2,1,5,6]中的偶數變成它的平方,奇數保持不變
l = [9,7,8,3,2,1,5,6]
for i,value in enumerate(l):
if(value % 2 == 0):l[i] = value**2
print(l)
運行:
[9, 7, 64, 3, 4, 1, 5, 36]
6. 編寫程序,輸入字符串,將其每個字符的ASCII碼形成列表并輸出
s = input("請輸入一個字符串:")
l = list()
for i in s:
l.append(ord(i))
print(l)
運行:
請輸入一個字符串:zgh666
[122, 103, 104, 54, 54, 54]
案例研究:猜單詞游戲
https://blog.csdn.net/Zhangguohao666/article/details/103948234
通過猜單詞游戲的設計和實現,幫助讀者了解使用Python系列數據類型和控制流程
第六章 輸入和輸出
幾個例題
一:運行時提示輸入密碼
輸入密碼時,一般需要不明顯,則可以使用模塊getpass,以保證用戶輸入的密碼在控制臺中不回顯
import getpass
username = input("user:")
password = getpass.getpass("password:")
if(username == 'zgh' and password == '666'):
print('logined!')
else:
print('failed!')
input()#為了看到輸出結果。因為執行完畢后,控制臺會立馬關閉
注意:上面這個代碼,如果使用IDLE執行,會因為安全問題而執行失敗
但是,在控制臺中執行就沒問題,看輸出結果(可以看到,輸入的密碼不會顯示出來):
user:zgh
password:
logined!
二:重定向標準輸出到一個文件的示例
這種重定向由控制臺完成,而與Python本身無關。
格式:
程序 > 輸出文件
其目的是將顯示屏從標準輸出中分離,并將輸出文件與標準輸出關聯,即程序的執行結果將寫入輸出文件,而不是發送到顯示屏中顯示
首先準備一個test.py文件(代碼如下)
import sys,random
n = int(sys.argv[1])
for i in range(n):
print(random.randrange(0,100))
然后在PowerShell中:python test.py 100 > scores.txt
記住,切記,一定要注意:千萬能省略python,這樣寫./test.py 100 > scores.txt會出現問題,生成的scores文件中會沒有任何內容!?。。ㄔ蛭粗?/p>
然后在當前目錄下,100個[0,100)范圍內的的整數生成在scores.txt文件中了
三:重定向文件到標準輸入
格式:
程序 < 輸入文件
其目的是將控制臺鍵盤從標準輸入中分離,并將輸入文件與標準輸入關聯,即程序從輸入文件中讀取輸入數據,而不是從鍵盤中讀取輸入數據
準備一個average.py文件(代碼如下)
import sys
total =0.0
count = 0
for line in sys.stdin:
count += 1
total += float(line)
avg = total/count
print("average:",avg)
然后問題總是不期而至,
在PowerShell中:python average.py < scores.txt,會報錯,PowerShell會提示你:“<”運算符是為將來使用而保留的。
很無奈,我只能使用cmd了,然后得出結果
四:管道
格式:
程序1 | 程序2 | 程序3 | … | 程序4
其目的是將程序1的標準輸出連接到程序2的標準輸入,
將程序2的標準輸出連接到程序3的標準輸入,以此類推
例如:
打開cmd,輸入python test.py 100 | average.py,其執行結果等同于上面兩個例子中的命令
使用管道更加簡潔,且不用創建中間文件,從而消除了輸入流和輸出流可以處理的數據大小的限制,執行效率更高
五:過濾器
-
使用操作系統實用程序more逐屏顯示數據
-
使用操作系統實用程序sort排序輸出數據
more和sort都可以在一個語句中使用
填空題:1、2
print(value, ..., sep = ' ', end = '\n', file = sys.stdout, flush = False)
- sep(分隔符,默認為空格)
- end(換行符,即輸入的末尾是個啥)
- file(寫入到指定文件流,默認為控制臺sys.stdout)
- flush(指定是否強制寫入到流)
1
>>> print(1,2,3,4,5,sep='-',end='!')
1-2-3-4-5!
2
>>> for i in range(10):
print(i,end=' ')
0 1 2 3 4 5 6 7 8 9
例題及上機實踐:2~5
2. 嘗試修改例6.2編寫的命令行參數解析的程序,解析命令行參數所輸入邊長的值,計算并輸出正方形的周長和面積
argparse模塊用于解析命名的命令行參數,生成幫助信息的Python標準模塊
例6.2:解析命令行參數所輸入的長和寬的值,計算并輸出長方形的面積
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--length', default = 10, type = int, help = '長度')
parser.add_argument('--width', default = 5, type = int, help = '寬度')
args = parser.parse_args()
area = args.length * args.width
print('面積 = ', area)
input()#加這一句是為了可以看到輸出結果
輸出:面積 = 50
如果在執行這個模塊時,加入兩個命令行參數
輸出:面積 = 36
基本上看了上面這個例子后,就可以理解argparse的用法了
本題代碼:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--length', default = 10, type = int, help = '長度')
args = parser.parse_args()
area = args.length ** 2
perimeter = 4 * args.length
print('面積 = {0},周長 = {1}'.format(area,perimeter))
input()#加這一句是為了可以看到輸出結果
在PowerShell中輸入.\test.py
不給命令行參數,輸出是以默認值來計算的
輸出:面積 = 100,周長 = 40
給命令行參數:.\test.py --length 1
輸出:面積 = 1,周長 = 4
3. 嘗試修改例6.8編寫讀取并輸出文本文件的程序,由命令行第一個參數確認所需輸出的文本文件名
f = open(file, mode = 'r' , buffering = -1, encoding = None)
- file是要打開或創建的文件名,如果文件不在當前路徑,需指出具體路徑
- mode是打開文件的模式,模式有:
‘r’(只讀)
‘w’(寫入,寫入前刪除就內容)
‘x’(創建新文件,如果文件存在,則導致FileExistsError)
‘a’(追加)
‘b’(二進制文件)
‘t’(文本文件,默認值)
‘+’(更新,讀寫)- buffering表示是否使用緩存(緩存為-1,表示使用系統默認的緩沖區大小)
- encoding是文件的編碼
例6.8:讀取并輸出文本文件
import sys
filename = sys.argv[0]#就讀取本文件,騷的呀皮
f = open(filename, 'r', encoding = 'utf-8')
line_no = 0
while True:
line_no += 1
line = f.readline()
if line:
print(line_no, ":", line)
else:
break
f.close()
輸出(代碼輸出的就是本python文件):
1 : import sys
2 :
3 : filename = sys.argv[0]#就讀取本文件,騷的呀皮
4 : f = open(filename, 'r', encoding = 'utf-8')
5 :
6 : line_no = 0
7 : while True:
8 : line_no += 1
9 : line = f.readline()
10 : if line:
11 : print(line_no, ":", line)
12 : else:
13 : break
14 : f.close()
15 :
本題代碼:
對例題代碼進行些許修改就可以了,首先將上例中的第二個語句改為:filename = sys.argv[0],再考慮下面怎么進行
準備一個用來測試的文件test.txt:
對于這個文件要注意一點(你們很可能回出現這個問題?。。?/strong>),win10默認創建的文本文件的字符編碼是ANSI
代碼怎么寫,有兩種:
- 將test.txt文本文件的編碼修改為utf-8,代碼如上所說
記事本方式打開test.txt文件,點擊文件,點擊另存為,看到下方的編碼(修改為utf-8) - test.txt就用默認的ANSI編碼方式,再將上例代碼的第三個語句修改為
f = open(filename, 'r', encoding = 'ANSI')
在PowerShell中輸入:./test.py test.txt
輸出:
1 : ?大家好
2 : 我是Zhangguohao666
3 : 如果本文章對大家有幫助,請點贊支持一下
4 : 還有:
5 : 如果發現了什么問題,請在評論區指出,我會積極改進
4. 嘗試修改例6.9編寫利用with語句讀取并輸出文本文件的程序,由命令行第一個參數確認所需輸出的文本文件名
為了簡化操作,Python語言中與資源相關的對象可以實現上下文管理協議,可以使用with語句,確保釋放資源。
with open(file,mode) as f:
例6.9:利用with語句讀取并輸出文本文件
import sys
filename = sys.argv[0]
line_no = 0
with open(filename, 'r', encoding = 'utf-8') as f:
for line in f:
line_no += 1
print(line_no, ":", line)
f.close()
基本上,看這個例子,就可以上手with語句了
本題代碼:
還是上一題準備的文本文件,
代碼一(文本文件的編碼為默認的ANSI):
import sys
filename = sys.argv[1]
line_no = 0
with open(filename, 'r', encoding = 'ANSI') as f:
for line in f:
line_no += 1
print(line_no, ":", line)
f.close()
代碼二(將文本文件的編碼修改為utf-8):
import sys
filename = sys.argv[1]
line_no = 0
with open(filename, 'r', encoding = 'utf-8') as f:
for line in f:
line_no += 1
print(line_no, ":", line)
f.close()
本題的輸出,我再不要臉的放一次吧:
1 : ?大家好
2 : 我是Zhangguohao666
3 : 如果本文章對大家有幫助,請點贊支持一下
4 : 還有:
5 : 如果發現了什么問題,請在評論區指出,我會積極改進
5. 嘗試修改例6.12編寫標準輸出流重定向的程序,從命令行第一個參數中獲取n的值,然后將0-n,0-n的2倍值,2的0-n次冪的列表打印輸出到out.log文件中
例6.12:從命令行第一個參數中獲取n的值,然后將0-n,2的0-n次冪的列表打印輸出到out.log文件中
- 標準輸入流文件對象:sys.stdin,
默認值為sys.__stdin__- 標準輸出流文件對象:sys.stdout,
默認值為sys.__stdout__- 錯誤輸出流文件對象(標準錯誤流文件對象):sys.stderr
默認值為sys.__stderr__
書中給的代碼是這樣的:
import sys
n = int(sys.argv[1])
power = 1
i = 0
f = open('out.log', 'w')
sys.stdout = f
while i <= n:
print(str(i), ' ', str(power))
power = 2*power
i += 1
sys.stdout = sys.__stdout__
如果使用的編輯器是PyCharm(現在大多數編輯器會幫你對代碼進行優化和處理一些隱患),運行書中的這個代碼沒有問題。
但是:
若使用的編輯器是python自帶的IDLE,運行這個代碼有問題!
第一:out.log文件會生成,但是沒有東西
(發現文件關閉不了(就是×不掉),
確定是文件沒關閉(f.close())的原因)
第二:控制臺沒有輸出’done’語句(估計是IDLE編輯器處理不了__stdout__這個值)
經過研究后,發現(基于IDLE編輯器):
如果在上面的代碼中加入f.close()后,該輸入的東西都成功輸入進out.log文件了,
但是,
還有一個問題
控制臺依舊沒有輸出’done’語句
經過一步步的斷點調試(就是手動寫print)
發現sys.stdout = sys.__stdout__不會執行
然后進行改動后,就可以了,代碼如下:
(既然__stdout__不好使,就使用中間變量)
import sys
n = int(sys.argv[1])
power = 1
i = 0
output = sys.stdout
f = open('out.log', 'w')
sys.stdout = f
while i <= n:
print(str(i), ' ', str(power))
power = 2*power
i += 1
f.close()
sys.stdout = output
print('done!')#這一句是用來檢測上面的代碼是否成功執行
問題雖然解決,但是原因沒有徹底弄清楚,求助。。。。。。
本題代碼:
import sys
n = int(sys.argv[1])
power = 1
i = 0
output = sys.stdout
f = open('out.log', 'w')
sys.stdout = f
while i <= n:
print(str(i), ' ', str(2*i), ' ', str(power))
power = 2*power
i += 1
f.close()
sys.stdout = output
print('done!')#這一句是用來檢測上面的代碼是否成功執行
比如時輸入的命令行參數是6
輸出:
案例研究:21點撲克牌游戲
https://blog.csdn.net/Zhangguohao666/article/details/103948545
通過21點撲克牌游戲的設計和實現,了解使用Python數據類型、控制流程和輸入輸出
第七章 錯誤和異常處理
Python語言采用結構化的異常處理機制捕獲和處理異常
而我感覺,Python在這方面的知識點其實和Java的差不多
幾個例題
一:程序的錯誤和異常處理
- 語法錯誤
指源代碼中的拼寫錯誤,這些錯誤導致Python編譯器無法把Python源代碼轉換為字節碼,故也稱之為編譯錯誤
- 運行時錯誤
在解釋執行過程中產生的錯誤
例如:
- 程序中沒有導入相關的模塊,NameError
- 程序中包括零除運算,ZeroDivisionError
- 程序中試圖打開不存在的文件,FileNotFoundError
- 邏輯錯誤
程序可以執行(程序運行本身不報錯),但執行結果不正確。
對于邏輯錯誤,Python解釋器無能為力,需要用戶根據結果來調試判斷
大部分由程序錯誤而產生的錯誤和異常一般由Python虛擬機自動拋出。另外,在程序中如果判斷某種錯誤情況,可以創建相應的異常類的對象,并通過raise語句拋出
>>> a = -1
>>> if(a < 0): raise ValueError("數值不能為負數")
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
if(a < 0): raise ValueError("數值不能為負數")
ValueError: 數值不能為負數
>>>
在程序中的某個方法拋出異常后,Python虛擬機通過調用堆棧查找相應的異常捕獲程序。如果找到匹配的異常捕獲程序(即調用堆棧中的某函數使用try…except語句捕獲處理),則執行相應的處理程序(try…except語句中匹配的except語句塊)
如果堆棧中沒有匹配的異常捕獲程序,則Python虛擬機捕獲處理異常,在控制臺打印出異常的錯誤信息和調用堆棧,并中止程序的執行
二:try …except…else…finally
try:
可能產生異常的語句
except Exception1:
發生Exception1時執行的語句
except (Exception2,Exception3):
發生Exception2或Exception3時執行的語句
except Exception4 as e:
發生Exception4時執行的語句,Exception4的實例是e
except:
捕獲其他所有異常
else:
無異常時執行的語句
finally:
不管異常發生與否都保證執行的語句
except語句可以寫多個,但是要注意一點:系統是自上而下匹配發生的異常,所以用戶需要將帶有最具體的(即派生類程度最高的)異常類的except寫在前面
三:創建自定義異常,處理應用程序中出現的負數參數的異常
自定義異常類一般繼承于Exception或其子類。自定義異常類的名稱一般以Error或Exception為后綴
>>> class NumberError(Exception):
def __init__(self,data):
Exception.__init__
(self,data)
self.data = data
def __str__(self):
return self.data + ':非法數值(<0)'
>>>
>>> def total(data):
total = 0
for i in data:
if i < 0: raise NumberError(str(i))
total += 1
return total
>>>
>>> data1 = (44, 78, 90, 80, 55)
>>> print("sum: ",total(data1))
sum: 5
>>>
>>> data2 = (44, 78, 90, 80, -1)
>>> print("sum: ",total(data2))
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
print("sum: ",total(data2))
File "<pyshell#18>", line 4, in total
if i < 0: raise NumberError(str(i))
NumberError: -1:非法數值(<0)
>>>
四:斷言處理
用戶在編寫程序時,在調試階段往往需要判斷代碼執行過程中變量的值等信息:
- 用戶可以使用print()函數打印輸出結果
- 也可以通過斷點跟蹤調試查看變量
- 但使用斷言更加靈活
assert語句和AssertionError
斷言的聲明:
assert <布爾表達式>
即:if __debug__: if not testexpression: raise AssertionErrorassert <布爾表達式>,<字符串表達式>
即:if __debug__: if not testexpression: raise AssertionError(data)
字符串表達式(即data)是斷言失敗時輸出的失敗消息
__debug__也是布爾值,Python解釋器有兩種:調試模式和優化模式
- 調試模式:
__debug__ == True - 優化模式:
__debug__ == False
在學習中,對于執行一個py模塊(比如test.py)我們通常在cmd中這么輸入python test.py,而這默認是調試模式。
如果我們要使用優化模式來禁用斷言來提高程序效率,我們可以加一個運行選項-O,在控制臺中這么輸入python -O test.py
看一下斷言的示例吧,理解一下用法:
a =int(input("a: "))
b =int(input("b: "))
assert b != 0, '除數不能為零'
c = a/b
print("a/b = ", c)
cmd出場:
輸入正確數值時:
輸入錯誤數值時:
禁用斷言,并且輸入錯誤數值時:
案例研究:使用調試器調試Python程序
https://blog.csdn.net/Zhangguohao666/article/details/103948568
了解使用Python調試器調試程序的方法
第八章 函數和函數式編程
一些知識點總結和幾個例題
Python中函數的分類:
- 內置函數
在程序中可以直接使用 - 標準庫函數
Python語言安裝程序同時會安裝若干標準庫,例如math、random等 - 第三方庫函數
Python社區提供了許多其它高質量的庫,在下載、安裝這些庫后,通過import語句可以導入庫 - 用戶自定義函數
- 函數名為有效的標識符(命名規則為全小寫字母,可以使用下劃線增加可閱讀性,例如
my_func()) - 函數可以使用return返回值
如果函數體中包含return語句,則返回值,
否則不返回,即返回值為空(None),無返回值的函數相當于其它編程語言中的過程
調用函數之前程序必須先執行def語句,創建函數對象
- 內置函數對象會自動創建
- import導入模塊時會執行模塊中的def語句,創建模塊中定義的函數
- Python程序結構順序通常為
import語句>函數定義>全局代碼
一:產生副作用的函數,純函數
打印等腰三角形
n = int(input("行數:"))
def print_star(n):
print((" * " * n).center(50))
for i in range(1, 2*n, 2):
print_star(i)
輸出:
行數:5
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
上面代碼中的print_star()是一個產生副作用的函數,其副作用是向標準輸出寫入若干星號
- 副作用:例如讀取鍵盤輸入,產生輸出,改變系統的狀態等
- 在一般情況下,產生副作用的函數相當于其它程序設計語言中的過程,可以省略return語句
定義計算并返回第n階調和數(1+1/2+1/3+…+1/n)的函數,輸出前n個調和數
def harmonic(n):
total = 0.0
for i in range(1, n+1):
total += 1.0/i
return total
n = int(input("n:"))
print("輸出前n個調和數的值:")
for i in range(1, n+1):
print(harmonic(i))
輸出:
n:8
輸出前n個調和數的值:
1.0
1.5
1.8333333333333333
2.083333333333333
2.283333333333333
2.4499999999999997
2.5928571428571425
2.7178571428571425
上面代碼中的harmonic()是純函數
純函數:給定同樣的實際參數,其返回值唯一,且不會產生其它的可觀察到的副作用
注意:編寫同時產生副作用和返回值的函數通常被認為是不良編程風格,但有一個例外,即讀取函數。例如,input()函數既可以返回一個值,又可以產生副作用(從標準輸入中讀取并消耗一個字符串)
二:傳遞不可變對象、可變對象的引用
- 實際參數值默認按位置順序依次傳遞給形式參數。如果參數個數不對,將會產生錯誤
在調用函數時:
- 若傳遞的是不可變對象(例如:int、float、bool、str對象)的引用,則如果函數體中修改對象的值,其結果實際上是創建了一個新的對象
i = 1
def func(i,n):
i += n
return i
print(i)#1
func(i,10)
print(i)#1
執行函數func()后,i依舊為1,而不是11
- 若傳遞的是可變對象(例如:list對象)的引用,則在函數體中可以直接修改對象的值
import random
def shuffle(a):
n = len(a)
for i in range(n):
r = random.randrange(i,n)
a[i],a[r] = a[r],a[i]
a = [1,2,3,4,5]
print("初始:",a)
shuffle(a)
print("調用函數后:",a)
輸出:
初始: [1, 2, 3, 4, 5]
調用函數后: [1, 5, 4, 3, 2]
三:可選參數,命名參數,可變參數,強制命名參數
可選參數
- 在聲明函數時,如果希望函數的一些參數是可選的,可以在聲明函數時為這些參數指定默認值
>>> def babbles(words, times=1):
print(words * times)
>>> babbles('Hello')
Hello
>>>
>>> babbles("Hello", 2)
HelloHello
>>>
注意到一點:必須先聲明沒有默認值的形參,然后再聲明有默認值的形參,否則報錯。 這是因為在函數調用時默認是按位置傳遞實際參數的。
怎么理解上面那句話呢?
默認是按位置傳遞實際參數(如果有默認值的形參在左邊,無默認值的形參在右,那么在調用函數時,你的實參該怎么傳遞呢?)
命名參數
- 位置參數:當函數調用時,實參默認按位置順序傳遞形參
- 命名參數(關鍵字參數):按名稱指定傳入的參數
參數按名稱意義明確
傳遞的參數與順序無關
如果有多個可選參數,則可以選擇指定某個參數值
基于期中成績和期末成績,按照指定的權重計算總評成績
>>> def my_sum(mid_score, end_score, mid_rate = 0.4):
score = mid_score*mid_rate + end_score*(1-mid_rate)
print(format(score,'.2f'))
>>> my_sum(80,90)
86.00
>>> my_sum(mid_score = 80,end_score = 90)
86.00
>>> my_sum(end_score = 90,mid_score = 80)
86.00
>>>
可變參數
- 在聲明函數時,可以通過帶星號的參數(例如:
def func(* param))向函數傳遞可變數量的實參,調用函數時,從那一點后所有的參數被收集為一個元組 - 在聲明函數時,可以通過帶雙星號的參數(例如:
def func(** param))向函數傳遞可變數量的實參,調用函數時,從那一點后所有的參數被收集為一個字典
利用帶星的參數計算各數字的累加和
>>> def my_sum(a,b,*c):
total = a+b
for i in c:
total += i
return total
>>> print(my_sum(1,2))
3
>>> print(my_sum(1,2,3,4,5,6))
21
利用帶星和帶雙星的參數計算各數字的累加和
>>> def my_sum(a,b,*c,**d):
total = a+b
for i in c:
total += i
for key in d:
total += d[key]
return total
>>> print(my_sum(1,2))
3
>>> print(my_sum(1,2,3,4))
10
>>> print(my_sum(1,2,3,4,male=1,female=2))
13
強制命名參數
- 在帶星號的參數后面聲明參數會導致強制命名參數(Keyword-only),然后在調用時必須顯式使用命名參數傳遞值
- 因為按位置傳遞的參數默認收集為一個元組,傳遞給前面帶星號的可變參數
>>> def my_sum(*, mid_score, end_score, mid_rate = 0.4):
score = mid_score*mid_rate + end_score*(1-mid_rate)
print(format(score,'.2f'))
>>> my_sum(mid_score=80,end_score=90)
86.00
>>> my_sum(end_score=90,mid_score=80)
86.00
>>> my_sum(80,90)
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
my_sum(80,90)
TypeError: my_sum() takes 0 positional arguments but 2 were given
>>>
四:全局語句global示例,非局部語句nonlocal示例,輸出局部變量和全局變量
- 在函數體中可以引用全局變量,但是要為定義在函數外的全局變量賦值,需要使用global語句
pi = 2.1415926
e = 2.7182818
def my_func():
global pi
pi = 3.14
print("global pi = ", pi)
e = 2.718
print("local e = ", e)
print('module pi = ', pi)
print('module e = ', e)
my_func()
print('module pi = ', pi)
print('module e = ', e)
輸出:
module pi = 2.1415926
module e = 2.7182818
global pi = 3.14
local e = 2.718
module pi = 3.14
module e = 2.7182818
- 在函數體中可以定義嵌套函數,在嵌套函數中如果要為定義在上級函數體的局部變量賦值,可以使用nonlocal
def outer_func():
tax_rate = 0.17
print('outer function tax rate is ',tax_rate)
def inner_func():
nonlocal tax_rate
tax_rate = 0.01
print('inner function tax rate is ',tax_rate)
inner_func()
print('outer function tax rate is ',tax_rate)
outer_func()
輸出:
outer function tax rate is 0.17
inner function tax rate is 0.01
outer function tax rate is 0.01
- 輸出局部變量和全局變量
- 內置函數
locals(),局部變量列表 - 內置函數
globals(),全局變量列表
五:獲取和設置最大遞歸數
在sys模塊中,函數getrecursionlimit()和setrecursionlimit()用于獲取和設置最大遞歸次數
>>> import sys
>>> sys.getrecursionlimit()
1000
>>> sys.setrecursionlimit(666)
>>> sys.getrecursionlimit()
666
>>>
六:三個有趣的內置函數:eval()、exec()、compile()
eval
- 對動態表達式進行求值,返回值
eval(expression, globals=None, locals=None)
expression是動態表達式的字符串
globals和locals是求值時使用的上下文環境的全局變量和局部變量,如果不指定,則使用當前運行上下文
>>> x = 2
>>> str_func = input("請輸入表達式:")
請輸入表達式:x**2+2*x+1
>>> eval(str_func)
9
>>>
exec
- 可以執行動態表達式,不返回值
exec(str, globals=None, locals=None)
>>> exec("for i in range(10): print(i, end=' ')")
0 1 2 3 4 5 6 7 8 9
>>>
compile
- 編譯代碼為代碼對象,可以提高效率
compile(source, filename, mode)
source為代碼語句的字符串;如果是多行語句,則每一行的結尾必須有換行符\n
filename為包含代碼的文件
mode為編碼方式,可以為'exec'(用于語句序列的執行),可以為'eval'(用于表達式求值),可以為'single'(用于單個交互語句)
>>> co = compile("for i in range(10): print(i, end=' ')", '', 'exec')
>>> exec(co)
0 1 2 3 4 5 6 7 8 9
>>>
七:map(),filter()
- map(f, iterable,…),將函數
f應用于可迭代對象,返回結果為可迭代對象
示例1:
>>> def is_odd(x):
return x%2 == 1
>>> list(map(is_odd,range(5)))
[False, True, False, True, False]
>>>
示例2:
>>> list(map(abs,[1,-2,3,-4,5,-6]))
[1, 2, 3, 4, 5, 6]
>>>
示例3:
>>> list(map(str,[1,2,3,4,5]))
['1', '2', '3', '4', '5']
>>
示例4:
>>> def greater(x,y):
return x>y
>>> list(map(greater,[1,5,7,3,9],[2,8,4,6,0]))
[False, False, True, False, True]
>>>
- filter(f, iterable),將函數
f應用于每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素,返回結果為可迭代對象
示例1(返回個位數的奇數):
>>> def is_odd(x):
return x%2 == 1
>>> list(filter(is_odd, range(10)))
[1, 3, 5, 7, 9]
>>>
示例2(返回三位數的回文):
>>> list(filter(is_palindrome, range(100, 1000)))
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]
>>>
八:Lambda表達式和匿名函數
匿名函數廣泛應用于需要函數對象作為參數、函數比較簡單并且只使用一次的場合
格式:
lambda arg1,arg2... : <expression>
其中,arg1、arg2等為函數的參數,<expression>為函數的語句,其結果為函數的返回值
示例1(計算兩數之和):
>>> f = lambda x,y : x+y
>>> type(f)
<class 'function'>
>>> f(1,1)
2
>>>
示例2(返回奇數):
>>> list(filter(lambda x:x%2==1, range(10)))
[1, 3, 5, 7, 9]
>>>
示例3(返回非空元素):
>>> list(filter(lambda s:s and s.strip(), ['A', '', 'B', None, 'C', ' ']))
['A', 'B', 'C']
>>>
補充:
strip()用來去除頭尾字符、空白符(\n,\r,\t,’’,即換行、回車、制表、空格)lstrip()用來去除開頭字符、空白符rstrip()用來去除結尾字符、空白符
再補充一點:
\n到下一行的開頭\r回到這一行的開頭
示例4(返回大于0的元素):
>>> list(filter(lambda x:x>0, [1,0,-2,8,5]))
[1, 8, 5]
>>>
示例5(返回元素的平方):
>>> list(map(lambda x:x*x, range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
九:operator模塊和操作符函數
Python內置操作符的函數接口,它定義了對應算術和比較等操作的函數,用于map()、filter()等需要傳遞函數對象作為參數的場合,可以直接使用而不需要使用函數定義或者Lambda表達式,使得代碼更加簡潔
示例1(concat(x,y)對應于x+y):
>>> import operator
>>> a = 'hello'
>>>> operator.concat(a, ' world')
'hello world'
實例2(operator.gt對應于操作符>):
>>> import operator
>>> list(map(operator.gt, [1,5,7,3,9],[2,8,4,6,0]))
[False, False, True, False, True]
>>>
十:functools.reduce(),偏函數functools.partial(),sorted()
functools.reduce()
functools.reduce(func, iterable[, iterable[, initializer]])
- 使用指定的帶兩個參數的函數
func對一個數據集合的所有數據進行下列操作:- 使用第一個和第二個數據作為參數用
func()函數運算,得到的結果再與第三個數據作為參數用func()函數運算,依此類推,最后得到一個結果- 可選的
initialzer為初始值
示例:
>>> import functools,operator
>>> functools.reduce(operator.add, [1,2,3,4,5])
15
>>> functools.reduce(operator.add, [1,2,3,4,5], 10)
25
>>> functools.reduce(operator.add, range(1,101))
5050
>>>
>>> functools.reduce(operator.mul, range(1,11))
3628800
偏函數functools.partial()
functools.partial(func, *arg, **keywords)
- 通過把一個函數的部分參數設置為默認值的方式返回一個新的可調用(callable)的partial對象
- 主要用于設置預先已知的參數,從而減少調用時傳遞參數的個數
示例(2的n次方):
>>> import functools,math
>>> pow2 = functools.partial(math.pow, 2)
>>> list(map(pow2, range(11)))
[1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0]
>>>
十一:sorted()
sorted(iterable, *, key=None, reverse=False)
- iterable是待排序的可迭代對象
- key是比較函數(默認為None,按自然順序排序)
- reverse用于指定是否逆序排序
示例1(數值。默認自然排序):
>>> sorted([1,6,4,-2,9])
[-2, 1, 4, 6, 9]
>>> sorted([1,6,4,-2,9], reverse=True)
[9, 6, 4, 1, -2]
>>> sorted([1,6,4,-2,9], key=abs)
[1, -2, 4, 6, 9]
示例2(字符串,默認按字符串字典序排序):
>>> sorted(['Dod', 'cat', 'Rabbit'])
['Dod', 'Rabbit', 'cat']
>>> sorted(['Dod', 'cat', 'Rabbit'], key=str.lower)
['cat', 'Dod', 'Rabbit']
>>> sorted(['Dod', 'cat', 'Rabbit'], key=len)
['Dod', 'cat', 'Rabbit']
示例3(元組,默認按元組的第一個元素排序):
>>> sorted([('Bob', 75), ('Adam', 92), ('Lisa', 88)])
[('Adam', 92), ('Bob', 75), ('Lisa', 88)]
>>> sorted([('Bob', 75), ('Adam', 92), ('Lisa', 88)], key=lambda t:t[1])
[('Bob', 75), ('Lisa', 88), ('Adam', 92)]
十二:函數裝飾器
這玩意就很有意思了,很Java語言中的注解是很相像的
示例1:
import time,functools
def timeit(func):
def wrapper(*s):
start = time.perf_counter()
func(*s)
end = time.perf_counter()
print('運行時間:', end - start)
return wrapper
@timeit
def my_sum(n):
sum = 0
for i in range(n): sum += i
print(sum)
if __name__ == '__main__':
my_sum(10_0000)
結果:
4999950000
運行時間: 0.013929100000000028
怎么理解上面的代碼呢?
- 首先,
timeit()返回的是wrapper,而不是執行(沒有小括號) @timeit相當于,在調用my_sum()的前一刻,會執行這么個語句:my_sum = timeit(my_sum)
示例2:
def makebold(fn):
def wrapper(*s):
return "<b>" + fn(*s) + "</b>"
return wrapper
def makeitalic(fn):
def wrapper(*s):
return "<i>" + fn(*s) + "</i>"
return wrapper
@makebold
@makeitalic
def htmltags(str1):
return str1
print(htmltags('Hello'))
輸出:
<b><i>Hello</i></b>
選擇題:1~5
1
>>> print(type(lambda:None))
<class 'function'>
2
>>> f = lambda x,y:x*y
>>> f(12, 34)
408
3
>>> f1 = lambda x:x*2
>>> f2 = lambda x:x**2
>>> print(f1(f2(2)))
8
4
>>> def f1(p, **p2):
print(type(p2))
>>> f1(1, a=2)
<class 'dict'>
5
>>> def f1(a,b,c):
print(a+b)
>>> nums = (1,2,3)
>>> f1(*nums)
3
思考題:4~11
4
>>> d = lambda p:p*2
>>> t = lambda p:p*3
>>> x = 2
>>> x = d(x)
>>> x = t(x)
>>> x = d(x)
>>> print(x)
24
5
>>> i = map(lambda x:x**2, (1,2,3))
>>> for t in i:
print(t, end=' ')
1 4 9
6
>>> def f1():
"simple function"
pass
>>> print(f1.__doc__)
simple function
7
>>> counter = 1
>>> num = 0
>>> def TestVariable():
global counter
for i in (1, 2, 3) : counter += 1
num = 10
>>> TestVariable()
>>> print(counter, num)
4 0
8
>>> def f(a,b):
if b==0 : print(a)
else : f(b, a%b)
>>> print(f(9,6))
3
None
求最大公約數
9
>>> def aFunction():
"The quick brown fox"
return 1
>>> print(aFunction.__doc__[4:9])
quick
10
>>> def judge(param1, *param2):
print(type(param2))
print(param2)
>>> judge(1, 2, 3, 4, 5)
<class 'tuple'>
(2, 3, 4, 5)
11
>>> def judge(param1, **param2):
print(type(param2))
print(param2)
>>> judge(1, a=2, b=3, c=4, d=5)
<class 'dict'>
{
'a': 2, 'b': 3, 'c': 4, 'd': 5}
上機實踐:2~5
2. 編寫程序,定義一個求階乘的函數fact(n),并編寫測試代碼,要求輸入整數n(n>=0)。請分別使用遞歸和非遞歸方式實現
遞歸方式:
def fact(n):
if n == 0 :
return 1
return n*fact(n-1)
n = int(input("請輸入整數n(n>=0):"))
print(str(n)+" ! = " + str(fact(n)))
非遞歸方式:
def fact(n):
t = 1
for i in range(1,n+1):
t *= i
return t
n = int(input("請輸入整數n(n>=0):"))
print(str(n)+" ! = " + str(fact(n)))
輸出:
請輸入整數n(n>=0):5
5 ! = 120
3. 編寫程序,定義一個求Fibonacci數列的函數fib(n),并編寫測試代碼,輸出前20項(每項寬度5個字符位置,右對齊),每行輸出10個。請分別使用遞歸和非遞歸方式實現
遞歸方式:
def fib(n):
if (n == 1 or n == 2):
return 1
return fib(n-1)+fib(n-2)
for i in range(1,21):
print(str(fib(i)).rjust(5,' '),end = ' ')
if i %10 == 0:
print()
非遞歸方式:
def fib(n):
if (n == 1 or n == 2):
return 1
n1 = n2 = 1
for i in range(3,n+1):
n3 = n1+n2
n1 = n2
n2 = n3
return n3
for i in range(1,21):
print(str(fib(i)).rjust(5,' '),end = ' ')
if i %10 == 0:
print()
輸出:
1 1 2 3 5 8 13 21 34 55
89 144 233 377 610 987 1597 2584 4181 6765
4. 編寫程序,利用可變參數定義一個求任意個數數值的最小值的函數min_n(a,b,*c),并編寫測試代碼。例如對于“print(min_n(8, 2))”以及“print(min_n(16, 1, 7, 4, 15))”的測試代碼
def min_n(a,b,*c):
min_number = a if(a < b) else b
for n in c:
if n < min_number:
min_number = n
return min_number
print(min_n(8, 2))
print(min_n(16, 1, 7, 4, 15))
輸出:
2
1
5. 編寫程序,利用元組作為函數的返回值,求序列類型中的最大值、最小值和元素個數,并編寫測試代碼,假設測試代碼數據分別為s1=[9, 7, 8, 3, 2, 1, 55, 6]、s2=[“apple”, “pear”, “melon”, “kiwi”]和s3=”TheQuickBrownFox”
def func(n):
return (max(n),min(n),len(n))
s1=[9, 7, 8, 3, 2, 1, 55, 6]
s2=["apple", "pear", "melon", "kiwi"]
s3="TheQuickBrownFox"
for i in (s1,s2,s3):
print("list = ", i)
t = func(i)
print("最大值 = {0},最小值 = {1},元素個數 = {2}".format(t[0], t[1], t[2]))
輸出:
list = [9, 7, 8, 3, 2, 1, 55, 6]
最大值 = 55,最小值 = 1,元素個數 = 8
list = ['apple', 'pear', 'melon', 'kiwi']
最大值 = pear,最小值 = apple,元素個數 = 4
list = TheQuickBrownFox
最大值 = x,最小值 = B,元素個數 = 16
案例研究:井字棋游戲
https://blog.csdn.net/Zhangguohao666/article/details/103280740
了解Python函數的定義和使用
由于本文的內容太多了,導致了兩個很不好的結果,
一是:在網頁中打開本篇博客的加載時間太長了,明顯的卡頓很影響閱讀體驗;
二是:本人在對本篇文章進行更新或者修改內容時,卡的要死。
遂,
將本文第八章后面的很多內容拆分到新的文章中,望大家理解
第九章 面向對象的程序設計
- 《Python程序設計與算法基礎教程(第二版)》江紅 余青松,第九章課后習題答案
第十章 模塊和客戶端
- 《Python程序設計與算法基礎教程(第二版)》江紅 余青松,第十章課后習題答案
第十一章 算法與數據結構基礎
- 《Python程序設計與算法基礎教程(第二版)》江紅 余青松,第十一章課后習題答案
第十二章 圖形用戶界面
我對圖形用戶界面基本無興趣,無特殊情況,基本不打算碰這方面內容
案例研究:簡易圖形用戶界面計算器
- Python實現簡易圖形用戶界面計算器
第十三章 圖形繪制
與上一章相同,我對于圖形繪制的興趣也基本沒有,嘗試做了2-7題,就完全沒興趣做下去了
圖形繪制模塊:tkinter
2. 參考例13.2利用Canvas組件創建繪制矩形的程序,嘗試改變矩形邊框顏色以及填充顏色
from tkinter import *
root = Tk()
c = Canvas(root, bg = 'white', width = 130, height = 70)
c.pack()
c.create_rectangle(10, 10, 60, 60, fill = 'red')
c.create_rectangle(70, 10, 120, 60, fill = 'green', outline = 'blue', width = 5)
創建畫布對象:
root = Tk()
創建一個Tk根窗口組件rootc = Canvas(root, bg = 'white', width = 130, height = 70)
創建大小為200 * 100、背景顏色為白色的畫布c.pack()
調用組件pack()方法,調整其顯示位置和大小
繪制矩形:
c.create_rectangle(x0, y0, x1, y1, option, ...)
- (x0,y0)是左上角的坐標
- (x1,y1)是右下角的坐標
c.create_rectangle(70, 10, 120, 60, fill = 'green', outline = 'blue', width = 5)
用藍色邊框、綠色填充矩形,邊框寬度為5
3. 參考例13.3利用Canvas組件創建繪制橢圓的程序,嘗試修改橢圓邊框樣式、邊框顏色以及填充顏色
from tkinter import *
root = Tk()
c = Canvas(root, bg = 'white', width = 280, height = 70)
c.pack()
c.create_oval(10, 10, 60, 60, fill = 'green')
c.create_oval(70, 10, 120, 60, fill = 'green', outline = 'red', width = 5)
c.create_oval(130, 25, 180, 45, dash = (10,))
c.create_oval(190, 10, 270, 50, dash = (1,), width = 2)
繪制橢圓
c.create_oval(x0, y0, x1, y1, option, ...)
- (x0,y0)是左上角的坐標
- (x1,y1)是右下角的坐標
c.create_oval(70, 10, 120, 60, fill = 'green', outline = 'red', width = 5)
綠色填充、紅色邊框,寬度為5c.create_oval(130, 25, 180, 45, dash = (10,))
虛線橢圓
4. 參考例13.4利用Canvas組件創建繪制圓弧的程序,嘗試修改圓弧樣式、邊框顏色以及填充顏色
from tkinter import *
root = Tk()
c = Canvas(root, bg = 'white', width = 250, height = 70)
c.pack()
c.create_arc(10, 10, 60, 60, style = ARC)
c.create_arc(70, 10, 120, 60, style = CHORD)
c.create_arc(130, 10, 180, 60, style = PIESLICE)
for i in range(0, 360, 60):
c.create_arc(190, 10, 240, 60, fill = 'green', outline = 'red', start = i, extent = 30)
繪制圓?。?/strong>
c.create_arc(x0, y0, x1, y1, option, ...)
- (x0,y0)是左上角的坐標
- (x1,y1)是右下角的坐標
- 選項start(開始角度,默認為0)和extend(圓弧角度,從start開始逆時針旋轉,默認為90度)決定圓弧的角度范圍
- 選項start用于設置圓弧的樣式
5. 參考例13.5利用Canvas組件創建繪制線條的程序,嘗試修改線條樣式和顏色
from tkinter import *
root = Tk()
c = Canvas(root, bg = 'white', width = 250, height = 70)
c.pack()
c.create_line(10, 10, 60, 60, arrow = BOTH, arrowshape = (3, 4, 5))
c.create_line(70, 10, 95, 10, 120, 60, fill = 'red')
c.create_line(130, 10, 180, 10, 130, 60, 180, 60, fill = 'green', width = 10, arrow = BOTH, joinstyle = MITER)
c.create_line(190, 10, 240, 10, 190, 60, 240, 60, width = 10)
繪制線條:
c.create_line(x0, y0, x1, y1, ..., xn, yn, option, ...)
- (x0,y0),(x1,y1),…,(xn,yn)是線條上各個點的坐標
6. 參考例13.6利用Canvas組件創建繪制多邊形的程序,嘗試修改多邊形的形狀、線條樣式和填充顏色
from tkinter import *
root = Tk()
c = Canvas(root, bg = 'white', width = 250, height = 70)
c.pack()
c.create_polygon(35, 10, 10, 60, 60, 60, fill = 'red', outline = 'green')
c.create_polygon(70, 10, 120, 10, 120, 60, fill = 'white', outline = 'blue')
c.create_polygon(130, 10, 180, 10, 180, 60, 130, 60, outline = 'blue')
c.create_polygon(190, 10, 240, 10, 190, 60, 240, 60, fill = 'white', outline = 'black')
繪制多邊形:
c.create_polygon(x0, y0, x1, y1, ..., option, ...)
- (x0,y0),(x1,y1),…,(xn,yn)是多邊形上各個頂點的坐標
7. 參考例13.7利用Canvas組件創建繪制字符串和圖形的程序,繪制y = cos(x) 的圖形
繪制字符串:
c.create_text(x, y, option, ...)
- (x,y)是字符串放置的中心位置
y = sin(x)
from tkinter import *
import math
WIDTH, HEIGHT = 510, 210
ORIGIN_X, ORIGIN_Y = 2, HEIGHT/2 #原點
SCALE_X, SCALE_Y = 40, 100 #x軸、y軸縮放倍數
ox, oy = 0, 0
x, y = 0, 0
arc = 0 #弧度
END_ARC = 360 * 2 #函數圖形畫兩個周期
root = Tk()
c = Canvas(root, bg = 'white', width = WIDTH, height = HEIGHT)
c.pack()
c.create_text(200, 20, text = 'y = sin(x)')
c.create_line(0, ORIGIN_Y, WIDTH, ORIGIN_Y)
c.create_line(ORIGIN_X, 0, ORIGIN_X, HEIGHT) #繪制x軸,y軸
for i in range(0, END_ARC+1, 10):
arc = math.pi * i / 180
x = ORIGIN_X + arc * SCALE_X
y = ORIGIN_Y - math.sin(arc) * SCALE_Y
c.create_line(ox, oy, x, y)
ox, oy = x, y
y = cos(x)
from tkinter import *
import math
WIDTH, HEIGHT = 510, 210
ORIGIN_X, ORIGIN_Y = 2, HEIGHT/2 #原點
SCALE_X, SCALE_Y = 40, 100 #x軸、y軸縮放倍數
ox, oy = 0, 0
x, y = 0, 0
arc = 0 #弧度
END_ARC = 360 * 2 #函數圖形畫兩個周期
root = Tk()
c = Canvas(root, bg = 'white', width = WIDTH, height = HEIGHT)
c.pack()
c.create_text(200, 20, text = 'y = cos(x)')
c.create_line(0, ORIGIN_Y, WIDTH, ORIGIN_Y)
c.create_line(ORIGIN_X, 0, ORIGIN_X, HEIGHT)
for i in range(0, END_ARC+1, 10):
arc = math.pi * i / 180
x = ORIGIN_X + arc * SCALE_X
y = ORIGIN_Y - math.cos(arc) * SCALE_Y
c.create_line(ox, oy, x, y)
ox, oy = x, y
圖形繪制模塊:turtle
…
后面章節內容:未完待續…
第十四章 數值日期和時間處理
第十五章 字符串和文本處理
第十六章 文件和數據交換
第十七章 數據訪問
第十八章 網絡編程和通信
第十九章 并行計算:進程、線程和協程
第二十章 系統管理
總結
以上是生活随笔為你收集整理的《Python程序设计与算法基础教程(第二版)》江红 余青松 全部章节的课后习题,上机实践,课后答案,案例研究「建议收藏」(Python.org)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: libusb开发指南
- 下一篇: 转发pptp和l2tp