OmniAICreator/Qiita-1.07M huggingface dataset:
EC2起動時に、自身も監視するCloud Watch Alarmを自動で作成する

## What's This
userdata使用で、起動時にcloudwatch alarmを作りました。

要件的には、以下

```
・OSはUbuntu（AWS公式イメージ）
・自分のCPUメトリクスを監視するalarm
・アラーム名に自身のインスタンスIDを付与
・例 ec2-i-aaaaaaa-cpu-alarm
```

## Userdata

Credentials情報はベタ張りなので、もっとセキュアな方法があるかも
アラーム名に自身のインスタンスIDを付与するのは、環境変数使って通しました



```
#!/bin/bash
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip
unzip awscliv2.zip
sudo ./aws/install
export InstanceId=`curl http://169.254.169.254/latest/meta-data/instance-id -w "\n"`
export AWS_ACCESS_KEY_ID="XXX"
export AWS_SECRET_ACCESS_KEY="XXX"
export AWS_DEFAULT_REGION="XXX"
aws cloudwatch put-metric-alarm --alarm-name ec2-$InstanceId-cpu-alarm --namespace AWS/EC2 --metric-name CPUUtilization --dimensions "Name=InstanceId,Value=$InstanceId" --evaluation-periods 1 --comparison-operator GreaterThanOrEqualToThreshold --period 60 --statistic Average --threshold 80
```

## 参考

```
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-cloudwatch-createalarm.html
https://hacknote.jp/archives/43635/
```

参考にさせていただきました。ありがとうございます。
踏み台サーバの公開鍵を使用せずに踏み台サーバ経由の SSH 接続をする（VS Code でも使用可能）

# はじめに
今回は、踏み台サーバ経由で別の LAN に接続されたマシンに SSH 接続をする設定方法をご紹介します。
前回の [Ubuntu 20.04 LTS で NIC（ネットワークインターフェース）を2つ同時に使用する方法](https://qiita.com/maru_ocu/items/6289a4cfccc2d393e6ac) の記事の構成の話の延長です。
今までは 10.11.2.0/24 上のみに存在するマシンだと 10.11.2.0/24 のネットワークに VPN などで接続する必要がありましたが、前回のマシンを踏み台にすることによって直接外部から触ろうという試みです。

# 構成
![nic-wlan3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1652242/b4b2b889-42f8-a6a1-7e61-bca295b726fc.png)

[前回 LAN ケーブルを2本差ししたマシン](https://qiita.com/maru_ocu/items/6289a4cfccc2d393e6ac)の名称は Bastion（要塞）、10.11.2.0/24 上にある接続したいマシンを Client とします。
あまり関係ないですが、Bastion の OS は Ubuntu 20.04.3 LTS、Client の OS は  Rocky Linux 8.4 です。

# 準備
接続したいマシンの公開鍵を事前に Bastion と Client に登録しておきます。踏み台サーバを使いたいなと思う方なら SSH キーの発行や登録方法はわかると思いますので省略します。

# 方法
`/Users/[user]/.ssh/config`（Windows なら `C:\Users\[user]\.ssh\config`） のファイルを以下のように編集します（`[user]` はご自身のユーザ名です）。
    
```config:/Users/[user]/.ssh/config
Host bastion
  HostName 192.168.0.3
  User root
  Port 22
  IdentityFile /Users/[user]/.ssh/id_rsa
  ForwardAgent yes

Host Client # Windows の場合。Mac / Linux の場合は下記
  Hostname 10.11.2.8
  Port 22
  User root
  ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -q -W %h:%p bastion # bastion は上で設定した Host の名称を使用
  IdentityFile /Users/[user]/.ssh/id_rsa

Host Client # Mac / Linux の場合
  Hostname 10.11.2.8
  Port 22
  User root
  ProxyCommand ssh -q -W %h:%p bastion
  IdentityFile /Users/[user]/.ssh/id_rsa
```

# VS Code のエクスプローラーも使用可能
Remote-SSH のプラグインが入っていれば、例の左下の緑の SSH のボタンで Client に接続するとエクスプローラーも使用可能です。

# 終わりに
私がハマったのは、Windows の場合は `ProxyCommand` のところで ssh.exe のフルパスを書かないといけないことでした。
特に Windows 使いの方で、ハマっている人が居て救われれば幸いです。
初めてのMacOSの歩き方

## 目的とペルソナ
- Windowsばかりを使ってきたユーザが、Macを使い始めるまでの諸設定。
- Windowsユーザが設定しておくと幸せになれる、Macの最低限の備忘録。

## 課題と解決策
### ショートカットで解決
- 削除（デリート）
- コピー＆ペースト
- スクリーンショット
- ゴミ箱に入れる

### 設定で解決
- ファンクションキー
- 文字入力時のライブ変換オフ
- 変換決定をシングルクリック

### ツールで解決
- 高機能テキストエディタ
- ホイールマウスの快適化


### 解決できないもの
- 半角全角切り替え

***

## ショートカットで解決
### 削除（デリート）
~~~
fn + deleteキー
~~~
- Macのdeleteキーは、Windowsのbackspaceと同じなので。

### コピー＆ペースト
~~~
# コピー
command + c

#　ペースト
command + v
~~~

### スクリーンショット
~~~
# 画面全体を撮る
command + shift + 3

# 画面の一部を撮る
command + shift + 4

# 特定のウィンドウのみ撮る
command + shift + 4 でカメラアイコンに切り替わった後、space + クリック

# スクリーンショットアプリを開く
command + shift + 5
~~~

### ゴミ箱に入れる
~~~
# ファイルを選択した状態で…
command + backspace
~~~

## 設定で解決
### ファンクションキー
- システム環境設定から、キーボードを選択
- キーボードタブ内の、以下の項目にチェック
    - F1、Fなどのキーを標準のファンクションキーとして使用
        - F2：リネーム
        - F6：全角かな変換
        - F7：全角カナ変換、などのように使用できる。
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/d41d06d9-f298-9d46-e44d-b724a9033a99.png)

### 文字入力時のライブ変換オフ
- システム環境設定から、キーボードを選択
- 入力ソースタブ内の、以下の項目のチェックを解除
    - ライブ変換
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/e37fe0ee-f9d7-b70f-89ec-189aa3f1d5c0.png)

### 変換決定をシングルクリック
- システム環境設定から、キーボードを選択
- 入力ソースタブ内の、以下の項目をチェック
    - Windows風のキー操作
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/e37fe0ee-f9d7-b70f-89ec-189aa3f1d5c0.png)

## ツールで解決
### 高機能テキストエディタ
- CotEditor
    - App Store からインストール可能

### ホイールマウスの快適化
- Mos
    - 概要（こんな人にのために）
        - Magic Mouseは使いにくい！
        - 一般的なホイールマウスを使いたい！
        - ホイールの方向と加速度がおかしい！
    - ダウンロード先：[＜公式サイト＞](https://mos.caldis.me/z)よりダウンロード
    - インストール時：悪質なソフトウェアかどうかを…という警告が出る場合あり。
    - 諸設定のお手本：[＜ろくじゅうどデザインのブログ様＞](https://rokujuudo.com/blog/entry/app-mos)を参考にすると幸せになれる。

## 解決できないもの
### 半角全角切り替え
- キーボード下部の＜英数＞＜かな＞キーで切り替え。
- 任意のキーを全角半角キーとして使うことは難しい。
ORACLE MASTER SQL BRONZE WEB問題集




##SQL BRONZE WEB問題集

## サンプル問題

次のようなコミットログが存在するとする

<pre>
1: Aが社員10の所在地を東京から大阪に変更する
2: Cさんが検索
3: Aさんが社員10の所在地を大阪から京都に変更
4: Bさんが社員20を大手町から新宿に変更
5: Aさんがコミット

</pre>

5が完了した時点でのBさんが社員10と社員20を参照した時の場所として正しいものを選べ

A: 社員10は東京, 20は大手町

B: 社員10は京都、20は大手町

C: 社員10は東京, 20は新宿

D: 社員10は京都、20は新宿


## リンク集

https://techblog.short-tips.info/sql/5010oracle_sql_basic_q.html

https://techblog.short-tips.info/sql/5020oracle_sql_q.html

https://techblog.short-tips.info/sql/5030oracle_select_q.html

https://techblog.short-tips.info/sql/5040oracle_function_q.html

https://techblog.short-tips.info/sql/5045oracle_function_q.html

https://techblog.short-tips.info/sql/5050oracle_group_function_q.html

https://techblog.short-tips.info/sql/5060oracle_join_q.html

https://techblog.short-tips.info/sql/5080oracle_set_q.html

https://techblog.short-tips.info/sql/5090oracle_q_dcl_trans.html
Cloudflare Pages で iOS Safari から mp4 が再生できない

# TL;DR
iOS Safari は mp4 などのメディアコンテンツを `HTTP 範囲リクエスト(206 Partial Content)` で受け取らないと再生してくれませんが
Cloudflare Pages は HTTP 範囲リクエスト に対応してないため `200 OK` で返してきます（response header に `Accept-Ranges` があり、値が `none` 以外であれば、そのサーバーは HTTP 範囲リクエストに対応してることになります）。
その response を Service Worker でインターセプトして206に書き換えて解決します。

# Nuxt × Workbox の場合
当方は普段 Nuxt × Workbox を利用しているためその場合の利用法になります（それ以外の環境の方は参考程度に御覧ください）

```nuxt.config.js
export default {
  ...
  workbox: {
    cachingExtensions: '~/plugins/workbox-range-request.js',
  },
}
```

```/plugins/workbox-range-request.js
// メディアファイルのrangeRequest対応

