1. 程式人生 > >兩週學會Python 第01天(上午)

兩週學會Python 第01天(上午)

目標: 熟悉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("&","&amp;")
    text = text.replace("<","&lt;")
    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()

小結

  1. abs(x) < sys.float_info.epsilon 判斷x是否是0
  2. float(x) 將x轉為float型別,類似有: int(x),hex(x),bin(x)等等
  3. print(“ax\N{SUPERSCRIPT TWO} + bx + c = 0”)特殊字元表示\N{…}
  4. b ** 2 計算b的平方,m ** n即m的n次方,如2 ** (1/2)等於2的平方根,注意負數哦!!!
  5. math.sqrt(x) x平方根 同理cmath.sqrt(x)複數級別的平方根
  6. fields.append(field)陣列新增元素
  7. 定義5個常量ID,FORENAME,MIDDLENAME,SURNAME,DEPARTMENT = range(5)
  8. User = collections.namedtuple(“User”,”username forename middlename surname id”)定義User類
  9. users[(user.surname.lower(),user.forename.lower(),user.id)] = user相當於java的map,左邊 集合名稱[key] = value
  10. 定義集合users = {}
  11. “,”.join([“{0:.2f}”.format(m) for m in statistics.mode]) ,遍歷statistics.mode,將每條結果通過”,”連線.
  12. mode = [number for number,frequency in frequencies.items()
    if frequency == hightest_frequency] 定義一個數組,裡面存著number

下面的需要多練練,熟才能生巧:

  1. format()將本地引數轉為特定格式,這個需要多練練,才能靈活運用
  2. x.XXX()字串的一些方法
  3. Python可以將字串當做字元陣列來處理,比如遍歷 for c in x;又比如x[3],還有切片功能用來擷取字串
  4. len(),sorted()等等方法