頭の中は異空間

ものづくり中心

【STEINS;GATE】【ネタバレあり】シュタゲ(elite, 0)の感想書いてみる

シュタゲエリート(無印)およびゼロをクリアし、アニメも観終わったので、簡単に感想など書いてみようと思います。なお映画は見ていません。

 

それぞれの世界線と違い

世界線 未来(2036年) 紅莉栖 まゆり タイムマシン 岡部達が関わる相手
α SERNによるディストピア すぐには死なない※1 2010/8/13に死亡 SERNが完成させる。未来のダルがそれを真似て完成させる
過去への一方通行
SERN(のラウンダー)
β アメリカ、ロシアを巻き込んだ第三次世界大戦勃発、終戦後も各地で内戦
世界人口が10億人にまで減少

2010/7/28に死亡

記憶だけAmadeusに残存

すぐには死なない 未来のダルが完成させる
未来にも過去にも行けるがバッテリー残量わずか
ストラトフォー
DURPA
ロシア軍
SERN(のラウンダー)※2
SG 戦争も起きずディストピアもない すぐには死なない すぐには死なない 存在するのか不明 不明

※1 タイムマシン完成後に死亡だった気がする

※2 敵として出てくるのはほんの1世界線の出来事であり、ここでは影が薄い

 

時間、世界線変動

  Dメール、Dライン タイムリープ タイムマシン
世界線変動 できるが、結果は受け取った相手の行動に左右される できない※1 できない※1
時間旅行 できない できるが制限あり できる

 

設定はこんな感じだったと思います。タイムマシンでさえ世界線を変えられないのは、世界線の収束のせいですね。ただ、収束と言っても「決まった結果」として出てきたのは人の生死ばっかりですが。

タイムリープマシンはタイムマシンよりはリスクが少ないものの、それが出来た時から最大48時間前(最終的にはもっと伸びるが)までという制限がついていました。

 

※1 厳密には、アトラクタフィールド理論により世界線の収束が起こるので、特定の過去の出来事を変えられない、という意味

 

感想

ダル、チート過ぎない?足跡の残らないハッキングを一発成功させる(それも国家機密が相手)というまさにスーパーハッカーが味方にいるのが頼もしい、と思いました。未来ではタイムマシンを作っちゃうしね。活躍度でMVPをあげるなら彼じゃないか。

無印→ゼロの順に話が進みますが、ゼロのトゥルーエンドが無印のトゥルーエンドにつながるのが衝撃的でした。未来の岡部が、αから戻ってきた現在の岡部にムービーメールを送って道を示すところで察しました。

 

f:id:notwo:20181125093645j:plain

シュタゲをやるとタイムマシンが意外とそこまで万能ではないなという印象が強くなります。β世界線に来た鈴羽が言っていたバッテリー問題が、過去では常に付きまとううえマシンの故障タイミングによっては時空の狭間に閉じ込められかねないという欠点。アトラクタフィールド理論により、決まった結果は覆せない。特にここが問題な気がします。過去を変えても結果が変わらないなら、過去に戻る意味があるのかわかりません。ところが、そこにDメールないしはDラインを組み合わせることで、本当の意味で時間や世界を自由に操ることが出来るようになります。

しかしそんなことをすればSERNにマークされるし(Dラインは監視されていないのでセーフ)、タイムマシンはその存在がバレればその世界では戦争が起こってしまうという諸刃の剣であり、活躍の場がほとんどなかったのが意外でした。ドラえもんの世界の未来人の持っているタイムマシンはそういう欠点をどうやって克服しているのか、なんて考えてしまいますw

 

アニメでなくゲームをプレイした人ならではの感想としては、各ルートどれもハズレにはなりえない点が素晴らしい(ゼロのレスキネンルート除く)。例えば無印のフェイリスルートはむちゃくちゃ切ないルートではあるけれど、まゆりも紅莉栖も死なない一つの解答だと思います。選択肢で何を選ぼうがFateと違って分岐によってDead endとならないのが特徴だと思います(だからといってFateが悪いわけではない)。それでも私は結局トゥルーエンドが一番納得が行きますが。

他には、専門用語がそこそこ出てくるのですがその解説をTIPSという用語辞典で補っています。トロコンしたい場合、そのTIPS集めのためにも全ルート回ることになります。

 

