2024-2I プログラミング1 第05回 講義資料

2024年05月24日(金)1・2時限

1 準備と概要

2 前回までの復習 ( 12分)

プログラミングスキルを効果的に習得するためには 調べる試す考える の「3つ」をバランスよく実践していくことが求められます。

また、授業時間外の学習をせずに 授業を受けるだけ では、実質的に1ヵ月あたり わずか4時間未満 の学びにしかなりません (中間試験を除くと講義は年間28回。28回/12カ月=2.33回/月。1回90分なので、2.33回、つまり1ヵ月あたり約210分≒3.5時間です)。たったそれだけの時間では、到底、ソフトウェアエンジニアに必要な知識もスキルも身に付かないことを予め了承しておいてください。また、早期専門教育というスタートダッシュも活きてきません。

以下は、前回までの学習内容 (主に第03回講義の学習内容) の復習に相当する演習です。

2.1 準備 ( 目標3分)

2.2 演習1 ( 目標7分)

img
  1. 変数 a に整数値 25 を格納する。同様に b に実数値 15.9 を、 c22.9 を格納する。
  2. \(30a+79\) を計算し、その結果を (1) 0011_0011_1101 のように、アンダーバーで4桁区切りした12桁の「2進数」で出力する。
  3. 次の値を計算して、結果を (2) 3.11 のように小数点以下第2桁まで出力する。ヒント: 平方根は、0.5乗に相当します。つまり、5の平方根は、5の0.5乗として計算できます。 \[\frac{c-3}{\sqrt{a+b}}\]
  4. 次の値を計算して、結果を (3) 99.594 のように小数点以下第3桁まで出力する。 \[ 6a^5\{(-3b-2)(2c-80)\}\times 10^{-9} \]

期待する実行結果は、次のようになります。

(1) 11_0011_1101
(2) 3.11
(3) 99.594

さて、どれだけ定着していたでしょうか ?

もしも定着していようであれば、自分に適する「学びのスタイル」を探って、毎回の授業内容が定着するように努めてください

3 標準入力の利用

標準入力Standard Input)とは、コンピュータ上でプログラムが実行される際、ユーザからの入力を受け取るための標準的な窓口のことです。主にキーボードやファイルを通して「文字列」が与えられます (流し込まれます) 。

例えば、GUI (Graphical User Interface) を持たない コンソールプログラム においてユーザに名前や年齢を入力 してもらうような処理は「標準入力」を使って実現します。

Pythonでは、input という関数を使って標準入力を受け取り、それを 「文字列」として変数に格納 します。例えば、標準入力から 2024 のような数値を入力しても、変数に格納されるデータは 「数値」でなく「文字列」 となるので注意してください。

次のプログラムを実行して、標準入力 の動作を確認してください。

%reset -f
print('名前を入力してください >> ',end='')
name = input()
print('年齢を入力してください >> ',end='')
age = input()
print(f'{name}さんは{age}歳なんですねwww')
img

次に変数 age に格納された値が 文字列であることを確認 するために、次のプログラムを実行して動作を確認してください。

%reset -f
print('名前を入力してください >> ',end='')
name = input()
print('年齢を入力してください >> ',end='')
age = input()
print(f'{name}さんの年齢を2倍すると{age*2}歳っすねwww') # ここを変更

非ノートブック環境で実行した場合

GoogleColab や Jupyter ではなく、通常のコンソール環境 (非ノートブック環境) で print('名前を入力してください >> ',end='') を実行したときは、以下のように画面表示されます。

名前を入力してください >> _

3.1 演習2 ( 目標4分)

名前、年齢、性別を標準入力から受け取り、高専太郎(20歳・男性) のような文字列を出力するプログラムを作成せよ。

取り組みにあたっての注意事項

授業時間内では演習に使用できる時間が限られているので、既出の再利用可能なコードはコピー&ペーストして演習に取り組んでください。(特に基礎的な処理については) ゼロからプログラムを書いたほうが格段に力が付きますが、それは自宅学習の時間で行なってください。

4 文字列を「整数値」に変換する int関数

文字列を整数値に変換するためには int() 関数を使用します。

次のプログラム実行して「文字列が整数値に変換できていること」を確認してください。

%reset -f
print('あなたの年齢を入力してください >> ',end='')
age = input()
age = int(age) # ここで文字列から整数値に変換
print(f'年齢を2倍すると{age*2}歳っすねwww')

5 文字列を「実数値」に変換する float関数

文字列を実数値 (小数を含む数値、厳密には浮動小数点数) に変換するためには float() 関数を使用します。

%reset -f
print('''時刻0において速度 v (m/s) の物体が、
一定の加速度 a (m/s^2) を保ちながら
t秒間の間に進む 距離 x (m) を求めます。
''')
v = input('速度 v (m/s) を入力してください >> ')
v = float(v)
a = input('加速度 a (m/s^2) を入力してください >> ')
a = float(a)
t = input('走行時間 t (s) を入力してください >> ')
t = float(t)
x = v*t + 0.5*a*t**2
print(f'走行した距離は {x} (m) です。')

