OmniAICreator/Qiita-1.07M huggingface dataset:
VSCode Tunnel で ECS Fargateのコンテナに接続

# ECS Fargate のコンテナに VSCode Tunnel で接続

接続できると、下記のように `ECS Fargate`のコンテナ内を ローカルの VSCode でファイル編集・シェル実行できるようになります。

![スクリーンショット 2023-07-31 16.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/1d31875a-2ba0-f727-e85e-4e4cfab1b008.png)

# 目的

ECS Fargate のコンテナ内に接続し、VSCode から編集

# 前提条件

## 1. (Must) curl か wget が使用できる ECS Fargate コンテナ

## 2. (Must) Github アカウント必要(認証)

## 3. (Must) [Remote Tunnels](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-server)

![スクリーンショット 2023-07-31 16.54.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/bc2e12d7-cc14-ff0e-0fe6-e0a721efc76f.png)

## 4. (Option) [AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode)

![スクリーンショット 2023-07-31 17.07.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/ba465daa-d7e2-a6ed-6dd0-d1a181ba12c6.png)

Option については、`ecs fargate exec` ができれば OK です。

# 接続手順

## 1. ECS Fargate(リモート) 側で VSCode CLI インストール

※ `ecs fargate exec`　で コンテナの中に入るか、`dockerfile`に書くでもいいです。

```sh
curl -Lk 'https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-x64' --output vscode_cli.tar.gz;
tar -xf vscode_cli.tar.gz;
```


## 2. Tunnel 作成

```sh
./code tunnel;
```

## 3. Github 認証

ブラウザで `https://github.com/login/device`にアクセスして、コード入力

※ 入力コードは、`./code tunnel`実行したターミナルに表示されてます

- 認証画面

![スクリーンショット 2023-07-31 17.19.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/2e84c5fd-12ec-de08-1885-51523ed21386.png)

↓

![スクリーンショット 2023-07-31 16.09.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/14a9dbfc-bb2d-a5d6-882b-572cb93b3827.png)

↓

任意の tunnel 名入力

## 4. VSCode の拡張でアクセス

![スクリーンショット 2023-07-31 17.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/8150f9e6-189a-6524-09eb-3e70a11ee8b2.png)

Remote Explorer
↓
REMOTES(TUNNELS/SSH)
↓
先程任意の tunnel 名をクリック
↓
`Connect in Current Window` or `Connect in New Window`

※ コマンドパレットで`Connect to Tunnel`でも実行できます ↓

![スクリーンショット 2023-07-31 17.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/5d2c201b-5e14-43a3-8d75-3a7129bad376.png)

# 接続解除手順

- リモート側で、`./code tunnel unregister`
- VSCode から 右クリックで`Unregister Tunnel`

![スクリーンショット 2023-07-31 16.19.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/9e9a2023-8d4a-57a4-586b-a415ae00910e.png)

# メリット

- セキュリティグループに SSH 用のポート開ける必要なし
- ローカルの VSCode で fargate 内部を編集（Vim インストール必要なし）

# 参考

- https://code.visualstudio.com/docs/remote/tunnels

# 注意

- 検証したコンテナは`Public Subnet`に配置されたECS Fargateで検証しました。`Private Subnet`に配置されたコンテナでは未検証です。
- 未検証ですが、EC2でも可能だと思います。
【Go】値レシーバーとポインタレシーバーの実装比較

# ポイント
値レシーバー： 値を更新しない。
ポインタレシーバー：値を更新する。

# 実装例
- 値レシーバー
```go:main.go
package main

import "fmt"

type Rectangle struct {
    width  int
    height int
}

// 値レシーバーを持つメソッド
func (r Rectangle) Area() int {
    return r.width * r.height
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    fmt.Println("Area:", rect.Area()) // Area: 50

    // メソッド内で値を変更しても、元のオブジェクトには影響しない
    rect.width = 20
    fmt.Println("Area:", rect.Area()) // Area: 50
}

```

- ポインタレシーバー
```go:main.go
package main

import "fmt"

type Rectangle struct {
    width  int
    height int
}

// ポインタレシーバーを持つメソッド
func (r *Rectangle) DoubleSize() {
    r.width *= 2
    r.height *= 2
}

func main() {
    rect := &Rectangle{width: 10, height: 5}
    fmt.Println("Width:", rect.width, "Height:", rect.height) // Width: 10 Height: 5

    // メソッド内でオブジェクトの値を変更する
    rect.DoubleSize()
    fmt.Println("Width:", rect.width, "Height:", rect.height) // Width: 20 Height: 10
}

```
[AWS Q&A 365][StepFunction]AWSのよくある問題の毎日5選 #101

# 1. ワークフロー・スタジオがワークフローを保存する際の制限は何ですか？
回答: ワークフロー・スタジオは自動的にワークフローを保存しないため、ユーザーはAWSコンソールのタイムアウトにより進捗が失われるのを避けるために、頻繁に作業を保存する必要があります。

# 2. ワークフロー・スタジオはInternet Explorer 11をサポートしていますか？
回答: いいえ、ワークフロー・スタジオはInternet Explorer 11をサポートしていません。ワークフロー・スタジオを使用中に問題が発生した場合、ユーザーは別のブラウザを使用することを推奨します。

# 3. ワークフロー・スタジオを使用するための前提条件は何ですか？
回答: ワークフロー・スタジオを使用するには、ユーザーはAWSアカウントと、使用したいリソースに必要な権限を提供する資格情報が必要です。

# 4. ワークフロー・スタジオの主なインターフェースコンポーネントは何ですか？
回答: ワークフロー・スタジオの主なインターフェースコンポーネントは、ステートブラウザ、キャンバス、インスペクターパネルです。

# 5. ユーザーはローカル開発またはAWS CloudFormationのためにワークフロー・スタジオから生成されたコードをエクスポートできますか？
回答: はい、ユーザーは作業の検証と必要な調整を行った後に、ワークフロー・スタジオから生成されたコードをローカル開発またはAWS CloudFormationのためにエクスポートすることができます。
[AWS Q&A 365][StepFunction]Daily Five Common Questions #101

# 1. What is the limitation of Workﬂow Studio when it comes to saving workflows? 
Answer: Workﬂow Studio does not automatically save workflows, which means users need to save their work frequently to avoid losing their progress due to an AWS console timeout. 

# 2. Can Workﬂow Studio support Internet Explorer 11? 
Answer: No, Workﬂow Studio does not support Internet Explorer 11. Users are advised to use a different browser if they encounter issues while using Workﬂow Studio. 

# 3. What are the prerequisites for using Workﬂow Studio? 
Answer: To use Workﬂow Studio, users will need an AWS account and credentials that provide the necessary permissions for any resources they want to use. 

# 4. What are the main interface components of Workﬂow Studio? 
Answer: The main interface components of Workﬂow Studio are the states browser, the canvas, and the inspector panel. 

# 5. Can users export the generated code from Workﬂow Studio for local development or AWS CloudFormation? 
Answer: Yes, users can export the generated code from Workﬂow Studio for local development or AWS CloudFormation after validating their work and making necessary adjustments.
EC2インスタンス内ソースコードをgithub push時に自動更新するために試したこと

github actionsでec2内ソースコードを更新出来るようにしました。

git pullだと同じ認証でも失敗するのでgit cloneで今は更新しています。

（プライベートリポジトリだからいいけどPATを直書きしないとssh後のshellの処理で失敗するのがタマにキズ）

## 事前準備

githubで動作させたいリポジトリのsetting→actions→secretの画面まで移ってから

SSH_PRIVATE_KEY=接続対象のec2インスタンスのssh秘密鍵情報を入力
SERVER_HOST=接続対象のec2インスタンスのホストipを入力
SERVER_USER=接続対象のec2インスタンスのユーザを入力
SERVER_DIRECTORY=ソース展開ディレクトリを入力（/var/www）



```
name: Deploy to EC2

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Set up SSH
      run: |
        mkdir -p ~/.ssh/
        echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts

    - name: Deploy
      env:
        GIT_SSH_COMMAND: ssh -o StrictHostKeyChecking=no
      run: |
        ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} "rm -rf ${{ secrets.SERVER_DIRECTORY }}/html && git clone -b main --depth 1 https://<PATを直接入力> ${{ secrets.SERVER_DIRECTORY }}/html"

```


参考：AWS(EC2)への自動デプロイをDeployerからGitHub Actionsに移行する
https://qiita.com/nakaji0210/items/5b609cb952e2dd5a88d1
[C#][備忘録]ビルド時に不要な言語フォルダが出力されないように設定する

# はじめに

C#でアプリケーションを開発中、ビルドをすると、不要な言語フォルダおよびアセンブリファイルが出力される問題に遭遇しました。
その解消を行った備忘録です。

## 環境

- アプリケーションのターゲットフレームワーク：.NET6
- 開発ツール：Visual Studio 2022

## 問題の詳細

使用しているNuGetパッケージのバージョンを上げたところ、本現象が発生しました。
今回`en`フォルダは英語リソースを作成しているため必要なのですが、以下の画像のように、不要なその他の言語のフォルダが出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562946/c3f5c29e-db0e-de43-baee-2806819e6032.png)

また、各フォルダには、以下のファイルが出力されていました。
`System.Private.ServiceModel.resources.dll`

そのため、ライブラリで参照しているNuGetパッケージ（System.Private.ServiceModel）で、ローカライゼーションを有効にしたのが原因のようです。

## 解消方法