さて、主人公の岡部視点で物語が進みますが、岡部が世界線を移る理由はまゆりと紅莉栖を死なせたくないからです。舞台のどちらの世界線も20年後には地獄が待ち受けていますから、殆ど誰にとっても辛い世界線に変わりはないものの、岡部にとってはその世界のことなんてどうでも良い※3わけです。あくまで目の前の紅莉栖、まゆりの無事が確認できれば良い。つまり世界線を移りたいのは岡部のエゴでしかないのですが、「独善的だ」なんて紅莉栖に言われても、それを強がって否定したりしないあたりに好感が持てます※4。結局、世界線を変えないと地獄なので、独善的だろうが岡部が世界線を変えることに、他人にとっても意義が生まれています。この辺の設定がとてもうまくできています。

加えて、岡部はαからβに移るときは紅莉栖に背中を押してもらい、βからSG世界線に移るときはまゆりに背中を押してもらっている。どちらのヒロインが欠けてもSG世界線にはたどり着けていなかった。このことがどちらも岡部にとって無くてはならない、ということを表現しているように感じられる。そんなヒロインをどちらも守ろうとする、だからこそ、最後の最後まで岡部を応援したくなる、そう出来ているんだと自分で納得しています。

※3 β世界線2036年を見た時はさすがに変えないといけない!と使命感を持っていましたが。

※4 β世界線に移るとき、「紅莉栖を見捨てる」ことを覚悟し、受け入れたことも含め。ただし、途中までは世界線を変えることの影響を恐れてはいた模様。

 

f:id:notwo:20181125093353j:plain

後は、物語にはあまり関係ない部分ですが、ゼロの冒頭でレスキネン教授の講演中、アマデウスに批判的な意見を出した人に対して岡部が「最初は無理だと思われた技術なんていくらでもある、それを克服した研究者がいたから今があるんだろ」というセリフ、ここ個人的に名言と思ってます。全く新しい技術やサービスが生まれようとしている時、そこには必ず批判する輩がいますが、技術的な困難だけでなくそういう批判にも打ち勝った結果出来上がった作品が世の中を変えていく、そういう流れは歴史上でも起こっていることですから。

 

 

f:id:notwo:20181125093300j:plain

復ッ活ッ 鳳凰院凶真復活ッッ

そして最後に、やはり鳳凰院凶真が復活したことが嬉しいです。この厨二ネームなくして岡部はありえないでしょうw元々無理してつけてた設定とはいえ、無印の頃の印象が強いから普通の大学生をしている岡部って違和感バリバリ。でも最後にしっかりもとに戻ってよかった。こっちのほうがより困難に立ち向かっている雰囲気が出ていると思います。

 

原作とアニメの違いについて

無印・・・原作ではトゥルーエンドの他に紅莉栖/まゆり/ルカ子/フェイリス/鈴羽のそれぞれのルートが存在。アニメでは原作のまゆりルートに準ずる。

ゼロ・・・原作ではトゥルーエンドの他にレスキネン/まゆり/紅莉栖/かがり/真帆のそれぞれのルートが存在。アニメでは各ルートを部分的になぞりつつトゥルーエンドへ。

 

ゼロはアニメと原作にちょくちょく違いがあるというか、アニメ限定シーンがあったりします(最後に岡部がBC18000に漂流した鈴羽とまゆりを迎えに行くシーンだったりかがりの格闘シーンでかがりの素顔がバレてたりダルの告白シーンがあったりetc)。

細かい突っ込みどころを無視すれば十分アニメも楽しめると思います。

 

アニメも原作も良いと思いますが、やはり私は原作を推します。原作であれば、岡部はもちろんサブキャラの深掘りもよりされているので。ただ、無印の鈴羽ルートつまり無限サイクリングはちょっと怖いけどね・・・

 

【Python】【Tk】treeview(表)に横スクロールバーを付ける

treeviewで横スクロールが出来ないと不便なのでつけよう、というものです。表以外の形式でも出来ると思います(未検証)。

 

コードとしては

frame = ...(frame初期化)
tree = ...(treeview初期化)
tree.pack()
hscrollbar = ttk.Scrollbar(frame, orient = tk.HORIZONTAL, command=tree.xview)
tree.configure(xscrollcommand=lambda f, l: hscrollbar.set(f, l))
hscrollbar.pack(fill='x')

