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行のプログラムを書くことができました。


ちゃんちゃん♪



2017年2月28日火曜日

高度なプログラミングは基礎の繰り返し


今日思ったことはタイトルで完結しています。

やはり基礎の充実は非常に大事ですので、自分のできる問題を数多くこなすことが重要だと思いました。

受験勉強と違って、ほぼ解き方が決まっていたりするわけではありません。
遠回りしたプログラムでも正解は正解です。

効率化やスピードは後回し後回し。



今日解いた問題は、今まで使ってきたメソッドをふんだんに使いました。
たとえば

mojiwake = input().split(" ")
  #文字列をスペースで分ける

intni = list(map(int,mojiwake))
  #リスト内の文字列を数字列に変化

sumlist =[]
for i in range (n):
  sumlist.append(intni[n])
  #空のリストを作成、n回繰り返してsumlistリストに加えていく
     (意味はないですが例として・・・w)




他にもあと何個か使いましたが、それはまた今度の記事で。
1つのプログラムを書くためにはいろんなメソッド、関数を組み合わせる必要があります。
上記のプログラムだけでも

  • 変数の使い方
  • input()
  • .split(" ")
  • list()
  • map()
  • int()
  • list =[]
  • .append()
  • for i in range()

これだけの文法が組み合わさっているわけです
どうすればプログラムが想定通り動くか、1個1個調べては悩み、調べては悩みでは埒があきません。


よく使う構造は、結局のところよく使って覚えるのが一番です。


2017年2月27日月曜日

paizaスキルチェックCランクの正解率低い問題に挑戦

うーん、なかなか難しいですね

条件を一つ一つ満たしていって、「そろそろいいかなぁ」と思って提出すると結構残念な判定になります。


問題自体をブログに載せる事はできませんので、どんな困難があるのかということを漠然に書いてみたいと思います(例なので色字だけ読んで頂ければ大丈夫です)


例えば
o2i35y28957234h2348ry28rwhr28
fj30497tujf084570956
w3oj42094w6
j2308929754urj8fwj35ru

アルファベットと数字の羅列した文字列が入力されるとして、それぞれ数字部分を選別し、奇数よりも偶数の数字が多ければTrue,同じならEqual,小さければFalseと出力する
(1行目は偶数が5個、奇数が1個なのでFalse,
 2行目は偶数が1個、奇数が1個なのでEqual)

という問題です。

このとき手順として

  • 数字とアルファベットを分ける
  • リストなどでそれぞれの数字を管理する
  • それぞれの数字が奇数か偶数か判定する
  • 偶数or奇数の数字の個数を判定する
  • 偶数が多ければTrue,同じならEqual、小さければFalseを出力


といったいろいろ面倒な手続きを踏まないといけないわけです

初心者の場合、いろんな変数を出したり場合分けをしていくうちに頭の中がごちゃごちゃになってしまい、だんだんちょっと書き直して実行→ちょっと書き直して実行を繰り返してしまいます。

Pさん(仮)は試行錯誤の結果
True
Equal
True
True

と、なんとか問題例の解答に適したコードができたので、そのコードを提出しました



するとどうでしょう、答案は間違いだらけ

なぜPさんは問題例の解答に適したコードを提出したのに間違いだらけだったのでしょうか






------

Pさんの解答を改めて見てみましょう

True
Equal
True
True


解答のなかに"False"がないですね、つまりPさんはFalseの条件判定をどこかで間違えていた可能性が高いです。


例題では正解しても、提出したコードのチェックは条件を満たすさまざまな値を代入してチェックします。

したがって例題とは異なる文字列が入力されたとき、Pさんのコードではそのすべての条件を満たすことはできなかったということになります。


------


Cランクの正答率が低い問題は、おおよそ”さまざまな条件を仮定したときに正確に動くプログラム”というのが求められます。慣れないうちは問題文をしっかり読み、すべての条件に当てはめられるプログラムを作成できるかどうかが重要になるかと思います。プログラミング速度はその後。


当然、1問を解くだけでも時間のかかる作業になりますが、このような正確性の練習の積み重ねがプログラミングの上達に重要だと信じております。



リスト内の文字列を数値(整数など)に変換【Python】最大値最小値の取得

moji = ("2 4 6 8 -10 15 -19 21")

などの文字列を整数型のリストにします

# -*- coding: utf-8 -*-
moji = ("2 4 6 8 -10 15 -19 21")
mojilist = moji.split(" ") #mojiをスペースで区切ってリストに変換
integer = list(map(int,mojilist)) #リスト内の文字列をint型に変換
print (integer)
view raw 02261 hosted with ❤ by GitHub