const myPlugin = {
  async fetchDidSucceed({ request, response }) {
    if (response && response.status !== 206 && request.headers.has('range')) {
      response = await workbox.rangeRequests.createPartialResponse(request, response)
    }
    return response
  },
}

workbox.routing.registerRoute(
  /\.(mp3|ogg|mp4|webm)/,
  new workbox.strategies.CacheFirst({
    cacheName: 'media-file-cache',
    plugins: [
      new workbox.rangeRequests.RangeRequestsPlugin(),
      myPlugin,
    ],
  }),
  'GET'
)
```

本来 Cloudflare に限らず、 Service Worker を利用したサイトの動画を iOS で再生する際は
range request に対応する必要がありますが、
workbox の RangeRequestsPlugin では `キャッシュされたレスポンス` のみのコントロールになってしまいます。
今回の Cloudflare の場合は `キャッシュされる前のオリジンレスポンス` のコントロールも必要になりますので、
（workboxの場合は） `fetchDidSucceed` のタイミングで最適化するコードを入れました。

# Service Worker 以外の解決法
確認してませんが、Cloudflare Workers を利用して
上記の [createPartialResponse](https://github.com/GoogleChrome/workbox/blob/v6/packages/workbox-range-requests/src/createPartialResponse.ts) 関数内と同様の処理を施せば対応可能かと思います。
もじぴったんで最強になる


<h2>やりたいこと</h2>

* 文字登録
* 文字検索（あいまい検索）

エクセルがぴったりだ！
VBAというものを使いました。

![画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2302298/df78ab71-1421-17f7-c1ac-7681f4a3f3d8.png)
完成はこんな感じです。
文字数別に分けました。見やすいので。

それぞれのテーブル横に、今登録済みの言葉の数を出しています。
**=COUNTA(B6:B206)**
を入れてます！Bが変わるやつです。

あとB2のセルの文字数がA2に出るようにしてます。
**=LEN(B2)**
です。


<h2>ソースコード</h2>
登録ボタンの方

```vb
Private Sub CommandButton1_Click()
    Dim a As Long

    If Range("A2") = 3 Then
        a = Range("C6")
        Range("B" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 4 Then
        a = Range("F6")
        Range("E" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 5 Then
        a = Range("I6")
        Range("H" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 6 Then
        a = Range("L6")
        Range("K" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 7 Then
        a = Range("O6")
        Range("N" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 8 Then
        a = Range("R6")
        Range("Q" & a + 6).Value = Cells(2, 2)
    ElseIf Range("A2") = 9 Then
        a = Range("U6")
        Range("T" & a + 6).Value = Cells(2, 2)
    End If
End Sub
```

検索ボタンの方

```vb
Private Sub searchBtn_Click()
    Dim arr(1 To 200) As String
    Dim c As Range
    Dim firstAddress As String
    Dim i As Long: i = 1
    
        With Range("B6:T206")
            Set c = .Find(Cells(2, 2), LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False)
            If Not c Is Nothing Then
                firstAddress = c.Address
                Do
                    arr(i) = c.Value & ","
                    i = i + 1
                    Set c = .FindNext(c)
                    If c Is Nothing Then Exit Do
                Loop Until c.Address = firstAddress
            End If
        End With
    
    MsgBox Join(arr, " ")
End Sub

```

<h2>おわり</h2>
もじぴったんは登録されている言葉の一覧とかが公開されていないので、対戦しながら言葉を登録していって、みたいなかんじです。

ボタン押してぽんぽん登録していけるから楽だけど、
重複した登録ができないようにするとかを追加したい。

とりあえずこちらを参考に登録してみました。

https://encore.mojipittan.jp/files/mojipittan_newwords01.pdf

<br>
超地道だった。

ふつうにもじぴったんした方が楽しいかも
C言語で配列に+1すると+配列の要素サイズ分になる

## 例1

```c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
  char *a1 = "abc";
  char *a2 = "def";
  char *c[2] = { a1, a2 };
  printf("%"PRIuPTR"\n", (uintptr_t)c);
  printf("%s\n", c[0]);
  printf("%"PRIuPTR"\n", (uintptr_t)(c + 1));
  printf("%s\n", *(c + 1));
  return 0;
}
```

```sh
$ clang main.c
$ ./a.out
140702003177488
abc
140702003177496
def
```

## 例2

```c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
  char *a1 = "abc";
  char **c = { &a1 };
  printf("%"PRIuPTR"\n", (uintptr_t)c);
  printf("%s\n", c[0]);
  printf("%"PRIuPTR"\n", (uintptr_t)(++c));
  return 0;
}
```

```sh
$ clang main.c
$ ./a.out
140701791635488
abc
140701791635496
```

## 例3

```c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
  int a1 = 123;
  int *d[] = { &a1 };
  printf("%"PRIuPTR"\n", (uintptr_t)d);
  printf("%d\n", *d[0]);
  printf("%"PRIuPTR"\n", (uintptr_t)(d + 1));
  return 0;
}
```

```sh
$ clang main.c
$ ./a.out
140701859366944
123
140701859366952
```

## 例4

```c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
  int a1 = 123;
  int d[] = { a1 };
  printf("%"PRIuPTR"\n", (uintptr_t)d);
  printf("%d\n", d[0]);
  printf("%"PRIuPTR"\n", (uintptr_t)(d + 1));
  return 0;
}
```

```sh
$ clang main.c
$ ./a.out
140702013851684
123
140702013851688
```
AmplifyでGraphQLを使いつつ、Lambdaを非認証ユーザーで叩く（Typescript）

## 概要
AWS Amplifyにて非認証ユーザーで外部のAPIを叩いて、JSONを引っ張ってくるところを作りたかったが、色々詰まったのでシェア

## 環境
-  "aws-amplify": "^4.3.12",
-  "typescript": "~4.1.5"
-  "vue": "^3.0.0"

## Amplifyの各環境を作る
```ruby:cmd
amplify configure
amplify init
amplify add api
amplify add function
```

このあたりは[この辺](https://amplify-sns.workshop.aws/ja/)を見れば詰まらないと思う。
ファンクション名は`readList`とした。

## Authを設定する
ここからがポイント。
まず、認証の方法だが、非認証ユーザーでのアクセスを許可する場合は、API KeyとIAMがあるが、
API Keyは日付制限（最長365日）があるので、IAMとする。

```ruby:cmd
amplify add auth
```

すると、問が出てるくので以下を選択する。

```ruby:cmd
Do you want to use the default authentication and security configuration? (Use arrow keys):
→ Manual configuration
```

進めると、更に問が出てくるので以下と答える。

```ruby:cmd
Select the authentication/authorization services that you want to use: (Use arrow keys)
→ User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Analytics, and more)
```

さらに進めると、更に問が出てくるので以下と答える。

```ruby:cmd
? Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM)
→ Yes
```
これで、認証の設定は完了。

## GraphQLのスキーマを編集
次にGraphQLのスキーマを変更していく。
以下の設定とした。

```ruby:schema.graphql
input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

