2017年3月28日火曜日

リストから文字列結合 【Python】

"".join(list)


非常に便利なjoinです。今まで使ったことがなかったのが不思議なぐらい

""の間に結合する文字を入れます。どういうことかというと例の通り

# ハイフン"-"で結合
moji =["py","tho","n"]
print ("-".join(moji)) #=> py-tho-n
# なにもなしで結合
moji =["py","tho","n"]
print ("".join(moji)) #=> python
view raw 03281 hosted with ❤ by GitHub



これでpython入門だったときに疑問だった文字列結合方法がクリアされました。

ちなみに入門のときはfor文とif文を使って頑張って結合していました

n = input()
nn = int(n)
a =[]
for i in range(nn):
a.append(input())
for i in range(nn):
print(a[i],end="")
if i < nn-1:
print(",", end="")
elif i == nn-1:
print(".", end="")
view raw 03282 hosted with ❤ by GitHub


まわりくどすぎるわ!wwwwwww

日本語で説明すると
----------
文字列をインプットして、インプットした文字列をintにして、空のリストを作って、数字をリストに追加していき、ループで数字をprintして、最後の文字でなければカンマ","を書いて改行しないようにループ、最後の文字であればカンマを入れず改行もしない
----------

まぁたしかにできなくもないですが、いろいろ大変なことになってますね
入門の頃の試行錯誤でできた作品でした。



今なら同じようなものでも次のように書けます

print ("-".join(list(map(int,input().split(" ")))))
view raw 03283 hosted with ❤ by GitHub


まさかのワンライナーwww

11行のプログラムコードを1行にまとめることができました!



さて、久しぶりに勉強枠の記事でした。
問題解いていないとメソッド忘れちゃいますねぇ。定着するまでちゃんと復習しましょう


2017年3月21日火曜日

FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その5 ~ベホイミ回復のタイミング~

その4までのプログラミングコードを書いてしまえば、あとは変数"z"を好きなパラメータに置き換えるだけでいろいろな条件を考察できるようになります

さて、今までは初期条件としてHPが48以下になったらベホイミで回復としていました。これは竜王の攻撃によってゆうしゃに与えるダメージの最大値が48であるためです。
しかし実際には最大値の48を食らうことは少なく、ベホイミを掛けられる回数からもなるべくMPを温存すべきです。

そこで、HP24~48の間で、どのタイミングで回復をすれば最良かを計算しました

結果が以下の図です




おお!きれいな図!

勝率最大値を見ると・・・若干グラフがずれていますがHP45が最大値!!

ちなみに
HP45で回復 勝率 38.906%
HP46で回復 勝率 37.326%
HP47で回復 勝率 34.985%
HP48で回復 勝率 32.563%

45と48の差はなんと6%以上!!



~~~結論(初期HPだけで考えたとき)~~~
FC2ドラクエ1,RTAレベル18ルートでは
HP45以下になったらベホイミで回復が最良!!
#なお条件が実機と同じであると仮定ですので、RTAで竜王に勝てなくても当ブログ筆者は一切の責任を負いません (笑)






FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その4 ~ゆうしゃの初期HPと勝率の関係~

FC版ドラクエ1、りゅうおう第二形態との戦いをシミュレーションしています。

前回は勇者の初期HPを変えたときの勝率を求めました。

今回は前回に引き続き、初期HPが1のときから最大値の115までの条件を一気に計算するようにコードを書き換えました。

修正点をメモ書きで書いております

# -*- coding: utf-8 -*-
"""
基礎データ
ゆうしゃ
HP115
MP100
こうげきとベホイミのみ
こうげき 6~12のランダム
ベホイミ 85~100のランダム
りゅうおう
HP130
こうげき 24~48
ほのお 42~48
確率半分とする
ルーチーン
HP49以上ならこうげき
HP48以下になったらMPが尽きるまでベホイミで回復
"""
import random
import matplotlib.pyplot as plt #グラフを描くためにmatplotlibをインポート
katilist=[] #勝率を格納するための空のリストを作成、負け率はいらないので消しました
joukenlist=[] #グラフの横軸になる値を格納する空のリストを作成
step = 100000
for z in range(1,115):
kati = 0
for i in range(step):
myHP = z
myMP = 100
HP = 130
syouhiMP = 10
try:
while HP > 0:
if myHP >48:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
elif myHP >0:
if myMP >= 10:
behoimi = random.randint(85,100)
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
ryucommand = random.randint(0,1)
if ryucommand == 0:
mydamage = random.randint(24,48)
myHP -= mydamage
elif ryucommand == 1:
mydamage = random.randint(42,48)
myHP -= mydamage
if myHP < 0:
raise Exception
except Exception:
pass
katilist.append(kati/step*100) #勝率をリストに入れていく
joukenlist.append(z) #横軸の値をリストに入れていく
plt.plot(joukenlist,katilist,'o') #↑で得られたリストをグラフ化
plt.show #グラフ表示
view raw 03211 hosted with ❤ by GitHub




1条件につき10万回繰り返し、115条件の計算をしました
1150万回の計算です。さすがにそろそろ計算速度も考えてプログラミングしないと計算時間がかかるようになってきました。

基本的にfor,if文は短縮余地があるので今後改良予定です

計算結果は以下のグラフの通りです



前回は"単純なグラフにはならない"ことを示しましたが、

今回はHP48を下回ると一気に勝率が下がることを示しました。

RTAをやってるときに第2形態戦闘開始時にHP48以下だったら絶望しかないですね(たぶん実際はあまりないと思いますが)



<<<   FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その3


2017年3月17日金曜日

FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その3

以前作ったりゅうおう戦シミュレーションで遊んでみました



これまでの流れとして、本ブログのメインの目的「Pythonプログラミングの上達」のために比較的単純なゲームを再現するということを考え、ドラクエ1のりゅうおう戦を再現してきました。
最初はただ「ゆうしゃのこうげき!」と表示させるところから始まりましたが、Pythonプログラミングに慣れてくるに連れて、ランダムで攻撃の値を変更したりループを取り入れることで、再現性の高いりゅうおう戦を再現できるようになりました。

