OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】Spring bootのDockerイメージを作成し、Docker上で動かすまでの方法

# はじめに
Spring bootアプリケーションをコンテナ化したいと思ったときにやったことを備忘録として書き残しておきます。

# 前提
- Spring bootアプリケーションは既に作ってあるものとする
- Dockerの基礎知識がある
- Docker hubのアカウントを作っている

本題のみにフォーカスした記事にするため、このような形にしています。ご承知ください。(他の方の記事を参照ください)

# Spring bootのDockerイメージを作る
方法は2つあります。
1. Cloud Native Buildpacksを使う
2. Dockerfileを使う

本記事では1つ目の方法を使います。
コマンドプロンプトを開いて以下の通り進めてください。
```
cd [アプリ化したいプロジェクトのフォルダのパス]
mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=[docker hubのユーザ名]/[任意のimage名]:[tag]
```
これだけで簡単にDockerイメージが作れてしまいます。すごいですね...

ちなみにここで私はエラーを吐かれましたが、windowsのシステム環境変数に昔作ったJAVA_HOMEと結び付けていたJavaのバージョンとEclipseで使ってるJavaのバージョンが違っていたのが原因でした。
(mvnwの中身見たらなぜか勝手にJAVA_HOMEのバージョンを使うようにされてた)

# Docker上で使う
イメージができているか確認しましょう。この時点ではローカル環境にのみ作られます。
```
docker images
```

Docker hubにイメージを登録したいなら以下のコマンドを実行してください。
```
docker push [Docker hubのユーザ名]/[image名]:[tag]
```

早速動かしましょう！
```
docker run -dit --name [コンテナ名] -p 8080:[spring-bootのserver.port] [ユーザ名]/[image名]:[tag]
```
これでlocalhost:8080で接続できるはずです。
[spring-bootのserver.port]は、特に何もいじっていなければ8080に設定されています。
この数値は、application.propertiesに server.port=ポート番号 を記述することで任意のポート番号に変えれます。
Docker上でSpring bootアプリケーションが待ち受けているポートになるので、他のコンテナのポートと被らないように気を付けましょう。

# 最後に
Dockerfileの記述から逃れることができるっていうのはCloud Native Buildpacksを使うメリットだと思います。ぜひ使ってみてください。Spring bootはいいぞ。
新しいMacへ移行したのでメモしておく

最近新しいMacへ環境移行したのでメモを残しておこうと思います。
(M1 から M3 になりました！)

# まずは Homebrew をインストール
https://brew.sh/ja/

# vscode の設定やプラグインを移行
https://blog.35d.jp/2020-11-21-copy-vs-code-setting

# cursor をインストール(vscodeから移行)
https://zenn.dev/umi_mori/books/ai-code-editor-cursor/viewer/install

# vim カラーリングを molakai へ変更
https://zenn.dev/hiroki_tkg/articles/ea251782fca849a9d8bc

# Oh My Zsh(Powerlevel10k) をインストール
https://slacknotebook.com/zsh-powerlevel10k-installation-linux/

あとは .zshrc, .zprofile をコピーして終わり！
知識ゼロからのG検定合格体験記 #1

# はじめに
2019年に日本ディープラーニング協会（通称JDLA）が主催するAIの資格、Deep Learning for General 略称「G検定」を取得しました。
少し前の話になりますが、最近AIやデータサイエンス関連の資格についての話題が多くなってきた気がするので、これから挑戦してみたいという人に向けて勉強法や感想などを書いていきたいと思います。

#### この記事の対象者
✅ これからAIについて勉強を始めてみたいと思っている人
✅ G検定を受験したいが、何をやっていいかわからない人
✅ 「自分じゃAIなんて無理」と思ってしまうが、興味はある人

# G検定って何？
G検定とは、日本ディープラーニング協会という、日本のAI事業を発展させるために発足した、一般社団法人です。AIを事業の核とする企業および有識者が中心となって、産業活用促進、人材育成、公的機関や産業への提言、国際連携、社会との対話などの様々な取り決めや、見解を発表しています。
理事長はAIの研究で有名な、東大の松尾 豊教授です。
このJDLAがAI人材育成のために実施している試験が、「G検定」と「E資格」の２種類の資格です。
このうち、ビジネス分野にもAiの知見を広く生かせる人材＝ジェネラリストを育成向けの資格がG検という感じでしょうか。
平たく言えば、「AIを自分の業務でうまく使ったり、エンジニアと事業開発の話がきちんとできる人の育成」のためでしょうか。

※JDLAについては以下を参照
https://www.jdla.org/

![bnr_g2022-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426787/792963ae-956d-ec7f-0380-8a69b30180c1.png)


# どんな人におすすめの資格？
G検定はジェネラリスト育成資格なので、例えば以下の様な人が対象って感じがします。
- 特にエンジニアにならなくてもいいがAIには詳しくなりたい
- 自分の今の仕事に活かせればいいという社会人
- 就活のアピールに使いたい学生
- 何していいかわからないが、とにかくAIが勉強したい人

入門編の様な位置づけの資格なので、とりあえずアピールできてかつ勉強のとっかかりとしては初学者には向いているのではないでしょうか。
ただ、初学だと「難しいぞ・・・」と感じる部分は多いかもしれません。

# 受験当時の筆者のレベル
全く知識ゼロです。プログラミングも当時は全くやったことがありませんでしたし、何をやっていいかもわかりませんでした。AIとか人工知能とか、なんか難しそうだし、よくわからない。自分にできるのかなぁ、と半信半疑で勉強を始めた記憶があります。

# 試験の概要
試験は年に３回（3月、7月、11月）実施されています。私は2019#1を受験しました。年に複数回実施されているので、自信がついたら直近の試験に受験をするといいでしょう。
オンライン受験（２０２２年も同様）なので自宅で受験できるのが嬉しいです。試験時間内にネットで検索することは認められているので、わからないことがあれば調べられます。ただし、問題数が多く試験時間がタイトなので、調べまくっていると間に合いません。以下に試験の概要をまとめます。

- 試験時間：120分
- 知識問題（多肢選択式・220問程度）
- オンライン実施（自宅受験）
- 受験費用	
 一般：13,200円（税込）
 学生：5,500円（税込）

学生は割引があります。受験資格は特にないので、誰でも受験できます。

# 試験範囲
割と幅広く出題されます。AIの技術的な内容はもとより、歴史や法律、国の政策や社会問題など時事問題的な部分からも出題されます。一応シラバスはあるんですが、実際はやったことも、見たこともないような部分から出題されたりもしていました。２０２２#2でもそうだったみたいです。

**試験範囲**
- 人工知能（AI）とは（人工知能の定義）
- 人工知能をめぐる動向
- 人工知能分野の問題
- 機械学習の具体的手法
- ディープラーニングの概要
- ディープラーニングの手法
- ディープラーニングの社会実装に向けて

2022年にシラバスが若干改訂されて新しい分野も範囲に入りましたが、合格率にはそれほど影響もなかったみたいですね。
ちなみに、協会の名前にもなっている「ディープラーニング」というのは、AIブームが起こるきっかけになった技術、日本語では深層学習のことです。
JDLAのサイトでもシラバス（試験範囲のこと）が公開されています。
https://www.jdla.org/certificate/general/#


次の記事では具体的な勉強法や筆者なりの対策について書きたいと思います。
com.arenagod.gradle.MybatisGeneratorが動かない

Kotlin × SpringBoot × MyBatisを使用しようとして、MyBatisGeneratorを使用しようしとしたら以下エラーで詰まりました。

## エラー内容

```
In plugin 'com.arenagod.gradle.MybatisGenerator' type 
'com.arenagod.gradle.MybatisGeneratorTask' property 'configFile' 
is missing an input or output annotation.
```

## 原因

どうやら、Gradleのバージョン起因で7系だと動かないみたいです。

## 対策

代わりに以下をしようすることで解消できました。

```gradle
plugins {
    id("com.thinkimi.gradle.MybatisGenerator") version "2.4"
}
```
Google Apps ScriptとGitHubを連携する方法

# 今回使用するもの
- GitHub
- Google Chrome
- Google Apps Script GitHub アシスタント


