OmniAICreator/Qiita-1.07M huggingface dataset:
【docker-compose】env_fileとenvironmentの違い。環境変数適用の優先順位について

個人用メモです。

env_fileとenvironmentはどちらもdocker-compose.ymlでrun時に**環境変数を指定する**。


- run（コンテナ作成）時のみ適用される。
- **build（イメージの作成）では使われない**
    - build時に環境変数を指定したい場合は、build -> argsを使う。


<br>
##env_fileとenvironmentの違い


###・環境変数の読み込み方法と設定方法が違う
env_fileは**環境変数が記載されたファイルを読み込む**。

environmentは**docker-compose.ymlに直接変数を記述**する。



```:env_fileの例
env_file: 
  - .env
  - .env.prd
  - .env.local.aws
  - ./common.env
  - ./apps/web.env
```

```:environmentの例
environment:
  - NODE_ENV=development
  - PORT=80
  - MIGRATE=true
  - USER=${USER}
  - AWS_REGION=ap-northeast-1
```



<br>
###・優先度が違う

それぞれで同じ環境変数を指定している場合、env_fileよりも**environmentの設定の方が優先**される。

env_fileで複数のファイル指定や、environmentで複数重複する変数の指定がある場合は、**最後の方が優先**される。

ホストに環境変数が設定されている場合は、その値が優先される。


・優先順位：
*`(1)ホスト > (2)environment > (3)env_file > (4)DockerfileのENV`*


ホストの環境変数が最優先なため、もしホストの環境変数が適用されてしまう場合は、docker側の環境変数名の変更が必要。




<br>
##env_file

env_fileで指定するファイルパスはdocker-composeを実行したディレクトリが基準となる。

**▼ファイルの指定方法**

1. ファイルが一つの場合　`env_file: .env`
2. ファイルが複数の場合（１つでも可）

```:複数の場合
env_file:
  - .env
  - .env.prd
  - .env.local.aws
  - ./common.env
  - ./apps/web.env
```

```:１つの場合
env_file:
  - .env
```


**▼ファイル名は複数の付け方がある**

| ファイル名 | 内容 |
|:-:|:-:|
| .env  | デフォルトのファイル名  |
| .env.local.aws  | 頭に .env がつく  |
| common.env  | 後ろに .envがつく  |
| ./apps/web.env  | 下の階層のファイル  |
【JavaScript】Proxyオブジェクトについて【まとめ】

# Proxyオブジェクトとは

指定したオブジェクトのプロパティを操作する際に**独自の処理を追加**する為のオブジェクト。

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}

const handler = {
  メソッド
}

new Proxy(target, handler);

// target  = 指定するオブジェクトが入る
// handler = 指定したオブジェクト(target)を操作する際に
//           実行されるメソッドが格納されたオブジェクト

```

# 使用例１

プロパティの値に変更があった際に「変更がありました。」と出力する。

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}
const handler = {
  set(target, prop, value) {
    target[prop] = value;
    console.log('変更がありました。') ;
  }
}

const pxy = new Proxy(target, handler);
pxy.hoge = 'ほげ';

console.log(pxy);

```

![スクリーンショット 2020-11-18 9.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/7d774993-31f7-8a97-75b9-8bb72fb129d2.png)


**setメソッド**
値の変更を検知する。

第一引数：targetオブジェクト
第二引数：プロパティの名前
第三引数：変更された値

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}
const handler = {
  set(target, prop, value) {
    console.log(target);
    console.log(prop);
    console.log(value);
  }
}

const pxy = new Proxy(target, handler);
pxy.hoge = 'ほげ';

```

![スクリーンショット 2020-11-18 7.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/8a9e860e-28ff-b4a0-a95c-b0e225c3097e.png)

# 使用例２
プロパティの値を取得した際に「取得しました。」と出力する。

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}
const handler = {
  get(target, prop) {
    console.log('取得しました。');
    return target[prop];
  }
}

const pxy = new Proxy(target, handler);
pxy.hoge;

console.log(pxy);

```

![スクリーンショット 2020-11-18 9.29.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/621fde88-d837-c670-62d2-db8146e708cb.png)

**getメソッド**　
値の取得を検知する。

# 使用例３
プロパティの値を削除した際に「削除しました。」と出力する。

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}
const handler = {
  deleteProperty(target, prop) {
    console.log('削除しました。') 
    delete target[prop];
  }
}

const pxy = new Proxy(target, handler);
delete pxy.hoge;

console.log(pxy);

```

**deletePropertyメソッド**
値の削除を検知する。

![スクリーンショット 2020-11-18 9.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/8c1a7d28-70bd-c991-3fc3-4222a6d213e7.png)

# 使用例４
存在しないプロパティにアクセスしたときエラーを表示させる。

```JavaScript:main.js

const target = {
  hoge: 'hoge',
  fuga: 'fuga'
}
const handler = {
  get(target, prop) {
    if (!target[prop]) {
      throw new Error('プロパティが存在しません。');
    }
    return target[prop];
  }
}

const pxy = new Proxy(target, handler);
console.log(pxy.hoge);
console.log(pxy.fuga);
console.log(pxy.piyo);

```

![スクリーンショット 2020-11-18 9.49.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/7094bb08-41e6-0a57-d69c-828211e21f11.png)



***
以上、Proxyについてまとめでした。
ここまで見て頂きありがとうございました！
FirestoreとSwiftでLINEみたいなチャットを作ってみた

1年前に作ったソースですが、備忘までに晒しておきます。
https://github.com/yuuuta-kimura/SampleChat

#実装のポイント

* Firestoreを使うと、データのCRUDの検知がアプリ側でリッスンするだけで簡単に実装できる。
* 会話の流れは、UITableViewを使って実装する
* 一つ一つの会話は、UITableViewCellを使って実装する
*  UITableViewCell同士の上下マージンは、セクションごとに区切ることで実現できる
*  無限スクロールは、scrollViewDidEndDraggingを検知して実装できる
*  キーボードの表示非表示の処理を実装する

とりあえず今思い出せるのは、以上。

#チャットを実装したアプリ
なかまリサイクル
https://nakama.land
React-親から子に値を渡す方法【関数コンポーネント】

### Propsって?
  * 親コンポーネントから渡されたプロパティ（値）
  * 直接外部のStateに接続する場合にはPropsで受け取る
  * 不変のデータ
  * 変更不可
  * 親から渡される
  
Props は、一般的に、親コンポーネントから子コンポーネントに渡される値。


###記述方法

今回説明するページの構造

```
OyaComponent.jsx
 - ChildComponent.jsx
```

親Componentに値を管理するStateがある。
そのStateの値を子Componentで表示させる。

では早速。


####親Component

```React:OyaComponent.jsx

import React, { useState } from "react";
import TextField from "@material-ui/core/TextField";

function OyaComponent (props) {

const [allData, SetAllData] = useState({
    nickname: "値１",
    txtData:"値2"
  });

  return (
    <ChildComponent data={allData}/>
  )
}
```

###子Component

```React:ChildComponent.jsx

import React from 'react';

function ChildComponent(props) {
  return (
    //それぞれに値1,値２が表示される
    <p>{props.data.nickname}</p>
    <p>{props.data.txtData}</p>
  )
}
```

###渡された値の確認方法

```React
consol.log(props);
```
アラビア数字をローマ数字に変換する



# 概要

アラビア数字を受け取り、ローマ数字を返す method を Ruby で作成する

ローマ数字: <https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%9E%E6%95%B0%E5%AD%97>


# コード

```ruby
 1  $table = {1=> 'I', 4=> 'IV', 5=> 'V', 9=> 'IX', 10=> 'X', 40=> 'XL', 50=> 'L', 90=> 'XC', 100=> 'C', 400=> 'CD', 500=> 'D', 900=> 'CM', 1000=> 'M'}
 2  
 3  # reverse sort
 4  $table = Hash[ $table.sort.reverse ]
 5  
 6  
 7  def arabic2roman(arabic_num)
 8    if arabic_num.between?(1,3999)
 9      # initialize
10      i = arabic_num
11      roman_num = ''
12  
13      for s in $table.keys
14        if i == 0
15  	break
16        else
17  	# q: quotient, r: remainder
18  	q = i / s
19  	r = i % s
20  	# update
21  	i = r
22  	roman_num += $table[s] * q
23        end
24      end
25      return roman_num
26    end
27  end
```

以下の行を追加して、コードをテストする

```ruby
test = [1, 2, 4, 5, 6, 9, 10, 11, 14, 15, 19, 38, 42, 49, 51, 97, 99, 439, 483, 499, 732, 961, 999, 1999]

test.each do |num|
  puts "#{num} #{arabic2roman(num)}"
