OmniAICreator/Qiita-1.07M huggingface dataset:
自作新幹線マスコンを作ってみた。

自己紹介
飛行機&鉄道が好きな人です。

普段の趣味は航空機、鉄道の写真撮影、カメラ沼？です。




今回は自作で新幹線マスコンを作ってみました！
始めてQiitaで書くので、不慣れですがお許しください。


改めまして
今、私が作っているものは新幹線の運転台です。

なぜ私が運転台を作ろうと思ったのかざっくり言うと、欲しかったからというのと、誰も作っていないものを作ってみたいと思ったからです。


それでは、今まで自分がどのように制作してきたかを紹介したいと思います！

まずは大事なマスコン本体から始めていきます。
モデリングはFusion360を使い、おおよそのモデルを作ります。
![E984F13C-CA1F-467E-A779-DC0783F16614.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716444/6aa3cec3-9a37-46c5-370a-4304f60fcce8.png)

次に3Dプリンターで印刷をします。
(印刷し、組み立てた物がこちらです。)
![IMG_7688.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716444/3fe2cbe0-68e2-892c-c4c2-0917cf22d37f.jpeg)
![IMG_7687.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716444/04651c1c-00d2-b309-bc81-0c9f3287826a.jpeg)


しっかりと中の機構も考え、マスコンを動かした時の、(カチン、カチン)というギミックも考え、自作マスコンに組み込みました。
さらに無駄のないように、右に(カチン、カチン)というギミック、左には可変抵抗を取り付けしました。
1番苦労した点はマスコンの根本のギアと可変抵抗のギアとのギア比の計算が大変でした。

![IMG_7683.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716444/77895142-5a04-4880-c9dc-3eee9510468d.jpeg)


今、出てきた可変抵抗を何に使うかと言うと、今回自作マスコンでBVEというゲームを動かしたいと思ったためこのようなプラグインを使ってみました。
それがこちら！
三八電車店さんのUniversal Contactlnte face　というプラグインを使用してゲームを動かします。
こちらどのようなプラグインかと言いますと、可変抵抗で0~1023までの抵抗値をそれぞれ、マスコンであれは10段下に、ブレーキでは９段階に割り振り、その中央値をArduino IDEに書き込みパソコン本体に入っているプラグインに読ませ、ゲームを動かすといったものです。


Arduinoとマスコン&ブレーキと繋がっている可変抵抗との配線図がこちらです。
![CB939C31-94C5-4EB0-A4D3-81A1731908DE_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716444/4fd9435a-07c3-49b3-bc2d-d94f9eddfd8d.jpeg)

このように配線し、まずはマスコン、ブレーキ、それぞれの段階の抵抗値を計測し、計測ができたら次に測定した抵抗値をPCに送る用のプログラムに抵抗値を書き込みます。

これで完成です！



最後に接続方法と設定方法を紹介します。
まずはマスコン側に付いている可変抵抗のピンとArduinoから伸びている配線を接続、そしてWindowsとArduinoを専用ケーブルで繋ぎます。
BVEを立ち上げてUniversal Contactlnte faceを選択し、プロパティーからを選択します。
プロパティーからArduinoを接続しているピンを選択します。
エラーが出なければ成功です！
Laravel × MongoDB

# 初期設定

1 . ComposerでMongoDBのドライバをインストールします。

```plaintext
$ composer require jenssegers/mongodb
```

2 . config/database.phpファイルで、connectionsへMongoDB接続用の新しい接続を追加します。

```php
'mongodb' => [
    'driver'   => 'mongodb',
    'host'     => env('MONGO_DB_HOST', 'localhost'),
    'port'     => env('MONGO_DB_PORT', 27017),
    'database' => env('MONGO_DB_DATABASE'),
    'username' => env('MONGO_DB_USERNAME'),
    'password' => env('MONGO_DB_PASSWORD'),
],
```

3 . `.env`にMongoDBへの接続情報を書き加えます。\
```plaintext
MONGO_DB_HOST=mongo
MONGO_DB_PORT=27017
MONGO_DB_DATABASE=mongo-database
MONGO_DB_USERNAME=mongo-user
MONGO_DB_PASSWORD=password
```

# migrationの作成

_※mongoDBのマイグレーションは必須ではありません。
DBへのデータ登録時に任意のコレクションとプロパティを作成できます。
しかし、マイグレーションファイルを作成しなければ、`php artisan migrate:refersh`コマンドなどでデータ削除をしたりすることが出来ません。

mySQLと併用しながらmongoDBにアクセスするには`connection('mongodb')`と指定することによって、mongoDBの操作ができます。
config/database.phpファイルのdefaultプロパティでmysqlが指定されているので、mysqlへは今まで通り操作できます。

(例)migration (testテーブルの作成)

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class Test extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
                // ↓ここ
        Schema::connection('mongodb')->create('test', function (Blueprint $collection) {
            $collection->string('name');
            $collection->string('email')->unique();
            $collection->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::connection('mongodb')->dropIfExists('test');
    }
}
```

# Modelの作成

mongoDBもModelを使用してデータを取得することが出来ます。

1. modelの作成

```plaintext
$ php artisan make:model mongo/Test
```

2 . 作成したModelでどのDBを使うかを指定

```php
protected $connection = 'mongodb';
```

3 . 今まで通り`$fillable`などの設定を行う

## MYSQLとのクエリビルダの違い

基本的にはMySQLの時と同じように操作することができます。

```php
// IDが`6409645ad2771f75080f7b97`のユーザーを取得
$user = User::find('6409645ad2771f75080f7b97'); // ObjectId

// ユーザーの作成
User::create([
    'hoge' => hoge,
]); // created_at, updated_atも自動で入ります。(ただしUTC)
```

詳しくはライブラリのREADMEを参照してください。\
https://github.com/jenssegers/laravel-mongodb#eloquent

## GUI操作を行うには？

1 . こちらをインストール https://www.mongodb.com/try/download/shell
2 . New connection → 接続情報を入力する

- General
  - Host: 127.0.0.1:27017
- Authentication
  - UserName: mongo-user
  - Password password

3 . Connectをクリック
4 . admin, config, localの３つのDBが表示されれば成功
《プログラミングの基礎》をReScriptで読む 第二章-第四章

[《プログラミングの基礎》](https://www.amazon.co.jp/dp/4781911609/ "Amazonへのリンク")はとても良い本です。
サンプルプログラムをReScriptで書いて、プログラミングの基礎とReScriptを学びます。
ReScriptはmacOS Sonoma(バージョン 14.4.1)で動かしています。
# 第二章
```ocaml:ocaml
"新" ^ "横浜" ^ "駅"
```
```Rescript:Rescript
"新" ++ "横浜" ++ "駅"
```
stringの連結子は`++`です。
# 第三章
特になし
# 第四章
```ocaml:ocaml
let f x = 3 * x
```
```ReScript:ReScript
let f = (x) => {3 * x}
```
関数は`let 関数名 = (引数) => {本体}`と書きます。
***
```ReScript:Ex04_1.res
let jikyu = 850 
 
let baito_kyuyo = (year, month) => {
  month * (jikyu + year * 100) 
}

Console.log(baito_kyuyo(1, 10))
```
```ReScript:Ex04_2.res
let jikoshokai = (namae) => { 
  "私の名前は" ++ namae ++ "です。よろしくお願いします。" 
}

Console.log(jikoshokai("戯画蛙"))
```
```ReScript:Ex04_3.res
let hyojun_taiju = (shincho) => {
  shincho *. shincho *. 22.0 
}

Console.log(hyojun_taiju(1.75))
```
```ReScript:Ex04_4.res
let bmi = (shincho, taiju) => { 
  taiju /. (shincho *. shincho)
}

Console.log(bmi(1.75, 75.))
```
```ReScript:Ex04_6.res
// 目的：鶴の数 tsuru を受け取ったら足の本数を返す
// tsuru_no_ashi : int -> int
let tsuru_no_ashi = (tsuru) => tsuru * 2 
 
// テスト
Console.log(tsuru_no_ashi(0) == 0)
Console.log(tsuru_no_ashi(1) == 2)
Console.log(tsuru_no_ashi(7) == 14)
```
```ReScript:Ex04_7.res
// 目的：鶴の数と亀の数を受け取ったら足の本数を返す
// tsurukame_no_ashi : int -> int -> int
let tsurukame_no_ashi = (tsuru, kame) => tsuru * 2 + kame * 4 
 
// テスト
Console.log(tsurukame_no_ashi(0, 0) == 0)
Console.log(tsurukame_no_ashi(1, 1) == 6)
Console.log(tsurukame_no_ashi(2, 3) == 16) 
```
```ReScript:Ex04_8.res
// 目的：鶴と亀の数の合計と足の数の合計を受け取ったら鶴の数を返す
// tsurukame : int -> int -> int
let tsurukame = (gokei, ashi) => (gokei * 4 - ashi) / 2 
 
