OmniAICreator/Qiita-1.07M huggingface dataset:
【A-FRAME】a-skyをいじって360°をimageでうめてみよう

#できあがりイメージ
WASDで移動可能でかつマウスコントロールで視点移動が可能です。
![スクリーンショット 2020-09-15 7.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/2a4e0287-65c5-e048-6e60-1cf186e395b7.png)

#コード全部
https://github.com/i-am-ethan/aframe-a-sky

#360°画像のサイト
http://texturify.com/stock-photo/room-in-private-flat-10096.html

#やり方
githubからコードをダウンロードしていただければ完成なのですが簡単にコードを解説します。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>atapra</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
aframeを使うためのライブラリ
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-assets>
imgを取り込むタグ
        <img id="sky" src="texture.jpg" />
      </a-assets>
360°表示するためのタグ（radiusを変更で半径が変わります）
      <a-sky id="image-360" radius="10" src="#sky"> </a-sky>
    </a-scene>
  </body>
</html>
```

以上。
エラーメッセージを日本語表示にする方法

#1.config.i18n.default_locale = :jaを記述する

```
config/application.rb
 class Application < Rails::Application
   # 日本語の言語設定
   config.i18n.default_locale = :ja
　　# 省略
end
```

#2rails-i18nをインストールする
```
#Gemfile
gem 'rails-i18n'
```
記述した後
ターミナル bundle install

rails-i18nに登録された日本語
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml

これでrails-i18nに書いてあることは翻訳できた
しかし他の文言は日本語訳できていない。

#3ログイン用の日本語化用のファイルを作成
config>locales>devise.ja.yml
ファイルを作成する

deviseに関する日本語訳をコピーして先ほど制作したdevise.ja.ymlに貼り付ける
https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml

#4その他のフォームに関する日本語訳のファイル(ja.yml)を作成

config>locals>ja.yml

```
ja:
 activerecord:
   attributes:
     user:
       nickname: ニックネーム
     tweet:
       text: テキスト
       image: 画像
```
userテーブルのnicknameが日本語訳される
tweetテーブルのtextが日本語訳される
　　　　　　　　imageが日本語訳される
AWSでのDocker から AKS までの学び方を並べる

Dockerはなんとなくわかるが、KubenetesをAWSでマネージドで？というと、すごく先が遠いイメージがするが、自分はどのくらい理解しているか、どのへんの技術があればよいかわかるようにする。徐々に更新します。

+ Docker on localhost
 - Docker で 1-tier の Web環境を構築する ことができる。
 - Docker Compose で 2-tier の 簡単な Web/DB構成を構築する ことができる。
 - Kubernetes で 冗長化された 2-tier の 簡単な Web*N/DB構成を構築する ことができる。
+ Docker on EC2
 - EC2 に Docker で 1-tier の Web環境を構築する ことができる。
 - Beanstalk で冗長化された 2-tier の簡単な Web*N/DB構成を構築する ことができる。
+ Container on AWS
 - ECS で 1-tier の Web環境を構築する ことができる。
 - Fagete on ECS で 1-tier の Web環境を構築する ことができる。
 - AKS で 冗長化された 2-tier の 簡単な Web*N/DB構成を構築する ことができる。

以上
AWSの鍵管理方法を簡単に整理する

AWS の 鍵管理方法が整理できそうだったのでまとめてみます。途中です。

# まとめ
+ ACM
 - IAM内でデジタル証明書（SSL証明書）を管理できます。
 - AWSのWeb系サービスをHTTPS化する際にマネージドに利用することができます。
 - 持ち込んだ証明書も管理できます。正規の認証局で作成したりオレオレ認証局で作ったりした、外で作った自前ルートキー（CMK）を持ち込めます。
+ KMS
 - AWSマネージドな鍵管理サービスです。
 - ACMのルートキーを暗号化したり、S3やEBS、ログ暗号化、など、いろいろなサービスをマネージドに暗号化できます。
 - 外で作った自前鍵（CMK）を持ち込めます。
+ CloudHSM
 - VPC上に鍵管理専用のサーバをプロビジョンできます。
 - KMSより暗号化レベルが強く、管理が利用者になるため、エンタープライズな用途に向いているようでした。
 - 外で作った自前鍵（CMK）を持ち込めます。

# 参考
+ AWS KMS と CloudHSMの違い
 - https://qiita.com/ayumi_imai/items/6a74c6327e0f6a1ac7db
 - https://awsjp.com/AWS/hikaku/KMS-CloudHSM-compare.html

+ KMS と CloudHSM と ACM
 - https://qiita.com/leomaro7/items/46dafff79206087c2524

+ CloudHSM
 - https://d1.awsstatic.com/webinars/jp/pdf/services/20190723_AWS-Blackbelt-CloudHSM.pdf （詳しい）

+ KMS
 - https://dev.classmethod.jp/articles/cm-advent-calendar-2015-aws-relearning-key-management-service/

+ ACM
 - https://aws.amazon.com/jp/certificate-manager/

+ KMS と Azure Key Valut
 - https://azure.microsoft.com/ja-jp/services/key-vault/

以上
【GCP】mac OSでgcloudコマンドを再び使えるようにする。

__前提__

* 既にGCPにプロジェクトがある。
* 一度はgcloudコマンドをローカルで使っていて、再度その設定を行う。

# 1. install 
`./google-cloud-sdk/install.sh`


```
% ./google-cloud-sdk/install.sh
Welcome to the Google Cloud SDK!

To help improve the quality of this product, we collect anonymized usage data
and anonymized stacktraces when crashes are encountered; additional information
is available at <https://cloud.google.com/sdk/usage-statistics>. This data is
handled in accordance with our privacy policy
<https://policies.google.com/privacy>. You may choose to opt in this
collection now (by choosing 'Y' at the below prompt), or at any time in the
future by running the following command:

    gcloud config set disable_usage_reporting false

Do you want to help improve the Google Cloud SDK (y/N)?  y


This will install all the core command line tools necessary for working with
the Google Cloud Platform.


All components are up to date.

Modify profile to update your $PATH and enable shell command
completion?

Do you want to continue (Y/n)?  y

The Google Cloud SDK installer will now prompt you to update an rc
file to bring the Google Cloud CLIs into your environment.

Enter a path to an rc file to update, or leave blank to use
[/Users/kuraya/.zshrc]:
Backing up [/Users/kuraya/.zshrc] to [/Users/kuraya/.zshrc.backup].
[/Users/kuraya/.zshrc] has been updated.

==> Start a new shell for the changes to take effect.


For more information on how to get started, please visit:
  https://cloud.google.com/sdk/docs/quickstarts
```

ここでターミナルを起動しなおします。


# 2. SDKの初期化
`gcloud init`

```
Pick configuration to use:
 [1] Re-initialize this configuration [xxx] with new settings
 [2] Create a new configuration
 [3] Switch to and re-initialize existing configuration: [default]
Please enter your numeric choice:  1
```

```
Choose the account you would like to use to perform operations for
this configuration:
 [1] a*****ya@gmail.com
 [2] Log in with a new account
Please enter your numeric choice:  1
```

ここでは、対象のprojectを選択します。

```
Pick cloud project to use:
 [1] XXXXXX
 [2] YYYYYY
 [3] select-client
 [4] word-press-mmm
 [5] Create a new project