type Query {
  readList: String
  @function(name: "readList-${env}")
  @auth(rules: [
    {allow: public, provider: iam},
  ])
}
```

## ファンクションの編集
ファンクションの編集をする。
今回はファンクション名は`readList`として、コードは以下とした。

```ruby:index.js
exports.handler = async () => {
  return JSON.stringify('Hello from Lambda!');
};

```

ここで一旦、プッシュしておく。

```ruby:cmd
 amplify push
```

## フロントの編集
今回はVueのサンプルページをそのまま使用した。

```ruby:Home.vue
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App" />
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';
import HelloWorld from '@/components/HelloWorld.vue';
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import config from '@/aws-exports';
import { readList } from '@/graphql/queries';

@Options({
  components: {
    HelloWorld,
  },
})
export default class Home extends Vue {
  public async mounted(): Promise<void> {
    Amplify.configure(config);
    const res = await API.graphql(graphqlOperation(readList));
    console.log(res);
  }
}
</script>
```

しかし、このままだとエラーが出るため以下の対応をする。
ファイル名 `aws-exports.js → aws-exports.ts` に変更する。
（[こちらの記事](https://qiita.com/higuuu/items/980b1c90ecb8ae347c24)を参考にさせてもらった。ありがとうございます。）

また、aws-exports.tsに以下の記載があるか確認して、ない場合は追加する。
`"aws_appsync_authenticationType": "AWS_IAM"` 

## 確認
結果を確認する。
Homeページにアクセスして、コンソールを開いて確認すると 
`readList: "\"Hello from Lambda!\"` と表示されていると思う。
windows10環境でgit, pythonをインストールしてpowershell上で使う

## powershellとは