// テスト
Console.log(tsurukame(0, 0) == 0) 
Console.log(tsurukame(5, 12) == 4)
Console.log(tsurukame(12, 34) == 7)
```
《プログラミングの基礎》をReScriptで読む 第一章

[《プログラミングの基礎》](https://www.amazon.co.jp/dp/4781911609/ "Amazonへのリンク")はとても良い本です。
サンプルプログラムをReScriptで書いて、プログラミングの基礎とReScriptを学びます。
ReScriptはmacOS Sonoma(バージョン 14.4.1)で動かしています。

# 第一章
[《プログラミングの基礎》](https://www.amazon.co.jp/dp/4781911609/ "Amazonへのリンク")は使用する言語にOCamlが選ばれています。
第一章でOCamlの設定が書かれているので、真似してReScriptの設定をします。
## Node.jsのインストール
ReScriptを動かすのにNode.jsとnpmが必要なのでインストールします。
[Japan Node.js Assosiation](https://nodejs.jp/)からリンクをたどってインストールしました。

## ReScriptのインストール
ReScript Language Manualの[Installation](https://rescript-lang.org/docs/manual/latest/installation)を参考にインストールしました。
```SH:SH
npm create rescript-app
```
インストールスクリプトを起動します。
***
```SH:SH
┌  create-rescript-app 1.6.0
│
◇  Welcome to ReScript! ─────────────────────────────────╮
│                                                        │
│  Fast, Simple, Fully Typed JavaScript from the Future  │
│  https://rescript-lang.org                             │
│                                                        │
├────────────────────────────────────────────────────────╯
│
◇  New Project ───────────────────────────────────────────╮
│                                                         │
│  Create a new ReScript 11 project with modern defaults  │
│  ("Core" standard library, JSX v4)                      │
│                                                         │
├─────────────────────────────────────────────────────────╯
│

◆  What is the name of your new ReScript project?
│  fundamentals-of-programming_
```
プロジェクト名を聞かれるので適切に名付けます。プロジェクト名でフォルダが作成され、その配下にファイルが配置されます。
***
```SH:SH
◆  Select a template
│  ○ Vite
│  ○ Next.js
│  ● Basic (Command line hello world app)
└
│
◇  Versions loaded.
│
```
テンプレートはBasicを選びました。
***
```SH:SH
◆  ReScript version?
│  ● 11.1.0-rc.8
│  ○ 11.1.0-rc.7
│  ○ 11.1.0-rc.6
│  ○ 11.1.0-rc.5
│  ○ 11.1.0-rc.4
│  ○ 11.1.0-rc.3
│  ○ 11.1.0-rc.2
│  ○ 11.1.0-rc.1
│  ○ 11.0.1
│  ○ 11.0.0
└
```
バージョンは一番新しいものを選びました。
***
```SH:SH
◆  ReScript Core version?
│  ● 1.2.0
│  ○ 1.1.0
│  ○ 1.0.0
│  ○ 0.7.0
│  ○ 0.6.0
└
```
ReScript Coreも一番新しいものを選びました。
ReScript v11では、大きな変更があったため、ReScript Coreが別途インストールになっているということでした。バージョンが上がると個別選択が不要になっているかも知れません。
***
```SH:SH
◇  Project created.
│
└  Happy hacking!
```
Happy hackingしていきます。
***
```SH:SH
cd fundamentals-of-programming
npm run res:build
node src/Demo.res.js
```
`Hello, world!`が表示されます。
srcの配下にReScriptのプログラムファイルを置いて、`npm run res:build`すれば、JavaScriptにコンパイルされたファイルが作成されます。
watsonx.aiのllama3でchatbot

LCELを使えばOK。

```python
# %%
from dotenv import load_dotenv
import os

load_dotenv()
#print(os.environ['WATSONX_APIKEY'])
# %%
from langchain.globals import set_verbose

set_verbose(True)
# %%
from langchain_ibm.llms import WatsonxLLM

model_id = 'meta-llama/llama-3-70b-instruct'
project_id = '13facb99-f76c-4679-94c5-14e692b114db'
url = 'https://jp-tok.ml.cloud.ibm.com'
params = {
	'decoding_method': 'sample',
	'max_new_tokens': 4096,
	'top_k': 50,
	'top_p': 1,
	'repetition_penalty': 1
}
llm = WatsonxLLM(
    model_id=model_id,
    project_id=project_id,
    url=url,
    params=params
)
# %%
from langchain_core.prompts.prompt import PromptTemplate

template = """



system
You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don’t know the answer to a question, please don’t share false information.


user

{history}
Human: {user}



assistant

"""
prompt = PromptTemplate(template=template, input_variables=['history', 'user'])
# %%
from langchain.memory.buffer_window import ConversationBufferWindowMemory

memory = ConversationBufferWindowMemory()
# %%
from langchain_core.runnables.passthrough import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

chain = RunnablePassthrough().assign(
    history = lambda x: memory.chat_memory
) | prompt | llm | StrOutputParser()
# %%
#user = 'watsonx.aiとは何ですか？'
#ai = ''
#for tmp in chain.stream({'user': user}):
#    ai += tmp
#    print(tmp)
#memory.chat_memory.add_user_message(user)
#memory.chat_memory.add_ai_message(ai)
#print(memory.chat_memory)
# %%
```

```python
import gradio as gr
from llama3 import chain, memory

def fn(message, history):
    user = message
    ai = ''
    for tmp in chain.stream({'user': user}):
        ai += tmp
        yield ai
    memory.chat_memory.add_user_message(user)
    memory.chat_memory.add_ai_message(ai)
    #print(memory.chat_memory)