Please enter numeric choice or text value (must exactly match list
item):  2
```

以上です。

参考：
https://cloud.google.com/sdk/docs/quickstart-macos?hl=ja
ちゃんとしないと VirtualizedList の仮想化を生かせない

React Native の話です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">RN で作る画面のレイアウト、NavigationBar と TabBar を除くと、VirtualizedList があるのみ or スクロール無し の2パターンしかない</p>&mdash; moriyuu (@moriyuu__) <a href="https://twitter.com/moriyuu__/status/1305581930956509184?ref_src=twsrc%5Etfw">September 14, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

と思った。

<img width=400 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130756/8814b2bb-951a-6420-a883-e2c636b48feb.png />

みたいなレイアウトの（下にスクロールした先にコンテンツが並んでいる）ユーザー詳細画面があったら、

```jsx:A
const UserPage = () => {
  return (
    <ScrollView>
      <ProfileComponent />
      <FlatList
        data={tweets}
        renderItem={renderItem}
      />
    </ScrollView>
  )
}
```

ではなく、

```jsx:B
const UserPage = () => {
  return (
    <FlatList
      ListHeaderComponent={<ProfileComponent />}
      data={tweets}
      renderItem={renderItem}
    />
  )
}
```

と作る。

A で作ってしまいそうだけど、これでは FlatList はうまく仮想化されず、レンダリングのパフォーマンスが最適化されない。

A, B それぞれの `renderItem` の中で `console.log` するなどして、画面よりだいぶ下のほうの item が、画面をスクロールする前の段階でレンダリングされてしまうかどうかを確かめられる。A だとレンダリングされてしまうが、B だとその item の近くまでスクロールしないとレンダリングされない。

あと onEndReached とかも使えないしね


## 参考

https://reactnative.dev/docs/virtualizedlist
感度関数と相補感度関数について

# 背景

最近仕事で新しく、サーボ系のチューニングをすることになりました。

そこで制御工学を改めて勉強したのですが、
よく理解できなかった感度関数と相補感度関数について、その理論的背景をまとめるとともに、
それを物理的にどう理解したらよいかを私が掴んだ観点から皆様に共有したいと思います。

# ブロック図
![block.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529547/c3d47436-f1bf-fb3f-9c13-57a38353c173.png)

これをサーボ系だとみなす。

* $r$ : 位置指令
* $y$ : 現在位置

# 理論
上記ブロック図をベースとして感度関数と相補感度関数を定義する。

閉ループ伝達関数とは、
$ r \rightarrow y $への伝達関数、すなわち$\frac{y}{r}$が定義となる。
これを上記ブロック図から計算すると

```math
 \frac{y}{r} = \frac{PC}{1+PC}
```

となる。


感度関数$S$とは、
$ d \rightarrow y $への伝達関数、すなわち$\frac{y}{d}$が定義となる。
これを上記ブロック図から計算すると

```math
 S = \frac{y}{d} = \frac{1}{1+PC}
```

となる。

相補感度関数Tとは、
$ n \rightarrow y $への伝達関数、すなわち$\frac{y}{n}$が定義となる。
これを上記ブロック図から計算すると

```math
 T = \frac{y}{n} = \frac{PC}{1+PC}
```

よって、下記の関係

```math
S + T = 1
```

が成り立つ。

# 解釈

感度関数とは現在位置$y$にそのまま乗っかってくる外乱$d$、たとえばサーボ系で言ったら不要な振動などが考えられるが、
そういったものが、実際の位置にどういう影響を与えるかを示すものである。
感度関数が0dB以下であれば、外部振動はサーボ系によって抑えられる。
逆に0dBより大きければ、外部振動はサーボ系によって拡大される。

相補感度関数とは現在位置$y$とは無関係に乗っかる外乱$n$、たとえばサーボ系で言ったらエンコーダなどにおる電気的ノイズなどが考えられるが、、
そういったものが、実際の位置にどういう影響を与えるかを示すものである。
相補感度関数が0dB以下であれば、ノイズはサーボ系に無視される。
逆に0dBより大きければ、ノイズによってサーボ系は不要な動きをしてしまう。

# 結論

感度関数、相補感度関数はそれぞれできるだけ小さくするひつようがある。
ただし、$S+T=1$の関係があるため、それぞれを独立に小さくすることはできない。
この次はそのトレードオフをどうするかについてまとめる。
AWS ALBにWAFを設定して海外からのアクセスを遮断してみる

# AWS ALBにWAFを設定して海外からのアクセスを遮断してみる

## AWS WAF (Web Application Firewall)

クラウド上で動作するファイヤーウォール
IPアドレスや、国情報、ヘッダーの内容をもとにアクセスを許可、遮断できる

Amazon CloudFrontや、Application Load Balancer (ALB)にデプロイして利用できる
[WAF（Web アプリケーションファイアウォール）とは？| AWS](https://aws.amazon.com/jp/waf/what-is-waf/)

2016年から後発でALBでも使用できるようになったとこと

[AWS WAFがALB(Application Load Balancer)で利用出来るようになりました | Developers.IO](https://dev.classmethod.jp/articles/aws-waf-alb-support/)

## 目標

- 日本国内からはEC2にアクセス可能
- ALBにWAFを設定し海外からのアクセスを遮断する

## アーキテクチャ - 構成図

上が目標物、下はCloudfrontを使用するパターン
基本はweb serverの前に置く、よりクライアントに近い側に設置するのがいいと思われる
![basic_VPC_ALBWAF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649386/e9362841-bb38-cf81-d784-fdb12f0f7728.png)

![basic_VPC_CFWAF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649386/0b001fa0-e45c-eff5-521a-d8e06a883848.png)

## 既存のALBにWAFを設定する

### web ACL (Access Control List)の作成

[AWS WAF](https://console.aws.amazon.com/wafv2/homev2/start?region=ap-northeast-1)

- ホワイトリスト、ルールなしで作成（すべてのトラフィックを遮断）
- ALBにアクセスできなくなることを確認

`Create web ACL`

Describe web ACL and associate it to AWS resources

```
Web ACL details
Name: 任意
CloudWatch metric name: （自動）
Resource type: 
CloudFront distributions
Regional resources (Application Load Balancer and API Gateway)　#こっちを選択
Region: Asia Pasific (Tokyo)

#後で選択することも可能
Associated AWS resources - optional
Add AWS resources > Application Load Balancer
適当なALBを選択 > ADD
```

`Next`

Add rules and rule groups

```
Rules
#後で追加します

Default web ACL action for requests that don't match any rules
Default action: Block
```

`Default action: Block`とすることでホワイトリスト化、後で追加するルールのみalllowにする

`Next` > `Next` > `Create web ACL`

この時点でブラウザからドメインにアクセスすると403エラーを返すことを確認する

### Allow Ruleを追加

- Allow Rule (country - JP) を追加
- allow条件でリクエストが成功することを確認

作成したweb ACLを選択して

Rules > Add rules  > Add my own rules and rule groups

```
Rule type
Rule type: Rule builder

Rule builder

Rule
Name: 任意
Type: Regular rule

If a request: matches the statement
#(AND, OR, NOT指定可)

Statement
Inspect: Originates from country in
# 他にIPやリクエストの内容を選択可
Country codes: Japan - Ja

Source IP address #こっちを選択
IP address in header

Then

Action
Action: Allow
```

`Add rule`

再びブラウザからドメインにアクセスすると今度はリクエストが成功する

### IP address in headerオプションの使用に注意

ヘッダーのIPは書き換えられる場合があり、それによって意図せずアクセスコントロールを通過するリスクが有り、注意が必要

> When a request comes through a CDN or other proxy network, the source IP address identifies the proxy and the original IP address is sent in a header. Use caution with the option, IP address in header, because headers can be handled inconsistently by proxies and they can be modified to bypass inspection.

## 検証

以下のサイトで海外からのアクセスをシュミレート可能

[WebPageTest - Website Performance and Optimization Test](https://www.webpagetest.org/)

Location: Tokyo, Japan 以外で"403 Forbidden"を確認
KubernetesでEBS CSIドライバーを利用してPVを作成する

# 参考
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/ebs-csi.html

# CSIドライバーのデプロイ
- Nodeに適用されているEC2インスタンスに専用ポリシーを割り当てる
- CSIドライバーをデプロイ

## IAMポリシーのダウンロード

```
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/v0.5.0/docs/example-iam-policy.json
```

## ポリシーを適用

```
aws iam create-policy --policy-name Amazon_EBS_CSI_Driver \
    --policy-document file://example-iam-policy.json
```

出力結果

```
{
    "Policy": {
        "PolicyName": "Amazon_EBS_CSI_Driver",
        "PolicyId": "ANPA2EXCVS2IDDNDPI5OH",
        "Arn": "arn:aws:iam::697333814928:policy/Amazon_EBS_CSI_Driver",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2020-09-14T18:06:31Z",
        "UpdateDate": "2020-09-14T18:06:31Z"
    }
}
```

## 作成したARNの確認

```
kubectl -n kube-system describe configmap aws-auth
```

```

Name:         aws-auth
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
mapUsers:
----
[]