end
```

結果は以下の通り

    1 I
    2 II
    4 IV
    5 V
    6 VI
    9 IX
    10 X
    11 XI
    14 XIV
    15 XV
    19 XIX
    38 XXXVIII
    42 XLII
    49 XLIX
    51 LI
    97 XCVII
    99 XCIX
    439 CDXXXIX
    483 CDLXXXIII
    499 CDXCIX
    732 DCCXXXII
    961 CMLXI
    999 CMXCIX
    1999 MCMXCIX

Ruby初心者なので、キレイなコードではないかもしれません

これからもっとRubyについて学んでいきたいと思います!



------
 - **source** ~/doc/lecture/multi-scale/grad_members_20f/members/yukiue/docs/roman_numerals.org
[JavaScript] 配列とオブジェクトについて

4回目の投稿です。
記事を投稿する度に少しずつ要領を掴めてきた気がします。
ノートにさっとまとめながら勉強しています。

#配列
##基本的な書き方
配列は他の言語と書き方はほぼ同じ。

```javascript
const 定数名 = [要素1,要素2,要素3];
console.log(定数名);
console.log(定数名[インデックス番号]);
定数名[インデックス番号] = "文字列"; //数値の場合は""で囲まない。
console.log(定数名[インデックス番号]);
```
このように書く。
一行目は、定数を宣言し、定数に配列を代入
二行目は、(定数を記述することで)配列を出力
三行目は、配列の中でも指定のインデックス番号の要素(文字列や数値)を更新
四行目は、二行目と同様に(定数を記述することで)配列を出力

具体的には以下のように書く。

```javascript:sample1
const names = ["itiro","jiro","saburo"];
console.log(names);
console.log(names[0]);
names[0] = "hanako";
console.log(names[0]);
```
```
["itiro","jiro","saburo"]
itiro
hanako
```
と表すことができる。

##配列とfor文の組み合わせ
配列とfor文を組み合わせることによって、配列内のすべての値を簡単に出力できる。

```javascript:sample2
const names = ["itiro","jiro","saburo"];
for (let i = 0; i < names.length; i++) {
  console.log(names[i]);
}
```
```
itiro
jiro
saburo
```
となる。これは、**変数i が 0～ 配列namesの要素数まで繰り返す**という意味。
また、**配列.length** とすることで配列の要素数を取得できる。

```javascript:sample3
const names = ["itiro","jiro","saburo"];
console.log(names.length);
```
```
3
```
#オブジェクト
**オブジェクト**とは、複数のデータをまとめて管理するのに用いる。
オブジェクトがそれぞれの値に名前を付けたものを**プロパティ**という。

```
配列
[値1,値2,値3]

オブジェクト
{プロパティ1:値1,プロパティ2:値2}
```
書き方は配列とほとんど変わらない。要素を更新することもできる。

```javascript:sample4
const item = {name:"pen",price:150};
console.log(item);
console.log(item.name);
item.price = 300;
console.log(item.price);
```
```
{name:"pen",price:150}
pen
300
```
#オブジェクトを要素に持つ配列
[配列]内に{オブジェクト1},{オブジェクト2}が存在する。

```
[{プロパティ1:値1},{プロパティ2:値2}]
```
```javascript:sample5
const items = [
      {name:"pen",price:150},
      {name:"note",prce:200}
];
console.log(items);
console.log(items[0]);
console.log(items[0].name);
console.log(items[1]);
conlole.log(items[1].price);
```
```
[{name:"pen",price:150}, {name:"note",price:200}]
{name:"pen",price:150}
pen
{name:"note",price:200}
200
```
#参考
**Progate**>**JavaScriptⅡ**
ベクトルにかかっている行列を求める


# 定理

あるベクトル$x \in {\rm R}^n$, $y \in {\rm R}^m$の間に
$$
    y=Ax
$$
という関係が成立している．
$x$と$y$は既知であり，$A\in {\rm R}^{m\times n}$が未知の場合を考えよう．

このとき，かかっている行列$A$はヤコビ行列を用いて

```math
A = \frac{\partial y}{\partial x}
=\begin{bmatrix}
\dfrac{\partial y_1}{\partial x_1} & \dfrac{\partial y_1}{\partial x_2} & \cdots & \dfrac{\partial y_1}{\partial x_n}\\
\dfrac{\partial y_2}{\partial x_1} & \dfrac{\partial y_2}{\partial x_2} & \cdots & \dfrac{\partial y_2}{\partial x_n}\\
\vdots & \vdots & \ddots & \vdots\\
\dfrac{\partial y_m}{\partial x_1} & \dfrac{\partial y_m}{\partial x_2} & \cdots & \dfrac{\partial y_m}{\partial x_n}\\
\end{bmatrix}
```

で求められる．

## 証明

$x \in {\rm R}^n$に対して定義される関数$f(x) \in {\rm R}$の全微分は

$$
f'(x) = \dfrac{\partial f}{\partial x_1} dx_1+ \dfrac{\partial f}{\partial x_2} dx_2 + \cdots +\dfrac{\partial f}{\partial x_n} dx_n
$$

で与えられる．

$y=f(x)\in {\rm R}^m$でも同様に，全微分は

```math
dy_1 = f_1'(x) = \dfrac{\partial f_1}{\partial x_1} dx_1+ \dfrac{\partial f_1}{\partial x_2} dx_2 + \cdots +\dfrac{\partial f_1}{\partial x_n} dx_n\\
dy_2 =f_2'(x) = \dfrac{\partial f_2}{\partial x_1} dx_1+ \dfrac{\partial f_2}{\partial x_2} dx_2 + \cdots +\dfrac{\partial f_2}{\partial x_n} dx_n\\
\vdots\\
dy_m =f_m'(x) = \dfrac{\partial f_m}{\partial x_1} dx_1+ \dfrac{\partial f_m}{\partial x_2} dx_2 + \cdots +\dfrac{\partial f_m}{\partial x_n} dx_n
```

で与えられる．

ここでヤコビ行列$J$を

```math
J = \frac{\partial y}{\partial x}= \frac{\partial f}{\partial x}
=\begin{bmatrix}
\dfrac{\partial f_1}{\partial x_1} & \dfrac{\partial f_1}{\partial x_2} & \cdots & \dfrac{\partial f_1}{\partial x_n}\\
\dfrac{\partial f_2}{\partial x_1} & \dfrac{\partial f_2}{\partial x_2} & \cdots & \dfrac{\partial f_2}{\partial x_n}\\
\vdots & \vdots & \ddots & \vdots\\
\dfrac{\partial f_m}{\partial x_1} & \dfrac{\partial f_m}{\partial x_2} & \cdots & \dfrac{\partial f_m}{\partial x_n}\\
\end{bmatrix}
```
とおいたとき，上式は

$$
dy = f'(x) = Jdx
$$

と書ける．

一方，$y=Ax$が成立することから
$$
dy = Adx
$$
も成立する．
したがって，$A=J=\partial y/\partial x$となる．（証明終了）
[Vue.js]computed

<h1>computedはどう使うのか</h1>
```html
//クリックされた回数
    <p>{{num}}</p>
//クリックするたび１増えるボタン
    <button @click ="countUp">+1</button>
    <p>{{lessThanThree}}</p>
    
```

```javascript
//クリックした時に表示される回数。初期値は0
 data:{num: 0},
    computed:{
//クリックが３より上の時と３以下の条件指定　左true:右fauls
       lessThanThree:function(){
         return this.num > 3 ? '3より上' : '3以下'
        }
  },