三連引用符

'''''' で囲んだ三連引用符を使用すると、長文や改行付の文字列リテラルの記述が簡単になります。三連引用符のなかでは 改行やスペース がそのまま有効になります。"""""" による囲みでも有効です。

次のように変数に格納して使用することもできます。

# 元ネタ FC版FF1
%reset -f
msg = '''このせかいは あんこくにつつまれている
かぜはやみ うみはあれ
だいちはくさっていく
しかし ひとびとは1つのよげんをしんじ
それをまっていた
このよ あんこくにそまりしとき
4にんのひかりのせんし あらわれん
ながいぼうけんのすえ
4にんのわかものがこのちにたどりついた
そしてそのてには
それぞれクリスタルがにぎられていた'''
print(msg)

5.1 演習3 ( 目標6分)

標準入力から半径 r と高さ h を与えて「円柱」の体積 V と表面積 S を計算するプログラムを作成せよ。なお、\(\pi\) (定数) は、mathライブラリから、次のように値を得ることができる。

%reset -f
import math
p = math.pi
print(f'pi={p}') # => 

取り組みにあたっての注意事項

プログラムを作成するだけでなく「プログラムを使って正しく計算できているかどうかを検証・確認すること」も演習に含まれています。また、現時点では不要ですが 不正な値が入力された場合 には、それを検出して適切な処理をするようなコードを書くことも求められます。

6 コメント

プログラムにおける コメント とは、コードのなかに 説明や注意事項、開発者の意図などを表すために記すテキスト です。コメントはプログラムの実行に影響を与えず、他の開発者未来の自分 がコードを理解する助けとして使用されます。

Python では # がコメントを表す記号になります。

Google Colab や VSCode などの開発環境では Ctrl+/ のショートカットキーより、アクティブ行の「コメントアウト (コメント化) 」「アンコメント (コメント解除) 」を切り替え可能です。範囲選択しておけば、複数行をまとめてコメントアウト/アンコメントが可能です。

6.1 計算式をテストするとき

今回の講義では「標準入力」を取り上げましたが、ノートブック開発環境においては 基本的に標準入力は使用しません。特にデバッグ (プログラムが意図した動作をするようにエラーを取り除いたり、検証したりする行為) の際には、実行毎に標準入力から値を与えることは煩雑なので、以下のようにコメントを利用して「標準入力」と「リテラルによる入力(ハードコーディング)」を切り替えます。

%reset -f
print('''時刻0において速度 v (m/s) の物体が、
一定の加速度 a (m/s^2) を保ちながら
t秒間の間に進む 距離x(m) を求めます。
''')
# v = float(input('速度 v (m/s) を入力してください >> '))
# a = float(input('加速度 a (m/s^2) を入力してください >> '))
# t = float(input('走行時間 t (s) を入力してください >> '))
v = 1.5
a = 2
t = 4
x = v*t + 0.5*a*t**2
print(f'走行した距離は {x} (m) です。')

開発中 (=様々な値を与えて動作を検証するとき) は 第06行目 ~ 第08行目 をコメントアウトして、第09行目 ~ 第11行目 を使って、直接、変数に値を与えます。一方で、本番環境では、第06行目 ~ 第08行目 のコメントを解除して、第09行目 ~ 第11行目 をコメントアウトすることで、ユーザからの入力を受け取ります。

7 繰返し構文の利用

Python では次のような構文で n 回の 繰り返し処理 ができます。

%reset -f
n = 5
for i in range(n):
  print('Hello ', end='')
  print('World.')

上記を実行すると、以下のように Hello World. という文字が5回出力されます。

Hello World.
Hello World.
Hello World.
Hello World.
Hello World.

Pythonでは、繰返し処理をする範囲インデント (字下げ) により指示します。例えば、次にように 第05行目 のインデントを解除して「どのように動作が変化するか」を確認して、「なぜそのようになるか」を考えてみてください。

%reset -f
n = 5
for i in range(n):
  print('Hello ', end='')
print('World.') # インデントを解除

ここでは、変数 n を使用していますが、次のように range の引数に直接、数値リテラルを入れることもできます。

%reset -f
for i in range(7):
  print('Hello World.')

7.1 演習4 ( 目標4分)

繰り返し構文を利用して、次のような出力を得るプログラムを記述せよ。

AAA
AAA
AAA
BBBB
BBBB
BBBB
BBBB
BBBB

AAA が3行、BBBBが5行、出力されています。

8 休憩

ChatGPTに質問してみましょう。

