OmniAICreator/Qiita-1.07M huggingface dataset:
Mesa 21.3 RADV で AMD GPU で Vukan レイトレするメモ

Mesa 21.3(2021/11/17 release)で AMD GPU(RADV backend)で, 悲願の Vulkan レイトレ拡張が使えるようになりました.

https://docs.mesa3d.org/relnotes/21.3.0.html

ちなみに AMD GPU 向けの Vulkan ドライバは知る限り以下の 3 つがあります.

* RADV: Mesa の Radeon Vulkan backend. コミュニティ開発? それなりによい. 21.3 からレイトレ拡張対応(experimental. Polaris など古い GPU も emulation で対応)
* AMDVLK: https://github.com/GPUOpen-Drivers/AMDVLK AMD が出している OSS Vulkan ドライバ. レイトレ拡張非対応. 開発もあまりされていないようで, なんのためにあるかあまり良くわからない(Linux とかでとりあえず最低限 Vulkan 動かすとき用?)
* amdgpu-pro: https://amdgpu-install.readthedocs.io/en/latest/install-script.html#installation-vulkan-optional-component プロプライエタリなドライバ. RDNA2 以降ではレイトレ拡張対応だが, それ以前では未対応

  
## 環境

* Ubuntu 20.04 
* amdgpu ドライバ 21.40(OSS stack のみ(デフォルトの設定でインストールされるもの))
* RX6800

## ビルドする

RADV で最新 Vulkan を使うため, Mesa をコンパイルするメモ
https://qiita.com/syoyo/items/9b98a3124ce47065453f

を参考にビルドください.
いずれは ubuntu などで apt で入るようになるでしょう.

## 使う

そのままではレイトレ拡張出てきません.
オフィシャルにはどう使えばいいのかの十分なドキュメントがないです...
環境変数で `RADV_PERFTEST=rt` を指定する必要があります.

https://docs.mesa3d.org/envvars.html?highlight=radv

また, ソースコード見ると llvm backend が有効だと動きません(RADV 使う時点で llvm backend は使っていなさそうであるが...)

```
$ RADV_PERFTEST=rt vulkaninfo
```

で, `VK_KHR_ray_tracing` 出れば成功です!


Sascha 先生の Vulkan サンプルを動かしてみます.

https://github.com/SaschaWillems/Vulkan

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Mesa 21.3 RADV + RX6800 Vulkan ray tracing, finally !!!!!!!🍾🍾🍾🍾㊗️㊗️㊗️㊗️㊗️🎉🎉🎉🎉🎉🎉🎉 (set envvar RADV_PERFTEST=rt) demo from <a href="https://twitter.com/SaschaWillems2?ref_src=twsrc%5Etfw">@SaschaWillems2</a> &#39;s super awesome Vulkan examples 🙏 <a href="https://t.co/g2DkpMI1CF">pic.twitter.com/g2DkpMI1CF</a></p>&mdash; Syoyo Fujita 🌸 レイトラ ® 🐯 3 周年 🎉 (@syoyo) <a href="https://twitter.com/syoyo/status/1461657456828764163?ref_src=twsrc%5Etfw">November 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

Ultra super coooooooooooll!!!!!! :tada: :tada:

ただ, vulkan shadows demo はあんまり性能出ませんでした. indirect ray みたいなのはまだ SW 処理なのか, HW 的に性能出ないのかもしれません.

## Mesa RADV 利点

* Full(?) OSS スタックで動く(はず).
  * ドライバは amdgpu(OSS), その上に RADV(Mesa OSS)のため
* マイニングファーム, データセンターでレイトレ動かし放題(ちなみに amdgpu-pro 自体はデータセンター利用禁止していない)
  * マイニングしつつ, レイトレしたいときにレイトレするなど可能になる
  * レイトレできずマイニングに酷使されていた Polaris, Vega ちゃんがついに解放できる...かも :thinking:
  
## 欠点

* まだ experimental
* RDNA2 では BVH トラバースだけ HW 化(それも image(texture) unit を使って実現でちょっとしょぼい感がある)なので, vulkan shadows demo のように, シーンによってはすごい性能が出ない状態になるようです.
  * RDNA2 以降の GPU 使っており, レイトレ性能を求めるのであればしばらくは amdgpu-pro でもいいかもしれません.  
* Intel DG 出てきて Vulkan レイトレ性能良かったらどうなるか...
<Java学習中>型について

今回は前回に引き続き、型についてもう少し深くメモっておきたいと思います。


型には種類があり、宣言した型に沿うデータにしか対応できない点。基本的には整数、実数、文字、論理の４つを使用します。

型は上の４つだけではなく、実は細かく分類されています。
整数型といえばint型を真っ先に思いつきましたが、扱う数の範囲によって細かく分けられていました。
・byte  : -128 ～ 127
・short : -3,2768 ～ 32767
・int   : -2,147,483,648 ～ 2,147,183,647
・long  : -9,223,372,036,854,775,808 ～ 9,223,372,036,854,775,807

byteやshortは数が少ない感じがするし、longは数が大きすぎて何を想定してるんだって印象を受けます。
こう考えるとintがちょうどよいサイズって感じしますね。よく見かけるのも勝手に納得しました。

整数以外を取り扱う型も存在します。主に小数を利用する目的の型が、

float   :±1.40239846×10^-45～±3.40282347×10^38
double  :±4.94065645841246544×10^-324～±1.79769313486231570×10^308

かなり精密な計算結果が出そうな小数点以下の桁数まで出してくれそうですね。これも普段はfloatで良さそう。

文字を扱う型として、

char  : Unicode準拠

があります。Unicodeという文字コード規格があり、一文字を0 ～ 65535の範囲の数字で表したものです。

文字を扱うと聞いてよく聞くStringはどうなるのかというと、char型は一文字を表すものに対し、Stringは0文字以上の文字が集まったモノです。お互いに扱っているモノは似ていますが、お互いに代入しようとしてもエラーが出ます。


最後にboolean型と呼ばれる。論理を扱うための型。
これは、boolean型というデータ型にtrue(真)かfalse(偽)のどちらかのデータが入ることを指します。この２つ以外のデータは入らないようになっています。

基本の４つの型に加えて、変数の初期化した時の値が明らかな場合、型推論による変数宣言が出来ます。
これは何かと言うと、プログラマが型を明示しなくてもコンパイラがどの型に当てはまるのか判断してくれることをいいます。

その時に使うのが、var　という型です。
宣言でこれを使うと、

```java
class Sengen{
      public static void main(String[] args){
         var num = 123;
         var num2 = 3.14;
         var num3 = "Hello World";

         System.Out.println(num);
         System.Out.println(num1);
         System.Out.println(num2);
     }
}
```
```text:実行結果
123
3.14
Hello World
```

全て型は var で統一されていますが、var型を使用することで代入されたデータから、どの型が相応しいか推論して適切な形で表示してくれます。

実行結果は本来の型を使用した時と同じ出力結果で、本来の型を使用して宣言したのと同じ扱いになります。
例えば一つ目の結果　123　は　int num = 123;　と入力したのと同じです。


今日はここまでとします。
何か間違ってましたらツッコミお願いいたします。
Next.js v12+TypeScriptでプロジェクトの雛形を生成する

この投稿ではNext.js v12 + TypeScriptのプロジェクトの雛形を生成するまでの流れを簡潔に説明します。

## 要件

- Node.js 12.22.0以上の環境が必要

## プロジェクトの雛形を生成する

`npm`コマンドまたは`yarn`コマンドでプロジェクトの雛形を生成します。

```sh
npx create-next-app@latest
# または
yarn create next-app --typescript
```

プロジェクト名を聞かれるので、適当に名前をつけます。

このコマンドを実行すると必要なパッケージのインストールも行われます。

## 開発サーバーを起動する

雛形が生成されたら開発サーバーを起動します。開発サーバーの起動は`yarn dev`コマンドです。

```sh
cd my-app
yarn dev
```

最後に`http://localhost:3000`にアクセスし、次の図のようなWelcomeページが表示されていれば、雛形の生成は完了です。

![20211119_201232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/2f3fc5f3-283c-9416-b87e-021122f0405f.png)
ElastiCache接続不可の場合の切り分け