gr.ChatInterface(fn=fn).launch()
```
より良い Git コミットメッセージを書こう

より良いコミットメッセージを残すことは Git を使った開発をする上で重要なことです。優れたコミットメッセージは、それを読んだ人がコードを理解するのに大いに役立ちます。

では、どのようなメッセージが良いもので、どのようなメッセージが悪いものなのでしょうか？ それについて掘り下げていきたいと思います。

## 基本的な Git Commit Message の書き方

詳しいところは、以下の3サイトを参照してください。特に「How to Write a Git Commit Message」には基本がすべて書かれています。

How to Write a Git Commit Message
https://cbea.ms/git-commit/

Gitのコミットメッセージをうまく作成する7つのルール （「How to Write a Git Commit Message」の和訳記事）
https://meetup-jp.toast.com/839

[転載] gitにおけるコミットログ/メッセージ例文集100
https://gist.github.com/mono0926/e6ffd032c384ee4c1cef5a2aa4f778d7

まず、英語の Commit Message については、日本語でも適用できる点、そうでない点があります。例えば「大文字で始める」というルールは日本語には適用できませんが、「本文はどのようによりも何を、なぜに合わせて作成する」というルールは日本語でも有用です。

まずは英語のコミットメッセージの書き方を知っておいて、日本語でも有用なところを取り入れていきましょう(もちろん、英語の Commit Message を書く場合はそのような心配はありません)。

## コミットメッセージの実例

では次に、実際にコミットメッセージの例を見てみましょう。

### 「レビュー対応」「指摘修正」

~~~
レビュー対応
~~~
~~~
指摘箇所を修正
~~~

一見して無難なコメントに見えますが、これらは実のところ何の情報も得られないコメントです。一体どのようなレビュー指摘があったのでしょうか？ それが分からないので、コードの修正差分を見ても妥当性が分かりません。後から見返して非常に困ってしまうコメントなのです。

基本的に「レビュー指摘があった」ことはコミットメッセージに残す必要はありません。それよりも、指摘の内容をコメントに残す方が有用です。

~~~
例外発生時にトランザクションをrollbackする
~~~
~~~
watchで値を更新するのを止めてcomputedを使う
~~~

このように、修正の理由が明確になるコメントを残しましょう。

### 「●●を修正する」

~~~
ユーザー登録APIを修正する
~~~
~~~
SQLを修正する
~~~

これも良くないパターンです。

何を修正したのか(What)、どのような修正を行ったのか(How)は、修正差分を見れば分かります。コミットメッセージとしては有用ではありません。

大事なのはなぜ修正したのか(Why)です。同じ修正に対しても、例えば以下の書き方であれば分かりやすくなります。

~~~
ユーザー登録APIの入力チェックを強化する
~~~

~~~
SQLインジェクションを修正する
~~~

これであれば、ユーザー登録APIやSQLを修正する理由が明確ですね。

### 「●●を追加する」

~~~
ユーザー登録APIを追加する
~~~
~~~
SQL を追加する
~~~

これは、先ほどの例の「修正する」を「追加する」に書き換えたものですが、コメントの良し悪しについては評価が変わります。

「ユーザー登録APIを追加する」は、良いコメントです。新しい機能を追加することは、それ自体が理由になり得ます。ユーザーを登録する機能が必要だったからこそ、登録APIを追加したのでしょう。

一方で「SQLを追加する」は、悪いコメントです。どのようなSQLが追加されたのか分かりませんし、その理由も伺い知れません。

### リファクタリング

~~~
コードフォーマットを修正する
~~~
~~~
count() -> getCount()
~~~

これらも良いコメントです。ロジックに変化がなく、コードを整形されていたり、メソッド名が修正されていることが予想できます。

後者のような「aaa -> bbb」が許容されるのは意外に思うかも知れませんが、リネームの書き方として定着しているものであり、問題ありません。丁寧に書くのであれば、以下のように書いても良いでしょう。

~~~
Rename count() -> getCount()
~~~
なお、「->」はあくまでリネームやタイポの修正を意図するものなので、それ以外で使わないようにしましょう。以下は悪い例です。

~~~
Redis keys -> scan
~~~

これは以下のように書き換えるべきです。

~~~
Redis の負荷を軽減するため keys の代わりに scan を使う
~~~

書き換え前と比べ、 scan を使う理由が明確になっています。

## まとめ

コミットメッセージはコードを保守する上で重要なヒントになるものです。そのコミットが作られた理由が明確になるように書きましょう。

半年後の自分や、他人が見ても理解できるコメントを書くよう心がけましょう。
トリプルシンキングしってますか？

考える力や思考法に関するフレームワークが数多くありますが、それを有効活用できるかはシンキング力によります。

・ロジカルシンキング
・クリティカルシンキング
・ラテラルシンキング

の3つを総称したものを「トリプルシンキング」と呼びます。この3つの思考法を身につけて活用すると一段階も二段階もスキルアップできます！

# ロジカルシンキング
ロジカルシンキングとは、物事を矛盾なく、筋道を立てて論理的に考えることを指します。ビジネスシーンで特に重視されるスキルであり、問題解決や意思決定、効果的なコミュニケーションに役立ちます。ロジカルシンキングには、演繹法、帰納法、弁証法などの手法があり、それぞれ異なるアプローチで物事を考えるために用いられます

ロジカルシンキングを鍛えることで、分析力や問題解決能力、説得力が向上し、より効果的な意思決定が可能になります。ただし、前提条件が間違っている場合には、正確な結論にたどり着けないというデメリットもありますので、情報の正確性を確認することが重要です。

# クリティカルシンキング
クリティカルシンキングとは、物事の本質を見極め、客観的な視点で分析し、問題を解決するための思考スキルです。この思考法では、与えられた情報や状況に対して批判的にアプローチし、事実に基づいた判断を下すことを目指します。クリティカルシンキングは、前提条件を疑い、異なる角度から物事を考察することで、新たな解決策やアイデアを生み出すことができます

クリティカルシンキングの実践には以下のようなメリットがあります：

１．事実に基づいた判断がしやすくなる：主観や周囲の感情に影響されず、中立的な立場から考えることができます。
２．矛盾点を見つけやすくなる：前提条件を疑いながら考えることで、問題点や課題を明らかにしやすくなります。３．リスクを回避できる：気づかなかったリスクを発見し、それを回避する機会を得られます。
４．コミュニケーションがスムーズになる：私情を含まない客観的な議論が可能になり、問題解決までのプロセスが加速します。
５．新たなアイデアが生まれる可能性がある：異なる視点で考えることで、革新的なアイデアや新規事業に役立つ可能性があります1。

クリティカルシンキングを身につけるためには、第三者の視点を意識する、事実を基に発言する習慣をつける、正しい情報を集めるスキルを高める、研修を受けるなどの方法があります1。また、ロジカルシンキングと比較すると、クリティカルシンキングは前提を疑うことに重点を置いており、論理的な思考法だけでなく批判的精神も含まれています2。このように、クリティカルシンキングは複雑で不確実な現代社会において非常に重要なスキルとされています。

# ラテラルシンキング
ラテラルシンキング、または水平思考とは、従来の論理的な思考法（垂直思考）とは異なり、問題解決や新しいアイデアを生み出すために、直感を活かし、既成概念にとらわれずに物事を多角的に捉える思考法です。この思考法は、医師で心理学者のエドワード・デボノによって提唱されました。

ラテラルシンキングの特徴は以下の通りです：

・既成概念にとらわれない：伝統的な前提や制約から自由になり、新しい視点で物事を見ることができます。
・多面的な考察：問題を一つの角度からではなく、さまざまな角度から考えることで、より多くの解決策やアイデアを見つけることが可能になります。
・直感的な発想：論理的なステップを踏まず、直感を信じて思考を進めることができます。
・偶然の発見を大切にする：偶然に出会った情報や出来事から新しい価値を見出すことができます。

ラテラルシンキングは、特に新しいアイデアや創造的な解決策が求められる場面で有効です。ビジネスの世界では、イノベーションを生み出すための重要なスキルとして注目されています。ただし、論理的な検証を経ないため、提案されたアイデアが実用的かどうかは別途検討する必要があります

# この３つを組み合わせるメリット
ロジカルシンキング、クリティカルシンキング、ラテラルシンキングの3つの思考法を組み合わせることには、多くのメリットがあります。これらを組み合わせることで、より包括的で効果的な問題解決や意思決定が可能になります。以下にそのメリットを挙げます：

1. **多角的な視点**：ロジカルシンキングは論理的なアプローチを提供し、クリティカルシンキングは情報の検証と批判的な分析を促し、ラテラルシンキングは創造的で革新的なアイデアを生み出します。これらを組み合わせることで、問題を多面的に捉え、より深い理解を得ることができます。

2. **効率的な問題解決**：各思考法は異なるアプローチを提供するため、組み合わせることで問題解決のプロセスが加速されます。ロジカルシンキングで問題の構造を理解し、クリティカルシンキングで情報の妥当性を評価し、ラテラルシンキングで新しい解決策を探求することができます。

3. **強化された意思決定**：異なる思考法を用いることで、意思決定の際に考慮すべき要素が明確になります。ロジカルシンキングが論理的な根拠を提供し、クリティカルシンキングが潜在的なバイアスや誤りを指摘し、ラテラルシンキングが新しい選択肢を提示します。

4. **革新的なアイデアの創出**：ラテラルシンキングは特に、従来の枠を超えたアイデアを生み出すのに役立ちます。これにより、ビジネスや科学、芸術などの分野で革新的な発展が期待できます。

5. **コミュニケーションの向上**：異なる思考法を理解し、適切に組み合わせることで、他者とのコミュニケーションがスムーズになります。相手の視点を理解しやすくなり、より効果的な議論が可能になります。

# まとめ
これらの思考法を組み合わせることで、ビジネス、教育、日常生活など、さまざまな分野での活動がより豊かで効果的になるでしょう。トリプルシンキングとしての組み合わせは、個々の思考法を超えた大きな効果を発揮する可能性を秘めています。
Security HubでNIST SP 800-53 Rev.5を有効化してみた

# はじめに
今回はSecuirty HubでNIST SP 800-53 Rev.5（以降 NIST SP）を有効化してみたので、NIST SPの概要や有効化する際の注意事項を紹介したいと思います。

## Security HUb セキュリティ基準
Security Hub のセキュリティ基準には、規制のフレームワーク、業界のベストプラクティス、企業ポリシーのコンプライアンスを判断するための一連の要件が含まれています。
Security Hubは要件をコントロールにマッピングし、各項目のセキュリティチェックを実行します。
有効なチェックの項目数を分母として合格しているチェックの項目数を分子とした割合から、セキュリティスコアが算出されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/ae27ac34-bf5f-be2b-f9c0-bf122dd01d68.png)

NIST SPは2023年3月にセキュリティ標準として追加されたもので、米国商務省の一部である国立標準技術研究所 (NIST) によって開発された、サイバーセキュリティ及びコンプライアンスのフレームワークです。
NIST SPを有効化することで、情報システムの重要なリソースの可用性、機密性、完全性を保護するのに役立ちます。

## NIST SPの有効化手順
Security Hub>セキュリティ標準から、NIST Special Publication 800-53 Revision 5の標準を有効化します。
※有効化には数分かかる場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/61382a5c-30c7-7e91-154e-4f795f441b78.png)

以上で有効化は完了です。

## NIST SPの有効化時の注意事項
### 既存のセキュリティ標準との差分を確認する
NIST SPを有効化する必要性があるのか、既存のセキュリティ標準と比較しましょう。
私は、AWSベストプラクティス標準とCIS Benchmark v1.4.0を有効化していたので、チェック項目の差分を調査しました。
2024年1月時点で、NIST SPにあって上記の2つにない項目は20個ありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/83c94ea7-1fde-a492-d4d4-2079d53552d0.png)

この中で、Security Hubを利用してチェックしたい項目がある場合には、NIST SPを有効化するという形で導入前の検討を行いましょう。


### 既存の検知項目の無効化・抑制設定を確認
Security  Hubにて検知する項目はあくまで推奨設定であるため、全ての項目に準拠する必要はありません。システムの特性に合わせ、設定が必要な項目を設定することが推奨されます。
システムの特性に合わあない場合は、以下の2つの対応を取ることができます。
* 無効化：検知項目自体を無効化する
* 抑制：検知があったとしてもアラートが発行されないよう抑制する
    ※抑制の場合はリソースごとに設定を変更できます。

既存のセキュリティ標準にて無効化・抑制している項目がNIST SPに含まれている場合は、NIST SPでも同様の対応を取りましょう。

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/controls-configure.html

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/automation-rules.html


### システムの特性に合うようパラメータを変更
2023年11月のアップデートで、Security Hubのチェック項目のパラメータの値を変更できるようになりました。
これまでは、チェック項目がシステムの特性に合わない場合、その項目を無用化または抑制する必要がありましたが、パラメータを変更することで自社のポリシーに合わせることができるようになりました。
※Organizationなしでマルチアカウントを管理している場合、コントロールの制御は各アカウントに委任することとなるため、Security Hub管理者が意図しない形でセキュリティの基準を緩くすることができるため、注意しましょう。

チェック項目の内容を確認し、必要に応じてパラメータを変更しましょう。

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/custom-control-parameters.html

## Security HUbの運用方法
### セキュリティスコアの改善活動
Security Hubのセキュリティスコアを100%にするよう、運用の中で改善活動を行いましょう。
いきなり100%にするのは負荷が高いため、定期的にコツコツと運用することを推奨します。

### アラートの重要度による運用方法の確立
Security Hubのチェック項目には、Criticul、High、Medium、Lowの4つの重要度が設定されています。
重要度が高いほど、即時の対応が求められるようなリスクのある設定状況になっています。
そのため、アラートをうけたら、すぐに対応するような運用をあらかじめチームで決めておくことをお勧めします。
重要度が低い項目については即時の対応は必要なく、日々の改善活動での対応で問題ありません。

# おわりに
Security HUbは利用することも多いと思いますので、是非NIST SP 800-53 Rev.5の有効化を検証してみてください。
githubの既存のリモートブランチ開発を別の環境で再開する方法

# はじめに

@siida36さんの素晴らしい[チーム開発の記事](https://qiita.com/siida36/items/880d92559af9bd245c34)を読んで、よっしゃ頑張るぞー！！となっていたのですが、私は家と外出先で違うパソコンを使っていたために、しばしば`git pull`で苦戦していました。

ずっと、`git pull`で頑張ると思っていたのですが、コンフリクトは起こるし手順が多いしで大変でした(ずっとローカルブランチを作成してそこにpullしていた)。
もっと楽な方法をClaude3に教えてっもらったので、メモしておきます。
一応、手元の環境で動いたので、コマンドは間違っていないと思います。
詳しい方は、「こんなリスクあるよ」って感じで教えていただけると平身低頭して感謝します。m(_ _)m

# 手順

既存のリモートブランチで開発を行う場合の手順は以下の通りです。

## リポジトリのクローン
まだリポジトリをローカル環境にクローンしていない場合は、クローンします。
```
git clone https://github.com/your-username/your-repo.git
```

## リモートブランチの一覧を確認
リモートにあるブランチの一覧を確認します。`origin/~`みたいなブランチ名がたくさん出てきます。
```
git branch -r
```

## 対象のブランチを取得 
開発したいリモートブランチをローカル環境に取得します。
```
git checkout -t origin/branch-name
```

(`git checkout -h`を見たところ、branchの設定を引っ張ってきているっぽい)

## コーディングと変更のコミット
コードの変更を加え、変更をコミットします。
```
git add .
git commit -m "変更内容の説明"
```

## リモートにプッシュ
ローカルブランチの変更をリモートリポジトリにプッシュします。
```
git push origin branch-name
```

## プルリクエストの作成
GitHubにアクセスし、変更したブランチに対してプルリクエストを作成します。レビューを受け、承認されたらmasterブランチにマージできます。

## マスターブランチの更新 
プルリクエストがマージされた場合、ローカルのmasterブランチを更新します。
```
git checkout master 
git pull
```

この手順に従えば、既存のリモートブランチで開発を行うことができます。複数人で同じブランチを共有して開発する場合は、共有先のリモートブランチを最新状態に保つ必要があります。そのためにはgit pullやgit rebaseなどのコマンドを使って定期的に変更を取り込む必要があります。

# 参考文献

- Githubでチーム開発するためのマニュアル https://qiita.com/siida36/items/880d92559af9bd245c34 (2024/4/22参照)
Pythonの備忘録 (超初心者) <入出力>

僕がPythonの使い方をド忘れした時のための備忘録を作成します。

ざっくりPythonの使い方は下の図で表したような感じになっています。
![スクリーンショット 2024-04-22 9.56.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575336/20647be7-dfde-97ee-3afd-5fe0101e5bfe.png)

:::note warn
あくまで上記はイメージです
厳密さを必要とする場合は下記LINKを参照してください。
https://www.python.org/
:::


<!-- open属性あり -->
<details open><summary>数字を出力</summary>

```python
print(1)
```
:::note info
出力
1
:::

<!-- open属性あり -->
<details open><summary>文字を出力</summary>

```python
print(Hello world!)
```


:::note alert
エラー
print(Hello world!)
                ^
SyntaxError: invalid syntax
:::
直訳すると、構文エラー：無効な構文

```rb
print("Hello world!")
```
:::note info
出力

Hello world!
:::

ここまででPythonを使って文字と数字を出力することができました。

Pythonでは四則演算を行うこともできます。
### A問題 (1-1)

```python
print(10+3)
#足し算

