【CS50 學習筆記】week6 — Python

Chengcheng Hsu
9 min readDec 10, 2023

--

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 語言有的 longdouble 不見了,因爲 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 語言的工程師。

--

--