で出来ます。

先にtree.pack()しておくことで、スクロールバーを表の下部につけることが出来ます。見て分かる通り同じframe内にtreeviewおよびスクロールバーを収める必要があります。

hscrollbar.pack()するときfill='x'がないと、スクロールバーのサイズが最小化されてしまって使い物になりません。

 

余談ですが、下記リンクの

autoscroll

を使うことで、ウィジェットのサイズによってスクロールバーをつけたり消したり出来ます。

python 2.7 - Horizontal scrolling won't activate for ttk Treeview widget - Stack Overflow

 

なお、縦スクロールバーも同様につけることが出来るものの、デフォルトでホイールに縦スクロールが対応しているようなので、わざわざつける必要があるのかは疑問。デザイン面を考慮するなら、ですね。

【Python】【Tk】treeview(表)の選択状態についての注意点

ttk.treeviewの表形式で登録データを総入れ替え(delete→insert)なんかするときに悩むであろう罠について。

 

データをすべてtreeview.deleteしたとき、選択中だったデータの選択状態が強制的に外れます

明示的に言えば、treeviewを見た目で選択した状態の「選択」と内部的に選択した状態の「フォーカス」に分かれます。これを元に戻すには、「選択」と「フォーカス」の2つを動的に行う必要があります。

 

# データ全削除
tree.delete(*tree.get_children())

この時点で選択、フォーカスの2つが外れた状態になっています。そのため、本当の意味で表のデータを再選択するには下記(1), (2)の双方が必要です。

# (1)データのフォーカス(プログラム上で内部的に選択した状態)
tree.focus(iid)

 

# (2) データの選択(見た目上で選択された状態)
tree.selection_set(iid)

 

focus(iid)することで、例えば下記のように選択中のデータを取得できたりします。

focused_record = tree.item(tree.focus())['values']

また、selection_set(iid)することで見た目的にもどれを選択中か見せられるのでユーザにとっても親切な作りになります。

 

肝心のiidはデータをinsertするときに返り値として取得可能です。

for record in data:
iid = tree.insert("","end",values=(record))

 

あとは、全データ(data)のループ内でfocused_record == recordのときにfocus, selection_setすることで再選択を実現できます。

【Python】【Tk】Tkのtreeview(表)のヘッダ部分のクリックイベント設定方法

1時間くらいどん詰まりしたので覚書。

 

例えばこんな感じのテーブルがあって、お客様氏名とか郵便番号あたりの行をクリックしたときの挙動をつけたいとき。

f:id:notwo:20180615000844p:plain

 

ttk.Treeviewを継承したクラス内で実装する前提です。

イベント設定を

self.heading(番号(連番だと楽), text=表示したい名前, command=コールバック関数)

こんな感じにして、

コールバック関数内で

x = self.winfo_pointerx() - self.winfo_rootx()
self.identify_column(x)

とすると、どのヘッダがクリックされたかを、#~の形で取得出来ます(厳密にはどのカラムがクリックされたかの情報)。

 

たったこれだけで出来ます。

とはいえ、リファレンスを隅から隅まで見てもそれっぽい非常に旨味なメソッドがなかったのでやり方はこれしかないと思います。

 

やってることは画面に表示しているx座標をもとにidentify_column()でヘッダ名を特定しているだけです。クリック時のマウスカーソルx座標からtreeview自体のx座標を引けばクリック時のtreeview上の位置が特定出来ます。取得した番号から#を取り除いてcolumn()やheading()に渡せば、カラムやヘッダの設定を取得まで出来ます。

 

この手のイベント設定で考えられる使い道はたぶん、ソートしたいとき位ではないかな...?

【Windows10】【Python】pyinstallerを使うとき注意すべきこと

Windows10でpython+Tkで書いたツールをexe形式にしたいとき、pyinstallerを選択しました。で、結構躓いたので後学のために注意点をまとめます。

 

 

Pythonのバージョン

一番大事なことです。

まず私が試したのはPython Releases for Windows | Python.orgPython 3.7.0b5 - 2018-05-30です。これで

pyinstaller -F -w xxx.py

とかすると、確かにexeは作られるんですが実行しようとしても何も起きません。おそらく裏でコケてエラー吐いてると思います。

