OmniAICreator/Qiita-1.07M huggingface dataset:
古いMastodonを今更アップデートした話 v2.0.0->v2.7.0 

備忘録です。
とても古いバージョンなので今更な話です。

2021/11/1時点でmastodon v2.0.0からアップデートを行いました。
いくつか問題が出たので対応策を記録します。
まとまりが無いので後日問題ごとの個別ページに分けるかもしれません。

#環境

* EC2 ubuntu
* RDS PostgreSQL(9.6 -> 12.6)
* S3
* Mastodon(v2.0.0 -> v2.7.0)
* Docker環境

#アップデート経由バージョン

1. v2.0.0
2. v2.1.0
3. v2.2.0
4. v2.4.0
5. v2.4.1
6. v2.5.0
7. (Postgres9.6 -> 12.6)
8. v2.7.0

#対応した問題

* mimemagic 0.3.6以前の公開停止
* let's encrypt ルート証明書期限切れ
* RDS PostgreSQLのメジャーバージョンアップデート

# mimemagic 0.3.6以前の公開停止
MITライセンス・GPLライセンスの問題で2021/11/1現在はmimemagic 0.3.6以前は公開されていません。
mastodonはmimemagic 0.3.2～0.3.5あたりに依存しているため、その公開停止以降はdocker-compose buildを実行しても失敗します。

対応として公開されている0.3.10を使用するよう設定を書き換え、このバージョンに必要なshared-mime-infoをインストールしてやることで解決します。

* Gemfile.lockの書き換え(必須)

gemでmimemagicを参照している部分を0.3.10に書き換えます。

```Gemfile.lock
--    mimemagic (0.3.2)
++    mimemagic (0.3.10)
++      nokogiri (~> 1)
++      rake
```

* Dockerfileの書き換え(バージョンによって適宜)

Dockerコンテナにshared-mime-infoをインストールするための記述を追加します。
また依存に必要なのでdockerイメージのバージョンを書き換えます。

```Dockerfile
--    FROM ruby:2.4.2-alpine3.6
++    FROM ruby:2.5.0-alpine3.7
```

```Dockerfile
++    RUN apk update
++    RUN apk add shared-mime-info
```

#let's encrypt ルート証明書期限切れ

「let's encryptのルート証明書DST Root X3が期限切れ」と「Openssl 1.0.2の仕様」が合わさったことで、Dockerコンテナからlet's encrypt証明書を持つサイトにアクセスできなくなりました。
そのためdocker-compose build時に必要なファイルを取得できずにエラーを出していました。

> 2021/10/1をもってlet's encryptのルート証明書「DST Root X3」が期限切れとなっています。
> それ以降はISRGという別のルート証明書が使われるようになっています。

> Openssl 1.0.2では「信頼できないルート証明書」を一つでも持っている証明書は信頼しないという仕様があります。
> 「信頼できるルート証明書」を持っていても、「信頼できないルート証明書」の方が優先されるのです。

> この2つが合わさることでDockerコンテナからはlet's encrypt証明書を使用したサイトへアクセスできなくなっていました。

コンテナ内の証明書チェーンファイルを新しいもので上書きし、期限切れルート証明書チェーンのファイルを削除し、必要なISRGのルート証明書をコピーすることで対応します。

* Dockerfile追記

Dockerfileに下記の内容を追加します。
COPY処理が書かれている部分の前後に書いてました。
なんか一部不要な記述がありそうですが、とりあえずこれで動きました。

```
RUN apk -U upgrade
RUN rm -f /etc/ssl/certs/2e5ac55d.0
RUN rm -f /etc/ssl/certs/790a7190.0
RUN rm -f /etc/ssl/certs/ca-cert-DST_ACES_CA_X6.pem
RUN rm -f /etc/ssl/certs/ca-cert-DST_Root_CA_X3.pem
RUN rm -f /usr/share/ca-certificates/mozilla/DST_ACES_CA_X6.crt
RUN rm -f /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt
COPY isrgrootx1.pem /usr/local/share/ca-certificates/isrgrootx1.pem
COPY cacert-2021-09-30.pem /etc/ssl/cert.pem
RUN update-ca-certificates
```

