OmniAICreator/Qiita-1.07M huggingface dataset:
opensslバージョンアップ @ruby

#この記事は
opensslのバージョンアップにより、各種アプリケーションが起動できなくなるエラーが起きているようです。

ssl関係はgoogleはじめプラットフォーマーが敏感なせいかサボりにくい部分です…。

'18年後半から現在まで「phpが動かないよー」とか「rubyが動かないよー」という記事がたくさん出ていて、ぶっちゃけ対処法はそれらにも載っているのですが、如何せんスマートな方法を書いている記事がなく。

・他により良い対処法はないのか？
・なぜスマートな方法が見つからないのか？

ということで調べてみました。(phpの名前を出しておいてアレですが、rubyだけです悪しからず。)

#この記事の対象
○Macユーザー
△その他Unix系ユーザー
×windowsユーザー

#検証環境
Mac OS Mojave 10.14.6 （アップデートをサボっています）
rbenv 1.1.2
ruby 2.6.3
Rails 5.2.3

#rubyが動かない現象
事の発端は久々にrailsでバックエンドを作ろうとした時のこと。とりあえずrails -vを打ったところ、やたら長いエラーが発生。もしかしてrails --versionじゃないとダメだったか？と思い、ロングオプションを打つも同じエラー。

仕方がないのでエラーをちゃんと読むとopenssl関係だと分かりました。
運がいいことに、前日postgresqlのバージョンアップでopenssl1.1.0を入れていたので、"openssl1.0.0"の文字からバージョン関係のエラーだと切り分ける事ができました。

#ググる
rubyを再インストールして見たら動いたというパターンと、rubyを再インストールすればいいよという記事を見て再インストールしているケースが多数。なるほど最悪rubyを再インストールすればいいと分かりました。
でも明らかに参照先のopensslが違うだけのエラーなので、もうすこし簡単な方法があるはずでは？

#間違ったopensslを探しに行っている犯人を探してみる
##ruby2.6.3のなかに設定ファイルはないか？
結論→ない
grep -r "（opensslのパス)" .rbenv/versions/2.6.3 してもそれらしい設定ファイルは見つからず。

その代わり、
.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin18/digest/md5.bundle
.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin18/digest/sha2.bundle
.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin18/digest/rmd160.bundle
.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin18/digest/sha1.bundle
.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin18/openssl.bundle
.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/puma-3.12.1/puma/puma_http11.bundle
.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/ext/puma_http11/puma_http11.bundle
.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/puma_http11.bundle

がヒット。pumaはgemだけど、後のはどう見てもruby本体のライブラリ、嫌な感じしかしないですね。

##もしかして：環境変数
結論→ない

printenvしても一切見つからず。
大抵こういうパターンでも新たに特定の変数名で環境変数を作ってやると解決するパターンがある可能性は高いですが、とりあえず「なくても動いている」=「他の参照元が有効である」ことは確実です。

##ということは
rubyをビルドする時にインストール済みのopensslを探しに行ってライブラリに直書きするパターン？
だから再インストールで直るのかー。

#rubyが正常に動く状態にする
##シンボリックリンクを張る
ln -s libssl.1.1.dylib libssl.1.0.0.dylib
ln -s libcrypto.1.1.dylib libcrypto.1.0.0.dylib

私の環境ではopenssl絡みで参照されるライブラリはlibsslとlibcryptoだけでした。(grepすると分かります。)
おそらく一般的にそうなのではないかと思います。
コマンドの数字の部分は左側が実在のファイルと同じ、右側が最初のエラーで出たopensslのバージョンです。

##動いた
まあそうですよね。動くに決まっています。

#どのような対応がベストか？
シンボリックリンクを張るだけでうまいこと動いてくれました。
ですが、またopensslのバージョンを変えた場合は同じことの繰り返しです。

それを考えると、どうしても今のrubyを維持したい場合はこの方法でも良いのですが、そうでなければ再インストールでもいいような気がしました。

#（追記）そんな甘い話ではなかった
openssl1.0x以下とopenssl1.1xでは起動時にライブラリをロードする方法が違うとのことで、1.0xからバージョンアップした際、openssl.bundleがエラーを吐くことがわかりました。
1.0x以下の環境下でビルドされたrubyはopenssl1.1xの実行に必要なOPENSSL_init_sslを起動できず、
逆にopenssl1.1xに存在しない_SSL_library_initを呼び出そうとするためエラーになる模様。

