OmniAICreator/Qiita-1.07M huggingface dataset:
ロクに勉強してこなかったエンジニアが輪読会参加とかPCA受験に向けて勉強とかしてみた話

# この記事について
40歳でフリーランスから転職をきっかけに会社員エンジニアになって、社内のエンジニアの熱意に影響を受けて勉強をはじめてみた中年エンジニアの感想とか気づきとかです。

# 先に結論
勉強することってほんと良いなと。脳細胞が活性化する気がします。
あと、自分のなかに積み上がってたものの振り返りや、業務でちょっとかじったものをきちんと学ぶことによって自身のなかで体系化できるような気がします。
そんなのすでに知ってるよという人も多いかもしれませんが、自分の中ではほんとうに新鮮な感覚でした。

# 前段:そもそもなんでフリーランスから転職したの？
自分はだいたい30歳〜40歳くらいまでフリーランスでエンジニアをやってました。

ありがたいことに知人に恵まれて、ほぼ空き期間なくコンスタントにお仕事をいただけていましたが、現場で使う技術以外への興味は薄く、読書や（現場で使わない）新しい技術のキャッチアップはほぼしてきませんでした。

このままじゃいけないかな？と思いつつもなんとなく時間が過ぎて、気づけば40歳。
一昔前は「エンジニア35歳定年説」なんて言ってたところから、なんと+5歳にもなってるじゃないか。
このまま50、60になって脳が衰えてしまったらお仕事続けられないかも、どうしよう、といよいよ不安に、、、はなってなかったものの、何もしないと能力（≒年収）も萎んでいくだけかなと思うようになりました。
フリーランスとして絶対的な強みみたいなものは自分では無いと思っていたのと、知人からお仕事をもらえている状況がいつまで続くかわからないというのも、会社員になろう、と思う一つのきっかけだったような気がします。

そんな折に今の会社に入社する機会をいただき、自身に足りないと思っていた技術領域であるクラウドインフラや運用まわりの知識や技術も補強できるかと思い転職を決めました。

# で、なんで勉強（読書）したの？
エンジニアが半分以上という会社の中で、社内輪読会が実施されてるのを見て「なんだか面白そうだから参加してみよ」っと飛び込んでみたのがきっかけです。

当時の輪読会では、「SREの探求」を読んでいて、SREについてネット上でさらって見たぐらいの知識で全然知らない領域だったので、輪読会中に知らない単語とか出てくるたびに裏でめちゃくちゃググってました笑
> SREの探求:https://www.oreilly.co.jp/books/9784873119618/

ちなみに今は「SREの探求」の輪読会が終わって「ソフトウェアアーキテクチャの基礎」の輪読会になっています、これも面白い。
> ソフトウェアアーキテクチャの基礎:https://www.oreilly.co.jp/books/9784873119823/

PCAについては、今までのお仕事的にAWSを扱うことが圧倒的に多くて、自身の担当プロダクトはGCP上なので、ちゃんと勉強してみたかったのと、自社がGoogleのパートナーということもあり、資格試験のバウチャーがもらえたというのも大きかったです。

# 勉強（読書）して気づいたこと
SREってなんか遠そう、とか思ってたのが意外と、今まで出会ってきた現場でも見てきたしある程度体験してきたな、ということが多かったのが少し意外でした（「10章 大企業でSRE導入の道を開く方法」とか「31章 複雑なシステムのためのエレジー」とか）
が、よく考えると今までも運用周りのチームの人と協働する機会も多く、また小さなサービスでは自身も運用作業を行うことも多かったので、過去の体験が実はSREに近い、というかまんまDevOpsをやっていたということに、改めて気づかされました。

また、「44のアンチパターンに学ぶDBシステム」の2章輪読会の参加者コメントから出てきた指数バックオフによるリトライ処理についても、PCAの模擬問題の中にでてきてハッとなったり、PCAの模擬問題の中でもGCPに関係ない、MySQLについての知識の問題があり、それを迷わずに正解できたという体験からも、過去の自身の知識を見返してさらに補強できる感覚もありました。

※余談ですが輪読会でも次第にNotion記事にコメント入れたり、Slackのハドルスレッドで発言したり（ほぼ茶々ですがｗ）して、他部署の人とも交流できるようになってきた気がします（Notion＋Slackのハドルで実施しています）

# 最後に
正直いうと最初は勉強や読書の習慣がなく、時間を作ることがかなり苦痛でした。
が、今では知らないことを知れるのが刺激になって本当に楽しくなってきています。
まだまだ知らないことはたくさんありますが、少しでも知識を積み重ねて、今後は実際の業務にも活かしていきたいなと思っています！
3Dプリンターの印刷開始時間変更方法

# 目的
3Dプリンターを朝起動して、でかけている間に印刷したいですよね。
ただ、朝一番は音的に良くないかなと心配になります。

そこで、起動後一定時間あとに印刷開始するように設定する方法を説明します。

# 条件
Cureなどでg-codeを生成して実行していること

# やり方と仕組み
g-code内のG4コマンド（ドウェル：一定時間待機）をg-code中に挟む。

中華系3Dプリンターによく使われるMarlinというfirmwareの場合は

https://marlinfw.org/docs/gcode/G004.html

```
G4 P10
```
は**10ms待機**

```
G4 S100
```
は**100s待機**
を意味します。

## g-codeについて
g-codeは工作機械などNC装置（数値制御装置）一般で昔から使われているプログラミング言語です。

https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E6%95%B0%E5%80%A4%E5%88%B6%E5%BE%A1


g-codeの

* G～に関してはNC装置全体で一般化された内容
* M～に関しては3dプリンター・NCフライス盤など機種ごとに自由に設定できるコードです。

ちなみに、g-codeは現行のマシニングセンターや生産設備で普通に使われています。
可読性はゴミofゴミですが、これが一般的です。ゴミポイントを上げると

* 変数名が#1~#300 みたいな番号式
* インデントなし
* 関数名（サブプログラム）も番号式

という感じでアセンブラに近いです。

# どこにG4を入れるか
とりあえず、Cureで生成したg-codeの先頭の意味を調べましょう。
以下は生成したg-codeの先頭部分です。

```
M140 S50   //ベッド温度50度
M105       //ホストに温度センサの値を返す
M190 S50   //ベッドが50度になるまでまつ
M104 S220  //プリンタノズル温度220度
M105       //ホストに温度センサの値を返す
M109 S220  //ホットエンドの温度が220度まで待つ

M82 ;absolute extrusion mode
G28 ;Home
G1 Z15.0 F6000 ;Move the platform down 15mm
;Prime the extruder
G92 E0　　　//現在のエクストルーダーの位置を0とする
G1 F200 E3 //エクストルーダーを3mm出す
G92 E0
G92 E0
G92 E0
G1 F1500 E-6.5
;LAYER_COUNT:49
;LAYER:0
M107       //プリンタ fan off (1層のみ)
G0 F3600 X63.083 Y64.122 Z0.3
;TYPE:SKIRT
・
・
・
```
一番最初に、温度設定をしているので、一番先頭にG4を入れればいいということですね。

```
G4 S7200
;FLAVOR:Marlin
;TIME:8849
;Filament used: 5.30532m
;Layer height: 0.2
;MINX:55.875
;MINY:55.875
;MINZ:0.3
;MAXX:164.125
;MAXY:164.125
;MAXZ:9.9
;Generated with Cura_SteamEngine 4.7.1
M140 S50
M105
M190 S50
M104 S220
・
・
・
```
こんな感じ

# 検証
5年前ぐらい前に買ったALUNARの3Dプリンターで試したところ、無事印刷開始を遅らせることができました。

https://www.amazon.co.jp/stores/ALUNAR/ALUNAR/page/219FCEDD-A055-4D33-BCDB-7927403E0620
【Android版】ONLYOFFICE Documents 5.7：DocSpaceとの連携、ファイル共有、UXとセキュリティ

[ONLYOFFICE Documents](https://play.google.com/store/apps/details?id=com.onlyoffice.documents)のAndroid版をバージョン5.7にアップデートしました。このリリースでは、DocSpaceへの接続、ドキュメントでの新しいアクション、より多くのセキュリティ、そしてモバイル編集をより簡単にするためのインターフェイスの改善が行われました。

## DocSpaceとの連携

ONLYOFFICE DocSpaceに保存されたドキュメントにAndroidモバイルデバイスからアクセスできるようになりました。

*どこにあるのか：クラウド -> ONLYOFFICE DocSpace*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/d538a7d9-4736-94dd-1632-fc1541d904d8.png)


## ファイル共有、書き出し、保存

Bluetooth、メッセンジャー、電子メールなどを介してファイルのコピーを送信する機能、そしてAndroidデバイス上で必要な形式でファイルをエクスポートして保存する機能を追加しました。

*どこにあるのか：設定 -> コピーを送信 / 書き出し /名前を付けてダウンロード*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/6c185b6b-8aca-f34c-d0d7-811f990cedd8.png)


## オートシェイプと表でテキストを縦に揃える

このバージョンから、シェイプとテーブルでテキストを垂直に揃えることができます。

*どこにあるのか：シェイプまたはテーブルを選択 -> テキスト -> 縦揃えの種類を選択（上、中央、下）*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/c471b605-6430-fdf1-d080-f5621897dee8.png)


