この投稿では2つの大事な内容を扱いと思っています.1つは条件分岐文というもので,for文に並んでプログラミングでかなり大事になってくるパーツです.名前から大体機能の予想はつくかと思いますが,「もしAならBをしてください」のような指示です.もう一つは標準入力です.プログラムであらかじめすべてを決めておくのでなく,実行した後に何かを自分で入力したいときがあります.例えば「入力した数に3をかけてその数字を出力しなさい」のようなプログラムを考えると,「入力した数」はプログラムを作成する際に決まっていない場合も考えられます.
また,前回の投稿までの知識では言語処理100本ノック 2015の一章の問題は全部解けないかと思います.このの投稿の最後で,それを解く際に助けになろうであろう知識を羅列していこうと思います,あくまでもpythonの基礎的使い方がメインです.
条件分岐:if文,else文,if文
日本語の「もしAなら,Bをしなさい.」という指示に対応するプログラムの言葉を「条件分岐(文)」といいます.ある条件(A)のときだけ実行する,という指示のことです.具体例を見ながら理解していきましょう.
b = 'blue' if b == 'blue': print( 'b is blue' ) else: print( 'b is not blue' )
実行結果は「b is blue」と表示されます.行ごとに見ていきましょう.1行目ではbという変数にblueという文字列を代入しています.プログラムでの「=」は代入の意味でしたね.
そして2行目からが今回習う内容です.if文を説明する前に,まず「b == ‘blue’」の部分に着目してみましょう.
ブール型:真偽判定
試しに次のコードを実行してみてください.
b = 'blue' print( b == 'blue' )
実行してみると「True」と表示されます.Ture は英語で「真」という意味ですね.なぜこのような答えが返されるのでしょう.
まず,イコールが二つつながった「==」の意味は数学でのイコール「=」です.つまり「b = ‘blue’」とは「bという変数に格納されている値は’blue’という文字列に等しい」と翻訳されます.このように「真偽を判断できる(プログラム上の)文章」は実はその文章自体で一つの型を持っており,それをブール型と呼びます.
先ほどの翻訳された文章を「真か偽」で判断するのであれば哲学的な問題を抜きにすれば明らかに真です.一行目でbという変数にblueという文字を格納したので,もちろん真ですね.なのでprint文で表示された文字がTrueとなったのです.ちなみに翻訳された式が嘘だと「False」と表示されます.
if文
if文に話を戻します.if文の一般的な使い方は次のようになります.
if ブール型の条件文: インデントされた実行文
ブール型のところには真偽を判定できるものであれば何でもよいです.例えばxに何か実数値が代入されていた時にブール型の部分に「x>0」のような文も入れれます.これは日常言語に直すと「xは0より大きいか?」ということになるので,確かに真偽を判定できますね.
そしてif文の最後にコロン(:)を付けることを忘れないようにしましょう.忘れるとエラーになります.
最後に,もしif文の条件が正しかった際に実行したいプログラムをすべてインデントして書いてください.条件が真の場合はif文の次の行にあるインデントされた文からインデントが終わる分までが実行されます.逆にif文の条件が偽だった場合はインデントされた文は実行されません.このインデントされた文をif文の実行文といいます.日常言語の「もしAなら,Bをしなさい.」を対応させるとAはブール型の条件文,B条件文が真だった場合の実行文になりますね.
ただし,あまり日常言語と比べても問題です.プログラムのif文が日常言語と違う部分は,条件が成り立たない場合になります.ある人が「あした雨が降るなら,会社を休む.」と言ったとしましょう.そして次の日,雨が降ったのでこの人は確かに会社を休みました.これは「雨が降る→会社を休む」という図式が確かに成り立っています.では,もし晴れたのにその人が会社を休んだという場合はどうでしょう.腑に落ちませんがその人曰く「...別に雨が降ったら休むって言っただけで,晴れたら休まないとは言ってないです.」だそうだ.つまり日常言語は「条件文-実行文」の図式からいうと,条件文が偽である際に実行文を実行するかどうかについては何も語っていない.
反面,プログラムの「条件文-実行文」の構造はそうではありません.条件文が偽ならば実行分は絶対実行されません.初心者の方はあまり気にする必要はないかもしれませんが,日常言語とプログラム言語の違いを理解しておくことは大事です.気を付けましょう.
この件とはちょっと違いますが,次のような面白いジョークもあるのでぜひ見てください(ちょっと難しいかもしれませんが).
else文
if文の条件を満たされなかったときに,次の処理をどうするのかを決める必要がある場合があります.その際に用いる元のしてelse文というものがあります.先ほどの例をもう一度見てみましょう・
b = 'blue' if b == 'blue': print( 'b is blue' ) else: print( 'b is not blue' )
ハイライトされている部分が「else文」というものになります.else文の一般的な使い方は次のようになります.
if 条件文: 実行文1 else: 実行文2
else文は必ずif文とセットで使われます.for文やif文同様,コロンを付けるのを忘れないようにしましょう.
上の一般的な使い方を日本語に翻訳すると「もし条件文が真ならば,実行文1を実行しましょう(実行文2は実行しない).偽であれば実行文2を実行しましょう(実行文1は実行しない)」となります.
つまり一番最初のプログラムをすべて日常言語に翻訳すると
bに'blue'という文字列を代入します. もし(bに格納されているものが'blue'という文字列と等しい)が正しいのであれば, 「b is blue」と表示しましょう. そうでない場合は, 「b is not blue」と表示しましょう.
となるのです.
elif文:もっと一般分岐させる
if文とelif文の組み合わせしか使えない場合「ある条件を満たすか,そうでないか」の二分法的考え方になってしまいます.このままでは条件によっての処理の変化を2つまでしか考えられません.そこで登場するのがelif文です.例えば次のような日本語になっているプログラムを考えてみましょう.
x点を取った人への評点は もし90点以上なら, Aです. それ以外の人で,80点以上なら, Bです. それ以外の人で,70点以上なら, Cです. それ以外の人の全員は, Dです.
このようにより多くの分岐を作る際に用いるのがelif文です.次のような使い方になります.実際例を見た方が早いでしょう.次のプログラムの中にある「>=」は数学の[math]\geq[/math]と同じ「以上」という意味になります.
x = 74#74点の場合 if x >= 90: print('A') elif x >= 80: print('B') elif x >= 70: print('C') else: print('D')
これを実行すると「C」という結果を表示してくれます.
elif文はelse文のときと同じく,必ずif文がそれより前に現れている必要があります.そしてその意味は「上(まで)のif文やelif文の条件に該当せず,今見ているelif文の条件に該当する場合,今見ているelif文の次の行からインデントされている部分を順に処理していく」というものになります.
もう少しわかりやすく説明しています.今まで出てきたif文,else文,elif文をフィルターのように考えてみてください.そして上のプログラムを実行した際に上から順にどのような流れになっているのか書いてみると次のようになります.
- 1行目:xという値を74に設定する.
- 2行目:xが90以上であるか判別する.今の場合,これは偽である.よって3行目のインデントされた処理は飛ばされる(フィルター通過).
- 4行目:xが80以上であるか判別する.今の場合,これも偽である.よって5行目のインデントされた処理は飛ばされる(フィルター通過).
- 6行目:xが70以上であるか判別する.今の場合,これは正しい(真である).よって7行目のインデントされた処理をする(フィルターに引っかかる).
- 7行目:画面に”C”と表示する.
- それ以降のelifやelse文は実行されない(上のフィルターで引っかかったから).最後の行まで来たので,プログラム終了
コマンドラインから入力(標準入力)
今度は標準入力の話をしたいと思います.
標準出力,標準入力の「標準」の意味
ある意味で,コンピューターは単純(馬鹿)です(「ある意味で」ですから誤解されませんよう.私はむしろ,その単純なものを複雑にして使いこなす人間すごいと思います).「0と1しか区別できない」,「電源抜けば一発で死ぬ」,などなど人に例えることで「(ある意味)馬鹿だなー」と思われるような点はいくらでもありますが,その中でも「言われたことしかできない(プログラムに書いてあげたことしかしない)」とうい特徴があります.こう書くと,人工知能業界あたりから「その考えは古い」という声が聞こえますが,とりあえずいま皆様がpythonを学ぶ際に使っているパソコンは上の意味で「馬鹿」なパソコンなので,まぁ揚げ足取りせずに進みましょう.そして,その「馬鹿」な例の一つとして「ごちゃごちゃ計算したものの,その結果をどう人間に表示させるのか指示しないと,そもそも表示してくれない」というのがあります.これではせっかく計算させても意味がないですね.
しかしご心配なく.プログラムには「特に指示がなければ,ここに出力しろ」という場所が決まっています.その場所のことを「特に言われなくてもデフォルト(標準)で表示する場所」といういみで標準出力といいます.出力の逆の入力の場合も同様に,「特に言われなくても,この場所からの信号があればそれを(無視しないで)受けろ」という特定の場所があり,その場所のことを標準入力といいます.一般に,標準出力はプログラムを動かしている画面,標準入力はキーボードからの入力になります.
Python で標準入力から,文字列を受け取る
では,プログラムを動かした後にキーボードからの入力を受け取る方法を見てみましょう.Pythonファイルを次のように書いてみてください.
x = input('今の時間を入力してください : ') print(x)
これを実行すると,まず”今の時間を入力してください:”という画面が現れます.そしてその画面に,例えば「I don’t know.」と入力してみましょう.そしてEnterを押すと,もう一度「I don’t know」と返してくれます.
中身は簡単です.「x = input(‘文字列’)」とすることで,「文字列をまず表示させて,次に文字を打てるようにしてください.そしてEnterを押されるまでを入力された文字列とします.その文字列をxとしましょう」という意味になります.先ほどの場合「I don’t know」という文字列がxの意味になっています.
そして二行目はただその文字列を表示させるだけですね.
注意していただきたいのは,python で上のようにinputで標準入力から入力を受けた場合,数字を入力しても文字列として扱われることに気を付けましょう.例えば次のようなプログラムを作ってみましょう.
x = input('今の時間を入力してください : ') print(x+1)
これを実行して,’今の時間を入力してください : ‘が表示されてから「1」を入力してみましょう.予想(期待)は「2」が表示されてほしいところですが,なぜかエラーが吐かれてしまいます.これは,「input(‘文字列’)」という方法で入力したものはstr型(文字列)になってしまっていて,いくら1と入力したからといってもint型(整数)として扱われていないことが原因です.
Python で標準入力から,数字を受け取る
では,入力として数字を受け取るにはどのようにすればよいでしょうか? 答えは次のようにしてみてください.
x = int(input('今の時間を入力してください : ')) print(x+1)
これを実行して,’今の時間を入力してください : ‘が表示されてから「1」を入力してみましょう.期待通り「2」を表示してくれるでしょう.このように「int(hoge)」と書くことで,hogeという型(今の場合文字列)を無理やり整数型に変更することができます.「input(…)」の部分までで「1」を文字として受け取り,それを整数の型に変えてからxに代入しています.
そのほかの文字列操作
さて,あとは言語処理100本ノック 2015を解く際に助けになるであろう,pythonの基本的文字列操作を書いていきます.「Pythonの基礎だけを学びたい」という方は,このパートは飛ばして読んでいただいてもよいでしょう.
出力の形式を指定
print('xの値は{0}です'.format(x))
printのようにただ出力するのでなく,細かい条件を指定して出力したいときに「format」という機能を使うことがあります.これはまた後でちゃんと説明することにして,今はそういうものがあるのだぐらいで理解しておいてもよろしいです.簡単に説明すると「’文字列{0}’.format(x)」とすることで,「{0}のところにxの値を入れて,”(クオテーションマーク)の中を表示しなさい」ということになります.formatは複数の変数を同時出力するときにも使えて,例えば
x=10 y=20 print('xの値は{0},yの値は{1}です'.format(x,y))
を実行すると「xの値は10,yの値は20です」と表示されます.変数を複数出力する際には,文字列の中で変数を書きたい部分を{番号}の形で順番に書き,formatのかっこの中に番号の順番に入れていけばよいです.
文字列の Unicode を表示
言語処理100本ノック 2015の「08-暗号文」で必要になる知識です.暗号化の際に使います.
x = ord('a') print(x)
「ord(‘文字’)」とすることで,文字のユニコードをint型で返してくれます.上のプログラムを実行すると「97」という数字が返されるので,小文字のaのユニコードは97であることがわかりますね.
Unicode から文字列
同じく,言語処理100本ノック 2015の「08-暗号文」で必要になる知識です.今度は暗号の復号化に用います.
x = chr(97) print(x)
先ほどとは逆で,「chr(整数)」とすることで,整数の値に相当するユニコードの文字を意味します.先ほど見た通り,小文字のaのユニコードは97だったので,char(79)は小文字のaを表しています.よってこのプログラムはaを表示してくれます.
アルファベットの大文字小文字判定
またまた言語処理100本ノック 2015の「08-暗号文」で必要になるかと思われる内容です.解く際に,条件文の中に小文字か大文字化の判定を使う必要があるかと思います.
x = 'A' y = 'a' print( x.islower() ) print( y.islower() )
これを実行すると,「Flase(改行)True」と出力されるかと思います.「x.islower()」とすることで「xに格納されている文字が大文字の場合はFalse,小文字の場合はTrueを返す」ということをしてくれます.つまり,小文字判定をしているわけです.コロン(.)の前にあるxという文字ではなく,xという変数が意味している文字の小文字判定なので注意しましょう.「is lower(より低い=小文字)」ってことが小文字判定っていう意味になっているんですね.
この問題を解く際には直接使いませんが,次のように大文字判定もできます.
x = ‘A’
y = ‘a’
print( x.isupper() )
print( y.isupper() )
[/python]
これを実行するとさっきとは逆に,「True(改行)False」と出力されるかと思います.「x.isupper()」とすることで「xに格納されている文字が大文字の場合はTrue,小文字の場合はFalseを返す」ということをしてくれます.つまり,小文字判定をしているわけです.「is uppeer(より高い=大文字)」ということですね.
一文字についての判定はこのisuppre()とislower()を用いて簡単にできましたが,格納されているものが文字ではなく文字列であるときは注意が必要です.文字列の場合「文字列が大文字であるか,小文字であるか?」というのは意味をなさない,ナンセンスです.こういう場合,isupperとislowerの機能は少し違ってきます.初めて習われる方は気にしなくてもよいですが,気になる方は次の投稿を参考にするといいかと思います.文字列についてのisupper(), islower()について大変よくまとまっております.
[Python]Pythonの islower() と isupper() の判定処理のワナ – 強火で進め
文字列のランダムな並び替え
言語処理100本ノック 2015の「09-Typoglycemia」で必要になるかと思います.次のようにすることで,文字列をランダムに並び替えれます.
import random s1 = 'mojiretudayo' s2 = ''.join(random.sample(s1,len(s1))) print(s2)
少し難しいのでパーツを分けます.
ランダムに並び替える
まず「import random」とすることで乱数を使えるようにします.乱数については,Matplotlib 超入門(2)文字の挿入,ヒストグラムの投稿に書いてありますので,そちらを参照していただきたいです.そして「random.sample(s,n)」は「sというリスト(もしくは文字列)から,nこを重複なくランダムに持ってきて,新たにリストを作る」ということになっています.上の例の場合,s1という文字列からs1の長さ分の文字をランダムにとってくるということをしていて,つまり文字列全体をランダムに入れ替えたリストを実現することができました.念のため例を見てみましょう
import random s1 = 'mojiretudayo' print( random.sample(s1,len(s1)) )
出力結果は乱数を使ているため実行するたびに代わりますが,例えば自分は[‘e’, ‘t’, ‘o’, ‘r’, ‘u’, ‘m’, ‘y’, ‘o’, ‘d’, ‘a’, ‘j’, ‘i’]と出力されました.確かにリストの形で並び変わっていますね.
後は,このリストを一つにくっつけて文字列に変えるだけです.
リストの文字列を一つに結合
最後にjoinというものについて書きます.上の例のように,joinというものを使って,リストの文字列を一つに結合することができます.例を見てみましょう.
list = ['ab','cd','ef','gh'] mojiretsu = '8'.join(list) print(mojiretsu)
これを実行すると「ab8cd8ef8gh」が出力されます.joinの使い方は「(str型の文字か文字列).join(リスト)」となり,これで「リスト同士をくっつけ文字列にするが,連結部分に(str型の文字か文字列)を挟む」という指示になっています.つまり上の例では,「listの中にある文字列をくっつけるんだけど,のりとして’8’という文字を使いなさい」ということなので,先ほどのような出力になります.
これを応用して,連結部分ののりを空白(”or””とする.マークの中には何もない)にすると「なんも挟まずにくっつけろ」という指示になるので,リストの文字列をただ単につなげることができるわけになります.ここまでを理解していただくと文字列をランダムに並び替える方法がわかりそうですね.
Python 超入門,お疲れさまでした!
ここまでのpythonの知識を組み合わせることで,言語処理100本ノック 2015の1章は解けると思います.一連の投稿を書く際に自分の解答を振り返って見逃しがない様に気を付けたつもりですが,もしかしたらミスなどがあるかもしれないので,その時はコメントなどで意見をください.
そして,ここまででpython入門シリーズも一区切りといった感じでしょう.ここまでの過程で標準出力,反復文,条件分岐,リスト,これらの扱いにひとまずpythonを初めて触る方にとっての「超入門」のレベルは超えれたのではないかと考えます.後は,各自作りたいプログラムがあったときに,必要であろう機能をインターネットで調べて使えるようにし,もう一度見たときにそれがどういう意味なのか思い出せるようにメモをする習慣さえつければ,プログラミングの実力派伸びていくかと思います.このメモの習慣が慣れるまでは意外と難しいんですよね...このメモの手段としてブログという手段は大変有効なので,プログラミングでつまずいたことやひらめいたことのメモとしてブログをはじめてみるのもありかと思います.
さて,私はといいますと,今後は「超入門」ではなく「入門」というシリーズ(?)で,pythonの基本的の使い方のメモを書いていきたいと思います.内容は言語処理100本ノック 2015の2章からの内容をやろうかなと思っています.
ブログに書いていくpythonの投稿は入門シリーズだけでなく,pythonを使ったグラフ出力機能のmatplotlib,GUIプログラミングのkivy(苦戦中),数値計算ライブラリーのnumpyなどについてもちょこちょこ書いていく予定です.ぜひそちらも参考にしてみてください.
長くなってしまいましたが,読んでいただきありがとうございます!!