OmniAICreator/Qiita-1.07M huggingface dataset:
Perlのハッシュ - テキスト処理プログラミング入門【Windows・Mac・Linux対応】

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

Perlのハッシュについて解説しました。

・ハッシュとは連想配列
・キーと値のペア
・ハッシュの初期化
・ハッシュの関数
・keys関数・values関数・exists関数・delete関数・each関数
・ハッシュのリファレンス
・業務でのデータベースからのデータの取り出し

Perlのハッシュ - Perlゼミ

https://perlzemi.com/blog/20161013147635.html

■Perlプログラミングちゃんねるとは

Perlプログラミングちゃんねるは、初級者向けのPerlプログラミング入門講座です。テキスト処理プログラミングを覚えると文章の中に含まれる文字を簡単に検索・置換できるようになります。対応OSは、Windows/Mac/Linuxです。

テキスト処理プログラミングは、一番簡単なプログラミングの分野のひとつです。プログラミングが初めての方でも大丈夫。

Perlのダウンロードとインストールからはじめて、Perlの基本的なプログラミングが書けるようになります。Perlゼミの無料オンラインテキストも活用できます。わからないことがあれば、Perlクラブフォーラムで、質問することができます。
Postgresqlで`/bin/launchctl bootstrap gui/501` エラーが出た

自分の覚書として書き残します。

## 環境
OS macOS 12.3.1
Ruby 3.0.1
Rails 6.1.6
Postgresql 14.5

## 経緯
```
$ rails db:create
```
を実行したところ、下記のエラーが発生。

```bash
ActiveRecord::ConnectionNotEstablished: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

「ポスグレが起動していないのだろう（瞬殺だ）」と考えて
```bash
$ brew services start postgresql@14
```
を実行したら、こんなのが出ました orz

```bash
Bootstrap failed: 5: Input/output error
Try re-running the command as root for richer errors.
Error: Failure while executing; `/bin/launchctl bootstrap gui/501 /Users/username/Library/LaunchAgents/homebrew.mxcl.postgresql@14.plist` exited with 5.
```

なぜに `bootstrap` ？

## 解決策

結局、ポスグレをいったんストップさせて、再度起動させたら解決。
```bash
$ brew services stop postgresql@14
$ brew services start postgresql@14
```

理屈はまだわかっていませんが、この記事で救われる人が一人でもいらっしゃれば幸いです。
「今日は何の日」をAIに描かせてみた

「今日は何の日API」ただいまv2が公開中です。

https://note.com/sooz/n/n0f85c8dee503

Twitterでデモ用のbotアカウントも作っていて、毎日つぶやいています。

https://twitter.com/grd09607765/status/1576072794885877761?s=46&t=f5bEZAHHxor6ZlV8fiMQ2g

新しい使い方も模索&実験中ですが、いまいちぱっとしません。Twitterで他のアカウントを見ていると、イラストや写真などと一緒に「今日は何の日」を投稿していて、とても楽しそうです。私に絵心でもあれば…。
と、ここで目に止まったのが、話題のお絵描きAI「Stable Diffusion」。

こいつに描いてもらえばいいのです。

1. 「今日は何の日API」から「○○の日」を取得
2. 「○○の日」をお題にAIが画像生成
3. Twitterに投稿

この辺を1日1回まとめて実行する方法を探してみたのですが、すぐ頓挫しました。2022年10月現在、Google Colaboratoryも含めて、無料でGPU環境をスケジュール実行するサービスはありません。
そこで方針を変えました。

1. 一年分の記念日画像をあらかじめAIに描いてもらう
2. 画像をAPIのURLに組み込んで呼び出す

これなら何とかできそうです。

## お絵描きAIに一年分の記念日画像を描かせる

さっそくStable Diffusionの使用環境を整えます。こちらの記事を参考にさせていただきました。

https://signyamo.blog/stable-diffusion/?utm_source=pocket_mylist#toc6


* Hugging Faceアカウント登録
* Hugging Faceでの利用規約同意
* Hugging Faceを利用するトークン取得

そして機械学習ライブラリdiffusersをインストールします。

```
!pip install diffusers==0.2.4 transformers scipy ftfy
```
そして閏日も含めた366日分の記念日をリストでえんえん読み込ませました。「今日は何の日API(記念日API)」で"anniv1"のレスポンスに当たる部分です。[^1]
[^1]: 記念日APIは"anniv1"〜"anniv5"まで、1日最大5つの記念日をレスポンスします。でも記念日がない場合は""空文字を返します。ただし、"anniv1"には、何かしら必ず記念日を入れるようにしています。

最後に366日分のpng画像を、サーバにアップします。

## アップした画像を呼び出す

画像URL

```

https://wazka.jp/v2/anniv1_img/

```

こちらにmmdd形式のファイル名でpng画像を格納しました
例えば2月14日「バレンタインデー」の画像なら0214.pngですから、

https://wazka.jp/v2/anniv1_img/0214.png

こちらに格納されています。
Twitterで「今日は何の日」をAPIとともに画像付き投稿する場合は以下のようになります。

```

import json
import datetime
import tweepy
import requests
from io import BytesIO


def get_api():
    consumer_key = "xxxコンシューマーキーxxx"
    consumer_secret = "xxxコンシューマーシークレットxxx"
    access_token = "xxxアクセストークンxxx"
    access_token_secret = "xxxアクセスシークレットxxx"

    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    api = tweepy.API(auth, wait_on_rate_limit = True)
    
    return api


def anniv(api):

    today = datetime.date.today()
    mmdd = today.strftime('%m%d')
    mmdd_h = today.strftime('%m月%d日')

    url = "https://wazka.jp/v2/anniv/" + mmdd
    r = requests.get(url).json()

    #ツイート本文作成
    contents = ["【AIが描く今日の一枚】"]
    contents.append(mmdd_h)
    contents.append(r['_items'][0]["anniv1"])
    contents.append("")
    contents.append("#stablediffusion #今日は何の日")
    tweet = '\n'.join(contents)
    
    #アップロード画像を取得してUP
    fname = mmdd + ".png"
    imgurl = "https://wazka.jp/v2/anniv1_img/" + fname
    img = requests.get(imgurl).content
    result_img = api.media_upload(filename=fname, file=BytesIO(img))

    #画像付きツイート
    api.update_status(status=tweet, media_ids=[result_img.media_id])


if __name__ == '__main__':
    api = get_api()
    anniv(api)


```

実行結果がこちら。

https://twitter.com/grd09607765/status/1576227743385391104?s=46&t=D32k87bpIe4tl7-fKpdMzw

この日はわりとお題に忠実な画像が生成されましたが、日によって「ギリギリセーフ」「ギリギリアウト」「何を表現したいのかわかるけどアウト」「明らかにアウト」などの判定が楽しいです。あまりにも意味不明な画像は、差し替えたりもしてますが…。
これからも、面白い…もとい役立つ機能や活用法を考えていこうと思います。
カメラ画像から顔を検出して矩形で囲む15行


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png" align="top" /> メモ


# やること
カメラ入力の動画の画像から顔を検出し、バウンディングボックス（検出領域を示す矩形）を表示させます。
pythonです。

# 準備
https://github.com/opencv/opencv/tree/master
からカスケード識別器をDLしておき、そこに含まれる
https://github.com/opencv/opencv/tree/master/data/haarcascades
のフォルダを適切な場所に保存しておきます。
（これから作るpythonファイルのフォルダと同じ場所など）

#
```python:face_detect.py
import cv2 as cv

capture = cv.VideoCapture(1) #カメラの指定 ID1はノートブック内蔵カメラ 必要に応じてID変更
cascade = cv.CascadeClassifier( #顔認識用学習ファイルの指定
        r'＜該当箇所までのフルパス＞/haarcascades/haarcascade_frontalface_alt.xml'
    )
    
while(True):#ループでカメラから連続で画像を取得する
    ret, frame = capture.read()# retにはカメラの接続状況がBoolで入る。frameには画像データが入る
    facerect = cascade.detectMultiScale(frame)#frameに含まれる顔を検出し、その位置をfacerectに格納する
    if len(facerect) > 0:#顔が検出されない場合はlen(facerect)が0以下になる、検出されればfacerectに位置が格納される。
        for rect in facerect:#rectの1,2個目、3,4個目のデータを取得して矩形を書く
            cv.rectangle(frame, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]),(255,0,0), thickness =2)#blue,green,red

    cv.imshow('Frame', cv.flip(frame, 1))#結果をwindowに鏡像表示する
    
    if cv.waitKey(1) & 0xFF == 27:#ESCキーが押されたら終わる
        break

capture.release() #カメラ終了
cv.destroyAllWindows() #ウィンドウ破棄