pyinstallerはまだpython3.7をサポートしていない可能性大です。

-->python3.6.5でやり直したところうまくいきました。

3.6が大丈夫というのは

PyInstallerがPython3.6をサポートしてくれた

で確認しました。

 

インポートファイル

ファイルが複数に分かれていて依存関係がある場合、それらも含めてビルドしないと失敗します。

--paths="`ここに含めたいパス"をつけてpyinstaller実行しましょう。

ex) pyinstaller -F -w xxx.py --paths="./modules"

※xxx.pyでエントリポイントのあるファイルを、--pathsでそこからimportしているファイルのあるディレクトリをすべて指定すること。

 

アラートがいっぱい出る

7477 WARNING: lib not found: api-ms-win-crt-stdio-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7547 WARNING: lib not found: api-ms-win-crt-runtime-l1-1-0.dll dependency of
c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7625 WARNING: lib not found: api-ms-win-crt-heap-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7703 WARNING: lib not found: api-ms-win-crt-time-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
...

上記メッセージだけではなんのことやら...といった感じですが、この辺の投稿によればWindows 10に起因する問題の模様です。更に、Windows Vista/7/8ではwarningを抑えるためのdll(つまりwin10で足りない部品)があるとのこと。

しかしgithubの同スレの上部の投稿にある通り、warningが出ていても動作するexeファイル作成自体はできるようで、私もたくさんのエラーが吐かれているにもかかわらず、正常動作するexeファイル作成には成功しています。

どうしてもwarningを消したい、という場合は先程のcodewarrior0氏の言う

so the only thing to do is to install the VC 2015 runtime on the Vista/7/8 machine.

をやれば良いと思います。そこから先は軽く読んだもののこれといった対処法は書かれてないです(私は試していないので↑で出来る!とは断言は出来ませんが...)。

他に何某かのエラーが出てexeが作れない、となったら再び上記warningを疑えば良いのかなと...

 

 

【Windows10】[Windows10]PCの調子がおかしくなったとき用の修理メモ

最近、ドスパラで買ったデスクトップPCのパーツがイカれてきたので、この機会にやったことと起きた現象をメモ。

 

今回起きた現象

  1. 電源は付くがHDDが全くつかない、ディスプレイに全く表示されない
  2. 途中でHDDランプが全く点灯しなくなる

 

1について

急に画面が全くつかなくなり、強制終了してつけ直すとHDDランプすらつかない→こうなるとchkdskすら出来ず、HDDの故障を疑う→分解してHDD(C, Dドラ)を取り出し、診断用の製品(名前忘れた)で動作チェック→問題見当たらず。

 

2について

グラボを外したのに調子が悪いのでHDD不良を再度疑うがCrystalDiskInfoでは正常と出るので問題なさそう、CPUが古くパワーが足りてない疑惑があるためグラボをつける必要が出てきた。

→PCゲームや動画を見なくてもフリーズが頻発するためCPUの負荷が高まったのが原因とかんがえられる

 

実は一昨年あたりに一度HDDを交換しておりHDDがそんなに早く壊れるとは思えないので、冷静になってみればHDDより先に他の周辺パーツに目を向けられたかもしれないです。

 

やったこと

1→HDDチェック、グラボ取り外し

2→HDDチェック、グラボ付け替え

 

PCを買ったのが2011年なので、実に7年近くも使っているのでガタが来てもおかしくないということでパーツ交換をしました。

まるごと買い替えだとそれはそれで安心感は有りますが出費がひどくなるし色々設定し直しでただただ面倒という欠点もあります。安く済ませられる部分は安く済ませるのが賢い解決策だと思います。

 

1について、グラボが原因でない場合はCMOSが悪さをしている可能性もあるということで、その場合はCMOSクリア(取り外して5分間くらい放置)、それでも駄目なら電池買い替えまでありえました。

 

結局悪さをしていたのは古いグラボで、これを買い換えることで無事解決。

【Django】MacでCommunity版PyCharmでDjango環境を触れるようにする + herokuにデプロイまで

Herokuを始めるとき、getting-statedでなく、自分の手元のDjangoプロジェクトをherokuにデプロイすることもできます(むしろこっちが普通かも)

pythonにはPyCharmという便利なSDKがあるので、使えるようにしたいところ。

 

