Windows10×VSCodeで快適なPython3.7開発環境を立てる
WindowsでPython開発する機会があったので、その手順を紹介。今回はAnacondaを使って環境構築する。
動作確認
2019/02/13
既に入っているPythonを削除する
人によって既にPythonが入っていると思う。大概Pythonのバージョン更新はうまくいかないので、事情がなければ今入っているPythonをコントロールパネルから削除したほうがいい。
Anacondaをダウンロード
https://www.anaconda.com/distribution/
上記のサイトからwindows版のAnacondaインストーラーをダウンロード。
Anacondaをインストール
基本はデフォルトの設定でインストーラーの指示に従っていけばいいが、1つだけ注意。
ここで[Add Anaconda to the system PATH environment variable]にチェックをいれないようにする。
Anaconda Promptを使ってみる
インストールが終了したらAnaconda Promptを起動。pythonコマンドが叩けたら正しくインストールが出来ている。(終了するときはexit()
と入力する
VSCodeでPython開発環境を整える
Pythonに対応したエディタは数多あるが、今回は流行りのVSCodeを採用。
flake8を導入
ここまででとりあえずはpythonの開発、実行環境が出来上がるが、よりPythonを書きやすい環境を作る為、flake8という文法チェックツールを導入する。
このツールを導入することで、大抵のタイプミスを実行前に防ぐことができる上、かなり厳しいコードレビューを自動で行ってくれる為、自ずと見やすいプログラムを書くことができるようになる。
flake8をインストールするにはAnaconda Promptを起動し、以下のコマンドを実行する。
conda install flake8
VSCodeの設定を変更する
flake8をインストールしただけではVSCodeに適用されない。
setting.jsonに以下を記述した後、VSCodeを再起動すると、flake8が使えるようになる。
"python.linting.lintOnSave": true, "python.linting.pylintEnabled": false, "python.linting.flake8Enabled": true,
その他おすすめの設定
flake8のコードレビューはかなり厳しく、こんなの気にしなくていいでしょ、というものまで警告を吐く。
python.linting.flake8Args
に無視したい警告を記述すればそういった警告を除外することができる。
私が使っている設定は以下。
"python.linting.flake8Args": [ "--ignore=W293,W504" ],
その他、setting.jsonに書いておいたほうがいい設定を示しておく。その中身についてはここでは記載しない。
"editor.minimap.enabled": false, "editor.parameterHints.enabled": false, "files.autoSave": "afterDelay", "files.autoSaveDelay": 1000
レオパレス民族大移動に巻き込まれた①
レオパレス民族大移動に巻き込まれた。
[緊急報告] レオパレス不備物件に付き緊急引っ越し確定
— ai (@ai_9684_dct) February 9, 2019
https://twitter.com/ai_9684_dct/status/1094171497399169026
— ai (@ai_9684_dct) February 9, 2019
家電付きの魅力に囚われレオパレスを選んだのだが、まさかこんなことになるとは。とにかく引っ越しの準備を急いでしなければならない。
で、先程レオパレスの担当者が謝罪と今後の予定について話しに部屋までやってきたので、そこで判明したことを共有。
- 本来退去時に必要な清掃費等は一切かからない
- 引っ越し先はこちら側の条件を聞きレオパレス側が候補を挙げ、そこから選ぶ。レオパレス物件から優先しての案内になるが、他社物件の可能性もある。
- 引っ越しにかかる費用は「全額」レオパレスが負担。(※ここでいう「全額」がどこまでを指すかは不明。見舞金が出るかどうかも言わなかった)
- 家電備え付けでない他社物件に引っ越す際、現在住んでいる住居に備え付けられている家電を持ち出すことができる。
特に家電の心配をしなくても良くなったのはデカい。
今後進展があれば書ける範囲で随時ブログに書くと思います。
※現在募集停止【告知】2D経営シミュレーション系ゲームのドッター募集
※今回の記事は個人的な告知です。
現在、私を含む開発メンバー二人で、2Dの経営シミュレーション系ゲームを開発しています。
今年末のデジゲー博、もしくは冬コミで頒布を目標として開発を進めていますが、ドット絵の素材の用意に非常に苦労しています。
そこで、2Dのドット絵を描いてくださる方を募集します。
依頼内容
- C++(OpenSiv3Dライブラリ)で開発中の経営シミュレーション系ゲームで使用する人物系のドット絵の作成
「48x48のサイズ、差分は各キャラ2個ずつ」の仕様を満たしていればどんなキャラクターでも構いません。
報酬
- 応相談。金銭的な報酬は多額は出せないと思います……
その他
- 開発の中心メンバーとして加入という形でも、外注という形でも構いません。
連絡先
- このブログのコメント欄
- Twitterアカウント @ai_9684_dct
大々的には募集しませんが、プログラマーとして参加したいという方もいらっしゃれば連絡をください。
どうかよろしくお願いいたします。
UE4 マテリアルとRenderTargetを使ってライフゲームを作ってみる
一体どこに需要があるのかわからないが、マテリアルをとRenderTargetを使ってライフゲームを作ってみた。
ブログ用 pic.twitter.com/MbuzXXsIf1
— ai (@ai_9684_dct) February 2, 2019
wikipediaだったり検索すればすぐに分かりやすい説明が見つけられるので、ここではライフゲームがなんぞやという説明はしない。
バージョン
UE4.21.2
概要
パラメータとしてTextureを与えると、次のタイムステップのライフゲームの結果を吐き出すマテリアルを作成。
ブループリントでRenderTargetを2つ(RT1とRT2とする)用意し、最初に上のマテリアルで計算した結果をRT1、RT2に書き込む。
続けて、
- RT2をマテリアルのパラメータに与えその結果をRT1に書き込む
- RT1をマテリアルのパラメータに与えその結果をRT2に書き込む
をTickを使って交互に実行することでライフゲームの時間軸を進めていく。
マテリアルの中身
- M_LifeGame
注意はBase Colorに繋ぐのではなくEmmisive Colorに繋がねばならないこと。理由は後述。
- MF_8NeighbourPixel
キモはTexel SizeノードとTexCoord。
Texel SizeはTexture Propertyと検索すれば使えるノードで、入力として与えたテクスチャのピクセルサイズを取得することができる。
TexCoordには今見ているピクセルのUV座標が入っている。
- MF_8NeghbourLifeGame
MF_8NeighborPixelで取得した8近傍ピクセルのR値を四捨五入。それと現在のピクセルのR値を使って現在のピクセルの生存・死亡・誕生をCustomノードを使って判定する。
今回採用したライフゲームのルールは、
- 今死んでいる時周囲のピクセルがちょうど3つ生きていれば誕生する
- 今生きている時周囲のピクセルが2か3つ生きていれば生存する
- 今生きている時周囲のピクセルが1つ生きていれば過疎で死亡する
- 今生きている時周囲のピクセルが4つ以上生きていれば過密で死亡する
Customノードの中身は以下の通り。
float1 count = 0; if(N1 == 0){count++;} if(N2 == 0){count++;} if(N3 == 0){count++;} if(N4 == 0){count++;} if(N5 == 0){count++;} if(N6 == 0){count++;} if(N7 == 0){count++;} if(N8 == 0){count++;} if(thisPixel==0) { if(count <= 1) { return float3(1.0, 1.0, 1.0); } if(count >= 4) { return float3(1.0, 1.0, 1.0); } else { return float3(0.0, 0.0, 0.0); } } else { if(count == 3) { return float3(0.0, 0.0, 0.0); } else { return float3(1.0, 1.0, 1.0); } }
ブループリントの中身
- 構成
Static Mesh Actorを継承し、MeshにPlaneなりBoxなりを割り当てる。マテリアルには先程作成したM_LifeGameを設定。
ライフゲームの初期状態として与えるTexture2D型の変数、InitialTextureを用意。Instance Editableにチェックを入れて置くと便利。
- Construction Script
メッシュのDynamic Material Instanceを作成し変数LifeGameDMIとして保存しておく。続けてSet Texture Parameter Valueを使ってライフゲームの初期状態を与える。
- Event Begin Play
初期状態テクスチャと同じサイズのレンダーターゲットを2枚作成。それぞれにLifeGameDMIの結果を書き込む。
ここにハマりポイントが2つある。
1つはCreate Render Target 2Dするタイミング。
この関数をConstruction Scriptで実行すると正しく動作しないので、必ずBeginPlayで作成する。
もう1つはレンダーターゲットに描くマテリアルについて。
Draw Material to Render TargetするのはEmissive Colorの結果のみ。Base Colorの結果は一切関係ない。先程ライフゲームの結果は必ずEmissive Colorに繋がなければいけないといったのはこういうこと。
- Event Tick
FlipFlopを使って交互に実行する。
最後にClass SettingでTickが呼ばれる回数を好みに設定して完成。
まとめ
Customノードの中身を変えれば簡単に他のルールのライフゲームを再現できそう。Draw Material to Render Targetはかなり面白いことができるのでもうすこし遊んでみたい。
参考
それでも小学生にプログラミングの授業はあってほしい
某バズった刺身タンポポ記事、大学生時分の私には身に覚えがある事が多すぎて余りに頭の痛い話だった。
運良く地方の国立理系に通わせて貰っているが、プログラミングの講義の質は本当に先生次第。基本に忠実に、かつ最新の規格に沿って教えてくれる先生もいれば、まだC言語しか触っていない学科で、第二回で世界に挨拶し、第三回で説明もなくjavaでクラスを作らされ、置いてけぼりの学生をよそに講義予定の30分前に「もういいよね?」帰宅する先生もいる。
他大の話だが、リストを自作し、それも含めて課題を提出したのに「ライブラリに頼るな」というありがたいフィードバックを頂いたというお話をTLで観測したこともある(出来が良すぎたからどこかからコピペしたとでも思われたんだろうか)。
教えられる学生側もまぁ問題はあって、エラーメッセージ読まない、サンプルを丸写しだけして的はずれなことをやってる、質問の意図が意味不明など……元記事の通り色々問題はある。(もしこの記事をガチ同級生が読んでたらスマン。これは特定個人宛のメッセージではないし、私の知る同級生は皆私にないもの沢山持ってて羨ましいって日々思ってる)
大学でさえこの有様だから、政府が進める「小学校でのプログラミング教育」なんぞ上手くいくわけがなく。断言できる。
文科省の考えるプログラミング教育
文科省の資料によると、プログラミング教育の目的は、「プログラミング的思考を育成」らしい。
まぁそんなの無理だと思う。
バイトで小学生に算数を教えることがあるが、絶望的に出来ない子はいる。掛け算すらままならないような彼らに「プログラミング的思考を育成」なんて目的でやるプログラミング教育は絶対にうまくいかない。彼らにプログラミング・コンピュータに対する苦手意識を植え込むだけ。彼らはいずれ「圏外でLINEが繋がらないバグをどうにかしろ!」とクレームを入れるリテラシー皆無のモンスタークレーマーとなるのだろう。
結局のところ、伝統などと理由をつけて元号公表を必死に遅らせようとする政治が主導するプログラミング教育に期待してはならないのである。
だが小学校のプログラミング教育に賛成
悲観的な話ばかりしてきたが、私は小学校でのプログラミング教育は是非してほしい、と考えている。ただし、プログラミング的思考の習得などという高尚な理由ではなく、プログラミングに夢を抱く純真無垢な少年少女の「その幻想をぶち壊す」目的でなら、である。
閑話休題
私が本格的にプログラミングの勉強を始めたのは2年半前。小学校の頃から漠然と抱き、高校生時に読んだ「社長が訊く」で絶対になりたいと決めたゲームプログラマーという夢。夢自体は持っていたがその夢に向けて動き始めたのはつい最近になってから。理由は単純で「プログラミングの学び方」を知らなかったから。
田舎者で小心者の私は身近にプログラマーがおらず、探すことも出来ず。結局大学進学で親元を離れるまでプログラミングはしなかった。それでもパソコンは大好きで、実家のオンボロPCでOfficeを弄ったり、ブラウザゲームを遊んだり、Firefoxにアドオンを大量に突っ込んでマルウェアをインストールしてしまい大目玉を食らったりしてきた。
大学で漸くプログラミングが学べそうな情報系に進学した。あとで聞くと、大学の同期もざっくりと「プログラミングが学べそうだから」という理由で弊学科に進学している方が多いらしい。
入学した時はこの学科に来るような人はプログラミングの経験の有無はあれど、皆PCスキルは一定以上持っていると思っていた。
しかし実際は物理化学では私より遥かにいい成績を取れる人がexcelをロクに使えない という現実。プログラミングは出来なくともOfficeが使えたaiくんはいつの間にやら「パソコン詳しいオタク」扱いされるようになったのである。
変に持ち上げられてしまった以上、それに見合うスキルを得たいと、何冊も技術書を買って、独学でプログラミングを学ぶようになった。ここでようやく私は、交友関係、社会性を生贄に捧げることで「プログラミング書いたことない」から「プログラミングかけなくはない」にクラスチェンジすることができたのだ。
プログラミングの向き不向きは早めに判断したほうがいい
長々自分語りしてしまったが、言いたい事は一つ。
「もっと早くプログラミング勉強したかった!!!!!!」 私はゲームを作るためなら大学でのキラキラな交友関係や社会性を投げ捨ても構わないと割り切り、独学で(勿論講義で貰った資料、課題も参考にしたが)プログラミングを学び、一人でミニゲームを作れるくらいにはなれた。
しかしもっと早くから勉強できていれば今頃とんでもないゲームが作れていたかもしれない。今頃ゲーム会社のスーパープログラマーになれていたかもしれない。そんな後悔は尽きない。(まあまあ長いこと勉強してるのにその程度かって指摘はやめて。心折れる)
大学に入るまでプログラミングをしてこなかったのは、結局のところきっかけがなかったから。そして学び方が分からなかったからなのだろう。
もし小学校でプログラミング教育が実現すれば、プログラミングの才能、面白さに目覚めた小学生が私の様な後悔をすることなくとんでもない3Dゲームを作るかもしれないし、その若さ故の柔軟な発想で世界を変えるサービスを開発するかもしれない。
逆に今のままであれば、プログラミングで薔薇色の未来が待っているという幻想を抱き情報系の大学、専門学校に進み、そこで自分には向いていないと悟り四年(二年)をつまらなく過ごしてしまう人が生産され続けるだろう。
悲しいことにプログラミングは向き不向きがはっきり出る技能。大人になってそれを判断するよりかは、もっと早い段階で判断させ、向かない人にはプログラミングへの幻想を捨ててもらい別の道に迷いなく進んでもらう。向いている人には授業を足がかりにその才能を早くに開花させてもらう。
これならばプログラミング教育に賛成できる。
締め
随分元記事と趣旨がずれた話をしてしまった。
こんな記事を書くことにしたのは(打ち消し) 自分のツイートがバズってブログ告知ぶら下げたらアクセス伸びたから乗っかって記事書こうとおもった 元記事にプログラミング教育なんて無理、といった話があったから。TLで稀に見かける、真剣に小・中学生向けのプログラミング教育機材開発に取り組んでいる方を見ていると、そんなに悲観しなくてもと思う。
いつかこういったプログラミング教育機材でプログラミングに目覚めた子から産まれた傑作ゲームが遊んでみたい。
2018振り返りと来年の話
今年振り返り
— ai (@ai_9684_dct) 2018年12月30日
1月 記憶にない
2月 ぷちコン初参加
3月 UE4Fest行った
4月 Niagaraやった
5月 ハッカソン参加した
6月 某逆求人いった
7月 インターンの面接した
8月 インターン行った
9月 ぷちコン参加した
10月 某ゲームの企画練ってた
11月 死んでた
12月 Pythonばっか書いてたら
本当はしっかりした記事を書きたかったのだが年末時間が取れなかったので振り返りのツイートで。年明け時間があればちゃんとした記事を書きたい。
来年は就活に卒研色々忙しくなりそうで、ブログ更新頻度も下がると思われ。それでも最低月1ブログ更新、そして大学卒業までにゲームリリースはしたいなあ。
Python 連番テキストファイルを結合する
test_0.txt, test_1.txt, test_2.txt, test_3.txt...と連番で用意したテキストファイルを順番通りに結合して、test.txtという一つのファイルとして書き出すプログラム。
import glob import os.path # ファイルの結合 def join_file(filePath): fileList = create_filelist(filePath) with open(filePath, 'wb') as saveFile: for f in fileList: data = open(f, "rb").read() saveFile.write(data) saveFile.flush() # 連番ファイルのリスト作成 def create_filelist(filePath): pathList = [] for index in range(100000): filename = file_indexed(filePath, index) # ファイルが存在しなければ終了 if not os.path.exists(filename): break else: pathList.append(filename) return pathList # ファイル名に指定のindex値をふる def file_indexed(filePath, index): name, ext = os.path.splitext(filePath) return "{0}_{1}{2}".format(name, index, ext) if __name__ == "__main__": join_file("testData/test.txt") # 相対パス
まとめ
catでいいやん。