前回までの「Python初体験」の続きです。

(実はこれ、一回誤って削除した原稿を思い出しながら書き直しました。)
コレクションのアンパックはC系言語を使っていた人にはやや物珍しいのではないでしょうか?(と、私は感じますが。)

シーケンスなコレクション(順に並んだデータ集合、と言い換えてもよいかと思います)であるリストやタプルでは、コレクションの特定の要素を添字をつけて呼び出すことが可能でした。

#サンプルプログラム
#リスト
list = [1, 2, 3,]
#タプル
tuple = ('a', 'b', 'c')

print("list :", list)
print(list[0], list[1], list[2])
print("tuple :", tuple)
print(tuple[0], tuple[1], tuple[2])

コレクションは一挙に要素を代入することもできるそうです。

#↑と同じ出力となる
first, second, third = list
print("list :", list)
print(fiwrst, second, third)

el1, el2, el3 = tuple
print("tuple:", tuple)
print(el1, el2, el3)

更に面白いのは、関数で複数の戻り値を簡単にコレクションで返せることです。

def total_and_average_and_number(values):
 

    total = 0 #合計値を初期化する
    num = len(values)  #データの件数を求める
    for value in values:  #valuesはコレクション
        total = total + value
    average = total / num  #平均値を求める

    #複数の戻り値をコレクション(タプル)で返す
    return (total, average, num)

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

r1, r2, r3 = total_and_average_and_number(numbers)
print(r1, r2, r3)

【出力】
list : [1, 2, 3]
1 2 3
tuple : ('a', 'b', 'c')
a b c
list : [1, 2, 3]
1 2 3
tuple: ('a', 'b', 'c')
a b c
55 5.5 10

次の例題はゲームを書くというので期待しましたが、要すれば乱数と平方根で西瓜までたどり着くゲームです。

#西瓜割ゲーム
import random  #乱数使用の為
import math  #平方根を求める為

def calc_distance(x1, y1, x2, y2):
    #2点間の距離を求める
    diff_x = x1 - x2
    diff_y = y1 - y2
    
    return math.sqrt(diff_x**2 + diff_y**2)


suika_x = random.randrange(0, 5)  #スイカのx座標
suika_y = random.randrange(0, 5)  #スイカのy座標

player_x = random.randrange(0, 5) #プレイヤーのx座標
player_y = random.randrange(0, 5) #プレイヤーのy座標

#スイカとプレイヤーの位置が異なる間、処理を繰り返す
while (suika_x != player_x) or (suika_y != player_y):

    #スイカとプレイヤーの距離を表示する
    distance = calc_distance(player_x, player_y, suika_x, suika_y)
    print("スイカへの距離:", distance)
    
    #キー入力に応じて、プレイヤーを移動する
    c = input("n:北に移動 s:南に移動 e:東に移動 w:西に移動")
    if c == "n":
        player_y = player_y - 1
    elif c == "s":
        player_y = player_y + 1
    elif c == "w":
        player_x = player_x - 1
    elif c == "e":
        player_x = player_x + 1

print("スイカを割りました!")

【出力】
スイカへの距離: 4.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動e
スイカへの距離: 5.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動w
スイカへの距離: 4.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動
スイカへの距離: 4.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動w
スイカへの距離: 3.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動w
スイカへの距離: 2.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動w
スイカへの距離: 1.0
n:北に移動 s:南に移動 e:東に移動 w:西に移動w
スイカを割りました!

まぁ、分かりますが、余り興奮はしませんね。
次の項に行くと「マジックナンバーを避ける」とあり、↑の西瓜割ゲームの枠数を変数でまとめるということが書かれていました。

import random
import math

BOARD_SIZE = 5  #ボードの初期サイズ(これがマジックナンバー?)

def calc_distance(x1, y1, x2, y2):
    #2点間の距離を求める
    diff_x = x1 - x2
    diff_y = y1 - y2

    return math.sqrt(diff_x**2 + diff_y**2)

suika_x = random.randrange(0, BOARD_SIZE)  #スイカのx座標 <- この行を修正
suika_y = random.randrange(0, BOARD_SIZE)  #スイカのy座標 <- この行を修正

player_x = random.randrange(0, BOARD_SIZE) #プレイヤーのx座標 <- この行を修正
player_y = random.randrange(0, BOARD_SIZE) #プレイヤーのy座標 <- この行を修正

#スイカとプレイヤーの位置が異なる間、処理を繰り返す
while (suika_x != player_x) or (suika_y != player_y):

    #スイカとプレイヤーの距離を表示する
    distance = calc_distance(player_x, player_y, suika_x, suika_y)
    print("スイカへの距離:", distance)

    #キー入力に応じて、プレイヤーを移動する
    c = input("n:北に移動 s:南に移動 e:東に移動 w:西に移動")
    if c == "n":
        player_y = player_y - 1
    elif c == "s":
        player_y = player_y + 1
    elif c == "w":
        player_x = player_x - 1
    elif c == "e":
        player_x = player_x + 1

print("スイカを割りました!")

解説では、
「この5のように、プログラム中にいきなり出てくる意味のわからない数字は、一般に マジックナンバー といいます。基本的には、マジックナンバーは、値を直接書くのではなく、その値の意味がわかるように、常に 変数に代入してから利用するようにします。」
とあり、これはプログラミング一般の話でPython particularなものではありませんね。
 

ps.  カウントダウンです。「Python日記」も後2回を残すだけとなりました。