私は高専の2年生です。知能情報コースという情報系の学科に所属してソフトウェアエンジニアとして就職して新規開発プロジェクトに従事すること目指しています(既存案件の保守業務に携わることや、SESなどの派遣系の企業に就職することは希望していません)。プログラミング科目の先生からは「そのようなキャリアを目指すのであれば、学校での授業という「受動的で最低限のプログラミング学習」では、新卒採用時に要求されるスキルレベル(期待されているスキルレベル)に到達しない。授業の枠を超えて自学したり、課外活動としてクラスメイトとソフトウェア開発の経験を積むことが絶対的に必要だ。」と言われました。このアドバイスは「まとも」なものですか。

9 タートルグラフィックス

繰り返し構文に到達したので、その応用として タートルグラフィックス で遊んでみます。

タートルグラフィクスの例 ( Google画像検索 )

タートルグラフィックス (Turtle Graphics) は、プログラミング言語で簡単な「図形」や「アニメーション」を描画するためのグラフィカルな方法です。Turtle は、そのまま「亀」の意味になります。

タートルグラフィックス

タートルグラフィックスの核となる概念は「タートル」と呼ばれるカーソルです。タートルは、プログラムによって指示されたとおりに画面上を移動し、その軌跡に沿って線や図形を描画 します。タートルには「 前進」「後退」「左回転」「右回転」などの基本的な操作が用意されており、これらの操作を組み合わせてさまざまな図形を描くことができます。

タートルグラフィックスは、特に「小学生」や「初心者向け」のプログラミング教育において、視覚的で直感的な理解を促すためによく使用されます。また、繰り返しや条件分岐などのプログラミングの基本的な概念を学ぶのにも役立ちます

9.1 準備 (ライブラリの読み込み)

独立したコードセルを作成して、以下を実行してください 。以降、ノートブックを再開するたびに (GoogleColabに再接続するたびに) 実行してください。

!pip install ColabTurtle

上記はPythonのプログラムではなく、Colab.を実行している 仮想マシン (Linux) に対する直接的な命令 (コマンド) になります。このコマンドは、Pythonの パッケージ管理システムである pip を使って、ColabTurtleというライブラリを仮想マシンにインストールするために実行しています。

この「ColabTurtle」は、Google Colab 上でも動作するように Turtle Graphics を実装したライブラリで、簡単な図形やアニメーションを描画するために使われます。

9.2 基本形

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

第02行目 では ColabTurtle.Turtle という モジュール (ライブラリ) を インポート して、t という略称で扱うことを指示しています。もともとインポートとは「輸入」の意味ですが、ここでは「自分のプログラムのなかにXXXというライブラリを取り込む」のようなイメージでとらえてください。

第03行目 では、t (=ColabTurtle.Turtleを略名) の 初期化 (初期設定) をしています。Initialize という語 (初期化という意味) はプログラミングでは頻出するので覚えておいてください。

9.2.1 補足

上記のプログラムは 第02行目as t を使わずに以下のように書くこともできます。このようにすると「可読性」が下がり、タイプミスしやすくなるというデメリットがあります。

%reset -f
import ColabTurtle.Turtle # ここで `as t` をつけていない
ColabTurtle.Turtle.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

例えば、第02行目import ColabTurtle.Turtle as tur としたら、第03行目 はどのように記述するべきでしょうか。考えて実際に手を動かして実行してみてください。

9.3 絶対位置座標を与えてカメを移動させる

次のプログラムを実行して結果を確認してください。

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))
t.goto(50,30)

さらに、次のプログラムを実行して結果を確認してください。

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))
t.goto(50,30)
t.goto(50,100) # 追加

「コード」と「実行結果」を突き合わせながら、次のようなことを推測して、さらに確証を得てください。プログラミングでは、このように「サンプルコード」と「その実行結果」から 機能や仕組み、内部動作を推測する・検証する 能力が強く要求されます。この過程では goto メソッド (関数) のパラメータを変更したり文を追加したりして、実際に試すこともしてください。また、リファレンス も参照してください。

上記のことが、指示されなくても反射的に、自然にできるようになってください。さらに「引数に描画領域の範囲外の値を与えるとどうなるのか」「goto メソッドの引数に実数値を与えるとどうなるのか」のような好奇心を持てるようになってください。

9.4 ペンの上下/形状/色を操作する、背景色を設定する

次のプログラムを実行して結果を確認してください。また、shape メソッド、bgcolo メソッド、color メソッド、up メソッド、dowb メソッドなどの各メソッドがどのような機能を持つのか、引数としてどのような値を持つのかについて、考える試す を通して推測し、また、調べる試す を通して確証を得てください。

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

# ペンの形状をカメ('turtle')から円('circle')に変更 
t.shape(shape='circle')

# 背景色をセット(RGB指定 0~255)
t.bgcolor(240,240,240)

# ペンの色をセット(RGB指定 0~255)
t.color(0,0,255)
  