mapRoles:
----
- groups:
  - system:bootstrappers
  - system:nodes
  rolearn: arn:aws:iam::697333814928:role/eksctl-k8s-cluster-nodegroup-ng-2-NodeInstanceRole-PPPRL3U54S9K
  username: system:node:{{EC2PrivateDNSName}}

Events:  <none>
```
## Nodeに適用されているIAMRoleにポリシーを割り当てる

```
aws iam attach-role-policy --policy-arn arn:aws:iam::697333814928:policy/Amazon_EBS_CSI_Driver --role-name eksctl-k8s-cluster-nodegroup-ng-2-NodeInstanceRole-PPPRL3U54S9K
```


## CSIドライバーを割り当てる
```
kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
```

出力結果

```
serviceaccount/ebs-csi-controller-sa created
clusterrole.rbac.authorization.k8s.io/ebs-external-attacher-role created
clusterrole.rbac.authorization.k8s.io/ebs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/ebs-csi-attacher-binding created
clusterrolebinding.rbac.authorization.k8s.io/ebs-csi-provisioner-binding created
deployment.apps/ebs-csi-controller created
daemonset.apps/ebs-csi-node created
csidriver.storage.k8s.io/ebs.csi.aws.com created
```
コード補完がちゃんと効く状態で Flutter の Plugin プロジェクトを開く

Android Studio 上で flutter の Plugin プロジェクトを普通に開くと、 flutter SDK 関係のライブラリのコード補完が効きません。

flutter/dart プラグインが Android Studio にインストールされた状態で、プロジェクトの android フォルダを右クリックし、メニューから [Flutter]-[Open Android module in Android Studio] を選択すると、コード補完が効いた状態で Plugin プロジェクトを開くことができます。

![Screen Shot 2020-09-15 at 1.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43781/fd666636-d576-e798-9a3b-d00983d37f67.png)
AWSソリューションアーキテクトアソシエイト受験記録

# AWS ソリューションアーキテクトアソシエイトを受けたので勉強した内容と方法を残します
勉強期間2週間くらいでソリューションアーキテクトアソシエイトも受けました。
ご参考まで。

## 前提知識の有無
社会人ももう15年目くらいのおじさんなので、一通りのIT用語はわかります。
20代の頃にソフトウェア開発技術者とテクニカルエンジニアネットワーク(呼び方古い。。。)を取っているので知識の下地はある感じ。
昨年の10月くらいに[プラクティショナー](https://qiita.com/fukuham/items/a121bae5ec410a1bfa44)に合格しています。
ただ仕事ではほぼ関わっておらず、趣味でもほぼノータッチ。
ソリューションアーキテクトアソシエイト受験用のzoom研修を1回受けています。
（ぶっちゃけ会社の認定数を稼ぐために受けさせられただけとも。。。）


## 教材
-  [参考書](https://www.amazon.co.jp/dp/B07R1H87Y1/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) 
プラクティショナーに引き続きこのシリーズ。
読み物として１週、問題だけ解く形でもう１週。計5時間くらい。

- [Web問題集](https://aws.koiwaclub.com/) 
AWSの認定試験の問題集サイトがあったので、ゴールドプラン(2か月参照可能)のやつに登録してみました。
約4000円


## やったこと

1. 動画を見る
これは皆さん受けれるかわからないのですが、AWSのトレーナーが開催しているzoomの研修に参加しました。
まぁ、原則聞くだけだったのでUdemyとかで受験勉強用のコースを買ってひとなめするとかでもいいかもです。
必須かと言われると。。。まぁここで聞いた内容も数問は出題されました。

2. 白本を読む
大体4時間くらいで読めました。
プラクティショナーと違って多少各サービスの中身、使いどころあたりが出てきます。
サービス名とか受験範囲とかを確認する意味で有効だったかな。と。

3. Web問題集を解きまくる
有償ですが、最短の道かと思います。
ソリューションアーキテクトアソシエイトの問題だけで1000問くらいあるので、
これを淡々と解きました。間違ったところは解説がついているので、ここ読むのと関連情報をググる感じ。
問題自体は徐々に追加しているようなので、後半のほうが最近出題された問題に近いようです。
なので、逆順で解いていくほうがよいかと。
本当は1000問全部ひと舐めしようと思ったのですが、準備期間的な意味で700問くらいで試験当日を迎えちゃいました。
が、さすがに数百問単位で問題を見ていると大体出てくる問題の傾向が見えるので数をこなすのは大事かもしれません。

4. 試験当日。
白本の章末問題だけをつらっと舐めて受験。

## 結果
試験はAWS講習をzoomで受けた後約2週間後に設定しました。あまり遠くに置くとダレそうだったので。
平日は毎日じゃないですが1日1-2時間。試験前日と当日午前で詰込みした結果、無事合格。
ちなみに合格時の点数は822/1000点。(合格ラインは720点)

## 感想
VPC関係の設計みたいな内容が多かったです。これこれの要件を満たすような構成はどれか？みたいな。
とりあえずWell-Architected フレームワーク＋サービス内でできることを白本レベルで押さえておけば何となく答えには行きつきました。
何々なサービスを応えよ、みたいな言葉を言わせる問題はほぼなかったので、試験受けてる時は手応え的なものはあまり感じませんでしたが。。。
ソリューションアーキテクトはNW、DB、ストレージ、VMあたりの予備知識が多少あればAWSコンソール自体はそこまで触らなくても受かるかな。
という印象でした。


以上。
【Rails】controllerでassets下に保存されている画像を変数に格納してviewに出力する方法

#controllerを使ってassets下に保存されている画像をviewに出力する方法
Railsの自作アプリ開発を進める中で、パラメーターの値によってviewに出力する写真を変えたいと考えていました。
ネットを探っている中で例がなかったため、記事にすることにしました。
#試したこと
バージョン：Ruby:2.6.3 Rails:5.1.7
controllerでassets/imagesに保存されている画像を変数に格納し、viewに出力する

```ruby:controller
def image
  @image = URI("/assets/sample1.jpg")
end
```
コントローラーでは、変数に上記のようにURIを使って代入できることがわかりました。
初めはurl("/assets/sample1.jpg")と書いたところ、NoMethodErrorが発生。
undefined method `url' for #< SampleController:0x00007fc44b041bd8> Did you mean? URIと表示され、それを試したところ、うまく表示されたという経緯です。

```ruby:view.html.erb
<%= image_tag @image %>
```
あとは、image_tagを使用して変数を書けば無事に出力できます。

自作アプリではcontrollerで受け取ったパラメーターをcase文を使用することで画像を変えています。
普通はviewにてimage_tagで画像を出力できます。controllerを用いて、条件によって出力する画像を変えたいと考える方が他にもいらっしゃれば、お力になれたら幸いです。
声でおしえるAI画像分類 Image AI Classifier, that Speaks


Google のコードラボから、画像を見て、分類、結果をしゃべってくれるK近傍法によるAIを作ってみた。コードはこちら。From Google CodeLabo, made KNN AI to classify image and speak out the result. Code is here.

各分類ごとに読み方をローマ字で名前を入れる。デフォルトはグー チョキ パーだ。Input the name of each class in the fields below. Default is set as Goo, Choki and Paa, that is rock, scissors, paper in Japanese.

 


次に、カメラの前で、グーとチョキとパーを作り、確率が１になるまで、A、B、Cボタンをクリックする。Then make sign of each rock, scissors, paper in front of Camera and click corresponding A, B, C button until probability goes 1.

教育が完了すると、カメラの前でサインを作っただけで、グーかチョキかパーかをしゃべってくれる。サインだけでなく、写真とか、物とか、色々応用可能。Once training is done, just showing hand sign in front of Camera, computer speaks if it is rock, scissors, or paper. Application is not just limited to hand signs but pictures, objects etc. 

遊んでみてください！ Enjoy this playground!

https://randomwalkjapan.blogspot.com/2020/09/tensorflow-image-classifier.html
WSL2なUbuntu20.04でSSHサーバを立てる

# はじめに
WSL2なUbuntu20.04でSSHサーバを立てようとしてハマったので、解決方法をご紹介します

# なにがいけないのか
* systemctlを受け付けない
* OpenSSH Server自体も変

