Pythonの基本
- 今日は、Pythonという新しいプログラミング言語について学びます。C言語よりも新しい言語であるため、単純さだけでなく機能も追加されており、その人気につながっています。
- PythonのソースコードはCよりもずっと簡単に見えます。実際、「hello, world」を出力するには、以下のように書くだけです。
print("hello, world")
- C言語とは異なり、
print
関数で改行を指定したり、セミコロンを使用して行を終了する必要はありません。- このプログラムを作成して実行するには、CS50 IDEを使用し、新しいファイルを上記の行を記入し
hello.py
として保存し、コマンドpython hello.py
を実行します。
- このプログラムを作成して実行するには、CS50 IDEを使用し、新しいファイルを上記の行を記入し
- ユーザーから文字列を取得できます。
answer = get_string("What's your name? ")
print("hello, " + answer)
PythonバージョンのCS50ライブラリcs50
もget_string
関数用にインポートする必要があるため、コードは次のようになります。
from cs50 import get_string
answer = get_string("What's your name? ")
print("hello, " + answer)
- 型を指定せずに
answer
という変数を作成し、+
演算子を使用して2つの文字列を結合 (連結) してから出力print
に渡すことができます。 - 書式文字列
f"..."
の構文を使用して、変数を組み込むことができます。例えば、print(f"hello, {answer}")
を作成して、answerの値を中括弧で囲んで文字列に組み込むことができます。 counter = 0
とするだけで変数を作成できます。値0
を割り当てると、型は暗黙的に整数に設定されるため、型を指定する必要はありません。変数を増加させるには、counter = counter + 1
またはcounter += 1
を使用します。- 条件は次のようになります。
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")
- コードのブロックを示すために中括弧が使用されるCとは異なり、Pythonでは各行のインデントによってネストのレベルが決まります。
else if
の代わりに、elif
と書きます。
- ブール式も少し異なります。
while True:
print("hello, world")
- Pythonでは、
True
とFalse
の両方が先頭大文字で表記されます。 - 変数を使ってループを書くことができます。
i = 0
while i < 3:
print("hello, world")
i += 1
for
ループを使用して、リスト内の値ごとに何かを行うこともできます。
for i in [0, 1, 2]:
print("cough")
- Pythonのリスト
[0, 1, 2]
は、Cの配列のようなものです。- このfor ループは、変数iに最初の要素0を代入し実行され、次に2番目の要素1を代入し実行されます。
- 多機能な関数
range
を使うと、for i in range(3)
のようにいくつかの値を得ることができます。range(3)
は、値0、1、2からなる (3は含まない) 3つの値を持ちます。 - range()は他のオプションを取ることもでき、異なる値で始まり、リストの要素間で一定の増分を持つリストを作成することもできます。ドキュメントを見ると、例えば
range(0, 101, 2)
を使用すると、2
ずつ増える0から100までの範囲を取得することができます (2番目の値101は含まれません) 。
- 変数
i
も印刷するには、print(i)
と書くだけです。
- Pythonで同じコードを書くには複数の方法があることが多いので、最も一般的に使用され、受け入れられている方法はPythonicと呼ばれます。
- Pythonには、多くの組み込みデータ型があります。
bool
,True
またはFalse
float
, 実数
int
, 整数
str
, 文字列
- C言語は型が厳密に定義された言語であり、型を指定する必要がありますが、Pythonは型が緩やかに定義されており、型は値によって暗黙的に定義されます。
- Pythonのその他の型は次のとおりです。
range
, 番号のリスト
list
, 変更可能な値のリスト、シーケンス、または変更可能な値- リストはC言語の配列に似ていますが、Pythonでは自動的に拡大縮小されます。
tuple
, タプル、x座標やy座標、経度や緯度などの順序付けられた値の集合
dict(dictionary)
, 辞書、キーと値のペアの集合、ハッシュテーブルのようなもの
set
, 集合、一意 (重複のない) の値のコレクション
- Python用CS 50ライブラリには次のものが含まれます。
get_float
get_int
get_string
- 関数は一度に1つずつインポートすることも、まとめてインポートすることもできます。
from cs50 import get_float
from cs50 import get_int
from cs50 import get_string
import cs50
from cs50 import get_float, get_int, get_string
例
- Pythonには、他の人が作成したコードのライブラリーだけでなく、多くの機能が含まれているため、すべての詳細を自分で実装するのではなく、高度な抽象化レベルで問題を解決することができます。
- 次のようにしてイメージをぼかすことができます。
from PIL import Image, ImageFilter
before = Image.open("bridge.bmp")
after = before.filter(ImageFilter.BoxBlur(1))
after.save("out.bmp")
- Pythonでは、
import
で他のライブラリをインクルードできます。ここでは、PIL
ライブラリからImage
とImageFilter
の名前をimport
します (他の人がこのライブラリを書いて、私たち全員がダウンロードして使えるようにしてくれました)Image
はデータだけでなく、.
構文を使用してアクセスできる関数も併せ持つ構造をしています(Image.open
のように)。
bridge.bmp
という名前の画像を開き、ぼかしフィルタ関数を呼び出して、out.bmp
という名前のファイルに保存します。
- これを
blur.py
という名前のファイルに保存した後、python blur.py
で実行できます。
- 辞書を実装するには、次のようにします。
words = set()
def load(dictionary):
file = open(dictionary, "r")
for line in file:
words.add(line.rstrip())
file.close()
return True
def check(word):
if word.lower() in words:
return True
else:
return False
def size():
return len(words)
def unload():
return True
- 最初に、
words
という新しいセットを作成します。main
関数は必要ありません。Pythonプログラムは上から下へと実行されます。ここでは関数を定義したいので、def load()
を使います。load
は引数としてdictionary
を受け取り、その戻り値はTrueを返しています。open
を使用してファイルを開き、for line in file:
を使うだけでファイル内の行を繰り返し処理します。次に、行末の改行を削除し、setのwords
に追加します。line
は文字列ですが、.rstrip
関数を呼び出すことができます。
- そうして、
check
関数内でif word.lower() in words
を使い確認しています。size
については、len
を使用してセット内の要素の数をカウントし、最後にunload
については、Pythonがメモリを管理するため、何もする必要がありません。
- Pythonでプログラムを実装する方が私たちにとっては簡単ですが、メモリ管理などの汎用的なソリューションでは、より多くの作業を実行する必要があるため、Pythonでのプログラムの実行時間はCでのプログラムよりも遅くなります。
- さらに、Pythonはインタプリタと呼ばれるプログラムの名前でもあります。インタプリタはソースコードを読み込んで、CPUが理解できるコードに1行ずつ変換します。
- たとえば、Week 0の擬似コードがスペイン語で、スペイン語が理解できない場合、電話帳で名前を検索する前に、行ごとにゆっくりと英語に翻訳する必要があるでしょう。
1 Recoge guía telefónica
2 Abre a la mitad de guía telefónica
3 Ve la página
4 Si la persona está en la página
5 Llama a la persona
6 Si no, si la persona está antes de mitad de guía telefónica
7 Abre a la mitad de la mitad izquierda de la guía telefónica
8 Regresa a la línea 3
9 Si no, si la persona está después de mitad de guía telefónica
10 Abre a la mitad de la mitad derecha de la guía telefónica
11 Regresa a la línea 3
12 De lo contrario
13 Abandona
- 私達の目的に応じて、人間がより効率的にプログラムを書く時間と、プログラムの実行時間との間にはトレードオフがあることを考慮する必要があるでしょう。
入力、条件
input
関数を使用してユーザーから入力を取得できます。
answer = input("What's your name? ")
print(f"hello, {answer}")
- ユーザーに2つの整数を入力してもらい、それらを足します。
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)
- コメントは、
//
ではなく#
で始まります。 - inputを呼び出すと、値の文字列が返されます。
# Prompt user for x
x = input("x: ")
# Prompt user for y
y = input("y: ")
# Perform addition
print(x + y)
- したがって、各値を格納する前に、
input
をintにキャスト (変換) する必要があります。
# Prompt user for x
x = int(input("x: "))
# Prompt user for y
y = int(input("y: "))
# Perform addition
print(x + y)
- しかし、ユーザーが番号を入力しなかった場合は、さらにエラーチェックを行う必要があります。そうしないと、プログラムがクラッシュします。このような問題を解決するには、一般的によく使用されるライブラリを使用します。
- 値を除算します。
# Prompt user for x
x = int(input("x: "))
# Prompt user for y
y = int(input("y: "))
# Perform division
print(x / y)
- 2つの整数で割ったとしても、浮動小数点の10進数が返されることに注意してください。
- 条件を示すことができます。
from cs50 import get_int
x = get_int("x: ")
y = get_int("y: ")
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")
- ライブラリ全体をインポートし、ライブラリ内の関数を構造体のように使用することができます。
import cs50
x = cs50.get_int("x: ")
y = cs50.get_int("y: ")
- プログラムが2つの異なるライブラリをインポートする必要がある場合、例えばそれぞれが
get_int
関数を持っている場合、名前が衝突しないように、ライブラリの名前を冠し、異なる名前空間にあるメソッドとして使用する必要があります。 - 文字列を比較するには、次のように記述します。
from cs50 import get_string
s = get_string("Do you agree? ")
if s == "Y" or s == "y":
print("Agreed.")
elif s == "N" or s == "n":
print("Not agreed.")
- Pythonには文字型 (char) がないので、
Y
などの文字を文字列としてチェックします。また、文字列を直接==
と比較することもできます。最後に、ブール式では、記号の代わりにor
またはand
を使用します。if s.lower() in ["y", "yes"]:
で、小文字に変換した後で文字列がリスト内にあるかどうかを調べることもできます。
meow (ニャー)
meow
の改良版も作れます。
print("meow")
print("meow")
print("meow")
main
関数を宣言する必要がないので、同じコード行を3回記述します。
- 再利用できる関数を定義できます。
for i in range(3):
meow()
def meow():
print("meow")
- しかし、これを実行しようとするとエラー
NameError: name 'meow' is not defined
が発生します。関数を使用する前に関数を定義する必要があるため、meow
の定義を先頭に移動するか、メイン関数を最初に定義することができます。
def main():
for i in range(3):
meow()
def meow():
print("meow")
main()
- これで、
main
関数を実際に呼び出すまでに、meow
関数はすでに定義されています。 - 関数は入力も取ることができます。
def main():
meow(3)
def meow(n):
for i in range(n):
print("meow")
main()
meow
関数はパラメータn
を取り、それをrange
に渡します。
get_positive_int
- 正の整数を取得する関数を定義できます。
from cs50 import get_int
def main():
i = get_positive_int()
print(i)
def get_positive_int():
while True:
n = get_int("Positive Integer: ")
if n > 0:
break
return n
main()
- PythonにはCのようなdo-whileループがないので、無限に続く
while
ループで、n > 0
になればbreak
を使用してループを終了します。最後に、この関数はwhile
ループの外側の元のインデントレベルでn
を返します。 - Pythonの変数はデフォルトで関数にスコープされることに注意してください。つまり、
n
はループ内で初期化されますが、関数内から後でアクセスできます。
マリオ
- 画面にクエスチョンマークを一列に印刷することができます。
for i in range(4):
print("?", end="")
print()
- 各ブロックを出力するときは、自動的に改行されないようにするため、キーワード引数とも呼ばれる名前付き引数を、
print
関数の特殊な引数として渡すことができます。これまでは、関数呼び出し内の位置に基づいてパラメータが設定される位置引数のみを見てきました。- ここでは、文字列の最後に何も表示されないようにするために、
end=""
としています。end
はオプション引数でもあり、print
は通常では新しい行を追加するため、デフォルト値の\n
を渡す必要はありません。このため、print
は通常では、新しい行を追加します。
- 最後に、ループを使用して行を出力した後、他の引数を指定せずに
print
を呼び出して新しい行を出力することができます。
- ここでは、文字列の最後に何も表示されないようにするために、
- 文字列を 「乗算」 し、
print("?" * 4)
で直接出力することもできます。 - ネストされたループを実装できます。
for i in range(3):
for j in range(3):
print("#", end="")
print()
オーバーフロー、非精度
- Pythonでは、整数オーバーフローを発生させようとしても実際には動作しません。
i = 1
while True:
print(i)
i *= 2
- 整数が特定のバイト数に固定されているC言語とは異なり、Pythonは自動的により多くのメモリを使用して数値を格納するため、出力される数値はどんどん大きくなります。
- 浮動小数点数の精度は存在しますが、ライブラリによって必要十分な精度で小数を表現することができます。
リスト、文字列
- リストを作りましょう。
scores = [72, 73, 33]
print("Average: " + str(sum(scores) / len(scores)))
sum
(Pythonに組み込まれた関数) を使用してリスト内の値を合計し、それをスコアの数で割ります。len
関数を使用してリストの長さを取得できます。次に、連結して出力する前に、floatを文字列にキャストします。- 同じ結果を得るために、書式付き文字列に式全体を追加することもできます。
print(f"Average: {sum(scores) / len(scores)}")
- 以下を使用してリストにアイテムを追加できます。
from cs50 import get_int
scores = []
for i in range(3):
scores.append(get_int("Score: "))
...
- 文字列内の各文字を繰り返すことができます。
from cs50 import get_string
s = get_string("Before: ")
print("After: ", end="")
for c in s:
print(c.upper(), end="")
print()
- Pythonは文字列中の各文字を
for c in s
だけで繰り返します。 - 文字列を大文字にするには、
s.upper()
を呼び出すだけでよく、各文字をループさせる必要はありません。
コマンドライン引数、終了コード
- 次のコマンドライン引数を使用できます。
from sys import argv
if len(argv) == 2:
print(f"hello, {argv[1]}")
else:
print("hello, world")
- Pythonに組み込まれているシステムモジュール
sys
からargv
をインポートします。argv
はリストなので、argv[1]
で2番目の項目を取得できます。したがって、コマンドpython argv.py David
で引数を追加すると、hello, David
が出力されます。
- Cと同様、
argv[0]
はargv.py
のようなプログラムの名前です。
- また、Pythonにリストを繰り返し処理させることもできます。
from sys import argv
for arg in argv:
print(arg)
- プログラムの終了時に終了コードを返すこともできます。
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
モジュール全体をインポートします。これでsys.argv
とsys.exit()
を使ってプログラムを特定のコードで終了できます。
アルゴリズム
- リスト内の各要素をチェックするだけで、線形探索を実装できます。
import sys
numbers = [4, 6, 8, 2, 7, 5, 0]
if 0 in numbers:
print("Found")
sys.exit(0)
print("Not found")
sys.exit(1)
if 0 in numbers
で、リストをチェックするようPythonに指示しています。- 文字列のリストも次のように検索できます。
names = ["Bill", "Charlie", "Fred", "George", "Ginny", "Percy", "Ron"]
if "Ron" in names:
print("Found")
else:
print("Not found")
- 辞書 (キーと値のペアのセット) がある場合、特定のキーをチェックし、そのキーに対して格納されている値を調べることもできます。
from cs50 import get_string
people = {
"Brian": "+1-617-495-1000",
"David": "+1-949-468-2750"
}
name = get_string("Name: ")
if name in people:
print(f"Number: {people[name]}")
- まず辞書
people
を宣言します。ここで、キーは保存したい名前の文字列で、各キーに関連付けたい値は対応する電話番号の文字列です。- そして、
if name in people:
を使って辞書のキーから名前name
を検索します。キーが存在する場合は、ブラケット表記の値people[name]
を取得することができます。これは、Cで配列にインデックスを付ける場合とよく似ていますが、ここでは整数の代わりに文字列を使用します。
- 辞書は、集合と同様に、ハッシュテーブルのようなデータ構造を使ってPythonで実装されているのが普通なので、ほぼ一定の時間検索を行うことができます。繰り返しになりますが、内部で何が起こるかを正確に制御することができなくなるというトレードオフがあります。たとえば、ハッシュ関数を選択できるというメリットと、自分で行う作業が減るというメリットのトレードオフです。
- そして、
- 2つの変数の入れ替えは、単に両方の値を同時に割り当てることによって行うこともできます。
x = 1
y = 2
print(f"x is {x}, y is {y}")
x, y = y, x
print(f"x is {x}, y is {y}")
- Pythonではポインタにアクセスできなくなっていて、メモリでの操作ミスから守ってくれています。
ファイル
- CSVファイルを開きます。
import csv
from cs50 import get_string
file = open("phonebook.csv", "a")
name = get_string("Name: ")
number = get_string("Number: ")
writer = csv.writer(file)
writer.writerow([name, number])
file.close()
- PythonにはCSVファイルを扱うための
csv
ライブラリもあります。ファイルに追記するためにオープンした後、fileからwriter
を作成するためにcsv.writer
を呼び出すことができます。これによりwriter.writerow
のような関数が使えるようになり、行としてリストを書き込むことができます。 with
キーワードを使用すると、完了後にファイルが閉じられます。
...
with open("phonebook.csv", "a") as file:
writer = csv.writer(file)
writer.writerow((name, number))
- 別のCSVファイルを開き、値が表示される回数を集計します。
import csv
houses = {
"Gryffindor": 0,
"Hufflepuff": 0,
"Ravenclaw": 0,
"Slytherin": 0
}
with open("Sorting Hat (Responses) - Form Responses 1.csv", "r") as file:
reader = csv.reader(file)
next(reader)
for row in reader:
house = row[1]
houses[house] += 1
for house in houses:
print(f"{house}: {houses[house]}")
csv
ライブラリからreader
関数を使用し、next(reader)
でヘッダ行をスキップし、残りの各行(ヘッダ行の次の行から)を繰り返します。- 各行の2番目の項目である
row[1]
は、houseの文字列です。この文字列を使用して、houses
に格納されているそのキーの値にアクセスし、またキーを追加できます。
- 最後に、各houseのカウントを印刷します。
- 各行の2番目の項目である
その他のライブラリ
- 私たちのMacやPCで、Pythonをインストールした後にターミナルを開き、別のライブラリを使ってテキストを音声に変換することができます。
import pyttsx3
engine = pyttsx3.init()
engine.say("hello, world")
engine.runAndWait()
- ドキュメントを読むことで、ライブラリの初期化方法や文字列の発音のさせ方を知ることが出来ます。
- 書式文字列を
engine.say(f"hello, {name}")
に渡して入力を伝えることもできます。
- 書式文字列を
- 別のライブラリである
face_recognition
を使用して、イメージ内の顔を検索できます。
# Find faces in picture
#https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py
from PIL import Image
import face_recognition
# Load the jpg file into a numpy array
image = face_recognition.load_image_file("office.jpg")
# Find all the faces in the image using the default HOG-based model.
# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.
# See also: find_faces_in_picture_cnn.py
face_locations = face_recognition.face_locations(image)
for face_location in face_locations:
# Print the location of each face in this image
top, right, bottom, left = face_location
# You can access the actual face itself like this:
face_image = image[top:bottom, left:right]
pil_image = Image.fromarray(face_image)
pil_image.show()
- recognize.pyを使えば、特定の顔にマッチするものを見つけるプログラムを書くことができます。
- 別のライブラリを使用して、QRコードまたは2次元バーコードを作成できます。
import os
import qrcode
img = qrcode.make("https://youtu.be/oHg5SJYRHA0")
img.save("qr.png", "PNG")
os.system("open qr.png")
- マイクからの音声入力を認識できます。
import speech_recognition
# Obtain audio from the microphone
recognizer = speech_recognition.Recognizer()
with speech_recognition.Microphone() as source:
print("Say something:")
audio = recognizer.listen(source)
# Recognize speech using Google Speech Recognition
print("You said:")
print(recognizer.recognize_google(audio))
- マイクを使った音声入力を行うライブラリのドキュメントに従って、音声をテキストに変換します。
- 基本的な応答を行う拡張機能を追加することもできます。
...
words = recognizer.recognize_google(audio)
# Respond to speech
if "hello" in words:
print("Hello to you too!")
elif "how are you" in words:
print("I am well, thanks!")
elif "goodbye" in words:
print("Goodbye to you too!")
else:
print("Huh?")
- 最後に、さらに洗練された別のプログラムを使用して、ディープフェイク、つまり本物のように見えるがコンピュータで生成されたさまざまなパーソナリティのビデオを生成できます。
- オンラインで自由に利用できるこれらのライブラリを利用することで、独自のアプリケーションに高度な機能を簡単に追加できます。