Week 6 Python
ようこそ!
これまでの数週間で、プログラミングの基本的な構成要素を紹介してきました。
Cと呼ばれる低級プログラミング言語でのプログラミングについて学びました。
今日は、Pythonと呼ばれる高級プログラミング言語を扱っていきます。
この新しい言語を学ぶにつれて、自分自身で新しいプログラミング言語を学ぶ能力がさらに身についていくことに気づくでしょう。
Hello Python!
人間は数十年にわたって、以前のプログラミング言語で行われた設計上の決定をどのように改善できるかを見てきました。
Pythonは、すでにCで学んだことに基づいて構築されたプログラミング言語です。
さらに、Pythonはユーザーが作成した膨大な数のライブラリにアクセスできます。
Cのようなコンパイル言語とは異なり、Pythonはインタプリタ言語であり、プログラムを別途コンパイルする必要はありません。代わりに、Pythonインタプリタでプログラムを実行します。
これまでは、コードは次のようになっていました:
// A program that says hello to the world
#include
int main(void)
{
printf("hello, world\n");
}
- 今日、コードを書いてコンパイルするプロセスが簡素化されていることに気づくでしょう。
例えば、上記のコードはPythonでは次のように表現されます:
# A program that says hello to the world
print("hello, world")
セミコロンがなくなり、ライブラリも必要ないことに注目してください。ターミナルで python hello.py と入力することで、このプログラムを実行できます。
- Pythonは、Cでは非常に複雑だったことを比較的シンプルに実装できるのが特徴です。
Speller
このシンプルさを説明するために、ターミナルウィンドウで「code dictionary.py」と入力し、次のようにコードを書いてみましょう:
# Words in dictionary
words = set()
def check(word):
"""Return true if word is in dictionary else false"""
return word.lower() in words
def load(dictionary):
"""Load dictionary into memory, returning true if successful else false"""
with open(dictionary) as file:
words.update(file.read().splitlines())
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
上には4つの関数があることに注目してください。check 関数では、word が words の中にある場合、True を返します。Cでの実装よりもはるかに簡単です!同様に、load 関数では辞書ファイルが開かれます。そのファイルの各行について、その行を words に追加します。rstrip を使用して、追加された単語から末尾の改行が削除されます。size は単に words の len(長さ)を返します。unload は、Pythonが独自にメモリ管理を行うため、単に True を返すだけで済みます。
上記のコードは、なぜ高級言語が存在するのかを物語っています。それは、コードを簡素化し、より簡単に書けるようにするためです。
しかし、速度はトレードオフです。Cではプログラマであるあなたがメモリ管理に関する決定を下せるため、コードによってはPythonよりも高速に動作する場合があります。Cはコードの行のみを実行しますが、Pythonは組み込み関数を呼び出すときに、その背後にあるすべてのコードを実行します。
関数の詳細については、Pythonのドキュメントで学ぶことができます。
Filter
このシンプルさをさらに説明するために、ターミナルウィンドウで code blur.py と入力して新しいファイルを作成し、次のようにコードを書きましょう:
# Blurs an image
from PIL import Image, ImageFilter
# Blur image
before = Image.open("bridge.bmp")
after = before.filter(ImageFilter.BoxBlur(1))
after.save("out.bmp")
このプログラムは、PIL というライブラリから Image と ImageFilter モジュールをインポートしていることに注目してください。これは入力ファイルを受け取り、出力ファイルを作成します。
さらに、次のように edges.py という新しいファイルを作成できます:
# Finds edges in an image
from PIL import Image, ImageFilter
# Find edges
before = Image.open("bridge.bmp")
after = before.filter(ImageFilter.FIND_EDGES)
after.save("out.bmp")
このコードは blur のコードを少し調整したものですが、劇的に異なる結果を生み出すことに注目してください。
Pythonを使用すると、Cやその他の低級プログラミング言語でははるかに複雑になるプログラミングを抽象化できます。
関数
Cでは、次のような関数を見たことがあるでしょう:
printf("hello, world\n");
Pythonでは、次のような関数を目にすることになります:
print("hello, world")
ライブラリ、モジュール、パッケージ
- Cと同様に、PythonでもCS50ライブラリを利用できます。
特に以下の関数が役立ちます:
get_float
get_int
get_string
次のようにCS50ライブラリをインポートできます:
import cs50
また、次のようにCS50ライブラリから特定の関数のみをインポートすることもできます:
from cs50 import get_float, get_int, get_string
文字列
Cでは、このコードを覚えているかもしれません:
// get_string and printf with %s
#include
#include
int main(void)
{
string answer = get_string("What's your name? ");
printf("hello, %s\n", answer);
}
このコードはPythonでは次のように変換されます:
# get_string and print, with concatenation
from cs50 import get_string
answer = get_string("What's your name? ")
print("hello, " + answer)
ターミナルウィンドウで code hello.py を実行することで、このコードを書くことができます。その後、python hello.py を実行してこのコードを実行できます。+ 記号が "hello, " と answer をどのように連結しているかに注目してください。
同様に、連結なしでこれを行うこともできます:
# get_string and print, without concatenation
from cs50 import get_string
answer = get_string("What's your name? ")
print("hello,", answer)
print文は、hello の文と answer の間に自動的にスペースを作成することに注目してください。
同様に、上記のコードを次のように実装することもできます:
# get_string and print, with format strings
from cs50 import get_string
answer = get_string("What's your name? ")
print(f"hello, {answer}")
波括弧によって、print 関数がその中に answer が表示されるように answer を補間できることに注目してください。answer を適切にフォーマットして含めるには、f が必要です。
位置引数と名前付き引数
Cの
fread、fwrite、printfなどの関数は、引数をカンマで区切って指定する位置引数を使用します。プログラマであるあなたは、どの引数がどの位置にあるかを覚えておく必要があります。これらは位置引数と呼ばれます。Pythonでは、名前付き引数(名前付きパラメータ)を使用することで、位置に関係なく引数を指定できます。
print関数のパラメータの詳細については、ドキュメントで学ぶことができます。
そのドキュメントにアクセスすると、次のような記述が見つかるでしょう:
print(*objects, sep=' ', end='\n', file=None, flush=False)
さまざまなオブジェクトをprintに渡せることに注目してください。print に複数のオブジェクトが指定されたときに表示されるセパレータとして、1つのスペースが指定されています。同様に、print 文の最後には改行が指定されています。
変数
変数の宣言も簡素化されています。Cでは
int counter = 0;としていたかもしれませんが、Pythonでは同じ行がcounter = 0となります。変数の型を宣言する必要はありません。Pythonは1ずつインクリメントするために
counter += 1を好みます。Cにあるcounter++と書く機能はありません。
型
- Pythonのデータ型は、明示的に宣言する必要はありません。例えば、上記の
answerが文字列であることを見ましたが、インタプリタにそう伝える必要はありませんでした。インタプリタが自分で判断したのです。
Pythonでよく使われる型には以下のものがあります:
bool
float
int
str
long や double がないことに注目してください。Pythonは、大きな数や小さな数にどのデータ型を使用すべきかを自動的に処理します。
Pythonのその他のデータ型には以下のものがあります:
range 数値のシーケンス
list 可変値のシーケンス
tuple 不変値のシーケンス
dict キーと値のペアのコレクション
set 一意の値のコレクション
- これらのデータ型はどれもCで実装できますが、Pythonではより簡単に実装できます。
電卓
コースの最初の方で見た calculator.c を覚えているかもしれません:
// Addition with int
#include
#include
int main(void)
{
// Prompt user for x
int x = get_int("x: ");
// Prompt user for y
int y = get_int("y: ");
// Perform addition
printf("%i\n", x + y);
}
Cで行ったのと同じように、シンプルな電卓を実装できます。ターミナルウィンドウに code calculator.py と入力し、次のようにコードを書きましょう:
# Addition with int [using get_int]
from cs50 import get_int
# Prompt user for x
x = get_int("x: ")
# Prompt user for y
y = get_int("y: ")
# Perform addition
print(x + y)
CS50ライブラリがどのようにインポートされているかに注目してください。次に、x と y がユーザーから取得されます。最後に、結果が表示されます。Cプログラムで見られた main 関数が完全に消えていることに注目してください!main 関数を利用することも可能ですが、必須ではありません。
CS50ライブラリという補助輪を外すことも可能です。コードを次のように修正してください:
# Addition with int [using input]
# Prompt user for x
x = input("x: ")
# Prompt user for y
y = input("y: ")
# Perform addition
print(x + y)
上記のコードを実行すると、奇妙なプログラムの動作になることに注目してください。なぜでしょうか?
インタプリタが x と y を文字列として理解したと推測したかもしれません。次のように int 関数を採用することで、コードを修正できます:
# Addition with int [using input]
# Prompt user for x
x = int(input("x: "))
# Prompt user for y
y = int(input("y: "))
# Perform addition
print(x + y)
x と y の入力が int 関数に渡され、それが整数に変換される仕組みに注目してください。x と y を整数に変換しないと、文字が連結されてしまいます。
条件分岐
Cでは、このようなプログラムを覚えているかもしれません:
// Conditionals, Boolean expressions, relational operators
#include
#include
int main(void)
{
// Prompt user for integers
int x = get_int("What's x? ");
int y = get_int("What's y? ");
// Compare integers
if (x y)
{
printf("x is less than y\n");
}
else if (x > y)
{
printf("x is greater than y\n");
}
else
{
printf("x is equal to y\n");
}
}
Pythonでは、次のようになります:
# Conditionals, Boolean expressions, relational operators
from cs50 import get_int
# Prompt user for integers
x = get_int("What's x? ")
y = get_int("What's y? ")
# Compare integers
if x y:
print("x is less than y")
elif x > y:
print("x is greater than y")
else:
print("x is equal to y")
波括弧がなくなったことに注目してください。代わりに、インデントが利用されます。次に、if 文でコロンが利用されています。さらに、else if は elif に置き換わっています。if や elif 文では、括弧も不要になりました。
比較についてさらに詳しく見てみましょう。Cの以下のコードを考えてみてください:
// Logical operators
#include
#include
int main(void)
{
// Prompt user to agree
char c = get_char("Do you agree? ");
// Check whether agreed
if (c == 'Y' || c == 'y')
{
printf("Agreed.\n");
}
else if (c == 'N' || c == 'n')
{
printf("Not agreed.\n");
}
}
上記は次のように実装できます:
# Logical operators
from cs50 import get_string
# Prompt user to agree
s = get_string("Do you agree? ")
# Check whether agreed
if s == "Y" or s == "y":
print("Agreed.")
elif s == "N" or s == "n":
print("Not agreed.")
Cで利用されていた2本の垂直バーが or に置き換わっていることに注目してください。実際、Pythonは人間にとって読みやすいため好まれることが多いです。また、Pythonには char が存在しないことにも注目してください。代わりに str が利用されます。
同じコードに対する別のアプローチとして、リストを使用して次のようにすることもできます:
# Logical operators, using lists
from cs50 import get_string
# Prompt user to agree
s = get_string("Do you agree? ")
# Check whether agreed
if s in ["y", "yes"]:
print("Agreed.")
elif s in ["n", "no"]:
print("Not agreed.")
y や yes のような複数のキーワードを list で表現できることに注目してください。
オブジェクト指向プログラミング
特定の型の値が、その内部にプロパティや属性を持つだけでなく、関数も持つことができます。Pythonでは、これらの値はオブジェクトとして知られています。
Cでは、自分で作成した単一のデータ型の中に複数の変数を関連付けることができる
structを作成できました。Pythonでは、これに加えて、自分で作成したデータ型に関数を含めることもできます。関数が特定のオブジェクトに属している場合、それはメソッドとして知られています。
例えば、Pythonの str には組み込みのメソッドがあります。したがって、次のようにコードを修正できます:
# Logical operators, using lists
# Prompt user to agree
s = input("Do you agree? ").lower()
# Check whether agreed
if s in ["y", "yes"]:
print("Agreed.")
elif s in ["n", "no"]:
print("Not agreed.")
s の古い値が、str の組み込みメソッドである s.lower() の結果で上書きされていることに注目してください。
同様に、Cで文字列をコピーした方法を覚えているかもしれません:
// Capitalizes a copy of a string without memory errors
#include
#include
#include
#include
#include
int main(void)
{
// Get a string
char *s = get_string("s: ");
if (s == NULL)
{
return 1;
}
// Allocate memory for another string
char *t = malloc(strlen(s) + 1);
if (t == NULL)
{
return 1;
}
// Copy string into memory
strcpy(t, s);
// Capitalize copy
if (strlen(t) > 0)
{
t[0] = toupper(t[0]);
}
// Print strings
printf("s: %s\n", s);
printf("t: %s\n", t);
// Free memory
free(t);
return 0;
}
コードの行数に注目してください。
Pythonでは上記を次のように実装できます:
# Capitalizes a copy of a string
# Get a string
s = input("s: ")
# Capitalize copy of string
t = s.capitalize()
# Print strings
print(f"s: {s}")
print(f"t: {t}")
このプログラムがCの対応するプログラムよりもいかに短いかに注目してください。
この講義では、Pythonの表面をなぞるだけです。したがって、学習を進めるにあたって Pythonのドキュメント が特に重要になります。
文字列メソッドの詳細については、Pythonのドキュメントで学ぶことができます。
ループ
PythonのループはCと非常によく似ています。Cの以下のコードを覚えているかもしれません:
// Demonstrates for loop
#include
int main(void)
{
for (int i = 0; i 3; i++)
{
printf("meow\n");
}
}
for ループはPythonで次のように実装できます:
# Better design
for i in range(3):
print("meow")
i が明示的に使用されていないことに注目してください。しかし、Pythonは i の値をインクリメントします。
さらに、while ループは次のように実装できます:
# Demonstrates while loop
i = 0
while i 3:
print("meow")
i += 1
Pythonにおけるループと反復処理の理解を深めるために、次のように uppercase.py という新しいファイルを作成しましょう:
# Uppercases string one character at a time
before = input("Before: ")
print("After: ", end="")
for c in before:
print(c.upper(), end="")
print()
end= を使用して、行末なしで次の出力を続けるためのパラメータを print 関数に渡していることに注目してください。このコードは1文字ずつ渡しています。
ドキュメントを読むと、Pythonには文字列全体に対して次のように実装できるメソッドがあることがわかります:
# Uppercases string all at once
before = input("Before: ")
after = before.upper()
print(f"After: {after}")
.upper が文字列全体に適用されていることに注目してください。
抽象化
今日の前半で示唆したように、関数を使用し、さまざまなコードを関数に抽象化することで、コードをさらに改善できます。以前作成した meow.py のコードを次のように修正してください:
# Abstraction
def main():
for i in range(3):
meow()
# Meow once
def meow():
print("meow")
main()
meow 関数が print 文を抽象化していることに注目してください。さらに、main 関数がファイルの先頭にあることにも注目してください。ファイルの最後で、main 関数が呼び出されています。慣習として、Pythonでは main 関数を作成することが期待されています。
実際、次のように関数間で変数を渡すことができます:
# Abstraction with parameterization
def main():
meow(3)
# Meow some number of times
def meow(n):
for i in range(n):
print("meow")
main()
meow が変数 n を受け取るようになったことに注目してください。main 関数では、meow を呼び出して 3 のような値を渡すことができます。すると、meow は for ループの中で n の値を利用します。
上記のコードを読んで、Cプログラマであるあなたが上記のコードを非常に簡単に理解できることに注目してください。いくつかの慣習は異なりますが、以前に学んだ構成要素はこの新しいプログラミング言語でも非常にはっきりと現れています。
切り捨てと浮動小数点数による不正確さ
- Cでは、ある整数を別の整数で割ると切り捨てが発生し、不正確な結果になる可能性があることを思い出してください。
calculator.py のコードを次のように修正することで、Pythonがそのような除算をどのように処理するかを確認できます:
# Division with integers, demonstration lack of truncation
# Prompt user for x
x = int(input("x: "))
# Prompt user for y
y = int(input("y: "))
# Divide x by y
z = x / y
print(z)
このコードを実行すると値が得られますが、.333333 の後のより多くの桁を見ると、浮動小数点数による不正確さに直面していることがわかります。切り捨ては発生しません。
コードを少し修正することで、この不正確さを明らかにできます:
# Floating-point imprecision
# 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}")
このコードが不正確さを明らかにしていることに注目してください。Cと同様に、Pythonも依然としてこの問題に直面しています。
例外
- Pythonコードを実行するときに発生する可能性のある例外について、さらに詳しく見ていきましょう。
calculator.py を次のように修正します:
# Doesn't handle exception
# Prompt user for an integer
n = int(input("Input: "))
print("Integer")
誤ったデータを入力するとエラーが発生する可能性があることに注目してください。
次のようにコードを修正することで、潜在的な例外を処理(try)して捕捉(catch)しようとすることができます:
# Handles exception
# Prompt user for an integer
try:
n = int(input("Input: "))
print("Integer.")
except ValueError:
print("Not integer.")
上記のコードは、正しいタイプのデータを取得しようと繰り返し試み、必要に応じて追加のプロンプトを表示することに注目してください。
マリオ
数週間前、マリオのように3つのブロックを積み重ねるという課題があったのを思い出してください。
Pythonでは、これに似たものを次のように実装できます:
# Prints a column of 3 bricks with a loop
for i in range(3):
print("#")
これは3つのレンガの柱を表示します。
Cでは、do-while ループという利点がありました。しかし、Pythonには do-while ループがないため、while ループを利用するのが一般的です。mario.py というファイルに次のようにコードを書くことができます:
# Prints a column of n bricks with a loop
from cs50 import get_int
while True:
n = get_int("Height: ")
if n > 0:
break
for i in range(n):
print("#")
高さを取得するために while ループがどのように使用されているかに注目してください。0より大きい高さが入力されると、ループは終了します。
次の画像を考えてみてください:
Pythonでは、次のようにコードを修正することで実装できます:
# Prints a row of 4 question marks with a loop
for i in range(4):
print("?", end="")
print()
print 関数の動作を上書きして、前の print と同じ行にとどまることができる点に注目してください。
以前の反復と同様の考え方で、このプログラムをさらに簡素化できます:
# Prints a row of 4 question marks without a loop
print("?" * 4)
* を利用して print 文を掛け算し、4回繰り返すことができる点に注目してください。
大きなレンガの塊はどうでしょうか?
上記を実装するには、次のようにコードを修正します:
# Prints a 3-by-3 grid of bricks with loops
for i in range(3):
for j in range(3):
print("#", end="")
print()
1つの for ループが別のループの中に存在している仕組みに注目してください。print 文は、レンガの各行の最後に改行を追加します。
print 関数の詳細については、Pythonのドキュメントで学ぶことができます。
リスト
list(リスト)はPython内のデータ構造です。
list には組み込みのメソッドや関数が含まれています。
例えば、以下のコードを考えてみましょう:
# Averages three numbers using a list
# Scores
scores = [72, 73, 33]
# Print average
average = sum(scores) / len(scores)
print(f"Average: {average}")
組み込みの sum メソッドを使用して平均を計算できることに注目してください。
次のような構文を利用して、ユーザーから値を取得することもできます:
# Averages three numbers using a list and a loop
from cs50 import get_int
# Get scores
scores = []
for i in range(3):
score = get_int("Score: ")
scores.append(score)
# Print average
average = sum(scores) / len(scores)
print(f"Average: {average}")
このコードがリストの組み込みメソッドである append を利用していることに注目してください。
リストの詳細については、Pythonのドキュメントで学ぶことができます。
また、
lenの詳細については、Pythonのドキュメントで学ぶことができます。
探索と辞書
- データ構造内を探索することもできます。
次のような phonebook.py というプログラムを考えてみましょう:
# Implements linear search for names using loop
# A list of names
names = ["Yuliia", "David", "John"]
# Ask for name
name = input("Name: ")
# Search for name
for n in names:
if name == n:
print("Found")
break
else:
print("Not found")
これが各名前に対して線形探索をどのように実装しているかに注目してください。
しかし、リストを反復処理する必要はありません。Pythonでは、次のように線形探索を実行できます:
# Implements linear search for names using `in`
# A list of names
names = ["Yuliia", "David", "John"]
# Ask for name
name = input("Name: ")
# Search for name
if name in names:
print("Found")
else:
print("Not found")
in を使用して線形探索を実装している仕組みに注目してください。
それでも、このコードは改善の余地があります。
辞書(dictionary)または
dictは、キー(key)と値(value)のペアのコレクションであることを思い出してください。
Pythonでは次のように辞書を実装できます:
# Implements a phone book as a list of dictionaries, without a variable
from cs50 import get_string
people = [
{"name": "Yuliia", "number": "+1-617-495-1000"},
{"name": "David", "number": "+1-617-495-1000"},
{"name": "John", "number": "+1-949-468-2750"},
]
# Search for name
name = get_string("Name: ")
for person in people:
if person["name"] == name:
print(f"Found {person['number']}")
break
else:
print("Not found")
各エントリに対して name と number の両方を持つように辞書が実装されていることに注目してください。
さらに良いことに、厳密に言えば、name と number の両方は必要ありません。次のようにこのコードを簡素化できます:
# Implements a phone book using a dictionary
from cs50 import get_string
people = {
"Yuliia": "+1-617-495-1000",
"David": "+1-617-495-1000",
"John": "+1-949-468-2750",
}
# Search for name
name = get_string("Name: ")
if name in people:
print(f"Number: {people[name]}")
else:
print("Not found")
辞書が波括弧を使用して実装されていることに注目してください。次に、if name in people という文は、name が people 辞書の中にあるかどうかを調べます。さらに、print 文の中で、name の値を使用して people 辞書をインデックスする方法に注目してください。非常に便利です!
Pythonは、組み込みの探索を使用して定数時間に到達するように最善を尽くしています。
辞書の詳細については、Pythonのドキュメントで学ぶことができます。
コマンドライン引数
Cと同様に、コマンドライン引数も利用できます。以下のコードを考えてみましょう:
# Prints a command-line argument
from sys import argv
if len(argv) == 2:
print(f"hello, {argv[1]}")
else:
print("hello, world")
print 文に含まれる f で示されるフォーマット済み文字列を使用して argv[1] が表示されていることに注目してください。
sys ライブラリの詳細については、Pythonのドキュメントで学ぶことができます。
終了ステータス
sys ライブラリには組み込みメソッドもあります。sys.exit(i) を使用して、特定の終了コードでプログラムを終了できます:
# Exits with explicit value, importing sys
import sys
if len(sys.argv) != 2:
print("Missing command-line argument")
sys.exit(1)
print(f"hello, {sys.argv[1]}")
sys.exit(0)
sys の組み込み関数を利用するためにドット記法が使われていることに注目してください。
CSVファイル
- PythonはCSVファイルのサポートも組み込まれています。
phonebook.py のコードを次のように修正します:
import csv
file = open("phonebook.csv", "a")
name = input("Name: ")
number = input("Number: ")
writer = csv.writer(file)
writer.writerow([name,number])
file.close()
writerow がCSVファイルにカンマを自動的に追加してくれることに注目してください。
file.close や file = open はPythonで一般的に使用され、利用可能な構文ですが、このコードは次のように改善できます:
import csv
name = input("Name: ")
number = input("Number: ")
with open("phonebook.csv", "a") as file:
writer = csv.writer(file)
writer.writerow([name,number])
コードが with 文の下でインデントされていることに注目してください。これにより、処理が終わると自動的にファイルが閉じられます。
同様に、CSVファイル内に次のように辞書を書き込むことができます:
import csv
name = input("Name: ")
number = input("Number: ")
with open("phonebook.csv", "a") as file:
writer = csv.DictWriter(file, fieldnames=["name", "number"])
writer.writerow({"name": name, "number": number})
このコードは前の反復とよく似ていますが、代わりに csv.DictWriter を使用していることに注目してください。
サードパーティライブラリ
Pythonの利点の1つは、膨大なユーザーベースと、同様に膨大な数のサードパーティライブラリがあることです。
Python がインストールされていれば、
pip install cs50と入力することで、自分のコンピュータにCS50ライブラリをインストールできます。他のライブラリに関して、Davidは
cowsayとqrcodeの使用をデモンストレーションしました。
まとめ
このレッスンでは、これまでのレッスンで学んだプログラミングの構成要素をPythonでどのように実装できるかを学びました。さらに、Pythonによってコードをいかに簡素化できるかについても学びました。また、さまざまなPythonライブラリの活用方法も学びました。最終的には、プログラマとしてのスキルは単一のプログラミング言語に限定されないということを学びました。すでに、このコースを通じて、あらゆるプログラミング言語、そしておそらくあらゆる学習分野で役立つ新しい学習方法を発見しつつあります!具体的には、以下について議論しました…
Python
変数
条件分岐
ループ
型
オブジェクト指向プログラミング
切り捨てと浮動小数点数による不正確さ
例外
辞書
コマンドライン引数
サードパーティライブラリ
また次回お会いしましょう!