```
さきほどDLして保管した「haarcascade_frontalface_alt.xml」までのフルパスを指定します。
カスケード識別器を変更すれば他のものも検出できます。

## 実行結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/60720188-3d50-1953-54cc-2a9769d0c70f.png" width = 300>

カメラの動画入力に対してリアルタイムに顔検出が行われ青色で矩形が表示されます。


### 参考
『Pythonで始めるOPENCV4プログラミング』北山直洋著
デザインパターン_Adapter

## 参照
[2．Adapter パターン 1](https://www.techscore.com/tech/DesignPattern/Adapter/Adapter1)
[C++でデザインパターンを実装する:アダプター編](https://qiita.com/omuRice/items/488ac76409973bdbf2bc)
[wiki Adapter パターン](https://w.wiki/yJP)


## まずAdapterパターンとは
adaptとは「適合させる」
adapterは「適合させるもの」
つまりAdapterパターンは
インタフェースに互換性の無いクラス同士を組み合わせることを目的としたパターンです。

![Adapterパターン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/bbd048ee-2b0b-f167-2f43-26a34cab5f97.png)

今までが上のパターンでmainから処理までのクッションが1回となっている．
下のAdapterパターンを使用した場合mainから処理までのクッションが2回となっている．
Adapterパターンの場合は，処理に何らかの不具合が見つかった場合，Adapterで変更・修正を行えることで修正・変更箇所が，コード全域ではなくAdapterの1箇所のみで済む．

## Adapterパターンのメリット
- 修正が生じた際に修正が1箇所で済む

## どのような場合に使うべきか
- 同じ関数を何回も書くときなど

## クラス図
![750px-Adapter_using_inheritance_UML_class_diagram.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/9bbaae0d-8379-e0f4-ce5f-9434ddc6a283.png)

[wiki-Adapter パターン](https://w.wiki/yJP)より引用

## 各機能

### Adapter
AdapteeとInterfaceの処理を纏める

### Adaptee
ここで複数回使うコードのクラス・処理を記述する


### Target(Interface)
Target(Interface)では仮想関数・純粋仮想関数を記述する

## 処理

### Adapter

```C++:Adapter.cpp
#pragma once

#include "Adaptee.h"

class Adapter :public Adaptee
{
public:
	Adapter() :Adaptee() {};
	~Adapter() {};

	//Adapteeの関数を結合する
	void Coupling() { Method(); }
};
```

### Adaptee
``` C++:Adaptee.cpp
#pragma once

#include <string>
#include <iostream>
#include "Intorface.h"

using namespace std;

class Adaptee
{
private:
    string str;
public:
    //Adaptee(const string s) :str(s) {}
    Adaptee() {};
    ~Adaptee() {}

protected:
    void Method() { cout << "Adaptee" << endl; }
};
```


### Target(Interface) 
```C++:Target
#pragma once

#include <string>
#include <iostream>

using namespace std;

template<class T>
class Interface
{
private:
    T obj;
public:
    Interface(){}
    ~Interface() {};

    void printStr() { obj.Coupling(); };
};
```

### main

```C++:main.cpp
#include "Adapter.h"
#include "Intorface.h"

int main()
{
    Interface<Adapter> adapter;

    adapter.printStr();//output: Adaptee

    return 0;
}
```
Flutter 環境構築 doctorが通った話

今回やっとFlutterインストール後の環境構築が進み始めたお話となります！

10/2 修正！
解決方法としてpowershellは管理者権限で実行しております。

というのがまずどこまでやったのかというと、タイトルの通りdoctorまでです。

結論から言うとWindows Powershellで「flutter doctor」入力して結果出せた。までとなります。
...全体的にはほんと1ミリも進んでないって感じかもしれないですが、これ個人的に超進歩したっていうお話になります。(´・ω・｀)

[流れ]
「Flutter インストール」と検索してあらかた「コレとコレとコレインストールして」という記事が何件か出たのでそれらをインストールまで完了させました。

そしてPath通しですね。これは筆者が超IT未経験なので何それ？ってなると
もう何も言えませんが記事とか動作みてった感覚でいうとインストールした格納場っていう点とPCの管理室？みたいな点を「繋ぐ線」を通してあげたって感じですかね。
（多分間違っているので参考にはしないことをオススメします！）


[今回の問題点,壁]
そして今回進んだっていうのがpowershellで「flutter doctor」を入力して動いたっていうのが本題となります。

[前提]
・「powershell」 = 「Windows power shell」
ていうコマンドプロンプトのWindowsオリジナル版?みたいなアプリという認識
・「flutter doctor」
flutterを動かすにあたって、何かインストール忘れしてるものないかって診断してくれるコマンド。診断してくれるからdoctor。

[問題,壁の解決法]
待つこと。
ほんと事前に朝とかにpowershellにdoctorコマンド入れて放置しておけばよかったですね。。

筆者はコマンド入力後、アプリがコマンド入力されたこと受け取ったような挙動したと感じましたがその後ズラ～って返答コマンド来るかと待ってましたが来ず、ひたすら再起動とかして試行錯誤してました。。
色々ググったり拙い日本語や英語で検索かけたりと。。

果報は寝て待てとはまさにノートPCで入力したflutter doctorの事に対してですね。

元々作業しているのがノートPCで、色々アプリ入れてるから余計に重かったんですが。
15～30分待っても返答コマンド出てこなかったので試行錯誤してましたが疲れ果て、息抜きに某FPSやったりで小一時間経ってました。
「そういえば」と思いチラッとPC確認するとこれ↓
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2214304/bf9d1114-9247-db6f-e74d-215abc94726b.png)
個人情報載ってないか怖かったのでここのみ撮りました

というようにこの通り無事ネット記事で見た成功例の返答のまんま！
これには本当に感動しましたねー。

この下にまた何のアプリがインストールされてないって表示されているので
やっとスタートラインに立ったのかなという感じです。

と、長くなりましたが結論↓
自分と同じようにノートPCで実行してて同じような現象になった人はいったん待ちましょう！
です。コマンド入力してなんか読み込みっぽい、文字入力してみても反応ない,入力されないって方いましたらお出かけしてみたりって待ちましょう！

引き続きflutter頑張れるとこまで頑張ってみようかと思いました！
SpringBoot/JPAのはじめ方0 - Docker設定

こんにちは。こまつです。

概要
---
サーバサイドのアプリ開発はDBにアクセスしながら進めると思いますが、ローカルにDBを立ててしまうと
「プロジェクト毎のDB管理が煩雑になる」「ローカル環境が汚れる」といった問題が起こります。
そのためdocker上にDBを起動するのがおすすめです。
マイグレーションSQLも一緒に管理すれば、テーブル再構成、データ復元も気軽に行えます。
ここではDocker設定とDB起動、IntelliJでのDB参照までやります。


前提
---
dockerの知識はここ
https://knowledge.sakura.ad.jp/13265/

docker desktopのインストールはここ
(mac)
https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/
(windows)
https://matsuand.github.io/docs.docker.jp.onthefly/desktop/windows/install/

dockerファイルを作成する
---
必要なファイルは以下の3つ。

docker-compose.yaml
```docker-compose.yaml
version: '3'
services:
  mysql:
    build: ./docker/mysql <- Dockerfileの位置
    container_name: hello_springboot_kt_mysql <- コンテナ名。ユニークな名前をつけておいた方が管理しやすい
    volumes:
      - ./docker/mysql/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf <- mysqlのconfig
    ports:
      - 3306:3306 <- ポート。DB複数起動する場合はそれぞれ別のポートを指定する
```

Dockerfile
```Dockerfile
FROM mysql:8 <- MYSQLのバージョン指定
ENV MYSQL_DATABASE testdb <- DB名
ENV MYSQL_USER mysql <- ユーザ名
ENV MYSQL_PASSWORD password <- パスワード
ENV MYSQL_ROOT_PASSWORD password <- ルートパスワード
CMD [ "mysqld" ] <- デーモン起動
```


MySQLの設定ファイル
```my.cnf
[mysqld]
character-set-server=utf8mb4 <- 文字コード
collation-server=utf8mb4_bin

# time zone
default-time-zone = SYSTEM
# log_timestamps = SYSTEM

# default authentication plugin
default-authentication-plugin = mysql_native_password

[mysql]
default-character-set=utf8mb4 <- 文字コード