## テキスト文書の保護
閲覧、フォームへの入力、変更履歴、コメントのために開かれたテキスト文書を保護します。ファイルの暗号化も再設計され、改善されました。

*どこにあるのか：設定 -> 保護 -> ドキュメントの保護*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/d285e14a-03a3-bdb4-68e2-5811368c53a6.png)


## 数式のヒント

スプレッドシートに数式を入力すると、適切な構文がヒントに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/a63ce2a5-9e83-82b8-aad8-1ffaf2cf61e0.png)

## UXの改善

ONLYOFFICE Documents、Android版のバージョン5.7では、モバイル編集を完璧にするために、多くのパフォーマンス向上が施されています。

* インターフェーススタイルの統一
* ダイアログの再設計
* アプリの言語変更

ONLYOFFICE Documents 5.7をお使いのAndroidスマートフォンやタブレットに今すぐ無料で。

[**今すぐダウンロード**](https://play.google.com/store/apps/details?id=com.onlyoffice.documents)

## お役立ちリンク

* ONLYOFFICE Docs 7.4の新機能。[投稿を見る](https://www.onlyoffice.com/blog/ja/2023/06/onlyoffice-docs-7-4?utm_source=qiita&utm_medium=article&utm_campaign=android5-7)
* ONLYOFFICE DocumentsのAndroid版とは？[関連ページを見る](https://www.onlyoffice.com/ja/office-for-android.aspx?utm_source=qiita&utm_medium=article&utm_campaign=android5-7)
* すべてのONLYOFFICEモバイルアプリを見る。[WEBサイトを見る](https://www.onlyoffice.com/office-for-android.aspx?utm_source=qiita&utm_medium=article&utm_campaign=android5-7#mobile)
Macに日本語インラインパッチをあててEmacs30をインストールする

久しぶりにMac環境にEmacsをインストールする機会があったので、備忘録になります。

## brew tap

Homebrewの[emacs-plus](https://github.com/d12frosted/homebrew-emacs-plus)を使ってEmacsをインストールしていきます。まずはリポジトリをタップします。

```bash
$ brew tap d12frosted/emacs-plus
```


## インラインパッチのsha256ハッシュ値取得
[こちら](https://github.com/takaxp/ns-inline-patch)のインラインパッチを使わせて頂きます :bow:   
パッチファイルをダウンロードしたら、ファイルのsha256ハッシュを取っておきます。

```bash
$ curl https://raw.githubusercontent.com/takaxp/ns-inline-patch/master/emacs-head-inline.patch -OL
$ shasum -a 256 emacs-head-inline.patch
```

## brew edit

`brew edit` コマンドでパッチをあてます。

```bash
$ brew edit emacs-plus@30

# 既にダウンロード済みのEmacsを使って編集したい場合は:
$ HOMEBREW_EDITOR=emacs brew edit emacs-plus@30
```

エディタが開くので、`local_patch` の下に下記の項目を追記します。

```ruby
#
# Patches
#
local_patch "..."
local_patch "..."

# 以下を追加
patch do
url "https://raw.githubusercontent.com/takaxp/ns-inline-patch/master/emacs-head-inline.patch" # Patch URL
sha256 "..." # 先程取得したSHA256の値
end
```


## brew install  

最後に `brew install` でインストールします。(オプションはお好みで)

```bash
$ brew install emacs-plus@30 --with-imagemagick --with-native-comp --with-poll
```

ビルドが終わり、正常にEmacsが起動したら、`M-x mac-ime-toggle`、 `M-x mac-ime-activate`、 `M-x mac-ime-deactivate` 等のコマンドが使えるか確認します。使えていたら成功です。

## おまけ

[Alfred](https://www.alfredapp.com/) がemacs-plusでインストールしたEmacsを見つけられない場合があるようです。私の場合、[こちらのコメント](https://www.alfredforum.com/topic/16578-alfred-not-finding-homebrew-apps-on-m1-opthomebrew/#comment-92630)の手順を試したところ、無事見つかるようになりました。
【WordPress】画面表示がおかしい！

:hatching_chick::sweat_drops:ローカル環境でWordPressで作ったサイトを表示したら画面崩れが発生した！

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473595/c40ae3af-0399-ef7e-8ad2-637ead720f71.png)

:computer:環境
・WordPressバージョン：6.2.2
・ブラウザ：Google Chrome

# 対応内容

### Chromeのキャッシュを削除してみる

① Chromeのウィンドウ内右上「⁝」>「設定」の順に押下

② サイドメニュー内「プライバシーとセキュリティ」を押下

③ 「閲覧履歴データの削除」を押下

④ 「閲覧履歴」「Cookieと他のサイトデータ」「キャッシュされた画像とファイル」のチェックボックス全てにチェックを入れる
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473595/7bca7e1a-60e5-cf67-f70e-cce50a1fffb2.png">

⑤ 「データを削除」ボタンを押下

⑥ 当該ページをリロードする

→事象解消できず:sweat_drops:

### DirectoryIndexディレクティブを設定する

公式ドキュメントの下記を参照

https://ja.wordpress.org/support/article/how-to-install-wordpress/#%e3%82%88%e3%81%8f%e3%81%82%e3%82%8b%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e6%99%82%e3%81%ae%e3%83%88%e3%83%a9%e3%83%96%e3%83%ab

① wordpressディレクトリ直下にある.htaccessファイルを編集

② 下記を追記する
<dd>
<pre>&lt;IfModule dir_module>
  DirectoryIndex index.php
&lt;/IfModule></pre>
</dd>

→事象解消できた!:v_tone1:

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473595/36c933b4-1078-8d97-7687-cfa19ff75390.png)
【Git】.gitignoreの設定を反映させたい！

プロジェクトの途中で``.gitignore``を更新したけれど、すでにコミットしてしまっているファイルは、削除されません。
管理対象から外したファイルをローカルで削除したいという場合はこちらのコマンドを。
```
全てのファイルを削除
git rm -r --cached .
ファイルを指定
git rm -r --cached {ファイル名}
```
UniRxのReactiveCollectionがシリアライズできないので作ったクラス　SerializedReactiveListWrapper

### なんで作ったの
UniRxのReactiveCollectionは便利ですが、シリアライズできないのでinspectorで要素の操作をしたい時に困っちゃいます。なので、シリアライズ可能なReactiveCollectionを暫定的にでも作りたいなーと。

で、作ったのがSerializedReactiveListWrapperです。

### 特徴（制限）
- OnCollectionChangedをサブスクライブすることで監視状態にできます。
- OnCollectionChangedは、要素数が変化したときに発火します。
- ObserveAdd、ObserveRemoveなど細かく監視を分けてはないです。各自コード修正して頂ければ。。。
- 使えるCollectionはListだけです（今後、もっと拡張性高めたくなったらやります）

```cs:使用例
public class IntReactiveList : SerializedReactiveListWrapper<int> { }

[Serializable]
public class TestObject
{
	public IntReactiveList ReactiveList => reactiveList;
	[SerializeField] private IntReactiveList reactiveList = new IntReactiveList();
}

public class User : MonoBehaviour
{
	//通常は別のクラスで定義して使うパターンがほとんどだろうけど、簡単のためこっちにインスタンス化。
	TestObject testObject = new TestObject();
	
	private void Start()
	{
		testObject.ReactiveList.ObserveCollectionChanged
			.Subscribe(_ => Debug.Log("ReactiveListの変更を検知しました。"))
			.AddTo(this);
	}
}
```


```cs:SerializedReactiveListWrapper.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;

[Serializable]
public abstract class SerializedReactiveListWrapper<T> : IList<T>
{
    [SerializeField] protected List<T> collection = new ();
    
    /// <summary>
    /// 要素のあらゆる状況変更時に一律発行されるイベント
    /// </summary>
    public IObservable<Unit> ObserveCollectionChanged => observeCollectionChanged;
    protected readonly Subject<Unit> observeCollectionChanged = new Subject<Unit>();

    // 要素数の保存用
    protected int indexCount = 0;

    /// <summary>
    /// 要素数が変化したら発行
    /// </summary>
    protected void Trigger()
    {
        if(indexCount != collection.Count)
        {
            indexCount = collection.Count;
            observeCollectionChanged.OnNext(Unit.Default);
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return collection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Add(T item)
    {
        collection.Add(item);
        Trigger();
    }

    public void Clear()
    {
        collection.Clear();
        Trigger();
    }

    public bool Contains(T item)
    {
        return collection.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        collection.CopyTo(array, arrayIndex);
    }

    public bool Remove(T item)
    {
        var result = collection.Remove(item);
        Trigger();
        return result;
    }

    public int Count => collection.Count;

    public bool IsReadOnly => false;
    
    public int IndexOf(T item)
    {
        return collection.IndexOf(item);
    }

    public void Insert(int index, T item)
    {
        collection.Insert(index, item);
        Trigger();
    }

    public void RemoveAt(int index)
    {
        collection.RemoveAt(index);
        Trigger();
    }

    public T this[int index]
    {
        get => collection[index];
        set => collection[index] = value;
    }
}
```
Laravelでインストールしておくコンポーネント

新しいプロジェクトを始めるときに、入れておくコンポーネントの備忘録。
2023年6月27日 Laravel 10 現在。

## Laravel
まずはLaravel本体（sail）をインストール

```
curl -s "https://laravel.build/アプリケーション名" | bash
```

アプリケーション名が「good-project」の場合

```
curl -s "https://laravel.build/good-project" | bash
```

「good-project」のフォルダは自動で作られる。


## 大体どのプロジェクトでも使うコンポーネント

Laravelの設定後にそれぞれのコンポーネントをインストール。

### Laravel Debugbar
https://github.com/barryvdh/laravel-debugbar

デバッグ用のバーが画面下部に表示される。


### IDE Helper Generator for Laravel 
https://github.com/barryvdh/laravel-ide-helper

開発時IDE用のヘルパ。


### Laravel Breeze
https://readouble.com/laravel/10.x/ja/starter-kits.html#laravel-breeze

ユーザー認証機能追加。
下記Jetstreamのどちらかを使う。


### Laravel Jetstream
https://jetstream.laravel.com/3.x/introduction.htm

ユーザー認証機能追加。


### LaravelCollective HTML
https://github.com/LaravelCollective/html

bladeでのフォーム作成用。


### Doctrine DBAL
https://github.com/doctrine/dbal

migration後のDBカラム変更用。


### Laravel Livewire
https://github.com/livewire/livewire

vueみたいなリアルタイム更新ができる。


### Laravel-backup
https://github.com/spatie/laravel-backup/tree/main

Backup用。


### Intervention Image
https://github.com/Intervention/image

画像リサイズ（圧縮）や編集などを行う。
リサイズだけならアップ前にリサイズしたほうが良いかも。
https://bashalog.c-brains.jp/21/03/08-190000.php


### Easy AdminLTE integration with Laravel
https://github.com/jeroennoten/Laravel-AdminLTE

管理画面作成用。


### Log activity inside your Laravel app
https://github.com/spatie/laravel-activitylog

操作ログ記録用。


### Laravel Mix
https://readouble.com/laravel/10.x/ja/mix.html

CSS, JSプリプロセッサ。



## プロジェクトごとに使用

### noCAPTCHA (new reCAPTCHA)
https://github.com/ARCANEDEV/noCAPTCHA

Google reCaptchaをログイン画面に追加できる。


### Laravel Enum
https://github.com/BenSampo/laravel-enum

Enum を使う。


### Laravel Cashier (Stripe)
https://readouble.com/laravel/10.x/ja/billing.html

決済機能（Stripe）を追加できる。


### Laravel Socialite
https://readouble.com/laravel/10.x/ja/socialite.html

SNSでのログイン機能を追加できる。
各SNSはプロバイダーで追加する。
https://socialiteproviders.com/


### Laravel Favorite
https://github.com/overtrue/laravel-favorite

「いいね」機能を追加できる。


### Laravel-tags
https://github.com/spatie/laravel-tags/tree/main

ハッシュタグ機能を追加できる。


### laravel Nestedset
https://github.com/lazychaser/laravel-nestedset

カテゴリなど階層データを扱えるようになる。


### Laraburg
https://github.com/VanOns/laraberg

Gutenbergを使えるようにできる。
【Salesforce認定資格】Salesforce Certified Platform App Builderの受験結果

※本記事は2022年05月に受験した「Salesforce Certified Platform App Builder」の振り返りを記載しています。

## はじめに
デベロッパー資格を受けてから1年以上受験していませんでしたが、デベロッパー資格を持っていれば少ない学習で取れるかと思い挑戦してみました。

## 試験結果
結果は __「合格」__ でした。
試験に関しては時間は余裕がありましたが、いつもより少ない2回の見直しで終了しました。

| 受験料 | 試験時間 | 設問数 | 合格ライン | | 受験日 | 正答率 | 所要時間 |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| 20,000円 | 105分 | 60問 | 63% | | 2022/05/18 | 87.97% | 58分 |

内訳を見ると、全体的に取れていたので知識定着が進んでいる確認ができました。

| 試験内容 | 内訳 | 設問数 | | 正答率 |
| :-- | :-: | :-: | :-: | :-: |
| SALESFORCEの基本 | 23% | 13.8問 | | 85% |
| データモデリングおよび管理 | 22% | 13.2問 | | 84% |
| ビジネスロジックとプロセスの自動化 | 28% | 16.8問 | | 88% |
| ユーザインターフェース | 17% | 10.2問 | | 90% |
| アプリケーションのリリース | 10% | 6.0問 | | 100% |

![Salesforce_Certified_Platform_App_Builder_01_テスト結果詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/4d1d3b87-dff8-3fe7-40ba-857d24d0e22c.png)

## 学習方法
受験を急に思い立ったので、受験に向けた学習は受験ガイドを読むことしかしていません。
受験ガイドを読んでみて、これまでのアドミニストレーター資格やデベロッパー資格の範囲と重複している部分が多いことと、実務でフローを大量に構築していたため、追加で学習する必要はないかと思いました。

## 学習の意識付け
アドミニストレーター資格やデベロッパー資格の範囲と重複している部分が多いため、2つの学習を行っておけば受かりはするのかなと思いました。
2つの資格でカバーできない部分は、フローと承認プロセスの具体的な構築部分ですが、具体的な内容を問われる問題は少ないので大きな問題にはならないかと思います。
.ipynbを.pyに変換する方法

# 概要
機械学習のコードを`.ipynb`ファイルで実装していたが、実行に非常に時間がかかるので、GPUサーバー（Ubuntu Server）でバックグラウンド実行したくなった。`.ipynb`だと扱いにくいので、`.py`に変換し、`nohup`で実行したい。

# 前提
- Python環境があること
- Jupyter環境があること

# 手順
1. `nbconvert`のインストール
変換には`jupyter nbconvert`を使うので、nbconvertをインストールする必要がある。

```sh
pip install nbconvert
```

↓詳しくは
https://github.com/jupyter/nbconvert
https://nbconvert.readthedocs.io/en/latest/

2. 変換
以下を実行するとpythonファイル（`<ファイル名>.py`）が生成される。

```sh
jupyter nbconvert --to python <ファイル名>.ipynb
```

# まとめ
その他の形式への変換も可能です。知りたい方は以下を参照してください。

https://kakakakakku.hatenablog.com/entry/2022/06/28/223225
【MT5】【XMTrading】デモ口座のログインで詰まった時の対処法

# 初めに
この記事はXMTradingでデモ口座を開設しMT5へログインする際に詰まった点と解決法の備忘録です。
本記事と同様の問題が発生しているがXMTrading以外のブローカーを利用している場合、本記事で紹介する対処法では解決しない可能性があることをご了承ください。


# サーバのドロップダウンリストに「XMTrading-MT5」が存在しない
以下の「サーバ:」を押下したときに、「XMTrading-MT5」が表示されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3100878/dfc44dc1-6890-e358-e0bf-439e8a03aa51.png)

## 解決手順

### 1. 「会社一覧」で「Tradexfin Limited」を検索する
以下画像のように「Tradexfin Limited」が表示されていることを確認してください。
※検索前から存在する場合はこの手順を省略してOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3100878/cfcae629-a7d6-58bd-ae51-13a632075efe.png)

### 2. 「会社一覧」で「XMTrading」を検索する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3100878/16397ce4-18d7-d623-db8c-782ff6203ce6.png)


### 3. 「取引口座にログイン」からログイン
「XMTrading-MT5」が表示されていれば解決です。
「取引口座にログイン」は上部メニューの「ファイル」＞「取引口座にログイン」で開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3100878/fb306e84-581f-ae93-9d18-d6745ce455d4.png)

# 参考サイト
https://kichiten.jp/how-to-add-server/
CSSプロパティまとめ　（多分時々更新）

<h3>box-sizingボックス サイジングプロパティ</h3>

要素のボックスサイズをどのように算出するか指定できるCSSプロパティです。

このプロパティの値にborder-boxを指定すると、要素のボックスサイズにpaddingとborderを含めるようになります。

たとえば、ある要素にwidth: 300pxを指定し、あわせてpadding: 0 20pxとborder: 2px solid #888を指定すると、横幅は300 + 20×2 + 2×2で合計344pxになります。これでは、横幅300pxのつもりでレイアウトを作成したとき、表示が崩れてしまうでしょう。

このような場合、要素にbox-sizing: border-boxを適用し、paddingやborderを指定してもボックスサイズに含まれるようにして、横幅を300pxに維持させます。
要素のサイズに影響を及ぼすCSS（paddingなど）を記述した場合の対処法として、以下のようにbox-sizingプロパティを追記します。
```css
* {
  box-sizing: border-box;
}
```
これで、paddingやborderの設定を行っても、要素の大きさはwidthやheightで指定したサイズのまま変わらなくなります。

また、上記で設定している「*」というセレクターは、すべての要素に適用させるという意味です。
あるクラスから別クラスを呼び出す方法-忘備録-【UnrealC++】

## 概要
あるクラスから別のクラスを呼び出す方法を忘れてしまうので、知っている範囲でまとめていきます。

:::note warn
・この記事のクラス名は全てSample + クラス名とします。
・引数からキャストする方法は除外することにします。
:::

***

## Characterクラスから別クラスを呼び出す

```c++:SampleCharacter.cpp
// GameMode
ASampleGameMode* SampleGameMode = SampleGameMode == nullptr ? GetWorld()->GetAuthGameMode<ASampleGameMode>() : SampleGameMode;

// GameState
ASampleGameState* SampleGameState = Cast<ASampleGameState>(UGameplayStatics::GetGameState(this));

// PlayerState
ASamplePlayerState* SamplePlayerState = SamplePlayerState == nullptr ? GetPlayerState<ASamplePlayerState>() : SamplePlayerState;

// PlayerController
ASamplePlayerController* SamplePlayerController = SamplePlayerController == nullptr ? Cast<ASamplePlayerController>(Controller) : SamplePlayerController;
```
<br>

## GameModeクラスから別クラスを呼び出す

```c++:SampleGameMode.cpp
// GameState
ASampleGameState* SampleGameState = GetGameState<ASampleGameState>();

// PlayerController (全てのコントローラーを取得しています)
for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It)
	{
		ABSamplePlayerController* SamplePlayer = Cast<ASamplePlayerController>(*It);
	}
```
<br>

## GameStateクラスから別クラスを呼び出す
```c++:SampleGameState.cpp
// PlayerController
ASamplePlayerController* SamplePlayer = Cast<ASamplePlayerController>(GetWorld()->GetFirstPlayerController());
```
<br>

## PlayerStateクラスから別クラスを呼び出す
```c++:SamplePlayerState.cpp
// Character
ASampleCharacter* SampleCharacter = SampleCharacter == nullptr ? Cast<ASampleCharacter>(GetPawn()) : SampleCharacter;

// PlayerController
ASampleController* = SampleController == nullptr ? Cast<ASamplePlayerController>(SampleCharacter->Controller) : SampleController;
```
<br>

## PlayerControllerクラスから別クラスを呼び出す

```c++:SamplePlayerController.cpp
// Character
ASampleCharacter* SampleCharacter = Cast<ASampleCharacter>(GetPawn());

// GameMode
ASampleGameMode* SampleGameMode = SampleGameMode == nullptr ? Cast<ASampleGameMode>(UGameplayStatics::GetGameMode(this)) : SampleGameMode;

// GameState
ASampleGameState* SampleGameState = Cast<ASampleGameState>(UGameplayStatics::GetGameState(this));

// PlayerState
ASamplePlayerState* SamplePlayerState = SamplePlayerState == nullptr ? GetPlayerState<ASamplePlayerState>() : SamplePlayerState;
```
<br>

## ほかにも
```.cpp
// その他
UGameplayStatics::GetAllActorsOfClass(this, 呼び出したい任意のクラス::StaticClass(), クラスを格納する任意の変数);
```

***
Ender3にESP3Dを導入した

# 無線化したい
いちいちSDカードを抜いてpcにさしてデータ書いて抜いてさし直すのが面倒
pcでボタンポチるだけで印刷できたら最高

## OctoPrint
RaspberryPiに入れてプリンタのUSBと繋ぐことで無線化できる

https://octoprint.org

- メリット
    - 情報がいっぱいある
    - Klipper(簡単に言うと印刷品質が向上するやつ)が使える
    - USBと電源だけ繋げば良い
- デメリット
    - 起動に時間がかかる
        - ラズパイとは言えPCを起動することになるので
    - ラズパイの入手性の悪さ
        - 高い
        - そもそも品薄で売ってない
    - 消費電力
        - オーバースペック感ある

## ESP3D
ESP8266/ESP32に入れてプリンタのシリアル線と繋ぐことで無線化できる

https://github.com/luc-github/ESP3D

- メリット
    - ESPの入手性の良さ
        - チップ単体なら秋月で¥300~¥600程度
    - 起動が数秒
    - 物理的に小さい
- デメリット
    - 情報が少ない
    - プリンタの改造(非破壊)が必要
        - 細かな半田付け
        - USB OTG対応のESPなら要らない
    - SDカードの読み書きがすごく遅い(後述)

# ESP3Dの導入
## 用意したもの
- ESP32-WROOM-32E モジュール ¥480
- 128x64 SSD1306 白色OLEDディスプレイ ¥580
- UEW、ビニール線、ピンヘッダ&ソケット等適当な配線材

## ESP側の準備
### PlatformIOのインストール
エディタの拡張として入れる方法が主流
普段使っている環境が汚されるのが嫌なのでCLIのみインストール

pipでインストールするとライブラリのバージョン違いで色々と問題が起きる
公式が良さげなインストーラを用意している

https://github.com/platformio/platformio-core-installer/blob/develop/get-platformio.py

これをダウンロードして`python get-platformio.py`する
ユーザーフォルダ直下にインストールされる

恐らくどの階層で実行しても大丈夫

`pio`コマンドが動く事を確認する

### ESP3Dの用意
https://github.com/luc-github/ESP3D

このリポジトリを丸々ダウンロード
platformio.iniがある階層でpioを走らせると良い感じに全部やってくれる
異なるボードを使う場合はplatformio.iniの編集が要るかも
今回は生のモジュールを使ったためiniは特に編集はしていない

#### `esp3d/config.h`の編集 *!important*
このまま使うと上手くシリアル通信ができないのでTXは別ピンを指定する必要がある
ここら辺は[別記事](https://qiita.com/McbeEringi/items/c564a1a35df272217fdd)にまとめた
```diff_c
- #define ESP_RX_PIN -1
- #define ESP_TX_PIN -1
+ #define ESP_RX_PIN 2
+ #define ESP_TX_PIN 0
```
書き込みの関係上io0は引き出してあったのでTXに割り当てた
片方だけ-1はできない模様

その他OLEDを用意したのでそのピン番号を書いた


諸々の編集が終わったあと
[自家製ライタ](https://qiita.com/McbeEringi/items/d72c793d7fb079dc6997)でpcと接続して

```
pio run -e esp32dev -t upload
```

で書き込んだ

#### index.html.gz のアップロード
書き込んでしばらくするとSSID: ESP3Dが現れる
パスワード: 12345678を入れて192.168.0.1にアクセスすると
index.html.gzが無いよと言われるので`esp3d/data/index.html.gz`をアップロードする


## Ender3側の準備
うちのEnder3のメインボードはv4.2.2でstm32互換のチップが載っていた
このチップとUSBシリアル変換のch340gが繋がっている配線がある
これを引き出してespに繋げる

| CPU | CH340G | ESP32 |
|:-:|:-:|:-:|
| TX | RX | RX |
| RX | TX | TX |

![IMG_2404.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479627/4c7da5f4-d9aa-349c-4043-2ec992d859fd.jpeg)

今回はch330gの足からUEWで引き出した
ESPの電源はそこら辺に生えていたデバッグ端子から適当に引き出した
古いボードは5vらしいので3.3vである事を確認しておく

## 配線
ESP32にGND, 3.3v, TX, RXを繋ぐだけ
OLEDは必要に応じて
![IMG_2420.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479627/97066741-5132-a676-0f04-55f5cbe17f9d.jpeg)

# 動いた
![IMG_2414.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479627/de48d0bd-de29-be45-3f74-a0d248fd3d38.jpeg)
![IMG_2419.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479627/acf5e337-5253-d792-96c6-6c0c38623baa.png)

# SDカードのアップロードが遅い問題
配線が ESP>プリンタcpu>SDカード な以上
ESPがSDにアクセスするにはgcodeのプロトコルを使うしか無い模様
現在アルファ版のESP3Dv3.0は直接結線することで解決できる模様
テストCI実行時間を半分にした話

# はじめに
株式会社HRBrainでフロントエンジニアをやっているしっぽくんです。最近は担当プロダクトの脱monorepoだったりアーキテクチャ見直し、エラーログ解析などの改善作業を業務の傍らやっております。

今回はその中でCI時間の短縮を行ったよ、という話をします。

かなりターゲットは限定的なので、該当する人に届けばいいなと思います。

# ターゲット（これらに合致する人向けです）

- 利用技術スタック
    - TypeScript を使っている
    - テストプラットフォームは `Jest`
    - TypeScript のトランスパイルに `ts-jest` を使っている
- CI時間が長くなり始めた

# TL;DR

- `@swc/jest` でトランスパイルするようにした
    - CIの実行時間が14分から6分の約半分ほどになった
- `jest.spyOn` は使えないので、 `jest.mock` に書き直した
- より早くしたい場合は `vitest` や `Bun` への移行を視野に入れよう

# テストCIがいつまでも終わらないんだけど?!

弊社では GitHub Actions を使いCIを回しています。日々の開発のなかでプルリクを出しプロダクトにコミットを積み重ねていきますが、軽微な修正でもなかなかCIを終わらないことに気づきました。

![遅いCI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202715/fa5195f6-95da-8459-f108-60b452305cc5.jpeg)
> え、CI完了までに14分もかかってる?!

テストケースもそれなりにありますが、とはいえ14分はかかりすぎです。豆を挽いてコーヒーを1杯入れる時間すらあります☕️

# 遅さの原因

端的に言えば ts-jest で型も含めたトランスパイルを行っていることが原因でした。

```js
// jest.config.js
"transform": {
  "^.+\\.(ts|tsx)?$": "ts-jest"
},
```
> 設定ファイルに書いてたこれ

ではトランスパイルをしないようにすればいいというわけです。
とはいえメイン業務もあるので大きく変更するのは難しいです。（コスパよく対応したい...
そこで `@swc/jest` が候補に挙がりました。

https://swc.rs/docs/usage/jest

> To make your Jest tests run faster, you can swap out the default JavaScript-based runner (ts-jest) for a drop-in Rust replacement(opens in a new tab) using SWC.

設定もシンプルでほとんど差し替えする程度でした。（実際には設定ファイルを1つ追加しましたが、環境ごとに書く設定も違うので出しません）
```js
module.exports = {
 transform: {
 "^.+\\.(t|j)sx?$": "@swc/jest",
 },
};
```

適当に設定を書き換えし実行してみました。
![差し替えのみ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202715/94469e7f-989f-6255-a5ab-d7024f000025.jpeg)
> 見事に半分以下に!

しかしそう簡単に移行はいかず、エラーがいくつか発生しました。（CI結果も落ちている😭）

# 立ちはだかる壁

ログを見ると複数のテストがこけており、中身はどれも jest.spyOn をつかっている場所でした。
エラー例： `TypeError: Cannot redefine property: xxxx`

調べてみると `spyOn` ではモジュールとしてインポートしたオブジェクトを書き換えています。 ECMAScript Modules（ESモジュール）ではモジュールの書き換えが基本的には不可能のため `spyOn` を利用している箇所で書き換えに失敗した結果になりました。

幸い `spyOn` を利用している箇所も少なかったため、　`mock` への置換を行うことで対処することにしました。

:::note warn
Jestは最新バージョンでESモジュールに対応しつつあるため、バージョンによっては今回の対応は不要になるかもしれません。
:::

マイグレーション作業を下記で実施しました。

```ts
// spyOn実装
import HogeModule from 'hoge'
const spy = jest.spyOn(HogeModule, 'hogeMethod')

expect(spy.hogeMethod).toHaveBeenCalled()
```

```ts
// mock実装
jest.mock('hoge', () => {
  ...jest.requireActual('hoge'),
  hogeMethod: jest.fn()
})

import HogeModule from 'hoge'

expect(HogeModule.hogeMethod).toHaveBeenCalled()
```

## 改善結果

最終的には install ステップもキャッシュ対応し実行時間の改善することができました👏

![改善結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202715/f773cae3-765a-bb1c-0547-96dcce4b742e.jpeg)
> installもcache対応してテスト自体は4分に！

# まとめ

遅いなと思ってから実装完了まで2時間半程度（内マイグレーション作業が2時間ほど）で改善できました。
設定ファイルだけ差し替えてCI回すだけならすぐ出来るので、まだ `ts-jest` 使っているよ！という方は検討してみてください。

ちなみに `Vitest` や `Bun` への移行でさらに早くなるらしいのでより速さを求める人はこちらを。

https://twitter.com/colinhacks/status/1673408135720239104?s=20


# 参考文献
https://nodejs.org/api/modules.html

https://github.com/kulshekhar/ts-jest

https://github.com/swc-project/swc/discussions/7024

## spyOnの実装

https://github.com/jestjs/jest/blob/3da370f58b20791fd98c7b7654853dfd9b8a043d/packages/jest-mock/src/index.ts#L1154C27-L1154C27
[ServiceNow] 読み取り専用のReference列の[i]マークの表示制御

# 概要
Reference列の横の[i]を選択すると、値として選択されているレコードのプレビュー画面が表示される。
※この[i]マークは「参照フィールドアイコン(reference icon)」と呼ぶらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920664/669f191a-51b5-bdbb-0342-2270586fdefa.png)

ただし、Reference列が読み取り専用の場合、[i]は表示されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920664/d18fc6d7-a324-6755-aa40-aad4b921c7a8.png)

本書では、読み取り専用のReference列に対して[i]を表示するための設定を記載する。

# 設定方法
## その１）System propertyでの制御

読み取り専用のReference列に対しての[i]の表示は、以下のシステムプロパティによって制御されている
* Name: glide.ui.reference.readonly.clickthrough
* デフォルト値: false

このプロパティ値を**true**にすることで、読み取り専用でも[i]が表示されるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920664/28d2c7e6-cd77-d94c-f1d2-7e2aaeb1fa36.png)

この方法はシステムプロパティによる設定のため、インスタンス全体に影響する。
個別で特定のカラムのみ表示したい場合は「その２」の方法で実施する。

## その２）Attributesでの制御

設定対象カラムのAttributesに`readonly_clickthrough=true`を追加することで、読み取り専用でも[i]を表示されることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920664/5550a51f-d5e8-6e3d-44d6-9e15d318a1cb.png)


