OmniAICreator/Qiita-1.07M huggingface dataset:
画面上のQRコードをデコードするCsharpのフォームアプリを作る


下記、記事を発展させて、画面上に表示されたＱＲコードを、読みこむフォームを作る

---

QRCodeEncoderDecoderLibraryを用いてQRコードをデコードする（読み込む）Csharpの単体アプリを作る
https://qiita.com/santarou6/items/7b3a449f7f794639f252

---

```c#:qr_decode_frm

//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:QRCodeEncoderDecoderLibrary.dll /target:winexe qr_decode_frm.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using QRCodeEncoderDecoderLibrary;

namespace qr_decode_frm
{
public class Form1 : Form
{

	public Button button1;

	public Form1()
	{
	this.TransparencyKey = this.BackColor;
	button1 = new Button();
	button1.Size = new Size(40, 40);
	button1.Location = new Point(0, 0);
	button1.Text = "★";
	this.Controls.Add(button1);
	button1.Click += new EventHandler(button1_Click);
	}
	
	private void button1_Click(object sender, EventArgs e)
	{
	
	try{
	
	Rectangle rc = this.ClientRectangle;
	Point p = this.PointToScreen(new Point(0, 0));
	double rt = 1.5;  //96dpi_rt=1, 144dpi_rt=1.5
	p.X = (int)(p.X * rt);
	p.Y = (int)(p.Y * rt);
	rc.Width = (int)(rc.Width * rt);
	rc.Height = (int)(rc.Height * rt);
	Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
	var g = Graphics.FromImage(bmp);
	g.CopyFromScreen(p.X, p.Y, 0, 0,rc.Size, CopyPixelOperation.SourceCopy);
	
	QRDecoder   QRCodeDecoder;
	Bitmap      QRCodeInputImage;
	
	QRCodeDecoder = new QRDecoder();
	QRCodeInputImage = bmp;
	byte[][] DataByteArray = QRCodeDecoder.ImageDecoder(QRCodeInputImage);
	
	//string Result = System.Text.Encoding.GetEncoding(932).GetString(DataByteArray[0]);
	string Result = System.Text.Encoding.UTF8.GetString(DataByteArray[0]);
	//string Result = System.Text.Encoding.GetEncoding(51932).GetString(DataByteArray[0]);
	
	MessageBox.Show(Result);
	//Clipboard.SetDataObject(Result,true,20,500);
	
	}
	catch(Exception ex){
		MessageBox.Show("読み取りエラー\n\n"+ex);
	}
	
	}

	[STAThread]
	static void Main()
	{
	Application.EnableVisualStyles();
	Application.Run(new Form1());
	}

}
}

```

結果
<img width="370" alt="kekka.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/107418/0edf5e75-a6d9-ae7d-8525-64e81850c6fe.png">
Android開発にてインターネットに繋がらない場合


##久しぶりに、Androidで開発したらハマったので備忘録。

今更感ですが…。

Androidでインターネットに接続するには、**AndroidManifest.xml**に以下の一文を追加する必要がある。

```
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
```

これが記載されていないと、インターネットに繋がらず、「Permission denied」という文言がLogcatに出力されるだけとなる。
react-native ios Archiveで main.jsbundle エラーが起きた場合の対策 

react-nativeでdebug（シミュレータ）ではbuildできるのに、release buildではerrorがおきて、buildできない場合の対処方法です。

エラー内容: main.jsbundle does not exist

原因: xxx.app 内部にreactnative本体であるmain.jsbundleが無いから

対策: xcodeでTARGETS -> BuildPhases -> Bundle React Native code and images
    そこの NODE_BINARYを変更

```js:
　　 変更前　export NODE_BINARY=node
    ↓
　　 変更後　export NODE_BINARY=/Users/ユーザー名/.nodebrew/current/bin/node 
````


補足: 私はnodeをnodebrewで入れてたので、それが原因だったかなと、nodebrewなしで素のnode.jsだったら、
　　　そのままで良いのだと思います。

以上
Macbook に Debian系 Linux をインストールした後にすること

はじめに
----
Macbook に Debian系 Linux をインストールした際に色々と初期設定することをここにまとめておく。
不定期に更新していくことになる。

fcitx-mozc をインストールする
----
```
$ sudo apt-get install fcitx-mozc -y
```

iSight を使えるようにする
----
iSight は Macbook の内蔵カメラのこと。ファームウェアのコピーが必要となる。
なにか色々と問題がありそうなので、参考になる[リンク](https://unlockforus.com/linux-mint-17-2-rafaela-on-macbook-41-late-2007-isight-webcam/)を貼っておく。
「isight-firmware-tools」と言うツールを使う。

```
$ sudo apt-get install isight-firmware-tools
```
「isight-firmware-tools」を実行してファームウェアファイルを要求されるのでファイルの場所を指定すれば完了。
リブートすれば「iSight」が使えるようになる。cheeseなどのカメラツールで動作確認する。
「isight-firmware-tools」実行時にファームウェアが無いと「isight-firmware-tools」が実行できなくなる。そのためアンインストールしてから再インストールすることになる。

```
$ sudo apt-get remove --purge isight-firmware-tools
$ sudo apt-get install isight-firmware-tools
```

ファンクションキーのデフォルト設定
----
ファンクションキーが「fn」キーを押しながらでないときかない。
「fn」キーを押しながらでなくてもファンクションキーとして動作するようにする設定。

```
$ sudo su
# echo 2 > /sys/module/hid_apple/parameters/fnmode
```
起動時に実行するようにするには、「/etc/rc.local」の最終行「exit 0」の前にでも書いておく。
「/etc/rc.local」に書いたコマンドはroot権限で実行される。
Webpack4 - How to Get Build Mode Parameter?

>Get build mode parameter is a hard way in Webpack4. I found the issues [here](https://github.com/webpack/webpack/issues/6460). Anyway, I got an easy solution.

# 1. Install
```
yarn add -D webpack-mode
```

# 2. Modified package.json scripts part.
```diff

"scripts": {
-    "dev": "webpack --config webpack.dev.js",
-    "prod": "webpack --config webpack.prod.js,
+    "dev": "webpack --mode=development --config webpack.dev.js",
+    "prod": "webpack --mode=production --config webpack.prod.js,
},
```
# 3. Used Example.
```javascript:webpack.common.js
...
const { isProduction } = require('webpack-mode');
...
module: {
    rules: [
      ...
      {
        test: /\.(ico|plist|png|jpg|gif|mp3)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[hash].[ext]',
              outputPath: 'assets',
              publicPath: isProduction ? 'assets' : 'publish/assets', <--- Add code here
            },
          },
        ],
      },
    ],
  },
```
https://github.com/mckomo/webpack-mode
【PHP】APIを使用しQiitaでの自分の投稿を取得する方法。

#Qiitaでの自分の投稿を取得しよう！

今回は、ポートフォリオに学習したことを掲載するためQiitaの投稿を取得しました。そして、取得した内容をブラウザに表示するまでのことを記事にします。
##コード
```index.php
<?php
$curl = curl_init('https://qiita.com/api/v2/authenticated_user/items');
$option = [
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer [取得したアクセストークン]',
    'Content-Type: application/json',
  ],
];
curl_setopt_array($curl, $option);

$result = curl_exec($curl);

$decode_res = json_decode($result);
?>

