OmniAICreator/Qiita-1.07M huggingface dataset:
supabaseで簡単なTodoアプリを構築した話 - ０からフロント側の設定まで

# はじめに

Baas(Backend As A Service)で何かサービスを構築してみたいと思い、
firebaseを触ってみようと思ったところ、Firebase の代替と謳われているsupabaseを発見。

こちらの方が面白そうだと感じたため、構築してみることに

# 使ったもの

* Vite + Svelte + Typescript
    * @supabase/supabase-js
    * tailwind css

* supabase
    * auth
    * db
    * realtime

# ローカル環境の構築手順

## supabase

1. [supabase](https://app.supabase.com/)でアカウント及びプロジェクト作成

2. SQL Editorより以下を実行し、taskテーブルを作成する
   (todoアプリ用のため、いらない人はスキップ)

    ```sql
    create table if not exists public.tasks (
      id uuid not null primary key default uuid_generate_v4(),
      user_id uuid not null references auth.users(id) default auth.uid(),
      content text not null,
      is_done boolean not null default false,
      created_at timestamp with time zone default timezone('utc' :: text, now()) not null
    );
    ```

3. プロジェクトの設定 > APIから、Project URL及びProject Project API Keys内のanon keyをコピーしておく。

## Vite + Svelte + Typescript

### 前提
nodejsが入った環境を準備

### 構築手順

```bash
$ npm init vite@latest
  # svelte ⇒ typescriptと選択
$ cd <プロジェクト名>
$ npm install
$ npm install @supabase/supabase-js
```

vite.config.tsを修正

```typescript
//vite.config.ts

export default defineConfig({
  plugins: [svelte()],
  server: {       // 追加
    host: true,   // 追加
    port: 8080    // 追加
  }               // 追加
})
```

ここまでで`http://localhost:8080`を開くとvite + svelteのwelcome画面が出ているはず。

次に.envファイルをルートディレクトリに作成しanon keyとapi keyを設定する。

```.env
VITE_SUPABASE_URL=*****
VITE_SUPABASE_ANON_KEY=******
```

src/supabaseClient.tsを作成し、呼び出しやすくする

```typescript
// src/supabaseClient.ts

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

const realtime_opt = {
  realtime: {
    params: {
      eventsPerSecond: 10,
    }
  }
}

export const supabase = createClient(supabaseUrl, supabaseAnonKey, realtime_opt)
```

これでsupabaseをフロントで使う準備ができた。
あとは自由にコーディングを進めることができる。
次回はsupabase上のdbの操作について書きます。


例) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/4b2454e3-717f-e79e-fa34-f6b8e1057dde.png)


```vuejs
// email＋passwordのサインインの場合

<script lang="ts">
  import { supabase } from '../supabaseClient';
  let email = '';
  let password = '';

  const LoginHander = async () => {
    const { data, error } = await supabase.auth.signInWithPassword({
      email: email,
      password: password,
    });
  }
</script>

<form on:submit|preventDefault="{LoginHander}">
  // 省略
</form>

```

supabase、とってもいい感じ


### 追記

投稿しました。

https://qiita.com/doyaseizin/items/d6e0237b700448cc1826
【Photoshop】「Creative Cloudに保存」を表示させないようにする

こんにちは。E-kan株式会社の岡田です。

先日、作業用PCを移行して新しくセットアップした際にphotoshopもインストールし直したのですが、ファイル保存時に「Creative Cloudに保存」という表示が毎回出て地味に鬱陶しかったので、非表示にする方法をメモ。

## やりたいこと

「Creative Cloudに保存」という表示を出ないようにして、常にローカル環境に保存するようにする。
![スクリーンショット 2022-11-15 14.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2656687/c71ff26f-4f93-fb14-bd68-4a265dd50ddc.png)
↑これを出なくしたい。

## 手順
「環境設定」＞ 「ファイル管理」を選択
![スクリーンショット 2022-11-15 14.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2656687/fae73040-ca07-fd6d-3dfb-daf6c01773a5.png)

「ファイルの保存オプション」内「初期設定のファイルの場所」で「コンピューター上」を選択してOKボタン押下。
![スクリーンショット 2022-11-15 14.45.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2656687/4a598270-176e-2131-b791-365fafefccc9.png)

これで「Creative Cloudに保存」が表示されなくなります。
やっぱりクラウドに保存したいと思った時は、「初期設定のファイルの場所」で「Creative Cloud」を選択すればOK

クラウド保存、便利なんですけどね。
セキュリティポリシー的に禁止されてる時もありますから、デフォルトでクラウド保存を推されるのはちょっと迷惑。
プログラマー孔子「道千乗之国」


プログラマー孔子が言いました
「プロジェクトをマネジメントするのに大切なメソッドが三つあります。
インシデント対応の1つ1つをまじめに取り組んでクライアントの信用を得ること、
出来るだけマスト要件だけに絞ってプロジェクトメンバーの稼動を減らすこと、
そしてプロジェクトメンバーに残業や休日出勤のアサインをする場合には、プライベートイベントとの兼ね合いを考えてタイミングを調整することです」

# 漢文
> 子曰、道千乗之国、敬事而信、節用而愛人、使民以時。

# 現代訳

>　先師がいわれた。――
>「千乗せんじょうの国を治める秘訣が三つある。即ち、国政の一つ一つとまじめに取組んで民の信を得ること、出来るだけ国費を節約して民を愛すること、そして、民に労役を課する場合には、農事の妨げにならない季節を選ぶこと、これである。」

青空文庫
現代訳論語 下村湖人
https://www.aozora.gr.jp/cards/001097/files/43785_58836.html

# ポエム
クリスマスだけじゃなくて、その前から子供のプレゼントを買う戦いが始まってて、すいませんが今は時間が無いんですよ
OpenWetherMapのAPIを叩く[Swift]備忘録

この記事参考にした
https://auto-worker.com/blog/?p=1612

OpenWeatherMapのホームページ
https://home.openweathermap.org/

```
https://api.openweathermap.org/data/2.5/weather?lat=34.0778755&lon=134.5615651&appid={API_KEY}&lang=ja&units=metric
```

レスポンス
```
{
"coord": {
"lon": 134.5616,
"lat": 34.0779
},
"weather": [
  {
"id": 801,
"main": "Clouds",
"description": "薄い雲",
"icon": "02d"
}
],
"base": "stations",
"main": {
"temp": 21.97,
"feels_like": 21.79,
"temp_min": 21.97,
"temp_max": 22.45,
"pressure": 1013,
"humidity": 60
},
"visibility": 10000,
"wind": {
"speed": 2.57,
"deg": 60
},
"clouds": {
"all": 20
},
"dt": 1667456496,
"sys": {
"type": 1,
"id": 8027,
"country": "JP",
"sunrise": 1667424156,
"sunset": 1667462876
},
"timezone": 32400,
"id": 1857689,
"name": "万代町",
"cod": 200
}
```

アイコンは
https://openweathermap.org/img/wn/02d@2x.png
"{iconCode}@2x.png"
で取得可能

緯度経度で指定したかったのでこうした
しかし、少数点以下4桁で四捨五入される様なので

lat=34.0778755&lon=134.5615651
↓
lat=34.0779&lon=134.5616

までの指定でOK

パラメータに入れる方法がわかれば

```swift
    // OpenWeatherMapのAPIから天気情報を取得
    public func getWether() {
        let latitude = "34.0778755" // 緯度 (徳島大学の座標)
        let longitude = "134.5615651" // 経度
        let API_KEY = "xxx"
        let parameter = "lat=\(latitude)&lon=\(longitude)&appid=\(API_KEY)&lang=ja&units=metric"
        
        let urlStr = "https://api.openweathermap.org/data/2.5/weather?" + parameter
        
        state?(.busy) // 通信開始（通信中）
        apiManager.request(urlStr,
                           success: { [weak self] (response) in
            
            guard let self = self else { // HomeViewModelのself
                AKLog(level: .FATAL, message: "[self] FatalError")
                fatalError()
            }
            
            // 天気の様子が返ってくる 例: 曇
            self.weatherDiscription = response["weather"][0]["description"].string ?? "Error"
            
            // 体感気温がdoubleの形で返ってくる　例: 21.52
            if let temp = response["main"]["feels_like"].double {
                var tempStr = String(temp) // 例: "21.52"
                
                // "21.5"の時は4桁
                if tempStr.count == 5 {
                    tempStr = String(tempStr.prefix(tempStr.count-1)) // 例: "21.5"
                }
                self.weatherFeelsLike = tempStr + "℃" // 例: "21.5℃"
            }
            
            // 天気を表すアイコンコードが返ってくる 例 "02d"
            if let iconCode = response["weather"][0]["icon"].string {
                let urlStr = "https://openweathermap.org/img/wn/" + iconCode + "@2x.png"
                self.weatherIconUrlStr = urlStr
            }
            
            self.state?(.ready) // 通信完了
            
        }, failure: { [weak self] (error) in
            AKLog(level: .ERROR, message: "[API] userUpdate: failure:\(error.localizedDescription)")
            self?.state?(.error) // エラー表示
        })
    }
```

参考
https://qiita.com/tajihiro/items/6f1996a701ed8b0253e3
https://mo-gu-mo-gu.com/ios-alamofire/
GooglePlayへアプリを公開　つまづいたとこ　備忘録

