---
title: Python111-1
tags: NTOU CLASS, Homework, Python
---
# Python111-1 上課例題
:::info
* 課程名稱:Python程式語言
* 授課老師:[name=張欽圳老師]
* 修課學期:111-1
:::
[TOC]
## 主題1
### 計算C(m,n)
##### **題目說明**
輸入兩個正整數m與n, m>=n,計算C(m,n)。
##### **程式碼參考**
```python=
m = int(input())
n = int(input())
ans = int(1)
up = max(m-n, n)
temp = int(1)
for i in range(up, m):
ans *= (i+1)
temp *= (m-i)
ans //= temp
print(ans)
```
##### **測資**
輸入
5
3
輸出
10
---
### 計算本利和
##### **題目說明**
寫一個程式輸入本金m、利率r、存幾年y。計算y年後本利和一共是多少錢。
公式m*(1+r)^y^。為了準確計算請使用decimal。
本金:40000
利率:0.07
存20年
的本利和
你的程式輸入/輸出要像這樣。
本金:100000
利率:0.06
存幾年:100
本利和:33930208.35144854913075581851
import decimal #試試下面的指令
m=input()
m=decimal.Decimal(m)
##### **程式碼參考**
```python=
import decimal
m = input("本金:")
r = input("利率:")
y = input("存幾年:")
m = decimal.Decimal(m)
r = decimal.Decimal(r)
y = decimal.Decimal(y)
ans = decimal.Decimal(m*(1+r)**y)
print("本利和:", end="")
print(ans)
```
##### **測資**
輸入
100000
0.06
100
輸出
本金:利率:存幾年:本利和:33930208.35144854913075581851
---
### 計算共有多少輸入數字
##### **題目說明**
輸入以逗點(,)隔開的數字。計算共有多少數字。
例如:
輸入
123,456
輸出
2
輸入
123
輸出
1
輸入
123,456,789
輸出
3
##### **程式碼參考**
```python=
a = input()
ans = int(1)
for i in range(0, len(a)):
if (a[i] == ','):
ans += 1
print(ans)
```
##### **測資**
輸入
123,456
輸出
2
---
## 主題2
### 計算共有多少正確輸入數字
##### **題目說明**
輸入以逗點(,)隔開的數字。計算共有多少數字(浮點數)。
例如:
輸入
123,456
輸出
2
輸入
123
輸出
1
輸入
123,a,456,\,789
輸出
3
##### **程式碼參考**
```python=
a = input("").split(",")
ans = 0
for i in range(len(a)):
f = 1
if len(a[i]) == 0:
f = 0
for j in range(len(a[i])):
if (a[i][j] == '.' or a[i][j] == '-' or a[i][j] == '0' or a[i][j] == '1' or a[i][j] == '2' or a[i][j] == '3' or a[i][j] == '4' or a[i][j] == '5' or a[i][j] == '6' or a[i][j] == '7' or a[i][j] == '8' or a[i][j] == '9'):
continue
else:
f = 0
break
if f == 1:
ans += 1
print(ans)
```
##### **測資**
輸入
123,546,,234
輸出
3
---
### 使用formatter
##### **題目說明**
輸入1個字串x與整數n,欄寬整數w,補空白(padding)字元p,使用formatter,依序對x與n
產生如測試範例4種顯示格式。
1.以欄寬w往右靠齊顯示x
2.以欄寬w往左靠齊顯示n
3.以欄寬w往中靠齊顯示x,要有補空白字元
4.以欄寬w往中靠齊顯示n,每千位一個,
##### **程式碼參考**
```python=
x = input("")
n = int(input(""))
w = int(input(""))
p = input("")
print('{0:>{width}}'.format(x, width=w))
print('{0:<{width}}'.format(n, width=w))
print('{0:{char}^{width}}'.format(x, char=p, width=w))
print('{0:{char}^{width}}'.format(format(n, ','), char=p, width=w))
```
##### **測資0**
輸入
abc
123456789
15
−
輸出
abc
123456789
------abc------
--123,456,789--
##### **測資1**
輸入
cdefgh
10000000
9
−
輸出
cdefgh
10000000
-cdefgh--
10,000,000
> 此處測資部分 '-' 皆為減號
---
### 使用string
##### **題目說明**
輸入三個字串x,y,z,照順序輸出下面結果
1.輸出y是否出現在x裡(True/False)
2.輸出y第一次出現在x裡的足標,若沒有輸出-1
3.輸出x以','拆解後的結果 (a list)
4.將x裡前3個以,隔開的子字串以'---'串接後輸出
5.檢查x開頭是否為y(True/False)
6.檢查x結尾是否為y(True/False)
7.將x轉大寫後輸出
8.將x裡每個全由英文字母構成的子字串開始的第一字轉大寫其他轉小寫
9.檢查y是否為全為數字(True/False)
10.將x裡所有的子字串y改為z
##### **程式碼參考**
```python=
x = input("")
listx = x.split(',')
y = input("")
z = input("")
if (x.find(y) >= 0):
print("True")
else:
print("False")
print(x.find(y))
print(listx)
for i in listx:
if (i == listx[0]):
print(i, end='')
else:
print("---", i, sep='', end='')
print("")
print(listx[0] == y)
print(listx[len(listx)-1] == y)
print(x.upper(), sep=',')
print(x.title(), sep=',')
try:
y = int(y)
print("True")
except:
print("False")
for i in listx:
if (i != listx[0]):
print(',', end='')
if (i == y):
print(z, end='')
else:
print(i, end='')
print("")
```
##### **測資**
輸入
aa,bb,cc
bb
abcd
輸出
True
3
['aa', 'bb', 'cc']
aa---bb---cc
False
False
AA,BB,CC
Aa,Bb,Cc
False
aa,abcd,cc
---
### 使用sys輸入
##### **題目說明**
寫1個Python程式使用sys模組,讀入一連串整數(一輸入列只有一個整數)直到EOF為止,輸出奇數的和與偶數的和。
範例:test.py
```python
import sys
even, odd = 0, 0
# 由下面範例選擇恰當指令來讀入一連串整數(一輸入列只有一個整數)直到EOF為止。
# 輸出結果
print('odd:{} even:{}'.format(odd,even))
```
測試方式:
打開命令列視窗
在程式所在目錄python test.py
模組說明
```python
import sys
+ sys.argv: 命令列參數。 若命令列指令為python hello.py -a -b
那麼sys.argv[0]、sys.argv[1]、sys.argv[2]分別為"hello.py"、"-a"、"-b"。
+ sys.path: 模組搜尋路徑,可自行增減路徑。
+ sys.getrefcount(x): 傳回x的引用個數。
+ sys.exit(x): 離開程式。若x為整數,效果如同C裡的exit(x)。若x為其他物件效果等同於sys.stderr.write(x); sys.exit(1)
+ sys.stdin, sys.stdout, sys.stderr: 標準輸入、輸出、錯誤輸出。
範例
1. sys.stdin.read() #由sys.stdin輸入,按Enter + Ctrl-Z (Ctrl-D Linux)後傳回讀入字串。
2. for line in sys.stdin: # 輸入ㄧ行,直到EOF為止
print(line) #line會包含\n
另一種寫法
while True:
try:
line = input()
print('{'+line+'}') # line不包含\n
except EOFError:
break
3. x=sys.stdin.readline() # 輸入ㄧ行直到\n (包含\n)
4. x=sys.stdin.readlines() # 輸入多行直到Enter + Ctrl-Z
5. for line in sys.stdin.readlines():
print(line)
6. sys.stdout.write(x): 輸出x,沒加\n。
7. sys.stdout.writelines(x): x為iterable,將x裡的項目逐個輸出。
```
##### **程式碼參考**
```python=
x = input("")
listx = x.split(',')
y = input("")
z = input("")
if (x.find(y) >= 0):
print("True")
else:
print("False")
print(x.find(y))
print(listx)
for i in listx:
if (i == listx[0]):
print(i, end='')
else:
print("---", i, sep='', end='')
print("")
print(listx[0] == y)
print(listx[len(listx)-1] == y)
print(x.upper(), sep=',')
print(x.title(), sep=',')
try:
y = int(y)
print("True")
except:
print("False")
for i in listx:
if (i != listx[0]):
print(',', end='')
if (i == y):
print(z, end='')
else:
print(i, end='')
print("")
```
##### **測資**
輸入
123
456
789
1
0
輸出
odd:913 even:456
---
### 使用eval
##### **題目說明**
寫一個Python程式,應用eval函式,可以讀入下面字串,並做簡單運算,例如下面敘述
x<-3
y<-1
z<-(x+y)*5/x
print(z)
bye()
其中
1. <-為assignment operator;
2. bye() 離開程式;
3. print();
4. 支援三角函數cos, sin (使用角度,非徑弧度)計算。
##### **程式碼參考**
```python=
import sys
import math
def bye():
sys.exit()
def cos(x):
return math.cos((x*math.pi)/180)
def sin(x):
return math.sin((x*math.pi)/180)
d = dict()
for line in sys.stdin:
if line.find('<-') >= 0:
l = line.split('<-')
for i in d:
if l[1].find(i) >= 0:
l[1] = l[1].replace(i, str(d[i]))
# print(l[1])
d[l[0]] = eval(l[1])
else:
if (line == "bye()\n"):
break
else:
for i in d:
if line.find(i) >= 0:
print(d[i])
```
##### **測資**
輸入
x <-2
z <-cos(60)*x
print(z)
bye()
輸出
1.0000000000000002
---
## 主題3
### 使用list,tuple,set,dict-I
##### **題目說明**
使用input()分別輸入兩字串s與t。寫出對應的程式片段,回答對下面問題。
1. s共有幾個字(包含標點符號)?
2. s共有幾個不同的字(包含標點符號)?
3. 若list_s=list(s),那麼如何從list_s兜成字串?
4. 有哪些字在s與t都出現過(包含標點符號),由小到大逗點隔開輸出?
5. s與t共有多少不同的字(包含標點符號)?
6. 有多少字只出現在s沒出現在t(包含標點符號)?
7. 哪一個字在s與t出現次數最多(包含標點符號),輸出那個字與次數?
輸出格式: 字:次數 於單獨一列
##### **程式碼參考**
```python=
s = input("")
t = input("")
# 1
print(len(s))
total = 0
tem = 0
set1 = set()
set_s = set()
set_t = set()
for i in s:
set_s.add(i)
set1.add(i)
# 2
print(len(set1))
list_s = list(s)
# 3
for i in list_s:
print(i, end='')
print()
for i in t:
set_t.add(i)
set1.add(i)
set2 = set_s & set_t
l = list(set2)
# 4
print("".join(sorted(l)))
# 5
print(len(set1))
set3 = set_s.difference(set_t)
# 6
print(len(set3))
dic = dict()
for i in s:
if i in dic:
dic[i] += 1
else:
dic[i] = 1
for i in t:
if i in dic:
dic[i] += 1
else:
dic[i] = 1
v = 0
for k in dic:
tem = dic.get(k)
if tem > v:
v = tem
for k in dic:
tem = dic.get(k)
if tem == v:
print(k, end='')
print(':', end='')
print(v)
```
##### **測資**
輸入
蘋果一顆通常約為180-200克,熱量約92大卡,熱量相較其他水果不高,膳食纖維去皮的蘋果約2.3-3.4克,為中高膳食纖維水果,另也含鉀、維生素A、Beta胡蘿蔔素等營養。青蘋果的維生素A又多比紅蘋果來得更高。
整體而言,蘋果的各類營養多為「中高階」,但從綜合營養來看卻相當多元,且果皮植化素優異,對身體的幫助相當廣泛,這也是為什麼常聽到「一天一蘋果,醫生遠離我」。
輸出
106
65
蘋果一顆通常約為180-200克,熱量約92大卡,熱量相較其他水果不高,膳食纖維去皮的蘋果約2.3-3.4克,為中高膳食纖維水果,另也含鉀、維生素A、Beta胡蘿蔔素等營養。青蘋果的維生素A又多比紅蘋果來得更高。
。一中也來多常果為營生的皮相素蘋養高,
104
46
,:11
---
### 使用list,tuple,set,dict-II
##### **題目說明**
輸入一連串以逗點隔開的資料(字串)。請進行下面操作,並輸出結果:
(1)由小到大輸出,每項資料單獨一列。
(2)由大到小輸出,每項資料單獨一列。
(3)由大到小輸出唯一的資料於單獨一列。
##### **程式碼參考**
```python=
x = input("")
listx = x.split(',')
listx = sorted(listx)
for i in listx:
print(i)
listx = sorted(listx, reverse=True)
for i in listx:
print(i)
setx = set()
for i in listx:
setx.add(i)
setx = sorted(setx, reverse=True)
for i in setx:
print(i)
```
##### **測資**
輸入
1,2,2,3,4,5,6,7,8
輸出
1
2
2
3
4
5
6
7
8
8
7
6
5
4
3
2
2
1
8
7
6
5
4
3
2
1
---
### 使用list,tuple,set,dict-III
##### **題目說明**
寫一個程式輸入一個dict(**此dict在第一個輸入列**)。照順序執行下面操作:
key, value皆為數值型態。
1.輸出dict有多少元素於單獨一列。
2.讀入整數x,輸出x是否在此dict內(keys())於單獨一列 (True/False)。
3.讀入整數x,輸出key為x的值是否為0於單獨一列。(True/False/Notexisting (x若不在dict內))
4.讀入tuple x,將以x[0]為key,value為x[1]的元素,加入此dict。
5.由小到大輸出dict所有key (一個元素一列)。
6.由小到大輸出dict所有value (一個元素一列)。
7.由小到大輸出dict所有(key,value) (一個tuple一列)。
##### **程式碼參考**
```python=
x = input("")
d = eval(x)
print(len(d))
x = int(input(""))
f = 0
for k in d:
if k == x:
if f == 1:
f = 0
break
else:
f = 1
if f == 0:
print("False")
else:
print("True")
x = int(input(""))
f = 0
for k in d:
if d.get(k) == x:
if f == 1:
f = 2
break
else:
f = 1
if f == 0:
print("Notexisting")
elif f == 1:
print("True")
else:
print("False")
x = input("")
t = eval(x)
d[t[0]] = t[1]
l = list()
l1 = list()
for i in d:
l.append(i)
l1.append(d.get(i))
l = sorted(l)
for i in l:
print(i)
l1 = sorted(l1)
for i in l1:
print(i)
for i in l:
print("({}, {})".format(i, d[i]))
```
##### **測資**
輸入
{1:5, 3:7, 8:9, 0:10}
7
4
(10,11)
輸出
4
False
Notexisting
0
1
3
8
10
5
7
9
10
11
(0, 10)
(1, 5)
(3, 7)
(8, 9)
(10, 11)
---
### List操作
##### **題目說明**
輸入以逗點隔開的一連串數字,並存放於一個list1裡。
試試 list1 = list(map(int,input().split(',')))
請對此list1做下面操作:
1. 列出元素及其足標。
2. 照順序移除(in-place)list1裡小於0的元素至list2。
3. 使用zip,同時疊代與輸出list1與list2元素,以格式 l1:l2顯示,逗點隔開。
##### **程式碼參考**
```python=
list1 = list(map(int, input().split(',')))
x = 0
l1 = list()
list2 = list()
for i in list1:
if (x > 0):
print(",", end="")
print(x, end=":")
print(i, end="")
x += 1
print()
for i in list1:
if (i < 0):
list2.append(i)
else:
l1.append(i)
x = 0
for i, j in zip(l1, list2):
if (x == 0):
x = 1
else:
print(",", end="")
print(i, end=":")
print(j, end="")
print()
```
##### **測資**
輸入
1,-1,2,-2,3,4,5,-6,7,-4,9,-20
輸出
0:1,1:-1,2:2,3:-2,4:3,5:4,6:5,7:-6,8:7,9:-4,10:9,11:-20
1:-1,2:-2,3:-6,4:-4,5:-20
---
## 主題4
### List comprehension
##### **題目說明**
輸入正整數x,使用list comprehension找出邊長a,b,c介於1與x(1<=a,b,c<=x)的直角三角形。格式必須是這樣[(a,b,c),...],a<=b<=c,(a,b,c)表示一個三角形的邊長。
**Sample Output**
若x為10,答案為[(3, 4, 5), (6, 8, 10)]。
```python
#上載下面程式
x = int(input())
#將你的運算方式,填入answer字串,使得eval(answer)會得到所欲答案。
answer = ''
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
x = int(input())
answer = '[(a,b,c) for a in range(1,x+1) for b in range(a+1,x+1) for c in range(1,x+1) if a**2+b**2==c**2]'
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
### Dict comprehension
##### **題目說明**
輸入c,其中c在'A',...,'Z'。使用dict comprehension建立一個dict,'A',...,c的所有組合為key(排除空集合),value=組合元素個數
(hint: use itertools.combinations)
**Sample Output**
若c為'C',答案為{('A',): 1, ('B',): 1, ('C',): 1, ('A', 'B'): 2, ('A', 'C'): 2, ('B', 'C'): 2, ('A', 'B', 'C'): 3}
```
#上載下面程式
c = input()
#將你的運算方式,填入answer字串,使得eval(answer)會得到所欲答案。
answer = ''
# 連同下面程式上載至e-tutor
_cmd =''
while True:
try:
_s = input()
_cmd += _s+'\n'
except EOFError:
break
p = compile(_cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
from itertools import combinations
c = input()
l1 = list()
for ca in range(ord('A'), ord(c)+1):
l1.append(chr(ca))
answer = "{cc: len(cc) for ca in range(0, ord(c) - ord('A') + 1) for cc in combinations( l1, ca + 1)}"
_cmd = ''
while True:
try:
_s = input()
_cmd += _s+'\n'
except EOFError:
break
p = compile(_cmd, 'default', 'exec')
exec(p)
```
---
#### 使用lambda函數及filter, map, reduce
##### **題目說明**
```python
a = list(map(int,input().split(',')))
# expr1寫出使用filter,選擇a裡正的且為3的倍數。
expr1=filter()
# expr2寫出使用map,將a裡的元素的對映至math.exp(-a)
expr2=map()
# expr3寫出使用reduce計算a裡的元素絕對值的和
expr3=reduce()
#你上載的程式最後要包含下面幾行,用於檢查答案正確性。
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
import math
from functools import reduce
a = list(map(int, input().split(',')))
# expr1寫出使用filter,選擇a裡正的且為3的倍數。
expr1 = filter(lambda x: x % 3 == 0 and x > 0, a)
# expr2寫出使用map,將a裡的元素的對映至math.exp(-a)
expr2 = map(lambda x: math.exp(-x), a)
# expr3寫出使用reduce計算a裡的元素絕對值的和
expr3 = reduce(lambda x, y: abs(x)+abs(y), a)
# 你上載的程式最後要包含下面幾行,用於檢查答案正確性。
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
## 主題5
### 產生器
##### **題目說明**
撰寫產生器stackperm(a),產生list a內元素以堆疊操作方式可以產生的所有排列,順序可以和例子不同但是個數要一樣。
Sample Output
for idx,i in enumerate(stackperm([1,2,3])):
print(idx,i)
會輸出:
0 [3, 2, 1]
1 [2, 3, 1]
2 [2, 1, 3]
3 [1, 3, 2]
4 [1, 2, 3]
```python
#上載下面程式至e-tutor
#撰寫你的產生器
def stackperm(x): #若需要額外參數可用預設參數如,def stackperm(x,p=None,s=None)
...
# 連同下面程式上載至e-tutor
x = input().split(',')
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
from itertools import permutations
def checkStack(x, y, l):
s = []
j = 0
for i in range(l):
s.append(x[i])
while (len(s) > 0 and s[- 1] == y[j]):
s.pop()
j += 1
if (len(s) == 0):
return True
return False
def stackperm(x):
ans = list(permutations(x, len(x)))
for i in ans:
if (checkStack(x, i, len(x))):
yield list(i)
# 連同下面程式上載至e-tutor
x = input().split(',')
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
### 修飾器
##### **題目說明**
製作修飾器@pretty,讓函式f1的輸出字串首尾會自動加上$記號。
```python
@pretty
def f1():
return 'f1'
print(f1())
```
```python
#上載至e-tutor
def pretty():#自行加上必要參數
...
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
def pretty(func): # 自行加上必要參數
def add():
return "$"+func()+"$"
return add
# 連同下面程式上載至e-tutor
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
## 主題6
### 依據檔案大小搜尋檔案
##### **題目說明**
寫一個generator, 其名稱及參數定如下:
def list_file_by_size(directory, n)
列出此目錄directory(包含子目錄)下所有檔案或目錄大小>=n bytes的完整檔案名稱(包含檔案路徑)。
輸入參數:目錄directory,及檔案大小n整數。
Return: yield (full_file_name, filesize)
Hint: os.walk, os.path.getsize
full_file_name指的是不管那個檔案是否和程式在同個目錄下,只要給full_file_name就可以找到它,即是:os.path.exists(full_file_name)為True。
如果在Windows以下面程式片段測試會顯示類似下面結果
for f in list_file_by_size("c:\\users",1000000):
printf(f)
...
('c:\\users\\adm\\.conda\\envs\\tf-gpu\\Library\\bin\\cublas64_10.dll', 64257536)
....
```python
上載程式請依照下面範例:
注意:
1.不要有任何輸出訊息
2.不要有任何輸入指令
3.最後一定要有藍色程式片段
#只擺入你的list_file_by_size
import 必要模組
def list_file_by_size(directory, n):
....
#你上載的程式最後要包含下面幾行,用於檢查list_file_by_size(directory, n)正確性。
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
import os
from os.path import join, getsize
def list_file_by_size(directory, n):
for root, dirs, files in os.walk(directory):
for file_name in files:
file_name=join(root,file_name) #路徑+名字
filesize=getsize(file_name)#檔案大小
if filesize>=n:
yield (file_name, filesize)
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
---
### Datetime
##### **題目說明**
寫一個程式輸入兩個時間格式為yyyy-mm-dd hh:mm:ss,計算他們
(a)差幾天,幾秒;
(b)差幾秒。
Hint: 使用datetime.datetime.strptime, timedelta.total_seconds()
例如
t1='2017-11-18 17:05:31'
t2='2013-11-18 17:05:31'
相差1461天
相差126230400秒
注意:由於datetime.timedelta表示時間差距會根據下面原則正規化
days, seconds and microseconds are normalized so that the representation is unique, with
* 0 <= microseconds < 1000000
* 0 <= seconds < 3600*24 (the number of seconds in one day)
* -999999999 <= days <= 999999999
因此這題計算時要求以較晚的時間-較早的時間。
##### **程式碼參考**
```python=
import datetime
s1=str(input())
s2=str(input())
t1=datetime.datetime.strptime(s1,"%Y-%m-%d %H:%M:%S")
t2=datetime.datetime.strptime(s2,"%Y-%m-%d %H:%M:%S")
d=t2-t1
print(d.days,d.seconds)
print(int(d.total_seconds()))
```
##### **測資**
輸入
2500-1-11 1:1:0
2500-1-12 1:1:1
輸出
1 1
86401
---
## 主題7
### Rectangle
##### **題目說明**
設計一個滿足下面操作的Rectangle class
1. rect = Rectangle(x0,y0,width,height)可建構一個涵蓋(x0,y0)-(x0+width,y0+height)的矩形
2. 使用@property製作rectangle.area計算其面積
rect2=Rectangle(x1,y1,width2,height2)
3. rect3=rect1 | rect2 #rect3為涵蓋包含rect1與rect2區域的最小矩形
4. rect4=rect1 & rect2#rect4為剛好涵蓋rect1與rect2重疊區的矩形
5. override member function str使得print(rect1) #會顯示Rectangle: (x0,y0)-(x0+width,y0+height)
6. rect == eval(repr(rect)) #為True
**使用範例:**
#1
rect1 = Rectangle(0,0,10,10)
rect2 = Rectangle(10,10,10,10)
#2
print(rect1.area)
#3
rect3 = rect1 | rect2
print(rect3)
#4
rect4 = rect1 & rect2
print(rect4)
#5
print(rect1)
#6
print(rect1==eval(repr(rect1)))
**使用範例輸出:**
#2輸出:
100
#3輸出:
Rectangle: (0,0)-(20,20)
#4輸出:
Rectangle: (10,10)-(10,10)
#5輸出:
Rectangle: (0,0)-(10,10)
#6輸出:
True
**上載至e-tutor程式樣板**
```python
# class Rectangle定義
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
# class Rectangle定義
import sys
class Rectangle:
def __init__(self, x0, y0, width, height):
self.x0 = x0
self.y0 = y0
self.width = width
self.height = height
def __or__(self, other):
x1 = self.x0+self.width
y1 = self.y0+self.height
x2 = other.x0+other.width
y2 = other.y0+other.height
return Rectangle(min(self.x0, other.x0), min(self.y0, other.y0), max(x1, x2), max(y1, y2))
def __and__(self, other):
x1 = self.x0+self.width
y1 = self.y0+self.height
x2 = other.x0+other.width
y2 = other.y0+other.height
if x1 <= x2 and x1 >= other.x0 and y1 <= y2 and y1 >= other.y0:
xx = (x1-(max(self.x0, other.x0)))
yy = (y1-(max(self.y0, other.y0)))
return Rectangle(max(self.x0, other.x0), max(self.y0, other.y0), xx, yy)
elif x2 <= x1 and x2 >= self.x0 and y2 <= y1 and y2 >= self.y0:
xx = (x2-(max(self.x0, other.x0)))
yy = (y2-(max(self.y0, other.y0)))
return Rectangle(max(self.x0, other.x0), max(self.y0, other.y0), xx, yy)
elif x1 <= x2 and x1 >= other.x0 and self.y0 <= y2 and self.y0 >= other.y0:
return Rectangle(other.x0, self.y0, x1-other.x0, y2-self.y0)
elif x2 <= x1 and x2 >= self.x0 and other.y0 <= y1 and other.y0 >= self.y0:
return Rectangle(self.x0, other.y0, x2-self.x0, y1-other.y0)
else:
return 0
def __eq__(self, other):
if self.x0 == other.x0 and self.y0 == other.y0 and self.width == other.width and self.height == other.height:
return True
else:
return False
def __repr__(self):
return "Rectangle("+str(self.x0)+","+str(self.y0)+","+str(self.width)+","+str(self.height)+")"
def __str__(self):
return "Rectangle: ("+str(self.x0)+","+str(self.y0)+")-("+str(self.x0+self.width)+","+str(self.y0+self.height)+")"
@property
def area(self):
return self.width*self.height
# 連同下面程式上載至e-tutor
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
### Duck typing
##### **題目說明**
設計函式distance(p1,p2)只要物件p1與p2有x,y屬性,就可以根據公式((p1.x-p2.x)**2+(p1.y-p2.y)**2)**0.5計算其距離,否則拋出AttributeError例外。
```python
#
def distance(p1,p2):
#...
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
def distance(p1, p2):
try:
return ((p1.x-p2.x)**2+(p1.y-p2.y)**2)**0.5
except AttributeError:
raise AttributeError()
# 連同下面程式上載至e-tutor
cmd = ''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd, 'default', 'exec')
exec(p)
```
---
### 製作__Iter__
##### **題目說明**
製做一個class myChain。你必須override `__iter__` (or `__iter__` + `__next__`)達到下面功能。
```python
a = myChain([1,2,3],[4,5,6],[],[6,7,8])
for i in a:
print(i)
```
會輸出
1
2
3
4
5
6
6
7
8
**上載至e-tutor的程式**
```
#你的程式
class myChain:
# ....
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
##### **程式碼參考**
```python=
class Node:
def __init__(self ,data=None, next=None):
self.data = data
self.next = next
class myChain:
def __init__(self,*num):
self.head = None
self.next=None
self.tail=None
for i in num:
for j in i:
self.insert_head(j)
def insert_head(self,data):
now = Node(data)
if self.head==None:
self.head=now
self.tail=now
else:
self.tail.next = now
self.tail = self.tail.next
def __iter__(self):
self.iter_p=self.head
return self
def __next__(self):
if self.iter_p is None:
raise StopIteration
else:
now=self.iter_p
self.iter_p=self.iter_p.next
return now.data
# 連同下面程式上載至e-tutor
cmd =''
while True:
try:
s = input()
cmd += s+'\n'
except EOFError:
break
p = compile(cmd,'default','exec')
exec(p)
```
---
## 主題8
### 找出整數並計算總合
##### **題目說明**
請使用re寫出一個程式,其輸入一個字串,並可以正確計算如下字串裡()內整數總和。注意:若數字每千分位有',',那麼就要符合千分位格式
`s='(1,234)5678(123)987(100,888,909)'`
總和為:100890266
`s='(1,234)5678(123)987(100,8888,909)'`
總和為:1357
##### **程式碼參考**
```python=
import re
s = input()
reg = r'[(]{1}([+-]?\d{1,3}(,\d{3})*)[)]{1}'
ans = 0
for m in re.finditer(reg, s):
s = m.group()
s = s.replace('(', '')
s = s.replace(')', '')
s = s.replace(',', '')
ans += int(s)
print(ans)
```
##### **測資0**
輸入
(1,234)5678(123)987(100,888,909)
輸出
100890266
##### **測資1**
輸入
(1,234)5678(123)987(100,8888,909)
輸出
1357
---
### 計算牲畜數目
##### **題目說明**
使用re輸入如下字串,
`'大雄有3隻羊2條狗,小明有狗3隻雞2隻,小花有1頭牛3隻豬2隻雞狗5條。'`
抽取出相關資訊來計算大雄、小明、小花共有幾隻羊、狗、雞、豬、牛(照順序輸出)。
##### **程式碼參考**
```python=
import re
s = input()
reg = re.compile(r'((\d)+[隻條頭][羊狗雞豬牛])|([羊狗雞豬牛](\d)+[隻條頭])')
animal = re.compile(r'[羊狗雞豬牛]')
cnt = re.compile(r'(\d)+')
d = {'羊': 0, '狗': 0, '雞': 0, '豬': 0, '牛': 0}
for m in re.finditer(reg, s):
st = m.group()
i = re.search(cnt, st).group()
ani = re.search(animal, st).group()
d[ani] += int(i)
for i in d:
print(str(i)+':'+str(d.get(i)))
```
##### **測資**
輸入
大雄有3隻羊2條狗,小明有狗3隻雞2隻,小花有1頭牛3隻豬2隻雞狗5條。
輸出
羊:3
狗:10
雞:4
豬:3
牛:1
---