【CS50 學習筆記】week6 — Python
Python
python 相較於 c 語言是一個 higher-level 的程式語言,意思是它更容易理解和使用,所以很多人自學程式語言最好入門的都會是高階語言,例如到了python,不需要做記憶體的 allocate 和 free,因為底層它會幫你做好,但因為是拿別人做好的東西拿來用,裡面有些程式你其實不需要跑,所以速度上會有所犧牲,順帶一提,python 是由 c 語言編寫的,因此 python 可以做到的事,c 語言都能做到。
Speller
在上一週的 speller 作業若用 python 編寫如下,可以發現少了好幾行,但在執行上會比 C 更慢跑出結果。
# Words in dictionary
words = set()
def check(word):
"""Return true if word is in dictionary else false"""
if word.lower() in words:
return True
else:
return False
def load(dictionary):
"""Load dictionary into memory, returning true if successful else false"""
file = open(dictionary, "r")
for line in file:
word = line.rstrip()
words.add(word)
file.close()
return True
def size():
"""Returns number of words in dictionary if loaded else 0 if not yet loaded"""
return len(words)
def unload():
"""Unloads dictionary from memory, returning true if successful else false"""
return True
Types & Variables
在 python 很常使用的 type 如下,可以發現在 c 語言有的 long
和 double
不見了,因爲 python 會自動判斷該輸入的值來賦予相對應的 type。
bool
float
int
str
range
list
tuple
dict
set
以下為宣告變數的差異,python 不用在變數前面宣告 type
c 語言:
int counter = 1
python:
counter += 1
Loops & Functions
在 c 可以這樣寫迴圈
// Demonstrates while loop
#include <stdio.h>
int main(void)
{
int i = 0;
while (i < 3)
{
printf("meow\n");
i++;
}
}
在 python 則省略 main 、int 變數以及大括弧 {}
# Demonstrates while loop
i = 0
while i < 3:
print("meow")
i += 1
也可以用 for 迴圈
# Better design
for i in range(3):
print("meow")
可以透過 def
來宣告函式
# Abstraction with parameterization
def main():
meow(3)
# Meow some number of times
def meow(n):
for i in range(n):
print("meow")
main()
Calculator
在使用 python 來計算輸入的值時,需注意應將 input 的值透過 int
轉換成該變數型態再進行加減乘除,否則編譯器會認為那是字串,而 python 也如同 c 語言會遇到 floating-point imprecision 的問題,例如:2/3 應該是 0.666666666666…
,但剛剛說的 imprecision 的問題是電腦無法用有限的記憶體儲存無限的小數點,因此透過以下印出小數點後 50 位數即可發現結果是 0.66666666666666662965923251249478198587894439697266
,這樣的情況可以透過 round 等其他函式來進行四捨五入。
# Prompt user for x
x = int(input("x: "))
# Prompt user for y
y = int(input("y: "))
# Divide x by y
z = x / y
print(f"{z:.50f}")
Object-Oriented Programming
在 c 語言我們透過 struct
來宣告一個可以包含多個 type 的物件,而在 python 我們也可以這樣來宣告,但 default 就已經有一些好用的物件,如 str
我們就可以用它裡面的函式來操作變數。像是以下:s 這個變數就是一個 str
物件,可以使用 lower()
這個函式來轉變變數成小寫形式。
# Logical operators, using lists
from cs50 import get_string
# Prompt user to agree
s = get_string("Do you agree? ")
s = s.lower()
# Check whether agreed
if s in ["y", "yes"]:
print("Agreed.")
elif s in ["n", "no"]:
print("Not agreed.")
Mario
若我們想透過 # 印出如 mario 場景中的方塊該怎麼做?
以下可以做到, print(“#”)
後預設會換行,因此呈現會是直的。
# Prints a column of bricks, catching exceptions
def main():
height = get_height()
for i in range(height):
print("#")
def get_height():
while True:
try:
n = int(input("Height: "))
if n > 0:
return n
except ValueError:
print("Not an integer")
main()
但今天想印出橫的如 ####
該怎麼做,因為 print 是預設換行,因此要給予一個 end
告訴它 print 完不要換行,最後迴圈完再透過一個print()
來換行。
# Prints a column of bricks, catching exceptions
def main():
height = get_height()
for i in range(height):
print("#", end="") # 結果會是橫的 ####
print()
def get_height():
while True:
try:
n = int(input("Height: "))
if n > 0:
return n
except ValueError:
print("Not an integer")
main()
也可以直接透過 *
來達成
print("#" * 4)
Command-line arguments.
可以透過 sys 來印出 command-line arguments
# Printing command-line arguments, indexing into argv
from sys import argv
for i in range(len(argv)):
print(argv[i])
也可以透過 sys 的函式來做到一些事,例如 argv 來得到 arguments 的長度,透過 exit 來結束程式。
import sys
if len(sys.argv) != 2:
print("Missing command-line argument")
sys.exit(1)
print(f"hello, {sys.argv[1]}")
sys.exit(0)
Search
在高階語言的 search 在底層會透過最有效率的搜尋法來儲存、提取搜尋資料,如 hash table 或是符合那個資料大小的搜尋法,在 python 就是透過 in 來做搜尋。
# Implements linear search for names
import sys
# A list of names
names = ["Bill", "Charlie", "Fred", "George", "Ginny", "Percy", "Ron"]
# Ask for name
name = input("Name: ")
# Search for name
for n in names:
if n == name:
print("Found")
sys.exit(0)
print("Not found")
sys.exit(1)
CSV
可以透過 csv 的套件來處理 csv 檔案,新增寫入等等,若透過 DictWriter 的話則可以清楚的描述輸入的值應該塞到哪個 column name。
# Saves names and numbers to a CSV file using a DictWriter
import csv
# Get name and number
name = input("Name: ")
number = input("Number: ")
# Open CSV file
with open("phonebook.csv", "a") as file:
# Print to file
writer = csv.DictWriter(file, fieldnames=["name", "number"])
writer.writerow({"name": name, "number": number})
小結:
python 確實相較於 c 語言是個更快上手程式語言,我一開始也是從 python 開始自學,但當初就是知其然而不知其所以然,若是時間允許了解 c 語言也能更了解程式為什麼會跑的慢,為什麼 google 這間公司還是會希望找到會寫 c 語言的工程師。