OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】SQLSTATE[42000]:1075 エラーの解消

## エラー内容

マイグレーションファイルを編集。

```php
Schema::create('items', function (Blueprint $table) {
            $table->bigIncrements('id');               //自動で連番が割り振られる
            $table->unsignedBigInteger('user_id', 20); //ここが問題
            $table->string('name', 255);
            $table->string('description', 1000);
            $table->unsignedBigInteger('category_id'); //ここが問題
            $table->integer('price', 20);              //ここが問題
            $table->string('image', 100);
            $table->timestamps();
            
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
        });
```
```
php artisan migrate
```
マイグレーションを実行させたとき


>SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key (SQL: create table items (～)


というエラーが発生。
翻訳すると

>sqlstate[42000]: 構文エラーまたはアクセス違反が発生しました。1075 テーブルの定義が正しくありません; auto 列は 1 つだけで、キーとして定義する必要があります (SQL: create table items (～).

とのこと。

## 原因調査
integerは第二引数を指定してはいけないみたい。
Laravelの仕様だそう。

### 参考文献

https://qiita.com/msht0511/items/49ca034426ad7c036e23

## 解決方法
integer型の第二引数を削除

```diff_php
Schema::create('items', function (Blueprint $table) {
            $table->bigIncrements('id');               //自動で連番が割り振られる  
-           $table->unsignedBigInteger('user_id', 20);
+           $table->unsignedBigInteger('user_id');
            $table->string('name', 255);
            $table->string('description', 1000);
-           $table->unsignedBigInteger('category_id', 20);
+           $table->unsignedBigInteger('category_id');
-           $table->integer('price', 11);
+           $table->integer('price');
            $table->string('image', 100);
            $table->timestamps();
            
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
        });
```
```
php artisan migrate
```
マイグレーションを実行させたとき
<img width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/0676861e-571d-944b-7a17-9a3bf8b7c67d.png
">
成功。

## まとめ
integer型は第二引数を設定しない


## その他
unsignedBigInteger型のデフォルト値は「20」
integer型のデフォルト値は「11」
![データ型](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/f074ec99-068f-25e2-4a20-919d255fbf20.png)
IoTシステムの全体像② 〜データ通信〜

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# IoTシステムの全体像
IoTシステムでは次のような順でデータが流れていきます。
`①データ収集 -> ②データ通信 -> ③データ可視化 -> ④データ蓄積 -> ⑤データ分析 -> ⑥データ活用`
6つの記事に渡ってそれぞれのセグメントについてまとめていきますが、この記事では「②データ通信」について記述します。

# ■IoTデバイス と インターネットの接続方法
IoTデバイスとインターネットを接続する方式としては、IoTゲートウェイ方式と直接通信方式の2種類があります。ここでは、それぞれの接続方法について説明します。

## - IoTゲートウェイ方式
IoTシステムの通信方式としては __IoTゲートウェイ方式が一般的__ で、IoTシステムでは必ずと言っていいほど、このIoTゲートウェイが使用されています。
IoTゲートウェイとは、`IoTデバイスと遠隔地にあるサーバー(クラウド)が、インターネットを介して通信を行う際に、データの中継を行う機器`のことです。IoTゲートウェイは見た目的にはルーターに似ていますが、ルーターとの大きな違いは、IoTゲートウェイが __「多種類の通信規格に対応可能」__ であるという点です。また、IoT端末で生成されたデータを、IoTゲートウェイで処理や加工を行ってからクラウドに送信することで、ネットワーク負荷を低減させたり、サーバーの容量圧迫を抑えたりすることができます。

## - 直接通信方式
直接通信方式とは、`個々のIoTデバイスに通信機能を持たせて、そのものが直接インターネットに接続する方式`のことを指します。
直接通信方式は、前述した通り個々のデバイスに通信機能を持たせることから、__構築コストが高くなりやすいだけでなく、通信負荷も高まる__ 傾向にあります。そのため、IoTシステムの通信方法としては、IoTゲートウェイ方式が一般的となっています。

# ■無線通信方式
IoTは一般的に無線通信を使用してシステムを構築するので、本記事では無線での通信方法として、LPWAについて記述します。

## - LPWA
LPWA(Low Power Wide Area)はその名の通り、`省電力かつ広範囲にデータを送信できる、IoT向けの無線通信技術`です。
では、なぜLPWAがIoTシステムにとって非常に適した通信方式なのでしょうか？
IoTシステムでは、遠隔地にIoTデバイスを配置するため、電力が確保しづらい環境にあることがあります。そのため、バッテリーでIoTデバイスを稼働させる場合があるのですが、大容量バッテリーを搭載するにはコストがかかります。そこで、__デバイスを省電力化することで、あらゆる場所で、低コストでIoTシステムを構築できる__ ようになります。
また、LPWAは3GやWi-FIと比較して低速ですが、IoTシステムでは動画のような容量が大きいデータを送信することはあまりないため、低速通信でも十分な品質を確保することができます。

# 終わりに
IoTシステムのデータ通信についてまとめましたが、前述した通りIoTシステムでは、従来のネットワークの構築とは違った特徴があります。ネットワークを構築するときは、接続するモノの特徴を捉えることが重要となります。



最後までお付き合いくださりありがとうございました。
setodaNoteCTF - Estimated 120

# 問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6b9eacbc-285c-2b96-c68a-7ec467ea400b.png)

# 解いてみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ba9e0f7a-3a83-ed2e-0d43-2db28f277783.png)


普通のブログぽい感じです。
右上に検索窓があったので、SQLインジェクションをやってみましたが、そもそも検索窓が機能していないようでした。
もう少し見てみると20210603.htmlに以下の記載がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/92563a1d-1575-afd8-88a3-0fbebe3dec96.png)

つまり1日前の6/2を見ればいいんだろうと。
20210602.htmlにアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/2958dd6b-c7ce-98cf-083d-c1beb09249fc.png)

違うんですね。
よく文章を読むと「掲載していた"画像"に」とありました。
6/3の記事に画像がないので他の記事を見て、画像のURLの流れを見ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5f5c9911-a99d-cbd9-51ec-b0a911fbf6b5.png)

7/1の記事の画像が20210710001b.jpgでした。
つまり今知りたい6/2の画像は20210602001b.jpgと予想できるので、アクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7c6758d3-dd98-2aec-c0bd-1453d8cb59d6.png)

画像ありました。
見た感じフラグなんてないんですけど、アップしてみるとありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b27f6755-e4e9-2324-d074-ee9d055810b7.png)
RTSP受信時のリアルタイム性

