OmniAICreator/Qiita-1.07M huggingface dataset:
UIPageViewControllerをEnumで管理する


実務でコードを書いてる時に、UIPageViewControllerをEnumでいい感じに書いているコードに出会ったので、
自分のための備忘録も兼ねて、ご紹介します

###実行環境
Xcode: Version 11.6

##実装

####PageViewController親の実装

PageViewControllerの親になるクラスには、Enumを使って、載せたいコンテンツを定義します
今回は例として以下のようなEnumを定義します
(Enumのコレクションの扱いを楽にする為に、CaseIterableを継承させています)
また、UIPageViewControllerはすでに宣言されていることとします(今回のサンプルはコードで宣言しています)


```BasePageViewController.swift
enum Content: CaseIterable {
    case first, second, third

    var title: String {
        switch self {
        case .first:
             return "1番目のViewController"
        case .second:
             return "2番目のViewController"
        case .third:
             return "3番目のViewController"
        }
     }

     // ここで載せたいViewControllerを定義する
     func instantiated() -> UIViewController() {
        switch self {
        case .first:
             return ContentViewController(type: self)
        case .second:
             return ContentViewController(type: self)
        case .third:
             return ContentViewController(type: self)
        }
     }
}
```

その後、このような感じでViewControllerのインスタンスを作成して、配列を作成します

```BasePageViewController.swift
private lazy var viewControllers: [UIViewController] = {
    return Content.allCases.map{ $0.instantiated() }
}()
```

あとは、それを定義してあるUIPageViewControllerに渡してあげます

```BasePageViewController.swift

// ~~~
override func viewDidLoad() {
    super.viewDidLoad()
    
    // ~~~ 省略
    // ~~~
    
    // viewDidLoadが走るタイミングで表示させるViewControllerを指定する
    pageViewController.setViewControllers([viewControllers[0]], direction: .forward, animated: true)
}
// ~~~

```

残りはUIPageViewControllerのDataSourceの実装が必要となりますが、
これだけでEnumで管理できるようになりました🤙

####PageViewController子の実装

Enumで定義した子のViewControllerでは以下のようにContentを受け取っています

```ContentViewController.swift
private let contentType: BasePageViewController.Content

init(type: BasePageViewController.Content) {
    self.contentType = type
    super.init(nibName: nil, bundle: nil)
}

// 以下受け取ったContentを使って実装
```

##完成
実際に上のコードを使って作ってみたものがこちら

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393442/8a525a1b-d285-b0ae-c06c-1d4146027e0b.gif" width="400">

##最後
Enumで管理する方法はすごく便利ですね！
CollectionViewとかもEnumで管理すれば、またいい感じに書けますよね💪

最後まで読んでいただいてありがとうございました👀
何か修正等がございましたら、なんなりとお申し付けください🙇🏻‍♂️

#### ソースコード
サンプルプロジェクトのソースコードはこちら
https://github.com/Take111/PageViewControllerSample