## 設定後確認

どちらの方法でも実際に設定後、読み取り専用でも[i]が表示されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920664/0830f25d-d668-affd-5220-f12446de7e3f.png)
[FCM] the legacy Firebase Cloud Messaging (FCM) APIs 廃止予定のお知らせ

先日、とあるプロジェクトにてGoogleから以下のようなメールが届きました。

>We’re writing to let you know that starting June 20, 2024 the legacy Firebase Cloud Messaging (FCM) APIs will be discontinued.
>
>Your Firebase project(s) that use Firebase Cloud Messaging APIs are listed below:
>
>1. project_name (project_id)
    1. Your recent usage of impacted APIs/features: Server Keys
    2. Your recent usage of impacted APIs/features: Legacy HTTP protocol
>
>1. project_name_stg (project_stg_id)
    1. Your recent usage of impacted APIs/features: Legacy HTTP protocol
    2. Your recent usage of impacted APIs/features: Server Keys

どうやらFCMの話のようです。

## the legacy Firebase Cloud Messaging (FCM) APIs will be discontinued.

関連するFirebase公式ページとしては、この辺りになりそうです。

https://firebase.google.com/docs/cloud-messaging/migrate-v1?hl=ja

移行についてのアナウンスは前からあると思われますが、メールの内容の限りでは、**2024年6月20日より、レガシーなFirebase Cloud Messaging (FCM) APIは廃止される予定**のようです。