print(10-3)
#引き算

print(10/3)
#割り算

print(10*3)
#掛け算
```
:::note info
出力
13
7
3.3333333333333335
30
:::

### A問題 (1-2)

```python
print(10//3)
#商を求める

print(10%3)
#剰余(あまり)を求める
```
:::note info
出力
3
1
:::

### A問題 (1-3)

```python
print("Hello world!"*3)
#Hello world!を３回表示する
```
:::note info
出力
Hello world!Hello world!Hello world!
:::

### B問題 (1-4)

```python
print("Hello world!" + 365 days)
#Hello world! 365 daysを表示する
```
:::note alert
エラー
print("Hello world!" + 365 days)
                               ^
SyntaxError: invalid syntax
:::
構文エラー：無効な構文
```python
print("Hello world!" + "365 days")
#Hello world! 365 daysを表示する
```
:::note info
出力
Hello world!365 days
:::
文字列のデータと数字のデータは直接結合できない。
※文字列を結合する際には数字を文字列とする必要がある
【 Python 超入門書 ① を出版しました】


プログラミングと Python が, 超初心者な方のために, 入門書を書かせていただきました (o'(ェ)')人🐍✨  
<br>

[第２版] になります 🐍
<br>

Windows11 を, プラットフォームとしております 🐍
<br>

amazon の規定で ｢最長５日間｣ までしか, 無料キャンペーンを行えないので, ４月21日から, 25日までの５日間だけ ｢無料配布｣ をさせていただいております 🐍✨
<br>

ご興味ありましたら, 何卒, よろしくお願いいたします 🐍✨


<br>
<br>

↓ ココ

https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Python-%E5%85%A5%E9%96%80%E8%80%85%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%EF%BC%91%E6%AD%A9-Windows11-%E7%AC%AC%EF%BC%92%E7%89%88-ebook/dp/B0D25S733M/ref=sr_1_55?crid=YJK71I1TU9FB&dib=eyJ2IjoiMSJ9.8W6EHlFmfPE5MjnTJke5XB7GNt7k9afgQOamSWCXZyWQB0APm-UvyYVAK3jAMy4-W9T3P68F270dm7kOVV1DhxmY7FYhkZ7FrucA4ob_yx5SP2fM_EmNnc_e1DruymRVhRGz_s5FehDJtfn6ScAIvof4496E2wEEBHlgM6uuUgN4wgWx3HWIM01vnVVJWQIOO_bh-F4daR5EQ5bVNrtOJGECXm8nvPHniuFch2wJxI0AF6K7IsOwjG1wGmS3OPK8q_jckOtjGxUOnUmV-YFpQqJOVwWtzdkZq7zfyi5CnMc.L0KU1FkJ9K0D9MTowzU50znfUviBLh_WJX0poG4jRY8&dib_tag=se&keywords=python+%E5%85%A5%E9%96%80&qid=1713748154&sprefix=%2Caps%2C380&sr=8-55



![japanese_1po_Windoes_Master_ver1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680561/1fa4689e-c2d2-fa05-2cc1-c034b239947c.jpeg)
<br>
<br>
<br>
create-react-appで作成したファイルをGitHub Pagesにdeployする方法

こんにちは！

先日やっとの思いで、create-react-appで作成した簡単なアプリケーションをGitHubPagesにデプロイすることができたので、ここにメモとして残しておきます。

今回のトラブルシュートに関しては二つのサイトを参考にさせていただきました。大変助かりました！ありがとうございました。

https://qiita.com/tat_mae084/items/745761eee6cd1d42949d

https://zenn.dev/acha_n/articles/deploy-react-app-with-github-actions



前提として各種バージョンをここにまとめておきます。

| | Version |
|----|----|
| Ubuntu | 20.04 |
| node | 20.12.2 |

上記のバージョンで本記事の内容に関しては操作していますので、この記事を見て対応される方はこの設定にしてから行っていただくスムーズに進むかと思います。

まず、私の場合では、Ubuntuを用いてGithub操作をしているため、下準備しておかないといけない点がひとつあります。

Ubuntuでのpushの際の認証はユーザー名とトークンで認証を行うのですが、トークンの作成をするさいにworkflowsの項目を選択して発行したものを用いる必要があります。

また、GitHub Actionでは、現在nodeのバージョン16に対応していないので、nodeのバージョンを確認して20まで行進しておいてください。

nodeのバージョン管理の方法に関しては、さまざまな対処法がネット上に挙げられていますが、windowsなのか、macなのか、等環境によってできるできないがあるかもしれません、、、。私の場合、nを使ったバージョン管理の方法がうまくいかず、下記に記載する方法でバージョン管理を行いました。

まずはnodeのバージョンを確認してみて下さい

````
node -v
````

この結果が

````
v20.12.2
````

のように20を超えているのであれば次のセクションの内容は無視してしまって大丈夫です！

## node バージョンアップするための方法

### nvmのインストール

Ubuntuないのお好きなディレクトリ内で以下のコマンドを実行してください

````
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
````

これはnodeのバージョン管理をするためのnvmをインストールします。

### ターミナルを再起動

ここで以下のどちらかの操作をします。

- ターミナルを閉じて再起動


- 下記コマンドを実行して手動でnvmを読み込む
````
source ~/.bashrc
````

### Node.jsをインストールします

````
nvm install 20
````

このコマンドでバージョン20のNodejsをインストールします。

### デフォルトのNode.jsのバージョン管理

````
nvm use 20
````

このコマンドで現在のセッションに対してNode.jsのバージョンを20に変更します。

#### 永続的にnodeのバージョンを20に設定する

現在のセッションでnodeのバージョンは20ですが、これはセッションを新しくするとまたリセットされてしまいます。ですので、後日ここに永続的にnodeのバージョンを設定する方法を記載したいと思います。


## workfrowファイルの追加

deployに必要となる新規ファイルを作成します。

````
mkdir .github

cd .github

mkdir workflows

cd workflows
````

この手順でコマンドを実行し、本操作でデプロイするためのディレクトリに移動し、code .を実行してVS codeを開きましょう。

workflowsディレクトリの階層下に<お好きな名前.yml>ファイルを作成します。

このファイルの内容は

https://zenn.dev/acha_n/articles/deploy-react-app-with-github-actions

こちらの記事に記載していただいているので、こちらを参考にしていただけるといいと思います！nodeのバージョンなどは自身の環境に対応するように設定してみてください。

## package.jsonファイルの編集

こちらの内容に関しては

https://qiita.com/tat_mae084/items/745761eee6cd1d42949d

この記事を参考にさせていただきました。

このように操作をすると、一通り、GitHub Pagesにデプロイすることができると思います！

手詰まりで非常に困っていましたが、上記2つの記事のおかげで解決し、無事デプロイすることができました！

私と同じ状況で困っている方がいらっしゃいましたら、この記事を参考にしていただけますと幸いです！
Microsoft Edge (及び Chromium 系 Browser 全般) v124 から Office 系ファイルの DL に制限がかかる件について

# これは何？
Microsoft Edge v124 に更新後、下記画像のように "XXX を安全にダウンロードすることはできません" と表示され、
Office 系のファイル等にてダウンロードに失敗する事象の理由と解決策です。
なお、先立ちますがこの動作は **Chromium の仕様変更による想定の挙動**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/253cb7a3-1a58-43fe-ddbe-0898f3b78c1a.png)

# 2024/05/01 追記
リリースノートに下記が追記されました。
元の動作に一時的に戻っていますが、~~v127 で再度警告表示されるようになります。~~
今のうちから対処 (https 化) することをお勧めします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/0632d6af-514a-339d-7373-89c658af7596.png)


# 2024/06/04 追記
5/9 付で再警告表示への切り戻しが v127 → 未定となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/1055bef3-c1a8-ca58-6e9e-11d6fc5cec07.png)

# 理由
Chromiumの "HTTPS by default"イニシアチブの一環として v124 から "Insecure Download Warnings" 機能が有効になったことが起因です。

HTTP での一部ファイル ダウンロードにて制限が発生するというものです。

# 解決策
クライアント (ブラウザ) サイドでの対応は下記ポリシーを利用することが唯一の回避策となります。
・[指定されたサイトのセキュリティで保護されていないコンテンツを許可する (InsecureContentAllowedForUrls)](https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-policies#insecurecontentallowedforurls) 

Edge のポリシーテンプレートは[こちら](https://www.microsoft.com/ja-jp/edge/business/download?form=MA13FJ)からご利用ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/a6dca11c-7ca0-a3a1-b79b-f02089632548.png)

## ポリシーのレジストリ適用サンプル
ポリシードキュメントをお読みいただくのが一番ですが、一応。
HKLM / HKCU どちらでも OK です。
```Edge:Registry
SOFTWARE\Policies\Microsoft\Edge\InsecureContentAllowedForUrls\1 = "[*.]example.com"
```

## ポリシー補足
このポリシー自体の説明文には特に記載はありませんが、末尾の "参考" にも本ポリシーの記載が言及されています。


# 本質的には

基本的にはファイルの取得元プロトコルを https 化することが推奨される対応事項となります。

# 補足
どうにも "拡張子のみを見ている" ようで、同バイナリでもファイル名を変えるだけでダウンロードが可能なようです。

# 参考
[Towards HTTPS by default (Chromium Blog)](https://blog.chromium.org/2023/08/towards-https-by-default.html)
知らなかったPostgreSQLとMySQLのCURRENT_TIMESTAMPの違い

# 結論
* PostgresqlのCURRENT_TIMESTAMPはトランザクションを開始していれば、トランザクション開始日時(マイクロ秒+タイムゾーン)
* MySQLのCURRENT_TIMESTAMPはSQL実行日時(秒)

# 実験
## Postgresql(トランザクションなし)
*　SQL実行ごとにtimestampが変化する

```
test=# select current_timestamp;
       current_timestamp
-------------------------------
 2024-04-15 12:21:01.667985+09
(1 row)

(10秒ほどまつ)

test=# select current_timestamp;
       current_timestamp
-------------------------------
 2024-04-15 12:21:13.965251+09
(1 row)

```

## Postgresql(トランザクションあり)
*　SQL実行ごとにtimestampが変化しない

```
md=# start transaction;
START TRANSACTION
md=*# select current_timestamp;
       current_timestamp
-------------------------------
 2024-04-15 12:22:05.814094+09
(1 row)

(同じく10秒ほどまつ)

md=*# select current_timestamp;
       current_timestamp
-------------------------------
 2024-04-15 12:22:05.814094+09
(1 row)
```

## MySQL(トランザクションなし)
* SQL実行ごとにtimestampが変化する

```
mysql> select current_timestamp;
+---------------------+
| current_timestamp   |
+---------------------+
| 2024-04-15 13:13:09 |
+---------------------+
1 row in set (0.00 sec)

(同じく10秒ほどまつ)

mysql> select current_timestamp;
+---------------------+
| current_timestamp   |
+---------------------+
| 2024-04-15 13:13:19 |
+---------------------+
1 row in set (0.01 sec)
```

## MySQL(トランザクションあり)
* SQL実行ごとにtimestampが変化する

```
mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)

