投資、科技、生活


Stanford Code in Place線上Python入門課程 - Week 5

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

點我到 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

    Python File Reading

點我到 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

    Nested Structures

點我到 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