map関数に関していろいろ書こうと思いましたが、私自身まだmapの使い方がよくわからなかったので、今後勉強していきたいと思います

とりあえず今回は魔法の言葉として書いておきます
integer = list(map(int,mojilist))

型変換のとき、listを追加しないとエラーを吐くようなので忘れないようにしましょう

使い方の例を示します

文字列のうち、最大値を出力するときは max(リスト)を使います
# -*- coding: utf-8 -*-
moji = ("2 4 6 8 -10 15 -19 21")
mojilist = moji.split(" ") #mojiをスペースで区切ってリストに変換
integer = list(map(int,mojilist)) #リスト内の文字列をint型に変換
print (max(integer))
view raw 02262 hosted with ❤ by GitHub


最小値はmin()にします
# -*- coding: utf-8 -*-
moji = ("2 4 6 8 -10 15 -19 21")
mojilist = moji.split(" ") #mojiをスペースで区切ってリストに変換
integer = list(map(int,mojilist)) #リスト内の文字列をint型に変換
print (min(integer))
view raw 02263 hosted with ❤ by GitHub




最近風邪気味で1日だけプログラミング練習できませんでした。
1日だけなのにいろいろと忘れてしまったような感覚に陥ってます。怖いですね。

入門・初心者はやっぱり1日に少しでも練習できると良いですね



2017年2月25日土曜日

はじめての辞書型【Python】(paizaのpython入門じゃ教えてくれない)

ネット上の音声つきの親切な解説はリストまで

これ以上はサンプルコードや本での勉強が重要になってきます

辞書型の使い方

変数= {"文字1":値1,"文字2":値2,..."文字n":値n}

とすると、文字nに対応した値nを取得できます



さて今回のタスクは 「文字の置き換え」です
例えばABCと入力すると、それに対応された数字123が出力される、といった形です。

試しに"Python"という文字を"123456"に変換するコードを書いてみます



最初は愚直に書いてみます

# coding: utf-8
moji = "Python"
mlist = list(moji)
for i in range (len(mlist)):
if moji[i] == "P":
print(1,end="")
elif moji[i] =="y":
print(2,end="")
elif moji[i] =="t":
print(3,end="")
elif moji[i] =="h":
print(4,end="")
elif moji[i] =="o":
print(5,end="")
elif moji[i] =="n":
print(6,end="")
view raw 02225 hosted with ❤ by GitHub



moji = "Python"                   #文字を指定
mlist = list(moji)      #mojiを1文字ずつ区切り、mlistに格納
for i in range (len(mlist)):   #iをmlistの要素数だけ繰り返す
    if moji[i] == "P":     #moji[i]の文字がPであれば
        print(1,end="")    #1を出力する 改行なし
以下



これをスマートに辞書型で書きます

# -*- coding: utf-8 -*-
a = {"P":1,"y":2,"t":3,"h":4,"o":5,"n":6} #辞書に対応した文字と数字を入れる
moji = "Python" #変換前の文字をmoji変数に入れる
mojiList = list(moji) #mojiを1文字ずつリストに入れる
for i in range (len(mojiList)): #mojiListの要素数だけ繰り返し
print (a[mojiList[i]], end="") #辞書型に対応した数字を出力, 改行なし
view raw 02252 hosted with ❤ by GitHub





いやいや、for文にはリストをそのまま入れられるんでしたね、lenはつい癖でいれちゃいます

# -*- coding: utf-8 -*-
a = {"P":1,"y":2,"t":3,"h":4,"o":5,"n":6}
moji = "Python"
mojiList = list(moji)
for i in mojiList:
print (a[i], end="")
view raw 02253 hosted with ❤ by GitHub


だいぶスッキリしました!
最初のforとifの力技では文字が増えるたびにどんどん行数が増えますが、辞書型を使えば辞書の文字をいれるだけで大丈夫です。



今回ブログの書き方も途中でいろいろ思いついて、説明方法がバラバラですみませんでした(直さない)

Python修行 近況2

ブログ開設から1週間が経ちました。

ほぼ独り言を書いているだけですが、Pythonブログを書くことで復習しながら身につけていくというスタイルですのでコメント等なにもなくても続けていきたいと思っています

これまでの閲覧数は246、1記事に6~20程度の閲覧が着いています(だいたいは機械的な巡回だと思いますが詳しくは知りません)


