OmniAICreator/Qiita-1.07M huggingface dataset:
MS-DOS時代のリアルタイムレイトレーシング


最近はDLSS使って描画補完してレイトレーシングをリアルタイムに行う事が可能になり、ゲームでリアルタイムレイトレーシングが使えることが現実的なってきたよなぁ、と感じてきたので、そういえば２０年以上マニリアルタイムレイトレーシングやってた人が居たよなーっとの記憶から当時メガデモでリアルタイムレイトレーシングしていた物を紹介してみようかなと思いました。

#１９９６年
もう２５年以上前のフィンランドのイーサルミで開催されたパーティJuhalaで64kカテゴリの３位を獲得した物。実際のイベントは当時も知らなかったのだけど、scene.orgでアップロードされたのでフィンランドのデモパーティを知らなくても当時拾うことが出来て動かすことが出来た。最初に見た印象は何だろう？コレ？だった記憶
ちゃんとアーカイブされていて

https://files.scene.org/view/demos/groups/mfx/mfx_tgr2.zip


scene.orgは現在も健在なので２０２１年でも拾うことが出来る。
#実行
当時のMS-DOS環境が無いとしても実は動作させるのが可能で
DOS BOX使うとWIndows環境で当時のデモを見ることが出来る。

https://www.dosbox.com/

コレを書いている時点ではver 0.74-3　2019年なので若干更新が止まっている気真するけど動作に関しては特に問題ない。

インストールするとディスクトップにDOSBOXアイコンが出現
インストールオプションはデフォルトのまま進めて問題無し
ディスクトップのアイコンをダブルクリックで実行すると
 ![dosbox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908163/9dd8521e-bcfe-9517-cf58-77e698a3f417.png)

この画面がウインドウ表示される。

件のデモmfx_tgr2.zipをdownloadサイトから拾って解凍する。
手元の実行環境だとDドライブにmegademoディレクトリ作成してそこをdemo置き場にしているので、解凍したファイルをそこに置いている。

```
Mount x d:\megademo
```

の様にマウントするとxドライブがdosbox内部でマウントされる。

```
X:
Cd  MFX_TGR
TGR2.exe
```

で実行される。
DosBoxはキーボードの設定が日本語キーボードではなくデフォルトで101英語キーボードなので注意。
\を入力したいときは¥を入力_（アンダーバー）は-のキーのシフト:は;のシフトで入力できる。

![dosbox2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908163/fce3dda9-c29b-22e5-8b20-3e102bbaf469.png)
 
こんな感じで入力すると実行することが出来る。
![demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908163/60333c69-f3aa-2929-23fc-3c75952d004b.png)
 
デフォルトの状態だととっても遅いのでCTRL+F12連打で大体20万サイクルにCPUスピードを上げると滑らかに表示される。
音が出ない….昔はDOSBOXはGUS対応していたのですが、最近はSB16になってしまい、メガデモ定番の「GUSしか音出ません」状態で音が出ません。

実は、youtobeにDosBoxのGUS環境で動作させた動画が上がっている。

https://www.youtube.com/watch?app=desktop&v=kIN0vDdzl-s

#解説
本当はソースコードでもあると良いのだけど当時はGitHubなど無くsvnさえ存在しない時代（かろうじてCVSがあったかも）なので探してみたがソースコードは見つからなかった。残念、なので憶測による解説になるが、当時の一般的なDOS/Vの解像度640x480から、更に解像度を下げて320x240に（ブラウン管の解像度が変更されて反応していたブーンって奴ね）した上にインターレースでの描画そのまま表示せずにfogを焚いてボカして見た目を少しごまかし。サウンドはGUS(ハードウエアでXMやMOD,S3Mなどのサウンドが再生できる)のみで完全にCPUぶん回してレイトレーシングとレンダリングしてのではないかと推測していた。
1996年当時はwindows95の翌年でDirectXがライブラリとして登場したのは良いが安定していなく環境によって動作したりしなかったり、対応したドライバが安定していなかったりと、ゲームやるのならDOSで遊ぶのが当然、洋ゲーではDukeNukemやQUAKEが発売された頃、コンシューマーゲームではプレイステーションとセガサターンが日本では発売され覇権を争い、未だにファイナルファンタジー７は発売されずにいた時代。その様な時代にリアルタイムにレイトレーシングをPCで行うプログラムを作成している事に当時ビビった記憶。まぁ、実際当時動かしてみた感想はリアルタイムでレイトレーシングって相当無茶苦茶だけど、この描画されている物は何だ？って感じだった。ちなみにメガデモはファイルサイズを正気じゃないほど縮小するのが正義だったのでこのデモもzipに圧縮されると64kbyteを切るファイルサイズになっている64k以下のサイズのプログラムでリアルタイムレイトレーシングをやってのけたメガデモは自分の知る限りコレが最初、この後は２１世紀に突入してCPUが高速になってきた頃に再燃して、GPUが使えるようになる事で計算速度が飛躍的に強化され、ゲームではCyberpunkやBattlefieldでリアルタイムレイトレーシングが部分的に採用されるようになって来ている。もうちょっとで現実的な世界に手が届きそう。
Unityで紙吹雪演出をする

# はじめに
<!-- 発端や概要を記載 -->
Unityで紙吹雪的な演出をする機会があったのでメモしておきます。
備忘録のつもりでも書いているのでそのあたりご了承ください〜〜

！！！注意！！！
これはPlaneの性質を使っているため、紙吹雪の裏面は真っ黒です。裏面見せない方法もあると思うけどそれは今回省略で、、、

<!-- 各チャプター -->
# 下準備

まずHiearchy→Effects→Particle Systemを選択しましょう。名前はわかるようにつけましょう。(今回はデフォのままにしてます(サボり))
<img width="300" alt="スクリーンショット 2021-12-15 22.21.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/5bd81334-bf0f-5ad1-2c32-b313c981fee8.png">

ついでに紙吹雪に使うmaterialも作っておきます。今回は銀テっぽくしたかったので光沢もつけて金色に近いものを作りました。




次に、Particleの細かい設定をしていきます。

ParticleのRendererのRenderModeをMeshに、MeshをQuadに、Materialを先ほど作成したものに変更します。(MeshをQuadに変更するのは右にある◉押せばできるよ)
<img width="400" alt="スクリーンショット 2021-12-15 22.36.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/4ab743e3-eadd-a9ce-55f8-460888ea85f9.png">
ParticleSystemのStartSizeから大きさは変更できるのでお好みで変更してください。


# 生成範囲の設定

ちな今はこんな感じです。このままだと上に昇っていって舞ってる感じが全然しないので、ここからまたいじっていきます。
<img width="250" alt="スクリーンショット 2021-12-15 22.38.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/9eae45ff-e32b-5c8e-c25d-2a538c6d0456.png">

ShapeのとこにあるshapeをConeからMeshに変更。その下のTypeはTriangleにしておきます。 MeshはPlaneを選択し、 RandomDirectionは1にしておきます。(数字は見ながらお好みで調節してね)
<img width="350" alt="スクリーンショット 2021-12-15 22.47.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/d7ada4a3-e108-8740-da55-bc7f494b308b.png">
向きと出現範囲はtransformで自由に調節してください。

# 紙吹雪を降らせる

ここからParticleに重力をつけていき落下させます。

ParticleSystemのGravityModifierを0.1くらいに設定してみましょう。
<img width="350" alt="スクリーンショット 2021-12-15 22.54.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/b3d7e557-e989-b093-404a-e6112d56d84c.png">

紙吹雪をくるくる回転させながら落としたいのでRotate by speedをONにし、Angular Velocityを360にします。
<img width="350" alt="スクリーンショット 2021-12-15 22.53.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/3a87ba89-8e4b-646a-c1f1-16b6341dde66.png">


# 追加の要素
あとはお好みでEmission(Rate over Time)とか、Max ParticlesとかDurationを調整してみるといいかと思います。
![スクリーンショット 2021-12-15 23.22.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384741/e81f8677-74ab-020f-ae82-c598d435e50e.png)
これはRate over Time:300,Max Particles:10000,Duration:2で発生位置をカメラからちょっとずらしてます。
MVC、Flux、そしてRedux。アーキテクチャを理解する。

#なぜアーキテクチャを知るのか。
コンポーネント指向のライブラリ・フレームワーク(ReactやVueなど)では、アプリケーションがより複雑なとき状態管理のライブラリの導入を考えるだろう。

アプリケーションが疎結合なコンポーネントのみで成り立っていることは少ないからだ。

当初ReduxやVuexといったメジャーな状態管理のライブラリを見た時、私は直感的にそれらが~~煩雑~~複雑に思えた。
もっと上手く書けるのではないかと、違和感を覚えたのだ。

この違和感を整理するには、Redux(Vuex)がFluxというアーキテクチャパターンに基づいていることを理解すると良いことが分かった。

アーキテクチャを理解することは、複数存在するReactの状態管理のライブラリを選定する際において、今後役に立つかもしれない。

Fluxを知る前に、従来のMVC(MVVM)というアーキテクチャを理解し、なぜフロントエンド開発にそれらが適していなかったのかを知っておきたい。

# クライアントMVC
下記の図を見ることで、視覚的にMVCの問題点に気がつくことができる。
![mvc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1766904/10f9348d-2c3b-8882-a488-2325cafaffa4.png)

ViewとModelが複雑に連結しあっているのが分かるだろうか。

