OmniAICreator/Qiita-1.07M huggingface dataset:
AnafiをROSで動かしたい 1

# AnafiをROSで動かすために環境構築
parrot社のドローン anafiをROSで動かせるようにしたくて奮闘中です．まだまだ開発段階ですが，少しずつまとめていきたいと思っています．わからないことが多いので，間違っていたり足りないところがあれば指摘してください．

## 参考にしているもの
GitHubでanafiのパッケージをROSとbridgeしているものがありました．
https://github.com/andriyukr/olympe_bridge
こちらを元に開発していきたいと思っています．

## Parrot Ground SDKのダウンロード
https://developer.parrot.com/
このサイトにあるparrot droneのsdkを以下のコマンドでインストールしていきます．

    mkdir -p ~/code/parrot-groundsdk
    cd ~/code/parrot-groundsdk
    sudo snap install git-repo
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    repo init -u https://github.com/Parrot-Developers/groundsdk-manifest.git
    repo sync
    ./products/olympe/linux/env/postinst
    ./build.sh -p olympe-linux -A all final -j

この時にいくつかエラーが出ると思われます．実際に自分が確認したエラーや参考にしたサイトに載っているエラーへの対処を以下にまとめていきます．

Issue:

    pkg_resources.DistributionNotFound: The 'osrf-pycommon>0.1.1' distribution was not found and is required by catkin-tools

Solution: python3-catkin-toolsのインストール
 
    sudo apt install python3-catkin-lint python3-pip
    pip3 install osrf-pycommon

---
Issue:

    File "/home/andriy/code/parrot-groundsdk/.repo/repo/main.py", line 79
    file=sys.stderr)
      ^
    SyntaxError: invalid syntax
または以下のエラーも

    /snap/git-repo/18/usr/bin/python: can’t open file `/home/das-note-11/.repo/repo/main.py`: 
    [errno13] Permission denied


Solution: Use Google Repo binary
    
    mkdir -p ~/.bin
    PATH="${HOME}/.bin:${PATH}"
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
    chmod a+rx ~/.bin/repo
---
Issue:
    
    /usr/bin/env: ‘python’: No such file or directory
Solution: Set python3 as default

    echo 'alias python=python3' >> ~/.bash_aliases
    source ~/.bash_aliases
Create a symbolic link to python3

    sudo ln -s /usr/bin/python3 /usr/bin/python
---
## インストール完了したかの確認コマンド
以下を入力してインストール完了したか確認してください．

    source ~/code/parrot-groundsdk/./products/olympe/linux/env/shell
    python -c 'import olympe; print("Installation OK")'

Issue:

    ModuleNotFoundError: No module named 'olympe.messages'

Solution: Downgraded aenum

    pip install --upgrade aenum==2.2.5
---
Issue:

    ModuleNotFoundError: No module named 'ulog'

Solution:

    AttributeError: 'module' object has no attribute 'abc'


## 最後に
長くなるので，ここではparrot sdkのインストールについてまとめました．
次回からはROSのanafi_bridgeをインストールしていきます．

## 参考
    
https://github.com/andriyukr/olympe_bridge
https://developer.parrot.com/
base64エンコードされたデータをFileオブジェクトに変換する方法

## 結論

base64エンコードされたデータの**データ URL**を作成し、`fetch`を使用する。

```javascript
fetch('data:image/jpeg;base64,' + 'BQCgFS+uHO/W...')
  .then(response => response.blob())
  .then(blob => new File([blob], 'image.jpeg'))
  .then(file => {
    //fileはFileオブジェクト
  })
```
1. base64エンコードされたデータの**データ URL**を`fetch()`
1. Response オブジェクトから Blob オブジェクトを取得
1. Blob オブジェクトから File オブジェクトを作成


## 補足