```
<p>書き方としてはmethodsと同じ</p>

<h1>methodsと書き方が同じなら何故methodsに書かないのか</h1>
<p>理由はその対象以外が書き換えられたときにも一緒に動作してしまうから</p>
<p>computedに記述している場合はその条件が書き換わる瞬間だけプログラムが変わるようにしてくれるらしいです。</p>
<p>二重中括弧に複雑な処理を入れるときは必ずmethodsではなくcomputedに入れる</p>
バズったTwitterの動画、画像を自動収集するWebサイト

## 概要
twitterでバズった動画や画像のツイートをいいね順、リツイート順、日付順で閲覧できるwebサイトを作った
https://twipop-app.tontonton.work/

## 使用した技術
* サーバサイド
Rails

* フロントエンド
React

* API
公式TwitterAPI

* DB
firebase Realtime Database

* ホスティング
Heroku

* ssl
cloud flare 

## 全体像
こんな感じ
![export_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361500/ec5faca8-3de4-2c46-0634-a1bb83d7a539.png)


## なぜRails
サーバサイドはRailsしか扱ったことがないから。Rails以外の技術を勉強する時間が勿体無い。

## なぜReact
前々からSPAに興味がありReactの勉強を進めていた。Vueはちょっと勉強して挫折。
ページの部分更新するにもstate更新するだけで実現できてお手軽なのが魅力的。
gemはreact-rails

[Reactを知る前の貧弱な僕]
ビューにpartialファイル用意して、コントローラで専用のインスタンス変数用意して:sweat_drops:
あとpartialを返すようにして、それとそれとjavascript側でDOM更新してっ:dizzy_face:ｱﾜﾜﾜ

⬇️

[Reactを知った頑強な僕]
「フンッ:muscle_tone4:」取得データでstate更新
シャッ(華麗にページ更新される音)


## なぜRealtime Database
なるべく無料DBを使用したいと思っていた。
最初はFireBaseのCloud Fire Storeを使おうとしていた。

### Cloud Fire Storeについて

CRUDについて無料プランは以下の制限がある。
書き込み 2 万/日
読み取り 5 万/日
削除     2 万/日

nosqlは初めて扱った。RDBしか使ったことのない僕は最初

「1日でこんなにselectしないでしょw」
とか見当違いのことを思っていた。

実装を進めるにつれ、読み取り数の使用状況がおかしいことに気づいた。

>![ラッコ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361500/0db3d98f-c927-df8a-faf1-429ecf47b759.jpeg)

「うわ・・・私の読み取り数多すぎ？」

どうやらこの制限はデータ件数のことみたいだった。データ件数自体は1万も2万も扱うつもりはないが、読み取るたびに累積していくので断念。

### RealTime DataBaseについて
RealTime DataBaseはCRUDの制限はない。容量は1GB。
gemはfirebase。
今の所問題なく動いているが以下のようなデメリットもある。

* 日本語の関連記事があまりない
* データの降順機能がない。今の所、昇順で取得したリストを自力で降順するしかない
* FireBase自体はCloud FireStoreを推奨している

参考
[FireBase公式料金プラン](https://firebase.google.com/pricing?hl=ja)

## なぜHeroku
アクセス数などの制限が無くRailsと親和性の高いHerokuを使用することにした。

最初はFireBaseでホスティングしようと思っていたけど、Twitter APIを使ってデータ取得するのにNode.jsが必要なので断念。
FireBaseでNode.js利用するときはCloud Functionを使う必要がある。
Cloud FunctionはBlazeプランに変えないと使用できない。
プランを変えたからといってすぐ課金されるわけではないけど、なるべく慎重にいきたい。

## まとめ
DBの差し替えとかHeroku環境変数の設定とか、結構つまづいたことが多かったが学びも多かった。
今後も少しずつ改良を加えていきたい
KaTeX@VSCode の日本語での分数に上下の余白を入れる

# はじめに

VSCode で [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) や [Markdown Preview Enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/) を使って数式をプレビューする際は KaTeX が使われますが、英数字ではなく日本語で分数（`frac`）を表現すると括線との隙間がほとんどない状態で表現されます。特にインライン数式ではそれが顕著です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/8981974d-edb9-0a70-0f03-82ed5b7af6d3.png)
とりあえず上2つについて、強引に見た目だけでも余白を入れます。

# やりかた

なるべく幅が小さい文字 `|` を使って上下に余白を入れつつ `\phantom` で見えなくします。

* **分子**：`|` を入れるだけで下側に余白が生じるので、バランスを取って両脇に入れます。
* **分母**：どの文字を入れても上側に余白は生じないので、`\vec|` としてベクトルの矢印も入れて強引に余白を入れます。分子と同様に両脇に入れますが、矢印の有無で幅は変わらないため片方はただの `|` で良いです。

|| \frac{分子}{分母} | \frac{&#124;分子&#124;}{&#124;分母\vec&#124;} | \frac{\phantom&#124;分子\phantom&#124;}{\phantom&#124;分母\phantom{\vec&#124;}} |
|---|:-:|:-:|:-:|
|1|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/ff68126f-f20f-ea42-f04c-b04a49872a7f.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/298af99c-8a86-5d0a-1b23-a319c6bdb2b2.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/dc759f42-a1cf-cf16-93fc-5b15bf38ebd4.png)|
|2|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/44611565-760e-57ab-89d1-265ac50369ae.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/0ec5f2e5-bcb8-4e24-f306-d083a0809137.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256480/7d7e3e31-c7bb-fd4a-a95c-115af7b70035.png)|

# おわりに

あまり必要なシーンはないでしょうし、もっと環境設定的な話もあるかも知れませんが、手軽なその場しのぎとしては使えると思います。

# 参考

* [LaTeX 数式の縦/横の調整](http://www.math.kobe-u.ac.jp/HOME/kodama/tips-latex-math-margin.html)
【React/Vue】ReactReduxとVuex 概念の互換性

#記事について
この記事は、駆け出しエンジニアの僕がVue→Reactの翻訳学習の際に、より理解を深めるために綴っている記事です。
Vueについてはあまり学習しておらず、Reactに重点を置いて学習をしています。

拙い部分があるかもしれませんが、ご指摘・ご意見がある際は是非お願いします。

#概念
ReactReduxとVuexでの基本的な概念

ReactRedux: __State__ / __ActionCreator__ / __Action__ / __Reducer__ / __Store__
Vuex: __State__ / __Getters__ / __Mutations__ / __Actions__ / __Store__

それぞれの互換性について理解を深めて、React ⇆ Vueの翻訳に役立てる

##Reduxの概念について
1. State:　データを保持する領域
　
2. ActionCreator:　Actionオブジェクトを生成する関数

3. Action(object):　Actionの情報をもとにステート更新を行う。Storeの「dispatchメソッド」でStoreにActionオブジェクトを渡す
　　※thunkなどで非同期を実装する際にはobjではなく関数をStoreに渡す

4. Reducer:　Actionと現在のステート情報をもとに新しいステートを生成して、Storeに保持する

5. Store:　ステートをもつ。store周りのメソッドをもつ。

##Vueの概念について
1. State:　データを保持する領域
　
2. Getters:　ステートに加工したデータを返す機能（同期処理only）

3. Mutations:　ステートの変更を行う機能

4. Actions:　内部でMutationを行いStateを更新する機能（同期処理&非同期処理）

5. Store:　1~4を保持するオブジェクト

##互換性
reduxで非同期を実装する場合は、適応したライブラリのインストールが必要

|ReactRedux(x) / Vuex（y） | State | ActionCreator | Action | Reducer | Store |
|:-:|:-:|:-:|:-:|:-:|:-:|
|  State |  ほぼ同義 |  x |  x |  x |  x |
|  Getters | x  | x  |  x |  x |  x |
|  Mutations | x  | x  |  x | 同様にstateの値を更新する  | x  |
| Actions  | x  |  非同期のロジックはActionCreatorに記述される| Actionは非同期の関数にもなる |   x| x  |
|  Store |  x |  x |  x |  x | stateを保持するが、異なる部分もある |

##まとめ
互換性について記事を書きましたが、VueとReactは似ている部分もありますが別のフレームワークなので、例としてReactにはGettersがなかったりします。
翻訳作業時に足りない機能などは、同等のものを自作などする必要があります。
urllib3.exceptions.LocationParseError: Failed to parse への対策

`pip`でインストールしたコマンドなど、Pythonで書かれたコードで起こる問題。どうやらURLをパースするのに失敗しているらしい。
どうにも局所的でかつユーザ側の環境による問題なのだが、それ故か対処法がまとまっていなかったのでメモしておく。

### 経緯
atcoder-tools(競プロ用のツール)を使っていたところ、11月のはじめあたりに突然正しく動作しなくなった。ツールにアプデがあったわけでは無い、というかそもそも自分ではupdateを挟んでいないのでupdateで動作しなくなったというわけではなさそう。本当に心当たりがないのでよくわからない。

エラーを見ると

```python
  File "/usr/lib/python3/dist-packages/requests/models.py", line 380, in prepare_url
    scheme, auth, host, port, path, query, fragment = parse_url(url)
  File "/usr/lib/python3/dist-packages/urllib3/util/url.py", line 392, in parse_url
    return six.raise_from(LocationParseError(source_url), None)
  File "<string>", line 2, in raise_from
    urllib3.exceptions.LocationParseError
```
という感じのログがある。問題があるのは`six`あるいは`urllib3`モジュールだろうと見当をつけて調べてみる。


### 対処法1

```bash
$ pip3 install six==1.15.0
```
`six`モジュールのバージョンが古く、不具合を起こしている可能性がある。
`module 'six' has no attribute 'ensure_str'`みたいな感じのログが出てる人はまあこれだろう。`six`に`ensure_str`が追加されるのは`1.15.0`以降なので以上のコマンドとなる。
実際これで改善された人もいるらしい。ただ、自分はこれでは直らなかった。これをしても変わらんよって人は以下の対処法2を試してみるといいかもしれない。


### 対処法2

```bash
$ pip3 insatll --upgrade urllib3
```
これまた`urllib3`のバージョンを最新に引き上げている。
自分はこれで正常に動作するようになったが、これをすれば直るとも言い切れない。


### まとめ
かなりくだらない理由だったので悲しくなった。途中まで通常に動作していたのに、どこかのタイミングでバージョンダウングレードが挟まってしまったということだろうか。途中でコマンドの install,uninstall などを行ったが、そのせいかも？わからん
Macのターミナル上でTab補完を有効にしたら、Git操作が爆速になった話

エンジニアの先輩から教わったスキルハックです。

ターミナル上で、pushする際に、```git branch```でブランチ名確認して、
「```feature/fix-password-form```いちいち打つのめんどくさいな〜。」って思っていました。

Tab補完ができれば、```fe```くらいのタイミングでもう入力できます。
楽ちん楽ちん。

コミットする際も地味にめんどくさい。
```git commit -m "xxxxxxxx"```

**g → tab　→　c → tab → "xxxxxx"**
てな感じでスイスイ行きます。

Sourcetreeをaddする時くらいしか使わない自分からするとだいぶありがたい。

**だまされたと思ってやってみてください。マジで捗ります。**

#導入方法


**macOS Catalina**からMacのデフォルトのシェルが**zsh**になったそうです。
それまでは、bashだったそう。
シェルについて詳しくないですが、以下の記事がわかりやすくまとまってました。
[bashとzshの違い。bashからの乗り換えで気をつけるべき16の事柄](https://kanasys.com/tech/803)

##zsh-completionsをインストール

https://formulae.brew.sh/formula/zsh-completions
上記サイトの通り、コマンドを叩く
**-[注意]-**  就業中や勉強中の方はビール飲みたくなるので、見ないほうがいい。


```
brew install zsh-completions
```

##設定を有効にするために~/.zshrcに追記

```
 if type brew &>/dev/null; then
     FPATH=$(brew --prefix)/share/zsh-completions:$FPATH

     autoload -Uz compinit
     compinit
 fi