と言われてもアプリエンジニア的には何をすれば良いのか、、:thinking:
FCMのAPIをモバイルアプリから直接使用している箇所はないはずだし、、？
やるとしても、firebase-messagingライブラリを更新するくらいかなと。

モバイルアプリのPush導入は一般的によくあるものだと思いますが、かといって頻繁に触るところでもない。
おさらいがてら、どこを解決していくべきなのかを探ります。

## FCM & App & Backend 構成

モバイルアプリとPush機能の構成については、大まかですが以下のようなイメージです。
![push_flow.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472463/f962a087-37ae-2011-3993-19bedbcade6e.png)
FCMやAPNs経由で取得したデバイストークンをバックエンドに登録させ、何かイベントが発生した時にそのバックエンドからPush通知の送信をFCMやAPNs経由で行う、という流れ。
バックエンド周りはSaaSやBaaSとして提供されていることも多いかと思います。まさに当プロジェクトもPush通知機能の連携にそれらを採用しています。
また、モバイルアプリ→バックエンドの通信(③などにあたる)は、各OSに用意されたライブラリを使って行っています。

FCMのAPIを使用するのは、Push要求を行うバックエンド(Server)であることが多いはず。
そういえば、Push通知サービス管理画面(バックエンド)に**サーバーキー**を設定する必要があったな、、ということを思い出しました。