# 解決方法
[トラブルシューティング](https://docs.microsoft.com/ja-jp/windows/wsl/troubleshooting#openssh-server-connection-issues)は無視して入れなおしてしまいましょう  

```
$ sudo apt purge openssh-server
$ sudo apt install openssh-server
```

systemctlは使わず、serviceを使って起動しましょう

```
$ sudo service ssh start
 * Starting OpenBSD Secure Shell server sshd                                                                     [ OK ]
```

無事TCP22番ポートが開きました

```
$ sudo ss -autoSnp
Netid   State       Recv-Q   Send-Q      Local Address:Port       Peer Address:Port   Process
tcp     LISTEN      0        128               0.0.0.0:22              0.0.0.0:*       users:(("sshd",pid=2067,fd=3))
tcp     LISTEN      0        128                  [::]:22                 [::]:*       users:(("sshd",pid=2067,fd=4))
```

# 最後に

まさかsystemctlが使えないとは
やられました
CakePHP3 ORMのWHERE句で、date_formatで指定した "Y" が "y" になってしまう

# TL;DR
- DATE_FORMATで *%Y* を使用する場合は、以下を参考にする
    - where句でコールバック関数とクロージャーを使用し、eqメソッドを使用する

```php
$createdFormat = $query->func()->date_format([
    'created'    => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);
$query->where(function ($exp) use ($createdFormat, $created) {
    return $exp->eq($createdFormat, $created);
});
```

# 前提
- PHP
    - 7.3.11
- CakePHP
    - v3.6.14

# 事象
```php
1.
ORM: $query->where(["DATE_FORMAT(created, '%Y-%c') = " => $date])
SQL: WHERE DATE_FORMAT(created, '%y-%c') = :c0
################
2.
ORM: $query->where(["DATE_FORMAT(created, '%Y-%c') = ${date}"])
SQL: WHERE DATE_FORMAT(created, '%Y-%c') = 2020-8)
```

- 上記の通り、連想配列によるデータの渡し方では、発行されるSQLのフォーマットが、*Y* → *y* になってしまう
- 変数展開による渡し方では、発行されるSQLのフォーマットは、*Y* のまま

# 原因
- 巡りめぐって```QueryExpression::_parseCondition()```を参照し、そこで[strtolower](https://www.php.net/manual/ja/function.strtolower.php)を行ってるため
- 以下対象コードの一部抜粋

```php
    protected function _parseCondition($field, $value)
    {
        $operator = '=';
        $expression = $field;
        $parts = explode(' ', trim($field), 2);

        if (count($parts) > 1) {
            list($expression, $operator) = $parts;
        }

        $type = $this->getTypeMap()->type($expression);
        $operator = strtolower(trim($operator));

        ...

        return new Comparison($expression, $value, $type, $operator);
    }
```

# 対策
1. date_formatで指定したいカラムを、別でフォーマット化する
2. WHERE句でコールバック関数とeqメソッドを使って条件に追加する

```php
$createdFormat = $query->func()->date_format([
    'created'    => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);
$query->where(function ($exp) use ($createdFormat, $created) {
    return $exp->eq($createdFormat, $created);
});
```
dprint とても良いよ

## dprint とは

[dprint](https://dprint.dev/) とは Rust で実装され高速に動作するコードフォーマッタです。
一応、売りを公式ページからコピペすると以下の通りです。

 1. フォーマットは非常に高速です。
 1. プラグインは、URLまたはファイルパスからインポートできるWebAssemblyファイルです。
 1. 公式プラグインは高度な設定が可能で、好みに合わせてコードを自動フォーマットできます。
 1. URLから構成をインポートして、再利用および共有できます。

実際動かしてみると、”すっ” と動作する感じです。この動作の軽快さは Deno のビルトインのフォーマッタやリンタの軽さに通じるところがあります。(`deno fmt` の内部で `dprint` が動いているので当たり前ですが。)
VS Code の拡張機能にも対応しているので、Deno User は是非お試しあれ！！

## インストール

[公式のインストールページ](https://dprint.dev/install/) の通りです。Linux だと以下の通りです。

```
curl -fsSL https://dprint.dev/install.sh | sh
```

コマンド実行後にインストーラの指示通りに PATH を通せば完了です。

## 実行！

CLI として実行したい場合はまずは設定ファイルを作ります。

```
$ dprint init
What kind of project will dprint be formatting?

More information: https://dprint.dev/sponsor

> commercialEvaluation Dprint is formatting a project whose primary maintainer is a for-profit
                       company or individual and it is being evaluated for 30 days.
  commercialSponsored  Dprint is formatting a project whose primary maintainer is a for-profit
                       company or individual AND the primary maintainer sponsored the project.
                       Thank you for being part of moving this project forward!
  openSource           Dprint is formatting an open source project whose primary
                       maintainer is not a for-profit company (no sponsorship requirement).
  educational          Dprint is formatting a project run by a student or being used for
                       educational purposes (no sponsorship requirement).
  nonProfit            Dprint is formatting a project whose primary maintainer is a non-profit
                       organization (no sponsorship requirement).
Select plugins (use the spacebar to select/deselect and then press enter when finished):
> [x] dprint-plugin-typescript
  [x] dprint-plugin-json
  [x] dprint-plugin-markdown
  [x] dprint-plugin-rustfmt
```
プラグインを選べ的なことを言われるので、対象としたいものを選択します。

フォーマットチェックだけして、ファイルを書き換えたくない場合は

```
$ dprint check
```

フォーマットしたい場合は、

```
$ dprint fmt
```

で OK! (雑)


## 最後に背景というか本論というか愚痴

ただ僕は assertNotMatch() の Usage がドキュメントに書いていなかったから、修正して pull request を出しただけなんだ。そうしたら、Deno の github action の CI が fail してしまった。
![スクリーンショット 2020-09-15 00-08-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699236/6ddde64d-964f-2514-a513-5a8589976758.png)
どうも python から formatter を呼び出したら差分が出てしまい、「おい、ちゃんとフォーマットしろよ！」ということらしいです。Deno の勉強するときはいつも `deno fmt`や `deno lint` のお世話になっていますが、マークダウンで怒られるとは...。`python` コードを眺めてみるとどうも `md` ファイルに対しては`dprint` というものが動いているようで、こいつでちゃんとフォーマットチェックをしないとダメらしいです。いや、知らんがな...。

(2020/09/18 追記)
マークダウンでも deno fmt 使わせろよという[issue](https://github.com/denoland/deno/issues/7352) がありました。

ちなみに本記事投稿時に `dprint` について書いている日本語記事は「[ESLint 上で dprint を使う](https://qiita.com/mysticatea/items/32b0dc07f63e4bc101ba)」くらいしか見当たりませんでした (そして、あちらは至極全うな記事)。

今後、`dprint` という文字列を見て、「何これ？」と思う人が少しでも減ればと思い、この記事を書きます。
laravel-admin でRowAction の表示方式を変更する

## 環境
* Laravel Framework 8.2.0
* laravel-admin 1.8.4

## 経緯
laravel-admin 1.8.4 では RowAction はハンバーガーメニューみたいな形式になってるが、[ドキュメントの TOP](https://laravel-admin.org/docs/en/) のスクリーンショットにあるようなリンク形式にしたくて若干ハマった。
![2020-09-14 23_40_02-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60104/6f301f85-5e19-f1b4-56ef-64b2cdb178a0.png)
こんなの

## 変更方法

```php:config/admin.php
    /*
    |--------------------------------------------------------------------------
    | The global Grid action display class.
    |--------------------------------------------------------------------------
    */
    'grid_action_class' => \Encore\Admin\Grid\Displayers\DropdownActions::class,
```
`config/admin.php` 内の `grid_action_class` を `\Encore\Admin\Grid\Displayers\Actions::class` に変更するだけで良かった。

改めてドキュメントを見るとこの辺で `grid_action_class` について書いてるけど古い方式だから（？）触れられていないのかな？
https://laravel-admin.org/docs/en/model-grid-custom-actions#Old%20version%20compatible

## もう少しカスタマイズする
`Actions::render(View|Edit|Delete)` をオーバーライドする。

`renderDelete` はクラスやデータ属性を下手に消すと削除用のスクリプトが動かなくなるので注意。

```php:CustomActions.php
<?php

namespace App\Admin\Grid\Displayers;

use Encore\Admin\Grid\Displayers\Actions;

class CustomActions extends Actions
{
    protected function renderView()
    {
        return <<<EOT
<a href="{$this->getResource()}/{$this->getRouteKey()}" class="{$this->grid->getGridRowName()}-view btn btn-sm btn-default">
    <i class="fa fa-eye"></i> View
</a>
EOT;
    }

    protected function renderEdit()
    {
        return <<<EOT
<a href="{$this->getResource()}/{$this->getRouteKey()}/edit" class="{$this->grid->getGridRowName()}-edit btn btn-sm btn-default">
    <i class="fa fa-edit"></i> Edit
</a>
EOT;
    }

    protected function renderDelete()
    {
        $this->setupDeleteScript();

        return <<<EOT
<a href="javascript:void(0);" data-id="{$this->getKey()}" class="{$this->grid->getGridRowName()}-delete btn btn-sm btn-default">
    <i class="fa fa-trash"></i> Delete
</a>
EOT;
    }
}
```

`config/admin.php` を修正。

```diff
     /*
     |--------------------------------------------------------------------------
     | The global Grid action display class.
     |--------------------------------------------------------------------------
     */
-    'grid_action_class' => \Encore\Admin\Grid\Displayers\Actions::class,
+    'grid_action_class' => \App\Admin\Grid\Displayers\CustomActions::class,
```

![127.0.0.1_8000_admin_auth_permissions(iPad).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60104/6bd674be-4aad-2abe-c9fc-ded679981ebf.png)
[Swift]アプリ起動中に、コードによりホーム画面に戻る方法

# はじめに
とあるiOSアプリを触っていると、設定画面に言語変更のオプションがあり興味本位で変更してみるとアプリの再起動を促されて自動でホーム画面に戻るというUXを見つけました。そこでどういう実装をしているのか気になり調べてみました。
完成図↓

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これはアプリからコードでホーム画面に戻る方法 <a href="https://t.co/Q9rmDxzlpK">pic.twitter.com/Q9rmDxzlpK</a></p>&mdash; M (@p_x9) <a href="https://twitter.com/p_x9/status/1305518700192096257?ref_src=twsrc%5Etfw">September 14, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# アプリを意図的に落とすUXはどうなのか
この点に関しては以下の記事に詳しく書かれていました。
https://news.mynavi.jp/article/20190528-iphone_why/

メモリ不足に起因するリソース不足などについてもシステム側でメモリの開放が行われることから、アプリを落とさなければならないという状況は極めて限定的ではあると考えられます。しかし表示言語の変更などのやむをえない場合についてはこのようなUXを実装しても問題なさそうです。

# 単純にアプリを落とす方法
ただ単にアプリを落とすだけなら、exit(0)などで落とすことができます。ただし、これだけだとアプリが突然クラッシュしたかのような挙動となりあまりふさわしいとは思えません。

また、exit(0)以外にも、fatalError()やassertなどで落とすことができますが、今回の言語の変更を目的とした、使用用途としては不適だと言えます。これらの使い分けについては以下の記事が大変参考になりましたのでご覧ください。

https://scior.hatenablog.com/entry/2019/04/04/202352


```swift
exit(0)//今回使用する
fatalError()//不適
assert(false, "")//不適
```

# そこで
そこでアプリを終了させる前にホーム画面に戻るという処理を行います。こうすることでクラッシュしたかのような挙動は避けることができました。
コードは以下の通り単純です。

```swift
UIControl().sendAction(NSSelectorFromString("suspend"), to: UIApplication.shared, for: nil)
```

この処理の後に先程のexit(0)を呼べば良いのですが以下のように直後に呼んでしまうと一瞬画面がブラックアウトしたように見えてしまい、これもまた好ましい挙動ではありません。

```swift
UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
exit(0)
```

よって、タイマーを用いて、ほんの少しの間遅延させて実行することとします。
自分は以下のように実装しました。


# 完成したコード
```swift
UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
            exit(0)
        }
```

# 最後に
これからちょくちょく記事を書いて行くのでよかったら見て行ってもらえたら嬉しいです。
何かご指摘や質問(わからないかもですが)などありましたら気軽にコメントでもDMでもください。

# 追記
## AppStore公開時の審査について
StackOverflowなどでこの方法では審査に通らないとする意見も見られるそうです。
しかし自分で調べたところ大手アプリにおいてもこの方法を使用しているものが見受けられたので、一概に落とされるとも限りません。
もし、この方法を用いたアプリを審査申請された方がおられましたらどうなったかコメント頂けると助かります。自分も次のアプリ公開時にこの方法を使用して試してみようと思います。
MacのVSCodeのShellをZshにする

#目的
VSCode(Visual Studio Code)のターミナルで使用するShellをBashからZshに変更する。

#今回の経緯
新しいMacでVSCodeを入れてコマンドを入力したらインストールしたはずのコマンドがないと言われた。
理由は簡単でした。
VSCodeのShellのデフォルトは**Bash**なのに対して
Mac側のShellのデフォルトが**Zsh**だからでした。

※MacOS CatalinaからデフォルトがZshに変更されました。
詳しくは調べてみてください。

なのでVSCodeのShellの設定をZshに変更します。

#変更手順

##Zshのパスの確認
まずはZshのパスを確認します。
ターミナルを開いて以下のコマンドを実行してください

```Bash
$ wich zsh
```

そうするとzshのパスが出力されるのでそれをコピーします。
Catalinaの初期のパスだと以下になると思われます。

```
/bin/local
```

##VSCodeの設定の編集画面の表示
次にVSCodeの設定を変更をする場所はメニューバーにある
**Code > Preferences > Settings** (英語)
**Code > 基本設定 > 設定** (日本語)
をクリックしてください

そうすると設定項目を検索できる検索バーが出てくるので以下をコピペしてください
`terminal.integrated.shell.osx`

検索して出てきた結果に表示されている
**Edit in settings.json** (英語)
**settings.jsonで編集** (日本語)
をクリックしてください。

これで以下のような色々な設定の書かれた編集画面が開きます。

```
{
・・・
色々な設定
・・・,
"terminal.integrated.shell.osx": ""
}
```

##設定の変更
先ほど開いた**settings.json**にZshに変更するための記述をしていきます。
settings.jsonの中に以下の一文があると思います。ない場合は以下の一文を追加してください！

```
"terminal.integrated.shell.osx": ""
```
これをいかのように先ほど確認したzshのパスに変更します。

```
"terminal.integrated.shell.osx": "zshのパス"
```

Catalinaの初期のパスだと以下のように変更します。

```
"terminal.integrated.shell.osx": "/bin/local"
```

これの記述ができたら**command + s**で保存をして一度VSCodeのタスクを切って再度立ち上げればshellの設定変更は完了です！
Vue.js(Typescript)でPropsに型定義する方法

Vue.jsをTypescriptで書く場合、オブジェクトをネストするような形をとることで、Propsに型定義することができます。
型定義以外にも必須項目やデフォルト値を設定することもできます。
PropTypeを忘れないよう気をつけてください

```vue.js
<script>
import Vue, { PropType } from 'vue'

export type DataType = {};
export default Vue.extend({
    name: "Sample",
    components: { RoundRectButton },
    data(): DataType {
        return {};
    },
    props: {
        target: {
            type: String as PropType<string>,,
            required: true,
            default: "ターゲット",
        },
        message: {
            type: String as PropType<string>,,
            required: true,
            default: "メッセージ",
        },
        btnText: {
            type: String as PropType<string>,,
            required: true,
            default: "ボタン",
        },
        btnColor: {
            type: String,
            required: true,
            default: "btn-main",
        },
    },
});
</script>
```
CakePHP3 リレーション関係にあるテーブルに対してバリデーションを掛けたい

# 前提
- PHP
    - 7.3.11
- CakePHP
    - v3.6.14
- MySQL
    - 5.7.26

# 0. テーブル構造
```mysql
mysql> desc users;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| id            | int(11)      | NO   | PRI | NULL    | auto_increment |
| name          | varchar(255) | NO   |     | NULL    |                |
| tel           | varchar(255) | NO   |     | NULL    |                |
| email         | varchar(255) | NO   | MUL | NULL    |                |
| created       | datetime     | NO   |     | NULL    |                |
| modified      | datetime     | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)

mysql> desc addresses;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| id            | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id       | int(11)      | NO   |     | NULL    |                |
| city          | varchar(255) | NO   |     | NULL    |                |
| building      | varchar(255) | NO   | MUL | NULL    |                |
| created       | datetime     | NO   |     | NULL    |                |
| modified      | datetime     | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)
```

# 1. 保存したいデータ
- リレーション関係のような階層構造を持った連想配列にする

```php
$data = [
	'user' => [
		'email' => 'hoge@example.com',
		'tel' => '09012345678',
		'name' => '山田太郎',
		'address' => [
			'city' => '2200011',
			'building' => '14',
			'address' => '横浜市西区高島',
			'building' => '123'
		],
	],
];

```


# 2. バリデーション
- リレーション関係のような階層構造を持った連想配列にする

```php
$validate = [
    'associated' => [
        'Addresses' => [
            'validate' => 'default',
        ],
    ],
];
```

## バリデーションクラス

```php
/**
 * Default validation rules.
 *
 * @param \Cake\Validation\Validator $validator Validator instance.
 * @return \Cake\Validation\Validator
 */
public function validationDefault(Validator $validator)
{
    $validator->notEmpty('city');
    $validator->notEmpty('building');

    return $validator;
}
```

# 3. オブジェクト生成
- 第一引数に保存したいデータを、第二引数にバリデーションを渡す

```php
$user = $this->Users->newEntity($data, $validate);
```

# 4. エラー検知
- バリデーションエラーに引っかかってる場合、以下のメソッドでエラー内容を取得することが可能
    - ```EntityTrait::getError()``` or ```EntityTrait::getErrors()```
JupyterLabにkernelを追加、削除

備忘録です。

# 追加

```bash
ipykernel install --user --name=<config-dir> --display-name=<display-name>
```
| 引数 | 説明 |
| --- | --- |
| config-dir | 設定ファイルを保存するディレクトリ名 |
| display-name | JupyterLab上で表示される名前 |

# 削除

以下のコマンドで、kernel本体のパスの一覧を表示。

```bash
jupyter kernelspec list
```

`rm`コマンドで削除。

```bash
rm -rf <kernel-path>
```
フォームオブジェクトで結びついている要素を全て初期値として表示する方法

[前提] フォームオブジェクトを使ってitemsテーブルとtagsテーブルの値を同ページで保存している。
[現状]コントローラのeditメソッドで
@item=Item.find(params[:id])と記述しているため、itemsテーブルに保存されている値の初期値のみが表示されている。ハッシュタグのフォームにも初期値を出したい。
[理想図]
![スクリーンショット 2020-09-14 23.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682043/b9362ebe-b67a-c9cf-0981-2a0daeedcfe3.png)

[方法]

```ruby:item_controller
def edit
  @item = Item.find(params[:id])
   @tag = @item.tags 
end
```
と一つの商品に紐つぐ複数タグの要素をもつ@tagを定義

```ruby:edit.html.erb

<% @tag.each do |t|%>
   <div class="weight-bold-text">
     タグ（スペースで区切って複数投稿できます）
   <%= f.text_field :tag_name, class:"items-text", id:"item- 
   tag", value:t.tag_name  %>
   </div>
 <%end%>
```
@tagという配列の中に複数のタグが入ってるので、eachメソッドで一つ一つ出す。
「t」の中のカラム名「tag_name」の値をvalue属性としてフォームの中に配置する。

以上です。
【Laravel】APIでSessionが使えなかった時の予備録

laravelでAPIでルーティングされている処理の中でSessionを呼び出そうと思ったら、
エラーになりました。。

下記が追記したAPIのルーティングファイルです。

```ruby:routes/api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});
Route::post('/api/func/', 'ApiController@cardAuth');
```
そして以下がAPIの処理になります。
今回はカード情報をrequestで取得したあと、Sessionに入れようとしました・・・

```ruby:Controllers/ApiController.php
public function cardAuth(Request $request) {

        Session::put(self::KEY_SESSION_ONE, $request->all());

        $ss_one = Session::get(self::KEY_SESSION_ONE)

        $model = new InfoForm($ss_one);

     
        〜〜 （処理） 〜〜
```

が、設定しておいたloggerを見てみると、
$ss_one内に値が設定されていないというエラーの連続。


**<font color="blue">〜〜以下からが解決方法です！〜〜</font>**
appディレクトリのKarnel.phpを見てみましょう。
デフォルトでは'api'にSessionに関する記述が書かれていません。
なので追記します。

```ruby:app/Karnel.php
　　　　　　　　　　　　　　　　　　　　　〜（中略）〜

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            \App\Http\Middleware\EncryptCookies::class, //追記
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,　//追記
            \Illuminate\Session\Middleware\StartSession::class, //追記
            \Illuminate\View\Middleware\ShareErrorsFromSession::class, //追記
            'throttle:60,1',
        ],
    ];

```

こうすればAPIルーティングされた処理の中でもSessionを使うことが可能になります！
Modelの設定だと思い込み１時間ほど悩まされました。。笑
レイテンシとは？

- 一言でいうと、**転送要求を出してから実際にデータが送られてくるまでに生じる`「通信の遅延時間」`**のこと。

- 英語のスペルは「Latency」なので、レイテンシーと語尾を伸ばす言い方もする。

- 単位は**ms(ミリ秒)**で表される。

- 遅延時間が短ければ「レイテンシが小さい(低い)」と、逆に遅延時間が長ければ「レイテンシが大きい(高い)」などという言い方をする。

- このレイテンシ以外にも、ネットワークの通信性能を評価する指標は以下のようなものがある。
 - スループット：単位時間あたりに伝送できるデータや信号の量のこと
 - パケットロス：送信したパケットのうち、途中で消失して相手に届かなかったパケットの割合を示す指標のこと


参考サイト：https://www.idcf.jp/words/latency.html
参考サイト：https://blogs.manageengine.jp/itom_what_is_latency/
Boost semantic actionについて少し調べた(2)

Boost Spiritは、parserの動作に細かいチューニングができるようになっているのが特徴である。

     1#include <iostream>
     2#include <string>
     3#include <boost/spirit.hpp>
     4using namespace std;
     5using namespace boost::spirit;
     6
     7void display( int x ) { cout << "you typed: " << x << endl; }
     8
     9struct IntDisplay : grammar<IntDisplay>
    10{
    11    template<typename ScannerT>
    12      struct definition
    13      {
    14          typedef rule<ScannerT> rule_t;
    15          rule_t r;
    16          definition( const IntDisplay& )
    17          {
    18              r = int_p[&display] % ',';
    19          }
    20          const rule_t& start() const { return r; }
    21      };
    22};
    23
    24int main()
    25{
    26    IntDisplay parser;
    27
    28    string line;
    29    while( cout<<"# ", getline(cin, line) )
    30    {
    31        parse_info<string::const_iterator> info =
    32            parse( line.begin(), line.end(), no_actions_d[parser], space_p );
    33        cout << (info.full ? "OK" : "fail") << endl;
    34    }
    35    return 0;
    36}

32行目に、no_actions_dというのがあるが、これをディレクティブと呼ぶ。

<pre>
    32            parse( line.begin(), line.end(), no_actions_d[parser], space_p );
</pre>

実行してみる。。。

<pre>
# g++ boost-semantic-action.cpp -lboost_system
# ./a.out 
# 1,2,3
OK
</pre>

つまり、18行目とかでセマンティックアクションdisplayを設定してあるが、no_actions_dによってそれを有効にしたり無効にできる。

<pre>
    18              r = int_p[&display] % ',';
</pre>
A Tour of Go メモ 【4】二日目

#A Tour of Go


#Range

```
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
	for i, a := range hiragana {
	    fmt.Printf("「%s」は、%d番目\n", a, i+1)
	}
}
> 2**0 = 1
> 2**1 = 2
> 2**2 = 4
> 2**3 = 8
> 2**4 = 16
> 2**5 = 32
> 2**6 = 64
> 2**7 = 128
> 「あ」は、1番目
> 「い」は、2番目
> 「う」は、3番目
> 「え」は、4番目
> 「お」は、5番目
```

#rangeと"_(アンダーバー)"

```
func main() {
	pow := make([]int, 10)
	for i := range pow {
		pow[i] = 1 << uint(i) // == 2**i
	}
	for _, value := range pow {
		fmt.Printf("%d\n", value)
	}
    s := "hello"
	for i, _ := range s {
	    fmt.Printf("%d回目の%s\n", i+1, s)
	}
}

> 1
> 2
> 4
> 8
> 16
> 32
> 64
> 128
> 256
> 512
> 1回目のhello
> 2回目のhello
> 3回目のhello
> 4回目のhello
> 5回目のhello
```

#Maps
make(map["keyになる値の型"]"valueになる値の型")
例えば、
・ keyも値もint型
=> make(map[int]int)
.keyも値もstring型
=> make(map[string]string)

```
type Vertex struct {
	Lat, Long float64
}

var m map[string]Vertex
//変数を定義するときにキーと値を設定できる
var n = map[string]Vertex{
    "key1" : Vertex {
        10.0, 10.000,
    },
	"key2" : Vertex {
         20.0, 20.000,	    
	},
}
var z = map[string]Vertex{
    "key1" : {333.33, 44.444},
    "key2" : {88.888, 999.999},
}

func main() {
    fmt.Println(m)
    //エラー。　初期化していないので、追加できない。
    m["insert"] = Vertex{
       11.111, 22.222,
    
    }

    fmt.Println(n)
    // 初期化
	m = make(map[string]Vertex)
	fmt.Println(m)
	//キーの追加
	m["Bell Labs"] = Vertex{
		40.68433, -74.39967,
	}
	m["test"] = Vertex{
	    22222, 2020202,
	}
 	fmt.Println(m)
	fmt.Println(m["Bell Labs"])
}

> map[]
> map[key1:{10 10} key2:{20 20}]
> map[]
> map[Bell Labs:{40.68433 -74.39967} test:{22222 2.020202e+06}]
> {40.68433 -74.39967}
```

#Mapの操作

```
func main() {
	m := make(map[string]int)

	m["Answer"] = 42
	fmt.Println(m)
    //keyを指定すると対応した要素(elem)を取得でkりう
	fmt.Println("The value:", m["Answer"])

	m["Answer"] = 48
	fmt.Println("The value:", m["Answer"])

    //要素の削除
	delete(m, "Answer")
	fmt.Println("The value:", m["Answer"])

    //keyに対応する値があるか
    //もしもkeyがあれば、対応する値がvに入る、keyがなければ、map作成時に指定した型のゼロ値が入る
    //okには、keyがあれば、true, なければfalseが入る
	v, ok := m["Answer"]
	fmt.Println("The value:", v, "Present?", ok)
}

> map[Answer:42]
> The value: 42
> The value: 48
> The value: 0
> The value: 0 Present? false

```

#関数

関数の引数に関数を渡せる

```

import (
	"fmt"
	"math"
)

//引数に関数を渡すときに渡す関数の引数と戻り値の型を書かなくてはいけない
//引数に渡された関数の引数に3,4をいれる関数
func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(5, 12))

    // hypot関数の引数に3,4をいれる
	fmt.Println(compute(hypot))
    //3の４乗を返す
	fmt.Println(compute(math.Pow))
}

> 13
> 5
> 81
```

#クロージャー
・複数の関数がセットとなり、その関数内で変数を共有できる
・オブジェクトの変数やメソッドを容易に変更できないようにカプセル化できる

```
func adder() func(int) int {
   //sumの値を維持できる
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}
```
A-FrameでCORSエラーが出た


ローカルで、A-Frameを使って360度カメラで撮った写真をウェブ上に表示させようとしたら、

```index.html
<!doctype html>
　<html>
　　<head>
　　　<meta charset="utf-8">
　　　<title>ページのタイトル</title>
     <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
　　</head>
　　<body>
　　　<a-scene>
   　    <a-sky src="pic1.jpeg" rotation="0 0 0"></a-sky>
　　　</a-scene>
　　</body>
　</html>
```

<br>
こんなエラーが出た。

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

<br>
そこで、http-serverをインストールして、ローカルホストにアクセスしたら、エラーは出ず、360度カメラの画像が表示された。

```
$ npm install -g http-server

$ http-server
```
サーバーが立ち上がったら、
http://localhost:8080/　
にアクセスする。




<br>
AWS SAAテスト対策ノート：暗記すべき数値一覧

AWSソリューションアーキテクトの勉強ノート。
**暗記すべき数値**の一覧を自分なりにまとめてみた。

関連ページ：
[【合格体験記】半年かけて確実に合格！ AWSソリューションアーキテクト合格までの道のり](https://qiita.com/Kohei-Sato-1221/items/b5a12e24cf550d64c6c9)
[AWS SAAテスト対策ノート：一問一答集＆試験に出るポイントまとめ](https://qiita.com/Kohei-Sato-1221/items/b108fa5e98dd2fba5bc9)



| カテゴリ | 内容 | 数値 |
|-----------:|------------:|:------------|
|VPC|リージョン辺りのMaxVPC数|デフォルト５（100まで緩和可）|
||VPC毎のMaxSubnet数|200|
||VPCに設定可能なCIDR範囲|/16~/28|
|ストレージ|以下のスループット(秒)・IOPS<br>a.汎用SSD<br>b.Cold HDD<br>c.スループット最適化HDD<br>d.プロビジョンドIOPS<br>e.Amazon FSx<br>f.EFS|<br>a. 250MB/16000<br>b. 250MB/250<br>c. 500MB/500<br>d. 1GB/64000<br>e. 2GB/数百万<br>f. 10GB/50万|
|EC2|スケジュールドリザーブドインスタンスの最低利用時間|年間1200時間<br><font color="red">※ 1200/365✕24≒14%</font>|
||1つのインスタンスにアタッチできるIAMロール数|1|
|RDS|自動バックアップの保持期間|35日|
|S3|STANDARDの可用性・耐久性|99.99%・99.999999999%|
||STANDARD-IAの可用性・耐久性|99.9%・99.999999999%|
||ONEZONE-IAの可用性・耐久性|99.5%・99.999999999%|
||最大ファイルサイズ|5TB|
||１回のPUTでの最大サイズ|5GB|
|S3 Glacier|最小保存期間|90日|
||「迅速」の取得時間/取り出し可能なオブジェクトの最大サイズ|1~5分/250MB|
||「標準」の取得時間|3~5時間|
||「大容量」の取得時間|5~12時間|
||最大ファイルサイズ|40TB|
|S3 Glacier Deep Archive|最小保存期間|180日|
||「標準」の取得時間|12時間以内|
||「大容量」の取得時間|48時間以内|
|ELB|デフォルトのヘルスチェック間隔|30秒|
||デフォルトのアイドルタイムアウト|60秒|
||AutoScalingのデフォルトクールダウン期間|300秒|
|Route53|デフォルトのヘルスチェック間隔|30秒|
|IAM|１アカウントで作成できるMAXユーザー数|5000|
||１アカウントで作成できるMAXグループ数|300|
||１ユーザーが所属可能なMAXグループ数|10|
|[Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html)|一時ボリュームの最大サイズ|512MB|
||最大同時実行数|1000(数十万まで引き上げ可能)|
||最大実行時間|15分|
||関数レイヤストレージ最大サイズ|75GB|
||メモリ割り当て|128MB~3,000MB|
|DynamoDB|1RCUの性能|4KBを1秒間に2回読み込み可|
||1RCUの性能（強力な整合性）|4KBを1秒間に1回読み込み可|
||1WCUの性能|1KBを1秒間に1回書き込み可|
|SQS|キューの最大サイズ|256KB(緩和して2GBまで増やせる)|
||キューのデフォルト保持期間|4日間|
||キューの最大・最小保持期間|60秒~14日|
||1APIあたりの最大メッセージ数|10|
||可視性タイムアウトデフォルト値|30秒|
|CloudWatch|メトリクスの間隔(通常)|5分間|
||メトリクスの間隔(詳細)|1分間（有料）|
||CloudWatch Logs エージェントからログデータが送信されるデフォルト間隔値|5秒|
|Kinesis|ストリームのアクセス可能時間|デフォルト24時間・最長7日間|
|タグ|キー・値の最大文字数|UTF-8で、128文字と256文字|
||１リソースがアタッチできる最大数|50|

<font color="Red">※他に覚えていたほうが良い数値があればコメント欲しいです！</font>
Vue.js使いの自分がReact + TypeScriptにコンバートするためにやったこと（まだ途中）

タイトル通りの話で, 今まで2年ちょいVue.js（含むNuxt.js）使いだった自分がReact + TypeScriptの組み合わせを覚えて仕事にしよう！...という目標に向けて何をしたかについてまとめました.

- React + TypeScriptの組み合わせでちゃんと開発したい&覚えたい人
- Vue.js等, 他のJavaScriptライブラリ・フレームワークと二刀流を目指している人
- SPA(Single Page Application)開発をちゃんとやりたい人

の参考になれば幸いです.

なおコードスニペット的なのは一切ないです.

が, これから学習する方の役に立つと嬉しいです.

# わたし（shinyorke）のJavaScript/SPA歴

- 昔から仕事や趣味⚾️開発でJavaScript, JQuery, Bootstrapは触っていました.
- JavaScriptは自力で調べながらどうにかやれます.
- 前職でVue.jsを2年近くやったのでSPAについてはそれなりに開発経験あります.
- Nuxt.jsでゼロベースからSPAを二回ほど実装・ローンチしました.
- npmとかyarnの意味はわかってます&環境もnvmで切り替えながらやれるレベルなのでそのへんのエコシステム周りは初心者ではないです（強くもないけど）.

なお, Vue.jsのときにやったネタはブログにまとめています.

https://shinyorke.hatenablog.com/entry/hello-nuxt-coreui

https://shinyorke.hatenablog.com/entry/vue-django-hateoas

https://shinyorke.hatenablog.com/entry/front-app-and-vuejs

# React + TypeScriptになれるまで

やったことを時系列で.

**なお, まだ途中です！**

## Reactの公式チュートリアル

会社のつよつよフロントできるマンたちのオススメだったので素直に乗って写経しました.

https://ja.reactjs.org/tutorial/tutorial.html

ゲーム完成まで楽勝でいきました.

構成とかどういった意味なのか?的なのをチュートリアルと書いたコードを読みながら理解.

ただ, 肝心なComponentのライフサイクルだの状態遷移だのといった所はわかったようなわかんないような🤔でした.

## 書籍を写経してSlack（っぽい）アプリを自前で実装する.

ゲームよりも実践的なアプリを作ると慣れるかな?と思い, 昔読んだ書籍をもう一度掘り返しました.

[React, Angular, Vue.js, React Nativeを使って学ぶ はじめてのフロントエンド開発](https://amzn.to/3htqbe8)

2年ちょっと前の本なのでそのままのコードで動かんやろ...という不安はあったものの, まあ自己解決できるだろっていう謎理論でそのままスタート.

## サーバーアプリを作る（写経）

本編のSlack（風）チャット・クライアントアプリを作る前に, 書籍の説明通りチャットのサーバー部分をFirebase + Expressで作りました.

これについては, ほぼ書籍通りの写経で完了. これは意外だった.

唯一, デプロイができなかったぐらいですかね. 無料プランじゃできないぞ的な（おそらく書籍リリース時はできてた）.

ただ, デプロイできなくてもローカルサーバーとして立ち上げて開発できたので別に困らなかったです.

ちなみにFirebaseをゼロから使うのは今回がはじめてでした. 思わぬ所で新しい道具を覚えた.

## 本丸のReact + TypeScript製チャット・クライアント開発

書籍を見ながらゼロから写経しました, 途中動かないとか色々ありました.

特にライブラリのバージョンがきつかった...書籍通りで動かん！と思い,

https://github.com/okachijs/jsframeworkbook/tree/master/3_6_react

こちらのpackage.jsonを見ながら調整. 

あとnodeのLTS（12系）じゃダメだったので8系に落として動かしました, この騒動で半日ほどドハマリ.

これはまあしょうがないか...

その後は順調に行きました, 型安全のJavaScriptは精神衛生上すごく良いというのがよくわかった.

# これからやりたいこと

Vue.jsで作ったやつをReact + TypeScriptで写経して本格的に慣れるとか, 今いくつか作りたいネタがあるのでそれをReact + TypeScriptでやるとか.

あと, 会社のプロダクトでいくつかReact + TypeScriptあるのでそこにコントリビュートとか考えています！
macOS High SierraでiPhoneアプリ開発はもうできない（2020年9月時点）

Macが古くなって処分するに当たり、iPhoneアプリ開発に使えるか調査する必要があったので調べました。

# 結論
できない。Catalinaが入ったMacを入手するのが良さそう

# 調査の流れ
## 対象のMac
MacBook Air (13-inch, Mid 2011) 
OSはmacOS 10.13 High Sierra
※これより新しいOSは入れられない模様

## XCodeを入れることはできるのか？→XCode10.2なら入るかも（最新はXCode11）
+ AppStoreから最新のXCodeのインストールを試みる→MacOS10.15.2（Catalina）以降でないとインストール不可
+ Developerサイトから古いXCode10.2とかを入れる方法はある模様
  + https://qiita.com/kizitorashiro/items/0ae6263dac9b2c44be5d

## XCode10.2を入れてiPhoneアプリを作ることができるとして、AppStoreで配信することはできるのか？
アプリをAppStoreにおきたいなら、この制限に引っかかるようです
> 2020年4月以降、App Storeに提出するすべてのAppはXcode 11でビルドする必要があります。Xcode11にはmacOS Mojave 10.14.3以降が必須です。

https://developer.apple.com/jp/app-store/submissions/

## というわけで結論

iPhoneアプリ開発には古いMacで良いという記事もいくつか見つけましたが、練習用ならともかく、AppStoreに置きたいなら古いMacOSはどんどん切られていきそうなので、新しめのOSのMacを買うのがいいのかもしれません。
iPhoneアプリ開発をしたいなら、Catalina対応のMacを入手するのが良さそうです。以下のURLにCatalina対応のMacの発売時期が書いてあります。
https://support.apple.com/ja-jp/HT201475

# 参考
https://i-app-tec.com/ios/xcode-install.html
https://ja.wikipedia.org/wiki/MacOS
【JavaScript, jQuery】nullとremoveメソッドを使ったif文で、click表示を１つだけに収める方法（+α　oneメソッドとの比較）

「ボタンを連打したら何個も同じメッセージが生成されてうざったい。１つだけの生成でいいのに。」
・・・この問題を解決するコード記述で詰まったので、備忘として残す。

例えば下記のような挨拶ボタンを作りたいとする。
![html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/32d1a0f1-7e29-05e0-ad94-5878c1d9b2da.png)
プレビューはこんな感じ（cssの記述は、内容と直接関係ないので割愛。）
※黒い部分はただの墨塗りです。気にしないでください。
![shoki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/d594a0fc-234c-4122-c7c9-ed153a812cc9.png)

挨拶ボタンを押すと、「こんにちは！私の名前は（以下略）」と定型文を出力するようにする。
![oomoto.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/fb69dd87-48d8-f4d8-1304-45436fbcaeb1.png)

しかし、このままだと挨拶ボタンをクリックする度にメッセージが何個も出てくる。
![dame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/f71120f1-5897-ee28-0ff7-4c0cff368359.png)

click表示（挨拶メッセージ）１つだけに収めたいので、下記のようにnullを使ったif文を関数の中に追記する。
![kairyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/2b661826-54d2-7735-cde1-99fd1d334c79.png)
つまり、if文で「あるHTML要素がすでに存在している場合（nullではない場合）」と「存在している場合（else）」の処理をそれぞれ実行できるようにする。
「!= null」は、null（不存在）ではないという意味。
その結果、何度ボタンを押してもclick表示は１つだけしか表示されない。
（正確には、「（ボタンを２回目以降押した場合は、一度既存の表示を削除（remove）し、あらたに生成(append,text）」している。）
![okay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698990/4d8c42ea-d4ed-1f12-65a9-3aaec5a11bc9.png)

「挨拶ボタンのclickイベントを１回だけしか実行させない。」という目的だけを実現するのであれば、oneメソッドを使った方が簡素な記述で済む。
例）

```js
$("#btn-greeting").one("click",function() {
 $("#greeting").text(greeting());
});
```
今回のように、決まった定型文を出力する場合はこれでもよい。
しかし、「10歳の田中太郎」以外も挨拶ボタンを使いたい場合、つまり挨拶文の内容（名前や年齢）を変更し、ボタンを押すことで更新（再表示）するようなプログラムを作成したい場合は、oneメソッドでは融通が利かないため、前述のif文が有効である。