* 証明書・証明書チェーンファイルのコピー
mastodonのフォルダ(Dockerfileなどと同じフォルダ)に「isrgrootx1.pem」「cacert-2021-09-30.pem」を用意します。
 * isrgrootx1.pem : [このファイル](https://letsencrypt.org/certs/isrgrootx1.pem.txt)を保存して名前と拡張子を書き換えてください
 * cacert-2021-09-30.pem : [ここ](https://curl.se/docs/caextract.html)から適宜最新のものを選んでください。

#RDS PostgreSQLメジャーバージョンアップデート

RDSでPostgreSQLのメジャーバージョンを上げたときにCPU使用率が高いままになってしまう問題がありました。
これはデータベースの統計データを保存するpg_statisticテーブルが更新されていないためおこる症状です。
RDSコンソールでアップデートするだけでは自動で行われないため、手動で最適化処理ANALYZEを実行する必要があります。

* ANALYZE実行
今回はmastodonを動かしているEC2にPostgresをインストールし、RDSに接続することでANALYZEを実行しました。

```
psql -h [RDSのエンドポイント] -U [ユーザ名] -d [DB名]
password:
```

ユーザ名、DB名、パスワードはmastodonの.env.productionファイルに記載しているものでOKです。

```
> ANALYZE VERBOSE;
```
DB内に入ったらANALYZEコマンドを実行します。
VERBOSEオプションは無くても良いですが、途中経過が表示されるので確認のために付けました。

# 最終的には

一番新しいstableのmastodon v3.2.2まで上げる予定です。
そこで問題などがまた出たら追記予定です。
【Linux】Linuxコマンド基礎

## 概要
Linuxコマンドでよく使うものを備忘録として載せておきます。
何もない場合は例、$をbash入力、#はコメント及び出力と読み取ってください。

## ディレクトリ・パス関連

**ルートディレクトリ**：ディレクトリの頂点に立ってる場所。「**/**」で示す。

**ホームディレクトリ**：ユーザのホームディレクトリ。基本的に「**/home/[ユーザ名]**」となる。「**~/**」で示すことも可能。

**カレントディレクトリ**：今いる場所のディレクトリ。「**./**」で示す。カレントディレクトリの１つ上の階層に移動したい場合は「**../**」で示す。

**絶対パス**：ルートディレクトリを基準にディレクトリを指定

```bash:bash
# /home/taro/Desktop
```

**相対パス**：今いる場所を基準にディレクトリを指定（例は/home/taroにいてDesktopを指す場合）

```bash:bash
# ./Desktop
# Desktop

# こんなことも可能
# ../home/taro/Desktop
```

## ディレクトリ移動
使い方：**cd [ディレクトリ]**
cdのみだとホームディレクトリに連れて行かれる。

```bash:bash
$ cd /home/taro/Desktop
$ cd ./Desktop
```

## カレントディレクトリを確認
```bash:bash
$ pwd
# /home/taro/Desktop
```

## カレントディレクトリにあるファイルを確認
使い方：**ls [オプション]**
オプションなしだと概要のみ、lオプションで詳細情報（権限・所有者・所有グループ・サイズ等）が得られる。
権限の項目は10桁あり、それぞれ以下の意味を持つ。

１列目　　：ディレクトリ（**d**）かファイル（**-**）か
２〜４列目：所有者権限（r:読み込み、w:書き込み、x:実行）
５〜７列目：グループ権限（r:読み込み、w:書き込み、x:実行）
８〜10列目：その他権限（r:読み込み、w:書き込み、x:実行）

```bash:bash
$ ls
# test

$ ls -l
# drwxr-xr-x  46 taro  staff  1472  2  6  2021 test
```

## 管理者権限で実行
使い方：**sudo [コマンド]**

```bash:bash
$ sudo cd Desktop
```

## 権限付与
使い方：**chmod [オプション]**
オプションには各権限を３桁の数字（それぞれ所有者・グループ・その他）で与える。
２進数表記（各権限r, w, xの順）となっているため、４で読み込み、６で読み込みと書き込み...と言った形で権限が付与される
（読み込み＝**４**, 書き込み＝**２**, 実行＝**１**として足し算すると覚えたら良い）。
全ての権限に読み込み権を与えたい場合は**+r**、外したい場合は**-r**を用いる。

```bash:bash
# 全ての権限に実行権付与
$ chmod +x test.sh

# 全ての権限から読み込み権削除
$ chmod -r test.sh

# 所有者は読み書き、グループは書き実行、その他は書き込み権を付与
$ chmod 632 test.sh 
```

## 所有者変更
使い方：**chown [変更したいユーザ名] [ファイル or ディレクトリ名]**

```bash:bash
$ chown root test.sh
```

## 所有グループ変更
使い方：**chgrp [変更したいグループ名] [ファイル or ディレクトリ名]**

```
$ chgrp users test.sh 
```

## まとめ

とりあえず絶対に覚えておいた方が良いのはこの辺りな気がします。
なんか他にもありそうなので、思い出したら追記します。
亭主関白をサポート★ぱっと見では分からない「缶ビールの残量」をAIが判定

#疲れた旦那さまを癒したい！
ということで、旦那さんのビールがなくなる前に、
新しい缶ビールをそっと持ってくるのが、私の夜のお仕事（笑）
でも、ちょっとテレビを見たり、目を離すと、
気付いたらなくなってしまっていて、
「おかわりちょうだい」と言われて、イラっとしちゃう自分がいるのも事実（笑）

#缶の中身が分かる！？
居酒屋で働いていることもあり、お客様の飲み物の残量には敏感で、
実はグラスの中を見ているのではなく・・・
**肘やグラスの角度**を見て残量を把握しています。
なので、缶ビールに置き換えると、
**この角度になったら、少なくなっているな！**というのが、
缶の中身が見えなくても分かるのです！！

#完成品
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExvogEo" data-user="haranakaizumi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/haranakaizumi/pen/ExvogEo">
  旦那さんにビールを持ってきて、亭主関白しましょう</a> by HaranakaIzumi (<a href="https://codepen.io/haranakaizumi">@haranakaizumi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

私が使うとこんな感じです。
<iframe width="560" height="315" src="https://www.youtube.com/embed/NDU6CQvO6FE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#缶の角度で３段階に分ける
[Teachable Machine](https://teachablemachine.withgoogle.com/)を使いました。
![3段階.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2052662/25dbf2e1-9e5c-d47a-41c4-019c6e67d2ad.png)

・まだある
・なくなりそう
・やばい！なくなる！

の３段階に分けて学習をさせました。

学習させてつまづいたところは、

:::note warn
飲んでいない時（缶がない）ときのことを考えていなかった
:::

ということです。
本当の意味でずーーーっとビールを飲んでいるわけではないので、
（そうなると家計が火の車）
ここを考慮する必要がありました。
「まだある」の中に入れたので、ここのサンプルの写真が多くなっています。

#帰ってくるのが待ち遠しい・・・
お前の旦那、どこ行った！？と思っていらっしゃる方もいるかもしれませんが、
ただいま出張中で家にいないので、一旦自分の写真で学習させてみました。

:::note warn
人が変わっても使えるのか？
再度学習させないと使えないのか？
:::

は旦那さんが帰ってきてから試してみたいと思います。
（帰ってくる日はいっぱいビールを冷やしてあげよう♡笑）
エクスプローラーを検索モードでコマンドから起動する

# 背景
RPA なんかで自動化する際、API が公開されてないツールを利用する場合どうしてます？

ファイルパスを元に、エクスプローラーを開き固定位置からドラッグ＆ドロップすればなんとかなるなと思った為の布石。

# やりたいこと
- エクスプローラーにて、一番上のアイテムが目的のファイルになる。

# 結論

search-ms で実施
実際に使う際は、query にファイル名、location にフォルダ名を指定してやればいい感じかな、と
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/67924f88-6c9a-9c54-2ecc-1f6137fede85.png)


```bat:検索モードでエクスプローラー起動例
start search-ms:"query=選択&crumb=location:C:\temp&displayname=検索モードをコマンド起動&inputlocale=1041&keywordlocale=1041&"
```
:::note
search: でもいけるかもだけど、その差は未調査
:::

## パラメータ説明
|Parameter|例|補足|
|-|-|-|
|query|query=選択|検索キーワード|
|crumb|crumb=location:C:\temp|検索フォルダ|
|displayname|displayname=検索モードをコマンド起動|表示名![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/67eea2eb-c1ad-f6fd-16ae-04c236079646.png)|
|inputlocale|inputlocale=1041|Query の LCID|
|keywordlocale|keywordlocale=1041|Indexer の LCID。恐らく Windows Search のかな|

https://docs.microsoft.com/en-us/windows/win32/search/-search-3x-wds-qryidx-searchms

# AQS Advanced Query Syntax 

Example にあった、<code>crumb=folder:</code> でも行けそうだったけど、できない理由は未調査

```bat:ダメだった例
start search-ms:"query=選択&crumb=folder:C:\temp&"
```

https://docs.microsoft.com/en-us/windows/win32/search/-search-3x-advancedquerysyntax

# LCID はここ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/2ebd598e-9134-edd8-5554-28e5367131a7.png)
10進変換：0x0411 ⇒ 1041 

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37

# あとがき

あとは、PAD で料理。

# keyword

how to start explorer as search mode
【JavaScript】上スクロールすると出現するheaderの作り方【jQuery未使用】

上スクロールするとふわっと出現するheaderを、素のJavaScriptのみで実装します。
ユーザービリティの高いヘッダーの挙動だと思うので、よければ参考にしてみてください！



## 成果物

下スクロールすると要素が消えて、上スクロールすると要素が現れます。
※今回はJavaScriptの解説がメインなので、header本体のスタイリングについては触れません。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYjeZpN" data-user="ryowakitazawa82" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ryowakitazawa82/pen/LYjeZpN">
  Untitled</a> by ryowa.kitazawa (<a href="https://codepen.io/ryowakitazawa82">@ryowakitazawa82</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 事前準備

### headerにidを指定
JavaScriptで要素をとってくるために必要な記述です。

```
<header class="header"　 id="header">
```

### removeクラスを作成
非表示にしたときのスタイリングです。
opacityを0にして透明にしましょう。
aタグなどを付与した時も考え、user-selectもnoneに。

```
#header.remove {
  opacity: 0;
  user-select: none;
}
```

### headerにtransitionを指定
自然にふわっと表示させるために、transitionを設定しましょう。
要素の重なりも考えて、z-indexも設定しておくと良いと思います。

```
header {
    opacity: 1;
    transition: 0.5s;
    z-index: 100;
}
```

## JavaScriptの記述
では、JavaScriptを記述を解説していきます。

### header要素をとってくる
まずは先ほどheaderに指定したidを利用して、header要素をとってきましょう。

```
const header = document.getElementById('header'); // まずはheader要素をとってくるよ。
```

### 初期値と現在地を変数で指定
後々の処理で必要になる記述です。
値はそれぞれ適当に、0としておきましょう。

```
let startPosition = 0; // headerのY座標の初期値を変数で指定しておくよ。
let NowPosition = 0; // headerのY座標の現在値を変数で指定しておくよ。
```
### スクロールイベントを設定
windowにスクロールイベントを設定しましょう。
引数なしのアロー関数で書くのが記述量が少なくて良いでしょう。

```
window.addEventListener('scroll', () => {
 });
```

### headerのY座標の現在値を更新
スクロールされたらheaderのY座標の現在値を更新をしましょう。
次のif文で、必要な処理になります。

```
 NowPosition = window.scrollY; // headerのY座標の現在値を更新。
```

### 条件に応じてheaderにremoveクラスを付与する
準備段階で記述したremoveクラスの登場です。
このクラスを付け外しすることで、ヘッダーの表示・非表示を切り替えます。
初期値より現在値が大きい時にremoveクラスを付与、初期値より現在値が小さい時にremoveクラスを外します。

```
if(NowPosition >= startPosition) {
            header.classList.add('remove');
        } else {
            header.classList.remove('remove');
        }
```

### 初期値を更新
最後に初期値を更新してあげましょう。
初期値という少々わかりにくい表現をしていますが、要はNowPositionが更新される1つ前の値をこのstartPositionにいれています。
これにより、下スクロールした時にif文がtrueになり、removeクラスが付与されてheader要素が消えるのです。
逆に上スクロールしたときには、removeクラスが外れてheader要素が出現します。

```
startPosition = NowPosition; // 初期値を更新。
```
where メソッドに配列を渡すとインスタンスを配列で返してくれる

## 開発環境
ruby 2.6.5
Ruby on Rails 5.2.5

## 本題

`where` メソッドは `each` とか使わなくても
配列を入れたら
中の要素をすべて処理してくれる

```
@searching_task_id = Combination.where(label_id: params[:task][:label_name].to_i).pluck(:task_id)
```
```
@irb(#<TasksController:0x00007fc0d76f9380>):002:0> @searching_task_id
=> [2333, 2334, 2335]
```
上のように配列の入った変数を利用して
データベースから
レコードを引っ張るためには

```
@tasks = Task.where(id: @searching_task_id)
```
```
@tasks
=> #<ActiveRecord::Relation [#<Task id: 2333, title: "１", content: "あ", created_at: "2021-06-11 03:56:56", updated_at: "2021-06-11 03:56:56", deadline: nil, status: "", priority: "高", user_id: 68>, #<Task id: 2334, title: "２", content: "あ", created_at: "2021-06-11 03:57:05", updated_at: "2021-06-11 03:57:05", deadline: nil, status: "", priority: "高", user_id: 68>, #<Task id: 2335, title: "３", content: "あ", created_at: "2021-06-11 03:57:17", updated_at: "2021-06-11 03:57:17", deadline: nil, status: "", priority: "高", user_id: 68>]>
```
そのまま入れるだけで大丈夫
ASUS CM5500FDA メモリ不具合 その後

##メモリ不具合はどうなったのか！

以前の投稿

https://qiita.com/irisis2021/items/003acc7a80aa9ed93b27


特にASUSからもGoogleからもアナウンスはなかったと思うのですが、なんどかChromebookのアップデートも走っているので、直っていたりしないのかと思いリセット（Powerwash）を実施することにしました。

##結果

リセット後、メモリはちゃんと認識されていました。どうやら対応済みのようです。なんにしても良かった。

##余談

メモリ不具合で暫定対応を行った後、いろいろ困ったことがありました。
Linuxを入れて日本語化しようとするも、エラーでできず。
その他いろいろインストールでエラーとなる状態でした。javaすら入れれない。
よくまぁその状態でFlutterの開発環境を動かせれるようになったものだ。

今回は日本語化もjavaのインストールも問題なくできてます。
あれはいったいなんだったのだろう。

新環境はVScodeで開発環境を作ってみました。まだ使い方よくわかってません。
論文メモ：Differentiable Hierarchical Graph Grouping for Multi-Person Pose Estimation

# 論文
**論文名**
*Differentiable Hierarchical Graph Grouping for Multi-Person Pose Estimation*

**著者**
*Sheng Jin, Wentao Liu, Enze Xie, Wenhai Wang, Chen Qian, Wanli Ouyang, and Ping Luo*

**学会**
*ECCV2020*

https://arxiv.org/abs/2007.11864


# 概要
　多人数姿勢推定のためのキーポイントグルーピングに興味がある。ボトムアップ方式の姿勢推定は効率的ではあるが、キーポイント検出とそのグルーピングは別々に解決されることが多く、最適化されていない。そこで、人物のパーツグルーピングをグラフクラスタリングタスクとして再定式化し、HGG（Differentiable Hierarchical Graph Grouping）を提案。HGGはキーポイント検出ネットワークとエンドツーエンドで学習可能であり、キーポイント候補を多層グラフニューラルネットワークを用いてクラスタリングする。また、クラスタリングの性能向上を図ってエッジ識別器とマクロノード識別器を新たに提案。主流なボトムアップ手法に簡単に組み込むことができ、複数のデータセット（COCO, OCHuman）において性能を向上させることを確認。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246925/e91475cb-1b6a-3ba2-212c-5a08c2c15eae.png" width=500>
</div>
>Sheng Jin, Wentao Liu, Enze Xie, Wenhai Wang, Chen Qian, Wanli Ouyang, and Ping Luo. Differentiable hierarchical graph grouping for multi-person pose estimation. In ECCV, pages 718–734, 2020.

# 貢献
- 多人数姿勢推定タスクをグラフクラスタリングとして定式化し、ボトムアップ方式においてグルーピング監視可能なエンドツーエンドのフレームワークを初めて提案

- ローカル（近い距離？）およびグローバル（遠い距離？）なペアワイズ関係の特徴を学習し、グループ化の精度を高めるエッジ識別器とマクロノード識別器を提案

- COCOにおいて最先端性能と同等、OCHumanにおいてSOTA
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246925/24cdf56f-f79b-76e6-3286-0aa24d22892c.png" width=500>
</div>
>Sheng Jin, Wentao Liu, Enze Xie, Wenhai Wang, Chen Qian, Wanli Ouyang, and Ping Luo. Differentiable hierarchical graph grouping for multi-person pose estimation. In ECCV, pages 718–734, 2020.

# 評価
- MS COCO：性能向上？
- OCHuman : SOTA

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246925/3a2e6fc6-fb39-042f-38df-55a64b932c18.png", width=600>
</div>

>Sheng Jin, Wentao Liu, Enze Xie, Wenhai Wang, Chen Qian, Wanli Ouyang, and Ping Luo. Differentiable hierarchical graph grouping for multi-person pose estimation. In ECCV, pages 718–734, 2020.

OCHuman: 難易度の高い人物姿勢推定データセット。訓練データはなく、人物姿勢推定の精度限界を調査するためのもの
# 課題
多物体追跡やインスタンスセグメンテーションへの応用
"[Violation] 'setTimeout' handler took ○○ms"という表示がでてくる

#はじめに
React x Firebase realtime databaseを使ってアプリケーションを作成していたところ、コンソールに"[Violation] 'setTimeout' handler took ○○ms"という表示が出てきた(setIntervalのものもあった)。原因がなにか分からなかったので調べたものを備忘録として残す。

#結論
致命的なエラーなどではない。

#詳細
こちら[[1]]で詳細が書かれていた。調べてみるとsetTimeoutとsetIntervalはjavascript関数のよう。自分で書いた覚えはないので、ライブラリなどのなかで使われている可能性が高い。今回だとFirebase realtime databaseがかなり怪しい。他にもなっている方がいたら連絡ください。必ず直す必要があるわけではないが、改善の余地があるという認識で良さそう。

#対策
どれが原因なのかはっきり分かっていないので対処のしようがない。もし消すならば、コメントアウトなどして原因のコードを追求し、改善する必要がありそう。

#おわりに
もうちょっと詳細を書いておいてほしい感はある。

#参考文献
[1]:https://stackoverflow.com/questions/42218699/chrome-violation-violation-handler-took-83ms-of-runtime/44824402#44824402
[2]:https://wordpress.ideacompo.com/?p=11336

[[1]]:Chrome violation : [Violation] Handler took 83ms of runtime
[[2]]:Chromeブラウザにおける「Violation」JSアラート
【Nuxt.js】injectについて

#はじめに
こんにちは。
こちらの記事では、Nuxt.jsのinjectについて記しています。
誤っている点がございましたらコメントいただけると幸いです。

##injectとは
pluginsディレクトリで使用できるメソッドで、関数や値を共通化することができ、importしなくてもコンポーネントやVuexストアに挿入することができます。`this.$~`を使って呼び出すことができる。


>参考記事：https://nuxtjs.org/ja/docs/directory-structure/plugins

##実装手順

実際のコードの例で見ていきたいと思います。
今回はfirebaseを導入し、injectでVuexストアに呼び出す処理を記述します。

###1. injectの定義
pluginsディレクトリでinjectの定義を行います。

```javascript:plugins/firebase.js
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/functions';

const config = {
    //APIキー
}

firebase.initializeApp(config)

export default function (context, inject) {
    inject('auth', firebase.auth())
    inject('functions', firebase.functions())
}
```

injectメソッドは下記の構成となっており、呼び出す際は`this.$key`となる。

```javascript:
inject('key',value)
```

###2. nuxt.config.jsの設定
puluginsが使用できるように、nuxt.config.jsのpluginsに以下のように記述します。

```javascript:nuxt.config.js
plugins: [
  '~/plugins/firebase.js'
]
```

###3. Vuexストアで呼び出す
Vuexストアのactionsで呼び出します。
下記の`this.$auth`の部分が、先ほど定義したinjectの`inject('auth', firebase.auth())`のkeyを指定しています。

`functions`を呼び出す場合は、`this.$functions`となります。

```javascript:store/index.js
export const state = () => ({
});

export const actions = {
  login({ dispatch }, payload) {
    this.$auth //以下省略
};
```


<br>

#おわりに
ここまでNuxt.jsのinjectについてまとめました。
紹介したのは一部の実装に過ぎないので、今後injectに触れる機会があれば改めて記事にしていきたいと思います。
以上、最後まで読んでいただきありがとうございました！
よければLGTMを押してくれると嬉しいです！
コールバックの際に使う self について

## 開発環境
ruby 2.6.5
Ruby on Rails 5.2.5

## 前提
ユーザーの認証機能をつけているアプリ
ユーザーに boolean 型で admin というカラムをつけ、admin が true のユーザーを管理者としている

## 本題

管理権限を持ったユーザーがが０人にならないようにする
バリデーションの機能実装


```
class User < ApplicationRecord
  before_destroy :admin_exist_check
  before_update :admin_update_exist

  has_many :tasks, dependent: :destroy

 # 中略

  def admin_exist_check
    if User.where(admin: true).count <= 1 && self.admin == true (←ここ)
      throw(:abort)
    end
  end

  def admin_update_exist
    if User.where(admin: true).count == 1 && self.admin == false
      throw(:abort)
    end
  end

end

```

上記みたいなコードを書く。

なにかを参考にしながら書いたコードなんだけど
このコードをモデルに書くと admin というカラムが true のユーザーが0人にならないようになる

ただ self という部分に違和感
自分で書いといてあれだけど self ってなんだ。。


___

```
binding.irb
def admin_exist_check
    if User.where(admin: true).count <= 1 && self.admin == true (←ここ)
      throw(:abort)
    end
end
```
上のように動きを止めて、コンソール上で

```
self.admin 
```
と打つと `true` が返ってくる

さらにコンソール上で

```
self
```
と打つと

```
self
=> #<User id: 31, name: "adm", email: "xxx", password_digest: "$2a$12$mDmd3aFZR9D7korRsx/qvedQmflQo3QSz2h3i0BWebH...", created_at: "2021-06-07 13:44:56", updated_at: "2021-06-07 13:44:56", admin: true>
```
こんな風に値を保有していることがわかる。


つまりコールバックが発生した瞬間に呼び出されるメソッド内での self には
そのコールバックで変化する予定のリソースが入ってくる

ってことかな？笑。わかりません笑
Java学習　ブラックジャック作ってみた

こんにちは。
Javaの基礎文法の学習を進めていく中でそろそろなにか形のあるものを作ってみようということで、コンソールで動く簡単なブラックジャックゲームを作ってみた。

↓GitHub　URL
　https://github.com/hananokensho/practiceBlackJack

今回作ってみて感じたこと
・コンストラクタが優秀
・インスタンスが実体というのがよくわからなかったが理解が深まった。

Mainクラスだけ載せておきます。

```Java:Main.java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Deck deck = new Deck(); //山札
        Player player = new Player(); //プレイヤー
        Dealer dealer = new Dealer(); //ディーラー（相手）
        Scanner sc = new Scanner(System.in);
        System.out.println("ブラックジャックゲーム");
        System.out.print("名前を入力してください >");
        player.setName(sc.nextLine());
        //はじめの2枚ドロー
        player.Draw(deck);
        dealer.Draw(deck);
        player.Draw(deck);
        dealer.Draw(deck);

        //　ディーラーは合計点が17より上になるまで引く
        boolean dealerPoint = false;
        while(!dealerPoint){
            if(dealer.totalPoint() < 17){
                dealer.Draw(deck);
            }else{
                dealerPoint = true;
            }
        }

        // プレイヤーがもう一枚引くかの判断
        boolean decision = false;
        while(!decision){
            System.out.println("ディーラーのカード1枚:" + dealer.myCard.get(0).getNum());
            for(int i = 1 ; i < player.myCard.size()+1; i++){
                System.out.println(player.getName() + "のカード"+ i + ":" + player.myCard.get(i-1).getNum());
            }
            System.out.print("もう一枚引くなら[ドロー]：引かないなら[判定]と入力してください >");
            String stringDecision = sc.nextLine();
            if(stringDecision.equals("ドロー")){
                player.Draw(deck);
            }else if (stringDecision.equals("判定")){
                decision = true;
            }else{
                System.out.println("正しい入力をしてください");
            }
        }

        //勝敗判定
        Decision decisiton = new Decision(player.totalPoint(), dealer.totalPoint()); //判定クラス
        System.out.println(decisiton.decisiton(player.totalPoint() , dealer.totalPoint() , player.getName()));
        if(player.totalPoint() == 21){
            System.out.println("おめでとうございます！ブラックジャックです！");
        }
        System.out.println(player.getName() + "のポイントは" + decisiton.getPlayerPoint() + "でした");
        System.out.println("ディーラーのポイントは" + decisiton.getDealerPoint() + "でした");
        System.out.println("終了します");
    }
}
```

↓実行結果はこのような感じ

```
ブラックジャックゲーム
名前を入力してください >haraitai
ディーラーのカード1枚:10
haraitaiのカード1:2
haraitaiのカード2:10
もう一枚引くなら[ドロー]：引かないなら[判定]と入力してください >ドロー
ディーラーのカード1枚:10
haraitaiのカード1:2
haraitaiのカード2:10
haraitaiのカード3:1
もう一枚引くなら[ドロー]：引かないなら[判定]と入力してください >判定
haraitaiの負けです！
haraitaiのポイントは13でした
ディーラーのポイントは21でした
終了します

プロセスは終了コード 0 で完了しました
```
もっと改善できるのだろうと思いながらも形になったので良かった。
Azure Pipelines で Azure Container Apps Preview にデプロイしてみる

Ignite 2021 で発表があった Azure Container Apps Preview に Azure Pipelines を使って早速デプロイしてみようという記事です。まだ Preview なので、参考までに。

今回は Azure Pipelines で Azure CLI を使ってデプロイしています。 Preview が終わるころまでには Azure Pipelines のタスクも出来ていると思いたいです。

ちなみに Azure Portal を見ると Continuous deployment メニューがあって、恐らく Azure Container Registry 経由で継続的なデプロイが出来るようになると思います。ただ、タイミングが悪かったのか Start ボタンが Enabled にならず上手く使えなかったのと、 Azure CLI でこれらの設定が見つからなかったため、この記事では書いていないです。 Azure Container Registry 経由のデプロイなら Web app for Container と似たような形になると思うので、慣れているなら少し待ってこっちを試したほうが楽なはずです。

## 前提条件

- Azure Container Apps Preview のリソースが作成されていること

[Quickstart: Deploy your first container app | Microsoft Docs](https://docs.microsoft.com/en-us/azure/container-apps/get-started?tabs=bash)

正常にリソースが作成されると containerapps-helloworld イメージの、この画面が表示されます。
[![Image from Gyazo](https://i.gyazo.com/068b6c64dc073fa93ef4cf68ac7b6e25.png)](https://gyazo.com/068b6c64dc073fa93ef4cf68ac7b6e25)

## Azure Pipelines でデプロイ

この YAML 定義を使って Azure Pipelines を動かします。
まだ ubuntu-latest に Azure CLI の Azure Container Apps extension がないため、それをインストールしてから `az containerapp update` を使って Azure Container Apps へ新しいイメージをデプロイします。
この例では `docker/getting-started` のイメージファイルをデプロイしています。イメージは Docker Hub から取ってくるようです。

```yaml
pool:
  vmImage: ubuntu-latest

steps:
- script: |
    az extension add \
      --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.0-py2.py3-none-any.whl \
      --yes

- task: AzureCLI@2
  inputs:
    azureSubscription: '<YOUR_SERVICE_CONNECTION>'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az containerapp update -n my-container-app -g my-containerapps \
          --image docker/getting-started
```

デプロイされると containerapps-helloworld から、この画面に変わります。
[![Image from Gyazo](https://i.gyazo.com/1f03daac291a53d3186c6506f3601965.png)](https://gyazo.com/1f03daac291a53d3186c6506f3601965)


## Azure CLI のコマンドについて

困ったときは --help しましょう。

```shell
$ az containerapp --help

# Group
#     az containerapp : Commands to manage Containerapps.
#         This command group is in preview and under development. Reference and support levels:
#         https://aka.ms/CLI_refstatus
# Subgroups:
#     env           : Commands to manage Containerapps environments.
#     github-action
#     revision      : Commands to manage a Containerapp's revision.

# Commands:
#     create        : Create a Containerapp.
#     delete        : Delete a Containerapp.
#     list          : List Containerapps.
#     scale
#     show          : Show details of a Containerapp.
#     update        : Update a Containerapp.
```
Rspecインストールの手順

環境
---
MacOS Big Sur11.5.2
ruby 3.0.2
rails 6.1.4
docker 20.10.6

Gemのインストール
---
まずは Gemfile に`rspec-rails`と`rspec_junit_formatter`を追加します。
本番環境では RSpec を使わないので、開発とテスト環境にのみ gem をインストールさせます。

```ruby:Gemfile
group :development, :test do
  
  gem 'rspec-rails' # 追加
  gem 'rspec_junit_formatter' # 追加

end
```

そしてdocker-compose run web bundle installとdocker-compose buildをします。

Rspecの基本設定
---
以下のコマンドでRspecをインストールします。

```
$ docker-compose run web rails g rspec:install
```
Rspecの実行
---
この段階ではまだ何もテストは書いていませんが、動作確認の意味で RSpec を実行してみます。

```
$ docker-compose run web rails spec
Starting rails-scaffold-circleci_webpacker_1 ... done
Creating rails-scaffold-circleci_app_run     ... done
No examples found.


Finished in 0.00124 seconds (files took 0.38309 seconds to load)
0 examples, 0 failures
```
まだ何もテストを書いていないので当然テスト(exmaple) は 0、失敗(failure)も 0 ですが
とりあえず RSpec が動作していることは確認できました。

テスト用 model 生成
---
最低限のテストを行うため、適当に User モデルだけ作成しておきます。
string型の name, email カラムを用意しておきましょう。

```
$ docker-compose run web rails g model User name:string email:string
```
上記コマンドに以下のマイグレーションファイルが自動されます。


```ruby:db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```
自動生成されたマイグレーションファイルをもとに、マイグレーションを行います。

```
$ docker-compose run web rails db:migrate
```
これで、name カラムと email カラムを持った User モデルが作成されました。
次は User モデルに対するテストを RSpec で書いてみます。

Userモデルのテスト用RSpecファイルを生成
---
rspec-rails を入れているので、テスト用のファイルは rails g コマンドで生成できます。

```
$ docker-compose run web rails g rspec:model User
```
```ruby:rspec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  pending "add some examples to (or delete) #{__FILE__}"
end
```
これを書き換えていきましょう。
今回はとりあえずテストが出来ればよいので、適当な name と email を持ったユーザーを登録できることを確認します。

↓
#####修正後
```ruby:rspec/models/user_spec.rb(修正後)
require 'rails_helper'

RSpec.describe User, type: :model do

  it "name と email を持ったユーザーを登録できること" do
    user = User.new(
      name: "John",
      email: "john@example.com",
      )
     # オブジェクトをexpectに渡す動作が有効であることを確認
     expect(user).to be_valid
  end

end
```
これで RSpec を実行してみましょう。

```
$ docker-compose run web rails spec
```
失敗 (failure) は無く成功していることを確認します。

```
Finished in 0.10029 seconds (files took 8.17 seconds to load)
1 example, 0 failures
```
これでテストが実行できることを確認しました。

参考
---
https://zenn.dev/tmasuyama1114/articles/docker-rails-circleci-rspec-test
Laravel8 URLがディレクトリまで同じでも、ファイル名で処理を振り分けたい！

##はじめに
Laravel8で`ディレクトリまでが同じURLでも、ファイル名(数値or文字列)次第でコントローラーを振り分ける`必要が出て、少し焦ったので備忘録を書きました。

##やりたいこと

```.php
① Route::get('/team/{member_id}', [MemberController::class, 'index']);
② Route::get('/team/{country}', [CountryController::class, 'index']);
```
①の{member_id}には`数値`を
②の{country}には`文字列`を渡して、
それぞれのコントローラーまで処理を通したい。

※それぞれのコントローラーでバリデーションされ、①は数値のみ、②は文字列でしかパラメーターを受け取らない前提。




##問題
(ドメイン名はhoge.comとして)
① https://hoge.com/team/1
② https://hoge.com/team/japan
それぞれのルーティングの処理に上記のようなリクエストをした場合、
①はコントローラーまで通るが②は通らない。

原因は`/team/japan`と文字列のパスを指定しても
②の{country}側にルーティングをする前に、
①の{member_id}側に処理が渡ってしまっていること。


##対策

正規表現を使って数字以外を弾いて、①の処理をスルーさせる。

```.php
① Route::get('/team/{member_id}', [MemberController::class, 'index'])
   ->where('member_id', '[0-9]+');
② Route::get('/team/{country}', [CountryController::class, 'index'])
   ->where('country', '[a-zA-Z]+');
```
*②の`->where('country', '[a-zA-Z]+');`は書かなくても大丈夫。

##終わりに
URLを先に決めて処理を書いていたので、
気づいた時には焦りましたが簡単に対策が打てました。
URLの設計に問題があるとか、そういった話は一旦無しでお願いします..笑
自分による自分のためのクラス練習

##はじめに
前回の記事でイメージのために人間クラスとか書いていた。折角だからコードで練習。

https://qiita.com/dem_kk/items/55df6fb68cf9e670abbb

##コード
```python
#クラスの定義
class Human:
  def __init__(self,name='佐藤',age=25,place='東京'):
    self.name = name 
    self.age = age
    self.place = place 

  def info(self):
    text = '{}さんは{}歳で、{}に住んでいます。'
    return text.format(self.name, self.age, self.place)

#インスタンス化
human = Human()

#インスタンスから関数を実行
human.info()

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/5ee364e1-5777-92eb-acae-3312a2e62302.png)

東京に住んでいる佐藤さん(25)というありふれた自己紹介になった。今度は東京だとざっくりしすぎているから、もう少し説明を加えてみたい。そこでインスタンス化の時に引数を追加して説明を変えよう。

```python
#インスタンス化
human = Human('佐藤','25','東京都葛飾区')

#インスタンスから関数を実行
human.info()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/679a8b42-47bc-4ce8-4e95-83e3b8433b14.png)

自分で指定したことで、デフォルトの値から変更されて東京都葛飾区に変更されたことがわかる。変える引数が1つだからといって、インスタンスに引数を1つだけしか入れないと第一引数だけ変更されておかしなことになる(これは確認)。

```python
#インスタンス化
human = Human('東京都葛飾区')

#インスタンスから関数を実行
human.info()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/30659ee0-24b3-6b42-26d0-98dddce0809f.png)

東京都葛飾区さんが人物名になってしまった。クラス中で引数の順番を指定しているので、対応させて書かないといけないことがよくわかる。

### super()による継承
上記で人間クラスを作成したので、これを利用して社会人クラスを作っていく。

```python
#Humanクラスを継承して社会人クラスを作成
class Work(Human):
  def __init_(self,name,age,place):
    super().__init__(name,age,place) #親クラスからのオーバーライド

  def company(self):
    print('社会人です。')
  
#インスタンス化
work = Work()
#インスタンスから関数を実行
print(work.info()) #同時に表示するためprintで実行
work.company()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/f5c4294d-f471-408a-7d51-675de638332f.png)
佐藤さんの属性に社会人が加わった。でも普通社会人です、で終わるのではなく所属会社や部署を伝えるはず。そこで社会人クラスに新しく引数を設定する。

```python
#Humanクラスを継承して社会人クラスを作成
class Work(Human):
  def __init_(self,name,age,place,working,department,title):
    super().__init__(name,age,place) #親クラスからのオーバーライド
    self.working = working
    self.department = department
    self.title = title

  def company(self,working='〇×会社',department='営業部',title='一般社員'):
    print('{0}の{1}に所属している{2}です。'.format(working,department,title))
  
#インスタンス化
work = Work()
#インスタンスから関数を実行
print(work.info()) #同時に表示するためprintで実行
work.company()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/ba76acc3-2669-ce90-d90e-e0bc814ae8a5.png)

社会人らしい表現になったのでは。
その後佐藤さんは異動で別の部署になった。子クラスの引数を変更してみる。

```python
#インスタンス化
work = Work()
#インスタンスから関数を実行
print(work.info()) #同時に表示するためprintで実行
work.company('○×会社','企画部','一般社員')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/47354c4c-2e30-f02a-4bc7-8e9f7c74e107.png)

ちゃんと部署異動になったことがわかる。

##まとめ
Classそんなに使うのかな？defでよくない？と思っていたけど、実際にコードを書いてみるとクラスの継承ができるので、まとめられて便利かも。
ひとまず自分用の演習は終わり。

##参考
https://xtech.nikkei.com/atcl/learning/lecture/19/00108/00005/?P=2
Dagger Hilt alpha版からの移行

いささか気を逸した話題ではありますが......
記録しておきます。

運用中のプロダクトで使用しているDagger Hiltのアップデートを行いました。
**2.28-alpha**から**2.38.1**までアップデートしています。
以下、やったことを順番に記載します。

# build.gradleの編集

hilt-lifecycleが不要になりましたので依存関係から排除します

before

``` build.gradle
    implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$dagger_hilt_version"
    def hilt_lifecycle_version = "1.0.0-alpha02"
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_lifecycle_version"
    kapt "androidx.hilt:hilt-compiler:$hilt_lifecycle_version"
```

after

``` build.gradle
    implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$dagger_hilt_version"
```

# コンポーネントのクラス名変更①

**ApplicationComponent**を**SingletonComponent**に変えます

before

``` ExampleModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object ExampleModule {
}
```

after

``` ExampleModule.kt
@Module
@InstallIn(SingletonComponent::class)
object ExampleModule {
}
```

# コンポーネントのクラス名変更②
**ActivityComponent**を利用しているModuleを**ActivityRetainedComponent**に変更しました。新旧でコンポーネントのスコープが変わっており、あえてActivityComponentにしておく必要がないと判断したためです。
[AndroidDevelopers](https://developer.android.com/training/dependency-injection/hilt-android#component-scopes)では以下のような対応となっています。

ActivityRetainedComponentのスコープ

||新|旧|
|---|---|---|
|クラス|Avtivity|ViewModel|

before

``` ExampleModule.kt
@Module
@InstallIn(ActivityComponent::class)
object ExampleModule {
    @ActivityScoped
    @Provides
    fun provideExampleClient(): ExampleClient {
    }
}
```

after

``` ExampleModule.kt
@Module
@InstallIn(ActivityRetainedComponent::class)
object ExampleModule {
    @ActivityRetainedScoped
    @Provides
    fun provideExampleClient(): ExampleClient {
    }
}
```

# ViewModelの記法修正
**ViewModelInject**がなくなりました

before

``` ExampleViewModel.kt
class ExampleViewModel @ViewModelInject constructor() : ViewModel() {
```

after 

``` ExampleViewModel.kt
@HiltViewModel
class ExampleViewModel @Inject constructor() : ViewModel() {
Haskellで整数の剰余環を実装する

Qiita初投稿です。
Haskellの練習として、整数の剰余環 $\mathbb{Z}/m\mathbb{Z}$ の実装に挑戦してみます。
特に次の2つを目標にします。

* 整数の剰余環を```Num```クラスのインスタンスとして実装する。
* ```a```と```b```で法が異なる場合、```a + b```などはコンパイルが通らないようにする。

# 実装
整数の剰余環を実装するにあたって、以下の記事を参考に致しました。

https://qiita.com/mod_poppo/items/3a37424d299a9f71b757

型レベルの自然数についてはまだ十分に理解できていませんが、とりあえず整数の剰余環は実装できたのではないかと思います。

```haskell:Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}

import Data.Proxy
import GHC.TypeLits

newtype IntMod (m :: Nat) = IntMod Integer

instance KnownNat m => Show (IntMod m) where
  show t@(IntMod x) = show x ++ " (mod " ++ show (natVal t) ++ ")"

instance KnownNat m => Num (IntMod m) where
  fromInteger x = IntMod (mod x (natVal (Proxy :: Proxy m)))
  (IntMod x) + (IntMod y) = fromInteger (x + y)
  (IntMod x) * (IntMod y) = fromInteger (x * y)
  negate (IntMod x) = fromInteger (-x)
  abs = id
  signum _ = IntMod 1

main = do
  let a = fromInteger 12 :: IntMod 101
  let b = fromInteger 34 :: IntMod 101
  print $ a + b
  print $ a - b
  print $ a * b
  print $ a ^ 100
```
```text:結果
46 (mod 101)
79 (mod 101)
4 (mod 101)
1 (mod 101)
```
計算結果が正しいか確認します。

```haskell
main = do
  let a = 12
  let b = 34
  print $ mod (a + b) 101
  print $ mod (a - b) 101
  print $ mod (a * b) 101
  print $ mod (a ^ 100) 101
```
```text:結果
46
79
4
1
```

正しく計算できていそうですね。
ちなみに、4番目に計算している```a ^ 100```ですが、[フェルマーの小定理](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9E%E3%83%BC%E3%81%AE%E5%B0%8F%E5%AE%9A%E7%90%86)から計算するまでもなく```1```であるとわかります。

法が異なる場合も確認してみましょう。

```haskell
main = do
  let a = fromInteger 12 :: IntMod 101
  let b = fromInteger 34 :: IntMod 103 -- 法を101から103に変更
  print $ a + b
  print $ a - b
  print $ a * b
  print $ a ^ 100
```
```text:結果
Main.hs:24:15: error:
    ? Couldn't match type ‘103’ with ‘101’
      Expected type: IntMod 101
        Actual type: IntMod 103
    ? In the second argument of ‘(+)’, namely ‘b’
      In the second argument of ‘($)’, namely ‘a + b’
      In a stmt of a 'do' block: print $ a + b
   |
24 |   print $ a + b
   |               ^
```
ちゃんとコンパイルが通らずにエラーが出ました。

# 感想など

```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}
```
言語拡張が3つありますが、今の所あまり理解できていません。
今回の場合では型レベルの自然数を扱うために用いているのだと思うのですが、それ以外の例も知りたいところです。

```haskell
import Data.Proxy
import GHC.TypeLits
```
こちらもその他の例を知りたいですね。

```haskell
abs = id
signum _ = IntMod 1
```

Haskellで```Num```クラスのインスタンス宣言をする際、ここがどうしても気になるところですね。
特に環をHaskellで実装しようとすると、```(+)```や```(*)```は欲しいけどこの2つはいらないことが多い気がします。
とりあえず、上のように定義しておきました。

今回は型レベルの自然数を用いて整数の剰余環を実装しましたが、より一般の剰余環も同様に実装出来るのかが気になりました（例えば多項式環の剰余環など）。
また、型レベルのプログラミングには興味があるので、今後より詳しく勉強してみたいと思います。
Elixirのobserver.start（ ）で、マシンの論理コア数を確認する

今回は、MacBookの論理コア数を、Ellixirのobserver.start（ ）で確認してみました。

###IExの__*observer.start( )*__関数で調べる

```erlang:IEx
electron@diynoMacBook-Pro erlang_training % iex
Erlang/OTP 24 [erts-12.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Interactive Elixir (1.12.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :observer.start()
:ok
iex(2)>
```

- CTRL-Cを2回叩いて終了する。

```erlang:IEx
iex(2)>
BREAK: (a)bort (A)bort with dump (c)ontinue (p)roc info (i)nfo
       (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution
^C%                                                                                                          electron@diynoMacBook-Pro erlang_training %
```

###次の画面が立ち上がる

![スクリーンショット 2021-11-03 16.38.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/fd485327-238d-d7dc-76ad-b35bdc72751c.png)

- __Logical CPU's : 8__と表示されている
- __*Applicationのタブ*__をクリックすると、起動中のアプリケーションの相互関係が表示される。

![スクリーンショット 2021-11-03 16.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/3f3ee65b-51fd-419c-61c8-78b56d91bf6c.png)

###MacBookのシステム設定画面から、物理コア数を調べる

- デスクトップ画面上部のりんごのロゴマークをクリックし、__「このMacについて」 -> 「システムレポート」を選択__する。

![スクリーンショット 2021-11-03 20.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/1a59dacc-0b2e-a777-9810-13e66bb35558.png)

![スクリーンショット 2021-11-03 16.45.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/ebc04914-96a7-4f81-d008-9fef67c0d73e.png)

- 物理プロセッサの数は、4個だった。

論理コアは、物理コア（プロセッサ）の数より大きな個数になりえる。
１つの物理コアを使う時間を、複数の論理コアに割り当てることができるからです。

今回は、調べた結果、__物理コア数　4、論理コア数8、という構成であること__が分かった。
Could not find a JavaScript runtimeの解決法

環境
---
MacOS BigSur 11.5.2
docker 20.10.6
ruby 3.0.2
rails 6.1.4

エラー
---
CircleCIでbuild中database　setupにて引っかかりました

```
ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.
```
試したこと
---
①https://github.com/rails/execjs にアクセスし、`$ gem install execjs`を実行
②node.jsは元々入っていたがアンインストール、再度インストール
③Gemfileに`therubyracer`と`execjs`を追加、docker-compose run web bundle installまたはdocker-compose build

複数の記事を調べ以上３つを試すもエラーは消えず。

解決法
---
Gemfileに`mini_racer`を追加→docker-compose run web bundle installまたはdocker-compose build

私が試した`therubyracer`や`execjs`ではなく`mini_racer`が最近では使われているようです。
なのでこれからruntimeを動かしたい時は`mini_racer`を使いましょう。

参考
---
https://note.com/konpyu/n/na213a14ad1e3
Docker for Mac で npm を使うと死ぬ時の対処

## 概要
死にます。

```
$ docker run node:latest npm -v

#
# Fatal process OOM in Failed to reserve virtual memory for CodeRange
#

qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
```

なおここでは `:latest` を使っています (執筆時点で `node v17.0.1`) が、試した限りでは `:16-buster`, `:16.13-buster` でも同様の事象が発生しました。後述する issue では `14` 系でも起こっているようです。

## 環境
- mac OS Big Sur 11.6
- Mac mini (M1, 2020) 16 GB
- Docker Desktop: 後述

## 解決
Docker for Mac の [issue](https://github.com/docker/for-mac/issues/5831) に上がっていました。

結論から言うと、筆者の場合は [コメント](https://github.com/docker/for-mac/issues/5831#issuecomment-939970734) を参考に Docker Desktop のバージョンを上げることで解決しました。 `4.1.1` に更新後、正常に動作することができました。

ただ、更新前のバージョンを確認しなかったため、対象となるバージョンは不明です。コメント主の場合は `v4.0.1` らしいです。

issue についている他のコメントを見ると、使用するイメージのバージョンを下げたりすることでも解決できる場合があるみたいですね。

## まとめ
gg ると結構頻発している問題のようですが、日本語のサイトはないように見えたので残しておきます。

以上です。
エクセルのA1形式の列を0ベースの10進数にする

# エクセルA1の列を0ベースの10進数にしたい
## なぜ？
エクセルでデータ見ているのに、pandasのusecolsで絞りたいときは0ベースの10進数を使う。
いちいち「これって…10進数で言うと何?」ってなる時がある。

## 実装例
```python
def xlcol_to_deci(string:str, zero_base:bool=True)->int:
    # アルファベット列挙する　['A', 'B', 'C', ...'Z']
    alphabet_order = [ chr(i) for i in range(65, 91) ]
    # 対応表を作る {'A':1, 'B':2, 'C':3, ...'Z':26}
    table = { chara:i for i,chara in enumerate(alphabet_order,1) }
    # 文字列を逆転させ、1桁目から変換を始める (enumerateがstepを書けず、iを活用できないため)
    # 対応数値 * 26 ** i 
       # iは文字列の長さ毎に増えていく。 最初は0なので26**0 = 1となり、対応数値 * 1
       # 3文字目はi=2で、対応数値 * 26**2
    sum_ = sum([ table[one_letter] * (26**i) for i, one_letter in enumerate(reversed(string)) ])
    return sum_ - int(zero_base)
```

参考: アルファベットを列挙する
https://qiita.com/ell/items/6eb48e934a147898d823
トラブル切り分けの成功時に何をやったのかの記録～formの送信先間違えてたよ編～

#前置き
最近Djangoアプリの開発を趣味でやっています。
初心者につき、トライ１に対してエラー１０くらいの試行錯誤中で、なかなか完成しないですが
本日2021年11月3日、文化の日は丸一日エラーと向き合っていたのでせっかくなので記録しておくことにしました。
自己満足記事かつQiitaの投稿テストも兼ねています

#事象
メニューの自動化アプリを作っていますが、メニューの作成の際に
ModelFormのsave()メソッドが何をやっても効かない。
一方でサインアップで使うユーザーの方のsave()メソッドは正常に作動する。

#予定していた処理の流れ
１．ユーザーがログイン状態でメニュー登録画面に移動
２．リクエストがGETであればテンプレートでハンドリングしてform.as_pでメニューのフォームを出す(urls.py->views.py->templates/myapp/menu_settings_create.html)
３．ユーザーが入力して送信ボタンを押すとviews側で受けてDBに登録し、登録完了画面にページ遷移する

#やったこと
##ググって同様の事例がないか確認
キーワード「Django Modelform save できない」とかでググってみた。
同様の事例は見当たらなかった。

##同様の処理でうまくいっている箇所との比較確認
これに数時間かけたが、同じ書き方にしても何故かできない。

##送信データの確認
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246479/1b22a2e2-f182-b54c-1b92-203ce3da8687.png)

POSTで送っているデータそのものがおかしい可能性を考えた。
そうなったときにDjango側でどう確認すればよいのかわからなかったのとWireshark覚えたてで使いたかったのでWiresharkを使用。
予想に反してPOSTでちゃんとデータが送れていた。(画像の下半分の"testgohan3"のところ)

##受信側DBの確認
DBの受信している箇所をロギングしてみた。
この人の記事を参考にしてみた。
https://qiita.com/fumihiko-hidaka/items/0f619749580da5ad9ce5
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246479/e6efd514-045e-6d2f-2e7d-3951383e7094.png)

画像は最終的にうまくいったときのものだが、デフォルトでこのようにrunserverしてあるターミナルの標準エラー出力にDB書き込み時のログが出るようになる。（それとmanage.py shell実施時にも出る）

そして確認の結果、このログが問題の箇所では出ていない事がわかった。
すなわち、POSTしているデータは正しいのだが、DBに書き込み処理が走っていない事がわかった。

##POST送信指定箇所の確認
views.pyは穴があくほど確認していたが、テンプレートのhtmlの方の確認があまりできていなかった。
そして、formactionの指定先がviewsで受ける宛先と異なっていることに気づいたので、修正

#結果
formactionの指定をviewsで受ける宛先と同じにしてうまくいった。

#まとめ
凡ミスではあったが、アプリ開発のコードは量が多いゆえ色々と見落としが発生するのも仕方ない。
焦らずに一個一個確認していくことが大事。
（本当は凡ミスをしないのが一番良い）
[Python]途中まで素数を求める方法[オイラー]

# はじめに
備忘録として残します🐍
Python3環境下にて、是非お使いください🎸

# 素数とは
素数とは、1とその数字以外に割ることができない孤独な数字です。
これは、ある素数NはNはN-1の整数倍で表すことができないという意味でもあります。
素数係数関数(Π(x))や素数定理などの発見はあるものの、数式で求めることはできません。
暗号方式の一つであるRSA暗号は、100桁以上の素数の難発見性の性質を利用しています。

現在の主流なIT技術にも貢献している素数ですが、
nが整数のとき、-40≦n≦40の範囲で素数を生成する式が存在します。

今回は、生成式のコーディングとn=0~40の出力結果を参考までに御覧ください。
素数を詳しく知りたい方は、数学者ガウスやオイラーについて調べてみるといいでしょう。

- [参考]RSA暗号とは：https://qiita.com/YutaKase6/items/cd9e26d723809dc85928

>※n^2-n+41は二次関数で、n=-1のとき43、n=-2のとき47という具合に
対称性が保証されているため、出力結果を省略いたします。

▶外部ライブラリにつき、予めインストールを要します。（以下、入力例）

```bash:bash/zsh
conda install sympy　#エラーが起これば、下のコマンドを実行してください。
pip install sympy 
```

# 本編
## 数式
```math
オイラー 素数生成式（Lucky Numbers Of Euler）:  f\left(n \right)= n^{\!2}-n+41
```
## コーディング
```python:python
from sympy import *
n = Symbol("n")
seq = sequence(n**2 - n + 41, (n,0,40))

#以下、出力
print([int(i) for i in seq])
```
>出力結果
[41,41, 43, 47, 53, 61, 71, 83, 97, 113, 131, 151, 173, 197, 223, 251, 281, 313, 347, 383, 421, 461, 503, 547, 593, 641, 691, 743, 797, 853, 911, 971, 1033, 1097, 1163, 1231, 1301, 1373, 1447, 1523, 1601]

# References
## More Info
- About Sympy:https://www.sympy.org/en/index.html
- About How to Use Sympy: https://note.nkmk.me/python-sympy-factorization-solve-equation/

## About me

- SNS landing page(lit.link): https://lit.link/myon123
- GitHub: https://github.com/myon-bioinformatics
- Qiita: https://qiita.com/myon-bioinformatics
- Twitter(仕事用): https://twitter.com/myonitbusiness
- Twitter(プライベート用): https://twitter.com/myonmusicpgdev
- tumblr: https://www.tumblr.com/myon-helloworld
- Reddit: https://www.reddit.com/user/myon_reddit
- Pixiv: https://www.pixiv.net/users/87109499
- YouTube(Composer): https://www.youtube.com/channel/UC22_pvlkQynYsrSpAfyzEzA
- SpeakerDeck: https://speakerdeck.com/myon_bioinformatics
- マシュマロ(質問箱): https://marshmallow-qa.com/myonitbusiness

- LINE: https://line.me/R/ti/p/@661cphit
- Microsoft TechNet: https://social.msdn.microsoft.com/Profile/myon.TechNet
- プロフカード: https://profcard.info/u/ziUhwgZihSSTLZdqPZ0gz5aru6A3
- ニコニコ動画(niconico): https://www.nicovideo.jp/user/126513036
- Wish List: https://www.amazon.co.jp/hz/wishlist/ls/290EJPJ3PAS73?ref_=wl_share
- 転職ドラフト: https://job-draft.jp/users/58541
- RESUME.id: https://www.resume.id/myon
- Wantedly: https://www.wantedly.com/id/myon123
- Mastodon: https://mstdn.social/@myon
- mixi: https://mixi.jp/show_profile.pl?id=68...
- Instagram: https://www.instagram.com/myonmusicpgdev
- Pinterest: https://www.pinterest.jp/myonmusicpgdev
- Forkwell: https://portfolio.forkwell.com/@myon

https://twitter.com/myonitbusiness/status/1573533239133671424


https://twitter.com/myonitbusiness/status/1587393241371987968
djangoのビューを関数ベースからクラスベースに書き換える

今回のお題
-
今回は、djangoのビューを関数ベースからクラスベースに書き換えていきます。

私は今まで関数ベースビューしか書いたことがありませんでしたが、クラスベースに慣れておいた方が便利だという意見をあちこちで目にしたので、良い機会かなと思いました。

目次
-

- クラスベースビュー・関数ベースビューとは
- クラスベースに変える場合の変更点
- 設定項目が少ない場合の書き方
- 終わりに

クラスベースビュー・関数ベースビューとは
-
まずは最初に用語の説明をしておきます。

そもそもビューとはリクエストに応じて必要な変数やテンプレートを用意するためのものですが、この必要なものを用意するための処理を関数として表しているものを関数ベースビューと呼びます。

```python:views.py
# 関数ベースビュー
def index(request):
  books = Book.object.all()
  return render(request, "book/index.html", { "books": books }
```
いつものやつですね。

この書き方は他のフレームワーク(Ruby on RailsやPHP Laravelなど)とほぼ同じなので馴染みがあるという方も多いですし、実際のところ初心者向けの書籍では関数ベースビューから入るものが多いと思います。

ついでに、関数ベースビューに対応したルーティングも載せておきます。

```python:project/urls.py（プロジェクト側)
urlpatterns = [
  path("index", include(("book.urls", "book"))),
]
```
```python:book/urls.py（アプリ側)
urlpatterns = [
  path("index", views.index, name="index"),
]
```

これと同じものをクラスベースビューで書くと以下の通りになります。

```python:views.py
from django.views.generic import TemplateView # 他にも色々とimportはありますが省略

class IndexBookView(TemplateView):
  template_name = "book.index.html"

  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    books = Book.objects.all()
    context["books"] = books
    return context
```
```python:book/urls.py
urlpatterns = [
  path("/index", views.BookIndexView.as_view(), name="index"),
]
```

とりあえず全体像が掴めたら、変更点を見ていきます。

クラスベースに変える場合の変更点
-
クラスベースに変える場合の変更点（というか記述するべき項目）は、

- views.pyの中にXxxxviewというクラスを作る(この際にTemplateViewクラスを継承させる）
- そのクラスの中で`template_name`と`get_context_data関数`を定義する。
- ルーティングで、ビューの関数ではなくテンプレートビュークラスを呼び出すようにする。

です。

最初のクラスの作成が以下の部分。

```python
class IndexBookView(TemplateView):
```
`TemplateVeiw`クラスを継承しています。

次に`template_name`を定義し、呼び出したいテンプレートファイルの相対パスを記述します。

```python
template_name = "book.index.html"
# IndexBookViewが呼ばれた場合には"book/index.html"が表示される。
```

最後に`get_context_data`関数でテンプレートに渡す変数を定義しています。

クラスベースビューではcontextという箱に入って変数が受け渡されるので、そこに必要なものを追加してあげる形ですね。

```python
  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    books = Book.objects.all()
    context["books"] = books
    return context
```
ちなみに、この`get_context_data関数`は親クラス(TemplateViewクラス）にも存在しているので、関数の定義がオーバーライドの形を取ることに注意してください。

これでビューの方は完成なので、ルーティングからテンプレートビューを呼び出せるようにすればOKです。

```python
urlpatters = [
  path("index/", views.IndexBookView.as_view(), name="index"),
]
```
第二引数は`views.テンプレートビュークラス名.as_view()`という形式になります。

設定項目が少ない場合の書き方
-
クラスベースビューの基本的な書き方は上記の通りで、`views.py`で定義したクラスを`urls.py`で呼び出すという形になります。

しかし以下のように記述することで`views.py`での処理を省略し、`urls.py`への記述のみで完結させることができます。

```python
urlpatterns = [
  path("hoge", TemplateView.as_view(
    template_name = "hoge.html",
    extra_context = { "fuga": "fuga" }
  ), name="hoge"),
]
```

要は

- 新しいテンプレートビュークラスを用意せずにデフォルトのTemplateViewをそのまま使う。
- `template_name`と`extra_context`を`as_view`のキーワード付き引数として渡す（`extra_context`はcontextに追加する変数)

ということです。

もちろん変数を用意するロジックとルーティングのロジックは分離させるのが原則なので、あくまでも簡単に書ける場合の処理ですが。

終わりに
-
以上がクラスベースビューの実装手順でした。

他の言語ではあまり見ない概念ですが、早く慣れていきたいですね。
「SESを辞めたかった理由」と「実際に辞めてみて思うこと」

## SESを辞めたかった理由
僕は28歳のときにITの知識無しの状態でSESの会社に転職しました。
入社してからしばらくの間は毎日とにかく仕事を覚えるのに必死だったんですが、日に日にスキルが身についていくのを実感できて楽しかったのを覚えています。
ですが、1年2年と経験を積んでいくにつれて少しずつ客先常駐（SES）という働き方に疑問を持つようになって、入社から5年が経った今年の5月に退職して社内SEになりました。

SESという働き方への疑問は具体的には以下のようなところです。

 * 自分の作ったシステムが役立ってるかどうか分かりづらい
 * 自分の会社に所属してるという感覚がない
 * 自分の頑張りが自社にきちんと評価されない
 * 自社の作業は定時後にやる（しかも残業扱いにならない）

恐らく今SESエンジニアとしての働き方に不満のある方々と同じような内容だと思います。

## 実際にやめてみて思うこと
結論から言うと、SESのときに感じていた疑問や不満はきれいさっぱり解決しました。
システム作りは業務担当の人と相談しながら進めて、リリース後は実際に使った感想がダイレクトに返ってきます。
自分の頑張り次第で会社の業績アップに貢献できる環境があって、結果を出せればきちんと評価してもらえます。
基本的に残業はなくて、システム作り以外の作業はもちろん定時内にやればOKです。

## 僕は転職して世界が変わりました！
SESを否定するつもりはありません。
SESを必要としている会社がたくさんあるのも事実ですし、SESとしての働き方がしっくりくる人もいると思います。
ですが、僕の場合は社内SEに転職して本当によかったと思ってます。
僕が実際にどうやって転職したのかは↓の記事に書いたので、よかったら覗いてみてください。

→[客先常駐（SES）のITエンジニアが会社を辞めて理想的な働き方を実現する方法と手順][1]
[1]:https://domona.info/ideal-job-change/

もし今後、社内SEとしての働き方に思うことがあればまた更新します。