OmniAICreator/Qiita-1.07M huggingface dataset:
【Unity】ML-AgentsとFinal IKでアバターを学習させて動かす(ように見せる)

[KuMA Advent Calendr 2022](https://adventar.org/calendars/8188)　1日目の記事です．

みなさんアバターに<b>強化学習</b|>，させたいですよね！？

この世界には [Unity ML-Agents](https://unity.com/ja/products/machine-learning-agents) という，Unityで機械学習を行うことができる神パッケージが存在しています（しかも無料！）．これを使ってアバターを動かしてみたので紹介します．

## Unity ML-Agentsのサンプル環境

ML-Agentsは[release_18](https://github.com/Unity-Technologies/ml-agents/blob/release_18/docs/Installation.md)，Unityは2019.4.22f1を用いました．
ML-Agentsの環境構築などに関する説明はこの記事では割愛します．[公式のドキュメント](https://github.com/Unity-Technologies/ml-agents)が結構丁寧に書かれているので，そちらを参考にやってもらえればと思います．

今回はML-Agentsのサンプル環境の一つである「3DBall」を参考に学習させてみました．「3DBall」は，水色のキューブ型のエージェントがボールを落とさないように回転運動を学習するサンプルです．
![agentMovie1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/688f6c78-48f5-118e-0f7c-20a6cd420db0.gif)

このエージェントの厚みを薄く（高さを小さく）して，アバターが板を持ってボールを落とさないように動かすような場面を考えます．雑なイメージ↓
![IMG_6397.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/f3e3cfee-7786-97bb-ead3-c12a4a146da8.png)
アバターが板を把持する部分には後述のFinal IKを用います．

## Final IKについて
まずIKというのはInverse Kinematics（逆運動学）の略で，目標点に向けて腕の関節を動かす，みたいなやつです．あまり詳しくないですが，もともとはロボット工学でロボットアームを動かす方法とかからはじまったのかな（知らんのに語りたがるオタク登場）．
CGのアバターを動かすときなどにも使います．例えばVRSNSでHMDを被ってバーチャル美少女になるとき，自分のコントローラの位置にアバターの手が追従（同期）しますよね．そのときにもIKが使われていることが多いです．コントローラ位置を目標点として，アバターの手や腕（のボーン）をいい感じに動かすような計算が行われています．VTuberが3Dの身体を動かすときにも多く使われているはずです．

[Final IK](https://assetstore.unity.com/packages/tools/animation/final-ik-14290?locale=ja-JP)は，UnityでIKを簡単に動かすことができるアセットです．神アセットで1万円くらいするんですが，不定期的に半額とかになっているので安いときに買うのがおすすめです．僕は情弱だったので90ドルで買った記憶があります．
（今（2022/12/1/0:45JTS）見たらサイバーウィークセールで50%オフの45ドルになっていました．）

今回は板の端に目標点となるCubeを配置して，ここにアバターの手を追従させるようにしてみます．アバターは[VRoid Studio](https://vroid.com/studio)で作成したVRMモデルを用いています．
![ik_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/69fec04b-8db8-b3d5-56d7-20438b487c75.jpeg)

FinalIKの設定は以下の通りです．
![hands.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/c827964d-b103-2b3d-9c6c-2f7951e4068c.png)



## 学習させてみる
与える報酬やエージェントの動作，ハイパーパラメータなどはサンプルそのままで学習させてみます．ボールが板の上にあるとき報酬+0.1，ボールが板から落下したとき報酬-1を与えます．

5000万ステップ学習後のモデルを適用すると，下のようになりました！
<img src="https://drive.google.com/uc?id=1bxvWX7M2LNZAO5Ywe-PRmloQwqQHiNQW
">
上手にできましたね．


## ちょっといじってみる
サンプルはx軸，y軸両軸の回転だったので，この軸を減らしてみます．
報酬やハイパーパラメータはサンプルのままです．

以下のようになりました．
<img src="https://drive.google.com/uc?id=1TTOF5fOEj0xcfrzBBiwyT9_PsygBtUWP">
<img src="https://drive.google.com/uc?id=1DOr-bta8nK6pjS5v1azfSiU53Kve3JFu">
かわいいね．
___

今回紹介した方法は直接アバターを学習させているわけではなく，あくまで板がエージェントであり，勝手に動く板にアバターの手を追従させてそれっぽく見せるという方法ですが，わりといい感じにアバターが動いているように見えるのではないでしょうか．

今後はドラえもんのようなAIを作っていきたいです．


## 追伸

ポケモンSVのやりすぎでアドカレ初日から遅れてしまいました．申し訳ございませんでした．説明も雑になってしまったので，時間があるときにまた追記しようと思います．質問などあればお気軽にコメントください．ここまで読んでいただきありがとうございました．
プロジェクトマネジメントについて述べる1

初投稿です。
これまでWebエンジニア→営業→マネージャー→役員といったジョブチェンジをして来ましたが、昨今プロジェクトマネジメントの重要性と課題を再認識しており、仲間を増やすためにも情報発信をしてみます。
いつまで続くかわかりませんが、よろしくお願いします。

# はじめに
私の経験上、対象とするプロジェクト規模は小規模-中規模を想定した内容になります。
案件の都合上、詳細をぼやかした表現などもあるかと思いますがご理解ください。

# プロジェクトマネジメントの重要性
わざわざ説明するまでもないですが、プロジェクトマネジメントは重要です。
せっかくなのでどういった点が重要だと考えているのかを列挙してみます。
- 進捗状況、予算の把握
- 社内、協力会社、顧客との調整が必要かの判断
- 売上や資金繰りへの影響
- 次の営業活動やリソース配分のタイミング

もちろんこれだけでは無いですが、直ぐに思い当たるものを上げてみました。
いずれも会社経営に直結する部分を重視していることがわかります。（現在の立場上当然なのですが）

# 課題感
プロジェクトを遂行するにあたり当然これまでもプロジェクトマネジメントは行っているのですが、最近課題だと感じているのは**プロジェクトマネジメントルールの構築**です。
これまで様々なプロジェクトに参画してきましたが、明確なルールが存在せずに各PMの経験で対応する事が多いと感じており、そうなると人によって粒度も精度も異なります。

例えば

Aプロジェクトでは進捗状況を確認するとタスク単位でチケット管理されており週次でイテレーションを回して状況を把握出来るパターン

もあれば、

Bプロジェクトではスプレッドシートで機能単位でガントチャートが引かれており開発しながら見通しを立てているパターン

もあるというイメージです。

マネジメントのやり方、粒度、考え方、といった前提が異なる事で、進捗状況を確認するにしてもそもそもの前提を確認しないと順調なのかそうでないのか判断出来ない、といった事になってしまいます。

この様な状況があり、プロジェクトマネジメントルールを構築しないとそもそもプロジェクトが管理出来ないと感じ、この課題に取り組むことにしました。
プロジェクトマネジメントマネジメントです。（ダサい）

# 当たり前とは
少し話がそれますが、プロジェクトマネジメントを担当する人によっては当たり前な事を管理しない人がいる事に気づきました。
なぜだろうと考えた末にこれこそ当たり前なのですが**人によって当たり前が異なる**という事でした。
技術開発でもそうだと思いますが、この**当たり前**はあると思っています。例えばこの記事を見ている皆さんはソースコードをGitで管理するのは当たり前だと思っているのではないかと思います。
そういったレベルの当たり前をどうすれば暗黙知ではなく形式知にできるのか、そんな取り組みにも繋げていきたいです。

# これから
まずは自身の自己紹介も兼ねてプロジェクトマネジメントに対する考えを共有しました。
今後少しずつ、プロジェクトマネジメントがどうあるべきなのか、実際に体験した事やその時の対応なども交えながら発信していきたいと思います。
生波形を忠実に再現するHiFi-GAN

## HiFiGANとは
入力となる「メルスペクトルグラム」という音声の中間表現から、直接音が消ける生波形を生成します。
HiFi-GANは入力を忠実に再現するニューラルネットワークのパラメータを推定します。

## 先行研究と比べてすごいところ
GANを使った高い再現精度と精度の評価を他の人が聞いても高いスコアを付けるというところです。
GANを使った音声の再現はあまり、成功していませんでしたが、HiFi-GANでは精度が高くなっております。


## アーキテクチャー
### ジェネレータ
ジェネレータでメルスペクトルグラムから生波形を生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33329/ac0bcf83-0559-eb22-e660-0678a869467e.png)

### ディスクリミネーター
２種類のディスクリミネーターで生波形を評価し敵対的学習を行います。MSDでさまざまなサイズの平滑化された音声を受け取り、MPDは不連続な波形を受け取ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33329/f6d487f6-995c-f9e6-5c5f-672b590b75ef.png)

## 試してみる
こちらのコードを実行しました。詳しいアーキテクチャもこちらを参考にしてください。
https://github.com/jik876/hifi-gan

LJSPeechのデータを使って学習します。学習は思ったより時間がかかりませんでした。もちろんepochがデフォルトの3000とかだと、10時間以上はかかってくると思います。今回の実験では30epochぐらい回しましたがノイズはあるもののイントネーションはしっかりと再現できていました。

## まとめ
今回はメルスペクトルグラムから生波形を作るHiFi-GANをご紹介しました。
これにテキストからメルスペクトルグラムを生成するのを組み合わればテキストから生波形を生成させられます。
興味があるかたは試してみてください。
ChatGPTとは


https://www.itmedia.co.jp/news/articles/2212/01/news188.html


https://gigazine.net/news/20221201-chatgpt/

https://matomedane.jp/page/119567


https://article.auone.jp/detail/1/3/7/48_7_r_20221201_1669870392975335


https://texal.jp/2022/12/01/openai-releases-gpt-3-5-and-chatgpt-an-interactive-ai-model-for-admitting-mistakes/


https://openai.com/blog/chatgpt/

https://qiita.com/tak001/items/c3000b3ce9b6e72b2ae5

https://qiita.com/akiraak/items/b8ad643eafe1a32341ff
フロントエンド入門 どうする？


# 経緯
フルスタックエンジニアですが、ベースはバックエンドとインフラが主戦場での自分なので、フロントエンドもやれないとフルスタックとは名乗れないので、フロントエンドも勉強してみることにしました。

# フロントエンドとは？

主にJavaScriptsでブラウザで動作するプログラミンやそれに付随する技術のこと。

かなり昔だったら、JQueryとCSSができればフロントエンドでバックエンドの片手間でやるか、HTMLコーダーやデザイナーでコードがわかる人がやるような感じでした。

しかし、今はJavaScriptsのフレームワークを使ったフロントエンドが主流になり、大きく３つの派閥に別れてるでしょう

* React.js  （三国志でいうところの魏）
* Vue.js （三国志でいうところの蜀）
* Angular.js (三国志でいうところの呉)


これからのことを考えるとReact.jsがしばらくメインになっていく気がするので、React.jsを学ぶ

## 前提
他の言語を４、５年程度、経験、学習している。


## 学習方法
* 本
* eラーニング(有料/無料)

大きく分けるとこの２つになるだろう。

個人的に本を見ながらコーディングするのがちょっと面倒なので、（もちろん見返したりするのは本のほうが楽）動画で学ぶことにした。

今、はじめているのが、[udemy](https://www.udemy.com/)の講座です。

いろんな方がおすすめしている講座

* [Nextjs + Tailwind CSS + Django REST Framework で学ぶモダンReact開発](https://www.udemy.com/course/nextjs-tailwind-css-django-rest-framework-react/)

* [【世界で7万人が受講】Understanding TypeScript 日本語版](https://www.udemy.com/course/understanding-typescript-jp/)


この２つから学ぶことにしました。

主流なReact.jsと、今後、静的型付けがほぼ必須になるので、TypeScriptを学習することで基本を抑えるのが大事かと思います。

また、学習の成果については記事を書きたいと思います。
Goの命名に頭を悩ませよう

## 命名の大切さ

どうも[ナレッジワーク](https://tenn.in/kw)の[tenntenn](https://tenn.in)です。

名前は大切です。それは人の名前だったり、商品名だったり、そしてプログラミングにおける識別子だったり、どれも大切です。名は体を表す。設計と命名は表裏一体であり、良い命名は良い設計に繋がります。

ここでは主にGoの命名について考えていきます。

Goはよく名前を短くするの習慣であると勘違いされます。[Goに入ってはGoに従え](https://ukai-go-talks.appspot.com/2014/gocon.slide#24)においても『与えられたコンテキストの中でわかりやすい名前にする』とされています。

命名については[Goの命名規則](https://micnncim.com/posts/ja/go-naming-convention)という記事をみるとよくまとまっています。この記事で参照されている公式ブログの記事はかなり前の記事です。つまり、Goはリリース当初から名前が短ければ短いほどよいとしているわけではありません。

## 文脈を構築する

名前（識別子）は、プログラミング言語に登場するオブジェクトを識別するために用いられます。ここでは、変数、関数、定数、パッケージなどの命名できるものを指しています。

人の名前をフルネームで呼ぶことはあまりないでしょう。上田さんという名前で呼んでも、その呼んだ文脈によって同僚の上田さんか、ご近所の上田さんか区別が付きます。

プログラミングにおいても名前を呼ぶ場合は、その文脈とともに考える必要があります。`net/http`パッケージの`*Client`型のメソッドが`Do`であれば、それはHTTPリクエストを送ることは想像しやすいでしょう。引数の型が`*http.Request`型であればなおさらです。`SendHTTPRequest`や`SendRequest`しても情報量は増えないでしょう。

名前が長くなってしまうと感じる場合は、うまく文脈が構築できていない可能性があります。文脈がないと、名前が説明的にならざる得ないでしょう。北海道苫小牧市に住んでいる、宮崎県出身の上田拓也さんのように呼ばないといけません。1度なら我慢できますが、何度もそんなに長い名前で呼ぶのは疲れます。名前が長いとソースコードも長くなり、重要な情報が隠れてしまい、可読性が下がります。

文脈は、パッケージ、関数、型、メソッドなどで構築できます。Goは他パッケージの機能を使うには、必ずパッケージ名を伴う必要があるため、パッケージ名も含めて命名を考えると良いでしょう。

## テストで確認する

命名は誰のために行うべきでしょうか？定義をするパッケージのためではなく、利用するパッケージにおいての可読性を考えるべきでしょう。

自パッケージ内で可読性が高いように思えても、実際に利用し、命名が重要になるのは他パッケージにおいてです。テストコードのパッケージを`mypkg_test`のように、テスト対象のパッケージと別のパッケージにすることで、命名がうまく言ってるか確認できます。

命名がうまくいってない場合は、テストコードでも分かりづらいし、名前が長くなります。名前が長いとテーブル駆動テストのテストケースが縦に長くなり、改行を含む表計算ソフトのセルのように可読性が下がります。改行することで可読性をあげようとするのではなく、命名を工夫したり、リファクタリングすることで解決すると良いでしょう。

## スケールを意識する

プログラミングは命名の繰り返しです。冗長な名前をつけていると、徐々に可読性が下がってきます。ソースコードの大半が長い識別子によって専有されるようになります。長い名前をいくら読んでも、情報量は増えません。

命名はスケールを考えておくと良いでしょう。たとえば、メソッドは増える可能性があり、引数の型をメソッド名に含めていると、引数のバリエーションが増えると名前はどんどん長くなり可読性は下がります。

フィールドやメソッドは増えていくことを忘れてはいけません。命名だけに限りませんが、何が増えるのかを予め予測し、備えておくと良い設計につながるでしょう。

ただし、1回の命名で素晴らしい名前がつけれ、それが未来永劫、素晴らしい名前とは限りません。文脈は変化していくので、リファクタリングを伴いながら良い名前を探っていく必要があるでしょう。

## 指針を得る

[Google Style Guides](https://google.github.io/styleguide/)に[Go Style](https://google.github.io/styleguide/go/)があります。

このガイドラインは、[Style Guide](https://google.github.io/styleguide/go/guide)、[Style Decisions](https://google.github.io/styleguide/go/decisions)、[Best Practices](https://google.github.io/styleguide/go/best-practices)から構成されています。

Style Guideは、Goのスタイルガイドの基礎となる指針のようなものが書かれています。Style Decisionsには、より具体的な例が、そしてBest Practicesにはマストではないが、準拠すると良さそうなベストプラクティスが書かれています。

命名についても書かれているので、一度読んでみると良いでしょう。

## 宣伝

[Gopher塾](http://gopher.school/)の[#2 Goらしいコードの書き方](http://gopher.school/2)では、命名などのGoらしいコードの書き方について扱う予定です。学生は無料ですので、ぜひご参加ください。
Testing Library のtestidが便利

## Testing Libraryとは

[Testing Library](
https://testing-library.com/)は、ユーザーの視点からWebアプリケーションをテストすることを重視している、UIコンポーネントをテストするためのライブラリです。UI上に表示される文字列や操作方法を簡単にテストすることができるようになっています。また、どのようなJavaScriptフレームワーク（ReactやVueなど）が使用されているかにかかわらず、統一されたAPIが提供されていて、フレームワーク間の移行や異なるフレームワークを混在させることができるようになっています。

## data-*属性

`data-*属性`は、HTML5で導入された属性で、ユーザー定義のデータをHTML要素に追加するために使用されます。
この属性は、HTML要素の任意の属性に付与することができます。
`data-*属性`の名前は、`data-`から始まり、その後に任意の文字列を付けることができます。
例えば、`data-custom-attribute`という名前の属性を付けることができます。

例：
``` html
<div data-custom-attribute="value">Content</div>
```

テストコードを書くときには、idやclassなどのセレクタを利用して、テストに利用するHTML要素を識別する必要があります。

テストに利用する要素を識別する方法として、ベストプラクティスといわれている方法は、要素に`data-*属性`を付与して、
`data-*属性`を利用して、識別する方法です。

どうしてこれがベストプラクティスと呼ばれているかの背景については、下記の記事に詳しく説明されているので、そちらをご覧ください。
https://blog.autify.com/ja/why-id-should-not-be-used


## data-testid

Testing Libraryでは、`data-testid属性`を割り当てたHTML要素の参照を取得するAPIがあります。

ByTestIdを使用しない場合は、次のような形で取得しなければならず、直感的でないため覚えるのが大変でした。

例：
```javascript
const element = baseElement.querySelector('[data-testid="custom-element"]');
```
[ByTestId](https://testing-library.com/docs/queries/bytestid/
)を使うと、HTML要素の参照を簡単に取得することができます。

例：
```html
<div data-testid="custom-element" />
```
```javascript
import {screen} from '@testing-library/dom'
cost element = screen.getByTestId('custom-element')
```
button要素などでも同様に取得することができ、

例：
``` javascript
fireEvent.click(buttonElment)
```

で、buttonのクリックをすることができます。




## まとめ

要素の参照の取得方法のベストプラクティスである`data-*属性`を使うときは、
Testing LibraryのByTestIdを使うと快適にテストコードを書くことができます。

他にも便利なAPIがたくさんあるので、ぜひTesting Libraryを試してみてください。
「状態ホイスティング」の説明

## はじめに

本記事は [Android Advent Calendar 2022](https://qiita.com/advent-calendar/2022/android) の1日目の記事です。
1日目から空いていたので、急きょ埋めました。

状態ホイスティングについて説明します。

## 「状態ホイスティング」とは？

英語で「state hoisting」といいます。

状態をコンポーザブル（ビュー）の呼び出し元に移動して、コンポーザブル自体をステートレスにするプログラミングパターンのことです。

「表示する現在の値」と「値を変更するイベント（ `(T) -> Unit` ）」をコンポーザブルへ渡し、値を「コピー」するのでなく「移動」することで、信頼できる唯一の情報源を実現できます。

## 状態ホイスティングのメリット

TBD

## おわりに

急きょ書いたので、公式ドキュメントより中身が薄いです、、
後ほど編集したいと思うのでお許しください。

最初に状態ホイスティングを知ったときは感動しました。
私はiOSアプリ開発がメインなので、SwiftUIでも適用できないか試したのですが、なかなか難しかったです。
Jetpack Composeは関数でUIを構築し、状態を保持できないのに対し、SwiftUIは構造体でUIを構築し、状態を保持させる構造になっているのが難点でした。

以上 [Android Advent Calendar 2022](https://qiita.com/advent-calendar/2022/android) の1日目の記事でした。
明日は @waterada さんで「Android UnitTestでR.stringのテストを劇的に見やすくする」です。

## 参考リンク

- https://twitter.com/the_uhooi/status/1586176902674649089
- https://developer.android.com/jetpack/compose/state?hl=ja#state-hoisting
C++の共用体やタイプパニングについて

# はじめに
同じメモリ領域に別の型を格納したい, 同じメモリ領域を初期化したときとは別の型で読み出したい, シリアライザの実装などで必要になることがあると思います. 
解決策として, 共用体を~~悪用~~活用したり, ポインタの指す型を読み替えたりする~~違法~~行為が行われてきました [(JPCERT EXP32-C)](https://www.jpcert.or.jp/sc-rules/c-exp39-c.html).

## 共用体の誤った使い方
次のコードはC言語の場合は未規定で動作しますが, C++では未定義です.

```cpp
union U
{
    int32_t i_;
    float f_;
};
U u;
u.i_ = 0;
float f = u.f_; //< 最後に値を入れたメンバ以外でアクセスすることは, 未定義
```

## 型の読み替えの誤った使い方
ポインタの指す型が互換性のない型の場合, 未定義動作になります.

```cpp
int32_t i=0;
float f = *((float*)&i);
```

# タイプパニング
型変換ではなく, ビット単位で同じ内容の別の型に変換することを, タイプパニング(type-punning)といいます. 共用体やポインタの型を読み替える方法は, 多くの処理系で期待したとおりに動作してしまいます（全ては調査していないです）.
安全な方法を次に記載します.

## C++17以前
`memcpy`を使う方法があります. シリアライザなどで, エンディアンを入れ替える場合は, バイト毎に入れ替えてから`memcpy`を行うことになるでしょう.
コードの面倒くささはどうしようもないですが, パフォーマンスに関してはコンパイラ組み込み関数を使うと型の読み替えと同等になると思います.

```cpp
#include <cstdint>
#include <cstring>
#include <iostream>

int main(void)
{
    int32_t x=0;
    float f;
    ::memcpy(&f, &x, sizeof(f));
    std::cout << f << std::endl;
    return 0;
}
```

## C++20以降
正にタイプパニングを行う`std::bit_cast`が加わりました.

```cpp
#include <cstdint>
#include <bit>
#include <iostream>

int main(void)
{
    int32_t x=0;
    float f = std::bit_cast<float>(x);
    std::cout << f << std::endl;
    return 0;
}
```

# なんでも型
C++17からより安全な共用体として, `std::variant`と`std::any`が追加されました. 誤った使い方をした場合例外を投げてくれます.

```cpp
#include <cstdint>
#include <iostream>
#include <variant>
#include <any>

int main(void)
{
    using namespace std;
    variant<int32_t, float> v = 0;
    any a = 0;
    cout << get<int32_t>(v) << endl;
    cout << any_cast<int32_t>(a) << endl;
    cout << get<float>(v) << endl; //bad_variant_access例外
    cout << any_cast<float>(a) << endl; //std::bad_any_cast例外
    return 0;
}
```

`std::variant`はコンパイル時に入れることができる型が決まるので, 従来の`union`に近いです. 入れた型を忘れてしまった場合は, `std::variant::get_if`や`std::variant::visit`を使用します.

`std::any`はランタイムで動的に入れる型を変更することができます. 入れた型を忘れた場合は, `std::any::has_value`や`std::any::type`を使用します.

# まとめ
簡単な方法がないため, 処理系も仕方なく上手く処理していたようで, 間違った方法が解説されていたように思います. プロダクトでは移植性のある方法に切り替えていくとよいでしょう.
副業人材とマネジメント

# はじめに

[UdonTech Advent Calendar 2022](https://qiita.com/advent-calendar/2022/udontech) の1日目です。

以前は自分自身が副業エンジニアとしていくつかの案件に参画しており、最近ではマネジメント側として受け入れることも多くなりました。

その上で、副業人材がワークするためには、こんなことを気にするといいかもねということを少し並べてみたいと思います。


# 副業はマネジメントコストが高い！？

副業人材を抱えるマネージャーであればこう感じたことがある方も多いのではないでしょうか。

確かにフルタイムの人材に比べて直接的にコストが増える部分があります。
タスクを切り出して、期限内に完了するように計画し、超過していないかを計測する。
ここまでは本業人材と同じなのですが、次のような項目については新たに発生します。

・稼働のタイミングを個別に把握する。
・独りで問題解決しにくいタスクはアサインを遠慮する。または解消できるメンバーとのコミュニケーションを計画する。

ただこれは副業人材に固有と言うよりは、同じ時間に稼働できないメンバー全員に当てはまりやすい現象です。
フレックスで稼働時間がズレている場合や、海外拠点などで時差がある場合などにも似たようなことが起きやすいです。


そして本業人材に比べて担当するタスクの両自体は少ないですので、マネジメントコストの全体量が多いということはないです。

しかし、週5日メンバーに 5のマネジメントコストが掛かっているとすると、週1日メンバーに 2のマネジメントコストが掛かるような割高感はあります。


# 重宝される副業人材とは！？

上記のような状況ですが、多くの副業人材を見ていると、数人に一人は主体的にコミュニケーションをとってくれる方がいらっしゃいます。

マネージャーが気にするであろうことを聞かれる前に、情報提供してくれる方です。

割合が高くないので、出会ったときはかなり嬉しいです。

おそらく本業のほうでは皆さん出来ていると思うのですが、意識的にも体力的にも後手に回りがちな副業では、実施できている方が少ないように感じます。

加えて、自らタスクを取りに来てくれる方はめちゃくちゃありがたいです。


これから副業を始められる方は、主体的にコミュニケーションを取って、自らタスクを取りに行って、是非愛され副業人材になってくださいね。
【Laravel】view()とredirect()の使い分け

現在独学でLaravelを使用し、簡単な掲示板を作成しています。
掲示板を作成していくなかで、view()とredirect()の使い分けについて紛らわしいなと感じたので,備忘を兼ねて記事を投稿させていただきます。

## そもそもview()とredirect()ってなに？
フロントの画面からフォームでデータが送信されたときに
LaravelではコントローラーでPOSTやGETのリクエストを受け取り、データの保存やリストの取得などの処理をします。
その処理の後、view側に処理したデータを渡す際に使うのがview()とredirect()です。

## view()について

 サンプルコード↓↓
~~~ 
 return view('home', compact('comments'));
~~~

**ものすごく簡素化していうとGETの時はview（）を使う！！以上！！！笑**
もう少し丁寧に説明すると
まず上記のサンプルコードの記載の
第一引数の **'home'** は、viewのファイル名を記載しています。
そして、第二引数の **compact('comments')** はコントローラー内に記述している処理が入った変数をcompact()内に記述し、viewファイルで使用できるように記述をしています。
ビューファイルへの遷移と、その際に使用したいデータを一緒に渡しているんですね〜

## redirect()について

サンプルコード↓↓
~~~ 
 return redirect(route('home')); 
~~~
**はい！こちらはPOSTの時はredirect（）を使う！!以上！**
ちゃんと説明します。。。
redirect()はフォーム送信などのRoute::post()で呼び出すメソッド内に記述します。
上記のサンプルコードの記載の
第一引数の **'home'** は、routes/web.phpのルーティングでルートに名前を付けて、その名前（home）を指定します。
なので、ファイルを直接呼び出しているviewとは呼び出し方にも違いがあります。
また使用例としては、POSTの際やセッションを保持させてエラー情報を付加させたり、明示的にステータスコードを指定するなどの実装パターンも可能です。

## 最後に
色々と記載しましたが、とりあえず！！
**GETの時はview()**
**POSTの時はredirect()**
このパターンを理解して、そこから引数の付与等で出来ることを追加で学習していければいいかな？と思いました。
まだまだ僕も知識が浅いので、今後使用していく中でさらに理解を深めていければと思います！
最後までご覧いただきありがとうございました！
ずっと可視化したかった図を可視化してみた


# 記事を書くに至った経緯
ゼロから作るDeeplearning１では非線形分離問題としてXOR回路を扱っており、単純パーセプトロンを2層にすることで解くことができると書かれている。
ただ、非線形領域は2層以上のパーセプトロンで表現できることに少しギャップを感じた。そこで、2層のパーセプトロンで曲線のような非線形な領域を表現できることを図で表現してみたいと考え、この記事を書くに至りました。


# 線形な領域と非線形な領域
単純に言うと直線で分離可能かどうかである
以下の図は赤と青の点は直線で分離できる、分離した領域は線形な領域
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/ef4b8305-e5b7-b408-c3c5-e3b10b85a54d.png)

以下の図は赤と青の点は直線で分離できない、そのため分離した領域は非線形な領域となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/908da8ef-a93e-de3a-9e9e-96b33a2b97cf.png)


# パーセプトロンの限界
パーセプトロンは、複数の信号入力として受け取り、ひとつの信号を出力します。

パーセプトロンを数式で表すと、以下のようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/6619cb9b-9dfa-f32e-7880-06f89d531e81.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/9a563352-1d20-7f1a-7d39-7a962bfafc1b.png)



パーセプトロンはこのように1本の直線で分けた線形な領域は表現できるが。非線形の領域を表現できない。このことを**パーセプトロンの限界**といいます

# パーセプトロンを2層重ねることで非線形な領域を表現する
そこで、XORゲート問題について扱う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/6126950a-a601-cab9-f158-456451a7d920.png)
この赤と青を分離することを考える
以下のように2つのパーセプトロンを重ねることで分離することができる(それぞれの座標を代入すると分離できることを確認できると思います）
![ゼロつく.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/44616b37-7b07-f57b-b699-549a1699dba7.png)
二つの特徴量とｚの関係を可視化すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/7c168e1f-1e3a-0bfa-7a9d-27056d2fddb4.png)

二次元上の点を二つの単純パーセプトロンによってもう一つの次元（z軸）に写像し、
z軸の値で線形分離することを考えると
zの値を0以下はnegative 0以上はpositiveとするとXOR回路を表現できたことになる

つまり、2つの線形分離で重なる部分が非線形な領域となっている
ただ、単に直線を2つ引いて重なる部分をy=1としているだけである

**先ほど紹介した曲線のような分離境界線は本当に引けるのかと疑問に思ったため、その様子を実際に可視化してみました**
# 曲線のような非線形領域も単純パーセプトロンの重ね合わせを用いて表現できるのか

分離境界線としたい曲線の接線をパーセプトロンで表現し、それらを組み合わせることで曲線のような非線形な領域を表現できるのではないかと考えた

ただ、この曲線を式で表現することが難しかったため、その曲線の接線ぽい直線をパーセプトロンで表現することにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/6b96abd5-004c-1902-36cf-a511125ef0d6.png)
それぞれの直線をパーセプトロンで表し、その出力を入力としたすべての重みs=1のパーセプトロンを考える
![名称未設定ファイル (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/65ab2570-26a6-6881-4197-0261ca2e9c27.jpeg)


二つの特徴量とｚの関係を可視化すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/49cd3fa2-96e3-758b-570b-00008e42c9da.png)

この図を上から見てみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2589821/b4a3793d-43c1-4823-3d2b-50dfdfcb2ffc.png)

黄色い部分が曲線のような非線形領域の分離境界線となっていることがわかる

# 終わりに

パーセプトロンの組み合わせを変えるとどんな関数でも近似できるなぁと実感しました。
パーセプトロンを無駄遣いしている気もしますが、、


また勉強会で気になった点などを書いていきたいです！

# 参考文献
ゼロから作るDeeplearning-Pythonで学ぶディープラーニングの理論と実装　著者　斎藤 康毅
パーセプトロンを多層にするとなぜXOR回路を表現できるのか- https://ker60.hatenablog.com/entry/2017/06/13/000609
ニューラルネットワークが任意の関数を表現できることの視覚的証明 - https://nnadl-ja.github.io/nnadl_site_ja/chap4.html
Windows11 HomeとProの違いについて

# はじめに
未経験からプログラミングスクールでRubyに触れSEに転職しました。

業務では基幹システムの要件定義や設計、コーディング、保守を行なっています。
言語はDelphiとRPGⅢ。プライベートはSwiftで開発してます。
今回、法人ユーザー様から端末買換えとのこと質問をいただきました。
ProとHomeなにが違うのか調査したことを書きます。

# 目次
- [目次](#目次)
- [本記事の対象者](#本記事の対象者) 
- [当初のイメージ](#当初のイメージ)
- [わかったこと](#わかったこと)
    - [Proの特徴](#Proの特徴)
    - [サーバ、ネットワークエンジニアから聞いたこと](#サーバ、ネットワークエンジニアから聞いたこと)
    - [リモートデスクトップのホストとは](#リモートデスクトップのホストとは)
- [お客様へ伝えたこと](#お客様へ伝えたこと)
- [参考](#参考)
- [Windows11　HomeとPro比較](#Windows11　HomeとPro比較)
- [おわりに](#おわりに)


# 本記事の対象者
- 新入社員の方
- OSに詳しくない方

# 当初のイメージ
- Pro：業務用の端末
- Home：家庭用の端末

業務用の端末だからProを選んでくださいでは説明不足感が否めません。

# わかったこと
- Proは会社、ビジネス向けに高度な設定やセキュリティ機能を追加したエディション
- Homeは個人、一般家庭向けに、必要最低限の機能に抑え、価格を安くしたエディション
#### Proの特徴

- ビジネス向けに管理機能、セキュリティ機能が搭載されている
- リモートデスクトップのホスト（遠隔操作される側）になれる
 
1. セキュリティ
　→暗号化やフォルダ、ファイル単位でロックが可能
2. ネットワーク
　→他端末とのネットワーク共有しやすくなっている
3. スペック
　→HOMEは最小スペックに対してPro最大スペックまで選択できる

#### サーバ、ネットワークエンジニアから聞いたこと

- HOMEとProでは設定方法が異なる
- セットアップ時にHOMEだとコマンドプロンプトからでしかできない設定がありサポート時に不便。
- 業務用ビジネスシーンではProが安パイ。

#### リモートデスクトップのホストとは
- 遠隔操作される側の端末=ホスト
- お客様自身が出先からモバイル端末で会社端末を操作したいときにProだと実現しやすい
    - アプリを利用してスマホ、タブレットから会社の端末を操作できる 
- teamviewer接続などであればPro/Homeどちらでも変わらなさそう

# お客様へ伝えたこと
1. セキュリティの担保：ドライブ、ディスク単位でロックをかけられます
2. スペック：Homeは最小スペックのみ、Proは最大スペックまで選択可能です
3. ネットワーク構成：他端末とのネットワーク共有があります 
業務用システム運用では上記3点を満たすOSとしてProを推奨しています。

# 参考
[Windows 10 HomeとProの違いを解説 - 個人でもProを選ぶべき？](https://news.mynavi.jp/article/20210506-1884142/)
[「Windows 11」導入するならエディションによる違いを最低限知っておこう](https://qiita.com/espritfort_tech/items/d4719754f8f25927fe8b)
[Windows の比較表](https://www.microsoft.com/ja-jp/windows/compare-windows-11-home-vs-pro-versions)

# Windows11　HomeとPro比較
利用用途に応じた必要な機能があるかを確認し、必要なエディションを選定する。 
|スペック|Windows 11 Home|Windows 11 Pro|
|:---|:---:|:---:|
|RAM制限|128GB|2TB|
|CPU コアの制限|64コア|128 コア (64+64)|
|CPUソケット|1|2|

|機能|Windows 11 Home|Windows 11 Pro|
|:---|:---:|:---:|
|BitLocker によるデバイス暗号化||○|
|デバイスの暗号化|○|○|
|デバイスを探す|○|○|
|ファイアウォールとネットワーク保護|○|○|
|インターネット保護|○|○|
|保護者による制限と保護|○|○|
|セキュア ブート|○|○|
|Windows Hello|○|○|
|Windows 情報保護 (WIP)||○|
|Windows セキュリティ|○|○|
|割り当てられたアクセス||○|
|動的プロビジョニング||○|
|Azure による Enterprise State Roaming||○|
|グループ ポリシー||○|
|キオスク モードのセットアップ||○|
|ビジネス向け Microsoft ストア||○|
|MDM (Mobile device management)||○|
|Active Directoryのサポート||○|
|Azure Active Directory のサポート||○|
|ビジネス向け Windows Update||○|
|Auto HDR||○|
|Microsoft Teams からのチャット||○|
|デスクトップの整理||○|
|DirectStorage||○|
|Microsoft Store|○|○|
|Microsoft Teams|○|○|
|新しい絵文字||○|
|「フォト」アプリ|○|○|
|シームレスな再ドッキング||○|
|スナップ アシスト|○|○|
|タッチスクリーン|○|○|
|アップデート||○|
|ウィジェット||○|
|ARM 版 Windows|○|○|

# おわりに
- イメージ通りだったが端末選定には導入事後の運用保守なども考慮する。
- チェックする箇所は用途や役割に応じて異なることが分かった。
- 営業は価格の話もするので納得感のある説明スキルが必要そう。
- お客様のITリテラシーに合わせ伝える内容を考える必要がある。
圧縮率40%とは

# 圧縮率40%とは
## 概要
圧縮率の表記について疑問を持ったのでまとめる。
## 内容
以下の応用情報の問題についてである。

https://www.ap-siken.com/kakomon/29_haru/q11.html

以下のような問題である。
> 15Mバイトのプログラムを圧縮した状態でフラッシュメモリに格納している。プログラムの圧縮率が40%，フラッシュメモリから主記憶への転送速度が20Mバイト／秒であり，1Mバイトに圧縮されたデータの展開に主記憶上で0.03秒が掛かるとき，このプログラムが主記憶に展開されるまでの時間は何秒か。ここで，フラッシュメモリから主記憶への転送と圧縮データの展開は同時には行われないものとする。

ここでは、「プログラムの圧縮率が40%」と記載されているが、どちらの意味なのかがよくわからなかった。
- プログラムが40%のサイズに圧縮されるのか
- 60%を圧縮ファイルとして出力するのか


何が言いたいかというと、圧縮率10%と圧縮率100%を例に挙げてみると、共感しやすいかもしれない。
下記は、解答例に沿った解き方を用いて計算した結果である。
> 15M * 10% = 1.5M
> 15M * 40% = 6.0M
> 15M * 100% = 15.0M

圧縮率100%ならめちゃくちゃ圧縮しているように見えるが、
上記の計算だと15Mのままで圧縮できていないのである。

## 正解は...
「プログラムが40%のサイズに圧縮される」のが正解だと記載されていた。
> 15M * 40% = 6.0M

## 一応圧縮率について調べてみた
IT用語辞典を見てみる。

https://e-words.jp/w/%E3%83%87%E3%83%BC%E3%82%BF%E5%9C%A7%E7%B8%AE%E7%8E%87.html#:~:text=%E3%83%87%E3%83%BC%E3%82%BF%E5%9C%A7%E7%B8%AE%E7%8E%87%E3%80%90data%20compression,%E3%81%A8%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E3%81%82%E3%82%8B%E3%80%82

以下のように記載されていた。
> 例えば、100MBのファイルが10MBに圧縮された場合、10/100の0.1（百分率で10%）を圧縮率とする場合と、（100-10）/100の0.9（同90%）を圧縮率とする場合がある。前者は値が小さいほどより少ない量に圧縮できていることを表し、後者はその逆である。いずれの場合でも慣例的に、より少ない量に圧縮された（よく圧縮できた）状態を「圧縮率が高い」、多い量に圧縮された（あまり圧縮できなかった）状態を「圧縮率が低い」と言い表す。

## つまり...?
**意味合いはどっちともとれるのである。**

# 結論
日本語難しい。
応用情報の問題に従っておくのが無難と思い、勉強を進めていこうと思う。
Pythonで形態素分析を行う

# Pythonで形態素分析してみる

## MeCabインストール
MeCab 64bit 版を入手
インストーラーは[こちら](https://github.com/ikegami-yukino/mecab/releases/tag/v0.996.2)からダウンロードできます。

## MeCab 64bit 版をインストール
インストーラを、ダブルクリックし、画面のメッセージに従ってインストールします。

この時、辞書の文字コード選択は「UTF-８」を選択しておくことがポイントです。

但し、Womdowsのコマンドプロンプト上で文字化けしますが、ここでは我慢しましょう。

もし、コマンドプロンプト上でしかMeCabを使わないのであれば、初期値（SHIFT-JIS）のままでも問題はありません。


## Pathの設定
設定＞システム＞詳細情報＞システムの詳細設定＞環境変数

からPathの編集を行う。

システム環境変数内のPathを選択し、編集を押す。
そして、Pathの編集画面が出たら、新規を押して下記のPathを追加し、OKを押す。

C:\Program Files (x86)\MeCab\bin
C:\Program Files\MeCab\bin

## もしエラーが出るなら
私は、[こちら](https://github.com/polm/fugashi/issues/42)のサイトを参考に解決いたしました。
方法といたしましては、

"C:\Users\[ユーザー名]\AppData\Roaming\Python\lib\site-packages\MeCab\libmecab.dll"
を
"C:\Users\[ユーザー名]\AppData\Roaming\Python\Python310\site-packages\MeCab"
このフォルダに移行することで強制的にエラーを回避しました。










:::note info
インフォメーション
infoは省略可能です。
:::

:::note warn
警告
○○に注意してください。
:::

:::note alert
より強い警告
○○しないでください。
:::
運を味方につけて遊ぶマインスイーパー

最近，2日間で一本ゲームを作らなければいけない状況に陥ったので，簡単なものをリリースしました．しかし，たいして面白くないのでその作ったゲームをここで供養しようと思います．

# 何を作ったか

「**Minesweeper++**」というマインスイーパーの運要素を高めたゲームです．

![Web キャプチャ_1-12-2022_2395_minesweeper-plus-plus.vercel.app.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2274081/5b83db0c-20cf-0b31-bc70-36e90f17027a.jpeg)

https://minesweeper-plus-plus.vercel.app/

https://github.com/kage1020/MinesweeperPlusPlus

ロゴはC++をいじって作りました．非商用なので許してください．

https://github.com/isocpp/logos

具体的に何の運要素を高めたかというと，「マスを開けたときに周りに何個の地雷があるか」の数字を確率で減少させるようにしました．つまり，**周りの地雷の数がすべて見つかるとは限らない**という状況になるようにしました．
世の中すべてうまくいくことってなかなかないですよね．時には大事なことを見逃したり，視野が狭くなって実際のものよりも過小評価してしまったり，などなど．
このゲームはそんな世の中の道理を反映させたゲームです(大嘘)．

ただ，全てのマスにおいて見つかる地雷の数が減少してしまうと，ゲームとして成り立たないのでいくつか救済処置を入れました．

* 減少する地雷の数は50%まで
* 周りに地雷が1つしかない場合には必ず「1」と表示される．

これは以下の式によりもたらされる効果です．

```js
// count: 表示される地雷数
// mines: 実際の地雷数
count = Math.ceil( (Math.random() / 2 + 0.5) * mines )
```

0から1の一様乱数を0から0.5の範囲に縮小し，0.5だけずらした乱数を減少確率として実際の地雷数にかけています．ここで注意したいのは，マスに1が表示されるのは

* 実際の地雷数が1
* 実際の地雷数が2で，乱数が0

のときのみであることです．つまり，よほどのことがない限り1は信頼のおける数字だということです．これを頼りにゲームを進めていくと何とかクリアできるんじゃないかと思っています．また，2以上の数字は実際の地雷数から減少した数なので，最低保証数と捉えることもできるので案外簡単かもしれません．

# 実装とその他諸々

実装には普段から使い慣れているNext.js+TypeScript+TailwindCSSを使いました．
盤面の情報はhooksで管理し，マス1つ1つをボタンでレンダリングしました．

工夫した点としては，マスを開けるのか，フラグを立てるのかの操作を，マスを選択した後にポップアップ形式で表示させて選択させる方法です．多くのマインスイーパーではopen/flagボタンが1つ用意されてそれによって切り替えたり，右クリックや長押しで判定を切り替えたりするものが多かったですが，ユーザーの操作感に左右されたり，正確な操作が求められUXが悪いと感じたのでこのような形にしました．

![Web キャプチャ_1-12-2022_231058_minesweeper-plus-plus.vercel.app.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2274081/15201a1f-18e9-8e6e-2e55-273acef22321.jpeg)


この発想は，Google Playゲームに標準でインストールされているマインスイーパーから得ました．

![nse-3030379952932332300-1000000058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2274081/664341bb-d423-77bf-97ff-c1a92d36b88a.png)

また，今回様々なデバイスで使われることを想定して**LogRocket**を導入しました．これはそのサイトにアクセスした人がどこをクリックし，どのような操作をしたのかが丸見えになるツールで，不具合などが起きたときに解析がしやすくなります．

https://logrocket.com/

---

以上，簡単に作ったものを紹介しました．一度サイトに訪れていただければ幸いです．
【AWS x ECS x Go】New Relic の導入① ログ設定とメトリクスの収集

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

弊社では、ログ保管やAPM・メトリクスの収集先としてNewRelicを採用しています。
私は認証チームとして、Go言語のサービスにNewRelicを導入したため、その方法を紹介できればと思います。

本記事は、その取り組みの中で行なったログ転送とメトリクス収集に関する記事になります。

# 実施環境
言語：Go言語
フレームワーク：[go-chi](https://github.com/go-chi/chi)
実行環境：ECS on Fargate
CI/CD： Codeシリーズ

# 導入
## ログ転送
ログをあらかじめjsonにシリアライズしておく必要はありますが、タスク定義に以下の設定を組み込むことですぐ使用開始できます。
タスク定義上のアプリケーションコンテナ部分に以下のように書きます。
これらの設定をすることで、firelensでログを飛ばす設定ができます。
```json
"logConfiguration": {
  "logDriver": "awsfirelens",
  "options": {
    "Name": "newrelic"
  },
  "secretOptions": [{
      "name": "apiKey",
      "valueFrom": "${NEWRELIC_LICENSE_KEY}"
  }]
},
```

ログルータ部は以下の通り設定します。
NewRelic謹製のimageがあります。
```json
{
  "name": "log_router",
  "image": "533243300146.dkr.ecr.us-east-2.amazonaws.com/newrelic/logging-firelens-fluentbit",
  "essential": true,
  "firelensConfiguration": {
    "type": "fluentbit",
    "options": {
      "enable-ecs-log-metadata": "true"
    }
  }
}
```

## メトリクスの収集
メトリクスの収集についてもタスク定義に以下の設定を組み込むことですぐ使用開始できます。
```json
{
  "name": "newrelic-metrics",
  "image": "newrelic/nri-ecs:latest",
  "environment": [
    {
      "name": "NRIA_OVERRIDE_HOST_ROOT",
      "value": ""
    },
    {
      "name": "NRIA_IS_SECURE_FORWARD_ONLY",
      "value": "true"
    },
    {
      "name": "FARGATE",
      "value": "true"
    },
    {
      "name": "NRIA_PASSTHROUGH_ENVIRONMENT",
      "value": "ECS_CONTAINER_METADATA_URI,ENABLE_NRI_ECS,FARGATE"
    },
    {
      "name": "NRIA_CUSTOM_ATTRIBUTES",
      "value": "{\"nrDeployMethod\":\"downloadPage\"}"
    }
  ],
  "secrets": [
    {
      "name": "NRIA_LICENSE_KEY",
      "valueFrom": "${NEWRELIC_LICENSE_KEY}"
    }
  ],
}
```

# まとめ
今回は、GoのWebアプリケーションにおいて、NewRelicを使ったログルーティングとメトリクス収集の設定方法について紹介しました。
いずれの設定もタスク定義を修正することで利用できるため、簡単にはじめられてよいですね。
次回は、APMの導入記事を書こうと思います。
【React】コードはもっと無責任に書いて欲しい

## はじめに

コードレビューをしていると**このコードは優しすぎる**と思うことが多々あります。

現実世界では優しいことは美徳とされますが、コードが優しいと保守性が崩れていきます。

今回は、**コードはもっと無責任に書いて欲しい**という話をします。

:::note warn
Reactを知っている前提で書きますが、知らない人もなんとなく言っていることはわかるかと思います。
:::

## 優しいコード

優しいコードとは**複数の責務を持ってしまっているコード**です。

以下で郵便番号フォームの一機能を作ってみます。

### 仕様

- 郵便番号の形式に沿っていない場合
    - 「正しい郵便番号を入力してください」とメッセージが出力される
- 正式な郵便番号の形式の場合
    - APIからデータをフェッチし、住所が出力される

### 優しいコード

`zipcode`を受け取り、適切なメッセージを返すカスタムフックを作ります。

```tsx:use-address-message.ts
import { useEffect, useState } from 'react';
import { fetchAddress } from './fetch-address';

export const useAddressMessage = (zipcode: string) => {
  const [message, setMessage] = useState('');
  useEffect(() => {
    if (zipcode.length !== 7) {
      setMessage('正しい郵便番号を入力してください');
    }

    (async () => {
      const address = await fetchAddress(zipcode);
      setMessage(`${address.pref} ${address.city} ${address.town}`);
    })();
  }, [zipcode]);

  return { message };
};
```

一見、良さそうに見えるのですが、**addressを取得してくる処理**と**エラーメッセージの処理**が同居してしまっていることは問題だと思います。

### 問題になるシーン

#### 1. エラーメッセージの種類が増えた時

現状、`zipcode.length !== 7`の時にエラーを出すという処理しか書かれてません。
でも、**zipcodeに`-`が入っていた時には別のエラーを出してほしい**という要望が増えたらどうでしょう？

次、コードを書く人は条件分岐を増やしてしまい、どんどん肥大化していってしまうと思います。
きちんとエラー処理は分けるべきだと思います。

#### 2. フェッチしたaddressを別のものに使いたいと思った時

今は、messageで連結した文字列を返していますが、もしかしたら**フェッチした住所を用いて別のAPIを叩きたくなるかもしれません**。
そんな時に密結合してしまっていると切り離しの処理が発生してしまいます。

## 無責任なコードにリファクタしてみる

### アドレスをフェッチするカスタムフック

アドレスをフェッチして返すだけのカスタムフックを作りましょう
このカスタムフックの関心事としては、APIを叩く条件になったらAPIを叩き、レスポンス（アドレス）を返すのみです。

```tsx:use-address.tsx
import { useEffect, useState } from 'react';
import { fetchAddress } from './fetch-address';

type Address = {
  pref: string;
  city: string;
  town: string;
};

export const useAddressMessage = (zipcode: string) => {
  const [address, setAddress] = useState<Address | undefined>(undefined);
  useEffect(() => {
    if (zipcode.length !== 7) return;

    (async () => {
      const res = await fetchAddress(zipcode);
      setAddress(res);
    })();
  }, [zipcode]);

  return { address };
};
```

役割が分かれ、シンプルになりましたね。
再利用性も抜群です。

### エラーメッセージを生成する関数

実は、エラーメッセージを出す処理はカスタムフックにする必要すらありません。
zipcode自体がstateなので、値が書き変わるたびに再レンダリングされます。

なので、以下のようなシンプルな関数で良いですね。

```tsx:zipcode-error-message.ts
export const zipcodeErrorMessage = (zipcode: string) => {
  if (zipcode.length !== 7) return 'エラーです';
};
```

処理が増えたとしても見通しが良さそうです。

## まとめ

コードの責務をきちんと分ける。というのはできているようで意外とみんなやりがちだったりします。

みんな優しすぎるんですね。

繰り返しますが、**現実世界では優しいは美徳ですが、コードの世界に持ち込まないようにお願いします**。
fastlaneのタイムアウトの時間を引き伸ばす

## 事象
fastlaneで動かした処理に時間がかかると、以下のようにタイムアウトが発生します。

```
/Users/vagrant/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/fastlane-2.210.1/fastlane_core/lib/fastlane_core/project.rb:486:in ``': execution expired (Timeout::Error)
```
必要に応じて、タイムアウトまでの時間を増やす対応が必要です。

## 環境
fastlane: [2.210.1](https://github.com/fastlane/fastlane/releases/tag/2.210.1)


## 対応方法
fastfileに以下を記載します。
数字はタイムアウトまでに設定したい秒数を入れてください。
```ruby
ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "30"
```

## 解説
タイムアウト発生時時に以下のような文言が吐かれているはずです。
```
[06:45:23]: Command timed out after 3 seconds on try 1 of 4, trying again with a 6 second timeout...
[06:45:29]: Command timed out after 6 seconds on try 2 of 4, trying again with a 12 second timeout...
[06:45:41]: Command timed out after 12 seconds on try 3 of 4, trying again with a 24 second timeout...
（中略）
[06:46:05]: Command timed out after 24 seconds on try 4 of 4
（中略）
XXX timed out after 4 retries with a base timeout of 3. You can override the base timeout value with the environment variable FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT, and the number of retries with the environment variable FASTLANE_XCODEBUILD_SETTINGS_RETRIES
```

fastlaneでは、タイムアウト（FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT）のデフォルト値は3秒のようです。
公式ドキュメントには記載がありませんが、コードがその様になっています。
https://github.com/fastlane/fastlane/blob/e14064258cd784d65e30c19fe137ecbe5f5c8da7/fastlane_core/lib/fastlane_core/project.rb#L457
失敗すると、タイムアウト値を2倍にして再チャレンジします。
https://github.com/fastlane/fastlane/blob/e14064258cd784d65e30c19fe137ecbe5f5c8da7/fastlane_core/lib/fastlane_core/project.rb#L492
再試行回数（FASTLANE_XCODEBUILD_SETTINGS_RETRIES）のデフォルトは4回なので、デフォルトのまま変更していない場合、以下のように試行されます。
- 1回目：3秒
- 2回目：3 * 2 = 6秒
- 3回目：3 * 2 * 2 = 12秒
- 4回目：3 * 2 * 2 * 2 = 24秒

再試行回数も変更したい場合は、タイムアウトと同じようにfastfileでの設定が可能です。
```ruby
ENV["FASTLANE_XCODEBUILD_SETTINGS_RETRIES"] = "2"
```
実行したい処理の速さや内容によって、適切な時間を設定しましょ！
TODOリストをJavaScriptで作ったよ！

# 今回はJavaScriptの練習も込めてTODOlistを作りました。
まずは、コードを紹介します。↓
## HTMLコード
***
```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body class="bg-light">
    <div class="container w-75">
    <h1 class="text-center text-info my-4">TODO</h1>
    <form id="form" class="mb-4">
        <input type="text" id="input" placeholder="TODOを入力" class="form-control">
    </form>
    <ul class="list-group text-secondary" id="ul"></ul>
</div>
    <script src="index.js"></script>
</body>
</html>
```
## javascriptのコード
***
```javascript
const formget = document.getElementById("form");
const inputget = document.getElementById("input");
const ulget = document.getElementById("ul");

const todos = JSON.parse(localStorage.getItem("todos"));

if(todos){
    todos.forEach(todo => {
        add(todo);
    });
}

formget.addEventListener("submit",function(event){
    event.preventDefault();
    add();
});

function add(todo){
    let todoText = input.value;

    if(todo){
        todoText=todo.text;
    }

    if(todoText){
    const li = document.createElement("li");
    li.innerText = todoText;
    li.classList.add("list-group-item");

    if(todo && todo.completed){
        li.classList.add("text-decoration-line-through");
    }
    
    li.addEventListener("contextmenu",function(event){
        event.preventDefault();
        li.remove();
        saveDate();
    });

    li.addEventListener("click",function(){
        li.classList.toggle("text-decoration-line-through");
        saveDate();
    });

    ulget.appendChild(li);
    input.value = "";
    saveDate();
    }
}

function saveDate(){
    const lists = document.querySelectorAll("li"); 
    let todos = [];

    lists.forEach(list => {
        let todo = {
            text: list.innerText,
            completed: list.classList.contains
            ("text-decoration-line-through")
        };
        todos.push(todo);
    });
    localStorage.setItem("todos",JSON.stringify(todos));
}
```

## 使い方
***
これがホームです。
![スクリーンショット 2022-12-01 20.45.43（2）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982406/3a5569bd-6d4b-7b0d-45ab-0f28ade7a3d3.jpeg)

入力フォームからTODOを入力します。
![スクリーンショット 2022-12-01 20.46.50（2）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982406/61e65345-e6aa-aa86-1941-a8ab79a9436d.jpeg)

終わったTODOは左クリックで線を引けます。
![スクリーンショット 2022-12-01 20.47.02（2）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982406/23318453-26bc-4b94-4072-664eaec9053d.jpeg)

やっぱりいらないTODOは右クリックで消せます。
![スクリーンショット 2022-12-01 20.47.20（2）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982406/51ddf38a-30f3-13ca-fabb-f20ec37c657a.jpeg)


#つかってみてね！
読んでくれてありがとう。
クリスマスまで残り**２３日!!**
VS CodeのArduino IDE拡張機能を入れたら開発体験が最高になった

## はじめに
これまではArduino IDEをそのまま使用していましたが、VS Codeで開発したいと思い良い方法がないか探していました
Arduinoの拡張機能を入れたら世界が変わったので紹介します

## やること
1. Arduino IDEをインストール
1. VS Code拡張機能を入れる
1. 拡張機能の設定を行う
1. 開発する

## Arduino IDEのインストール
こちらから自身の環境にあったものをインストールしてください
https://www.arduino.cc/en/software

## VS Code拡張機能を入れる
こちらのリンクの拡張機能を入れてください
https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.vscode-arduino

## 拡張機能の設定を行う
最低限こちらが設定されていれば問題ないです
```json
{
  "arduino.path": "C:\Program Files (x86)\Arduino",
  "arduino.commandPath": "arduino_debug.exe",
}
```
arduino.path: Arudino IDEがインストールされている場所のパス
arduino.commandPath: Arduino IDEの実行ファイルを指定します

## 開発する
![d398ddbed96c6b06bdae9d2522e35c4c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362594/5bb7f54f-5505-078f-461e-eef7d6418346.png)

VS Codeのデフォルト設定だと右下にBord選択やSerial Portの選択メニューが出てきます
必要に応じて選択してください

### コンパイルと書き込み
VS Codeの右上に書き込みとコンパイルのボタンが出てきます
![1e65b7d9b8c7c977fec93a1f95961dec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362594/ec0a3e57-3f00-5ca0-913f-5184a25f486c.png)

## まとめ
VS Codeで最低限Arduinoを利用する環境ができました
コードの保管などもやりやすくなるので、これまでより開発効率をあげることができそうです

## 参考
https://github.com/microsoft/vscode-arduino
Can't connect to MySQL server on 'xx' (115)エラーの解決方法と思わぬ落とし穴

# 起きた事象
MySQLとRailsの環境をdocker-composeで作成し、DBを作成しようとしたら下記のエラーになりました。

```java:terminal
$ docker-compose run web rails db:create
・
・
・
Can't connect to MySQL server on 'db' (115)
Couldn't create 'app_development' database. Please check your configuration.
rails aborted!
ActiveRecord::ConnectionNotEstablished: Can't connect to MySQL server on 'db' (115)


Caused by:
Mysql2::Error::ConnectionError: Can't connect to MySQL server on 'db' (115)

Tasks: TOP => db:create
(See full trace by running task with --trace)
```

解決まで半日ぐらいかかりましたので備忘録をこめてこちらに記載しておきます。

私は初学者のため、当たり前すぎることの記載や間違い等もあるかもしれないので予めご了承ください。

# 環境
- Rails:7.0.4
- Ruby:3.1.2
- MySQL:
    dockerimage:8.0.31


# 結論
結論から述べますと、database.ymlのpasswordの値をダブルコーテーションで囲んでいないのが原因でした。（おそらく）
```java:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: "password"   # ←passwarodから修正
  host: db
```

こちら　を修正しまして、再度
```java:terminal
$ docker-compose run web rails db:create
```
を実行すると正しくDBが作成されました。

おそらく、ymlがうまく読み取れていなかったのが原因のようです。。。
いろんな記事を参考にしていましたが、上記のように記載されている記事はなかったので穴でした。
私だけかもしれませんが、参考になれば幸いです。


# 経緯と参考記事
この結論にいたるまでの道のりと参考記事をこちらに記載していきます。
おかげさまで勉強になったのは間違いないので、、、


## 環境変数とは

まず問題があるとすれば3つのファイルのうちどこかの設定が間違えているのだろうと思い色々試してみました。
- docker-compose.yml
- config/database.yml
- .env(参照できていない？)

エラーの内容からDBに接続出来ていないんだなと思い、docker-compose.ymlのmysql部分について再度勉強し直しました。
環境変数(environment句)とはなんなのか。パスワードは.envに記載するべきなのか検討してみました。
[こちら](https://qiita.com/nanakenashi/items/180941699dc7ba9d0922)の記事をがとても参考になりました。
※最初からドキュメントを読むのも手です。

MYSQL_ROOT_PASSWORD
MYSQL_DATABASE
MYSQL_USER
MYSQL_PASSWORD

上記がこんがらがっていたのでいろんな手を使って修正してみましたが、ずっとタイトルと同じエラーでした。。

そんな時に[こちら](https://teratail.com/questions/317758)の記事を拝見しまして、そんなんで治るわけないだろ。。と思いながらやってみると直りました。。。


## 結局docker-composeのパスワードは.envに記載するべきなのか
いろんな記事を見ているともちろん.envに記載する人もいましたが、大多数が.envに記載せず直書きしていました。
すごく心配でしたが、そもそもdockerというものの性質上、不要でないと意味ないのではないかと思い始めました。

コンテナの特性としてポータビリティ（一貫性）があります。
それを考えた時に.envファイルを使わないと環境を構築できないのは結構致命的だと思いました。
てかそもそもコンテナは仮想空間に作るものなので、自身のmysqlのroot権限がとかパスワードがとかどうとか関係ないんですよね。
もちろん.envファイルを使用しなければいけない場面もあるとは思いますが。。
※初学者なので、認識の違いがあればご指摘いただけれ幸いです。

# まとめ
今回、docker-composeの良い勉強となり結果よかったです。
まずは理解しないとやっぱりダメだなと思いました。
ただ手を動かして分からない部分を詰めていくように、outputからinputする方が良いのかもしれません。

終わり。



# 参考記事
https://teratail.com/questions/317758
https://qiita.com/croquette0212/items/7b99d9339fd773ddf20b
🍪Cookieと戯れる

# TL;DR
Cookie の中身見たいなぁと思うことありますよね。そう思って調べた内容の備忘録。

# 本題
Cookie を見る方法をブラウザを使ったり、生のファイルを見る方法など色々紹介したいと思います。

## 1. 開発者ツール
`F12`で開ける開発者ツールの画面で [アプリケーション] > [Cookie] から、今開いてるサイトの Cookie を確認できます。（Chrome / edge 共通）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252806/944abd70-4a73-d41c-e01f-9f741183ce44.png)

## 2. 拡張機能

もっと手軽にCookieの中身を見るなら拡張機能を使う手もありますね。（Chrome）

https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg?hl=ja

## 3. 生ファイル
保存されているCookieファイルはサイトの種類やOSによって保存場所が異なるようですが、主要なものを紹介します。

### Chrome の Cookie

```bash
// Windows
$ pwd
/c/Users/{USERNAME}/AppData/Local/Google/Chrome/User Data/Default

// macOS
/Users/{USERNAME}/Library/Application Support/Google/Chrome/Default

```

ファイルの名前は`Cookies`とか`Extension Cookies`とかになっていると思います。
ファイルの中身をコピーして↓のWebアプリで見たり、

https://inloop.github.io/sqlite-viewer/

↓をインストールして見ることもできます。このファイルは [SQLite format](https://www.sqlite.org/fileformat.html)形式になっており、SQLite Studioで見る場合は拡張子を `.sqlite`にする必要があります。

https://sqlitestudio.pl/

また、一部暗号化されているデータもあるので、それについては↓の方の記事でちゃちゃっと復号してみることもできます。助かる。

https://qiita.com/relu/items/8689b2d6ee2716cefe4f


### Chrome以外のサイトの Cookie

#### Windowsの場合
[コントロールパネル] > [ネットワークとインターネット] > [閲覧の履歴] の「設定(S)」 > 「ファイルの表示(V)」でキャッシュファイルの場所が分かります。

https://web.vogue.tokyo/cookie#toc12




# まとめ
Cookie の中身を見る方法を知って仲良くなりましょう。
【AWS x ECS x Go】New Relic の導入② APMの取得

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

弊社では、ログ保管やAPM・メトリクスの収集先としてNewRelicを採用しています。
私は認証チームとして、Go言語のサービスにNewRelicを導入したため、その方法を紹介できればと思います。

本記事は、その取り組みの中で行なった、APMの取得に関する記事になります。

# 実施環境
言語：Go言語
フレームワーク：[go-chi](https://github.com/go-chi/chi)
実行環境：ECS on Fargate

# 導入
## 初期化
NewRelicのAPM計測用Goエージェントを初期化する。

まずは、アプリケーションに `github.com/newrelic/go-agent/v3/newrelic`パッケージをインポート
```golang
import github.com/newrelic/go-agent/v3/newrelic
```

次にmain関数、またはinitブロックに以下を追加することで、Goエージェントを初期化
```golang
app, err := newrelic.NewApplication(
    newrelic.ConfigAppName("アプリケーション名"),
    newrelic.ConfigLicense("ライセンスキー"),
)
```

実装によっては、main関数で初期化しつつ他パッケージから呼び出したいため、以下のように`newrelic`パッケージを作成しグローバル変数としてappを保持する。
```golang
var App *newrelic.Application

// NewTracer ...
func InitializeApp() {
	app, err := newrelic.NewApplication(
		newrelic.ConfigEnabled(true),
		newrelic.ConfigDistributedTracerEnabled(true),
		newrelic.ConfigAppName(config.Get().NewRelic.AppName),
		newrelic.ConfigLicense(config.Get().NewRelic.LicenseKey),
		newrelic.ConfigAppLogForwardingEnabled(true),
	)
	if err != nil {
		clog.L.Fatal(err)
	}
	App = app
}
```

## トランザクション
NewRelicのAPMでは、1リクエストに対して1トランザクション紐づく。
トランザクションを開始する方法は、以下の二通りある
- NewRelicが用意したラッパーを利用する

公式推奨の簡単な方法。HandleFuncをラップすることでWebトランザクションを計測しはじめられる。
```golang
http.HandleFunc(newrelic.WrapHandleFunc(app, "/users", usersHandler))
```
- 任意のタイミングでトランザクションを開始する

go-chiを使っている場合など上記の方法をとれない場合、手動でトランザクションを開始できる。
```golang
txn := nr.App.StartTransaction(r.URL.RequestURI())
defer txn.End() // リクエスト処理終了時、クローズが必要

txn.SetWebRequestHTTP(r) // Webトランザクションとする。（設定なしだと非Webトランザクション扱いされる）
ctx = newrelic.NewContext(ctx, txn) // リクエストのコンテキストに埋め込むことができ、これにより他パッケージからでも簡単に呼び出せる
```

## セグメント
1トランザクションは、複数のセグメントから構成される。
各エンドポイントの処理の頭に以下のように記述し、セグメントの計測を行える。
```golang
// NewRelic データストアのセグメントを定義
txn := newrelic.FromContext(r.Context())
s1 := txn.StartSegment("MySegment")
defer s1.End()
```

もしくは、DB関連の処理をセグメントで囲むこともある。
```golang
// NewRelic データストアのセグメントを定義
seg := newrelic.DatastoreSegment{
	Product:            newrelic.DatastoreOracle,
	Collection:         "テーブル名",
	Operation:          "SELECT",
	ParameterizedQuery: query,
}
seg.StartTime = txn.StartSegmentNow()
// この行でDML実行
seg.End()
```

# まとめ
今回はGoのWebアプリケーションへNewRelicのAPMを導入する手順を紹介しました。
NewRelicは公式のドキュメントが充実しているのでシンプルに導入できますが、トランザクションやセグメントなどの前提知識がないと少し混乱していますかもしれませんね。

## 参考記事
https://docs.newrelic.com/jp/docs/apm/agents/go-agent/instrumentation/instrument-go-transactions/
Deno で COPC の範囲情報を取得する

## はじめに
Smart Maps に取り組むことができるようになって、新たに点群を取り扱えるようになりました。Virtual Shizuoka の点群データ（静岡点群）を Cloud Optimized Point Cloud に変換して自家用オブジェクトストレージから提供する Tansei プロジェクトを進めています。

### デモサイト
https://optgeo.github.io/tansei/#15.28/34.979751/138.385075

https://viewer.copc.io/?copc=https://x.optgeo.org/tansei/08nd7773.copc.laz

## COPC のメタデータをスクリプトで取り出したい
現在、静岡点群の LAS ファイルを取り出しては PDAL で COPC に変換して自家用オブジェクトストレージにアップロードするバッチを長期運用で流しているところですが、低速なオブジェクトストレージから COPC の範囲情報を取り出すためには、メタデータの必要なところをスマートに取り出す必要があると思っています。

そのために、connormanning/copc を使ってみたいと思います。実装を除いてみたところ、スマートにデータを取り出すように作られているように見えたからです。

https://github.com/connormanning/copc.js

JavaScript のコマンドラインスクリプトを久しぶりに書くので、Deno で書いてみます。

### コード
こんな感じかなと思います。

```js:reentry.js
import { Copc } from 'npm:copc'
import proj4 from 'npm:proj4'

const url = 'https://x.optgeo.org/tansei/08nd7773.copc.laz'
const copc = await Copc.create(url)

console.log(proj4(copc.wkt).inverse(copc.header.min))
console.log(proj4(copc.wkt).inverse(copc.header.max))
```

### 実行
こんな感じで、うまくいきました。

```zsh
$ deno run --allow-read --allow-sys --allow-net reentry.mjs 
[ 138.38170965503224, 34.977754143479515, 18.09 ]
[ 138.3860944932108, 34.980462747653114, 52.18 ]
```
NewRelicのDocker AgentでLaravelのAPM監視まで導入

# 前提条件

- NewRelicのアカウント取得済み
- Laravel(6.x)の環境構築済み

## docker-compose.ymlの設定

```yml
version: "3"
services:
  app:
    build:
      context: ./
      args:
        - NEW_RELIC_AGENT_VERSION=10.3.0.315
        - NEW_RELIC_LICENSE_KEY=${NRIA_LICENSE_KEY}
        - NEW_RELIC_APPNAME="${APP_NAME}"
    depends_on:
      - newrelic-php-daemon
    volumes:
      - ./:/var/www/html
  new-relic-agent:
    image: newrelic/infrastructure:latest
    hostname: newrelic-infra-${APP_NAME}
    network_mode: host
    cap_add:
      - SYS_PTRACE
    privileged: true
    pid: host
    volumes:
      - /:/host:ro
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - NRIA_LICENSE_KEY=${NRIA_LICENSE_KEY}
  newrelic-php-daemon:
    image: newrelic/php-daemon:10.3.0
```

## Dockerfileの設定

```dockerfile
FROM php:7.4-fpm

ARG NEW_RELIC_AGENT_VERSION
ARG NEW_RELIC_LICENSE_KEY
ARG NEW_RELIC_APPNAME

RUN curl -L https://download.newrelic.com/php_agent/archive/${NEW_RELIC_AGENT_VERSION}/newrelic-php5-${NEW_RELIC_AGENT_VERSION}-linux.tar.gz | tar -C /tmp -zx \
    && export NR_INSTALL_USE_CP_NOT_LN=1 \
    && export NR_INSTALL_SILENT=1 \
    && /tmp/newrelic-php5-${NEW_RELIC_AGENT_VERSION}-linux/newrelic-install install \
    && rm -rf /tmp/newrelic-php5-* /tmp/nrinstall*

RUN sed -i -e "s/REPLACE_WITH_REAL_KEY/${NEW_RELIC_LICENSE_KEY}/" \
    -e "s/newrelic.appname[[:space:]]=[[:space:]].*/newrelic.appname=\"${NEW_RELIC_APPNAME}\"/" \
    -e '$anewrelic.daemon.address="newrelic-php-daemon:31339"' \
    $(php -r "echo(PHP_CONFIG_FILE_SCAN_DIR);")/newrelic.ini

#略
```

## 立ち上げ

.envに環境変数を適宜入れた後

```sh
$ docker-compose up
```

以下イメージ

![スクリーンショット 2022-12-01 22.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133718/169d5ac8-e303-ae39-e68b-51c5a319fce5.png)

## 注意点

**ログフォワーダーは、コンテナ化されたエージェントには含まれていません。すべての機能を提供する基盤となるホストにエージェントをインストールすることをお勧めします。**

ログはDockerAgentだと取得できないらしい😇

## 参考

- https://docs.newrelic.com/jp/docs/infrastructure/install-infrastructure-agent/linux-installation/docker-container-infrastructure-monitoring/
Java　基本の基本３

# はじめに
自身でprogataやスクールでJavaを勉強中。学んだことをアウトプットして、より定着させるために記事にまとめていきます。継続は力なり！

# 演算子
四則演算や値の比較などの演算を行うための記号。

### 算術演算子
```java
int num1 = 20;
int num2 = 5;

num1 + num2 //加算
//演算結果　25

num1 - num2 //減算
//演算結果　15

num1 * num2 //積算
//演算結果　100

num1 / num2 //除算
//演算結果　4

num1 % num2 //余剰
//演算結果　0
```

### 文字列結合演算子
```java
String firstName = "Toro";
String lastnName = "Yamada ";

String fullName = lastName + firstName;
//演算結果　"Yamada Toro"
```
### 代入演算子
```java
int num1 = 10;
int num2 = 5;

num1 = num1 + num2 //10 + 5をして、num1に代入する。つまり15
//右側を省略して書く。
num1 += num2; // 15
num1 -= num2; // 10
num1 *= num2; // 50
num1 /= num2; // 10
```

### インクリメント演算子、デクリメント演算子
```java
int num1 = 10;
int num2 = 5;

num1++; //11　インクリメント→１を加算
num2--; //4　　デクリメント→１を減算
num1 = ++num2; //num1=5, num2=5  インクリメントをしてから代入
num1 = num2++; //num1=5, num2=6  代入してからインクリメント
```
CpawCTF Writeup Level 2 Q28.[Network] Can you login？ (注意<spoiler>)

# Q28.[Network] Can you login？
```

古くから存在するネットワークプロトコルを使った通信では、セキュリティを意識していなかったこともあり、様々な情報が暗号化されていないことが多い。そのため、パケットキャプチャをすることでその情報が簡単に見られてしまう可能性がある。
次のパケットを読んで、FLAGを探せ！
network100.pcap
（2021/04/11: 問題ファイルを更新しました。）
```

wiresharkを使用してpcapファイルを見ると118.27.110.77宛てにftp通信していることがわかる。
他に知れる情報
user cpaw_user
PASS 5f4dcc3b5aa765d61d8327deb882cf99

ftpでアクセスする。隠しファイルがあったのでgetでローカルに持ってくる。

```
$ ftp 118.27.110.77
Connected to 118.27.110.77.
220 Welcome to Cpaw CTF FTP service.
Name (118.27.110.77:rudy_candy): cpaw_user
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> pwd
257 "/" is the current directory
ftp> ls
227 Entering Passive Mode (118,27,110,77,234,103).
150 Here comes the directory listing.
-rw-r--r--    1 ftp      ftp            36 Sep 01  2017 dummy
226 Directory send OK.
ftp> ls -la
227 Entering Passive Mode (118,27,110,77,234,123).
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp            42 Mar 17  2021 .
drwxr-xr-x    2 ftp      ftp            42 Mar 17  2021 ..
-rw-r--r--    1 ftp      ftp            39 Sep 01  2017 .hidden_flag_file
-rw-r--r--    1 ftp      ftp            36 Sep 01  2017 dummy
226 Directory send OK.
ftp> get .hidden_flag_file
local: .hidden_flag_file remote: .hidden_flag_file
227 Entering Passive Mode (118,27,110,77,234,109).
150 Opening BINARY mode data connection for .hidden_flag_file (39 bytes).
226 Transfer complete.
39 bytes received in 0.00 secs (97.9073 kB/s)
ftp>
```

```:.hidden_flag_file
cpaw{f4p_sh0u1d_b3_us3d_in_3ncryp4i0n}
```

cpaw{f4p_sh0u1d_b3_us3d_in_3ncryp4i0n}