今回は,この連載の第8回「宝くじでひと山当てるプログラムをPythonで作るには?─辻真吾からの問題」の解説編です。宝くじで何億円も当たったら,アパート経営でも始めて,気が向いたらコードを書く生活をしたいと思っていますが,なかなかそうもいきません。今回は「ひと山当てよう」と銘打ってみましたが,もちろんお金儲けができるわけではなく,数字選択式宝くじのシミュレーションをするプログラムを皆さんに作っていただきました。全部で18人の方々からご応募いただき,少し惜しかったお2人を除いて,16人の方々は正解でした。基本的な問題だったとは言え,CodeIQ挑戦者のレベルの高さがわかります。included"なところを体験していただきたかったという気持ちもありました。架空の売り上げ枚数を生成するためのポイント売り上げの数については,設問で次のようにしました。何口売れるか,20万~30万口という幅の中から,それらしい数字が選ばれるような仕組みを考えてみてください。なんともあいまいな書き方ですが,ここから正規分布を連想してもらえるかを期待していました。結果は,4人の方々に期待どおりのコードを書いていただきました。正規分布についてはWebにもくわしい情報がたくさんあるで,そちらを参照していただくとして,Pythonには正規分布に従う乱数を生成する関数が標準ライブラリに含まれています。以下のように記述することで,平均が250,000,標準偏差が50,000/3.0の正規分布に従う乱数を1つ取得できます。random.gauss(250000,50000/3.0)260870.83563410284確率変数なので,このコードを何度も実行すれば違った値になりますが,99.7%は200,000から300,000の間に入ります。これは,標準偏差をσとすると,±3σの範囲になります。それをわかりやすくするために,50,000/3.0と書いています。中には,「⁠そもそも売り上げが正規分布するのか?」という鋭い指摘をコメント行に入れていただいた解答者もいらっしゃいました。ごもっともかと思います。200,000から300,000の範囲で等確率に生成される,一様な乱数でもかまいません。randomモジュールには,正規分布のほかにも,いろいろな分布に従う乱数を取得できる関数が用意されています。一度試してみてください。当たり判定と結果をまとめるコードはどう書くか今回の問題のために用意した架空の宝くじ「LOTO-G」は,1から40までの中から5つの数字を選び,全部当たると1等,4つ当たると2等,3つ当たると3等になる,というものでした。架空の販売くじは,約25万あることになります。そのすべてについて,当たりを判定する必要があります。これは,以下のようにするといいでしょう。・当たりの番号5つと,当籤を確かめる5つの番号で,interactionメソッドを使い,いくつの数字が重なるかを調べる18人の応募者のうち最多の6人がこの方法を採用していました。当たり判定の後,当籤順位ごとに結果をまとめるコードが必要ですが,次のような働きをしてくれるCounterを使うと便利です。1})これを使えば,以下のように短く書けます。jackpotは当たりくじ,lotog_salesは5個の数字のリストを要素にもつリスト型これでresult[5]とすると,1等の当籤が何本あるか,すぐにわかります。resultの中に5がなくても,KeyErrorにならず,0が返ってくるところが便利です。collections.Counterについては,英語ですが以下の記事がわかりやすく参考になります。Week大きな数字はわかりやすい表示に今回は,売り上げや主催者の取り分など,大きな数字がたくさん出てくるので,表示のときに3桁ごとに区切ると,よりわかりやすくなります。18人中7人の方々が,この処理をしてくださいました。print(locale.currency(val,grouping=True))¥200,000,000数字のカンマ区切りは,適切なlocaleを設定して,locale.format関数を使うことで実現できます。その時,grouping引数にTrueを指定するのがポイントです。今回のようにお金を扱っている場合,通貨に関するlocaleを使う方法もあります(使うと,数字の先頭に円マークがつきます⁠)⁠。国際化も簡単で,日本円の場合,JPYを付けることもできます。端数の問題をどう処理するか大きな数字に限りませんが,お金を数字として扱うときにもっと問題になることがあります。それは端数の問題です。当籤準備金は,売り上げの60%に設定していました。通常,複数口出る2等の当籤者は,この1/3を山分けすることになっています。これは割り切れない可能性があり,その場合は端数が出ます。18人の解答者の中でお1人だけ,このことについてコメント行で言及されている方がいらっしゃいましたが,基本的には端数を回避するコードを書かれた方はありませんでした。端数をどうするのか,問題文には書いてありませんでしたが,末尾に掲載した解答例では主催者の懐にこっそり入れることにしました。ここで便利なのが,組み込み関数のdivmodです。この関数は,1つ目の引数を2つ目の引数で割り,商と余りをこの順のタプルで返してくれます。1)Pythonには便利な道具がたくさんプログラミングには,ちょっとした想像力が必要です。日本語など,普通の言語で書かれたことを,forとかifとか,まったくあいまいさのない,厳密なロジックに落とし込む必要があるのがプログラミングです。アルゴリズムが浮かんでくる天才ハッカーは別として,我々普通のプログラマは便利な道具がたくさんある方が仕事が早く終わります。そんな普通のプログラマのために,Pythonはとても便利なプログラミング言語です。ところで,皆さんのコードを実行するついでに,入力として私の好きな番号を買い続けましたが,残念ながらまったく当たりませんでした。来週のロト6も買ってしまうんだろうな......。'''Python2.7での実行を想定しています。金額を少し見やすくします。help='1から40までの数字から5つを選んで,スペース区切り入力してください。help='購入する口数を指定してください。print('今回の当選番号は「{}」です。#端数は胴元が持って行くことにします。print('{}等の当籤はありません。print('総売上は{}でした。print('主催者の取り分は{}でした。著者プロフィール辻真吾(つじしんご)現在は大学で情報科学を駆使して生物医学の研究をしていることになっている37歳。小学生の頃にMSX2でLOGOを動かして以来コンピュータが好き。C++やJavaに傾倒した時期もあったが,最近はPythonが最高だと思っている。著書に『Pythonスタートブック』(技術評論社)。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。コードの安全性・安定性を高める開発サイクル~テスト管理の効率を上げ,脆弱性診断を自動で行う~本連載では,連載「業務を改善する情報共有の仕掛け」を受けつつ,安全性・安定性を加えた開発サイクルについて考えていきます。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。