##検証内容
grep -r _SSL_library_init /(path to 2.6.3's)/openssl.bundle
-> match
grep -r OPENSSL_init_ssl /(path to 2.6.3's)/openssl.bundle
-> no match

openssl1.1.0が存在する状態で
rbenv install 2.6.0
rbenv local 2.6.0
元が2.6.3なので、rubyのバージョンは下がっています。ですのでrubyのバージョンが左右する訳ではないはず。
grep -r _SSL_library_init /(path to 2.6.0's)/openssl.bundle
-> no match
grep -r OPENSSL_init_ssl /(path to 2.6.0's)/openssl.bundle
-> match

呼び出し関数名が変わっているのがわかります。

gem install rails
rails new test-app
cd test-app
rails s
-> OK

今度は正常に動いてますね…。

##つまり
やっぱり再インストールした方が無難です。
[Unity] invalid build pathでAndroidビルドが出来ない


# 事象

```console
Invalid build path: c:/develop/unity/test
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at C:/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:179)
```

`Unity 2019.2.13f1` でAndroidビルドをしようとすると、`.apk`ファイルの保存ができなかった。

ビルドボタン選択時、表示されるダイアログで、(保存先の？)**フォルダ選択しかできず**。
いつもなら、保存する`.apk`ファイルの名前を指定して保存する手順のはず。。。

**いつものビルドパターン**
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171600/b40caf36-764d-5913-e473-65d5d5404f8b.png)

**今回のビルドパターン**
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171600/f55f0e1f-9912-979e-621c-0b8a9a8407ef.png)


とりあえず、プロジェクトフォルダを選択してみると、このエラー。

いや、なんで？？？？？


# 解決方法

**プロジェクトフォルダ以外のフォルダを指定する。**

ただし、プロジェクトフォルダ配下のフォルダはいくつか試してみてダメだったので、それより手前のフォルダを指定する必要があるかも。

今回は適当にフォルダを掘って、`C:\new`を指定してみました。
するとビルドが始まり、success後、指定したフォルダに.apkファイルが出来た。。。

いや、なんで？？？？？


# ちなみに

環境
Windows10
Unity 2019.2.13f1
AndroidSDK 26.1.1

UnityでOculusQuestのビルドを試していたところ発生。

AndroidSDKのバージョンと、Unityのバージョンに互換性がないと動かないらしいけど、2週間ほど前にビルド実績があるのでおそらく関係なし。

Questビルド用に、プロジェクトの設定を色々変えていたのが原因？
分かり次第、追記したい。。
Laravel 6 で laravel/ui をインストールしたらwebpackがコンパイルできなかった

# 前提

Laravel 6 から、認証機能を使うためには `laravel/ui` を追加インストールしなければいけなくなった。

[公式ドキュメント](https://laravel.com/docs/6.x/authentication)

公式ドキュメントだとwebpackのコンパイルに関しては書かれておらず、UIを適用するには、以下のコマンドを実行する必要がある。

```
$ npm install
$ npm run dev
```

参考: [https://www.techiediaries.com/laravel-authentication-tutorial/](Laravel 6 Auth Tutorial: Login/Register/Password Reset UI)

# エラー

実行しようとしたら、エラーが出た。

```
npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js`
```

どうやら、以下が問題となっているらしい。

```
Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (72)
```

調べていくと、 `node-sass` を再インストールすればいいらしい。
が、 `npm install -g node-sass` で、再度エラー。

```
Error: EACCES: permission denied, mkdir /Users/xxx/node_modules/node-sass/build
```

権限関係ならと思い、 `sudo` してもだめ。
これは、そもそも **npmをsudoでインストールしている** と出てしまうらしい（？ちゃんと理解できてないかも？）

参照
[Error: EACCES, mkdir '/usr/local/lib/node_modules/node-sass' - installing globally #1098 へのコメント](https://github.com/sass/node-sass/issues/1098#issuecomment-133677759)
[Resolving EACCES permissions errors when installing packages globally](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally)

# 解決方法

node バージョンマネージャーである `nvm` をインストールして、そこから改めて `node` をインストールする。
すでに `npm` が `sudo` でダウンロードされていても大丈夫。

[Github: nvm](https://github.com/nvm-sh/nvm)

## `nvm` のインストール
```
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
```

`~/.bash_profile` などに以下を追加

```
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```

## `node-sass` のインストール
```
npm install -g node-sass
```

## コンパイル成功
```
$ npm install
$ npm run dev
```
Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': The provided selector is empty.

devtoolを開いてdropdownメニューをクリックするとこのエラーが出た。

```
Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': The provided selector is empty.
```

調べていると、下記のissueでも同内容のエラーが出ている。
bootstrapのdropdownが原因だった。
https://github.com/puppeteer/puppeteer/issues/1203

### 解決方法

1. 親要素の`id`を、`data-target`にする。

2. 子要素の`aria-labelledby`を、`id` にする。

```html:修正前

<div class="global-header-menu">
  <a href="#" class="dropdown-toggle dropdown-toggle-link" role="button" data-toggle="dropdown" id="navbarDropdownMenuLink" aria-haspopup="true" aria-expanded="false">☰</a>
  <div class="dropdown-menu dropdown-menu-right dropdown-menu-link" aria-labelledby="navbarDropdownMenuLink">
    <a class="dropdown-item" href="/howto">このアプリについて</a>
    <a class="dropdown-item" href="/about">管理人について</a>
  </div>
</div>
```

```html:修正後

<div class="global-header-menu">
  <a href="#" class="dropdown-toggle dropdown-toggle-link" role="button" data-toggle="dropdown" data-target="#navbarDropdownMenuLink" aria-haspopup="true" aria-expanded="false">☰</a>
  <div class="dropdown-menu dropdown-menu-right dropdown-menu-link" id="navbarDropdownMenuLink">
    <a class="dropdown-item" href="/howto">このアプリについて</a>
    <a class="dropdown-item" href="/about">管理人について</a>
  </div>
</div>
```

これでエラーが解消した。
kubernetesを使う人のための便利なalias

# はじめに

こんにちは、インフラエンジニアです。
普段はKubernetes（GKE）をよく使っています。


# なぜ書いたか

K8sをCLIで操作する際にKubectlというコマンドがあるのですが
タイプするのが面倒くさい！長い！
なので、便利なエイリアスを設定したので記事にしました。

# 本題

Macの場合

```
$ vim ~/.bash_profile
```

以下の二行を追加して保存

```:bash_profile
alias k='kubectl'
alias kg='kubectl get'
```

```
$ source ~/.bash_profile
```

k で kubectl を実行できるようになります。
簡単ですね。


# 参考文献（なければ不要）

[Qiitaで簡単に記事を書くためのフォーマット](https://qiita.com/kenseitogari1/items/1dcf4328d54e9f2c087c)

# 最後に

最後まで読んでいただきありがとうございます！
Qiitaで簡単に記事を書くためのフォーマット


# はじめに


広報：「広報や採用で使いたいから技術を発信して」
エンジニア：「何を・どうやって書いたらいいか分からん」
広報：「登壇しろ、それかせめて`Qiita`書け」
エンジニア：「そんな時間ない、開発で忙しい」

このような状況の会社少なからずあるのではと思います。

# なぜ書いたか

広報部門が困っている。エンジニアも書きたいけど書けない。
そんな会社や人のために、エンジニアが省エネで書けるフォーマットを用意しました。


# 本文

以下の４ステップで記事が完成します

1. 分かりやすいタイトルを決める
2. キーワードを追加する
3. 以下のフォーマットをコピペ＆修正する
4. 投稿する


```
# はじめに
＜問題や課題、執筆に至った経緯など＞

こんにちは、インフラエンジニアです。
普段はKubernetes（GKE）をよく使っています。

# 何を書いたか（本題が短い場合は不要）
＜本題の要約＞

# なぜ書いたか
＜状況や目的、対象読者＞

K8sをCLIで操作する際にKubectlというコマンドがあるのですが
タイプするのが面倒くさい！長い！
なので、便利なエイリアスを設定したので記事にしました。

# 本題
＜本題が大きい場合はTopicに分割＞

Macの場合

$ vim ~/.bash_profile

以下の二行を追加して保存

alias k='kubectl'
alias kg='kubectl get'

$ source ~/.bash_profile

k で kubectl を実行できるようになります。
簡単ですね。

### Topic1

### Topic2


# 参考文献（なければ不要）
＜参考にした文献や引用した資料がある場合は記載＞

[Qiitaで簡単に記事を書くためのフォーマット](https:)

# 最後に
＜もしあれば一言とお礼＞

最後まで読んでいただきありがとうございます！
```
ちなみにこのフォーマットで作った記事が[こちら](https://qiita.com/kenseitogari1/items/0f7b99ea9909f53214ba)です
*以下の小技も少し使ってます

# 小技

コードを[```]で囲うとそれっぽくなります
>
（空行）
\`\`\`ruby:qiita.rb
puts 'The best way to log and share programmers knowledge.'
```
（空行）

↑が↓になります。


```ruby:qiita.rb
puts 'The best way to log and share programmers knowledge.'
```

>
\`\`\`言語(なくてもOK)：ファイル名(なくてもOK)
コード or コマンド
```

# 参考文献

[Qiitaで良い記事を書く技術](https://qiita.com/t12u/items/8c28484100dfd3a6351b#1-1-%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB%E3%82%92%E6%B1%BA%E3%82%81%E3%82%8B)

# 最後に


この記事をストックして、記事を書くときに本文の内容をコピペ＆修正すると便利です。
最後まで読んでいただきありがとうございました。
Leetcode Easy 88. Merge Sorted Array

Vectorを結合してソートする問題。

```cpp
using namespace std;
#include <iostream>
#include <algorithm>
#include <vector>
#include <random>
class Solution {
    public:
        void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
            vector<int> ans;
            for (int i = 0; i < n; i++) {
                nums1[m+i] = nums2[i];
            }
            sort(nums1.begin(), nums1.begin() + m + n);

            //確認用
            for (int i = 0; i < n + m; i++) cout << i << " " << endl;
        }

};

int main()
{
    Solution* Sol = new Solution();
    random_device rnd;
    mt19937 mt(rnd());

    vector<int> v1(300);
    for (int i = 0; i < 100; ++i) v1[i] = (mt() % 1000);

    cout << endl;
    vector<int> v2(100);
    for (int i = 0; i < 100; ++i) v2[i] = mt() % 1000;

    Sol->merge(v1,100, v2,v2.size());
}
[tensorflow]tf.nn.conv2d()のfiltersにはtensorを与える．

備忘録です．
tf.nn.conv2d()の引数filtersにはtensorとして定義したkernelを与えましょう．

##悪い例

```
conv = tf.nn.conv2d(
                input=image,
                filters=[8,8,64,128],
                padding="VALID",
                data_format="NHWC"
            )
```

[公式ドキュメント](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d?version=stable)を見ればわかるが，filtersにはtensorを与える．上のように**kernelのshapeを与えてはいけない**(気持ちはわかる).
ちなみに上記のコードだとこんなエラーが出る．

```
ValueError: Shape must be rank 4 but is rank 1 for 'Conv2D_1' (op: 'Conv2D') with input shapes: [?,28,28,64], [4].
```

##動く例

```
fil = tf.get_variable('weights', [8,8,64,128], dtype=tf.float32)
conv = tf.nn.conv2d(
                input=image
                filters=fil,
                padding="VALID",
                data_format="NHWC"
            )
```
kernel(fil)をtensorとして定義して，filtersにはそのtensorを与える．
Laravel で Stripe を使うなら key は .env に書く

# はじめに

「Laravel Stripe 実装」とかで検索すると、コントローラーに Key を直接書いて動かしている方が多い気がします。（自分もそうしてました...!!）

コントローラーに直接書いても動くのですが、デプロイとかで本番の Key に変換する時にいちいち command + shift + F とかで探すのも面倒ですし、ミスも出やすいし、手間なので、こういう本番環境で変えるだろう設定周りは .env に移動した方が良いと思いました。

## .env ファイルに7行追加

``` .env
# テスト環境
STRIPE_PUBLIC_KEY=pk_test_************************
STRIPE_SECRET_KEY=sk_test_************************

# 本番環境
# STRIPE_PUBLIC_KEY=pk_live_************************
# STRIPE_SECRET_KEY=sk_live_************************
```
本番環境の時は、テスト環境の2つの key を # でコメントして、本番環境の2つの key の # を取ってあげましょう。

## config フォルダに stripe.php ファイルを新しく作成

``` config/stripe.php

<?php

return [
    'pk_key' => env('STRIPE_PUBLIC_KEY'),
    'sk_key' => env('STRIPE_SECRET_KEY'),
];

```

## Stripe を使っているコントローラーで呼び出し

```app/Http/Controllers/StripeControlller.php

// public key (view 側に決済機能を表示させる時に必要)
$stripe_pk_key = config('stripe.pk_key');
dd(stripe_pk_key);

// secret key (支払いが発生した時の決済時に必要)
$stripe_sk_key = config('stripe.sk_key');
dd(stripe_pk_key);

```

# さいごに

自分も、一回一回デプロイする時に、時間かかるし、めんどくさかったし、怖かったので、同じ思いをしている方のお役に立てれば幸いです。
JupyterLabの実行環境を構築する

[機械学習のエッセンス　実装しながら学ぶPython、数学、アルゴリズム](https://www.amazon.co.jp/dp/B07GYS3RG7/)

この本を読むにあたり、macOS Mojave(10.14.6)にJupyterLabの環境をpipを使って構築したときのメモ。

HomebrewのPython3がインストールされていることが前提。バージョンは3.7.5。

```
$ python3 --version
Python 3.7.5
```

## 作業ディレクトリと仮想環境

作業ディレクトリとPythonの仮想環境を用意する。

```
mkdir /path/to/ml

cd /path/to/ml
python3 -m venv venv
```

## pipの更新とモジュールのインストール

仮想環境上でpipを更新し、必要なモジュールをインストールする。

```
source ./venv/bin/activate

pip install --upgrade pip

pip install jupyterlab
pip install matplotlib
```

## 確認

JupyterLabを起動して確認する。

```
jupyter lab
```

## インストール後の起動方法

作業ディレクトリに移動し、仮想環境をアクティベートしてコマンドを実行する。

```
cd /path/to/ml
source ./venv/bin/activate
jupyter lab
```
[Vue] ポートフォリオサイトつくってみた

VueでWebデザインのポートフォリオサイト作りました。
https://portfolio-6d299.firebaseapp.com/

[Topページ]
![screencapture-portfolio-6d299-firebaseapp-2020-01-05-17_02_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393193/a11274a0-632b-a2c5-6896-8cc2810fcf32.png)
[Portfolioページ]
![screencapture-portfolio-6d299-firebaseapp-product-2020-01-05-17_02_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393193/d5fcb52f-f639-ec37-0622-63916ca7f8d2.png)


Portfolioページ右上のDownloadからGit Cloneできるコマンドをコピーできるので
コマンドラインもしくはターミナル上から実行してください。

このページのデザインコードはもちろん、JS部品単位でつくったものも入れていますので
開発の際にお役に立てていただければ幸いです。

【今後】
Topページはまだ作ってないのでこちらもデザインして作り込んでいく。
[自分メモ]Dockerコンテナの立ち上げメモ

イマドキDocker使うなんて当たり前だけど、あまりまともに触ったことなかったので、最初の使い方をまとめる。

# コマンドで実行する

## イメージを取得する

- [Docker Hub](https://hub.docker.com/)で目的のイメージのページを探す
- pull する

```bash

$ docker pull ubuntu:latest
```

## 立ち上げる

- 取得したイメージをrunする

コンテナの立ち上げ。

```bash

$ docker run -it -d --name ubuntulatest ubuntu:latest
```

## 立ち上げたイメージ上で操作する

```bash

$ docker exec -it ubuntulatest /bin/bash
```

## コンテナの停止

```bash

$ docker stop ubuntulatest
```

## コンテナの削除

```bash

$ docker rm ubuntulatest
```

---

# Dockerfileを使う

チーム開発などの場合、複数人間で環境を共通化したい。
その場合は、Dockerfileを作成し、立ち上げる。
以下は、DockerHubの[Rubyイメージ](https://hub.docker.com/_/ruby)を参考にする。

ドキュメント
http://docs.docker.jp/engine/reference/builder.html

## Dockerfileを作成

```dockerfile

#ベースとなるイメージ
FROM ruby:2.5 

# コマンドを走らせる
RUN  bundle config --global frozen 1 
...
```

## ビルド

```bash

$ docker build -t my-ruby-app .
```


## 立ち上げ

```
$ docker run -it --name my-running-script my-ruby-app
```

## 参考資料

DockerでUbuntu 16.04 LTSのイメージを利用してみよう
https://weblabo.oscasierra.net/docker-ubuntu1604/
cscの作法 その34 xml

#概要

cscの作法、調べてみた。
練習問題やってみた。

#練習問題

dbpediaにsparql投げてxmlを取得せよ。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/084bb022-6195-4ccd-53a8-71b2e2acc79e.png)


#サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Net;
using System.Web;
using System.IO;
using System.Text;
using System.Xml;


class form1: Form {
	form1() {
		Text = "dbpedia";
		ClientSize = new Size(200, 200);
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		WebRequest request = WebRequest.Create("http://ja.dbpedia.org/sparql");
		request.Method = "POST";
		string postData = "SELECT DISTINCT * WHERE { dbpedia-ja:デ・トマソ dbpedia-owl:abstract ?abstract .}";
		postData = "query=" + HttpUtility.UrlEncode(postData);
		Console.WriteLine(postData);
		byte[] byteArray = Encoding.UTF8.GetBytes(postData);
		request.ContentType = "application/x-www-form-urlencoded";
		request.ContentLength = byteArray.Length;
		Stream dataStream = request.GetRequestStream();
		dataStream.Write(byteArray, 0, byteArray.Length);
		dataStream.Close();
		WebResponse response = request.GetResponse();
		Console.WriteLine(((HttpWebResponse) response).StatusDescription);
		using (dataStream = response.GetResponseStream()) {
			StreamReader reader = new StreamReader(dataStream);
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(reader);
			XmlElement rootElement = xmlDoc.DocumentElement;
			XmlNodeList nodelist = rootElement.GetElementsByTagName("literal");
			MessageBox.Show(nodelist.Item(0).InnerText);
		}
		response.Close();
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
PhpStormでファイルが保存済みかどうかをタブに表示する

PhpStormを購入しました。まだ使い始めたばかりですが、ファイルが保存されているか
分からないためメモしておきます。

Preference > Editor > General > Editor Tabs
Mark Modified(*) にチェック
<img width="1126" alt="Screen Shot 2020-01-04 at 13.05.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287391/5c6963a3-9927-8c3f-9122-60cca999107b.png">
参考：
http://wigwamania.hatenablog.com/entry/2016/09/23/171123
バージョン、言語の違いで場所が違ったため記事にしました。

macOS Mojave Version 10.14.6
PhpStorm 2019.2.5
Leetcode Easy 21. Merge Two Sorted Lists 

2つの単方向LinkedListを小さい順に1つの単方向LinkedListにつなぎ替える。
有名な問題。実際に実装してみると、慣れていないとかなり面倒である。


ポイント
与えられる２つのListは既にSortされている
一つ目から順に比較して、ポインタをつなぎ変える

実装上の注意
ポインタを３つ用意する。
－１つ目のListの要素ポインタ
－２つ目のListの要素ポインタ
－順に追って行くときに使用する要素ポインタ
それぞれ２つのListの要素比較しながら要素が小さい方を選択し、
現在のポインタを移動させていく。
要素のNextがNULLになったらそのListの最後尾なので、
もう一つのListをNextに指定すればよい。

エッジケース
与えられるLinkedListがNULLの場合
片方がNULLの場合はもう一つのListがそのまま答え
＊両方がNULLのケースが存在するが、これはテストケースに存在しない。
実際はNULLでも返しておくのが良い




```cpp
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //edge case
        if (l1 == NULL && l2 == NULL)return NULL; //no test case
        else if (l1 == NULL)return l2;
        else if (l2 == NULL)return l1;

        ListNode* p1 = l1;
        ListNode* p2 = l2;
        ListNode* start = new ListNode(-1);
        ListNode* C = start;

         while (1) {
            if (p1->val <= p2->val) {
                C->next = p1;
                C = p1;
                p1 = p1->next;
                if (p1 == NULL) {
                    C->next = p2;
                    break;
                }
            }
            else if (p1->val > p2->val) {
                C->next = p2;
                C = p2;
                p2 = p2->next;
                if (p2 == NULL) {
                    C->next = p1;
                    break;
                }
            }
        }
        return start->next;
    }
 };
PostgreSQLのテーブルにjsonデータをインポート

# 確認環境
📀PostgreSQL 9.6.14

# 対象テーブルの定義
インポート対象のテーブルとして、`my_table`を定義します。

```SQL
create table my_table (
  id integer default nextval('steps_id_seq'::regclass) not null
  , name character varying(255) not null
  , age integer not null
  , primary key (id)
);
```
# インポートデータの定義
以下のファイルを作成し、`/home`下に配置しました。フルパスは`/home/sample.json`になります。

```Javascript:sample.json
[{ "name": "Mike", "age": 18 }, { "name": "Jhon", "age": 45 }, { "name": "Bob", "age": 23 }]
```
※改行を入れると、取り込み時にエラーが発生します。改行は入れないでください。

# データのインポート
psql等で以下を実行します。

```SQL
BEGIN;

create temporary table temp_json (values text) on commit drop;
copy temp_json from '/home/sample.json';

insert into my_table ("name", "age") 
select 
  values->>'name' as name,
  cast( values->>'age' as integer ) as age
from (
  select json_array_elements(replace(values,'\','\\')::json) as values 
  from temp_json
) a; 

COMMIT;
```

# 結果
👀テーブルの内容を確認します。

```
select * from my_table;

 id  | name | age
-----+------+-----
 101 | Mike |  18
 102 | Jhon |  45
 103 | Bob  |  23
(3 行)
```

以上。
【Rails】1つのテーブルに複数の外部キーを設定

##複数のテーブルを参照
###モデル生成時に設定する場合
```terminal
$ rails g model Song user:references mc:references song
```
```rb:migrationファイル
class CreateSongs < ActiveRecord::Migration[6.0]
  def change
    create_table :songs do |t|
      t.references :user, foreign_key: true
      t.references :mc, null: false, foreign_key: true
      t.string :song

      t.timestamps
    end
  end
end
```

###後から追加する場合
```
add_foreign_key :参照元のテーブル名, :参照したいテーブル名, column: :参照元につける外部キー名
```
```rb:migrationファイル
add_foreign_key :songs, :users, column: :user_id
add_foreign_key :songs, :mcs, column: :mc_id
```

###参考
[【rails5】テーブルに複数の外部キーを追加する](https://qiita.com/mah666hhh/items/7badaccb01480a595e2e)

##1つのテーブルを2つのカラムで参照
モデル作成時のコマンドでは外部キーを指定せず、作成されたマイグレーションファイルを手動で変更しました。

```terminal
rails g model Video url
```
```rb:migrationファイル
class CreateVideos < ActiveRecord::Migration[6.0]
  def change
    create_table :videos do |t|
      t.references :mc1
      t.references :mc2
      t.string :url

      t.timestamps
    end
    add_foreign_key :videos, :mcs, column: :mc1_id
    add_foreign_key :videos, :mcs, column: :mc2_id
  end
end
```
試していませんが、既存のテーブルに外部キーを追加する時にも`add_foreign_key :videos, :mcs, column: :mc1_id`のような書き方でコネコネすれば出来そうな気がします。

###参考
[テーブルの同じモデルの外部キーを複数もたせる](http://h-piiice16.hatenablog.com/entry/2018/08/13/114358)
Mean Average Precision @ 3 (MAP@3)についてのメモ

#画像分類のMAP@3の数式

```math
MAP@3 = \frac{1}{U} \sum_{u=1}^{U}\sum_{k=1}^{min(n,3)} P_u(k)
```
Uは画像の枚数。P(k)は適合率。nは予測した個数

#例
猫の画像
↓
推論
↓
１．猫　適合率:1
２．犬 
３．魚　
AP(平均適合率)=1

犬の画像
↓
推論
↓
１．猫　
２．犬  適合率:0.5
３．魚
AP(平均適合率)=0.5

MAP(平均適合率の平均)=(1+0.5)÷2=0.75
#参考
https://www.kaggle.com/c/whale-categorization-playground/overview/evaluation
https://analysis-navi.com/?p=1126
【MySQL入門を始める手順 macOS】【備忘録】

ドットインストール　MySQL入門を始める手順　Mac【備忘録】


MySQL入門 #01 MySQLを使ってみようの始める手順 Mac


①Spotlight検索（右上の虫眼鏡マーク）より、terminalを起動

まずはログインする

②$ cd（ホームフォルダに移動）

③$ cd MyVagrant（仮想マシンをまとめたフォルダに移動）

④$ cd myCentOS（仮想マシンのフォルダに移動）

⑤$ vagrant up（仮想マシンが停止していれば、仮想マシンが起動する）←ちょっと時間かかる
※大体２５〜３０秒くらいかな。

⑥$ vagrant ssh（仮想マシンにログインする）←5秒ほどかかる

⑦（[vagrant@localhost ~]$ となっていたら仮想マシンにログインできている証拠）

⑧Spotlight検索から、cyberduckを立ち上げる（ファイル転送ツールを立ち上げる）

⑨ブックマークを設定している為、出てきたものをダブルクリック（仮想マシンにアクセスする）

⑩/home/vagrantに移動できているか確認
※移動出来ていなければ、▲マークの左側のボタンを押して→/home/vagrantを選択

11.ここでMySQL用のフォルダを作る右クリックを押す→新規フォルダを作成→mysql_lessons

12.作ったmysql_lessonsのフォルダをダブルクリック

13.terminalに戻る

14.$ cd mysql_lessons（先ほど、作成したmysql_lessonsのフォルダにterminal上で移動する）

15.［vagrant@localhost mysql_lessons］$ となっているか確認


これで、

#01 MySQLを使ってみよう

を

始められる所まで進みました。



#補足.$ clear（←clearとすると、terminal内がキレイになる）


terminal内がごちゃごちゃしているのが嫌であれば、

こうやってキレイにすると見易くなります。

注意：設定が消えた訳ではないので、安心して下さい

ここから、MySQLの学習を始めればOKです。



#補足2 学習を正常に終えたい場合

サーバーが開いていない場合

①$ exit（これで仮想マシンからログアウトできて、mbpの操作に戻る）※mbpはMacBook Proのことです


②$ vagrant suspend（これで仮想マシンを停止させることができる）←5、6秒かかります

③$ exit（これでターミナルを終了させることができる）

④終わり


今回は以上です。
「QtQuickアプリケーション開発」のサンプルプログラムで困った話

#「QtQuickアプリケーション開発」のサンプルプログラム
[QtQuickアプリケーション開発](https://www.amazon.co.jp/%E3%80%8CQt-Quick%E3%80%8D%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-I%E3%83%BB-BOOKS-%E6%9D%91%E4%B8%8A/dp/4777520609/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=qt+quick&qid=1578102494&sr=8-1)の７章のサンプルプログラムを私の環境で実行したところエラーにより実行できませんでした。そこで、使用しているバージョンのQtCreatorが生成する雛形にサンプルプログラムを書き写していたところエラーでハマったのでメモ。

まだまだQt初心者ですが、誰かの役に立てばと思います。

#環境
- Qt : 5.12.6
- QtCreator : 4.10.2

#発生したエラーと解決方法

## エラーその1 「QAudioDeviceInfoがインポートできない」
QAudioDeviceInfoがImportできず、「’QAudioDeviceInfo’ file is not found」というエラーメッセージが表示される。

## エラーその1の解決方法
修正前

```qml
#include <QAudioDeviceInfo>
```
修正後

```qml
#include <QtMultimedia/QAudioInput>
```

QAudioInputの前にQtMultimediaをつけることでエラーが出なくなりました。
しかし、エラーその2の解決方法を実施することで、そもそも修正前のコードでも問題なくなるようです。


## エラーその2「Undefined refernce to …」
サンプルプログラムを一通り書き写した時点でビルドしたところ大量の「Undefined refernce to …」というエラーが発生しました。

## エラーその2の解決方法
[リファレンス](https://doc.qt.io/qt-5/qtmultimedia-module.html)を確認していたところ、下記の説明が。

>To link against the C++ libraries, add the following to your qmake project file:

```
QT += multimedia
```

ということでプロジェクトファイルに上記のコードを追加したことでエラーが解決しました。また、エラーその1も発生しなくなることを確認しました。



## エラーその3「QQmlApplicationEngine failed to load component / LevelMeter is not a type」
LevelMeterはサンプルプログラム内で作成しているカスタムQMLタイプです。

## エラーその3の解決方法
ファイル「LevelMeter.qml」のプロジェクト上の配置に問題がありました。
下記のプロジェクトビューワーが修正前。
![Screenshot from 2020-01-04 12-26-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558403/d20aa316-b6dc-89ff-9b8d-81ae780cb99d.png)

修正後
![Screenshot from 2020-01-04 12-28-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558403/7de1f7a0-9467-fbbd-17e6-6fa119e04596.png)

ファイルを追加する際に「section7」というプロジェクトの直下を右クリックして追加すると修正前のようにQMLの下にLevelMeter.qmlが入ってしまいます。

「qml.qrc」を右クリックしてファイルを追加すると修正後のようにファイルが追加されます。
これでエラーが解決しました。

勉強不足のため、.qrcファイルがどんな役割をしているのかわかりません。ご存じの方いらっしゃったらぜひ教えてください。


#参考文献
[QtQuickアプリケーション開発　工学社](https://www.amazon.co.jp/%E3%80%8CQt-Quick%E3%80%8D%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-I%E3%83%BB-BOOKS-%E6%9D%91%E4%B8%8A/dp/4777520609/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=qt+quick&qid=1578102494&sr=8-1)
[QtQuickアプリケーション開発　工学社 (サンプルプログラム)](https://github.com/qtquickbook/samples)
[Qt Multimedia Module C++ Classes](https://doc.qt.io/qt-5/qtmultimedia-module.html)
転職日記2日目

Git,GitHubに関してUdemyで学んだことをここに記述します。
間違えているところや理解が乏しいところがあるかと思いますが、その時は容赦なく突っ込んでいただければ幸いです。

１Gitとは
→バージョン管理システム。「どのファイルを」「いつ」「誰が」「何のため」変更したかを残せる
　仕組みとしては変更履歴を順々に記録している

2開発の流れ
→個人のファイルを個人リポジトリにcommitして、共有リポジトリにpushする。
・リポジトリとはファイルとファイルの変更履歴が入る箱
・commitとは個人リポジトリに変更履歴を記録
・pushとは共有リポジトリに変更を共有

3,GitHubとは
→個人リポジトリのファイルやディレクトリを預かってくれるところ
特徴
・プルリクエストでの複数人開発
→プルリクエストとは開発者のローカルリポジトリでの変更を他の開発者に通知する機能
　これにより、より質の高いコードが作れる
・他チームのソフトウェアが見える
nuxt+firebaseで開発環境を分ける

# やりたいこと

* 下記の構成で開発環境を分けたい
    * nuxt
    * firebase
        * firestore
        * firebase auth
        * firebase hosting
* 環境は下記
    * local・・・開発確認用
    * production・・・本番

下記以外に方法思いつかなかったのでいい方法あったら誰か教えてくだせえ

# 全体図

* dotenvでenvファイルをprodとstagingでそれぞれもつ
* サーバー起動時に分けて読み込む

# dotenv

https://qiita.com/yfujii1127/items/c77bff6f0177b4ff219e

dotenvの準備はこの記事がわかりやすい

# NODE_ENVでの出し分け

https://blog.ikedaosushi.com/entry/2019/04/17/220317

# deploy

* サーバーを起動してそれぞれで環境変数を切り分けてからdeploy

開発環境

```
npm run dev
firebase deploy
```

本番環境

```
npm run build
firebase deploy
```

＊nuxtのコマンド

https://ja.nuxtjs.org/guide/commands/
【＃14 hostsファイルを編集してみよう 設定の仕方-ローカル開発環境の構築［macOS編］】【備忘録】

ドットインストール＃14 hostsファイルを編集してみよう 設定の仕方-ローカル開発環境の構築［macOS編］【備忘録】

今回はドットインストールの

ローカル開発環境の構築［macOS編］の

＃14 hostsファイルを編集してみよう

が

ややこしかったので

備忘録として残します。


ドットインストールの内の

ローカル開発環境の構築［macOS編］の

下記の手順でやればOKです。


#12 学習を再開してみよう(この手順で、Vagrantにログインできる)
①$ cd
②$ cd MyVagrant
③$ cd MyCentOS
④$ vagrant up（ここまでで仮想マシンが立ち上がる）

⑤$ vagrant ssh（これでログインできる）
［vagrant@localhost ~］$　←これが仮想マシンにログインできている証拠

↓
#10 PHPの学習をしてみよう(今回はPHPだが、Webサーバーが立ち上がる)

#10でWebサーバーを立ち上げた状態で、

↓

#14 hostsファイルを編集してみよう

を行っていくとスムーズに設定できるかと思います。

dev.dotinstall.com等に設定する

↓

#11 学習をやめる手順を見ていこう
(これでWebサーバーからログアウトしたり、学習を正常にやめたりできる)

※今回の#14の設定終了後、安全にターミナルを終わらせる為に必要な手順。

※サーバーが開いている場合
control +C（これでサーバーが閉じる）

①$ exit（これで仮想マシンからログアウトできて、mbpに操作に戻る）

②$ vagrant suspend（これで仮想マシンを停止させることができる）

③$ exit（これでターミナルを終了させることができる）

④終わり


今回は以上です。
Django でexcel,csvインポート、エクスポート

#Djangのmodelをexcel,csvからインポートしたり、エクスポートしたりする方法

##django-import-exportプラグインを使う
手っ取り早くインポートエクスポートが使えるようになります。
[django-import-export](https://kurozumi.github.io/django-import-export/index.html)

インストール方法
https://kurozumi.github.io/django-import-export/installation.html

各アプリフォルダ内のadmin.pyにてModelAdminの代わりにImportExportActionModelAdminを使う

```
from import_export.admin import ImportExportActionModelAdmin
from sampleapp.models import SampleData

class SampleDataAdmin(ImportExportActionModelAdmin):
    names = [f.name for f in SampleData._meta.get_fields() if not isinstance(f, models.ManyToOneRel)]
    list_display = names
    list_filter = ['sample_row1', 'sample_row2', 'sample_row3',]
```
これだけで、csv,excelの他、jsonやyamlが使用できるようになります。
インポートはadminの一覧画面の右上、エクスポートは操作(action)よりデータを選択して実行します。


##スクラッチで実装
django-import-exportプラグインを使うと楽なのですが、どうしても使いたくない場合の実装方法は、下記リンク先に記載されています。このサイトはDjango adminの勉強にも良いと思います。
https://books.agiliq.com/projects/django-admin-cookbook/en/latest/export.html
https://books.agiliq.com/projects/django-admin-cookbook/en/latest/import.html
WindowsでC++の実行環境を構築してみた

# 概要
競技プログラミングには、実行速度が速いC++がおすすめということなので勉強するための環境を作成する。
`Visual Studio` でもいいのだが、アプリを作るわけではないのでコンソール実行ができればよいという方針。重たいし。
とりあえず`C++`触ってみたい人向け。

# 環境
* Windows10 Home
* MinGW 
* Visual Studio Code 1.41.1

# インストール
### MinGWのインストールとコンパイラのインストールを行う
以下のサイトの「1. コンパイラのインストール」を参照。画像付きで分かりやすい。
[2020年版 C言語/C++ 入門者のための環境構築 (Windows編) - LYNCSブログ](http://lyncs.hateblo.jp/entry/2018/03/11/032127#1-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

### Visual Studio Code のインストール
以下の公式サイトからインストール。
[Visual Studio Code – コード エディター | Microsoft Azure](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)

# C++ でHello World
以下のソースを準備する。

```cpp:hello.cpp
#include <iostream>

using namespace std;

int main()
{
    cout << "hello world." << endl;
    return 0;
}
```

## 実行

### コンパイル
`Visual Studio Code`のコンソールから以下のコマンドを実行する。

```
g++ -o hello hello.cpp
```

### 実行

```
./hello.exe
```

### 実行結果

```
$ ./hello.exe
hello world.
```

Hello Worldが出力された。

# 終わりに
とりあえず構文から勉強していく。  

# 参考サイト
* [2020年版 C言語/C++ 入門者のための環境構築 (Windows編) - LYNCSブログ](http://lyncs.hateblo.jp/entry/2018/03/11/032127)
* [C++でHello World - Qiita](https://qiita.com/monhan/items/ea7e642b91392bfce8a6)
A/Bテストをやるときに気をつけておくこと

## この記事の概要
独断と偏見で、A/Bテストをやるときに気をつけておいた方が良いことをまとめました。
これからA/Bテストをやっていきたい！っていう人がつまずかないような記事になっていると幸いです。

また、統計に関する記載に関しては出来る限り誤った事を書かないように注意したつもりですが、私自身の統計や検定に対する理解不足から、説明や表現に間違いがあるかもしれません。その際は指摘していただけると助かります。

## AAテストをやろう
AAテストとは、A系とB系で全く同じロジック・デザインを同一の比率で出し分けてそれぞれの結果を評価する方法です。
AAテストを実施する理由は大きく分けて2つです。

### ABテストの仕組みが問題なく動いているか確認する
AAテストは同じロジック、デザインで出し分けして結果を計測するので、計測対象のKPIに差はつかないはずです。
しかしながら、何らかの理由（ツールが壊れた・ABテスト用の実装に不具合があったなど）でKPIに有意な差がついてしまうことがあります。もちろんこの差は本来調査したいA系とB系の間の本質的な差異ではないので、ABテストを実施する前に修正する必要があります。
もしこの差を修正することも、調べることもなく最初からABテストを実施してしまった場合、本来A系とB系の間に差がなかったにも関わらずKPIに差が出てしまい、間違った意思決定をしてしまう可能性があります。この失敗を避けるために、AAテストを実施して大きな差が発生しないことを確認する必要があります。

### 誤差の範囲を把握する
A系とB系で同じロジックを使用しても、計測誤差によって全く同じ数値にはなりません。
サンプルサイズを大きくすることで計測誤差は減らすことができますが、完全に誤差がなくなることはありえません。
AAテストを実施することで、全く同じロジック、デザインでテストしたときにどの程度の差が発生することがありうるのかあらかじめ把握しておくことができます。
この結果は、本番のABテストを実施して結果にそこまで差異がなかったときにA系とB系の間の本質的な差なのか、それとも単なる計測誤差なのかを判断する時に役立ちます。


## ABテストで使う検定手法の前提・特徴を理解しておこう
ABテストの結果を評価する時、何らかの統計検定の手法が使われることが多いと思います。
「色々な統計検定の手法があり、何を使えばいいのかわからない…」「とりあえずみんなあの
◯◯っていう検定をしているからとりあえずこれでいこう」と流されてはいけません。

それぞれの統計検定は実行するための前提条件があるため、その前提を理解せずに誤った手法を選んでしまうと出てくる結果が無意味なものになってしまいます。

[こちら](https://www.rco.recruit.co.jp/career/engineer/blog/ab-test-logic/) の記事がABテストで使われる検定方法について大変詳しく解説してくれているので詳細な説明は省きますが、ABテストで利用する検定手法を選択する際はおおよそ次のような事柄を押さえておくと良いと思います。

- ABテストで計測したいKPIの種類
  - 指標がクリック率のような比率なのか、売上のような連続した数値なのか
  - 前者の場合、二項検定やカイ二乗検定が有力な候補となり、後者の場合はt検定やウィルコクソンの順位和検定が有力候補となる
- それぞれの仮説検定の帰無仮説と対立仮説は何か
- サンプルサイズの大きさ
  - カイ二乗検定やt検定は取得できるデータの量が十分に大きい場合しか使ってはいけない

## あらかじめ必要なサンプルサイズを見積もっておこう
A/Bテストで得たデータに対して統計的検定を実施する場合、十分な量のデータを確保しないと有意差が出なかった場合に「実際に帰無仮説が真」なのか「本当は対立仮説が正しいが、十分なデータ量が足りず差を検出できなかった」のか判断がつかないことがあります。
逆に不必要に大きいデータ量でA/Bテストを実施すると、本来不要なコストが掛かったり、ビジネス上は意味がない小さい効果を「有意差あり」として検出してしまう可能性があります（統計的検定ではデータの量を増やせば増やすほど、小さな差異でも有意な差として検出しやすくなる）。

上記のような状況を避けるためには、A/Bテストの前に必要なデータ量（以下、サンプルサイズと呼びます）を見積もっておく必要があります。

ここからの説明は統計的な知識を必要とするのですが、例えばA系とB系のクリック率に統計的に有意な差があるかどうか、カイ二乗検定を用いて知りたい場合は下記のような手順を踏みます。

1. A系とB系それぞれの予想クリック率を見積もる
  - 例えば、A系の予想クリック率が1%で、B系はA系に比べて1.1倍クリック率が高そうなので1.1%と見積もる、など
  - 一般的に、A系とB系の間の差異が少ないと見積れば見積もるほど、必要とするサンプルサイズは大きくなります
     - わずかな差を見極めようとする場合、なるべく計測誤差による影響を減らす必要があるため、より多くのデータが必要になります
  - 今回はクリック率を例に出しましたが、他の指標を検定するためのサンプルサイズを求める場合も大筋は同じです。ただし、その他の検定手法を用いる場合は予想クリック率ではなく効果量（effect size）と呼ばれる指標を事前に見積もります。
     - effect sizeについては[こちら](https://tjo.hatenablog.com/entry/2014/02/24/192655#fn-829e84b8)が詳しいので必要に応じてご覧ください
2. 必要とする検定結果の精度を決める
  - サンプルサイズを決めるには、次の2つを決める必要があります
    - A系とB系には差がないにも関わらず、差があると結論してしまう確率α
    - A系とB系の間に本来差があるにも関わらず、差がないと結論してしまう確率β
  - αやβを小さくしようとする(=より精度を高める)と、必要になるサンプルサイズは大きくなります
3. 1と2で見積もった数値を計算式に当て込んでサンプルサイズを計算する
  - 最近は下記のような大変便利なサイトがあるので、こちらに当て込んでしまうとスパッと計算してくれたりします。
     - https://keisan.casio.jp/exec/user/1489063696 
  - 普段サンプルサイズを見積もる時は上記のようなサイトを使えばいいのですが、上記のサイトでやっている計算はどのような根拠に基づいているのかは、一度勉強しておくことを強くおすすめします。
     - [こちら](https://www.amazon.co.jp/exec/obidos/ASIN/4254126654/hatena-blog-22/)の書籍とかがおすすめです
VYOS 1.2.X系 (apt パッケージの有効化)

# 実行環境
- VYOS 1.2.3
　VYOS 1.1.3にHaproxyをインストールするためにパッケージマネージャーの有効化を行う。VYOS1.2.X系では、1.1.X系で使用出来ていた、以下のコマンド類が廃止されている。

```bash
set system repository 省略
```

　VYOSはルータであるため、他のパッケージを入れる事は非推奨だが、サーバー台数を減らすためなど様々な理由で、パッケージを入れたい事もある。今回は、haproxyをインストールするために、パッケージの有効化を行う。

```bash
vi /etc/apt/source.list
deb http://deb.debian.org/debian/ jessie main
deb http://security.debian.org/ jessie/updates main
```

## Haproxyのインストール
```bash
sudo apt update
sudo apt install haproxy
```

# 参考文献
- https://wiki.debian.org/DebianJessie
WindowsUpdateが勝手に実行されないようにする

\:information_source: この記事は別サイトで執筆した[WindowsUpdateを勝手に実行されないようにする – ひつじぶどう](https://blog.rumraisin.tokyo/?p=49)の内容を加筆・修正した上で転載しています。
# はじめに
こんにちは‪✋(´･ᴗ･\` )‬
WindowsUpdateは定期的に実行すべきものではありますが,

- Windowsを再起動したいけど「再起動」ボタンが「更新して再起動」になっており, 仕事の区切り等から今更新プログラムのインストールはしないでほしいので再起動できない
- 勝手にWindowsUpdateがダウンロードされてWindowsの動作が重くなる

等々, WindowsUpdateは都合の悪いタイミングで再起動を要求してくるものです。
この記事ではその問題の回避方法を説明します。
が, くれぐれもWindowsUpdateはお風呂に入っている間とか, PCを使わない時に必ず実施するようにはしてください。

# 前提条件
- Windows 10 Pro/Enterprise/Education エディションであること
- 管理者権限を持っていること
- この設定を入れても**WindowsUpdateを手動で実行**すること

# 実行環境
| 項目 | 値 |
|:-----|:-----|
| OS | Windows 10 Pro |
| Build | 1809 |

# 手順
以下の手順を実施します。

## 「シャットダウン」のメニューを「更新して◯◯」にさせないようにする
① スタートメニューに”gpedit.msc”と入力して実行する
![スクリーンショット 2019-04-14 19.28.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/344cb2b5-fcd8-c42f-df76-c4de73c7dd65.png)

② "コンピューターの構成/管理用テンプレート/Windowsコンポーネント/WindowsUpdate"を展開する
![スクリーンショット 2019-04-14 19.31.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/ebcf3885-9871-45a4-f5f0-26b539176f1a.png)

③ [Windows シャットダウン]ダイアログボックスの既定のオプションを[更新をインストールしてシャットダウン]に調整しないを開き, 「有効」に設定する
![スクリーンショット 2019-04-14 19.32.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/db601b52-38b1-ab43-80e8-ae3436bb98d6.png)

## WindowsUpdateのダウンロード・インストールのタイミングを変更する
① 上記の①, ②の手順を未実施であれば実施する。
② 「自動更新を構成する」を開き, 「有効」に設定した上で, 「自動更新の構成」から好きなタイミングを選択する(設定項目はWindows 7までで設定できていた内容と同じです)
![スクリーンショット 2019-04-14 19.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/19a3d82c-0b0c-c78d-30f4-186ebc07855f.png)
ランダム数列

ランダム値を生成する。
言語はC++
テストやサンプル作成時、
競技プログラミングでも使用する。


```cpp
using namespace std;
#include <iostream>
#include <random>
int main()
{
    vector<int> v;
    random_device rnd;
    mt19937 mt(rnd());
    for (int i = 0; i < 100; ++i) v.push_back(mt() % 100);

    //sort
    sort(v.begin(), v.end());

    //output
    for (auto i : v)  cout << v[i] << " ";

	return 0;
}
```
javascriptでclickしたらclass追加

# やりたいこと

* clickしたらevent発火
* classを追加してcssを変更

# コード

```html
<html>
<body>
<div id="ababa"></div>
</body>
</html>
<script>
    document.getElementById('ababa').addEventListener('click', () => {
      document.getElementById('ababa').style.background = 'blue';
    });
  </script>
```

# 解説

DocumentはオブジェクトでgetElementByIdがメソッドになる。getElementByIdでdocument内にある指定したidと一致したものをとってくる。そのとってきたidに対してaddEventListenerメソッドを使っていてclickで発火するようにしている。

Document
https://developer.mozilla.org/ja/docs/Web/API/Document

getElementById
https://developer.mozilla.org/ja/docs/Web/API/Document/getElementById

addEventListener
https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener
Raspberry Pi 4B を1か月使ってみた感想

Raspberry Pi 4 (Rev1.1)を１か月使ってみた感想です。
手持ちの 3B+ と比較してみたいと思います。

|項目|Pi4|Pi3B+|
|---|---|---|
|RAM|4GB版を購入|1GB版を購入|
|CPU|Pi3B+の3倍程度の速度|Pi4の1/3程度の速度|
|SWAP|NOOBSインストールだと100MBが自動設定|NOOBSインストールだと100MBが自動設定|
|OpenCV|4.0.1コンパイルは標準のスワップ領域で可能。4.1.x, 4.2.x はライブラリ不足でコンパイルできず。|やったことはないがたぶん2GBのスワップが必要と思われる。|
|mplayer|とても不安定(10分程度しか動作せず)|不安定(25分程度しか動作せず)|
|vlc|やや不安定(半日程度は動作)|安定的に動作|
|WiFi|やや不安定(時々再接続が起こる）|安定的に動作|
|bluetooth|安定的に動作|安定的に動作|
|USBカメラ|接続できず|接続可能で画像も映る|

画像処理目的で 3B+ から 4 への乗り換えを検討する人も多いと思われますが（私もそう）、Logitec の USBカメラを認識はするものの、フレーム読み込みに失敗します。3B+ では正常に映ることから原因は bcm2835_v4l2 とかなと思いますが、今後の対応に期待したいところ。

mplayer は使い物にならないほど不安定でした。まあ、cvlc が標準でインストールされるので、そちらを使えばインターネットラジオは聞けるわけですが。mplayer は kernel もろともお亡くなりになる現象が起きますが、cvlc では単に音が出なくなるだけで kernel へのダメージはないようです。
cvlc の 3B+ における CPU 占有率は28%ですが、4Bは8%程度なので、CPUが3倍速くなったという見解は当たっているようです。

OpenCV がまともにコンパイルできるようになったのが少しうれしい。(パッケージは3までしかないのが惜しい。)
【Mac】VSCode 調べたショートカット

# キー記号(Mac)
|記号|キー|参考|
|:--|:--|:--|
|⌘|コマンド||
|⇧|シフト||
|⌥|オプション||
|^|コントロール||

参考
[Macのoptionやshiftの記号を入力する方法](https://takaslife.com/2014/06/11/mac-kigou/)

# デフォルト

|説明|ショートカット名(Mac)|参考|
|:--|:--|:--|
|ファイルの先頭に移動|⌘↑|
|ファイルの末尾に移動|⌘↓|
|特定の行に移動|^G|
|左からn番目のエディタにフォーカス|⌘n (n = 数字キー)|
|プロジェクト内検索|⇧⌘F|
|フォーカス行の削除|⇧⌘K|
|区切りのよいところまで移動|⌥← or ⌥→|
|現在行の次に行を追加|⌘Enter|[vscodeで行の途中から改行するキーボードショートカットを教えてください](https://ja.stackoverflow.com/questions/41894/vscode%E3%81%A7%E8%A1%8C%E3%81%AE%E9%80%94%E4%B8%AD%E3%81%8B%E3%82%89%E6%94%B9%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84)|
|スクロールアップ・ダウン|fn↑ or fn↓||
|置換|⌥⌘F||
|行のコピー|⌘C||
|サイドバーにフォーカスを移動|⌘0||
|エクスプローラーの表示|⇧⌘E||
|全てのエディタを閉じる|⌘K + ⌘W||
|サイドバーのトグル|⌘B||
|アクティブなファイルの絶対パスをコピー|⌘K + P||
|アクティブなファイルの相対パスをコピー（エクスプローラーにフォーカスがある時）|⇧⌥⌘C||
|ターミナルの画面分割|^⌘⌥¥||
|コンソール画面を閉じる|⌘J||
|波線（エラーor警告）発生時のHoverを表示|⌘K + ⌘I||
|QuickFixの表示|⌘.||


# 独自設定

|説明|ショートカット名(Mac)|参考|
|:--|:--|:--|
|エディタを右に分割|⌘⌥¥|
|ターミナルへフォーカス|^;|
|左のターミナルへフォーカス|^⇧.|
|右のターミナルへフォーカス|^⇧,|

# 便利なコマンド (⇧⌘P-> コマンド名)
|説明|コマンド名|参考|
|:--|:--|:--|
|アクティブなファイルの相対パスをコピー|Copy Path||
"スクラム"について

こんにちは！エンジニアのTakutoです。

最近、スクラムといった単語をよく耳にするな〜と思っております。
ラグビーW杯でもいっぱい出てきましたね笑 今回はITの世界でのお話です。

![418a5524dcd56c9e2210b781c1f289ef_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269830/7b6f6fa6-4e12-ecfa-f807-6ac32260adc7.jpeg)
(<a href="https://www.photo-ac.com/profile/1645511">makieni</a>さんによる<a href="https://www.photo-ac.com/">写真AC</a>からの写真)                         



IT業界ってよく耳にするわりに全然わからない単語が多いですよね・・・
スクラムもそのひとつかなと思います。
今回はそんな”スクラム“について理解を深めていきたいなと思います。

実はスクラムの定義については以下のサイトに掲載されています。
https://www.scrumguides.org/

そして英語版しかないと思った方も安心してください。
しっかり日本語に翻訳されたPDFもダウンロードできます！
https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf

本日紹介していく話を全てこちらのPDFを元に進めていきます。
私なりの理解を取り入れて、なるべく端的に説明していきます。

# 端的に
スクラムのガイドを読んだ結果、スクラムで言いたいことはこんな感じかなーと思いました。
細かいところ置いておいて、流れとしてはPDCAサイクルを定期的に回すように定義したフレームワークだと思いました。

<img width="355" alt="スクリーンショット 2020-01-03 21.21.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269830/c78086e8-4254-6daf-464c-6fb0ebdd5e1e.png">

# スクラムとは？
スクラムとは一言で説明すると
「複雑なプロダクトを開発・提供・保守するためのフレームワーク」です。

Ken Schwaber と Jeff Sutherlandという偉い方々が
「複雑で変化の激しい問題に対応する」ために考え出したフレームワークです。

ですので、昨今聞くスクラム開発はスクラムというフレームワークを用いた開発のことをさします。いまいちピンとこない定義なので、具体的な内容に入っていきたいと思います。

# 役割
スクラムの中ではいくつかの役割が定義されています。

* プロダクトオーナー
* 開発チーム
* スクラムマスター

## プロダクトオーナー
プロダクトオーナーはプロダクトの価値の最大化に責任をもつ役割です。
ここでいうプロダクトとは成果物のことであり、プログラマーであれば、作成しているアプリケーションなどを想像してください。

意思決定の裁量が大きく、エンジニアではなくビジネスサイドの担当者がプロダクトオーナーを担う場合が多いみたいです。部長とか。

* 各チームに１人
* プロダクトバックログの管理
* バックログを明確にする
* バックログに優先度をつける
* バックログの見える化
* バックログの周知

ここでバックログという言葉が出てきました。
一旦ここではアプリケーションの機能と理解してください。

## 開発チーム
開発チームは実際に開発を行っていく役割です。

* スプリント内でプロダクトインクリメントを作成する
* 3〜９名
* みんな平等
* 開発チームの中にチームを作らない

今度はスプリントとプロダクトインクリメントという言葉が出てきました。
ここではスプリントは開発期間、プロダクトインクリメントはほぼできあがったプロダクトと
捉えてください。

## スクラムマスター
スクラムマスターはチームのお助け役です。

* 各チームに１人
* スクラムチームの支援
* プロダクトオーナーの支援
* 開発チームの支援

役割のリレーションを図にしてみるとこんな感じ。それぞれの役割はいっぱいあるので割愛している部分も多いが関係性が理解できればいいかなーと思います。

<img width="561" alt="スクリーンショット 2020-01-03 20.26.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269830/440370de-ef22-7cf8-266d-14d1460ff75e.png">


# 手順
次はスクラムのイベントを紹介していきたいと思います。
スクラムではイベントを定義することで、定義外のイベントを最小化しています。

* スプリント
* スプリントプランニング
* デイリースクラム
* スプリントレビュー
* スプリントレトロスペクティブ

## スプリント
定義ではタイムボックスと表記されています。
これは１つの開発期間の単位です。スプリントが複数あることでプロダクトが完成していきます

## スプリントプランニング
スプリントプランニングではスプリント内で、何をどうやって作成していくかを決定します。
また、プロダクトバックログをベースにスプリントゴールを明確に決めます。
スプリント内である程度のプロダクトインクリメントを作成する必要があるので、重要な工程です。

## デイリースクラム
デイリースクラムではスプリントバックログを元に、その日やったことを振り返り
次の日やることを決定します。
開発チームが主体で行い、15分で実施します。

スプリントバックログとはスプリントで実施が決定したバックログを達成するために必要な作業などを書いたタスクのことである。

## スプリントレビュー
スプリントレビューではチームおよびステークホルダーにスプリントで実施した成果をレビューしてもらいます。レビューでは様々な要素が含まれるが、主にスプリントバックログの確認、次に実施する作業の相談などを行う。
スプリント期間が１週間の場合はスプリントレビューは１時間くらい。

## スプリントレトロスペクティブ
スプリントレトロスペクティブでは前スプリントの成果を元に次回のスプリントの改善実施計画などを検討します。人・関係・プロセス・ツールなどの観点から調査して、効果的であったものは残します。

# まとめ
いかがでしたでしょうか。
スクラムへの理解が少しでも進んでいただければ幸いです。

<img width="800" alt="スクリーンショット 2020-01-03 21.28.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269830/d277509f-ded5-fea0-2c51-e6d64ab5a335.png">

しかし一人で試せないから実践できないのが辛いよなー。
[Rails]rails sを実行した際のPG::ConnectionBadの対処法

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#rails sを実行すると画像のようなエラー画面になります
<img width="1195" alt="9b14f558d5741ade85174b2f5f175e78.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/fd1d6dbe-e9ed-3a40-7208-d574a363a9b7.png">

この様な場合は、PostgreSQLサーバーが起動していない事が原因の様です。
[PG::ConnectionBad　の対処法 - Qiita](https://qiita.com/ho_soft/items/c8a2cbf087016b7a712b/)

ただ、macの場合は、以下のコマンドは使えないので

```apache
$ sudo service postgresql start
```

以下のPostgreSQL起動コマンドを使用すればエラーが無くなりました！
・[ローカル Mac で PostgreSQL を起動したり停止したり - Qiita](https://qiita.com/mochizukikotaro/items/84204d5c46b67c9b74f4/)

```apache
# Start
$ postgres -D /usr/local/var/postgres
```
【Rails】CSVを取り込み、計算し、画面に出力

運営しているシステムの大幅回収にあたり、DBを移行しました。

その際あるテーブルのIDが連番になっていなかった部分を1から連番にしたのですが、関連するテーブル(1対多)のIDを1つずつ手動で変更するには量が膨大すぎたので、IDの値を簡単に変更するためのプログラムを組んだので内容を記録します。

##プログラムの内容
・webページ上でCSVファイルをアップロード
・受け取ったファイルの各行1列目(一番左の項目)を配列に保存する
・数値を確認し、値ごとに計算を行う（42~117の間の数値だった場合-10、など）
・計算後の数値を画面に出力

画面に出力された数値をコピペすることで、手元のCSVのIDを一括で修正することが出来ます。

##実装
```app/controllers/csv_controller.rb
class CsvController < ApplicationController
  require "csv"
  def input; end

  def output
    file = params[:file]
    @a = Array.new
    CSV.foreach(file) do |i|
      b = i[0].to_i
      if b
        @a.push(b)
      end
    end
    @a.each_with_index do |value, index|
      if value.between?(5,8)
        @a[index] -= 4
      elsif value.between?(12,28)
        @a[index] -= 7
      elsif value.between?(31,40)
        @a[index] -= 9
      elsif value.between?(42,117)
        @a[index] -= 10
      elsif value.between?(119,300)
        @a[index] -= 11
      end
    end
  end
end
```
`CSV.foreach(file)`で動かない時には`CSV.foreach(file.path)`に変えると動くことがある。

```erb:app/views/csv/input.html.erb
<%= form_with url: csv_path, local: true do |f| %>
  <%= f.file_field :file %>
  <%= f.submit %>
<% end %>
```
```erb:app/views/csv/output.html.erb
<% @a.each do |i| %>
<p><%= i %></p>
<% end %>
```
```app/config/routes.rb
Rails.application.routes.draw do
  get '/csv', to:'csv#input'
  post '/csv', to:'csv#output'
.
.
```

##学んだこと
・`require "csv"`をコントローラー内に書き込むことで、`CSV.foreach`等のメソッド?群が使えるようになる。
・`between?(12,28)`というメソッドで、変数に格納されている数値が12以上28以下かどうかを確認することができる
・ファイルの送信は`f.file_field :file`、受け取りは`params[:file]`でできる。
→Strong Parametersは、DBに値を保存するとき以外は、使わなくてもエラーは発生しない
・配列内の値を編集し、再度代入する時には`each_with_index do |value, index|`が使える
・コントローラー名を単数形にしてしまったが、普通に動いた。
Django関連サイト

#Django

Django本家本元
[DjangoThe web framework for perfectionists with deadlines.](https://docs.djangoproject.com/ja/)

Django本家本元admin
[The Django admin site](https://docs.djangoproject.com/en/3.0/ref/contrib/admin/)

Djangoのユースケース別のプログラミングを調べるのによい
[Aqiliq](https://www.agiliq.com/)
Rails6 開発中のアプリに機能追加をする時は専用のブランチを作ろう

# 目的

- Railsアプリに機能追加する時の筆者の手法をまとめる

# 実施方法概要

1. 機能追加用ブランチの作成
1. 機能追加を実施
1. テスト
1. 機能追加ブランチへの登録
1. 機能追加ブランチをmasterブランチへmerge

# 実施方法詳細

1. 機能追加用ブランチの作成
    1. 下記コマンドを実行してブランチを作成、機能追加ブランチへ移動する。

        ```terminal
        $ cd railsアプリのルートディレクトリ
        $ git branch 任意のブランチ名
        $ git checkout 任意のブランチ名(前述の物と同じもの)
        ```

1. 機能追加を実施
    1. 追加したい機能をコーディングなどを行い追加する。
1. テスト
    1. 追加した機能が正常に動作するかブラウザでの簡単なテストを行う。 
1. 機能追加ブランチへの登録
    1. 下記コマンドを実行して追加した機能用のコードをgitに登録する。

        ```terminal
        $ git add 修正を行なったファイル名
        $ git commit
        $ git push リモートリポジトリの別名(デフォルトならorigin) 任意のブランチ名(前述の物と同じもの)
        ``` 

1. 機能追加ブランチをmasterブランチへmerge
    1. 下記コマンドを実行して`master`ブランチに移動する。

        ```terminal
        $ git chechkout master
        ```

    1. 下記コマンドを実行して機能追加用ブランチの修正内容を`master`ブランチにmergeする。 

        ```terminal
        $ git merge 任意のブランチ名(前述の物と同じもの)
        ```
SICP読書録 #28 2.2.3(続き)マップのネスト - 練習問題2.41

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら]()

## マップのネスト

整数$n$が与えられたとき、$1 \leq j \le i \leq n$で、かつ$i+j$が素数となるような、$i, j$のペアを見つける、という問題を考える。

$i, j$を含む2次元ベクトルをどうにか生成する、というのがこの問題の要点となる。まずは完全なコードを示そう。

``` _.scm
(define (flatmap proc seq)
  (accumulate append nil (map proc seq)))

(define (prime-sum? pair)
  (prime? (+ (car pair) (cadr pair))))

(define (make-pair-sum pair)
  (list (car pair) (cadr pair) (+ (car pair) (cadr pair))))

(define (prime-sum-pairs n)
  (map make-pair-sum
      (filter prime-sum? (flatmap
        (lambda (i)
          (map (lambda (j) (list i j))
               (enumerate-interval 1 (- i 1))))
        (enumerate-interval 1 n)))))
```

`prime-sum-pairs`手続きにおいて、`map`の中で`map`を呼んでいる。このネスト構造により、多次元のベクトルを生成している。

続いて、集合を与えるとそのすべての順列を生成する手続きを作ってみる。

``` _.scm
(define (remove item sequence)
  (filter (lambda (x) (not (= x item)))
    sequence))

(define (permutations s)
  (if (null? s)
    (list nil)
    (flatmap (lambda (x)
      (map (lambda (p) (cons x p))
        (permutations (remove x s))))
    s)))
```

この場合、ベクトルの次元数は集合の大きさによって決まる。`map`内で`permutations`手続きを再起的に呼ぶことでこれを実現しているのだ。

### 練習問題 2.40

$1 \leq j \le i \leq n$となる整数のペア$(i, j)$を生成する手続きを作成する。

``` _.scm
(define (unique-pairs n)
  (flatmap
    (lambda (i)
      (map (lambda (j) (list i j))
        (enumerate-interval 1 (- i 1))))
    (enumerate-interval 1 n)))
```

これさえあれば、`prime-sum-pairs`手続きは以下のように簡単になる。

``` _.scm
(define (prime-sum-pairs n)
  (map make-pair-sum
    (filter prime-sum? (unique-pairs n))))
```
### 練習問題 2.41

次元をひとつ上げて、$1 \leq j \le i \le k \leq n$となる整数のトリオ$(i, j, k)$を生成する手続きを作成する。

``` _.scm
(define (unique-trios n)
  (flatmap
    (lambda (i)
      (map (lambda (p) (cons i p))
        (unique-pairs (- i 1))))
    (enumerate-interval 1 n)))
```

トリオの合計値が指定された値となるものを見つける手続きを作ってみる。

``` _.scm
(define (sum-trio t)
  (+ (car t) (cadr t) (caddr t)))

(define (eq-sum-trios n s)
  (filter
    (lambda (t) (= (sum-trio t) s))
    (unique-trios n)))
```
SICP読書録 #27 練習問題2.37 - 練習問題2.39

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら](https://qiita.com/shuetsu@github/items/f995aea71449e84cd08b)

### 練習問題 2.37

リストのリストで行列を表すことができる。例えば以下の行列は、

```math
\begin{pmatrix}
1 & 2 & 3 & 4 \\
4 & 5 & 6 & 6 \\
6 & 7 & 8 & 9
\end{pmatrix}
```

`((1 2 3 4) (4 5 6 6) (6 7 8 9))`という式で表す。

行列を表せるようになったんだから、行列に対する各種の操作を行うための手続きを作ろう。

まずは内積。

``` _.scm
(define (dot-product v w)
  (accumulate + 0 (map * v w)))
```

行列とベクトルの積。

``` _.scm
(define (matrix-*-vector m v)
  (map (lambda (r) (dot-product r v)) m))
```

転置行列。

``` _.scm
(define (transpose mat)
  (accumulate-n cons nil mat))
```

行列どうしの積。

``` _.scm
(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map (lambda (r) (matrix-*-vector cols r)) m)))
```

### 練習問題 2.38

`accumulate`は、列の最初の要素と、右のすべての要素を組み合わせた結果、を組み合わせる手続きなのだから、`fold-right`と名付けてみよう。

``` _.scm
(define fold-right accumulate)
```

逆方向に組み合わせを行う`fold-left`手続きを以下のように定義する。

``` _.scm
(define (fold-left op initial sequence)
  (define (iter result rest)
    (if (null? rest)
      result
      (iter (op result (car rest))
            (cdr rest))))
  (iter initial sequence))
```

それぞれ実行してみる。

``` _.scm
gosh> (fold-right / 1 '(1 2 3))
3/2
gosh> (fold-left / 1 '(1 2 3))
1/6
```
と、このように結果が異なる。

`fold-right`は`(/ 1 (/ 2 3))`という計算を行っていて、
`fold-left`は`(/ (/ 1 2) 3)`という計算を行っているためだ。

もうひとつ実行例。

``` _.scm
gosh> (fold-right list nil '(1 2 3))
(1 (2 (3 ())))
gosh> (fold-left list nil '(1 2 3))
(((() 1) 2) 3)
```

`fold-left`と`fold-right`が同じ結果となるためには、渡す手続きが交換則を満たす必要がある。

### 練習問題 2.39

`fold-right`と`fold-left`をそれぞれ使って、リストの要素を逆順にして返す`reverse`手続きを作ってみよう。

``` _.scm
(define (reverse1 sequence)
  (fold-right (lambda (x y) (append y (list x))) nil sequence))

(define (reverse2 sequence)
  (fold-left (lambda (x y) (cons y x)) nil sequence))
```