以下を参照すると、リソースのサテライトアセンブリを含むNuGetパッケージを参照するプロジェクトにおいて、`SatelliteResourceLanguages`プロパティに言語を指定することで、必要な言語のサテライトアセンブリのみを出力できるようになるようです。

https://learn.microsoft.com/ja-jp/dotnet/core/project-sdk/msbuild-props#satelliteresourcelanguages

>多くの NuGet パッケージには、ローカライズされたリソースのサテライト・アセンブリがメイン・パッケージに含まれています。ローカライズされたリソースを必要としないこれらの NuGet パッケージを参照するプロジェクトでは、ローカライズされたアセンブリによってビルドとパブリッシュの出力サイズが不必要に増大する可能性があります。プロジェクト・ファイルに SatelliteResourceLanguages プロパティを追加すると、指定した言語のローカライズされたアセンブリのみがビルドおよびパブリッシュ出力に含まれるようになります。

以下のように、プロジェクトファイルで出力したい言語を`SatelliteResourceLanguages`プロパティに指定します。
この場合、`en`が指定されていますので、英語の言語フォルダおよびリソースファイルのみが出力されるようになります。また、`;`区切りで複数言語を指定できます。

```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
  </PropertyGroup>
...
</Project>
```

サテライトアセンブリが無い場合は、言語でない無効な文字列を指定すると、出力されなくなります。

```xml
  <PropertyGroup>
    <SatelliteResourceLanguages>_</SatelliteResourceLanguages>
  </PropertyGroup>
```

以下のように、`SatelliteResourceLanguages`に何も指定が無いと、すべての言語フォルダが出力されます。

```xml
  <PropertyGroup>
    <SatelliteResourceLanguages></SatelliteResourceLanguages>
  </PropertyGroup>
```

# さいごに

簡単なプロジェクトの設定で解消できてよかったです。
Japan AWS Jr. Champion活動記録 Vol.2

## はじめに
本務の開発でバタバタしていて、7月の投稿になってしまいましたが、AWS JAPAN Jr. Championとしての6月の活動について書いていきます。6月は、Jr. Champions有志による自主勉強会とJr. Champions LTが開催されました。

↓ 前回の記事はこちら ↓

https://qiita.com/am_i-12/items/72adf43772a7359730b4