```

これだけです。
ちなみに自身は```.zshrc```ファイルがなかったので

```
touch .zshrc 
```

でファイルを作ってから``vim``を使って追記しました。
エディタはなんでもいいと思います。

```
vim .zshrc
```
ターミナルを開き直すのは面倒なので以下のコマンドで再読み込み

```
source .zshrc 
```

**すると、Tab補完が有効になっているはずです。**
これで今日から、Tab補完なしで生きれない体になったぜ！！
マジでgitの操作が捗ります。多分1.8倍くらい。ありがたや。アディオス。

###参考
[Homebrew Formulae](https://formulae.brew.sh/formula/zsh-completions)
[zsh-users/zsh-completions](https://github.com/zsh-users/zsh-completions)
Steinを使ってSpreadSheetのデータをとるときのメモ

#準備
１．Steinにアカウント登録（Googleアカウント）　このとき、SpreadSheetへのアクセス許可がなされる。
２．SteinのSpreadSheetのURLを貼り付けるところがあるので、扱いたいSheetのURLをコピペ　どのファイルなのかを指定する目的
３．Stein上に表示されるAPIのURLをコピー　Steinを通してSpreadSheetにアクセスされる。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/fb71f1df-09b1-d8ce-138b-b9c75e3787eb.png)
４．Node.js（今回使う言語）上にコピペ

```javascript
// Read Sheet1
const SteinStore = require("stein-js-client");
const store = new SteinStore(
  "https://api.steinhq.com/v1/storages/xxxxxxxxxxxxxxx"
);

store.read("Sheet1", { limit: 1, offset: 2 }).then(data => {
  console.log(data);
});
```


#参考URL
[Steinのサイト](https://docs.steinhq.com/read-data)
Laravel+jQueryでAjax通信してみる

自分の中でなんと無くとっつきにくさを感じてたjQueryですが、コントローラーとJS間の値の受け渡しについて自分なりにまとめてみました。

## Ajaxの基本の書き方

```js

$(function(){
  $.ajax({
    type: "get", //HTTP通信の種類
    url:'/home', //通信したいURL
    dataType: 'json'
  })
  //通信が成功したとき
  .done((res)=>{
    console.log(res.message)
  })
  //通信が失敗したとき
  .fail((error)=>{
    console.log(error.statusText)
  })
});
```

`$(function)`で、画面が読み込まれたタイミングで発火させることができる(vueでいうmounted的なやつ??)

## 関数の書き方

```js

$('セレクタ').イベント名(function(){
  //イベント発生時に実行したい処理
});
```

## 【GETメソッド】 DBの値を取得してHTMLに表示する

```js
//ボタンを押したタイミングで発火する
$("#bt").click(function () {
  $.ajax({
    type: "get", //HTTP通信の種類
    url: "/getuser",
    dataType: "json",
  })
    //通信が成功したとき
    .done((res) => { // resの部分にコントローラーから返ってきた値 $users が入る
      $.each(res, function (index, value) {
        html = `
                      <tr class="user-list">
                          <td class="col-xs-2">ユーザー名：${value.name}</td>
                      </tr>
         `;
      $(".user-table").append(html); //できあがったテンプレートを user-tableクラスの中に追加
      });
    })
    //通信が失敗したとき
    .fail((error) => {
      console.log(error.statusText);
    });
});
```

- $("#要素名")で、idを指定することができる。
- $(".要素名")で、classを指定することができる。

サーバー側の処理で、users テーブルの値を全て取ってきて、$usersに代入してjsonとして返す。

```php
   public function getUser()
  {
    $users = User::select('name','email')->get();
    return $users;
  }
```

## 【POSTメソッド】
```js
$("#bt2").click(function () {
  $.ajaxSetup({
  headers: {
    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
  },
});
  $.ajax({
    //POST通信
    type: "post",
    //ここでデータの送信先URLを指定します。
    url: "/postgmail",
    dataType: "json",
    data: {
      uid: 100,
      subject: "テストタイトル",
      from: "テストfrom",
      body: "テストbody",
    },

  })
    //通信が成功したとき
    .then((res) => {
      console.log(res);
    })
    //通信が失敗したとき
    .fail((error) => {
      console.log(error.statusText);
    });
});
```

```php
// コントローラー側
 public function postGmail(Request $request)
  {
    $result = $request->all();
    return $result;
  }
```

```php
// ルーティング
Route::post('/postgmail', 'HomeController@postGmail');
```
console.log(res)で値が確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/cb37ed80-8275-c5ad-ca96-e9867b611698.png)

### AjaxでPOSTした値をDBに保存する

AjaxでPOSTした値をDBに保存します。
上記のAjaxの記述はそのままで、コントローラー側を編集します。

```php
// 一番上の useの部分に追記
use App\Gmail;
=== 省略 ===
  public function postGmail(Request $request)
  {
    $gmail = new Gmail();
    $gmail->uid = $request->uid;
    $gmail->subject = $request->subject;
    $gmail->from = $request->from;
    $gmail->body = $request->body;

    $gmail->save();
  }
```

値が保存されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/47fe9bfb-cd31-958d-e486-f7b49afe5fbb.png)
ffmpeg4.3.1をUbuntuでWindows用にビルドする

忘れないようにメモします。

私はとりあえず動けばOKという感じでビルドするので警告とか無視していきます。
**この記事の手順でビルドして問題が起きても私は責任を負いません。自己責任でお願いします。**

専用のツールが用意されているのでとっても楽です。

# Ubuntuの設定
今回はUbuntu 20.4 jaを使用しました。
仮想化ソフトはVMware Workstation 15 Playerを使用しました。
WSLでも動きます。

# ツールのダウンロード
ディレクトリはhomeディレクトリ以下ならどこでもいいです。

```bash
git clone https://github.com/rdp/ffmpeg-windows-build-helpers.git
cd ffmpeg-windows-build-helpers
```

# 必要パッケージのダウンロード
とりあえず実行します。

```bash
./cross_compile_ffmpeg.sh
```
するとログの中にsudo apt install 〇〇みたいなコマンドが出るのでそれをコピーして実行します。

```bash
sudo apt-get install subversion ragel curl texinfo g++ bison flex cvs yasm automake libtool autoconf gcc cmake git make pkg-config zlib1g-dev mercurial unzip pax nasm gperf autogen bzip2 autoconf-archive p7zip-full clang python3 python3-pip python3-setuptools python3-wheel ninja-build -y
```
Ubuntu 18.04なら

```bash
sudo apt install python3-distutils -y
```
Ubuntu 20.04なら

```bash
sudo apt install python-is-python3 -y
```
が必要です。

次にその他に必要なものをインストールします。

```bash
sudo apt install python3-pip -y
sudo pip3 install ninja meson
```

# ffmpegのビルド

```bash
./cross_compile_ffmpeg.sh --build-ffmpeg-shared=y --build-intel-qsv=y --build-amd-amf=y --ffmpeg-git-checkout-version=n4.3.1 --enable-gpl=n
```
私はこんな感じで実行しました。
数時間かかります。
ターゲットには32bit、64bit一緒にビルド、もしくは片方だけを選びましょう。

dllがほしかったので--build-ffmpeg-shared=yでdllを生成するようにしました。不要であれば--build-ffmpeg-static=yです。

--build-intel-qsv=y --build-amd-amf=y
ここでIntel QSV、AMD amfをオプションで有効にします。
NVENC、NVDECは自動で有効になるようです。

--enable-gpl=nにするとlibx264が無効になります。--enable-gpl=yだとlibx264がインストールされます。
どうやら標準でOpenH264が使われるようです。

--ffmpeg-git-checkout-version=n4.3.1でffmpegのバージョンを指定します。指定しなかったら最新のファイルを落としてくるようです。
こちらのツールは最新版用に作られているようなので、最新版を指定しないとエラーが出る可能性があります。

その他詳しい設定についてはshファイルの中を覗くのがいいかもしれません。
詳細に変更したいなら直接書き換えたほうがいいと思います。

# ビルド完了ログ
```
Done! You will find 32-bit shared binaries in /home/kusaanko/ffmpeg-windows-build-helpers/sandbox/win32/ffmpeg_git_lgpl_n4.3.1_shared/bin

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz (906E9),ASM,AES-NI)

Scanning the drive:
9 folders, 145 files, 82126029 bytes (79 MiB)

Creating archive: /home/kusaanko/ffmpeg-windows-build-helpers/sandbox/redist/ffmpeg-N-98189-g6b6b9e593d-win32-shared.7z