# RTSPの遅延時間
RTSP自体がリアルタイムとうたっているのになんのことだが、
[VANTRUE Element 1 Lite Hack](https://qiita.com/cartooh/items/0e29cc34289685d2b385)で、
RTSPをOpenCVで受け取ったとき、なぜか500msぐらいとか（ばらつきがある）遅延して、
かつ
```[h264 @ 0000026727ff1d00] error while decoding MB 18 10, bytestream -12```
とか言って、取得できなくなっていた。

何か他の方法でRTSPを受信できないかと調べていたら
[PyAV](https://pyav.org/)でも受信できることが分かった。

こちらを試したら、RTSPの名の通り、リアルタイムに受信でき(100msぐらいの遅延)、エラーが起きても次を受信続ける。まさに一石二鳥！

ただし、ログレベルを変えないと、めっちゃワーニング出るので注意。
```error while decoding MB *, bytestream *```で調べても、
そんな情報出てこないので、VANTRUEが悪いんだろうけど、RTSPをOpenCVで受信して、問題出る人はPyAVを試してみるのをすすめます。

# コード

```python
import logging
import av
import cv2

logging.basicConfig()
logging.getLogger('libav').setLevel(logging.ERROR)

container = av.open('rtsp://192.168.1.254/xxx.mov')


for frame in container.decode(video=0):
    try:
        img = frame.to_ndarray(format='bgr24')
        cv2.imshow('VIDEO', img)
        
        cv2.waitKey(1)
    except KeyboardInterrupt:
        print("KeyboardInterrupt")
        break

cv2.destroyAllWindows()
```
🔰VSCodeにPrettierを導入する🔰

# はじめに
プログラミング学習中の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。
コード整形ツールのPrettierを、機能する状態まで設定したため方法を残しておきます🙇
（インストールするだけで全く使っていませんでした、、、）

![image.png](https://soco-st.com/wp-content/themes/socost/upload/11813_color.svg)

# 結論
VSCodeにてインストール後、設定が2つ必要でした

# 設定
行っていきます！

## 0.インストール（既に入れている方は飛ばしてください）
1. VSCodeの拡張機能を開く（ショートカット：`Shift`＋`⌘`＋`X`キー）
1. 「Prettier」と検索
1. トップにヒットする「Prettier - Code formatter」をインストールする

（参考画像）
![Screen Shot 2023-02-01 at 20.59.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/aaee3cc7-fdbc-0f6d-078e-a21d47ad0860.png)

これを入れるだけで良いという訳では無かったです💦

## 1.Format On Saveを有効にする
1. VSCodeの設定を開く（ショートカット：`⌘`＋`,`キー）
1. 「Format On Save」と検索
1. `Editor: Format On Save`のチェックを付ける☑

（参考画像）
![Screen Shot 2023-02-01 at 20.50.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/5c8e928b-a22c-bd15-fc1e-41fee56316ab.png)

## 2.Default FormatterをPrettierに設定する
1. VSCodeの設定を開く（ショートカット：`⌘`＋`,`キー）
1. 「Default Formatter」と検索
1. `Editor: Default Formatter`に「Prettier - Code formatter」を選択する


（参考画像）
![Screen Shot 2023-02-01 at 20.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/dcf46bea-ec3b-c3c2-9187-69f81e15d393.png)

以上です！
これにてファイルを保存したタイミングでコードが自動で整形されるようになります！🙌🎉🎉🎉

# （おまけ）任意のタイミングで自動整形を走らせたい場合
上記設定にて、ファイル保存時の自動整形が動きますが、`shift` + `⌥` + `F`にて任意のタイミングで整形することもできるようです！

# おわりに
お読みいただきありがとうございました。
自分と同じく学習中の方の参考になれば嬉しいです。
一緒に頑張っていきましょう〜😄

# 参考
https://qiita.com/KKKKK/items/3b9dba55653cb7993bf5
ssh-agent


gitにpushしようとしたら、エラー↓がでて詰まったので備忘録ついでに、書き残します。。。

``` 
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository. 
```

# まずsshとは
- SSH（Secure Shell、セキュアシェル）というのは、通信プロトコルです。暗号化 と 認証 の仕組みを持っているため、安全な通信が可能
    - 使い道としてはターミナルを用いて、遠隔にあるサーバーにログインしコマンドを打ち込むことで、なんらかの作業ができる
- SSH でサーバーにログインするには、以下のようにログインユーザー名とログインするサーバーのホスト名を指定して、sshコマンドを実行。（ホスト名の部分は、代わりにIPアドレスを指定することもできます。）
`` ssh ログインユーザー名@ホスト名 ``

# ssh-agentとは
- sshで利用される認証方式
 - 一般的な、ユーザーID・パスワードが漏れてしまった場合は、簡単になりすましができるが、それを避けるために、交換鍵認証方式を利用することが推奨されている。
 - ssh-agent を起動して秘密鍵を登録しておけば、sshコマンドを実行した際に自動的に秘密鍵を適用して認証処理を行ってくれ、パスフレーズの入力は、秘密鍵の登録時に一度行うだけで済む
 - 公開鍵認証には以下の特徴があるため、パスワードよりも漏れる心配がかなり低く安全なのです。
     -  秘密鍵はランダムで大きめなサイズのデータになっており、予測はほぼ不可能である。
     - 秘密鍵の配置場所や、パーミッション（アクセス権限）に厳しい制限がある。
     - 認証時にはパスフレーズの入力が必要である。

# shhコマンド
| コマンド |  |
|:-:|:-:|
| ssh-add  | [秘密鍵へのパス]	秘密鍵を登録する ex) ssh-add id_rsa |
| ssh-add -l  |	登録されている鍵のFingerprints一覧を表示する  |
| ssh-add -L  | 登録されている鍵の公開鍵一覧を表示する |
| ssh-add -d  |  [秘密鍵へのパス]	登録されている鍵を削除する  |
| ssh-add -D  |  	登録されている全ての鍵を削除する 　 |
文字当てクイズ(Powershell)

文字当てクイズプログラムを**Powershell**を使って実装しました。

```Powershell
##########################
##########################
####  文字当てクイズ  #####
####  新規作成 2023/1/31##
####  修正    2023/2/1  ##
##########################


$num = 4
$i = 0
$j = 1

####正解文字列を作成する


function ans_str {
    while($true){
        $random = Get-Random -Minimum 1 -Maximum 5
        if ($random -eq 1){
            $msg = $msg + "A"
        } elseif ($random -eq 2) {
            $msg = $msg + "B"
        } elseif ($random -eq 3) {
            $msg = $msg + "C"
        } elseif ($randon -eq 4) {
            $msg = $msg + "D"
        } else {
            $msg = $msg + "C"
        }
        if($i -eq 3){
            return $msg
            break
        }
        $i += 1
    }
}


#####入力文字列作成処理
function str_input {
    while($true){
        $msg = Read-Host("A,B,C,Dの4文字を使ったアルファベット4語を入力してください")
        $flag = $msg -match '[A-D][A-D][A-D][A-D]'
        if($flag -eq "True") {
            $count = $msg.Length
            if ($count -eq $num){
                return $msg
            } else {
                Write-Host("4文字にしてください")
            }
        } else {
            Write-Host("A,B,C,D以外入力しないでください")
        }

    }
       
}


####################
#####メイン処理########
$ans_str = ans_str

##正解まで繰り返す
while($true) {
    $input_str = str_input
    if($ans_str -eq $input_str){
        Write-Host("${j}回目で文字列がそろって正解です")
        break
    } else {
        Write-Host("${j}回目、不正解です")
        $ans_array = $ans_str.ToCharArray()
        $inp_array = $input_str.ToCharArray()
        for($k=0;$k -lt $num;$k++){
            if ($ans_array[$k] -eq $inp_array[$k]){
                $p = $k + 1
                Write-Host("左から${p}文字目が正解です")
            }
        }
        $j++
    }
}
```

正解の文字までたどり着いた回数、失敗したときに左から何番目の文字が当たっているかのヒントが出ます。
**Powershell**でも簡単なゲームが実装できるのですね。
setodaNoteCTF - tkys_royale 120

# 問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6aa06d09-dd30-c1fd-e23b-649ac50e4852.png)

# 解いてみた

ソースを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/03df7f95-abaf-a2a9-54fa-e343201b5e9e.png)

```
<!-- TEST ONLY user:pass123 -->
```

と書かれているので入力してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c44b2308-d3ff-aca0-3406-19a0a8b7a999.png)

ログインはできたもののフラグはなさそうです。
ありがちなSQLインジェクションでもやってみます。

```
' or 1=1 --
```

をユーザ名に入力してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b3d24257-863d-e267-0c48-e2e5798e3019.png)

エラー画面が出たので惜しい気はしますがフラグは出ません。
パスワードにも入力してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e829114d-0d9a-e555-46f0-3c5a6d553ee6.png)

惜しい気はする。。。
このあとorをORにしてみたり、いろいろやってみたけど同じようなエラーが出るだけ。
あきらめかけたころフラグにたどり着きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a6e4a7bc-4c5e-c680-3aea-0973d7c7b45d.png)

結局のところ、最後にスペースが必要だったようです。

```
' or 1=1 --
```

ではなく

```
' or 1=1 -- 
```