これまでのシミュレーションの問題点として、HPが48以下になったときにすぐにベホイミをかけて回復というルーチーンだけを考えていました。HP48以下で回復というのは、相手のりゅうおうの攻撃の最大値が48ですので、HPが49以上あるときはゆうしゃがやられることがないからです。
しかしこれだけだと、最後にあと1撃だけりゅうおうを攻撃できるかできないかという微妙な戦闘のときに、HPが47のときにベホイミで回復するかしないかという選択は非常に判断のしづらい場面になります。とくに7時間以上もぶっ続けでドラクエ1をプレイし、クリアまでのタイムを競うRTAという競技では、最後のりゅうおう戦で最良の判断ができるかどうかは、世界記録がでるかでないかのとてつもなく重要な分かれ道になるわけです。

この判断はトップレベルのRTA走者は何度も練習し、感覚的に「攻撃」を選ぶか「ベホイミ」を選ぶかはだいたいわかっています。しかしそれは完全ではありません。おそらくRTAトップ走者でも、ありとあらゆるデータを取り、統計的処理から得られた合理的な判断を下している方はほとんどいないでしょう。現実的には悩む前に操作して進めないとタイムが伸びないからです。

そこでプログラミングの最適化の出番です。戦い方のルーチーンを決めたら、次は戦い方の最適化です。プログラミングの強みはある条件の確率や期待値を求めるだけではありません。条件自体を変えることでいかなる場合でも最良の選択を選ぶように最適化することができます。

ドラクエ1のりゅうおうとの戦闘は「こうげき」か「ベホイミ」しか基本的に選ばないので、非常に単純なコマンド選択です。
しかしどのタイミングでどちらが最高の判断かは非常に難しい問題です。なぜなら最高の判断をするためには次の3つ(大きく分けて)の要素をすべて考慮する必要があるからです。


  • 自分のHP
  • 自分のMP
  • りゅうおうのHP



--------------------------
さて、ここまで非常に長くなってしまいました。

今回はりゅうおう第一形態を倒したときに、ゆうしゃのHPに応じた勝率を求めました。

基本データは以下のとおりです
"""
基礎データ
ゆうしゃ
HP60~115
MP100
こうげきとベホイミのみ
こうげき 6~12のランダム
ベホイミ 85~100のランダム

りゅうおう
HP130
こうげき 24~48
ほのお 42~48
確率半分とする

ルーチーン
HP49以上ならこうげき
HP48以下になったらMPが尽きるまでベホイミで回復
1条件で10万回の戦闘から勝率を求める
"""
プログラムコードは以前の記事を参照ください
基本的に 変数[MyHP]を変えるだけです

結果は以下のようになりました。



グラフを見るとわかりますが、HPが115から97の間は線形的に勝率が減少しますが、減少量は比較的大きくありません。

しかしHPが97のときに勝率が27.3%ですが、HP90になると勝率が16.2%と、HP7違うだけで10%以上も勝率が変わってしまうという結果が得られました。

最初はなだらかな曲線になるのかと思っていましたが、ゆうしゃのHPを変えるだけで複雑なグラフになってしまいました。これはやはり1つの式でまとめるというよりは、統計的に判断するしかなさそうですね。

考察としては、ゆうしゃの最大HPが115、かつ確率の低くなるHP90という値が重要になります。このHPの差は25です。これは竜王のこうげき”ランダムで24~48”という値がキーになってるのではないかと思います。HP91~HP97というのは、りゅうおうの最後の1撃を耐えるか耐えられないか非常に微妙な値ということです。


いやぁ、面白いですね。このデータを出すために50万回以上もシミュレーションで戦ってくれたゆうしゃとりゅうおうに感謝いたしますw



<<< FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その2






2017年3月12日日曜日

Python競馬予想プログラミング【6】~Excelデータから馬番ごとの複勝率(3着以内に来る確率)を求める~

Excelデータから各種データの値を取得する方法は過去の記事を参照してください






今回はとりあえず2016年1月5日に開催された中山のダート1200mだけの結果を抽出して出力します。
この日は該当するレースが3レースがあり、出走数はいずれも16頭でした。
出走数は16で固定していますが、次回以降必要に応じて変数にしていきます。

print("レースごとの着順データ (allumabanに格納されている)")
print(allumaban)
print("レース情報、allbabaにダートか芝か、allkyoriに距離が格納されている")
print(allbaba)
print(allkyori)
tousuu = 16
fukulist = [[0 for i in range(3)]for j in range(tousuu)]
numofrace = 0
for i in range(12):
if allbaba[i][0]== "ダ":
if allkyori[i]=="1200":
fuku = (allumaban[i][:3])
for t in range(3):
fukulist[int(fuku[t])-1][t]+=1
numofrace +=1
print ("該当レース数")
print (numofrace)
print ("馬番ごとの3着以内の数")
print (fukulist)
print ("複勝率")
for i in range(tousuu):
print (str(i+1)+"番 "+str(sum(fukulist[i])/numofrace*100))
view raw 03121 hosted with ❤ by GitHub



