OmniAICreator/Qiita-1.07M huggingface dataset:
VaccImageのバイアル計算について

VaccImageについては、  

 [VaccImage](https://github.com/YohYasushi/VaccImage "VaccImage")

に記載のとおりです。  
ワクチンのバイアル管理を目的としたWebアプリです。Ver1.0.1までは本当にひどいスパゲッティCodeだったんですが、Ver2.0.0ではSQLを駆使し、随分と見通しがよいCodeになりました。  
今回はVaccImageについて初回のQiita投稿ということで、バイアル計算について取り上げてみます。  

他の先生方がどうしているか知りたいのですが、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/VaccImage?src=hash&amp;ref_src=twsrc%5Etfw">#VaccImage</a> <br>インフルでも新コロでも。ワクチンのバイアルの計算、とくに余りが生じることによる破棄バイアル含めた使用バイアルの計算はどうしてますか？<br>割算の余りの計算になって、結構ややこしいんですが？</p>&mdash; 楊 泰(Yoh_Yasushi): 何にも無い科専門医/総合内科専門医💦 (@Yoh_Yasushi) <a href="https://twitter.com/Yoh_Yasushi/status/1484644541311623169?ref_src=twsrc%5Etfw">January 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ここでわかりやすくPythonで書くとGitHub上で、
 [こちら](https://github.com/YohYasushi/VaccImage/blob/main/VaccImage.ipynb "VaccImage")
にも上げたんですが、直接書くと、

```
NA = int(input('大人の接種人数'))
NC = int(input('子供の接種人数'))
Ap = int(input('大人の接種ポイント数'))
Cp = int(input('子供の接種ポイント数'))
Vp = int(input('1バイアルの接種ポイント数'))

#インフルエンザワクチンを想定すると、Ap=2, Cp=1, Vp=4になります。
#ファイザーCOVID19を想定すると、Ap=3, Cp=1, Vp=18になります。

Tp = (NA * Ap) + (NC * Cp)
print('合計接種ポイント(Tp): ',Tp)

print('Tp/Vp(割り算しただけのもの): ', Tp/Vp)
print('Tp/Vpの整数部分: ', int(Tp/Vp))
print('Tp/Vpの余り: ', Tp%Vp)
print('半端バイアルで打てるポイント:', Vp-(Tp%Vp))

if((Vp-(Tp%Vp)) == Vp):
    print('破棄分も含めた必要バイアル(TotalVials): ', int(Tp/Vp))
else:
    print('破棄分も含めた必要バイアル(TotalVials): ', int(Tp/Vp) + 1)    
```

という事になります。  
剰余の計算など、文章で書くよりCodeのほうがわかりやすいですよね。  

半端のバイアルの計算って現場ではかなり面倒くさい。If文で仕分けしてあげないと、バイアル数を過小評価しちゃうんですよね。  
これ、結構現場では困っているのじゃないでしょうか。  

IF文で仕分けがいるので(フツーに考えたら)、その時点でExcelじゃ処理が面倒なんですよね。  
このあたりが、VaccImageの開発のモチベになりました。  
また、不定期ながら、VaccImageについて投稿していきます。
【React】react-router-dom v6について

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## react-router-dom v6について

### v6の基本的な書き方

```Router.jsx

// <BrowserRouter>で <Routes>,<Route>を囲む
<BrowserRouter>
    {/* <Routes>で<Route>を囲む */}
    <Routes>
        {/* path="Url" element={コンポーネント} */}
       <Route path="/" element={<Home />} />
       <Route path="teams" element={<Teams />}>
         <Route path=":teamId" element={<Team />} />
         <Route path="new" element={<NewTeamForm />} />
         <Route index element={<LeagueStandings />} />
       </Route>
    </Routes>
  </BrowserRouter>
```

```.jsx

// "/"へのリンクを作成
<Link to="/">ホームへ</Link>

// "/"へ遷移する処理を追加
<Navigate to="/" />;

```
データベース、SQL・MySQLの基礎

#データベースの基礎について
先日データベースの基礎学習を行った為、情報を整理するために投稿。
まずはデータベースの基礎について
※本記事では、RDB（リレーショナルデータベース）を管理方式とする。

##リレーショナルデータベースとは
データを表形式で管理するデータベースのこと。
![スクリーンショット 2022-01-22 3.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754263/e0e6778f-cfb7-3c51-bd50-b4dea181aeb2.png)

##テーブル
表全体のこと


##レコード
行のこと。上の表では、４レコード存在している状態。

##カラム
Id、言語、目的、使用場所という4つの属性があり、これら属性の事をカラム又はフィールドと呼ぶ。

##主キー、プライマリーキー
カラムの中でも、データを特定することが可能なカラムを指す。複数のカラムを組み合わせて複合キーと呼ぶ事もある。

##ユニークキー
データの重複を許さないカラムというものが存在する。（アカウント名、メールアドレス等）
データの登録時、重複データは登録できないようにするカラムには、ユニークキーという制約を設定する。
※設定方法は後述

![スクリーンショット 2022-01-22 3.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754263/3b32a4ee-2711-11a2-4500-ff6b2745d364.png)

##外部キー
他の表(テーブル)と関連付けされているキーのこと。
上記の表のように、データが重複している箇所がある。
そこで言語と用途でテーブルを分け、データをIdで関連させるようにすることで、データの冗長性や不盤合を減らすことができる。この時、参照先の主キーが外部キーとなる。
また、データの重複をなくすことを正規化という。
![スクリーンショット 2022-01-22 4.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754263/51d58ae8-5a0e-aeca-d6d0-6e9a48026a2b.png)


＜次回の記事＞
・データベース、SQL・MySQLの基礎（テーブルの作成から削除）
https://qiita.com/TaikiTkwkbysh/items/d1d38dda0f5844f7603b
2022/1/22主にITとかセキュリティの記事

「LINE VOOM」で非公開の友だちに投稿を閲覧される不具合
https://www.security-next.com/133479

ペット用品通販サイトに不正アクセス - 閉鎖直後に被害が判明
https://www.security-next.com/133202

2021年4Qの脆弱性届出、ソフトとウェブともに減少
https://www.security-next.com/133477

「Drupal」に複数脆弱性 - サードパーティ製ライブラリに起因
https://www.security-next.com/133528

悪意あるファイルの検知、前年比5.7％増 - 1日平均約38万件
https://www.security-next.com/133163

SQLインジェクションで顧客アドレス9万8,635件が流出か、石橋楽器店(1/19)
https://cybersecurity-jp.com/news/62662

サイバー攻撃でサイト壊滅、マルカンからカード情報1,152名流出か(1/19)
https://cybersecurity-jp.com/news/62664

五輪選手の健康管理アプリに「欠陥」、個人情報筒抜けに(1/20)
https://www.yomiuri.co.jp/olympic/2022/20220120-OYT1T50003/

バイデン大統領、NSAや国防総省のサイバー防衛強化に関する覚書に署名(1/20)
https://japan.zdnet.com/article/35182346/

長引きがちなオンライン会議の処方箋、対話加速に効くアフラック生命の5原則(1/20)
https://xtech.nikkei.com/atcl/nxt/column/18/01902/122800002/

デジタルアーツ、メール経由のランサムウェア攻撃に対する対策のホワイトペーパーを公開(1/20)
https://securityinsight.jp/news/13-inbrief/4891-220120-2

テレワーク時のセキュリティ対策として実施していること第1位は？(1/20)
https://news.mynavi.jp/techplus/article/20220120-2253025/

赤十字国際委員会、サイバー攻撃で51万人以上の行方不明者などの個人情報が漏えい(1/20)
https://www.itmedia.co.jp/news/spv/2201/20/news089.html

物理的に隔離されたエアギャップネットワークを攻撃するマルウェアフレームワークの手口(1/18)
https://ascii.jp/elem/000/004/080/4080513/

他人の携帯電話アカウントに不正アクセス　ゲーム機など購入した疑いで28歳女を逮捕【新潟】(1/19)
https://news.yahoo.co.jp/articles/bf41194cced32d87276cefe1074ed0e21abf144d

約8.4万のeコマースサイトに影響与えるWordPressプラグインの脆弱性発見(1/18)
https://news.mynavi.jp/techplus/article/20220118-2250803/

感染した端末「だけ」の対処がダメな理由(1/18)
https://news.mynavi.jp/techplus/article/SmallandMediumEnterprises_security-5/

パソコンがウイルスに感染…“サポート詐欺容疑”国内初検挙　フィリピン人3人逮捕(1/18)
https://news.tv-asahi.co.jp/news_society/articles/000241891.html

jQueryでできること一覧を紹介！スライドショーの作成も可能(1/20)
https://and-engineer.com/articles/YV6t9REAACMA7qVD

個人情報保護委員会から個人情報が漏えい ⇒「公式が矛盾している」厳しい指摘相次ぐ(1/19)
https://news.yahoo.co.jp/articles/98e416a58a046ca2c339a93431c2c285b76eb1d1

ネットバンク詐欺容疑　組員ら3人を3度目の逮捕　沖縄県警(1/19)
https://ryukyushimpo.jp/news/entry-1456547.html

赤十字の委託業者にサイバー攻撃、紛争や災害被災者５１万５千人の情報侵害(1/20)
https://www.cnn.co.jp/tech/35182341.html?ref=rss

またも封殺される日本企業。ゲーム業界をも「囲い込む」マイクロソフトのデファクト・スタンダード戦略(1/20)
https://www.mag2.com/p/money/1147981

キヤノン製レーザープリンタと複合機の一部に脆弱性、アップデートを(1/20)
https://news.biglobe.ne.jp/it/0120/mnn_220120_0558586600.html

高齢者の携帯に不審メッセージ　連絡するとカードを用意するよう指示　福岡県久留米市(1/19)
https://www.nishinippon.co.jp/sp/item/n/864029/

自治体DXで膨らむ行政負担、システム標準化でもコスト削減できない懸念(1/21)
https://xtech.nikkei.com/atcl/nxt/column/18/00989/011900073/

「ウイルス作成罪」乱用捜査の歯止めになるか、Coinhive無罪判決でも残る課題(1/21)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/06480/

DXはトップダウン？ボトムアップ？名物CIOが効果的な進め方を指南(1/21)
https://xtech.nikkei.com/atcl/nxt/column/18/01698/122400021/
Styled-componentsで背景画像を使う際のメモ

## 背景

Propsを受け取って背景画像をするときに
どうすんだ！？と思い調べていると
ついつい毎回覚えないのでメモ


## 結論

```

//typescriptバージョン

interface IBgImageProps {
	bgImage?: string;
}



const Content = styled.div<IBgImageProps>`
    background-image: url(${props => props.bgImage});
`;


//通常


const Content = styled.div`
    background-image: url(${props => props.bgImage});
`;


//jsx側

import {bg} from "assets/image";

<StyledBg bgImage={bg}>
　　テキストテキスト
<StyledBg>
	
```

## まとめ

色々とできるが
ついつい忘れがち。。。

とはいえ
色々とできるので、忘れそうになったらメモしていこう
unbound による DNS フィルタリング

`a-records.conf` にフィルタリングしたい FQDN と、それに対応する dummy の A レコードを記載する

```a-records.conf
# A Record
  #local-data: "somecomputer.local. A 192.168.1.1"
  local-data: "filtered.host.com A 0.0.0.0"

# PTR Record
  #local-data-ptr: "192.168.1.1 somecomputer.local."
  local-data-ptr: "192.168.1.2 laptop.local."
```

unbound の docker を動かして終わり。

```
docker stop my-unbound && \
docker rm my-unbound && \
docker run --name my-unbound -d -p 53:53/udp -v $(pwd)/a-records.conf:/opt/unbound/etc/unbound/a-records.conf:ro --restart=always mvance/unbound:latest
```

ちなみに

Chrome の dev tool で、 network のところで Copy all as HAR みたいにすると、 JSON でとれる。その URL を取得するには、以下のようなかんじで jq をすれば OK

```
cat xxx.json | jq .[].entries[].request.url > yyy.txt
```

あるいは

```python
import json
from string import Template
from urllib.parse import urlparse

# JSON file をロード
a = json.load(open('./a.json', 'r'))

# hostname だけとる
hostname_set = set()
for e in a['log']['entries']:
    url = e['request']['url']
    u = urlparse(url)
    hostname_set.add(u.hostname)

# フィルタリングしたくない hostname のリスト
excepted_hostnames = [
    'google.analytics'
]

# Generate config string.
template = Template('  local-data: "${hostname} A 0.0.0.0"')
for h in sorted(hostname_set):
    if h in excepted_hostnames:
        continue
    print(template.substitute(hostname=h))
```
【Laravel】jetstreamをinstallする際に「Error Class 'Inertia\Inertia' not found」が出る対応メモ

# はじめに

Laravelにjetstreamを導入する際に「Error Class 'Inertia\Inertia' not found」が出たのでその対応の自分用メモ。

# 解決

```
$ php artisan jetstream:install livewire
$ npm install && npm run dev
```

次に、seed流し、キャッシュを切ればOK

# 参考

https://laracasts.com/discuss/channels/livewire/laravel-8-jetstream-livewire-inertia-error
[Ruby]ハッシュのアレコレ

学んだことのアウトプット
ハッシュを使ったコードを書きながら「あれ？どうやったっけ？」となったので復習しました

###"ハッシュ"とは
「データ」とそれに対応する「名前」のセットを要素として持つ値。
データを`バリュー`、それに対応する名前を`キー`と呼ぶ。
配列と同じように、複数の値を持つことができるし、配列にハッシュ自体を入れ込むことも可能。

```ruby
#ハッシュの宣言
変数 = {}

#下記２つは出力すると同じものが出力される
変数 = { キー1 => バリュー1, キー2 => バリュー2, キー3 => バリュー3 } 
変数 = {キー1: バリュー1, キー2: バリュー2, キー3: バリュー3} #シンボルを使うとシンプルに書ける
```

##ハッシュに値を追加する

```ruby
ハッシュ[追加するキー] = 値

#例
teacher = { name: "Mike", age: 25 }
teacher[:subject] = "English"

puts teacher #=>{name: "Mike", age: 25, subject: "English"}
```

##ハッシュの値を取得する

```ruby
ハッシュ[取得したい値のキー]

#例
teacher = {name: "Mike", age: 25, subject: "English"}

puts teacher[:name] #=>Mike
```

##ハッシュの値を変更する

```ruby
ハッシュ[変更したい値のキー] = 値

#例
teacher = {name: "Mike", age: 25, subject: "English"}
teacher[:name] = "Emma"

puts teacher[:name] #=>Emma
```

以上。
【JavaScript】ES2021で使えるようになった機能

今更ながら、ES2021で使えるようになった `JavaScript` の新しい機能をさらっと振り返ります。

# Numeric Separators
- 数値セパレータ
- 数値を_で区切れるようになった
- 数値の可読性を上げられる
- あくまで人間がみやすいようにするだけで、実体は `_` が無い状態

```typescript
10000 === 10_000 // true
100000000 === 100_000_000; // true
```

# String.prototype.replaceAll
- 文字列全体に対して置き換えを行う
- 今までは正規表現で 「g」オプションでグローバルサーチを行っていたが不要になった

```typescript:ES2021
'0120-123-4567'.replaceAll('-', ''); // 01201234567
```

```typescript:2021以前
'0120-123-4567'.replace(/-/g, ''); // 01201234567
```

# Promise.any
- 複数のPromiseを渡した時に、何かしらの値が resolve されるまで待ってくれる
- Promise.allは「全てのPromiseが成功したら」

```typescript
const promise1 = Promise.reject(0);

const promise2 = new Promise((resolve, reject) =>
	setTimeout(resolve, 1000, 'quick')
);

const promise3 = new Promise((resolve, reject) =>
	setTimeout(resolve, 1500, 'slow')
);

// この場合、一番最初にresolveされる「promise2」のquickが返る
Promise.any([promise1, promise2, promise3])
	.then(resolve => console.log(resolve))
	.catch(reject => console.log(reject));
```

# Logical Assignment Operators
- 変数への代入がよりシンプルになった
- 論理演算子 + 代入演算子

```typescript:ES2021
// 例1：userName が「null」か「undefinded」なら、'test tarou' を代入する
userName ?? = 'test tarou';

// 例2：userName が falsy なら、'test tarou' を代入する
// !!(値) === false の時なので、「?? =」よりも広い範囲で使える
userName || = 'test tarou';

// 例3：userName が truthy なら、'override tarou' で上書きする
userName && = 'override tarou';
```

```typescript:2021以前
// 例1：userName が「null」か「undefinded」なら、'test tarou' を代入する
userName = userName ?? 'test tarou';

// 例2：userName が falsy なら、'test tarou' を代入する
userName = userName || 'test tarou';

// 例3：userName が truthy なら、'override tarou' で上書きする
userName = userName && 'override tarou';
```

- 「??」は、ES2020で追加された「ヌル合体(Nullish Coalescing)演算子(??)」

ヌル合体(Nullish Coalescing)演算子 ?? を用いることで、値が undefined や null の時にデフォルト値を設定するといった処理を、下記の様に記述することが可能となります。

```typescript
// 古い書き方(obj.fooが未設定の場合デフォルト値60を設定する)
if (typeof(obj.foo) == "undefined" || obj.foo == null) {
    obj.foo = 60;
}

// ES2020以降の新しい書き方
obj.foo = obj.foo ?? 60;
```

# WeakRefs
- 弱参照が作れる
- 使うことがなさそう？なので今回は割愛

以上です。
お読み頂き有難うございました。
週末研究ノート　ー　(Easy!) Monty Hall Problem Simulation

# はじめに　ー　週末研究ノートとは？

個人的に研究的な活動をやるにあたり、オープンにしてみたら面白いかもと思い、自分が興味を持っている ざっくりテーマについて、これから、ゆるい週末研究を公開していこうと思います。（有識者の方のアドバイスも、ちょっとというかかなり期待してます！笑）

どこかの権威的な学会やジャーナルなどで発表する予定はないため、万が一、私の記事を利用する際には自己責任でお願いします。そんな人はいないと思いますが、念のため。



# 今回のサマリ （TL; DR）


今回は、閑話休題？！

ひさしぶりに「[モンティ・ホール問題](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C#%E3%82%B2%E3%83%BC%E3%83%A0%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%AB)」に出会ったので、選択肢を変えた場合の確率をシミュレーションしてみました。


# 環境

- [Google Colaboratory](https://colab.research.google.com/?authuser=1)
    - コードは、[こちら](https://colab.research.google.com/gist/tkosht/37e0bf929643a5dda55dd11c97ecd2fa/monty-hall.ipynb?authuser=1)


# 今回の週末研究ノート

モンティ・ホール問題の選択肢を変えた場合について、シミュレーションしたよ♪

## モンティ・ホール問題とは？

「[こちら](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C#%E6%A6%82%E8%A6%81)」（Wikipedia）を参照ください


## 選択肢を変えた時のシミュレーション

```
%%time
n = 100000
n_corrects = 0

for _ in range(n):
    # 正解の車のドアをランダムに決める
    door_car = rnd.choice(doors)

    # ハズレのヤギのドアを記録しておく
    door_goats = [dr for dr in doors if dr != door_car]
    
    # プレイヤーがドアをランダムに１つ選ぶ
    door_pickedup = rnd.choice(doors)
    
    # 司会のモンティがハズレのドアをランダムにオープンにする
    door_opened = rnd.choice([dr for dr in doors if dr not in [door_car, door_pickedup]])
    
    # プレイヤーがドアをランダムに変える
    door_changed = rnd.choice([dr for dr in doors if dr not in [door_opened, door_pickedup]])
    
    # 変更したドアが正解の車のドアだったら、正解数をインクリメントする
    if door_changed == door_car:
        n_corrects += 1

# 正解率を表示
print("正解確率:", n_corrects/n)
```


# まとめ

- 選択肢を変えると、ちゃんと、正解率は $\frac{2}{3}$ になるよ！
- 思ったより、簡単にシミュレーションを実装できた♪


# 参考文献

- [モンティ・ホール問題 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C)
【手順】Macの開発環境構築

記事の目的
-
私が実施した手順を簡潔に記載した記事です。
詳細はリンクとして添付していますので、興味がある方は併せてお読みください。
**参照した記事：https://qiita.com/kenshin1025/items/4ce0521fdf83f0c39048**
##1.Homebrew(パッケージ管理システム)の導入
#####詳細:[新卒エンジニアの開発日記](https://fukatsu.tech/homebrew)
下記リンクにアクセスして「インストール」の下にあるコードをコピーしてください。
https://brew.sh/index_ja
コピーしたコードをターミナルを使って実行します。
>ターミナルの補足:「commandキー」と「スペースキー」を同時に押すと「Spotlight検索」というのが表示されるのでそこに「ターミナル」と入力し、「エンターキー」を押せば開くことができます

「**Press RETURN to continue or any other key to abort**」
一度、上記の表記にてインストールが停止しますが「ENTERキー」を押下することでインストールが継続します。
*※要求されるパスワードはMacの画面解除のパスワードです。*

最後に「Next steps:」の表記後、下記コードを実行。
```brew help```
下の4項目を確認出来れば、Homebrewの構築完了。
「**Example usage:**」「**Troubleshooting:**」「**Contributing:**」「**Further help:**」

##2.VisualStadioCodeの導入
先ほど起動したターミナルにて、下記コードを実行。
```brew install visual-studio-code```
処理が完了すれば、環境の構築は終了です。

##3.環境構築テスト
**概要:ファイルを作成し、ターミナルにてコンパイル後実行**

インストールされたVSコードを起動してください。(アプリとして存在しています)
**1.フォルダ作成**
任意の場所に新規のフォルダを作成し、そのフォルダを選択して開くを押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537607/c694315f-1d9e-664d-aa2d-e0bd1d8614fe.png)

**2.Cファイル(C言語プログラムファイル)の作成**
ファイルを新規作成するボタンを押下してファイルを作成します。
名前は任意で構いませんが拡張子は「**.c**」を使いましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537607/0c8e7129-1206-9c7c-131d-d5f7fd5d5a00.png)

**3.テストコード記入**
ファイルの中に実際にコードを書きましょう。
今回は「Hello World!!」を出力する基本的なコードを使います。

```main.c
#include <stdio.h>
int main(void){
    printf("Hello World!\n");
    return 0;
}
```

コード記載が完了したらファイルを保存してください。
>補足:保存は「commandキー」+「sキー」の同時押しです。

**4.コンパイル→実行**
作成したファイルのパスを取得し、ターミナルで「**cd**」コマンドを使いディレクトリの移動をします。
移動後、「**ls**」コマンドでコンパイルしたいファイルの存在を確認し、そのファイルを「**gcc**」コマンドでコンパイルします。
最後に「**ls**」コマンドでコンパイルされた「a.out」のファイルを確認、実行しターミナル内に
「Hello World!!」が確認されれば、環境構築は完成です。

```terminal:ターミナル内
↓「cd」コマンド
cd コピーしたパス

↓「ls」コマンド
ls

↓「gcc」コマンド
gcc 拡張子含むファイル名

↓実行コード
./a.out
```

>パス貼付の補足:「commandキー」+「vキー」
パス取得の補足:ファイルのパスは画像の状態で「optionキー」あるいは「altキー」を押すと表示が変わりますので「〇〇のパス名をコピー」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537607/37cec878-a0e9-21d5-4161-1dfc40a87f7c.png)
1月の予定：LINUXの実装強化月間中

1月の実装内容：
-----
*/21: iptablesでパケットフィルタリングを実装
*/22: SAMBAの実装
*/23: OpenLDAPの実装
*/24: 暗号化ファイルシステムの実装
*/25: user / server認証の実装
*/26: X.509証明書の実装
*/27: 公開鍵の実装
*/28: DNS（BIND）の実装
*/29: iptablesでパケットフィルタリングを実装
*/30: LDAPディレクトリの実装
*/31: PostFixとDovecotの実装

-----
見てね～～～～～～～～(=^・^=)
[html][scss] ボタン

ボタンのhtmlとscssです。

```html:index.html
<div id="container">
    <button class="btn">Button</button>
</div>
```

```scss:style.scss
$cWhite: white;
$cBlack: black;

#container {
    text-align: center;
}

.btn {
    background-color: $cWhite;
    color: $cBlack;
    border: 1px solid $cBlack;
    padding: 10px 40px;
    margin: 50px 0;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;

    &:hover {
        background-color: $cBlack;
        color: $cWhite;
    }
}
```
WSL2のUbuntuでRustを経由してexaやbatコマンドを使えるようにする

# はじめに

WSL2 の環境で `exa` や `bat` コマンドを使いたいなと思ってインストールしたのですが、1度 Rust をインストールしてから導入する方が良さそうだったので載せておきます。

# `exa` と `bat` とは

`exa` は `ls` コマンドの代替コマンドであり、カラフルで見やすくなっています。

https://github.com/ogham/exa

`bat` は `cat` コマンドの代替コマンドであり、ファイルの拡張子に応じてソースコードの色が変わり、VSCode みたいで見やすくなっています。

https://github.com/sharkdp/bat

# 導入手順

2つのコマンドの導入に当たっては、以下の手順で入れました。

1. Rust のインストール
2. Cargo にパスを通す
3. `exa` と `bat` のインストール

コマンドのインストールでは直接 GitHub から `apt install` やファイルを落としてきてパスを通してもいいのですが、

* WSL2 でデフォルトで入る Ubuntu は `20.04` なのに対し、`exa` は `20.10` 以降のバージョンしか `apt install` で入れられない
* Rust のパッケージマネージャである Cargo でまとめて管理しておく方が後々のアップデートなどで楽

という観点から、Rust のインストールをした上で行う形をとりました。

### 1. Rust のインストール

Rust を WSL2 にインストールする場合、以下のコマンド1つで入れられます。

```
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

コマンドを実行すれば Cargo もインストールされるはずですが、もしインストールされない場合は以下のコマンドで入れます。

```
$ apt install cargo
```

### 2. Cargo にパスを通す

今の状態だと Cargo にパスが通っておらず、`exa` とか `bat` コマンドを入れても実行できないので、パスを通します。

```
$ export PATH="$HOME/.cargo/bin:$PATH"
```

### 3. `exa` と `bat` のインストール

以下のコマンドで2つをインストールします。

```
$ cargo install exa
$ cargo install --locked bat
```

これで2つともコマンドが実行できるようになっているはずです。

# 終わりに

Rust 製のコマンドは多いみたいなので、随時便利そうなのを入れていって Cargo で管理してもいいかもです。

# 参考

* [ls よりも exa を使おう！モダンな Linux コマンド達を紹介](https://qiita.com/navitime_tech/items/c249269a3b47666c784b)
* [Rust をインストール](https://www.rust-lang.org/ja/tools/install)
* [exa](https://github.com/ogham/exa)
* [BAT](https://github.com/sharkdp/bat)
Power Automate: Poeple Picker を使ってみた

# 背景
新しく展開されたっぽいので、会社で使う前に機能確認

# 概要
メンションの時と同じように使えて便利そうですね。
![PeoplePicker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/5c4e9ffd-4fbf-d163-49d2-79d3f6f7db3d.gif)

# 使い方
以下を Input.Choices に追加して、choices を空にするだけっぽい。
選択肢を用意しておきたい場合は、追加しておくことも可能

## ユーザー全員の場合
```json:ユーザー全員
			"choices.data": {
				"type": "Data.Query",
				"dataset": "graph.microsoft.com/users"
			}
```

## チャット/チャネル内のメンバーに限定する場合

```json:限定メンバー
			"choices.data": {
				"type": "Data.Query",
				"dataset": "graph.microsoft.com/users?scope=currentContext"
			}
```

## Default 選択の追加
メンバーのID を、Value に設定してやるだけで、以下のように 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0cf07e38-c6c5-1591-1820-bb5d1e38922d.png)

```json:メンバー設定例
"value": "42cd8ce7-5ed3-446d-98c8-xxxxxxxxxxxx,c0084ef3-0f77-4ab1-806f-xxxxxxxxxxxx"
```

## 追加選択肢
こんな感じで追加することも可能。
普通の選択肢なので、ここは [Adaptive Card Designer](https://www.adaptivecards.io/designer/) で対応してる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0c6f7c58-da03-205c-3bf4-bc09a2b28566.png)

```json:静的ユーザー
            "choices": [
                {
                    "title": "Guest User 1",
                    "value": "c0084ef3-0f77-4ab1-806f-xxxxxxxxxxxx"
                },
                {
                    "title": "Guest User 2",
                    "value": "29619b8b-f5ff-4be0-9bdf-xxxxxxxxxxxx"
                }
            ],
```

# あとがき
結構 [Adaptive Card Designer](https://www.adaptivecards.io/designer/) が便利なんですが、未対応なのが悲しい。
でも、対応は難しいかもですね。

# 参考資料
https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/people-picker?tabs=desktop&fbclid=IwAR3NObEbw52dVDEz6WLdIEvbD-yUhOo_jqVdA4UNiuTOIdKi_IlJNSeLUJw
shield effectをvfx graph/ShaderGraphでつくろう

VFXGraph練習メモ

## 完成品

https://twitter.com/mustankatti/status/1484525963782520834

## 元ネタ


Gabriel Aguiar Prod. がチュートリアル作ってる

<iframe width="560" height="315" src="https://www.youtube.com/embed/IZAzckJaSO8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## 雑解説

ShaderGraph

![ShaderGraph](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15000/9653ed17-73ff-4916-8770-5be8a1d81c91.png)

VFXGraph

![VFXGraph](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15000/214996c8-efea-f5fb-796b-b9d03231aa91.png)

blender: icosphere

![icosphere](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15000/8a2bf0b1-87ab-0d74-c743-c9971be79e56.png)

### 1. モデル作成

1. icosphereを作成. (subdivide)
1. modifierを適用 (subdivision)
1. いらない頂点を削除
1. UVをいい感じに分離 (ここが難しい. 一度UVマップを削除しつつ、全頂点選択してunwrap、五角形と六角形に分離)
1. 個別の六角形、五角形に面分割する (Split Faces by Edge)
1. UVは線分付近を光らせるようにリソース作成する

めんどくさければ下記DL

- [shield.fbx](https://github.com/mattak/ShaderGraphDiscipline/blob/master/Assets/Learnings/Learning005_Shield/shield.fbx)
- [shield_uv_fill.png](https://github.com/mattak/ShaderGraphDiscipline/blob/master/Assets/Learnings/Learning005_Shield/shield_uv_fill.png)

### 2. VFXGraph作成

大きく４つのブロックで構成

1. EdgeColor (UVTextureから線分の色付けをする)
1. Fresnel (球の周囲を光らせる)
1. NormalPosition (ObjectPositionをとって、面垂直方向にモデルの各面をバラす)
1. Time (NormalPositionの動きをアニメーションで管理)

ポイント
- URPのShaderGraphとして作成
- VFX SupportをONにして、VFXGraphから参照できるようにする.
- Transparent設定にしつつ、Bothで両面をレンダリングする

### 3. VFXGraph

作成したShaderGraphを参照する以外は特別な設定なし.

## 振り返り

blenderでのモデリングが3.x系でかなり変わってそこでハマった。
基本動画のとおりに作ればできるが、HDRPでもFresnel系のちょっと差分があってハマるかも.
［Laravel］ポリモーフィックリレーション

# [Laravel]ポリモーフィックリレーション
## とは？？？
超端的に言うと複数テーブルと紐付けることが出来るリレーション
## 経緯
PL「この設計は多対１のポリモーフィックを表していると思うので、設計とそれに伴った実装修正しておいて。」
自分「確かにそうですよね！（は？？？ポリモーフィックとはなんぞや？？？）」
ということで何もわからない状態から1日かけてマイグレーション、モデル、取得、作成処理を書き直しました。
このあたり公式ドキュメントも意外と詳しく書いてくれていなくて、中々苦労したので備忘録とします。
## 実装方法
### テーブル定義

| users|
| ---- | 
|  id  | 

|  admin_users  |
| ---- |
|  id  |

| comments |
| ---- |
| id |
| user_id |
| admin_user_id |

みたいな感じでusersとadmin_userとcommentsテーブルがあるとします。
この際ユーザーも管理者もコメントをかくことが出来るとします。
commentsテーブルのuser_idはusers、admin_user_idはadmin_user_idの外部キーです。
この外部キーを1つに出来るのがポリモーフィックです。
まず結論からこのcommentsテーブルをどう変えるかというと

| comments |
| ---- | 
| id |
| commentable_id |
| commentable_type |
このcommentable_idとcommentable_typeがミソで、comment_typeにどちらのテーブルかを記載し（少し語弊がありますが後で詳しく書きます）、commentable_idにusers、admin_usersのidが入ります。

### マイグレーション
```
$table->morphs('commentable');
```
この1行足すだけで勝手にidとtype両方作ってくれます。

### Model
```
// Userクラス
public function comments()
{
    return $this->morphMany(
                  Comment::class,
                  'commentable',
                  )
}
```
```
// AdminUserクラス
public function comments()
{
    return $this->morphMany(
                  Comment::class,
                  'commentable',
                  )
}
```
```
// Commentクラス
public function commentable()
{
    return $this->morphTo();
}
```

こちらで下処理完璧です。
ちなみに自分がハマった原因として、commentableの部分をマイグレーション時点でスネークケースで000_000_idと000_000_typeで表現していたことが原因でこのモデルにカスタム設定を使用しないとリレーションが取れませんでした。（ちなみに取得はできるけど作成ができなくなる）
もし自分と同じ方法でやるなら

```
// Userクラス、AdminUserクラス
public function comments()
{
    return $this->morphMany(
                  Comment::class,
                  null,
                  'commentable_type',
                  'commentable_id',
                  'id'
                  )
}
```
こちらならスネークケース２区切り以上の名前ものも可能です。

### 取得
クエリを使うために、whereHasMorph()を使用します

```
Comment::whereHasMorph('commentable', 
    [User::clss, AdminUser::class], 
     function ($query, $type) {
         $query->~~~~~
     }
     )->get();
```

### 作成
リレーションを繋げて作成処理するという、あまり経験したことのない処理をすることで新規作成出来ます。リレーション先の主キーのidから自動で作成してくれます。
以下が参考コードになります

```
User::find($userId)->comments()->create([~~~]);
```

## 最後に
自分が詰まった部分が調べても出てこないことが多かったので、この記事で同じことに悩んでいる方の一助になれば幸いです。
ちなみに調べていると出てきたと思いますが、ポリモーフィックリレーションはSQLのアンチパターンみたいなので鵜呑みにせず一度は他の方法も考えたみたほうがいいかもしれません。。。
Unity の SystemInfo.deviceModel が表示するiPhoneの情報

Unity の SystemInfo.deviceModel が表示する iOS の情報についてです。


# 結論
https://www.theiphonewiki.com/wiki/Models の Identifier が表示されています。

# 背景
問い合わせ用に Unity の SystemInfo.deviceModel の情報を取得しようとして、自身の端末 iPhone 11 Pro が iPhone 12,3 と表示され、なんのこっちゃと思ったので調べました。
Android は未調査です。

# 参考
* [iPhone iPad 端末での 一般名と内部名の対応表](https://qiita.com/YumaInaura/items/31838a72678fa09d7e19)
npm run dev が上手くできない時の対処法 〜 Error: error:0308010C:digital envelope routines::unsupported 〜

## はじめに
こちら自分用のメモであるためとても雑な記事です。
ただ、同じようなエラーが出た人の助けに少しでもなれば幸いです。
## エラーログ

![スクリーンショット 2022-01-21 22.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/9e7dfc55-f58b-3151-d338-a03e89d2cbce.png)

```.zsh
> 〇〇@1.0.0 dev
> webpack --watch

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:135:10)
```

##原因
Nodeのバージョンが高すぎることが原因のようです

##解決策
Nodeのバージョンを下げる

###環境
macOS Monterey 12.1![スクリーンショット 2022-01-21 23.00.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/214c145a-8a40-7ff0-c76c-d440f451aa50.png)
![スクリーンショット 2022-01-21 23.00.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/e0cfd6f8-3adc-f529-00cf-cc633504f919.png)


###1. Homebrewをインストール (※インストールしている方は飛ばして大丈夫です)
下記リンクからインストール可能です

https://brew.sh/



###2.nodenvをインストール

```.zsh
$ brew install nodenv
```

```.zsh
$ eval "$(nodenv init -)"
```
ここで一度ターミナルを再起動します。

```.zsh
$ curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
```
成功した時のターミナルがこちら↓↓
![スクリーンショット 2022-01-21 23.09.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/e1923c6a-da80-4fca-3f81-42ebf6bd047c.png)

###3.取り入れたいバージョンのNode.jsをインストール

下記コマンドによってインストール可能なNode.jsのバージョンが取得できます。

```.zsh
$ nodenv install -l
```
取り入れたいバージョンを指定してNode.jsをインストールする

```.zsh
$ nodenv install 〇〇.〇〇.〇
```

```.zsh
$ nodenv rehash
```

インストールされているNode.jsのバージョンを確認する

```.zsh
$ nodenv versions
```

###4.Node.jsのバージョンを切り替える

カレントディレクトリ配下で利用するNode.jsのバージョンを切り替えたい場合

```.zsh
$ nodenv local 〇〇.〇〇.〇
```

システム全体で利用するNode.jsのバージョンを切り替えたい場合

```.zsh
$ nodenv global 〇〇.〇〇.〇
```
Reactで作成したアプリをfirebaseにデプロイするときに注意すること

# はじめに
この記事は、`react`, `react-router`で作ったアプリをFirebase Hostingを利用してデプロイしたときに自分がコケた場所を紹介するものです。何かの役に立つと幸いです。

## 環境
- react: ^17.0.2
- react-dom: ^17.0.2
- react-router: ^6.0.0-beta.0
- react-router-dom: ^6.0.0-beta.0

# Reactで階層を含んだURLを直接叩くと404になる；；
## 状況
react-router でルーティングしている

```jsx:App.tsx
<Routes>
	<Route path="/" element={<Home />} />
	<Route path="hoge/:piyoId" element={<Hoge />} />
	<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
```

## 階層を含んだURLを直接アクセスするとエラーになる
![](https://storage.googleapis.com/zenn-user-upload/ea42dc3de8bd-20220121.jpg)

### 上手く行くケース
1. `http://my-app.com/`にアクセス、`<Home />`が表示される。
2. `<Home />`から`http://my-app.com/hoge/1`にアクセス、`<Hoge />`が表示される。

### 上手く行かないケース
- `<Home />`から`http://my-app.com/hoge/1`にアクセスしリロードする → `Page Not Found`
- 階層を含んだページでリロードする → `Page Not Found`
- `http://my-app.com/hoge/1`に直接アクセスする → `Page Not Found`

## 原因
- SPAなのでリソースがないため404になる?

## 解決策
firebaseのドキュメントを見ているとリライトというのを設定すると良いらしいので設定してみる。
リライト：複数のURLで同じコンテンツを表示するために使用するもの
参考 : [ホスティング動作を構成する  |  Firebase Documentation](https://firebase.google.com/docs/hosting/full-config?hl=ja#rewrites)
https://firebase.google.com/docs/hosting/full-config?hl=ja#rewrites


今回は存在しないファイルまたはディレクトリへのリクエストに対してindex.htmlを返したいので下記を設定する。

```json:firebase.json
{
  "hosting": {
    "public": "build",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

これでデプロイして`http://my-app.com/hoge/1`アクセスして確認して終わり〜！！
と思いきや…

## Uncaught SyntaxError: Unexpected token '<' エラーが出てる！！
![](https://storage.googleapis.com/zenn-user-upload/a9209212525b-20220121.jpg)

コンソールを見てみると何やらエラーが出てる…とりあえずjavascriptの読み込みのパスを見てみる

```HTML:index.html
<body>
	...
	<script src="./static/js/2.c291979f.chunk.js"></script>
	<script src="./static/js/main.ca9cdfff.chunk.js"></script>
</body>
```

`./static/js/2.c291979f.chunk.js`と相対パスになっているのが確認できる。
相対パスなので`http://my-app.com/hoge/`からの読み込みなのがわかる。

## 原因
検証の為にネットワークの欄を見てみる
![](https://storage.googleapis.com/zenn-user-upload/4f2a113f71dd-20220121.jpg)

やっぱり相対パスになっているのが原因で別のURLからソースを取得していた！！
読み込まれていたURL : `https://portfolio-abee2.web.app/works/static/css/main.a180d1c6.chunk.css`
期待していたURL : `https://portfolio-abee2.web.app/static/css/main.a180d1c6.chunk.css`

## 解決策
```json:package.json
{
  ...
  "version": "0.1.0",
  "homepage": "/",
```
`package.json`の`homepage`が`./`になっており相対パスになっているみたいだったので、`/`に変更してデプロイしてみる。
参考 : [Deployment | Create React App](https://create-react-app.dev/docs/deployment/#building-for-relative-paths)
https://create-react-app.dev/docs/deployment/#building-for-relative-paths


```HTML:index.html
<body>
	...
	<script src="/static/js/2.c291979f.chunk.js"></script>
	<script src="/static/js/main.ca9cdfff.chunk.js"></script>
</body>
```
正しく表示されるようになった！！よかった！！
git初歩メモ - テキストファイルをローカルリポジトリに登録

#この記事で書くこと
エンジニアの方々にとって、gitは普通に使うツールのようです。趣味でプログラミングをやっていた私はそうした慣習が無かったので、gitを使ったオペレーションには慣れておくべきと考え、gitを使うことにしました。勉強メモとして書いているので、間違いなどあるかと思います。ご容赦ください。（どんどん慣れてきたら都度リバイズしていきます）

##gitを一言で言い表すと
ファイルバージョン管理のツール。プログラミングをしていると、更新を何度も行い、様々なバージョンのファイルができる。そういえば、私が仕事で行っているWeb制作の現場もいろんな改訂版はよくあります。こうしたバージョンを更新ごとに記録していき、取り扱いに間違いが無いようにする仕組みのようです。特に、チームでともに開発していると、ファイルの取り違えなんて考えたくもないマズい事態になることもあるでしょう。
そこで、このツールの意義がでてきます。

##gitを使うには何が必要なのか
PCにgitクライアントというものをインストールします。私のPCはWindowsなので、git Bashというものをインストールしました。コマンドプロントのようなもので、いわゆるCUI（Command Line Interface)です。

##gitを使って、ファイルの登録と上書き、差分の確認をテストしてみた
今回はテストとして以下の通りにやってみました
1. テキストファイルを作成し、所定のディレクトリに格納
2. そのディレクトリにローカルリポジトリを作成
3. 作成したテキストファイルをステージングエリアに登録
4. テキストファイルの中身を変更し、上書き保存
5. ワークツリーで上書き保存したテキストとステージングエリアに登録したテキストとの差分を確認

##各段階で行ったgitコマンド
###テキストファイルを作成し、所定のディレクトリに格納
gitコマンドは使わず。vscodeを使って適当にテキストを入力。あえて言えば、文字コードはutf-8としたくらい。

###そのディレクトリにローカルリポジトリを作成
```
$ git init
```
###作成したテキストファイルをステージングエリアに登録
```
$ git add ファイル名
```
###テキストファイルの中身を変更し、上書き保存
gitコマンドは使わず。vscodeを使って、テキストを追記し保存。

###ワークツリーで上書き保存したテキストとステージングエリアに登録したテキストとの差分を確認
```
$ git diff 
```
vue-c3のグラフにデータを追加する方法

# はじめに

Vue.js で作ったアプリにグラフを表示するために vue-C3 というコンポーネントを利用しています。これで描いたグラフに動的にデータを追加したいと思ったのですが、リファレンスを見てもいまいちやり方がわかりませんでした。
いろいろと試すなかでやり方が分かってきたので載せておきます。

# 対象者

- 基本的な JavaScript を書ける方
- Vue.js の利用経験がある方

# 環境

- Vue 2.6
- c3 ( https://github.com/c3js/c3 )
- vue-c3 ( https://github.com/chryb/vue-c3 )

# 前提

Vue と C3 を利用する環境は出来上がっているものとして進めます。
環境が無い方は公式サイトなどを見て準備をしてください。

# データ追加の方法

例えば折れ線グラフがある場合、グラフデータの追加には以下の 2 パターンがあると思います。それぞれのやり方について説明します。

1. 折れ線グラフの本数を増やすパターン
1. 各折れ線グラフの末尾にデータを追加するパターン

結論から言うとどちらのパターンも以下のようなコードでグラフを再描画することで実現できます。

```js
this.handler.$emit('dispatch', chart => {
  chart.load({
    columns: [
      ...
    ]
  })
})
```

## グラフの本数を増やすパターン

追加したいグラフのデータを上記の `columns` に指定します。

### サンプルコード

```js
this.handler.$emit('dispatch', chart => {
  chart.load({
    columns: [
      ['data2', 1, 2, 3, 4, 5] // 追加したいデータ
    ]
  })
})
```

### デモ

<p class="codepen" data-height="457" data-theme-id="dark" data-default-tab="html,result" data-user="kyamadahoge" data-slug-hash="xxqEpNY" style="height: 457px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="vue-c3 load-data">
  <span>See the Pen <a href="https://codepen.io/kyamadahoge/pen/xxqEpNY">
  vue-c3 load-data</a> by kyamadahoge (<a href="https://codepen.io/kyamadahoge">@kyamadahoge</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 各グラフの末尾にデータを追加するパターン

こちらは `data` 部で保持しているグラフ用のデータに追加したいデータを追加した上で、上記の `columns` にデータ部のグラフデータを指定すると、グラフに追加（再描画）されます。

### サンプルコード

```js
this.chartData.push(5) // 追加したいデータを追加
this.handler.$emit('dispatch', chart => {
  chart.load({
    columns: [
      this.chartData // 再描画するデータ
    ]
  })
})
```

### デモ

<p class="codepen" data-height="457" data-theme-id="dark" data-default-tab="js,result" data-user="kyamadahoge" data-slug-hash="ExWNqoK" style="height: 457px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="vue-c3 append-data">
  <span>See the Pen <a href="https://codepen.io/kyamadahoge/pen/ExWNqoK">
  vue-c3 append-data</a> by kyamadahoge (<a href="https://codepen.io/kyamadahoge">@kyamadahoge</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
【C#.NET】TimeSpanを使って、秒から時間表示にする時の注意

# はじめに

725000秒を「 **時間 : 分 : 秒** 」に変換したい。


```cs
int timeSec = 725000;
Console.WriteLine(TimeSpan.FromSeconds(timeSec).ToString(@"hh\:mm\:ss")); // 09:23:20
```

よし！これでおっけ！


と思った方、ぜひこの記事を読んでください。

# 環境
- Windows 11
- Visual Studio 2022
- C# ( .NET 6.0 )

# 本文


```cs
int timeSec = 725000;
Console.WriteLine(TimeSpan.FromSeconds(timeSec).ToString(@"hh\:mm\:ss")); // 09:23:20
```

実はこれ、**日**の情報がカットされています！

```cs
int timeSec = 725000;
Console.WriteLine(TimeSpan.FromSeconds(timeSec).ToString(@"hh\:mm\:ss")); // 09:23:20
Console.WriteLine(TimeSpan.FromSeconds(timeSec).ToString(@"dd\:hh\:mm\:ss")); // 08:09:23:20
```

"dd"を追加することで、8日と9時間23分20秒であることが分かります。

日も時間として表示したい！！という場合は、時間を別途計算してあげることで、実現可能です。

```cs
int timeSec = 725000;

TimeSpan timeSpan = TimeSpan.FromSeconds(timeSec);
int hours = timeSpan.Days * 24 + timeSpan.Hours;

Console.WriteLine($"{hours}:{timeSpan.Minutes}:{timeSpan.Seconds}"); // 201:23:20
```

# おわりに
少しでも、間違ってコードを書く人が減りますように！
読んでいただきありがとうございました。


# 参考
- マイクロソフトドキュメント：カスタム TimeSpan 書式指定文字列

https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-timespan-format-strings
対数の数値計算

対数って数値的にはどうやって計算するんだろうと思って調べてみました。

# 計算の概要

$1 \leq a,b$とする。

```math
\log_{a}{b} =\frac{1}{c}\log_{a}{b^c} \\
 =\frac{1}{c}\log_{a}{b^c} \\
= \frac{1}{c}( \log_{a}\frac{b^c}{a} + 1)
```

ここで$c=\lceil\log_{b}{a} \rceil$ ($\lceil x \rceil$は$x$を切り上げた整数)とすると、

```math
\log_{b}{a} \leq c < \log_{b}{a} + 1
```

だから

```math
1 \leq \frac{b^c}{a} < b \\
```

よって、

```math
b_0 = b \\
c_i = \lceil\log_a{b_i} \rceil\\
b_{i+1} = \frac{b_i^{c_i}}{a}
```

とすれば、
 
```math
1 \leq \cdots < b_i < \cdots < b_1 < b
```

だから $\lim_{i\rightarrow \infty} b_i = 1 $となる。

よって

```math
f_a(1)=0\\
f_a(b) = \frac{1 + f_a(b^{c(b)}/a)}{c(b)}\\
c(b) = \lceil\log_{b}{a} \rceil
```

を再帰的に解けば、$\log_a{b}$が求められる。

# 実装

```log.cpp
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

//閾値
const double th = 1e-6;

double log( double a, double b ){
    if( b-1<th ) return 0;
    ll c = 1;
    double x = b;
    while( x<a ) x *= b, c +=1;
    return (double)( log(a,x/a) + 1 )/c;
}

int main(){
    double a,b;
    //1<a,bでないと、エラーが生じる
    cin >> a >> b;
    cout << log(a,b) << endl;
    //STLの結果と比較
    cout << log10(b)/log10(a) << endl;
    return 0;
}
```

＊前に何かのページで見て知ったのですが、参考にしたページがどこだったか忘れてしまいました。
【Unity】音を管理するオブジェクトの作り方（1weekの知見共有）

#この記事で得られること
・1weekで音管理をするソースコードでいい感じに作れたものがあったので共有します
・音源ごとに音の大きさを変更できます

#できること
画像のように
・音源のラベル
・音源
・ボリューム
の設定を個別にできるようになります。
![スクリーンショット 2022-01-15 16.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67439/6d0dd182-ae47-4c9f-6111-8f96445e443b.png)


#解説動画
https://youtu.be/nERSRHegijc


#コード

```SoundManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class SoundManager : MonoBehaviour
{
    [SerializeField] AudioSource bgmAudioSource;
    [SerializeField] AudioSource seAudioSource;

    [SerializeField] List<BGMSoundData> bgmSoundDatas;
    [SerializeField] List<SESoundData> seSoundDatas;

    public float masterVolume = 1;
    public float bgmMasterVolume = 1;
    public float seMasterVolume = 1;

    public static SoundManager Instance { get; private set; }

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void PlayBGM(BGMSoundData.BGM bgm)
    {
        BGMSoundData data = bgmSoundDatas.Find(data => data.bgm == bgm);
        bgmAudioSource.clip = data.audioClip;
        bgmAudioSource.volume = data.volume * bgmMasterVolume * masterVolume;
        bgmAudioSource.Play();
    }


    public void PlaySE(SESoundData.SE se)
    {
        SESoundData data = seSoundDatas.Find(data => data.se == se);
        seAudioSource.volume = data.volume * seMasterVolume * masterVolume;
        seAudioSource.PlayOneShot(data.audioClip);
    }

}

[System.Serializable]
public class BGMSoundData
{
    public enum BGM
    {
        Title,
        Dungeon,
        Hoge, // これがラベルになる
    }

    public BGM bgm;
    public AudioClip audioClip;
    [Range(0, 1)]
    public float volume = 1;
}

[System.Serializable]
public class SESoundData
{
    public enum SE
    {
        Attack,
        Damage,
        Hoge, // これがラベルになる
    }

    public SE se;
    public AudioClip audioClip;
    [Range(0, 1)]
    public float volume = 1;
}

```


#使い方
音を鳴らしたいところで以下のように実行してやればOK
`SoundManager.Instance.PlayBGM(BGMSoundData.BGM.Title);`

#利点
・音源とラベルにズレがないので設定ミスが減る
・音源ごとにボリュームの調節ができる

#スタジオしまづとは
Unityを使ったゲーム開発のサポートをする団体です

https://ci-en.net/creator/10761

https://www.youtube.com/channel/UCDunz_CPkqkQT5ljKXcYkhg
かくも読みにくい ｍファイル

##１．はじめに
今、赤の他人のmatlabスクリプトを解読しているのですが、異様に読みにくいので、記事に書くことにしました。

##２．どういうスプリプトなのか
シンプルな形で書きますと、次のようになります。

```matlab:abc.m
a = 1;
b = a + 2;
cde;

d = c + b;
disp(d);
```
こんな感じです。ああ、それか！と思った方も多いかと思われます。
変数ｃが定義されないまま、下から２行目で唐突に出てきて、ｂと加算されて、ｄに代入されます。
このスクリプトを実行してエラーが出ないのは、途中でcde.mというスクリプトを読みに行き、

```matlab:cde.m
c = 4;
```
みたいな感じに、cに値を代入して、abc.mに戻ってくるからです。
このくらいの長さだったら、それほど問題なく読めてしまうのですが、これがもっと長いスプリプトで、cde.m のような ”ネズミ穴”（とりあえず、ネズミ穴と命名しました）が何か所もあると、どこからネズミ（変数）が出てくるのかを突き止めるのが一苦労となります。
いつの間にかネズミが増殖しているという事態ですね。
「引数」とか「戻り値」がない荒涼とした原野みたいな世界。

##３．さらに、
また、このネズミ穴にもぐるときには、もとのスクリプト（この場合abc.m）の変数を全部持っていくので、例えば、

```matlab:cde.m
c = 4;
b = b - c;
```
こんな感じにも書くことができ、穴に入る前と、出てきてからではｂの値が変わっているということになります。

##４．ということで、
悪夢のようなスクリプトと闘っているわけですが、これって「MATLABあるある」なんですかね。

以上です。
短くてすみません。
今、どこにいる？Power Automate Desktopでバスの運行状況を取得したい。

Power Automate Desktop（以下、PAD）を使って、バス会社のサイトから最新の運行状況を取得・表示させてみました。

#今、どこにいる？
現在、小売業の企業で社内教育や採用を担当しています。
当社ではオンラインでは教えにくい魚の切り方などの実技指導は、研修施設に集まって実施しています。施設が数か所ありますが、いずれも交通機関はバスのみとなります。
研修開始前に受講生の集まりが悪いと、「もしかしてバスがちゃんと動いていないのでは…」と心配になることが多々あります。
特に冬は雪害で遅延が前提となり、研修前に何度もバス会社のサイトへアクセスして確認していたので、この不安と手間を解消したいと思いました。

#したいこと
- バス停へのバス出発・到着予定時刻が確認出来れば、遅刻を予測出来る。
- 最新の運行状況が取得したい。
- ちょうどPADについて勉強したばかりなので、問題解決に使えるかを試してみたい。

#完成品
PADを使用し、バス会社のサイトから所定のバス停の最新運行状況を取得→メッセージボックスへ表示させました。
（表示しているバス停名は、記事作成のためのサンプルとして選択しています）
<B>今まで「ブラウザを開く→お気に入りからサイトへアクセス→ページ内の該当箇所を探す」という３ステップを踏んでいたのが、ワンクリックで完了するようになりました！
![結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/f6e1e226-e88f-b81a-2bf5-32f7e24a8f79.png)![全体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/98ae954d-3914-9941-9179-b5402f867cf8.png)

#使用したもの
- Power Automate Desktop
- [バス運行情報（北海道中央バス　バス接近情報）](https://transfer.navitime.biz/chuo-bus/pc/map/Top "バス接近情報")

#作成過程
1.[北海道中央バス　バス接近情報](https://transfer.navitime.biz/chuo-bus/pc/map/Top "バス接近情報")から情報を取得したいバス停を探し、検索ボタンを押す。
（表示しているバス停名は、記事作成のためのサンプルとして選択しています）
![検索画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/fc5f7110-07fc-b1ee-a4d7-809d138a4273.png)
2.表示されたWebページのURLをコピーし、の「初期URL」に貼る。
![Cromeの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/f721273d-e886-3151-980e-9687841119fd.png)
3.フローの2つ目「Webページから情報を抽出する」をクリックし、先程選んだURLのページをChromeで表示。ページ内の欲しい情報が赤枠で囲われるようにマウスを動かして右クリックし、「要素の値を抽出」から表示させたい内容を選ぶ。（今回はテキストを選択）
![データ抽出.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/7c7589e1-f25b-8eed-98fc-f123a4a2f9f4.png)
4.Power Automate Desktopより実行する。

#失敗したところ
さて実行だ！と思ってボタンを押したところ、何も書いていないメッセージボックスが出てきました。
![真っ白.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/30e5c32e-20ec-479f-d718-98431d42b055.png)
各フローの中身を見直したところ、4つ目「メッセージを表示」で「表示するメッセージ」に抽出したデータの情報を入れるという指示を入れ忘れていたという単純な理由でした。
![理由.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/fd40720a-341f-6b06-3d1e-af8809c123f3.png)

#出来た！
時間を置いて次に出発するバスの情報も取得出来るかを確認したところ、問題なく表示されました。4行目に「（遅れなし）」とあるので、このタイミングでは遅延はないようです。
![結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/d00c058b-403e-8964-d37d-849eb3fea16b.png)![結果2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/a6e70ee2-d3c1-22cd-e74b-4f84d088cf75.png)

#調べてみてわかったこと
JR北海道の運行情報も取得出来るか試しましたが、運行状況の評価（〇△×）は画像を使用しており、それが理由なのか同じ方法で表示させることは出来ませんでした。
バスと同様の表示が出来れば便利なので、引き続き対応可否を調べたいと思います。
![画像だった.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490846/7dd9bed1-0956-3d17-b864-401300d848e6.png)
【Android】Some kotlin libraries attached to this project were compiled with a newer Kotlin compiler and can’t be read. Please update kotlin plugin. が出る（自分用メモ）

## エラーとの出会い
これから新しいアプリを作ろうと思い、build.gradleの依存関係をある程度整え、Activityファイルの実装に移ろうとしたところで妙な警告が画面上部に出ているのを発見しました。

![IMG_8701 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1274260/3b37a478-1bfa-ccef-0a47-008f88af20e5.jpeg)

```Some kotlin libraries attached to this project were compiled with a newer Kotlin compiler and can’t be read. Please update kotlin plugin.　 No updates found.```


kotlinライブラリが読み込めないのでkotlinプラグインをアップデートしてくださいとのこと。なのにその隣にはNo updates found.とか書いてあります。アップデートしてくださいと言われているのにアップデートがないってどういうこと？

ちなみに一番右のDetailsがあるのでクリックしてみたところ、
![IMG_8698.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1274260/d15b1d85-a824-401f-3afe-cc60c91e3e64.jpeg)
kotlin-stblibやコルーチンのバージョンが1.6.0になっているけど1.4.2のはずでは？と言われている様子。

しかし不思議なのが、ついさっきstblibの依存関係を削除したばかりなんですよね。
試しにgradleに

```build.gradle
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.2
```
の記述を書き直したりしたのですが、バージョンを1.6.0にしても1.4.2にしても警告の内容は変わりません。


## kotlinプラグインを見てみる
ルートのbuild.gradleのdependenciesの中に

```build.gradle
implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version'
```
と書いていた箇所がありました。

この```$kotlin_version```は同じくプロジェクトレベルのbuild.gradleの上の方に

```build.gradle
buildscript {
ext.kotlin_version = "1.6.10"
}
```

と定義されています。
警告の横にあるDetailsをタップしたときに怒られてたバージョンも1.6.10なのでこの辺りをアップデートすればよさそうですね。
しかしkotlinのリリースノートを見ると1.6.10が最新だったため、アップデートのしようがありませんでした。（2022/01/21現在）
[Kotlin releases | Kotlin](https://kotlinlang.org/docs/releases.html#release-details)
だからNo updates foundになっていたんですね。

## 解決法
* 上記の```$kotlin_version```を1.4.32に下げた
* 同様にkotlin-coroutineのバージョンを1.6.0→1.4.2に下げた

build.gradleを触っているときに```$kotlin_version```を1.4.32から最新版の1.6.10にしていたのでそこを戻しました。アップデートしなければならないと思い込んでいたため、バージョンを下げるという結論に達するまでに少し遠回りをしてしまいました。
今回は前の状態に戻しただけなのですが、Detailを押したときに「expected 1.4.2」と出ていたので1.4.2にしてもよかったかもしれません。（今回は試していないのですが、[リリースノート](https://kotlinlang.org/docs/releases.html#release-details)を見ると1.4.2ではなく1.4.20と書かれていたので、そう書けば動きそうです。）
コルーチンに関しても同じく最新版にしていたので、[こちら](https://github.com/Kotlin/kotlinx.coroutines/blob/master/CHANGES.md)のリリースノートを参考にバージョンを1.4.2まで下げました。

とりあえずエラーを吐かなくなったからよかったものの、なぜ削除したはずのstblibでこのようなエラーが出たのかは謎です。
[Kotlin 1.4.0のWhat’s new](https://kotlinlang.org/docs/whatsnew14.html#dependency-on-the-standard-library-added-by-default)によるとkotlinプラグインと同じバージョンが自動でstblibのバージョンとして追加されるようになったそうなのですが、その影響で入るべきでないバージョンが追加されてしまったんですかね？
初心者ゆえにこの辺り全く理解できていないので、もしわかる方いたら教えてください...
VAIO Z(2021)を買ってUbuntu入れちまった<人柱>

# これQiitaで良いのか問題
あくまで、ある機械のレビューをしているだけなので駄目臭くもある。
だけど、一部の人に有用かも知れないので投稿します。

# TLDR; VAIO Z(2021)にうぶんつは入るのか?
VAIO Z(2021)にうぶんつはネイティブで入ります。
大変に実用的なんですが、ちょっと条件があります。完璧じゃないです。

もちろん、WindowsがあればWOLは動くんでしょう。
今回は人柱をした結果、デュアルブート出来ましたので、報告です。

# COI
この記事の筆者は、VAIO株式会社どころか、いかなる会社からも支援を受けていません。

# Windowsは残しておきましょう
そんなことする人は居ないと思いますが、デュアルブートするにしても、
**Ubuntuだけにしてはいけません。**
バッテリーの設定など、一部の設定がWin側からしか出来なさそうです。(僕の調べた範囲では)

/sysの中を覗いてみましたが、僕にはよく分かりませんでした。
sony時代とはちょっと作りが違うっぽいです。
まぁ、そもそもそんな使い方するのは想定されていないのですが。

# 画面やスピーカーは？
トラブルなく行けました。dGPU乗ってないのでそんなところでコケることは少ないですよね。
使い勝手自体は単なるTigerlakeベースのシンプルで高性能なモバイルノートです。
挙動は素直なんですけどね。

# LTEは？
それ載せたのを買わなかったからわからないです。

# パフォーマンスやバッテリーは？
Vaioにはいたわりバッテリー機能として、例えば50％以上充電しない設定とか出来ます。
そりゃ、クソ高いので長持ちしてもらわないとですね。
で、そのいたわりバッテリーがWindowsからしか設定する方法がなさそうなのです。
ひょっとするとVaio True Performanceとかも動いてないかもですね。

# キーボード
とてもいいですが、好みもあるから店で触るといいです。

# ハードウェア的自由度
SSDは交換できるようですね。

# Win11Update
Dual bootのUbuntu環境は死にませんでした:D
# 感想
全体的に、ハードウェアの設定の一部をWin側でしないといけませんが、
大変素直な挙動です。
流石に高級品だけあって、触り心地はいいです。
財布は痛みますが、一日をコンピュータと向き合って過ごす人には
性能以上の価値をくれそうな気がします。
Node-REDを使ってノーコーディングでLINE botを作ってみよう!! (02_基礎編～LINE bot作成におけるNode-REDのデータの流れ～)

#はじめに
Node-REDを使ってLINE botを作る記事は調べればでてきますが、最初から最後までノーコーディングで作成している記事はなかったのでここで解説していこうと思います。

データの内容からなるべく詳細に記載しようと思うので、必要な部分のみ参考にして下さい。

当該記事はNode-REDのデータの流れについて解説するのみになります。
以下目次のリンクより必要記事にアクセスして下さい。

#目次
[01_環境構築編](https://qiita.com/VulpeS404/items/da196c87541b6af9214c)
[02_基礎編～LINE bot作成におけるNode-REDのデータの流れ～](https://qiita.com/VulpeS404/items/ee9e719f37ae535571fd)
[03_Node-REDからbotユーザーにメッセージを送信しよう](https://qiita.com/VulpeS404/items/c2e0db947db1b4c6229c)
[04_オウム返しbotをつくろう](https://qiita.com/VulpeS404/items/640b075b0a9eaaad249f)
[05_LINEから受信したデータの詳細を見てみよう](https://qiita.com/VulpeS404/items/554119209a4469130b98)
[06_ユーザーから送られたメッセージを判定して返事を返そう](https://qiita.com/VulpeS404/items/308f599660a79d2c457e)
[07_Node-REDとCloudantDBを連携させよう](https://qiita.com/VulpeS404/items/0d73963177d5829bc5a9)
08_ユーザーとやりとりできるbotをつくろう
09_おすすめの〇〇を紹介するbotをつくろう
[99_各nodeの解説まとめ](https://qiita.com/VulpeS404/items/0ce3057451d18f4d87ec)

#2. 基礎編～LINE bot作成におけるNode-REDのデータの流れ～概要
今回は基礎中の基礎となるNode-REDのデータの流れを解説します。
（内容的に秒で終わります）

#2-1. Node-REDのデータの流れ
Node-REDの基本的なデータの流れはmsg.payloadという箱が流れていくイメージです。
以下の図のようにノードAでmsg.payloadの箱にXXを入れた後、ノードBでYYを入れると内容は上書きされます。
この図だと最終的にNode-REDから送信されたデータはYYになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395385/2bacbf5f-d84a-abe0-b32c-eb893b9e0e61.png)

これが例えばXXがLINE側に送るデータでYYがデータベースの情報という2種類のデータの種類であると想像してみてください。

最初に例えばXXの情報としてbotに送ったテキストの情報が入ってきたとしましょう。
その後にそのテキストを基になにを返すか判定して、返信するテキストを格納したいとしましょう。

次にYYの情報としてデータベースから現在のステータス情報を取得してきたとしましょう。
これを基に最初に受信したbotに送られたテキスト情報を判定するとします。

この場合、判定ノードに行くときにはmsg.payloadの中身はデータベースから受信した情報に上書きされ、botに送ったテキストは保持されていません。
そのため判定に使うテキスト自体がない状態になってしまうのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395385/e6679869-7188-2e06-7498-ed108c4d816b.png)

そのため、最初にbotに送ったテキスト情報を受信したらその情報を別の箱に入れてあげる必要があります。
そうすればノードBでデータベースの情報が入ってきてもmsg.payloadにはテキスト情報はありませんが、msg.XXを見れば入っています。
その後に返信する内容（XS）をmsg.XXに格納します。
最後送信する前にmsg.payloadにmsg.XXの内容を上書きすれば、その手前で別の情報（ZZ）が入ってきても最終的に送信されるデータはXSになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395385/0afca31f-dee1-5195-7dc2-9de7c6580f76.png)

#2-2. データの運用
今回LINE botを作るにあたって、LINE関係のデータ（LINEから受信するデータ・LINEに送信するデータ）とデータベース関係のデータ（データベースから取得するデータ・データベースに格納するデータ）の2種類を使います。

そのため前述の例のように、LINEから受信したタイミングでLINE関係のデータ用に変数の箱を作り、そこに格納します。
データベース関係のデータもデータベースから取得したタイミングでデータベース関係のデータ用変数を作り、そこに格納します。
それ以降は作った変数で情報の加工や更新を行い、LINEに送信するタイミングでmsg.payloadにLINE用変数のデータを格納します。
データベースも同様にデータベースに格納するタイミングでmsg.payloadを上書きし送信します。

こうすることで後続のノードの影響でmsg.payloadに格納された情報が上書きされる心配がなくなりますし、ある時点でどこにどのデータがあるかわかるためメンテナンスも容易になります。
msg.payloadだけだとその時点でなにが入るか遡って見る必要がでてきてしまいます。

#おわりに
今回はプログラミング等している人であれば改めて見るような内容ではないレベルの基本的な話でした。
次回から実際にbotを作成していきます。
VSCode: Live Serverで文字コードがUTF-8以外の場合

訳合って、文字コードをEUC-JPでコーディングを行う必要があったのですが、いつもどおりVS CodeのLive　Serverを利用したところ見事に文字化けてしまいました。

時間をかけて調べてみましたがLive Severのままでは解決できそうにありませんでした。
issueもいくつかあがっているようです。

- [Encoding](https://github.com/ritwickdey/vscode-live-server/issues/587)
- [language encoding is not preserved while serving](https://github.com/ritwickdey/vscode-live-server/issues/459)

また、[こちらのissue](https://github.com/ritwickdey/vscode-live-server/issues/24)を参考にlive-reloadのindex.jsを直接いじるということも試してみたのですが、設定方法が悪かったのか動作しませんでした。

そこで、node-staticを利用することにしました。(今回はグローバルインストールで進めます。)

## インストール、 実行方法

```
npm install node-static -g
```

あとは、対象のディレクトリで実行するだけです。

```
cd [target_dir]
static
```

ただこれだけだと、ブラウザがキャッシュを持ってしまい開発に不向きなので、
キャッシュを持たせないようno-cacheを設定できます。

```
static -H '{"Cache-Control": "no-cache"}'
```

## 参考記事

[VSCode の Live Server で文字コード Shift_JIS が文字化けしてしまう
](https://qiita.com/YoshinoriKanno/items/dc7da5d890c6ee0f5cc8)