OmniAICreator/Qiita-1.07M huggingface dataset:
DeepLab で Sematic Segmentation する（デモを動かす）

[DeepLab: Deep Labelling for Semantic Image Segmentation](https://github.com/tensorflow/models/tree/master/research/deeplab) で Sematic Segmentation する、と偉そうなことが書いてありますが、デモを動かすところまでです、すいません。

もののけ姫の１シーンを読み込ませてみると、鳥と人と馬というなかなかありそうな判定で面白かったです。
![スクリーンショット 2020-04-15 21.41.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/58d7f4c3-66d6-0cdb-eea1-295a150e79e5.png)

# [Installation](https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/installation.md)

* 基本は書いてある通りに実施する。
    * ただし以下に注意に注意。
* installation の `python deeplab/model_test.py` まで動けば大丈夫

## 注意
1. `pip install tensorflow` すると、現状だと tensorflow ver.2 が入りますが、前提が ver.1 なので、バージョン指定でインストールしましょう。ver.2 でやると[エラー](https://qiita.com/matchyy/items/85e7086d83d578f9bcba)が出ます。
2. `pip install tensorflow-gpu` は gpu版が要らなければ入れなくて大丈夫です。逆に入れると[エラー](https://qiita.com/matchyy/items/dcaebd06291b7ff9884c)が出て動かなくなります。よくわからなかったら、とりあえずスルーした方が無難かもしれません。
2. `sudo apt-get install python-pil python-numpy` は、mac であれば Pillow と numpy が入っていれば大丈夫そう（と信じて実行したら大丈夫だったけで、嘘かもしれません）。確認方法は、 `pip list` て表示されれば大丈夫です。されなければ `pip install` してあげてください。


# DeepLab Demo.ipynb を動かす
1. git clone `url`
2. cd models
3. jupyter notebook deeplab/deeplab_demo.ipynb  
↑を実行すると、ブラウザで勝手に `http://localhost:8888/notebooks/deeplab_demo.ipynb` にアクセスされるはず。
4. run all しろと書いてあるが、run all すると import 不足のエラーが出るので足して（下参照）から実施する。
`run all` は、メニューの `Cell` から選べます。
5. 完了すると入力した画像に合わせて以下のような結果が表示される。
<img width="953" alt="スクリーンショット 2020-04-15 0.22.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/c5881161-945b-5022-09f6-0f7ac8a80d5f.png">


## import の追加
### Select a pretrained model
import tensorflow as tf

### Run on sample images
from six.moves import urllib
from PIL import Image
from io import BytesIO
脱出ゲーム#2　アイテムスロット

##脱出ゲームのアイテムスロットを作ってみました。
アイテムをクリック→かばんにアイテムが入る→アイテムが消える流れを作りました。
（2020/04/15追記　試作のため、粗削り。）

```nazotoki.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="nazotoki.css">
    <title>謎解きWEB</title>
</head>

<body>
    <div id="app">
        <div class="bag">
            {{bag}}
        </div>
        <hr />
        <div class="itembox">
            <div class="ball item" 　v-on:click="onclick('ball')"  v-show="show1" key="ball">ボール</div>
            <div class="banana item" 　v-on:click="onclick('banana')" v-show="show2" key="banana">バナナ</div>
            <div class="key item" 　v-on:click="onclick('key')" v-show="show3" key="key">カギ</div>
        </div>
    </div>

    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="nazotoki.js"></script>
</body>

</html>
```

```vue.js
new Vue({
    el: '#app',
    data: {
        bag: ['〇','〇','〇','〇','〇'],
        show1: true,
        show2: true,
        show3: true,
    },
    methods: {
        onclick: function(kind){
            if (kind === 'ball'){
                Vue.set(this.bag, 0, 'ボール');
                this.show1 = false;
            }else if (kind === 'banana'){
                Vue.set(this.bag, 1, 'バナナ');
                this.show2 = false;
            }else if (kind === 'key'){
                Vue.set(this.bag, 2, 'カギ');
                this.show3 = false;
            }
        }    
    }
});
```

```nazotoki.css
.itembox{
    display: flex;
}

.item{
    width: 60px;
    margin: 10px;
    font-weight: bold;
    border: 1px solid #000;
    border-radius: 2px;
    cursor: pointer;
    cursor: hand;
}

.ball{
    background-color: blue;
    color: white;
}

.banana{
    background-color: yellow;
}

.key{
    background-color: red;
}
```
【書籍まとめ】イラスト図解式 この一冊で全部わかるWeb技術の基本【Chapter2 Webとネットワーク】

# はじめに

みけた＠プログラマー転職です。
元公務員、無職の31歳です！

転職に向けて、まずWebの基礎について理解したいと思い、下記の書籍を読んでいくことにしました。
間違いがあるかもしれませんが、この書籍を読まれる初学者の方にとって参考になれば幸いです。

><a href="https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%B0%8F%E6%9E%97-%E6%81%AD%E5%B9%B3-ebook/dp/B06XNMMC9S">イラスト図解式 この一冊で全部わかるWeb技術の基本</a>
小林 恭平  (著), 坂本 陽  (著), 佐々木 拓郎  (監修)
※ Amazonで、Kindle版が1000円弱で買えます

# Chapter ２ - Webとネットワーク

### ○ Webの仕組みついてのおさらい

改めて、前回のまとめで貼った画像を貼っておきます。
<img width="700" alt="WebArchitecture" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429155/3c364d67-b219-b041-1d49-1f4ff6edf35f.jpeg">  

以上の図のとおり、自宅のPCのChromeやIEなどにWebページが表示されるのは、
ChromeなどのWebブラウザからWebサーバーに対して「〜ページを表示して！」というリクエストが
送られ、それを受けたWebサーバーが該当のファイルを送り返しているからである。

そのやり取りを行うにあたって使われているのが、HTTP（HyperText Transfer Protocol)
という規格や、より安全なHTTPSという規格である。

「〜ページを表示して！」というリクエストの行き先は、統一資源位置指定子！！！
（URLのことです。。。）によって特定され、IPアドレスという番号の羅列に変換されて、
初めてPCが分かる行き先になる。

Webサーバーから送られるファイルは、サーバー内のサーバーサイド言語（Ruby・PHP・Python）
などによって、その都度生成されることがあり、これを「動的ページ」という。

ちなみに、FacebookやInstagramがユーザーごとにカスタマイズしたページを表示できるのは、
Webブラウザから受け取った情報を元にして、動的にWebページを生成しているからである。

### ○ DNSについて

先ほどの説明だと、単純にWebページの表示は自宅のPCとWebサーバーのみで完結しているように
思われる。だが、実際には、IPアドレスを見つける為に、その間にはDNSサーバーが介在している。

単純に自宅のPCがダイレクトにWebサーバーに行けるわけではなく、IPアドレス取得のため、
DNSサーバーへのスタンプラリーを終えなければいけない。

<img width="700" alt="WebArchitecture" src="https://www.nic.ad.jp/ja/dom/img/basics_b.gif"> <br>

これがそのスタンプラリーの様子だ。
会社の稟議のように、DNSルートサーバーを始めとして、多くのDNSサーバーを媒介しなければならない。

ところで、DNSとはDomain Network Systemの略称である。
要は、場所を特定するためのネットワークシステムということである。

文字どおり、場所特定のためのスーパーコンピュータがあるわけではなく、
複数のコンピュータが繋がった形で、それぞれが協力してIPアドレスを特定しているのである。

><a href="https://www.nic.ad.jp/ja/dom/system.html">ドメイン名のしくみ</a>
一般社団法人日本ネットワークインフォメーションセンターHP


### ○ TCP/IPについて

TCP/IPとは、インターネット上のプロトコルの総称を指す。
例えば、以下のようなプロトコルがある。
- HTTP（HTMLのプロトコル）
- FTP（Fileのプロトコル）
- SMTP（メール送信のプロトコル）
- POP（メール受信のプロトコル）

ちなみに、TCP/IPはいくつものレイヤー（層）に分かれている。
HTTPやFTPはアプリケーションというレイヤーに属している。

><a href="https://tomslifestylelab.com/tcp-ip/">TCP/IPとは？初心者がTCP/IPを理解するための完全ガイド</a>
ブログ 「LIFESTYLE LAB（ライフスタイルラボ）」

><a href="https://qiita.com/naoki_mochizuki/items/7ee0e01db61e1e7abd62">[インターネット通信の流れ]</a>
Qiita記事 @naoki_mochizuki
【AndroidStudio】Android sdk is up to dateと表示されてAndroid sdkがインストールできない

### 状況
AndroidStudioが開けなくなっていたため、再インストールしようとした際に発生。

android sdk削除後、Android Studioを再インストールするとsdkがないのに
すでに最新版がインストールされていると認識される
>Android sdk is up to date.

###やっていたこと
android studioをアンインストールし、sdkも削除した。

```sh
rm -Rf /Applications/Android\ Studio.app
rm -Rf ~/Library/Preferences/AndroidStudio*
rm ~/Library/Preferences/com.google.android.studio.plist
rm -Rf ~/Library/Application\ Support/AndroidStudio*
rm -Rf ~/Library/Logs/AndroidStudio*
rm -Rf ~/Library/Caches/AndroidStudio*
rm -Rf ~/.gradle
rm -Rf ~/.android
rm -Rf ~/Library/Android*
```

新規Android studioをインストールしたが、

>android sdk is up to date.

と出てsdkのDLができなかった。
sdkが参照しているフォルダ（/Users/ユーザ名/Library/Android）は存在していなかった。

###結論
```sh
rm ~/Library/Preferences/com.android.Emulator.plist
```

でエミュレータの設定を削除したところ、sdkがインストールできました。
Google Analyticsが正しく設定されているかを調べる方法

Google Analyticsを設定していてよくあるミスとして次のようなものがあります

- 設置したつもりが、データが入ってこない
- 実は狙った値が計測されていなかった
- 二重でページビューが発生した

こういう時に、わざわざGoogle Analyticsを見なくても正しくGAに値が入ったかを調べる方法を以下に伝授します

## ChromeのデベロッパーツールのNetworkに全てがある

#### STEP.1 Chromeのデベロッパーツールを画像を参考に開いてください。
![スクリーンショット 2020-04-14 23.27.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/f4cab826-a5a1-c8a3-b33a-402c6191484f.png)

#### STEP.2 デベロッパーツールの中からNetworkを選んでください
![スクリーンショット 2020-04-14 23.29.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/09407501-367a-070e-8d7f-f83790273caa.png)

#### STEP.3 対象のページ移動、もしくは対象のページでリロードをかけてください

今回はQiitaのトップページを使わせてもらいます。

#### STEP.4 フィルタで「collect」と入力し、「IMG」を選択する

![スクリーンショット 2020-04-14 23.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/1d8a9dde-1f86-4f02-b55e-eed20ce16260.png)

出てきました、下の2つのInitlatorがanalytics.jsの奴がGoogle Analyticsへの通信です。
ここで何も出てこない場合、「設置したつもりが、設置されていない」という事になります。尚、フィルタでXHR等を選択していると、出てこなくて焦るので、ちゃんとフィルタを「IMG」にしてください。

また、最近はSPAでGoogle Analyticsのタグをいれただけでは、いい具合に動かないページも出てきています。
そういう場合は、是非ちゃんと狙ったタイミングでこの通信が発生するかを確認してみると良いでしょう。

#### STEP.5 該当の選択してHeadersの中のQuery String Parametersをみる

試しに「t=pageview」見てみると、UA-24675221-12というGAのプロパティにuid(ユーザーID)293892、cd1(カスタムディメンションの1番)にtrue等が送られていることがわかります。
![スクリーンショット 2020-04-14 23.44.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/55542dbf-18fe-ea6f-ce19-63f0e6eccbcf.png)

ついでに「t=event」も見てみましょう。ec(イベントカテゴリ)にCommunity Sponser(Sponsorの誤字？) List、ea(イベントアクション)にShow、el(イベントラベル)に/、ev(イベント値)に1が送られているのが分かります。
![スクリーンショット 2020-04-14 23.48.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/372d3f5a-1c99-4ef1-0c33-6acc8b10e634.png)

ここでtidが空白が空白だったりすると、データが格納されません。また、設定したカスタムディメンションやイベントカテゴリ等が正しく入っているかを確認してみてください。

具体的にどのパラメータが何を指すかはMesurement Protocolと呼ばれる仕様で決まっています。詳しくは下記を参照にしてください。
https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=ja

## よくあるミス「二重通信を防ぐ」
以下をチェックしてみましょう

- クエリの「t=pageview」の通信でStatusが200の物が2回発生しているかどうか
- 2回発生している場合、クエリの「tid」が同じプロパティ(UA-XXXXXXX-XX)でないか？

同じ場合は二重通信の可能性が高いです。二重通信が行われると、直帰率が下がる可能性が高いです。
Hyper-V上でUbuntu-18.04.3を動かしてZabbixサーバでルータを監視してみる。

# はじめに
Hyper-Vでインストール時にシクると永遠に拡張セッション（Enhanced Session）でログインできなくて
解像度固定に成り、かつその挙動もモッサリしたものになってしまう。
どうせならフル画面かつサクサクした環境が良いよね！Virtualbox使えないわけだし！
そんなわけでUbuntu 18.04のインストールとそのハマりポイントも書き記しておく。

# Ubuntu 18.04インストール時のハマりポイント
クイック作成の一覧に有れば、これをインストールします。
無ければISOをダウンロードかな。
![コメント 2020-05-04 232635.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/09906ef3-ed34-997e-232a-5a6ef3fd9f01.png)

で、Hyper-V上でUbuntuのインストールを進めていくわけですが
ログイン時にパスワードを入力するかどうかの画面で
 **「自動的にログイン」** をつけてしまうと、RDPでログインできなくなってしまう（＝Enhanced Sessionでログインできなくなる）ので **「パスワードを毎回入力する」** にチェックを付けましょう。

# 高解像度ディスプレイの人へ
高解像度(4K)でありながらも物理サイズが24インチ以下の環境では、Hyper-VのEnhance Sessionでつないだ時フォントサイズが非常に小さいと思います。 
なので[このあたりのMethod 2: Through Gnome Tweaks Tool](https://vitux.com/how-to-change-text-size-in-ubuntu/)を参考にして文字サイズを大きくしてしまいましょう。環境に合わせて適当に。  

# 粛々とZabbixのインストールをしていく。
次のハマりどころは
Zabbixのインストールプロセス
https://www.zabbix.com/jp/download?zabbix=4.0&os_distribution=ubuntu&os_version=18.04_bionic&db=postgresql&ws=apache

手順：e. Configure PHP for Zabbix frontend にある
/etc/zabbix/apache.conf のタイムゾーン設定（PHP5/PHP7両方の設定があるので注意すること。新規に立てるならPHP7が入ってくる気がするので、PHP7の方に書かないと、設定されてないよって怒られる。）
![/etc/zabbix/apache.conf](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/ec036bce-3a7e-eb30-022a-99d558dfa3ff.png)

で、apacheを再起動する手順（f. Start Zabbix server and agent processes）をやるとサーバが起動するので
http://localhost/zabbix
にアクセスするとオッケーっぽい。

とりあえず全部OKのハズ。しらんけど。
もしここにないハマり方をしたらその解決策もQiitaに書くと良いと思うんです。


次は、ZabbixのDB接続の設定。パスワードはインストール手順（d. Configure the database for Zabbix server）で打ったパスワードでOK
![コメント 2020-05-04 234730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/fff703bc-4522-6d3a-145c-1e3fac472cd5.png)


うまいこと行けば
Congratulations! You have successfully installed Zabbix frontend.

って出るからインストールは終わり。

ID: Admin
Pass: zabbix

でログインできる。おめでとうこれでスタートラインに立てたよ。やったね。

あとは、Hyper-Vで構築したZabbixサーバを監視対象のLANからのパケットを受け取れるようにルーティング可能なネットワーク（一番ラクなのは物理ルータでルーティングできるネットワークに繋ぐ=[仮想スイッチを物理スイッチ（外部仮想スイッチ）にリンクさせる方法](http://www.vwnet.jp/windows/WS12R2/Hyper-V/Hyper-V_Network.htm)）

あとは[このあたりのQiita記事](https://qiita.com/t-son/items/00006bb84ee687cccb1a)とか[このあたりのRTX830のSNMPテンプレ](https://qiita.com/aske315/items/5c1c5e22d1b58231f4c1)を参考にすると良いと思うっす。
ちなみにこのRTX830テンプレは、SNMPv2を使っているので、RTX830側ではこんなコンフィグを使う。

## RTX830のコンフィグ（例示）
```
# SNMPv2で情報を取得できるホスト(ZabbixサーバのIP)とモード（読み書き）を指定する
# 基本書き込みは必要ないので、読み込みのみ許可する。
# CPUの情報とかを取らせるためにこの設定をする。
snmpv2c host <Zabbix Server> read-only public
# なにか障害が起きたときにトラップするサーバ（Zabbix）を指定する。
snmpv2c trap host <Zabbix Server> inform public 
# システム名を設定する
snmp sysname <System Name>
```
ちなみに、最後の public という文字列は、SNMPのグループ名らしい。
デフォルトがpublicらしい（RTXもZabbixも。明示的に一応指定しておく）

## RTX830のコンフィグ（具体例）
```
# 具体的な設定例(Zabbixホストが192.168.100.50の場合)
snmpv2c host 192.168.100.50 read-only public 
snmpv2c trap host 192.168.100.50 inform public 
# RTX830のLAN1（VLAN）に繋がっているからそんな感じ
snmp sysname RTX830-LAN1 
```
※[参考にしたYamaha公式の設定](https://network.yamaha.com/setting/switch_swx/simple_smart/switch_swx-command/snmp
)

RTX830を監視対象に追加できた！
![Zabbix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/29112ac0-2f92-b077-731c-15092dfd34df.png)
【xcode11】swift5 音声読み上げBMI

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/xcode11?src=hash&amp;ref_src=twsrc%5Etfw">#xcode11</a> <a href="https://twitter.com/hashtag/swift?src=hash&amp;ref_src=twsrc%5Etfw">#swift</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://t.co/BhBRBhgugY">pic.twitter.com/BhBRBhgugY</a></p>&mdash; aa2302 (@aa23021) <a href="https://twitter.com/aa23021/status/1257320887486803971?ref_src=twsrc%5Etfw">May 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><img width="772" alt="スクリーンショット 2020-05-04 23.39.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627010/f53c69cb-a906-82b1-8298-62953a666739.png">

【学んだ点】
・四捨五入で数字を出すにはroundを使う
・音声読み上げ機能はAVFoundationを使う

【メモ】
コードのuttrance.rate は音声の速さを決める
uttrance.voiceのlanguageは言語を決める（ja.JPは日本語）
【Java】参照値渡しという言葉が悪い！

#必ずつまづくJavaの参照値渡し
Javaにおいて、参照渡しは存在しないとよく聞きます。
最初は「えっ」って思いましたが、調べた結果をまとめました。

#一般的なメソッドの引数の渡し方
・値渡し
・参照渡し
・参照値渡し

#Javaにおけるメソッドの引数の渡し方
・値渡し
・参照値渡し
※「参照渡し」はJavaでは存在しません。
「値渡し」、「参照値渡し」について、説明していきます。

#値渡しの例
```java:RefValHandOver.java
private static void editNumber(int arg){
	arg = 0;
	System.out.println("editNumber ： " + arg);
}
public static void main(String[] args) {
	int number = 100;
	editNumber(number);
	System.out.println( "main : " + number);
}
```
##結果
```
editNumber ： 0
main : 100
```
editNumber内では0になっているが、main内では100のままで変わらない。
引数をプリミティブ型にした場合は値渡しとなる。
###プリミティブ型
|  型  |  bit  |  初期値  |
| ---- | ---- | ---- |
|  boolean  |  1bit  |  false  |
|  byte  |  8bit  |  0  |
|  char  |  16bit  | \u0000  |
|  short  |  16bit  |  0  |
|  int  |  32bit  |  0  |
|  float  |  32bit  |  0.0  |
|  long  |  64bit  |  0  |
|  double  |  64bit  |  0.0  |


ここまでは特に問題ないですよね。

#参照値渡しの例
3つのパターンに分類して説明していきます。
・1. メソッド内でデータ操作した場合
・2. メソッド内でnewしなおす。
・3. メソッド内でnullを代入する。


```java:RefValHandOver.java
// 1. メソッド内でデータ操作した場合
private static void methodAddArray(ArrayList<String> arg){
	arg.add("B");
	System.out.println("methodAddArray : " + arg.hashCode() + " : " + arg.toString());
}
//2. メソッド内でnewしなおす。
private static void methodNewArray(ArrayList<String> arg){
	arg = new ArrayList<String>();
	arg.add("C");
	System.out.println("methodNewArray : " +arg.hashCode() + " : " +  arg.toString());
}
//3. メソッド内でnullを代入する。
private static void methodNullArray(ArrayList<String> arg){
	arg = null;
	System.out.println((arg != null) ? "methodNullArray : " + arg.hashCode() + " : " +  arg.toString() : "null");
}

public static void main(String[] args) {
	ArrayList<String> arrayList = new ArrayList<String>() {{add("A");}};
	// 1. メソッド内でデータ操作した場合
	methodAddArray(arrayList);
	System.out.println("main : " + arrayList.hashCode() + " : " +  arrayList.toString());

	//2. メソッド内でnewしなおす。
	methodNewArray(arrayList);
	System.out.println("main : " + arrayList.hashCode() + " : " +  arrayList.toString());

	//3. メソッド内でnullを代入する。
	methodNullArray(arrayList);
	System.out.println((arrayList != null) ? "main : " + arrayList.hashCode() + " : " +  arrayList.toString() : "null");

}
```
##結果
```
// 1. メソッド内でデータ操作した場合
methodAddArray : 3042 : [A, B]
main : 3042 : [A, B]　　　　　　　//参照先が変わっていない

//2. メソッド内でnewしなおす。
methodNewArray : 98 : [C]
main : 3042 : [A, B]　　　　　　　//参照先が変わっている

//3. メソッド内でnullを代入する。
methodNullArray : null
main : 3042 : [A, B]　　　　　　　//参照先が変わっている 
```

##図解してみる
![参照値渡し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621352/d8d9e540-cd34-5d58-9c7a-09b679de8703.png)


##説明してみる
焦点は引数に新しい参照先を___代入___しているかどうかです。
代入されると「main内のローカル変数」と「メソッド内の引数」が別物になってしまいます。
※Javaには存在しない___参照渡し___では2、3の例がmainのローカル変数に反映されます。

#まとめ
___値渡し___、___参照値渡し___について説明してきました。
個人的には参照値渡しを<span style="color: red; ">___参照先アドレス渡し___</span>としたら、わかりやすいんじゃないかと思います。
go mod プロジェクトを go build したら invalid version: unknown revision ってエラーが出たときのメモ

Same as title. go modプロジェクトのあるブランチを `go build` したら

```
$ go build
go: <repo>@v0.0.0-20200503112449-<commit hash>: invalid version: unknown revision <commit hash>
```

というエラーになった。SSHもGOPRIVATEも正しく設定できているはずだ。GithubのWeb上で、commit hashが存在することも確認した。なぜunknown refisionなのか。しばらくハマったが、このIssueがヒントになって解決した。

[cmd/go: invalid version: unknown revision when GOPROXY/GOSUMDB disabled · Issue \#36624 · golang/go](https://github.com/golang/go/issues/36624)

GithubのWeb上では確かにcommitがあったが、実はこれはただのキャッシュである。ローカルで `git show <commit hash>` すると、実はすでにコミットハッシュは存在しない。特定ブランチを指定して `go get` して、その後 `<repo>` 側でそのブランチがdeleteされたらしい。なるほどまさしく unknown revision である。

で、`go get <repo>@master` で更新しようとしても、同じエラーが出て更新されないので、`go.mod` から一度該当パッケージを削除し、改めて `go get <repo>@master` を実行したところ無事に更新できた。

以上。
【Deep Learning】パーセプトロンで作るAND回路

#1. AND回路
　AND回路についての説明は省略する. 入力は２つ, 出力は1つである. 入出力関係を下記の真理値表に示す.

|　入力a　|　入力b　|　出力c　|
|:---:|:---:|:---:|
|　0　|　0　|　0　|
|　0　|　1　|　0　|
|　1　|　0　|　0　|
|　1　|　1　|　1　|

#2. パーセプトロン
　パーセプトロンとはディープラーニングに必要なアルゴリズムである. 複数の信号を入力として受け取り, 一つの信号を出力する.各入力に重みwを加えた値が一定値を超えると信号を出力する. 下記にパーセプトロンのモデルを示す.
![Screenshot from 2020-05-05 15-52-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606887/1cc8d394-5dce-4361-01d6-ba6a76200802.png)


#3. パーセプトロンを用いたAND回路実装（使用言語: Python）
　パーセプトロンによってAND回路を作成する. 下記のコード内の関数ANDがパーセプトロンを表しており, 入力信号と出力信号をmain内で確認している. 下記のコードを実行すると, AND回路と同じ入出力結果が得られることが分かる.

```php:AND.py
# -*- coding: utf-8 -*-

def AND(x1, x2):

    w1, w2, theta = 0.5, 0.5, 0.7 #重み, 値域
    y = x1*w1 + x2*w2             #出力

    if   y <= theta:
        return 0
    elif y  > theta:
        return 1

if __name__ == '__main__':

    a, b = 0, 0      #入力
    c    = AND(a, b) #出力
    print ('入力%d %d 出力%d' % (a, b, c))

    a, b = 0, 1      #入力
    c    = AND(a, b) #出力
    print ('入力%d %d 出力%d' % (a, b, c))

    a, b = 1, 0      #入力
    c    = AND(a, b) #出力
    print ('入力%d %d 出力%d' % (a, b, c))

    a, b = 1, 1      #入力
    c    = AND(a, b) #出力
    print ('入力%d %d 出力%d' % (a, b, c))
```
Revit Test Frameworkを使ったRevitアドインのテスト

#Revit Test Framework (RTF)とは
AutodeskのDynamo開発チームが提供するRevitAPIのテスト機能。Revitのモデルを指定してテストができ、コマンドラインとGUIが提供されています。
Dynamoだけではなく、Revitアドインのテストにも活用できるということなので使ってみました。

#NuGetでパッケージをインストール
NuGetで下記のパッケージをテストプロジェクトにインストールしましょう。

- RevitTestFramework
- NUnit

#テストクラスを書く
例えば、ドアインスタンスを取得するメソッドをテストする場合、ドアの取得数をテストする時、５個のドアを入力したRevitデータ（5doors.rvt）を用意します。

```C#:DoorUtility.cs
using Autodesk.Revit.DB;
using System.Collections.Generic;

namespace FamilyUtility
{
    public class DoorUtility
    {
        public static IList<Element> GetDoorInstance(Document doc)
        {
            var doors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).OfClass(Typeof(FamilyInstance)).ToElements();
            return doors;
        }
    }
}
```

```C#:DoorUtilityTest.cs
using FamilyUtility;
using NUnit.Framework;
using RTF.Applications;
using RTF.Framework;

namespace FamilyUtilityTest
{
    [TestFixture]
    public class DoorUtilityTest
    {
        [SetUp]
        public void Setup() {}

        [TearDown]
        public void ShutDown() {}

        [Test, Category("Door")]
        [TestModel(@".\5doors.rvt")]
        public void DoorInstanceCountTest()
        {
            var doc = RevitTestExecutive.CommandData.Application.ActiveUIDocument.Document;
            var doors = DoorUtility.GetDoorInstance(doc);
            Assert.IsNotNull(doors);
            Assert.IsTrue(doors.Count == 5);
        }
    }
}
```
指定するデータはワイルドカード`[TestModel(@".\*.rvt")]`でも指定できます。

#GUIでテストを実行
NuGetで取得した RevitTestFrameworkGUI.exe を起動しテストを行います。

 - File: 下記の設定をファイルに保存できます。
 - Test Assembly: テストクラスを持つアセンブリを指定します。
 - Results File Path: 結果出力ファイルを指定します。
 - Working Directory: 作業フォルダを指定します。テストデータのカレントになります。
 - Run: テストを開始します。自動でRevitが起動し、テストデータもロードされます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107554/bbd6a95c-5f0f-72ed-12d4-b0369bc21f98.png)

#注意点
指定するテストデータはテストするRevitバージョンで保存しておきましょう。
例えばRevit 2019でテストする場合のテストデータは、Revit 2019で保存したデータでないとダメなようです。

#おわりに
うまく使えば品質管理が効率的に行えると思います。
Revitの起動が繰り返しあるととにかく遅いです。

#参考
- [GitHub - DynamoDS / RevitTestFramework](https://github.com/DynamoDS/RevitTestFramework)
- [The Building Coder - Revit Unit Test Framework Improvements](https://thebuildingcoder.typepad.com/blog/2018/08/revit-unit-test-framework-improvements.html)
- [Dynamo Developer Resources - Testing for DynamoRevit](https://developer.dynamobim.org/04-Testing/4-1-revit-testing.html)
- [AUTODESK UNIVERSITY - Automate Your Revit Add-In Testing with Unit Testing](https://www.autodesk.com/autodesk-university/class/Automate-Your-Revit-Add-Testing-Unit-Testing-2019#downloads)
ふだん使いの dual boot Ubuntu

## 序

最近ではノート PC でもメモリが 16GB 以上のモデルも増え、Linux を扱うにしても Windows や macOS 上に VM として入れたり、Docker container として利用するようなことが多いかと思います。
とはいえやはり VM を利用すると特に IDE と組み合わせて作業するときなどには全体で大量のリソースを必要とし、起動までの待ち時間や操作中のレスポンスも気になってきます。

かたや Windows や macOS の機能がふだんからそこまで必要かというと、Office suite の機能もブラウザで済むようになった今、むしろ UNIX 機能を重視してもよいのでは、と思われてきます。
今回は、Linux をふだんの作業環境として使うための、それこそ 10 年ぶりくらいの、PC への Linux 直接インストールの記録です。

## 目的

ふだん使いの PC 要件を満たしつつ、快適な開発環境の構築を目指します。Linux で。

- 一般的なブラウザ利用
- Netflix などの視聴
- Docker
- Visual Studio Code

## 環境

- [Dell XPS 13 9343](https://www.dell.com/support/home/jp/ja/jpbsd1/product-support/product/xps-13-9343-laptop/overview) (Intel Core i5 5th gen, 8GB memory)
  - 購入から 5 年くらいは経っているものです。
  - もともとの Windows は partition を整理して残し、dual boot にします。
- Ubuntu 19.10
  - 書いている時点で最新 20.04 がリリースされています。

## インストール

ありがたいことにほとんど素のインストールで問題ありませんでした。追加で以下の対応を行いました。

### Wifi driver

使用した Dell XPS 13 では悪名高い? Broadcom の wireless card が搭載されており、Ubuntu を USB 起動で試したときにすでに driver がそのままでは入らないことを確認していました。おそらく [こちら](https://www.maketecheasier.com/fix-wi-fi-not-working-ubuntu/) にあるような "Additional drivers" から入れる方法で対応できるのだと思いますが、今回は SSD の換装も予定していたので、ついでに wireless card を Intel 製のものに置き換えました。これによりあっさり認識され、今のところ不具合も感じられていません。

購入したのは Intel AX200NGW というカードで、Wifi と Bluetooth がついているものです。たしか 2,800 円くらいでした。もともとついているものとほぼ同等の形状で、気をつければ差し替えは難しくありませんが、ケーブルをさすちいさなコネクタの場所がすこし違っていて、長さのあまったケーブルの取り回しに注意が必要でした。(末尾に画像をつけました)

### 日本語入力

Ubuntu 19.10 標準では ibus という framework で入力を受け付けています。日本語入力は Google 日本語入力の OSS 版である mozc を使えるようにするため ibus-mozc をインストールしました。

```
apt install ibus-mozc
```

## トラブル

### 日本語入力

わたしの普段の使い方がちょっとマイナー寄りのせいなのもあるのですが、以下のような不都合が生じました。

- かな入力 で US キー配列 を使用できない (意図しない文字が入力される)
- Shift を含む shortcut が動作しない (設定は可能だが押しても何も起こらない)

これらに関しては残念ながらソースの変更が必要でした。いずれも完全な修正には手間がかかりそうでしたので、ひとまず自分が使うのに不都合ない程度に対応しました。[mozc](https://github.com/google/mozc) は二年ほど前に開発が止まったようで、将来の利用に不安が残ります。

### 音声

音量調整を触っていたら急に「ヘッドホン利用時にだけ左側だけ聞こえない」状態になりました。Windows を起動して試すことでハードウェア故障ではないことはわかり、結局は alsamixer での調整で回復しました。最初に触ったときにはわからず、[ここ](https://www.maketecheasier.com/fix-no-sound-issue-ubuntu/) の解説でたすかりました。 

## で、使い勝手は?

いまのところ、非常によいです。install 直後から Windows をほぼ起動しなくなりました。バッテリーの持ちも Windows に比較して同等か、むしろよいように感じます。

ブラウザは Chrome を利用していますが、Windows での利用にくらべて明らかに軽いです。PC を起動してから使えるようになるまでの時間がかなり短く感じます。Windows 版 Chrome ではこれまた悪名高い "Software reporter tool" の暴走に困ることもままありましたが、そういったものとも無縁なのがうれしいです。
日々 Netflix を観ていますが、音声含め Windows での利用と差を感じません。extension も、そこまでヘビーユーザーではありませんが不都合なく動作しているようです。

Docker も非常にキビキビ動作してとても快適です。こちらは Linux が本家なので当然といえばそうですね。メモリが 8GB ということで、minikube でどこまでいけるかを試してみたいと思っています。WSL で一喜一憂することを考えたら天と地の差を感じます。
VS Code でも今のところ不具合を感じていません。Remote - container extension で local docker container とつないでみましたが、やはり非常に快適です。

長期間利用でどうなるか、様子を見ていきます。まずは 20.04 への upgrade ですね。

## おまけ

今回は、ストレージ容量増加 (250GB -> 1TB) のために SSD の換装と、driver の不安払拭のために wireless card の換装を行いました。左下に見切れているのが SSD (M.2 SATA タイプ)、中央にふたつ並んでいるのが換装中の wireless card です。標準装備のカードでは黒と白のケーブルがつながっているコネクタが左右にひとつずつわかれているのに対し、左の Intel のカードでは右側に寄っているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210165/c0273246-002f-eba0-27ef-f43a748f8065.png)
(MAC address が印刷されていたのでちょっと加工しています)
deviseを使ってアプリに認証システムを導入しよう。

#deviseとは？
railsのgemの一つです。
ユーザーの新規登録、ログイン、ログアウトなどユーザーの認証システムを簡単に導入でき、
SNSのログイン画面のようなものを作ることができます。

Twitterのようなオリジナルアプリを作った際に使いましたので、使い方などを書いていきます。

##deviseの導入方法

```Gemfile.
gem 'devise'
```
Gemfileに記述後にgemをインストールします。

```
$ bundle install
```

deviseの設定ファイルを作成します。

```
$ rails g devise:install
```

config/initializers/devise.rb
config/locales/devise.en.yml
こちらのファイルが作成されます。

##deviseに必要なuserモデルを作成します。
deviseはユーザーの管理機能なので、ユーザーmodelを作成する必要があります。

```
$ rails g devise user
```
こちらのコマンドで作成できます。

app/models/user.rb
db/migrate/20XXXXXXXXXXXX_devise_create_users.rb
test/fixtures/users.yml
test/models/user_test.rb
こちらのファイルが作成されます。
また、ルーティングも自動で記載されます。

```config/routes.rb
Rails.application.routes.draw do
  devise_for :users
```

マイグレーションを反映させます。

```
$ rails db:migrate
```

##devise用のビューを作成する
devise用のビューを作成し、認証機能を実装します。

```
$ rails g devise:views
```

このような画面が作成されます。

[![Image from Gyazo](https://i.gyazo.com/184a1f511366c6f8b2ed2b5dc8ac6dc5.png)](https://gyazo.com/184a1f511366c6f8b2ed2b5dc8ac6dc5)

sign upすることでアカウントを作ることができます。

これでdeviseの説明を終わります。
間違いなどがありましたらご指摘いただけたら幸いです。
最後までご覧いただきありがとうございました。
react-navigation-bottom-tabsの導入でTypeError: Cannot read property 'Provider' of undefinedが表示されるとき

# はじめに
React Nativeで画面の下にタブメニューを作るときにreact-navigation-bottom-tabsを使おうとしてコードは合ってるはずなのに
`TypeError: Cannot read property 'Provider' of undefined`
と表示される場合の対処法です。

# 前提条件
今回対象のアプリは、expoを使って作成しています

# 表示されるエラー
`TypeError: Cannot read property 'Provider' of undefined`

# 対処法
1. react-navigationをアップデート
   `expo install @react-navigation/native`

2. node_modulesを削除
   `rm -rf node_modules`

3. yarnでmoduleをインストール(npmではダメ）
   `yarn install`

# 参考
https://github.com/react-navigation/react-navigation/issues/8166
Laravel 学習したこと

#前提
Laravelで学んだことを書いていきます。

#本題

###fillableプロパティ
メリット
１、不正なリクエストへの対策
例えば、記事投稿画面ではタイトルと本文のみを入力してPOST送信できるようにした場合、
クライアント側でツールなどを使ってそれ以外のパラメーターも含んだ不正なリクエストをPOST送信することは可能。
しかし、fillableプロパティを定義することで、クライアントからのリクエストのパラメーター値をそのまま取り込んで更新しても良いプロパティを制限することができる。
これにより、不正なリクエストによって予期せぬ内容に更新されることを防ぐことができる。

２、コントローラー側にモデルのプロパティへの代入処理をプロパティの数だけ羅列せずに済むようになるという点。

###画像アップロード
```ArticleController.php
public function store(ArticleRequest $request, Article $article)

    $filePath = $originalImg->store('public');
    $article->image = str_replace('public/', '', $filePath);
    $article->save();
    return redirect()->route('articles.index');
      
}
```

getClientOriginalName()→アップロードするファイル名を取得するため
getFilename()→アップロードするファイルの一時的な名を取得するため
getRealPath()→アップロードされたファイルのパスを取得
getClientSize()→アップロードされたファイルのサイズを取得
getClientMimeType()→アップロードされたファイルのmimeタイプを取得
getClientOriginalExtension()→アップロードされたファイルの拡張子を取得

```
$ php artisan storage:link
```

###HTTPのPUTメソッド
新しいリソースを新規作成するか、既存のリソースを置き換える時に使用。

###HTTPのPATCHメソッド
既存のリソースを部分的に変更する時に使用。

###Null合体演算子(??)
例えば、<code>$article->title ?? old('title')</code>となっているコードの<code>??</code>はNull合体演算子と呼ばれるものです。

null合体演算子は、式1 ?? 式2という形式で記述し、以下の結果となる。

式1がnullでない場合は、式1が結果となる
式1がnullである場合は、式2が結果となる

###__constructメソッド
PHPのクラスでは、__constructメソッドを定義すると、クラスのインスタンスが生成された時に初期処理として特に呼び出さなくても必ず実行される。
なお、こういったメソッドをオブジェクト指向のプログラミング言語ではコンストラクタと呼ぶ。

###authorizeResourceメソッド
createアクションメソッドやupdatedアクションメソッドを持つリソースコントローラーであれば、コントローラーのコンストラクタでauthorizeResourceメソッドを使用できる。
authorizeResourceメソッドの第一引数には、モデルのクラス名を渡す。
第二引数には、そのモデルのIDがセットされる、ルーティングのパラメータ名を渡す。

###nullableな型宣言

```php

public function viewAny(?User $user)
```
このように?を付けると、その引数がnullであることも許容される。
PHP7.1から、このnullableな型宣言が使用可能。
Flutter アップデート(for macOS)

久々にFlutterを起動しようとしたときにアップデートをしたい場合のメモです。

# Flutter アップデート方法

doctor を実行する

```
$ flutter doctor
```

実行するとアップデートの通知やIDEのバージョン互換のエラーとか教えてくれます。

```
  ╔════════════════════════════════════════════════════════════════════════════╗
  ║ A new version of Flutter is available!                                     ║
  ║                                                                            ║
  ║ To update to the latest version, run "flutter upgrade".                    ║
  ╚════════════════════════════════════════════════════════════════════════════╝


Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.15.4 19E287, locale
    ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
[!] Android Studio (version 3.6)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.44.2)
[!] Connected device
    ! No devices available

! Doctor found issues in 2 categories.
```

flutter upgrade　でアップデートする

```
$ flutter upgrade
```

アップデートに10分〜とかかるが、エラーが出なければ成功。

念の為バージョンの確認

```
$ flutter --version
```

```
Flutter 1.12.13+hotfix.9 • channel stable •
https://github.com/flutter/flutter.git
Framework • revision f139b11009 (5 weeks ago) • 2020-03-30 13:57:30 -0700
Engine • revision af51afceb8
Tools • Dart 2.7.2
```

以上です。
MacへのGoogleChromeインストールについて

# はじめに
本記事は、私が所有するMacBookへGoogleChromeをインストールしようとした際に苦労したことを記す。

# インストール
- インストーラーは、sufariなどからGoogleのホームへアクセスし、最新バージョンをダウンロード
- ダウンロードした**googlechrome.dmg**をクリックし、Chromeのアイコンをアプリケーションフォルダへドラッグ&ドロップ
- 後は、Finderのアプリケーションから起動するだけ、、、かと思いきや

# どんだけアイコンをクリックしても起動しない！
- アプリケーションを開きますか？と聞かれて*開く*をクリックするものの開かない
- Dockに表示されたアイコンをクリックしても、ピョコピョコアイコンが動くだけ
- うーん、困った、、、ここでGoogle先生の出番

# 起動しない原因と解決方法
- インストーラーがぶっ壊れている
 - 一旦、アプリケーションフォルダからChromeを削除し、インストーラーをダウンロード後、再インストール
- インストールしたChromeに不要なユーザープロファイルが残っている
 - Finderを起動し、メニューバーから*移動*を選択
 - フォルダへ移動をクリックし、フォルダの場所を入力：へ *~/ライブラリ/Application Support*を入力し、*移動*をクリック
 - Googleディレクトリをダブルクリックし、配下のChromeディレクトリの中身をすべて削除する
 - 上記対応だけではダメだったので、Googleディレクトリに存在したChrome Canaryディレクトリの中身もすべて削除
- アクセス権がない
 - Finderを起動し、メニューバーから*移動*を選択
 - フォルダへ移動をクリックし、フォルダの場所を入力：へ *~/ライブラリ/Application Support*を入力し、*移動*をクリック
 - Googleディレクトリを右クリックし、*情報を見る*をクリック
 - 共有とアクセス権：をクリックし、右下のロックを解除
 - *+*をクリックし、Administratorを選択
 - 名前のadminのアクセス権を*読み/書き*へ変更し、⚙をクリックし、*内包している項目に適用*をクリック

以上！
Node + TypeScriptの複数の実行方法（node, ts-node, nodemon, pm2）

プライベート開発時に使う[microsoft/TypeScript-Node-Starter](https://github.com/Microsoft/TypeScript-Node-Starter)の開発環境がwatchなどあり快適。
社内の開発環境もその水準にするために調べた際のメモです。

## nodeコマンドで実行する

tscでトランスパイルして、nodeコマンドで実行します。

```
tsc
node dist/app.js
```

### プロセスを確認

```
xxx     20864   0.0  0.4  4594780  67820 s004  S+    6:38PM   0:00.21 node /usr/local/Cellar/yarn/1.17.3/libexec/bin/yarn.js start
```

## ts-node

tsc + nodeのハッピーセット :fries: :hamburger:

```
ts-node src/app.ts
```

### プロセスを確認

```
xxx     23344   0.0  0.8  4637472 140320 s004  S+   11:23PM   0:03.45 node /usr/local/bin/ts-node --files src/server.ts
```

## nodemon

> node.jsアプリケーションの変更を監視し、サーバーを自動的に再起動します。開発に最適です。

最初はプロセス管理のモジュールだと思ってたのですが、開発用のファイル監視&再起動モジュールだったようです。

### プロセスを確認

```
ps aux | grep nodemon
xxx     22182   0.0  0.2  4560652  30024 s004  S+    9:19PM   0:00.18 /usr/local/bin/node /Users/xxx/works/tsoa-project/node_modules/.bin/nodemon
```

## pm2

> PM2 は、ロード・バランサーが組み込まれた、Node.js アプリケーション用の実動プロセス・マネージャーです。PM2 では、アプリケーションの稼働を永続的に維持して、ダウン時間を発生させずに再ロードすることができる。

pm2でトランスパイルを使うことができるが、本番環境では非推奨とのことです。
[PM2 - Transpilers \| Integration | PM2 Documentation](https://pm2.io/docs/runtime/integration/transpilers/)

pm2コマンドだけでts-nodeの代わりにもなり、watchオプションを使えばnodemonの代わりとしても使えます。（watchの設定はnodemonのほうが使いやすかった）

### プロセスを確認

```
ps aux | grep pm2
xxx      1594   0.0  0.4  4614480  59928   ??  Ss    2:56PM   0:04.33 PM2 v4.4.0: God Daemon (/Users/xxx/.pm2) 
```

God Daemon（神）

## まとめ

|コマンド  |役割  |
|---|---|
|[tsc](https://github.com/microsoft/TypeScript)  |TypeScriptをJavaScriptにトランスパイル  |
|[ts-node](https://github.com/TypeStrong/ts-node)  |TypeScriptを直接実行  |
|[nodemon](https://github.com/remy/nodemon)  |ファイル監視、再実行  |
|[pm2](https://github.com/Unitech/pm2)  |プロセス永続化、ファイル監視  |

開発時の実行環境は `tsc -w + nodemon` または `ts-node + nodemon` がよさげ。
本番の[プロセス管理](https://expressjs.com/ja/advanced/pm.html)にはpm2やfoeverなどを使う。
HTMLメールへのplaintextでの返信で引用部分が1行おきに改行される話

## 状況
- 日々多量に受信する電子メールの多くがHTMLメールである。
- しかしながら、自身はplaintextでの送信、返信をなるべく実施したい(ポリシーみたいなもの)。
- 周囲の標準環境はOutlookだが、自身の肌に合っているMUAはThunderbirdである。
- Outlook 2016 / Thunderbird 68.7.0 / Windows 10

## 解決したい問題
- OutlookのHTML形式で送信されたメールにThunderbirdでplaintextで返信しようとすると、元メールの引用部分に1行おきに余計な改行が入ってしまう。
- 単純に1行おきになるのではなく、もともと空行だった箇所はそのまま1つの空行になる。

元メール(Outlookで書かれたHTML形式)

    こんにちは。
    いつもお世話になっております。
    
    例の件ですが、OKです。
    よろしくお願いいたします。

Thunderbird plaintextで返信しようとしたときの引用文

    > こんにちは。
    > 
    > いつもお世話になっております。
    > 
    > 例の件ですが、OKです。
    > 
    > よろしくお願いいたします。

## 解決策の模索
- Thunderbirdのメール編集画面での置換で直せるか？
  - 上述の通り、「単純に1行おきになるのではなく、もともと空行だった箇所はそのまま1つの空行」となり失われている情報があるため、返信メールの編集画面での解決は不可能。
- 元メールをコピー&ペーストして置換で直せるか？
  - これはうまくいきそう。

元メール(Outlookで書かれたHTML形式)

    こんにちは。
    いつもお世話になっております。
    
    例の件ですが、OKです。
    よろしくお願いいたします。

元メールをテキストエディタにコピー&ペーストしたもの(`[space]`はわかりやすく明示したもの)

    こんにちは。
    
    いつもお世話になっております。
    
    [space]
      
    例の件ですが、OKです。
    
    よろしくお願いいたします。

本来の空行でスペースがひとつ入る親切設計。

テキストエディタで `s/\r\n\r\n/\r\n> /g` (2連続CRLFをCRLFと引用符に置換)して、冒頭に追加で引用符を挿入すればOK。

    > こんにちは。
    > いつもお世話になっております。
    > 
    > 例の件ですが、OKです。
    > よろしくお願いいたします。

これで欲しい引用部分ができた。

## 実装方針の模索
1. Thunderbirdの本体修正やアドオン開発
    - Thunderbird BugZillaを見てもいまいちピンとくるものはなく、11年前が最終更新の [Bug 520755](https://bugzilla.mozilla.org/show_bug.cgi?id=520755) があるくらい。事情を説明して修正に持っていくまではかなり労力がかかりそう。
    - アドオン開発は、可能かどうかの調査を含めて土地勘がなさすぎて今回は見送り。
2. テキストエディタで置換
    - 正規表現での置換ができるエディタであれば何でもできる。
    - 実際これでしばらく運用していたが、「受信メール全体をコピー」→「エディタの画面に移動して貼り付け」→「置換」→「エディタで全体コピー」→「返信メールに貼り付け」という流れがやはり面倒。
3. クリップボードの中身を置換するプログラムでの実装
    - エディタに頼らずクリップボードの中身を置換してしまう作戦。
    - 「受信メール全体をコピー」→「プログラムの実行」→「返信メールに貼り付け」とエディタを使うよりも大分ショートカットできる。
    - プログラム自体の起動はキーボードショートカットでもなんでもよし。
    - 今回はこれでいってみよう。サクッとGoで。

## 仕様とコード
- クリップボードの中身を読んで置換する。改行の前提はCRLF。
- ついでに前後の余計なスペースや空行も除去しておく。

```go:replyfilter.go
package main

import (
	"strings"
	"github.com/atotto/clipboard"
)

func main() {
	var str string

	// Read from clipboard
	str, _ = clipboard.ReadAll()

	// Trim, replace and quote
	str = strings.TrimSpace(str)
	str = strings.Replace(str, "\r\n\r\n", "\r\n> ", -1)
	str = "> " + str + "\r\n"

	// Write to clipboard
	clipboard.WriteAll(str)
}
```

## 使い方

- 適当な名前(replyfilter.exe)で`go build`して実行すればクリップボードの中身が置換される。
- キーボードで何でもしたいなら、exeファイルにショートカットを作って、ショートカットをスタートメニューかデスクトップに置いて、キーボードショートカットを設定するなりなんなり。

## 備考
- 返信でなく転送でも同じような問題があり、対応するならコードの置換のところを引用符を除くようにすればOK。
- 細かい裏取りをしていないが、OutlookとThunderbirdでどっちがRFC的に正しいとかあるのかもしれない。plaintextの市民権がどれほど、ということもあるが、本体でなんとかしてほしい挙動ではある。
- 関連リンク
  - [520755 - explicitly underlined links in html mail corrupted when quoted in plaintext reply](https://bugzilla.mozilla.org/show_bug.cgi?id=520755)
  - [リッチテキスト形式のメールにテキスト形式で返信しようとすると原文の引用 - BIGLOBEなんでも相談室](https://soudan1.biglobe.ne.jp/qa5950901.html)
  - [linux - Every other line is blank when copying an HTML document and pasting it as plain text - Super User](https://superuser.com/questions/689685/every-other-line-is-blank-when-copying-an-html-document-and-pasting-it-as-plain)
クリーンアーキテクチャ【僕の備忘録】

##前書き
クリーンアーキテクチャってよくわからなかったので、自分用に概要まとめてみました。
細かいとこまで理解できてるか怪しい。。

##クリーンアーキテクチャとは
**依存関係が一方通行となるような設計**


下記初見では理解できないと有名な図
![20190708031020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348801/3d033fd4-dc11-8208-1ad8-b0c63c2de295.png)


#各層のイメージ
webページなんでもいいんだけど一旦、Qiitaでイメージしてみる。（このイメージはフィクションです。実際のアーキテクチャとは一切関係ありません。）

**Frameworks & Drivers層**
DevicesとWebとUI→PCでクローム使ってQiitaを見ようとする。
DB→Qiitaの記事情報を保存している。
ExternalInterfaces→記事の中に出てくる広告をAPI経由で取得する。

**Interface Adapters層**
Presenters→MVCのビュー（HTML、CSS、JS）
Controllers→MVCのコントローラー、リクエストの振り分け。
Gateways→実際に外部DBへアクセスする処理（UseCasesのInterfaceを実装したrepositry）

**Application Business Rules層**
UseCases→記事単体の情報取得、記事一覧の情報を取得などビジネスロジックを記載。（外部接続用のInterfaceなどもここ）

**Enterprise Business Rules層**
Entities→記事の情報（タイトル、本文、日付、投稿者など）

##ポイント
**クリーンアーキテクチャで実現したいことは依存の方向を統一し、仮に円の外側のコンポーネントが入れ替わってもより円の中心のロジックには影響を与えないようにすること。**
そのため基本的には依存関係と制御フローは同じになることが多いのでそこを一部調整する必要がある。
例えばDBアクセスのSQLを直接UseCasesに書いておくとすると、DBではなくファイルからデータを取得したいと変更する場合UseCasesを修正する必要がある。そのためUseCasesにはデータを取得するというInterfaceを用意しておきアクセスする先がDBなのかファイルなのかによってGatewaysでそれぞれInterfaceを実装することによってUseCases内に影響を与えなくすることができる。

##まとめ
クリーンアーキテクチャは一つ一つのコンポーネントを分離し依存方向を明確にすることを目的としたアーキテクチャと言える。
HerokuにHaskellで作ったWebサービスを公開する簡単な方法

趣味で作ったWebアプリをHerokuにデプロイしたのですが、4年前にまとめた[HerokuにHaskellのアプリを公開する](https://qiita.com/lotz/items/e5d0dc85363e590f7e2b)に比べてかなりデプロイが簡単になっていたので設定方法をまとめておこうと思います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GW暇だったので簡単なバーチャルオフィスみたいなアプリを作りましたー！バックエンドはHaskellとServantで作ってます✌／<br>lotz84/remote-house<a href="https://t.co/VWPRPtMN87">https://t.co/VWPRPtMN87</a> <a href="https://t.co/CbkZ0IpMss">pic.twitter.com/CbkZ0IpMss</a></p>&mdash; lotz (@lotz84_) <a href="https://twitter.com/lotz84_/status/1257224385536000000?ref_src=twsrc%5Etfw">May 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

設定方法
-------
結論、Dockerを利用したデプロイがとても楽です。

事前にHeroku側のアプリを新規作成しデプロイするWebサービスを用意しておきましょう。ここでは`web-service`という名前のプロジェクトを作成したと仮定しますので以下のファイル名などは適宜置き換えて読んでください。

### 1. `Dockerfile` を用意する

```dockerfile:Dockerfile
FROM haskell:8.8.3

WORKDIR /work

COPY stack.yaml web-service.cabal /work/
RUN stack build --only-dependencies

COPY . /work/
RUN stack build && stack install

CMD web-service-exe -p $PORT
```

`Dockerfile` は様々な工夫の余地が考えられますが、ここでは手軽さを優先して[Haskellの公式イメージ](https://hub.docker.com/_/haskell)を利用しています。Heroku上では効きませんがローカルでのビルド時にキャッシュを再利用できるように依存ライブラリのビルドだけ `--only-dependencies` を使って分けています[^1]。Herokuでは公開されるポートが `$PORT` に設定されているので、この例では実行ファイルに渡しています。最初 `CMD` で `stack exec web-service-exe` のように `stack exec` で実行するようにしていたのですが、これだと起動時に毎回GHCのダウンロードが走ってタイムアウトになってしまっていたので `stack install` でバイナリをインストールしそれを実行する形式に変えました。

### 2. `heroku.yml` を用意する

```yml:heroku.yml
build:
  docker:
    web: Dockerfile
```

`heroku.yml`には実行するコマンドを指定する`run`の項目も設定できますが、省略すれば `Dockerfile` の `CMD` が実行されます。

### 3: Heroku の stack を `container` に設定する

```shell
$ heroku stack:set container
```

あとは普通に `git push heroku master` すればHeroku上で公開されるはずです。

参考: [Building Docker Images with heroku.yml | Heroku Dev Center](https://devcenter.heroku.com/articles/build-docker-images-heroku-yml)

おまけ: Herokuボタンの設定
----------------------

GitHubのREADME等にHerokuボタンを置いておくと誰でも自由に自分のHerokuにそのレポジトリのサービスをデプロイすることができます。Herokuボタンを設置するレポジトリには`app.json`を置いておく必要があり、ここでstackを指定しておくのを忘れないようにしましょう。

```json:app.json
{
  "name": "Web Service",
  "repository": "https://github.com/githubuser/web-service",
  "stack": "container"
}
```

Herokuボタン自体は以下のMarkdownを記載すればOKです。

```md
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
```

参考: [Creating a 'Deploy to Heroku' Button | Heroku Dev Center](https://devcenter.heroku.com/articles/heroku-button)

[^1]: この工夫は[ymyzk](https://github.com/ymyzk)氏の実装を参考にさせていただきました :pray:
Postfixを使ってGmailでメールを転送する

# 久々のメールサーバ設定
かれこれ9年くらいメールサーバ設定はしていなかったのだが、Linuxサーバ上のアカウントからメールすることになった。
今時メールサーバを自前で立てても、世の中に信用してもらえないし、セキュリティ上いろいろ面倒なことが起こっても嫌なので、Postfixを使ってGmailにメールを転送する設定をしてみた。

##必要なパッケージ
まずはPostfix。このサーバはCentOS7をインストールしたのでPostfixは普通に入っている。

```
# rpm -qa | grep postfix
postfix-2.10.1-9.el7.x86_64
```

次にcyrus-saslが以下の4つ分ないとGmailでの認証ができない。

* cyrus-sasl-lib
* cyrus-sasl
* cyrus-sasl-plain
* cyrus-sasl-devel

CentOS7をインストールした状態だと

```
# rpm -qa | grep cyrus-sasl
cyrus-sasl-lib-2.1.26-23.el7.x86_64
cyrus-sasl-plain-2.1.26-23.el7.x86_64
```
2個しか入っていない。なので残りを追加する。

```
# yum install cyrus-sasl cyrus-sasl-devel
```
入ったことを一応調べると

```
# rpm -qa | grep cyrus-sasl
cyrus-sasl-lib-2.1.26-23.el7.x86_64
cyrus-sasl-2.1.26-23.el7.x86_64
cyrus-sasl-plain-2.1.26-23.el7.x86_64
cyrus-sasl-devel-2.1.26-23.el7.x86_64
```
となる。

## main.cfの編集
/etc/postfix/main.cfを編集する

```
# cd /etc/posrtix
# vi main.cf
```
一番最終行に以下を追加

```
myorigin = example.com
myhostname = smtp.example.com
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
inet_protocols = all
smtp_use_tls = yes
smtp_tls_security_level = encrypt
tls_random_source = dev:/dev/urandom
```

## sasl_passwdを編集する
/etc/postfix/sasl_pawwsdを編集する

```
# vi sasl_passwd
[smtp.gmail.com]:587    メールアドレス@gmail.com:パスワード
```
権限をrootだけ読み書きできるように変更

```
# chmod 600 ./sasl_passwd
```

postmapコマンドを使ってpostmap.dbを作る

```
# postmap /etc/postfix/sasl_passwd 
```
できたかな？

```
# ls -al sasl_passwd*
-rw------- 1 root root    60  5月  4 21:23 sasl_passwd
-rw------- 1 root root 12288  5月  4 21:23 sasl_passwd.db
```

##postfixのプロセスを再起動
設定を反映させるためにpostfixのプロセスを再起動する

```
# systemctl restart postfix
```

##Googleのセキュリティ設定を変更する
Googleアカウントのセキュリティ設定で「安全性の低いアプリのアクセス」をオンにしないと行けない。

* [Googleアカウント/セキュリティ](https://myaccount.google.com/securit)　にアクセス
* 安全性の低いアプリのアクセス で　「アクセスを有効にする（非推奨）」をクリック

## 試験してみる
できたかどうか、試験してみる。

```
# mail hoge@example.com
Subject: test
test
EOT
```
ここで、subjectは件名。次の行は本文。EOTはCtrl+dで終了（送信）させると、EOTと出てくる。

hoge@example.com　にメールが届いていることを確認して終了。

とりあえず以上。


2023/05/01 追記
Gmailはアプリパスワードを使用しないと送信できなくなった。
1.Gmailアカウント-セキュリティ-2段階認証プロセス　をONにする必要がある
2.セキュリティ-アプリパスワード　で設定する。（が、GoogleはしょっちゅうGUIを変更するのでこれで次に行けるかどうかは不明）
MacにPythonとpyenvを構築するメモ

Mac に Python のインストールと pyenv で管理する方法を、短くまとめてみました。
忙しい人向けです。

# Python と pyenv のインストール

```
# Homebrewとpyenvのインストール
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install pyenv

# /Users/user/.pyenv から /usr/local/var/pyenv に変える設定
cat << 'EOS' >> ~/.zshrc

# ↓↓↓ heredoc>
export PYENV_ROOT=/usr/local/var/pyenv   
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi
EOS
# ↑↑↑ heredoc>

# リロード
zsh -l  

# Pythonのインストール
pyenv install 3.8.2
pyenv global 3.8.2

# 確認
python -V   
3.8.2
pyenv version
3.8.2 (set by /usr/local/var/pyenv/version)

# バージョンを変えたいとき
pyenv install 3.6.5
pyenv global 3.6.5
python -V   
```

# pyenv でバージョンが切り替わらないとき

失敗例

```
pyenv versions
  system
* 3.6.5 (set by /Users/koji4104/.python-version)
  3.8.2
```

成功例

```
pyenv versions
  system
  3.6.5
* 3.8.2 (set by /usr/local/var/pyenv/version)
```

原因は、過去に local で構築したと思われます。
Finder でユーザー直下にある .python-version ファイルを削除してください（隠しファイルです）

# まとめ
Python と pyenv を構築する手順をまとめてみました。新しい Mac でちょっと Python を実行しようとしたとき少してこずりました。詳しい解説サイトはあるのですが、短くまとめてるサイトが見つからなかったので記事にしました。
今までの学習記録

# 初めに
未経験からAIエンジニアになりたくて絶賛勉強中です

# 簡単なプロフ
- 理系大卒アラサー
- プラント生産設備設計・開発・保全

できること：ハードとソフト両方できます
　　　　　　電気回路、制御回路、化工、PLC、タッチパネル、工事監理

プログラミングはド素人

# 学習記録
- 2019年6月 Python基礎勉強を始める
- 2019年6月～8月　オンライン講座やyoutubeで学習、KaggleのTitanicなどの学習コンペ参加
- 2019年9月~10月 オライリー本などで学習
- 2019年10月~12月 courseraのHow to Win a Data Science Competition受講
- 2020年1月  「Kaggleで勝つデータ分析の技術」、「ゼロから作るディープラーニング」で学習 
- 2020年2~3月　　Kaggleのバスケコンペに参加するもコロナで中止となり落ち込む
- 2020年4~5月　Kaggleの細胞コンペ参加中　←今ココ

あらためて書くともうすぐ1年経つのですね
成長感じない涙

# 勉強時間
2019年6月~12月：約500時間
平均：2時間/日
社会人で月100時間超えしてる方はどんな生活を送っているのだろうか・・・

#教材
**udemy**

・【キカガク流】人工知能・機械学習 脱ブラックボックス講座 - 初級編 - 
・【キカガク流】人工知能・機械学習 脱ブラックボックス講座 - 中級編 -
・[【ゼロから始めるデータ分析】 ビジネスケースで学ぶPythonデータサイエンス入門](https://www.udemy.com/share/101XSEBkcaclpVQ34=/) ←おすすめ
・現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル  
**youtube**
- [Able Programming](https://www.youtube.com/channel/UCh5M2YUAPW7HnpfTUv7XHmA)　←おすすめ

**progate**
Pythonコース

**参考書**
・pythonによるデータ分析入門
・Ipythonによるデータサイエンスクックブック第2版
・Kaggleで勝つデータ分析の技術　←おすすめ
・ゼロから作るディープラーニング 
・達人データサイエンティストによる理論と実践


**coursera** 
[How to Win a Data Science Competition: Learn from Top Kagglers](https://www.coursera.org/learn/competitive-data-science)
講師はロシア人ですべて英語です。講義は英語でもgoogle翻訳先生があるので何とかなりますが、
プログラミング課題は難しいです。
最終課題はKaggleのコンペに参加して一定以上のスコアを取る必要があり、
そのカーネルもEDAやデータリーク対策、アンサンブルなど記述して受講者同士で採点する必要があるため
けっこうハードです。
この講座でKaggleについて一通り学べる良い講座です。
（Kaggleを2~3か月やってからのほうが理解しやすかったかも）

**kaggle**
- [Titanic: Machine Learning from Disaster](https://www.kaggle.com/c/titanic)
- [House Prices: Advanced Regression Techniques](https://www.kaggle.com/c/house-prices-advanced-regression-techniques)
- [Google Cloud＆NCAA®ML Competition 2020-NCAAM](https://www.kaggle.com/c/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament)
- [Predict Future Sales](https://www.kaggle.com/c/competitive-data-science-predict-future-sales) 
- [University of Liverpool - Ion Switching](https://www.kaggle.com/c/liverpool-ion-switching)


# 反省
・ブログなどでアウトプットをやるべきだった
・目標より3か月は遅れている
・朝が弱い。朝活頑張る
・まだ成果がでてない。Kaggleソロメダル獲る
C++ STLコンテナlistを用いてABC66 C問題を解く

競技プログラミングの備忘録用
C++ STLコンテナlistを用いてABC66 C問題を解く

[C - pushpush](https://atcoder.jp/contests/abc066/tasks/arc077_a)

###問題
長さ$n$の数列$a_1,...,a_n$が与えられます。空の数列$b$に対して、以下の操作を$n$回行うことを考えます。$i$回目には数列の$i$番目の要素$a_i$を$b$の末尾に追加する。$b$を逆向きに並び替える。この操作をしてできる数列$b$を求めて下さい。

###制約
- $1≤n≤2×10^5$
- $0≤a_i≤10^9$
- $n,a_i$は整数である。

###入力例
```
4
1 2 3 4
```
###出力例
```
4 2 1 3
```

###方針
毎回reverseして数列を入れ替えては計算量的に間に合わないことがわかる．
そこで，入力例を見ると与えられた順番にlistを用意して後前後前...と順番に繋げれば答えの数列が求められることがわかる．
(上の入力例だけでは気づきにくいのでリンクから入力例を見てください。)

###listの宣言
```c++

list<int> b;
```

vectorと同じ感覚で宣言できる.

###listへの値の追加
前に値を追加したいとき

```c++

b.push_front(追加したい値);
```

後ろに値を追加したいとき

```c++

b.push_back(追加したい値);
```

###list内要素を走査し値を表示

```c++
for(auto i=b.begin(); i!=b.end(); i++){
    cout << *(i) << " ";
}
```

###解法コード
```c++

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for (ll i=0; i<(ll)(n); i++)
#define repd(i,n) for (ll i=n-1; i>=0; i--)
#define all(x) (x).begin(), (x).end()
#define F first
#define S second
#define PF push_front
#define PB push_back
 
int main()
{
    int n; cin >> n;
    vector<int> a(n);
    rep(i,n){
        cin >> a.at(i);
    }
    list<int> b;
    if(n%2==0){
        for(int i=0; i<n-1; i+=2){
            b.PB(a.at(i));
            b.PF(a.at(i+1));
        }
    }
    if(n%2==1){
        rep(i,n){
            if(i%2==0){
                b.PF(a.at(i));
            }
            else{
                b.PB(a.at(i));
            }
        }
    }
    for(auto i=b.begin(); i!=b.end(); i++){
        cout << *(i) << " ";
    }
    cout << endl;
}
```

数列の長さが偶数と奇数の場合で場合分けしている。
Laravel で Class 'PDO' not found エラー出たときの解決方法 

|開発環境|
|:--|
|centos6|
|vagrant|
|laravel7.0|


#はじめに
Laravelで以下のコマンドを打つと
このようなエラーが出たので解決方法を載せておきます。

````
[vagrant@localhost]$php artisan migrate
PHP Fatal error:  Class 'PDO' not found in .. 
````

#原因
php-pdoがなかったからエラーが起きてしまった

#解決方法

````
#php-pdoをyumでインストールする
[vagrant@localhost]$yum install php-pdo

#remiリポジトリを使っている場合はPHPのバージョンを確認する
[vagrant@localhost]$php -v

#バージョンにあったものをインストールする
[vagrant@localhost]$yum install --enablerepo=remi,remi-php73 php-pdo

#yumが使えない場合はインストールしてください
[vagrant@localhost]$yum install
````

これで解決できます！
他の記事も参考にしたい方は
こちらの[<font color="LimeGreen">Laravel で Class 'PDO' not found というエラーが出た場合の対処（CentOS7）</font>](https://qiita.com/hondy12345/items/60066d0bbb71d70a750a)を
ご確認ください。
Kinx アルゴリズム - 挿入ソート

# アルゴリズム - 挿入ソート

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。「プログラム＝アルゴリズム＋データ構造」。アルゴリズムの実装例をご紹介。

元ネタは「C言語による（30年経っても）最新アルゴリズム事典」。今回はソート（挿入ソート）です。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。  

アルゴリズムと言えばソート。挿入ソート。

## 挿入ソート

* https://ja.wikipedia.org/wiki/挿入ソート
    * 遅いが単純、ただしほとんど整列済みのデータに対しては高速
    * $O(n^2)$
    * 安定

### テスト・ドライバ

テスト・ドライバコードは [前回](https://qiita.com/Kray-G/items/bbc1ee89d4bffd4dfe68) と一緒です。

```javascript
function display(name, a) {
    System.println(name, a.map(&(e) => "%2d" % e).join(' '));
}

function demo(N, func) {
    var a = N.times(&() => Integer.parseInt(Math.random() * 100));
    display("Before: ", a);
    a = func(a);
    display("After:  ", a);
}
```

### サンプル・コード

```javascript
function inssort(n, a) {
    var j;
    for (var i = 1; i < n; i++) {
        var x = a[i];
        for (j = i - 1; j >= 0 && a[j] > x; j--)
            a[j + 1] = a[j];
        a[j + 1] = x;
    }
}

demo(20, &(a) => {
    inssort(a.length(), a);
    return a;
});
```

### 結果

```
Before: 78  8 62 49 37 43 22 71 18 74 66 53  0 46 50 69 27  9 20 99
After:   0  8  9 18 20 22 27 37 43 46 49 50 53 62 66 69 71 74 78 99
```

## おわりに

こちらも元ソース（C言語）からほとんど修正していない点は合格。しかも記載通り単純で実装が簡単。また、Kinx でも `&&` は短絡演算子なので、`j >= 0 && a[j] > x` で `j == -1` のとき `a[j]` は評価されないので問題はありません。

ではまた、次回。
【Ruby】おみくじプログラムの仕組みを解説自分用






```
array = ["大吉","中吉","吉","凶"]

a = array.split(",")  #配列arrayの値をカンマで区切る。

b = a.length          # 変数Aの要素の数を数える。

c = rand(b)           #要素の数であるBからランダムに配列の番号(0から始まるやつ)を取得する。

puts a[c]
  #または
puts a[rand(b)]　　　　#配列arrayの値をカンマで区切ったものから、先ほどランダムに取り出した配列番号の値を出力する。
```


もしくは、sampleメソッドを使用して

```
puts ["大吉","中吉","吉","凶"].sample
```
とすると複数の行が1行で済んでしまう。

###ポイント
randメソッドは配列の範囲のランダムな数を持ってくるので、事前にlengthメソッドなどでデータを取ってくる配列の要素の数を知らせておく必要がある。