<DOCTYPE html>
/
/ (省略)
/
<?php foreach($decode_res as $res){ ?>
   <a href="<?php echo $res->url;?>" target="_brank">
     <p><?php echo $res->title;?></p>
   </a>
<?php } ?>
```
基本的にはアクセストークンをQiitaで取得し自分の投稿を取得します。
配列の形になって返ってくるので、foreachで回すだけです。

##Qiitaのアクセストークン取得方法
「設定」⇨「アプリケーション」⇨「新しくトークンを発行する」
この後は、自分が何をしたいのかによって取得するトークンは変わるのですが、今回は投稿を取得するので「read_qiita」でアクセストークンを取得します。

##関数curl()
取得したら実際にコードを書いていきます。
その時に使うのがcurl()関数です。
今回はこちらを使います。
[・curl_init()](http://php.net/manual/ja/function.curl-init.php)
[・curl_setopt_array()](http://php.net/manual/ja/function.curl-setopt-array.php)
[・curl_exec()](http://php.net/manual/ja/function.curl-exec.php)
[・curl_close()](http://php.net/manual/ja/function.curl-close.php)
流れはこう。
1,curl_init()で初期化
2,curl_setopt_array()で色々なオプションを決める
3,curl_exec()で実行
4,curl_close()で終了

##説明
まずcurl_init()にこのURLを「https://qiita.com/api/v2/authenticated_user/item」
ちなみにこのURLは何がしたいかによって変わるのでこちらを参照してください。
[Qiita API](https://qiita.com/api/v2/docs)

そして次にcurl_set_opt()でオプションの設定です。
オプションとはなんだ？って方はまたもやこちらを参考にしてください。
[オプション一覧](http://php.net/manual/ja/function.curl-setopt.php)

ここで使っているオプションの説明だけします。
・CURLOPT_CUSTOMREQUEST⇨HTTPリクエストの方法を指定します。GETだったりPOSTだったり。
・CURLOPT_RETURNTRANSFER⇨curl_exec()の値をデータで返すのか、文字列で返すのかの指定です。trueなら文字列で返します。
・CURLOPT_HTTPHEADER⇨ 任意でHTTPヘッダーを設定できます。簡単にいうとサーバーにリクエストする際の情報をこちらで追加できるみたいな感じですかね。

後はcurl_seopt_array()で配列に格納。
実行したものを＄resultに代入。
このとき$resultはjsonファイルになっているのでjson_decode()でPHPの型にして返します。

それをforeachでぶん回します。

取得したいものはQiit APIで確認してみてください。
capistranoでRailsアプリをdeployした時のエラー　♯プリコンパイル編

capistranoでRailsアプリをdeployしたらエラーが発生したので、その解決方法を備忘録として記述します。
初歩的な内容なのに解決するのにえらい時間がかかった。。。

##実行したこと
ローカル環境で　`bundle exec cap production deploy`　を実行した。

##エラー発生

```
deploy:assets:precompile
　01 $HOME/.rbenv/bin/rbenv exec bundle exec rake assets:precompile
　01 rake aborted!
　01 Uglifier::Error: Unexpected character '`'
(後略)
```

##エラー内容詳細
<dl>
<dt>・エラー文</dt>
<dd>``Uglifier::Error: Unexpected character '`'``</dd>
<dt>・デプロイ実行内容</dt>
<dd>アセットファイルをプリコンパイルした。
人間仕様のソースコードをコンパイラが理解できるように書き直す作業です。
※ちなみにデフォルトで書き直されるアセットファイルは、app/assetsディレクトリの、.jsと.css以外のファイルみたい。ただし、application.jsとapplication.cssはコンパイルされるとのこと。</dd>
<dt>・エラー内容</dt>
<dd>JavaScriptコード軽量化Gemの`Uglifier`がエラーを起こしている。
``'`(バッククォート)'``ってなんですか〜？って感じでしょうか。</dd>
<dt>・原因</dt>
<dd>今回はjsファイルでテンプレートリテラル記法を採用しており、ここで``'`(バッククォート)'``を使っているためエラーが発生していた。
要はテンプレートリテラル記法は比較的新しい記法のため、デプロイする際にエラーになる。</dd>

##解決方法
`config/environments/production.rb`の
`config.assets.js_compressor = :uglifier`
をコメントアウトしました。

だって、テンプレートリテラル便利だから使いたい。。。
if let さっぱり分からん☆（＾～＾）

`cargo clippy` とかしてるとお前の `match` 構文よりもっと良い `if let` というもっと簡潔な書き方がある、とオヌヌメが入ってくる。

[if let](https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/if-let.html)

rust は ヌル なんか使わない言語なんで

```
let mut fruit: Option<String>;
fruit = Some("Applet".to_string());
fruit = None;
fruit = Some("Banana".to_string());
fruit = Some("Casava".to_string());
```

Option にくるんで Some か None で分ける。
Some なら中身は有るし、 None なら中身は無い。

そこで中身を使うために

```
let mut fruit;
match fruit_box {
    Some(content) =>{
        fruit = content
    },
    None => {},
};
```

といった `match` 構文を使ったときに　Ｏｈ，ｍｙ　ｇｏｄ！　といった感情が表される☆
この書き方はヘタクソなのか。フーム☆（＾～＾）

りくつでいうと、以下のように書けばいいらしい。

```
if let Some(content) = fruit_box {
    fruit = content
};
```

うーむ☆（＾～＾）
Some(content) と None しかないのだから、 match にするまでもないから if なのか☆

if文の条件式のところに `==` ではなく `=` があるので　違和感　があるが、
`if` 文は　条件分岐　で、
`if-let` 文は　Some の中身を取り出すだけで　別物だな☆（＾～＾）
回帰予測で多ラベル・複数項目を出力させたい！

プロジェクトで｢多ラベルの回帰予測｣をしなければならないことになりました｡
※機械の自動運転なのですが､調整する値が20個ほどある

ですが､多ラベル出力に対応していないregressorが結構あるので
その時に使ったscikit-learnのMultiOutputRegressorについて書いていきます！