Items to compress: 154

                                       
Files read from disk: 145
Archive size: 27850375 bytes (27 MiB)
Everything is Ok
```

# 完成したファイルの場所
私の場合だとここにありました。
ffmpeg-windows-build-helpers/sandbox/win64/ffmpeg_git_lgpl_n4.3.1_shared/bin/
最後のログに出てるのでそこを読めばわかります。

# エラー
## ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl.
libaribb24の最新バージョンが1.0.3なのに1.0.3より新しいバージョンを要求されます。
LGPLでのビルドを諦めるか、同梱を諦めます。
同梱を諦めるコマンドがこちら

```bash
sed -i -e 's/--enable-libaribb24 //' ./cross_compile_ffmpeg.sh
sed -i -e 's/--enable-libx264 --enable-libx265/--enable-libx264 --enable-libx265 --enable-libaribb24/' ./cross_compile_ffmpeg.sh
```

# 最後に
ffmpegを使うときはライセンスに気をつけましょう。ライセンス料とか色々考えなければなりません。
Ruby AtCoder向けVSCode設定 __debug__(ruby 2.7版)

# はじめに
以前投稿しました、[Ruby AtCoder向けVSCode設定](https://qiita.com/superrino130/items/b9a7bedd9737932ddfc9) では、`msys2`を使用していましたが、最近は`rubyinstaller`を使用しています。

その rubyinstaller で`VSCode`のデバッグ環境が動作するようになりましたので、記録として残したいと思います。
# 構築順
手前味噌ですが、[Ruby AtCoder向けVSCode設定](https://qiita.com/superrino130/items/b9a7bedd9737932ddfc9) を合わせて参照願います
**VSCode インストール**
**Ruby インストール**
今回は、`rubyinstaller-devkit-2.7.2-1-x64.exe`を使用しております。
**Gem インストール**

```Gemfile.rb
gem "ruby-debug-ide"
gem "debase"
gem "rcodetools"
```
**VSCode settings.json 設定例**

```settings.json
{
    "ruby.rctComplete.commandPath": "C:\\Users\\user\\...\\rct-complete.bat"
}
```
`rct-complete.bat` のパスを通します

**VSCode launch.json 設定例**

```launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Local File",
            "type": "Ruby",
            "request": "launch",
            "program": "${workspaceRoot}/main.rb",
            "pathToRDebugIDE": "C:\\Users\\user\\...\\rdebug-ide.bat",
            "pathToBundler": "C:\\Ruby27-x64\\bin\\bundle.bat",
            "useBundler": true,
            "stopOnEntry": true,
            "args": [
                "data.txt"
            ]
        },
    ]
}
```
`rdebug-ide.bat` のパスを通します。
`bundler`を使用しています。

**data.txt**

```data.txt
2 3
```
`main.rb`と同じディレクトリに`data.txt`を置きます。

では、`F5`キーを押下
![20201118a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/2d49c874-5c56-d283-8d51-762bbaa301bb.png)
![20201118b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/d6630479-6fff-7202-74b3-b11655d1472b.png)
変数表示もバッチリ
# まとめ
+ Windows10 の VSCode の Ruby でデバッグができるようになった

参照したサイト
*[VSCodeでrbenv環境のrubyのデバッグ、コードコンプリートができない](https://qiita.com/jyami/items/299fe5f74b417ef70e3a)*
*[Ruby AtCoder向けVSCode設定](https://qiita.com/superrino130/items/b9a7bedd9737932ddfc9)*
# 追記(2022-03-09)
```
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x64-mingw32]

An error occurred while installing debase (0.2.4.1), and Bundler cannot
continue.
```
Ruby3.0 及び 3.1 ですと debase のインストールに失敗するようですので、AtCoder の Ruby2.7 向けの記事になります。
NavMeshAgentを使いたいが、AI用のオブジェクトが空中からスタートするからエラーになってしまうとき

# この記事でできること
- とりいそぎ、空中からスタートしなくてもよいのであれば、AI用のオブジェクトがエラーを出さずにNavMeshAgentとして機能できるようになる。

# 前提
- あえて空中からスタートしなくても良い場合。

# やり方
- 地面に近い場所にtransform.positionを変更する。

## 「地面に近い」場所が分からない場合
- 実行後、AI用のオブジェクトは地面に接しているはずなので、そこでコピーコンポーネントを行う。
- 実行を終了して、AI用のオブジェクトのtrnasformコンポーネントで、ペーストコンポーネントバリューを行う。
awkで特定の列を抽出

# やりたいこと
- 任意のファイルから特定の列を出力させたい。

# commannd
- あるログファイルの中から`Kubernetes`という文字だけ抽出するサンプル。

```bash
$ cat test
[2020-11-18 04:18:17 DEBUG] [__init__:66] Using Kubernetes context: default
$ cat test | awk -F" " '{print $6}'
Kubernetes
```
- 空白区切りじゃなくカンマ区切りの場合は以下のように指定する。

```bash
$ cat test | awk -F"," '{print $6}'
```
Jenkinsのメール通知設定で、SendGridのAPI認証を設定する

SendGridから、[2FAの有効化とAPI認証への切替をするよう通知](https://sendgrid.com/docs/for-developers/sending-email/upgrade-your-authentication-method-to-api-keys/?mc=email&mcd=2FAexistingcustomers&cvosrc=email.nurture.2FAexistingcustomers&utm_medium=email&utm_source=nurture&utm_campaign=2FAexistingcustomers) がありました。

Jenkinsのメール通知設定でも、API認証を使ってSendGridへの接続が可能だったので本記事でまとめておきます。ポイントはユーザ名を `apikey` とするところです。

TLSでの接続設定：

- SMTPサーバー：`smtp.sendgrid.net`
- ユーザー名：`apikey`
- パスワード：SendGridで発行したAPIキー
- `SSL` にチェックを入れない
- `Use TLS` にチェックを入れる
- SMTPポート：587 (25または2525でも可能ですが、587が推奨設定)

その他の項目は環境に合わせて設定して下さい。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/4edb012f-d823-a23d-8a62-f9a95251204d.png)|
|:-:|

Jenkinsのバージョンが少し古いと `Use TLS` のチェックが表示されない場合もあるようです。その場合のSSL接続設定は以下になります：

- SMTPサーバー：`smtp.sendgrid.net`
- ユーザー名：`apikey`
- パスワード：SendGridで発行したAPIキー
- `SSL` にチェックを入れる
- SMTPポート：465

その他の項目は環境に合わせて設定して下さい。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/d3a9df16-15be-adae-0f23-4fe2e5c203ae.png)|
|:-:|

# 参考情報

- [SendGrid : Upgrade your authentication method to API keys](https://sendgrid.com/docs/for-developers/sending-email/upgrade-your-authentication-method-to-api-keys/?mc=email&mcd=2FAexistingcustomers&cvosrc=email.nurture.2FAexistingcustomers&utm_medium=email&utm_source=nurture&utm_campaign=2FAexistingcustomers)
- [SendGrid : SMTP接続情報](https://support.sendgrid.kke.co.jp/hc/ja/articles/204187885-SMTP%E3%81%AE%E6%8E%A5%E7%B6%9A%E6%83%85%E5%A0%B1%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-)
Git エイリアスのタブ補完

皆さん、Git コマンドをタブ補完していますか？

まだだよ、って方は以下のエントリがオススメです。

- [「Git補完をしらない」「git statusを1日100回は使う」そんなあなたに朗報【git-completionとgit-prompt】 - Qiita](https://qiita.com/varmil/items/9b0aeafa85975474e9b6)

----

では、タブ補完できるようになったところで「Git のエイリアス」の話に戻ります。

> Git のエイリアスを設定して、せっかく短いコマンドで実行できるようになったのに、タブ補完が効かなくて逆に面倒くさい

![komatta_man2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31613/af2f9579-e9db-6b21-3850-db6dd6a7386b.png)

というようなことはないでしょうか？ このエントリはそんな悩みを解決する助けになると思います。

さて、一言で「Git のエイリアス」と言っても、以下ふたつの意味があります。

- `alias gco='git checkout'` と定義するもの
- `git config alias.co checkout` と定義するもの

多くの人は前者の `gco` コマンドをタブ補完したいようで、こちらの情報はググるとたくさん見つかりました。今回私がやりたかったのは後者で、こちらは全然見つけられなかったので、前者と合わせてここにまとめておきます。

### alias コマンドで作成したエイリアスのタブ補完

以下のように行います。

```shell-session
$ alias gco='git checkout'
$ __git_complete gco _git_branch
$ alias g='git'
$ __git_complete g __git_main
$
```

`git-completion.bash` 内で `__git_complete` も `_git_branch` も `__git_main` も定義されていて、読み込んだ後であれば使用できます。どのコマンドにどの関数を使用すればよいか、は `git-completion.bash` を眺めればなんとなくわかるので、後は試してみるだけです。

### git config alias.* コマンドで作成したエイリアスのタブ補完

以下のように行います[^1]。

```bash
__git_my_main() {
  if [ ${COMP_CWORD} = 2 -a "${COMP_WORDS[1]}" = "co" ]; then
    _git_branch
  else
    __git_main
  fi
}
__git_complete git __git_my_main
```

`git-completion.bash` を読み込むと、この内部で `__git_complete git __git_my_main` を実行しており、`git` コマンドに対して `__git_main` 関数を登録していますが、これを自分で定義した `__git_my_main` に置き換えます。

`__git_my_main` 内の `COMP_CWORD` では入力が確定した引数の数、`COMP_WORDS` では入力途中を含む引数の内容が配列で得られるため、これらを参照して適切な補完を実装すれば完成です[^2]。

[^1]: 今回のような既存のサブコマンドの置き換えであれば、実際は何もしなくても補完は効きますが、簡単のためこの例で説明します
[^2]: bash 以外の方は使用しているシェルに読み替えてください
GitHub ActionsでプルリクエストのURLを取得する方法

# 結論

```.yml
${{ github.event.pull_request.html_url }}
```
で取れる

```sample.yml
name: Show Pull Request Event

on:
  pull_request:
    branches:
      - master

jobs:
  show:
    runs-on: ubuntu-latest
    steps:
      - name: Run echo
        run: echo ${{ github.event.pull_request.html_url }}
