OmniAICreator/Qiita-1.07M huggingface dataset:
-2- 個人的にお勧めしたいUdemyの講座２選

# 　次になにを学ぼうか

私はUnityでの開発を始めて、UdemyやYoutubeでの教材を割とこなしました。
Unityの使い方やC#の文法など、かなり覚えることができました。
学習開始から一か月くらいが立ち、**もっと深ぼったことを学びたい**なという気持ちが生まれた
そこで出会ったのが、今回お勧めしたいUdemyの講座です。
是非、私と同じような気持ちでいる方に**挑戦**していただきたい。


## １\.　Youtubeから「ITeens Lab」様

https://www.youtube.com/@iteenslab7476

このチャンネルではUnityの基本的な操作やオブジェクト、コンポーネントの操作方法など、**初歩であり大事な基礎を体系的に学べます！**
教材のよくあるあり方の一つとして簡単なゲームを作ってみよう！というのがありますが、このチャンネルではさらにその**手前のことを学べ、今まで学んだことの復習**ともなって非常に勉強になりました。

動画の再生数はそこまで多くないですが、個人的にはもっと伸びるべきだと感じるほどわかりやすく、動画数も50を超えるほどたくさん出ており、
**一度学んだことを整理したいという方**にお勧めする講座です！！


## ２\.　Udemyから「GameDev.TV」様

https://www.udemy.com/user/gamedevtv/

この教材ではコンポーネントの具体的な操作方法や**Unityの専門的な部分**、そして**C#コードの意味やルーツ**などを学べます！
一つの講座には５つのミニゲーム作成があり、そのボリュームには相応の満足感があります！
英語音声教材なので苦手な方もいるでしょうが、日本語字幕がついているので、しっかりと学べます！
正直私も最初は避けていましたが、**Udemy内のレビュー数の多さに対する信頼**や**内容への興味が高まり**購入に至りました。

お勧めするユーザー層は**1、2カ月程Unity、C#の学習を行っている方**です。この教材の注意点は、やはり日本語字幕での学習になるので、内容の理解が日本語字幕の正確さにかかってしまうところです。まぁ、私が学んでいる限りは問題ないのですが、それは**ある程度の知識がついているから理解できている**のかもしれないと思います。

そのような注意点を差し置いても次への**ステップアップをしたいユーザーにはもってこいの講座**になります。

# 　まとめ

講座での学習は動画教材をお勧めしています。しかし、技術本などには触れていたほうが将来的に活用できることがたくさんでてくると考えていますので、私はこれから本での学習も始めていきたいと思っています。

それでは、また。この記事を閲覧して頂き誠にありがとうございました！！
Amazon Personalize の --role-arn オプションがちょっと意地悪な件


Amazon Personalize を導入しようとしたところ、
--role-arn オプションが上手く付けられなくて、しばらく詰みました...結論、エラーをよく読みましょうということではあるのですが、これはちょっと難しい...。

状況としては、
1, Amazon Personalize CLIでデータセット作成のコマンドを投げたかった。
2, やってみた
3, roleの設定(= --role-arn というオプションで設定する）がエラーを吐き続けた。

roleは必須項目なので、逃げられない...ということでしばし格闘したところ、下記のことがわかりました。↓


```ruby:qiita.rb
 --role-arn  arn:xxx:iam::000000000000:user/xxxxxxxxxxx
```

とかなってると動かない。


```ruby:qiita.rb
--role-arn arn:xxx:iam::000000000000:role/user/xxxxxxxxxxx
```

て感じにroleを足しましょう。この文字が大切よ！！！

吐いてるエラーにも書いてはあったのですが...ちょっとわかりにくかった...
Next.js(v13.2.4)/TypescriptのLPにカルーセル（Swiper:v9.1.1）を実装する

## はじめに

Next.js/Typescriptで構築した静的なLPにカルーセルのライブラリ（Swiper:v9.1.1）を導入して実装する事になりました。
Next.js(v13.2.4)に初めてライブラリを導入するのは初めてで、少し詰んだので備忘録として記事にする事にしました。

## Swiperのインストール
```
npm install swiper
```

## CSSのインポート
カルーセルに必要なcssをインポートします。
今回LPなのでapp/page.tsxに追加しました。
ナビゲーションも付けたいのでnavigationもインポートしています。
```Typescript:
import 'swiper/css'
import 'swiper/css/bundle'
import 'swiper/css/navigation'
```
## カルーセルを作成
カルーセルに必要なタグをインポートします
```Typescript:
import { Swiper, SwiperSlide } from 'swiper/react'
import SwiperCore, { Navigation } from 'swiper'
SwiperCore.use([Navigation])

// カルーセル用の画像
const images = [
    `/sample.jpg`,
    `/sample.jpg`,
    `/sample.jpg`,
]
const Home = () => {
    return (
        <>
            <Swiper
                // スライドの表示枚数
                slidesPerView={1}
                // 前後の矢印
                navigation
                className="mySwiper"
                loop={true}
            >
            {images.map((src: string, index: number) => {
                return (
                    <SwiperSlide key={`${index}`}>
                        <Image
                            src={src}
                            width={640}
                            height={480}
                            alt='sample'
                            className='text-c'
                        />
                    </SwiperSlide>
                )
             })}
            </Swiper>
        </>
)}

export default Home
```

## エラーが発生しました
動作確認をしたところ、swiperのライブラリのファイルで**ReactServerComponentsError**が発生していました。
エラーを調べたところ、Next.jsのversion13以降からコンポーネントはデフォルトでサーバーコンポーネントになっているようです。
ですので、クライアントでコンポーネントを使用する場合は明示的にクライアントで使用する`'use client'`の記述が必要です。

サーバーおよびクライアント コンポーネント
https://beta.nextjs.org/docs/rendering/server-and-client-components

今回はapp/page.tsxの先頭に`'use client'`を追加するとカルーセルが表示されて、カルーセルが動くようになりました。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936514/fdd9131e-3b12-afba-dcc7-135ba85afc24.png)

## 参考サイト
https://swiperjs.com/react

https://b-risk.jp/blog/2022/04/swiper/#01_Swiper

https://qiita.com/Hiiisan/items/9561cabb7d125a431df7
yqで出力した結果にくっつくダブルクォーテーション("")を除ける方法

AWSを使い始めてから、yamlという設定ファイルの素敵さを知りました。
Python × Shell使いには持ってこいなとっても良い子です。書くの楽だし見やすいし。

しかしshell × yamlの組み合わせにチャレンジしてみたところ、アウトプットにダブルクォーテーション("")がついてくるのが嫌...
(ちなみにうちのyqさんはPython系です。yqさんにはGO系とPython系がいるようですね。)

結論、

```shell:terminalな画面
yq -r [yaml内の設定] [yamlのpath]
```

としたらアウトプットから""は消えました!! Python系（つまりjqと依存関係のあるyq）をお使いの方はこれで""とおさらばできると思います٩( ᐛ )و huhuh
destroy、deleteの違いを調べる

削除の方法はこれだけではありません。オブジェクト同士が```dependent: :destroyで関連付けられている場合はdestroy```されますが、オブジェクト同士が```dependent: :delete_allで関連付けられている場合はdelete```されるのでご注意ください。

# 出典
https://railsguides.jp/association_basics.html#has-many%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0%E3%81%AA%E5%8F%82%E7%85%A7:~:text=%E5%89%8A%E9%99%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AF%E3%81%93%E3%82%8C%E3%81%A0%E3%81%91%E3%81%A7%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%90%8C%E5%A3%AB%E3%81%8Cdependent%3A%20%3Adestroy%E3%81%A7%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AFdestroy%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%81%8C%E3%80%81%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%90%8C%E5%A3%AB%E3%81%8Cdependent%3A%20%3Adelete_all%E3%81%A7%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AFdelete%E3%81%95%E3%82%8C%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%94%E6%B3%A8%E6%84%8F%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82

# 気づき
```destroy```と```delete```の違いはなんだろう?

# ```destroy```
```指定した条件のレコードを削除```
dependentが設定されている場合は関連付けられたモデルも削除

# 出典
https://railsdoc.com/page/model_destroy#:~:text=%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E6%9D%A1%E4%BB%B6%E3%81%AE%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%89%8A%E9%99%A4%0Adependent%E3%81%8C%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AF%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%89%E3%82%8C%E3%81%9F%E3%83%A2%E3%83%87%E3%83%AB%E3%82%82%E5%89%8A%E9%99%A4

# ```delete```
```指定した条件に一致するレコードをSQLを直接実行して削除```
```関連付けられたモデルは削除しない```

# 出典
https://railsdoc.com/page/model_delete#:~:text=%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E6%9D%A1%E4%BB%B6%E3%81%AB%E4%B8%80%E8%87%B4%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92SQL%E3%82%92%E7%9B%B4%E6%8E%A5%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%A6%E5%89%8A%E9%99%A4%0A%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%89%E3%82%8C%E3%81%9F%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AF%E5%89%8A%E9%99%A4%E3%81%97%E3%81%AA%E3%81%84

```rb
def delete(id_or_array)
  delete_by(primary_key => id_or_array)
end
...

def delete_by(*args)
  where(*args).delete_all
end
```
# 出典
https://github.com/rails/rails/blob/7c70791470fc517deb7c640bead9f1b47efb5539/activerecord/lib/active_record/persistence.rb#L676