>たとえば表示するタブによってAPIへのリクエストパラメータを変更しなくてはならないケースではどうでしょう。UIにも紐付いたモデルとAPIから得られるデータモデル紐付きも強くなるはずです。さらにフロントエンドには変更希望や機能追加が頻発するため、一画面では既に実装されたModelを参照しながら新しいModelも参照しなければならないといったようにViewとModelの関係はどんどん複雑化していきます。
安達稜・武田（2020） 「フロントエンド開発入門」秀和システム出版

コード量が多く、開発が大きくなるとよりこの問題は顕著になる。
そしてFacebookは、MVCはスケールしないと結論づけたのだ。
参考：[Facebook: MVC Does Not Scale, Use Flux Instead](https://www.infoq.com/news/2014/05/facebook-mvc-flux/)

# Flux　～ユーザーインターフェース構築のためのアーキテクチャ～
Fluxは、単一方向のデータフローを採用している。
![flux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1766904/b54ac9f2-3060-5f24-1130-b030dd1b8cd4.png)

まず全てのデータはDispatcherを経由する。Dispatcherは、Actionに応じてコールバックを呼び出し、Storeのデータを更新する。そしてViewはStoreのデータを監視し、変更があるとコンポーネントツリーを再レンダリングするのだ。
Flux がデータの流れにこの強い制約を与えることで、 Store を安全な状態に保つことができる。
参考：[Flux Application architecture for building user interfaces](https://facebook.github.io/flux/)

Store の状態を予測可能にできることで、 MVCが抱えていた複雑さの問題を解決している。

# Redux　～Single source of truth～
ReduxはFluxに基づく状態管理のライブラリである。

![reduxjpg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1766904/9ab56cc2-5d28-0420-e5fb-9c402a192ffd.jpeg)
出典：[React Redux: A Complete Guide to Beginners](https://dev.to/ashikacronj/react-redux-a-complete-guide-to-beginners-2a45)

Reduxの特徴はFluxでは複数のStateを許容するのに対して、一つのStoreしか許容していない点だ。
Single source of truthであることは、ユニバーサルアプリケーションをつくりやすく、そしてデバッグやテストを容易にしてくれる。
>The global state of your application is stored in an object tree within a single store.This makes it easy to create universal apps, as the state from your server can be serialized and hydrated into the client with no extra coding effort. A single state tree also makes it easier to debug or inspect an application...
[Three Principles](https://redux.js.org/understanding/thinking-in-redux/three-principles#single-source-of-truth)

Reduxは、コンポーネントをまたぐステートを管理する状態管理のライブラリだ。
そして同時に、Fluxというアーキテクチャを採用している。
アプリケーション規模が大きくなるにつれて、有力な選択肢になるだろう。

# 何番煎じかは分からないが、、
MVC(MVVM)、Flux、Reduxの詳しい説明は、他記事が参考になる。
下記のサイトを参考に、何番煎じかは分からないが今回の記事を作成した。
※既に述べたものは除く。
[Fluxとは何か MVC, MVVMとの違いも含めて](https://namu-r21.hatenablog.com/entry/2018/03/21/232726)
[Flux パターンが解決した課題](https://techblog.roxx.co.jp/entry/2019/06/12/134154)
[JavaScript: Reduxが必要なとき/不要なとき（翻訳）](https://techracho.bpsinc.jp/hachi8833/2021_06_03/53183)
若い子に「ITで失敗してもリカバリができるんだよ」と教えるまで

## プログラムの事を書けって言ったよね？
すいません、でも、今ITの現場で結構起きてる事なんです。はい。

## 今の若い子は失敗を極度に怖がる
若い子の面倒を見るようになってまず気になる事は、**若い子は失敗を極度に恐れて、恐れすぎて、逆に失敗してしまう事が多い**という事だ。
失敗するぐらいならやらない、という思想の子が多いように感じている。
そういう時代なのかも知れない。

## まず経験すべきは「失敗すること」
ただ、**仕事で失敗しないなんて事はあり得ない。**
誰しもが失敗し、失敗からいっぱい学んで、隙を無くしていくのだ。
なのでまずやらせる事は「**ITの世界は失敗してもだいたいリカバリができる**」という事を学んでもらう事ではないだろうか。

## 「リカバリの効く失敗」を経験させよう
自分の場合は、viの使い方を教えることで失敗を学ばせた。
/tmp/test.txtを開いて、特定のパターンの文字列を入力して、セーブする、という作業だ。この作業は遊びではない。「設定ファイルを変更する」など、未来を見据えた作業だ。
これであれば、rootでもなければ、よっぽどの偶然がない限り、サーバにダメージが行くような事は無いはずだ。
(**:w ~/.ssh/id_rsa.pubなんて入力する確率は0%**だろう。多分。)
いくら失敗しても、:q!でいくらでも無かった事にできる。
viの使い方も判るし、コンピュータの世界に入る一歩としてはかなりいいのではないかと自負している。

## 失敗は友達
先輩は、よっぽどの失敗でもなければ、若い子を叱らないで欲しい。
何しろ極端に「**失敗して怒られる事を怖がっている**」世代なのだ。
自分だっていっぱい失敗したのだから、優しくリカバリを教えてあげればいい。教えて君になったらググる事を教えてあげればいい。
とにかく**乗ってしまえば一流のパフォーマンスを発揮する。**それが今の若い世代なのだ。
乗るまでは、待ってあげよう。
Event Report of OSS Management Forum 2021

#はじめに
こんにちは。あるいは、はじめまして。
OpenChain Japan WGの渡邊歩です。OSS活用に関するコンサルをしています。好きなライセンスは、[Beerware License](https://spdx.org/licenses/Beerware.html)です。
今日は、2021年12月1日～3日に開催されたオンラインセミナー、**<font color="Red">OSSマネジメントフォーラム2021~トヨタ/ユニ・チャーム/ソニー/メルカリ/NEC/富士通/日立が大集合～</font>**のイベントレポートをお送りします。

#OSSマネジメントフォーラム2021の概要
本セミナーの概要は下記の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528217/7b25cc79-9ccd-3f90-11dc-4bf56ffbedc0.png)
今回は、OpenChain JapanWGで活躍しているOSSコンプライアンスのプロフェッショナルの方々をお招きし、パネルディスカッション形式で色々なトピックスについて語っていただく、非常に密度の濃い1時間×3日間のセミナーをお届けすることができました。資料配布NG、録音や画面のキャプチャNGで行われた非常に貴重なセミナーの模様を、特にOpenChainに関するところを少しだけピックアップして公開しちゃいます。

#イベントレポート
**<font color="Red">Day1は「どうするべきか？企業のOSSコンプライアンス業務」をテーマに、ユニ・チャームさん、トヨタ自動車さん、日立製作所さんの知的財産部門の方々にそれぞれの会社でどのようなタスクを行っているのか、またそれに対する工夫点などを共有していただきました。</font>**各社に共通的だった事項として、OSSライセンスに関するコンプライアンス遵守のための取り組みや特許調査などに加え、社内のエンジニアに対する啓発活動を知的財産部門が担当しているということがわかりました。過去の係争事例やホラーストーリーなどを通してリスクを理解して貰った上でライセンス遵守を促すような内容で、会社によってマンガ形式にしたり生々しい具体事例を含めたりという工夫をしながら、他言語に翻訳し全世界向けに提供しているとのことでした。


**<font color="Red">Day2は「先輩事例に学ぶ！OSS専門組織(OSPO)の作り方」と題して、メルカリさんとソニーさんのOSPOについて教えていただきました。</font>**それぞれの会社のOSPOの成り立ちは全く違うものの、両社とも同じ「コミュニティの良き一員であろう」という目標を掲げて活動されているというのが印象的でした。また、このような活動を通じてエンジニアのEmployee Engagementを向上し、それが企業風土や採用、ひいては本業のビジネスに良い影響を与えていくというプラスの循環についても言及されていました。単なる管理のための組織ではなく、社内の雰囲気の醸成やエンゲージメントの向上をOSPOという組織が担っているというメッセージが印象的でした。

**<font color="Red">Day3は企業のOSS活用推進やいま話題のSBOMについて、NECさんと富士通さんにお話しいただきました。</font>**OSS活用推進の活動の中では、使用するOSSのライセンスや脆弱性のチェック、技術情報の発信、教育などを行っており、複数の専任メンバーが国外のグループ会社を含めた企業全体のポリシーに基づく管理・サポートを担当されているとのことでした。SBOMについては、以前から社内ではSBOMの作成・管理を行っており、必要に応じて管理要素を増やしたり減らしたりしながらフォーマットを工夫し続けている、管理することによって得られた統計的な情報を社内で共有するなどの情報の活用も行っているとのことでした。SBOMのフォーマットの共通化については、今後どのフォーマットが主流になってくるかを見極めつつ、どうなっても良いように準備をしておいた方が良い、営業や調達などの担当者にも理解して貰う必要がある、というようなお話がありました。

#おまけ
Day3では、バイデン政権のサイバーセキュリティ大統領令で言及されているSBOMの代表的な3種類のフォーマットに関しての投票を行ったのですが、その結果が興味深かったので共有します。今年ISO化されたSPDXの**勢いが感じられる**結果となりました。**<font color="Red">面白いですね！</font>**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528217/13edbc01-a2c4-6757-14f9-1a3ed99d98af.png)


***
Pandasで複数の条件で絞り込む

# 概要
サッカーJリーグの2017年から2019年シーズン成績のcsvを
pandas.DataFrameで読み込んだものを条件指定で絞り込む

# 前提
1.絞り込みたいcsvデータを所定のパスに配置していること
2.Python、pandasの環境構築が済んでいること

過去の記事からの流れの記事です
　過去記事：https://qiita.com/wooooo/items/ab55104b4ae031291a62
  (こちらに対象のCSVデータについてリンクがあります）

# 実装編

```python:analysis.py
# -*= encoding: utf-8 -*-
import pandas as pd

# csvファイルのパス(任意)
csv_path = '/Users/app/csv/J. League Data Site.csv'

# csvファイルを読み込む
data = pd.read_csv(csv_path)

# 出力
print(data)
```
![スクリーンショット 2021-12-13 23.04.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/c3f79913-a43c-da81-d2e4-6b69213c647e.png)

このように、"Year"や"Result_Home"など項目があります。

csvファイルを見ると、"Home"、"Away"というホーム・アウェイ側のチーム名の項目があるので
「川崎フロンターレのホーム」側のデータを出力してみます

```python:analysis.py
# 川崎フロンターレで絞り込み
print(data.query('Home == "Kawasaki-F"'))
```
![スクリーンショット 2021-12-15 22.23.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/d669f7f0-adee-a3a9-f791-8c56f6843e13.png)


csvには複数の項目があるので
続いて、「2017年」の「川崎フロンターレのホーム」側のデータを出力してみます

```python:analysis.py
# 2017年の川崎フロンターレで絞り込み
print(data.query('Home == "Kawasaki-F" & Year == 2017'))
```
![スクリーンショット 2021-12-15 22.44.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/b51c2bd3-4bf3-10cf-cffc-f79438c05520.png)

2017年から2019年の3年分から2017年だけの
川崎フロンターレがホームの成績だけに絞り込めました

```python:analysis.py
# 2017年の川崎フロンターレのホームの1試合平均
print(data.query('Home == "Kawasaki-F" & Year == 2017').mean())
```
![スクリーンショット 2021-12-15 22.48.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/6005094b-51b2-af22-8faa-f69b01216196.png)

ソースコード全体

```python:analysis.py
# -*= encoding: utf-8 -*-
import pandas as pd

# csvファイルのパス(任意)
csv_path = '/Users/app/csv/J. League Data Site.csv'

# csvファイルを読み込む
data = pd.read_csv(csv_path)

# 2017年の川崎フロンターレのホームの1試合平均
print(data.query('Home == "Kawasaki-F" & Year == 2017').mean())
```

今回はcsvをpandas.read_csvで読み込んだDataFormatを
絞り込む方法を記事にしました
その他、pandasで学んだことを記事にしていきます！
Blazorアプリでテキスト翻訳する仕組みを実装する

今回はBlazorアプリケーションにGoogle翻訳を使って、テキスト翻訳する仕組みを実装する例をご紹介したいと思います:rocket:

**[デモ](https://blazorappforgas.web.app/)**

https://blazorappforgas.web.app/

![forgas4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110304/c8361297-9f85-734f-6b77-bb9133fb0cca.gif)

#概要
今の時代、twitter,Instagram,tiktokやYoutubeなど、ありとあらゆるグローバルなコンテンツに自動翻訳する機能が当たり前についてくるようになってきました。そこで今回は、Blazorアプリケーションにテキスト翻訳する機能を実装してみたいと思います:thumbsup:

翻訳する機能はGoogle翻訳をGoogleAppScript(GAS)経由で呼び出します。GASからGoogle翻訳を呼び出す機能にあたっては、参照させて頂いた記事を参考に実装します。

**[Google翻訳APIを無料で作る方法](https://qiita.com/satto_sann/items/be4177360a0bc3691fdf)** ( @satto_sann さん)

https://qiita.com/satto_sann/items/be4177360a0bc3691fdf

#実装
今回はGoogle翻訳を無料で使ってしまおうという簡易的な方法で実装です。非常に簡単な実装になりますが、APIにリクエストしてJSON形式で受け取り、C#ソースでは変数に格納、表示の更新。。実に簡単に実装ができてますね:writing_hand:

```javascript:Index.razor
@page "/"
@inject HttpClient Http

<PageTitle>Index</PageTitle>


<div class="alert alert-secondary mt-4">
    <p>@str1</p>
    <a href="" @onclick="@(_=>OnClick(1))">メッセージを翻訳する</a>
</div>

<div class="alert alert-secondary mt-4">
    <p>@str2</p>
    @if(str3?.Length>0)
    {
        <p>@str3</p>
    }
    <a href="" @onclick="@(_=>OnClick(2))">メッセージを翻訳する</a>
</div>



@code {

    string? str1 = "We cleaned the conference room as customers are scheduled to come in the afternoon.";

    string? str2 = "Today is Friday. I'm going to my friend's house on Friday. I go home at night. My mother is worried and calls.";
    string? str3 = "";

    private async void OnClick(int i)
    {
　　　　👇APIリクエストして、、
        var ret = await Http.GetFromJsonAsync<APIRet>("https://script.google.com/macros/s/AKfycbwFUkQusbcQNPmFRnX6A8wXyxYbe_QjRvk9yAcd6_UEQ4g_sfWGZDSXk5AkKo-UPvmsSw/exec?text=" + (i == 1 ? str1:str2) +"&source=en&target=ja");

        if(ret?.Code == 200)
        {
            if(i==1)
            {
　　　　　　　　　👇変数に格納
                str1 = ret?.Text;                
            }
            else
            {
                str3 = ret?.Text;
            }
　　　　　 　👇表示を更新
            this.StateHasChanged();
        }
    }

    public partial class APIRet
    {
        public long Code { get; set; }

        public string? Text { get; set; } = "";
    }
}
```

Blazorの表示更新は、Razor構文で直感的に書けるでの、C#開発者にとってはとてもとっつきやすいのではないでしょうか。
例えば、2つ目のメッセージでは、原文を残してその下に翻訳されたメッセージを差し込んでいます。HTML上に`if`などを使うことができ、また、コード量が少なくて済むところが、Blazorアプリケーションの良いところではないでしょうか:blush:

```javascript:
<div class="alert alert-secondary mt-4">
    <p>@str2</p>
    @if(str3?.Length>0)  👈文字がある時だけ表示
    {
        <p>@str3</p>
    }
    <a href="" @onclick="@(_=>OnClick(2))">メッセージを翻訳する</a>
</div>
```

#おわりに
簡易的ではありますが、Blazorアプリケーションにテキスト翻訳を行う機能の実装例をご紹介しました:ok_hand:
今回はGASを使用した例ですが、BlazorアプリケーションはAPIと連携するのが思いのほか簡単に実装できるので、ぜひ試してみてください:zap::zap::zap::rocket:

今回も小ネタになってしまいましたが、何かのお役に立てれば幸いです:bow_tone1:
【Python】月末日を取得する方法

###月末の日付を取得する方法をメモしておきます。
###①dateutilライブラリを使用する
標準ライブラリのtimedeltaでは、日付に加算・減算はできますが、月の加算はできません。
そのため外部ライブラリのdateutilを使用します。

外部ライブラリなので、まずはインストールします。

```
$ pip install python-dateutil
```

今月の末日を取得する処理を例に解説をします。

```python
import datetime
from dateutil.relativedelta import relativedelta

today = datetime.date.today()  #　2021-12-15

last_day_current_month = today + relativedelta(months=1, day=1) - relativedelta(days=1)
print(current_month_lastdate)
# 2021-12-31

```
1つ目の足し算で来月の1日となります。
2つ目の引き算で１日引き算をしているので今月の末日となります。
[dateutil/relativedelta](https://dateutil.readthedocs.io/en/stable/relativedelta.html)


###②calendarライブラリを使う
こちらは標準ライブラリですので、インストールは必要ありません。

```python
import calendar

print(calendar.monthrange(2021, 12))
# (2, 31) <- (1日の曜日, 指定月の日数)
```
戻り値を見てみると
2番目の値が指定月の日数、すなわち月末日を表します。
ちなみに1番目の値は、1日の曜日を表します。
月曜日から日曜日までを0から6で表しますので、2は火曜日ということになります。
[Python/Calendar](https://docs.python.org/ja/3/library/calendar.html#calendar.monthrange)


###まとめ
月末日付のdate型もしくはdatetime型を取得する場合は①dateutilライブラリを使用して
指定月の翌月の1日から1日引き算することで、指定月の末日が取得できます。

月末が何日までなのかを取得する場合は②を使うと簡単に月末日を取得できます。
ネットワークが遅い環境でVS Code の Remote SSH のターミナルの表示が正しくないのをどうにかする

## 環境
VS Code 1.62.3

## 現象
表示は正しいのにenterを押すと画面に表示されていない文字列が送信されている。

```bash
$ redis-cli -n 0 --raw hget 'hogehoge'
Unrecognized option or bad number of args for: '--rawhget'
```
どうもカーソル移動した際に実際に移動した数と表示上のカーソルの位置がずれているっぽい。
Ctrl+Lで真に入力されているものに更新されるのでそれでしのいでいたが、だんだん辛くなってきたのでターミナルの設定を上からなめていった。

## 解決方法
>Terminal › Integrated: Local Echo Latency Threshold
試験的: ネットワーク遅延の長さ (ミリ秒単位)。ローカルの編集内容はサーバーの確認を待たずに端末にエコーされます。'0' の場合ローカル エコーは常にオンになり、'-1' の場合は無効になります。

これを-1にしてみたところ、ズレは発生しなくなった。
mapbox メモ

<strong>地図の生成</strong>
<p>まず初めにする</p>

```
mapboxgl.accessToken = "yourtoken";
const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/light-v10",
  center: [139.7671, 35.6812], // 東京の場合
  zoom: 4
});
```

<strong>カスタムマーカー</strong>
<p>ピンなど地図にマーカーをつける場合</p>

```
map.on("load", () => {
  // カスタムマーカーとして使用する画像を追加する
  map.loadImage(
    "画像のurl",
    (error, image) => {
      if (error) throw error;
      map.addImage("custom-marker", image);
      // geojsonを追加する
      map.addSource("points", {
        "type" : "geojson",
        "data": {
          "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "geometry": {
                "type": "Point",
                "coordinates": [
                  139.7671, 35.6812
                ]
              },
              "properties": {
                "title": "Mapbox DC"
              }
            },
          ]
        }
      });

      // 記号のレイヤーを追加する
      map.addLayer({
        "id": "points",
        "type": "symbol",
        "source": "points",
        "layout": {
          "icon-image": "custom-marker",
          "text-field": ["get", "title"],
          "text-font": [
            "Open Sans Semibold",
            "Arial Unicode MS Bold"
          ],
          // ここでテキストの位置を設定
          "text-offset": [0, 1.25],
          "text-anchor": "top"
        }
      });
    }
  );
});
```

<strong>水の色を変える</strong>

```
map.setPaintProperty("water", "fill-color", "#262626"); // 黒
```
C#でデバッグ時のみ実行する処理を書く


## はじめに
C#でローカル環境だけで動かしたい処理がありました。
調べてみると、プリプロセッサディレクティブを使って`#if DEBUG`のように記述すると、`[Conditional("DEBUG")]` のように記述して属性を付与する二つの書き方があることがわかりました。
初学者向けに単語の説明も交えながら簡単にまとめてみました。
プリプロセッサディレクティブ使うやり方を方法１、属性を付与するやり方を方法２としています。

## 目次
[方法１（プリプロセッサディレクティブ）](#方法１プリプロセッサディレクティブ)
[方法２（属性）](#方法２属性)
[まとめ](#まとめ)




## 方法１（プリプロセッサディレクティブ）
### 基本的な書き方
```
public void TestMethod()
{
#if DEBUG
    Console.WriteLine("デバッグ時に実行");
#else
    Console.WriteLine("デバッグ以外で実行");
#endif
}
```

### 解説
プリプロセッサディレクティブを使用して、`#if`、`#else`、`#endif`をシンボルの定義に基づいて条件付きコンパイルを制御しています。ざっくり用語の解説をします。

#### プリプロセッサディレクティブ
- `#if`、`#else`、`#endif`の部分
- コンパイルの前に行う処理のこと


#### シンボル
- `DEBUG`の部分
- `#if`などの後ろに記述する
- コンパイル時に生成するIL（中間言語）を切り分けるのにプリプロセッサディレクティブと組み合わせて使われる
- コンパイルするコマンドのオプションでシンボルを定義できる
- `DEBUG`はビルド構成プロパティのデバッグモードやリリースモードで自動的に指定できる




#### 条件付きコンパイル
次の 4 つのプリプロセッサ ディレクティブを使用して、条件付きコンパイルを制御します。

- `#if`    
条件付きコンパイルを開く。コードは、指定されたシンボルが定義されている場合にのみコンパイルされる。
- `#elif`   
前の条件付きコンパイルを閉じ、指定されたシンボルが定義されている場合、新しい条件付きコンパイルを開く。
- `#else`   
前の条件付きコンパイルを閉じ、前に指定されたシンボルが定義されていない場合、新しい条件付きコンパイルを開く。
- `#endif`　   
前の条件付きコンパイルを閉じる。

仕組みとしては、C# コンパイラが、`#if` ディレクティブ、次いで `#endif` ディレクティブが検出すると、条件で指定されているシンボルが定義されている場合に、ディレクティブ間のコードがコンパイルされます。
簡単に例をあげると、`DEBUG`でシンボルを定義してコンパイルすると`#if DEBUG`以降の処理が実行されます。


### 実用的な書き方
以下のような発展的させた実用的な書き方がありました。

```
internal static class AssemblyState
{
    public const bool IsDebug = 
#if DEBUG
    true;
#else
   false;
#endif
}

public void Foo()
{
    if(AssemblyState.IsDebug)
    {
        Console.WriteLine("デバッグ時に実行");
    }
    else
    {
        Console.WriteLine("デバッグ以外で実行");
    }
}

```

### 解説
プリプロセッサディレクティブをまとめて書くために1つクラスを用意しています。 
それにより、分岐したい部分が複数あっても、`#if`を書くのは一ヵ所で済みます。

### メリット   
実行時に分岐処理が発生せず、処理速度が落ちない。    

実行時に分岐が定数の場合はJITコンパイラコンパイル時に不要な`#if`と分岐を削除し、機械語レベルで最初のコードと同じになります。つまり、IL には分岐が存在するが、機械語には分岐がないため実行速度も落ちません。


## 方法２（属性）
### 記述例
```
[Conditional("DEBUG")] 
public static void ShowMessage(string str) 
{ 
    Console.WriteLine(str); 
}
```
※Attributeを省略してConditionalでも記述可能

### 解説
- 属性（attribute）
- クラスやメンバに追加情報を与える
- DEBUGがシンボルで定義されている時のみ有効となる

### メリット
- コード量が少なくてすむ

### デメリット
- 使用できる場面が限られている   
クラスか戻り値のないメソッドに使えるが、戻り値のあるメソッドには使えない。

## まとめ
デバッグのみで動かしたい処理が複数箇所ある場合は方法１の実用的な書き方が使いやすいです。
戻り値のないメソッドの場合は方法２がコード量が少なくて見やすいのでおすすめです。
また、個人的にこの記事を作成するにあたってC#が動く仕組みについて理解する良い機会になりました。
初学者の方は本記事に沿って単語を理解してみてはいかがでしょうか。

## 参考URL
[C# プリプロセッサ ディレクティブ](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/preprocessor-directives)
[#if DEBUG を使わないデバッグ分岐](https://ikorin2.hatenablog.jp/entry/2020/06/27/065646)
[属性](https://ufcpp.net/study/csharp/sp_attribute.html)
C#でソケット通信を行うためのTcpClientToolを作成

# 前置き
ソケット通信の勉強がてらにソケット通信用のクライアントツールを作成しました。

※UIについてはご愛嬌
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/10f6a733-6c56-b3eb-81e0-2ffeaa71a8f0.png)

MSDNを参考に、UIブロックをしないよう非同期にしたり、
接続先の保存など、すこしだけ実用性を考慮してます。

せっかく作ったのでGithubで公開しました。
https://github.com/shinnosukekubo/TcpClientTool
C++/CLIでグローバル変数にハンドルを保存する方法

#1. はじめに

C++/CLIでハンドルをグローバル変数に保存しようとして、

```cpp
static System::String^ s;
```

などと書くと、
「静的ストレージ存続期間のある変数にハンドルや追跡参照型を指定することはできません」
とコンパイルエラーになります。

なんとかハンドルをグローバル変数に保存したく、下記の方法を考えました。
C++/CLIは詳しくないので、問題ないかどうかまだ評価中です。

Windows 10、.NET Framework 4.8、Visual Studio 2019で確認しています。

#2. GCHandleを使う

```cpp
using namespace System;
using namespace System::Runtime::InteropServices;

static GCHandle gcStr;

int main(int argc, char** argv) {
	System::String^ str = "abc";

	// アンマネージドメモリに保存
	gcStr = GCHandle::Alloc(str);

	// 保存したハンドルを取り出す
	System::String^ str2 = safe_cast<System::String^>(gcStr.Target);
	
	Console::WriteLine(str2);
}
```

#3. 参考
[C++/CLI #5: safe_cast (mixi 日記アーカイブ)](https://loafer.jp/mixi/diary/class.xsp?2007-09-04-18-44)
Teams: エンゲージメントの確認をしつつ Power BI を広めよう

# 背景
Microsoft の方に教えてもらったエンゲージメント確認方法が非常に簡単で、Power BI の良さを Teams 利用者に広めるのに便利そうだったので。

# 概要
Teams の利用分析は、以下の方法が主だと思ってました（管理用のは別で）

- Teams 標準の分析<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/fc8ea9df-0d27-98d4-d2c5-0838dad5507e.png)
- Teams Connector を利用した Power BI での分析<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/05a8725c-c0db-f1b2-2975-f1d4816e1155.png)

それが、以下のやり方で、ボタンポチポチでもっと簡単に、自分と、自分の所属するチームの分析が出来るようになってました。
これを使って、Power BI のレポート操作もしてもらえば・・

1. Power BI いいね！
1. Power Query いいね！
1. Power Platform 使ってみよう！
という三弾展開が期待できる・・・筈 :laughing:

# やり方
1. アプリ追加<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9027c58f-72d0-63fc-c9aa-218e6dd35c27.png)
1. 「作成」を選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/68c00903-c103-27ee-2b4a-cd6b6bfd767b.png)
1. 「お客様のTeams のデータを分析」を選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/db4139b0-359a-6189-c6d6-a524e8244571.png)
1. （日本語版で使う場合は）以下のクエリの「ナビゲーション」ステップで、"Name" → "Key" に変更
    1. Teams usage
    1. Teams user activity
    1. Active Teams<br>
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/dc353ca1-eec1-521f-2d13-9730c37f7825.png)

## 動画でどうぞ
![Teams分析.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/195a790c-afd6-52c9-dc4b-78c92f98a045.gif)


# 自分で改造出来る？
出来ますよ

1. まずはダウンロード<br>![2021-12-16_09h06_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/4d97f029-1710-6260-e0ae-04ec251e86b5.png)
1. 中身を見ると、上述した以下のコネクターを使用しているだけ。<br>![2021-12-16_09h13_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/eacd4b6f-0413-2193-dd3d-a2d78f72122f.png)
1. （日本語版で使う場合は）以下のクエリの「ナビゲーション」ステップで、"Name" → "Key" に変更
    1. Teams usage
    1. Teams user activity
    1. Active Teams<br>
    ![2021-12-20_13h05_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/88b1d455-b2c1-1f7a-3fc2-9482807e2150.png)
1. あとはよしなに編集
1. マイワークスペースに公開して上書きすればOK

# 参考情報
https://docs.microsoft.com/ja-jp/power-bi/collaborate-share/service-teams-analytics

https://docs.microsoft.com/ja-jp/microsoftteams/teams-analytics-and-reports/user-activity-report

# keyword
easiest way of analyzing teams activity to spread Power BI
GoのDuck Typingを活用する

本記事は Go Advent Calendar 2021 の16日目の記事です。

https://qiita.com/advent-calendar/2021/go

## はじめに🎄
Clean Architectureの概念にそって、GoでWebのBackend APIを開発する時に
依存性の注入が多く、特にデータのCRUD処理を行うRepositoryが課題になったので解決策を考えてみました。

## Repositoryが多くなる問題
例えばECサイトでユーザーが購入をするユースケースの場合、
ざっくりと`売る人`, `商品`, `買う人`があって、そのデータたちの取得と保存をするRepositoryがそれぞれあるとします。

その場合、購入のユースケースに必要なリポジトリは3つ以上になってDIするときもコードが長くなって可読性が落ちることや、機能追加時に必要なRepositoryが増えると、更にusecaseに追加するなどによって保守性が低くなります。

```go
type ConsumerUsecase struct {
	consumerRepo repository.ConsumerRepository
	productRepo  repository.ProductRepository
	sellerRepo   repository.SellerRepository
	// ... どんどん追加される😰
}

func (u *ConsumerUsecase) Buy(consumerID, productID int) error {
	product := u.productRepo.GetProduct(productID)
	if product.IsSoldout() {
		return errors.New("Soldout")
	}

	if err := u.consumerRepo.Buy(product); err != nil {
		return err
	}

	seller := u.sellerRepo.GetSeller(product.SellerID)
	u.Notification(seller)

	return nil
}
```

### 複数のテーブルをまたぐ処理は?
単純にRepositoryが増えるだけでなく、複数のテーブルをまたぐ処理の場合(特にトランザクションを張る必要がある処理)は、どのRepositoryに処理を置くべきか基準が曖昧になって、命名にも迷うことになり設計にブレが発生します。

## UsecaseごとにRepositoryを作ったら？
では、usecaseごとに一つのRepositoryを持つ形だと先程の問題が解決できそうです。
しかし、各リポジトリごと同じメソッドがありまして、実装部をinterfaceごと作ってしまうと、コードの再利用がうまくできない場面が発生します。

```go
// 買う人のUsecaseで使われるrepository
type ConsumerRepository interface {
	GetConsumer(id int) model.Consumer
	GetProduct(id int) model.Product // 商品情報は買う人側でも必要な情報
	LikedProducts(id int) []model.Product
	...
}

// 売る人のUsecaseで使われるrepository
type SellerRepository interface {
	GetConsumer(id int) model.Consumer
	GetProduct(id int) model.Product // 商品情報は売る人側でも必要
	SaleHistory() []model.Sale
	...
}
```

:::note warn
「買うと売るは一つのユースケースじゃないか！」と思いますが、例えのためのコードですのでご了承ください。
:::

各Repositoryごとに実装を分けるとソースコードのファイル管理面的には利点がありますが、同じ役割をするメソッドを両方書くのは無駄で、保守性が低くなります。
また、重複する部分は関数に取り出すのも考えましたが、元の引数とDBコネクションまで渡す必要があります。

### Duck Typingを活用しよう 🦆
GoはDuck Typingを採用しているので、活用すればシンプルに解決できるかと思います。
すべてのRepositoryのメソッドを一つの実装部にまとめて置くと、実装の重複もなせるし、命名やコードを置く場所を悩むことは減ると思います。
interfaceを満たさないことがあればビルドもできず、Compilerが教えてくれるので実装漏れは防げます。

```go
type SqlRepo struct {
	db *sql.DB
}
func NewSqlRepo() *SqlRepo {
	return &SqlRepo{}
}

func (r *SqlRepo) GetConsumer(id int) model.Consumer {
	...
}
func (r *SqlRepo) LikedProducts(id int) []model.Product {
	...
}
func (r *SqlRepo) OrderHistory(id int) []model.Product {
	...
}
func (r *SqlRepo) GetProduct(id int) model.Product {
	...
}

...

func (r *SqlRepo) SaleHistory() []model.Product {
	...
}
```

ただ、repositoryのメソッドが多くなって、各実装自体も複雑で長くなれば、一つのファイルで管理するのは
読みづらさとコンフリクト等の課題が新たに発生します。
その時は、構造体とConstructor、返すモデルごとなど、いくつかのファイルに分けるのもありかと思います。

構造体とメソッドが別ファイルになるのはデメリットがありそうですが、パッケージに他の実装を入れない構成での運用やIDEの機能でカバーできるので、前述した課題に比べるとさほど辛くはないと思います。

## まとめ🎅🏼
今まで私は、一つのinterfaceに紐づく一つ以上の実装はよくやっていましたが、
Duck Typingを活用した複数のinterfaceに紐づく一つの実装はあんまりやっていませんでした。
この方法で業務のGo x Clean Architectureで開発しているところも改修してみようと思います。

Goを勉強し始めた頃、このDuck Typingを理解するのが難しかった覚えがありますが、よく活用すると利点が多くありそうです。
エンジニアが詐欺サイトに引っかかるまで

# はじめに
本記事はWeb開発エンジニアの私が詐欺サイトに引っかかるまでの経緯を赤裸々にノンフィクションで解説していきたいと思います。


## 10月下旬
11月末に控えた妻の誕生日に生まれ年のワインをプレゼントしようとググってみると良さげなサイトを発見:bulb: → https://love-wine.jp/vintage/
※安心してください。まだ詐欺サイトではなく優良なサイトです:wine_glass:

このサイトで味もラベルも好きそうなドンピシャなワインを見つけるも既に「**終売**」:sob::sob::sob:
諦めきれずに他のワイン販売サイトで同じ銘柄を探すも「**在庫なし**」:cry:


## 11月上旬
少し時間を置き、再度ワイン探しの旅を開始 :mag_right:
すると、なんとお目当てのワインを発見 :heart:

:::note alert
:warning: :skull: ↓実際の詐欺サイトです↓ :warning: :skull:
<img width="300" alt="sagi_site.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/9d6b06b6-680e-9824-ebaa-927dc7180cc9.png">
:warning: :skull: ↑実際の詐欺サイトです↑ :warning: :skull:
:::
しかも送料無料で半額だと:heart_eyes:

## 購入前確認作業
すぐにでも購入したい衝動を抑え、冷静に信頼出来るサイトかどうかの確認作業を始める :eyes:

- SSL証明書 → ○
- サービス名存在確認 → △
    - 同名のサイトは存在するも主に化粧品を取り扱っている
    - サービス名だけで検索するも詐欺サイトにはたどり着けない(ドメインが異なるから当たり前)
- ドメインチェック → ×
    - サービス名とは全く異なるドメイン

## 購買意欲との葛藤
恐らくそこまで購買意欲が高くなければ上述の確認結果から怪しいサイトと判断し、購入を見送っていたかもしれない。しかし誕生日までの期限が迫り、焦りもあったのか私の思考回路はこうなっていた。

- 同名のサイトは存在するも主に化粧品を取り扱っている
    - 化粧品以外にもきっと他の商品も取り扱いはあるだろう :thinking:
- サービス名とは全く異なるドメイン
    - 幅広く事業を展開していてサービス名とドメインが異なる事情もわからなくもないな :thinking:

## いざ購入！
しばらく葛藤していたが、**送料無料+相場の半額**の誘惑に負け、購入を決意 :money_with_wings: 
個人情報を入力し、注文ボタンを押した。:point_down: 

(実際に届いたメール本文上部)
<img width="300" alt="sagi_mail.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/f43b8ef7-de09-eca2-27f2-0c1a2b4f7737.png">

## 感じた違和感
モザイクをかけているのでわからないが、差出人は知らない日本人名でメールアドレスもTLDは一緒だがドメインがそもそも違う。メールを受信した時点で少し違和感を感じながらも最後まで内容の確認を進めた:eyes:

(実際に届いたメール本文下部)
<img width="300" alt="sagi_mail_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/c0ee4c85-e578-2a41-7ad2-66c17cdad9d1.png">

## 決定打
おわかりいただけただろうか:interrobang:

:::note warn
差出人は日本人なのになぜか振り込み先口座名義は外国人名
振込手数料を引いてから入金すればいいです。(敬語じゃない一文)
:::

この時点で違和感がほぼ確信に変わり、このワインの購入は断念しました。
ただ個人情報は既に入力してしまっていたため今後の警戒は必要です :cry:

## ウェブサイトの安全性確認サービス
色々と疑っていながらもなぜ[こういうサービス](https://check.gred.jp/)で調べようと思わなかったのが不思議ですが、調べた結果は...
<img width="400" alt="site_check_result.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/cb9a51a0-d8ea-ff70-1185-f505f2708c43.png">
見事に**フィッシングサイト**でした :fishing_pole_and_fish:
クレジットカード入力ではなく銀行振込だったのは不幸中の幸いでした:sweat_smile:

## 振り返り
- エンジニアだろうが騙されるときは騙される←
- ウェブサイトの安全性確認サービスで事前に確認する
- 疑うことをやめない

## 後日談
誕生日には別のワインを無事に探し、その日に渡すことが出来ました:gift: (ちゃんちゃん)
android版dxlibの使いかた（2021年12月）

　アドベントカレンダーに投稿する記事の3番目です。
　今回は、dxlibのandroid版の使いかたです。今回何かandroid版を使って記事を書こうとしたら色々と苦労したので苦労したところを共有しようと思いました。なお、あくまでも私の環境で成功した方法ですし、アプリを公開する予定はないので自分のスマホで動けばいいの精神で開発しています。アプリを公開する人は気を付けてください。

# 前提条件
　android版を使うには以下のものが必要です。

* android studio
  (visualstudioでも開発できますが、今後を考えると絶対にandroidstudioにしてください)
* android版dxlib

# 環境構築
　1からすべてを説明するには大変なので、ある程度公式サイトに書かれていることは省略させていただきます。※最初にandroid版dxlibの加工する工程がありましたが管理人さんが対応したことにより消去しました。
 
1. 公式サイトを参考にandroidstudioでプロジェクトを作成する。
   注意することがあって、途中にあるminimumSDKというところをAPI26にすることです。
   こちらの環境ではデフォルトはAPI21となっていました。
   正確には必須かはわかりませんが、ここで指定しているのが低すぎると一部機能がきちんと動かない可能性があります。ちなみに、ここで公式サイトではNDKが無いとエラーが出ると書いてありますが、こちらで確認した限りでは自動でダウンロードされました。
1. 次にAndroidManifest.xmlを編集します。公式のものにいくつか修正が必要です。11行目の@style/AppThemeを@style/Theme.(プロジェクト名)、13行目のandroid:name=".MainActivity"の後ろの>の前で改行してandroid:exported="true"というのを追加します。
1. 公式サイトの通りにCMakeLists.txtを変える。
1. （ここは今のところ警告だったと記憶してるのでやらなくてもいいですがやった方がいいです。）setting.gradleのrepositoriesというところのJCenter()というところを消す。コメントで警告が書いてあるので場所はすぐにわかると思います。
1. ここが一番わかってなく、管理人さんとの違いを考えるといまいち条件がわかっていません。build.gradle（Moduleなんとかってカッコに書いてあるやつです。もう一つと間違えないように）を開きます。一番下のdependenciesというところを確認します。

```
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
```
となっていたら僕と同じ状態で、ビルドすることができません。どうやら、バージョンが高すぎるようです。(API31を使うなら上記のままでもいいですがこちらでは正常に起動できることを確認できていません。)

```
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'    
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
```
という風に変更してください。本当はむやみやたらに変更したらよくなさそうですが、管理人さんが正常に実行できることを確認しているプロジェクトと同じものなのでたぶん大丈夫です。
　これでプロジェクトの設定は終了です。
　プログラムは変わらないので自由にプログラミングをしてください。従来はプログラムのヘッダーファイルを読み込んでいるのところに赤線が引かれ、関数名が赤文字になっているのですが、管理人さんが対応したことによって、必要がなくなりました。
次にエミュレータの用意です。

1. c:\\users\ユーザー名\\.androidをエクスプローラで開く。
1. advancedFeatures.iniというファイルを作成して、

```
Vulkan = off
GLDirectMen = on
```
という2行を入力して保存。（これが無いとエミュレータが起動できません。なお、意味は分かっていません。）
3. 公式サイトの通りにエミュレータを作成する。一応管理人さんはAPI30で動いたらしいですが、僕はAPI29のエミュレータを使いました。
　これで後は公式サイトに書いてあるようにエミュレータ上でアプリを動かすことができます。
# おまけ
　最後に実機で動かしたい向けにって思ったのですが、ここから先はちょっと説明が難しいので自分で調べてください。スマホ側で設定が必要なのですが、google公式の方法ですが隠しコマンドっぽい操作になるので頑張ってください。僕は既にその操作をやっていたのでスムーズに実機デバッグできました。API29でビルドしたのでandroid11のスマホで動くか心配でしたが、無事に実機で動かすことができました。
# まとめ
　この記事に書いてある情報が役立つ人…がいるかわかりませんが、誰かしら役に立ってくれると嬉しいです。
　次の記事はいろいろ考えていますが、アドベントカレンダーに記事投稿しているのは今のところ僕だけなのが気になって果たして記事を追加していいものか。もしよさそうだったらせっかくandroid版の開発環境が整ったのでdxlibとopencvを同時利用した何かを作ってみたいと思います。で、さらに次の記事では（できたら）ARアプリを作ってみたいと思います。
Logistic回帰でアヤメデータを分類



■Logistic回帰でアヤメデータの分類やっていきます。

######1.モジュールインポート
```
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler

```

#####2.データセット読み込み
今回はversicolorとvirginicaを使用
データの確認

```
df = sns.load_dataset('iris')
df = df[(df['species']=='versicolor') |(df['species']=='virginica')]
```
![df.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175940/66f2c43b-7db3-ffd1-783e-3d5cce9f8c4d.png)



#####3.データを可視化してみる
```
sns.pairplot(df, hue='species')
plt.show()
```
![相関.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175940/1ed73cf6-d56b-b44a-eea9-7fa6e5299aa3.png)


#####4.標準化 & モデル作成 & 未知データへの予測

$wに回帰係数、bに切片$
$z = w_1x_1 + w_2x_2 + w_3x_3 + w_4x_4 + b$  

下記シグモイド関数により予測される。
$sigmoid(z)=\frac{1}{1 + exp(-z)}$

下記コスト関数が最小になるように回帰係数を求める。
$Loss =\frac{1}{n} \sum_{k=1}^{a}y(log(sigmoid(z)+(1-y)log(1-sigmoid(z))$

特徴量を標準化することで平均０、分散１にスケールを整える→値の大きい特徴量に引っ張られて値の小さな特徴量の寄与率低下を防ぐ。

```
#versicolorを0, virginicaを1に変更
df['species'] = df['species'].apply(lambda x: 0 if x == 'versicolor' else 1)
y = df['species']

#特徴量を標準化
X = df[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]
std = StandardScaler()
df_std = std.fit_transform(X)

#データスプリット
X_train, X_test, y_train, y_test = train_test_split(df_std, y, test_size=0.2, random_state=0)

#インスタンス化
lr = LogisticRegression()

#学習
lr.fit(X_train, y_train)

print('切片：',lr.intercept_)
print('係数：',lr.coef_)
切片： [0.31092366]
回帰係数： [[-0.22945621 -0.64463112  2.25437115  2.10390759]]
```




```
#１に近づくほど0(versicolor)である確率が高い
y_proba = lr.predict_proba(X_test)[: , 0]
y_proba

array([0.80232846, 0.0083395 , 0.77687909, 0.00173345, 0.04900388,
       0.0048721 , 0.84531764, 0.22558666, 0.00642644, 0.02140575,
       0.05924045, 0.07914323, 0.01190993, 0.83569148, 0.99769158,
       0.98796255, 0.46769446, 0.96532535, 0.29089213, 0.92908486])
```



######5. 結果評価

```
#testデータに対して予測してみる
y_test_pred = lr.predict(X_test)

#正解率を確認
accuracy_score(y_test, y_test_pred)
0.9

np.array(y_test)
array([0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])

y_test_pred
array([0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0])

```

Accuracyだけでなく混同行列で真陽性、偽陽性、真陰性、真陽性の確認を行う。
混同行列を作成
陰を０、陽を１と考える

![confusion_matrix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175940/863f5c7f-f8ce-2228-74c3-509f00844b67.png)


```
classes = [0, 1]
cm = confusion_matrix(y_test, y_test_pred, labels=classes)

# データフレーム化
cmdf = pd.DataFrame(cm, index=classes, columns=classes)

# 混同行列をプロット
sns.heatmap(cmdf, annot=True)

```
![Confusion.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175940/9aec0bb5-3adb-1865-a4ce-928896ee3b39.png)

```
# 適合率、再現率、F値を出力
print(classification_report(y_test, y_test_pred))
```
![F値など.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175940/bbbb60b7-fe4f-eddf-9371-06d3a8888db0.png)



以上より、あやめデータ(versicolor,versinica)の２値分類を行うことができました。
IBN5100でしか動かないシステム

# なにがあった

IBN5100。。。ではないが、同じくらいレガシーな環境でしか動かないサービスが最近まで普通に本番で使われてた話。

官公庁や老舗企業ではあるあるだと思いますが、**今動いているその環境でしか動かないシステム**というものが世の中には多数存在しています。特にWindows環境向けに開発されたシステム。
私は21世紀に**Windows3.1で動く名刺印刷システム**が現役で動いているのをみたことがあります。

最近まで現役で動いてたサービスで、

- WindowsServer2003
- .NetFramework3.5
- [BASP21 DLL](http://www.hi-ho.ne.jp/babaq/basp21.html)
- Vbscript(Classic ASP)

じゃないと動かないWebサービスがあり、当然サポートなんてとうの昔に切れているので、古いインストーラーを**秘伝の書**のごとく大切に保管して、新しいサーバにインストールして運用していました。

セキュリティ的な脆弱性ありありだったと思います。幸いハッキングはされませんでしたが（ハッカーも興味なかった？）。

正常に動作していたので、まあそれでも実害ないといえばないのですが、強いていうなら他社のエンジニアにシステムを説明するときに**「VBScriptってwwwwwwwwwwwwwwwww」**と大草原を生やされることくらいでしょうか。

# どうしてそうなった

シンプルに、直接利益の産まないシステムのリニューアル、バージョンアップとかをないがしろにし続けた結果です。

# どうすればよかった

少なくともサポートが切れる前には、バージョンアップとかリニューアルとかしましょう。

さもないと、脆弱なサーバやシステムを使い続けないといけなかったり、新しいサーバではインストールができなくなったり、技術が古すぎてエンジニアが採用できなかったり、**大草原生やされたり**、良いことはありません。
ここ1,2年のデータ整備の話



この記事はdatatech-jp Advent Calendar 2021(https://qiita.com/advent-calendar/2021/datatech-jp )の15日目の記事となります。

---
初めての方ははじめまして。showyouと申します。フリーランスから大企業に出戻りしまして、社内のデータ活用推進を行っています。

ここからこの1～2年間行ってた仕事の話を書きますが、嘘とかぼかしを適当に混ぜますので気楽に読んでください。

# 小さいところから改善を図ったデータ移行プロジェクト
前提としまして、中央にデータレイクやDWHの基盤は存在しますし、管理する部隊や実装する部隊などもいました。しかし依頼側が発注の仕方をわからず独自に構築していたため、コンウェイの法則の如くチーム毎に集計システムが出来ていました。「集計システム」と言ってもプログラミングで自動化されたものではなく、Excelを駆使した黒魔術等が点在していました。この方式だと実用に耐えきれなくなって来ましたので、私が間に入ってシステム化しました。

本当は体制とか考えた方がいいのかもしれませんが、システム化にあたり、まず手をつけられそうな部分で改善して効果を実感してもらうところからはじめました。すなわちExcelで黒魔術になっているところを、PythonやPandas.Dataframe、matplotlibを使った簡易なスクリプトに置き換えました。そうやって改善できると信頼されたところで、いよいよ元データの、中央のDWHへの移行を進めました。

DWHへの移行に関しては、装置の運用を別の部隊が行っていたので、技術的な面ではそれほど辛いこともありませんでした。一方大変辛かったというか、工数の9割ぐらいかかったのがデータの整合性チェックでした。というのも、そもそも移行前後で完全に同じ元データが使えなかったため、データの差分を見ながらおおよそあっている？それともおかしい？という事を繰り返していました。

またこのフェーズでは、集計環境をSQLiteからDWHに環境を移しました。しかし完全に同じ動作を再現できない処理もあり、そこも移行前後のデータ不一致の原因になっていました。ここでは、違いの発生したレコードに関して一件ずつ計算を追って、原因を解消していきました。一番しんどかったのはSQLiteのint型に小数のデータを入れた場合はDECIMAL?として扱われ小数の計算ができるのに、整数のデータを入れたときにintegerと扱われ、小数点以下切り捨てられていたことを知ったあたりでしょうか。

```SQL
-- INT_VALUEに0.8とか入れてると0.4になるのに、1を入れるとint/intとして扱われて0が返ってくる
INSERT TABLE hoge(data) AS SELECT
  INT_VALUE / 2 
FROM MOTO_TABLE;
```

また小数の計算時の桁丸めで非常に小さい値になるとき場合、誤差がとても大きくなった事も挙げられます。一例を挙げると：0.00000055 が 0.0000006と切り上げられて誤差10％以上になる場合です。
これらと似たような辛さの話はyuzutasoさんが丁寧に解説されております。https://atmarkit.itmedia.co.jp/ait/articles/1808/03/news009.html

おかげさまでデータも99％以上元データと一致、残りも違いの原因が説明できるところまで来まして、このチームでは中央のDWH基盤を使えそうというところまで来ました。同じ集計結果を使っている複数のチームにも本件が伝わり、中央のDWHへの利用申請が進んでおります。[^1]

# 10年経って変わったものと変わらないもの
ここまでほとんど技術の話をせずに書いてきました。この10年くらいビックデータの業務に携わって感じたこととして、DWH相当がHadoopからBigQuery/Snowflake等に変わりました。しかし集計に取り込むための要件定義とか集計結果のチェックなど大変なところは相変わらず残っている感じはします（単に自分がそういう場所ばかり放り込まれてるのかも）。データサイエンスの方はAutoMLが頑張ってきてるので、適当にデータ取って投げ込んでくれるものとかが出てきてくれると嬉しいですね。

自分は特に技術的にものすごく尖っているわけではないのですが、ある程度現場の悩みを聴いた上で手を動かすことは得意です。そのため要件を満たす最低限のものを高速に提供する、などのことを結構行っています。

今は上記の仕事の他に、電子系の設計や開発などを行っている方々が自分たちでプログラミングする習慣をつけられるよう、レクチャーを進めています。それらの方々全員が隅々までコーディングできる必要あるのか？という質問が来たりします。その時には、"DeNAやメルカリ等は企画の方たちでも全員SQL叩いて実行する文化が根づいているので[^2]、せめてデータマートからデータを取り出して好みの形に仕上げるぐらいまではなってほしい"と答えています。

---

余談ですが弊社でもまだまだデータエンジニアが足りていないので、興味のございます方は[Twitter:@showyou](https://twitter.com/showyou)までお声がけください。私はこういう地味？な仕事をしていますが、他のメンバーはAWS LambdaでServerless集計環境とかもっとイケてることもしてます。

[^1]: 一件不具合を大量に報告されるのは辛いと思うかもしれません。しかし出力した結果を直後に隅々までチェックしてくれる顧客はとてもありがたいです。辛いところだとデータを出した数ヶ月後に「あれ、間違ってるよ」と言ってきたり（架空の話です）
[^2]: "DeNAに入ってびっくりしたのが、エンジニア以外のプロデューサーやプランナーがHue（Hadoop用GUIツール）を使い、HiveQLを駆使してサービスなどの分析を行っていること。" https://codezine.jp/article/detail/7678?p=2
PiMaxのIPD問題かと思ったらフェイスプレートが広すぎた話

PiMax 8k Plusでゲームをしていると画像がぼやける。IPDの海外記事を読んでいくら合わせても合わない・・・これがPiMaxの難しいIPD問題かと思ったら・・・。

フェイスプレートが広すぎただけでしたｗ

・アジア人向けフェイスプレート
Valve Indexから乗り換えて一番感動したのはもちろんFOVの広さですが、2番目はフェイスプレートのアジア人向けサイズでした。Indexのそれは欧米人向けの超狭い形状で困ったものですが、PiMaxのものは実にぺったんこで馴染む。
![PXL_20211215_115738384.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/65e8b556-5d71-3a32-bb63-34e8aeb41c49.jpeg)


・落とし穴
しばらくは喜々として使っていたのですが、IPDがどうも合わない。まず右目を合わせて、左目を合わせて、右目に戻るとずれてるの繰り返し。
で、顔にフェイスプレートを左右目に密着させて気がつきました。顔が左右にずれる。
なんのことはない、私の顔よりPiMaxのフェイスプレートがより平面だったのです。そりゃゲームすれば左右にずれますよね"(-""-)"


・改良
Valve IndexのAMVR社のフェイスプレートに付いていた狭くするパット（欧米人はあれよりまだ狭くしないといけない人がいるのに驚く）を、左右に挟み込む。
![PXL_20211215_115821801.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/deb08849-4f0e-1e1d-ee5d-f7fd90a116eb.jpeg)
![PXL_20211215_115912412.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/9a7c464e-6ace-7c24-8c3a-e3f13a4418eb.jpeg)

ちょいキツメのフェイスプレートの出来上がり！！
これで後ろのダイアルを思いっきり締め上げなくてもヘッドセットが左右にずれません。
![PXL_20211215_120059293.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/93a7b688-4dca-bda2-2791-91b9cff74c9c.jpeg)

・結果
長時間使うと若干の眼精疲労があるので、IPD問題はまだありそうですがずれないだけで超改善しました。
右目だけで見て、ヘッドセットを揺すってみて、ピントがずれるようなら、あなたの頭はPiMaxのフェイスプレートより小さいです。何らかの詰め物で狭くすると改善するかもです。
Obsidianの小技その2｜2ペイン・編集＆プレビューでつかうと右脳と左脳が気持ちよい

### はじめに

パソコンでつねに開きっぱなにしているアプリ、[Obsidian](https://obsidian.md)。使い続けて1年をこえたので、べんりにつかうための小技を紹介するシリーズです。

### 2ペイン・編集＆プレビューでつかう

ディスプレイのサイズや、Obsidianをつかう目的にもよるとおもいますが、わたしの場合は2ペインで安定しました。左側は編集モード、右側はプレビューモードです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/3b7d4d67-dfc4-cc86-c620-bee05fc70483.png" width=60%>

左側サイドバーはだいたいは開いていて、ファイルエクスプローラか検索が表示されています。右側サイドバーは閉じていて、よほどのことがないと開きません。

なお、右上のアイコンをCtrl（macOSの場合はcommand）キーを押しながらクリックすると、プレビューペインが開きます。こうすると、編集ペインとプレビューペインは連動します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/0fd4b351-93ea-11d6-010e-3d6d8b0447b0.png" width=40%>

### どうして2ペイン・編集＆プレビューがいいのか

「気持ちいいから」そうしているんですけれども、どうして気持ちいいのか自問自答してみると「右脳と左脳をつかいわけられるから」じゃないかとおもうんですよね。

左側の編集ペインはロジック担当、右側のプレビューペインはビジュアル担当、と役割がわかれています。

たとえば、文中に画像を埋め込むとき、思考している脳は、2つのことを把握したいのです。ひとつは、その画像はどこから引っ張ってきているのか。もうひとつは、その画像はどのように表示されるのか。左右ペインにわけて表示してあると、「思考している脳がいま現在まさに把握したいほう」を瞬時に目にできます。

他のメモやサイトへのリンクの場合も、2要素あります。リンク先はどこかと、リンク先の内容はなにか。Obsidian内部へのリンクの場合、プレビューペインでマウスカーソルを置くと、リンク先のプレビューが出るので、リンク先のコンテンツを「実際に目にする」ことができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/fd1f41ef-6256-14bf-3b60-a7491ac7b326.png" width=45%>

あるいは内部リンクを`![[xxxxxx]]`形式で書くと、リンク先の内容を常に表示しておけます。

こういったことがどうして「気持ちいい」のかというと、なにか操作しなくても、右脳のリクエストと左脳のリクエストに、すいすい応えられるからではないか。脳に負担がなければ、心も身体も安らかになるし、それが気持ちいのではないでしょうか。

### おわりに

エンジニア目線ではMarkdownというのは簡易版HTMLです。せっかくHTML（=Markdown =ロジック）とCSS（=デザイン）を分離しているのだから、ロジックとビジュアルを分けて表示しておけると安心感があります。それはなぜか考えてみたところ、ああ右脳と左脳がそれぞれ快適なんだとおもいました。

Obsidianでも、グラフビューを入れてみたり、いろいろなペイン構成を試しましたが、けっきょく（わたしは）編集とプレビューの2ペインに戻ってくる。その理由に接近できた気がしました。

と書いていたら、Obsidianのv.0.13.0からはライブプレビューモードが搭載され、0.13.8からはライブプレビューがデフォルトになりました。2ペインで編集＆プレビューというのは、もしかすると今風ではないのかもしれません😢　とまれ、「気持ちいい」設定を探すご参考になればさいわいです。

### ご参考

[Obsidian｜使いかたとコツ（目次）](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)
jit結構いいかも

## jitに変更して実装している
結構やりやすい。僕はお薦めします。
configに追加しないといけなかったのでそれがなくてもできるのですごく直感的にスタイルを当てられれるので大変便利です。

`tailwind.config.js`で`mode`指定をする

```js
module.exports = {
  mode: 'jit',
  purge: [
    './pages/**/*.{ts,tsx}',
    './components/**/*.{ts,tsx}',
    './lib/**/*.{ts,tsx}',
  ],
  darkMode: false,
  theme: {},
  variants: {
    extend: {},
  },
  plugins: [],
}
```

こんな感じにスタイルクラスを当てていきます。

```html
<div class="w-[56px]"></div>
```

## まとめ
大体はこんな感じで使っていけます。
MacBook Pro 2021を買って初めに行ったこと

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">新しいMacBook Pro届いてた <a href="https://t.co/mm4qyKzdLl">pic.twitter.com/mm4qyKzdLl</a></p>&mdash; Takahashi Tomohiko 高橋智彦 (@kter) <a href="https://twitter.com/kter/status/1470762853892501511?ref_src=twsrc%5Etfw">December 14, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

あまり凝ったことはせず基本デフォルトのままで使おうと思っていますが、最小限の設定を行ったのでメモ

### インストール系

* Docker for Mac
* Chrome
* Kindle
* iTerm2
* Authy
* VSCode
* Zoom
* Authy

### 設定系

* ディスプレイで解像度をスペースを拡大に変更
* キーボードの装飾キーでcaps lockをControlに割り当て変更
* トラックパッドのタップでクリックを有効化
* [３本指のスクロールを有効化](https://support.apple.com/ja-jp/HT204609)
* キーのリピートを最速に、リピート入力認識までの時間を最短に変更

### ファイル系

旧Macでリモートログインを有効にしてrsyncでコピー（SMBによるファイル共有は遅くて諦めた
Enum.reduceのデバッグにEnum.scanが便利

この記事は「fukuoka.ex Elixir／Phoenix Advent Calendar 2021」の16日目です。
昨日は@MzRyuKaさんの「elixir-desktopを起動しようとして環境構築でハマっている話」でした。

https://qiita.com/MzRyuKa/items/2a7f00fa56120f3ea54c

## 導入
さて、本日は「`Enum.reduce`のデバッグに`Enum.scan`が便利」というテーマです。
`Enum`には`map`や`filter`、`reduce`といった、使用率の高い非常に便利な関数がありますが、`reduce`は`map`や`filter`とは少し異なります。`map`は受け取ったリストと同じサイズのリストを返し、`filter`は受け取ったリストのサイズ以下のリストを返します。

```elixir
# Enum.map
lst = [1,2,3,4,5]
Enum.map(lst, fn n -> n * 2 end)
# [2,4,6,8,10]

# Enum.filter
Enum.filter(lst, fn n -> n > 3 end)
# [4,5]
```

両者に共通していることは必ずリストを返すという点です。しかし、`reduce`に関しては必ずしもリストを返さない関数です。

- リストの要素の合計値を求める
- リストの重複する要素を取り除く
- 出現する要素を集計する...

などなど、「リストから何かをする」というケースに非常に便利に用いることが出来ます。

```elixir
lst = [1,2,3,4,5]
Enum.reduce(lst, 0, fn n, accum -> accum + n end)
# 15
```

## reduceの難しい点🤔
便利な`reduce`関数ですが、データの動き方には少し慣れが必要です。
基本的にはアキュムレーターと呼ばれる値の更新処理が重要となります。

リストから要素の合計を求めるという処理の場合は、初期値を`0`の数値をアキュムレーターとして、数値同士の加算処理を行う必要があります。

```elixir
fn n, accum -> accum + n end
```

次のアキュムレーターがどのような値になっているかを把握するのが`reduce`の難点です。
普通にデバッグをすると以下のようになります(実際に過去に自分はこの方法でやっていました)。

```elixir
lst = [1,2,3,4,5]
Enum.reduce(lst, 0, fn n, accum ->
  next = accum + n
  IO.inspect(next)
  next
end)

# ※見やすさのために改行しています
# 1 3 6 10 15
```

第2引数の無名関数内部で、標準出力を行えばいいのですが、これでは非常に面倒です...

## Enum.scanを使う🧪
https://hexdocs.pm/elixir/1.12/Enum.html#scan

`Enum`で提供されている`scan`がreduceのデバッグに非常に便利です。
まずは`Enum.scan`の実行結果を見てみます。

```elixir
lst = [1,2,3,4,5]
Enum.scan(lst, 0, fn n, accum -> accum + n end)
# [1,3,6,10,15]
```

どうでしょうか。先ほどのアキュムレーターの値の更新結果を確認することが出来ました。
リストの最大値を取得する処理でも見てみます。

```elixir
lst = [3,1,4,5,2]
Enum.scan(lst, 0, fn n, acc ->
  if n > acc do
    n
  else
    acc
  end
end)
# [3,3,4,5,5]
```

最大値がどのように推移しているのかが確認できました。`reduce`の動作確認には非常に便利ですね。
ぜひご活用ください。

注意点としては、`Enum.scan`は`Enum.reduce`と異なり、最終的にはリストを返します。なので、デバッグが完了したら、必ず`reduce`に戻しておく必要があります。

## 最後に
明日は「fukuoka.ex Elixir／Phoenix Advent Calendar 2021」の17日目は@pojiroさんです。
お楽しみに🙌
WSLにCode_Asterのインストール

#1 はじめに
WSLにCode_Aster14.6がインストールできたので共有したいと思います。
並列版は別に記事を作成します。先人たちに感謝。

* [Code_Aster14.4の並列化] (https://qiita.com/hiro_kuramoto/items/269ecf6293cfbe38b314)

#2 環境
OS : Windows 10
WSL : Ubuntu 18.04 LTS

インストール済みのパッケージの問題でエラーが発生することがあるので新規ディストリビューションを作ってインストールするのも一考です。

* [WSLで使い捨てのUbuntuをポコポコ作る](https://qiita.com/akiraak/items/12646cc0d1746c1bedd5)

#3 準備
Windowsの環境変数を読み込むとエラーが出ることもあるようなので読み込まないように設定します。

```bash
echo -e "[interop] \nappendWindowsPath = false" |sudo tee /etc/wsl.conf
```
上記を反映するためにwslを再起動します。

次にインストール先 ( /opt )の所有権の変更と必要なパッケージのインストールを行います。

```bash
sudo chown username /opt    #usernameにユーザ名を入れる
sudo apt update
sudo apt install gcc g++ gfortran cmake python3 python3-dev python3-numpy tk bison flex liblapack-dev libblas-dev libboost-all-dev zlib1g-dev
```

下記バージョンのソースをサイトからダウンロードします。

| パッケージ | バージョン                            | ダウンロード先                                                   |
|:----------|:-------------------------------------|:----------------------------------------------------------------|
| Code_Aster| aster-full-src-14.6.0-1.noarch.tar.gz| https://www.code-aster.org                                      |

##4 Code_Aster
解凍してインストールします。

```bash
tar xf aster-full-src-14.6.0-1.noarch.tar.gz
cd aster-full-src-14.6.0
python3 setup.py install
```
サマリーの最後は以下のようでした。

```bash
--------------------------------------------------------------------------------
     SUMMARY OF INSTALLATION
--------------------------------------------------------------------------------
...

Installation of   : aster 14.6.0
Destination       : /opt/aster
Elapsed time      : 609.26 s
                                                                      [  OK  ]
Installation of   : Code_Aster + 9 of its prerequisites
Destination       : /opt/aster
Elapsed time      : 1907.03 s
                                                                      [  OK  ]
```
動作確認をします。

```bash
/opt/aster/bin/as_run --vers=14.6 --test forma01a
```
アラームが出ていますが無事計算ができているようです。

```bash
...
as_run 2020.0

------------------------------------------------------------
--- DIAGNOSTIC JOB : <A>_ALARM
------------------------------------------------------------
```
ありがとうございました。