OmniAICreator/Qiita-1.07M huggingface dataset:
「良いコード／悪いコードで学ぶ設計入門」を読んだ

ミノ駆動本こと「良いコード／悪いコードで学ぶ設計入門」を読み終えました。面白かったので感想をちょっと書いてみます。
https://gihyo.jp/book/2022/978-4-297-12783-1
なお、サブタイトルに「保守しやすい成長し続けるコードの書き方」とあるので、先日感想を書いた[「継続的デリバリーのソフトウェア工学」](https://qiita.com/sakisakira/items/f0569b3dc538ee5864ab)と内容が被るかな〜と思いましたが、あまり被っていませんでした。

実のところ第4章を読んでいたころまでは、他の本にもよくある内容だなと、あまり良い印象を持っていませんでした。が、第5章ぐらいからコード例をある程度真面目に読まないと理解が進まないようになってきてから印象が良い方向に変わってきました。
この本では、例示として悪いコードを示し、それがどうして悪いのかを説明し、それを解消する良いコードを示すという説明方法を繰り返していきます。このコード例が結構良くできていて、読み易いです。デザインパターンに出てくるようなコード例もあるのですが、具体的に、どういう問題をどのように解決するのかが示されていてわかりやすいです。
あまり喜ばれる言い方ではないかも知れませんが、「継続的デリバリーのソフトウェア工学」の[第3部「複雑さ管理の最適化」](https://qiita.com/sakisakira/items/f0569b3dc538ee5864ab#第3部複雑さ管理の最適化)の内容を、より具体的かつコード例も豊富にしたような本であると感じました。

告白すると、かつての自分にはソフトウェアに保守しやすさが大事であるとの観念はありませんでした。保守に力点を置いた本を読んでもその利点を理解できていませんでした。自分の場合には、保守に関してOSS活動や仕事やらで痛い目に合い続けることで、かつて読んだ本に書かれていた保守の技法の意味がようやくわかってきたというのが正直なところです。本の書き方が抽象的であって具体的なコードに当て嵌めるだけの理解力が自分に足りなかったんだろうなとも思います。
この「良いコード／悪いコードで学ぶ設計入門」を当時の自分が読んでいたらひょっとしたらもっと早く保守を意識したソフトウェアを書けるようになっていたかもなと思います。偉そうなことを書きましたが、この本に書かれている方法の全てを私が実践できている訳でもなく、個人的に参考になる事柄が多く書かれています。(逆に自分ならこうしないという例もありましたが、細かい話なので置いておきます。)

最後の第17章も面白かったです。特に節17.1では「さらにステップアップするための設計技術書紹介」として、様々な本のどのような点が良いかを各々説明しています。自分が既に読んだ本に対する評価も適切であると感じたので、読んでない本の内に次に何を読むべきかの判断に役立ちそうでワクワクします。
実のところ、この本を買うかどうか迷っていたときに、目次にこの節を見つけて購入を決めました。

評価されるだけの本だなと思いました。書いて終わりではなくメンテナンスが必要となるソフトウェアには、この本にあるような保守に対する意識・技術が必要です。多くのソフトウェアエンジニアに読んで欲しいと思われた本です。
【論文読み】Transformerによる時系列予測

## はじめに
こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「Transformerによる時系列予測」という論文です。  

- タイトル： 【論文読み】Transformerによる時系列予測
- 出典： 本田 良司, et al.; 人工知能学会、 2020   
- URL： https://www.jstage.jst.go.jp/article/pjsai/JSAI2020/0/JSAI2020_1N4GS1301/_pdf/-char/ja


## 概要
自然言語処理で発展しているTransformerを、時系列予測に応用できるかを評価。


## 特徴
- 比較モデル
    - LSTNet
        CNN,RNN,VAR(多変量自己回帰モデル)を合わせRNNにski-connectionまたはattentionを導入
    - MTNet
        時系列依存の情報を記憶、CNN,RNNを内部に蜜。LSTNetより精度が高い

- Transformerによる時系列予測
    最終的に予測したt×D(説明変数の次元)の多変量予測値の内、目的変数の部分のみを数値に戻してdで平均を取り予測値とする。

- 実験データ
    - 1つ目
        - PM2.5濃度を目的変数とし、湿度、温度、気圧、風向、風速、降雪量、降雨量が説明変数
        - 5年分の1時間毎のデータ
    - 2つ目
        - ECMWFの提供している東京地点の予報値と、気象庁のアメダス東京地点の観測値を使って、24時間先までの予測値を計算
        - 予測値は51種類、観測値を含めて52変数のデータ
        - 2017~2019の3年分の1時間毎のデータ、ECMWFの3時間毎予測を内挿
        - 気温を予測

- まとめ
    説明変数が多変量で目的変数が一変量である時系列予測には、Transformerが良い精度を与えうる


## 想定される適用例
- 多変量時系列の回帰予測全般  


## 参考
- [Transformerによる時系列予測](https://www.jstage.jst.go.jp/article/pjsai/JSAI2020/0/JSAI2020_1N4GS1301/_pdf/-char/ja)
【メモ】SQL Server Management Studio (SSMS) インストールできない

RDS for SQL Server にログインしたくて SSMS をインストールしようとしたら、以下のようにエラーになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/2d0be3f5-a671-c2a3-06ef-415fae46ddef.png)

```
セットアップに失敗しました
インストール中に致命的なエラーが発生しました。(0x80070643)
```

Microsoft サイトでエラーを調べたが、

https://learn.microsoft.com/ja-jp/sql/ssms/troubleshoot/install-failed-requires-restart?view=sql-server-ver16

このサイトに記載されている "Microsoft ODBC Driver 17 for SQL Server" は手元の端末（Windows 10）にインストールされていなかったので困った。

もう少し調査したところ、以下記事の対応方法で無事インストールできた。

https://oooomincrypto.hatenadiary.jp/entry/microsoft-sql-server-management-studio-install-error

解決方法は [Visual Studio 2013 の Visual C++ 再頒布可能パッケージ](https://www.microsoft.com/ja-jp/download/details.aspx?id=40784) をインストールしてから SSMS のインストールを実行するとうまくいった。

## SSMS インストーラーダウンロード
SSMS のインストーラーは以下ページからダウンロードできる。

https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16

上記サイトにアクセスしてすぐ「SQL Server Management Studio (SSMS) 18.12.1 の無料ダウンロード」というリンクがあるが、今回は日本語版をインストールしたいので少しスクロールして日本語版のリンクをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/37fe4f47-c3ba-345a-60c6-2d4b8843760d.png)

「SSMS-Setup-JPN.exe」がダウンロードできるので、実行する。

## 参考

https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16

https://learn.microsoft.com/ja-jp/sql/ssms/troubleshoot/install-failed-requires-restart?view=sql-server-ver16

https://oooomincrypto.hatenadiary.jp/entry/microsoft-sql-server-management-studio-install-error
Javaでハッシュ値を生成する

JavaでSHA1, SHA256のハッシュ値を作成するには、[MessageDigestクラス](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/security/MessageDigest.html)を使用します。

## byte配列を16進数文字列で出力する

Java17から標準クラスライブラリである[HexFormatクラス](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/HexFormat.html)でbyte配列を16進数文字列で変換することが出来るようになりました。

## サンプルプログラム

SHA1, SHA256アルゴリズムでハッシュ値を生成し、出力するプログラムです。

```java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;

public class HelloWorld_SHA {

	public static void main(String[] args) {

		// SHA-1
		try {
			MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
			byte[] sha1Byte = sha1.digest("Hello World".getBytes());
			
			//Java17以降からしか使用出来ない
			HexFormat hex = HexFormat.of().withLowerCase();
			String hexString = hex.formatHex(sha1Byte);
			System.out.println("SHA1");
			System.out.println(hexString);
		}
		catch (NoSuchAlgorithmException e) {
			
		}
		
		// SHA-256
		try {
			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
			byte[] sha256Byte = sha256.digest("Hello World".getBytes());
			
			//Java17以降からしか使用出来ない
			HexFormat hex = HexFormat.of().withLowerCase();
			String hexString = hex.formatHex(sha256Byte);
			System.out.println("SHA256");
			System.out.println(hexString);
		}
		catch (NoSuchAlgorithmException e) {
			
		}
	}

}

```

## 参考情報
https://www.sra.co.jp/Portals/0/files/gsletter/pdf/GSLetterNeoVol164.pdf
TypeScript: Date を "YYYY年MM月DD日" にしたい

# 背景
Date を特定の書式にしようとしたところ・・また詰まったので、調査してみた記録

2022/02/02 みたいなのであれば、intl.DateTimeFormat が一番かな、とは思うんですけどね

# 結論
Intl.NumberFormat / dayjs のどちらかを使う、かな・・と
前者の方が速いけど、書式フォーマットで出来るので dayjs のが分かりやすい

## Intl.NumberFormat を使う
```typescript: フォーマット
const intlNumberFormat = new Intl.NumberFormat('ja-JP', { minimumIntegerDigits: 2 });
const getDateString2 = (date: Date) => {
    return `${date.getFullYear()}年${(intlNumberFormat.format(date.getMonth() + 1))}月${intlNumberFormat.format(date.getDate())}日`;
};
```

##  dayjs を使う
```typescript: フォーマット
const getDateString = (date: Date) => {
    return dayjs(date).format("YYYY年MM月DD日");
};
```
TypeScript で使う

https://day.js.org/docs/en/installation/typescript

Format はこちらで

https://day.js.org/docs/en/display/format

# 調査記録
## DateTimeFormat を使う
dateStyle: 'long' でいい感じなんだけど、月日の表示が一桁に省略されてしまう・・。


```typescript: format
const date = new Date(Date.UTC(2022, 1, 2, 3, 23, 16, 738));

console.log(new Intl.DateTimeFormat('ja-JP', { dateStyle: 'full', 
                                              timeZone: 'JST' }).format(date));
console.log(new Intl.DateTimeFormat('ja-JP', { dateStyle: 'long', 
                                              timeZone: 'JST' }).format(date));
console.log(new Intl.DateTimeFormat('ja-JP', { dateStyle: 'medium', 
                                              timeZone: 'JST' }).format(date));
console.log(new Intl.DateTimeFormat('ja-JP', { dateStyle: 'short', 
                                              timeZone: 'JST' }).format(date));
```

結果はこんな感じ

> "2022年2月2日水曜日"
> "2022年2月2日"
> "2022/02/02"
> "2022/02/02"

で、month: day: を '2-digit' で指定出来れば完璧だったんですが・・以下があって両立できず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3ce58407-f7ea-2c2f-623f-88d2804d2a3c.png)

ということで、結論に書いた二つへと

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat

# 計測
以下な感じで計測してみた。
結果は共有してないけど、dayjs の方が遅いかな？って程度

```typescript: measure
function measureExeFunc(executeFunction: { (timestamp: Date): string; (arg0: Date): void; }, date: Date) {
    var startTime = performance.now();
    executeFunction(date);
    var endTime = performance.now();
    console.log(`${executeFunction.name}: `, endTime - startTime);
}

measureExeFunc(getDateString, date);
measureExeFunc(getDateString2, date);
```

# あとがき
目的は、DynamoDB で日付文字列でソートが使えるように、zero padding したかった
ぶっちゃけ日本語である必要はない

まぁ、日本語好きな場合もありますし、調査することは大切かなぁ、って程度でした。
スクラムと文化人類学


スクラムガイドの「スクラムの理論」の章には次のような記述があります。
> スクラムは「経験主義」と「リーン思考」に基づいている。経験主義では知識は経験から生まれ、意思決定は観察に基づく。リーン思考では、ムダを省き、本質に集中する。[^1]

経験主義[^2]とは、empiricism のことなので、超経験的なものに依拠するのではなく、唯物論・実証主義のような考え方で、客観的に観察できた事象をもとに行動しようとするアプローチと言い換えることができます。

# 文化人類学との類似

こうしたスクラムのアプローチについて、文化人類学と類似する点があるように思います。どちらも人間に対して、質的な方法で理解を深めようとする活動だと言えるからです。
この記事では、スクラムでの開発活動と文化人類学のアプローチについて類似する点を考えてみます。

## 研究の目的
文化人類学[^3]は、人間の理解をその文化的側面から行うことを目的としています。
ITエンジニアが行うシステム開発でも、人間自身が暗黙的に行っている文化的な情報処理を、明文化された形で記述し、実行可能にすることが目的とされます。
両者とも人間の文化的な理解という意味で、半ばまでは同じ目的を共有していることになります。

## 理解のための方法
### フィールドワーク
ある調査対象について、その対象に関する客観的な事実を、調査対象自体が存在する場所に赴いて収集することが、フィールドワーク[^4]です。観察者がいて。一方に理解を深めるべき対象があり、その対象について客観的な事実の収集が必要であるという点において、システム開発でも同じようなアプローチが必要になります。
フィールドワークの中で実施する活動として文献調査、アンケート調査、聞き取り調査などがある点も同じです。

### エスノグラフィー（民族誌）
ある調査対象についての研究の結果を記述したものとして、エスノグラフィー[^5]があります。調査された事象は質的説明として記述されます。

# スクラムでは何を理解の対象にするのか

## プロダクトマネジメントの視点
スクラムのメンバーのうちプロダクトオーナーは、プロダクトを利用する人々を理解するために、このようなメソッドを利用することができます。[^6]
機能要件やユーザビリティは、質的な記述によって根拠を観察するべきものです。
（もちろん、一方で計量できるようなパフォーマンス要件は、量的な記述で価値を明示できます。）

## スクラムチームを運営する視点
スクラムマスターや開発者は、このようなメソッドをスクラムチーム自身に対して利用できます。
開発の活動の中で除去すべき障害について、客観的な観察から問題を特定し、解決が進んでいるかを見極める必要があります。
スクラムの理論が経験主義に基づいているということは、先に解決法があって、状況をそれに合わせるのではなく、スクラムチーム自身を先に観察する必要があるということです。
プロダクトオーナーやスクラムマスター自身や開発者について理解を深めるために、イテレーションについてのメトリクスを収集したり、聞き取りを行ったりする必要があります。

# 違い
スクラムチームが目指していることは、最終的に成果物を作り上げ、ユーザーに価値を届けることです。
この意味ではスクラムチームは、文化人類学的なアプローチを取りながらも、そのようにして自分たちのゴールを達成することができます。
一方で、スクラムチームは自分たちについて質的な理解を深めることが最終目的ではないため、それを通じてユーザーへの価値を最大化することを忘れないようにする必要があるでしょう。

[^1]: https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf
[^2]: https://ja.wikipedia.org/wiki/%E7%B5%8C%E9%A8%93%E8%AB%96
[^3]: https://ja.wikipedia.org/wiki/%E6%96%87%E5%8C%96%E4%BA%BA%E9%A1%9E%E5%AD%A6
[^4]: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%83%AF%E3%83%BC%E3%82%AF
[^5]: https://ja.wikipedia.org/wiki/%E6%B0%91%E6%97%8F%E8%AA%8C
[^6]: https://www.epicpeople.org/about-epic/
論文のrevisionをいい感じにするcommandたち

自分用メモ．
revisonのときに変更箇所をわかりやすくするためのコマンド，変数書き換えるだけで4パターンのバージョンを出力できる．

# 使い方
```latex
\setcounter{OutputVersion}{x}
% x = 0: submit, 1: revised, 2: diff, 3: highlight
Erase: \Erase{foo}
Add: \Add{bar}
Replace: \Replace{hoge}{fuga}
```

## OutputVersion=0のとき
revision前のテキストを表示

> Erase: foo
> Add: 
> Replace: hoge

## OutputVersion=1のとき
revision後のテキストを表示
> Erase: 
> Add: bar
> Replace: fuga

## OutputVersion=2のとき
差分を表示(本当は取り消し線と"bar"と"fuga"は赤字)
> Erase: <s style="text-decoration:line-through;color:red;">foo

> Add: bar
> Replace: <s style="text-decoration:line-through;color:red;">hoge
 fuga

## OutputVersion=3のとき
revision後のテキストを強調して表示(本当は"bar"と"fuga"は赤字)
> Erase: 
> Add: bar
> Replace: fuga

## 文中で使うときの注意

```latex
%これはダメ
This is \Add{an} apple. 
% OutputVersion=0のとき -> This is  apple.(スペース2個)
It is \Erase{the} rainy.
% OutputVersion=1のとき -> It is  rainy.(スペース2個)

%これはOK
This is \Add{an }apple. 
% OutputVersion=0のとき -> This is apple.
It is\Erase{ the} rainy.
% OutputVersion=1のとき -> It is rainy.
```

# コード
適宜プリアンブルの中で`\input{preamble.tex}`で挿入する．
行末の`%`は改行とインデントを無視させるため．

数式モードでの`\RobustSout`の出力はインラインなので\sumとか\fracみたいなでかいやつはちっちゃくなる．
どうせ消すので妥協していますが，いい感じにできる方法があれば教えてください．

```latex:preamble.tex
\usepackage{ulem, color}

\newcommand{\Remove}[1]{\if0{#1}\fi}  % 削除
\newcommand{\Redtext}[1]{\textcolor{red}{{#1}}}  % 赤字
\newcommand{\Blacktext}[1]{\textcolor{black}{{#1}}}  % 黒字

\DeclareRobustCommand{\redsout}{\bgroup\markoverwith{\Redtext{\rule[.5ex]{2pt}{0.6pt}}}\ULon}  % 赤取消し線

\newcommand{\RobustSout}[1]{%
    \relax%　これがないとalign環境などでおかしくなる
    \ifmmode%  数式モードか否か
        \hbox{\redsout{$#1$}}%  数式モードなら\hboxで抜けて線引いて数式モードに戻る
    \else%
        \redsout{#1}%
    \fi%
}

\newcounter{OutputVersion}%  counter(変数的な?)を定義
% OutputVersion
% 0: submit, 1: revised, 2: diff, 3: highlight
\setcounter{OutputVersion}{1}%  値をセット
% \value{OutputVersion}で値を取得
% \ifnum[不等式]で判定
\newcommand{\Erase}[1]{%
    \ifnum\value{OutputVersion}=0%
        {#1}%
    \else%
        \ifnum\value{OutputVersion}=2%
            \RobustSout{#1}%
        \else%
            \Remove{#1}%
        \fi%
    \fi%
}

\newcommand{\Add}[1]{%
    \ifnum\value{OutputVersion}=0%
        \Remove{#1}%
    \else%
        \ifnum\value{OutputVersion}=1%
            {#1}%
        \else%
            \Redtext{#1}%
        \fi%
    \fi%
}

\newcommand{\Replace}[2]{%
    \ifnum\value{OutputVersion}=2%
        {\Erase{#1} \Add{#2}}%  diffのときスペースを入れて見やすくするだけ
    \else%
        {\Erase{#1}\Add{#2}}%
    \fi%
}
```

## 参考
http://mirrors.concertpass.com/tex-archive/macros/latex/contrib/ulem/ulem.pdf

https://qiita.com/ultimatile/items/3982b1f69bc277ddb9ba

https://beiznotes.org/latex-strike-out-in-equation/

https://zrbabbler.hatenablog.com/entry/20151211/1449838215

http://www.yamamo10.jp/yamamoto/comp/latex/make_doc/basic/index.php#BASIC_COMMENT
GPT-3で漫画タイトル生成 


**工事中**

## 目次
1. GPT-3のapi利用申請
    1. アカウント作成
    1. APIキーの取得
    1. ＊＊＊
2. 環境
    1. ＊＊＊
1. アプリ案
    1. あらすじから生成
    1. 画像から生成
    1. ジャンルから生成
    1. デザイン


## 環境


  ```json:package.json
  "dependencies": {
    "@chakra-ui/react": "^2.4.9",
    "@emotion/react": "^11.10.5",
    "@emotion/styled": "^11.10.5",
    "@next/font": "13.1.1",
    "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-share": "^4.4.1"
  }
  ```


## アプリ案

### あらすじから生成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/8a8e9406-f650-6104-429f-8786f94a20c8.png)

↑イメージ図。
最近ジャンププラスで読んだ読切です。(斬新、控えめに言って最高だった)
引用：こちら(https://shonenjumpplus.com/episode/316190247056444405)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/fecef371-069f-7c63-e7f8-471aad1648dd.png)

↑ChatGPTに頼んでみた。

頼み方を工夫すればなかなかいい線いってる？？
"もっとキャッチ―にして"と言ったらそれっぽくなった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/4cdd0d83-b1d6-e33f-5521-bdd2ce024964.png)


**あらすじが既にある人向け**。
あらすじ生成もGPT-3を使用して同じ要領で作れる？

### 画像から生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/22b637ef-0be0-8243-4d5c-68d0133ddd71.png)

画像からテキストを生成するのは安直だが、モノによっては良いかもしれない。
例えば、ハイキュー、SPY×FAMILY、チェンソーマンなど、話やキャラが一発で分かるタイトル。

一方、ダンダダンやボボボーボ・ボーボボ等の一般に意味を持たない言葉を使用するタイプのタイトルを作る際には微妙？

**とりあえず漫画書いてみた人向け**。作成した漫画画像をぶち込んでみたら気に入ったタイトルが出てくると楽しそう。

### ジャンル等から生成

私の技術的にはこちらが本命。

- 学園漫画 - 学生群像を描いた漫画
- ギャグ漫画 - ギャグ描写を中心にした漫画
- ファンタジー漫画 - ファンタジー要素が含まれた漫画
- SF漫画 - SFを題材にした漫画
- ホラー漫画 - ホラーを題材にした漫画
- 恋愛漫画 - 恋愛を主題にした漫画
- ラブコメ漫画 - 恋愛を主題にしたコメディ漫画
- スポーツ漫画 - スポーツを題材にした漫画
- 野球漫画 - 野球を題材にした漫画
- サッカー漫画 - サッカーを題材にした漫画
- 音楽漫画 - 音楽を題材にした漫画
- 料理漫画 - 食に関することを題材にした漫画
- 推理漫画 - 「ミステリー漫画」もしくは「探偵漫画」とも称される
- 医療漫画 - 医療を題材にした漫画
- 格闘漫画 - 格闘技や戦闘を題材とした漫画。「バトル漫画」とも称される。
- 歴史漫画 - 歴史上の人物や出来事を題材とした漫画。近代以降の戦闘を描いたものは「戦争漫画」と呼ばれる。
- エッセイ漫画
- レポート漫画

引用Wiki(https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E3%81%AE%E6%BC%AB%E7%94%BB)

ジャンルの他に以下のパラメータも加味する？
- 表現形式(1ページ漫画、4コマ漫画、コミック、webtoon)
- 連載形式(連載か、読切か)
- 投稿場所(ジャンプルーキー、漫画ボックスインディーズ、＊＊＊)
    - https://storymaker.click/%E6%BC%AB%E7%94%BB/5363/
- 対象読者(少年、青年、少女、女性)


**全般向け**。誰でも使える

### デザイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092463/39786498-e40d-ee58-3f01-e685d3540944.png)
↑のようなデザインが理想
*引用:(https://1password.com/jp/password-generator/)*


## 参考
- https://zerebom.hatenablog.com/entry/2021/12/07/082607
    - ブログのタイトル生成の記事
- https://data-analytics.fun/2021/12/01/gpt-3-api/#toc2
    - 文章生成によるアイデア出しの部分を参考にする
草莽Erlang ── 11. パターンマッチ

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

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

## マッチ演算子

`=`演算子は代数学でいうところの等号に相当するものです。左辺と右辺の値をマッチさせ、マッチに成功すると、式の値が返されます。失敗する場合はエラーを投げます。

https://www.erlang.org/doc/reference_manual/expressions.html#patterns

https://learnyousomeerlang.com/syntax-in-functions#pattern-matching

まずは単純なマッチングを試してみます。

```erlang
> X = 1.
1

> 1 = X.
1

> 2 = X.
** exception error: no match of right hand side value 1
```

リストでマッチングを試してみます。

```erlang
> L1 = [1, 2, 3].
[1,2,3]

> [1, 2, 3] = L1.
[1,2,3]

> [] = L1.
** exception error: no match of right hand side value [1,2,3]

> [1 | Tail] = L1.
[1, 2, 3]

> Tail.
[2, 3]

> [2|_] = L1.
** exception error: no match of right hand side value [1,2,3]
```

タプルでマッチングを試してみます。

```erlang
> {ok, Value} = {ok, "Successful!"}.
{ok,"Successful!"}

> Value.
"Successful!"

> {ok, Value} = {error}.
** exception error: no match of right hand side value {error}
```

マップでマッチングを試してみます。

```erlang
> #{y := Y} = #{x => 1, y => 2}.
#{x => 1,y => 2}

> Y
2
```

## 束縛

Erlangでは一度変数が束縛されると、値の変更はできません。

```erlang
> Z = 1.
1

> Z = 2.
** exception error: no match of right hand side value 2
```

## 関数

Erlangではパターンマッチは変数だけに限定されているわけではなく、関数へと適用することもできます。

最初にマッチするオプションが実行されます。

```erlang
> F = fun (ok) -> a; (error) -> b; (_) -> c end.
#Fun<erl_eval.42.3316493>

> F(ok).
a

> F(error).
b

> F(hello).
c
```

https://elixirschool.com/en/lessons/basics/functions

## Elixirにも挑戦したい

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

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

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
ScribusでLuaLatexを利用できるようにする

## はじめに
ScribusはオープンソースのDTP(Desktop Publishing)ソフトウェアです。

DTPソフトウェアと言ったらAdobeのInDesignが最も使われていると思いますが、有料かつ不自由なソフトウェアなため、Scribusはその代替として機能します。
~~(不自由なソフトウェアを使っている兄貴はいねえよなぁ！？)~~

機能面でも充実しており、概ねやりたいことは出来ます。

ただ、英語で開発されており(というか殆どのOSSがそう)、日本語の扱いがあまり良くありません。
特に現状は縦書きが出来ないため、そこは妥協せざるを得ません。
日本人にとってその点は大きなマイナスですね。

そんなScribusですが、Latexを利用することが出来ます。
数式を沢山利用する兄貴たちには嬉しい機能だと思います。
ただ、そのままだとLatex内で日本語を使うことが出来ないので、今回はその紹介です。

環境としてはArch LinuxベースのManjaroを使っていますが、どのディストロでも大きくは変わらないと思います。
ただTexlive等でLuaLatexが使える状態にしておいてください。

## 手順

1. Scribusを開き、"ファイル>設定>外部ツール"に行く

2. "フレームを描画"の設定内にある"Latex"を選択し、変更をクリック

3. "latex --interaction nonstopmode" と書いてあるのを
    "lualatex --interaction nonstopmode" に書き換える。

4. "Uniconvertor"の"実行ファイル名"にlualatexのpathを書く。
    私の場合は "/usr/bin/lualatex" です。

5. OKボタンを押し、設定を確定させる。
これでLatexを用いる時にLuaLatexを使うようになります。
次に実際に利用していきます。

6. ツールバーから"RenderFrame"をクリックし、画面上にてクリック&ドラッグで適当な大きさのフレームを作ってあげます。
この時点で英語と数式らしきものがフレーム内にあれば、正常にTexが使えているということです。
その際に文字がぼやけて見えると思いますが、おそらくこれは仕様で、PDF化する時にはきれいに表示されるため問題はありません。

7. フレーム内で右クリックし、"ソースを編集"をクリック

8. "Fonts/Headers"のタブにある"Additional Headers"に "\usepackage{luatexja}" を書き加える。
この作業で日本語を表示されるようになります。

9. 後は自由に、"オプション"タブの"コードを入力"のボックス内か、"外部エディタを実行"でソースコードを書いて、日本語でLatexな文章を表示させることが出来ます。
お疲れ様でした。

## 最後に

本当に、後は縦書きさえ出来ればという感じなので、技術書等を出版される際に一度使ってみてはいかがでしょうか。
日本語の情報は他のOSSに漏れずあまりありませんが、英語でならYoutubeにでも使い方が載っているのでそちらで学習できます。
Java Enum(列挙型)

enumを使ったメソッドを作成した時の備忘録。
変数に決められた値を入れるときは、enum型を使うのは基本のようですね。

```java
private enum MDID {
    IPHONE("001"),
    ANDROID("002"),
    IPAD("003"),
    TABLET("004");

    private String modelId = "";
    private MOID(String modelId) {
        this.modelId = modelId;
    }

    public String getId() {
        return this.modelId;
    }
}

private enum SVID {
    PRICE("0010"),
    DATA("0020"),
    NEWS ("0030");

    private String serviceId = "";
    private SVID(String serviceId) {
        this.serviceId = serviceId;
    }

    public String getId() {
        return this.serviceId;
    }
}

public Map<String,String> getState() {
    Map<String String> ret = new HashMap<String,String>();

    String contentModelId = "";
    List<String> contentServiceList = new ArrayList<String>();

    if (条件1) {
        contentModelId = MDID.IPHONE.getId(); //001
        contentServiceList.add(SVID.PRICE.getId()); //0010
    } else if (条件2) {
        contentModelId = MDID.ANDROID.getId(); //002
        contentServiceList.add(SVID.DATA.getId()); //0020
    } else if (条件3) {
        contentModelId = MDID.IPAD.getId(); //002
        contentServiceList.add(SVID.NEWS.getId()); //0030
    } else if (条件4) {
        contentModelId = MDID.TABLET.getId(); //003
        contentServiceList.add(SVID.DATA.getId()); //0020
        contentServiceList.add(SVID.NEWS.getId()); //0030
    }

    if(contentServiceList.size() == 0) {
        return ret;
    }

    ret = this.AnotherMethod(contentModelId,contentServiceList)
    return ret;
}
```

## 簡単に解説
MOID.IPHONEにすることで、enum内のコンストラクが動く
```java
    contentModelId = MDID.IPHONE
```

コンストラクトによって変数modelIdに引数である001が入る。
```java
    IPHONE("001");//引数は001

    private String modelId = "";
    private MOID(String modelId) { //コンストラクトが動く 引数は001
        this.modelId = modelId; //001が変数のmodelIdに入る
    }

    public String getId() {
        return this.modelId;
    }
```
getId()でmodelIdを取得するので001がcontentModelIdに入る
```java
contentModelId = MDID.IPHONE.getId();
```

enumの基本的な使い方でした:disappointed:
R にインストール済みのパッケージのバージョンを確認する方法

### 概要
Rで解析した結果を論文に記載したり、論文の内容を自身の環境で再現する際に、インストールされたパッケージのバージョンを確認する必要がると思います。

インストール済みのパッケージのバージョンを確認する関数には、「packageVersion」があります。

### プログラムの実行
使い方は以下の通りです。

```r
packageVersion("パッケージ名")
```

以下に、コマンドの例を示しておきます。
```r
packageVersion("clusterProfiler")
> [1] ‘4.2.2’

packageVersion("ggplot2")
> [1] ‘3.3.6’
```

ご覧いただきどうもありがとうございました。
【Android】`Failed to resolve: androidx.appcompat:appcompat-resources:1.4.2エラー`が出た時の対処法

# 依存関係を解決できないというエラーが発生

ある日、古くなっていたmainブランチの内容を最新のものに反映させるために、Android Studioにてブランチのアップデート、合わせbuild.graldeの同期を行いました。

最後にコミットした時には、アップデートを行なった開発環境ではなく、別の開発環境にて作業をしていました。その時には、依存関係に関するエラーが発生することはありませんでした。

ところが、最新の内容に更新されたbuild.gradleの同期を行った際に、次のようなエラーが発生しました。

```shell
Failed to resolve: androidx.appcompat:appcompat-resources:1.4.2
Add Google Maven repository and sync project
Show in Project Structure dialog
Show Details
Affected Modules: app
```

# エラーの原因はio.coil-kt:coil:2.2.2だった

エラーの内容を調べていたら、この問題の原因が`io.coil-kt:coil:2.2.2`らしいことに辿り着きました。

```shell
* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not resolve androidx.appcompat:appcompat-resources:1.4.2.
     Required by:
         project :app > io.coil-kt:coil:2.2.2 > io.coil-kt:coil-base:2.2.2
      > No cached version of androidx.appcompat:appcompat-resources:1.4.2 available for offline mode.
      > No cached version of androidx.appcompat:appcompat-resources:1.4.2 available for offline mode.
```

# エラーの内容を元に、試しに依存関係を追加してみたが・・・

そこで、試しにバージョン`1.4.2`の`androidx.appcompat:appcompat-resources`を`depdencies`に追加してみることにしました。

```gradle
implementation("androidx.appcompat:appcompat-resources:1.4.2")
```

そして、build.gradleの同期を行いましたが、再度次の内容のエラーが発生しました。

```shell
Failed to resolve: androidx.appcompat:appcompat-resources:1.4.2
Add Google Maven repository and sync project
Show in Project Structure dialog
Show Details
Affected Modules: app
```

試しにプロジェクトのビルドを行なってみたのですが、次の内容のエラーが表示されてしまい、ビルドに失敗してしまいました。

```shell
No cached version of androidx.appcompat:appcompat-resources:1.4.2 available for offline mode.
Disable Gradle 'offline mode' and sync project
```

# 安定版を依存関係に追加することで解決

上述のエラーの内容から察して、`1.4.2`のバージョンの`androidx.appcompat:appcompat-resources`がリポジトリにて見つからないのだろうと思いました。

そこで、公式ドキュメントのリリースノートで、`AppCompat`の内容を確認しました。

https://developer.android.com/jetpack/androidx/releases/appcompat?hl=ja

安定版として`1.5.1`が公開されていることがわかったので、次の依存関係を追加してみることにしました。

```gradle
implementation("androidx.appcompat:appcompat-resources:1.5.1")
```

そして、build.gradleの同期を行いました。結果、エラーは消え同期に成功しました。同様にプロジェクトのビルドにも成功しました。

```shell
> Task :prepareKotlinBuildScriptModel UP-TO-DATE

BUILD SUCCESSFUL in 468ms
```

# まとめ

依存関係が解決できない系のエラーが発生した場合は、一回落ち着いてエラーログをよく読み、対象のライブラリの現在のバージョンを確認してみることをオススメします。~~（将来の自分へ）~~
RP2040-Zero + Arduino IDEでI2CやSPIのピン割り当てに苦労した話

## この記事は？
RP2040搭載の安いマイコンボード [Waveshare RP2040-Zero](https://www.waveshare.com/wiki/RP2040-Zero)で、Wire (I2C)とSPIにを同時に使うため、割り当てられるピンを変更しようとして結構ハマりました。対処方法を備忘録かねて記事にします。
本記事ではRP2040-Zero + Arduino IDEの環境ですが、ほかのRP2040を使ったマイコンボード（Raspberry Pi Picoなど）を使う場合でも同じようにできるんじゃないかと思います。

## 環境
マイコンボード：RP2040-Zero (RP2040搭載）
IDE: Arduino IDE 2.0
ライブラリ：Arduino Mbed RP2040 Boards

## RP2040-Zeroについて
RP2040はRaspberry Pi財団開発のマイコンです。最近すごくホットですね。  
公式SDKを利用してC/C++で開発したり、MicroPythonで開発することが多いと思います。
Arduino公式のパッケージ（Arduino Mbed RP2040 Boards）を導入するとArduino IDEで開発することができます。※1

RP2040-Zeroは、Waveshare社が販売する、RP2040搭載のマイコンボードです。
![PXL_20221118_144254421.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166634/4b38d361-3247-cc58-ea42-b38c89ecf239.jpeg)

[スイッチサイエンス](https://www.switch-science.com/products/7886?_pos=1&_sid=036487e72&_ss=r)では700円弱、[Aliexpress](https://ja.aliexpress.com/w/wholesale-rp2040%2525252dzero.html?catId=0&initiative_id=SB_20230106064924&SearchText=rp2040-zero&spm=a2g0o.home.1000002.0&dida=y)だと500円くらいで手に入ります。Raspberry Pi Picoよりちょっと安いですね。
価格そうですが、一部のピンをパッドに引き出す、ボードの裏表に部品を実装するなどにより（このため表面実装はできません）、RP2040よりかなり小さいサイズもこのボードの魅力です。
Raspberry Pi Picoの21mm×51.3mmに対し、RP2040-Zeroは18mm×23.5mmです。半分くらいですね。
あとUSB Type-C接続なのが地味にうれしかったりします。

## ピンの割り当てについて
RP2040はI2CおよびSPIのユニットをそれぞれ2つずつ搭載しており、それぞれの信号用端子を複数のピン組み合わせから選択して割り当てることができます。
一方、Arduino IDE + Arduino Mbed RP2040 Boardsを使用する場合、I2CおよびSPIのピン割り当てはライブラリ内であらかじめ以下のように設定・固定されています。
|ピン種別|ピン|
|--|--|
|I2C SDA|GP7|
|I2C SCL|GP5|
|SPI MISO|GP16|
|SPI CS|GP17 |
|SPI SCK|GP18 |
|SPI MOSI|GP19 |

Arduinoスケッチの`setup()`に制御が移る前に各モジュールの初期化が完了しているため、`setup()`内ででピン割り当てを変更しようとするとプログラムがクラッシュしたりします。（Raspberry Pi Picoの場合、プログラムがクラッシュするとLEDが点滅します）

これを変更するには、ピンの定義をしている`pins_arduino.h` を直接編集します。
`pins_arduino.h`はデフォルトだと`C:\Users\[ユーザ名]\AppData\Local\Arduino15\packages\arduino\hardware\mbed_rp2040\[バージョン]\variants\RASPBERRY_PI_PICO`に配置されています。
コード中の以下の箇所を、所望の設定に書き換えます。
```pins_arduino.h
//L45~

//SPI
#define PIN_SPI_MISO  (16u)
#define PIN_SPI_MOSI  (19u)
#define PIN_SPI_SCK   (18u)
#define PIN_SPI_SS    (17u)


//L55~

// Wire
#define PIN_WIRE_SDA        (4u)
#define PIN_WIRE_SCL        (5u)
```

それぞれのピンの名前でマクロ定義される数値を、GPIOの番号（注：ピン番号ではありません）に変更します。
例えば僕の場合、SPIをGP4～GP7、I2CをGP12,13に割り当てたかったので、以下のように編集します。
```pins_arduino.h
//L45~

// SPI
#define PIN_SPI_MISO  (4u)
#define PIN_SPI_MOSI  (7u)
#define PIN_SPI_SCK   (6u)
#define PIN_SPI_SS    (5u)


//L55~

// Wire
#define PIN_WIRE_SDA        (12u)
#define PIN_WIRE_SCL        (13u)
```

あとは通常通りスケッチを作成・ビルドし、ボードに焼いてやると、設定したピンでI2C/SPIが使用できます。

RP2040-Zeroを使用する場合、一部マイコンのピンがパッドに引き出されている関係でピンアサインが干渉しやすく、デフォルトからの設定変更がほぼ必要となってきます。
このやり方でうまくピン割り当てを変更してやると、所望のモジュールが問題なく使えるようになります。

※1: Arduino IDE用RP2040パッケージは公式のものと別に非公式で有名なやつがあって、そっちの方が開発楽っぽいですね・・・そっちでもI2Cなどのピン割り当て変更できないか、時間があるときに確認してみようと思います
麻雀で学ぶTypeScript 3 鳴き

前回：[麻雀で学ぶTypeScript 2](https://qiita.com/bonetaro/items/4a95111ce30e70934189)
ソースコード：https://github.com/bonetaro/mahjong-ts

鳴きの実装のうち、とりあえず暗槓だけ実装しました。
![スクリーンショット 2023-01-07 184900.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4989/b56ed00c-1b8e-492a-2a0d-7146c8852b41.png)

前回、局の進行がとりあえずできるところまで実装して、軽い気持ちで次に鳴きの処理を実装し始めましたが、泣きたくなるくらいめんどいですね。麻雀のアクションがツモかロンだけなら、もっとシンプルな実装なのに・・・なんてぼやきながら実装してます。

だいぶ実装が大変になってきたので、イカサマモード(cheat)をつくりました。（ゲーム開発なら当たり前ですかね汗）まだ親の配牌を積み込みできるだけですが、いろいろなイカサマができるような仕組みを入れて遊びたいですね。

実際に麻雀をするときには意識していなかったのですが、鳴きにはいろいろな概念がありますね。暗か明か、誰から鳴いたか、順子ならどの組み合わせかなどなど。

実装上は、槍槓がエグいですね。他のは、捨て牌かツモリ牌でアガリですが、槍槓のアガリ牌（加槓の牌）は、捨て牌ではないですよね？

よく考えると、暗槓は「暗」なのに副露しているのもよく考えるとモヤモヤしますね。字面からも「明」がさらしている（=副露）、「暗」がそうではないって思ったら、そういう意味はないんですかね。歴史的な経緯とかあるのかな。

あと、リーチ後に積もった牌で暗槓するときは、待ちが変わらないものに限るというのも見落としがちですね。

なんか麻雀の話ばっかりでTypeScriptの話をしていないので、少しはTypeScriptの話も。

TypeScriptのoverloadはちょっとほかの言語と比べると癖がありますね。解説記事は良いものがたくさんありますので、詳細はそちらを参考にしていただくといいですが、シグネチャと実装を分けるんですね。これはこれで書きやすい気もします。

https://typescriptbook.jp/reference/functions/overload-functions

あと、気になっていたjestのカバレッジはオプションで簡単に確認できますね。

```
jest --collectCoverage
```

![スクリーンショット 2023-01-07 191043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4989/d1acb1e7-d7ba-33b6-ae7b-4c54ef5defc9.png)

今更ですが、便利ですね。お仕事では、テストコード書いてないんですが:-p、書かないと損ですね、こりゃ。出力の意味から少しずつ勉強していきます。
【Ultimate Member】ブロガー向けのプレスリリース投稿サイトを作ったので備忘録

プログラミングとか分かりません。
分からないなりにプレスリリース投稿サイトを作ってみたので備忘録置いておきます。

<h2>【ブロリリ】プレスリリース投稿サイト（無料）</h2>

作ったのは「ブロリリ」という無料のプレスリリース投稿サイトです。

https://japan-release.net/

CMS：Wordpress。
テーマ：SWELL

主なプラグイン：

Ultimate Member
会員制サイトを作るためのプラグイン。
登録・ログインフォームを作れたりなどなど～。

Ultimate Member - reCAPTCHA
登録時やログイン時に「あなたロボットじゃないですよね？」的なチェックをするためのやつ。

WP User Frontend
ユーザーがWordpressの管理画面に入らずに、フロント画面から記事を投稿できるようにするためにインストールしてます。

WP ULike
投稿した記事に「いいね」ができるように。

XO Security
ログイン管理とかセキュリティもろもろ。はじめは「SiteGuard WP Plugin」というセキュリティプラグインを入れてましたが、正しいパスワードを入力してもログインできない事象が発生したため、こちらに乗り換えました。

<h2>Ultimate Member「0」で新規登録できてしまう問題</h2>
サイトを作っている途中、少し困ったことがありました。

それは、登録フォームのユーザー名入力を"3桁以上"と設定しているにも関わらず、登録画面で「0」と入力すると通っちゃう問題です。
（本来なら「0」と入力して登録ボタンを押すとエラーメッセージが出るのが正しいはず）

ちなみに(1)
「00」や他の一桁の数字で試した場合はちゃんと弾かれました。

ちなみに(2)
一桁の「0」で新規登録フォーム通っちゃうんですが、その際に実際にユーザー名として登録されたのはメールアドレスのユーザー名部分でした。

解決方法としては
Wordpress管理画面の左メニューから
1.「Ultimate Member」の「設定」
2.アクセスタブを選択し、その他を選択
3.「Blacklist Words (Enter one word per line) 」に「0」を追加
![ul.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988047/27442a2a-834d-d855-cbd9-102c9de30d6e.png)


「Blacklist Words (Enter one word per line) 」は、特定のユーザー名で新規登録できなくするブラックリスト的な項目のようですね。
ここに手打ちで0を追加して解決しました。

<h2>あきらめたこと1：Twitterアカウントでの登録</h2>
解決できたことばかりではありませんでした。

Twitter垢で登録できるようにしたいと思い、ジャイアニズムというプラグインを取り入れました。
実際Twitter垢で登録できたのですが、そうすると登録フォームの「利用規約に同意する」にチェックを入れなくても登録できてしまうようになりました。
さすがに利用規約への同意は回避させたくないなと思い、導入はあきらめました。

<h2>あきらめたこと2：外部リンクを開くと英語で警告が出る</h2>
もう一つあきらめたことがあります。

ユーザーのプロフィール画面（フロント画面）に外部サイトへのリンクが設定されている場合、そのリンクをクリックすると「This link leads to a 3rd-party website（外部サイトに行きますけど良いですかね？）」的なメッセージが挟まれます。
このワンクッションは要らないなぁと思いつつも、解決方法が分からずそのままにしてます。

「バグは夜更け過ぎに仕様へと変わるだろう」
の意味を知りました。

<h2>最後に</h2>
僕がエンジニアならもっとバリバリこだわっていたと思いますが、今はこれが限界なのでとりあえずこれで。

よく考えてみたら、僕は
ライターでもないし
デザイナーでもないし
マーケターでもないし
エンジニアでもないし

ただのブロガー。

なので、全部が中途半端だなぁとも思ったりしますが、今は"やること"に意味を持たせようと思います。
少しずつ、少しずつで。


被リンクを貼れる無料サイト「ブロリリ」について解説【宣伝できます】
https://nekasegi.org/buroriri/

ブロリリであなたのブログを宣伝しよう！
https://japan-release.net/313/
Rails6 – rspec + capybara のテストで Webpacker::Manifest::MissingEntryError

# 問題

rspecでページにvisitするだけでエラーが発生する

```rb
require 'rails_helper'

feature type: :feature do
  scenario do
    visit new_user_session_path
  end
end
```

# エラー

```
Failures:

  1) {:type=>:feature}
     Failure/Error: <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

     ActionView::Template::Error:
       Webpacker can't find application.js in /Users/yumainaura/projects/YumaInaura/rails6-app/public/packs-test/manifest.json. Possible causes:
       1. You want to set webpacker.yml value of compile to true for your environment
          unless you are using the `webpack -w` or the webpack-dev-server.
       2. webpack has not yet re-run to reflect updates.
       3. You have misconfigured Webpacker's config/webpacker.yml file.
       4. Your webpack configuration is not creating a manifest.
       Your manifest contains:
       {
       }
     # ./app/views/layouts/application.html.erb:9:in `_app_views_layouts_application_html_erb__639505929452759243_23340'
     # ./spec/features/login_spec.rb:5:in `block (2 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # Webpacker::Manifest::MissingEntryError:
     #   Webpacker can't find application.js in /Users/yumainaura/projects/YumaInaura/rails6-app/public/packs-test/manifest.json. Possible causes:
     #   1. You want to set webpacker.yml value of compile to true for your environment
     #      unless you are using the `webpack -w` or the webpack-dev-server.
     #   2. webpack has not yet re-run to reflect updates.
     #   3. You have misconfigured Webpacker's config/webpacker.yml file.
     #   4. Your webpack configuration is not creating a manifest.
     #   Your manifest contains:
     #   {
     #   }
     #   ./app/views/layouts/application.html.erb:9:in `_app_views_layouts_application_html_erb__639505929452759243_23340'

Finished in 6.57 seconds (files took 4.64 seconds to load)
1 example, 1 failure
```

# 解決？

webpacker.yaml の test の設定を development に合わせてみたら成功するようになった

以下はデフォルトの設定

```yaml
test:
  <<: *default
  compile: true

  # Compile test packs to a separate directory
  public_output_path: packs-test
```

developmentと全く同じ設定にしたもの

```yaml

test:
  <<: *default
  compile: true

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: localhost
    port: 3035
    public: localhost:3035
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    compress: true
    disable_host_check: true
    use_local_ip: false
    quiet: false
    pretty: false
    headers:
      'Access-Control-Allow-Origin': '*'
    watch_options:
      ignored: '**/node_modules/**'
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Azure Administrator AssociateとAzure Solutions Architect Expertを更新してみた

有効期限の6か月前になり、通知メールを受け取りましたので、更新をしてみました。

「AZ-104: Microsoft Azure Administrator」と「AZ-305: Microsoft Azure Infrastructure Solutions の設計」が過去近い期間で取得したため、この2件を更新しています。
なお、AZ-104とAZ-305を保持していると「Azure Solutions Architect Expert」となるため、AZ-104に対する更新案内は「Azure Administrator Associate」、AZ-104&AZ-305に対する更新案内は「Azure Solutions Architect Expert」となるようです。

# 概要
- 更新は、Microsoft Learnから評価試験(選択問題の30問弱)を受けて、60%前後の合格率を超えると更新となります。
- 無料となります。
- 評価試験は、予約無しでいつでも何度でも受けることができますが、一度落ちると次の試験が24時間後となるようです。
が、私は1回目不合格でしたが、2回目をすぐに受けることができました。(2回までは連続して受けることができるかもしれません)
- 試験時間は45分と記載されていますが、試験を始めてもカウントダウンの表示は無いため、無制限かもしれません。
- 試験監督や専用の試験アプリは無く、Microsoft Learnの中で受けることができます。
- 試験中はドキュメントや本などを見ながら進めることができます。画面もキャプチャできますので、あとで復習も可能です。
- 試験に合格すると有効期限が1年更新されます。合格日から1年後ではなく、当初の有効期限から1年となります。

# 更新の流れ
1. 「アクションが必要です - Microsoft 認定資格は 180 日後に期限切れになります!」という件名のメールを受信します。
1. その中の[認定資格を更新する]をクリックすると更新サイトが表示します。
※英語で表示しますが、左下の言語設定で日本語へ変更できます。
1. 少し下へスクロールすると[更新評価を受ける]ボタンがあるためクリックします。
1. すぐに試験が始まります。(開始案内はなく、いきなり1問目が表示します)
1. 問題数は、「Azure Administrator Associate」は28問、「Azure Solutions Architect Expert」は26問でした。
1. 最後の問題にて[次ぎ]をクリックすると数秒の集計が始まり直後に結果が表示します。また、正答率を見ることができます。回答は表示されません。

# 注意点
- 問題は進むのみで、戻ることはできません。
- 試験中に言語を変更することは可能ですが、その場合、1問目に戻り、且つ、問題も刷新されます(リセットのような挙動となります)。
- 「Azure Solutions Architect Expert」については、問題文は日本語で、回答選択文が英語になっているものが、ちらほらありました。Google翻訳を活用しました。

# その他
- 評価試験を受ける前に、Microsoft Learnにて「更新評価の準備」として関係する学習モジュールがリストされますが、ここからそのまま試験問題としては出題されていません。このため、分からない問題は、ググって調べることなります(殆どは公式ドキュメントベースで回答可能です)。
- 評価試験用の問題は世に出回っているようで、英語にした上で、その問題分でググると幾つかの海外サイトでヒットします。ただ、有料サイトであったり、回答が間違っていたりします。

# 感想
- この仕組み良いですね。AWSもこのようにしてくれたら良いのになと思いました。
【Heroku】デプロイエラーを解決（JisonLexerError / peerDependencies / Precompiling assets failed）

# エラー概要
* Herokuのデプロイで以下のエラーが表示された。解決までたどり着いたので、その対応方法を記しておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/2641b519-852e-34b2-5712-135deee40edd.png)


* この中でも、以下に問題があると推測する。

```terminal
Compilation failed:
JisonLexerError: Lexical error on line 1: Unrecognized text.
Erroneous area:
1: 2 * $table-border-width
```

* ただし、この辺のエラーメッセージでぐぐっても全然記事がヒットせず...。挫折しそういになるくらい、かなりの時間を浪費しましたので、誰かの一助になればと思います。
    
# 原因の追究

* 下にpostcssのことがたくさん記載されているので、そこに"Unrecognized text."が存在しているのか。ただ、postcss.config.jsは以下の通りとなっており、とくにいじった覚えはない。

```json
module.exports = {
  plugins: [
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}

```

* VSコードで`table-border-width`を全体検索すると、以下がヒット。CALC関係のCSSファイルが悪さしているのかと思ったが、検索結果にそのようなCSSファイルはないよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/16680607-584e-41a2-83bf-bab59f2eed78.png)

# 原因
* herokuプッシュ時のログによく見たら

```terminal
”webpack-dev-server@4.9.2" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".”
```

とあり、webpack-dev-serverの依存パッケージに合致（peerDependencies）したwebpackのversionにしておいた方がいいよ、という意味らしいです。（この警告が出てもデプロイできることがあるので見逃されがちらしい）

* 結局、JisonLexerErrorやpostcss-calcが直接何かの原因になっているわけではない？ようです。この辺詳しい方いらっしゃったらぜひコメントください。

# 解決方法
* package.jsonにてwebpackerのバージョンを以下に変更

```package.json
- "@rails/webpacker": "4.3.0",
+ "@rails/webpacker": "^5.1.1",
```

* 上記変更の後、以下を実行する。
```terminal
$ yarn install
$ git add yarn.lock
$ git commit -m "Updated Yarn lockfile"
$ git push heroku main
```

* これで、`Precompiling assets failed.`も無くなりました。

# 参考記事
* Precompiling assets failedについての記事：
    * [heroku Precompiling assets failed. を解決した方法](https://qiita.com/Yamashita-Taiki/items/0ef9e76cfceb4a655452)


* has unmet peer dependencyについての記事：
    * [Unmet peer dependencies #1078](https://github.com/rails/webpacker/issues/1078)

* Teratailでも質問しましたが、上記の通り自己解決となりました。
    * [Herokuのデプロイエラーを解決したいです（JisonLexerError）](https://teratail.com/questions/meo72xz35v2qkp)
RustのESP32開発環境構築

# RustのESP32開発環境構築

プログラミング言語`Rust`を使用してESP32用のプログラムを開発するための環境を構築する。

## 実行環境

- ターゲットボード

    [ESP32-DevKitC-32C](https://akizukidenshi.com/catalog/g/gM-15673/)

    ※ターゲットボードが変わると以下で使用するコマンドが変わるので注意

- 開発ホスト

    [Ubuntu 20.04 LTS](https://www.ubuntulinux.jp/News/ubuntu2004-ja-remix)


## 環境準備

### Rustインストール

開発ホストにRustをインストールする。Rustはインストールが非常に簡単で下記のコマンドを実行するだけで完了する

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

[Rustをインストール](https://www.rust-lang.org/ja/tools/install)

### Rustの環境変数を設定する

ホームフォルダ直下の`.cargo`フォルダ内に環境変数のスクリプトがあるので、
そのスクリプトから設定を行う。

```bash
source ~/.cargo/env
```

環境変数が正しく設定されれば以下のコマンドが実行できるはずなので確認する。

```bash
# rustcコマンドの確認
rustc --version
# cargoコマンドの確認
cargo version
# rustupコマンドの確認
rustup show
```

### ESP32用のツールチェインをインストールする

```bash
cargo install espup
cargo install cargo-espflash

espup install --esp-idf-version <ESP_IDF_VERSION>
# <ESP_IDF_VERSION>は4.4を使用する
# バージョン情報は[esp-idf-template](https://github.com/esp-rs/esp-idf-template)を参考にする
# ex. espup install --esp-idf-version 4.4

# ESP32用の環境変数を設定
. $HOME/export-esp.sh
```

### ESP32用プロジェクトを作成する

`cargo-generate`を使用して`esp-idf-template`からプロジェクトを作成する

```bash
# [no_std]
cargo generate --git https://github.com/esp-rs/esp-template

# [std]
cargo generate --git https://github.com/esp-rs/esp-idf-template cargo
```

### ESP32用プロジェクトをビルドする

デフォルトでは使用するツールチェーンはESP32になっていないため、使用するツールチェーンを指定してビルドを実施する。

```bash
# ※ビルドする前に必ず設定
# ESP32用の環境変数を設定
. $HOME/export-esp.sh

cargo +esp build
```

### ESP32にプログラムを書き込む

```bash
# 書き込みのみ
# no_std
# Debugモード
cargo espflash --target=xtensa-esp32-none-elf /dev/ttyUSB0
# Releaseモード
cargo espflash --release --target=xtensa-esp32-none-elf /dev/ttyUSB0

# std
# Debugモード
cargo espflash --target=xtensa-esp32-espidf /dev/ttyUSB0
# Releaseモード
cargo espflash --release --target=xtensa-esp32-espidf /dev/ttyUSB0

# 書き込み後、シリアルモニタを開始
# no_std
# Debugモード
cargo espflash /dev/ttyUSB0 --monitor
# Releaseモード
cargo espflash --release /dev/ttyUSB0 --monitor

# std
# Debugモード
cargo espflash --target=xtensa-esp32-espidf /dev/ttyUSB0 --monitor
# Releaseモード
cargo espflash --release --target=xtensa-esp32-espidf /dev/ttyUSB0 --monitor
```

### ESP32実行中プログラムのシリアルモニタ

```bash
# シリアルモニタソフトをインストール
cargo install cargo-espmonitor

# デバイスを指定してシリアルモニタを起動する
cargo espmonitor /dev/ttyUSB0
```

### 1つのプロジェクトで複数の実行ファイルを作成

`.Cargo.toml`に以下の追記する
```toml
...
[[bin]]
name = "trial1"
path = "src/trial1.rs"

[[bin]]
name = "trial2"
path = "src/trial2.rs"
...
```

ビルドしたいものを選択する

```bash
cargo build --bin <name>
```

書き込みたいものを選択する

```bash
cargo espflash --bin <name>
```

## 参考リンク

* [The Rust on ESP Book](https://esp-rs.github.io/book)

* [Wokwi](https://wokwi.com/rust)

* [esp-hal(GitHub)](https://github.com/esp-rs/esp-hal)

## ESP32 on Rust チートシート

* [タイマー割込と排他制御](https://qiita.com/DaiGuard/items/4a58e5afe076b201ca50)
GitHub Actionsで文章校正を行う(textlint)

# 概要
GitHub Actionsで文章校正をする

# 参考ページと違う部分
参考ページでは決められたフォルダの全mdファイルをチェックするようになっていた。
それを、どの階層のテキストでも変更があったmdファイルのみチェックをするように変更

# なにはともあれ準備
対象リポジトリにtextlintの設定をする
node.jsはインストール済みとする

```
$ npm init -y
$ npm install --save-dev \
    textlint \
    textlint-rule-preset-ja-spacing \
    textlint-rule-preset-ja-technical-writing \
    textlint-rule-spellcheck-tech-word
$ npx textlint --init
```

そうすると
- .textlintrc
- package-lock.json
- package.json

が出来上がるのでそれらをgitで管理する
`node_modules/*`は`.gitignore`行き

ルールとかそういうのは使いながら調整

# 関連ファイルの配置例
```
.textlintrc
package-lock.json
package.json
.github
|-workflows
  |-textlint.yml
```

# github actionsの設定

・pull_requestのopen時とブランチが更新されたときに実行
・ubuntuで
　contentsはreadのみ
　長時間動いてしまうと怖いのでtimeoutは1min（足りなくなりそうな気もする）
・PR対象のブランチをチェックアウト
　元となるブランチもfetch（mainに固定してしまっているので、元ブランチが違う場合には記述を変える必要あり）
　textlintをインストール(npm周りはキャッシュをする）
　変更があった.mdファイル名だけを取り出す
　textlintを実行する
　

```.github/workflows/textlint.yml
name: textlint

on:
  pull_request:
    types: [ opened, synchronize ]

jobs:
  main:
    runs-on: ubuntu-22.04  # runner OS version
    permissions:
      contents: read
    timeout-minutes: 1
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: actions/setup-node@v3
        with:
          node-version: 14
          cache: npm
      - run: npm install
      - name: Fetch base branch
        run: git fetch origin main
      - name: Create target file list
        run: git diff origin/main HEAD --name-only |grep \.md$ > /tmp/textlint-target-list.txt
      - name: textlint
        run: cat /tmp/textlint-target-list.txt |xargs npx textlint
```

# 参考
https://dev.classmethod.jp/articles/markdown-writing-with-textlint-ci/

https://qiita.com/takasp/items/22f7f72b691fda30aea2
Rails6 – Webpacker::Manifest::MissingEntryError  を解決する

ページアクセスすると `Webpacker::Manifest::MissingEntryError ` が発生する

# 解決

Gemfile で webpackerのバージョンを上げる

```
gem 'webpacker', '~> 5.0'
```

```
bundle install
```

# Webpackerの実行

nodeバージョンによってはSSL関係のエラー ( `ERR_OSSL_EVP_UNSUPPORTED` ) が出るので、環境変数 `NODE_OPTIONS=--openssl-legacy-provider` を付ける

```
rails webpacker:install
NODE_OPTIONS=--openssl-legacy-provider rails webpacker:compile
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
40代が始めるWordPress副業 (3)

昨今の物価高、中国経済の停滞に伴う不況、増税により私の生活は厳しくなるばかり・・・
これはいよいよ副業でもせんとやってけん、ということで、最近副業が解禁された
製造業の社内SEとしてサーバサイドや基幹システムばかりやっていた40代成りたてのおっさんが、
副業を始めて1年後までにどの程度稼げるようになるか、ツラツラと残していきます。

過去ログ
[#1](https://qiita.com/Takeshi_Shimoda/items/1421fc66b595b635e6de) [#2](https://qiita.com/Takeshi_Shimoda/items/9762a9e1b1feaeb7c699)

# 正月の終わり
大体、毎日1-2時間くらいをWordPressかOutSystemsの勉強に費やせたと思う。
その他はビール飲んだり、子供と遊んだりしてました。
皆様、新年頑張っていきましょー

# やったこと
2023/1/7
Udemyで動画勉強中

ざっくり学ぶ、WordPress 6.xでノーコードサイト制作講座
　37/118まで
ちゃんと学ぶ、WordPress テーマ開発講座
　38/52まで

# 備忘録
パーマリンクが反映されない(ように見える)ときはブラウザキャッシュをクリアしてみる。
EdgeであればInPrivateで別ウィンドウで立ち上げて見る。

参考サイト様
Miyachi Labo　[URLの取得方法](https://labo.kon-ruri.co.jp/home_url-vs-get_template_directory_uri-etc/)

問い合わせ等のフォームの代表的なプラグイン
MW WP Form
Contact Form7

条件分岐タグの活用
同じphpの中でカテゴリやタグで用途を分ける場合、下位層のphpを作らなくとも条件分岐タグで部分的に
置き換えるだけでもよい
maya Cannot find procedure "CgAbBlastPanelOptChangeCallback Cannot find procedure "look" crash export mb

## Cannot find procedure "CgAbBlastPanelOptChangeCallback 
```python
import pymel.core as pm
def cleanupPanelCallback():
    for item in pm.lsUI(editors=True):
        if type(item) == pm.ui.ModelEditor:
            pm.modelEditor(item, e=True, ec='')
cleanupPanelCallback()
```

## Cannot find procedure "look"
mel
```mel
outlinerEditor -edit -selectCommand "" "outlinerPanel1";
```

python
```python
maya.mel.eval('outlinerEditor -edit -selectCommand "" "outlinerPanel1";') 
```

## maya crash export mb
Export Selection
Vue3でtrainsition-groupを使って順番にカードがスライドするようなアニメーションを作る


# はじめに
このページで作成できるのは以下のようなものです。
![test ‐ Clipchampで作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697721/d64071ac-52fd-9bdd-7037-a54bfa21da90.gif)
# 全体のコード
```vuejs:TestPage.vue
<template>
  <v-app>
      <v-main class="bg">
        <v-container>
          <v-row class="ma-8">
            <transition-group name="list">
              <v-col v-for="(item) in links" :key="item" class="list-item"
                :style="{ 'transition-delay': `${item.id * 0.3}s` }" cols="4">
                <v-card height="150" class="ma-8" >
                  <v-card-title class="text-center">{{ item.name }}</v-card-title>
                </v-card>
              </v-col>
            </transition-group>
          </v-row>
        </v-container>
      </v-main>
  </v-app>
</template>

<script>
export default {
  data() {
    return {
      links: [
      ],
    }
  },
  methods: {
    
  },
  mounted() {
    this.links = [
      { id: 1, name: "Page1" },
      { id: 2, name: "Page2" },
      { id: 3, name: "Page3" },
      { id: 4, name: "Page4" },
      { id: 5, name: "Page5" },
    ]
  }
};
</script>

<style scoped>


.bg {
  background-color: rgb(222, 212, 199);
}


.list-enter-active {
  transition: all 1s ease-out;
}


.list-enter-to {
  opacity: 1.0s;
  transform: translateY(0px);
}

.list-enter-from {
  opacity: 0;
  transform: translateY(300px);
}
</style>
```
# やってること
- カードを段組み表示
- transition-groupによるスライドアニメーション

## カードの段組み表示
vuetifyのv-colとv-rowを組み合わせて実装できます。
詳しく知りたい方はこちら
https://vuetifyjs.com/ja/components/grids/#v-spacer
## transition-groupによるスライドアニメーション
Vueでは、transitionのためにenter/leaveクラスを使用することができます。
- enter : 要素が追加されたとき（表示）
- leave : 要素が削除されたとき（非表示）


今回使用しているのはenterクラスの
- enter-from (初期状態)
- enter-active (途中)
- enter-to (終了)
の3つとなります。

これらは下の図でわかりやすく説明されています。

![](https://v3.ja.vuejs.org/images/transitions.svg)
(https://v3.ja.vuejs.org/guide/transitions-enterleave.html)

trainsition-groupを使うとv-for内の要素全てにアニメーションを付けることが可能です。
今回は、各要素に時間差を付けてスライドさせるため、trainsition-delayを使ってindex番号を基にdelayをかけています。

# 参考
- https://tech-broccoli.life/articles/engineer/vue-created-animation-with-transition-group/

- https://v3.ja.vuejs.org/guide/transitions-enterleave.html
DockerでReact, TypeScript環境を構築する

## 事前準備
[Docker Desktop](https://www.docker.com/products/docker-desktop/) をダウンロードしておく。
ダウンロードしたら、起動しておく。

## 手順
1. 任意の場所にプロジェクトフォルダを作成する
1. 作成したプロジェクトフォルダ内に以下の2つのファイルを作成する
    - Dockerfile
    - docoker-compose.yml
1. Dockerfile, docker-compose.yaml に記述する
1. ターミナルでコマンドを実行し、Reactアプリを作成する

以下順番に解説していきます。

## プロジェクトフォルダの作成

任意の場所で以下のコマンドを実行し、プロジェクトフォルダを作成する。
今回は my-news-app としました。

```bash
mkdir my-news-app
cd my-news-app
```
プロジェクトフォルダに移動したら、以下のコマンドを実行し、Docker 関連のフォルダを作成する。

```bash
touch Dockerfile
touch docker-compose.yml
```
画像のような構成になっていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/e30c2665-c887-28e1-692a-d298ab1f9852.png)

## Dockerfile, docker-compose.yaml への記述
```Dockerfile:Dockerfile
FROM node:18.12.1-alpine
WORKDIR /usr/src/app
```

バージョンは、現時点での推奨である 18.12.1 を使用します。
推奨版の確認は [node公式](https://nodejs.org/ja/) をご確認ください。

```yaml:docker-compose.yaml
version: '3'

services:
  node:
    build: .
    volumes:
      - ./:/usr/src/app
    command: sh -c 'cd react-app && yarn start'
    ports:
      - '3000:3000'
```

`command:`の`react-app`ですが、これはのちに React アプリを作成する際に指定したアプリ名となります。

作成したら以下のコマンドを実行します。

```bash
docker-compose build
```

## React, TypeScript アプリの作成

ターミナルで以下のコマンドを実行してください。
`react-app`の部分をご自身のプロジェクトの名前に置き換えてください。

```bash
docker-compose run --rm node sh -c 'npx create-react-app react-app --template typescript'
```

React アプリが作成されると、以下のようなディレクトリ構成となるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/2fca22c6-7078-5f1d-c9b1-994172c650cb.png)


React アプリが作成されたことを確認したのち、以下のコマンドを実行する。

```bash
docker-compose up -d
```

コンテナが起動します。
[http://localhost:3000](http://localhost:3000) にアクセスし、以下の画面が表示されれば、環境構築完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/e808414e-cbdd-3fcd-93ea-ef3e46e2964b.png)

お疲れ様でした。
CircleCIのセキュリティインシデント（2023/1/4）に対応した話

:::note warn
**この記事の情報は古い、または正確ではない可能性があります。本件に関する情報は公式からの報告を参照してください。**
:::

# CircleCIのセキュリティインシデントについて

こちらで1月4日（日本時間 1月5日）にキュリティインシデントが発生したとの報告がありました。

https://circleci.com/ja/blog/january-4-2023-security-alert/

CircleCIに保存しているシークレットのローテーションが推奨されたので、これを実施しました。
主な対象はこちらで列挙されているものです。
（対応中に上記の日本語記事にも記載されました）

https://support.circleci.com/hc/en-us/articles/11816211460891

# 個人でやったこと

## 1. OAuthトークン

まずはCircleCIへのログインに使用するOAuthトークンです。
こちらは記載の通りに更新しました。

## 5. ユーザーAPIトークン

[VS Codeの拡張機能](https://marketplace.visualstudio.com/items?itemName=circleci.circleci)を使っているので、このユーザAPIトークンも更新しました。

# プロジェクトでやったこと

## 3. プロジェクトの環境変数

アプリケーションやクラウドプラットフォームに関する接続情報などがあったので、これを更新しました。
ローテーションのために２つのキーが用意されているケースは簡単なのですが、パスワードなどはユーザの作成から必要なものもあったので手間がかかりました。開発環境など、ちょっと止まっても大丈夫な環境であればそのまま変更でいいのですが、本番環境はそうはいきませんからね。

## 4. コンテキスト変数

組織単位で設定しているものです。
こちらもプロジェクトの環境変数と同じように更新していきます。

## 6. プロジェクト SSH キー

GitHubからチェックアウトするためのキーが設定されていたので、これを更新しました。

# まとめ

さらっと書きましたが準備があったわけでもなく、サービスを止めないように気を配りつつ作業したので実際はなかなか大変な作業でした。とはいえ被害にあってからだともっと大変なので、可能な限り早く対応することが大切ですね。

近年は多くの外部サービスを利用するようになってきているので、こうした事例は避けられないものでしょう。外部の変化に素早く対応できるような環境を作ることが大事になると思います。