アプリから接続エラーのExceptionが出てしまった時の切り分け方法について。

##1.イベントログを確認する

AWSマネージメントコンソールでElasticacheのページから「イベント」を確認。
例えばフェイルオーバー発生の場合下記のように表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469267/830b8630-0bba-c47a-aa61-3c9814e498ac.png)

##2.Personal Health Dashboardを確認
ここから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469267/ecbcbb28-2a02-82e1-8e72-295da99d5dfd.png)
**Personal Health Dashboardで表示されるのは下記のみ**
・サービス系で一定時間継続している障害で復旧目処が経っていないもの
・計画メンテ（短期）
・計画メンテ（中長期）

その為各リソース側の短時間の障害、フェールオーバーは表示されない

##まとめ

1、2両方とも該当するイベントがないパターン：瞬断と捉える
1、2どちらかに表示があるパターン：イベントの内容を見て判断
[GCP] Compute Engine の Linux 仮想マシンを作成について

# はじめに
GCP(Google Cloud Platform)に興味があってイジってみたので忘却録。
Compute Engine で Linux 仮想マシンを作成するまで。

## Cloud プロジェクトで Compute Engine を有効にする
Compute Engine を有効にするには、Cloud プロジェクトを選択し、Compute Engine に必要な API を有効にします。

- プロジェクトの選択
- Compute Engine APIを有効にする

![ 2021-11-19 16.58.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/1f113415-6f60-a320-82eb-4fb2af613d0d.png)


## Ubuntu VM インスタンスを作成する
- Cloud Console のナビゲーション メニューで、[Compute Engine] > [VM インスタンス] をクリックします。 
- 次のボタンをクリックすると、場所を確認できます。
![ 2021-11-19 16.58.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/528a4666-5d39-f14a-3b0a-77eda9036f84.png)

- [インスタンスを作成] をクリックします。
- 後で新しいインスタンスを確認できるように、インスタンス名をメモしておきます。
![ 2021-11-19 16.58.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/39f2af61-d61c-857b-4a5b-dce0d3dc6b60.png)
![ 2021-11-19 16.58.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/a4b650e6-20a4-465c-b347-077a1584533d.png)

- [ブートディスク] セクションで、[変更] をクリックします。
 ![ 2021-11-19 17.11.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/179c61fb-efdf-60b9-ece3-b9f9bfc7f5cc.png)

- [公開イメージ] タブで、次の設定を変更します。
    - [オペレーティング システム] を [Ubuntu] にします
    - [バージョン] を [Ubuntu 20.04 LTS] にします
- [選択] をクリックします。
![ 2021-11-19 17.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/ea322f8f-8c3c-b16f-5107-2055a5c7c28f.png)
![ 2021-11-19 17.12.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/22781c74-06c7-3398-1ca7-e90e9301658d.png)

- [ファイアウォール] セクションで [HTTP トラフィックを許可する] を選択します。
- [作成] をクリックして VM インスタンスを生成します。
![ 2021-11-19 17.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/a4673629-16e0-de28-aee3-78740e69b76f.png)

- [VM インスタンス] ページに新しいインスタンスが表示されます。チェックマークが表示されたら、インスタンスに接続できます。
![ 2021-11-19 17.13.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/b4687571-41bd-27c9-8ae2-1071ad63cbd9.png)
![ 2021-11-19 17.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/2a3e30cb-9f41-a0a3-f1ff-812c90644ba8.png)

## VM インスタンスに接続する

- [VM インスタンス] ページの [名前] 列で、作成した VM インスタンスを見つけます。
- VM インスタンスの [接続] 列で、[SSH] をクリックします。
![ 2021-11-19 17.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/75ef9154-143e-bf12-1e5b-0fcdf4da3284.png)

- 新しい cmd ウィンドウが開き、VM ターミナルに接続したことが示されます。
![ 2021-11-19 17.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/e24a63ac-010c-6af9-eb17-1dea8134fb28.png)
![ 2021-11-19 17.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/c8edcda0-fc25-690c-ce7f-7cbe1cc34991.png)

これで、Compute Engine で VM インスタンスを正常に作成して、そのインスタンスに接続しました。
Elasticsearch 6ではindex定義に'_type'が必要

Elasticsearch 7以上の場合はindexのmapping定義の`_types`

# 環境

Docker環境で以下の時

- Elasticsearch 6.8.20
- kibana 6.8.20
- PHP7

```yml:docker-compose.yml

version: '3'
services:
  # 省略...
  es:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.20
    environment:
        - discovery.type=single-node
        - cluster.name=docker-cluster
        - bootstrap.memory_lock=true
        - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
        - "9200:9200"
    volumes:
        - es-data:/usr/share/elasticsearch/data
  kibana:
    image: docker.elastic.co/kibana/kibana:6.8.20
    ports:
        - "5601:5601"
    environment:
      ELASTICSEARCH_HOSTS: http://es:9200

  # 省略...

volumes:
  es-data:

  # 省略...

```

# 問題

```bash
In Connection.php line 636:
                                                                                                   
  {"error":{"root_cause":[{"type":"action_request_validation_exception","reason":"Validation Fail  
  ed: 1: type is missing;2: type is missing;3: type is missing;4: type is missing;5: type is miss  
  ing;6: type is missing;7: type is missing;8: type is missing;9: type is missing;10: type is mis  
  sing;11: type is missing;12: type is missing;13: type is missing;14: type is missing;15: type i  
  s missing;16: type is missing;17: type is missing;18: type is missing;19: type is missing;20: t  
  ype is missing;21: type is missing;22: type is missing;23: type is missing;24: type is missing;  
  25: type is missing;26: type is missing;27: type is missing;28: type is missing;29: type is mis  
  sing;30: type is missing;31: type is missing;32: type is missing;33: type is missing;34: type i  
  s missing;35: type is missing;36: type is missing;37: type is missing;38: type is missing;39: t  
  ype is missing;40: type is missing;41: type is missing;42: type is missing;43: type is missing;  
  44: type is missing;45: type is missing;46:

...

```

上記が出る

# 解決法

Elasticsearch 6以下では `_type`の記述が必要なので下記のように書いておく。


```php

// 一例です

    public function index(int $id): array
    {
        return [
            'index' => [
                '_index' => 'index_name',
                '_type' => 'index_type',
                '_id' => $id,
            ],
        ];
    }
```

# 補足

Elasticsearch 7以降ではタイプレスAPIとして`_type`がデフォルトで`_doc`に設定されるようなので、指定は不要。

https://www.elastic.co/jp/blog/moving-from-types-to-typeless-apis-in-elasticsearch-7-0
pythonのglobal変数について

pythonで下のように書いたとき、エラーが発生した。

```python
def foo():
    a+=1
    return 

def main():
    global a
    a=0
    foo()

main()
```

```terminal
UnboundLocalError: local variable 'loadIndex' referenced before assignment
```
..ん？グローバル変数で定義してるんだけど？

調べてみたら、pythonのglobal宣言は、そのスコープの中においてaをglobal変数として扱う、ということらしい。
つまり、fooのローカルスコープから参照したときにaはローカルスコープから探し出される。
よって、foo内でaを参照したければ、foo内でもglobal宣言してあげる必要があるってこと。

```python
def foo():
    global a
    a+=1
    return 

def main():
    global a
    foo()

main()
```

こう書けば大丈夫。

下の記事がpythonのスコープについてわかりやすい。
https://pouhon.net/python-scope/2236/

## クラスインスタンスの場合
先程はint型の変数で実験を行ったが、こんどはクラスインスタンスについて同じことを行ってみる。
```python
class B():
    def __init__(self) -> None:
        self.b=0
    
    def add(self):
        self.b+=1

b=B()

def foo():
    b.add()
    return 

def main():
    foo()
    foo()
    print(b.b)

main()
```
以下出力
```terminal
2
```
今度はfoo内で global b としなくてもエラーが発生しなかった。
おそらく、変数への代入行為を行うとその時点でローカルスコープが発生するんだと思う。詳しく調べたら書きます。
【Kaggle】 New Notebookの位置

#New Notebookってどこ？？
Kaggleに挑戦したのですが...