さて、最近は「もし女」でスキルC相当の問題を解き始めています。

Dランクしか解いてこなかった人間にはやや難しくは感じますが、Dランクを数十問解いてきた努力はCランククリアにつながっていると実感しています

たぶんDランク5問ぐらいしか解いてなかったらCランクの問題見た瞬間にブラウザバックしていると思います。


Dランクのランキングでは、すぐに解き方がわかった問題では入賞するようになってきました。ただし3位の壁は厚い・・・w


逆にすぐに解き方が見えなかった問題は10分以上考えることもあり、40位代もそこそこあります。
ちなみにランキングは無作為に選ばれた50人のうちのランキングみたいです。

まぁ、40位代だとしても、正解者が90%とすると
rank = int(40/50)*int(90/100)*100
print (rank)
# 72
なので100人中の72人に入っているわけです。

こいうところ私はポジティブに考えますw
合格率70%の資格というのは"一定以上の勉強すれば"誰でも合格できるレベルですが、要するに"一定以上の勉強"をこなすことができたという称号が与えられるわけです。



paizaからの推定年収は現在422万円です。
10問ぐらい解くと1万円ぐらい上がっている気がします


そろそろスキルランクDを脱却しても良い頃合いでしょうかね




(1週間後の成果やいかに・・・!!)   Python修行3   >>>


2017年2月23日木曜日

~の倍数の値を取得【Python】リスト.append


リスト内の数字の合計【Python】for文とリスト操作の続きです

a = [23,17,13,42,91,83,156,248]

というリストがあるとき、13の倍数を取得します。

方法としてはfor文で取り出すことが考えられますが、取得された数値をprintするだけでなく、次の作業がしやすいリストの形で出力するにはどうすれば良いでしょうか

結果として
13
91
156
と改行した文字列でただ出てくるよりも、

[13,91,156]
とリストで整理されて出力されたほうが、次の作業がしやすいはずです。

ここではfor文で取得した値を"append"で追加するメソッドを使用します

# -*- coding: utf-8 -*-
a = [23,17,13,42,91,83,156,248]
# 13の倍数を取得
b =[]
for i in a:
if i % 13 ==0:
b.append(i)
print (b)
view raw 02234 hosted with ❤ by GitHub



b =[]
#空のリストを作成

for i in a:
#for文でリストaの要素数で繰り返し

    if i % 13 ==0:
 #a[i]を13で割ったときの余りが0であれば

        b.append(i)
   #空のリストbにa[i]を追加

print (b)




もちろん繰り返し回数を"len(a)"で取得しても良いです

# -*- coding: utf-8 -*-
a = [23,17,13,42,91,83,156,248]
b = []
for i in range(len(a)):
if a[i] % 13 ==0:
b.append(a[i])
print(b)
view raw 02235 hosted with ❤ by GitHub

<<<  リスト内の数字の合計【Python】for文とリスト操作



リスト内の数字の合計【Python】for文とリスト操作



for文の繰り返し回数にはリストをそのまま入れることができる!


し・・・知らなかった・・・。

# -*- coding: utf-8 -*-
a = [100, 250, 300]
goukei = 0
for i in a:
goukei += i
print (goukei)
view raw 02231 hosted with ❤ by GitHub


a = [100, 250, 300]
# aというリストを作る

goukei = 0
#goukeiという変数を作る

for i in a:
#aの要素数だけ繰り返す

    goukei += i
  #goukei変数にa[i]を足していく

print (goukei)
#goukeiを出力


なんて便利なんでしょう
私の今までの書き方だと↓

# -*- coding: utf-8 -*-
a = [100, 250, 300]
sum = 0
for i in range(len(a)):
sum += a[i]
print (sum)
view raw 02232 hosted with ❤ by GitHub



for i in range(len(a)):
でわざわざリストの長さを取得して合計を出してますね

まぁ、やってることはまったく同じですが





さて、実際はリストの合計を出すだけなら"sum"メソッドが用意されています

# -*- coding: utf-8 -*-
a = [100, 200, 350]
print (sum(a))
view raw 02233 hosted with ❤ by GitHub


2行。


あっさりしてますなぁ


~の倍数の値を取得【Python】リスト.append   >>>


基礎力が身についてきたらスキルチェックCにチャレンジ!【Python】

先日のブログの内容(PaizaスキルチェックDランクをひたすら解いている理由)をある程度こなしてきたら、やっぱりいろんなものにチャレンジしないといけないかなって思ってきました。

