OmniAICreator/Qiita-1.07M huggingface dataset:
Github PagesでReactアプリケーションをデプロイ

#はじめに
久しぶりのQiitaの記事投稿です！
今回はGithub PagesにReactアプリケーションのデプロイ方法を記述しました。
途中つまづいた点があったので、付録として記述しました。
また、今回は環境によって

#[Step1] Reactアプリケーションの作成

###必要なもの
- node (バージョン 8.10以上)
- npm (バージョン 5.6以上)
- Githubアカウント (アカウントが無い方は[こちら](https://github.com)から作成)

###Reactアプリケーションの作成

```
$ npx create-react-app {アプリケーション名}
```

#[Step2] gh-pagesパッケージのインストール
プロジェクトディレクトリに移動

```
$ cd {アプリケーション名}
```
gh-pagesのインストール

```
$ yarn add --dev gh-pages
or
$ npm install --save-dev gh-pages
```

#[Step3] package.jsonの変更
predeployは自分が使用したパッケージ管理ツールによって変わります。
npm => npm run build
yarn => yarn run build

```js
{
  // ...
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    // 追加
    "predeploy": "{yarn or npm} run build",
    "deploy": "gh-pages -d build"
  },
  // ...
  "devDependencies": {
    "gh-pages": "^2.1.1"
  },
  // 追加
  "homepage": "https://{Githubのユーザ名}.github.io/{リポジトリ名}/"
}

```

#[Step4] Githubにリポジトリの作成
1. githubで新しいリポジトリ作成
2. アプリケーションをデプロイ

自分のパッケージ管理ツールによって実行コマンドが異なります。

```
$ git init
$ git remote add origin https://github.com/{githubアカウント名}/{リポジトリ名}.git
$ {yarn or npm} run deploy 
```
#[Step5] アプリケーションの確認
deployできたら
`https://{githubアカウント名}.github.io/{リポジトリ名}/`
にアクセスするとアプリケーションが表示されると思います。

![スクリーンショット 2019-11-27 16.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247084/c9216f71-9c8e-c1c5-46a5-cb2fef1a5a87.png)

#付録
###[Step4]のdeployでエラーが起きた場合!

```
...
$ gh-pages -d build
Cloning into 'node_modules/gh-pages/.cache/git@github!M01tyan!credit-card-form.git'...
ssh: Could not resolve hostname github: nodename nor servname provided, or not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```
deployに失敗して、上のようなエラーメッセージが表示された場合は
下記のコマンドを入力して、リモートリポジトリのurlを変更する必要があります。

```
$ git remote set-url origin git@github.com:{githubアカウント名}/{リポジトリ名}.git
```
変更したら再び `{yarn or npm} run deploy` を実行

`Published`
と表示されたら成功！！

#参考記事
https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf
https://qiita.com/EisKern/items/15dcf7864fa49df8f247
https://dev.to/yuribenjamin/how-to-deploy-react-app-in-github-pages-2a1f
Goを書く前に知っておくべき3つのこと

# Goを書く前に知っておくべき3つのこと

**言語について学習する以外**で知っておくとあとあと人生が楽になることがいくつかあるので個人的に必須だと思っていること3つをサクっとリストアップしてみました。



## 1. 環境の準備
Goの面倒な要素として `$GOPATH` という変数（未設定の場合は `$HOME/go`）が指すディレクトリの下に全てのGoのソースコードが（少なくともエクスポートしたいものに関しては）入っている必要があります。変なこと（たとえばiCloudやDropBoxでコードをクラウドで同期するみたいなこと）をしない場合は未設定あるいは `GOPATH=$HOME/go` と明示的に設定してしまっていいと思います。合わせて `PATH=$PATH:$GOPATH/bin` も設定してしまいましょう。

`$GOPATH` 以下の階層は大雑把に以下のように構造化されています。

- `$GOPATH/`
  - `bin/` go get などでインストールされたバイナリ郡
  - `pkg/` 標準ライブラリ
  - `src/` その他のGoコード

ここでポイントになるのは `src` 以下の構造です。本来であれば `src/myprojects` などとディレクトリを切りたいところですが、そうもいきません。というのも `src` 以下にはまずドメイン名が来るからです。「なんでや」と思われるかもしれませんがこの切り分けをすることでそのソースコードがどこから来ているかがわかりやすくなるというメリットがあります。

Goをインストールしたての場合は `src` 以下には何もないかと思います。そこで試しに以下のコマンドを実行してみてください。

```sh
$ go get github.com/ktnyt/assert
```

すると、`$GOPATH/src/github.com/ktnyt/assert` というディレクトリが生成されます。同様に `go get doma.in/path...` というコマンドを実行すると `$GOPATH/src/doma.in/path...` というディレクトリができます。なので、自分のコードは原則的に `$GOPATH/src/github.com/<GitHub user name>` というディレクトリ以下に作りましょう。

「現実的に github.com 以外のドメインからコード拾ってくることはあるの？」と思われるかもしれませんが実は結構あります。まず Go 公式のツールは大体 `golang.org/x/tools/cmd/<toolname>` にあります。あとはGitHubのレポジトリから勝手にバージョンタグを拾って適切にインストールしてくれる `gopkg.in` というサービスがあったり（例： `gopkg.in/go-yaml/yaml.v2` は `github.com/go-yaml/yaml` というレポジトリのバージョンタグで `v2`, `v2.x`, または  `v2.x.x` とついている中で最新のものを拾ってくる）と実は色々あります。

Go のディレクトリ構造やコード整理などについてより詳しいことは[公式ドキュメント](https://golang.org/doc/code.html)にまとまっているので一読することをおすすめします。



## 2. プロジェクトの構造
次に重要なのは個別のプロジェクトの構造です。Goのソースコードは**プロジェクトディレクトリの直下に置いてください**（ `src ` などのディレクトリを切ることは**非推奨**です）。なぜかというとプロジェクトディレクトリ以下にディレクトリを切るとそれらのディレクトリはサブパッケージ扱いになるからです（`github.com/<username>/<package>/src` は `src` というパッケージになってしまう）。大量のファイルができてしまうことが憂慮される場合は適切にディレクトリを切ってサブパッケージ化したりプロジェクトを分けたりと**コードの境界を意識して**開発をする必要があります。

次にバイナリを配布したい場合はプロジェクトそのものを `main` パッケージにしてしまうことは基本的に避けましょう。`cmd/<commandname>` というディレクトリを切って `go get github.com/<usermame>/<package>/cmd/<commandname>` とさせましょう。もちろん `cmd/<command1>` `cmd/<command2>` のように複数のコマンドを作ることも可能です。

他にも慣例的にいくつかのディレクトリを切ることがあります。例としてパッケージ内に参照範囲を限定する `internal` やバージョンをフリーズしてコードを配布するための `vendor` などがあります。Go プロジェクトの標準レイアウトは https://github.com/golang-standards/project-layout にテンプレートがあるので一度ご覧になることをおすすめします。



## 3. goimports
Goを書くときにストレスになりがちなことのひとつにインポート管理があります。未インポートのAPIを参照すると当然コンパイルエラーになりますが未使用のパッケージがインポートされているのもまたコンパイルエラーになります。Goと同梱のフォーマッタである gofmt は便利ですが実は goimports というインポートを自動的に挿入・削除してくれる上位互換があります。

```sh
$ go get golang.org/x/tools/cmd/goimports
```

このコマンドを実行すれば `$GOPATH/bin` にバイナリがインストールされます。あとはお好みのエディタのフォーマッタコマンドに goimports を指定すればよしなにインポートを解決してくれるのでとても便利です。



## まとめ
TL;DR

- `mkdir -p $GOPATH/github.com/<GitHub Username>`
- https://golang.org/doc/code.html
- https://github.com/golang-standards/project-layout
- `$ go get golang.org/x/tools/cmd/goimports`

Happy Hacking!
AE シェイプパスをエクスプレッションで描画した時にそのサイズをエクスプレッションでGetする方法

#シェイプパスに書いたエクスプレッション

```jsx
seedRandom(0,true);
createPath([[0,0], [random(500),0]], inTangents = [], outTangents = [], isClosed = false);
```
簡単に説明すると単純にxに0pxからrandom(500)pxまでパスを描いた単純な物です。
それを他のプロパティで取得したかった

#その取得方法は

```jsx
thisComp.layer("シェイプレイヤー 1").content("Object").content("Stroke").content("パス 1").path.points(time)
```
これでとりあえず配列が返ってきます。
実際に返ってきたのは

```console
0,0,194.5625,0
```

これは最初のcreatePathの最初の引数　[[0,0], [random(500),0]]　の部分が多次元配列で返ってきています。
![コメント 2019-11-27 163739.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/0c30a402-3caa-eeb1-1f9d-331582adb438.jpeg)

#多次元配列なので
あとは取得したい配列を取ればよし
例えば

```jsx
thisComp.layer("シェイプレイヤー 1").content("Object").content("Stroke").content("パス 1").path.points(time)[1][0]
```
ってな具合です。

#言いたい事
パスに関してはwidthやheightでは返ってこない。それを私は知らなかったという事です。
というか初めて使った(笑)
お恥ずかしい・・・
Emacs 26.3 で vue-mode の js パートのインデントが効かなくなる件の対処法

`syntax-ppss-table` に何かが設定されているのが原因のようで、Issueにあった次の設定を追加したら直りました。

```el
(setq mmm-js-mode-enter-hook (lambda () (setq syntax-ppss-table nil)))
(setq mmm-typescript-mode-enter-hook (lambda () (setq syntax-ppss-table nil)))
```

# 参照

Indentation problems in \<script> tags #74
https://github.com/AdamNiederer/vue-mode/issues/74#issuecomment-539711083
これから作るRailsアプリの大まかな作成手順～簡易画像投稿サイト～

０．Railsチュートリアルに準拠

１．rails _5.1.6_ new 『名前』

２．gemの準備をしてから、gitしておく
bundle
git init
git add -A
git commit -m "Initialize repository"

３．rails generate controller Home top #ホームコントローラとトップページを作る
root 'home#top'

４．rails generate controller Post new #ポストコントローラとnewページを作る
  get  '/signup',  to: 'users#new' #登録フォームページになる

５．rails generate model User name:string #モデルを作る
rails db:migrate
  resources :users

６．RESTに従った設計にする
GET	/users	index	users_path	すべてのユーザーを一覧するページ
GET	/users/1	show	user_path(user)	特定のユーザーを表示するページ
GET	/users/new	new	new_user_path	ユーザーを新規作成するページ (ユーザー登録)
POST	/users	create	users_path	ユーザーを作成するアクション
GET	/users/1/edit	edit	edit_user_path(user)	id=1のユーザーを編集するページ
PATCH	/users/1	update	user_path(user)	ユーザーを更新するアクション
DELETE	/users/1	destroy	user_path(user)	ユーザーを削除するアクション

７．topに登録、一覧表示へのリンクを表示。余裕があればtopを一覧表示にする。

８．クリックで特定画像ページへのリンク

９．一覧に編集と削除の表示。

１０．form_forがきまれば、carrierとimagemagicもきまる。

１１．一覧ページではclassで大きさを指定してきれいに並べ、実際のページでは原寸表示
.gazouookisa img {
    width: 200px;
    height: 200px;
}

１２．heroku設定。アップして動いたら完成
【初学者・初心者】if分の条件判定を正しく認識するには。

#if文の正しい理解
## 対象者
これからプログラミングを勉強する人

##if文とは

```
if(式){
文
}
```

式が TRUE と評価された場合、 PHP は文を実行します。FALSE と評価された場合は、これを無視します。どのような値が FALSE と評価される

以上の事がif文である。
TRUEの場合とは以下の場合。

```
if(true){
文
}
```

ここで問いです。
問1.以下の場合はtrueですか？falseですか？

```
if(1){
}

```
迷う必要はないですね笑笑
答えはtrueです。
1はtrue、0はfalseとなります。


問2. 以下のの場合はtrueですか？falseですか？

```
if(null){
}
```
答えは、falseです。

:::note warn
警告
上記が全てではないので、ドキュメントで確認してください。
エンジニアならば必ずドキュメントで確認しましょう。
:::

参考URL
[PHP 型の比較表](https://www.php.net/manual/ja/types.comparisons.php)
Glideについて


#Glideとは
Android用の画像読み込みライブラリになります。

機能面でいうと
・基本的に画像URLと表示するImageViewを指定するだけ
・メモリキャッシュ、ファイルキャッシュを自動に行ってくれる
・Gifアニメーションが表示できる

#準備
インポートからします
app/build.gradleに以下を書きこむ

```app/build.gradle
dependencies {
    //Glide
    def glide_version = '4.9.0'
    implementation "com.github.bumptech.glide:glide:$glide_version"
    annotationProcessor "com.github.bumptech.glide:compiler:$glide_version"
}
```

#実装

最低限必要なコードがいかになります。
画像URLをImageViewに入れる感じになります。

```sample.kt
Glide.with(itemView)
    //以下で画像のURLをStringで渡す
     .load("画像URL")
   //配置するImageViewを指定
     .into(imageView)
```

#オプションコード（その他機能）
```sample.kt
Glide.with(itemView)
     //角丸に 
     .apply(RequestOptions.bitmapTransform(RoundedCorners(30)))
     //大きさを指定
     .override(300, 300)

```


#終わりに
自分が行なっていて詰まった点は画像は読み取れるのに表示されないことでした。
原因として、XMLで置いたパーツが他のパーツに潰されて隠れていました。
コードには問題なくも、パーツの設定とかで見えなくなってしまう可能性もあるのでもし、表示されなかったらその辺もみてみるいいかと思います。
[Catalina][Safari] Mac でプロキシの設定を簡単に切り替える

## はじめに
Chrome だと拡張機能を利用すれば簡単にプロキシの設定を切り替えられます．
ちなみに私が愛用しているのは [Proxy SwitchyOmega](https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif) です．

しかしながら，Safari でプロキシを使うには OS のネットワーク設定を変更しなければなりません．
そのこと自体に変わりはありませんが，比較的簡単に切り替えられる方法を見つけたので載せておきます．


## やり方
通常，OS の環境設定からプロキシを設定する場合
「システム環境設定」→「ネットワーク」→「詳細…」→「プロキシ」
のように辿っていくと思います．

下の画像は，「SOCKSプロキシサーバ」で設定する場合の例です．

![スクリーンショット 2019-11-27 15.29.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131552/2d5f6c5f-3376-5caa-4019-68400b7b5dd8.png)

ただ，プロキシを使用する度にこうした必要事項を入力するのは面倒ですよね．

そこでおすすめしたいのが「ネットワーク環境」の追加です．
おそらく，みなさんが普段使用しているのは「自動」という名前のネットワーク環境だと思います．
「システム環境設定」→「ネットワーク」→「ネットワーク環境」→「ネットワーク環境を編集」
のように辿っていくと，「＋」ボタンからネットワーク環境を追加できるのです．

![スクリーンショット 2019-11-27 15.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131552/1d9bfa31-8ac6-4a73-0bb5-c76ae2f5bded.png)

今回は「プロキシ」という名前のネットワーク環境を追加しました．

あとは今まで通り「詳細…」から自分に必要な設定を加えていきましょう．
プロキシを使いたい場合のみ，作成したネットワーク環境に切り替えて「適用」すれば OK です．


## おまけ
私は **SSH ダイナミックポートフォワード** する場合にプロキシを使用します．
研究室外からの通信を遮断しているマシンに，SSH 経由でブラウザからアクセスしたいからです．

詳しいことは別の方の記事を参考にしてください．

- [ポートフォワーディング](https://qiita.com/shuma/items/6b9d0127840f08398126)
- [SSHダイナミックポートフォワードを使ってローカルマシンから固定IPアドレスでWebアクセスをする](https://qiita.com/toshihirock/items/cd28604ecccc5736063d)

`~/.ssh/config` で以下のような記述をしておくと

```~/.ssh/config
Host fwd-hoge
    HostName <IPアドレス or ホスト名>
    User <ユーザ名>
    IdentityFile ~/.ssh/id_rsa
    DynamicForward 1080
```

簡単なコマンドでダイナミックポートフォワードが可能です．

```shell
$ ssh fwd-hoge
```

その後は，上に載せた画像のように 1080 番ポートでプロキシ設定すれば大丈夫です．
もちろん `<IPアドレス or ホスト名>` に `<ユーザ名>` で SSH できることが大前提となっています．


## おわりに
ネットワーク環境の追加はプロキシに限定した話ではありません．
いつも使用するネットワーク設定があり，それを頻繁に切り替えたい場合に有効だと思います．


## 追記
専用のスクリプトを書いて切り替える方法もあるようですね．

- [sshのDynamicForwardで学内専用サービスを家から使う](https://qiita.com/saa/items/35fc55343173b3d135f3)

ついでに，この記事で使用されている `networksetup` コマンドの `man` を見てみました．

```

NETWORKSETUP(8)           BSD System Manager's Manual          NETWORKSETUP(8)

NAME
     networksetup -- configuration tool for network settings in System Preferences.

SYNOPSIS
     networksetup [-listnetworkserviceorder] [-listallnetworkservices] [-listallhardwareports] [-detectnewhardware]
                  [-getmacaddress hardwareport] [-getcomputername] [-setcomputername computername]
                  ...(中略)...
                  [-setsocksfirewallproxy networkservice domain portnumber authenticated username password]
                  [-setsocksfirewallproxystate networkservice on | off] [-getproxybypassdomains networkservice]
```

ありましたね．
ということは，以下のコマンドで `domain` や `portnumber` も指定できそうな気配です．

```shell
$ networksetup -setsocksfirewallproxy wi-fi localhost 1080
```

できました．ネットワーク環境を追加するより，むしろこの方が便利かも…
ROS2初心者トラブルシューティング

# はじめに
ROSConJPや関西ROS勉強会で行われたROS2講習会においてTAをやったり、研究室の後輩にROS2を教えたりしていました。
似たようなところでつまづく人が多かったので、今回はよくあった質問をまとめてみました。
基本的には、[ROS2講習会](https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Debians/)までの範囲で起こりうる内容になっています。
#よくある質問
### サンプルを動かしたら、たくさんHello worldが飛んできます。バグですか？
講習会で、備え付けのサンプルである
`ros2 run demo_nodes_cpp talker`
`ros2 run demo_nodes_py listener`
を動かした際に起こります。明らかに自分のpublishしたHello worldではないものが飛んでくる時があります。
ROS2では同一ネットワーク間に存在するとデータのやりとりをしてしまうので、識別するためのIDを設定するとよいです。
~/.bashrcの一番下に
`export ROS_DOMAIN_ID=1225`(1~65532で被らなそうな値)
を追加してあげましょう。

###colcon: command not found
`sudo apt install python3-colcon-common-extensions`
なぜかバイナリでROS2をインストールしてもcolconはついてこないんですよね...

###colcon buildが通らない
間違えた場所にCMakeLists.txtやpackages.xmlを作り、一回colcon buildして「あっ失敗した！」となった後に正しい場所に置き直してませんか？
一度colcon buildを行うと、パッケージの場所がキャッシュに残り、違う場所に置き直した時に前と違いますよと怒られる仕様になっています。
解決策：colcon buildの実行オプションでキャッシュを削除する
``colcon build --cmake-clean-cache``

# たまにある質問

###パソコンのスペックが低すぎてビルドが途中で落ちる
ROS2のビルドは、デフォルトでは4並列で行うようになっており、低スペックPCやラズパイだとうまく行かないことがあります。
解決策：colcon buildの実行オプションで並列実行数を1にする
``colcon build --parallel-workers 1``

###macOSで動かない...
実は、macOSでサポートされている（動作検証が行われている）のは、Sierra(10.12)だけです。（参考：https://index.ros.org/doc/ros2/Installation/Dashing/OSX-Install-Binary/#system-requirements ）
最新のCatalinaが10.15であることを考えるとだいぶ古いです。新しいバージョンでも動くのですが、ライブラリが新しすぎてエラーが起きる場合があります。

エラーの中に
```Library not loaded: /usr/local/opt/（ライブラリ名）```
がある場合がそれです。
Mojave(10.14)はよく使われていて、[ros2のissue](https://github.com/ros2/ros2/issues/)に上がっていることも多いですが、取り上げられていない場合エラーメッセージから検討をつけるしかないです。

解決策：該当ライブラリのダウングレード
ダウングレードの参考：https://blog.spiralray.net/archives/978


Dashingなど古いdistroで起こりやすいらしいので、新しいEloquentを使うのもいいかもしれません。

#その他一回だけあった質問
#### colcon testってどうかけばいいの？
各パッケージにCTestとpytestを書けばいいらしいです。テスト大事ですね（戒め）
#### windowsでROS2使えるんでしょ？
使えるらしいですが、Ubuntuで普通に動かすよりもはるかにハマりポイントが多いらしいです。
#### zshって使えるの？
使えます。ROS2インストールフォルダにsetup.zshがあるのでそちらを読み込んでください。
#### 一つのPCにDashingやCrystalなどの複数のバージョンを入れて動かせる？
多分推奨はされませんが、ある程度動かせることは確認しています。
#### Ubuntu16.04で動かせますか？
Crystalまでは動かせます。ただDashingは動かないと思います。（公式でもサポートされていません）
私がやった時はpython3.5じゃ古すぎると言われて動きませんでした。
#まとめ
`colcon build -h`でオプションを一通り確認しておくといいかもしれません。
--continue-on-error（失敗したパッケージがあっても全体のビルドが止まらない）、--packages-select（特定のパッケージだけビルドする）など色々な状況に対応できるようになっています。

ROS2はLinuxでもmacOSでもwindowsでも動くよ！とは言われていますが、今の所最低限動かすだけでも、Linux > macOS >> (超えられない壁) >> windowsという感じです。
macOSのHomebrewバージョン依存の問題は把握しづらいので、自分でなんとかできる中級者向けです。
windowsはパッケージ管理ソフトがなく手順がややこしい上、人口が少なすぎて問題共有の機会すら少ないのが難しさに拍車をかけている状況です。

#参考
同一ネットワーク内で複数人がROS2を使用する場合 https://qiita.com/NeK/items/6163d5a307665a3c9c1c
ROS2ではじめよう 次世代ロボットプログラミング
1/30 days　hackerrank　で学んだこと。

この記事は、
pythonを用いてHackerRank1/30に取り組んだ時に、
調べた内容をまとめたものです。

#データ型~数値の扱い~

int:整数を扱う
double:有効桁数15桁
float:有効桁数6,7桁
string:文字列型の扱い
round:四捨五入

データ型の変換を__キャスト__という。
printで数値を出力するときにstrをよく忘れるので注意です。

#listで文字列を１文字ずつ認識できる
例）

```
str="Hacker"
char_list=list(str)
print(char_list)
```
で、`["H", "a", "c", "k", "e", "r"]`と出力されます。

#リストを文字列に変換する
つまり今度は、
`["H", "a", "c", "k", "e", "r"]`
と表示されるものを、

`Hacker`に
直したいということです。

①forをつかう

``` 
str_list = ['python', 'list', 'exchange'] 
 mojiretu = ' ' 
for x in str_list:
mojiretu += x
print(mojiretu) 
```
実行結果：pythonlistexchange

②joinを使う
join関数の使い方
`文字列 = ‘区切り文字’.join(リスト)`

```
str_list = ['python', 'list', 'exchange']
mojiretu = ','.join(str_list) 
print(mojiretu)
```
実行結果：python,list,exchange


#スライス
列の要素を部分的に取り出すのに有用な方法です。

基本の例)
[@ycctw1443](https://qiita.com/ycctw1443/items/03f99f3f72a797fdcbf6)さんのものを引用しています。
```
a = [1, 2, 3, 4, 5]
print(a[0: 4])
print(a[: 4])
print(a[-3:])
print(a[2: -1])

```
すると、
[1, 2, 3, 4]
[1, 2, 3, 4]
[3, 4, 5]
[3, 4]
と出力されます。

これを発展させ、
「n番目ごとに要素を得る」こともできます。
`a[始まりの位置: 終わりの位置: スライスの増分]`です。

```
a = [1, 2, 3, 4, 5]
print(a[:: 2])
print(a[1:: 2])
print(a[::-1])
print(a[1::-1])
```
結果）
[1, 3, 5]
[2, 4]
[5, 4, 3, 2, 1]
[2, 1]

#複数の文字列を入力する
`input().split()`

#printと%
%を使えば、変数が組み込まれた文字列を
簡潔に出力することができます。

```
print("好きな果物は、%sです。" %'リンゴ') 
print("好きな果物は、%sと%sです。" %('リンゴ','ミカン')) 

x = 'サッカー' 
y = 'スノーボード' 
print("好きなスポーツは、%sと%sです。"%(x,y)) 
```

%sはstr()をあらわし、
値を文字列として整数も少数も表示できますが、
%dとすると整数になります。

%rはrepr()で、
渡された値をそのまま表示します。

#Star演算子
配列を展開することができます。



##参考
https://programming-study.com/technology/python-list-join/
https://code-graffiti.com/print-format-with-string-in-python/
UnityをGitHub Actionsで動かす際にライセンス認証周りで注意するべき点

さんざん手こずったので初投稿です（やけくそ）。

GitHub ActionsでUnityのライセンス認証周りで撃沈しすぎた。
正しいライセンス認証の方法と注意点をここに記す。

GitHub Actionsのsecretsにulfファイルの内容を保存しているものとする。キーは&quot;ulf&quot;。

```yaml
- run: |
    echo -n "$ULF" > unity.ulf
    /opt/Unity/Editor/Unity -nographics -batchmode -quit -logFile -manualLicenseFile ./unity.ulf || exit 0
  with:
    ULF: ${{ secrets.ulf }}
```
上記コードでライセンス認証は正しく行える。

```
Initiating legacy licensing module

 Load manual activation license file.

LICENSE SYSTEM [20191127 7:6:38] Load license file from: ./unity.ulf

LICENSE SYSTEM [20191127 7:6:38] Next license update check is after 2019-11-27T15:24:07


 License file loaded.
```
logFileの出力は上記の通り。
認証が正しく行えると「Next license update check is after ほげほげ」と出力される。

#注意点0 echoのオプション

```
echo -n
```
echoコマンドのオプションに必ず-nを指定するべし。
これは最後の改行コードを出力しないという意味である。
何故か知らないが、一文字でも余計な文字が加わると認証にしくじる（10敗）。

#注意点1 環境変数をダブルクォートでくくる

```
echo -n "$ULF"
```
環境変数の中身をechoしたいならばダブルクォートでくくる必要がある。
くくらない場合は単に$ULFと出力される（50敗）。

#注意点2 環境変数を使う
環境変数ULF（名前は何でもいい）にsecrets.ulfを設定するべし。

```
echo -n ${{secrets.ulf}}
```
と仮に記述したらulfが複数行なのでエラー吐いてジョブが死ぬ（２敗）。

#注意点3 ulfの中身は絶対に外部に見せない
ulfは機密情報なので明かしてはならない(0敗)。
デバッグ時に自分が見れる情報は全て他の人が見れると考えられる。
故に間違えてもそれに気付けない。コワイ！

#感想・終わりに
一回５分～７分×60回つまり5~7時間無駄にした上で得た教訓を活かしてください。
[ Android Studio ]　ショートカットキー

今回はAndroid Studioで使われるショートカットキーを紹介する。

##ショートカット
|内容 | ショートカット |
|:-----------|------------:|
| コードフォーマット       | Ctl + Alt + L        | 
| ファイル構造のチェック     | Ctl + F12      | 
| 進む       | will        | 
| 戻る       | Ctl + Alt + →          | 
| メソッドジャンプ       | Ctl + Alt + ↓ or ↑           | 
| 呼び出し階層を開く    | Ctl + Alt + H     | 
| 使用箇所を探す    | Alt + F7     | 
| 選択範囲拡大   | Ctl + W     | 
| 選択範囲拡大   | Ctl + Shift + W     | 
| リネーム    | Ctl + F6     | 
| クラスファイル検索    | Shiftを二回押す     | 
| クラスファイル検索    | Shiftを二回押す     | 


##参考サイト
https://qiita.com/arai-wa/items/b0957d042c479577e8e3
https://qiita.com/takke/items/5cbc629f7f65d6a49906
Javaで電卓アプリ作ってみる 〜ウィンドウの中に表示領域を作る

Javaの開発環境は、Ubuntu 18.04にインストールしたOpenJDK 11.0.4を使用しています。

[前回の記事](https://qiita.com/tsweblabo/items/23e7e858cc81ccabed59)では、アプリケーションウィンドウを表示させました。今回はウィンドウの中の表示領域を作っていきます。
前回のコードは、とりあえずJframeを使ってアプリケーションウィンドウの表示が目標だったので、コードの全てをmainメソッドの中に書いてましたが、今後の書きやすさ・読みやすさを考えてMyFrameメソッドを作り、mainメソッドの中でインスタンス化しています。

```java:MyFrame.java
import javax.swing.JFrame;

public class MyFrame extends JFrame{
    public static void main(String[] args) {
        MyFrame frame = new MyFrame("JavaSwingのテスト");
        frame.setVisible(true);
    }

    MyFrame(String title){
        setTitle(title);
        setSize(500, 600);                                // ウィンドウのサイズ (幅, 高さ)
        setLocationRelativeTo(null);                      // ウィンドウを画面中央に表示
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   // x(バツ)ボタンでアプリケーションを終了させる。
    }
}
```

JavaSwingでは、土台となるJFrame、その上にパネルやボタンなどを配置するレイヤー構造をしています。
JFrameだけではウィンドウを表示させるだけなので、電卓アプリに必要な数字を表示させるパネルを作ってみます。

```java:MyFrame.java
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Container;



public class MyFrame extends JFrame{
    public static void main(String[] args) {
        MyFrame frame = new MyFrame("JavaSwingのテスト");
        frame.setVisible(true);
    }

    MyFrame(String title){
        setTitle(title);
        setSize(500, 600);                                // ウィンドウのサイズ (幅, 高さ)
        setLocationRelativeTo(null);                      // ウィンドウを画面中央に表示
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   // x(バツ)ボタンでアプリケーションを終了させる。

        setLayout(new FlowLayout());

        JPanel panelDisplay = new JPanel();                         // パネルのインスタンス化
        panelDisplay.setPreferredSize(new Dimension(500, 60));      // パネルサイズ
        panelDisplay.setBackground(new Color(51, 51, 51));          // カラーコード#333333
        BevelBorder border = new BevelBorder(BevelBorder.RAISED);
        panelDisplay.setBorder(border);

        Container contentPane = getContentPane();
        contentPane.add(panelDisplay);
    }
}
```

実行結果は、下図のようになりました。
今回は暫定でパネルのサイズを500×60、カラーを#333333としました。
この後ボタンなどの配置などもあるため、サイズ等の変更があるかもしれません。

![JavaApp003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150278/8bcc76b8-8eaa-d799-1c20-7d28028e1950.png)


---

### 本記事目次ページ

[Javaで電卓アプリ作ってみる](https://qiita.com/tsweblabo/items/a77d1146c9057c369e39)
pipenv環境でjupyterを使う際のkernel設定

pipenvで構築した環境にjupypterを追加し際、Pipfileでインストールしたモジュールが見つからず悩んだ。
jupyterで使用するkernelを設定することで解決したので覚え書き。

## 1. 必要ライブラリのインストール
Pipfileに `jupyter` と `ipykernel` を追記してインストール。

```
[packages]
tensorflow = "*"
keras = "*"
pillow = "*"
numpy = "*"
scikit-learn = "*"
ipykernel = "*"
jupyter = "*"
```

`ipykernel`は、IPythonのkernelを設定できる？ツールの様。
jupyter上でnotebookを作成する際にこのツールで設定したkernelを選択できる。

## 2. kernelの作成
下記のコマンドでjupyterで使用するkernelを作成する。

```
$ pipenv shell
$ python -m ipykernel install --user --name=<お好きな名前>
```
※--name で設定した名前がjupyterで選べるkernel名となる

## 3. kernelの選択
下記コマンドでjupyterを起動する。
```
$ jupyter notebook
```
jupyterの画面の右上の「New」から2で設定したkernel名を指定する。

これで、Pipfileでインストールしたモジュールが使えるようになる。
みんな大好き @mattn_jp さんのホクイモRuby ver.の解説

# 概要
@mattn さんの[ホクイモ](https://qiita.com/mattn/items/d447a43ad12fada71663)、Rubyでわからないところがあったので調べました。

# 説明
コード再掲

```ruby
puts '%1$s%1$sの%2$s'%((%w[ホイクモ]*2).map{|x|x.chars.sample(2).join})
```

`'%1$s%1$sの%2$s'%`の最後の%は[`String#%`](https://ruby-doc.org/core-2.6.5/String.html#method-i-25)で、Stringクラスのメソッドで、フォーマットに対して呼び出すと引数を適用した文字列を返してくれるそうです。

フォーマットの詳細は[`Kernel::sprintf`](https://ruby-doc.org/core-2.6.5/Kernel.html#method-i-sprintf)を見ろというので、見に行きます。

見てみると、`%`、`s`、`$`を使っているとわかります。
下記の事例などがわかりやすいですね。

```ruby
sprintf("%1$*2$s %2$d %1$s", "hello", 8)   #=> "   hello 8 hello"
```

# 感想
元記事のコメント欄で、C++の人から強い言葉でコメントがついていて、（以下略）。
【Laravel】データベースを作成しよう

こんにちは！
今回はデータベースにデータを保存できるようにすることを最終地点として説明します
大まかな流れは以下の通りです
1. 環境変数を設定する
2. データベースを作成する
3. データベースに接続する
4. データベースにデータを保存する

では、始めます！！

#環境変数の編集
環境変数を編集していきます
環境変数は使用するOS上でのルールを決めている変数というイメージです。
ここで編集するファイルは二つです

##.envファイルの編集
.envファイルを編集します
下記のように編集していきましょう
データベースの名前はご自身のアプリケーション名に対応させてください
`DB_USERNAME`は`root`、`DB_PASSWORD`は`secret`で設定しましょう

```:.env（一部）　編集前
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

```

```:.env（一部）　編集後
DB_DATABASE=laravel-project
DB_USERNAME=root
DB_PASSWORD=secret
```

##database.phpの編集
`.env`に合わして`database.php`も編集しましょう

```php:config/database.php
'mysql' => [
//　　　　　　　　　　　　　　　　　　　　　：
//　　　　　　　　　　　　　　　　　　　　　：
     'database' => env('DB_DATABASE', 'laravel-project'),
     'username' => env('DB_USERNAME', 'root'),
     'password' => env('DB_PASSWORD', 'secret'),
//　　　　　　　　　　　　　　　　　　　　　：
//　　　　　　　　　　　　　　　　　　　　　：
],
```


#データベース作成
MySQLにログインして、データベースを作成しましょう！
MySQLにrootユーザーでログインします。

```
$ mysql -u root
```



MySQLにログイン完了後、`laravel-project`というデータベースを作成します

```
mysql> CREATE DATABASE `laravel-project`;
```

下記のコマンドでデータベースが作成されているか確認しましょう

```
mysql> show databases;
```

#データベース接続
上で作成したデータベースに接続しましょう

```:ターミナル
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.9-1+ubuntu18.04.1+deb.sury.org+1 — cli) by Justin Hileman
>>> DB::connection();
=> Illuminate\Database\MySqlConnection {#2891}
```

#テーブル作成
マイグレーションして、テーブルを作成します。
マイグレーションする前に少し準備をします。
##文字列の最大文字数を191文字にする
マイグレーション時にエラーになるので設定しましょう

```php:app/Providers/AppServiceProvider.php
    public function boot()
    {
        \Schema::defaultStringLength(191);
    }
```

では、下記のコマンドでマイグレーションを行い、テーブルを作成しましょう

```:ターミナル
$ php artisan migrate
```

テーブルの作成が完了しました。

#データ作成
一度に複数のデータを作成しましょう!!
まず、下記のコマンドを実行するとUsersTableSeeder.phpが生成されます。

```:ターミナル
$ php artisan make:seeder UsersTableSeeder
```

生成されたUsersTableSeeder.phpのRun関数内に下記のように追記しましょう

```php:database/seeds/UsersTableSeeder.php
    public function run(){
        DB::table('users')->insert([
            'name' => 'test1',
            'email' => 'test1@test.com',
            'password' => bcrypt('test1') 
        ]);
    }
```

次に、DatabaseSeeder.phpのRun関数内をコメントアウトしてください

```php:database/seeds/DatabaseSeeder.php
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }
```

上記で編集したファイルを元にデータを作成しましょう

```
$ php artisan db:seed --class=UsersTableSeeder
```

コンソールから作成されたデータを確認しましょう

```
$ php artisan tinker

>>> use App\User
>>> User::all()
```

上記のコマンドでテーブル内のデータが表示されます
表示されれば完了です！！

**疑問、気になるところがございましたら、質問、コメントよろしくお願いします！！！**
01. 「パタトクカシーー」

## 01. 「パタトクカシーー」
「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ．

###Go
```go
package main

import "fmt"

func main() {
	var src string = "パタトクカシーー";
	var des string = "";

	//	rune 型へ変換
	msrc := []rune(src);

	//	1.ループで処理
	for i := 0; i <= 7; i++ {
		//	問題では 1,3,5,7 指定だが奇数判定で対応
		if (i % 2) != 0 {
			des += string(msrc[i]);
		}
	}
	fmt.Println(des);
}
```


###python
```python
# -*- coding: utf-8 -*-
src = u"パタトクカシーー"
des = ""

#   1.ループで処理（range)
reverse = ""
for i in range(len(src)):
    # 問題では 1, 3, 5, 7 指定だが奇数判定で対応
    if i % 2 != 0 :
        des += src[i]
print(des)

# -*- coding: utf-8 -*-
src = u"パタトクカシーー"
des = ""

#   1.ループで処理（range)
reverse = ""
for i in range(len(src)):
    # 1, 3, 5, 7 指定だが奇数判定で対応
    if i % 2 != 0 :
        des += src[i]
print(des)

#   2.スライスで処理（ステップを指定）
print(src[1::2])
```


###Javascript
```Javascript
var src = "パタトクカシーー";
var dsc = ""

//	1.ループで処理
for (var i = 0; i < src.length; i++) {
    //  問題では 1, 3, 5, 7 指定だが奇数判定で対応
    if (i % 2 != 0) {
        dsc += src[i];
    }
}
console.log(dsc);
```

## まとめ
単純なループ処理しか思いつかない。
他のロジックって有るのかな？。100本ノックの記事探してみる。
1,3,5,7 を渡すと、切り出してくれる標準関数とか有るのかな？。

[トップ](https://qiita.com/naoshin1984/items/3d7814e2f8eb01eea8dd)
言語処理100本ノック 2015 をやって「みた」→「みる」

#言語処理100本ノック 2015 をやってみた
##動機と目的
新たな言語を勉強してみるが使わないと忘れていく。
Qiita で 100本ノックの記事を見た。なるほど。やってみよう!!。

## 目標
- 毎日（たぶん）、問題を解くことでそれぞれの言語に慣れるようにしてみる。
- Qiita に書くことで Markdown に慣れる。

## 言語
- Go
- Python
- Javascript

を主にやってみる。


## 100本ノック
### 第1章: 準備運動
- [00.文字列の逆順](https://qiita.com/naoshin1984/items/04d54f4437c7e37d20aa)
文字列"stressed"の文字を逆に（末尾から先頭に向かって）並べた文字列を得よ．




- [01. 「パタトクカシーー」](https://qiita.com/naoshin1984/items/97b87c326058fc110657)
「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ．



- [02. 「パトカー」＋「タクシー」＝「パタトクカシーー」](https://qiita.com/naoshin1984/items/2a415642f214236e4f79)
「パトカー」＋「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ．



- [03. 円周率](https://qiita.com/naoshin1984/items/dc15a3de948ab3f91957)
"Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."という文を単語に分解し，各単語の（アルファベットの）文字数を先頭から出現順に並べたリストを作成せよ．



- [04. 元素記号](https://qiita.com/naoshin1984/items/87e255ee81ba6f3e46cd)
"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."という文を単語に分解し，1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字，それ以外の単語は先頭に2文字を取り出し，取り出した文字列から単語の位置（先頭から何番目の単語か）への連想配列（辞書型もしくはマップ型）を作成せよ．



- [05. n-gram](https://qiita.com/naoshin1984/items/d1034d0fa5b1adaeaa26)
与えられたシーケンス（文字列やリストなど）からn-gramを作る関数を作成せよ．この関数を用い，"I am an NLPer"という文から単語bi-gram，文字bi-gramを得よ．



- [06. 集合](https://qiita.com/naoshin1984/items/9434543959dd5569eecf)
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ



- [07. テンプレートによる文生成](https://qiita.com/naoshin1984/items/a19a803fe2c567dc68d7)
引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ．さらに，x=12, y="気温", z=22.4として，実行結果を確認せよ．



- [08. 暗号文](https://qiita.com/naoshin1984/items/eedb9fc83328dc8ac927)
与えられた文字列の各文字を，以下の仕様で変換する関数cipherを実装せよ．
 - 英小文字ならば(219 - 文字コード)の文字に置換
 - その他の文字はそのまま出力
 - この関数を用い，英語のメッセージを暗号化・復号化せよ．

- [09. Typoglycemia](https://qiita.com/naoshin1984/items/fb35342bb6a562b7a572) 
スペースで区切られた単語列に対して，各単語の先頭と末尾の文字は残し，それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ．ただし，長さが４以下の単語は並び替えないこととする．適当な英語の文（例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."）を与え，その実行結果を確認せよ

### 第2章: UNIXコマンドの基礎
- [10. 行数のカウント](https://qiita.com/naoshin1984/items/159aba4adff08e81fe67)
行数をカウントせよ．確認にはwcコマンドを用いよ．

- [11. タブをスペースに置換](https://qiita.com/naoshin1984/items/33e21f6ebdc0017bd592)
タブ1文字につきスペース1文字に置換せよ．確認にはsedコマンド，trコマンド，もしくはexpandコマンドを用いよ．

- [12. 1列目をcol1.txtに，2列目をcol2.txtに保存](https://qiita.com/naoshin1984/items/36c8f49a70a5afea6d80)
各行の1列目だけを抜き出したものをcol1.txtに，2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ．確認にはcutコマンドを用いよ．

- [13. col1.txtとcol2.txtをマージ](https://qiita.com/naoshin1984/items/edaddeb8c842e41cd1b1)
12で作ったcol1.txtとcol2.txtを結合し，元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ．確認にはpasteコマンドを用いよ．



## 参考
[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)
Google Cloud AI Platform、What-if Toolを使ってみた②

# 1. はじめに
 - 前回[Google Cloud AI Platform、What-if Toolを使ってみた①](https://qiita.com/yuxzux/items/ebf1b992a168c387b05e)の続きです。
 - What-if Toolで何が見れるかを記載します。

# 2. What-if Tool を使ってモデルを解釈する
## Step 1: 個別データポイントの探索
デフォルトでは*Datapoint editor*タブが表示されています。各データをクリックすると個別の特徴が見えます。複数データの特徴を見ることで各データがモデルにどのように影響を与えているかが確認できます。

1つデータを選んで、特徴量の値を変更して、`Run Inference`をクリックしてみます。
`agency_code_Department of Housing and Urban Development (HUD)`を試しに0から１に変更してみましょう。

<img width="1382" alt="スクリーンショット 2019-11-27 14.00.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/52669b48-4637-335a-ffc9-0cf8ae926882.png">

モデルの承認予測値が変化します。これで特徴量がどのくらい予測モデルに影響を与えているかがわかります。

左下のUIからそれぞれの予測スコアを見ることができます。
<img width="525" alt="b389f416a1909353.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/20d6ead7-ce25-a8aa-cd05-147f4aa34cda.png">

## Step 2: 反事実分析
データポイントを選択して、**Show nearest counterfactual datapoint**スライダーを右にスライドさせましょう。

<img width="525" alt="b389f416a1909353.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/8a27487d-eca1-2e53-20fb-dda97464213f.png">

最も似ている特徴量を持ち、反対の予測値を示すデータポイントが表示されます。２つの差分を理解できます。

## Step 3: 部分変数重要度
それぞれの特徴量が予測モデルにどのように影響するか見るために、**Partial dependence plots**をチェックし、**Global partial dependence plots**を選択します。

![72117b5ceb683841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/c1d23086-0a23-1c0a-889f-80b82ce31e0c.png)

HUDからのローンは否認される確率がわずかに高いことがわかります。

`application_income_thousands`は数値特徴量です。200kドルまでは収入が多いほど承認されやすいことがわかります。200kドルより高い場合は、モデルの予測に影響を与えていないことがわかります。

## Step 4: 性能と公平性の探索

**Performance & Fairness**タブを開きます。混同行列、PR曲線とROC曲線を含むモデルの性能統計結果をみられます。

`mortgage_status`を選択し、混同行列を見ます。
![fe1384ee47699498.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/1bdc84da-8c37-d8be-5fc0-d51eca251e56.png)

混同行列はモデルの正解・不正解の予測を示します。

ローンの`approved`を予測する前に、閾値のスライダーを使って、分類スコアの変動を確認できます。この場合、閾値が**0.55**の時accuracyが最大になります。

`loan_purpose_Home_purchase`を選択します。
![f3f1858d627d57ab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/d9cd7fc3-902c-6193-cbc4-4ce893e6a7ec.png)

"0" は住宅用のローン、"1"はそれ以外のローンであることを示します。false positiveとfalse negativeの値に差があることを確認できます。

画面を展開すると混同行列が表示されます。住宅ローンの場合は70%が承認されていると予測し、それ以外のローンでは４６％が承認されていると予測しています。
![318a8d5a8ffc6bea.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/f6963c91-1324-96cb-5e27-17722a58f437.png)

**Demographic parity**を選択すると、2つの閾値が調整され、2つのスライスが同じくらいの割合で`approved`と予測されるようになります。

## Step 5: 特徴量の分布
What-if Toolの**Feature**タブでは特徴量それぞれの分布が見られます。

![48ab3c4879793324 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271751/2badfdc2-8a89-75cb-2317-5ce69c154607.png)

偏りをみましょう。
Python3: JSON ファイルを http サーバーにアップロード

Python の cgi で　JSON  ファイルをアップロードする方法です。
この例では、アップロードしたファイルが、
/var/tmp/json/example.json
に書き込まれます。

サーバーサイドの処理

```py:json_receive.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#       json_receive.py
#
#                                       Nov/23/2019
#
# --------------------------------------------------------
import  sys
import  os
import  string
import  json
import  fcntl
import  cgi
import cgitb
cgitb.enable()
#
# --------------------------------------------------------
def file_write_proc(file_name,str_out):
#
        fp_out = open(file_name,mode='w',encoding='utf-8')
        fcntl.lockf(fp_out, fcntl.LOCK_EX)
        fp_out.write(str_out)
        fp_out.close()
#
# --------------------------------------------------------
def get_string_proc(ff,key):
    if key in ff:
        value = ff.getfirst(key,"")
    else:
        value = "0000"
#
    return value
# --------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
ff=cgi.FieldStorage()
#
json_str = get_string_proc(ff,"json")
#
file_name = "/var/tmp/json/example.json"
file_write_proc(file_name,json_str)
#
print ("Content-type: text/json; charset=UTF-8\n\n")
print (json_str)

sys.stderr.write("*** 終了 ***\n")
#
# --------------------------------------------------------
```

クライアントの処理

```py:json_send.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#   json_send.py
#
#                   Nov/27/2019
#
# ------------------------------------------------------------------
import  sys
import  json
import  requests

from file_io import file_to_str_proc
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
        str_out = ""
        try:
                fp_in = open(file_in,encoding='utf-8')
                str_out = fp_in.read()
                fp_in.close()
        except Exception as ee:
                sys.stderr.write("*** error *** file_to_str_proc ***\n")
                sys.stderr.write(str (ee))
#
        return  str_out
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_json = sys.argv[1]
#
json_str = file_to_str_proc(file_json)
#
url="https://example.com/json_receive/json_receive.py"

args={}
args['json'] = json_str
#
rr=requests.post(url,args)
print(rr.text)
#
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------
```

クライアントの使い方

```bash
./json_send.py in01.json
```
Windows10のWSLでLinuxを使う手順

# Windows10のWSLでLinuxを使う手順

## WSLを有効にする

Win+Rで「ファイル名を指定して実行」ダイアログを開く
`control`と入力して`<ENTER>`

![Clipboard01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170209/42ecf26e-d8d8-6c1a-8ccf-510075a2e78d.jpeg)

「プログラムと機能」をクリックして、表示されたウィンドウから
「Windowsの機能の有効化または無効化」をクリック

![Clipboard02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170209/cf5bdc5e-b73c-a173-d5a3-543f9f192d38.jpeg)

「Windows Subsystem for Linux」のチェックを入れてOK
再起動

![Clipboard03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170209/a3434730-976b-d9a1-06b5-6536c768c7aa.jpeg)

## Linux（Ubuntu）をインストールする

スタートメニューからMicrosoft Storeを実行し「ubuntu」で検索する。
検索結果から「Ubuntu」をクリック、続いて「入手」をクリックでしばらく待てばインストールが完了する

その後、ユーザー名とパスワードを聞かれるのでそれぞれ入力して完了

## Ubuntuの起動

スタートメニューの「ubuntu」アイコンをクリックで起動
またはプログラムを指定して実行で「ubuntu」を指定で起動

## pxoryとaptの設定

proxyの設定
というか、[proxy環境下の設定（ubuntu 14\.04\) \- Qiita](https://qiita.com/showsuzu/items/9ee031208d38ff8ac889)を参考に設定

```sh
export https_proxy=ProxyのURL
export http_proxy=ProxyのURL
```

aptのproxy設定（ファイルは新規に作成する）

```conf:/etc/apt/apt.conf
Acquire::ftp::proxy "ftp://username:password@your.proxy.address:proxy.port/";
Acquire::http::proxy "http://username:password@your.proxy.address:proxy.port/";
Acquire::https::proxy "https://username:password@your.proxy.address:proxy.port/";
```

aptのupdate

```sh
$ sudo apt-get update
```

その他、aptの使い方
[aptコマンドチートシート \- Qiita](https://qiita.com/SUZUKI_Masaya/items/1fd9489e631c78e5b007)

## gccとかmakeとかの開発ツールインストール

```sh
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev
sudo apt-get install libffi-dev
```

## gitからdotfilesとかダウンロード

gitのSSL無視。必要な場合のみ。

```sh
$ git config --global http.sslVerify false
```

gitから設定ファイル等をクローンしてくる。必要な場合のみ。

```sh
$ git clone htts://github.com/<user_name>/<repository_name>.git
```
【Unity(C#),Python】API通信勉強メモ②Flaskでローカルサーバー立ち上げ

##今回やること
この記事は前回の勉強の続きです。
【前回】：[【Unity(C#)】API通信勉強メモ①](https://qiita.com/OKsaiyowa/items/d0d2de3f39c2b3da8f2f)

前回できなかったPostの処理を学びます。

なんもわからんなりの解釈が山盛りなのでマサカリ、オールオッケーです。

##Flask

>Flask（フラスク）は、プログラミング言語Python用の、軽量なウェブアプリケーションフレームワークである。標準で提供する機能を最小限に保っているため、自身を「マイクロフレームワーク」と呼んでいる。

[Wikipedia](https://ja.wikipedia.org/wiki/Flask)より引用


今回はFlaskというPythonのウェブアプリケーションフレームワーク[^1]を使用して
**ローカルにアプリケーションサーバーを立て、Unity側からHTTPリクエスト(POST)を送る**
までやってみようと思います。

おおよそ、参考リンクに沿って進めていきます。

【参考リンク】：[Pythonと連携する方法](https://sharkattack51.github.io/post/cs_py/)


###Flaskのインストール
```
$pip install flask
```


##GETリクエスト

まずはFlaskで立てたローカルのサーバーにGETリクエストを送ってみます。

```Python:Python側の処理
from flask import Flask

app = Flask(__name__)


@app.route("/", methods=['GET'])
def index():
    return "HIKAKIN「ブンブン！ハローユーチューブ！」"


if __name__ == "__main__":
    app.debug = True
    app.run()

```

Unity側の処理は下記リンクから拝借しました。
【参考リンク】：[UnityでHTTPに接続する](https://qiita.com/ponchan/items/65aeb43e8fea8da0bcac)

```C#:Unity側でHTTPリクエストを送るスクリプト
using System.Collections;
using UnityEngine.Networking;
using UnityEngine;

public class HTTPGet : MonoBehaviour {

    //接続するURL
    private const string URL = "http://localhost:5000/";

     void Start()
    {
        //コルーチンを呼び出す
        StartCoroutine("OnSend", URL);
    }

    IEnumerator OnSend(string url)
    {
        //指定したURLでGET
        UnityWebRequest webRequest = UnityWebRequest.Get(url);

        //URLに接続して結果が戻ってくるまで待機
        yield return webRequest.SendWebRequest();

        //エラーが出ていないかチェック
        if (webRequest.isNetworkError)
        {
            //通信失敗
            Debug.Log(webRequest.error);
        }
        else
        {
            //通信成功
            Debug.Log("Get" + " : "+webRequest.downloadHandler.text);
        }
    }
}

```


![GetHIKAKIN.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/2c25e33c-a545-3003-97c9-1beeb06d68e9.gif)

成功しました。
①Python側(VSC)でデバッグを開始
②UnityでPlay
という順番です。

##POSTリクエスト

次はFlaskで立てたローカルのサーバーにPOSTリクエストを送ってみます。
`@app.route("/", methods=['POST', 'GET'])`にPOSTを追加しただけです。

```python

from flask import Flask

app = Flask(__name__)


@app.route("/", methods=['POST', 'GET'])
def index():
    return "HIKAKIN「ブンブン！ハローユーチューブ！」"


if __name__ == "__main__":
    app.debug = True
    app.run()

```

実際にやってみて思ったこととしては**結局POSTとGETは何が違うんだよ**ってことです。
この疑問に関しては下記リンクを見て一旦深く考えるのを止めることにしました。
【引用元】：[GETとPOSTの違いについて](https://qiita.com/kanataxa/items/522efb74421255f0e0a1)

>本当はGETでやるべきこともPOSTでできてしまうのです。
やろうと思えばすべての処理をPOSTで作れてしまうのです。
この辺りは思想的な話もあるので、何とも言えない部分です。


##次回やること
Postの処理も上手くいったので次回は**Unity側から入力した情報を登録 & ログインする機能**を作っていきます。


とりあえずわかっていることとしては、
リクエストを送る際に情報を渡す方法として、
Unity側に`WWW.Form`が用意されていることです。

```C#
    //POSTする情報
    WWWForm form = new WWWForm();
    form.AddField("user_id", idInputField.text, Encoding.UTF8);
    form.AddField("password",passInputField.text, Encoding.UTF8);
```

上記のようにUnity側でログイン画面に入力したIDやパスワードをサーバーに送れる。。。はずです。

---
やりました→[【Unity(C#),Python】API通信勉強メモ③簡易版ログイン機能の実装](https://qiita.com/OKsaiyowa/items/d4a7e6a15b3366f54346)

[^1]: [フレームワークとライブラリの違い](https://qiita.com/azuki8/items/ad7710fdefaedc63e3f7)
rails db:migrateに失敗してStandardError: An error has occurred, all later migrations canceledが出た場合の対処方法


バージョン
Rails 5.0.1

rails db:migrateコマンドを実行した際に、
タイトルのエラーが出た時の対処方法メモです。

エラーはこちら

```console
# rails db:migrate
== 20191126024458 CreateDataProvisionUserStatuses: migrating ==================
-- create_table(:user_statuses)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'user_statuses' already exists: ~~~~
```

##対処方法として

テーブルが既に存在していると怒られています。
なので

```console
# rails db:reset
```

一度リセットしてから再び、

```console
# rails db:migrate
```

これで解決しました。

##参考
Rails:migrateでDBをリセットして最初からつくり直す方法。
https://qiita.com/Atsushi_/items/a230fb7f624d1eebf2f3
[PowerShell]フォーマット文字列に中かっこ(={})を出力する

# 結論
Powershellのフォーマット文字列中の中かっこは`{{`または`}}`で出力できる。

## 説明
PowerShellのフォーマット文字列については、次のリンクなどを参照ください。
[フォーマット文字列ざっくりまとめ](https://qiita.com/zaki-lknr/items/506bb446ba510e40a776)

中かっこの使用意図としては「フォーマット文字列を作成するためのフォーマット文字列の作成」ということになります。[ここ](https://qiita.com/mattn/items/ae764601862b0073071e#comment-e7dffed2ebf0e0caeedb)で使うときに調べました。

たとえば`3,1,2,4,0`という配列から`"{3}{1}{2}ー{4}ー{0}ー"`という文字列を得たいとします。

```PowerShell
"{0}{1}{2}ー{3}ー{4}ー" -f 3,1,2,4,0
```
こう書くと、結果はこうなります。

```PowerShell
"312ー4ー0ー"
```
ちゃんと配列の順序通りに数字が出力されていますね。
これを中かっこで囲いたいので、囲ってみます。

```PowerShell
"{{0}}{{1}}{{2}}ー{{3}}ー{{4}}ー" -f 3,1,2,4,0
```
結果はこうなります。

```PowerShell
"{0}{1}{2}ー{3}ー{4}ー"
```
配列の順序が全く無視されたかのようですが、これは`{{`が`{`に、`}}`が`}`にエスケープされているので、`{n}`(n=0..4)ではなく`n`として解釈されているわけです。
引数を受けるためには`n`ではなく`{n}`にする必要があります。つまり、もう一重囲います。

```PowerShell
"{{{0}}}{{{1}}}{{{2}}}ー{{{3}}}ー{{{4}}}ー" -f 3,1,2,4,0
```
結果はこうなります。

```PowerShell
"{3}{1}{2}ー{4}ー{0}ー"
```
求めたい文字列を取得することができました。

## 補足
-fを用いない通常の文字列では中かっこのエスケープの必要がないためか、エスケープされません。
`"{{"`は`"{{"`になります。`"{{" -f 0`は`"{"`になります。
PandocでMarkdownからVueのSFCを生成してみた

以前、[FAQみたいなページをmarkdownで書けるようにしていた](https://qiita.com/kira_puka/items/68732b402b2523f4ccd7)けど、
ランタイムでコンパイルするのはやっぱり重いなと思い、
軽量化の一環で前処理にしてみたときの備忘録。

事前にPandocでVueのSFCを生成すればよかった(*´ω｀*)


### インストール

```shell
$ brew install pandoc
```

### テンプレートを用意する

こんな感じのファイルを用意する。
`$body$`にmarkdownで書いたHTMLが挿入される感じ

```html
<!-- ./vue-sfc.vue-->
<template>
  <div>$body$</div>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

@Component
export default class extends Vue {}
</script>
```

### Pandocで.vueを生成する

こんなMarkdownファイル(`faq.md`)を例に。

```markdown
# よくある質問 / FAQ

## 積読本しか登録してはいけないのですか？
```

こんな感じで実行すると

```shell
$ pandoc -f markdown -t html --template=./vue-sfc.vue ./faq.md > ./FaqContent.vue
# -f ... 入力ファイルのフォーマット
# -t ... 出力のフォーマット
# --template ... テンプレートファイル
```

こんなファイルが生成されます。

```html
<!-- FaqContent.vue -->
<template>
  <div><h1>よくある質問 / FAQ</h1>
<h2>積読本しか登録してはいけないのですか？</h2><div>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

@Component
export default class extends Vue {}
</script>
```

あとは、このコンポーネント(`FaqContent.vue`)を表示するページにimportすればOK!

ランタイムでコンパイルしなくても、前処理でいけた(*´ω｀*)

#### 小ネタ

##### `npm run build`時に生成する

手動で実行するのはめんどうなので、`package.json`の`scripts`に追加した。

```json
{
  "scripts": {
    "dev": "npm run build:md && nuxt",
    "build": "npm run build:md && nuxt generate",
    "build:md": "pandoc -f markdown -t html --template=./vue-sfc.vue ./faq.md > ./FaqContent.vue",
  }
}
```

##### .md内で別のコンポーネントを使う

別のコンポーネントを使いたいときは、テンプレートに追加しておく。
今回は、[vue-tweet-embed](https://github.com/tonickkozlov/vue-tweet-embed#readme)を使いたかったので追加。

```html
<template>
  <div>$body$</div>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";
import { Tweet } from "vue-tweet-embed";

@Component({ components: { Tweet } })
export default class extends Vue {}
</script>
```

生のHTMLを表示したいときは、入力フォーマットに`+raw_html`をつけるらしい

```shell
$ pandoc -f markdown+raw_html -t html --template=./vue-sfc.vue ./faq.md > ./FaqContent.vue
```

ただ、ちゃんと変換されないことがあるので、`sed`で置換したりしてる...

```shell
$ pandoc -f markdown+raw_html -t html --template=./vue-sfc.vue ./faq.md | sed 's/&lt;Tweet/<Tweet/g' | sed 's:&gt;</Tweet>:></Tweet>:g' > ./FaqContent.vue
```

Markdownの書き方などで回避できるかもしれないけど、暫定的にこの対応。。

以上!!

## こんなのつくってます!!

積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました！
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで♪


# 参考にしたサイト様
- [Pandocの比較的簡単なインストール方法 - Qiita](https://qiita.com/sky_y/items/3c5c46ebd319490907e8#mac)
- [Pandocを使ってMarkdownを整形されたHTMLに変換する - Qiita](https://qiita.com/cawpea/items/cea1243e106ababd15e7)
- [Pandoc ユーザーズガイド 日本語版 - Japanese Pandoc User's Association](http://sky-y.github.io/site-pandoc-jp/users-guide/)
- [Pandocを使って、改行が必要な箇所にスペースを2ついれる - Qiita](https://qiita.com/tmsanrinsha/items/89df4500eb38a20e896e)
【Kotlin】KtlintのImportOrderルールの解除

## 概要
Ktlintを`com.github.shyiko:ktlint:0.22.0`から`com.pinterest:ktlint:0.35.0`に変更しました。
そうしたらデフォルトでimportorderルールがOnになったので解除しました。

## 解除方法
プロジェクトのrootに`.editorconfig`というファイルを作ります。
ここに`disabled_rules`項目を作り、解除したいルールを追加します。
今回はimport文のアルファベット順ルールを解除したいので`import-ordering`を追加します。


```vim:.editorconfig
[*.{kt,kts}]
disabled_rules=import-ordering
```

## まとめ
Ktlintのページの解除方法が分かりづらかったので、メモベースなので書き残しました。
個人的にはimport文の並び順がそこまで可読性に影響があるとは思わないので・・・
他のルールの追記や解除については、Githubのページを参照ください


## 参照ページ
[Ktlint](https://github.com/pinterest/ktlint#editorconfig)
opencvの新しい機能QRコード検出を使ってみた


## 実装環境

Mac OS Catalina 10.15.1
opencv 4.1.1
python

## 実験用のQRコード作り

どうせなら実験用のコードも自作しようということでQRコードの作り方もまとめてみます

### 作れればいい人

とはいえQRコード検出がメインテーマなのでQRコードなんかさっさと作ってしまいたいという人もいると思うのでそんな人は

[QRコード作成](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwjBoebkxonmAhXXzIsBHUk_CFsQFjAAegQIBxAB&url=https%3A%2F%2Fwww.cman.jp%2FQRcode%2F&usg=AOvVaw1yC1MJPXBzgv4lX2FH5Wv2)

ここのサイトで無料でQRコード作成できます
ファイル形式も指定してダウンロードできるのでさくっと作っちゃいましょう

### どうせならpythonで全部作りたい

僕的にはpythonでQRコードも作ってみたかったのでそちらの方もやり方をまとめてみようと思います

pythonの外部ライブラリでqrcodeというものがあるらしく今回はそれを使っていきます

```
pip install qrcode
```

いつも通りpipでインストール可能です

今回は簡単なQRコードが作れればいいのでしたのコードを実行すればいけました

```
import qrcode

img=qrcode.make("hirotoyyy.com")
img.save('QR')
```
説明するまでもないですが、一様説明しておくと

qrcode.make()の引数にQRコードを読み込んだときに表示するものを与えます

(特に表示したいものがなかったので、自分が運営してるブログのURLにしました笑 )

save()で引数に与えた名前でファイルを保存します



## QRコード検出

いよいよ QRコード検出です


```
import cv2

img = cv2.imread('QR')
qr = cv2.QRCodeDetector()
data, points, straight_qrcode = qr.detectAndDecode(img)

print('データ:', data)
print("バージョン：", ((straight_qrcode.shape[0] - 21) / 4) + 1)

```
QRコードの認識についてはQRCodeDetector()が勝手にやってくれます


## 参考にしたサイト

QRコードをpythonで作るには
https://note.nkmk.me/python-pillow-qrcode/
一人でVIPERアーキテクチャーでiOSスマホアプリ開発した感想　まとめ

ここ最近、フルスクラッチのiOSアプリ開発でVIPERアーキテクチャを使用して、開発したので、感想を書いてみます。

# はじめに

開発期間が３ヶ月ほどのiOS新規開発アプリで、Swift VIPERアーキテクチャを使用したアプリを開発しました。
途中まで、シンプルなMVCで作成していましたが、いまいちだったのでVIPERを気まぐれで採用した感じです。

**いきなり結果ですが、見通しがよく、改修しやすい、品質の高いアプリを実装出来たので、今後も新規開発で採用していこうと思ってます！**
**あとは、そろそろ誰がガチガチのiOSのフレームワークを作ってくれないかなーと**

# 参考にした資料

* [iOS Project Architecture: Using VIPER](https://cheesecakelabs.com/blog/ios-project-architecture-using-viper/)
* [iOS Project Architecture : Using VIPER [和訳]](https://qiita.com/YKEI_mrn/items/67735d8ebc9a83fffd29)
* [VIPERアーキテクチャ まとめ](https://qiita.com/hicka04/items/09534b5daffec33b2bec)
* [MindorksOpenSource/iOS-Viper-Architecture](https://github.com/MindorksOpenSource/iOS-Viper-Architecture)

# VIPERを使って特によかったところ

* 理解と導入が楽(Clean Architecture / MVVMと比べて）
* 他のアーキテクチャと比べて、良い意味で奥が深くないと思うので、気楽に導入できる<BR>（MVC、MVVMは毎回色々悩むので）
* 慣れると、流れ作業で画面を量産できる
* 適当に作っても、ルールにしたがっていればそれなりに綺麗にできる<BR>(ロジックをInteractorにぶち込む）
* 他の案件に使いまわせる実装がかなり多いイメージ
* ViewController内に、画面遷移のコードを書かなくて良いのがすごくかっこいい
* ロジック、WebAPIの仕様変更があっても、ViewControllerまで変更が入ることが少なかった

# メリット詳細

* プロジェクト構成を悩まなくて良い
* MVCで開発する速度と、慣れさえすれば変わらないと思う
* ViewControllerを徹底的に軽くできる
* APIの仕様変更時に、ViewControllerを変更しなくて良い確率が上がる
* 途中まで、MVCで作っていた物を、さほど苦戦せずにVIPERに変更できた
* MVVMとは違い、ロジックの処理をまとめやすい
* 開発が進むにつれて、開発速度をどんどん上げることが出来た
* 開発が進んでも一定の品質を簡単に保てた
* 複数人開発の時に、基準ができるので無駄な争いが起きなそう
* 各階層ごとの役割が明快なので、コードレビューもしやすいはず
* エラー表示処理や、インジゲータ表示処理などをViewControllerのExtensionにまとめると、使いまわしがすごくしやすい
* 無駄な条件分岐の実装が極端に減った
* プログラム内のネストが極端に減った
* 多分、UTもしやすいはず（そんな工数はもらってないので、やってない）


# デメリット詳細

MVCと比べて、開発速度が下がると行ったこともほとんどないので、デメリットはほとんど無しです。

* 開発の初期は、プロジェクトの構成作りに悩んでしまったので、時間を浪費した
* 当たり前だが、引き継ぎ時にアーキテクチャを相手に理解してもらう必要が出てきた
* 日本では、RxSwiftを使ったMVVMの方が流行ってるイメージ

# 悩んだところ

* 色々なサンプルをみたが、割とみんなバラバラなプロジェクト構成、作りになっている <BR>->　PHPのフレームワークのようにガチガチな規約があると考えなくて助かるのになぁと
* Interactorを使い回す時の取り回し<BR>->　DIする時にまとめて渡す方式にした
* Protocolの置き場所<BR>->　モジュールごとに1ファイルにまとめた
* View -> Presenter部分のメソッド名の付け方<BR>->　結局アクション名でつけた 例)didPushHoge, didSelectHoge

# 失敗したところ

* ViewControllerに少しロジックが乗ってしまった
* 前の画面に戻る遷移は、全RouterにInterfaceでつければよかった
* モジュールの自動作成をできるようにすれば、もっと工数を下げれた

# 次回以降、気をつけたいところ、やりたいこと

* 公開できるレベルの実際に動作するサンプルPJを作りたい
* VIPER + Rxでいい感じになるかも
* View -> Presenter部分のメソッド名の付け方を再考する
* モジュールのテンプレをコマンドで作成できるようにする
* RouterのViewController生成部分でNavigationControllerを渡したのはよくない

# おまけ（似たようなアーキテクチャ感想記事）

* [クリーンアーキテクチャーでスマホアプリ開発した感想（勉強会用）](https://qiita.com/knagauchi/items/8c9fb93520b56fd3a564)
* [iOSをMVC,MVP,MVVM,Clean Architectureで実装してみた](https://medium.com/@rockname/clean-archirecture-7be37f34c943)