# 手順
1. [拡張機能のインストール](#拡張機能のインストール)
1. [Githubのアクセストークンを作成](#githubのアクセストークンを作成)
1. [Githubのアクセストークンを取得](#githubのアクセストークンを取得)
1. [ログイン連携](#ログイン連携)


## 拡張機能のインストール
chrome ウェブストアで **Google Apps Script Github アシスタント**をインストールします。

https://chrome.google.com/webstore/detail/google-apps-script-github/lfjcgcmkmjjlieihflfhjopckgpelofo?hl=ja

## Githubのアクセストークンを作成
- [Github](https://github.com)に移動
- トップページから右上のユーザーアイコンをクリック
- [**Settings**] を選択
- メニューの1番下 [**Developer settings**] を選択します
- [**Personal access tokens**] を選択
- [**Generate new token**] をクリックします

- 以下の設定後[**Generate token**]ボタンを押す（画像）
    - [**Note**]に作成したトークンがわかる名前を入力する
    - [**Select scopes**]に必要な項目を選択する
        - repo
        - gist

![スクリーンショット 2022-07-30 22.50.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520484/14aed9a5-657f-71f6-3f6a-2e6f3d6712f9.png)

# Githubのアクセストークンを取得
以下のようにアクセストークンが表示されるので、忘れないようにメモしましょう。
後で認証する時に必要になります。
![スクリーンショット 2022-07-30 22.58.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520484/d6eb9004-d5aa-62ca-1ad5-3fe4c8679ffc.png)



## ログイン連携
Google Apps Scriptを開きます。

https://script.google.com/home

新しいプロジェクトを開き、「Login to SCM」をクリック

![スクリーンショット 2022-07-30 23.26.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520484/33c42d59-291e-cc8d-0388-49a63499b093.png)


ログイン画面にするので、**Githubのユーザ名**と先ほど取得した**Githubのアクセストークン**を入力します。
**GITHUB LOGIN**を押すとGoogle Apps ScriptでGithubが使えるようになります。
![スクリーンショット 2022-07-30 23.16.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520484/60164650-47e5-3f15-1f76-cf8c0f659610.png)

ログインができたら、以下の画面が出てきます。
**LOGOUT**ボタンを押さずにGoogle Apps Scriptのページに戻りましょう。

![スクリーンショット 2022-07-30 23.15.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520484/db12c8ca-53d8-0c35-bff8-aa2723be13c8.png)

>注意：ログイン後の画面はログアウトのボタンが表示されていますが、ログアウトをするとGASでGithubが使えなくなるので注意してください。



# 参考文献
[【Google Apps Script】GitHubを活用したチーム開発手順の解説](https://qiita.com/ffggss/items/3aac232bdb0fb33c980a)
[Google Apps ScriptのコードをGitHubで管理する方法](https://qiita.com/kita3folio/items/7a5bd678864ae46ff616)
[GASのコードをGithub管理するChrome拡張が便利](https://qiita.com/nkjzm/items/d384896d01ac3ff6f91c)
「Google Maps の検索結果から Yahoo! カーナビで経路案内できる iOS ショートカット」を再復活させた

:::note info
@otchy さんが作られていた [Google Maps の検索結果から Yahoo! カーナビで経路案内できる iOS ショートカット](https://qiita.com/otchy/items/79184c6124c683509aeb) に記載されている `v2` が再び動作するようになっておりました。この記事のショートカットは `v2` が動作しない場合にご使用ください。　(2023/02/12時点)
:::

@otchy さん、 @musubi05 さんが作られていた [Google Maps の検索結果から Yahoo! カーナビで経路案内できる iOS ショートカット](https://qiita.com/otchy/items/79184c6124c683509aeb) を再復活させました。

## Y!カーナビで経路案内

以下のリンクからショートカットを追加できます。

v6: https://www.icloud.com/shortcuts/b893173258884c5a8de1ff32fb891643
~~v5: ttps://www.icloud.com/shortcuts/823d3d68d2984d1ebff9e42fffdc5710~~

v5: 「入力から住所を取得」を「場所」に置き換えました。

|v4|v5|
|:---|:---|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/cb642f22-a4ce-b266-1339-927b921939d7.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/0bc46047-9a20-ab9d-019e-916e37e37ebb.png" width="50%">|

v6: 項目のインデックスを変更しました。

|v5|v6|
|:---|:---|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/166c70eb-8489-54dd-f824-cf9dfabc5647.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/61bd076a-985a-c471-8475-107523e4fb07.png" width="50%">|


## 原因の特定

緯度・経度が取得できなくなっていました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/808d44d7-5323-d854-0c63-384e1c4d08f9.png" width="25%">

## 緯度・経度を取得する方法の調査

「`address`から住所を取得」の下に「`住所`周辺の`住所`を検索」を追加すると、
緯度・経度が取得できるようになりYahoo!カーナビに目的地が転送されるようになりました。

上記は @musubi05 さんの記事に [コメント](https://qiita.com/musubi05/items/edc38dc70a52447e2ffa#comment-1d55c5bc1622ee8fed90) した内容です。

@Neru-Neru さんの [記事](https://qiita.com/Neru-Neru/items/178fb18550796c1e5cdb) から「現在地を取得」でも緯度・経度が取得できるようになることが分かりました。
記事にコメントをしたあとにTwitterでこの記事があることを知りました。

|近くの店舗や企業を検索|現在地を取得|
|:---|:---|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/7896eb69-cf5b-1487-e96c-2258e8f623ee.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/39a6d0d8-511d-55de-92aa-1f65b22ef733.png" width="50%">|

緯度・経度を取得する方法は「入力から住所を取得」の他に「場所」があることが分かりました。
「場所」では緯度・経度が取得できました。

|入力から住所を取得|結果|場所|結果|
|:---|:---|:---|:---|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/5ee4995a-476d-4a64-7c73-2d56df3e30f1.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/8a87ef81-5ceb-18a2-8f02-edb1260b09c3.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/ec3e90ba-741d-6cf6-9c5d-e80c8b5bf3bc.png" width="50%">|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935877/f8e20799-c385-05ee-0a27-6d0ced99658e.png" width="50%">|
【PHP初級㉞】for文応用6

[問題]　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)

整数値を入力させ、1から9まで、入力値と入力値+1以外を表示するプログラムを作成せよ。入力値が9の場合は9のみ表示しない。



# コード
```php
$a = intval(fgets(STDIN));
for($m = 1; $m <= 9; $m++){
    if($m <> $a && $m <> $a+1){
        echo $m,PHP_EOL;

    }
}
```

↓「7」を入力

# 結果
```
1
2
3
4
5
6
9
```
データ解析や機械学習はプログラミングスキルだけを上げてもダメだなと思う話

## 本記事の対象者
- データ解析や機械学習をしてみたいと思うけど実務経験のない方
- Pythonのプログラミングの学習を始めたての方

## はじめに
記事を書く前に簡単な自己紹介をしておきます。
- 普段は主にPythonを使ったデータ解析や機械学習をやっています。
- プログラミングは基本独学
- Rも多少かじってます。
すごくざっくりですがこんな感じ。私は自分のブログもやっているので、独学でプログラミングを習得した方法について気になる方は[こちら](https://fuyutsuki.net/programming-master/)をご覧ください。

ここでは、<b>特にPythonでのデータ解析や機械学習を独学で習得しようとしている方に読んでほしい</b>記事となっています。

## プログラミングの独学
独学でプログラミングを学習しようとしている方はどのように勉強されているでしょうか？
書籍・ウェブサイト・Udemy、今ではYoutubeという方も多いのかもしれません。
私はというと、以下のようなサイクルでプログラミングを勉強していました。
1. 何を作るか(どの言語を勉強するべきか)考える。
1. 書籍やGoogle検索などでインプット
1. 他の方のコードを真似て、適宜コードをいじる
1. 分からないところは更にグーグル検索し、エラーを解決。
1. 作りたいものができたら、1に戻る。
一見すると、シンプルかつ特に問題のなさそうなPDCAサイクルに見えるのではないでしょうか。
実際のところ、<b>"何かを作る"</b>ことに関して言えばこういった独学でも全く問題ないと思います。

### 独学の壁
独学の壁を感じ始めるのは<b>設定した課題に対して機械学習をやってみようと思ってから</b>です。
結論から言うと、<b>得られた結果が妥当かどうかが素人には判断がつかない</b>のです。

書籍に乗っ取って勉強を進めているうちは良いのです。
コードも書籍に記述されていますし、得られた結果をどのように解釈すればよいのかも解説してあるので。

問題は、<b>いざ自分で課題を設定し解決しようとするとき</b>です。
例えば、機械学習の前処理フェーズである主成分分析を行うとき。
欠損値処理はどのように行うのか？相関係数の高い説明変数は素直に削除してよいのか？ScalingはAuto Scalingで良いのか？などなど<b>プログラミングや機械学習分野だけを独学してきた人にとっては解決できないお悩みがたくさん発生します</b>。

## この記事で伝えたいこと
要は何が言いたいねん！ですよね。
<b>機械学習を行う分野にも詳しくないとダメだよ！！！！</b>ということです。
データサイエンスの分野では<b>"ドメイン知識"</b>という風に言います。
<b>ドメイン知識がないと、得られた結果が妥当かどうか・データの前処理が正しく行えているのかということが分かりません。</b>

### コミュニケーション大事
自分にはドメイン知識がない！どうすればいいんだ！という方、ご安心ください。
<b>ドメイン知識がある方と交流すればよい</b>のです。
結局のところ、プログラマーやデータサイエンティストにもコミュニケーション能力はとても大事だと思います。
<b>自分の不足している知識は、その分野に詳しい人に教えていただきましょう。</b>一方的に教えてもらうわけではなく、きちんと議論するようにしましょうね。

## まとめ
私はデータ解析や機械学習を行う上でドメイン知識が重要になるということに気が付くまでにかなり遠回りしてしまいました。
私と同じように遠回しをしてしまわないよう、<b>データ解析や機械学習において前処理を正しく行い、得られた結果に対して誤った解釈をしないようにするためには、ドメイン知識が重要になるということを念頭に置いてもらえれば幸い</b>です。
Go言語でyesコマンド

# Go lang始めてみた
[A Tour of Go](https://go.dev/tour/welcome/)のConcurrency以外を読み終えた。
ここまでの内容をまとめるのにちょうど良さそうなのでyesコマンドを実装してみた。

# 仕様
- 1つ目のコマンドライン引数が"-h"または"--help"ならばヘルプメッセージを表示
- コマンドライン引数がなければ"y"をひたすら出力
- その他の場合はコマンドライン引数を" "でjoinした文字列をひたすら表示
- ~~最適化を頑張らない~~

# コード
https://github.com/NI57721/go-scripts
```go:yes.go
package main

import (
  "fmt"
  "io"
  "os"
  "strings"
)

type yesReader struct{
  yes string
  reader io.Reader
}

func (r *yesReader) Read(b []byte) (int, error) {
  n, err := r.reader.Read(b)
  if err != nil {
    return n, err
  }
  for i := range b {
    b[i] = byte(r.yes[i])
  }
  return len(b), nil
}

func isNoCommandlineArgs() bool {
  return len(os.Args) == 1
}

func includeHelpCommandlineArg() bool {
  return os.Args[1] == "-h" || os.Args[1] == "--help"
}

func execHelp() {
  fmt.Println(`Usage: yes String or Option
	-h --help: display this message`)
}

func yesOnece(yes string) {
  s := strings.NewReader(yes)
  r := yesReader{yes, s}
  b := make([]byte, len(yes))
  for {
    _, err := r.Read(b)
    fmt.Println(string(b))
    if err == io.EOF {
      break
    }
  }
}

func main() {
  var yes string
  switch {
  case isNoCommandlineArgs():
    yes = "y"
  case includeHelpCommandlineArg():
    execHelp()
    return
  default:
    yes = strings.Join(os.Args[1:], " ")
  }

  for { yesOnece(yes) }
}
```

# 実行
```
$ go run yes.go --help
Usage: yes String or Option
        -h --help: display this message
$ go run yes.go foo bar   baz | head -n 5
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
signal: broken pipe
$ go run yes.go | head -n 5
y
y
y
y
y
signal: broken pipe
```
# 感想
嬉しい。
次はLISPのインタープリタを書いてみたい。
ISOファイルからVMware Cloud on AWS上に仮想マシンをデプロイしてみる  (データストアに手動アップロード編)

# 1. はじめに
セットアップしたVMware仮想環境にVMware仮想マシンをデプロイする際、ピュアなISOイメージからデプロイすることもあるかと思います。VMware Cloud on AWS環境においても、通常のオンプレミスVMware仮想環境と手順は同じです。今回は後続のブログへの参照用のためにいったんまとめてみます。
似たような手法としてコンテンツライラブリを作成する方法もあり、それについては次のブログもご参考ください。

https://qiita.com/sanjushi003/items/2870c8feced5fd367604

# 2. 早速やってみる

## (1) ISOファイルの入手
#### (1)-1 まずはISOファイルを入手します。
今回はMicrosoft社のEvaluation Centerから、Windows Server 2019(評価版)をダウンロードしました。5.5GBほどのサイズだったのでダウンロードは気長に待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/16b2046d-9b75-722d-5f76-2e2c509285a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/c32b0086-7f9b-37de-d79c-501c9f204f61.png)

https://www.microsoft.com/ja-jp/evalcenter

## (2) vCenterにISOファイルのアップロード
#### (2)-1 データストアにフォルダを作成します
さっそく仮想マシンのデプロイ、といきたいところですがまずはvCenterにISOファイルを格納するフォルダをデータストアに作成して、そこにISOファイルをアップロードしてやる必要があります。
フォルダ名は「ISO File」としています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/bab2856b-b834-6dfb-db1a-6b19040366c2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/bd01ba93-d21d-5bab-e7d8-ff26b3f33a94.png)

#### (2)-2 ISOファイルを作成したフォルダにアップロード
作成したデータストア内のフォルダに、ISOファイルをアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/ff049094-2479-cb0e-0baa-e87e8e3468bf.png)

## (3) 仮想マシンのデプロイ
#### (3)-1 デプロイ先のCompute Resource Poolもしくは仮想マシンフォルダなどに遷移して、仮想マシンをデプロイします。
この際、アップロードしたISOファイルがパワーオン時に接続(マウント)されるように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/846af3ff-77c8-427b-5bf9-56eede295e2a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/e956868a-f9ba-d5ed-fd5f-c367dac844a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/d720e94a-bf9e-4412-d119-9fc3b7427219.png)


#### (3)-2 仮想マシン再起動の前には、ISOファイルのアンマウント(切断)を忘れずに。
OSの初期設定、あるいはVMware Toolsインストール後には再起動が必要となるかと思います。
ついつい忘れがちですが、仮想マシン「設定の編集」からISOファイルのアンマウント(切断)を忘れないようにします。（再度インストールが始まってしまいます。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/b02dc100-4d13-4dd2-ce0f-8bc3edba13a2.png)

再起動後には、いつものWindows環境が立ち上がってきます。これにて完了です。


# 4. 関連記事

https://qiita.com/sanjushi003/items/2dd1ccdafdb93795561b

https://qiita.com/sanjushi003/items/2870c8feced5fd367604

https://qiita.com/sanjushi003/items/4d20c85b80032e6f6b25
「はじめよう！要件定義」を読んだ

https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86-%E8%A6%81%E4%BB%B6%E5%AE%9A%E7%BE%A9-%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%81%8B%E3%82%89%E3%83%99%E3%83%86%E3%83%A9%E3%83%B3%E3%81%BE%E3%81%A7-%E7%BE%BD%E7%94%9F-%E7%AB%A0%E6%B4%8B/dp/4774172286/ref=asc_df_4774172286/?tag=jpgo-22&linkCode=df0&hvadid=296301907375&hvpos=&hvnetw=g&hvrand=10691462729459774604&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009292&hvtargid=pla-531209636572&psc=1&th=1&psc=1

# 内容整理
## 第１部　要件定義って何だろう？
- 要件=注文
- 要求が、明確に定まった形で作る側の人に伝わらなければならない
- 実現可能性も考慮しなければいけない
- 要件とは、作って欲しい人と作る人の合意事項
- 依頼した人ができあがったものに対して「これならOKです」と言うために、「何がどうなればよいのか」ということを明確に定めたもの
- プログラマーがソフトウェアを完成させるために必要な情報
  - UI
  - 機能
  - データ
## 第２部　要件定義の詳細
### ［準備編］
- 企画書を確認できない＝ゴールの定義が不明瞭
- 「通った企画がいったいどのようなものなのか」を
「企画を実現する関係者」が
「理解する」ために必要な企画書
- これから作るソフトの全体像を描きましょう
- 実装技術を、要件定義前に決める必要があるのか？
  - 上流工程と実装は別物であるから、実装技術を決めなくても要件を定義することはできるという意見もありますが、ではそこで要件とは具体的にいったい何なのか、それを決めることで後工程に何を送るのか、ということを曖昧にしたままもっともらしい言葉で誤魔化すのは、プロジェクトに火種を持ち込むだけです。基本的な実装の裏付けはこの時点で用意しておきましょう。
### ［助走編］
- 行動シナリオとは？
  - ソフトウェアが完成した暁には利用者がどんな風に行動するようになるか整理したもの
  - ビジネスプロセスフローやプロセスマップ、業務フローやユーザーシナリオやユースケースなユーザーストーリーと呼ばれる
- 行動シナリオから何を得たいのか。以下のものです。
  - ソフトウェアを利用するタイミング
  - ソフトウェアを利用する理由
  - ソフトウェアを利用することで利用者が具体的に達成する仕事
- 利用者が行う行動の単位を「仕事」とする
- 仕事とは、何らかの成果と、その成果を出すために行う活動のまとまり
### ［離陸編］
#### UI
- UIを構成する要素
  - データ項目
  - 操作項目
  - レイアウト
- UIを考える作業は、リニア（直前的）に進むというより、ああでもないこうでもないという感じで試行錯誤して進めていくことになります。
- トラブルを引き起こしやすい要因
  - エイリアス
    - 別名
  - シノニム
    - 異音同義語
  - ホモニム
    - 同音異義語
- 要件定義（UI）の成果
  - ラフイメージまたはモックアップ
  - 画面遷移図
  - 項目の説明
#### 機能
- 機能というのは、ソフトウェアが行う処理の具体的な手順を決めていくこと
- 要件定義（機能）の成果
  - 機能の入出力定義
  - 機能の処理定義
#### データ
- データベース設計の手順
  1. ワークセット単位で設計する
  2. 1の成果を1つに統合する
- 要件定義（データ）の成果
  - 統合ERD
### ［要件定義、その後］
- CRUDマトリックスをつくる

## あとがき
- 本書の肝は画面遷移図を書こう、ということ

# 感想
- 「要件定義の準備段階で、実装技術の整理を行う」という記述に驚いた。要件定義では、実際にどのように実装を行うかは考えないと思っていたので。
- 「機能要件定義で、処理を細かく分割し、処理定義／入出力定義をする」という記述に驚いた。処理の細かい分割などは設計段階で行うものだと思っていたので。
Γx の 計算方法(Python)

今回は[hmath](https://caleb7023.hmath.pro/)で使用されている$\Gamma x$(Gamma(x))の計算方法をご紹介します。
## 計算式
[hmath](https://caleb7023.hmath.pro/)は次の数式で$\Gamma x$を定義しています。
```math
\begin{eqnarray}
\Gamma x =
\begin{cases}
\frac {\pi}{\sin(\pi x)\Gamma (1-x)} & if　\Re x < 0.5\\
\sqrt \tau (x+6.5)^e(x-0.5)(0.99999999999980993+\frac{676.5203681218851}{x}-\frac{1259.1392167224028}{x+1}+\frac{771.32342877765313}{x+2}-\frac{176.61502916214059}{x+3}+\frac{12.507343278686905}{x+4}-\frac{0.13857109526572012}{x+5}+\frac{9.9843695780195716e-6}{x+6}+\frac{1.5056327351493116e-7}{x+7}) & if　0.5 \leqq \Re x\
\end{cases}
\end{eqnarray} 
```
$\tau$は$\pi 2$で定義される定数です。
## プログラム
[hmath](https://caleb7023.hmath.pro/)内では次のプログラムで計算しています。
```ruby:Gamma.py
import hmath
__Gamma_list = [
      676.5203681218851      ,
    -1259.1392167224028      ,
      771.32342877765313     ,
     -176.61502916214059     ,
       12.507343278686905    ,
       -0.13857109526572012  ,
        9.9843695780195716e-6,
        1.5056327351493116e-7,
]
def Gamma(x):
    if hmath.real_part(x) < 0.5:
        ans = hmath.pi() / (hmath.sin(hmath.pi() * x) * Gamma(1 - x))
    else:
        y = 0.99999999999980993
        for (i, Gamma_v) in enumerate(__Gamma_list): # enumerateというデータ型はループの回数と要素を合わせて取得できる。
            y += Gamma_v / (x + i)
        t = x + len(__Gamma_list) - 1.5
        ans = hmath.sqrt(hmath.tau()) * t ** (x - 0.5) * hmath.exp(-t) * y
    return ans
```
最後まで見ていだきありがとうございました。
少し長くなりました。
ぜひ活用してみてください。
iphoneで撮った映像をDVDプレーヤーで再生できるようにmacで書き出す方法

# オーサリング
各種データからメディアを作成することをオーサリングというらしい。
メディアからデータを抽出することをリッピング。

# 経緯
iphoneで撮りためていたムービーをiMovie(有料アプリだったはず)で編集してmacに転送し、それをDVD-Rに書き出してdvdプレーヤーで見たかった。
macからDVD-Rに焼く時のDVDドライブも買った。DVD50枚組と合わせて4000円もしなかった

# インストールするもの
オーサリングソフトはすべて `brew install` できた。 mkisofsはcdrtoolsに対応している。

- ffmpeg
- dvdauthor
- mkisofs

```
brew install ffmpeg
brew install dvdauthor
brew install cdrtools
```

# 手順
## 1.DVD-Rの初期化
- DVDドライブをmacに接続する。空のDVD-Rは入れておく
- Finder > 移動 > ユーティリティ > ディスクユーティリティを開く
- ディスクユーティリティのwindowの左ペインでDVDドライブを右クリック > イメージを作成 > フォーマットを `DVD/CDマスタ` にして保存

## 2．iMovieのファイルフォーマットをmpegに変換
1時間40分ほど(！)のiMovieファイル(.mov)をffmpegを使って .mpg に変換する。
iPhoneからmacへの転送はAirDropを使った。２０Gほどあった。
ffmpegは使いこなせてないので単にフォーマット変換するだけにとどまっている。変換後は4.5Gほどになった。

```
% ffmpeg -i imovie.MOV -target ntsc-dvd out.mpg
```

## 3.mpegファイルをDVDで再生できるフォーマットに変換する
細かい話はよくわからないけどこうやったら見れるようになった。iso形式にするんですって。

```
% dvdauthor -o dvd -t out.mpg
% VIDEO_FORMAT=NTSC dvdauthor -o dvd -T
% mkisofs -dvd-video -o mydvd.iso dvd
```

## 4.isoファイルをDVD-Rに焼く
mydvd.isoを右クリック > ディスクを作成　で実行する。

２０分くらいはかかったかもしれない。

これで完了。
【#43 エンジニア転職学習】GinTutorialのWebApp改造 PUT/DELETE

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

7月いっぱいまでGoのフレームワークであるGinについて、
学習をしていきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
GinのTutorialで作成したAPIを改造して、簡素なWebアプリを作成しようと思います。
本日はAPIにメソッドを追加しました。

* **PUT/DELETEメソッド追加　←Topics!!**


# PUT/DELETEメソッド追加
GinのtutorialではGETとPOSTのみ実装だったので、
先日挙げたタスク通り、まずはPUTとDELETEメソッドを追加実装します。

##### 追加する機能等
* **APIのPUTとDELETE**
* albumデータのDB管理
* ブラウザ上での表示（HTMLから）
* キーワード一致のGET

##### タスク
1. **PUTとDELETEのコード記述**
1. GORMの基礎学習とMySQLのDBテーブル作成
1. GORMを使用したAPI部分とDBの連携
1. フロントエンド部分のインターフェース作成、Goと連携
1. キーワード一致GET機能の追加、実装

### PUTとDELETE実装コード
基本的には指定GETとPOSTの組み合わせのような構造だと思いました。
~~~sample.go
//UpdateAlbumByID update an album from JSON received in the request body.
func UpdateAlbumByID(c *gin.Context) {
	id := c.Param("id")
	var album Album

	//Data binding.
	if err := c.BindJSON(&album); err != nil {
		c.IndentedJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	//Loop over the list of albums, looking for ID
	//and PUT album data.
	for i, a := range albums {
		if a.ID == id {
			albums[i] = album
			c.IndentedJSON(http.StatusOK, album)
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "album not found"})
}

//DleteAlbumByID delete an album form JSON received in the request URI.
func DeleteAlbumByID(c *gin.Context) {
	id := c.Param("id")

	//Loop over the list of albums, looking for ID
	//and Delete album data.
	for i, a := range albums {
		if a.ID == id {
			albums = append(albums[:i], albums[i+1:]...)
			c.IndentedJSON(http.StatusOK, gin.H{"message": "Album has been deleted"})
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "album not found"})
}
~~~

##### 使用している教材はこちら↓


https://go.dev/doc/tutorial/web-service-gin


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
Power Automate Desktop で innerHTML が取得できることに気づいた

Power Automate Desktop を使って、Webページ上で、特定の要素の、特定の属性の値を取得する方法です。  
以下のように、選択肢にないものでも直打ちで設定できます（innerHTML を設定した例）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467348/707e5cfc-dbe5-629f-b3ed-7132563913da.png)

当初は、対応するアクションが見当たらなかったのであきらめていましたが、「Webページ上の要素の詳細を取得します」のアクションで、取得できることに気づきました。
取得する属性は「Own Text」や「Title」などしか選択肢がなく、HTMLソースなど取得できないものだと思い込んでいましたが、直打ちで「innerHTML」って入れれば、HTMLソースが取得できるんですね。これでできることが格段に増えそうです。
(もちろん、outerHTML, id などその他の属性も直打ちすれば取得できます）

Power Automate Desktop は、Webブラウザの手動操作を自動化できるので便利です。
以前は、Seleniumなどで WebDriver や JavaScript を駆使して苦労してましたが、今は、Power Automate Desktop でずいぶん楽になりましたね。(実はPower Automate Desktopでも裏では同じ仕組みのものが動いてますが😅)

https://qiita.com/tags/powerautomatedesktop
konva+reactでreact-iconsのsvg画像をcanvasに表示したかったメモ

## 概要
表題のことをしたかったが、あまり情報がなかった。
一旦`renderToStaticMarkup`でdata-urlに変換することで表示できたので、メモ。

もっとスマートな方法があれば知りたいです。

## 環境

* "react": "^18.2.0"
* "react-icons": "^4.4.0"
* "react-konva": "^18.2.1"
* "konva": "^8.3.10"

## ソース

```ts
import React from 'react'

export const useImage = (
  url: string,
  crossOrigin?: 'anonymous' | 'use-credentials',
) => {
  const statusRef = React.useRef<'loading' | 'loaded' | 'failed'>('loading')
  const imageRef = React.useRef<HTMLImageElement>()
  const [_, setStateToken] = React.useState(0)

  const oldUrl = React.useRef<string>()
  const oldCrossOrigin = React.useRef<string>()
  if (oldUrl.current !== url || oldCrossOrigin.current !== crossOrigin) {
    statusRef.current = 'loading'
    imageRef.current = undefined
    oldUrl.current = url
    oldCrossOrigin.current = crossOrigin
  }

  React.useLayoutEffect(
    function () {
      if (!url) return
      const img = document.createElement('img')

      function onload() {
        statusRef.current = 'loaded'
        imageRef.current = img
        setStateToken(Math.random())
      }

      function onerror() {
        statusRef.current = 'failed'
        imageRef.current = undefined
        setStateToken(Math.random())
      }

      img.addEventListener('load', onload)
      img.addEventListener('error', onerror)
      crossOrigin && (img.crossOrigin = crossOrigin)
      img.src = url

      return function cleanup() {
        img.removeEventListener('load', onload)
        img.removeEventListener('error', onerror)
      }
    },
    [url, crossOrigin],
  )
  return [imageRef.current, statusRef.current] as const
}
```
```ts:icons.tsx
export { FaTag } from 'react-icons/fa'
```

```tsx
import { renderToStaticMarkup } from 'react-dom/server'
import * as icons from '@/components/atoms/icon/icons'
import { useImage } from './useImage'
type Icons = keyof typeof icons
export const useIconImage = (icon: Icons, size?: number) => {
  const svgString = encodeURIComponent(
    renderToStaticMarkup(icons[icon]({ size })),
  )
  const dataUri = `data:image/svg+xml,${svgString}`

  return useImage(dataUri)
}
```

```tsx
const WithIconImage: React.FC = ({ children }) => {
  const [image] = useIconImage('FaTag', 50)
  return (
    <Stage width={canvasWidth} height={canvasHight}>
      <Layer>
            <Image x={leftGap} y={pictTop} image={image} size={50} />
      </Layer>
    </Stage>
  )
}
```



## 参考
[konva.js svg](https://konvajs.org/docs/sandbox/SVG_On_Canvas.html)
[svg-to-dataurl](https://github.com/F1LT3R/svg-to-dataurl/blob/master/index.js)
Ubuntuでcron実行履歴確認

# 概要

設定したcronがちゃんと動作したか確認したい時など。

# やり方

syslogに対してgrep検索。

```shell
less /var/log/syslog | grep CRON
```

# 参考サイトさん

https://helog.jp/linux/crontab/

# バージョン

Ubuntu 20.04.5 LTS
Automatorを使ってMail.appからJSON形式で情報を取り出す

(2022.7.31) 追記あり

Automatorを使って、AppleScriptでMail.appアプリから選択されている情報を取り出し、JavaScriptでJSONに変換した後に、他のスクリプト言語(ここではRuby)でファイルに書き出しています。

### ワークフローの作成

#### 全体の構成

![widow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171895/1b4f4f9f-eb04-be9c-b4ff-6b726d721c4a.png)

#### 作成方法

* Automatorを起動し、新規にワークフローを作成します。
* 一番上にアクション「AppleScriptを実行」を追加します。

以下のスクリプトを書き込みます。


```AppleScript
on run {input, parameters}
	tell application "Mail"
		set theSelected to selection
		set theList to {}
		repeat with theMessage in theSelected
			set end of theList to {mail_subject:subject of theMessage, mail_sender:sender of theMessage}
		end repeat
		return theList
	end tell
end run
```

ここではMail.appで選択したメッセージ(複数でも可)を取り出し、その中の題名と送信人の情報を取得しています。本文や受信日時など必要な情報を追加することもできます。
`{mail_subject:subject of message1, mail_sender:sender of message1}`
でレコードを作成し、そのリストを次のアクション(JavaScript)に渡します。

（注　レコードのキーを最初はsubjectとsenderとしていましたが、何かの使われている名前と重なるようで、JavaScriptに渡したときにキーが変更されてしまいました。それを避けるためにmail_subject、 mail_senderとしました)

AppleScriptのコマンドの使い方はユーティリティフォルダの中にある「スクリプトエディタ.app」の「用語説明を開く」で調べることができます。

* 次にアクション「JavaScriptを実行」を追加します。

```JavaScript
function run(input, parameters) {
	return JSON.stringify(input);
}
```

単純にJSONに変換するだけのアクションです。AppleScriptのレコードとリストは、相当するJavaScriptの連想配列と配列に自動的に変換されます。
（逆のJavaScriptからAppleScriptも自動変換されます）
この自動変換はマニュアル化されているかわかりませんでしたので、たまたまこのような機能があるだけかも知れませんので注意してださい。

JSONに変換するのではなく、ここにスクリプトを書いて必要な情報を書き出すこともできます。

* 最後に、アクション「シェルスクリプトを実行」を追加します。JSON形式のデータを読み込み、必要な情報をファイルに書き出しています。

```Ruby
require "json"
open("mail_list.txt", "a") do |fo|
	ARGF.each do |f|
		JSON.load(f).each do |message|
			fo.puts "#{message['mail_subject']}\t#{message['mail_sender']}"
		end
	end
end
```


(以下　2022.7.31 追記)

### クイックアクションへ変換
Automatorのメニュー ファイル -> 変換... でクイックアクションを選ぶと、Mail.appのサービスメニューから実行できるようになります。


![クイックアクション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171895/a67345d1-bf8e-e398-1136-79d54e9251c6.png)

検索対象をメール.appに変更しておきます。(この時起動しているアプリしか選べません)

作成したクイックアクションは ~/Library/Services/ に保存されます。
ショートカットは、システム環境設定のキーボートを開き、その中の ショートカット で設定できます。

### AppleScript部分をJavaScriptで書き換え
上のAppleScript+JavaScriptの部分を、JavaScriptだけで書くと次のようになります。

```JavaScript
function run(input, parameters) {
	let app = Application("Mail");
	let theSelected = app.selection();
	let theList = theSelected.map(theMessage => 
		({mail_subject: theMessage.subject(), mail_sender: theMessage.sender()})
	);
	return JSON.stringify(theList);
}
```

MacOS 12.5
MacBook Air (Retina, 13-inch, 2019) Inter CPU
go のコンパイラが死んだ (go 1.18.4)

# これは何？

go のコンパイラが死んだので報告。

# 殺す方法

以下のコードをコンパイルすると死ぬ。

```go:go1.18
package main

import "log"

type Obj interface{ Hoge() string }
type objType struct{}

func Send[T Obj](obj T) {
	func() { obj.Hoge() }()
}

func foo(o Obj) { Send(o) }

func (o *objType) Hoge() string {
	log.Println("objType.Hoge")
	return "objType.Hoge"
}

func main() { foo(&objType{}) }
```


実行結果はこう

```
$ go1.18.1 run main.go 
2022/07/30 20:12:04 objType.Hoge
$ go1.18.2 run main.go
2022/07/30 20:12:07 objType.Hoge
$ go1.18.3 run main.go
2022/07/30 20:12:10 objType.Hoge
$ go1.18.4 run main.go
# command-line-arguments
./main.go:9:19: internal compiler error: assertion failed

Please file a bug report including a short program that triggers the error.
https://go.dev/issue/new
```

ご覧のとおり、1.18.1 〜 1.18.3 は OK だったけど、1.18.4 だと死ぬ。

手元は Darwin(AMD64) なんだけど、たぶん x86_64 でも同じ。

ちなみに `Send` の定義を

```go:go1.18
func Send[T Obj](obj T) {
	obj.Hoge()
}
```

のようにすると死ななくなる。

なお。

上記のコードだけを見ると、最初っからそうしろよ、という話に見えると思うけど、これは可能な限り単純化した結果。もともとコンパイルしたかったコードは `func(){略}` の前にも後にも、 `obj.Hoge()` の前にも後にも色々あったりした。

# ちなみに

ちなみに

```
Please file a bug report including a short program that triggers the error.
https://go.dev/issue/new
```

というメッセージに従い、報告済み。

# go 1.18.5 と go 1.19

2022.8.4 追記。

go 1.18.5 と go 1.19 がリリースされたので試した。

```
$ go1.18.5 run main.go
2022/08/04 19:33:32 objType.Hoge
$ go1.19 run main.go 
2022/08/04 19:33:43 objType.Hoge
```

いずれも治っている。すばらしい。
アノテーションの形式(.txt/.xml)等の変換まとめ

最近アノテーションの形式を変更することが多く、そのツールを調べたりしていたので簡単にこちらに書いておきます。
https://github.com/pylabel-project/samples

![スクリーンショット 2022-07-30 20.33.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/29232cd1-4b8a-8448-c9f4-86dc646a199c.png)
alexheatさんが作っている.txtから.xmlに変えるツールなど（逆も可能）など様々な変換ツールです。
Colabでも動くようになっているので簡単にアレンジしてフォルダ下の一括変換などの用途に使っています。
Markdown記法について調べてみた

### 投稿背景
先日行われた「Qiita Conference 2022」を見て、早速触発されたので勢いで初投稿。
![スクリーンショット 2022-07-30 17.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737996/7d90fe4c-d7df-8ba3-13d4-88d8589ba94a.png)
↑
投稿に際して、Markdown記法で書いてね、と言われたので存在は知っていたものの詳しくは知らなかったので調べてみました。

# Markdownってそもそも何？
簡単に言えば
　**「デジタル文書の書き方のルール」**
だそうです。

特徴はこんな感じ。
> - 手軽に文章構造を明示できること
> - 簡単で、覚えやすいこと
> - 読み書きに特別なアプリを必要としないこと
> - それでいて、対応アプリを使えば快適に読み書きできること
>>引用：[日本語Markdownユーザー会](https://www.markdown.jp/)

# 開発者
フィラデルフィア生まれのジョン・グルーバー(John Gruber)さんによって、2004年に作られたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737996/8160c1c3-e031-fb46-beb9-ba13ce756152.png)
↑ [JohnさんのTwitter](https://twitter.com/gruber?lang=ja)アイコンです。
（[wikipedia](https://en.wikipedia.org/wiki/John_Gruber)でお顔も拝見しましたが、すごくやさしそうな方でした。）

# 使えると何がうれしいの？

Markdown記法に対応したサイトなどでこんなことが簡単にできちゃいます。

:::note info
見に来てくれてありがとう
:::
:::note warn
気をつけて帰ってね
:::
とか

| 1 | 2 | 3 |
|:-:|:-:|:-:|
|こんな|ことも|できちゃうぜ|
|いえい|いえい|いえい|

とか
```math
\left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq
\left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
```

とか

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```

とか

```plantuml
ぼく->外国人 : Hello!
```

とか、、、

 **（注）画像を貼り付けてるわけではないです**

こんな感じでMarkdown記法で書かれた文字列を変換してくれてるわけです。
![スクリーンショット Markdown 変換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737996/42da0a15-1ef2-1e4f-d709-9e3c88a81270.png)

いろんな表現が簡単にできちゃう。
Markdown記法すごい。。。


# Markdown記法の書き方
詳しく書いてくださった方がいらっしゃったので、こちらのリンクを参照してみてください。

[Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)
↑　一般的な記法。

または

[QiitaでのMarkdown記法詳細](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
↑　動画や数式の埋め込み、絵文字の記載など細かいニーズにも対応してくれてます。

# 使えるところ
ブラウザで使えるMarkdownエディタなるものもあるようです
- [StackEdit](https://stackedit.io/)
![スクリーンショット StackEdit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737996/3b02e6b4-0735-5e20-fd23-5f691a9f2154.png)
他にも
- Wordpress
- Github
- VScode
とかでも使えるらしいです（詳しくは[コチラ](https://codelikes.com/about-markdown/)の記事を参照）。

# まとめと感想
長くなっちゃいましたが、こんな感じです。
いろんな可能性を感じますね。。

一例として、日本の政府資料をMarkdownで書こう！みたいな話があるそうです。
基本的に政府資料はPDFとして公表されることが多いですが、これだと文字データが拾えないのでキーワード検索がかけづらく、情報アクセスが難しくなってるんだとか。。へー。

とまあ、この記事を書くにあたっていろんなサイトを調べましたが、知見が広がったようで楽しかったです。

また機会があったら、書こうと思います。では。


# 参考文献
1. [Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)
2. [QiitaでのMarkdown記法詳細](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
3. [日本語Markdownユーザー会](https://www.markdown.jp/)
4. [John Gruber - Wikipedia](https://en.wikipedia.org/wiki/John_Gruber)
5. [John Gruber - Twitter](https://twitter.com/gruber?lang=ja)
6. [Daring Fireball: Markdown](https://daringfireball.net/projects/markdown/)
7. [【ブラウザ専用】オンラインMarkdown(マークダウン)エディタ おすすめ4選 - NotePM](https://notepm.jp/blog/1147)
8. [StackEdit](https://stackedit.io/)
9. [Markdownとは？どこで使えるのか？【4つのサービスを実際に確認】](https://codelikes.com/about-markdown/)
ESXi環境でのAlmaLinux8.6初期設定

# はじめに
- ESXiにAlmaLinuxのVMを立てて設定しています。
- 他に必要な設定を学んだら追記します。

# インストール
1. ようこそ画面で使用する言語を選択します。
私は、日本語を選択しました。
2. インストール概要
・時刻を東京にあわせます。
・ソフトウェアの選択は、ベース環境を最小限のインストールにして、他のソフトウェアは標準のみをチェック。
・インストール先は選択するけど特に何も変更せず完了する。
・ネットワークとホスト名は、Ethernet接続がオフになっているのでオンにする。
　オンにすると、DHCPでIPアドレスが割り当てられる。
　サーバーのホスト名も変更可能。
・ルートパスワードを設定。
・ユーザーを作成。このユーザーを管理者にする、にチェックを入れておく。
上記設定ができたらインストール開始！
インストール完了すると、再起動するボタンが表示されるので、クリックして再起動します。

# ログイン
- ユーザー名とパスワードを入力してログインします。

# ルートユーザーになる
```
$ su -
Password: パスワードを入力してEnter
```

# dnfをアップデートする
```
# dnf -y update
もしくは
# dnf upgrade

Complete! と表示されたら完了
```

# 日本語設定
日本語パッケージのインストール（もしかしたら最初からインストールされてるかも）
```
# dnf -y install langpacks-ja
# localectl set-locale ja_JP.utf8
# source /etc/locale.conf
```
確認コマンド
```
# localectl
```

# Open VM Toolsのインストール
Open VM Toolsインストール（もしかすると最初からインストールされてるかも）
```
# dnf -y install open-vm-tools
```

# SELinux無効化
SELINUXのenforcingをdisabledに変更
```
# vim /etc/selinux/config
-----------------
SELINUX=enforcing
↓
SELINUX=disabled
-----------------
# setenforce 0
```
確認コマンド
```
# getenforce
```

# ネットワーク設定
IPアドレス等を設定します
ens192部分はネットワークデバイス名が入ります
```
設定コマンド
# nmcli connection modify ens192 ipv4.method manual
# nmcli connection modify ens192 ipv4.addresses 192.168.0.101/24 
# nmcli connection modify ens192 ipv4.dns 192.168.0.100
# nmcli connection modify ens192 ipv4.gateway 192.168.0.100
# nmcli connection modify ens192 ipv6.method ignore
# nmcli connection modify ens192 ipv4.may-fail no 

設定をアクティベート
# nmcli connection up ens192
```
確認コマンド
```
認識しているデバイスを確認
# nmcli device

デバイスの詳細を確認
# nmcli device show
# nmcli device show ens192
```

# 保守運用に使う機能をインポート
```
# dnf -y install traceroute
```
【ドメイン駆動設計】なぜ値オブジェクトそのものを比較できるようにしなければならないのか?

値オブジェクトは以下の3つの要素を持ったオブジェクトだとされている。

1)不変である(一度インスタンスが作られたら、それが保有する属性の値は変化してはいけない)
2)交換が可能である(再代入=交換によってのみ値を変更することができる)
**3)等価性によって比較される**

このうち、3)は絶対に必要なんだろうか?

例えば、Date型にかなり近い、YearMonth(年と月をもったオブジェクト)を定義してみよう。

```ruby
class YearMonth
  attr_reader :date

  def initialize(year, month)
    @date = Date.new(year, month, 1)
  end

end
```

一応値オブジェクトとして定義しているものの、「日付が1日のDate型オブジェクト」」としても外部から認識できる。なら、YearMonthそのものを比較できなくても、保有しているDate型(プリミティブ型)同士を比較すればいいんじゃないか?という疑問が生まれる。

実際にやってみよう。

```ruby

year_month1 = YearMonth.new(2022, 7)
year_month2 = YearMonth.new(2022, 8)

# 等価性比較
year_month1.date == year_month2.date
# →false
```

パット見問題なさそうに見える。が、

```ruby
0.value == 1.value
```

としているような気持ち悪さはある。両方Integer Objectなんだからシンプルに`0 == 1`でええやん。それと全く一緒の考えから、

```ruby
year_month1 == year_month2
year_month1 > year_month2
year_month1 < year_month2
```

で比較したらいい。

そして、もう一つ見逃してはならないこのルールの意図として、**変更に柔軟であること**が挙げられる。

例えば、この値オブジェクトにインスタンスが一つ追加されたことを考えてみる。

```ruby
class YearMonth
  attr_reader :date, :something

  def initialize(year, month, arg)
    @date = Date.new(year, month, 1)
	@something = Something.new(arg)
  end

end

year_month1 = YearMonth.new(2022, 7, arg1)
year_month2 = YearMonth.new(2022, 8, arg2)

# 等価性比較
year_month1.date == year_month2.date &&
year_month1.something == year_month1.something
```

この比較が一箇所ならいいが、等価性比較をしているすべての箇所で`&& year_month1.something == year_month1.something` を追加しなければならない。

ということで、**値オブジェクトを導入する際はオブジェクトそのものの等価性比較をできるようにすることがmustである**と言える。

```ruby
class YearMonth
	include Comparable

    def initialize(year, month, arg)
        @date = Date.new(year, month, 1)
        @something = Something.new(arg)
    end

	# 外部から呼び出す値
	def value
		@date.strftime('%Y.%m')
	end

	# 等価性比較のために必要なメソッド
	def <=>(other)
        @date <=> other.to_date # to_dateというメソッドを持つオブジェクトなら比較できると定義
    end

	# 同じYearMonthを比較できるように自身にもto_dateメソッドを実装しておく。
    def to_date
        @date
    end
end
```

今回の例だと、なにか変更があったとしても`def <=>(other)` を変更するだけで、YearMonth同士の比較を実際にしているところのコードは全くいじらなくていい。

DDD全体の良さの一つは「拡張性が高い」ことだが、値オブジェクトでも等価性比較ができるようにしておくことでこのオブジェクト自身が拡張性の高い状態になる。
3ステップで終わったWSL2とDockerの環境構築

# 目次
前置き
ステップ1 : WSLのインストール
ステップ2 : Dockerのインストール
ステップ3 : Dockerの設定
余談

# 前置き
Windows10でWSL2立ち上げてLinuxでDockerを使えるようにするまでの環境構築する方法です。

# ステップ1 : WSLのインストール

PowerShellを管理者権限で開いて以下の文を入力します。
```
wsl --install
```
実行が成功すると以下のようになるので、再起動するように。
![tmp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/76f61b3d-95d6-a1ef-a15b-c785a8733d8b.png)


# ステップ2 : Dockerのインストール
dockerの[ドキュメント](https://docs.docker.com/desktop/install/windows-install/)からインストーラーをダウンロードして起動する。実行結果は以下のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/fe00b44a-2094-7ee2-6811-11a46e9a54b5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/f4f80aa6-1f6c-4d0f-7856-c37c20dcad55.png)

close and log outをクリックすると自動的に再起動する。

# ステップ3 : Dockerの設定

dockerを起動させると、以下のような画面出るので、右上の歯車マークをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/647edf66-e882-a264-ea91-2649509932ba.png)

Use the WSL 2 based engineにチェックする。多分デフォルトでチェック入っていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/0d92379e-f01a-65bb-44e8-0053cc2bec24.png)

Ubuntuの項目をチェックする。これでWSL上のUbuntuでDocker使えるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2635057/68fbbfb7-f20c-5d57-8433-007240f0309d.png)

以上です！

# 余談

引っかからないなら、物凄い簡単に環境構築できるようになってて驚きでした。先人に感謝。

ちなみに私が引っかかったのは、以下2点。
・wsl --installができるのはwslが入ってない場合だけらしい。wslが既にあるならアンインストールすること
・仮想化の有効ができなくてBIOSで解除した

まっさらな環境なら今回の手順で問題なくできるはず...？
【 React Native】ExpoでWebをビルドする際にルートのパスを設定したい

## 概要
[Expo](https://expo.dev/)というツールを使うと、React NativeでWebサイトのビルドを簡単に出来ます。
ビルドしたファイルを例えば`https://example.com/samplebuild`のような感じで、URLのパスの`sampleBuild`配下に配置したいという時もあるかと思います。今回はこのパスの設定の仕方をメモ書きします。

## 対応
Expoのドキュメントの[Publishing Websites](https://docs.expo.dev/distribution/publishing-websites/)にパスを設定する方法が書いてあります。`package.json`の`homepage`の項目に設定すれば大丈夫です。ドキュメントに書いてある通り、以下のように設定します。

```json:package.json
{
  "homepage": "/samplebuild"
}
```
Solidityで面白いと思った点列挙

CryptoZombiesでSolidityチュートリアルやる中で、面白いと思った点をメモ。（適宜追記）

・一度デプロイしたコントラクトは、チェーン上に乗ってしまうと変更・削除できなくなってしまう（だから、セキュリティには細心の注意が必要）
    改ざんできないということであり、それこそがブロックチェーンアプリの堅牢性を象徴する性質とも言える。
    ⇒後で変更しなければいけないような値は、set()関数で設定するようにしておく

・プログラム実行条件として、require()句を設定できる。条件を満たさないと、処理を中断できる。（レベル制限などの実装用）
Bash: Yahoo 郵便番号検索API の使い方

参考ページ
[郵便番号検索API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/zipcodesearch.html)

```bash:get_postal.sh
#
APPID='dj0zaiZpPW9NN3F****'
URL='https://map.yahooapis.jp/search/zip/V1/zipCodeSearch'
ZIP_CODE=$1
echo $ZIP_CODE
#
http GET $URL"?query="$ZIP_CODE"&appid="$APPID"&output=json" > tmp01.json
#
jq .Feature[0].Property.Address tmp01.json
```

実行結果

```text
$ ./get_postal.sh 131-8634
131-8634
"東京都墨田区押上１－１－２東京スカイツリーイーストタワー１１Ｆ"
```
【React Hook Form】Controllerの中でonChangeを使うときの注意点

## 概要
以下の記事からその方法を教えてもらった。（ありがとうございます。）
ただ、一点注意点があって、解決に時間がかかったのでシェア。


https://qiita.com/tashinoso/items/ce2cb7aaffaaa56e42ff



## プロパティの順番が大事

{...field}がonChangeの後に記載されていると動かなかった。
前に記載しないとダメ。

```javascript:
// これだと動かない。
<Controller
  control={control}
  name="email"
  render={({field}) => (
    <TextField
      onChange={(e) => {
        field.onChange(e)
        handleOnChange(e)
      }}
      {...field}
    />
  )}
/>
```

```javascript:
// これで動く
<Controller
  control={control}
  name="email"
  render={({field}) => (
    <TextField
      {...field}
      onChange={(e) => {
        field.onChange(e)
        handleOnChange(e)
      }}
    />
  )}
/>
pxをViewport Widthに変換するStylus関数

pxをViewport Widthに変換するStylusの関数をつくった


```s
//基準となるwidth(単位はpx)
baseWidth =

px-to-vw(px)
vw = 100 / baseWidth * px
unit(vw, 'vw') //'vw'という文字列を末尾につける。vwの数値だけを返したい場合は削除
```

# Usage
1.基準となるwidth(単位はpx)を設定し、関数を記述

```s:_setting.styl
baseWidth = 1400

px-to-vw(px)
vw = 100 / baseWidth_pc * px
unit(vw, 'vw')
```

2.変換したいpxを引数に与えて関数を呼び出す

```s:style.styl
p
  font-size px-to-vw-pc(16)
```

3.Stylusをコンパイル。CSSにvwとして出力される

```css:style.css
p {
  font-size: 1.142857142857143vw;
}
```

# 今後の課題
- 負の値にも対応する
PHP: Yahoo 郵便番号検索API の使い方

参考ページ
[郵便番号検索API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/zipcodesearch.html)

ライブラリーのインストール

```bash
composer require guzzlehttp/guzzle
composer require vlucas/phpdotenv
```

```php:get_address.php
#! /usr/bin/php
<?php
// ------------------------------------------------------------------
require_once 'vendor/autoload.php';

fputs (STDERR,"*** 開始 ***\n");

$CODE_POSTAL = $argv[1];

echo $CODE_POSTAL . "\n";

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$APPID = $_ENV['APPID'];

$client = new GuzzleHttp\Client();
$URL_BASE = 'https://map.yahooapis.jp/search/zip/V1/zipCodeSearch';
$URL = $URL_BASE . "?query=" . $CODE_POSTAL . "&appid=" . $APPID . "&output=json";

$res = $client->request('GET', $URL);

echo $res->getStatusCode() . PHP_EOL;

// echo $res->getBody() . PHP_EOL;

$contents = (string)$res->getBody();
$dict_aa = json_decode ($contents,true);
 
// print($contents);

// var_dump($dict_aa['Feature'][0]['Property']['Address']);
echo $dict_aa['Feature'][0]['Property']['Address'] . "\n";

fputs (STDERR,"*** 終了 ***\n");
// ------------------------------------------------------------------
?>
```

```text:.env
APPID = 'dj0zaiZpPW9NN3F****'
```

実行例

```text
$ ./get_address.php 131-8634
*** 開始 ***
131-8634
200
東京都墨田区押上１－１－２東京スカイツリーイーストタワー１１Ｆ
*** 終了 ***
```

>この結果は誤りの可能性があります。東武タワースカイツリー株式会社は、19F です。
[東武タワースカイツリー株式会社 (スカイツリー)](https://www.tokyo-skytree.jp/company/)
Pythonが嫌いなのでC++版のPytorchで画像認識をやってみる 3日目

# 昭和のおじさんは動じない
前回から日が開いてしまった。
↓このエラーメッセージで躓いた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/17d52453-4e3b-5665-0486-906877bdbdff.png)
おそらく親クラスかメンバ変数の中にテンプレートがあって、インスタンス生成時にエラーが出る可能性が高いのだろう。要するにメモリサイズが不定なわけだ。こんなものは動的メモリ確保で一発である。昭和のおじさんはこんなエラーメッセージで動じないのだ。

# new宣言してやればいい
動的メモリ確保は変数をポインタにしてコンストラクタでnew宣言してやればいい。newでメモリ確保したら、使用後はdeleteで開放してやる。メモリをきっちり管理するのはプログラミングの基本だ。
```c++:c++
class Net : torch::nn::Module
{
public:
    torch::nn::Conv2d* conv1;
    torch::nn::MaxPool2d* pool;
    torch::nn::Conv2d* conv2;
    torch::nn::Linear* fc1;
    torch::nn::Linear* fc2;

    Net();
    ~Net();
};

Net::Net()
{
    torch::nn::Module();
    conv1 = new torch::nn::Conv2d(1, 6, 5);
    pool = new torch::nn::MaxPool2d(torch::nn::MaxPool2dOptions({2, 2}));
    conv2 = new torch::nn::Conv2d(6, 16, 5);
    fc1 = new torch::nn::Linear(16 * 16, 64);
    fc2 = new torch::nn::Linear(64, 10);
}
Net::~Net()
{
    delete conv1;
    delete pool;
    delete conv2;
    delete fc1;
    delete fc2;
}

int main() 
{
    Net net1;
    std::cout << *net1.conv1 << std::endl;
    std::cout << *net1.pool << std::endl;
    std::cin.get();
}
```

↓コンパイルエラーも出ないし、リンクも正常。実行時エラーも出ない。
昭和のおじさんは動的メモリ確保など朝飯前なのだ。
```
E:\Programing\TorchProject1\TorchProject1\x64\Debug>TorchProject1.exe
torch::nn::Conv2d(1, 6, kernel_size=[5, 5], stride=[1, 1])
torch::nn::MaxPool2d(kernel_size=[2, 2], stride=[2, 2], padding=[0, 0], dilation=[1, 1], ceil_mode=false)
E:\Programing\TorchProject1\TorchProject1\x64\Debug>
```
# コードが美しくない
それにしてもコードが美しくない。メンバ変数の型の種類が多すぎるような気がする。ストリーム演算子はうまくオーバーロード機能が働いているようだが気持ち悪い。継承しているなら共通している親クラスがあるだろう。変数は正しい型で記述するのがCの作法である。昭和のおじさんは行儀が良いのだ。実はMaxPool2dOptionsてのはGoogle先生にきいて出てきたコードをコピペしただけで意味が分かっていない。{2,2}みたいな記述も気になる。こんな表現C++にあったっけ・・・
エラーメッセージにあった記述↓もひっかかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/d251bf10-dbd3-e0f1-8aee-9aeeacfaa2f7.png)
nullptrなんて予約語は知らない。

# 公式サンプル
コードが適当になってきたので、このまま進むのは危ない。やはり先人の知恵を借りたい。というわけでサンプルコードを検索してみたら公式サンプルらしきものが出てきたぞ。↓
https://github.com/nuka137/pytorch-cpp-example/tree/6d82b0240af6cb33af015e30b01ee3f0fc3deec2/resnet/cpp

今日はここまで
つづく

https://qiita.com/pipimaru1/items/38e4846e8fb5342ff49f
Twitter APIのアクセスキーを取得する

TwitterのWebAPIを使用する為のアクセスキーの取得方法について説明します。


１．以下のURL(Twitter Developers)にアクセスする。

https://developer.twitter.com/en/apps

:::note info
ログイン画面が表示される場合、アクセスキーを取得したいアカウントでログインしてください。
同様に使用するアカウントと異なるアカウントでログインしてしまった場合、ユーザを切り替えてください。
:::

２．画面左上にある、「Create an App」ボタンを押下する。

![0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/5e11251e-589e-b81e-c53d-fcb4d0bf8069.png)

次のポップアップが表示された場合、Apply(適用)を押下して先に進んでください。
![0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/704ae5fa-25d0-c047-b0ae-c17c63d1bdb0.png)

:::note info
ざっくり、「あたなのアカウントは開発者用のアカウントではないよ。既存のアカウントでもアプリの管理は出来るけど開発者として申請してね。」的な事が書いてあります。
承諾できる人はApplyを押下して先に進んでください。
:::

３．TwitterAPIの利用目的を入力する。
　赤枠の項目を入力し、「Let’s do this」ボタンを押下する。
画像入力内容は参考例。自身の利用目的に近い項目を選択してください。

![0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/6fe57fd0-153e-571b-fee1-1d757741a292.png)

４．利用規約を承諾する。
　開発規約が表示されるので内容を確認の上、合意の場合、「Accept Terms & Conditions」を選択にし、「Submit」ボタンを押下する。

![0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/c85f0a2f-cf39-c7d7-e5de-a1e9ccbf16c4.png)

:::note info
ちゃんと目を通して欲しいですが、最低ライン認識すべき、II. Restrictions on Use of Licensed Materials(ライセンス対象物の使用制限について)の搔い摘んだ内容を記載します。
・TwitterAPIを解析しようとするのはダメ。
・TwitterAPIをぶっ壊そうとするのはダメ。
・作ったものを誰かに譲渡したり、アクセス権を渡すのはダメ。
・著作権物を勝手に使ったらだめ。また、著作権のあるものを集めるのにAPIを使っちゃダメ。
・人の作ったAPIを邪魔するようなAPIを作っちゃダメ。
・収集した情報を商売に使っちゃダメ。
・非商用で登録している場合、商用利用しちゃダメ。
・ユーザの監視とかアカウント数の計測に使用しちゃダメ。
・TwitterAPIの使用回数制限を極端に超えるアクセスをしちゃダメ。やったら永久にアカウント停止する。
・Twitterコンテンツの位置情報は使うとき以外保存しちゃダメ。集計とかキャッシュにして保持するのはダメ。
・Twitterのロゴを勝手に使っちゃダメ。
・TwitterAPI等ログイン情報を他人に渡しちゃダメ。
:::

:::note warn
筆者環境では、Submitを押下した際にエラーが発生しました。
Twitterアカウントに電話番号を紐づけていないことが原因でした。
もし、エラーが表示される場合は、使用するTwitterアカウントについてプロファイルを更新してみてください。
:::

５．Developer　Potalよりアプリの登録を行う。
　Twitterアカウントと紐づくメールアドレスに、確認メールが届くので、メール内の「Confirm your email」をクリックすると、登録が完了となります。

![0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/9c539810-3b88-851d-348a-02c25ffa2b75.png)

６．アプリケーションキーの払い出しを行う。
App nameに任意の名称(自分が作るアプリ名)を入力し、「Get Keys」ボタンを押下する。

![0009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/38fafb47-ac45-b817-28fc-e7c197315a5b.png)

アプリケーションに対するキーが払い出されました。
このハッシュ値を保存しておいてください。

![0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317688/18ee3090-f63f-dd2c-568f-a1bca1ae3285.png)
久しぶりにPostgre使おうとしたらエラー出た時の対応メモ

# 前提
```
$ sw_vers
ProductName:	macOS
ProductVersion:	12.3.1
BuildVersion:	21E258

$ psql --version
psql (PostgreSQL) 14.2
```

# エラー
```
$ psql -l
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?
```

# ログ確認
```
$ less /usr/local/var/log/postgres.log
=>
...
2022-07-30 17:28:36.811 JST [20718] FATAL:  lock file "postmaster.pid" already exists
2022-07-30 17:28:36.811 JST [20718] HINT:  Is another postmaster (PID 975) running in data directory "/usr/local/var/postgres"?
...
```

公式情報で、ログ出力ファイルのデフォルトパス見つからなかった :thinking: 
設定ファイル（`/usr/local/var/postgres/postgresql.conf` の `REPORTING AND LOGGING`）では特に設定していない

Postgreが正常終了しなくて、PIDファイルが残っていて起動できなかったよう

# 対応
```
$ rm /usr/local/var/postgres/postmaster.pid
$ psql -l
=>
...
```

起動できた

# 参考
- [同じ事象の調査記事](https://k-koh.hatenablog.com/entry/2020/07/13/115340)
- [基本的な調査の流れ](https://gist.github.com/taea/8865831)
- [ログ記録場所](https://www.web-dev-qa-db-ja.com/ja/postgresql/postgresql%E3%81%AFmac-os-x%E3%81%AE%E3%81%A9%E3%81%93%E3%81%AB%E3%83%AD%E3%82%B0%E3%82%92%E8%A8%98%E9%8C%B2%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/968202054/)
- [ログ設定](https://www.postgresql.jp/document/9.4/html/runtime-config-logging.html)