OmniAICreator/Qiita-1.07M huggingface dataset:
DynamoDBのデータをPartiQLでお手軽にCSVエクスポートする

DynamoDBのデータをちょっとCSVで引き抜きたいってとき、色々方法はありますがマネジメントコンソールから一番手っ取り早くやる方法を紹介します。

# 項目を探索してエクスポート

DynamoDBのマネジメントコンソールからテーブルをスキャンorクエリすることで得られた結果をCSV形式でダウンロードできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/a702fb35-d9d0-452c-963f-c3dfefec306a.png)

ただし、このやり方には注意点があり**今ページ上で読み込まれた分のデータ**しか出力してくれません。

「次のページを取得」が表示されなくなるまでポチポチ押していかないとすべての結果が得られず、少ないデータならこれでもいいのですが量が多いと難儀します。

# PartiQLエディタを使ってエクスポート

こっちが本題です。

PartiQLエディタではSQLに似た構文を使ってDynamoDBをクエリすることができます。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ql-reference.html

クエリ結果を見るだけでなくCSV形式でエクスポートすることができ、これを使えば例えばWHERE句で項目を絞り込んだ結果やSELECT句で任意のカラムを削った状態でのエクスポートも可能になります。
**※SELECT句でのカラムの並び替えやエイリアス付与はできないよう**

```sql
SELECT 
  StringPK
 ,NumberSK
 ,BooleanValue
 ,DecimalListValues[0]
 ,JsonValue.bar
FROM "my_table"
WHERE StringPK = 'bar'
ORDER BY NumberSK DESC
```

例えば上記のようなクエリが実行できます。
**※文字列引用符がシングルコーテーション限定なのに注意**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/9f19c66b-1fd3-3c58-755f-a1382425952b.png)

これも先ほどの手順と同じように一度に取得できる項目数に限界はあるのですが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/7a2d4199-3d05-b2b3-8d1a-bd49acfc875f.png)

テスト用に作った10,000項目あるテーブルでも一回の実行で0.7秒ほどで7,000件近く取ってこれるので、先ほどの手順より圧倒的に少ない回数ですぐに全件読み込むことが可能です（※注：試したのは10,000項目までです）。

## 注意点

1点気を付けることがあるのは、項目を探索ではスキャン及びクエリで消費した読み込みキャパシティユニットが表示されますが、PartiQLエディタでは表示がありません。

じゃあ消費されていないのかというとそんなことがあるはずはなく、しっかり消費されています。

`ExecuteStatement API`でクエリを実行するときに`ReturnConsumedCapacity`パラメータを付けると消費したキャパシティユニットを確認することができます。

```
$ aws dynamodb execute-statement --statement "SELECT * FROM my_table" --return-consumed-capacity TOTAL
～省略～
    "NextToken": "qLVEjEw4XwpTOlsc3SViU54Fqt/G/Sz5sZ7jynxjdsrpkYT4gtXNfZm4WObnb9dTW2nu7YOBOKtCVb8OaVBak0PdEfxF4dQxTMee4cAUQCTN9ft+UWJuNywRhAh7mHjoOZcg/4doWfx8JtIuWkiVn5/FEdOyImCCgWWc4Tv7Q7QI4TkjRPkrYypTKduo3nE8l2r7KiXlLMeUF/BAQBS3txpe+Jtuh4cpBooBpfQn1rFOHTYasbNvSxJhfyMQAKd0O+KaoigAeWCZlLOQ/buNRnliyWOEXCOzhx//7ho4wFwvnTfN5SixkAq1iu1aE0qTXVePQz0jWQT+2iogXCdxd9529TfKm8AG5Ls0w5bdWzJ9NbBHfO6bE7Ul7kvRK/Y=",
    "ConsumedCapacity": {
        "TableName": "my_table",
        "CapacityUnits": 128.5
    },
    "LastEvaluatedKey": {
        "StringPK": {
            "S": "bar"
        },
        "NumberSK": {
            "N": "152"
        }
    }
}
```

先ほどの10,000項目読みだすクエリだと128.5キャパシティユニット消費しています。
速いわけです、たとえテーブルのプロビジョンされた読み込みキャパシティーユニットを1に設定してても問答無用で消費されるので、キャパシティーモードがオンデマンドになっているのと同じ状況と考えた方がよさそうです。

利用するときはDynamoDBのコストを考えてなるべくクエリの無駄打ちをしないようにした方がよいでしょう。

limitを付けると返す項目数を制限してキャパシティユニットの消費を抑えられますが…。

https://aws.amazon.com/jp/about-aws/whats-new/2022/03/amazon-dynamodb-limit-request-partiql-operations/

`ExecuteStatement API`しか対応しておらず、PartiQLエディタ上でLIMIT句のようなものは使えないようです。
lambda-uploaderでResourceConflictExceptionが発生する時の対処


## 事象
lambda-uploaderを実行した際に以下のエラーが発生していた。

```
ResourceConflictException: An error occurred (ResourceConflictException) when calling the UpdateFunctionConfiguration operation: The operation cannot be performed at this time. An update is in progress for resource
```

## 原因

2019/11/27 lambdaの仕様が変更された。

https://aws.amazon.com/jp/blogs/compute/tracking-the-state-of-lambda-functions/

おそらく、これが原因で、lambda-uploaderコマンドにて実行時ResourceConflictExceptionが発生するようになった。
以下のPRで問題解消されており、v1.3.1(2022/4/16)としてリリースされていた。

https://github.com/rackerlabs/lambda-uploader/pull/169

しかしながら、pip install lambda-uploaderで取得したバージョンはv1.3.0(2018/5/15)になっていた。

## 対策

lambda-uploaderをGitHubから直接取得し、最新のライブラリを入れるようにした。

```
- pip install lambda-uploader
+ pip install git+https://github.com/rackerlabs/lambda-uploader
```

無事uploadできた。
lambda-uploaderを使っていたが、敢えて使う理由もないかも。。
BLob を使ってブラウザからバイナリデータをダウンロードするときの罠 (javascript) 


ダウンロードすると、データがすべて文字列化テキスト化）されてしまう現象に悩まされたのでメモ。

## 問題

```hoge.js
data = [0,1,2,3,4];
const blob = new Blob(data, { "type" : "application/octet-stream" });
const downloadURL = window.URL.createObjectURL(blob);
```

こうすると、ダウンロードしたデータは下記のようにテキストデータになってしまうようです。

```hoge.bin
01234
```

# 解決方法

```hoge.js
data = [0,1,2,3,4];
const blob = new Blob([data], { "type" : "application/octet-stream" });
const downloadURL = window.URL.createObjectURL(blob);
```

これで、ダウンロードしたデータはバイナリになってくれます。

data を `[]` で array にすると、バイナリでダウンロードされるようです。data がもともと array なので、配列化しなくてもいいと思ってたら、そういうことではなかったようです。

何でやー
Django+Reactで学ぶプログラミング基礎(28): Reduxチュートリアル(準備と概要)

##### [前回] [Django+Reactで学ぶプログラミング基礎(27): Reactチュートリアル(タイムトラベル実装とチュートリアルまとめ)](https://qiita.com/mingchun_zhao/items/626685221299476890a4)

## はじめに