[client]
default-character-set=utf8mb4 <- 文字コード
```

具体的な配置場所は以下を参照ください
https://github.com/komkomh/HelloSpringBootKt


docker上にMySQLを起動する
---
起動コマンド
```
docker-compose up
```

IntelliJなら2行目の横にある矢印をクリック
![スクリーンショット 2022-10-02 2.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/fce19c55-0b82-c8ab-a730-be7c93a8cb90.png)


docker desktopで起動を確認する
![スクリーンショット 2022-10-02 2.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/056b4e6f-1886-a6b8-3ba2-0832a72ce1e4.png)


接続してみる
---
お手持ちのDBクライアントから接続を確認ください。

以下、IntelliJでの接続確認手順になります。

「右のDBタブ」 → 「＋ボタン」 → 「MySQL」
![スクリーンショット 2022-10-02 2.16.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/058bffa1-366f-5cd7-3c7f-e3979659e247.png)

「接続情報を入力する」 → 「Test Connection」 → (Succeededでたら) → 「OK」
![スクリーンショット 2022-10-02 2.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/ed76e69b-5cce-063a-5400-4e63eff3bcc1.png)

接続できると以下の表示
![スクリーンショット 2022-10-02 2.22.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/4a972da1-5dfc-de0b-56d5-3bcd9d178083.png)

アプリを起動し、テーブル作成後にリフレッシュ
![スクリーンショット 2022-10-02 2.24.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/55c2d8c1-1e51-c4fe-7021-33be50e73dae.png)


まとめ
---
以上でDocker上にMySQLの構築、DBの参照までできました。
IntellJのDBクライアントは多機能のため開発効率が実感しやすいです。
※私はultimate使っているので確認できてないですが、無料版のIntelliJにDBクライアントなかったらすみません。

◾️開発時のDBはdockerで管理するのがいい
独習プログラミングの備忘録　2 前編　【式と演算子】

覚えることが多いため2つに分けることとした。

～学んだこと～
・+, -, *, /, % を演算子(operator)、a, b, 5 をオペランド(operand)と呼ぶ

・整数リテラルの先頭に「0x」または「0X」を付けると16進数、「0」を付けると8進数となる

・どのエスケープシーケンスも、先頭は「\」から

・代入演算子(+=, -=)の優先順位は最低

・インクリメント・デクリメント演算子(++, --)は単独で使用する

・小さな値の型を大きな型の変数に代入する時(int型 → long型)は問題ないが、逆は深刻なエラーが発生する可能性がある

～感じたこと～
文字を強調するためにエスケープシーケンスは必須である。しかし「"」はprintfにも使うため、非常にややこしい。
.gitignoreで機密情報を守る。

<h1>はじめに</h1>

Djangoを学習した手の時にGitHubにpushした際に以下のようなメールが届いた。

<img width = 500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1090582/146b0a01-583e-140d-4cee-d56551e99635.png >

どうやらDjangoののSecretKeyをGitHub上にアップロードしてしまったのがいけなかったらしい。

慌てて消そうとしたが該当箇所を削除するだけで解決する問題なのかわからず、色々調べたところ、.gitignoreで指定したファイルをGit上にあげないようにする事ができるらしい。
今回はその方法について書いていく。


本記事では初心者向けに手順にのみ絞って記述していくので、細かい説明は割愛する。


<h1>.gitignoreファイルを作成する。</h1>　

まず.gitignoreファイルをmanage.pyファイルと同じ階層に作成してみましょう。
（※mysiteの中のsettings.pyファイルの中に作成しても構わないが、import部分が本記事と微妙に変わるので初心者の方にはおすすめしません。）

　
ターミナル上で以下のコマンドを実行する、もしくは手動で.gitignoreファイルを作成してください。
```
(venv) labokgs@MacBookAir mysite %  touch .gitignore
```
　
作成後のディレクトリ構成は以下のようになると思います。
　
```
mysite/
    .gitignore
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py

```

　
　<h2>settings.pyファイルとlocal_settings.pyファイルに変更を加える。</h2>
　次にsettings.pyファイルと同じ階層にlocal_settings.pyファイルを作成し、settings.pyファイルのSECRET_KEYをコピーアンドペーストします。

```python:settings.py
from .local_settings import *  →これの記述も忘れずに！

# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = 'jlfkajlkjdfoaojunalnall&(&)' 　　→これを削除

```



```python:local_settings.py

SECRET_KEY = 'jlfkajlkjdfoaojunalnall&(&')'　　　　→ここにペースト

```

<h2>.gitignoreファイルに無視したいファイルを記述</h2>

最後に、.gitignoreファイルに
無視したいlocal_settings.pyファイルを記述する。

```python:.gitignore

mysite/local_settings.py

```

<h1>おわりに</h1>

以上で完了。
これでGitはlocal_settings.pyファイルを無視してくれるようになりました。

SECRET_KEY以外にも、APIを実装する際のAPIキーやデータベース情報、クラウドの情報などGit上に上げてはいけない機密情報を無視してほしい時にこの方法を用いる事ができます。
Blender奮闘記⑨

# 初めに
yukiさんのモンブラン作成動画の後、ブッシュドノエルを作ろうとしていた。

# 作成途中

![スクリーンショット 2022-09-26 012324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/2eb5a8fd-9c17-7584-b557-148a68b882e0.png)

円柱を2つ接続すればそれっぽい見た目になるので、くっつけ、外枠をモンブランの時のようにシェーダーを使ってチョコの木の幹のように作成する。

![スクリーンショット 2022-09-27 011028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/a6150a05-6296-2de1-e752-d23af78a8eab.png)

少しずつ少しずつ並べて……サンタを置いてあきらめました。

![スクリーンショット 2022-09-30 005742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/f293b8f1-20b1-9e10-4395-7024b6b502cd.png)

レンダリングすると上の巻いているようなクリーム部分が消えました。また、最初に作ろうと思っていた柊の葉もうまいこと作れず、イメージ画像からは遠いものとなってしまいました。

#終わりに

平面で意図した形状のものを作ることができないという課題が見つかりました。
そこの部分を意識しながらひとまずブッシュドノエルの作成は終わろうかと思います。
今度はyukiさんの動画を見ながらハートのモデリングとアニメーションを行います。
【Python】全探索で要素を一つずつ減らして探索してもオーダー変わらないよって話【AtCoder】

# この記事で学べること
リストの全探索をするときに、要素を一つずつ消しながらやったって、
オーダーは変わらず **O(N^2)** ですから！

# 状況
こんな問題を考えます。
> 要素がN個のリストAが与えられるので、リストAの中に0 ~ N-1がいくつ存在するかを出力してください（簡単化のため、とりあえずN=10にしておきます）。

愚直に解いてみましょう。

# 解法1: 工夫なしに解く
``` Python:solution1.py
A = [8, 5, 6, 2, 3, 9, 1, 0, 4, 7]
cnt = 0
for i in range(10):
    for j in A:
        if i == j:
            cnt += 1
            break
print(cnt)
>>> 10
```

ここで、この解法のオーダーを考えてみます。
Aの要素の数だけAを全探索する必要があるので、O(N^2)であることが明らかですね。
でも、私は考えました。
 **「あれ？Aでヒットした要素をAから消去すればもっと早くなるんじゃない？？」**
もしかして、オーダーが減るんじゃないの？！

# 解法2: 取り出した要素を消しながらソート処理
``` Python:solution2.py
A = [8, 5, 6, 2, 3, 9, 1, 0, 4, 7]
cnt = 0
for i in range(10):
    for j in range(len(A)):
        if i == A[j]:
            cnt += 1
            del A[j]    # 消してみた
            break
print(cnt)
>>> 10
```
今回の問題の場合は、0 ~ N-1まで全てAに含まれているので、for文のループ回数が必ず一回ずつ減っていくことになります。従って、計算量は項数Nの等差数列の和になるはずです。
```math
\sum_{k=0}^{n-1}k=\frac{1}{2}n(n+1)=\frac{1}{2}n^2+\frac{1}{2}n
```
・・・ん？
オーダー記法での計算量の求め方は、最高次数を参考にするって話だったから…
結局、要素を消していこうがいかまいが、 **オーダー変わらずO(N^2)じゃん！**

# まとめ
少しでも計算量減らそうと足掻きますが、要素を一つずつ減らしていったり、途中で計算を打ち切ったりするくらいの小手先では、膨大なNに対しては何の効果もありません。TLEが出たときにはそんなところを気にするんじゃなくて、解答の方針を見直した方が良さそうです。

# 終わりに
自分用のメモとして記事を作成しましたので、非常に読みづらく、かつミスが多いかと思われます。ミスを発見した際にはスルーしていただくか、お手柔らかにご指摘していただけると嬉しいです。
MacBook Air M1チップモデルのUSB-Cケーブルでは外部ディスプレイへの映像出力はできない事実

# 伝えたいこと（だいぶ恥ずかしい）

[MacBook Air M1チップモデル](https://www.apple.com/jp/macbook-air-m1/specs/)に同梱されているのUSB-Cケーブルを使って、外部ディスプレイへの映像出力はできません。
という事実を、ようやっと把握。
仕様を確認すると、
```USB-C充電ケーブル（2m）```
だものね。それはできませんですよ。
今（２０２２年１０月）からM1を購入される方がいるか分かりませんが、同じハマりをされないように残します。

## 経緯

-　MacBook Air M1チップモデルをUSB-Cポートをもつ外部ディスプレイに接続して大画面でvscodeを使いたいと思い立つ。
-　接続しても「シグナルが検出されません」が出るばかり。
-　Macを再起動したり別のUSB-Cケーブルに変えたりして接続を試すも事象改善せず。
-　変換コネクタを使ったHDMI接続では外部ディスプレイに認識される。
-　ケーブルを疑って調査する。
-　「[オルタネートモード](https://www.elecom.co.jp/pickup/usb_type-c/)」という用語を知る。
-　MacBook Air M1チップモデルの同梱ケーブル名称を確認する（上述）。
-　そそくさとオルタネートモード対応のUSB-Cケーブルを購入する。お急ぎ便一択。
-　外部ディスプレイへのUSB-Cケーブルでの出力成功する。

## 結論

あれこれ試す前に同梱物も含めて仕様はよく確認しましょう。
AI-900 Microsoft Certified: Azure AI Fundamentalsに合格しました

## 記事について

AI-900 Microsoft Certified: Azure AI Fundamentalsに合格したので合格記

https://learn.microsoft.com/ja-jp/certifications/azure-ai-fundamentals/

## いつもの学生割引で無料で受けました

学生はMicrosoftのFundamentalレベル試験が無料で受験できるので、今回もその制度を使わせていただきました。
詳しくはこちらの記事を読んでください。

https://qiita.com/komajo/items/91676a74f092b2a0d07b

## 難易度

超簡単でした。今までで受けたベンダー資格のなかで一番簡単だったのでびっくりしました。
総勉強時間は10時間未満。
テストセンターで費やした時間はトータル20分程度でした（試験前の書類サインやIDチェックも含めて）、と言えば難易度がなんとなくつかめると思います。

## 試験前にやったこと

### ①試験範囲の学習

https://learn.microsoft.com/ja-jp/certifications/azure-ai-fundamentals/

このページの「準備する2つの方法」セクションにあるMicrosoft Learnのコースを一通りすべて行いました。といっても試験範囲はぜんぜん広くないので、コースもとても短いです。ささっと済ませれば全部で5時間くらいで終えられると思います。
ハンズオンとかはやらなかったです。やり方だけ目視確認。

### ②模擬試験・模擬問題

MeasureUpの模擬試験（これも学生特典）を5周くらいしたら、だいたいほとんどの問題を解けるようになってました。
それで足りないなぁと感じるところはもう一度Microsoft Learnで確認しました。

その他に、公式に掲載されているサンプル問題も３周くらいしました。

https://learn.microsoft.com/ja-jp/certifications/resources/ai-900-sample-questions

この感じで試験に行きましたが、一通りのスキルはカバーできていました。

## さいごに

めちゃくちゃ簡単なので合間時間で取れて、デジタルバッジももらえて、履歴書にも書けるちょうどいい資格だと思います。
社会人でもMicrosoftのトレーニングイベントに参加すれば試験バウチャーがもらえたりするそうです。
今はAIについてまったくわからないけどちょっと理解してみたい、という方はぜひ挑戦してみてはいかがでしょうか。
「ちょっと午後までに標準偏差表示しといて」～C# での最速標準偏差～

残念ながら .NET の標準ライブラリーで**標準偏差**を算出することはできません。
もちろんあります。NuGet に。[Math.NET Numerics](https://numerics.mathdotnet.com/ "Math.NET Numerics") を使って最速で標準偏差を出しましょう。

# 環境
- Visual Studio 2022
- .NET 6
- コンソールアプリ

# 手順

## 1. NuGet パッケージをインストール
1. プロジェクトファイルを右クリック
1. `NuGet パッケージの管理(N)...` をクリック
1. `参照` タブで `mathnet` と検索
1. `MathNet.Numerics` をインストール！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/eb8ce2c2-2430-fcb8-36a4-8b4cd47fd825.png)
※2022/10/01 現在の最新安定版は 5.0.0

## 2. 使う
1. `using MathNet.Numerics.Statistics` 追加
1. `IEnumerable<double>` の拡張メソッド `StandardDeviation()` or `PopulationStandardDeviation()` を呼ぶ！

```diff_c_sharp:Program.cs
using MathNet.Numerics.Statistics;