Community版PyCharmではDjangoプロジェクト作成が出来ないので、PyCharmでは予め作ったDjangoプロジェクトを読み込むだけとしましょう。

 

 

PyCharmのインストール

あえて解説するまでもないので詳細は割愛します。

 

Djangoプロジェクトの作成

インストールが終わったら、下記コマンドを実行してDjangoのプロジェクトを作成しましょう。

cd ~/PycharmProjects
# まだなにもない
ls
# プロジェクト作成。ここでは「myMenu」とします。
django-admin startproject myMenu
# 生成物を確認
ls

ここまでで最低限のモノが揃いましたので、PyCharmで開きます。

f:id:notwo:20180520133704p:plain

開くとこんな感じ

ここからエディタをPyCharmとして実装を進めて行きます。

念のため、一応ローカルサーバが立ち上がることを確認します。

f:id:notwo:20180520133359p:plain

こんな画面が出ればOK

herokuへデプロイ

以下コマンドでherokuデプロイ用のローカルgitリポジトリを作成~デプロイまでを行います。

cd myMenu
git init git add ./ git commit heroku create アプリ名※

※Name must start with a letter and can only contain lowercase letters

ここでは「testpythonmenu」としました。

作成するとurlが出てくるので開いてみましょう。

f:id:notwo:20180602205033p:plain
f:id:notwo:20180602205048p:plain

こんな画面が出ればOK(.comの方)

現時点で

git push heroku master

をしても正しく動きません。rejectされるので、pushする前に必要な作業を済ませます。具体的には、

This occurs when Heroku cannot detect the buildpack to use for this application automatically.

とか出るので、

elements.heroku.com

にある通りの対策をします。

その前に、

devcenter.heroku.com

に従い、Procfileをプロジェクトルートに生成します。Procfileは↑公式サイトの通りで問題ないです。

他にはgunicornというwebサーバが入ってないといけないので合わせて入れます。

gunicornのインストールにはpipenvが必要なので、

# プロジェクトルートにいることを確認
pwd
# 1つずつインストール
pip install pipenv pipenv install gunicorn pipenv install django-heroku

と実行していきましょう。この時点でPipfileおよびPipfile.lockが作られます。

gunicornのインストールに失敗したら、おそらく下記の通りにすればうまくいきます。

www.lifewithpython.com

install成功したら、settings.pyへの記述も忘れずに(import django_herokuの記述も必要です)!

以上を設定してcommitしたら、

heroku buildpacks:set heroku/python

として今度こそpushします。

それでも、

remote:  !     Push failed: An unhandled error occurred, please try again shortly. See https://status.heroku.com/ for current Heroku platform status. If the problem persists, please contact https://help.heroku.com/ and provide Request ID fb0fb17b-ec7f-870d-28ca-7e53f9960147.
remote:  !     Please try pushing again.
remote:  !     If the problem persists, see http://help.heroku.com/ and provide Request ID fb0fb17b-ec7f-870d-28ca-7e53f9960147.

などという謎エラーを吐くことがありますが、こういうときは再度pushし直してください。うまくいくはずです。

これで出力されたURLにアクセスすると

 

f:id:notwo:20180605015519p:plain

無事に設定が終わったことがわかります。

 

今までの手順に異常があると、URLアクセス時に

f:id:notwo:20180603153225p:plain

となります。

heroku logsでログを見れるので、エラーメッセージをもとに修復すること。

 

番外編

requirements.txtがあるのにProcfileを生成してしまった

なんとrequirements.txtが同じディレクトリに残っていると、Pipfileはrequirements.txtの内容を自動で読みに行ってその内容を勝手にインポートしやがります。このせいで、その後pipenv installしたパッケージによっては依存関係がめちゃくちゃになってエラーを吐く原因になります。

こうなると解決は困難なので、一度herokuアプリからすべて消して作り直したほうが速いです。

まずないと思いますが、昔の名残でrequirements.txtが残っている場合は先に削除してからpip installするように!!

 

Pipfileがあってbuildpackしたのに同じエラーでpushできない!

こんなときは

Ruby on railsのtutorialをherokuに突っ込んだ時に躓いたこと

と同じ問題な可能性が高いです。pipenv installするときは必ず、プロジェクトルートディレクトリにcdしてから行うこと!