OmniAICreator/Qiita-1.07M huggingface dataset:
002_デザイン素人が団体のロゴを考えてみる話（進行中）

# ロゴデザインを考えよう

## 0. 前回までのおさらい
農業農村工学サマーセミナーという団体のロゴを作ろう
できれば無料で

https://sites.google.com/view/n-n-summer-seminar
## 1. イメージを固める
NNの魅力（実学、歴史、スケールのでかさ、ロマン、自然、食料自給、インフラ整備、災害防止）
Think Globally, Act Localy.
若々しさ←NEW!!

## 2. 情報収集
ロゴの印象＆モチーフを決める、情報量を絞る

https://321web.link/logo/#index_id0

手書きの下書きが大事

http://imamagininal.com/archives/6607

ロゴデザインの主な種類（幾何学模様、文字、簡略＆概念、余白、色）

https://goodpatch.com/blog/logo-design-inspiration

## 3. 実践（本編ここから）
1.および2.を踏まえて、実際にロゴのアイデアを考えてみます。
なお、使用ツールとして想定しているのは
Microsoft PowerPoint
Microsoft Excel
Inkscape
の3点です。とはいえ、個人的にデジタルイラストよりもアナログイラストの方が手軽にできるので、本日は色鉛筆でお絵描きしてみようと思います。

情報収集にて発見した<https://321web.link/logo/#index_id0>
を参考に、印象＆モチーフ＆色＆ストーリーを決めます。
#### 印象
温かみのある、スタイリッシュな
#### モチーフ
河川、自然、農村、人、
NNの文字（のうぎょうのうそんこうがくの略称、なんで工学を省いたんだよ……）
#### 色
アースカラー（緑、青、茶、オレンジなど自然界の色味をイメージ）
白黒印刷に耐える色
#### ストーリー
「農業農村工学ってすごいんだなあ（小並感）」

##### おや？いろいろとまとめるのが難しいぞ？？
なんということでしょう。前回ダニングクルーガー効果が観測され、
「デザインかなりわかる」状態であったにもかかわらず、実際に自分の手を動かすことで
「デザインわからない、むずかしい」状態になってしまいました。
（ダニングクルーガー効果について考えれば、これは良い傾向です。この先は地獄だで。。。）

特に初っ端、「温かみのある」かつ「スタイリッシュな」ってどないやねん。
プロなら2つの要素を組み合わせることができるのでしょうが、いかんせん素人なもので……

今日はプロトタイプとして、以下の3要素のみ拾い上げて考えてみます。
「スタイリッシュな」「NNの文字」「水色」

### 下書き開始
さあ、楽しいお絵描きの時間です。
山、川、野原、水田、畑を描いてみたり、YouTubeで気を紛らわしたりしつつ、
ある程度方向性を決めました。
##### 「NNの文字を河川の流れに見立ててみよう」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1699005/fb84154d-ed3f-21f0-d7a2-b6727a05f77c.png)

参考元（パクリ元）はマイナビ転職のロゴ（Mのおしゃれな筆記体？）です。

https://tenshoku.mynavi.jp/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1699005/4cc0e602-84fd-bed6-b9d7-ae131b00d97d.png)

「これかなり川っぽいな」というところから、NNをつなげた河川を書いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1699005/81b4760c-07ff-a8f5-47b0-b626d9fd159f.png)

これを…こうして（PowerPoint）…こうじゃ！！

## 4. 完成（ひとまず）
ということで、ロゴマーク1号が完成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1699005/dc4b95c0-3571-b77d-94c7-c141a741a7b6.png)

いかがでしょう。スタイリッシュ＝無彩色、加えて空の青さを表現したつもりです。
今後、「温かみのある」「アースカラー」版も作ってみたいですね。
成果物を作れば作るほど、生みの苦しみが増えていくことでしょう。お絵描き楽しい。

それでは次回、「003_デザイン素人が団体のロゴを考えてみる話」でお会いしましょう。
ごきげんよう。

## 参考資料
https://tee-916.com/2018/11/02/ppt_illust/
json-serverのserver.js起動でエラーになった件

json-serverでserver.jsを起動しようとしたらエラーになったので、解決策をメモ。
- - -
以下コマンドでserver.jsを起動しようとした所・・・
```
node server.js
```
以下のエラー。
```
node:internal/modules/cjs/loader:1042
  throw err;
  ^

Error: Cannot find module 'json-server'
```
調べてみたら同じエラーが出たという以下サイトが見つかった。

https://qiita.com/wattak777/items/488278a80d47b03f928c

>で、色々調べてたら、コレがヒントに。
>https://github.com/typicode/json-server/issues/454
>要はnpmで取ってきたjson-serverのパスがNODE_PATHに当たっていなかったってことか。
>ってことで、改めて環境変数を取ることに。
C:\work\Dummy_Rest> npm root -g
C:\Users\wattak\AppData\Roaming\npm\node_modules
C:\work\Dummy_Rest> set NODE_PATH=C:\Users\wattak\AppData\Roaming\npm\node_modules
その後 node コマンドによる global.module.paths で上記設定されたパスが入っていることを確認すると。。。
C:\work\Dummy_Rest> node server.js
Dummy REST API is running.
と、無事起動しましたとさ。

しかしその通りやったものの私の環境(Mac)ではうまくパスが入らず。
さらに調べて以下サイトを発見。

https://note.com/cessial6/n/ncc12e493fac4

以下のやり方でいきました（Macだから最初のサイトのやり方でうまくいかなかったのかな？）

>※ Macの場合は、ダブルクォーテーションだとNODE_PATH = npm root -gとなるのでで以下のようにすること。
```
// .bash_profileに設定
NODE_PATH=`npm root -g`
export NODE_PATH
```

以上でserver.jsが起動できました！
```
% node server.js
JSON Server is running
```
Virtualboxをインストール

こんにちは！
本日はVirtualBoxをインストールして仮想環境を構築する準備をしていきたいと思います。

## 1.VirtualBoxをダウンロード
[ORACLE社公式ページ](https://download.virtualbox.org/virtualbox/6.1.36/VirtualBox-6.1.36-152435-Win.exe)からVirtualBoxのインストーラーをダウンロード

## 2.インストール
**ダブルクリックでインストーラーを実行**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/21deadbc-7b47-50bf-e6bd-a666342df5ab.png)

**実行したインストーラーで[Next]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/f54f1e5c-b123-5f46-fc3c-6693789c66cc.png)

**[Next]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/6c607ec9-f2e2-f7db-8912-c196fd82d0d5.png)

**[Next]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/7fd151b1-b9fa-b44c-290d-7bb19a30778b.png)

**[Next]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/61119314-c876-8ff2-da43-d57c41395127.png)

**[Next]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/5d689754-47f7-642a-2b0e-65a152cfd2e0.png)

**インストール実行中**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/4b223db5-97ef-dd04-650d-90fd304a1876.png)

**[Finish]をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/ebe672f6-2368-a740-b0dc-6d706c90fdb7.png)

**VirtualBoxを起動**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/52d072eb-76f2-38d0-651b-33b8df3341cc.png)

**インストール完了！！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/c5c7ac78-0461-1830-1f02-6a3a3586721f.png)
ペアプログラミングのメリット・デメリット

## 背景
　これからペアプログラミングを行なうことになったため改めてペアプロについて調べて
メリット/デメリットをまとめてみた

## ペアプログラミングとは

- 2人のプログラマーが同じコンピューターを使用して同じプログラムを作成する方法
    ドライバー（コードを書く人)/ナビゲーター(指示する人)に分かれるパターンや
    テストを書く人/テストに通る実装を行う人に分かれて毎回その役割を交代するパターン
    があるみたいです。


## メリット

- **コードの質向上**
　ソロプロで開発を進めている場合プルリクエスト後のコードレビューの際、実装者がなぜそのような実装をしたのかのWhyの部分がわかりづらいため、コード仕様上問題あるコード以外の指摘がレビューから漏れて潜在的なバグになることもある。
また、ペアプロにより思考を共有することでなぜそのコードが書かれたのかという過程を知ることができるのでコードに対してより深い議論をペアと行うことができ、潜在的バグの発生が抑えられコードの質が向上する。
さらに、常にペアに見られるていることを意識したコードを書くようになる。


- **コードレビューが端折れる**
　変更量の多いコードレビューはレビュワーの負担になるがペアプロを行うことで実装しながらコードレビューが行えるためレビュワーの負担が軽減される。
※開発現場においてはペアプロをしつつコードレビューもするところもあるみたいです。

- **学習の効率up**
　ソロプロだとわからないことに一人で悩む時間が多くなり無駄な時間を過ごしがちだがペアプロの場合相方が理解していることならその場ですぐに教えてもらえるので調べるコストがかからず効率的。
他にもしょうもない文法ミス、設定ミスがあっても他の人が見ればすぐに解決するパターンが多い。無駄な時間を過ごさなくて良くなり、本来のコーディングに集中できる。


- **チームワークの向上**
　ペアプロによりチームメンバーとコミュニケーションをとることができチームワークの向上につながる。



## デメリット

- **高コスト**
　単純にリソースが2人分必要になる。
※ペアプロによるコードの質、効率化を踏まえるとペイできるという考え方もある。