前回まで、Reactの基本を勉強しました。
今回から、Reduxの勉強をスタートします。
教材は、[Redux公式チュートリアル](https://redux.js.org/tutorials/fundamentals/part-1-overview)を使用します。

## 今回の内容

- チュートリアルの概要と準備
- Reduxの概要
    - Reduxとは、なぜ必要か

## チュートリアルの内容と準備

- チュートリアルの内容
    - Reduxのコアコンセプトと原則
    - Reduxアプリの構成要素
    - Reduxのデータの流れ
    - Reduxアプリ構築の標準パターン

- チュートリアルの構成
    - パート1
        - Reduxアプリのミニマムサンプル
    - パート2
        - Reduxの概念とデータフロー
    - パート3
        - State、Action、Reducerの概念
        - サンプルアプリを作成し、Reduxの機能を理解
        - Reduxの標準パターンと抽象化

- チュートリアルの進め方
    - まず、Reduxの標準パターンで、ゼロからアプリコードを書いてみる
        - Reduxアプリの基本概念と構成要素を理解
    - つぎ、Redux Toolkitを使用し、Reduxアプリを作成
        - Redux Toolkitは、本番アプリを構築するため推奨される方法
        - Modern Reduxでは、標準パターンを最新パターンに変換する方法を勉強

- チュートリアルの前提知識
    - HTMLとCSS
    - ES6の構文と機能
    - 配列
    - スプレッド演算子
        - 反復可能なオブジェクト(配列など)の内部にアクセスし、オブジェクトの複製/マージを行う
    ```
    const foo = ['one', 'two', 'three'];
    const bar = [...foo]; // "..."がスプレッド演算子
    console.log(bar);
    // ['one', 'two', 'three'];
    ```
    - Reactの知識
        - JSX
        - State
        - 関数コンポーネント
        - Toolkit
        - フック(Hook)
            - stateなどReactの機能を、クラスを書かずに使用可能に
    - 非同期JavaScriptとAjaxリクエストの作成
        - Ajaxは、Webブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法
            - XMLHttpRequestによる非同期通信を利用し、通信結果に応じてダイナミックHTMLで動的にページの一部を書き換えるというアプローチ

- ブラウザにReactおよびReduxDevTools拡張機能をインストール
    - React DevTools拡張機能
    - Redux DevTools拡張機能
    - ※ ブラウザは[Brave](https://brave.com/ja/)を使用しています([Braveの検証ブログ](https://qiita.com/mingchun_zhao/items/f789e551ac7e8f6920df))

## Reduxとは、なぜ必要か

- Reduxとは
    - アクションと呼ばれるイベントを使用し、アプリ状態を管理および更新するためのパターン/ライブラリ
    - アプリ全体で使用する状態の集中ストアとして機能

- なぜReduxを使用する必要があるか
    - Reduxは、グローバル状態の管理に役立つ
    - Reduxが提供するパターンとツールを使用し、以下を簡単に理解できる
        - アプリの状態がいつ、どこで、なぜ、どのように更新されているか
        - それらの変更が発生したときに、アプリロジックがどのように動作するか
    - Reduxは、予測/テスト可能なコーディングを支援し、アプリケーションの正常機能を担保

- いつReduxを使うべきか
    - 中/大規模のアプリで、状態管理のロジックが複雑になる場合
        - 大量の共有状態管理が必要で
        - アプリ状態が時間の経過とともに頻繁に更新される場合

## Reduxのライブラリとツール

- Redux自体は小さな独立したJavaScriptライブラリ
    - 通常、以下のようなパッケージにより使用される

- React-Redux
    - ReactコンポーネントがReduxストアと対話できるようにする、公式パッケージ
    - Reduxは任意のUIフレームワークと統合でき、Reactで最も頻繁に使用される
    - React-Reduxは、状態の一部を読み取り、アクションをディスパッチし、ストアを更新

- Redux Toolkit
    - Reduxロジックを作成するための推奨アプローチ
    - Reduxアプリの構築に不可欠なパッケージと関数が含まれている
    - 推奨されるベストプラクティスに基づいて構築されている
        - Reduxアプリ作成におけるReduxタスクを簡素化
        - よくある間違いを防ぐ

- Redux DevTools Extension
    - 時間の経過に伴うReduxストア状態の変化履歴を表示
    - `タイムトラベルデバッグ`など強力な手法を提供
        - アプリを効果的にデバッグできる

## おわりに

Reduxの勉強をスタートしました。
次回も続きます。お楽しみに。

##### [次回] [Django+Reactで学ぶプログラミング基礎(29): Reduxチュートリアル(構成要素とデータフローの概要)](https://qiita.com/mingchun_zhao/items/59e1b271cbba92606c2b)
【Android, Kotlin】Timerを使い一定間隔で一定処理を行う

## はじめに
IT企業入社3か月目の初学者のアウトプットです。

## やりたいこと
Timerを使って、一定間隔で一定の処理を行う
（TimerTaskの内容を繰り返し行う）

## 手順
様々な書き方があると思いますが本記事ではシンプルな書き方を記述します。
１．Timerオブジェクト作成
```kotlin
val timer = Timer()
```
２．TimerTaskクラスに繰り返したい処理を記載
```kotlin
private val timerTask = task()

class task : TimerTask() {
    override fun run() {
    println("hello")
    }
}
```
３．scheduleAtFixedRateメソッドを記載
```kotlin
scheduleAtFixedRate(TimerTask task, long delay, long period)
```
第1引数：繰り返しを実行するクラス
第2,3引数：Long型
## サンプルコード

```kotlin:MainActivity.kt
package com.webserva.wings.android.radio;

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.webserva.wings.android.radio.R.*
import java.util.*
import java.util.Timer

class MainActivity : AppCompatActivity() {
　　// Timer()のインスタンス生成
    val timer = Timer()
    private val timerTask = task()
    // scheduleAtFixedRateメソッドの引数
    private val delay: Long= 0L
    private val Long: Long = 5000L
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(layout.activity_main)

        timer.scheduleAtFixedRate(timerTask, delay, Long)
    }
    class task :TimerTask() {
        override fun run() {
            // 繰り返したい処理
            println("hello")
        }
    }
    // Timer()の終了
    override fun onStop() {
        super.onStop()
        timer.cancel()
    }
}
```

## おわり
Databricks Certified Data Engineer Professionalに合格しました！

そもそも、Databricks Certified Data Engineer Professionalが何かというところから説明させてください。

![Screen Shot 2022-06-17 at 8.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5f5fe84c-cd8b-89af-7c01-889836763188.png)

https://credentials.databricks.com/10f4797f-b030-408e-8a74-9a4565a9d267#gs.3u3fhf

こちらはDatabricksの資格です。

https://databricks.com/learn/certification/data-engineer-professional

Databricks Certified Data Engineer Professional検定試験は、高度なデータエンジニアリングタスクを実行するために、Databricksを活用する個人の能力を評価します。これには、DatabricksプラットフォームやApache Spark、Delta Lake、MLflow、Databricks CLI、REST APIのような開発ツールに対する理解が含まれます。また、最適化、クレンジングされたETLパイプラインを構築する能力も評価します。さらに、一般的なデータモデリングコンセプトに対する知識を用いて、レイクハウスにデータをモデリングすることも評価されます。最後に、デプロイメントの前にデータパイプラインがセキュア、信頼できるものであり、モニタリング、テストされることを保証することもこの試験には含まれます。この検定試験に合格した人は、Databricksと関連ツールを用いた高度なデータエンジニアリングタスクを完了できることを期待されます。



# 求められる知識

- 構造化ストリーミングに対する包括的・実践的な知識
- Delta Lakeにおけるデータ操作(MERGE/CDC/CDF)やパフォーマンス、メンテナンスに関する知識
- Delta Live Tablesの基本と応用(Auto Loaderを用いたインクリメンタル処理)
- Databricks Workflow(Jobs)に対する知識

主に以下のようなDatabricksのマニュアル、ブログ、Spark関連の記事など読みました。読むだけで合格するのは相当難しいと思います。動かしてみてパラメーターや設定と挙動がどう関連しているのかを理解していないと難しいと思います。

- Structured Streaming | Databricks on AWS https://docs.databricks.com/spark/latest/structured-streaming/index.html
- Delta Lake guide | Databricks on AWS https://docs.databricks.com/delta/index.html
- Delta Live Tables | Databricks on AWS https://docs.databricks.com/data-engineering/delta-live-tables/index.html
- Taking Apache Spark’s Structured Streaming to Production - The Databricks Blog https://databricks.com/blog/2017/05/18/taking-apache-sparks-structured-structured-streaming-to-production.html
- Change data feed | Databricks on AWS https://docs.databricks.com/delta/delta-change-data-feed.html

# 受験方法

こちらはオンライン試験です。こちらでアカウントを作成してログインします。ログイン後、試験を選択します。なお、200ドルです。PCに専用のソフトウェアをインストールした後で試験を受けます。カメラで監視(!?)されるので、本を見ながら、調べながらというのはNGです。制限時間は2時間で60問の問題に回答します。選択式です。そして、英語です。

https://webassessor.com/databricks

Professionalの前にDatabricks Certified Data Engineer Associateからスタートするのが良いと思います。

https://databricks.com/learn/certification/data-engineer-associate

Associate試験についても記事を書きました。

https://qiita.com/taka_yayoi/items/76dee9ec942274cb23ca

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
100日後くらいに個人開発するぞ！day047

## 今日は引数を学んでみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/6b8687ef-9abb-d0fd-5542-b26af57437f0.png)




## 今日の学び

### メソッドの使い方

* メソッドは何度も同じような処理を書く必要があるときに有効
    * 例
        * `def introduce(name)`
        * `puts "こんにちは"`
        * `puts "私の名前は#{name}です" `
        * `end` 
        * `introduce("山田太郎")`
        * `introduce("鈴木花子")`
        * `introduce("田中二郎")`

* 引数は文字列だけでなく数値も渡せる
    * 例
        * `def introduce(age)`
        * `puts "こんにちは"`
        * `puts "私は#{age}歳です" `
        * `end` 
        * `introduce(10)`
        * `introduce(25)`
        * `introduce(30)`

* 引数があるメソッドは引数なしでは呼び出せないため結果がエラーになる

### メソッドで複数の引数を受け取る方法
* 括弧の中に受け取る引数をコンマ(,)で区切って並べることで複数の引数を指定することができる
    * 例
        * `def introduce(name,age)`
        * `puts "こんにちは"`
        * `puts "私の名前は#{name}です" `
        * `puts "私は#{age}歳です" `
        * `end` 
* 複数の引数を渡してメソッドを呼び出す場合は定義した時と同じようにコンマ(,)を用いる
    * `introduce("山田太郎",10)`
複雑なことを考えなくてもjavascriptでsleep関数が使える記事

テキストを入力するだけでメッセージ動画が作れるサービス[Teloppy](https://teloppy.com "Teloppy")を運営しております！
## sleepとは？
phpの例で言うと
```php
sleep(1);
echo "１秒経過"
sleep(1);
echo "2秒経過"
```
こんな感じでsleepで指定した秒数待った後に処理ができるようになるという便利な関数で様々な言語で使われています。javascriptにも似たような関数でsetTimeoutがありますが、setTimeoutは非同期関数なので上の処理を実現させるためには
```js
setTimeout(() => {
	console.log("1秒経過");
	setTimeout(() => {
		console.log("２秒経過");
	}, 1000);
}, 1000);
```
このような記述になり、見ずらくて何してるかあまり分からないコードになります。俗に言うコールバック地獄ですね。
Javascriptでは同期処理を実現させるためのawait/async、Promiseが存在しますが、使えるようになるにはある程度勉強しなければなりません。

なので、今回は「**複雑なことは覚えたくないけど、sleepは使いたい**」人向けの記事になります

## 手順
まず、何も考えず無心でこれをコピペします。(※スコープには注意)
```js
const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));//timeはミリ秒
```
そしてsleepを使いたい関数のfunctionの前に無心で"**async**"という文字を入れます。
```js
async function hogehoge(){}
```
のようasyncを入れたらあとは、sleepを呼び出すだけですがsleepを呼び出す際にもまた無心で"**await**"という文字を入れておきます。これで
```js
const sleep = (time) => new Promise((r) => setTimeout(r, time));//timeはミリ秒

async function hogehoge(){
	await sleep(1000);
	console.log("1秒経過");
	await sleep(1000);
	console.log("2秒経過");
}
hogehoge();
```
のようにsleepを呼び出すことができます！

## 使用する時の例
sleep関数を使いたい関数の前にとにかく"async"という単語をいれればよいのでよく使われるようなwindow.onloadの中で使う場合の例で言うと
```js
window.onload = async()=>{
	await sleep(1000);
	console.log("1秒経過")
	await sleep(1000);
	console.log("2秒経過")
}
```
のような形で使います。
jqueryの場合は
```js
$(window).on("load",async()=>{
	await sleep(1000);
	console.log("1秒経過");
	await sleep(1000);
	console.log("2秒経過");
})
```
こうですね。

またいちいち関数を宣言せずに処理を実行したい場合は即時関数で
```js
(async()=>{
	await sleep(1000);
	console.log("1秒経過");
	await sleep(1000);
	console.log("2秒経過");
})();
```
こんな感じで使えます。

また当然のことですが、sleepを使った後の処理は指定の秒数待たないと処理が進みません。
```js
window.onload = async()=>{
	await sleep(1000);
	//１秒後にやりたかった処理
	hogehoge();
	//１秒待つ必要のなかった処理
	gehogeho();
}
```
このようにhogehoge()は1秒後にやりたかったけど、gehogeho()は1秒待ちたくなかったという場合でもgehogeho()は１秒後に実行されてしまいます。
このような場合はwindow.onloadのfunctionにasyncをつけるのではなく別の関数を用意してasyncをつけます。
```js
window.onload = () => {
    async function useSleep(){
        await sleep(1000);
        //１秒後にやりたかった処理
        hogehoge();
    }
    function dontUseSleep(){
        //１秒待つ必要のない処理
        gehogeho();
    }
    useSleep();
    dontUseSleep();
}
```
こうして分けてやると、hogehoge()だけが１秒後に実行されることになります。もっと省略した書き方をすると
```js
window.onload = () => {
    (async(){
        await sleep(1000);
        //１秒後にやりたかった処理
        hogehoge();
    })();
    //１秒待つ必要のない処理
    gehogeho();
}
```
こんな感じです。

## 最後に
今回使った"async"、"await"はES7(2017)以降でないと動かず、古いブラウザだとエラーになってしまうので古いブラウザのサポートも必要な場合はbabelなどでトランスパイルする必要があります。

ちなみにTypescriptで使いたい場合は
```typescript
const sleep= (time: number) => new Promise<void>((r) => setTimeout(r, time));
```
こうです。
cscの作法 その190

# 概要
cscの作法、調べてみた。
ピアノ、やってみた。

# 参考にしたページ

http://otktake.blogspot.com/2016/02/c.html

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1d104ad0-2742-b743-b40c-5678f1da8566.png)



# サンプルコード

```
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;

class Program {
	[STAThread]
	static void Main() {
		Application.Run(new FormPiano());
	}
}




```


以上。
IEが終了したので、webpackやbabelは不要？

IE終了により、webpackやbabelを使う必要がなくなるのか、フロントエンドからビルドステップを完全に消し去ることはできるのか。

# そもそもなぜフロントエンドを「ビルド」していたのか

そもそもなぜwebpackやbabelを使ってJavaScriptをバンドル（1ファイルにまとめる）していたのか

### 1. HTTP/1.1とモジュールシステムの相性の悪さ

ブラウザにはES Moduleというモジュールシステムが導入されています。これは`import`文で他のファイルを読み込むことができるシステムです。
HTTP/1.1については、ブラウザ側で同時接続数制限があります。これは、ファイルを多数読み込む必要があるES Modulesには不向きでした。

### 2. ブラウザのES Module対応率の低さ

ES ModulesはIE非対応です。開発するWebサイトがIEをターゲットにしたい場合、ES Moduleを使うことはできません。
また、JavaScriptフレームワークもシェアを獲得するにはIE対応しなければならず、これらを使っている限りブラウザ上でES Modulesを使うことはできませんでした。

### 3. 高機能なIDEサポートの欠如

TypeScriptなどの静的型付けAltJSを使用すれば高機能なIDEサポートを受けられます。一方、ブラウザで動くJavaScriptの構文では補完や診断などのIDE機能は利用できませんでした。

# IE終了後はどうなるか

### 1. HTTP/2と`<link rel="preload">`

HTTP/1.1に代わってHTTP/2が普及したことにより、同時接続数制限が無くなりました。
また、`<link rel="preload">`が導入されたため、後からimportされるモジュールを全て先読みしておくことが可能になりました。
そのため、パフォーマンスの問題は存在しません。

少し試してみたところ「HTTP/1.1 + bundle」よりも「HTTP/2 + `<link rel="preload">`」のほうが高速でした。

https://twitter.com/_ayame113_/status/1557271685426204677

:::note warn
ただし、高速化するためには深い場所（importしたファイルからさらにimportされるなど）にある依存関係も含めて`preload`する必要があります。

つまり、パフォーマンスを維持しながらwebpackやbabelを捨てるには「依存解析を解析し`<link rel="preload">`をまとめてHTMLに突っ込んでくれるライブラリorフレームワーク」が必要です。
:::

更に、今後「[103 Early Hints](https://blog.jxck.io/entries/2016-12-16/103-early-hints.html)」が本格導入されると、さらにモジュールの先読みができるためもっと高速になります。

### 2. 全モダンブラウザがES Modulesに対応済み

2022年6月16日にIEが亡くなられたので、本番環境でES Modulesを使っても問題ないでしょう。

### 3. Denoによる高機能なIDEサポート

Denoはブラウザと同じURLベースのimport文を採用しています。そして、Deno組み込みのlanguage serverは**ブラウザで使われる構文に対して補完や診断を出すことができます**。
つまり、エディタにDeno拡張機能をインストールすればブラウザ向けESMに対してIDE機能が使えます。
（Node.js向けのtsserverでもいいのですが、Denoを使うとHTTP経由で読み込んだモジュールにも補完が出ます。）
更にTypeScriptも使えます。

:::note warn
TypeScriptやJSXのトランスパイルもサーバー上で行うことができるライブラリがあるため、これを使えば完全にビルドステップを消し去ることができます。
https://github.com/ayame113/ts-serve

これをcloudflare workersやdeno deployなどのエッジコンピューティングサービスで動かすと、処理能力的にも読み込み速度的にも十分実用的です。
:::

総合すると、フロントエンドのコードをbundleする意味は**原理的には**ほぼほぼ無くなっていると言えます。


# 現実的にビルドステップを廃止することは可能か

では既存のプロジェクトから今すぐwebpackやbabelを剥がしてビルドステップを消すことは現実的に可能でしょうか。

##### フレームワークを使っている場合

Next.jsやReactなどのフレームワークやミドルウェアやライブラリに縛られているため、**バンドラーを今すぐ捨てるのは不可能**だと思います。
そもそもnode_modulesをどうするかという問題もありますし。
ただし、最近はブラウザでnative ESMを使う思想のフレームワークも出てきているため、それらに乗り換えることで間接的にwebpackやbabelを捨てていけると思います。

:::note
実際、node_modulesに縛られないDenoには「ビルドレス」を謡うフレームワークが多数あります（[fresh](https://fresh.deno.dev/)や[ultra](https://deno.land/x/ultra@v1.0.1)や[ruck](https://ruck.tech/)など）。
:::

##### フレームワークを使わない小規模なサイトの場合

依存関係が小さい場合、普通にブラウザで`<script src="./main.js" type="module">`のようにESMを読み込んでしまって問題ないと思います。
npmライブラリも、https://esm.sh/ 経由で読み込めば使えます。

フロントエンドでパフォーマンスを維持しながらESMを使うためには、1項で書いたように「深い依存関係を読み取って自動でHTMLに`<link rel="preload">`を挿入してくれるライブラリ」が必要です。
これをcloudflare workersやdeno deployで動かしながら効率よくトラフィックを捌いていくのが大事だと思うのですが、それも結局フレームワークを作っている側の内部実装の話になるので、ユーザーがすぐ切り替えてどうこうという話ではありません。

# まとめ

- IE死んだのでそろそろバンドラー使う意味はないかも（理論上は）
- 結局のところフレームワークの内部実装をどうしていくかという話であって、今すぐwebpackとbabelをdependenciesから外そうという話**ではない**
- 小さいプロジェクトでは普通にESM使っていい（使っている）

今すぐbabel捨てるみたいな話にはならなくて、2年後3年後にbabeらないフレームワークが普通になってくるかもね、くらいの温度感です。

そもそもブラウザで動かすコードをブラウザで動かない構文（`require('lodash')`）で書いた上で1ファイルに結合して使う、というのは言語として不健全極まりない形なので、書いたものがそのまま動く世界を実現したいところです。
2022年、IE卒業式、IEありがとうのアルバム

ここ数日の記念スナップショットです。

## 卒業式
https://web-study.connpass.com/event/250191/

https://www.youtube.com/watch?v=VWHJ06K9UwY

### 卒業証書

<script async class="speakerdeck-embed" data-id="d89d98e536e542619204b1f2a60594ea" data-ratio="0.707258064516129" src="//speakerdeck.com/assets/embed.js"></script>

### 功績をたたえる
<script async class="speakerdeck-embed" data-id="7b49117445704e8ab29d72687252950a" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>

### Edgeへ
<script async class="speakerdeck-embed" data-id="f6f25ef9eaf94b0cac12f775908d9a97" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>


## Twitter

https://twitter.com/VeryFastBrowser



## 記事
[IE11のサポートがついに日本時間2022年6月16日で終了、しかし日本の組織のなんと49％が3月時点でまだIEを使用中との調査結果も - GIGAZINE](https://gigazine.net/news/20220616-internet-explorer-11-shutdown-panic/)

[Internet Explorer に会いたくなったら...](https://zenn.dev/mattn/articles/1486dc4346718a)

[さようなら、全てのインターネット・エクスプローラー（1/5 ページ） - ITmedia NEWS](https://www.itmedia.co.jp/news/articles/2206/17/news073.html)

[Productivity Weekly (2022-06-15号) 簡易版](https://zenn.dev/korosuke613/articles/productivity-weekly-20220615#internet-explorer-11-%E3%81%AF%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%82%92%E7%B5%82%E4%BA%86%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82%E9%95%B7%E5%B9%B4%E3%81%AE%E3%81%94%E6%84%9B%E9%A1%A7%E3%81%82%E3%82%8A%E3%81%8C%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82---windows-blog-for-japan)

["没IE時代" のCSSプロパティが凄い - Qiita](https://qiita.com/monji586/items/b3caaa0e68b42a0a7285)

参考: [IE11サポート終了に備える (主にデスクトップアプリにおいて) - Qiita](https://qiita.com/e99h2121/items/053b3720cc6cc2204956)

以上です～
[TypeScript][lodash] toggle処理（Arrayが値を持っていればremove、なければadd）


```tsx
// xor
const list = ["a", "b", "c"]

console.log(xor(list, ["d"]))
// add => ["a", "b", "c", "d"]
console.log(xor(list, ["b"]))
// remove => ["a", "c"]
```


```tsx
// xorBy
list = [{id: 1}, {id: 2}, {id: 3}]

console.log(xorBy(list, [{id: 4}], item => item.id));
// add => [Object {id: 1}, Object {id: 2}, Object {id: 3}, Object {id: 4}]
console.log(xorBy(list, [{id: 2}], item => item.id)); 
// remove => [Object {id: 1}, Object {id: 3}]
```


## REF

- https://stackoverflow.com/a/37041417
- https://lodash.com/docs/4.17.15#xor
- https://lodash.com/docs/4.17.15#xorBy
Smash Balloon Social Photo Feedのカスタマイズ

Instagramの投稿をWordPressに掲載できるプラグインで、Smash Balloon Social Photo Feedがあります。

このプラグインを実装したときに、H3の要素に、CSSでボーダーを使った修飾がありました。
これが文字に重なって見づらかったので、非表示にするカスタマイズをしました。

Smash Balloon Social Photo Feedの設定画面を表示します。
![2022-06-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/ab2a35a1-2884-fbc3-7282-95a58430b5c6.png)

画像のように、Instagram Feedのメニューの設定を選択します。

![2022-06-17-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/fed8d17c-793e-8814-ad36-634abb3a4680.png)

Feedsの画面のカスタムCSSの欄に、下記のコードを入力します。
そして、右上にある変更を保存のボタンをクリックします。

```css
.article h3::after{
    content: none;
}
```

これで、タイトルの文字のみ表示されるようになります。
Python勉強③ 最大公約数と最小公倍数 2022/06/16

さて今日は最大公約数の問題でユークリッドの互助法にぶち当たりました。

ユークリッドの互助法とは...

2つの自然数 𝑎, 𝑏 について，𝑎 を 𝑏 で割ったときの商を 𝑞，余りを 𝑟 とすると
「𝑎 と 𝑏 の最大公約数」は，「𝑏 と 𝑟 の最大公約数」に等しい。

具体例で表すと
 
120 ÷ 50 = 2 ... 20
50　÷ 20 = 2 ... 10
20　÷ 10 = 2 ... 0
(10　÷ 0  =  10を返す)

この場合10が最大公約数となります。

~~~
def gcd(x, y):
    if y == 0: #上記の数式だと10÷0=の場合、10を返す。つまり余りが0で計算が終わりの場合
        return x
    else: #あまりの数でわる式を返す
        return gcd(y,x%y)

print(gcd(12, 18))
~~~

次に最大公倍数。これは最大公約数がわかっていたら簡単なんですね。

aとbの最小公倍数は

最小公倍数　＝　a÷ 最大公約数　× b 

という公式があるようで。何か見覚えがあるような気もする。

ということで最小公倍数は以下のように求められます。

~~~
def lcm(x, y):
	return int(x / gcd(x, y)) * y
~~~

最大公約数の書き方を覚えていればこっちは楽勝ですね。
JavaScriptでページ内リンクにスクロールする方法

ページ内リンクへの移動をjavascriptでやる方法が通常のaタグで行うのとは違う感じだったので、関数を作ってさっくりできるようにしてみました。

ついでに移動先を微調整できるようにしました。idの位置よりちょっと上にしたりできるのでヘッダーなどを固定していてもずらして表示できます。
```javascript
function scrollToID(id, margin){
  const elm = document.getElementById(id);
  if(!elm){
    console.error("idが見つかりません");
    return;
  }
  if(!margin) margin = 0;
  window.scrollTo({ 
    top: elm.offsetTop + margin, 
    behavior: 'smooth' 
  });
}
```
引数に移動先のidを入れてください。marginはidよりちょっと上に移動したい場合にマイナスの値を入れてください。marginは省略可能です。

使うときは要素にonclickで実行するようにすればOKです。
OracleのUNDOデータまとめてみた

Oracleをいじっていると聞くことがあるUNDOという言葉、なんとなくロールバックのデータを保持しているのかと思っていたけどどうやらそれだけではないらしいので少し深堀して調べてみた。
# UNDOデータとは何か
簡単に言うと、トランザクション中変更したデータの元データの事をいう。
deleteやupdate文を流した後に、流す前のデータを保持している簡単に言うと期間限定のバクアップのこと。
つまり、このデータがあればいつでも、テーブルを更新前の状況にできるということだ。

# UNDOデータの使い道
### トランザクションのロールバック
おそらく最も認知されているUNDOデータの利用方法
コミットしていないトランザクションをロールバックするのに利用する。

### 読み取り一貫性の確保
テーブルを更新しても、コミットしない限りほかのユーザーやセッションには表示されない

### フラッシュバック機能
テーブルを昔のある時点まで、戻す機能で利用される。
これはのちに述べるUNDOデータの保存期間との兼ね合いもあるがとても便利な機能。

### DBリカバリ
DBに何か障害があった場合、トランザクションを張る前の状態に戻すのに利用する。

# UNDOセグメントとUNDO表領域
UNDOデータはUNDOセグメントに格納されます。UNDOデータは必ず一つのセグメントに格納されてほかのセグメントにまたがることはありません。1つのトランザクションにつき1つのUNDOデータを作成するで参照するセグメントも1つになるということ。
逆にUNDOセグメント内に複数のUNDOデータが格納されることはある。

このUNDOセグメントはUNDO表領域内に格納される。
1つのインスタンスにつきUNDO表領域は1つ必要になる。

# UNDOの保存期間
### 最小保存期間
UNDOはトランザクションをコミットすると古いUNDOデータが不要になることがあります。また、フラッシュバック機能を実行するために古いUNDOデータが必要になる。古いUNDOデータをトランザクションが終了した後も残しておくには、UNDO_RETENTIONを設定する。
UNDO_RETENTIONパラメーターの値絵を変更すると最小保存期間を変更できる。

:::note info
デフォルト値では「900」が設定されている
:::

### 保存期間の保証
保存期間の保証を有効にすることでUNDOデータの最小保存期間が保証される
保存期間を有効にするにはUNDO表領域を作成する際にRETENTION GUARANTEE句を指定する。
またALTER TABLESPACE文で指定を変更することもできる。
無効化するにはRETENTION NOGUARANTEE句を指定する

### UNDO_RETENTIONの確認
公式リファレンスによると
>現行のUNDO表領域に対してUNDOがOracle Databaseで保存される時間は、V$UNDOSTAT動的パフォーマンス・ビューのTUNED_UNDORETENTION列に問い合せて取得できる。

# UNDOに関するエラー

### UNDO表領域が小さくてエラーになる場合
UNDO表領域は自動拡張が可能である。この自動拡張機能がOFFになっており、UNDO表領域が小さい場合大量のデータ更新処理がおこなわれると、__ORA-30036: UNDO表領域内でセグメントを拡張できません__ というエラーが出る。

### 読み取り一貫性が維持できない事による「スナップショットが古すぎます」
ORACLEは更新前にテーブルを確認した場合、更新する前のテーブルを確認し続ける。この時確認しているテーブルはUNDO領域に保存されたものである。
UNDO領域が狭い場合、UNDOの保存期間が短すぎる場合は、__ORA-01555 スナップショットが古すぎます__ というエラーが出る。


# 参考
[Oracle® Database管理者ガイド](https://docs.oracle.com/cd/E16338_01/server.112/b56301/undo.htm#BJFFIACJ)
[社内SE雑記ブログ](https://techblog.short-tips.info/sql/6042dba_undo.md)
[Oracleデータベース・リファレンス](https://docs.oracle.com/cd/E82638_01/refrn/UNDO_RETENTION.html#GUID-D238E854-A2C5-463E-A146-31F61300124E)
[なんとなくを腑に落とすシリーズ ～第1回 UNDO（前編）](https://www.intellilink.co.jp/column/oracle-promenade/2018/091800.aspx)
[ORA-30036: UNDO表領域内でセグメントを拡張できません　株式会社コソール](https://cosol.jp/knowledge/knowledge_post/ot0022_ora30036)
[OracleのUNDO表領域でやらかしてしまった話](https://iine-programming.hatenablog.com/entry/2019/08/28/223447)
[Oracle Database ORA-01555 の原因と対処方法](https://dekiruengineer.com/engineer/workaround_for_oracle__ora_01555/)
Androidでボタンを一定時間無効にする方法

# 概要

Androidのボタンの連打を防ぐためボタンが押されたら一定時間無効化したいことがあった。
そのため、ボタンを一定時間無効にする方法を記載する。
言語はKotlin

# ボタンを一定時間無効にする方法

以下のような関数を定義する。
```Kotlin
// Buttonを指定mill秒の間無効化する
fun disableButtonFixedTime(button: Button, millSec: Long) {
    button.isEnabled = false
    Handler().postDelayed({ button.isEnabled = true }, millSec)
}
```

ボタンを押したときに上記の関数を呼び出すことによって指定時間ボタンを無効化することができる。
```Kotlin
button.setOnClickListener {
    disableButtonFixedTime(it, 1000)
    something() // ボタンを押したときにやりたい処理
}
```
DJコンをUnityで制御できるようにしてみた(配布あり)

# 前置き
## どうでもいい人は飛ばしていいです
「なんでもできるUnityなんだしDJコンも入力いけるんじゃね？」
「それできるならDJコン使ったゲームとかいけるじゃん！」
って思ったことから始まりました。

まず自分が持っているのは「DDJ-400」です。
色々と調べた結果Midiコンであることが判明しました。
そこからMidiコンをUnityで使う方法を探し、遂に見つけました！
**Keijiro**さんが出している「[**Minis**](https://github.com/keijiro/Minis)」です!
そして最近の「InputSystem」を使っていることがわかり、勉強したり触ったりしてました。
しかしDJコンとMinisの相性が悪いことが判明しまた色々と試行錯誤してみました。
その結果同じ人がMinisの前バージョンである「[**MidiJack**](https://github.com/keijiro/MidiJack)」を見つけました！
こちらの方がMinisよりも相性がよいことがわかり、今回はこちらで実装をしています。

# 作ったもの
1. MidiJackのコントローラー入力をDJコン用にするスクリプト
2. DDJ-400のようなUIを作ってボタンやジョグ入力が何Channelで何番なのかが一目でわかるもの
![unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/379d4cee-df26-fb79-314d-548dd744255f.png)


3. 試しにDDJ-400でEffectを制御できるようにしたもの(外部アセット使用のため差し替えてあります)
![IMG_9287_MOV_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/c75ec32e-a07f-f830-0868-16429ebb2081.gif)

# 開発環境
Unity2021.3.1f1
DDJ-400
# 導入方法
1. まず[ここ](https://github.com/Blood421/DDJ400Inputter)から[.unitypackage](https://github.com/Blood421/DDJ400Inputter)をダウンロードしてインポートします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/ee6e4c52-d4f1-4490-a192-a39c38123c28.png)
2. その他必須パッケージをインポートします
- [**MidiJack**](https://github.com/keijiro/MidiJack)
- [**UniRx**](https://assetstore.unity.com/packages/tools/integration/unirx-reactive-extensions-for-unity-17276)
- **TextMeshPro**(PackageManagerから)

**これで導入は完了です！**

# 使い方
まず入力をConsoleで確認するだけのSceneがあります。(TestDebug)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/a14d1401-7ffb-b7d6-818e-05856d9dcea6.png)
これは接続してコントローラーをいじるだけでConsoleに出力されるだけのものです。
***
続いて↑にも画像を載せたUIで確認できるSceneがあります。(DDJ400DebugUI)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/b5050849-e6d0-ca42-535b-b2ef380ff446.png)
これは入力があったものに応じてジョグやツマミなら回ったりボタンなら赤くなったりするものです。
Channelなどを確認するためのものです。
ついでにここからビルドした.exeをダウンロードできます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/b05e044a-4be8-d40f-219e-e1f903907b25.png)

***
最後にエフェクトを制御できるSceneがあります。(Demo)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/b629fdc0-9724-d212-1cd2-68578591ce64.png)
ここではジョグでエフェクトの再生スピードを変化させることができます。
コントローラー中央最上部のツマミ(ロータリーセレクター)でエフェクトの種類を変えられます。
# スクリプトについて
本パッケージはUniRxを使っています。
基本的にこのように各ControllerからSubscribeするだけで使えます！
詳しくはDebugUIに入っているスクリプトを見てください！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/7d39d85b-d186-788f-d66a-95156709c304.png)


# 最後に
これでDDJ-400を使ってゲームだけじゃなくて色々なものが作れそうです！
もし他の人で使いたい人がいたら是非使ってください！
お世話になっている公式ドキュメント

タイトル通り、日頃からお世話になっている技術の公式リファレンス集です。知識を得る時ググるのはもちろんですが、やはり一次情報を読むのが一番だと思う!!ということでまとめました。随時更新していきます。

<br>

##### Ruby
https://docs.ruby-lang.org/ja/3.1/doc/index.html

<br>

##### Ruby on Rails
https://api.rubyonrails.org/

https://guides.rubyonrails.org/command_line.html

<br>

##### RSpec
https://rspec.info/documentation/

https://relishapp.com/rspec/rspec-core/v/3-11/docs/command-line

<br>

##### Gem
https://guides.rubygems.org/command-reference/

<br>

##### Bundler
https://bundler.io/docs.html

<br>

##### rbenv
https://github.com/rbenv/rbenv

<br>

##### Git
https://git-scm.com/docs
VBA_12_Class_Get_Let_サンプル

Keyword
---
Class
Private
Public
Get
Let

Sample Code
---
```vb:Module
Public Sub MySample20220617()
    Dim myWktime As Class_WorkTime2
    Set myWktime = New Class_WorkTime2
    
    Debug.Print myWktime.BusinessDay
    Debug.Print myWktime.DayOfWeek
    Debug.Print myWktime.WorkTime
    
    myWktime.BusinessDay = "2022-07-01"
    myWktime.DayOfWeek = "木"
    myWktime.WorkTime = 8
    
    Debug.Print myWktime.BusinessDay
    Debug.Print myWktime.DayOfWeek
    Debug.Print myWktime.WorkTime
End Sub
```
```vb:Class Module
Private myBusinessDay As String
Private myDayOfWeek As String
Private myWorkTime As Long

Public Property Get BusinessDay() As String
    BusinessDay = myBusinessDay
End Property
Public Property Get DayOfWeek() As String
    DayOfWeek = myDayOfWeek
End Property
Public Property Get WorkTime() As Long
     WorkTime = myWorkTime
End Property
Public Property Let BusinessDay(ByVal pBusinessDay As String)
    myBusinessDay = pBusinessDay
End Property
Public Property Let DayOfWeek(ByVal pDayOfWeek As String)
    myDayOfWeek = pDayOfWeek
End Property
Public Property Let WorkTime(ByVal pWorkTime As Long)
    myWorkTime = pWorkTime
End Property
```
Aurora Serverless V2を使ってみた感想(まだ商用ではないかも。。)

# 初めまして
初めまして、都内でクラウドエンジニアをやっている平野です。
今回は初投稿として、AuroraServerlessV2を利用してみました。

# 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/91c70f1c-5802-3fae-3819-47fadaf2a9a1.png)
この構成を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/036ce44c-2cfe-bc60-cdf2-f1ee9b525d1c.png)
こんな感じにします。

# やること
## 1. Zabbixサーバーを停止する
```
sudo systemctl stop zabbix-server
```
## 2. Webサーバーも停止する
```
sudo systemctl stop httpd
sudo systemctl stop php-fpm
```
## 3. RDSをAuroraServerlessV2に変更する
スナップショットを取り、Aurora DB Clusterを作成する。
```
aws rds create-db-snapshot --db-snapshot-identifier zabbix-db --db-instance-identifier zabbix-db-snapshot
aws rds restore-db-cluster-from-snapshot --db-cluster-identifier zabbix-db-cluster --snapshot-identifier zabbix-db-snapshot
--engine aurora-postgresql
```
PostgreSQL 13.10にバージョンを上げてServerlessインスタンスを追加する。
```
aws rds modify-db-cluster --db-cluster-identifier zabbix-db-cluster --engine-version 13.10
```
クラスタ設定でとりあえず、ACUの設定を行う(0.5～4)
```
aws rds modify-db-cluster --db-cluster-identifier zabbix-db-cluster --serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=4
```
サーバーレスインスタンスの追加
```
aws rds create-db-instance --db-instance-identifier zabbix-db-cluster-instance-01 --db-cluster-identifier zabbix-db-cluster --db-instance-class db.serverless 
```

## 4. ZabbixのDB設定を変更する。
`/etc/zabbix/zabbix_server.conf`
```
DBHost=クラスタのリードエンドポイント
```
`/etc/zabbix/web/zabbix.conf.php`
```
$DB['SERVER']   = 'クラスタのリードエンドポイント'; 
```
## 5.Zabbixを起動
```
sudo systemctl start zabbix-server
```
## 6. Webサーバーも起動する
```
sudo systemctl start php-fpm
sudo systemctl start httpd
```


# 最後に
ACUをコスト的に考えてvCPU1のACU4 を上限とした場合、勝手に落ちる事象が発生した。(07:30頃)
AWSにチケットを切って質問したところACUを上げたら落ちないかもしれないとの情報を得た。
(追記:2022/06/24 ACU上限をついていかったが、起動時に100%だったための判断か・・そもそも、Insertがたまっているので再起動するとACUがある程度高く設定していても100%になる。ACU負荷が50%程度の時に落ちている。画像はないが、1秒のメトリックスでも突然死前に急上昇をモニタ出来ていない)

クラスタ設定でとりあえず、ACUの設定を行う(0.5～4)
```
aws rds modify-db-cluster --db-cluster-identifier zabbix-db-cluster --serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=8
```
##### ~~上限をACU 8にしたところ、勝手に落ちる事象は発生しなくなった~~。また、ACUの一日平均が1.7が1.2程度になり、結果的にコストを抑えることができた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/dcff309f-baf7-9355-45e7-786c9a11c9e1.png)

##### ただあげても、基盤負荷のピークか何かのタイミングで連続して停止していまう問題が発生。リーダーインスタンスとしてサーバーレスを使うのもありかもしれないが、なぜか12ACU上限設定で負荷0にもかかわらずACU8をキープしていたので、結果的にdb.r6g.largeにした。


# まとめると(追記:2022/06/24)
- 負荷に対して結構リアルタイムでACUがスケールする。
- ACU上限が低いと再起動する（らしい）
- リーダーでもなんかACUが高い。

フェールオーバーが多発しても許容できる環境であれば、使えるかもしれない。1ACU=0.2USD/hは高いのでSavings Planなどが対象で、突然死がなければサーバーレスインスタンスがスモールスタートPJのスタンダードになるかもしれない。
AndroidのEditTextのつまみ部分の色をする方法

# 概要

AndroidのEditTextのつまみ部分の色を変更したいときがあった。
変更が反映されず少し手こずったので忘備録としてやり方を記載する。

# EditTextのつまみ部分の色をする方法

styleで`colorControlActivated`に変更したい色を定義する。
```styles.xml
<style name="CustomTextSelectionHandle">
    <item name="android:colorControlActivated">@color/newYellow</item>
</style>
```

レイアウトのTextViweのthemeにstyleを反映させるとつまみの色が変化する。
<font color="Red">`style="@style/CustomTextSelectionHandle"`としてもつまみ部分の色は変更されず、themeでないと反映されなかった</font>
```layout.xml
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView"
    app:theme="@style/CustomTextSelectionHandle" />
```
Gitコマンド逆引きメモ

Gitコマンドの逆引きメモです。「やりたいこと→コマンド」という形にしています。最後に公式ドキュメントへのリンクを付けてますので合わせて参考にしてください。

<br>

##### 現在のリモートリポジトリを確認する
```
$ git remote -v
```

<br>

##### リモートリポジトリ（origin）を変更する
```
$ git remote set-url origin <URL>
```

<br>

##### ローカルブランチの名前を変更する
```
masterをmainに変更する
$ git branch -m master main
```

<br>

### 参考
https://git-scm.com/docs
DataikuDSSをRockyLinuxにインストールする

# はじめに
DataikuDSSをRockyLinuxにインストールした際の手順のメモです。

# 手順
基本的に次を参照します。

https://www.dataiku.com/ja/%E8%A3%BD%E5%93%81/%E5%A7%8B%E3%82%81%E3%82%8B/linux/


https://doc.dataiku.com/dss/latest/installation/custom/requirements.html


①　（適当なディレクトリに移ってから）wgetでDataikuDSSインストーラを取得する
```
$ wget https://cdn.downloads.dataiku.com/public/dss/10.0.2/dataiku-dss-10.0.2.tar.gz
```
②　解凍する

```
$ tar xzf dataiku-dss-10.0.2.tar.gz
```

③ Dataiku用のデータ格納ディレクトリを作る（DataikuDSS起動プログラムもインストール後に入る）
※名前は適当です。

```
$ mkdir dataiku_data
```

④ インストーラでインストールする
マニュアルに沿ってポートは-p 11000としましたが、多分空いていれば何でもいいと思います。

```
$ ./dataiku-dss-10.0.2/installer.sh -d dataiku_data -p 11000
```

インストール時に必要なパッケージが無いと、事前に入れろとErrorが出ます。例えば、git, nginx, ncurses-compat-libs, python2, python36などです。その場合、表示されたパッケージをdnf installで入れてから再度先のコマンドを実行します。

⑤ 11000ポートをあけておく

```
$ sudo firewall-cmd --add-port=11000/tcp --zone=public --permanent
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all
(portsに11000/tcpが追加されていることを確認)
```
⑥ DataikuDSSを起動し起動確認
インストール時に-dで指定したディレクトリ内のbinの中に起動プログラムがある
```
$ ./dataiku_data/bin/dss start
$ ./dataiku_data/bin/dss status
（backend, ipython, nginxがそれぞれrunningであればOK）
```

⑦ Webブラウザからhttp://${マシンのIP}:11000にアクセスする
先のrequirementに書かれている指定ブラウザで開くと、アクセスできるはず。
 
おしまい。

# 環境
- RockyLinux 8.6(Hyper-V)
- DataikuDSS 10.0.2
リプライ機能を実装するには？Day2

オリジナルアプリ開発Day2、２本目の記事です。自分のメモのために書いています。

# RDB構造でリプライ機能実装する方法は？
Twitterやyoutubeのコメント欄のように、コメントに対して、コメントをする機能をreplyと言いますが、その機能をどのようなRDB設計で再現すればいいのか考えていました。

自分が考えたものも含めて、解決策は５つ。

## 先人たちが見つけてくれた解法
・隣接リストモデル（ナイーブツリー）.
・経路列挙モデル
・閉包テーブルモデル
・入れ子集合モデル

よく纏められたサイトがあったのでそちらをご紹介します。

https://www.wantedly.com/companies/tutorial/post_articles/299434

https://www.slideshare.net/kamekoopa/ss-27728799

自分ならば、上記４つの解法の中から１つ選ぶとしたら、閉包テーブルモデルを採用すると思います。

## 自分が考えた解法
コメントテーブルに対して、コメントのIDを外部キーとしたリプライテーブルを作成します。これで、２階層構造のコメント欄が完成です。
![絵-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/4010d7e7-4b73-cc0f-6504-9ed5bbcb7944.jpeg)
リプライに対して、さらにリプライしたいのならば、リプライ２テーブルを作成します。アソシエーションを図示すると下のような感じです。
![絵-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/3f2f793f-d92d-430d-2a32-280ad286f5fd.jpeg)
さらに階層構造を作りたいのなら、テーブルを増やしていけばその分階層も増えます。
#### 自分が考えた解法の欠点
テーブルの数を上限にリプライの階層が数の上限が決まってしまうということです。例えば、コメントテーブルとリプライテーブルしか用意していない場合、コメントにリプライし、さらにそのリプライに対して、リプライするということができません。**しかし**、実際に顧客が利用する場面を想像すると、リプライに対してさらにリプライを返す行為を何度も繰り返している場面は想定されにくく、この方法でツリー構造を作っても問題ないのかなと思いました。
arraybuffer 画像を form-data で Node.js サーバにアップロードできない問題

LINE WORKS のトーク Bot を使って送信した画像をLINE WORKSのストレージからダウンロードして、 Node.js サーバーにアップロードするサンプルです。
LINE WORKSのストレージからダウンロードした画像はarraybufferの形です。
axiosを利用します。

#### ダメなコード

```
import Axios from 'axios';
import FormData from 'form-data';

......

try {
  const lwResponse = await Axios.get(
    'http://storage.worksmobile.com/openapi/message/download.api',
    {
      headers: {
        consumerKey: consumerKey,
        authorization: 'Bearer ' + accessToken,
        'x-works-apiid': apiId,
        'x-works-resource-id': resourceId,
      },
      responseType: 'arraybuffer',
    }
  );

  const formdata = new FormData();
  formdata.append('file', arraybuffer);

  await Axios.post(
    toUrl,
    formdata,
    {
      headers: {
        'content-Type': 'multipart/form-data',
      }
    }
  )
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    throw error;
  });
} catch (error) {
  console.error(error);
}
```

form-data の boundary（境界線） エラーと403エラーが出ました。
ヘッダーを出力して見ると、確かにboundaryのデータがありませんでした。

```
Content-Type: multipart/form-data; boundary=
```

403エラーの原因は、アップロードしようとするファイルのメタ情報が足りないからです。

Bufferデータを処理しないとアップロードできないと思いましたが関係ありませんでした。


#### 修正後のコード：

```
import Axios from 'axios';
const FormData = require('form-data');

......

try {
  const lwResponse = await Axios.get(
    'http://storage.worksmobile.com/openapi/message/download.api',
    {
      headers: {
        consumerKey: consumerKey,
        authorization: 'Bearer ' + accessToken,
        'x-works-apiid': apiId,
        'x-works-resource-id': resourceId,
      },
      responseType: 'arraybuffer',
    }
  );

  const formdata = new FormData();
  formdata.append('file', imageBuffer, {
    filename: 'dummy.jpg', //ポイント1：ダミーファイルを設定してメタ情報をつける
  });

  await Axios.post(
    toUrl,
    formdata,
    {
      headers: formdata.getHeaders(), //ポイント2：getHeadersでヘッダーを取得
    }
  )
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    throw error;
  });
} catch (error) {
  console.error(error);
}
```

+ ポイント1：ダミーファイルを設定してメタ情報をつける
画像をNode.js サーバにダウンロードして保存先の実際のファイル名で指定する方法もあります。ダウンロードした画像を参照しない場合はダミーファイル名のがおすすめです。

+ ポイント2：FormDataのgetHeadersでヘッダーを取得
通常の`content-Type: multipart/form-data`だとboundary情報がなくなるようです。

参考
https://qiita.com/itoudium/items/d9f04f379d34265387d8
【Angularアプリケーション開発 #7】選択したデータの詳細を表示する。

今回やること
・リストから選択したデータの詳細を表示する。

- onSelectメソッドを作成します。
引数はMember型です。memberを受け取りselectedMemberへ設定します。

```typescript:members.component.ts
import { Component, OnInit } from '@angular/core';
import { Member } from '../member';
import { MEMBER } from '../mock-member';

@Component({
  selector: 'app-members',
  templateUrl: './members.component.html',
  styleUrls: ['./members.component.css']
})
export class MembersComponent implements OnInit {

  members = MEMBER;

  member:Member = {
    id:'1',name:'huyuki'
  }

  selectedMember: Member;

  constructor() { }

  ngOnInit(): void {
  }

  onSelect(member:Member): void{
    this.selectedMember = member;
  }

}

```
- HTMLファイルも作成しましょう。
`<div *ngIf="selectedMember">`はselectedMemberの存在チェックを行なっています。


```html:members.component.html
<h2>従業員一覧</h2>

<ul class="members">
  <!-- (click)はイベントバインディング -->
  <li
   *ngFor="let member of members"
   [class.selected]="member === selectedMember"
    (click)="onSelect(member)"
  >
    <span class="badge">{{member.id}}</span> {{member.name}}
  </li>
</ul>

<div *ngIf="selectedMember">
  <h2>{{selectedMember.name}}</h2>
  <div>
    <label>id:</label>{{selectedMember.id}}
  </div>
  <div>
    <label>名前:
      <!-- 双方向データバインディング -->
      <input type="text" [(ngModel)]="selectedMember.name" placeholder="名前">
    </label>
  </div>
</div>

```

こんな感じになりました。
![スクリーンショット 2022-06-16 23.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/6ffba049-1170-49b0-37a2-eeadfb8d4f73.png)
【TypeScript】関数

## function
```ts
function bmi(height: number, weight: number):number {
  return weight / (height * height)
}

console.log(bmi(1.91, 100))
```

## 無名関数
```ts
let bmi: (height: number, weight: number) => number = function(height: number, weight: number): number {
  return weight / (height * height)
}

console.log(bmi(1.91, 100))
```

## アロー関数
```ts
let bmi: (height: number, weight: number) => number = (
  height: number,
  weight: number
): number =>  weight / (height * height)

console.log(bmi(1.91, 100))
```

## オプショナルなパラメータ
```ts
// printableはオプショナル
let bmi = (height: number, weight: number, printable?: boolean): number => {
  const bmi: number = weight / (height * height)
  if (printable) {
    console.log({ bmi })
  }
  return bmi
}
// trueはなくても可
bmi(2.4, 92, true)

```

## デフォルトパラメータ
```ts
// rateのデフォルト値は1.1
const nextYearSalary = (currentSalary: number, rate: number = 1.1): number => {
  return currentSalary * rate
}

console.log(nextYearSalary(1000))
```

## 残余引数
```ts
const reducer = (accumulator: number, currentValue: number): number => {
  console.log({ accumulator, currentValue})
  return accumulator + currentValue
}

const sum: (...values: number[]) => number = (...values: number[]): number => {
  return values.reduce(reducer)
}

console.log(sum(1, 2, 3, 4, 5));
```

## オーバーロード
```ts
function double(value: number): number
function double(value: string): string

function double(value: any): any {
  console.log(typeof value)
  if (typeof value === "number") {
    return value * 2 
  } else {
    return value + value
  }
}

console.log(double(200))
// > 400
console.log(double("Foo "))
// > Foo Foo
// console.log(double(true))
// error TS2769: No overload matches this call.
// Overload 1 of 2, '(value: number): number', gave the following error.
//   Argument of type 'boolean' is not assignable to parameter of type 'number'.
// Overload 2 of 2, '(value: string): string', gave the following error.
//   Argument of type 'boolean' is not assignable to parameter of type 'string'.
```
TECH CAMP11日目　~中間テーブル~

# 中間テーブルとは
・多対多の関係性があるテーブルの間に設置するテーブル
・接続する2テーブルの外部キーをもつ

分かりやすい記事↓
https://qiita.com/ramuneru/items/db43589551dd0c00fef9


## 注意
テーブル間にアソシエーションを書く時、
例）usersテーブル、tagsテーブル、tweetsテーブルがある時、

Userモデルには
`has_many :user_tweets`
`has_many :tweets, through: :user-tweets`
の順番でかく。
`has_many through`で経由するテーブルとのアソシエーションを先に記載しないとエラーになる。
DBってどんな種類があるの？Day2

# 今日の問題
オリジナルアプリ開発のday2です。今日は要件定義の作成、DB設計をやっていました。Twitterのようなフォロー機能を作る時どのようなDB設計を作ればいいのかわからず、DB設計について調べました。今回はDBについてまとめます。

# DBは３種類ある
テックキャンプではRDB（リレーショナルデータベース）についてしか学びませんでしたが、DBは主に３種類あるそうです。


### １、階層型データベース
１つの頂点（親）が存在し、その下に複数の子供、孫が結び付けられている構造です。常に親とこの関係は「親１人対子１人」か「親１人対子多」の関係しか持てません。
![絵-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/98e7b1ef-7995-1f23-b12d-6981cc154667.jpeg)
#### メリット
・「各ノード（親や子、孫などを示している丸１つ１つのこと）へのルートが決まっているので、処理速度が早くなる」というもの。
#### デメリット
・データの追加や削除をする場合、変更が膨大になるため、柔軟性に欠けること
・子が複数の親を持つことができないため、不自然なデータが出来上がる


### ２、ネットワーク型データベース
１の階層型データベースのデメリットである「子供が複数の親を持つことができない」というデメリットを解消したものになります。どのようなDBかというと子が複数の親を持つことのでき、ネットワーク（網目）のような構造を持つDBです。
![絵-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/c62d2b3d-210b-6c76-b49b-f9d63b1954ed.jpeg)
#### メリット
階層型DBと比べ、構造が簡潔になる。
#### デメリット
各ノードが複雑に絡み合うため、一度データ構造決めると変更が難しい


### ３、リレーショナルデータベース（RDB）
現行、最優のDB構造です。上記１と２のDBはサーバー同士がインターネットで繋げられておらず、メインフレームと呼ばれる中央集権的な大型処理機が主流だった時代に利用されていたものらしいです。1970年（コッド博士）にRDBの論文が公表され、現在ではDBの８割近くがRDBを採用しているという話もあります（正確なところは不明）。構造としてはレコードとカラムで構成されているテーブルを複数つなげることでデータベースを構築するものです。
![絵-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/477debcd-7b03-3b33-1bfb-8a8dc4e8c5c1.jpeg)
#### メリット
データの構造の変更や追加が楽
#### デメリット
・プログラムが複雑化しやすい
・処理が遅くなる


## まとめ
以上３つのDB構造を見てきました。コメントに対するリプライ機能導入にあたって、複数のDBの構造を組み合わせた方がいいんじゃな以下とか悩んでいましたが、どうやらテックキャンプで学んだRDBの方法で十分対応できるようです。

## 参考文献

https://www.oracle.com/jp/technical-resources/articles/introductory-database-seminar.html

https://it-trend.jp/database/article/89-0066

https://jp.quora.com/%E9%9A%8E%E5%B1%A4%E5%9E%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9-%E8%AA%BF%E3%81%B9%E3%81%A6%E3%82%82%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%E4%BB%A5%E5%A4%96%E3%81%BB%E3%81%A8%E3%82%93%E3%81%A9
Ethersを使ってみる

## 概要

Entereum とやり取りするライブラリとして、
web3.js だけではなく最近は Ethers も人気とのことなので、使ってみました。


## プロジェクト作成、インストール

```
% node -v
v18.3.0

% mkdir hellow-eathers
% cd hellow-eathers

% npm init -y

% npm install --save ethers 
```


## Ethereum の Mainnet に接続し、block numberを取得する

```js
const { ethers } = require("ethers");

const provider = ethers.getDefaultProvider("homestead")

provider.getBlockNumber().then(console.log)
```

実行結果は次の通りとなり、執筆時点の Etherscan とほぼ一致しています。

```console
% node index.js                                                                                                                                          
14973615
```

![Screen Shot 2022-06-16 at 22.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697865/d5d7f112-9ff1-6f72-a12e-a64f40cebe8a.png)


## Ethereum Mainnet の balanceを取得する

下記のように自分のWallet Addressを指定すると現在のamountが取得できました。
```
provider.getBalance("0xXXXXXXXXXXXXXXXXXXXXXXXXX").then(console.log)
```

このタイミングで下記のようにrate limitに達した旨のメッセージが表示されました。
リンク先を見たところ、EtherscanやINFURAでAPI Keyを取得してとの記載がありました。
```
========= NOTICE =========
Request-Rate Exceeded  (this message will not be repeated)

The default API keys for each service are provided as a highly-throttled,
community resource for low-traffic projects and early prototyping.

While your application will continue to function, we highly recommended
signing up for your own API keys to improve performance, increase your
request rate/limit and enable other perks, such as metrics and advanced APIs.

For more details: https://docs.ethers.io/api-keys/
==========================
```

## まとめ

簡単ではありますが、ひとまずEthersを使ってみることをしました。
Android studioのパスを通す

## Android Studioのインストール
Android StudioのページへGO
https://developer.android.com/studio

Android Studioをダウンロード
![スクリーンショット 2022-06-16 22.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632129/45c7c289-cafb-764d-d609-85a61823fe43.png)

## 
これを試してみる。
多分今は何も表示されないはず。
```
echo $ANDROID_HOME
```

次はこれ。vimを開く。
```
vim ~/.zshenv 
```
vim上でこれを書く。書けたら保存して閉じる。
```
export ANDROID_HOME=/Users/自分のユーザーネーム/Library/Android/sdk/
export PATH=$ANDROID_HOME/platform-tools:$PATH
export PATH=$ANDROID_HOME/tools:$PATH
```
次はこれ。
```
source ~/.zshenv 
```
最後にこれ。うまくいっていればパスが表示されるはず。
```
echo $ANDROID_HOME 
```
JDKのパスを通す

## JDKをインストールする
ADOPTIUMのサイトへGO
https://adoptium.net/

最新版をダウンロード
![スクリーンショット 2022-06-16 22.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632129/064e4620-af62-4e35-4c83-4465480e7335.png)

ダウンロードしたインストーラーをクリックしてインストールを完了させる

## JDKのパスを通す
ターミナルでこれを実行してみる
多分今は実行しても何も表示されないはず

```
echo JAVA_HOME
```

次はこれ。vimを開く。
```
vim ~/.zshenv
```

vim上でこれを追記して保存。
```
export JAVA_HOME=$(/usr/libexec/java_home)
```
次はこれ。

```
source ~/.zshenv
```

echo $JAVA_HOMEでこのように表示されていればOK

```
echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk-16.jdk/Contents/Home 
```
【#2 エンジニア転職学習】ターミナル / シェル

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

学習内容は昨日投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
* 模写コーディング（昨日の続きでCSS部分を追加学習しました）
* **ターミナルとシェルについて　←Topic!!**
* おうちで学べるデータベースのきほん（隙間時間読書）

# ターミナルとシェル
本日はGitの基礎をやる予定でしたが、初期設定等していたらターミナルから操作することに気付きました。
Linuxの基本コマンドはざっくりやりましたが、**Winndowsのコマンドはほぼ触ってない**ということで急遽Windowsのコマンド操作を学習することにしました。
がその前に、ターミナルとシェルの違いやWindowsでのおすすめターミナルを調べてからにします。

何も気にせず「コマンドプロンプト」を使用していましたが、
今後のことを考えると**Windows terminal**と**Powershell**を使ったほうがいいということでした。

また、今までターミナルとシェルを一緒だと思っていたのですが、
それぞれ違うものということも学んだので簡単にまとめておきます。

### ターミナルとシェルの違い
ターミナルからシェルに命令実行をして、OSとやり取りしてもらうかたち。
「コマンドプロンプト」等はシェルにターミナルが同梱されている形のようです。
| 名称 |役割  |
|:-:|:-:|
| ターミナル  | GUIでCUI操作するときにシェルを呼び出し命令実行するソフトウェア  |
| シェル  | コマンドの集まり　OSとの対話的インターフェース  |

### Windowsでのおすすめターミナル&シェル
見た目や使いやすさからターミナルは「Windows terminal」にする。難しいがシェルは「Windows Powershell」に慣れておくのが吉のようです。
* **Windows terminal**：2020年にリリースされたWindows公式のterminal。タブ管理や見た目が綺麗で使用しやすい。私のパソコンはWindows11だったので初期からインストールされていたみたいです（今日まで知らなかった）
* **Powershell**：コマンドプロンプトに比べできる操作範囲も広いため、シェルを本格的に使用するならこっち。

# おわりに
最後までお読みいただきありがとうございました。
明日はWindows Powershellでのコマンド操作を軽くやって進めていこうと思います。
Windowsでのターミナル設定や認識についてご意見等いただけますと幸いです。