OmniAICreator/Qiita-1.07M huggingface dataset:
開発環境をDocker化 Rails 6 x PostgreSQL

# Railsの開発環境をDocker化
Docker、docker-composeで既存のRailsアプリをDocker化する方法についてまとめてみます。

### バージョン
- ruby 3.0.2
- rails 6
- node 14.19.1
- postgres 15

### 1. Dockerfileの作成
今回はnodejsやyarnのインストールに`apt-get`ではなくマルチステージビルドを利用します。
少しですがビルドの時間を短くし、イメージサイズも小さくするためです。
```docker:Dockerfile
FROM node:14.19.1 as node
FROM ruby:3.0.2

ENV YARN_VERSION 1.22.17
COPY --from=node /opt/yarn-v${YARN_VERSION} /opt/yarn/
COPY --from=node /usr/local/bin/node /usr/local/bin
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
	&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
	&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
	&& ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
	&& ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx

RUN apt-get update -qq && apt-get install -y \
	build-essential \
	libpq-dev

WORKDIR /myapp
COPY Gemfile Gemfile.lock /myapp/
RUN bundle install
COPY . /myapp/
```

### 2. docker-compose.ymlの作成
docker composeとは複数のコンテナを一括で効率的に操作できるツールのことです。
docker-compose.ymlにはコンテナの利用方法、起動方法を定義しておきます。
ここに書いておくことでコンテナの起動時に毎回毎回オプションの指定などしなくて済むようになります。
```yaml:docker-compose.yml
version: '3'

services:
  db:
    image: postgres
    volumes:
      - 'db-data:/var/lib/postgresql/data'
    environment:
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_DB=mydb

  web:
    build: .
    command: bash -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -b '0.0.0.0'"
    ports:
      - '3000:3000'
    volumes:
      - .:/myapp
    environment:
      - POSTGRES_PASSWORD=postgres
    tty: true
    stdin_open: true
    depends_on:
      - db

volumes:
  db-data:
```

### 3. database.ymlの編集
今回はデータベースにpostgresを利用しています。
```yaml:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: postgres
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
```

### 4. 起動
以下のコマンドを実行します。
```
$ docker-compose build
```
```
$ docker-compose run web rake db:create db:migrate
```
```
$ docker-compose up
```

### 5. 動作確認
上記コマンドを実行後、http://localhost:3000 でアクセスできることを確認しましょう！
llama.cppでalpaca(4bit量子化)を動かす

# llama.cppのコンパイル
```bash
git clone git@github.com:ggerganov/llama.cpp.git
cd llama.cpp
make
```
(投稿時点の最終コミットは`53dbba769537e894ead5c6913ab2fd3a4658b738`)

# tokenizerとalpacaモデルのダウンロード
```bash
mkdir models/alpaca_7b
wget -O models/alpaca_7b/tokenizer.model https://huggingface.co/chavinlo/alpaca-native/resolve/main/tokenizer.model
wget -O models/alpaca_7b/ggml-alpaca-7b-q4.bin https://huggingface.co/Sosaka/Alpaca-native-4bit-ggml/resolve/main/ggml-alpaca-7b-q4.bin
```

# 新ggml形式へ変換
```bash
python convert-unversioned-ggml-to-ggml.py models/alpaca_7b models/alpaca_7b/tokenizer.model
python migrate-ggml-2023-03-30-pr613.py models/alpaca_7b/ggml-alpaca-7b-q4.bin models/alpaca_7b/ggml-alpaca-7b-q4.bin.1

# 変換前のファイル削除
rm models/alpaca_7b/ggml-alpaca-7b-q4.bin.orig
rm models/alpaca_7b/ggml-alpaca-7b-q4.bin
```

# 推論
```bash
./main -m models/alpaca_7b/ggml-alpaca-7b-q4.bin.1
```
Python Printで改行せずに処理経過を表示

# print文で改行しない方法
引数end=""とすればOK
```python
print("表示する文字",end="")
```

# 行頭に戻る方法
エスケープシーケンス 「\r」を付けます。
```python
print("\r表示する文字",end="")
```

# 処理ループに組み込み
```python
stime = time.time()

num = len(iter)
for i, r in enumerate(iter):
    etime = time.time()
    print("\r time:",int(etime-stime),'sec ',i+1,"/",num, end="")
    # 処理内容
print('') # 最後に改行
```

## 結果
以下のカウンタが同じ行で表示されます。
```
time: 19 sec  346 / 1855
```
kintone REST API のエラー確認

kintone でエラーが発生している場合、REST API のエラーが分かりにくい場合がありますので、確認方法を紹介

# 概要

レコード編集画面の submit イベント処理で、エラーが発生した場合、画面が編集画面から詳細画面に遷移してしまい、エラー情報が確認できないことがあります。
ブラウザーの開発ツールの「ログを保持」をチェックすることで、前の画面のログを見ることができます。

![2023-04-05_10h58_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e64e4c0d-965e-c3da-15b3-9e00ce06f774.png)

※開発ツールの使い方は、下記を参照
[kintone JavaScript カスタマイズデバッグまとめ](https://cybozudev.zendesk.com/hc/ja/articles/4977994758297-kintone-JavaScript-%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%BE%E3%81%A8%E3%82%81#check-the-network)


# 手順

エラーの再現性がある場合は、ブラウザーの開発ツールで、エラーを確認できます。

- 開発ツールのネットワークタブを開く
- 「ログを保持」をチェック　英語表記の場合は、「Preserve log」をチェック
　※編集画面から詳細画面に画面遷移すると、通常はログが消えますが、「ログを保持」をチェックすることで、前の画面のログを見ることができます。
- 編集画面でエラーが発生するまで、「保存」を繰り返す
- エラーが発生したら、赤く表示されている処理をクリックして、プレビュータブで内容を確認

# REST API でエラーになる要因

よくある要因としては、アプリの項目変更や制約条件の変更で、JavaScript カスタマイズやプラグインでエラーになります。

- アプリについて、項目の追加やフィールドコードの変更等
　プラグイン再設定が必要な場合があります。
- アプリについて、必須や文字数制限などの制約について変更
　既存レコードに、必須や文字数制限のチェックでエラーになるものがあると更新できません。
【git filter-repo】リポジトリーのファイルとコミット履歴をディレクトリ階層を変えつつ別のリポジトリーに移動する

# 前置き

表題の件のようなことをやりたくて調べると`git filter-branch`を使用する例が良く出てきますが、今はサードパーティの`git filter-repo`の使用が推奨されています。  
`git filter-repo`を使って「リポジトリーのファイルとコミット履歴をディレクトリ階層を変えつつ別のリポジトリーに移動」した際の手順をまとめました。

# 1. git filter-repo コマンドを使えるようにする

## 1-1. scoop のインストール

`python`と`git filter-repo`を`Scoop`でインストールするため、まず`Scoop`をインストールします。

https://scoop.sh/

PowerShell を実行するだけです。

``` PowerShell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
```

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

コマンドプロンプトで以下コマンドを実行します。

```
scoop install python
```

## 1-3. git-filter-repo のインストール

コマンドプロンプトで以下コマンドを実行します。

```
scoop install git-filter-repo
```

## 1-4. PCを再起動する

python のパスが通っておらず`git filter-repo`が見つからない可能性が大なので、一旦PCを再起動します。

# 2. コミット履歴を移動したいリポジトリーの --no-local リポジトリーを作成する

普通に clone したリポジトリーで`git filter-repo`でコマンドを実行すると以下のように警告が表示されます。

```
Aborting: Refusing to destructively overwrite repo history since
this does not look like a fresh clone.
  (expected freshly packed repo)
Note: when cloning local repositories, you need to pass
      --no-local to git clone to avoid this issue.
Please operate on a fresh clone instead.  If you want to proceed
anyway, use --force.
```

一旦、以下のようにローカル間で clone したリポジトリーで作業します。

```
cd temp
git clone https://github.com/old-repo.git
git clone old-repo old-repo-work --no-local
```

# 3. git filter-repo の実行

引越し先では`hoge`のファイルはすべて`src`ディレクトリ配下に移動することにします。
以下のコマンドを実行します。

```
cd old-repo-work
git filter-repo --to-subdirectory-filter src
```

# 4. 引越し先のリポジトリーでファイルとコミット履歴を取り込む

## 4-1. 引越し先のリポジトリーで old-repo-work リポジトリーをリモートリポジトリとして追加する

```
cd ..\new-repo
git remote add old-repo-work ..\old-repo-work
```

## 4-2. 引越し先のリポジトリーで old-repo-work をマージする

`--allow-unrelated-histories`を付与することで履歴を共有していないコミット履歴を取り込む事ができるようになります。

```
git fetch old-repo-work
git merge old-repo-work/main --allow-unrelated-histories
```
【Tips】時系列順に週を並べたい

## はじめに
とあるダッシュボードを作っている際、週毎の売上推移を見るため、日付のディメンジョンを「週」だけにしたとき、正しく並ばない問題が発生しました。

▼の例だと、時系列順であれば、「45週から始まり、4週で終わる」並びですが、単純に昇順で並んでしまっています。

この解決方法を見つけたので、記事にまとめました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/8f780899-4426-36f1-43f0-2dcbe07cf7fa.png)