## Server Key

以下のページでサーバーキーについての説明がありました。

>アプリサーバーによる Google サービスへのアクセス（以前の Firebase Cloud Messaging プロトコル経由でのメッセージの送信など）を承認するサーバーキー。

https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ja

FCM経由でのPush送信などに必要なキーということですね。

さらにこのように続きます。

>サーバーキーは Firebase プロジェクトの作成時に取得します。サーバーキーを確認するには、Firebase コンソールの [設定] ペインにある [クラウド メッセージング] タブに移動します。

そういえばこのような設定がありました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333437323436332f30636130396134312d326336332d353365632d366537302d6131306637366530376462342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472463/c91568a8-c1ea-4a63-bfca-0ba789e94201.png)
そしてこのサーバーキーを、Push通知のSaaS管理画面で設定しています。

Firebaseプロジェクト設定画面からは、サーバーキーを削除・GCPでレガシーAPIを無効化とする必要がありそう。
その前にバックエンドがFCM連携のやり方を変える必要があるか、、？
というところで一旦調査をストップ。

## まとめ
- (現時点での発表では)2024年6月20日より、レガシーなFirebase Cloud Messaging (FCM) APIは廃止となる予定。
- Firebaseプロジェクトで参照するServer Keyを使ってバックエンドとFCMの連携を行うやり方はもうできなくなるかもしれない。

***
(記憶力が終わってる)
憧れの飛天御剣流を俺は出す！（まだ先は長そう）

# 「二重の極み」練習したことありますよね？

30代半ば～40代半ばぐらいの人で二重の極みを練習したことが無い人は恐らくいないでしょう。

今回はスマートフォンに内蔵されている加速度センサーを利用して、るろうに剣心の技が発動するウェブアプリを作ろうとしてみたのでその途中経過です。

