順番決めツール(Python学習)

Pythonを使ってPython講座に使うファイルの自動作成に挑戦しています。今回は6回目(番外編)です。 前回の記事はコチラになります。

hirocom777.hatenadiary.org

前回まででPython講座に使うファイルとフォルダーの自動生成に取り組んできました。きちんと形になってよかったと思います。

ところで私が所属しているノンプロ研で開催される講座は、最後に卒業LT(ライトニング・トーク)大会なるものがあります。最後に講座を通して得た学びを発表するんですね。ところが急遽、今回の卒業LT大会の司会を仰せつかりました。大変、準備しなきゃ!!

順番決めツールをつくる

司会の準備とは何が必要でしょうか。自分の発表はおいといて、他の人の発表はメンバーが準備してくれるわけだし、ブレイクアウトや最後のおしらせなどはホストさんが担当してくれます。何もしなくてもいいんじゃないかな・・・と思いながら過去の卒業LT動画を観ていたら、準備しなきゃいけないものがありました。順番決めツールです。

卒業LT大会では複数名が発表するわけですが、直前で発表する順番を決めます。やり方は色々なのですが今回はPython講座です。折角なのでPythonで順番決めツールをつくろうじゃありませんか。

手順を考える

順番決めツールの手順を考えてみました。

  1. 発表メンバーリストを用意する
  2. 発表順リストを用意する
  3. 発表メンバーリストからメンバーをランダムに選ぶ
  4. 選んだメンバーが発表順リストになければ発表順リストに追加して表示する
  5. 発表メンバーリストと発表順リストの項目数が同じになるまで2.から繰り返す

こんな手順でいいんじゃないでしょうか。

乱数を使う

このプログラムでは、発表メンバーをランダムに選出する必要があります。つまり整数の乱数が必要となるわけです。randomモジュールのrandint()関数をを使えば実現できます。使い方は以下になります。

from random import randint
print(randint(数値1, 数値2))

これで数値1~数値2の範囲の整数をランダムに取得できます。

実際のコード

実際のコードは以下の様になりました。リストのメンバー数はlen()関数で取得しています。これで直前に発表メンバー数が変更になっても柔軟に対応できますね。

from random import randint

members = [
"さとう",
"たなか",
"やまだ",
"おおた",
"きのした",
]

members_count = len(members)
result = []
while True:
    # ランダムにメンバーを選出
    index = randint(0, members_count - 1)
    # メンバーがリストになければ登録して表示
    if not members[index] in result:
        result.append(members[index])
        result_count = len(result) 
        print(str(result_count) + ':'
            + result[-1])
        if members_count == result_count:
            break

実行してみると以下の様になりました。

1:たなか
2:やまだ
3:きのした
4:さとう
5:おおた

ちゃんとバラバラに並べ替えられています。複数回実行すると順番が変わって表示されます。順番決めツールの完成です!!

改善してみる

順番決めツールが完成しました。でももう少しシンプルにできないでしょうか?上のブログラムでは選んだメンバーが発表順リストにすでにある場合、メンバーの選出をやり直しています。繰り返しの回数はメンバー数に抑えたいところです。

  1. 発表メンバーリストを用意する
  2. 発表メンバーリストからメンバーをランダムに選んで表示する
  3. 選んだメンバーの要素は発表メンバーリストから削除する
  4. 発表メンバーリストのメンバー数だけ2.から繰り返す

これならば繰り返しの回数は必ずメンバー数になりムダがありません。また発表順リストが不要となるので使用するリソースも少なくなります。 リストからの要素削除はリストのpop()で実行します。

ブログラムは以下の様になりました。randomモジュールのインポートと発表メンバーリストは上のプログラムと一緒なので省きます。

for i in range(1,len(members) + 1):
    # ランダムにメンバーを選出して登録
    index = randint(0,len(members) - 1)
    print(str(i) + ':' + members[index])
    # 登録したメンバーはリストから削除
    members.pop(index)

使用する変数も減って、ぐっとシンプルになりました。もちろんちゃんと動きます。 len(members)でメンバー数を読み込んでいますが、for文でのrange内では初回で設定されるだけなのでメンバーが削除されても値は変わりません。対してループ内ではメンバーが削除されるたびに数値が減っていきます。

発表資料がまだ

やれやれ、やっと準備は整いました。いや、まだ自分の発表資料が未だでした。次回は私が卒業LTで発表する内容をご紹介しようと思います。お楽しみに!!

hirocom777.hatenadiary.org