OmniAICreator/Qiita-1.07M huggingface dataset:
S3にコンテナデータを保存

ハンズオン教材を使って、S3にコンテナデータを保存をしたので備忘録として残します。

# インストール
AWS CLI をインストールします。
```
pip install --upgrade --user awscli
```

アクセスキーID とシークレットアクセスキーを使用します。
us-east-1デフォルトのリージョンとして使用します。
出力は今回はjsonとします。

```
aws configure
AWS Access Key ID [None]: xxxx
AWS Secret Access Key [None]: xxxx
Default region name [None]: us-east-1
Default output format [None]: json
```

資格情報をユーザーにrootをコピーします。
```
sudo cp -r ~/.aws /root
```

s3fs-fuseインストールします。
```
sudo yum install s3fs-fuse -y
```

# バケット設定
サーバーにマウントポイントを作成します。
```
sudo mkdir /mnt/widget-factory
```

S3 バケットをマウントします。
```
export BUCKET=xxxx
```

AWSの請求額を抑えるためS3への余計な呼び出し減らすには、use_cacheマウント時にオプションを設定して、ローカルファイルシステムのキャッシュを有効にします。
```
sudo s3fs $BUCKET /mnt/widget-factory -o allow_other -o default_acl=public-read -o use_cache=/tmp/s3fs

ll /mnt/widget-factory
total 0

ll
total 0
drwxrwxr-x. 4 xxxx xxxx 29 Oct  8 23:42 widget-factory-inc
```

ウェブサイトのファイルをバケットにコピーします。
```
cp -r ~/widget-factory-inc/web/* /mnt/widget-factory
```

ファイルがフォルダーにあることを確認します。
```
ll /mnt/widget-factory
total 13
drwxrwxr-x. 1 cloud_user cloud_user    0 Oct  9 02:09 img
-rw-rw-r--. 1 cloud_user cloud_user 3059 Oct  9 02:09 index.html
-rw-rw-r--. 1 cloud_user cloud_user 2910 Oct  9 02:09 quote.html
-rw-rw-r--. 1 cloud_user cloud_user 2611 Oct  9 02:09 support.html
-rw-rw-r--. 1 cloud_user cloud_user 2645 Oct  9 02:09 widgets.html
```

ファイルがS3バケットにあることを確認します。
```
aws s3 ls s3://$BUCKET
                           PRE img/
2022-10-09 02:09:31       3059 index.html
2022-10-09 02:09:32       2910 quote.html
2022-10-09 02:09:32       2611 support.html
2022-10-09 02:09:32       2645 widgets.html
```

# DockerコンテナでS3バケットファイルの設定
Webサイトを提供するコンテナを実行します。
バケットをマウントし、WebサーバーのHTTPポートを公開します。
```
docker run -d --name web1 -p 80:80 --mount type=bind,source=/mnt/widget-factory,target=/usr/local/apache/htdocs,readonly httpd:2.4
```

ファイルに先ほどの設定が反映されているか確認します。
```
ll /tmp/s3fs/
total 0
drwxr-xr-x. 3 root root 93 Oct  9 02:09 widgetfactory-xxxx

ll /tmp/s3fs/widgetfactory-xxxx
total 16
drwxr-xr-x. 2 root root   76 Oct  9 02:09 img
-rw-------. 1 root root 3059 Oct  9 02:09 index.html
-rw-------. 1 root root 2910 Oct  9 02:09 quote.html
-rw-------. 1 root root 2611 Oct  9 02:09 support.html
-rw-------. 1 root root 2645 Oct  9 02:09 widgets.html
```

ブラウザでパブリックIPを入力し、Webページを表示します。

既存のページのコピーを作成して、バケット内に`newPage.html`という新しいページを作成します。
```
cd /mnt/widget-factory/
cp index.html newPage.html
```

ブラウザーで下記の新しい Web ページを表示します。
`http://<パブリックIP>/newPage.html。`

新しい Web ページが S3 バケットにあることを確認します。

```
aws s3 ls $BUCKET
                           PRE img/
2022-10-09 02:09:31       3059 index.html
2022-10-09 02:23:05       3059 newPage.html
2022-10-09 02:09:32       2910 quote.html
2022-10-09 02:09:32       2611 support.html
2022-10-09 02:09:32       2645 widgets.html
```
DockerでRedmineを構築

# 背景
プロジェクト管理で、以下の条件を満たして課題・タスクを管理できるツールを探していたところ、Redmineにプラグインを追加することで条件を満たしそうだったので、Dockerを使ってサクッとRedmine環境を構築してみた。

- 前提条件
    - 無料
    - 課題とタスクの紐づけ
    - タスクをかんばんで表示
    - タスクをガントチャートで表示

# 構築環境
- OS             : Ubunt 20.04.4 LTS
- Docker         : 20.10.17, build 100c701
- Docker compose : version 1.29.1, build c34c88b2

# プラグイン
以下のプラグインを追加した。（プラグインの詳細については、別にまとめる）
- issue templates
  チケットのテンプレートを作成できるプラグイン
  https://github.com/akiko-pusu/redmine_issue_templates
- absolute dates
  チケットの作成日や更新日の表示を変更するプラグイン
  絶対日付で「YYYY/MM/DD」(例：2020/10/01)のように表示されるようになる
  https://github.com/suer/redmine_absolute_dates
- redmine_issues_panel
  チケットをかんばんで表示
  複数ユーザのチケットを、ユーザごとに分けて表示することができる
  https://github.com/happy-se-life/kanban
- チケットパネル（Redmine Issues Panel)
  チケットをかんばんで表示
  かんがんでひょうじするさいに、チケットに表示できる情報が多い
  https://github.com/redmica/redmine_issues_panel

# テーマ
以下のテーマを追加した。
- farend bleuclair
https://github.com/farend/redmine_theme_farend_bleuclair

# 構築
RedmineはDBを使う。
SQliteでも構築できるらしいけど、RedmineをDockerで構築しているので、DBもついでにDockerで構築してしまう。
コンテナが2つになったので、Docker composeを利用する。

### バージョン選定
- Redmien
最新バージョン(2022/10時点)は、5.0系だったが、利用予定のpluginが4.2系までしか対応していなかったので、4.2を採用した。
- DB
こだわりはなかったので、適当にmysqlの5.7を採用



### フォルダ構成
``` 
redmine 
 ├─ data
 │  └─ db 　　  : redmineのデータを保存する環境
 │  └─ plugins  : redmineで使用するプラグインを保存
 │  │ 　├─ kanban
 │  │ 　├─ redmine_issues_panel
 │  │ 　├─ redmine_issue_checklist
 │  │ 　├─ redmine_issue_templates
 │  │ 　├─ redmine_issues_tree
 │  │ 　└─ redmine_issues_panel
 │  ├─ themes   : redmineの表示テーマを変更する際に、利用テーマを保存
 │  │ 　└─ bleuclair
 │  ├─ files    : 各チケットに添付したファイルや画像データ
 └─ docker-compose.yaml
```

### Docker compse
- Docker composeのバージョンは作成時に最新のバージョンだった3.8を指定。
- mysqlは、デフォルトの文字コードがlatin1になっているそうなので(未確認)、utf-8を指定。これを指定しないと、Redmineのチケットステータスなどで日本語を使用できない。
mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
```
version: '3.8'

services:
  redmine:
    image: redmine:4.2.8
    ports:
      - 8888:3000
    volumes:
      - ./data/files:/usr/src/redmine/files
      - ./data/plugins:/usr/src/redmine/plugins
      - ./data/themes:/usr/src/redmine/public/themes
    environment:
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PASSWORD: example
      REDMINE_SECRET_KEY_BASE: supersecretkey

  db:
    image: mysql:5.7
    volumes:
      - ./data/db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: redmine
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
```

# 起動
``` 
user@server:/home/com/redmine$ docker-compose up -d
```

起動＆ログインできました！
※デフォルトユーザとパスワードはadmin, admin
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404547/56bbdcca-9362-72f1-c1c2-139511403e15.png)

# 参考にしたサイトなど
- https://glodia.jp/blog/11799/ 
- https://redmine.jp/glossary/t/theme/get-themes/

# 追記　2024/07/10
- 「各チケットに添付したファイルや画像データ」が格納されるディレクトリ(/usr/src/redmine/files)が、永続化の対象になっていなかったため、docker-compose.yamlを修正
WindowsからMacに開発環境を移行する

# はじめに
WindowsPCの動作が重かったため、MacPCを購入して開発をすることにした。
新しいMacPCで開発環境を構築するにあたり実施したことを記録する。

# 環境
Windows10からMacbookpro MacOS Catalina 10.15.7に開発環境を変更した。