mysql> select current_timestamp;
+---------------------+
| current_timestamp   |
+---------------------+
| 2024-04-15 13:14:48 |
+---------------------+
1 row in set (0.01 sec)

(同じく10秒ほどまつ)

mysql> select current_timestamp;
+---------------------+
| current_timestamp   |
+---------------------+
| 2024-04-15 13:15:01 |
+---------------------+
1 row in set (0.01 sec)
```
エクセルのマクロで特定の条件を満たす行を色分け

このQiita記事では、Excelのワークシートで特定の条件に基づいて行の背景色を動的に設定するVBAマクロ「Condition1」について詳しく解説します。ビジネスでのレポートやデータ分析において、特定のデータを視覚的に際立たせることは非常に重要です。このマクロは、特定の条件を満たすデータをすぐに識別できるように色分けするために使える便利なツールです。

### マクロの活用シナリオ

- **週末のデータの強調**: 週末（土曜日や日曜日）のデータを自動で色分けし、平日との比較を容易にする。
- **重要度に基づく色分け**: 特定の列に設定された重要度（例えば1から6の評価）に応じて、行全体の色を変更し、重要な情報をすぐに目に付くようにする。
- **データの監視とレポート作成**: 定期的に更新されるレポートで、即座に注目すべき変更や傾向を識別するために使用する。

### コードの解説

マクロは以下の主要なステップで構成されています：

1. **ワークシートの設定**
    ```vba
    Dim ws As Worksheet
    Set ws = ActiveSheet
    ```
    現在アクティブなワークシートを`ws`変数に設定して操作します。

2. **色を設定する列の長さ**
    ```vba
    Dim Length As Long
    Length = 40
    ```
    背景色を設定する範囲を1列目から40列目までと定義します。

3. **条件に応じた色の設定**
    ```vba
    Dim i As Long
    For i = ActiveCell.Row To ws.UsedRange.Rows.Count
        ' 土曜日または日曜日の行の色を設定
        If ws.Cells(i, 2) = "Sat" Or ws.Cells(i, 2) = "Sun" Then
            ws.Range(ws.Cells(i, 1), ws.Cells(i, Length)).Interior.ColorIndex = 48
        Else
            ws.Range(ws.Cells(i, 1), ws.Cells(i, Length)).Interior.ColorIndex = xlNone
        End If
        ' 重要度に基づく色の設定
        Select Case ws.Cells(i, 3)
            Case 1 To 6
                Dim ColorIndexes As Variant
                ColorIndexes = Array(xlNone, 48, 42, 50, 8, 15, 10)
                ws.Range(ws.Cells(i, 1), ws.Cells(i, Length)).Interior.ColorIndex = ColorIndexes(ws.Cells(i, 3))
        End Select
    Next i
    ```
    - 各行に対してループを行い、条件に応じて背景色を設定します。土曜日や日曜日は色インデックス48で塗りつぶされ、他の条件（1から6の重要度）にはそれぞれ異なる色が割り当てられます。

### まとめ

このVBAマクロは、データの視覚的分析を強化し、特定の情報を迅速に把握するために非常に役立ちます。マクロの自動化により、時間を節約し、エラーの可能性を減らすことができます。Excelでのデータ管理を次のレベルに引き上げるための一歩として、このようなカスタムマクロの開発と適用を検討してみてください。
公開グループのまとめ public group 

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)


+ [公開リンク(Public Link)](https://qiita.com/Keiji_otsubo/items/507a40a10ebb4f3aa746)

+ [Experience Cloud コミュニティユーザーは Experience Cloud 上で Chatter グループを共有できますが、Salesforce 内部の Chatter グループは共有できないと思います。](https://qiita.com/Keiji_otsubo/items/f7396a7effc0f34c8239)
+ [グループメンバーからユーザーレコードを取得(フローを使う)](https://qiita.com/Keiji_otsubo/items/89d76dddfa9ba51140d2)
+ [MIXED_DML_OPERATION](https://qiita.com/Keiji_otsubo/items/2819e743710c72d20e0b)
AWS Certified Solutions Architect – Associate になった (SAA-C03)

812 点でした。取ろうと決意したのは 1 年前ですが、真剣に勉強したのは 10 日ほどです。仕事が落ち着いていたので、フレックスタイムを駆使して時間を捻出しました。

この記事では、おすすめの勉強法 & 受験法と、補足として私の AWS 関連の経験をお伝えします。


# おすすめの勉強法 & 受験法

1. [『AWS認定ソリューションアーキテクト－プロフェッショナル ～試験特性から導き出した演習問題と詳細解説～』](https://www.ric.co.jp/book/qualification3/detail/272)の「第 2 章 各種サービスの概要」を読む
    - 買うのはちょっと、という場合は、わからないサービスは検索して調べる。
    - SAP-C01 の頃の本だが、Professional まで取るつもりならば買う価値はある。
1. [AWS Certified Solutions Architect - Associate (SAA-C03) 試験問題サンプル](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Sample-Questions.pdf)を解く
    - 後述の模擬問題集よりも説明がわかりやすく正確。
    - 誤答してしまったり、あやふやだったところはノート[^note]にポイントをメモしておく。以下同様。
1. Skill Builder の [AWS Certified Solutions Architect – Associate Official Practice Question Set (SAA-C03 - Japanese)](https://explore.skillbuilder.aws/learn/course/external/view/elearning/13269/aws-certified-solutions-architect-associate-official-practice-question-set-saa-c03-japanese) を解く
1. [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)を解く
    - 会社で年 4 回の Udemy for Business の募集がかかった際にすかさず申し込み、早い者勝ちの競争に勝利したので、無料で利用できた。
    - 1,500 円なら自費でもおすすめ。
    - 解説が正しいか疑問に思うところは研修で確認するため別途メモしておく。
1. Architecting on AWS 研修を受講する
    - 問題を解いていて疑問に思ったところを、研修環境で確認したり、講師に質問したりする。
    - たぶんアソシエイト試験のバウチャーがついてくる。有効期限は短いので、受講後すかさず申し込む。迷惑メール フォルダーに届く場合があるので要注意。
    - 自費での受講は無理だと思うので、自費の人は AWS のアカウントを作って少しでも実際に触れておくと良い。自腹では確認困難なところは勉強会や Qiita で質問すると良いかもしれない。
1. 前述の問題集の正答率を上げていく
    - Udemy の問題集の方が難しいという噂。
    - 9 割取れればたぶん大丈夫。
1. 受験する
    - 予約前に、利用可能な AWS のキャンペーンがないか検索。
    - 受験前にノートを読み返す。
    - 誤訳もありえるので日本語でわからない問題は英語も参照する。
    - 2 時間後に結果がメールで届いた。

**大事なことは以上です。**

---

# AWS 関連の経験

真剣に勉強を始める前にどのくらいの知識があったかも記しておいた方が良いと思いますので、AWS 関連の経験を書いておきます。AWS は 2013 年から個人的に触っているのですが、業務として触れられた機会はあまりなく、知識が偏っていました。

## 個人での利用経験

S3 をファイルの保管と転送用に継続的に使っているほかは、年に数回ネットワーク関連のソフトウェアの動作確認に VPC & EC2 を使う程度です。とはいえ、これらの基本的なサービスを理解していたことは学習を進める上でとても助けになりました。

## 業務経験

- 2019 年頃、EC2 + RDS 環境の構築と、その環境での Spring Batch の性能検証をしました。サーバーの停止忘れ防止のために EventBridge + Lambda を使ったような気がします。
- 2021 年頃、Serverless Application Model (SAM) を使ってプライベート クラウドで Java で書かれた Lambda を動作確認できるようにしました。業務中に見つけた SAM のバグには、[修正のプル リクエスト](https://github.com/aws/aws-sam-cli-app-templates/pull/156)を出し、取り込んでいただくことができました。しかし残念なことに開発したもの自体はお蔵入りになってしまっているため、AWS のクラウドには全く触れられませんでした。
- 2024 年、時々 aws s3 cp コマンドで EC2 にファイルをダウンロードしています。これも一応業務経験ですよね。

## 研修受講経験

- 2022 年頃、AWS ではありませんが、[Architecting with Google Kubernetes Engine](https://cloud.google.com/training/class-schedule?hl=ja#/language=Japanese&title=Architecting_with_Google_Kubernetes_Engine) 受講
    - この研修のおかげで AWS の EKS がどんなサービスなのか想像できた
- 2023 年頃、[Architecting on AWS](https://academy.intellilink.co.jp/aws/ArchitectingonAWS) 受講
- 2023 年頃、[Advanced Architecting on AWS](https://academy.intellilink.co.jp/aws/AdvancedArchitectingonAWS) 受講

## 反省点

研修を受講してから問題集を解いたので、疑問点を自分で調べなければならず大変でした。問題集で勉強してから研修を受講し、研修で疑問点を解消した方が良かったと思います。研修で試験のバウチャーが貰えるようですので、その意味でも研修は後が良いです。


[^note]: 紙か電子媒体かは迷うところです。私は紙派ですが、電子媒体なら検索できたのにと思うことはあります。
[TypeScript] オブジェクト型の型宣言をマスターしよう！

### 初めに

オブジェクト型の型宣言についてマスターしていきましょう！

### 【目次】
[まずは基本的な型宣言をマスターしよう！](https://qiita.com/PenPe/items/c189a611b3407b7ceef9)
[オブジェクト型の型宣言をマスターしよう！](https://qiita.com/PenPe/items/440683cc6e5e4ac0ca32) ←🈁
[関数の型定義をマスターしよう！](https://qiita.com/PenPe/items/bff109c6f83f46d191a7)
[配列をマスターしよう！](https://qiita.com/PenPe/items/7e056eec2cce76a745a9)
[インターフェースをマスターしよう！](https://qiita.com/PenPe/items/f9314aeccb2f23cac382)
[クラスを使いこなそう！](https://qiita.com/PenPe/items/c8e6289f386c4db23a6f)
[型修飾子についての理解を深めよう！](https://qiita.com/PenPe/items/7af57861e93830fe9a79)
[ジェネリックをマスターしよう！](https://qiita.com/PenPe/items/fde6a342e746e265d907)
[独自の構文拡張をマスターしよう！](https://qiita.com/PenPe/items/c79cdb5bc4a68a1dfd7f)

---

### 基本的な型宣言
```typescript
let sampleObj: {
  prop1: string, 
  prop2: number
}
```

```typescript
type SampleObj = {
  prop1: string,
  prop2: number
}

