OmniAICreator/Qiita-1.07M huggingface dataset:
INSERT ON CONFLICT  DO UPDATE が atomic じゃなかった

## TL; DR
- PostgreSQL での UPSERT に該当する `INSERT ON CONFLICT DO UPDATE` が atomic な処理ではない。
  - 1レコードずつ行ロックされる
- 複数レコード追加/更新する際は、主キーなりでソートしておかないと、 multi-thread/process から実行すると `dead lock` に悩まされる。

## 環境
PostgreSQL 9.6.9 on AWS Aurora

## 例
こういうテーブルに

```
CREATE TABLE foo (
    key1 int primary key,
    key2 text
)
```

こんな感じでデータを投入しておく。

```
INSERT INTO foo (
    key1, key2
) VALUES (
    1, 'foo'
), (
    2, 'bar'
), (
    3, 'baz'
);
```

で、以下のクエリを同時に流し込むと、タイミングによっては `dead lock` する。

クエリ1：

```
INSERT INTO foo (
    key1, key2
) VALUES (
    1, 'foobar'
), (
    3, 'qux'
) ON CONFLICT (key1)
DO UPDATE SET
    key2 = excluded.key2
WHERE
    foo.key1 = excluded.key1
;
```

クエリ2：

```
INSERT INTO foo (
    key1, key2
) VALUES (
    3, 'qux'
), (
    1, 'foobar'
) ON CONFLICT (key1)
DO UPDATE SET
    key2 = excluded.key2
WHERE
    foo.key1 = excluded.key1
```

VALUE の順序が逆になってるのがミソなんだけど、たぶん内部的には
1. クエリ1が `key1=1` の行を UPDATE してロック
2. クエリ2が `key1=3` の行を UPDATE してロック
3. クエリ1が `key1=3` の行を更新しようとしてクエリ2のロック解除を待つ
4. クエリ2が `key1=1` の行を更新しようとしてクエリ1のロック解除を待つ
5. 無事 dead lock 発生

て感じになってるんだと思う。

半信半疑だったんだけど、試しに key1 でソートしてからクエリ流すようにしてからは1度も dead lock が発生していないので、おそらくそうなんだろうなーと思ってる。
DjangoからLouts Notesへデータの受け渡し

標題の通り、Djangoで作成した入力フォームデータをNotesのデータベースへワンボタンで受け渡したい。色々調べたがわからない。どういったテクニックで実現できますか？COM?Djangoのjavascriptから？ajax?,pythonのAPI?　ご教授お願いします。
マウス・キーボードをネットワーク上のPCで共有する

Mouse witout Borders
https://www.microsoft.com/en-us/download/details.aspx?id=35460

ALL PC modeにするとマウスとキーボードの操作を共有できるようになってまとめて4台のPCを操作できる。

以下、要検証。
・ALL PC modeを自動でオンにすると、オンにならない事がある（オンになってるけど効かない）？ ← ユーザー操作で明示的にオンにするなら効く。
・ALL PC modeをオフにすると、それぞれのキーボードが効かなくなる？
Prometheus: 対象ジョブが全部死んでることを表現する式

## `up` メトリクス自体が無いというケース

Prometheus ターゲットには`up{job="jobname"}` というヘルスチェック用メトリクスが生えているが、
これを使って 「up == 1 (running) な jobname が存在しない」という意味の式
`count(up{job="jobname"} == 1) == 0` を書いたとする。

これは jobname が全て死んだとき true を返さない。
というのも jobname が全て死んでいる時 Prometheus は `up{job="jobname"}` にマッチするメトリクスを収集できておらず、
`count(up{job="jobname"} == 1)` は `no data` を返してしまうから。

## `absent()`

ではどうすればいいのかというと、メトリクス自体が存在しない場合を表現するには [`absent()`](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) という関数を使えばよい。

これを使えば、「`up{job="jobname"}` が全く存在しない」という意味の式
`absent(up{job="jobname"})` を書くことができる。
作ったOSS（笑）まとめ ほぼGCP関連のshellscript

## ただのshellscriptなんだよなあ

### [gcctx](https://github.com/ykamenashi/gcctx)
* 使いづらすぎる `gcloud config configurations` をなんとかするやつ