です。。。
いつも後ろにスペース入れてたっけ？
久しぶりすぎて忘れてしまいました。
Kotlinのエラーハンドリング

メモです

# try-catch

```kotlin
val res = try {
    if (Random().nextBoolean()) {
        throw HogeException()
    } else {
        throw FugaException()
    }
} catch (e: HogeException) {
    
} catch (e: FugaException) {
    
} finally {
    
}

```

# runCatching

alsoがfinally相当で使えるが早期リターンが可能
Kotlin 1.5からResult型が返り値に指定できるようになった

```kotlin

val res = runCatching {
    if (Random().nextBoolean()) {
        throw HogeException()
    } else {
        throw FugaException()
    }
}.onSuccess {

}.onFailure {
    when (it) {
        is HogeException -> {

        }
        is FugaException -> {

        }
        else -> {

        }
    }
}.also {
    // ★ここが finally 相当です。（onSuccess や onFailure のブロック内で return しない限りは。）
}

```

```kotlin
fun hoge(): Result<Nothing> = runCatching {
    if (Random().nextBoolean()) {
        throw HogeException()
    } else {
        throw FugaException()
    }
}


hoge().fold(
    onFailure = {

    },
    onSuccess = {

    }
).also {
    // ★ここが finally 相当です。（onSuccess や onFailure のブロック内で return しない限りは。）
}

hoge().getOrXX()

```


# Either

Arrowライブラリ
https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/-either/
Exceptionの型を安全にできる
慣例的に右が正常値(Rightのダブルミーニングという説)
    
```kotlin

fun hoge(): Either<HogeException, Int> =
  if (Random().nextBoolean()) Either.Right(0)
  else Either.Left(HogeException())

val value = hoge()
val res = when(value) {
    is Either.Left -> when (value.value) {
        is HogeException -> {
        }
        else -> "Unknown error"
        }
    }
    is Either.Right -> {

    }
}

```

```kotlin

fun hoge(): Either<Hoge, Int> =
  Either.catch { throw HogeException() }.mapLeft { Hoge() }

if (hoge().isLeft()) {
}

```
On Demand Resourceをテストする

# On Demand Resourceをテストする

* ライブラリーをODRでダウンロードして使えるかをテスト

## 設定方法

* XcodeのProject SettingのBuild Settingsに移動し、Enable On Demand Resourcesを Yesにする。
* XcodeのProject SettingのResource Tagsタブに移動しタグを追加する。そのタグにODRにしたいAssetを追加する。

## 実装方法

```Swift
Task {
    // NSBundleResourceRequestインスタスを先作成したタグ名で生成する
    let request = NSBundleResourceRequest(tags: Set(["Tag"]))
    // ODRがすでにダウンロードされたかを確認する
    let accessible = await request.conditionallyBeginAccessingResources()
    //　ダウンロードされなかった場合、App Storeからダウンロードする
    do {
        try await request.beginAccessingResources()
    } catch {}
    // ダウンロードされている場合、すぐに使用可能
    request.bundle
}
```

## テスト方法

* 前準備：Ditribution認証書が必要。 ちゃんとした認証書（オレオレX）を使っているTLS(https)サーバーが必要。 AWS S3を使うと便利。

1. XcodeでArchiveを実行した後OrganizerでDistribution Appボタンを押す![1_step1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123134/219e6c3d-1121-53fc-17e8-23fc65cfab86.png)
2.Ad hocを選択する![2_step2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123134/6fec8590-0ee5-2ba8-c0cd-29fdc59b3c29.png)
3.On-Demand ResourceをHost on Serverに変更する![3_step3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123134/3b2b42c7-a8e0-0118-5776-aa6581716bce.png)
4.URLを入力する. App URLはAsset Pack Manifest URLは入力必須.![4_step4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123134/12b04f72-0f05-5b40-3b52-d32795cd4d05.png)
5.生成されたファイルを全部サーバーにあげる ![5_step5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123134/538bcaab-f364-93fa-e65c-da11feee39a5.png)
6.iPhoneから接続するhtmlを作って一緒にあげる
```
<html>
<a href="itms-services://?action=download-manifest&url=https://bluerain-blog.s3.ap-northeast-1.amazonaws.com/manifest.plist">App Install</a>
</html>
```
Web技術に関する用語(プロトコル、ポート番号、リクエスト、レスポンスなど)を整理

# はじめに
### 本記事を読んでほしい方
以下の内容について理解が不十分な方。この記事を読んで、理解を深めましょう。
-  プロトコル
-  ポート番号
-  リクエストとレスポンス
-  ステートフルとステートレス
-  Cookie(クッキー)

それでは早速説明していきます！

# 1. プロトコル
ネットワークに接続された機器同士が通信をするときの、決められたルールや手順のことを言います。
最も有名なものに、HTTP(HyperText Transfer Protocol)があります。HTTPはクライアント(Webブラウザ)とサーバー(Webサーバー)がWebコンテンツを送受信するためのプロトコルです。

※TCP/IPについて
インターネットサービスを実現するために、広く利用されているプロトコルの集まりをTCP/IP (Transmission Control Protocol/Internet Protocol)と言います。このTCP/IPが利用されるまでは、同じデバイスでなければ通信ができませんでしたが、TCP/IPの普及によりパソコンやスマートフォン、サーバーといった異なるデバイス間で通信ができるようになりました。

# 2. ポート番号
このポート番号というものを理解するには、まずIPアドレスについて知る必要があります。IPアドレスとは、インターネットを利用しているコンピューターについた識別番号のことです。要は、コンピューターひとつひとつに割り当てられた住所のようなものです。

ただし、IPアドレスはコンピューターを指定することはできますが、そのコンピュータが提供するサービス(アプリケーション)までは指定することができません。そこで、コンピューターが提供するサービスを指定するためにポート番号が利用されます。IPアドレスが住所だとすると、ポート番号は部屋番号のようなものですね。

# 3. リクエストとレスポンス
一般的に、Webの世界ではHTTPを使って、WebブラウザがWebサーバーにリクエストを送り、それに対してレスポンスを返すというような手順を踏みます。そのため、HTTPリクエストとHTTPレスポンスについて理解する必要があります。それぞれを以下にまとめておきます。
- HTTPリクエスト
WebブラウザがWebサーバーに対してどのような処理をして欲しいのかというリクエスト情報を伝えること。
- HTTPレスポンス
WebサーバーがWebブラウザから受け取ったHTTPリクエストを処理して、その結果をレスポンスとして応答すること。

# 4. ステートレスとステートフル
HTTPのプロトコルの特徴として、ステートレスであることが挙げられます。ステートレスなプロトコルとは、リクエストとレスポンスの1回のやりとりで完結してしまい、2回目のやりとりにその状態が引き継がれないことを言います。それに対して、1回のやり取りだけで完結せずに、2回目以降にそのやりとりの情報が反映される方式をステートフルなプロトコルと言います。

最近では、Webアプリケーションが発達し、ログイン後のユーザーの情報を反映させ続けるためにステートフルであることが望まれます。そこで考えられたのが次項で説明するCookieという技術です。

# 5. Cookie(クッキー)
Cookieとは、HTTPの仕様を拡張してWebアプリケーションとWebブラウザの間で情報を交換できるようにしたものです。Cookieの仕組みを説明します。まず、WebサーバーからWebブラウザへHTTPレスポンスの一部を利用して小さな情報を送ります。この情報がCookieです。WebサーバーからCookieを受け取ったWebブラウザは、次回同じWebサーバーへアクセスする際、HTTPリクエストにCookieを入れて送信します。Webアプリケーションが、このリクエストに入っているCookieを調べることで、アクセスしてきた相手が誰かということを調べることができるといったものです。

このCookieという技術は、ログイン情報やショッピングサイトの商品かごの情報の維持に利用されます。

# 参考文献
- [イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%B0%8F%E6%9E%97-%E6%81%AD%E5%B9%B3/dp/4797388811)
- [プロになるためのweb技術入門](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352)