let obj: SampleObj;

obj = {
  prop1: "str",
  prop2: 1234
}
```

---

### ネストされたオブジェクト型の場合
```typescript
type SampleObj = {
  nested: NestedObj,
  prop1: string
}

type NestedObj = {
  prop1: string,
  prop2: number
}

let obj: SampleObj = {
  nested: {
    prop1: "nested",
    prop2: 1234
  },
  prop1: "SampleObj"
}
```

---

### オプショナルプロパティ
TypeScriptのオブジェクトは基本的に全てのプロパティへの値格納が必須です。
但し、プロパティ名の末尾に `?` を付与することで省略可能プロパティとして宣言することができます。

```typescript
type OptionalObj = {
  prop1: string,
  optionalProp?: number
}

// OK
let sampleA: OptionalObj = {
  prop1: "str",
  optionalProp: 1234
}

// OK
let sampleB: OptionalObj = {
  prop1: "str",
}
```

---

### オブジェクト型の合併型
:memo: オブジェクト型についても合併型を用いることができます。

```typescript
​​type ObjA = {
  prop1: string,
  prop2: number,
  type: "A"
}

type ObjB = {
  prop1: string,
  prop3: number,
  type: "B"
}

let objA: ObjA = {
  prop1: "str",
  prop2: 1234,
  type: "A"
}