https://twitter.com/ghbcKTpFr5rvfE4/status/1672123290981380096?s=20


# 最初に作ったもの

最終目標は「九頭龍閃」ですが、あまりに動きが複雑なので、まずは動きが単純（失礼）な「牙突」から作ってみました。
（飛天御剣流はどこに行った？というのは一旦置いといてください）

スマートフォンから以下のQRコードを読み取ってください。
加速度センサーが必要なので、ブラウザでは動作しません。
![QR_854505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/618ce280-f754-4680-0d9f-340f0e95bed5.png)

牙突の速度によって齋藤一の画像が変わっていくようになっております。
ちょっと分かりにくいですが動画です。

<iframe width="448" height="797" src="https://www.youtube.com/embed/cdutwAzSFbo" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

コードはこちらに記載しております。
https://codepen.io/tbahbiri-the-reactor/pen/rNQjzRy

加速度センサーを使って前後水平方向の動き（X軸）を測定し、X軸の値が10、30、60を超えたときに画像が切り替わるようにしております。

# 使った感想（フィードバック）をもらった

妻：内容知っている人だったら面白いのかもしれないけど、私みたいに知らない人からすると良く分からん。せめて音声ぐらい付けたら。
息子：振ったら画像が変わるの面白い。あと最初の顔が面白い。僕もパソコン欲しい。


# 音声実装（途中）→2023年6月30日実装完了

![QR_105718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/b3b73286-b7d1-adf1-d6ff-34ad1c9ca3c7.png)

コードはこちらに記載しております。
https://codepen.io/tbahbiri-the-reactor/pen/jOQyjrY?editors=1010


音声はこちらで作っています。

https://ondoku3.com/ja/

画像が切り替わるのは最初に上げたものと同じですが、
10＜30
「まだまだだな」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/a8aecd3f-c730-babf-b021-37e6263fb5fd.png" alt="まだまだだな" width="400" height="10">

30＜50（子供でも遊べるように60から10値を小さくしました）
「なかなかやるな」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/6e1bd9e5-7649-7084-ad64-253fe152faab.png" alt="なかなかやるな" width="400" height="10">

50＜
「～免許皆伝だ～」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/72af5de5-232b-4c60-5c30-47c29482858f.png" alt="免許皆伝" width="400" height="10">


と画像だけではなく、音声も出し分けるようにしました。


# 今後に向けて

前後方向だけではなく、左右（Y軸）や前後（Z軸）の動きも組み合わせて他の技も登録するようにしていきたいなと考えております。

お読みいただきありがとうございました。
3.3浮動小数点 3.4誤差

### 浮動小数点
浮動小数点は，実数（小数点の付いた数）を扱う場合に使用する形式で、指数を使い，大きな数や小さな数を固定小数点よりも少ないビット数で表現できます。

#### 浮動小数点の形式
IEEE754，32ビット形式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/f34971e3-ef75-23c1-0cc0-721dc6e8de4a.png)
S：仮数部の符号（0：正，1：負）
E：2を基数として，実際の値に127を加えたバイアス値（後述）
B：絶対値を2進数で表す。1.M（1.xxx…）となるように，桁移動する（正規化）。

7.25をIEEE754で表現すると

① 10進数7.25は正数なので，符号（S）に0を入れます。
0 E B
② 10進数7.25を2進数で表現すると，111.01となり，仮数部が1.M（1.xxx…）になる
ように正規化します。
111.01＝111.01×20
　→（正規化）→　1.1101×22
仮数部（B）の最上位から順に1101，残りのビットに0を入れます。ここで，仮数部の
「1.」はこの形式では自明なので省略されています。1桁節約していることになります。
0 E 110100　…　00
③ 指数部（E）は，2＋127＝129，2進数に基数変換して10000001を入れます。


确定符号位：由于7.25是正数，符号位为0（正数）。

将绝对值转换为二进制形式：7的二进制表示为0111，0.25的二进制表示为0.01。将它们组合在一起得到0111.01。

归一化数：将二进制数0111.01归一化，使小数点位于第一个非零数字的右边，得到1.11101。

计算指数：归一化后的数小数点右移4位，因此指数部分为4。加上偏移量127，指数位为131（二进制表示为10000011）。

表示尾数：将归一化后的数的小数部分提取出来得到尾数部分11101。

组合符号、指数和尾数：将符号位、指数位和尾数位组合在一起得到32位的二进制表示。

最终，十进制数7.25转换为IEEE 754单精度浮点数的二进制表示为：
01000001111010000000000000000000

### 誤差
コンピュータ内部で，数値を指定されたビット数で表現しているために，真の値と表現する値との間に差が発生することを誤差といい。

#### 桁あふれ誤差
表現できる範囲を超えることで発生する誤差。

オーバフロー　表現できる範囲を超えること
アンダフロー　浮動小数点では限りなく0に近づいて表現しきれなくなり発生するアンダフロー

#### 丸め誤差
切捨て・切上げ・四捨五入することで発生する誤差

#### 桁落ち誤差
有効桁数が減少することで発生する誤差
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/38d7670d-d5b3-d728-1f3c-ba19a63ccf7e.png)

#### 情報落ち誤差
小さな数値が計算結果に反映されないことで発生する誤差
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/663e717b-16b0-f2c1-a63d-a85140cd29c0.png)

#### 打切り誤差
計算処理を打ち切ることで発生する誤差　
円周率は3.14159…と続きますが，計算処理を打ち切って3.14とすることによって発生します
【Trailhead】Salesforceの学習の道程（2021/10/01〜2021/12/31）

## 期間内の活動
他の学習を行っていたため、Trailheadを進められませんでした。

## Salesforce認定資格受験履歴
期間内で資格の受験はありませんでした。

## Trailhead学習履歴