# 最後に
Web技術に関する用語(プロトコル、ポート番号、リクエスト、レスポンスなど)についてお分かりいただけたでしょうか？Webアプリケーション開発において、重要な知識ばかりなので何となくでも知っておくと良いと思います。もし、不備があればご指摘いただけるとありがたく思います。最後まで読んでいただきありがとうございました！
Swift Date関連の備忘録

# **Swiftで曜日を表示する**
**yyyy/MM/dd(EEE)**
DateFormatterから曜日のフォーマットを指定して表示することができるようにする。
[Apple DateFormatter](https://developer.apple.com/documentation/foundation/dateformatter)


```swift
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd(EEE)"
let date = dateFormatter.string(from: Date())
```

冗長だけど、、、
DateFormatterから曜日を取得できることを知る前は、以下のように取得していた。
[Apple CalendarComponet](https://developer.apple.com/documentation/foundation/calendar/component)
```swift
let weekDay = Calendar.current.component(.weekday, from: Date()) - 1
switch weekDay {
case 1:
    result = "(月)"
case 2:
    result = "(火)"
case 3:
    result = "(水)"
case 4:
    result = "(木)"
case 5:
    result = "(金)"
case 6:
    result = "(土)"
case 7,0:
    result = "(日)"
default:
    result = ""
}
```


# **Swiftで月初、月末を表示する**

特定の日から、月初、月末を算出したい場合は、from: Date()の部分を置き換えれば良い。

**月初**
```swift
let calendar = Calendar(identifier: .gregorian) 
let dateComponents = calendar.dateComponents([.year, .month], from: Date())
let beginMounth = calendar.date(from: dateComponents)!
```

**月末**
```swift
let add = DateComponents(month: 1, day: -1)
let endMonth = calendar.date(byAdding: add, to: beginMounth)!
```
You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch.

```bash
Note: switching to 'v5.5.28'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at f4cba4f2 Merge branch 'master' of github.com:laravel/laravel
```

```bash
注: 「v5.5.28」に切り替えます。

あなたは「切り離された頭」の状態にあります。 あなたは周りを見回して、実験的にすることができます
変更してコミットし、この中で行ったコミットを破棄できます
ブランチに戻すことで、ブランチに影響を与えずに状態を維持します。

作成したコミットを保持するために新しいブランチを作成したい場合は、
スイッチコマンドで -c を使用して、(今または後で) そうします。 例：

   git switch -c <新しいブランチ名>

または、次のコマンドでこの操作を元に戻します:

   git スイッチ -

構成変数の advice.detachedHead を false に設定して、このアドバイスをオフにします

HEAD は現在、github.com:laravel/laravel の f4cba4f2 Merge ブランチ 'master' にあります。
```
[React]<input type='number'>のスクロールイベントを削除


`<input type='number' />`ではデフォルトの挙動ではスクロールしても何も起こらないと思いますが、スクロールに従って数値が上下するという現象に出会いました。
勝手に数値が変動するとUX的にまずい気がするのでそれを止める方法を残しときます。

# 結論
focusを外しましょう。
```typescript
<input type='number' onWheel={(e) => e.target.blur()} />
```

# これは無理
```typescript
<input type='number' onWheel={(e) => e.preventDefault()} />
```

preventDefaultでもいけそうですがエラーになります。
スクロールをはじめとするpassiveイベントはjsの完了を待っていてはUXが悪くなるのでユーザーの入力に対して制御できないみたいですね。
```js
Unable to preventDefault inside passive event listener invocation.
```

# おまけ
フォームの右に出る⇅消す方法
![スクリーンショット 2023-02-01 20.42.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/1513045f-7a83-fba7-4de8-1f24c523f238.png)

```css:global.css
input[type='number']::-webkit-outer-spin-button,
input[type='number']::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type='number'] {
  -moz-appearance: textfield;
}

```
stream peek()

peekはimediate processの途中で値を出力したりするときに使う
値を変更はしない
stream lineはeach elementについてfilter,peek,map,forEachされるイメージ

```java
public class Outer {
    public static void main(String[] args) {
        List<String> l = List.of(
                "sato-a",
                "sato-b",
                "sato-c1",
                "sato-d1"
        );
        Stream<String> s = l.stream();
        s.filter(x -> x.length() == 6).peek(System.out::println).map(x -> x.toUpperCase()).forEach(System.out::println);
    }
}
```
```
sato-a
SATO-A
sato-b
SATO-B
```
TypeScriptのletについて

letはTypeScript言語での変数宣言の一種です。 letを使用すると、変数のスコープをブロックレベル（{}で囲まれた範囲）に限定することができます。これに対して、varを使用すると関数レベルのスコープになります。このため、letは他の変数との名前衝突を避けたり、同じ名前でも異なる値を保持することができます。また、再代入も可能です。

例えば、以下のようなコードです。

```typescript
let count = 0;
count = 1;
```
上記のように、letで宣言された変数は再代入が可能です。
Databricksクラスターのコンピュートタイプ：機能比較

[Databricks cluster compute types: feature comparison \| Databricks on AWS](https://docs.databricks.com/administration-guide/account-settings/workload-types.html) [2022/11/23時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Databricksでは、それぞれが異なるタイプのワークロードに適した5つのコンピュートタイプを提供しています。

- **ジョブコンピュート:** スケーラブルかつ高信頼性の計算資源でデータエンジニアリングやMLワークロードを実行します。プロダクションワークロードで使用することを強くお勧めします。
- **汎用コンピュート:** インタラクティブなデータサイエンス、分析ワークロード向けに設計されています。
- **SQL Pro:** 高い同時実行性、低レーテンシーワークロード向けに設計された計算資源でBIや分析ワークロードを実行します。
- **サーバレスSQL:** SQL Proの全機能に加え、Databricksによって管理される最適化計算資源フリートを通じて提供される高速な起動時間とオートスケールを実現します。
- **SQL Classic:** お使いのデータレイクからタイムリーに洞察を得るために、BIレポート、分析、ビジュアライゼーションのためにSQLクエリーを実行します。

:::note
**プレビュー**
コンピュートタイプSQL Proは[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。
:::

以下の表では、それぞれのコンピュートタイプで使用できる機能を説明しています。

| 機能 | Jobs compute | All-purpose compute | SQL Pro/Serverless SQL | SQL Classic |
|:--|:--|:--|:--|:--|
| **マネージドApache Spark**: Databricksプラットフォームで提供される、アラートやリトライ機能を搭載したプロダクションジョブ実行のためのApache Sparkクラスター。  | X  | X  |   |   |
| **ジョブスケジューリング:** モニタリング機能付きのストリーミング、マルチステップジョブ、SQL、稼働ライブラリのスケジューラを含むプロダクションジョブ。 | X  |  X | X  |   |
| **オートパイロットクラスター:** 計算資源やインスタンスストレージのオートスケーリング、自動起動、Photonやスポットインスタンスの活用、クラスターの自動停止によるコスト効率の高いクラスター | X  | X  |   |   |
| **Databricks機械学習ランタイム:** Spark/Horovod連携、XGBoost、TensorFlow、PyTorch、Kerasサポート、エクスペリメント追跡、ハイパーパラメーターチューニング、AutoMLによるガラスボックスML、特徴量エンジニアリング、Databricks Feature Store、MLflowモデルレジストリを含む、アウトオブボックスのML  |  X | X  |   |   |
| **マネージドMLflow:** MLflowリモート実行、マネージドトラッキングサーバーによるエンドツーエンドのMLをシンプルにするために、Databrikcs上でMLflowを実行。また、Databricks外からMLflowを実行することも可能(利用が制限される場合あり)。 | X  | X  |   |   |
| **DeltaエンジンとDelta Lake:** 大規模なデータ分析で高パフォーマンスをサポートする、クリーンかつ高品質のデータを提供する堅牢なパイプライン。DatabricksにおけるDelta LakeはACIDトランザクション、スキーマ管理、バッチ・ストリームの読み書きのサポート、データバージョン管理、Deltaエンジンの最適化パフォーマンスを提供。  | X  | X  | X  | X  |
| **インタラクティブクラスター:** 複数ユーザーのためのハイコンカレンシーモードや分析のための堅牢なクラスター。 |   | X  |   |   |
| **ノートブックとコラボレーション:** ワンクリックの可視化、インタラクティブダッシュボード、データプロファイル、ノーコードのデータ探索、パラメーターウィジェット、実験トラッキング、改訂履歴、GitHubのようなGitプロバイダーを用いたバージョン管理連携を提供するScala、Python、SQL、Rノートブックを用いた、アナリストや同僚との高度な連携や生産性の高い作業の実現。 |   | X  |  X |   |
| **エコシステム連携:** RStudio連携や、JDBC/ODBCを通じた様々なサードパーティBIツールとの連携。 |   |  X |   |   |
| **ビジネスインテリジェンス:** SQLウェアハウスを通じた高性能、スケーラブル、完全マネージドのSQLクエリー向けPhotonエンジン。コストや信頼性の最適化オプション、ビルトインのクエリーエディター、クエリー履歴、クエリープロファイル、高信頼のデータキャッシュ、自動停止、ビルトインのダッシュボードやアラートを含む。 |   |   |  X | X  |

コンピュートタイプごとの価格に関しては、[AWS Pricing](https://databricks.com/jp/product/aws-pricing)をご覧ください。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Collectors#partitioningBy(), groupingBy()

groupingBy()はgrouping keyとなるものをFunctionとして指定
Map(key, List)をreturnする。
partitioningBy()はtrue/false conditionとなるものをPredicateとして指定
Map(key, List)をreturnする。
Collectorをsecond argumentに追加すると、Listに対してさらに処理してくれる。

```java
class SampleClass {
    String name;
    int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SampleClass(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "name:" + name + ", price=" + price;
    }
}
public class Outer {
    public static void main(String[] args) {
        List<SampleClass> l = List.of(
            new SampleClass("sato-a",100),
            new SampleClass("sato-a",200),
            new SampleClass("sato-b1",300),
            new SampleClass("sato-b1",400)
        );
        Stream<SampleClass> s = l.stream();
        Map<String, Integer> mp = s.collect(Collectors.groupingBy(SampleClass::getName, Collectors.summingInt(SampleClass::getPrice)));
        System.out.println(mp);
        s = l.stream();
        Map<String, List<SampleClass>> mp3 = s.collect(Collectors.groupingBy(SampleClass::getName));
        System.out.println(mp3);
        s = l.stream();
        Map<Boolean, List<SampleClass>> mp2 = s.collect(Collectors.partitioningBy(x -> x.getName().length() == 6));
        System.out.println(mp2);
    }
}
```
```
{sato-a=300, sato-b1=700}
{sato-a=[name:sato-a, price=100, name:sato-a, price=200], sato-b1=[name:sato-b1, price=300, name:sato-b1, price=400]}
{false=[name:sato-b1, price=300, name:sato-b1, price=400], true=[name:sato-a, price=100, name:sato-a, price=200]}
```
Ruby on Rails チュートリアル　非ログインユーザーからのプロフィールページへのアクセスを防ぐ

Ruby on Rails　チュートリアル（第7版)を1周走破しましたが、個人的に気になる点があったので修正してみました。

気になる点とは、
”非ログインユーザーが、登録済みユーザーのプロフィールページにアクセスできる”点です。
（プロフィール編集ページにはアクセスできないため、問題ないのでしょうか？）

/users/(id)　リクエストを送信すると、非ログインユーザーでもアクセス可能でした。

この操作を行っている箇所を探します。

```ruby:users_controller.rb
  def show
    @user = User.find(params[:id])
    redirect_to root_url and return unless @user.activated?
    @microposts = @user.microposts.paginate(page: params[:page])
  end
```

showアクションでプロフィールページが表示されています。
この前にログイン確認をしたいので、

```ruby:users_controller.rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
                                        :following, :followers]
.
.
.
end
```

logged_in_userメソッド（ログイン確認）をshowアクション前にも行うようにします。

before_action :logged_in_user に :show を追加

```ruby:users_controller.rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :show, :edit, :update, :destroy,
                                        :following, :followers]
.
.
.
end
```

これで非ログインユーザーが、登録済みユーザーのプロフィールページにアクセスすると、
ログインページにリダイレクトされるようになりました。
![スクリーンショット 2023-02-01 20.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2881997/314d6a3b-6efd-69ae-8b0f-d5d45c25424f.png)
SwiftUIを使ってアイコンを爆速で作成する

## この記事の狙い
デザインツールを使わないでSwiftUIのみでアイコン(ボタン)を作成する試みです。[^1]
以下のような未来の職場風景を想像しています。

| 今まで |  これから  |
|:----:|:----------:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/c6ffa12b-ae84-8dc3-52ad-9af91899f98b.png" width=256> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/fb62e772-ddfb-c8a6-9b70-80149cfbf48a.png" width=128> |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/5ccebf7b-e450-8cb5-4220-34676b7aeb7b.png" width=720>

デザイナーと開発者がペアプロする。

## 完成イメージ
翻訳機能を呼び出すためのボタンを想定しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/5198cd0c-6eb4-54ff-a1a2-bc7fd0c330a8.png" width=178>

## アイコンの構成

### ベース
アイコンのベースとなる`Rectangle()`を用意します。
```Swift
// 簡易コードです。
Rectangle()
    .foregroundColor(Color.clear)
    .frame(width: 44, height: 44)
    .overlay {
        ZStack {
           下レイヤー
               .mask {
                   マスク
               }
           上レイヤー
        }
    }
```

### 上レイヤー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/ec0c3133-d196-2599-04ab-2fc1788224ae.png" width=144>

右下に`A`を表示するだけです。

```Swift
// 簡易コードです。
Text("A")
    .font(.system(size: 32,
                  design: .rounded))
    .position(x: /* ベースの右端 */,
              y: /* ベースの中央 */)
    .offset(x: /* 基準位置からの補正値 */,
            y: /* 基準位置からの補正値 */)
```


### 下レイヤー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/44dc1872-99c1-ed7d-11fc-69f06999dca2.png" width=144>

左上に`文`を表示しますが、上レイヤーの`A`と重ならないように一部をマスクします。

```Swift
// 簡易コードです。
Text("文")
    .font(.system(size: 24,
                  weight: .bold,
                  design: .rounded))
    .position(x: /* ベースの左端 */,
              y: /* ベースの中央 */)
    .offset(x: /* 基準位置からの補正値 */,
            y: /* 基準位置からの補正値 */)
    .mask {
        // 以下で説明
    }
```


### マスク
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/22d5570c-dae2-f7d3-5993-0df2fd7bb9ce.png" width=144>


上レイヤーの`A`より一回り大きい`A`型のマスクを作成します。
SwiftUIに袋文字のAPIがあれば一発だったのですが、今のところ無いので、`A`を8方向へずらしてマスクとします。
**マスクされた部分を消したい**ので`blendMode(.destinationOut)`でリバースマスクにします。

```Swift
// 簡易コードです。
Rectangle()
    .frame(width: 44, height: 44)
    .overlay {
        ZStack {
            Text("A").offset(/* 左上にずらす */)
            Text("A").offset(/*   上にずらす */)
            Text("A").offset(/* 右上にずらす */)
            Text("A").offset(/*   左にずらす */)
            Text("A").offset(/*   右にずらす */)
            Text("A").offset(/* 左下にずらす */)
            Text("A").offset(/*   下にずらす */)
            Text("A").offset(/* 右下にずらす */)
        }
        .blendMode(.destinationOut)
    }
```

## コード
GitHubに全コードを置いています。

https://github.com/hackenbacker/SwiftUI-icon-design-demo.git


## まとめ
デザインツールを使わなくても、コードのみで素早くアイコン作成ができました。(1h未満)

以下のようなケースならすぐに導入できそうです。
* 小規模：個人開発やプロトタイプなど。
* 短期間：動く物がすぐにほしい。
* 低予算：FigmaやIllustratorを導入するのは、ちょっと。。

SwiftUIの可能性を感じていただけたなら幸いです。:relaxed:

## 開発環境
* Xcode 14.2
* Swift 5.7.2
* iOS 16.2

[^1]: **Creation as Code** と命名したい。
Fedora 37でVSCodeを使う & mac風日本語入力

# Fedora 37 にvscodeをインストールする

## 参考ページ

https://code.visualstudio.com/docs/setup/linux

## 行ったこと

上のページにあるFedoraの項目のコマンドを実効。

レポジトリとキーの追加。

``` Bash
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'
```

アップデートとVSCodeのインストール。

``` Bash
dnf check-update
sudo dnf install code
```

# ibus-anthyの設定

## mac風な日本語入力の切り替え

変換でひらがな入力、無変換でローマ字入力にしたい。

設定としてはGUIで行った。

右上にあとか_Aとかあるので、そこから「設定 - Anthy」をクリック。

開いたウィンドウでキー割り当てのタブのコマンドとキーの割り当てから設定を行った。

latin_modeにMuhenkan、hiragana_modeにHenkanを割り当てた。
【PHP】CSVファイルのBOMを削除する方法

PHP（Laravel）のシステムにUTF-8形式のCSVファイルをアップロードする際、BOMを削除する方法です。

BOM付きの場合とBOM付きでない場合、両方に対応する必要がありました。



## 解決策

```php:
$text = preg_replace("/^\xEF\xBB\xBF/", '', $text);
```

## 参考：BOMとは

- Byte Order Markの略
- テキストの先頭に付く
- CSVファイルを保存する際、Excelのバージョンや保存形式により、BOMが付く場合と付かない場合がある
- 16進法で「EF BB BF」と表される
- 「ファイルがUnicodeで書かれているか」や「[エンディアン](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3)の形式」を判別するために付いている（※ただし、UTF-8ではエンディアンは関係ない）



## 余談：`�`について

UTF-8の状態でデバッグした際、BOMは`�`と出力されていました。
（ex.`'日付'`の場合、`'�日付'`)

>これは代替文字（REPLACEMENT CHARACTER）と呼ばれるもの。

> UTF-8だと U+FFFD とされる文字であり、他の文字コードからUTF-8に置き換えたときに該当する文字がないときなどに使用される

[参考サイト](https://shinkufencer.hateblo.jp/entry/2019/04/05/233000)より

## 参考サイト

https://doroidpanic.com/php%E3%81%A7bom%E3%82%92%E5%89%8A%E9%99%A4-remove-xefxbbxbf-ufeff-efbbbf/

https://www.php.net/manual/ja/function.preg-replace.php

https://shinkufencer.hateblo.jp/entry/2019/04/05/233000

https://learningbox.online/2021/06/18/blog_csv-bom-utf8/

https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3

https://nyanblog2222.com/windows/4659/
Pythonチートシート - Tuple型の使い方一覧

仕事や学習の時に役立つちょっとしたチートシートを作ってみることにしました。今回はリスト、ディクショナリーに次いで使うタプルの使い方をまとめてみました。

## タプルについて
listと違い、tupleは読み取り専用のコレクション(イミュータブル)となっています。変更したくない値を格納して参照のみとしたい場合は、tupleを使うのが効果的です。また処理の過程でタプルにしたコレクションをリスト・ディクショナリー等に変えたい時に使います。

### タプルの内容を参照する(スライス、len)
```python
tuple01 = (1,2,3)
print(tuple01)

# インデックス指定で参照する方法
tuple02 = (10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
print(tuple02[0])
print(tuple02[2:5])
print(tuple02[-1])
print(tuple02[-5:-1])

# 要素数を取得
print(len(tuple02))
```
```python
(1, 2, 3)
10
(30, 40, 50)
100
(60, 70, 80, 90)
10
```

### タプルをネスト化する
```python
tuple_nest = (('01', '02'), ('03', '04')) 

print(tuple_nest[0]) 
print(tuple_nest[1]) 

print(tuple_nest[0][0]) 
print(tuple_nest[0][1]) 
print(tuple_nest[1][0]) 
print(tuple_nest[1][1])
```
```python
('01', '02')
('03', '04')
01
02
03
04
```

### タプルを演算する
```python
# タプルを結合する
t01 = ('elen', 'mikasa', 'armin')
t02 = t01 + ('jean', 'sasha')
print(t02)

# タプルを繰り返しにする
t03 = ('liberty', 'equality', 'fraternity') * 3
print(t03)
```
```python
('elen', 'mikasa', 'armin', 'jean', 'sasha')
('liberty', 'equality', 'fraternity', 'liberty', 'equality', 'fraternity', 'liberty', 'equality', 'fraternity')
```

### タプルの参照に用いるメソッド(index, count, in演算子)
index - 指定した要素が何番目にあるかを取得
count - 指定した要素が何個あるかを取得
in演算子 - 指定した要素がタプルにあるかを判定
```python
print(t01.index("Python"))
print(t01.count("C#"))
print("Java" in t01)
```
```python
1
2
True
```

### タプルの並び替え、最大値と最小値(max, min, sorted)
```python
t01 = (4,1,9,3,8,9,5)

print(max(t01))
print(min(t01))

print(sorted(t01))
print(sorted(t01, reverse=True))
```
```python
9
1
[1, 3, 4, 5, 8, 9, 9]
[9, 9, 8, 5, 4, 3, 1]

```
### リスト、文字列をタプルに変換(tuple)
```python
l = ['a', 'b', 'c']
s = 'python'

ltoTuple = tuple(l)
stoTuple = tuple(s)

print(ltoTuple)
print(stoTuple)
```
```python
('a', 'b', 'c')
('p', 'y', 't', 'h', 'o', 'n')
```
JavaのMapを値(int)でソートする

Mapを値の降順で出力したかったのだけど、
調べてもよく分からないAPIを利用する方法しか見つからなかったので、
普通の制御文だけでソートするコードを書きました。

```Main.java
//キーはString、値はint
Map<String, Integer> map = new HashMap<String, Integer>();

//中身の格納は省略

//値の最大値と最小値を求める
int max_v=-2_147_483_648;
int min_v=2_147_483_647;
for(String key:map.keySet()) {
	max_v=Math.max(max_v, map.get(key));
	min_v=Math.min(min_v, map.get(key));
}

//最大値から最小値まで降順に総当たりしてヒットしたら出力
int i=max_v;
while(i>=min_v) {
	for(String key:map.keySet()) {
		if(map.get(key)==i) {
			System.out.println(key+" "+map.get(key));
		}
	}
	i--;
}	
```
paizaの「文字と整数の組のソート2」は一応これで通りました。
https://paiza.jp/works/mondai/prob60/sort_add_9
System.out.printlnの代わりに
LinkedHashMapに格納しても便利かもしれない。
値がfloatだと普通に使えないですが……。
法務省登記所備付地図データをマージする

2023年1月23日に[法務省登記所備付地図データ](https://front.geospatial.jp/houmu-chiseki/)が公開されました。しかし、ダウンロードに時間がかかったり、XML形式のファイルをコンバートする手間などがあり、少し使いにくいものです。
ですが、北海道分のデータに関しては北海道庁の喜多耕一さんがGeojsonに変換したものをGitHubにアップロードして公開してくれました（[登記所備付地図（Geojson）のダウンロード](https://koukita.github.io/touki_map_hokkaido/index_link.html?fbclid=IwAR0QTgV2eM-y2Pdyc1tgpufsNHvjO5TpnvlCU4_pPMNprYYDuCDg36Vv-LA)）。
せっかくのデータですので、使い倒していきたいと思います。

## 地番データは細かい領域に分かれている
ダウンロードしたGeojsonは小さな領域に分割されています（厚沢部町は36の領域に分割されていました）。このままQGISに読み込んでもきちんと表示されるのですが、このままでは少し具合が悪いので、Rを利用して一つのファイルに結合します。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/da809cd5-8e4f-24dd-095e-e8376e13cbc2.png)

## データをマージする
`tidyverse`と`sf`パッケージを使います
```R
library(tidyverse)
library(sf)
```

データを読み込みつつ結合していきます。
```R
# read data
map <-
  # geojsonファイルをリスト化する
  list.files(path = "data/",  # データの格納されているディレクトリを指定  
           pattern = ".geojson",  # 「.geojson」が含まれるファイルを検索
           full.names = T) %>% # ファイル名をフルパスで取得
  # map関数で、リスト化されたデータにそれぞれst_readを適用 
  purrr::map(sf::st_read) %>%
  # geojsonファイルを結合
  dplyr::bind_rows() %>%
　 # 座標系をJGD2000UTMzone54に変換（オリジナルはJGD2011の緯度経度系）
  sf::st_transform(3100) %>%
  # 必要なデータ項目だけを残す
  dplyr::select(市区町村名, 大字名, 丁目名, 小字名, 地番)
```
データの中身はこんな感じです。
```R
>map
Simple feature collection with 33550 features and 5 fields (with 395 geometries empty)
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -1358599 ymin: 4630667 xmax: 8537937 ymax: 17948300
Projected CRS: JGD2000 / UTM zone 54N
First 10 features:
       市区町村名 大字名 丁目名 小字名 地番                       geometry
1  檜山郡厚沢部町   <NA>   <NA> 字峠下    1 MULTIPOLYGON (((449812.8 46...
2  檜山郡厚沢部町   <NA>   <NA> 字峠下    2 MULTIPOLYGON (((449809 4644...
3  檜山郡厚沢部町   <NA>   <NA> 字峠下    3 MULTIPOLYGON (((449817.8 46...
4  檜山郡厚沢部町   <NA>   <NA> 字峠下    4 MULTIPOLYGON (((449838.6 46...
5  檜山郡厚沢部町   <NA>   <NA> 字峠下    6 MULTIPOLYGON (((450081.3 46...
6  檜山郡厚沢部町   <NA>   <NA> 字峠下    7 MULTIPOLYGON (((449854.8 46...
7  檜山郡厚沢部町   <NA>   <NA> 字峠下    8 MULTIPOLYGON (((449849.2 46...
8  檜山郡厚沢部町   <NA>   <NA> 字峠下   11 MULTIPOLYGON (((449869.7 46...
9  檜山郡厚沢部町   <NA>   <NA> 字峠下 13-1 MULTIPOLYGON (((450816.7 46...
10 檜山郡厚沢部町   <NA>   <NA> 字峠下 13-2 MULTIPOLYGON (((450799 4644...
```

`mapview()`関数で表示してみます。
```R
library(mapview)
mapview(map)
```
うまく結合できているようです。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/8dc284a8-896c-0358-ecd5-07408b5f9ba0.png)

## データを書き出す
うまくデータを結合できたので書き出します。
```R
# write data
  sf::st_write(
    obj = map,
    driver = "GPKG",
    append = FALSE ,
    "output/01363_JGD2000utm54.gpkg")  
```
QGISで読み込むとうまく表示されました。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/5c78b446-cff3-8774-99b3-2c3678fa7da5.png)

## まとめ
結合された地番データは様々な使いみちが考えられます。次回は地番データをりようした郷土研究への活用事例を紹介します。
Salesforce レコードトリガーフローをデバッグする

# 概要

- Salesforce(以後SFと呼称)のレコードトリガーフローをデバックする方法を簡単にまとめる。

# 情報

- 諸事情でスクショを載せられないので文書ベースのメモ的な記載で失礼する。

# 方法

1. デバッグしたいフローをフロービルダーで開く。
1. 上部の「デバッグ」をクリック
1. 特に設定はいじらず、トリガレコードのみプルダウンで選択し「実行」をクリック
1. 右サイドバーの「デバックの詳細」の「インタビューの開始方法」や「開始条件の要件」を確認すると情報が見れる。

# 参考文献

https://help.salesforce.com/s/articleView?id=sf.flow_test_debug.htm&type=5
【2023】motoのmock_dynamodb2は使えませんよという話

# mock_dynamodb2使えない
Pythonの単体テストにおいて、dynamodbをモックする場合、[moto](https://github.com/getmoto/moto)を使用している記事がたくさん見つかります。
これらの記事を見てみると
`mock_dynamodb`は古いので`mock_dynamodb2`を使いましょうと書かれていますが、
2023年2月現在、最新バージョンのmoto4.11では`mock_dynamodb2`は使用できず

```python
from moto import mock_dynamodb2
```
としても`ImportError`になります。

現在の`moto`のソース↓を見てみると`moto/__init_.py`に`mock_dynamodb2`はありません。
https://github.com/getmoto/moto/blob/master/moto/__init__.py#L60

では、いつ頃変更されたのかというと、2022年8月16日にマージされたプルリクエストで`mock_dynamo2`が削除されていることがわかり、バージョン4.00から反映されているようです。
https://github.com/getmoto/moto/pull/5383/files#diff-d19bb31311354ef2f3edec922b8ad8820cc476ba365d5c40bbf3927bd3bf410cL80

## まとめ
ということで、motoを使ってdynamodbを使用する際はバージョンが4.00以降か、参照している記事が2022/08より新しいかの2点に気をつける必要がありそうです。
C#でクラスライブラリのDLLをビルド後イベントで自動配布する

# 1. はじめに

* C#のクラスライブラリで作成したDLLを別プロジェクトへコピーしたい
* プロジェクトのビルド後のイベントで自動的にコピーしたい



# 2. 実行環境
* 統合開発環境: Visual Studio 2022
* 下記フォルダ構成のClassLibraryプロジェクトで作成したDLLを、Clientプロジェクトへコピーする

```
├─class-library : クラスライブラリのGitリポジトリー
│  └─ClassLibrary : クラスライブラリのプロジェクト
│      ├─bin
│      │  └─Debug
│      │      └─net6.0-windows ←　コピー元
│      └─Util
└─client : クライアントのGitリポジトリー
   └─Client : クラスライブラリのプロジェクト
       ├─bin
       │  └─Debug
       │      └─net6.0-windows ←　コピー先
       └─View
```



# 3.  プロジェクトのビルド設定

* プロジェクトを右クリックして、```プロパティ```を選択する
* ```ビルド``` > ```イベント``` >  ```ビルド後のイベント``` に下記を追記する

```xcopy /s /y /d $(ProjectDir)bin\$(Configuration)\net6.0-windows\* $(ProjectDir)..\..\client\Client\bin\$(Configuration)\net6.0-windows```

| マクロ               | 説明                                                         |
| -------------------- | ------------------------------------------------------------ |
| $(ProjectDir)        | プロジェクトのディレクトリ (ドライブとパスで定義)。最後に円記号 (\) が含まれます |
| $(ConfigurationName) | 現在のプロジェクト構成の名前 ("Debug" など)                  |

* ```ビルド後のイベントをいつ実行するか``` に　```ビルドに成功したとき``` を選択する

# 4. xcopyコマンド

* 今回ビルド後のイベントで使用した部分を中心にコマンドの内容を記載する

## 4.1. コマンド説明

ディレクトリごとファイルをコピーする。隠し属性やシステム属性ファイルなどをそのままコピーすることが可能。ワイルドカードの使用もできる。



## 4.2. コマンド形式

``` xcopy <Source> [<Destination>] [/w] [/p] [/c] [/v] [/q] [/f] [/l] [/g] [/d [:MM-DD-YYYY]] [/u] [/i] [/s [/e]] [/t] [/k] [/r] [/h] [{/a | /m}] [/n] [/o] [/x] [/exclude:FileName1[+[FileName2]][+[FileName3]]] [{/y | /-y}] [/z] [/b] [/j] [/compress]```



## 4.3 コマンドオプション

| オプション | 説明                                                         |
| ---------- | ------------------------------------------------------------ |
| /s         | 空の場合を除き、ディレクトリとサブディレクトリをコピーします |
| /y         | 既存の宛先ファイルを上書きするかどうかを確認するプロンプトを抑制します |
| /d         | 既存の "宛先" ファイルよりも新しいすべての "ソース" ファイルをコピーします |



# 5. 動作確認

* ビルドを実行する毎に自動で別プロジェクトへDLLがコピーされることを確認した



# 6. 参考文献

https://learn.microsoft.com/ja-jp/visualstudio/ide/reference/pre-build-event-post-build-event-command-line-dialog-box?view=vs-2022
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/xcopy
Chrome拡張機能の右クリックメニューが、ページの背景以外で右クリックしても表示されるようにする。

# 前置き

chrome拡張機能を開発する際、`manifest` の `permissions` に `contextMenus` を追加し、

```json:manifest.json
{
    ...
    "permissions": [..., "contextMenus"]
}
```

スクリプトで

```js:*.js
chrome.runtime.onInstalled.addListener(() => {
    chrome.contextMenus.create({
        id: "parent",
        title: "サンプルのメニュー項目",
    });
});
```

とすれば右クリックメニューを追加できますが、ウェブページの背景で右クリックしたときのみ表示されます。

では、例えば画像などをクリックしたときに表示されるようにするにはどうすればよいのでしょうか？

# 解説

`chrome.contextMenus.create` する際の引数に `contexts: ["image"]` を追加すればよいです。

```js:*.js
chrome.runtime.onInstalled.addListener(() => {
    chrome.contextMenus.create({
        id: "parent",
        title: "サンプルのメニュー項目",
        contexts: ["image"]
    });
});
```

使える ContextType は以下のとおりです。

```js
"all"
"page"
"frame"
"selection"
"link"
"editable"
"image"
"video"
"audio"
"launcher"
"browser_action"
"page_action"
"action"
```

# あとがき

https://developer.chrome.com/docs/extensions/reference/contextMenus/#type-ItemType

↑このドキュメントを読めばすぐに分かることですが、日本語で解説したページが見当たらなかったため記事にしました。

### おまけ

このノートの主題ではないですが右クリックしたときにスクリプトを実行するにはこうです。

```js:*.js
chrome.contextMenus.onClicked.addListener((item) => {
    /** いずれかのメニュー項目がクリックされたときに実行される関数 **/
});
```

`contextType` が `image` のときの `items` の構造

```js:
{
    "editable": false,
    "frameId": 0,
    "mediaType": "image",
    "menuItemId": "parent",
    "pageUrl": "https://example.com/example.html",
    "srcUrl": "https://example.com/images/example.jpg"
}
```
Dockerでdynamodb環境を作りたい

# はじめに
業務でmysqlからdynamodbに移行することになり、dynamodbの環境構築について学びました。
他に記事がありましたが、個人的に学んだ箇所も踏まえて簡単にまとめてみます

# ファイル
公式にymlのテンプレートがありました

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html

```docker-compose.yml
services:
  dynamodb-local-hoge:
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-local-hoge
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal

  dynamodb-admin-hoge:
    container_name: dynamodb-admin-hoge
    image: aaronshaf/dynamodb-admin:latest
    environment:
      DYNAMO_ENDPOINT: ${DYNAMO_ENDPOINT}
    ports:
      - "8001:8001"
    depends_on:
      - dynamodb-local-hoge
```

```.env
DYNAMO_ENDPOINT=dynamodb-local-hoge:8000
```

今回はaws cli用とgui用でコンテナを2つ立てています。
cli用(dynamodb-local-hoge)が8000番ポート、gui用(dynamodb-admin-hoge)が8001番ポートです。
gui用からcli用にアクセスするためにDYNAMO_ENDPOINTという環境変数でcli用のポート番号を指定しています。


上の2ファイルを同階層に作成し、コンテナを立ち上げます
```
$ docker-compose up
```

まずテーブルを作成するコマンドをコンソールで実行してみます。
```
aws dynamodb \
  --region ap-northeast-1 \
  --endpoint-url http://localhost:8000 \
    create-table \
  --table-name HogeTable \
  --attribute-definitions \
    AttributeName=userId,AttributeType=N \
    AttributeName=userName,AttributeType=S \
  --key-schema \
    AttributeName=userId,KeyType=HASH AttributeName=userName,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST
```

コンソール上ではこのような表示がされました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/626f793d-f6d4-ee91-2408-abf8624bb72d.png)

localhost:8001にアクセスすると、テーブルが作成できています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/a197756e-dfea-cb15-2c8f-da4a29aff60c.png)

次にテーブルにレコードを挿入します

```
aws dynamodb \
  --region ap-northeast-1 \
  --endpoint-url http://localhost:8000 \
    put-item \
  --table-name HogeTable \
  --item '
    {
      "userId": {
        "N": "1"
       },
      "userName": {
        "S": "ほげ太郎"
      }
    }
  '
```

GUIからレコードを確認することができました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/3d3d59db-d1a2-6e98-8313-391ba072c2cf.png)


# おわりに
mysqlを導入していた際はguiを使用していなかったので、gui用のパッケージを使ったコンテナからlocalにアクセスするやり方を初めて知りました。
db操作のコマンドもmysqlと違うので慣れていきたいです。

# 参考

https://qiita.com/kiyo27/items/6b135907dccfbb37ff36

https://zenn.dev/nameless_gyoza/articles/c49a6eddc46b90cb7a7d
Day.jsで日付データから指定したフォーマットの文字列を取得する

今まで日付取得のモジュールを使用せずに長ったらしく書いていたため、  
短縮するためのモジュール紹介兼、自分用の備忘録として記載します。

これまでコンソールログなりWebページ上での表示なり、日時を取得する際に記載したコードは以下の通り。

```javascript:before.js
 const today = new Date();
 const week = ["日", "月", "火", "水", "木", "金", "土"];
 const year = today.getFullYear();
 const month = today.getMonth() + 1; // 1月~12月 -> 0~11
 const date = today.getDate();
 const day = today.getDay();
 const hour = today.getHours();
 const minute = today.getMinutes();
 if (hour < 10) hour = "0" + hour
 if (minute < 10) minute = "0" + minute;
 const textmessage = year + "年" +
     month + "月" + date + "日(" + week[day] + ")" +
     " " + hour + "時" + minute + "分"

/**結果は投稿日を例にすると
 2023年2月1日(水) 08時05分 と返ってきます。
*/
```
取得している内容はわかりやすいものの、
日時を取得して表示するのに10行もコードを記載することになり、
これだけでかなりの時間を要してしまいます。
ただこれだけの内容をモジュールひとつのインストール・インポートで、  
2・3行に短縮することが可能です。  
以降に扱い方について記載いたします。

### インポートの仕方

ターミナルorコマンドプロンプト上でインポートしたいファイルに移動し、下記のコマンドを実行してください。
```
yarn add dayjs
```

### 実際の記載方法  
ログで確認する場合
```javascript:after.js
const dayjs = require('dayjs');
dayjs.locale('ja');
```
1行目でインポートしたdayjsを読み込み、
2行目で時刻と曜日の表示を日本基準に変更します。  
```javascript:after.js
console.log(`現在時刻：${dayjs().format('YYYY年M月D日(ddd) HH時mm分')}`);
```
でコンソールのログにて確認できます。  
 
今回の場合ですと、  
>現在時刻：2023年2月1日(水) 08時05分

とログにて表示されます。

因みに、『format』以降の内に記載されている内容ですが、 
ここでは表示する形式を指定することができます。  
[公式ページ](https://day.js.org/docs/en/installation/installation)をご確認ください。
またこれ以外にも表示形式や日付の加算減算等ができますのでお試しあれ。