####参考にさせてもらった記事
・CaseIterableとは何か(https://dev.classmethod.jp/articles/wwdc18-swift-4-2-case-iterable/)
Vueの環境構築を初心者ながらしてみた

#入社研修で使ったVue.jsの環境構築をしたい
自分と彼女の写真をまとめたサイトを
作ろう！と思った笑
時間があまりないため、使ったことあるVue.jsをフロントのフレームとして採用

###詰まったところ
>・VueCliバージョン管理
Vueのバージョン確認むずかった。
vue-cliでインストールしてた。


#VueCliバージョン管理が問題
結論
**`vue-cli`**と**`@vue/cli`**のさにマジでひっかけられた。

###$ npm run dev ？？？？
サクッと検索して出てきた記事を元に環境構築をしてみたけど
サーバーを動かすところで`$ npm run dev`を入力することに。

ここで、思いっきり違和感。
研修の時は`$ npm run serve`でやったぞ。。。
何かがおかしい。。。
（あとで、package.jsonの問題らしい記事を見つけたけど。）

#バージョン確認
バージョン確認をしてみて、
VueCliが２．xx.xなバージョンになってた。
バージョンの確認方法（以外に苦戦した）

```
$ npm vue --version
```

これはnpmのバージョンが出ます。

```
$ vue --version
```
これはVue/Cliのバージョンがでます。

え、Vueのバージョンは？？？


```
👇プロジェクトごとにインストールしてる時
$ npm list vue
```

プロジェクトにVueがインストールされてないと
`└── (empty)`を返されます。


```
👇グローバルにインストールしている場合
$ npm list -g vue
```

`└─┬ @vue/cli@4.4.6`
`　 └── vue@2.6.11 `みたいな感じで返ってきます（2020/07/28現在）

#インストールすべきは@vue/cli
そして、

```
$ npm install -g vue-cli
と
$ npm install -g @vue/cli
```

の差を発見できました！
どうやらVueCli3からは`$ npm install -g @vue/cli`を使用するのが正しいようです。

公式っぽい下記のサイトには$ npm install -g vue-cliで書いてあるのでご注意を。。
https://v1-jp.vuejs.org/guide/installation.html

ちなみに、package.jsonをいじったら
$ npm run sureveできるっぽい

#プロジェクト作成

```
$ vue create [プロジェクト名]
```

聞かれることには、とりあえずエンターで応答。
うまくいくと

```
🎉  Successfully created project vue.
👉  Get started with the following commands:

 $ cd [プロジェクト名]
 $ npm run serve
```

と教えてもらえるので、それに沿って`$ npm run serve`する！
うまくいくと

```
App running at:
  - Local:   http://localhost:8080/ 
  - Network: http://192.168.2.200:8080/
```

と出るので、好きな方にアクセスして

```
Welcome to Your Vue.js App
```

を拝みましょう。
お疲れ様でした！

#参考サイト
https://qiita.com/Sinhalite/items/64731c0a84cadb516a24
https://qiita.com/BlueMountLab/items/f44c4925009c3f94565b
https://www.it-swarm-ja.tech/ja/javascript/vuejs%E3%81%AE%E3%80%8Cnpm-run-serve%E3%80%8D%E3%81%A8%E3%80%8Cnpm-run-dev%E3%80%8D%E3%81%AE%E9%81%95%E3%81%84/810503343/
RSpecの自動的にロードされるパスについて

# 要約
RSpec実行時に自動的にロードされるパスがあります。(下記の2つです)

- `./lib`
- `./spec`

Railsプロジェクトを触っていると、
そもそもRSpecの自動的にロードされるパスを気にする必要はあまりないのですが、
`Rubyのみのプロジェクト + RSpec` で動作を確認する時は知っておきたい情報ですね。

これがgem内のどこで設定されているのかを調べました。
ついでに [default_path](https://www.rubydoc.info/gems/rspec-core/RSpec%2FCore%2FConfiguration:default_path) についても記載しています。

# 対象のバージョン
- [rspec-core](https://github.com/rspec/rspec-core): `3.9.2`

# ロードの設定箇所
では、実際にgem内のどこでパスをロードしているのかを確認します。

## `$LOAD_PATH` に パスを追加するメソッド

[$LOAD_PATH](https://docs.ruby-lang.org/ja/latest/method/Kernel/v/=2dI.html) に、指定したパスを追加するメソッドは下記のファイルにあります。

```ruby:lib/rspec/core/ruby_project.rb
      def add_to_load_path(*dirs)
        dirs.each { |dir| add_dir_to_load_path(File.join(root, dir)) }
      end

      def add_dir_to_load_path(dir)
        $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir)
      end
```

- [ソースリンク](https://github.com/rspec/rspec-core/blob/d89b6920da5aa7b6b9ba48dd3b1d2454a74bfdc7/lib/rspec/core/ruby_project.rb#L8)

## `add_to_load_path` メソッドを実行している箇所

`add_to_load_path` メソッドは、下記のメソッド内で呼び出されています。
`['lib', default_path]` が `add_to_load_path`メソッドの引数になっています。

「`default_path`が指定するディレクトリ」と 「`'lib'`」が `$LOAD_PATH` に追加されることになります。

```ruby:lib/rspec/core/configuration.rb
      def requires=(paths)
        directories = ['lib', default_path].select { |p| File.directory? p }
        RSpec::Core::RubyProject.add_to_load_path(*directories)
        paths.each { |path| load_file_handling_errors(:require, path) }
        @requires += paths
      end
```

- [ソースリンク](https://github.com/rspec/rspec-core/blob/d89b6920da5aa7b6b9ba48dd3b1d2454a74bfdc7/lib/rspec/core/configuration.rb#L1565)

`default_path`の初期値は、下記の箇所で設定されています。

```ruby:lib/rspec/core/configuration.rb
        @default_path = 'spec'
```

- [ソースリンク](https://github.com/rspec/rspec-core/blob/d89b6920da5aa7b6b9ba48dd3b1d2454a74bfdc7/lib/rspec/core/configuration.rb#L528)

上記の `requires=` メソッドが、
テスト実行時、事前に呼び出されるようになっているので、
`lib` ディレクトリと `spec` ディレクトリは
`rspec` 実行時の `$LOAD_PATH` に追加されるようになっています。

# `default_path`を変更する方法

`default_path`を変更する場合はどうすればよいのでしょうか？
(必要がなければやらない方がいいとは思いますが・・・。)

例えば、テストファイルを 
`spec` ではなく `behavior` というディレクトリに置いている場合、
どうすれば `default_path`を変更できるでしょうか。


## 方法1: 実行時にオプションを渡す

テスト実行時にオプションを渡すことで、`default_path` を指定できます。

```console
$ rspec --default_path behavior
```

## 方法2: `.rspec` を修正

`.rspec` を下記のどちらかの内容に変更することで、
`default_path` を指定できます。
実行時、毎回オプションを指定したくない場合はこちらの方法がよいでしょう。

```diff:.rspec
- --require spec_helper
+ RSpec.configure do |config|
+  config.default_path = 'behavior'
+ end
```

```diff:.rspec
- --require spec_helper
+ --default_path behavior
```

- 参考リンク
  - [Class: RSpec::Core::Configuration](http://rspec.info/documentation/3.9/rspec-core/RSpec/Core/Configuration.html)


# あとがき

普段はコマンドを実行すればとりあえずテストが流れるので、
中身まで見ることはあまりないです。
調べる過程でいろんなオプションとかを知れて面白かったです。
vimにPowerShellのシンタックスハイライト（キーワードの色付け）を追加する

ほぼ自分向けのメモですが、vimmerのために、PowerShellのシンタックスハイライト（キーワードの色付け）の追加方法をメモしておきます。

追加すると、こんな感じ（↓）になります。

| <font color="Magenta">対応前</font> | <font color="Magenta">対応後</font> |
| --- | --- |
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/96d770ba-4420-9153-ce3b-6a7f56f854ae.png"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/bab253e8-3d7e-461f-c440-fcbcd4482426.png"> |





# 追加手順

## Windows10 に vim をインストール

インストール済みの人は、飛ばしてOK。

<details><summary><b>【ここをクリックして開く】Windows10 に vim をインストール</b></summary><div>
### 1. KaoriYa-vimのダウンロード

Windows向けのVimである「KaoriYa-vim」を前提とした設定方法です。
KaoriYa-vimは以下のURLからダウンロードできます。

[Kaoriya-vim](https://www.kaoriya.net/software/vim/)

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/5d6e19b5-cf37-f965-e07c-38f4c9dbc84d.png)


> Linuxでも可能だと思いますが、Linux上でPowerShellを使用することを聞いたことが無いので、とりあえずWindowsだけ解説します。



### 2. ダウンロードしたKaoriYa-vimを解凍

ダウンロードした`vim82-kaoriya-win64-8.2.1287-20200724.zip`を解凍します。

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/f4eb857c-af42-e695-7b69-e7ccb04f3820.png)



### 3. 解凍したフォルダを適当な場所に移動する

解凍したフォルダは<font color="red">自分が分かりやすい場所に保存</font>しておきます。
`vim82-kaoriya-win64-8.2.1287-20200724`の中にある`vim82-kaoriya-win64`を移動します。

ここでは例として、`vim82-kaoriya-win64`を以下のパスに移動しました。

```
C:\Program Files\vim82-kaoriya-win64
```

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/2062e31c-9878-f0e8-174b-e010a76a42a5.png)

> デスクトップ直下でもOKです。
> とにかく自分が分かりやすいところに保存すること。




### 4. 移動後のKaoriYa-vimに環境変数PATHを通す

<font color="red">PowerShell（コマンドライン上）でもvimを呼び出せるようにしたいので、環境変数Pathを設定します</font>。

1. 「コントロールパネル」→「システム」→「システムの詳細設定」を開きます。<br>（「システム」は`[Windowsキー] + [Pause/Breakキー]`で開くこともできます。）
2. 「環境変数（N）...」をクリック。
3. 「～のユーザーの環境変数（U）」→「PATH」をダブルクリック。
4. 「新規（N）」をクリック。
5. `C:\Program Files\vim82-kaoriya-win64（保存先によって異なる）`をコピペして「OK」をクリック。

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/408a9d13-5574-19bb-10f4-1321388c6f7b.png)

</div>



## シンタックスハイライトの追加

### 1. プラグインのダウンロード

以下のURLからプラグインをダウンロードします。

[ps1.vim](https://github.com/PProvost/vim-ps1)

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/f3a91bba-7c37-9905-b73d-8b31276bdb7c.png)

### 2. ダウンロードしたvim-ps1-master.zipを解凍

![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/bb2e7488-8313-0e5c-9be3-684aec50c060.png)

### 3. 解凍後のvim-ps1-master下にあるftdetectをvim82-kaoriya-win64\vim82下に移動

解凍した`vim-ps1-master`下にある`ffdetect`を`vim82-kaoriya-win64\vim82\`に丸ごと移動します。
ここでは`C:\Program Files\vim82-kaoriya-win64\vim82\`下に移動します。

![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/4fd37d89-8ffc-f601-6137-b914367eed56.png)

### 3. 最後にps1ファイルを開いて確認。

適当にps1ファイルを作って、シンタックスハイライトが効いていれば、設定完了です。

![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/9e2d6ffa-6523-0fb9-1edf-10331ca7f1ab.png)
AWS本番環境でよく使うコマンド一覧

自分のメモ用です。

#環境
Rails 5.2.4
ruby 2.5.1
capistrano 3.13.0
AWS(EC2)
Web Server Nginx
Application Server Unicorn

#Capistranoを導入後の自動デプロイの手順

###ターミナルからEC2userへログイン
```
MacBook-Pro ~ % $ cd .ssh/

# ログイン
MacBook-Pro .ssh % ssh -i app名.pem ec2-user@18.000.000.00(IPアドレス)

# リポジトリに移動
[ec2-user@ip-111-11-11-111 ~]$ cd /var/www/app名　
```
###Nginxの再起動
```
ターミナル（EC2サーバ）[ec2-user@ip-111-11-11-111 ~]
$ sudo service nginx reload
$ sudo service nginx restart
```
###MySQL起動
```　
ターミナル（EC2サーバ）[ec2-user@ip-111-11-11-111 ~]
$ sudo service mysqld start
```
###unicornのプロセスを停止(killコマンド)
```
ターミナル（EC2サーバ）[ec2-user@ip-111-11-11-111 ~]
$ pgrep -f unicorn
123456
678910
$ kill -9 123456
```
###自動デプロイ前に念のため、git pull origin master
```
ターミナル（EC2サーバ）[ec2-user@ip-111-11-11-111 ~]
$ git pull origin master
```
####git pull origin masterとは、
ローカルリポジトリの状態を追跡ブランチであるorigin/masterにコピー(git fetch)、
masterブランチの追跡ブランチ(origin/master)をローカルのmasterブランチにマージする

[ローカルリポジトリがリモートについて](https://kray.jp/blog/git-pull-rebase/)


###Capistranoによる自動デプロイ
```
ターミナル(ローカルPC)　アプリのディレクトリで下記を実行
$ bundle exec cap production deploy
```

###credentials.yml 編集方法
```
ターミナル(ローカルPC)　アプリのディレクトリで下記を実行
$ EDITOR='code --wait' rails credentials:edit

閉じれば、保存される。編集中はTerminal使用不可。
```

###mysqlをターミナルで操作
```
$ mysql -u root -p
Passward :  123456
「ユーザ名：root」で接続します、パスワードは後で聞いて という意味

#ログアウト
mysql> exit

#データベース一覧を表示
mysql> show databases;

#使用するデータベースを選択
mysql> use app名_production 

#テーブル一覧を表示
mysql> show tables;

#カラム一覧を表示
mysql> show full columns FROM [テーブル名]; 

#特定のテーブル
mysql> show index FROM [テーブル名]; 
```

###マイグレーションファイルを変更した場合の本番環境でのコマンド
```
本番環境のcurrentディレクトリで
[ec2-user@ip-111-11-11-11 current] $ git pull origin master

[ec2-user@ip-111-11-11-11 app]$

#rails db:drop
$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop

#rails db:create
$ rake db:create RAILS_ENV=production

#rails db:migrate
$ rake db:migrate RAILS_ENV=production

#rails db:seed
$ rake db:seed RAILS_ENV=production

```
###本番環境のエラー解決
・currentディレクトリでproduction.logの確認

```
[ec2-user@ip-111-11-11-111 ~]$　ec2サーバーにログイン
$ cd /var/www/app名/current/
$ cd log/
$ tailf production.log

#ログアウト
$ exit
```

###本番環境で写真が反映されない写真保存先の確認
```
$cd app/assets/
$cd images/
```

###環境変数を定義
```
・本番環境やローカル環境は ~/.bash_profileへ記述
$ vim ~/.bash_profile


・Capistranoを使用し自動デプロイを行う場合、環境変数は/.etc/environmentmに記述
$ vim ~/.etc/environment
$ sudo vi /etc/environment
```
[viコマンド（vimコマンド）リファレンス](https://qiita.com/pe-ta/items/0510bee10bcfd88afeee)

###本番環境のエラー表示
config/environments/production.rb

```
config.consider_all_requests_local = false
↓
config.consider_all_requests_local = true
```
【c言語＋DXライブラリ】構造体を引数として渡す

<!-- wp:paragraph -->
<p>　C言語の勉強としてシューティングゲームを作っていく中で知りました。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>　構造体を引数として渡すことの何が嬉しいのかと、その使い方を書き残しておきます。</p>
<!-- /wp:paragraph -->

#構造体を引数として渡せると何が嬉しいのか
<!-- wp:paragraph -->
<p>　簡潔になるところです。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>　構造体を作らずに書いたプログラムと、構造体を書いたプログラムを比較すると、構造体を書かないプログラムはめちゃくちゃ長いうえに、読みにくいです。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>構造体なら<span class="marker-under-red">読みやすく</span>、一つ一つ指定しなくて済むため<span class="marker-under-red">訂正も簡単</span>です。<span class="marker-under-red">新しい要素を足すときも簡単</span>で、shoot4をすべて作る、なんてことをせずになくて済みます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>構造体にしてしまえば自分の手間も省け、それを読む相手の負担も避けられます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>プログラムを貼っておきます。まずは構造体を用いないで書くと…</p>
<!-- /wp:paragraph -->
```notkouzou.c
//変数宣言(新しい変数のたびに要素をすべて宣言)
int Shoot1_graph = …;
int Shoot1_x;
int Shoot1_y;
int Shoot1_flag;

int Shoot2_graph = …;
int Shoot2_x;
int Shoot2_y;
int Shoot2_flag;

int Shoot3_graph = …;
int Shoot3_x;
int Shoot3_y;
int Shoot3_flag;

int Shoot4_graph = …;
int Shoot4_x;
int Shoot4_y;
int Shoot4_flag;

//この先が引数

int spaceKey(int Shoot1_graph = …,int Shoot1_x,int Shoot1_y,int Shoot1_flag){
//略

```
きゃー！
以下、構造体を用いたコードです。

```kouzou.c
//構造体宣言
struct Shoot {
	int graph;
	int x;
	int y;
	int flag;
};

//構造体に名前をつける(いくつでも可)
Shoot myshoot[] = { { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 }}

//この先が引数

int spaceKey(Shoot* myshoot1, Shoot* myshoot2, Shoot* myshoot3) {
}
```

わ、なんかいい！
#構造体を引数として渡す方法
プログラム例を貼ります。

```sample.c
//①
struct Player {
	int graph;
	int x;
	int y;
	int damage;
};

//②
int move(Player *po);

int main(void){
    //③
    Player po = { LoadGraph("xx.png") , 300, 300, 4 };

    //④
    move(&po);
}

//⑤
int move(Player *po) {
//処理
	return 0;
}
```

<!-- wp:paragraph -->
<p>①構造体を宣言します。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>②関数を宣言します(moveとする)。「*po」と書くことで「po<strong>構造体の<span class="marker-under-red">アドレスを</span>引数として受け取るmove関数があるよ</strong>」と宣言しています。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>③構造体の名前を決め(poとする)、要素を指定します。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>④move関数を呼び出します。ここで、「&amp;po」とすることで、move関数にpo<strong>構造体の<span class="marker-under-red">アドレスを</span>渡します</strong>。(<span class="bold-red">*poではありません</span>)</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>⑤move関数が「*po」でpo構造体のアドレスをもらい、move関数の処理を書きます。この関数内で、構造体の中身は全て使用できます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<h1>！注意！</h1>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>move関数の中では、Player.xは使えません。Player-&gt;xとして使います。(詳しくはアロー演算子で検索)</p>
<!-- /wp:paragraph -->

#まとめ
<!-- wp:paragraph -->
<p>　構造体を、ポインタを使用して引数として渡すことを「参照渡し」と呼ぶそうです。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>　先輩にプログラムを見てもらう機会が一度だけあり、その時に「参照渡しできるんだ」と言われた時「参照渡してなんですか？」と返して呆れられました。単語大事。</p>
<!-- /wp:paragraph -->
VSCodeのRemote WSLからIntegrated Terminalを起動すると.bashrcも.bash_profileも読まれない件

# TL;DR

表題の通りだったが、以下の2点を実施したら読まれるようになった。
1. `Settings`の`Terminal > Integrated > Shell Args: Linux`に`-l`を追加し、ログインシェルとして起動するようにする
2. `.bash_profile`の先頭に以下を書き、`.bashrc`が読まれるようにする

```
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
```

# バージョン

## OS

Windows 10 Pro 1809

(諸事情によりかなり古い）

## WSL

多分1

## WSL上のOS

Ubuntu 18.04.4 LTS

## VSCode

1.44.2
Burp Suiteの拡張機能の作り方メモ

(ほぼ)日課のQiita記事の投稿です。
毎日書くの結構難しいから、今後平日は興味のある情報のURLまとめるとかの方がいいかも･･･

とりあえず今回は、Burp Suiteの拡張機能を作成し始めた頃に調べた情報をまとめました。
Burpのインストールや使用方法については割愛します。

今回は以下を参考にさせていただきました。

* [SSTtechlog 09 Burp拡張の作成に挑戦！ | SST 株式会社セキュアスカイ・テクノロジー](https://www.securesky-tech.com/column/techlog/09.html)
* [Burp Suite拡張を作ろう | MBSD Blog](https://www.mbsd.jp/blog/20160914.html)
* [Burp Suite拡張プラグイン作成入門 その１ - Hello world編 - まったり技術ブログ](https://blog.motikan2010.com/entry/2018/02/11/Burp_Suite%E3%81%AE%E6%8B%A1%E5%BC%B5%E3%82%92%E4%BD%9C%E6%88%90%E5%85%A5%E9%96%80_%E3%81%9D%E3%81%AE%EF%BC%91_-_Hello_world%E7%B7%A8)

## Burpの拡張機能の作り方

1. Burpからインターフェイス用のソースを取得し、作成する拡張機能に組み込む。
(“Extender” -> “APIs” -> “Save interface files”)
2. burp.BurpExtender という名のクラスを、以下のように作る。
 - パッケージが burp に属している
 - クラス名が BurpExtender
 - インターフェース IBurpExtender を実装

3. 実装した IBurpExtenderインターフェイスの registerExtenderCallbacks()メソッドの中に実際に実行したいコードを書いていく

```java:BurpExtender.java
package burp;

public class BurpExtender implements IBurpExtender {

    public void registerExtenderCallbacks(IBurpExtenderCallbacks iBurpExtenderCallbacks) {
        // ここに実際に実行されるコードを書いていく
    }
}
```

## 作成できる機能の一部

- I(Proxy|Http|Scanner)Listener API
  ProxyなどのHTTP通信やScannerで検出した問題を取得

- IContextMenu～, IMenuItemHandler API
右クリックメニューを拡張

- IMessageEditor～ API
HTTPの編集画面をカスタマイズ

- IIntruderPayload～ API
Intruderで使うペイロード生成

他の機能など、詳しくは以下を参考にしてください。

* APIドキュメント：[Generated Documentation (Untitled)](https://portswigger.net/burp/extender/api/)
* APIのインターフェイスのソースコード：[GitHub - PortSwigger/burp-extender-api: Burp Extender API](https://github.com/PortSwigger/burp-extender-api)

## 拡張機能の読み込み

- Extender > Extensions > Add
- Select file... から、追加したい拡張機能のjarファイルを選択する
- Errorタブに何も表示されていなければ、エラーなく読み込み成功

## メモ

- BurpのUIはLatin-1(ISO8859-1)が使われているようです。文字化けが面倒ですなぁ･･･
[Go言語] 初心者必見シリーズ: マップ（Map）

# マップ（Map）

Golangではハッシュテーブル（hash table）のことを `map` と呼びます。

**キーと値の組**を複数個格納し、キーに対応する値をすばやく参照するためのデータ構造です。

![golang-map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170309/c68cc7cb-b8ad-c6b3-f416-000550a99277.png)


## 定義方法

### 方法1

* 構文

  ```go
  変数名 := map[型]型{初期値1, ..., 初期値n}
  ```

* 例

  ```go
  languages := map[string]string{
      "go":"golang", 
      "rb":"ruby", 
      "js":"javascript",
  }
  ```

### 方法2

* 構文

  ```go
  変数名 := make(map[型]型, 容量)
  ```

* 例

  ```go
  languages := make(map[string]string)
  languages["go"] = "golang"
  languages["rb"] = "ruby"
  languages["js"] = "javascript"
  ```

## 要素の挿入と更新

* 要素の挿入や更新: 

  ```go
  languages := map[string]string{}
  languages["go"] = "golang" // "go"キーが存在する場合は、valueが "golang" に更新され、
  							 //  存在しない場合は、("go", "golang") という Key-ValueのペアがMapに挿入される。	
  ```

* 要素の取得:

  ```go
   elem, ok := languages["go"] // "go"キーが存在する場合は、 ok == true
                               //          存在しない場合は、ok == false
  ```
  ![golang-find.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170309/6a167d0e-3944-0521-5fc8-77a8a0ce483f.png)


## 要素の走査 (iteration) 

* `range` でMapを走査できる。

  ```go
  for key, value := range languages{
    ...
  }
  ```

  > 注意： GoのMapのiterationは、
  >
  > 　　　**要素がランダムに取得**されるため、実行するたびに異なる結果になります。



## 要素の衝突

複数の異なるキーが同じバケットに入ることを**衝突**（collision）と呼びます。

GoのMapは衝突を起こしたキー同士をポインターでつなぎます。（**連鎖法**）

![golang-collision.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170309/95720560-7932-1927-04d5-b657f8af539e.png)

# 動画

https://www.youtube.com/watch?v=HQuIjHZqNxI

# 元記事
https://aifan.jp/2020/07/28/Go%E8%A8%80%E8%AA%9E-%E5%88%9D%E5%BF%83%E8%80%85%E5%BF%85%E8%A6%8B%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%83%9E%E3%83%83%E3%83%97%EF%BC%88Map%EF%BC%89/
PHPデバッグが捗るTips

# この記事について
PHPのデバッグで「var_dump($test);exit;」しかしない人のために
手動デバッグで役に立ったことをまとめてみました。

# デバッグおすすめリスト
| やりたいこと | デバッグ方法 | 役立つ度|
|:--|:--|:--|
| 配列をコピペで変数代入できる状態で出力する | 「var_dump()」ではなく「var_export()」を使用する |★★☆|
| var_dumpの「string(5)」みたいな出力をなくす | 「print_r()」で出力する |★☆☆|
| 関数の呼び出し元の関数を特定する | `echo debug_backtrace()[1]['function'];` |★★★|
| 呼び出し元のクラス名を特定する | `echo debug_backtrace()[1]['class'];`|★★★|
| ログを指定したファイルに出力する | error_logの第2引数に「3」<br>第3引数に出力させたいログパスを記載する<br>error_log($message, 3, '/var/log/php/test_log'); | ★★★ |
|var_dumpした値の文字化けを解消|chromeのテキストエンコーディングを入れる<br>https://chrome.google.com/webstore/detail/set-character-encoding/bpojelgakakmcfmjfilgdlmhefphglae?hl=ja<br><br>もしくは<br>`header('Content-Type: text/html; charset=UTF-8');<br>var_dump(配列);`|★☆☆ |
|var_dump()を見やすく出力する|`echo '<pre>';var_dump($array);`|★★★|
|MySQLのエラーを表示する|`echo mysql_error();`|★☆☆|
|「echo 111;exit;」を簡潔に書く(Laravel/CakePHPの場合)|dd(111);|★★☆|
golangのユニットテストにおけるprivateとpublic

春の終わりからgolang修行中の身。
趣味以外ではproductionのgolangコードをまだいじったことのない、ひよっこの考察を残してみる。

## golangにおけるprivate / publicの理解
関数名や変数名・定数名の先頭を大文字にすることで別packageから参照可能になるいわゆるpublicな状態が `exported`、
反対に先頭を小文字にして同一package内のみ参照が可能になるいわゆるprivateな状態が `unexported` と理解している。

参考：https://tour.golang.org/basics/3

## testpackageとの出会い

書きかけのアプリケーションに、Linter（golangci-lint）をいれたところ、以下のような指摘に遭遇。

```shell
$ golangci-lint run ./... 
/usecase/hoge_test.go:1:9: package should be `usecase_test` instead of `usecase` (testpackage)
package usecase
        ^
```

`testpackage` にて、テストのpackage指定は `_test` をつけるように言われている模様。

golangのユニットテストは、テスト対象コードと同一ディレクトリ内に配置するのがお作法で、
packageを同じにすることで `unexported` なテストも書きやすいのが良いなと思っていた矢先だったのでちょっともにょる。

## unexportedなテストの考慮

識者からの助言で、レポジトリの説明にexported/unexported的な話があるということで見てみる。
ちゃんとドキュメントを読もう。
https://github.com/maratori/testpackage

> The linter reports if a test is in a package without suffix _test. If you really need to test unexported function, then put the test into file XXX_internal_test.go. The linter skips such files by default. It also skips the file export_test.go by default (see the last article below).

どうやら、unexportedなテストでもにょることは見通されており、
`XXX_internal_test.go` のファイル名に従うことで、unexportedなテストはlint対象から除外されるようになっている。

~~また、以下のように同一package内でexportしてテストをおこなう `XXX_export_test.go` の場合も同様に除外される。~~
後ほどわかったがこの記法でpackage内のself importはできず、そもそもself import自体が不可だったため解釈誤っている可能性あり（2020/8/4追記）

```golang:hoge_test.go
package hoge

// export test
var Hoge = hoge
```
参考：https://medium.com/@robiplus/golang-trick-export-for-test-aa16cbd7b8cd

除外するファイル名の定義は自分で指定することも可能になっている。

## exportedとunexportedなテストの使い分け
いまのところサンプルレベルの自身のコードでは、ユニットテストはexportedとunexportedを意識せずに同一package内で記述している。

testpackageの想定に従うこともできるが、

* テストは対象コードと同一ディレクトリ内に `xxx_test.go` として1つだけ配置する
* unexportedなテストはpackage内参照でそのまま書く
* ~~exportedなテストは一度変数に入れてから、変数経由でpackage外参照を想定して書く~~
    * 上述のコメントの通りself importは不可のため想定しているやり方はできず、結果的に `xxx_test_go` （package別にしてexported想定） `xxx_internal_text.go` （同一packageでunexported想定）としているのが今（2020/8/4追記）

が自分には合っていそうと感じた。

想定に従って例えば

* `hoge_test.go`
    * → packageは `xxx_test`
* `hoge_internal_test.go`
    * → packageは 対象コードと同じ`xxx` 

のように分けるとすると、
~~同一ディレクトリ内で対象コードよりテストコードが増えてしまうのがなんとなく見通し悪くなりそうなのと、
別packageにするのであれば、並列に配置する意図が薄れるためtestをまとめた別ディレクトリをつくってそちらで書くことも検討したくなってくる。~~
と考えていたが、今は分けるのがベターという見解。ただしディレクトリの見通しは落ちており、exportedなテストは別ディレクトリでもいいのでは？はキープ（2020/8/4追記）

いざ複雑なロジックを含むコードを書き出すとまた考え方が変わってくる可能性もあるが、現時点では[golangci-lint自体の開発でもdisabledになっているよう](https://github.com/golangci/golangci-lint/blob/b98fda6f34d6648156b25f0ddf7a016a3c924df9/.golangci.yml#L119)だし、今日のところは自分のコードでもdisabledにさせてもらおう。

いやでもすぐに気が変わるかもしれないから、一旦コメントアウトで。

```yaml:.golangci.yml
# - testpackage
```
プログラミング初心者がUnityでゲームをつくってみる　その（3）

こんにちは！お母さんです。
今日もUnityを頑張っていきます。昨日は緑色の芝生のグランドが完成しました。
今日は、カメラの位置を変えて、グランドの周りに壁を作っていきます。

まずは、カメラの位置です。白い小さな雲のような形のものが中央左よりにありますが、これがカメラみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/55b2eb47-a826-9f96-1602-0b6b7ace2b05.png)

これをクリックする、または「hierarchy」→「Main　camera」をクリックするとカメラが操作できます。左上のツールからでも操作できますが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/2d5e4377-7291-05e0-2b32-363ff73ad182.png)

「Transform」に値を入力しても操作できます。
「position」のYを20に、「Rocation」のXを90にすると、
緑のグランドを真上から見た図になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/e1530fde-2654-e271-74f5-2bbec1ef83a9.png)

次はこのグランドに壁を作ります。
「Hierarchy」→「3Dobject」→「Cube」で、また□を作ったら、細長くします。
グランドの大きさは、20×20。
ここに、幅20、厚さ1高さ1の壁を上端に作ります。
まず一つ目（上の部分）→wall1
「position」は　0、1、9.5
「Scale」は　　1、1、20
同じようにして、cubeを作り、両端の壁を作ります。
二つ目（右端）→wall2 
「position」9.5、1、0
「scale」1、1、20
三つ目（左端）→wall3
「position」－9.5、1、0
「scale」　1、1、0


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/1fb350de-14e3-8b5b-1223-9f1e30a88966.png)
これで、3方向の壁ができました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/5c18a92a-139c-2a5b-b005-1512f38b8de2.png)
次に！このグランドの中で動かすボールを作ります。
ボールは、「Hierarchy」→「3Dobject」→「sphere」で作ることができます。
最初の状態では、床に埋まった状態なので、
「Transform」→「position」を、0、10、0に変えます。
これでボールが床の上にきました。早く動かしたいなあ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/f61dbe51-7885-2c47-b4b3-cb9b1ef2d15c.png)

次に、一番右下にある、「Addcomponents」をクリックして、🔍マークから、「Rigidbody」と入れて検索し、キリックします。これで、「Rigidbodyコンポ－ネンツ」が追加されました。
こうすることで、ボールが物理法則に従って動くそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/fa400bee-84e5-7428-6259-3a1371de97b5.png)
早速実行ボタンを押して、動きを確認してみます。実行は、上部真ん中にある▶マークです。
まだ、ボールがポーンと落ちるだけですが、動くことが分かりました。
ここまできたら、もっとボールを動かしてみたいですね！
ここからは、スクリプトを書いてボールを動かすそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296644/143b59c4-d661-9b37-efd2-204ef8472f87.png)

続きは、また明日！
[Flutter]AndroidでTextFieldがキーボードで隠れてしまうときの対処方法

## 起きたこと
Android向けにビルドしたアプリで、TextField、TextFormFieldをタップすると、テキストフィールドがキーボードで隠れる現象に遭遇しました。(iOS版では問題なし)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/774b5aaa-e922-8bd1-656c-7566eb078ba8.png)

## 対処方法

`android/app/src/main/res/values/styles.xml` で `<item name="android:windowFullscreen">true</item>` を `<item name="android:windowFullscreen">false</item>` に変更すると解決します。

## 参考
[Flutter keyboard hides textfield in android but working fine in iOS · Issue #54816 · flutter/flutter · GitHub](https://github.com/flutter/flutter/issues/54816)
【bash 便利ショートカット】『esc ＋ .(ドット)』直前の引数を再利用しよう



## bash 便利ショートカット

####直前に実行したコマンドの引数を再利用することができる

``esc`` ＋ ``.(ドット)``



```
$ ls hoge/fuga.txt

$ cat ←【esc＋.】

$ cat hoge/fuga.txt ← 補完される
```

#こんな時に便利

```
$ tail -f laravel-2020-07-27.log

$ less ←【esc＋.】

$ less laravel-2020-07-27.log ← 補完される
```


引数が長すぎて打つの面倒くさい時に、大変便利です。
nuxt.js × firebase で画像保存処理実装してみた

 
## 使うもの

- nuxt.js
- firebase storage

## 今回実装するもの

- ローカルフォルダから画像を選択してfirebaseのstorageに保存する処理
- firebaseのstorageからデータを取得して画面上に表示する処理

## コード

### 画像をfirebaseのstorageに保存

```htmlmixed=
<!-- 画像を選択 -->
<input type="file" @change="selectIcon">
```

```javascript=
selectIcon (e) {
    // 選択した画像ファイルを取得
    const file = e.target.files[0]
    // refの中身が保存する場所のpathになる
    const storageRef = firebase.storage().ref('images/sample.jpg')
    storageRef.put(file)
}
```

### firebaseのstorageからデータを取得して画面上に表示

```htmlmixed=
<!-- ここに表示する -->
<img :src="icon">
```

```javascript=
data () {
    return {
        icon: ''
    }
},
methods: {
    async setIcon () {
        const storageRef = firebase.storage().ref()
        // childの中身にパスを指定してurlを取得する
        const url = await storageRef.child('images/sample.jpg').getDownloadURL()
        this.icon = url
    }
}
```

## おまけ（画像選択してその場で表示する方法）

```htmlmixed=
<img :src="icon">
<input type="file" @change="selectIcon">
```

```javascript=
data () {
    return {
        icon: ''
    }
},
methods: {
    selectIcon (e) {
        const file = e.target.files[0]
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = (e) => {
            this.icon = e.target.result
        }
    }
}
```
Spring Boot + Springfox springfox-boot-starter 3.0.0つかう

https://github.com/springfox/springfox をつかう。

```gradle:build.gradle
plugins {
  id 'org.springframework.boot' version '2.3.2.RELEASE'
  id 'io.spring.dependency-management' version '1.0.9.RELEASE'
  id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
  mavenCentral()
}
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  }
  // https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter
  implementation 'io.springfox:springfox-boot-starter:3.0.0'
}
test {
  useJUnitPlatform()
}

```

```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class MainApp {
	@GetMapping("/hoge")
	public String hoge() {
		return "hoge";
	}
	
	public static void main(String[] args) {
		SpringApplication.run(MainApp.class, args);
	}
}
```

これで起動して http://localhost:8080/swagger-ui/index.html にアクセスすると以下の画面が表示される。2.0以前とは異なりauto-configがあるのでswagger用のjava-configを作る必要がない。

![swagger333.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/19ee3abb-95f4-fb07-b771-98f5668e0584.jpeg)
【Swift】テーブルビューのスクロールを滑らかにする方法【KingFisher】

Qiita初投稿です！
iOSアプリ開発をしていると、UITableViewをかなり高頻度で使います。
今日はこのUITableViewを、より滑らかにスクロールできるように改善する方法を紹介します。

##画像のキャッシュで滑らかに
スクロールがガクつく原因は色々考えられますが、セルに表示する画像のダウンロードに時間がかかって処理が重くなっているケースが多いです。

今回、同じ様に画像表示でアプリが重くなってしまった際に[KingFisher](https://github.com/onevcat/Kingfisher)というライブラリを使うことで、超簡単に画像をキャッシュしてサクサク動くようになりました。
UITableViewなどのアプリ内で、複数の画像を使う方にはオススメのライブラリです。

##インストール
Cocoapodsを使いました。
`pod 'Kingfisher'`とPodfileに入れてinstallします。

##使い方

```swift:ViewController.swift
let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)
```

上記のコードで画像のキャッシュを行うことができ、アプリがサクサク動くようになりました。

画像を初めて表示する際はURLからダウンロード、それ以降はキャッシュから表示するのでダウンロードを待たずに表示することが可能になります。

##まとめ
画像のキャッシュと聞くとかなりハードな実装のイメージがありましたが、実際に行ってみると便利なライブラリもあり、短時間で行うことができました。

テーブルビューが滑らかに動かないと悩んでいる方は是非参考にしてみて下さい。

##参考
https://github.com/onevcat/Kingfisher
【初心者でもわかる】cssで使えるショートハンドの書き方と、ショートハンドかロングハンドのどちらを使うべきかについての考察

# どうも7noteです。ショートハンドの書き方と使い分け方について書いていきます。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/discussion/shorthand/
Rails form_for フォームコントロール

### 使い方

### メソッド
f.textfield :インスタンスのカラム名

### form_forのプチ情報
- form_forの送信先URLとHTTPメソッドはインスタンスに応じて変わる。
- form_forを経て送信されたパラメーターは、paramsのそのモデル名をキーとする値に、ハッシュとして定義されている。
HTMLの基本的なタグ

#HTMLの基本的なタグについて
HTMLのタグは様々な種類があり、それによって文字の役割が変わってくるので非常に重要なものである。
タグは基本、<>（開始タグ）や</>（終了タグ）を用いて書いていく。

##htmlタグ
htmlタグは、HTMLで書くコード全てを囲むタグである。開始タグは一番上、終了タグは一番下に書く。この中に様々なhtmlのコードを書いていく。

##headタグ
headタグは、doctype宣言やmetaタグなど、読者の目には見えない情報をこの中に記述するタグである。

##metaタグ
metaタグ、は製作者や日付、キーワードなどを記述するタグである。このタグには終了タグはなく、開始タグの中に書き込んでいく必要がある。

##linkタグ
linkタグは、外部のサイトやCSSなどを読み込むときに使うタグである。こちらも,metaタグ同様に終了タグがない。

##bodyタグ
bodyタグは、読者が読む内容を記述していくタグである。bodyタグからCSSを適用していく。

##headerタグ
headerタグは、ロゴやホームページ内の構造などを書き記すときに使うある。headerをクリックすると一番上に戻るなどの役割を持たせる。

##footerタグ
footerタグはページの一番したに置いておくものを書くときに使うタグである。

##divタグ
divタグは、一つのまとまりを作る時に使うであり、タグ自体に意味は持たない。

##h1〜６タグ
H1〜６タグは、見出しに使うタグ。番号が大きくなるにつれて見出しの大きさも小さくなっていく。

##pタグ
pタグは、説明文など文章を書く時に用いるタグである。

##imgタグ
imgタグは、画像などを表示させる時に使うタグ。srcに続けて画像のurlを指定する。こちらも終了タグがない。

##aタグ
aタグは、他のサイトのリンクを貼るときやページ内の別の場所に飛ばしたい時に用いるタグである。hrefに続けてリンクを貼る。

##liタグ
liタグはリストなどを作成する時に用いる。主にulタグで囲って使用する。

###他にも様々なタグがあるので使いながら覚えておくといい。
これからも学習次第、Qiitaにまとめて行けたらと思う。
RSpecのCapybaraを使ったシステムスペックで`NotImplementedError`が出たときの対処法

システムスペックを書いている際にCapybaraのsend_keysメソッドを使おうとしたら、
`NotImplementedError`が発生し、解決に時間がかかってしまったので、対処法を備忘録として記載します。

結論から言うと、**RSpecでJavaScriptを使う設定をし忘れていたことが原因**でした。

## エラーの発生
下記のテスト実行時に、`NotImplementedError`が発生しました。

```
Failures:

  1) Messages can display messages in real time
     Failure/Error: find('#message').send_keys(:enter)
     
     NotImplementedError:
       NotImplementedError
```

発生箇所はsend_keysメソッドのようです。

```spec/systems/messages_spec.rb
require 'rails_helper'

RSpec.describe 'Messages', type: :system do
  # 略
  it 'can display messages in real time', js: true do
    log_in(user)
    visit room_path(room)
    message = 'Hello'
    expect{
      fill_in 'Write a message', with: message
      # send_keysメソッドでエラー発生
      find('#message').send_keys(:enter)
    }.to change(Message, :count).by(1)
    expect(page).to have_content message
  end
```

## 対処法

1 JSのドライバの設定を追加する

```spec/support/capybara.rb
RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end
  # 追記
  config.before(:each, type: :system, js: true) do
    driven_by :selenium_chrome_headless
  end
end
```

2 スペックでJSを有効にする

```spec/support/capybara.rb
require 'rails_helper'

RSpec.describe 'Messages', type: :system do
  # 略
  # js: true を追記
  it 'can display messages in real time', js: true do
    log_in(user)
    visit room_path(room)
    message = 'Hello'
    expect{
      fill_in 'Write a message', with: message
      find('#message').send_keys(:enter)
    }.to change(Message, :count).by(1)
    expect(page).to have_content message
  end
```

## 参考
- [RSpecコトハジメ ~初期設定マニュアル~](https://qiita.com/naoki_mochizuki/items/1d3026a32786642fc762)
[jQuery] 基本の「き」

今日はjQueryに関してまとめたいと思います。

相当今更ですが、日々なんとなく使っているのでまとめました。（まとめていきます）

# jQueryとは

>jQuery（ジェイクエリー）は、ウェブブラウザ用のJavaScriptコードをより容易に記述できるようにするために設計されたJavaScriptライブラリである。ジョン・レシグが、2006年1月に開催された BarCamp NYC でリリースした。様々な場面で活用されており、JavaScriptライブラリのデファクトスタンダードと呼ぶ者もいる。ロゴの下に表記されているキャッチコピーは「write less, do more」（「少ない記述で、もっと多くのことをする」の意）。

write less, do more ..理想的！　日々 write more, doing less な私とは正反対です。

## サイト
jQueryのオフィシャルサイトは下記
https://jquery.com/

# 基本

基本こんな構文です。

```javascript
$("button.continue").html("Next Step...");
```

`$`がjQueryオブジェクト認識キャラクターですね。jQueryは（ほぼ）いつも`$`から始まります。

## ドキュメントがロードしたら関数を呼ぶ

ドキュメントがロードしたら関数を呼ぶときはこんな感じです。

```javascript

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

```

もっと簡単に、こんな風にも表現できます

```javascript
// Shorthand for $( document ).ready()
$(function() {
    console.log( "ready!" );
});
```
EC2インスタンス作成が2回目以降の場合の手順

#無料使用期間について
アカウント作成から12ヶ月間、以下のアプリケーションは無料で利用できます。12ヶ月間の無料期間を過ぎた後、課金が開始されます。
また、12ヶ月以内でも使用量が無料利用枠を超えた場合、料金がかかるので注意が必要です。
 カリキュラム内で使用したサービスの無料枠は以下の通りです。
○Amazon EC2
　・750時間/月 (t2.microインスタンスの使用もこれに含む)まで
○Amazon S3:
　・5GBの標準ストレージ、20,000件のGETリクエスト、2,000件のPUTリクエスト
○Elastic IPアドレス
　・実行中のインスタンスに関連づけられたElastic IPアドレスを1つだけ
　・インスタンスに紐付いていないElastic IPアドレスは全て課金対象
○IAM
　・IAMユーザーの一時的なセキュリティ認証情報を使用して他のAWSサービスにアクセスするときのみ料金が発生

#2つ目以降のインスタンスを立ち上げる際に踏む手順
1 Elastic IPアドレスを解放する
2 （すでに作成済みで、これ以上必要の無い場合）紐付いているS3バケットを削除する
3 インスタンスを削除する
4 新たなインスタンス立ち上げを行う

#1.Elastic IPアドレスを解放しよう
Elastic IPアドレスは、停止しているインスタンスに関連づけられている場合に時間ごとに料金が発生します。そのため、インスタンスを停止するときにElastic IPアドレスを解放する必要があります。

1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。 

2. ナビゲーションペインで [Elastic IP] を選択します。 

3. Elastic IP アドレスを選択し、[Actions]、[Release addresses] の順に選択します。プロンプトが表示されたら、[Release] を選択します。

参考URL:[Elastic IPアドレスを解放する方法](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-releasing) 

#2.S3バケットを削除しよう
今後、使用予定のない不要なバケットである場合、以下の手順で削除することができます。(ただし、同じバケット名を別のサービス等で使いたい場合は、バケットの中身を空にするようにしてください。)

1. AWS マネジメントコンソール にサインインし、Amazon S3 コンソール (https://console.aws.amazon.com/s3/) を開きます。 

2. [バケット名] リストで、削除するバケットの名前の横にあるバケットアイコンを選択し、[バケットを削除する] を選択します。

3. [バケットを削除する] ダイアログボックスで、削除するバケットの名前を確認のために入力し、[確認] を選択します。

参考URL: [S3バケットを削除する方法](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/delete-bucket.html) 

#3.EC2インスタンスを停止させましょう
インスタンスを停止するとEIastic IPアドレスは関連づけられなくなるので、あらかじめEIastic IPアドレスを解放し課金されないように気をつけましょう。

1. ナビゲーションペインで [Instances] を選択し、インスタンスを選択します。 

2. [Actions] を選択して [Instance State] を選択し、[Stop] を選択します。
[Stop] が無効になっている場合は、インスタンスが既に停止しているか、またはルートボリュームがインスタンスストアボリュームです。（インスタンスを停止すると、インスタンスストアボリューム上のデータは消去されます。インスタンスストアボリュームのデータを保持するには、このデータを永続的ストレージに必ずバックアップしてください。） 

3. 確認ダイアログボックスで [Yes, Stop] を選択します。
※インスタンスが停止するまで、数分かかる場合があります。

参考URL： [インスタンスの停止と起動](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/Stop_Start.html)

#最後に

###費用はこまめに確認する
発生している料金については、AWSの請求ダッシュボードからいつでも確認することができます。気になる場合は、こまめに確認するようにしましょう。

###インスタンスを複数作成して課金されたとしたらいくら位になるのか
もしインスタンスの停止やElastic IPアドレスの解放を失念した状態で複数のインスタンスを作成した場合、状況によりますが500~3000円程度の費用が発生します。もちろん状況によっては数万円程度に達することもありますが、多くの場合法外な費用が発生するわけではないので、落ち着いて対応しましょう。

###法外な課金がされる場合
awsのアクセスキーをgithubにpushした際などに、不正に利用されて数十万円の課金がされることがあります。基本的にTECH::EXPERTのカリキュラムのみに沿って進めて頂いた場合はその可能性はありません。一方、Webで検索して見つけた記事などを参考にし、デプロイ作業等を進める場合は注意してください。

###不明な課金がされている場合
その他にも数十円の料金が発生していたり、不明な料金が発生していることがあったら以下のような対応を取りましょう。
　・AWSのカスタマーサポートに問い合わせてみる
　・解決しない場合は、AWSのアカウントごと消去する

###高度な設定
費用発生を最小限に留めるために、EC2を自動でシャットダウンされるように設定したり、無料利用枠を超えないようにS3でオブジェクトの有効期限を設定できたりします。以下のリンクを参考にしてください。 

[無駄なコストを省こう！AWSで消し忘れを防止するためにチェックすべき７つのポイント](https://dev.classmethod.jp/articles/cost-check-point/)

AWSのようなクラウドコンピューティングサービスはこれからも広く使われて行くものです。エンジニアになった後も、頻繁に使用することでしょう。正しく使えば適正な費用しか発生しませんので、ぜひしっかりと調査を行いつつ、様々なチャレンジをしてみてください！
Juliaでのデータの保存と読み込み：HDF5を使ってみる

Juliaでのデータの読み込み、皆様はどうされていますか？
今回は、HDF5フォーマットでの読み書きについて記します。便利です。
HDF5とは
Hierarchical Data Format 5
の略だそうです。高速に読み書きができるそうです。
では、Juliaで使ってみましょう。
JuliaでのHDF5.jlの良い点は、型について気にせずにデータの読み書きができることです。
テキストデータだといちいちstring型として読み込んでparseをしたりする必要がありますから、その部分を省けるのは便利です。

# 環境
- Julia 1.4.2
- Mac OS 10.14.6
- HDF5.jl 0.13.2

# インストール
いつものように]を押してパッケージモードにして、

```
add HDF5
``` 
で入れます。

# 使い方
使い方を見てみましょう。
## 書き込み
まず書き込みです。適当なfunctionを作りました。

```julia
using HDF5
function test()
    Lx = 12
    Ly = 16
    U = 3.0
    r = rand(10)
    cr = rand(3,3) .+ im+rand(3,3)

    println("Lx = $Lx")
    println("Ly = $Ly")
    println("U = $U")
    println("r = $r")
    println("cr = $cr")

    @time h5open("test.h5", "w") do file #ファイルtest.h5を開き、書き込み
        write(file,"Lx",Lx) 
        write(file,"Ly",Ly)
        write(file,"U",U)
        write(file,"r",r)
        write(file,"cr",cr)
    end
end
test()
```

これを実行すると、test.h5というファイルが作られます。
HDF5の面白いところは、データに名前がついていることです。例えばwrite(file,"Lx",Lx) はLxという名前をつけました。
読み込む時には、自分の好きな名前のものを好きな順番で読み込むことができます。

## 読み込み
例えば、

```julia
function test2()
    file = h5open("test.h5", "r")
    
    U = read(file,"U")
    cr = read(file,"cr")
    Lx = read(file,"Lx")
    Ly = read(file,"Ly")
    r = read(file,"r")

    close(file)
    
    println("Lx = $Lx")
    println("Ly = $Ly")
    println("U = $U")
    println("r = $r")
    println("cr = $cr")


end
test2()
```
としてみました。
読み込む順番と書き込んだ順番が違うところに注目してください。このように、データの名前で読み込みができるので、順番を気にせずに良くなります。また、読み込みではfile = みたいな形で書きましたが、書き込みと同様にdo構文も使えます。普通のファイルの読み書きと同じですね。
実数、複素数、配列がちゃんと読み込まれていることを確認してみてください。

# 階層構造
次に、階層構造を扱ってみます。

```julia
function test()
    Lx = 12
    Ly = 16
    U = 3.0
    r = rand(10)
    cr = rand(3,3) .+ im+rand(3,3)

    println("Lx = $Lx")
    println("Ly = $Ly")
    println("U = $U")
    println("r = $r")
    println("cr = $cr")

    @time h5open("test.h5", "w") do file
        write(file,"Lx",Lx)
        write(file,"Ly",Ly)
        write(file,"U",U)
        write(file,"r",r)
        write(file,"cr",cr)
    end

    fp = h5open("test.h5", "cw") 

    for i=1:10
        ra = rand()+im*rand()
        write(fp,"/data/$i",ra)
        println("$i $ra")
    end
    close(fp)
end
test()
```
としました。最初のコードに足しました。ここで、"cw"とするとファイルの追記モードになります。今度はopenしてcloseしてみました。```write(fp,"/data/$i",ra)```とありますが、これが階層構造になっています。ループでiが動くので、/data/1から/data/10まで複素数の乱数が保存されたことになります。
読み込むには、

```julia
function test2()
    file = h5open("test.h5", "r")
    
    U = read(file,"U")
    cr = read(file,"cr")
    Lx = read(file,"Lx")
    Ly = read(file,"Ly")
    r = read(file,"r")

    data4 = read(file,"/data/4")
    
    close(file)
    
    println("Lx = $Lx")
    println("Ly = $Ly")
    println("U = $U")
    println("r = $r")
    println("cr = $cr")

    println("4 $data4")

end
```
とすればOKです。ここでは、/data/4だけを取ってきています。
このように、名前をつけてどんどん保存し、どんどん開けるので、大量のデータを処理することに向いています。
kintoneからGoogleMapsAPIを呼び出して、緯度・経度から住所を取得してみた（リバースジオコーディング）

# やってみたこと
kintoneアプリに緯度と経度を入力してレコードを保存すると、GoogleMapsAPIを呼び出して、「住所」フィールドに取得した住所をセットするアプリを作ってみました。

# 準備１：kintoneアプリの作成
まずはkintoneアプリを作成しましょう。

| フィールドの種類 | フィールド名 | フィールドコード |
|:---------------:|:-----------:|:--------------:|
| 数値            | 緯度        | 緯度            |
| 数値            | 経度        | 経度            |
| 文字列（1行）    | 住所        | 住所            |

# 準備２：APIキーの取得
[Google Maps Platform](https://cloud.google.com/maps-platform/user-guide/)に記載の手順で、GoogleMapsのAPIキーを取得しましょう。
３つのポイントがありますので、ご注意ください。

- Maps JavaScript APIだけでなく、Geocoding APIも有効にする必要がある。
- アプリケーションの制限を「HTTPリファラー（ウェブサイト）」に設定して、APIキーを盗用されないようにする。
- Google Cloud Platform Consoleの設定にはタイムラグがある。設定が反映されないと思ったら１時間ほど待つと良い。

# プログラム
- 5行目の「APIキー」の部分は、準備２で取得したAPIキーに書き換えてください。
- 24行目でPromiseを使用しているのは、eventをreturnしてレコードを更新するためです。
- 31行目で「results[0]」を使用しているのは、Geocoder.geocode()は複数の結果を一致度が高い順に返すという仕様のためです。

```JavaScript:JavaScript
(function () {
    "use strict";

    // API キー
    var api_key = "APIキー";

    // ヘッダに要素を追加
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "https://maps.googleapis.com/maps/api/js?key=" + api_key;
    head.appendChild(script);

    // レコード追加・編集画面の保存実行前イベント
    kintone.events.on(["app.record.edit.submit", "app.record.create.submit"], function (event) {
        // 緯度・経度の指定
        var request = {
            "location": {
                "lat": parseFloat(event.record.緯度.value),
                "lng": parseFloat(event.record.経度.value)
            }
        };

        return new Promise(function (resolve, reject) {
            // リバースジオコーディングの実行
            var geocoder = new google.maps.Geocoder();
            geocoder.geocode(request, function (results, status) {
                if (status === "OK") {
                    if (results[0]) {
                        // 住所を取得できた
                        event.record.住所.value = results[0].formatted_address;
                    } else {
                        // 住所を取得できなかった
                        event.error = "住所を取得できませんでした。";
                    };
                } else {
                    // エラーが発生した
                    event.error = "エラーが発生しました。：" + status;
                };
                resolve(event);
            });
        });
    });
})();
```

# 動作確認
緯度と経度を入力してから「保存」ボタンを押すと・・・
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643129/da074a7c-da68-50e0-e137-289626ab6120.png)

住所を取得し、レコードが保存されます。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643129/6b6d95cd-531b-3ad9-b40f-8f006a152c21.png)

# 参考にしたWebサイト
- [Google Maps Platform](https://developers.google.com/maps/documentation/javascript/geocoding)
- [cybozu developper network](https://developer.cybozu.io/hc/ja/articles/202640950)
ホールドアウト検証と交差検証

#はじめに
多くの機械学習では過去のデータに基づき将来を予測する技術ため必ず学習用のデータが必要になります。また、つくったモデルがちゃんと出来ているのきちんと出来ているのかどうかを確認するために、テスト用のデータも必要となります。（結果を隠した状態でモデルに予測をさせ、答え合わせをするわけです。）よって、手元にあるデータを｢学習用のデータ｣と｢テスト用のデータ｣に分割し、検証するがあります。この分け方を検証の仕方が今回のテーマとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/18792b26-8c46-4cce-9a95-95203f083e83.png)

#ホールドアウト検証（Hold-out Validation）
。ホールドアウト検証では、学習用のデータとテスト用のデータを完全に分け、テスト用のデータは学習用のデータに含めません。後述の交差検証と違い、過度に精度の良いモデルを作ることはないのですが、分けたデータに偏りがあると、学習データの傾向とテストデータの傾向が違い、よい結果がでないというデメリットがあります。データの分布の影響を受けてしまうということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/3097dc97-ba38-9561-2e08-ec69d2c2786a.png)

#交差検証(cross-validation)
↑の偏りの影響をなくすための方法が交差検証です。（K-分割交差検証とも呼ばれるます。）データを学習用データ、検証用データ（パイパーパラメータの調整などに使用）、テスト用データに分割し、n回の検証を行い、平均のスコアをモデルのスコアとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600679/f757b3b9-ca24-00c1-8a0c-ef6985c41107.png)

#最後に
初心者にもわかるように、Pythonで機械学習を実施する際の必要な知識を簡便に記事としてまとめております。
目次は[こちら](https://qiita.com/Yanagawa_Yoshihisa/items/a3fa521d89c471b3e71f)になりますので、他の記事も参考にして頂けると幸いです。
JavaScriptでラジオボタンの情報を取得

「addEventListener()」を使った、チェックによるイベント処理の方法です。
「addEventListener()」とは、さまざまなイベント処理を実行することができるメソッドです。

+ 入力がされた
+ クリックがされた
+ ページが読み込まれた

などが発生した場合に「addEventListener()」を使って処理を実行できます。

## 書き方
```javascript
対象要素.addEventListener( 種類, 関数, false )
```

■第1引数にイベントの種類を指定

■第2引数に関数を指定

■第3引数にイベント伝搬の方式を「true / false」で指定
通常はfalseを指定しておく。

## ラジオボタンが押されたらvalueの情報を取得する

```html:html
<form id="CheckBtn">
    <input type="radio" name="group" value="ラジオボタン1" checked> ラジオボタン1
    <input type="radio" name="group" value="ラジオボタン2"> ラジオボタン2
    <input type="radio" name="group" value="ラジオボタン3"> ラジオボタン3
</form>
```
```javascript:javascript
const CheckBtn = document.getElementById('CheckBtn');
CheckBtn.addEventListener('change', function () {
  console.log(CheckBtn.group.value);
});
```


## まとめ
ラジオボタンでサイトの装飾を変化させたときのコードです。

よく見るドロワーやアコーディオンメニューなどの機能も「addEventListener()」で作れるので、覚えておいても良いかも。
IoT機器ー住宅展示場でのホームセキュリティシステムの実証実験－午後

応用情報技術者令和元年秋期 午後問4

ファイル：2019r01a_ap_pm_qs.pdf
当該記事はメモだけです。フル出題は、上記ファイルをご覧くださいますようよろしくお願いします。

１、フレームレート
「フレームレート」は、1秒間の動画で見せる静止画の枚数（コマ数）です。単位は、「FPS」（frames per second）で、「コマ/秒」を表します。

フレームレートの数値が大きいと滑らかな動画になり、小さいとかくかくした動画になることがわかります。

どれくらいの数値に設定すればよいの？
ネットワークカメラのフレームレートの設定は、用途目的や撮影対象などにより異なります。

例えば…
・一連の動きをしっかり確認したい場合 ⇨24〜30FPS程度
・一時停止画像の確認などを重視したい場合 ⇨1FPS〜5FPS程度

防犯カメラでは用途によりますが、画像などの確認も必要になる場合があるため、画像の劣化を防ぐために、監視目的ではフレームレートは5FPS程度に設定されるケースが多いです。よくテレビで流れる防犯カメラのカクカクした映像ですね。

ちなみに**人の目に、自然な動きに見えるフレームレートは、30FPS**と言われています。


２、動作サイズ
動画のサイズ計算につきました、多分下記です：

**カメラパラメータ**：
解像度：1280 X 720　pixel(ピクセル）
フレームレート：30 フレーム/秒
1ピクセル：24bit

計算：
・１フレームピクセル数：1280 * 720 -> 921600 pixel
※解像度は１フレームのピクセル数、つまり、１画像ですね。

・１フレームサイズ：921600 pixel * 24 bit/pixel -> 22118400 bit
※１ピクセルは24 bit

・１秒のサイズ：22118400 bit/フレーム * 30 フレーム/秒 -> 663552000 bit/秒
※30フレーム/秒

質問で、簡単に、１Mbit = 10^6 bitとの設定があるので　
トータルサイズは、664M bit /秒になりますね。（四捨五入）

動画データに、フレーム間の差分が少ないため、効率よく圧縮できて、１％に圧縮できる想定ので、必要なネットワーク帯域は6.6 Mbit/秒になります。

・７日間の圧縮された動画データは：
6.6Mbit/秒　*(60*60*24)秒->3991680Mbit -> 498960 MByte
質問で、簡単に、１Gbit = 10^9 bitとの設定があるので　
トータルサイズは、499 GByte　になります。（少数０位、四捨五入）

３、動画データの圧縮符号化方式
・AAC―Advanced Audio Coding（略称: AAC、先進的音響符号化）は、不可逆のデジタル音声圧縮を行う音声符号化規格のひとつである。

・H.264
Advanced Video Coding（AVC）は、H.264またはMPEG-4 Part 10、Advanced Video Coding（MPEG-4 AVC）とも呼ばれ、ブロック指向の動き補償型整数DCT符号化に基づく動画圧縮規格である。2019年9月現在、**ビデオ業界の開発者の91％が使用しており、ビデオコンテンツの記録、圧縮、配信**のために圧倒的に最も一般的に使用されているフォーマットである[1][2][3]。8K UHDまでの解像度をサポートしている[4] [5]。

H.264/AVCプロジェクトの目的は、従来の規格（すなわち、MPEG-2、H.263、MPEG-4 Part 2の半分以下のビットレート）よりも実質的に低いビットレートで良好な映像品質を提供できる規格を作成することであり、設計の複雑さを増大させずに、実用的ではない、または実装するために過度に高価になるようなことはなかった。

・WMA
WMA  【 Windows Media Audio 】  .wmaファイル
WMAとは、米マイクロソフト（Microsoft）社が開発した音声データの圧縮符号化方式。単体で保存する際の標準のファイル拡張子は「.wma」で、動画に付随する音声として動画ファイルに保存される場合もある。同社のWindowsなどが標準で対応している。


下記は自分で解答するときに、自分の答えと標準答えの異なる点のメモです：
４、
動画のフレーム間の差分が少ない
→
動画に動きが少ない

５、
１は検知速度が遅い、検知画像範囲が設定できないため
→
動体検知範囲の設定ができないから

６、
３は監視カメラのメモリカード容量が不足、７日間データ保存はできないため
→
メモリカードに７日分の動画データを記録できないから

７、
Fさんのスマートフォン容量が不足のでメールサーバーから送信失敗
→
C社メールサーバーのFさんのメールボックスの空き容量

参考：
フレームレート
https://nvr.bz/topics/knowledge/what-framerate.php

動画サイズ
https://photo-tea.com/p/1808/movie-fps-pixel-size/#%E5%8B%95%E7%94%BB%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%AE%E8%A6%8F%E6%A0%BC%E3%81%A8%E5%90%8D%E7%A7%B0-%E6%97%A9%E8%A6%8B%E8%A1%A8

AAC
https://ja.wikipedia.org/wiki/AAC

H.264
https://ja.wikipedia.org/wiki/H.264
メモ: mruby

* https://ja.wikipedia.org/wiki/Mruby
* [mrbgemsリスト - 特定非営利法人軽量Rubyフォーラム](http://forum.mruby.org/download/index211.html)
    * [mruby - libraries](http://mruby.org/libraries/)
    * [mruby/mgem-list: A list of all GEMs for mruby to be managed by mgem](https://github.com/mruby/mgem-list)

## インストール

```sh
apt install -y \
 libmruby-dev mruby
```

```c:example.c
#include <stdio.h>
#include <mruby.h>
#include <mruby/compile.h>

int main(void) {
    mrb_state *mrb = mrb_open();
    char code[] = "5.times { puts 'mruby is awesome!' }";

    printf("Executing Ruby code with mruby:\n");
    mrb_load_string(mrb, code);

    mrb_close(mrb);
    return 0;
}
```

```sh
cc example.c -lmruby -lm -o example

./example
```

## ubuntuでwindows向けにクロスコンパイル(あんまよくわかってない)

```sh
apt install -y \
 mingw-w64 binutils-mingw-w64 gcc-mingw-w64 g++-mingw-w64
```

* 以下調査中

```sh:エラーでダメだった。
x86_64-w64-mingw32-g++ \
 -I /usr/include/ \
 -I /usr/include/x86_64-linux-gnu/ \
 mruby.c \
 -lmruby -lm \
 -o example.exe
```


![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/3a0145a7-e98b-8bfb-5410-ec2b89a8c901.png)

## dockerを使ってクロスコンパイル

```go
git clone "https://github.com/hone/mruby-cli"
cd mruby-cli
docker-compose run compile
```

```sh
mruby-cli --setup hello_world

cd hello_world
docker-compose run compile
```