出力結果
----------
レースごとの着順データ (allumabanに格納されている)
[['12', '11', '13', '9', '5', '7', '14', '4', '10', '2', '15', '6', '16', '3', '8', '1'], ['5', '15', '7', '9', '11', '6', '8', '3', '14', '2', '12', '10', '13', '4', '1', '16'], ['12', '8', '13', '11', '4', '5', '15', '16', '7', '6', '1', '14', '2', '9', '10', '3'], ['10', '7', '2', '14', '13', '11', '6', '12', '16', '3', '1', '8', '9', '4', '5', '15'], ['2', '13', '10', '5', '1', '6', '9', '4', '7', '15', '12', '14', '11', '8', '3'], ['8', '9', '4', '11', '5', '2', '14', '10', '13', '12', '1', '7', '3', '6'], ['12', '3', '8', '11', '5', '1', '14', '2', '13', '6', '7', '16', '10', '4', '15', '9'], ['16', '12', '3', '5', '2', '7', '4', '9', '8', '6', '14', '1', '15', '11', '13', '10'], ['3', '5', '1', '13', '7', '8', '2', '10', '9', '14', '11', '4', '15', '6', '12'], ['4', '10', '6', '2', '9', '1', '8', '5', '7', '3'], ['5', '7', '10', '14', '3', '6', '4', '2', '13', '1', '8', '12', '11'], ['8', '3', '7', '15', '11', '5', '2', '12', '9', '4', '10', '13', '1', '6', '16', '14']]
レース情報、allbabaにダートか芝か、allkyoriに距離が格納されている
[['ダ'], ['ダ'], ['ダ'], ['ダ'], ['芝'], ['芝'], ['ダ'], ['ダ'], ['ダ'], ['芝'], ['芝'], ['芝']]
['1200', '1800', '1200', '1800', '2000', '2000', '1800', '1200', '1800', '1600', '2000', '1600']
該当レース数
3
馬番ごとの3着以内の数
[[0, 0, 0], [0, 0, 0], [0, 0, 1], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0], [0, 1, 0], [2, 1, 0], [0, 0, 2], [0, 0, 0], [0, 0, 0], [1, 0, 0]]
複勝率
1番 0.0
2番 0.0
3番 33.33333333333333
4番 0.0
5番 0.0
6番 0.0
7番 0.0
8番 33.33333333333333
9番 0.0
10番 0.0
11番 33.33333333333333
12番 100.0
13番 66.66666666666666
14番 0.0
----------

今回の肝となるのは、出走頭数に応じた"0"のリストを作成することです

tousuu = 16
fukulist = [[0 for i in range(3)]for j in range(tousuu)]


2次元の要素が全て"0"であることで、着順に応じた馬番に1を足すことができます。
例えば馬番"12"番が"1"着の場合、fukulist[12][1]の値が+1となります。

複勝率は3着以内ですので、sum[fukulist[i]]で3着以内の回数を求めます。
あとはダート1200mに該当したレース数"numofrace"で割り算すれば複勝率になります。

ちなみに3着以内の合計を求めなければ1着率になります。



だんだん解析コードっぽくなってきましたね


<<<  Python競馬予想プログラミング【5】~Excelシートをレースごとにリスト化~


2017年3月11日土曜日

Python競馬予想プログラミング【5】~Excelシートをレースごとにリスト化~

とりあえずレース数を入力すると、そのレースの結果を出力するコードを書きました

着順と一緒の順に、馬番・騎手・人気・倍率を出力します。

コード全部は載せませんが、重要なところだけをピックアップします。

import xlrd
import os.path
nanR =10 #何レース目か
r =nanR-1 #数え方を合わせます
#Excelファイルを開きます
xlsfile ="2016010506.xls"
if os.path.exists(xlsfile):
xls = xlrd.open_workbook(xlsfile)
sheet1 = xls.sheet_by_index(0)
開催場所
basho = sheet1.cell(0,0).value.split(" ")[3]
"""
着順・馬番・馬名・騎手・人気・単勝
"""
#空のリストを作成
allbaba=[]
allkyori=[]
allchaku=[]
allumaban=[]
#12レース分のデータがあるので、縦方向に3R,横方向に4R分のループを作ります
for n in range(4):
for m in range(3):
  #ループの中で空のリストを作ります
baba=[]
kyori=[]
chakujun =[]
umabanjun =[]
#10R以降は書式が異なるのでifで場合分けします
if nanR>=10:
race = sheet1.cell(1+m*25,n*12).value.split(" ")[2]
else:
race = sheet1.cell(1+m*25,n*12).value.split(" ")[3]
#馬場状態とそのレースの距離を出力
baba += race[:1]
kyori =race[1:5]  
#着順に相当する列を取得し、ループで得た結果を空のリストに追加していきます
for i in range (4,22):
chaku = sheet1.cell(i+m*25,0+n*12).value.split(" ")
if "" in chaku:
chaku.remove("")
chakujun += chaku   
#あとは同様
for i in range (4,22):
umaban = sheet1.cell(i+m*25,1+n*12).value.split(" ")
if "" in umaban:
umaban.remove("")
umabanjun += umaban
#レース毎の結果を.appendで追加していきます
allbaba.append(baba)
allkyori.append(kyori)
allchaku.append(chakujun)
allumaban.append(umabanjun)
#最初に入力したレースの結果を出力します
print (allbaba[r])
print (allkyori[r])
print (allchaku[r])
print (allumaban[r])
view raw 03111 hosted with ❤ by GitHub



出力結果(3回分)
['芝']
1600
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']
['8', '3', '7', '15', '11', '5', '2', '12', '9', '4', '10', '13', '1', '6', '16', '14']
['ルメー', 'ベリー', '横山典', '田中勝', '柴田善', '柴田大', '戸崎圭', '内田博', '蛯名正', '石橋脩', '津村明', '柴山雄', '井上敏', '池添謙', 'コント', '伴啓太']
['1', '3', '6', '4', '9', '8', '2', '7', '11', '5', '13', '10', '16', '12', '15', '14']
['1.8', '10.8', '15.6', '13.4', '29.8', '21.3', '5.6', '18.9', '46.8', '14.3', '104.0', '31.1', '345.4', '67.8', '177.3', '136.6']

----------------------------------
['ダ']
1800
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15']
['3', '5', '1', '13', '7', '8', '2', '10', '9', '14', '11', '4', '15', '6', '12']
['デムー', '黛弘人', '勝浦正', '戸崎圭', 'ベリー', '嘉藤貴', '吉田豊', '内田博', '横山典', '大野拓', '蛯名正', '江田照', '柴山雄', '石川裕', '柴田大']
['2', '9', '3', '1', '10', '12', '7', '6', '8', '13', '5', '15', '11', '4', '14']
['4.8', '50.9', '5.9', '2.5', '59.2', '73.1', '32.4', '12.1', '39.3', '98.6', '8.9', '189.3', '61.6', '7.1', '144.1']

----------------------------------
['芝']
1600
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
['4', '10', '6', '2', '9', '1', '8', '5', '7', '3']
['丸山元', 'ベリー', '大野拓', 'ルメー', '柴田大', '戸崎圭', '嘉藤貴', '池添謙', '長岡禎', '蛯名正']
['4', '1', '7', '2', '8', '5', '10', '3', '9', '6']
['10.4', '1.9', '17.0', '4.6', '22.8', '11.4', '137.7', '8.2', '53.8', '11.6']