debuggable false
へ変更

```build.gradle(app)
release {
    debuggable false
}
```

android:exported="false"
の追加

```AndroidManifest.xml
<activity android:name="com.???"
          android:exported="false">
```

KeyStoreの保存場所
Googleのドキュメントでは
/Users/{userName}/key/upload_keystore.jks

Youtubeでは
/Users/{userName}/Dev/key/upload_keystore.jks
としていた

備忘録
【VBA】Workbookにある署名の数を数えるマクロ

## 目的
署名付きのExcelファイルにあるすべての署名の中から、署名済み/未署名の署名欄が何件あるかを集計する。

## 環境
- Windows 10 Pro x64
- Microsoft 365 Excel 64ビット


## 概要
Workbook.SignaturesのSubsetのプロパティを指定することで、どの種類の署名に対して操作をするかを決定しています。

設定値に関しては以下のURL/表をご参照ください。
<https://learn.microsoft.com/ja-jp/office/vba/api/office.msosignaturesubset>
|名前|値|説明|
|---|---|---|
|msoSignatureSubsetAll|5|すべての非表示の署名およびすべての署名欄|
|msoSignatureSubsetSignatureLines|2|すべての署名欄|
|msoSignatureSubsetSignatureLinesSigned|3|署名済み署名欄|
|msoSignatureSubsetSignatureLinesUnsigned|4|未署名の署名欄|
|msoSignatureSubsetSignaturesAllSigs|0|すべての非表示の署名およびすべての署名済み署名欄|
|msoSignatureSubsetSignaturesNonVisible|1|すべての非表示の署名|

## コード
```.vas
Option Explicit

Sub Main()
    Dim path_ As String
    Dim wb As Workbook
    Dim totalCount As Long
    Dim signedCount As Long
    
    path_ = "***.xlsx"
    Set wb = Workbooks.Open(path_, ReadOnly:=True)
    
    With wb.Signatures
        .Subset = msoSignatureSubsetAll
        totalCount = .Count
        .Subset = msoSignatureSubsetSignatureLinesSigned
        signedCount = .Count
    End With
    
    MsgBox (signedCount & "/" & totalCount & " signed.")
    
    wb.Close False
End Sub
```
変更セットじゃなくて、スタックを消して0から作り直したらできた

# 経緯
AWSで新しくEC2を追加するのに、CloudFormationを利用することになりました
仕様は下記です
- VPC、サブネット、セキュリティグループは既存のEC2で利用しているものを使う
- 固定プライベートIPを指定する
- EBSのボリュームは2つ
- EBSはAmazon Data Lifecycle Manager を利用してスナップショットをバックアップする
 
当初は AWS::EC2::Instance だけで作成していたのですが、これだと EBSのボリュームは2つ作れますが、Tagが付けられません
TagがないとAmazon Data Lifecycle Managerが利用できません
AWS::EC2::Volume と AWS::EC2::VolumeAttachment  でTagが付けられますが、ルートデバイスボリュームにできません
困っていましたが、AWS::EC2::LaunchTemplate を使えばルートデバイスボリュームのEBSにTagがつけられることがわかったので、これを使っていました
というのを、CloudFormationのテンプレートに少しずつ修正したり、追加したりと1つのスタックを変更セットを利用して作業していました。


# 事象
AWS::EC2::LaunchTemplate を使ってスタックを修正していくうちに セキュリティグループの修正になりました
LaunchTemplateData 直下のSecurityGroupIdsではなく
NetworkInterfaces の下のGroupsに追加して、スタックの変更も UPDATE_COMPLETE で成功！
と思ったのですが、インスタンスのセキュリティを見てもセキュリティグループが反映されていませんでした
なぜ、Defaultのセキュリティグループのままなの……

# 解決方法
タイトルを実施したら直りました
変更セットじゃなくて、スタックを消して0から作り直したら、セキュリティグループが正常に設定されました


# 感想
公式のリファレンスのどこかに書いているのだとは思うのですが、みつけられていませんでした。
今まで

1. なんか作る
1. former2でテンプレート取得
1. 取得したテンプレートをリファレンスを見ながら最小限にしてスタック作成
1. 成功したらリファレンスを見ながら変更セットを利用して少しづつ追加していく

このような手順でテンプレートを作っていたのですが、それでは駄目なものもあるという学びを得ました
まだts-node使ってるの？tsxの紹介

これは [ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.3 の 10日目の記事です。

[ts-node](https://www.npmjs.com/package/ts-node) 便利ですよね。
TypeScriptで書いてトランスパイルをしないで動かせるので簡単なスクリプトやデバッグで用いることがあると思います。

でも、遅いですよね。

## そんなあなたにtsx

tsxといっても `App.tsx` みたいな TypeScript+JSX の話ではないです。

### tsxとは

https://github.com/esbuild-kit/tsx

ts-nodeのように使えるコマンドです。
内部的にはトランスパイルにesbuildが用いられており、ts-nodeより早く~~速く~~TypeScriptファイルを実行できます。

### v.s. esbuild-register

ts-nodeより早くてTypeScriptを実行するesbuildなパッケージにesbuild-registerというものもあります。（ほかにも様々ありますが検索した感じ日本で一番メジャーなように感じました）

概ねゴールは同じですが、esbuild-registerの起動は

```sh
node -r esbuild-register some/typescript/file.ts
```

のように `--require` オプションで利用されるのに対しtsxではts-node同様

```sh
npx tsx some/typescript/file.ts
```

といったようにコマンドとして利用でき、ts-nodeをほぼそのまま置き換えることができます。

https://npmtrends.com/esbuild-register-vs-tsx

ダウンロード数を見ても、後発のtsxがesbuild-registerに追いついていることがわかります。(2022/12/08現在)

### その他比較

ts-nodeになく、tsxにある機能として **Watch mode** があります。
ts-nodeではnodemonなどと併用する必要がある変更検知ですが、tsxでは `tsx watch some/typescript/file.ts` と実行することで、インポートされているファイル含め変更を検知して自動で再実行を行えます。

またモダンフロントエンド開発でハマりやすいモジュール解決なども、他のソリューションに比べうま〜くやっているのでハマりづらくなっています。

ts-node から切り替える際に注意が必要な点としては、tsxは型チェックを行わないという点です。
別途 `tsc --noEmit` やIDEの機能で型チェックを走らせる必要があります。

より細かい点は作者が比較を出しているのでそちらを参照してください。

https://github.com/privatenumber/ts-runtime-comparison
Nuxt3 ctrl, cmdを押しながらクリックでリンク先を新しいタブで開く

アンカーリンクのようにctrl, cmdを押しながらクリックして別タブで開くを対応したいケースがあります。
複数タブを開くことで情報を同時に見れるようするユーザービリティの向上目的です。

最近はディスプレイの大きなものを使う人もいるので、こういった配慮もできるとうれしいなーということで対応してみました。

## 動いたコード

とりあえず動いてるコードを最初に記載しておきます。
Ctrl, Cmd押しながらクリックすると新しいタブが開き、押さなければ普通にページ遷移します。
解説は後述。

---

- 検証バージョン情報
    - Nuxt: 3.0.0

---

```vue
# /pages/href/index.vue
<template>
  <div>
    <!-- /pages/href/newpage.vue リンク先 -->
    <button @click="hrefTo('/href/newpage', $event, { id: 1111 })">LINK</button>
    <br />
    <button @click="hrefTo('/href/newpage', $event)">LINK</button>
    <br />
    <button @click="clickAction">LINK</button>
  </div>
</template>
<script lang="ts" setup>
import { LocationQueryRaw, RouteLocationRaw } from 'vue-router'

const clickAction = (event?: MouseEvent) => {
    hrefTo('/href/newpage', event)
}

const hrefTo = (path: string, event?: MouseEvent, query?: LocationQueryRaw) => {
  const to: RouteLocationRaw = {
    path: path,
    query: query,
  }
  // ここでctrlキーかcmdキーが押されているか取得できる
  if (event && (event.ctrlKey || event.metaKey)) {
    // resolveによってURLが生成されるのでwindow.openさせる
    window.open(useRouter().resolve(to).fullPath, '_blank')
    return
  }
  navigateTo(to)
}
</script>
```

## 解説

- 解決ポイントは２つ
    - 新しいタブを開く(nuxt3 open new tab問題)
    - ctrl,cmdの状態を取得する

### 新しいタブを開く

Nuxt3にはリンクを開く方法がいくつかあります

- useRouter().push()
    - https://nuxt.com/docs/api/composables/use-router#userouter
    - これはnavigationToが推奨されてる
- navigationTo
    - https://nuxt.com/docs/api/utils/navigate-to#navigateto
- NuxtLinkタグ
    - https://nuxt.com/docs/api/components/nuxt-link#nuxtlink

この中で新しいタブで開く同じみの`target="_blank"`を指定できるのがNuxtLinkタグだけになります。
(navigationTo何故ないんだ。。。)

しかしイベントの処理によって遷移先を変えるなど、ロジックを動かしたあとに画面移動したい場合が多く、そうなるとnavigationToを使うことになるので、NuxtLinkタグそこまで使ってない状況です。

しかしnavigationToはtargetに対応していないので、結局のところwindows.openを使うしかないという判断です。

window.openに渡すURLを生成するのは`useRouter().resolve()`を使えばnavigationTo用のパラメタと同じものから生成できます。

### ctrl,cmdの状態を取得する

これがコード上にある`$event`ですね。
MouseEvent型が取れるみたいなので、そこでctrlKey, metaKeyでctrl, cmdの状態を調べることができます。
queryのほうは、遷移先のパラメタ指定したいときあるよね、という意味でサンプル的につけてみました。

今回はclickに直接callしていますが、submitActionなどを作って$eventさえ渡していれば、何らかの処理後に今回作ったhrefTo()を呼べば良いわけです。


というわけで、これでctrl, cmdを押しながらクリックした場合別タブを開くという動作ができました。
composablesなどに定義しておけば、どこでも使える便利なやつになります。

Nuxt3用に書いてみましたが、よくよく見るとVue.js系ならどこでも使えそうな内容ですね。。。
QuickSightからAurora PostgreSQLにネットワークエラーで繋がらないと思ったら原因が違った

タイトルの事象にぶつかって少し詰まったので書いておきます。


# 事象
QuickSightからAurora PostgreSQLに繋ごうとしたところ以下のようなネットワークエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/672fe80c-a110-8902-353e-8c5fa1691199.png)

>sourceErrorCode: DATA_SOURCE_TIMEOUT
sourceErrorMessage: Connection to the data source timed out before validation is complete.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/7628e993-2f29-6cfb-eeef-7ec2a84771d4.png)





