OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向】jQueryでHTMLの値を取得する方法

# HTMLの変数をjQueryで使えるようにしたい

例えばLaravelでWEBアプリを作成する際にはデータベースと連携して
`変数をHTMLに渡す`ことがよく用いられますが

HTMLの変数をjQueryで使えるようにするためには
`data()メソッド`を使う必要があります。

## jQueryを扱うための注意事項

### jQueryを使うための事前準備

jQueryを利用するには次の`どちらか`の準備が必要です
- jqueryへのリンク(CDN)をHTMLのheadタグ内に記述する
- jqueryを公式HPからダウンロードする

### jQuery(JavaScript)はHTMLの後に記述する



後述にサンプルコードがありますが、
jQuery(JavaScript)をHTMLのbodyタグに記述する際は
jQuery(JavaScript)のコードをbodyの最下部に記述します

htmlファイルのコードは上から順に処理されるため
jQuery(JavaScript)をbodyの上部に記述すると
HTMLのコードが読み込まれずエラーの原因になります

## 実際の操作方法

### jQueryのリンクを貼る方法
[jQuery CDN](https://code.jquery.com) にアクセスし
jQuery Core 3.*.*の`minified`をクリック(最新のCDNをクリック）

コピーボタン（Copy to clipboard!）をクリックしてコピーする

```html:sample.html

<head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>

```



## data()メソッドとは？

HTMLタグへ事前に`data-****`などと属性を付与しておくことで、
付与していたHTMLタグのdata属性に対してjQueryから
`値を取得`したり、`属性名を設定（変更）`したり
`値を変更`したりすることができます

## data()メソッドの使い方

HTMLの値を取得するには予めHTML内のタグへ
独自の属性、つまりdata属性を付与しておく必要があります。

### htmlの書き方

属性の書き方は`data-****`のように
`data-`にプラスして`任意の名前`を記述します
```html:sample.html
<!--
例：htmlの pタグへname属性とage属性、そしてtel属性を付与します
  -->  
 
<body>
<p data-name="tanaka" data-age="25" data-tel="000-1234-5678">
私の名前は田中です　年齢は25歳です。
</p>
```
### jQuery(JavaScript）の書き方

jQuery(JavaScript)でHTMLのタグから値を取得するには
`$対象のタグ.data()`のようにdata()メソッドを実行します。

```html:sample.html 
<body>
<p data-name="tanaka" data-age="25" data-tel="000-1234-5678">
私の名前は田中です　年齢は25歳です。
</p>

<!--
例：jQuery(JavaScript)にてname,age,telの値を取得します
 -->

<script>
    // 変数へpタグに付与された全てのdata属性の値を取得します
    const result = $('p').data();
    // 変数の中身を出力します
    console.log( result );
</script>
</body>

```
**取得された属性には自動的に`data-`の部分が除外されます**
```javascript:実行結果
{age: 25, name: "tanaka", tel: "000-1234-5678"}
```

### 特定のdata属性を指定して取得する
data()メソッドへ`引数`を渡すことでdata属性を指定できます
```html:sample.html 
<body>
<p data-name="tanaka" data-age="25" data-tel="000-1234-5678">
私の名前は田中です　年齢は25歳です。
</p>

<!--
例：jQuery(JavaScript)にてname,age,telの値を取得します
 -->

<script>
    // 変数へpタグに付与されたdata-name属性の値を取得します
    // この時、"data-"の部分は省略して記述します
    const result = $('p').data('name');
    // 変数の中身を出力します
    console.log( result );
</script>
</body>

```


```javascript:実行結果
tanaka
```
## data属性を後から設定する

dataメソッドを使えば、取得だけではなく
`data属性が付与されていないタグ`に対して
data属性を`後から付与`することも可能です。

`＜script>`内へ以下の記述を行います
$('対象のセレクター').data('任意の属性名', '任意の値');
属性名に対しては`"data-"の記述は不要`です

```html:sample.html
<body>
<p>おはようございます</p>
 
<script>
    $('p').data('name', 'yamada');
 
    console.log( $('p').data('name') );
</script>
</body> 


```
```javascript:実行結果
yamada
```
### 後からdata属性の値を変更したい場合

次の方法で属性の値を変更することができます

$('対象のセレクター').data('すでに存在する属性名', '任意の値');
属性名に対しては`data-`の記述は不要です


```html:sample:html
<body>
<p>ありがとうございます<p>
 
<script>
    $('p').data('name', 'yamada');
 
    console.log( $('p').data('name') );

    //すでに存在するdata属性に対して値を変更します

    $('p').data('name', 'tanaka');
 
    console.log( $('p').data('name') );
</script>
</body>
 
```

```javascript:実行結果
yamada

//変更後

tanaka

```
エンジニアキャリア13年のWebエンジニアが作る「Webエンジニアのスキルマップ」

# はじめに
こんにちは、muff1225です。
株式会社ZOZOでエンジニアリングマネージャーをやっています。
現在は[新事業の立ち上げ](https://corp.zozo.com/news/20220825-madebyzozo/)で中国子会社へ出向中。

現地のエンジニアに「エンジニアはどういう勉強をしたらいいですか？」と聞かれたのをきっかけに、
これまでのキャリアを振り返って、エンジニアのスキルマップを作りました。

同じような疑問を抱いている人にちょっとでも参考になればと思い、公開することにしました。
概ね1〜7年目ぐらいのキャリアの人で、これからどういう勉強をしていったらいいかわからない、という人向けになります。

現在Webサーバ/スマホアプリを使ったサービスをやっている関係もあり、
偏りがあったり、抜け漏れがあると思いますが、大枠として捉えていただけると。

※このスキルマップはmuff1225個人の主観であり、会社を代表する内容ではありませんので悪しからず・・・

# スキルマップ
![スキルマップ](https://raw.githubusercontent.com/muff1225/engineering-skillmap-jp/main/skillmap.drawio.svg)

# スキルマップのダイジェスト
1. 需要と希少性によって給与が決まる。
1. 他社事例含め、よく知ることがスキルアップの近道。
1. まずは自分の領域で偏差値55（パフォーマンスチューニングができるぐらいの理解度と活用度）を目指そう。
1. 自分の領域 + 隣の領域を攻めよう。

# muff1225の簡単な経歴
## 経歴
2009年 SIerとしてエンジニアキャリアをスタート
2013年 株式会社スタートトゥデイ（現株式会社ZOZO）へ入社
2022年 新規事業の立ち上げで中国出向中

現在は事業ドメイン特化型（アパレル製造業）のサービスを中国子会社で開発中。
MES/ERP/MRPなどといったキーワードの機能群を開発しており、DIYの精神で要件決めから開発、運用まで自分たちでやっています。
メイン言語はGo / Kotlin、インフラはAlibaba CloudのフルマネージドなKubernetes。

# さいごに
ちょっとでもいいね、と思ったら「いいね」お願いします:thumbsup:

# ファイルの置き場所
Githubに置きました。
https://github.com/muff1225/engineering-skillmap-jp
LaTeX環境メモ　レポート用

レポート用LaTeXテンプレ

```latex:report.tex

\documentclass[a4paper,titlepage]{jarticle}　%titlepageで表紙が作れる
\usepackage{amsmath}
\usepackage{physics}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage[dvipdfmx]{color}
\usepackage{multicol}　%表の縦連結
\usepackage{longtable}
\usepackage{here}　%大文字Hで表と図の場所を確定させる
\usepackage{url}　%urlは\url{}で
\usepackage{tikz}　　%tikz(作図)使えるように
\usepackage{fancyhdr}
\usepackage{siunitx}
\usepackage{comment}
\usepackage{lastpage} %pageref{LastPage}で最終ページがわかる
\usepackage{ifthen} %ifthenelse{条件}{条件一致時の実行内容}{elseの実行内容}
\usepackage{otf}　%ローマ数字は\ajroman{n}か\ajRoman{N}
\usetikzlibrary{intersections,calc,arrows.meta}　%tikz使えるように
\input{|"rm platex*.fls"}　%余計なファイル消す
\usepackage[top=20truemm,bottom=20truemm,left=15truemm,right=15truemm]{geometry}
\parindent = 0pt

\renewcommand{\thesection}{＃\arabic{section}}　%セクションを＃1,2にする
\renewcommand{\thesubsection}{\arabic{subsection}}
\renewcommand{\thesubsubsection}{設問\arabic{subsubsection}}　%(i),(ii)なら\roman

%図hogeと打つのがめんどくさいので
\newcommand\figref[1]{(図~\ref{fig:#1})}
\newcommand\tabref[1]{(表~\ref{tab:#1})}

\makeatletter　%計算式のラベルを(1.1)に．計算式の参照は\eqref{eq:hoge}
  \renewcommand{\theequation}{\arabic{section}.\arabic{equation}}
  \@addtoreset{equation}{section}
\makeatother

\makeatletter　%minipageで表と図を混ぜた時のために
\newcommand{\figcaption}[1]{\def\@captype{figure}\caption{#1}}
\newcommand{\tblcaption}[1]{\def\@captype{table}\caption{#1}}
\makeatother

\pagestyle{fancy} %ヘッダフッタ使う時
  \rfoot{\ifthenelse{\value{page}=\pageref{LastPage}}{以上}{次ページへ}}
  \rhead{学籍番号と名前}
  \lhead{}
  \cfoot{\thepage/\pageref{LastPage}}
  \renewcommand{\headrulewidth}{0pt} %線を消す

\begin{document}

%タイトル
\title{科目名}
\author{学籍番号・名前}
\date{}
\maketitle
%\thispagestyle{empty} %1ページ目のページ番号を消す
\thispagestyle{fancy} %1ページ目はデフォルトのスタイルになってしまう．

\section{1章}
本文

\begin{comment} %大きなコメントアウト
\begin{figure}[H] %表と図のminipage
	\begin{tabular}{cc}
	\begin{minipage}{.6\linewidth}
		\centering
		\includegraphics[width=.75\linewidth]{hoge.png}
        \vspace*{-0.5cm} %下のキャプション離れすぎ
        \figcaption{hoge}
		\label{fig:hoge}
	\end{minipage}
	\begin{minipage}{.4\linewidth}
		\centering
        \tblcaption{hoge}
        \label{tab:hoge}
        \begin{tabular}{ccc}
          表
        \end{tabular}
    \end{minipage}
	\end{tabular}
\end{figure}
\end{comment}

\begin{thebibliography}{300}%参考文献　数字は適当
  \bibitem{hoge}
  hoge著hoge　\url{https://hogehoge}
\end{thebibliography}

\end{document}
```
正規の方法でWSL2でsystemdを使う

今までWSLでsystemdは使えないものだと思っていましたが、
WSL 0.67.6からsystemdがサポートされていたようなので、使い方をメモっておきます。

# やり方
wslでは、ディストリビューション内の`/etc/`に`wsl.conf`を作って、その中に記述をすることで設定を変えることができるようです。

wslを開き、vimとかで`/etc/`に`wsl.conf`を作ります

```bash
cd /etc/
vim wsl.conf
```

下のように記述します

```conf
[boot]
systemd=true
```

保存したのち、windowsのコマンドプロンプトなんかでwslを終了させます。

```bash
wsl --shutdown
```

これで幸せになれます。

# 参考文献
https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config
【読書感想文】長谷川康一 現場が主役の日本型DXを読んで

# はじめに
UiFesに参加した際にこの本の紹介があったので、
気になって読んでみました。
読んだ中で感じたことをメモとして残します。

読書感想文として記録を残すときはスルメ本に限って残していますので、
今後も定期的に読み直してこの本に対する理解を深めていきたいです。

# 今回読んだ本

UiPathの公式サイトで無料試し読みもできるみたいです。

https://www.uipath.com/ja/resources/automation-whitepapers/book2-download

# どんな本なの？
UiPathの日本法人CEOである長谷川さんと、AIや自動化についての対談に始まり、
日本独自であろう「現場が主役のDX」について、実際にDXが成功した事例を取り扱いながら「自動化・そしてDXはどのように推進していくか」についての本です。
また、ユーザーコミュニティである「UiPath Friends」についてもかなり多くの記載がされていました。

# どう活かせそうなの？
## 「自動化」を考えるうえでのゴールを思い出すきっかけになる
日々の業務をこなしていると、どうしても目先の進捗ばかりに気を取られて、
本来の目的（RPAの内製化であったり、業務の自動化であったり…）が薄れてしまいがちです。
この本を読むことで、内製化や自動化本来の目的を思い出すための「高い視座」を
再認識させてくれる本であると感じました。

## 成功事例を実際に学ぶことで、今の課題について考えることができる
この本には、DXに成功した企業のプロセスが記載されていたりします。
しかし、それを鵜吞みにしてそのまま真似するだけでは、DXはおそらく成功しないでしょう。

成功事例を学ぶことによって
- 成功事例と比べて現在自分たちにはどのような課題があるのか
- 既存のITツールなどの技術とどのように折り合いをつけていくのか
- 自動化を求めるあまり、本来自動化に不向きである業務を自動化するのに必要以上の工数を割いていないか
を今一度考えるきっかけとなる本だなと感じました。

# おわりに
長谷川さんの本がもう一冊あるみたいなので、
そっちも読んでみたいなと思いました。
新人エンジニアにおすすめしたい勉強法まとめ

# はじめに
こんにちは。[rendaman0215](https://twitter.com/rendaman0215)です。

最近、新人エンジニアの方に勉強方法などを伝える機会があったため、
勉強する際に活用しているコンテンツをまとめてみました。

# コンテンツ別紹介
## 公式ドキュメント
費用：　無料
一番正確で、細かい部分まで網羅的に載っているため最強です。
が、英語でのみ書かれていることが多かったり、小難しい表現がされていたり、網羅的に乗っているがゆえにどこから手をつければいいかわからないといったデメリットもあります。
これらをデメリットと感じない方は、公式ドキュメントを見るのが一番良いと思います。
ただ、最近の言語やFWはチュートリアルが充実していることが多いので、初学者の方でもチュートリアルはやってみることをおすすめします。

## 書籍
費用：　3000〜５０００円くらいが多い
入門から発展、概念系まで幅広く存在し、良書に出会うとハッピーになれます。
あたりハズレはあるが、かなり身になります。

## 技術系記事
費用：　無料
言わずがもですが、素敵な記事がたくさんあります。
よかった技術記事のまとめ みたいな記事から情報仕入れたりします。

## Udemy
費用：　〜2400円くらい（セール時）
章ごとにまとめられていて、復習しやすい。
また、しっかりとした講師の方がコーディングしながら解説してくれるところが熱いです。
価格も一般的な書籍に比べ情報量の割に安い。
流し身でもそれなりに知識がつきます。
ただし、書籍や記事に比べると同じ情報量でも時間がかかりがちです。

## Progate
費用：　1000円くらい/月
プログラミングの基本から丁寧にわかりやすく解説してくれるので、真の初学者にはいい教材だと思います。
ある程度わかってくると優しすぎるかも。

## YouTube
費用：　無料
少々極端な表現が多かったり、誤った情報が見受けられます。
無料で動画コンテンツを使って学習したい場合は選択肢にあがるかもしれません。

# まとめ
## 技術系記事を書く
費用：　無料
アウトプットこそ最大の学び。
みなさんも技術系記事を書きましょう！
【Rails,Mysql】DBの中身確認に関するメモ

# DBの中身確認
完全にメモになるので、詳細な内容の説明は割愛する。
本番環境にDockerを使ったRailsアプリのDBの中身を確認する。尚、DBはRDSを使用し、Mysqlで管理している。
まずEC2にSSH接続し、dockerをビルド、アップし直す。その上で以下を実行する。
```:terminal
$ docker-compose exec app rails db:create 
#まだDBを作成していない場合

$ docker-compose exec app rails db:migrate
```
その上で、

```
$ docker-compose exec app rails dbconsole
```
ここでパスワードを聞かれるので、DBのパスワードを入力するとクエリを打てるようになる。

例えば、作成したusersデータの内容を確認したければ、```select * from users\G```のように実行する。また、データの仕様を確認したい時には、```describe users``` のように実行すればよい。

# コンテナにログインしてDBを確認する。
以下のコマンドを実行し、appコンテナのコンテナID（アルファベットと数字で構成される）を確認する。
また、別途、AWSでRDSのエンドポイントも確認しておく。

```:terminal 
$ docker ps
```
確認したContainerIDを使って以下のコマンドを打つ。
```
$ docker exec -it コンテナID bash
```

Mysqlを起動させる。
```
$ service mysql start
```

その後、以下のコマンドでMysqlに接続する。

```
$ mysql -u root -h RDSのエンドポイント -p
```
パスワードを入力するとクエリを打てるようになる。
そこで、
```
MySQL [(none)]> show databases
```
と入力すると、作成済みのDBを一覧で見られる。アプリのデータベース名を確認し、以下のコマンドで指定する。
```
MySQL [(none)]> use appname_db 
```
これで、同様にアプリのDBの中身をクエリで確認することができる。
エンジニア初心者がスウォーミングを経験したお話

# はじめに
チームでモブプロに取り組んでからある程度期間が経った後、メンバーからの紹介でスウォーミングという方法を知り、スウォーミングで簡単な作業を行ったので所感を簡単にまとめます。
スウォーミングについてはこちらの記事で知りました。

https://blog.cybozu.io/entry/2022/06/08/141944

# 良かった点
- モブプロで学んだことを自分の思考スピードでアウトプットできる機会だったので、自分でどこまでできるか試すことができた
- 自分がキャプテン(優先度高い作業を担当している)のときは詰まったらモブプロ招集ができるので安心感があった
- キャプテンが1~2日で一巡するように作業を分担したので、ソロプロだけどチームで取り組んでいる間があって心強かった
- キャプテンが出したマージリクエストのレビューが最優先なので、レビューの後回しがなかった

# 気を付けたい点
- ソロプロに集中してしまい、詰まった際は自分で解決しようと時間をかけてしまいがち
- 自分がキャプテンでないときに詰まっても基本的にはペアプロやモブプロ招集ができないため、解決力がある程度ないとしんどそう

# おわりに
今回は以下の条件でスウォーミングを試したため、モブプロ招集がかかるようなことはありませんでした
- 作業はその日中(もちろん定時内)に終わるような軽めのものを割り振る
- 少し質問して分かりそうなことであればモブプロでなくペアプロにする
- 案件を担当してから期間が経っているので仕様やソースコードの理解が進んでいる

モブプロを導入した後に取り入れてみるとメンバーの成長具合が測れつつ、チーム全体の開発速度も出るので相性が良いなと感じました
【VSCode】特定のフォルダやファイルを非表示にする方法

## 設定方法

設定前は以下のように表示されています。  

![E0BC8A3C-B39F-4F04-95BA-66B51372278A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1cbdf52d-5746-1a79-be6c-a58858f37622.png)

VSCodeで設定を開きます。  

設定画面で`files.exclude`を検索します。  

![C556903D-7CA5-4FB3-BC16-85596EF1A4BA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5a77dead-4e6b-de05-265c-c7b25ad10fee.png)

「Files: Exclude」の「パターンを追加」をクリックして`**/example`を入力します。  

![C556903D-7CA5-4FB3-BC16-85596EF1A4BAのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e0c9747d-4dd6-e3ed-8aa3-6a74d07d5316.png)

すると`example`フォルダが表示されなくなります。  

![A9A32C7B-C8C7-410C-A727-BE5CCF1B9FAB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ca5910ce-1b83-6d89-73d0-e187fe8a20bf.png)

また「Files: Exclude」に`**/test.txt`を追加すると`test.txt`が非表示になります。  

![59730607-424B-470C-8A39-6A04B2B5F8EE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/7a115adb-977b-d25c-cf75-33f6fe1c5f77.png)
【Tips】Typescript＋Webpackで'Critical dependency: the request of a dependency is an expression'が発生した場合の対処法

# はじめに
記事タイトルのエラーの対処方法を見つけるのに苦労したので記録しておく。
ちなみに、'Critical dependency: the request of a dependency is an expression'のエラーは、requireに変数を渡した場合に発生するWarningだ。Warningなのでeslintがエラーになって止まってしまうということはないが、毎回表示されるのも面倒なので無視をしたかった。

## 方法① パース対象外にする
以下の通り、Webpackの設定で該当のモジュールをパース対象外にする。なお、自分の環境ではlog4jsで発生していた。

```Javascript
  module: {
    noParse: [/log4js/],
  },
```

パース時にエラーになるなら、パースなんてやめちゃえばいいじゃない、という考え。
確かにエラーは消える。でもちょっと待て。パースやめるなんてそんな乱暴でいいのか？

## 方法② stats.warningsFilterで無視する
[ここ](https://webpack.js.org/configuration/stats/#statswarningsfilter)参照。

調べている内にdeprecatedであると書かれていたので自分では試していない。

## 方法③ ignoreWarningsで無視する。
↑からもリンクされているのでこれが一番正攻法のようだ。
Webpackの設定でignoreWarningsの仲間に入れる。
この方法であれば、モジュールやファイル全体ではなくて、特定のモジュールの一部のWarningだけ無視できる。
余計に無視しすぎてエラーを見逃してしまうことがなくなるので、良い感じの方法なのではなかろうか。


```Javascript
  ignoreWarnings: [
    {
      module: /log4js/,
      message: /Critical dependency: the request of a dependency is an expression/,
    },
  ],
```

これでビルドすると、Warningが消えてくれる！
RailsでのRPC, REST, ドキュメント, クライアント自動生成について調べた

## GraphQL
https://github.com/rmosolgo/graphql-ruby

クエリを１回で取得できないのが悩み
コードにドキュメントを書く

### GraphQLのクライアントコードジェネレータ 
https://github.com/dotansimha/graphql-code-generator

## REST + jsonapi-serializer + OpenAPI
https://github.com/jsonapi-serializer/jsonapi-serializer

Netflix製 早いらしい
OpenAPIを手書きする必要がある。
クライアントとサーバー同時開発し、最初にOpenAPIから書くならば良さそう

### OpenAPIのクライアントコードジェネレータ 
https://github.com/OpenAPITools/openapi-generator

## gRPC
https://github.com/grpc/grpc/tree/master/src/ruby

webの場合、envoy proxyが必要

### gRPCのドキュメント
https://github.com/pseudomuto/protoc-gen-doc

コメントアウトでドキュメントを書き、generateする

## twirp
https://github.com/twitchtv/twirp
twitch製のRPC protoで記述する
HTTP 1.1で動作する

### twirpのクライアントコードジェネレータ
https://github.com/twitchtv/twirp

---
↓ここからRails関係ない

## hasura
https://github.com/hasura/graphql-engine

PostgresからGraphqQLを構築
サーバーのロジックをクライアントが持つことになる

## tRPC
https://github.com/trpc/trpc

サーバーのコードはTypeScriptで記述することになるが、server側で定義したInterfaceをそのままclient側で取り込んで繋ぎ込みができる
RaspberryPiにDockerとdocker-composeをインストールする

# Dockerのインストール

```bash
# Dockerのインストール
sudo apt install -y docker.io

# 現在のユーザーでdockerコマンドを使用できるようにする
sudo usermod -aG docker $USER

# 再起動
sudo reboot
```

# docker-composeのインストール

```bash
# docker-composeのインストール
sudo apt install -y docker-compose
```

# 参考
https://tech-lab.sios.jp/archives/27798
自作のChromeプラグインでサイト自動ログイン

Chromeの拡張機能作るってなんか難しそうって思うかもですが（実は自分もそうだった）実は意外と簡単でした。
よく使うとあるサイトでUIが恐ろしく悪くて、毎回ログインを要求されます。で、これを解消するプラグインとかあるかなーと思って探している時に自分で作ればいいということがわかったので以下にやり方を記載します。

適当にディレクトリ作って以下のファイルを用意します。

```manifest.jspon
{
	"manifest_version": 3, // 今だと最新は3
	"name": "somewebsite", // 何か名前をつける
	"version": "1.0",
	"description": "ログイン",　// 説明を記述
	"content_scripts": [{
		"matches": ["https://somewebsite.jp/login"], // こちらのURLにマッチしたら
		"js": [
			"main.js" // こちらのJSを実行
		]
	}]
}
```

フォームはシンプルなEmailとPassword入れるだけのものとします。
```main.js
//web login

document.forms[0].elements[1].value = "email@email";
document.forms[0].elements[2].value = "password";

document.forms[0].submit();
```

Chromeの拡張機能を開いてデベロッパーモードをONにします。
その後「パッケージ化されている拡張機能を読み込む」をクリックして上のファイルを読み込みます。
![拡張機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1593/fdd939d4-6f61-49e3-a40f-9bd4d15c1c9c.png)

とここまでやるとあとはChromeで当該ページ（ https://somewebsite.jp/login ）を開くだけで勝手にログインしてくれます。

ぜひお試しください。
gem `puma`を6.0にアップグレードすると`capybara` の初期化で`NoMethodError:   undefined method `strings' for Puma::Events:Class`エラーが発生する問題の対処法

# 結論

`puma`を`6.0`以上で動作する場合`capybara`は`3.38.0`以上のバージョンが必要です

# 詳細

#### 1. 元々`puma`の実装で`Puma::Events`クラスは以下の2つの異なる責務を担っており責務過多だった

- ロギング
- コールバックイベントの管理

#### 2. 上記の2つをそれぞれの`class`に分離するBreaking changeが入るリファクタリングを行い`6.0`でリリース

https://github.com/puma/puma/pull/2798

#### 3. `capybara`で``Puma::Events`を参照していたが上記の変更の影響を受けてエラーが発生

```ruby
Failure/Error: events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
            
NoMethodError:
  undefined method `strings' for Puma::Events:Class

    events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
                                                   ^^^^^^^^
# ruby/3.1.0/gems/capybara-3.37.1/lib/capybara/registrations/servers.rb:32:in `block in <main>'
# ruby/3.1.0/gems/capybara-3.37.1/lib/capybara/config.rb:64:in `block in server='
# ruby/3.1.0/gems/capybara-3.37.1/lib/capybara/server.rb:77:in `block in boot'
# 
#   Showing full backtrace because every line was filtered out.
#   See docs for RSpec::Configuration#backtrace_exclusion_patterns and
#   RSpec::Configuration#backtrace_inclusion_patterns for more information.
```

#### 4. `capybara`で対応がされて`3.38.0`でリリース

https://github.com/teamcapybara/capybara/pull/2530

# その他

## puma 6.0 のupgrade用ドキュメント

https://github.com/puma/puma/blob/master/6.0-Upgrade.md
GoのOpenAPI3.0コードジェネレータ、oapi-codegenでchiのコードを生成しサーバーとして動かす

GoのOpenAPI3.0コードジェネレータであるoapi-codegenは、yaml定義からGoのコードを生成できる。
今回は、サーバサイドのコードをchiで生成し、サーバとして動かすところまでを実施する。

https://github.com/deepmap/oapi-codegen

## 環境
- Ubuntu 20.04 LTS (WSL2)
- Go 1.19.3

Goはインストール済みであるとする。

## 0. goプロジェクトの作成

```sh
mkdir go-oapi
cd go-oapi
go mod init gen
```

## 1. コードの生成

生成元となるyamlのサンプルを準備する。以下のファイルを`petstore-expanded.yaml`として作業フォルダに保存する。

https://github.com/deepmap/oapi-codegen/blob/master/examples/petstore-expanded/petstore-expanded.yaml 

また、以下を`config.yaml`として作業フォルダに保存。

```sh
package: gen
generate:
  chi-server: true
  models: true
  embedded-spec: true
compatibility:
  apply-chi-middleware-first-to-last: true
output: petstore.gen.go
```

以下のコマンドを実行すると、`petstore.gen.go`としてサーバサイドのコードが生成される。

```sh
go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
oapi-codegen -config config.yaml petstore-expanded.yaml
```
## 2. APIの実装

サンプルコードを利用する。以下のコードをapi.goとして作業フォルダに保存し、パッケージ名をgenに変更する。

https://github.com/deepmap/oapi-codegen/blob/master/examples/petstore-expanded/chi/api/petstore.go

## 3. サーバーの作成

以下を実行し、

```
mkdir main
touch main/main.go
```

以下のコードをmain.goに記入する（サンプルコードを利用）

```go
package main

import (
	"flag"
	"fmt"
	"gen"
	"log"
	"net/http"
	"os"

	middleware "github.com/deepmap/oapi-codegen/pkg/chi-middleware"
	"github.com/go-chi/chi/v5"
)

func main() {
	var port = flag.Int("port", 8080, "Port for test HTTP server")
	flag.Parse()

	// swagger定義の読み込み
	swagger, err := gen.GetSwagger()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
		os.Exit(1)
	}

	swagger.Servers = nil

	// 自分のAPI実装を入れる
	petStore := gen.NewPetStore()

	// chiのルータを作る
	r := chi.NewRouter()

	// バリデーションミドルウェアの追加
	r.Use(middleware.OapiRequestValidator(swagger))

	// API定義と実装を紐づけ、それをルータrに登録する
	gen.HandlerFromMux(petStore, r)

	s := &http.Server{
		Handler: r,
		Addr:    fmt.Sprintf("0.0.0.0:%d", *port),
	}

	log.Fatal(s.ListenAndServe())
}

```

これができたら、以下を実行して、ライブラリをインストールしておく。

```sh
go mod tidy
```

## 4. 実行
以下のコマンドでサーバーを起動して、

```
go run main/main.go
```

以下のcurlコマンドによって動作テストができる。

```sh
# データの登録
curl -X 'POST' \
  'http://localhost:8080/pets' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "tag": "string"
}' 
# > {"id":1000,"name":"string","tag":"string"}

# データの表示
curl -X 'GET'   'http://localhost:8080/pets'   -H 'accept: application/json' # > [{"id":1000,"name":"string","tag":"string"}]
```

以上です。

# 参考
Go の Open API 3.0 のジェネレータ oapi-codegen を試してみた

https://future-architect.github.io/articles/20200701/

小ネタ／Open API 3.0 ジェネレータ oapi-codegen v1.11.0 のコード自動生成の方法

https://qiita.com/hmatsu47/items/5da28bf8c1f7165d03e9

oapi-codegenでchi用APIインターフェースを自動生成

https://rinoguchi.net/2022/06/oapi-codegen-chi-server.html
python: pip installをコマンドしてもinvalid syntaxでうまくいかないときの対処法

## 環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2649584/bd8c248e-f27f-67ac-5622-8071fd0177c8.png)
<table>
<thread>
<tr>
<td></td>
<td>環境</td>
</tr>
<tr>
<th>pc</th>
<td>windows10</td>
</tr>
<tr>
<td>言語</td>
<td>python3.11</td>
</tr>

## コマンドプロンプト起動後すべきこと

コマンドプロンプト起動後、pythonを起動する前にpip installを実行することで、エラーを回避することができる
```python3.11
pip install ~　# pip installがpyの前に来る

py 
```



参照：https://sprockethole.work/2018/09/09/python%E3%81%AEpip%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%84%EF%BC%9F/#pip%E3%81%A7%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%AE%E6%96%B9%E6%B3%95


<table class="table">
Janomeが半角記号を「名詞,サ変接続」と認識するのを変更する

# はじめに
MeCabと同様、Janomeでも半角文字を形態素解析すると「名詞,サ変接続」と予測される（ややこしい）仕様が存在します。

```python
from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()

for t in tokenizer.tokenize("/"):
    print(t.surface, t.part_of_speech)
#=> / 名詞,サ変接続,*,*
```

MeCabの場合は辞書を書き換えてインストールし直す必要があります。

https://nymemo.com/mecab/564/

しかし、JanomeはPythonだけで書かれているのでPythonのコード上でなんとかすることができます。

```
# バージョン
janome==0.4.2
```

# Pythonのコード上で変更する方法
tokenizerを呼び出した後、以下のように未知語に対する辞書の設定を呼び出すことができます。
```python
from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
tokenizer.sys_dic.unknowns
#=>
{'DEFAULT': [(5, 5, 4769, '記号,一般,*,*')],
 'SPACE': [(9, 9, 8903, '記号,空白,*,*')],
 'KANJI': [(1285, 1285, 11426, '名詞,一般,*,*'),
  (1283, 1283, 17290, '名詞,サ変接続,*,*'),
  (1293, 1293, 17611, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 12649, '名詞,固有名詞,組織,*'),
  (1289, 1289, 17340, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 15295, '名詞,固有名詞,一般,*')],
 'SYMBOL': [(1283, 1283, 17585, '名詞,サ変接続,*,*')],
 'NUMERIC': [(1295, 1295, 27386, '名詞,数,*,*')],
 'ALPHA': [(1285, 1285, 13398, '名詞,一般,*,*'),
  (1293, 1293, 18706, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 13835, '名詞,固有名詞,組織,*'),
  (1289, 1289, 18188, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 15673, '名詞,固有名詞,一般,*'),
  (3, 3, 15235, '感動詞,*,*,*')],
 'HIRAGANA': [(1285, 1285, 13069, '名詞,一般,*,*'),
  (1283, 1283, 20223, '名詞,サ変接続,*,*'),
  (1293, 1293, 17882, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 14761, '名詞,固有名詞,組織,*'),
  (1289, 1289, 18060, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 14787, '名詞,固有名詞,一般,*'),
  (3, 3, 16989, '感動詞,*,*,*')],
 'KATAKANA': [(1285, 1285, 9461, '名詞,一般,*,*'),
  (1293, 1293, 13661, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 10922, '名詞,固有名詞,組織,*'),
  (1289, 1289, 13581, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 10521, '名詞,固有名詞,一般,*'),
  (3, 3, 14138, '感動詞,*,*,*')],
 'KANJINUMERIC': [(1295, 1295, 27473, '名詞,数,*,*')],
 'GREEK': [(1285, 1285, 7884, '名詞,一般,*,*'),
  (1293, 1293, 12681, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 8573, '名詞,固有名詞,組織,*'),
  (1289, 1289, 12697, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 10029, '名詞,固有名詞,一般,*')],
 'CYRILLIC': [(1285, 1285, 7966, '名詞,一般,*,*'),
  (1293, 1293, 12600, '名詞,固有名詞,地域,一般'),
  (1292, 1292, 8492, '名詞,固有名詞,組織,*'),
  (1289, 1289, 12615, '名詞,固有名詞,人名,一般'),
  (1288, 1288, 9866, '名詞,固有名詞,一般,*')]}
```
この`'SYMBOL': [(1283, 1283, 17585, '名詞,サ変接続,*,*')]`の部分を書き換えてしまえば目的は達成です。

```python
symbol_settings = list(tokenizer.sys_dic.unknowns["SYMBOL"][0])
symbol_settings[3] = "記号,一般,*,*"
tokenizer.sys_dic.unknowns["SYMBOL"][0] = symbol_settings
```

この結果、形態素解析の結果が変更されます。
```python
tokenizer = Tokenizer()
for t in tokenizer.tokenize("/"):
    print(t.surface, t.part_of_speech)
#=> / 記号,一般,*,*
```

ちなみに`unknowns`の定義場所は以下

https://github.com/mocobeta/janome/blob/dc7ee378e3ae771d0ad4147c9f87c0feccee2210/janome/dic.py#L340

# 辞書のファイルを変更する方法
https://github.com/mocobeta/janome/issues/93

のイシューで言及されているように、以下のzipファイルを解凍して`sysdic/unknowns.py`の中身を書き換えても実現可能なようです

https://github.com/mocobeta/janome/blob/master/ipadic/sysdic.zip
環境構築が毎回うまくいかないマン～Anacondaに繰り返しインストールして70GB～

# それは私
絶賛、環境構築失敗中です。
経緯としては、ESPNetなる技術を使いたくて、解説サイト通りに、UbuntuとAnacondaを入れてやっていました。
ところが、上手くいかず、インストールをあの手この手で趣向を変えながら何度も繰り返しているうちに70GBほど容量を食ってしまいました。3日間で18時間くらいの時間を無駄にしました。もう一度やり直すために、Anacondaと関連ファイルを全て消してやり直すことになり今に至っています。現在、約70GBのファイル達を消しながら記事制作中です。
何故、今回に限らず毎回失敗するのか、何がいけないのかについてメモ程度にまとめます。

# 0. 構築に関する技術を体系的に理解していない
全てこれに集約されます。
理解していなければ理解すればいい話なのですが、環境構築後の本題とはほとんど関係ないので飛ばしがちです。
解説サイトの内容をそのままやれば行けるだろうなどという考えもそれを後押ししています。
とはいえ、環境構築はある程度ささっと終わらせたいのが本望。本題ではないところに理解する時間を割くのはもったいないです。
では、この願いを叶えながら環境構築するにはどうすればよいのか。これについて考えていきます。

# 1. 解説サイトを何か所かまわり、一番ポピュラーそうな方法を探す
どのサイトも同じでしょ～とか思って、検索結果の一番上に出てくるサイトを鵜呑みにするのはやめます。
何か所か見て良さそうなのを判断するのが堅実。

# 2. 環境構築に必要なソフトを知らずに進めない
今回、UbuntuもAnacondaも初めてなのでほぼ何も知らなかったのですが、よくよく考えてみるとUbuntuは導入を楽にするために必要としてもAnacondaまではいらなかった気がします。
何をダウンロードするかさえ書いていないサイトを見て挿入するのはやめます。アンインストールしてやり直すのすら大変なので。

# 3. 導入したものは本当に必要だったのか疑う
ずーっとAnacondaを主とした構築を進めてきましたが、Anacondaはどうやら古いパッケージなどを保持するらしく、さらにディレクトリごとに異なる環境を作り出すため、後片づけが大変でした。
何が必要で何がいらないかをちゃんと判断していきたいです。

# おしまい
記事書くのも萎えたので終わります。
以上！良い環境構築ライフを！！
【Linux】scpコマンドの使い方

scpコマンドの使い方を良く忘れるので備忘録として記事を書きます。
(特にユーザとホスト名どちらが先かをよく忘れます)

## scpコマンドとは

サーバ間でファイルの送受信を行うためのコマンドです。
通信プロトコルにはSSHが使われます。(SecureCoPyと覚えるといいでしょう。)

## 基本的な実行方法

まずはオプションを使わずに実行する方法を確認します。
この場合、リモートサーバに接続する際の認証方法はパスワード認証です。

### ローカルサーバからリモートサーバにファイルをコピーする

```:bash
scp [コピー元のローカルファイル] [リモートサーバのユーザ]@[リモートサーバのIPorホスト名]:[コピー先のディレクトリ]
```

例えば、ローカルサーバの ```/usr/local/hoge.txt``` を```000.00.0.0```のrootユーザの/tmpディレクトリに送信する場合次のようになります。

```:bash
scp /usr/local/hoge.txt root@000.00.0.0:/tmp
```

複数パスを指定するとまとめてコピーすることができます。

### リモートサーバからローカルサーバにファイルをコピーする


```:bash
scp [リモートサーバのユーザ]@[リモートサーバのIPorホスト名]:[コピー元のファイルパス] [ローカルサーバのコピー先ディレクトリ]
```

リモートサーバの ```/usr/local/hoge.txt``` をローカルサーバのrootユーザの/tmpディレクトリに送信する場合次のようになります。

```:bash
scp root@000.00.0.0:/usr/local/hoge.txt /tmp
```

## 使用頻度が高めなオプション

|オプション名|説明|
|-----------|---|
|-4|IPv4のみ許可する|
|-6|IPv6のみ許可する|
|-C|通信量を圧縮する|
|-i|秘密鍵ファイルのパス|
|-P|リモートホストのポート|
|-p|権限や変更日時を保持したままコピーする|
|-r|ディレクトリごと再帰的にコピーする|

特によく使うのは-iと-rです。

-i: パスワード認証だと対話的に実行する必要があり、自動化の妨げになる。それに対して鍵認証の場合対話処理が不要であるため自動化しやすい。

-r: ディレクトリごとコピーすれば何回もコマンドを実行する必要がない。

## 参考資料

- [UX MILK](https://uxmilk.jp/50946)
- [manページ  — SCP](https://nxmnpg.lemoda.net/ja/1/scp)
- manコマンドで表示されるマニュアル
エンジニア初心者がチームでテスト駆動開発を経験したお話

# はじめに
チームでテスト駆動開発に関する動画を視聴したことがきっかけでした。

https://www.youtube.com/watch?v=Q-FJ3XmFlT8

# 良かった点
- 仕様を理解しているか最初に確認できる
- 実装がシンプルになるので後からバグが…ということが少なくなる
- 後からテストを書く必要がないので気持ちが楽になる

# 気を付けたい点
- テスト未経験だと学習コストが高い
- 急ぎの案件だからテスト駆動開発をしないケースがある

# おわりに
以下の理由から複数人で同じ作業を行うペアプロやモブプロとの相性が良いと感じました。経験の浅い自分にとっても相性が良かったかもしれないです。
- お互いに仕様を理解しているか、早い段階確認できる
- todoリストを作ることから始めるので経験の浅いメンバーの教育が期待できる
Atomエディタショートカット（自分用メモ）

#Atomエディタ機能
※自分用メモ（よく使うの増えたら随時追加する予定）

コマンドパレット開き方
→「Ctrl + Shift + P」

作成中のHTMLのプレビュー表示方法
→「Ctrl + Shift + H」
※事前に拡張機能の「auto-html-preview」をインストールする必要あり
エンジニア初心者がモブプロを経験したお話

# はじめに
モブプロを経験するまでは約1年ほど個人で開発をしていました。
その後チーム内でモブプロを導入したので、所感を簡単にまとめます。
モブプロについては各自で調べて見てください。

# モブプロをするとどうなるか
## 良かった点
- モブプロの仕組み的にチーム内の会話が増える
- 全員で同じ作業に取り掛かるので質問しやすくなる
- 経験のあるメンバーにリアルタイムで教えてもらえるので、経験の浅いメンバーが成長しやすい
- 作業の属人化が少なくなる
- チームの残業時間が平均化される
- タイピストを10分/人で3人回したら5分休憩といったルーティンで行うので業務にメリハリがつく
- メンバーが使用している開発の小技が身に着く

## 気を付けたい点
- 経験が浅いメンバーはモブプロ中の発言が少なくなる
    - チームメンバーによると思いますが、経験があってよく話すタイプがメンバーにいるとその人達でガンガン進んでしまうときは気づいたら実装がかなり進んでいる…といったことになりがちでした。分からないと思った時はすぐにモブを止めて質問するようにしましょう。経験の浅いメンバーがよく話すタイプでないときは、経験のあるメンバーはあまり話さないようにして、ヒントを与えたり、状況を整理するような立ち回りをするとモブが上手く回るようになると思います。 
- 自分で手を動かす時間が少なくなるので理解しているつもりになりがち
   - 個人的に一番気を付けていました。モブプロとソロプロでは「思考スピード」に違いがあると感じていて、モブプロで実装した内容を経験の浅いメンバーがすぐに一人で実装できるかと言われると難しいと思います。そのため、実装した内容を後から自分で実装して復習するようにしていました。

- モブプロ中は外部環境の影響を受けないようにするため、他の作業の優先度を低くする必要がある
    - メンバーの中に別案件を担当していて時間をとられてしまう人がいるときは、モブプロを行う時期や時間を相談した方が良いと思います。


# おわりに
モブプロを導入するとチーム開発がしやすく、メンバーの育成と相性が良いと感じました。
全員で同じ作業に取り掛かる分、ソロプロに比べるとプロジェクト全体の進捗は遅くなりますが、
常に全員が同じコードを見ているため、後から発生しやすいバグの対応が少なくなります。
チームに初めてモブプロを導入する際は、案件が急ぎでないこと、チームがほぼ未経験のメンバーで構成されていないことなどを確認した上で検討すると良いと思います。
SQLServerでは文字列比較の際、空白に注意する必要がある (+ おまけつき)

「詳しくは下のドキュメントを読んでね!!!以上!!!!」という内容ですが、お仕事ではまった内容なので、個人的にメモしておきます。

https://support.microsoft.com/en-us/topic/inf-how-sql-server-compares-strings-with-trailing-spaces-b62b1a2d-27d3-4260-216d-a605719003b0

このドキュメントにもある通り、SQLServerでは、特別に設定をしない限り、末尾の空白はトリムされたものとして、文字列比較をします。たとえば、以下の比較はTRUEとなります。

```SQL
'AAA' = 'AAA   '
```

ここで注意したいのは、いわゆる空文字と空白文字だけの文字列が同じとして扱われることです。たとえば、以下はスペース5文字と空文字を比較したものですが、これはTRUEです。

```SQL
'     ' = ''
```

ほとんどのシステムでこの仕様が問題にはならないと思いますが、たとえば以下のような業務上の要請がある場合、考慮が必要になります。

- 空文字と空白文字で業務上の意味合いが異なる
- 末尾に空白のない`'A'`と末尾に空白のある`'A '`を明確に区別したい

はっきりいって、わけのわからない仕様だと思いますが、わけのわからない仕様が飛び出してくるのが、システム開発というもの。とくに古いシステムをそのままコンバージョンするような場合、何が出てきてもおかしくないので、気を付けましょう(?)

**おまけ**

末尾の空白について関連した話題をあげておくと、SQLServerでよく利用される関数に`LEN`があります。これは文字列長を返す関数ですが、この関数も末尾の空白を切り捨てる仕様です。

> Returns the number of characters of the specified string expression, excluding trailing spaces.

https://learn.microsoft.com/en-us/sql/t-sql/functions/len-transact-sql?view=sql-server-ver16

これも空白文字や空文字については注意する必要があります。たとえば、以下は5個のスペースのみからなる文字列をLENの引数にしていますが、この結果は0になります。

```SQL
SELECT LEN('     ')
```

上述したようにこの仕様は空文字や空白文字、末尾の空白に業務上の意味合いがあるシステムでは問題になることがあります。気を付けましょう(?)
BitcoinブロックチェーンのバランスをAPI経由で取得する方法

## 本番環境

ブラウザに以下を投げるとバランスが取得できる。
```
https://api.blockcypher.com/v1/btc/main/addrs/<your bitcoin address>/balance
```


## テスト環境

ブラウザに以下を投げるとバランスが取得できる。
```
https://api.blockcypher.com/v1/btc/test3/addrs/<your bitcoin address>/balance
```

## 参考文献
https://www.blockcypher.com/dev/bitcoin/#introduction

https://github.com/bitcoinjs/bitcoinjs-lib/issues/678


## おまけ

本番環境についてはこちらの方が色々できそうです。

https://jsapi.apiary.io/apis/blockchaininfo/reference.html
【Terraform】AWSのS3をbackendに設定するための必要最低限の設定

## はじめに
AWSのS3をTerraformのbackend(tfstateファイルの保管場所)として利用するために必要最低限の設定についてまとめました。

## backend保管のイメージ
tfstateファイルをローカル保存ではなく、S3内に保存することでチームでtfstateファイルを共有可能です。

![backend.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/4273747c-8ba6-0e3b-cf8f-b5406cc3b559.png)

## S3 の設定

### 1.S3 Bucket の作成

|  項目  |  設定  |
| ---- | ---- |
|  Bucket name  |  任意の名前  |
|  AWS Region  |  ap-northeast-1  |
|  Object Ownership  |  ACLs enabled  |
|  Block Public Access settings for this bucket  |  Block all public access  |
|  Bucket Versioning  |  Enable  |
|  Default encryption  |  Disable  |
|  Advanced settings  |  Disable  |

Terraformの公式ドキュメントを確認すると、Bucket Versioning を有効化にすることが推奨されています。

> Warning! It is highly recommended that you enable Bucket Versioning on the S3 bucket to allow for state recovery in the case of accidental deletions and human error.
> 引用 : https://developer.hashicorp.com/terraform/language/settings/backends/s3

### 2.Bucket policy の設定
対象のIAMユーザーからのみS3 Bucket へのアクセスを通すようにする。
※今回は、必要最低限の設定のため、IAMユーザーとしています。

```json:Bucket policy
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::************:user/Terraform"
			},
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::terraform-backend1103/*"
		}
	]
}
```

[AWS Policy Generator](https://awspolicygen.s3.amazonaws.com/policygen.html)を利用すれば、直接JSONを記述しなくてもコードを生成することが可能。

|  項目  |  設定  |
| ---- | ---- |
|  Select Policy Type  |  S3 Bucket Policy  |
|  Effect  |  Allow  |
|  AWS Service  |  許可したいIAMユーザーのARN  |
|  Actions  |  Block all public access  |
|  Amazon Resource Name (ARN)  |  backendを格納するS3のARN  |


## 参考
https://developer.hashicorp.com/terraform/language/settings/backends/s3
【Perl初学者】Perlとは

# 目次
- 歴史
- 特徴
- 勉強する価値アリ？ナシ？
- まとめ

# 歴史
> 引用:Wikipedia
Perl（パール）とは、ラリー・ウォールによって開発されたプログラミング言語である。実用性と多様性を重視しており、C言語や[sed（セド）](https://ja.wikipedia.org/wiki/Sed_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))、[awk(オーク)](https://ja.wikipedia.org/wiki/AWK)、[シェルスクリプト](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB#%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)など他のプログラミング言語の優れた機能を取り入れている。ウェブ・アプリケーション、システム管理、テキスト処理などのプログラムを書くのに広く用いられている。

登場時期は１987年。日本でのインターネット黎明期前に登場したということで、かなり歴史のある言語となっております。
影響を受けた言語はC, awk, シェルスクリプトなど, 知らないものも結構ありますね。ITって奥が深いなあ。。
なお影響を与えた言語は[JavaScript](https://ja.wikipedia.org/wiki/JavaScript), [PHP](https://ja.wikipedia.org/wiki/PHP_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)), [C++](https://ja.wikipedia.org/wiki/C%2B%2B)と、かなりメジャーな言語が影響を受けているんですね、すごいです。

マークは、こんな感じ↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2647183/d07491fd-03a8-fbf4-0972-5a49dea211d6.png" width=50%>

# 特徴
### オブジェクト指向
> 引用:Perl公式 
その主な機能は、使いやすく、手続き型プログラミングとオブジェクト指向 (OO) プログラミングの両方をサポートし、テキスト処理の強力な組み込みサポートを備えており、世界で最も印象的なサードパーティ モジュールのコレクションの 1 つを備えていることです。

オブジェクト指向とは、システムを構成する際に、役割ごとにファイルを分けて分けたファイル同士を結びながら構成していく考え方です。

ただPerlのオブジェクト指向は、もともと備わっているものではなく、アップデートによって後付け的に追加されたもの、らしいです。

つまり、一般的な言語で使われているオブジェクト指向とは少し風変わりな挙動をするとか、しないとか。
例えばオブジェクト指向の役割を分担することに欠かせない**クラス**のことをPerlでは**パッケージ**と呼びます。
他にもクラスの分身（ちょっといい例え見つからない）でいう**インスタンス**のことを**リファレンス**と呼ぶし、**関数=メソッド**のことを**パッケージ内のサブルーチン**と言ったりします。
自分がまだ本当に新人の頃、研修としてPHPを勉強していましたが、当時習ったオブジェクト指向と呼称が全く変わっていてびっくりしました。

## 勉強する価値アリ？ナシ？
もちろんありだと思います。PHPやPythonを触っていると、確かにすごく可読性が高くて読みやすいと感じますが、少し踏み入った関数やシステムに触っていくと、(ここどういう構造になっているんだろう？)
とつまづくところがあります。そう言った点で、影響を受けたPerlなどの言語に触レていることで読み解く力が上達するのではないしょうか。と自分に言い聞かせています。

## まとめ
こんな感じで、、つらつらとPerlの概要について触れていきましたが、次回は変数宣言あたりに触れていこうと思います。では！
IntelliJ 便利なショートカットキー一覧

# ショートカットキー一覧（Windows）
自分が必要だと思ったものを適宜追加していきます。

- **Ctrl + Y**：現在行削除
- **Ctrl + D**：現在行複製
- **Ctrl + F**：検索
- **Ctrl + R**：置換
- **Ctrl + Space**：コード補完
- **Ctrl + Z**：元に戻す
- **Ctrl + Shift + Z**：やり直し
- **Ctrl + Alt + S**：設定（preference）を開く
Lチカに半年かかった話(FPGA)

# 結論から
長々と話すこともないので結論だけ書くと，Vivadoでbitファイルを作成してAdeptで書き込むことでうまくいきました．

# 詳しく
もしかしたら全く同じことでつまずいている人がいるかもしれないので，タイトル通りLチカに半年かかった話をもう少し詳しくしていきます．
## Lチカとは
Lチカとは「LEDチカチカ」の略です．
ArduinoやRaspberry Piを初めて触る人がまずやる定番の入門プログラムです．名前の通りLEDを点滅させます．
「hello world」のようなものと言えば分かりやすいでしょうか．

## ソフトウェア
* Vivado 2020.2
* Adept v2.26.1

## ハードウェア
* Arty S7-50

## 経緯
FPGA経験は2年前，研究でPYNQ-Z2を触ったのが最初です．その時にVivadoをインストールしました．

半年前，ついに自分用のArty S7を購入し，さっそくLチカのプログラムを書きbitファイル生成まで済ませたものの，ボードをパソコンにつないでもVivadoがボードを認識せず書き込めないという問題が生じていました(PYNQでは問題なく認識し書き込めていました)．

インターネットや本を漁っても，「ケーブルでつなげばOK」くらいのことしか書かれておらず参考になりません．そもそもArty S7自体，「ボードを買うだけでFPGAができる！　手軽！」が売りの商品なのでそれ以上の説明は本来必要ないのでしょう．

それでも「Vivado 認識しない」などのワードで見つかった数少ないサイトを頼りに，Vivadoに追加のデバイスドライバを入れてみたりもしましたが全く解決しませんでした．

二週間ほど挑戦を続けたものの，見つけたサイトの方法もすべて試しつくして打つ手をなくし，日々の忙しさも相まってそのまま放置してしまっていました．

しかし昨日，「Vivadoがボードを認識しないなら書き込み専用ソフトを使えばいいのでは？」とひらめき，Adeptをインストールして使ってみたところあっけなく成功してしまいました．

もし同じことで悩まれている方(いるのか分かりませんが・・・)，Adeptを使うととりあえず書き込むことはできます．

# 追記(2022/11/5)
Adeptでの書き込みが成功すると，Vivadoからボードが認識されるようになりました．
binファイルの書き込みはAdeptからではできないようなので，もしbinファイルを使いたい場合は適当なbitファイルをAdeptを使い書き込んだのち，Vivadoで書き込む必要がありそうです．
rails db:resetした時にActiveRecord::MismatchedForeignKeyと出た際の解決法

## 環境
- Ruby3系
- Rails7系
- MySQL
（SQLiteからMySQLにDBを変更しようとした際にエラーが発生した）


## エラー内容
```terminal:terminal
rails db:reset
と実行したら↓

ActiveRecord::MismatchedForeignKey:
↑エラーが発生した
```


## 解決法
```terminal:terminal
rails db:migrate:reset
```
を実行すれば、ActiveRecord::MismatchedForeignKeyが出ずに正常に動作します✅


## 原因
```rails db:reset```は、
1. 全テーブルdrop
1. schema.rbを元にDBを作成

します。
なので、**reference先が作られていないのに、任意のテーブルのreferenceカラムが先に作成されて、今回のエラーが発生します！**

そして、、、

```rails db:migrate:reset```は、
1. 全テーブルをdrop
1. migrationファイルを元にDBを作成

なので、**reference先のテーブルが先に作成されている限り、エラーは発生しません！**
※ referenceカラムが先に作成されるmigrationファイルの順番の場合は、reference先のテーブルを先に読み込むことでエラーが発生しなくなります。


## 参考にさせていただいた記事
- [Active Record マイグレーション　4.3 データベースをリセットする \- Railsガイド](https://railsguides.jp/active_record_migrations.html#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%92%E3%83%AA%E3%82%BB%E3%83%83%E3%83%88%E3%81%99%E3%82%8B)
- [rails db:resetとrails db:migrate:resetの違い \| junblog](https://junblog11.com/rails-dbreset%E3%81%A8rails-dbmigratereset%E3%81%AE%E9%81%95%E3%81%84/)


## 最後に
エラー解決記事が少なかったので執筆しました。
本記事が多くの悩める方に届くこと願っています🌱
Thang Nâng Hàng Bảo An

Thang nâng hàng Bảo An![thang-nang-hang-bao-1000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955385/5b8646c5-f3ce-0117-ce3b-efe5ce6ef078.jpeg)
 là thương hiệu được hình thành và phát triển từ những năm 2008. Ban đầu chúng tôi cung cấp thiết bị nâng hạ như tời kéo, palang phục vụ các công trình công nghiệp phục vụ cho các nhà máy, xí nghiệp, thủy điện.
Liên hệ :
Địa chỉ:Số 356 Phan Trọng Tuệ - Thanh Trì - Hà Nội 
Số điện thoại:0976292002 
Email: thangnanghangbaoanh@gmail.com
Website: https://thangnanghangbaoan.com/ 
Map: https://goo.gl/maps/QHUS1cf8MYKHZBU6A 
Tag: #thangnanghang #thangnanghangbaoan #baoan #toinanghang

Social:

https://thangnanghangbaoan.wordpress.com/ 
https://vi.gravatar.com/thangnanghangbaoan2022 
https://archive.org/details/@an_thang_n_ng_h_ng_b_o 
https://talk.plesk.com/members/thangnanghangbaoan.265938/#about 
https://bbs.now.qq.com/home.php?mod=space&uid=2911763 
https://thangnanghangbaoan.mystrikingly.com/ 
https://www.buzzfeed.com/thangnanghangbaoan/thang-nang-hang-bao-an-29xjbm3g8i 
https://www.liveinternet.ru/users/thangnanghangbaoan/post496143258/ 
https://www.tes.com/member/thangnanghangbaoan 
https://note.com/thangnanghang/n/n3ae72587540b 
https://ameblo.jp/thangnanghangbaoan
WSL2でCypressを動かしたかった4日間の記録

# はじめに

最近[こちら](https://www.youtube.com/watch?v=lI8CjHspGFU&t=0s)の動画を見ながらRSSからテックブログを作るのをやっていたのですが、TDDの中でフロントを作成するのに`Cypress`を導入する場面がありました

いままでE2Eの経験はなかったので、この動画をみて思っていたよりも直感的で導入してみたいなと思いました
そこで`WSL2`に導入しようとしてかなり苦戦したのでまとめます

Cypress以外にもGUIを使うものでしたら適応できるかと思います

# 解決方法

今回解決した方法としては

1. Windows11にアップデートする
2. Ubuntu 22.04を利用する
3. 以下のコマンドを実行する

```
$ sudo apt-get install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
$ npm install -D cypress
$ npx cypress open
```

私の場合は初回起動時に以下のエラーが発生しました

```
Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
```

そこで以下のコマンドでバスの起動をしたところ成功しました

```
$ sudo /etc/init.d/dbus start
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/289c9744-7872-b4f2-873e-cec7f8f06783.png)

# 苦戦日記

## 1日目

WSL2でGUIが起動できないのはもともと把握していました
そこで以下の記事通りにやったのですがうまくいきませんでした

https://blog-jp.richardimaoka.net/20210411

https://zenn.dev/kai/articles/cypress-e2etest

## 2日目

https://twitter.com/myskng/status/1583446799679131649?s=20&t=435LKEe2yV7t6Hgwu7iZLA

このツイートを発見して、Ubuntuの最新版22.04を使ってみることにしました
しかし、うまく動かず、1日目の設定をしてもうまくいきませんでした
なぜツイートの方は起動できているのでしょうか。。。

## 3日目

以下のツイートをまず発見

https://twitter.com/n_nishioka/status/1377445128697114624?s=20&t=435LKEe2yV7t6Hgwu7iZLA

社内でESETを利用しているのでそれが原因かもしれないとまず1つ目の原因っぽいものを見つけました

そしてこの日革新に迫るものを見つけました

https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-11-with-gui-support#1-overview

この記事には、Windows11でUbuntuがGUIに対応しましたよって書いてありました
ここでWindows11で最新のUbuntuでやれば成功することがわかり、試したところうまくいきました

# おわりに

かなりの時間がかかったので記事にしてみました
困っている人が多いイメージですので参考になると嬉しいです

GUIが対応されたのはかなり嬉しいアップデートでした！
NetBSDのarmのこと

NetBSDのコードが汚いとツイートしたところ、指摘されたので気になった点を書きます。

* ディレクトリの名前の付け方や階層がカオス
* 積極的に共通化してない

まずカーネルソースのsys/archの下の名前の付け方なのですが、CPUの名前とマシンからの名前がありごちゃまぜな感じです。

例
arm64 -> CPU
luna68k -> マシン

armのkernelソースは以下のディレクトにあります。

sys/arch/arm
sys/arch/evbarm
sys/arch/hpcarm

sys/arch/arm下もカオスでメーカー名とかCPUの名前があります。

marvell -> メーカー名
sunxi -> CPUコード名(メーカーはallwinner,CPU名はA10など)

またimxというCPUは初期のimx5まではFreescaleで、imx6以降は買収されてNXPになったのですが、

sys/arch/arm/imx
sys/arch/arm/nxp

というふうにCPU名とメーカー名に分かれています。

このディレクトリにはarmとarm32というディレクトリまであり、そもそもarmって32ビットじゃなかったっけ？とか思ったりします。~~これはおそらくarm32は後から共通化コードを作った時に別にしてしまったのではないでしょうか。~~ と思ったのですがlocore.Sがここにあるので最初からなのかもしれません。

sys/devの下に直接ファイルがあったりsys/dev/icの下にごちゃ混ぜでいれてるのもいけてません。

arm/pic/pic.cでPIC_MAXMAXSOURCESという定義が使われいます。PIC_MAXSOURCESというのもあります。SOC毎の定義もさまざまあり、なんのこっちゃ状態です。

共通化などで新しい実装を増やした時に、どれが新しくて、どれが古いのかがわかりにくいです。

arm/arm/armv6_start.Sというコードがあるのですが、imx/imx21でも使われていてv5でも使えるような気がします。とすると、armv5の方が良かったのではないでしょうか。v4のサポートは無いって意味のarmv6だったのでしょうか。

名前を自由に付けられる権利は必要だが、統一感がなくなると担当以外が理解しにくくなる。

NetBSDは多くのアーキテクチャをサポートする事を目標にしていると思うので、より分かりやすくディレクトリを掘るべきだと思います。

FreeBSDとNetBSDはbus_spaceというkpiを使っていますが、初期の時点では、個別実装だったのをFreeBSDでは力技で共通化してかなりコードが減っています。またこの共通化したものを標準化して古いものを消していたりします。しかしNetBSDでは古いものはいじらないってポリシーのようで、共通化もあまり積極的じゃないように見受けられますし、古いものはそのままにしているようです。

あと暗黙の決まりごとが多いように思います。cpu_initclocks()など自動的に呼び出されるので用意が必要なようです。あとグローバルでhzとか切ってあって、なんのこっちゃって感じです。

コメントが少ないのも気になります。

ソースツリーでビルドして、オブジェクトがソースツリーにできるのもいけてないです。

USBはumassでシングルユーザーの前で使われる可能性があるのに、デバッグ機能が貧弱なきがします。

NetBSDはターゲットを極力維持するという方針と思われますし、FreeBSDはターゲットを極力絞っていくという方針のため、違いが出ているのかもしれません。

armのCPUが入ったSOCのコードは、担当者が自分が作ったり修正したコードが影響するすべてのターゲットを持っていて確認できるわけではないので、対応が難しいことも事実です。

端的に言うとNetBSDはいじらない、FreeBSDはいじるということでしょうか。

またNetBSDは実装者に最大限の自由を提供するが、FreeBSDは統一を重んじるということでしょうか。

FreeBSDは力技で綺麗にしていて、メンテできないんなら消すって、脅迫じみたところもあります。あまりに力技なので、ちゃんと動くのか疑問なものも多いです。

NetBSDの悪口になってしまっていますが、FreeBSDのarmのv5の実装はいじったけっかNetBSDの30倍近くパフォーマンスが悪く、ほとんど使い物にならないことを考えると、NetBSDの方が現実的なのかもしれません。
GCPの実行異常クラスタを通知する方法

## 概要
実行異常でクラスタが存在し続けることがあります。
未発見の場合、ずっと実行がなされるので異常な料金が発生します。

そこで、定期的に実行の確認をするために、Cloud Functionsを活用して
ログを抽出して存在すればslackチャンネルを通知する　というシステムを構築しました。

![gcp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180499/b722eded-8194-2da2-1223-99b550439e9a.jpeg)


## 対応方法

### 前提

#### Webhook URL？

今回このslackへの通知に使用する「Webhook URL」についての解説

・アプリケーションの更新情報を他のアプリケーションへ
 リアルタイム提供する仕組みや概念

・イベント（リポジトリにプッシュなど）発生時
 指定した**URLにPOSTリクエストする仕組み

Webhookの説明を見ると**「通知する、Webhookを送る」などの言葉が用いられているが、
これはPOSTリクエストのことを指している**。

Webhookを利用すると何ができるのか？
GitHubやSlackなどのサービスのWebhookを利用すると、ユーザーはサービス側がPOSTリクエストするURLを指定可能

### 手順
1: Cloud Scheduler に定期実行スケジュールなどを登録
2: Cloud Scheduler が　Cloud Pub/Subトピックにメッセージを送信(←トリガーの役割)
3: Cloud Functions が起動
4: Cloud Functions内でSlackに投稿


### アーキテクチャ
Cloud Scheduler > Cloud Pub/Sub > Cloud Functions > slack

#### Cloud Scheduler & Pub/Subを設定
◼︎[Cloud Scheduler]
スケジューラーからもCloud Pub/Subの設定が可能。

設定方法は省略

#### 実装内容
一定時間ごとに下記コードが実行

#### 実装概要
異常起動実行を確認して一定時間以上起動していると
異常と認識してslaackへ通知


#### Cloud Functions

◼︎必要モジュールファイル

ファイル名：requirements.txt
　　必要なモジュールなどバージョンのインポートするバージョンなどを記載してファイル保存
[ブログ参照](https://nupwhite.com/posts/-freO993)


◼︎実行コード
ファイル名：main.py
```py
from google.cloud import proc
import datetime
import dateutil.parser
import requests
import base64
import os
import json


def extract(x):
    return (x.cluster_name, x.status.state, x.status.state_start_time)

def me2(y, t_limit):
    return y[2] < t_limit

def check_cluster(event, context):
    
    if 'data' in event:
        s = base64.b64decode(event['data']).decode('utf-8')
    else:
        s = os.environ.get('max(指標)', '(数値)')
    m = int(s)

    client = proc.ClusterControllerClient(
    client_options={"api_endpoint": "地域-dataproc.googleapis.com:443"}
    )

    # Initialize request argument(s)
    request = proc.ListClustersRequest(
        project_id="プロジェクト名", 
        region="",
    )

    # Make the request
    page = client.list_clusters(request=request)

    t_delta = datetime.timedelta(minutes = m)
    t_limit = datetime.datetime.now(datetime.timezone.utc) - t_delta

    me1 = lambda x: me2(x, time_limit)

    list = list(filter(me1, map(extract, page)))

    if list:
        webhook_url = "https://hooks.slack.com/~"
        message = f'`{checked_list[0][2]}から{m}時間以上`'
        requests.post(webhook_url, data=json.dumps({'text': message}))
    else:
        print("その他")

```

実行補足
functionsを作成する際に
ランタイム環境変数を設定して引数を渡すことが可能
スケジューラーのメッセージ本文からも引数設定が可能




## 参照資料
[Google cloud scheduler で Functionsを定期実行する](https://qiita.com/morita-toyscreation/items/358ed054655b4999f8cb)
GoでミニマムなWebサーバを書く(net/http, chi)

GoでミニマムなWebサーバを書いてみる。以下の2つを書く。

1. net/httpのみを使った例
2. chiでパスパラメータを取得する例

## 環境
- Ubuntu 20.04 LTS (WSL2)
- Go 1.19.3

Goはインストール済みであるとする。

## 1. net/http
以下を実行してプロジェクトを作成する。

```sh
mkdir go-http
cd go-http
go mod init go-http
touch main.go
```

main.goに以下を記述する。

```go
// main.go
package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/world", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

`go run main.go`を実行してサーバーを立ち上げ、http://localhost:8080/world をブラウザで開く。

以下のように表示されたら成功。

```
Hello, "/world"
```

## 2. chi

以下を実行してプロジェクトを作成する。

```sh
mkdir go-chi
cd go-chi
go mod init go-chi
touch main.go
```

main.goに以下を記述する。

```go
// main.go
package main

import (
	"net/http"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

func main() {
	r := chi.NewRouter()
	r.Use(middleware.Logger)
	r.Route("/{username}", func(r chi.Router) {
		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			articleID := chi.URLParam(r, "username")
			w.Write([]byte("hello, " + articleID))
		})
	})

	http.ListenAndServe(":3000", r)
}

```

`go run main.go`を実行してサーバーを立ち上げ、http://localhost:3000/world をブラウザで開く。

以下のように表示されたら成功。

```
hello, world
```

## 参考資料

net/http
https://pkg.go.dev/net/http

go-chi/chi
https://github.com/go-chi/chi
開発PCのメモリ容量をケチるのはプロジェクト施策として最悪手の一つである

# はじめに
　2022年ももうすぐ終わろうというこの時節にこんな基本的な話を書くのは自分としてもいささか遺憾なのですが、具体的に書かないとわからない人というのが世の中にはいらっしゃるようなので、記します。

# 開発環境のメモリサイズを削減すると何が起きるか
　開発PCで作業中に搭載されているメモリが足りないと不足分をディスク上に作成した仮想メモリで補おうとします。必要なメモリサイズに対して搭載メモリが足りないと[スラッシング](https://e-words.jp/w/%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0.html)を起こしてディスクアクセスが始まり、アクセスランプがチカチカしたまま処理がいっこうに終わらないといった現象が発生します。この現象は、動作が遅いけれどもエラーにはならないというのがクセモノで、極端に遅いのを我慢すればどうにか作業はできてしまいます。しかし、こういう現象が起きるようになったら普通に考えてメモリ増設を検討すべきです。
　特に大量の資材を使って開発を行うような現場でメモリが不足するPCを使っていると、劇的に生産性が下がることになります。とある大規模システムの開発現場では、Eclipce上で一回のビルド時に扱うソースファイル類が2万ファイルくらいあり、クリーンビルドをすると30分や1時間平気でかかっていました。ところがこれほどの大規模システムにもかかわらず（あるいは、大規模だからこそちょっとでも経費節減しようとしてか？）開発機にはメモリがたったの8GBしか搭載されておらず、何かというとPCの動作が不安定になって開発メンバーは四苦八苦していました。
　Eclipseを使ったJava開発のプロジェクトではよくあることですが、IDEだけでなくJavaEE用のアプリケーションコンテナやDBMSも開発PC内で動かす必要があります。使っているテストツールやビルドツールもできるだけ安くあげようとしてOSSを使うため品質が悪く何かというとクリーンビルドからのやり直しが必要になることがあり、生産性を著しく落としていました。ビルドだけでなく、ソースの表示動作も遅くなり、少しでもマシにするためパンくずリストやサジェスチョンなどの便利な機能もオフにして作業したりしていました。「せめてメモリを16GBにしてくれたら…」と開発者みんなが思っていました。


# 試算してみます

* メモリ増設：仮に8GB(6,000円）追加すると生産性が1.2倍になるものとする。
　いまどきメモリ8GBどころか16GBのモジュールでも数千円で買えます。数千円のメモリをケチって生産性が激落ちしているような現場、例えば上に書いたような劣悪な環境の現場で各PCに8GBのメモリを増設すれば、生産性は2倍に上がってもおかしくないですが、ここでは控えめに、生産性が1.2倍に上がると仮定します。 メモリ購入にかかるコストはたぶん3～4,000円くらいだと思いますが、調達やセットアップにかかる手間も含めPC１台につき 6,000円としてみましょう。
* 人件費：仮に総勢 100名 x 平均単価60万/月 ＝ 6,000万/月とする。
　最近は人手不足で人件費も高騰してきていますのでもっとかかるのではないかと思いますが、控えめに平均単価60万としておきます。
　人数は案件によりますが、大規模案件なら開発者の人数は数百人規模になることは普通にあります。ここでは計算を簡単にするために100人としました。
* この100人のPCに8GB増設をすれば、メモリ増設にかかる費用は6,000 x 100 = 600,000円(１人月)です。
* 一方、生産性が1.2倍になることで、単純計算で100人月 x 0.2 = 20人月分の工数が実質的に増えることになります。
* つまり、たった１人月分(1%)の出費で、差し引き19人月分=19%もの効率アップが見込めるわけです。
* 上に書いたように、控えめな数字で見積っています。費用を1人月追加して開発者を一名増員しても、スキルによってはまったく戦力にならないこともあり、場合によっては足手まといになることもありますが、メモリ増設はそのような心配もなく、入れた瞬間から確実にプロジェクトの生産性を上げてくれるのです。この増えた20人月は、新たに教育する必要もなく、入退場管理をする必要もなく、机もフロアスペースも用意する必要がありません。そして初期費用として最初に費用がかかるだけで、次の月も、その次の月も無料で効果が持続するのです。素晴らしくないですか？
* __開発PCのメモリを減らすということは、この逆をやるということです。__ プロジェクト施策の最悪手という意味がおわかりでしょうか。メモリの不足は、PCを使ったすべての作業の生産性に影響します。開発において、特に製造以降のほとんどの作業にブレーキがかかるということです。このことの重要さがもっと認識されるべきではないかと思います。PMBOKだとか、スクラムだとか、心理的安全性だとかいった高尚な話をする前にこういう基本的な問題をクリアすべきでしょう。

# 【余談】協力会社はこのことを指摘してくれません。
* もしあなたが発注側プライムベンダーのPMだったとして、開発に使うPCのメモリが足りないことが原因でプロジェクトの効率が激落ちしていたとしても、あなたのプロジェクトに開発者を派遣している協力会社の営業マンはそのことを教えてくれたりはしません。彼らはあなたのプロジェクトに人をたくさん入れさせるのが仕事なので、効率の悪い施策は大歓迎だからです。
* 逆にそのような場合に「PCのメモリを増設した方がよいのでは？」と言ってくれるような業者さんであれば、本当にプロジェクトのことを考えてくれている良心的な業者さんである可能性があるので、大事に長くつきあうべきでしょう。


# あとがき
* この記事で言いたいことは、ケチケチするなという話ではありません。__ケチケチするなら合理的にやりませんか？__ という話です。
開発経費をできるだけ削減するのもプロジェクトマネジメントの一環でしょう。それはわかります。しかし、削減すべきところはそこではありません。他の何を削ってもそこだけは削ってはいけません。わずかな費用を浮かすために開発PCのメモリ容量を減らすのは自分で自分の首を絞める行為であり、最悪手なのです。この施策によってプロジェクトが遅延し、その結果最大の被害をこうむるのは、ほかならぬこれを決めたプロジェクトオーナーの皆さんなのです。
最低限の装備を用意しないで戦に勝つことはできません。何卒ご考慮ください。

* 以上です。どなたかのお役に立てば幸いです。
プロジェクトの「時間」

# プレシデンスダイアグラム法(PDM(Precedence Diagramming Method)
連続する作業の依存関係(開始と終了のタイミング)を次の４つの方法で表現できる。
### FS（Finish-to-Start)
前作業が終わったら後作業が開始できる。
### SS(Start-to-Start)
前作業が開始したら、後作業が開始できる。
### SF(Start-to-Finish)
前作業が開始したら、後作業が終了できる。
### FF(Finish-to-Finish)
前作業が終了したら、後作業が終了できる。

# トレンドチャート
時間経過と予算消化を軸にして、予定と実績の差異を確認する目的で使用する。
チャートでは、```作業進行上の区切りや重要なチェックポイントとなるマイルストーンを設定し、予定通りに到達しているかをみる```。

# EVM（アーンド・バリュー管理）
EVMは、コストに注目して進捗管理を行う手法で、予算に対する出来高を見ていく。
４つの基本要素といくつかの指標がある。
## ４つの要素
### PV(Planned Value):計画予算（ベースライン）
### EV(Earned Value): 出来高
### AC(Actual Cost):実績コスト
### BAC(Budget At Completion):完了時の総予算

## いくつかの要素
### SV:スケジュール差異(Schedule Variance)
作業が先行していればプラス、遅延はマイナス。

### CV:コスト差異(Cost Variance)
予算に対して実コストが少ない場合はプラス、超過している場合は、マイナス。

### ETC:残作業の予測コスト(Estimate To Complete)
(BAC-EV)/CPIで求めることができる。

### EAC:完成時の予想コスト(Estimate at Completion)
AC+ETCで求めることができる。


# 関連記事
https://qiita.com/masatom86650860/items/77108dae7231a3974b40

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8