# 感想
難しい。
とりあえず関連付けされたモデルを削除できるかできないかの違い。
しか分からなかった。
ドメインコントローラーの降格に失敗した場合の対処

備忘録的な意味合いとして雑に残しておきます。
# エラー内容
ドメインコントローラー降格時に **「ディレクトリサービスで必須の構成情報が不足しているため、浮動単一マスター操作の役割に対する所有権を判断できません。」** というエラーが出ました。
FSMOの役割を強制的に移行した場合に起こるらしい。

環境はWindowsServer 2019
ドメインの機能レベル：WindowsServer 2016
フォレストの機能レベル：WindowsServer 2016
です。
# 解決方法
Microsoftが公開している[KnowlgeBase949257](https://learn.microsoft.com/ja-JP/troubleshoot/windows-server/identity/error-run-adprep-rodcprep-command "KB949257")内のfixfsmo.vbsをデスクトップなどサーバー内の任意の場所に保存します。
コマンドプロンプトを開き以下のコマンドをそれぞれ入力します。
~~~
cscript fixfsmo.vbs DC=ForestDnsZones,DC=contoso,DC=com
~~~
~~~
cscript fixfsmo.vbs DC=DomainDnsZones,DC=contoso,DC=com
~~~
コマンド実行後に再度通常通りの手順でドメインコントローラーの降格を行えばエラーなく降格できるはずです。

:::note warn
『DC=contoso,DC=com』の部分はそれぞれの環境で異なります。
例えばドメイン名が sudare.local だった場合は「DC=sudare,DC=local」と書き換えましょう。
:::

念のためfixfsmo.vbsのスクリプトを以下に記載しておきます。
<details><summary>fixfsmo.vbs</summary>

~~~fixfsmo.vbs
'-------fixfsmo.vbs------------------
const ADS_NAME_INITTYPE_GC = 3
const ADS_NAME_TYPE_1779 = 1
const ADS_NAME_TYPE_CANONICAL = 2

set inArgs = WScript.Arguments

if (inArgs.Count = 1) then
    ' Assume the command line argument is the NDNC (in DN form) to use.
    NdncDN = inArgs(0)
Else
    Wscript.StdOut.Write "usage: cscript fixfsmo.vbs NdncDN"
End if

if (NdncDN <> "") then

    ' Convert the DN form of the NDNC into DNS dotted form.
    Set objTranslator = CreateObject("NameTranslate")
    objTranslator.Init ADS_NAME_INITTYPE_GC, ""
    objTranslator.Set ADS_NAME_TYPE_1779, NdncDN
    strDomainDNS = objTranslator.Get(ADS_NAME_TYPE_CANONICAL)
    strDomainDNS = Left(strDomainDNS, len(strDomainDNS)-1)

    Wscript.Echo "DNS name: " & strDomainDNS

    ' Find a domain controller that hosts this NDNC and that is online.
    set objRootDSE = GetObject("LDAP://" & strDomainDNS & "/RootDSE")
    strDnsHostName = objRootDSE.Get("dnsHostName")
    strDsServiceName = objRootDSE.Get("dsServiceName")
    Wscript.Echo "Using DC " & strDnsHostName

    ' Get the current infrastructure fsmo.
    strInfraDN = "CN=Infrastructure," & NdncDN
    set objInfra = GetObject("LDAP://" & strInfraDN)
    Wscript.Echo "infra fsmo is " & objInfra.fsmoroleowner

    ' If the current fsmo holder is deleted, set the fsmo holder to this domain controller.

    if (InStr(objInfra.fsmoroleowner, "\0ADEL:") > 0) then

        ' Set the fsmo holder to this domain controller.
        objInfra.Put "fSMORoleOwner",  strDsServiceName
        objInfra.SetInfo

        ' Read the fsmo holder back.
        set objInfra = GetObject("LDAP://" & strInfraDN)
        Wscript.Echo "infra fsmo changed to:" & objInfra.fsmoroleowner

    End if

End if
~~~
</details>
PHPでjsonを読み込んで配列化。

メモメモ。
# PHPでjsonファイルを読み込む
PHPでjsonファイルを読み込む方法は以下。
```php
<?php
//json取得先
$json_url = dirname(__FILE__).'/../json/article.json';

//jsonを読み込み
$input_json = file_get_contents($json_url);

//json_decodeで連想配列に変換
$arrays = json_decode($input_json);
?>
```
3/29 Linux コマンド操作part5

# 個人的リマインド用
プロセス・ジョブ 

## プロセスとは
実行中のプログラムのことをプロセスという
実行ファイル(/bin/less, /bin/yum)
↓
実行中のプログラム(プロセス1, プロセス2, プロセス3)メモリ
コマンドを実行すると、実行ファイルをメモリに格納して、メモリ上でCPUがプログラムを実行する。一つ実行すると新しいプロセスが一つ作られる

## psコマンド
実行中のプロセスを表示するコマンド
```
ps [オプション]
ps
PID TTY   TIMECMD
3935 pts/0 00:00:00ps
20961 pts/0 00:00:00bash
```
PIDにプロセスIDが、CMDに実行中のコマンドが表示されている

**オプション**
全ユーザーのプロセスを、詳細情報を併せて表示
```
ps aux
※オプションだけど-をつけなくていい
xがpsコマンドを実行したユーザーのすべてのプロセス
aがすべてのユーザーのプロセス
uが詳細情報を合わせて表示するという意味
```
## ジョブ
まとめて実行されるプロセスの集まりがジョブ。シェルごとに管理される
```
ps aux | grep bash | less
プロセスは3つ生成される
ジョブは1つ生成される
```
**ジョブとプロセスの違い**
・プロセスはOS全体で統一して管理される。システムが自動で実行しているプログラムや他のユーザーが実行しているコマンドを一括して管理
・ジョブは、そのジョブを実行するシェルで管理される

バックグラウンドでプログラムを実行する際ジョブが必要になる

## バックグラウンドとフォアグラウンド
シェルの画面外でコマンドを実行することをバックグラウンド、シェルの画面内で実行することをフォアグラウンドという

状態はフォアグラウンド、バックグラウンド、停止の3つ
```
フォアグラウンド  -Ctrl+z→  停止
　　　　　　　　 ←fgコマンド-  ↓ bgコマンド
　　　　　　　　　　　　　　バックグラウンド
```
**jobsコマンド**
現在のジョブの一覧を表示するコマンド
```
jobs
```
**fgコマンド**
ジョブをフォアグラウンドにするコマンド
```
fg %<ジョブID>
```
**bgコマンド**
ジョブをバックグラウンドにするコマンド
```
bg %<ジョブID>
長い時間がかかる処理をバックグラウンドで実行することで、コマンドが終了するのを待たなくて良くなる
```
## killコマンド
ジョブやプロセスを終了させるコマンド
```
kill [オプション] %<ジョブID>
kill [オプション] %<ジョブID>
```
正確には、killコマンドはシグナルを送信するコマンド
```
kill -<シグナル名> <プロセスID>

時々使うのはSIGKILLという強制終了のシグナル(最終手段)
kill -SIGKILL 4965
kill -9 4965(このように省略可)
```
Groovy × Spock の各役割

## 初めに
テストコードを書くのに【Java × Junit】と【Groovy × Spock】を経験しました。
個人的に【Groovy × Spock】がかなり書きやすかった印象があります。
ですので、まとめます。

## whenとthen（そしてsetup）

|ブロック　|内容|
|------|----------------------------------------|
|setu　|前提条件を記述します。 |
|when　|テスト対象となる動作を記述します。|
|then |whenの実行結果として、期待される条件を記述します  　|

## expect

|ブロック　|内容　|
|------|-------------------------------|
|expect　|whenとthenを合体させたようなものです。 |

## cleanup

|ブロック　|内容　|
|------|-------------------------------|
|cleanup　|テストの為にsetupでファイルを作成したりした場合、このcleanupブロックで削除します。<br>例外が発生しようがしまいが、必ず実行されるという点に注意。 |

## where

|ブロック　|内容　|
|------|-------------------------------|
|where　|データドリブンテストが可能。 |

## @Unroll

|ブロック　|内容　|
|------|-------------------------------|
|@Unroll　|whereブロックの行数分、それぞれ独立したテストのように繰り返し実行されます。 |

## こんな感じで書けます。

```groovy:test.groovy
@Unroll
def "selectMany動作確認: 従業員名検索：#testCase：取得データ有"() {
    given:
    def employeeId = null
    def employeeName = _employeeName

    when:
    def dtoList = employeeDao.selectMany(employeeId, employeeName)


    then:
    dtoList.size() == 2
    dtoList[0].each {
        assert it.employeeId == "100000000"
        assert it.employeeName == "従業員NAME"
    }
    dtoList[1].each {
        assert it.employeeId == "100000001"
        assert it.employeeName == "従業員NAME"
    }

    where:
    _employeeName   | testCase
    "従業員NAME"     | "完全一致"
    "従業員"         | "部分一致"
}
```

## 参考
ありがとうございます🙇‍♂️
https://koji-k.github.io/groovy-tutorial/index.html
wemosでalexaデバイス その7

# 概要
wemos d1で、alexaデバイスを作ってみる。
「アレクサ、デバイスを検出して」のプロトコル。
（想像）

# やり取り

- アレクサとwemoは、同じネットワーク上にいる、前提。

```mermaid
sequenceDiagram
    person  -->>+ echo: 「アレクサ、デバイスを検出して」
    echo ->>+ wemo: upnp m-search
    wemo ->>- echo: response xml
    echo ->>+ wemo: http get
    wemo ->>- echo: http response
    echo -->> person: 「はい、ライトを登録しました」
    person  -->>+ echo: 「アレクサ、ライトを点けて」
    echo ->>+ wemo: http post soap
    wemo ->>- echo: http response
    echo -->> person: 「はい」
```

以上。
"." の扱い。

PHP7.4 までは 「"." に 0.0を足す」といういささかアタマノワルイ^H^H^H^H^Hイレギュラーな処理について、Warningこそ出しながら、致命的な型エラーにならなかったものも、PHP8.0からは TypeError になり、通してもらえません。

## test.csv 
<pre>
0,1,2,3,4,5,6,7,8,9,10
0 , 1 , 2 ,3 ,4 5 ,7, 9, 19
.,.,.
~
</pre>

## テスト環境 
<pre>
$ php -v
PHP 8.0.28 (cli) (built: Mar 23 2023 09:00:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.28, Copyright (c) Zend Technologies

$ ./php -v
PHP 7.4.33 (cli) (built: Mar 28 2023 16:33:02) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
</pre>

## テストコード
<pre>

$csvfile = fopen('test.csv',"r");
while ($data = fgetcsv($csvfile,1000,",")) {
    
   $num = count ($data);
   print $num . "\n";
   for ($colmn=0;$colmn<$num; $colmn++) {
     print "0.0"+ $data[$colmn]."\n";
   }  

</pre>

## テスト結果
まずは、php7.4 です。
<pre>
 ./php test_fgetcsv.php
11
0
1
2
3
4
5
6
7
8
9
10
8
0
1
2
3
4
7
9
19
3

Warning: A non-numeric value encountered in /usr/home/strnh/test_fgetcsv.php on line 10
0

Warning: A non-numeric value encountered in /usr/home/strnh/test_fgetcsv.php on line 10
0

Warning: A non-numeric value encountered in /usr/home/strnh/test_fgetcsv.php on line 10
0
</pre>
ワーニングが出るだけでとりあえず "." を 0と認識します。

PHP8.0ではどうでしょうか：
<pre>
 php ./test_fgetcsv.php 
11
0
1
2
3
4
5
6
7
8
9
10
8
0
1
2
3
PHP Warning:  A non-numeric value encountered in /usr/home/strnh/test_fgetcsv.php on line 10
4
7
9
19
3
PHP Fatal error:  Uncaught TypeError: Unsupported operand types: string + string in /usr/home/strnh/test_fgetcsv.php:10
Stack trace:
#0 {main}
  thrown in /usr/home/strnh/test_fgetcsv.php on line 10

</pre>

## 結論
もはや型変換が厳しく、変なデータを喰わせたときの挙動が明らかにゲキオコです。
0.0 + というやり方が悪いのか。
 
"." という表現を 0.0 であるとする古いcsvファイルを読み込ませるときにトラブルが発生します。混ざっている " " 空白については 文句をいうだけで、とりあえずパースはしてくれます。

文字列から数値に変換する際の細工がもう少し必要なのでしょう。

以上
CoreSimulator や IBAgent-iOS でエラーが出て悩んだとき

数ヶ月前まで問題なくビルド出来ていたFlutterのビルドで、いつの間にか以下のエラーを吐くようになった。

```
Failed to launch AssetCatalogSimulatorAgent via CoreSimulator spawn
```

```
Encountered an error communicating with IBAgent-iOS
```

Xcode/Mac/iPhoneの再起動や`clean`などを何度試しても改善せず、途方に暮れていた。

`~/Library/Logs`の所有者が`root`になっているのが関係あるようなアドバイスをどこかで見かけ、以下を試すとどちらの問題も発生しなくなっていた。

```
sudo chmod 777 ~/Library/Logs 
```

対応前がどのようなパーミッションだったのか覚えておらず、以下のように削除して自動的に作ってもらった。これでも問題は発生しなかった。

```
sudo rm -rf ~/Library/Logs
```

より正しい対応方法があるような気がするが、ひとまずビルドは出来るようになった。
なんでほくろから生えてくる髭は長く伸びるのですか?

ほくろから生えてくる髭が他の髭よりも長く伸びるという科学的な証拠はありません。髭の成長速度は、個人差や遺伝子、ホルモンバランスなどによって異なるため、髭が生えている場所がほくろであっても、それ以上に速く成長するわけではありません。

ただし、髭が生えている場所がほくろである場合、その部位は通常の皮膚よりもデリケートであることがあります。そのため、髭を剃るときには、ほくろ周辺を傷つけないように注意する必要があります。また、ほくろの形状や色素沈着の程度によっては、剃り残しや切り傷が目立ちやすく、それが炎症を引き起こすことがあります。そのため、ほくろ周辺の髭を剃る場合は、十分に注意して行うことが重要です。
AlmaLinux 上のgitlab runnerがsetlocale: LC_CTYPE: cannot change locale (en_US.UTF-8) のエラーを吐く

[AlmaLinux9\.1にGitLabをインストールする \- Qiita](https://qiita.com/qyen/items/482fde75e9c34065c9c8) の環境。

c# でmvc6 coreプロジェクトに外部のAPIとswaggerを使って連携したコードをPushしたところgitlab-runnerが
```
setlocale: LC_CTYPE: cannot change locale (en_US.UTF-8)
```
のエラーを吐いてFailするようになった。

原因は多分これ。 [NuGet Gallery \| NSwag\.ApiDescription\.Client 13\.18\.2](https://www.nuget.org/packages/NSwag.ApiDescription.Client#readme-body-tab)

### 原因調査

setlocaleで失敗するって権限かlankpackか

```
[root@localhost ~]# locale -a
C
C.utf8
POSIX
ja_JP.eucjp
ja_JP.utf8
```

あ、en_us入ってない。

### 言語パックインストール

```
[root@localhost ~]# dnf install langpacks-en glibc-langpack-en
Dependencies resolved.
======================================================================================
 Package                   Architecture   Version              Repository    Size
======================================================================================
Installing:
 glibc-langpack-en         x86_64         2.34-40.el9_1.1      baseos        558 k
 langpacks-en              noarch         3.0-16.el9           appstream     9.4 k
Installing dependencies:
 langpacks-core-en         noarch         3.0-16.el9           appstream     9.4 k

Transaction Summary
======================================================================================
Install  3 Packages

Total download size: 577 k
Installed size: 5.7 M
Is this ok [y/N]: y
```
で、OK。

```
[root@localhost ~]# locale -a
C
C.utf8
POSIX
en_AG
en_AU
en_AU.utf8
en_BW
en_BW.utf8
en_CA
en_CA.utf8
en_DK
en_DK.utf8
en_GB
en_GB.iso885915
en_GB.utf8
en_HK
en_HK.utf8
en_IE
en_IE.utf8
en_IE@euro
en_IL
en_IN
en_NG
en_NZ
en_NZ.utf8
en_PH
en_PH.utf8
en_SC.utf8
en_SG
en_SG.utf8
en_US
en_US.iso885915
en_US.utf8
en_ZA
en_ZA.utf8
en_ZM
en_ZW
en_ZW.utf8
ja_JP.eucjp
ja_JP.utf8
```

### 参考

- [\[Linux\]ログイン時にsetlocale: LC\_CTYPE: cannot change locale \(en\_US\.UTF\-8\)エラーが出た時の対処法 \| akamist blog](https://akamist.com/blog/archives/665)
- [び～ぼちゃんのお部屋。 \- locale追加手順](https://bobineko.biz/linux/centos/set_locale.html)
- [Docker centos:centos8のロケール等を設定 \- gxliuのブログ](https://gxliu.hatenablog.com/entry/2020/10/23/004826)
【JS】時間操作まとめ【Vue】



よく使う時間操作の処理をまとめました。
思いつきしだい随時追記していこうと思います。



## 「分」を「時間」に直したい時

``` js
let m = 66 //66分

console.log(
  `${Math.floor(m / 60)}時間${ m % 60 }分` // 1時間6分
)
```

## 日付からミリ秒を取得する

```js
Dateオブジェクト.getTime()

let now = new Date();

console.log(now.getTime()); // 1654525795212
```

## ミリ秒から秒、分、時間を求める

```js
let time=now.getTime().getTime() // 1654525795212

let sec = Math.floor(time/1000)%60 //秒

let min = Math.floor(time/1000/60)%60 //分

let hours = Math.floor(time/1000/60/60)%24 //時間
```


## 特定の日付から曜日を得る

```js
// 曜日を表す文字列の配列を作っておく
var WeekChars = [ "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" ];
 
// 日付オブジェクトから曜日を得る
var dObj = new Date( /* 何らかの日付 */ );
var wDay = dObj.getDay();
alert("指定の日は、" + WeekChars[wDay] + "です。")
```

## 「202301011200」 を 「2023-01-01 12:00」 の形式にする

```js
let datetime = 202301011200

datetime = datetime.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/, '$1-$2-$3 $4:$5')

console.log(datetime)  //2023-01-01 12:00
```

## 現在日時を取得し、"2022/12/ (木) 11:21" ←この形にする

```js
var dayOfWeekStr = ['日', '月', '火', '水', '木', '金', '土']

function pad(num) {
   return String(num).padStart(2, '0')
 }

 function formatDate(date) {
                return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}（${dayOfWeekStr[date.getDay()]}）`
        }

 let now = new Date()
 let currentHour = pad(now.getHours())
 let currentSecond = pad(now.getMinutes())
 let dateTime = `${formatDate(now)}${currentHour}:${currentSecond}`
 
console.log(dateTime)  //2022/12/05 (木) 11:21
```

## 昨日を取得する

```js
// 現在の日付を取得
const today = new Date();

// 1日分のミリ秒数を計算
const oneDay = 24 * 60 * 60 * 1000;

// 1日前の日付を計算
const yesterday = new Date(today.getTime() - oneDay);

// 結果を出力
console.log(yesterday);
```

new Date()で現在の日付を取得し、getTime()メソッドを使用してミリ秒単位での時刻を取得します。
次に、1日分のミリ秒数を計算し、現在の日付の時刻から1日分を引いて、1日前の日付を計算します。

## 時間同士の差を求める

```js
let date1 = new Date("2022-01-02T13:58:00+09:00")
let date2 = new Date("2022-01-02T14:05:00+09:00")

let diff = date2.getTime() - date1.getTime()

console.log(diff)
```

## 時間の0埋め

`.toString().padStart(2, "0")`とすることで、

9:3のとき  →  09:03
13:6のとき → 13:06
10:13とき → 10:13　（そのまま）

と、適宜0埋めしてくれます。

``` vue
<div>
{{Time.getHours().toString().padStart(2, “0")}}:{{Time.getMinutes().toString().padStart(2, “0”)}}
</div>
```
苦手克服に向けて。。。(SQL)

# はじめに

SQLは研修で基礎を学んだ程度で、業務でもあまり関わる機会が無く。。。
その状態で早入社まる3年が経とうとしている。
年数が上がるにつれ、保守で担当するものもDBを見ないと解決できないような問い合わせも複数。。。
まずはSQL怖いという先入観から無くしていきたい。

## 実施したこと
#### 一通りの復習
SQL攻略-Web上でSQL実行しながらマスターするサイト「ＳＱＬ攻略 - Ｗｅｂ上でＳＱＬを実行しながらマスターするサイト」で一通りの復習
https://sql.main.jp/

基礎も復習でき、SQLでの調査を率先して受けられるモチベに！

### 書籍を使用した学習（実施中・・・）
「スッキリわかるSQL入門」を使用して、業務で使えるSQL技術を身に着け中。。
（とりあえずQiita更新したかったので。。お許しを。。）
https://book.impress.co.jp/books/1121101090

### おまけ-SQLで出力した結果をCSVで吐き出す（My SQL）
今後使いそうなSQL結果のCSVの出力を勉強。
SELECT文に「INTO OUTFILE」を記述すればCSVファイル出力ができる。
INTO 形式を使用すると、クエリー結果を変数に格納したり、ファイルに書き込んだりできる。

基礎構文
```
SELECT カラム名, ... FROM テーブル名 INTO OUTFILE '出力ファイルパス';
```

さらにオプションを付けることで、区切り文字や改行コードを指定することができる。

|オプション              |オプション              |
|:-----------------:|:-----------------:|
|TERMINATED BY          |区切り文字を指定。デフォルトはタブ区切り。
|ENCLOSED BY         |フィールドを囲む文字を指定。デフォルトは囲み文字なし。
|TERMINATED BY       |改行コードを指定。デフォルトはLF（\n）。（カーソルを次の行に移動する。）


ヘッダーを付けるオプションはなさそう。
UNION句で付与する。
```
SELECT カラム名, ... UNION SELECT * FROM テーブル名 INTO OUTFILE '出力ファイルパス';
```

## さいごに
まだインプット・アウトプットが十分ではないため、業務の中で実際に触る機会を積極的に増やし、自分が意図したデータを出力、短い時間での調査を進められるようにしたい。
Laravel 翻訳関数__()


実務にてコードリーディングをしている際に現れた__()という見慣れない記法。

どういう意味なのか、どう使うのかがわからなかったので、調べてまとめてみました！

## __()が何を表すのか

>__関数は、指定した翻訳文字列か翻訳キーをローカリゼーションファイルを使用し、翻訳します。
>(Laravel 日本語ドキュメントを参照)

* __ヘルパ関数と呼ぶ
* Lang::getの省略形

現在設定中の言語ファイルから、指定したデータを呼び出すときに使用するみたいです！

## 使用前の準備

### 現在設定している言語
config > app.php の中のlocaleを参照

日本語の場合は以下のようになっている。

```
'locale' => 'ja'
```

### 言語ファイルの場所

resources > lang 配下
に上記のようにjaで設定されていれば、jaディレクトリを作成し、そこにファイルを置く

## __()の使い方

例えば、言語設定が'local' => 'ja' のときに使うと、
jaディレクトリの指定したファイルのデータを取得することになる。

```
__('ファイル名')
ファイルの中のデータを全て取得

__('ファイル名.プロパティ名')
指定したプロパティのデータを取得
```

### 使用例 (翻訳文字列の取得)

resources/lang/ja/messages.phpのファイルが
```resources/lang/ja/messages.php
'hello' => 'こんにちは'
```
となっている場合

```
echo __('messages.hello')
```
とすることで、「こんにちは」と出力される

### 使用例 (翻訳文字列の取得)

resources/lang/ja.json
```resources/lang/ja.json
{
    'hello' => 'こんにちは'
}
```
となっている場合

```
echo __('hello')
```
とすることで、「こんにちは」と出力される


### 応用例

```php
  
$authority_state = 'manager' 

if(__('authority.'. $authority_state .'.is_writing') === "true")
{
  //処理
}
```

という処理があり

resources/lang/ja/authority.phpのファイルが
```resources/lang/ja/authority.php
return [
    'manager' => [
        'position' => '管理者',
        'is_reading' => true,
        'is_writing' => true,
    ]
]
```
となっている場合

```php
__('authority.'. $authority_state .'.is_writing') // 返り値は、true
```
で取得したデータは、trueとなる

つまり
```php
if(__('authority.'. $authority_state .'.is_writing') === "true")
```
この条件式がtrueになるので処理が実行される。
GetEnumerator拡張メソッドを使って複数のIEnumerableオブジェクトをまとめてforeachで処理する

# はじめに
本記事はGetEnumerator拡張メソッドを使って複数のIEnumerableオブジェクトをまとめてforeachで処理する方法をまとめることを目的とします。

# 以前投稿した記事での実現方法
以前投稿した[こちらの記事](https://qiita.com/tat_tt/items/b9757cc940338c7deeab)では複数のIEnumerableオブジェクトをまとめてforeachで処理するのにLinqのZipメソッドを利用していました。
具体的にはページ名一覧とユーザーID一覧のIEnumerableオブジェクトを一つのIEnumerableオブジェクトにまとめて、foreachで処理しています。以下のような感じです。
```csharp
// ページ名一覧
IEnumerable<string> pageNames = ...;
// ユーザーID一覧
IEnumerable<string> userIds = ...;

// ページごとのユニークIDを取得するためにページ名一覧とユーザーID一覧を1つのEnumerableにまとめる
var pageNameAndUserIds = pageNames.Zip(userIds, (pageName, userId) => new { pageName, userId });

// ページ名とユーザーIDの組み合わせ一覧に対して反復処理をする
foreach (var pageNameAndUserId in pageNameAndUserIds)
{
    // ページ名
    var targetPageName = pageNameAndUserId.pageName;
    // ユーザーID
    var targetUserId = pageNameAndUserId.userId;
    ....
}
```

# GetEnumerator拡張メソッドを使う場合
C#9.0の新機能である[GetEnumerator拡張メソッド](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/proposals/csharp-9.0/extension-getenumerator)を使うことで、任意の型に対してイテレート(foreach)処理をするための列挙子を生成する処理の定義が可能になります。
前章のサンプルをGetEnumerator拡張メソッドを使うようにすると以下のようになります。
```csharp
// ページ名一覧
IEnumerable<string> pageNames = ...;
// ユーザーID一覧
IEnumerable<string> userIds = ...;

// ページ名とユーザーIDの組み合わせ一覧に対して反復処理をする
foreach (var (pageName, userId) in (pageNames, userIds))
{
    // ページ名
    var targetPageName = pageName;
    // ユーザーID
    var targetUserId = userId;
    ....
}

/// <summary>
/// 拡張メソッドを定義するクラス
/// </summary>
public static class Extensions
{
	/// <summary>
	/// string型のIEnumerableオブジェクトを2つ同時にForEachで処理するための列挙子を生成する拡張メソッド
	/// </summary>
	/// <param name="stringTuple">対象とするstring型のIEnumerableオブジェクトのタプル</param>
	/// <returns></returns>
	public static IEnumerator<(string, string)> GetEnumerator(this (IEnumerable<string>, IEnumerable<string>) stringTuple)
	{
		var str1Enumerator = stringTuple.Item1.GetEnumerator();
		var str2Enumerator = stringTuple.Item2.GetEnumerator();

		// 要素数が少ないほうに合わせて列挙子を返す
		while (str1Enumerator.MoveNext() && str2Enumerator.MoveNext())
		{
			yield return (str1Enumerator.Current, str2Enumerator.Current);
		}
	}
}
```
上では、string型のIEnumerableオブジェクトをまとめたタプルに対してforeachで処理をするための列挙子をGetEnumerator拡張メソッドで提供しています。
定義したGetEnumerator拡張メソッドは、string型のIEnumerableオブジェクトをまとめたタプルに対してforeachで反復処理をする際に自動で呼び出されます。
そのため、以下のように明示的に拡張メソッドを呼び出さなくても処理ができます。
```csharp
// ページ名とユーザーIDの組み合わせ一覧に対して反復処理をする
// (pageNames, userIds)のタプルに対してGetEnumeratorメソッドは自動で呼び出される
foreach (var (pageName, userId) in (pageNames, userIds))
{
    // ページ名
    var targetPageName = pageName;
    // ユーザーID
    var targetUserId = userId;
    ....
}
```
このGetEnumerator拡張メソッドは、独自のデータ型に対して独自の列挙子の取得処理を手軽に定義し、それを共有する際に使えるかなと思いました。
ただ、あまり安易に定義してしまうとデータ型によってforeachの振る舞いが想定と異なる動きをしてしまうという問題につながる可能性もあるため、使いどころを考える必要がありそうです。

# まとめ
本記事ではGetEnumerator拡張メソッドを使って複数のIEnumerableオブジェクトをまとめてforeachで処理する方法をまとめました。
GetEnumerator拡張メソッドを使うと独自のデータ型に対して独自の列挙子を取得する処理が手軽に定義できることがわかりました。
ただ、安易に使うとデータ型によってforeachの振る舞いが想定と異なる動きをしてしまう危険性もあるため、使いどころを選んで使っていきたいと思いました。
PHPerKaigi2023に参加しました

# PHPerKaigi2023にオフライン・オンラインで参加しました

## Day0

参加していません


## Day1

### オフラインで見た

https://fortee.jp/phperkaigi-2023/proposal/280706e0-7158-4237-8202-c9d64330b96f

改善を行う時に、なんとなくCacheを使う選択をしないようにしようと思った。

https://fortee.jp/phperkaigi-2023/proposal/f7f2f18a-e6b0-47e4-ade0-e324f72428ae

とても分かりやすかった。
新人さんとかに共有したい内容だった。

https://fortee.jp/phperkaigi-2023/proposal/7e212cb2-be37-43e8-b6ee-5236d259fcbf

分からない内容がたくさんあったけど、話が面白くて引き込まれた。

https://fortee.jp/phperkaigi-2023/proposal/ad3ba31c-0214-4557-a0df-3755db8ed8cc

静的解析・フォーマットの恩恵を受けないとなーと思った
暗黙的なコード規約なんて誰も見ないしな。

https://fortee.jp/phperkaigi-2023/proposal/46c96d4a-194d-4bde-a4d8-f9c82c3b0302

Composer on Dockerで、Dockerイメージを本番と開発でなるべく同等の環境で動かすための
工夫が参考になった。

https://fortee.jp/phperkaigi-2023/proposal/979ceebe-479d-4310-b5be-c2912e634224

草の根活動で、非エンジニア含めて広く分析データ活用していく様子すごい。
越境だ。

https://fortee.jp/phperkaigi-2023/proposal/d3084a8f-89b5-48d6-8a81-59c460b3b3e0

php7.4(既存）、php8.1両方で動く互換性を持たせることで、既存の追加開発を止めることなく
バージョンアップを行う戦略がなるほどなーと思いました。
いざRector使うとなったら、それぞれのプロダクトごとに試行錯誤は必要そうだ。

https://fortee.jp/phperkaigi-2023/proposal/dc54af9b-f879-47b6-9737-12ae6e84bf1d

知らない言語学ぶのに使おうと思った。
RESPというものを知った。

https://fortee.jp/phperkaigi-2023/proposal/4a67cc68-83f0-492d-86ca-54304fc256c8

Take1のスロークエリ改善だけでもできているのがすごい。


LT大会　を全て見ました。
話が面白く、ペンライトも振れたので楽しかった。

## Day2

朝から雨 :umbrella: だったので、行く気が起きず、午前中はオンラインで参加。
でもポスターセッションを見たかったので午後から練馬に移動してオフライン参加した。

https://fortee.jp/phperkaigi-2023/proposal/e00788a4-ef25-49ee-b254-9d2b53e19633

配列に苦しめられているのでうなずきながら聞いていた。
「配列に旅をさせない」が明言です。
配列を捨てられるように信頼できるデータ転送クラスを作れるようにしたい。

(練馬に移動）

https://fortee.jp/phperkaigi-2023/proposal/6211083d-fc51-49a3-8b27-485d8e231b1f

愛。Laravelの思想を読みとること
（でももう一度振り返って見直さないと理解できていないかも！）

TrackDでポスターセッション見たり、スポンサーブースでお守りもらったりする。

LTを全部見た。
面白い。話が上手ですごいな〜

https://fortee.jp/phperkaigi-2023/proposal/4f5fbca0-711c-4e30-a339-8aa200a4e5a8

TrackDでアンカンファレンスのようなものを見る。

クロージングを見る。
サイン入りちょうぜつ本は当選しなかったので残念 :cry: 

### 見ていないけど後で動画を見るつもり！！

https://fortee.jp/phperkaigi-2023/proposal/db787adc-c855-4114-99b6-8c6958d47b42

https://fortee.jp/phperkaigi-2023/proposal/9ba49904-038c-4e0a-9419-181d08301a45

https://fortee.jp/phperkaigi-2023/proposal/3630baf7-f540-4dba-b10a-89cdbddf62da

https://fortee.jp/phperkaigi-2023/proposal/95e4dd94-5fc7-40fe-9e1a-230e36404cbe

https://fortee.jp/phperkaigi-2023/proposal/98ad84b9-df03-4449-ab25-377761945005

https://fortee.jp/phperkaigi-2023/proposal/6125c4e2-528c-4b6b-b383-ffc8bfeec29a

https://fortee.jp/phperkaigi-2023/proposal/86a02001-4409-49c9-9fbe-4db251c96cb0

## 感想

楽しかった！！
AWSのNATインスタンスとNATゲートウェイって何が違うの？

# はじめに
AWSのNATインスタンスとNATゲートウェイの違いが良くわからなかったので調べてみました。

## 対象者
この記事は下記のような人を対象にしています。

- AWS初学者

## 役割とスケーラビリティ
NATインスタンスは、EC2インスタンスとして実行され、トラフィックを転送するために設定が必要です。一方、NATゲートウェイは、AWSマネージドサービスであり、自動的にスケーリングされ、高可用性を提供します。NATゲートウェイは、数千の同時接続を処理できるため、より大きなスケールで使用することができます。

## パフォーマンス
NATゲートウェイは、高速でスケーラブルなAWSマネージドサービスであり、NATインスタンスよりも高速であるとされています。

### コスト
NATゲートウェイは、NATインスタンスよりも高価であるため、小規模なアプリケーションの場合、NATインスタンスを使用することが一般的です。

## まとめ
総合的に、NATインスタンスは小規模なアプリケーションの場合に適しており、NATゲートウェイは大規模なアプリケーションの場合に適しています。ただし、どちらを選択するかは、アプリケーションの要件や費用対効果に基づいて決定する必要があります。
GXWorks3の置換機能

三菱電機　シーケンサー（PLC）のプログラミングツール、GXWorks3で、CTRL+Hで普通に置換したり
CTRL-Fで普通に検索しようとするが、
なぜか何も引っかからない。

なんで？

・・・・って悩んだ時がありました。

初期値で右下に出ている「検索と置換」窓、その題名のすぐ下に「デバイス／ラベル変換(E)」と出ている・・・このデフォ状態が曲者。
他のエディタでの常識的な検索・置換をするには、
プルダウンして「文字列検索(D)」「文字列置換(H)」にする。
これで、ふつうに色々探せるようになる。
プルダウンの隣の「（プロジェクト全体）」「（現在のウィンドウ）」の使い分けも重要。特に置換では範囲絞り込みがこれくらいしか見当たらない。
続xscaleの道

ブートローダーをいろいろ試しているうちに、つぶしてしまったので、urjtagでブートローダーを書き込む事にしました。

u-bootにもixp425のビルド設定がありますが、NSLU2はredbootを使っていたようで、redbootの方が良さそうです。

NSLU2のサイトはほとんどなくなっていますが、かろうじて下記のレポジトリが見つかりました。

https://github.com/nslu2

ここにある、redbootのレポジトリはtoolchainレポジトリ(gcc3)のLinuxのバイナリでビルドが通ります。ただ通常のredbootとディレクトリ構成が違っていて、configした後のファイルを抜き出したもののようです。いつものようにFreeBSDのLinuxエミュレーションでビルドしてみます。

gcc3なのが気になりますが、普通にarmでビルドされたgcc4はbigでもlittleでもコンパイルはできますが、big用のlibgccを用意しなければいけないのでこれを使うのが良さそうです。

どうもこのソースはNSLU2とは関係ないものだけどixp425がターゲットなので一緒にしているようです。

iop_redbootというレポジトリはIntelが配布していた、ソースから抜き出したオリジナルのeCosのredbootのコードのようです。元になったIOP_Redboot_Mar_19_2007_source.tar.gzはsourceforgeにありましたが、eCosのツールなどが入っていないので、別に用意する必要があるようです。

すんなりビルドは通ったのでurjtagで焼いてみます。

自作の20ピンの変換コネクタは、そのままでは周りの部品にあたって使えないので、いろいろ考えてみて足長ピンソケットの下駄を履かせて使うことを思いつきました。

足長ピンソケットは一列なのでVCCとGNDは別に取れるように改良しました。

![写真（2023-03-29 09.33）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/89d22cbb-3260-2051-6143-35390805ed2f.jpeg)


```
cable ft2232
detect
endian big
detectflash 0x50000000
flashmem 0x50000000 redboot.bin noverify
```
何も出ません。

ixp425にはUARTが2つあるので、逆になってるのかもしれません。設定を変えてビルドしてみます。

```diff
--- a/include/pkgconf/hal_arm_xscale_grg.h
+++ b/include/pkgconf/hal_arm_xscale_grg.h
@@ -18,7 +18,7 @@
 #define HAL_PLATFORM_MACHINE_TYPE  245
 #define CYGNUM_HAL_BREAKPOINT_LIST_SIZE 32
 #define CYGNUM_HAL_BREAKPOINT_LIST_SIZE_32
-#define CYGSEM_HAL_IXP425_PLF_USES_UART1 1
+//#define CYGSEM_HAL_IXP425_PLF_USES_UART1 1
 #define CYGSEM_HAL_IXP425_PLF_USES_UART2 1
 #define CYGSEM_HAL_ROM_MONITOR 1
```

出ました。

```
Sercomm(tm) intel board bootloader [ROMRAM]
Sercomm certified release, version 1.00 - built 08:12:35, Mar 29 2023

Platform: Intel Generic Residential Gateway (XScale) 
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x00000000-0x04000000, 0x001f4588-0x04000000 available
welcome, snowel 888
== Executing boot script in 2.000 seconds - enter ^C to abort
not have eRcOmM 
Initialize GIGAbit ethernet PCI card
Found device on bus 0, devfn 0xa0:
 Vendor    0xffff
 Device    0xffff
PCI can't find GigaBit card 
In download function
```

ixp425のurjtagはflashは焼けましたが、機能が完全に使えているわけではなさそうです。

ちなみにopenocdはhaltできませんでした。

しかし、redbootは複雑なディレクトリになっていて、よく抜き出してコンパイルが通る状態にしたものだと感心します。

なにか特殊用途に作りこまれているようです、ブートのデバッグはちょっと間違えると、何も出なかったりして難しいので、とりあえずこれをベースにいじってみます。

確実なビルドのRedbootがあればOpenRGのbootからjtagを使わずに書き換えが可能です。ただ失敗する可能性もあるのでurjtagは用意したほうが良いです。urjtagのixp425対応はすこぶる安定してます。

|GPIO|Dir|Func|
|:--|:--|:--|
|2|IN|SW2|
|3|OUT|LVC374 OE|
|4|OUT|LED8(下)|
|8|IN|PCI INTD|
|9|IN|PCI INTC|
|10|IN|PCI INTB|
|11|IN|PCI INTA|
|13|OUT|PCI RESET|
|14|OUT|PCI CLK|
PlantUMLのシーケンス図調整の際に覚えておくべきSkinparam

[PlantUML]:https://www.plantuml.com/
[PlantUML] で図を書くとにき、「こんなところを調整したい」とよく思うところの多くは実は [Skinparam](https://plantuml.com/ja/skinparam) という機能を使うと対応できたりします。
このメモはそんな Skinparam のうち、シーケンス図でよくうものに関する備忘録です。

ちなみに、この情報は基本的に公式サイトの [シーケンス図の構文と機能](https://plantuml.com/ja/sequence-diagram) に書いてあるのですが、キーワードが不適切なのかなかなか欲しい情報に辿り着けないので、記事として書いておきます。

## Participant (オブジェクト） の間隔・距離を調整する `ParticipantPadding` と `maxMessageSize`

PlantUMLのシーケンス図では Participant の間隔は、基本的に矢印上に書いてある文字列が収まるように自動的に決定されるため、同種の図を並べる際に見た目を揃えたい場合などに間隔を調整する機能が欲しくなる場合があります。
そのために使うと想定される *Skinparam* が `ParticipantPadding` です。

### 最小間隔を設定する `ParticipantPadding`

設定がない場合
```
Alice -> Bob
```
```plantuml
Alice -> Bob
```

設定がある場合（単位は多分 Pixel）
```
skinparam ParticipantPadding 50
Alice -> Bob
```
```plantuml
skinparam ParticipantPadding 50
Alice -> Bob
```

この設定は Padding なので、矢印上に書く文字列が溢れると矢印の長さは Padding の設定値よりも長くなります。
```
skinparam ParticipantPadding 50
Alice -> Bob: An example of a long message text
```
```plantuml
skinparam ParticipantPadding 50
Alice -> Bob: An example of a long message text
```
↑矢印が 50px を超えて伸びていることに注目。

### 折り返しの長さを設定する `maxMessageSize`

この場合は、折り返しまでの長さを `maxMessageSize` で設定すると、想定に近くなる場合があります：
```
skinparam maxMessageSize 50
skinparam ParticipantPadding 50
Alice -> Bob: An example of a long message text
```
```plantuml
skinparam maxMessageSize 50
skinparam ParticipantPadding 50
Alice -> Bob: An example of a long message text
```
ただし、折り返しの単位は単語なので、長い単語をメッセージとして書くと矢印のサイズは `maxMessageSize` で指定したサイズを超えてしまいます。
```
skinparam maxMessageSize 50
skinparam ParticipantPadding 50
Alice -> Bob: An_example_of_a_long_message_text( test )
```
```plantuml
skinparam maxMessageSize 50
skinparam ParticipantPadding 50
Alice -> Bob: An_example_of_a_long_message_text( test )
```

## Box の間隔を調整する `BoxPadding`

PlantUMLのシーケンス図の *Box* 間のパディングは非常に小さく設定されています。
これを調整するための *Skinparam* が、`BoxPadding` です。

設定がない場合
```
box
Alice -> Bob
end box
box
Taro -> Hanako
```
```plantuml
box
Alice -> Bob
end box
box
Taro -> Hanako
```

設定がある場合
```
skinparam BoxPadding 10
box
Alice -> Bob
end box
box
Taro -> Hanako
end box
Bob -> Taro
```
```plantuml
skinparam BoxPadding 10
box
Alice -> Bob
end box
box
Taro -> Hanako
end box
Bob -> Taro
```
Approve Records with Approval Processes  > Build an Approval Process


+ [Build an Approval Process](https://trailhead.salesforce.com/content/learn/modules/business_process_automation/build-an-approval-process)

+ [Playground とテストの承認メール](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgeIj)


:::note alert
Unable to send the template preview email. Uncheck 'Send email preview to' checkbox to continue with preview.
:::

アカウントの確認コードを再生成したところ、プレビュー メールを送信できました。 

別のユーザーを受信者として選択しましたが、User オブジェクトは現在ログインしているアカウントを参照しています。私のシステム管理者アカウントには {!User.Manager} がないため、値は空白です。

 
個人的には、これは直感的ではないバグのように思えます。受信者がユーザーに設定されていて、特にユーザーを指定すると、{!User} コンテキストが選択したものにマップされるはずです。

# We approved an account, but we can't find that account's Type set to 'Customer

+ [am stuck on Create an approval process getting a error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgxoySAB)

:::note
This is because you have created the same action in "Account Approval Process." approval process. First delete the action from this process and then try. Let me know if you are facing any further issues.
:::


# その他

+ [ i cant seem to get passed the 5th step](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007aib4J)

# 自分でやったときの情報

注意
Before You Start
Go to Object Manager. In Fields and Relationships for the Account object, check the Type field’s picklist values for Prospect, Customer, and Pending. Add any of these values that are missing.


+ 何もしないで検証ボタンをクリック

:::note alert
We can't find an active approval process named Approve New Account. Make sure the unique name is 'Approve_New_Account'.
:::
ChatGPTで始めるJavaScript入門⑤～条件分岐～


# 概要
　今回は3.JavaScriptの文法と構文について、の
　条件分岐について確認していきます。

　ここは言語ごとに個性が出るところですね。

　**※無料版なので、誤っている情報もあると思いますが、アウトプットできれば良しとします。**


# 条件分岐
　条件分岐はいくつか種類があるのでその辺を聞いてみます。


　【質問】
　JavaScriptの文法と構文について、条件分岐の種類、記述方法や注意点を教えてください。

　【回答】
　JavaScriptの条件分岐には、以下の3つの種類があります。

**if文**
指定した条件が真の場合に実行されるブロックを指定するために使用されます。

```javascript:if.js
if (condition) {
  // 条件が真の場合に実行する処理
}
```

**if-else文**
指定した条件が真の場合に実行されるブロックと、偽の場合に実行されるブロックをそれぞれ指定するために使用されます。

```javascript:ifelse.js
if (condition) {
  // 条件が真の場合に実行する処理
} else {
  // 条件が偽の場合に実行する処理
}
```

**elseif文**
条件分岐において、複数の条件を判定するためには、else if文を使用することができます。
以下のように記述することで、複数の条件に対してそれぞれ異なる処理を行うことができます。

```javascript:elseif.js
if (condition1) {
  // condition1がtrueの場合の処理
} else if (condition2) {
  // condition2がtrueの場合の処理
} else if (condition3) {
  // condition3がtrueの場合の処理
} else {
  // どの条件にも該当しない場合の処理
}

```

**switch文**
複数の条件に基づいて、異なる処理を実行するために使用されます。

```javascript:switch.js
switch (expression) {
  case value1:
    // expressionがvalue1の場合に実行する処理
    break;
  case value2:
    // expressionがvalue2の場合に実行する処理
    break;
  default:
    // 上記のどの条件にも該当しない場合に実行する処理
    break;
}
```

条件式には、**比較演算子や論理演算子**を使用することができます。また、if文やif-else文では、条件式を括弧でくくることが推奨されます。

```javascript:if.js
if ((x > 0) && (y < 10)) {
  // xが0より大きく、かつyが10未満の場合に実行する処理
}
```

switch文では、各case文の最後に必ずbreak文を記述する必要があります。これを忘れると、該当するcase文だけでなく、それ以降のcase文の処理も実行されてしまいます。


if，if-else，switchは他言語でもよく使用しますね。
条件式には比較演算子や論理演算子を入れるということで、JavaScriptで使用できる比較演算子、論理演算子を聞いてみます。

# 比較演算子・論理演算子

【質問】
　JavaScriptで使用できる比較演算子や論理演算子を教えてください。

　【回答】
　JavaScriptで使用できる比較演算子と論理演算子は以下の通りです。

***比較演算子:***

**==**
等しい場合にtrueを返す。

**===**
値と型が等しい場合にtrueを返す。

**!=**
 等しくない場合にtrueを返す。

**!==**
値または型が等しくない場合にtrueを返す。

**>**
左辺の値が右辺の値より大きい場合にtrueを返す。

**<**
左辺の値が右辺の値より小さい場合にtrueを返す。

**>=**
左辺の値が右辺の値以上の場合にtrueを返す。

**<=**
左辺の値が右辺の値以下の場合にtrueを返す。


***論理演算子***

**&&**
論理積（かつ）
両方の式がtrueの場合にtrueを返す。

**||**
論理和（または）
どちらかの式がtrueの場合にtrueを返す。

**!**
否定
式の結果を反転させる。


例えば、以下のように使用することができます。

```javascript:if.js
var x = 5;
var y = 10;

if (x < y) {
  console.log("x is less than y");
}

if (x == 5 && y == 10) {
  console.log("x is 5 and y is 10");
}

if (x !== "5") {
  console.log("x is not a string with the value of 5");
}
```

上記の例では、<、==、!==演算子と、&&演算子が使用されています。
注意すべき点として、==演算子と===演算子の違いがあります。
前者は型の変換を行うため、異なる型の値でも比較が可能であるため、注意して使用する必要があります。


===や!==など、言語によって使用できるできないとか、使い方が違うとかありますね。
JavaScriptの場合は型まで判断するときに使用できるみたいです。
firestoreの設計書フォーマットのご紹介

こんにちは。[virapture株式会社](https://virapture.com)でCEOしながら[ラグナロク株式会社](https://ragna-rock.com)でもCKOとして働いている[@mogmet](https://twitter.com/mogmet)です。
![mogmet.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42234/fef919f4-8bca-b924-ebb9-fd1a44d36cc9.jpeg)
リリースが立て込んでなかなかアウトプットができてなかったのですが、本日から再開しようと思います！
本日はfirestoreの設計書を書くときに私が使っているフォーマットの紹介です。

## 前提

firestoreの設計書として必要な要素としては、CollectionのPATH情報、フィールドの要素についてが分かれば十分と考えています。
リポジトリのREADME.mdでマークダウンで書く方法もありますが、保守しづらい部分もあったのでconfluenceなどのドキュメント管理ツールで作ることをお勧めします。

## 設計書フォーマットの紹介

今回はチャットサービスを考えた場合のサービスで設計をしてみます。
では早速紹介します。

![CleanShot 2023-03-29 at 07.52.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42234/2a5b7eb2-ba19-44ec-f6cf-e414076e397a.png)

下記にコピペ用のフォーマットを記載しておきます。

```
## 基本構造
### users/{uid}

ユーザ情報をまとめる
uidはFirebaseAuthenticationのuidと同等

|Field|Type|Description|Sample|
|---|---|---|---|
|createdAt|Timestamp|作成日時|1987-12-01 00:00:00|
|username|string|ユーザ名|もぐめっと|

### chatRooms/{chatRoomId}

チャット部屋一覧。
lastChatに関してはCloudFunctionsで自動的に更新される。

|Field|Type|Description|Sample|
|---|---|---|---|
|createdAt|Timestamp|作成日時|1987-12-01 00:00:00|
|updatedAt|Timestamp|作成日時|1987-12-01 00:00:00|
|title|string|部屋名|もぐめっとの部屋|
|lastChat|string?|最後のチャット|犯人はヤス...|

### chatRooms/{chatRoomId}/chats/{chatId}

チャット部屋に送信されるチャット情報。

|Field|Type|Description|Sample|
|---|---|---|---|
|createdAt|Timestamp|作成日時|1987-12-01 00:00:00|
|chat|string|送信されたチャット|犯人はヤス...|


## ビジネスプラン周りの構造

...
```

見出しをPathにすることで目次を表示したときに一覧してみやすくなるのでとてもおすすめです。
Pathに関してはDocument IDに対して特筆があれば記載しています。

コレクションの説明について、さらに実際の画像なども一緒に乗せるとなおわかりやすい設計書になると思います！
また、ある程度コレクションに塊の意味があれば別途H2で分けるとよりわかりやすくなります。（課金周りの構造をまとめるなど）

## まとめ

Firestoreの設計書のテンプレートになるようなフォーマットを紹介いたしました。
是非新規サービスを作るときの参考にしてもらえたら幸いです。

最後に、スノボの楽しく滑るコツを掴める [cotsume](https://cotsume.page.link/blog) というアプリを作ってます！よかったらDLしてみてね！

https://cotsume.page.link/blog

また、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)、問い合わせ対応が簡単にできる[CSmart](https://csmart.jp/lp)、フリーランスのコミュニティの[NextFreelance](https://next-freelance.net/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

https://csmart.jp/lp

https://next-freelance.net/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/

ラグナロクでもエンジニアやデザイナーのメンバーを募集しています！！楽しくぶち上げたい人はぜひお話ししましょう！！

https://ragna-rock.com
docker の中で docker 使う方法（メモ）

# 概要

リリース環境など docker の中で docker クライアントを使いたい場合のメモ。
セキュリティ上の問題があるので docker 自体公開しない前提。
cdk のリリース環境など、docker の中で docker 走らせる必要がある場合に使う。
ホスト側（WSL2）に docker がインストールされており、docker からは docker クライアントのみ使う。

# Dockerfile に下記を追加

```Dockerfile
# install docker client
RUN apk add --update curl && rm -rf /var/lib/apt/lists/*
ENV DOCKER_CLIENT_VERSION=1.12.3
ENV DOCKER_API_VERSION=1.24
RUN curl -fsSL https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_CLIENT_VERSION}.tgz \
  | tar -xzC /usr/local/bin --strip=1 docker/docker
```
Googleデジタルマーケティング＆Eコマース：Google Adsのパフォーマンスプランナー

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8957baaf-ce73-a2a4-19cd-72db89b6874f.png" width="800">

# Google Adsのパフォーマンスプランナー

[以前、特別なイベントや祝日をマーケティングやプロモーションのチャンスととらえることについて学びました。][event]今回は、このようなイベントを想定したGoogle広告の機能について学びます。

[event]: https://qiita.com/mapami/items/9e860c5c4c569fb1b951

特別なイベントや祝日には、オンラインで商品を購入するために検索する人が増えるため、ECショップはコンバージョン率（この場合は広告をクリックする人の数）の増加を望んでいます。Google広告では、パフォーマンスプランナーを使用することで、このような事態に備えることができます。

パフォーマンスプランナーは、Google Ads内の便利なツールで、検索、ディスプレイ、ショッピングキャンペーンのパフォーマンスを予算に基づいて予測することができます。つまり、週末セールやスペシャルイベントセールなどの将来の成果を予測することができます。また、このプランナーは、お客様のビジネスの種類や場所に基づくシーズナリティにも対応します

キャンペーンの変更が全体的なパフォーマンスやコンバージョン、コンバージョン値、クリック数などの主要な指標にどのような影響を与えるかを確認することができます。

さらに、パフォーマンスプランナーを使用することで、以下のことが可能になります。

- キャンペーン設定を調整することによる成果の検証
- 季節ごとの機会把握
- アカウントとキャンペーン全体の予算管理

# How it works

パフォーマンスプランナーは、キャンペーンの履歴と数十億の検索クエリを使用して、キャンペーンのパフォーマンスに関する予測（フォーキャスト）を作成するツールです。このツールは、広告予算の計画を立てるのに役立ちます。

スマート入札の調整を行うのとは異なり、パフォーマンスプランナーは既存のキャンペーンに依存します。キャンペーンに予測を作成するのに十分なコンバージョンがない場合でも、十分なクリックがある場合は、コンバージョン率を手動で入力してコンバージョン予測を評価することができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c3684bc4-6b59-4bcf-6a78-dca1acf1e077.png" width="７00">

# パフォーマンスプランナーツールの使用条件

スタンダードキャンペーン、またはスマートショッピングキャンペーンでパフォーマンスプランナツールを使用するには、以下の条件が必要です。

- 過去7日間に少なくとも100インプレッションを獲得していること。
- 過去10日間に少なくとも10件のコンバージョンまたはコンバージョンバリューを獲得していること。
- 過去10日間に最低10ドル以上の買い物をし、毎日アクティブであったこと。

# 参考

- [Get your campaigns ready for the holidays](https://support.google.com/google-ads/answer/6167153?hl=en): Read about the tools Google Ads offers to help you get ready for holiday advertising.
- [About Performance Planner](https://support.google.com/google-ads/answer/9230124?hl=en): Read more about the features offered with the Performance Planner
【VueJS】郵便番号から住所検索するライブラリ

yubinbango-core2というライブラリを使用し、郵便番号から住所検索を実現します。

環境
laravel9
Vue.js3

# インストール

```
npm i yubinbango-core2@^0.6.3
```
packege.jsonに追記されていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/3245fcda-b37f-81c3-b04c-51f4dd316f21.png)

# コード

```vuejs:Create.vue
<script setup>
    import { Core as YubinBangoCore } from "yubinbango-core2";

// 数字を文字に変換 第１引数が郵便番号
// 第２がコールバックで引数に住所
const fetchAddress = () => {
    new YubinBangoCore(String(form.postcode), (value) => {
    form.address = value.region + value.locality + value.street
    })
}

</script>

<template>
    <input name="postcode" @change="fetchAddress">
    <input name="address">
</template>
```
Googleデジタルマーケティング＆Eコマース：Eコマース戦略最適化のための効果的なテクニック

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8957baaf-ce73-a2a4-19cd-72db89b6874f.png" width="800">

# 業界のブームとスランプに関する調査をより多く行う

Eコマースのトラフィックが急増する時期や減速する時期を知ることは、事前の計画を立てる上で非常に重要です。

Google Trendsは、世界中の市民がGoogleで何を検索しているかを調べることができるGoogleのツールです。Eコマース製品に関連する単語やトピックをインターフェイスに入力するだけで、そのトピックに関する検索関心の高さを知ることができるのです。統計は、指定された地域と時間のチャート上の最高点からの相対的なものです。その単語やフレーズがどれだけ検索されたかを判断することができます。

花屋がオンシーズンの別のピーク日を特定したい場合、Google Trendsフォーラムに「花」と入力することができます。過去1年間に「花」という言葉が検索された時間の統計が表示されるのです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/ae711426-224d-4873-1b09-ce0346ad3dda.png" width="600">

- グラフの中で最も大きなスパイクを描いているのは、5月頃です。母の日は花屋にとって最も忙しい日であり、ほとんどの国で母の日は5月頃に当たるので、このスパイクはそれを裏付けるものです。
- しかし、2つ目のスパイクがいつ起こるか、想像がつきますか？Google Trendsのタイムラインを見ると、このスパイクは2月中旬に発生していることがわかります。これは、恋人や友人が花の贈り物を交換する人気の祝日、バレンタインデーと相関しています。

これはほんの一例です。花屋やeコマースのアナリストは、このツールを使って、自分たちの業界にとってピークとなりうる他の日を特定することができます。ピークとなりそうな日を把握したら、その日に合わせてプロモーション・イベントを実施し、売上を伸ばすことができます。期間限定セール、割引、送料無料などのインセンティブを盛り込むことができます。

# 購入プロセスをシンプルにする

ショッピングカートを放棄してしまったことはありませんか？これは、オンライン注文のチェックアウト処理を開始したものの、購入が完了しないことを指します。多くの場合、これは購入プロセスが複雑であることが原因です。チェックアウトボタンを見つけるのに非常に苦労したり、商品を購入するために不必要なステップが複数あったりすることがあります。このようなプロセスのために、あなたはオンラインストアから離れ、二度と戻ってこないかもしれません。

このような問題を「ペインポイント」と呼びます。Eコマースでは、ペインポイントとは、現在または将来の顧客がサイトとのやり取りの中で直面する特定の問題と定義されます。ペインポイントを解決することで、購入者のブランド体験が向上し、顧客を再びサイトに呼び戻すことができる可能性があります。

多くの場合、企業はユーザーが直面している問題に的を絞り、サイトの側面を再設計するためにユーザーエクスペリエンスデザイナーを雇います。初級デザイナーであれば、ショッピングカートの放棄とも呼ばれる、買い物客がショッピング体験から離れることを決めたプロセスの場所を特定することを任される可能性が高いでしょう。

もしあなたがEコマース事業を営んでいるのであれば、すぐにユーザーエクスペリエンスデザイナーを雇う必要はないでしょう。多くの中小企業は、顧客アンケートやフォーカスグループなどの簡単な調査を実施・分析することで、顧客のペインポイントを特定します。

問題の原因を特定したら、Eコマース・プラットフォームが提供するリソースを利用して、購入体験をシンプルにすることができるのです。

# 価格設定を再考する

Eコマースビジネスには、使ったお金よりも多くのお金をもたらすことが不可欠なのです。商品の価格を設定するとき、商品の価値を高く設定したくなることがあります。理論的には、商品価値を高く設定すれば、お客さまが購入したときに、より多くのお金を稼ぐことができますよね。しかし、価格が高いと、お客様に商品を選んでもらえなくなる可能性があります。商品の価値を下げろとは言いませんが、新規購入者やリピーターにとってリーズナブルな商品出品価格にすることが大切なのです。

さらにもう一歩踏み込んで、他の小売業者と競争できる商品価格にすることもできます。これは、特定の商品の価格を、競合他社と同じかそれよりも低くなるように調整することを意味します。Googleショッピングのタブに商品が表示されたとき、その低い価格帯が目立つようになります。このテクニックを使用する場合は、妥当なROIデータを算出していることを確認してください。
64x64ドット12時短針メーターを作る2(STM32G071)(SSD1306)


フォント仕様

0時から11時までを作る


![o_cop451.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/64a1e74b-f89d-7854-e544-a7ebb53328da.jpeg)

![o_cop452.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5f297d16-1c5b-a7b5-7aa1-ac8b9b809ba8.jpeg)
64x64ドット12時短針メーターを作る1(STM32G071)(SSD1306)


目的
とりあえず長針を作って
後で短針を合成する

仕様

短針のみ
64x64固定
真円
0時から11時のまでの1時刻みで12バターン
配列は、縦に結合
線の太さは、1ドット
めもりあり

![o_cop450.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d9564319-1b2b-75ff-ff8b-98474b2810d3.jpeg)
mp4ファイルをm3u8ファイルに変換する

## 事前準備
以下の事前準備が必要です。

- [【Windows/Mac/Linux（Ubuntu）】Node.jsインストール方法](https://qiita.com/ryome/items/eec08b28aff294e8c3d6)

## フォルダ構成

```
.
├─index.js
├─【任意】.mp4
├─package-lock.json
├─package.json
└─node_modules
    └─...省略
```

## コード
```js:index.js
const ffmpeg = require('fluent-ffmpeg');
const ffmpegStatic = require('ffmpeg-static');

// MP4ファイルのパス
const inputPath = process.argv[2];

// 出力M3U8ファイルのパス
const outputPath = 'output.m3u8';

// ffmpegのパスを強制的に設定
ffmpeg.setFfmpegPath(ffmpegStatic);

// MP4からM3U8への変換処理
ffmpeg(inputPath)
  .outputOptions([
    '-codec:v libx264',
    '-codec:a aac',
    '-hls_time 10',
    '-hls_list_size 0',
    '-f hls'
  ])
  .output(outputPath)
  .on('end', () => {
    console.log('変換が完了しました。');
  })
  .on('error', (err) => {
    console.error('変換エラー: ', err.message);
  })
  .run();
```

```json:package.json
{
  "name": "m3u8",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ffmpeg-static": "^5.1.0",
    "fluent-ffmpeg": "^2.1.2"
  }
}
```

## 使い方

1. `MP4` ファイルを配置する
2. `npm install` コマンドを実行する
3. `node index.js 【任意】.mp4` コマンドを実行する
4. 以下のように `output.m3u8` と `output0.ts ...etc` が作成されていれば成功

```
.
├─index.js
├─input.mp4
├─output.m3u8
├─output0.ts
├─output1.ts
├─output2.ts
├─output3.ts
├─output4.ts
├─output5.ts
├─package-lock.json
├─package.json
└─node_modules
    └─...省略
```

## GitHub

GitHubにソースコードを公開しています。

https://github.com/ryomeblog/Mp4ToM3U8Converter