書籍「退屈なことはPythonにやらせよう」を教本にした「投資家のためのプログラミング勉強会(投プロ)」第6回目です。
本日は、whileループ(2章7.4) を使って、対話式に処理をしてくれるアプリを作ってみます。
前回開発したアプリ「アメカブくん」は、ティッカーコードを入力すると米国のニュースサイトを検索&翻訳して表示してくれるお便利アプリでしたが、続けてティッカーコードを入力しようとすると、いちいちアプリを起動する必要がありました。
今回はwhileループを使って、ティッカーコードを対話式に入力できるように改善していきます。
whileループは、第四回で学習したforループの親戚みたいなもので、使用頻度はforループが多いのですが、便利な機能なのでぜひ覚えておきましょう。
forループとの使い分けは、whileループは「終わりなく処理させ続けたいケースで利用する」と覚えてください。
例えば今回のように、ティッカーコードを繰り返し入力したいといったケースが該当します。またユーザーに選択メニューを表示して、そのメニューにそったプログラムを実行する(対話型アプリ)を実装する際などに利用する機能です。
ではまず最初にシンプルなwhileループから
1 2 |
while True: print(“投プロ会で丸儲け”) |
以上のコードを実行してみましょう。
だーーーーっと同じ文が表示され続けているかと思います。
このまま放っておいても止まりことはありませんので、Ctrl + Cやcmd + Cなどで強制終了してください。(実行環境アプリそのものを終了してもよいです)
このようにwhile True: と記載すると次に書かれた処理(今回の場合はprint()関数 )を永久に繰り返すのがwhile文の機能です。while の後ろには条件を記載して、それがTrueの間中、繰り返し処理(ループ)を続けます。今回はTrueと直接記載していますので人が外側から強制的に止める必要がありました。
プログラムの世界では、プログラム自身にループを止める構造がないことを無限ループと呼びます。無限ループに一旦陥るとアプリとしては暴走状態に入ってしまい、今回のように止めるのにも一苦労といったことになります。
意図しない無限ループは、コンピュータに不要な負荷を与えることになり、通常は重篤なバグとしてみなされます。
例えばファイルを生成する処理で、無限にファイルを作成し続けてディスクが一杯になってしまったり、ウェブサイトへのアクセスが集中してサーバーをダウンさせてしまうなどです。(今回の例は print()関数のみの無限ループなので実害はありません)
このように、whileに限らずforなどのループ処理を実装する際は、無限ループに陥らないかどうか、慎重にロジックを検討する必要があります。
それでは、ループを抜ける命令 breakを使って、3回ループしたら終了するロジックに変更してみましょう。
使用するのは演算子のプラス+ (教本の1.4)と条件分岐の if (同2.7.1) です。
では先ほどのコードを改造してみましょう。(目安時間:5min)
1 2 3 4 5 6 |
count = 0 while True: if count == 3: break print("投プロで丸儲け") count = count+1 |
いかがですか。
やり方はいろいろありますが私は上記のように書きました。
ループした回数を入れてる変数 countを用意し、初期値として0をセットしておきます。
whileループに入ったら、条件分岐の if でcountが3かどうかを調べます。count が3に達していたらbreakでループを抜けます。
3に達していなかったら、print()関数を呼び出し countに1を足したものを新たにcount変数にセットし、次のループ処理に入ります。
最後の表現 count = count + 1 は初めて出てきましたが、このように元の値に何かをした(今回の例では1を足した)結果を、同じ変数にセットし直すことができます。これによりcountという変数を使いまわすことができるのです。
変数は値を入れる箱でしたね。変数についは教本の1.4を参照してください。
whileを使ってよく実装するのが対話式アプリを作るときです。
通常のアプリは一度実行すると自動的に終了してしまいますが、前回作成したアメカブのように、いちいちプログラムを終了せずに、繰り返しティッカーコードを入力したい場合に対話式アプリを実装します。
例えばこのようなプログラムを実行させてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
us_stocks = {"PEP": "PepsiCo","JNJ": "Johnson & Johnson","PG": "Procter & Gamble","GIS": "General Mills", "KO": "The Coca-Cola Co", "MO": "Altria Group", "PM": "Philip Morris International", "BUD": "Anheuser Busch Inbev NV", "CL": "Colgate-Palmolive Company", "UL": "UNILEVER N.V. Common Stock", "XOM": "Exxon Mobil Corporation","GILD": "Gilead Sciences","T": "AT&T","HRL": "Hormel Foods", "V": "Visa","OKTA": "Okta","TEAM": "Atlassian"} while True: print("好きなティッカーを選んでください。") ticker = input() flag = ticker in us_stocks.keys() if flag: company = us_stocks.get(ticker) print("選んだのは{0}ですね".format(company)) else: print("有効なティッカーをいれてください") |
前回学んだ辞書型変数 us_stocks で米国株のティッカーと会社名を定義しています。
さらにwhileループを使って、入力したティッカーに対する会社名を表示するアプリとなっています。
このように、ユーザーと対話式で繰り返し処理を行わせたい場合にwhileループがよく使われます。
ついでにプログラムを終了する処理も追加してみましょう。
ティッカーコードに”end”を入れるとbreakしてアプリが終了する処理を追加してみてください。
1 2 3 4 5 6 7 8 9 10 11 12 |
while True: print("好きなティッカーを選んでください。") ticker = input() if ticker == "end": print("終了します") break flag = ticker in us_stocks.keys() if flag: company = us_stocks.get(ticker) print("選んだのは{0}ですね".format(company)) else: print("有効なティッカーをいれてください") |
では、ここまでの知識を使って、前回開発したアメカブくんをバージョンアップしましょう。
ティッカーコードを繰り返し入力できるような対話式の作りに変更してみてください。
またティッカーコードに”end”が入力されたら終了する機能もつけてみましょう。(目安時間:10分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#------- ここからコピペする ----------# import urllib import urllib.parse from bs4 import BeautifulSoup import requests from time import sleep def get_stock_news(company): ret = [] googlenews = "https://news.google.com/search?q={}&hl=en-US&gl=US&ceid=US:en".format(urllib.parse.quote(company)) print(googlenews) r = urllib.request.urlopen(googlenews) html = r.read() sp = BeautifulSoup(html, "html.parser") for tag in sp.find_all("article"): url = tag.find("a").get("href") title = tag.find("span").getText() if url is None or title is "": continue if "article" in url: ret.append(title) if len(ret) == 10: break return ret def translate_en_jp(en): sleep(1) url = "https://translate.google.com/translate_a/single" headers = { "User-Agent": "GoogleTranslate/5.9.59004 (iPhone; iOS 10.2; ja; iPhone9,1)" } params = { "client": "it", "dt": ["t", "rmt", "bd", "rms", "qca", "ss", "md", "ld", "ex"], "dj": "1", "q": en, "tl": "ja" } res = requests.get(url=url, headers=headers, params=params) res = res.json() return f'{res["sentences"][0]["trans"]}' #------- ここまでコピペする ----------# while True: print("--- 検索したいニュースのティッカーコードを入れて下さい:") ticker = input() if ticker == "end": print("終了します") break flag = ticker in us_stocks.keys() if flag: print("ニュースを検索しています...") company = us_stocks.get(ticker) news = get_stock_news(company) for n in news: trans = translate_en_jp(n) print(trans) else: print("有効なティッカーをいれてください") |
いかがでしたか?
どんなに複雑なプログラムも結局は「ユーザの何らかの入力に従って処理を行い、それを条件分岐しながら繰り返す」ということを行なっています。ですので今回の構造を理解できれば、プログラミングのベースはマスターといっても過言ではありません。
アメカブくんを自分なりにいろいろ改造するなりして、繰り返しと条件分岐をじっくり理解してきましょう。
こちらの本を教本にした「投資家のためのプログラミング勉強会(投プロ)」を主宰しています。
そもそもプログラミングとはなんぞや、Pythonを実行させる環境をどのように用意するか、などプログラミングにおける超基本的な内容が、我々のような非ソフトウェアエンジニア向けに分かりやすく記載されています。はじめの一歩にはこれ以上ない教材です(^^)