<img width="700" alt="2021-11-19 18.36.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295160/a79193f5-1ed9-6a6c-13e0-926394e7a774.png">

New Notebookってでてこない！
どうして？

#Code選択時にNew Notebookになりました

<img width="700" alt="2021-11-19 18.36.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295160/0b779b8c-07ae-5251-f53d-69688926a4b7.png">

出てきました.2,3年前のページとはレイアウトが変わっているようです.

#おわり
これだけです.こんなことで迷ってしまいますが,頑張ります.
実務で良く使うChatworkの装飾タグたち

本当は僕はSlackが大好きですが、Chatworkを実務で使う機会が増えてきたのでChatworkの使い方をまとめておく。
実務で使ってはいるが、やはりSlackの方がなんというか直感的だし、Markdownっぽく記述することができるからSlackが好き。
Chatworkさんごめんなさい。

## Chatworkで使える装飾タグたち
### info
```
[info]
TODO
・あ
・い
・う
[/info]
```
![スクリーンショット 2021-11-19 18.30.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/0a7e4369-d9b3-3928-fe7c-55577d9e04b5.png)
こんな感じに表示される。

### title
```
[info]
[title]TODO[/title]
・あ
・い
・う
[/info]
```
infoの中に[title][/title]を追加すると
![スクリーンショット 2021-11-19 18.32.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/e878cfe7-d9ba-cea1-5d50-22c26b18cf6c.png)
こんな感じで、タイトルを目立たせることができる。

### hr
```
[info]
[title]TODO[/title]
・あ
・い
・う
[hr]
ゴリラになりたい。
[/info]
```
infoの中に[hr]を追加すると、罫線を入れることができる。
![スクリーンショット 2021-11-19 18.35.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/e58e04b7-4e29-c2c1-bad1-ecec1c075703.png)

### ソースコードを共有したいとき code
```
[code]
[code]
<h1>ゴリラになるためには</h1>
<h2>ゴリラになりたい理由</h2>
<div class="gorira">
　 <p>本当はゴリラになんかなりたくない。</p>
</div
[/code]
```
Chatworkではこのように、[code][/code]の中にソースコードを記述して共有することでインデントを崩さず共有することができる。
![スクリーンショット 2021-11-19 18.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/f79ae321-a951-e0f2-0d9f-3aba4b5d1fec.png)

## まとめ
だいたいこのタグたちを覚えていれば戦っていける。
その他、絵文字などもあるらしいけどもし興味があるなら自分でググってください。

僕はSlackが大好きです。
【JavaScript】非同期処理④　Promiseチェーン


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/f38e7583b7e06e8c23e6

#目的

* 非同期処理についての理解を深める

#本題
###1.Promiseチェーン

PromiseチェーンとはPromiseを使って非同期処理を順次実行すること。

####例1

Promiseを使って可読性を上げる

```js
function sleep(callback, val) {
  setTimeout(function() {
    console.log(val++);
    callback(val);
  }, 1000);
}
````
これをPromiseチェーンを使って書くと以下の通りとなる

````js
function sleep(val) {
  // sleepに値が返却されるようにreturnを使う
  // Promiseの中でsetTimeoutを使う
  return new Promise(function(resolve){
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, 1000);
  });
}

// sleepのvalを実行
// sleepにresolveの値が入っているのでthenメソッドを使ってコールバック関数を追加
sleep(0).then(function(val){
  //Promiseのチェーンを繋げる
  // Promiseのインスタンスを使ってPromiseをチェーンする
  // 1秒ごとに1,2,と出力される
  return sleep(val);
}).then(function(val){
  return sleep(val);
}).then(function(val){
  return sleep(val);
}).then(function(val){
  return sleep(val);
})
`````




今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
* [Let'sプログラミング JavaScript入門](https://www.javadrive.jp/javascript/)
React（Next.js/GraphQL）からHasuraを使ったCRUD操作のブラウザ側の検証

## はじめに

CRUD操作のための処理部分をこれまで作成してきました。

詳細👇

https://qiita.com/ryosuketter/items/d9106135dd81bee3c038

今回は、完成した機能をブラウザやHasuraを確認して検証していきます。

前回まで作成していたのは以下で確認できます。

https://qiita.com/ryosuketter/items/49a6ce5c1791d090381b


## 最終的なゴール

以下のような構成のアプリを作ることです。

![スクリーンショット 2021-10-18 17.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/e8a9a2e1-2723-4fec-77ef-be3b9eefdd81.png)

### 目的

- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上

## 検証

動作を確認していきましょう

CRUDのうち、以下を確認していきます。

- C: 新規作成
- U: 更新
- D: 削除

### 新規作成

![6580e906622f9343ff087b534193348a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/afc7f5e5-99c0-44e3-4452-f7baa8abd949.gif)

#### Request Data

`CREATE_USER`が実行されていそうですね。

```json
{
   "operationName":"CreateUser",
   "variables":{
      "name":"check"
   },
   "query":"mutation CreateUser($name: String!) {\n  insert_users_one(object: {name: $name}) {\n    id\n    name\n    created_at\n    __typename\n  }\n}\n"
}
```

#### Hasura

データの新規作成を確認

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/676cac41-a9fd-280d-1bee-ce4841968028.png)

### 更新

新規作成したデータを更新してみます。

![772cd70d817cabdfbbb8f15e2e372304.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/ad8c4d1f-a7cc-0431-a87d-324efbcaeca9.gif)

#### Request Data

`UPDATE_USER`が実行されていそうですね。

```json
{
   "operationName":"UpdateUser",
   "variables":{
      "id":"876673a4-b215-4c1b-b6dc-eef9ab529609",
      "name":"check 2"
   },
   "query":"mutation UpdateUser($id: uuid!, $name: String!) {\n  update_users_by_pk(pk_columns: {id: $id}, _set: {name: $name}) {\n    id\n    name\n    created_at\n    __typename\n  }\n}\n"
}
```

#### Hasura

データの更新を確認

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/6979af86-d899-44e8-3e2e-085a17b3b17a.png)

### 削除

更新したデータを削除してみます。

![be0c1de0358b21f4a37d217383a0cfaf.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/60e9ea53-38e2-92e1-22ed-f9a61ad7d772.gif)

#### Request Data

`DELETE_USER`が実行されていそうですね。

```json
{
   "operationName":"DeleteUser",
   "variables":{
      "id":"876673a4-b215-4c1b-b6dc-eef9ab529609"
   },
   "query":"mutation DeleteUser($id: uuid!) {\n  delete_users_by_pk(id: $id) {\n    id\n    name\n    created_at\n    __typename\n  }\n}\n"
}
```

#### Hasura

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/05ba5585-6052-253e-51fc-b12967349e84.png)

データが削除されたことを確認

今日のところは以上です。

## 最後に

これで、React（Next.js/GraphQL）からHasuraを使ったCRUD操作は以上です！

次回は、SGとISRをapolloクライアントとHasuraと連携を見ていきます。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
Athenaを使ってCloudTrailログを検索する〜パーティション追加

#１、Athenaテーブルを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/191af266-c872-b44d-4b0b-fcfde2749f72.png)

ここで場所を指定して直接作成するか、SQLをコピーしてAthenaで作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/c06e44c6-b311-7a09-cebd-41ec3cbc95e2.png)

今回はパーティションを追加するため、SQLをコピーして、パーティションを追加してAthenaで作成する

```SQL:create_table.sql
CREATE EXTERNAL TABLE cloudtrail_logs_aws_service_log (
    eventVersion STRING,
    userIdentity STRUCT<
        type: STRING,
        principalId: STRING,
        arn: STRING,
        accountId: STRING,
        invokedBy: STRING,
        accessKeyId: STRING,
        userName: STRING,
        sessionContext: STRUCT<
            attributes: STRUCT<
                mfaAuthenticated: STRING,
                creationDate: STRING>,
            sessionIssuer: STRUCT<
                type: STRING,
                principalId: STRING,
                arn: STRING,
                accountId: STRING,
                userName: STRING>>>,
    eventTime STRING,
    eventSource STRING,
    eventName STRING,
    awsRegion STRING,
    sourceIpAddress STRING,
    userAgent STRING,
    errorCode STRING,
    errorMessage STRING,
    requestParameters STRING,
    responseElements STRING,
    additionalEventData STRING,
    requestId STRING,
    eventId STRING,
    resources ARRAY<STRUCT<
        arn: STRING,
        accountId: STRING,
        type: STRING>>,
    eventType STRING,
    apiVersion STRING,
    readOnly STRING,
    recipientAccountId STRING,
    serviceEventDetails STRING,
    sharedEventID STRING,
    vpcEndpointId STRING
)
COMMENT 'CloudTrail table for aws-service-log bucket'
PARTITIONED BY(region string, year string, month string) #パーティション
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://<BUCKET-NAME>/AWSLogs/<account-id>/CloudTrail/'
TBLPROPERTIES ('classification'='cloudtrail');
```
完了したらパーティションが確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/625e066b-1a64-fef5-8c5c-1fc130ef41b7.png)