と、だいぶ長くなってきましたね。

正直わかりにくくてブログ書きながらも自分しかわからないコードになってしまっているかもしれません。

今回は微修正や調整が主だったので、pythonの新たなメソッドを使ったりはしていません。

強いて言えば前回の.appendを使うところが重要ですねw
.appendの使い方ですが、例えば

a=[1,2,3,4,5]と
b=[6,7,8,9] というリストがあったときに

a + b  => [1,2,3,4,5,6,7,8,9]
ですが
a.append(b) =>[1,2,3,4,5,[6,7,8]]
となります。


bレース目のデータを取り出すとしたら、前者のよくわからないところから取得するよりも、次元を増やして別々のリストから取得したほうがわかりやすいですよね。

.appendにより決まった数値から機会的に欲しい数値を取り出してくれるリスト作成を学びました。


<<<Python競馬予想プログラミング【4】~Excelシートをすべてリスト化~



2017年3月8日水曜日

Python競馬予想プログラミング【4】~Excelシートをすべてリスト化~

使用するExcelデータは【Python競馬予想プログラミング【2】~Excelファイルを読み込む~】を参照してください


基本的に一連の値を取得するコードを作ってしまえば、あとは膨大なデータもすぐに処理できるようになります。


たとえば最初に
a=25
print (a)

みたいな形を作っておいてから

for i in range(25):
  print(a)

とか

if a ==25:
  print(a)

みたいに書き換えていけば良いのです。

今回はこの書き換えの作業です。長くなってきたので全レースの着順だけを表示するコードを示します

import xlrd
import os.path
import numpy as np
xlsfile ="2016010506.xls"
if os.path.exists(xlsfile):
xls = xlrd.open_workbook(xlsfile)
sheet1 = xls.sheet_by_index(0)
"""
レース情報
"""
basho = sheet1.cell(0,0).value.split(" ")[3]
race = sheet1.cell(1,0).value.split(" ")[3]
baba = race[:1]
kyori = race[1:5]
print (basho)
print (baba)
print (kyori)
"""
着順
"""
allchaku=[]
for m in range(3):
for n in range(4):
chakujun =[]
for i in range (4,22):
chaku = sheet1.cell(i+m*25,0+n*12).value.split(" ")
if "" in chaku:
chaku.remove("")
chakujun += chaku
allchaku.append(chakujun)
allchaku.append(chakujun)
print (allchaku)
view raw 03081 hosted with ❤ by GitHub



それぞれのfor文で作成したリストを.appendで追加していきます。
+=の場合、1次元のリスト内に要素が追加されるだけなので、後で整理ができなくなってしまいます。
そこで.appendを使うことでレースごとの要素に分割することができます

以下は出力結果
=>[['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '7', '9', '10', '11', '12', '13'], ['1', '2', '3', '4', '5', '6', '7', '7', '9', '10', '11', '12', '13'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']]


とそれぞれレースごとのリストになっているのがわかります

<<<Python競馬予想プログラミング【3】~最初は力業で試してみる~


2017年3月7日火曜日

Python競馬予想プログラミング【3】~最初は力業で試してみる~

数学の数列の問題を解くときに若干似ていますが、法則性を与えてルール化するためにはまずルール作りをしっかり決めなければなりません。

いきなり格好良くループを作るよりは、地味~にどこの値を取得してどうするのかを把握することが大切です。いきなりあれもこれもクリアする条件の式を書こうとすると、無駄に長くてわかりにくい式になります。変数をちゃんと使ってわかりやすく作業していきましょう

ということで、今回はほぼ同じスタイルの読み込みの繰り返しを行うコードを作成しました。

Python競馬予想プログラミング【2】~Excelファイルを読み込む~ と同じExcelファイルを使用してください

import xlrd
import os.path
xlsfile ="2016010506.xls"
if os.path.exists(xlsfile):
xls = xlrd.open_workbook(xlsfile)
sheet1 = xls.sheet_by_index(0)
"""
レース情報
"""
basho = sheet1.cell(0,0).value.split(" ")[3]
race = sheet1.cell(1,0).value.split(" ")[3]
baba = race[:1]
kyori = race[1:5]
print (basho)
print (baba)
print (kyori)
"""
着順・馬番・馬名・騎手・人気・単勝
"""
chakujun =[]
umabanjun =[]
bameijun =[]
kishujun = []
ninkijun =[]
tanshoujun =[]
for i in range (4,22):
chaku = sheet1.cell(i,0).value.split(" ")
if "" in chaku:
chaku.remove("")
chakujun += chaku
for i in range (4,22):
umaban = sheet1.cell(i,1).value.split(" ")
if "" in umaban:
umaban.remove("")
umabanjun += umaban
for i in range (4,22):
bamei = sheet1.cell(i,2).value.split(" ")
if "" in bamei:
bamei.remove("")
bameijun += bamei
for i in range (4,22):
kishu = sheet1.cell(i,4).value.split(" ")
if "" in kishu:
kishu.remove("")
kishujun += kishu
for i in range (4,22):
ninki = sheet1.cell(i,9).value.split(" ")
if "" in ninki:
ninki.remove("")
ninkijun += ninki
for i in range (4,22):
tanshou = sheet1.cell(i,10).value.split(" ")
if "" in tanshou:
tanshou.remove("")
if "" in tanshou:
tanshou.remove("")
tanshoujun += tanshou
print (chakujun)
print (umabanjun)
print (bameijun)
print (kishujun)
print (ninkijun)
print (tanshoujun)
view raw 03071 hosted with ❤ by GitHub


長いですが着順から下はほぼ同じなので着順のところだけ解説を載せます


for i in range (4,22):
#最高18頭立てなので、マジックナンバーで入れといてかまわないと思います
4~22(1頭目~18頭目)までのループを作ります

    chaku = sheet1.cell(i,0).value.split(" ")
#着順の値を取得し、.valueで文字列に変換します
#.split(" ")でスペース区切りでリストを作成します
  =>["", "1"] (最初の出力結果)

    if "" in chaku:
#最初の空の要素は邪魔なので消します。 chakuのなかに""があれば~

        chaku.remove("")
#""を消す

    chakujun += chaku
#予めつくっておいた空のchakujunリストにchakuを代入して付け足していく




これで一応 場所・馬場・距離・着順・馬番・馬名・騎手・人気・単勝
のデータを取得できました


基本的にはあとはこの作業を単純化し、すべてのExcelファイルに適用していくだけです

道筋は見えています。

少しずつ進めていきましょう

<<<Python競馬予想プログラミング【2】~Excelファイルを読み込む~


2017年3月6日月曜日

Python競馬予想プログラミング【2】~Excelファイルを読み込む~

Pythonからxlsファイルを読み込むだけでも若干手間取ってしまったので、今回は本当に簡単な操作だけ書きます


------------------------------------------------
1.xlrdをインストール

xlsなどのExcelファイルを開くためには"xlrd"というパッケージが必要です

https://pypi.python.org/pypi/xlrd からダウンロードを行います




私は「xlrd-1.0.0.tar.gz」 を使用しました。

「.gz」ファイルは圧縮されたファイルですので、解凍して使用します。

Lhaplusではできなそうだったので「7-Zip」を使用して解凍し、インストールしました。

が、どのようにインストールしたか忘れてしまいました。しかも思い出せないwので慎重に、自己責任でのインストールをお願いいたします。



ここまででも一苦労でしたねw




----------------------------------------------------------------------
2. Pythonでxlsファイルを読み込む


xlrdとos.pathをインポートしましょう

今更ですが私は開発環境は「Anaconda」を使用してます。もともといろんなパッケージが入っているのですごく便利です