## 解決方法
:::note info
年月日の「Year」と「Week」を結合し、その結果を大小比較して並べる。
:::

おそらく最もシンプルな解決法は、「年月日のディメンジョンを入れる」ことだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/41c4ccca-ee64-21d7-3071-794bf6014c8f.png)

ただ今回は、「週」のディメンジョンのみという要求仕様があったため、解決には少々工夫が必要でした。

### ① Prep上で、レコード毎に「Year」と「Week」を文字列結合
文字列を結合するときの前提は以下の通りです。
- 文字列の構造は、[Year]＋[Week]で、6桁とする。
- [Week]が1～9週の場合、結合結果を6桁とするために、Weekの冒頭に'0'を付与する。

この前提に従って、文字列結合を行う計算フィールドを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/7829dbd7-590e-f264-be04-6fcfb0246d45.png)

▼2022年の52週は、'202252'となっていますので、正しく結合されていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/c075b7a7-51e8-3a52-8760-876cc19616ab.png)

### ② 結合結果を「数値型」に変換する。
大小比較をしたいので、文字列型を「数値型」に変えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/9246825f-0ac0-b145-7a4b-6a7ae511c533.png)

### ③ ②を基準として、ORDER BYで昇順に並び替える。
「週」に「年」を付加した6桁の数値に作り変えたので、これを基準で並び替えます。

▼の場合、「週」だけ見ると、前年(2022年)の方が大きいですが、6桁の数値で見ると、当年(2023年)の方が大きいため、正しく時系列順に並んでいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/912402c1-f00c-310e-ac18-a861fe301fb7.png)

## おわりに
いかがでしょうか。もっとシンプルな方法や関数などあれば、ぜひ教えてください！
Node.js: ChatGPT Speech to text の使い方 (axios)