```

# ドキュメント

[Webhook events and payloads](https://docs.github.com/ja/free-pro-team@latest/developers/webhooks-and-events/webhook-events-and-payloads#pull_request)

![スクリーンショット_2020-11-18_18_11_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/ceeabd9d-0bd3-2b16-3379-1eb7d4b3468a.png)

# まとめ
slackとかに通知するときにつけておくと、飛べるから便利かも
LineSDKSwiftでonly available in iOS 10.0 or newerのエラーが出た時の解決

自分の備忘として記載します。

#現象
xcodeをアップデートしたら、LinSDKSwiftがコンパイルエラーになりました。

#エラー内容
定数などがonly available in iOS 10.0 or newerになる

#回避方法
podsのdeployinfoのiosが10.0未満になっていないか確認して、適切なバージョンを指定します。
ECCUBE4系の、受注一覧で商品コードで検索する。

自分用のメモ程度です。
ECCUBE4系を利用しているのですが、商品コードで検索したいとの要望があったので実施。

フォームを増やしたりするのは面倒なので、現状の詳細検索→購入商品名を商品コードにも対応させる方法で進めました。

変更箇所は１箇所のみで、
/src/Eccube/Repository/OrderRepository.php
に　 OR oi.product_code LIKE :buy_product_nameを追加すれば完了です。

```php
// buy_product_name
if (isset($searchData['buy_product_name']) && StringUtil::isNotBlank($searchData['buy_product_name'])) {
    $qb
        ->andWhere('oi.product_name LIKE :buy_product_name OR oi.product_code LIKE :buy_product_name')//ここに追加
        ->setParameter('buy_product_name', '%'.$searchData['buy_product_name'].'%');
}
```
Note Book : Build OpenCV v4.5.0 backend Openvino


###Install Openvino

```shell:openvino
# bin ver install

cd /tmp

wget https://apt.repos.intel.com/openvino/2021/GPG-PUB-KEY-INTEL-OPENVINO-2021

sudo apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2021
sudo apt-key list
sudo rm -rf GPG-PUB-KEY-INTEL-OPENVINO-2021
sudo apt -yV update
sudo echo "deb https://apt.repos.intel.com/openvino/2021 all main" | sudo tee /etc/apt/sources.list.d/intel-openvino-2021.list

sudo apt-get -yV install intel-openvino-dev-ubuntu20-2021.1.110

```

###Build OpenCV

```shell:opencv
# looks like cd /yor/oath/opencv/build

export InferenceEngine_DIR=/opt/intel/openvino_2021/inference_engine/share
export NGRAPH_DIR=/opt/intel/openvino_2021/deployment_tools/ngraph/cmake

cmake \
-DInferenceEngine_DIR=${InferenceEngine_DIR}  \
-DWITH_INF_ENGINE=ON \
-Dngraph_DIR=${NGRAPH_DIR} \
-DENABLE_CXX11=ON \
-DWITH_NGRAPH=ON \
..

```
Vue.jsを学ぶ #1

Vue.jsを学習するにあたり、言語化するため記事を作成しました。

# ディレクティブ
「v」から始まる属性をディレクティブと呼ぶ。主にデータバインディングを行うために使用される。

データバインディング・・・データと描画を同期させる仕組み。データに変化があれば、自動的にDOMを更新させる。例としてE-mail入力欄に入力した時に確認として入力した文字列を表示させて確認させる仕組みなど。

```ruby:filename.rb
① <div key="id"></div
② <div v-bind:key="id"></div>
```
①の場合は文字列、②の場合はv-bindであるためJavaScriptの変数となる。

v-bind=ディレクティブ　:value=引数　.sync = "message"=値
引数や値はオプションで付き、②の場合は:key引数のオプションが付属している。

# コンポーネント
 機能ごとにJavaScript, HTML, CSSを１セットとして他機能とは分離させる仕組み。
 つまり上記ファイルをよりスマートに扱うことができる。
 例)header...HTML+CSS+JavaScript, main...HTML+CSS+JS, footer...HTML+CSS+JS
 このように、ヘッダー・メイン・フッターを独立したコンポーネントとすることで、ファイル管理が容易になる。

###2に続きます。
IDWR速報データのインフルエンザ定点当たり報告数・都道府県別をスクレイピング

+ [厚生労働省のインフルエンザの発生状況についてのPDFをデータラングリング](https://qiita.com/barobaro/items/88bb9cdcbf080382c27f)
+ [厚生労働省のインフルエンザの発生状況についてのPDFをデータラングリング（pdfplumber）](https://qiita.com/barobaro/items/29059c83b2cb11600627)

[国立感染症研究所](https://www.niid.go.jp/niid/ja/data.html)に同じデータのCSVがあるのでスクレイピング

```python
from urllib.parse import urljoin

import requests
from bs4 import BeautifulSoup

url = "https://www.niid.go.jp/niid/ja/data.html"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}

r = requests.get(url, headers=headers)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

tag = soup.select_one(
    'div.leading-0 > table > tbody > tr > td > p.body1 > a[href$="-teiten.csv"]'
)

link = urljoin(url, tag.get("href"))

import pandas as pd

df = pd.read_csv(
    link,
    encoding="cp932",
    skiprows=3,
    index_col=0,
    header=0,
    usecols=[0, 1, 2],
    na_values="-",
)

df1 = df[df.index.notna()]
```
【Vue】this.$nextTick。前の処理完了をまってから指定した処理を実行する。

コードは正しいのに、メソッド実行後の処理の出力結果が狙ったものと違うものになってしまう事象が発生。

`this.$nextThick`を使うことで解消できた。


##発生状況

・クリックイベントで変数を変更する操作。
・対象の変数が、親テンプレートでwatchや、getter、setterの対象となっていた。

クリックイベントで変数を変更したが、他のgetterやsetterでその変数を別の値に代入する処理が行われており、watchで変更を自動検知した時に、**古いデータに戻っていた**。

処理の実行順序が入り組んでしまったことが問題。


<br>
##対処法

処理を意図的に遅らせる`$nextTick`を使用する。

###nextTickとは？

`this.$nextTick(() => { 処理 })`

callback関数を使って、DOMを更新後に指定した処理を実行する処理。

tickとは時計のチクタク音。次のカッチまで待つということ（と思われる）

グローバルに宣言する「Vue.nextTick(() => { })」も同じ処理になる。

＞[Vue公式 nextTick](https://jp.vuejs.org/v2/api/index.html#Vue-nextTick)


###記述例

変数が宣言されていない場合に、親のタグで属性「:xxx.sync」で指定した変数xxxを変更する処理。

```js:
if(xxx != undefined){
        this.$nextTick(() => {
          this.$emit('update:xxxSync', xxx)
        })
      }