[ドキュメント](https://scikit-learn.org/stable/modules/generated/sklearn.multioutput.MultiOutputRegressor.html)

# 回帰予測で他ラベル出力するには
回帰予測で他ラベル出力するにはいくつか方法があります。

**1.  元々他ラベル出力に対応しているRegressorを採用する**
　→scikit-learnのRandomForestが代表的ですが、もともと他ラベル出力に対応しているものがあります。
　　これを使えば、複数のラベルが入ったデータを学習データとして与えても大丈夫！

**2.  ニューラルネットワークを使う**
　→ニューラルネットワークは隠れ層や出力層の数を変えられるため、当然出力層の数を変えれば多ラベル出力も可能です。
（私はニューラルネットワークを使ったことがないクソ雑魚のため、この案はスルーしました）

**3. scikit-learnのMultiOutputRegressorを使う**
　→これを使えば多ラベル出力に対応していないRegressorも出力させることができます。

## RandomForest　おっそ...
いや、これなんですよね...
上の方法を見たとき「いや、じゃあRandomForest使えよ」って思いませんでした？
私も最初RandomForestで頑張ってたわけなんですが学習遅くね...?ということなんですよ。
精度は別に悪くないと思うんですけどね。

そこで、kaggleで使ったことのあるLightGBMを使ってみたところ、**クッソ爆速**。
<img src="https://qiita-image-store.s3.amazonaws.com/0/160512/1183e62b-3913-fe95-6cb7-21d23585cc38.png", width=60%>


「じゃあ、LightGBMに変えよー！」と思ったらLightGBMは多ラベル出力に対応してないんですね...
そのままデータを渡して学習させようとするとValueErrorになってしまいます。

```
ValueError: DataFrame for label cannot have multiple columns
```

## そういう時にMultiOutputRegressorなんすわぁ
そういう「使いたいRegressorがあるけど多ラベル出力に対応してない」時に使えるのが`MultiOutputRegressor`!!
使い方は正直めちゃくちゃ簡単です。
例えばLightBGMで以下のように書いて、`y`がラベルだとしますよね？

```python
import lightgbm as lgb

params={'learning_rate': 0.05,
        'objective':'mae',
        'metric':'mae',
        'num_leaves': 7,
        'verbose': 0,
        'bagging_fraction': 0.7,
        'feature_fraction': 0.7
       }

reg = lgb.LGBMRegressor(**params, n_estimators=500)
reg.fit(x, y)
```

これが、こう！

```python
from sklearn.multioutput import MultiOutputRegressor
import lightgbm as lgb

params={'learning_rate': 0.5,
        'objective':'mae', 
        'metric':'mae',
        'num_leaves': 9,
        'verbose': 0,
        'bagging_fraction': 0.7,
        'feature_fraction': 0.7
       }
reg = MultiOutputRegressor(lgb.LGBMRegressor(**params, n_estimators=500))

reg.fit(x, y)
```

そう！LightGBMのオブジェクト作成するところを`MultiOutputRegressor()`で包むだけです。
これだけで、多ラベルデータを学習・予測できるようになります。やったぜ。

# 課題？
MultiOutputRegressor使っていて問題とまでは言いませんが感じたことを書いていきます。

## 各ラベルの予測モデルよりは精度が落ちている気がする
これ、当たり前といえば当たり前な気がしますがそんな気がします。
MultiOuputRegressorを使わずに、ラベルの数だけモデルを作って予測させた場合と比べると
やはり少しですが精度が落ちてます。

これは、モデルをひとつにすることで、本来必要ないデータも学習することになるからだと思います。
あるラベルでは必要ないデータでも、他のラベルの学習に必要なデータであれば全て学習データに含める必要があります。
**結果的に、各ラベル単位で見ると無駄に多い学習データを使っていることになります。**

MultiOuputRegressorの内部的な仕組みとしては、ラベルの数だけ独立して予測させているようなので
やはり不要なデータが増えているのが要因なんでしょうなあ。

## feature_importanceが使えない
これも仕方ないのかもしれませんが、特徴量選択によく使うので使えないのは困ります。
私はfeature_importanceを見るためだけに各ラベルごとのモデルを作って見てました。二度手間。
（上でも書いたように、内部的にはラベルごとに独立で動いているので結果はほとんど同じはず）

for文ぶん回して放っておくだけなので言う程手間でもないんですが、
やはりMultiOuputRegressorで包んだやつから直接見れたらラクなのになーとは思っちゃいますね。

# 終わり
とはいえとはいえ、導入も物凄く簡単で便利なので、ぜひ使ってみてくださいー！
rails s 時のエラー (Gem::GemNotFoundException)

Railsアプリ作成中に、rails sでサーバー起動しようとしたら、Gem::GemNotFoundException エラー。
とくになにかしたわけではないが、突如発生。
stack overflowで似たようなエラー事例があったので、参考にし、解決。
[参考：stack overflow](https://stackoverflow.com/questions/52051122/cant-find-gem-railties-0-a-with-executable-rails-gemgemnotfoundexceptio#)
rails s 時のエラー。

```
Traceback (most recent call last):
   4: from /home/ec2-user/.rvm/gems/ruby-2.6.0/bin/ruby_executable_hooks:24:in `<main>'
   3: from /home/ec2-user/.rvm/gems/ruby-2.6.0/bin/ruby_executable_hooks:24:in `eval'
   2: from /home/ec2-user/.rvm/gems/ruby-2.6.0/bin/rails:23:in `<main>'
   1: from /home/ec2-user/.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/home/ec2-user/.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem railties (>= 0.a) with executable rails (Gem::GemNotFoundException)
```
以下で解決。

```
gem install bundler
bundle install
```
Djangoのチュートリアルをする前に知っておけばよかったこと

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている梅原です。
今回は僕がdjangoチュートリアルをやってみて、あまりにも効率の悪い勉強をしていたと後悔したので、これからdjangoの勉強をされる方に向けて書きたいと思います。
特に、web系のプログラミングがはじめてという方に向けてかきます。
　ですので、御経験ある方（Railsとか）は時間の無駄なので飛ばしてください！

#そもそもdjangoとは
djangoはwebフレームワークです。フレームは骨組みの意味です。
ウェブページを作るときにはかなりの作業が必要で、それの共通する部分を自動生成しちゃって楽しよう！っていう感じです。だから、djangoは「プログラミング言語」ではないんですね。

###ここで一つ注意！
先ほど、共通部分を自動生成と書きましたが、様々なwebアプリケーションを作るので、応用がきくようにファイルの構成やデータの受け渡しの部分で、初心者の方からすると複雑に感じるポイントが結構あります。djangoのチュートリアルをする場合はアナログなノートに手書きでデータのやり取りやディレクトリ構成をメモして、頭の中を整理しながらやっていきましょう！

#まず理解してほしいポイント~Webページの仕組み~

webページの仕組みをまず理解しましょう。
簡単にいうと、[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)←をクリックしてみると、「サーバー」という機械にインターネットを通じて「リクエスト」が送られます。

・リクエストはその名の通り、「こんな情報（webページ）を見たい」という要求です。

・サーバーは「リクエスト」を受け取り、求められている情報（写真や文字データ）をユーザーに返します。

djangoはこのサーバーの中で動くプログラミング言語pythonのフレームワークです。

#次はサーバーの中身の動き（django）を見てみる。
[この記事](https://qiita.com/maisuto/items/bcdb0fd6c63cf0c544d6)がとてもありがたかったです。
この全体像の部分をお手元のノートやメモ帳にメモしてから、チュートリアルを進めてください。


#まとめ
とても内容の薄い記事でしたね（笑）
でも、ぼくはこの全体像というか、データの流れをとらえずにチュートリアルの細かいところ（ｺｰﾄﾞの書き方とか）ばっかりに目が行ってしまい、自分でいざ実際にアプリを作るときに、拡張が全く効かない状態になってしまいました。
チュートリアルを何周かしてみて、
１（コピペ：全体像を把握）　２（写経：なるべく、この追加したｺｰﾄﾞでなにが起こっているのかを把握するように努める）　３（写経：２で分からない部分があれば、こべつで検索して理解を深めましょう）４（自作アプリ）
みたいな感じでいいと思います。

なお当方もdjango始めて２週間ですので、間違っている部分もあるでしょうが、そのときは教えていただけると嬉しいです！
YAMAHA RTX1200 パケット転送フィルター

仕事でパケット転送フィルターを触ったのでちょっとまとめてみます。
基本的にはRTProにすべて書かれていますが、よくわかっていないので個人的な整理のために書きます。

# パケット転送フィルターとは
* 特徴  
  * ルーティングテーブルに関わらず、ルーティングする前に独立して動作する。
  * ロードバランスはできないらしい。
  * YAMAHA以外ではこのようなパケット転送のやり方は見つからなかったけど、ポリシールーティングに近いものなのかな・・・。
  * YAMAHAでもフィルタ型ルーティングでポリシールーティングができるし負荷分散もできるから正直出番は少ない？
  * IPv4のみ対応
  * 指定できるゲートウェイの種類はルーティングよりも狭い

* 処理の順序  
    受信NAT→受信フィルタリング→パケット転送フィルター（条件に合致しない場合はルーティング）→送信フィルタリング→送信NAT

# 実際に入れるコマンド

ここでは例として

LAN1:192.168.10.1
LAN2:172.16.0.1
PP1,PP2を使用

とします。

* フィルタリングしたい条件  
 * LAN1はPP!へ
 * LAM2はPP2へ

```
IP LAN1 foward filter 100
IP LAN2 foward filter 100

ip filter 10 pass 192.168.10.0/24 * * *
ip filter 20 pass 172.16.0.0/24 * * *

ip foward filter 100 1 gateway pp 1 filter 10
ip foward filter 100 2 gateway pp 2 filter 20
```

# 冗長化について
keepaliveを入れると冗長化ができる。

```
ip keepalive 1 icmp-echo 5 3 8.8.8.8
ip keepalive 2 icmp-echo 5 3 8.8.4.4

ip foward filter 100 1 gateway pp 1 filter 10 keepalive 1
ip foward filter 100 2 gateway pp 2 filter 20 keepalive 2
ip foward filter 100 3 gateway pp 2 filter 10
ip foward filter 100 4 gateway pp 1 filter 20
```
keepalive 1がDownした場合、foward filter 3が有効になるようなイメージ。フィルタ番号が若い順に評価される。
キープアライブ先はISPのDNSとか指定すればいいと思ってる。
例としてGoogleのパブリックDNSを指定している。

# ルーティングについて
* ルーター自身のパケットはパケット転送フィルターでは処理されずルーティングテーブルによって処理される（YAMAHAサポートより）らしいので、それぞれルーティングも追加しないといけない。そのため、別途デフォルトゲートウェイとKeepalive先へのルーティング設定が必要。
* DNSやNTP、http revision-up goなどを使う場合は忘れずに設定する。

```
ip route default gateway pp 1
ip route 8.8.8.8 gateway pp 1
ip route 8.8.4.4 gateway pp 2
```

# 感じたこと
* そこそこ柔軟性がある上、ルーティングテーブルをいじらないのがメリットのような気がする。
* YAMAHAの機能の中では正直使いづらい部類な印象。
* 他人が見たときに一見して何してるかわからない。
* コンフィグを一覧した際にルーティングと離れて記述されているため見落とす場合がある。
【iOS】UIButtonにON/OFFのスイッチ処理を１行で書く【Swift】

**UIButtonに「on/off」のスイッチを付与したい...**

**けどいちいちフラグ立てるのはスマートじゃない...**

**それに複数のUIButtonにon/offのスイッチを持たせるとなったらｱｰｯ**

ってことで、UIButtonにon/offのスイッチを持たせたい時に、簡単一行でon/offのスイッチを実装するコードを書いたので（誰でもやってるかもしれないけど）晒したいと思います。

|sample|
|:------:|
|![button.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310527/9933b3a4-b7c6-a876-6e97-d0773d81d64d.gif)|

##開発環境
- Swift5.0
- Xcode10.1

##目的

UIButtonにON/OFFのスイッチ機能を持たせたい時に、下のように書くのはスマートじゃない。

```ViewController.swift

    @IBOutlet var label: UILabel!
    
    var flag: Bool = false
    
    @IBAction func tappedButton(_ sender: UIButton) {
        if flag == false {
            //ONにする時に走らせたい処理
            label.text = "ONになったよ！"
            flag = true
        } else if flag == true {
            //OFFにする時に走らせたい処理
            label.text = "OFFになったよ！"
            flag = false
        }
    }
```

ボタン１個だけなら良いかもしれないが、何個ものUIButtonにスイッチ機能を持たせたい時は全部に同じコードを書く羽目になる。~~あと誰でも考えつきそう~~

`UIButton.switch(on: , off: )`みたいな感じで一行で書きたい（切実）

##解決法：UIControlのisSelectedプロパティを利用してExtensionを書けば良い（2019年5月更新）

>そんなわけで解決法を「Extensionでなんとか実装できないかなー...」と思って頑張ってみたんですがダメでした（）
>
>**どうしてもUIButtonのインスタンスに状態を保持するプロパティを持たせる必要があったので、インスタンスプロ>パティを追加することができないExtensionでは実装は難しそうです。**Extensionで出来る方法あればぜひ教え>てください（懇願）

Extensionで出来ました（白目）
UIButtonのスーパークラスであるUIControlが、「isSelected」という選択された状態を保持するプロパティを持ってました（）
クラスを作る必要はなかったというか愚策だったというか、無知でしたすいません（土下座）

というわけでUIButtonのExtensionで改めて書くとこんな感じになります。

```ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBOutlet var label: UILabel!
    
    @IBAction func tappedButton(_ sender: UIButton) {
        
        sender.switchAction(onAction: {
            self.label.text = "ONになったよ！"
        }) {
            self.label.text = "OFFになったよ！"
        }
    }

}

extension UIButton {
    
    func switchAction(onAction: @escaping ()->Void, offAction: @escaping ()->Void) {

        //選択状態を反転
        self.isSelected = !self.isSelected
        
        switch self.isSelected {
        case true:
            //ONにする時に走らせたい処理
            onAction()
        case false:
            //OFFにする時に走らせたい処理
            offAction()
        }
        
    }
}
```

これをそのままコピペして、Storyboardで@IBAction接続しているUIButtonのクラスにselectedSwitchを指定してあげれば動きます。(あとテスト用のlabelも@IBOutlet接続してるのでそれもお忘れなく)

ちなみにUIControl.isSelectedプロパティは「選択された状態＝Buttonが押されたらONにする」という仕様なので、「ON状態のButtonをOFF」にするという処理は自分で書く必要があります。

```swift
//extension UIButton {....
//func switchAction(...

選択状態を反転。ONだったらOFF、OFFだったらONに切り替える処理を入れてます。

self.isSelected = !self.isSelected

//switch ...
```

そんなこんなでこのExtensionでどのUIButtonでも一行でon/offスイッチが書けるようになりました。

他に良い方法あれば教えて頂けると嬉しいです！
ちょまどさんとロッシェルさん『マンガでわかる外国人との働き方』出版記念イベント開催！

# これ
![51ad8165de124816d46c24bc3ecd1f31.png](https://qiita-image-store.s3.amazonaws.com/0/134953/97f9f45d-fa62-dca1-71fa-b326920aed1b.png)
2019/3/22(金)に「**外国人との英語での働き方講座**」というイベントが開催されたのだが、
これがちょっとした**祭り**だったのでまとめる。

# 経緯
![D1JYkv2UYAEv3Ip_arr.JPG](https://qiita-image-store.s3.amazonaws.com/0/134953/99957045-379e-237e-c3d2-492b1b2fcfaa.jpeg)

* 3/07(木)
  * MicrosoftのDeveloper Advocateである[ちょまどさん](https://twitter.com/chomado)と「[英語の品格](https://www.amazon.co.jp/英語の品格-インターナショナル新書-ロッシェル-カップ/dp/4797680121/)」の[ロッシェルさん](https://twitter.com/JICRochelle)が、何かを企んでいることをほのめかす
* 3/12(火)
  * ちょまどさんが**人生初となる主催イベント**を開催することを発表
* 3/13(水)
  * イベントの募集をかけていないのに100名の枠が埋まる**（※何を言ってるのかわからねーと思うが、IT勉強会のポータルサイト[connpass](https://connpass.com/)にイベントが登録されたことを察知して瞬時に申し込んだ人が100人以上いて、twitterで告知する頃には時既に時間切れ）**
* 3/14(木)
  * イベントのキャンセル待ちが200人を超え、イベントの再演が決定（再演は200名に増枠したが現状600名近くが応募中）
* 3/18(月)
  * ちょまどさんが「重大発表をする」とツイート
* 3/19(火)
  * ちょまどさんがロッシェルさんとの共著本「**[マンガでわかる外国人との働き方](https://www.amazon.co.jp/マンガでわかる外国人との働き方-ロッシェル・カップ/dp/4798057282/)**」を出版することを発表、同時に手作りの[販促動画](https://youtu.be/d8j59mWCXDo)が公開される （この時点でイベントの実態は出版記念イベントだったことが判明）
* 同日
  * 本は瞬く間にamazonでベストセラーを獲得
* 3/22(金)
  * 予定通り無事にイベントが開催され、盛況で幕を閉じた

# 客層
![D1JYkv2UYAEv3Ip_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/134953/47eb67bd-76c7-802e-d074-46c4831ecc57.jpeg)

**20代中盤～30代の会社員男性**と思わしき人が多い。
100人の枠に滑り込んだ人間は間違いなくconnpassユーザ（つまりイベントに慣れている人）のはずだから、きっと「今日は楽しみっすね～あ、これ僕の名刺っす、おにいさんは普段何されてんすか～？」みたいなノリでワイワイやってるのかと思ったら、みんな静かに着席しててびっくりした。（開場前はそうでもなかったのかな？）

# イベント内容
![D2QZ5jVUYAE-vYT_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/134953/22e5c4da-c80f-91fd-b5b4-15ff99e6e1f6.jpeg)
（@imaeさん撮影）

登壇者は全員ユーモアに溢れていて、非常に良い雰囲気。
大筋は、外国人からみた日本人あるあるを交えながら、ロッシェルさんが実際に使える英語を教えてくれる、という流れ。

ジョークもバンバン飛んだ。
ロッシェルさんはとある会議でちょまどさんと出会い、ちょまどさんのことを**Microsoftが開発したロボット**だと本気で勘違いしていたらしい。
ダニエルさんは**ドリキャスのあるソフト**が好きで日本語を勉強し始めたとのこと。何だろうね。**検討もつかないね**。

今回不安だったのは「**多国籍な状況に置かれる可能性がおそらくない自分にとって参考になるのか？**」ということ。しかし意外や意外、実際は日本での働き方を見直させられるような話ばかりだった。
「**会議で発言しなかった人は次回から呼ばれない**（その人の貴重な時間を無駄に奪ってしまうから）」という話や、「分からないときは分からないとハッキリ言って欲しい」、「日本人は外国人から『過労死』という言葉の意味を聞かれる」などなど。

ちょまどさんはとにかく体当たりでこなすタイプだが、それを背景とした精神論を語ったりしない。あくまで自分の恥をさらけ出すことに終始するため、嫌味がない。
ロッシェルさんは日本企業の経営コンサルをしていることもあり、「**ここが変だよ日本人**」というような陳腐な批判は一切なく、優しく手ほどきしてくれる感じ。
ダニエルさんはアイルランド人であり、特に多種多様な人々と働いているため、「米国と比べた日本」に留まらなかったのも好印象。一人一人のバックグラウンドを見極めなければならないということを言っていたが、それは果たして多国籍企業だけだろうか…？

イベント内容を一言で言うと「**エキシビジョン**」。
無知でも楽しめ、肩肘張らずに参加できる、とても敷居の低いイベントだった。

最後に書籍即売会＆サイン会も行われた。
![D2RDYQkU8AAvoz9 (keigo.M @cyan_oooo_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/134953/c1f5e398-ffb0-f4c9-5938-40ed0ba8fc52.jpeg)
（@cyan_ooooさん撮影）

# まとめ
* ちょまどさんテンションたけぇ！
* ロッシェルさんはほんと優しくて気遣い上手！
* ダニエルさんはしっかり者で上手に話をまとめてくれてた（日本語上手すぎ！）
* 愛用してるVAIOにサインしてもらえた！

![IMG_0152_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/134953/fd7e4fe1-4490-a3cd-3340-1292772a4532.jpeg)

* 書籍は[コチラ](https://www.amazon.co.jp/マンガでわかる外国人との働き方-ロッシェル・カップ/dp/4798057282/)から購入可能（日本人の働き方を考えさせられる良書、英語の例文も優秀）
* 再演は[コチラ](https://connpass.com/event/124362/)から応募可能（再演は早い者勝ちではなく抽選、4/5(金)まで申込可能）

参加された皆様、お疲れ様でした！
古めのcmakeでOpenSSL 1.1.0系をfind_packageしたい場合の対処

## 環境

- cmake version 2.8.12.2
- OpenSSL 1.1.1b  26 Feb 2019(ソースコンパイル)

## OpenSSLをインストールしてあるのに、なぜかfind_packageで見つからない

毎回cmakeのパッケージ検索をするのが面倒だったのでfind_packageを仕込んだはいいんですが、以下のようなエラーが出てしまい見つかりませんでした。
ちゃんと対象のファイルは環境下にインストールされているのに。。。

```
-- Configuring incomplete, errors occurred!
See also "/home/developer/work/EncryptedEditor/build/CMakeFiles/CMakeOutput.log".
CMake Error at /usr/share/cmake/Modules/FindOpenSSL.cmake:278 (list):
  list GET given empty list
Call Stack (most recent call first):
  lib/src/CMakeLists.txt:5 (find_package)


CMake Error at /usr/share/cmake/Modules/FindOpenSSL.cmake:279 (list):
  list GET given empty list
Call Stack (most recent call first):
  lib/src/CMakeLists.txt:5 (find_package)


CMake Error at /usr/share/cmake/Modules/FindOpenSSL.cmake:281 (list):
  list GET given empty list
Call Stack (most recent call first):
  lib/src/CMakeLists.txt:5 (find_package)


CMake Error at /usr/share/cmake/Modules/FindOpenSSL.cmake:283 (list):
  list GET given empty list
Call Stack (most recent call first):
  lib/src/CMakeLists.txt:5 (find_package)
```

## 原因

エラー箇所の`/usr/share/cmake/Modules/FindOpenSSL.cmake`を覗いてみたところ、`ヘッダーパス/openssl/opensslv.h`内の*OPENSSL_VERSION_NUMBER*をパースしてバージョン情報を取得していました。
しかし定義を見比べるとdefineの前にスペースのあるなしという違いが。何それ(-_-;)

```c:header/openssl/opensslv.h
# define OPENSSL_VERSION_NUMBER  0x1010102fL
//#とdefineの間にスペースがある
```

```cmake:/usr/share/cmake/Modules/FindOpenSSL.cmake
    file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
         REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
##とdefineの間が詰まっていることを想定している
```

## 対処

### その1. cmakeのversionを上げる
cmake 3.10の場合は、ちゃんとスペースのありなしが判別できるようになっています。なのでcmakeのversionが上げるのがベターですね。

```cmake:/usr/share/cmake-3.10/Modules/FindOpenSSL.cmake
  file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
       REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
```

### その2. FindOpenSSL.cmakeを修正する。

cmakeのversionを変えなくても、その1の処理と同じように#とdefineの間にタブ、スペースがある場合を想定した正規表現に変えてあげればOKです。
環境によるツールバージョンの違いはこういったことが起こるのが嫌ですね(-_-;)
リンク遷移後でアコーディオンの開状態を保持する

リンク遷移後でアコーディオンの開状態を保持させたいが、単純にアコーディオンのみ実装すると閉状態に戻る。
これはリンクに限らず、リロードさせると閉状態に戻ってしまう。

解決するには、jQueryでcookieを用いる。
jquery.cookie.jsでcookieが使えるようになる。
使用するには、ダウンロードするか、CDNサイトのURLから引っ張ってくるかになる。
ダウンロードは下記から
[jquery.cookie.js](https://github.com/carhartl/jquery-cookie)

今回はCDNサイトからURLを引っ張ってくるやり方で行う。
```
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
```
まずHTMLのheadに部分にscriptタグでURLを引っ張ってくる。

```erb:application.html.erb
<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
  </head>
  <title>Cookieサンプル</title>
</html>
```
**両方の方法で必ずjQueryのライブラリを読み込んでおく必要がある。**

これで準備はオッケー。

jQueryで処理を書いていく。

```js:test.js
 $(function(){
    if($.cookie("open-panel")){
      $("#treeview-menu").show();
    }
    $("#accordion").click(function() {
      if($.cookie("open-panel")){
        $("#treeview-menu").slideUp();
        $.removeCookie("open-panel" , { path: "/" });
      } else {
        $("#treeview-menu").slideDown();
        $.cookie("open-panel" , "open" , { expires: 1,  path: "/" });
      }
    return false;
    });
  });
```
htmlファイル

```erb:test.erb
<ul>
  <li class="treeview active">
    <a href="" class="accordion" id="accordion">サンプル一覧</a>
      <ul class="treeview-menu" id="treeview-menu" style="display:none">
        <% @samples.each do |sample| %>
          <li><%= link_to sample.name, sample_path %></li>
        <% end %>
     </ul>
  </li>
</ul>
```
これでサンプル一覧押し込みで、アコーディオンが開閉でき、リンク先遷移後でも開状態を保持できる。
kubernetes内で実行中のrails(puma)の実行された場所を知る

まずはpodを調べる

```
$kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
mysql-76c755cc88-bv9wf             1/1     Running   5          12m
rails-679bf9b89c-rcl26             1/1     Running   0          2m26s
```

`kubectl exe -it <pod> /bin/bash`でログイン

```
$kubectl exec -it rails-679bf9b89c-rcl26 /bin/bash
```

pumaのpidを調べる。この例だと、`pid=1`

```
root@rails-679bf9b89c-rcl26:/myapp# ps aux | grep puma
root         1  0.3  2.9 1142908 59432 ?       Ssl  03:27   0:02 puma 3.12.1 (tcp://0.0.0.0:3000) [myapp]
root        77  0.0  0.0  11112   852 pts/0    S+   03:41   0:00 grep puma
```

実行されている場所を調べる

```
root@rails-679bf9b89c-rcl26:/myapp# ls -l /proc/1/cwd
lrwxrwxrwx. 1 root root 0 Mar 24 03:41 /proc/1/cwd -> /myapp

root@rails-679bf9b89c-rcl26:/myapp# cat /proc/1/cmdline
puma 3.12.1 (tcp://0.0.0.0:3000) [myapp]root@rails-679bf9b89c-rcl26:/myapp#
```

---
ref
- [kubernetes: コンテナイメージにログインする](https://qiita.com/suzukihi724/items/515654f54538a2103ee0)
- [プロセスが実行された場所を知る方法](プロセスが実行された場所を知る方法)
【LXD】Ubuntu 18.04 LTSにApache HTTP Serverを立ち上げる

# はじめに
余っていたノートPCを貰ってきたので、簡易的にこれを共同作業用のサーバーにしようと思う。各種ソフトウェアはLXDコンテナの上にインストールし、将来スペックの高いサーバーへ移行する際にはコンテナのマイグレーション機能を使って安全に移行可能とする。

# インストール環境

|項目             |ソフトウェア        |バージョン         |
|:----------------|:------------------|:-----------------|
|ホストOS         |Ubuntu             |18.04.2 LTS       |
|ゲストOS         |Ubuntu             |18.04.2 LTS       |
|HTTPサーバー     |Apache HTTP Server |2.4.29            |

WikiやBlog、ITSなどをインストールしようと計画しているが、まずは上記の環境を整備する。

# コンテナ環境の構築
コンテナといえばdockerが独走状態だが、今回のように関連するソフトウェア一式を乗せるにはシステム・コンテナのLXDが都合が良い。

## LXDのインストール
普通にサーバー版やデスクトップ版をインストールしていればLXDはデフォルトでインストールされていると思う。
筆者の場合には[ZFS上にスクラッチでUbuntuをインストール](https://qiita.com/InitialK/items/b11773305030d9fe4b25)したため、手動でインストールした。

```
$ sudo apt install lxd lxd-client
```

## コンテナイメージのダウンロードと起動
サーバー用途なので安定性重視でLTSをインストール。documentsは作成するコンテナ名である。

```
$ lxc launch ubuntu:18.04 documents
```

## コンテナの中に入ってアップデート

```
$ lxc exec documents -- /bin/bash
# apt -y update && apt -y upgrade　←コンテナ内に入っている
```

## Apache HTTP Serverのインストール

```
# apt -y install apache2
```

# ポートフォワーディング

コンテナはNAPT配下にあるため、コンテナから外部へのネットワーク接続は可能であるが、外部からコンテナ内のサーバーへは接続できない。外部からApache HTTP Serverに接続できないのは困るので、ポートフォワードを設定する。

```
# exit ←コンテナから抜けてホストに戻る。
$ lxc config device add documents port81 proxy \
     listen=tcp:0.0.0.0:81 connect=tcp:localhost:80
```
|パラメータ        |説明                                                                              |
|:----------------|:---------------------------------------------------------------------------------|
|documents        |ポートフォワードを設定するコンテナ名                                            |
|port81           |任意の設定名                                                                       |
|listen           |リッスンするアドレスとポート。この例では全てのアドレスからの81番ポートへの接続を待ち受ける|
|connect          |フォワードするアドレスとポート。コンテナの80番ポートへフォワードしている                |
上記のコマンドは、documentsというコンテナに対して、ホストの81番ポートへの接続をコンテナ内の80番ポートへフォワードする、という意味になる。
うまく設定されていれば、ブラウザでホストの81番ポートに接続すると下図のようにApache HTTP Serverのデフォルト画面が表示される。
![apache2.PNG](https://qiita-image-store.s3.amazonaws.com/0/354946/a1f4659d-a2d4-fbe1-94e2-a47a47031d04.png)

# おわりに
VM上にOSをインストールするのと違って、LXDだと気軽にコンテナ上にフルスタックのOSを手にすることができる。設定を間違ってわけがわからなくなってもコンテナごと削除した上ですぐに新しいコンテナを立ち上げることができる。
次回はこのコンテナ上にWikiやBlogを構築する。
VScode x Rails：erbファイルでEmmet(エメット)を使う方法

2023/4/12 時点でこちらの記事の`最終更新が３年前`と、かなり古くなっていましたが、
現在でも emmet の設定について情報を求めてる方がいらっしゃるようなので、更新しました。

また、記事を保存されてる方も多いようなので、念の為、過去に記載していた内容もページ下部にそのまま記載しておきます。

# emmet の設定方法
設定は簡単です。

1. VSCode の左下の歯車マークをクリックし、settings（設定) を開きます。
1. 検索窓に `emmet` と入力し、`Emmet: Include Languages` という項目を見つけます。
1. `Add Item` をクリックし、`key`と`value`に以下の値を入力します。

| key | value |
|:-:|:-:|
| ruby |  html |

最後に`OK`をクリックしたら完了です。

手元で確認したところ、上記記載のみで、`.erb`および`.rb`ファイルどちらでも emmet を利用できました。

## 補足
`.html`ファイルは初期状態から emmet が利用できるので設定は不要です。

そして設定の変更は、settings.json にも自動で反映されます。（反対にsettings.jsonの変更も設定画面側に反映されます。）
settings.json の開き方は[こちらの記事](https://qiita.com/y-w/items/614843b259c04bb91495)を参考にしてください

両者の違いは、VSCodeの設定をGUIから行うかファイルから行うかという違いだけなので、変更時はお好みで。

ちなみにsettings.json ファイルを使うメリットは、
チーム開発などで皆同じVSCodeの設定が必要な場合に、コードなら簡単に共有できるというのが利点です。
頭の片隅に入れておくと今後の開発に役立つかもしれません。

# 過去の記載
:::note warn
このセクションは、**2023/4/12 以前** にこの記事を参考に設定をしていた人のために、念のため残しています。

これから 初めて emmet の設定をする人は**見る必要はありません**。
:::


<details><summary>クリックで展開</summary>

この記事は情報が古い可能性があります。
後述の Expension on Tab を true にするだけで解決するかもしれません。

***VSCode*** で ***Rails開発*** してるんだけど、***erbファイル*** で ***Emmet 使えない！***という人や
そもそ も***HTMLファイル*** でも ***Ememt 使えないよ！*** という人は以下を試してみてください。

## VSCode の設定
>まず VSCode の左下の歯車マークをクリック
次に、 settings をクリック

検索窓で、
>"***Trigger Expansion On Tab***" と検索
Emmet:Trigger Expansion on tab　の左の***チェックマークを入れる***


これで Html ファイルでは Emmet が使えるようになったはず。

## セッティングファイルの記述

さらに続けて、検索窓で

>”***edit in settings***” と検索
>少し小さい文字の ***Edit in settings.json*** をクリック

ファイルが開くので以下を追記

```settings.json
{
    "workbench.iconTheme": "vscode-icons",
    "window.zoomLevel": 0,
    "emmet.triggerExpansionOnTab": true,

    # ここから記述
    "emmet.includeLanguages": {
        "erb": "html"
    }
}
```

これで試しに ***erbファイル*** で
***h1*** と打ってから ***Tabキー*** を叩いてください。

それでうまくいかなければ,

## 拡張機能のインストール


>VSCode 画面上 の左上側 にあるアイコンの 下の方 にある、
四角のアイコンの拡張機能 ( ***Extentions*** ) をクリック
***erb*** と検索してerbをインストール

コレです⬇︎
https://marketplace.visualstudio.com/items?itemName=CraigMaslowski.erb

---

上記全て終えたら、晴れて Emmet が使用できるはずです。

※ Emmet は VSCode じゃなくても使えます。



たくさんコードを書いてみんなで爆速になりましょう

# ごあいさつ
実はこの記事がQiitaでの初投稿になります。
1人でも多くの人のお役に立てたらと願っていますが、至らない所あるかもしれません。
その際は遠慮なく教えていただけると幸いです。

# 参考

https://qiita.com/gorohash/items/bb5c42e0054c83fd4a2d

</details>


ではみなさん、良い開発を！
SICP読書録 #25 2.2.3 標準インターフェイスとしての列

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

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

## 2.2.3 標準インターフェイスとしての列

突然だけど、木構造を受け取り、含まれる奇数値の２乗の和を返す手続きはこうなる。

``` _.scm
(define (sum-odd-squares tree)
  (cond ((null? tree) 0)
        ((not (pair? tree))
         (if (odd? tree) (square tree) 0))
        (else (+ (sum-odd-squares (car tree))
                 (sum-odd-squares (cdr tree))))))
```

引数nで指定した数だけフィボナッチ数列を生成し、偶数のもののリストを返す手続きはこう。

``` _.scm
(define (even-fibs n)
  (define (next k)
    (if (> k n)
        nil
        (let ((f (fib k)))
          (if (even? f)
              (cons f (next (+ k 1)))
              (next (+ k 1))))))
  (next 0))
```

さて、上記2つの手続きは誰が何と言おうと「似ている」。どちらも次のことを行なっているのだ。

- (列挙) 木の葉を列挙し / フィボナッチ数を列挙し
- (フィルタ) 奇数を選び / 偶数を選び
- (変換) 2乗して / 値をそのまま
- (集積) 和を求める / リストにする

この、列挙、フィルタ、マップ、集積というパターンに基づいて、この手続きを作り直してみよう。

### 列の演算

まずは、リストに対して任意のフィルタをかける手続きを作ろう。

``` _.scm
(define (filter predicate sequence)
  (cond ((null? sequence) nil)
        ((predicate (car sequence))
         (cons (car sequence)
               (filter predicate (cdr sequence))))
        (else (filter predicate (cdr sequence)))))
```
動かしてみる。

``` _.scm
gosh> (filter odd? (list 1 2 3 4 5))
(1 3 5)
```

次は、集積を行う手続きだ。

``` _.scm
(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))
```

動かしてみる。

``` _.scm
gosh> (accumulate + 0 '(1 2 3 4 5))
15
gosh> (accumulate cons nil '(1 2 3))
(1 2 3)
```

残るは、列挙。

指定した範囲の整数リストを返す手続き。

``` _.scm
(define (enumerate-interval low high)
  (if (> low high)
      nil
      (cons low (enumerate-interval (+ low 1) high))))
```

木の葉を列挙する手続き。

``` _.scm
(define (enumerate-tree tree)
  (cond ((null? tree) nil)
        ((not (pair? tree)) (list tree))
        (else (append (enumerate-tree (car tree))
                      (enumerate-tree (cdr tree))))))
```

それぞれ動かしてみる。

``` _.scm
gosh> (enumerate-interval 2 7)
(2 3 4 5 6 7)
gosh> (enumerate-tree '(1 (2 (3 4)) 5))
(1 2 3 4 5)
```

これで部品は完成した。先の手続きをそれぞれ作り直してみよう。

``` _.scm
(define (sum-odd-squares tree)
  (accumulate + 0 (map square (filter odd? (enumerate-tree tree)))))

(define (even-fibs n)
  (accumulate cons nil (filter even? (map fib (enumerate-interval 0 n)))))
```

まるで積み木を組み合わせるかのようにして実装できた。この方法だと、本来は複雑な手続きを簡単に作れる。

例えば、フィボナッチ数の２乗のリストが欲しい、となればこうだ。

``` _.scm
(define (list-fib-squares n)
  (accumulate cons nil (map square (map fib (enumerate-interval 0 n)))))
```

指定したリスト内の奇数の２乗の積が欲しい、のならばこう。

``` _.scm
(define (product-of-squares-of-odd-elements sequence)
  (accumulate * 1 (map square (filter odd? sequence))))
```

それぞれ動かしてみよう。

``` _.scm
gosh> (list-fib-squares 10)
(0 1 1 4 9 25 64 169 441 1156 3025)
gosh> (product-of-squares-of-odd-elements '(1 2 3 4 5))
225
```

社員マスタからプログラマだけを抽出し、最も給料が高いのは誰か？という手続きにだって応用できる。

``` _.scm
(define (salary-of-highest-paid-programmer records)
  (accumulate max 0 (map salary (filter programmer? records))))
```
immerで複雑な構造のオブジェクトを扱う

複雑な構造のオブジェクトに何か値を追加する際、現在の構造を壊さずに値を追加しなければならないのでスプレッド演算子をたくさん使ったコードになりがちです。

イメージとしてはこんな感じのやつです。

```js
const user; // 変更前のユーザー。複雑な構造をしている
const additionalHoge = ['hoge', 'huga']; // 追加したいデータ

const newUser = {
  ...user,
  detail: {
    ...user.detail,
    hoge: [...user.detail.hoge, ...additionalHoge],
  }
}
```

こういう雰囲気のコードをいい感じにリファクタできる[immer](https://github.com/mweststrate/immer)というライブラリを最近知りました。mobxの作者の方が作ったライブラリみたいです。

immerを使うと上のやつはこんな感じで書き直せます。
元の変数 `user` には変更はなく、新たに変更が反映されたオブジェクト `newUser` が返ってきます。
元の構造を維持するための `...user` みたいなコードは一掃出来るのでどこに変化があるのかがわかりやすいです。

```js
import produce from 'immer';

const user; // 変更前のユーザー
const additionalHoge = ['hoge', 'huga']; // 追加したいデータ

const newUser = produce(user, draftUser => {
  draftUser.detail.hoge = [...draftUser.detail.hoge, ...additionalHoge];
});
```

これくらいの構造のネストであれば、そのままjsで書いてもいいと思いますが、ネストが何重にもなればなるほど、immerの見やすさが顕著に出てくると思います。

使いどころとしてはreduxのreducerで使うような例が公式のreadmeにものってます。
他に使えそうと思ったところとして、react-apolloでreact-infinite-scrollerを用いた無限スクロールを行う際、元のデータにデータを追加するコードがスプレッド演算子だらけになるので、ここでも使えるなあと思いました。

react-apollのこういう感じのコードを綺麗に出来る。[参考](https://medium.com/@dai_shi/infinite-scroll-example-with-react-apollo-for-github-graphql-api-15209a043a0f)

```js

          return {
            ...previousResult,
            search: {
              ...previousSearch,
              nodes: [...previousNodes, ...currentNodes],
              pageInfo: currentSearch.pageInfo,
            },
          };
```
CNNをディジタルフィルタ的な観点から眺める #1

CNNをディジタルフィルタ（FIRフィルタ）設計的な観点から眺めたらもしかして面白いのでは？という記事です。

# CNNとディジタルフィルタの関係
## そもそもCNNって？
みなさんご存知のCNN（畳み込みニューラルネットワーク）とは、構成要素として畳み込み層（とプーリング層）を持ったニューラルネットワークのことです。
典型的な構成はこんな感じです。（こういった図で活性化層をわざわざ書くのはあまり見たことがないのですが、後の信号処理の記号と対応させるために書いています。）
![CNN構造図.png](https://qiita-image-store.s3.amazonaws.com/0/372879/9e791d55-2bae-9199-ff1c-ae5ecb74ebd8.png)


## CNNとディジタルフィルタって関係あるんですか？
CNNの畳み込み処理はディジタル信号処理のFIRフィルタの処理と同じです。
上記のCNN構成を信号処理の記号で書き直すとほぼこんな感じです。
![CNN対応回路図.png](https://qiita-image-store.s3.amazonaws.com/0/372879/9e78888b-2943-b6df-118d-b457903d97a6.png)

つまりCNNの学習は「特定の波形の特徴を抽出するようにフィルタ特性とクリッピング特性を最適化する処理」と捉えることが出来ます。

# ディジタルフィルタの特性
## 周波数特性
フィルタ特性を$f(t)$、入力信号を$x(t)$とすると畳み込み演算は
$$ \int_{- \infty } ^ {\infty} f(u) x(t-u) du $$
となります。この演算を$*$という記号を用いて
$$ f(t) * x(t) $$
と書くことがよくあります。

さらに$f(t)$のフーリエ変換を$F(\omega)$、$x(t)$のフーリエ変換を$X(\omega)$とします。$f(t)$と$x(t)$の畳み込み演算をフーリエ変換すると、その結果は$F(\omega)$と$X(\omega)$の積となります。
$$ f(t) * x(t) \to F(\omega) X(\omega) $$

フィルタの重みをただ眺めるだけではその特性をとらえるのは難しいのですが、フーリエ変換して周波数領域に変換することで、どの周波数成分を抽出しているのかが分かりやすくなります。

## 位相特性
信号がフィルタを通過する際に、通過後の波形が歪まないようにするには、フィルタの重みが偶対称もしくは奇対称である必要があります。

1次元の5次フィルタを例にとると、フィルタの重みが偶対称とはこのようにフィルタの重みが左右対称になっていること。
![偶対称_1次元.png](https://qiita-image-store.s3.amazonaws.com/0/372879/72a1020a-eb42-2a79-ee4e-1ba89831aeb3.png)

奇対称とはこのようにフィルタの重みが左右で原点に対して対称になっていることです。
![奇対称_1次元.png](https://qiita-image-store.s3.amazonaws.com/0/372879/1c193da0-1ad2-a26a-6f02-d9b173dd60a3.png)

この話は画像向けのような2次元フィルタに対してはこのように拡張できます。下の画像では左から数えて1列目と5列目、2列目と4列目が偶対称になっており、横方向に対して対称性があります。
![偶対称_2次元ん.png](https://qiita-image-store.s3.amazonaws.com/0/372879/2b726076-317d-bc73-ffc5-d242920655d5.png)

フィルタが2次元になると話は横方向だけでなくその他の方向に対しても広がります。下の画像は縦方向に偶対称であることを示しています。
![偶対称_2次元_縦.png](https://qiita-image-store.s3.amazonaws.com/0/372879/f7dc4aaa-74ad-f31c-cab7-6c2715eb204f.png)


# 実際のCNNの重み
実際にCIFAR-10のデータセットで学習させたCNNのカーネルを可視化したものが下記です。
ネットワークの構造はカーネル数10個、カーネルサイズ6x6の1層のCNNです。 @sasayabaku さんの [KerasでCNNを簡単に構築](https://qiita.com/sasayabaku/items/9e376ba8e38efe3bcf79) のコードを参考にさせて頂きました。10個のカーネルを縦に並べています。それぞれのカーネルについて左からRGBのそれぞれのチャネル別の重みを出力しています。

![CNN_kernel10_size6.png](https://qiita-image-store.s3.amazonaws.com/0/372879/e6166761-89bc-57b8-3b1f-e4dbe665449c.png)

1層のCNNなので性能は全然出ていない（Accuracy=0.60程度）のですが、偶対称な重みが学習されたカーネルが結構あるように見受けられます。次は対称性を定量的に評価できるようにしたいですね。（わざわざフィルタの周波数特性の話をしたのに対称性にしか触れていないのはFFTするのがめんどくさかったからです。その話も次にやりたいです。）

# 追記
このあたりの内容を既に議論している論文等あれば教えて頂けると嬉しいです。
Confirmed状態のCognitoユーザーをBoto 3で即作成する

# 概要

指定されたユーザー情報を使って、すぐにログインできるConfirmed状態のCognitoユーザーをバックエンド側でサクッと作成したい。
`admin_create_user`だとForce Change Password状態となるので、この後に処理が必要。

# 今のところの結論

```python
import boto3

username = '{ユーザー名}'
password = '{パスワード}'
email = '{メールアドレス}'

user_pool_id = '{ユーザープールID}'
client_id = '{アプリクライアントID}'

cognito_idp = boto3.client('cognito-idp')

# ユーザーを作成する。
cognito_idp.admin_create_user(
    UserPoolId=user_pool_id,
    Username=username,
    TemporaryPassword=password,
    UserAttributes=[{'Name': 'email', 'Value': email}],
    MessageAction='SUPPRESS'
)

# ログインを試みる。（パスワードの変更を要求される。）
response = cognito_idp.admin_initiate_auth(
    UserPoolId=user_pool_id,
    ClientId=client_id,
    AuthFlow='ADMIN_NO_SRP_AUTH',
    AuthParameters={'USERNAME': username, 'PASSWORD': password},
)
session = response['Session']

# パスワードを変更する。
response = cognito_idp.admin_respond_to_auth_challenge(
    UserPoolId=user_pool_id,
    ClientId=client_id,
    ChallengeName='NEW_PASSWORD_REQUIRED',
    ChallengeResponses={'USERNAME': username, 'NEW_PASSWORD': password},
    Session=session
)
```

# 解説

以下の3ステップでConfirmed状態のユーザーを作成しています。

1. ユーザーの作成（`admin_create_user`）
2. 最初の認証（`admin_initiate_auth`）
3. パスワードの変更（`admin_respond_to_auth_challenge`）

### 1. ユーザーの作成（`admin_create_user`）

管理者によるユーザーの作成を行う。
通常は作成した時に仮パスワードが通知されますが、`MessageAction='SUPPRESS'`で無効にできます。

### 2. 最初の認証（`admin_initiate_auth`）

管理者による最初の認証を試みる。
すると、以下のようなレスポンスが返却され、新しいパスワードが必要だということが分かります。この中の`Session`が次の処理で必要となります。

```json
{'ChallengeName': 'NEW_PASSWORD_REQUIRED',
 'ChallengeParameters': （省略）,
 'ResponseMetadata': （省略）,
 'Session': '{セッションを表す長い文字列}'}
```

また、`AuthFlow='ADMIN_NO_SRP_AUTH'`とする場合は、アプリクライアントの設定で「サーバーベースの認証でサインイン API を有効にする (ADMIN_NO_SRP_AUTH)」を有効にしておく必要があります。SRPというのは認証のプロトコルで、使用するとセキュアでない通信経路でもユーザー名とパスワードによる認証を安全に行なえるようになるようですが、実装が難しくなり、また今回は全てバックエンドでの処理となるので、使用しなくても良いこととしています。

### 3. パスワードの変更（`admin_respond_to_auth_challenge`）

管理者による`NEW_PASSWORD_REQUIRED`に対する返答。
成功すると各種トークンが返却され、ユーザーの状態もConfirmedへ移行します。これでめでたくユーザーが普通にログインできるようになりました！

なお、コードにある通り、新しいパスワードは仮のパスワードと同じでも問題ありませんでした。

# 他の方法

一応、次の方法でもConfirmed状態のユーザーを作成することができます。

```python
# ユーザーがサインアップする。
cognito_idp.sign_up(
    ClientId=client_id,
    Username=username,
    Password=password,
    UserAttributes=[{'Name': 'email',' Value': email}]
)

# それを管理者が承認する。
cognito_idp.admin_confirm_sign_up(
    UserPoolId=user_pool_id,
    Username=username
)
```

簡単だったので、最初はこちらの方法を使っていたのですが、アプリクライアントの設定で「アプリベースの認証でユーザー名とパスワードの (SRP を使用しない) フローを有効にする (USER_PASSWORD_AUTH)」を無効にしたり、属性の書き込み権限を変更したりすると`sign_up`ができなくなるので、全て管理者の操作で行える上記の方法に変更しました。
Intel Neural Compute Stick 2をMac+Parallels Desktopで動かす

# 概要
以前はMovidius Neural Compute Stickと呼ばれていたのが、装い新たにIntel Neural Compute Stick 2としてリリースされています。Movidius Neural Compute StickとMac上のVMWare Fusion(上のUbuntu)との組み合わせに関しては、既に先立がいらっしゃるので、今回は、Mac上のParallels Desktop(上のWindows 10)と組み合わせてみました。

- [Movidius Neural Compute StickをMac+VMWare Fusionで動かす](https://qiita.com/akitooo/items/40bdafbb98b35125755d)



# 環境
## Mac
- MacBook Air (Retine, 13-inch, 2018)
- プロセッサ: 1.6GHz Intel Core i5(第8世代)
- メモリ: 16GB 2,133MHz LPDDR3メモリ
- macOS Mojave 10.14.3

## Parallels Desktop
- バージョン: Pro Edition 14.1.3 (45485)

## Windows 10(仮想マシン)
- Windows 10 Pro(64bit) バージョン1809 (OSビルド17763.379) 
- 2プロセッサ、8192MBメモリ割り当て

# 作業手順
Mac上でVM作成してインストール、起動できるようにするところまでは通常のやり方です。(USB3.0を使用)。

その後、こちらの手順に従い、Intel Distribution of OpenVINO toolkitをインストールします。

- [Install Intel® Distribution of OpenVINO™ toolkit for Windows* 10](https://software.intel.com/en-us/articles/OpenVINO-Install-Windows#next-steps)

二点失敗してしまったのは、
- 上記Toolkitのインストール時、(Windows VMから見て)ローカルのドライブにインストールイメージを展開する必要がある。母艦MacBookをDownloadフォルダを共用している場合、そのまま(ネットワーク越しの)Downloadフォルダに展開すると、インストールがスタートしない。
- Visual Studio 2017 or 2015が必要なのに対し、インストールされているVisual Studio 2019 RC版では検出してもらえなかったので、Visual Studio 2017をインストールしました(並存可能)。

# サンプル実行
まずは、Image Classificationデモ(demo_squeezenet_download_convert_run.bat)です。画面左がCPUのみの実行結果、右がNeural Compute Stick 2を使った場合の実行例です。

![demo_squeezenet_download_convert_run.PNG](https://qiita-image-store.s3.amazonaws.com/0/19248/e1f38cf2-3898-68c3-f13f-07e09654846f.png)

|                    |CPU       |w/ Stick2  |
|--------------------|---------:|----------:|
|Total Inference Time|12.1692000|7.2014998  |
|Avarage Running Time|12.1692000|7.2014998  |
|Throughput(FP       |82.1746705|138.8599641|

次に、Inference Pipelineデモ(demo_security_barrier_camera.bat)の実行例です。

![demo_security_barrier_camera.png](https://qiita-image-store.s3.amazonaws.com/0/19248/b7414e48-37ec-1b24-21d9-875db5654d84.png)

(途中ですが一旦公開します→手放してしまったので今後の追加はありません。)
[postfix,sendmail] phpでメールを送信するまでのまとめ

# 目的
プログラムでメールを送っている仕組みを整理したい。
# 本当の目的
qiitaで久しぶりに何か上げたかった
# 役者たち
- php
    - 今回メール送信を行う言語
- sendmail
    - プログラムでメール送信を行うときに内部で呼び出されるコマンド
- postfix
    - メール送信の設定を行う何か（メールの送信元とか)


# 実験環境
OS: OSX ver 10.13.6
php: 7.1.16

# メール送信プログラム
今回実行するコード(test.php)↓(メールアドレスは匿名)

```php
<?php
$to = 'hogehoge@example.com';
$subject = "let's php mail";
$message = 'Can you see it?';
mb_send_mail($to, $subject, $message);
```
# メールの送信元設定
メールは送信元がないと送れない（常識)
その設定をpostfixで行う
## postfixでメールの送信元を設定

```
$ sudo vim /etc/postfix/sasl_password
```
今回はgmailを利用してメールを行う。
そのためには、gmailのアプリケーションパスワードが必要である。
アプリケーションパスワードの設定は[こちら](https://support.google.com/mail/answer/185833?hl=ja)(注意：gmailに紐づくアカウントが２段階認証されてないとダメ)
### sasl_password(メールを送信するエージェントをgmailに設定)
```
[smtp.gmail.com]:587 <ここにメールアドレス>:<ここにアプリケーションパスワード>
```
### 設定をpostfixに反映
 
```
$ sudo postmap /etc/postfix/sasl_password
```

# 試しにsendmailで送ってみる
```
$ sendmail hoge@example.com(送信先アドレス)
testhoge
.
```

# phpで実行

```php
$ php test.php
```

# まとめ
メール送信するだけでも、色々疲れちゃった
Three.js で遊び倒す - カメラを動かそう  Part.1 -

Three.js day 4 となりました。

[昨日](https://qiita.com/duka/items/ab73c293c7dc06cce738) は、3D オブジェクトを動かしました。
本日は、カメラを動かす準備をします。


#1. 完成版

![スクリーンショット 2019-03-24 11.25.07.png](https://qiita-image-store.s3.amazonaws.com/0/232715/c51f5878-b6cd-0f52-2853-bbcaee444379.png)


#2. 参考文献
[ICS MEDIA](https://ics.media/tutorial-three/index.html)
[初めてのThree.js](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEThree-js-%E7%AC%AC2%E7%89%88-%E2%80%95WebGL%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEJavaScript-3D%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA-Dirksen/dp/4873117704)
[CodeGrid](https://app.codegrid.net/entry/threejs-location)



#3. 分解してみる


❶. 
現状では、カメラが移動すると、その物体を追い続けることができず、見失ってしまいます。
カメラが、物体を注視し続けるためには、どうしたらよいでしょうか？

これには、``camera.lookAt()``を使います。

###camera.lookAt メソッドとは？
このメソッドで、どの位置からでも、指定された座標に強制的に追い続けます。

```
camera.lookAt(new THREE.Vector3(0,0,0))
```

camera.lookAt() の引数には、``THREE.Vector3``にて、生成されたオブジェクトが入ります。
このコンストラクタは、引数に3つの数字を取り、

```
(0,0,0)  ->  {x:0, y:0, z:0}
```

と変換されたインスタンスを作ります。

[デモ](https://ics.media/wp-content/data-demos/140930_angularjs_away3d/src/index.html) 　がICS MEDIA からありましたので、ぜひ一度ご覧ください。
<br/>
###星空を作ろう！

カメラの動きをわかりやすくするために、星空を作ります。
前回までの復習です。

```index.html
starNight();

function starNight(){

const star = new THREE.Points(geometry, material);
scene.add(star);
}
```

THREE.Pointクラス で、3D空間内に大量のParticle を作ることができます。
詳しくは、[公式DOC](https://threejs.org/docs/#api/en/materials/PointsMaterial) や、[ICS MEDIA](https://ics.media/tutorial-three/points.html) をご参照ください。

では、上のコードに、geometry と material を書いていきましょう。

```index.html
starNight();

function starNight(){

  const geometry = new THREE.Geometry();

  for (let i=0; i<1000; i++){

    const star = new THREE.Vector3();
    star.x = THREE.Math.randFloatSpread( 3000 );
    star.y = THREE.Math.randFloatSpread( 3000 );
    star.z = THREE.Math.randFloatSpread( 3000 );

    geometry.vertices.push(star)
  }


  const material = new THREE.PointsMaterial({ 
      size : 10,
      color: 0xffffff
  });

  const star = new THREE.Points(geometry, material);
  scene.add(star);
}
```

geometry は、まず、空のgeometryを作り、loop 文を使います。
``geometry.vertices.push(new THREE.Vector3())`` は、自前でgeometry を作る時によく、使う構文です。

vertices とは、多面体を構成する頂点のことです。つまり、上の構文は、
__geometryの頂点に、座標を設定しますよという意味になります。__


material には、PointsMaterial を設定しました。
こちらも、[公式](https://threejs.org/docs/#api/en/materials/PointsMaterial) の素晴らしい説明をご参照ください。


![スクリーンショット 2019-03-24 11.25.07.png](https://qiita-image-store.s3.amazonaws.com/0/232715/e064c9b8-eb3b-ef3c-8a45-0df3d481d61f.png)

綺麗な星空ができました。
これで、カメラを動かした時に、わかりやすくなります。

それでは、明日、目的であるカメラを動かして、3Dの醍醐味を堪能しましょう。
それでは、また〜
npm installした際に、fetchMetadataで止まった際の解決方法

# はじめに
`vue create`した際にfetchMetadataで止まってしまった際の解決方法の備忘録です。

## 解決方法
下記を参考にして、設定変更しましたが解決しなかったです。
最終的にネットワーク(wifi)を変更したところ、解決しました。
原因までは特定できませんでした。

- [npm installしようとすると"fetchMetadata"で止まるのをなんとかする](https://argrath.ub32.org/annex/2017/04/06-04.html)

- https://stackoverflow.com/questions/37860219/npm-gets-stuck-on-fetchmetadata-network