OmniAICreator/Qiita-1.07M huggingface dataset:
AndroidTVでインジケーターを実装

# はじめに
初めましての方ははじめまして。

最近仕事でAndroidTVアプリの開発をすることが増えてきたので備忘録です。
AndroidTV(またはFireTV)はAndroidと違ってリモコンを用いて操作するので特有のUIになります。
トレイアートを横に並べるデザインが主流ですのでインジケーター等で視認性を上げる必要があります。

# 実装方法
いくつかあり、RecyclerViewで並べたりfor文で並べたり[jetpack Compose](https://developer.android.com/jetpack/androidx/releases/tv?hl=ja)を用いたりと実装方法自体はAndroidと変わりません。

今回はわかりやすさも兼ねてfor文で紹介します。

# 実装


レイアウトファイルにインジケーターの挿入位置を決めます。
```xml
<LinearLayout
                android:id="@+id/indicator"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="@dimen/masthead_content_margin_end"
                android:gravity="end"
                android:orientation="vertical"
                app:layout_constraintBottom_toBottomOf="@id/space_masthead"
                app:layout_constraintStart_toStartOf="@id/linear_layout">

                <LinearLayout
                    android:id="@+id/indicator_container"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal" >

                </LinearLayout>

            </LinearLayout>
```
`indicator`がインジケーターの位置、`indicator_container`が１つ１つのインジケーターになります。

それではインジケーターを追加していきます。

```java
indicatorView = findViewById(R.id.indicator_container);

for(int i = 0; i < "表示したい数"; i++) {
    ImageView indicator = new ImageView(this);
    indicator.setId(i);
    indicator.setFocusable(true);
    indicator.setOnFocusChangeListner(new view.OnFocusChangeListner() {
        @Override
        public void onFocusChange(View view, boolean isFocused) {
            if(isFocused) {
                view.setBackGroundResource("フォーカス時のインジケーター");
            } else {
        view.setBackGroundResource("非フォーカス時のインジケーター");
            }   
        }
    });
    indicatorView.addView(indicator)
}

```


ざっくり言えばindicator_containerを表示させたい数だけaddViewするだけです。

インジケーター自体はImageViewなどで作成し、AndroidTVはリモコンを使った操作をするのでフォーカスされるような場合は`setFocusable`を`true`としておきましょう。

そしてフォーカスされる場合、フォーカスされたときとされていない時の見分けがつかないとユーザーが迷子になってしまうので色を変えるなり、デザインを変えるなりを`onFocusChangeListner`で行います。

最後に上記で設定した要素を持ったindicatorをaddViewすれば完成です。


ご覧いただきありがとうございました。
Googleプロジェクト管理：バーンダウンチャート

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

スクラムチームがスプリントとプロダクトバックログ全体の進捗に合わせて作業を管理するための、2つの非常に重要な概念があります。

その2つの概念とは、
- バーンダウンチャート
- ベロシティ

です。

今回、バーンダウンチャートをご紹介します。

# バーンダウンチャート

バーンダウンチャートは、作業量と残作業量に対して時間を測定します。

バーンダウンチャートを使う目的は、***<font color="MediumBlue">チームが全体のゴールに対してどのように取り組んでいるか</font>*** を意識し続けることです。

スクラムチームでは、バーンダウンチャートは、チームがスプリント中にユーザーストーリーを完成させるためにどのように行っているかを反映します。

スクラムマスターは、チームがゴールに到達するかどうかを調べるために、時には毎日、バーンダウンチャートを見直すことになります。

# バーンダウンチャートを使って、スプリントの進捗状況を把握する

スプリント期間が4週間で、20営業日としてカウントされると仮定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/cbef66e0-5ef8-1b6f-cf11-6e5ca10b772c.png" width="600">

- 7月のスプリントでは、スプリントバックログに合計200ポイントの完了すべきストーリーがありました。
- もし、営業日数で均等にポイントを消費すると仮定すると、毎日10ポイントずつ消費することになります。
- スプリントの5日目までに、22のポイントが完了しました。まだ25％だから、順調なのかもしれない。
- 10日目には、45ポイントを完了しました。バーンダウンチャートによると、スプリントゴールからすると、遅れていることになる。今は、パニックになってチームにストレスを与えている場合ではありません。

この時点で、スクラムマスターは、すでにチームと話し合い、どうすれば彼らを助け、ブロックを解除できるかを見つけ出しているはずです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/253d611a-d71e-1842-69c8-0c47a7187859.png" width="600">

- 15日目までに、バーンダウンは140ポイントになりました。ふぅー! チームは再び活気を取り戻しています。
ラズパイ環境作成

# これは何？

ラズパイ環境作成時にやることを忘れないように備忘録。

# やること

## imager で microSD つくる

* ホスト名が重複すると不便なので、ホスト名は毎回新しいものにする。
* ユーザー名とパスワードもちゃんとする。
* 無線LAN が必要ならその設定も。

## config.txt

32bit OS で運用したい場合は `[all]` に以下を追記。

```text
arm_64bit=0
```

そうしないと、`apt upgrade` で 64bit に変わってしまう（かもしれない）。

## 起動後

microSD 作る時にホスト名ミスっていたら、 `sudo arp-scan -l -I en0` などで IP を確認。
ユーザー名をミスっていたら負けかな。

SSH でラズパイに入って

まずは

```shell:ラズパイ側
$ sudo raspi-config
```

で `8 Update` を選択。

ついでに

`4 Localisation Options` → `I2 Change Timezone` でタイムゾーンを今いる地域にしておく。

つづいて `apt` 。

```shell:ラズパイ側
$ sudo apt update -y
$ sudo apt upgrade -y
$ sudo apt install -y vim byobu sysstat
```

さらに、ホスト側から以下を実行して、楽に `ssh` などができるようにする。

```shell:ホスト側
$ ssh-copy-id -i ~/.ssh/id_rsa.pub 【ユーザ名】@【ホスト名】.local
```

`id_rsa` の部分は `id_ed25519` とかかも。

## 固定IP

### 設定する前に

ミスると面倒なことになるので、無線LANと有線LANの両方が使える状況にしておくと安心。

### 設定方法

接続名を得る

```shell:ラズパイ側
$ nmcli con show
NAME                UUID TYPE      DEVICE 
preconfigured       略   wifi      wlan0  
lo                  略   loopback  lo     
Wired connection 1  略   ethernet  --     
```

有線を固定するなら `"Wired connection 1"` を変える。

`"192.168.12.34/24"` にするなら

```shell:ラズパイ側
$ sudo nmcli con mod "Wired connection 1" ipv4.addresses "192.168.12.34/24"
$ sudo nmcli con mod "Wired connection 1" ipv4.method manual
```

こんな感じにすればいい。

一応接続を off/on するなら

```shell:ラズパイ側
sudo nmcli con down "Wired connection 1"
sudo nmcli con up "Wired connection 1"
```

こう。
Reactのディレクトリ構成を考えてみた

# 概要
1つのアプリケーション内に複数のプロジェクト(機能)を内包したアプリケーションのディレクトリ構成を考察する

# 構成

```
src
├── pages                   # routerで遷移するページコンポーネント
│   └── project
├── components              # アプリケーション全体で使用する部品コンポーネント
├── features                # プロジェクトごとのモジュール
│   └── project
│       ├── api             # 該当プロジェクトで使用するAPIリクエスト関数
│       ├── components      # 該当プロジェクトでのみ使用するコンポーネント
│       └── models          # 該当プロジェクトで使用する型
├── models                  # アプリケーション全体で使用する型
├── lib                     # どこからも参照できる共通定義
│     ├── config            # 静的な設定や環境変数のエクスポート
│     ├── utils             # 共通利用できる関数
│     ├── hooks             # React機能を使用した共通利用できる関数
│     └── constants         # 定数
├── assets                  # 画像やアイコン、共通スタイルシート
│     └── icon
├── routes                  # ルーティング定義
└── stores                  # ストア定義
```

# 参考
https://github.com/alan2207/bulletproof-react
監視カメラの映像をOBSでライブ配信していて、Pythonでシーンを自動切り替えできるようにしてみた

# はじめに

去年の年末から店舗を運営することになり、遠隔監視ができたらいいな〜と思っていたところ、簡単にできそうだったので試してみました。

# 使ったもの

- [監視カメラとレコーダー](https://amzn.to/3HAhAXm)
- [HDMI-USB変換アダプタ](https://amzn.to/3Y31B9S)
- ワークステーション(DELL Precision 3690)
- [OBS](https://obsproject.com/)

# 基本設定

- 監視カメラを設置し、レコーダーに接続
- レコーダのHDMI出力に変換アダプタを接続
- USBをワークステーションに接続
- OBSでキャプチャデバイスとして映像を配信

# やりたくなったこと

同じ映像がずっと流れるのは少しつまらないかなと思ったので、少し工夫してみたくなりました

- カメラのレイアウトを変えたシーンをいくつか作ってそれを切り替えながら見れるようにしたい
- レイアウトに隙間があるので、店舗の告知も入れていきたい

結果、いくつか面白そうなシーンができたので、これを切り替えながら表示したいなと思ったら自動でシーンを切り替える機能が標準ではなかったので、Pythonで10秒おきに自動切り替えできるようにしてみました。

# 使ったライブラリ

[simpleobsws](https://github.com/IRLToolkit/simpleobsws)

```
pip install simpleobsws
```

# 作ったスクリプト

```switch_scenes.py
#!/usr/bin/env python3

import asyncio
import simpleobsws
import time

# 接続パラメータ
parameters = simpleobsws.IdentificationParameters(ignoreNonFatalRequestChecks = False)

# OBSとの接続設定
ws = simpleobsws.WebSocketClient(url = 'ws://localhost:[your port]', password = '[your password]', identification_parameters = parameters)

async def make_request():
    
    # OBSに接続
    await ws.connect()
    await ws.wait_until_identified()

    # シーンの一覧を取得
    request = simpleobsws.Request('GetSceneList')
    ret = await ws.call(request)
    if ret.ok():
        print("Request succeeded! Response data: {}".format(ret.responseData))

    # シーンの一覧から切り替え
    scenes = ret.responseData['scenes']

    while True:
        # 各シーンを10秒ごとに切り替える
        for s in scenes:
            sceneName = s['sceneName']
            data = {'sceneName': sceneName}
            request = simpleobsws.Request('SetCurrentProgramScene',data)
            ret = await ws.call(request)
            time.sleep(10)
    
    # OBSと切断
    await ws.disconnect()

loop = asyncio.get_event_loop()
loop.run_until_complete(make_request())
```

できた！

監視カメラの映像はこちらから確認できます。

https://www.youtube.com/watch?v=-JGAVnAbYrA
Googleプロジェクト管理：スプリントレトロスペクティブ

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# スプリントレトロスペクティブとは

スプリントレトロスペクティブ（レトロスペクティブ）は、スクラムチームが一歩下がって振り返り、チームとしての ***<font color="MediumBlue">仕事の進め方の改善点</font>*** を確認するために、***<font color="MediumBlue">最大3時間</font>*** 行われる重要なミーティングです。

レトロスペクティブでは、スクラムチームは、

- ***<font color="MediumVioletRed">人</font>***
- ***<font color="MediumVioletRed">プロセス</font>***
- ***<font color="MediumVioletRed">ツール</font>***

に関して、チームにとって何がうまくいっているか、またはうまくいっていないかを振り返ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/536be87d-5a95-2a1e-be70-dbd63c8f8f02.png" width="600">

レトロスペクティブを行う際には、スプリントのさまざまな側面をカバーします。
- チームの生産性と効率性
- 完了の定義の範囲と理解
- チーム内のコミュニケーションと相互作用
- ステークホルダーとのコミュニケーション
- より長期的なリリース計画への進捗

# スプリント・レトロスペクティブを成功させるための重要な対策

#### 対策1
スクラムの価値観である「尊敬」を示し、***<font color="MediumBlue">常にチームに非がないようにする</font>*** ことが重要です。もしチームメンバーの誰かが、フィードバックを提供することで否定的な結果になるかもしれないと心配していたら、結果はそれほど有益なものにはならないでしょう。

潜在的な気まずさを認識し、必要に応じて匿名または非公開のフィードバックのためのスペースを作ることによって、率直さのための安全なスペースを作成する必要があります。

レトロスペクティブは、参加者が自分の意見が重要であると感じて初めて機能するため、参加は重要な鍵となります。参加者が自発的に意見を言わないことに気づいたら、新しいアイデアを生み出す方法を探してみてください。

- ***<font color="MediumVioletRed">次のスプリントで試せることは何でしょうか？</font>***
- ***<font color="MediumVioletRed">何が足を引っ張ったのか？</font>***
- ***<font color="MediumVioletRed">予想外のことが起こったのでしょうか？</font>***
- ***<font color="MediumVioletRed">どうすればチームはもっと透明性を担保できるか？</font>***
- ***<font color="MediumVioletRed">スプリントの価値を守れましたか？</font>***

これらの質問に対する回答は、改善策を理解するのに役立ちます。

> 例えば、私のチームは、スクラムチーム以外のステークホルダーに依存することが、私たちのペースを低下させていることを発見しました。レトロスペクティブでは、いくつかの新しいコミュニケーションチャネルを通じて、外部のステークホルダーとの優先順位の認識を高めることにしました。

#### 対策2

次に、***<font color="MediumBlue">ネガティブとポジティブのバランス</font>*** をとることです。改善点を聞くだけでなく、

- ***<font color="MediumVioletRed">成功に気づいた点はどこか？</font>***

チームには成功したと思ってもらいたいし、その成功の成果を再現したいのです。


#### 対策3

- 最後に、***<font color="MediumBlue">必ず行動</font>*** に移しましょう。フィードバックが変化のきっかけにならないと感じると、チームは今後のレトロスペクティブに参加するのをためらってしまうかもしれません。改善点を探すか、または、最もうまくいったことをチームの習慣や規範に変えるだけでよいのです。

# 落とし穴

- **あまりに多くのギミック（仕掛け）を避ける。**
スクラムマスターがスプリントレトロスペクティブを進行するときに使える楽しいゲームや演習はたくさんあります。しかし、すべてのチームがこのスタイルを楽しむわけではありません。これらの演習は、たまにしか使わないか、チームがレトロスペクティブの新しい方法を求めてきたときに使うことを検討してください。

- **レトロスペクティブのたびにプロセスを変更するのは避けましょう。**
新しいプロセスが有効であったかどうかを判断する前に、数スプリントの間、新しいプロセスを維持することは問題ありません。新しい変更を実施する前に数スプリント待つようにしましょう。


:::note info
レトロスペクティブとデイリーのワークフローの両方で、スクラムチーム間の会話を促進することは、スクラムマスターとプロジェクトマネージャであることの非常に重要な側面です。
:::
Ubuntu: Visual Studio Code の使い方

Ubuntu 22.10 で Visual Studio Code を使う方法です。

## インストール
deb ファイルをこちらからダウンロードします。
[Visual Studio Code on Linux](https://code.visualstudio.com/docs/setup/linux)

```bash
sudo dpkg -i code_1.97.2-1739406807_amd64.deb
```

インストールできたことを確認

```text
$ which code
/usr/bin/code

$ code --version
1.97.2
e54c774e0add60467559eb0d1e229c6452cf8447
x64
```

## 起動

```bash
code
```

## サンプルプログラムの実行

```py:sample.py
import sys
sys.stderr.write("*** 開始 ***\n")
print(sys.version)
print("Hello World")
print("こんにちは")
for it in range(5):
    print("テスト　%d" % it)
sys.stderr.write("*** 終了 ***\n")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c1081c88-9c7d-91f3-371d-b88e554f4f9e.png)

実行結果

```text
$  cd /home/uchida/tmp/jan27 ; /usr/bin/env /bin/python /home/uchida/.vscode/extensions/ms-python.python-2022.20.2/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 44905 -- /home/uchida/tmp/jan27/print\(\"Hello\ World\"\).py 
*** 開始 ***
3.10.7 (main, Nov 24 2022, 19:45:47) [GCC 12.2.0]
Hello World
こんにちは
テスト　0
テスト　1
テスト　2
テスト　3
テスト　4
*** 終了 ***
```
EclipseでVimを使おうとしたけどキーバインドが反映されない

Eclipseで、Vimを使いたくて、Vrapperを入れましたが、キーバインドで、`ctrl + [`が効かない！

という事象に対して、気づけなかった設定変更を備忘録として残します。

OS: Mac 13.1
Eclipse: Version: 2022-12 (4.26.0)
Vrapper: 0.74.0

結論としては、[設定]>[キー]の[スキーム]を、[Vim's key bindings]に変更する。

`ctrl + [`でインサートモードから抜け出せえるようになりました！

![スクリーンショット 2023-01-27 16.51.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239851/30145ce3-2489-8970-d7ea-4089206aa9fb.png)
AWS SDK V3 のSQS(Simple Queue Service)で、いくつか動作確認した話（AWS SDK V2 → V3 移行Tips）

# はじめに

https://qiita.com/Syoji_Yonemoto/items/09883e57643583ef39af

引き続いて、今度は、SQS（Simple Queue Service）についても確認しました。
やはり初回（Firehose）の運が悪かっただけで、基本は互換できてそうだという感触になりつつありますが、自分のメモも兼ねてるので確認できた範囲をまとめていきます。

# 結論
SQS（Simple Queue Service）に関しては、私が普段使うメソッド群については、問題ありませんでした。

# V2 と同じ使い方で問題なく動作確認できたメソッド

+  sendMessage
+  receiveMessage
+  deleteMessage
+  getQueueAttributes

# 余談（雑多な感想）
受信・送信・削除・状態確認、一通りLambdaからSQSを活用する際に利用するAPIは試しましたが、V2の時と変わらぬ使い方ができて良かったです。

https://qiita.com/Syoji_Yonemoto/items/e619d8199b7c8354248f

上記は一体、何だったのか！？という位の順調っぷりですね。

# まとめ
残りのメッセージ数を見ながら、まとめて受信して、処理後にキューから削除する処理はV3でも組めそうですね。

引き続き、小ネタシリーズとして、 V2 → V3 の動作確認メモを書いていこうと思います。

# AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。

https://www.cs-cloud-aid.com/
AWS:EC2のユーザーデータで、タグNameの値を自動付与

名前のとおり。通常NameタグはGUIなどで入力していくが、AutoScalingのインスタンスなどの場合、増減を勝手にした場合にいちいちGUIで設定していくのはしんどい。
EC2のNameタグには、そのインスタンスがどのアベイラビリティーゾーンに属するのかを識別するために、ゾーン名（AとかCとか）を付与する場合が多い。そういうとき、ユーザーデータに以下シェルを設定しておくと自動で名前をつけてくれる。

前提条件
・今回の場合「SERVERNAME-AZNAME」というNAMEタグの命名規則としている。このとき、AZNAMEの部分を自動的に付与する。
・AmazonLinux2またはRHELインスタンスで対応可能。


```bash:bash(USER DATA)
#!/bin/bash

IID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
REG_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
AZ=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | tail -c1`
variable=${REG_ZONE}
length=${#variable}
REG=${variable::length-1}
wait
aws --region ${REGION} ec2 create-tags \
    --resources ${IID} --tags Key=Name,Value=SERVERNAME-${AZ}
```

メタデータ情報より、自身のインスタンスID、リージョンとゾーン情報を取得。
ゾーン情報とリージョンを分離して抽出。
そうしたらawsコマンドのcreate-tagsで、上記の情報をもとにNameタグを設定。
AutoScaling環境で利用すると便利。

# 追記　2023/3/16
IAMポリシー、IAMロールの設定が必要のため、[追記しました。](https://qiita.com/If_it_bleeds-we_can_kill_it/items/1ddd5f522c95e5802091)
brew install old version's formula

# Background

Sometime if we want to install some old version's formula, for example I was hope to install a old version python with brew. 
Basically we can install the latest version of 3.7, for now it is 3.7.16, but what if I want to install 3.7.2?

Here introduce a way to do it.

# Extract the old version

First extract the specified version to local, it will show the saved path when extract succeed.

```shell
brew extract --version=3.7.2 python homebrew/cask
```

# Install the old version of python

Then we can install the specified version directly.

```shell
brew install python@3.7.2
```

# Edit formula if necessary

Sometimes, when we install the old version, it often has some issues, we may need do some fix for the formula, we can use this command to do this.

```
brew edit python@3.7.2
```

It will open a editor and let you edit the formula.

By setting the environment variable `HOMEBREW_EDITOR` to choose the editor for editing. Such as if we use vim for editing we can setup a variable in `~/.zshrc` or `~/.bashrc`.

```sh
HOMEBREW_EDITOR=vim
```

# Debug formula installation 
Sometimes we need to know what error occurred or why the installation failed. We can add `-vd` options for investigation when install the formula.

```
brew install -vd python@3.7.2
```

If we got a error for the installation, it will stop and show some options for debuging. We can choose 5.shell to rerun the last commands and check what happened etc.

```
BuildError: Failed executing: xxxxxx
1. raise
2. ignore
3. backtrace
4. irb
5. shell
```
Laravelを基本からまとめてみた【ルーティング】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/d5369436-02a3-e40c-c194-7bc2e13c6fd4.png)


## Laravelルーティングの基本形

Route::リクエスト方法('URL','コントローラー名＠メソッド名')

- リクエスト方法(GET,POST等)
- URL
- コントローラー名
- メソッド

例
Route::（'/','HomeController@index'）


## ルーティングのURLパラメーター

Route::get('show/{id}','homeController＠show')

- URLの組み込める変数
- パラメーターはコントローラーで
- DBに関わる事が多い
- 利用可能になる

具体例
http://uchida.link/article/111 ⇨ 記事ID ＝ 111の記事を指定



## 参考サイト
[【Laravelの使い方】「ルーティング」の基本を実践解説！簡単なページの出し分けから便利なグループ化まで](https://www.youtube.com/watch?v=M58aCituLYc&t=30s)
パスワードの表示/非表示を切り替える

## 環境
- Rails5.2
- Slim
- JavaScript

## はじめに
パスワードを入力をする際、セキュリティのため、入力した文字が「・・・」で表示されます。それを、チェックボックスを使って、入力文字が表示できるよう、切り替えられるようにします。どのようにするのかといえば、HTMLの**input**タグの**typ**e属性を、**password**から**text**に変更するだけです。これだけで、入力文字が表示されるようになります。非表示にしたい場合は、input属性を逆に、textからpasswordに戻せばいいだけの話です。フロントエンド側の操作になるため、JavaScriptを使って実現させることになります。

## 動き
チェックを外すと、パスワードが非表示になります。
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/d1806192-15dd-d713-ff70-38434251dd3c.png)

チェックをつけると、パスワードが表示されます。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/74ec414d-834b-d1b4-ce2c-4df5b5c7b450.png)

## 内容
パスワードを入力するform-group内に、パスワード表示のチェックボックスを追加します。サーバーサイドのRailsに直接送信させる項目ではないため、独立させた項目として記述します。slimを使っている中に、HTMLを直接埋め込んでも動作します。
```_form.html.slim
.form-group
    .row
        .col-md-2
            = f.label :password, 'パスワード', class: 'form-label'
        .col-md-4
            = f.password_field :password, class: 'form-control', id: 'usr_password'
            <input type = 'checkbox' id = 'users_passcheck' class = 'form-check-input'> パスワード表示
```

slimで記述すれば、次のようになります。
```_form.html.slim
input#users_passcheck.form-check-input type = 'checkbox' パスワード表示
```

JavaScriptのコードを記述します。最初に、ファイルの拡張子がデフォルトではcoffeeになっているため、jsに変更します。

チェックボックスにチェックをオン/オフしたときに発火するイベントは**change**です。
RailsでTurboLinskを有効にしているため、**turbolinks:load**はお約束です。

```user.js
document.addEventListener('turbolinks:load', function() {
    document.getElementById('users_passcheck').addEventListener('change', function() {
        let txt_pass = document.getElementById("usr_password");
        if (txt_pass.type === "password"){
            txt_pass.type = "text"
        }else{
            txt_pass.type = "password"
        };
    })
}, false)
```
【小ネタ】GitLabで削除できないリリースが残った場合の対処法

## 概要
GitLab上でタグとリリースを管理している際に、手違いでタグのみを消してしまった場合の対処法についての記事です。

## 環境
- GitLab Community Edition 14.9.2

## 前提
GitLabには、リリース時に利用できる以下の2機能が用意されています。
- gitブランチ上の一地点にタグをつける[タグ機能](https://docs.gitlab.com/ee/topics/git/tags.html)
- タグに紐づいたリリースを作成する[リリース機能](https://docs.gitlab.com/ee/user/project/releases/#releases)


リリース機能はタグと合わせて利用することが前提なので、リリース単体を削除する方法はなくタグを削除する際に併せて削除されます。
そのため、普通に画面上から操作していれば特に問題はありません。

## 今回起こったこと
GitLab上でタグのみが削除され、リリースが編集・削除できなくなりました。

私は普段VS Codeの[Git Graphという拡張機能](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)を利用してタグの作成・削除を行なっています。
そのGit Graphの機能にタグの削除(オプションでリモートも併せて削除する)があるのですが、その機能でGitLab上にリリースが残ったままタグのみを削除してしまいました。
![スクリーンショット 2023-01-27 15.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/f7071e32-1ac2-60f1-2b50-0e9d9d6661f3.png)

画面上の操作ではリリースはタグに紐づいて削除されるのですが、今回はこの機能でタグのみを削除してしまった結果編集・削除できないリリースのみが残っていました。

※以下画像は編集した際の画面

![スクリーンショット 2023-01-27 15.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/96cdc676-1156-ec03-1663-413cf4b64c51.png)


## 解決策
この事象の解決策はわかってしまえば簡単で、同じコミットに同じタグ名をつけ、再度pushしてあげることで削除したものと同じタグが作成され解決します。

GitLabの画面上では以下の画像の通りタグ画面にリリースのリリースノートが表示され、事前に作成したリリースと再度pushしたタグが自動で紐づいています。

![スクリーンショット 2023-01-27 15.49.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/24569946-7153-2b79-4308-639cd041ca8c.png)

以上の方法で、タグ画面上からタグを削除しリリースも併せて削除できるようになります。

![スクリーンショット 2023-01-27 16.10.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/eb86088b-1ad3-f7d8-9484-756a2643f302.png)
![スクリーンショット 2023-01-27 16.10.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/11528b67-2f45-fcf1-81e6-f5fbdd08c03c.png)











## 補足
利用しているGitLabのバージョンを調べる際に、以下の記事が参考になりました。

https://orebibou.com/ja/home/201610/20161028_003/#:~:text=1.%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%8B%E3%82%89%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B,%E3%81%A7%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%A7%E3%81%8D%E3%82%8B%E3%80%82
Googleプロジェクト管理：プロダクトインクリメント

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# プロダクトインクリメントとは

***<font color="MediumVioletRed">『プロダクトインクリメントとは、あるスプリントの後に生成され、リリース可能とみなされるもの』</font>***

スクラムガイドには
**「インクリメントは、製品目標に向かう具体的な足がかりである」**
と書かれています。

各インクリメントは、それ以前のすべてのインクリメントに追加され、すべてのインクリメントが一緒に機能することを保証するために徹底的に検証される。価値を提供するために、インクリメントは使用可能でなければならない。

# 潜在的にリリース可能なプロダクトインクリメント

潜在的にリリース可能なプロダクトインクリメントは、チームがスプリントの望ましい結果について考えるための便利な方法である。すべてのスプリントゴールは、製品またはソリューションに、完成し、テストされ、すぐに出荷できるものを追加することである。

これは、製品が実際に顧客に出荷されることを意味するものではありません。例えば、ペットを見つけて飼うためのアプリケーションを構築することを考えてみましょう。プロダクトバックログには、次のような3つの機能があります。

1. ペットの情報を提供する
2. 養子縁組の可能性を評価する
3. 里親募集センターへの問い合わせができる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b6e63c48-5453-9572-f1b6-a2a3f12ccc0c.png" width="550">

しかし、潜在的にリリース可能なプロダクトインクリメントを完成させることは、チームが3つの機能の断片に取り組むのではなく、1つの機能を全体として見ることができ、実際にはどれも完成していいません。潜在的にリリース可能なプロダクトインクリメントがあれば、1回のスプリントで1つの機能の完全な、動作し、テストされた実装を作成することができます。

また、潜在的にリリース可能なインクリメントを持つことで、チームは製品に関する初期のフィードバックを得て、作業の品質を確保し、変化に対応する機会を持つことができます。

***<font color="MediumVioletRed">『スプリントのゴールとして、常にリリース可能なプロダクトインクリメントに焦点を当てるべき』</font>***

# Doneの定義

Doneの定義は、潜在的にリリース可能なプロダクトインクリメントの状態と、それが製品に要求される品質指標を満たしている場合の意味を正式に記述したものである。バックログ項目のうち、"完了 "とみなされるものに対して、チームが合意した要件である。

ソフトウェアプロジェクトでは、"Done "とはソフトウェアが完成し、レビューされ、テストに合格したことを意味するとチームが判断することが多い。ソフトウェア以外のプロジェクトでは、「完了の定義」は、承認付きの法的レビューや正式な終了報告書を含む文書となる場合があります。

チームの「Doneの定義」を決定する上で重要なのは、「Done」とは何を意味するのかについて、明確かつ共有された理解を持つことです。

しかし、ソリューションがいつリリース可能か、またはリリース可能かを知るにはどうしたらよいのでしょうか。スクラムチームでは、アイテムをリリースする前に価値があることを確認するのは、最終的にはプロダクトオーナーの判断になります。これを決定するために、彼らはいくつかのことを考慮することがあります。

- ***<font color="MediumBlue">そのインクリメントは完全か？</font>***
- ***<font color="MediumBlue">インクリメントは完成しているか、価値をもたらすか、品質基準を満たすか。十分にテストされているか？</font>***
- ***<font color="MediumBlue">エンドユーザーにとって使いやすいか？エンドユーザーからの直接的、間接的なフィードバックは、今後のバージョンアップに活かせるか？</font>***

# リリース可能な製品インクリメントとMVPの比較

***<font color="MediumVioletRed">『MVP（Minimum Viable Product）とは、初期の顧客を満足させるのに十分な機能を備えた製品のバージョンのこと』</font>***

MVPから洞察を収集することで、100％テストされていない、あるいは安全でない可能性のある全機能の製品を開発するよりも、ユーザーからのフィードバックを迅速に得ることができるのです。MVPの例としては、Webサイトのランディングページなどがあります。


MVPとは、数回のスプリントを経て開発される機能パッケージのことです。

潜在的なリリース可能性とMVPを区別するために、ペットの里親募集アプリと前回説明した3つの機能を例にとって考えてみましょう。これらの機能は、それぞれ単独ではソリューションの有用なリリースにはならないことを指摘しました。しかし、プロダクトオーナーは、このユーザーエクスペリエンスのMVPは、この3つの要件を猫だけに実装することだと判断することができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/932d9b5c-0e6f-e8d5-aff2-1c8ac38f7e81.png" width="200">


MVPの範囲を狭めることで、プロダクトオーナーはソリューションを市場にリリースし、猫を飼いたいと考えているユーザーからフィードバックを収集することができます。このフィードバックは、猫の養子縁組プロセスだけでなく、製品の将来のイテレーションにおいて、あらゆる種類のペットの養子縁組のために貴重なものとなるでしょう。
placelIMGが終了するらしいから代わりのサービス見つけた

部で使うように作ったポータルサイト。
タイトルをかっこよくしたくて画像をplacelIMGを利用して表示していた。

ある日から画像に文字が表示されるようになった。
自分で入れている文字としっかり被って読みづらいなぁ、なんてかいてあるんだろうと翻訳へ
（英語まったく読めません）

`placelIMG is shutting down on june 30, 2023`
`placelIMGは、2023年6月30日に閉鎖されます。`

使えなくなってしまう？！？！

ということで、代わりになるサービスを探したのでご紹介。
（需要はあるのかな…まぁ、備忘録）

### Lorem Picsum
こちらを利用することにしました。

placelIMGでは`https://placeimg.com/640/480/any`で画像を取得することができていました。
変更後も`https://picsum.photos/200/300?random`で画像が取得できます。
ほぼ変わらない！最高！！

ちなみに…
たくさんアクセスするのは気が引けるので、
AWS　CloudFrontを利用してキャッシュさせてます。
Pull Requestでマージしたのに、対象ブランチにマージコミットが存在しない

あ…ありのまま 今起こった事を話すぜ！
な…何を言っているのか分からねーと思うが、おれも何が起こっているのかわからなかった…

# 発生した事象
1\. ２つの作業ブランチを本番化するため、masterブランチへPull Requestをそれぞれ作成
2\. Pull Requestを、担当者の承認してマージする
3\. マージすると同時に、Github ActionsでBump versionする処理（package.jsonのバージョンを上げる）が実行される
4\. その後、Github Actionsの本番デプロイワークフローが実行され、無事に本番化完了
5\. ところがmasterブランチには**Pull Requestした作業ブランチのうち１つかマージされていない**

下図の青枠で囲った２つが、今回masterにマージした作業ブランチである。
#12と#13のPull Requestを出している。
そのうち#13のPull Requestでマージしたはずのブランチは、`Merged`状態なのに、進行しているコミットがある（masterより進んでいる）
![screencapture-github-ligua-WORKBASE-WORKBASE-ligua-branches-2023-01-27-13_30_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31785/7b86e0b4-0b1f-90c3-5856-5365a1ea8df4.png)

#13のPull Requestを確認してみると、問題なく承認されマージが完了しているように見える。
マージコミット`6108aea`を確認してみる。
![screencapture-github-ligua-WORKBASE-WORKBASE-ligua-pull-13-2023-01-27-13_29_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31785/cdb85de7-f5e6-34c6-c7c8-b6064783fb72.png)

何やら注意文が出ている。
![screencapture-github-ligua-WORKBASE-WORKBASE-ligua-commit-6108aead88000599eb0e49e9f92631efbef25d94-2023-01-27-13_29_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31785/09cc3cac-4c41-6c99-5f6e-01df1d47b511.png)
> This Commit does not belong to any Branch on this repository, and may belong to a fork outside of the repository
> （訳：このコミットはどのブランチにも所属していない。フォークされた外部リポジトリのものかもしれない）

ちなみに、フォークなどされてないので、外部リポジトリのコミットである可能性などない。

# 原因
結論から言う。
Github ActionsでmasterへのPull Requestの直後に、**Bump versionする処理により、マージコミットを上書きして無きものにしていた**。
- Bump versionのために追加したコミットをforce Pushしていた
- 複数のPull Requestを立て続けに承認・マージした

この二つが重なって問題が起きていた。
詳細は以下の通り。

## Github Actionsの処理
Github Actionでは、以下のようなワークフローを設定している 
- プルリクエスト後に、`npm version`コマンドを実行して、package.jsonのバージョンを書き換えて、Gitにコミットする
  - そのときバージョン番号のタグが付けられる
- バージョン番号のタグがpushされると、本番環境へのデプロイを実行

### Bump Version
詳細は省くが、プルリクエストが承認されると以下のようなコマンドを実行するように設定している。
```bash
npm version minor
# major, minor, patchは場合分けしている

git push origin master --follow-tags --force
```
### 本番デプロイ
`npm version`で自動で付けられるタグ（`v2.7.0`）がpushされると、本番へのデプロイが実行されるように設定している。

# 実際に起こったこと
実際に起こったことを時系列に沿って書いておこう。
[]内は、masterブランチに含まれるコミット

1\.担当者がプルリエクエスト#12 を承認し、作業ブランチAがマージされる [Aのマージ]
2\.Bump Versionの処理が実行を開始 [Aのマージ]
3\.担当者がプルリエクエスト#13 を承認し、作業ブランチBが作業ブランチAのマージコミットの直後にマージされる（**#12のBump versionはまだリモートリポジトリにpushされてない**） [Aのマージ,Bのマージ]
4\.Bump Versionの処理が実行を開始 [Aのマージ,Bのマージ]
5\.#13の方のBump versionしたコミットがPushされる [Aのマージ,Bのマージ,Bump]
6\.本番デプロイ処理が開始される [Aのマージ,Bのマージ,Bump]
7\.#12の方のBump versionしたコミットがPushされる [Aのマージ,Bump]

こうして、#13でマージされたのに、当該作業ブランチBは、masterにマージされていない状態になっていた。
なお、本番デプロイはAもBも両方の変更を反映したものになっていたのは、#13の方のBump versionコミットが先にPushされたためである。

### もし#13のBump versionのpush　が、#12のBump versionより遅かった場合
masterブランチの最新コミットは、[Aのマージ,Bのマージ,Bump]と意図したものとなっていたであろう。
だが、本番デプロイは[Aのマージ,Bump]のコミット状態で開始されていたであろうから、作業ブランチBの更新内容が含まれないままリリースされてしまっていただろう。

# 教訓
この環境におけるプルリクエストは1個ずつ承認してもらうこと。
あるいは、複数の作業ブランチを同時に本番化するなら、プルリクエストする作業ブランチを1個にまとめること。
JetpackComposeでカレンダーを作れるライブラリ

個人開発でカレンダーを作りたくていい感じの方法を探していた時に見つけた
良さげなライブラリの紹介です。

## Calendar
https://github.com/kizitonwose/CalendarView

知らなかったんですが結構使われてるみたいで、
大分好きに見た目など変えられるみたいで良さそうだし
サンプルのカレンダーが豊富🤔


## カレンダーを作っていく方法

### ライブラリの導入
`build.gradle`にこちらを追加
```
dependencies {
  // Compose用
  implementation 'com.kizitonwose.calendar:compose:<latest-version>'
}
```

### カレンダーの作成

https://github.com/kizitonwose/Calendar/blob/main/docs/Compose.md

ここにCompose向けの利用法がまとまっている

カレンダーの描画に必要になるものなどと、
カレンダーを描画するライブラリ内のComposable関数の呼び出し部分をドキュメント参考に書いていったのが下記

```Kotlin
@Composable
fun CalendarDisplay() {
    // 現在の年月
    val currentMonth = remember { YearMonth.now() }
    // 現在より前の年月
    val startMonth = remember { currentMonth.minusMonths(100) }
    // 現在より後の年月
    val endMonth = remember { currentMonth.plusMonths(100) }
    // 曜日
    val daysOfWeek = remember { daysOfWeek() }
    // カレンダーの状態を持つ
    val state = rememberCalendarState(
        startMonth = startMonth,
        endMonth = endMonth,
        firstVisibleMonth = currentMonth,
        firstDayOfWeek = daysOfWeek.first(),
        outDateStyle = OutDateStyle.EndOfGrid
    )

    // 横スクロールのカレンダーを作成するためのComposable関数
    // 縦スクロールのVerticalなどもある
    HorizontalCalendar(
        state = state,
        // 日付を表示する部分
        dayContent = {Day(it)},
        // カレンダーのヘッダー
        monthHeader = {DaysOfWeekTitle(daysOfWeek = daysOfWeek)}
    )
}
```

### ヘッダー
曜日の表示を行うComposable関数を作成している
```Kotlin
@Composable
fun DaysOfWeekTitle(daysOfWeek: List<DayOfWeek>) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        for ((index, dayOfWeek) in daysOfWeek.withIndex()) {
            Text(
                modifier = Modifier.weight(1f),
                textAlign = TextAlign.Center,
                text = dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault()),
                // 土日だけそれぞれ色を変えたいので対応したカラーコードを返している
                color = getDayOfWeekTextColor(index)
            )
        }
    }
}
```

### 日付表示部分
カレンダーの日付にあたる部分を表示するためのComposable関数を作成する。
日付をタップした時の挙動や、月始まりと終わりの前後にある前月や次の月の日付をグレーアウトさせるなどはこの中でやるのがいいっぽい。
```Kotlin
@Composable
fun Day(day: CalendarDay) {
    Box(
        modifier = Modifier
            .aspectRatio(1f),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = day.date.dayOfMonth.toString(),
            // ここで今月でないものの日付をグレーアウトさせている
            color = if (day.position == DayPosition.MonthDate) Color.Black else Color.Gray
        )
    }
}
```

## 実際に作成した画面

個人開発の方で実際に上記のコードをもとに色々追加で書いて作成した画面がこんな感じ。
比較的簡単に実装でき、見た目もいじりやすく作成者様には感謝です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067453/8f5e5ea7-d5ca-1f69-19db-aabcc8122d0e.png" width=50% height=50%>
Auzre Synapse SQL って何？

# プロローグ

**ほげ君**：あーこの前のかつ丼美味かったなあ。
**ふが君**：Azure Synapse Analytics の話聞いた後行ったとこね。
**ほげ君**：前回は全体の概要だけ聞いたんだっけな。じゃあ今日は Synapse SQL についてもうちょっと教えてくれよ。
**公式ドキュメント君**：分かりました。

# 〇〇 概要
**公式ドキュメント君**：Synapse SQL では、スケールアウト アーキテクチャを使用して、複数のノードにデータの計算処理を分散します。 コンピューティングをストレージから切り離すことで、システム内のデータとは無関係に、コンピューティングをスケーリングできるようになります。

**ほげ君**:あ？何言ってんだ？なんも分からんぞ。
**ふが君**:んー、分散処理するから早いってことかな？

**公式ドキュメント君**:Synapse SQL は、ノードベースのアーキテクチャを使用します。 アプリケーションでは T-SQL コマンドに接続し、これを Synapse SQL の単一のエントリ ポイントである制御ノードに発行します。Azure Synapse SQL の制御ノードでは、分散クエリ エンジンを利用して並列処理のためにクエリが最適化された後、作業を並列で実行するために操作がコンピューティング ノードに渡されます。

**ほげ君**:制御ノード？コンピューティングノード？
**ふが君**:仕事を振り分ける人と渡された仕事を実際に行う人かな？

**公式ドキュメント君**:サーバーレス SQL プールの制御ノードは、分散クエリ処理 (DQP) エンジンを利用して、コンピューティング ノードで実行される小さなクエリにユーザー クエリを分割することにより、ユーザー クエリの分散実行の最適化と調整を行います。 この各小さなクエリはタスクと呼ばれ、分散実行の単位を表します。 タスクでは、ストレージからファイルを読み取り、他のタスクの結果、または他のタスクから取得したグループや注文データを結合します。

**ほげ君**:えーと、ユーザが依頼主で、なんか仕事を制御ノードに依頼して、制御ノードが依頼された仕事を小分けして、コンピューティングノードに渡すのか。
**ふが君**:このコンピューティングノードに渡される小分けされた仕事のことを「タスク」と呼ぶんだね。

**公式ドキュメント君**:コンピューティング ノードはすべてのユーザー データを Azure Storage に保存し、並行クエリを実行します。 Data Movement Service (DMS) はシステム レベルの内部サービスで、必要に応じて複数のノードにデータを移動し、クエリを並列に実行して、正確な結果を返します

**ほげ君**:データは別の場所に置いてあるのか。
**ふが君**:なんでそんなことするんだろう？一緒に置いた方が簡単なのに。

**公式ドキュメント君**:Synapse SQL を使用すると、ストレージとコンピューティングを分離することにより、ストレージのニーズに関係なく、コンピューティング能力を独立してサイジングできるという利点があります。 サーバーレス SQL プールのスケーリングは自動的に行われますが、専用 SQL プールでは次のことが可能です。

**ふが君**:そっか！データをどれぐらいの量置けるかとデータをどれぐらい早く処理できるかは全然違う能力だから、分離したほうが各能力を別々で調整できるから嬉しいのか！
**ほげ君**:なるほど！分かりやすいな。

**公式ドキュメント君**:サーバーレス SQL プールでは、データ レイク ファイルにクエリを実行できます。専用 SQL プールでは、クエリを実行し、データ レイク ファイルからデータを取り込むことができます。 データを専用 SQL プールに取り込むと、システムのパフォーマンスを最適化するために、データはディストリビューションにシャード化されます。 どのシャーディング パターンを使用して、テーブルを定義するときにデータを分散するかを選択できます。

**ほげ君**:シャード化ってなんだ？
**ふが君**:教えて、グーグル先生！

**グーグル先生**:シャーディングとは、データベースの負荷分散の手法の一つで、一つの表（テーブル）を複数の物理コンピュータに分割して記録する方式。

**ほげ君**:専用 SQL プールはデータを処理しやすいように小分けして持っておくのか。
**ふが君**:サーバレスはストレージのデータを処理するだけで、自分ではデータは持たないんだね。

**ほげ君**:こういうのってテクノロジーッて感じするよな。
**ふが君**:そうだね。
**ほげ君**:よし、腹減ったし辛ラーメン食おうぜ。
**ふが君**:いいね。
flaskでSQLiteのデータベース作成時に発生するapp.app_context()に関するエラーを解決する。

flaskでSQLiteのデータベースを作成するときに、以下のようなエラーが発生した。teratailでのとある質問のやりとりが参考になったので、紹介しようと思う。
## 発生したエラー
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
## エラーが発生するまでの流れ
1\. app.pyに以下のコードを記述
```python:app.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import pytz

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(50), nullable=False)
    body = db.Column(db.String(300), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, default=datetime.now(pytz.timezone('Asia/Tokyo')))

#以下、今回のエラーとは関係のない部分
@app.route("/")
def index():
    title = "Hello"
    return render_template("index.html", title=title)
```

2\. コマンドプロンプトで以下のコマンドを実行(このコマンドは、エラーが発生した時のものです。)

:::note alert
以下のコマンドは、エラーが発生したコマンドです。
以下のコマンドは実行しないでください。
:::

```python:cmd
app.pyのあるディレクトリ>python
>>>from app import app,db
>>> db.create_all()
```
# 正しい実行コマンド
2\. コマンドプロンプトで以下のコマンドを実行

:::note info
以下のコマンドが正しいものです。
:::

```python:cmd
app.pyのあるディレクトリ>python
>>>from app import app,db
>>>with app.app_context():
...   db.create_all()
...
>>>exit()
```
## 実行結果
app.pyと同ディレクトリにinstanceフォルダーが作成され、その中に.dbファイルが作成されました。
## 参考にさせていただいたサイト記事
https://teratail.com/questions/rgcmdk8o0z2ksa
C#でDataverseに接続してテーブル一覧を表示してみた

# はじめに
PowerAppsのモデル駆動の設定が面倒なのでC#からDataverseを操作してみたくなった。
まずはDataverseにあるテーブルの一覧を表示するコードを作成してみた。
# 前提
・C#の.Net frameworkのコンソールプログラムを作成
・Microsoft.CrmSdk.XrmTooling.CoreAssembly をnugetで追加
# コード
dataverseへの接続文字列を構築してCrmServiceClientのインスタンスを作成(CreateCrmService)。
あとは全てのテーブル情報を取得するRetrieveAllEntitiesRequestを作成して実行。
```C#
static void Main(string[] args)
{
    if (args.Length < 3)
    {
        Console.WriteLine("引数：ユーザ名 パスワード URL");
        return;
    }
    string user = args[0];
    string password = args[1];
    string url = args[2];
    var organizationService = CreateCrmService(user, password, url);

    var request = new RetrieveAllEntitiesRequest { EntityFilters = EntityFilters.All };
    var response = (RetrieveAllEntitiesResponse)organizationService.Execute(request);
    foreach (var table in response.EntityMetadata)
    {
        Console.WriteLine(table.EntitySetName);
    }
}

private static OrganizationWebProxyClient CreateCrmService(string user, string password, string url)
{
    string authType = "OAuth";
    string appId = "51f81489-12ee-4a9e-aaae-a2591f45987d";
    string reDirectURI = "app://58145B91-0C36-4500-8554-080854F2AC97";
    string loginPrompt = "Auto";
    string ConnectionString = string.Format("AuthType = {0};Username = {1};Password = {2}; Url = {3}; AppId={4}; RedirectUri={5};LoginPrompt={6}",
                                            authType, user, password, url, appId, reDirectURI, loginPrompt);

    var serviceClient = new CrmServiceClient(ConnectionString);
    var organizationService = serviceClient.OrganizationWebProxyClient;
    return organizationService;
}

```
*プログラムに渡す引数はユーザ名、パスワードはdataverseにアクセス可能なM365ユーザ、URLはモデル駆動のアドレスの先頭部分「https://xxxxxxx.crmx.dynamics.com」を指定

# おわりに
テーブルの一覧はわりと簡単に表示できました。今度はテーブルや列の作成、フォームやビュー、ワークフローの中身を探索していこうと思います。

# 参照情報
https://learn.microsoft.com/ja-jp/power-apps/developer/data-platform/xrm-tooling/use-connection-strings-xrm-tooling-connect
【Django】POST無し GETのみでフォームの内容を取得して表示に反映させる

フォームに入力した値によって表示内容を変えたい時に、POSTを使わずにフォーム内容を取得し、反映させる方法の備忘録

## 仕様

選択フォームで選んだものを、選択フォームの下部に表示するWebページ。

## ソースコード

まずフォームを設置する。ここではSelectフォームとする。

~~~python:form.py
class SelectForm(Form):
    select_sample = ChoiceField(
        widget=Select(),
        choices=[
            ("", "未選択"),
            ("01", "選択肢1"),
            ("02", "選択肢2"),
            ("03", "選択肢3"),
        ],
        required=False
    )
~~~

ビューファイルでフォーム送信内容を取得

~~~python:view.py
template_name = "sample.html"

...

# もし送信されていたら
if form.is_valid():
    # 内容を取得する
    selected = int(form.cleaned_data.get("select_sample"))
    # 選択フォームの選択を取得した値で固定する
    form.fields['select_sample'].initial = [selected]

...

context = {
    ...
    "form": form,
    "selected": selected,
    ...
}
return render(request, self.template_name, context)
~~~
「フォームに入力された値を取得する」ではなく「パラメータの値を取得する」の場合は以下のようにできる。
~~~python:views.py
selected = request.GET.get(key="select_sample", default="")
# 上記のようにNoneだった場合のdefaultも指定可能
~~~

htmlファイル。POSTは使っていないので{% csrf_token %}は必要ない。
{{ selected }}の部分に選択した内容が表示される。

~~~html:sample.html
...

{{ form.select_sample }}
<button type="submit">更新</button>

{{ selected }}

...
~~~
Ruby クラスとインスタンス

# クラスとインスタンス

## クラスは個別の値(データ)を作るための雛形。
値の元となるもの。値の共通のルールを定義します。
よく設計図に例えられます。（ひな形、〇〇の設計図など。）

クラスの定義
```ruby
class クラス名

end
```
※クラスは大文字から始めます。


## インスタンスはクラスをもとにして作られる「データ」のことです。
クラスから作られた個別の値(データ)のこと。
クラスが定義した共通の属性やメソッドをインスタンスは持ちます。
実態を持ちます。

クラス（設計図）を元に、インスタンス（実態）を作るということ。
クラスは設計図なので、実際に何か行うには、クラスから実態であるインスタンスを作る必要です。

インスタンスは、クラスが使用できる***newメソッド***を実行し、生成します。

## newメソッド
newメソッドは、使用したクラスのインスタンスを生成して返す役割があります。
以下のようにして、インスタンスを生成し変数で扱います。
```ruby
変数名 = クラス名.new
```

<br>
例

```ruby
class Takoyaki

end

takoyaki = Takoyaki.new
```
たこ焼きを作る例で書きました。
たこ焼きは、たこ焼き器を使うと便利ですね。
この場合だと、たこ焼き器というクラスから生まれた、インスタンスがたこ焼き（実態）ということになります。
class~end　でクラスの定義をしており、Takoyakiはたこ焼き器にあたります。
newメソッドを使ってtakoyakiというインスタンスを作成しています。
循環参照

# 循環参照
Flaskの循環参照について調べたのですがあってるのか謎

```python:app.py
# app.py
from flask import Flask
import db

app = Flask(__name__)
db.init_app(app)
```

```python:db.py
from flask import current_app
from flask_sqlalchemy import SQLAlchemy
import app ←app.pyをインポート

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy()
```

app.py で db.py をインポート (import app) しないとdbが定義されていないことになるので、エラーがでます。
その為import dbをする事でdb.pyを読み込みますがそこでdb.pyでappが定義されている為app.py をインポート (import app) すると、
app.py の ```import db``` 行で db.py をインポート
db.py の ```import app``` 行で app.py をインポート

つまりimport文にて app.py(import dbを読み込む)→db.py(import appを読み込む)→app.py(import dbを読み込む)→db.py(import appを読み込む)
といった形でimportで繰り返し処理がされてしまう。
Visual Studio 2017 Express ダウンロード

マイクロソフトはVisual Studio 2017 Expressの公開を中止したらしいので、
下記のURlからダウンロードできました。

https://download.visualstudio.microsoft.com/download/pr/473f1a59-e5bc-4332-8f76-5ff45df9cd24/c21d455200a01dec730482f03256ed0877861a7344d8d26169f5515c1bbd7805/vs_WDExpress.exe
Laravelでアプリを作成してみた【ミニ受注入力システム】

## 環境開発の作成

①ターミナルを起動し、プロジェクトフォルダーを作成する

```
mkdir <project>
cd <project>
```
②次にルートフォルダにファイルを作成し、内容（dockerの構成）を以下にする
docker-compose.yml
Dockerfile

```docker-compose.yml
version: '3.7'

services:
  php:
    build: .
    volumes:
      - ./src:/var/www/html
    ports:
      - '8000:8000'
  mysql:
    image: mysql:5.7
    ports:
      - '3306:3306'
    volumes:
      - ./db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: laravel
```

```
//Dockerfile

FROM php:7.4-fpm

COPY --from=composer:1.10.12 /usr/bin/composer /usr/bin/composer

RUN apt-get update && apt-get install -y zip unzip

RUN docker-php-ext-install pdo pdo_mysql
```

## 開発環境立ち上げ

```
//terminal
docker-compose up -d
```
コンテナが起動したら成功

```
Creating laravel_todo_mysql_1 ... done
Creating laravel_todo_php_1   ... done
```

```
//terminal
docker ps
```
下記のようにPHPとMySQLコンテナが立ち上がっていれば環境構築成功

```
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
dc165c1c61af        mysql:5.7           "docker-entrypoint.s…"   18 seconds ago      Up 18 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   laravel_todo_mysql_1
f01498ef3163        laravel_todo_php    "docker-php-entrypoi…"   18 seconds ago      Up 18 seconds       0.0.0.0:8000->8000/tcp, 9000/tcp    laravel_todo_php_1
```

## Laravelインストール

```
docker-compose exec php composer create-project --prefer-dist "laravel/laravel=6.*" .
```
下記メッセージで成功
```
> @php artisan key:generate --ansi
Application key set successfully.
```
開発サーバー立ち上げてインストールされているか確認

```
docker-compose exec php php artisan serve --host=0.0.0.0 --port=8000
```





## 参考サイト
[Webアプリケーションを作りながら覚える！！#1 LaravelとBootstrapで作るTodoアプリケーション開発（環境構築編）](https://www.youtube.com/watch?v=KG4qoj8rkAU)
VSCodeでSpringBootアプリの環境構築をやってみた

Javaに触れようと思い、まずは環境を構築しないと、と考えていた矢先、

「簡単なSpringBootWebアプリケーションを作成し、それをローカルにテストする為に必要な手順」が解説されているWebページをいくつか見かけたので、実際にVSCodeでも試してみました。


事前準備として、私は必要なツールを揃えるところから始めました。

・エディターまたは統合開発環境 (IDE) ：Visual Studio Code
・<b>Extension Pack for Java（VSCode拡張機能）
・Spring Boot Extension Pack（VSCode拡張機能）</b>
・JDK（Java 17）　　　https://www.oracle.com/jp/java/  　：端末にインストール

・端末環境：Ubuntu / Linux 用 Windows サブシステム(WSL2推奨)
・git

参考）VS Code を使用してコンテナーでの開発をする場合
<a href="https://code.visualstudio.com/docs/devcontainers/containers#_installation" target="_blank">https://code.visualstudio.com/docs/devcontainers/containers#_installation</a>


[手順]：VSCodeでSpring Boot アプリを作成する

まず、VSCodeでコマンドパレットに「Spring Initializr」 コマンドを入力し、Spring Boot のWeb開発用プロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2355311/ed69654a-2c32-0b14-40e6-66b338444227.png)
Project:Maven Project ／ Language:Java ／ GroupID：com.example
ArtifactID：demo ／ PackagingType:Jar ／ Java version:17

依存関係はここでは、以下の４つを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2355311/9c09c560-8da1-875c-e842-5d8df15846f4.png)
次に、OpenJDKをインストールします。
WSL環境でOpenJDKを設定する場合、ターミナルで

```
＄sudo apt-get install openjdk-17-jdk
```
と入力し、以下のURLページの設定をしてください。
参考URL：https://kontext.tech/article/621/install-open-jdk-on-wsl

次に、ControllerとViewを作成して、Hello Worldを画面表示していきます。


```java:DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@GetMapping("/")
	public String helloWorld() {
		return "index";
	}
}

```

```java:src/main/resources/templates/index.html
<html>
  <head>
    <meta charset="UTF-8" />
    <title>hello world</title>
  </head>
  <body>
    <p>Hello World</p>
  </body>
</html>
```

demoプロジェクトを右クリック⇒Run して「localhost:8080」でHello Worldと表示されるのを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2355311/9c71215a-c9c1-344c-ed32-ca359956af06.png)
出来ました！


今後、VSCodeでもSpringBootアプリケーションの開発をしていけると良いなと考えています。

以上となります。
【備忘録】DBeaverでDBをdumpする2つの方法

## 概要
DBeaverの機能を利用してDBをダンプする機会があったので、試した方法2つを整理した。

## 環境

MySQL: mysql8.0.26(Dockerコンテナを利用)
DBeaver: バージョン22.3.0.202212070729

## 試したこと
### 1. SQLの生成とデータのエクスポートを併用

SQLの生成機能:
- テーブルを右クリックで選択後、SQLの生成→DDLを選択

![スクリーンショット 2023-01-27 13.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/6fc2a40c-bf3d-8e55-fbff-be5b0cb89c27.png)

- 以下のように、`CREATE TABLE`文が表示され、コピーして利用できる(複数テーブル選択時は、複数テーブル用のSQLがコピーできる)
```sql
-- database.test definition

CREATE TABLE `test` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` timestamp NOT NULL,
  `updated_at` timestamp NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
```


データエクスポート機能:
- テーブルを右クリックで選択後、データエクスポートを選択
![スクリーンショット 2023-01-27 13.20.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/d75bc89c-8599-9e3e-6a4e-0955163edd26.png)

- 以下のような`INSERT`のSQLをファイルとして出力できる(1テーブルずつ別々に出力)

```sql
INSERT INTO database.test (created_at,updated_at,description) VALUES
	 ('2023-01-27 12:00:00','2023-01-27 12:00:00','説明'),
	 ...
```


上記2つの機能を併用することで、各テーブルのスキーマ作成、データ挿入用のSQLを用意できる


### 2. Dump databaseを利用
- データベースを右クリックで選択後、ツール→Dump databaseを選択
![スクリーンショット 2023-01-27 14.05.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2427362/96d6bbf3-9fe1-5368-e53a-7bef53f1a38c.png)

- 1の方法で作成した`CREATE TABLE`と`INSERT`が全テーブル分1ファイルにまとまって出力される
```sql
DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` timestamp NOT NULL,
  `updated_at` timestamp NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO database.test (created_at,updated_at,description) VALUES
	 ('2023-01-27 12:00:00','2023-01-27 12:00:00','説明'),
	 ...
```


## 各方法の利点と欠点

### 1.SQLの生成とデータのエクスポートを併用
- 利点:スキーマとデータをわけて利用したい場合には手軽に利用できる
- 欠点:出力がテーブルごとなので、出力を1ファイルにまとめたい場合はむいていない

### 2.Dump databaseを利用
- 利点:出力が1ファイルにまとまるので、ファイルの配布、利用が楽
- 欠点:データ量によってはDBeaverのSQLエディタなどからSQLを実行することが難しい(処理落ちする)
AWS EventBridge 用語まとめ

# 概要

- EventBrigdeの自分がわからなかった用語を簡単にまとめる。

# 内容

## イベント

- AWS内部、またはAWSのパートナーサービスやアプリケーション、顧客が作っているサービスやアプリケーションなどでの環境変化のこと。

## ルール

- 後述するイベントバスに紐付け、受信したイベントをマッチングし評価する。
- ルールの定義の事をイベントパターンと呼ぶ
- 要するに、どんな条件で後述するターゲットを起動するかの条件を決める。

## イベントバス

- イベントを受信するパイプラインのこと。
- イベントバスに関連付けたルールによって受信したイベントを評価するらしい。

## ターゲット

- イベントバスで受信したイベントがルールで定義されたイベントパターンに実行するリソース、もしくはエンドポイントのこと。

# 雑な図示

![private__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b414c00b-5c7b-7966-487e-7a176ef4f252.png)


# 参考文献

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-events.html

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-event-bus.html

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-rules.html

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-event-patterns.html
neosでlogix その99

# 概要
neosでlogixやってみる。
logixを、俺コードで表現してみる。

# 参考にしたページ

https://qiita.com/ohisama@github/items/1fc82e1babb470206541


# 俺コード

```
String = Timer 1 do
	Int.pc
	|> Multiprexer 2 3 4 6 5 1 0
	|> ImpluseMultiprexer Int.pc do
		a = Int.pc 
			|> Multiprexer 0 100 0 0 0 1 0
		case do
		0:
		1:
			If Int.c > 0 do
				a
				|> Write Int.pc
			end
		2:
			a
			|> Write Int.b
		3:
			a
			|> Write Int.c
		4:
			Int.b
			|> + 1
			|> Write Int.b
		5:
			Int.c
			|> - 1
			|> Write Int.c
		6:
			String
			|> + ToStr(Int.b)
			|> Write String
		end
	end
	|> + 1
	|> Write Int.pc
end


```

以上。
APIテストツールのInsomniaで、ログインしてトークンを取ってからリクエストさせるようにする

APIのテストツールのInsomniaで、ログインしてトークンを取ってからリクエストさせるようにさせます。

Insomniaを始めとしたテストツールでは環境変数にログイン情報やAPIキーを入れておくことで、認証付きのリクエストも送ることができます。

ですがリクエストしたいAPIが一時的なアクセストークンを必要としている場合、トークンの有効期限の都度、取得し直す必要があります。

Insomniaではリクエストを送る際、別のリクエストを使ってトークンを取得し、その結果をそのリクエストに入れて送信することができます。

# ログインリクエストの作成
まずはトークンが取れるようにログインリクエストを作成します。
大体のシステムで必要なものは

- ログイン用URL
- ユーザーID
- パスワード

です。
Insomniaでリクエストを作成し、必要な情報を埋めます。

この例では `/auth/v1/token` というエンドポイントに `POST` でリクエストを行い、JSONでIDとパスワードを入れる、というものでした。

![Screenshot 2023-01-27 at 13.50.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/797fa9aa-1141-964f-02f0-40e16f318f12.png)

IDとパスワードは環境変数を使っています。

実際にリクエストを組み立てる場合には実システムの通信を確認し、どういった内容で送るかを確認しておきます。

Insomniaからリクエストを送ってトークンが取れることを確認します。

![Screenshot 2023-01-27 at 13.54.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/83585d0c-26b5-4f67-387d-6978f8d374b8.png)

この例では

```json
{
  access_token: "xxxxxxx",
....
}
```

として、直下の `access_token` でトークンが取れていることを確認しました。


## 使いたいリクエストの作成
実際に送りたいリクエストを作成します。こちらのリクエストも、トークンを送るヘッダー名を確認しておきます。この例では `authorization` というヘッダーに `Bearer` で始まる文字列にトークンを入れていました。[^1]

[^1]: https://ja.wikipedia.org/wiki/Bearer%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3


`Auth` タブから `Bearer` を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/ce8264e9-763e-6d4d-35ed-c46851b88190.png)

この `TOKEN` に先ほどのリクエストの戻り値を使いたいため、`TOKEN` の箇所で `CTRL+Space` を押します。

そうすると利用できる特殊な変数などが表示されます。
真ん中より少し下にある `Response => Body Attribute` を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/8b213f8c-cb78-6f80-a1da-32f0691cf568.png)

選択した直後は文字が赤いのですが、これをクリックするとポップアップが開いて編集することができます。

![Screenshot 2023-01-27 at 14.00.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/fca9a617-2426-34a6-558f-e4f73c72963c.png)

それぞれの項目を埋めていきます。

![Screenshot 2023-01-27 at 14.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/cd20e1fa-14ad-a028-8b6e-22ea3366a355.png)


設定名 | 説明
---|---
Function to Perform | Response （他のレスポンスを参照）を選びます
Attribute | Body Attribute （レスポンスボディの属性を利用）を選びます
Request | 先ほど作成したトークン取得のリクエスト名を指定します。ここでは `POST Login(Get Access Token)`
Filter (JSONPath or XPath) | 利用するトークンをJSONPath もしくは XPath で指定します。
Trigger Behavior | トークン取得を利用する頻度を選びます。都度取りに行くこともできますが、ここでは When Expired（期限が切れたら取得）を選択しました。
Max age | 期限切れ前に利用すると判断する最大の秒数を指定します。
Preview | 取得される内容がここにプレビューされます。かなり便利！

### JSONPath もしくは XPath
ここでは `$.access_token` としました。
利用方法はこちらを参考にしました。

https://qiita.com/takkii1010/items/0ce1c834d3a73496ccef


### 動作確認
ここまでできたら動作確認を行います。

無事にリクエストがされていたら成功です。


## 参考ページ

https://www.ankursheel.com/blog/automatically-set-access-token-authenticated-requests-insomnia