OmniAICreator/Qiita-1.07M huggingface dataset:
【SQLServer】データベース内の指定したカラム名を持つテーブルおよび詳細情報の検索

カラム名からデータ型だったり有効桁数だったり確認したいなーって時のコピペ用に。

```sql:
select
	t.name as TableName
    , c.name as ColumnName
    , type_name(user_type_id) as 属性
	, c.precision as 有効桁数 
	, c.scale as 小数点以下桁数 
from sys.tables as t
	inner join sys.columns as c
		on t.object_id = c.object_id
where c.name = 'hoge' -- 任意のカラム名
order by TableName, ColumnName
;
```

テーブル定義書に必要な項目名、データ型なんかをとってきたーい！
そんなときのためのクエリもついでにおいておきます。

```sql:
select
	c.name as ColumnName
    , type_name(user_type_id) as 属性
    , max_length as 長さ
	, c.precision as 有効桁数 
	, c.scale as 小数点以下桁数 
    , case when is_nullable = 1 then 'YES' else 'NO' end as NULL許可
from sys.tables as t
	inner join sys.columns as c
		on t.object_id = c.object_id
where t.name = 'fuga' -- 取得したいテーブル名
order by ColumnName
;
```
その他に取りたい要素があった場合の参考
https://docs.microsoft.com/ja-jp/sql/relational-databases/system-catalog-views/sys-columns-transact-sql?view=sql-server-ver15
Firebase Hostingで変更が反映されずにデプロイされてしまう時に確認すること

#概要
Angularアプリを作成し、firebase hostingでアプリをデプロイしたのに、ビルドした内容が反映されていない事象に出くわしました。
解決策を調べてみるも、キャッシュ云々やら、`firebase.json`のpublicの箇所がdist云々になっていない等の記事がほとんどで、それを試しても結果は変わらない…

#原因
`Firebaseコンソール > プロジェクトの設定ページ > 全般タブ`　の下の方のマイアプリにデプロイしたいアプリが登録されていると思うのですが、
ここの`アプリのニックネーム`と開発環境内の`.firebaserc`ファイルに書かれているアプリ名が同じになっていないことが原因でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169561/56e0b430-d0b5-bc6b-8f12-43b7e33327dc.png)

```:.firebaserc
{
  "targets": {
    "angular-realtimedb-demo": {
      "hosting": {
        "angular-realtimedb-demo": [
          "angular-realtimedb-demo"      ←ココ！
        ]
      }
    }
  },
  "projects": {
    "default": "angular-realtimedb-demo"
  }
}
```

#まとめ
プロジェクト作成時に「ニックネームを登録」なんて書かれていたので、「コンソール上で識別するためくらいの設定かな？」と安易な気持ちで`client-app`みたいなニックネームにしていました…

お恥ずかしいミスだったのであまり記事にしたくはなかったのですが、他にもハマっている方がいるのではないかと思い、投稿しました。

誰かの時間が失われずに済んだのなら幸いです。
[Git]不要なリモートブランチをコマンド+ちょっと手動で一括削除する

長い間整備されていないリポジトリに対して、いくつかのブランチを残しつつ、大部分のブランチを削除する作業をしたので、メモを残す。


やり方は以下。

1. コマンドで、全既存ブランチ名をテキストファイルに書き込む。
1. 手動で、テキストファイルから残したいブランチを削除する（削除したいブランチを残すことに注意）。
1. コマンドで、テキストファイルをインプットとして、ブランチを一括削除する。

※わざわざ一度テキストファイルに書き込んでから消したいブランチを選別している理由は、今回の場合残す必要のあるブランチが少数かつ特にそれぞれに規則性があるわけではなかったので、テキストファイルから目視で選別するのが効率的だと考えたからだ。逆に、消したいブランチ（あるいは残したいブランチ）の数が多すぎて手動でのピックアップが大変だったり、ブランチに規則性があって上手いことコマンドなどで一括指定できる場合はそうすれば良い。

```bash:削除方法
# ブランチ名一覧を一旦テキストファイルに書き込む。
git branch -a -r --sort=refname --format="%(refname:short)" > deleteBranches.txt

# deleteBranches.txtから残したいブランチを取り除く（削除したいブランチを残すことに注意）
# deleteBranches.txtからブランチ名先頭の“ref/remotes/origin”を削除しておく。VSCodeとかなら複数行操作ができるので一気に消せるはず

# cat + xragsを使って一括削除。ブランチ数が多い場合はコマンド実行後に一定時間待つ必要あり。（参考：消去ブランチ数200程度で3~5分かかった）
# originのところは人によって異なる可能性あり。適宜指定する。
cat deleteBranches.txt | xargs git push --delete origin
```


ちなみに削除後はリポジトリをローカルにクローンしている人全員に、リモートと状態をあわせてもらうことなると思います。コマンドは以下です。GUIのGitクライアント使ってる場合は普通にFetchボタン押せば大丈夫だと思います。

```bash
git fetch --prune
```


#### 既存ブランチの一覧化  

複数人で開発しているリポジトリだと、どのブランチを消せばよいか事前にメンバーに聞く必要があると思います。メンバーも忙しいし昔のことは覚えてないと思うので一覧表をつくってあげると良いでしょう。以下の様なコマンドで、作成者、ブランチ名、最終更新日の表をさっとつくれます。

```bash
# --sort, --formatの中身は適宜調整してください。
git branch -a --sort=authorname --format="%(authorname),%(refname),%(authordate:short)" > branches.csv
```

#### xargsの解説

`xargs`は標準入力やファイルからリストを読み込み、コマンドラインを作成して実行するコマンドです。ここではcatの結果をパイプで渡してます。

ちなみに、`xrags`の後に続くコマンドの引数によって動作が変わります。今回の`git push`コマンドのような引数を1つ受け取るコマンドの場合は、同じコマンドが行数分実行されます。

```bash
git push --delete origin branchA
git push --delete origin branchB
git push --delete origin branchC
（...以下渡された行数分実行される）
```

引数が複数のコマンドの場合は、1行が1引数の形でコマンドが実行されます。便利ですね`xargs`。
Power AutomateでRSSフィードをTeamsに通知する

昔これ（表題）を実現させるために色々四苦八苦したんですが、
簡単なテンプレートを見つけたので動作するか試してみます。

四苦八苦した時のメモ↓↓↓

https://qiita.com/TakahiRoyte/items/9987efdb980ef2e1b668

## 作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/f745b097-075e-5206-a76e-0c548066f32c.png)

この画面の右上の検索ボックスから、「RSS Teams」と検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/e0f8299b-47fc-ca1d-6a55-818866d18663.png)

いくつか使えそうなのがでてきました。
右下の数字がテンプレートが使われた回数とかなのかな、と勝手に想像。
Teamsへの投稿できそうなので一番多い以下の名前のテンプレートを選択。
「RSSフィードが公開されたときにTeamsにメッセージを投稿する」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/94cfeb4e-3759-b791-3c52-8c68d86844f4.png)

すごい、わかりやすいです。続行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/6defc7da-dc80-6db1-5c1b-0c98e4820f73.png)

TeamとChannelは一旦自分の個人Teamで動作確認。
ここからテストします。

## テスト

実際にこの記事を発行して動作するかを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/81052f6a-65ad-f4f3-0ac8-4c10540a9559.png)

うまく行ってそうです。Teams確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/326943cb-f8f1-8a4f-ff95-01101a223d49.png)

投稿されてる！が、URLがハイパーリンク切れてたり、概要入れたから長くなってたりイケてないですね。
投稿メッセージを修正していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/3a667325-073c-2d2b-6165-46aa9736ed01.png)

こんな感じに修正して、問題なく動作しました。
TLS Allocator ALLOC_TEMP_THREAD, underlying allocator ALLOC_TEMP_THREAD has unfreed allocations, size 102 のエラー解消方法

#はじめに
まだUnityを勉強して間もない人間ですので、認識不足の部分があるかもしれません。
あらかじめご了承ください。

#エラー内容
コードを書き込んでいたら、急にコンソールに以下のエラーが表示されてきました。
日本語で検索しても、まあ出てこない。

```TLS Allocator ALLOC_TEMP_THREAD, underlying allocator ALLOC_TEMP_THREAD has unfreed allocations, size 102
```

#参考URL
以下のURLを参考に、Google先生に翻訳してもらったところ
読み込みし直せば治るよ！ってことでした。

https://forum.unity.com/threads/debug-stack-leak-how-to-fix-it.660004/

#解消方法
UnityメニューのAssets＞Reimport ALL を選択
→再度ゲーム実行

![スクリーンショット 2022-02-04 18.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521365/88ee6a7d-aa94-425f-bf3d-6d4b5dc25a30.png)


意外と簡単。
これで幸せになれる人が増えますように。
MSGからPSTへのコンバーター - MSGファイルをOutlookに変換する