# 1.TypeScriptの環境構築を行う
以下の記事を参考にTypeScriptの環境構築を行った。
[トラハック github](https://github.com/deatiger/ts-basic-demo)

1.homebrewのインストール
``` 
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
2.nodebrewのインストール
```
brew install nodebrew


/usr/local/opt/nodebrew/bin/nodebrew setup_dirs

echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```

3.nodeの安定バージョンをインストール
```
nodebrew install stable
```
4.nodebrewのバージョン一覧を確認
```
nodebrew ls
```

5.インストールしたバージョンを指定して切り替える
```
nodebrew use v18.10.0
```
6.nodeのパスを通す
```
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
```
7.ターミナルの再起動
8.nodeとnpmのバージョン確認
```
node -v
npm -v
```

# 2.GoとVScodeをインストール
1.以下のサイトに従ってGoとVSCodeをダウンロード
[Go 開発用に Visual Studio Code を構成する](https://learn.microsoft.com/ja-jp/azure/developer/go/configure-visual-studio-code)
2.VSCodeダウンロード後、VSCodeのGo拡張機能を設定

# Dockerのインストール
以下のサイトでインストール、私のmacはintelチップだったのでintel
チップ版をダウンロード。
[Mac に Docker デスクトップをインストールする](https://docs.docker.com/desktop/install/mac-install/)

# gitを設定する
1.gitはmacにインストールされていたので、以下のサイトの「3.gitの初期設定」から実施
[【Mac】Gitの環境構築をしよう！](https://prog-8.com/docs/git-env)
「4. GitHubの設定」はアカウントを作成ずみだったので飛ばし、SSH Keyを作成した。
GitHub アカウントへSSHキーを追加したのち、既存のリモートリポジトリからリポジトリをクローンした。
[【Git入門】git cloneで既存リポジトリをクローンしよう！](https://tech-blog.rakus.co.jp/entry/20220624/git#git-clone%E3%81%A3%E3%81%A6)

既存のリポジトリをクローンしたのち、動作確認のため新規にブランチを生成した

# VSCodeに拡張機能を追加
ESLint,Prettierをインストール

# 動作確認
WindowsからMacに移行したため、前回と同様に動作するか確認した。
1.フロントの確認
```npm upgrade ```を実施してnodeのパッケージをインストール。
```npm run dev```を実施、開発途中のアプリケーションが起動することを確認。

2.バックエンドの確認
docker起動する確認
```docker-compose build```
```docker-compose up -d```

# 感想
Dockerの便利さを認識した。
Dockerfileを作成すれば新しいPCにも即座に環境を構築してアプリケーションを起動させることができる。
EC2のENA とは

## 勉強前イメージ

HVM調べてたときにふと目に入った項目
全然知らん

## 調査

### ENA とは

Elastic Network Adapter の略で、旧世代とは仕様が変更された新しいタイプのネットワークアダプターになります。
元々は大きなインスタンスタイプでも通信の帯域幅が最大10Gbpsだったものが
ENAによって最大20Gbpsまでサポートされるようになりました。
AWSの基本的なAMIではすでに有効化されているようです。

イメージとしては以下の図です。

![1EC2のENA とは - diagrams.net - Google Chrome 2022-10-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/25d6983a-8952-5d4f-2cca-afe042f93345.png)



以下はEC2作るときにデフォルトで選択されているamazon linux2のAMIになります。
`ENA 有効: はい` と記載されていることからamazon linux2を新規に作る場合は
ENAのサポートが有効になっています。

![5インスタンスを起動 _ EC2 Management Console - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/0c0ccd9b-0de9-0d9e-1f05-e48a2d37f66e.png)


モジュールが含まれているAMIから構築する場合は特に問題はなくそのまま作成できますが、
拡張ネットワーキングに対応していないインスタンスタイプに変更する場合は拡張ネットワーキングを有効にする必要があります。
インスタンスタイプを変更する際に躓くことがあるので、気をつけないといけません。


## 勉強後イメージ

確かに記事見てたらインスタンスタイプ変更するときに
ENA有効じゃないよって言われているの見た。
新規で作る場合はあまり気にしなくていいけど、インスタンスタイプ変更するときは気をつけないと！

## 参考

- [進化する AWS ｜ 新世代 EC2 インスタンスへのタイプ変更](https://aws.taf-jp.com/blog/77207)
- [AWS EC2 インスタンスタイプの変更でハマりました。ENAってなんだ？？](https://hit.hateblo.jp/entry/aws/ENA)
Salesforce開発に参加した方が「え？」と戸惑うこと

## はじめに

これまで自分よりSalesforce経験が短い方のサポートを4名行ってきました。

皆さんが戸惑うSalesforceのポイントが共通しているなあと思ったので、それを記事にしてキャッチアップの一助になればいいかなと記事にしました。

噛み砕いた用語解説＋αくらいの内容になっています。

## サンドボックス

開発環境のこと。ローカルではなく、Salesforceのクラウド上に構築される。  

サンドボックス同士での干渉は起こらず、独立した環境として開発に集中できる。

容量・本番環境の再現具合ごとに、[いくつか種類](https://qiita.com/xQIEBo4zFWKZ0ig/items/ea9a3c2bf7fdac5d38b1)がある。

## DB

SalesforceではDB関連の用語が以下のようになっている。

- テーブル -> オブジェクト

- カラム -> 項目

オブジェクトには主に以下の2種類がある。

- 標準オブジェクト：Salesforceに初めから存在するオブジェクト

- カスタムオブジェクト：自分で追加したオブジェクト。オブジェクト名の末尾に__cと付く

## ガバナ制限

リソース制限のこと。制限を超えるとエラーが起きて例外が発生する。

クエリの発行回数・実行時間・ヒープサイズなど、制限の種類は様々。（[ガバナ制限の種類](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apexgov.htm)）

回避方法は[こちら](https://qiita.com/xQIEBo4zFWKZ0ig/items/544273a00de7e1d0ddfc)にまとめてあります。

## 数式項目

項目にロジックをもたせたもの。

保存した値を少し加工したい時などに便利。

例）

- 項目A：メアドが保存されるテキスト項目

- 項目B（**数式項目**）：項目Aのメアドのうち、@以降（＝ドメイン）だけを切り取ったテキストが自動で入る

## DBのリレーション

よく使うのは以下のリレーション。

- 主従関係

	- 強いリレーション

	- 以下のようなことができる

		- カスケード削除（親レコードが削除されたら子レコードも消える）

		- 紐づく子レコード数の集計結果を、親レコードの項目に保存する

- 参照関係

	- 弱いリレーション

    	- 「主従関係」のようなカスケード削除や子レコードの集計などはできない

	- ただリレーションが欲しいだけならこちらを使う

    	- 主従関係は設定できる数に限りがあったり、カスケード削除など考慮事項も増えるので

## カスタム表示ラベル

管理画面からグローバル定数を作れる機能。

定数の値は文字列になる。

以前はHTMLタグなどを埋め込めたが、今はできない。

例）  
  以下のラベルを登録。
  - 名前：TEST_LABEL  
  - 値：テストラベル  
  
  以下のように書くと、testLabelに「テストラベル」が代入される。
  - ```String testLabel = System.Label. TEST_LABEL```

### カスタム表示ラベルの追加方法

- 管理画面から追加する方法

	- 設定→カスタム表示ラベルから追加

- コードから追加する方法

	- ```force-app/main/default/labels/CustomLabels.labels-meta.xml```に追加

## カスタム設定

カスタム表示ラベルより高度なグローバル定数を作れる方法。

コレクションの形式にしたり、オブジェクトの形式にしたりできる。

以下のメリットがある

- 管理画面上から変更できるので、プログラムのリリースが不要

- セレクトしてもSOQL発行数にはカウントされず、ガバナ制限を回避できる

## トリガ

レコードの保存・削除があった時に、自動で動く処理を定義するファイル。

他のコントローラと同じくApexで記述する。

例）
商品オブジェクトのレコードが新規保存されたときは、対応する在庫オブジェクトのレコードも自動で作成・保存する。

<br>
<br>

パッと見使い勝手がよく、保存時のルールを強要できるので、レコードの一貫性も保てる。

**ただ以下の特性もあるので、注意は必要**

- 運用していくうちに「この画面の時はトリガを動かしたくない」みたいな要件が出てきて、どんどん複雑になっていく

    - トリガに任せることが増えてきて、責務が重くなりすぎる

- 実際に動くプログラムと、トリガのプログラムが分離されているのでコードが読みづらい

	- 保存処理が書かれているのが画面でも、その後動くトリガを探して、関係性に注意しながら直さなくてはいけない
データをフィッティングする分布の選択

# 問題設定
与えられたデータがあり, そのデータが従う確率分布としてどのようなものが適切か知りたい状況を想定する. 

# 今回用いる方法
手当たり次第分布を持ってきて, パラメータのフィッティングを行う. フィッティングして得られた最適な分布とデータの経験分布を比べ, コルモゴロフ-スミルノフ検定(KS test)を行う. 

# 使用環境
Python 3.10
Numpy 1.22
Scipy 1.9

# コード例
```python
import numpy as np
import pandas as pd
from scipy import stats

def compare_distribution(data: np.ndarray):
    result = []
    all_dists = [d for d in dir(stats) if isinstance(getattr(stats, d), stats.rv_continuous)]
    for dist in all_dists:
        dist_object = getattr(stats, dist)
        try:
            param = dist_object.fit(data)
            param_, loc, scale = param[:-2], param[-2], param[-1]
            if not param:
                D, p = stats.kstest(data, dist_object.cdf, args=(param_, loc, scale))
            else:
                D, p = stats.kstest(data, dist_object.cdf, args=(loc, scale))
        except:
            param, D, p = np.nan, np.nan, np.nan
            pass
        
        result.append({'distribution': dist,
                       'D': D,
                       'p': p,
                       'param': param
                      })
    return pd.DataFrame.from_records(result)

df = compare_distribution(data)

display(df)
```

# あとがき
持ってきた分布の中に, 適切な分布が存在しない場合も当然ありうることに注意する. データ解析をやるときに頻繁にデータが従う分布候補の特定を行うので, 関数化しておくと便利そうだ. 

# 参考資料
https://docs.scipy.org/doc/scipy/tutorial/stats.html
useStateを調べたら、Reactのレンダリングもついでに分かったよって話

ここ最近Reactに入門してみて、`useState`に遭遇して、「何それ」ってなったので今回はそれを解説してきます。
※タイトルがよくないかもしれませんが、
あくまでこの記事は、`useState`についてまとめた記事であることをご了承ください。

## useStateとは何か？
結論から言うと、**useState()は関数コンポーネントでstateを管理するための機能**です。
ただ、これだけだと全くわからないと思うので詳しく解説していきます。

`useState`を理解するためには以下の２つのことを理解する必要があります。
1\. `state`とは何か？
2\. `React`におけるレンダリングとは何か？
### 1\. Stateとは何か？
`State`とは値が変わると再レンダリングが発生する変数のことをいいます。
文章だけ見てもよくわからないと思うので例を見ていきます。
`state`を使えるようにするには、まず`useState`をインポートすれば使えるようになります。
使い方は他の記事などを参考にしていただけると幸いです。
```
import React, { useState } from 'react';

export default function CountNumber() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}回クリックしましたよ！</p>
      <button onClick={() => setCount(count + 1)}>
        ここをクリックしてください
      </button>
    </div>
  );
}
```
実際に画面を見てみましょう。
![画面収録.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/e0087ab8-4cf0-05e4-039f-15fec375e6a5.gif)

この例のように、0から１に値が変更されたとき、レンダリングが行われる変数のことをいいます。
次の章で、`React`におけるレンダリングについて詳しくみていきます。
### 2\.レンダリングとは何か？
よくレンダリングというと、ブラウザに画面を表示することを指すことが多いです。
詳しくは、以下の記事に詳しく書かれていますので、そちらを参照ください

https://zenn.dev/oreo2990/articles/280d39a45c203e

しかしながら、`React`におけるレンダリングは、ブラウザに表示するレンダリングとは意味が違います。
実際に、[公式ドキュメント(Beta版)](https://beta.reactjs.org/learn/render-and-commit#epilogue-browser-paint)では言葉の意味を分けるために、`React`におけるレンダリングはレンダリングと表現し、ブラウザにページを表示することを**ペイント**と言葉を分けています。

[公式ドキュメント](https://beta.reactjs.org/learn/render-and-commit#step-2-react-renders-your-components)を読むと、
**レンダリングとはReactがコンポーネントを呼び出すこと**と書いてあります。

>“Rendering” is React calling your components.
[公式ドキュメント](https://beta.reactjs.org/learn/render-and-commit#step-2-react-renders-your-components)

つまり、`React`におけるレンダリングという言葉の意味には、画面に何らかを表示させるだけじゃなく、コンポーネントを呼び出して値を更新していくことも言葉の意味に含まれているんです。

どのようなプロセスを経てコンポーネントが呼び出される（レンダリング）のかというと、
1\.トリガーをレンダーする
2\.コンポーネントをレンダーする
3\.DOMにコミットする

マジで意味不明だと思いますが、１つ１つ解説していくので安心してくださいね！
#### 1\.トリガーをレンダーする
トリガーと言う言葉には、「引き金」という意味があります。つまり原因ですね。
トリガーは2種類あります。
1つ目は初期レンダリング。要はアプリケーションを起動したときです。
2つ目は画面更新時に発生する再レンダリングです。`state`が変更されたときなどですね。

つまり、この２つの時にトリガーが発生するということです。

#### 2\.コンポーネントをレンダーする
１つ目でみた、初期レンダリング、もしくは画面更新時に発生する再レンダリングがありましたね。
この２つのうちどれかが発生した時に、Reactはコンポーネントを呼び出して、画面に何を表示するかを決定します。

レンダリングする際には、更新する前と後の差分を見つけています。

#### 3\.DOMにコミットする
先程の2での変更部分や、初期レンダリングを経て画面に表示させています。

## まとめ
`useState`とは関数コンポーネントで`state`を管理するための機能であるということ。
そして`state`とは値が変わると再レンダリングが発生する変数のことをいい、レンダリングとは、コンポーネントを呼び出すことだということがわかりました。



【参考資料】

https://www.geeksforgeeks.org/reactjs-state-react/

https://ja.reactjs.org/docs/hooks-intro.html

https://beta.reactjs.org/learn/render-and-commit

https://zenn.dev/1129_tametame/articles/bf4fc2005bea4d
HVM とは(PVも調べてみた)

## 勉強前イメージ

なんかふわっと聞いたことある気もしなくもないレベル・・・・

## 調査

### HVM とは

Hardware-assited VM の略で、仮想化方式での完全仮想化の意味です。
以下の画像はEC2のインスタンス構築の画面ですが
ここでもamazon linux2のAMIには `仮想化:hvm` と書かれています。
また、HVMは現行のインスタンスタイプにサポートされています。

![3インスタンスを起動 _ EC2 Management Console - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3d33ea8b-f289-e34a-6863-52db4c7c7d2a.png)

必要なアーキテクチャをすべてエミュレートしてくれるのでそのまま動作します。
HVMは自分がゲストOSだと思ってないので、物理マシンにOSとインストールするときと同様、ブートローダーからカーネルを起動します。
なので、 [GPT](https://qiita.com/miyuki_samitani/items/eb4fcf431f4846b8946f) or MBRとブートローダーが必要です。
また、ホスト上のハードウェアへの高速なアクセスをするためのハードウェア拡張が利用可能です。

HVMはAMIの仮想化方式の一つの選択肢になります。

### 他にもAMIの仮想化方式の種類がある？

他にもAMIの仮想化方式の種類があり、 `PV` というものが存在します。
paravirtualの略で準仮想化の意味になります。

実際にEC2を確認すると以下のように `仮想化: paravirtual` と記載されています。

![4インスタンスを起動 _ EC2 Management Console - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8a67f2f5-777b-5614-7f39-dfc7c8376a6e.png)

PVはEC2のサービス当初から提供されている仮想方式になります。
準仮想化は完全仮想化よりもオーバーヘッドが少ない方式で
元々はHVMより速かったですが、今は優位性はないようです。
PVはハードウェアの仮想化を行っているのでハードウェアの拡張はできないです。

### まとめ

- HVM : 完全仮想化
	- 最近主流？
	- 拡張性がある
- PV : 準仮想化
	- サービス当初から提供されている
	- オーバーヘッドが少ない

## 勉強後イメージ

完全に理解したまではいってないけど、雰囲気分かった。
仮想化の方式までもいろいろあるのね

## 参考

- [仮想化方式(HVM と PV)についてまとめ](https://kanny.hateblo.jp/entry/2014/01/19/182759)
- [EC2の仮想化方式についてのおぼえがき](https://blog.kasei-san.com/entry/2018/01/10/003933)
- [メモ: AMIの仮想化方式 hvm、paravirtualについて](https://torazuka.hatenablog.com/entry/20110517/ami)
[Gerrit] Change-Idがなくてpushできない時の対処法

Gerritを使っていて、コミットメッセージの末尾（フッター）にChange-Idがなく
git push に失敗することがあったので、その対処法です。
動作確認環境は、Windows11、git 2.38.0、gerrit 3.6.2 です。


# push時のエラー内容
```
$ git push origin HEAD:refs/for/master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Writing objects: 100% (3/3), 281 bytes | 281.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Processing changes: refs: 1, done
remote: ERROR: commit 91240a8: missing Change-Id in message footer
remote:
remote: Hint: to automatically insert a Change-Id, install the hook:
remote:   gitdir=$(git rev-parse --git-dir); scp -p -P 29418 admin@localhost:hooks/commit-msg ${gitdir}/hooks/
remote: or, for http(s):
remote:   f="$(git rev-parse --git-dir)/hooks/commit-msg"; curl -o "$f" http://localhost/tools/hooks/commit-msg ; chmod +x "$f"
remote: and then amend the commit:
remote:   git commit --amend --no-edit
remote: Finally, push your changes again
remote:
To ssh://localhost:29418/test
 ! [remote rejected] HEAD -> refs/for/master (commit 91240a8: missing Change-Id in message footer)