# 原因調査
VPCネットワーク内の話であり、タイムアウトのメッセージなので、セキュリティグループやネットワーク経路を調べていたのですが、全く原因が掴めませんでした。

ただ、色々検証するとPostgreSQL 13系だと繋がり14系だと繋がらないようです。そこで更に調べて見ると、**Postgres14からユーザのパスワードの保存時暗号化方式が変わったことが原因** ということがわかりました。

https://community.amazonquicksight.com/t/my-quicksight-cannot-connect-to-rds-postgresql-db-via-vpc/4696/3

https://www.percona.com/blog/postgresql-14-and-recent-scram-authentication-changes-should-i-migrate-to-scram/



# 対応 
対応としてはクラスターグループのパラメータを `password_encryption=md5`に変更します。 

パラメータグループから変更してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/d7b34d0e-0ed3-9cdb-8705-df132d92377c.png)

適用前後で以下のSQLを打つと以下のようパスワード暗号化に使われるアルゴリズムがmd5に変更されているのが確認できます。パラメータは動的に適用されるのでDBの再起動等は不要です。

```sql
SHOW password_encryption;
-- 適用前 scram-sha-256 
-- 適用後 md5
```

利用するDBユーザのパスワードを再度設定してあげます。この際のパスワードは変更前と同じものでも問題ありません。

```sql
ALTER USER quicksight_user WITH PASSWORD 'P@ssw0rd';
```


データソースの作成から再度接続検証すると、今度は接続できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/6653641b-d815-94fc-109b-c48f2cda35d0.png)
indexメソッドを使って検索

任意の文字列に"code"が、左から何文字目に出てくるかを返し、その数を出力するメソッドを作りましょう。

出力例：
count_code("codexxcode") → 1
count_code("aaacodebbb") → 4
count_code("cozexxcode") → 7

ヒント: indexメソッドを使用


# indexメソッドとは
文字列や配列の中に、指定した文字列が含まれていた場合、その文字列の開始位置を整数の値で返すメソッド。
```ruby:例
str.index(検索したい文字列, [検索を開始する位置])
```


```:解答
def count_code(str)
  puts str.index("code", 0) + 1
end

count_code("codexxcode")
```

```:ターミナル
1
```

+1を記述しなかった場合、ターミナルでは０が返ってきます。
文字列の先頭を０から数えた数字を返すため、 +1をしています。

```解答
def count_code(str)
  puts (str.index("code") + 1)
end
```
文字列の先頭から検索を開始する場合、第二引数は省略することができます。上記のように記述することも可能です。


##### 参考文献
https://docs.ruby-lang.org/ja/latest/method/String/i/index.html
Pythonでエラー：error: (-5:Bad argument) in function 'inRange'

# 前提
Pythonで画像編集処理を行っていた際にぶつかったエラーになります。非常に初歩的なものですが少し悩んでしまったので自分用に投稿。

エラー内容は下記。


```:python
OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'inRange'
> Overload resolution failed:
>  - src is not a numpy array, neither a scalar
>  - Expected Ptr<cv::UMat> for argument 'src'
```

# 実現したいこと

`cv2`モジュールの`inRange`メソッドを用いて、読み込んだ画像を色で閾値を設けて処理したい。コードがこれ。

```python:
# 抽出関数を定義
def ext(img_bw_func, bgrt_obj_func) :
    # 0以下、255以上の値が出ないように処理
    minbgr = []
    maxbgr = []
    for i in range(0,3) :
        minbgr.append(max(0, bgrt_obj_func[i] - bgrt_obj_func[3]))
        maxbgr.append(min(255, bgrt_obj_func[i] + bgrt_obj_func[3]))
    
    minBGR_func = np.array(minbgr)
    maxBGR_func = np.array(maxbgr)

    img_mod_func = cv2.inRange(img_bw_func, minBGR_func, maxBGR_func)

    return img_mod_func
```

# 解決...?

`inRange`メソッドでは第一引数に画像の多次元配列、第二引数に2値化するときの下限、第三引数に上限を記載する。第二引数、第三引数の書き方はリストではなく、`cv2.inRange(img, (0, 0, 0), (255, 255, 3))`のように記述するべきであった。

numpyで実装した。

```python:
# 抽出関数を定義
def ext(img_bw_func, bgrt_obj_func) :
    # 0以下、255以上の値が出ないように処理
    minbgr = []
    maxbgr = []
    for i in range(0,3) :
        minbgr.append(max(0, bgrt_obj_func[i] - bgrt_obj_func[3]))
        maxbgr.append(min(255, bgrt_obj_func[i] + bgrt_obj_func[3]))
    
    mymin = np.array(minbgr)
    mymax = np.array(maxbgr)

    img_mod_func = cv2.inRange(img_bw_func, mymin, mymax)

    return img_mod_func
```

# また、エラー!!＆解決

これで実行ヨシ！ファッ？またエラーが出たゾ...。
よく見たら、`img_bw_func`に`mss`でキャプチャした画像をそのまま入れていたことが原因でした。`cv2`は`mss`と違い、配列に変換してから処理するようです。参考文献を見て、`img_bw_func`を修正しました。

参考文献は以下に示すので、見に行って、どうぞ(投げやり)。


# 参考文献
https://qiita.com/harupy/items/057204f0e14765b608ca
PHP8.2バージョンアップ 新機能

## 目次
- 概要
- PHP8.2 新機能3選
- おまけ
- 最後に

## 概要
今回のスキルアップのため不定期で30分でインプットしたことを投稿の
第五弾として、PHP8.2 新機能についてやっていこうと思います!

未経験からエンジニア転職を目指し、2021年10月頃から本格的にプログラミングに触れ、2021年11月頃からPHPを触り始めたので、
2021年11月25日のPHP 8.1と今回のPHP8.2へのバージョンアップで2回目のバージョンアップを経験することになりますが、
PHP8.1の頃はバージョンアップしたことも知らなかったので実質初めてのバージョンアップで楽しみです！

今回はPHP８.2の新機能の中から30分以内でインプットできる内容から3つ選んでご紹介しようと思います。