こちらと同じことを Node.js で行いました。
[Curl: ChatGPT Speech to text の使い方](https://qiita.com/ekzemplaro/items/df9953f484f329ca11de)
音源も同じです。

## プログラム

```js:node_text.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	node_text.js
//
//						Apr/05/2023
// ---------------------------------------------------------------
'use strict'
const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')
const dotenv = require('dotenv')

dotenv.config()

const token = `${process.env.API_KEY}`
const file = 'yonendowa1_08_rappa_niimi.mp3'
const model = 'whisper-1'

const form = new FormData()
form.append('file', fs.createReadStream(file))
form.append('model', model)

axios({
  method: 'post',
  url: 'https://api.openai.com/v1/audio/transcriptions',
  data: form,
  headers: {
    'Content-Type': `multipart/form-data boundary=${form.getBoundary()}`,
    'Authorization': `Bearer ${token}`
  }
})
  .then(response => {
    console.log(response.data)
  })
  .catch(error => {
    console.error(error)
  })

// ---------------------------------------------------------------
```

```text:.env
API_KEY="sk-11******************************************"
```

必要なライブラリーのインストール

```bash
npm install axios
npm install dotenv
```

## 実行結果

```text
$ ./node_text.js 
{
  text: 'LibriVox.orgのために録音されました。 ラッパ おじいさんは田舎に一人ぼっちで暮らしていました。 だんだん耳が遠くなったので、 都にいる息子のところへ 耳が遠くなったから よく聞こえる機械を買って送ってくれ と言ってやりました。 息子はいろいろ探したが あまり良い機械がないので ラッパを買って これを逆さまにして耳につけて ラッパの尻から聞きなさい と言ってやりました。 おじいさんはそのラッパを喜んで使っていましたが 耳はどんどん遠くなって とうとうつんぼになりました。 それでもおじいさんは あのラッパでは聞こえなくなったから もっとよく聞こえるのを 送ってくれと息子に手紙をやりました。 息子はいろいろ考えてから また前のラッパと同じラッパを送って このラッパを耳につけると 私の声が聞こえます と言ってやりました。 おじいさんはそのラッパを耳に当ててみました。 そして ああ、聞こえる、聞こえる 懐かしい息子の声が聞こえる と言って喜びました。 けれど、それはおじいさんの耳が聞いたのではありません 心が聞いたのです。 ラッパ終わり この録音はパブリックドメインです。'
}
```

## 確認したバージョン

```text
$ node --version
v19.8.1
```
Windows10でデスクトップアイコン（ゴミ箱やコンピューターなど）の表示切替

# やり方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9580653a-63b7-3019-a009-58538b48b8a8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/53975fd1-8664-8f98-fd38-feafb797767c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9e3f4266-0880-726a-8874-0e0c62576945.png)

# 参考サイトさん

https://support.microsoft.com/ja-jp/windows/%E3%81%94%E3%81%BF%E7%AE%B1%E3%81%AE%E8%A1%A8%E7%A4%BA%E3%81%A8%E9%9D%9E%E8%A1%A8%E7%A4%BA%E3%82%92%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%8B-0d4d40aa-be23-91ec-96ab-338818d5e5fb

# バージョン

Windows 10 Pro 22H2 19045.2788
Railsフォームビルダー


form_withメソッドの使い方

```rb:form_withメソッドの使用例
<%= form_with model: @user, url: :registration do |f| %>
  <%= f.label :name, "名前" %>
  <%= f.text_field :email %>
  <%= f.submit "送信" %>
<%= end %>
```


::: note info
フォームビルダーに備わっているメソッド
ブロック引数 f は<font color="red">フォームビルダー</font>と呼ばれます。
このオブジェクトのメソッドを呼び出すと、フォーム上に部品が生成されます。先程の例では、
３つのメソッドを用いてボタンを生成しています。

     label・・ラベル
     text_field・・テキスト入力欄
     submit・・・送信ボタン

[フォームビルダー用のメソッドのリスト]
https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html
:::
WordPress: Local で CGI (Perl スクリプト) を動かす

Local (by flywheel) を v6.7 にアップデートしたら、Perl のスクリプトが動かなくなった。アクセスすると実行でなくファイルがダウンロードされてしまう… ぐぬぬぬ。。

解決法は公式コミュニティに投稿されていた。感謝！
[Cgi-bin script does not run - Local Community](https://community.localwp.com/t/cgi-bin-script-does-not-run/3226/3)

## 手順

1. Local のコントロールパネルで、任意のプロジェクトを開き、Webサーバーを nginx から Apache に切り替える
2. プロジェクトフォルダ/conf/apache/apache2.conf.hbs に以下を追記。挿入箇所は、最後の ######## の前にした。
    ```apache2.conf.hbs
    #
    # Add on 2023-04-05
    # To be able to use Perl
    # https://community.localwp.com/t/cgi-bin-script-does-not-run/3226/3
    #
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Require all granted
    </Directory>
    ```
3. Local を再起動
4. サイトを開き、CGI が動いていることを確認できたら OK!

Apache に変えなければならないのが嫌だけど、これで、cgi-bin ディレクトリ内の Perl スクリプトが動作するようになった。
深層学習、機械学習でおすすめのサイト、コンテンツ

<h1>はじめに
<p>　個人的に気に入っているサイトを紹介していこうと思います。これから紹介するサイトは、どれもわかりやすく、面白いので情報収集や機械学習の勉強にきっとお役に立てると思います。Colabのものがあるので、部下や学生の方の指導に使っても面白いかもしれません。深層学習の基礎から最先端をカバーしているサイト、サービスを紹介していこうと思います。

<h1>NVIDIA DeepLearning
<p>

https://blogs.nvidia.co.jp/category/deep-learning/

 GPU大手企業であるNVIDIAの中の人が書いている記事です。一流のデータサイエンティスト、エンジニアが業界の動向やホットな技術を解説しているので、流行をキャッチアップするのに良きです。Qiitaでは見慣れない記事が多く、たまに読むと新鮮な気持ちがしますよ。

<h1>FarmL Blog 
<p>

https://farml1.com/

 家庭菜園が好きなデータサイエンティストさんのブログです。最先端の画像解析が、「やってみた」を通して書かれています。具体的には、DALL·E mini、YOLO、MiDas、DeepSort、Pix2Pix、TecoGANなどなど。それらの動かし方も解説されているので、画像解析を実践的にこのサイトで学ぶことも可能です。個人的にお気に入りなのは、「YOLOv5で物体検出した作物の数を数える【Object Counter】」(https://farml1.com/object_counter/)です。「人工知能を使って解析した！」というかんじがあって、楽しいですよ。

<h1>Deep Learning JP(https://deeplearning.jp/)
<p>　Deep Learning JP はディープラーニング技術に関する研究会です。無料で人工知能を理論から実装まで、講座(Zoom)を通して、学ぶことができます。なんと、人工知能界隈で世界的に権威のある松尾研究室が監修しています。プログラミングスクールだったら、100万円するのではないかという内容を無料で学べる(宿題も出ます)ので、かなりすごい講座だと思います。ただ、「学生」という条件があることに注意です。

<h1>Axross Recipe
<p>

https://axross-recipe.com/

　「学んだが活用できない人を減らしたい」という想いのもと、エンジニアのノウハウを”レシピ”という独自コンテンツで提供するプラットフォームです。学習者は”レシピ”をもとに手を動かしながら学習することができ、エンジニアは投稿者として、”レシピ”を公開することで知名度や対価を得ることができます。Axross Recipeは、ソフトバンクグループ社内起業制度「ソフトバンクイノベンチャー（SoftBank InnoVenture）」で事業化検討決定され、立ち上げたサービスです。なんかすごいですね。
<p>　筆者も何度か利用したことがあります(確かAlphafold2、twitterAPIを用いた形態素解析)。コンテンツは、Colabで実装されているので、再現性があるので、逐一バージョン違いによるエラーを解決する必要がないので、ストレスフリーです。有料ですが、500円ぐらいなので、「ポケットマネー、ポケットマネー」と自分を納得させながら支払っています。結構いいサービスのですが、意外と知られていないので、残念です。

引用文献；https://axross-recipe.com/

<h1>SonyのGithub
<p>

https://github.com/sony/nnabla-examples

 　Sonyの画像解析例のレポジトリーです。結構いろいろ紹介されているので、おすすめですよ。Colabなので、教材として利用するのも良いかもしれません。

<h1>最後に
<p>　深層学習を楽しく学べたら～と思って、記事を書かせて頂きました。みなさんの学びが少しでもワクワク感が増えたら、嬉しいです。
【Windows版】PythonのセットアップからHelloWorldを行うまで

# Pythonのインストール
## Pythonインストーラーをダウンロードする
下記URLから、特定のバージョンのインストーラーをダウンロードする。
https://qiita.com/drafts/3787f6c61a4fb38d6a89/edit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/1a276f6f-9fb6-ebed-9a6d-dac67f44a3c0.png)
※今回は、バージョン3.10.9を使用する。
## Pythonをインストールする
1. ダウンロードした、インストーラを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/15a8c35e-6370-d42a-1986-cf748c4532ce.png)
1. 「Add python.exe to PATH」にチェックを入れ、「Install Now」をクリックしインストールを開始する。
![Group 32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/92c37c56-1a68-3c92-3290-8415dd7a609c.png)
1. インストールが完了すると、「Set up successful」と出るので「close」をクリックしウィンドウを閉じる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/43edefe4-2afd-5238-79cc-79074ed86ce4.png)
## Pythonがインストールされているかを確認する。
1. 「command prompt(コマンドプロンプト)」を開く。(検索で「cmd」と入力するとヒットする)
1. コマンドプロンプト上で`python`と入力し、以下のように起動するかを確認する。
```
C:\Users\<ユーザー名ディレクトリ>>python
Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec  6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
3.以下のコマンドを入力して、文字列が出力されるかを確認する。
```
>>> print("Hello world")
Hello world
``` 
## VSCodeをダウンロードする。
1. 以下のリンクからVSCodeのインストーラーをダウンロードする。
https://code.visualstudio.com/download
![Group 33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/1d88d174-eb3e-01a5-fe46-0b1173984e30.png)
1. インストーラーを起動し、「VSCode」をインストールする。
1. 「VSCode」を起動する。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/b080ad21-3017-239e-b721-a6dc6de4e4ec.png)
## VSCodeを使って、Pythonのプログラミングを行う
1. メニュータグの「File」から「New Text File」を選択し、新しいテキストエディタを開く。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/212c98a2-c199-2642-506d-ea940839261d.png)
1. 「File」から「Save As」を選択し、任意のフォルダに保存する。(この時に拡張子は「Python(.py)」を選択している事。)
1. テキストエディタに以下のソースコードを入力し、保存する(Ctrl+s)。
``` .py
print("Hello world")
```
## ターミナルから保存したプログラムを起動する。
1. メニュータグの「Terminal」の「New Terminal」をクリックし、ターミナルを表示する。![Group 34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114007/c7977cad-723f-074c-e6b3-f6687a86a42c.png)
1. `cd`コマンドでソースコードの保存先までディレクトリを移動する。(「cd」コマンドについては「cd コマンド」でググると記事が出てくるので参考にする事。 )
1. 以下のコマンドを入力し起動するかを確認する。
```
PS C:\python> python <保存したファイル名>.py
Hello world
```
【データ可視化/Redash】EC2でRedashを立ち上げて、Snowflakeのデータを可視化する

# 今回の課題
EC2にRedashを建てて、Snowflakeのデータを参照するまでにつまずいたりしたので、流れを記録する。

ちなみに、これまで下記の記事のようにRDSからスナップショットをparquet形式のファイルでS3にエクスポートし、S3にエクスポートしたファイルをSnowflakeにロードする。ということを行ってきた。
今回はそれらをRedashで可視化してみる。

https://qiita.com/Ayumu-y/items/523f700960129c57e3b3

https://qiita.com/Ayumu-y/items/d6713e09b0a409d1bd25

## 進めた手順
### 1)EC2にRedashを立ち上げる
下記の手順でEC2にRedashを立ち上げた
##### 1)-1. リージョン毎に用意されているAMIからインスタンスを立ち上げる
└`ca-central-1`のAMIを使用した。
└また、インスタンスタイプは`t2.small`が推奨されていたので、そちらを使った。
<font color="Red">※インスタンスタイプを無料枠の`t2.micro`でインスタンスを立ち上げると、ブラウザからRedashにアクセスすることができなかったので注意。</font>
└パブリックIPアドレスの自動割り当ては「有効化」を選択して、パブリックIPアドレスは割り当てておく。

##### 1)-2. 立ち上げたインスタンスのセキュリティグループを設定する
立ち上げたインスタンスのセキュリティグループのインバウンドルールに、
`ポート22(SSH), 80(HTTP), 443(HTTPS)`を追加する。
これによって、インスタンスにSSH, HTTP, HTTPS接続でアクセスすることができるようになる。


##### 1)-3. Elastic IPを設定する
EC2のパブリックIPアドレスは動的なIPアドレスなので、インスタンスを立ち上げるたびに変ってしまう。
そこで、Elastic IPアドレスをEC2インスタンスに割り当てることで、
EC2インスタンスのアドレスを固定にすることができる。




### 2)ブラウザからRedashにアクセスしてログインする
ブラウザのアドレスバーに、`https://[ECのElastic IPアドレス]`を入力して検索することで、Redashのログイン画面にアクセスすることができるので、必要項目を入力してRedashにログインする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/278622c1-3140-6840-2987-781fbd406875.png)

### 3)RedashとSnowflakeを接続する
ログインが完了したら、
Redashのトップページの`Connect a Data Source`をクリックして、
`Dew Data Source`に進み、`Snowflake`を選択する。
すると下記のような画面に進むので必要な箇所を入力していく。


![a9ac9a0ae8b9bae39e31b26f85c06e83.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/2153c26c-c1ed-10d5-d88d-9d4e2ed2f02c.png)

##### 入力項目
SnowflakeとRedashを接続する際の、
入力項目が少し分かりずらかったため補足説明をメモ。

* `Name`：接続設定につけたい名称を入力する。

* `Account`：`[Locator].[リージョン名].aws`を入力する。
Locatorはworksheets上で`show organization accounts;`を実行して、抽出されたデータの`account_locator`カラムの値と同じ。
* `User`：Snowflakeのユーザー名を入力する。
* `Password`：Snowflakeのパスワードを入力する。
* `Warehouse`：使用したいWarehouseを入力する。
* `Database`：Redashに接続したいDatabaseを入力する。
* `Region`：入力すると原因不明のエラーが発生するので空欄にする。

### 4)Redashでクエリを実行してみる
メニューバーの`Create > Query`から、
下記の画像のようなクエリの編集画面に飛ぶことができるので、ここでクエリを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/b7ae9116-35cd-44e9-ecd3-0368193c7e53.png)

また、クエリ編集画面の下の、`+ New Visualization`をクリックすることで、
Visualization Editorに飛ぶことができ、データを可視化することができる。
`Save`と`Publish`ボタンを押して、保存することも忘れないようにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/ed8a5e2c-c2ac-aef0-dfe2-e8b14cc6fcee.png)