#２、パーティションをロードする
下記のコマンドを実行し、データを全部ロードする

```SQL:load_all_data.sql
MSCK REPAIR TABLE <table-name>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/e440250b-e348-3c87-2ec9-2c82d2199104.png)

全部ロードしたくない場合は下記のコマンドで指定するパーティションをロードする

```SQL:load_data.sql
ALTER TABLE <table-name> 
ADD PARTITION (region='ap-northeast-1', year='2021', month='10') 
location 's3://<BUCKET-NAME>/AWSLogs/<account-id>/CloudTrail/ap-northeast-1/2021/10/'
```

#３、ログを検索する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/269206a9-b8ca-6881-2ff7-d8f470dfe391.png)
RailsでON句を綺麗に書きたい

# 目的
ActiveRecordで、(WHERE句でなく)ON句で絞り込んでからテーブルをJOINしたいが、ON句用のメソッドがない。
できるだけActiveRecordっぽく、綺麗に書きたい。

# 結論
テーブルをJOINする`.join()`の直後に、`.join("AND ...")`でON句は直書きする。

```ruby
Sample.joins(:users) # usersテーブルをJOIN
      .joins("AND users.type = #{User::USERTYPE_COOK}") # 調理師（ON句）
      .where(users: {id: params[:user_id]} )
```
```
SELECT `samples`.* 
FROM `samples` 
INNER JOIN `users` 
  ON `users`.`id` = `samples`.`user_id`
  AND users.type = "cook"
WHERE `users`.`id` = 1
;
```

# 備考
`.merge()`を試したがダメだった。
STM32L010とACM1602K(キャラクター液晶)で「HELLO ...」を表示(VSCのcubeide)3


x 原因は、わからないが液晶がちらつく場合は、ウェートを調整してね!!

x cubeideは、初心者ころしである。
x MXは、動ないと思っていた　初心者にトラブルの自己解決は、不可能?
x VSCでnecleo-l011を選択
x 動けば正義、細かい事を気にするな
x STM32L010F4P6との違い、ピン数、内部温度センサー、コンパレータ
x いつも、動くと思うなよ(バクや頻繁なアップデートの為)
x 改造 PB3->PB1 , PA15 -> PA3
x 74hc164を使用

目的
GPIOのテスト




主なプログラム(後は、めんどいので省略、各自、自習の事)(main)



```c++



    //GPIOの初期化
    DW(en,GPIO_PIN_RESET);     //ビットが0 
    DW(swdclk,GPIO_PIN_RESET); //ビットが0 

    //液晶の初期化
    for(int ii=0;ii<8;ii++){ 
        seg1( lcd_int[ii] , 0);HAL_Delay(2);
    }//for

    //画面クリア
    seg1(   0x01  , 0  ); 
    HAL_Delay(1000);

    seg1( 0x80+0x00 , 0  ); //1ライン目にカーソルを移動
    ns_printf("Hello World !");HAL_Delay(500); //debug




```


mainの外


```c++





#define swdclk GPIO_PIN_5   //A4
#define swdio  GPIO_PIN_7   //A6
#define en     GPIO_PIN_4   //A3

#define DW(AAA,BBB)  HAL_GPIO_WritePin(GPIOA,AAA,BBB)

GPIO_PinState bi1[]={GPIO_PIN_RESET,GPIO_PIN_SET};

//1文字送信
void seg1(char v,int rs)
{
    for(int jj=0;jj<8;jj++){
        if( (v<<jj) & 0x80 ){
                DW(swdio,GPIO_PIN_SET);   //ビットが1 
        } else {
                DW(swdio,GPIO_PIN_RESET); //ビットが0
        }//endif
        DW(swdclk,GPIO_PIN_SET);DW(swdclk,GPIO_PIN_RESET); //clk
    }//for
    DW(swdio, bi1[rs] );
    DW(en,GPIO_PIN_SET);   HAL_Delay(1); //ビットが1 
    DW(en,GPIO_PIN_RESET);               //ビットが0      
}//seg1

//文字列の表示 nana_seg
int ns_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        seg1( *str1 ++ , 1  );

    } //while

    //戻り値
    return(0);
}//ns_printf

//液晶初期化配列
int lcd_int[]={
  0x30,0x30,0x30,0x38,0x08,0x01,0x06,0x08+0x04
};//lcd_init