error: failed to push some refs to 'ssh://localhost:29418/test'
```

# 手順1: .git/hooks ディレクトリに commit-msg ファイルを配置する 

エラーのHintに記載の通り、Change-Idをコミット時に自動挿入するためのcommit-msgファイルを取得します。
ユーザ名やホストはご自身の環境に合わせて変えてください。（エラー文のコマンドをコピペでOKです。）

```
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 admin@localhost:hooks/commit-msg ${gitdir}/hooks/
```

#### 失敗する場合
以下エラーで失敗する場合は、scpコマンドに -O オプションをつけると成功します。
```:失敗
$ gitdir=$(git rev-parse --git-dir); scp -p -P 29418 admin@localhost:hooks/commit-msg ${gitdir}/hooks/
subsystem request failed on channel 0
scp: Connection closed
```
```:成功
$ gitdir=$(git rev-parse --git-dir); scp -O -p -P 29418 admin@localhost:hooks/commit-msg ${gitdir}/hooks/
commit-msg                                    100% 2272   765.5KB/s   00:00

```
gitのとあるバージョンあたりから -O オプションをつけないと失敗するようになった気がします。
-O が必要な理由は詳細見れてないですが、こちらの[ページ](https://bugreports.qt.io/browse/QTQAINFRA-4974?focusedCommentId=660149&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel)を参考にしました。

# 手順2: git commit --amendでコミットを修正する
こちらもエラーのHintに記載の通り、以下コマンドを実行してコミットを修正します。
--amend オプションで直前のコミットの修正、--no-edit オプションでコミットメッセージの変更なしです。
```
git commit --amend --no-edit
```

以上です。git logを確認すると、コミットメッセージの末尾にChange-Idが付与されているので、再度pushを行ってください。

# どうしてもcommit-msgが落とせない場合

手順1のcommit-msgがどうしても落とせない場合は、git commit --amend でコミットメッセージにChange-Idを
直接書いてあげる方法があります。既にgerritにアップされたコミットがあれば、
そのChange-Idをコピーして一部書き換えてあげるとよいです。
本来はSHA1で自動で作られるハッシュ値なので、手動で付与するのはあくまで暫定対応ですが。

```:コミットメッセージ修正前
これはコミットメッセージです。
```
```:コミットメッセージ修正後
これはコミットメッセージです。