(Anaconda ダウンロード先→https://www.continuum.io/downloads)

Excelのファイルを「2013010506.xls」とします
Excelファイルは競馬インジケータからダウンロードしました



セルA1に年月日と開催競馬場がまとめられていますので、ここからとりあえず開催競馬場を取得したいと思います。



import xlrd
import os.path
xlsfile ="2013010506.xls"
if os.path.exists(xlsfile):
xls = xlrd.open_workbook(xlsfile)
print (sheet1.cell(0,0).value.split(" ")[3])
view raw 03061 hosted with ❤ by GitHub





xlsfile ="2013010506.xls"
#pythonプログラムファイルと同じフォルダにあるファイルを開きます

if os.path.exists(xlsfile):
    xls = xlrd.open_workbook(xlsfile)
#指定したExcelファイルがあれば、開いてxlsという変数にします

print (sheet1.cell(0,0).value.split(" ")[3])
#sheet1.cell(0,0)で文字列を「cell」という型で読み込みます
 →['16年', '1月', '5日', '中山'] (出力結果)

#ちなみにセル(0,0)はExcel上ではA1です

#.valueで読み込んだ文字列の型を「cell」から「value」に変換します
 →'16年', '1月', '5日', '中山' (出力結果)

#.split(" ")で文字列をリスト化します
 →['16年', '1月', '5日', '中山'] (出力結果)
 見た目は変わっていませんが、リストの中を編集可できる文字列になりました

#[3]でリスト内の4番目の文字列を取得します
 →中山 (出力結果)





今回はここまでです。

次回は開催競馬場だけでなく、いろんな情報を取り出したいと思います


2017年3月5日日曜日

Python競馬予想プログラミング【1】 ~他人の予想を信じられない~

【不確定要素を含み、かつ膨大なデータが蓄積されている競馬に着目し、競馬を予想しながらデータ収集方法や解析手法を学んでいきたい】
という非常に欲深いテーマを掲げて始めたいと思います。

これまでにも多くの人が挑戦し実践されてきたことですが、基本的に他人の予想って信じられないですよねw 回収率とかで一応の評価はできますが、そのときは運が良かったとか悪かったでなんとでも良い評価ができますし悪い評価もできます。

多くの人が同じ競馬新聞を買い、予想した場合だったとしても馬券の買い方は十人十色、結局は自分の信じる馬を買っているわけです。

ネット上に転がっている「統計的に」出した予想とかほんっと多いですが、どのように統計的に出されたのかは他人から見たら完全にブラックボックスです。中身がわからない。

やっぱり自分で作るしかないのです。

ないものは作るしかない!



ということでまずはデータの取得方法とかから段階的に進めていきます。

プログラミングしたコードも随時公開していきます。



データですが、本当はJRAの公式そのままのデータをガシガシ取得できればよいのですが、私にはまだネット上データからのスクレイピング技術はありません。とりあえずある程度の情報があるExcelなどのデータを扱う予定です
競馬インジケータよりダウンロード可能


馬ごとのデータは取りにくいかもしれませんが、コース適性などの俯瞰的な解析はできそうです




2017年3月4日土曜日

❤Pythonプログラムで色付きのハート型をランダムにいっぱい描く❤

前回(Pythonプログラムでハート型をランダムにいっぱい描く❤)の続きです
ランダムハートに色を塗りました

# -*- coding: utf-8 -*-
import numpy as np
import random
import matplotlib as plt
from matplotlib import cm
from matplotlib import pylab as plt
sizex = 1000
sizey = 1000
en = np.zeros([sizex,sizey])
han = np.zeros([sizex,sizey])
for m in range(sizex):
for n in range(sizey):
seeds = random.randint(1,10000)
hsize = random.randint(10,70)
if seeds == 1:
en += np.fromfunction(lambda x,y: (x-m)**2+((y-n)-(abs(x-m))**0.95)**2 <hsize**2, (sizex,sizey))
for m in range(sizex):
for n in range(sizey):
han[m][n]=en[n][sizex-1-m]
plt.imshow((han),cmap=cm.Reds)
plt.colorbar()
plt.savefig("heartt")




せっかく❤マークを多用して可愛くしようとしていますが、理系的な(?)思考が身についていてグラフとかカラーバーとか無駄な情報を入れていますね

あとは解像度よくしたり均等にハートを作ってみたいです、今後の課題です。


from matplotlib import cm
from matplotlib import pylab as plt
#色とカラーバーをつけるのに新たなモジュールmatplotlibをインポートしました


plt.imshow((han),cmap=cm.Reds)
plt.colorbar()
plt.savefig("heartt")
#カラーマップRedsを使用、カラーバーをつけてセーブ 単純ですね



<<<   Pythonプログラムでハート型をランダムにいっぱい描く❤

Python修行3

ブログ設立から2週間経ちました~♪

風邪引いた日を除いてだいたい1日2記事ぐらいのペースで更新できています。

最初の頃の実力を振り返ってみましょうか


うーん、6位入賞はあるものの、30位、40位台が目立ちますね。このランキングは無作為に50人選んで基本的に早い順にならんでいるらしいので、解けた人の中では40位の成績という感じです。

まだ基本的なコードを覚えていないので、いちいち関数などを調べたりして頑張って解いているのがわかりますねぇ、しみじみ







そして!2週間経った今の成績!

デデ~ン!!

おぉ、私、成長しましたなぁw

数々の入賞を重ね、ついに2位をとりました!
 イエーイ☆-(ノ゚Д゚)八(゚Д゚ )ノイエーイ☆

ちなみにAボタンBボタンはAmazonギフトプレゼントキャンペーンやってたので初期の頃に解いたもので、46位になっています。


これが基礎をじっくり楽しくやってきた成果です。

これからプログラミングを学んでみたいと思っている入門者さん、超初心者さん、
本を買ってみたけどいまいち勉強が進まないアナタ!

私の勉強方法をオススメします!(何を偉そうに・・・
 だいたいpaizaで勉強しているのでそちらのほうがずっと偉いです。本当に感謝しています。



スキルチェックですが、Cの問題も少しずつ進めています


推定年収535万だって~w 今の給料より高いw 
今の職場を離れることになりそうだったら本気でこっち目指そうかなぁ



さて、コードガールこれくしょんはというと、Pythonのストーリーを一通りクリアしてガチャやりまくったところ、

運に見放されて結局URのレアを取ることはできませんでした


なので現在PHPプログラミングを始めました!!
違う言語とはいえ基本的な構造は似たようなもんです。pythonに慣れてしまえば、PHPもそこそこできるんじゃないかなぁと勘ぐっています。





あとはもし女ですね、がんばって進めています


もし女ではスキルランクBの問題を2問解きました! 
Cランクの問題に慣れてきたら、Bの問題も少しずつチャレンジしていければいいかなと思います。

Bランクが解ければ"中級"ですよ"中級"!


俺達のプログラミングはこれからだ!!   もうちっとだけ続くんじゃ



<<<   Python修行 近況2



2017年3月3日金曜日

Pythonプログラムでハート型をランダムにいっぱい描く❤

ランダムに円を描画する【Python】の続きです

式を変えてランダムにハート型を描画するプログラムです


# -*- coding: utf-8 -*-
import numpy as np
import random
import scipy as sp
sizex = 1000
sizey = 1000
en = np.zeros([sizex,sizey])
han = np.zeros([sizex,sizey])
for m in range(sizex):
for n in range(sizey):
seeds = random.randint(1,10000)
hsize = random.randint(10,70)
if seeds == 1:
en += np.fromfunction(lambda x,y: (x-m)**2+((y-n)-(abs(x-m))**0.95)**2 <hsize**2, (sizex,sizey))
for m in range(sizex):
for n in range(sizey):
han[m][n]=en[n][sizex-1-m]
sp.misc.imsave("testing.png",han)



変えたところを主に紹介いたします

hsize = random.randint(10,70)
#ランダムでハートの大きさを変える設定です

en += np.fromfunction(lambda x,y: (x-m)**2+((y-n)-(abs(x-m))**0.95)**2 <hsize**2, (sizex,sizey))

#複雑な式になってしまいました。順に説明します

円の基本式は  x^2+y^2=r^2
円の内側を描画するために  x^2+y^2 < r^2
ハートの式 x^2+(y-|x|^0.95)^2<r^2
  #0.95を小さくすると円に近づきます

座標を入れると
(x-m)^2+((y-n)-|x-m|^0.95)^2 < r^2

実はこのままだとハートを横倒しにした形❥になるので、座標変換を行いました

単純に
en.transpose()を使うと逆ハート型になってしまいましたので、自力で反転しました
for m in range(sizex):
    for n in range(sizey):
        han[m][n]=en[n][sizex-1-m] 


重なるマークは省くとか考えたらいろんな画像を作れちゃいそうですね

そのうちブログの背景とかサムネがpythonでプログラムした画像になっているかもしれませんねw


<<<   ランダムに円を描画する【Python】



2017年3月2日木曜日

ランダムに円を描画する【Python】


画像処理の基礎になりそうな図ができました。

# -*- coding: utf-8 -*-
import numpy as np
import random
import scipy as sp
sizex = 1000
sizey = 1000
r = 100
en = np.zeros([sizex,sizey])
for m in range(sizex):
for n in range(sizey):
seeds = random.randint(1,50000)
if seeds == 1:
en += np.fromfunction(lambda x,y: (x-m)**2+(y-n)**2<r**2, (sizex,sizey))
sp.misc.imsave("testing.png",en)
view raw 03023 hosted with ❤ by GitHub


sizex = 1000
sizey = 1000
#画像サイズ

r = 100
#円の半径

en = np.zeros([sizex,sizey])
#np.arreyを0で埋め尽くす

for m in range(sizex):
    for n in range(sizey):
        seeds = random.randint(1,50000)
#1pixelに対して50000通りの種を作る

        if seeds == 1:
#種が1であれば(確率は1/50000,総pixel数は1000^2=1000000)

        en += np.fromfunction(lambda x,y: (x-m)**2+(y-n)**2<r**2, 
(sizex,sizey))
#半径rに応じて行列をつくる

sp.misc.imsave("testing.png",en)
#np.arrayをpngファイルとして保存


画像作ったり編集するのも楽しいですね







FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】 その2

前回(FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】)からの続きです。

FC版ドラクエ1のレベル18にしてはりゅうおうに勝率50%とやけに高いなぁと思っていましたが、原因がわかりました。
if myMP >= 10:
behoimi = random.randint(85,100)
print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
view raw 03021 hosted with ❤ by GitHub


これが問題のコードです

HPが48以下のときにベホイミをかけるループですね

 if myMP >= 10:
 #MPが10以上ならベホイミをかけられるのでかけます

                    behoimi = random.randint(85,100)
                    print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
                    myHP += behoimi
                    myMP -= syouhiMP
                    if myHP >115:
                        myHP =115
#上から順に
#ベホイミ回復量85-100を 変数behoimi に代入
#文章
#自分のHPに behoimiを足す
#自分のMPをshouhiMP (10)を減らす
#HPが最大HPの115より大きくなってしまった場合、115に戻す


さて、ここから次の文章へのつなぎ部分が問題でした


  if myMP >= 10:
                    behoimi = random.randint(85,100)
                    print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
                    myHP += behoimi
                    myMP -= syouhiMP
                    if myHP >115:
                        myHP =115
                    else:
                        damage = random.randint(6,12)
                        print ("  りゅうおうに " + str(damage) + " のダメージ")
                        HP -= damage

悪さをしていたのはこの else以降の文章のインデントでした

このelse文は直前のHP部分の条件にかかっています。
したがって、ベホイミをかけてHPが最大HP(115)に届かなかった場合、さらにりゅうおうに追加攻撃できる状態でした。


それは強いですね、チートですね。

さて、書き直しますと

if myMP >= 10:
behoimi = random.randint(85,100)
print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
view raw 03022 hosted with ❤ by GitHub



見た目ほとんど変わりませんが、結果は大きく違います




さらに計算を早く回すために無駄な文章は結局削除し、勝率だけを求めるコードに書き換えました。

戦闘回数は10万回! 勝率は・・・・!?


import random
kati = 0
make = 0
step = 100000
for i in range(step):
myHP =115
myMP = 100
HP = 130
syouhiMP = 10
try:
while HP > 0:
if myHP >48:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
elif myHP >0:
if myMP >= 10:
behoimi = random.randint(85,100)
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
HP -= damage
if HP <= 0:
kati +=1
raise Exception
ryucommand = random.randint(0,1)
if ryucommand == 0:
mydamage = random.randint(24,48)
myHP -= mydamage
elif ryucommand == 1:
mydamage = random.randint(42,48)
myHP -= mydamage
if myHP < 0:
make +=1
raise Exception
except Exception:
pass
print (kati /step * 100)
print (make /step * 100)
view raw 03023 hosted with ❤ by GitHub



勝率:32.6%

だいぶ減りましたね、実際この条件ではこのぐらいだと思います。

実際のプレイではさらに

  • 後手を引く
  • 第一形態でHPを削られている
  • MPを消費してしまっている
などが原因でもうちょっと下がります

ちなみに第一形態でHPが90になった状態で第二形態と戦う場合
勝率16.1%になります。

HP85の場合は13.8%でした。

プログラムでは10万回の戦闘を5秒ぐらいで終わらせますが、実機でやったら1戦に数十分かかるので、精神的にこの確率よりも低くなると思います。





(5秒で10万回戦ってくれるりゅうおうさん)





2017年3月1日水曜日

FC版ドラクエ1 りゅうおうとの戦いシミュレーション【Python】

前回よりいろいろ改良し、いい感じのところまで作れてきたと思います

午前4時前・・・今日ももちろん仕事です、
プログラミングにはまっちゃうとやばいですね


さて、今日のところは詳しく書きませんが、以下の設定で1000回戦うコードを作りました(何万回でも良いですが)

勝率およそ63%くらいでした
かなり高いと思いますので、ドラクエ1に詳しい方いらっしゃいましたらご指導お願い致します

"""
基礎データ
ゆうしゃ(Lv18を想定)
HP115
MP100
こうげきとベホイミのみ
こうげき 6~12のランダム
ベホイミ 85~100のランダム

りゅうおう
HP130
こうげき 24~48
ほのお 42~48
こうげきとほのおの確率を半分とする

ルーチーン
HP49以上ならこうげき
HP48以下になったらMPが尽きるまでベホイミで回復
"""

# -*- coding: utf-8 -*-
"""
基礎データ
ゆうしゃ
HP115
MP100
こうげきとベホイミのみ
こうげき 6~12のランダム
ベホイミ 85~100のランダム
りゅうおう
HP130
こうげき 24~48
ほのお 42~48
確率半分とする
ルーチーン
HP49以上ならこうげき
HP48以下になったらMPが尽きるまでベホイミで回復
"""
import random
kati = 0
make = 0
for i in range(1000):
myHP =115
myMP = 100
HP = 130
syouhiMP = 10
turn = 1
try:
while HP > 0:
print("ターン"+str(turn))
turn += 1
if myHP >48:
print("ゆうしゃ のこうげき")
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
elif myHP >0:
if myMP >= 10:
behoimi = random.randint(85,100)
print ("ゆうしゃ は ベホイミのじゅもんを となえた!")
myHP += behoimi
myMP -= syouhiMP
if myHP >115:
myHP =115
else:
damage = random.randint(6,12)
print ("  りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
if HP <= 0:
print("りゅうおうを たおした!")
kati +=1
raise Exception
ryucommand = random.randint(0,1)
if ryucommand == 0:
mydamage = random.randint(24,48)
print("りゅうおうの こうげき")
print("ゆうしゃ は"+str(mydamage)+"のダメージを うけた!")
myHP -= mydamage
elif ryucommand == 1:
mydamage = random.randint(42,48)
print("りゅうおうは ほのおをはいた!")
print("ゆうしゃ は"+str(mydamage)+"のダメージを うけた!")
myHP -= mydamage
print(HP)
print(myHP)
if myHP < 0:
print ("ゆうしゃは しんでしまった!")
make +=1
raise Exception
except Exception:
print (kati)
print (make)
view raw DQ1-v1 hosted with ❤ by GitHub

---------------


出力例
ターン1
ゆうしゃ のこうげき
  りゅうおうに 7 のダメージ
りゅうおうの こうげき
ゆうしゃ は47のダメージを うけた!
ターン2
ゆうしゃ のこうげき
  りゅうおうに 11 のダメージ
りゅうおうの こうげき
ゆうしゃ は40のダメージを うけた!
ターン3
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうの こうげき
ゆうしゃ は44のダメージを うけた!
ターン4
ゆうしゃ のこうげき
  りゅうおうに 7 のダメージ
りゅうおうの こうげき
ゆうしゃ は34のダメージを うけた!
ターン5
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうは ほのおをはいた!
ゆうしゃ は45のダメージを うけた!
105
70
ターン6
ゆうしゃ のこうげき
  りゅうおうに 11 のダメージ
りゅうおうは ほのおをはいた!
ゆうしゃ は43のダメージを うけた!
94
27
ターン7
ゆうしゃ は ベホイミのじゅもんを となえた!
  りゅうおうに 6 のダメージ
りゅうおうは ほのおをはいた!
ゆうしゃ は46のダメージを うけた!
88
69
ターン8
ゆうしゃ のこうげき
  りゅうおうに 7 のダメージ
りゅうおうの こうげき
ゆうしゃ は43のダメージを うけた!
ターン9
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうは ほのおをはいた!
ゆうしゃ は45のダメージを うけた!
81
70
ターン10
ゆうしゃ のこうげき
  りゅうおうに 6 のダメージ
りゅうおうの こうげき
ゆうしゃ は25のダメージを うけた!
ターン11
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうの こうげき
ゆうしゃ は46のダメージを うけた!
ターン12
ゆうしゃ のこうげき
  りゅうおうに 10 のダメージ
りゅうおうの こうげき
ゆうしゃ は30のダメージを うけた!
ターン13
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうの こうげき
ゆうしゃ は26のダメージを うけた!
ターン14
ゆうしゃ のこうげき
  りゅうおうに 7 のダメージ
りゅうおうの こうげき
ゆうしゃ は33のダメージを うけた!
ターン15
ゆうしゃ のこうげき
  りゅうおうに 12 のダメージ
りゅうおうは ほのおをはいた!
ゆうしゃ は42のダメージを うけた!
46
14
ターン16
ゆうしゃ は ベホイミのじゅもんを となえた!
  りゅうおうに 8 のダメージ
りゅうおうの こうげき
ゆうしゃ は37のダメージを うけた!
ターン17
ゆうしゃ のこうげき
  りゅうおうに 7 のダメージ
りゅうおうは ほのおをはいた!
ゆうしゃ は44のダメージを うけた!
31
26
ターン18
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうの こうげき
ゆうしゃ は41のダメージを うけた!
ターン19
ゆうしゃ のこうげき
  りゅうおうに 11 のダメージ
りゅうおうの こうげき
ゆうしゃ は41のダメージを うけた!
ターン20
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうの こうげき
ゆうしゃ は42のダメージを うけた!
ターン21
ゆうしゃ のこうげき
  りゅうおうに 12 のダメージ
りゅうおうは ほのおをはいた!
ゆうしゃ は44のダメージを うけた!
8
29
ターン22
ゆうしゃ は ベホイミのじゅもんを となえた!
りゅうおうは ほのおをはいた!
ゆうしゃ は48のダメージを うけた!
8
67
ターン23
ゆうしゃ のこうげき
  りゅうおうに 9 のダメージ
りゅうおうを たおした!
kati637
make363


<<<   りゅうおうを倒すまでの攻撃回数【Python】if文,while文

スペースで区切られた数値を数値型でリストに格納【Python】



a = list(map(int,input().split(" ")))
view raw 02281 hosted with ❤ by GitHub

いろんなものを使ってますが、これで
入力されたスペース区切りの数値をそれぞれリストに格納することができます


例 入力値 "1 1 2 3 5 8 13 21 34 55 89 144"
a = list(map(int,input().split(" ")))
print(a)

=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]




---------------
結論だけ先に書きましたが、このブログでは結論に至るまでの考え方も載せたいので以下に書いていきます。

Pythonの初級プログラム以上では、入力された数値をリスト化して計算に使用する機会が非常に多くなりました。

スペース区切り(カンマ区切りなどでも良いですが)の数値をリスト化する際には、

a = input().split(" ")
を主に使います。インプットした文字列をスペースでスプリットするということです。


入力される文字が2行あった場合、
1 1 3 5
8 13 21 34
に対して
a = input().split(" ")
b = input().split(" ")
と2回インプットを行うことで、2行の文字列をa,bそれぞれのリストに格納できます。

ここでaの最初の数字とbの最初の数字を足し合わせる場合、

a[0] + b[0]
としたいのですが、入力された数字は"文字列"であるため、結果は
"18"
と出力されてしまいます。

したがって数字の計算をしたい場合は
int(a[0]) + int(b[0])
(出力: 9)
とint()で囲い、数値型に変換しなければなりません。


計算をする場合はほとんど数値型であるため、計算するたびにint()を出すのは面倒だしかっこ良くないです。

であれば、結局文字型で格納されているリスト内の数字を数値型にしてしまえば、毎回int()などを使わなくても良いことになります。

そこで使えるのが リスト内の文字列を数値(整数など)に変換【Python】最大値最小値の取得 で覚えたmap()です。

map()により、リスト内の文字型を数値型に変換することができます
a = input().split(" ")
b = list(map(int,a))
view raw 02282 hosted with ❤ by GitHub



これで入力された文字を b に数値型でリスト化することができました。

しかし1行の数字の入力に対して、2行のコードを使用するのはスマートではないと思いますし、入力される文字列が2行、3行と増えてしまうと、それだけプログラムも長くなってしまいます。

そこで1行にまとめる方法案として
いきなり数値型のままリストに格納する関数、メソッドがあるのか調べる
という考えを持っていましたが、初心者の私が調べたところなさそうでした。

うーん、どうすれば1行にできるかと悩んでいてもう一度コードを見たところ、

a = input().split(" ")
b = list(map(int,a))



「あれ、bの式にa入れればいいじゃん!」

a = list(map(int,input().split(" ")))
view raw 02281 hosted with ❤ by GitHub


ということにやっと気づき、1行のプログラムを書くことができました。


ちゃんちゃん♪