Paizaの問題には模範解答がついていません。このブログを見ても答えは書いてありません。また、自分の解答したコードよりももっといいコードがあるはずですが、どうすれば良くなるのかを知ることができません。

知っている基礎力だけで応用していくことは重要ですが、場合によっては解答へ遠回りをしてしまうかもしれません。

「if文が迷いなくかけるようになってきたなぁ~」、「for文の中にifを入れても頭の中で整理されて使えるようになってきたなぁ~」と、基礎が固まってきたと感じたら、ちょっと上の段階に挑戦してみましょう。

PaizaのDランクよりちょっと上というのは「入門~初心者本を覗いてみる」、「いろんな関数を調べてみる」という感じです。Cランクの問題はDランクの問題みたいに一筋縄ではいきませんので、ちょっとずつ進めていくのが良いです。

ちなみにPaizaスキルチェックと同等の問題を、スキルチェック以外で試してみることもできます。


もし次の常駐先が女子エンジニアばっかりだったら

問題自体はスキルチェックと同じ形ですが、制限時間など縛りはありませんし、ゆっくりと問題を解くことができます。

本の"演習問題"解けたかなー、うーん →次のページぺらっ っていう無機質な作業よりも飾りだけでもゲーム風になっているとぜんぜんモチベ違いますよ

ゲームの中でスキルランクC相当の問題が難しくて解けなかった場合は、今一度スキルチェックDの問題を解きまくって基礎力をつけましょう

C相当の問題を解けたら、スキルチェックCもちょっとずつチャレンジしていきましょう



<< PaizaスキルチェックDランクをひたすら解いている理由

2017年2月22日水曜日

使う関数は違っても結果は同じ【Python】プログラミングは人それぞれ

1~10の数字が入力されるとき、その数字番目のアルファベットを表示します。

例えば
1 ⇒ A
6 ⇒ F


最初に大変な例を
# -*- coding: utf-8 -*-
#1~10の数字が入力されるとき、その数字番目のアルファベットを表示
#5 ⇒ E
num = int(input())
if num == 1:
print("A")
elif num == 2:
print("B")
elif num == 3:
print("C")
elif num == 4:
print("D")
elif num == 5:
print("E")
elif num == 6:
print("F")
elif num == 7:
print("G")
elif num == 8:
print("H")
elif num == 9:
print("I")
else:
print("J")
view raw 02225 hosted with ❤ by GitHub




次にいささか短くした例を
# -*- coding: utf-8 -*-
#1~10の数字が入力されるとき、その数字番目のアルファベットを表示
#5 ⇒ E
a = "ABCDEFGHIJ"
al = list(a)
num = int(input()-1)
print(al[num])
view raw 022226 hosted with ❤ by GitHub


だいぶ短くなりました。

ある意味では最初の例はシンプルで、入門者(プログラム未経験者)でもコードでやりたいことがわかるという、非常に理解しやすいコードだと思います。

対して2番目のコードは少なくともリストの形を知らないとわかりにくいですが、プログラムのコードは4行に抑えられました。




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

竜王のHPを130として、1回攻撃すると10のダメージを与えられるとします。

変数に入れると

HP = 130
damage = 10

となりますね。

攻撃回数はHPが0になるまでなので、HPをダメージで割り切れる場合

HP / damage が攻撃回数です



次にHPをダメージで割り切れない場合を考えます。

damage = 9 のとき、
HP / damage は 14あまり6 となり、もう一回攻撃しなければなりません。

したがってdamage = 9 のときの攻撃回数は
(HP / damage +1) となります。


ループ基本形 if文
これをif文で書くと

# -*- coding: utf-8 -*-
damage = 9
HP = 130
if HP % damage == 0:
print (int(HP/damage))
else:
print (int(HP/damage)+1)
view raw 02221 hosted with ❤ by GitHub

これはdamage = 9と固定しているので、攻撃回数は

In [1]: 15

と表示されます。


--------------------------
それでは次にif文ではなく while文で記述してみます

ループ基本形 while文

臨場感を出して出力される文字も入れてみました。