<p>すべてのWindowsOutlookユーザーが知っているように、複数のMSG電子メールファイルをOutlook PST形式に変換することは一般的な問題ですが、多くのユーザーはそれを実現する方法を知りません。したがって、このパートでは、MSGをPSTに変換するためのいくつかの手法について説明します。</p>
<p>MSGおよびPSTファイルは、ほとんどのコンピューターユーザーによく知られています。 OutlookのMSGファイルとPSTファイルのファイル拡張子は同じですが、内容が異なります。 PST（Personal Storage Table）ファイル形式は、Outlookがすべてのデータを保存するために使用します。これらのファイルは情報の保存にも使用されますが、ヘッダーと本文のテキスト、添付ファイル、送信者と受信者の名前、および受信者に関するその他の情報を含むOutlookの単一のメッセージなどの1つだけです。</p>
<h2>ユーザーがMSGをPST形式に変換したいのはなぜですか？</h2>
<p>これらすべての懸念事項を確認して、MSGファイルを一括でPSTに変換したい人の要件を見てみましょう。</p>
<p>こんにちは、私は現在、ガジェットを含むプロジェクトに取り組んでいます。プロジェクトの更新を受け取る唯一の方法は、同僚から送られてきたMSGファイルを使用することでした。 50,000個のMSGファイルの近くで何かを受け取りましたが、それらを追跡することはますます困難になっています。 PSTファイル形式は私にとってより管理しやすいので、MSGファイルをそれに変換するための解決策を探しています。何卒よろしくお願い申し上げます。</p>
<p>こんにちは、メールボックスフォルダをクリアしているときに、大量の情報がMSGファイルに含まれていることに気付きました。 Microsoft Outlook for Windowsは、私が使用しているソフトウェアです。手動でアプローチしようとしましたが、完全に失敗しました。一方、私のデータは何もしません。尊敬される選択肢は、私が探し求めているものです。信頼性が高く、エラーのないソフトウェアを見つけることは可能ですか？</p>
<h2>MSGファイルをPST形式に変換する方法は？</h2>
<p>その結果、OutlookアプリケーションにはMSGファイルをPSTファイルに変換するための変換オプションが含まれていないため、OutlookでMSGファイルをPSTファイルに変換する手動の方法はありません。この窮状に直面したとき、専門的で手間のかからない、費用効果の高い選択肢を選ぶのが賢明でしょう。<a href="https://www.mailsware.com/jp/msg-converter.html"> <b>MSGコンバータアプリケーション</b></a>は、1つのパッケージですべての変換ニーズを満たすため、MSGファイルをPST形式に変換するのに適した選択肢です。</p>
<p>ここで概説されている手順に従うと、複数のMSGファイルをPSTに変換するのは簡単で簡単なプロセスです。</p>
<p>開始する前に、MSG to PSTConverterをコンピューターのWindowsオペレーティングシステムにダウンロードしてインストールします。</p>
<p>プログラムをダウンロードしたら、使用する前に正しくインストールする必要があります。</p>
<p>[フォルダーの選択]オプションを選択すると、OutlookMSGファイルを保存するフォルダーを選択できるようになります。</p>
<p>このプログラムは、現在開いているすべてのMSGファイルとフォルダーを左側のパネルに表示します。</p>
<p>プレビュー全体を表示するには、ドロップダウンメニューから[メール]を選択します。さらに、添付ファイルをOutlookPST形式に変換する前に保存するオプションがあります。</p>
<p>次に、[変換]をクリックし、ドロップダウンメニューから保存形式として[PST]を選択します。</p>
<p>すべての設定が完了したら、宛先ディレクトリを選択し、[変換]ボタンをクリックして変換プロセスを開始します。</p>
<p>それがすべてです。プログラムは、多数のMSGファイルをPST形式にすばやく変換し始めます。この操作を完了するのに必要なのはほんの数秒です。</p>
<h3>主題の最後の言葉</h3>
<p>この記事は、多数のMSGファイルをPST形式に変換する必要がある人々を支援することを目的としています。推奨ソフトウェアを使用している場合は、数回クリックするだけでこのアクティビティを完了することができます。</p>
<p>このエッセイを楽しんでいただけたでしょうか。</p>
<p>ご不明な点がございましたら、いつでもお気軽にお問い合わせください。</p>
FileMaker Server の Data API で CORS 対応

# はじめに
## 対象読者
* [Claris FileMaker](https://www.claris.com/ja/) ユーザ
* とりわけ Windows Server において FileMaker Server を用いて管理している

## 環境
* Claris FileMaker Server 19.4.2
* Windows Server 2016 Datacenter Edition

## 状況
* 自前の WEB サイトから Data API を呼び出している
* 自前の WEB サイトのドメインと FileMaker Server のドメインとが異なる
* 上記の場合、CORS 対応が必要となる
* Windows Server ( IIS ) 環境での CORS 対応がややしんどい、知らないと詰む

## CORS とは？
* [MDN Web Docs - オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)

# ことのきっかけ
## 補足
* この段については、どうしてこの記事を書くに到ったかの経緯説明です。読み飛ばしていただいても構いません

## FileMaker Server の ver.up 時に……
* FileMaker Server 19.4.1 → 19.4.2 への updater を実行してアップデートし、再起動した
* その後、バグなのか何なのか、Admin Console へのログインができなくなる
    * パスワードが通らない
    * PIN 番号も通らない
    * 認証情報が全部吹っ飛んでいる……？

## FileMaker Server を再インストール
* 上記のため、いたしかたなく一度アンインストール → 再インストール
* この時点で、そもそもこのサーバで CORS 対応をしていたという事実を、既存メンバーは誰一人として認識になかった……
    * 以前にこのサーバで CORS 対応をしていたメンバーが育休中……

## WEB サーバ側で Data API が読めない！
* 後日、問題が発覚。API 通信ができずに機能不全
* Chrome の console を見ると CORS 問題のもよう……


# 対応法
## IIS CORS Module のインストール
* これが必須となる。以前に一度インストールされていたら不要
* もし初めて CORS 対応を入れる場合にはインストールが必要
* https://www.iis.net/downloads/microsoft/iis-cors-module
  * たまにこのページが開けなくなることがあるけれど、根気強くアクセスしていると、またアクセスできるようになる……

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37739/18836678-87e0-1005-93c8-66f922540e5a.png)

## web.config への CORS 許可の追記
* `C:\Program Files\FileMaker\FileMaker Server\HTTPServer\conf` に存在している
* IIS のアプリケーションプールにある HTTP リクエストヘッダ付与あたりと連動しているので、IIS 側で設定を変えると自動で変更される。基本的には、あまり不用意に弄らない方が良い
* 以下のように `cors` ブロックを `</system.webServer>` の手前の位置に追加。管理者権限でおこなう必要がある

```config:web.config
    <security>
      <requestFiltering allowDoubleEscaping="true">
        <requestLimits maxAllowedContentLength="4294967295" />
      </requestFiltering>
    </security>
    <cors enabled="true" failUnlistedOrigins="true">
      <add origin="*">
        <allowHeaders allowAllRequestedHeaders="true" />
        <allowMethods>
          <add method="GET" />
          <add method="PATCH" />
          <add method="POST" />
          <add method="PUT" />
          <add method="DELETE" />
        </allowMethods>
      </add>
    </cors>
  </system.webServer>
</configuration>
```

* FileMaker Server をアンインストール → 再インストールすると、この箇所の記述が消えます。ので、再度記述を挿入してあげる必要があります。いかにも忘れがち！

## アプリケーションプールの再起動
* 上記の追記と保存が完了したら IIS 上でアプリケーションプールの再起動をおこなえば、完了


# おわりに
## 雑感
* 公式ドキュメントに記載しておいて欲しいのですが……！