windowsで利用できる、コマンドラインインターフェース。
「Windows」＋「S」で検索ボックス"powershell"と入力すると見つかるはず。
> [Windows10 - PowerShell(パワーシェル)の開き方](https://www.curict.com/item/f0/f0f6ab0.html)  

## 1. git のインストール

以下をダウンロードする。
> [git Downloading Git](https://git-scm.com/download/win)
> 64-bit Git for Windows Setup  

以下の「Gitのインストール」部分記載の通り、インストールを進める。以下の記載部分は選択が必要。

> Windows 10 と Powershell（WSL含む） で git を利用する
> https://qiita.com/kerobot/items/78372640127771f92ee0#git-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
> > コマンドラインやPowerShellなどからGitのコマンドを利用するため「Git from the command line and also from 3rd-party software」を選択します。

powershell上で以下を実行して結果が表示されればOK

```
git --version
## ex.) git version 2.34.1.windows.1 等と出力されればOK
```

## 2. python のインストール

以下記事を参照し、パッケージのダウンロード～PowerShellの環境設定までを実施する

> [Windows版Pythonのインストール](https://www.python.jp/install/windows/install.html)

2022.1時点ではpythonのバージョン3.9.9が利用し易そうである。
この場合は、以下のダウンロードリンクからインストーラ(`.exe`)を取得するとよい。

> [非公式Pythonダウンロードリンク](https://pythonlinks.python.jp/ja/index.html)
> [python-3.9.9-amd64.exe](https://www.python.org/ftp/python/3.9.9/python-3.9.9-amd64.exe)

特に以下の点を忘れずに実施する。

> > "Add Python 3.x to PATH" をチェックするのを忘れないようにしてください。
> > もし忘れたら、あわてず落ち着いてもう一度インストールしましょう。何度でも繰り返して大丈夫です。
> > PowerShellの環境設定
> > PowerShellでスクリプトの実行を許可しておきます。
> > スタートメニューで Windows PowerShell | Windows PowerShell を起動し、次のコマンドを実行します。
> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force

powershell上で以下を実行して結果が表示されればOK

```
python --version
## ex.) Python 3.9.9 等と出力されればOK
```

## 参考
[git Downloading Git](https://git-scm.com/download/win)
[Windows 10 と Powershell（WSL含む） で git を利用する](https://qiita.com/kerobot/items/78372640127771f92ee0#git-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
[Windows版Pythonのインストール](https://www.python.jp/install/windows/install.html)
[非公式Pythonダウンロードリンク](https://pythonlinks.python.jp/ja/index.html)
[WindowsPowerShellでPythonを利用する](https://bluebirdofoz.hatenablog.com/entry/2019/01/19/141007)
[GNU Emacs for Windows再入門](https://emacs-jp.github.io/tips/emacs-for-windows)
[visual studio codeをinstall](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)
[WindowsにBashをインストールする方法](https://lab.sonicmoov.com/development/windows-bash/)
[Windows Subsystem for Linuxが表示されない](https://qiita.com/taraka/items/0b5919ac8ee02d81f7ff)
PostCSS で animation の keyframe 名に `:local` が入る

React (Next.js）で開発していて、CSS ファイルで animation の指定を行ったが反映されずに悩んだ。

結論としては、併用していた PostCSS のプラグインの中に悪さしているものがありそう（詳しく検証はしていない）。animation のプロパティを書く順番によって、`:local` が埋め込まれることがあるようだ。

keyframe 名を一番最初に持ってくることで解決する。

```css
@keyframes spinner {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

// これは動かない
animation: 1s infinite alternate spinner;
// => animation: 1s infinite alternate :local(spinner)

// これは動く
animation: spinner 1s infinite alternate;

```

久々にくだらない罠にハマった。

https://stackoverflow.com/questions/48134725/weird-local-in-css-output-file
Redis の WebAPI (Genie)

こちらで定めた仕様を満たすサーバーサイドのプログラムです。
Genie で実装しました。
[Redis の WebAPI を作成](https://qiita.com/ekzemplaro/items/1746b31beef382023f2d)

```julia:redis01.jl
# --------------------------------------------------------------------
#	redis01.jl
#
#						Jan/09/2022
# --------------------------------------------------------------------
using Genie
using Genie.Router
using Genie.Renderer.Json
using Genie.Requests
using Redis

# --------------------------------------------------------------------
function redis_get(key_in)
	conn = RedisConnection()
	str_json = get(conn, key_in)
	disconnect(conn)
#
	str_json
end

# --------------------------------------------------------------------
function redis_list()
	conn = RedisConnection()
	set_keys = keys(conn,"t*")
	disconnect(conn)
#
	json(set_keys)
end

# --------------------------------------------------------------------
function redis_insert(key_in,value_in)
	conn = RedisConnection()
	set(conn,key_in,value_in)
	disconnect(conn)
#
	key_in
end

# --------------------------------------------------------------------
function launchServer(port)

	Genie.config.run_as_server = true
	Genie.config.server_host = "0.0.0.0"
	Genie.config.server_port = port
#
	println("port set to $(port)")

	route("/") do
		"Hello."
	end

	route("/redis_get", method = POST) do
		key = jsonpayload()["key"]
		redis_get(key)
#		"redis_get key = " * String(key)
	end

	route("/redis_list", method = POST) do
		redis_list()
	end

	route("/redis_insert", method = POST) do
#		"redis_list"
		key = jsonpayload()["key"]
		value = jsonpayload()["value"]
		redis_insert(key,value)
	end

	Genie.AppServer.startup()
end

# --------------------------------------------------------------------
launchServer(parse(Int, ARGS[1]))

# --------------------------------------------------------------------
```

サーバーの起動

```bash
julia redis01.jl 8000
```

#クライアントからアクセス#

キーの一覧

```text
$ http POST http://127.0.0.1:8000/redis_list/
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Genie/Julia/1.7.1
Transfer-Encoding: chunked

[
    "t1855",
    "t1857",
    "t1853",
    "t1854",
    "t1852",
    "t1859",
    "t1856",
    "t1858",
    "t1851"
]
```

キーを指定して値の取得

```text
$ http POST http://127.0.0.1:8000/redis_get/ key=t1852
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Genie/Julia/1.7.1
Transfer-Encoding: chunked

{
    "date_mod": "2013-1-16",
    "name": "敦賀",
    "population": 17395
}
```

値の挿入

```text
$ http POST http://127.0.0.1:8000/redis_insert/ key=t1853 value='{"name": "宇都宮","population": 8751600,"date_mod": "2021-3-17"}'
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Genie/Julia/1.7.1
Transfer-Encoding: chunked

t1853
```
E資格合格に向けて　深層学習day4 （物体検知・セグメンテーション）

#物体検知
物体認識タスクの共通事項として、入力は「画像」である。
物体認識では出力において4つの認識タスクがある。
「分類」「物体検知」「意味領域分割」「個体領域分割」の4つである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/4cf4b113-3136-fb51-af12-5be2dbcb2be9.png)

《物体検知における評価指標について》
前提：物体検出は、指定した閾値（Threshold）以下の検出物はそもそもの検出データとして含めない。（限りなく低い閾値の検出物も表示してしまうと、無数に検出されてしまう恐れがあるため）
よって、下記図のように、クラス分類と違い、閾値を変化されることで、検出されるデータの数が6個から3個へと変化している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/114c6d40-6abd-0107-0a79-0d1fc999f14c.png)


物体検知では、予測したBounding Box（BB）と真値としての（BB）の重なりで、精度を評価。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/71b0a27d-f6a4-b225-645f-9203aebdf0b0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/38e4e146-9ca8-167f-609c-60d46c286576.png)

入力1枚で見るPrecision/Recall
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/ae1624a4-274b-dfd2-82b0-e63233730152.png)
※Recallの分子の0は、FN（False Negative：真値は正だが、負と予測したもの）が無いため。

クラス単位でみるPrecision/Recall
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/12a82015-b859-8c4d-f40e-0a0eabdb3a68.png)
※Recallの分子の1は、FNとして、画像4（Pic4）の人を検出できていないため、1となっている。

#SSD（Single Shot Detector）
1ショット検出器を意味する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/2693e409-a214-b065-380a-5e9638fbda1b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/82cbdac6-9f08-1c0b-77fb-ebb927ab65ea.png)

【実装例】

```
from utils.ssd_model import SSD
import torch

# SSD300の設定
ssd_cfg = {
    'num_classes': 2,  # 背景クラスを含めた合計クラス数
    'input_size': 300,  # 画像の入力サイズ
    'bbox_aspect_num': [4, 6, 6, 6, 4, 4],  # 出力するDBoxのアスペクト比の種類
    'feature_maps': [38, 19, 10, 5, 3, 1],  # 各sourceの画像サイズ
    'steps': [8, 16, 32, 64, 100, 300],  # DBOXの大きさを決める
    'min_sizes': [21, 45, 99, 153, 207, 261],  # DBOXの大きさを決める
    'max_sizes': [45, 99, 153, 207, 261, 315],  # DBOXの大きさを決める
    'aspect_ratios': [[2], [2, 3], [2, 3], [2, 3], [2], [2]],
}

# SSDネットワークモデル
net = SSD(phase="train", cfg=ssd_cfg)

# SSDの初期の重みを設定
vgg_weights = torch.load('./weights/vgg16_reducedfc.pth')
net.vgg.load_state_dict(vgg_weights)

```

#セグメンテ－ション
セマンティックセグメンテーションとは、R-CNNのようなバウンディングボックスを出すのではなく、より、詳細な領域分割を得るモデル。すなわち、物体認識においては領域分割を詳細に行うことが必要となる。入力画像のどの位置に物体が存在するのかを画素単位で指定することができれば認識精度も向上すると予想される。

セグメンテーションを実現するネットワークとして、完全畳み込みネットワーク（FCN：Fully Convolution Network）がある。文字通り、全ての層が畳み込み層になっている。通常のCNNは、出力層のユニット数が識別すべきカテゴリー数であった。一方、FCNでは入力画像の画素数だけ出力層が必要になる。すなわち、各画素がそれぞれどのカテゴリーに属するのかを出力する必要があるため、出力層には縦画素数×横画素数×カテゴリー数の出力ニューロンが用意される。

CNNでは畳み込み演算によって、上位層では下位層に比べて受容野が大きくなり、その影響で画像サイズは小さく（あるいは粗く）なる。そのため、最終出力層に入力層と同じ解像度の画素数を得るためには、畳み込みと反対方向の解像度を細かくする工夫が必要となる。

⇒これを解決する1つの方法が「アンサンプリング」と呼ばれる方法で、下位のプーリング層の情報を用いて詳細な解像度を得ることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/a6769a7e-4f6e-bf85-4ace-e1a19623abf9.png)
【typescript入門1】型推論・型アノテーション・型アサーション

# 概要

オンラインサロン IT_KINGDOM で学んだことを、typescript で学んだことを備忘録としてメモしていきます。

# 学習内容

- 型推論
- 型アノテーション（型注釈）
- 型アサーション

# 型推論

- 型を自動で付与する

# 型アノテーション

- 開発者による型の設定

## メリット

- 開発者のドキュメントの役割
- コンパイル速度が上がる
- 型推論のみでは足りない場面がある

# 型アサーション

- 一度設定した型を上書きする(as を用いる)
- 多用すべきではない
- TypeGuard という方法で多用を防ぐ方法もある

```typescript
let foo = {} as {bar: number};

foo.bar = 1;

function double(x: number): number  | undefined {
  if (x > 0) {
    return;
  }
  return x * 2;
```

# 参考資料

[IT KINGDOM](https://it-kingdom.com/)
chocolatey uninstallしてもchocolatey listに出てくるとき

AdobeAIRとかさすがにもうランタイムもいらないだろうと

```powershell
choco uninstall AdobeAIR -y
```

としてchocolateyでAdobeAIRをアンインストールした。
無事インストーラーが起動してアンインストールできた。
※Windowsの設定→アプリと機能で見てもAdobeAIRはなくなった。
しかし、

```powershell
choco list -local
```

とやると何故かまだAdobeAIRが出てくる！
ごみ掃除をしたのにごみが出てくるとか…。
悲しい気持ちになった。適当にあたりを付けて探したところ下記から削除すれば一覧からも削除されるということが分かった。

```
C:\ProgramData\chocolatey\lib
```

誰かの役に立てばいいな。
科学の入り口としての哲学

科学と哲学の関係について書かれていた方がおみえだった。

自分の経験を記録する。

# デカルト
我思う故に我あり。

１０歳くらいの頃、暗い絵ばかり描いて親が心配したらしい。

学校で教えていることが、中途半端で、物事の考え方がさっぱりわからなかった。

絵を描くときに、そのものの色を塗るのではなく、そのものの周りにあるものの色を、そのものに置いてみろという指導を受けた。

そのこと自体は、理論的な整理は後になる。経験として蓄積していった。

理論的にそのころに嵌ったのはデカルトだった。

学校で教えていることよりも、一貫性があるように感じた。

# サルトル
デカルトでは、じゃ、自分が何をするとよいかが考えられなかった。

現象学というのが流行っていた。

サルトルは、社会の中に自分を投げ入れることによって、社会に関係することを選んだ。

その行動と現象学との関係はそんなにうまく整理できなかった。

# マッハ
サルトルで行き詰まっているときに出会ったのが廣松渉だった。
廣松渉が紹介していた

エルンスト・マッハ『感覚の分析』須藤吾之助共訳、法政大学出版局、1971年
https://bookmeter.com/books/7401412

エルンスト・マッハ『認識の分析』加藤尚武共編訳、法政大学出版局、1971年
https://bookmeter.com/books/203520

そして、伏見譲の訳書にであう。

『マッハ力学―力学の批判的発展史』伏見譲訳、講談社、1969年。ISBN 4061236512。
https://bookmeter.com/books/1796431

哲学者が訳したものでなく、物理学者が訳した著書だ。

# ふりかえり
サルトルの考え方は、相対性理論のように、観測主体が、観測対象の中にあっても成立する系について合致している。

つまり、哲学が科学を誘導する場合もあれば、科学が哲学を次の段階に進むように促すこともあるというような。

マッハの考え方から、現代物理学を紐解く緒が理解できたような気になった。

確率論及び統計論　輪講

確率論及統計論輪講 小寺浩司、柏原一雄、石津和紀、北野敏明、佐藤克、小室睦、小川 清†
https://www.ipa.go.jp/files/000055797.pdf

で対象にしている

確率論及統計論　伏見 康治
https://bookmeter.com/books/4297804

の輪講での使用の許諾は著作権者の伏見譲にお願いした。

伏見譲さんは、遺伝子のシーケンサ等でご活躍されている。

「DNAと遺伝情報の物理」伏見譲。統計と確率(20)
https://qiita.com/kaizen_nagoya/items/150646f72c55a36f8c39

# 感染症と遺伝子学
どちらも確率論に基づく分野である。

一番不得意な分野で、どこから着手しようか迷っていた。

病原菌と国家―ヴィクトリア時代の衛生・科学・政治― 小川 眞里子
https://bookmeter.com/books/10149807

科学史家の著作の参考文献から始めようとしている。

# 特異解
一般解が発見的にしか見つけられないことがある。
特異解も発見的にしかみつけられないことがある。

特定の特異解を発見する一般的な手法はあるかもしれない。

「シンギュラリティサロン：松田卓也」を聞いて
https://qiita.com/kaizen_nagoya/items/0efe179ad1b8fd97d7d0

特異点(singular point)は特異(singularity)である。仮説・検証（27)
https://qiita.com/kaizen_nagoya/items/26f2ff3f24496b8252c7

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
### 文書履歴(document history)
ver. 0.01 初稿 　 20220109
ver. 0.02 ありがとう追記 20230530
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
今回はおみくじを作ります　＊1日1回御神籤編

前回は、おみくじ何回も押せる編を、作りました
今回は、1日1回編です
＊ページを更新すると、また、押せます。ページを閉じてまた開くと、また押せます
そこには、ご了承ください

```html
<!--背景設定したかったら、()に、入れる-->
<body style="background-image: url(.jpg);">

<div class="samplearea">
    <div class="omikujibase">
        <p class="kRes" id="KujiRes2">？？</p>
        <p class="kCom" id="KujiCom2">＊＊＊</p>
    </div>
    <p class="button">
        <input id="lottery-start" onclick="ShowKuji( 'KujiRes2', 'KujiCom2' );" type="button"
               value="おみくじを引く"/>
    </p>
</div>

<script type="text/javascript">
    mres = [];
    mcom = [];
    // おみくじの結果とコメント集
    mres[13] = ' 石墨丘 ';
    mcom[13] = '人生が、30年伸びる～お父さんたちより、80年長く生きれるよ';
    mres[12] = ' 平 ';
    mcom[12] = '大吉より上だ　好き～～～～～～～なこと、させてくれるで';
    mres[0] = '大吉';
    mcom[0] = '好きなものをなんぼでも買ってくれるかもしれへんで';
    mres[1] = '中吉';
    mcom[1] = '人生の中で一番楽しい日になるかも';
    mres[2] = '小吉';
    mcom[2] = '勉強に進んで出来る様になるかもね！！';
    mres[3] = ' 吉 ';
    mcom[3] = '頑張ったら褒められるかも';
    mres[4] = '末吉';
    mcom[4] = '頭が、回転しなくて勉強できないかも';
    mres[5] = ' 凶 ';
    mcom[5] = '今日は不幸だ。元気に遊んだら変わるかも';
    mres[6] = ' 大凶 ';
    mcom[6] = '誰もからも、しゃべてくれなくなるかも';
    mres[7] = ' 鬼吉 ';
    mcom[7] = 'すごくひどい病気になって30年、入院生活になるかも';
    mres[8] = ' 悪吉 ';
    mcom[8] = 'ストレスがすごくたまって、友達にいじめをしてしまうかも';
    mres[9] = ' 嫌凶 ';
    mcom[9] = 'いらいらして自殺してしまうかも';
    mres[10] = ' 変凶 ';
    mcom[10] = 'パソコンウイルスに感染して、パソコンを没収されるかも　';
    mres[11] = ' 死亡凶 ';
    mcom[11] = '巨大地震が起きて、家が壊れてご飯も食べれなくなって、死ぬかも';

    /**
     * くじ引きロジック
     * @param kRes
     * @param kCom
     * @constructor
     */
    function ShowKuji(kRes, kCom) {
        // くじを混ぜる
        const lotteries = Math.floor(Math.random() * mres.length);

        // くじ引き結果表示
        document.getElementById(kRes).innerHTML = mres[lotteries];
        document.getElementById(kCom).innerHTML = mcom[lotteries];

        // 1回だけ引ける
        document.getElementById('lottery-start').disabled = true;
    }
</script>
</body>
```
homebrewでインストールしたnginxの設定ファイルの場所


M1 macにしてhomebrewでインストールしたnginxの設定ファイルが、
下記になかったのでどこにあるか調べるとどうやら場所が変わったよう


```
/usr/local/etc
```

下記の場所にありました。
homebrewでインストールしたアプリの設定ファイルは、ここにあるようですね。

```
/opt/homebrew/etc/
```
Firebase Custom Token認証

## サーバサイド(Node.js）
### Cloud Functionsにエンドポイントを作る
```javascript
import {auth} from "firebase-admin"

exports.getCustomToken = functions.https.onCall((data, context) => {
    if (!context.auth) {
        throw new Error("not logged in.")
    }
    return auth().createCustomToken(data.userId)
        .then((customToken) => {
            // Send token back to client
            return {customToken: customToken}
        })
        .catch((error) => {
            console.log('Error creating custom token:', error);
            throw error
        })
})
```

## クライアントサイド
### 通常ログイン成功時
```javascript
import {signInWithEmailAndPassword} from "firebase/auth"
import {httpsCallable, getFunctions} from "firebase/functions"

// login with mail & password 
signInWithEmailAndPassword(firebase.auth, email, password).then(r => {
    // Custome Token エンドポイントへのリクエスト
    const getCustomToken = httpsCallable<{userId: string}, { customToken: string }>(getFunctions(), 'getCustomToken')
    getCustomToken({userId: user?.uid}).then(r => {
        localStorage.setItem('customToken', r.data.customToken) 
    })
})
```

### Tokenでログイン
```javascript
import {getAuth, signInWithCustomToken} from "firebase/auth"

// localstorageからtoken取得
const token = localStorage.getItem("customToken")
if (token) {
    signInWithCustomToken(getAuth(), token).then(r => {
        if (r) {
                // login 成功時の処理
        }
    })
}
```

## 留意事項
### CustomTokenの有効期間
[60分](https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk)。


## 用途
### サービス間のSSO
firebaseで認証しないサービスからfirebaseを用いたサービスへ遷移する際に遷移元でCustomeTokenを生成し、
これを用いてログイン可能。

### 他にも色々
Apple Silicon 搭載機で React Native を使って iOS・Androidアプリを開発する

Apple Silicon 搭載の MacBook Pro で React Native を動作させたときのメモです。なお、React Native 0.66.4 で新規作成したプロジェクトで、MacBook Pro（14インチ、2021）, Apple M1 Pro, macOS  Monterey 12.1 で確認しています。使用環境や、プロジェクトの状況により、異なる場合があります。

## 開発環境

Node.js を 16 以上ににする。私は 16.13.0 を採用しました。iOS はこれだけでシミュレーション・実機のビルドが成功しました。

## Android

Androidビルドは以下のように設定してビルドができるようになりました。ただし、シミュレーターだと上手くいかず、実機ビルドのみ成功しました。


- Kotlin を Apple Silicon をサポートした 1.5.30 以上にする。私は、1.6.10 を採用しました。

```
buildscript {
    ext {
        // ...
        kotlinVersion = "1.6.10"
    }
    // ...
}
```



- Java を Apple Silicon をサポートした 17 に変更する

```
% brew install java
% sudo ln -sfn $(brew --prefix)/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
% java --version
openjdk 17.0.1 2021-10-19
OpenJDK Runtime Environment Homebrew (build 17.0.1+1)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.1+1, mixed mode, sharing)
```
- Gradle を Java 17 をサポートする 7.3.3 に変更する

```
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
```

```
buildscript {
	// ...
	dependencies {
		classpath('com.android.tools.build:gradle:7.0.2')
	}
}
```

## 余談

私の `yarn android` での失敗の1,2割は、eset のファイアウォールでブロックされたが原因でした。
【ABC234】A - Weird Function をC++で解説

#はじめに
　皆さんこんにちは！ 競プロの問題の理解を深めるために解説記事を書いていこうと思います！今回は **ABC234 A, B, C** です！
 気に入っていただけたら**LGTM**して頂けるとうれしいです！
何かあれば**コメント**や[Twitter](https://twitter.com/python05238919)からお願いいたします!
#[A - Weird Function](https://atcoder.jp/contests/abc234/tasks/abc234_a)
 問題の詳細は上の見出しからいけます．
 Difficulty : <font color="Gray">7</font>
####問題概要
 関数$f$を$f(x) = x^2 + 2x + 3$としたときの
   $f(f(f(t) + t) + f(f(t)))$を求めよ．
####制約
　$0 \leq t \leq 10 $
###考察
####ポイント
 **$f(x)$を関数で定義しよう**
####解説
 求める関数$f(x)$を**プログラミングにおける関数**にして出力しましょう．
##実装
 値が大きくなるので関数の戻り値は`long long`型を用いましょう．
##正解コード

```C++:
#include <bits/stdc++.h>
using namespace std;

 //f(x)の関数
long long f(int t){
    return t * t + 2 * t + 3;
}

int main()
{
    //入力
    long long t;
    cin >> t;
    //出力
    cout << f(f(f(t) + t) + f(f(t))) << endl;

}

```
pubspec.yamlのワーニングを無効化する方法

本記事では、pubspec.yamlで出てくるワーニングを無効化する方法を紹介します。

基本的には、ワーニングは無視しない方がいいです。
ただ、以下のような場合、無視したくなることが起きます。

> 1. GitHubに上げたくない画像があり、その画像をgitignore。
> 2. CI (GitHub Actions)で``flutter analyze``を実行
> 3. GitHub上では画像が存在しないため、pubspec.yamlの``asset_directory_does_not_exist``のワーニングでCIが失敗

CIを成功させるためには、ワーニングを無視するしかない、という場合ですね。
このような場合にワーニングを無効化する方法を紹介します。

##無効化する方法##

analysis_options.yamlに以下の文を追記します。

```yaml:analysis_options.yaml
analyzer:
  errors:
    無視したいワーニング名 : ignore
```
上の例でいうと、以下のようになります。

```yaml:analysis_options.yaml
analyzer:
  errors:
    asset_directory_does_not_exist : ignore
```

これで、ワーニングが無効化されました。

##まとめ##

今回はpubspec.yamlで出てくるワーニングを無効化する方法を紹介しました。
CIを使っていると悩ましい状況多々あると思いますが、
今回の情報がお役に立てれば幸いです。

##参考##
https://makicamel.hatenablog.com/entry/2019/04/09/234024
[java]戻り値を利用して台形の面積を求める

アウトプット用!!

5回目は
戻り値を利用して台形の面積を求めていく！！

はじめに
戻り値とは何なのか？？
戻り値とは呼び出されたメソッドから、呼び出し元のメソッドへ値を返すことまたは値を戻すことを言います。
戻り値を使うことでより汎用性のあるメソッドを作れるようになります。

早速ですが、こちらがコードになります

```ensyu1.java
//戻り値を利用して台形の面積を求める
//台形の公式　　　　　面積 ＝ {(上辺 + 下辺)　*　　高さ} /2
public class ensyu1 {
	public static void main(String[] args) {
		int area = daikei(5, 7, 4);
		System.out.println("台形の面積は" + area + "㎠です");
	}
	
	public static int daikei(int topside, int bottomside, int height) {
		return ((topside + bottomside) * height) / 2;
	}
}
```
#①mainメソッドからdaikeiメソッドを呼び出す。
引数に(5,7,4)の値が入っていますが、これは上辺、下辺、高さです。

#②daikeiメソッドで計算する
return areaの部分が戻り値で戻り値の値がdaikeiメソッドの呼び出し元であるmainメソッドに返される。
この場合、daikeiメソッドの左側の戻り値の型をintにする必要があります。なぜなら、returnで戻される型が整数だからです。もし文字列を戻す場合だとStringを指定する必要があります。

##戻り値を使用しない場合のコード

```ensyu1.java
//戻り値を利用して台形の面積を求める
////台形の公式　　　　　面積 ＝ {(上辺 + 下辺)　*　　高さ} /2
public class ensyu2 {
	public static void main(String[] args) {
		 daikei();
	}
	
	public static void daikei() {
		int topside = 5;
		int bottomside = 7;
		int height = 4;
		
		int area = ((topside + bottomside) * 4) /2;
		System.out.println("台形の面積は" + area + "㎠です");
	}
}
```
awsをterraformで構築するには(基本編)



#プロバイダーを決める
```
terraform {
  required_version = ">= 1.0.1"
  required_providers {
    aws = ">= 3.0"
  }
}

provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.aws_region
}
```

#変数定義
terraform.tfvarsにて

```
aws_access_key="xxxxxxxx"
aws_secret_key="xxxxxxxx"
aws_region="xxxxxxxx"
```

variables.tfの中で

```
variable "aws_access_key" {
  type = string
}

variable "aws_secret_key" {
  type = string
}

variable "aws_region" {
  type    = string
}
```

#resourceの定義
あとは例えばaws_alb.tfみたいなファイルを作って(ファイルは分割しなくても動くが、基本分割した方が綺麗だし、わかりやすい)、リソースの定義をする。詳しくはドキュメントを確認。

```
resource "aws_lb" "api_lb" {
  name               = "test-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.test-group.id]
  subnets            = ["${aws_subnet.test_subnet.id}", "${aws_subnet.test_subnet2.id}"]

  enable_deletion_protection = true

  tags = {
    "Environment" = terraform.workspace
    "Application" = "api"
  }
}
```

一通り記載したら下記を実行

```
terraform plan

terraform apply
```

変更あるたびに `terraform plan` `terraform apply`を行う

リソースを一旦消したいのであれば

```
terraform destroy
```

以上メモように記録
おみくじを作ろう　＊何回も押せる版

こんかいは、おみくじ（御神籤）何回も押せる編を作ってみます
スターティン

```ruby


<body>
<body style="background-image: url(mmこ.jpg);">

	</style> 	<script type="text/javascript"><!--
		mres = new Array();
		mcom = new Array();
		// おみくじの結果とコメント集
		mres[0] = '大吉'; mcom[0] = '今日はラッキーな日';
		mres[1] = '中吉'; mcom[1] = 'いいことあるかも？';
		mres[2] = '小吉'; mcom[2] = 'そこそこ良い日かも';
		mres[3] = ' 吉 '; mcom[3] = '頑張れば報われる？';
		mres[4] = '末吉'; mcom[4] = 'まあまあでしょう。';
                     mres[5] = ' 凶 '; mcom[5] = '今日は不幸だ。元気に遊んだら変わるかも';
　　　　　　　　mres[6] = ' 大凶 '; mcom[6] = '誰もからも、しゃべてくれなくなるかも';
　　　　　　　mres[7] = ' 鬼吉 '; mcom[7] = 'すごくひどい病気になって30年、入院生活になるかも';
	         mres[8] = ' 悪吉 '; mcom[8] = 'ストレスがすごくたまって、友達にいじめをしてしまうかも';
                   mres[9] = ' 嫌凶 '; mcom[9] = 'いらいらして自殺してしまうかも';
　　　　　　　mres[10] = ' 変凶 '; mcom[10] = 'パソコンウイルスに感染して、パソコンを没収されるかも　';
                   mres[11] = ' 死亡凶 '; mcom[11] = '巨大地震が起きて、家が壊れてご飯も食べれなくなって、死ぬかも';
        　　　　mres[13] = ' 石墨丘 '; mcom[13] = '人生が、30年伸びる～お父さんたちより、80年長く生きれるよ';
　　　　　　　mres[12] = ' 平 '; mcom[12] = '大吉より上だ　好き～～～～～～～なこと、させてくれるで';　　　
		// 関数
		function ShowKuji(kRes,kCom) {
			// ジャンケンを選ぶ
			var kuji = Math.floor(Math.random()*mres.length);
			// ジャンケンを表示
			document.getElementById(kRes).innerHTML = mres[kuji];
			document.getElementById(kCom).innerHTML = mcom[kuji];
		}
	// --></script>
<div class="omikujibase">
<p id="KujiRes" class="kRes">くじを引いてみよう</p>
<p id="KujiCom" class="kCom">＊＊＊</p>
</div>
<p class="button"><input type="button" value="1日一回までおみくじを引く" onclick="ShowKuji( 'KujiRes', 'KujiCom' );" /></p>
</div>
</style>


<html>
<body>
<pre>
<ol>

```
これで、OK
これにて完成です
は、終了
Premiere Pro のAPI、Scripts TIPS

ほぼ個人用。Premiere Proはスクリプト書く度に調べ回る事になるのでTIPSでまとめておくことにする。

## 外部スクリプト取り込み
``` js
//@include 'functions.jsx'
```


## 現在のシーケンスを取得 app.project.activeSequence
``` js
var seq = app.project.activeSequence;
var seqH = seq.frameSizeHorizontal;//幅
var seqV = seq.frameSizeVertical;//高さ
```

## シーケンス設定取得 getSettings()
``` js
var seq = app.project.activeSequence;
var Pwidth = seq.getSettings(); //セッティング一覧
var Pwidth = seq.getSettings().previewFrameWidth; //プレビュー幅
var Phigh = seq.getSettings().previewFrameHeight;//ブレビュー高さ
var Vwidth = seq.getSettings().videoFrameWidth;//ビデオ幅
var Vhigh = seq.getSettings().videoFrameHeight;//ビデオ高
```
## シーケンス設定変更 setSettings

``` js
//シーケンスのビデオ幅と高さ設定変更
    var seqSettings = seq.getSettings();
    seqSettings.videoFrameWidth = 1280;
    seqSettings.videoFrameHeight = 720;
    seq.setSettings(seqSettings);
```

## 現在選択中のビデオトラックとクリップを取得

```js
    var seq = app.project.activeSequence;//現在のシーケンス
    for (var i = 0; i < seq.videoTracks.length; i++) {
        var videoTrack = seq.videoTracks[i];//ビデオ選択
        for (var j = 0; j < videoTrack.clips.length; j++) {
            var clip = videoTrack.clips[j];//クリップ選択
            if (clip.isSelected()) {//選択したクリップ、videoTrackは現在のビデオ、clipは現在のクリップ
            }
        }
    }
```

## エフェクト取得と設定
``` js
for (var k = 0; k < clip.components.numItems; k++) {
    component = clip.components[k];
    if (component.displayName.match(/テキスト/)) {//クリップエフェクト項目
        for (var l = 0; l < component.properties.numItems; l++) {
            componentPropaty = component.properties[l];
            if (componentPropaty.displayName.match(/スケール/)) {//クリップエフェクト内項目名
                componentPropaty.setValue(100, true);
            }
        }
    }
}
```

## 書き出す文字列が文字化けする時の対処
premiereProで出力するファイルは文字コードがShiftJisで、PremiereProではUTF-8を読み込むので、ファイルの文字コードを変更する。

``` js
    flag = fileObj.open("w");
    if (flag == true) {
        fileObj.encoding = "UTF-8"
        fileObj.write(text);
        fileObj.close();
    }
```

## アイテムの時間を設定する。
clipのstartに秒数を足してendに入れる。この時、time形式にする必要がある。

```js
    var myTime = new Time();
    myTime.seconds = clip.start.seconds + 15;
    clip.end = myTime;
```
AWS Step Functions で AWS Batch のステートマシンを作成する

# ステートマシンの作成

まずステートマシンの `Type` フィールドですが、 `Task` を指定します。これはステートマシンが他の AWS リソースを呼び出すときに使用します。

```json
"Type": "Task"
```

次に `Resource` フィールドですが、Batch 用には次の ARN が用意されています。

`arn:aws:states:::batch:submitJob`

さらにサフィックスに `.sync` を付与すると、ステートマシンは実行完了まで待機します。

> リクエストの完了まで待機してから、次の状態に進むことができます。Step Functions を待機させるには、"Resource"フィールドを使用して、タスク状態定義の.syncサフィックスをリソース URI の後に付加します。

詳しくはこちらを参照してください。

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-to-resource.html#connect-sync

上記を踏まえ、以下のような `Resource` を指定します。

```json
"Resource": "arn:aws:states:::batch:submitJob.sync"
```

次に `Parameters` フィールドですが、以下のように指定します。

```json
"Parameters": {
  "JobDefinition": "call-job",
  "JobName": "call-job",
  "JobQueue": "call-queue"
}
```

以下が完成版になります。

```json
{
  "Comment": "Execute Variant Call",
  "StartAt": "call",
  "States": {
    "call": {
      "Type": "Task",
      "Resource": "arn:aws:states:::batch:submitJob.sync",
      "Parameters": {
        "JobDefinition": "call-job",
        "JobName": "call-job",
        "JobQueue": "call-queue"
      },
      "End": true
    }
  }
}
```

実行時はジョブキューで指定したコンピューティング環境を有効化することを忘れないように注意してください。

以下は実行結果になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/c4760384-05f3-dee8-19c3-530cf683032f.png)

# 参考記事

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-task-state.html

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-to-resource.html#connect-sync

https://docs.aws.amazon.com/ja_jp/batch/latest/APIReference/API_SubmitJob.html
サイト内検索機能を作成してみよう

ホームページにいろいろなことが、入力されていたら、
サイト内検索機能が、あったらいいですね
なので、サイト内検索機能を作成機能を、投稿してみました
じゃぁスタ－ト
<h1>サイト内検索機能全部</h1>


```ruby

<html>
<css>
<form action="自分のページURLを入力" method="get">
<input type="search" name="search" placeholder="検索したいことを入力">
<input type="submit" name="submit" value="検索">
</form>
```

これで完成です
なんと、3行で作れるんです
すごくないですか
完成です
ご参考になると辛いです
SpringBootでAPI提供する時のCORS接続エラーを解決する

# 経緯

Vue.js と SpringBoot を用いて SPA 開発をしていたところ、API が叩けない問題が発生しました。

Postman 等のツールで API を確認すると Spring は正常に機能しているのに、いざ Vue や React から API を叩こうとするとエラーが出てしまう状況でした。

そこでフロントとバックエンドの接続から、値の受け渡しができるまでを記述していこうと思います。

# 結論

結局の所、SpringBoot 側の問題でした。

具体的には、他のプログラムからは接続できないようにセキュリティがかかっているとのこと。

そこで今回は、指定した URL からは API を叩けるように指定していく。

Docker コンテナ間でも接続確認できました。

# SpringBoot の記述

今回は、

1. Vue から { email: ○○, password: ☓☓ } を送信し、Spring で受信内容を出力

2. Spring から { result: OK } を返却する

## ディレクトリ構成

    app
    ├src/main/java/com/example
    |                   ├ controller - SampleController.java
    |                   ├ form       - LoginForm.java
    |                   └ common     - CorsConfig.java
    └ build ...

## SampleController.java

```java:SampleController.java
package com.example.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.form.LoginForm;

@RestController
@RequestMapping("/user")
public class SampleController {

	@PostMapping("/login")
	public Map<String, String> login(@RequestBody LoginForm form) {
		System.out.println(form);
		Map<String, String> sample = new HashMap<>();
		sample.put("result", "OK");
		return sample;
	}

}
```

## CorsConfig.java

```java:CorsConfig.java
package com.example.common;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

	@Bean
	public CorsFilter corsFilter() {
		CorsConfiguration config = new CorsConfiguration();
		config.setAllowedOrigins(Arrays.asList("http://localhost:8081")); // アクセス許可するURL
		config.setAllowCredentials(true);
		config.addAllowedMethod("*");
		config.addAllowedHeader("*");
		config.addExposedHeader("Set-Cookie");

		UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
		configSource.registerCorsConfiguration("/**", config);

		return new CorsFilter(configSource);
	}

}
```

# 起動してみる

![spring_pic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110704/95543b11-52af-38a8-d634-6ede11c9cc02.png)
![vue_pic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110704/caa587cf-5969-2399-cad2-86c217fda0b1.png)

Vue - SpringBoot 間で値の受け渡しができました。

# 最後に

今回はローカル環境上で CORS エラーを解決できましたが、Docker を使ったコンテナ間でのやり取りはまだ CORS エラーが出たままとなっているので、次は Docker 環境上でも機能する仕様にしていきたいと思います。
Lambdaでec2自動起動停止

#自動起動
#iam role作成
AWSコンソールへログイン
https://console.aws.amazon.com/iamv2
左ペインロール押下
ロールを作成押下
一般的なユースケース：lambda
ポリシー：AmazonEC2FullAccess
ロール名：control-ec2
作成

#lambda関数作成
https://console.aws.amazon.com/lambda
関数の作成押下
関数名：start-ec2
ランタイム：python3.9
デフォルトの実行ロールの変更
既存のロールを使用する：control-ec2
関数の作成
以下コード入れる

```
import boto3
region = 'ap-northeast-1'
instances = []
instances.append('対象インスタンスID1')
instances.append('対象インスタンスID2')

ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))
```

test押下
新しいテストイベントの作成
イベントテンプレート：そのまま
イベント名：適当に
作成
test押下
ちゃんと動くか確認

#EventBridge
＋トリガーの追加
トリガーの選択
EventBridge
新規ルールの作成
ルール名：auto-start-ec2

ルールタイプ
スケジュール式
cron(0 23 ? * SUN-THU *)　#平日の朝8時起動

#自動停止
#lambda関数作成
https://console.aws.amazon.com/lambda
関数の作成押下
関数名：stop-ec2
ランタイム：python3.9
デフォルトの実行ロールの変更
既存のロールを使用する：control-ec2
関数の作成
以下コード入れる

```
import boto3
region = 'ap-northeast-1'
instances = []
instances.append('対象インスタンスID1')
instances.append('対象インスタンスID2')

ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))
```

test押下
新しいテストイベントの作成
イベントテンプレート：そのまま
イベント名：適当に
作成
test押下
ちゃんと動くか確認

#EventBridge
＋トリガーの追加
トリガーの選択
EventBridge
新規ルールの作成
ルール名：auto-stop-ec2

ルールタイプ
スケジュール式
cron(0 13 ? * MON-FRI *)　#平日の22時停止
暗い場所で撮影された動画をくっきりあかるくする　機械学習で数行のコードで

#暗い場所で撮影された動画を、明るくする方法です
かんたんに機械学習モデルをつかって実行します。

<img src=https://user-images.githubusercontent.com/23278992/148665528-ca039f32-6207-4e21-b2b8-6b84d96f9801.gif>

#暗くて不明瞭な動画から情報をとりたい
個人のスマホだけでなく、夜間の車載カメラや監視カメラなど、暗くて不明瞭な動画だけど、そこから情報をとりたい場合などあると思います。

#動画用の軽量明るさ強化モデルStableLLVEがすごい
StableLLVEという2021年に発表されたモデルは、軽量で高速ながら、きれいに明るくしてくれます。

<img src=https://user-images.githubusercontent.com/23278992/148664179-4d0cd417-d8f9-4d0e-bc05-cff3a4a30b5a.jpg width=300> <img src=https://user-images.githubusercontent.com/23278992/148664220-c756198f-e8c5-4ea8-8737-59c004d2f08c.jpg width=300>

https://github.com/zkawfanx/StableLLVE

これで動画を処理すれば、明瞭な動画が得られます。

#動画への使用方法
CoreMLモデルを使ってiPhoneで実行してみます。

[**CoreML-Models**](https://github.com/john-rocky/CoreML-Models)からモデルをダウンロード。

https://github.com/john-rocky/CoreML-Models

初期化。

```swift
guard let model = try? VNCoreMLModel(for: StablLLVEImage(configuration: MLModelConfiguration()).model) else { return nil }
let request = VNCoreMLRequest(model: model)
```

[**SemanticImage**](https://github.com/john-rocky/SemanticImage)で動画にモデルをアプライ。

https://github.com/john-rocky/SemanticImage



```swift
SemanticImage().applyProcessingOnVideo(videoURL: url, { ciImage in
     let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
     try? handler.perform([request])
     guard let result = self!.animeRequest!.results?.first as? VNPixelBufferObservation else { return ciImage }
     let newImage = CIImage(cvPixelBuffer: result.pixelBuffer)
     return newImage
}, {  err, editedVideoURL in
   // handle editedVideo in here.
}
```

<img src=https://user-images.githubusercontent.com/23278992/148665563-e3d09097-88d8-4e8f-876b-8c3bf4fbfe40.gif>


動画の再生時間の２〜3倍程度の時間で処理できます。

処理が高速なので、スマホのカメラフィードをモデルに与えれば、リアルタイムで明るくすることもできます。
今回はスマホでやってみましたが、もちろん、PythonとOpenCVでオリジナルモデルを実行することもできます。

#決定的瞬間を逃さずに

モバイル用のモデルを使うことでスマホでも使えますし、モデル自体が軽量なのでさまざまな状況で使えます。
暗闇にさまたげられずに、必要な瞬間を取得できると良いですね。

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

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

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Rails 7.0.1 のプロジェクトで RSpec 実行環境をセットアップ


Ruby 3.0 x Rails 7 のプロジェクトで RSpec の実行環境を作る方法をメモ的に記します。
具体的には **RSpec と FactoryBot** gem をインストールして設定していきます。

```
# 環境情報
$ ruby -v
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [arm64-darwin21]

$ rails -v
Rails 7.0.1
```

結論からいうと Rails 7 独自の設定は特に必要ありません。

# プロジェクトを作成

Rails 7 では `rails new` のオプションでフロントエンド関連の色々を指定できますが、特に指定してません。

```
$ rails new rails7_rspec
```

# RSpec 環境用の gem をインストール

rails new した時に rails7_rspec ディレクトリに生成された Gemfile に追記します。

```
group :development, :test do
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
  gem "rspec-rails" # 追加
  gem "factory_bot_rails" # 追加
end
```

Gemfile に従って gem をインストールします。

```
$ bundle install
```

# 各種 gem を設定

### RSpec を設定

RSpec の基本設定は rails のジェネレータコマンド (rails) を使って作成します。

```
rails g rspec:install
```

これで rspec コマンドから RSpec を即時実行できるようになります。
試しに叩いてみると実行されるはずです。(テストは作ってないので 0 examples になります。)

```
$ rspec
No examples found.

Finished in 0.0002 seconds (files took 0.07517 seconds to load)
0 examples, 0 failures
```

### FactoryBot を設定

RSpec のテストコードで FactoryBot のメソッドを使う際、クラス名 (FactoryBot)　を省略できるようにしておくと便利です。
省略するためには RSpec の基本設定をした時に自動生成された `spec/rails_helper.rb` ファイルに追記します。

```spec/rails_helper.rb
RSpec.configure do |config|
  # RSpec.configure ブロックの中に追記
  config.include FactoryBot::Syntax::Methods
end
```

この記述により、以下のように `FactoryBot` というクラス名をつけなくても FactoryBot のメソッドを spec ファイル内で呼び出せるようになります。

```ruby
user = create(:user)

# 参考：クラス名をつける場合　　user = FactoryBot.create(:user)
```