Console.WriteLine("Hello, World!");

double[] doubles = { 1.0, 2.0, 3.0, 5.0, 8.0, 13.0 };

// データを標本だとみなす場合
double stdev = doubles.StandardDeviation();
Console.WriteLine(stdev);

// データを母集団全体だとみなす場合
double pstdev = doubles.PopulationStandardDeviation();
Console.WriteLine(pstdev);
```

```console:出力
Hello, World!
4.501851470969102
4.109609335312651
```
はやい！

## 3. 確認してみる
よし、じゃあ Excel 様と比較しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/096d02de-f529-4b2e-eb7d-1da749e3994f.png)

Excel 様の有効桁数は15桁なので、下一桁が異なっていますね。実用十分。

# まとめ
C# で標準偏差を出したくなったら、[Math.NET Numerics](https://numerics.mathdotnet.com/ "Math.NET Numerics") を使ってみよう。
Math.NET Numerics には他にも多くの機能があります。これから何度もお世話になりそう。
~~.NET の標準ライブラリーにあってもいいと思うんだけどなぁ。~~
Cloud Watchで請求アラームを設定する

マネコンにログイン
http://console.aws.amazon.com

リージョンをバージニア北部に変更する。
請求データとそのアラームはバージニア北部で表示・管理。
リージョンを変えておかないと後々で警告が出て設定できないのでここでやっておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/33da2ae6-8da4-8998-a4fc-8425e3849013.png)

Cloud Watchに移動し、左メニューから「請求」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/f84c8e0a-667b-b65d-5177-eb9bb16d55a8.png)

画面下方の「アラームの作成」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/d712e3d7-678a-98fb-5015-b9b78184e02b.png)

「メトリクス」と「条件」を設定。
「期間」は6時間より短くすると警告が出るため6時間としておく。
「条件」は今回50USDを超えたくなかったのでその一歩手前の「45USD」を設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/602d7b0e-d3a1-373a-bfaa-cc634aa6e225.png)

「トピック名」「Eメールエンドポイント」を設定し「トピックの作成」を選択する。
※アラームメールはSNS(Amazon Simple Notification Service)から送る形となるため
　SNSのトピックを新規作成する。すでに適切なトピックがある場合は「既存のSNSトピックを選択」。
※トピックはメールの宛先をセットしたオブジェクトのようなもので
　SNSはトピック単位で通知を行う（メーリングリストをイメージすると近いかも）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/9946e4c1-8bbe-fd23-ba48-0354fe8f3239.png)

「トピックの作成」をクリックするとメールアドレス検証のためAWSから確認メールが届くので
リンク(Confirm subscription)をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/9256a79d-7519-c468-1b3b-b17f99cee401.png)

リンク先に遷移し、Subscription confirmed!が表示されればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/8fa53afa-2a29-dff2-e723-ac810a9056d3.png)

Cloud Watchのアラーム作成画面に戻り、
SNS画面を開いてサブスクリプション完了を念のため確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/0bce8009-32df-cf3b-7417-3e0160f88ddd.png)

ステータスが「確認済み」になっていればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/d34ecb52-f849-e1f1-3545-3f06ca9915e5.png)

Cloud Watchのアラーム作成画面に戻り「次へ」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/bc4072db-c275-246d-8fea-ad0427e887ae.png)

アラームの名前と説明を適当に記入して次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/223ef4f9-bda4-c55c-5dc8-a99d52eaf42c.png)

確認画面が表示される。問題なければ画面最下部の「アラームの作成」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/83d2d500-837b-1687-cb9d-179145a92c11.png)

作成に成功すれば、作成したアラームが表示される。
「状態」が「データ不足」となっているのはおそらく請求情報の更新は6時間単位であり
アラーム作成直後は情報がないためと思われる(推測)。そのうちデータが表示されるはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/23362caa-115c-1c68-03ef-9464a0d6e8d9.png)

ちゃんと動くか心配な場合は
閾値(今回だと45USD)を下げて動作確認してみてください。


以上です、おつかれさまでした。
MsBuildを支配しろ ～Directory.Build.props / Directory.Build.target～

## はじめに
.NETで開発していると嫌でも利用することになるのがMsBuildです。
最新の.NET 6環境でもdotnet CLIに隠れているだけでMsBuildを利用しているのは同じです。
（一時期は脱MsBuildをしようとしてたらしいですが、辞めたようです）

今回は、複数プロジェクトの設定を一括で変更できる、Directory.Build.target / Directory.Build.propsについて紹介します。
Visual Studio 2017以降で利用できます。

## Directory.Build.*
だいたいリポジトリ直下に置くファイルですが、次のような効果を持ちます。
- Directory.Build.props
  - csprojの”前”に読み込まれる。
    csprojで上書きができる
- Directory.Build.target
  - csprojの”後”に読み込まれる。
    csprojの設定を上書きできる

これの仕組みとしては、MsBuildがcsprojをビルドする時に、ドライブルートまで親ディレクトリを遡っていき最初に見つかったファイルを読み込むというものです。

C:\aaa\bbb\ccc\ddd\eee\eee.csproj というパスにプロジェクトがある場合
```
C:\aaa\bbb\ccc\ddd\eee\
C:\aaa\bbb\ccc\ddd\
C:\aaa\bbb\ccc\
C:\aaa\bbb\
C:\aaa\
C:\
```
の順番で探索します。
見つかった時点でそれ以上の探索は行われません。

## 何に使うの？
複数のcsprojから構成されるアプリケーションの場合に有効的に使えます。
例えば、NULL許容参照型を全プロジェクトで有効化する場合、こうなります

```xml:Directory.Build.props
<Project>
  <PropertyGroup>
      <Nullable>true<Nullable>
  </PropertyGroup>
</Project>
```
（ただし、プロダクトでこれをやるとビルド時に大量の警告が出ます‥）

決定論ビルドの有効化や、言語バージョンの指定などもできます。
```xml:Directory.Build.props
<Project>
  <PropertyGroup>
      <Nullable>true<Nullable>
      <Deterministic>true</Deterministic>
      <LangVersion>9.0</LangVersion>
  </PropertyGroup>
