Stanford Python程式課 - 第五週
第五週學習目標
Code in Place 第五週課程 Lesson 12: Dictionaries |
Lesson 12: Dictionaries 字典
學習重點
- “None” - Python 用來代表 “no value”、
- 創建、使用、修改字典 Dictionary
- Dictionary 是 CodeinPlace 課程中最後學習的變數
Dictionaries associate a key with a value
- Key: 獨一無二的指標
- Value: 與 key 關聯的內容
YouTube課程影片
Lecture 12-1: Intro
Lecture 12-2: Dictionaries
Lecture 12-3: Adding to dictionaries
Lecture 12-4: Dictionaries are mutable
Lecture 12-5: Dictionary functions
Lecture 12-6: count_characters.py
Lecture 12-7: phone_book.py
點我下載課程講義
延伸閱讀Python Reader
點我到 Dictionaries 課程程式範例
Lesson 13: Files 檔案
學習重點:
- 學習讀寫檔案
- 了解如何從檔案產生視覺化資料
- 學習 csv、json libraries
YouTube課程影片
Lecture 13-1: Introduction
Lecture 13-2: What's a File?
Lecture 13-3: Reading and Writing Files
Lecture 13-4: Data Visualization
Lecture 13-5: Smarter Files
點我下載課程講義
延伸閱讀Python Reader
點我到 Files 程式範例
Lesson 14: Data Science 資料科學
學習重點:
- 練習運用字典、清單、資料解決一些有趣的問題
- 終極 CS106A 問題 - 如何將一個字典反向?
- 為何 Google 搜尋這麼快速?答案在最後一個影片
Google 搜尋快速是因為用了 Dictionary 架構 |
YouTube課程影片
Lecture 14-1: Introduction
Lecture 14-2: Review
Lecture 14-3: Ultimate CS106A
Lecture 14-4: Ed forum (為何 Google 搜尋這麼快?)
點我下載課程講義
延伸閱讀Python Reader
點我到 Data Science 程式範例
未完待續 ...
Dictionaries 程式範例
birthday.py
""" File: birthday.py ----------------- Program to show an example of using dictionaries with functions. """ def have_birthday(dict, name): """ Print a birthday message and increment the age of the person with the given name in the dictionary passed in. """ print("You're one year older, " + name + "!") dict[name] += 1 def main(): ages = {'Chris': 33, 'Julie': 22, 'Mehran': 50} print(ages) have_birthday(ages, 'Chris') print(ages) have_birthday(ages, 'Mehran') print(ages) # Python boilerplate. if __name__ == '__main__': main()
count_characters.py
""" File: count_characters.py ------------------------- This program counts the number of each character in the string TEXT. It uses a dictionary to store the results, where each key is a character and the corresponding value is the number of times that character appeared in the string. """ TEXT = 'Happy day! I love the Code in Place community!' def get_counts_dict(str): """ Returns a dictionary with where each key is a character and the corresponding value is the number of times that character appeared in the string str passed in. """ counts = {} # create empty dictionary for ch in str: if ch not in counts: counts[ch] = 1 else: counts[ch] += 1 return counts def print_counts(dict): """ This function prints out the key and its associated value for each key/value pair in the dictionary passed in. """ print('Counts from dictionary') for key in dict: print(str(key) + ' = ' + str(dict[key])) def main(): """ Display the number of times each character appears in the constant TEXT. """ count_dict = get_counts_dict(TEXT) print('count_dict = ', count_dict) print_counts(count_dict) # Python boilerplate. if __name__ == '__main__': main()
phonebook.py
""" File: phonebook.py ------------------ Program to show an example of using dictionaries to maintain a phonebook. """ def read_phone_numbers(): """ Ask the user for names/numbers to story in a phonebook (dictionary). Returns the phonebook. """ phonebook = {} # Create empty phonebook while True: name = input("Name: ") if name == "": break number = input("Number: ") phonebook[name] = number return phonebook def print_phonebook(phonebook): """ Prints out all the names/numbers in the phonebook. """ for name in phonebook: print(name, "->", phonebook[name]) def lookup_numbers(phonebook): """ Allow the user to lookup phone numbers in the phonebook by looking up the number associated with a name. """ while True: name = input("Enter name to lookup: ") if name == "": break if name not in phonebook: print(name + " is not in the phonebook") else: print(phonebook[name]) def main(): phonebook = read_phone_numbers() print_phonebook(phonebook) lookup_numbers(phonebook) # Python boilerplate. if __name__ == '__main__': main()
Files 程式範例
plot_country.py:
各個城市的CSV檔可以在這邊下載 https://simplemaps.com/data/world-cities
# don't worry about this import! It just allows us to grab all the files in the countries/ directory import os from simpleimage import SimpleImage # Dimensions of the final visualization. Change these if the # image is too large for your screen VISUALIZATION_WIDTH = 1920 VISUALIZATION_HEIGHT = 1080 # Setting the 'boundaries' for the visualization. By default, the # visualization holds the entire world. If you want to zoom in on a # specific country, you can find the corresponding latitudes and longitudes # here: https://gist.github.com/graydon/11198540 MIN_LONGITUDE = -180 MAX_LONGITUDE = 180 MIN_LATITUDE = -90 MAX_LATITUDE = 90 # The folder in which all the country data can be found COUNTRY_DIRECTORY = "countries/" def plot_country(visualization, filename): """ Responsible for reading in geographic data from a file about the cities in a particular country and plotting them in the visualization. Parameters: - `visualization` is the SimpleImage that will eventually be shown to the user - `filename` is the file we want to read through """ # TODO fill me in! with open(filename) as f: next(f) for line in f: line = line.strip() parts = line.split(",") latitude = float(parts[1]) longtitude = float(parts[2]) plot_one_city(visualization, latitude, longtitude) """ DO NOT MODIFY THE CODE BELOW (but you're welcome to read it 😀 ) """ def main(): # create a blank image on which we'll plot cities visualization = SimpleImage.blank( VISUALIZATION_WIDTH, VISUALIZATION_HEIGHT ) # get which countries should be plotted from the user countries = get_countries() # iterate through each of the countries and plot it for country in countries: country_filename = COUNTRY_DIRECTORY + country + ".csv" plot_country(visualization, country_filename) # once we're done with all the countries, show the image visualization.show() def get_countries(): """ Gets the list of countries from the user, but doesn't check that the user types in valid country names. Returns a list of country names """ countries = [] while True: country = input("Enter a country, or 'all'. Press enter to finish: ") if country == "": break if country == "all": # don't worry about this bit of code! It just looks inside # `COUNTRY_DIRECTORY` and returns a list of all the filenames return [s.split(".")[0] for s in os.listdir(COUNTRY_DIRECTORY)] # if the user didn't press enter immediately or type all, # store the country name # Add this line so country name of lower case will also work country = country.title() countries.append(country.strip()) return countries def plot_one_city(visualization, latitude, longitude): """ Given the visualization image as well as a single city's latitude and longitude, plot the city on the image Parameters: - `visualization` is the SimpleImage that will eventually be shown to the user - `latitude` is the latitude of the city (a float) - `longitude` is the longitude of the city (a float) """ # convert the Earth coordinates to pixel coordinates x = longitude_to_x(longitude) y = latitude_to_y(latitude) # if the pixel is in bounds of the window we specified through constants, # plot it if 0 < x < visualization.width and 0 < y < visualization.height: plot_pixel(visualization, x , y) def plot_pixel(visualization, x, y): """ Set a pixel at a particular coordinate to be blue. Pixels start off as white, so all three color components have a value of 255. Setting the red and green components to 0 makes the pixel appear blue. Note that we don't return anything in this function because the Pixel is 'mutated' in place Parameters: - `visualization` is the SimpleImage that will eventually be shown to the user - `x` is the x coordinate of the pixel that we are turning blue - `y` is the y coordinate of the pixel that we are turning blue """ pixel = visualization.get_pixel(x, y) pixel.red = 0 pixel.green = 0 def longitude_to_x(longitude): """ Scales a longitude coordinate to a coordinate in the visualization email """ return VISUALIZATION_WIDTH * (longitude - MIN_LONGITUDE) / (MAX_LONGITUDE - MIN_LONGITUDE) def latitude_to_y(latitude): """ Scales a latitude coordinate to a coordinate in the visualization email """ return VISUALIZATION_HEIGHT * (1.0 - (latitude - MIN_LATITUDE) / (MAX_LATITUDE - MIN_LATITUDE)) if __name__ == "__main__": main()
write_example.py:
""" Example of using library to write CSV """ import csv def write_data(): with open("data.csv", "w") as f: writer = csv.writer(f) writer.writerow(["x", "y"]) writer.writerows([ [1,2], [2,4], [4,6] ]) def main(): write_data() if __name__ == "__main__": main()
dictwriter_example.py:
""" Example of using dictionary to write CSV """ import csv def write_data(): with open("data.csv", "w") as f: columns = ['x', 'y'] writer = csv.DictWriter(f, fieldnames=columns) writer.writeheader() writer.writerow({'x': 1, 'y': 2}) writer.writerow({'x': 2, 'y': 4}) writer.writerow({'x': 4, 'y': 6}) def main(): write_data() if __name__ == "__main__": main()
Data 程式範例
ed_small.json (資料檔) :
[ { "created_at": "2021-05-21T01:20:39.296044+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-21T01:21:25.225994+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "admin" } }, { "created_at": "2021-05-21T01:18:55.160661+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-21T01:29:58.2526+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-21T01:02:48.854092+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-20T23:57:12.340442+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-20T23:40:06.718832+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-21T00:21:04.357038+10:00", "votes": 0, "user": { "name": "Anonymous", "role": "" } }, { "created_at": "2021-05-21T00:11:00.373241+10:00", "votes": 1, "user": { "name": "Anonymous", "role": "admin" } }, { "created_at": "2021-05-20T23:18:03.604335+10:00", "votes": 1, "user": { "name": "Anonymous", "role": "" } } ]
post_times.py:
# for loading files with nested data import json # for turning strings into dates from dateutil import parser from pytz import timezone # for making pretty graphs import seaborn as sns import matplotlib.pyplot as plt def main(): ed_data = json.load(open('ed_small.json')) hour_counts = {} for hour in range(24): hour_counts[hour] = 0 for post in ed_data: timestamp = post['created_at'] hour = get_hour(timestamp) hour_counts[hour] += 1 print('day, n_posts') for hour in range(24): n_posts = hour_counts[hour] print(hour, n_posts) make_bar_plot(hour_counts) def get_hour(time_string): """ Given a time string, returns the day of the week (in pacific time). >>> get_hour('2021-05-21T01:20:39.296044+10:00') 'Thu' """ date_time = parser.parse(time_string) # change to my timezone date_time = date_time.astimezone(timezone('US/Pacific')) # get the hour out of the time object return date_time.hour def make_bar_plot(count_map): """ Turns a dictionary (where values are numbers) into a bar plot. Labels gives the order of the bars! Uses a package called seaborn for making graphs. """ # turn the counts into a list counts = [] # loop over the labels, in order for label in count_map: counts.append(count_map[label]) # format the data in the way that seaborn wants data = { 'x':list(count_map.keys()), 'y':counts } sns.barplot(x = 'x',y = 'y', data= data) plt.savefig("plot.png") if __name__ == '__main__': main()
student_to_staff.py:
# for loading files with nested data import json def main(): # load the dataa ed_data = json.load(open('ed_small.json')) n_teacher_posts = 0 # loop over each post in the list for post in ed_data: # get the role of the author of the post role_str = post['user']['role'] # if the post came from a teacher if role_str == 'tutor' or role_str == 'admin': # increase the count n_teacher_posts += 1 # show the fraction of posts from teachers n_posts = len(ed_data) print(n_teacher_posts / n_posts) if __name__ == '__main__': main()
0 comments