Change-Id: Ic721d7c5cb44d18b70acb65ae8fb3dfae95f9264
```

ちなみにChange-Idはリポジトリ・ブランチ内で一意であればよいので、ほぼ被ることはないかと思います。
> Note that a Change-Id is not necessarily unique within a Gerrit instance. It can be reused among different repositories or branches

> Change-Id は、Gerrit インスタンス内で必ずしも一意であるとは限らないことに注意してください。異なるリポジトリまたはブランチ間で再利用できます

https://gerrit-review.googlesource.com/Documentation/user-changeid.html
HTMLでプルダウンの選択フォームの作り方

# プルダウンでの選択で必要な要素
<dl>
<dt>select要素</dt>
<dd>選択式のプルダウンメニューを作る要素</dd>
<dt>option要素</dt>
<dd>select要素で囲われたoption要素は１つ１つの選択項目になる</dd>
</dl>

# ものすごく簡単なプルダウンの例
```html
<select>
  <option>リンゴ</option>
  <option>ゴリラ</option>
  <option>ラッパ</option>
  <option>パセリ</option>
</select>
```
これで、リンゴ〜パセリの４つの選択肢のあるプルダウンができる。

# 関連して覚えたい要素、属性
<dl>
<dt>label要素</dt>
<dd>この選択フォームがどんな目的のフォームなのかタイトルをつける要素</dd>
<dt>selected属性</dt>
<dd>option要素にこの属性を付けると、最初にその選択肢が選択されて表示される</dd>
</dl>
Jetson Nano用に、Google Colab上でYOLOv5 v6.0を用いて学習させる

## 最新版をご覧ください。
https://qiita.com/ez_tera/items/e62987c66113c2e9d85e

## はじめに
2022/8/17にYOLOv5 v6.2がリリースされました。
Google Colab上でYOLOv5 v6.2を用いて学習させたウェイトファイルを、Jetson Nano上のYOLOv5 v6.0で用いると以下のエラーが出てしまいます。
そこで、Google Colabのtorchとtorchvisionをダウングレードし、v6.0で学習させることにしました。

```
AttributeError: Can't get attribute 'DetectionModel' on <module 'models.yolo' from '/home/xxx/yolov5/models/yolo.py'>
```

https://qiita.com/ez_tera/items/56a7f97c5d98dd914fd9

## Google Colab上でYOLOv5 v6.0を用いて学習させる
### Google ドライブをマウントします
```
from google.colab import drive
drive.mount('/content/drive')
```

### YOLOv5用のディレクトリを作成します
```
%cd /content/drive/My Drive/
%mkdir ultralytics_v60
%cd ultralytics_v60
```
### YOLOv5 v6.0をクローンします
```
!git clone -b v6.0  https://github.com/ultralytics/yolov5
%cd yolov5
```

### Google ドライブからアプリ(Text Editor)を用いて yolov5/requiments.txtを編集します
```
torch==1.7.0
torchvision==0.8.1
```

### 必要なモジュールをインストールします
```
!pip install -r requirements.txt

Successfully uninstalled torch-1.12.1+cu113
Successfully uninstalled torchvision-0.13.1+cu113
Successfully installed dataclasses-0.6 thop-0.1.1.post2209072238 torch-1.7.0 torchvision-0.8.1
```

### YOLOv5の動作確認をします
```
!python detect.py
```

### yolov5/data内にtrain、validフォルダとdata.yamlをアップロードし、学習を行います
```
!python train.py --img 640 --batch 8 --epochs 300 --data ./data.yaml --cfg ./models/yolov5s.yaml --weights ''
```

:::note info
学習結果がyolov5/runs/train/exp/weights内に保存されます。
:::
raspbian stretchの作法

# 概要
raspbian stretchの作法を調べてみた。

# 電源を繋ぎたい。

- usb電源を繋ぐ。容量は２A

# マウス、キーボードを繋ぎたい。

- usbに繋ぐ。

# LCDディスプレイを繋ぎたい。

- hdmi-rgbの変換器を使う。

# ネットに繋ぎたい。

- ethernetケーブルを繋ぐ。

# ヴァージョンが知りたい。

- uname -a

# ターミナルを起動したい。

- メニューからターミナルをクリック。

# エディタを使いたい。

- メニューからメモ帳、クリック。


# ファイルエクスプローラーを使いたい。

- メニューからファイルをクリック。

# 画面をコピーしたい。

- scrot -d 3

# 画像が見たい。

- ファイルをダブルクリック

# webサーバーを使いたい。

- aptitude install apache2

# 音を録音したい。

- usbにマイクとスピーカー繋いで　rec

# 音を再生したい。

- aplay

# guiなgrepが使いたい。

- aptitude install regexxer

# webが見たい。

- Chromiumをクリック。

# 時間を合わせたい。

- date --set='2022/10/10 13:15:30'

# 日本語入力したい。

- aptitude install ibus-mozc

# IPアドレスが知りたい。

- ifconfig

# raspi-configがやりたい。

- sudo raspi-config

# node-redを使いたい。

- sudo systemctl enable nodered.service

# usbの接続を見たい。

- lsusb

# パッケージを検索したい。

- aptitude search pekepeke

# nslookupしたい。

- sudo aptitude install dnsutils



# 以上。
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その048

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
ワークフローと自動化の学習

にある練習問題4問目をご紹介します

なお今回の内容は動画でも紹介されています

https://www.youtube.com/watch?v=BfpJsEAaFCM

<iframe width="560" height="315" src="https://www.youtube.com/embed/BfpJsEAaFCM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/study-up-on-security-and-access?trail_id=administrator-certification-prep

今回の内容はこちらです

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1f4b4ffb-a46d-9418-89e8-a414bb30dc42.png)


ワークフロールールは1つのオブジェクトに１つのルール作成が必要です

今回はケースオブジェクトと商談オブジェクトでのメール送信なので２つのワークフロールールが必要でした

（なのでAは間違いですね）


なお、１つのワークフロールールは新規作成および更新の対応が可能です
４０代おっさんPythonを勉強する（データ構造と組み込み関数）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## データ構造と組み込み関数

### strの関数format

- format関数の基本的な構造：'文字列{}'.format(引数)
- 引数の場所を指定しないとき順番で代入するが、場所指定があれば、指定した順番で代入する
- 文字列に変数の値を埋め込む
- 変数がリストやタプル、シーケンス型の場合は、{0[0]}を使って何番目かの要素を指定できる
- {0[0]}であれば、0番目の引数の0番目の要素を表す

```python
fruit1 = ('みかん', 80)
fruit2 = ('バナナ', 50)
fruit3 = ('リンゴ', 100)
str3 = '{0[0]}一つ{0[1]}円と{1[0]}一つ{1[1]}円、合わせて{2}円。'

total1 = str3.format(fruit2, fruit1, fruit2[1]+ fruit1[1])
print(total1)

total2 = str3.format(fruit2, fruit3, fruit2[1]+ fruit3[1])
print(total2)
```

- 数値表現
  - 整数を10進数以外にも2、6進数などで表すこともできる
 
|型名|説明|
|----|-----|
|b|2進数で出力|
|d|10進数で出力|
|o|8進数で出力|
|x|16進数で出力|
|X|16進数で出力|
|f|固定小数点で出力|

```python
decimal = 111
print('{0}は　2進数<>{0:b}、8進数<>{0:o}、16進数<>{0:X}、固定小数点<>{0:f}'.format(decimal))
```

- 浮動小数点数型に固定小数点の後の制度がいくつを見せるか指定できる
- デフォルトは小数点後６つ

```python
pi = 3.1415926535
print(f'pi = {pi:f}')
print(f'pi = {pi:.3f}')
print(f'pi = {pi:.8f}')
```

### split & join関数

- split関数では文字列を単語ごとに分けてリストを返す
- 分けられる文字はwhitespaceセットを使う(スペース、タブ、改行)

```python
str1 = '私は 利樹が 大好きです \n' # スペースで分けている
print(str1.split())
```

- 区切り文字を指定する

```python
str1 = '私は、利樹が、大好きです' # (、)で分けている
print(str1.split('、'))
```

- join関数ではリストの要素を結合する
- つなげる文字列はjoinを呼び出した文字列を使う

```python
namelist = ['としき', 'あっきー', 'たろう']
print(''.join(namelist))
print('大好き'.join(namelist))
```

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
クラスとインスタンスについて

この記事では、自分が学習した用の備忘録として記事にしました。
初学者の知識整理の助けに少しでもなれば幸いです。

# クラスとは
設計図。オブジェクトの属性や振る舞いを定義したもの

# インスタンスとは
クラス(設計図)から作り上げた実体

### 実際のコード
```ruby:class.rb
class Italian
    attr_accessor :name
    attr_accessor :price