</Project>
```
## わかっていないこと
csprojにはSDK styleとそうでない旧式のものが存在します。
これらが混在している場合、特に旧式のcsprojでの挙動がまだよくわかっていません。

Directory.Build.propsでNullableを有効化、csprojの方で個別に無効化してみたのですが、何故かnullableが有効になっていました。
全体的に無効にした上で個別に有効化したらちゃんと意図通り動きました。なんで？

## まとめ
NULL安全の導入、言語バージョンの指定にDirectory.Build.propsが使えるという話でした。
破壊的な事もできてしまうので、プロダクトで使う場合は十分注意が必要です。
for _ in range(3) について

備忘録

python(3.8.2)のfor文
`for _ in range(3)` の`_` について

## 疑問点
`_`とは何でしょうか。

## 調査結果
`for _ in range(3)`は`for i in range(3)`のように書いてもOKです。
変数名が`_`になっているだけであり、変数名を`_`にすることによって、
「その変数を使っていません」ということを表現しています。（Pythonの習慣です）。

ソースコード
```python
N = 3
for i in range(0, N):
    print(i)

for _ in range(0, N):
    print(_)
```


標準出力
```python
0
1
2
0
1
2
```
InstantNeRFでの動画出力の仕方

こんにちは！！[Aster](https://twitter.com/Beehibiki)です！！！
本日はInstantNeRFでの動画の出力の仕方を記事に書こうと思います！

# InstantNeRFとは

「NeRF」(Neural Radiance Fields)は、さまざまな角度から撮影した複数の写真から、自由視点画像を生成する技術です。深層学習によって生成された画像を通じて、好きな視点から対象物を見ることができます。

要するに動画から3Dシーンをつくることができるということですね。
githubは[こちら](https://github.com/NVlabs/instant-ngp)です。

# 動画の出力の仕方

まず、instantNeRFを立ち上げてください
(19044\aster\NeRFの部分とdataの部分は自身の環境に合わせてください)
```
C:\Users\19044\aster\NeRF\instant-ngp\build\testbed.exe --scene data/meijo2
```
するとこの画面が出てくると思います.

![screenshot.8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/bd0368c6-583a-4243-91e9-3a3cb7044898.jpeg)

次に動画を撮るためのカメラ位置を決めます。
撮りたいカメラ位置に移動したらAdd from camのボタンをクリックしてください。

![screenshot.9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/7c1bba1f-4fcd-55d8-c3e8-09f866cf597e.jpeg)

するとカメラ位置にカメラ情報が出てきます。
これを繰り返してカメラ位置を追加していきましょう
![screenshot.11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/d1625232-3867-1790-1f4a-de91106ed826.jpeg)

カメラ位置を追加すると下記のように軌道が生成されます。
![screenshot.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/be69a364-28d2-025d-e97c-695d2e42a4c1.jpeg)

次にこのカメラの軌道を保存しましょう.
追加方法は画像のように2つのSaveを押すだけです。

![screenshot.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/2dec9698-dd78-a984-0e9b-0d7821a983a6.jpeg)

![screenshot.17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/04b3f7c3-f71f-0376-7e36-8656550a3fcd.jpeg)

これで下記のように
base.msgpackとbase_cam.jsonファイルが生成されていれば完了です。

![screenshot.18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/c9d65539-84ac-0b13-bf9d-c9cd1a6a8e1e.jpeg)

次に動画の出力をしましょう。
※ffmpegが入っていないと学習が終わっても動画の出力がされません。絶望します...
念のため下記のコマンドを実行し,ffmpegが入っているか確認しましょう!

```
ffmpeg -version
```
入っていなかったら、[こちらの記事](https://algorithm.joho.info/windows10/ffmpeg-install-win10/)を見て入れましょう

ffmpegが入っていれば下記のコマンドを実行してみましょう
pathは各自のpathに変えましょう

結構時間がかかるので、注意してください。10秒で30分かかります。
時間を変える場合は--video_n_seconds 10 を変えてください
```
python scripts/run.py --scene data/meijo2 --load_snapshot data/meijo2/base.msgpack --video_n_seconds 10 --video_fps 60 --width 1920 --height 1080 --mode nerf --video_camera_path data/meijo2/base_cam.json
```

このように学習が始まれば成功です。
![screenshot.19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/ab200c08-8d73-8bf4-7221-f784e56409b9.jpeg)

撮られた動画はinstant-ngpの中にあります。
![screenshot.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/985b4a04-1e84-fb78-b42b-6a76cd9308f6.jpeg)


![meijo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/7503e3f6-47cb-7856-4530-ca5aff013e75.gif)


以上で動画を撮ることができます。

# まとめ
動画の出力は英語の動画しか見当たらなかったため、今回InstantNeRFでの動画の出力の仕方を記事にしました。
この記事をみて、NeRFで撮った動画がもっと世に出ることを願っています！！！
【Power Apps】簡易作成フォームを有効にする方法

Dataverseでフォームは4種類ありますが、規定ではその中の「簡易作成フォーム」は無効です。簡易作成フォームを使いたい場合は個別で有効化手順が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/73a0eed1-5f92-be32-3191-eaba28f4167d.png)


# 手順
対象のテーブルの詳細画面にて[プロパティ]を選択し、出てきたメニューで[高度なオプション]を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/be0ccc62-ae7f-5a70-850c-d47f3b77d2c3.png)

「可能な場合は、簡易作成フォームを活用します」を選択して[保存]ボタンをクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/8ee43b80-889c-3507-1c7c-6d975012887a.png" width=40%>

これでできるようになったはずです

# 確認

テーブルの詳細画面の[フォーム]を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/cb219b23-0ae3-c202-b93f-e1794264d56d.png)
[新しいフォーム]にて簡易作成フォームが可能になっていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/720f0c64-956a-a40d-890e-7c7f660b1f40.png)
fatal: unable to connect to github.com: errno=Connection timed out を解決

```
luarocks install nngraph
```

これを実行してあげようとしたら、タイトルのエラーが出ちゃったのよ。
エラーはこんな感じね。
```
Installing https://raw.githubusercontent.com/torch/rocks/master/nngraph-scm-1.rockspec...
Using https://raw.githubusercontent.com/torch/rocks/master/nngraph-scm-1.rockspec... switching to 'build' mode
Cloning into 'nngraph'...
fatal: unable to connect to github.com:
github.com[0: 20.27.177.113]: errno=Connection timed out
```
原因は、インストールしたいこを"git://"経由でダウンロードしちゃってるっぽいのよね。これを"https://"経由でのダウンロードにしてあげれば解決よ。
```
git config --global url."https://".insteadOf git://
```
終わり。
Javaで何か作ってみる(2022/10/21 Day1)

## 今日やった事
- Qiitaで、「Javaで何かを作る」と宣言した。
## 所感
- Qiitaの記事を書けたのは良かったものの、それ以外は何も出来なかった。
## 明日の予定
- 何かしら、Javaの勉強は進めたい。
- Qiitaの記事を整理して、後々振り返りしやすくしたい。（タイトル、レイアウト、タグ付けetc）
PHP8.0の新機能を試してみた

# はじめに
今更ですが、PHP8.0の新機能をいくつか試してみました。
試してみた新機能は以下です。
* 関数の名前付き引数
* union型
* match式
* nullsafe演算子

それでは早速使用例や詳細を書いていきたいと思います。

# 目次
[1. 関数の名前付き引数](#1-関数の名前付き引数)
[2. union型](#2-union型)
[3. match式](#3-match式)
[4. nullsafe演算子](#4-nullsafe演算子)
[5. おわりに](#5-おわりに)

# 1. 関数の名前付き引数
関数を実行する際に引数を名前で指定できます。
任意の順番で引数を渡せるため、デフォルト値をもつ引数をスキップできます。

```php
<?php
function foo($a = 0, $b = 0, $c = 0) {
    return $a + ($b * 2) + ($c * 3);
}
// $c以外はデフォルト値を使用したい
echo foo(0, 0, 10); // 位置指定の場合
echo foo(c: 10); // 名前付き引数の場合
```
名前付き引数の場合、`$c`にだけ値を渡せるので楽ちんです。

# 2. union型
複数の型を`or`条件で指定できるunion型が追加されています。
`null`を受け入れるような場合などに使用できそうです。

:::note alert
```php
<?php
function foo($val): int {
    return $val;
}
echo foo (1);
echo foo (null);
```
`null`を許容していないため、返却する値が`null`だとエラーが発生してしまいます。
:::


:::note info
```php
<?php
function foo($val): int|null {
    return $val;
}
echo foo (1);
echo foo (null);
```
こちらはunion型で`null`も許容しているためエラーが発生しません。
:::

# 3. match式
match式は値をチェックした結果によって実行される処理が決まります。
switch文のような感じで使えますが、switch文とは違い型のチェックまで行います。

`$foo`の値とマッチする条件式があるかチェックします。

```php
<?php
$foo = 'qux';
$result = match($foo) {
	'bar' => 'barです。', 
	'baz','qux' => 'bazかquxです。' // 条件式を複数書くこともできる
};
echo $result;
```
この場合2つ目の条件式とマッチするので`bazかquxです。`が返されます。
また、条件式を複数設定したり、返却式で関数を実行することもできます。

## 3.1 デフォルトパターンを設定
全ての条件式にマッチしなかった場合エラーが発生しますので、エラーを発生させたくない場合はデフォルトパターンを設定します。

:::note alert
```php
<?php
$foo = '';
$result = match($foo) {
	'bar' => 'barです。',
	'baz' => 'bazです。'
};