```



LCD_ACM1602K_HELLO_010_1内をいろいろ適当にコピー




https://os.mbed.com/users/caa45040/code/f303_h_p1/


いろいろ(かつてに応援)(白熊くん)(どっかの高専)
モーターコントローラーを作っているみたい(また燃えたみたい)


https://shirokuma-89.github.io/


白熊くんがSTM32L010F4P6でVSC,CubIDEの環境で開発をやっていると言うので
かるく試してみました。
ここまで来れるかな「ふっふっふ」(まじで難しいぞ!!)
AWSサーバー　発行された証明書は失効しています エラーの対策

#Postgres11にアップデートする時下記エラーが発生しまた。
下記コマンドを実行する

    sudo wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

エラーが発生しました。

    --2021-11-11 18:48:48--  https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
    download.postgresql.org (download.postgresql.org) をDNSに問いあわせています... 72.32.157.246, 217.196.149.55, 147.75.85.69, ...
    download.postgresql.org (download.postgresql.org)|72.32.157.246|:443 に接続しています... 接続しました。
    エラー: download.postgresql.org の証明書(発行者: `/C=US/O=Let\'s Encrypt/CN=R3')の検証に失敗しました:
    発行された証明書は失効しています。
    download.postgresql.org に安全の確認をしないで接続するには、`--no-check-certificate' を使ってください。

#解決方法
この問題は、OpenSSL パッケージの最近のリリースに伴い Ubuntu 16.04 で修正されています。Amazon Linux と Red Hat は、期限切れの証明書を拒否する新しい CA 証明書パッケージもリリースしました。

##Amazon Linux 1

    sudo yum install https://cdn.amazonlinux.com/patch/ca-certificates-update-2021-09-30/ca-certificates-2018.2.22-65.1.24.amzn1.noarch.rpm
##Amazon Linux 2

    sudo yum install https://cdn.amazonlinux.com/patch/ca-certificates-update-2021-09-30/ca-certificates-2021.2.50-72.amzn2.0.1.noarch.rpm
プログラマになれ!プログラミング学習のWebサイト5選

　ソフトウェア開発は急速に発展する分野です。プログラミング技術も絶えず更新されています。この文章で、ベスト5のプログラミング学習サイトを集めました。プログラミングは絶えず勉強しなければなりません！
##1.One Month
　「1か月でプログラミング言語を学ぶにはどうすればよいですか？」と質問された場合は、必ずこのWebサイトを確認してください。このプログラミングWebサイトは、ジュニアプログラマーがJS、Python、Rubyの基本概念をすばやく習得するのに役立ちます。残念ながら、提供されたほとんどのコースは有料ですが、無料のコースがいくつかあります。また、プログラミングの最新ニュースについて説明しているブログもあります。
**リンク：https://onemonth.com/**
![1. One Month.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/e5cef781-8d5f-997b-3a2d-d6e2f1d4a98d.png)
##2.PluralSight
　Pluralsightのコースは、入門から上級まで、すべての一般的なプログラミング言語とデータサイエンスの基礎を含まれています。コースの幅が広く、上級開発者向けのコースもあります。
**リンク：https://www.pluralsight.com/codeschool**
![2.luralSight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/60c31e02-f236-d803-c811-6ed6bca71ff7.png)
##3.Coursera
　このWebサイトは、コンピュータサイエンス専攻の強力なリソースであり、スタンフォード大学、ミシガン大学、およびその他の学校からコースを学ぶために使用できます。このプラットフォームが注目しているのは、実践の理念ではなく、大学レベルの深く研究することです。これは、CSおよびプログラミングの学生にとって学ぶ価値のあるリソースです。
**リンク：https://ja.coursera.org/**
![3.Coursera.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/c7453026-30fa-f479-6cee-783c2e1cc20b.png)
##4.Udemy
　Udemyは、ほとんどのプログラミング言語コースを提供する主要なオンライン教育プラットフォームです。ユーザー層もかなり大きいです。授業は有料と無料に分かれています。これは講師によって決められます。価格は10ドルから数百ドルまでです。自分のペースで学習材料を得ることができます。
**リンク：https://www.udemy.com/ja/**
![4.Udemy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/bb4c4488-706e-0226-45e4-03f68b445ff9.png)
##5.Codewars
　Codewarsはコードトレーニングサイトで、プログラマー、特にプログラミング初心者の論理的思考能力を育成することができます。壁の階段を作る方式により、プログラミングにもっと興味を持つようになります。そのコミュニティも注目に値します。ここでは多くのプログラマーを悩ませている問題や、他の人が解決策を教えてくれます。
**リンク：https://www.codewars.com/**
![5.Codewars.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/05b7f493-005e-f38e-4e25-77424ab7e89f.png)
caffe公式のdockerfile(GPU)を動くようにする

# はじめに
諸事情でcaffeのGPU対応版が必要になった．GPU対応のものがビルドされていないのと，対応OSが普段使っていないubuntu16ということもあり，Dockerを使って環境構築をしてみた．この記事は```docker build``` の合間に書いているので，もしかしたらうまくいかないことも出てくるかもしれない．

（この記事は2021/11/18現在のものである．十分注意すること．）

# 問題点
公式で発行している[DockerFile](https://github.com/BVLC/caffe/blob/master/docker/gpu/Dockerfile)がpipを使用している．しかしこのpipのバージョンは古いので```pip update```が通らない様子．

# 解決
curlかwgetか何かで比較的新しいpipを持ってきてあげることにする．Dockerfileは下記．今回はNCCLはcaffeのビルドに含めない．ビルドするとpython2.7関係でwarningの表示が出るので，重大なエラーを吐いていないか用心深く確認した方がよい．





## Docker File
```` Dockerfile
FROM nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04
LABEL maintainer caffe-maint@googlegroups.com

RUN apt-get update && apt-get install -y --no-install-recommends \
        curl \
        build-essential \
        cmake \
        git \
        wget \
        libatlas-base-dev \
        libboost-all-dev \
        libgflags-dev \
        libgoogle-glog-dev \
        libhdf5-serial-dev \
        libleveldb-dev \
        liblmdb-dev \
        libopencv-dev \
        libprotobuf-dev \
        libsnappy-dev \
        protobuf-compiler \
        python-dev \
        python-numpy \
        python-pip \
        python-setuptools \
        python-scipy && \
    rm -rf /var/lib/apt/lists/*

ENV CAFFE_ROOT=/opt/caffe
WORKDIR $CAFFE_ROOT

ENV CLONE_TAG=1.0

RUN git clone -b ${CLONE_TAG} --depth 1 https://github.com/BVLC/caffe.git . && \
    curl -O https://files.pythonhosted.org/packages/27/79/8a850fe3496446ff0d584327ae44e7500daf6764ca1a382d2d02789accf7/pip-20.3.4-py2.py3-none-any.whl && \
    python pip-20.3.4-py2.py3-none-any.whl/pip install --no-index pip-20.3.4-py2.py3-none-any.whl && \
    pip install --upgrade pip && \
    cd python && for req in $(cat requirements.txt) pydot; do pip install $req; done && cd .. && \
    mkdir build && cd build && \
    cmake -DUSE_CUDNN=1 .. && \
    make -j"$(nproc)"

ENV PYCAFFE_ROOT $CAFFE_ROOT/python
ENV PYTHONPATH $PYCAFFE_ROOT:$PYTHONPATH
ENV PATH $CAFFE_ROOT/build/tools:$PYCAFFE_ROOT:$PATH
RUN echo "$CAFFE_ROOT/build/lib" >> /etc/ld.so.conf.d/caffe.conf && ldconfig

WORKDIR /workspace

``` 
## 参考
- [Qiita -Python 2.7 に pip をインストールする-](https://qiita.com/sg0hsmt/items/f8fc8d587bff816654a8)
- [github BVLC/caffe -Caffe_GPU Dockerfile-](https://github.com/BVLC/caffe/blob/master/docker/gpu/Dockerfile)
【javascript】getter/setter/static

# getter/setter/static
* ディスクリプターの中にはオプションでgetter/setter/staticを追加することができる。
* オブジェクトを呼び出した時に、同時に異なる処理をしたい場合に使用する。

# case1
* Person1コンストラクタにdefinePropertyを使用して、nameプロパティを追加。
* 第三引数にget, setを追加していく。

```js

function Person1(name, age) {
	this._name = name;
	this._age = age;
}

// インスタンス化されたp1を,definePropertyで追加されたname経由でbobを出力している。
//すなわち出力される値は  _name === name となる。
Object.defineProperty(Person1.prototype, 'name',{
	get: function(){
		return this._name;
	},
	set: function(val){
		this._name = val;
	}
})

const p1 = new Person1('Bob', 45)
console.log(p1.name) >>> Bob

```
nameが追加されている。
![スクリーンショット 2021-11-19 17.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/85e9c3f6-ac31-e894-9ebe-2e4ad2dd6844.png)

# case2

* setは追加されたプロパティに値を上書きすることができる。

```js

function Person1(name, age) {
	this._name = name;
	this._age = age;
}

Object.defineProperty(Person1.prototype, 'name',{
	get: function(){
		return this._name;
	},
	set: function(val){
		this._name = val;
	}
})

const p1 = new Person1('Bob', 45)

//上書きしている。
p1.name = "Tom"
console.log(p1.name) >>> Tom

```

# case3
* メソッドが呼ばれるときはgetterも同時に呼び出されるのでget内で異なる処理を追加することができる。

```js
function Person1(name, age) {
	this._name = name;
	this._age = age;
}

Object.defineProperty(Person1.prototype, 'name',{
	get: function(){
		alert('hello')
		return this._name;
	},
	set: function(val){
		this._name = val;
	}
})

const p1 = new Person1('Bob', 45)

p1.name = "Tom"
console.log(p1.name)
```

# case3
ES6からはクラスでより簡潔に書ける。

```js

class Person2{
	constructor(name, age) {
		this._name = name;
		this._age = age;
	}

	get name(){
		alert('hello')
		return this._name;
	}
	set name(val){
		this._name = val;
	}
}

const p2 = new Person2('hoge', 33)
console.log(p2.name) >>> hoge
```
# static
* クラス内で記述できる。
* メソッドを追加
* インスタンス化しなくても使える。
    * thisが使えない。


```js

class Person2{
	constructor(name, age) {
		this._name = name;
		this._age = age;
	}

	get name(){
		alert('hello')
		return this._name;
	}
	set name(val){
		this._name = val;
	}
	static hello(){
		console.log('hello23')
	}
}

Person2.hello() >>> hello23

```
phx_gen_authでメール認証


phx_gen_authはコマンド一発でユーザー認証のコードを生成できるため大変便利ですが、今日のWEBサービスのほとんどはユーザー名とパスワードだけの一段階認証ではなく、メールや確認コードなども組み合わせた多段階の認証が一般的です。

phx_gen_authで確認メールのリンクをクリックしたかどうかの認証機能の実装方法を紹介します。

# confirmed_atでメールリンクをクリックしたか判定
※この方法はliveviewのみ有効です.

phx_gen_authによって生成されたユーザーのテーブルにはconfirmed_atという確認メールのリンクがクリックされたかどうかを示すフィールドがあります。


[on_mountというmacro](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#on_mount/1)を使って毎回LiveViewがmountするごとにユーザーのconfirmed_atがnilではないかを確認する処理を挟むということをやります。

イメージ↓

```elixir
if user.confirmed_at do
  {:cont, socket} # like ~N[2021-11-16 03:19:57]
else
  {:halt, socket |> redirect(to: "/")} # nil 
end
```

# LiveViewモジュールにon_mountを差し込む

live/user_live_auth.exに以下のような確認メールのリンクを踏んだか確認するモジュールを定義します。

```elixir:user_auth_live.ex
defmodule MyAppWeb.UserLiveAuth do
  import Phoenix.LiveView

  alias MyApp.Accounts

  def on_mount(:default, _params, %{"user_token" => user_token} = _session, socket) do
    socket = assign_new(socket, :current_user, fn ->
      Accounts.get_user_by_session_token(user_token)
    end)

    if socket.assigns.current_user.confirmed_at do
      {:cont, socket}
    else
      {:halt, redirect(socket
        |> put_flash(:error, "Please confirm your email before signing in. An email confrimation link has been sent to you."),
        to: "/")
      }
    end
  end
end
```
※userをsocket.assignsにassignするときに[assign_new/3](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#assign_new/3)を使うことでmountするたびに何度も繰り返しassignしないで済むようになります。

他のLiveViewモジュールにon_mountを追加します。

```elixir:hoge_live.ex
defmodule MyAppWeb.HogeLive do
  use MyAppWeb, :live_view
  on_mount MyAppWeb.UserLiveAuth # <- added

  ...
end
```

これで確認メールのリンクをクリックしていないユーザーはHogeLiveにアクセスしようとするとルートディレクトリにリダイレクトされるようになりました。

on_mountはrouterで[live_session/3と一緒に使う方法](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Router.html#live_session/3)もあります。

また確認メールの認証のみならず特定のユーザーをBANする、sendgridで確認メールを送信できるようにセットアップする、など色々なチュートリアルがあり、可能性を感じました。参考資料をご覧ください。

#参考資料
[Security considerations of the LiveView model](https://hexdocs.pm/phoenix_live_view/security-model.html#content)
[Elixir Forumのメール認証に関するスレッド](https://elixirforum.com/t/phoenix-1-6-user-authentication-working-email-confirmation-i-need-to-write-a-tutorial/42277)
[phx_gen_authを使ったメール認証のチュートリアル　その１](https://experimentingwithcode.com/phoenix-authentication-with-phx-gen-auth-part-1/)
[phx_gen_authを使ったメール認証のチュートリアル　その2](https://experimentingwithcode.com/phoenix-authentication-with-phx-gen-auth-part-2/)
[phx_gen_authを使ったメール認証のチュートリアル sendgrid版](https://www.literatelabs.com/p/how-to-get-verification-emails-for)
【初心者】AWS Wavelengthを使ってみる #4 (Janus によるWebRTC ビデオ通信)

# 1. 目的
- AWS Wavelengthのメリットは低遅延での通信が可能となること。「低遅延」がイメージできるようなサンプルアプリケーションとして、WebRTCでのビデオ通信などを実現できるソフトウェアである「Janus」をインストールし動作を確認する。
- 無償でWebRTCが試せるソフトウェアを探していたところ、「[仕事で WebRTC](https://gist.github.com/voluntas/379e48807635ed18ebdbcedd5f3beefa)」というサイトがあり、有償/無償版のソフトウェアの一覧が掲載されていた。無償版のおすすめは「Janus」ということで、それを信じてやってみることとした。

# 2. やったこと
- AWS Wavelength 上に EC2 インスタンスを作成し、Janus をインストールする。
- 複数のPCやスマホから Janus サーバに接続し、相互にビデオ通信ができることを確認する。
- 単純にEC2インスタンスにJanusをインストールしただけのため、この記事の内容はAWS Wavelengthではなく、AWSの通常のリージョンでも同様に実現可能。

# 3. 構成図

![janus構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/4a3ea24f-7697-69d9-f0cd-77008e7d0dc5.png)



# 4. 実施手順
## 4.1 事前準備
- 構成図のようなインフラ環境を準備する。
    - VPC作成
    - Wavelength Zoneに紐づくSubnet作成
    - Wavelength Zoneで起動するUbuntu 20.04 のEC2インスタンス作成
    - EC2インスタンスへのキャリアIP付与
    - SecurityGroupの設定(検証のためフルオープン。UDPのポート番号が動的なため)

## 4.2 Janusの構築
- 公式の導入手順もあるが、「[Janusで自前のWebRTCビデオチャットサーバー](https://www.mikan-tech.net/entry/2020/05/02/173000)」が非常に分かりやすいため、基本的にこのサイトの手順に沿ってそのまま実施する。
- 上記のサイトの手順通りに、作成したインスタンス上で以下のような内容を実施する。
    - 各種ライブラリ、及びJanusそのもののインストール
    - nginx、自己署名証明書の設定
    - Janusのhttps対応設定
- AWS上で利用する場合、上記までの手順に加えて、インスタンスに付与されているプライベートIPと、キャリアIPとのマッピングの情報をJanusに対して設定する必要がある。「[Setting up Janus WebRTC on AWS](https://towardsaws.com/setting-up-janus-webrtc-on-aws-a8aa8914b0c6)」を参考に、Janusの設定ファイル /opt/janus/etc/janus/janus.jcfgの301行目、nat_1_1_mapping = "x.x.x.x" のところに、インスタンスに付与したキャリアIPを設定する。

``` /opt/janus/etc/janus/janus.jcfg(該当行付近)
# if the Janus is deployed in a DMZ between two 1-1 NAT for internal and
# external users.
nat_1_1_mapping = "x.x.x.x(インスタンスに付与したキャリアIP)"
```

- Janus を起動する。

```
$ sudo /opt/janus/bin/janus
```
 　
## 4.3 動作確認

- PC(Windows10, auスマホでテザリング)のブラウザから、https://(キャリアIP) にアクセスする。自己署名証明書を使用しているため、「接続がプライベートではありません」のような警告が表示されるが、了解の上アクセスする。
- いくつかのDemo用ツールがデフォルトで用意されているが、「Video Room」が分かりやすい。メニューから 「Demos -> Video Room」 を選択する。

![janus01a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/9e87fb72-8cf0-0dc8-e3e7-3a5f80dc19d1.png)

- 「Start」を押してビデオ会議を開始する。

![janus02a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/aea93bdf-cd15-86b8-e577-3e4184b4e1ef.png)

- 参加者名(今回はpcuser)を入力して、「Join the room」を押す。

![janus03a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/a966964b-3a6d-a9b1-aa4c-a9d9314730db.png)


- 成功すると、「Local Video」として、自分のPCカメラの映像が表示される。もし「Probably a network error, is the server down? [object Object]」というエラーが出る場合、https://(キャリアIP):8089/ に手動でアクセスし、再度自己署名証明書の警告を出して、了解のアクセスをする。（Janusのアプリにアクセスするところからport番号が変わるため、自己署名証明書に対する承認が再度必要になる場合がある）

![janus04a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/45b2d637-efae-c052-f51e-f4f2b48f3a14.png)

- スマホからも同じようにアクセスすると、PC側にスマホ側の映像が出る。ビデオ会議のように、相互に映像や音が伝送されることを確認できる。

![janus05a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/98bc5b12-4606-3a34-7301-c09ac72f2308.png)


# 5. 所感

- WebRTCでの映像伝送の雰囲気が分かるような環境は作ることができた。画面をカスタマイズするなど、もう少し工夫ができるようにしたい。
【javascript】プロパティーとディスクリプター

# プロパティーとディスクリプター
オブジェクトのプロパティにはvalueを設定するが、内部的に設定値が設定されている。その設定を変更するのがディスクリプター

## ディスクリプターの種類
* ディスクリプター
    * value(バリュー)：値の設定
    * configurable（コンフィグラブル）：設定変更可能性
    * enumerable（エニュメレイタブル）:列挙可能性（ループなどの時にプロパティが参照されるかどうか）
    * writable（ライタブル）:値の変更可能性


# case1
ディスクリプターを確認する。

* propというプロパティを用意
* ディスクリプターを確認する`getOwnPropertyDescriptor(第一引数：対象オブジェクト, 第二引数：対象プロパティ名)`を用意。

```js
const obj = {prop: 0}

const descriptor = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(descriptor)
```
初期値は全てtrueとなっている。
![スクリーンショット 2021-11-19 16.28.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/3ee6ebaf-3c3e-9aa1-0c66-2b3eeaca49dc.png)

# case2
definePropertyメソッドを使い、ディスクリプターの設定を変更する。

* `defineProperty（第一引数：対象オブジェクト, 第二引数：プロパティ名, 第三引数：{ プロパティ設定項目 }）`

```js
const obj = {}

Object.defineProperty( obj, 'prop', {
    value: 0
})
const descriptor = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(descriptor)

```
definePropertyで設定すると初期値は全てfalseとなる。

![スクリーンショット 2021-11-19 16.33.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/21793b7e-52ea-aa3e-e42d-d29a008c5a5c.png)

現在writableがfalseなので、valueの上書きはできない。

```js
Object.defineProperty( obj, 'prop', {
    value: 0
})

obj.prop = 1

const descriptor = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(descriptor)
```
![スクリーンショット 2021-11-19 16.40.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/e030bb91-6dcb-a74e-c0ec-298353c06771.png)

writable: trueに変更してみる。

```js
Object.defineProperty( obj, 'prop', {
    value: 0
    writable: true
})

obj.prop = 1

const descriptor = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(descriptor)
```
変更できている。
![スクリーンショット 2021-11-19 16.42.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/2d06131f-6f59-ce6b-47c0-7be69403c5c7.png)

その他、enumerableの変更をするときは,configurable（コンフィグラブル）：設定変更可能性をtrueとする必要がある。
[Swift]セーフエリアの色を変える

iOS11から導入されたセーフエリアの色を変えたい。

結論としては、色を直接変えるのではなくセーフエリアの上にUIViewを被せることで対応できる。
viewDidLoadなどに記述するとよい。

```safeArea.swift
        if #available(iOS 11.0, *)
        {
            let topFrame: CGRect = CGRect(x: view.safeAreaInsets.left,
                                       y: view.safeAreaInsets.top,
                                       width: UIScreen.main.bounds.size.width,
                                       height: 44)
            let safeAreaOverlay: UIView = UIView()
            safeAreaOverlay.frame = topFrame
            safeAreaOverlay.backgroundColor = .green //変えたい対象の色
            view.addSubview(safeAreaOverlay)
        }
```
ActiveReports 14.0J の使い始めで迷わないために

ActiveReports は帳票作成案件では多数の採用実績をもつフレームワークパッケージです。超細かな指定がある帳票も簡単に作れます。

<img src='https://grapecitycontentcdn.azureedge.net/jp/products/activereports/feature-designer.png' width='60%'>

コロナ起点の DX ブームのおかげで紙帳票は少なくなりましたが、紙が PDF に変わっただけで超細かな指定の帳票作成はまだまだ残っているというか増えているので、新しい ActiveReports 14.0J Professional を購入してもらいました。
外字を扱えるのは Professional だけなのでやむなしです。

トライアル版を入れて、購入後に案内メールが届くので、それに従ってシリアル入れたりするだけです。

https://www.grapecity.co.jp/developer/download

プロジェクトで早速使用していきたいところですが、気をつけなければならない点があります。

AcitiveReports 14.0J は、通常、C:\Program Files (x86)\ActiveReportsNET14 にインストールされ、実プログラム群はその下の Tools にあります。

・・・と見せかけて、実は日本語版は Tools の下の ja フォルダ下にあります。

同名のファイルが Tools と Tools/ja に入っているので、最初はインストールの不具合かと思ったのですが、英語版が「Tools」直下、ローカライズされたものはその下に「Tools/ja」みたいな形で配置されるようです。

ja 配下の dll を使用しないと、クラス名称も違うようで、外字どころかサンプルのソースコードも動きません。

PDF ファイルへの Export テストをしようとしたのですが、下の説明通りにコードを書いても「型が一致がない」などと言われてしまいます。
https://docs.grapecity.com/help/activereports-14/#rendering-to-pdf.html

試行錯誤に時間を取ってしまったので、何をすれば良いのかまとめておきたいと思います。

## プロジェクトを作成したら最初にすること

正しく速やかに ActiveReports を使うためには、次の手順を行います。

### Windows Form の場合

#### 本体

プロジェクト作成後、パッケージマネージャーコンソールで GrapeCity.ActiveReports のパッケージをインストールします。コアの機能が利用できるようになります。

```powershell:パッケージマネージャーコンソール
PM> install-package GrapeCity.ActiveReports.ja
```
:::note alert
絶対に 「.ja」を忘れてはいけません。
:::

#### ビューア

ビューアを使ってレビューを見るなら、次のパッケージをインストールします。

```powershell:パッケージマネージャーコンソール
PM> install-package GrapeCity.ActiveReports.Viewer.Win.ja
```
:::note alert
絶対に 「.ja」を忘れてはいけません。
:::

このパッケージをインストールすると、ツールボックスに「ActiveReports 14」が追加され、ビューアコンポーネントを利用することができるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/3eed36d7-13ce-cb75-c02c-98c2e473b319.png)

#### ファイル出力

PDF ファイルの出力機能は、デフォルトで要求されるのではないでしょうか。ならば、次のパッケージが必要です。

```powershell:パッケージマネージャーコンソール
PM> install-package GrapeCity.Activereports.Export.Pdf.ja
```

他にも、XML、Word、HTML、RDF、Excel、画像形式での出力が可能です。必要に応じてインストールします。

```powershell:パッケージマネージャーコンソール
PM> install-package GrapeCity.ActiveReports.Export.Xml.ja
PM> install-package GrapeCity.ActiveReports.Export.Word.ja
PM> install-package GrapeCity.ActiveReports.Export.Html.ja
PM> install-package GrapeCity.ActiveReports.Export.Rdf.ja
PM> install-package GrapeCity.ActiveReports.Export.Excel.ja
PM> install-package GrapeCity.ActiveReports.Export.Image.ja
```

:::note alert
絶対に 「.ja」を忘れてはいけません。
:::

### WPF の場合

WPF の場合は、次のパッケージをインストールします。

```powershell:パッケージマネージャーコンソール
PM> install-package GrapeCity.ActiveReports.Viewer.Wpf.ja
```

インストール後、ツールボックスを見ると、WPF Viewer が現れますので、これを フォームに貼り付けます。

![wpfviewer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/ea306097-3ca5-a2f8-ab1c-5782221c4c8c.png)

### 参考

なお、これらの情報は次のページを参照しています。

* [クイックスタート - GrapeCity ActiveReports for .NET 14.0J](https://docs.grapecity.com/help/activereports-14/#quick-start.html)
* [依存関係の管理 - GrapeCity ActiveReports for .NET 14.0J](https://docs.grapecity.com/help/activereports-14/#manage-activereports-dependencies.html)
* [利用可能なパッケージ - GrapeCity ActiveReports for .NET 14.0J](https://docs.grapecity.com/help/activereports-14/#available-packages.html)
自然言語処理の技術をAPI化し、レスポンス結果として受け取るとき、タイムアウトなどしてしまうときの対処

・自然言語処理の技術をAPI化し、レスポンス結果で受け取るとき、ベクトル化の部分などで時間が掛かりタイムアウトエラーになることがある。
・その対処法として、ベクトル化データをnumpyフォーマットで保存する方法。

```
# モデルファイルのパスを取得
file_path = f'{os.path.dirname(os.path.abspath(__file__))}/data/SentenceBert_Triplet'
model = SentenceTransformer(file_path) # モデルを読み込み

## 結果で出力するクエリをベクトル化
#sentence_vectors = model.encode(sentences)

## ベクトルデータを numpy フォーマットでファイル保存
## モデルに変更があれば、作り直す必要がある
#np.save('/tmp/sentence_vectors.npy', sentence_vectors)

# ベクトルデータファイルのパス
vector_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/data/sentence_vectors.npy'
# 保存しておいたベクトルデータファイルのデータを読み込む
sentence_vectors = np.load(vector_file_path)
```
HTTP入門（社内勉強会資料）

# これはなんですか
HTTPの歴史と仕組み、現状について説明します。

HTTPはクライアントからサーバに対して接続を開始し、リクエストを送信しレスポンスを受け取り、用がないと判断した側が接続を切断するシンプルな通信モデル。
CONNECTなどの特殊なメソッドを除き、基本的にリクエストとレスポンスがあり、その中身は下記の通り

通信の内容は
https://triple-underscore.github.io/rfc-others/RFC2616-ja.html#section-4
RFCの中でNBF記法という方法でメッセージの書式が定義されている。

# HTTPの歴史
https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol ここにすごくよくまとまっている。
RFCというインターネット標準を規定する文章群によって仕様が定められている。

# 教材
書こうとしていたことのほとんどはここにあったので引用
https://qiita.com/shiei_kawa/items/1c10311225eeef17fa01

# 実例
リモートIPアドレス取得の httpbin.org/ip を例にとって説明します。

## リクエスト

```
GET /ip HTTP/1.1
Host: httpbin.org
User-Agent: curl/7.77.0
Accept: */*
```

### １行目 リクエストライン
1. `GET` メソッド
1. `/ip` パス
1. `HTTP/1.1` HTTPのバージョン

### ２行目以降 リクエストヘッダs
1. Host 必須ヘッダ。これがない時代は一つのIPアドレスで一つのサイトをホスティングしていたが、複数のホスティングを行う場合必須。最近顕著なのはALBとか
1. User-Agent 任意ヘッダ。クライアントの情報
1. Accept リクエストヘッダフィールドは、レスポンスで受け入れ可能なメディアタイプを指定するために使われる。 `application/json` とか指定するとjsonしか受け入れないといったかんじ。

### ５行目以降
レスポンスで後述するが、POST等のボディ部を有する場合はレスポンスと同じような感じになる。

## レスポンス

```
HTTP/1.1 200 OK
Date: Fri, 19 Nov 2021 06:20:55 GMT
Content-Type: application/json
Content-Length: 32
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "220.97.32.135"
}

```

### 1行目 ステータスライン
1. HTTP/1.1 HTTPのバージョン
1. 200 ステータスコード
1. OK メッセージ

### 2行目〜８行目 レスポンスヘッダs
1. Date 日付。書式は決まっている
1. Cotnent-Type body部がある場合、その形式はなにか、エンコーディングや文字コードはなにかを示す
1. Content-Length ボディ部の長さ、バイト単位
1. Connection keep-aliveはTCPの接続を切らない命令。TCPを再接続するオーバヘッドが大きいため、後続でリクエストが続く場合は同一のTCP接続(TCP Session)が再利用される。
1. Server レスポンスを返すサーバの情報。製品やバージョンなど。近年は製品共通のセキュリティホールを狙った攻撃を受ける可能性があるため非公開になる場合が多い。

### 9行目
空行に見えるけどリクエストヘッダsとボディ部を分けるセパレータのようなもの。 なおここまでの改行コードは CRLF 以外認めないもよう。
### 10行目以降:
ボディ部。、この場合はjsonですが、jpegのバイナリだったりXMLだったりHTMLだったりさまざまなデータがやりとりできる。

# Plain Textと SSL/TLS 通信
URLの最初のスキーマと呼ばれる部分が http だったら平文の通信、httpsだったら暗号化された通信。
平文は傍受される可能性があるけど、クレジットカードや個人情報などの情報は傍受されるとマヅいのでhttpsとし、暗号化する。
最近はすべての通信を暗号化しようとする方向にある。

# 通信実演

## curl

```
curl -v httpbin.org/ip
```

## telnet (for http)

```
$ telnet httpbin.org 80

GET /ip HTTP/1.1
Host: httpbin.org

GET /ip HTTP/1.1
Host: httpbin.org
Connection: close

```


## openssl (for https)

```
$ openssl s_client -connect httpbin.org:443 -servername httpbin.org
GET /ip HTTP/1.1
Host: httpbin.org

GET /ip HTTP/1.1
Host: httpbin.org
Connection: close

```

※ --srrvername はSNIというこれまた一つのIPアドレスで複数のSSL証明書をホスティングする仕組みがあるので、だいたいはなくてもいいけど接続先アドレスとホストが異なってる場合は必要。この場合は要らない。例えばAWS ALB相手にlookupしたIPアドレスで接続に行っても相手にしてもらえないけど、

## /etc/hosts によるだまくらかしのテクニック

裏技のようなもの。
間に強引にproxyみたいなのかましたいとき、 /etc/hosts にホスト名を書いてでジャックする方法をとることもあります。
年に１回位は使ってる気がする・・

以上
AWS Step Functions でオプション引数を使いたい

# はじめに
本記事では、AWS StepFunctionsでオプション引数の機能を実現する方法をまとめました。
### negocia株式会社について
[negocia株式会社](https://negocia.jp/)では３つのValueを行動指針とし、「うれしい広告」の実現を目指しています。
#### Value
- Professional Pride　プロであり続ける
- Praise the Challenge　挑戦を楽しむ
- Ownership for All　全てにオーナシップをもつ

興味を持たれた方は[採用情報](https://negocia.jp/recruit/)をご覧ください。

# やりたいこと
このPythonコードのように、AWS StepFunctionsでオプション引数を使いたい。

```python
>>> def say_hello(name="World"):
...     return f"Hello, {name}"
... 
>>> say_hello()
'Hello, World'
>>> say_hello("negocia")
'Hello, negocia'
```
# 手段
[StepFunctions](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/welcome.html)の[Choice](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-choice-state.html)と[Pass](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-pass-state.html)を使う。
`Choice`で引数の有無を調べ、`Pass`でデフォルト値を補う。

# StepFunctions の定義
```json
{
  "StartAt": "HasName",
  "States": {
    "HasName": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.name",
          "IsPresent": false,
          "Next": "FillName"
        }
      ],
      "Default": "Say"
    },
    "FillName": {
      "Type": "Pass",
      "Result": "World",
      "ResultPath": "$.name",
      "Next": "Say"
    },
    "Say": {
      "Type": "Pass",
      "Parameters": {
        "message.$": "States.Format('Hello, {}', $.name)"
      },
      "OutputPath": "$.message",
      "End": true
    }
  }
}
```

# 実行例
## 引数を与えなかった場合
- 入力`{}`
- 出力`"Hello, World"`

![stepfunctions_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2302749/6d8dd207-9ef6-1749-fd56-e458ce5ae974.png)

## 引数を与えた場合
- 入力`{"name": "negocia"}`
- 出力`"Hello, negocia"`

![stepfunctions_graph(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2302749/83f266ca-49a0-da11-8335-72efcc09e7a3.png)





# 参考

https://aws.plainenglish.io/aws-step-function-tricks-ffe7eef81a5e

https://stackoverflow.com/questions/59056043/aws-step-functions-and-optional-parameters
【javascript】Symbol

# Symbol
* プロパティの重複を避けるために、必ず一意の値を返す関数。
* Symbolというプリミティブのデータ型
* Symbol('名前をつけることができる。')

# case1

一意の値を返すとはなにか？

```js

const s1 = Symbol('hello');
const s2 = Symbol('hello');

//コンソール上は同じ出力となる。
console.log(s1) >> Symbol(hello)
console.log(s2) >> Symbol(hello)

//しかし、内部的には違うものとなる。
console.log(s1 === s2) >>>false

```

# case2
どのような時に使うのか？

ES5からES6にupdateする時に、既存のコードが新しいバージョンと重複せずに動作することを目的に作られた。

* 例えば、Stringに新しいメソッドを追加したい場合にSymbolを使用して一意のメソッドを追加することができる。
* シンボルを登録するときはブラケット記法[]となる。
* 登録したメソッドを使用するときは`関数名[シンボル変数]()`となる。

```js

const s1 = Symbol('hello');

String.prototype[s1] = function() {
       return 'hello ' + this;
}

const tom = 'Tom'; 
console.log(tom[s]());

```

![スクリーンショット 2021-11-19 16.00.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378066/4c96e8f9-216f-6d9b-4f96-a196e4cc84d3.png)