end

#インスタンスの生成
Italian1 = Italian.new
#インスタンス変数に値を代入する
Italian1.name = "ピザ"
Italian1.price = 1000
```
このコードで説明をすると、
「Italian」というクラスから、
「ピザ」というインスタンスを作成しました。
例えばですが、「Italian」というクラスから、「パスタ」や「フォカッチャ」などのインスタンスも作れます。

**クラスをもとにインスタンスを作成**
これが、クラスとインスタンスの関係性になります。

# 最後に
とても簡単にですが、さくっとクラスとインスタンスについて説明をしてみました。
学習の過程で、クラスとインスタンスという言葉は頻繁に出てくると思います。
最初は、混乱する部分があると思いますが、何か具体例と一緒に考えると記憶に残りやすいと思います。

ご指摘事項がありましたら、ご連絡ください。
Windows × Makefile × pandoc ： openBinaryFile: invalid argument (Invalid argument)

Markdown で記載した設計書を納品用に pandoc で PDF 化する案件がありました。
Markdown ファイルは内容に応じて複数に分けて作成しています。
この複数のファイルを PDF 化するコマンドを Makefile に記載していましたが、Makefile をWindows 10 で実行したところ、エラーになりました。

```powershell
PS C:¥docs> make
pandoc src/*.md --resource-path src --pdf-engine=lualatex -F pandoc-crossref -t pdf -f markdown -o doc.pdf
pandoc: docs/*.md: openBinaryFile: invalid argument (Invalid argument)
make: *** [doc.pdf] Error 1
```

エラー発生原因は以下の記載にあります。

```
pandoc src/*.md ...
```

Unix だと `*`（アスタリスク）で `src/` ディレクトリ以下にある全ての md ファイルを取得してくれるのですが、Windows だとこれが効かない模様。
以下のように `wildcard` 関数を使うことで、エラーが解消しました。

```
pandoc $(wildcard src/*.md) ...
```
WordPress Certified by Bitnami and AutomatticでSiteGuard WP Pluginを入れたけどログインできなくなった際の対応

SiteGuard WP Pluginとは？
https://www.jp-secure.com/siteguard_wp_plugin/


不正ログインなどの防止のためにSiteGuard WP Pluginを入れて管理画面のURLを作成したが、
EIPでIPを固定しておらず　EC2の停止→起動を行ないIPが変更されたため、ログインできなくなった時の対処方。

方法
サーバーにSSHを行い、siteguardを検索。siteguardを_siteguardなどにリネームして無効化する。

(例)
```
root@XXX-XXX-XXX-XXX:~# find / -name siteguard
/bitnami/wordpress/wp-content/plugins/siteguard
root@XXX-XXX-XXX-XXX:~# cd /bitnami/wordpress/wp-content/plugins/
root@XXX-XXX-XXX-XXX:/bitnami/wordpress/wp-content/plugins# mv siteguard _siteguard
```
ブラウザからカメラを起動しようとするとWebcam Errorが発生する

# 初めに
Unity WebGLのARWTプロジェクト(AR.jsのラッパー？)をビルド後に公開するとカメラ関連のエラーが発生したため、対処方法を記録します。

https://github.com/ToughNutToCrack/ARWT

# エラー内容

アプリ起動後に以下のエラーが発生し、カメラが起動しない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/4abdf51c-5b06-1926-27c2-17876f42a0b0.png)

# 原因
httpサーバーで公開していたことが原因でした。

# 対処方法
WebCameraはhttps接続時のみ利用できるため、httpsサーバーで公開すると問題なくカメラを起動できました。
Perlのサブルーチン  - Perlテキスト処理プログラミング入門

Perlのサブルーチンを解説しました。

https://www.youtube.com/watch?v=j0j-siENxtI

サブルーチンとは
引数と戻り値
戻り値とコンテキスト
Perlのサブルーチンの癖
wantarrayについて
配列、ハッシュを引数に渡す方法

Perlのサブルーチン - Perlゼミ

https://perlzemi.com/blog/20101130129876.html

■Perlプログラミングちゃんねるとは

Perlプログラミングちゃんねるは、初級者向けのPerlテキスト処理プログラミング入門です。テキスト処理プログラミングを覚えると文章の中に含まれる文字を簡単に検索・置換できるようになります。対応OSは、Windows/Mac/Linuxです。

テキスト処理プログラミングは、一番簡単なプログラミングの分野のひとつです。プログラミングが初めての方でも大丈夫。テキスト処理は、あらゆる分野に登場するので、実用性も高いです。

Perlのダウンロードとインストールからはじめて、Perlの基本的なプログラミングが書けるようになります。Perlゼミの無料オンラインテキストも活用できます。わからないことがあれば、Perlクラブフォーラムで、質問することができます。

木本裕紀のプロフィール

Perlゼミを運営しているPerlクラブ代表の木本です。次世代プログラミング言語SPVMの作者。CPANモジュール、Giblog、DBIx::Customの作者。Youtube「Perlプログラミングちゃんねる」。YAPC::Kansai 2017 OSAKA ゲストスピーカー。技術評論社「業務に役立つPerl」著者。
語彙力こそが教養である

https://www.amazon.co.jp/%E8%AA%9E%E5%BD%99%E5%8A%9B%E3%81%93%E3%81%9D%E3%81%8C%E6%95%99%E9%A4%8A%E3%81%A7%E3%81%82%E3%82%8B-%E8%A7%92%E5%B7%9D%E6%96%B0%E6%9B%B8-%E9%BD%8B%E8%97%A4-%E5%AD%9D/dp/4040820126/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E8%AA%9E%E5%BD%99%E5%8A%9B%E3%81%93%E3%81%9D%E3%81%8C%E6%95%99%E9%A4%8A%E3%81%A7%E3%81%82%E3%82%8B&qid=1665265691&qu=eyJxc2MiOiIxLjgxIiwicXNhIjoiMS41OCIsInFzcCI6IjEuNjMifQ%3D%3D&sr=8-1


背景
文脈力の本を読んでいたときに、語彙力も合わせて身につけることでより文章を輝かせることができると目にし、読むことにしました。
文脈力の本は齋藤孝さんの本を読んでいたので、同著でこちらに決めました。

本書のテーマ
語彙力を豊かにし、ビジネスでもプライベートでも一目置かれる存在になる。適切な場面で適切な言葉を使える人になること。

個人的なポイント
１，無条件にあなたの評価を高めてくれるのが語彙力
人は少し話せば知的レベルを判断される。教養の深さを見積もられる。その結果、重要な話を貰えないこともある。それをカバーできるのが語彙力。

２,専門用語のインプットは短期間で
IT用語、経営用語、心理学用語など専門用語は２週間で一致にインプットする。それと同時進行でその分野に詳しい人と会話を重ねる。このときに、４〜５回キーワードが出てくればちゃんとインプットできてるということ。

３，語彙へのアンテナを高めるステップ
認識を改める→頼りがちな語彙を見つける→頼りがちな語彙をNGワードとし付箋など貼って封印する→NGワードを別の言葉で言い換える

４，慣用句を使いこなす
レベルC：多くの人が使う慣用句を理解できてない
レベルB：慣用句を知っているけど、使えてない
レベルA：慣用句、四字熟語、独特の言い回しを自由自在に使える
レベルS：その言葉の背景を知ってる、他の慣用句に言い換えられる
本書を通してAを目指す。

５，話す言葉の速さと内容の違いによる印象の違い
語彙が豊富で早口：リーガルハイ的。現代日本に求められてる
語彙は豊富でゆっくり：説法やお別れの挨拶。人を諭すときに用いる
薄っぺらい早口：浅薄な印象。
薄っぺらくてゆっくり：頭の悪い印象

６，練習アウトプット
インプットした言葉を５回繰り返す。なぜ５回なのか。言葉を間違えると嘲笑の対象になったりするが、５回練習するとある程度意味と使い方が感覚でみにつく。それが平均的に５回というだけ。嘲笑されるリスクを鑑みると安いもの。

７，おもしろい話を伝えられないケース
漫才や落語のときなど、その言葉の「意味」だけ捉えているとツッコまれてる理由がわからない。
言葉の背景まで読むから笑いが理解できる。

８，パッションに薪をくべる
こういう知識は「もういいや」となってしまいがち。そうならないように毎日最初の情熱に薪をくべることが大事。

一番心に残ったこと
人の印象は最初の数分のやりとりで決まってしまっているということ。
これは会話だけでなく、メールでのやり取りなど様々なシーンで伝わってしまうのだろうと思いました。
印象を変えるポイントは語彙力だけではないと思いますが、どうやって変えたらいいかわからず、見ないふりをしていた部分でした。

やること
今まで文学を読むということをやってきませんでした。ビジネスに直結していないとあまり見る気になれないからです。
本書を読んで、文学から語彙力をつけ、引用することで相手の印象を変えられると知り、すごく読んでみたくなりました。
また、これらをドラマ、アニメなどにも活かせると思うと、流し見するのではなく、一つずつ目的をもって見ることが語彙力を磨くポイントになると思いました。

インプット→アウトプットを意識して、トレーニングしていくようにします。

まとめ
いままで、資格などの目に見える実績にばかり注力してきました。
資格を取るにはお金もかかるし、会社から見られるのはそういう結果の部分だったので、読書をするというアクションを怠ってきました。
体のいいいいわけです。

読解力などの本を読んで来ましたが、本書はかなり実践が書いてある内容でしたので、「目に見えないスキル」「測りづらいスキル」も育んでい後と思います。
LPC812MAXとI2Cを使い0x80に「hello...」と出力する。(2)(A4,A5)


x mbed2リビジョン144
x リビジョンを変更できる人むけ

目的
I2Cのテスト
ちょっと改良

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり



![o_con873.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/20521854-ea67-3d61-3564-ada8ce5faaaa.jpeg)


![o_con898.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/050dbee5-e5e6-7498-dc37-7a944b71de59.jpeg)




I2C(ADD 0x80)→USART(9600bps)



https://qiita.com/caa45040/items/5032e6905c9425f41495



```c++


//I2C_TEST_STRING_812_2

#include "mbed.h"

DigitalOut myled(LED1); //red

#define ADDR (0x80)  //I2Cのアドレス

//       SDA    SCL
I2C i2c(A4, A5); //812

//10の割り算 0から9999までは、正しい。
#define DIV10(n) (((n*409)+((n*154)>>8))>>12)

char ch_hex_a_b[16];
char *ch_hex_a(int d)
{

    ch_hex_a_b[4] = 0;
    ch_hex_a_b[3] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    d = DIV10(d);
    ch_hex_a_b[2] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    d = DIV10(d);
    ch_hex_a_b[1] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    ch_hex_a_b[0] = '0' +  DIV10(d);                  // '0'+(d/10)

    return(ch_hex_a_b);

}//ch_hex_a

//一文字出力
void pc_putc(char ch)
{

    i2c.write(ADDR, &ch, 1);
    wait_ms(1);//1mS待つ　連続送信防止用　受信落ち対策

}//pc_putc

//文字列の表示 nana_seg
void  pc_puts(char *str1)
{

    //文字の中身がゼロか
    while(*str1) {

        pc_putc( *str1 ++);

    }//while

}//pc_puts

//メインプログラム
int main()
{

    //無限ループ
    while(1) {

        myled = 1;//LEDをオン

        //I2Cに文字列を出力
        pc_puts("hello world\r\n");

        //I2Cに文字列を出力
        pc_puts(ch_hex_a(1234));

        //I2Cに文字列を出力
        pc_puts("\r\n");

        myled = 0;//LEDをオフ

        wait_ms(1000);//1秒待つ

    }//while

}//main




```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8c997030-37ac-3f46-cb88-b69c5cacaab4.jpeg)
Rubyのバージョン変更

```
ys@mbp ~ % rails -v
Rails 7.0.3
ys@mbp ~ % ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
ys@mbp ~ % which ruby
/Users/ys/.rbenv/shims/ruby
ys@mbp ~ % rbenv install -l
2.6.10
2.7.6
3.0.4
3.1.2
jruby-9.3.7.0
mruby-3.1.0
picoruby-3.0.0
rbx-5.0
truffleruby-22.2.0
truffleruby+graalvm-22.2.0

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all / -L' to show all local versions.
ys@mbp ~ % rbenv install 2.7.6
To follow progress, use 'tail -f /var/folders/6x/5qgd746161767rs9g20q5g8w0000gn/T/ruby-build.20221009070553.56692.log' or pass --verbose
Downloading openssl-1.1.1q.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca
Installing openssl-1.1.1q...
patching file test/v3ext.c
Installed openssl-1.1.1q to /Users/ys/.rbenv/versions/2.7.6

Downloading ruby-2.7.6.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.bz2
Installing ruby-2.7.6...
ruby-build: using readline from homebrew
Installed ruby-2.7.6 to /Users/ys/.rbenv/versions/2.7.6

ys@mbp ~ % rbenv versions
  system
  2.6.8
  2.7.6
* 3.0.2 (set by /Users/ys/.rbenv/version)
ys@mbp ~ % rbenv rehash  
ys@mbp ~ % rbenv versions
  system
  2.6.8
  2.7.6
* 3.0.2 (set by /Users/ys/.rbenv/version)
ys@mbp ~ % ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
ys@mbp ~ % rbenv global 2.7.6
ys@mbp ~ % 
```

参考サイト
Rubyのバージョン切り替え方法！（Mac用） | 狼読
https://info-wcn.com/ruby-changeversion-mac/
rbenv rehashをちゃんと理解する
https://mogulla3.tech/articles/2020-12-29-01
【Ruby】MacでRubyのインストール＆バージョンを変更する方法 | くにぽんず☆きちめきパラダイス
https://kunipon.com/3105
C言語忘備録 ~基本構文

# 基本構文
```c
#include <stdio.h>
int main(void){
    printf("HelloWorld");
    return 0;
}
```
文字の出力
printf("~~~~");
計算結果の表示
printf("%d",1+1);
# 数字の入力
```c
#include <stdio.h>
int main(void){
    int number;
    scanf("%d",&number);
    printf("%d",number);
    return 0;
}
```
# 小数扱い方
```c
#include <stdio.h>
int main(void){
    double x;
    x = 9.99;
    printf("%f",x);
}
```
# for文
```c
#include <stdio.h>
int main(void){
  int i;
  for(i=0; i<=5; i++){
      printf("%d\n", i);
  }
}
```
# 多重ループ
```c
#include <stdio.h>
int main(void){
  int i,j,width=7,height=7;
  for(i=1; i<=height; i++){
      for(j=1; j<=width; j++){
          printf("*");
      }
      printf("\n");
  }
}
```
# 配列
```c
#include <stdio.h>
int main(void){
    int i;
    int num[10];
    for(i=0; i<10; i++){
        num[i] = i*2;
        printf("%d\n",num[i]);
    }
    return 0;
}
```
# 関数
```c
```
# 再帰
```c
```
# 文字列の配列
```c
```
# ポインタ
```c
```
# 構造体
```c
```
【Ruby】継承とは | 初学者向け

## はじめに
継承とはどういうことなのか。
僕はRubyを学び始めた頃にあまり理解をしていなかったので、
これからRubyを学ぼうとしている方のために簡単にここに記しておく。

## Rubyでクラスを継承する方法
### そもそも継承とは
そもそもクラスを継承するとは、Google辞書で検索すると`うけつぐこと`と表示される。
まさにその通り、ほかのクラスの内容をうけつぐことを`継承`という、らしい。

### クラスの継承　｜　具体例
``` ruby
class Takeshi
    def super_method
        puts "スーパー！！！！！！！！！！！！！"
    end
end

# Super クラスの機能（メソッド）を Sub クラスで継承（取り込む）する
class Gorira < Takeshi
end

# Super クラスのメソッドが利用できる
p Gorira.new.super_method
# => スーパー！！！！！！！！！！！！！
```
多分こんな感じになります。

これが継承です。以上
リストが連番かどうか判定する（C#）

# はじめに
　本記事はリストが連番かどうかを判定するC#のコードを考えたので私が備忘録的に残した記事です。もしよろしければお読みになった方のお役に立てたら嬉しいです。また、連番の中に欠番がある状態かどうかを判定するコードも書いてみたので[こちら](https://qiita.com/anoiro/items/f1e91ae3d598d11d0c9a)もご参考ください。

追記：
　当初リストがソートされていないと連番だとは言えないという前提で記事を書いていたのですが、いただいたコメントから下記2ケースに分けて書きかえることにしました。ケースに合わせて需要のある方のコードをご参考いただければうれしいです

- Listがソートされている状態で判定したい場合
- Listが未ソートの状態でも判定したい場合

　またリストのサイズが0の時の判定結果はどうするのかという定義が曖昧でしたので、今回は「リストのサイズが0ならば連番だと判定しない」ということにしました。

# Listがソートされている状態で判定したい場合

## 処理内容とソースコード

### 処理内容
　どんな処理手順で判定を行うかというアイデアについて書きます。

1. 判定対象のリストが昇順にソートされているか調べる
1. リスト内で重複した要素を削除したリストの長さと元のリストの長さが等しいか調べる
1. 判定対象のリストの最大値と最小値の差が、判定対象のリストの長さ - 1と等しいか調べる
1. 1.　と2. と3. の真偽値がいずれも真であれば連番だと判定する
1. 上記以外の場合に連番でないと判定する

　下記の方法でも良いかなと思っていたのですが、[こちらの記事]( https://qiita.com/anoiro/items/f1e91ae3d598d11d0c9a)で書いたコードへの拡張性を持たせたかったので上記のアルゴリズムにしてみました。

1. 判定対象の最小値と長さを取得
1. この長さで最小値始まりのリストを新たに生成
1. 新たに生成されたリストと判定対象のリストが等しいか判定する

### ソースコード

```Main.cs
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Main {
    /// <summary>
    /// 指定されたリストが連番かどうかを判定します。
    /// リストのサイズが0だとFalseと判定します。
    /// </summary>
    /// <param name="intList">判定対象のリスト</param>
    /// <returns>連番かどうかの真偽値</returns>
    public bool isSequence (List<int> intList) {
        return intList.Count() > 0
            && intList.OrderBy(element => element).SequenceEqual(intList)
            && intList.Distinct().Count() == intList.Count()
            && intList.Max() == intList.Min() + intList.Count() - 1
        ;
    }
}
```

# Listが未ソートの状態でも判定したい場合

## 処理内容とソースコード

### 処理内容

　よろしければ[こちらのコメント](https://qiita.com/anoiro/items/2502f2e945b8d0616e54#comment-f0b0eedb971ba752a00f)をご参照いただければと思いますが、改めてこの節で想定している処理内容を整理しておきます。

1. 判定対象のリストをHashSet化する（重複要素を省く）
1. 上記のHashSetの最小値から最大値までの要素が、HashSet内が含まれているか逐次確認する
1. 全要素が含まれていれば連番だと判定する
1. 上記以外だと連番だと判定しない

### ソースコード

```Main.cs
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Main {
    /// <summary>
    /// 指定されたリストが連番かどうかを判定します。
    /// リストのサイズが0だとFalseと判定します。
    /// </summary>
    /// <param name="intList">判定対象のリスト</param>
    /// <returns>連番かどうかの真偽値</returns>
    public bool isSequence (List<int> intList) {
        var uniqueList = new HashSet<int>(intList);
        return uniqueList.Count() > 0
            && Enumerable.Range(uniqueList.Min(), uniqueList.Count).All(i => uniqueList.Contains(i));
    }
}
```

# おわりに
　もっとうまい書き方あるかもですがもしよろしかったら何かのお役に立てていただければと思います。ちなみに当方ポーカーのゲームを作っておりましてその運びで連番かどうかを判定するアルゴリズムを考えておりました。
　またコメントくださった@shiracamusさんと@albireoさんほんとにありがとうございました！とても勉強になりました。
リストが連番か（欠番あり）どうか判定する（C#）

# はじめに
　本記事はリストが連番か（欠番あり）どうかを判定するC#のコードを考えたので私が備忘録的に残した記事です。

　たとえばこんなリストであれば連番（欠番あり）だと判定します。
　{1, 2, 4, 5, 6}

　たとえばこんなリストであれば連番（欠番あり）だと判定しません。
　{1, 2, 3, 4, 5}

　もしよろしければお読みになった方のお役に立てたら嬉しいです。もともとは[連番かどうか調べる記事](https://qiita.com/anoiro/items/2502f2e945b8d0616e54)を書いてたのでよかったらこっちもどうぞ。

追記：
　[こちらの記事](https://qiita.com/anoiro/items/2502f2e945b8d0616e54)でいただいたコメントから、リストのサイズが0の時の判定結果はどうするのかという定義が曖昧でしたので、今回は「リストのサイズが0ならば連番だと判定しない」ということにしました。

# 処理内容とソースコード

## 処理内容
　どんな処理手順で判定を行うかというアイデアについて書きます。

1. 判定対象のリストが昇順にソートされているか調べる
1. リスト内で重複した要素を削除したリストの長さと元のリストの長さが等しいか調べる
1. 判定対象のリストの最大値と最小値の差が、判定対象のリストの長さ + 欠番している要素数 - 1と等しいか調べる
1. 1.　と2. と3. の真偽値がいずれも真であれば連番（欠番あり）だと判定する
1. 上記以外の場合に連番（欠番あり）でないと判定する

## ソースコード

```Main.cs
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Main {
    /// <summary>
    /// 指定されたリストが連番か（欠番あり）どうかを判定します。
    /// リストのサイズが0だとFalseと判定します。
    /// </summary>
    /// <param name="intList">判定対象のリスト</param>
    /// <param name="missingCount">欠番している要素数</param>
    /// <returns>連番かどうかの真偽値</returns>
    public static bool isSequentialWithMissingInMid (List<int> intList, int missingCount) {
        return intList.Count() > 0
            && intList.OrderBy(element => element).SequenceEqual(intList)
            && intList.Distinct().Count() == intList.Count()
            && intList.Max() == intList.Min() + intList.Count() + missingCount - 1
        ;
    }
}
```

# おわりに
　ポーカーゲームを作っていた運びで標題の処理を書くに至りました。よかったらお役立てたらと思います。
UMLを使ってクラス図を書く方法

## 目次
- 概要
- そもそもUMLって何？
- UMLでクラス図を書いてみる
- 最後に

## 概要
最近一気に寒くなってきてまだ衣替えしていなく、半袖半ズボンで寝てるので三連休で衣替えしようと思います🥶

さて今回のスキルアップのための不定期30分インプット・アウトプット投稿第三段は、「UMLを使ってクラス図を書く方法」ついてやっていこうと思います！
第二弾は、[Dockerを使ってPHPを実行する方法](https://qiita.com/kitamurakunihiko/items/bf2e9998efceff115a0f)について投稿したのでよければ確認してみてください。

　
## そもそもUMLって何？
wikiだと下記のような定義らしいです。
>ソフトウェア工学で用いられる、汎用的かつ開発方面に特化させたモデリング言語である。
システム設計を視覚的に図式化しての標準化されたモデリング手法の提供を目的にしている。
UML(Unified Modeling Language)の略語で呼ばれることが多い。オブジェクト指向分野でよく用いられている。

ということで噛み砕くと、
**システムの構造や動きを図にしたもので、世界中の人が見てもわかるように決められた書き方**
ということみたいです。

　
## UMLを使ってクラス図を書いてみる
UMLの中でも構造を表すクラス図を書くときのルールをまとめておきます。
ちなみにクラス図を書くツールはいろいろあるようですが、私は[drow.io](https://www.draw.io
)を使って書いていきます。

### 基本的なルール
クラス図は、属性と操作で上下分けて書きます。
PHPでいうと上がプロパティ、下がメソッドで分けられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/ef427c57-ef83-1919-ff6f-fd4122f52085.png)

### アクセス範囲のルール
プロパティやメソッドの前に記号がついていますが、これは```public```や```private```などのアクセス修飾子を表しています。。
| 記号(可視性) | アクセス修飾子 | アクセス範囲 |
| --- | --- | --- |
| + | pablic | 自クラス外からもアクセス可能 |
| - | private | 自クラス内からアクセス可能 |
| # | protected | 自クラスと継承クラスからアクセス可能 |
| _ | static | インスタンス化せずに自クラス外からもアクセス可能 |

### 相互関係の書き方
#### インターフェイスを継承する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/a7db0e42-2224-6ad6-1026-8b8fad97b6ee.png)

### クラスを継承する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/2bab47a1-5fb7-4483-04a4-77c49722103b.png)

### クラスAのインスタンスをクラスBが保持
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/f055bc79-a015-25f7-237b-57b97eb7bd3f.png)

### クラスAがクラスBを生成(クラスAの返り値がクラスB)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/2db1de18-2f51-be6e-443c-e5d3a956180d.png)

　
## 最後に
まだ多重度と呼ばれる関連する数を表現する方法があるみたいですが、30分で調べきれなかったのでまたの機会にします。

クラス図の書き方を調べるにあたって、Javaを例にクラス図の紹介がされている記事は多く見つけましたが、PHPで紹介されている記事が少なく同じPHP初学者の人の助けになれれば嬉しいです。
エイリアスについて

●ネットワークインターフェースには、複数のアドレスを割り当てることができる。基本的に、最初に割り当てたアドレスを「プライマリ」アドレス、追加で割り当てたアドレスを「セカンダリ」アドレスと呼ぶ。3つ目、4つ目と複数設定したアドレスも「セカンダリ」アドレスと呼びます。これは、アドレス設定に順位があるわけではなく、「プライマリ」以外のもの、という意味で「セカンダリ」と呼んでいる。

セカンダリアドレスの設定方法は、使用するコマンドによって異なります。

ifconfig コマンドでは、直接セカンダリアドレスを設定することができません。インターフェースに別名（エイリアス）を付与し、そのインターフェースにアドレスを割り当てることで、セカンダリアドレスを設定。

以下のコマンドは、eth0のエイリアスとしてeth0:0を作成し、セカンダリアドレス 192.168.200.1/24 を設定

ifconfig eth0:0 192.168.200.1/24

この手法は現在では非推奨。かわりに ip コマンドによるアドレス設定が推奨。

ip コマンドによるセカンダリアドレスの設定は、プライマリアドレスの設定と同じコマンドを使います。

ip addr add 192.168.200.1/24 dev eth0


※ipコマンドで設定したセカンダリアドレスは ifconfig では参照できない。


●ifconfig コマンドで参照できるようにするには、ipコマンドでのセカンダリアドレス設定時に、labelオプションを使ってインターフェースのエイリアスを設定。
【AWS】1か月でAWS DASに合格した話

# はじめに
タイトルの通りAWS Certified Data Analytics-Specialty(DAS)に無事合格いたしました！
AWS試験の難易度ってその人が今まで勉強してきた内容や業務で関っているか・いないかでかなり意見が割れると思うのですが、私の場合はデータ分析にかかわる仕事やサービスってほとんど触ったことがなかったので、かなり難しく感じました。
特にKinesis関連が紛らわしくて。。。

この記事ではどんな感じの内容が出るのか、対策方法等をご紹介できればなと思っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/e91222ff-c1c8-00c2-d699-4e3138355a01.png)

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [難易度](#難易度)
1. [学習方法と使用した教材](#学習方法と使用した教材)
1. [頻出サービスと内容](#頻出サービスと内容)
1. [さいごに](#さいごに)


# 難易度
これから受ける方はこの試験がどのくらい難しいのか結構気になると思うのですが、
記事の冒頭でも述べた通り、Kinesisを使った経験・知識がないと結構難しく感じるんじゃないかなと思いました
現時点でSAP on AWSとプラティクショナー以外は取得しているのですが、個人的な難易度は以下の通りです。
(各試験の細かい感想とかについては全制覇後にまとめようと思います。)

1. AWS Certified Solutions Architect - Professional
1. AWS Certified Advanced Networking - Specialty 
1. AWS Certified DevOps Engineer - Professional
1. AWS Certified Data Analytics - Specialty
1. AWS Certified Security - Specialty
1. AWS Certified Machine Learning - Specialty
1. AWS Certified Database - Specialty 
1. AWS Certified SysOps Administrator 
1. AWS Certified Solutions Architect – Associate
1. AWS Certified Developer - Associate




# 学習方法と使用した教材
今回はKoiwaClubの問題集のみで合格できました。
Udemyからも問題集が出ているかと思いますが、その場で答えが確認できないので私はあまり好きではないです。。笑

ちなみに、問題集のみで合格といっても、完全にデータ分析に関わる知識が０だったわけではありません。
難易度のとこでも話した通り、事前知識としてある程度はサービスの概要を理解できていたことが大きかったのかと思います。（完全初学者の方には参考にならず申し訳ないです。。。


# 頻出サービスと内容
この試験では以下のような内容が非常に多く問われます。
* リアルタイムデータ分析
* データ形式の変換
* 可視化
* 費用対効果の向上
* ジョブのパフォーマンス向上
* データレイクへの保存


サービスは以下のようなものが対象になります。
* Amazon Kinesis
    * Data Dtreams
    * Data Firehose
    * Data Analytics
* Amazon Redshift
* AWS Glue
* AWS Athena
* Amazon QuickSight
* Amazon Elasticsearch Service
    *  Kibana
* Amazon S3
* Amazon DynamoDB
* AWS Lake Formation

特にKinesisに関するところでは、どのサービスを使ってデータを転送するのか、分析するのか、それぞれのサービスがサポートしているサービスは何かというところを集中的に身に着けたほうがいいです。

可視化についてはAmazon Elasticsearch Service とKibanaを使うのがいいのか、AthenaとQuickSightを使うのがいいのか
どう言った場合にこのサービスを選べばいいのかしっかり理解しておく必要があります。

# さいごに
Specialtyの資格も残すところあと１つ　SAP on AWSのみとなりました！
このまま気を休めず取得し、全制覇としたいと思います！
SAP on AWSは最近新しくできた試験なので合格記も少なく勉強法もあまり周知されていないと思うので、
自分なりの学習方法や頻出内容、検証内容等を記事に残せたらなと思います。

最後まで読んでいただきありがとうございました。
引き続き検証の結果も記事に残していこうと思いますのでよろしくお願いします！
自作のアプリケーションの紹介

# 同窓会アプリDumpling（ダンプリン）
- 同窓会を開くための発端になるように設計したアプリケーション
- ①Twitterでログイン
- ②三つ巴の相互フォロー関係を判定して初期メンバー３人で同窓会を薦める
- ③アプリからTwitterに飛び、同窓会を開くための文言を入れて＠ツイート
## 同窓会を開くための発端になるように設計したアプリケーション
![スクリーンショット 2022-07-11 13.45.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901058/4ee76261-4ea5-5a06-9e7b-d57d5657acf9.png)
## ①Twitterでログイン
- firebaseのログイン認証でtwitter認証を用いてtwitterログインを実装
- 同時にユーザーのtwitterのidやscreenName,imageURLなども取得
![Simulator Screen Shot - iPhone 8 Plus - 2022-05-17 at 16.02.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901058/0ce5faaf-1a7a-c56d-ee80-51c1606aa559.png)
## ②三つ巴の相互フォロー関係を判定して初期メンバー３人で同窓会を薦める
- idを投げると三つ巴の相互フォロー関係が帰ってくるwebアプリをデプロイしてるのでそこからXMLパースで情報を取得
- メンバー３人でのミニ同窓会的なものを無限にお薦めする
![Simulator Screen Shot - iPhone 8 Plus - 2022-05-17 at 16.04.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901058/ecd6df10-4301-6be0-fb67-8ebeb2042a31.png)
## ③アプリからTwitterに飛び、同窓会を開くための文言を入れて＠ツイート
- メンバーのセルをタップすると「twitterでシェア」or「アプリ内でトーク」を選べる（アプリ内トークはメンバー全員がアプリを登録してなければエラーを出す）
- twitterでシェアボタンを押すとtwitterに飛び、同窓会アプリDumplingで３人の同窓会が提案されましたという内容の＠ツイートをする画面になる
- twitterでシェア後、そのまま開催するかtwitterでメンバーを増やしてもらってから開催されたらいいなっていうアプリです！
![Simulator Screen Shot - iPhone 8 Plus - 2022-05-17 at 16.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901058/eda20109-be44-61dc-57f2-2c7548e13666.png)
![Simulator Screen Shot - iPhone 8 Plus - 2022-05-17 at 16.06.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901058/1f95fd2e-3e9d-df31-6d4a-32854ad10a45.png)
Progate HTML&CSS中級編終わり

<h1>2h未満程度で終わった</h1>
初級編の続きをしている感じであった。
<br>btn img の概念等よく作られているサイトだとしみじみ感じた。</br>
しかし実際に１からプログラムを書けって言われると、これ終わらせただけでは未だうまくコーディング出来ないんだろうなってのが正直なところ。
<br>次はjavascript！早くアニメーションで動的サイトを作りたい。（簡単なボタンは中級編で作ったが）</br>
Markdown記法が苦手だったのでNotionのコピペで楽した話

NotionはMarkdown記法を採用していますが、
下図のようにGUIで見出しやテーブルなど、大体のマークダウン記法を選択して、記事を作っていくことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374914/5effd161-2f59-6145-731d-f293b80c902d.png)

Qiitaに記事投稿する際、1からMarkdown記法を書くのが大変だったので、NotionのGUIで作成したMarkdownテキストをQiitaでコピペしたところ、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374914/14ac0fa7-50f4-1f08-8b0b-dcce42b95077.png)
Markdown記法でペーストされました。ありがたや
rails db:migrateが"Mysql2::Error: Duplicate column name ‘~’"で失敗した際の対応法

はじめに
--
実装している途中にDBテーブルに外部キーを追加する必要がありました。
いつものようにmigrationファイルを作成し、rails db:migrateを行ったところ下記のエラーメッセージが返ってきました。
~~~
~ # bundle exec rails db:migrate
Running via Spring preloader in process 1242
== 20221007040407 {migrationファイル名}: migrating ===============
-- add_reference(:テーブル名, :カラム名, {:null=>false, :foreign_key=>true})
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Duplicate column name ‘{追加したかったカラム名}’
~~~

原因がよくわからず、エラー解消まで少し時間がかかったので備忘録として残そうと思います。

結論:
--
作成したmigrationファイルの記述を消して、一旦rails db:migrateを叩くとschema.rbに反映がされる。
反映後、migrationファイルに元の記述加えればOK

~~~ruby
#エラーが起きたmigrationファイルの中身
class Add"カラム名"To"テーブル名" < ActiveRecord::Migration[6.1]
  def change
    add_reference :"テーブル名", :"カラム名", null: false, foreign_key: true
  end
end
~~~

手順
--
~~~ruby
#change内の記述を空にする
class Add"カラム名"To"テーブル名" < ActiveRecord::Migration[6.1]
  def change
    #空白にしてdb:migrateを行う
  end
end
~~~
~~~ruby
#空白でdb:migrateを行なってから記述を戻す
class Add"カラム名"To"テーブル名" < ActiveRecord::Migration[6.1]
  def change
    add_reference :"テーブル名", :"カラム名", null: false, foreign_key: true
  end
end
~~~


なぜエラー解消まで時間がかかったのか
--
"Mysql2::Error: Duplicate column name ‘{追加したかったカラム名}’"をネットで検索すると、結論で記載した解決法が書かれている記事はすぐに見つかります、実際すぐに解決できると思うのですが僕は時間がかかってしまいました。

その理由は、記事の多くは「"rails db:migrate"は失敗するけど、migrationはできている」という前提があって解消法が書かれていたことです。
僕のschema.rbはエラーが出た後も更新されておらず、前提である「migrationができていない」と考え、別に原因があると考え立ち止まってしまいました。

少し悩んだ後、失敗しても元に戻せばいいかと思いmigrationファイルを空白にして"rails db:migrate"をしたところ無事にschema.rbに反映がされました。

終わりに
--
同じ箇所で悩んでいる方の力になれればと思いqiitaに書きましたが、
正直、原因と解決した理由がいまいちわかっていない状態で少しモヤモヤしています。

もし詳しいことがわかる方がいらっしゃいましたらご教示いただけるとありがたいです。。

参考
--
https://qiita.com/niyomong/items/22fa60657ea8ee478647