- **コミュニケーションのハードルが高い**
どちらか片方でもコミュニケーション能力が欠如している場合、作業効率が低下する。

- **スケジュール管理や調整が難しい**
　ペアと予定を合わせる必要がある。

- **初心者同士ではメリットがほぼない**
　正しい指示や正しいコーディングがわからない状態での作業になるため

- **スキル差のある場合は退屈になる**
　上級者にとって一方的に教えるだけの簡単な作業になってしまいがち。
※初級者にもわかりやすく教えることで自分の知識をより深めることもできる



## まとめ
メリデメは色々あるが上級者-初級者ペアでの人材育成には最適。
そしてとにかくコミュニケーションが大事。リモートだと特に顔や声から相手の
理解度を読み取ることが困難（マスクしてると尚更）なため積極的な
意思表示（相槌や質問するなど）が大事。
とりあえず自分は足引っ張らないようタイピングの練習しようと思いました。

## 参考
これ面白かったです

https://qiita.com/chieping/items/6698b274c8da69b443f8
Flutterで、より厳しいLintを使おう

# FlutterのLint

Flutter v2.5以降では、 `flutter create`で新規作成したプロジェクトでは、デフォルトでは、`flutter_lint`というLintルール集が用いられる。
この`flutter_lint`では、[Lintで設定できるすべてのルール 209個](https://dart-lang.github.io/linter/lints/index.html)のうちの、９７個(46.4%)しか設定していない。

もちろん、相反するルールもある(例えば、[prefer_single_quotes](https://dart-lang.github.io/linter/lints/prefer_single_quotes.html)と[prefer_double_quotes](https://dart-lang.github.io/linter/lints/prefer_double_quotes.html))ので、すべてのLintオプションを設定することはできないが、より多くのルールを課することは、一貫したコーディングスタイルを実現できるので、特にチームでの開発では重要だと、個人的には思っている。

`analysis_options.yaml` にルールを追加していくことも可能だが、一つ一つ取捨選択するのは大変なのです。
そこで登場するのが、OSSのLintルール集です。
有名なものに、次の２つがあります。

* [Lint](https://pub.dev/packages/lint) : 151 (72.2%)
* [very_good_analysis](https://pub.dev/packages/very_good_analysis) : 184 (88.0%)

があります。
それぞれで、どのLintルールが設定されているがをみたい場合は、[Google Sheet](https://docs.google.com/spreadsheets/d/1Nc1gFjmCOMubWZD7f2E4fLhWN7LYaOE__tsA7bf2NjA)を見てください。

導入の仕方は、どちらもほぼ同じです。例えば `Lint`の場合、


```yaml:pubspec.yaml
dev_dependencies:
  # lintパッケージを追加
  lint: ^2.0.0  

  # flutter_lintsパッケージは削除
  # flutter_lints: ^2.0.0   
```

```yaml:analysis_options.yaml

# flutter_lintsの設定は削除
#include: package:flutter_lints/flutter.yaml

# lintの設定を追加
include: package:lint/strict.yaml # For production apps

linter:

  rules:
    # Util classes are awesome!
    # avoid_classes_with_only_static_members: false
    
    # Make constructors the first thing in every class
    # sort_constructors_first: true

    # Choose wisely, but you don't have to
    # prefer_double_quotes: true
    # prefer_single_quotes: true
```

足らないルールは、`linter.rules` に記載していきます。


参考
https://rydmike.com/blog_flutter_linting.html
モンテカルロ法で円周率を求める場合の考え方メモ

勉強会で[問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本](https://gihyo.jp/book/2022/978-4-297-12521-9)を読んでいる。
モンテカルロ法の節が一回では理解できなかったのでメモ。

## モンテカルロ法とは

- 数値計算の手法の一つ。
	- ランダムな数を使う。
- [ジョン・フォン・ノイマン](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A7%E3%83%B3%E3%83%BB%E3%83%95%E3%82%A9%E3%83%B3%E3%83%BB%E3%83%8E%E3%82%A4%E3%83%9E%E3%83%B3 "ジョン・フォン・ノイマン") が名付けた。
	- モナコ公国の都市モンテカルロから取った。
		- カジノで有名な都市とのこと。

https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%AB%E3%83%AB%E3%83%AD%E6%B3%95

## 考え方
- 辺の長さが1の正方形
- 正方形の中のランダムな位置に点を打つ
- 正方形の左下の角を中心とする半径1の円の内側に入った点の数を数える
	- 半径は正方形の辺の長さと等しい
- 正方形の面積は
$$1\times1 = 1$$
- 正方形内の円の面積は円の面積の4分の1なので、
$$(1\times1\timesπ)\div4 = \dfrac{π}{4}$$
- 正方形の面積のうち、正方形内の円の面積が占める割合は
$$\dfrac{π}{4}\div1=\dfrac{π}{4}$$
- 面積の割合と点の数の割合は等しくなるはずなので、
$$\dfrac{π}{4}=\dfrac{正方形内の円の内側の点の数}{点の総数}$$
## 実装
Goで実装してみた。
```go
package main

import (
	"math/rand"
	"fmt"
	"time"
)

func main() {
    fmt.Printf("%f\n",solve(10000))
}

func solve(n int) float64 {
	rand.Seed(time.Now().UnixNano())
	var m int
	var i int
	for ; i < n; i++ {
		x := rand.Float64()
		y := rand.Float64()
		// ルート1.0 より大きい値は、必ず1.0より大きいのでSqrt不要
		distance := (x*x+y*y)
		if distance <= 1.0 {
			m++
		}
	}
	return 4 * (float64(m) / float64(n))
}
```

2023.01.28 [コメントでの指摘](https://qiita.com/ss49919201/items/6beec6223a27e8f7f1df#comment-b2ab6a45c05cf4919ae4)を反映
CloudFront 経由で LiveWire を使う場合はヘッダーに気をつけよう

タイトルの通りなんですが、最近の CloudFront はポリシーを当ててリクエストヘッダーやレスポンスヘッダーを操作できるようになっています。
フルでヘッダーを通す、とかでない場合は `x-livewire` と `x-csrf-token` 辺りを解放しておかないと 419 Page Expired になって帰ってきます。

```
This page has expired due to inactivity. 
Would you like to refresh the page?
```

恐らくこんなエラーが出てると思いますので、そんな時は LiveWire が通信する時の HTTP ヘッダーがきちんと通過できているかのチェックをお忘れ無く。
【Linux】ファイルの空行を削除する方法

## すべての空行を削除

### `grep`コマンド

`grep`コマンドを使用して次のように実行することですべての空行を削除して出力できます。  

```terminal
grep -v '^$' ファイルパス
```

```terminal
$ cat sample.txt
sample

sample

sample

sample

sample

$ grep -v '^$' sample.txt
sample
sample
sample
sample
sample
```

### `sed`コマンド

`sed`コマンドを使用して次のように実行しても上記同様の結果が得られます。

```terminal
sed '/^$/d' ファイルパス
```

```terminal
$ sed '/^$/d' sample.txt
sample
sample
sample
sample
sample
```

## 連続する空行を1行にする

空行が連続している場合に空行を1つにまとめるには`cat`を使用して次のように実行します。  

```terminal
cat -s ファイルパス
```

```terminal
$ cat sample.txt
sample



sample




sample
$ cat -s sample.txt
sample

sample

sample
```
【SQL】REPLACEした文字列の比較をしたけどJSとPHPのようにはいかなくて冬

少しだけハマったので備忘録含め記事にする。

## ハマったこと
本日こんな感じのSQLを作成しました。（色々簡略化はしてます。）


```sql
SELECT shop_id,name,close_time
FROM `shops`
WHERE REPLACE(close_time, ':', '') > '2000'
```

close_timeというのはお店の閉店時間。
db上には「19:00」とか、「22:00」とか、文字列で保管されてます。
replaceすることで、1900とか、2000とかになります。

replace参考：https://www.javadrive.jp/mysql/function/index44.html

'2000'はアプリで入力された時間。文字列。
なので、2000と1900や2200を比較してました。

が、何度やってもうまく判定ができず。
時間によってはうまく行ったりするのでなんでだろ〜？となっていましたが、
SQLでの数字の比較においては基本的にちゃんと数字でやる必要がありました。


## 解決策

```sql
SELECT shop_id,name,close_time
FROM `shops`
WHERE cast(REPLACE(close_time, ':', '') as SIGNED) > cast('2000' as SIGNED)
```

このように、cast(xxxx as SIGNED)とすることで、xxxxを数値に変換可能です。
cast参考：https://www.javadrive.jp/mysql/function/index51.html#section1

数値同士できちんと変換しよう、というお話しでした。

ここんところjsやphpが8割、2割くらいがSQLいじりだったので、完全にjsやphpの”==”によるよしな比較のノリでいて、気付くのに時間がかかりました。
データベースにおけるインデックスとは

 ## SQLの実行とパフォーマンス
 ユーザーがSQLを実行しテーブルからデータを取りに行くときにユーザーは取りに行くデータを指定するが、取りにいくルートを指定することはない。そのルートによってデータベースのパフォーマンスに大きく影響する。ルートを最適化することによってパフォーマンスを挙げることができる。そのルートを選択する方法に**インデックス設計**がある。
 - SQLパフォーマンスを改善するにはインデックス設計をする
    - **アプリケーション透過性**：インデックスに指定によってアプリケーションへ影響することはないため、優れた手段である。
    - **データ透過性**：インデックスによってデータの中身や構造が変わることはないのでデータに対しても優れた改善手段である。
    - **大きな改善効果**
   
DBを使用したことのある人ならば誰しもがパフォーマンスを気にしたことがあると思います。各DBによってチューニング方法はありますが、インデックスのようにどのDBにも共通で存在しているチューニング方法を知っておくと、パフォーマンス改善を求められたときに対策できる一つのアイデアになるかもしれません。

## B-treeインデックス
インデックスの種類は様々あるが、一番最初はB-treeインデックスを使用する。B-treeインデックスは他のインデックスに対して平均点の高さ（満遍なく性能が良い）が優れている。
- **均一性**：各キー間で検索速度のばらつきが少ない
- **持続性**：データ量の増加に対してパフォーマンスの低下が少ない
- **処理汎用性**：検索などのいずれの処理に対してそこそこ早い
- **非等値性**：不等号を使用してもそこそこ早い
- **親ソート性**：GROUP BYなどのソートに対する処理に対してそこそこ早い

### B-treeインデックスの設計方針
具体的にどのようなデータベースに対して設計するか
- 大規模なテーブルに対して作成する
- カーディナリティの高い列に作成する
- SQL文でWHERE句の選択条件、または結合条件に使用されている列に使用する

データ量が少ない場合はインデックスの効果はなくなる。
B-treeインデックスの作成の際はカーディナリティが多いテーブルに対して作成するのが効果的。カーディナリティとは行の数。インデックスは列に対して作成して、SELECT文などの実行速度を上げる。
- カーディナリティの注意点  
    - 複数列に対してインデックスを作成する際はカーディナリティは複数列が対象になるということを意識する。
    - カーディナリティが高くても特定の値にデータが集中してるような列に向いていない

### その他注意事項
- 主キーや一意制約の列には不要  
内部的にすでにB-Treeインデックスが作成されている。
- インデックスは更新性能を劣化させる  
インデックスを設定したデータを更新するとき、インデックスの更新も必要になるため更新性能が劣化してしまう。
- 定期的なメンテナンスが必要になる  
データの更新などが長期的に続くと構造が崩れてしまうため、インデックスの再構築など性能を維持するためにメンテナンスが必要になる。

インデックスの作成しパフォーマンスを上げるには一定の条件はあるものの、試してみてパフォーマンスの変化を試してみるのも面白いかもしれません。テーブルやデータの内容に大きな影響を与えないということも試しやすい理由の一つです。自身の使用しているDBのインデックスの作成の仕方を調べて実装してみましょう！！

## まとめ
インデックスを作成することでSQLのパフォーマンスを向上させ、アプリケーションの性能の向上にまでつながる。インデックスは列に対して作成することでSELECT文やJOIN句などの重い処理の速度を上げることができる。最もメジャーなインデックスとしてB-Treeインデックスがある。木構造を取ったインデックスであり、平衡木を作成することで処理を簡略化させる。インデックスを作成するのみ適したケースは大規模のテーブルに対しての作成、カーディナリティ（行）の高い列への作成、WHERE句などの選択条件・結合条件に使用される列に対して作成することである。インデックスはデータの更新や構造の変化などのより性能が劣化していくため、定期的なメンテナンスが必要である。以上を考慮し、インデックスを利用してデータベースの速度向上に寄与することができる。

## 残った疑問
- インデックスを使用すべきデータ量はどの程度のなるのか
- どのDBでもインデックスは使用可能？？DBによって適しているインデックスはあるか？？

## 参考資料
- 達人に学ぶDB設計徹底指南書/ミック
- B-treeインデックス入門：https://qiita.com/kiyodori/items/f66a545a47dc59dd8839
Rust + eguiで簡単なゲームを作ってみた

Rustを使う機会が増えてきたので、趣味で簡単なゲームを作ってました。
以下の人には参考になるかもしれません。
* [egui](https://crates.io/crates/egui)で少し複雑なものを作ってみたい人
* WebのAPIから情報を取得してみたい人
* 小学校1～6年生レベルの漢字のテストを受けてみたい人

## ゲームをプレイ
適当なフォルダに移動して↓のコマンドをコマンドプロンプトで入力してください。
Windows環境で、[git](https://gitforwindows.org/) と [Rust](https://www.rust-lang.org/ja/tools/install) がインストールされていればすぐにプレイ出来ると思います。

```
git clone https://github.com/8bitTD/kanji_test
cd kanji_test
cargo run --release
```

## ゲームの説明
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139073/cb6736ab-56b0-aead-7979-2b5da2ee0de4.gif)
* 漢字が表示されますので、ひらがなで読みを入力してエンターキーを押してください。
* 制限時間は、1問ごとに10秒になります。
* 20問連続で正解するとゲームクリア(エンディング)になります。
* 途中で間違うとゲームオーバーになります。
* エンディング後にタイトル画面に戻ると英語モード(激ムズ)が追加されます。
※作者は、英語モードをクリアできませんでした...orz

## コードの説明
ゲームのコードはすべてこちらにアップされております。
https://github.com/8bitTD/kanji_test
* [define.rs](https://github.com/8bitTD/kanji_test/blob/master/src/define.rs)　定義ファイルです。
* [kanji.rs](https://github.com/8bitTD/kanji_test/blob/master/src/kanji.rs)　Webで取得した漢字を格納する処理をしております。
* [kanji_info.rs](https://github.com/8bitTD/kanji_test/blob/master/src/kanji_info.rs)　[WebのAPI](https://kanjialive.com/user-guide-jp/)から漢字や読みを取得する処理をしております。
* [main.rs](https://github.com/8bitTD/kanji_test/blob/master/src/main.rs)　eguiを表示する処理をしております。
* [ui.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui.rs)　eguiのベースの処理をしております。
* [ui_ending.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui_ending.rs)　エンディングの処理をしております。
* [ui_game.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui_game.rs)　ゲーム中のメイン処理をしております。
* [ui_gameover.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui_gameover.rs)　ゲームオーバーの処理をしております。
* [ui_state.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui_state.rs)　ゲーム中の状態や状態を跨いだときにも情報を持っていけるような処理をしております。
* [ui_title.rs](https://github.com/8bitTD/kanji_test/blob/master/src/ui_title.rs)　タイトル画面の処理をしております。

## 参考にさせていただいたサイト
https://www.egui.rs/index.html#demo

https://crates.io/crates/reqwest

https://kanjialive.com/user-guide-jp/
修士（農学）が社会人博士を目指す話

## 農業農村工学を学んだ26歳が、博士（農学）を取るためにできることは何か

こんにちは。Nagaseです。
突然ですが皆様、博士（農学）についてどのようにお考えでしょうか。

「就職先がない」「大変そう」

では、社会人博士については？

「うちの会社にもいたっけ」「大変そう」

Qiitaにはエンジニアの方が多く記事を投稿していらっしゃいます。
しかし、その内訳を見るとエンジニアの前にシステムとか横文字が並ぶ方が多いのではないでしょうか。

私はエンジニアです。大学では農業土木（灌漑排水学）を専攻していました。
Qiitaでは農業土木分野の人間は少数派であると自覚していますが、同時に「自分にしか書けない記事がある」という利点も感じています。
技術職（農業土木）に誇りを持ち、新入社員1年目の日々を過ごしています。
しかし、「私はこれをやっています」「私はこういう人間です」と説明するのにいつも苦労してしまいます。

若い女性ということもあり、何の肩書・資格のない状態では業務で仕事相手に信用してもらえない、と思うことがあります。建設業はどうしても男社会であり、年功序列の文化が根付いているので。
もちろん若手社員（男性）であっても、同様の問題はついて回るとは思います。
「Nagaseさんは顔採用じゃない（と僕は思う。実力で採用されたと思うので、今後も期待している）よ:point_up::joy::blush:」という失礼極まりない言葉をかけられたこともある（解決済み）
ので、外見と中身の両方を伸ばそう、業務に携わる中で経験を積み、実力と才能をこれから伸ばしていこうと頑張っているのですが…

おとなしい見た目（黒髪＆眼鏡）の若い女性というだけで、タクシーの運転手やレジの店員など、身の回りで関わる人に舐められてしまうことも多いのがストレスです。
姿勢を良くするだけで、かなり改善されました。胸を張って生きていこう、猫背を止めよう、と気を付けています。

「自信を持ちたい」「強くなりたい」
自分自身に強みがあれば、もっと生きやすくなるのではないか、と日々考えています。

自分の強みは何か、考えてみました。
・知的好奇心旺盛
・若い女性である
・学生時代とほぼ同じ専門分野に就職した
・大学と近くの会社に就職した
・心の闇に学生時代苦しみ、対処法を学んだ
・Excel、Excel VBA、Python、PHPに触れたことがある
・業務において、「学生時代これを知っておけば」という機会が多い
（例：成果物の納品、Excelのピボットテーブル）
・学生時代から農業農村工学会に所属している
・入社後、水文学会にも入会した
・安定した生活基盤がある（月20万～30万円：残業時間により変動）
・完璧主義者
・自分の知識をわかりやすく相手に伝えたい
・権力志向
・アウトプットするのが得意、文章を書くことが好き
・運動が好き、合気道初段（弐段取得に向けて、稽古中）
・自分に厳しい

## 今後の展望
### 理想
所属していた研究室のお世話になり、リモートワーク等を利用しながら社会人博士を目指す
業務で得た知識をアウトプット→圧倒的成長！！

### そのためにできること
自分の強みを具体化
指導教員に自分自身を売り込む
文章力向上のため、ブログ（QiitaおよびWix）の更新を続ける
→畑地灌漑、蒸発散量推定に関する現在の研究をキャッチアップする

まとめながら発信していけば一石二鳥では（取らぬ狸の皮算用になりませんように）

心の健康を第一に、やれることはやってみようと思います。
なぜなら、今日の私は今後の人生において一番若いので。
（今朝プリキュア20周年の記念動画を見たので、一念発起して決意表明をいたします。）
期限は自分が死ぬまでとします。私たちには、夢がある。
なんでもできる！なんでもなれる！なりたいじぶんになる！
がんばえぷいきゅあ～～～

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

今後、追加修正更新を行うとは思いますが、
「なんか意識高い人間もおるんやなあ」と観測していただければ幸いです。

### 参考文献（今後整理していきます）

https://qiita.com/yosatonet/items/6d8d4377cf6b56d6c7c5

https://qiita.com/7404/items/ce80e1425a413832473e

https://zine.qiita.com/interview/interview_udemy_20170906/?utm_source=qiita&utm_medium=banner

https://nougyoudoboku.com/category/sikaku/professional-engineer/
【AWS】WordPressを構築してみた（初心者用）

# ～ はじめに ～
今回は構築した[**Webサーバー**](https://qiita.com/ponponpoko/items/e5553ef3ace2e4cb5633)にWordPressをインストールし、ブログを開設していきたいと思う。

今回の記事は、長くなりそうなため３パートに分けて書きます。

**【今回の流れ】**
　[**Part１：WebサーバーにPHPをインストール**](https://qiita.com/ponponpoko/items/954c1181824582ed642d)
　[**Part２：WordPress用にデータベース作成**](https://qiita.com/ponponpoko/items/d7e5f2c1df16925ced72)
　[**Part３：WordPressのインストールと設定**](https://qiita.com/ponponpoko/items/1291a654eec95614580a)

WordPressを動作させるためには、以下を満たしている必要がある。

[**【WordPress動作環境】**](https://ja.wordpress.org/about/requirements/)
　\-　PHP バージョン 7.4 以上。
　　　--> PHPは今回Webサーバーにインストールしていく。
　\-　MySQL バージョン 5.7 以上、または MariaDB バージョン 10.3 以上。
　　　--> [RDS MySQL 8.0 構築済み（リンク）](https://qiita.com/ponponpoko/items/4e1304bf3d9901d1eaf0)
　\-　HTTPS 対応
　　　--> [Webサーバー構築済み（リンク）](https://qiita.com/ponponpoko/items/e5553ef3ace2e4cb5633)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/7c49a938-1a92-ef1a-5b5f-d65ac65dcf52.png)


:::note info 
[**【WordPressとは？】**](https://digital-marketing.jp/creative/what-is-wordpress/)
サイトの作成やブログの作成などができるCMS(コンテンツ管理システム)の1つで、無料のソフトウェアです。Web関連技術が無い人でもサイト管理や記事投稿ができるため、世界中のサイトのおよそ4分の1はWordPressで構築されていると言われています。

[**【CMSとは？】**](https://www.hitachi-solutions.co.jp/digitalmarketing/sp/column/cms_vol01/)
「Contents Management System：コンテンツ・マネジメント・システム」の略で、簡単にいうとWebサイトのコンテンツを構成するテキストや画像、デザイン・レイアウト情報（テンプレート）などを一元的に保存・管理するシステムのことです。
:::
RubyからOpenAIのAPIを叩く

## はじめに

RubyからChatGPTで有名なOpenAIのAPIをたたく記事を探したが、意外となかったので忘れるまえに書いておく。

これは少し古い記事なので、ChatGPTのAPIを叩きたい人はこちらの記事を参照してください。

https://qiita.com/yocajii/items/cbce3cb92c601984314c

https://qiita.com/kojix2/items/a426a68b968b6b9e1834

## 利用するライブラリ

https://github.com/alexrudall/ruby-openai

これを使う。

```sh
gem install "ruby-openai"
```

ChatGPTの API Key を取得しておく。

あとは次のようにすれば、利用することができる。（自分の場合は、以前に登録したときの無料枠が失効しており、クレジットカードを登録する必要があった。）

```ruby
require "ruby/openai"

client = OpenAI::Client.new(access_token: "ACCESS_TOKEN_GOES_HERE")

res = client.completions(
        parameters: {
            model: "text-davinci-003",
            prompt: "Are you a cat?",
            max_tokens: 10
        })

puts res["choices"].map{|i| i["text"]}.join
# No, I am not a cat.
```

ChatGPTのAPIを叩くまでは知らなかったが、文章校正や、プログラミングなどに特化したモデルもあり、そういったものを選ぶこともできる。

この記事は以上です。
ionicでカメラまたはライブラリの写真を使用する

あまり、実装についての参考サイトがなかったため、書きました。

## 公式ページ
https://capacitorjs.com/docs/apis/camera

## 表
公式より抜粋(2023年1月26日)後、日本語訳
|prop|Type|Description|Since|
|---|---|---|---|
|base64Strinig|string|CameraResultType.Base64を使用している場合、base64 でエンコードされた画像の文字列表現|1.0.0|
|dataUrl|string|CameraResultType.DataUrlを使用する場合は、「data:image/jpeg;base64」で始まる URL、および base64 でエンコードされた画像の文字列表現。|1.0.0|
|path|string|CameraResultType.Uriを使用する場合、パスにはプラットフォーム固有の完全なファイル URL が含まれ、後で Filesystem API を使用して読み取ることができます。|1.0.0|
|webPath|string|webPath は、効率的な読み込みとレンダリングのために画像の src 属性を設定するために使用できるパスを返します。|1.0.0|
|exif|any|画像から取得した Exif データ (存在する場合)|1.0.0|
|format|string|画像の形式。例: jpeg、png、gif。iOS と Android は jpeg のみをサポートします。Web は jpeg と png をサポートしています。gif は、ファイル入力を使用する場合にのみサポートされます。|1.0.0|
|saved|boolean|画像がギャラリーに保存されたかどうか。Android および iOS では、ユーザーが必要なアクセス許可を付与していない場合、ギャラリーへの保存が失敗する可能性があります。Web にはギャラリーがないため、常に false を返します。|1.1.0|

|prop|Type|Description|
|---|---|---|
|quality|number|JPEG として返す画像の品質 (0 ～ 100)|
|allowEditing|boolean|ユーザーがトリミングまたは小さな編集を行うことを許可するかどうか (プラットフォーム固有)。iOS 14 以降では、 CameraSource.Camera でのみサポートされていますが、 CameraSource.Photosではサポートされていません。|
|resultType|CameraResultType|データを返す方法。現在、「Base64」、「DataUrl」、または「Uri」のみがサポートされています|
|saveToGallery|boolean|写真をギャラリーに保存するかどうか。写真がギャラリーから選択された場合、編集された場合にのみ保存されます。|
|width|number|保存するイメージの希望の最大幅。アスペクト比は尊重されます。|
|height|number|保存されたイメージの望ましい最大の高さ。アスペクト比は尊重されます。|
|correctOrientation|boolean|縦向きモードで画像を自動的に「上」に回転させて向きを修正するかどうか|
|source|CameraSource|写真を取得するソース。デフォルトでは、これによりユーザーはフォト アルバムを選択するか、写真を撮るように求められます。|
|direction|CameraDirection|iOS および Web のみ: カメラの方向。|
|presentationStyle|'fullscreen' / 'popover'|iOS のみ: カメラのプレゼンテーション スタイル。|
|webUseInput|boolean|Web のみ: PWA 要素エクスペリエンスまたはファイル入力を使用するかどうか。デフォルトでは、インストールされている場合は PWA 要素を使用し、ファイル入力にフォールバックします。常にファイル入力を使用するには、これを に設定しtrueます。PWA 要素の詳細: https://capacitorjs.com/docs/web/pwa-elements|
|promptLabelHeader|string|プロンプトを表示するときに使用するテキスト値。|
|promptLabelCancel|string|プロンプトを表示するときに使用するテキスト値。iOS のみ: 「キャンセル」ボタンのラベル。|
|promptLabelPhoto|string|string	プロンプトを表示するときに使用するテキスト値。保存した画像を選択するボタンのラベル。|
|promptLabelPicture|string|プロンプトを表示するときに使用するテキスト値。カメラを開くボタンのラベル。|


### CameraSource
|Members|Value|Description|
|---|---|---|
|Prompt|'PROMPT'|Prompts the user to select either the photo album or take a photo.|
|Camera|'CAMERA'|Take a new photo using the camera.|
|Photos|'PHOTOS'|Pick an existing photo from the gallery or photo album.|

## 簡単に実装
```js
Camera.getPhoto({
                quality: 100,            // 0~100まで
                source: CameraSource.Prompt,   // 写真を撮るorライブラリから選択or両方
                resultType: CameraResultType.DataUrl, // 実行後のデータの種類を指定
                presentationStyle: 'popover',    // 画像の表示
                webUseInput: true,               // ブラウザで実行した時の処理
                promptLabelHeader: "写真を選択",   // 以下の文言のタイトル的なもの
                promptLabelPicture: "写真を撮る",  // 写真を撮るときに表示される文言
                promptLabelPhoto: "アルバルから選択", // ライブラリにアクセスする時に表示される文言
                promptLabelCancel: "キャンセル"      // 実行を取りやめる時の文言
            })
```
Ruby3

# 問題

国語が80点、英語が50点、数学が70点の場合のテストの平均点をターミナルに出力するプログラムを記述してください。

条件1：このプログラムでは各教科の点数を変数を使って定義してください。
条件2：出力結果は以下のようになるようにコードを書きましょう。


```Ruby:ターミナル
３教科の平均点は、◯点です。
```

※◯の箇所には計算した平均点が入ります。

出力にはputsを使います。putsのあとに半角スペースと出力したい文字列を続けることで、文字をターミナルに出力できます。


```Ruby:記述方法
puts "出力したい文字列"
```
<br>
<br>
<br>

# 模範解答

```Ruby:解答
japanese_score = 80
english_score = 50
math_score = 70

average_score = (japanese_score + english_score + math_score) / 3

puts "3教科の平均点は、#{average_score}点です。"
```

# 【解説】
「変数を使って」と指定があるため、各教科の点数をそれぞれ変数として定義します。変数名はjapanese_score、japanese、kokugo_score、kokugoなどの分かりやすい名前をつけましょう。

```Ruby:変数として定義
japanese_score = 80
english_score = 50
math_score = 70
```

また、平均点に関しても変数を使うほうが望ましいです。変数を使わない場合は以下のようになります。

```Ruby:変数なし
puts "3教科の平均点は、#{(japanese_score + english_score + math_score) / 3}点です。"
```

これだとコードが読みにくく、(japanese_score + english_score + math_score) / 3が何を指しているのかを見ただけでは判断することが難しいです。

そこで平均点も以下のように変数として定義しましょう。平均点は全ての変数の合計を3で割った値です。

```Ruby:変数あり
average_score = (japanese_score + english_score + math_score) / 3
```

平均点の出力の際には、文字列と数値の連結となるので、式展開かto_sメソッドを使います。

```Ruby:最終的なソースコード
japanese_score = 80
english_score = 50
math_score = 70

average_score = (japanese_score + english_score + math_score) / 3

puts "3教科の平均点は、#{average_score}点です。"
```

変数を使うことでソースコード全体が読みやすくなりました。
複雑に記述されているコードよりも、見やすく分かりやすいコードになるように心掛けることです。
linuxとは

**<span style="font-size: 200%">linuxとは</span>**

Linuxとは、WindowsやMac OSと同じOSの一種です。
OSとは、`オペレーティングシステ`の略語です。
ソフトウェアとハードウェアをつなぐ役割を担っています。
たとえば、Wordなどの`ソフトウェア`で作成したテキストは、ハードウェアへ記録・保存されます。このときデータがハードウェアへ正しく記録・保存されたり、保存したデータを読み込んで閲覧できたりするのは、OSが機能しているからこそです。このほか、OSはユーザーのアクション（操作）をコンピューターへ正しく伝える役割も担っています。
***

**<span style="font-size: 200%">linuxの特徴</span>**

PCやスマホは、初めから0Sが備わっています。
PCやスマホに新たにWindowsやMacOSを組み込む際はOSを新たに購入する必要がありますが、linuxは無料で公開されているため誰でも使えます。
無料で公開されているため、linuxを使い新たなOSを作ることもできます。
linuxは自由に改良できるOSの為、必要な分だけサーバーを構築できるのも強みです。
本来はサービスの速度や安全性をキープするために多くのサーバーが必要になり、コストが発生しますが、linuxはコストを大幅に抑えてサーバー構築ができます。
構築する上でも、有料のOSと違い、自由にソースコードを書き換えたりもできます。
そして、無料だから安全性に欠けると思雨かもしれません。
ですが、ユーザー制限が厳しく管理されているのが特徴です。常に厳重なセキュリティ体制のもと最新版をリソースしているため、安全性の高いサーバーとして活用されています。
***
**<span style="font-size: 200%">linux用語</span>**


linuxを使う上で不可欠な専門用語についてです。

**カーネル**        
 ユーザーの指示を正しく反映させるOSの中核部分

 **シェル**
Linuxのカーネル（中核）の指示を伝えるためのツール

 **コマンド**
 シェルへ入力する命令文

 **パッケージ**        
Linuxが導入しているアプリケーションの配布形態

一つ一つ説明していきます。

# カーネル

OSの中核となる部分を`カーネル'と言います。
ソフトウェアとハードウェアを繋げて、ユーザーの指示を正しく反映させる役割を担っています。
Linuxにおけるカーネルは、メモリ管理機能やネットワーク、ファイルシステムなどから成り立っています。
# シェル

ユーザーの指示を、Linuxのカーネル(中核)へ伝えるためのツールです。例えると、人間の指示を翻訳して、カーネルへ伝えてくれる通訳者のような感じです。
# コマンド

Linuxを動かす際に、シェルへ入力する命令文のことを`コマンド`と言います。
たとえば`cd`はディレクトリの移動、`cp`はファイルやディレクトリの複製、`rpm`はパッケージのインストールというように、それぞれの動作に対するコマンドが決まっています。
# パッケージ

Linuxが導入しているアプリケーションの配布形態を表します。
Windowsでは`インストーラー`を用いてアプリケーションをインストールするように、Linuxでは`RPM`や`DFN`などのパッケージ管理ツールを用いてアプリケーションをインストールします。
【Django】既にデータが入っている既存テーブルにユニークキーを追加したい時



単純にやろうとするとどうしてもエラーがでてしまいますよね。
そんなときに使える処方箋です。

```python
class Profile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    ## user_nameを追加
    user_name = models.CharField(max_length=40, null=False, blank=False, unique=True)
    display_name = models.CharField(max_length=40, blank=True)
```


既存のテーブルに上記の `unique=True` がついた、 `user_name` カラムを追加しました。

この状態で, `python manage.py migrate` するとエラーで怒られると思います。


## マイグレーションファイルをいじります。

`python manage.py makemigrations` を叩いて作成されたマイグレーションファイルを編集します。

```python
from django.db import migrations, models

## 以下のメソッドを追加
def set_default_code(apps, schema_editor):
    """
    既存の行に対してuser_nameを一意の名前で追加する関数
    """

    profile_model = apps.get_model('app_name', 'Profile')
    for row in profile_model.objects.all():
        row.user_name = 'UserName_{}'.format(row.display_name)
        row.save()


class Migration(migrations.Migration):

    dependencies = [
        ('app_name', '0007_profile_image'),
    ]

    operations = [
        migrations.AddField(
            model_name='profile',
            name='user_name',
            ## 作成された直後はここにunique=Trueが書いてあると思うけどそれは削除
            field=models.CharField(default='hoge', max_length=40, null=True),
            preserve_default=False,
        ),

        ## この行を追加
        migrations.RunPython(set_default_code, reverse_code=migrations.RunPython.noop),

        ## これも追加
        migrations.AlterField(
            model_name='profile',
            name='user_name',
            field=models.CharField(max_length=40, unique=True),
            preserve_default=False,
        ),
    ]

```

多分これでいけるはず。

ときにはこうやってマイグレーションファイルを直接いじることも必要なんだなと。
PureScript さわってみたゼ🍝

# 初めに

Haskell と　elm さわっている人が PureScript さわってみたいと思ってとりあえず動かしてみただけの記事です。

自分の備忘録のためと PureScript の発展のために誰かのためになりますように書きます🥰

# PureScript インストール

プロジェクト初期化

```shell-session
$ mkdir hoge
$ cd hoge
$ npm init -y
...
$
```


インストール

```shell-session
$ npm install --save-dev purescript
...
```

# PureScript 周りのツールのインストール

先人である　@yukikurage_2019 さんの記事を参考に以下をインストール

https://qiita.com/yukikurage_2019/items/a2c7b0d1d2c34aee120c

> - `spago`
>    - プロジェクト / パッケージ管理ツール
> - `purs-tidy`
>     - フォーマッタ
> - `esbuild`
>     - `spago` が専らバンドラとして間接的に使う。

```shell-session
$ npm install --save-dev spago purs-tidy esbuild
...
```

# PureScript 初期化

```shell-session
$ npx spago init
...
```

初期化すると `/src/Main.purs/` に以下のファイルが出来上がります

```haskell
module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)

main :: Effect Unit
main = do
  log "🍝"

```

# 実行

```shell-session
$ npx spago run
...
[info] Build succeeded.
🍝
$
```

実行すると 🍝 が出力されます。

# 最後に

次は PureScript の一番メジャーっぽいフレームワークの [Halogen](https://purescript-halogen.github.io/purescript-halogen/) をさわってみたいと思います😎
開発環境と本番環境で色の表示が異なる問題


<!-- 発端や概要を記載 -->

:::note info
こちらのアプリをNext.jsで作成中
:::

https://qiita.com/kajiyai/items/b8c9b9fec255dedda38f



# 目次
<!-- タイトルとアンカー名を編集 -->
1. 問題
1. 開発環境
1. 調査
1. 解決(?)
1. 参考文献


# 問題

開発環境と本番環境(vercel)で色の表示が異なる。
開発環境の何かが問題だと予想。色の調整が行えなくて困る

【開発環境】
![localhost_3000_ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/1de1d110-fb39-bbb7-59c6-3f4454c8f07f.png)

【本番環境】
![manga-title-generator-sable.vercel.app_ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/6cfd8ae8-c2be-b4eb-7f47-700486bbbd2a.png)


<!-- 各チャプター -->
<a id="#C1"></a>
# 開発環境



```:dependencies
 {
    "@chakra-ui/react": "^2.4.9",
    "@emotion/react": "^11.10.5",
    "@emotion/styled": "^11.10.5",
    "@next/font": "13.1.1",
    "dotenv": "^16.0.3",
    "eslint": "8.31.0",
    "eslint-config-next": "13.1.1",
    "framer-motion": "^8.5.0",
    "next": "13.1.1",
    "openai": "^3.1.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-icons": "^4.7.1",
    "react-share": "^4.4.1"
}
```


<a id="#C2"></a>
# 調査


## こいつが原因ぽい


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/4946f340-856d-10a7-ec77-6a8836697672.png)


data-themeとは、、、data-*で任意の属性を付与することが出来るぽい。

https://logical-studio.com/develop/frontend/20210312-the-uses-of-data-property/#data


Chakra UIを使ってるので、cssとか書いてないのだが。。という事でChakra UIのcolorのページを見る

これか？Tipsにストレージかクッキーに保存されるよ、と書いてある

>
>Tip: Chakra stores the color mode in localStorage or in cookies and appends a className to the body to ensure the >color mode is persistent.
>In case you need to reset the color mode, you must delete the item from localStorage or cookies, so on next page >load the value is initialized like the first time user visited the page.
>

https://chakra-ui.com/docs/styled-system/color-mode

クッキー削除したが変化なし。ローカルストレージとは。。


<a id="#C3"></a>
# 解決(?)

根本的な問題は分からなかったが回避策は思いついた
完成を優先するために、やむなくこれ以上の調査は中断した。

仕方がないので、[公式のチュートリアル動画](https://youtu.be/wI2vqXsjsIo)を見ながらダークモードを管理するトグルボタンを作った。

ついでにボタンではなくアイコンにもしてみた

https://qiita.com/hirochan/items/3ea354440ab53c71c265


(メモ)
react-iconsのimport方法を間違えると次のエラーが出た

https://cpoint-lab.co.jp/article/202005/15172/

![ezgif.com-gif-maker (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/32dfee34-54eb-ed19-ebf1-13d1c121a23d.gif)

制御できた。

<a id="#reference"></a>
# 参考文献
- [_document.tsx,_app.tsxあたりの記述](https://31navi.com/next-darkmode)
Python で バイト文字列をサニタイズ

通信などで取得したデータとして、バイト列

```
data= b'@-79,8,7 251 507 10146 1404 152 3700 70b3d559e01d25a3\r\n'
```

がある。
これを処理する前にサニタイズし、決まったフォーマットでデータを採取しよう。

# 環境

- Python 3.9.2
- LANG=en_GB.UTF-8

# 最後の改行を rstrip で削除する

まずは、最後の改行。もし改行コードがあったりなかったりLFだったりCRLFだったりということを許容しないといけない場合は、右端に \r ないし \n を削除しておきたい。

`rstrip` を使うとすると バイト列で処理

```
  data2 = data.rstrip(b'\r\n')
```

ないし str で処理

```
  data2 = data.decode().rstrip('\r\n')
```

となる。

しかしながら後者はもし受信データが文字化けして以下のようになった場合

```
data= b'@-83,7,7 257 497 10153 423 \x00\x7F\xEF\xFE\xFF\r'
```

以下のようにエラーになる。

``` 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xef in position 29: invalid continuation byte
```
エラーを対策することもできるが、バイト列で処理するのが確実かな?


# 最後に改行が付いていた特定のキャラクタセットかどうか判定する

@,スペース、ハイフン、カンマ、数字(0〜9)、英小文字(a〜f) であるかどうかの判定

先に rstrip で \r\n  を削除した。正規表現の書き方で`[\r\n]*` なので、改行の有無、個数や並び順を問わなかった。今回はそうではなく、最後が \r\n であるかどうかを厳密にチェックする。

```
if not r  if not re.fullmatch(b'[0-9a-f@ \-,]+\r\n', data):
    print("illeagal caracter error", file=sys.stderr)
```

# 決まったフォーマットのデータを抽出する

```
# 前半の3パラメータを取得
data2=( re.match( rb'^@([-0-9]+)'   # 行頭の@に続く符号付整数
                   +b',([-0-9]+)'   # カンマで区切られた2つ目の整数
                   +b',([-0-9]+)'   # カンマで区切られた3つ目の整数
            , data))
if ( None == data2 ):
    print("Not match error",file=sys.stderr)
    exit()
print (data2.group(1),data2.group(2),data2.group(3))
```
て、決まったフォーマットで並んだデータを取得。


# スペース区切りのデータを抽出する

```
# 後半のスペース区切りデータを取得する
data3=( re.findall( rb' ([-0-9abcdef]+)',data))   # スペース区切りフィールド
print(len(data3))
if (7 == len(data3)):
    print(data3)
else:
    print("Value error", file=sys.stderr)
    exit()
```
スペースで区切られたデータを取得する。「決まったフォーマットのデータを抽出する」の方が厳密だけど、スペースの個数が可変な場合や、フィールドにより10進/16進が決まってない、フィールドの個数が可変などの場合はこちらの方がフレキシブル。

# 全部まとめたもの


```
#!/usr/bin/env python3
import re
import sys
# 受信電文例
data= b'@-83,7,7 257 497 10153 423 152 3700 70b3d559e01d25a3\r\n'
#data= b'@-83,7,7 257 497 10153 423 \x00\x7F\xEF\xFE\xFF\r\n'
#data= b'@-83,7,7 257 497 10153 423 \x00\x7F\xEF\xFE\xFF\r'
print(data)

# 不必要な文字セットが含まれておらず、最後が \r\n で終わっているかチェック
if not re.fullmatch(b'[0-9a-f@ \-,]+\r\n', data):
    print("illeagal caracter error", file=sys.stderr)
    exit()

# 前半の3パラメータを取得
data2=( re.match( rb'^@([-0-9]+)'   # 行頭の@に続く符号付整数
                   +b',([-0-9]+)'   # カンマで区切られた2つ目の整数
                   +b',([-0-9]+)'   # カンマで区切られた3つ目の整数
            , data))
if ( None == data2 ):
    print("Not match error",file=sys.stderr)
    exit()
print (data2.group(1),data2.group(2),data2.group(3))

# 後半のスペース区切りデータを取得する
data3=( re.findall( rb' ([-0-9abcdef]+)',data))   # スペース区切りフィールド
print(len(data3))
if (7 == len(data3)):
    print(data3)
else:
    print("Value error", file=sys.stderr)
    exit()
```


# 実行結果

```
$ python3 encodetest.py 
b'@-83,7,7 257 497 10153 423 152 3700 70b3d559e01d25a3\r\n'
b'-83' b'7' b'7'
7
[b'257', b'497', b'10153', b'423', b'152', b'3700', b'70b3d559e01d25a3']


```
xcodeで実機にビルドするときのBundle Identifierで起こるエラー

## 問題

 ```
Provisioning Profile Xcode Managed Profile
Signing Certificate Apple Development: メールアドレス
```

## 解決方法
![スクリーンショット 2022-11-06 23.56.55のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712534/a918bd56-f212-88c8-970e-89c41c9d99b9.png)
画像のように後ろに文字を入力すると解決する。
画像では日付を入力した。
また障害を引き起こしたので始末書と考えられる対策方法とか。

# あっやｂ(ry（2回目）
もうね、なんかメンタル強くなった。

# 不具合の内容
「ピン留めメッセージ」という、本来は1度しか送信されないはずのメッセージが、何度も何度も送信されてしまった。

# では、何がおきたのか？
まず、今回は「サーバーの再移行作業」を行っていました。
理由としては、VALORANTをプレイしたいけど、[Vanguard](https://support-valorant.riotgames.com/hc/ja/articles/360046160933-Vanguard%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)が起動していなかったのでPCを再起動したくて、1時間以内の作業目安で作業を行っていました。
本番環境とデータベースファイルを元のサーバーから移行先のサーバーへと移していって...
「とりあえず、HTTP_dbを再起動して...いや、長いことサーバー再起動してなかったからサーバーごと再起動するかー...」

```sh
$ sudo shutdown -r now
```

再起動は悪なんです。（ネタバレ）（風評被害）

というわけで、サーバーを再起動しました。

さて、出来るだけダウンタイムを減らすために、BOTを移行前サーバーで起動させながらの作業でした。

ではここで移行後サーバーでの動作のお話です。
`「BOTのサービスを自動起動するように設定している。」`

というわけで...
移行前サーバーと、移行後サーバーの両方で本番環境が**2重起動**してしまいました！（つらい！）

# なぜ分かったか
まず、ありえないほど通知がやってきて、荒らしを疑いましたが、誰もいませんでした。
なので、とりあえず設定をオフにするコマンドを使用しました。

しかし、別サーバーでも同じ状況が発生している状況。

とりあえず何が起きているのか冷静に判断します。

すると...BOTのステータス画面でのプリフィックスが`n#`と表示されていました。
本来であれば`n!`なはずなので、本番環境で別のプリフィックスが表示されるということは、「もしかしてさっきの再起動でBOTが...ﾊｯ(絶望)」っとなりました。
すぐにBOTをコマンドで停止しました。

# 解決策
トークンが複数ファイルPCの中に転がっていたせいで、本番環境アカウントでの二重起動が行われてしまいました。
今回は、プリフィックスを「たまたま」変えていたのですぐに気が付くことが出来ました。
が、なによりも2重起動対策をしなければなりませんね...。

# 終わりに
ちょっと流れ作業で書いたので簡単な始末書になってしまいましたが、これにて終わらせていただきます。
今回はちょっと洒落にならないタイプの不具合だったので本当に申し訳ないです。
対策を頑張りますので、これからもにらBOTをよろしくお願いします。
[Spine]GIMPからSpineにエクスポートする手順

# 概要
PhotoShopからSpineへのエクスポート方法は公式で用意されていますがGIMPには無いようです。
検索しても全く情報がありませんでしたので、ここにまとめておきます。

# 本文
## GIMPで画像作成
「**ファイル > 新しい画像**」で新規作成します。
今回は雪だるまぽい画像を用意しました。
![スクリーンショット 2023-01-30 22.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a99b7aff-4e05-6ce6-36aa-2048e6d7ec99.png)
パーツごとのレイヤーを選択した後「**レイヤー > 内容で切り抜き**」をします。こうすることでパーツごとのサイズに合わせてレイヤーがサイズ調整されます。
![スクリーンショット 2023-01-30 22.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a25a78b8-3a13-a106-2562-1d6500478fe1.png)
![スクリーンショット 2023-01-30 22.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/de18fa9f-b02e-0b40-a81d-dd6f730e7925.png)
「**画像 > キャンバスをレイヤーに合わせる**」を選択するとキャンバス全体のサイズが画像のサイズに合わせて調整されます。
![スクリーンショット 2023-01-30 22.14.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/70c23d23-496b-78bc-9260-8b43c6a64840.png)
![スクリーンショット 2023-01-30 22.16.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/130c7f48-817c-9a0b-dd80-7ac106c3a6e9.png)
一度xcfファイルとしてGIMPのデータを保存しないと次のエクスポートの手順でエラーが出ます。必ず一度保存してください。
![スクリーンショット 2023-01-30 22.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/9a2371f3-a2a8-ba6b-4eba-c4ae66bc6738.png)

## エクスポートの手順
こちらのサイトからスクリプト「GimpToSpine.py」をダウンロードします。
https://github.com/EsotericSoftware/spine-scripts/tree/master/gimp
![スクリーンショット 2023-01-26 21.12.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8fb0ea7c-6ff0-5da0-504d-c169833190ff.png)

同サイトに手順が書いてありますが、主な部分だけこちらにも書いておきます。
GIMP > 設定
![スクリーンショット 2023-01-26 20.58.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/6a182ca7-7f1e-d430-e401-e6e7d1122d84.png)
フォルダ > プラグイン
プラグイン用フォルダが表示されます。ここに示されている場所に、ダウンロードした「GimpToSpine.py」を移してください。
![スクリーンショット 2023-01-26 20.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5f00ac63-c94a-6573-a701-8c1fa24a0f6c.png)
macの場合はスクリプトを実行可能にするためにTerminalからファイル設定を変更します。プラグイン用フォルダに移動した後、以下のコマンドを入力します。(Windows版ではこの操作は必要ありません)
```terminal
chmod +x GimpToSpine.py
```

ここまでの準備ができたらGIMPを再起動します。
ファイル > Export to Spineが追加されているのが確認できました。
![スクリーンショット 2023-01-26 21.08.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/c97d0702-75e9-d161-44c8-376a15b7144b.png)
エクスポートがうまくいかない時はCropをNoにしてみてください。
![スクリーンショット 2023-01-26 21.43.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/63bbd2e3-171c-b474-a47f-2064f570be5f.png)

## Spineへのインポート
データファイルをエクスポートしたらSpineを起動します。
メニューからデータインポートを選び、出力したファイル群の中にあるjsonファイルを指定します。
![スクリーンショット 2023-01-26 21.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8d093255-c17c-2d1e-4103-679ac22172b9.png)
無事Spineへのインポートに成功しました！:sunny:
![スクリーンショット 2023-01-30 22.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/b6b3068f-1d40-1952-7739-a293cb92863a.png)
Fess 14.6インストール

# ダウンロード
https://fess.codelibs.org/ja/downloads.html
Fess/Opensearch の rpm をダウンロ―ド
# Java17 インストール
```
dnf install java-17-openjdk
```
# Openseachインストール
```
rpm -ivh opensearch-2.4.1-linux-x64.rpm
/usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-fess:2.4.0
/usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-extension:2.4.0
/usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-minhash:2.4.0
/usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-configsync:2.4.0
```
/etc/opensearch/opensearch.ymlを修正
```/etc/opensearch/opensearch.yml
configsync.config_path: /usr/share/opensearch/data/config/
plugins.security.disabled: true
```
# fessインストール
```
rpm -ivh fess-14.6.0.rpm
```
/usr/share/fess/bin/fess.in.shを修正
```/usr/share/fess/bin/fess.in.sh
SEARCH_ENGINE_HTTP_URL=http://localhost:9200
FESS_DICTIONARY_PATH=/var/lib/opensearch/data/config/
```
# 起動
```
systemctl enable elasticsearch.service
systemctl enable fess.service

systemctl start elasticsearch.service
systemctl start fess.service
```
AutoHotKeyで作る超個人的作業効率化ツール①　ChatGPTによるコーディング支援

# はじめに
個人的に使ってるAutoHotKeyのスクリプトを晒すだけの記事です。
コードの解説などはしていません。
というかAutoHotKeyの文法あんまり理解してないまま書いてます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802626/69f8feea-76f5-35d9-7752-5af70083c71e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802626/bee61fe1-e722-0261-84f5-24b393c4b39b.png)


VSCodeにChatGPTの拡張機能がありますが、devContainer環境ではブラウザのパスを指定できずうまく動かなかったので自分で作りました。
わざわざこっちを使うメリットは
・アプリを問わず使える
・AIに対する指示を自由に登録できる
・APIを使っていないのでタダ
ぐらいです。

# インストール方法

#### 1 AutoHotKey Version 1.1.36.02をインストール
#### 2 下記のchatGPT.ahkとorder.txtをコピペしUTF8 BOM付きで（重要）同じディレクトリに保存
#### 3 chatGPT.ahkをAHKで開く

# 使い方
#### 1.既定のブラウザでChatGPTにログインしておく
#### 2.テキストを選択しCtrl+Shift+Xを押す
#### 3.選択したテキストに対してChatGPTに行わせる指示をクリック







```chatGPT.ahk
global CustomOrder


^+x::
  array := {}

  orderIndex := 0
  Loop, Read, order.txt
  {
    parts := StrSplit(A_LoopReadLine, ",")
    array[parts[1]] := parts[2]
    
  }
  length := 0
  for index, value in array
      length++

  clipboard := ""
  order := ""
  Send ^c
  ClipWait, 1
  my_Text := clipboard
  Gui, Font, s12
  For k, v in array
  {
    gui, add, button,x+5 vtext%v% ggeneric, % k
  }
    GUI Add, Edit, X10 y+20 W200 +Multi vCustomOrder
  　GUI, Add, Button, x+5 Gcustom, カスタム
    GUI, Show, , ChatGPT
    GuiControl, Focus, CustomOrder
    Return


    custom:
    Gui, Submit, NoHide
    Gui, Destroy
    ORDER_GPT(customOrder,Clipboard)
    Return

    
    generic:
    StringReplace, order, A_GuiControl, text,
    Gui, Destroy
    ORDER_GPT(order,Clipboard)

    return

    ;Xボタンが押されたときのハンドラ
    GuiClose:
    Gui, Destroy
return


ORDER_GPT(order,body) {
 
  run, https://chat.openai.com/chat
  Sleep, 200
  while (A_Cursor = "AppStarting" or A_Cursor = "Wait") ; Wait for browser
    continue
  Sleep, 200
  while (A_Cursor = "AppStarting" or A_Cursor = "Wait") ; Wait for browser
    continue
  Sleep, 500

titleToWaitFor := "New chat"

SetTitleMatchMode, 2
while (!WinExist(titleToWaitFor))
{
    Sleep, 100
}

WinActivate, %titleToWaitFor%
WinGetTitle, currentTitle

IfInString, currentTitle, % titleToWaitFor
{
    clipboard := order
    sendinput, ^v
    Sleep, 200
    clipboard := body 
    sendinput, ^v
    Send, {Tab}
    Send, {Enter}
}
else
{
    MsgBox, エラーが発生しました
}
}
```

```order.txt
バグ修正,このコードのバグを修正して下さい
リファクタリング,このコードをリファクタリングして下さい
解説,このコードを説明して下さい
TS型変換,このコードをTypescriptの型に変換して下さい
```
TS型変換はDBのスキーマからTypescriptの型を生成するときに使ってます。
くっそ便利。

# 指示の登録方法
order.txtを編集し
カンマの前にボタンのテキスト,カンマの後にそのボタンを押したときにchatGPTに対して与える指示を記述して下さい。

プログラミングに限らず文章の要約、校正、翻訳などにも利用できます。
例
```
校正,以下の文章を校正してください。
要約,以下の文章を校正してください。
```

# その他
AutoHotKeyでブラウザをDOM経由で操作するには色々必要なので
単純にブラウザ開いて指示と選択した内容貼り付けてタブキー押してEnterとやってるだけです。

そのためブラウザでurlにフォーカスが当たっている、具体的には新しいタブを開いている（タブ一覧に新しいタブがあるだけならOK）状態だと変なところに入力してしまい、うまく動作しません。


# 結論
AIに仕事をやって欲しいけど仕事は奪わないで欲しい
Ruby getsメソッド

# getsメソッド
ターミナルに値の入力機能を起動するメソッドのことを言います。
文字列としてプログラムに渡されます。

例
```ruby
name = gets
puts "私の名前は#{name}です"
```
このように記述すると、ターミナルではまず、入力機能が実行されます。
入力待ちの状態。（name = getsの部分）
入力してEnterすると、"私の名前は#{name}です"の部分が表示されます。
以下のようになります。
```
ポチ
私の名前はポチ
です
```
と出力されます。
"です"の部分が改行されています。
このように文字列オブジェクトの後ろには、改行が入ります。
この改行を取り除くときには以下のように書きます。
```ruby
name = gets.chomp
puts "私の名前は#{name}です"
```

ターミナルでは以下のように出力されます。
```
ポチ
私の名前はポチです
```
***chomp（チョンプ）メソッド***と言います。
このメソッドを使用すると、文字列の末尾に存在している改行を取り除いて文字列を返します。
【TypeScript】ExcelJSで出力したCSVへのSJIS対応

### ExcelJSによるCSV出力とSJIS対応
ExcelJSを利用して出力したCSVファイルをSJIS対応させようとサイトを参考にコードを書いたらエラーを吐いて動かなかったので備忘録。
SJIS対応にはecoding.jsをnpm installしてインポートする。

https://github.com/polygonplanet/encoding.js/blob/master/README_ja.md

CSVファイルを作成する部分は他サイトにお任せして、エラーになった部分を以下に抜粋。
```react: Csv.ts
import Encoding from "encoding-japanese";
// 省略
const workbook = new ExcelJS.Workbook(); //ブックを作成

// 省略
const uint8Arr = new Uint8Array(
  Encoding.convert((await workbook.csv.writeBuffer()), { 
// await workbook.csv.writeBuffer()にエラーが表示される
    from: "UTF8",
    to: "SJIS",
  })
);
```
```Encoding.convert```の引数の定義を見てみると以下のように一つ目の引数は```string```型か```IntArrayType```型である必要がある。


```typescript
export function convert(data: IntArrayType, to: Encoding, from?: Encoding): number[];
export function convert(data: string, to: Encoding, from?: Encoding): string;
export function convert(data: IntArrayType | string, options: ConvertStringOptions): string;
export function convert(data: IntArrayType | string, options: ConvertArrayBufferOptions): ArrayBuffer;
export function convert(data: IntArrayType | string, options: ConvertArrayOptions): number[];
export function convert(data: string, options: ConvertUnknownOptions): string;
export function convert(data: IntArrayType, options: ConvertUnknownOptions): number[];
```
さらに```IntArrayType```型は以下のように複数の配列の型で構成されている。

```typescript
type IntArrayType =
    | ReadonlyArray<number>
    | Uint8Array
    | Uint16Array
    | Uint32Array
    | Int8Array
    | Int16Array
    | Int32Array;
```
そして```convert```の一つ目の引数に入れた関数```writeBuffer```は以下のように```Buffer```を返してくれるようだが、```Buffer```は```ArrayBuffer```を継承しただけの模様。
```typescript
writeBuffer(options?: Partial<CsvWriteOptions>): Promise<Buffer>;
declare interface Buffer extends ArrayBuffer { }
```
```ArrayBuffer```や```Uint8Array```についてはここが綺麗にまとまっていて読みやすい。

http://var.blog.jp/archives/62330155.html

### 解決策
つまりエラーメッセージにもあるように```IntArrayType```型の引数が必要なのに```Buffer```型の変数を入れてんじゃねぇと怒られているわけなので、以下のように```Uint8Array```型にキャストしてあげるとエラーが解消され、SJISで文字化けしないCSVファイルが無事に出力される。

```react: Csv.ts
const uint8Arr = new Uint8Array(
  Encoding.convert((await workbook.csv.writeBuffer() as Uint8Array), { 
// asでキャストする
    from: "UTF8",
    to: "SJIS",
  })
);
```
jquery.jpostal.jsで自動入力が反映されない

# はじめに

jquery.jpostal.jsで自動入力された先がselect2だった場合、値が反映されなかった
（selectタグだと正常に自動入力された）

# 解決方法
triggerオプションを追加することで自動入力された値の変更を検知できるようになる



```
		trigger : {
			'#address1_kana'  : true,
			'#address2_kana'  : true,
			'#address3_kana'  : false
		}
```

# 参考文献
[「jquery.jpostal.js」で自動入力された値に反応して特定要素のテキスト変更とクラスの付与をしたい](https://teratail.com/questions/215786)
git初プッシュまで

1. githubでリモートリポジトリを作る。
2. VSCodeのターミナルで（git init） する。
3. VSCodeのターミナルで（git add *）する
4. 初回だけVSCodeのターミナルで（git config --global user.email "youremail@address.com")する。
5. 初回だけVSCodeのターミナルで（git config --global user.name "yourname")する。
6. VSCodeのターミナルで（git commit -m "first commit"）する
7. 初回だけVSCodeのターミナルで（git remote add origin リモートリポジトリのURL）する。
8. VSCodeのターミナルで（git branch -M main）する。
8. VSCodeのターミナルで（git push origin main）する。

githubでtokenが必要な場合は
https://note.kiriukun.com/entry/20210904-github-password-authentication-was-removed
この記事を読んでTokenを作成する
PlantUML使い方

## 0.0 はじめに
PlantUMLの使い方に関して忘れがちなことをメモしています。
主にクラス図を作成する際のショートカットキーなどをメモしています。

ちなみにPlantUML言語リファレンスガイド（説明書）は下記にあります（日本語版）
https://plantuml.com/ja/guide





## 1.0 プレビューの表示（ショートカットキー）
**Alt+D**





## 2.0 コマンドパレットの表示（ショートカットキー）
**F1** または **Ctrl + Shift + P** 





## 3.0 UMLの画像の保存
コマンドパレットを表示して　**PlantUML: Export Current Diagram**　を入力/選択します。
その後、.pngなど保存フォーマットを選んで保存します。










## 4.0 タイトル表示
**title** キーワードを付ける。
2個目以降は上書きされます。（それ以前のtitleキーワードは無視されます） 






## 5.0 コメントアウト
一行のみのコメントアウトはシングル・クォート（'）を行の最初に書く
ブロック・コメントは /' と '/ で囲む
草莽Erlang ── 38. lists:keyreplace


口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:keyreplace/4

```
keyreplace(term, integer, [tuple], tuple) -> [tuple]
keyreplace(検索ワード, タプルの要素の位置, タプルのリスト, 置換するタプル) -> 新しいタプルのリスト
```

[lists:keyreplace/4](https://www.erlang.org/doc/man/lists.html#keyreplace-4)は指定された位置の要素が検索ワードと等しいタプルを探し、該当するタプルが見つかった場合はそのタプルを指定されたタプルに置き換えます。置き換えられるのは最初に出現した一個だけです。

```erlang
% 2番目の要素が「20」のタプルを「{"I", 123}」に置き換える
> lists:keyreplace(20, 2, [{"A", 10}, {"B", 20}, {"C", 30}], {"I", 123}).
[{"A",10},{"I",123},{"C",30}]

% 該当するタプルが見つからない場合は、元のリストのまま
> lists:keyreplace(foo, 2, [{"A", 10}, {"B", 20}, {"C", 30}], {"I", 123}).
[{"A",10},{"B",20},{"C",30}]
```

## lists:keystore/4

[lists:keystore/4](https://www.erlang.org/doc/man/lists.html#keystore-4)は[lists:keyreplace/4](https://www.erlang.org/doc/man/lists.html#keyreplace-4)と似てますが、検索ワードと等しいタプルが見つからない場合には指定されたタプルがリストの最後尾に追加されます。

```erlang
% 2番目の要素が「20」のタプルを「{"I", 123}」に置き換える
> lists:keystore(20, 2, [{"A", 10}, {"B", 20}, {"C", 30}], {"I", 123}).
[{"A",10},{"I",123},{"C",30}]

% 該当するタプルが見つからない場合は、最後尾に追加
> lists:keystore(foo, 2, [{"A", 10}, {"B", 20}, {"C", 30}], {"I", 123}).
[{"A",10},{"B",20},{"C",30},{"I",123}]
```

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1