let objB: ObjB = {
  prop1: "str",
  prop3: 1234,
  type: "B"
}

let sampleObj: ObjA | ObjB = Math.random() > 0.5 ? objA : objB;

// 通常の合併型と同様両データ型が持ちうるプロパティのみ呼び出し可能
sampleObj.prop1 // OK
sampleObj.prop2 //NG
```

#### :memo: オブジェクトの絞り込み
変数が取りうるデータ型を絞り込むことで、特定のデータ型のみが持つプロパティを呼び出すことが可能です。

```typescript
if (sampleObj.type === "A") {
  sampleObj.prop2
} else {
  sampleObj.prop3
}
```

このようにオブジェクトの`type`（リテラル型）で絞り込むデザインパターンを`discriminated union`という。
https://typescriptbook.jp/reference/values-types-variables/discriminated-union

---

### 交差型
以下の定義で、複数のデータ型を同時に満たす型を定義できる。
`データ型A & データ型B`

```typescript
type ObjFirst = {
  prop1: string,
  prop2: number,
}

type ObjSecond = {
  prop1: string,
  prop3: number,
}

// 交差型の定義
type ObjFirstAndSecond = ObjFirst & ObjSecond;

// ObjFirst, ObjSecondを組み合わせたデータ定義となる
let sampleObj: ObjFirstAndSecond = {
  prop1: "str",
  prop2: 1234,
  prop3: 4567
}

```

---

### まとめ

以上です！
次節として、配列に関する記事を公開しておりますので、よろしければご覧ください🙏

https://qiita.com/PenPe/items/bff109c6f83f46d191a7
You or your organation has execeeded the maximum limit 

事例を集めて整理したいと思います。

+ [Your Org Has Exceeded Maximum Limit for this Feature - Flows](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A9CMcSAN)

:::note
Sounds like you have too many steps in your flow to complete transation. Flows are limited to 2000 steps per transaction. 

I'm guessig that you're either processing lots of records individually, or have some nested loops in your flow. 

Try debugging your flow from editor window. You'll see how many steps it performed before hitting the limit. 

You can add screen elements to your flow to break it into smaller transactions - this works for me at least :)

フロー内にトランザクションを完了するにはステップが多すぎるようです。フローはトランザクションごとに 2000 ステップに制限されます。 
 
多くのレコードを個別に処理しているか、フロー内にネストされたループがいくつかあると思います。 
 
エディター ウィンドウからフローをデバッグしてみてください。制限に達するまでに実行されたステップ数が表示されます。 
 
フローに画面要素を追加して、より小さなトランザクションに分割できます - これは少なくとも私にとってはうまくいきます:)
:::

+ [Limit Exceeded You or your organization has exceeded the maximum limit for this feature.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000KgieRSAR)

The flow error email reads Apex CPU time limit exceeded
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/711f32fa-d2a8-2757-1db3-5a8a37883701.png)

# トレイルヘッド

+ [CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Mars” process failed. Give your Salesforce admin these details. <b>Limit Exceeded</b><br>You or your organization has exceeded the maximum limit for this feature. Error ID: 1605358900-91659 (-1643661209)anization has exceeded the maximum limit for this feature. Error ID: 1605358900-91659 (-1643661209): []](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000078S9UASA0)
+ [We can't save this record because the “Mars” process failed. Give your Salesforce admin these details. <b>Limit Exceeded</b> You or your organization has exceeded the maximum limit for this feature. Error ID: 998694744-144711 (1624281920)ganization has exceeded the maximum limit for this feature. Error ID: 998694744-144711 (1624281920](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000076AmqPSAS)
+ [CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Mars” process failed. Give your Salesforce admin these details. <b>Limit Exceeded</b><br>You or your organization has exceeded the maximum limit for this feature. Error ID: 1404601904-88007 (-1643661209)anization has exceeded the maximum limit for this feature. Error ID: 1404601904-88007 (-1643661209): []](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000J9DFL0A3)
秋月の1.3 インチフルカラーグラフィック液晶ディスプレイで時計を作って遊ぶ(StampS3)


x 時間合わせは、別
x あまり、正確では、ない
x 秋月のDS1307ユニットを使用
x 秋月のAE-ATM0130B3を使用
x 過去ログを見よ!!

目的
ST7789V2のディスプレイで時計を作って遊ぶ。

結果

![o_coq052.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f2098b7f-9625-7d9e-458f-ae9400530f8a.jpeg)


プログラム

```c++



//spi_st7789_DS1307_M5S3_1


//ヘッダーファイル
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>


//定義
#define TFT_CS    1
#define TFT_RST   3
#define TFT_DC    5
#define TFT_MOSI  7
#define TFT_SCLK  9

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);


//初期化
void setup() {

  //I2Cの初期化
  Wire.begin();

  //240x240の液晶を使用する。
  tft.init(240, 240);           // Init ST7789 240x240

  // 画面表示をクリア
  tft.fillScreen(ST77XX_BLACK);

  // テキストサイズを設定
  tft.setTextSize(5);

}//setup


char cn1[16] = "12:34"; //時刻

//メインループ
void loop() {

  // 前に表示した内容で消す。
  // テキスト色を設定
  tft.setTextColor(ST77XX_BLACK);
  // テキストの開始位置を設定
  tft.setCursor(0, 10);
  tft.print(cn1); //前に表示した内容


  // テキスト色を設定
  tft.setTextColor(ST77XX_WHITE);
  // テキストの開始位置を設定
  tft.setCursor(0, 10);

  //RTC DS1307のアドレス
#define ADDR    0x68    // 2進数 1101000

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  unsigned char data_read[16] = {0x88, 0x88, 0x88}; //データバッファー
  int ii = 0;
  while (Wire.available())  {   // 要求より短いデータが来る可能性あり
    data_read[ii++] = Wire.read();       // 1バイトを受信
  }//while

  //dbug
  //char data_read[16];//debug
  //data_read[2] = 0x01; data_read[1] = 0x23;

  //表示変換する
  cn1[0] = '0' + (data_read[2] >> 4);  //0 時 上位
  cn1[1] = '0' + (data_read[2] & 0xf); //1 時 下位
  cn1[2] = ':';
  cn1[3] = '0' + (data_read[1] >> 4);  //2 分 上位
  cn1[4] = '0' + (data_read[1] & 0xf); //3 分 下位
  cn1[5] = 0;

  tft.print(cn1); //表示

  for(int hh=0;hh<60;hh++) {delay(1000);  /*1秒待つ*/}

}//loop