データ URL は
* 接頭辞 (data:)
* データの種類を示す MIME タイプ
* テキストではないデータである場合のオプションである base64 トークン
* データ自体 (base64エンコードされたデータ or テキスト）

の4 つの部品で構成される。

```
data:[<MINEtype>][;base64],<data>
```

MIME タイプは、 例えば `'image/jpeg'` で JPEG 画像を表す。

詳細は[MIME タイプ (IANA メディアタイプ) - HTTP - MDN Web Docs](/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types)を参照。

## 参考
[データ URL - HTTP - MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)
【Flutter】XcodeをアップデートしたらiOSシュミレーターでビルド失敗（domain=NSMachErrorDomain, code=-308）

# はじめに
タイトル通りですが、XcodeをアップデートしたくてmacOSも同時にMontereyにアップデートさせました。

するとアプデ前まで正常にシュミレーターでビルドできていたのに、👇のようなエラーで失敗するようになりました。。。。

```console
Unable to install /Users/userName/flutter/insta/build/ios/iphonesimulator/Runner.app on DE709473-59D9-47A3-AE88-A4F9A756EE21. This is sometimes caused by a malformed plist file:
ProcessException: Process exited abnormally:
An error was encountered processing the command (domain=NSMachErrorDomain, code=-308):
The operation couldn’t be completed. (Mach error -308 - (ipc/mig) server died)
  Command: xcrun simctl install DE709473-59D9-47A3-AE88-A4F9A756EE21 /Users/userName/flutter/insta/build/ios/iphonesimulator/Runner.app
Error launching application on iPhone SE (3rd generation).
```

# とりあえず`flutter doctor`

```console
 flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.0, on macOS 12.3.1 21E258 darwin-x64, locale
    ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.66.2)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

• No issues found!
```

何も問題はなさそう・・・:frowning2:

# エラーメッセージに書いてあるコマンドを試してみる

```console
 xcrun simctl install DE709473-59D9-47A3-AE88-A4F9A756EE21
Install an app on a device.
Usage: simctl install <device> <path>
```

何も変わりませんでした・・・:expressionless:

>simctlとは
Xcodeに含まれる標準CLIツールで、主にシミュレータの管理を行うための機能を備えています。
https://qiita.com/tamaki/items/02eb43253193b950b08f

# よくわからんが`flutter pub get`で解決？
`flutter pub get`した後、なぜかiOSシュミレーターでビルド成功するようになりました！:sweat_smile:

`ios/Runner.xcodeproj`からXcodeで開いてビルドしてみると、 **「firestoreが見つからない！」** と言われていた・・・。なんでやろう・・。
![スクリーンショット 2022-04-21 23.41.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/dfdf55ba-7fd2-ccf3-5de1-ad39b71215a6.png)
なのでとりあえず`flutter pub get`してみました。


「domain=NSMachErrorDomain, code=-308」とかで検索しても全然ヒントが出てこなかったので、わかる人いたらコメントお願いします〜！！！
Rubyの配列の要素を変更するメソッド

# 配列の要素を変更するメソッド
配列の要素を変更するメソッド3つ紹介する
```
[]=
fill
replace
```

## `[]=`メソッド
指定したインデックスの値を書き換える。インデックスが配列の範囲を越える時には、配列の長さが自動的に伸長され、伸長された領域は nil で初期化される。
インデックスに Range オブジェクトを指定すると、その範囲にある要素を置換する。
また `[start, length] =` と指定すると、インデックス start から length 個の要素を書き換える。

```ruby
ary = [1, 2, 3, 4, 5]
ary[0] = "a"
p ary # => ["a", 2, 3, 4, 5]

ary[9] = 10
p ary # => ["a", 2, 3, 4, 5, nil, nil, nil, nil, 10]

ary[1..3] = ["b", "c", "d"]
p ary # => ["a", "b", "c", "d", 5, nil, nil, nil, nil, 10]

ary[5, 4] = [6, 7, 8, 9]
p ary # => ["a", "b", "c", "d", 5, 6, 7, 8, 9, 10]
```

## `fill`メソッド
配列のすべての要素をしていしたオブジェクトに置き換える。
引数を2つ以上与えた場合、始点と終点やRangeオブジェクトを与えることで、該当する部分のみ変更される。
引数の代わりにブロックを指定すると、ブロックの評価結果で要素を変更する。

```ruby
ary = [1, 2, 3, 4, 5]
ary.fill("a")
p ary # => ["a", "a", "a", "a", "a"]

ary[0].upcase!
p a # => ["A", "A", "A", "A", "A"]

ary.fill("b", 2..4)
p ary # => ["A", "A", "b", "b", "b"]

ary.fill { |index| index * 2 }
p ary # => [0, 2, 4, 6, 8]
```

## `replace`メソッド
引数で指定された配列で自身を置き換える。
`=` の再代入とは異なり、object_id は変化しない。

```ruby
ary = [1, 2, 3]
p ary.object_id # => 260

ary = [4, 5, 6]
p ary.object_id # => 280

ary.replace([7, 8, 9])
p ary # => [7, 8, 9]
p ary.object_id # => 280 
```
Logic AppsでAzure Blob Storage内のデータを定期的に自動で削除する

こんにちわ、[のりじ](https://twitter.com/nori790822) です。
バックアップデータなどをAzure Blob Storageに保存する場合、「どの期間で保存データを削除するか」も考えておかないと後々大変だな…という経験をしたので備忘録。

Azure Blob Storageには「ライフサイクル管理」という機能があるので、それを利用する方法がありますが「Storage（汎用 v1）」は機能が提供されていません…。

- [データ ライフサイクルを自動管理してコストを最適化する](https://docs.microsoft.com/ja-jp/azure/storage/blobs/lifecycle-management-overview)

というわけで、「Storage（汎用 v1）」でも定期的にデータの削除を自動で行ってくれるLogic Appsを使った方法を試してみました。

# 1. Logic Appsのワークフローを作る

![202204-000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/616b6652-d9e2-bce6-e94a-8928efaaebd6.jpeg)

全体図はこんな感じ。非常にシンプルです。

## 2. トリガー：繰り返し

トリガーには「スケジュール」コネクタの「繰り返し」を利用します。
検索窓に「スケジュール」と入力すると出てきます。

![202204-001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/c653c179-f5cd-f156-88c5-111d01c6212f.jpeg)

今回は1週間に1回ワークフローが動くようにします。（この期間はお好みで）
図のように「Add new parameter」も表示して設定してください。
タイムゾーンを設定していないと夏時間の影響を受ける可能性があるそうなので忘れずに。

- [夏時間と標準時間での繰り返し](https://docs.microsoft.com/ja-jp/azure/logic-apps/concepts-schedule-automated-recurring-tasks-workflows#recurrence-for-daylight-saving-time-and-standard-time)

### 2-1. アクション：BLOB を一覧表示する (V2)

検索窓に「Blob」と入力すると「Azure Blob Storage」が一覧に出てくるのでクリックし、一覧の中から「BLOB を一覧表示する (V2)」をクリック。

![202204-002-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/950b546f-0029-bb59-036d-de4adfe2e221.jpeg)

初めてコネクタを利用するときはBlob Storageへの接続が必要になります。入力する情報は「ストレージアカウント」の「アクセスキー」ページに表示される内容です。（「接続名」はわかりやすい名前にしておく）

![202204-002-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/7c6f9292-123f-9b4b-7d41-42af385da4f9.jpeg)

接続できると、赤枠内はプルダウンメニューで表示されるものを選ぶだけになります。定期的にデータを削除したいコンテナー名を選びます。（今回はbackup）

### 2-2. アクション：アレイのフィルター処理

検索窓に「データ操作」と入力し、一覧の中から「アレイのフィルター処理」をクリックします。

![202204-003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/1a999df7-25f6-5efa-da09-727fa6b569af.jpeg)

以下の内容を設定します。

1. 動的なコネクタの中から「value」を選択
2. 動的なコネクタの中から「LastModified(ファイルまたはフォルダーが最後に変更された日時)」を選択
3. 「次の値未満」を選択
4. 「式」に以下を入力
```
addDays(utcNow(), -60)
```
今回はトリガーが起動した日より「60日（2ヶ月）より前のものを削除する」形にしました。日数は必要に合わせて変更してください。

### 2-3. アクション：For each

検索窓に「制御」と入力してクリック、一覧の中から「For each」をクリックします。

![202204-004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/6aef24cb-b6eb-e6bd-f123-37133e15a396.jpeg)

「以前の手順から出力を選択」には「アレイのフィルター処理」の動的なコンテンツ「本文」を選択します。
For each内の「アクションを追加」をクリック。

### 2-4.  アクション：BLOB を削除する (V2)

検索窓に「Blob」と入力すると「Azure Blob Storage」が一覧に出てくるのでクリックし、一覧の中から「BLOB を削除する (V2)」をクリック。

![202204-005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/13362613-abd9-06e6-963f-d56f7e09bbf3.jpeg)

「ストレージ名」はプルダウンメニューから該当のものを選択します。
「BLOB」には、動的なコネクタの「Path（ファイルまたはフォルダーのパス）」を選択。

以上でワークフローは完成です。

# 3. 最後に

私の場合、個人ブログのバックアップデータをAzure Blob Storageに自動で保存していってるのですが「Storage（汎用 v1）」を利用していたためライフサイクル管理が使えず困った、という話でした。
ライフサイクル管理が利用できないAzure Blob Storageの定期的なデータ削除にぜひご活用ください！
【地方在住】未経験からエンジニア転職を目指す【自分に喝を】

初めまして。地方在住で未経験からIT転職を目論むものです。
いままでダラダラと学習をしてきてしまったので、自分に喝を入れるためにも自分の活動を記録に残しながらやっていこうと思います。

# 自己紹介
年齢：28歳
居住地：地方都市
家族構成：妻子持ち
学歴：某国際的な大学卒　在学中に1年ほど交換留学でデンマークへ
現職：某教育系企業でスクールマネージャー

# なぜIT転職をしたいのか？
ものづくりが好きで、、IT業界プログラミングに興味があって、、などもありますが、
IT転職を目指す中でプログラミングに興味があるというのは大前提かと思いますので、
自分の中で軸となりうる以下の2点に絞りました。

##### 　①今後の人生設計のために働き方を変えたい
　現職は教育系のサービス業に従事しています。
　そのため平日は昼から夜中まで、土日祝休みのない働き方をしています。
　子供は今幼稚園児ですが、今の働き方だと自分の思い描く理想の家族像とは合わなくなるなという実感があります。

　なぜ？
　→自分の父は製鉄業の工場勤めで還暦を過ぎた今でも3交代で働いています。
　　当然休日はバラバラ、盆も年末年始も関係なく仕事。大晦日の昼に出勤して年が明けてから帰宅なんてことは普通でした。
　　そうなると自分の子供時代の思い出を振り返ったときに、父との記憶がほとんどないんですよね。。
　　自分が父になった今思うことは、父としてきちんと子供の思い出に残りたい、の一心です。

#### 　②自分で稼げるスキルが欲しい
　シンプルに言うといわゆる手に職が欲しい状態です。
　大学は文系学部卒、学部では国際関係を学びましたがその道のプロフェッショナルになることはなく
　交換留学の経験もあるのはありますが、かといって英語がペラペラということもなく
　今後のキャリアプランを考えたときに、今の仕事では給料をもらうための仕事はできても、自分でお金稼ぐための仕事はできないと感じました。

　あとはその他、前述のようにモノづくりがすきだったとか、プログラミングに興味があるだとか
　小さな希望を色々と組み合わせた結果
　ITエンジニアという職業が自分の人生像に合う、今後の長い人生における選択肢を最大化できる可能性があるという結論になりました。

# これからの計画
【学習計画】
言語：PHP、Javascript
フレームワーク：Laravel
その他Webアプリ開発に必要なことを全般的に
（AWSやDockerなども理解したい）

PHPとLaravelを選んだのは特に深い理由があるわけではありませんが、
比較的PHP、Laravelは幅が広そう（案件数的に）なのと、学びやすそうというイメージ（あくまでイメージです）
（Pythonは人気は高く高給取りになれそうだがPythonでの未経験者転職は現実的ではなさそう、Javaも人気が高く案件も多いが学習コストが高そう、というイメージです。あくまで）

【目指すもの】
とにかくWebアプリを作りまくる、とまず目標にします。
1つの成果物に色んな要素を詰め込むのではなく、その時その時に勉強としていることを一つないし複数テーマにしたWebアプリを作っていく
数打ちゃいいというものでもないと思いますが、自分はそのスタイルがいいのかと（これもあくまでイメージです）

Githubに草を生やすことをとにかく意識します。

# おわりに
アラサー、地方在住という時点でかなり厳しい挑戦というのは重々承知ですが。
やれることはやろうと思います。

未経験からIT転職を叶えた先人の方々、ITエンジニアとして活躍中の方々
色んな叱咤激励いただけますと幸いです。

では。
iTerm2で.bash_profileが読み込まれなかった時の対処

# この記事の背景
今まではMacにプリインストールされているターミナルを使用していたのですが、iTerm2なるものが便利とのことで試しにダウンロードしてみました。しかし……なぜか.bash_profileが読み込まれない！
.bashrcは読み込まれているようなのですが、.bash_profileで設定しているpathなどが通っておらず、しばらく原因に悩んでいました。

# この記事では触れないこと
- .bash_profile等の仕組み
- Linuxの仕組み
- iTerm2の機能紹介

# 解決編
結果から言うと、以下の2つが原因です。

1. ログインシェルがzshになっていた。
1. Preferences->Profiles->General->Command の設定が`login shell`になっていなかった。(`/bin/bash` で開いていた)

## ログインシェルの変更
まず1.を修整するには、以下のコマンドを打ち込みます。

```bash
$ chsh
```

コマンドを打つとパスワードの入力が求められるので、入力してやるとvimで設定ファイルが開きます。
ここで、`Shell :`の行が`/bin/zsh`等になっている人は`/bin/bash`に変更してください。

```
Shell: /bin/bash  # ココ！
Full Name: User Name
Office Location:
Office Phone:
Home Phone:
```

以上で設定は終わりです。また、`chsh -s /bin/bash`でログインシェルを切り替えることもできます。
なお、(ないとは思いますが)bashがインストールされていない場合も考えられるので、どうしてもbash自体が開かない人は`cat \etc\shells`でインストールされているシェルの一覧を確認してみましょう。

## iTerm2の設定変更
これは僕がiTerm2や.bash_profileの仕様を知らなかった頃に設定したもののせいで起きたことなのですが、iTerm2のPreferencesより、Profiles->Generalの中にあるCommandの設定が`Command`になっていたことに起因しています。これを`login shell`に変更しましょう。デフォルトでは`login shell`になっているはずなので、変にイジっていなければ特にこの設定変更は必要ないと思います。

# おわりに
最近のMacはログインシェルがデフォルトだとzshになっているので、これを変更すれば.bash_profileが読み込まれるよーって記事はいくつも出てくるのですが、最初に余計な設定をしていたために「なんでこれでも読み込まれないんだ……？」とずっと悩んでいました。
僕以外に余計な設定をしたために.bash_profileが読み込まれなかったなんて人がいるのかわかりませんが、念のためこの記事を書きました。役に立てばなによりです。

Q.ところで、わざわざbash使う必要なんてあるんですか？
A.さぁ……
AWS Cloud Quest 全クリしたので紹介と感想

# 結論

こんな人にはプレイをおすすめ

- 英語力は無いけど嫌いではない
- AWSの経験がほぼ無く、これから学びたい
- まずはざっくりとAWS(クラウド)の世界を知りたい
- テキストのみだと読み飛ばしたり飽きたりしちゃう
- **非エンジニアだけどAWSの知識が欲しい or 今後必要になる**

こんなに人には not おすすめ

- 英語アレルギー
- AWSをある程度知っている/使った事がある（S3, EC2などを使った事があるレベル
- AWSの各サービスを細部まで理解したい
- 自分が考える学習プランで進めたい

# 概要

本記事では、先月公開されたamazonが提供するAWS学習ツール?の **「AWS Cloud Quest」** のプレイレポートになります。
ゲーム内で取り扱うサービスの種類や、このゲームがどんな人に合っていて、どんなことを学べるのかなどを書いていきます。

**ゲームのざっくりとした紹介・始め方などは本記事では取り上げないため、下記の記事をご覧ください。**

https://www.publickey1.jp/blog/22/awsawsaws_cloud_quest.html

# 学べる要素

「AWS Cloud Quest」では、AWSの様々なサービス・概念に触れる事ができます。
下記がその一覧になります。
※やりながらのメモなので、抜け漏れご容赦ください

- S3
- EC2
    - EBS
    - AMI
- AWS Pricing Calculator
- VPC
    - VPC Peering
- RDS
- IAM
- EFS
- No SQL
    - Dynamo DB
- Auto Scaling
- High Available(可用性)
    - ELB(Elastic Load Balancer)


## ボリューム

**12セクション**あり、**1セクション30分〜長くても1時間**程度でクリアする事ができます。
ただし全編英語のため、理解できなかった箇所を別途調べたりしていると、もう少し時間がかかるでしょう。

# 良かった点

## 英語がかなりわかりやすい

筆者はTOEIC400点レベルの英語弱者ですが、たまにわからない単語を調べる程度で、読み進めることにあまり支障はありませんでした。
ただし、動画の内容を正しく理解するためには、リスニングのスキルも必要になります。
→動画の視聴は必須ではなく、興味のある人が見るものになっています。また、動画で紹介している内容はAWSの公式ドキュメントでも取り扱っているため、テキストの方が良い・リスニングが苦手な人はそちらを見ると良いでしょう。

## 現実でも多々あるシステムの課題をゲーム上の課題にしている

- 急激なアクセス増加にサーバーが耐えられない → EC2使おう！Auto Scaling使おう！
- サーバーの保守運用に工数・コストがかかりすぎている → EC2,RDSなどサーバーのメンテはAWS側でやるよ！コストも最適化するよ！

こんな形で、どこででも起き得る一般的なシステム課題を解決する形でAWSのサービスを学ぶ事ができる。
**AWSの各サービスはあくまで手段で、目的は何なのか、何を解決できるのかを明確にしてくれている**と感じました。

## 一切詰まる事がない丁寧な操作手順

本ゲームでは実際にAWSコンソールを操作しながら学んでいく事になります。
このAWSコンソール、慣れるまではどこをどう操作すれば良いのかわかりづらいと思います。
しかしこのゲームでは、どこの何を確認するか、どこをクリックするか、何をタイプするかなど、一つ一つ丁寧に記載がされているため、初学者・非エンジニアの方でも詰まる事なく進める事ができると思います。

![スクリーンショット 2022-04-09 23.57.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257762/c40df9e6-d1d9-ede8-93b7-74b72b9dcaf0.png)
スクリーンショット 2022-04-09 23.57.19.png

## ラストのDIYステップ(自分で課題をクリアする)をスキップする事ができない

本ゲームでは各セクションの最後に`DIY`と呼ばれるステップがあります。
ここではそのセクションで学んだ内容をもとに、出された課題を解決する事になります。
このステップの課題はスキップする事ができず、（SKIPボタンはあるけど未クリアで次に進めない）
**「説明だけ読んで、練習問題などはもうわかったつもりでスキップする」**
こういった学習の進め方をしてしまって最終的に理解が浅くなる、なんて人にとっては良い仕組みになっているのかなと思います。
（とはいってもどれも簡単な内容なので、スキップしたいと思う人も多いかもしれませんね）


# 悪かった・改善して欲しい点

正直あまり無いですね。
強いて言えば、動画と同じ並びで、公式ドキュメントのリンクを置いておいて欲しいぐらいでしょうか。（自分で探すのが面倒なので）
後はゲーム内リンクからのAWSコンソールの立ち上げがかなり遅いのですが、まぁ下準備で色々なインスタンスを用意したりしてるせいかなと思うので、しょうがないのかなぁと思っています。

# 全クリ後の特典?

全クリすると`AWS Certified Cloud Practitioner Official Practice Exam`のアクセスコードがもらえて、[benchprep](https://amazonwebservices.benchprep.com/)からオンライン学習ができるみたいです。
ゲームをクリアした後にもっと詳しく学びたくなった人は利用すると良いのかもしれませんね。
freezedでgetterを定義する

Flutter開発で`@freezed`を使うけど、getterを定義すると`.freezed.dart`でエラーが出る時がある。
その解消法を載せる

```
Missing concrete implementation of 'getter XXX.xxx'.
Try implementing the missing method, or make the class abstract.dart(non_abstract_class_inherits_abstract_member)
```

### 修正前

```dart
@freezed 
class Hoge with_$Hoge {
  const factory Hoge({
    @Default("") String message,
  }) = _Hoge;

  String get foo => hoge;
}
```

### 修正後

`const`を外すのと`Hoge._()`を追加し、再度build_runnerしてください

```dart
@freezed 
class Hoge with_$Hoge {
  const Hoge._();
  
  const factory Hoge({
    @Default("") String message,
  }) = _Hoge;

  String get foo => hoge;
}
```
【基本情報技術者学習】一言メモ・非機能要件

非機能要件

ざっくり言うと機能要件以外の要件でして、
その上に機能要件よりずっと項目が多いので、
逆に機能要件をしっかりと理解できればやりやすいかなと思いました。

でうので非機能要件をまとめるではなく、
機能要件をメモしておきます。

>要件定義の中で「実装する機能」に関する要件のことを機能要件といいます。例えば、「商品Aを購入したユーザーを検索する機能」のように、実際にクライアントが必要になる機能は機能要件として分類します。

https://www.brain-gate.net/content/column/system-program-functional-requirement/

>機能要件は、「ソフトウェアやシステム開発において、クライアントから求められる『機能』のこと」です。一方、非機能要件とは『機能以外』のユーザービリティ、性能、拡張性、セキュリティなどの品質的に関連するもの全般を指します

https://hnavi.co.jp/knowledge/blog/functional-requirement/
Anacondaセットアップ備忘録

# 旧環境がある場合

事前にインストール済のパッケージをtxtファイルにエクスポート
```export.cmd
conda list --export > package-list.txt
```

# Anacondaのインストール
[anaconda公式のWEBサイト](https://www.anaconda.com/)のDownloadよりインストール
* just meを選択
→user profile下層にAnacondaがインストールされる
* 基本的にすべての項目をrecommendでOK
anaconda.exeチェックもつけたまま

# Anaconda起動後
まず初期設定
```init.cmd
conda init
```

事前にリストアップしていたパッケージのインポート
```inport.cmd
conda create -n [env-name] --file package-list.txt
```

# 他コマンド
### 使用環境の情報を確認
```check_info.cmd
conda info -e
```
### 自分の環境[env-name]をアクティベート
```activate_e.cmd
activate [env-name]
```
### パッケージの一覧出力
```packagelist.cmd
conda list
```
### pipでライブラリインストール
※必ず、自分の環境[env-name]をアクティベートした後に実行
```pip_install.cmd
activate [env-name]
pip install [library-name]
```

以上
Ants(POJ No.1852)の最小値を数式で書き下す

[プログラミングコンテストチャレンジブック](https://www.amazon.co.jp/dp/4839941068)の「気楽にウォーミングアップ」でさらっと解説されてる Ants(POJ No.1852) を数式に落とすとどうなるのか試してみた。最小値の方だけ書いてみたけど、このままだとプログラミングの勉強も進まないので、最大値はその気になったら書く。
```:Ants(POJ No.1852)
長さLcmの竿の上をn匹のアリが毎秒1cmのスピードで歩いています。
アリが竿の端に到達すると竿の下に落ちていきます。
また、竿の上は狭くてすれ違えないので、二匹のアリが出会うと、
それぞれ反対を向いて戻っていきます。
各アリについて、現在の竿の左端からの距離x_iはわかりますが、
どちらの方向を向いているのかはわかりません。
すべてのアリが竿から落ちるまでにかかる
最小の時間と最大の時間をそれぞれ求めなさい。

制約
1 <= L <= 10^6
1 <= n <= 10^6
0 <= x_i <= L 
L, n, x_i はすべて整数値

原題には書いてないですが、
向き・位置が同じ蟻がいた場合を弾くため x_i はすべて相異なるとしておきます。

```

## 問題の定式化
$L$, $n$, $x_i(i=1,...,n)$は定数とし、以下の議論では固定する。
この問題で問われている最小値は(1)で表される。
$$
\begin{equation}
\min_{d=(d_1,...d_n) \in \\{Left, \\ Right\\}^n } \\ \max_{i=1,...,n} f_i(d) \tag{1} 
\end{equation}
$$

関数 $f_i$ は、$i=1,...,n$ について、$(Right,Left)$のいずれかの向き$d_i$を向く蟻 $A_i$ が、竿の端点まで到着する時刻（整数）を表す。

## 最小値を求める。
証明の方針：下界を求め、その値を実現するベクトル $d$ を構成することで、その下界が最小値であることを示す。

### STEP1： 下界を求める。
 $d$ , $i$ を任意の値にとる。$A_i$の左端までの距離 $x_i$ と、右端までの距離 $L-x_i$ のうち、短い方 $(=\min(x_i,L-x_i))$ 未満の距離を $A_i$ が歩いても、 $A_i$ が竿から落ちることない。よって以下の不等式が成立する。この式は $x_i=0$ の場合も成立する。
$$
\min(x_i,L-x_i) \leq f_i(d)
$$
この両辺に $\min_{d=(d_1,...d_n) \in \\{Left, \\ Right\\}^n }\max_{i=1,...,n}$ を施しても不等号の向きは変わらないことと、左辺は $d$ の選択に依存しないことから式(1)の下界を得る。
$$
\max_{i=1,...,n} \min(x_i,L-x_i) \leq \min_{d=(d_1,...d_n) \in \\{Left, \\ Right\\}^n }\max_{i=1,...,n} f_i(d) \tag{2}
$$

次に、この式の左辺が最小値であることを示す。

$$
\newcommand{\argmax}{\mathop{\rm arg~max}\limits}
\newcommand{\argmin}{\mathop{\rm arg~min}\limits}
$$

### STEP2： 下界を実現する蟻の向きを構成する。
まず
```math
LR_{min}(x) := \left\{
\begin{array}{ll}
Left & \big( x \leq \frac{L}{2}\big) \\
Right & \big( x > \frac{L}{2}\big)
\end{array}
\right.
```
$$
d_{min}:=(LR_{min}(x_i))_{i=0,...,n}
$$
と定義する。この値を蟻の向きのベクトル $d$ に選択する。このとき
 $x_i \leq \frac{L}{2}$ を満たす $i$ の集合 $\it{I_L}$ について、蟻の速度は一定であることから以下が成り立つ。

$$
f_i(d_{min})=x_i=\min (x_i ,L-x_i) \ \  ( \ \forall i \in \it{I_L}  \ ) 
$$

同様に $x_i > \frac{L}{2}$ を満たす $i$ の集合 $\it{I_R}$ について以下が成り立つ。

$$
f_i(d_{min})=L-x_i=\min (x_i ,L-x_i) \ \  ( \ \forall i \in \it{I_R}  \ ) 
$$

が成立する。以上から

$$
f_i(d_{min})=\min (x_i ,L-x_i) \ \  ( \ i=\{1,...,n\}  \ ) 
$$

が成り立つ。よって

$$
\max_{i=1,...,n} f_i(d_{min}) = \max_{i=1,...,n} \min(x_i,L-x_i)
$$

この式はベクトル $d=d_{min}$ の選択が、(2)の左辺の下界の値を実現することを意味する。

以上から(2)の下界が最小値であることが示された。
iOS safariで「問題が繰り返し起きました」と出てページが表示できない場合の対応方法

## 事象
コンテンツが多い一覧ページをスマホのブラウザで開くと、

__https//hogehoge.comで問題が繰り返し起きました。__
__問題が起きたため、このWebページを再度読み込みました__

といった現象に遭遇した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/df3857fe-163a-ad6f-7144-98ebcaaaa24d.png)

【環境】
検証端末：iphone XS、iphone12Pro
iOS：15.4.1
Safari：15.4
Chrome：100.0.4896.85

## 詳細
調査の過程で以下のようなことがわかりました。
・PCブラウザでは発生しない（chrome、Safari、firefox）
・iOSのSafariだけでなく、iOS版のchromeでも似た現象になる
・キャッシュやcookieなどを削除しても現象は起こる
・webフォントやJSなどは使っていない
・ページ内のコンテンツ数を減らすと表示できる
・コンテンツ数を減らした状態でページにアクセスし、ページ内をスクロールすると一瞬白くなるが、少し経つと描画されるいった現象が起きる

## 原因
私が遭遇した事例の場合では、
CSSの`filter: drop-shadow()`が原因を引き起こしていました。

■該当ソース
```list.html
<div class="container">
    <div class="grid-item">コンテンツ1</div>
    <div class="grid-item">コンテンツ2</div>
    　　　　　　　<!--中略-->
    <div class="grid-item">コンテンツ60</div>
</div>
```

```style.css
.grid-item{
  filter: drop-shadow(0px 0px 5px #ccc);
}
```

## 解説
3D Transform やcss filterなどのCSSアニメーションに関するプロパティは、指定がない場合CPUのみで処理しようとするため、表示の乱れやレンダリング速度の低下、ブラウザが固まるなどの現象が起きてしまうようです。

私が体験した事例はコンテンツが多すぎることが主な原因ですが、
根本はCSSアニメーションはリペイントを繰り返すため、端末のCPUが描画処理に耐えきれずに上記のような現象を引き起こしたというのが私の見解です。


## 対策
GPU側に処理を助けて貰えるようにGPUレイヤーを作成するようにします。

### 対応方法①
`translateZ(0)`をつける。
昔からある手法で、GPUによるレンダリング処理を高速化するような場合に使われています。

```style.css
.grid-item{
  filter: drop-shadow(0px 0px 5px #ccc);
  translateZ(0);
}
```

### 対応方法②
`will-change: filter`をつける。
こちらもGPUレイヤーを作ることができます。
元々の用途はブラウザにレンダリングを予告し、これから起きる変化に備えて最適化を行わせるためのようです。

```style.css
.grid-item{
  filter: drop-shadow(0px 0px 5px #ccc);
  will-change: filter;
}
```

## 注意
上記のどちらを使う場合でも大量にリソースを消費します。
そのため不要に要素全体に当てるのではなく、必要な箇所にだけ当てるのが望ましいです。

どうしても一覧で出す理由がない場合はページネーションなどでページを分ける事も検討すべき。

## 参考記事
当問題の解決にあたり、下記を参考にさせていただきました。

■解決のヒント
[iOS SafariはCSSのfilterプロパティを使用すると重くなる](https://webty.jp/staffblog/production/post-3590/)
[iOS Safariでcss filterを掛けると表示が壊れるときの対処法](https://qiita.com/siy1121/items/d5a5f198744cf882ef02)

■仕組みを知る
[CSS アニメーションについて深く知る](https://qiita.com/yuki153/items/9aac0e5c8d7230a7bbe2)
[CSS will-changeプロパティについて知っておくべきこと](https://postd.cc/css-will-change-property/)

■検証方法
[GPUで処理されているかどうか](https://jajaaan.co.jp/web-production/frontend/css-animation-gpu/)

以上となります。
参考になれば幸いです。
GH-UDG-MCLTE2をLinuxでACMモードで使う

# 概要
表題の通り、GREEN HOUSEのLTEドングル GH-UDG-MCLTE2 をLinux上でACMモードで使う話。

# モードについて
LTEドングルは色々なメーカーが発売しているが、どの製品も複数モード対応しているようだ。但し、一般的な使い方はより簡単に使えるようなっており、PCに挿すだけで使えるようにしてあることが多い。この製品もデフォルトは「PCモード」である。
* ACM
* ECM
* RNDIS

## モード変更方法
以下のページにあるファームウェアアップデート手順書(pdf)内に、アップデートする準備段階としてモード変更できる方法が記載されている。手順に従い、ACMを選択してApplyして準備完了とする。
https://www.green-house.co.jp/iot-wireless/usb-dongle-downloads/

ちなみにACMモードからは、同ページ内の"「GH-UDG-MCLTEB_C」用のモード変換用ツール" でデフォルトのモード(PCモード)に戻れるが、その他のモードを指定すると容易に戻れない。

## ACMインターフェース
モード変更後、その他のデバイスが接続されていなければ、以下のACMインターフェースが見えるはず。
このインターフェースは、ATコマンドを受け付けてくれる。pppdやwvdialでLTE網に接続できる。
```
/dev/ttyACM0
```

L-02CとかL-03Dで。ttyは複数あったはず・・・となって他のインターフェースを認識させるには？

## その他のインターフェース
デバイスのIDを調べる。この製品は、AM Telecomが製造していることが分かる。
また、Vendor IDは 0x1ecb で、Product IDは 0x0202と判明。
```
Bus 001 Device 002: ID 1ecb:0202 AMTelecom AMTelecom Network Device
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
略
```

usbserial.ko をID指定でロードする。するとttyデバイスが追加で現れる。
この手順はUSB Serialを使うデバイスでよくやる。
```
sudo insmod /lib/modules/5.13.0-39-generic/kernel/drivers/usb/serial/usbserial.ko vendor=0x1ecb product=0x0202

Linux$ ls -al /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0  4月 21 18:24 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1  4月 21 18:24 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2  4月 21 18:24 /dev/ttyUSB2
```

# なにか更新予定
Evinceで開いたPDFの中のURLをクリックしても、ブラウザで開かない事象と対応方法のメモ（Ubuntu 21.10）

## 事象
Evinceで開いたPDFにあるURLをクリックすると、`/var/log/kern.log`に以下のようなエラーが出て、URLは開かなかった。

```
apparmor="DENIED" operation="sendmsg" profile="/usr/bin/evince//sanitized_helper" pid=1485788 comm="msedge"
```

## 解決策

`sudo vim /etc/apparmor.d/abstractions/ubuntu-browsers`
でファイルを開いて、最後に以下の行を追加する。（Edgeの対応のため）

```
  /opt/microsoft/msedge{,-beta,-dev}/microsoft-edge{,-beta,-dev} Cx -> sanitized_helper,
```

また、以下の`/etc/apparmor.d/abstractions/ubuntu-helpers`ファイルを開いて、以下を追記する。

```
  /opt/microsoft/msedge/msedge_crashpad_handler Pixr,
  /opt/microsoft/msedge{,-beta,-dev}/msedge-sandbox PUxr,
  /opt/microsoft/msedge{,-beta,-dev}/microsoft-edge Pixr,
  /opt/microsoft/msedge{,-beta,-dev}/msedge Pixr,
  /opt/microsoft/msedge{,-beta,-dev}/{,**/}lib*.so{,.*} m,
```


２つのファイルを保存したあと、以下のコマンドで反映させる。

`sudo apparmor_parser -T -W -r /etc/apparmor.d/usr.bin.evince`

## 参考
[Ubuntu bug report](https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/964510/comments/12)
[Forum thread](https://forum.vivaldi.net/topic/50759/apparmor-issue-with-evince-ubuntu-bionic/6)
［自主学習］しょぼちむさんがAWSのS3で静的Webサイトを公開する方法を紹介していたので試してみました

### AWS S3を用いたハンズオンをやってみました

※解説記事ではなく動画を参考にハンズオンしてみたよという報告です。

こんな感じのテキストサイトを公開しました。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/2b193d54-a626-cd66-3153-c822a6cca157.png)


たまたま開いたAWSの動画に、何やら見覚えのあるお顔の方がおりました。

「あ、しょぼちむさんだ！」

何でわかったかというと、
①Twitterをフォローしている
②しょぼちむさんの本を持っている
③しょぼちむさんの動画を見たことがある
④しょぼちむさんのエヴァンス本100日まとめを読んだことがある
etc...

と、一方通行でお世話になっているからです。
しょぼちむさんを詳しく知らない方にはこちらの記事と動画がオススメです。

https://syobochim.hatenablog.com/entry/2022/03/04/194646

https://www.youtube.com/watch?v=CfEcjnpLo7U

### AWS S3初ハンズオンをしました

https://www.youtube.com/watch?v=UJB7rAJd-QY

10分程度でAWSで静的Webサイトを公開できますぜ、ﾀｲｼｮｰという内容の動画です。

もしこの記事読まれている方が完全にAWSの環境構築から入ります、という場合
I AM ユーザーのセットアップを先に済ませることをお勧めします。

AWSで最初に手に入れるユーザーアカウントは権限が強いので、
実務では権限を一部譲渡したI AMユーザーを使うことがほとんどだと思いますので、慣れましょう～。

I AMユーザーの作成方法も紹介しておきます。
下記にAWSでLinuxを起動させるハンズオン動画があります。
最初の20分くらいでI AMユーザーの設定方法や設定する意味を丁寧に解説してくれています。

https://youtu.be/-hsHz7cV2MM

同じ方のブログverです。文字のほうが良い方はこちらです。
https://www.yamamanx.com/aws-init-account-mfa/

### ハンズオン

しょぼちむさんの動画の通りにやっただけですので、ここではスクリーンショットを公開する程度です。
解説するほど詳しくもありません！！

AWSでS3と検索
![バケットの作成.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/6231c35d-decb-89c1-0dfa-47e36e9b5b4b.jpeg)

おそろしいドメイン名をつけました
![onfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/36a6b4c5-43d3-7efb-4622-44ec56587c5b.png)

アクセス許可とプロパティとJSONコピペで完成！
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/e8ec95e0-5ca8-2653-1311-78d984b4cc21.png)

大体10分くらいで出来ました。
恋人の為にちょっとしたサイトを作って公開してあげたらロマンチック・・・かはご想像におまかせします。

一応動画の最後でも注意しておりますが、HTTPSに対応していないなど、このままの状態では様々な問題を抱えた状態での公開になりますので、あくまでお試しとして楽しみましょう。
より本格的なハンズオンは公式からも出ております。
https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-StaticWebsiteHosting-2020-reg-event-LP.html

最後になりますが、無料枠でハンズオンした方は削除も忘れずに行いましょう。
STM32G031で超音波距離センサーHC-SR04 ソフトウェアシリアル出力


目的
超音波距離センサーのテスト


![o_con326.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2638b2e2-09d7-be14-3b9b-919ae10f5c1b.jpeg)


![o_con327.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d6d29ad4-e603-760a-162b-0cdabf1ea087.jpeg)




STM32G031でPWMの測定を作てみた。


https://qiita.com/caa45040/items/66bae6f9c9459c0d5be5






```c++



#include <Arduino.h>


#include "SER_9600_031_1.h"


#define TRIG PA11
#define ECHO PB7

unsigned long times;
int distance;

void setup() {

  //シリアルの初期化
  pc.beginNS(9600);

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

}//setup

void loop() {

  // 超音波を発生させる
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  // 超音波を受け取る
  times = pulseIn(ECHO, HIGH,2000000);

  //times = (unsigned long)7700; //debug



  //distance = (int)(times * 0.017);
  distance = (int)((times * ((unsigned long)(17))) / 100);
  


  //データの表示
  String thisString9 = String( distance );
  pc.printNS( (char *)thisString9.c_str() );
  pc.printNS( "\r\n" );

  delay(500);
  
}//loop





```


SER_9600_031_1.hのプログラム


```c++



#ifndef TEST_H
#define TEST_H

//SER_9600_031_1.h


#define TX1      PA0  // 4pin
#define UART_DELAY 102   //  9600bps ok 031


#define DW   digitalWrite


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
};


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //ポートをhiにする初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif




````
ソフトウェア品質を高める開発者テストの15章で手が止まったので備忘録

15章の単体テストやコード網羅測定で脳氏でできなかったので調べたことをまとめる。

https://www.shoeisha.co.jp/book/detail/9784798165035

# 環境
Android Studio Bumblebee | 2021.1.1 Patch 3

# ここから
書籍はAndroidStudioで標準のJUnit4ではなくJUnit5を使わないと進められそうにない。
「JUnit5 androidstudio」で調べてみると書籍が3rd-party 製プラグインを利用していることを以下記事で発見。
どうせなら本家から導入したい。（？）

【参考】
[Android プロジェクトで JUnit5 を使う](https://qiita.com/toastkidjp/items/8753b16e0f6fbaa5b289)

### 変えたところ
15.1.2単体テストのセットアップをガン無視で以下を追記して「Sync Now」
```build.gradle(app)
android{
    testOptions {
        unitTests.all {
            useJUnitPlatform()
        }
    }
}
dependencies{
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
}
```
15.1.3の図15.9は[正誤表](https://www.shoeisha.co.jp/book/detail/9784798165035)を確認して<b>androidTest</b>の方を選択
図15.10の通りに以下を書き換え
```CalcTest.java
import static org.junit.jupiter.api.Assertions.*;
@org.junit.jupiter.api.Test
　↓
import static org.junit.Assert.assertEquals;
import org.junit.Test;
@Test
```

【参考】
[JUnit5でテストするために](https://qiita.com/Hisashi97/items/d4a69c180a4adf2d26a2)
[Gradle公式のGradle部分](https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle)
[AndroidStudio公式のリファレンス](https://developer.android.com/reference/tools/gradle-api/7.1/com/android/build/api/dsl/TestOptions)

### 結果
![Screenshot from 2022-04-21 20-58-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1626240/8c279dc9-a67f-992b-8661-d729c19268d1.png)


# まとめ
15.1単体テストはJUnit4（）
15.2コード網羅測定はこの方法でなんとかしたが結果の通りパーセント表示が0

変なとこしかないので指摘等よろしくおねがいします。
UE4のデータテーブルとGUIの依存を切る

※2022/04時点の素人の個人的な意見です。ご指摘大歓迎です。

※Blueprint Onlyの話です。

# データテーブルの依存を切る

データテーブルは変数としてスポーン時のパラメータに出来るので、そこで構造体だけの依存に切り離せます。
![img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/a64a0ec9-eddc-6692-812b-dcff50fb8885.png)

なので、自分はレベル用の管理アクター（と言っても肥大化しないように注意）を配置して、データテーブルをスポーンの変数にして、そのアクターに保持、アクターコンポーネントなどに機能とその変数を移してGetはそこを経由してもらう。管理アクターはアクターとして抽象化してGameModeなどに保持。
すると、依存はアクターコンポーネントと構造体と管理アクターだけになります。

# 追記：2023/04/02

あと、サブクラスに依存オブジェクトを参照させる方法があります。
スーパークラス >>> サブクラス -> 依存オブジェクト -> スーパークラス
のような関係であれば、スーパークラスが派生クラスを参照していないので
依存オブジェクトはスポーンパラメータにするなり、メソッドはオーバーライドするなりすればOKだと思います。
スーパークラスにオブジェクト型で保持させて、サブクラスでキャストするとか。
循環参照を検知するには、以下のようなプラグインも存在します。

https://www.unrealengine.com/marketplace/ja/product/circular-dependencies-detector

とはいえ、個人的に有料プラグインでも循環しているものも確認していますし、循環自体がどのような問題を引き起こすのか全体像は分かりかねます。


# GUIの依存を切る（画面と機能の分離）

同じ機能でデザインだけ変えたい時など、BlueprintWidgetに直接ロジックを書くと変更に弱いので分離した方がいいと思ってます。
（機能とデザインが一緒だと、それに結びついているテクスチャとかマテリアルまで移行してしまうなど）
外部からバインドなどをするオブジェクトが必要なのですが、
ObjectだとC++をいじらないと自由度上がらないので、BlueprintWidget管理用のアクターを作ります。

# 何でActorなんだYO

素人の自分の場合、現時点でBlueprint Onlyだと拡張性を考えるとアクターになりました。
トランスフォームは不要ですが、スポーンのパラメータ指定ができて、タイムラインが使えて、オブジェクト・ウィジェットが作成できる。
ActorComponent、Objectの制約とか、何であるんだろう？
設計思想がイマイチ分からないです。
どこかに載ってないかな。
PythonのTypedDictのキーの有無・値の型をチェックするツールtypeddict-validatorを作った

JSON を受け取る API などでは、多くの場合で何らかのバリデーションをしていると思うが、そのバリデーションに Python の TypedDict を使えるようにしてみました。

## 概要

https://github.com/SogoKato/typeddict-validator

TypedDict を使って辞書型のデータをバリデーションするユーティリティ。辞書が必要なキーを持っているかや、値が適切な型を持っているかを再帰的にチェックします。 API リクエストや何らかのファイルのような、 JSON や YAML をデシリアライズするシーンで便利です。

現在のところ、一般的な型および Optional を含む Union 型をサポートしています。

## 要件

* Python 3.10 以降

## インストール

PyPI からインストールできます。
https://pypi.org/project/typeddict-validator/

```
pip install typeddict-validator
```

## つかいかた

`validate_typeddict` が本体です。辞書型のデータと TypedDict の型 (T) を渡します。返り値は TypeGuard[T] なので、辞書が入力された TypedDict の型のオブジェクトであることが保証されます。

```python
>>> from typing import TypedDict
>>> from typeddict_validator import validate_typeddict
>>>
>>> PersonDict = TypedDict("PersonDict", {"name": str, "age": int, "interests": list[str]})
>>>
>>> person = {"name": "Taro Yamada", "age": 30, "interests": ["programming", "painting"]}
>>>
>>> if validate_typeddict(person, PersonDict):
...     print("It's a PersonDict!")
```

```
It's a PersonDict!
```

デフォルトでは、一致しない場合にエラーを投げます。

```python
>>> robot = {"name": "Doraemon"}
>>>
>>> if validate_typeddict(robot, PersonDict):
...     print("It's a PersonDict!")
```

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/app/typeddict_validator/validate.py", line 37, in validate_typeddict
    raise DictMissingKeyException(key=k)
typeddict_validator.validate.DictMissingKeyException
```

`silent=True` オプションを使って黙らせることもできます。この場合、エラーではなく False を返します（ただし 第2引数が TypedDict でない時は ValueError を返す）。

```python
>>> if not validate_typeddict(robot, PersonDict, silent=True):
...     print("It's not a PersonDict!!")
```

```
It's not a PersonDict!!
```

ほかのサンプルを見るには [validate/validate_test.py](https://github.com/SogoKato/typeddict-validator/blob/main/validate/validate_test.py) をご参照ください。

## さいごに

基本的な用途においては十分かと思いますが、まだまだサポートできていない機能やエンハンスの余地は多いと思います。気になった方はぜひ使ってみて、不便なところがありましたら Pull Request などをしていただけますと大変喜びます。

それではよい Python ライフを～。
新人プログラマにやってほしいこと

## はじめに
新人プログラマ応援 - みんなで新人を育てよう！」イベントの投稿記事です。

https://qiita.com/official-events/3f21c92121aa125807b4

エンジニア歴5年、管理職もやってましたので、
その経験から新人さんにやってほしいことをまとめてみました

# 1. マインド
### 1-1. 100%を目指さない
100%を目指さないでください
　　
できると思っている上司でも思考錯誤しているので、
**個人的な100%** を模索するよりも60%〜80%の状態で
早めにコミュニケーションをとるほうが重要です

### 1-2. かならず自己研鑽を実施する
1タスク（機能)の開発が完了したら、かならず自己研鑽する時間をとりましょう

* 自己研鑽した内容は必ず次回以降のタスクで意識して作業していく
* 意識しなくても作業できるようになるまでは目につくところに記載しておく

```:自己研鑽の仕方
　① 「できたこと」 ・ 「できなかったこと」について3個以上あげる
　② それぞれ挙げたものについて2段階以上の深掘りして、内容を精査
```

```: 深掘りの例
工数がオーバーしてしまった
　　Q1.なぜ工数がオーバーしてしまったのか
　　　　A1. 工数を意識して作業していなかったから
　　　　　　Q1-1. どうしたら工数を意識できるようになるか
　　　　　　　　A1-1. 作業工数がわかるように、作業時にアラームを設定する
```

失敗することが問題でなく、
失敗したことを繰り返してしまうことが問題なので、
自己研鑽して再発防止策の策定を実施しましょう

また、成功事例については他領域でも再利用できる可能性が高いので、
`できたこと`についても自己研鑽できるといいと思います


# 2. コミュニケーション

### 2-1. 報連相の目的を意識したコミュニケーション

> 報連相とは「報告」「連絡」「相談」の頭文字をとったもので、
仕事を円滑に進めるうえで必要不可欠なスキルです。

というのは有名な話ですが、
上司とコミュニケーションする際には、
「**報告**・**連絡**・**相談**」のどれに自分の行動が該当するか確認しましょう

また、その行動に対する目的を達成するようにしましょう

```:報連相の目的
報告: 相手に結果を伝えて承認を得ること
連絡: 相手に現状or調査結果を伝えること
相談: 相手と話合い方向性・対応方針を決定する
```

よく、`仕様を確定した報告`なのか`仕様の相談`なのかわからないコミュニケーションをうけてました

### 2-2. 質問の仕方

質問するのはいいことですが、以下2点注意しましょう

* なんでも丸投げしない
どうしても解決できない問題なら仕方ないですが、
`これどうしたらいいですか?`ではなく
`これこうしようと思っているのですがどうでしょうか？`のように1人称で質問する

* 調査過程についても共有する
`これ調べたのですが、わからなかったです`ではなく、
`こういう風に調べてみたのですがわからなかったです`のように
調査過程についても共有する
調査過程も報告することで調査の仕方や考え方についても上司からアドバイスがもらえます

### 2-3. アラートは爆速で

自分でどうにもならなくなったら、
臆せず早いタイミングで上司に相談しましょう

相談が早い場合と遅い場合で上司がとれる手段が変わってきます

```: 相談が早い場合に上司がとれる手段
　・増員
　・アサインの変更
　・リスケ
```

```: 相談が遅い場合に上司がとれる手段
　・増員
```

# 3. 開発
### 3-1. プログラム内で一貫した自分ルール

1タスク（機能）内の改修について、
一貫性があるプログラミングをしましょう

※ もちろん社内のコーディングルールは遵守ください

※ 自分ルールでいいものができたら、積極的にコーディングルールに追加していきましょう

### 3-2. 機能を因数分解

自分の知識レベルまで機能を因数分解する

```:因数分解イメージ
機能A
  → 機能a
　　   →　機能a-1
　　　    →　関数Xで実装可能 
　　   →　機能a-2の技術調査・開発 
  → 機能bの開発
```

### 3-3. 予定工数の割り振り

過去の経験を基に算出します

未経験・知識レベルが足りていない内容については、
スケジュール上の工数でおさめにいくと仮定した際の目安工数を割り振る

※あくまで作業前の目安のスケジュールとして、
変動があることを前提として割り振りしましょう

```: 工数割り振り (24h作業の場合)
機能A
  → 機能a
　　   →　機能a-1
　　　    →　関数X: 4h: 実装方法が明確なため
　　   →　機能a-2
　　　    →　機能a-2の実装方法に関する調査・実装: 12h = 24h - 8h - 4h
  → 機能b: 8h: 過去の類似の開発工数から算出
```

### 3-4. 知識レベルが足りていない内容から実施していく

知識レベルが足りていないな内容について、
工数が大きくかかる可能性があり、
あとまわしにしているとリカバリーがきかない状況になる可能性が高いです

残作業時間を明確化されていると、
「余力あるから、この技術深掘りしよう」とか、
「ちょっと遅れ気味なので、ここはよく理解できていないけどとりあえず」など、
自身の知識習得についても考えながら作業を実施できます

工数が不明確・知識レベルが足りていないな内容から順に対応していきましょう

### 3-5. 全体進捗を意識する

新人のうちは割り振った工数から遅れることが多いと思いますが、
その遅れについて他改修箇所で吸収できそうか確認しながら進めていきましょう

どうにもならない場合は、上司にアラートを爆速であげましょう

# さいごに

よきエンジニアライフを
Ruby on Rails 投稿フォームでの改行を反映

この記事は学習中に実装した内容をアウトプットし、更に理解を深めるための記録用投稿になります。
投稿している内容と同じ箇所で躓いている方に少しでもお力添えできれば幸いです。

---
## 解決したい内容
入力フォームで入力した内容を表示させるときに改行が反映されずに空白が入り表示されるのを解決し、入力した時のレイアウトのまま表示したい。

### 実装前
---
![スクリーンショット 2022-04-21 19.45.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608572/31a7846c-4c82-d5a2-d8a0-c4fe0a6b8e3c.png)
---

### 実装後
----
![スクリーンショット 2022-04-21 19.44.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608572/3689604c-c010-1127-7065-479162063a3f.png)

---


## 前提
・紹介文はdishesテーブルのintroductionカラム。
・form_withは記述済み


## 解決方法
エスケープしてから改行コードを変換

1,まずh関数で特殊文字をエスケープ
2,その後改行コードをbrタグに置換
3,その結果をhtml_safeやrawで表示させる

 ＊変更前
```erb
<%= @dish.introduction %>
```
＊変更後
```erb
<%= h(@dish.introduction).gsub(/\n|\r|\r\n/, "<br>").html_safe %>
```
---
今回、実装した際に「エスケープ」や「gsub」「html_self」などの初めて知った用語や記述方法を知りました。
難しそうですがさらに調べて理解を深めていこうと思います！
WEB+DB PRESS Vol.127 特集 作って学ぶPhoenix 第1章 を読んでみた

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回は2月24日に発売された[「Elixirによる高速なWeb開発！　作って学ぶPhoenix」](https://gihyo.jp/magazine/wdpress/archive/2022/vol127)を読んで、プログラミング歴3ヶ月、Elixirひよっこの私が学んだことをまとめます。

# 内容まとめ
## Elixirとは？
今年でバージョン1.0のリリースから10周年になる、関数型プログラミング言語[^1]です。
Erlang VMという仮想化環境下で動くプログラミング言語ですが、母体のErlangにはない非常に便利なライブラリがたくさんあります。
その一つが今回特集になったPhoenixというフレームワークです。

# 再現してみた（第1章）

## 実行環境
<dl>
  <dd>・Windows 11 Home(バージョン 21H2, OS ビルド 22000.613)</dd>
  <dd>・Ubuntu v18.04 ※WSL2環境下</dd>
  <dd>・Elixir v1.13.0 (compiled with Erlang/OTP 24) ※WSL2環境下</dd>
  <dd>・Phoenix v1.6.7 ※WSL2環境下</dd>
  <dd>・psql (PostgreSQL) 10.19 ※WSL2環境下</dd>
</dl>

本紙では生のElixirをローカルにダウンロードする方法や、Dockerを使用した方法で進めていますが、私は今回はWSL2環境下で「作って学ぶPhoenix」のRealworldを再現してみたいと思います。
WindowsのCLIはUNIX系と違って使いづらいのです...


### 事前準備

https://qiita.com/piacerex/items/6b64dfe70f48c89d8385

こちらの記事を参考に、PhoenixとPostgreSQLを準備。

## iexで遊ぶ
```
iex()> IO.puts("Hello, World!")
Hello, World!
:ok
iex()> "Hello, World" |> IO.puts()
Hello, World
:ok
```
iexもpsqlと同じ対話型コンソール。逐一「:ok」と言ってくれる姿が可愛らしい。



## 多彩なMixコマンド
今の私のお気に入りはmix testとmix test.watch
[ちなみに、mix testにもオプションがあるそうで](https://zenn.dev/koga1020/articles/85748f48a9758566d232)。
```
mix test --failed
```
「直近でエラーになったものだけ」のオプション、使いやすくていい感じです！


mix test.watchはソースコードが編集されるたびにmix testをかけてくれる優れものです。

Mixコマンド実行時の注意点はmix.exsのファイルがカレントディレクトリでないと動きません。



## パターンマッチ[^8]

```Elixir:hoge_test.exs
test "pattern match" do
    x = 1
    2 = x
    |> IO.inspect()
  end

#実行結果
# 1) test pattern match (HogeTest)
#     test/hoge_test.exs:10
#     ** (MatchError) no match of right hand side value: 1
# 2 = x の「2」が右辺におけるx, つまりその行より前で定義されたx =「1」という値と異なります。というエラー。
```

これがどのようなことに役に立つかというと、

「ユーザーのログイン情報のIDと、投稿された記事に紐づけられた著者のIDとがマッチすれば記事の変更や削除が可能なページに遷移することができる」とか、

「入力されたパスワードとパスワードに大文字が入っていないことという条件式がマッチすれば、『パスワードには大文字を１文字以上入れてください』と表示させる」とかいうことができる」とか、

割となんにでも使えるような気がします。


※パターンマッチは別記事化予定。関数パターンマッチを理解するための型や基本的な関数を理解してからまた書きます。






# 本紙の購入はこちらから

https://gihyo.jp/magazine/wdpress/archive/2022/vol127

# 終わりに・感想

次回は第2章で学んだことをまとめたいと思います。

本記事の著者の皆様、技術評論社の皆様のご尽力に感謝いたします。頑張って再現します。




# ～Elixirの国のご案内～
※Elixirって何ぞや？と思ったらこちらもどぞ。未来がぎゅっと詰まった、Elixirは今年で生まれて10周年です:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/7bf8f9f4f5f576e597f5



[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^9]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。


まずは気軽に話しかけてみてください。


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian


[^1]: 関数型プログラミング言語は近寄りがたいイメージがあるらしいですが、私は他言語と比較できないのでその感覚は分かりません。でも、未経験文系の私がマスターできるなら難しくはないはずです、たぶん。
[^8]:追加記事1本分どころじゃない沼が見える...
[^9]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。
【PHPUnit】テストデータ作成時はFakerを積極的に使おう

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## テストデータを作成するとき
テストケースではパラメーターに入れる値などを直接入れないほうがいいらしい。
値を固定してしまうと本当の意味で正確なテストではなくなってしまう。

## Bad

```php
$this->users = User::factory(2)->create();
$params = [
      'user_id' => $this->users[0]->id,
      'message' => 'メッセージです',
      'points' => 10,
];
```
## Good
Fakerなどを使うとテストが実行されるごとにランダムな値でテストしてくれる。

```php
$this->users = User::factory(2)->create();
$params = [
      'user_id' => $this->users[0]->id,
      'message' => Str::random(10),
      'points' => Faker\Factory::create()->randomDigit,
];
```
メールドメインもある。とにかくなんでもある。

```
$this->faker->unique()->safeEmailDomain()
```

https://github.com/fzaninotto/Faker

## 

Railsをメインでやっていたとき、RSpecではFakerを使ったことがなかったので存在を知らなかったけどめっちゃ便利…！

https://github.com/faker-ruby/faker
超初心者向け　HTMLで要素を横並びにしたい!!　時

# 目次
[1.要素の横並び](#-要素の横並び)
[2.横の並び方を調整](##-横の並び方を調整)
# 要素の横並び

今まで、ブロック要素やインライン要素も理解できない、親要素子要素も分からない状態で場当たり的に「要素　横並び」とかで調べた内容で```float:left;```とかを上手く動くまで適当に試してめちゃめちゃ苦戦してました。

よく分からないけど横並びにさせたい！！って場合にとりあえず使ってみてください。笑

## 結論　flexbox めっちゃ楽。

```float:left;```使ってると変なところが横並びになってしまったり、何をどうしていいかわからない状態に僕はよく陥ってました。
なんで横に並べるだけなのにこんなに面倒臭いんだと...

_flexboxを使うと簡単シンプルに横並びができます！_

## 使い方

並べたい要素くん達が入っている親要素に、```display: flex;```とCSSで書くだけ！！

下記の例でいくと
A B C を横並びにしたい。
この場合、ABC達が入っている「field」クラスに対して```display: flex;```　を書きます!
これだけ！

```display: flex;```　を書く場所間違えちゃうと動かないのでそこだけ注意です!

```.html
  <div class="field">
    <div class="card">A</div>
    <div class="card">B</div>
    <div class="card">C</div>
  </div>
```

```.css
.field {
display: flex;
}
```


めちゃめちゃ簡単にできちゃいました。

もー少し綺麗に並べたいよって方は読み進めてみてください!


## 横の並び方を調整

横の並び方は、親要素に```justify-content```を書くことで調整できます!
親要素ってどこ?という方は、```display: flex;```を書いたところです
今回は5種類だけ紹介します!
画像で見方がわかりやすいと思うのであまり解説書きません。。

### space-around 　画面の幅に応じて中心からいい感じ広がってくれる
自分的にはこれが一番便利かなーと思っています
```justify-content: space-around;```
![around.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096105/d4193386-9b10-ef89-9fe1-de9dcac6f386.png)

### space-between  最初と最後の要素を両端に。あとは均等にいい感じ
```justify-content: space-between;```
![beteween.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096105/09006a12-aa5f-b0c5-dd24-5a1308450a30.png)

### center    間隔なしで中央に寄せる
```justify-content: center;```
![flex1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096105/79a64e81-e1c0-20ad-51af-322ba87c0434.png)

### flex-start    左寄せ

```justify-content: start;```
![start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096105/f7071a36-0d32-53c4-ff0c-3d6457601ffc.png)

### flex-end    右寄せ
右よせ、ABCの並び順はそのまま!
```justify-content: start;```
![end.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096105/4761aa5e-4e5d-d44d-f88a-60e020dbd45f.png)
UE4のフォルダ分けについて自論

※2022/04の個人的な感想です。間違いがあればご指摘歓迎です。

# これが多分ダメなBPインタフェースフォルダの例です。
![img00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/47418d35-5020-8380-2c10-9af5523623e0.png)
過去の遺物で。そもそも、こんなに増えるはずじゃなかったんですが、

プロジェクト名（ルートに配置）
┣ Blueprints
┣ Interfaces　＜ここ
┣ Maps
┣ ...

こんな感じで、メッシュとかはサブフォルダ分けしてたんですが、構造体とかが集約されてカオスな感じになってました。
なので、というかそもそも

プロジェクト名（ルートに配置）
┣ 機能1
┃┣ Blueprints
┃┣ Interfaces
┃┣ ...
┣ 機能2
┣ ...

こうやって機能ごとに分けるのがいいんじゃないかと思います。というか、皆そうしてるかも？
そして例えば機能1を移行しても他も芋づるで他の機能の部品が引きづられないのが理想。
機能（モジュール）単位で何事も考えていかないと破綻するって事なのかなと。
レベル内で全部依存させればヨシって事か。

## ルートにプロジェクト名のフォルダで置いているけど
UE4の最初のフォルダって実質、namespaceになると思います。
だったらルートはプロジェクト名じゃなくて筆者名とかチーム名にした方が被らないのでは、と思ってます。滅多なことではないと思いますが。
乗換情報をさくっと調べるLINEbot作成に挑戦してみた

私は、小売業のネット販売の運営を仕事としております。各地にある出荷拠点への出張が多い。Makeを使いLINEbotで乗換案内を尋ねると返事が返ってくるものを作成に挑戦する。

**検索を早くしたい**
ウェブサイトでの検索では、日時・現在地・行先を入力して表示されるが、移動途中で当初の想定と違う乗り継ぎが発生した場合に、検索がかかり過ぎて乗り遅れてしまう危険性があるのを改善。

**LINEbotでの作成**
〇〇駅から〇〇駅までと入力すると乗換情報がLINEbotで返ってくるものを目指す。
乗換案内サイトのURLをHTTPに1.Events[]：Messge.Textで設定。
MethodはGETで設定。JSONには乗換案内の元となるデータを入れました。
以下の画像のようにうまく動きませんでした。原因としてはJSONでエラーとなっておりますが、JSONのAPIの設定、その他のHTTPの設定もうまくいっていないかもしれません。

![メイク画像.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2624365/c915311a-d2af-c712-2081-5c3caf5cd343.jpeg)


**【筆者の後記】**

今回の内容は、乗換情報の改善になると思い取り組みましたが、MakeでのLINE-HTTP-JSON-Routerまでを動かすために必要な設定が、今回の乗換情報を返すLINEbotづくりができるほど分かっておらず。完成には至りませんでした。初心者が作れるLINEbotから始めてエラーの原因と攻略方法を理解しながらステップアップを目指します。
最後まで読んでいただきありがとうございました。
【socialite】Googleログインのモックを使ったテスト

## 環境
Laravel v9.5.1 (PHP v8.1.3)


## socialiteを使ったモック

```socialite```でGoogleログインを実装したときのテストでモックを使用。

```php
class OAuthTest extends TestCase
{
  use RefreshDatabase;

  private function createSocialiteMock()
  {
    $user->shouldReceive('getEmail')
         ->andReturn(Faker\Factory::create()->unique()->safeEmail)
         ->shouldReceive('getName')
         ->andReturn(Faker\Factory::create()->name);

    $provider = Mockery::mock('Laravel\Socialite\Contracts\Provider');
    $provider->shouldReceive('user')->andReturn($user);

    Socialite::shouldReceive('driver')->with('google')->andReturn($provider);

    return $user;
  }

  public function testCreateUser()
  {
    $googleUser = $this->createSocialiteMock();
    $googleUser->getName(); //nameを取得
    $googleUser->getEmail(); //emailを取得
    ...
  }
}
```
## プロパティのみをモックしたい
参考記事では```getEmail``` ```getName```functionもモックしていたが、
私の実装の場合はプロパティのみをモックした方がテストの都合が良かった。


プロパティをモックしたいときは```shouldReceive``` ```andReturn```を使わずにそのまま代入すればいい。

```php
$user = Mockery::mock('Laravel\Socialite\Two\User');
$user->email = uniqid().'@example.com';
$user->name = Faker\Factory::create()->name;

//test case
$googleUser = $this->createSocialiteMock();
$this->assertDatabaseHas('users', [
   'name' => $googleUser->name,
   'email' => $googleUser->email,
]);
```

## 参考
https://php-junkie.net/framework/laravel/socialite-testing/
いまさらArduino UNOで超音波距離センサーHC-SR04


x @sasakisanさんの記事を非営利、研究目的で参考にして移植しました。



目的
周期測定のテスト


![o_con326.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b212becf-bae5-2ef4-cb15-4bbf9ff1b286.jpeg)



![o_con325.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/764d40a3-046e-f514-90e2-437f72515fa6.jpeg)




ArduinoUNOとCO2センサーモジュールMH-Z19CでCO2測定



https://qiita.com/caa45040/items/fd9a2a8e71f6e73b6a47



【初心者向け電子工作】超音波センサーで距離を測ってみる



https://qiita.com/sasakisan/items/9f2aa0fd7203e0999129






```c++



#define TRIG 6
#define ECHO 7

unsigned long times;
int distance;

void setup() {

  Serial.begin(9600);

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

}//setup

void loop() {

  // 超音波を発生させる
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  // 超音波を受け取る
  times = pulseIn(ECHO, HIGH,2000000);

  //Serial.println( times );//debug

  //distance = (int)(times * 0.017);
  distance = (int)((times * ((unsigned long)(17))) / 100)     ;
  
  Serial.println( distance );

  delay(500);
  
}//loop




```


スイッチサイエンスさん


https://www.switch-science.com/catalog/1606/


```


    Duration = pulseIn(Echo,HIGH);
    if (Duration>0) {
      Distance = Duration/2;
      Distance = Distance*340*100/1000000; // ultrasonic speed is 340m/s = 34000cm/s = 0.034cm/us 
      Serial.print(Duration);


```
【React】Auth0でコールバックURLを動的に設定する方法

## 背景
Auth0では、[OAuth 2.0 Security Best Current Practice 25](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09#section-2.1)に
則るため、コールバックURLの許可設定（Allowed Callback URL）の
パスにワイルドカードを使用出来ません。
そのため、動的にリダイレクトするようなサイト
(https//example.com/users/?user_id=21など)では、そのまま利用出来ません。

[Auth0のFAQ](https://community.auth0.com/t/how-do-i-set-up-a-dynamic-allowed-callback-url/60268)では、コールバックURLからさらにリダイレクトさせることで
この問題を回避する手順が紹介されています。

今回は、Reactの環境で設定した内容を記載します。

## 概要
コールバックURLを固定し、クエリ部分に初回アクセス時のURLを保持させます。
コールバックURLへのアクセス時にクエリを確認し、その内容にリダイレクトさせます。
### 画面遷移
①未ログイン状態で、https//example.com/users/?user_id=21　にアクセスし、ログイン画面にリダイレクトされる
②ログイン後、RedirectURL(https//example.com/?pathname=users&user_id=21)に遷移する
③さらにリダイレクトされて、初回アクセス時のURL(https//example.com/users/?user_id=21)にリダイレクトされる

## 設定内容
Auth0のReactサンプルを元に変更箇所を記載します。
サンプルを元にしているため、少し古い書き方かも知れませんが、ご了承ください。

```javascript:src/index.js
const onRedirectCallback = (appState) => {

+  const location = useLocation();
+  const {pathname} = qs.parse(location.search, ops);
+  let uri;

// 保持されたURL情報を元に、リダイレクトさせる 
+  if (pathname) {
+    uri = pathname + '?'
+    delete searchParams['pathname'];
+    delete searchParams['code'];
+    delete searchParams['state'];
+    for (const key in searchParams) {
+      uri += key + '=' + searchParams[key] + '&';
+    }
+    uri = uri.slice(0, -1)
+  } else {
+    uri = window.location.pathname;
+  }

  history.push(
-    appState && appState.returnTo ? appState.returnTo : window.location.pathname
+    appState && appState.returnTo ? appState.returnTo : uri
  );
};

// クエリをつけてリダイレクトすることで、URL情報を保持させる
+  const redirectUri = window.location.origin + '?pathname=' + window.location.pathname + '&' + window.location.search.slice(1)
const providerConfig = {
  domain: config.domain,
  clientId: config.clientId,
  ...(config.audience ? { audience: config.audience } : null),
-  redirectUri: window.location.origin,
+  redirectUri: redirectUri,
  onRedirectCallback,
};
```

## 最後に
実際の環境ではもう少し処理を追記していますが、大まかな流れは以上になります。
当初Auth0のFAQを確認したときは、複雑な処理が必要になると思いましたが、思ったよりあっさりと実装出来ました。