OmniAICreator/Qiita-1.07M huggingface dataset:
USB Wi-Fi子機の自動再接続

## 【序文】
前回 [Wi-Fi通信速度測定 2　～ここWi-Fi飛んでんな～](https://qiita.com/god19/items/00f752ecc7fa3e110762 "Wi-Fi通信速度測定 2　～ここWi-Fi飛んでんな～") の続き。
動作確認を兼ねて殆ど点けっぱなしでいるけど、気が付くと Wi-Fi接続が切れている。
Wi-Fi中継機が不安定なので時々切れるのは仕方がない。
しかし自動で再接続して欲しいもの。
取り合えず、Wi-Fi子機を差し直すと再接続されるけど、一緒に接続している USB HDD が何故かイジェクトされてしまい不便。（因果関係は不明）
これは何とかしたいと重い腰を上げる。

## 【環境】
| 機器等 | 説明 |
| ---- | ---- |
| Raspberry Pi | 3B |
| OS | Raspbian GNU/Linux 9.11 (stretch) |
| Wi-Fi子機 | WI-U2-433DHP |

## 【最初に試したこと】
これはよくある問題のようで、ぐぐれば対応方法が直ぐに出てくる。
まず参考にさせていただいたのは以下。
[Raspberry PiでWi-Fi切断時、自動的に再接続されるようにする方法](https://qiita.com/gzock/items/0b3d925c16079561abc4 "Raspberry PiでWi-Fi切断時、自動的に再接続されるようにする方法")
そっくりそのまま真似するも再接続されない。
よくよく確認してみると以下のスクリプトが自分の環境では見当たらない。

```shell
/etc/ifplugd/ifplugd.action
```

Jessie 以降（多分）は以下に差し変わった模様。

```shell
/etc/ifplugd/action.d/action_wpa
```

そこだけ書き換えた結果が以下。

```shell
pi@raspberrypi3:~/scripts $ ls
reconnect.sh
pi@raspberrypi3:~/scripts $ cat reconnect.sh
#!/bin/sh
ping -c 1 192.168.11.1
test $? -eq 1 && sudo /etc/ifplugd/action.d/action_wpa wlan0 up

pi@raspberrypi3:~/scripts $ crontab -l
（中略）
* * * * * sh ~pi/scripts/reconnect.sh
```

ところが、これで正しい筈なのにまだ再接続されない。
うーむ、何が悪い。

## 【次に試したこと】
スクリプトを直接叩いてもダメ。

```shell
sh ~pi/scripts/reconnect.sh
```

そもそも手動で接続 - デスクトップ画面のタスクバーの Wi-Fi 一覧から目的の AP を選択 - しても繋がらない。
うーむ、何が悪い。

流石にタスクバーの Wi-Fi メニュー [Turn Off Wi-Fi] -> [Turn On Wi-Fi] としてから目的の AP を選択すれば繋がる。
でもこれって、Wi-Fi子機を抜き差ししたのと同じだよね。

うーむ、スクリプトにはそこまで仕込まなければダメなのだろうか。というか、それってコマンドで実行するにはどう記述する？

などとぐるぐる考えていたら、気が付けば自動で再接続されるようになっていた。
Wi-Fi を一旦 OFF にしてから再度 ON にしたら改善された、ということ？
それぐらいの操作しかしていなし。
結局何が原因で何が解決方法だったのかよくわからないままですっきりしないけど、取り合えず様子見で。
chainerのTrainerのextensionのEvaluatorを普通に使うと、テストデータ数÷バッチサイズに余りがある場合重みを付けて補正しないと計算結果がずれる

### 現象の紹介
ChainerはTrainerがとても便利なので使いたい。
`numpy.arange(10)`の平均を計算し、ログに出すことを考える。`4.5`になるのが正しい。
Trainerを用いる際は`chainer.report`を使えば良い感じにログに入るので、これを使う。

```python
import chainer
import numpy

# データセット
dataset = numpy.arange(10, dtype=float)
train_iterator = chainer.iterators.SerialIterator(dataset, batch_size=10)
test_iterator = chainer.iterators.SerialIterator(dataset, batch_size=3, repeat=False)  # 10÷3なので余りがある！

# モデルとか
class Model(chainer.Chain):
    def __call__(self, x):
        x = chainer.Variable(x)
        chainer.report({'x_mean': chainer.functions.mean(x)}, self)
        return x

model = Model()
optimizer = chainer.optimizers.SGD().setup(model)
updater = chainer.training.StandardUpdater(train_iterator, optimizer)

# 学習
extensions = [
    chainer.training.extensions.Evaluator(test_iterator, model),
    chainer.training.extensions.LogReport(),
    chainer.training.extensions.PrintReport([
        'iteration',
        'main/x_mean',  # Updaterのxの平均
        'validation/main/x_mean',  # Evaluatorのxの平均
    ]),
]
trainer = chainer.training.Trainer(updater, stop_trigger=(5, 'epoch'), extensions=extensions)
trainer.run()
```

良さそうに見えるが、実際はUpdaterとEvaluatorで計算結果がずれてしまう。

```bash
iteration   main/x_mean  validation/main/x_mean
1           4.5          4.25
2           4.5          4.75
3           4.5          5.08333
4           4.5          4.75
5           4.5          4.41667
```

原因はすごく単純で、Updaterは10データ全部の平均を取っているのに対し、Evaluatorは**10データを3つずつ取って平均したものを平均している**から。最後の1バッチには1データしかなく、重みが変わっちゃうので、値が変わる。

回避策は2つある。

### 回避策1　重みを指定する
Evaluatorは内部で[DictSummary](https://github.com/chainer/chainer/blob/4deedf110031bb38b22bce87799e4b96734a43d2/chainer/reporter.py#L325)を使っていて、これは重み付き平均に対応している。
ちょっと直感的ではないが、計算結果と重みをタプルにして与えることができる。

```python
# モデルとか
class Model(chainer.Chain):
    def __call__(self, x):
        x = chainer.Variable(x)
        chainer.report({'x_mean': (chainer.functions.mean(x), len(x))}, self)  # 重み（データ数）と一緒にタプルにする
        return x
```

こうすると、計算結果もちゃんと補正される。

```
iteration   main/x_mean  validation/main/x_mean
1           4.5          4.5
2           4.5          4.5
3           4.5          4.5
4           4.5          4.5
5           4.5          4.5
```

### 回避策2　テストデータ数÷バッチサイズに余りが出ないようにする
愚直に余りが出ないようにすれば、計算結果はずれない。

```python
test_iterator = chainer.iterators.SerialIterator(dataset, batch_size=5, repeat=False)  # 10÷5なので余りがない！
```

```bash
iteration   main/x_mean  validation/main/x_mean
1           4.5          4.5
2           4.5          4.5
3           4.5          4.5
4           4.5          4.5
5           4.5          4.5
```

### その他
accuracyの遷移具合などを見るときは、人間が目でなんとなく平均すれば良いんけど、
Optunaとかで自動パラメータ調整するときとかは端数によっては偏りが無視できなくなって、
調整に支障が出てきそうだからちゃんと調べてみた。

別にこれはChainerに限った話ではなく、どのフレームワークでも起こり得るので、気をつけていきたい。
トーンエンコーダ／デコーダを作る

みなさんこんにちは

CTCSSという音声信号に更に低い音を付加して、聴こえる信号を
区別する方法があります。それをトーンスケルチと言います。

スケルチとはそもそもFMを受信するときに、信号が無い時に
雑音が出力されてしまうために、無信号時に復調回路を切る仕組み
なのですが、トーンスケルチは、それをさらに拡張したものです。

今では、コンピュータ搭載のチップを無線機が積んでいるので、
トーンスケルチ位は処理してしまいます。
ところが、昔の無線機はアナログ回路なのでそこまでの処理は
出来なかったので、専用のICがありました。
もちろん、トーンスケルチはアマチュア無線に限った話ではなく
当時のタクシー無線などにも使われていました。

今の世に、トーンスケルチを使う理由は？？となると思いますが、
アクセスしたい局を区別するためです。

基本、アマチュア無線は暗号化は許されていません。トーンスケルチを
使うと暗号化されるのでは？と思われると思いますが、特定の周波数の
音が載っているだけで、トーンデコーダを介さなければ、普通に聞こえます。という事で、暗号化せずに、選択できるのでよく使われる訳です。

前段はこれくらいにして、今時、トーンデコーダなんて売っているのか
と調べてみると、昔製造されたICがまだ残っているようです。
mn6520という、松下！のICです。
このIC、結構ジャンク屋で転がっているようですね。

昔の無線機にトーンデコーダを入れて、トーンスケルチを作ってやろうという目論見です。
今のところ、部品を発注したばかりなので、これからでしょうか。

もちろん、ラズパイで制御してやろうと考えています。

今日はこんなところで

図面とか、数式を貼れないので、もう少しQitaに慣れないとな
と思います。
Win7のIEショートカットの小技

今さらです。他に方法があれば、教えて下さい。

#「InPrivate ブラウズを開始する」のショートカット
win7のgoogleのホームで

ctrl+shift+P
alt+home

以下の画面がでます。
「
プライバシーの設定を確認しませんか
あなたにあったプライバシー設定になっているかを確認できます
後で確認する　確認する
」

###操作方法
(参考)履歴を残さずにネットを楽しみたいときは「InPrivate ブラウズ」がオススメ！
＞ちなみに、IEにメニューバーを表示されている場合、「ツール」→「インターネットオプション」→「全般」と選んでいき、「閲覧の履歴」という項目にある「終了時に閲覧の履歴を削除する」にチェックを入れておくことでも、同じ効果を得られる。
https://setsuzoku.nifty.com/koneta_detail/170307000243_1.htm

(参考)Internet ExplorerのInPrivateブラウズとホームページ設定を活用する
https://news.mynavi.jp/article/win81tips-64/

(参考)バッチファイルで「既定のブラウザ」をシークレットモード(InPrivateブラウズ、プライベートブラウジング)で起動する
https://qiita.com/riafeed/items/794013bc012fbff3ff1d
この先生きのこるためにデータアナリティクス分野を勉強したいな、というポエム

# そもそもの話

転職関係の企業分析をやっていて気づくのは、「データアナリスト」「データサイエンティスト」とかの分野じゃないかなぁとぼんやり思ったわけで(根拠は無いですが…)、そこらへんの話(妄想)をポエムしたいなと思います。

# というのも

データは貯めておくだけじゃたんなるストレージの肥やしにしかならず、どうせ肥やしになるぐらいなら適切かつ多方面に解析して、今後起こるであろうトレンドに備えたほうが食いっぱぐれがなさそうだねと

自分の会社で役に立ちそうなら結果を反映すればいいし(人工知能に食わせるなりしてサービスを立ち上げ)、直接関係なくても必要そうな業界に売ることもできる(いろんなところから出している「白書」の類)。

というか、こんな話昔っから知っとるわい！　と怒られそうですが(は、恥ずかしい…)、思い立ったが吉日というわけで、色々まとめてみようと…たんなるリンク集ですが。

# 役に立ちそうなリンク集

* [データサイエンスにおけるRubyの現在の位置づけと可能性](https://www.s-itoc.jp/report/reaserch_results/439)
  * Rubyといえば島根、島根といえばRubyのお膝元ですが、この記事はRubyでデータアナリティクスできるようにしたい！という意気込みを感じさせる記事です。
  * その代わり、SciRubyの影の薄さを嘆いていますが…
  * 記事が書かれたのは2016年なので、2019年にはどうなっているのか…

* [Rubyでデータ解析 - Daru入門](https://qiita.com/yohm/items/b63e20634f86b4f66f9d)
  * 簡単なデータ解析ならDaruというライブラリがありますよ、という話ですね

* [Anaconda公式サイト](https://www.anaconda.com/)
  * 私もML-Agentsでお世話になっているPythonの仮想環境ツールです。
  * 特に、学術計算分野に強く、Tensorflowとかnumpyとか普通に入れられますし。取捨選択して仮想環境として準備できるのも強みです

* [DAINOTE - Pythonでデータ分析する方法を初心者向けに解説してみた](https://dividable.net/python/python-data-analysis/#Web_API)
  * Pythonでデータ解析するための情報をまとめたブログ記事です

* [Python本まとめ・2019年版 - Webとデータ分析を初心者が仕事にするまで](https://shinyorke.hatenablog.com/entry/python2019)
  * こちらもデータ分析(Webページ解析も)をまとめた記事です
  * 「なぜ必要なのか」という解説もまとめてあるのでちょくちょくチェックしたいですね

# 最後に

やっぱりPythonのほうがデータ解析の分野では記事が多いですね…ただ、日本語の扱いはアレ(3.X系は進歩してるのかなぁ？)なときがありますが…(涙)
Unity ～子オブジェクトと孫オブジェクトの取得～

# 使い方
1. 親オブジェクトにアタッチします。
2. 動作させると子と孫の名前が表示されます。

※Debug.Logを処理に変えれば子や孫を操作できます。

# コード
```csharp
    void Start()
    {
        foreach (Transform childTransform in this.gameObject.transform)
        {
            Debug.Log(childTransform.gameObject.name); // 子オブジェクト名を出力
            foreach (Transform grandChildTransform in childTransform)
            {
                Debug.Log(grandChildTransform.gameObject.name); // 孫オブジェクト名を出力
            }
        }
    }
```
Objective-Cは型が弱いのではなく型が少ない

Objective-Cは以下の型を持つ

* 基本型
    * int
    * float
    * double
    * char
    * など
* 構造体
* 配列型
    * 要素数が異なれば型も異なる
* ポインタ型

# NSObjectインスタンスは全てポインタ型

NSObjectインスタンスを格納する変数をスタック領域に確保することは出来ない

```Objective-C
// コンパイルエラー
NSObject object;
```

必ずallocでポインタ型として受け取る必要がある

```Objective-C
NSObject *object = [[NSObject alloc] init];
```

ポインタ型は指し示す先の型が異なっても代入が可能

```Objective-C
NSString *str = @"Hello World";
NSNumber *num = str; // warning: incompatible pointer types

int a = 10;
float *f = &a; // warning: incompatible pointer types
```

# 異なる型への代入は出来ない

```Objective-C
int a = 10;
float b = a; // コンパイルエラー
```

キャストをする必要がある

```Objective-C
int a = 10;
float b = (float)a;
```

# まとめ

Objective-Cは型が弱いのではなく、**型が少ない** と言えます
【GAS】Twitterのリストの更新分をGmailに送る

#なんで作ろうと思ったか
元々はRSSリーダーをGASで実装しようと思ったのですが、作るのが意外と面倒でRSSのURL引っ張ってくるのも面倒だったのでTwitterのListをRSS代わりに使おうということになりました。
Twitter使えばいいじゃないってなりますが、Twitterは流して見るのが難しいのと更新分がわからないのでメールにしました。
LINEやSlackでしたい方はAPI使ってください。
###UI
- Twitterのリストの登録
- 1日に1回そのリストの更新分がメールで送られてくる
- リンククリックでそのサイトが開く

最短1分で1回実行できると思うので頻繁に更新確認したい方は調整してください。
メールはこんな感じです。
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242971/c75c9e61-6633-b5f1-9ad2-25c58a26f5fd.png)

###処理フロー
1. Twitterの特定のリストの読み込み
2. 時間でフィルタして更新分のみ取得
3. メール文への整形
4. メール送信

#ソース
Twitterの認証は参考資料1または参考資料2を参照してください。

```javascript

// 認証用インスタンス
var twitter = TwitterWebService.getInstance(
  //必要なライブラリ　1rgo8rXsxi1DxI_5Xgo_t3irTw1Y5cxl2mGSkbozKsSXf2E_KBBPC3xTF
  'aaa', // 作成したアプリケーションのConsumer Key
  'bbb'  // 作成したアプリケーションのConsumer Secret
);

// 認証
function authorize() {
  twitter.authorize();
}

// 認証解除
function reset() {
  twitter.reset();
}

// 認証後のコールバック
function authCallback(request) {
  return twitter.authCallback(request);
}

var service  = twitter.getService();

function getListTweets(listName, userName, count, retweet) {
  return JSON.parse(service.fetch('https://api.twitter.com/1.1/lists/statuses.json?slug='+ listName +
                                  '&owner_screen_name=' + userName +
                                  '&count=' + count +
                                  '&include_rts=' + retweet));
}

function getHtmlBodyFromListUpdate(listName, userName, periodHour) {
  //@userNameのlistNameリストを200ツイート分読み込む、リツイートはなし(false)
  return getListTweets(listName, userName, 200, false)
  .filter(function(x) { 
    //periodHour時間以内のツイート取得。x.created_atは東京時間ではないがnew Dateが
    //勝手に東京時間にしてくれる、えらい。getTime()でミリ秒取得
    return new Date(x.created_at).getTime() > new Date().getTime() - periodHour * 60 * 60 * 1000
  }).map(function(x) { 
    //ツイート内部の改行削除
    return x.text.replace(/\n/g, '') 
  }).reduce(function(acc, cur) { 
    //見た目の処理。URLが2つある場合は最初のURLが使用される。残りは消える。
    const url = pullUrls(cur)[0];
    return acc + '<li><a href=' + url + '>'  + removeUrls(cur) + '</a></li><br>' 
  }, '<ol>') + '</ol>';
}

//文字列内のURLをすべて取得する。返り値は配列
function pullUrls(str) {
  const urls = str.match(/(http(s)?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/gi);
  return (urls == null) ? [] : urls;
}
//文字列内のURLをすべて削除する。返り値はURLのなくなった文字列
function removeUrls(str) {
  return str.replace(/(http(s)?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/gi, "");
}

function main() {
  const htmlBody = getHtmlBodyFromListUpdate('listName', 'userName', 24)
  GmailApp.sendEmail('xxx@email.address', 'ニュースまとめ', '', {htmlBody: htmlBody})
}
```

#あとがき
設定した時間内のツイートが200以上だと漏れが出る。これはAPIの仕様なので仕方ない。実行時間を早めるなどしてください。(periodHourの変更)
ニュースチェックのために作ったので、ツイート内にリンクがある前提で書いてます。リンクなしのツイートも問題なく動くと思いますが、無効なリンクが貼られるので適当に修正してくだいさい。

#参考資料
1. [Google Apps Script (GAS) でTwitterへ投稿するだけの機能を実装してみる](https://qiita.com/akkey2475/items/ad190a507b4a7b7dc17c)
2. [GASでTwitterの投稿とタイムライン取得](https://qiita.com/golyat/items/6b430986dbfd8dd1c239)
3. [GET lists/statuses — Twitter Developers](https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses)
Rubyのシンタックス勉強用（push, shift, unshift）[RUBY技術者認定試験...問題16]

# 基本説明

配列操作系のメソッド。`push`, `shift`, `unshift`を一気に学べる良問があったので共有します。

| メソッッド名 | 説明 | 戻り値 | 破壊的？ |
|-----------|------------|------------|------------|
| push       | 配列の **末尾** に引数を要素として追加 | レシーバ自身 | TRUE |
| shift     | 配列の最初の要素を削除し、その要素を返す。配列が空のときはnilを返す。 | 削除した要素 | TRUE |
| unshift       | 配列の **先頭** に引数を要素として追加 | レシーバ自身 | TRUE |

オブジェクト自身（レシーバ）の内容を変えてしまうものを破壊的メソッド。

# 例題

以下の出力結果は？

```rb
ary = %w(a b c d e)
ary.push(ary.shift)
ary.unshift(nil)
p ary
```

RUBY技術者認定試験 公式ガイド (ITpro BOOKs)　153p 問題16より抜粋

# 実行結果は以下でサクッと試せます

[Online Ruby Editor and IDE \- Fast, Powerful, Free \- Repl\.it](https://repl.it/languages/ruby)

# 参考

- [push \(Array\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/push)
- [shift \(Array\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/shift)
- [unshift \(Array\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/unshift)

# 正解

- 例題： `[nil, "b", "c", "d", "e", "a"]`

```rb
ary = %w(a b c d e) # => ["a", "b", "c", "d", "e"]
ary.push(ary.shift) # => ["b", "c", "d", "e", "a"]
ary.unshift(nil) # => [nil, "b", "c", "d", "e", "a"]
p ary # => [nil, "b", "c", "d", "e", "a"]
```
10分ではじめるpuppeteer


```text:Terminal
brew install nodebrew

$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
$

$ mkdir -p ~/.nodebrew/src
$ cd ~


$ nodebrew install-binary latest
Fetching: https://nodejs.org/dist/v12.10.0/node-v12.10.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully

$ nodebrew use v12.10.0
use v12.10.0

$ node -v
v12.9.0

$ npm install --save puppeteer

> puppeteer@1.20.0 install /Users/%user%/node_modules/puppeteer
> node install.js

Downloading Chromium r686378 - 110.2 Mb [====================] 100% 0.0s 
Chromium downloaded to /Users/%user%/node_modules/puppeteer/.local-chromium/mac-686378
npm WARN saveError ENOENT: no such file or directory, open '/Users/%user%/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/Users/%user%/package.json'
npm WARN %user% No description
npm WARN %user% No repository field.
npm WARN %user% No README data
npm WARN %user% No license field.

+ puppeteer@1.20.0
added 43 packages from 22 contributors and audited 50 packages in 11.012s
found 0 vulnerabilities


saveError ENOENT: no such file or directory, open '/Users/%user%/package.json'
package.jsonが存在していない


$ npm init --yes
Wrote to /Users/%user%/package.json:

{
  "name": "%user%",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "puppeteer": "^1.20.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}




   ╭────────────────────────────────────────────────────────────────╮
   │                                                                │
   │      New minor version of npm available! 6.10.3 → 6.11.3       │
   │   Changelog: https://github.com/npm/cli/releases/tag/v6.11.3   │
   │               Run npm install -g npm to update!                │
   │                                                                │
   ╰────────────────────────────────────────────────────────────────╯

$ ls package.json
package.json


$ npm install --save puppeteer

> puppeteer@1.20.0 install /Users/%user%/node_modules/puppeteer
> node install.js

Downloading Chromium r686378 - 110.2 Mb [====================] 100% 0.0s 
Chromium downloaded to /Users/%user%/node_modules/puppeteer/.local-chromium/mac-686378
npm WARN %user%@1.0.0 No description
npm WARN %user%@1.0.0 No repository field.

+ puppeteer@1.20.0
updated 1 package and audited 50 packages in 9.048s
found 0 vulnerabilities

$ cd puppeteer/
$ node scraping_google_co_jp.js 
$

正常に動作！
```

* 参考になった技術まとめ
  * [puppeteerを体験してみた](https://qiita.com/AYA_iro/items/e5dd0956b3ba82f6bf31)
ElmのHTTPで空レスポンスを許容するresolverのコード

これ

```elm
emptyResolver : Http.Resolver Http.Error ()
emptyResolver =
    Http.stringResolver <|
        \response ->
            case response of
                Http.BadUrl_ url ->
                    Err (Http.BadUrl url)

                Http.Timeout_ ->
                    Err Http.Timeout

                Http.NetworkError_ ->
                    Err Http.NetworkError

                Http.BadStatus_ { statusCode } _ ->
                    Err (Http.BadStatus statusCode)

                Http.GoodStatus_ _ _ ->
                    Ok ()
```
JavaScriptにおけるconst {a, b, c} = data; の手法名

検索しようと思って毎回忘れるのでメモ。
とりあえず名前がわかればその後はググれる。

オブジェクトの**分割代入**という。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Arrayも可能。

```javascript
const [a,b] = [1,2];
```

キー名の変更も可能。感覚とは逆に指定するので注意

```javascript
var {aa: a , bb: b } = {aa: 3, bb: 5};
```


デフォルト値の設定もできる

```javascript
var {a = 10, b = 5} = {a: 3};
```
Unity ～画像のフェード～

# 使い方
1. オブジェクトのImageの透明度を0にします。
2. スクリプトをアタッチします。
3. 動作させるとフェードインし始めます。

※活用
事前にオブジェクトを非アクティブ化させておき、
フェードインさせたいタイミングでsetActive(true)することで任意のタイミングでフェードインさせることが出来ます。

# 動作
フェードさせたいオブジェクトにアタッチすると、fadeStartの時間経過後にフェードインを開始します。
publicにしているので、数値を変えることで開始時間及び速度を変更できます。
fadeInのbool変数が仕事してないですが、拡張することでフェードアウトもできるのでもしよければ。




# コード
```csharp

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class fade : MonoBehaviour
{

    GameObject me; // 自分のオブジェクト取得用変数
    public float fadeStart = 1f; // フェード開始時間
    public bool fadeIn = true; // trueの場合はフェードイン
    public float fadeSpeed = 1f; // フェード速度指定


    // Start is called before the first frame update
    void Start()
    {
        me = this.gameObject; // 自分のオブジェクト取得
    }

    // Update is called once per frame
    void Update()
    {
        if (fadeStart > 0f)
        {
            fadeStart -= Time.deltaTime;
        }
        else
        {
            if (fadeIn)
            {
                fadeInFunc();
            }
        }
    }

    void fadeInFunc()
    {
        if (me.GetComponent<Image>().color.a < 255)
        {
            UnityEngine.Color tmp = me.GetComponent<Image>().color;
            tmp.a = tmp.a + (Time.deltaTime * fadeSpeed);
            me.GetComponent<Image>().color = tmp;
        }
    }
}
```
Node.js: UNIXドメインソケットを扱うリバースプロキシを立てる方法

本稿では、UNIXドメインソケットで待ち受けているHTTPサーバを対象とした、リバースプロキシの立て方を説明する。リバースプロキシを立てるにあたっては[http-proxy]パッケージを使う。本稿のサンプルコードはTypeScriptで書く。

[http-proxy]: https://github.com/http-party/node-http-proxy

## 本稿のゴール

UNIXドメインソケットでListenしているHTTPサーバを対象とした、リバースプロキシをNode.jsで作れるようになる。

## http-proxyをUNIXドメインソケットに向ける実装例

下記に示すコードは、http-proxyでプロキシサーバを立て、UNIXドメインソケットでListenしているHTTPサーバにリクエストを転送するものである。

```ts
import http, {IncomingMessage, ServerResponse} from 'http'
import httpProxy from 'http-proxy'
import fs from 'fs'

const socketFile = '/tmp/http.sock'

fs.existsSync(socketFile) && fs.unlinkSync(socketFile) // ファイルがあるとHTTPサーバが起動しないため

// HTTPサーバ(Unixドメインソケットでリッスンしている)
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    res.write(JSON.stringify(req.headers, null, 2)) // リクエストヘッダをレスポンスBodyに出す
    res.end()
}).listen(socketFile)

// プロキシサーバ
const proxy = httpProxy.createProxyServer()
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    proxy.web(req, res, {
        target: {
            // @ts-ignore
            socketPath: socketFile,
        },
    })
}).listen(8000)
```

ポイントは、`proxy.web`の第3引数のオプションに`target.socketPath`を与え、そこにソケットファイルのパスを指定するところ。

### `@ts-ignore`を付けている理由

そもそも`target`は`string | url.URL`しか受け付けないインターフェイスになっている。しかし、`{ socketPath: string }`型を渡すと、内部実装上ソケットファイルを読み込めるようにはなっている。`@ts-ignore`をつけることで、`string | url.URL`の制限を迂回している。当然、型安全性は犠牲にしている。加えて、言うなれば、プライベートAPIを叩いているような形にはなる。インターフェイスの仕様が変更されたら、この方法は使えなくなるかもしれない。

## 参考文献

* [Node.jsのhttp.ServerでUNIXドメインソケットを使う - Qiita](https://qiita.com/suin/items/e205b70b5d80fff6bdf5)
* [TypeScript: node-http-proxyを用いリクエスト/レスポンスを書き換えるリバースプロキシを作る方法 - Qiita](https://qiita.com/suin/items/ff1cd56823d2eb0462f3)
MySQL のテーブルを InnoDB に一括変換する方法


MySQL のテーブルを一括で InnoDB に変換する方法です。

MySQL データベース一覧を取得し、InnoDB に一括変換する SQL をコマンドで作成し、実行する方法を解説します。

# 手順

## 1. バックアップ

データベースをバックアップします。

## 2. 実行用 SQL を生成

MySQL のテーブル一覧をリストし、SQL ファイルとして一括変更できる準備をします。

```
(mysql -h {DB Host} -u {DB User} -p {DB Name} -e "show tables" --batch --skip-column-names | xargs -I{} echo 'alter table `'{}'` ENGINE=InnoDB;') > alter_innodb_$(date +%Y%m%d%H%M%S).sql
```

文字列を以下のように書き換えて実行します。

文字列     | 書き換え先
----------|------------
{DB Host} | DB ホストアドレス
{DB User} | DB ユーザー名
{DB Name} | DB 名

alters_20190924XXXXXX.sql といったファイル名で SQL ファイルが生成されます。

## 3. SQL ファイルを確認 & 編集

SQL ファイルを確認し、MyISAM テーブルのままでいたいテーブルを削除します。

例えば concrete5.6.4.0 では、

- FileVersions
- PageSearchIndex
- PageStatistics

この3つのテーブルは MyISAM のままで良いので、
SQL ファイルを編集してこの3行を探し削除します。

## 4. SQL を実行

生成された SQL を実行。

```
mysql -h {DB Host} -u {DB User} -p {DB NAME} < alter_innodb_XXXXXXXXXXXX.sql
```

## 5. 確認

Squel Pro などの MySQL クライアントソフトを使って確認


以上
[Rails]referencesを使用した外部キー設定で沼った

#referencesを使用した外部キー設定
`Rails`で`references`を用いて外部キーの設定を行おうとしたら、

> Mysql2::Error: Table 'テーブル名' doesn't exist: SHOW FULL FIELDS FROM ...

といったエラーがでてだいぶ時間を取られてしまったのでどう解決したかを備忘録として記します。


#エラーとなった実装
エラーとなってしまった`migration`ファイルは次のようなものでした。

※`table_names`というテーブルのカラムである
`user_id`を`user.id`に、
`book_id`を`book.id`に紐付けたい。


```ruby

class ClassName  < ActiveRecord::Migration[5.1]
  def change
    create_table :table_names do |t|
      t.references :user, foreign_key: true,
      t.references :book, foreign_key: true
    end
  end
end
```

同じ事例を調査していたところ次のような記事を発見。
[Rails5.1に移行後のmigrationファイルの注意](https://qiita.com/umeneri/items/b46c537661f612f7318b)

この記事によると、Rails5.1後に作成する`migration`ファイルはデフォルトでidカラムに`bigint`型を使う(Mysqlの場合)
不都合が生まれるケースが生じる場合があるとのこと。

確かに今回私のケースでは、userが`integer`型でbookが`bigint`型で行っている。



記事を参考にし、以下のようにコードを修正。


```ruby

class ClassName  < ActiveRecord::Migration[5.1]
  def change
    create_table :table_names do |t|
      t.integer :user_id, foreign_key: true
      t.bigint :book_id, foreign_key: true
    end
  end
end
```

修正後、確かにエラーは消えるが、当たり前だがこれでは外部キー設定が何もできていない。。笑


#解決策
とりあえず、型の関係でエラーとなっていることは分かった。
ということで、`references`を用いた上で`type`を指定してあげることに。

```ruby

class ClassName  < ActiveRecord::Migration[5.1]
  def change
    create_table :table_names do |t|
      t.references :user, type: :integer, foreign_key: true,
      t.references :book, type: :bigint, foreign_key: true
    end
  end
end
```

これでうまいこと実行できた。
こんなことにすごく時間をかけてしまった。
Ruby言語によるクラスの定義とクラスメソッドの定義及びクラスメソッドの呼び出し

# 学習
ここのところ、毎日少しでも時間があればruby言語の基礎の復習をやりアウトプットのつもりで
ここに投稿させていただいてます。
今日はRuby言語による、クラスの定義とクラスメソッドの定義、クラスメソッドの呼び出しを軽くおさらいする為に載せておくことにします。

# クラスの定義
```ruby:sample_calss.rb
class Review

end
```
これで最もシンプルなクラスの定義ができる

# インスタンスの生成
+ newメソッド

```ruby:sample_calss.rb
class Review

end
review = Review.new # Reviewクラスのインスタンスを生成
puts review
```
ターミナルから```ruby sample_class.rb```と実行すると

```terminal:result
#<Review:0x00XXXXXXXXXX>
````
とReviewクラスのインスタンスの生成に成功していることがわかる。

# クラスメソッド
+ クラスメソッドの定義

クラスメソッドはメソッド名の前に```self.```を付ける

```ruby:classMethod.rb
class クラス名
  def self.メソッド名
    # 処理
  end
end
```
+ 呼び出し

クラス名に続けてメソッド名を書く。引数は()のなかに入れる。これは普通のメソッドと同様。

```
クラス名.メソッド名(引数)
```
+ 代表的なクラスメソッドはnewメソッドがある。

```ruby:sample.rb
user = User.new # newメソッド
```
# Reviewクラスにクラスメソッド```get_review_count```を定義してみる。
```ruby:sampl_class.rb
class Review
  def self.get_review_count
    return 0
  end
end

review = Review.new # Reviewクラスのインスタンスを生成
puts review

puts Review.get_review_count # get_review_countの呼び出し
```
最後にクラスメソッド```get_review_count```を呼び出しているので0を返す。
# まとめ
クラスメソッドはクラスが使用できるメソッドであり、クラスメソッドを定義したクラス自身が使用できる。
```クラスで共通の情報を使った処理```に使用される。
redirect_to url and return ってなんだろうか

[railsチュートリアル リスト11.40から引用](https://railstutorial.jp/chapters/account_activation?version=5.1#sec-mailer_templates)

```ruby
  def show
    @user = User.find(params[:id])
    redirect_to root_url and return unless @user.activated?
  end
```

上記のコードが行なっていることはなんとくわかるのですが`and return`が何をしているのか詳しく理解できたいなかったので調べてみることにしました。


まずは`and return`から調べていきます。

参考資料:[2.2.14 二重レンダリングエラー](https://railsguides.jp/layouts_and_rendering.html#%E4%BA%8C%E9%87%8D%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E9%81%BF%E3%81%91%E3%82%8B)


"Can only render or redirect once per action" 
例

```ruby
def show
  @book = Book.find(params[:id])
  if @book.special?
    render action: "special_show"
  end
  render action: "regular_show"
end
```


上記の例では"Can only render or redirect once per action" エラーになってしまいます。理由として
例えば@book.special?がtrueの場合、レンダリングを開始し、@book変数をspecial_showビューに転送します。
しかし、showアクションのコードはそこでは止まりません。showアクションのコードは最終行まで実行され
regular_showビューのレンダリングを行おうとします。ここでエラーが出力されます。1つのコード実行パス内では、renderメソッドやredirectメソッドの実行は1度だけにしなければなりません。ですので明示的にreturnが必要にな
ります。修正したコードを以下に示します。


```ruby
def show
  @book = Book.find(params[:id])
  if @book.special?
    render action: "special_show"
    return
  end
  render action: "regular_show"
end
```

ここで`render action: "special_show"`とreturnを一行にして可読性をあげるために`and `を使います。
修正したコードを以下に示します。


```ruby
def show
  @book = Book.find(params[:id])
  if @book.special?
    render action: "special_show" and return
  end
  render action: "regular_show"
end
```

`&&`を使用すると評価の優先順位が高くてうまく機能しないため注意です。([優先順位参考資料](https://www.xmisao.com/2014/03/05/ruby-difference-between-and-and-or-or.html))
また`render` の戻り値が`ture`の以外の場合は`return`は実行されないのも注意です。

ここまで`render`の話でしたが`redirect_to`でも同じように`redirect_to`を行なっても即時にメソッドが中断され
ることはないので上記のように`and return`を使用します。
tsconfig.jsonのrootDirとbaseUrlに関するメモ [TypeScript]

# はじまり
TypeScriptのtsconfig.json
パラメータ多くてどれがどういう作用を及ぼすのかいまいちです。

今回はtsconfig.jsonでよくわかっていなかった
**rootDir**と**baseUrl**の動きについてメモ。

# rootDir
TypeScriptのソースコードがあるディレクトリを指定する。

## 例) こんな感じのフォルダ構成だったとして

```
project_root
  ┣━ src
  ┃  ┣━ index.ts
  ┃  ┗━ foo.ts
  ┣━ hoge.ts
  ┗━ tsconfig.json
```

**rootDir**に**./src**と指定した場合

```tsconfig.json
{
  "compilerOptions": {
    "rootDir":"./src",
  }
}
```

**./src**の外にあるソースコードを参照できなくなる。

```index.ts
import * from '../hoge'; // ← これがNGになる
import * from './foo'; // ← これはsrc配下なのでOK
```

## まとめ
**rootDir**は変なところにあるソースコードを無理やり参照するようなコードを防げる。


# baseUrl

> /* Base directory to resolve non-absolute module names. */

コメントにはこう書いてある。
**非絶対モジュール名を解決するためのベースディレクトリ**

要するに絶対パス指定じゃない場合、どこを基準のフォルダにします？
というパラメータ

## 例) こんな感じのフォルダ構成だったとして

```
project_root
  ┣━ src
  ┃  ┣━ index.ts
  ┃  ┗━ foo.ts
  ┣━ hoge.ts
  ┗━ tsconfig.json
```

**baseUrl**に**./**を指定した場合

```tsconfig.json
{
  "compilerOptions": {
    "baseUrl":"./",
  }
}
```

モジュールを指定する際、以下のようになる。

```index.ts
import * from 'foo';      // これはNG
import * from 'src/foo';  // これはOK
import * from './foo';    // 相対パス指定もOK
```

## まとめ

というわけで**baseUrl**はパスの起点が書かれていない場合に使われる。

他にもStorybookを使おうとすると、baseUrlを指定しろと言われたり
tsconfig.jsonの**paths**(エイリアスの設定)などを使う場合もbaseUrlを指定しとかないといけない。

# おわり
他にもこんな動きがある、それ間違ってるなどあれば
コメントで指摘お願いします。
MySQL のエンコーディングを utf8 から utf8mb4 に変換する方法


オープンソース CMS 「[concrete5](https://concrete5-japan.org)」も、 utf8mb4 に完全対応しました。

ただ、昔のサーバーにインストールした時、デフォルトの設定で UTF8 になってしまったので、作成済みの DB や DB 内のテーブルを一括で utf8mb4 に変換する必要があります。その方法です。

# 手順

## 1. バックアップ

データベースをバックアップします。


## 2. my.cnf に文字コードを設定

サーバーとクライアントの文字コードを設定

```
[mysqld]
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4

```


## 3a. concrete5 で UTF8 から UTF8mb4 に変更

concrete5 CMS は CLI コマンドで文字列を一気に変更できます。
config ファイルも書き換えてくれます。
管理画面から出来ますが、DBが大きいとタイム・アウトするので、CLI から実行することをおすすめ

```
$ cd [concrete5 へのパス]
$ concrete/bin/concrete5 c5:database:charset:set utf8mb4
```

## 3b. 手動で実行する (concrete5 のコマンドで修正できない時)

なんらかの原因で 3a の CLI コマンドだけで修正できない場合、手動で MySQL テーブルの文字コード設定を編集する必要があります。以下は手動で MySQL のコンソールから設定を修正する方法です。

サーバーの設定も変更しないとエラーが出る場合があります。特に MySQL 5.6 とそれ以前のバージョンは気をつけてください。


### 3b-1. データベースのキャラクターセットを変更

データベースの文字列を変更します。
MySQL にログインし、MySQL コマンドを実行します。

```
$ mysql -h {DB Host} -u {DB user} -p {DATABASE_NAME}
mysql> ALTER DATABASE {DB Name} DEFAULT CHARACTER SET utf8mb4;
mysql> ALTER DATABASE {DB Name} COLLATE utf8mb4_general_ci;
```

データベースの設定は完了です。


### 3b-2. 変更用 SQL ファイルを生成

MySQL からログアウトしてシェルに戻ります。

既存のDBテーブルを取得し、文字コードを変更する SQL を生成します。

```
$ (mysql -h {DB Host} -u {DB user} -p {DB Name} -e "show tables" --batch --skip-column-names | xargs -I{} echo 'alter table `'{}'` convert to character set utf8mb4;') > alters_$(date +%Y%m%d%H%M%S).sql
```

文字列を以下のように書き換えて実行します。

文字列     | 書き換え先
----------|------------
{DB Host} | DB ホストアドレス
{DB User} | DB ユーザー名
{DB Name} | DB 名

### 3b-3. SQL ファイルを実行して変更を適用

生成された SQL を実行。

```
mysql -h {DB Host} -u {DB User} -p {DB NAME} < alters_XXXXXXXXXXXX.sql
```

### 3b-4. MySQL を再起動

my.cnf の設定変更を適用するため MySQL サーバーを再起動します。


## 7. 変更 確認方法

MySQL テーブルの文字列設定を確認します。
MySQL サーバーにログインして確認します。

```
mysql> show variables like "chara%";
mysql> use {DB NAME};
```

Squel Pro などの MySQL クライアントソフトを使って確認してもらっても構いません。

# トラブルシューティング

## 255 character error

concrete5 の CLI を実行していた時、下記のようなエラーが出るときがあります。

```
[ERROR] The database does not support index fields with a length up to 255 characters when using the collation "utf8mb4_general_ci"
```

my.cnf や DB 内で

```
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
```

等と `STRICT_TRANS_TABLES` の表記があったら、それを削除してください。

## MySQL 5.6 以下での対応方法

MySQL 5.6 以下であれば、デフォルトの設定が違います。以下の設定を追加し、MySQL を再起動しましょう。 

```
innodb_file_format=Barracuda
innodb_file_per_table=ON # MySQL 5.6.6+ はデフォでオン
innodb_large_prefix=ON
```
#docker | docker run -it bash が使えないときは --entrypoint=bash とかでエントリーポイントを上書きしてみてください母より。

DockerfileとかでENTRYPOINTが設定されているときは、コマンドよりもそちらの方が強い。

```
docker run -it some-docker-image bash
```

次のようにエントリーポイントを書き換えると動いたりする場合がある。以上。父より。

```
docker run -it --entrypoint=bash some-docker-image
```

```
docker run -it --entrypoint=sh some-docker-image
```

```
docker run -it --entrypoint=ash some-docker-image
```



# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2520








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Pythonのコードを何も考えずにフォーマットする方法



**2023/09 更新**
black + ruff を使うようになりました。

**2021/07 更新**

[pfnet/pysen](https://github.com/pfnet/pysen) を使うのが良いと思います。

----


ライブラリに任せる。

# 使うライブラリ
## [isort](https://github.com/timothycrosley/isort)
importのソートをしてくれる
`$ isort -rc -sl .`で、importをすべて1行のimportに変換してくれる。
`$ isort -rc -m 3 .`で、importをすべて複数行のimportに変換してくれる。

## [autoflake](https://github.com/myint/autoflake)
pyflakesによって報告された未使用のインポートと未使用の変数を削除する。
複数行importの未使用importは削除してくれないので、前後にisortで整える。

## [black](https://github.com/psf/black)
妥協のないPythonコードフォーマッター


# 使い方
```bash
$ pipenv install isort autoflake black
```

```:Makefile
fix:
	isort -rc -sl .
	autoflake -ri --remove-all-unused-imports --ignore-init-module-imports --remove-unused-variables .
	black .
	isort -rc -m 3 .
```

```bash
$ pipenv run make fix
```
Node.jsのhttp.ServerでUNIXドメインソケットを使う

本稿ではNode.jsのビルトインモジュール[http]を使い、UNIXドメインソケットをリッスンするHTTPサーバの立て方を説明する。サンプルコードにはTypeScriptを用いる。

[http]: https://nodejs.org/api/http.html

# 本稿のゴール

Node.jsの`http.Server`でUNIXドメインソケットを使ったHTTPサーバを立て、そのサーバとHTTPで話してみる。

# http.Serverでドメインソケットを使う

ドメインソケットをリッスンするHTTPサーバの立て方の実装例を示す。

```ts
import http, {IncomingMessage, ServerResponse} from 'http'
import fs from 'fs';

const socketFile = '/tmp/http.sock'

fs.existsSync(socketFile) && fs.unlinkSync(socketFile) // ソケットファイルがあるとHTTPサーバが起動しないため

// HTTPサーバ
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    res.write('Hello!')
    res.end()
}).listen(socketFile)
```

ポイントとしては、`listen`関数にポート番号を与えるのではなく、ソケットファイルのファイルパスを与えること。与えられたファイルパスにファイルがあるとHTTPサーバは起動しない。そのため、`listen`を呼び出す前にソケットファイルが無いことを確認しておく必要がある。

# ドメインソケット越しにHTTPサーバと話す

ドメインソケットを通じて、HTTPサーバにリクエストを送ってみる。ここでは`nc`コマンドを使う。

```bash
echo -e "GET / HTTP/1.1\nHost:localhost\n" | nc -U /tmp/http.sock
```

出力結果

```http
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2019 09:56:25 GMT
Connection: keep-alive
Transfer-Encoding: chunked

6
Hello!
0

```

HTTPサーバからのレスポンスが表示される。

## 参考文献

* [HTTP | Node.js v12.10.0 Documentation](https://nodejs.org/api/http.html#http_server_listen)
* [Net | Node.js v12.10.0 Documentation](https://nodejs.org/api/net.html#net_server_listen)
Rewriteモジュール+PHPでもっと賢いWebP画像の選択配信

ブラウザのWebP対応/非対応に応じ、ApacheでWebP画像の配信を振り分ける方法について以前、書きました。

.htaccessによるWebPの選択的レスポンスとその問題点と改善案
https://qiita.com/miyanaga/items/6570c3c9ae8e15dbb57c

バッチ処理によるWebPファイルの作成はこちら
https://qiita.com/miyanaga/items/94b5bb42501e2292fb67

オリジナルの画像(Jpeg、PNG、GIF)と、それに対応するWebP画像がある場合、対応ブラウザにはWebP、非対応ブラウザにはオリジナル画像を自動で配信する方法を説明しています。

# オリジナル画像差し替え問題

上記の方法は手軽なのですが、弱点があって**オリジナル画像を変更して上書きすると次のバッチ処理までWebP画像の不一致**が生じてしまいます。

新規の画像であれば、WebP画像がないうちはすべてのブラウザにオリジナル画像が配信されるので問題ないのですが、後でオリジナル画像だけ内容が変更されると、**次のバッチ処理までWebP画像の追従を待たなければなりません。**

SafariやIEだと新しい画像が表示され、ChromeやFirefoxだと古い画像が表示される時間帯ができてしまいます。

# ファイルの更新日も見て比較したいがRewriteでは無理

そこでWebP画像の有無に加え、その更新日がオリジナル画像の更新日より新しいときにWebP画像を配信するようにしたくかなり試行錯誤しましたが、Rewriteモジュールだけでは無理そうでした。

# PHPでファイルの更新日も判別してみる

そこで簡単なPHPスクリプトでオリジナル画像とそのWebPフォーマット画像の有無と更新時間を比較して振り分けをするサンプルを作ってみました。

ApacheのRewriteモジュールとPHPによる更新日を考慮したWebP画像の振り分けサンプル
https://github.com/ideamans/php-webp-rewrite-image

気楽に作り始めましたが、ただの静的ファイルのWeb配信でも考えなきゃいけないことが多いもんだなーと再確認…

## 中小規模のサイトであれば使えそう

PHPを使ってファイルの更新日を比較してWebP画像とオリジナル画像の振り分けを行えば、いつでも気軽に画像を差し替えできて楽ちんです。

一方で画像についてWebサーバーの挙動(キャッシュまわり)が一部、Apache設定ファイルで変更できなくなるのは手間です。

## ベンチマーク

それより気になるのは、画像リクエストでPHPを毎回実行することによる遅延と負荷でした。

一応手元のマシンでベンチマークをとってみました。
https://github.com/ideamans/php-webp-rewrite-image#%E3%83%99%E3%83%B3%E3%83%81%E3%83%9E%E3%83%BC%E3%82%AF

一般的なWebサーバーでも平常時であれば数ミリ〜十数ミリ秒くらいの遅延ではないかと思います。

負荷にシビアではない中小規模のサイトで、画像の差し替えが頻繁に行われるような現場で、PHPを使ったこのやり方もありです。

# Apache 2.5からはApache単独でできそう！

Apache 2.4から設定ファイルにおいて`<If>`ディレクティブで動的な条件分岐が記述できるようになったようです。

Apache コア機能
https://httpd.apache.org/docs/2.4/ja/mod/core.html#if

しかもファイルの更新日を取得する`filemod`関数もあるじゃん！
https://httpd.apache.org/docs/current/expr.html

…と思ったのですが、どう頑張っても`filemod`関数がエラーに。

しれっと`filemod`が書いてありますが、どうやら2.5から使えるようになる模様です。

Apache httpd 2.5.0-aplhaには`filemod`あり
https://github.com/apache/httpd/blob/2.5.0-alpha/server/util_expr_eval.c#L1509

2.4.xにはいまのところ`filemod`なし
https://github.com/apache/httpd/blob/2.4.41/server/util_expr_eval.c

`RewriteRule`と`If`って組み合わせられるの？と心配しましたが、Apache 2.4系で試したところ大丈夫そうでした。

今度Apache 2.5をビルドして検証してみます。
#docker alpine のデメリットは  yum や apt-get がなくて apk っていう Alpine 専用パッケージ管理システムを使う必要があるところ、かな？

# パッケージ管理ツール

- Ubuntu なら apt-get
- Centos なら yum
- Apline では apk 

[Alpine Linux - Wikipedia](https://ja.wikipedia.org/wiki/Alpine_Linux)

>Alpine Linuxは独自のパッケージ管理システムとしてAPKを採用している。最初の頃はシェルスクリプトによって書かれていたが[12]、現在はC言語によって書き直されている[13]。GNOME・FFmpeg・Mozilla Firefoxなどが利用できる[14]。

 # 最初は bash が使えないけど？

これも apk add すれば使えるようになるし、ね。

```
$ docker run -it alpine ash
/ # apt add bash
/ # bash
bash-5.0#
```


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2519








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【備忘録】Lambda(node)でレスポンスを返す方法

# 3通り

### async関数でreturn(Promiseを返す)

```javascript

exports.handler = async (event) => {
    return // レスポンス
}
```

### context.done() | context.succeed() | context.fail()

```javascript

exports.handler = (event, context) => {
    context.done(null, /*レスポンス*/)
}
// 第一引数に何か入れるとfail
```

```javascript

exports.handler = (event, context) => {
    context.succeed(/*レスポンス*/)
}
```

### callback()

```javascript

exports.handler = (event, context, callback) => {
    callback(null, /*レスポンス*/)
}
// 第一引数に何か入れるとfail
```

## contextとcallbackの違いについて

context.done()などの場合は呼ばれた瞬間にレスポンス返るのに対して、
callback()の場合はLambda内で動いている処理が全て終わるまで待機する。
使い分けができるとかなり便利。
JS探し

クリックしたら動くイベントを探すとき
コンソール画面で
要素のイベントをゲットしたら見れる

```
$._data($('button[name="edit_button"]').get(0), "events");
```
handler 右クリックshowXXx

>https://qiita.com/zaru/items/b7732ebad9b732518359
PAIPの2章 A Rule-Based Solutionでプリキュアの文章を作ってみた

いつもプリキュアエンジニアになりたいと思っている46歳です。つまりこれはポエム枠です。

[RustのマクロでPAIPの2章 A Rule-Based Solutionをやってみた](https://qiita.com/natsutan/items/19987949cc55973d5ecc)


このアルゴリズムを使って、頭が悪そうなプリキュアの文章を作ってみました。マクロ定義などはそのままで、ルールだけ変更しました。

```rust
composite_rule!(sentence,   ->, shubu, jutubu);
composite_rule!(shubu,      ->, precure, joshi);
composite_rule!(jutubu,     ->, syusyokubu, jutugo);
composite_rule!(precure,    ->, pre, cure);
composite_rule!(syusyokubu, ->, obj, joshi2);

simple_rule!(joshi,  ->, "は が");
simple_rule!(joshi2, ->, "が を と");
simple_rule!(jutugo, ->, "好き 戦う 会う 食べる");
simple_rule!(pre,    ->, "キュア キュア キュア シャイニー");
simple_rule!(cure,   ->, "ブラック ホワイト ルミナス マリン エール ミルキー");
simple_rule!(obj,    ->, "ザケンナー たこやき キリヤくん カッパード");
```

単にcomposite_rule!(precure, ->, pre, cure);で面白いプリキュアできないかなと思っただけです。rustのマクロが上手く抽象度を上げているので、エラーに悩ませることなくルールを追加、修正できます。

このルールで先の実行してみると、頭悪そうなプリキュアの文章が無限に生成できます。やってから気が付いたんですが、ルールの再利用をしていないので適当にランダムに選んでいるだけですね。

```
キュア エール が たこやき を 戦う 。
シャイニー エール が キリヤくん を 食べる 。
キュア ミルキー は たこやき が 会う 。
キュア ホワイト が たこやき を 戦う 。
キュア ミルキー は ザケンナー と 戦う 。
キュア ブラック は キリヤくん を 会う 。
キュア マリン が たこやき と 食べる 。
キュア マリン は ザケンナー と 戦う 。
キュア ミルキー が カッパード と 会う 。
キュア エール が ザケンナー が 会う
```

キリヤくんが食べられてるけど、シャイニーエールという偽プリキュアなのでセーフ。
LSTMまで使わなくても、マルコフ連鎖でずいぶんまともになりそう。
macで仮想WEBサーバ構築

#はじめに
仮想WEBサーバを構築したので、備忘録的に。

#環境
macOS Mojave ver10.14.6
VirtualBox 6.0.12
Vagrant

#手順
①必要ファイルインストール（virtualbox・vagrant）
②vagrantセットアップ
③centOS起動確認
④WEBサーバ構築

#必要ファイルインストール
・参考サイトは以下の通り
https://qiita.com/sudachi808/items/3614fd90f9025973de4b
https://pc-karuma.net/mac-virtualbox-install/

#vagrantセットアップ
・以下を順序よく実行。
$ cd　　　　　　　　　    　念の為、まずはカレントディレクトリーへ移動
$ ls　　　　　　　　　　     一旦、ディレクトリ内を閲覧
$ mkdir centos7　　     　その後ディレクトリ作成
$ ls                     きちんと作成できているかを確認
$ cd centos7             作ったディレクトリへ移動
$ vagrant init centos/7  初期設定を行う
$ ls                     ファイルができたかを確認
<img width="561" alt="スクショ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356270/ec53c2b5-0c7c-4a2f-9826-733c6a5078bc.png">



#centOS起動確認
vagrantを起動させる
$ vagrant up
$ vagrant ssh
$ cat /etc/redhat-release
以下のようになればひとまずOK！
<img width="561" alt="スクリーンショット 2019-09-24 17.34.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356270/57524f04-4e43-76cf-9843-9f557085ea1b.png">

#WEBサーバ構築
今回はApacheをインストールします。

参考サイト：https://weblabo.oscasierra.net/apache-installing-apache24-yum-centos7-1/

まずはApacheの公開されているバージョンを確認
$ yum info httpd
<img width="574" alt="スクリーンショット 2019-09-24 18.07.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356270/52ddc987-b338-a5ba-ed7e-764fb554a1a3.png">

Apacheをインストール
$ sudo yum -y install httpd
以下のようにCompleteと出ればOK！
<img width="574" alt="スクリーンショット 2019-09-24 18.08.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356270/94e4872e-8b23-45b8-8ff6-2770328cfc50.png">

一旦ここまで。
次は、Apacheを起動させるところを記載したいと思います。
閉じるときは以下の流れで
$ exit
$vagrant halt
【RubyOnRails】DBにテーブルを作るため、マイグレーション実行

# この記事の概要
・RubyOnRailsについて、Progateで学んだことを書き記す
・ガチ初心者によるもの
・主に備忘録として、随時書き足していく

# 項目
## マイグレーションファイル作成
`rails g Model [作成するテーブル名の単数形] [カラム名]:[データ型]`
例）`rails g Model Post content:txt`
結果）
①作業ディレクトリ/db/migrateに、マイグレーションファイルが作成される
※マイグレーションファイルには、テーブル作成時に必要な情報が自動で記述されている
②作業ディレクトリ/app/modelsに、[作成するテーブル名の単数形].rbという、
モデルが定義されたファイルが作成される
（上記のコマンドでは、実はマイグレーションファイルとモデルファイルを同時に作成していた）

##マイグレーション実行
`rails db:migrate`
※特定のマイグレーションファイルのみを実行するコマンドとか有りそう。後日追記
Atom使いがVS Code使いになるまでにやったこと・覚えたこと

# 背景
Atomさん、かっこいいしMac/Winで無料で利用できるし…と思って4年くらい何かを信じて使ってたけど、
まー諸々の処理が遅い…！！！もう我慢できねえ！！！

ここ数年くらいで乗り換え先をほんのりと検討していて、
Sublime Textをちょこっと触ってみたり、IntelliJ IDEAの価格に打ちのめされたりした結果、
VS Codeが結構いい感じという噂を聞きつけて、移行コスト問題に負けずこの1ヶ月くらい頑張って触ってみた。

　
# 結論
VS Code良い。さようならAtomさん…。（いままでありがとう。）


# 慣れるまでにやったこと・覚えたこと
まだ全然使いこなせてないけど、とりあえず普通に触ってやりたいことはやれるようになった。
若干躓いたポイントや、設定変更したところをまとめてみた。


## 概念を覚える
```
vscodeは4つの設定定義レベルが存在する。

vscode全体の設定(プログラム規定値)
vscode全体の設定
ワークスペース単位の設定
フォルダ単位の設定
```
ご想像の通り下の方が優先される。
基本は使うワークスペースに対して設定しておけば大丈夫そう…？

参考：https://prius.cc/itya/20181218_vscode-workspace



## 表示を変更する
### 【設定】文字コード
設定の検索窓に Encoding でOK。
この辺の設定をワークスペースごとだったりフォルダごとに変更できるの、結構便利そう

### 【設定】フォント
安心と信頼と実績の Ricty Diminished さん。
Font Family を変更。

### 【設定】カラーテーマ
Ctrl+Shift+P で theme。
Dark + (default dark)　で落ち着いた。
※Atom Dark みたいな配色にしたかったけど、もう割り切ってデフォルトのものを使っちゃう


### 【設定】エディタの表示幅
設定の検索窓に wordWrap でOK。
Editor: Word Wrap　ON
Editor: Word Wrap Column　160
って感じにしてみてある。

参考：https://www.atmarkit.co.jp/ait/articles/1807/27/news035.html


### 【設定】文字サイズをマウスホイールでぐりぐり変更
なんだか意外と使うやつ。
editor.mouseWheelZoom　にチェックを入れる。

参考：https://www.atmarkit.co.jp/ait/articles/1811/30/news032.html


### 【設定】日本語化
参考：https://qiita.com/nanamesincos/items/5c48ff88a4eeef0a8631
※Atomもなんやかんや英語のままで使っていたのもあり、結局採用しなかった。


## 機能を覚える
### 【設定】ファイルの開き方を変更
デフォルトだと、Ctrl+P でファイルを開いたときに別タブで開かずに上書きで開かれてしまうという…。
Atom使い的にはこの仕様は全然慣れなかった…。
Preview Modeを無効にすればOK。

enablePreview　のチェックを外す。

参考：http://it-engineer.hateblo.jp/entry/2018/12/22/135735


### 【ショートカット】Diff
Ctrl+Shift+P で compare with する。
※Atomで使っていたSplit Diff と操作性がかなり違って慣れるまで手間取った…。

参考：https://www.atmarkit.co.jp/ait/articles/1806/08/news028.html


### 【操作】開いているファイルのパスをコピー
ショートカットもあるけど、普通にマウス操作したほうがわかりやすいかも。
ファイル名のタブのところで右クリックをして Copy Relative Path。


## その他
### マルチカーソルショートカットと競合する、Windows側のホットキーを無効にする
> マルチカーソル
> Alt + Ctrl + ↑/↓ マルチカーソルを上/下に広げる。

参考：https://qiita.com/12345/items/64f4372fbca041e949d0

　
> パソコンによっては、Ctrl + Alt + 矢印キーで、画面が90度単位に回転してしまうことがある。
> この回転機能を無効にするには以下を行なう。
> ・デスクトップのウィンドウの無いところで、マウスを右クリックする。
> ・表示されたメニューの中にある「グラフィック オプション」にカーソルを合わせる。
> ・表示されたサブメニューの中にある「ホットキー」にカーソルを合わせる。
> ・表示されたサブメニューの中から「無効」を選択する。

参考：http://kiracchi.com/2012/11/23/invalidate_hotkey/


### デフォルトの保存場所
おいおい一体どこなんだ！！！ってなってちょっと焦った。自分の場合は以下だった。
C:\Users\hogehoge\AppData\Local\Programs\Microsoft VS Code\Code.exe

参考：https://qiita.com/psychoroid/items/7d85ae6bade4a67aedb1


# 今後
しばらくはVS Code使いとして生きてみる。また何か躓いたポイントがでてきたらきっと足す！！
TypeScript: node-http-proxyでリクエストに応じてサーバを振り分けるリバースプロキシを作る方法

本稿では、node-http-proxyを使い、TypeScriptでサーバを振り分けるリバースプロキシを作る方法を紹介する。

node-http-proxyの基本的な使い方は、[TypeScript: node-http-proxyを用いリクエスト/レスポンスを書き換えるリバースプロキシを作る方法](https://qiita.com/suin/items/ff1cd56823d2eb0462f3)で説明しているので、合わせてご参照いただきたい。

# 本稿のゴール

HTTPリクエストのパスに応じて、HTTPリクエストをサーバ1とサーバ2に振り分けるリバースプロキシをTypeScriptで書けるようになる。

![Pasted_Image_2019_09_24_17_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/1750ac75-9c64-e76c-643b-ffdedd511cc4.png)


# リクエストを振り分けるリバースプロキシを実装する

ここでは、HTTPリクエストのパスに応じて、HTTPリクエストをサーバ1とサーバ2に振り分けるリバースプロキシの実装例を示す。

```ts
import http, {IncomingMessage, ServerResponse} from 'http'
import httpProxy from 'http-proxy'

// HTTPサーバ1
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    res.write('HTTP Server 1')
    res.end()
}).listen(9001)

// HTTPサーバ2
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    res.write('HTTP Server 2')
    res.end()
}).listen(9002)

// プロキシサーバ
const proxy = httpProxy.createProxyServer()
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    // パスに応じて送信先を変える処理
    const target = req.url && req.url.startsWith('/server1')
        ? 'http://127.0.0.1:9001'
        : 'http://127.0.0.1:9002'
    proxy.web(req, res, {target})
}).listen(8000)
```

ここでのポイントとしては、リクエストに応じたロジックを書く上で、次のイディオムがあるということ。

```ts
const proxy = httpProxy.createProxyServer()
http.createServer((req: IncomingMessage, res: ServerResponse): void => {
    //
    // リクエストに応じたロジックを書く場所
    //
    proxy.web(req, res, options)
}).listen(proxyPortNumber)
```

最初に示した実装例のプロキシサーバを動かしてみる。

次のリクエストを送ると、

```http
GET /server1/foo/bar HTTP/1.1
Host: localhost:8000
```

リクエストはサーバ1に振り分けられ、次のレスポンスが返ってくる:

```http
HTTP/1.1 200 OK
connection: close
date: Tue, 24 Sep 2019 08:51:38 GMT
transfer-encoding: chunked

HTTP Server 1
```

今度は、サーバ2に振り分けられるリクエストを投げてみる:

```http
GET /foo/bar HTTP/1.1
Host: localhost:8000
```

期待通りサーバ2からレスポンスが返ってくる:

```http
HTTP/1.1 200 OK
connection: close
date: Tue, 24 Sep 2019 09:07:24 GMT
transfer-encoding: chunked

HTTP Server 2
```

# 参考文献

* [http-party/node-http-proxy: A full-featured http proxy for node.js](https://github.com/http-party/node-http-proxy)

[node-http-proxy]: https://github.com/http-party/node-http-proxy
npm-scripts で自前の環境変数を利用する方法（Win/Mac共通化）

普段タスクランナーとしてgulpを使っていますが、依存するパッケージを減らすためnpm-scriptsに移行中です。
その中で自前の環境変数を使う場合、Win/Macで同じscriptを使って環境変数を展開する方法の情報が見つけられなかったので忘備録として残しておきます。

# 普通の環境変数展開の方法
```json:package.json
{
  "config": {
    "value": "MyValue"
  },
  "scripts": {
    "var:mac": "echo $npm_package_config_value",
    "var:win": "echo %npm_package_config_value%"
  }
}
```
これだとWinとMacで同じスクリプトを2回ずつ書く必要があります。

# マルチプラットフォーム対応の環境変数展開の方法
[cross-env](https://www.npmjs.com/package/cross-env)を使います。

```sh
$ npm i -D cross-env
```

```json:package.json
{
  "config": {
    "value": "MyValue"
  },
  "scripts": {
    "var": "cross-env-shell \"echo ${npm_package_config_value}\""
  },
  "devDependencies": {
    "cross-env": "^5.2.1"
  }
}
```
これなら1つのスクリプトでWin/Macに対応できます。

## うまく環境変数展開できないケースの対処
モジュールに渡す変数でglob指定を使っている場合、上記の方法では、うまく変数展開ができない場合があったので下記のようにしたところ、Win/Macでうまく動きました。

```json:package.json
{
  "config": {
    "src_dir": "src",
    "dest_dir": "dest"
  },
  "scripts": {
    "copy": "cross-env TARGET=\"./${npm_package_config_src_dir}/**/*.!(js)*\" npm run copy:exec",
    "copy:exec": "cross-env-shell \"cpx \\\"${TARGET}\\\" \\\"./${npm_package_config_dest_dir}\\\"\""
  },
  "devDependencies": {
    "cpx": "^1.5.0",
    "cross-env": "^5.2.1"
  }
}
```

無理やり実現している気がするので、もっと良い方法ご存知の方は情報いただけると助かります。

以上です。
Ruby 配列 に 格納 された ものを 順に出力する

# 目的

- Rubyにて、配列に格納された文字列などを順に出力する方法を知る。

# 書き方の例

- 変数_1には配列の形で任意の文字列が2つ以上格納されていることとする。
- 下記にRubyの処理を記載する。

```ruby
変数_1.each do |変数_2|
  puts 変数_2
end
```

# より具体的な例

- 変数`string`に「みりを」「miriwo」「MIRIWO」を配列として格納する。
- 変数`string`の中身を一つづつ出力為る。
- 下記にRubyの処理を記載する。

```ruby
# 変数への文字列格納
strings = ["みりを", "miriwo", "MIRIWO"]

# eachを用いてstringsの中身を一つづつstringに格納
string.each do |string|
# stringに格納された中身を出力
puts string
# eachを閉じる
end
```
TypescriptでIterableなオブジェクトにスプレッド構文が適用できない時の対処

CompilerOptionに``--downlevelIteration``を付けろと言われてしまった場合の対処。

# 原因
問題はオプションが付いていないことではなく、``CompilerOption``の``target``が古すぎること(es5など)
エラーで出てくるオプションを付けても対応できるが、基本的にtargetを上げた方が良い。
(tsをコンパイルするような環境だったら当然babelも入っているだろうし)

# 余談
なお、vsCodeの場合はtsconfig.json上でtargetを編集しても即反映されないので、
ReloadWindow辺りを叩く必要がある。