#### おまけ
* [cshell](https://github.com/ykamenashi/gcctx/blob/master/cshell)
* どんな `gcloud config set` をしていたとしても、所望のprofileを有効化した上でcloud shellにSSHし、終わったら元のprofileに戻すショトカです。

### [adcmod](https://github.com/ykamenashi/adcmod)
* terraform Google Cloud provider plug-in とかが参照する `Google Application Default Credentials` を切り替えるやつ。
* 多数の認証情報を扱う必要のある当社社員みたいな人にはありがたい、はず。

### [tfgetws / tfsetws](https://github.com/ykamenashi/tfgetws)
* `terraform plan` => あーっ！ `default` workspaceだった！ みたいなのがいい加減うざいので作った。
    * いま、どのworkspaceにいるのか？
    * どんなworkspaceがあるのか？
    * workspaceを設定するのに長い長いterraformコマンド打ちたくない
* という方に。
日記：GO言語に出くわす。

# 嘘のまえがき

偉い人から、これこれこのコマンドを打ってみてって言われるがままに押し通る。

言われるがまま動いたところで、それ以上を見込めない気がして。
偉い人が教えてくれればいいけど、それもお手を煩わせてしまう様で忍びない。

((というか、グーグルさえなければ、
ググれと言われることもなかったのに、せめてこの本を読みなさいと、
あ、だから、今なら「この公式とブログをお読みなさい」とオススメされるならいいね。))

プログラマの端くれなら、
偉い人につまらない事を聞いて、毎日教えてもらえたらいいけど、そんなん最初だけだし
「これ読むといいよ」って言ってくれたらそれがいいよね。それでも分からん事を聞きにおいで！！

さて、GOである。goかもしれないし、Goかもしれない。

Let's go boy and girl！！

# IMPORTANT！

goにはテスト機能が付随している。早速実行してみよう。
`go test`、`go test -run`

```
$ go test
can't load package: package .: no Go files in /Users/user-name/workdir

$ go test -run
go test: missing argument for flag run
run "go help test" or "go help testflag" for more information
```
素直にこれを読んで全て解決なのじゃ。
`"go help test" or "go help testflag"`

英語読めんのじゃー死
Sparkで複雑なクエリを書いたときに実行計画が生成されないときに試す設定

# 動機

100カラム以上のcase文やwindow関数を書いてしまうとsparkの実行計画(physical plan の生成?(要検証))がうまく動作しない時がある。

# 変更点


`
spark.sql.constraintPropagation.enabled false
`

に設定する。

# 参考文献

https://medium.com/@viirya/slowness-of-ml-pipeline-in-spark-6ec76d66042f
桁数を抑えたバイナリ法

# 普通のバイナリ法

```Rust
// バイナリ法
// a^n mod m
fn pow_mod(mut a: usize, mut n: usize, m: usize) -> usize {
    let mut res: usize = 1;
    while n > 0 {
        if n & 1 == 1 {
            res = res * a % m;
        }
        a = a * a % m;
        n >>= 1;
    }
    res
}
```

# 桁数を抑えたバイナリ法

桁数を底の２乗以下に抑えます

```Rust
fn pow_mod2(a: usize, mut n: usize, mk: usize) -> usize {
    let mut m = a;
    let mut ans = 1;
    let mut sf = true;
    while n > 0 {
        if sf {
            sf = false;
        } else {
            m = m * m % mk;
        }
        if n & 1 == 1 {
            ans = m * ans % mk;
        }
        println!("{} {} {}", n & 1, m, ans);
        n >>= 1;
    }
    ans
}
```
2ヶ月プログラミングを独学で勉強して分かったこと

<p>皆さん、勉強進んでますか？<br />僕はスクールに行くお金がないので6月から独学でプログラミングを勉強しています。そこで初心者がこれは言っておいて欲しかったと思うことや学んだことを書き残したいと思います。</p>
<p> </p>
<ul>
<li>1：タイピング</li>
<li>2：ブルーライトカット眼鏡</li>
<li>3：ググる力</li>
<li>4：毎日の目標と習慣</li>
<li>5：2画面推奨</li>
<li>6：折れない心</li>
</ul>
<p> </p>
<p><strong>1：タイピング</strong></p>
<p><br />毎日タイピング練習をしましょう。英文字を。</p>
<p>僕はブラインドタッチが出来ませんでした。PCに触って10年以上たつのにも関わらず。タイピングがものすごく遅いうえに、タイプミスが多いです。これは致命的な欠陥です。Progateを最初始めましたが、教科書を理解する、コードを打つ、見返す、コードを打つ、ミス、BackSpace、打ち直す・・・全然進まなかったです。これはもうコードを勉強する以前の問題だなと思いました。</p>
<p>プログラミングを初めてみようかなと思う方は、まずタイピングを上手くなっておいた方がいいでしょう。ブラインドタッチまで行くのが望ましいですが、ゆっくりでいいからミスなく打てるレベル、指と文字を結びついてるレベルを目指しましょう。<br />僕は毎日30分の練習でだいたい2ヶ月でブラインドタッチの2歩手前ぐらいまで来ました。（個人的に成長スピードは遅い方でしょう）</p>
https://www.e-typing.ne.jp/english/
<p>僕はこのサイトでDランクからBランクまで練習しました。</p>
<p><br /><strong>2：ブルーライトカット眼鏡</strong></p>
<p><br />何時間もPC画面を眺めるのでオススメはJINSのブルーライトカット眼鏡です。5千円程度で買えます。40%カットのBOSTONが良いです。</p>
<p><a href="https://www.jins.com/jp/jins-screen/">https://www.jins.com/jp/jins-screen/</a></p>
<p>何時間もPC画面を眺めると絶対視力が悪くなります。ドライアイや肩こりとの戦い長く続きます。なので、せめて目は大事にしたいところです。</p>
<p> </p>
<p><strong>3：ググる力</strong></p>
<p> </p>
<p>ひたすらググりましょう。何をやればいいのか、どれを勉強すれば良いのか右も左も分からない状態の初心者は調べるしかありません。これのデメリットは情報に振り回されることですが、そうはいっても何も知らないなら調べて知識を得るしかありません。</p>
<p>たくさん情報に触れて、選球眼を養いましょう。ブラウザのショートカットキー（Ctrl＋W、Ctrl+クリック）を駆使しましょう。</p>
<p> </p>
<p><strong>4：毎日の目標と習慣</strong></p>
<p> </p>
<p>独学は孤独です。横にメンターや講師がいるわけでも、誰かの監視があるわけでもありません。常に、自分はエンジニアになるんだという強い気持ちを忘れないように、毎日目標を決めて行動しましょう。</p>
<p>僕は大体目標通りに全然進みませんでした。Progateの簡単な講座ですらクリアできず、一日の終わりに罪悪感にまみれて寝れなくなりました。そして、いつの日かProgateを開くことすら怖くなったのです。だから、最初はProgate開く、エディタを開く、技術書を１ページ読むと言った小さな習慣や小さなスタートを大事にしましょう。</p>
<p>毎日の進捗をTwitterにあげても良いかもしれませんね。</p>
<p> </p>
<p><strong>5：2画面推奨</strong></p>
<p> </p>
<p>２画面です。ノーパソ＋モニタです。デュアルモニターが捗ります。</p>
<p>正直、マスト事項だと個人的に思っています。一画面でいちいちエディタとブラウザを行き来するのはナンセンスだなぁと。ラップトップ自体が小さい画面ならなおのこと大きいデスクトップモニタを使ってあげたほうが良いです。</p>
<p> </p>
<p><strong>6：折れない心</strong></p>
<p> </p>
<p><strong>3000回はプログラミング向いてないと思う瞬間を乗り越える。</strong></p>
<p>「エラーは友達」を寝る前と朝起きたときに唱える。</p>
<p> </p>

追加するなら、貯金はあったほうが良いです。ご飯買うお金で節約しなきゃ！という意識があると、スクールに通わないにしても、技術書を買うのを躊躇しちゃいます。貯金があるならMacも買えるし、モニターも買えます。
プログラマーとして仕事を得るためには一番求人がある東京にくるしかありません。
これから出ていくお金は数十万単位です。引っ越し代、スクール代、技術書、交通費、生活費、税金・・・考えると頭が痛くなりますが、働きながらProgateやタイピング練習、情報収集はやっておいた方がいいです。
無職になってから、さぁーやるぞ！だとめちゃくちゃ苦労します。ぼくみたいに！笑
PCの自動起動(BIOS)

通電時の自動起動や指定時間に起動させるBIOS設定。
パソコンによって項目名や設定名が違うので注意。

●通電時に自動で電源オン
Setting / Advanced / Power Management Setup / Restore after AC Power Loss
→ Power On

●指定時間に自動で電源オン
Setting / Advanced / Power Management Setup / Wake On RTC Alarm
→ Enabled。あわせて日時指定をする。

●ビデオカード以外にマザーボードのグラフィックポートも使えるようにする
Setting / Advanced / Integrated Graphics Configration / Initiate Graphic Adapter
→ PEG
IGD Multi-Monitir
→ Enabled
【Ruby 2.4.6 update】ArgumentError:  key must be 32 bytes への、versionを動かさない対処

## 背景
Ruby 2.3.1 -> 2.4.6　へversion upしたら、ActiveSupport::MessageEncryptor周りでエラーがでた。
この中で使われているOpenSSLがもともと32bytes以上でも受け入れていたところを、32バイトぴったりしか受け付けなくなったのが原因の様子。
[これが修正のcommit](https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1)
データベースに32バイトより大きいkeyで暗号化したデータが入っていたので、それらをdecryptできなくて落ちていた。
ちなみにRailsは4系。

## 捕捉
Rails 5.0.0.1　で対応が入っているらしい
https://github.com/rails/rails/pull/25192/files
でも今回はRailsのversionは上げられないので別の対処法を探す。
色々調べた感じ、多くの人はRubyのversionを戻したりとversionを上げ下げしてこの問題を回避してそうだった。

## 解決案その１
Ruby 2.3系に戻し、32バイトより大きいkeyでdecryptして、32bytesでまたencryptする。
これでもいいのですが、ちょっと時間がかかりそう。

[参考](https://qiita.com/amyroi/items/f30dbea87d3b33e3908b)

## 解決案その２
32バイトっていうので、とりあえず32bytesにしてみた。
しかしdecryptで失敗。
これはchiperの方はsecretを32bytesに切ってくれるが、復号で使うverifierの方はそのままの長さを使ってるからのが原因の模様。

```ruby
d = ActiveSupport::MessageEncryptor.new(some_key[0..31])
rb(main):005:0> d.encrypt_and_sign("hoge")
=> "K3dtYVJUL1NucVpnRUFJWm9OZ3VQQT09LS1SMlRKb3dWWXFFajZ5MDFMcHQ3NmxRPT0=--910efa18ef525a38f7bf2482e94a54ec39ad1e65"

d = ActiveSupport::MessageEncryptor.new(some_key[0..31])
irb(main):003:0> d.encrypt_and_sign("hoge")
ArgumentError: key must be 32 bytes
```



しかし、`ActiveSupport::MessageEncryptor`のコードを読んでいたら、optionsで渡せそう。
option引数の先頭で渡せば`@sign_secret`に入って、そっちが優先されてverifierが作成される。

```ruby
#=>  ActiveSupport::MessageEncryptor
    def initialize(secret, *signature_key_or_options)
      options = signature_key_or_options.extract_options!
      sign_secret = signature_key_or_options.first
      @secret = secret
      @sign_secret = sign_secret
      @cipher = options[:cipher] || 'aes-256-cbc'
      @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer)
      @serializer = options[:serializer] || Marshal
    end
```

つまりこうすれば良い。

```ruby
  ActiveSupport::MessageEncryptor.new(some_key[0..31], some_key) 
```

急ぎだったので、解決案２で解決しました。
salt使うように修正予定。


## 終わり
ベテランの方に助けてもらいました
ライブラリのコードリーディング力を高めなければ
EC2をタグに基づいて、特定の時間に自動で起動/停止する

# 概要
いったい何番煎じだよという感じですが、Lambda上にデプロイしたコードから、EC2のインスタンスを定期的に起動/停止させます。

今の時代、[こちらの記事](https://qiita.com/t-toyota/items/5d7455568f1856fd2f4e)にある通り、プログラムを書かずともLambdaの定期起動/停止ができてしまいます。
それでも、本記事のコードをデプロイした後であれば、EC2インスタンスを立てるたびにCloudWatchの設定をいじる必要もなく、インスタンスにタグを追加するだけで自動起動/停止の設定ができるようになり、便利です。

# Lambdaの設定
本記事のコードは、EC2に設定されているタグを見て、インスタンスの起動/停止を行います。そのため、自動設定対象にしたいEC2インスタンスには、以下のように`start-time`,`stop-time`のタグをつけます。それぞれ、起動時間と停止時間を`HHMM`形式で表します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283226/053deb5e-e3c7-cae7-061d-c8443f44881d.png)


# コード
以下のPythonのコードを、Lambdaにデプロイします。もちろん、LambdaにはEC2を起動や停止するための、適当なIAMロールをつけます。

```python:manage_ec2.py
import boto3;
import datetime;

# 最初に呼ばれる関数
def lambda_handler(event, context):
    client = boto3.client('ec2', 'ap-northeast-1')
    # boto3でec2の全インスタンスの情報を取得
    response = client.describe_instances()
    # 必要な情報のみを抜き出したリストを作成
    instance_list = extract_instance_info(response)
    # 上のリストを基に、必要であればインスタンスを起動/停止する
    manage_instances(instance_list,client)
    
# ec2インスタンスのリストを作成
def extract_instance_info(response):
    return_val = []
    for instance_data in response['Reservations'][0]['Instances']:
        try:
            tmp = {}
            # インスタンスのid
            tmp['id'] = instance_data['InstanceId']
            # タグで指定されている起動時間
            tmp['start_time'] = convert_time([tag['Value'] for tag in instance_data['Tags'] if tag['Key'] == 'start-time'][0])
            # タグで指定されている終了時間
            tmp['stop_time'] = convert_time([tag['Value'] for tag in instance_data['Tags'] if tag['Key'] == 'stop-time'][0])
            # 現在のインスタンスの起動状況
            tmp['status'] = instance_data['State']['Name']
            return_val.append(tmp)
        except (KeyError, ValueError, TypeError) as err:
            print(err)
            # かなり乱暴なのは承知ですが、自動起動/停止対象外のインスタンス（タグが設定されていないもの）があれば、例外を発生させて無視します
            continue
    print(return_val)
    return return_val

# タグで指定されている起動/停止時間を、datetime.time型に変換
def convert_time(str_time):
    hour = int(str_time[:2])
    min = int(str_time[2:4])
    return datetime.time(hour,min)

# インスタンスの起動/停止を行う
def manage_instances(instance_list,client):
    # 現在時刻をdatetime.time型で取得
    current_time = datetime.datetime.now().time()
    for instance in instance_list:
        # インスタンス停止中で、起動時間を過ぎていれば、インスタンスを立ち上げる
        if instance['status'] != 'running' and current_time >= instance['start_time']:
            response = client.start_instances(
                InstanceIds=[
                    instance['id']
                ]
            )
            print(response)
        # インスタンス起動中で、停止時間を過ぎていれば、インスタンスを停止する
        elif instance['status'] == 'running' and current_time <= instance['stop_time']:
            response = client.stop_instances(
                InstanceIds=[
                    instance['id']
                ]
            )
            print(response)
        else:
            # 何もすることないけど、ログだけ出しとく
            print('no action was taken')
 ```

このコードをデプロイしたLambda関数を、CloudWatchで30分おきなどで実行させれば、完成です。

上のコードでは現在時刻を取得するコードが含まれているので、Lambdaの環境変数に、必ず`TZ`:`Asia/Tokyo`を付け加えてください。
【FileMaker】続々・カテゴリごとに管理番号を振る　最大値に追加

「[カテゴリごとに管理番号を振る](https://qiita.com/tyuma/items/9afe39bb9575e7b3a244)」回と「[【FileMaker】続・カテゴリごとに管理番号を振る　インポート編](https://qiita.com/tyuma/items/4078d650b16dde563170)」の続々編です。（こんなに続くとは、、、）
最初の記事はリレーションシップで自己参照をして連番していました。
このやり方は同じカテゴリのデータ数を集計して採番しているので、データが物理削除されて管理番号が欠けてしまった場合、削除した管理番号を採番してしまう可能性があります。
データが物理削除されないケース（削除フラグを設けているなど）ではこのやり方で十分ですが、物理削除をしている場合はちょっと困りますよね。

FileMakerの関数には、FileMaker Pro 7.0で追加された[SerialIncrement](s://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help%2Fserialincrement.html)がありますので、これを使って採番の最大値に増分を加えていく手段ができます。
「データベースのフィールド設定で、シリアル番号を設定すればいいんじゃね？」と思った方。
<img width="633" alt="qiita20190724_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/5645796f-e2fd-b75a-ad27-a0ea7a87c7c2.png">
ある意味正解で、固定のテキスト＋番号であればこれで十分です。

ですが、お題は「カテゴリごと」ですので、固定のテキストではないところが痒いです。
ということで、動きです。

# 動き
カテゴリごとの管理番号で2000番があったとします。
その前の番号が17なので、ざっくりデータが削除されていることがわかります。
<img width="651" alt="qiita20190724_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/b971ce99-1477-a322-83d8-59e93abddf96.png">

ここにカテゴリにデータを１件追加します。
最終番号である2000に増分1の管理番号が振られました。
<img width="633" alt="qiita20190724_3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/17633ebe-5341-7eb3-ead9-6b592695c8b3.png">

# 実装
これは以前と同じようにスクリプトトリガで実装しています。
<img width="979" alt="qiita20190724_4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/558617d4-7f25-0512-21e1-c3f6effd8caa.png">

実装でのポイントは、ソート順です。
検索した後にソートし、最後の管理番号にたどり着きます。
その番号を使って、SerialIncrementで増分していきます。
<img width="672" alt="qiita20190724_5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/055f694a-62c7-60e4-be7c-313872dc4980.png">

最後は、元のデータに戻すべくレイアウト用のソートをします。（この動きは管理番号を振ること自体にはなんの影響もありません）
<img width="629" alt="qiita20190724_6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f3ee7c07-8ba9-df10-6fb1-5aa31a651cb2.png">

最初のソート後にデータの移動をしているところがあります。
これは、ソート後の最終値を拾いに行った後、まだ管理番号が振られていないデータ（最初の行）まで移動します。
ここも、重要ですね。
これを忘れると、既存の管理番号を上書きしてしまう可能性がありますので注意です。
<img width="402" alt="qiita20190724_7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/94aa5252-5e44-6024-8ad5-0648e2ca269b.png">

# 一つの実装方法です
管理番号を振るのは業務に応じて様々なケースがあると思います。
このやり方以外にもあると思いますが、一つの実装方法として参考にしてください。
[質問] Rstanを実行しようとして、Rtools35インストール後、Rが[c:/Rtools/mingw_64/bin/gcc]を認識しない

[環境]
windows10
R3.6.1
Rstudio:1.2.1335
Rtools35　※Rtoolsは、自宅、会社ともに「C:\Rtools」にインストールされています。


[状況]
Rstanで分析しようとしています。
自宅PCではRstanが実行できます。
会社のPCではRstanが実行できません。

自宅と会社の環境は、上記[環境]で記載した同じ環境です。

[Rの動き]
１：
Rstanを動かそうとすると、Rtoolsが動くのだと思うのですが、以下のポップアップが出ます。
Building R package from source requires installation of additional build tools. 
Do you want to install the additional tools now?

２：Yesを選択すると、Rtools35のダウンロードが始まり、更に進むと、インストールが始まります。

上記が2回繰り返されるのですが、その後、Rstanを動かそうとすると、１にもどります。これを繰り返します。

[調べて参考にしたもの]
以下を参考に、自宅と会社の両環境で比較しました。
※自宅環境ではRstanが動きますが、会社環境ではうごきません

▽参考にしたURL
https://github.com/rstudio/rstudio/issues/3563

Sys.getenv("PATH")
＞＞＞同じような内容

system("g++ -v")
＞＞＞ともに、戻り値は「127」

pkgbuild::has_rtools(debug = TRUE)
＞＞＞自宅
Scanning R CMD config CC...
cc_path: c:/Rtools/mingw_64/bin/gcc 
install_path: c:/Rtools 
VERSION.txt
Rtools version 3.5.0.4 
Found compatible gcc from R CMD config CC
[1] TRUE

＞＞＞会社
Scanning R CMD config CC...
cc_path: 
'.exe' does not exist
Scanning path...
ls: C:/Rtools/bin/ls.exe
gcc_path:
VERSION.txt
Rtools version 3.5.0.4
version: 3.5
Found compatible gcc on path
[1] TRUE

callr::rcmd_safe("config", "CC")$stdout
＞＞＞自宅　[1] "c:/Rtools/mingw_64/bin/gcc\n"
＞＞＞会社　[1] ""

.Call("rs_canBuildCpp")
＞＞＞自宅　TRUE
＞＞＞会社　FALSE

Sys.which("gcc.exe")
＞＞＞ともに
gcc.exe 
     "" 

[現在考えていること]
会社のPCでは、Rstudioが、[c:/Rtools/mingw_64/bin/gcc] を認識できないことが、問題ではないか、と思っています。
しかし、それが正しいかわからないのと、仮にこの考えが正しい場合、課題解決方法がわかりません。
参考にしたURLには、C直下にRtoolsをインストール(CRANからダウンロードしたEXE)したら動いた、とあり、完結しており解決方法がわかりませんでした。


解決方法をご存知の方がいらしたらご教示いただきたいです。
よろしくお願いいたします。

(追記　20190812)------------------------
会社環境は、Pathが切れていないのではないか、と「c:/Rtools/mingw_64」のPathをシステム部門に入れてもらいました。
しかし、上記の状況は改善せず。以下、ともに認識していない状況。困りました。

pkgbuild::has_rtools(debug = TRUE)
callr::rcmd_safe("config", "CC")$stdout
マウス・キーボードを押したことにするマクロ設定ツール

キーボードマクロ&マウスマクロ KMmacro
https://www.vector.co.jp/soft/win95/util/se211440.html

batファイルを作成して操作を自動化。遅延起動と組み合わせての使用もOK。
Xcode 10.3 が容量不足でダウンロードできない

# 状況と解決

はじめ空き容量 25GB で容量不足のメッセージが出ていたので、Xcode をアンインストールし、空き容量を 67GB 確保しました。が、相変わらず容量不足とのこと。

参考の[1]にある `~/Library/Caches/com.apple.appstore` を削除して AppStore を再起動する方法を試してみるも、効果なし。

結局、参考の[2]にある直接ダウンロードを行いました。以下方法です。

1. Webブラウザで https://developer.apple.com/download/all/?q=Xcode を開く
2. ログイン
3. Xcode 10.3 を選択しダウンロード（6.04GB）
4. ダウンロードした Xcode_10.3.xip をダブルクリック
5. （展開に長い時間がかかる）
6. 出てきた Xcode をアプリケーションフォルダ（~/Applications）に移動
7. 移動した Xcode をダブルクリックして起動
8. Additional Requirement をインストールするように言われるので従う

# 環境

**MacBook Pro** Early 2015, SSD 128GB
**macOS** Mojave 10.14.6
**Xcode** 10.3

# 参考

* [1] [40+ GB Free. Trying To Install Xcode. App Store Says "Not Enough Free Space". Screenshot Included.](https://www.reddit.com/r/MacOS/comments/9h9fo0/40_gb_free_trying_to_install_xcode_app_store_says/)
* [2] [Xcode on Mac App Store can't install , show disk space not enough](https://stackoverflow.com/questions/53432700/xcode-on-mac-app-store-cant-install-show-disk-space-not-enough/55810703#55810703)
HTMLでスマホキーボードの改行ボタンを検索ボタンに変更する方法

# やりたいこと

`<input>`tagを使用して検索バーを作ると、focusしたときのスマホキーボードのEnter Keyは「改行」と表示される。

検索バーの場合Enter Keyを押したときの挙動は「改行」ではなく「検索」させたいため、Enter Keyの表示も「検索」に変更したい。

# 変更する方法

- `<input>`を`<form>`の中に入れる
- `<form>`に`action`attributeを追加（submitの挙動をここで定義したくない場合は`action="#"`とすればOK）
- `<input>`に`type="search"`を追加

```
<form action="#" @submit="search">
   <input type="search" />
</form>
```

これでEnter Keyが「検索」になる。
awsのEC2でWebサーバーを作成しBasic認証を設定する際の注意

Amazon Elastic Computing Cloud(EC2)はAWSのIaaSリソースです。

これを使ってWebサーバーを立てることも多々あると思います。

今回はBasic認証の設定まで行いましたが知識の整理のために要点だけ記載します。

# EC2
## インスタンスの作成とssh接続
基本的にはAWSのコンソールに従えば問題なくssh接続できます。


- pemキーをダウンロードしたらそのファイルを作業ディレクトリもしくはホームディレクトリへ移動する
- `chmod 400 [pem key]`を実行し、読み取り権限を付与する

`chmod`を実行しないとエラーになるので注意が必要です。

## apachのインストールと実行
- `sudo yum install httpd`
- `sudo service httpd start`

これだけ。

## セキュリティグループの設定
上記の設定をしただけではまだVMに対してhttpでアクセスすることはできません。
内向きのhttpアクセスを許可する必要があります。

これは、インスタンスの説明タブ上にあるセキュリティグループのリンクをクリックすることで編集できます。
既存のルールにHTTPを追加します。

# Basic認証
## .htaccessと.htpasswd
Basic認証を行うためには`.htaccess`と`.htpasswd`の二つのファイルが新たに必要になります。
以下が例になります。

```.sh:.htaccess
AuthUserFile /var/www/html/.htpasswd #自分の環境に合わせる
AuthName “Please enter your ID and password”
AuthType Basic
require valid-user 
```

`.htpasswd`には認証に利用するユーザ名とPASSを記入します。
PASSは暗号化されている必要があるので外部サイト等を利用して生成すると良いでしょう。

```.sh:.htpasswd
test:PASSWARD
```
この後、これらのファイルに`chmod`で権限を付与します。
大抵は604/644のどちらかでうまくいくはずです。

## httpd.confを編集する必要がある。
見落としがちなので注意が必要です。`httpd.conf`を確認してください。

```.sh:.httpd.conf
#/var/www/html
AllowOverride None
```
となっている場合は、

```.sh:.httpd.conf
#/var/www/html
AllowOverride All
```
に書き換える必要があります。これを忘れるとBasic認証が効きません。
私はこれで時間を溶かしました。
毎朝8時にEテレをつける。

# 前置き

最近購入したのですが、Nature Remo良いですよね。（買ったのはmini）
Google Home miniと連携させて遊んでます。

本題と関係ないですが、息子くん（4歳）がGoogle Home miniに「おっけーぐるぐる」とか
話しかけてて可愛かったので、もうそれだけで元取れたかな、という感じです。

# 本題

我が家では、毎朝8時からEテレを見る習慣があります。
つまり、「Nature Remoを使って自動で毎朝8時にEテレを付ける」ということがしたいのです。

これだけであれば簡単なのですが、公式アプリのルール機能やIFTTTではタイムラグがあり、
8時になってから1分くらい待たされることがあるのです。

これを解決したいというお話です。

# 解決方法

## 1. Nature Remoアプリのルール機能

### アプリからルール作成

[この記事](https://nature.global/jp/blog/2019/1/25/vol2-rule)を参考にルールを作る。
月から土、8:00にEテレを付けるようにルールを作る。

### 結果

タイムラグあり。1分後くらいに実行される場合もある。

## 2. IFTTTのDate&Timeトリガー

### IFTTTのイベント作成

* トリガー：Date&Time
    * Every day at
        * 8 AM
        * 00 Minutes

* アクション：Nature Remo
    * Control TV
        * テレビ - 2

### 結果

タイムラグあり。1分後くらいに実行される場合もある。

## 3. IFTTTのWebhooks + [Cloud Scheduler](https://cloud.google.com/scheduler/)

### Webhooksをトリガーとしたイベント作成

* トリガー：Webhooks
    * Receive a web request
        * Event Name：okaitsu

* アクション：Nature Remo
    * Control TV
        * テレビ - 2

### Cloud Schedulerでジョブ作成

すみません、まずこの機能知りませんでした。
cronのジョブをGoogleクラウド上で実行できるって感じです。

```shell:月-土の8時に起動
0 8 * * 1-6
```

```shell:ターゲットにIFTTのWebhooksイベントを指定
https://maker.ifttt.com/trigger/okaitsu/with/key/{key}
```

### 結果

この中では最速で実行される。8時になってから数秒でチャンネルが変わる。
今回は、この方法を採用しました。

# まとめ

時間指定のトリガーで何か処理したい場合は、Cloud Schedulerが最速なのかなという結果でした。
他に良いやり方あったら知りたいです。

Cloud Scherdulerは1分単位で指定できるので、前もって7時59分に実行するようにしておいても良いかも。
Nature Remoのルールや、IFTTTは15分単位なんですよね。
vscode remoteのよく分からんプロセスをkillする

vscode remoteは便利だがリモートサーバーによく分からんプロレスが乱立してしまうので、雑に消す。

対象はvscodeを含むものとsleep infinity


```sh:kill_vscode_process.sh
thisfile=`basename $0`
kill -9 `ps -FHU ${USER} | grep "vscode\|sleep infinity" | grep -v "grep\|${thisfile}" | perl -ane 'print $F[1], "\n"'`
```
【MyBatis】List＜Map＜＞＞ 入れ子をMapperパラメータとして渡す

# MyBatis のMapperパラメータに入れ子で渡したい!

- Mapは key, value で可能
- Listは 普通に入れ子で可能

# 環境
開発PC: Windows 10
STS: 4
mybatis:3.2.5
mybatis-spring:1.2.2
Java: 8

# 公式ドキュメント
http://www.mybatis.org/mybatis-3/ja/dynamic-sql.html
入れ子の説明は特になし

# SQL用意
- マッパー:xml

```xml:SampleMapper.xml
  <select id="selectTestMapList" resultMap="BaseResultMap">
  SELECT
    sample.*
  FROM
    sample
  WHERE
    sample.id IN
    <foreach item="internalMap" collection="nestedMapList">
        <foreach item="value" index="key" collection="internalMap"  open="(" separator="," close=")">
            #{value}
        </foreach>
    </foreach>
  </select>
```

# java定義
- マッパー:java

```java:SampleMapper.java
List<Sample> selectTestMapList(@Param("nestedMapList") List<Map<String, Integer>> nestedMapList);
```

# 実行してみる

```java:TestMapperExecutor.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/sample/spring/test-context.xml"})
public class TestMapperExecutor {

	@Autowired
	private SampleMapper sampleMapper;

	@Test
	public void test() {
		List<Map<String, Integer>> nestedMapList = new CopyOnWriteArrayList<>();
		Map<String, Integer> internalMap = new ConcurrentHashMap<>();
		internalMap.put("iKey", 1);
		nestedMapList.add(internalMap);

		List<Sample> result = null;
		try {

			result = sampleMapper.selectTestMapList(nestedMapList);
		}
		catch (Throwable t) {
			t.printStackTrace();
		}

	}

}
```

以上、お疲れ様でした！
中国のシリコンバレー、Huaweiも本社をおく深センで暮すにはいくらかかる？

米中貿易戦争、米中「5G戦略」の炎上にとともに、中国の通信機器大手である「HUAWEI（ファーウェイ/華為技術）」が世界で注目を集めています。HUAWEIは、1987年に中国 ・深センに設立され、30年かけて世界有数のICTソリューション・プロバイダーで、世界市場シェアは3位になっています。Tech系モノ作りの精神にあふれた深センも「中国のシリコンバレー」としていま世界中から注目されています。

Huawei、Tencent、ZTEなどのテクノロジー系会社が深センに本社を置くようになり、驚くべきスピードで新しい最先端技術を駆使して成長しています。深セン、中国の経済を推進する非常に多くの大企業を惹きつけてきた都市の魔法は何ですか？

深センは、中国の南側にある都市で香港に近く、港があるためコンテナ輸出入に有利な地形があり、1980年代には中国の最初の経済特区として設立され、その後、「トリクルダウン」政策の原動力となった深センでは、1,300万人が暮らしています。深センの経済と人々の生活状況をよりよく理解するために、住宅販売に関する20,000件以上の情報をスクレイピングしました。以下では調査結果を説明したいと思います。

 

#ステップ1.　データを収集する

 

Webサイト：Lianjia.com（中国で最も広く利用されている不動産Webサイト）

[Octoparse](https://www.octoparse.jp)を使用して、には、住宅名、住所、価格、利点、住居計画、住居地域、発売日、賃貸期間、賃貸要件、駐車スペース、電気、および駅までまでの距離が含まれる情報をスクレイピングします。

 

#ステップ2.　データを整理する
![住所情報.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/d8d445cc-97cf-d164-7fd5-5d9f1d948a5b.gif)

 

#ステップ3.　データを視覚化する
![地域1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/78c27b19-660d-fe62-f49b-d4ca47e5bdf4.jpeg)
![地域2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/eddcc002-5a7f-c67f-08d7-b6af295877b8.jpeg)

上のグラフは平方メートル当たりの家賃を示し、青は価格帯の安いのほうを、赤は高いのほうを表し、円の大きさは市場での家賃の数を表します。地図から家賃の放射輝度を見ると、香港（深センの南の方にある）に近いほど家賃は高くなる傾向が見られます。

![1st-degree-rental-numbers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/71fff35b-a7d7-49a4-cd2a-3d598e806799.png)

次に、家賃と物件の数です。棒が物件のレコード数で、赤い線が中国人民元の平方メートル当たりの単価を表しています。例えば、左から2番目の棒は、福田区の2550戸が平均130元/㎡で賃貸可能であることを示しています。

それでは、小地域（1つ区にはの複数の小地域がある）のデータを詳しく見てみましょう。どの区内でも都心部に近いエリアほど家賃が高いです。
![2nd-degree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/bc393392-fdb6-7aa5-4cf6-46538c942b1c.png)



下のグラフは平方メートル当たりの費用とアパートの面積の関係を示しています。小さいアパートは単価レベルでより多くの費用がかかることは明らかです。20㎡より小さいアパートは最も高いです。
![rental-cost-and-area.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/5f1046e0-b4de-96c9-e41e-d68c97d69ed0.png)


8〜15㎡の物件は1戸当たりの家賃が最も高いのに対し、70〜110㎡の物件は1戸当たりの家賃がはるかに低くなります。一方、家賃は110㎡を超える物件で回復しています。


家賃と地下鉄駅までの徒歩距離の相関関係を見てみましょう。相関係数の値は-0.49で、これは、地下鉄の駅までの距離が家賃と強い相関を持つことを意味します。駅に近いほど家賃が高くなる傾向があります。
![家賃と地下鉄駅.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/270d3b00-24b8-124d-a1b4-f00843cadb8d.jpeg)


HUAWEIの本社は深セン市の中心部の外として扱われてきた龍崗区にあり、家賃は55元/㎡なので、50㎡のアパートは50 * 55 = 2750元となります。

しかし、TencentやZTEを含むほとんどのハイテク企業と南山区のすべてのスタートアップ企業で働いている場合、例えば、毎月の給料は8000元で、50㎡のアパートを借りるなら、現在の家賃は50 * 130 = 6500元になり、相当大変でしょう。ですから、南山区ではルームシェアは普通です。もし一人暮らししたいなら、給料はそらく月に2万元ぐらいなら、そんな余裕があると思います。もちろん、平均㎡単価の低いエリアに住むのもいいですが、毎日の通勤ストレスを考えると思い切ってオフィスの近くに引っ越しをするというのもいいかもしれませんね。

 

いかがでしたか？深センに住みたい方はぜひ参考にしてみてください！
React.useEffectでfetchをするhookの実装方法

## はじめに

本記事は過去記事のまとめです。とはいえ、スクリーンキャストは新しい内容です。

## スクリーンキャスト

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">🎬 How to develop React useFetch hook. <a href="https://t.co/HEx5TwgUAo">https://t.co/HEx5TwgUAo</a> with code-surfer v2. 👍 <a href="https://twitter.com/hashtag/reactjs?src=hash&amp;ref_src=twsrc%5Etfw">#reactjs</a> <a href="https://twitter.com/hashtag/react?src=hash&amp;ref_src=twsrc%5Etfw">#react</a> <a href="https://twitter.com/hashtag/javascript?src=hash&amp;ref_src=twsrc%5Etfw">#javascript</a> <a href="https://twitter.com/hashtag/reacthooks?src=hash&amp;ref_src=twsrc%5Etfw">#reacthooks</a> <a href="https://t.co/QKukxnabbJ">pic.twitter.com/QKukxnabbJ</a></p>&mdash; Daishi Kato (@dai_shi) <a href="https://twitter.com/dai_shi/status/1146047738372485121?ref_src=twsrc%5Etfw">July 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

ゆっくり見るには、[リンク](https://dai-shi.github.io/react-hooks-fetch/)を開いて、右矢印を押して進めてください。

## 各ステップの記事

- [ステップ1](https://qiita.com/daishi/items/f78cf1b088961413170a)
- [ステップ2](https://qiita.com/daishi/items/2c40e27f7589231dbcef)
- [ステップ3](https://qiita.com/daishi/items/cdd1109ffa12826db44a)
- [ステップ4](https://qiita.com/daishi/items/873dca99cd18bb86239c)
- [ステップ5](https://qiita.com/daishi/items/a6a1caeb28f599b10517)
- [ステップ6](https://qiita.com/daishi/items/091cd4f8bb86cb5347fa)

## おわりに

[当初の記事](https://qiita.com/daishi/items/f12f524e9d1df0b52d2b)に載せたコードもほぼ同じものです。色々改善して最後に作成したスクリーンキャストの[コード](https://dai-shi.github.io/react-hooks-fetch/13)が分かりやすくなっていると思います。
怪しいユーザーにフォローされたときの対応方法

注意、非技術投稿です。

# 経緯
今朝Qiita確認したら、フォロー通知が届いていたのでアカウントを確認したら、出会い系みたいなところにリンクされているだけのアカウントだった。朝からムカついたので通報することにした。しかし一つ問題が、、:scream:

###### 記事やコメントの通報はできるけど、アカウントってどうやるのか分からない、、

ということで、Qiitaサポートにメールすることにしました。
当日中にアカウントの凍結（利用規約の第8条に違反のため）と、通報方法を教えてくださいました。

# 方法
ユーザーのプロフィールページより通報できるようになったそうです。(今朝の段階ではミュートのみ)
<img width="290" alt="スクリーンショット 2019-07-24 17.01.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283053/745ce11a-d20f-52d0-f05e-b792083002eb.png">

# まとめ
利用人数が増えればこういうことも増えると思うけど、いたちごっこだとしても、通報などをすることで
可能な限り(コードと一緒で)クリーンな環境になれば幸いですね。

最初はムカついたからが動機ですが、Qiita作っている方々の素早い対応に感動です。
自分もスピーディーに仕事せねば:expressionless:
Laravelで、Namespace declaration statement has to be the very first statement or after any declare call in the scriptってエラーが出た時の対策

## 環境
Ubuntu 16.04.5 LTS (Xenial Xerus)
Laravel Framework 5.6.26
 
## 状況
普通にコントローラーを作っていて、エディタ上ではエラーがないのでサーバーを立ち上げてみると、
「Namespace declaration statement has to be the very first statement or after any declare call in the script」
とエラーが出ました。

ググったら、
・namespaceの上に何も書くな
・<?php の上に何も書くな
みたいなことが書いてあったのですが、自分のコードを見た感じ問題なさそうだったが、、、
## 僕の解決策
<?php
の上に文字はないが、改行されていた。
まず、IPを確認

```
//ここは何もなく改行されていた。
<?php
//Bladeのテンプレートを使ってみるコントローラ
namespace App\Http\Controllers;
```

上記の何もない行をつめた。

```
<?php
//Bladeのテンプレートを使ってみるコントローラ
namespace App\Http\Controllers;
```

これでうまくいった。



##感想
フレームワークとかではなくPHP単体で使っていた時は、
そんなことでエラーがでた記憶はないのだが、、、
F#で独立性の検定（カイ2乗検定・フィッシャーの直接確率検定）

# 概要

データ分析なら「Python」か「R」がいいよね。

・・・ということで「**F#**」で「独立性の検定（カイ2乗検定・フィッシャーの直接確率検定）」を行なってみました。内容は「[PythonとRで独立性の検定](https://qiita.com/code0327/items/376955fe8479407f7982)」の移植です。解説は Python版 のエントリを参照ください。

　なお、F#で実行するにあたって **Accord.NET** というパッケージを利用しました。あらかじめ nuget で Accord.Statistics を導入しておいてください。ここではバージョン 3.8.0 を使いました。

# コード

```FSharp:独立性の検定
open System
open Accord.Statistics.Testing
open Accord.Statistics.Analysis

[<EntryPoint>]
let main argv =
  
  let m = ConfusionMatrix(array2D [ [140; 150]; [160; 180] ])

  let cst = new ChiSquareTest(m,yatesCorrection=false)
  printfn "カイ２乗検定"
  printfn "p値     = %.3f" <| cst.PValue
  printfn "自由度   = %d" <| cst.DegreesOfFreedom
  printfn ""

  let cst = new ChiSquareTest(m,yatesCorrection=true)
  printfn "カイ２乗検定（イェーツ補正あり）"
  printfn "p値     = %.3f" <| cst.PValue
  printfn "自由度   = %d" <| cst.DegreesOfFreedom

  printfn ""
  let ft = new FisherExactTest(m)
  printfn "フィッシャーの直接確率検定"
  printfn "p値 = %.3f" <| ft.PValue // 正しく計算できない！

  Console.ReadKey() |> ignore
  0
```

# 実行結果

　カイ2乗検定は正しく実行できています（[Python版](https://qiita.com/code0327/items/376955fe8479407f7982)と計算結果が一致）。

　しかし、残念ながらフィッシャーの直接確率検定による $p$ 値の計算は**失敗**しています（確率であるはずの $p$ 値が $1.0$ を超える数値で出力されている）。内部で階乗計算をする際にオーバーフローしていると思われます。

```:実行結果
カイ２乗検定
p値     = 0.760
自由度   = 1

カイ２乗検定（イェーツ補正あり）
p値     = 0.822
自由度   = 1

フィッシャーの直接確率検定
p値 = 1.300
```

## 観測度数が小さなものでフィッシャーの直接確率検定

観測度数が小さい場合は、うまく計算できるのかをチェックします。

まずは、Pythonで実行してみます。

```Python:Python
import pandas as pd
import scipy.stats as st
df = pd.DataFrame([[14,10],[21,3]])
_, p = st.fisher_exact(df)
print(f'p値 = {p :.3f}')
```

```:実行結果
p値 = 0.049
```

今度は、F# で実行してみます。

```FSharp:F#
let m = ConfusionMatrix(array2D [ [14; 10]; [21; 3] ])
let ft = new FisherExactTest(m)
printfn "p値 = %.3f" <| ft.PValue
```

```:実行結果
p値 = 0.049
```

一致しました。ついでに R でも試してみます。

```R:R
m=matrix(c(14, 10, 21, 3), nrow=2, byrow=T)
fisher.test(m)
```

```:実行結果
	Fisher's Exact Test for Count Data

data:  m
p-value = 0.04899
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 0.03105031 0.99446037
sample estimates:
odds ratio 
 0.2069884 
```

一致しています。
情報通信ネットワークの変遷

## 情報通信ネットワークの変遷
### モールス信号
電信
電気、音響、発行信号などで伝達可能
端点(・)と長点(-)を組み合わせてアルファベットや数字、記号を表現

### 電話
電磁誘導を応用し、音波による振動を電気に変換して伝達

メッシュ型接続
N個の電話機をつなぐ場合(N-1)*N/2本回線が必要

交換機の導入<-回線の本数を削減
手動交換機>>>自動交換機(ステップバイステップ方式)
日本でクロスバ交換機を導入

### トランジスタの発明
**トランジスタ**とは
増幅、スイッチ動作をする半導体素子
transfer(伝送)+register(抵抗)=transistor
デジタル回路の論理素子
現在はICに取って代わられている

### アナログからデジタルへ
**サンプリング定理**
原信号の最大周波数の2倍の周波数で標本化した信号はローパスフィルタで広域成分を除去することで現信号を還元に復元可能

電話回線では
人間の音声(0.3~4kHz)の2倍を超える8kHzでサンプリング->良好な音質を再現

デジタル交換機
超多重・即時処理
無中断アップグレード
対故障技術(冗長性)

### コンピュータネットワーク
ARPANET(国防総省,インターネットの原型)
核攻撃下でも生き残るネットワークを目指した
分散型ネットワーク
パケット交換方式(<->電話は回線交換方式)
1980年初頭よりTCP/IPによる通信のみに切り替え

## レイヤー、プロトコルの概念
### レイヤーの概念
上位と下位のように階層化
各レイヤーは独立に開発可能(モジュール化)
- モールス信号(上位層:モールス符号,下位層:物理層(電気、音、光、無線))
- アナログ電話通信(上位層:アナログ信号(音声),下位層:物理層(電気、無線))

### プロトコルの概念
**プロトコル** : 規約、規定
コンピュータ同士がネットワークを介して通信を行うために決められた「約束ごと」
(ex IP,ICMP,TCP,UDP,HTTP,...)

CPUやOSが異なるコンピュータ間で通信可能にするため
ビッグエンディアン：上位バイトから順に格納、リトルエンディアン：下位バイトから順に格納

**OSI参照モデル**：ネットワークプロトコルを単純化するためのモデル
通信に必要な機能を7つの階層に分けた。
7. アプリケーション層
6. プレゼンテーション層
5. セッション層
4. トランスポート層
3. ネットワーク層
2. データリンク層
1. 物理層

#### アプリケーション層

#### プレゼンテーション層
#### セッション層
#### トランスポート層
パケットの再送
#### ネットワーク層(IP層)
パケットの経路制御
#### データリンク層
フロー制御、ビット訂正
#### 物理層

下位層から見て上位層から受け取るものをペイロードという

### 通信方式の種類
①

- コネクション指向型(CO-mode)：データ送信の前にコネクションの確立。TCP
- コネクションレス型(CL-mode)：コネクションの確立や切断処理がない。送信したいホストはいつでもデータ送信可能。IP

②

- ユニキャスト：1対1,CO,CL
- マルチキャスト：1対多,CL
- ブロードキャスト：1対全,CL

③

- 回線交換
> 「回線」を占有=>「品質」保証
> 「帯域」の無駄が多い、コストがかかる

- パケット交換
> 「回線」を共有できる=>「帯域」を有効利用可能
> 「品質」を保証できない<=「混雑」する、遅延が揺らぐ、廃棄も起こる

### パケット交換が主流
柔軟な容量管理
CL通信が実現=>コネクション確立不要、相互接続が楽
CO通信も実現可能
高機能、低価格

賢い端末(TCP:高度な処理)とバカなネットワーク(IP:パケットの転送)
【Express】外部ファイルのコード読み込み

# はじめに
Expressで外部ファイルに記述した処理を使う方法のメモ。

## 外部ファイル``hogehoge.js``
``exports``を用いる。

```javascript
//例1
exports.hello = {
  name: 'Taro',
  age: '39',
}

//例2
exports.bye = function () {
  console.log('Good bye');
}
```

## 呼び出す側のファイル``index.js``
``require``で外部ファイル``hogehoge.js``を呼び出す。

```javascript
const hoge = require('hogehoge.jsのパス');

//例1
console.log(hoge.hello);

//例2
hoge.bye;
```
layoutsで取得したデータはページ遷移で更新されない

layouts の中で `this.$route.name` を取得し、フッターやヘッダーに渡したりしていました。

ページ間移動のときに当然 layouts の `this.$route.name` も同時に再取得されると思い込んでいましたが、どうやら更新されないようです。

[【Nuxt.js】layoutsに設定をまとめつつ、タイトルはpagesから設定したい](https://qiita.com/yama-t/items/b051cd9ea802f69da118)

こちらの記事を参考にし、 pages で `this.$route.name` を取得し、それを layouts に渡してからフッターに落とすように変更しました。

これでページ遷移のたびに `this.$route.name` が取得され、期待通りに動いてくれました。
Route53フェイルオーバ機能での夜間用Sorryページ切り替えをあきらめた話

Route53のフェイルオーバ機能を利用した日中⇔夜間のページ切替を行おうとしたところ、社内プロキシの壁に阻まれた（と思われる）がために、代替手段を模索したお話です。

####1.おおまかな要件
・日中のサービス時間帯のみウェブアプリケーションが稼働し、夜間はサーバを停止してコストカット
・夜間帯のサービスアウト時にはSorryページが表示される
・アプリケーションは特定多数のクライアント企業が使用し、クライアント証明が必要

####2.やろうとしたこと
・サービスイン時のみEC2(ASG)でウェブアプリケーションが稼働し、サービスアウト時はASGの起動インスタンス数を0にする
・サービスアウト時にRoute53のフェイルオーバ機能が働き、S3に静的ホスティングしたSorryページを表示
・クライアント証明のためにALB不可のため、NLBを選択

**構成図**
※Bastionは運用/保守用の24H稼動インスタンス
![処理フロー-ページ10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285420/f88710b3-5bac-2c89-9fd4-18b1095a1fd2.png)

####3.問題
ここで問題が発生しました。
Route53でドメインの向き先Aliasが切り替わった際、**名前解決先は切り替わっているのに30分以上Web画面が切り替わらない状態**に陥りました。
Resolve-DnsNameで確認しても、TTL（60秒）後にはちゃんと解決先が切り替わっていることが確認できます。

さらに確認を進めると、

・社内ネットワーク内の端末からのアクセス時には切り替わらない
・パブリックネットワーク上のEC2からのアクセス時にはちゃんと切り替わる

ということが分かりました。

ここから**”社内プロキシがドメインの名前解決先をキャッシュしてしまっているのでは...？”**と考えました。
しかし、社内プロキシ側の仕様はブラックボックスなため確実かどうかは判断できません。

####4.対応
とはいうものの、開発もIT工程後半に差し掛かっており、どうにか早急に代替策を考えねばならない。
かつ、もし社内プロキシが原因だとすると、特定多数のクライアント企業側のプロキシ仕様によっては同様の事象が置き得るのでは？
という状態になりました。

そこで、代替策としてNLBのListenerをLambdaで操作し、リクエストのターゲット先を切り替える方針を検討、

・NLB利用のため、バックエンドにLambdaを置く方法はだめ
・ちょうど、運用／保守用のBastionインスタンスが24H稼動している

という前提を踏まえて以下の構成をとり、サービスアウト時にはBastionインスタンスに配置したSorryページを応答することにしました。

![処理フロー-ページ11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285420/ee8ea413-de28-7917-357a-aaf4763e8b7c.png)


NLBを切り替えるLambdaFunctionはシンプルにこんな感じで、サービスイン／アウトフラグをCloudWatchEventから受け取って切替処理を行います。

```ChangeNlbTarget.py
import boto3
import os
import logger_formatter

logger = logger_formatter.setup_logging('ChangeNlbTarget')
client = boto3.client('elbv2')

def lambda_handler(event, context):
    logger.info('function start.')
    logger.info('event_param: %s', event)
    
    is_service_in = event['is_service_in']
    
    if not isinstance(is_service_in, bool):
        logger.error('error_message: %s is not boolean', is_service_in)
        raise Exception('Input Parameter is Invalid.')    
            
    if is_service_in == True:
        target = os.environ['TARGET_WEBAP_ARN']
    else:
        target = os.environ['TARGET_SORRY_ARN']
    
    try:
        res = client.modify_listener(
                ListenerArn = os.environ['LISTENER_ARN'],
                Port = 443,
                Protocol = 'TCP',
                DefaultActions = [
                        {
                            'Type' : 'forward',
                            'TargetGroupArn' : target
                        }
                    ]
            )
    except Exception as e:
        logger.error('error_message: %s', e)
        raise Exception('Change Nlb Target failed.')    


    logger.info('function end.')
    return{
        'statusCode': 200
    }
```

####5.結果
しっかりTTL後には日中⇔夜間のページ切替が完了できるようになりました。
また、もともと24H稼動の必要がある別インスタンスを利用することで、コスト増も避けることができました。

想定する原因が本当に合っているのか、対応方法はベターか、というところはあるかと思います。
もし同じような状況に陥ったことがある方がいらっしゃれば、原因・対応方法等をコメントいただけると幸いです。
Vagrant + VirtualBox + CentOS 7 に Nuxt.js を入れてみる

自主学習のメモ。ページが表示されるところまでは確認しました。

### Vagrantfile の修正

```:Vagrantfile

Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.6"
  config.vm.box_url = "https://app.vagrantup.com/bento/boxes/centos-7.6"

  #config.vm.network :forwarded_port, guest: 80, host: 8888
  config.vm.network :forwarded_port, guest: 3000, host: 3000
  config.vm.network :private_network, ip: "192.168.33.34"

  #config.vm.synced_folder "./mnt/project/", "/mnt/project/",
  #:owner => "vagrant", :group => "vagrant",
  #:mount_options => ["dmode=777,fmode=777"]
end
```

後でnuxt.jsでプロジェクトを作る際に、いろいろライブラリをインストールするんですが、
その際にシンボリックリンクを作ろうとします。
しかし、Vagrantでマウントしているディレクトリ内にシンボリックリンクは作成できず、エラーになるので、
マウントしないように設定します。

また、ローカル環境のURL「 http://localhost:3000 」にアクセスできるようにポートフォワーディングの設定をしています。

### Node.js のインストール

公式ドキュメントに従い、 `Nuxt.js` をインストールするために `create-nuxt-app` を使用します。
`create-nuxt-app` を使うためには、 `npx` がインストールされている必要があり、
`npx` をインストールするには、 `npm` が必要です。

`npm` は、 `node.js` をインストールすれば一緒にインストールされます。
ゆえに、 `node.js` をインストールします。

執筆時点での最新版であるVer12系をインストールします。

#### インストール

```
curl -sL https://rpm.nodesource.com/setup_12.x | bash -
yum install nodejs
```

#### バージョン確認

```
node -v
npm -v
```

`nodejs v12.7.0` と `npm v6.10.0` がインストールされました。

### npx のインストール

#### インストール

```
npm install -g npx
```

### Nuxt.js のインストール

これで `create-nuxt-app` が使用できるようになり、 `Nuxt.js` をインストールする準備が整いました。
次のコマンドで、いよいよ `Nuxt.js` を稼働させます。

```
cd /path/to/project
npx create-nuxt-app myproject
```

CUI上でどういうモジュールを入れるか色々と質問されます。
jQueryとPHPで生きてきた人間なので、
ぶっちゃけ質問内容がほとんどよくわかってないですが、フィーリングで乗り越えます。

```
npx create-nuxt-app myproject

npx: installed 379 in 18.122s
create-nuxt-app v2.8.0
✨  Generating Nuxt.js project in /path/to/project/myproject
? Project name test
? Project description My mind-blowing Nuxt.js project
? Author name
? Choose the package manager Npm
? Choose UI framework Bootstrap Vue
? Choose custom server framework Express
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support
? Choose linting tools ESLint
? Choose test framework Jest
? Choose rendering mode Universal (SSR)

cd test
rpm run dev
```

### おわり

できました。すごい。
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130352/ae191af2-df87-ddce-60bd-0769a1c3db98.jpeg)
数学から見た物体と運動, 砂田利一, 2004

岩波講座-物理の世界-物の理-数の理〈1〉数学から見た物体と運動, 砂田利一, 2004
![41239X7ZHSL._SX317_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/aa60990c-c3d7-03a1-ee33-c62db0ab50c6.jpeg)
https://www.amazon.co.jp//dp/4000111639/


#参考文献
###1
砂田
行列と行列式
###2

局面の幾何
###3
松島
多様体入門
###4
W. Rudin, Real and Complex Analysis, McGraw-Hill, 1987
###5
バナッハ・タルスキーのパラドックス
###6
谷島
物理数学入門
###7
C.L. Siegel and J.K. Moser, Lectures on Celestial Mechanics, Springer-Verlag, 1971
###8
ニュートン　世界の名著３１　中央公論社
###9
超函数の理論　岩波　１９７１
###10
ユークリッド原論-縮刷版-中村-幸四郎/　1996
https://www.amazon.co.jp/dp/4320015134/

>時間ができたら、ユークリッドを読もうと本棚に飾ってありました。
縮刷版が出るまえのものは、装丁がよいので、インテリアとして、ニュートンとならんでいます。
ブランデーでも飲みながら、読もうと思っていました。
設計工学、機械工学などで参考文献になっているので、読み始めました。
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
COTOHAで文章の類似度を取得してみる

# COTOHA
[公式サイト](https://www.ntt.com/business/services/application/ai/cotoha.html)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/1af0be73-5a69-defb-e704-5249b923bc17.png)

# 実装
* COTOHAというNTTが提供している自然言語系のAPIを触ってみます。
* 文章と文章の類似度を算出するAPIを使います。
* Ipython形式で実装します。

## ライブラリのインポート
```python
import json
import numpy as np
import pandas as pd
import urllib.request
from os import path
```

## 情報の定義
* [アカウントホーム](https://api.ce-cotoha.com/home)のデータを定義する。
* **Developer API Base URL**と**Access Token Publish URL**は全ユーザー共通だと思いますが、念のため各自登録してお調べください。
<img width="1440" alt="スクリーンショット_2019-07-24_8_33_45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106459/8af0045c-0546-9279-826d-7b146b76ba92.png">


```python
base_url = [Developer API Base URL]
developer_id = [Developer Client id]
secret = [Developer Client secret]
token_url = [Access Token Publish URL]
    'Content-Type': 'application/json',
}
```

## アクセストークンの取得
* アクセストークンを取得するため、POSTでアクセストークン取得用のAPIにアクセスします。

```python
data = {
  'grantType': 'client_credentials',
  'clientId': developer_id,
  'clientSecret': secret
}

req = urllib.request.Request(token_url, json.dumps(data).encode(), headers=headers, method='POST')
with urllib.request.urlopen(req) as res:
    access_info = json.load(res)
```

```python
print(access_info['access_token'])
```

## 単語文章同士の類似度取得
*取得したアクセストークンをヘッダーに詰めて、類似度取得APIにアクセスします。

```python
def similarity_api(s1: str, s2: str):
    data = {
        's1': s1,
        's2': s2,
        'type': 'default'
    }
    headers = {
        'Content-Type': 'application/json;charset=UTF-8',
        'Authorization': 'Bearer {}'.format(access_info['access_token'])
    }
    url = base_url + 'nlp/v1/similarity'
    req = urllib.request.Request(url, json.dumps(data).encode(), headers=headers, method='POST')
    with urllib.request.urlopen(req) as res:
        body = json.load(res)
    return body
```

```python
similarity_api('近くのレストランはどこですか？', 'このあたりの定食屋はどこにありますか？')
```

# 所感
* 単語や文章の類似度の算出は、tf-idf、word2vecやdoc2vecで割と世の中に出回っているため、目新しさはないです。
* ただ、機械学習に慣れていない方には比較的に簡単に扱えるため、便利だと思います。
* また、wikipediaのデータで自分で学習したword2vecのモデルより、**対応している単語も多く**かつ、**類似度の精度**も高い印象でした。
[Fortran] ネームリスト

[Qiita@earth06: 数値モデルにでてくるFORTRAN77文法~完結編#NAMELISTによる変数への値の代入]
(https://qiita.com/earth06/items/f8d6e2d504b24af0cbb7#namelist%E3%81%AB%E3%82%88%E3%82%8B%E5%A4%89%E6%95%B0%E3%81%B8%E3%81%AE%E5%80%A4%E3%81%AE%E4%BB%A3%E5%85%A5)


# 基本

### コード

```Fortran
program main
    implicit none
    character(len=256), parameter :: nml_path = './test.nml'
    integer, parameter :: unit = 11
    integer :: a = 1, b = 2
    namelist /test/ a, b

    open(unit, file=trim(nml_path), status='old')
    read(unit, nml=test)
    close(unit)
    write(*, *) 'a', a
    write(*, *) 'b', b
end program main
```

ネームリストに該当する変数が存在しない場合，単純に読み込みがスキップされるだけでエラーは発生しない
→デフォルト値を設定しておき，それを変更する場合のみネームリストを使う，ということができる

### ネームリスト

#### 書式

`&{ネームリスト名前}`で始め，`/`または`&end`で結ぶ．

```Fortran:test.nml
&test
a = 11
b = 12
/ ! &endでも良い
```


##### 改行・カンマはなくとも良い

以下はいずれも動作する．但し，`/`と`&end`のどちらかは必ず必要．

```Fortran:test.nml
&test a = 11  b = 12 /
&test a = 11, b = 12 /
&test a = 11  b = 12 &end
&test a = 11, b = 12 &end
```

私見：
改行して書くなら終わりは`/`でも`&end`でも良いと思うが，
1行に書くなら`&end`の方が視認性高そう（`/`だと書き忘れたときに気が付きにくい）．


##### 複数のネームリストがある場合，最初にヒットしたものが有効になる

1つ目のネームリストでbを与えない場合，2つ目からbを読み取る，ということは**ない**．

```Fortran:test.nml
&test a = 11, b = 12 &end
&test a = 21, b = 22 &end
! -> a = 11, b = 12

&test a = 11 &end
&test a = 21, b = 22 &end
! a = 11, b = 2
```

#### ネームリストのコメントアウト

##### 変数のコメントアウト

```Fortran:test.nml
&test
!a = 11
b = 12
/
! -> a = 1, b = 12
```

aとbを共にコメントアウトしてもOK (-> a = 1, b = 2)．
改行のないネームリストとは相性が悪いが，
bをコメントアウトするときは`a = 11!, b = 12`でも`a = 11, !b = 12`でも良い．

##### ネームリスト自体のコメントアウト

最初に示したコードだと，ネームリスト自体`&test`を削除するのはNG．
しかし，以下の通りIOErrorを陽に処理すると，この場合でも動作する（ネームリストが存在しない場合，デフォルト値のまま）．

```Fortran:main.f90
integer :: ios
read(unit, nml=test, iostat=ios)
```




## 配列の読み込み

2019年7月24日：ページ分割

ネームリスト内では`(/`や`[`などで囲まず，配列の要素をそのまま列挙する．

``` :test.nml
&nml_test
a = 1,2,3
/
``` 

- プログラム内で`/ネームリスト名/`として指定する際には，`(:)`は付けない
- ネームリストより配列が大きい場合でも問題なし
- ネームリストより小さい場合にはエラー
- 未割り付けの配列に読み込むことは不可

従ってネームリスト内の配列の大きさが分からない場合，

- 十分大きな配列を用意する
- センチネル値（ありえない値→その値になったらループを終える）を予め全要素に代入しておく

``` Fortran:namelist.f90
program main
    implicit none
    integer, allocatable :: a(:)
    character(len=256), parameter :: nml_path = './test.nml'
    integer           , parameter :: nml_unit = 11, nml_size = 3
    namelist /nml_test/ a ! "a(:)"と書くとコンパイラを通らない

    allocate(a(nml_size)); a(:) = 0
    open(nml_unit, file=trim(nml_path), status='old')
    read(nml_unit, nml=nml_test)
    close(nml_unit)
    write(*, *) a(:) ! 1 2 3
    deallocate(a)

    allocate(a(nml_size+1)); a(:) = 0
    open(nml_unit, file=trim(nml_path), status='old')
    read(nml_unit, nml=nml_test)
    close(nml_unit)
    write(*, *) a(:) ! 1 2 3 0
    deallocate(a)

    allocate(a(nml_size-1)); a(:) = 0
    open(nml_unit, file=trim(nml_path), status='old')
    read(nml_unit, nml=nml_test) ! forrtl: severe (18): too many values for NAMELIST variable
    close(nml_unit)
    write(*, *) a(:)
    deallocate(a)

    open(nml_unit, file=trim(nml_path), status='old')
    read(nml_unit, nml=nml_test) ! forrtl: severe (174): SIGSEGV, segmentation fault occurred
    close(nml_unit)
    write(*, *) a(:)
    deallocate(a)
end program main
```
これからAlexaスキルを作る方へ、しくみをざっくりと噛み砕いてみた





今巷でトレンドなテーマのAlexaスキルですが、簡単に出来る！と言われます。

確かにそうなのですが、概念も分からず作るのは、新入社員が「これはこういうものだからやれ」と理不尽な教育を受けるようなものなので、

いくつかスキルを作って私なりに理解した内容を噛み砕いて説明したいと思います。

この概念が分かれば、問題が起きた時に、どこを見れば良いかがいち早くわかるかと。

ではまず、全体の構成を見てみましょう。

# 全体の構成
全体の構成を図解するとこんな感じです。

高度なスキルはこの限りではないケースもありますが、説明しやすいよう最低限の構成にしています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/faadd065-bcab-e7bf-4ac9-652f6cd1e96e.png)


ここから、各ブロックごとの説明をしていきます。

# フロントエンド：Alexa developer console

ユーザが発話した内容を解析し、起動するインテントを判断するための部分。

要するに、発話内容をデータに落とし込む部分ですね。

データに落とし込んだものをJSONに変換してLambdaに送ります。

発話内容に関する設定はこの部分を変更します。


# バックエンド：AWS Lambda

バックエンドというと色々面倒な処理をするイメージがありますが、実はLambda側はルールに沿ってJSONフォーマットのコマンドを作ってるだけ。

それだけの役割なので、フロントエンドからインテントとして受け取った情報をどう料理するかを考えれば良いことになります。

そのため、ある程度言語に自由度があります。私なんかはPythonを勉強の一環で使ってます。

ただ、Alexa スキル関係の技術情報はJSを例にとることが多いので、特段理由が無ければJSが良いと思います。



## デバッグログ：AWS Cloudwatch logs

優秀なロギングサービスです。

JSONでやり取りしているフロントエンドとバックエンド間の通信ログを自動で取っておいてくれるスグレモノ。

意図しないインテントが呼び出されているなんてのはこれが無いとデバッグが難しいでしょう。

また、Lambdaでprint文を書いたりするとここに記録されるので、実行順や変数の中身を見るのにも使えます。

フィールドテストのときなどにも使えますね。


# まとめ

シンプルを目指すために、非常にざっくりとした説明にはなりましたが、ある程度構成の全貌が分かってもらえば幸いです。

これを理解しているかどうかでは、開発速度は格段に違うと思います。

まだまだ駆け出しのテクノロジですが、Amazonが公式で公開しているドキュメントの類が結構分かりやすくて優秀なので、ハードルを下げてくれています。

コード量もそれほど多くなくて始められるので、プログラミングの練習に使っても良いかもしれませんね。

エンジョイスキルライフ！
数学から見た連続体の力学と相対論, 砂田利一, 2004

岩波講座-物理の世界　物の理-数の理〈3〉数学から見た連続体の力学と相対論, 砂田利一, 2004
![516WCX4M3TL._SX320_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/627715a1-d176-fbd2-fbfb-23c4f3bad87e.jpeg)
https://www.amazon.co.jp/dp/4000111655/

# 参考文献
### 1 
変形と流れの力学
### 2
連続体の力学　岩波　１９９５
### 3
砂川
電磁気学　岩波　１９８７
### 4
深谷
電磁場とベクトル解析
### 5
望月
波動方程式の散乱理論
### 6
応用偏微分方程式　１９７１
### 7
L. Hormander, The analysis of linear partial differential operators III, Springer-Verlag, 1985
### 8
相対性理論　みすず書房　１９５９
### 9
佐藤
一般相対性理論　岩波２０００
### 10
砂田
行列と行列式　岩波　２００３

# 参考資料
物理記事　上位100
https://qiita.com/kaizen_nagoya/items/66e90fe31fbe3facc6ff

数学関連記事１００
https://qiita.com/kaizen_nagoya/items/d8dadb49a6397e854c6d

Qiita(0)Qiita関連記事一覧（自分）
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 初稿 　 20190522
ver. 0.02 ありがとう追記 　 20230525
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
【Flutter】ListViewのListTileにRipple Effectが表示されない

# 背景
ListViewの各項目をListTileで実装している画面にて、本来ならデフォルトで表示されるはずのRipple Effectが表示されませんでした。

# 原因
ListViewを`Container`で囲っていたことが原因でした。

```dart:sample.dart
Container(
  color: Colors.white,
  child: ListView.separated(
    itemBuilder: (context, index) {
      return ListTile(
        leading: leading,
        title: title,
        trailing: trailing,
        onTap: () {},
      );
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
    itemCount: data.length,
  ),
);
```

画面全体の背景とは別に、リスト自体にも背景を付けたいと思い白色の`Container`でListViewを囲っていました。
これが原因でListTileのRippleが表示されなくなっていたようです。

# 対応
ListTileを囲っていた`Container`を削除しました。
しかし、このままだとListViewの背景が画面全体の背景になってしまうので、ListTileをInkで囲うことで背景色を白色にしつつRipple Effectも残しました。

```dart:sample.dart
ListView.separated(
  itemBuilder: (context, index) {
    return Ink(
      color: Colors.white,
      child: ListTile(
        leading: leading,
        title: title,
        trailing: trailing,
        onTap: () {},
      ),
    );
  },
  separatorBuilder: (context, index) {
    return Divider();
  },
  itemCount: data.length,
);
```