OmniAICreator/Qiita-1.07M huggingface dataset:
【SAP】ユニオンクエリで複数の会社データをまとめてみる

この記事では、ユニオンクエリを利用した複数のクエリの統合をみてみます。例として、SAP Business Oneの会社別集計を行ってみます。
**[Sharperlight](https://sharperlight.jp/)クエリビルダ**をアプリケーションメニューから起動します。
そしてこのようなクエリを作成します。
![2022-03-07 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/07ab2f2c-88bc-be6e-4994-dd77293e793d.png)
[フィルター]領域で右クリックメニューを表示して、**クエリーユニオン**を選択します。
![2022-03-07 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0240f48c-5843-5888-4586-edd772a78265.png)
[クエリーユニオン]ダイアログが表示されます。
![2022-03-07 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2832e705-6bba-6a2d-3122-fd6798e23c1c.png)
リストには親クエリの情報が表示されています。
[新規]アイコンを押して、新しくユニオンクエリを追加します。
![2022-03-07 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d9682c85-8251-11ed-3dc3-4e0ecf10a82b.png)
新しく追加されたユニオンクエリを選択し、[クエリーを編集]ボタンを押します。
![2022-03-07 Figure 05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/df374e1e-6b31-5463-a648-227f0a7c6ac7.png)
[クエリビルダ]ダイアログが起動し、初期設定として親クエリが既に定義されています。今度は会社名を豪州支店に変更します。
その他のフィルターは、親クエリのフィルター値を参照するように今回は設定しました。
[OK]を押して保存します。[クエリーユニオン]ダイアログも閉じます。
親クエリに戻るので、[プレビュー]ボタンでクエリの動作確認をします。
![2022-03-07 Figure 07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8b93acdf-342e-53ee-4ecc-6415f81d52a3.png)
会社名フィールドは、拡張表現でこのように定義しました。
![2022-03-07 Figure 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9248f601-81bf-35fe-a508-dd63e4babd2e.png)
:postbox:[Sharperlight](https://sharperlight.jp/)
エラー：Use of 'type' refers to instance method rather than global function 'type(of:)' in module 'Swift'

# type(of: self)で発生したエラー
Use of 'type' refers to instance method rather than global function 'type(of:)' in module 'Swift'

## 原因
該当クラスにtypeというプロパティを保持していたため
```
class Hoge {
    private var type: TypeEnum = .none

    init() {
        // プロパティにtypeがあるためエラーになる
        print(String(description: type(of: self)))
```
## 対応
とりあえず変数名変えてあげましょう。それが嫌ならSwift.type(of: self)とする。
createdateを上書きする方法（sf中如何覆盖createdate）

再sf中如何覆盖createdate
1．設定 ＞ ユーザインターフェース ＞ユーザインターフェース [「レコードの作成時に監査項目を設定」および「無効な所有者のレコードを更新」ユーザ権限 ]を有効化にチェックを入れて保存。


2．設定 ＞ 権限セット　新規権限セットを作成し、システム権限の[レコードの作成時に監査項目を設定]（＝レコードを作成するときに、[作成者] や [最終更新者] などの監査項目を設定します (API のみ)）にチェックを入れて保存。


3．作成した権限セットをシステム管理者に割り当てる。
※システム管理者にはデフォルトで付与されていますが、「すべてのデータの編集」権限も必要です。

これで、データローダで Insert（Upsert)をする際に、次の監査項目を Mappingできるようになります。
・CreatedById（作成者）
・CreatedDate,（作成日）
・LastModifiedById,（最終更新者）
・LastmodifiedDate（最終更新日）
TypeScript勉強会 第5回 2022/03/07 - Conditional Types / Mapped Types

## Conditional Typesとは

Conditional Typesは型のif文です。指定された型をチェックしてその型の条件に応じて、別々の型を返すことができます。
構文は三項演算子に似ていて、
`A extends B ? C : D` で、型Aを型Bとみなせるとき、型Cを返す。みなせない場合はDを返す。
というような意味になります

```.ts
function func<T extends string | number>(arg: T):T {
 return arg
}

// 上記の関数の引数の型から返り値の型を推論する型関数を書くと以下のような感じになる
type ReturnType<Arg> = Arg extends string ? string : number

ReturnType<'aaa'> // => string
ReturnType<0> // => number
```

継承が絡む場合も同じような挙動になります

```.ts
class Animal {
}
class Dog extends Animal {
}
 
type Example1 = Dog extends Animal ? number : string; // => number
        
type Example2 = RegExp extends Animal ? number : string; // => string
```

## Mapped Typesとは

Mapped Typesは、連想配列を作成できる構文です。 `{[型変数名 in 型A]: 型B}`のような構文を書くことで、
型Aに指定されたものをキーに持つ連想配列を作成できます。
型Aは多くの場合`string`型か文字列リテラルが指定され、`string`型の場合は自由な文字列のキーを持つ連想配列を表し、文字列リテラルが指定された場合はその文字列リテラルで指定された文字列のキーのみを持つ連想配列を返します

```.ts
type A = {
  [key in 'a' | 'b']: boolean
};

// => {
//   'a': boolean
//   'b': boolean 
//  }

type B = {
 [key in string]: boolean
}

// => Record<string. boolean> と同じ

```

前回紹介した`Record`型との違いは、連想配列のキーとバリューの間に関係性をもたせられる点です。
バリュー側の型の中でキーの型を参照できるので、キーの型の条件に応じてバリュー側の型を変えることができます。

```.ts
type B = {
  [key in 'a' | 'b']: key extends 'a' ? 'a' : 'b'
};

// => type B = {
//      a: "a";
//      b: "b";
//  }
```

この機能を応用すると、[特定の型のメンバだけを抽出する型関数](https://qiita.com/KuwaK/items/7b7edd64eeb7e670509f)を作れたりします。

かなり応用の幅が広い機能なので、型パズルに興味がある人は色々試してみるのもいいかもしれません。
S3バケットにあるgzipファイルを加工して再度gzipで出力

大したことない作業のようですが、若干つまりどころがあったので残しておきます。

## やりたいこと
とあるS3バケットにあるgzipファイル（中身はjson）が生成されるたびに一部加工して、別のバケットに再圧縮して出力したい。
図を書くほどのものでもないんですが、こんな構成になります。
![Blank diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852059/6b84716b-cd55-0cff-954b-e9ba1f9df0f3.png)


## どうやるか
Source BucketからSQSに通知してLambdaを呼び出すところは一般的な設定なので割愛します。
gzipを取り扱えるnpmパッケージは有名どころだと[node-zip](https://www.npmjs.com/package/node-gzip)などがありますが、zlibだけで出来ましたので今回のようなシンプルなケースだと外部パッケージは不要でした。
解凍・加工・再圧縮を行うLambdaは下記のようになります。(nodejs14.x)

```javascript
const AWS = require('aws-sdk')
const s3 = new AWS.S3()
const zlib = require('zlib');

exports.handler = async (event) => {
  try{
    for (const record of event.Records) {
      for (const recordBody of JSON.parse(record.body)) {
        const key = recordBody.s3.object.key
        if (/\.gz$/.test(key)){
          // Source Bucketからgzipオブジェクトを取得
          const getParams = {
            Bucket: 'SOURCE_BUCKET_NAME',
            Key: key
          }
          const source = await s3.getObject(getParams).promise()

          // 1. 解凍
          const sourceData = JSON.parse(zlib.gunzipSync(source.Body))

          // 2.加工
          // ...

          // 3. 再圧縮
          const destData = zlib.gzipSync(JSON.stringify(sourceData))

          // 4. 保存
          const putParams = {
            Bucket: 'DESTINATION_BUCKET_NAME',
            Key: key,
            Body: destData,
            ContentType: 'application/json',
            ContentEncoding: 'gzip'
          }
          await s3.putObject(putParams).promise()
        }
      }
    }
    // done
    return true
  }catch(err){
    throw new Error("Exception error")
  }
}

```

### 1. 解凍
```javascript
zlib.gunzipSync(data)
```
dataは下記の形式いずれかとなります。今回はバケットから取得したBuffer値をそのまま入れています。
`<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string>`
第2引数で[オプション](https://nodejs.org/api/zlib.html#class-options)を渡すことも可能です。
zlib.gunzipというメソッドもありますが、別スレッドでのコールバック形式になります。
zlib.gunzipSyncだと同スレッドでの実行となるためコールバック形式となりません。

### 2. 加工
解凍後のデータ（今回はjson形式）をここで加工しています。

### 3. 再圧縮
```javascript
zlib.gzipSync(data)
```
dataは下記の形式いずれかとなります。今回は加工したstringをそのまま入れています。
`<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string>`
第2引数で[オプション](https://nodejs.org/api/zlib.html#class-options)を渡すことも可能です。
こちらも同様にzlib.gzipというメソッドもあり、別スレッドでのコールバック形式になります。
zlib.gzipSyncだと同スレッドでの実行となるためコールバック形式となりません。

### 4. 保存
Destination Bucketにputするだけ、ではあるのですが、今回保存するのはjsonをgzip圧縮したものなので下記のメタデータを付けています。
```
ContentType: 'application/json'
ContentEncoding: 'gzip'
```
このメタデータを付けることによってS3でのオブジェクトの取り扱いが変わり、コンソールからダウンロードした際に自動的に解凍されるようになります。
ちなみにメタデータを付けず保存した場合はContentTypeが`application/octet-stream`となります。
このあたりは後続の処理に応じて適切な値を付けるのが望ましいと思います。

### その他
エラーハンドリングについてもDLQの再処理や後続の処理に影響があるので適宜調整が必要です。
今回は再処理をそこまでシビアに考える必要が無かったためシンプルな記載にしています。

## 参考
https://nodejs.org/api/zlib.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html
Mac + Lima + Docker

会社の先輩T氏に `Docker Desktop for Mac` を使わず
Dockerが利用できる方法を教えてもらったので自分のプラベートMacにインストールした覚書

### Lima と Docer をインストール
```
% brew install lima docker
```


#### docker-compose を使う予定がある場合

docker-compose のインストール 
```
$ brew install docker-compose
$ mkdir -p ~/.docker/cli-plugins
$ ln -sfn /usr/local/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
```
起動コマンド
```
$ docker compose up -d
```

### LimaのにDockerサンプルファイルをもってくる
インストールしたバージョンと同一のものを [lima-vm/lima](https://github.com/lima-vm/lima) からもってくる
```
% limactl -v
limactl version 0.8.3

% curl -o docker.yaml https://raw.githubusercontent.com/lima-vm/lima/v0.8.3/examples/docker.yaml
```

### 初回起動

```
% limactl start ./docker.yaml
```

初回尋ねられるので `Proceed with the default configuration` を選択
```
? Creating an instance "default"  [Use arrows to move, type to filter]
> Proceed with the default configuration
  Open an editor to override the configuration
```

インストールが完了すると↓のメッセージが表示される。
```
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima --docker "host=unix:///Users/mykysyk/.lima/docker/sock/docker.sock"
docker context use lima
docker run hello-world
------
```

`DOCKER_HOST` を 起動したlimaのUnixソケットを指定した環境変数 を`.zshrc`に追記する
```
% echo 'export DOCKER_HOST=unix://$HOME/.lima/docker/sock/docker.sock' >> ~/.zshrc
% source  ~/.zshrc
```

nginxを起動してみる
```
% docker ps --all
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

% docker pull nginx
% docker run nginx -p 8080:80
% docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                                   NAMES
8f914543a791   nginx     "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:8888->80/tcp, :::8888->80/tcp   blissful_cerf
```

http://127.0.0.1:8888/ にアクセスして↓がブラウザに表示されたら成功
```
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.
```

# ボリュームマウントしたディレクトリに書き込むと Read-only file system となる場合

Docker停止
```
% limactl stop docker
```

lima.yaml 設定ファイルを編集
```
% ~/.lima/docker/lima.yaml
```
↓を追加
```
mounts:
- location: /path/to/shared/dir
  writable: true
```

Docker起動
```
% limactl start docker
```

書き込めるかテスト
```
% cd /path/to/shared/dir
% docker pull alpine:latest
% docker run -it --rm -v $(pwd):/home alpine:latest /bin/sh
# touch /home/a
# ls /home/a
```

# ディスク使用量
インストールするには約３G〜程必要
```
Used 136Gi -> 139Gi 
```

## limactl
DockerVMの状態確認
```
% limactl list
NAME      STATUS     SSH                ARCH      CPUS    MEMORY    DISK      DIR
docker    Running    127.0.0.1:52785    x86_64    4       4GiB      100GiB    /Users/mykysyk/.lima/docker
```

DockerVMのシェルにはいる
```
% limactl shell docker
```

DockerVMの停止
```
% limactl stop docker
```

DockerVMの起動(２回目以降)
```
% limactl start docker
```

DockerVMの削除
```
% limactl delete docker
```
DELLサーバーのファン交換したいのでそのやりとりをメモ失礼いたします。

でそのサーバーにはESXiが動作しているので
そちらの移行、停止が必要なんだよな……

デルからは
```
　■ホストとクラスターの停止・起動手順 
　https://www.nutanix.com/content/dam/nutanix/ja/documents/support/doc-node-restart.pdf
　 - [2. ホストの停止・起動手順 - ESXI (VSPHERE WEB CLIENT)]

```
みたいな事言われたけどとりあえずやってみるか……
Python環境構築

# Pythonの環境構築

ここでは、自分の備忘録としてメモ程度で書いていくので、環境構築をする際は、Youtubeに環境構築の方法を解説している方がたくさんいらっしゃいますので、そちらを参照してください。

私が参考にしたもの（キノコードさん）↓

https://youtu.be/1FxhleEex8s

`vidual studio code`をインストール（Youtubeにたくさん環境構築の法方があるのでそちらを参照してください。）
`Anaconda`のインストール→`JupyterLab`でPythonを実行していく。**NoteBookのPython3をクリック！！**

**JupyterLabでは、shift + enter**で実行処理ができる。

+ ターミナル上で下記を実行すると、JupyterLabを開くことができる

```csharp:terminal
jupyter lab

//終了法方は
control + c そして y
```
# JupyterLabの使い方

+ プログラミングの実行環境のこと
+ vscodeと違う点は、JupyterLabでは、`ブラウザ上で記述や実行ができる。`
+ 1行ずつ実行確認ができる。

# homebrew

+ 下記のサイトを参考にしました。ありがとうございます。
+ homebrewでさまざまなパッケージをインストールすることができる。

https://zenn.dev/sawao/articles/e7e90d43f2c7f9　

:::note
+ `homebrew`は**パッケージ管理システム**のこと。
+ 実行ファイルや設定ファイル、ライブラリなどを一つのファイルとしてまとめているものをパッケージ
+ パッケージ管理システムとはこのパッケージのインストール（アンインストール）作業を一元的管理するもの
+ gitなどのパッケージをバラバラに公式サイトからインストールするのではなく、パッケージ管理システムを使って、バージョンや他のライブラリとの相性を一元管理する。
+ パッケージ管理システムを使うと、バージョンのインストール、アンインストール、アップグレード、ダウングレードも簡単にできる。アンインストールするときには関連するファイルもすべて端末から削除することができるため、容量の節約にもなります
:::

# homebrewのインストール法方

+ ターミナル上で下記のコマンドを実行する。

```csharp:ターミナル
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
//自分のパソコンのパスワードが求められます。
//enterが求められるときはenterをクリック
```

# IDEのPyCharm

+ PyCharmはPython専用の統合開発環境
+ `対話型シェルで1行ずつ実行することができる`

```csharp:ターミナル
python//対話型シェル
```
言語モデルをiOSアプリで使うときに気をつけたこと

機械学習のモデルは日々進化しており、言語モデルもその例の一つです。Webサービスとしてはかなり普及している印象ですが、モバイルアプリでの活用も考えるといくつか注意点があります。今回はその課題と対処法を考えていきます。

# 課題
Webと異なるモバイルアプリ独特の問題点には次のようなことが挙げられます。
- **アプリのサイズ**
- **デバイスごとの処理能力の差**
- **セキュリティ**

## アプリのサイズ
機械学習の肝となるモデルはどうしてもデータサイズが大きくなってしまいます。もちろんモデル以外にもさまざまな機能をアプリ内に用意することを考えると負担の増加は避けられません。またこれらの事情はあくまでも知識のある私たちの目線であり、一般の人からすれば単に「やたらと容量を圧迫するアプリだな」という、使用をためらう原因になる恐れもあります。

## 処理能力の差
モバイル端末にはそれぞれ処理能力に差があります。使われる端末が最新機種なのか、それとも古いものなのかはわかりません。クラッシュや電池消耗はアプリの評価に影響を与えることが多く、ここは注意する点です。

## セキュリティ
特にAppleに言えることですが、モバイルアプリにおけるセキュリティは厳しくなっていく傾向があります。アプリ内の通信は可視化され、ユーザーの許可が必要な機能は増えてきています。モデルのアップデートやフィードバックの仕組みもこれを考慮しておかなくてはなりません。

# 解決法

## 1.モデルを外部に置く
Webアプリのように外部で処理を行うことで先述の上2つの課題は解決します。現在リリースされている「AIと会話する」というようなアプリはこのタイプが多いように感じます。ただしセキュリティの問題が解決できません。単なる会話アプリなら問題ありませんが、本格的な文書を扱う場合は話が別です。有名なDeepL翻訳のように、扱うデータに対する安全性の保証も必要になってくるかと思います。


## 2.モデルを内蔵する
こちらはセキュリティの問題を解決できます。iOSではモバイル向けに最適化された`Core ML`を使うことでサイズや処理の負担もかなり軽くすることができます。言語処理ではさらに`NaturalLanguage`というフレームワークも既に用意されています。

```swift:TextCheck.swift
import NaturalLanguage

let text = "ホメロスは人工知能で文章を分析するアプリです"

func tokenize(text: String) {
    let tokenizer = NLTokenizer(unit: .word)
    tokenizer.string = text
    let tokens = tokenizer.tokens(for: text.startIndex ..< text.endIndex)
    var textTokens: [String] = []
    for token in tokens {
        let tokenStart = token.lowerBound
        let tokenEnd = token.upperBound
        let text = text[tokenStart ..< tokenEnd]
        textTokens.append(String(text))
    }
    print(textTokens)
}

tokenize(text: text)
```

実行結果は以下のようになります。
```
["ホメロス", "は", "人工", "知能", "で", "文章", "を", "分析", "する", "アプリ", "です"]
```
もちろん最新の言語モデルに比べれば少々頼りないところもありますし、日本語に対しては十分機能しない機能もあります。ただトークン化は問題なく行うことが可能です。またiOS内のフレームワークであるため`Core ML`以上に負担の少ない実装をすることができます。





# まとめ
機械学習をモバイルアプリで使うには独自の工夫が必要になります。モデルを外部を外部に置くか内蔵するかは迷いどころですが、セキュリティ強化の風潮を見ると後者の方が安心です。サイズや処理の問題を解決する手段も提供されているから、という理由もあります。

## 実例
[<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713689/05738db0-029f-fa88-1f86-f974b54a1d32.png">](https://textcheckai.page.link/first)
例と言いながら自分の開発したもので申し訳ないのですが、こちらの「ホメロス」は今回紹介したように`NaturalLanguage`フレームワークを使用したものです。機能としては[以前の記事](https://qiita.com/KokumaruGarasu/items/dc8ce52cad3c924fc1ea)でも紹介しましたが、文章の文体や表現を分析してアドバイスを行うといったものです。

サイズは現状6.8MBとかなり抑えることができました。これならUIや機能をいくつか追加する余裕もあります。使い心地に関してはみなさんの判断に委ねたいと思うので、一度試していただけると嬉しいです。

## さいごに
モデル自体の精度はもちろん、その応用法も日々進化しています。モバイルアプリのみならず、ぜひ機械学習をさまざまな場面で活用してみてください！
AWSで立てたredashをv8->v10にバージョンアップ

## 背景
redash v8.0 でpreviewリリースされていたカスタムアラートを使いたいという依頼を受けてみてみた結果
そもそもv10系が出てるやん&カスタムアラートも正式リリースされてるやん！
と言うことでサクッとバージョンをあげてみた
(以前redash放置してたら太古のバージョンになっていたことによる恐怖心)

https://kakakakakku.hatenablog.com/entry/2019/11/05/065603

しかし redash のupgradeガイドを読んでもまだv10はなかったのでgithubのリリースノートを見て対応開始

https://redash.io/help/open-source/admin-guide/how-to-upgrade/

ちなみにv9はbeta版だけで正式リリースがなくv8->v10となりました(なんでかわからないですが)

カスタムレスポンス的な中身を展開することをしたくて以前個人開発で作ったものを利用していたのですがこちらで不要になりそう :rocket: 

## 対応準備
### AMI をとっておく
まずはバックアップ。。。
v8->v10のバージョンアップにミスった記事もちょいちょい見ていたので恐怖心爆上げ

### Dockerバージョンの書き換え
v10.1も出ていたが一旦v10.0にあげる
`docker-compose.yml` のimageを変更

`redash/redash:8.0.0.b32245` -> `redash/redash:10.0.0.b50363`

https://hub.docker.com/layers/redash/redash/10.0.0.b50363/images/sha256-9392753c03767453f3a803eea0f6f57b52163dac8814dd13a1724dc4037132cf?context=explore

### githubにある通りにアップデート手順を踏んでいく

https://github.com/getredash/redash/blob/master/CHANGELOG.md#v1000-beta---2021-06-16

```md
### Upgrading

(This section is duplicated from the previous release - since many users will upgrade directly from V8 -> V10)

Typically, if you are running your own instance of Redash and wish to upgrade, you would simply modify the Docker tag in your `docker-compose.yml` file. Since RQ has replaced Celery in this version, there are a couple extra modifications that need to be done in your `docker-compose.yml`:

1. Under `services/scheduler/environment`, omit `QUEUES` and `WORKERS_COUNT` (and omit `environment` altogether if it is empty).
2. Under `services`, add a new service for general RQ jobs:

--
worker:
  <<: *redash-service
  command: worker
  environment:
    QUEUES: "periodic emails default"
    WORKERS_COUNT: 1
--

Following that, force a recreation of your containers with `docker-compose up --force-recreate --build` and you should be good to go.
```

* `docker-compose.yml` の `scheduler` の `QUEUES` と `WORKERS_COUNT` を削除。他指定しているものもないので `environment` も削除してます
* `services` に `worker` を追加。(上のymlをそのまま追加)
* `docker-compose up --force-recreate --build` の実行

## v8 -> v10　にあげる際の問題に対応

こちらにある通り以下のコマンドを実行(db系のマイグレート)
* `sudo docker-compose stop server scheduler scheduled_worker adhoc_worker`
* `sudo docker-compose run --rm server manage db upgrade`
* `sudo docker-compose down`
* `sudo docker-compose up -d`

https://discuss.redash.io/t/upgrade-v8-to-v10-error/8799/2

これで画面アクセスして問題なくクエリの実行etcできたのですが db のスキーマ情報が見れなくなったのでこちらを参考に
`adhoc_worker` の `QUEUES` に `schemas` を追加

```yml
  adhoc_worker:
    <<: *redash-service
    command: worker
    environment:
      QUEUES: "queries schemas"
      WORKERS_COUNT: 1
```

https://qiita.com/uetaket/items/881b7bb5f289d500d32f

## 参考
https://qiita.com/uetaket/items/881b7bb5f289d500d32f
https://sadayoshi-tada.hatenablog.com/entry/2021/11/04/090000
https://github.com/getredash/redash
https://hub.docker.com/r/redash/redash
Pytorchモデル(AnimeGAN2)をONNXにエクスポートする

# AnimeGAN2をエクスポートします
![68747470733a2f2f63616d6f2e716969746175736572636f6e74656e742e636f6d2f373461303262366530623830653532633261653361663739386339336565613961613365333934642f363837343734373037333361326632663731363936393734363132643639366436313637363532643733373436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/4032b2f8-cdd2-036a-5d11-5685b4462bf3.png)

![68747470733a2f2f63616d6f2e716969746175736572636f6e74656e742e636f6d2f333131333439646134373133366666396365363137303164303963653539646336363363393562662f363837343734373037333361326632663731363936393734363132643639366436313637363532643733373436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ca2ffd02-7c22-fcbb-76c2-66f16f4b0fd0.png)

# 手順

```python
import torch

# Get the model from torch hub.

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v1").eval()

# Convert.

dummy_input = torch.randn(1, 3, 512, 512)

input_names = [ "input" ]
output_names = [ "var_444" ]

torch.onnx.export(model, dummy_input, "animegan2_face_paint_512_v1.onnx", verbose=True, input_names=input_names, output_names=output_names, opset_version=11) 
## Specify opset_version for upsampling layer.
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
【PHP】__construct(コンストラクタ)をなぜ使うのか？

# ※__constructをなぜ使うか？

インスタンスの生成した瞬間実行できるから
※クラスの初期値を設定できる

```PHP 
<?php
class Food
{
    function __construct($id,$name,$age,$height,$weight)
    {
        $this->id = $id;
        $this->name = $name;
        $this->age = $age;
    }
    function profile(){
        return '社員番号:'.$this->id.PHP_EOL.'名前は'.$this->name;
    }
    
    function introduction(){
        return $this->name.'の年齢は'.$this->age;
    }
}

$id = 12;
$name = '雅也';
$age = 34;
$height = 176;
$weight = 80;

$food = new Food($id,$name,$age,$height,$weight);

echo $food->profile();
echo PHP_EOL;
echo $food->introduction();
```

# 結果
```
社員番号:12
名前は雅也
雅也の年齢は34
```
M1 Macで有線LANが繋がらない問題

せっかく購入したM1 MBPで有線通信できない...!!
Appleサポートに連絡したりしても解決せずドハマりしたので、共有。

## 構成

- PC : Macbook Pro 14inch 2021
- OS : Monterey 12.2.1 (12.3 でもダメだった)
- 外付けハブ : Caldigit ts3 plus
- セキュリティソフト : Kaspersky 21.1.0.150c

2022/7/1 追記: OS 12.4 / 21.1.0.150c.d.e で解消されているのを確認しました。

## 症状

- Wifiには繋がる
- 同じルーターから出てる有線LANで通信できない

## 問題

Kasperskyの「ネットワーク攻撃防御」機能と、M1チップのMonterey相性が悪いらしい
https://community.kaspersky.com/kaspersky-internet-security-13/internet-connection-blocked-on-macos-12-and-m1-chip-21311

Apple側のアップデートになるか、Kaspersky側のアップデートになるかは不明だが、そのうち解消されると思う。

## 暫定対応

- カスペルスキーのネットワーク攻撃防御機能をOFFにする（したくねぇー...）
- or wifiを利用

## さいごに

ホワイトリスト対応をしようと思ったけど（できるのか？）そもそもハブが外部ネットワーク判定になってるのかな...? と思って諦めた。
つまりハブを仮にホワイトリストに入れたとして、そこから通信してるかぎり全て素通りになるのではないかという予想。

Wifiだとちょっとリモート会議のときにラグったりしちゃうので、有線がいいんですよね。
ということで、いったんネットワーク攻撃防御機能をOFFで生活することにすゆ...

## おまけ

同じ問題かわからなかったので、一応コミュニティに投稿しておいた。
追いたい人用にリンクを貼っておきます。
https://community.kaspersky.com/kaspersky-internet-security-13/ethernet-from-usb-hub-blocked-on-macos-12-and-m1-chip-23451
RDSの各ログをCloudWatchLogsに出力する時に地味にハマったこと 

## はじめに
AWSではRDSの各ログをCloudWatchLogs側に出力することが可能です。

ということで先日それを試してみたところ無駄にハマってしまいました。

この記事ではどこにハマって、結局どうしたのかの備忘録を書いていこうと思います。
もし何か参考になるところがあれば幸いです。

## CloudWatchLogsへのログ出力に必要なこと

- RDS側でCloudWatchLogsへの出力設定
- ログ出力の設定をしたオプショングループの作成,RDSへ割り当て
- ログ出力の設定をしたパラメータグループの作成,RDSへ割り当て
- (RDSの再起動)

## それぞれの設定内容
今回の記事ではハマったことに関しての記載が目的ですので、
それぞれの設定内容については特に記載しません。

それぞれの設定内容については、

https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-aurora-mysql-logs-cloudwatch/

https://dev.classmethod.jp/articles/rds-mysql-mariadb-export-cloudwatch-logs/

https://blog.denet.co.jp/rds-mysql-cloudwatch-logs/

上記が参考になるかと思います。

## 私がハマったところ

私は上記のサイトを参考にCloudWatchLogsへの出力設定、オプショングループ・パラメータグループの作成と割り当てをしたのですが、ログが出ませんでした。

なんでかなあと思い、実際に私が設定した内容とドキュメントに記載の設定との差分を確認したり、MySQLだと設定内容が違うのかと調べたりしたのですが分からず困りました。

しかしよくよくRDS側の設定をみていたらこんな文字が。

![capture49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523625/4f492c04-4889-9921-97ca-0a3d4b1efd3c.png)

はい。

お察しの通り、**再起動がまだされておらず実際には設定が反映されていなかった**ということです。

今回私はすでに作成済みのRDSに後からオプショングループ、パラメータグループを割り当てました。
その際、すぐに適用するか、次回のメンテ期間中に適用するかと聞かれるのですが、
この時次回のメンテ期間中を選択してしまっていたんですね。

そのため、変更内容の適用が実際にはその時には反映されておらず、
ログも出力されなかったということです。

RDSを新規作成する際には考えなくていいですが、
すでにあるRDSの設定を後から変更する場合はその内容をすぐに適用するか否かというのはちゃんと考えて設定しましょう。


## あとがき
「基本設定を変えたらリロードする」なんてことはサーバー上で設定しているとまず忘れないですが、AWSのコンソール上でポチポチやっていると意識から外れやすいですね。

クラウドも結局はどこかの物理サーバー上で起こっていることだということを改めて感じた出来事でした。
S3のTransfer accelerationの速度比較ツールを使ってみた

## はじめに

S3の Transfer acceleration の速度比較ツールが提供されてるので試してみました。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/transfer-acceleration-getting-started.html

Transfer accelerationを実際に導入する際には結構値が張るので注意です。

https://aws.amazon.com/jp/s3/pricing/


## 速度比較ツール

AWS謹製ツールなので、バケットポリシーやACLで公開しなくても使えました。
通常モードでアップロードした場合とTransfer accelerationを使ってアップロードした場合の速度を比較してくれるみたいです。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/transfer-acceleration-speed-comparison.html


### 使い方
`https://s3-accelerate-speedtest.s3-accelerate.amazonaws.com/en/accelerate-speed-comparsion.html?region=region&origBucketName=yourBucketName`
にアクセスするだけです。
（ `region` `yourBucketName` は自分のバケットのリージョンとバケット名に置き換える）

### 結果

共有用リンクも発行できるみたい。

https://s3-accelerate-speedtest.s3-accelerate.amazonaws.com/en/accelerate-speed-comparsion.html?result=02608-09469-7001-02202&identityId=us-east-1:af659bd0-9e6a-43ab-a48a-1ea047c2dd4d

スクショも貼っておきます。

![Screen Shot 2021-12-10 at 22.33.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187545/1d79efb4-d81f-00ff-9c8f-e548eb8e62e4.png)
![Screen Shot 2021-12-10 at 22.44.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187545/7ef9212a-0336-b067-757a-94c342bd3041.png)
![Screen Shot 2021-12-10 at 22.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187545/2a45758f-f147-87c1-a766-94da5442ff08.png)

絶対値は教えてくれないみたいですね。

バケットは東京にあるので、東京からのアップロードは他と比べるとそこまで上がらないようです。

東京から遠いリージョンほど高速化の恩恵を受けてますね。
世界中から単一のS3バケットにアップロードする時にかなり高速化できそうです。


## CloudFront との違い

こんな感じかと思ったんですが、違うみたいです。

* CloudFront: レイテンシを抑える
* S3 Transfer acceleration: スループットを上げる


> Amazon S3 Transfer Acceleration は、クライアントと S3 バケットの間で長距離にわたるファイル転送を高速、簡単、安全に行えるようにするバケットレベルの機能です。Transfer Acceleration は、Amazon CloudFront の世界中に点在するエッジロケーションを利用します。エッジロケーションに到着したデータは、最適化されたネットワークパスで Amazon S3 にルーティングされます。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/transfer-acceleration.html


* CloudFront: readアクセスが多い場合
* S3 transfer acceleration: writeアクセスが多い場合
という使い分けが良さそう。

> S3 transfer acceleration is essentially Cloudfront without the edge cache. If your content is relatively static then Cloudfront edge caching will greatly improve the user experience. If the content changes frequently (doesn't benefit from caching) then S3 acceleration is a good option because the request is made through the optimized Cloudfront network which is often a lot faster than most consumer grade ISP networks.

https://www.reddit.com/r/aws/comments/k9xqj2/s3_transfer_acceleration_vs_cloudfront_for/


## 終わりに

やっぱり数値で比較するの面白いですね。
実際に使ってる方いたら使用感教えてくれたら大変嬉しいです。
Rust 言語仕様06 構造体（enum）

前回に引き続き、構造体についてアウトプットしていきます。
今回は`enum`（列挙型）です。

### まずはコード

The Rust Programming Languageにもあります。

```rust
enum OS {
    Windows(u32, String),
    Mac(u32, String),
    Linux(u32, String),
}

let linux = OS::Linux(1991, String::from("linus")); // 実態
pattern_match(linux); // Linux : First release in 1991 by linus

fn pattern_match(os: OS) { // マッチングパターン関数
    match os { // ※1
        OS::Windows(year, who) => {
            println!("Windows : First release in {} by {}", year, who);
        }
        OS::Mac(year, who) => {
            println!("Mac : First release in {} by {}", year, who);
        }
        OS::Linux(year, who) => {
            println!("Linux : First release in {} by {}", year, who);
        }
    }
}
```

`enum`で用意した内容に該当しているパターンがあればコンソールに表示させるといった関数（`pattern_match`）と関数の引数に入れる実態（`linux`変数）を用意し、`pattern_match(linux);`で実行します。結構シンプルです。

matchフロー制御演算子を利用し上記を実現させます。※1
Mac OSでバックスラッシュを入力したい

# はじめに
１月〜プログラミングスクールで学習しています。
これから平日は毎日何かしらアウトプットのため投稿を続ける予定です。
プログラミングでよく使われるバックスラッシュ（\）をどうやって入力するかが分からなかっため調べました。

# 環境
- macOS Big Sur11.6.4で動作確認

# 　入力方法
macOSをJISキーボードで使っている場合下記で入力できる。
- option+¥

他にも設定からそもそも”¥キーで入力する文字”を”\（バックスラッシュ）”に変更することもできるようだが、今回は割愛します。
【備忘録メモ】Dockerをつないでlocalhostに接続する

<h3>Dockerを起動する</h3>
まずDockerを起動させる。起動したらMacの一番上にアイコンが出現する。

<h3>コマンド</h3>
①現在使っているディレクトリへ移動する

②下記打ち込む

```
docker-compose up -d nginx php-fpm mysql phpmyadmin
```

これで*localhost*に接続できるようになる
Node-RED2.2の新機能: エディタの機能追加

## はじめに
[Node-RED](https://nodered.org/)の最新バージョンであるv2.2ではフロー編集を便利にする機能がいくつか追加されました。この記事では、これらの機能追加内容を紹介します。

## 検索履歴
![検索履歴](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/48fc6d11-d0af-690a-9099-cf19f2fe8447.gif)
Node-REDのエディタでは、Ctrl-F(あるいはCmd-F)でフロー内のノードが検索可能です。v2.2からは過去の検索内容が保存されるようになったので、同一の検索を多数行うときなどに検索履歴から選択することが可能になります。

## 各ワークスペースのズームや位置の記憶
![ズーム量などの記憶](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/45a4e286-33b7-493c-ef43-863b2b1ed06b.png)
ワークスペースはズームやスクロールが可能ですが、これまではズーム量や表示していた位置はリロード等を行うと初期設定に戻ってしまっていました。v2.2からは、ユーザ設定にて「読み込み時に拡大/縮小のレベルを復元」「読み込み時にスクロール位置を復元」を有効にしておくと、これらの情報が記憶されるようになります。

大きなフローをズームアウトして編集しているときや、スクロールさせてその一部だけを編集しているときなどに便利な機能です。

## ノードの取り外し
![ノードの取り外し](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/9e4f63ba-c1a9-d7eb-3141-8b36743f39e7.gif)
多数のワイヤがつながっているノードをそのフローから外したり削除しようとすると、これまでは一つ一つワイヤを外したうえでまた改めてその間をつなぎなおすという作業が必要でした。v2.2から、取り外すノードの前後の接続関係を保ったままノードを取り外す機能が追加されました。

ノードの前後の接続関係を保ったままノードを削除する際には、対象ノードを選択してCtrl-Del(あるいはCmd-Del)を押します。

また、選択したノードをフローから取り外すときには、まずこの機能に対するキーボードショートカットをアサインします。キーボード設定にて、「選択ノードを接続から外す」に対して好みのショートカットをアサインしてください。下図ではCmd-Bをアサインしています。

![ノードの取り外しのショートカット設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/ff2b108e-ab88-f345-5375-6a2533e7aa9a.png)

この設定をしたのち、対象ノードを選択してキーを押すとそのノードがフローから取り外されます。

## 複数ワイヤの選択
![複数ワイヤの選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/61ff2c0c-8184-56a3-e823-e32d924d0d2f.gif)
Ctrlを押しながらワイヤをクリックすることで、複数のワイヤを選択することが可能となりました。ただし、1つめのワイヤをクリックするときにはCtrlを押さずにクリックしてください。1つめのワイヤをCtrlを押しながらクリックすると、選択したワイヤにノードを挿入する機能が起動してしまいます。

## ワイヤの切断
![ワイヤの切断](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/18c9d92e-5368-3e61-b7d0-36bff7832c3f.gif)
ワイヤの切断にも便利な方法が追加されました。ワイヤを選択してdeleteを押す方法に加えて、Ctrl(あるいはCmd)と右ボタンを押しながらドラッグするとその経路上にあるワイヤが切断されます。マウスカーソルをカッターとして画面上のワイヤを切断していくイメージです。

## サブフローの出力ポートのラベル
![出力ポート](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889500/21fe5cf8-8d21-a307-a8b5-2de390b345d6.png)
サブフローを編集する際に、サブフローテンプレート上では出力ポートのラベルは表示されず、単にポートの番号が書かれた仮想的なノードとして表示されていました。v2.2からは、「プロパティを編集」⇒「外観」の中の出力ポートのラベルを追加すれば、テンプレート内でもノードの名前として表示されるようになりました。これによって、適切なラベルをつけることで各出力ポートの役割がわかりやすくなります。

## 終わりに

この記事では、Node-RED v2.2でのエディタ関連の機能拡張について紹介しました。v2.x系のリリースはこれが最後で、次はv3.0のリリースが2022年4月末に予定されています。

## 参考

- [Node-RED2.2の新機能: システム定義の環境変数](https://qiita.com/HiroyasuNishiyama/items/7d592755127ac2c8011a)

*Node-RED: Node-REDは，OpenJS Foundationの米国およびその他の国における登録商標または商標である。*
ReferenceError: exports is not defined TypeScriptのコンパイルは成功してもブラウザが読み込まなかった件


## きっかけ
- [こちら](https://qiita.com/se_tachibana/items/5d3cb8fac1bf3f3c0574)でlaravel-mixをv5からv6にアップデートして起きたコンパイルエラーを改善した｡その後ブラウザのコンソールで遭遇

``` 
ReferenceError: exports is not defined
```

## 改善方法の結論
``npm install @babel/plugin-transform-modules-commonjs``
## 原因
完全には理解できなかった｡
installしたパッケージのリファレンスを見る限りtsconfig.jsonで設定している
```
"compilerOptions": {
    "target": "ES5", 
    "module": "commonjs", 
...
```
ここが起因していることが把握できた
パッケージをインストールすることでES5の形式をcommonjsに形式に変換できるよにしている

以上のことからlaravel-mixをv5からv6にアップデートしたことでこの機能が失われ パッケージインストールしたことで読み込めるようになったよう考えられる




### 参照リソース
[参考サイト](https://stackoverflow.com/questions/43042889/typescript-referenceerror-exports-is-not-defined)
[リファレンス](https://runebook.dev/ja/docs/babel/babel-plugin-transform-modules-commonjs/index)
自分のグローバルIPを確認する方法

# 下記のいずれかで確認可能

- CMANにアクセスする場合
https://www.cman.jp/network/support/go_access.cgi


- Bashでコマンド実行する場合
```
$ curl inet-ip.info
```
IPv4で返ってきた

```
$ curl ifconfig.io
```
IPv6で返ってきた
【個人開発】全部おれの声！？2歳娘のために簡易ゲームをつくった【React】

## はじめに

全国のパパ・ママエンジニアのみなさん。こんにちは。
2歳〜3歳くらいの子どもって動物大好きですよね？

わたしには2歳8ヶ月の娘がいるのですが、特にカピバラが大好きです。
そんな動物大好きっ娘のために簡易ゲームをつくりました。

## つくったもの

[Animal Sounds 〜おとあてげーむ！いきものどーれだ？〜](https://animal-sounds.cocoroworks.net/)
![dist.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/e271fa86-ff96-880c-aad5-11f684a76e5a.jpeg)

内容はとってもシンプル。
動物の音が流れるので、その音に合う動物（いきもの）を選択肢の中から選ぶゲームです。

## 作った目的（解決したい課題）
2歳といえば、いろいろなものに興味が湧いてくる年頃。
わたしの娘も例外でなく、まいにちさまざまなものに興味を示しています。

中でも、最近いちばん好きなのが動物。
毎晩のように動物図鑑を持ってきて、「ぱぱー。読んでー。」とせがんできます。

そんなに動物が好きなら、動物園に連れて行ってあげたいなぁと思いつつ、コロナ禍で頻繁に外出するわけにもいかない。

「なんとか、動物図鑑だけでは味わえない、もう少しだけ相互性のある体験ができるプロダクトはないかな？」

その結果、出来上がったのが今回のゲームです。


## 企画コンセプト
ゲームでもなんでも、何かプロダクトを作るのなら企画書は必要です。
すごく簡易ですが、ゲームを作るにあたって下記のコンセプトとビジョンを予め決め、企画書を作っておきました。

![concept.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/4fb001e0-5603-d355-9846-143b8ad6ed0a.jpeg)

## ビジョンについて

### 限りなくシンプルに！
2歳が遊ぶゲームなので、余計な機能はいっさい付け加えないことにしました。

「どうぶつの音が流れて、答えを選択肢から選ぶだけ」

という内容にすることで、直感だけで遊べるゲームを目指しました。

本当はログイン機能があったり、正解率が出たりとゲーム性をあげることも考えたのですが、娘がそんな機能を望むかと検討した結果、すべて削ぎ落としました。

### 迷わないUI。音で盛り上げる。
今回音声ゲームにした最大の理由として、UIがあります。
2歳だとまだ字が読めないのと、複雑な操作をすることも困難です。

どうしようか？と考え、実際に2−３歳の子どもが遊ぶようなゲームアプリを観察したところ、音声（キャラクターの声など）が多用されていることに気づきました。

平易な言葉なら、2歳くらいの子どもでも理解できると思ったので、音声形式のゲームにしました。

### コスト０
今回のような音声当てゲームをつくるにあたって、コスト面は絶対に0にすると決めていました。
あくまで**開発者のわたしにとっては**、それこそが他の類似プロダクトとの差別化につながると考えたためです。

コスト０を実現するために、画像は[unsplash](https://unsplash.com/)から拝借させていただきました。

また要となる音声ですが、フリー素材だとすべての動物の音がカバーできそうになかったので、[七声ニーナ](https://nanakoe-nina.dena.ai/)というサービスを利用することにしました。
※2022年3月末でサービス終了みたいです。

![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/bb01c124-35d9-be67-13cf-c89de4603730.jpeg)

### すぐに飽きさせない
出てくる選択肢がいつも同じで、答えも同じだったら1回やったらすぐに飽きてしまうと思いました。

そこで、毎回ランダムな選択肢を作り、答えも毎回違うようにプログラムを組みました。

### 外れても否定をしない
当初、正解ではない動物を選んだ場合は「はずれー」という音声にする予定でした。

しかし、子どものことを考えるとそれはどうなのか？と。

せっかくのゲームだから楽しく遊んでもらいたいと考え、「惜しいです！」の音声に差し替えました。


## 実際に使ってもらった反応
実際に娘に使ってもらいました。
期待通り、直感で遊び方を理解したようで、楽しく遊んでくれました！

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/63719745-5f88-d1a8-2751-2ea77ba714c1.png)


## 使用技術
- React　v17.0.2
- TypeScript　v4.5.5
- Material UI v5.4.2
- Emotion 11.8.1
- ESLint/Prettier

## 苦労した点

実ははじめてReactとTypeScriptを触ったため、2週間ほど基礎学習をするところから始めました。
そのため、Reactのコンポーネント分割やTypeScriptの型定義に慣れるのが苦労しました。

また動物の画像や音声データを準備するのが地味にしんどかったです。
おっさんが朝6時に動物の鳴き真似をして、音声録音を繰り返すという地獄絵図が我が家に生まれていたのは遠い過去のお話です。

## プルリク募集中！

さいごに、今回のアプリはReact初心者がつくったアプリなのでコード品質はあまり良くないと自覚しています。
もし、「Reactはチョットデキル」的な方がいらっしゃったらぜひGitHubからコードレビューいただき、あわよくばリファクタリングついでにアドバイスくれたりしたらとても勉強になります！

https://github.com/Naughty1029/animal-sounds
FlutterでCloud Firestoreを使う（Web）

下記の記事で、AndroidでCloud Firestoreを使う方法を記載しましたが、それをWebアプリに適用する方法を記載します。

https://qiita.com/shimizu-you/items/3c612bb2885b10581a78

* Firebaseの準備

Firebaseのプロジェクトの設定で、Webアプリを追加します。
追加すると下記の情報が取得できます。

```
const firebaseConfig = {
  apiKey: "xxx",
  authDomain: "xxx",
  projectId: "xxx",
  storageBucket: "xxx",
  messagingSenderId: "xxx",
  appId: "xxx",
  measurementId: "xxx"
};
```

* Flutterの実装

  * 変更前

```dart:main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}
```

  * 変更後

```dart:main.dart
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    name: "xxx",
    options: const FirebaseOptions(
        apiKey: "xxx",
        projectId: "xxx",
        messagingSenderId: "xxx",
        appId: "xxx",
    ),
  );
  runApp(const MyApp());
```

上記の情報を追加することで、Webアプリが使用することが出来ます。
laravel-mix 5→6 にバージョンアップしてハマりました｡error: unknown option ‘--hide-modules’ [webpack-cli] Run ‘webpack --help’

laravel mix をバージョンアップしたらハマったので黙示録


## きっかけ
1. 脆弱性チェック
``npm audit``
1. 脆弱性をみつけたので 愚かにも 何も考えずに 
``npm audit fix --force``
1. 気づかずlaravel mixがアップデートされていたことに気づく
1. 今後のためにも対応させたいと思い立つ
1. はまる
``error: unknown option ‘--hide-modules’ [webpack-cli] Run ‘webpack --help’ ``

## 改善方法の結論
- package.jsonの scriptsの書式をlaravel-mix v6に合わせて編集
```
"scripts": {
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "production": "mix --production"
}
 ```
- webpack.mix.jsをlaravel-mix v6に合わせて編集
```
mix.ts('resources/ts/app.tsx', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.react();  //ここ追加
```

## 教訓
-  ``npm audit fix --force``は安易に使わない
-  リファレンスを真っ先に探す






### 参照リソース
[リファレンス](https://laravel-mix.com/docs/6.0/upgrade#update-your-npm-scripts)
開発効率向上のためdockerでコンパイルを行う

## 目的
- docker環境でコンパイルを実施する。

## 利点
- 開発者のチームでVersionを揃えることができる。
- ホストマシンにNode.jsなどをインストールする必要がないので、開発環境の構築と運用が楽になる。
- システムの実行環境にnodeが入っていない場合、コンパイル用のイメージを分けることで実行環境用のdockerイメージが小さくなる。
  - 今回はマルチステージビルドの話はないです。

## 実施方法
- Dockerfile
```
FROM node:{DockerHubで公開されているTagのバージョン番号を入力してください。}
RUN yarn add node-sass@{node-sassのバージョン番号を入力してください。}
CMD node_modules/node-sass/bin/node-sass ./app/assets/scss/mdb.scss ./app/assets/css/mdb.css --output-style expanded
```

- makefile
```
scss:
  docker build -t node-sass-compaile ./ && docker run --rm -v $$PWD/app/assets:/app/assets node-sass-compaile
```

## 説明
Dockerfileでもvolumeの設定は可能ですが、Dockerfileに記載した場合はホスト側との共有はできません。そのため、コマンド実行時にボリュームを指定してあげる必要があります。
実行環境にdockerを使用している場合はボリュームの共有はできますが、gitへのプッシュや実行環境がまだdockerじゃないと言う方もいると思うので、ホスト側と共有するためにコマンドでボリュームを指定しています！

dockerコマンドでボリュームを指定するとコマンドが長くなるため、makefileやVSCodeのtask.jsonにdockerコマンドをあらかじめ記載しておくと楽になります！

## 感想
dockerは使えば使うほど、ローカル環境に依存されなくて良いなぁと感じています！
もうdockerなしの生活には戻れない・・・・・・。
HTML,CSS 凡ミス

# 超不器用な自分がHTMLの学習でinputとimageを間違えた話。


## 本日はHTML,CSSでサイト作り実践...のはずが
本日から学習したことを活かしてサイト作り実践(模写)に入りましたが早速ヘッダーの作成から間違えてしまいました...。

## 対象読者
- IT業界完全未経験者
- IT業界初学者

## どこが間違えているか

先ずはサンプルの模写サイトを確認、headerの部分のロゴマークはボタンみたいになってるからinputタグを使おう！
```html
<input type="button" value="ロゴマーク">
```
はいこの時点で間違いですね、当時の自分の中ではボタンみたいに押せる=inputタグを利用してvalueを設定して…みたいな思考になってました。

その時点で学習不足なのが露呈したので再度復習です。

先ずはボタンみたいでは無くリンク先に飛ぶ、又は画像をクリックしてる(今回の例だとロゴマーク)と認識した上でコーディング、そして改めてタグの意味を理解した上で
```html
<img src="ロゴマークのファイル名" alt="ロゴマーク">
```
と書くのが正解でした、この様にタグの意味や模写するサイトの仕様(リンク先に飛ぶのか画像ファイルを開いているのか等)を理解しない事にはサイト制作どころか模写も出来ません…。

ですがこうして間違いや忘れた個所はその都度復習してまた実践をこなして行けばいずれ上達すると勝手に思い込んでおります！
Mavenプロジェクトの全プロセスとFilter


# プロジェクトの全プロセス
1.新しいMaven projectプロジェクトを作成します
2. WEB-INFフォルダ内web-xmlファイルを補足します
```java
    <servlet>
    <description></description>
    <display-name>UserController</display-name>
    <servlet-name>UserController</servlet-name>
    <servlet-class>com.vanilla.controller.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserController</servlet-name>
    <url-pattern>/user</url-pattern>
  </servlet-mapping>
```
3.プロジェクト内必要なjarパッケージをpom.xmlファイルに追加されました
```java
        <!-- servlet jarパッケージ -->
		<dependency>  
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<!-- dbcp jarパッケージ -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
```
４.データベースを作成します----- Java Beanのクラスに対応します（このクラスでは、mySQLフォーム内のプロパティを記述します）
```java
public class User {
	private int id;
	private String userName;
	private String passWord;
	private String nickName;
	private String avatar;
	private Date created;
	private Date updated;
	private int status;
}
```
５.controllerでページから渡されたパラメータを受け入れ、受信されたかどうかを判断します
```java
public class UserController extends HttpServlet {
}
```で
６.serviceで補足ページで渡すことができないデータ、および処理ロジック
```java
public class UserServiceImpl implements UserService {
}
```
７.dao操作mySQL
```java
public class UserDaoImpl implements UserDao{
}
```
# Filterのパスをインターセプト（intercept）する方法
すべてのパスをインターセプトします
```java
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern> 
```
vanillaShowのパスをインターセプトします
```java
    <filter-name>MyFilter</filter-name>
    <url-pattern>vanillaShow</url-pattern> 
```
vanillaを含むパスをインターセプトします
```java
    <filter-name>MyFilter</filter-name>
    <url-pattern>vanilla*</url-pattern> 
```


#
nRF Connect SDK:スリープってできないの・・・？

# スリープ命令というのは存在しない
nRF SDKにはスリープモードに移行するためのAPIが存在していました。ところが、nRF Connect SDKはRTOSであるため、そのようなAPIは(調べた限りでは)存在していません。
## スリープスレッドというのが存在するらしい
その代わり、RTOSということでスリープ用のスレッドが最も優先順位が低い指定で最初から存在しているようです。優先順位が一番低いということなので、他に全くスレッドが動いていない場合に実行されることでスリープ状態ということになるようです。
## が
やってみても全然そんな風になりません。えっ、なぜなっていないのかが分かるのかって？だって電池消費がすごいですもん・・・1日で電池が空っぽに近くなってしまうのでどう見てもスリープスレッドが動いているようには見えません。
# 誠意調査中ですが・・・
おそらくBluetoothの初期化などを通すとスリープスレッドよりも優先順位の高いスレッドが動いてしまって、そのせいでスリープスレッドが起動しないのではないかと考えていますが、ソースコードを見てもよく分かりません。スレッドの初期化はいっぱいありますが初期化しただけでは動かなさそうなんですよね・・・。
しかも、Bluetoothの初期化って、初期化はできるけれど初期化を解除(なんで言うんだ、日本語でUn-initializedって存在しないよね)することができないので、もしこの仮説が正しいとした場合、機器の電源を入れたままスリープスレッドを使うことが事実上不可能なんじゃないかと思っています。
(Bluetoothを使いたいときだけ初期化する、ということができないので)
# ということで
To be continued...
駆け出しエンジニアのCI改善 (その1 seed.rbの作成)

## 自己紹介: 駆け出しエンジニア
はじめまして。
私はRailsで自社サービスの開発を行っている駆け出しエンジニアです。
2020年11月|エンジニアとしての学習を開始
---|---
**2021年5月**|**エンジニアへ転職**
**2022年3月**|**現在**(10ヶ月目)

現在、自動テスト作成の業務に取り組んでいます。
取り組んだことや気づいたことについて少しずつ記載して行きたいと思います。

### 実行環境: Ruby3.0 & Rails6.0
Ruby|3.0.3
---|---
**Rails**|**6.0.4.6**

## 目標: GithubActionsでテストを並列実行する

4つのステップに分けて進めて行きます。
1. テスト用DB作成の為にseed.rbを作成する **← 今回の記事**
1. [GithubActionsで自動テストを作成する](https://qiita.com/KON-ch/items/6744145c7ee66b344c3e)
1. 自動テスト実行時にテストカバレッジの測定をする
1. GithubActionsのテストを並列で実行したい (目標)

ということで、今回は1の **テスト用のDB作成の為にseed.rbを作成する** について記載します。

## 今回やること: DBの内容をseed.rbに書き出す
- テスト実行に必要なDBを作成する `seed.rb` を作る。
- 作成するseedは開発環境のDBから書き出す。

## 手段: gem 'seed_dump'
`seed_dump` というDBからseedを作成することができるgemを使用しました。

### Githubへのリンク
https://github.com/rroblak/seed_dump

## 使用理由: DBの内容をseedに書き出したい
自社では市区町村や駅などのマスターデータを使ったテストがあり、
テスト実行の為にはマスターデータが入っているDBを用意する必要があります。

現在は、CSVからマスターデータをインポートする仕組みがあり、更新処理ではこの仕組みを使っています。

しかし、この処理は実行に時間がかかるという課題があり、
CIでテスト実行の度にCSVからインポートすることは相応しくありませんでした。

また、現状のマスターデータに合わせたseedを作成することも検討しましたが、
これらは変わるものであり、その度にseedを作り直すのは大きなコストになります。

更新されたDBのマスターデータに合わせて、素早くseedを作り直したいという点からseed_dumpを使用しました。

## 使用感: シンプルでわかりやすい
使い方はREADMEを参考にしました。
1. Gemfileに追加してインストール
   ```sh
   # Gemfileに追加
   gem 'seed_dump'

   $ bundle install
   ```
1. モデル別にseedを作成
   ```sh
   # db配下にseedsディレクトリを作成
   $ mkdir db/seeds

   # (例)Cityという市区町村のモデルの場合
   $ rake db:seed:dump MODELS=City FILE=db/seeds/cities.rb EXCLUDE=created_at,updated_at
   ```
   `MODELS`で対象となるモデルを、`FILE`で出力するファイルを指定しています。

   また、`EXCLUDE`は対象外にするカラムを指定します。
   デフォルトでは `[:id, :created_at, :updated_at]` が除外対象となっています。

   今回はseedでDBを作成する際にIDを指定したいという点から `EXCLUDE`を上書きしてIDをdump対象にしています。
   (READMEに記述されていますが、モデル未指定での実行や `models_exclude` を設定することで対象外のモデルを設定して実行することもできるそうです)

1. 作成されるファイルの例
   ```rb:db/seeds/cities.rb
   City.create([
     { id: 1, name: ... },
     { id: 2, name: ... },
     ...
   ```
   バリデーションをスキップしたいなどあればお好みで`insert_all!`にしても良いかもしれません。
   ```diff
   - City.create()
   + City.insert_all!()
   ```
1. seed.rbで読み込む
   ```rb:db/seed.rb
   # 作成したファイル名を並べます
   %w[
     cities
     ...
   ].each do |table_name|
     path = Rails.root.join("db/seeds", table_name + ".rb")

     raise StandardError "#{table_name}.rbが見つかりません"　unless File.exist?(path)

     require path
   end
   ```
1. 実行
   ```sh
   $ rails db:seed
   ```
## まとめ: `db:seed` でテストに必要なDBを作成
`rails db:seed`で空のDBからテストに必要なデータを持ったDBを作成することができるようになりました。
## 次回: GithubActionsを使った自動化
開発環境でテスト用のDBを用意してテストを実行することができるようになりましたので、
次回はGithubActionsを使用した自動テストへの取り組みについて記載したいと思います。

最後まで読んで頂きありがとうございました。
ブロードキャストによるスプライト間つうしん「こども向けのSnap!かいせつ」

<a href="https://qiita.com/wordplugin/items/6f6644aaa46acd54e7ed">スプライトとへいれつ実行</a>でみたように、二つのスプライトを同時に動かすことができます。一つのスプライトがほかのスプライトに、話しかけることもできるのです。例えばこのようなスクリプトをつくってみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/f0cabb7a-fe8a-d73a-75b6-8756e7b3c0c1.png)　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/e4466c92-f65f-58bc-2152-cb171aa4e763.png)
アビーとアロンゾがかわるがわる話しているように動いていると思います。
「［］をおくってまつ」ブロックの［］のとなりの三角をクリックしてあらわれるメニューで、「しんき」を選ぶと新しいメッセージを作ることができます。
このブロックが動くと<b>すべての</b>スプライトやステージにメッセージが送られます。このことを「ブロードキャスト」といいます。このスクリプトでは、アロンゾだけがアビーが送ったメッセージを受けとっています。
アビーのスクリプトは「［］をおくる」ブロックではなく、「［］をおくってまつ」ブロックを使っているので、アロンゾがメッセージを受けとってそのスクリプトが終わるまで、アビーのスクリプトは次に進みません。これが一度にすべてのスクリプトが動かずに、二つのスクリプトがお話をしているように見える理由です。

ところで、「［］と［］びょういう」のブロックのひとつめの［］の部分は円形ではなく、四角形になっています。これは、数字ではなく文字を入力することができることをあらわしています。文字を入力できる［］の中で、スペースは茶色のドットであらわされます。茶色のドットの数を数えることで、文字の間のスペースの数を数えることができます。茶色のドットがあることで、何も文字のない［］とスペースが一つだけ入った［］をくべつすることができます。そして茶色のドットがあっても、ステージ上では茶色のドットは表示されません。

ステージにはステージ用のスクリプトエリアがあります。スプライトエリアのステージのアイコンをクリックすると、ステージ用のスクリプトエリアを開くことができます。スプライトとちがって、ステージは動かすことはできません。コスチュームのかわりに、はいけいをえらぶことができます。はいけいはステージ全体に広がる絵です。スプライトははいけいよりも必ず手前にひょうじされます。難しいプロジェクトでは、多くのスプライトをうまく動かすために、ステージのスクリプトを使うといいときがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/460cc134-abd4-7d4e-157f-13f48e85bb01.png)
「［］をおくる」の［］の横の▲をおすと、「［］to［］をおくる」ブロックになります。ふつうの「［］をおくる」では<b>すべての</b>スプライトおよびステージにメッセージを送りますが、「［］to［］をおくる」ブロックは、二番目の［］に書かれたスプライトやステージに<b>だけ</b>メッセージをおくることができます。このブロックには「［］をおくってまつ」というブロックはありません。「スプライトによるオブジェクトしこうプログラミング」では、「tell」ブロックや「ask」ブロックをつかってもっとじゆうにメッセージを送ることができます。

<a href="https://qiita.com/wordplugin/items/6f6644aaa46acd54e7ed">戻る</a>
Chart.jsでプルダウンと連動して表示を切り替える

# グラフが再描画されない

プルダウンを選択すると、それに合わせてchart.jsで描画する内容を変えたかった。
・・・が、変わらない。

# $setを使ってみる

```
this.$set(chartData, 'data', response)
```

としてみたけど、これでも変わらない。


# Chart.js側の設定が必要だった

`reactiveProp`を追加してあげればOKだった。

```
import { Line, mixins } from 'vue-chartjs'    ☆★ mixinsを追加！ ☆★
const { reactiveProp } = mixins               ☆★ これを追加！ ☆★

export default {
  extends: Line,
  mixins: [reactiveProp],                     ☆★ これを追加！ ☆★
  props: {
    chartData: { type: Object, default: null },
    options: { type: Object, default: null }
  },

  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
```

[Chart.js#Updating Charts](https://vue-chartjs.org/guide/#updating-charts, 'Updating Charts')
S3連携でCORSにブロックされた時の対処法

## エラー内容
HerokuとAWS S3を連携させてデプロイしたアプリのconsoleで、以下のエラー文が出て、S3内のデータを呼び出せない🤯

```javascript:console
Access to XMLHttpRequest at '任意のドメイン' from origin '任意のドメイン' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
```

<br>

より具体的には、
Rails側からS3に保存したデータ（画像・MP3・jsonファイル）のうち、フロント側（phina.js）で使用するデータ（MP3・jsonファイル）が呼び出せなかった🤯

<br>

## 開発環境
- Rails6系（バック）
- phina.js（フロント）
- Herokuデプロイ済
- S3バケット作成済

<br>

## 解決策
結論から言うと、
バケットのCORS設定（<font color="Blue">S3＞任意のバケット＞アクセス許可＞CORS</font>）に以下を追記すると呼び出せました！！！（コピペでOK）

```javascript:CORS
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
```
実際の画面↓
[![Image from Gyazo](https://i.gyazo.com/c2ca8bcded0da3251529baf5ccf9585f.png)](https://gyazo.com/c2ca8bcded0da3251529baf5ccf9585f)


アクセス元のドメインを指定する場合は以下のようにします。
```javascript:CORS
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "https://www.example.com（指定するドメイン）"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
```


<br>


## 補足
上記S3のCORS設定で解決しない場合は、Rails側にgemを入れて設定してあげると上手くいくかもしれません。
参考：[CORSがよくわからないので解説してみた＆Rails APIでのCORS設定](https://qiita.com/mtoyopet/items/326ba62d485e9ef0dacd)
 
## 参考にさせていただいた記事
https://www.automation-technology.info/index.php/2021/02/15/post-223/

## 最後に
Rails＋S3＋CORSというドンピシャ記事がなかったので執筆しました！
この記事が同じような内容で悩める方に届けば幸いです🌱
React: useState [アウトプット全くしてこなかったのでアウトプットする008]

来週あたりからReactをほぼ半年ぶりくらいに書く機会があるので思い出していくためにアウトプットしていきます。

### useState

> React は再レンダー間で setState 関数の同一性が保たれ、変化しないことを保証します。従って useEffect や useCallback の依存リストにはこの関数を含めないでも構いません。
新しい state が前の state に基づいて計算される場合は、setState に関数を渡すことができます。この関数は前回の state の値を受け取り、更新された値を返します。以下は、setState の両方の形式を用いたカウンタコンポーネントの例です。

```tsx
function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}
```

クロージャっぽい。
stateの値が変わると見た目が変わります。
この場合、 以下のカウントの部分が変わります。

```tsx
Count: {count}
```

またこのstateのやっかいなところが更新が非同期なため、

```tsx
const countUp = () => {
  setCount(count + 1)
  console.log(count)
}
```

上記のようにしてもconsole.logで表示されるcountの値はsetConuntされる前の値になります。
最初useStateを使用した時はこの挙動で実装がうまくいかずかなり時間を溶かした思い出があります。

> コンポーネントのsetCountで更新したらブラウザ上にも反映されるのが不思議だと感じる人もいるかもしれません。即座に反映されるのはuseStateで変数の値を更新する度にコンポーネントが再実行され、ブラウザ上で変数の再描写が行われているためです。ReactではuseStateによる変数の更新だけではなくpropsが更新されてもコンポーネントの再描写が行われるということを理解しておく必要があります。再描写を行う仕組みがない場合はstateを更新しても最新の情報がブラウザに表示されることはありません。React HooksのuseCallback, useMeme, useRef等がコンポーネントの再描写に関わってきます。

ここら辺の再描画に関しての知識があまりない状態で使っていたので深掘りしていきます。

Reactが再描画されるのは以下のタイミングです。この中にstateが入っています。

> 1. stateが更新された時
> 2. propsが更新された時
> 3. 親コンポーネントが再レンダリングされた時

1と3の合わせ技で親コンポーネントのstateが更新された時に子コンポーネントがレンダリングされてしまいますね。
再レンダリングの制御に関しては以下のサイトがわかりやすいです。

https://zenn.dev/b1essk/articles/react-re-rendering#%E5%86%8D%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%92%E6%9C%80%E9%81%A9%E5%8C%96%E3%81%99%E3%82%8B


### 参考サイト

https://ja.reactjs.org/docs/hooks-reference.html#usestate

https://qiita.com/seira/items/f063e262b1d57d7e78b4

https://zenn.dev/web_tips/articles/0de2d1dd2bcde7

https://reffect.co.jp/react/react-hook-usestate-understand#useState-2

https://zenn.dev/b1essk/articles/react-re-rendering
俺のRust勉強法

こんにちは。PythonParrotです。
今回は僕がどうやってRustを勉強していたかを紹介します
これからRustを勉強しようとしている方の参考になれば嬉しいです。


# The Rust Book
公式サイトにもある日本語版の解説。
まずはここから環境構築だったり、Rustの基本を学んでいく。

https://doc.rust-jp.rs/book-ja/

# Rustlings
Rustの文法を学ぶための実践的な問題集。
やっていくとRustの文法を実践的に学べるのでおすすめ。

https://github.com/rust-lang/rustlings/


# Atcoder
Atcoder Base ContestにRustで出る。
Rustの文法を学んである程度できるようになってから。
Rustは標準ライブラリに`Vec`、`VecDeque`、`HashSet`、`HashMap`、`BTreeset`、`BTreeMap`と基本的なデータ構造は揃っているので結構対応できたりする。
あとはAtcoder環境ではproconioを使うと入力が楽になるのでオススメ。
ただ、String周りが少ししんどいのでそこは注意かも？