# まとめ
以上で、Redashでデータを可視化するところまで実装することができた。

## おまけ
気になった言葉や参考にした記事など。
### AMI（Amazon Machine Image）とは
EC2インスタンスの起動に必要な情報を提供するテンプレート。
OSやボリュームの情報などを提供する。

今回の件では、Redashが用意しているAMI(OSやボリュームなどを提供するテンプレート)を使って、
EC2のインスタンスを構築した。というイメージ。

### 参考記事


https://redash.io/help/open-source/setup

https://blog.serverworks.co.jp/covid-19-visualization-via-redash-snowflake
Pythonで秘密鍵と自己証明書を生成する

## Pythonで署名をしたい
PythonでPDFに対する署名をテストしたかったため、まずは秘密鍵と自己証明書をワンクリックで生成できるスクリプトを作成してみました(わからない部分は某AIさんにお世話になりました)

私の環境のPythonバージョンが3.8.6と少し古いですが最新のものでも動くと思います(思ってるだけかもしれません)

## ライブラリ
ライブラリは**cryptography**を使用します。
```bash
pip install cryptography
```

## コード
```python
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import datetime


def generate_private_key():
    # RSA秘密鍵を生成
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    return private_key


def save_private_key_to_pem(private_key, filename):
    # 秘密鍵をPEM形式でファイルに保存
    with open(filename, "wb") as key_file:
        key_file.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        ))


def generate_self_signed_certificate(private_key):
    # 秘密鍵から公開鍵を取得
    public_key = private_key.public_key()

    # 証明書のsubjectとissuerを設定
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u"JP"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Osaka"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u"Osaka"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"xxxxx"),
        x509.NameAttribute(NameOID.COMMON_NAME, u"xxxxx.com"),
    ])

    # 自己署名証明書を生成
    cert = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        public_key
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.datetime.utcnow()
    ).not_valid_after(
        # 証明書の有効期限を1年後に設定
        datetime.datetime.utcnow() + datetime.timedelta(days=365)
    ).add_extension(
        # Subject Alternative Nameを追加
        x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),
        critical=False,
    ).sign(private_key, hashes.SHA256())

    return cert


def save_certificate_to_pem(cert, filename):
    # 証明書をPEM形式でファイルに保存
    with open(filename, "wb") as cert_file:
        cert_file.write(cert.public_bytes(serialization.Encoding.PEM))


def main():
    # 秘密鍵の生成と保存
    private_key = generate_private_key()
    save_private_key_to_pem(private_key, "private_key.pem")

    # 自己署名証明書の生成と保存
    cert = generate_self_signed_certificate(private_key)
    save_certificate_to_pem(cert, "certificate.pem")


if __name__ == "__main__":
    main()

```

上記コードを実行すると同階層のフォルダ内にprivate_key.pem(秘密鍵)とcertificate.pem(自己証明書)が生成されます。簡単！！

PDFへの署名に関しては出来次第投稿しようと思っています。
rex0220 計算式プラグイン S-JIS対応していない漢字を変換

cli-kintone で CSV出力すると、エラーになるとのことで、kintone でS-JIS対応していない漢字を変換できないかとの相談があり、計算式プラグインで対応を検討

# 概要

Shift_JIS (CP932) では保存できない文字40字を変換
![2023-04-05_15h35_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/fdf108c4-9b31-4865-f013-75608a976837.png)

「変換前」、「変換後」は、動作検証のため設定。
「文字列を変換」は、文字列入力時にそのまま変換

※参考[テキストエディター「Mery」](https://www.haijin-boys.com/wiki/%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E6%95%B4%E5%BD%A2)より

>表外漢字字体表 1022字のうち Shift_JIS (CP932) では保存できない文字40字を、保存できる文字に置換します。

# 操作例

![2023-04-05_15h50_56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/021aace4-e654-883d-3957-92580b966b4c.gif)

# 計算式プラグイン設定

![2023-04-05_15h34_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/478d2f78-eac6-3666-9efb-e3efa984dac9.png)

- 「循環参照を許可」をチェック
- 文字列の計算式
    - Shift_JIS (CP932) では保存できない文字40字を１文字ずつ、代替文字に変換

- 計算式プラグイン Ver.61 以降（サロゲートペア文字対応）
```.js
LET(
  x,"啞焰鷗摑麴噓俠頰軀俱繫姸鹼嚙攢𠮟繡蔣醬蟬搔瘦驒簞塡顚禱瀆吞囊剝潑醱屛幷麵萊屢沪蠟",
  y,"唖焔鴎掴麹嘘侠頬躯倶繋妍鹸噛攅叱繍蒋醤蝉掻痩騨箪填顛祷涜呑嚢剥溌醗屏并麺莱屡濾蝋",
  z,文字列,
  w,ARRAY_FOR(LENGTH(x),idx,  
     FSET(z, REPLACEALL(z, SUBSTR(x,idx,1),SUBSTR(y,idx,1)))
  ),
  z
)
```

- 計算式プラグイン Ver.60 以前（サロゲートペア文字未対応）
    - "𠮟"は、SUBSTR で切り出すと２文字になってしまうため、別で変換
```.js
LET(
  x,"啞焰鷗摑麴噓俠頰軀俱繫姸鹼嚙攢繡蔣醬蟬搔瘦驒簞塡顚禱瀆吞囊剝潑醱屛幷麵萊屢沪蠟",
  y,"唖焔鴎掴麹嘘侠頬躯倶繋妍鹸噛攅繍蒋醤蝉掻痩騨箪填顛祷涜呑嚢剥溌醗屏并麺莱屡濾蝋",
  z,文字列,
  w,ARRAY_FOR(LENGTH(x),idx,  
     FSET(z, REPLACEALL(z, SUBSTR(x,idx,1),SUBSTR(y,idx,1)))
  ),
  REPLACEALL(z,"𠮟","叱")
)
```
STSでエラー: SunCertPathBuilderException: unable to find valid certification path to requested target

# 事象

- STSで新規Springスタータープロジェクトの作成を実行すると、証明書エラーが表示され、プロジェクトを作成できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620712/f219dd54-7a02-09c9-38f6-5172a2c8efd4.png)

# 環境

- Windows10
- Corretto8u362
- STS4.18

# 前提

- CorrettoにJAVA_HOMEとPATH設定済み
- STSインストール済み

# 手順

## 証明書のダウンロード

- ブラウザでhttps://start.spring.io/ にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620712/2668d3ea-760e-8acc-99cd-ecb6ad274bc5.png)

- URL左のロックアイコンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620712/c96c533f-40ae-5b44-fdb3-b55960675a07.png)

- 「接続がセキュリティで保護されています」の右側の証明書アイコンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620712/5322c135-0bad-5b81-a5ad-c44e17c7820a.png)

- 詳細タブでエクスポートをクリック、ローカルの適当な場所にダウンロード(_.spring.io.crt)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620712/bfae6ead-86b4-809c-5f28-7af8b617a3ee.png)

## キーストアに証明書を追加

- コマンドプロンプトを起動し以下を実行

```
keytool -importcert -keystore "C:\Program Files\Amazon Corretto\jdk1.8.0_362\jre\lib\security\cacerts" -storepass changeit -file "C:\Users\user\Downloads\_.spring.io.crt"
```

- 「この証明書を信頼しますか。 [いいえ]:  」が表示されたら、「はい」と入力し実行

```
この証明書を信頼しますか。 [いいえ]:  はい
証明書がキーストアに追加されました
```

## iniにJVMオプション追加

- STSインストールフォルダ直下のSpringToolSuite4.iniをSpringToolSuite4.ini.orgなどにバックアップ
- SpringToolSuite4.iniをエディタで開き、最終行に以下を追加

```
-Djavax.net.ssl.trustStore=C:\Program Files\Amazon Corretto\jdk1.8.0_362\jre\lib\security\cacerts
-Djava.net.ssl.trustStorePassword=changeit
```

