兩週學會Python 第01天(上午)
阿新 • • 發佈:2019-02-03
目標: 熟悉Python程式碼,入門簡單的演算法題
學習知識點:
- 資料型別:
– integral:
– int
– bool
– 浮點
– 字串 - 組合型別:
– 序列型別
– 集合型別
– 對映型別
1. 學習程式碼示例:
quadratic.py 求一元二次方程的解
執行效果:
import cmath
import math
import sys
#控制輸入浮點數
def get_float(msg,allow_zero):
x = None
while x is None:
try:
x = float(input(msg))
if not allow_zero and abs(x) < sys.float_info.epsilon:
print("zero is not allowed")
x = None
except ValueError as err:
print(err)
return x
#獲取三個引數
print("ax\N{SUPERSCRIPT TWO} + bx + c = 0" )
a = get_float("enter a: ", False)
b = get_float("enter b: ", True)
c = get_float("enter c: ", True)
#求解方程
x1 = None
x2 = None
discriminant = (b ** 2) - (4 * a *c)
if discriminant == 0:#方程只有一個解
x1 = -(b / (2*a))
else:
if discriminant > 0:#方程有實數解
root = math.sqrt(discriminant)
else : #discriminant < 0 方程有複數解
root = cmath.sqrt(discriminant)
x1 = (-b + root)/(2 * a)
x2 = (-b - root)/(2 * a)
#控制輸出
equation = ("{a}x\N{SUPERSCRIPT TWO}{b:+}x{c:+} = 0 " "\N{RIGHTWARDS ARROW} x={x1}").format(**locals())
if x2 is not None:
equation += "or x = {0}".format(x2)
print(equation)
cvs2html.py 將csv資料集轉換為html
執行結果:
import sys
def main():
#文字最大寬度
maxwidth = 10
#輸出html開始部分
print_start()
count = 0
#輸出資訊部分
while True:
try:
line = input()
if count == 0:
color = "lightgreen"
elif count % 2:
color = "white"
else:
color = "lightyellow"
print_line(line,color,maxwidth)
count += 1
except EOFError:#通過ctrl+d來終止程式
break
#輸出html結束部分
print_end()
def print_start():
print("<table border='1'>")
def print_line(line,color,maxwidth):
print("<tr bgcolor='{}'>".format(color))
fields = extract_fields(line)
for field in fields:
if not field:
print("<td></td>")
else:
#number = field.replace(",","")
number = field
try:
x = float(number)#如果是數字
print("<td align='right'>{:d}</td>".format(round(x)))
except ValueError:#否則為單詞
field = field.title()#將首字母變為大些,其他字母變小寫
field = field.replace("And","and")#將And替換為and
if len(field) <= maxwidth:#如果字串長度在規定長度內
field = escape_html(field)
else:
field = "{}...".format(escape_html(field[:maxwidth]))#擷取maxwidth長度內的子串
print("<td>{}</td>".format(field))
print("</tr>")
def extract_fields(line):
fields = []
field = ""
quote = None
#"ARGE'N'TINA",37,35,33,36,39
for c in line:
if c in "\"'":
if quote is None:#獲取第一個字元 "
quote = c
elif quote==c:#獲取第一個字串 結束字元 "
quote = None
else:#獲取中間字元 ' '
field += c
continue
if quote is None and c==",":#字串的結尾處,將獲得的字串新增至fields
fields.append(field)
field = ""
else:#獲取中間字元,比如:ARGENTINA 37 35 33 36 39
field += c
if field:#最後一個字串
fields.append(field)
#最後的fields是: [ARGE'N'TINA,37,35,33,36,39]
return fields
#替換特殊字元
def escape_html(text):
text = text.replace("&","&")
text = text.replace("<","<")
text = text.replace(">","&g")
return text
def print_end():
print("</table>")
main()
generate_usernames.py 為組織內的每個員工生成使用者名稱
設定執行引數:
執行結果:
import sys
import collections
#定義5個常量
ID,FORENAME,MIDDLENAME,SURNAME,DEPARTMENT = range(5)
#定義User類
User = collections.namedtuple("User","username forename middlename surname id")
def generate_username(fields, usernames):
#取三個欄位的部分和
username = ((fields[FORENAME][0] + fields[MIDDLENAME][:1] + fields[SURNAME]).replace("-","").replace("'",""))
username = orginal_name = username[:8].lower()
count = 1
#如果出現重名,則在後面的尾數加一
while username in usernames:
username = "{0}{1}".format(orginal_name,count)
#將username新增到usernames
usernames.add(username)
return username
def process_line(line, usernames):
#按冒號切割成單個欄位
fields = line.split(":")
#計算username
username = generate_username(fields,usernames)
#構建user物件
user = User(username,fields[FORENAME],fields[MIDDLENAME],fields[SURNAME],fields[ID])
return user
#列印users
def print_user(users):
namewidth = 32
usernamewidth = 9
print("{0:<{nw}}{1:^6}{2:{uw}}".format("Name","ID","Username",nw=namewidth,uw=usernamewidth))
print("{0:-<{nw}}{0:-<6}{0:-<{uw}}".format("",nw=namewidth,uw=usernamewidth))
for key in sorted(users):
user = users[key]
initial = ""
if user.middlename:
initial = " "+user.middlename[0]
name = "{0.surname},{0.forename}{1}".format(user,initial)
print("{0:.<{nw}}({1.id:4}){1.username:{uw}}".format(name,user,nw=namewidth,uw=usernamewidth))
def main():
#輸入引數檢測
if len(sys.argv)==1 or sys.argv[1] in {"-h","help"}:
print("usage:{0} file1 [file2 [...fileN]]".format(sys.argv[0]))
sys.exit()
#使用者名稱集合
usernames = set()
#使用者map
users = {}
#遍歷所有輸入
for line in sys.argv[1:]:
line = line.rstrip()
if line:
#將一行資訊轉為user物件
user = process_line(line,usernames)
#將(user.surname.lower(),user.forename.lower(),user.id) ,user存入users
users[(user.surname.lower(),user.forename.lower(),user.id)] = user
print_user(users)
main()
statistics.py 統計資訊,計算出count次數,mean平均數,median中位數,mode最高頻率數,std.dev.標準差
argv引數設定為 statistics_data
statistics_data檔案:
執行結果:
import math
import sys
import collections
#定義Statistics類
Statistics = collections.namedtuple("Statistics","mean mode median std_dev")
#讀取檔案,將數字存入number,將數字出現的次數存入frequencies
#越來越覺得Python像shell了
def read_data(filename, numbers, frequencies):
for lino,line in enumerate(open(filename,encoding="ascii"),start=1):
for x in line.split():
try:
number = float(x)
numbers.append(number)
frequencies[number] += 1
except ValueError as err:
print("{filename}:{lino}:skipping {x}:{err}".format(**locals()))
#計算中位數
def calcutale_median(numbers):
numbers = sorted(numbers)
middle = int(len(numbers)/2)
median = numbers[middle]
if len(numbers)%2==0:
median = (median + numbers[middle - 1])/2
return median
#計算標準差
def calcutale_std_dev(numbers, mean):
total = 0
for number in numbers:
total += ((number - mean)**2)
variance = total/(len(numbers) - 1)
return math.sqrt(variance)
#計算各項值
def calcutale_statistics(numbers,frequencies):
#求平均數
mean = sum(numbers)/len(numbers)
#求頻率最高的數
mode = calcutale_mode(frequencies,3)
#計算中位數
median = calcutale_median(numbers)
#計算標準偏差
std_dev = calcutale_std_dev(numbers,mean)
return Statistics(mean,mode,median,std_dev)
#計算頻率最高的資料
def calcutale_mode(frequencies,maximum_modes):
hightest_frequency = max(frequencies.values())
mode = [number for number,frequency in frequencies.items()
if frequency == hightest_frequency]
if not (1 <= len(mode) <= maximum_modes):
mode = None
else:
mode.sort()
return mode
#列印結果
def print_results(count,statistics):
real = "9.2f"
if statistics.mode is None:
modeline = ""
elif len(statistics.mode) == 1:
modeline = "mode ={0:{fmt}}\n".format(statistics.mode[0],fmt=real)
else:
modeline = ("mode =["+",".join(["{0:.2f}".format(m) for m in statistics.mode])+"]\n")
print("""
count ={0:6}
mean ={mean:{fmt}}
median ={median:{fmt}}
{1}\
std.dev. ={std_dev:{fmt}}
""".format(count,modeline,fmt=real,**statistics._asdict()))
def main():
#檢測引數
if len(sys.argv) == 1 or sys.argv[1] in {"-h","--help"}:
print("usage:{0} file1 [file2 [...fileN]]".format(sys.argv[0]))
sys.exit()
#數字集合
numbers = []
#數字頻率
frequencies = collections.defaultdict(int)
for filename in sys.argv[1:]:
read_data(filename,numbers,frequencies)
if numbers:
#統計
statistics = calcutale_statistics(numbers,frequencies)
#列印
print_results(len(numbers),statistics)
else:
print("no numbers found")
main()
小結
- abs(x) < sys.float_info.epsilon 判斷x是否是0
- float(x) 將x轉為float型別,類似有: int(x),hex(x),bin(x)等等
- print(“ax\N{SUPERSCRIPT TWO} + bx + c = 0”)特殊字元表示\N{…}
- b ** 2 計算b的平方,m ** n即m的n次方,如2 ** (1/2)等於2的平方根,注意負數哦!!!
- math.sqrt(x) x平方根 同理cmath.sqrt(x)複數級別的平方根
- fields.append(field)陣列新增元素
- 定義5個常量ID,FORENAME,MIDDLENAME,SURNAME,DEPARTMENT = range(5)
- User = collections.namedtuple(“User”,”username forename middlename surname id”)定義User類
- users[(user.surname.lower(),user.forename.lower(),user.id)] = user相當於java的map,左邊 集合名稱[key] = value
- 定義集合users = {}
- “,”.join([“{0:.2f}”.format(m) for m in statistics.mode]) ,遍歷statistics.mode,將每條結果通過”,”連線.
- mode = [number for number,frequency in frequencies.items()
if frequency == hightest_frequency] 定義一個數組,裡面存著number
下面的需要多練練,熟才能生巧:
- format()將本地引數轉為特定格式,這個需要多練練,才能靈活運用
- x.XXX()字串的一些方法
- Python可以將字串當做字元陣列來處理,比如遍歷 for c in x;又比如x[3],還有切片功能用來擷取字串
- len(),sorted()等等方法