echo $result;
```
チェックした値がどの条件式にもマッチしていないためエラーが発生してしまいます。
:::

:::note info
```php
<?php
$foo = '';
$result = match($foo) {
	'bar' => 'barです。',
	'baz' => 'bazです。',
	default => 'デフォルトパターンです。'
};

echo $result;
// デフォルトパターンです。
```
どの条件式にもマッチしない場合、デフォルトパターンの返却式が実行されます。
:::

## 3.2 厳密な一致チェックを行わずに match 式を使う
制約式に`true`を指定すると条件式に比較演算子などを使用することができます。

```php
<?php
$num = 10;
$return_value = match (true) { // 制約式をtrueに
    $num > 5 => '$numは6以上の数字です。',
    $num <= 5 => '$numは5以下の数字です。'
};
echo $return_value;
```
`$numは6以上の数字です。`が返されます。
# 4. nullsafe演算子
オブジェクトにアクセスする際にそのオブジェクトが`null`だとエラーが発生しますが、`nullsafe`演算子を使用するとエラーが発生せず`null`が返却されるだけになります。

:::note alert
```php
<?php
$obj = null;
$foo = $obj->foo;
var_dump($foo);
// エラーが発生する
// Warning: Attempt to read property "foo" on null in /home/user/scripts/code.php on line 3
```
`$obj`が`null`だとエラーが発生する
:::

:::note
```php
<?php
$obj = null;
$foo = $obj?->foo;
var_dump($foo);
```
nullsafe演算子`?->`を使用すると`$obj`が`null`でもエラーは発生しない
:::

下記のように`is_null`でオブジェクトをチェックするよりシンプルに書けます。
```php
<?php
$obj = null;
if (is_null($obj)) {
	$foo = null;
} else {
	$foo = $obj->foo;
}
var_dump($foo);
```

# 5. おわりに
記事を見ていただきありがとうございました。
新機能は他にもありますので興味あれば確認してみてください。
PHP8.0

https://www.php.net/manual/ja/migration80.new-features.php



# 参考
https://www.php.net/manual/ja/functions.arguments.php#functions.named-arguments

https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.composite.union

https://www.php.net/manual/ja/control-structures.match.php

https://www.php.net/manual/ja/language.oop5.basic.php#language.oop5.basic.nullsafe
Security Hub とは

## 勉強前イメージ

AWSのサービスってくらいで実はあまり知らない

## 調査

### Security Hub とは

AWSの対象サービスのチェックを行って一元管理するサービスになります。
AWSにはいろいろサービスがありますが、使っっている対象サービスのチェックなどを一つ一つしていくのは大変です。
その為、AWSで対象となっているサービスのセキュリティアラートを集約して一つの管理画面で見れるようにしたのが
このSecurity Hubになります。

現時点では対象サービスは以下になります。

- Amazon GardDuty
- Amazon Inspector
- AWS System Manager
- AWS Health
- AWS config
- AWS Firewall Manager
- AWS IAM Access Analyzer
- Amazon Macie

### Security Hub のメリット

- データの集約

上記にも記載させていただいているサービスのセキュリティチェックを一つのSecutiry Hubで見ることができるので
個々のサービスを見に行く手間が省くことが出来ます。

- 自動でのセキュリティチェック

Security Hubではコンプライアンスチェックも可能です。
PCI DSSなどある一定の水準に達しているかどうかを自動で行うことが出来ます。

### Security Hub の注意点

Security Hubを利用するにはいくつか注意点があります。

- セキュリティチェックにはAWS Configの有効化を行う必要がある

データとして使用されるためAWS Configの有効化が必須になります。

- リージョン毎に有効化が必要である

Security Hubは対象リージョンだけのデータを処理するので
いくつかリージョンが見たい場合は各リージョンで有効化が必要になります。

## 勉強後イメージ

ちょっと見てて、trasted adviserと似てるなーって思ったけど
これはコンプライアンスとかセキュリティに特化してるって感じなのかな？
まぁ被る部分はあると思うけど。

## 参考

- [AWS Security Hubとは？概要とメリット を解説](https://www.skyarch.net/column/aws-security-hub/)
- [【はじめてのAWS】AWS Security Hub を設定しよう](https://blog.serverworks.co.jp/tech/2020/07/07/security_hub/)
【Terraform】Terraformの設定(terraform, providerブロック, dataブロック, outputブロック)

# はじめに
udemyを使ってTerraformの勉強をしたので、terraformブロック、providerブロック、dataブロック、outputブロックについての学習備忘録です。

https://www.udemy.com/course/iac-with-terraform/

# terraformブロック

Terraform全体に関わる設定ができる
* required_version : Terraformのバージョン設定
* required_providers: providerのバージョン設定

```terraform
terraform {
  required_version = ">=0.13"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0" # 4.0以上, マイナーバージョンを気にしない
    }
  }
}
```

https://developer.hashicorp.com/terraform/language

# providerブロック
* profile: AWSへアクセスするためのプロファイル
* region : デフォルトリージョン

```terraform
provider "aws" {
  profile = "terraform"
  region  = "ap-northeast-1"
}
```

# dataブロック
管理対象外のリソースの取り込みができる

```terraform
data "DATA_TYPE" "DATA_NAME" {
}
```

# outputブロック
作成したリソースを外部参照できるようにする

```terraform
output "OUTPUT_NAME" {
...
}
```

```terraform
# 例
resource "aws_instance" "hello-world" {
  ami           = "ami-0ce107ae7af2e92b5"
  instance_type = "t2.micro"
  tags = {
    Name = "${var.name}"
  }
}

output "ec2_instance_id" {
  # 参照時に指定する名前
  value = aws_instance.hello-world.id
}
```
WSL2上で起動したGUIアプリのDPIをディスプレイに合わせる

- Windows11上のWSL2 Ubuntu22.04LTSで起動したGUIアプリはWSLg経由でWindows側に表示できるけど、 (4Kディスプレイを使っているからなのか) 画面が小さすぎて合っていない
- Spacemacsは文字サイズでなんとかなるけど、他のGUIツールが小さすぎるのはきびしい


こうすれば調整できる

```sh:~/.bash_profile
export GDK_SCALE=2
export GDK_DPI_SCALE=0.75
```


cf. https://github.com/microsoft/wslg/issues/590#issuecomment-1284025721


issueにdpiと書いてあるからそうしたけど解像度とdpiの使い分けをわかっていない
adminのパスワードを忘れた話。

#### はじめに

今回は投稿サイト作成にあたって、gemのdeviseを使って
user側とadmin側を分けて作成しております。
ん？devise？user側とadmin側分けるってなに？って方は以下サイトをご参照あれ。
>https://nllllll.com/ruby-on-rails/rails-devise/
>https://www.sejuku.net/blog/13378

deviseを導入することで、簡単に認証機能を実装することができます。
つまりサインアップやサインインの実装が簡単にできてしまう便利なgemです！

今回user側からの実装を進めていき、ある程度終わりが見えたところで
「さ、admin側に行くか」と思ったんですが。。

admin側のログイン画面にいき、ふと立ち止まりました。
「あれ？一度サインアップしてる？？したかな。いやでもしたかも」
おそらく作成時にちゃんとサインアップできるかテストしていたんだと予測。
しかしそのパスワードもなにもかも覚えていない。

#### adminのパスワードを再設定しよう

<strong>方法① コンソールを使おう</strong>
コンソールを起動します。
```ruby
$ rails c
```
起動したら、、、下記のように入力


```ruby
3.1.2 :002 > Admin.create!(email: '自分のメールアドレス', password: '好きなパスワード入力してね', name: '自分の名前')
```
createの後ろの「!」を忘れずに。あとAdminのAは大文字です。
自分の情報を入力したらEnterを押しましょう。
```ruby
TRANSACTION (*.*ms) commit transaction
=> ＃<Admin id: 数字, email: "登録したemail", name: "登録した名前", created_at: "日付", update_at: "日付"
```
画面に上記の表示が出れば登録完了です！
ちなみにnameやemailがadminのカラムにあるか確認しておいてくださいね☺︎
忘れないようにseeds.rbにメモをしておくと良いです！
```ruby:db/seeds.rb
#例えです
Admin.create!(email: 'apiy@o', password: 'piyopiyo', name: 'apiyo')
```
<br>
<br>

<strong>方法② seedsファイルに直接記入</strong>
コンソールを使用しなくても、先ほど記述したようにseedsファイルに直接記入してもOKです。
しかし、seedsファイルに記入しただけでは反映されませんので、
seedsファイルのみ使用して登録する場合は、必ずこちら↓を忘れずに！！
```ruby
$ rails db:seed
```

今回私は既にコンソールから登録してあるので、rails db:seedは不要でした。

ちなみに複数の人に管理者権限を付与したい場合は、
同じようにseedsファイルに他の管理者の情報を記入すればOKです！
SystemVerilogでスタックトレースをログに出力

SystemVerilogでの検証中にある関数がどこから呼ばれているかを知りたいことは割と頻繁にあると思います。
言語の標準機能ではこれを表示させる方法は無いのですが、実はデファクトスタンダードになっている$stacktraceというコマンドがあり、この機能を使うことで関数呼び出しの順番をログに表示させることができます。
```verilog
function void fa(); 
  fb(); 