```

この変数xxxが他の場所で代入されたり、watchされていて、変更したはずのデータが反映されなかったが、nextTickを使ったことで、変更がきちんと反映された。


<br>

**▼補足**
nextTickは極力使用を避ける。各変数の依存が適切に記述され実行順序がクリアであれば、nextTickを使う必要はない。
qiitaに投稿する方法

新しくorgをつかってqiitaに投稿するときのやり方を忘れた時用にメモがてら残す


# 新しくページを作る


### qiitaからアクセストークンを取得

qiitaのマイページ、アプリケーションから新しくトークンを生成コピー

[org-modeのテキストをqiitaに投稿するgemを作ってみた](https://qiita.com/yamatoken/items/858692178d288c40714d)

上の記事を参考にテンプレを取得

テンプレをemacsで開きqiita\_publicのところをアクセストークンに上書き

これで新しいページは完成


# 中身の編集

大体は[Qiita書き方メモ](https://qiita.com/hiroyuki_hon/items/f2a779bb295fd12646ab)に載ってるがちょっとちがうとこや良く使うものは載せる


### コードの書き方

qiitaでは\`\`\`をつかうみたい

orgでは#+begin\_src rubyで始まり最後に#+end\_srcで終わるらしい

```ruby
print("Hello world")
```

こんな感じruby以外にも使えるっぽい

また、#+begin\_exampleとおわりに#+end\_exampleでもできる

    $ruby HelloWorld.rb
    Hello world　

こんな感じ


# qiitaに投稿

投稿はqiita post [FILE] [private/public/teams]でできる詳しくは[qiita\_orgのコマンドについて](https://qiita.com/yamatoken/items/9314161758e778fd82c0)を参照

これで新しいページ完成！！


# gitにアップする方法

ついでにgitにアップする方法も残す

    > git pull origin main      #gitから自分のPCへファイルをダウンロード
    > git add -A
    > git commit -m 'commit'
    > git push origin main      #自分のPCからgitにアップロード



------
 - **source** ~/grad_members_20f/members/0922tooy/qiita.org
Sessionとcookieをがよくわからないので、できるだけかみ砕いてまとめたよ

#SessionとCookie

Railsチュートリアルでログイン機能の実装まで学習したが、いかんせん【わからない】
本当に分からない。自分が今何をやっているか理解できない。
こういう「分からない事が分からない」のは基礎的な知識が抜け落ちているパターンが多い。

どの基礎を抑えれば理解できるのかわからないが、まずSessionとCookieというこの2つのキーワードがよくわからないので、自分なりにまとめていく。
___
私は現職が医療従事者であり、専門知識の理解は対象（自分　or　他人）が理解できる内容までかみ砕く（対象によって流動食、ペースト食とレベルを変える）必要があると考えている。
このページでの内容はプログラミング学習前の自分レベルでも理解できるように、出来る限りかみ砕いた。内容を簡素にしていくと、認識違いやそもそも間違ってるでという事も起きる。
その場合はご指摘、ご助言いただけるとうれしいです。

___

***※個人的ではあるが、感覚的に理解しやすいようにwebサーバーを「webページ」・ブラウザを「ユーザー」と表現している。***






##webの仕組みから始まる。
webの仕組みは

1. ユーザーがwebページにアクセスする（リクエストする）
2. アクセスしたページが表示される。（レスポンスが返ってくる）

3. 次のページにアクセスすると、①で送られてきたユーザーのリクエストは2つ目に引き継がれない



といった仕組みになっている

`HTTP通信は情報の引継ぎはできないようになっている。
※HTTPの通信には「HTTPリクエスト」と「HTTPレスポンス」の2つに分けられる。
※①がHTTPリクエスト②がHTTPレスポンス
※HTTPリクエストには「httpリクエストライン」「HTTPリクエストヘッダ」「HTTPメッセージボディ」の３つに分かれてる。
※HTTPリクエストヘッダには「ユーザーエージェント名」や「cookie」情報が含まれている`


<strong>情報が引き継がれないなら、webページでよくある、ログインする仕組みとかはどうなっているのか？？？
ここでsessionとcookieという仕組みが登場する。


#Sessionとcookieとは、それらの違い

Sessionとcookieは似ている。一見、動作としては同じように感じる。

違いとしては
`cokkieはユーザー側（ブラウザ）に保存、覚えられる情報に制限あり（サイズ、文字列のみ）、簡単に盗み見られる`

`sessionはサーバー側に保存、覚えられる情報に制限はない、簡単に盗み見られない`


#cookieとは
cookieはユーザー側（ブラウザ）にメモ書きレベルの情報を保存するための仕組み

**cokkieを使ったwebの流れはこうなる。**

1. ユーザーがwebページにアクセスする

2. リクエストされた画面を返す。この時①でユーザーから送られてきた情報を元にwebページはプログラミングで指示された処理をしてユーザーに画面を返す
（例：「あなたはこのサイトに○○回訪問したよ」とか「指示された色に画面の色を変えたよー」とか。この時にcookieというメモ書きも一緒につけている例でいうと「○○回」「○○色」など）

3. webページからついてきたメモをユーザーが保存します。次のページにアクセスする時にこのメモ書きの情報も一緒につけて、webページに要求します。

4. 本来のHTTP通信であれば情報は引き継がれないが、メモ情報がついているのでそのメモ情報を元にユーザーに適した画面が表示される。


***このcookieはユーザー（ブラウザ）が保存しているのでデベロッパーツールで編集や削除ができる。つまりメモの内容を見れるし、書き換えられるし、捨てる事もできる。
そのため、大事な情報はcookieで扱ってはいけない（ログイン情報とか）***

#Sessionとは
Sessionは情報をwebページ側で保存するのでデベロッパーツールで触る事はできない。
つまり安全である。

ただしwebサーバー上で保存しているので、アクセスしてきた人がAさんなのか、Bさんなのか、Cさんなのか識別しないといけない。（これはブラウザが変わっても同様の事が言える）

ユーザー（ブラウザ）とwebページで保存されているsessionを紐づけてあげる必要がある
sessionではそのためだけにcookieを使う。

**sessionの流れは**

1. ユーザーがwebページにアクセスする
2. リクエストされた画面を返す。①でユーザーから送られてきた情報を元にwebページはプログラミングで指示された処理をしてユーザーに画面を返す。そして情報をサーバー側で保持＆Session情報をcookieとしてセットするよう送ってくる。
3. ユーザーはsession情報をセットする。次のページにアクセスする時に、このセッション情報を送信してwebページに要求します。

4. 本来のHTTP通信であれば情報は引き継がれないが、session情報がついているのでその情報を元にユーザーに適した画面が表示される。




#ここまでのまとめ
`・通常HTTPではページ毎に情報を引き継げない
・そのためcookieやsessionを使って情報を継続しないといけない
・sessionとcookieは違いがある
・ログイン機能を実装するにはsessionとcookieを使う必要がある`


#参考リンク
https://wa3.i-3-i.info/word1841.html
https://wa3.i-3-i.info/word1791.html

[Webpicks](https://wepicks.net/itglossary-request/#:~:text=HTTP%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88(%E3%82%A8%E3%82%A4%E3%83%81%E3%83%86%E3%82%A3%E3%83%BC%E3%83%86%E3%82%A3%E3%83%BC%E3%83%94%E3%83%BC%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%80%81HTTP%20Request)%E3%81%A8,%E9%80%81%E4%BF%A1%E8%A6%81%E6%B1%82%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82&text=%E3%80%8CHTTP%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E8%A1%8C%E3%80%8D%E3%81%AB%E3%81%AF,%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
[ドットインストール](https://dotinstall.com/)
[railsチュートリアル](https://railstutorial.jp/)
型の違うReactivePropertyをCombineLatestしたい


# 型の違うReactiveProperty

```CS
private StringReactiveProperty sentence = new StringReactiveProperty(string.Empty);
private BoolReactiveProperty flag = new BoolReactiveProperty(false);
```

どちらかに何かあったときに、両方の値を参照できるようにしたい。

# 普通にはCombineLatestできない

```CS
sentence.CombineLatest(flag).Subscribe((s, f) =>
  {
    // ERR
  }).AddTo(this);
```

# Tupleで合成するといける

```CS
sentence.CombineLatest(flag, Tuple.Create).Subscribe(tuple =>
  {
    var (sentence, flag) = tuple;
    // OK
  }).AddTo(this);
```

# 他
`Zip`, `ZipLatest`はいける
`Merge`, `Amb`は無理

両方の変数が参照できる位置にあるなら、`sentence`と`flag`に同じ処理を`Subscribe`するのが楽でいいのかも。
MetabaseユーザーがLookerを1ヶ月触ってみた所感

## 結論

やっぱLookerすげぇわ。以上。
以下、駄文。

## お前は誰だ？

約2年間、社内で発生する「データ活用関連」の依頼をMetabase上で対応してきた人。
SQLを書かなかった日はないんじゃないか、と言えるぐらいにはSQLを書いてきた。


## Metabase運用で起きていた問題

### オレオレ指標の蔓延

お世辞にもデータ構造が綺麗とは言えないため、基本的にSQLを書いて、ネイティブクエリ機能(DBに対してSQLを投げれるやつ)を通して抽出→可視化する流れを取っていた。
そのため、同じKPIでもSQLを書く人によって違う数字が出力されるというオレオレ指標が蔓延していた。

### リアルタイム性の欠如

データ分析は往々にして「今知りたい」というニーズが存在する。
特にアドホック分析はそのニーズが強い。
にも関わらず、SQLの作成工数(+目的の確認なども含む)が間に存在するため、データ抽出依頼をしてから結果を受け取るまでに数日かかることも。
その頃には、依頼したデータが不要になっているケースもあった。(泣いた)

### カオス

「xxx件数(PC・スマホ合算)」「xxx件数(oooエリア抜き)」「xxx件数(ooo日ベース集計)」など、似た名前のデータが大量に存在していた。
大量にあるが故に、既に存在するデータかどうかも判断がつかず、「もういいや、新しく作ったほうが早いわ」となり、ひたすらに増加し続けていた。


## Lookerパイセンまじパネェ

普段データを触るメンバーに、初めてLookerを展開した時のあのキラキラした笑顔が今でも忘れられない。
「これこれ、こういうのが欲しかったんだよ！」という心の声さえ聞こえてきた。(というか隣の人が言ってた)

各々が好きな時に好きなデータを出せる状態になったため、「リアルタイム性の欠如」の問題が解決。
また、裏側でLookMLによるデータ定義を行っているため、「オレオレ指標の蔓延」の問題も解決。
「カオス」に関しては、まだメンバーが使い倒しきれていない面もあり、なんとも言えない状態。
ただ、アドホック分析をするのに一々「保存」という行為をしなくて済むため、確実にBIツール上に保存されているデータの数は減るだろう。


## 2年間データ活用の依頼対応をしてきた人間から見たLookerの良い点・悪い点

### 良い点

なんと言ってもLookMLの存在だ。
Lookerを採用したいと思える最たる理由がこれ。
エンジニアリング要素を要求されはするが、直感的に理解できる構造になっているため、ある程度書き続ければ自然と理解できるレベルの難易度でもある。
アナリストから「この数字ってどんなロジックになっているんですか？」と相談を受け、SQLをイチから読み解くという工数も減らせるだろう。

後はExploreの使いやすさ。
ちょっとした会話の中で仮説や疑問が生まれることはよくある。
その際、その場でデータを抽出して事実を確認できることで意思決定までの時間を短縮でき、最終的には事業スピードの加速に繋げられる。
UI/UXもシンプルでわかりやすいため、数分説明しただけでみな一様に理解して分析していた。
(あと、欠損している日付を埋めてくれるのも地味に感動した)

### 悪い点

機能面に対する不満はない。
強いて言うなら価格だろう。
アカウント課金制で、イニシャルコストが12アカウントで定価600万円/年と聞いた。(2020年11月18日現在)
更にアカウントが足りない場合は、必要な権限に応じて追加していく方式。
データ分析は直接売上を生み出さない手段のため、「金額以上のバリューを発揮できる」という覚悟があるかどうかが最終的な判断軸になるのだろうか？
もちろん、現状発生している問題の解決であったり、意思決定の質とスピードの向上にも繋がるため、単純にデータ分析だけにフォーカスしての判断は良くない。
(Googleに買収されたからGCP上で安く使える日がこないかなぁ…)


## まとめ

生まれて初めて有料BIツールを触ったが、想像以上の感動が待っていた。
(まじで、ここ2年間毎日のようにSQLを書いていたのはなんだったのか、と思えるぐらい感動した)

ただし忘れてはいけないのが、データは「使われてこそ価値を発揮する」ということ。
Lookerを導入して、環境を整えただけでは何も生み出されない。
如何に自然な形でビジネスサイクルにLookerを取り入れられるかが最初の関門になるだろう。

その他細かい気付きは沢山あるので、もし導入に迷われている方がいたらざっくばらんにお話しましょう。
[DMお待ちしています。](https://twitter.com/k_data_analyst)
マルチスケールシミュレーション特論8

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# Rake


## 講義ページリンク

[チャート式ruby-appendix-IV(rake)](https://qiita.com/daddygongon/items/1c2d6d2895333ccf5e62)


## 内容

rakeのかんたんな使い方


# NOTE

-   rakeはmakeのruby版
-   見た感じmakeよりわかりやすい気がする
-   けど環境(ruby, gem)に依存するのでその点はmakeのほうが使いやすい気がする



------
 - **source** ~/multiscalesim_toku/grad_members_20f/members/lynd2299/mss8.org
vue-chartjsでグラフのサイズ動的に変えたいな

仕事でVue.jsを使う機会があり、グラフを表示させたかったのでvue-chartjsを使いました。
グラフサイズを動的に変えたかったのですが、壁にぶち当たりまくったのでメモ。

##ぶち当たった壁
どうせwidthとheightをしていすればできるんやろ？はいよゆ～＾＾

```vuejs
<Chart
  :width="graphW"
  :height="graphH"/>
