OmniAICreator/Qiita-1.07M huggingface dataset:
Cloudfrontの 署名付きCookie 署名付きURL とは？

## 勉強前イメージ

署名付き・・・って？
SSL的な話？

## 調査

基本的にはどちらも同じ機能で、コンテンツにアクセスできる `ユーザを制御` します

### 署名付きCookie のユースケース

- 複数の制限されたファイル(HLS形式の動画やウェブサイトの購読者の領域にあるすべてのファイルなど)へのアクセスを提供する場合
- 現在のURLを変更したくない場合

### 署名付きURL のユースケース

- 個別のファイル (アプリケーションのインストールダウンロード) へのアクセスを制限する場合
- ユーザーがCookieをサポートしていないクライアント(カスタムHTTPクライアント等)を使用している場合

### そもそもcloudfrontとは？

AWSのCDN(負荷分散をするためのコンテンツを配信するためだけのネットワーク)のサービスです。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/345d3faaf9387f39ea1f) をご確認ください

### cloudfrontでの設定箇所

こちら日本語翻訳かけてます

![AWSCloudFront管理コンソール - Google Chrome 2021-03-01 22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f53b9041-366c-7aae-a08b-c987b13a0879.png)


## 勉強後イメージ

確かにURLを変えたくない時とかは、署名付きCookieを使えばいいのねー

## 参考