## 動作確認

- STSを起動
- 新規Springスタータープロジェクトの作成を実行し、エラーが解消されてることを確認する

# 他の手段

- STSでプロジェクトを作成せず、https://start.spring.io/ で作成したプロジェクトを利用すれば良い気がする

# 参考にしたサイト

https://stackoverflow.com/questions/50764343/spring-tool-suite-suncertpathbuilderexception-unable-to-find-valid-certificati

# めも

- JDK8はキーストアがjreフォルダ配下にある```$JAVA_HOME\jre\lib\security\cacerts```
- JDK11以降では```$JAVA_HOME\lib\security\cacerts```
超初心者向け　ワイルドカードと正規表現について

## ワイルドカードと正規表現の違い
ドットインストールで、コマンドラインについて勉強していたら、いきなりワイルドカードが出てきて、あれこれ何だっけってなって、調べたんですが、あまりいい情報が出てこなくて、正規表現と関連性があった気がするなと思って調べてみました。そしたらやはり、比較記事が見つかりました。とてもわかりやすい記事だったのでシェアします。もし同じ疑問思っている方がいたらみてみてください。

[ワイルドカードと正規表現の違い](https://algorithm.joho.info/computer/wildcard-regular-expression/)

今後この記事で、自分で解説を書く予定です。とりあえず今回は、共有という形で投稿します。
Railsのconfig（設定ファイル）の書き方

# Railsのconfigについて

Railsプロジェクトの設定変更をする事がしばしばあります。

- 既存のconfigファイルの書き換え
- configファイルの新規作成
- 設定を書き加える

##### ここではconfigの`置き場所`、`書き方の例`について簡単に触れたいと思います。

## 初期化コードの置き場所
initializerなど最初に実行されるconfigについて
##### Rails Guidesより抜粋
> 初期化コードの置き場所が4箇所あります。
>
> * config/application.rb
> * 環境ごとの設定ファイル
> * config/initializerファイル
> * after_initializerファイル
>  このフックは、アプリケーションの初期化が完了し、
>  かつconfig/initializers以下のイニシャライザが実行された後に実行されます。

https://railsguides.jp/configuring.html


## configの記述例
initializersの例です。
```rb:config/initializers/action_view.rb（新規作成）
# form_withはリモートフォームを使用しない為、普通のフォームを作るよう設定変更する
Rails.application.configure do
  config.action_view form_with_generates_remote_forms = false
end
```

*  form_withの設定方法（Rails Guidesより抜粋）
![スクリーンショット 2023-04-05 15.24.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288338/828f8367-c514-af24-4f6b-a4599ea3a49c.png)


* デフォルトでは、Strong Parametersと呼ばれるセキュリティ強化策が有効になっています。これを開発効率のために一時的に無効化する設定をしてます。真似しないように！
```rb:config/initializers/action_controller.rb（新規作成）
Rails.application.configure do
  config.action_controller.permit_all_parameters = true
end
```

## 最後に
configについて詳しく知りたければ、やはりRails Guidesを熟読しましょう！

Rails Guides(日本語)

https://railsguides.jp/configuring.html

Rails Guides(英語)

https://guides.rubyonrails.org/configuring.html
【AWS】ALB(Application Load Balancer)による負荷分散作成の備忘録

## 事前準備

- EC2に簡単にWebサーバーアプリを立てて、アクセスするとデフォルトページが表示されるようにしておく

## 1. ターゲットグループの作成

1.Amazon EC2 コンソール (https://console.aws.amazon.com/ec2/) を開きます。
1. ナビゲーションペインの [ロードバランシング] で [ターゲットグループ] を選択します。
1. [Create target group] を選択します。
1. [基本的な設定] で、[ターゲットタイプ] をインスタンスのままにします。
![ALB.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e75a7673-a6b5-6bd8-48ab-83374327bcc2.png)
1. [ターゲットグループ名] に、新しいターゲットグループの名前を入力します。
1. デフォルトのプロトコル（HTTP) とポート (80) のままにします。
1. インスタンスを含んでいる VPC を選択します。プロトコルのバージョンを HTTP1 のままにします。
![ALB1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/fa490aef-915a-2b2b-21c9-a428a88db342.png)
1. [Next] (次へ) をクリックします。
1. [ターゲットの登録] ページで、ルーティング先のEC2を選択して、Include as pending belowを押す
![ALN2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e0573e29-68eb-06ae-930d-304985c15445.png)
1. Create target groupを押す

## 2. ロードバランサーの作成

1. ナビゲーションペインの [Load Balancing] で、[Load Balancers] を選択します。
1. [Create Load Balancer] を選択します。
1. [Application Load Balancer] で [作成] を選択します。
![ALB4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/2a823958-2667-7d61-2e9e-57d6bffb8c3e.png)
1. [ロードバランサー名] に、ロードバランサーの名前を入力します。例えば、my-alb です。
1. [スキーム] および [IP アドレスタイプ] については、デフォルト値のままにします。
1. [ネットワークマッピング] で、EC2 インスタンスに使用する VPC を選択します。アベイラビリティーゾーンを少なくとも 2 つ選択する
![ALB5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/f62ec0d3-355a-7b43-19ed-3a34743e00b4.png)
1. [セキュリティグループ] で、セキュリティグループを選択します。
1. [リスナーとルーティング] で、今回はHTTPなのでデフォルトのプロトコルとポートを保持し、リストからターゲットグループを選択します。
![ALB6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/ec2cf636-7d8d-b0f1-f932-c28b6bb57aa3.png)
1. [デフォルトのアクション] で、登録したターゲットグループを選択します。
1. 設定を確認し、[ロードバランサーの作成] を選択します。

## 3. ロードバランサーのドメインへアクセス

1. ナビゲーションペインの [ロードバランシング] で [ターゲットグループ] を選択します。
1. 作成したターゲットグループを選択します。
1. [Targets] を選択して、インスタンスの準備ができていることを確認します。
1. ナビゲーションペインの [Load Balancing] で、[Load Balancers] を選択します。
1. 作成したロードバランサーを選択します。
1. ロードバランサーの DNS nameをブラウザのアドレスフィールドに入力して、アクセス可能か確認する。
![ALB7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/621de9cf-d9c0-8c58-5a12-51a2e13b2856.png)

## HTTPSにするには
下記公式サイトの手順に従い、HTTPS リスナーを追加する

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/create-https-listener.html

## 参考サイト

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancer-getting-started.html
visudoがない

## 背景
<b>debian11をインストールしたとき、`sudo`がインストールされていなかった。</b>

## 試したこと
sudoをインストールした後に、sudo apt install XXXを実行
👇
sudo権限がないと怒られた。
👇
visudoコマンドをroot権限からvisudoを実行
👇
visudoがないと怒られた。
<b>なぜvisudoのコマンドがありませんとなっていたのか？</b>

## 答え
`su`を実行していた

## 解決方法
`su -`を実行する
## 解説
ハイフンがないと環境変数がログインユーザーのままになってしまい、visudoが実行できない

## おまけ
Linuxユーザーにsudo権限を付ける方法
1. `visudo`で`sudoers`ファイルを開く
1. `sudoers`内の`sudo`グループに関する記述が`%sudo ALL=(ALL) ALL`になっていることを確認
    1. `%`はグループを表す
1. `usermod --append -G sudo <username> `を実行
1. `id`コマンドで`sudo`管理グループに追加されているか確認
1. `reboot`または`shutdown -r now`で再起動して`sudoers`ファイルの変更を反映させる

※他のテキストエディタで`sudoers`ファイルを開くと、read onlyなため編集できない！
[TypeScript] オブジェクトがN個のみのKey/Valueペアを許容する型

## 背景
オブジェクトのプロパティの個数を型で明示したかったので、それを実現する型です。個数が期待とは異なれば型エラーが起きます。よりベターな方法があればコメントください。

## コード

```typescript
/**********
 * Type
 ***********/
type ObjectEntries<T, U = Required<T>> = {
  [K in keyof U]:[K,U[K]]
}[keyof U]

type UnionToIntersection<U> = (
  U extends never ? never : (arg: U) => never
) extends (arg: infer I) => void
  ? I
  : never;

type UnionToTuple<T> = UnionToIntersection<
  T extends never ? never : (t: T) => T
> extends (_: never) => infer W
  ? [...UnionToTuple<Exclude<T, W>>, W]
  : [];

type Length<T extends unknown[]> = T['length']

type SatisfiedObject<T, N = -1> = Length<UnionToTuple<ObjectEntries<T>>> extends N ? T : never;

/**********
 * Type Checker
 ***********/
function asZeroPair<T extends Record<string, any>>(_: SatisfiedObject<T, 0>) {}
function asOnePair<T extends Record<string, any>>(_: SatisfiedObject<T, 1>) {}
function asTwoPair<T extends Record<string, any>>(_: SatisfiedObject<T, 2>) {}

/**********
 * Example
 ***********/
{
	const obj = {};
	asZeroPair(obj); // 👍
	asOnePair(obj);  // type error
	asTwoPair(obj);  // type error
}

{
	const obj = {a: 1};
	asZeroPair(obj); // type error
	asOnePair(obj);  // 👍
	asTwoPair(obj);  // type error
}

{
	const obj = {a: 1, b: 2};
	asZeroPair(obj); // type error
	asOnePair(obj);  // type error
	asTwoPair(obj);  // 👍
}
```

## 解説

1. `Object` を `ObjectEntries`[^1] で`[key, value]`のUnionに変換
    - ObjectEntries型への変換はTypeChallengingにあるので、これの中から良さそうな回答を参照[^1]
2. UnionをTupleに変換
    - UnionをTupleへの変換は直接行うことは基本的にできないので、一度Intersectionに変換した後に、Tupleへ再帰的へ変換する。[^2]
3. Tupleの個数を`.length` or `item['length']`で取得
4. Conditional TypeでTupleの個数がN個であることを確認する
5. 型チェックを行うためのas関数を作成してここまでに作ってきた型を使って型チェック

[^1]:
    Q [type-challenges/README.md at main · type-challenges/type-challenges · GitHub](https://github.com/type-challenges/type-challenges/blob/main/questions/02946-medium-objectentries/README.md)
    A [2946 - ObjectEntries · Issue #2988 · type-challenges/type-challenges · GitHub](https://github.com/type-challenges/type-challenges/issues/2988)
[^2]:
    [TypeScript で union to tuple をするのが難しい理由](https://zenn.dev/dqn/articles/union-to-tuple)
    [Type manipulations: union to tuple · Issue #13298 · microsoft/TypeScript · GitHub](https://github.com/microsoft/TypeScript/issues/13298#issuecomment-885980381)
Webページ上のコードブロックにシンタックスハイライトを適用する

# Webページ上のコードブロックにシンタックスハイライトを適用する

### コードブロックとは、ソースコードやコードの一部を示すために使用される区間を指す。
HTMLではpreタグとcodeタグを組み合わせてコードブロックを表現することが一般的である。

- preタグは、前後の改行や空白をそのまま表示するためのタグである。
- codeタグはコードやコンピュータ上の要素を示すためのタグである。

これらのタグを組み合わせることで、コードの構造を保持したままコードブロックを表示できる。

### シンタックスハイライトは、ソースコードの構造や構文に基づいて異なる要素に色を付けることで読みやすくする。
ウェブページに埋め込まれたコードブロックに、シンタックスハイライトを適用することができる。
この場合、highlight.jsやPrismなどのJavaScriptライブラリを使用することが一般的である。




## コードブロックにシンタックスハイライトを適用するプログラムの例
html:
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
</head>
<body>
  <h1>Pythonのプログラムを表示する例</h1>
  <pre><code class="language-python">
    def hello_world():
        print("Hello, World!")
    
    hello_world()
  </code></pre>

  <h1>シェルコマンドを表示する例</h1>
  <pre><code class="language-bash">
    chmod 400 key.pem
  </code></pre>

  <script>hljs.highlightAll();</script>
</body>
</html>
```
### 2つのscriptタグを使用して、まずライブラリを読み込み、次にライブラリを初期化し、シンタックスハイライトを適用する処理が行われている。

#### 1つ目のscriptタグは、src属性を使用してhighlight.jsのJavaScriptライブラリを読み込んでいる。
ここではCDN（Content Delivery Network）を使用して読み込んでいるが、ライブラリをローカルにダウンロードして使用することもできる。
CDNとは、インターネット上でコンテンツ（画像、動画、スタイルシート、JavaScriptファイルなど）を高速かつ効率的に配信するためのネットワークシステムである。
CDNは、世界中に分散配置されたサーバー群から構成されている。
これにより、ユーザーがアクセスする際に最も近いサーバーからコンテンツを取得できるようになる。
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
```
##### scriptタグの下のlinkタグは、HTMLファイルにhighlight.jsのCSSスタイルシートをリンクする。
CSSスタイルシートは、シンタックスハイライトの見た目（色、フォントスタイルなど）を定義している。

linkタグは、HTML文書と外部リソース（通常はスタイルシート）を関連付けるために使用される。

rel属性は、linkタグ内で使用され、リンクされた文書と現在の文書の関係を定義する。
relは"relationship"（関係）の略。

#### ２つ目のscriptタグは、ライブラリを初期化し、シンタックスハイライトを適用するためのコードを実行している。
hljs.highlightAll()は、ページ内のすべてのコードブロックにシンタックスハイライトを適用する関数。
この関数を呼び出すことで、ページ内のコードブロックがシンタックスハイライトされた状態で表示される。

## 補足
MacのターミナルのシェルコマンドをWebページに表示したいと思い、codeタグのclass="language-zsh"にしたらシンタックスハイライトが適用されなかった。

bashは適用された。
Django クエリ操作

# 絞り込み(Filter)

|クエリ　|説明|
|-------------|---|
|`Model.objects.filter(field='フィールド名')`|field='フィールド名で絞り込む'|
`Model.objects.filter(field1='フィールド名', field2='フィールド名')`|field1かつfield2で絞り込む
|`Model.objects.filter(field__startswith='A')`|filedがAから始まる行だけ絞り込む|
|`Model.objects.filter(field__endswith='B')`|fieldがBで終わる行だけ絞り込む|
|`Model.objects.filter(age__gt=20)`|ageが20より大きい行だけ絞り込む|
|`Model.objects.filter(age__li=20)`|ageが20より小さい行だけ絞り込む|
|`Model.objects.filter(age__gte=20)`|ageが20以上の行だけ絞り込む|
|`Model.objects.filter(age__lte=20)`|ageが20以下の行だけ絞り込む|
|`Model.objects.filter(field__in=['○○', XX'])`|fieldの値が[]内の文字列に該当するレコードのみ|
|`Model.objects.filter(field__contains='○○')`|fieldに○○を含むレコードのみ(部分一致、 大文字小文字を区別)
|`Model.objects.filter(field__icontains='○○')`|fieldに○○を含むレコードのみ(部分一致、 大文字小文字を区別しない)
Model.objects.filter(field__isnull=True)|fieldがNULLのレコードのみ|
|`Model.objects.exclude(field=`○○`)`|fieldが○○以外のものを取り出す|
|`Model.objects.values('column1', 'column2').all()`|column1とcolumn2だけ取り出す|

OR条件で絞り込む場合
`from django.db.models import Q`
`Model.objects.filter(Q(field1='フィールド名')|Q(field2='フィールド名'))`

# 集計する

|クエリ                                   |        説明|
|----------------------------------------|-----------|
|`Model.objects.aggregate(Max('column'))`|最大値を求める|
|`Model.objects.aggregate(Min('column'))`|最小値を求める|
|`Model.objects.aggregate(Avg('column'))`|平均値を求める|
|`Model.objects.aggregate(Sum('column'))`|合計値を求める|

## group byでカラムに応じて集計(annotate)
`Model.objects.values('column1').annotate(Max('column2'))`
coumn1でGroup Byして、column2のMaxを計算する。

# 外部テーブルの絞り込み
|クエリ|説明|
|----|---|
|`Model.objects.filter(外部テーブル__カラム='○○')`|外部テーブルのカラムを指定して絞り込み|
|`Model.objects.filter(外部テーブル__外部テーブル__カラム='○○')`|外部テーブルの外部テーブルのカラムを指定して絞り込み|
|`Model.objects.order_by('外部テーブル__カラム')`|外部テーブルのカラムで並び替え(昇順)|
|`Model.objects.order_by('-外部テーブル__カラム')`|外部テーブルのカラムで並び替え(降順)|
|`Model.objects.values('外部テーブル__カラム').annotate(Count('id'))`|外部テーブルのカラムでGroup Byして集計|

### 逆参照も可能
~~~python:models.py
class Person(models.Model):
    name = models.CharField()
    age = models.IntegerField()

class Team(models.Model):
    name = models.CharField()
    member = models.ForeignKey(Person)
~~~

~~~python
Team.objects.filter(person__name='太郎').all()
Person.objects.filter(team__name='チーム１').all()
~~~
Exception 'Your app is missing support for the following URL schemes: com.googleusercontent.apps.XXXXXX' was thrown while invoking signIn on target RNGoogleSignin with が出る場合

【やりたいこと】
Firebaseでgoogleの認証APIを叩きたい。

【状況】
・以下のエラーが出る

Exception 'Your app is missing support for the following URL schemes: com.googleusercontent.apps.XXXXX' was thrown while invoking signIn on target RNGoogleSignin with params (

・解決策
①PROJECTNAME.xcworkspaceをXcodeで開く
②XCodeでプロジェクトの一番上のファイルを選択する。
③TARGETSで変更したい対象のファイルを指定。
④画面真ん中の上のInfoを選択
⑤URL TypesからURL Schemesでエラーが出た「com.googleusercontent.apps.XXXXX」を入力する
⑥エミュレーターを起動コマンドで起動し直す
⑦FirebaseのgoogleのAPIを叩くと、叩けるようになった。
OpenJDK を MacOS にインストールする方法。最終版。

Oracle JavaとOpenJDKのインストール方法がOS毎に違うので、いつも混乱します。
Mac　OSへのOpenJDKへのインストール方法を備忘録としてまとめておきます。

因みに、Linuxへのインストール方法は、こちら。
→ https://qiita.com/naiveprince0507/items/544c978b6db33c8d3c33

この記事に書いてある通りです。
OpenJDK を MacOS にインストールする
http://nw.tsuda.ac.jp/lec/java/openjdk/install_mac/

＜以下は、単にコピペです。＞

ダウンロードしたバイナリを展開する。
ターミナル上で: tar.gzファイルを解凍・展開する
```
$ tar zvxf openjdk-14.0.1_osx-x64_bin.tar.gz    
```

置くべきフォルダを確認する
ターミナル上で: フォルダを確認する
```
$ ls -l /Library/Java  
total 0
drwxr-xr-x  2 root  wheel   64  7 16  2017 Extensions
drwxr-xr-x  4 root  wheel  128  4 23 16:56 JavaVirtualMachines

$ ls -l /Library/Java/JavaVirtualMachines  
total 0
drwxr-xr-x  3 root   wheel  96 12 29  2013 jdk1.7.0_45.jdk
```

OpenJDK 14 のフォルダを移動する(root権限が必要)。
ターミナル上で: root権限でmvする。
```
$ sudo mv jdk-14.0.1.jdk /Library/Java/JavaVirtualMachines/  
Password:rootのパスワード      ←タイプした文字は表示されない
```

配置した OpenJDK 14 がシステムから見えていることを確認する。
"OpenJDK 14.0.1" が表示されていることを確認する。
javaのバージョン一覧
```
$ /usr/libexec/java_home -V  
Matching Java Virtual Machines (2):
    14.0.1, x86_64:   "OpenJDK 14.0.1"	/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home
    1.7.0_45, x86_64: "Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home

$ /usr/libexec/java_home -v 14  
/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home
```

java バージョン14 を使うように環境変数を設定する。
ターミナル上で`   バッククォートで囲まれた文字列はシェル・コマンドとして実行されて、結果の文字列と入れ換わる。すなわち、java_home コマンドを実行した結果が環境変数 JAVA_HOME に設定される。
環境変数JAVA_HOMEの設定
```
$ export JAVA_HOME=`/usr/libexec/java_home -v 14`  
$ echo $JAVA_HOME  
/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home
```

java の バージョン14 が動いていることを確認する。
環境変数JAVA_HOMEの設定
```
$ java -version  
openjdk version "14.0.1" 2020-04-14
OpenJDK Runtime Environment (build 14.0.1+7)
```

シェルを起動する度に環境変数 JAVA_HOME が設定されるように ~/.bash_profile を変更する。 もしもログインシェルとしてzsh を使っている場合は ~/.zshenv に同じ内容を追加する。(2020/05/01追記)
~/.bash_profile または ~/.zshenv の先頭に次の行を追加する
```
export JAVA_HOME=`/usr/libexec/java_home -v 14`
```
Memo : rename npm public package. （npmパッケージのリネーム）

メモ

## 1. 新しいパッケージを登録


## 2. 古いパッケージをdeplicate

以下コマンドを実行し、deplicateするパッケージに新しいパッケージを参照するようにメッセージを付ける。
* WEBコンソールで行うとメッセージの登録ができないので、コマンドからメッセージを登録しつつdeplicateする。

```
npm deprecate <old-package-name> "WARNING: This project has been renamed to <new-package-name>. Install using <new-package-name> instead."
```

以上。
【Windows 10】スタートアップで起動時に実行されるアプリを追加・削除する

# ［スタートアップ］フォルダの場所
**■ユーザーごとの［スタートアップ］フォルダのパス**
```
C:\Users\＜ユーザー名＞\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```

**■全ユーザー共通の［スタートアップ］フォルダのパス**
```
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
```

### 参考サイト
https://atmarkit.itmedia.co.jp/ait/articles/1701/18/news029.html

### 小ネタ
```
Windows+Rを押して
shell:startup
```
でも行ける。
pip freezeで出力されたライブラリをダウンロードするスクリプト

chatGPTさんに書いてもらいました

```
@echo off
setlocal enabledelayedexpansion

set PACKAGES_FILE=requirements.txt
set PACKAGES_DIR=packages

if not exist %PACKAGES_DIR% mkdir %PACKAGES_DIR%

for /F "usebackq delims==" %%i in ("%PACKAGES_FILE%") do (
  set PACKAGE_NAME=%%i
  set FILE_NAME=%PACKAGES_DIR%\!PACKAGE_NAME!.tar.gz
  echo Downloading !PACKAGE_NAME!...
  pip download --dest %FILE_NAME% !PACKAGE_NAME!
)
```

PowerShell版
```
$packagesFile = "requirements.txt"
$packagesDir = "packages"

if (!(Test-Path $packagesDir)) {
  New-Item -ItemType Directory -Path $packagesDir | Out-Null
}

Get-Content $packagesFile | ForEach-Object {
  $packageName = $_
  $fileName = "$packagesDir\$packageName.tar.gz"
  Write-Host "Downloading $packageName..."
  pip download --dest $fileName $packageName
}
```
AWS Certified Cloud Practitioner (CLF)合格した話

# はじめに
AWS Certified Cloud Practitioner (CLF)に合格したので、偉そうに感想だったり勉強法を述べます。

# 受験者情報
・未経験22卒
・資格は基本情報技術者のみ（2021年4月に取得）
・AWSの実務経験無し
・EC2とRDSは個人的に触ってみたことあり

# 受験日・学習期間
受験日:2023年4月1日
学習期間:2023年2‐3月

# 学習教材等

## 参考書

### [AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー (SBクリエイティブ)](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/ref=asc_df_4797397403/?tag=jpgo-22&linkCode=df0&hvadid=295691444786&hvpos=&hvnetw=g&hvrand=8499890677422649995&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028853&hvtargid=pla-718362586207&psc=1&th=1&psc=1)

CLF合格しました！って言う人全員買っている気がします。
ただその人気に負けず、全部読めばAWSの基礎がある程度理解できる書籍になっています。
正直これ一冊読んだだけだと合格は難しい気がします。あくまで基礎をなぞっているだけですので。

## 模擬試験・問題集
### [この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-4260/)

これもCLF合格記的なのを書いている人全員買っている気がします。
実際かなり本番に近い問題になっているので、マストで買うべきですね。
内容は基本レベル2回、本番レベル3回分になっています。
正直本番レベルは実際の試験よりも難しく、上位試験のSAA-C03の出題範囲の問題まで出てきますので、
本番レベルの模擬試験で80-90％の正答率ならば確実に合格できると思います。


### [AWS認定 クラウドプラクティショナー模擬試験](https://apps.apple.com/jp/app/aws%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC%E6%A8%A1%E6%93%AC%E8%A9%A6%E9%A8%93/id1509436492)

アサインされていた案件が基本的に出社であったので、通勤中はこのアプリの問題集をスマホで解いていました。
練習問題10問×10回、模擬試験25問×13回の内容になっており、700円で全問題が受けられるようになります。
一部誤字脱字や、正解の回答が不正解になっていたりと、udemyの模擬試験よりはクオリティは低いですが、
解説がきちんと付属しているので問題なく学習できます。
学習のモチベーションが上がらないときなど、とりあえずスマホ開いて、問題解いて解説見て学習というのができるので、
私のような怠惰な人間にはおすすめです。

# 勉強方法
（当たり前ですが）基本的に業務終了後に勉強していました。

まず、上記の参考書を一周読みながら、重要そうなところはノートに書き出して覚えるというのを3週間ほどかけて行いました。
ノートに書き出していくことに関しては特にセオリーとかはなく、
自分が学生時代からやっていたことなので、皆さんも自分に合うやり方で参考書を一周してみるのが良いと思います。

そして、udemyの模擬試験をひたすら解いて、間違った問題の解説を再びノートに書き出していくというのを1ヶ月半やりました。
結局試験日まで模擬試験を解いて解説をノートに書くというのを全5回7周しました。7周目ともなるとさすがに全問正解もするようになってきたので、
大きな自信になったと思います。（問題を多少覚えたというのももちろんありますが）

余談ですが、5日でCLF合格！とかいう記事がインターネット上に多くありますが、
よほど頭の良い人でない限り、業務と並行して5日で合格するのはかなりきついレベルの難易度になっていると思います。
~~（ああいう人って業務が暇な人とかで、業務時間内に勉強している気がします）~~

# 試験について
私はピアソンVUEのテストセンターで受験しました。
テストセンターにあるPCで受験するので、筆記用具などは必要ないです。
ただ、本人確認の際に本人確認書類を2枚提示することを求められるので、そこは注意して下さい。（私はマイナンバーと運転免許証を提示しました）

試験時間は90分で、問題数は65問の選択式ですので、きちんと学習した人は時間が余ると思います。
試験のソフト（？）には見直し機能もありますので、気の済むまで見直しに時間を割いて高得点を狙いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626031/9f2f1ba5-33c6-0540-9e1c-5d98215dc427.png)
自分は15分で解き終わってしまい、見直しをしていましたが、これ以上考えても回答は変わらないな、と思い20分で提出しました。
CLFは提出すると合否がすぐ出るので、私のような心配症に優しいです。
結果は合格でしたが、~~20分で会場を出るという舐めプをかましていたにも関わらず~~模擬試験で9割程度取れていたにも関わらず、スコアが8割ほどだったので、少し悔しいなという思いです。

# おわりに
初めてのAWS認定試験でしたので、不安な部分も多くありましたが結果的に合格できたので良かったです。
自分の経験を共有することで、これからCLF受けるよという人の不安の解消の役に立てれば幸いです。
個人的には上位資格をどんどん狙って行こうと思っておりますので、上位資格受験の様子も記事にしていく予定です。
Slack の有料プランをダウングレードする

Pro から フリープランにダウングレードするのがとてもわかりずらかったのでメモ。

# 作業

- 2023/4/5 時点での作業
- Linux 用の Snap 版 アプリ 4.29.149 64-bit 
- Google Chrome バージョン: 103.0.5060.114（Official Build） （64 ビット） 

# 方法

ワークスペースから管理画面を呼び出して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e3dfa269-117b-9ffe-8e7d-21aca4ea6582.png)

ブラウザから設定画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d0796d37-f833-db9f-c8af-a61698b036de.png)


家のマークを押してホーム画面を出して「Billing」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bca96d59-cf58-1558-fe53-b71be4cb3841.png)

この画面中の
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f5281a29-69e6-b758-af1f-7ebe3ebcc524.png)
「Change subscription details」を押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/12c910eb-f90c-8a23-8cad-e84089031167.png)

「Downgrade to Free」を選び、変更時期を今すぐか次の支払いタイミングを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/62cac2e2-2c37-0807-a7db-c46ce511e4c4.png)

Downgrade Slack を押して内容を確認します。 今回のワークスペースで Slack-connect やゲストアクセスを使っていたのですが、それらは使えなくなることを確認しておきました。
問題なければ 「Downgrade Slack」を押せばフリープランへの移行は完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f2dff512-49e5-f0f4-8947-6999677c4086.png)
5つの人気のあるプラットフォーム・アズ・サービス（PaaS）の例

![611b991c107c5766be8b3238_cloud-paas-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/19f69ce1-10ea-823b-62ec-96a2da45feee.png)

<h2>1. PaaSとは

プラットフォーム・アズ・サービス（PaaS）は、現代のビジネスに適した、速いペースと高い機敏性を持っています。高度なツールを使用して、企業が迅速にカスタマイズされたソリューションを構築することができるようになります。車輪の再発明を回避するという理論により、主な利点があります。
すべてをゼロからコーディングする代わりに、PaaSプロバイダーは、開発者がプラグアンドプレイしてより優れたアプリを素早く構築できるビルド済みのブロックを提供しています。
クラウドのスケーラビリティのおかげで、自己プロビジョニングの必要性がほとんどないことも意味しており、低価格で提供されています。

<h2>2. 人気のあるトップ5のプラットフォーム・アズ・サービス（PaaS）の例

<h3>2.1. SAP Cloud>

SAPは非常に大きな企業であり、そのオファリングは複数のサービスモデルに及びます。その中には、ビジネスプラットフォームであるCloud PaaSがあります。開発者がアプリケーションをより簡単に構築するのを支援するために設計されており、サービスの幅広さと深さを提供しています。
このプラットフォームは、クラウドとオンプレミスのアプリを統合する可能性を開き、多数のサポートサービスも提供しています。これは、SAPの膨大なパートナーエコシステムのおかげであり、同じプラットフォーム上に構築された1,300以上のアプリの驚くべきライブラリを提供しています。

<h3>2.2. マイクロソフト Azure

マイクロソフト Azureは、PaaSコンセプトを利用した展開および開発環境です。その性質から、Azureはビルドからデプロイまでのウェブアプリケーション開発ライフサイクル全体をサポートできます。
Azureは、多数のツール、言語、およびフレームワークをサポートしています。それを使用する開発者は、Microsoftのクラウドコンピューティングサービスである100以上の関連サービスにアクセスできます。Azureの巨大な規模のため、SaaS、PaaS、IaaSのすべてのクラウドモデルを包括しています。

<h3>2.3. Heroku

Herokuは現在Salesforceに属しており、管理されたコンテナコンセプトに基づくPaaSの例です。多くのPaaS環境と同様に、高度に自己完結型で、データサービスだけでなく独自の完全なエコシステムも統合しています。
アプリ中心性のため、Herokuはエンタープライズソリューションとしての評価よりも、趣味やプロダクション開発の人々のフォローを得ています。Herokuはかなり使いやすいため、よりスムーズな体験を提供できることも役立ちます。
Heroku上で開発することに熱心な人にとって、私はこのプラットフォーム上で構築されたアプリが、相当な価格で売れることを見てきました。例えば、飲食物を販売するために構築された「The Regular」は、Flippaにて約25,000ドルでリストアップされています。

<h3>2.4. AWS Lambda

Amazon Cloudの一部であるAWS Lambdaは、実際には全体の一部として機能することが意図されています。本質的に、AWSリソースの効率的な管理をサポートすることが目的です。これにより、リソースのプロビジョニングやサーバー管理の必要がなく、コードを実行できます。
Lambdaの性質は、マルチコードに対応した環境であるため、どのような種類の開発にも適しています。サーバーレスアーキテクチャやマイクロサービスアーキテクチャを簡単に処理できることで、ユーザーから高い評価を受けています。

<h3>2.5. Google App Engine

Googleは、Google Cloudエコシステムの一部として、App Engineを提供しています。これは、迅速な展開に使用される高度にスケーラブルなサーバーレスPaaSであることを意図しています。Googleは巨大な企業であるため、ほぼすべてのクエリのボリュームに対応できる高性能サーバーを提供することができます。
ただし、一部の言語環境でのサポートの不足、開発ツールの不足、一部のアプリケーションのプラグアンドプレイのできない能力、およびGoogleをベンダーとしてロックインすることなど、開発者からいくつかの問題が指摘されています。

<h2>3. 終わりに

総括すると、PaaSは迅速で高いアジリティを持つ現代ビジネスの要件に適したサービスモデルであり、事前に構築されたブロックを活用して開発者が簡単にアプリケーションを構築できることが大きな利点です。PaaSプロバイダーによって提供されるプレミアムツールによって、リーズナブルな価格でスケーラブルなソリューションを提供できます。 SAP Cloud、Microsoft Azure、Heroku、AWS Lambda、Google App Engineなど、PaaSの例はたくさんあります。これらのプラットフォームのうち、適切なものを選択することが重要です。各プラットフォームは、ユーザーが必要とするスケーラビリティ、セキュリティ、およびフレキシビリティレベルに対応しています。

PaaSに関する記事：
https://miichisoft.com/what-is-paas-difference-paas-saas-laas/

Website: https://miichisoft.com/