```
Brightを使ってElixirのスキルを伸ばす方法を考える

# 前提
- Brightに登録後
- スキルを選ぶで「Webアプリ開発 Elixir」を選択済み
- １回目のスキル入力済み

https://app.bright-fun.org/

# スキルを分析してみる
- 「成長パネル」をクリック
- グラフを確認し自分の弱点を分析する
- あと、どのくらいで「平均」または「ベテラン」になれるかを目標を確認する
  - 仕事をもらうにあったて報酬に影響が実際あるところがある
    - 昭和の時代と違い「上司にごますり」でなく「スキルベース」であるところがBrightを使うメリット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/0f832b9e-8b5b-084a-399f-caddb5b82a61.png)

分析結果から「テスト」が弱いことがわかる

# 勉強する候補を考える
僕の例は「テスト」を強化したい
まず、グラフの「テスト」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/310efb80-0f7b-027d-6fff-9ffa408ca3de.png)

---

「スキルパネル」のテストに画面がスクロールする
僕の場合は「総合テスト」がわからない

学習メモをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/5c93d3f9-42f7-788d-13f4-50fb2448468b.png)


# 学習メモを使ってみる

### 質問してみる
- 学習メモを入力する
- 「このメモでヘルプを出す」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/8816f74c-eafc-82c3-877d-87a24bca7734.png)

### 学習記録を書いてみる
- 僕の場合はQiitaに記事を書く
- Qiitaの記事のリンクを張る
- 「メモを書き込む」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/0eb1ee31-d647-bc27-e7ec-1b9ef4296eae.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/a85b73ac-8bcf-01ca-3b56-4f842ee58f37.png)


### 学習候補を決めてメモする
僕の場合は調査中と書いてリンクを張る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/8971cdb5-a1a9-64d8-a80e-75915bde5a5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/d97399f4-3eac-7f3f-6bd5-887030be353e.png)

隙間時間に勉強をすることにする

僕はこのような使い方をしてます、以上
StampS3でI2Cスレーブから「46」を読み込む。

目的
I2Cスレーブの読み取りテスト

結果

![o_coq050.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f12f0a3d-c066-bdd4-3026-e014ae99623e.jpeg)

![o_coq051.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4641bb7f-371f-2fa6-b147-7664ab1f631e.jpeg)



受信(スレーブ) StampS3


```c++


//I2C_slave_OUT_46_M5S3_1


//インクルド
#include <Arduino.h>
#include <Wire.h>     //I2C


//定義 I2Cアドレス
#define ADD_1 (0x80>>1)


//初期化処理
void setup() {

  //I2Cの初期化
  Wire.begin( ADD_1 ); // Slave ID #80
  Wire.onRequest(requestEvent); //呼ばれる関数

}//setup


//メインループ
void loop() {
  delay(1); //ダミー
}//loop


//I2Cの読み取り関数
void requestEvent() {

  //値の送信
  Wire.write( 46 );

}//requestEvent



```


送信(マスター) Arduino UNO V3


```c++



//I2C_master_IN_46_UNO_1


//インクルド
#include <Arduino.h>
#include <Wire.h>     //I2C


//定義 I2Cアドレス
#define ADD_1 (0x80>>1)


//初期化
void setup() {

  Serial.begin(9600); //シリアルポートの初期化

  Wire.begin();  //I2Cの初期化

} //setup


//メインループ
void loop() {

  //読み込み
  Wire.requestFrom( ADD_1 , 1);

  int b = 99; //読み込み値 バイナリーの「b」
  while (Wire.available())  {   // 要求より短いデータが来る可能性あり
    b = Wire.read();            // 1バイトを受信
  } //while

  //値を表示
  Serial.println(b);

  delay(1000); //1秒待つ

} //loop



```
【個人開発】オススメするハードルの低い、コンテンツシェアアプリ「Recomd」を作りました！


 　
はじめまして、個人開発でアプリを作っているcatos/katoです。今回、アプリのきっかけとなるアイデアを思いついてから、5年くらい寝かせていたオススメするハードルの低い、コンテンツシェアアプリ「Recomd」（リコム）をリリースしました！
　

 
https://apps.apple.com/jp/app/recomd-%E3%81%8A%E3%81%99%E3%81%99%E3%82%81%E5%85%B1%E6%9C%89%E3%82%A2%E3%83%97%E3%83%AA/id6483865543

https://play.google.com/store/apps/details?id=com.catos.Recomd

# アプリの概要
このアプリは、Youtube、Netflix、ジャンプ+などのアプリで閲覧できる様々なコンテンツをレビューして共有するアプリになります。友達同士で、良いと思ったコンテンツを気軽にオススメしあったり、自分の好みと近い人を見つけることができます。（気軽に、どこかの誰かにオススメしたい時にも使えます。）

# アプリ開発のきっかけ
### ・  知り合いからのオススメは、強い
YouTubeやNetflixでAIが推薦するものや、どこかの誰かが決めたランキングよりも、友人からオススメされたり有名人が紹介しているのを聞いた時の方が、実際に興味を引かれて見ることが多く、知っている人からのオススメの力を感じました。

### ・  新しいコンテンツに出会いにくい

コンテンツが溢れている現代において、AIがオススメするのは、ユーザーが過去に閲覧したものの系統に偏っていて、普段見ていなかったジャンルと出会う機会が無いので、友達や好みが近い人からのオススメによって新たなコンテンツと出会える環境を作りたいと思いました。

### ・  オススメすることのハードルが高い

従来のソーシャルメディアでは、面白いと思った動画や漫画を気軽に紹介するのが難しく、特にLINEでは、「オススメ！」と強く推すと見ることを強制しているようだし、Twitterで毎回、これ面白い、これ面白いって投稿するとウザがられそうなどオススメすることのハードルがある環境に対して、強要しない形で、何も気にせず「これ面白いよ」と紹介する場が必要だと感じていました。

# アプリの機能
### ・  おすすめしたいコンテンツを投稿

#### 1. コンテンツの発見と共有
オススメしたい動画、曲、漫画などのコンテンツを見つけたら、「シェア」または「共有」ボタンをタップします。
#### 2. アプリでの操作
もし「Recomd」が共有オプションに表示されない場合は、「他のアプリで共有」を選択し、「Recomd」を開きます。（Recomdで直接URLを貼ってレビューすることも可能です。）
#### 3. コンテンツの評価とレビュー
レビュー画面が開いたら、コンテンツを5段階で評価し、コメント（任意）を付けてレビューを投稿します。投稿されたコンテンツは、あなたをフォローしているユーザーのホーム画面や新着の投稿閲覧画面で表示されるようになります。

 ![コンテンツ投稿.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774137/c0459a5f-8bf3-8353-b368-d8211646de90.png)
*Youtube Musicの曲をレビュー*

### ・  おすすめされたコンテンツを閲覧

#### 1. ホーム画面での閲覧
フォローしているユーザーの最新のレビューがホーム画面に表示されます。これにより、信頼できる情報源からのおすすめコンテンツをすぐにチェックできます。

#### 2. 検索画面での探索
検索画面では、新着レビューや最もレビューされているコンテンツが一覧で表示されます。ここから気になるコンテンツを見つけることができます。

#### 3. コンテンツの詳細閲覧
気になるコンテンツがあれば、レビューのコメントを読んだり、〜で開くボタンをタップして対象のアプリで直接コンテンツを閲覧することが可能です。
　
![コンテンツ閲覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774137/c3455a79-7049-d2fa-46e9-faadb869ad3e.png)
*Home画面（左）、新着のコンテンツ一覧画面（右）*


## 最後に

みんながRecomdでオススメをシェアしあって、世の中に溢れている良いコンテンツが、色んな人の目に止まるようになったり、初めましての人とRecomdのアカウントを見せ合って、お互いの好きなものを知って会話のネタにするのが、当たり前になったら嬉しいです！

ぜひ、友達や知り合いと使ってみてください！感想待ってます！

## 
https://apps.apple.com/jp/app/recomd-%E3%81%8A%E3%81%99%E3%81%99%E3%82%81%E5%85%B1%E6%9C%89%E3%82%A2%E3%83%97%E3%83%AA/id6483865543

https://play.google.com/store/apps/details?id=com.catos.Recomd
「変換/無変換」で「あ/A」の切り替え方法


- 変換/無変換キーによる日本語とローマ字の切り替えを実現するための備忘録
- キーボード左上の「半角/全角」キーによる切り替えと同等の機能を「変換/無変換」キーで実現

## 方法
1. タスクバーの言語バー(あ/A)を右クリックして、[設定]を選択します。
1. [設定]ウィンドウが表示されたら、[キーとタッチのカスタマイズ]を選択します。
1. [キーの割り当て]タブからIMEの設定を調整します。
    - 無変換キーをIME-オフに設定
    - 変換キーをIME-オンに設定

## リファレンス
- [日本語入力が劇的に楽になる！ 変換/無変換キーで日本語入力をON/OFFする方法](https://penchi.jp/archives/15550.html)
【Rails】ActiveStorageにバリデーションを設定する方法

## Gemをインストールする

`active_storage_validations`をインストールします。

https://github.com/igorkasyanchuk/active_storage_validations

```rb:Gemfile
gem 'active_storage_validations'

# :dimension　または　:aspect_ratioを使用する場合には以下のいずれかを併せてインストールします。
gem 'mini_magick', '>= 4.9.5'
gem 'ruby-vips', '>= 2.1.0'

```

```terminal:ターミナル
bundle install 
```

## バリデーションを設定する

モデルにバリデーションを記述します。

```app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar

  validates :avatar, content_type: { in: %w[image/jpeg image/png] }, size: { less_than_or_equal_to: 2.megabytes }
end
```

上記の場合にはjpegおよびpngのファイルで2MB以下のものを許可します。