```

・・・何も変わりませんでした。


##答え
[vue-chartjs公式ガイド](https://vue-chartjs.org/ja/guide/)の「動的スタイルを使用したチャート」セクションにがっつり書いてありました。
:styleで指定するみたいです。

##おわりに
結論から言うとちゃんと公式ドキュメント読めやって話。。。
CentOS7+Python3でpip3が使える環境を構築する

# やりたいこと

CentOS7にPython3をインストールしてpip3を使いたい。


# 前提

* CentOS7がインストール済であること。
* root権限でSSH接続できること。


# インストール前

当然、pip3コマンドは使えない。

```
bash: pip3: command not found
```

python -V
を打つと

```
Python 2.7.5
```

と表示される。

python3.6 -V
を打つと

```
bash: python3.6: command not found
```

と表示される。

# インストール手順

rootで下記を実行するだけ。

```
yum install python3
```

そして、y を入力して、

```

Installed:
  python3.x86_64 0:3.6.8-17.el7

Dependency Installed:
  libtirpc.x86_64 0:0.2.4-0.16.el7                python3-libs.x86_64 0:3.6.8-17.el7                python3-pip.noarch 0:9.0.3-8.el7                python3-setuptools.noarch 0:39.2.0-10.el7

Complete!
```

と表示されたら成功。


# 確認


python3.6 -V
と打つと

```
Python 3.6.8
```

と表示されてOK。


pip3
と打つと

```
Usage:
  pip <command> [options]
```

と表示されてOK。
pip3コマンドが利用可能になった。
Front-End Study #1「Cloud Native時代のフロントエンド」での学習事項

# はじめに
本記事は以下の勉強会での学習事項をまとめることを目的としています。
参加した勉強会は[こちら](https://forkwell.connpass.com/event/190313/)を参照ください。
上記の勉強会の基調講演、セッション1、セッション2について、学習事項をまとめます。

# 基調講演：「フロントエンド領域」を再定義する

## ここ10年の振り返り
- IE Firstが終わり、Chromeがシェアトップ。IEに合わせるではなく、足を引っ張るならサポートを切る。
- 動くテンプレートが当たり前に。仮想DOMを使う技術やフレームワークが豊富に。
- JavaScriptはウェブのCO2。使いすぎると悪影響が出る。
- Deno：npmパッケージを使わずにURLパスでライブラリ参照。
- Rome：TypeScript First。外部ライブラリを使わずに自前ライブラリで動作。
- Blitz：今までのベストプラクティスを詰め合わせ。
- prisma2：TSフレンドリーでクエリに型付けできる。Blitzを含めたライブラリから利用される。
- JavaScriptは古く、モダンJavaScript=TypeScriptとなっている。いいコードは型付けという思想。

## Next.jsから得たベストプラクティス
- Next.js：静的サイトやサーバー上で動作するアプリケーションを実現可能。
- 静的サイトジェネレータを動的に実行する形態。
- Next.jsが実現したこと：SPA/SSRの複雑な仕組みを隠ぺい。
- SSRは多くのユースケースで不要。

## フロントエンド領域の変化
- Blitzのフルスタックでは、フロントエンドとバックエンドの境界がほぼなく全てがnode.jsにのっかる。
- 現実的に、フロントエンドはJS以外は厳しい状況。
- ただC#のBlazorやRustのYewはNode.jsから脱却できる可能性を秘めている。
- 宣言的UI+Next.jsをWebAssemblyで実装。
- 多言語でJSに対応する仕組みを作るのがはやり。
- TypeScript + 部分的にRustが当面はベスト。
- CDN Edge Worker：Edgeに合わせて最適化されており、Lambda@Edgeよりデプロイが高速。
  - 自由度の高いキャッシュコントロールが可能。

## 将来の展望
- TS + Next.js + RustがWebのベストプラクティス。
- 2020年代にはFullstack Node.jsがRailsに置き換わる。
- 課題はNode.jsにはRailsのような学習コンテンツが存在しないこと。

## 質疑応答
- Rustは高速なので、CPU負荷が高くなる箇所が徐々に置き換えられていくだろうという予想。
- フロントエンドやWebアプリケーション開発するなら今後はRustは必須の流れになりそう。

# セッション1：フロントエンド開発者も知っておきたいAWS Lambdaとサーバーレス

## サーバーレスとは
- サーバサイドで語られることが多い。フロントエンド開発者が全てを自分で作るためにサーバレスを学ぶという比率は低い。
- サーバの準備が必要ない。セキュリティやネットワークもサービス側がケアする。
- SPA + API、SSR + API、SSG + APIがWebアプリケーションの構成のほとんどを占める。
- GraphQL：APIの実装方式の一つ。
  - AWS AppSync：GraphQLのエンドポイントを公開できるサービス。
  - AWS Amplify：フロントエンド開発者向けツールセット。AppSyncを使う場合におすすめ
- REST
  - Amazon API Gateway：HTTPのエンドポイントを公開できるサービス。
  - AWS Lambda：Funstion As A Service。ランタイムのセットアップ不要。多くのAWSサービスと連携できる。
  - DataStoreは目的に応じて使い分けることを推奨。

## SPA with Serverless
- Amazon S3とAmazon CloudFrontを使ってホスティング。
- Amplify CLIだとより楽にパブリッシュ可能。

## SSR with Serverless
- SSRはサーバーサイドでレンダリングするのでサーバーが必要。
- インフラ的には、CPC負荷が高くなり、さばけるリクエスト量が制限されるといった課題が生じる。
- AWS LambdaとSSRは相性がよい。
  - 関数の裏側はコンテナが立ち上がる。1リクエストは同時に1コンテナでしか処理されない。
  - リクエストが増えても、水平にスケールするため、リクエスト集中でCPU負荷が高まっても、クライアントにレスポンスが返せなくなることがない。
- How
  - Next.js/Nuxt.jsを使う。
  - Expressで動かせるようにする。Expressで作ったアプリをLambdaで動かす。
  - 全てが同じ関数でデプロイされてしまう。無駄が生じてしまう。
- 静的アセットはS3 + CloudFrontで配信する。

### SSG with Serverless
- 基本的にSSGの配信はSPAと同じ考え方でいい。

## まとめ
- API GatewayとLambdaはすでに事例も多く、参考ドキュメントも多い。
- サーバレスも現時点では技術的に過渡期にあたるので、最新技術は要チェック。

## 質疑応答
- サーバレスにおける、リクエスト量に対する負荷はアプリケーションに大きく依存する。
- したがって、実際に計測する必要がある。

# セッション2：STUDIOのデザインツールとホスティングの仕組み
- STUDIO
  - ノーコードで静的サイトを作成し、パブリッシュできるサービス。
  - C#におけるWindow.FormsのようにコントロールをGUIで配置できる。ライブプレビュー機能で編集内容が即座に確認可能。
- 登壇者がSTUDIOを開発したきっかけ
  - Vue.jsとFirebaseを使って遊んでいたところ、組み合わせることでWebページエディタが実現できることに気づいたため。
- STUDIOのストラクチャ
  - 公開するサイトはSSRで実現している。
  - Vue.jsとFirebaseとの親和性を考慮して、Google Cloud上で実現。
- 公開サイト公開のための工夫
  - 画像の最適化。
  - static jsonを使っての性能改善。ページのheadのみをSSRする。

## 質疑応答
- OpenGraphProtocolはスループットに影響を与える可能性が高い。
回転盤を回すと動画をコマ送り／逆コマ送りする機能を実装する

### デモ

https://codepen.io/qwe001/pen/PozgEvZ

動画はフリー素材として公開されているものを使用しています。

### 何がしたいか

* 回転盤を時計回りに回転させた時、動画を1フレームずつコマ送りする
* 回転盤を反時計回りに回転させた時、動画を1フレームずつ逆コマ送りする

### 実装

(仕事で必要だったので超急ぎで作りました。時間空いたら多分解説書きます)

### 参考サイト

素敵な回転盤はこちらの作者さんのものを使用しました

https://codepen.io/adadsa/pen/QEzbak