|    # | バッジ名                                                    |  種類  |   取得日   | 基準ポイント | 取得ポイント | 合計ポイント |
| ---: | :---------------------------------------------------------- | :----: | :--------: | -----------: | -----------: | -----------: |
| 1129 | Platform Developer I Certification Maintenance (Winter '22) | Module | 2021/12/09 |          500 |          500 |       541975 |

## まとめ記事
https://qiita.com/HNakazawa/items/08c356fcb2c9d1bf3d23
Amazon EC2: 基本から理解する


Amazon Elastic Compute Cloud (EC2) は、Amazon Web Services (AWS) の提供するセキュアでリサイズ可能なコンピューティング容量を提供するウェブサービスです。企業はこれを使って、より容易にアプリケーションをクラウド上で実行できます。物理的なコンピューターを設定する代わりに、EC2 を通じて仮想サーバー（これを "インスタンス" と呼びます）を租借することができます。企業は、ウェブサイトのホスティング、大規模なデータ処理、または他の多くの種類のアプリケーションを実行するために、これらのインスタンスを利用します。

では、実際に EC2 インスタンスを起動してみましょう。

## 1. AWS アカウントの作成と設定

まず最初に、AWS アカウントを作成する必要があります。既にアカウントをお持ちの場合は、この手順をスキップしてください。

1.1 [AWS のホームページ](https://aws.amazon.com/jp/)にアクセスし、「アカウント作成」をクリックします。

1.2 必要な情報を入力し、アカウントを作成します。

## 2. Amazon EC2 インスタンスの起動

2.1 AWS マネージメントコンソールにログインします。

2.2 ナビゲーションバーの「サービス」をクリックし、コンピューティングカテゴリから「EC2」を選択します。

2.3 EC2 ダッシュボードから「インスタンスの起動」をクリックします。

2.4 利用可能な AMI (Amazon Machine Image) リストから適切なものを選択します。今回は「Amazon Linux 2 AMI (HVM)」を選択します。
![スクリーンショット 2023-06-27 午後3.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3479750/95a6a554-7355-6099-30da-326239788cc3.png)

2.5 インスタンスタイプを選択します。初めての場合は、無料枠の「t2.micro」を選択します。その後、「次へ: インスタンスの詳細の設定」をクリックします。

2.6 インスタンス詳細の設定をそのままにして、「次へ: ストレージの追加」をクリックします。

2.7 ストレージの量を設定します。「次へ: タグの追加」をクリックします。

2.8 タグを追加します（オプション）。これは、インスタンスを簡単に識別するためのものです。「次へ: セキュリティグループの設定」をクリックします。

2.9 セキュリティグループを設定します。ここでは新しいセキュリティグループを作成し、SSH 用にポート 22 を開放します。「確認と起動」をクリックします。

※ここで "SSH" と "ポート 22" という用語が出てきました。SSH（Secure Shell）は、安全にリモートコンピューターにアクセスするためのプロトコルです。一般的には、ポート 22 が SSH 接続のために使われます。 "ポート" とは、ネットワーク接続を行うための仮想的なエンドポイントを指します。特定のポート（この場合は 22）を開放すると、そのポートを通じてデータの送受信が可能になります。SSH は、リモートで EC2 インスタンスに安全に接続するために必要です。

2.10 起動前に設定を確認し、「起動」をクリックします。

2.11 新しいキーペアを作成するか、既存のキーペアを使用します。「インスタンスの起動」をクリックします。

## 3. EC2 インスタンスへの接続

3.1 EC2 ダッシュボードから「インスタンス」をクリックします。



3.2 起動したインスタンスを選択し、「接続」をクリックします。

3.3 指示に従ってインスタンスに接続します。

以上で、Amazon EC2 インスタンスの起動と接続が完了です。これで、自由にサーバーを設定したり、アプリケーションをデプロイしたりできます。
システム開発での基本設計書作成のコツ：詳細と網羅性が鍵

# 1. 要件定義書を参考にする
基本設計書作成の最初のステップは、要件定義書をしっかりと理解し、それを基に作業を進めることです。
要件定義書は、システムの全体像を把握するための重要な資料であり、これを基にして設計が行われます。

# 2. システムの構成や機能を図や表で表現する
基本設計書は、システムの全体像を視覚的に捉えやすい形で表現するために、図や表を活用します。
これにより、システムの構成や機能を直感的に理解でき、
また全体の流れや相互関係を明確にすることが可能となります。

# 3. 網羅的な仕様や制約の記述の重要性
あなたが理解しているからといって情報を省略することなく、全ての詳細を記述することが重要です。
例えば、ログイン機能の場合、「ユーザーがIDとパスワードを入力し、システムが認証する」という表現では不十分です。
どのような条件で認証が成功し、どのような場合に失敗するのか？
認証後の画面遷移は？など、全ての詳細を網羅的に記述することが求められます。

不十分な例：
```
1. ユーザーはIDとパスワードを入力する。
2. システムは入力情報をチェックする。
```

網羅的な記述例：
```
1. ユーザーはIDとパスワードを入力する。
2. システムは入力情報がすべて埋まっているかチェックする。
3. もし、すべての情報が埋まっていなければ、エラーメッセージを表示する。
4. 入力情報がすべて埋まっている場合、システムはIDとパスワードが登録情報と一致するかをチェックする。
5. IDとパスワードが登録情報と一致しない場合、エラーメッセージを表示する。
6. IDとパスワードが登録情報と一致する場合、ユーザーをログイン状態にし、トップページにリダイレクトする。
```
# 4. データの送受信における詳細を記述する
システム内でのデータの流れについて詳細に記述することで、システムの動きをより明確にします。
具体的には、データの送受信元と送受信先、データの形式、処理のタイミングなどを明記することが重要です。

# 5. レビューとフィードバックを行う
設計書が完成したら、チームメンバーや関係者によるレビューを行います。
このフェーズは設計の品質を確保し、間違いや見落としを早期に発見するために重要です。

# 6. まとめ
基本設計書の作成は、一見難しそうな作業かもしれません。
しかし、要件を理解し、システムの構成や機能を図や表で表現し、網羅的な仕様や制約を記述し、
データの送受信における詳細を明記することで、十分に作成できます。
また、レビューとフィードバックを行うことで、設計書の品質を更に高めることができます。

以上のポイントを押さえて、より良い基本設計書作成に取り組んでみてください。
BigQueryで 複数キーワードの存在チェック(LIKE IN) したい時

# 背景

キーワードを保存しているテーブル keywordsと、ログを保存している logs テーブルが存在するとします。
keywordsにある文字列が存在するlogsのレコードを取得したい場合どうすればいいでしょうか。
`REGEXP_EXRACT()` を使ってみました。


# テーブル用意

```sql
CREATE TABLE `pj-name.dataset.keywords`
AS
  SELECT
    'こんにちは' as word
  UNION ALL
  SELECT  'こんばんは'
  UNION ALL
  SELECT  'おはよう'

CREATE TABLE `pj-name.dataset.logs`
AS
  SELECT
    'あああこんにちはああ' as message
  UNION ALL
  SELECT  'いいいこんにちはいい'
  UNION ALL
  SELECT  '新規です'
  UNION ALL
  SELECT  'えーおはようございます'
  UNION ALL
  SELECT  'うーこんばんは'
  UNION ALL
  SELECT  'こんこんにちにちは'
  UNION ALL
  SELECT  'こんにちは'
```

# keywordsの存在するログの抽出方法

```sql
DECLARE keywords_str DEFAULT (SELECT ARRAY_TO_STRING(ARRAY_AGG(word), '|') FROM `pj-name.dataset.keywords`);

-- match_knows_messageがNULLなら存在しない
SELECT
  message,
  REGEXP_EXTRACT(message, keywords_str) as match_known_message
FROM `pj-name.dataset.logs`

```

![スクリーンショット 2023-06-27 18.39.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/8e70f4b6-ebbb-1760-b2df-378928fd8f58.png)

# まとめ

`REGEXP_EXRACT()` を使ってkeywordsの存在するlogのレコードを抽出してみました。match_known_messageカラムがNULLかどうかで存在チェックの判断ができるかと思います。
Laravelでレイアウトを共通化する方法

# Laravelでレイアウトを共通化する方法

## レイアウトを共通化するイメージ
全ページに共通するレイアウトを実装したファイルを1つ作成。(親)
↓
各ページで違うレイアウトを実装したファイルをそれぞれ作成。(子)
![レイアウト共通化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/3222558f-461a-7961-4cf3-1be908286137.png)

## 親ファイルを作成する。
①`resource/views`にlayoutsフォルダを作成する。
②1で作成したフォルダに親ファイルを作成する。
　ファイル名：app.blade.php
③2で作成したファイルに、前ページに共通するコードを書く。
④ページごとに違うコードは`@yield`を使用する。
```app.blade.php
<head>
    <meta charset="UTF-8">
    <title>@yield('title')<title>
<head>
```
※引数は子ファイルで呼び出す時に、親ファイルのどの部分かわかるような名前にする。

## 子ファイルにコードを書く。
①親ファイルを指定する。`@extends`を使用する。
```〇〇.blade.php
    @extends('layouts.app')
```
※引数は`resources/view`を省略し、〇.blade.phpの`.blade.php`を省略する。
　階層は`/`ではなく`.`を書く。

②親ファイルに書いた@yieldを置きかえるコードを書く。`@section`を使用する。
```〇〇.blade.php
<!-- 文字列を置きかえる場合 -->
@section('@yieldの引数に指定した名前', '置き換える文字列')

<!-- 複数行のコードを置きかえる場合 -->
@section('@yieldの引数に指定した名前')
    置きかえるコード
@endsection
```
※書き方が2種類ある。

## ヘッダーとフッターを部品化する。
①ファイルを2つ用意し、それぞれヘッダーとフッターのコードを書く。
　ファイル場所：`resources/views/layouts`
　ファイル名：`header.blade.php`、`footer.blade.php`
②親ファイルにヘッダーとフッターのファイルを呼び出すコードを書く。`@include`を使用する。
```app.blade.php
@include('layouts.header')
:
@include('layouts.footer')
```
※引数の書き方は@extendsと同じく、`resources/view`を省略し、〇.blade.phpの`.blade.php`を省略する。
　階層は`/`ではなく`.`を書く。

## アプリ名を共通化する
例：ヘッダーの左側にどのページでも同じものを表示する場合

①HTMLでは以下のように記述する。（例）
```html
<a href="#">
    {{ config('app.name', 'Laravel') }}
</a>
```
↑config('文字列が設定されている場所', '文字列が設定されていない場合に表示する文字列')
例：app.nameに文字列が設定されていない場合は、'Laravel'という文字列を表示する。

②表示される文字列を変更する。
1：`config(app.name)` →config/app.php を見る。
2：app.phpで`name`を探す。
```app.php
'name' => env('APP_NAME', 'Laravel'),
```
3：APP_NAMEが定義されている場所を探す。(Laravelをダウンロードしたフォルダ直下の.envファイルを見る。)
4：.envで`APP_NAME`を探す。
```
APP_NAME=Laravel
```
5：`APP_NAMEの値を変える。`※文字列に`''`はつけなくて良い。
Surface Go 3 for BusinessのNFCリーダーが全然NFCリーダーじゃない件


## TL;DR
**Mifare Ultralightしか対応してなさそうだよ！**
他のType-AやFeliCaとかは読めないよ～

## 導入
Microsoftの主力タブレットシリーズ、**Surface**。
の、廉価版**Surface Go**の、その法人向けモデル**for Business**にはNFCリーダーが内蔵されているのをご存知でしょうか。
正直、ご存知の方は相当なSurfaceマニアと思われます。
[公式サイト](https://www.microsoft.com/ja-jp/surface/business/surface-go-3)の隅っこに小さく書いてるだけですからねコレ。

色々ありまして、**コイツの内蔵NFC機能でどこまでやれんのか**という技術調査を始めたわけなのですが……。

「ン？:thinking:何も読めんが？:sweat_smile:」

となったので、その記録です。

## 検証
つーわけで検証をやっていくワケですが。

### NFCリーダー
先述の通り、メインは**Surface内蔵リーダー**です。どうやらコイツは**NXP P3003**というリーダーを積んでいるみたいです。が、ググっても全然情報がヒットしない……。

対照実験用に、**SONY RC-S300**、いわゆる**PaSoRi**もご用意いたしました。

### 読み取るNFC
NFC、と言われるものには大きく分けて以下の三種があります。
* **Type-A**
	* NXP社製の、いわゆる**Mifare**。Taspoとか
* **Type-B**
	* モトローラ社が主導してるやつ。マイナンバーカードとか
* **FeliCa**
	* 我らがSONYが開発したやつ。Suicaとか

というわけで、上記3種すべてのカードを用意しました。
#### Type-A
* NXP NTAG213
	* 「NFCチップ」といえばだいたいコレ
	* 今回はサ○ワサプライさんのやつを使いました
* Taspo
	* 喫煙者で良かった
#### Type-B
* 運転免許証
* マイナンバーカード
#### FeliCa
* ICOCA
	* 関西人なんで
* そのへんにあった工場出荷状態のFeliCa

### 検証用アプリ
[**PC/SC**](https://learn.microsoft.com/ja-jp/windows-hardware/drivers/nfc/pc-sc-interface) インターフェースに則って、NFCと通信する簡単なアプリを作りました。
すべてのカードが一意に持ち、暗号化されずに公開されている**IDm/UID**の取得を行います（シリアルナンバーみたいなもんです）。

## 検証結果
Surface内蔵NFCリーダーで読み取りに成功したのは**NXP NTAG213**のみでした。ハァ？

ちなみにPaSoRiで検証してみた場合では全てのNFCが読み取れたので、マジで内蔵リーダーが終わってます。

## Type-AはType-Aでも
さて、NTAG213の読み取りには成功したものの、同じType-AであるTaspoは読み取ることができませんでした。
というのも、NTAG213とTaspoに搭載されているNFCチップとでは、以下の通り厳密には異なるチップなんですよね。

|        | チップ            |
| ------- | ----------------- |
| NTAG213 | MIFARE UltraLight |
| Taspo   | MIFARE Standard1K |

上記二種の違いの詳細は各々で調べていただいたらと思いますが、なにせSurfaceくんの内蔵NFCリーダーは**MIFARE UltraLight**しか対応してねー！ってことみたいです。トホホ

## 公式回答
僕が間違ってるかもしれないので、一応Microsoftにも聞いておきました。
回答を抜粋します。

> TypeB 及び FeliCa は対応しておらず、TypeA は対応していますが、Surface に搭載されている NFC は非常に限定的である為、カードの種類によって動作しないものがございます。

まじか～い
ここで言っている「Type-Aは対応していますが～」の下りは、おそらく先述のチップ種別を指すものと思われます。

また、[MicrosoftTechCommunity](https://techcommunity.microsoft.com/t5/surface-it-pro-blog/more-nfc-card-reading-accessories-released-for-surface-go/ba-p/2203298#aXtion)でも、以下のようにNFCサポートが限定的であることが示唆されています。
> Even though we have only limited support for NFC,

ちっちゃくこっそりな。

## 結論
Surface Go 3 for Business のNFC対応は非常に限定的でした。
とはいえ、Surfaceの用途に照らせば、Type-A ULが読めたら最低限支障はないということでしょう。NFCで一番普及しているのがコイツですから。

それはそれでいいんだけど、それはちゃんと書いておいてほしかった。

## 参考（外部リンク）
*  [Surface Go に内蔵されている NFC を試した - しばやん雑記](https://blog.shibayan.jp/entry/20181015/1539533463)
	* 先駆者さま
出力って何？入力って何？

しばしば出力とか入力とか出てきますよね？
じゃあそもそも出力って何？というお話をさせていただこうと思います

例えば車であれば「入力＝ガソリンを入れること」
「出力は＝走ること」になります。
（変数は車ということになります）

そしてこれらをプログラミングに置き換えると

```
int a;
a=10;
print(a);
```
これの結果は10になります

```
10
```

入力はaに「10」を入れること
出力は「10」と表示すること
初ハッカソンで賞を獲得しました！

先日6/24(土)に、「チームで挑戦！ ChatGPTサービス開発ハッカソン」というエンジニアTypeさん主催のハッカソンに出場させていただきました！ハッカソンに参加するのは今回が初めてだったので、緊張しながらも新鮮な雰囲気を感じながら開発を行えました。
ハッカソンのURL : https://type.jp/et/feature/22721/

# 目次
* 参加した経緯
* ハッカソンの概要
* 開発したサービスの概要
* 結果
* 最後に

# 参加した経緯
私は株式会社CODEMGYMでインターン生をしています。CODEMGYMはCODEMGYMAcademyという学生向けプログラミングスクールを運営していて、4期に渡り卒業生を輩出しているのですが、私はそのCODEMGYMAcademyの卒業生コミュニティであるCodeBuildersの企画運営を行っています。そして、再来月の8月にCodeBuilders主催のハッカソンを企画することになりました。しかし、「主催者である私がハッカソン未経験で大丈夫か？」という感情と、これまでの開発経験を評価してもらえる場に参加したいということで今回、エンジニアTypeさんのハッカソンに参加させていただくことになりました！

# ハッカソンの概要
私はインターン生チームのリーダーとして参加することになったのですが、実は弊社CEOのもっちさん(Twitter:https://twitter.com/mocchicc?s=20 )をリーダーとするチームも別チームとして参加していました！この2チームと他6チームの合わせて8チームで、2つの賞(最優秀賞・エンジニアType賞)の獲得を目指すという形で今回のハッカソンは始まりました。審査員はメディアアーティストの落合陽一さん、Rubyの生みの親であるまつもとゆきひろさん、AtCoderの代表取締役の高橋直大さん、Yazawa Ventures CEOの矢澤麻里子さんの豪華4人でした！
今回のハッカソンのテーマは「ChatGPT APIを用いたサービスの開発」ということで、(1)イノベーション性, (2)事業としての成長可能性, (3)完成度, の以上3つの評価基準で入賞チームを決めるものとなっていました。



# 開発したサービスの概要
私たちは、“賞金が貰えるAIチャット”ということで「ワードハンター」というLINEチャットを開発しました。簡単に言うと、AIに決まったフレーズを言わせたらポイントが貯まり、ポイント獲得数に応じて賞金が貰えるというサービスです。
以下に発表資料として用いたcanvaのスライドがありますので、ぜひご覧ください！
https://www.canva.com/design/DAFmtlX1rHA/IkhTptINrhr605Diu8z-1Q/view?utm_content=DA[…]mpaign=designshare&utm_medium=link&utm_source=publishsharelink

# 結果
今回の結果はなんと、最もイノベーション性の高いチームとしてエンジニアType賞を獲得することができました！落合陽一さんら審査員の方々からも高く評価していただいてとても嬉しかったです！8/1には、このサービスをリリースして、収益化を目指して運営できたらと思います。
また、弊社CEOのもっちさんがリーダーを務めた「チームn次元ポケット」が最優秀賞を獲得しました！なんと、CODEMGYMから参加した2チームでW受賞する結果となりました！これ以上ない結果だったので、オフィスも大盛り上がりでした！


# 最後に
今回、とても満足のいく結果でハッカソンを終えられて良かったです。AWSの環境や参加機会を下さったCODEMGYMや、4月以降様々な技術的指導をして下さったひげさん(Twitter:https://twitter.com/himaruuuun?s=20 )には大変感謝申し上げます。
再来月に開催する予定のハッカソンでは、運営だけでなく開発者としての参加も予定していますので、運営・開発ともに成功を収められるように頑張りたいと思います。
GitHub PagesにStorybook公開する

StorybookをGitHub Pagesに公開する方法を試してみたのでまとめます。
今回React + Typescriptのプロジェクトで試しています。

### プロジェクトの作成
以下のコマンドでプロジェクトを作成します。
```
npx create-react-app react-storybook --template typescript
```

プロジェクトが作成されたことを確認します。
```
npm run start
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/2dd58d5c-2ea9-0339-5ed5-7e28a21bd98a.png)



### Storybookをインストール
以下のコマンドを実行し、上で作成したプロジェクトにStorybookをインストールします。
```
npx storybook init
```

Storybookをインストールすると以下のコマンドでStorybookを確認できるので実行して確認します。
```
npm run storybook
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/b6532646-c157-1424-1684-913ff1a1b409.png)


### GitHub Pagesに公開
今回は上記で確認したStorybookをGitHub Pagesに公開します。
storyの書き方については別途試す予定のため、今回の記事には記載しません。

#### Storybookをビルド
package.jsonの値を変更します。
```"build-storybook": "storybook build -o ./docs"```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/bd325ed0-fbe4-33a9-34c5-74963baa13d2.png)

以下のコマンドを実行しビルドします。
```
npm run build-storybook
```

/docsに成果物ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/af098991-70c2-3d96-93e4-8b2e1173092c.png)


#### GitHubにコードを反映
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/295634af-33f5-053c-db3a-e03b85e3f851.png)


今回はPublicリポジトリに公開しますが、Publicに公開できないものはPrivateリポジトリにしてGitHub Pagesに公開します。
詳細は公式サイトを確認してください。
https://docs.github.com/ja/enterprise-cloud@latest/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site

#### GitHub Pagesの設定
Sorce: Deploy from a branch
Branch: main
folder: /docs
にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/f503259b-a72a-18fb-a0c1-e0ce1af5af58.png)


Saveボタンを押すと、URLが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/23e0e68e-6e0a-9a41-c873-84ceb0c7c1ba.png)



#### URLに接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/32a7ff84-d6d6-f2a0-47b4-0d6719adc221.png)


これでGitHub PagesにStorybookを公開することができました。