endfunction

function void fb();
  $display("Going to print stack trace");
  $stacktrace; 
endfunction

module topmd(); 
  initial begin 
    fa(); 
  end 
endmodule
```

以下はVCSのログです。出力結果はシミュレータによって少しずつ異なりますが、どれも同等の情報が出力されます。
```text
Compiler version S-2021.09; Runtime version S-2021.09;  Oct 19 21:42 2022 
Going to print stack trace 
#0 in fb at testbench.sv:7 
#1 in fa at testbench.sv:2 
#2 in topmd at testbench.sv:12 
           V C S   S i m u l a t i o n   R e p o r t  
Time: 0 ns
```

Questa, Xcelium, VCSで動作することを確認しています。

注意点ですが、本機能はあくまでログにスタックトレースを表示する機能であって、文字列として結果を返す関数ではないです。なのでSystemVerilogのプログラム中で結果を文字列として受け取ってuvm_infoに渡して、、、などという使いかたはできません。
VLOOKUP の結果 (数値列) が空の場合に既定値を返す

# はじめに

Excel や google スプレッドシート の `VLOOKUP` 関数で数値列を参照する際、検索キーは存在するのに値が空である場合に既定値を返す方法です。**検索キーが存在しない場合** とか **`IF` に `VLOOKUP` を 2 回書く方法** は検索で引っかかりますが、以下の方法は見つからなかったので備忘を兼ねて書いておきます。

# やりかた

適当にこんな表で `"b"` を検索キーとして値を取得する場合を仮定します。

||A|B|
|---|---|---|
|1|key|value|
|2|a|11|
|3|b|(空白)|

1. 数値として取得する場合
   `=IFERROR(VALUE(VLOOKUP("b",A:B,2,FALSE)&" "), NA())`
1. 文字列として取得する場合
   `=IFERROR(VALUE(VLOOKUP("b",A:B,2,FALSE)&" ")&"", NA())`

になります。ここでは `NA()` を既定値にしていますが好きな値を `IFERROR` の第 2 引数に指定してください。

`VALUE(" ")` は `#VALUE!` エラーを返して[^1] `VALUE("1 ")` は数値を返すことを利用します。
`VLOOKUP` 結果末尾に半角スペースを連結して `VALUE` に渡すと結果が空だった場合のみ `#VALUE!` エラーになるため[^2]、それを `IFERROR` で既定値に差し替えています。
`VALUE` は数値を返すため文字列として取得したい場合は `""` を連結して文字列化します。

# お呼びでない何か

* `=IFERROR(VLOOKUP("c",A:B,2,FALSE), NA())`
   検索キーが存在しない場合用ですが、検索キーが存在する前提の今回のケースでは使えません。
   ついでに言えば今回紹介した数式は検索キーが存在しない場合もカバーします。
* `IF(VLOOKUP("b",A:B,2,FALSE)<>"", VLOOKUP("b",A:B,2,FALSE), NA())`
   動きますが `VLOOKUP` を 2 回書かなければならず、数式が長いし、記述や修正が面倒だし、処理も遅そうだしでイマイチです。

# おわりに

元は python の pandas に読ませるデータを excel で作る時に、数値列なので空じゃなくて `#N/A` にしたかったので考えた方法です。どなたかのお役に立てば幸いです。


[^1]:`VALUE("")` だと Excel ではエラーになるが、スプレッドシートでは 0 が返りエラーにならない。
[^2]:文字列 (空白スペース) を連結せずに (空セルを) `VALUE` に渡すと 0 が返りエラーにならない。
検索バーでテーブルの行に対して検索をかけられるようにする方法

PowerAppsのホーム画面やモデル駆動型アプリの上に表示されている検索バー（Dataverse検索機能）でテーブルの行を検索できるようにするにはテーブルごとに設定しないといけません。


# ①テーブル定義の時に設定する方法
最初からこのテーブルは検索できるようにしたいというテーブルがあったら
テーブルを定義するときのテーブルの設定で「検索結果に表示」にチェックマークを入れて作る
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/0822a76b-c4f5-232e-8cf4-0b1dd693c257.png" width=60%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/d7fc1e11-8b50-b2d8-44b3-bb67cfea4d85.png" width=60%>

# ②すでにあるテーブルに設定する方法
検索できるようにしたいテーブルの詳細画面の「プロパティ」をクリック![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/0301c8bf-5b2d-3ff2-4abb-e65beb3e757d.png)

テーブルの編集メニューの「高度なオプション」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/bf54daa4-73d9-9619-9613-015397acdfb6.png" width=60%>
「検索結果に表示」にチェックマークを入れて[保存]ボタンクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/d9843124-db1f-d6ba-782f-152f73d3856b.png" width=60%>
ぼっち演算子(&.)

# ぼっち演算子とは
&.（Safe Navigation Operator）は、通称ぼっち演算子と呼ばれており
ぼっち演算子は、オブジェクトに対してとあるメソッドを呼び出した時、そのオブジェクトがnilでない場合は、実行結果を返します。一方で、nilの場合は、nilを返してくれます。
```ruby:ぼっち演算子を使って、テキストの情報を取得する
# 変数@itemに情報が定義されている場合
[1] pry(main)> @item&.text
=> "アイテム"

# 変数@itemがnilの場合
[2] pry(main)> @item&.text
=> nil
```

通常のオブジェクトメソッドという書き方では、オブジェクトがnilの場合はundefined methodのエラーになってしまいます。
ですがぼっち演算子を使う事によりif文を使わず簡潔化する事が出来ます
```ruby:例
# if文を使用した場合
@item.tags.first.tag_name if @item.tags.first.present?
# ぼっち演算子を使用した場合
@item.tags&.first&.tag_name
```
このようにシンプルな記述に出来ます。

# 参考にさせて頂いたサイト
[Ruby ぼっち演算子について](https://qiita.com/yoshi_4/items/e987b698c1978d248cfc)
新しい Windows マシンを使えるようにした記録

## 必要なアプリのダウンロードとインストール

今まで Mac オンリーだったのだけど、「Windows というものも、してみむとぞ思う」ということでやってみる。

まずは、以下のアプリをダウンロードしインストールする。

基本的には、それぞれの**公式ホームページ**で、**最新版をダウンロード・インストール**する。たとえば Python の場合、仮想環境を使って任意のバージョンの Python をインストールするということなどは、**しない**。（なんで素人さんが，いくつものバージョンの Python が必要なんだろう。あ，そうか，素人さんじゃないからだ。よかった，素人で）

- Python     3.10.8
- Julia      1.8.2
- R          4.2.1
- Octave     7.2.0
- RStudio    2022.07.2+576
- JupyterLab ???

インストール時にデスクトップにショートカットが（自動的に）作られるのは R, Julia, Octave のみのようだ。
RStudio は自分でデスクトップにショートカットを作る。
Python は、Windows PowerShell から以下のようにして起動する（ちょっと面倒くさい）。
```
> py
```
pip によるパッケージのインストールも、
```
> py -m pip install numpy
```
のように行う。

## jupyter lab の起動

まずは Jupyter Lab のインストール。

```
> py -m pip install jupyterlab
```
起動は、Windows PowerShell で以下を入力する。
```
> py -m jupyterlab
```
---
基本的にはこれでやっていけているのだが、「もっと便利な方法がありますよ」という場合には、教えていただければ嬉しいです（「仮想環境を使う」というのを除いて）。
raspberry pi に dualshock4を接続　覚書

# 初めに
タイトル通り
raspberry pi 4B
buster 32bit 

$ uname -a
Linux chirimen 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux

# ドライバインストール

```
sudo pip3 install pyPS4Controller
sudo pip3 install ds4drv
```

# Bluetooth接続
```
bluetoothctl
Agent registered
[bluetooth]# power on
Changing power on succeeded
```
Share + PS長押しでペアリングモード（白フラッシュ）
```
[bluetooth]# scan on
Discovery started
[CHG] Controller AA:AA:AA:AA:AA:AA Discovering: yes
[CHG] Device 00:22:68:F1:59:7F RSSI: -22
```
トラストする
```
[bluetooth]# trust 00:22:68:F1:59:7F
[CHG] Device 00:22:68:F1:59:7F Trusted: yes
Changing 00:22:68:F1:59:7F trust succeeded
```
ペアリングする
```
[bluetooth]# pair 00:22:68:F1:59:7F
Attempting to pair with 00:22:68:F1:59:7F
[CHG] Device 00:22:68:F1:59:7F UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device 00:22:68:F1:59:7F UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 00:22:68:F1:59:7F ServicesResolved: yes
[CHG] Device 00:22:68:F1:59:7F Paired: yes
Pairing successful
```

接続確認

一度終了してもう一度たちあげ
コントローラは電源を入れると接続モード（白点滅）
```
[bluetooth]# exit
$ bluetoothctl
[bluetooth]# power on
[CHG] Controller AA:AA:AA:AA:AA:AA Class: 0x000c0000
Changing power on succeeded
[CHG] Controller AA:AA:AA:AA:AA:AA Powered: yes
[CHG] Device 00:1F:E2:8B:32:9C Connected: yes
[Wireless Controller]# 
```


# テスト

```python
from pyPS4Controller.controller import Controller

class MyController(Controller):
    def __init__(self, **kwargs):
        Controller.__init__(self, **kwargs)

controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
controller.listen()
```
コネクトしてから上記テストコードを実行


# 参考
https://hellobreak.net/raspberry-pi-ps4-controller-0326/
https://hotsmmrblog.com/get-key-event-with-ds4drv/
🔰超初心者のこの先の超初心者の皆様に向けて#2

*Swiftとは?
Apple社が発表しているプログラミング言語

*静的型付き言語
Swiftの特徴は静的型付き言語で、どういう事かというとコンパイル時など実行前の段階に型の情報を決定するプログラミング言語

*コンパイルって？
人間が分かる言葉で書いたプログラミング言語のソースコードの中身をコンピュータが分かるようにすること
*ソースコード
人間の言葉で書いたプログラニングの元ネタ
*バイナリーコード
コンピュータが分かる言葉で書かれたプログラム


イメージ
ソースコード->コンパイル（翻訳）->バイナリーコード
といったイメージでしょうか？

*コンパイルエラー
プログラムに誤りに起因する実行時エラーを未然に防ぐこと

下の画像の下に赤枠で囲まれているのがコンパイルエラーの表示です。

![IMG_0266.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917691/c9b841e0-1cae-b889-ed2e-cd759f88603b.jpeg)
増設SSDもnvme接続で快適な開発環境を構築しよう

# SSD増設！


nVMEにするとdockerイメージのビルトとか、各段に速くなるので、開発環境には必須だとおもいます。
調子にのって、使っていると、ディスクトップ機のWSL2の領域が日増しに増加して、このままではC:が危ない。

nVMEのSSDを増設してみました。

# 用意するもの

-  nVME接続のSSD（M.2 NGFF M-Key）
私の場合、ノートPCで使用していた外付けのSSDを使いました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/d40d1d54-545c-217c-fe65-fc3eb9a48db8.png)