- [署名付き URL と署名付き Cookie の選択](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-choosing-signed-urls-cookies.html)
- [CloudFrontの署名付きCookieでプライベートコンテンツの配信](https://dev.classmethod.jp/articles/cloudfront-signed-cookie/)
npmとYarnのまとめ記事、Node.jsを添えて

# 目的
Yarnやnpm(node package manager)に関する情報を要点を抑えて簡単にまとめる。
Yarnやnpmに関する記事は既にたくさんあるので参考になりそうな記事もまとめて網羅的に調べやすい記事にしたい（いろいろ動きがあれば更新していく）。

# [npm](https://www.npmjs.com/)?

- npmはNode.js（後述）のパッケージ管理ツール。
- 必要なパッケージをインストールする際に、そのパッケージが動くために必要な他のパッケージも合わせてインストールすることができる。
- モダンな開発を行いたいなら必須。

### 参考記事
[フロントエンド開発の３ステップ（npmことはじめ）](https://qiita.com/hashrock/items/15f4a4961183cfbb2658)
npmの導入方法などのシンプルでわかりやすい記事。

# [Node.js](https://nodejs.org/ja/)?

- ブラウザ上でしか動けなかったJavaScriptをパソコン上で動かせるようにする。
- JavaScript実行環境。プラットフォーム。Webサーバの役割を担うことができる。
- 開発に便利なパッケージを使うのに必要。

### 参考記事
[Node.jsとはなにか？なぜみんな使っているのか？](https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb#fn5)
Node.jsを利用することでフロント側でできることが増え、開発を効率的に行えるようになった。
その背景を説明しています。


# [Yarn](https://yarnpkg.com/)?

- npmとほぼ同じような用途に使う。
- npmと互換性があり、npmで使用していたプロジェクト設定ファイル（package.json）がそのまま使える。
- npmと比較するとインストールが速い、セキュリティが高いという特徴がある。
- npmとコマンドが似ているので学習コストは低い。

Yarnをインストールするためにnpmをインストールするってなんか変な感じですよね。

### 参考記事

[npmとは　yarnとは](https://qiita.com/Hai-dozo/items/90b852ac29b79a7ea02b)
npmとyarnの違いを箇条書きで簡潔に紹介しています。

[yarnチートシート](https://qiita.com/morrr/items/558bf64cd619ebdacd3d)
Yarnのコマンドがまとめられてます。npmのコマンドと似ているので導入しやすい！2017年の記事。
PostgreSQLで重複するデータの内の1件だけを削除する(システム列のctidを使った削除)

基本こんな状態になることはないはずなので、こんな対応する必要がある事自体が異常ではありますが、どうすれば良いのか調べて対処したので記録。

## 状況

- とあるテーブルでid列がプライマリキーに設定されていて、重複は許可されていない状況
- id列以外にname列もあり
- 通常であればid列が重複することなく管理されており、削除する場合はDELETEでid指定で消せば問題ない
- 例えば以下のような感じでデータが登録されている

|id|name|
|:--|:---|
|no-111|test data 1|
|no-222|test data 2|

- このような状況で、PostgreSQLのWALデータが破損したことをきっかけに以下のように何故か重複されたデータが入った状態になってしまった

|id|name|
|:--|:---|
|no-111|test data 1|
|no-222|test data 2|
|no-111|test data 1|

## 重複したデータを削除するには

- no-111のデータが2つはいってしまったので削除する
- そもそもデータおかしいので本来はバックアップデータとかからの復旧が望ましいですが、ここではその対応はせずにクエリで復旧を試みる

- MySQLとかだと、DELETE文にlimitを指定できるようなので、以下のように2個あるno-111のデータの内1件だけ削除っていうのも可能。

```
DELETE FROM testtable WHERE id = 'no-111' LIMIT 1;
```

- PostgreSQLだと、DELETE文でLIMIT句使えない。かつ上記のように全カラム同じ値になっているのでWHERE句でフィルタができないので、そのままでは対応が難しい。
- PostgreSQLにはシステム列を持っているのでこれを活用する。
    - ctidという列を持っている
    - これは、行バージョンの物理的な位置を示す列情報
- 例えば上記のtesttableの例だと以下のようなイメージ
- ```SELECT ctid,id,name FROM testtable;```を実行すると以下のような感じで出力される

|ctid|id|name|
|:--|:--|:---|
|(0,1)|no-111|test data 1|
|(0,3)|no-222|test data 2|
|(41,3)|no-111|test data 1|

- ctidを指定して削除ができるので以下のように実行すればデータ削除可能

```
DELETE FROM testtable WHERE ctid = '(41,3)';
```

## 補足


- そもそもこのような主キーが重複するデータが入るのがおかしいので状況を見てみたところ、idをWHERE句で指定すると重複が発生する前の元のデータのみが取れる状態になっている

```
SELECT * FROM testtable WHERE id = 'no-111';
```

|id|name|
|:--|:---|
|no-111|test data 1|

- LIKE句で指定すると2件取れてくる

```
SELECT * FROM testtable WHERE id LIKE 'no-111%';
```

|id|name|
|:--|:---|
|no-111|test data 1|
|no-111|test data 1|

- idの末尾にビューでは見えない文字が含まれているのか？と思い絞り込んでみても特に入っているわけではなさそう(末尾をLIKEで任意の一文字指定してもひっかかるので)

```
SELECT * FROM testtable WHERE id LIKE 'no-11_';
```
|id|name|
|:--|:---|
|no-111|test data 1|
|no-111|test data 1|

- かつid列の長さを出しても全く同じ。

```
SELECT length(id),id,name FROM testtable WHERE id LIKE 'no-111%';
```
|length(id)|id|name|
|:--|:--|:---|
|6|no-111|test data 1|
|6|no-111|test data 1|

以下のページのやり取りでもあるように、おそらく主キーの情報が破損してしまっている可能性が高いので、こういったケースはバックアップデータから復旧するなど、ちゃんときれいに作り直した方がいいですね。

https://ml.postgresql.jp/pipermail/pgsql-jp/2005-June/010684.html
DenoがTypeScriptの使用をやめる5つの理由

![deno-will-stop-using-typescript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/6400c877-fb5e-5edb-2783-f15c5c45b773.png)
# 前書き
**この記事は翻訳記事になります。** :point_up_tone1:

近年、JSで書かれてるプロジェクトをTSに書き直すことが業界内で一種の風潮になって、
この記事で敢えてTSからJSに戻そうとする事例が目新しいと思ったので、翻訳してみました。

>出処: [5 reasons why Deno will stop using TypeScript - StartFunction](https://startfunction.com/deno-will-stop-using-typescript/)
原作者: [eliorivero](https://en.gravatar.com/eliorivero)
Denoの紹介:
V8 JavaScriptエンジン及びRustプログラミング言語に基づいた、
JavaScript及びTypeScriptのランタイム環境である。Node.jsの作者であるライアン・ダールによって作成され、セキュリティと生産性に焦点を当てている。      --ウィキペディア

# DenoがTypeScriptの使用をやめる5つの理由

最近、Denoが内部コードでTypeScriptの使用を停止することを指摘する文書が浮上しました。
言及されている問題には、TypeScriptのコンパイル時間、構造化、コード編成などが含まれます。
今後、Denoは内部コードに純粋なJavaScriptを使用されるそうです。

# TypeScriptを使用するDenoの既存問題

現在、DenoチームがTypescript使用上、好ましくないと思う主な理由は以下になります。

- ファイルを変更するときのTypeScriptのコンパイル時間は数分かかるため、継続的なコンパイルは非常に遅くなります。

- 実際のDeno実行可能ファイルを作成するソースファイルで使用しているTypeScript構造と、ユーザー向けAPIがランタイムパフォーマンスの問題を引き起こしています。

- TypeScriptは、Denoコードの整理に役立ててない。それどころか、逆効果とも言える。
言及された[問題](https://github.com/denoland/deno/issues/4748)の1つは、2つの場所で重複した独立したBodyクラスになってしまったことです。

- TypeScriptコンパイラはd.tsファイルの生成に役立たないため、内部コードとランタイムTypeScript宣言は手動で同期を保つ必要があります。

- 2つのTSコンパイラホストを維持しています。
1つは内部Denoコード用で、もう1つは外部ユーザーコード用ですが、どちらも用途としては近いです。

# DenoコードからTypeScriptを削除する 

Denoチームの目的は、ビルド時の全ての内部DenoコードのTSの型チェックを外すこと。
彼らは、すべてのランタイムコードをJavaScriptファイルに移動する。
ただし、タイプ定義とドキュメントを保持するために、d.tsファイルを引き続き使用します。

Denoチームは内部のコードに対してのみ、TypeScriptの使用を停止することに言及するが、
Denoのユーザーは引き続きTypeScriptを使用できますし、タイプチェックももちろんされます。

TypeScriptはJavaScriptの改良版と見なされることもありますが、実際はそうではない。
他の言語と同じように欠陥があります、最も重要なものの1つは、コンパイル時間が遅いことです。
小さなプロジェクトでは、純粋なJavaScriptからTypeScriptに切り替えるときにコンパイル時間が大幅に増加することはないかもしれませんが、複雑な、例えばReactのような大規模なプロジェクトでは顕著になります。
ランタイムのサイズが大きいことを考えると、DenoがTypeScriptを止めるのも当然のことです。

開発中の型チェックは、コンパイル時にコストがかかります。
TypeScriptプロジェクトに、コンパイル時間に対処して改善する方法に関する多くのドキュメントがあるのはそれなりの理由があります。
最も興味深いアプローチの1つは、プロジェクト参照を使用することです。
これにより、開発者はTypeScriptの大きなコードを小さなパーツに分割できます。

# DenoがTypeScriptの使用をやめる理由についてもっと読む

TypeScriptを内部Denoコードから削除し、代わりにJavaScriptを使用するという決定についての完全な議論は、この[ドキュメント](https://docs.google.com/document/d/1_WvwHl7BXUPmoiSeD8G83JmS8ypsTPqed4Btkqkn_-4/preview?pru=AAABcrrKL5k*nQ4LS569NsRRAce2BVanXw#)にあります。
そこには、Ryan Dahlと共同研究者が、問題、その解決策、およびその実装方法について説明しています。
inputタグのボタンがレスポンシブ実装時に自動でデザイン変更されてしまう現象を防ぐ

##はじめに
HTMLなどでフォームを作る際にスマートフォンのフォームデザインが勝手に変わっていることがある。

筆者の場合、HTML, PHPを用いてフォームを作成した時、PCでは自分で考えたデザインが反映されたのに対して、スマートフォンで実機確認するとボタンのデザインが変わっていた。
##解決方法
レスポンシブで自動でデザインが反映されたタグやクラスに対して、
-webkit-appearance: none;
border-radius: 0;
二つのプロパティを付ける。

（例）ブラウザによってボタンに自動で付けられた装飾を消去する

```
<input type="submit" type="cofirm" value="送信" class="c-btn">
```
該当するクラスがあるcssファイルにプロパティを適用する。

```
.c-btn {
　-webkit-appearance: none;
　border-radius: 0;
}
```
これで、レスポンシブ実装の時に自動でデザインが変わる現象を防げる。
##P.S.
今回はこのプロパティを適用すれば防止できるよ〜という記事。
ブラウザが勝手にプロパティを付与する理由には調べている途中なので記載していません。
IBMQ実機でQAOAをやってみた　の考察

# 前回記事
参考:[IBMQ実機でQAOAをやってみる](https://qiita.com/notori48/items/854d7c95ad004a14ebe8)

3qubitのQAOA（もどき）の回路が全然動かなかった理由を探ります。
素朴に、だんだん回路を複雑にしていったときの雑音の挙動を見てみます。[^1]

## 初期回路
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/fabf92ee-7993-949d-a338-eeb6c4d83621.png)

## 最後にXゲート挿入

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/f71c1dab-97f7-e649-d96e-2319e0c64698.png)

劣化はほぼない。

## CNOTに挟まれたHゲートをu1(=任意角度のRZ)ゲートにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/88861158-5989-9e8c-f05c-a8c659bb4efc.png)

劣化が大きい。

## 最後のXゲートをu3ゲートにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/b5ac0cc8-707d-6b59-a813-6229881fe940.png)

これも劣化が大きい。

## 全部入り

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/1bae0954-8557-2766-ec33-8aad8818e13d.png)

劣化が大きいものx2　なので、崩壊した。

#結論

u1ゲート,u3ゲートはコストが高そうな気配。
いったい何ならできるんだ・・・

それ以外のゲートについては [量子ゲート実機で回路深さの限界を調べる (その2)](https://qiita.com/notori48/items/a575a889062e7bcbfbaf) とかにまとめてます。

[^1]: 本来はnative gate のレベルまでtranspile した回路を眺めて考えるべきでしょうが、今回は大雑把に。
単体テストコードでエラーメッセージすら出なかった話

こんばんは。

本日は初投稿です。
今回の内容は単体テストコードで発生してしまったあるトラブルについてです。

## WHAT

まずは下の画像をご覧ください。
![単体テストコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692330/c4f7e84b-e332-1f11-ca8d-c68d0127c50b.png)

カード情報に不備があるとき、「Token」がないとしたテストコードでエラーが発生していますね。
これは何が発生しているのかというとエラーを期待する私に対してコンピュータが「エラーなんて発生していない」と返答をしているのです。

医者と患者を例にすると患者が「私風邪っぽいです」と申告したとします。

``` 
Failure/Error: expect(@address_form.errors.full_messages).to include("Token can't be blank")
 「ウチ風邪っぽいねん」
 ```

それに対して

```
expected [] to include "Token can't be blank"
「いや健康でっせ」
```
医者は診断の結果「健康です」と返してきました。
何が原因なのでしょうか？探っていきましょう。

## WHY

まず原因として考えられるのは、
単体テストコードの記述ミス（スペルミス、構文エラー）ですが、もしもこれが正解なら
ターミナルにはsyntaxエラーという別の返答を期待しますよね。
しかし、今回の事例ではそのような記載はなかったのでこの仮説はなしです。

では何が原因か？
それはバリデーションにありました。
今回に限らず言えることとしてテストコードとは自分のかけたバリデーションがうまく機能しているのかを確かめる言わば「答え合わせ」です。 
そんな答え合わせで発生した今回の事例modelsを見に行きましょう。

```
 with_options presence: true do
     validates :user_id
     validates :item_id
     validates :street_address, format: {with:/\A[ぁ-んァ-ン一-龥々]/, message: "Can't be blank"}
     validates :postal_code, format: { with:/\A\d{3}[-]\d{4}\z/ , message: "is invalid. Include hyphen(-)" }
     validates :municipality,  format: { with: /\A[ぁ-んァ-ヶ一-龥々]+\z/, message: "is invalid"}
```

はい、Tokenにバリデーションをかけていないどころかそれすらありません。
これが原因ですね。

というわけで

```
validates :token
```

としたことで事案は解消しました。


## 結論

今回の件で学んだこととしてテストコードから返されるメッセージが空白[]の場合、
expected [] to include
バリデーションを真っ先に疑った方がいいです。
【Rails】 バッチ処理でのエラー「sudo: systemctl: command not found」

はじめに
---
今回は、とあるスクールのカリキュラムを参考に、初めてバッチ処理を実装していた時の話です。
cronを利用して削除プログラムを定時処理として実行させようとしていたところ、エラーが発生してしまいました。
自身の備忘録として、また同じようなエラーに遭遇された方の参考になればと思い投稿させて頂いております。

（参考）
・crontabコマンド
https://it-mikeiken.com/crontab-command

・CentOSのバージョン確認
https://ja.stackoverflow.com/questions/66504/centos%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%A2%BA%E8%AA%8D
<br>

開発環境
---
Ruby 2.6.3
Rails 5.2.4.4
AWS Cloud9(Amazon Linux)
<br>

エラーの内容
---
推奨されていたコマンドがこちらですが、どちらも同じエラーで弾かれてしまいます。

```terminal.
# cronが起動しているか確認するコマンド
$ sudo systemctl status crond
sudo: systemctl: command not found

# cronを起動するコマンド
$ sudo systemctl start crond
sudo: systemctl: command not found
```
<br>

解決策
---
以下のコマンドを実行することで、cronを起動、そして起動しているかを確認することが出来ました。

```terminal.
# cronが起動しているか確認するコマンド(どちらも可)
$ sudo service crond status
            or
$ sudo /etc/rc.d/init.d/crond status

# cronを起動するコマンド(どちらも可)
$ sudo service crond start
            or
$ sudo /etc/rc.d/init.d/crond start
```
<br>

エラーが起きた原因
---
``CentOS6以前とCentOS7以降からでは、コマンドが変わっている``という記事を発見しました。
そこで、自身のバージョンを確認してみようと思い、以下のようにコマンドを入力すると、「No such file or directory」、つまり「そのようなファイルやディレクトリはありません」と言われてしまいます。

```terminal.
# CentOSのバージョンを確認するコマンド
$ cat /etc/redhat-release
No such file or directory
```
この時点で、そもそもOSってなんだっけ？と思い始めたわけです。
OSについて検索をしてみると、ある記事に「システム全体を管理し、様々なアプリケーションソフトを動かすための最も基本的なソフトウェア」と定義されていました。
更に調べてみると、私が開発環境で使用しているAWSのCloud9、「Amazon Linux」もCentOS/RHEL系に分類される``Linux OS``の一つだということが分かりました。OSの一つではあるが、``CentOS``とは異なるためファイルがないと言われてしまったということです。
Amazon Linuxのバージョンを調べるコマンドも見つけたので、一応下記に掲載しておきます。

```terminal.
# Amazon Linuxのバージョン確認コマンド
$ cat /etc/system-release
Amazon Linux AMI release 2018.03
```
<br>

結論
---
今回自身の結論としましては、OSの種類が違うとコマンドが変わるということで一度納得をすることにしました。まだまだ知識不足で、これらのコマンドがどう違い、どのOSにどのコマンドが正しいかというところまでは理解することが出来ませんでしたので、今後の課題としたいと思います。
もし詳しい方がいらっしゃいましたら、ご教授いただければ嬉しく思います。
<br>

終わり
---
今回は以上になります。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になればと思っています。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
10年間使ってみて見えたHaskellの闇と光

# はじめに
わたしがHaskellを使い始めてもうそろそろ10年目になります。（タイトルは多少サバを読んでいますね）
これまで使ってきた感想をまとめます。

# Haskellのつらいところ

まずは愚痴らせてください。

## コンパイルが遅い
  - 依存モジュールはすべてソースコードからビルドする必要があります。（バイナリ形式のモジュールはありません）
  - 最初のビルドに20分くらい待つのはザラです。
  - 複雑な型システムをつかうと型推論や型レベル計算に時間がかかります。
  - 高速なHaskellプログラムを書くためには多くの関数をインライン化する必要があります。最適化ビルドではインライン展開によってコードサイズが大きくなるので時間がかかります。

## デバッグが難しい
- 公式のGHCiデバッガはありますが、今のところIDEから簡単に利用できるわけではないですし、コンパイル済みのライブラリはデバッグできないです。
- 近年スタックトレースも出せるようになりましたが、書き方を工夫しないとあまり有益な情報は得られません。
- 基本はprintfデバッグに頼ることになりますが、多相関数の引数は`Show`できないことも多くデバッグのために型制約を追加するのも面倒です。
- リソースリークやメモリリークの特定はさらに困難です。（そして割とよく起きる）

## プロファイルがとりづらい
- プロファイルを有効にするためには依存モジュールを含め再コンパイルが必要です。（シャワーをあびるか、Uber Eatsでも頼んで待ちましょう）
- プロファイル実行は通常の2-3倍遅くなります。
- プロファイルを有効化すると最適化が効かなくなって真のボトルネックがわからなくなることもあります。
- サンクが溜まっているとプロファイルはよく嘘をつきます。適切な区切りでサンクを評価しましょう。

## テストが書きにくい
- （純粋な関数のテストは書きやすいです。QuickCheckも素晴らしいと思います。）
- 関数の実装を上書きする事はできないのでテストが書きやすいように工夫して書く必要があります。

## String型が遅い
- String型はHaskell最大の設計ミスです。
- 1文字40バイト消費するので油断しているとすぐボトルネックになります。
- とりあえず`Data.Text`使っておけばまあ問題ないと思います。
  - しかし、表示したい型が`Show`しか使えないことも多くてつらいです。 

## 文字列型いくつあるんだよ
- [Haskellの文字列型：分類と特徴](https://qiita.com/mod_poppo/items/740659702f31216fdade)によると11種類あるらしいです。
- 先述のとおり、一番標準っぽさそうな`String`が一番ダメな子なのもつらいです。
- Backpack ([参考](https://matsubara0507.github.io/posts/2017-12-12-backpack-memo.html))というので解決できるそうでしたが、あんまり使われている話を聞かないですね。誰か知っていたら教えてください。

## 言語拡張が多すぎる
- みなさんの端末で`ghc --supported-languages | grep -v '^No' | wc -w`を実行してみてください。いくつになりましたか？私の手元では**125**でした。
- 使うべきもの、注意して使うべきもの、すでにレガシーとなっているものが玉石混交となっており初心者に優しくないです。
- 最後の言語仕様はHaskell2010です。流石に11年経つと実際に使われる拡張とのギャップが大きいです。
  - [GHC2021](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0380-ghc2021.rst) というのがもうすぐできるのである程度は解消される見込みです。

## 「使える」ライブラリが少ない
- それなりにライブラリは充実していますが、「使える」ライブラリかどうか判断がつきません。
- 有名ライブラリでもメンテナが少ないのでライブラリの更新スピードは遅いです。（マイナー言語の宿命ですね）

# なぜそれでもHaskellを使うのか
ここまでいろいろと愚痴を述べてきましたが、私はHaskellをこれ以上ない素晴らしい言語だと思っています。


## 実用的な言語のなかでは最強クラスの型システム
- GHCの型システムは本当に強力で、うまく型設計すればそれに導かれるように正しいプログラムをかけます。
- 複雑なデータ型も`unsafeCoerce`をほとんど使わずに表現できます。（動的型づけさえも！）
- プログラムの仕様変更も大抵は型を変更して型エラーを直せば動きます。

## 参照透明性
- 変数の値が決して変わらないという性質はプログラムをリファクタリングする際に大きな安心感を与えてくれます。
- 参照透明だからこそできる融合変換（[参考](https://qiita.com/autotaker1984/items/5ec0bbd5a44e146dbada))を使いこないしたときの万能感は格別です。

## シンプルな構文と奥深さ
- Haskellの項は本質的には関数か、パターンマッチしかありません。それ以外は全て糖衣構文です。
  - GHCのCore言語のASTでも９種類のコンストラクタしかないそうです。 ([参考](https://serokell.io/blog/haskell-to-core))
- 高階関数を使えばいかなる共通した部分をも抜き出してDRYすることができます。これはHaskell（系言語）以外ではなかなか味わえない体験です。

- 構文のシンプルさとは裏腹に毎年のように新しいプログラミング技術や言語拡張が生まれています。私の知っている範囲だけでも次のような新技術が生まれてきました。勉強をしていて飽きる事はありません。
  - ライブラリ
     - Lens
     - Free/Operational Monad
     - Functional Reactive Programming
     - Iteratee/Conduit
     - Extensible Effects
  - 言語拡張
     - TypeFamilies
     - DataKinds
     - OverloadedLabels
     - LinearTypes
     - PatternSynonyms

# これから
残念ながらHaskellがRustのような成功を収めることは今後もないでしょう。
しかし、Haskellの発展は止まる気配はありませんし、Haskellで生み出されたプログラミング技術が他の言語にも取り込まれていく事でしょう。
一生極め続けられる言語である事は自信をもって保証できます。
この記事を読んでHaskellに興味を持ってもらえる人が増えれば幸いです。
また野生のHaskellerのマサカリもお待ちしてます。
[WEB]ビュー(画面側)のコードに入れる、動的生成の構文 環境別まとめ

# はじめに
webアプリケーションの実装について、ビュー(画面側)のコードには環境毎に独自の構文を埋め込むことで、webページを動的に生成する機能があります。
しかしこの構文が環境によって微妙に異なります。
いままで色々な環境での開発を経験する中で頭の中がごちゃごちゃになりそうなので、一度種類ごとに構文をまとめてみます。

## １．JSP(Java系各種フレームワーク、サーブレット)
```jspFile.jsp
<!-- 変数の値表示 -->
<%=(変数) %>

<!-- 処理記載 -->
<% (処理をここに書く) %>

<!-- ディレクティブ(JSPの設定) -->
<%@ (文をここに書く) %>

<!-- コメント -->
<%-- コメント文字列... --%>
<% /** コメント文字列... **/ %>

<!-- EL式 -->
${式}
```
## ２．Razor = .cshtml(ASP.net系)
```razorFile.cshtml

<!-- 変数の値表示 -->
@変数

<!-- 処理記載 -->
@{ (処理をここに書く) }

<!-- 処理記載の中に、そのままHTML出力したい文字を入れる -->
@{ <text>そのままHTML出力したい文字</text> }
@: そのままHTML出力したい文字

<!-- 名前空間のインポート -->
@using 名前空間

<!-- コメント -->
@* コメント文字列... *@
<% /* コメント文字列... */ %>
<% // コメント文字列 %>
```
## ３．EJS(node.js系)
```elsFile.ejs

<!-- 変数の値表示 -->
<%=(変数) %>

<!-- 変数の値表示(変数のエスケープをしない場合) -->
<%-(変数) %>

<!-- 処理記載 -->
<% (処理をここに書く) %>

<!-- コメント -->
<%# %>

```

## 上記の共通事項

- ここであげた方法でコメントを書くと、出力されるHTMLにそのコメントは出力されません。
- いずれも画面側のファイル単体では正しい画面表示ができません。ファイルはフレームワークのプロジェクト内に入れましょう。
Railsで通知機能を作る（②既読管理編）


## やったこと
Railsでアプリを作る課題を行っています。通知機能を作りましょうというタスクがありました。
初めて作る＆覚えておくと応用が効きそうなので、以下にやり方をまとめます。

なお、実行環境は以下の通りです。

- Rails `5.2.3`
- Ruby `2.6.4`

## 仕様
以下のような仕様になっています。

- `user`がフォローされた時
- `user`の投稿した`post`にコメントがついた時
- `user`の投稿に「いいね！」がされた時

なお、基本的な機能の実装は、こちらの記事で解説しています。

[Railsで通知機能を作る（①基本機能編）](https://qiita.com/tanutanu/items/479cb14cfea77c7429bd)

## DB設計
DB設計はこちらの通りです。
[![Image from Gyazo](https://i.gyazo.com/d7161965ac2a7b28150940fd8f4ceabc.png)](https://gyazo.com/d7161965ac2a7b28150940fd8f4ceabc)

`activities`テーブルの`read`カラムで既読の管理をしていますが、それ以外のDB設計の詳細については、先の「[①基本機能編](https://qiita.com/tanutanu/items/479cb14cfea77c7429bd)」の記事と、こちらの記事を参照してください。

## Routing

今回、既読管理は`read`というメソッドを`activity`コントローラー下に作って実装します。そのため、ルーティングを下記のように実装します。

```ruby:config/routes.rb
resources :activities, only: [] do
  patch :read, on: :member
end
```

`only: []`なんて書き方は初めて見ましたが、Railsの基本の７アクションがなくて、かつオリジナルのメソッドだけある時は、これで書けるようです。知らなかった。

## Model

続いてモデルです。モデルには、`enum`で`read`と`unread`を定義します。

```ruby:models/activity.rb
enum read: {
  unread: false,
  read: true,
}
```
enumって、boolean型にも使えるのですね。`true`と`false`にそれぞれ別の名前がつけられて、文脈がわかりやすくなりますね。

また、モデルには以下のようなメソッドも定義しました。

```ruby:models/activity.rb
def transition_path
  case action_type.to_sym
  when :commented_to_own_post
    post_path(subject.post, anchor: "js-comment-#{subject.id}")
  when :liked_to_own_post
    post_path(subject.post)
  when :followed_me
    user_path(subject.follower)
  end
end
```

こちらは、この後すぐ利用します＾＾

## Controller
controllerの`read`メソッドはこのように実装します。

```Ruby:controllers/activities_controller.rb
class ActivitiesController < ApplicationController
  # beforeフィルターなどは省略

  def read
    activity = current_user.activities.find(params[:id])
    activity.read! if activity.unread?
    redirect_to activity.transition_path
  end
end
```
`read`メソッドが実行されたら、`read`カラムの中身が`false(unread)`の時に、`read`にして、先に設定した`transition_path`に遷移する仕組みです。

## 仕上げ＆完成
あとは、詳細省きますが、Viewでは既読の時だけ色が変わるように設定して...。

[![Image from Gyazo](https://i.gyazo.com/ec3f58b796e7b93dc41c1ff8ff5ba191.gif)](https://gyazo.com/ec3f58b796e7b93dc41c1ff8ff5ba191)

クリックすると色が変わり、ビジュアルに既読管理ができるようになりました。

最終的には、こちらに「未読の件数」表示のバッジをつけて完成しましたが、以上で、既読管理の完成です。

## まとめ
初めは、実装についてあまりイメージのついていなかった「通知」機能ですが、

- 「通知」テーブルを別途作る
- 通知対象のアクションが行われたら、「通知」レコードを一つ作る
- 通知を確認するためのリンクを設定し、リンクをクリックしたらステータスを「既読」にする

というのが大まかなポイントなのかなと思いました。
[ポリモーフィック関連付け](https://qiita.com/tanutanu/items/726e7097c6ca4a9ca6e3)については、使い所をもう少し抽象的に理解したいです。

それでは、引き続き頑張っていきます。
今迄の学習内容1

上のタグにもありますように、最初に取り組んだのがPCの基礎知識と、Linux基本というか基礎でした。

Web上での検索結果以外でのPCの基礎知識に関しては、

<li>IT用語図鑑 ビジネスで使える厳選キーワード256（翔泳社）</li>

<li>ビジュアル版 コンピュータ&テクノロジー解体新書（SB Creative）</li>

<li>決定版 コンピュータサイエンス図鑑（創元社）</li>

Linux及びUNIXに関しての参考資料は、

<li>ゼロからわかるUNIX基礎講座 はじめてでも安心して学べる（技術評論社）</li>

<li>Linux標準教科書（2018-05-07 版 LPI-Japan  発行）</li> 

<li>新しいLinuxの教科書（SB Creative）</li>

が、実際に読んだ事のあるものです。

用語集や手許にあるが未だまともに読み始めていない資料等は挙げていません。

本当に初心者の方がこの記事をどれだけ見られるかは分かりませんが、参考になれば。
Top画面でヘッダーとフッターしか表示されない　rails備忘録



備忘録として、、、

初歩的なことですが、、


```application.html

<body>
    <%= render 'layouts/header' %>
      <main>
        <p id="notice"><%= notice %></p>
      </main>
    <%= render 'layouts/footer' %>

``````
これだけだと、トップページが呼び出されていないため
<%= render 'layouts/header' %>
<%= render 'layouts/footer' %>しか反映されない

そこで
<%= yield %>（渡されているブロックと同じ働きをするメソッドのようなものだそうで）
を記述すると

```application.html

<body>
    <%= render 'layouts/header' %>
      <main>
        <p id="notice"><%= notice %></p>
　　　　　<%= yield %>
      </main>
    <%= render 'layouts/footer' %>

``````

無事反映されました！
CSSでテキストを浮かせたり、グラデーションをかける方法

# はじめに
文字をサクッとデコレーションしたいなというときに役立つ方法をいくつか調べたのでまとめてみました。

# テキストにグラデーションをかける方法
仕組みとしては背景色にグラデーションを指定し、テキストでくり抜くというものです。
HTML

```erb
<h1>グラデーション</h1>
```
CSS

```css
h1{
  color: #ACB6E5;//非対応のブラウザでの文字色を設定
  background: -webkit-linear-gradient(0deg, #ACB6E5, #86FDE8);//背景色にグラデーションを指定
  -webkit-background-clip: text;//テキストでくり抜く
  -webkit-text-fill-color: transparent;//くり抜いた部分は背景を表示
}
```
ブラウザが非対応だった時のため、文字の色を指定しておきます。


ちなみにゴールドにしたいときはこのようにします。
とてもゴージャスになります！！

```css
h1{
  color: #DA8E00;
  background: -webkit-linear-gradient(-45deg, #F7DE05, #DA8E00, #EDAC06, #F7DE05, #ECB802, #DAAF08, #B67B03, #DA8E00, #EDAC06, #F7DE05, #ECB802, #EDAC06);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
```

# 浮き上がった文字
４方向に影をつけることで文字を作成できます。

```erb
<div class="sample1oya">
  <span class="sample1">浮いた文字</span>
</div>
```
```css
.sample1oya{
  background  : #ffffff;
  padding     : 20px;
}
.sample1{
  display     : inline-block;
  font-size   : 160%;
  font-weight : bold;
  color       : #ffffff;
  text-shadow:  2px  2px 10px #777 ,
               -2px  2px 10px #777 ,
                2px -2px 10px #777 ,
               -2px -2px 10px #777;
}
```

# 動く影
animationを使うと影を動かすこともできます。

```erb
<div class="sample2oya">
  <span class="sample2">影が変化する</span>
</div>
```

```css
.sample2oya{
  background : #fff;
  padding    : 20px;
}
.sample2{
  display    : inline-block;
  font-size  : 160%;
  font-weight: bold;
  color      : #fff;
  animation  : sample2Anime 4s linear infinite alternate;
}
@keyframes sample2Anime{
   0% { text-shadow:  2px  2px 10px #fff ,
                     -2px  2px 10px #fff ,
                      2px -2px 10px #fff ,
                     -2px -2px 10px #fff;}
 100% { text-shadow:  2px  2px 10px #777 ,
                     -2px  2px 10px #777 ,
                      2px -2px 10px #777 ,
                     -2px -2px 10px #777;}
}
```

# インライン
htmlで下線を直接引く方法です。

```erb
<span style="text-decoration: underline">例文です</span>
```

# 終わり
以上簡単なデコレーション方法でした。
A server is already running. 対処方法

<h1>前提条件</h1>

・ruby 2.6.6
・Rails 6.0.3.2
・macOS Catalina バージョン10.15.7


<h1>概要</h1>
 ローカル環境でrails sを走らせようとしたが
"A server is already running"
というエラーが発生した。その対処法を記述する。

<h2>１.再起動をする</h2>
ターミナルを全て閉じ再起動する。
これで解決する場合もあるみたい。私はやったことはない。

<h2>2.tmp/pids/server.pid.を削除する</h2>
私はこの方法で毎回解決している。
ターミナルで"A server is already running"の後に
Check /Users/・・・・/tmp/pids/server.pid.
と出ている。
サーバーを落とす際にこのファイルが消されるはずなのだが、何らかの不具合で
消されていない状況が発生するようだ。
Finderからアクセスし、直接"server.pid."を削除
これで解決。
爆速でTypeScriptの環境構築できるgts使ってみた

## gts とは

Google の TypeScript コーディングスタイルガイドです.
 TypeScript や Eslint, Prettierなど の環境構築や設定などをコマンド一発でやってくれます.

## 導入

```shell

> npx gtx init
> yarn install (or npm install)
```
だけです, めっちゃ楽ですね.

## npm スクリプト

導入した時点で作成されたスクリプトは以下です.

```json

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "lint": "gts lint",
    "clean": "gts clean",
    "compile": "tsc",
    "fix": "gts fix",
    "prepare": "npm run compile",
    "pretest": "npm run compile",
    "posttest": "npm run lint"
  },
```
コンパイルの環境も構築してくれるみたいですね.

## 実行

```shell
> yarn lint
```
コードフォーマットの確認をしてくれます.
問題があればいつものようにwarningが出ます.

<br>

```shell
> yarn fix
```
コードフォーマットの上書き修正をしてくれます.
<br>

```shell

> yarn compile
```
 `src` 以下のファイルを `build` 以下にコンパイルしてくれます.
<br>

```shell

> yarn clean
> yarn pretest
> yarn postest
> yarn prepare
```
`build` 以下の削除, テストなどをしてくれます.

## 使ってみた感想

Lintツール独特の面倒な設定などを一発でやってくれるのはとてもありがたいですね.小さいプロジェクトなどで活用できればいいなと思います.めっちゃ楽！わかりやすい！ですね.
## 参考

[gts - npm](https://www.npmjs.com/package/gts)
LCSCのEasyEDA ModelのフットプリントをKicadで使う方法

【2024/07/09追記】
Free trialで開くEasyEDAがstandardからProになって、ExportがAltiumのみになってしまい、下記の方法が使えなくなってしまいました。何か良い方法があったら、コメントにお願いします。
---

## はじめに
CADで基板を作っていると手間がかかるのが、部品ごとのフットプリントの作成。難しい作業ではないですが、単調で間違えられないのできれば避けたい作業です。また、データシートに寸法が載っていなかったりすると購入してから実寸を測る必要があるなど、手間がかかる作業です。

部品を”みんな大好き[LCSC](https://lcsc.com/)”で探す事が多いのですが、部品ページにEasyEDA Modelというリンクがあり、クリックしてみるとCAD図らしき物が表示されます。

あれ？これをそのまま使えればいいのでは？？と思って調べたのですが、日本語で情報をまとめたところが無かったので、ここにまとめておきます。

## やってみる

フットプリントを使いたい部品ページの「EasyEDA Model」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/0b9f8e68-6a49-951c-a004-4ffda26ba9c1.png)

「Free Trial」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/a88a8d7e-e0b6-24b5-bff5-573249a7e951.png)

フットプリントが表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/ecccb521-f0c1-120f-ae1f-91dcdd45df60.png)

「ファイル」→「エクスポート」→「EasyEDA...」をクリックしてファイルをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/f37051d4-0476-bf1e-1f64-d926bf6e9d82.png)

[WOKWI](https://wokwi.com/easyeda2kicad)を開き、先ほどダウンロードしたファイルをLoadします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/10924df4-16ae-e499-bef9-3b128c749262.png)

変換されたファイルをダウンロードしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/e6afd3e3-8142-4b8e-59b1-74b320900c32.png)

ダウンロードしたファイルをKicadのPcbnewで開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/78732916-c260-10ef-3045-5a5956ebe906.png)

表示されたパーツを選択し、「右クリック」→「フットプリント エディターで開く」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/12953560-f961-5a5f-17e4-79adc745201f.png)

フットプリントはこの時点で修正します。意図しないピン番号になっていたり、たまに間違っている事があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/d790008c-2099-f1d6-47cb-9732c9b1e63e.png)

「編集」→「フットプリントのプロパティ」を開き、リファレンスと定数をちゃんと直しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/2dad0824-e66e-316f-7b04-c92ba666ff57.png)

「ファイル」→「名前を付けて保存」で自分のライブラリを選択して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128436/09e59cb6-92fb-9a27-24f2-a9492a889ba0.png)

これで、自分のライブラリとして使えるようになりました。
CloudFrontで公開したSPAでページ遷移を行う時に、４０３エラーが返ってくる時の対処法

CloudFrontにてVue.jsで作成したSPAを公開して``window.loaction``などでページ遷移を行うと以下のようなエラーが起きました。

```
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>xxx</RequestId>
  <HostId>xxx</HostId>
</Error>
```

S3やCloudFrontでおなじみのエラーです。

ただ、今回のエラーはホーム画面は表示されるのにページ移動したら急にこのようなエラーが起きました。

また、``this.$router``などでページ遷移を行う時にはしっかりとページが表示されました。

``this.$router``ではページが表示される当たり、恐らくページを再描画するとどこか違うファイルを参照してしまうためこのようなエラーが起きているんだと思います。

何はともあれ、CloudFrontで次のように設定をしてあげるとこのエラーは解消されます。

「CloudFront」→「Error Pages」のタブを開いて「Create Custom Error Pages」をクリックしてください。

|HTTP Error Code|403: Forbidden|
|---|---|
|Error Caching Minimum TTL|0|
|Customize Error Response|Yes|
|Response Page Path|/|
|HTTP Response Code|200: OK|

無事ページを再描画してもページが表示されるようになりました！

以上、「CloudFrontで公開したSPAでページ遷移を行う時に、４０３エラーが返ってくる時の対処法」でした！

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

あと、最近「ココナラ」で環境構築のお手伝いをするサービスを始めました。

気になる方はぜひ一度ご相談ください！

Thank you for reading
LastPass CSV Exportの注意点 (Form Fields, Attachmentは出力されない)




# LastPass CSVエクスポートの注意点 
LastPassでCSVエクスポートすると、Form FieldsやAttachment(添付ファイル)はExportされません。


# Form FieldsやAttachmentの取り出し
lastpass-cliを利用すると、Form Fieldsの取り出しや、Attachmentが含まれたアイテムの確認ができます。
https://github.com/lastpass/lastpass-cli


# lastpass-cliのインストール
- 下記に記載の通りです。  
https://github.com/lastpass/lastpass-cli

- Ubuntu 20.04.1 LTS@WSL2 では、`sudo apt-get install -y lastpass-cli`だけでインストールできました。


# lastpass-cliでの操作

```
# lastpassへのログイン
lpass login USERNAME(email address)

# Item一覧の出力(アイテム名と、アイテムのUNIQUEIDが表示されます。)
lpass ls

# アイテム毎の出力
lpass show アイテムのUNIQUEID
```

## Form Fieldの場合
下記実行例のように、`custom_field01: test-value`という形で表示されます。

```
$ lpass show  1234567890
Sample-item [id: 1234567890]
Username: sample@gmail.com
URL: https://mail.google.com/mail/u/0/?hl=ja#inbox
custom_field01: test-value
````

## Attachmentの場合
下記実行例のように、`att-`で始まる行が出力されます。

```
$ lpass show  9876543210
test [id: 9876543210]
URL: http://sn
att-9876543210-12345: sample-attachment.png
Notes: SampleNotes
```

この方法では、有無の確認までで、出力はWebから行うか、下記のようなツールの利用を検討してください。（私は、lastpass-attachment-exporterためしていません。）
https://github.com/mindrunner/lastpass-attachment-exporter


# その他
- アイテムにマスターパスワードの再入力を有効にしている場合、`lpass show ****`でも入力を求められます。一括して外す方法は未確認です。私の場合、たくさんなかったので、`lpass show`でマスターパスワードが求められたら、都度Webから再入力を解除しました。
Boolean型の記述方法について

orangeを2倍にした数がappleの数以上であった場合にのみ
trueを返しそれ以外はfalseを返したい時、以下のように記述できる。

```
def fruit(apple, orrange)
  orrange * 2 <= apple
end
```

このような書き方は冗長になる。

```
def fruit(apple, orange)
  if orange*2 <= apple
    true
  else
    false
  end
end
```
Google Sheet API(Node.js利用)で、複数シートを順番に生成できずハマったので、解決コードを晒してみる

Google Sheet API(Node.js利用)で、複数のシートを「1,2,3,4...」と並べて生成したいのに、
async,awaitで生成しても、シートが2,4,3,1みたいに順不同になってしまうのを、
どう回避できるかなかなかわかりませんでした。

辿り着いた解決策は、
array.reduceとPromiseを組み合わせて、thenでつないでいき、
Promise内でsetTimeoutをする、というものでした。

[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)に慣れていなかったので、
各引数の理解（特に第1とinitialValue)と、thenの理解、
また、初期値にPromice.resolve()を渡すあたりが難しかったです。

以下、実際に動くようになったコードです。
（SheetAPIのラッパークラスを自作していますので、よしなに読み替えてください）

```js
import {Sheet} from './Sheet.mjs'//シート関連の処理を集めた自作クラス
import dotenv from 'dotenv'
dotenv.config()

const spreadsheetId = process.env.SOME_SPREADSHEET_ID

/**
 * 複数のシートを順番に作成する
 */
const main = async function() {
  const sheet = await Sheet.build()//auth取得などはここで処理している
  //複数シート作成のため連番を準備（スプレッド構文便利ね）
  const arr = [...(Array(10).keys())].slice(1)//0は排除

  //関数の中でPromiseオブジェクトを返す無名関数を準備。これをarr.reduceで逐次実行する
  const createWithSleep = (sheetName) => {
    return () => {//ここで無名関数化してPromiseを返すのがreduce.then実行のキモ。無いと動かなかった
      return new Promise(resolve => {
        setTimeout(()=>{
          createSheet(sheetName, sheet)//シート生成メソッド呼び出し
          resolve()//resolve()でreduce内のthenが発火
        }, 2000)//thenで実行していても、一定の時間差がシート順次生成に必要!500などではだめだった
      })
    }
  }

  //ここのarr.reduceでの逐次実行がとても重要！これがないとシートの生成が順不同になる(thenでの処理実行チェーン)
  //シート名は's2'などでは読み取りなどのAPI実行時にカラム名と間違えられ困ったので、'組'というダブルバイトにしている
  arr.reduce((pre, cur) => pre.then(createWithSleep('組' + cur)), 
    Promise.resolve())//最初にthenを発火させるために空のPromise.resolve()をinitialValueとして配置
}

//シートの生成部分. setTimeoutで十分時間をとっているのでasync,awaitは設定せず
const createSheet = (sheetName, sheet) => {
  //ここのcreateSheetは普通のAPIメソッドの単なるラッパーです
  sheet.createSheet(sheetName, spreadsheetId).then(() => console.log('created'))
}

main()
```

Google Sheet APIは、サクッとspreadsheetを作れたり、値を書き込んだり読み込んだり、
sheetを作成したり、超便利ですね。
nodeでローカルから楽しく操作できるのが気に入りましたが、
ちょいちょい書き方に詰まったので、同じところで詰まった方に役に立てばと、
恥を忍んでコードを晒してみます。

どなたかのお役に立てば幸いにて。
ではでは。
Node.jsでjQueryを使う方法

現在、jueryとNode.jsを勉強しています。
それぞれ別々にしていましたが、同じアプリケーションに２つとも入れれば効率いいんじゃない？と思いやってみました。

# 実践
```java:top.ejs

<head>
//省略
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<head>
```

```:ターミナル
$ npm install express ejs
```

```app.js
const express = require('express');
const app = express();
app.use(express.static('public'));

//以下省略
```

```public/script.js
$(function(){
//行いたい処理(jQueryの内容)
});
```

これでjQueryが使えるようになります。

注意としては`top.ejs`での
`<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>`
と
`<script type="text/javascript" src="script.js"></script>`
の記述は逆にしてしまうと読み込めなくなります。
必ずこの順番で記述することです。

そして、`app.js`で`app.use(express.static('public'));`
で`public`ディレクトリから読み込んでいるので、必ず
`public`ディレクトリを作り、`public`ディレクトリ配下に`script.js`を作成してください。
そうしないと`script.js`が読み込めません。

# もしかすると？
最初は`$ npm install jquery`で読み込ませようとして失敗し、今に至ります。
もし、上記の記述をやってもjQueryが読み込めない場合は、
`$ npm install jquery`
をやってみてください。

# 終わりに
結構な時間悩んだ割には簡単な記述で終わりました。

# 追記
必要な記述が１つ抜けていたので修正しました。
Finderでファイルサイズを棒グラフ表示する

Finderの表示では、個々のファイルの大きさが直感的にとらえられない。サイズでソートすると今度はどのファイルが新しいのかがわからない。そこで、ファイルサイズをComment欄に棒グラフで表示するだけのスクリプトを作った。

The Finder's display does not intuitively capture the size of individual files. If you sort by size, you can't tell which file is newer. So I made a script that just displays the file size as a bar graph in the comment column.

```bash
#!/bin/bash

function sizebar_ () {
    filepth="$1"
    comment=$(mdls -r -nullMarker "" -n kMDItemFinderComment "$filepth" | sed -e 's:|*::' )
    size=$(du -s "$filepth" | awk '{s=int(log($1)/log(2));for(i=0;i<s;i++)printf("|")}')

    newcomm=$size$comment
    /usr/bin/osascript -e "set filepath to POSIX file \"$filepth\"" \
    -e "set the_File to filepath as alias" \
    -e "tell application \"Finder\" to set the comment of the_File to \"$newcomm\""
}

# escape spaces in the file name
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in *
do
    sizebar_ "$f"
done
IFS=$SAVEIFS
```

スクリプトを実行したディレクトリの全ファイルに、対数目盛の棒グラフが付加される。

A bar graph in log scale will be added to the commend fields of all files in the directory where the script was executed.
![ScreenShot](https://i.gyazo.com/912eb9a0d5bade4eb1e424c2d82d3571.png)
（C#）配列の宣言時、要素数を変数で指定する方法。

C#はマクロ定義ができないそうですね。

同じ要素数の配列を何度も宣言したいと思い、変数名を要素数に入力してみたんですがうまくいきませんでした。

```
int maxObjectNum = 10;
Object[] Objects = new Object[maxObjectNum];
```

上のように変数で指定するとエラーですが、

```
const int maxObjectNum = 10;
Object[] Objects = new Object[maxObjectNum];
```

このように定数にするといけるみたいです。
（"変数で指定する方法"ではないですね、ごめんなさい）
PythonでFizzBuzz

Pythonの学習を始めた　備忘録

###コード
```Python
for i in range(1,31):
    if i%3==0 and i%5==0:
        print("FizzBuzz")
    elif i%3==0:
        print("Fizz")
    elif i%5==0:
        print("Buzz")
    else:
        print(i)
```

###出力
```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
```

###余談

[Python超入門コース 合併版｜Pythonの超基本的な部分をたった1時間で学べます【プログラミング初心者向け入門講座】](https://www.youtube.com/watch?v=HyU3XL2F9GE)

最初の一歩として上の動画を眺めた

FizzBuzzという問題の存在は知っていたので書いた
for文とif文の理解を試せてよかった

ところで、この出力結果は空間が余って嫌なので、横にカンマかなんかで区切って表示させたい　あとでやる
初心者がAWSとJavaでHello Worldレベルの何かがしたい

<h1>
背景
</h1>
会社の査定目標でJavaとAWSで何か作成します！と記入したものの先延ばしにしている内に結局
何も作れず査定日に近づいてしまったので、もうHello Worldレベルでもいいので何か
しなくてはということで取り組みました(実は提出義務はないので正直に作る必要も
本当はないのですが)。
作るの簡単だけど何か頑張ってそうに見えるAWS×Javaの成果物アイデアが別に何かあればぜひ
お教えください。非常に喜びます！

<h1>
概要
</h1>
AWSコンソールのLambda上から、maven projectをpackage化したJarファイルを起動します。

<h1>
①Mavenプロジェクトの作成
</h1>
Eclipse上で適当にMaven Projectを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/5d0deff4-37ea-48e3-cf90-138d7782a6f4.png)

<h1>
②Lambdaの実行対象であるJavaクラスを作成 
</h1>
これもシンプルに作成します。argはLambdaから渡される引数です。

```
package qiitaLambda;

public class Qiita {
	public static String handleRequest(String arg) {
   	 return arg + "20210301";
    }
}
```
<h1>
③Jarファイルを作成する
</h1>
プロジェクト名を右クリック→実行(R)→Mavenビルドで設定画面を開き、設定画面上でゴール(G)にpackageと入力し実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/d3f14a81-cb54-b206-6e30-3eb2f4092709.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/a0492083-36b7-5e44-9877-e32d282d26f7.png)

<h1>
④AWS Lambdaコンソール上で関数を作成する。
</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/bbf4c5fc-af47-a8cc-cbf7-5bf26c0af0e8.png)

<h1>
⑤Jarファイルをアップロードする
</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/4fea6f20-6202-c7bb-b9d9-d0f0393f0226.png)

<h1>
⑥ランタイム設定を行う
</h1>
ハンドラを{package名}.{クラス名}::{メソッド名}に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/f9407ae1-da64-1bbc-5590-40edf53ddf01.png)

<h1>
⑦テスト設定をする
</h1>
画面右上のテストを押下すると設定画面が出るのでイベント名とその内容を書きます。ここではシンプルに文字列のHelloを記載し、これが②の関数のargに渡されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/42a66ff5-922c-a28f-df54-12a7dc44f183.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/7f8075e9-d7bf-cfcb-8de3-6e0a35625deb.png)

<h1>
⑧テストをする
</h1>
もう一度画面右上のテストを押下するとLambda関数が実行されます。実行結果を見ると⑦のようにLambdaで記述したHelloとあらかじめ②のJavaクラスで記述していた日付を結合して表示しているのでJarファイルを呼べていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/0c41b9b3-8e42-4812-9be6-1f907c2f8cdd.png)

<h1>
感想
</h1>
背景でも述べさせていただきましたが、作るのは簡単だけど何か頑張ってそうに見えるAWS×Javaの成果物アイデアが別に何かあればぜひぜひお教え下さい！
mysqldumpの結果をimportするときに進捗率を知りたい


以下のようにpvコマンドを使うとどれくらいの進捗か分かるので便利。


```
 pv < dump_result.gz | zcat | mysql -u root database_name -p

 145MiB 0:05:38 [ 776kiB/s] [===========================================>  
                                                     ] 45% ETA 0:06:45 ] 43% ETA 0:07:07                         ] 42% ETA 0:07:09
```
C#のArrayもList<T>と同じ様に扱いたい

## はじめに

最近はコレクションを処理するのに、LINQばかり使っているので、`Array`のメソッドを呼び出すことはあまりないのだけれど、稀に`Array`のメソッドを呼び出したい時があります。

でも、

```cs
var items = new[] { 5, 3, 7, 9, 1, 4 };
Array.ForEach(items, Console.WriteLine);
```

て書くのはなんかイヤです。やっぱり、

```cs
var items = new[] { 5, 3, 7, 9, 1, 4 };
items.ForEach(Console.WriteLine);
```

って書きたいです。

## 拡張メソッドを定義しよう

そんな時は拡張メソッドの出番です。以下の様な拡張メソッドを定義することで、`Array`のメソッドも`List<T>`と同じ様な感覚でコードを書くことができます。

```cs
public static class ArrayExtensions
{
	public static void ForEach<T>(this T[] array, Action<T> action)
	{
		Array.ForEach(array, action);
	}

	public static void Sort<T>(this T[] array) where T : IComparable<T>
	{
		Array.Sort(array);
	}
}
```

ArrayExtensionsが定義されている名前空間をusingすれば、以下の様な記述が可能になります。

```cs
var items = new[] { 5, 3, 7, 9, 1, 4 };
items.Sort();
items.ForEach(Console.WriteLine);
```

結果は以下の通り。

```
1
3
4
5
7
9
```

IndexOfやFindAllなどのメソッドも同様に拡張メソッドにすれば使い勝手もよくなります。

## おわりに

まあ、LINQあるのでこういった拡張メソッドを書く必要性もあまり無いんですけどね。

昔書いたブログ記事を読み直していて、拡張メソッドで遊んでいたことを懐かしく思い出したので、こんな記事を書いてみました。
【Swift】ライブラリ "Material Components" の MDCOutlinedTextField を使ったTextField実装

# これはなに

マテリアルデザインのUIが簡単に実装できる **Material Components** を使ってこんな感じのTextFieldを作りたい。

![8e206d4c9234c0106c809d47f2c61e79.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/f68218cb-f1b3-7655-2664-9a7e1d06dbc0.gif)

Material Componentsのインストール方法は省く。

## 実装してみる

![41c5ba946265cc8c685e8ffddb57348a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/9b6624a4-c400-593e-ac11-8c6c2a97dd0c.png)

StryboardのTextFieldを選択して `MDCOutlinedTextField` を設定する。
そしたらControllerにつなぐ。

```swift:LoginViewController.swift
class LoginViewController: UIViewController {

    // ユーザ名入力欄
    @IBOutlet weak var userNameTextField: MDCOutlinedTextField!

// 中略
```

TextFieldのプロパティを設定していく。

```swift:LoginViewController.swift
override func viewDidLoad() {
        super.viewDidLoad()

        userIdTextField.label.text = "ユーザーなまえ"
        userIdTextField.placeholder = "なまえをいれなさい"
                
        // TextFieldが選択されていない状態の枠と文字の色
        userIdTextField.setOutlineColor(.gray, for: .normal)
        userIdTextField.setFloatingLabelColor(.gray, for: .normal)
        
        // 編集中の枠と文字の色
        userIdTextField.setOutlineColor(.blue, for: .editing)
        userIdTextField.setFloatingLabelColor(.blue, for: .editing)
}
```

これで上記の動画のようなTextField実装できる。

## 問題点

――が、ここまではドキュメントを読めば書いてあったんだけど、 `userIdTextField.label.text` の部分、つまりここでいう『**ユーザーなまえ**』の部分の色を変える方法がなかなか見つからなかった（`userIdTextField.label.textColor` ではダメだった）。

## 解決策

```swift
userIdTextField.setNormalLabelColor(.gray, for: .normal)
```

![29aef63b5023ea9509543814b6e11ab7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/039b44c2-788e-45d0-947e-7e207fddb62e.png)

ハー、できてよかった( ；∀；)
Big Query のテーブルのメタ情報の取得方法


# データセットのメタ情報を取得する
いきなり上司から「BigQueryで解析してくれ」と丸投げされた時にサクサク進めるためのTipsを作成する。
## ①.INFORMATION_SCHEMA.COLUMNSでカラム一覧取得
以下を打つだけでデータセット配下に存在するテーブル、カラムの一覧、その他のメタ情報を取得することができる。
SELECTコマンドで網羅的に取得するため、データセットのサイズがあまりにも大きい時にこれで取ってきたデータを元にカラムを参照するのが良いだろう。
https://cloud.google.com/bigquery/docs/information-schema-tables?hl=ja#columns_view

```sql
SELECT
    *
FROM
    `project.dataset.INFORMATION_SCHEMA.COLUMNS`
```


さあ！解析を始めよう
【Swift5】Timerを変数に保存しないでinvalidateする

結論から言えばそんなに大したことない話なんですけど、意外と使うので備忘録としてアウトプット。

# とっても便利なTimer

アプリを作るときには、何かしらの処理でほぼ必ず使うであろうTimer。
Swiftにも使いやすいTimer関数が用意されています。

```swift:ViewController.swift
class ViewController: UIViewController {

  var timer: Timer = Timer()
  var count: Int = 0

  override func viewDidLoad() {
        super.viewDidLoad()

        // １秒毎にup()を実行
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.up), userInfo: nil, repeats: false)
  }

  @objc func up() {
        // 60秒経ったらタイマーを止める
        if count > 60 {
            timer.invalidate()
        } else {
            count += 1
        }
  }

}
```

こんな感じで変数にタイマーを保存して、後から`.invalidate()`してタイマーをストップ＆破棄するのが基本的な使い方です。


# 毎回変数に入れるのだるくない？

ストップウォッチ的な奴は別ですが、上のサンプルみたいに「**x秒後に一回処理を実行する**」みたいなパターンではすぐにタイマーを破棄することになるのでいちいち変数に入れるのはめんどくさいですよね。
しかもタイマーの数が増えていく場合には変数を追加していかなければならない。

そこでタイマーを変数に入れなくても止める（invalidate()する）ことにしました。


# 引数に自分自身を入れちゃおう
``````swift:ViewController.swift
class ViewController: UIViewController {
        // 30秒後に止まるタイマー
        func setTimer() {
            Timer.scheduledTimer(timeInterval: 30, // x秒後
                                 target: self,
                                 selector: #selector(self.stopTimer(_:)), // 引数にTimer自身を指定する
                                 userInfo: nil, 
                                 repeats: false)
            print("Timer started")
        }

        @objc func stopTimer(_ timer: Timer) {
            timer.invalidate()
            print("Timer stopped")
        }
}
```

このように`selector`で関数を指定するときに引数を自分自身にすることで、変数にTimerのインスタンスを保持しなくてもあとで`.invalidate()`することができます。


# おしまい
Timerはメモリを圧迫するので、不要になったら必ず`.invalidate()`しよう。
OracleWER解説

# TL;DR
OracleWER = 「確信度を考慮せずに,ラティス内から正解文に一番近い」予測文を選択した場合のWER

# 記事を書こうと思った経緯
Googleが2015年に発表した有名論文であるAttention機構を用いた音声認識モデル[Listen, Attend and Spell](https://arxiv.org/abs/1508.01211)を読んでいた所、第4章Experimentsの項でいきなり知らないOracleWERという単語が説明なしで出現し、以降何度も(図中にすら)出現するため理解が必要だが、日本語での解説記事がなかったため、同じような境遇に陥った人に情報を残そうと思った。

# 事前知識
### WERとは
以下の式で表される、予測文が正解文にどれくらい近いかを表す評価指標、低ければ低いほど性能が良いと言える。

![WER](https://wikimedia.org/api/rest_v1/media/math/render/svg/7db6226f0c365982b94f221d68530bf8a6a50611)
S(substitutions) :置換語数D
D(deletions) :削除語数
I(insertions) :挿入語数 
C(correct words) :正解語数 
N :総単語数, N=S+D+C

### ビームサーチ
NLPタスクでは,以下のように推論結果をラティス構造で生成し、文全体での確信度スコアが一番高いパスを出力として選定する。(図で言うと出力推論文は"practice, he had")
<img src="https://ichi.pro/assets/images/max/724/1*Dqw1Y7zDcxKOBvsl_bbtog.png" width=70%>
この時、注意すべきなのは選ばれるパス出力は、文としての確信度スコアが一番高いものというだけで必ずしもそのパスがWERスコアが最も良いものだとは限らない。(推論時には答えのデータは与えられないため当然といえば当然)

# OracleWER
上記のように通常WERの計算というものは、確信度スコアが最も高いパスを出力としてその推論文章と正解文を比較して精度算出を行う。
これに対し、OracleWERは全ラティスパスの中でWERスコアが最も高くなるようなパスを出力としてそれと正解文とを比較し精度算出を行う指標である。

上の例で言うと、
正解文: **"practice, good deal"**
の時、通常のWER計算では、出力推論文は最も確信度の高いパスである
**"practice, he had"** となるので
WER=2/3=**0.66** となるが、

OracleWERの場合は、出力推論文は
「確信度に関係なく、正解文に最も近いパスを選ぶ」ので、出力推論文は
**"practice, great deal"** となり
WER=1/3=**0.33**となる

## 何故こんな指標を用意して評価したのか
WERは単にモデルの性能評価のために使われるのに対して、OracleWERはビームラティス内に正解に近い仮説(各ラティスパスで生成される文章)がどれくらい含まれているのかどうか（＝仮説のバリエーションの多さ）を評価するために導入されている。
仮にWERで見た場合に、同じスコアのモデルがあったとしても、ビーム仮説が多様性に富んでいるかどうかがOracleWERによって評価できるため、本論文ではこのような指標での評価も行っている。

# 最後に
様々な記事や文献を当たって書いている記事ですので、間違いがあればコメント等でご連絡お願いいたします。
一人でも論文を読んでいて詰まった人の助けになれれば幸いです。
BigQueryで他のユーザの実行クエリを見る

自分の実行したクエリは簡単に参照することができますが、他のユーザが実行したクエリを参照するにどうするかをみていきます。

まず、クエリを参照するためには、権限と方法の2つが重要です。

# クエリ・ジョブの実行履歴をみるための権限

権限については、以下の権限がクエリの実行履歴をみる操作に関係するものになります。

- bigquery.jobs.list : 自分のジョブが見れる
- bigquery.jobs.listAll : 全てのユーザのジョブが見れる

BigQueryの権限周りの基本は[こちら](https://cloud.google.com/bigquery/docs/access-control?hl=ja)を参照のこと。

Google Cloudでは、これらの権限を権限をまとめたロールとしてユーザアカウントに付与します。先ほどの2つの権限を含むロールは以下の通りになります。

- bigquery.jobs.list のみ
    - BigQuery ユーザー(roles/bigquery.user
- bigquery.jobs.list/bigquery.jobs.listAll 両方
    - BigQuery リソース管理者(roles/bigquery.resourceAdmin
    - BigQuery リソース編集者(roles/bigquery.resourceEditor
    - BigQuery リソース閲覧者(roles/bigquery.resourceViewer

権限の付与はIAMの画面でユーザやグループなどに対して行います。

# ジョブの実行履歴を見る方法
方法としては、3つあります。

1. WebUI上で見る
2. コマンドで見る
3. SQLで見る

このうち 1 と 2 は、同じ情報元を違う方法でみていることになります。

## WebUI上で見る
BigQueryのコンソールの画面の最下部に「ジョブ履歴」「クエリ履歴」があるのでそこから閲覧できます。それぞれクリックするとさらに「個人履歴」と「プロジェクト履歴」があり、自分だけのものか、プロジェクトないの他のユーザのものも含めてか、見ることができる。
先の通り、他のユーザのものを見るためには、閲覧するユーザが `bigquery.jobs.listAll` の権限を持っている必要がある。

## コマンドで見る
以下のコマンドを実行するとジョブの一覧が見れる

個人の履歴を見る時
 
```bash
bq ls -j
```

プロジェクト全体（他の人のものも含む）の履歴を見る場合

```bash
bq ls -j --all
```

## SQLで見る
INFORMATION_SCHEMAというメタデータを参照することでもジョブの履歴を見ることができます。

個人の履歴を見る時。テーブルには、頭にリージョンを指定します。

```sql
SELECT * FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_USER
```

プロジェクト全体を見る時。

```sql
SELECT * FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
```

さらに、テーブル名を `JOBS_BY_FOLDER`, `JOBS_BY_ORGANIZATION` とすることで、より上位の組織構造に対する情報の取得が一括でできます。


こちらも見るのに必要な権限の考え方は同じです。
INFORMATION_SCHEMAでジョブの情報をみる詳しい情報は[こちら](https://cloud.google.com/bigquery/docs/information-schema-jobs)を参照ください。

ちなみに、INFORMATION_SCHEMAではジョブ以外のテーブルの情報なども参照することができます。

最後に注意点としては、INFORMATION_SCHEMAの参照は通常のクエリと同様[お金がかかります](https://cloud.google.com/bigquery/docs/information-schema-intro#pricing)ので、ご注意を。
AtCoder ABC193振り返り(灰コーダー　AB2完)

注意：この記事は競プロ初心者が茶色を目指すために復習や反省するだけの記事です。使用言語はPython3で現状のパフォーマンスは200-400程度です。
あくまで自分の備忘録ですが同レベルの方の新しい発見に繋がれば嬉しいです。

#結果
A問題 正解
B問題 正解
C問題 大まかな形までは作れた
D問題以降 考える時間なし

#B問題

```Python:B.py

N=int(input())
data=[]
c=0
for i in range(N):
    data.append(input().split())
#dataに[時間　値段　個数]を各パターン入れた二次元配列
m=[-1]
for i in data:
    #売り切れるかどうか
    if int(i[2])-int(i[0])>0:
        #買えるならmに値段を代入
        m.append(int(i[1]))
#mをソートして結果を出力
ans=sorted(m)
if len(ans)>1:
    print(ans[1])
else:
    print(ans[0])

```
購入できないなら-1を返却とのことだったので購入可能な場合の料金を入れる配列に-1を入れておいた。
入力値がすべて整数との規定があったため0.5分,1.5分,2.5分...と1台ずつ減る場合でも複雑なことを考えずに1分経過なら1台、2分経過なら2台と減ることに少し考えてから気が付いた。
配列に購入可能時の値段をすべて入れソートしたが、値段の最小値min=-1を定義して購入可能時に毎回比較すほうが一般的で簡単だったと思う。

#C問題

数値Nが与えられa^bで表せない数値がN以下に何個あるか求める問題。

思考1
2^2～N^Nまで計算して配列に突っ込む。
(かぶりがあることを見逃していた)
思考2
1～Nまでが入っている配列を用意する。
配列内を二分探索してa^bが配列内にあればdelで消す。
(計算量がオーバー)

思考1.2で被りを気にして計算量が大きく増えた。
回答においてsetの存在を知った。setを使えばN以下のa^bをひたすらsetに追加していけばよかった。

```Python:C.py

N=int(input())
s=set()

for a in range(2,N+1):
    if a*a>N:
        break
    for b in range(2,N):
        x=a**b
        if x<=N:
            s.add(x)
        else:
            break

print(N-len(s))
```

#身についたこと
・setの存在
要素に重複のないリストのようなもの。リストのように順番は保存できない。listなどに変換も可能。

・計算量の大まかな限界
N=10^10の可能性がある時、計算量の都合から競プロでは力任せに1～Nまで求めることはできない。
gnubg のニューラルネットワーク

そろそろ次のプロジェクトに取り掛かろうと思い、深層強化学習の勉強を始めました。作りたいのは無論バックギャモンAIです。勉強の題材としては簡単そうだし、何よりモチベーションがあるからね！

どこから始めるかと考えた時に、まず思い浮かぶのは [GNU Backgammon](https://www.gnu.org/software/gnubg/) でしょう。先人たちはどのようなニューラルネットワーク(NN)を使っていたのか、調べてみました。

```
# /usr/games/gnubg -t
GNU Backgammon 1.06.002 Jan 25 2020
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 by Gary Wong.
Copyright (C) 2018 by Gary Wong and the AUTHORS; for details type `show version'.
This program comes with ABSOLUTELY NO WARRANTY; for details type `show warranty'.
This is free software, and you are welcome to redistribute it under certain conditions; type `show copying' for details.
```

どんな NN が使われているかは、以下のようにコマンドを入力すると分かります。

```
(No game) show engine
 * Contact neural network evaluator:
   - version 1.00, 250 inputs, 128 hidden units.

 * Crashed neural network evaluator:
   - version 1.00, 250 inputs, 128 hidden units.

 * Race neural network evaluator:
   - version 1.00, 214 inputs, 128 hidden units.

 * In memory 1-sided bearoff database evaluator
   - generated by GNU Backgammon
   - up to 15 chequers on 6 points (54264 positions) per player
   - database includes gammon distributions

 * In memory 2-sided bearoff database evaluator
   - generated by GNU Backgammon
   - up to 6 chequers on 6 points (924 positions) per player
   - database includes both cubeful and cubeless equities

 * Weights file and databases installed in:
   - /usr/share/gnubg
```

局面の評価に使われている NN は3つあり、それぞれコンタクトがある状況、"creashed"(これはあとで調べよう)、レースに分かれている。

それにしても記述が淡白だ。隠れ層が128ユニットというが、一体何層のネットワークなのでしょうか？

```neuralnet.c
static void
Evaluate(const neuralnet * pnn, const float arInput[], float ar[], float arOutput[], float *saveAr)
{
    const unsigned int cHidden = pnn->cHidden;
    unsigned int i, j;
    float *prWeight;

    /* Calculate activity at hidden nodes */
    for (i = 0; i < cHidden; i++)
        ar[i] = pnn->arHiddenThreshold[i];

    prWeight = pnn->arHiddenWeight;

    for (i = 0; i < pnn->cInput; i++) {
        float const ari = arInput[i];

        if (ari == 0.0f)
            prWeight += cHidden;
        else {
            float *pr = ar;

            if (ari == 1.0f)
                for (j = cHidden; j; j--)
                    *pr++ += *prWeight++;
            else
                for (j = cHidden; j; j--)
                    *pr++ += *prWeight++ * ari;
        }
    }

    if (saveAr)
        memcpy(saveAr, ar, cHidden * sizeof(*saveAr));

    for (i = 0; i < cHidden; i++)
        ar[i] = sigmoid(-pnn->rBetaHidden * ar[i]);

    /* Calculate activity at output nodes */
    prWeight = pnn->arOutputWeight;

    for (i = 0; i < pnn->cOutput; i++) {
        float r = pnn->arOutputThreshold[i];

        for (j = 0; j < cHidden; j++)
            r += ar[j] * *prWeight++;

        arOutput[i] = sigmoid(-pnn->rBetaOutput * r);
    }
}
```

なんということでしょう。隠れ層は「1つ」でした。そんなに単純だったのか・・

なお、入力として与えられている250の情報は、チェッカーの情報以外にも「ギャモンの知識」がいくつかエンコードされています。[これ](https://lists.gnu.org/archive/html/bug-gnubg/2003-05/msg00005.html)を参照。
出力は5つあり、勝率、ギャモン勝ち率、バックギャモン勝ち率、ギャモン負け率、バックギャモン負け率です。

このネットワークが"World Class"の強さを発揮するとは、バックギャモンはかくも簡単なゲームなのか？　それが本音なのかい？　僕にはそうは思えないよ。