OmniAICreator/Qiita-1.07M huggingface dataset:
Lex用語簡易まとめ

# はじめに
LexとConnectを連携してサービスを作る際、Lexについて調べましたので、まとめます。

- lex ボット
    - エイリアスで、本番・開発などのバージョンを分けられる
    - インテント：ボットの設定
        - 発話
            - ユーザーがこのインテントを呼び出そうとするフレーズを設定
                - 例、タクシーを予約したいのですが、予約、タクシー
        - スロット
            - スロットは、パラメータ・変数のようなもので、１つのインテントに、０個以上のスロットを定義することができる。
            - プロンプト
                - Lexがユーザに入力を促すための台詞を決める。
                    - 例、いつのご予約ですか？、何台必要ですか？
                - 最大再試行回数を設定できる
                - 聞き方のバリエーションが増やせる。どこにいますか？町名を教えて下さい。など
            - スロットタイプ
                - [https://docs.aws.amazon.com/ja_jp/lex/latest/dg/howitworks-builtins-slots.html](https://docs.aws.amazon.com/ja_jp/lex/latest/dg/howitworks-builtins-slots.html)
                - 組み込みタイプは、awsで設定済み。日付など
                - カスタムタイプは、自身で設定。２つ設定タイプがある
                    - 組み込みタイプを限定的にする場合。
                    - 中国というワードに対して、中華人民共和国、中華、は中国と同義にするといった設定もできる。
                    - 読み方を複数指定すると、人による間違いもフォローできる
        - 確認プロンプトと応答拒否
            - 全てのスロットで、必要情報を聞き出した後、ユーザーに必要情報を確認するように促すためのボットの発言内容
                - 例、{startDate}に{time}から {number}名様で予約します。
                - {startDate}、{time}、{number}、はスロットでユーザーが答えた情報
                - ユーザーの「はい」「いいえ」によって、connectでのフローを変える
        - フルフィルメント
            - インテントを処理している際に、当該インテントに定義されたスロットが、全て入力された状態をさします。 通常は、このタイミングで、インテントの目的となるビジネスロジックをlambda等で実行する事になります。
        - Lambda 関数でできること
            - バリデーション
                - 店が閉店21時の場合、予約時間22時はできませんので、「本日の営業は、21時までです。何時に受け取りますか」というようなレスポンスを返すことが可能になります。
            - 別のインテントへの遷移や、ビジネスロジックを実行
                - 「発注処理」（メール送信とか、APIコールなど）。予約情報を通知する
        - 応答を閉じる
            - インデントを閉じるときのメッセージを設定
        - 連携
            - slackボット、Facebookボットが構築できる
            - connect
                - 発話によって、インテントを使い分けることができる
                    - ユーザーが「予約」と回答すると、予約のインテント。「予約変更」と回答すると、予約変更のインテント。
社内で品質勉強会を始めたのでその動機や方法や今後のこと

この記事は ビビッドガーデン [Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vivid-garden) の16日目です。
一人目QAとして日々奮闘中の @uje です。今回は勉強会を社内で開催したのでその動機とか書いてみます。

# 始めた動機
ガッツリとした勉強会が社内でできていなかったので、そういったことをやっていく文化にしたかった気持ちがあります。
QAとして参画したこともあり、品質に関する理解や向上が少しでも進めば…といった思いもあり始めてみました。

# 勉強会スタイル
資料を準備してそれに基づいて説明する講義スタイルです。
また、自分の過去の経験でこんなことあったよ話も含めて1回30分の極短でやっています。
開催頻度は約1ヶ月に1回ぐらいです。

# 実施したテーマ
品質ってなにさ？
品質特性とは？
品質保証って何やる仕事？

みたいなものを簡単に。
どのテーマを切り取ってもそれだけで本書けると思うので、あくまで私はこの触りだけです。

合わせて経験を語ったテーマでは以下のようなものも実施しました。
コミュニケーションが腐るとテストも腐る話
そのバグや懸念、忘れた頃に爆発するよ話

# 参考にした書籍
[ソフトウェア品質知識体系ガイド（SQuBOK）](http://www.juse.or.jp/sqip/squbok/book.html)
こちらを参考に自身で資料化して勉強会を開催しています。

# 効果というか実感
概念的な説明が多いので即効性はまだまだかなと思っています。私の伝え方にも改善の余地があると思ってます。
とはいえ、こういった場で伝えること自体が自身の経験にもつながりますし、何より知識をみんなで共有しようという文化ができつつあるのかなと感じています。

# 今後のこと
講義スタイルは広く伝えるには楽な手法なので必要に応じて実施していこうと考えています。
とはいえ、実践的ではないのも事実で以下のような踏み込んだ勉強会的なことを考えています。

ペアテストまたはモブテストの定期開催（みんなで1つのテストをする）
1書籍の1テーマを題材にした輪読会または読み合わせ会
マイヤーズの三角形をテーマにしたグループワーク的なこと

# 最後に
拙くてもまずは始めてみることがいいんじゃないでしょうか。
発表の仕方を振り返る機会にもなりますし、資料を作るということ自体の勉強にもなります。
それに、結果的に文化作れたら、全体的な品質向上につながるだろうし、私が最初に始めたって胸張って言えるのでまずは行動してみようという考えで踏み出してみてもいいのかもしれません。
Laravel8とinertia.jsとReactとTypeScriptで環境構築したい（あとStorybookも）

# inertia.jsとは
LaravelやRailsなどのサーバーサイドのフレームワークの機能を活かしながら、SPAアプリを作成するためのJavaScriptのライブラリです。

ルーティングや認証といった機能はサーバーサイドの機能を使うので、それほどフロントエンドに強くない人でもReactやVueで手軽にSPAアプリを実装できるようになっています。

inertiaのHPでも`Rails + Vue`とか`Laravel + React`
といった組み合わせのデモアプリが紹介されています。
https://inertiajs.com/demo-application

# 今回の記事のモチベーション
デモアプリで`Laravel + React`の組み合わせはあったが、

- React使うならTypeScriptにしたい
- CSS in JS使いたい
- docker上で動かしたい

とか諸々、実案件で使うにはもう一声欲しかったので、そのサンプルを作成しました。

https://github.com/wish911wish/laravel-with-react-typescript-atomic-design

clone後

```
cd laravel-with-react-typescript-atomic-design
make init
make npm-watch
```
で動くはずです。 [^1]

今回利用したライブラリ等は下記の通りです。

- Laravel8
- inertia.js
- React
- TypeScript
- React Hook Form
- Emotion
- Storybook
- Docker　


# セットアップ時に参考にしたドキュメント・記事

#### Docker

最強のLaravel開発環境をDockerを使って構築する
https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4

#### inertia.js

Laravel側セットアップ
https://inertiajs.com/server-side-setup

React側セットアップ
https://inertiajs.com/client-side-setup

#### TypeScript

https://laravel-news.com/typescript-laravel


#### Emotion

Reactで`css`プロパティを利用するための設定
https://emotion.sh/docs/css-prop#jsx-pragma

TypeScriptの場合だと下記のプラグマを使用する必要がある...?

```
/** @jsxImportSource @emotion/react */
```

ちなみに、
CSS in JSをどれにするかは以下のページを参考にしました
https://github.com/andreipfeiffer/css-in-js#styled-components



#### Storybook

https://storybook.js.org/docs/react/get-started/install

インストール後、下記のパッケージで脆弱性警告が出てたので手動でpackage-lock.jsonの修正を行いました。(2021年12月時点)

- immer
- glob-parent
- trim



[^1]: [Makefile](https://www.gnu.org/software/make/) を使用しています。Macの方は`brew install make `にてインストールできます。https://formulae.brew.sh/formula/make#default
GASのここが好き！！【Google Apps Script】

アドベントカレンダー企画で、GASについて書くことになったのですが、
なにを書こうか迷いに迷って結局GASを褒めるだけの記事にすることにしました🎅。

私はもともと組み込み系をずっとやってきたこともあって、**WEB系のJS等よりもC言語やアセンブラなどの比較的に低級の言語ばかりに触れて**きました。

今の会社に転職してから始めてGASに触れて**その便利さやアウトプットのしやすさに感動**しました。

今回は個人的にGASのステキだと思ったところをまとめていきます。

#GASとは
そもそもGASとは何かというと、**Googleが提供しているJavaScriptベースのスクリプト言語で、Google Apps Scriptの略**です。
https://workspace.google.co.jp/intl/ja/products/apps-script/

Googleが開発・提供しているって時点で私にはぶっ刺さっているのですが、**JavaScriptベースで書けるという点が刺さる人も多い**のではないでしょうか。

GASはGoogle社のサーバで動作するので、ローカルで開発環境を構築する必要がないです。
さらに、**スプレッドシートやスライド、GmailやGoogle DriveのGoogleのサービスに紐づけて処理をすることができる**（というかそこがメイン）ので、すぐに明確なアウトプットをすることができるという楽しさもあります。

#GASでできること
**Googlebのサービスに紐づけて何でもできます。**
もう少し真面目に例を挙げると・・・

**1.スプレッドシートの内容をGmail、LINE、チャットワークに送る**
**2.Gmailで届いた内容をGoogleカレンダーにスケジュール登録する**
**3.フォーム入力者にメール送信**
**4.Google Driveのフォルダ整理、ファイル生成**

などなど、言い出せばキリがないほど何でもできます。
しかもすぐにアウトプットできて、その結果を確認できるので書いていて楽しいです。

シリアルライターを通してCのコードをマイコンに書き込んで、デバッグ用のLEDが点滅するか見て・・・
みたいな地味なアウトプットの確認が、GASには必要ないんです。

#GASの好きなところ
ということで、もうすでに色々と先走ってしまいましたがGASの好きなところを言っていきます。

##JavaScriptベースで書ける
GASは完全オリジナルの言語ではなく、基本的にJSをベースにしているのでJSのコードが走ります。
**基本的な組み込み関数や制御構文が一致しているので、困ったときはJSのリファレンスを見れば解決**します。
JSにも転用が効くので、**初めてプログラミングを始めるのにもおすすめの言語**かなと思います。

コードはこんな感じで、とにかく書きやすい↓

```JS:サンプルプログラム1
function testFunc(){
  let strHello = "hello world!";
  let toDay = new Date;

  console.log(strHello +"　今日は"+ toDay.getDate() +"日です");
}
```

```:実行結果
11:25:27	hello world!　今日は12日です
```

##Webアプリが作れる
Googleサーバーを使ってwebサーバーを立ち上げることもできるため、**なんと簡易的なwebアプリも作ることができます**。
もちろんドメインやらの設定はできないため、社内でのみ使うサービス程度になりますが、これはVBA等にはない旨味です。
例えば、オリジナルの入力フォームをwebアプリ化して、**入力された内容をスプレッドシートに記録するアンケート**なども比較的に簡単に作成できます。

##Googleサービスとの親和性が鬼高い
ここまで来るともはや説明不要ですが、とにかくGoogleのサービスと親和性が高いです。
**だってGoogleが作っているんだから！**

もちろん専用のライブラリも用意されており、非常に簡単に処理をすることができます。

```JS:アンケート回答済みかどうかを確認
function testForSpreadSheet(){
  let sheet = SpreadsheetApp.getActiveSheet()
  let allRange = sheet.getRange('A1:B11');
  let allrangeValue = allRange.getValues();

  let lastRow = allRange.getLastRow();
  
  for(let i=0;i<lastRow;i++){
    if(allrangeValue[i][1]==true){
      console.log('社員番号'+allrangeValue[i][0]+'はアンケート回答済み');
    }
  }
}
```
```:実行結果
11:21:33	情報	社員番号ID0001はアンケート回答済み
11:21:33	情報	社員番号ID0003はアンケート回答済み
11:21:33	情報	社員番号ID0006はアンケート回答済み
11:21:33	情報	社員番号ID0007はアンケート回答済み
11:21:33	情報	社員番号ID0009はアンケート回答済み
11:21:33	情報	社員番号ID0010はアンケート回答済み
```

![スクリーンショット 2021-12-12 11.20.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/b9d5ca47-35d7-c18e-a507-5f37ca5ca3b8.png)

**さぁ、GASを使ってどんどん仕組み化してきましょう！！**
CS業務のテックタッチ化に挑む Part2〜コードを書くようになった話〜

この記事は[「HRBrain Advent Calendar 2021」](https://qiita.com/advent-calendar/2021/hrbrain)12日目の記事です。

#はじめに
こんにちは！HRBrain カスタマーサクセス（以下CS）の小西です。
この記事では、所属するCSのテックタッチPJが何をしているのか、PJを進める中でコードを書くようになった話を書いていきます。
※同じくテックタッチPJを推進する竹縄さんの[入社から1年、CS業務のテックタッチ化に挑む話](https://times.hrbrain.co.jp/entry/2021/12/09)では、PJのテーマや課題を深掘った内容なのでぜひチェックしてみてください。

###自己紹介
・2016年新卒で通信キャリアへ入社し、自治体や学校への営業、営業企画や営業支援に従事
・2021年4月にHRBrainのCSへ入社、9月までテクニカルサポートやCSM業務に従事、10月からテックタッチチームでPJを推進

#テックタッチって実際何してるの？
これ社内でも結構言われるので（もっと発信していきます）、目的・目標・手段に分けて書きます。

###目的
テックタッチで目指すのは**「CS・ユーザーに関わる非効率を削減し、少人数でも継続率を上げられる仕組みをつくること」**です。
ありがたいことにユーザーが増えていく中、業務の非効率な部分を「テック」で効率化し、
CSが本来行うべきユーザーへ価値を届ける「活用提案」に時間を割けるよう日々施策を進めています。

###目標
ユーザーとの問合せ対応工数の削減、打合せ準備の工数削減などを設定しています。

###手段
主に以下３つの施策をそれぞれツールを活用して進めています。

**1. ヘルプページの改修**
操作に関する不明点をユーザー自身で解決できるよう、ヘルプページを刷新、Google Analyticsのデータを見ながら記事の作成・修正を行っています。

**2. プロダクト画面上での案内配信**
最適なタイミングで最適な情報を提供できるよう、ユーザーをセグメントに分けて関連FAQや活用促進の案内をプロダクト画面上で配信しています。 

**3. チャットオペレーションの見直し**
ユーザーからの問合せにより迅速・効率的に対応できるよう、チャットbotの構築、問合せのチケット管理、応対フローの見直しを行っています。

できてる風に書きましたが、各施策トライ&エラーを繰り返し、他のSaaS企業へ取り組みを聞きにいったりと、軌道修正しながら進めています。

#施策を進める中で立ちはだかった壁
施策を進めるにあたって最初に立ちはだかった「コードを書くこと」について書いていきます。

上記の**2.プロダクト画面上での案内配信**の施策にて、ポップアップを作成しようとツールで作業を始めました。
デザインの骨子ができたので色や配置を変更しようとカスタマイズボタンをクリックすると、↓のような画面に切り替わりました。
![computer_screen_programming 2 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295780/42485ecf-a485-3d03-26fe-2dec8c80f675.png)

コードの編集画面です。細かいカスタマイズをするにはソースコード(HTML/CSS/JavaScript)を書く必要がありました。
「やばい、、、エンジニアへ都度依頼するのか」自分で作れるものと思っていたのでスケジュール通り進められるか、焦りました。

そんな折に「自分で書くのはどうか？」というエンジニアK田さんの言葉を受け、できるイメージはないものの「とりあえずやってみよう！！」と勉強を始めました。
勢い良くやりますと言ったものの、ド文系で前職でも営業系だった私にとって**コードを書く**行為は遠い遠い存在であり、最初はかなり苦戦しました。

参考書を読んだり、学習サイトへ登録して勉強したり、とりあえず書いてみたり、時間はかかりましたが少しずつ自分が意図することをコードで書けるようになってきました。
初めて自分の作った案内がプロダクト画面上に出てきた時はめちゃくちゃ嬉しかったです。

まだ基礎の基礎ですが、できることが増えつつあって楽しいです。
今は開発メンバーの手厚いサポートありきですが、一定はCS内で完結できるようレベルアップしていきたいです！
（いつもサポートしてくれるエンジニアやデザイナー、PdMメンバー本当にありがとうございます:pray:）

#最後に
今回は施策を進める中で最初に立ちはだかった壁「コードを書くこと」を中心に書きましたが、データの分析やbotの構築などやることは盛り沢山です。
自分でできることを増やしつつ、メンバーの協力も得ながら着実に乗り越えていきたいと思います。

そして今学んでいるテックタッチの推進に必要なことは、他のCSメンバーもできるよう型化して、展開していきたいと思います。
非効率をなくし、ユーザーへより質の高いサポートができるよう、CSのテックタッチ化を推進していきます！

###最後の最後に
CSでは一緒に働く仲間を募集しています！
お客様の課題を解決に導くHRBrainのCSはめちゃくちゃやりがいがあります。
ご興味あればぜひお話を聞きに来てください！！
[人材育成と事業成長を支援！顧客を理解して寄り添うカスタマーサクセス募集](https://www.wantedly.com/projects/789399)
CloudWatchの標準メトリクスでEC2インスタンスのメモリ使用率はなぜ取得できないのか

CloudWatchを勉強している際に、メモリ使用率がなぜ標準で取得できないのか技術的な理由が気になったので、色々調べてみました。備忘録の意味も兼ねて、載せておきたいと思います。
# 疑問点
CloudWatchで取得できるEC2インスタンスの標準メトリクスについて、CloudWatchのBlack Beltでは以下のように書かれています。
<iframe src="//www.slideshare.net/slideshow/embed_code/key/kIXHagTrLi12zC?startSlide=24" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/AmazonWebServicesJapan/20190326-aws-black-belt-online-seminar-amazon-cloudwatch?startSlide=5" title="20190326 AWS Black Belt Online Seminar Amazon CloudWatch" target="_blank">20190326 AWS Black Belt Online Seminar Amazon CloudWatch</a> </strong> de <strong><a href="https://www.slideshare.net/AmazonWebServicesJapan" target="_blank">Amazon Web Services Japan</a></strong> </div>
この記載の通り、CloudWatchでは標準で取得できるメトリクスとしてCPU使用率やディスク読み込みバイト数、ネットワーク利用状況などが用意されておりますが、メモリ使用率などは標準では用意されておりません。
標準で用意されていない項目はカスタムメトリクスに分類されており、取得できるようにするためには、EC2にCloudWatchエージェントのインストールなどが必要になります。

[（参考記事：CloudWatchエージェントでEC2インスタンスのカスタムメトリクスを取得する）](https://qiita.com/t_okkan/items/9bec49fa5be76de4e5ef)

一般的なリソース監視において、メモリ使用率は重要な項目であるにも関わらず、なぜ標準で用意がされていないのでしょうか？

# 結論
結論を言うと、**メモリ使用率はOSからしか取得できないため**です。

#### ・EC2の構成
まず下記の図の通り、EC2インスタンスはハイパーバイザ型の仮想化技術が用いられており、ホストサーバの上に仮想マシンを立ち上げてOS（LinuxやWindows）を実行しています。
<iframe src="//www.slideshare.net/slideshow/embed_code/key/7rWkQ7hG6lGY2K?startSlide=9" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/AmazonWebServicesJapan/20190305-aws-black-belt-online-seminar-amazon-ec2" title="20190305 AWS Black Belt Online Seminar Amazon EC2" target="_blank">20190305 AWS Black Belt Online Seminar Amazon EC2</a> </strong> from <strong><a href="https://www.slideshare.net/AmazonWebServicesJapan" target="_blank">Amazon Web Services Japan</a></strong> </div>

#### ・EC2の責任分界点
そしてEC2はIaaSサービスであるため、責任分界点モデルより、OS以上のレイヤーは全てユーザーの管理領域となります。（[NRIセキュア ブログ](https://www.nri-secure.co.jp/blog/manage-cloud-administrator-accounts)より画像引用）
<img width="600" alt="責任分界点" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689573/ecb76ccb-8c60-f4b9-a3a9-ceef5a692cf6.jpeg">

#### ・標準メトリクスで取得できない理由
つまりどういうことかというと、**CloudWatch（AWS管理側）は管理領域外であるOSレイヤーのメトリクスを取得することが出来ない**のです。そのため標準で取得できるメトリクスは、仮想化レイヤー以下に関係するCPU使用率やディスク読み込みバイト数、ネットワーク利用状況などに限られます。
一方、**メモリの管理はOSの役割**なので、CloudWatchエージェントなどでOSからメモリ使用率を抽出して、CloudWatchに送信する必要があります。またメモリに限らず、空きディスク領域やログインユーザー数など、OS内部でしか取得できないメトリクスも同様となります。

# 最後に
CloudWatchのメトリクスについて調べてみましたが、多くのAWS書籍やネット情報では標準メトリクスとカスタムメトリクスの分類ぐらいまでしか記載されておらず、その先まで触れられているものは殆どありませんでした。CloudWatchとはそういうものなんだ、と言ってしまえばそれまでかもしれませんが、今回色々調べていくうちに、自分の中で多くの気づきを得たり、各領域の繋がりを整理することが出来ましたので、今後も疑問に思ったことは調べて発信していきたいと思います。

# 参考
https://stackoverflow.com/questions/57369025/why-memory-utilization-of-ec2-instance-is-not-default-metric-of-amazon-cloudwatc
MacOSで、AWS CLI のタブ補完

# 公式ドキュメント

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-linux

上記URLに　Windows , Linux の設定方法についても記載あります。

# MACでコマンド補完の手順
###1. aws_completer がシェルのパス上にあるか確認


```shell
$ which aws_completer
/usr/local/bin/aws_completer
```

###2.  シェルの識別

```shell
echo $SHELL
/bin/zsh
```

###3. ~/.zshrc　の末尾に追記

```shell
$ vi ~/.zshrc

#追記する内容
autoload bashcompinit && bashcompinit
autoload -Uz compinit && compinit
complete -C '/usr/local/bin/aws_completer' aws

$ source ~/.zshrc
```

###補完完了

```shell
$ aws dynamodb d
delete-backup                        describe-global-table
delete-item                          describe-global-table-settings
delete-table                         describe-limits
describe-backup                      describe-table
describe-continuous-backups          describe-table-replica-auto-scaling
describe-contributor-insights        describe-time-to-live
describe-endpoints
```
[ TypeScript ] 総称型（ジェネリクス）について

## このシリーズの概要

これまで、業務やプライベートで TypeScript を書いてきました👇 （例） しかし

https://qiita.com/ryosuketter/items/8dd8eb7c761abea8626c

なんとなく書いてきたので、キチンと理解する目的で書こうと思い、気になる単位ごとにまとめてアウトプットしようと思いました。

今回書くのは「総称型（ジェネリクス）」についてです。

## 総称型（ジェネリクス）の　について

ジェネリック（形容詞）の意味は「一般的な、包括的な、汎用的な、総称的な」という意味があるそうです。

TypeScriptでも、そんな感じの意味で使われています。TypeScriptでは、どんな使われ方をするかみていきましょう。

例えば、ある関数を作成するとします。その関数の方は「引数を文字列を受け取ったら、戻り値も文字列で返す。引数を数値を受け取ったら、戻り値も数値で返す。」こんな関数を作りたい時の型の指定はどうすればいいでしょうか？

```ts
const echo = (params: number): number => params
const echo = (params: string): string => params
```

それぞれに型を指定するのはめんどくさい。としましょう。

このように、型が違うだけで引数で受けたデータをそのまま返り値として返している（同じような処理の関数）の型の指定を共通化できるのがジェネリクスという仕組みです。

型における変数のような機能を振る舞わせることで、型が違うだけの同じような処理の関数をいくつも作ることを防げます。

先ほど書いた関数をジェネリクスを用いて共通化させます。

関数定義にジェネリクスを利用する場合、関数名に続けて「`<T>`」のようにT型をエイリアスとして指定します。

:::note info
型エイリアスは略称らしい
諸説あるらしいですが、型エイリアスの略称は、TはTypeを表し、KはKey、EはElement、UはUnknownを表すらしいです。
:::

先ほど書いた2つの関数を、型の指定にジェネリクスを使うことで共通化します。

```ts
const echo = <T>(params: T): T => params

// 大事なポイント 指定された型は全て同じ型になるということ（文字列を引数で渡す場合は、戻り値も文字列になる）
// どんな型でも使えるが、必ず渡された型に制約されます
```

注目するポイントは`<T>`で、これが総称的な、もしくは汎用的な型として機能しています。

この関数を使う場合はこんな感じで使います。

```ts
console.log(echo<string>("test"))
console.log(echo<number>(10))
console.log(echo<boolean>(true))

// 型推論もできる
console.log(echo("test"))
console.log(echo(10))
console.log(echo(true))
```

ジェネリクスを使うことで、型が違うだけで関数を作るコストが省けましたね。

### extendsを使って型に制約を付ける

特定の型のみに制限したい時は`extends`を使います。

```ts
const echo = <T extends string>(params: T): T => params

console.log(echo("test")) // エラーにならない

console.log(echo(10)) // エラー文 Argument of type 'number' is not assignable to parameter of type 'string'.
```

### 複数の型定義

複数の型の指定も可能です。

```ts
const echo = <T, K>(params1: T, params2: K): K => params2
console.log(echo("test", 10))
```

以上です。

## 参考

https://www.typescriptlang.org/docs/handbook/2/generics.html

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
CS50 filter RGBTRIPLE notation

## 概要
[CS50 week4 problemset4 Filter (less comfortable)](https://cs50.jp/x/2021/week4/problem-set/filter-less-comfortable/)にて、以下構文の**左辺**の理解に苦しんだ。

```c
RGBTRIPLE (*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
```
この表記法は講義では説明されなかったので、ネットで検索していても混乱している人が多い印象を受けた。
同じように迷った人がいる場合の手助けとなれば嬉しい。

## RGBTRIPLEとは
赤、緑、青の相対的な強さで構成される色を表す**構造体**。

```c
typedef uint8_t  BYTE; // 8ビットの符号なし整数型

typedef struct
{
    BYTE  rgbtBlue; //青色の強度
    BYTE  rgbtGreen; //緑色の強度
    BYTE  rgbtRed; //赤色の強度
} __attribute__((__packed__))
RGBTRIPLE;
```

## 右辺について

```c
calloc(height, width * sizeof(RGBTRIPLE));
```
C言語の**calloc関数**とは、**ヒープメモリに対し、指定したバイト数のメモリを指定個数分確保し、そのメモリブロックを0にクリアする関数**である。

**■calloc関数の書式**

```c
calloc(確保するメモリの個数, 確保するメモリ1つあたりのバイト数)
```

**■calloc関数の戻り値**
成功時 : 確保したメモリblockのポインタ
失敗時:NULL

**■calloc関数とmalloc関数の違い**
これら2つの関数の本質的な違いは、**確保したメモリ領域に格納される値**。

**malloc関数**で確保した領域の値は**不定**である。
一般に、malloc関数を呼び出す前にそのメモリ領域に格納されていた値がそのまま残る。

それに対して**calloc関数**では、確保したメモリ領域の**全ビットがゼロにクリア**される。

## 左辺について
結論を言うと、左辺は**<font color="FireBrick">「RGBTRIPLE型のwidth個の要素を持つ配列」へのポインターimageを宣言して、右辺で初期化</font>**しているといえる。

簡単に言うと、imageは**配列へのポインター**だ。

```c
RGBTRIPLE (*image)[width] = ...
```

これだけだと「ん？」と思われるかもしれない。
2日間探して「ベストアンサー」だと思った記事に出会えたので、引用しながら噛み砕いていく。

## (引用)配列へのポインターの書き方
**■参考記事**
https://atmarkit.itmedia.co.jp/ait/articles/1208/08/news133.html

以下、引用です。

配列へのポインターはどのように書くのでしょうか。
例えば、次のように書いたら、変数pの型はどうなるでしょうか。

```c
int ary[] = { 1, 2, 3 };
int (*p)[3] = &ary;
```
これは、**「int型の3つの要素を持つ配列」へのポインターpを宣言して、aryで初期化**しています。

とはいえ、慣れないうちは読みづらいと思いますので、1つずつ追いながら読んでみます。

まず右側です。
&ary は配列 ary のアドレスになります。
ary の型はint型の3つの要素を持つ配列ですので、int [3] となります。

このアドレスですから、**&ary の型はint (*)[3]**となります。

なぜ * を()で囲う必要があるかというと、int *[3] では「int *型の要素を持つ3つの配列」という別の意味になってしまうからです。

次に左側を見てみましょう。
まず注目すべきは、p という識別子です。
pの型を見るには、近いところにある記号から見ていきます。

pの最も近くにあるのは()内にある * です。
型の中に出てくる * はポインターを表しますから、p は何かを参照するポインターであることがわかります。

ここで () 内を外してみると、int [3] になります。

これはint型の要素を3つもつ配列です。
これらをまとめて読むと、**p は“「int型の要素を3つもつ配列」へのポインター”**であることがわかります。

つまり、型の一部を取り除くと、取り除いた部分の型が残るのです。

また、**左側から識別子pを取り払ってみると、int (*)[3]**になります。

これは、**右側の型 int (*)[3]と同じ**です。
まずは識別子を取り除くだけでも、どんな型になるかわかりやすくなります。

このことを覚えておくと、見慣れない型に出会っても、落ち着いて対処できるはずです。

## 結論
先程結論は述べたが、改めて。
上記の引用の理由から、左辺は**<font color="FireBrick">「RGBTRIPLE型のwidth個の要素を持つ配列」へのポインターimageを宣言して、右辺で初期化</font>**していると言えます！

```c
RGBTRIPLE (*image)[width] = ...
```
Googleスプレッドシートで米国株の株価推移をSPARKLINEで表示する

SPARKLINE関数とGOOGLEFINANCE関数を組み合わせて、米国株の株価推移をSPARKLINEで表示することができます。
画像のSPARKLINEはアップル社の過去1年分の株価推移です。
![20211212_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2377902/11f00cee-46c3-4f25-b549-84d90f94dd4a.png)

# 過去1年分の株価データを取得する
> 構文
> GOOGLEFINANCE(銘柄, [属性], [開始日], [終了日|日数], [間隔])

まずはGOOGLEFINANCE関数で過去1年分の株価データを取得します。
<code>=GOOGLEFINANCE("NASDAQ:AAPL","price", TODAY()-365, TODAY())</code>

# 過去1年分の株価データをSPARKLINE関数に渡す
> 構文
> SPARKLINE(データ, [オプション])

SPARKLINE関数に前項のGOOGLEFINANCE関数を埋め込みます。
<code>=SPARKLINE(GOOGLEFINANCE("NASDAQ:AAPL","price", TODAY()-365, TODAY()))</code>
これで365日分の株価推移が表示されます。

# 関連記事
* [Googleスプレッドシートで米国株の株価を取得する](https://qiita.com/WhimsicalTheo/items/6811bd81ab4e814c8d1f)
* [Googleスプレッドシートで様々な通貨を日本円に換算する](https://qiita.com/WhimsicalTheo/items/460b2ece81bc47a96375)
* [Googleスプレッドシートで米国株の配当利回りを取得する](https://qiita.com/WhimsicalTheo/items/401790003a20253eed08)

以上、最後まで読んでいただき、ありがとうございました。
【Nuxt.js】ボタンクリックで画面を表示させる方法

#はじめに
こんにちは！
今回は【Nuxt.js】ボタンクリックで画面を表示させる方法についてアウトプットしていきます！

#前提
・Nuxtの新規プロジェクト作成が既に済んでいる
・vue.jsの基礎学習が済んでいる

#対象
・真偽値を使用しての開発を学びたい方
・診断アプリケーションを作りたい方


#実装
```vuejs:template
<button class="mb-16 px-20 border-4 border-green-200 text-center rounded-full hover:bg-green-100 duration-1000" 
       @click="openQuestion" >
    <p class=" py-4 w-64 text-2xl">診断を始める！</p>
</button>

    <div v-if="showQuestion" class="bg-green-100 bg-opacity-85 py-28">
      <div class="max-w-screen-md m-auto  mb-28 py-16 border-4 border-red-600 rounded-lg bg-white">
          <p class="text-4xl ">Q.1</p>
          <p class="py-8 text-2xl">コミュニケーションで悩んだことはありますか？</p>
          <ul class="flex justify-center tracking-widest">
              <button class="text-2xl my-6 mx-10 py-6 px-6 border-2 border-red-600 rounded-full h-28 w-28 flex items-center justify-center"
              :class="answers.q1 ? 'bg-red-200' : ''"
              @click="answer('q1',true)">
              YES
              </button>
              <button class="text-2xl my-6 mx-10 py-6 px-6 border-2 border-blue-600 rounded-full h-28 w-28 flex items-center justify-center"
              :class="answers.q1 === false ? 'bg-blue-200' : ''"
              @click="answer('q1',false)">
              NO
              </button>
          </ul>
      </div>


```
```javascript:script

  data() {
    return {
      showQuestion: false,
    };
  },

  methods: {
    openQuestion() {
      this.showQuestion = true;
    },

```

#解説

コード見にくくて大変申し訳ありません。今回注目していただきたいのは`@click="openQuestion"`、`v-if="showQuestion"`の部分です。
`script`を見ていただくと`showQuestion`は`false`、`openQuestion`は`showQuestion`を`true`にするという記述がされています。

tempulate側でdivに`v-if="showQuestion"`と記述することで、falseが働き画面に表示させないようにしています。
それを上記に記述してある`button`で`@click="openQuestion"`と記述することで、「このボタンが押されたら、`showQuestion`を`true`にする」という処理が働く。よって以下のように

![スクリーンショット 2021-12-05 15.33.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/102de1e1-87e6-e4fe-0486-e6881ba03071.png)

診断を始める！ボタンを押すと、

![スクリーンショット 2021-12-05 15.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/728cf206-4f57-88f5-9e04-fdb88a4eb6e3.png)

`false`指定した画面が表示されるということになる。



#最後に
今回はボタンクリックで画面を表示させる方法についてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
全ての曲を1分にする２

https://qiita.com/o________o/items/d54a7da10c07968c12b9

これの続き。
長い曲聴くのだるいと思ったから作った。

# 1分にする
曲の間を適当に削って1分にする

```python:

path = "motoneta.mp3"

import numpy as np
import librosa
import pydub
from pydub import AudioSegment

y, sr = librosa.load(path)
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

# 曲の長さ（ミリ秒
time = int(librosa.get_duration(y=y, sr=sr) * 1000)
# BPMから1ビートの長さをとる（ミリ秒
beat_time = int( 60 / tempo * 1000)

base_sound = AudioSegment.from_file(path, format="mp3")
oneminit_sound = base_sound[0:0]
start_time = 0

# 1分にする
while(True):

    import random
    # 乱数で適当に切り出す箇所の終了位置決める(ここの乱数がいじりどころ
    end_time = start_time + (random.randint(1, 4) * beat_time)

    # 切り出してくっつける
    cut = base_sound[start_time : end_time]
    oneminit_sound = oneminit_sound + cut

    # 1分すぎたら終わり
    if 60000 < len(oneminit_sound):
        break

    # 乱数で適当に切り出す箇所の開始位置決める(ここの乱数がいじりどころ
    start_time = end_time + (random.randint(10, 16) * beat_time)

    # 曲一周したら頭に戻る
    if time < start_time:
        start_time = start_time - int(time)

oneminit_sound[:60000].export("oneminit.mp3", format="mp3")



```

おしまい

# 聞いてみた
49秒の曲が1分で6回聞けた、
長さが1/5になったくらいの計算になる。

https://soundcloud.com/bjack_mijilme/python-oneminit

原曲

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

#感想

忙しい現代人に

#今後の展望

今は行儀よく開始から終了の方向で連結してるけど、ランダムに戻ったり逆再生音源差し込んだりしたい
クラウド スキル チャレンジ Microsoft Ignite: Azure Developer Challenge  やってみた

# 経緯
Microsoft Igniteに寝落ちしながら参加してたところ、バウチャーのもらえるチャレンジを発見。いい機会なのでやってみることにした。一応、Azureに興味のある開発者なので、Azure Developer Challengeを選択。
さて、開始です。

# ボリューム
早速ボリュームチェック。
モジュール数33で約21時間。11/4~12/01の1ヶ月弱でこなせばOKです。
![2021-12-11 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/da7f3061-3d50-4893-21be-1e8a28be4cba.png)

# はじめてみた
2ヶ月あるしと、深く考えずに週末メインでゆったりこなせばいいんじゃないとはじめました。
が、半月くらい過ぎたところで、実際は1ヶ月弱しかなくて週末は4回しかないことに気が付きました。1週末に8モジュール…。すでに半月過ぎている。ちょっと用事があると厳しいボリューム。平日も1モジュールでも進めていく方針に切り替えました。

# モジュールの構成
モジュールに入ると、このモジュールについての説明があり

- 学習の目的
- 学習の前提
- ユニットの説明

が書かれています。1モジュールの中にだいたい7-8ユニット入っています。

# ユニットの構成
ユニットは、

- はじめに
- 説明もしくはチュートリアル ←複数ある
- 知識チェック
- まとめ

が入っています。説明を読んで理解したりチュートリアルで手を動かしたりしたら、知識チェックで簡単な問題に答えて、間違ったら正解するまで勉強しなおすパターンになります。

# チュートリアル
説明があってやってみればOKのものと、実際にAzureと連携して正しくできているか確認されるものと2種類あります。Azureのアカウントがあればサンドボックスで手を動かすので、料金はかからずに勉強を進められます。

サンドボックスが使える場所には、このような表示が出ますので「サンドボックスをアクティブ化」を押します。
![2021-12-11 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/1bb82e05-0c99-ec98-89d1-1c863edb2335.png)
するとこんな表示に変わるので、こんとは「アクセス許可の確認」を押します。
![2021-12-11 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/fc24304b-fbcf-5937-6858-50a769820c57.png)
するとマイクロソフトアカウント確認されるので、使いたいマイクロソフトアカウントを選択するとサンドボックスが有効化されます。
![2021-12-11 (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/e395a9b3-a5c4-c734-fb68-c13821a0fb94.png)
あとは、チュートリアルに従えばOK!

# 結果
無事に完了しました！
![2021-12-11 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/88a09085-97c2-3be2-13ab-90f5877e976c.png)

バウチャーもGET!
![2021-12-11 (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2317283/43e8cfba-918f-f8b3-c95f-b0d319a5a9a7.png)



#その他いろいろ
まだ日本語に対応していないモジュールもありますが、Google翻訳で雰囲気みたあと英語にきりかえれば、英語が超低レベルでも頑張れました。
実務未経験の初学者がAWS認定クラウドプラクティショナーに合格するまでにやったこと。

## はじめに
先日、AWS認定プラクティショナー試験を受験しました。
実務未経験だったのでサービスの理解等に心配がありましたが、無事に合格することができました。
この記事は、今後の自分のための学習の振り返りと、
自分と似たような状況でこれから受験する方への参考として、
- 事前にこんな知識を持っていて
- こんな勉強をすると
- テストのレベル感をどう感じて
- 実際どのくらいの点数が取れたか
といった記録を残しておこうと思って書いたものになります。

## 簡単なまとめ
|||
|--|--|
|学習時間|43時間|
|得点数|799 / 1000 点|
|テスト本番で使った時間|90 / 90分|

こちらを見ればわかると思いますが、
「最短最速で満点合格するぜ！」みたいな記事ではないのでご承知おきください。

事前知識と学習内容に対する本番のレベル感をイメージしやすくするためのものと思ってもらえると幸いです。

※学習時間はtoggl計測ですが、試験の受講登録や、学習用のテキスト・Udemy講座を探したりする時間も含まれています。

## 事前に持っていた知識
学習開始前、事前に持っていた知識は以下の通りになります。

### 基礎知識

- ITパスポート：取得済み
- 基本情報処理技術者試験：未受験

### AWS以外の知識

- HTML/CSS
- PHP
- Laravel
- JavaScript
- Git
- サーバー（Linux）
- セキュリティ

それぞれ入門書１-２冊分を写経したくらいの知識。

### AWSに関する知識
- 書籍：AWSで始めるLinux入門ガイド
- AWS公式：「はじめてのアマゾンウェブサービス」
- AWS公式：「AWS Hunds-on for Beginners」

EC2などいくつかの主要サービスについて、
「どんなサービスなのか雰囲気だけ知っている」くらいの状態。

## 学習内容
学習には以下を利用しました。
順番は個人的に役に立った順になります。

- Udemy：「この問題だけで合格可能！AWS認定クラウドプラクティショナー 模擬試験問題集（7回分455問）」
  - ほぼ一択の鉄板みたいにネットで紹介されてる問題集。
  - 本番に近い形式で解説もついているため、実際一番勉強になった。
- AWSスキルビルダー：「AWS Cloud Practitioner Essentials (Japanese) (日本語実写版)」
  - 日本人が日本語でAWSを解説してくれる動画講座。
  - 例えがとてもわかりやすく、サービスを一通り理解するのに非常に役立った。
  - 学習を飽きさせず、理解しやすくするための工夫がされていて取り組みやすい。
  - ノリが海外のそれなので最初は違和感があるが慣れると面白い（主観）
  - 和訳といっても、横文字がそのまま並ぶことが多いので（ニュアンスの関係上？）知らない横文字は調べながら視聴する必要がある。
- web問題集：「【AWS資格】無料WEB問題集＆徹底解説 | クラウドプラクティショナー(CLF)」
  - 無料だったのでやってみたが、学習の入り口としてとても使いやすかった。
- 書籍：「一夜漬けAWS認定クラウドプラクティショナー」
  - 他よりも網羅性が高いとの評判が多かったため購入
  - 正直そこまで活躍はしなかったが復習時にピンポイントで役に立つことがあった。
  - 付属する模擬問題集は解説とセットでかなり理解しやすかった。

  
### 詳細
1. はじめにスキルビルダーで基礎的なサービスを理解
1. スキルビルダーの後半からweb問題集を併用して学習
1. Udemyの模擬試験に挑戦→解説読む（基礎1週目）
1. 書籍により復習
1. Udemyの模擬試験に挑戦→解説読む（基礎2週目+応用1週目）
1. 随時復習しながらUdemyの模擬試験に挑戦→解説読む（応用2週目、3週目）

試験本番までの模擬テストの成績は以下のような感じでした。

|週目|基礎|応用|
|--|--|--|
|１週目|70%|55%|
|２週目|90%|70%|
|３週目|-|90%|
※ %はおおよその値です。


## テストのレベル感
最初にまとめて書いた通り、結果は試験時間90分をフル活用して799点でした。

予想より難しい！というのが受けてみた印象です。

AWS試験本番では見直したい問題をマークしておけるのですが、
１周解いた時点でマークが１５個ほどあり、少し焦りを感じました。

最終的にはマークを２個まで削り、テスト終了。

問題数６５問に対して２割間違えているので、配点が一定なら１３問落とした感じです。（不合格ラインはおそらく２０問前後）


大体マークした数と同じくらいなので割と感覚通りの得点ですね。


回答時に問題ごとにメモを残せる機能があり、見直しの際に非常に助けられました。


## 振り返り
今回のAWS認定クラウドプラクティショナーの試験を受けるにあたり、行った学習方法は以下のようなやり方でした。

1. 動画で基礎を一通り押さえる
1. 模擬テスト１週
1. 動画+書籍で復習
1. 模擬テスト２週、３週

### 振り返って思うこと
- １週目の動画視聴時に、理解しきれないサービスが「へーふーん」状態になったため、その時間はロスに思えた。

- テストまでの期間を考え連続で模擬テストを受講したが、解説を読むのに力を使うので、受講→解説→受講...というサイクルは集中力的にあんまり良くなかったかなと感じた。

- 短いサイクルで模擬テストを受けたので、答えを覚えている問題がどうしても出てしまい、惰性で解いている部分があった。

### 次回の学習をどうするか
次回SAA受ける時はテスト先行で学習してみようと思っています。
具体的には、以下のような小さなサイクルを回してみようかと。

1. 模擬テスト
1. 基礎学習・復習
1. 模擬テスト
...


理由は以下の通り。
- 模擬テストでは実務的な内容も多く出てくるのでその解説を読み、改めて動画を視聴したときに、なるほどと思えることが多かった
- 模擬テストで初見のサービス名が出てくると、基本太刀打ちできないが、後からそのサービスを動画等で確認すると理解がスムーズになる感覚があった


## 受験してみて思ったこと
- AWSのサービスの広さ半端ない
- 実務なしで資格を取ることについて、ただの暗記になってしまうのではと思っていたが、AWS自体がビジネスのニーズに応えて既存の課題を解決するためのサービスなので、普通にめちゃめちゃ勉強になった。

## 終わりに
学習記録を取っていたので振り返り用に作成してみました。もし「こういう内容も気になる！」ということがあればコメントいただけると嬉しいです。手持ちのメモで対応できるものなら追記したいと思います。
今後受験する方の参考になれば幸いです。最後まで読んでいただきありがとうございました！
Node-REDでフローが動かなくなったら試すこと

WindowsPCでNode-REDをバージョンアップして動かそうと思ったら
「 不明なノードが存在するため、フローを停止しました。」
と表示が出て動かなくなりました。
Node-RED User Group Japanのfacebookグループで質問したところ
@utaani がアドバイスしていただき無事解決できたのでやったことをまとめたいと思います。

##症状と経緯
下記のようなのが表示されフローが動かなくなりました。
iopluginが原因とのことでした。
![cap205.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/b81807bd-5614-9002-4a64-73fb6edb7715.jpeg)

iopluginを調べてみるとnode-red-contrib-gpioノードなので
パレットの管理で現在のノードで検索して調べてみるとノードが存在してました
![cap206.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/9ea418a7-e40a-be9d-6528-befb92cb5c05.jpeg)
削除もすべて無効もボタンを押せる状態でなく
途方に暮れてNode-RED User Group Japanのfacebookグループに相談し
アドバイスを受けました。

##対策
###Node-REDの終了
コマンドプさせるロンプトで　Ctrl＋Cで終了させる

###node-red-contrib-gpioの存在の確認
まずは、node-red-contrib-gpioが存在するのか？
エクスプローラーで確認しました。
ユーザー名/.node-red/node_modulesフォルダー内にnode-red-contrib-gpioフォルダーがあるか
確認

###node-red-contrib-gpioフォルダーも存在し中にファイルがあったので削除する
削除するのはコマンドプロンプトで行いました。
1.CDコマンドでディレクトリーを変更する為
エクスプローラー上でnode_modulesフォルダーを右クリックしてプロパティを選択して
階層を調べました。
2.CDコマンドを実施
3.npm uninstall node-red-contrib-gpiotと打ち込みファイル削除
4.エクスプローラー上でnode-red-contrib-gpiotフォルダーがなくなってるのを確認

###動作確認１（上手く行かなかった）
　１．Node-REDを起動して動作確認→症状消えず同じ表示が出てた
　２．パソコン再起動してNode-REDを起動して動作確認→症状消えず同じ表示が出てた
　３．再度　Node-RED User Group Japanのfacebookグループで相談
　４．未使用タブに存在してないか確認とアドバイスを受けました。

###動作確認２（上手く行った）
　１．設定ノードを開き未使用タブを開いた
![cap217.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/95c89349-e7f2-40ae-2a34-93000d7aca8e.jpeg)
　２．iopluginノードがあるか確認→存在せず
　３．すべてのフロー上に存在してるものを削除してみた。
　４．デプロイして動作確認→表示が消えて動き出した

##最後に
今回のトラブルもNode-RED User Group Japanのfacebookグループで相談したことで
無事解決できました。
@utaani さんありがとうございました。
Node-RED触ってると多動力だなとよく思いますが
トラブルを相談して解決するとさらに強く多動力を感じます。
私のスキルはこんなものですが引き続きあとから来る人達の問題解決に
わずかながらでも力になれたらと思います。
サクッとはじめるArduinoライブラリ

この記事は「[Arduino Advent Calendar 2021](https://qiita.com/advent-calendar/2021/arduino)」の13日目の記事です。

## よく使うメソッドは外出ししちゃおうっていう話
もう2〜3年くらいArduino使ってません（学生の時以来でしょうか）。でも使ってた頃よくあったのですが、スケッチは機能を追加すればするほどコード量が多くなります。しかも私がたまにあったのが、前に別のスケッチに書いた機能をコピってくるってやつです。
メソッド分ければコード量が多くてもそんな大したことないけれど、よく使うメソッドをしょっちゅうペッタンペッタンとコピーするくらいなら、ライブラリ化してしまってコード量減らしちゃおうって話です。

## Arduinoライブラリの作り方

### テンプレ
クイックスタートをモットーにしているので、細かいことは置いといてテンプレート貼っちゃいます。
（シリアル通信で`"Hello World"`を出す例をつけておきます）

```cpp:MyLib.cpp
#include "MyLib.h"

MyLib::MyLib(){
	// コンストラクタはArudinoライブラリでも有効
    Serial.begin(9600);
}

void MyLib::method(void){
	// ここにスケッチに書いたものを、そのまま書く
    Serial.println("Hello World");
}
```


```ヘッダー:MyLib.h
// Arduino.hをインクルードすれば、Arduinoの関数が使える
#include "Arduino.h"

class MyLib{
public:
 // publicメソッド=>スケッチからアクセスできる
 MyLib();
 void method(void);
private:
 // privateメソッド=>スケッチからアクセスできない
};
```

できたCPPファイルとヘッダーファイルはZIPに圧縮しましょう。
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/ef622493-46dc-3f44-f915-ab888fe462c9.png)
とまぁ、こんな感じに。

## 作ったライブラリを取り込む

※スクショはmacOSです。

__1.  Arduino IDEの[スケッチ]→[ライブラリをインクルード]→[.ZIP形式のライブラリをインストール]を開く__
![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/99f8450d-21db-d520-d888-b06d3c137d15.png)

__2. さっき作ったZIPを取り込む__
![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/cda3c8e5-d250-7288-0803-3c1657d956d8.png)

すると、[ライブラリをインクルード]のところに、`MyLib`ができます。
![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/51321355-af5f-4c29-613f-384276f47aeb.png)

## 作ったライブラリを使う
ライブラリをインクルードできたら、あとは使うだけです。

```:スケッチ
// ライブラリをインクルードすると勝手に追記される
#include <MyLib.h>

void setup() {
  // put your setup code here, to run once:
  // 定義するとコンストラクタが動く
  MyLib lib; // Serial.begin(9600);
  lib.method(); //Serial.println("Hello World");
}

void loop() {
  // put your main code here, to run repeatedly:

}
```

## 出力結果
シリアルモニタに`"Hello World"`が出ているはずです。
![fig5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/e17f79a1-26d3-d9e2-7cd1-e63ae70b9625.png)

## 最後に
この記事の動作確認で久しぶりにArduino触ったけど、やっぱ楽しいですね。
これをきっかけに、またArduino触ろうかしら…。
スクロールの理解が足りなさすぎて少し現場の予習。

## overflowがまずわかっていない

- デフォルトは**overflow: visible;**ではみ出した分はそのまま表示されるみたい
- hiddenで隠せるみたい
- scroll、autoどっちを指定してもスクロールはだせるみたいだが、ブルウザによって挙動がかわるよう。ここは現場に合わせて指定しようと思う。
- 縦スクロールはheigthで高さをしてして、autoをすればスクロールできるみたい
- スクロールした時にゆっくり終わるスクロールを慣性スクロールというみたい
- 横スクロールはoverflow-x:scrollを指定する、親要素を子要素の幅が超えた時にスクロールがでる
VMWARE イメージのデフォルトのインストール場所の変更

# VMWARE イメージのデフォルトのインストール場所

VMWARE イメージのデフォルトのインストール場所の変更方法を説明します。

## 結論

`%APPDATA%\VMware\preferences.ini` に `prefvmx.defaultVMPath = "D:\VMWARE"` というような記述を追加する。

(Windows 10, Windows 11 の場合 `C:\Users\ユーザー\AppData\Roaming\VMWARE\preferences.ini` に対応します。`ユーザ` の部分は自分のユーザー名)

## 背景

VMWARE を新規にインストールするとき、インストール先の場所のデフォルトは以下の値になります。

```
%HOMEPATH%\Documents\Virtual Machines
```

ユーザーが `user` の場合は以下のような値になる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/e68594ea-228d-cbff-e1b3-ad7c5dbc0bf7.png)


しかし、データ用のドライブに VMWAREの仮想マシンを作成したい場合、毎回インストール場所を指定しないといけないので面倒です。
デフォルトのインストール場所を変更する方法を説明します。

## 変更方法

(1). `%APPDATA%\VMware\preferences.ini` をテキストエディタで開きます。
(2). `%APPDATA%\VMware\preferences.ini` の最後に追加して保存します。

```
prefvmx.defaultVMPath = "D:\VMWARE"
```

`"D:\VMWARE"` は自分が使用したいパスに読み替えてください。

(3). VMWARE を起動していたら、終了してから、起動しなおします。

以下のようにデフォルトのインストール場所が変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/63e0b944-7c96-af27-3d2d-b4273294cbba.png)


## 参考リンク

* [共有仮想マシン ディレクトリ](https://docs.vmware.com/jp/VMware-Workstation-Player-for-Linux/16.0/com.vmware.player.linux.using.doc/GUID-E9A55CCD-A503-405F-94B4-D956734B0CA5.html?hWord=N4IghgNiBcICIHsDGBXAtgUwHYBcDOIANCBgB4wgBqAlgE44qQAEAsmEgBbVYYEC+QA)
* [Setting the default directory for VMs](https://communities.vmware.com/t5/VMware-Workstation-Player/Setting-the-default-directory-for-VMs/td-p/1157173)
文字列補間チートシート

すぐ記法を忘れてしまうので、私が最近よく使う言語の String Interpolation Cheat Sheet です。


|言語|記法|null文字列の出力結果|
|:-:|:-:|:-:|
|Kotlin|`"${foo}"`|`"null"`|
|Swift|`"\(foo)"`|`"null"`|
|TypeScript|``　`${foo}`　``|`"null"`|
|Ruby|`"#{foo}"`|`""`|
|Python|`f"{foo}"`|`"None"`

# Kotlin

```kotlin
val str: String = "nya"
val nullableStr: String? = "neko"
val nullStr: String? = null
print("Hello ${str}, ${nullableStr} and ${nullStr}")
```

```
Hello nya, neko and null
```

# Swift

```swift
let str: String = "nya"
let nullableStr: String? = "neko"
let nullStr: String? = nil
print("Hello \(str), \(nullableStr) and \(nullStr)")
```

```
Hello, nya, Optional("neko") and nil
```

なお Optional 型を使おうとすると `String interpolation produces a debug description for an optional value; did you mean to make this explicit?` という Compiler Warning が出る。
 

# TypeScript

バージョン 1.4 以上

```typescript
interface Hoge {
  str: string
  optionalStr?: string
  nullStr: string | null
  undefinedStr?: string
}

const hoge: Hoge = { str: "nya", optionalStr: "neko", nullStr: null }
console.log(`Hello ${hoge.str}, ${hoge.optionalStr}, ${hoge.nullStr} and ${hoge.undefinedStr}`)
```

```
Hello nya, neko, null and undefined
```

# Ruby

```ruby
str = "nya"
nullStr = nil
puts "Hello #{str} and #{nullStr}"
```

```
Hello nya and 
```

# Python

バージョン 3.6 以上。

```python
str = "nya"
nullStr = None
print(f"Hello {str} and {nullStr}")
```

```
Hello nya and None
```
データベースの種類を初めて知ったので備忘録

#目的
データベースの種類 備忘録

#結論
5種類あった。
1.階層型データベース
2.リレーショナルデータベース
3.オブジェクト指向データベース
4.XMLデータベース
5.NoSQLデータベース

***
__階層型データベース__
データをヒエラルキー構造で管理するデータらしい。
データベースの歴史上最初に登場した。
今でも稀に使われている。

__リレーショナルデータベース__
関係型データベースとも言うらしい。
二次元表でデータを管理するタイプで今の主流。

__オブジェクト指向データベース__
オブジェクトでデータを管理するらしい。
リレーショナルデータベースを超える存在として期待されたが、
ニッチな市場のためこれから頑張るみたい。

__XMLデータベース__
XMLでデータを管理するらしい。
こちらもオブジェクト指向データベースと同様期待されていたが、これから頑張るみたい。

__NoSQLデータベース__
リレーショナルデータベースの一部の機能を捨てることで、処理スピードを速くすることを追求したもので、
WEBサービスと相性が良く最近使われるらしい。

__豆知識__
データベースの始まりはアドレス帳らしい。

#参考
おうちで学べるデータベースのきほん
DockerコンテナにAWS CLI v2をインストールとLaravel＋S3

# Dockerコンテナで`AWS CLI V2`をインストール

前提としてコンテナが立ち上がっていて、`curl`、`unzip`がインストールされた状態です。

コンテナに入ります。

## １．下記のコマンド実施
`curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"`

## ２．解凍実施
`unzip awscliv2.zip`

## ３．インストール
`./aws/install`

## ４．確認
`aws --version`

こちらのように表示されればインストール完了です。
aws-cli/2.4.6 Python/3.8.8 Linux/5.10.25-linuxkit exe/x86_64.debian.10 prompt/off

- Dockerfileはこちら

```
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
 && unzip awscliv2.zip \
 && ./aws/install
```

## 5.必要ないのでzipを削除
rm ./awscliv2.zip


## ６．アクセスキーとシークレットアクセスキー
AWS Access Key ID
AWS Secret Access Key
AWS コンソールから取得しておきます。

## 7.設定と確認
最初に`aws configure`に設定をいれる。
下記のようにAccess Keyと、Secret Access Keyと、region nameを順に入力を求められるので、
答えていけば設定が完了します。


```
AWS Access Key ID [None]: 【Access Key】
```
```
AWS Secret Access Key [None]: 【Secret Access Key】
```
```
Default region name [None]: 【region】
```
東京regionの場合は`ap-northeast-1`

```
Default output format [None]: 
```

`ls`しても何もファイルは出来ていませんが

```
ls -al
total 76
drwxr-xr-x  6 root root   192 Dec  9 23:03 .
drwxr-xr-x 31 root root   992 Dec 12 09:41 ..
-rw-r--r--  1 root root  1465 Dec  9 22:54 README.md
-rw-r--r--  1 root root 68279 Dec  9 22:54 THIRD_PARTY_LICENSES
drwxr-xr-x 71 root root  2272 Dec  9 23:03 dist
-rwxr-xr-x  1 root root  4047 Dec  9 22:54 install
```

もう一度`aws configure`すると、見えないけど設定は入っていて、１行ずつマスクされて表示されるので
Enterで次が表示されます。


## ８．LaravelでAmazon S3を操作する場合
いろいろな記事を見ると.envに設定（AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY）を書くように書いてあるけど、上記ですでに設定しているので必要ないようです。

但し.envに下記の２点は書く必要があります。

```
AWS_DEFAULT_REGION=【region】
AWS_BUCKET=【バケット名】
```

```
/* s3を指定する */
$disk = Storage::disk('s3');

/* s3ディレクトリを指定する */
$dir = '/';

/* 転送する方法は諸説あります */
$disk->putFileAs($dir, 転送元のディレクトリとファイル名, ファイル名);
```


以上
importするライブラリと同じファイル名で実行してエラー

基本的なことでハマってしまったので、
備忘録として残します。

下記のthreading.pyというファイルを実行しようとして、エラーではまってしまいました。

``` threading.py
import threading
```

エラー内容は下記のとおり

```
AttributeError: partially initialized module 'threading' has no attribute 'RLock' (most likely due to a circular import)
```

解決方法

ファイル名を変更

threading.py → threading_test.py

これだけでエラーが解消しました。

けっこうエラー文だけからは判断しずらいですよね....
STM32L010のGPIOで遊ぶ(ポートA)


目的
ポート出力のテスト

いろいろ
少女A じゃなくて　ポートAだよ
完全には確認してないや




参考


https://os.mbed.com/users/okini3939/notebook/PortOut_jp/




```c++


#include "mbed.h"

//                       76543210
PortOut ledport(PortA, 0b00010000);
//DigitalOut myled(PA_4);


int main()
{

    while(1) {
        
        //myled = 1;
        ledport = 0b00010000;
        wait(0.2);
        //myled = 0;
        ledport = 0;
        wait(0.2);

    }

}

void error(const char* format, ...) {}


```
画像をクリックするとポップアップで拡大するサンプル

画像をクリックするとポップアップで拡大表示する、というのは良くありますが、プラグインなど追加せず書く必要に迫られたので対応しました。
せっかくなのでコードを共有します。

# 実装

## HTML
対象の`img`タグに、`class="popup"`を追加します。

```html:HTML
<img src="qiita.png" class="popup">
```

拡大表示用のモーダル枠を確保します。表示されないので、どこでも良いです。

```html:HTML
<div id="modal-container">
  <div><img src=""></div>
</div>
```

# CSS
SCSS記法なので、CSSでは読み替えて下さい。

```scss:SCSS
#modal-container {
  display: none;
  position: fixed;
  background: rgba(0, 0, 0, .6);
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 99;
  & > div {
    display: flex;
    height: 100vh;
    justify-content: center;
    align-items: center;
    & > img {
      max-width: calc(100vw - 30px);
      max-height: calc(100vh - 30px);
    }
  }
}
img.popup {
  cursor: pointer;
}
```

## JavaScript (ES2015)
要jQuery。

```js:JS
const modal = $('#modal-container');
const img = modal.find('img');

$('img.popup').each(function(index) {
  $(this).click(function() {
    img.attr('src', $(this).attr('src'));
    modal.show();
  })
});

modal.click(function() {
  $(this).hide();
});
```

jQueryを使わない環境なら、

```js
const modal = document.getElementById('modal-container');
```

```js
images = document.querySelectorAll('img.popup');
```

```js
modal.addEventListener('click', function() {
  modal.style.display = 'none';
}, false);
```

のような感じになるかと。

# デモンストレーション
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBPaJXa" data-user="mindwood" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mindwood/pen/qBPaJXa">
  Image popup sample</a> by マインドウッド｜ソフトウェアの修理屋さん (<a href="https://codepen.io/mindwood">@mindwood</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
【Python】文字列中に'a'から'z'までの文字がそれぞれ何個ずつあるかを取得する。

Paizaなんかをやっていると、結構よく使う気がします。
出現しなかった文字は0になる形で結果を得たいというのがポイントです。
forループを使えば簡単に書けるタスクではありますが、辞書の代わりに`Pandas.Series`を使い、標準機能の`collections.Counter`を用いることでも簡潔に書くことができます。


## 結論

以下の通り。

```python
labels = list(string.ascii_lowercase)  # カウントする文字のリスト
atoz_dict = pd.Series(  # Seriesを初期化
    np.repeat(0, len(labels)),
    index=labels
)
counts = Counter(text)  # 文字列・リスト中のユニークな要素と出現数の辞書
atoz_dict[counts] = counts  # pd.Seriesならこんな形で代入ができる。辞書だとできない

print(atoz_dict)
# a     5
# b     3
# c     1
# 　︙
# x     0
# y     2
# z     0
```


## ちょっとした補足

### インポートするもの

`pandas.Series`, `collections.Counter`が必要。



### 変数`labels` 「カウントする文字のリスト」

辞書でいう見出し・キー、`pandas.Series`でいうところのインデックスに当たる。

調査する文字列内に、このリストにない文字があるとエラーになる。

```python3
labels = list(string.ascii_lowercase)  # カウントする文字のリスト
# ['a', 'b', 'c', ..., 'x', 'y', 'z', ' ']
```



### `Counter`クラス

文字列・リストを渡して初期化すると、ユニークな要素とそれらの出現数の辞書の形が得られる。

ただし通常の辞書と違い、辞書内にないキーを指定した場合0が返ってくる。

```python
counts = Counter("abcab")
counts['a']  # 2
counts['z']  # 0
```



### `pandas.Series`への代入

以下のように１行で書くことができる。

```python
atoz_dict[counts] = counts
```

この書き方ができるのは`pandas.Series`であるからであり、辞書に対してこのような代入はできない。

`Series`が扱いづらい、という人は最後に`Series`を辞書に変換してください。

```python
atoz_dict = dict(atoz_dict)
print(atoz_dict)
# {'a': 5, 'b': 3, ...,'x': 0, 'y': 2, 'z': 0}
```



## コード全文

```python
import numpy as np
import pandas as pd
from collections import Counter
import string

text = "alice was beginning to get very tired of sitting by her sister on the bank and of having nothing to do"
text = text.replace(' ', '')  # 空白を削除

labels = list(string.ascii_lowercase)  # カウントする文字のリスト
# ['a', 'b', 'c', ..., 'x', 'y', 'z', ' ']

atoz_dict = pd.Series(  # Seriesを初期化
        np.repeat(0, len(labels)),  # np.zeros()だとデフォルトで小数型になるのでnp.repeat()を使用
        index=labels  # 辞書で言うところのkeyにあたる
)
counts = Counter(text)  # 文字列・リスト中のユニークな要素の数を辞書で返す。
atoz_dict[counts] = counts

print(atoz_dict)
# a     5
# b     3
# c     1
# 　︙
# x     0
# y     2
# z     0

# pandas.Seriesが扱いづらければ辞書に変換
atoz_dict = dict(atoz_dict)
print(atoz_dict)
# {'a': 5, 'b': 3, ...,'x': 0, 'y': 2, 'z': 0}
```
EC2とS3の間のVPCエンドポイント設定で通信料金のかからない方法

# AWSでS3を設定するとインターネットゲートウェイ経由として通信してしまう
S3とEC２の通信はインターネットに一度出てしまうため、料金が発生しますが、今回のようにVPCエンドポイントを設定することでセキュアに且つ、通信量が発生しない方法を取りたいと思います。

１．VPCダッシュボード
２．エンドポイント
３．`エンドポイントの作成`ボタン
４．サービスカテゴリ：`AWSサービス`にチェック
５．サービス名：`com.amazonaws.ap-northeast-1.s3`を選択(フィルターに追加した方が探しやすい)
エンドポイントタイプ：Gateway
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501225/dc357045-ac54-6ce1-43d2-33719d0c1bd3.png)

６．VPC：プルダウンから選択（ルートテーブルIDを確認してチェックボックスにチェックします）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501225/6ab11f62-bb3e-df1c-0f3f-9d7be90e230a.png)

７．ポリシー：ターゲットのS3バケットのみ操作可能にします（デフォルトは全ての操作が有効のため、最小限に変更）
※YOUR-TARGET-BUCKETの部分はS3の名前に書き換えてください。

```
{
    "Version": "2012-10-17",
    "Id": "PolicyXXXXXXXXXXXXXXXX",
    "Statement": [
        {
            "Sid": "StmtXXXXXXXXX",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::YOUR-TARGET-BUCKET",
                "arn:aws:s3:::YOUR-TARGET-BUCKET/*"
            ]
        }
    ]
}
```
８．エンドポイントの作成ボタンを押して完了です。
簡単ですが以上です。
TypeScriptの「こういう時ってどう書くの？」

## `Utility Types`を理解
こういう時ってどう書くの？って時にめっちゃ使います。
大抵のものが解決できると思っています(大ごと)

特に`Pick`やら`Omit`やらはよく使う印象です。

▼ 超参考になる記事

https://qiita.com/k-penguin-sato/items/e2791d7a57e96f6144e5

## 配列編
下記コードを例に説明していきます。

```example.ts
const cheeseList = ['モッツアレラ', 'チェダー', 'カマンベール'] as const;
```

### 何番目のリテラル型が欲しい
```ts
// type Mozzarella = 'モッツアレラ'
type Mozzarella = typeof cheeseList[0];
```

### 配列のユニオン型をつくりたい
```ts
// type CheeseList = "モッツアレラ" | "チェダー" | "カマンベール
type CheeseList = typeof cheeseList[number];
```


:::note
as const はすべての値をreadonlyにします。
つまり、変更不可になるため、より厳格な型定義がされるためユニオン型を実現することができます。
:::

## オブジェクト編
下記コードを例に説明していきます。

```example.ts
const cheeseObj = {
  mozzarella: {
    name: 'モッツアレラ',
    productionArea: 'Italia',
  },
  cheddar: {
    name: 'チェダー',
    productionArea: 'England',
  },
} as const;
```

### 入れ子になっているオブジェクトの型を取り出したい

```ts
// type Mozzarella = { name: 'モッツアレラ', productionArea: 'Italia' }
type Mozzarella = typeof cheeseObj['mozzarella'];
```

### オブジェクトのキーのユニオン型が欲しい

```ts
// type CheeseList = "mozzarella" | "cheddar"
type CheeseList = keyof typeof cheeseObj;
```

### オブジェクトの値のユニオン型が欲しい
これは自作する必要があります。


```ts
export type valueOf<T> = T[keyof T];
```

▼ 参考

https://zenn.dev/bom_shibuya/articles/ed8fd9f80d3782b1f156


```ts
const colors = {
  red: '#f00'
  blue: '#00f'
} as const;

// type Color = "#f00" | "#00f"
type Color = valueOf<typeof colors>;
```

## ジェネリクス活用編

ジェネリクスは難しく思えるかもしれませんが、

* 型に引数を持たせる(`<(引数)>`で渡してあげる)
* 引数の型に制限を持たせる(`<T extends 〇〇>`)

これらを組み合わせているだけです。

### 渡した型と同じ型を返す
複雑な処理の過程で、returnのタイプの抽象度が上がってしまう場合において使います。

```ts
const sameTypeArray = <T>(list: T[]): T[] => {
  // いろんな処理
  return formattedList
};

// エラーにならない
sameTypeArray(['one', 'two', 'three']).map((item) => item.toUpperCase());

// エラーになる
sameTypeArray([1, 2, 3]).map((item) => item.toUpperCase());
```

### 上の処理のTは、○型か△型しか受け付けない
このような時は`extend`を使います。

```ts
type ArrayType = number | string;
const sameTypeArray = <T extends ArrayType>(list: T[]): T[] => {
  // いろんな処理
  return formattedList
};
```

▼ 参考

https://qiita.com/tfrcm/items/cd8dafcc8ee4f824ccf5#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9%E3%81%AE%E5%88%B6%E7%B4%84




## never活用編
### Aの時はBを持たなくて、Bの時はAを持たない

```ts
type Link = {
  onClick?: never;
  href: string;
};

type Click = {
  onClick: () => void;
  href?: never;
};

type ButtonProps = Link | Click;


// エラーがでない
const buttonPropsOnClick: ButtonProps = {
  onClick: () => {
    console.log('link');
  },
};

// エラーがでない
const buttonPropsLink: ButtonProps = {
  href: 'https://example.com',
};

// エラーがでる
const buttonProps: ButtonProps = {
  href: 'https://example.com',
  onClick: () => {
    console.log('link');
  },
};

```

---

今後、「こういう時ってどう書くの？」と悩んだ時に追記していきます！！
BigQueryとデータポータルを使いデータ活用が進んだ話

# 概要
本ページは、[datatech-jp Advent Calendar 2021](https://qiita.com/advent-calendar/2021/datatech-jp)  12日目への投稿です。
この1年ほど、 BigQuery とデータポータルを使い、社内のデータ利活用が進みました。その取り組み内容を記事として残しておこうと思います。

# 課題
関連部署からデータ抽出の依頼があった場合、アナリストが都度 SQL で分析基盤からデータを取得し、結果をエクセル等 で依頼者に共有するようなケースは多いと思います。
私の周りではこの業務フローに関して下記のような問題が起こりがちでした。

- エクセルの行数がボトルネックになり、粗い粒度の集計結果しか提供できない
- 手動で抽出するケースが多く更新が手間
- 提供したデータの利用状況の確認が困難
    - 定期更新はしているが、実際にはほとんど利用されていないファイルが散見 

# やったこと
## 集計でよく使うデータを BigQuery に定期的にコピー 
エンジニアの協力の元、オンプレミスの分析基盤から必要なデータを BigQuery に取り込んでもらいました。
データが重くBigQuery への移行が難しいものに関しては、用途に応じて集約したりサンプリングしたテーブルを用意しました。

## Google データポータルでダッシュボードを作成
BigQuery に移したテーブルをデータソースにして、Googleデータポータルでダッシュボードを作成しました。
エクセルのような行数の制約がなくったため、今までは可視化できなかったような切り口のダッシュボードを作ることができました。

### Google データポータルに関するTips
Google データポータルに関しては細かい部分で躓くことが多かったため、いくつかメモを共有します。
(2021.12.12時点)

- 定期的に pdf をメール配信できる
    - 共有 → 「メール配信をスケジュール」　で設定
    - 複数のメールアドレスを登録した場合、各アドレスに都度メールが送られる
        - 公式のドキュメントには記載が見つからなかったのですが、複数のメーリングリストを宛先に設定したところ、「自分のところに同じ内容のメールが複数届く」という指摘を受けました。データポータルの共有先を一つのメーリングリストにまとめることで重複送信に対応しました。
- 閲覧者のログは残らない
    - Google spreadsheet 等と違い、どのデータポータルを誰が閲覧したか、ログは残りません。
    - 今回は作成したダッシュボードの利用状況を把握したかったので、Google アナリティクスのタグをデータポータルに埋める対応を取りました。閲覧者を特定することはできませんが、ダッシュボードのセッション数とユーザー数は見れるようになります。
- カスタムクエリでは DECLARE が使えない
    - どうやら使えないようです・・

## 社内イントラにダッシュボードへのリンクを貼った
ダッシュボードへの動線を確保するため、社内のイントラサイトにダッシュボードへのリンクを載せるようにしました。
URLだけでなく、データの更新頻度やオーナーが誰か、についても明記するようにしています。


## ダッシュボード作成マニュアルの整備
アナリストのメンバー全員がダッシュボードを作成できるようにするため、
以下の情報をマニュアルとしてまとめました。

- BigQuery にデータをコピーする際の依頼フォーマット
- データポータル作成の方法
- Googleアナリティクスのタグ設置
- 社内イントラサイトへの掲載


# 所感
ダッシュボードが作られたことで、「こんなデータ出せないか」という要望に対して会話がしやすくなりました。
(例：「まずはダッシュボードを見て」「このダッシュボードにこの項目を追加するのはどうか」)
また、ダッシュボードがあることで「このデータを誰に見せるか」といった議論もしやすくなり、総じてデータ管理の面でレベルが上がったと感じています。