t.up() # ペンを持ち上げる
t.goto(50,30)

t.down() # ペンを下す
t.goto(50+300,30)

t.hideturtle() # ペン先を非表示

9.5 絶対座標で移動・相対位置指示で移動

次の p1.py は絶対座標でカーソルを移動させて正方形を描いています。また p2.py は相対位置指示で移動で正方形を描いています。実際に動作させて確認してから、コードを解読してください。

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))
t.shape(shape='circle')
t.bgcolor(0,0,0)
t.color(0,255,0)
  
t.up(); t.goto(50,50);t.down() # 50,50に移動

t.goto(350,50)
t.goto(350,350)
t.goto(50,350)
t.goto(50,50)
%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

t.shape(shape='circle')
t.bgcolor(0,0,0)
t.color(0,255,0)

t.up(); t.goto(50,50); t.down() # 50,50に移動

t.right(90)
t.forward(300)
t.right(90); t.forward(300)
t.right(90); t.forward(300)
t.right(90); t.forward(300)

新しく登場した right メソッドについても、好奇心を持って「実数値は与えられるのか」「負の値は与えられるのか」「360を超える値は与えられるのか」「もしかして left メソッドも存在するのか」といったことが自然に思い浮かぶように思考回路を変容させて、さらに実際に確認してみる習慣を身に付けてください (指示されなくても…)。

1行に複数の文を記述する方法

Pythonでは原則として1行に1文を記述しますが、セミコロン ; で区切って 1行のなかに複数の文 を記述することができます。

例えば、次の2つのプログラムは同じ意味を持ちます。

t.up();t.goto(50,50);t.down()
t.up()
t.goto(50,50)
t.down()

9.5.1 発展1 (五芒星)

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

t.shape(shape='circle');t.bgcolor(0,0,0);t.color(0,255,0)
t.up(); t.goto(400/2,400/2);t.down()

d = 300
t.up()
t.forward(d/2);t.right(36/2)
t.down()
t.right(180-36);t.forward(d)
t.right(180-36);t.forward(d)
t.right(180-36);t.forward(d)
t.right(180-36);t.forward(d)
t.right(180-36);t.forward(d)

9.5.2 発展2 (三角形)

%reset -f
import ColabTurtle.Turtle as t
t.initializeTurtle(initial_speed=5,initial_window_size=(400,400))

t.shape(shape='circle');t.bgcolor(0,0,0);t.color(0,255,0)
t.up();t.goto(400/2,400/2);t.down()

a = 60
d = 300
t.up()
t.forward(d/2);t.right(a/2)
t.down()
t.right(180-a);t.forward(d)
t.right(180-a);t.forward(d)
t.right(180-a);t.forward(d)

9.5.3 演習5 ( 目標9分)

10 課題02

次の「演習6」について、今回の講義で作成したノートブック PG1-第05回講義_高専太郎.ipynb のなかで取組み、その共有リンクを Google Classroom 経由で提出してください。

img

10.1 演習6

タートルグラフィックスを使って、以下の条件でラインアートを作成してください。

10.2 参考

タートルグラフィクスの応用

今後、関数 (再帰処理)条件分岐の構文randomライブラリ、mathライブラリなどを学習していけば、次のようなプログラムを内容を理解して書けるようになっていきます。

%reset -f
import ColabTurtle.Turtle as t
import math
import random
import matplotlib.pyplot as plt

cm = plt.get_cmap('Wistia',17)

t.initializeTurtle(initial_speed=13,initial_window_size=(400,300))
t.shape(shape='circle')
t.bgcolor('black')
t.color(*map(lambda p:int(p*255),cm(1)[:3]))

t.up(); t.goto(t.window_width()//2,t.window_height()-30);t.down()

color_offset = 0
init_length = 40
init_width  = 15
min_length = 12
max_level = 12

def draw_branch(p, w, v):
  p2 = max(1,int(p + (p * random.randint(-15,15)*0.01)))
  t.down();t.width(w);t.color(*map(lambda p:int(p*255),cm(color_offset+v)[:3]))
  t.forward(p2);
  generate_branch(math.ceil(p2*0.82),math.ceil(w*0.75),v+1)
  t.up();t.back(p2)

def generate_branch(p, w, v):
  if p < min_length or v > max_level:
    return
  else:
    a1,a2 = 20+random.randint(-2,2), 20+random.randint(-2,2)
    t.left(a1)
    draw_branch(p,w,v)
    t.right(a1+a2)    
    draw_branch(p,w,v)
    t.left(a2)

t.face(-90)
t.color(*map(lambda p:int(p*255),cm(color_offset)[:3]))
t.width(init_width+1)
t.forward(init_length)
generate_branch(init_length,init_width,0)
t.color(*map(lambda p:int(p*255),cm(color_offset)[:3]))
t.back(init_length)
img