第四弾は、[Enum(列挙型)とは？](https://qiita.com/kitamurakunihiko/items/296ea5f3bda3be017836)について投稿したのでよければ確認してみてください👀
　

## PHP8.2 新機能3選
### 1. [Deprecate dynamic properties](https://wiki.php.net/rfc/deprecate_dynamic_properties)
今までは可能だったクラス内に定義していないプロパティに値を代入することが、
これからはクラス内に定義したプロパティでないと値を代入できなくなるというものみたい。

#### 変更点をコードで見てみる
```php5
class Cars 
{
  public string $toyota;
}

$cars = new Class;
// OK!
$cars->toyota = 'RAV4';

// E_DEPRECATEが出るが、プロパティは作成される。
$cars->subaru = 'OUTBACK';
```
今まで定義していないプロパティに値を代入したことがなかったけど、これはプロパティを定義し忘れていた場合に使っていたとかなのかな？🤔
あまり定義していないプロパティの使い方がわかっていないから、タイポに反応するようになって便利な気がする！

#### 動的プロパティを使いたい場合
もし今までどおり、クラス内に定義していないプロパティを生やしたい場合(動的プロパティ)は、```stdClass```を```extends```して
プロパティを生やせば使えるみたい。
あとクラスにアトリビュート```#[\AllowDynamicProperties]```を付与すればプロパティの生成が可能。
```php5
class Cars extends stdClass
{
  public string $toyota;
}

#[\AllowDynamicProperties]
class Cars
{
  public string $toyota;
}

$cars = new Class;
// 上記2つのクラスどちらもOK!
$cars->subaru = 'OUTBACK';

```
　
### 2. [Readonly classes](https://wiki.php.net/rfc/readonly_classes)
readonlyプロパティがPHP８.1で実装されましたが、それがクラスにも使えるようになるようです。
変更点をまとめると、
- readonlyをクラスに適応させると、プロパティも全てreadonlyになる。
- readonlyプロパティ同様に、プロパティへの書き込み不可。
- 動的プロパティの作成不可。
- プロパティへの型指定が必須。
- staticなプロパティも不可。
- ```#[\AllowDynamicProperties]```も不可。

#### 変更点をコードで見てみる
```php5
readonly class Cars
{
  public function __construct(
    public string $toyota;
  ) {
  }
}

$cars = new Cars('RAV4');
```
　
### 3. [Constants in Traits](https://wiki.php.net/rfc/constants_in_traits)
トレイト内で定数を定義できるようになったみたい👀

#### 変更点をコードで見てみる
```php5
trait Bar 
{
  //プロパティを定義できるようになった
  public const A = 'A';
  protected const B = 'B';
  private const C = 'C'

  public function foo() 
  {
  }
}
```
正直traitをあまり使ったことがないので、この変更がどう影響してくるのか理解できていないので、
もう少し深掘りして調べてみます！📝
すごいわかりやすい説明できる方がいらっしゃれば,お待ちしています🙇‍♂️笑笑


## おまけ
先日記事にしたenum(列挙型)についての新機能があったので、おまけとして載せておきます。
### [Fetch properties of enums in const expressions](https://wiki.php.net/rfc/fetch_property_in_const_expressions)
定数式の中でEnumのプロパティ(->name)が取得できるようになったみたい。

#### 変更点をコードで見てみる
```php5
<?php

declare(strict_types=1);

enum BackedPrefecture: string
{
    case AICHI = "愛知県";
    case SHIZUOKA = "静岡県";
    case MIE = "三重県";
}

const Location = BackedPrefecture::AICHI->name;
```
これも変更も正直どう影響してくるのか理解できてません🤣
今使えるじゃん！という場面にこれから出会ったときのために、ここに残しておきます笑笑

## 最後に
PHPは自由度が高く初学者もとっつきやすい面や世界中にユーザーがいることなどをきっかけに学び始めましたが、様々な型の導入や動的プロパティの禁止など、ルールが厳格化してきている感じがしています。
かといって、型指定をしないでも動くので初学者にも学びやすい面は残っていると思いました。
プログラマーの実力によってコードの質が大きく変わってくる言語という認識を持って、コードの質を上げて読みやすいコードを意識してこれからも学んでいきたいと思います!
Cloud Loggingによるクラウド破産を防ぐ方法

Cloud LoggingはGCPで発生した各種のログを集約し、そのログを使った様々な機能を提供します。
単にログを閲覧するだけではなく、ログに対してクエリを実行して特定の条件のログを抽出したり、特定のログが発生した時にアラートを上げたりという使い方ができます。

https://cloud.google.com/logging/docs/view/building-queries

https://cloud.google.com/logging/docs/alerting/log-based-alerts

また、何も設定せずともデフォルトで多くのログがCloud Loggingに集約される点も非常に便利です。
しかし、この便利さが故にCloud Loggingの費用が意図せずに高額になってしまう現象(通称クラウド破産)の危機があります。

# Cloud Loggingの費用発生タイミングについて
まず、Cloud Loggingの費用がどのタイミングで発生するのかを説明します。
以下のドキュメントの図によるとCloud Loggingに送信されたデータはCloud Logging API, Log sinkを通過し、最終的にはLog Bucketに到達することが分かります。
そして、費用の発生タイミングはLog Bucketに格納されたタイミングです。 それよりも手前のCloud Logging API, Log sinkまででは費用は発生しません。
Cloud Loggingによるクラウド破産を防ぐためには、この費用発生タイミングについて理解することが大事です。

https://cloud.google.com/logging/docs/routing/overview

# Log Bucketへの書き込みを止める方法
Log Bucketへの書き込みを止めるためには、Log Routerの設定を変える必要があります。


![スクリーンショット_2022-11-24_9_09_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/83aeef83-206e-f66a-b93e-c0f43dea3a47.png)

Cloud LoggingのLogs Router画面で、 `_Default` Routerの設定を変更します。
`_Required` ルーターによって書き込まれるログは監査ログであり、こちらはルーターの設定変更不可かつ費用がかからないので変更しません。

`_Default` ルーター右端からEdit Routerを選択し、Routerの設定を変更するページを開きます。
一番下にExclude Filterの設定があるので、ここに除外したいログの種類を指定します。

![スクリーンショット 2022-11-24 9.33.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/bb6801de-e435-492a-f572-bf87a9c8e4e9.png)

この設定を変更すると、Log Bucketへの書き込みが止まり、費用が発生も止まります。
しかし、それと同時にLog base metricsやLog base alertなどのCloud Loggingによって提供されていた便利な機能も停止します。
そのため、Log Bucketへの書き込み停止は無闇に行うべきではなく、費用の問題が発生したログのみに対して行うべきです。
多くのケースではこの設定を変更する必要がありません。

https://cloud.google.com/logging/docs/export/configure_export_v2

# 書き込みを止めたログをCloud Logging以外に格納する方法
上記の手順で書き込みを停止したログはCloud Loggingには保存されません。そのため、ログは破棄されてしまい、ログを確認することができなくなります。
Cloud Loggingよりも費用の安い場所にログを格納する方法を紹介します。

Log RouterはLog Bucket以外の場所にログを書き込むことができます。
Cloud Storage, Pub/Sub, BigQueryの3つが書き込み先として設定できます。

費用が問題になって_Defaultへの書き込みを停止するログは大容量のログであることが多いので、BigQueryに書き込みを行ってみます。
以下のterraformファイルをapplyすることでBigQueryへの書き込みを行えます。

```tf
resource "google_logging_project_sink" "log_sink_to_bq" {
  name = "log_sink_to_bq"

  destination = "bigquery.googleapis.com/projects/<プロジェクトID>/datasets/<データセットID>"

  filter = <<EOT
  _Defaultから除外したログの条件を書く
  EOT

  unique_writer_identity = true

  bigquery_options {
    use_partitioned_tables = true
  }
}
```

BigQueryへの書き込みをすると費用が発生しますが、Cloud Loggingの費用と比較するとかなり安いです。
_Defaultバケットへの書き込み & 30日間の保管には1GBあたり0.50USDがかかります。

https://cloud.google.com/stackdriver/pricing

一方で、BigQueryは、まず取り込みに1GBあたり0.05USDの費用がかかります。
さらに1ヶ月間の保管に1GBあたり0.02USDの費用がかかり、合計で1GBあたり0.07USDです。

https://cloud.google.com/bigquery/pricing#data_ingestion_pricing

このようにログをCloud LoggingではなくBigQueryに転送することでCloud Loggingの費用を大きく抑えられることが分かりました。
大量のログを保存しておきたいが費用が気になる方は試してみると良いでしょう。
繰り返しになりますが、Cloud Loggingに保存しないことで多くの便利機能が使えなくなりますので、費用のみを気にしてこの設定を入れるべきではありません。
ログ量が少ないならCloud Loggingに保存しても費用が問題になることはないです。
Figmaの「Auto Layout」を理解する

## はじめに
ここではデザイン制作ツールのひとつである**Figma**をマスターする(=**Figmaster**と僕は呼んでいます)ために必要な**Auto Layout**を紹介していこうと思います。

Figmaは基本、直感的なUIでツール慣れも早い気がしますが、このAuto Layout機能は手を出しづらい印象が個人的にあります。
そんなAuto Layout食わず嫌いちゃんのために、本記事を書きました。

まず簡単にFigmaの紹介をした後、Auto Layoutの解説をしていきます。

## Figmaとは？
**Figma**（フィグマ）は、ブラウザ上で共同編集ができるデザインツールです。

![](https://i.imgur.com/CAaWEhk.png)

[Figma: the collaborative interface design tool.](https://www.figma.com/)

### 特徴
- ブラウザ上で動く
- 複数人に共有可能
- 日本語版にも対応（2022年7月27日〜）
- 無料で利用可能

「**ブラウザ上で共同編集ができる**」というのが一番の特徴で、他のUIデザインツールである、XDやSketchなどには無い利点です。

デスクトップアプリもあるのですが、わざわざインストールせずに会員登録するだけで利用可能なのが便利ですね。

## Figmasterへの道(Auto Layout編)
Figmaの**Auto Layout**は、設定した内容でデザインを自動で調整できる機能です。
XDだと「スタック」とか「パディング」機能とほぼ同じ機能だと思っていただければ良いと思います。

矢印アイコンなしボタンを基本編、矢印アイコンありのボタンを応用編として解説していきます。

### Auto Layout(基本編)
まずは「ボタン」の最低限の構成要素は**四角形**と**テキスト**を想像するかと思いますので、それら2つの要素を配置します。

<img src="https://i.imgur.com/wfxi2SA.png" width="500" />


ここからAuto Layoutを適用していきます。
**四角形**と**テキスト**2つとも選択した状態で、画面右側のプロパティパネルの「Auto Layout」の「+」ボタンをクリックすると、中身の要素(テキスト)がグルーピングされます。

また、以下のショートカットでもAuto Layoutを適用できます
- ショートカット: `shift + A`

画面右側にAuto Layoutのプロパティ設定エリアが表示されました。以下、詳細を説明していきます。

<img src="https://i.imgur.com/h9saoKA.png" width="500" />

#### ①. Direction(方向)
縦並びか横並びを選びます。

#### ②. Spacing(アイテム間の距離)
アイテムが並んだ時の、アイテム間の距離をここで設定します。

#### ③. Padding(余白)
外側の余白をどれくらい取るかを設定します。
右側のアイコンをクリックすると、上下左右個別で設定できます。

#### ④. Alignment(配置)
要素の配置を調整します。
縦横中央寄せか、縦上寄せ横右寄せかなど、9パターンの配置ができます。

今回のボタンの場合、以下のようなAuto Layout設定にしました。
- Direction: 横向き
- Spacing: 0
- Padding: 横40, 縦20
- Alignment: 縦横中央寄せ

<img src="https://i.imgur.com/9Od7YXY.png" width="500" />


あとは塗りや角丸など変更して(テキストのみ)ボタンの完成！

<img src="https://i.imgur.com/GMrumxL.png" width="500" />




### Auto Layout(応用編)
まだ矢印アイコンをつけてなかったですね。
先ほどのボタンにそのままアイコンを入れると、こうなってしまいます。

<img src="https://i.imgur.com/ZButVzH.png" width="500" />

う〜ん...これでもいいのですが、矢印右側に40pxの余白があってバランスが悪いので、矢印アイコンをAuto Layoutのルールを無視して**相対配置**したいですよね。

こんな時に画面右側のプロパティパネルの一番上にある**Absolute Position**が使えます。

↓Absolute Positionのボタンの位置
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985518/3736fca9-9e36-e5bb-25ac-53a0cb9e97db.png" width="500" />

これで矢印の配置がいい感じになりましたね！
<img src="https://i.imgur.com/M3KEF50.png" width="500" />



## 結局Auto Layoutが使えて何が嬉しいの？
上記はボタンを例にしましたが、いろいろな恩恵を感じると思います。
特に以下の2つが大きな恩恵です。

### 恩恵1. デザインの変更に柔軟に対応できる！
これはみなさん経験あるかと思いますが、例えばLPデザインを作っていて、途中で文言を追加したいなと思うシーンを想像してください。

↓赤文字が追加文言
![](https://i.imgur.com/IBrvaGp.png)

みなさんの「あぁ〜(笑)」という声が聞こえてくるようです。

Auto Layoutにしてないようなこの場合、下の「Creative」のグループをずらして、そのせいでセクションの縦幅も変えて、またそのせいでページ全体の縦幅も変えて...

やってられないですね。これをちゃんとAuto Layoutで設定しておけば、全てが**自動で調整される**ので、ストレスフリーです。

### 恩恵2. コーディングを意識できる
デザイン作業が楽になるだけではなく、デザイナーは**デザインの仕様をエンジニアに伝えることができ**、エンジニアは**どのようなCSSを指定すればいいのか理解できる**という利点もあると思います。

先ほどのボタンの例の場合でも、

共通のボタンclassに指定する余白は何pxなのか？
矢印は`position: absolute`なのか？

などなどデザインファイルを見るだけで意図が伝わり、**認識齟齬が減らせる**ことがわかりますよね。

## おわりに
ここで紹介したことはAuto Layoutのほんの一部で、まだまだ紹介しきれてない機能もありますが、Auto Layoutくんの良いところが伝わり、今後使ってもらえたらなぁと思います。

興味のある方は、公式さんが公開しているチュートリアルファイルだけでも触ってみることをオススメします。
[Figma auto layout playground](https://www.figma.com/community/file/784448220678228461)
特定ドメインへのコールバックなどをlocalhostでテストしたい

## やりたいこと
Oauth2認証などリダイレクトが入るAPI関連で申請するURLがlocalhostが許可されないとき、手軽に動きをチェックできない。
※環境はmac前提、コマンドは違えどLinuxでもできると思う。

## 指針

1\. /etc/hostsにドメイン記載して、ローカルApacheやNginxのVirtualHostで実現
* railsなどポートのこと考えるとちょっと面倒。

2\. /etc/hostsにドメイン記載して、localhostの80,443をrailsのポートにフォワード
* 設定はややこしい、ちょっと知識も必要

### VirtualHost
これはある程度調べたら出るので割愛＆今回は採用しなかった。

## ポートフォワードで実現

まず考えるのは
* localhostの80,443はrailsの3000とかに飛ばす
* 実ドメイン=localhostの解決
* 既存の80,443はすでに使っている可能性があるため他のサービス停止など気にしたくない

### 80,443は使っている可能性がある
これが実はちょっと面倒、hostsに実ドメイン→localhostだけ入れても他サービスとバッテングするとわざわざ止めないといけなくなる。
手間はできる限りなくしたい。

#### lo0(localhost, 127.0.0.1)にAliasIPアドレスを追加する
ループバックにアドレスを追加できる。
ループバックアドレスは127.0.0.1だけでなく、〜.2とかも使える。
参考）　https://net-skills.net/intro-menu1/loopback/

なので
実ドメイン→追加したループバックアドレス（127.0.0.11とか）
に向ければ既存のlocalhost系は気にしなくて良さそう。

ひとまず追加
`sudo ifconfig lo0 127.0.0.11 alias`
確認
`sudo ifconfig`

``` bash
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	inet 127.0.0.1 netmask 0xff000000 
	inet 127.0.0.11 netmask 0xff000000   ←←ここ
	nd6 options=201<PERFORMNUD,DAD>
```

ちゃんとある。

ということで/etc/hostsに追加するエントリは
`127.0.0.11 なんたらドメイン`
になった。

これで（実ドメイン）へのアクセスは自PCの127.0.0.11に飛ぶことになった。
次はポートフォワード

#### ポートフォワード追加
調べるとパケットフィルタという機能があり`pfctl`コマンドで実現できるらしい。
細かい設定内容についてはここでは割愛するとして、ひとまず内容

``` conf
/etc/pf.conf
 19 #
 20 # com.apple anchor point
 21 #
 22 scrub-anchor "com.apple/*"
 23 nat-anchor "com.apple/*"
 24 rdr-anchor "com.apple/*"
 25 
 26 # localhost forward
 27 rdr pass on lo0 inet proto tcp from any to 127.0.0.11 port 80 -> 127.0.0.1 port 3000
 28 rdr pass on lo0 inet proto tcp from any to 127.0.0.11 port 443 -> 127.0.0.1 port 9292
 29 
 30 dummynet-anchor "com.apple/*"
 31 anchor "com.apple/*"
 32 load anchor "com.apple" from "/etc/pf.anchors/com.apple"
```

27, 28行が追加したエントリ
ちなみに最初は末尾に追加したが、設定される順番があるらしく、`rdr-anchor`の後に変更した。
これで
実ドメイン→127.0.0.11への解決→railsのポートフォワード
までできた。
`pfctl`はデフォルトでは立ち上がってないらしく、`sudo pfctl -e`で有効化。

#### ローカル用証明書追加
`mkcert`あたりが便利

## 確認して終わり
これでブラウザから実ドメインにアクセスするとrailsのページが出るはず。
（でなければcurlなどでチェック、なおnslookupでは127.0.0.1への解決はでないことあり、だいたいはpfctlの設定ミスなはず）
リダイレクト系のチェックもできるようになった。
コマンドの操作あるので楽な設定ではないが、一度書いとけばOKな設定も多いのでシェルスクリプト化していれば良さそう。

### `/etc/hosts`の指定は不要になったら外すことを忘れないように！
技術開発戦略

# 技術開発戦略
### プロダクトイノベーション
イノベーションは、「革新」や「新機軸」の意味。
```プロダクトイノベーション```とは、```他者が作れない革新的な製品やサービス```のこと。
```プロセスイノベーション```は、```製造工程や作業工程（プロセス）の革新によって必要な時間やコストを劇的に削減```すること。

### MOT(Management Of Technology)
技術に立脚する企業経営を行っている技業が、```さらに技術開発に集中的に投資```することで、他者との差別化を図り、```自社の価値をより高めていく```経営戦略。```技術経営```ともいう。

### R&D(Research and Development)
```研究開発業務やそれら業務を行う部門（研究所など）```のこと。技術の革新や市場変化の激しい今日では、R&Dは```ごく近い将来の収益を左右する```重要な業績と認識されている。

### コア技術
```他者には追従できない一連の技術```であり、将来に渡りその企業の```収益を支え続ける核となる重要な技術```のこと。コア技術の形成や保持のために積極的に経営資源を投入し、競合他社との```差別化を図る```ことで優位に立つこと経営手法が```コアコンピタンス経営```である。

### 技術提携
それぞれの企業が保有している```技術の提供し合う```こと。一方のみが提供する場合を```技術供与```という。
また、お互いに協力し合いながら新たな技術を開発・発展させたり、保持している技術を使って新製品の開発を行うことなども含む。

# 技術開発計画
### コンカレントエンジニアリング(Concurrent Engineering)
開発工程の効率化を目指し、製品の企画、設計、開発、販売、保守など、```複数の工程を同時並行的に進める```方法。開発期間の短縮のほか、あと工程の意見をフィードバックしながら前工程を進めることで、```無駄な省き（資源の有効活用）、コストダウンにつながる```。

### パイロット生産
製品の量産化する前に行う```試験的な少量生産```のこと。試作段階では見つからなかった量産段階で発生する可能性がある```トラブルを回避することができる```。

### 技術ロードマップ
将来における```技術分野の進展を予測```し、「どんな技術がいつ達成されるのか、その実現によってどのような影響（効果）がもたらされるのか」を時系列的で表現した```未来計画図```。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
Googleフォントを使ってみた　htmlファイルのみでサンプルを作成

「Googleフォントを使うには」は簡単にできそう、と説明を読んで思いましたが、
いざやってみると、htmlの書き方（イチから書くにはどうするか）をすっかり忘れていました。
ほんとにこれでいいのか、シンプルなサンプルで試してみて、フォントが使えることを確認してから、実際の環境に組み込みたいと思い、やってみた記録です。
　

(1) 使いたいWebフォントを選ぶ
https://fonts.google.com/
 LangageでJapaneseを選ぶと、日本語フォントが抽出される
![スクリーンショット 2022-11-22 16.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45016/b03489ae-a321-02dc-f8b8-3d464af5c159.png)
　　　　　　　　↓ 　　　　　　　↓ 　　　　　　　↓
![スクリーンショット 2022-11-22 16.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45016/19e48547-41ab-9b7a-f842-ff82e363ee3a.png)

下にスクロールすると「Select　Regular 数字 +」（＋の部分は丸に囲まれた＋）があるので、＋をクリック 
 
(2) HTMLで指定のコードを追記する
　　フォントをlinkタグで指定するか@importで指定するか　
　　　　今回はlinkタグを使用した　
　　linkタグをコピーして、headタグ内に貼り付ける

(3) CSSでfont-familyを設定する
　「CSS rules to specify families」の部分をコピーして、headタグ内のstyleタグとして貼り付ける

シンプルなサンプルはこちら

```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=RocknRoll+One&display=swap" rel="stylesheet">

    <title>Googleフォントの利用</title>
    <style>
     .fonttest {font-family: 'RocknRoll One', sans-serif; }
    </style>  
</head>
<body>
    <main>
        <p class="fonttest">フォントの指定を行いました</p>
        <p>ここは指定していません</p>
    </main>
</body>
</html>
```
恋愛の定式化

# はじめに  
僕の所属するゼミでは、週1回の頻度で進捗報告をしたり、学習のつまずいた点を解消する時間があります。そこで少し雑談が始まりました。そこでの些細な(しょうもない)やりとりです。  

## 恋愛の定式化(結論)  
$E$を求める恋愛エネルギーとするとき、
$$E = k\dfrac{Q_aQ_b}{r^2} - (Q_a - Q_b)^2$$
だたし、$k=$恋愛定数, $r=$2人の所在地距離($r\neq 0$), $Q_a, Q_b=$2人の好感度($Q_a,Q_b \geq 0$)。

## クーロンの法則って知ってる？  
教授が突如として「クーロンの法則って知ってる？」と雑談を始めました。僕も高校物理を学んでいた身でしたので存じておりました。その旨を返答すると、「あれは恋愛の法則とも呼ばれているの知ってる？」と立て続けに。どういう意味かわからなかったため、説明を求めると先述の通り、クーロンの法則に必要な$k, r, Q_a, Q_b$の定数や変数を説明してくれました。  

直感的な理解としては、 **距離が遠くてもお互いの好感度が高ければ恋愛エネルギーは高い** ということ。
なるほど、と思ったと同時に、それではカップルで好感度が大きく開いてしまっている場合、要するに片方が冷めていて、もう片方が異常なまでに好きであるという場合にも、エネルギーが大きくなってしまう。それは果たして恋愛エネルギーとして正しいのだろうか、そのカップルを羨むだろうかと思ったわけです。

## クーロンの法則にペナルティ項を追加  
そこで、教授に言われたクーロンの法則に加えて、$(Q_a - Q_b)^2$というペナルティ項を追加することにしました。このペナルティによって、双方の好感度に大きな差がある場合にはマイナスがエネルギーに付与されるというわけです。クーロンの法則も$Q^2$なわけですから、ペナルティ項が2乗されていても問題なさそうです(初めはユークリッド距離でした)。

# おわりに  
教授との雑談でしたが面白かったので記事を書くことにしました。難しい数式もなく直感的に理解する簡易的な定式化としては満足しています。もっと改良点がございましたらご指摘ください。  

余談ですが、この改良版の式を教授に提案したところ、「(僕の名前)-(教授の名前)の定理」と名付けようとお言葉をいただきました。
Nuxt.jsの環境構築時にエラーが出た時の対処方法

# はじめに
会社の環境でnpm installするとエラーが出てしまう場合があると思います。
自宅環境とは違い、プロキシやら証明書の関係でエラーが発生してしまいます。
ここではその対処方法を備忘録として残しておこうと思います。

# 発生事象①　UNABLE_TO_VERIFY_LEAF_SIGNATURE
例えば、npm install -g yarnを実行すると以下のエラーが出たりします。
```
npm install -g yarn
npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
```

# 対処方法①
以下のコマンドでSSLのチェックを無効にします。
```
npm config set strict-ssl false
```

# 発生事象②　unable to verify the first certificate
例えば、yarn create nuxt-app testVueを実行すると以下のエラーが出たりします。
```
unable to verify the first certificate
```

# 対処方法②
以下のコマンドでTLS接続の証明書検証を無効化します。
```
set "NODE_TLS_REJECT_UNAUTHORIZED=0"
```
超便利なショートカットキー

# はじめに
突然ですが、ショートカットキーってものすごく便利ですよね。
産技短に入ってからは毎日のようにショートカットキーを使うようになり、とても助けられています。今回はそんなショートカットキーについて記事を書いてみようと思います。

# ショートカットキーの紹介
Ctrl ＋ C、V、X、Z、Y、A、F、S
このへんはみなさんご存じだと思います。
ですが、調べてみたら初めて見るものがたくさんありました。その中でも個人的に便利だなと思ったものを紹介します。きっと社会人になっても役に立つので、知っていて損はないと思います。


>__Ctrl ＋ W ： アプリの終了__
ちなみに Alt ＋ F4 でも同じことができます。デスクトップ上で Alt ＋ F4 を実行するとシャットダウンができます。（ Ctrl ＋ W ではシャットダウンはできません。）


>__Windows ＋ L ： 画面ロック__
インターシップ先で教えていただいたのですが、席を離れる際は必ず画面ロックをするそうです。社会人になったらよく使うようになると思います。学生のうちから使って慣れておくと良いかもしれません。


>__Windows ＋ Shift ＋ S ： スクリーンショット__
選択した範囲だけをスクショできます。通常のスクリーンショットは Windows ＋ Prt　Sc　ですが、必要のない範囲までスクショしてしまいます。 ある範囲だけスクショする場合は Shift ＋ S のほうが便利かもしれません。


>__Alt ＋ P ： プレビューウィンドウの表示__
ファイルを開かなくても中身を確認することができます。いちいち開かなくてもいいので便利です。私はファイルを開いて確認していたので、今後活用していきたいです。


>__Alt ＋ Tab ： ウィンドウの切り替え__
複数のウィンドウを使っているとき、マウスを使わなくても切り替えができます。複数のウィンドウを使う授業や課題をやる際に使えそうです。

# おわりに
どうでしょうか？ショートカットキーっていろんなことができますよね。他にもたくさんあるので、気になった方は調べてみてください。
参考にしたページのリンクはこちらです。
[ショートカットキー一覧](https://dekiru.net/article/18619/)
はじめての機械学習向け無料授業リスト（英語）

AIやら機械学習やらはバズワードになってしまって意味があやふやで、どっから勉強すると良いのか案外わかりにくいので、自分が使って良かった授業のリストをメモ。
この頃、大人気のNeural Network系は、普通に機械学習の勉強を始めると早々出てこないので、Neural Networkだけ使いたいって場合は、のんびり勉強しなくても、すでに整備されたライブラリでちゃちゃっと出来る。
とはいえ、全体像がわかってる方が新しい手法に対応しやすいんじゃないかと思う。

最初に始めるならおススメはこれ
[FOUNDATIONS OF MACHINE LEARNING](https://bloomberg.github.io/foml/#home)
授業は全部YouTubeで無料公開。
一通り全部のトピックを網羅してあり、先生もわかりやすい。
専用ページに宿題もあるし、教科書も列挙されている。

数学的な内容で、わかりやすいのは、YouTubeの[mathematicalmonk](https://www.youtube.com/user/mathematicalmonk/playlists)がやっているMachine Learningのクラス。
昔、YouTube動画の長さに制限があった時の名残でやたら細かく刻まれているけど、内容はとても良い。
ちょっと難しかったら、その前にProbability PrimerのPlaylistsもおススメ。

だいたいわかって来たら、ちゃちゃっとNeural Network使ったDeep Learningについて復習
[Deep learning](https://www.youtube.com/watch?v=aircAruvnKk&list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi)
図表がとってもわかりやすい3Blue1BrownのPlaylists。

Deep Learningは、その辺に転がってるライブラリでお試ししてみるとわかりやすいかと。
この頃の流れは2020年の授業が良い。
[CMSC 828W: Foundations of Deep Learning](http://www.cs.umd.edu/class/fall2020/cmsc828W/)
ただ、最初に先生も言っているようにAI分野はどんどん変わるので、信じ込んではいけません。
2021年の授業は公開されていないけれど、2020年の授業はすべて[YouTubeに公開している](https://www.youtube.com/watch?v=DObobAnELkU&list=PLHgjs9ncvHi80UCSlSvQe-TK_uOyDv_Jf&index=1)。
論文のリストもあるので、ここからDeep Learningの世界にわけ行っていくにはちょうど良い。
メモ：複数テナントのAzureMLワークスペースで作業する

複数テナントにAzureMLワークスペースがあり、切り替えて作業する際に使うAzure CLIコマンドを覚える記憶力がないため、自分用のメモを置きます。

別テナントにログインする。
```bash
az login --tenant <tenant>
```

アクティブなサブスクリプションを変更する。
```bash
az account set --subscription <subscription>
```

デフォルトリソースグループとAzureMLワークスペースを指定。
```bash
az configure --defaults group=<group> workspace=<azureml ws>
```

これで以降の`az ml`コマンド実行時はリソースグループとAzureMLワークスペースを指定しなくて済むようになります。
もっと便利な方法をご存じでしたらコメントで教えて頂けると嬉しいです。

# 参考
[Azure CLI を使用してサインインする — ログインと認証 | Microsoft Learn](https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli#sign-in-with-a-different-tenant)
[Azure サブスクリプションを管理する方法 – Azure CLI | Microsoft Learn](https://learn.microsoft.com/ja-jp/cli/azure/manage-azure-subscriptions-azure-cli#change-the-active-subscription)
Azure環境構築（Key Vault設定〜関数アプリでのシークレット操作）

＜前提条件＞
・KeyVaultは作成済み

# 手順１：Azure CLIコマンドでAzureにログイン

```
az login
```

# 手順２：Azure CLIコマンドでシークレットキーを作成する

```
az keyvault secret set --vault-name "KeyVaultのコンテナ名" --name "シークレットキー名" --value "シークレット値"
```

# 手順３：Azure CLIコマンドで作成したシークレットキーを表示

```
az keyvault secret list --vault-name "KeyVaultのコンテナ名"
```

```
# 出力結果　
[
  {
    "attributes": {
      "created": "〇〇",
      "enabled": 〇〇,
      "expires": 〇〇,
      "notBefore": 〇〇,
      "recoveryLevel": "〇〇",
      "updated": "〇〇"
    },
    "contentType": 〇〇,
    "id": "〇〇",　　　　　　　　　　# idをコピーして控えておく
    "managed": 〇〇,
    "name": "〇〇",
    "tags": {
      "〇〇": "〇〇"
    }
  }
]
```

# 手順４：AzureポータルでAzure Functionsにアクセス権を追加する（初回のみ実施）
![スクリーンショット 2022-11-24 10.46.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2362827/98a3cb9a-068c-7490-bdb4-4c3a42ec9893.png)

参照：https://yotiky.hatenablog.com/entry/azurefunctions_keyvault

# 手順５：Azure Functionsのアプリケーション設定で、シークレット識別子を以下の書式で値として設定する。
※名前は何でもOK

```
@Microsoft.KeyVault(SecretUri=手順３で控えたid)
```

保存後、作成したアプリケーションを設定開き、状態が "Resolved" になっていることを確認する

# 手順６：Azure Functions(Python)のrequirements.txtに書き内容を追加（モジュール追加）（初回のみ実施）
※x.x.xはバージョンで任意のバージョンを指定

```
azure-keyvault==x.x.x
azure-identity==x.x.x
```

# 手順７：Azure Functions(Python)でシークレットキーを取得・表示

```python
import json
import logging

import azure.functions as func
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential

def main(event: func.EventGridEvent):
  keyVaultName = "xxxxx"  # キーコンテナ名
  KVUri = f"https://{keyVaultName}.vault.azure.net"

  credential = DefaultAzureCredential() # 資格情報の取得
  client = SecretClient(vault_url=KVUri, credential=credential)

  secretName = "yyyyy"  # シークレット名
  retrieved_secret = client.get_secret(secretName)
  logging.info(f"Your secret is : '{retrieved_secret.value}'.")
```

# 参照　
■Key Vaultの作成方法

https://qiita.com/kk-ishii/items/0176b1f02e77bd4fd948

■Key Vaultの料金

https://azure.microsoft.com/ja-jp/pricing/details/key-vault/


https://azure.microsoft.com/ja-jp/pricing/calculator/?service=key-vault


https://www.rworks.jp/cloud/azure/azure-column/azure-entry/24267/

■Key VaultとAzure Functionsの連携

https://yotiky.hatenablog.com/entry/azurefunctions_keyvault

https://github.com/MicrosoftDocs/azure-docs.ja-jp/blob/master/articles/key-vault/general/manage-with-cli2.md

https://aadojo.alterbooth.com/entry/2021/03/04/100000

■Key VaultのシークレットキーをAzure Functions上から取得する

https://qiita.com/takmot/items/65be3cfc2f23d6307fa6

https://learn.microsoft.com/en-us/python/api/azure-keyvault-secrets/azure.keyvault.secrets.secretclient?view=azure-python

■Key Vault周りのモジュール追加

https://qiita.com/dz_/items/472ee5bd7968d0b5f530

https://learn.microsoft.com/ja-jp/azure/developer/python/sdk/authentication-azure-hosted-apps?tabs=azure-cli%2Cazure-app-service

■Azure Functionsで環境変数を別ファイルから取得する

https://playfab-master.com/azure-environment-variable


https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python?tabs=asgi%2Capplication-level&pivots=python-mode-decorators
paiza.ioでelixir その98

# 概要
paiza.ioでelixirやってみた。
System使ってみた。

# サンプルコード

```
prev = System.os_time()
next = System.os_time()
diff = next - prev
IO.puts diff

prev = System.monotonic_time()
next = System.monotonic_time()
diff = next - prev
IO.puts diff

System.build_info()
|> IO.inspect

System.cmd("echo", ["hello"])
|> IO.inspect

System.cmd("echo", ["hello"], env: [{"MIX_ENV", "test"}])
|> IO.inspect

System.cmd("echo", ["hello"], into: IO.stream())
|> IO.inspect

System.fetch_env("PORT")
|> IO.inspect

System.fetch_env("NOT_SET")
|> IO.inspect

#System.fetch_env!("PORT")

System.get_env("PORT")
|> IO.inspect

#System.halt(0)
#System.halt(1)

System.pid()
|> IO.inspect

System.tmp_dir()
|> IO.inspect


#System.restart()
System.shell("echo hello")
|> IO.inspect

#System.stop(0)
#System.stop(1)
System.user_home()
|> IO.inspect

System.version()
|> IO.inspect



```

# 実行結果

```
408
159
%{
  build: "1.12.3 (compiled with Erlang/OTP 22)",
  date: "2022-09-01T08:25:44Z",
  otp_release: "22",
  revision: "a64d42f",
  version: "1.12.3"
}
{"hello\n", 0}
{"hello\n", 0}
hello
{%IO.Stream{device: :standard_io, line_or_bytes: :line, raw: false}, 0}
:error
:error
nil
"11"
"/tmp"
{"hello\n", 0}
"/workspace"
"1.12.3"
```

# 成果物

https://paiza.io/projects/EM1eNMUcoOy4I7yyTnRQQw?language=elixir


以上。
vuejsとwebpack

webpack.config.js
```
const path = require('path')
const webpack = require('webpack');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
    mode: 'development',
    entry: {
        index: './src/index.js',
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: '[name].bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: "vue-loader"
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                type: "asset/inline",
            }
        ]
    },
    resolve: {
        alias: {
          vue$: 'vue/dist/vue.runtime.esm-bundler.js',
        },
        extensions: ["*", ".js", ".vue", ".json"]
      },
    plugins: [
        new VueLoaderPlugin(),
        new webpack.DefinePlugin({
            __VUE_OPTIONS_API__: true,
            __VUE_PROD_DEVTOOLS__: false,
            }),
    ]
}
```
【React】Testing Libraryのロール名のメモ

Testing Libraryでロール名が分からないときがあったので書き留めておく

### h1~h6タグ
```typescript
const xxx = screen.getByRole('heading');
expect(xxx).toBeInTheDocument();
```

### buttonタグ
```typescript
const xxx = screen.getByRole('button');
expect(xxx).toBeInTheDocument();
```

### inputタグ　テキストボックス
```typescript
const xxx = screen.getByRole('textbox');
expect(xxx).toBeInTheDocument();
```

### inputタグ　ラジオボタン
```typescript
const xxx = screen.getByRole('radio');
expect(xxx).toBeInTheDocument();
```

### inputタグ　チェックボックス
```typescript
const xxx = screen.getByRole('checkbox');
expect(xxx).toBeInTheDocument();
```
### liタグ
```typescript
const xxx = screen.getAllByRole('listitem');
expect(xxx).toBeInTheDocument();
```
liは基本的には複数存在するので、getAllByRoleとします。

主に使いそうなのはここら辺でした。
参考は[こちら](https://www.w3.org/TR/html-aria/#docconformance)
rpibootがFile read: start4.elfと表示後、止まってしまう

# 事象

rpibootが、`File read: start4.elf`と表示した後、進行しない。

![67524009c9a7ea3ff2aa47e9035a911.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/e158790a-6eef-3afb-e805-4881028af2b1.png)

# 解決方法

rpibootを最新にすればOK。
Windowsの場合は、[ここ](https://github.com/raspberrypi/usbboot/tree/master/win32)の**rpiboot_setup.exe**をインストールする。

# 参考

* [rpiboot stops at File read: start4.elf](https://github.com/raspberrypi/usbboot/issues/166)
PowerPlafrom / PowerAutomate  - Boxコネクタの注意点

# Boxコネクタ
PowerPlatform/PowerAutomateのBoxコネクタのアクションのほとんどはBox側の言語が日本語で正常に動作しない不具合を持っています。 Box(https://www.box.com/ja-jp) のコネクタです。
個人的には2020年8月頃に確認した不具合ですが、その後2022年11月現在でも修正されていません。
[Boxコネクタのドキュメント](https://learn.microsoft.com/ja-jp/connectors/box/#known-issues-and-limitations) にも制限事項として記載されていますが、BoxユーザーがPowerAutomateを試してみようと思った時に躓きやすいポイントかと思いますのでまとめておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884114/67c6b217-b7fd-07e0-0031-ac162dd41c55.png)



# 不具合の内容
## 📁（ピッカー）でファイルパスを指定すると必ず失敗するアクション
- パスによるファイルコンテンツの取得
- パスによるファイルメタデータの取得
- フォルダーにアーカイブを展開します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884114/1ef4109c-dbbd-6f79-4b16-0ce4093fcc98.png)

ピッカーを使用してファイルパスを選ぶと、実行時に必ず下記エラーが発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884114/edc02b83-b4cd-f575-7239-69375be6b8f1.png)


## 回避方法
### [手段A]
「パスによる～」アクションの代わりに「IDによる～」アクションを使用する
「パスによるファイルコンテンツの取得」「パスによるファイルメタデータの取得」アクションに関しては「IDによる～」で代用可能です。

### [手段B]
ピッカーを使用しない。
ファイルパスを手入力する(または変数や他のアクションの出力を使う)と、この不具合は発生しません。

### [手段C]
PowerAutomateで利用するBoxアカウントの言語を"English"に変更すると問題は発生しなくなります。

# ファイルの作成アクションも
「ファイルの作成」アクションでピッカーでフォルダを選択して作成すると、ルートフォルダー直下に"すべてのファイル"フォルダが作成されてしまいます。

# 出力にパスが含まれるアクションも…

Boxの言語が"日本語"では、下記のアクションの出力のPathの先頭に"/すべてのファイル"が付与されてしまいます。
- フォルダー内のファイルとフォルダーのリスト
- ファイルの更新

Pathをそのまま扱うと同様にはまりますのでご注意ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884114/ee6c8847-121c-622d-3a13-19ee001b1f92.png)


# 原因の推察
Boxのルートフォルダは、英語環境では"All Files"ですが、日本語環境では"すべてのファイル"に変わります。
Boxコネクタ側がこの変化に対応できていないのでは、と推測しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884114/8b0d2af2-1886-2b91-563e-f14139e07600.png)

# 改善の見込みは…
この現象についてMicrosoftにはサポートリクエストにて確認済みです(2020年に)
その後、2022年11月でも改善されていません。
フィードバックしようにも"Box"という名前で検索してもいろいろなものがヒットしてしまい、すでに挙がってないかを調べることが困難で、心が折れております。
【Flutter】SDKのバージョンコンフリクトを解決する

flutterのSDKのバージョン設定する際、依存関係で悩んでいる方多いと思うので、本記事で解決策をまとめてみます。
# anyで解決する

下記の例でflutter pub getすると、バージョンコンフリクトが発生すると思います。

```yaml
environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  url_launcher: ^6.1.7
```
バージョンコンフリクト
~~~
Because demo depends on url_launcher >=6.1.3 which requires Flutter SDK version >=2.8.0, version solving failed.
pub get failed (1; Because demo depends on url_launcher >=6.1.3 which requires Flutter SDK version >=2.8.0, version solving failed.)
exit code 1
~~~
解決策：
- anyで問題ないバージョンを探し出す。
```yaml
environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  url_launcher: any
```
- pubspec.lockファイルから問題なかったバージョンを確認する
~~~
  url_launcher:
    dependency: "direct main"
    description:
      name: url_launcher
      url: "https://pub.dartlang.org"
    source: hosted
    version: "6.1.2"
~~~
- yamlファイルのバージョンを修正する
```yaml
environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  url_launcher: 6.1.2
```

# dependency_overrides
下記はパッケージの取得エラーです。
原因はもう１つのパッケージに同じsdkのfl_chartが^0.36.1を使っていたからです。
当然、その解決策は今使っているパッケージのバージョンを同じバージョンの^0.36.1にすれば解決できますが、もし２つのSDKで違うバージョンのSDKが存在する、または上記anyでも解決できない場合はdependency_overridesで解決できます。
~~~
Because some_package depends on another_package from path which depends on fl_chart ^0.36.1, fl_chart ^0.36.1 is required.
So, because some_package depends on fl_chart 0.20.1, version solving failed.
pub get failed (1; So, because some_package depends on fl_chart 0.20.1, version solving failed.)
exit code 1
~~~

解決策
```yaml
dependencies:
  flutter:
    sdk: flutter
  fl_chart: 0.20.1

dependency_overrides:
  fl_chart: 0.20.1
```
## 注意
この方法でバージョン依存関係コンフリクト解決できますが、SDK想定外の動作発生することがあるため、慎重に使った方が良いと思います。
Jetpack ComposeのPreviewにある便利な機能

# 初めに
今回は、Jetpack Composeで絶対に使う@Previewにある便利な機能について紹介していきます
### 本文
早速紹介していきます。
`name`にはプレビュー表示している左上にどのパーツなのかが分かりやすいように表示することができる名前です。
`device`は`Devices`の中にある端末から表示させたい端末を選択することができます。
`showSystemUi`はプレビュー内にステータスバーとアクションバーを表示することができます。
`showBackground`は本来プレビューは透明の背景が適応されてますが、背景を表示することができるようになります。
背景色を変えたい場合は`backgroundColor`に対してARGBの値を代入することで変更することができます。
```kotlin
@Preview(
    name = "画面名",
    device = Devices.PIXEL,
    showSystemUi = true,
    showBackground = true,
)
```
### 最後に
他にも便利なのはたくさんありますが、自分が一番よく使う機能たちを紹介していきました
何かのお役に立てれば幸いです
JJY40,60両対応構想

JJYの送信所は福島のおおたかど山の40kHzと九州のはがね山の60kHzがあります。

よりよく受信するにはバーアンテナを送信所の方向に直交させて置くのが一番良いです。

我が家からは送信所の方角は31度と256度の方向にあります。（こよみを表示する自作アプリで方角を表示するようにしてあります）

![Screenshot_20221124-095941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/1c39c6b9-18f5-beca-9b27-40391058923a.png)

一台の受信機で対応する方法は以下の方法が考えられます。

* バーアンテナを台の上においてサーボモーターなどで回転させる
* バーアンテナを二つ用意して切り替える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e002a288-13cf-b4aa-e478-240b21dd8328.png)

バーアンテナを回転させる方法はどなたかが、IoT LTで発表していたような気がします。

ジャイロやマイコンなどを使うことになりますが、これらがノイズ元になる可能性があり、対策が必要かもしれません。

実際やるかは微妙ですが、いろいろ考えてみたいと思います。
paiza.ioでelixir その96

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
api叩いて、covid-19の県毎の人員を求めよ。

# サンプルコード

```
:inets.start
:ssl.start
{:ok, {_status, _headers, body}} = :httpc.request('https://covid19-japan-web-api.vercel.app/api/v1/prefectures')
body = IO.iodata_to_binary(body)
Regex.scan(~r/name_ja\": \"(.+?)\",|population\": (.+?),/, body)
|> Enum.map(fn 
    [_, v] -> 
        IO.write(v)
        IO.write(" ")
    [_, _, v] -> 
        IO.puts(v)
end)

```

# 実行結果

```
北海道 5248552
青森 1246138
岩手 1226430
宮城 2303160
秋田 965968
山形 1077057
福島 1847950
茨城 2868041
栃木 1942312
群馬 1937626
埼玉 7337330
千葉 6279026
東京 13942856
神奈川 9200166
新潟 2222004
富山 1042998
石川 1137181
福井 767742
山梨 812056
長野 2049023
岐阜 1988931
静岡 3639226
愛知 7552873
三重 1779770
滋賀 1413959
京都 2583140
大阪 8823453
兵庫 5463609
奈良 1331330
和歌山 923721
鳥取 555663
島根 673891
岡山 1891346
広島 2807987
山口 1355495
徳島 728633
香川 956069
愛媛 1338811
高知 697674
福岡 5110113
佐賀 814211
長崎 1325205
熊本 1746740
大分 1134431
宮崎 1072077
鹿児島 1599984
沖縄 1454184
```

# 成果物

https://paiza.io/projects/DJOmmDXX0ePgBIHbrUXHhA


以上。