## Japan AWS Jr. Champion Partner Programとは
> [「Japan AWS Jr. Champion Partner Program」](https://aws.amazon.com/jp/blogs/psa/2023-aws-jr-champions/)とは、AWS Partner Network (APN) 参加企業に所属し、現在社会人歴 1 ～ 3 年目で AWS を積極的に学び、アクションを起こし、周囲に影響を与えている APN 若手エンジニアを選出しコミュニティを形成する、日本独自の表彰プログラムです。本プログラムでは、AWS に関して実践してきた技術的な挑戦や、コミュニティのリードなど自ら起点となって周囲に影響を与えているか、アウトプットを通じて周囲へ貢献しているか、という観点が評価の対象になります。2023 Japan AWS Jr. Champions に選出された方は、一定の技術力があり、社内の AWS コミュニティをリードでき、今後は Japan AWS Top Engineers そして Japan AWS Ambassadors になることが期待される皆様です。

2023年は[82名が選出](https://aws.amazon.com/jp/blogs/psa/2023-japan-aws-jr-champions/)されており、これから1年間Japan AWS Jr. Championsとして活動していきます。

AWS Summit Tokyoの表彰時に撮影した集合写真
![img_7571_720.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/b6c165ed-6033-741d-c32c-2338b9be42fe.jpeg)


## Jr. Champions自主勉強会
有志による自主勉強会が立ち上がり、6/9に初回が開催されました。AWS目黒オフィスとオンラインでハイブリッド開催で、50人以上が参加していました。初回は企画者の方の発表で、「Controll Towerで社内にサンドボックス環境を立てよう！」という内容で発表が行われました。

#### 感想
この自主勉強会は、Jr. Championsに選ばれたころから、さすがJr. Championsといわれる何かを行いたくて企画したということで、まずはその行動力に感服しました。Controll Towerを初めて聞いた私でしたが、内容を聞くと「自分でもできそう！」と思うくらい気軽に使い始められそうな印象を抱きました。発表の中でaws-nukeによるリソースの掃除についても学ぶことができ、大変勉強になりました。これからも月1ペースで開催されるとのことなので、楽しみです。

## Jr. Champions LT

オンラインにて、Jr. Championsのプレゼン会が開催されました。

**＜ プレゼンの前に、、 ＞**
Project LeadのYukkiさんからアナウンスメントがありました。
特に強調されていたのがアウトプットの重要性です。Jr. Championsの制度は、2023年に始まったばかりでまだ知名度が低いため、アウトプットで存在をアピールしていきましょう！とのことでした。

アウトプットの具体例として、[JAWS-UG](https://jaws-ug.jp/)での登壇を挙げられていました。AWSでJAWSをサポートしている[沼口さんの記事](https://note.com/s_numaguchi/)も要チェックとのことです！


#### LTの流れ
前回のKickOffにて、AWSについての早押しクイズが行われ、戦いを制した7名によってプレゼンが行われました。発表された内容は以下です。
* Amazon Connectの紹介
* Amazon SageMaker Studio Labの紹介
* Caution! s3BucketからLock out!
* 入社してからのAWS遍歴
* AWSシステムサンセットの課題。あなただったらどうする!?
* MWAAとは
* AWSのコスト最適化に関する施策発表

#### 感想
皆さん同じAWSを使っていながら、取り組んでいるプロジェクトや使っているリソースは様々なんだなと勉強になりました。発表者はエンジニアだけでなく、コンサルやSIerの方もいらっしゃって、2つのステークホルダーのすり合わせした事例や、コールセンターをAmazon Connectでクラウド化するなど、普段なじみのないProjectのお話が聞けて興味深かったです。
また、さすがJr. Championsに選ばれるだけあって、皆さん本務以外にもAWS関係のイベント登壇、ブログ執筆、社内プロジェクト参画など、精力的に活動されているのも印象的でした。これからの活動でも、プレゼンのイベントが多くあるので楽しみです！


## 6月の活動全体の感想
6月の活動では、Controll Tower、Amazon SageMaker Studio Lab、MWAAなど、知らないサービスを沢山知ることができて楽しかったです。
自分が知っているAWSのサービスは、資格勉強でかじったり、自社で使ったりしているものに偏ってて、一部だったことが分かりました。引き続きインプットとアウトプットを重ねて、AWSに関する知識を付けていきたいです。
pythonでAWS Lambda のレイヤー機能を利用する

# はじめに

前回、pythonでAWS Lambda を業務利用で量産するにあたって、自分があると便利だと思うクラス構成の雛形を記事で公開しました。

今回は、その続編です。
（前回はこちら）

https://qiita.com/Syoji_Yonemoto/items/7e8a7668358798656932

基底クラス達を、レイヤーに登録して複数Lambda関数から使いまわすと便利なので、レイヤー機能へ登録するためのメモ書きです。


# 公式ドキュメント

別言語（NodeJS）でもレイヤー機能を使ってるのですが、よくドキュメント迷子になるので、重要なページをメモ書き。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html#configuration-layers-path

＜抜粋＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/55deb790-40e6-9c36-f489-f3110970ab97.png)

上記の、「パス」の情報がレイヤー機能を利用する上では、非常に重要なので、引用しておきます。

# 一言メモ
AWS Lambdaを、ちょっと使った事ある人なら当然ご存知な事かもしれませんが、デプロイする時のZipに含む階層構造が重要になってきます。
python のレイヤー機能では、python のパス（ディレクトリ）を含めて、Zipを作ればという事ですね。

# 具体例

前回の基底クラスをレイヤーで利用する際に、どんなディレクトリ階層にして登録したら良いかを書いておきます。
（この階層用意の仕方と、Zipの作り方の紐づけが、なかなか説明されない罠どころ）

```
（ソース管理用のディレクトリ名：フリー命名）
　　　　　　L  python
　　　　　　　　　　 L  abstract_base_common.py
```

と、このように「python」ディレクトリを１つ噛ませておくことが重要です。

```shell
cd （ソース管理用のディレクトリ名：フリー命名）
zip -r Layer01.zip  ./python
```

Zipを作るときは、カレントディレクトリ（現在のディレクトリ）を、（ソース管理用のディレクトリ名：フリー命名）に移動して、配下の「python」ディレクトリごと圧縮することが大事です。
※ 解凍したときに、「python」が直下に展開されるようにZipを作る。

# まとめ
AWS管理コンソールでの手順や権限回りは他所でもイロイロ書かれているので、レイヤー機能を使うにあたって、あまり言及されない階層構造の用意の仕方や、Zipの作り方に言及しました。

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

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

https://www.cs-cloud-aid.com/
【LINE & GAS】ゴミ捨ての日を忘れないようにLINEで通知してみた

# 作った理由
夏の暑い時期になると当然喉が渇くのでペットボトル飲料の消費が多くなる。
そのため週に一度のペットボトルのごみの日を逃がそうものなら、部屋が空のペットボトルで溢れてしまう。
何度かやらかしたので忘れないように前日にLINEで通知するようにした。

# 出来たもの
スプレッドシートに記載した日付の前日夜にLINEで通知が来るようにした

## LINEの通知
![image0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126452/dd2bdc4c-2683-dcf3-eaae-afdff4904572.jpeg)

## スプレッドシート
![スクリーンショット 2023-07-31 163114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126452/66e1b847-7b1a-59bb-ef3b-154267d7d9dd.png)

## コード
```php
// LINE Notify アクセストークン
const LINE_ACCESS_TOKEN = "*********";  

function myFunction() {
  // アクティブシートを取得して変数sheetに格納
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  var today = new Date();
  var tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); // 実行日翌日の日付を取得
  tomorrow.setHours(0, 0, 0, 0); // タイムスタンプを0時0分0秒に設定

  // 日付の範囲内でゴミの情報を検索
  var dataRange = sheet.getDataRange();
  var dataValues = dataRange.getValues();
  var garbageInfo = '';

  for (var i = 1; i < dataValues.length; i++) {
    var date = new Date(dataValues[i][0]);
    if (date.getTime() === tomorrow.getTime()) {
      
      garbageInfo = dataValues[i][2];
      break;
    }
  }

  if (garbageInfo) {
    const options = {
      method: "post",
      payload: "message=明日は" + garbageInfo + "の日です",
      headers: {
        Authorization: "Bearer " + LINE_ACCESS_TOKEN
      }
    };
    UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
  }
}
```

# 参考記事
https://qiita.com/aimy_app/items/1bc392e371f8038cf5b3
初心者が久々にCharlesを使おうとしてハマったときの対処法（macOS）

## ~~3~~ 4行まとめ

* Charles の証明書は発行から1年間しか使えないので、期限切れになっていたら再発行が必要
* 期限切れの証明書が見当たらなければ キーチェーンアクセス > 表示 > 有効期限の切れた証明書を表示 で探す
* 再発行は Charles の Reset Charles Root Certificate から
* iOS のプロファイルの有効化には「VPNとデバイス管理」と「証明書信頼設定」の2つが必要

## 問題１：Charles Help > SSL Proxying > Install Charles Root Certificate ができない

症状： キーチェーンアクセス.app は起動するものの Charles の証明書が見つからない

### 確認：キーチェーンアクセス 表示 > 有効期限の切れた証明書を表示 してみよう

「表示」メニューから有効期限切れの証明書の表示/非表示を切り替えられるのですが、私の場合「非表示」になっていたので上述の症状になっていたようです。
「表示」にしてからキーチェーンアクセスの右上の検索フォームから「Charles」などと入力すると見つけられました。

## 問題2：Charles の証明書・プロファイルが期限切れ

症状： キーチェーンアクセス.app に入れた証明書や iOS 端末にインストールしたプロファイルが期限切れになっていて、プロキシがうまく動かない

### 確認： Reset Charles Root Certificate ... してみよう

期限切れなので新しく作り直したい、ということで **Charles Help > SSL Proxying > Reset Charles Root Certificate ...** からリセットします。
選択すると「証明書を全部再設定しないといけないけどいい？」みたいなことを聞かれるのでOKします。

そこから再度証明書・プロファイルをインストールします。手順は初回のセットアップとほぼ同様です。

* **macOS**
  * **Install Charles Root Certificate** で Mac に証明書をインストールし、キーチェーンアクセス.app で「常に信頼」にする
  * 期限切れの証明書は削除しておく（ログインパスワードの入力が必要でした）
    * 残っているとiOSのプロファイルインストールでエラーになるっぽい？
* **iOS**
  1. iOS 端末を Mac と同じネットワークに接続しておいて、プロキシも設定しておく
  2. 端末の Safari で http://www.charlesproxy.com/getssl を開き、プロファイルをダウンロード
  3. iOS の **設定 > 一般 > VPNとデバイス管理 > 構成プロファイル** で Charles のプロファイルを信頼する
  4. ついでに期限切れのプロファイルは削除しておいた方が無難？
  5. iOS の **設定 > 一般 > 情報 > 証明書信頼設定 > ルート証明書を全面的に信頼する** で 「Charles Proxy CA」を有効にする

## おわり？

Charles・プロキシ全然分からない勢なのでこれでちゃんとできたのかいまいち自信がないですが、対処する前よりは赤い×が減ってて多少は動いている気がする…。

### 参考にした記事

https://qiita.com/usagimaru/items/d340e87da98e62f99b60

https://qiita.com/shtnkgm/items/cd32df0c7b4bd424f107

https://qiita.com/ishigaki_hige/items/cf86d35e13470a543551
Hyper-V VMにUbuntu Desktop 22.04 LTSをインストールしたらGUIが死んでた話。

Hyper-V上の仮想マシンにUbuntu Desktop 22.04 LTSをインストールしたらログイン待ち画面でGUIが応答しなくなったので何とかしたメモ。

## 使ったもの
>Hype-vサーバー　WindowsServer 2019
Ubnutuイメージ　ubuntu-22.04.2-desktop-amd64.iso
仮想マシン状態　第2世代,SecureBoot無効,4CPU,8GBMEM,100GBHDD

## ことの流れ
インストールウィザードに沿って標準インストールが問題なく終了した。
仮想マシンを再起動したところ、ログイン待ちの画面が表示されたが応答しなくなった。なおマウスカーソルもフリーズしたのであった。

ctrl+Alt+F3を押して端末を表示し、現在のカーネルバージョンを確認。
```
$uname -r
5.19.0-50-generic
```
Microsoftのドキュメントを参照してAzureカーネルをインストールしてみる。

>[HYPER-V でサポートされている Ubuntu 仮想マシン](https://learn.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/supported-ubuntu-virtual-machines-on-hyper-v)

```
$sudo apt-get install linux-azure
$sudo reboot 
```

再起動後は正常にログインできた、と思いきやデスクトップで黒帯を表示しフリーズ。
![スクリーンショット 2023-07-31 153735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519401/babb18bf-f6ac-e07e-caa0-d692d5e99e68.png)


またctrl+Alt+F3を押して端末を表示し、現在のカーネルバージョンを確認。
```
$uname -r
5.19.0-50-generic
```
・・・カーネル変わってないじゃん。
なので
```
$sudo apt-cache serach linux-image-5.19.0 | grep azure
  //linux-image までで検索すると結果が大量にでるので現状と同じ5.19で絞り込んでます。
 
$sudo apt-get install linux-image-5.19.0-1027-azure
  //末尾-azureのカーネルをインストール

$sudo update-grub
$sudo reboot
```
そして再起動後は正常に操作できるようになった。
![スクリーンショット 2023-07-31 155226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519401/801493c8-2277-c0ea-7009-715ec3f0cfac.png)


なおカーネルバージョンもちゃんと上がってた。
```
$uname -r
5.19.0-1027-azure
```
　
インストールイメージが更新されれば起こらなくなる現象かもしれないけど残しておく。
ワイヤーフレームと画面設計の違い

順番：ワイヤーフレーム⇒次に⇒画面設計

### ワイヤーフレーム（Wireframe）：
シンプルな線や図形を使って、レイアウトや画面の配置、構造、コンテンツの配置、ナビゲーションの流れなどの設計をスケッチします。
色やフォントなどの詳細なデザイン要素は含まれません。

##### ワイヤーフレームの主な目的：
・デザインのコンセプトを”ビジュアル”に示す。
・アプリやウェブサイトの構造やレイアウトを確認し、”問題点”洗い出す。
・”ユーザーエクスペリエンス”の設計を検討する。

### 画面設計（UIデザイン）：
ワイヤーフレームの後の段階で行われるデザインプロセスです。ワイヤーフレームに基づいて、具体的な”デザイン要素”が追加され、アプリやウェブサイトの実際の外観が形成されます。色、フォント、アイコン、画像などが組み込まれ、視覚的なデザインが完成します。

##### 画面設計の主な目的：
ユーザーインターフェース（UI）のデザインを実装する。
視覚的な魅力を持つデザインを提供する。

=========================================
##### つまり何？
・ワイヤーフレームはアプリの構造や配置を示す初期のスケッチ
・画面設計は具体的なデザイン要素を含んだ最終的なデザイン

##### つまり何のため？
・ワイヤーフレームはデザインのコンセプトや構造を確認するために使用される
・画面設計は実際のデザインを提供するために使用される
[備忘録] visual studioでフォーム間で値をやり取りする方法

# はじめに
<!-- 発端や概要を記載 -->
バイト先で通知をしてくれるアプリを作成している際に、program.csからformに値を送るのに手間取ったので、その時の解決法を備忘録として残します。

# やったこと
form側で関数を作ったりしてみたが、引数を受け渡すことができなかった。

<!-- 各チャプター -->
# 解決法
form自体を呼び出すときに、一緒に変数を送る方法を今回使用した。
```c#:program.cs
Application.Run(new Form1(this.text));
```

```c#:Form1.cs
public partial class Form1 : Form
    {
        string text;

        public Form1(string str)
        {
            text = str;
        }
```
このやり方だと何度のアプリケーション自体を起動し直しているいるので、他にもっと良い解決法があるかもしれない。
RDS で Burst Balance メトリクスが出力される時とされない時の違い

CloudWatch でメトリクス「Burst Balance」が出力される RDS と出力されない RDS があった時に調べたメモです。

###  結論

ストレージが 1000GiB かつボリュームが Nitro System で構成されたインスタンスにアタッチされていたため、バーストが行われず BurstBalance が出力されなかった。

####  gp2 ボリューム
- バーストパフォーマンス
・IOPS性能はI/Oクレジットを使用して最大 3000 IOPS までバーストされる

- ベースラインパフォーマンス
・ベースラインパフォーマンスはストレージで決まる
・ストレージが 1000GiB の場合、ベースラインパフォーマンスは 3000 IOPS になる
- 今回 Burst Balance が出力されない RDS があった理由
・ストレージが 1000GiB 
・既にベースラインパフォーマンスがバーストラインパフォーマンスの最大値 3000 IOPS を超えており、かつ Nitro System で構成されたインスタンスにアタッチされていたため、バーストが行われず BurstBalance が出力されなかった
-  Burst Balance が出力されている RDS があった理由
・ストレージが 600 GiB
・ストレージが 600 GiB の場合はベースラインパフォーマンスが 1800 IOPS になる
・この場合はバーストラインパフォーマンスの最大値である 3000 IOPS を下回っているためバーストが行われ BurstBalance が出力される


以下詳細

###  gp2 ボリュームのパフォーマンス

IOPS パフォーマンス
> ベースライン IOPS パフォーマンスは、最小 100 から最大 16,000 の間で、
> ボリュームサイズの GiB あたり 3 IOPS のレートで直線的にスケールします。
> IOPS パフォーマンスは次のようにプロビジョニングされます。
>
> 33.33 GiB 以下のボリュームは、最小 100 IOPS でプロビジョニングされます。
> 33.33 GiB を超えるボリュームは、最大 16,000 IOPS (5,334 GiB (3 X 5,334) で到達) まで、
> ボリュームサイズの GiB あたり 3 IOPS でプロビジョニングされます。
> 5,334 GiB 以上のボリュームは、16,000 IOPS でプロビジョニングされます。
>
>1 TiB 未満の (および 3,000 IOPS 未満でプロビジョニングされた) gp2 ボリュームは、長期間にわたって必要な場合に 3,000 IOPS にバーストできます。ボリュームのバースト機能は I/O クレジットによって制御されます。I/O の需要がベースラインパフォーマンスよりも大きい場合、ボリュームは I/O クレジットを消費して、必要なパフォーマンスレベル (最大 3,000 IOPS) までバーストします。

ちなみに gp3 ボリューム
###  gp3 ボリュームのパフォーマンス

> gp3 ボリュームはバーストパフォーマンスを使用しません。これらは、フルプロビジョンド IOPS とスループットパフォーマンスを無期限に維持できます。
> gp3 ボリュームは、ストレージの料金に含まれている 3,000 IOPS の一貫したベースライン IOPS パフォーマンスを提供します。
追加料金を支払うことで、ボリュームサイズの GiB あたり 500 IOPS の割合で追加の IOPS (最大 16,000 まで) をプロビジョニングできます。
32 GiB 以上のボリュームに対して最大 IOPS をプロビジョニングできます (GiB あたり 500 IOPS × 32 GiB = 16,000 IOPS)。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/general-purpose.html#gp2-performance
DJI Mavic 2 Pro を自作Androidアプリで自動操縦させる(3)~サンプルプログラムの実行（実行編）~

今回はMobile SDK(Android版)のサンプルプログラムを動かすための準備をします。
[前回の記事](https://qiita.com/shiiiinnooooo/items/32f59f62fdc3ec3f98c0)では、サンプルプログラムを実行するための準備を行いました。

# サンプルプログラムのダウンロード

[このサイト](https://github.com/DJI-Mobile-SDK-Tutorials/Android-ImportAndActivateSDKInAndroidStudio)からサンプルプログラムをダウンロードしましょう。
今回実行するサンプルプログラムは、DJI SDKが正常に実行されることを確認する、というだけのアプリです。

早速ダウンロードしていきます。
下記画像の右上にある緑色の「Code」というボタンを押すと、zip形式でダウンロードできます。
![スクリーンショット 2023-07-31 11.57.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606166/dda8b675-d493-86ee-c2fa-697a4de6fd2b.png)

解凍したフォルダは以下のような階層構造になっています。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606166/f9cd6b03-d6b2-94c6-48fb-e87e030d4a05.png)

解凍したフォルダにあるImportSDKDemoフォルダをAndroidStudioで開きます。
開くと、画面の左上に以下のように表示されると思うので、「AndroidManifest.xml」というファイルを開いてください。
![スクリーンショット 2023-07-31 14.57.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606166/08e1950f-a20d-c0c1-4558-d44c5fdb0362.png)

このファイルの中から、以下のような部分を見つけます。
（今回実行するサンプルプログラムのAndroidManifest.xmlでは、40〜45行目が該当部分です。サンプルプログラムによっては位置が異なる場合があります。）
![スクリーンショット 2023-07-31 14.56.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606166/139ea941-ff9e-b5e4-815e-19c378929cbd.png)

画像内の45行目にある
```
android:value="Please enter your App Key here."
```
の部分に、[前回の準備編](https://qiita.com/shiiiinnooooo/items/32f59f62fdc3ec3f98c0)で用意したApp Keyを入力します。
（App Keyを準備する際の注意点として、APP NameとPackage Nameを合わせないとうまく実行できません。詳しくは前回の記事参照）

以下のように、xxxxxの部分にAppKeyを入力します。
```
android:value="xxxxxxxxxxxxxxxxxxxxx"
```

以上の作業により、サンプルプログラムが実行できるようになりました！

それでは、AndroidStudioでサンプルプログラムをビルドしてみましょう。
実際に実行した際のAndroidの画面は以下のようになっていれば成功です！！
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606166/dc0d2bde-17e2-7579-fcce-075efb7ecca5.png)

これで、サンプルプログラムの実行は終了です。
次回からは、実際にドローンを自動操縦するためのプログラムを作成していきます！
Chakra UIを使いながらもNext.jsのLinkを使いたい！

## この記事でできること
**Chakra UI** の機能を使用しながら [**SPA**（シングルページアプリケーション）](https://digitalidentity.co.jp/blog/creative/about-single-page-application.html) を実現する。

## 解決したいこと
### Next.js の Linkコンポーネント は、Chakra UIの機能を使うことができない
Next.jsでページを遷移するには、Next.jsで用意されているLinkコンポーネントを使用することが推奨されている。

https://nextjs.org/docs/app/api-reference/components/link

この方法でページ遷移するとリロードが発生しない。（SPAが実現できている。）

<font color="Red">**しかし、Next.jsで用意されているLinkコンポーネントはChakra UIの機能を使用することができない。**</font>

## 解決策
### @chakra-ui/next-jsパッケージ の Linkコンポーネント を使用する
Chakra UI の機能を使用しながらSPAを実現する方法として、Chakra UIが **@chakra-ui/next-jsパッケージ の Linkコンポーネント** を用意している。

https://chakra-ui.com/getting-started/nextjs-guide#chakra-ui-with-nextjs-link

このコンポーネントを使用することで、Next.jsとChakra UI、どちらの機能も使用することができる。

:::note
@chakra-ui/next-jsパッケージは、 **Next.js 13 から使用可能** 。
:::
:::note alert
@chakra-ui/**react**パッケージのLinkコンポーネントをインポートしないようにする。（リロードが発生してしまい、 **SPAにならない** 。）
:::

#### 使用方法
インポート文に以下のコードを追加する。
```jsx
import { Link } from '@chakra-ui/next-js'
```

以下のように、JSX内で使用する。
```jsx
<Link href="${ 遷移先のディレクトリ }">${ リンクを与えたいもの }</Link>
```

#### 使用例
サンプルとして「page1/page.tsx」と「page2/page.tsx」を作成し、「page1」から「page2」へ遷移するリンクを作成する。

「page1/page.tsx」に以下のコードを記述する。
```jsx
'use client'

import { Link } from '@chakra-ui/next-js'

export default function Home() {
  return (
    <Container centerContent py={8}>
        <Link href="/page2">page2へ</Link>
    </Container>
  )
}
```

上記のコードを追加すると、以下のような画面になる。
「page2へ」という文字をクリックすると、リロードせずに「page2」に遷移することが確認できる。
![スクリーンショット 2023-06-14 175738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471657/83569766-e458-4f38-6392-b266002e3d03.png)

次にスタイルを設定していく。
先ほど作成したLinkコンポーネントを、以下のように修正する。
```diff_jsx
-<Link href="/page2"                                                        >page2へ</Link>
+<Link href="/page2" px={8} py={3} bg="teal.400" color="white" fontSize={24}>page2へ</Link>
```

Chakra UIの書き方でスタイルを設定できることが確認できる。
上記の例だと、以下のような画面になる。
![スクリーンショット 2023-06-14 180423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471657/ab42bb47-bfd8-6baf-51cd-2c0ab8abbad9.png)

## 参考サイト
- [SPA（シングルページアプリケーション）](https://digitalidentity.co.jp/blog/creative/about-single-page-application.html)
- [Next.js - Linkコンポーネント](https://nextjs.org/docs/app/api-reference/components/link)
- [Chakra UI - Linkコンポーネント（@chakra-ui/next-js）](https://chakra-ui.com/getting-started/nextjs-guide#chakra-ui-with-nextjs-link)
- [Chakra UI - Containerコンポーネント](https://chakra-ui.com/docs/components/container)
- [Chakra UI - Style Props](https://chakra-ui.com/docs/styled-system/style-props)
ゼロからInSpec実行まで60秒

## InSpec インストール(推定15秒)
mac:
```
brew install chef/chef/inspec
```

curl使えるOS:
```
curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec
```

Windows Powershell:
```
. { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; install -project inspec
```
OR
Windows用インストーラをダウンロード：https://www.chef.io/downloads/tools/inspec

## InSpec実行(推定30秒)

```
$ inspec -v
5.21.29
$ inspec exec https://github.com/dev-sec/ssh-baseline.git -t ssh://automate
（※`git clone`ができる環境で実行し、[automate]の箇所をsshできるターゲットノードに変更）
```

## InSpec実行結果確認(推定15秒)

実行結果の一部抜粋↓↓↓
![capture 2023-07-31 14.53.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352042/60937de8-1a36-d04e-fe4f-28457468b5e0.png)

※今回使用しているテストコードはSSHの設定をスキャンするコード。SSHに関連したセキュリティリスクが57個以上検知されている。テストコードのソースは：https://github.com/dev-sec/ssh-baseline 


以上、スクラッチからInSpecの実行、セキュリティ監査を60秒で行うことができました。


---

##### InSpecに関する補足

InSpecはプロファイルと呼ばれるテストコードに基づいてスキャンを行います。特定のOSのCISベンチマークに沿ったプロファイルは、InSpecを公式にメンテナンスしている __Progress社から提供され__ ます。そのため、テストコードを __自前で用意する必要はありません。__ 将来的にCIS公式の基準が変更される場合、適宜Progress社から更新されたテストコードが配布されます。
また、テストコードは __カスタマイズ可能__ であるため自社ポリシーに合わせて __過不足の調整__ をすることができます。
__ライセンスや技術サポートについて詳しくは、連絡先： support@chef-sec.com にお問い合わせください。__ 
(Chef InSpecは、Chefと同様に2019年に無償の商用利用が出来なっています)　

https://www.chef-sec.com/chef_%e6%9c%89%e5%84%9f%e5%8c%96/


www.chef-sec.com

---

## 60秒以上お時間ある方はこちらへ

https://qiita.com/Gorilucky/items/d9318a368be003fec7e4
https通信したいけどACMが認証されずに止まる・503エラーが起きるの対策とか

## お名前ドットコムのドメインを使って手動でACMを承認する

参考：
https://zenn.dev/marumarumeruru/articles/40c33511900e33


1. お名前.comでドメインを買う
お名前.comで独自ドメインを買う
1年間1円とかで買えます

2. AWS Route53でホストゾーン作成
Route53 ホストゾーン作成

ドメイン名　購入したドメイン名
タイプ　パブリックホストゾーン
→ NSレコードとSOAレコードが作成されます
次の手順で、NSレコードに記載してる４個のDNSをお名前.comに設定します
3. NSレコードに記載してる４個のDNSをお名前.comに設定する
ご利用状況　ドメイン一覧
→ネームサーバー 初期設定
→ネームサーバーの選択　その他のサービス
Route53のNSレコードに記載されていた、４個のDNSを設定する
お名前.comに設定してあるメール宛に、ネームサーバー情報変更完了通知のメールが届く

4. AWS Certificate ManagerでSSL証明書を発行する
SSL証明書のリクエスト
証明書をリクエスト→パブリック証明書をリクエスト
完全修飾ドメイン名に購入した独自ドメインを設定する
この証明書に別の名前を追加をクリック　→ 購入した独自ドメインの先頭に*.を追加した文字列を設定する
DNS検証を選択
→ 検証保留中のステータスの証明書リクエストが作成されました。証明書の検証と承認を完了するには、追加のアクションが必要です。
の表示が出るので、証明書を表示する

SSL証明書の検証
Route53 CNAME作成
AWS Certicate Managerの証明書の表示画面の「Route53でレコード作成」のボタンをクリックする
→Route53のホストゾーンにはこのCNAMEは自動で設定されている
次の手順で、このCNAME名、CNAME値をお名前.comに設定する

お名前.comに外部のCNAMEを設定する
ドメイン　→ ドメイン機能一覧　→ ネームサーバーの設定　→ DNS関連機能の設定
→DNS設定　→ DNSレコード設定を利用する
→ A/AAAA/CNAME/MX/NS/TXT/SRV/DS/CAAレコードの追加の欄で
TYPEをCNAMEに変更して、ホスト名にROUTE53のCNAME名を設定する
VALUEにCNAME値を設定する（末尾のドットはとる）
TTLは3600のまま
状態は有効のまま
DNSレコード設定用ネームサーバー変更確認
のチェックは外したまま
→ 確認画面へ進む　→ 設定

AWS Certificate Managerのステータス確認
CNAMEのステータスが成功になっていること


-------------
## ACM承認がされない時の対策

1. ACMからCNAMEレコードをroute53に自動登録するを入力する。



2. dig or nslookupコマンド で登録されてるレコードを確認する



-------------
## 503エラーが出る対策

1. LBのリスナーにターゲットグループが登録されてるか確認する。
MIDIフットスイッチで本や漫画のページめくり

# 背景と課題

ギターの練習をしながらPCで本や漫画を読みたい、でも実際やってみるとページをめくるのに手を止めないといけないのでエクスペリエンスはイマイチ…という経験があるのは筆者だけではあるまい。この課題をクリアするため、筆者は以前 Tobii EyeX というアイトラッカーを使って視線によるページめくりシステムを実現・使用していたが、諸事情により現在は退役している。何か楽に作れる代替手段はないだろうか？

# ソリューション

辺りを見回すと、おお、筆者のPCには常時MIDIキーボードが接続されており、そのキーボードにはサスティンペダルとしてフットスイッチが繋がれている。このペダルを踏んだらページがめくられるようにスクリプトでも書けば、ギターを弾く手を止めずに次々と漫画のページをめくれるではないか。まっ/たく/簡/単/だ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465152/cbfe8947-7888-6af5-1113-a0f5ff5c1329.png)

やりようはいくらでもあるはずだが、調べるのも面倒なので、ChatGPT様に「MIDIデバイス上でサスティンペダルが踏まれたらスペースキーをインジェクトするPythonコード」とか言ってみる。洗練されてはいないが一応動くものを出して来るので、何度か質問を変えたりregenerateを繰り返し、選択肢がだいたいわかったら自分で書き直してこんなふうに仕立てる。(ChatGPT様は場当たり的かつ平気で嘘をつくので当然そのまま使ったりはしない。)

```inject_key_on_sustain.py
import sys
import mido
import keyboard


def inject_key_on_sustain(device_name, key):
    try:
        with mido.open_input(device_name) as midi_in:
            print(f"MIDI device: {device_name}")
            print(f"Key: {key}")
            for message in midi_in:
                if message.type == 'control_change' and message.control == 64 and message.value >= 64:
                    keyboard.press_and_release(key)
    except OSError as e:
        print(f"An error occurred: {e}");
        print(f"Available devices: {mido.get_input_names()}")


if __name__ == "__main__":
    inject_key_on_sustain(sys.argv[1], sys.argv[2])

```

この時点では監視対象のMIDIデバイスとインジェクトされるキーはオープン(パラメタで指定可能)にしてあるので、次のようなバッチファイルを作り、アイコンのクリックで実行できるようにしておく。これはページめくりにスペースキーを用いるビューワー用であるが、ページめくりキーが異なるビューワーを使う場合、別のバッチファイルを作成して実行時に自分で選択すればよい。

```inject_space_key_on_sustain.bat
python.exe inject_key_on_sustain.py "Keystation 49 MK3 0" space
pause
```

これでめでたしである。

# 車輪の再発明上等！

実を言うとこのソリューション自体、ノウハウとして共有するほど大層なものではないと思っているのだが、このようなちょっとした課題の解き方について思うところがあるので書いてみた次第である。

「自分がその課題に取り組んだことのある最初の人類でない限り、既にどこかの誰かがノウハウや実装を公開していると思え」というのは近年のソフトウェアエンジニアリング界隈のトレンドである。今回のように「MIDI入力をキー入力に変換する」といったシンプルでありきたりな課題については特に、「誰かが既に作ったものを使う方が効率よい、こんなことにわざわざコードを書くなんて馬鹿げている」と考える人もいるだろう。実際 https://midikey2key.de/ のようなGUIツールが存在し、これを使えばコードを書かずに同じことが実現できたはずである。

では何故筆者はその「どこかの誰かが既に公開してくれたツール」を使わずにコードを書いたのか？それは、そんなツールをダウンロードし、インストールし、マニュアルを読み、使い方を覚え、自分の目的に合っているかどうか評価するという**ツールを使うこと自体に対する時間と労力の投資がその場限りであり、その後得られるリターンが何もない**からである。一方自分でコードを書けば、軽い筋トレになり、将来自分が使うツールボックスの中身が増え、また今流行のGenerative AIの使い方の研究にもなる、と特に長い目で見たときに効くメリットが数多く得られる。

つまり、課題解決という機会があったときに、自分でコードを書くのは自分に対して投資すること、他者の解を使うのはその解に対して投資すること、だと考えられる。「既にあるから」という理由だけで自分への投資をやめて他者に投資する、というのは果たして合理的だろうか、ということはよく考えた方がよい。
Go言語によるゲーム開発: Ebitenライブラリの使用方法

## 使用するバージョン
　Ebitenバージョン: 2.2

## Ebitenとは？
EbitenはGo言語でゲームを開発するためのシンプルで使いやすいライブラリです。このライブラリを用いることで、2Dゲームの開発が容易になります。

## Ebitenのインストール
まず、Ebitenをインストールする必要があります。以下のコマンドでインストールできます。

```go
go get github.com/hajimehoshi/ebiten/v2
```

## 基本的なゲームの作成
それでは、Ebitenを使用して基本的なゲームを作成してみましょう。ここでは、画面上に四角形を描画し、キーボードの矢印キーで動かすシンプルなゲームを作成します。

まず、以下のコードで新しいゲームの構造体を作成します。

```go
package main

import (
    "github.com/hajimehoshi/ebiten/v2"
)

// ゲームの状態を保持する構造体
type Game struct {
    x, y float64  // 四角形の位置
}

func main() {
    // ゲームの初期化
    game := &Game{}
    // ゲームの起動
    ebiten.RunGame(game)
}
```

このコードはゲームを初期化し、EbitenのRunGame関数を使用してゲームを起動します。

次に、Update関数を実装します。この関数は毎フレーム呼び出され、ゲームの状態を更新します。

```go
// Update is called every frame (1/60 [s]).
func (g *Game) Update() {
    // 矢印キーの入力を取得し、四角形の位置を更新する
    if ebiten.IsKeyPressed(ebiten.KeyArrowUp) {
        g.y -= 2
    }
    if ebiten.IsKeyPressed(ebiten.KeyArrowDown) {
        g.y += 2
    }
    if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) {
        g.x -= 2
    }
    if ebiten.IsKeyPressed(ebiten.KeyArrowRight) {
        g.x += 2
    }
}
```

最後に、Draw関数を実装します。この関数はゲームの状態を描画します。

```go
// Draw is called every frame (1/60 [s]).
func (g *Game) Draw(screen *ebiten.Image) {
    // 四角形を描画する
    ebitenutil.DrawRect(screen, g.x, g.y, 64, 64, color.RGBA{0xff, 0, 0, 0xff})
}
```

以上で基本的なゲームの作成が完了しました。このゲームでは、矢印キーを押すと四角形が画面上を動きます。

## まとめ
今回はGo言語のゲーム開発ライブラリ、Ebitenの基本的な使用方法について記載しました。
Ebitenはそのシンプルさと強力さから、Go言語でゲーム開発を行う際の優れた選択肢です。
MySQLでtruncate tableするためのストアドプロシージャ

WorkatoではOn-prem Agent経由以外で任意のSQLを実行することが出来ません。

On-prem Agentを利用しない環境で任意のSQLを実行したい場合は、実行したいSQLをストアドプロシージャとして実装し、それを実行して対応することになります。

以下は、MySQLでtruncate tableするためのストアドプロシージャです。

※以下のコードはWorkato専用ではなく、MySQL/MariaDBで汎用的に利用可能です。

# コード

```sql
drop procedure if exists truncate_table;
delimiter //
create procedure truncate_table (IN table_name varchar(20)) 
BEGIN
    SET @sql = CONCAT('truncate table ', table_name, ';');
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
END;
//
delimiter ;
```

# 実行
以下の文を実行することで、指定されたテーブルをtruncateすることが可能です。

```
call truncate_table('<テーブル名>')
```
swift基本文法編

### 構造体(struct）とは
基本的にはクラスと同じだが、以下の相違点がある

| 違い | クラス | 構造体 | 備考 |
| - | - | - | - |
| デフォルトのイニシャライザがあるかどうか | × | ⚪︎ | （基本的にイニシャライザを書けばいい気がする）
| 型 | 参照型 | 値型 | クラスをコピーした場合はアドレス情報がコピーされ、構造体をコピーした場合は値がコピーされる |
| 継承ができるかどうか | ⚪︎ | × |

***
構造体名はPascal記法(UpperCamelCase記法)、
プロパティやメソッドはlowerCamelCase記法を用いることが推奨される。

| 記法 | 説明 | 例 |
| - | - | - |
| lowerCamelCase | 先頭は小文字で単語ごとに大文字 | `$myData` |
| アンダースコア記法 | 小文字で単語の間をアンダースコア(_)で繋ぐ | `$my_data` |
| Pascal記法 | 先頭と単語の区切りが大文字 | `$MyData` |
ElastiCache for RedisのClusterモード(暗号化)への接続方法 Rails編

# はじめに
AWSでRedis（クラスターモードかつ暗号化）を作成した際、
接続が止まった状態でエラーログも何も出ない。。
ということで何に気を付ければいいか書いていく

## サーバー内接続確認

まずは接続コマンドを入力する。
注意点として
`-c` クラスターモードON
`--tls` 暗号化転送ON
このオプションがないと延々と接続待ちになるので注意
```
$ redis-cli -h [エンドポイント] -p [ポート番号] -c --tls
```

ただし、自身のredis-cliの`4.0.10`をインストールしていたが、redis-cliのオプションである`--tls`が使えなかった（ここで詰まった）
```
Unrecognized option or bad number of args for: '--tls'
```

なのでバージョン6をインストールする
```
$ sudo amazon-linux-extras install redis6
```

接続確認して完了
```
# キー"mykey"に値"Hello, Redis!"をセットする
xxx.x.x.x:6379> SET my_key "Hello, Redis!"
# キー"mykey"の値を取得する
xxx.x.x.x:6379> GET my_key
"Hello, Redis!"
```


## アプリケーション(Rails)接続確認
使用gem
```ruby:Gemfile
gem 'redis-objects', '>= 2.0.0.beta' # gem 'redis'でもok
gem 'redis-clustering' # クラスター接続用
```

`rediss`はタイポではなく、暗号化認証(SSL)の場合はこのように書く。
```ruby:config/initializers/redis.rb
Redis::Cluster.new(nodes: ["rediss://#{ENV["REDIS_URI"]}:#{ENV["REDIS_PORT"]}"])
```

## まとめ
- 暗号化してクラスターを作成した場合は結構オプションやredis-cliのコマンドが通常と異なるので気をつけないといけない（公式にも接続方法載ってる）
- Railsによる接続も`gem redis-clustering`が必要になる（`gem redis-objects`だけでも出来るのか調査してもわからなかった。）

https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/GettingStarted.ConnectToCacheNode.html
NextcloudをDockerで構築する

## 目的
フォルダの共有場所を作成する必要が出てきたので、今回はNextcloudを構築する

## ディレクトリ構成

- docker-compose.yml
- .env  


## 構築
### Docker-compose.yml
```yml
version: '3.9'
services:
  nextcloud-db:
    container_name: nextcloud-db
    image: mariadb
    restart: always
    volumes:
      - ./nextcloud-db:/var/lib/mysql
    environment:
      - MARIADB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}  # .envファイルに環境変数を設定
      - MARIADB_PASSWORD=${MYSQL_PASSWORD}  # .envファイルに環境変数を設定
      - MARIADB_DATABASE=nextcloud
      - MARIADB_USER=nextcloud

  nextcloud:
    container_name: nextcloud
    image: nextcloud
    ports:
      - 8081:80
    volumes:
      - ./nextcloud:/var/www/html
    restart: always
    environment:
      - MYSQL_HOST=nextcloud-db
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}  # .envファイルに環境変数を設定
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
```

### .env
```.env
MYSQL_ROOT_PASSWORD=nextcloud
MYSQL_PASSWORD=nextcloud
```

## 起動
```
$ docker-compose up
```

## 確認
ok!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/575ff202-91f2-4727-79a4-1359ede0a272.png)
Qiitaにアップロードした画像を削除する機能が追加されていたので、Qiita投稿について自分の理解をまとめてみた

Qiitaでは画像をアップロードすると、S3に画像がアップロードされ削除するにはサポートに問い合わせが必要となり、自力での削除ができませんでした。

この状態がながく続いていましたが、2023年01月17日にアップロードしたファイルを削除する機能の機能追加があり、サポートに問い合わせなくても削除が可能となりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/e8485e88-b7aa-2f12-180a-ff60b9c4e814.png)

機能追加された事により、画像の削除手順について下記ページが追加されています。

[画像のアップロード・削除方法](https://help.qiita.com/ja/articles/qiita-image-upload)

いままで不備のある画像をアップロードして公開した場合、記事の削除をして再投稿をしていましたが、この機能のおかげて不備のある画像をアップロードした場合は画像を削除すれば問題なくなりました。

## 記事の削除をして、再投稿をする必要がなくなるか？

この機能追加で記事を削除して再投稿する必要がなくなったか？　といえば、そんな事はないかと思います。

画像については削除できるようになりましたが、Qiita記事は編集履歴に編集内容が残り、だれでも閲覧できる仕様となっているため、本文中に公開すると不備のある情報を書いてしまった場合。

記事のテキストを編集しただけだと、編集前の状態を編集履歴にのこってしまうため。
このケースでは記事の削除をして再投稿は必要となります。

まとめると下記がよさそうにおもいます。

- 不備のある画像をアップロードした ＝＞　今回のUIから削除。
- 文章として不備のあるテキストを公開した　＝＞　削除　＆　再投稿。

## 総評

編集履歴もどうにかなる機能追加がきてくれると嬉しいですね。
seleniumで自動ログインしたいのにHTMLを見てもidが見つからないとき

#検証ツールを開いてもidが見つからない
フィードバックお待ちしていますm(_ _)m

seleniumを用いて、webサイトにメールアドレスやパスワードを自動入力するための記事です。

当方の環境: mac, visual studio code

※webページのログイン画面へのアクセスまではできていると仮定します。

それではいきましょう。

ログイン画面に到達したら、右クリック(もしくはダブルクリック)で"検証"というツールが出てくると思います。

そこでメールアドレス入力画面のHTMLを確認すると、(自分の参考にしていたUdemy動画では存在するはずの)id="username"とかid="password"みたいなのがが出てこない！

こんな問題に遭遇しました。

そこで書いたコードがこちら。

`elem_username = browser.find_element_by_name('mail')`
`elem_password = browser.find_element_by_name('pass')`

ところが、ターミナルにてpython3 ファイル名
で実行を試みたところ、

```
'WebDriver' object has no attribute 'find_element_by_name
```
というエラーが。

どうやらfind_element_by_nameというメソッドを使用してはいけないようです。
(ググったら使えるって書いてたんだけどな。むむむ...でも他の方法を考えないと仕方ない。)

そこで、この記事ではByクラスを使用した解決策を提案いたします。

ソースコードの修正はたったの2点。

冒頭に
```
from selenium.webdriver.common.by import By
```

そして
`elem_username = browser.find_element_by_name('mail')`
を
```
elem_username = browser.find_element(By.NAME, 'mail')
```
に書き換えるだけ！

パスワードも同様です。一応書いておきますね。

```:修正前
elem_password = browser.find_element_by_name('pass')`
```

```:修正後
elem_password = browser.find_element(By.NAME, 'pass')
```

これで無事にメールアドレスとパスワードを自動入力するコードが書けました。

ここまでお読み頂きありがとうございました。
AWSのコンボ技

### Webアプリ + APIGateway 
APIGatewayのAPIエンドポイントを経由して他のWebアプリからAWSにデータを送信することが可能になります。
- 例：Kintone(website) ⇒ (Webhook経由) ⇒ APIGateway ⇒ その他のAWS（Lambdaなど）

### APIGateway + Lambda 
- APIGatewayのリソース➡POST➡総合リクエストからLambdaの指定ができます。
- APIGatewayでのAPIのデプロイ時には、ステージ変数を設定することができます。ステージ変数を使用することで、APIのエンドポイントURLにステージ名を含めることができます。

### Lambda + S3
- S3に配置されたオブジェクトに対してLambdaを実行する場合、IAMロールを作成してS3へのアクセス権限を与える必要があります。
- S3ファイルがアップロード、削除、更新された際、Lambdaを自動実行させることができます。
 　 Lambda関数➡設定➡トリガー➡トリガー追加でイベントタイプ、S3のバケット、プレフィックスを指定できます。
- トリガー経由せずにLambdaからでも、S3ファイルの作成、削除、情報を取得することができます。

### Stepfuncions + Lambda  

- Step Functionsは、AWSサービスを実行する手順を定義することができるサービスであります。
- State Machineと呼ばれるフローチャートのようなもので処理を定義します。
- Lambdaとの連携が容易であり、Lambdaの処理をワークフローで定義することができます。

例：

> 
> 
> 
> {  
>    "StartAt":"Lambda",
>    "States":{  
>       "Lambda":{  
>          "Type":"Task",
>          "Resource":"arn:aws:lambda:us-east-1:123456789012:function:(Lambda関数名) "
>       }
>    }
> }
> 

### EventBridge + Lambda

- EventBridgeは、様々なAWSサービスからのイベントを受信し、Lambdaなどのターゲットに送信することができるサービスであります。
- ルールを設定することで、特定のイベントに対してターゲットを指定したり、決めた値を渡したりすることができます。更に実行時間の指定することで、予約機能として使用されることも可能です。
- 例：
　　①毎日朝７時にLambda関数を実行する
　　②10分ごとにLambda関数を実行する

### Stepfuncions + Redshift

- Step FunctionsからRedshiftに対して、クエリを実行することができます。
- クエリの実行結果をS3に出力することもできます。
- また、Step Functionsによって、Redshiftのクラスターの起動や停止を行うこともできます。
『React & React Nativeで画像のアスペクト比をマスターする』



---

## 目次
1. [はじめに](#はじめに)
2. [React Nativeでのアスペクト比の調整](#React-Nativeでのアスペクト比の調整)
3. [React (Web)でのアスペクト比の調整](#React-Webでのアスペクト比の調整)
4. [まとめ](#まとめ)

---

<a name="はじめに"></a>
## 1. はじめに

画像のアスペクト比は、デザインやレイアウトに大きな影響を与えます。ReactとReact Nativeを使用して画像のアスペクト比を1:1にする方法について見ていきましょう。

<a name="React-Nativeでのアスペクト比の調整"></a>
## 2. React Nativeでのアスペクト比の調整

React Nativeでは`Image`コンポーネントの`style`プロパティを使用して、アスペクト比を調整することができます。

以下に具体的なコード例を示します：

```jsx
import React from 'react';
import { Image } from 'react-native';

const MyComponent = () => (
  <Image
    source={{ uri: 'https://example.com/your-image.jpg' }}
    style={{ width: 100, height: 100 }}  // この値を調節してアスペクト比を1:1にします
  />
);

export default MyComponent;
```

上記の例では、`width`と`height`の値が同じであるため、アスペクト比が1:1となります。これらの値を調節することで、望むアスペクト比に調整することが可能です。

React NativeではCSSの`aspect-ratio`プロパティは直接サポートしていないので注意が必要です。

<a name="React-Webでのアスペクト比の調整"></a>
## 3. React (Web)でのアスペクト比の調整

React（Web）では、CSSの`aspect-ratio`プロパティを利用してアスペクト比を調整できます。以下に具体的な方法を示します：

```jsx
import React from 'react';

const MyComponent = () => (
  <img
    src="https://example.com/your-image.jpg"
    style={{
      width: '100px',
      aspectRatio: '1/1'  // アスペクト比を1:1にします
    }}
  />
);

export default MyComponent;
```

上記の例では、CSSの`aspect-ratio`プロパティを使用してアスペクト比を1:1に設定しています。こちらも`width`の値を調節することで望むアスペクト比に調整することが可能です。

ただし、`aspect-ratio`は比較的新しいCSSプロパティであり、一部のブラウザではサポートされていない可能性があります。

<a name="まとめ"></a>
## 4. まとめ

React NativeとReact（Web）では、画像のアスペクト比を調整する方法が異なります。それぞれのプラットフォームに合わせて適切な方法を選択しましょう。

React Nativeでは`width`と`height`を設定することでアスペクト比を調整します。一方、React（Web）では、新しいCSSプロパティである`aspect-ratio`を利用することが可能です。

以上、画像のアスペクト比の調整方法についてご紹介しました。画像レイアウトの調整に是非お役立てください。

---

※ご不明な点や質問がございましたら、コメント欄よりお気軽にどうぞ。また、この記事が役に立ったと思われた方は「いいね」をお願いします。皆様からのフィードバックをお待ちしております。
InSpecでCISベンチマーク準拠スキャンを簡単実行

下記のページをご参照ください。

https://qiita.com/chef_inspec/items/7ad38683bb72e25fde1a


__ライセンスや技術サポートについて詳しくは、連絡先： support@chef-sec.com にお問い合わせください。__ 

www.chef-sec.com
djangoで、一意制約を持ったカラムの値を入れ替える

# 結論
値を入れ替えたい2つの行情報のうち、1行の対象カラムを一時的に別の値に更新することでタイトルのことができます。

# 解説
一意制約を持ったカラムは、一意であることが保証されています。そのため、いずれかの行と重複するような値に更新しようとするとエラーが発生します。ある2行に対して一意制約を持ったカラムの値を入れ替えたい場合、1行ずつ更新しようとするとどこかで一意制約にかかりエラーとなります。そこで、一方を一時的に別の値に更新し、入れ替えを行えるようにします。

# サンプルコード
```views.py
from django.db import transaction

# viewとなる関数を作成している想定
# hogeFieldが一意製制約を持っているIntegerFieldと想定

# エラーが起きた時にロールバックさせるため
@transaction.atomic
def hoge(request)
    # ...
    # 値を交換したい行情報を取得
    item1 = Item.objects.get(pk=0)
    item2 = Item.objects.get(pk=1)
    
    hoge_tmp = item2.hogeField
    # 必ず重複しないことが保証できる値を一時的に設定する
    item2.hogeField = -2000000000
    item2.save()
    
    # item1の値と「退避したitem2(hoge_tmp)」の値を入れ替え
    item1.hogeField, hoge_tmp = hoge_tmp, item1.hogeField
    item1.save()
    
    item2.hogeField = hoge_tmp
    item2.save()
    # ...
```

以上です。
オブジェクト指向とは

# 概要
「ある役割を持ったモノ」ごとにクラスを分割し、モノとモノとの関係性を定義していくことでシステムを作り上げようとする**システム構成**の考え方

# オブジェクトとは
直訳すると「物」「対象」
プログラミングにおいてはデータと処理の集まりを意味している

# イメージ図でまとめる
<img src="https://www.moringa-moringu.com/wp-content/uploads/2020/05/%E3%82%AA%E3%83%95%E3%82%99%E3%82%B7%E3%82%99%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91.002-1024x433.jpeg" />

**▼従来**
『剣を装備した敵』

**▼オブジェクト指向**
『敵』『剣』『銃』

**▼オブジェクト指向のメリット**
プログラムをまとめることで、『**プログラムの役割が分かりやすく**』『**効率よくプログラムを組みやすい**』メリットがある

従来のシステム構成では、敵の種類ごとに敵・剣・銃を設定していた。しかし敵の種類が増えた場合や、全種類の敵の装備する銃の攻撃力を変更する場合に、1種類ずつ修正する必要があって**非効率**だった。
それに対しオブジェクト指向は、『敵』『剣』『銃』ごとにプログラムを組み立てることで、種類が増えてもオブジェクトを設置するだけで設定が完了する。また銃の攻撃力を修正する場合に、『銃』のプログラムを変更するだけで全種類に対応できるメリットがある。

# オブジェクト指向プログラミング言語
1. Java
1. PHP
1. JavaScript
1. Python
1. C++
1. Swift

# オブジェクト指向の設計とは
『**各クラスの役割など全体の関係性を決めていくこと**』をオブジェクト指向における設計という

**▼設計の際に意識する事**
1：処理の意図を理解する
2：拡張性やセキュリティ等の考慮
3：パフォーマンスは問題ないか

https://qiita.com/Cookie_Iwate/items/3e56d794c6f3290d343d
GetModuleFileName (GetModuleFileNameA)を(他プラットフォームに)実装する

実装例は https://github.com/cielavenir/7bgzf/blob/master/lib/getmodulefilename.c にあるんですが、まとめ的なものを書いていなかった。[^1]

## Windows

Windowsの当該関数のクローンを作るって言うんだからWindowsでは当然ながらGetModuleFileNameで良い

## ハンドルがNULLの場合

プロセス本体のパスを返す仕様になっている。

### macOS[^2]

_NSGetExecutablePathを使う。

### Solaris

getexecnameを使う(らしい)

### FreeBSD

```c
	int mib[4];
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
	mib[2] = KERN_PROC_PATHNAME;
	mib[3] = -1;
	size_t bufsize = nSize-1;
	if(sysctl(mib, 4, pFilename, &bufsize, NULL, 0)<0){
		return 0;
	}
	// pFilename
```

### Linux

readlink("/proc/self/exe")

### NetBSD

readlink("/proc/curproc/exe")

### OpenBSD

readlink("/proc/curproc/file")

## ハンドルが非NULLの場合

### macOS

_dyld_image_count()分_dyld_get_image_name(i)することでimage_nameを列挙。dlopenして、与ハンドルと同じか見る

### Android

dlinfo関数が使えない。
/proc/self/map_filesディレクトリを列挙する、もしくは/proc/self/mapsファイルを開いて、image_nameを列挙。dlopenして、与ハンドルと同じか見る

### Linux / FreeBSD / NetBSD/ OpenBSD/ Soralis

```c
struct link_map *lm=NULL;
dlinfo(hModule, RTLD_DI_LINKMAP, &lm);
// lm->l_name
```

ところでp7zipってどんなことやってるんだろうなと思いましたが、https://github.com/p7zip-project/p7zip/blob/master/CPP/7zip/UI/Common/ArchiveCommandLine.cpp によると7z.exeと7z.soが同じディレクトリに存在することを仮定しているようですね…
(/usr/bin/7zの実体が/usr/lib/p7zip/7zに置かれている理由の一つでもある)

[^1]: ぐぐらびりてぃが低かったよね、って話
[^2]: 含Terminal導入済みiOS
[個人開発]52個のアプリを作り続けられる継続力について語ります

![スクリーンショット 2023-07-31 13.26.52（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/af0b1f82-8dd2-a3c0-beba-45ff16583eca.png)





こんにちわ。　いせりゅーです。

個人開発ネタだと割と閲覧してくれる方が多く、とても幸せです。なので、今回も個人開発についての話をしていこうと思います。

個人開発についての記事はこちらになります。↓

https://qiita.com/isekiryu/items/ef5919307b136c5959e8

https://qiita.com/isekiryu/items/211cca3d138ddf3ba975

https://qiita.com/isekiryu/items/cd62bd09e8b11e037c6c



# 自己紹介

![スクリーンショット 2023-06-13 7.33.21（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/be78807a-0aec-0478-13d2-429cc58e96a3.png)


# リリース履歴

- Apple Storeでリリースされた数・・・<b>５２個</b>

https://apps.apple.com/jp/developer/ryutaro-iseki/id1544199624?see-all=i-phone-apps

- Google Play Storeでリリースされた数・・・<b>18個</b>

https://play.google.com/store/apps/developer?id=ryutaro+iseki


- Flutterで作られたアプリ数・・・<b>4２個</b>

- Swiftで作られたアプリ数・・・<b>10個</b>

- 自信のあるアプリ数・・・<b>0個！？</b>


たくさん作っていながら自信のあるアプリがないのがとてもつらみですね。。笑
でも、来月（2023/07）に自信のあるアプリをリリース予定なのでお楽しみに！！
開発期間が半年ぐらいの割と大きなアプリとなっております😁


# アプリを作り続けられる継続力

まずは、「アプリを作り続けられる継続力」について話していこうと思います。

こちらについては人それぞれであると思いますが、僕なりの継続力の要因をご紹介します。

<b>１、就職活動のために開発を続けていた。</b>
- こちらについては、僕が就活をしていた時期に、「アプリをリリースしまくって無双するぞ！」という強い思いがありました。
- 個人的な感想ですが、就活生は、<b>インターンなどでの実務経験</b>と <b>個人開発</b>があれば割と無双できるかなと思っております。
- その理由としては、個人開発には、「ガクチカ」や「ポートフォリオ」が作れるというメリットがあります。

<b>２、お小遣い稼ぎができる。</b>
- やはりお金稼ぎのチャンスがあることはとてもでかいと思います😏
- 広告を実装できれば、誰でもお金を稼ぐチャンスはあります。

僕の場合は、Google様からお小遣いをもらいました。🔥

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/680f90ad-b27a-a633-f913-1462c1a38f0e.jpeg"/>


<b>３、意外と身近な人に使ってもらえる喜びを感じられる。</b>
- これについては、人に伝えてみたり、Apple Store ConnectのAppアナリティクスを見たりするとダウンロードしてくれた人数が閲覧できます。

「わあい！ダウンロード数がたくさんあって嬉しいぞぉぉぉ」となることが継続力につながりました。

![スクリーンショット 2023-07-28 14.18.21（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/98b6eb7c-ac29-8a04-619d-fab0b4eec58d.png)

- また、就活生だけになってしまうかもしれないですが、面接官にも触ってもらえる機会がたまにあります。

僕・・・😁
面接官・・・🕶

😁「このアプリを作りました！」

🕶「せっかくだから触ってみたいな」

😁「まだASOがしっかりとできていないため、僕の名前で検索してもらうとダウンロードできると思います😁」

🕶「お、結構しっかりと作れているね。これ何人で作ったの？？」

😁「すべてのアプリを自分一人で作成しました！」

🕶「す、すごいな。。。いいですね。。」



といったような会話がちらほらとありました。とても嬉しいですね。


# 最後に
もし何かを作り続けて、心が折れそうでしたら途中でもいいからアウトプットしてみるだけでもだいぶ変わると思います！
恥ずかしかったり、なんかな。。。と思いましたら僕のTwitterのDMとかでも連絡ください！！
９９％褒めちぎります！！笑
みんなでいいものを作り続けていきましょう😁
僕も頑張ります！！

<b>Twitter</b>

https://twitter.com/isekiryu
Oracleで00から99パターン2




SELECT
  CASE
    WHEN MAX(column_name) = 'ZZ' THEN 'ZZ'
    WHEN REGEXP_LIKE(MAX(column_name), '^[0-9]{2}$') THEN
      CASE
        WHEN MAX(column_name) = '99' THEN 'A1'
        ELSE
          CHR(ASCII(SUBSTR(MAX(column_name), 1, 1)) + 1) || '1'
      END
    WHEN REGEXP_LIKE(MAX(column_name), '^[A-Z][1-9]$') THEN
      CASE
        WHEN SUBSTR(MAX(column_name), 2, 1) = '9' THEN
          SUBSTR(MAX(column_name), 1, 1) || 'A'
        ELSE
          SUBSTR(MAX(column_name), 1, 1) || CHR(ASCII(SUBSTR(MAX(column_name), 2, 1)) + 1)
      END
    WHEN MAX(column_name) = 'AZ' THEN 'B1'
    ELSE
      CHR(ASCII(SUBSTR(MAX(column_name), 1, 1)) + 1) || '1'
  END AS next_value
FROM table_name;
Oracleで00からZZまでの連番を取得




SELECT
  CASE
    WHEN MAX(column_name) = 'ZZ' THEN 'ZZ'
    WHEN REGEXP_LIKE(MAX(column_name), '^[0-9]{2}$') THEN
      CASE
        WHEN MAX(column_name) = '99' THEN 'A1'
        ELSE
          CHR(ASCII(SUBSTR(MAX(column_name), 1, 1)) + 1) || '1'
      END
    WHEN REGEXP_LIKE(MAX(column_name), '^[A-Z][1-9]$') THEN
      CASE
        WHEN SUBSTR(MAX(column_name), 2, 1) = '9' THEN
          SUBSTR(MAX(column_name), 1, 1) || 'A'
        ELSE
          SUBSTR(MAX(column_name), 1, 1) || CHR(ASCII(SUBSTR(MAX(column_name), 2, 1)) + 1)
      END
    WHEN MAX(column_name) = 'AZ' THEN 'B1'
  END AS next_value
FROM table_name;
Oracle

登録されている値の最大値(00からZZ)を取得するSQL
SELECT
  CASE
    WHEN MAX(column_name) = 'ZZ' THEN 'ZZ'
    WHEN REGEXP_LIKE(MAX(column_name), '[A-Z]{2}') THEN
      CASE
        WHEN SUBSTR(MAX(column_name), 2, 1) = '9' THEN
          SUBSTR(MAX(column_name), 1, 1) || 'A'
        ELSE
          SUBSTR(MAX(column_name), 1, 1) || CHR(ASCII(SUBSTR(MAX(column_name), 2, 1)) + 1)
      END
    ELSE
      LPAD(TO_NUMBER(MAX(column_name)) + 1, 2, '0')
  END AS next_value
FROM table_name;