## 参考
* [Matatiro Solutions - Cross Origin Support For The FileMaker Data API](https://msdev.co.uk/fms-cross-origin/)
* [Claris Community - How do you allow for CORS when using the DATA API?](https://community.claris.com/en/s/question/0D50H00006f0bAdSAI/how-do-you-allow-for-cors-when-using-the-data-api)
クローゼットの自動換気システム

## 背景

クローゼットの中、タンスの中は湿気がたまってしまってカビが生えると言われています。

試しにクローゼットの中にswitchbotの温湿度計を設置して相対湿度のデータを取ってみたところ、80%を超えることがありました(縦軸が湿度(%))

 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/ddb23bdd-9d4a-21b9-9fb0-2e8cd3e20e02.png" width="70%">


どのくらいの湿度になるとカビが生えやすいのか明確な基準値は見つけられなかったのですが、70%とか80%以上だとよくないと書いてある記事がありましたので、あまりよくない状態な気がします。

冬場は部屋を暖かくして加湿器をつけるので、寒いクローゼットの中の湿度がとんでもなくあがるようです。

## 対策

というわけで、自動換気システムを作りました。
とても簡単です。
プログラミング不要です。

switchbotのシーンという機能を使って、
湿度が高くなるとスマートプラグがONになるように設定します。
そしてそのスマートプラグにUSBファンをつけるだけ。

#### 必要なもの

| No. | 機種 | 費用 |
|:-:|:-:|:-:|
| 1  | switchbot温湿度計  | 1,680円  |
| 2  | switchbotスマートプラグ  |  1,980円 |
| 3  | [USBファン](https://www.amazon.co.jp/gp/product/B08G8RN2PD/)  | 1,513円  |
* スマートプラグ→USB変換が別に必要です（電源プラグで動くファンやサーキュレーターを使えば不要です）
* あとは必要に応じて延長コードなど
* ちなみに、私は温湿度計2個、スマートプラグ3個、USBファン3個使っています。
* 大きな除湿器とか買うより安くて確実な方法な気がします（除湿器は水捨てたりするのがめんどくさいし）

#### 作り方

* switchbotの温湿度計とスマートプラグの初期設定します（詳しくは買ったときについてくる説明書を参照。簡単です。）
* switchbotの温湿度計をクローゼットの湿度が高そうな場所に置きます
* USBファンを空気を入れ替えられるような場所に置きます
* USBファンをスマートプラグにつなぎます
* switchbotのシーンで、湿度76%以上の場合スマートプラグをONにする設定を入れます
    * 70%以下になったらスマートプラグをOFFにする設定も入れておきます
    * 少し感度が悪くても80%にならないように76%にしています

#### ヒント

* 私は無印のポリプロピレン衣装ケースを横にも縦にも並べて使っているのですが、衣装ケースの裏側にホームセンターで幅12cmの木の板を買ってきておいて12cmの隙間をクローゼットの奥に作り、その板の上にUSBファンを設置しています
* 衣装ケースの奥だけでなく横にもおいているので、横から入った空気が裏側を回って、裏側の湿度の高い空気を換気しています（下の画像参照）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/052c99e4-a9fa-812e-9bf2-a7e31ca0a2b8.png" width="300">

* USBファンは強い風にすると少しうるさいので、気になる方は弱めの風にして時間をかけて換気する方法がよいのではないかと思います
* サーキュレータは大きくて衣装ケースの裏に置けなかったのでUSBファンにしましたが、サーキュレータをつなぐのでもいいと思います
* switchbotのシーンは閾値になったらすぐに動くわけではなく少しタイムラグがあるので、実際は閾値よりちょっと超えることもありますが、カビさんもそこまで急激に増えないと思うので、このくらいのタイムラグは問題ないかなと思っています。私は閾値を少し下げて設定しています。
* switchbotのシーンで複数のスマートプラグをONにすることで、複数のUSBファンを一度につけたり消したりできます
* データの取得はswitchbotのアプリでできますが、google spreadsheetに残すこともできます（下リンク参照）

https://qiita.com/tosshie/items/0b6a93a8e351cd801321

#### 導入結果

こんな感じの差分です。

* 左が換気システムが動いているとき。湿度76%で換気システムが動くようになっています。76%は少し超えてしまうものの、80%にはならないようになっています。
* 右が換気システムが動いていないとき。80%を超えることもあります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/e9941b93-3b84-b7e4-212e-1fc686f30134.png" width="40%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/ddb23bdd-9d4a-21b9-9fb0-2e8cd3e20e02.png" width="40%">
【Project Euler】Problem 73: 範囲内の分数の数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題73：範囲内の分数の数

原文 [Problem 73:Counting fractions in a range](https://projecteuler.net/problem=73)

**問題の要約：分母が$d \le 12000$の既約真分数が$1/3$と$1/2$の間にいくつあるかを求めよ**

例題として挙げられているのが$d \le 8$のときで、解は3つです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/9df815e6-29c8-91e5-25b7-e5169389da7b.png)

素直に考えると以下の式になるので

```math 
\frac{1}{3} < \frac{n}{d} < \frac{1}{2}  \\
各辺d倍して　\\
\frac{d}{3} < n < \frac{d}{2}  \\
```

この条件を満たし既約分数なので$gcd(n,d)=1$を条件に数を数えます。

```python 
N=12000
print(f"Answer: {[gcd(n,d)==1 for d in range(2,N+1) for n in range(floor(d/3)+1 ,ceil(d/2))].count(True)}")
```

### Stern–Brocot treeを使った解法

別解として[Stern–Brocot tree(Wikipedia)](https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree)を使う方法があります。日本語のWikipediaはないですが[ファレイ数列(Wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%83%AC%E3%82%A4%E6%95%B0%E5%88%97)に少しだけ説明があります。

以下のような性質があるので、範囲内の既約分数をすべて生成することが可能なのでまさにこの問題どおりです。

* 2つの既約分数の分子どおし、分母どおしを加える事を繰り返して作られる木
* できた分数も既約分数
* すべての分数を網羅する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/43977060-a54a-b93b-1649-0b2fdeb5762f.png)

例えば、以下のプログラムでは$d<8$の既約真分数を範囲を指定して列挙します。

```python 
### Stern–Brocot tree
def sternBrocot(nl, dl, nr, dr):
  nm, dm = nl+nr, dl+dr 
  if dm > Dmax: return []
  return sternBrocot(nl, dl, nm, dm)+sternBrocot(nm, dm, nr, dr)+[(nm, dm)]

Dmax = 8
rpf = sternBrocot(0,1,1,1)　# 0/1 < n/d < 1/1
print(f"Fractions(d<{Dmax}): {len(rpf)}, {rpf}")
rpf = sternBrocot(1,2,1,3)  # 1/2 < n/d < 1/3
print(f"Fractions (d<{Dmax}) between (1/3-1/2): {len(rpf)}, {rpf}")
#Fractions(d<8): 21, [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (2, 7), (2, 5), (3, 8), (3, 7), (2, 3), (3, 5), (4, 7), (5, 8), (3, 4), (5, 7), (4, 5), (5, 6), (6, 7), (7, 8)]
#Fractions (d<8) between (1/3-1/2): 3, [(2, 5), (3, 7), (3, 8)]
```
今回の問題は数だけ数えれば良いので、カウントだけreturnします。
再帰関数だと深くなりすぎるので、dequeを使った実装に変更しました。

```python 
from collections import deque
def sternBrocot(n1,d1,n2,d2,dmax):
  q = deque([(n1,d1,n2,d2)])
  ret = 0 
  while len(q)>0:
    (n1,d1,n2,d2) = q.pop()
    nm, dm = n1+n2, d1+d2
    if dm <= dmax:
      ret += 1
      q.append((n1, d1, nm, dm))
      q.append((nm, dm, n2, d2))
  return ret

print(f"Answer:  {sternBrocot(1,2,1,3, 12000)}")
```

（開発環境：Google Colab）
【Project Euler】Problem 72: 分数の数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 72. 分数の数

原文 [Problem 72: Counting fractions](https://projecteuler.net/problem=72)

**問題の要約：分母$d \le 10^6$の既約真分数の個数を求めよ**

例として$d=8$では以下のように21個あります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/a023d6a0-7bc8-b1d7-403c-5aa686d0d1da.png)

問題の見た目は問題 71.と似ていますが内容は全く異なります。以下のように分母$d$の既約真分数の分子の数は「dと互いに素である1以上d以下の自然数の個数 」となり[「オイラーのφ関数(Wikipedia)」](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC%E3%81%AE%CF%86%E9%96%A2%E6%95%B0)の定義そのものとなります。

| 分母| 分子| 分子の数 | 
|:---:|:---:|:---:|
|2|1|1|
|3|1,2|2|
|4|1,3|2|
|5|1,2,3,4|4|
|6|1,5|2|
|7|1,2,3,4,5,6|6|
|8|1,3,5,7|4|

従って答えは**sympy**の**totient**関数を使えば簡単に出ますが、制限時間1分を超えてしました。

```python
from sympy import totient
print(f"Answer: {sum([totient(den) for den in range(2,10**6+1)])}")
```
この**totient**関数を自分で**factorint**を使ってインプリして何とか1分を切れました。

```python
from sympy import factorint
def phi(n):
  ret = n
  for i in factorint(n).keys():
    ret = ret*(i-1)//i
  return ret

print(f"Answer: {sum([phi(den) for den in range(2,10**6+1)])}")
```
もしこれ以上のスピードアップを望むなら、ちょっと長いですが「[ユークリッドの果樹園 とオイラーのファイ関数の和の高速化（その１）](https://qiita.com/masa0599/items/f7f983cb976257dbdeda)」という記事（その3まであります）を読んでいただけたらと思います。ちなみに今回の答えも瞬時に出てきます。

```python
# totsum V3.1 totsum
from functools import lru_cache

def totsum(n):
  @lru_cache(maxsize=None)
  def G(n):
    if n == 0: return 0
    ret, m1 = 0, 2
    while m1 < n:
      n1 = n//m1
      m2 = n//n1 + 1
      ret += (m2-m1)*G(n1)
      m1 = m2
    return (n*(n-1))//2-ret
  return G(n)+1

n = 10**6
print(f"Answer: {totsum(n)-1}")
```
（開発環境：Google Colab）
【Project Euler】Problem 71: 分数の順序

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 71. 分数の順序

原文 [Problem 71: Ordered fractions](https://projecteuler.net/problem=71)

**問題の要約：分母$d \le 10^6$のすべての既約真分数を値の順に並べたとき$3/7$の直前の分数の分子を求めよ**

例として$d=8$の場合は$2/5$が答えとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/c5aa0516-37c7-6ce4-0f37-bdfe1ccd0aa8.png)
考え方としては$3/7$との差分が最小になる分数$n/d$を探せばよいので。

```math 
\frac{3}{7}-\frac{n}{d}=\frac{3d-7n}{7d}  \\
で分子3d-7n=1となる最大のdが答え \\
n=\frac{3d-1}{7}が整数
```
プロクラムにすると以下のようになりますが。電卓でも求まりそうです。

```python
for d in range(10**6, 0, -1):
  if (3*d-1)%7 == 0:
    break
print(f"Answer: {(3*d-1)//7}")
```

（開発環境：Google Colab）
【RSpec】traitとは

##traitとは
``trait``とは、``FactoryBot``で複数のサンプルデータを作成する際に使われるテクニック。
``Factory``が複数ある場合、``trait``を使用することで**記述の重複を減らす**ことができる。

##traitの使い方
例えば、締め切りが異なる2つのプロジェクト（1週間前が締め切りのプロジェクトと昨日が締め切りのプロジェクト）があったとする。締め切り以外は共通のなので、そこだけ``trait``を使って記述すると、記入するコードも減る上に見やすくなる

```rb
FactoroyBot.define do
  factory :project do
    # 1週間前が締め切り
    sequence(:name) { |n| "Test Project #{n}" }
    description "Sample project for testing purposes"
    due_on 1.week.from_now
    association :owner

    # 昨日が締め切り
    trait :due_yesterday do
      due_on 1.day.ago
    end
  end
end
```
なお定義方法は以下の通り。

```rb
FactoryBot.define do
  factory :モデル名 do
    trait :上記モデルを継承したインスタンスの属性値 do
       #コード記入
    end
  end
end
```

##実用例

```tasks.rb
FactoryBot.define do
  factory :task do
    title { 'Task' }
    status { rand(2) }
    from = Date.parse("2019/08/01")
    to   = Date.parse("2019/12/31")
    deadline { Random.rand(from..to) }
    association :project

    trait :done do
      status { :done }
      completion_date { Time.current.yesterday }
    end
  end
end
```

```task_spec.rb
RSpec.describe 'Task', type: :system do
 describe 'Task編集' do
 let(:task_done) { create(:task, :done) }
  it '既にステータスが完了のタスクのステータスを変更した場合、Taskの完了日が更新されないこと' do
   visit edit_project_task_path(task_done.project, task_done)
   select 'todo', from: 'Status'
   click_button 'Update Task'
   expect(page).to have_content('todo')
   expect(page).not_to have_content(Time.current.strftime('%Y-%m-%d'))
   expect(current_path).to eq project_task_path(task_done.project, task_done)
  end
 end
end
```
##参考記事
[【RSpec初級編】Factoryの継承をスマートに記述できるtrait(トレイト)を使いこなそう！](https://techtechmedia.com/inheritance-trait-rspec/)
rails s実行後にlocalhostにアクセスすると[BUG] Segmentation fault at 0x0000000000000000が発生する

#現象
タイトル通りです。
Rails sコマンドを実行後にrootに設定しているページへlocalhostで接続するとエラーが発生します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2259269/1f75df76-8f5a-9f2b-59fe-0fd87aeeb10a.png)

#環境
Windows10 20H2
Docker desktop for windows -v 4.3.2
Docker -v 20.10.11
ruby -v 3.0.3
rails -v 6.0.4.4

#エラー対処方法
`/config/initializers/assets.rb` に以下の文を追加する

```ruby
Rails.application.config.assets.configure do |env|
  env.export_concurrent = false
end
```

##余談
開発環境にGemを導入する前のGemのテスト環境でこのエラーが発生しました。
2回rails newからアプリケーションを作り直してテストしましたが、発生したのがDeviseを入れた直後だったので、Deviseのなにかが悪さしてるのかも…？ 
開発環境は前からDeviseを入れてて特に何も問題ないので違いがわからずでした…。
（Dockerで環境作ってるので実行環境も全く同じですし…。）

ひとまずある程度時間かけて調べても原因がわからなかったので、今回はリカバリー方法だけの紹介となります。
何かわかる方いらっしゃいましたら教えてください。

##参考文献
https://study-diary.hatenadiary.jp/entry/2021/01/05/200916
VSCodeのWSLを1から2に更新して運用できるようになるまでにしたこと

#前提
これは私の現在の環境で、この記事の内容を実行した時はもっと古いバージョンを使っていました。WindowsのOSが古すぎなければ大丈夫だと思います。

|  | Version |
|:-:|:-:|
|OS|Windows 10 Home (21H1)   |
| WSL| Ubuntu 20.04.2 LTS |
|Visual Studio Code | 1.63.2 |

#WSLを1から2に更新する
以下の記事を参照してください。
[WSL2導入｜WinアップデートからWSL2を既定にするまでのスクショ](https://qiita.com/tomokei5634/items/27504849bb4353d8fef8)
[VSCodeでRemote-WSLの接続に失敗する](https://qiita.com/tatsunari/items/8fdc4022e06b54e172f9)

#ファイルをUbuntuのhomeディレクトリ直下に移動する
エクスプローラーで、以下にアクセスしましょう。

```
\\wsl$\Ubuntu\home\（Ubuntuにおけるユーザネーム）
```
エクスプローラーにこのアドレスを打ち込んでもアクセスが拒否される場合、WSLの方からコマンドで

```bash:WSL
$ explorer.exe .
```
と打ち込めば、WSLのカレントディレクトリをエクスプローラで開けます。後は目的の場所に各種ファイルを移動しましょう。

#ファイル・作業ディレクトリの移動に伴う各種設定の変更
以下の記事に書きました。
[WSL2+VSCodeでC++ファイルをビルド・デバッグする際のtasks.json及びlaunch.jsonの設定]
(https://qiita.com/boatmuscles/items/54f5e9f3eb74118e76fa)
RailsのSPAにJestを導入してみた話

## この記事の内容
業務で、`Rails`のSPAを作っています。フロントのテストフレームワークとして`Jest`を導入することになり、チームで探りつつ実装したので、その記録をまとめたいと思います。
なお、各種バージョンは以下の通りです。

- Rails ... 6.1.0
- Jest ... 27.4.7
- node.js ... 14.19.0

## 必要なライブラリの導入

必要なライブラリを導入します。TypeScriptを使用していたので、Jestだけではなく @type/jest も必要でした。

```shell
$ yarn add --dev jest @types/jest
```
そして package.json の script に以下を追加します。

```json:package.json
{
  "scripts": {
    "test": "jest"
    ...
  },
  ...
}
```

## 設定、ディレクトリ構成
この時点で `yarn test`を実行しようとすると、 `config/webpack/test.js` を実行しようとしてテストが失敗します。これは[こちらの記事](https://techracho.bpsinc.jp/hachi8833/2018_03_26/53865)によると以下の理由からだそうです。

> これは、Jestがプロジェクト内のテストファイルを探索する方法が原因です。基本的にはプロジェクト全体のうち.spec.jsか.test.jsにマッチするすべてのファイルを実行します。ここではテストファイルが*.test.jsとマッチしたので、テストとして実行されようとしていたのです。

そのため、package.json に以下の記述を記載し、[Jestがファイルを検索するために使用するディレクトリのパスを指定](https://jestjs.io/ja/docs/configuration#roots-arraystring)します。

```json:package.json
{
  ...
  "jest": {
    "roots": [
      "<rootDir>/app/javascript"
    ]
  }
}
```

`<RootDir>`は[公式の記載](https://jestjs.io/ja/docs/configuration#rootdir-string)によると「`Jest`の設定ファイルか`package.json`を含むディレクトリ、もしくは設定がひとつもない時は`pwd`のディレクトリ」を表す記述」だそうです。

## 最初のテスト

ここでJestが動作するはずなので、最初のテストを書きます。
先ほど`roots`で指定した`/app/javascript`下に、`__tests__`というディレクトリを作って、サンプルのファイルを書きます。

```ts:/app/javascript/__tests__/example.test.ts
describe('サンプルテスト', () => {
  test('trueになる', () => {
    expect(true).toBeTruthy()
  })
})
```

フロントエンドをざっくり学んだ時に使用した[こちらのテキスト](https://www.shuwasystem.co.jp/book/9784798061771.html)によると、Jestでは、`describe()`という関数でテストケースをまとめ、そのブロック内に`test()`関数を書いてテストをしていくようです。

`describe()`や`test()`の第一引数に「何をテストするか」を書くことで可読性が上がります。
以上で、テストが動くことが確認できると思います！:relaxed:

## おまけ：CircleCIでも実行

テスト自体の設定はこれで終わりなのですが、今回はCIツールへの接続も行いました。
CIの`run`で実行するコマンドの中で、先ほど`package.json`で設定した`yarn test`を実行すれば良いだけなのですが、`node.js`のバージョンが合わなかったりしてエラーになったので、コマンド中で`yarn install`も実行しました。

```.circleci/config.yml
- run:
   name: Jestの実行
   command: |
    yarn install
    yarn test
```
※本当は`yarn install`と`yarn test`の記載は離れていたり、キャッシュを用いて処理を高速化するような記載もあるのですが、詳細割愛します。


## その他
これからReactで実装している諸々のテストの記載をしていくので、何か気づきがあれば投稿したいです:relaxed:

## 参考資料など

https://jestjs.io/ja/

https://techracho.bpsinc.jp/hachi8833/2018_03_26/53865

https://www.shuwasystem.co.jp/book/9784798061771.html
Postgres/PostGIS functions speed comparison

# Intro

I always wonder which is the best way to do certain Postgres and PostGIS functions. It's often hard to tell if a certain method is more efficient than another. I'll update this post as I test more functions and methods out to see who's the top dog. 

## ST_Buffer

ST_Buffer. Pretty simple, it makes a buffer based on your geometry. I often use it to make, say, a 10 meter buffer for every point in a table

### geom vs ST_Point

I always create a geom column when I have x and y data for points. But I was wondering if it's worth it. With a large dataset, creating the `geom` column can be very time consuming.

I took a table with 1,488,942 rows of data and tested this out.

The `geom` column (no index) method:

```sql
SELECT *, ST_Buffer(geom, 50) AS buffer
FROM my_table;
```

The query completed in 163.5 seconds.

The ST_Point method:

```sql
SELECT *, ST_Buffer(ST_Point(lon, lat), 50) AS buffer
FROM my_table;
```

They query completed in 280.1 seconds.

So using `geom` was way faster. Probably worth creating the `geom` column if you are planning on doing any buffering.

## JOIN vs subquery

Using JOIN or a subquery on a table with multiple entries per, for example, user. About 10 million rows.

### Subquery

```sql
SELECT *
FROM user_data
WHERE 
	user_id IN
	(
		SELECT DISTINCT user_id
		FROM user_data
		WHERE 
			purchased_item = 'something'
	)
	AND date = ('2022-02-02')
```

total time = 58 seconds

## JOIN

```sql
SELECT *
FROM user_data a
JOIN 
	(
		SELECT DISTINCT user_id
		FROM user_data
		WHERE 
			purchased_item = 'something'
	) b
	ON (a.user_id = b.user_id)
WHERE date = ('2022-02-02')
```

total time = 92 seconds.

Subquery is substantially faster.
Unity/WebSocket


# ご参考
https://note.com/hikohiro/n/n01007cb70c85
# 手順1　[websocket-sharp.dll]をビルドする。
VisualStudio2019 でビルドするとエラーが出る。これはJsonsoftなど必要なライブラリがないため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/df4de48e-0b25-89ff-d13b-138520bb2c18.png)

Nugetで[Newtonsoft]を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/64f94fec-59be-f1e2-b4dc-1ea17e8eb293.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/96e2943f-96a1-65f3-1e30-513d0d976526.png)

#手順2 Unityプロジェクトに[websocket-sharp.dll]を追加、動作確認を行う。


```

using UnityEngine;
using System.Collections;
using WebSocketSharp;
using WebSocketSharp.Server;
public class ExampleWebSocketServer : MonoBehaviour {

    public static int port = 5678;
    private WebSocketServer server;

    void Start()
    {
        server = new WebSocketServer(port);
        server.AddWebSocketService<Echo>("/");
        server.Start();

    }
    void OnDestroy()
    {
        server.Stop();
        server = null;
    }
}

public class Echo : WebSocketBehavior {
    protected override void OnMessage(MessageEventArgs e)
    {
        //    Debug.Log(e.data);
        Debug.Log(e.Data.ToString());
        Sessions.Broadcast(e.Data);
    }
}


```


```

using UnityEngine;
using System.Collections;
using WebSocketSharp;

public class WebSocketClient : MonoBehaviour {

    private WebSocket ws;
    void Start()
    {
        var t_url = "ws://localhost:" + ExampleWebSocketServer.port.ToString() + "/";
        Debug.Log(t_url);
        ws = new WebSocket(t_url);

        ws.OnOpen += (sender, e) =>
        {
            Debug.Log("WebSocket Open");
        };

        ws.OnMessage += (sender, e) =>
        {
            //    Debug.Log("WebSocket Message Type: " + e.Type + ", Data: " + e.Data);
            Debug.Log("WebSocket Message Type: " +e.GetType().ToString() + ", Data: " + e.Data);
        };

        ws.OnError += (sender, e) =>
        {
            Debug.Log("WebSocket Error Message: " + e.Message);
        };

        ws.OnClose += (sender, e) =>
        {
            Debug.Log("WebSocket Close");
        };
        ws.Connect();
    }
    void Update()
    {
        if (Input.GetKeyUp("s")) {
            ws.Send("Test Message");
        }
    }
    void OnDestroy()
    {
        ws.Close();
        ws = null;
    }
}

```
Python boto3でAWS S3を操作しよう

## はじめに
Python boto3でAWS S3へのバケット作成やデータアップロードなどjupyter notebookにて行います。

##### まずはboto3をインポート
```python
import boto3
```
インストールできていない場合は　pip install boto3　でインストール。
##### S3へのアクセスを可能にします
```python
client = boto3.client('s3',
                      region_name='ap-northeast-1',
                      aws_access_key_id = 'ご自身のkey_id',
                      aws_secret_access_key = 'ご自身のaccess_key')
```
ec2を操作したい場合は's3'の部分をec2にするとec2の操作が可能になります。
region_nameは東京であれば'ap-northeast-1'でokです。

access_key_idやsecret_access_keyがわからない場合はターミナルで下記を打つと確認できます。

```python
aws configure get aws_access_key_id
aws configure get aws_secret_access_key
```

###S3へバケットの作成
```python
client.create_bucket(Bucket='任意のバケット名', 
                     CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'})
```
これでS3上にバケットを作成することができます。
ちなみにCreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'}は必須でこれがないと以下のエラーが発生します。
ClientError: An error occurred (IllegalLocationConstraintException) when calling the CreateBucket operation: The unspecified location constraint is incompatible for the region specific endpoint this request was sent to.



###S3上の不要バケット削除方法
```python
client.delete_bucket(Bucket='任意のバケット名')
```
バケット内にデータが存在するとバケットの削除はできません。

### ローカルデータをS3上の指定したバケットにアップする方法
```python
def upload_files(file_name, bucket, object_name=None, args=None):
    """
    file_name: name of file on local computer
    bucket: bucket name
    object_name: name of file on s3
    args: custom srgs
    """
    
    if object_name is None:
        object_name = file_name
        
    response = client.upload_file(file_name, bucket, object_name, ExtraArgs=args)
    
    print(response)


upload_files('data/kari.txt', 'バケット名')
```
上記upload_files関数の引数にアップしたいデータのパス、空のバケット名を入れることでローカルからS3の空バケットにデータをアップすることが可能です。

### S3上のバケット内に複数のデータをアップしたい場合
```python
import glob

files = glob.glob('data/*')
files
#'data/kari3.csv', 'data/kari2.txt', 'data/kari.txt'が表示されます
#globを使用しローカルのdataフォルダ直下のデータをfilesに格納します。

for file in files:
    upload_files(file, 'バケット名')
    print('uploaded', file)
```
for文を使いローカルにあるdataフォルダ直下の全てのデータをS3へアップロードができます。

### S3上のバケットからローカルへデータをダウンロードする方法
```python
s3 = boto3.resource('s3')
list(s3.buckets.all())
client.list_buckets()
bucket = s3.Bucket('バケット名')
files = list(bucket.objects.all())

for file in files:
    client.download_file('バケット名', file.key, file.key)
```
ここもfor文を使用しデータをローカルへダウンロードします。

以上でPython boto3を使用してAWS S3へのバケット作成やデータのアップデートができます！
キースイッチのグラツキを軽減する

#注意事項
この記事を読んで同じような作業をして、ケガやその他、損害等が生じる危険性があります。
作業は**自己責任**でしてください。

削るなどの加工はしませんが、キースッチを開けて少し細工をします。
開ける前の状態には戻せない場合あることをご了承ください。

#キーボードスイッチの分解と測定
キーボードスイッチを分解して、ステムとトップカバーの寸法を測定していた。
測定方法はデジタルノギスによる実測定です。
各1個ずつの実測定のため、測定誤差、キースイッチの個体誤差が生じます。

Gateron Pre-lubed 3 Pins Linear　Sliver　
ステム　
　縦５．６３㎜　横７．２９㎜
トップカバー
　縦５．７３㎜　横７．４４㎜
スキマ
　縦０．１０㎜　横０．１５㎜

Gateron BOX INK V2 Black
ステム　
　縦５．６０㎜　横７．２６㎜
トップカバー
　縦５．７８㎜　横７．４６㎜
スキマ
　縦０．１８㎜　横０．２０㎜

この測定結果ではGateron BOX INK V2 Blackのほうが、少しスキマが広い。
Gateron BOX INK V2 Blackに下記の方法を試した。

#方法１　ステムにアルミテープを張る
0.08㎜の薄いアルミテープをステムに張る
その結果
スキマ
　縦０．０２㎜　横０．０４㎜

張った直後は固くスプリングで動かない。
ステムとトップカバーをすり合わせをすると
アルミが少し凹み、スプリングでも動くようになる。
グラツキは軽減されるがが、軽いスプリングには抵抗になるため
4面を貼るところを、グラツキの気になる3面、2面だけにすると抵抗が緩和する。


#方法２　トップカバーの内側に反らす
トップカバーを裏側から見ると、接点側はプラ板一枚が垂れ下がっている状態。
そのプラ板を少しだけ内側に反らす。
やり方は爪楊枝の持ち手側をプラ板の裏に入れて、テコの原理で少しずつ内側に傾ける。
やりすぎると折ってしまうため、少しずつ傾ける。

組立をしてグラツキの確認をする。
試したキースイッチは感覚的に
Gateron Pre-lubed 3 Pins Linear　Sliver
と変わらない程度のグラツキ加減となった。

副作用
ステムが奥側（ＬＥＤ側）に傾いたままになる。
傾くことで、ステムの接触が、奥側（ＬＥＤ側）の上側と、接点側はプラ板の下側の２か所になる。
傾いたままステムが上下するため、動作点が安定する。
奥側のグラツキは、ほとんど無い。接点側には少しスキマがあり、グラツキがある。


#方法３　ボトムカバーの両サイドのガイドを内側に曲げる（追記2022.02.10）
方法２は前後、方法３は左右のグラツキを軽減させる。
キースイッチを分解してボトムカバーだけにする。
ボトムカバーのガイドを左右が均等に内側に曲げる。
効果はキーを押し込む前がよくわかる。キーキャップの四隅を押しても
グラツキによる傾くより先にキースイッチが下がる。

平坦なキーキャップで試しているがパンタグラフのようなブレのない押し下がり方をする。

方法２と３の併用で、ステムが中心にくることでスムーズ差が増した感じがする。
Gateron Pre-lubed 3 Pins Linear　Sliver
Gateron CAP V2 キースイッチ Milk Yellow
の２つのキースイッチで試したところグラツキの軽減を感じました。（個人の感想です）

Gateron Pre-lubed 3 Pins Linear　Sliver　
ステム　
　横７．２９㎜
ボトムケース　ガイドピッチ
　横７．７７㎜　を　ハの字のにして　先端幅を　７．４６㎜に狭めた。

スキマが０．４８㎜から０．１７㎜に狭くなり、その分のグラツキが軽減する。

キースイッチオープナーに嵌めたままで、キースイッチ引き抜き工具をてこの原理で
片方ずつ傾ける。
OREO mapを知っていますか？

お疲れ様です！こんにちは！初めまして！
MIXIの開発本部　CTO室　QAグループのALICEです！


今回は個人的によく使っているコミュニケーション関連の話になります！
私は論理的な文章を書く・話すのが苦手です・・・
伝わりやすい文章が書けるように工夫してたら発見した、
一番役に立ってるものを紹介しようと思います！

----
## OREO map
今回紹介したい内容はOREO mapというものです！
頭文字をとって、**OREO** mapです！
（なんでmapが付くのかは不明・・！知ってる方教えてください！Mind mapみたいな感じだと勝手に思っています）
OREO mapは実際アメリカで使われているコミュニケーション方法です！
甘いお菓子ではないです！


## O
Opinion
└意見を述べる

・話題を決める
・話したい内容をまとめる

## R
Reason
└理由と、根拠を述べる

・意見を補足する理由を説明する
・妥当な根拠を提示し、意見を証明する

## E
Example
└例をあげる

・例をあげることで、理解度を高められる
・Rにあたる理由・根拠のベースになる

## O
Opinion/Offer
└意見の強調、提案

・最後にもう一度意見を述べて強調する
・理由と例をまとめて提案する

----
## 例
ちょっとおふざけな内容ですが実例だとこんな感じです！

O
リングフィットを買いたい！
R
運動不足すぎる！健康になりたい！筋肉をつけたい！
E
実際友だちが**毎日30分やって**１ヶ月で6kg痩せてるし、筋肉量が増えた！（Inbody測定）
継続してやれば確実に健康になれる！
O
リングフィットを買って、毎日やったら私も健康になれる！筋肉がつくかも！
私は毎日10分を目標に2月やってみる！


※1月26日(水)リングフィットを買いました。今の所毎日やれています。筋肉痛で死にそうです。横腹がめっちゃ痛いです。なんか知ってる方教えてください！！

----


## 最後に

上記OREO mapを活用することにより、
報告書、仕様書、メール、説明書など
文章を論理的に書くことができます！

これだけ見るとちょっと意見押し気味に見えるかもしれません。
しかしこちらは必ず、これに合わせる必要はありません！
コミュニケーションはとても繊細で、難しくて、（これについてもいつか紹介できたらと思ってます）
取りすぎても、取らなすぎてもよくないんです。
そこで**OREO mapをベース**に話を進めると、
低コストで高いコミュニケーションが取れます！

皆さんも
リモートでのチャット生活の中、少し試してみてはいかがでしょうか？！
[py2rb] Ruby#Array -> Python#Tuple

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# どうすRuby
`Ruby`の配列から、`Numpy.array`を作成します。

```ruby
dtype = [['score', Numpy.int8], ['label', Numpy.str_, 1], ['pep', Numpy.float64], ['is decoy', Numpy.bool_]]
psms_ = Numpy.array(PSMS.map{ |s, l, p| [s, l, p, @is_decoy.call([s, l, p])] }, dtype: dtype)

# error
RuntimeError: Wrapped undumpable exception for: PyCall::PyError: <class 'TypeError'>: Field elements must be 2- or 3-tuples, got '['score', <class 'numpy.int8'>]'
```
`tuble`で渡せと。

https://qiita.com/stat/items/a383451e7f824e4c9627#%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88%E5%9E%8B%E5%A4%89%E6%8F%9B

先駆者がいて助かる。

```ruby
dtype = [PyCall::Tuple.(['score', Numpy.int8]), PyCall::Tuple.(['label', Numpy.str_, 1]), PyCall::Tuple.(['pep', Numpy.float64]), PyCall::Tuple.(['is decoy', Numpy.bool_])]

# error
RuntimeError: Wrapped undumpable exception for: PyCall::PyError: <class 'ValueError'>: invalid literal for int() with base 10: 'A'
```
ぐぬぬ。

```ruby
PSMS ＝ [[0, "A", 0.01], [1, "B", 0.011], [2, "C", 0.012],........,[51, "z", 0.061]]
```
`'A'`が整数として無効です。

```ruby
psms_ = Numpy.array(PSMS.map{ |s, l, p| PyCall::Tuple.([s, l, p, @is_decoy.call([s, l, p])]) }, dtype: dtype)
```
こちらも、`tuple`で渡さないといけないのね。
# メモ
+ Python の tuple を学習した
+ 百里を行く者は九十里を半ばとす
scikit-imageを簡単にcudaで計算させる

画像処理ライブラリの`scikit-image`を簡単にCUDAで走らせる`cucim`というものを見つけたので、試してみる。

https://developer.nvidia.com/blog/cucim-rapid-n-dimensional-image-processing-and-i-o-on-gpus/
https://docs.rapids.ai/api/cucim/nightly/api.html

なお、`scikit-image`のすべてのサブモジュールが使えるわけではないようだ。
22/02/24現在、`future.graph.merge_hierarchical`は使えない。

# インストール


`pip`が使えるなら、


先に、`cupy`などの環境を整えておく必要があると思うが、

```
pip install cucim
```

で入るようだ。

`conda`などの方法は、以下を参照。

https://github.com/rapidsai/cucim


# numpyの配列 ⇔ cupyの配列の変換

numpy配列に入れた画像をcupy配列に入れてから用いるようである。


```python
# numpy-array --> cupy-array
image_gpu = cp.asarray(image)

# cupy-array --> numy-array
image_cpu = cp.asnumpy(image_gpu)
```

https://qiita.com/samacoba/items/d18e6cf09f544477aff4

# 例、ガウシアンフィルターと画像表示

```python
import numpy as np
import cupy as cp
import cucim
from cucim.skimage.filters import gaussian

from skimage import data, img_as_float
from skimage.io import imread, imshow
import matplotlib.pyplot as plt

def gpu_imshow(image_gpu):
    image = cp.asnumpy(image_gpu)
    imshow(image)
    plt.show()

image = img_as_float(data.camera())
image_gpu = cp.asarray(image)
blurred_gpu = gaussian(image_gpu, sigma=5)
gpu_imshow(blurred_gpu)
```

# 参考
https://biapol.github.io/blog/robert_haase/cupy_cucim/
正規表現 Javascript vs Python


Javascriptならよく利用される関数はtest(), match()です。

```js
const assert = require('assert').strict;

// 特定の文字列が存在するか
assert.ok(/\d{4}/.test('Today 2022 football.'));
assert.ok(/^\d{4}/.test('Today 2022 football.') === false);
assert.ok(/^\d{4}/.test('2022 football.'));
assert.ok(/^\d{4}$/.test('2022 football.') === false);
assert.ok(/^\d{4}$/.test('2022'));

// 特定の文字列を抽出する
// [ '2022', index: 6, input: 'Today 2022 football.', groups: undefined ]
console.log('Today 2022 football.'.match(/\d{4}/));
// [ '2022', '1234' ]  only matched value return if global match
console.log('Today 2022 football. 12345'.match(/\d{4}/g));
// [ 'Today 2022', 'football 1234' ]  no group info
console.log('Today 2022 football 12345'.match(/\w+ (\d{4})/g));
// Get group values
const allMatches = 'Today 2022 football 12345'.matchAll(/\w+ (\d{4})/g);
for (const match of allMatches) {
  console.log(match);
  assert.ok(/^\d{4}$/.test(match[1]));
}

```
Pythonでよく利用される関数はsearch()です。

```python
import re

#  match() check from the beginning
# <re.Match object; span=(0, 4), match='2022'>
print(re.match(r'\d{4}', '2022 football.'))
assert re.match(r'\d{4}', 'Today 2022 football.') is None
# <re.Match object; span=(0, 11), match='Today 2022 '>
assert re.match(r'\w+ \d{4} ', 'Today 2022 football.')
assert re.fullmatch(r'\d{4}','2012')
assert re.fullmatch(r'\d{4}','2012 year') is None

# search through the text
print('------------search------------')
assert re.search(r'\d{4}', '1234Today 2022 football.').group() == '1234'
assert re.search(r'\d{5}', '1234Today 2022 football.') is None
assert re.search(r'[a-zA-Z]+ (\d{4})', '1234Today 2022 football.').group() == 'Today 2022'
assert re.search(r'[a-zA-Z]+ (\d{4})', '1234Today 2022 football.').group(1) == '2022'

# ignore group
for m in re.findall(r'[a-zA-Z]+ (\d{4})','Hi 1234 Today 2022 football.' ):
    print(m)
```
Pythonのmatchは文字列の先頭からチェックするので、注意しよう。
Python リストが１次元か多次元か確認するときに便利なメソッド

# はじめに

リストの次元数によって処理を分岐しようとしたときに調べました

主に１次元リストを想定しているが、まれに２次元リストの処理もしたいときにどうすべきか考えて

# 方法

```python
def how_dimensions(something_list):
    if not isinstance(something_list[0],list):
        print('1次元リスト')
    else:
        print('多次元リスト')

ls1 = [1,2,3]
ls2 = [ls1,ls1]

how_dimensions(ls1)
how_dimensions(ls2)
```
```
1次元リスト
多次元リスト
```
MacでAndroidStudioを使うときにCtrl+FBPNで移動できるようにする

# 概要

- 普段は主にVSCode ＋ Macで開発している
- カーソル移動はCtrl+f(右), Ctrl+b(左), Ctrl+p(上), Ctrl+n(下)で操作している
- この度Andoroidを学ぶ必要があったためAndroidStudioをインストールした
- 上記が使えない:innocent:

# 結論
設定変えたらできた。

Preferences > Keymap > Keymap
を「macOS」 → 「macOS System Shortcuts」 に変更するだけ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347087/ab8412eb-4ebf-00c6-bc13-27790237088b.png)

なれると方向キーで操作するのはきつい。
NXP FRDM-K22F + MCUXpressoでHello world


# 概要
前回、FRDM-K22Fの開発環境が準備できたのでプロジェクトの作成を行う。
https://qiita.com/tetsuoMikami/items/77f9ee69e9a01b19d5cb

# プロジェクトの作成
メニューから選択してプロジェクトを作成する。
QuickStart Panel にもNew Project...があり、そちらからも作成できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/2dbc407d-56de-310e-a8e6-eb10eca7379f.png)

## SDK選択
ターゲットボードやLSIの型番を入力して目的のボードを選択状態として、Nextをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/aa62989c-154c-c3c6-ad80-e4b7fbda1444.png)
ここでNextやFinishが有効にならない(グレーアウト)であれば、SDKのインストールが正常に完了していない。

## 機能選択
テストなのでOSやドライバは適当な選択とした。
尚、Project name suffixに何か入力しないとNextやFinishが有効にならず押すことができない。
あとから変更できるが、トラブル防止のため、Project name と Project name suffixはよく考えて付ける方が良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/0b49b16e-378b-9ea0-f8b5-c1cdce70681e.png)

SDK Debug ConsoleをSemihostにしておくと、IDEのConsoleタブにログが表示される。PCにUART-USBなどで接続する必要がなくなるでそれなりに便利である。
但し、ログとしての使い勝手は悪い。

# Hello worldは準備されている
選択した機能の最低限の初期化と共に「Hello world」はテンプレとして用意される。
とりあえず動かすなら何もコードを書く必要がない。

DebugをクリックするとBuildとイメージファイルの作成、書き込みまで一気に行ってくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/ef4e4ddb-7e51-4050-d56c-59073ab5caf8.png)
※Breakかけているとエラーになる。

# 実行
メニューバーの実行アイコンか、F8(Resume)でソフトウェアが実行開始となる。
以下はConsoleにHello worldが表示され、無限ループに入った状態。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/9c85e93a-c47f-4139-6b19-1d543a2fe5c5.png)
Githubでフォルダに矢印がありファイルの中身が見えない

<h1>開発環境</h1>
・php
・mysql
・apache
・docker
・Laravel

いわゆるLAMP環境です。

<h1>起こってる現象</h1>
githubにプッシュするまでは良かったのですが、
プッシュした後一度正常に出来たか確かめたら
タイトルのような現象になっており、
laravelプロジェクト本体のみファイルの中身が閲覧不能状態になっていました。

laravel-cms/
　├ app/(laravelプロジェクト)←これのファイルの中身が見えない状況
　├ docker/
　│　└ Dockerfile
　└ docker-compose.yaml

<h1>試行錯誤してみる</h1>
まずcommitメッセージを確かめて見ました、すると```サブモジュールが<該当ファイル>に追加されました。```と出ていました。

その次にターミナル場で```git ls-files```でリポジトリで管理しているファイルを一覧表示できますので確かめてみたら・・・・

```terminal
.DS_Store
.gitattributes
README.md
app
docker/Dockerfile
docker-compose.yaml
```
どうやらapp/のファイルがリポジトリ管理下になってい内容です。

つまり入っていなかった（管理されていなかった）と考えました。

<h1>解決策</h1>
```terminal
$ git rm -rf --cached <対象ファイル or path>
$ git add <対象ファイル or path>
 // <対象ファイル or path>部分は、$git ls-files した時に表示されている部分。
 // --cachedオプションを付けることにより、ファイルを残したまま管理対象から外すことができる。
```

なので自分の場合は

```terminal
$ git rm -rf --cached app
//rm 'app' となり、いったん追跡対象から外す
$ git add app
//再び追加
```

これで解決できました。
UNETの代わりにMirrorが使われる理由


！！まだまだ絶賛編集途中です！！

## UNET

非推奨の昔からあるUnity純正のネットワーク・ライブラリ

### 特徴

1. 24 人を超えるプレイヤーの同期で死亡するらしい
2. 非推奨，安定性がない
3. SyncListの送信量の限界が最大64K bytes

> ピアツーピア（P2P）トポロジーでは一度に 24 人を超えるプレイヤーを同期しようとすると問題が生じることが多いため、25 人以上のプレイヤーに対応するセッションに関しては、専用ゲームサーバー（DGS）トポロジーへの移行が推奨されます。[1]

とUnityも公言しているので，なるべく使わないのが得策．



3に関して，SyncListでパケットサイズもUnit16.MaxValue(64KB)で制限されていたので，最大パケットサイズを大きくして，遅延送信させたとしても，それ以上のパケットを送ること自体ができなさそう．

```
if (buffer.Length > UInt16.MaxValue)
{
    if (LogFilter.logError) { Debug.LogError("NetworkWriter WriteBytes: buffer is too large (" + buffer.Length + ") bytes. The maximum buffer size is 64K bytes."); }
    return;
}
```



## Mirror

Mirrorは，有志が開発しているUNETの後継ネットワークライブラリです．

### 特徴

- 100人以上のプレイヤーの同期ができるらしい（[uMMORPG](https://assetstore.unity.com/packages/templates/systems/ummorpg-51212)　では480人参加をテストしたらしい）
- あああ


### 作られた経緯

- vis2kさん達（Mirrorの開発者）は、必死でUnityにバグレポートを出したのに、Unityは「仕様です」と返答するだけで、全然修正してくれなかったそう
- UNETのHLAPIは突如オープンソース化されたので、vis2kさんはこのHLAPIのバグを自力で修正しまくり始めました。
- Raknetの上にNetworkViewを増築して、さらに３階にUNETを建て増しした

Unityが後継として作ったMLAPIよりもMirrorの方がよいらしいです[2] 






[1] [今、Unityでネットワークマルチプレイ作るのに何を使えばいいのか] (https://soysoftware.sakura.ne.jp/archives/1686)
[2] [Unityのネットワーク、即戦力が欲しいならMLAPIよりやっぱMirrorのほうがいいかも 2021年5月20日](https://soysoftware.sakura.ne.jp/archives/2140)
【JavaScript】reduce()の使い方

データの合計を求めるのにreduce()を使用したので使い方をメモしておく。

# reduce()の使い方
reduce()は、配列に含まれる要素を順番に取り出していき、コールバック関数を呼び出すようになっている。
配列の要素の合計を求める時などに使用される。reduce()の基本的な書き方は以下となる。

```javascript
<対象の配列名>.reduce(<コールバック関数>,<初期値>)
```
ここで、初期値に関しては省略可能である。また、コールバックは順番に以下の4つの引数を取る。
■ １つ前のコールバック関数の結果の値。最初は、初期値か対象配列array[0]の要素。
■ 現在の要素。最初は、初期値が指定されている場合は対象配列array[0]の要素、指定なしの場合は対象配列array[1]の要素。
■ 現在の要素のインデックス。最初は、初期値が指定されている場合は0、指定なしの場合は1。
■ 対象となっている配列

# サンプル
配列の合計を求めるサンプルを書いてみた。

```javascript
const array = [1,2,3,4,5];

const total = array.reduce((sum, value) => {
	return sum + value;
}, 0);

console.log(total);     // 15
```

次に配列の中身がオブジェクトの場合も基本な書き方は変わらない。

```JavaScript
const array = [
	{ name: "ryota", number: 6 },
	{ name: "taro", number: 8 },
	{ name: "ken", number: 4 },
];

const total = array.reduce((sum, value) => {
	return sum + value.number;
}, 0);

console.log(total);     // 18
```
twitvimをdeinのplugins.tomlでinstallする

NeoBundleでtwitvimをinstall方法は[公式](https://github.com/twitvim/twitvim)に記載がある。しかし、deinでのinstall方法がないので記載する。

# 前提

- deinでvimパッケージの管理している。
- plugins.toml を使用している。

# 手順
### 1. plugins.tomlに下記を記載する
``` plugins.toml
[[plugins]]
repo = 'twitvim/twitvim'
```
### 2. vimを起動する。
```
$ vim
```

### 3. installコマンドを実行する

```
:call dein#install()
```

### install完了

# コマンド一覧

twitvimの[Usage](https://github.com/twitvim/twitvim#usage)に記載があるが、よく使うコマンドをこちらにも日本語訳して書く。

- :PosttoTwitter - ツイッターへメッセージを送るためのコマンドです。
- :FriendsTwitter - フォロワーのツイートを見る。
- :UserTwitter - 自分のタイムラインを見る。
- :PublicTwitter - 公開タイムラインを見る。
- :DMTwitter - ダイレクトメッセージを見る。
- :SearchTwitter - ツイッターの検索窓を使う。
デザインパターンを蒸し返して個人開発に生かす

#TL;DR
クラス型言語を使って自分で何か作る時、自分に言い聞かせる備忘録。
#GoFはいったん捨てろ
The Gang of Fourとかいう偉い4人組がデザインパターンの始祖を創造された。

- 特定のロジックの実装に名前をつけたのがアルゴリズム
- 特定のインスタンスの連携に名前をつけたのがデザインパターン

デザインパターンとはインスタンス間の連携の構造に名前をつけたものだ。
GoFの作ったデザインパターンは、思想の勉強としてはいい教材だがもう古い。
現代でも通用するものはあるが、不要なパターンのほうが多いと思う。
#具象と抽象を往復せよ
ある処理構造を設計する時に、最初のステップは具体的な事象のモデル化だ。
実現したい処理の構造を思い描いたら、そこから具体的な部分を削っていく。
抽象的な骨組みが残ったら、そこからまた具象部分を実装することを考える。
何度か具象と抽象を往復しているうちに、実装すべき内容が見えてくる。
#現代のパターンを使いまわす
典型的な要求とそれに適したパターンがあるのなら迷わずそれを使う。

- パブリッシャー・サブスクライバーパターン

マスターインスタンスが複数のクライアントインスタンスからの処理要求を
オンデマンドで処理するパターン。Webサーバのような形。

- パイプラインパターン

DirectShowフィルターグラフで通じる人もいると思う。インスタンスの入出力を
統一して、あるインスタンスの出力が次のインスタンスの入力になるようにする。
パイプラインの各段は（入出力待ちを除けば）並列に動ける。
#パターンを創造する
設計を進めるうちに、応用性のあるインスタンス構造や処理の構造を思いついた。
似たようなパターンは技術書で見たことがない。ネット検索でもヒットしない。
なら創造主となってパターンに命名しよう。すでに誰かが思いついていようとも
知ったことではない。俺流パターンを作り出そう。
**何番煎じであろうとも私はまだ煎じていない**という~~迷言~~名言もあるではないか。

だれかの考えたものを応用するだけがオブジェクト指向ではないのである。
Mirrorの最大パケットサイズ




ウィンドウサイズが`Math.Min(rcv_wnd, Kcp.FRG_MAX)`に制限されている（ 固定値で Kcp.FRG_MAX = 255 ）ので，それを超えることはできなさそう[1] で，最大値は298449 bytes (291KB)となっています．これはSyncListをN個持った場合でも，(N x SyncListの配列数)のバイト数 < 298449 bytes (291KB)なので，それが同期の限界っぽいです．

UNETの場合は，(N x SyncListの配列数)のバイト数 < 64 KB bytes となっており（30KBとかでも適切なエラーが出ずにバグるが），明らかにMirrorで同期できるバイト数が多そうです（4.54倍）．

[1] KcpConnection https://github.com/vis2k/Mirror/blob/2cacb89faed2d84f0df605e6584d1fa525988728/Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpConnection.cs#L69
RecyclerViewのいつもの設定をXMLでスマートに設定する方法

#はじめに
歴史のあるプロジェクトでは大体LayoutManagerの設定などをkotlinで指定しているのをよく見かけます。
この辺りはxmlでも設定ができるので、紹介したいと思います。

#LinearLayoutManagerを設定する場合

LinearLayoutManagerを設定する場合は以下をxmlに設定します。

```
<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
```

設定は以上です。
LinearLayoutManagerのみの設定でも問題ありませんが、スクロール方向をorientationで設定できるので、こちらを設定してあげると親切ですね。

#GridLayoutManagerを設定する場合

GridLayoutManagerを設定する場合は以下をxmlに設定します。

```
<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
            app:spanCount="1"/>
```
GridLayoutManagerの場合はspanCountを合わせて設定する必要があります。
LinearLayoutManagerと同様にorientationを設定することでスクロール方向を指定できますので、設定してあげると良いかと思います。

#おまけ
dividerを設定したいケースがあると思います。
そんな時は以下のようなBindingAdapterを設定しておくと簡単に設定できるようになります。

```
@BindingAdapter("hasDivider")
fun RecyclerView.setDivider(hasDivider: Boolean) {
    val layoutManager = this.layoutManager
    if (hasDivider && itemDecorationCount == 0) {
        addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL))
    }
}

ちなみに設定できるのは縦方向のスクロールの場合のみです。
check関数などで正しい設定が行われている状態で呼び出されているかチェックしてあげても良いと思います。
```
#さいごに

ご存知の方も多い設定かもしれませんが、意外とkotlin側で設定されていること多かったりしますよね。
ほんの数行の違いかもしれませんが、Fragmentが綺麗だとスッキリしますので、まだFragmentで設定しているよ、という方は是非試してみていただければと思います。