# -*- coding: utf-8 -*-
damage = 9
HP = 130
while HP > 0:
print ("りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
print ("りゅうおう を たおした")
view raw 022222 hosted with ❤ by GitHub


出力結果は
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおう を たおした

となりました。



while文中でダメージの値をランダムにする

while文の場合はループの回数が決まっていないので、damageがランダムでブレたとしても攻撃回数を出力することができます


# -*- coding: utf-8 -*-
import random
HP = 130
count = 0
while HP > 0:
damage = random.randint(8,10)
print ("りゅうおうに " + str(damage) + " のダメージ")
HP -= damage
count += 1
print ("りゅうおう を" + str(count) + "かい こうげきして たおした")
view raw 02223 hosted with ❤ by GitHub

結果
りゅうおうに 8 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 8 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 10 のダメージ
りゅうおうに 9 のダメージ
りゅうおうに 10 のダメージ
りゅうおう を14かい こうげきして たおした

この例では1回のダメージを8から10としてランダム値を生成して攻撃しています。

ランダムなので実行するたびに竜王を倒すまでの攻撃回数は変化します



while文中で会心の一撃やミスを入れる

ここまできたら攻撃するだけでなく、会心の一撃やミスも入れてみましょう

# -*- coding: utf-8 -*-
import random
HP = 130
count = 0
while HP > 0:
lucky = random.randint(1,10)
print("ゆうしゃ のこうげき")
if lucky >= 9:
damage = random.randint(16,20)
print ("かいしんの いちげき!")
print ("  りゅうおうに " + str(damage) + " のダメージ")
elif lucky >= 2:
damage = random.randint(8,10)
print ("  りゅうおうに " + str(damage) + " のダメージ")
else:
damage = 0
print ("ミス")
HP -= damage
count += 1
print ("りゅうおう を" + str(count) + "かい こうどうして たおした")
view raw 02224 hosted with ❤ by GitHub


結果
ゆうしゃ のこうげき
  りゅうおうに 10 のダメージ
ゆうしゃ のこうげき
かいしんの いちげき!
  りゅうおうに 16 のダメージ
ゆうしゃ のこうげき
かいしんの いちげき!
  りゅうおうに 17 のダメージ
ゆうしゃ のこうげき
  りゅうおうに 9 のダメージ
ゆうしゃ のこうげき
  りゅうおうに 10 のダメージ
ゆうしゃ のこうげき
  りゅうおうに 9 のダメージ
ゆうしゃ のこうげき
ミス
ゆうしゃ のこうげき
  りゅうおうに 10 のダメージ
ゆうしゃ のこうげき
かいしんの いちげき!
  りゅうおうに 17 のダメージ
ゆうしゃ のこうげき
  りゅうおうに 10 のダメージ
ゆうしゃ のこうげき
かいしんの いちげき!
  りゅうおうに 18 のダメージ
ゆうしゃ のこうげき
  りゅうおうに 9 のダメージ
りゅうおう を12かい こうどうして たおした



うんのよさに応じて会心の一撃やミスの確率も変動させられますね

こんな感じでwhile文はゴール地点の値が決まっていて、ループ回数が決まっていないときに使いやすそうです

2017年2月21日火曜日

Pythonで文字変換

文字列.replace("変換前","変換後")

さっき覚えました。使い所はイマイチわかりませんが、便利な気がします(てきとう)

現場に残された謎のメッセージ・・・!? 死体の近くに「たぬき」!

angou = hanntaninntahatayasu
print (a.replace("ta","_")
view raw 02212 hosted with ❤ by GitHub


なんてとき便利かもしれません


# hann_ninn_ha_yasu



PaizaスキルチェックDランクをひたすら解いている理由

私は大学時代に個別指導の塾で中高生にいろんな科目を教えていたのですが、大学受験の英語の問題を解くにあたって重要なことを知りました。

”センター試験の英語レベルなら「新中学問題集」をしっかり解ければ大丈夫”

私立英語とかは大学に合わせた勉強が必要になるのですが、国公立の前哨戦ぐらいなら基礎力だけでなんとかなるということです。

といいつつ正確には基礎力があればちょっとした応用がきく、ですね。


中学英語と高校英語の違いというのは根本的には、中学なら"関係代名詞"とか"仮定法"を習いますが、高校になると"関係副詞"とか"仮定法過去完了"を勉強するというだけの話です。

したがって中学で関係代名詞とか仮定法をしっかり身につけている状態であれば、ちょっと形が違う関係副詞とか仮定法過去完了がでてきたときに違和感を感じ、どういうときに使い分ければ良いのかという場合分けが簡単にできるのです。

逆に中学の範囲で判断があやふやになっていると、問題の答えを見てもなんでここでは関係代名詞で次では関係副詞を使うのかがわからなくなってしまいます。




という感じで、長々とすみませんでした、Pythonプログラミングのブログでしたね。

要するに基礎力ってすっごく重要だということが言いたかったのです。

簡単なプログラミングならパッパパッパ仕分け作業でできるということが重要だと思っています。


また、プログラミングであれ英語の勉強であれ、簡単な問題を解き続けるというのはそこそこ忍耐が必要な作業です。基礎力はすぐには身につきません。


よく勉強法の本で「10日でマスター!!~~~」みたいな本がありますが、一般人はそんな要領よくできていません。

基礎力は日々の勉強で培われるもので、時間は掛かります。

地道に勉強を進めていきましょう。





まぁ、プログラミングはコピペできるのでいくらでも自分の能力を飛躍したコード書けちゃうんですけどね (弱いオチ)



電子書籍のススメ【Python】

超初心者からのPython勉強法では「入門のころは本なんて買うな!」と書きましたが、いろいろと視野を広げるためには本というツールも大事だと思います(実際は)。


でもプログラミングの本ってでかくて分厚いですよね

家で勉強するだけなら良いですが、長期休みで実家に帰って読みたいときとか外に持ち出して勉強したいときは本の分厚さがネックになります

1冊でも十分おもいですが、3冊4冊となるともう専用のバッグに入れないと厳しいですね





そこで私がおすすめするのは電子書籍です

電子書籍なら何冊でも外に持ち出せますし、iPadだけじゃなく文庫本ならiPhoneでも十分読めます。 amazonのkindle本なら両方でダウンロードして好きなほうで読むこともできます。



しかもkindle本って紙媒体で買うよりだいぶ安かったりします

↓の「みんなのPython 第4版」の本を見てみると、



単行本 2916円 88ポイント
kindle 2700円 396ポイント

ポイント含めると電子書籍のほうが524円安い!




kindle本の問題点としては、電子書籍を読むということに慣れないときついということぐらいでしょうか

ここはどうしても若干ハードルになってしまいますが、慣れてさえしまえば

  • 安い
  • 持ち運び便利
  • 引っ越しのときに箱に詰める必要がない


といういいことだらけの生活を満喫することができます


ちなみに上で紹介したPythonスクレイピングの本も



驚異のポイント725pt!!


最近、私の家の近所の本屋がどんどん潰れ、自転車で40分ぐらい走らないといけないぐらい本屋がなくなってしまいました。

本屋は好きなんでさみしい気持ちもありますが、こりゃamazonには勝てないよなぁとしみじみ思います


文字列の先頭文字だけを抽出【Python】

今までやったことのない操作をするとき、「自分が知らない関数を使うんじゃないだろうか」と思うことがよくあります。

しかし実際には基本的な関数の組み合わせだけで問題を解決できることも多いのです。



今回のタスクは「文字列の先頭部分だけを抽出して出力」です。

Hello World

と入力を受けた場合に"H"と"W"を取得すればよいのです。


そこで最初に考えるのは

「大文字を取得する関数を使えば終了」

もちろんその通りかもしれませんが、その関数自体を知らないとき、使い方がわからないときは調べないと使えませんね。

単純作業であれば関数を調べなくても知っていることだけで済ませたいものです。

moji = input().split(" ")
print (moji[0][0] + moji[1][0])
view raw 02211 hosted with ❤ by GitHub

というように2行でパパっと書くことができました (初心者の私がこれを思いつくのに10分かかってしまいましたが)

解説

moji = input().split(" ")
#入力される文字を"半角スペース"で区切り、リストに挿入
#moji:   ['Hello' 'World']


print (moji[0][0] + moji[1][0])
#リストmojiの[0]番目の[0]文字目を取得 (1番目の要素の1文字目)
#リストmojiの[1]番目の[0]文字目を取得 (2番目の要素の1文字目)
#して出力


大文字とか関係なく先頭の文字を取得することができました

忘れられしWhile文【Python】

初期値
while 条件式:
  処理
  カウンタ変数の更新
  

単純なようで、使わないとすぐわすれちゃいますね

入門からプログラミングを勉強して for i in range () の形を覚えちゃうとすっごく便利なのでwhileは全然使わず、記憶の彼方に消えてしまいました。

使い方は

n = 0
while n <= 2:
print (a)
n += 1
view raw 02201 hosted with ❤ by GitHub

という感じです





PaizaのスキルチェックはDの問題を相変わらず解いていますが、その中で while は一回も使いませんでした

今一度 while の使い方について考えてみましょう

  • while文は初期値とカウンタ変数の更新が楽
  • for文と違い、回数に規定がない



もちろんfor文もrangeの部分をうまく変えてしまえば同じこともできると思いますが、基本的にはこの2点だと思います

import random
tozan = 0
while tozan < 3776:
climb = random.randint(10,500)
print("富士山を"+ str(climb) + "m登った")
tozan += climb
print ("富士山登頂!")
view raw 02202 hosted with ❤ by GitHub
こんな感じで、ランダムで何回処理するかわからないときとかに使いやすいと思います


whileもちゃんと身に着けて、使うべきときに使う判断ができるようになりたいですね

2017年2月19日日曜日

Python修行 近況1

ブログ始めてまだ2日目ですが、ブログは最初は量で攻めたいのでいろいろ投稿したいと思います


現在の勉強方法


  1. Paiza スキルチェックDランクの問題をひたすら解く
  2. コードガールこれくしょん Pythonの完全クリアを目指す

という感じでやっています。

本をやめてネット上で勉強するようになってから、ほんとうに勉強が捗るようになりました。

Paizaは最初のプログラミング勉強に対して非常にに優れたサイトだと思います。

ということでリンク貼り貼り
https://paiza.jp/
https://paiza.jp/cgc


超初心者からのPython勉強法でも紹介したとおり、最初は「コードガールこれくしょん」のクリアから始めました。


今でもコードガールこれくしょんはやっていますが、改めて見ると
  • 「間違いを正せ」→修正なしで正解
  • 「nが20以上になるように」→問題のコードの変数が「n」でなく「a」
といった理不尽な問題も多数見られますねw

しかしプログラミングはミスの修正が重要なので、修正能力を身につけるという意味で肯定的に捉えましょうww(実はわざと問題文間違ってたりして?)


コードガールこれくしょんは基本的に4問1セットで出題され、1セットの問題を限られた時間内でクリアするとダイヤ(ガチャ回すのに必要)がもらえます。

なので現在は今まで解いてきた問題をすべてダイヤを多くもらえる時間内でクリアすることを目標に解いてます。


現在はStage10まで完全クリアしています。


そしてガチャの引きは・・・



という感じ、URどころかSRさえ集めきれていない


つまりPythonモードを完全クリアし、ガチャ券(ダイヤ)を最大限集めてガチャしたところでURを取得できるとは限らない(できないと思う)。

URほしけりゃ他の言語も頑張れということですね!



引き続きコンプを目指して頑張っていきます( ;∀;)







さて、Paizaのスキルチェックですが、ランクDの問題ならそこそこ短時間で解けるようになってきました。



トロフィー22個ということで、22問解いたということになります。

確実にランクDで勉強した後、ランクCにも挑戦していきたいと思います



1週間後・・・ Python修行 近況2  >>>



文字列が等しいか判定するだけなのにだいぶ悩んだ話【Python】

2つの文字列があったとする

uhyohyoohooho
uhyouhaahaaha

さて機械的にこの文字列が等しいかどうか判定するために、Python初心者の私が考えたことは


---
「うーん、2つの文字を"listA"と"listB"のリストにしてfor文で繰り返し、iのときのa[i]とb[i]が等しいければいけるかなぁ」


listA = list(input())
listB = list(input())
n = len(listA)
for i in range (n):
if listA[i] == listB[i]:
print........
view raw gistfile1.txt hosted with ❤ by GitHub

・・・とprintのところで悩みました。

1文字ずつ何を出力したいんだろう・・・?

あれ、えーと全部正しければいいからprintする必要もないし

iを入れて違うところでelseでfor抜けて"違う文字列でした"を表示すれば、いやいやfor抜けたら正しい文字列でも表示されるんじゃくぁwせdrftgyふじこlp・・・














~10分後~




if listA == listB:
print("同じ文字列です")
view raw 02192 hosted with ❤ by GitHub

超シンプルだよ!

はい、リスト全体を比較するときは変数をそのまま使えばいいだけでした

めでたし めでたし

入力される改行区切りの数字をリストに変換【Python】



# coding: utf-8
a = []
for i in range(10):
a.append(input())
b = list(map(int,a))
print (b)
view raw 02191 hosted with ❤ by GitHub


a = []
#格納するための空のリストを生成

for i in range(10):
#10個の数字が入力されるとする

    a.append(input())
#リスト a に入力された数字を追加していく
#このときリスト内の数字は文字列"str"

b = list(map(int,a))
#魔法の関数mapでintに変換
#list()で囲まないとエラー吐きます

print (b)
#数字のリストを出力


今回からGitHubからプログラムコードの出力を試してみました

若干白黒のコントラストが強すぎるかなぁ

指定された文字数だけ文字を表示する【Python】

入力される文字列 aiueokakikukeko
のうち先頭からn文字を出力する

# coding: utf-8
a = list(input())
n = 10 
for i in range (n):
    print (a[i], end="")



-----
1行ずつ解説

a = list(input())
#入力される文字列を1文字ずつ区切り、リストに挿入する

n = 10 
#例としてn=10, 入力から受けるときはn=int(input())

for i in range (n):
#n回繰り返す

    print (a[i], end="")
  #a[0]からn回入力し、入力後は改行しない
-----

他いい方法があったら教えてください( `・∀・´)ノ

複数の文字列を出力するときに改行でなく"-"で結合するには?

Paizaのスキルチェックをずっとやっていたのですが、タイトル通り

「複数の文字列を出力するときに改行でなく"-"で結合する」方法がなかなかわからず手こずりました


問題の内容をそのまま書くわけにいかないので例を書きます


--------
入力:4 python weiwei nyu mya
(1列目に数字、数個の文字列がスペース有りで入力される)

期待する出力:python-weiwei-nyu-mya.
(最初に入力された数字分、以下の文字列を"-"で結合し表示、最後にピリオド)
--------

そこで私が苦し紛れに書いたコードが以下です


-----
# coding: utf-8
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="")
-----


まぁツッコミどころ満載なのはわかりながら書いてますが、

やさしくツッコんで頂ける方がいらっしゃいましたらお願い致します

自分だけでは改良していくのがむずかしいので・・・




意図(自分で解説)
-----
n = input()
nn = int(n)
#int(input())みたいに1行にしようとしたがエラー出たので2行にしました

a =[]
for i in range(nn):
    a.append(input())
#空のリストを作ってnn個の文字列をリストに挿入

for i in range(nn):
    print(a[i],end="")
#nn回まで、リストa[0]から文字列を挿入、改行を入れないで以下に

    if i < nn-1:
        print("-", end="")
#無理やりハイフンだけ挿入して

    elif i == nn-1:
        print(".", end="")
#無理やり最後だけピリオドを打つ
-----

とりあえずテストは動いて正常ならOKということで合格をもらってますが・・・w

もっとスマートに書きたいですね

2017年2月18日土曜日

超初心者からのPython勉強法

入門向けの本を買って読み進めよう!!


・・・



は、ムリ(結論)

基本的に本を見てもつまらんし、本で勉強できる方はこんなサイトに来ることはないだろう(笑

私がその良い(?)例で、オライリーの本数冊と入門書を買い勉強をしようとしたが、30分と続くことはなかった


いいかい、
なにか勉強するにあたって、現代は"基本無料"でなんでもできる

最初に本を買って無駄にお金を使うな、ネットで無料で勉強を始めよう!





インタラクティブで身につける

そう、繰り返すが"基本無料"でなんでも勉強できる時代だ

数ある勉強方法のうち、最も入門向けに適した方法は「インタラクティブ~(勉強を始めたい)~」という方法だ

インタラクティブは「対話型」とかそんな感じで訳されるが、ネット上の勉強方法として意訳すると、「簡単な操作をすると、その操作が正しいか間違っているのかを教えてくれる」という感じだ。

Pythonにおいてオススメのインタラクティブ勉強サイトは
コードガールこれくしょん」だ
https://paiza.jp/cgc (完全無料、ガチャとかあるけど無料ガチャだけ)


コードガールこれくしょんはプログラムの基礎の基礎、文字の入力方法からきちんと勉強することができる

簡単な演算子を使って計算ができるぐらいの人でも、新たにPythonを始める人は己の力を過信せず、print()からif文、for文と少しずつステップアップを目指そう

ちなみにPythonのステージは17まであり、気合を入れてやれば数日で全クリすることができる

難点といえばステージ12あたりから説明動画のリンクが明らかに間違っているために、勉強していない内容が問題として出題されることがあるぐらいだ

が、「説明ねーじゃん!」と憤りながらも問題文から推測したり、横でググってみたりするといった試行錯誤を繰り返すことでとりあえずクリアはできる




このブログの著者は2017年2月18日現在この記事を書いているが、コードガールこれくしょんを始めたのが2月8日、ステージ17を終わらせたのが2月12日という完全初心者



一緒にPythonを勉強して頂ける方、稚拙な私のPythonプログラムを直して頂ける方がいらっしゃいましたら今後もよろしくお願いいたします (こういうときだけ丁寧語)


初投稿

Pythonプログラミングを始めました。
勉強方法とかを書いていきたいと思います。