- PCIe変換アダプタ
amazonで、[こんなものを購入！](https://www.amazon.co.jp/gp/product/B07R9VB35J/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/a3b217e5-cabc-e973-1160-0ecf2fb90139.png)

## PCIe変換アダプタ購入時の注意

この変換アダプタはPCIe x4の製品もあります。[x4の製品例](https://www.amazon.co.jp/PCI-Express-M-2%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88%E5%A2%97%E8%A8%AD%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%83%9C%E3%83%BC%E3%83%89-M-2-PCIEPCIe-x4%E3%81%AE%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%81%B8%E3%81%AEPCI-NGFF%E3%81%AEPCIe%E3%82%AB%E3%83%BC%E3%83%89%EF%BC%88M-2/dp/B01J36B75S/ref=psdc_2151943051_t2_B07R9VB35J)
こちらの方が転送速度も速くなり良いですが、私のPCにはPCIex1のポートしかありません。x1のポートにx4は物理的に刺せません。
本体に合ったものを選ぶ必要があります。
x1のボードはx4のポートには刺して使う事ができます。


# SSDを取り付けて、本体に装着。

装着の写真とかあるといいんですが、撮ってませんでした(^^♪


# 転送速度比較

SSD上にあるファイル(ubuntuのISOイメージ)を同じ場所にコピーしてみました。
USB接続の時は、USB変換の処理がボトルネックになっていて、171MB/sで一定でした。

PCIe接続にすると、おお一桁違う。
SSDの読み書きが追い付かず、後半失速してますが、それでも1.3GB/s越え

## USB接続時

![USB接続時.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/668032a6-27e2-422a-c4c3-8ae762845c5c.png)

## PCIe接続時

![PCIe接続時.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/c1b181ed-b0a3-1797-b749-ce7857c8ef2f.png)
ロボットに乗せるメインマイコンは一つにしたほうがいい

# ロボットに乗せるメインマイコンは一つにしたほうがいい

## 自己紹介

こんにちは。初めてQiitaに投稿させていただきます。
2019から2022まで沖縄高専で高専ロボコンをしていました、nalinalyと申します。

後輩への技術継承を目的として、記事を投稿していこうと思います。いつまで続くかな？
この記事が少しでも助けになれば幸いです。

## 本題

自分が4年間ロボコンをしていて、4年目の地区大会が始まろうかというときに気づいたことです。

__メインマイコンは1つにしたほうがいい。__

タイトルの通りです。この記事で言いたいのはこれだけなので、もう読まなくていいです。

一応、メインマイコンを2つとか3つにすると何が起こるかだけ説明します。

## メインマイコンを2つとか3つにすると何が起こるか

悪いことばかりではなくて、一応メリットもあります。

__メリット__

- 使えるピンの数が増える
これはメリットというより、目的？
- すぐ動く
それぞれのマイコンが直接駆動系とかセンサに接続しているので、動作確認などは早いです。動くまではこっちの方が早いかな？
- すべてのマイコン基板を同じ設計にして、発注と設計のコストを下げる
たとえば、DCモータ3個、サーボモータ3個を接続する基板と、DCモータ2個、サーボモータ4個を接続する基板があるとすれば、DCモータ3個、サーボモータ4個を接続できる基板を設計すれば、その2つをカバーできるわけです。2022年の時は実際にそれで3つのマイコン基板を同じ設計にしてちょっと得意げになってました。5か月後くらいに何が起こるか予想できてればね。ちょっと想像力が足りなかったね、その時の自分。


__デメリット__
- 開発の手間がn倍
メインマイコンを３つにしていると、3つのマイコンで同じような処理を行うことがあります。たとえば、コントローラからの通信を受け取る部分とか。そのプログラムに変更を加えるときには、3つのプログラムの同じ箇所をそれぞれいじって、3つのマイコンにそれぞれ書き込む必要があります。これ、最初はいいんですが、後々コードが数百行とかになってくると、数百行のコードの中から該当する箇所を探すという作業が発生します。これを3つのファイルにまたがってやるのは結構ストレスなんですよね。軽く発狂するくらいには。とくにロボットの調整時期はパラメータを頻繁に変えるので地獄です。また、急いでいるときは「まあ、他のはあとから変更すればいいや～」っていって、それが積み重なって、あとからどのプログラムのどこを変えてないのかわからなくなります。その状態になると頭にもやがかかったみたいになって、作業効率が落ちます（自分だけかな？）。あと、プログラムを書き込むマイコンを間違えることもあります。そうするとロボットが想定していない動きをするので、最悪回路や機構が破損することも考えられます。
- 連携させるのが手間
役割は異なっていても、2つのマイコン間で同期をとらなければならない場面は必ず出てきます。通信を行って連携をとるのはできなくはないですが手間です。

## 結論

こうして書いてみると、なんかメリットよりデメリットの方が少ないですね。本当にロボットに乗せるメインマイコンは一つにしたほうがいいのか、ちょっと自信が持てなくなってきました。

でもいえるのは、ロボコンは絶対、設計製作段階で苦労しろってことです。ロボコンだけではないかもしれないですが。
そこで気の利いたシステムを作れば、後々調整段階に入ったときに圧倒的に楽になります。
そういった意味で、メインマイコンを一つにするのは半年後の自分を大いに助けると思います。

また、メインマイコンを一つにするために、UART通信でモータ6個制御します！みたいな回路を作っておけば汎用性が高いので、次の年のロボコンにも使えるかもしれないですね？

2022年の愚痴みたいな記事になってしましましたが、おかげで書き上げた私はかなりすっきりしています（2022年10月末時点）。また、気力と体力があれば、他にも記事を書いていこうと思います。
wsl2で、systemdを使う（2022年10月21日）

## まず、WSLをMicrosoft Store経由でアップデートする

※ Windows 11 Professional 22H2 で確認。Windows10 や 21H2 とかだと不明

* 予めWSLそのものはインストールしておくこと。
* Microsoft Store経由でアップデートできるようにする（`wsl.exe --update`コマンドでアップデートさせる）
* `wsl,exe --version`コマンドで、以下のバージョンになったことを確認する
* WSL バージョン: 0.70.0.0（もしくはこれより最新版）
* お好きなディストリビューションをインストールする（自分はAlmaLinux9で確認）
* AlmaLinux9など、ディストリビューションを立ち上げ入る
* `vi /etc/wsl.conf` で開き
```
[boot]
systemd=true
```
を追加しておく
* とりあえず、`wsl.exe --shutdown` と `wsl.exe --start AlmaLinux9` として再起動させ、wslのlinuxに入って `systemctl status hogehoge` として、`PID1 hoge` みたいなのが出なければ使えるようになったよ判定できるかと。

将来的には、この wsl.conf に書かなくてもよくなるとかありましたが、0.70では、入れないと systemctl を実行しようとすると PID1 エラーが出る状態でした
Motor-vehicle dynamics , ボッシュ自動車handbook 11版(32) p.470

 Motor-vehicle dynamics  , ボッシュ自動車handbook 11版(32)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

#  Motor-vehicle dynamics
p.470

## Characteristics of vehicle dynamics

Table 1 QUantities and Units

## Dynamics of linear motion 

## Dynamics of lateral motion

## Dynamics of vertical motion

## Special operating dynamics for commercial vehicles


# Reference
[1] 

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9

ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20221021

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.