OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on RailsでAPI認証（devise_token_auth）

## コマンドメモ
```
$ rails new project1 --api
$ cd project1
$ rake db:create
$ (Gemfileを更新する)
$ bundle install
$ spring stop   ←止めないと次のコマンドが止まる場合があった
$ rails g devise:install    ←ごちゃごちゃ言われるけど気にせず次に行く
$ rails g devise_token_auth:install User auth
$ (migrationファイルを更新する。confirmナントカはコメントアウト、indexのところも含めて)
$ rake db:migrate
```
【ffmpeg】ラズパイでh264_omxエンコードできないときは…

Raspberry Pi OS Lite (32bit) で 
ffmpeg を使って OpenMax(h264_omx) ハードウェアエンコードしようとすると

```
/opt/vc/lib/libbcm_host.so not found
Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

Conversion failed!
```

というエラーが出て、0バイトのmp4ファイルが作成される。

この問題を取り上げている記事がほとんど見当たらず、解決に２日以上かかったので備忘録として書いておく。

:::note warn
注意
OpenMaxは64bit環境に対応していません
64bitを使っている場合は、代替手段として V4L2コーデック (h264_v4l2m2m) を使ってください  →補足4. 参照
:::


# 解決方法

>/opt/vc/lib/libbcm_host.so が見つからない！！

と言ってるので `/opt/vc/lib/` を見てみると中身が空っぽだった。
**[raspberrypi/userland](https://github.com/raspberrypi/userland)（VideoCoreドライバー）を入れてみる。**
```bash
cd ~
mkdir git
cd git
mkdir raspberrypi
cd raspberrypi
git clone http://github.com/raspberrypi/userland.git
cd userland
./buildme
```
:::note info
正常にエンコードできるようになりました！
:::

# 補足

## 1. 環境
Raspberry Pi 4 (4GB RAM)
## 2. ffmpegのバージョンとか
```
ffmpeg version 4.2.4 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --prefix=/usr/local --disable-shared --pkg-config-flags=--static --enable-gpl --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-omx --enable-omx-rpi --enable-nonfree --disable-debug --disable-doc
```
## 3. Raspberry Pi 4 のビデオアクセラレーション
Raspberry Pi 4のハードウェア・エンコーダ情報
https://forums.raspberrypi.com/viewtopic.php?t=268356
## 4. 64bit環境のハードウェアエンコードについて
https://denor.jp/raspberry-pi-4%E3%81%A764%E3%83%93%E3%83%83%E3%83%88%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF
VsCodeでJerseyのデバック

# 1 MavenでJerseyプロジェクトの作成
下記写真のプロジェクトを選択
![スクリーンショット (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893794/63f54aaa-7b91-9ae1-75c8-32f5970e3685.png)

# 2 pom.xmlにjettyPluginを追加する
下記を参考
```
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>11.0.7</version>
</plugin>
```

# 3 launch.jsonの作成
```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Debug (Attach)",
            "request": "attach",
            "hostName": "localhost",
            "port": 8000
        }
    ]
}
```
# 4 mvndebug jetty:runを実行
# 5 Debugをクリック

上記手順でデバックができるはずです！！

> 参考https://github.com/kasecato/vscode-javadebug-sample/tree/maven-jetty
Google Speech Recognition 恐るべし

ソースコード

```Python
#!/usr/bin/env python3

import speech_recognition as sr

r = sr.Recognizer()

with sr.AudioFile("1-01.wav") as source:
  audio = r.record(source)

# text = r.recognize_google(audio, language='ja-JP')
text = r.recognize_google(audio, language='en-US')

print(text)
```

結果

```
TOEFL test must word 5,000 1:32 modern physical anthropology a major shift in the approach to physical anthropology occurred with the discovery of genetic principles to Gregor J Mendel had formulated the first laws of heredity 3 he had laid the foundation of the science of genetics for genes are the units within sex cells five the sperm and egg transmitted specific hereditary traits from one generation to the next six characteristics to be discarded in the hereditary process 7 blood types are genetically determined 8 we can trace early migration patterns
```

補足
パケットキャプチャを覗いたら、google宛にREST APIを叩いていることを確認できた。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182287/c72bf02e-56bf-2f70-02ca-5558ffcecc50.png)
重たいコンポーネントとv-showの勘所

最近あった出来事が印象的だったのでまとめます。
例えば以下のようなコンポーネントが定義されていたとします。`SuperOmoiComponent` はマウントするのに2秒かかります。membersの件数は、1000個の要素が存在しています。さて、`SuperOmoiComponent`がマウントして画面が自由になるのはどれぐらいかかるでしょうか。

```vuejs
<template>
  <div>
    <template v-for="(member, index)in members">
      <SuperOmoiComponent v-show="index < 10" :member="member"/>
    </template>
  </div>
</template>
```

...

ここで気づいてほしいのが、`v-show` のディレクティブです。v-show は、display: none を対象の要素やコンポーネントに設定するのですが、v-show を指定している場合はとりあえずレンダリングをする、という動きがなされます。`SuperOmoiComponent`　はマウントに2秒かかるので、単純計算では 2 * 1000 秒かかることになります。一方で v-if を指定していた場合は、最大でも10件までのレンダリングしか行いませんので、 2 * 10　秒しかかかりません。

ということで、v-if / v-show も使い所を考えて、重いコンポーネントを大量に表示させるような場合には、v-show は使わないなどの工夫が必要なのだと改めて思った次第でした。
Office Onlineのシート、スライドごとのURL【2022/11/3追記】

# 追記
2022/11/3にExcel Onlineのセルのリンクについて追記しました。

# はじめに

Googleのスプレッドシートやスライドではシートごと、スライドごとにURLが異なるので、共有する際に直接シート、スライドを指定できるので便利です。一方、Office Onlineではシート毎にURLが変わらない（ブラウザで表示されるURLは変わらない）ので、共有する際少し面倒です。
※いちいち『「〇〇」シートを見てください』『スライド番号nnを見てください』とか指定しないとならない。
GoogleみたいにURLだけ指定してあげれば良いようにしたい。ということで調べました。

# PowerPoint Onlineの場合
公式に載っていました。以前調べた時は無かったような気がするので、最近追加されたのかな。
[特定のスライドへのリンクを共有する](https://support.microsoft.com/ja-jp/office/%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%81%B8%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E5%85%B1%E6%9C%89%E3%81%99%E3%82%8B-4f5f3d5e-1674-4742-8cf1-9623050c19ef)

# Excel Onlineの場合

Excelはオフィシャルなものがないようです。
今後仕様が変わる可能性がありますが、以下のやり方でできそうです。

## activeCellパラメータを使う
activeCellパラメータはその名の通り、アクティブにしたいセル番号を指定できるパラメータのようです。このパラメータを指定してあげると良さそうです。

`&activeCell='[シート名]'![セル番号]
`

Excelをブラウザで表示した際のURLの最後尾に上記形式のパラメータをつければOK。

## 【2022/11/3追記】「この範囲へのリンク」機能追加
待望の特定のセルへのリンクが簡単に共有できるようになりました。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/bf73e09a-2e2c-2db6-9819-03169fac9973.png)

謝辞：@kzkamiyaさん

# 最後に
大したことがない記事ですが、つまりメモです。Wordは調査中。
E資格合格に向けて　応用数学 第1章：線形代数

# 0.なぜ線形代数を学ぶ必要があるのか？

　プログラミングの世界では複雑な処理を簡略化するためのタグや関数（繰返し処理など）が多く存在している。
　線形代数は、複雑な計算式などを簡略化させるために誕生したもの。
　Pythonのような簡略化が重要なプログラミングにおいて、線形代数の仕組みや理論を活用し、シンプル化を実現している。

# 1.線形代数とは

　代数というのはxやyのことであり、その部分にどのような数字が入るかわからないからひとまずxなどを代わりに使おう、という考えの元使用されている。
　そしてその代数をさらに簡略化させたものが、線形代数。

# 2.連立方程式と行列
　
　連立方程式も線形代数の一つ
　次のような連立方程式がある
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/5fd5c18a-17dd-e858-f569-126b53cf7606.png)
　これを数式で解くかわりに、行列を使ってシンプルな形にして解くことが出来る。この連立方程式を行列で表すと以下である。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/34b84121-ede8-ffd1-8d50-7bc5598018bd.png)
 この行列を変形させると、x1とx2が求まる。

# 3.単位行列と逆行列
　単位行列とは、「対角成分が全て1で、それ以外は全て0な正方行列」のこと
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/826e7fff-ec84-cc36-384c-51c7b2030599.png)
　
　逆行列とは、「元の行列にかけると単位行列になるもの」のこと
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/dbb0d0e7-a5d4-64d4-566b-01197ebc6a46.png)

![IMG_9865.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/294ccb6a-9818-81f7-1fbb-7a4e98f58439.jpeg)

#　4.固有値と固有ベクトル
　n次正方行列Aとλに対して、
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/e45d0bf8-ce6f-3fe8-9dab-b9ad4fc46926.png)
　を満たすゼロベクトルでないn次列ベクトル
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/1d73a1e2-02b3-72f5-ec9b-8b3a7ce1e4fd.png)
　があるとき、λを行列Aの固有値といい、xをAの固有値λに対する固有ベクトルという
　
　![IMG_9864.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/6f5e0a02-47ef-8173-ed7f-d73a10fa3e7e.jpeg)

# 5.特異値（分解）
　線形代数学における複素数あるいは実数を成分とする行列に対する行列分解の一手法
　
　![IMG_9866.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313001/500e146f-b045-068e-385b-de66dae4250c.jpeg)
インフラエンジニア学習　CCNA 1122

IPv４ヘッダ
バージョン…IPヘッダのバージョン
0100…IPv4
0110…IPv6

ヘッダ長…ヘッダの長さ
0101になる事が多い（1ビットが4Byte)
4×5=20バイト

サービスタイプ（ToS)…サービス品質
現在はToSとして使われない

DHCPフィールドやECNフィールドなど別の情報として利用される

パケット長…パケットの長さ
IPで運べるのは65535Byte
フラグメントしてデータを分割する。
識別子…フラグメントを再構成する時に利用する
フラグ…分割する時の制御情報
フラグメントオフセット…分割されたデータの位置情報
TTL…ルータを通過できる回数
プロトコル…IPヘッダの次のプロトコルを表す
ヘッダチェックサム…IPヘッダが壊れてないかを確認するための情報
送信先/宛先IPアドレス…TCP/IPで必須の情報、通信するための住所



Pingが失敗した時の表示：Destination Unreachable（宛先に到達不能の場合に使用されるタイプコード）

指定した宛先に対するpingが成功しない場合、OSI参照モデルのネットワーク層、データリンク層
、物理層に問題があると考えられる。

以下のアプリケーションプロトコルは、コネクション型のTCPを使用
・SMTP…メール転送用のプロトコル
・SSH…通信内容を暗号化する遠隔操作用のプロトコル
・FTP…ファイル転送用のプロトコル


以下のアプリケーションプロトコルは、コネクションレス型のUDPを使用
・TFTP…効率性重視のファイル転送用プロトコルで、ファームウェアの転送などに利用される。
・ＶolP…音声データを送信するためのプロトコル
・ＳＮＭＰ…ネットワーク上の機器を総合監視するためのプロトコル

ＦＴＰの特徴
・認証機能サポート…ＦＴＰサーバにアクセスする際のユーザ名とパスワードを求めるよう設定できる
・TCPの使用…トランスポートのプロトコルとしてTCPを使用する。
・制御用ポートと転送用ポートの使用使用…FTPのコマンドを送るための制御用ポート２１と、実際のファイルを送るための転送用ポート２０を使用する。

SSHの特徴…TCP/IPネットワーク上のネットワーク機器やサーバを遠隔操作するためのプロトコル。

DNS
DNSはドメイン名をIPアドレスに自動的に変換してくれるアプリケーション層プロトコル。
ドメイン名とIPアドレスの対応付けを行うことを名前解決。
名前解決を行うソフトウェアをリゾルバという。
リゾルバがDNSサーバに行うドメイン名からのIPアドレスの名前解決にはUDP（ポート番号53）を使用する。
　一方、DNSサーバとDNSサーバとがゾーン情報のファイル転送を行う場合 TCP(ポート番号53）を使用する。

DNSサーバ
DNSサーバは、ドメイン名とIPアドレスの対応情報を保持している。
この対応情報をゾーンファイルと呼ぶ。
DNSサーバはクライアントからの問い合わせに対して、ゾーンファイルを参照し、適合するIPアドレスをクライアントに回答する。

Telnet
Telnetは、ネットワークに接続された機器を遠隔操作するために使用するアプリケーション層プロトコル。
Telnetユーザは、IPネットワーク上にある機器に対してTelnet接続を要求します。
この時、Telnetユーザからの接続を受ける機器であるTelnetサーバに対して、あらかじめTelnet接続を許可するための設定が必要。
データはクリアテキストで送信される。

DHCP
DHCPは、ネットワーク接続するのに必要なIPアドレスなどの情報を自動的に割り当てるアプリケーション層プロトコル。
IPアドレスとサブネットマスクの他に、様々な情報を取得できる。

DHCPクライアントがDHCPサーバに対して送信するメッセージは、DHCP REQUEST、DHCP DISCOVER

・DHCP DISCOVERはブロードキャストで送信される。
・デフォルトではルータはDHCP DISCOVERメッセージを破棄するため、DHCPサーバが外部ネットワークに存在する場合は機能しない。
・DHCPリレーエージェントによって、ルータはDHCP DISCOVERを転送できる。


DHCPサーバの特徴
・クラアントに配布するためのTCP/IPの設定情報を保持する。
・クライアントのIPアドレスを配布する。
・デフォルトゲートウェイを通知する。
p5.js Web Editor上で Tone.js を使って音を鳴らす【その2： INSTRUMENT をいろいろ試す】

以下の記事の続きです。

●p5.js Web Editor上で Tone.js を使って音を鳴らす【その1】 - Qiita
　https://qiita.com/youtoy/items/d320580be404594f8cf8

[公式ドキュメントの中で、以下の画像に出てる部分](https://tonejs.github.io/docs/r13/Instrument)のものを使い比べてみる、という話です。

![INSTRUMENT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ac323e43-2c9f-07ff-71a6-87c11c0b48fe.jpeg)

## 下準備
p5.js Web Editor でのライブラリ　の読み込み（index.html での追記）は、前回と同様です。

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.32/Tone.min.js"></script>
```

## JavaScript のプログラム
sketch.js の内容は、以下のようにしてみました。

```javascript
let synth = [];

function setup() {
  createCanvas(400, 400);
  background(220);

  synth.push(new Tone.AMSynth().toDestination());
  synth.push(new Tone.DuoSynth().toDestination());
  synth.push(new Tone.FMSynth().toDestination());
  synth.push(new Tone.MembraneSynth().toDestination());
  synth.push(new Tone.MetalSynth().toDestination());

  synth.push(new Tone.MonoSynth().toDestination());
  synth.push(new Tone.NoiseSynth().toDestination());
  synth.push(new Tone.PluckSynth().toDestination());
  synth.push(new Tone.PolySynth().toDestination());
  synth.push(new Tone.Synth().toDestination());
}

function draw() {}

function keyPressed() {
  let synthTemp;
  const now = Tone.now();
  switch (key) {
    case "a":
      synthTemp = synth[0];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
    case "s":
      synthTemp = synth[1];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
    case "d":
      synthTemp = synth[2];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
    case "f":
      synthTemp = synth[3];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
    case "g":
      synthTemp = synth[4];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;

    case "z":
      synthTemp = synth[5];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
    case "x":
      synthTemp = synth[6];
      synthTemp.triggerAttackRelease("4n");
      break;
    case "c":
      synthTemp = synth[7];
      synthTemp.triggerAttack("C4");
      break;
    case "v":
      synthTemp = synth[8];
      synthTemp.triggerAttackRelease(["C4", "E4", "A4"], "4n");
      break;
    case "b":
      synthTemp = synth[9];
      synthTemp.triggerAttackRelease("C4", "4n");
      break;
  }
}
```

音を鳴らす部分について、以下のものは少し指定する内容に違いがあります。

- NoiseSynth()
    - triggerAttackRelease("4n")
- PluckSynth()
   - triggerAttack("C4")
- PolySynth()
   - triggerAttackRelease(["C4", "E4", "A4"], "4n")

上記を動かしてキーをポチポチ押していくことで、音の違いを簡単に確認できるようになりました。
電車でGO!新幹線専用コントローラーを修理する

引き続き、電車でGO!新幹線専用コントローラーで遊んでいきます。
使用時間は大したことないはずで、前回使ったとき（２０年近く前）は正常動作していたと記憶しているのですが、マスコンハンドルが動作不良を起こしており、ノッチ0と1しか反応しない状態になっていました。
今回の記事ではそれを修理してみようと思います。
# 分解
ねじ止めを外して分解した写真がこちらです。
![DSC_0016.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/f4ac4122-dfe7-d169-1a1a-bb3801056796.jpeg)
おお…古めかしい基板だ…
ハンドルの振動モーターってハンドルの先端の方についていたんですね～
今回は表示器の方には用がないのでここまでしか分解しません。
# マスコン周辺
マスコンを外す前はこんな感じ。~~ネジが１つ足りない感じがしますが、コストカットなのか、私のロットだけそうなのかはわかりません。~~ 1か所は底板と共締めです。
![DSC_0017.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/46dff104-89ec-6a88-efe2-1a16d97d072c.jpeg)
部品としてはシンプルで、小さい部品もないので難易度は低そうです。
筐体についている板バネがポロリと落ちてなくしそうなので気をつけてください。
# マスコン基板
問題の基板はこちらです。
![DSC_0018.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/b8bf607d-7e8f-1794-fdd9-24d56d33d3bf.jpeg)
きれいですね～。かわいいね～
適当に回路図を起こすとこんな感じです。
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/fead0155-138d-5101-f029-ed860fc41e8b.png)
シンプルですね。抵抗分圧をハンドルについたショートバーで選択してA/Dにでも突っ込んでいるのでしょう。
ブレーキの方は390 Ω→560 Ω、×14個→×9個に読み替えてください。
どちらも合計して約5.5 kΩほどになります。1 mA弱流れるわけですね。
精度の高い金属皮膜抵抗を使っているのか、チップ抵抗の表示は「3900」と有効数字が多めです。
サイズは1608と思われます。
# 故障原因
てっきり端子に付着したグリスが原因で接点不良を起こしているのかと思ったのですが、清掃しても復活しません。
そこで抵抗値を測定すると、いくつかの抵抗がオープンモードで故障していたようです。
どうやらこのコントローラーの泣き所らしく、ハンドルが反応しない原因はほとんどこれっぽいらしいです[1]。
部品の型番もデータシートもわからないので何とも言えませんが、定格電力ギリギリで設計されてしまっているのではないでしょうか。
20年前の1608サイズの金属皮膜抵抗の定格の相場を覚えている人がいたら教えてください。
ともかく、チップ抵抗の交換で直りそうです。
直ったら追記しようかなと思います。
# 直ったので追記
参考文献のとおり、チップ抵抗を交換したら直りました。
1608だとちょっと元のサイズより小さいですが、つけることは可能です。
[交換のやり方は適当に検索してください。](https://www.kogadenshi.co.jp/%E5%8D%8A%E7%94%B0%E4%BB%98%E3%81%91%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF/%E8%A1%A8%E9%9D%A2%E5%AE%9F%E8%A3%85%E9%83%A8%E5%93%81-smd-%E3%81%AE%E5%8D%8A%E7%94%B0%E4%BB%98%E3%81%91/)
あとはこの交換部品がどのくらい長生きしてくれるかですが…はてはて…
写真撮り忘れたので、動作確認用に作ったソフトのスクショでもおいておきます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/158be5eb-35a3-3fb5-17cc-1d3e324c8ae5.png)
やったね。
# 参考文献
[1][電車でGO！新幹線編専用コントローラの修理。](https://ameblo.jp/kuroha157/entry-12626857574.html)
【2021年度】使って便利だったSaasたち

## 概要
2022年度に向けて、今年使って便利だったsaasのまとめ

- [Sentry - エラー監視 -](#Sentry)
- [Agora - ライブ配信 -](#Agora)
- [Zendesk - ヘルプページ -](#Zendesk)
- [Sendgrid - メール -](#Sendgrid)
- [Mailtrip - メールテスト -](#Mailtrip)


## Sentry
Sentryは、エラーを監視するのに役立つサービスです。
特にフロントエンドのエラーを監視するのに重宝しました。

制限などはありますが、Developerライセンスなら無料で使用できます。
小さなアプリぐらいなら十分かと

https://sentry.io/welcome/

## Agora
ライブ配信に必要な機能を提供してくれているサービスです。
少し痒いところに届かないと感じますが、簡単なライブ配信アプリを作るのには十分だと思います。
※WebSDKは3.xと4.xがありますが、これから使用する場合は4.xをお勧めします。

**従量課金生なので注意**

https://docs.agora.io/en

## Zendesk
ヘルプ機能が結構簡単に実装できてすごく驚きました。
無料トライアルが終了すると課金しないと使用できないので、基本無料で使用するならgoogle formの方が良さげかも

https://developer.zendesk.com/documentation/zendesk-web-widget-sdks/

## Sendgrid
言わずと知れたメール配信サービス

https://sendgrid.kke.co.jp/docs/index.html

## Mailtrip
メールのサンドボックス環境を提供してくれているサービス
基本無料で使えるので、本番では上記のSendgrid・テスト環境ではMailtripと合わせて導入してました

https://mailtrap.docs.apiary.io/#


## まとめ
来年度もアプリケーションを作成する際には、こういったsaasを積極的に使用していきたいと思います。

## 最後に

アルサーガパートナーズ Advent Calendar 2021 5日目は @1zushun さんのターンです。:tada:
pomodoro-trackerでSlack連携の勘所を探る

ポモドーロテクニックは聞いたことがあったのだが、先のふりかえりでタイムキーパーを置くアクションが出た時にもこのワードが出てきた。
そしてまた、母校の繋がりで修士論文研究のお手伝いをする機会に、これまたポモドーロが出てきた。
サイバー自習室という取り組みに利用者として参加、形成的評価で協力させてもらえることになったのだが、ポモドーロテクニックを取り入れていて、pomodoro-trackerというサービスを使っていた。

https://pomodoro-tracker.com
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/a89b3397-6a33-21c9-aca8-b012952144d4.png)
これがSlackとも連携できるということで、どんなもんだか試してみた。

Slackのプラットフォームとしての可能性は無限大で、色々な連携が活用されている。アプリもその一つなのだが、何かまだフワッとしていて、何ができて、そのためにはどうすればいいのか、利用者の立場からもサービスを考案する人も、開発する人もスカッと入ってこないなじゃないかなー

そんなわけで、知りたいことはなんだろう？を明確にしつつ、そこに向けて、pomodoro-trackerとSlackを連携させることを例に、モヤモヤを晴らそうというのがこの記事で取り上げることになります！

## 知りたいこと

### Slackのアカウントと外部のサービスが、いかにして繋がるのか

Slackの中から「アプリを追加」することができ、多くは外部のWebサービスのアカウントと連携することになります。Slackと連携するにはOAuthが使われているようです。

### pomodoro-trackerとSlackがつながって何が嬉しいのか

pomodoro-trackerのサイトでタスクを登録し、ポモドーロテクニックを使ってタスクをこなしていると、ポモドーロ中なのか休憩中なのかといったステータスがSlackのステータスに連携します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/0107555d-37f9-1098-6722-d2ba8aa39cce.png)
連携の設定を見ると、３種類のステータスが設定できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/69053548-4735-35b1-6d91-3637c5079062.png)
絵文字とキャプションが設定できる感じですね。

### 複数のワークスペースで連携する

Slackは複数のワークスペースに参加できます。pomodoro-trackerは同時に複数のワークスペースと連携できるのでしょうか？

今回、研究の取り組みのためのワークスペースは区切りがつけられ、別のワークスペースができましたので、そちらに連携するとしたらどうなるかやってみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/96a1c658-9181-347f-2490-249bf1705b63.png)
すでに誰かがワークスペースへアプリを追加されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/d58b70df-3ba2-f098-af4c-9730db638c79.png)
あとは、pomodoro-trackerから連携の設定。一度解除して再度連携すると、ワークスペースの選択が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/0c5bc2bd-7f93-3859-b7f9-c288bd777089.png)
連携したいワークスペースがリストされていない場合は「別のワークスペースを追加する」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/23ab850a-5ae4-a287-4289-d1e46545e2da.png)
許可すると、無事新しいワークスペースのアカウントと連携しました。

### 特定のチャンネルと連携する

iOSの写真アプリからSlackに「送る」と、シェアするワークスペースからチャンネルないしDM先が選択でき、共有することになる。
pomodoro-trackerの場合はSlackワークスペースのアカウントに対してStatusの連携ができるが、チャンネルに対して何かできるのか。できて嬉しいとしたら、ポモドーロの開始、終了などのアクティビティを記録する感じか。
この辺はまた後日探ってみる。

## まとめ

Slackとの連携は、外部サービス側の連携設定からSlackへのサインインを行い連携の関係を結ぶという流れでした。またpomodoro-trackerは同時に一つのワークスペースとの連携となるようです。
複数のワークスペースに同時にサインインしている人も多そうですが、pomodoro-trackerでタスク遂行中のステータスを連携したいワークスペースは特定されていそうな気もしました。
Ruby　シンボルを理解する

## ハッシュについて
ハッシュとは配列と似たようなもので、配列はindex(0から始まる投資番号)でvalue(値)を管理するのに対して、key(文字列のものとシンボルがある)によってvalue(値がある)。
以下にハッシュの例としてuserハッシュを用意する.

#### Ruby

```ruby
user = { 'name' => '田中',
        'email' => 'tanaka@example.com'}
```

あれこれ連想配列じゃん、javascriptのオブジェクトじゃんと思った人も多いと思う。呼び名が違うだけで実際ほぼ同じである。しかし、keyの値が文字列になっているし、=>　このような記号が使われている。（PHPなら使われていたような...)
####Javascript

```javascript
user = { name: '田中',
        email: 'tanaka@example.com'}
```

#### keyの値を文字列以外で書くことも可能！！　
##シンボルを使う 
こちらの方がbetterらしい
#### Ruby

```ruby
user = { :name => '田中',
         :email => 'tanaka@example.com'}
```

だいぶjavascriptに近づいた。:key名　でこのようにシンボルを書くことができる。さらに省略記法があるというので書いてみる
#### Ruby

```ruby
user = { name: '田中',
        email: 'tanaka@example.com'}
```
あれ上のjavascriptと同じだ！！Rubyのversionが上がっていくごとにこのような他の言語と合わせるような書き方になったらしい。

### 注意したい点
Javascriptと全く同じであるかというとそういう訳ではない。呼び出したい時に異なる。
#### Javascript

```javascript
console.log(user[name])
//または
console.log(user.name)
```

#### Ruby

```ruby
p user[:name]
```

出力方法はさておきRubyではシンボルの名残が残っていることに注目したい。

## まとめ

Rubyではシンボルと呼ばれるあまり他の言語では見られない形式を使ってハッシュ（連想配列）のキーにしていたが、他の言語とできるだけ近い形になるように変化してきた。このように他の言語に影響されて書き方が変わることは非常に多い。さらに統一化が進み言語が一つになれば学習コストが下がるのになと思ったw

##　参考にしたサイト

https://railstutorial.jp/chapters/rails_flavored_ruby?version=6.0#code-palindrome_tester
Windows で「有効なフォントファイルではありません」と表示される場合の対処法

# イントロダクション

フォント画像の描かれた SVG から、FontForge で Python Script を使用して ttf のフォントファイルを作成しました。
その際以下のアラートが出て、フォントを利用できないことがありました。

![invalid_font_alert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33738/99ad82bb-f75e-2ef1-7315-e42c1ac25915.png)

# ENV

- Windows10
- FontForge

# 原因

! （半角ビックリマーク）が指定されていない。

## 解説

「!」は UTF-8 で U0021 という文字コードを割り当てられています。これは制御文字を除くと一番先頭の文字コードになるため、恐らく Windows ではフォントファイルの有効性を確認するアルゴリズムとして「!」の有無を見ているのだと思います。

ちなみに「!」に空白の画像を指定しても「有効なフォントファイルではありません」と出てプレビュー、インストールに失敗します。

# 対処法

! を指定する。

! だけ指定してみました。無事、プレビューが出るようになりました。

![exclamation_only_font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33738/11e8aecc-6bf3-a3c2-2dfc-5c6eab87959c.png)


# 蛇足

Windows10 で初めて確認したので、インターネットから落としてきたフォントでもこの現象が起こるかもしれません。
このアラートが出てしまった際は、製作者のフォント作家さんにこっそり教えてあげると、みんな幸せになるかと思います。
AWS  Budgetsの設定をして予算が超えたときにアラートを飛ばす方法

基本的に僕の記事はエンジニアじゃないでも理解できるように書いているつもりです。宜しくお願いします。

## AWS Budgetsの設定をする。
AWSは従量課金と言われていて、いつの間にか自分が知らない間に高額な請求が来ていたなんて話もよく聞く。
そのためにあらゆる事前対応が必要だ。

``AWSのコスト・使用量が設定した値を超えた、超えそうと予測さいたときに自動的にアラートを送信``

このような設定をすることができるらしい。

## 設定手順
マネジメントコンソールの右上にあるユーザー名をクリックし。アカウントというところをクリックする。
![スクリーンショット_2021-11-22_21_26_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/9d4db9ca-1fe3-096e-2387-9f3f45cdc584.png)

そして、左のメニューからBudgetsというところをクリックする。

![スクリーンショット_2021-11-22_21_29_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/f3571a15-d5f7-e338-4035-2276baf27fb4.png)

予算を作成をクリックする。

![スクリーンショット_2021-11-22_21_31_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/fbb01ea3-b255-00e6-2495-87be86fc7bae.png)

コスト予算を選択し、次へをクリックする。

![スクリーンショット_2021-11-22_21_32_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/fd806279-15d9-7ac9-4d13-966756574f37.png)

そうすると、予算の設定画面にいく。ここで予算名(一番下の方にある)、間隔、予算有効日、開始月、予算の作成方法を選択、予算額などを入力する。
※画面のUIは結構頻繁に変わる。

![スクリーンショット 2021-11-22 21.43.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/e744c64b-bfb6-cb63-b6d5-c3ad04ceb59b.png)

次に、アラートの設定を行う。ここでアラートのしきい値の追加をクリックし、しきい値、トリガー(実績か予測か選択できる)、しきい値を超えた時のEメール受信者を入力する。そして、次へ。

![スクリーンショット 2021-11-22 21.46.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/b77a322b-6a6f-1a59-036c-ce2f0fb8f5ef.png)

この次にアクションをアタッチという画面が表示されるが、特に設定が必要なければ「次へ」をクリックする。

すると、このように予算の詳細画面が表示されるので予算を作成するをクリックすればok!

![スクリーンショット 2021-11-22 21.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/4aeb88d7-3632-e923-e273-01ea7a9e23c8.png)


## まとめ
AWS budgetsを使用すると、自分で設定した予算が超えたときにアラートを飛ばすことができます。
ぜひ、初心者の方は設定をしてから学習を始めましょう。
jupyter notebookみたいなのがvscodeでできる！簡単

普通通りVSCODEを開き、拡張子を「ipynb」で保存する。
**それだけ！！！**
気分転換にいろいろなエディタでやるのもおもしろい！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756524/07a71aec-31e3-618c-c6c3-e5754f2cad29.png)
ライブストリーミングサービスの方法

ライブストリーミングは、編集やポストプロダクションを行う必要がないインターネット上でライブ放送されるビデオコンテンツです。カメラの電源を入れて、いつでも録画を開始するだけです。さらに、ライブストリーミングはインタラクティブであるため、視聴者は動画の途中でコメントや反応をすぐに残すことができます。それだけでなく、ライブストリーミングを開始するたびに、アカウントフォロワーにも通知が届きます。通常、ビデオはすぐに保存されるため、ストリーミングの終了後にビデオを再度視聴できます。そうすれば、あなたのビデオを見逃した人もそれを見ることができます。ライブストリーミングはコンテンツマーケティングの一種であり、ウェビナーやQ＆Aセッションの形で視聴者に情報を提供するなど、目標を達成するために実行する必要があります。

デジタルマーケティング戦略の1つとしてライブストリーミングを行うことで、より多くの視聴者にリーチし、フォロワーとのエンゲージメントを高めることができます。ライブストリーミングを使用すると、新鮮で自発的なコンテンツを提供できます。コンテンツは編集できないため、これらの「生の」動画は視聴者に新しい印象を与えます。さらに、ライブストリーミングでは、自発的な割引、プロモーション、新製品などの興味深いニュースを共有することもできます。レビューを行う必要があるコンテンツ作成者の場合、ライブストリーミングはリアルタイムコンテンツの提供にも役立ちます。たとえば、新製品があり、レビューを行う必要がある場合、迅速かつリアルタイムでレビューを行うことができます。

ブランドの場合、この方法を使用して舞台裏のコンテンツを共有できます。舞台裏の活動を共有することで、視聴者や顧客との距離を縮めることもできます。
エクセルファイルを操作する

　data.go.jpからExcelデータを持ってきて，処理してみたい。

## データ選び
　data.go.jpのリソースから良さそうなものを選ぶ。

```プロデル
あという日本政府データ取得器を作る。
いは，あが「ポストドクター」という名前のリソースを20個，0から検索したもの。
い（「result」）（「results」）をうへそれぞれ繰り返せ
	う（「name」）を報告。
	う（「url」）を報告。
繰り返し終わり
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/271124c8-c16d-0f2e-faf2-4747af31d0cf.png)

## リソースのダウンロード

```プロデル
「https://www.e-stat.go.jp/SG1/estat/Xlsdl.do?sinfid=000027380264」を「a.xls」へHTTPでダウンロードする。
```

　令和にもなって.xlsファイルを扱うのは驚きだが，プロデルはエクセルファイルではなくエクセルを扱うので，エクセルが開けるファイルなら何でもOKである。

## エクセル操作

### ブックを開く

```プロデル
エクセルを起動する
エクセルで「a.xls」を開く。
それを報告。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/8a27026f-893c-25d7-80b7-2761599e02a1.png)

　どうやら，`エクセルで【ファイル名】を開く`手順はブックオブジェクトを返すようだ。

### データを眺める

```プロデル
エクセルを起動する。
エクセルで「a.xls」を開いて，その選択シートの一覧を，データへ代入する。
エクセルを終了。

行番号を1から1ずつ増やしながら［データの個数］まで繰り返す
	「［行番号］：［データ（行番号）を「，」で繋げたもの］」を報告。
繰り返し終わり
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/6ff211ca-1c38-35d7-d59b-6f442e38a603.png)

　5行目が回答の選択肢で，6行目から回答の割合が書かれている。数値と割合が2段組で書かれており，後者の方には業種が書かれていない。

　ちなみに，配列の「個数」はよく取得に失敗するので［］で囲むのがコツである。
M1 MacBookPro 買ったらすぐやる 環境構築 web開発 iOS開発 Scala3対応 [2021]

# キーボード設定
システム環境設定から

- ライブ変換オフ
- キー速度最速
- CapsLocksキーでABCと切り替える

# zshを便利にする
以下をまとめてコンソールに貼って実行

```zsh
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```
refs. https://github.com/sorin-ionescu/prezto

# homebrew

```zsh
softwareupdate --install-rosetta && xcode-select --install && /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 
```

コンソールに下のようなコマンドを実行しろと出るのでコンソールからコピペして実行

```zsh
    echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/ishibashi/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"
```

#iterm2を見やすくする
icebergをダウンロード

```zsh
curl -O https://raw.githubusercontent.com/Arc0re/Iceberg-iTerm2/master/iceberg.itermcolors
```

インポートしてからicebergを選択

```
iTerm >> Preferences >> Profiles >> Colors tab >> Color Presets.. 
```

iterm2 で新しいタブを開いた時にworking directoryを保存

```zsh
iTerm > Preferences > Advanced Configuration > Reuse previous session's directory
```

# よく使うツールをまとめてbrewでインストール
まとめてコンソールに貼る

```zsh
brew install yarn asdf ag docker xcodegen cocoapods
 coursier/formulas/coursier vips iTerm2 mysql karabiner-elements && brew install --cask sourcetree intellij-idea webstorm google-chrome docker 1password deepl sublime-text 
```
brewでインストールしておくと```brew upgrade```でまとめてアップデートできて便利
グローバルのJDKはbrewで入れて、プロジェクト毎のjdkはasdfで管理

# Scalaのインストール
```
cs setup && cs install scala3-compiler && cs install scala3-repl
```

# 途中でbad CPUというエラーが出たら

```
softwareupdate --install-rosetta
```

# Dockerのインストールで失敗したら

> Error: It seems there is already a Binary at '/opt/homebrew/share/zsh/site-functions/_docker'.

一度アンインストールしてから再度インストール

```zsh
brew uninstall docker
brew install --cask docker
```
"The Bézier Game"の全ステージ紹介

# [The Bézier Game](https://bezier.method.ac/) とは？
* ベジェ曲線の練習が出来るサイト。
* 各ステージに絵が1つ表示され、なるべく少ない本数の線で描き切った方が、スコアが良くなる。
* チュートリアル4コ + 実戦ステージ10コ → 計14ステージ
![01_intro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/e7209ba9-8e22-be81-e08a-f62d356d4b22.png)

# ステージ紹介
## チュートリアル
1. 角（カド・コーナー）  
目標：線2本
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/9419b4a7-d3c8-437c-8f47-1e11c72fde41.png)

1. 家  
目標：線5本
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/657eef8d-00f7-002e-b2df-1fcf3d954055.png)

1. 円  
目標：線4本
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/390b5b9b-aea7-757c-4903-c283ae3b5555.png)

1. ハート  
目標：線2本  
最初に描き方を教えてくれるけど、速くて全然わからなかった。4回ぐらい見直して、実際に試してなんとかクリア。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/cb9be4cf-48d4-6947-a7d8-0afba47a4c1b.png)

## 実戦ステージ
1. クルマ  
目標：線9本
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/1e6bca79-3ee4-f829-1a97-0c5b12b82709.png)

1. 飛行機  
目標：線10本
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/575a3417-e56f-fffa-de25-a2146f943c42.png)

1. クリップ  
目標：線8本
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/4ea33682-91e6-d7b0-8f7b-31a1eba72704.png)

1. スパナ  
目標：線8本?
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/b9916a60-242c-10c3-d9d6-ef4e55a4e436.png)

1. 雲  
目標：線5本
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/0527e525-d964-08aa-2672-781abb5dfb66.png)

1. 横顔  
目標：線9本
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/3e58a6ec-45b8-bd0a-8f65-096fa297368c.png)

1. 水鳥  
目標：線9本
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/980eda9e-6595-e96c-562c-b5fe27469c93.png)

1. キャップ  
目標：線9本?
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/8f4ed5a5-a5d3-00a3-87ad-714ed300dc33.png)

1. アルファベットのS?  
目標：線6本
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/78603107-205b-4dc2-e3c6-a944bfec31e6.png)

1. 旗?  
目標：線9本
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/06212c6b-f167-5ce8-c9d0-14368e9c7d54.png)

1. スコア発表
![21_score.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/55017bfd-96f4-0e86-51ff-2cac1e143e55.png)

# 姉妹サイト
1. [Welcome to Method of Action](https://method.ac/)  
他にも、カーニングの練習が出来るサイトなど、ユニークなサイトがいくつか公開されています。
![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/04fded5b-9feb-3657-ec60-e31d47a95a4f.png)
GCP Compute Engine その②


前回は、サーバの構築をしました。
次は、保守性を上げるためとセキュリティのためのアクセス制限を実装したいと思います。
GCPの中で通信制御をかけているのが「VPC」となります。
https://cloud.google.com/vpc?hl=ja
VPN(Virtual Private Network)といい、仮想的なプライベートネットワークです。
初期設定では、外部からの直接アクセスは無効となっているのでホワイトリスト形式で
実装するのが良いかと思います。※使用する環境にもよります

国ごとに割り当てられているIPv4アドレスを確認することも可能です。
日本は、世界3位の割当量です。
https://ipv4.fetus.jp/

***
![スクリーンショット 2021-11-22 12.21.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/1f05eac8-f2a5-6813-8d76-08ff2671cdc4.png)

【外部からのアクセス許可】　
①VPCのファイアウォールの設定を開く
![スクリーンショット 2021-11-22 20.51.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/b044d087-fdff-31b0-a5d7-9ce7f80c5ab5.png)

②自分ネットワークのグローバルアドレスを確認する
※確認くん(https://www.ugtop.com/spill.shtml)
③ファイアウォールルールの作成
　・ポリシー名(test80)
　・ネットワーク(default)　※対象のネットワーク選択
　・優先度(任意の値)
　・トラフィック方向(上り)　※上りが受信通信
　・一致したときのアクション(許可)
![スクリーンショット 2021-11-22 21.00.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/8d6d7b85-0c2a-b81e-a40e-c9c52ad716de.png)

・ターゲット(ネットワーク上の全てのインスタンス)
※GCEのインスタンスにタグをつけて対象を指定できる
・送信元IPv4アドレス(特定のIPもしくは0.0.0.0/0で全て許可)
・プロトコルとポート(tcp/80)
※今回は80番のみを許可
![スクリーンショット 2021-11-22 21.10.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/5f870e29-9a91-5b4d-5b72-5b360f8b5222.png)

これでポリシーの作成が完了。
GCEインスタンスの「外部IP」にアクセスして動作確認。
今回はApacheなので以下のような画面が表示される。
![スクリーンショット 2021-11-22 21.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/7713a575-3ad9-e9f3-3735-bbc83b995116.png)

【余談】
GCEインスタンス側で、http/httpsを許可すると80/443のポートがVPCの許可ポリシーが自動追加されます。
![スクリーンショット 2021-11-22 21.20.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396218/f72c79e7-90f2-740c-94d0-572c5df5c8d2.png)


【おまけ】
Centos8でApacheをインストール/起動する手順を以下に記載します.

```
#Apacheインストール
sudo dnf install httpd
#Apache起動
sudo systemctl start httpd
#Apacheの自動起動
sudo systemctl enable httpd
#Apacheのサービスステータス確認
sudo systemctl status httpd
```

次回は、外部から安全にSSH接続する方法を書きたいと思います。
限制性原理的数学探究

某日，群内闲聊。潜艇大谈其打牌经验心得，不无得意的说道："昨天一副牌我坐庄手持💗A,RHO争叫过1h可以认为持有💗K,但必须假定他持有另外一个♠K才能打成，我认为这种情况下RHO持有两个K的概率应接近30%而不是50%，因为RHO已经至少有了1个K,持有另一个K的概率会减少"。
林师怒之。
潜艇忿，力辩。
桥牌小白梨子想了一下告诉潜艇，林师是对的，应该是50%的概率，这可能就是男孩女孩悖论，所以导致会感觉概率会接近33%而不是50%，但其实是不对的。
具体参考如下：
[男孩女孩悖论](https://zhuanlan.zhihu.com/p/373437748)

潜艇看完若有所悟，曰:其实这和限制性原理很像。
桥牌小白不明所以，仍随口附合称是。
林师不悦道：吾深知潜艇此人，莫为之欺。应以深究限制性原理为妙。
小白深以为是，遂有此文。



# 限制性原理
![restricted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311521/b2c3b51a-28fb-c3fb-625c-f1637912e449.png)
南北必须在黑桃里只失一墩牌，第一轮♠J飞过，西家出♠2东家出♠K拿进，
第二轮西家出♠3,那么请问这种情况下，东家持有♠Q的概率大还是西家持有♠Q的概率大。

# 概率计算
也许你会很简单的认为，东西持有♠Q的概率各为50%,即
P(东持有♠Q) = 0.5
P(西持有♠Q) = 0.5

但如果真是这样，那小白也不必写此文了。

令
事件B = 西持有♠32并且东持有♠K
又令
事件A = 西持有♠32 - 东持有♠KQ
事件A'= 西持有♠Q32 - 东持有♠K

则我们要计算的其实是以下两个条件概率
P(东持有♠Q|事件B) = P(A|B)
P(西持有♠Q|事件B) = P(A'|B)

首先，我们先计算A和A'的概率. 
P(A) = 2c2 * 22c11 / 26c13 = 1 * 705432 / 10400600 = 6.7826087%
P(A') = 1c1 * 22c12 / 26c13 = 1 * 646646 / 10400600 = 6.2173913%

另外我们有P(A|B)+P(A'|B)=1
及根据全概率公式P(B) = P(A|B)*P(B) + P(A'|B)*P(B)

并且我们假定如果东家持♠KQ的情况下第一轮打出♠K的概率为50%。

<b>case 1</b>
即
P(B|A) = P(东第一轮打出♠K从♠KQ中) = 0.5

那么:
则根据贝叶斯公式：
P(A|B) = P(B|A) *P(A) / P(B)
P(A|B)*P(B) = P(东第一轮打出♠K从♠KQ中) * (6.7826087%)
P(A|B)*P(B) = (0.5) * (6.7826087%) = 3.3913043%

则根据贝叶斯公式：
P(A'|B) = P(B|A')*P(A') / P(B)
P(A'|B)*P(B) = (1.0000) * (6.2173913%) = 6.2173913%

P(B) = P(A|B)*P(B) + P(A'|B)*P(B) = 9.6086956%

则根据贝叶斯公式：
P(A|B) = P(B|A) *P(A) / P(B) = 35.29%
P(A'|B) = P(B|A')*P(A') / P(B) = 64.71%

**即东持有♠Q的概率为35.29%,西持有♠Q的概率为64.71%，所以应飞西家的♠Q**
难道至此大功告成了？
No,作为严谨的研究者，还远远不够。


# 深入探讨，前方高能
<b>case 2</b>
潜艇略思而后道：且慢，你之前假定P(A|B) = P(东第一轮打出♠K从♠KQ中) = 0.5
那我如果是东家我就拿着♠KQ第一轮永远从中打出♠K会怎么样。
即：P(东打出♠K从♠KQ) = 100%

则:
P(A|B)*P(B) = (100%) * (6.7826087%) = 6.7826087%
P(A'|B)*P(B) = (1.0000) * (6.2173913%) = 6.2173913%
P(B) = P(A|B)*P(B) + P(A'|B)*P(B) = 13.0%

P(A|B) = P(B|A) *P(A) / P(B) = 52.17%
P(A'|B) = P(B|A')*P(A') / P(B) = 47.83%

也就是说东家持有♠Q的概率上升到52%,应该用♠A砸。
演算到此，潜艇哈哈大笑，看来限制性原理不过尔尔，误导苍生多少年，今日为我所破。
林师观其行，复怒之。

**预知后事如何，且听下回分解**
Rails 投稿したTaskが削除できない

・起きている問題
GithubにPushしたもので、投稿したTaskの削除が出来ない。


下記のように、コード部分には特に欠陥はないように見える。

config.routes.rb


    
    resources :tasks

app/tasks_Controller.rb

    def destroy
        @task.destroy

        flash[:success] = 'Task は正常に削除されました'
        redirect_to tasks_url
    end

app/views/tasks/show.html.erb

```
<%= link_to 'このタスクを編集する', edit_task_path(@task), class: 'btn btn-light' %>
<%= link_to 'このタスクを削除する', @task, method: :delete, data: { confirm: '本当に削除してよろしいですか？' }, class: 'btn btn-danger' %>
```

エディタ（Cloud9)上では画像のように問題なく削除できるが、Githubからクローンしたものだと出来ない。
https://gyazo.com/a45f5e33d2626d6bc69393c2ff729c7b

・原因
コードそのものではなく、 ``` rails new ``` を実行してアプリを作成し始めた際に、``` --skip-active-storage ``` を付け忘れていたのが要因かと思われる。

・対処法
app/javascript/packs/application.js

```
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()
```

↑の
3行目: ``` import * as ActiveStorage from "@rails/activestorage" ```　と
最後の行: ``` ActiveStorage.start() ```
を削除する。

・結果
Githubからクローンしたものでも問題なく削除することができました。
アプリを作成する初期の段階でミスをすると、その後の開発している段階での戻り作業が大変になるので、気をつけたいですね。
PostgreSQLのバックアップについて

## バックアップの基礎

### ファイル形式の種類
バックアップファイルの出力形式には、**スクリプト形式**と**アーカイブ形式**の２種類存在する。

- プレーンテキスト形式
    - テキスト形式で作成されるので生データが見える
    - 拡張子はdumpでもsqlでもよい
    - リストアする時はpsqlコマンドを利用する（pg_restoreコマンドは利用できない）
    - データ件数が多いとファイル容量が大きくなる
    - 異なるデータベースにデータ移行する時にも利用できる

- カスタムアーカイブ形式
    - バイナリ形式で出力される
    - リストアする時はpg_restoreコマンドを利用する
    - 実運用ではこの形式がよく使われる

- TARアーカイブ形式
    - バイナリ形式で出力される（カスタム形式とは圧縮形式が異なる）
    - リストアする時はpg_restoreコマンドを利用する

### バックアップの種類

- 論理バックアップ
１データベース単位でバックアップする場合はpg_dumpコマンドを使うが、全てのデータベースに対して一括でバックアップを取る場合はpg_dumpallコマンドを使う。バックアップされるのはデータだけでなく、リストアする時に利用されるcreate tableのSQL文も一緒に作られてバックアップファイルが作成される。また、データベースのサービスを停止する事なく利用できる。（逆にいうとpostgreSQLが起動中でないとコマンドは使えない）日次のバックアップを取るときは基本的に論理バックアップを取る。定期的にバックアップを取る場合は、pg_dumpコマンドを埋め込んだシェルスクリプトを作って、cronコマンドでスケジューリングすることになる。バックアップを行うユーザーはスーパーユーザーとなる。

- 物理バックアップ
postgreSQLのサービスを停止させて、cpコマンドでデータベースファイルそのものを、ファイル単位でバックアップを取る方法。DB稼働中は排他がかかるためコピーはできない。基本的にデータ移行などの用途で利用する。

## バックアップの取り方

psqlコマンドでPostgreSQLにログインしてから、pg_dumpコマンドでバックアップを取ることもできるが、pg_dumpコマンドだけでPostgreSQLへのログインとバックアップを同時に実行することもできる。

psqlコマンドでPostgreSQLにログインする。

```cmd
psql -h 192.168.19.xx -d test_db -p 5432 -U postgres
psql -h IPアドレス -d データベース名 -p ポート番号 -U PostgreSQLのユーザーID
```

PostgreSQLへのログインとバックアップを同時に実行する。
オプション-tはテーブル名。usersテーブルのみバックアップを取っている。
オプション-fは作成されるバックアップファイル名。

```cmd
pg_dump -h 192.168.19.xx -p 5432 -U postgres -t users -f /home/tanaka/users.dump
pg_dump -h IPアドレス -p ポート番号 -U PostgreSQLのユーザーID -t テーブル名 -f 出力先ファイル名
```

オプション-Fpをつけると、テキスト形式でバックアップがとれます。
オプション-cをつけると、リストアするときにデータベースを削除するコマンドがバックアップファイルに含まれます。
オプション-dはデータベース名。

```cmd
pg_dump -Fp -c -h 192.168.33.xx -d test_db -p 5432 -U vagrant -f /vagrant/test_db.sql
pg_dump -Fp -c -h IPアドレス -d データベース名 -p ポート番号 -U ユーザーID -f 出力先ファイル名
```
【初心者向け】Raspberry pi がHDMIで映らない?解決策

#目次
* 起こった事象
* 解決策
* 参考文献


# 1. 起こった事象
モニターにラズパイ以外のHDMIを挿していることに気づかず、そのままラズパイの電源をONにしてしまいました。モニター映らないな〜と思い、ラズパイのHDMIが挿さっていないことに気が付き、挿し替えてもモニターがつかない！！

モニターが付かない原因はたくさんあります。

・HDMIの接触不良
・電源の容量不足
・ラズパイのハードウェアの故障
・モニターの故障

などなど。
全て確認してみてもうまく映らない、、

調べてみるとどうやら、ラズパイの仕様で、モニター類を何も接続しないで起動するとHDMI出力が検出できず、出力先が自動的にHDMIではなくコンポジットに変わってしまうらしい、、

#### 時間ないのに余計な時間取られてしまった!!!!!!

ということでここから解決策です。
# 2. 解決策
まず、ラズパイのSDカードを抜いて、他のPCでそのSDカードの中身を見ます
って言ってもMacBookだからSDカードみる専用のやつ持ってない!

なので私は
VNC ServerからMac上でラズパイの画面から操作しました。
[VNC接続のやり方はこちら](https://sozorablog.com/vnc/)

その後、boot/config.txtのファイルをいじればどうにかなるらしいと知った私はGUIでconfig.txtを開き、

```
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1
```
↓

```
# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=1
hdmi_mode=5
```

\#を外すと強制的にHDMI接続に変更されます。
hdmi_modeの部分は基本的に5でいけるそうですが、、自己調節お願いします、、
私はは5では画面サイズがおかしくなりました。

無事、変更が終わり、保存しようと思ったら、、

#### 文書の保存に失敗しました。許可がありません。

と表示され、調べてみるとrootでログインしないとできないみたいです。
rootでログインするにはrootにパスワードをつけます。
コマンドで

```
sudo passed root
```
と入力し、パスワードを設定します。
その後

```
su
```
でログインします。bootまで移動しviコマンドでconfig.txtを開きます。

ちなみに'sudo'と'su'の違いは
sudoは1回だけ管理コマンドを実行する場合です。
suはrootに完全に入って管理コマンドを行います。
その際、全ての権限を持って管理できるため、要注意です。


その後bootまで移動しviコマンドでconfig.txtを開きます。

```
vi config.txt
```

#### コマンドモードのキーやり方
##### x １文字削除モード
これで \# を消します。
qxitでモードの解除

##### R　現在のカーソル位置から文字を上書きするモード
数字の1の上から5に書き換える
qxitでモードの解除

##### :wq 保存し終了



今回はこちらで十分だと思います。
参考にさせていただいたviコマンド集は[こちら](https://eng-entrance.com/linux-command-vi#i-5)

その後、rootからログアウト(exit打つだけ)します。
rootのパスワードがある状態はセキュリティホールになりかねるのでパスワード削除のため、

```
sudo passwd -l root
```
で作業完了です。
無事、ラズパイがモニターに反映されました。
お疲れ様でした。

### 参考文献
[viコマンド](https://eng-entrance.com/linux-command-vi#i-5)
[rootログイン](https://www.fabshop.jp/raspberrypi-administrator-01/)
[モニターに画面が映らない対処法](https://raspida.com/rpi4b-config-hdmi)
アプリのアップデートメッセージを眺めてみた

# はじめに
iPhoneでしばらくアプリのアップデートをしていなかったら、33アプリのアップデートがありました。
アップデートのメッセージを眺めていると、今後の参考になりそうだったので一覧にしてみました。

【2024/10/11追記】
いくつか追加とDeepL翻訳ではなくChatGPTによる翻訳に変更

# アップデートメッセージ
## 日本語
* 細かい調整をしました。
* 機能を改修しました。
* 軽微な修正を行いました。
* 軽微な改修を行いました。
* 軽微な不具合を行いました。
* 軽微な不具合を修正しました。
* 軽微な不具合に対応いたしました。
* 不具合を修正しました。
* 不具合な修正を行いました。
* いくつかの改良や修正をしました。
* いくつかの不具合を修正しました。
* 操作性の向上とバグの修正
* 安定性とパフォーマンスを改善しました。
* UI改善、軽微なバグの改修を行いました。
* UI改善、不具合の修正を行いました。
* バグの修正や安定性の向上などさまざまな改善を行いました。
* バグを修正してパフォーマンスを改善しました。
* 一部不具合の修正とパフォーマンスの改善を行いました。
* 最新バージョンでは各種不具合が修正され、パフォーマンスも向上しています。
* アプリがクラッシュする問題が修正され、機能の読み込み速度が改善されました。
* このアップデートには、操作性および安定性の改善が含まれます。
* さらに快適にご利用いただくため、機能強化と不具合の修正を行いました。
* ユーザーから報告された問題を修正し、新しい機能を追加して○○機能を改良しました。

「軽微な」って結構いいかもしれない、「バグ」ではなく「不具合」または「改修」の方がいいかな。
最後は「行いました」ですかね。

## 英語
ChatGPTにて「これはアプリケーションのアップデートの文言になります。一般的に使用している英語に翻訳してみてください。」で翻訳してみました。

* Made some fine-tuning adjustments.
* Updated the functionality.
* Made minor corrections.
* Applied minor updates.
* Fixed small bugs.
* Addressed minor bugs.
* Fixed minor bugs.
* Resolved a bug.
* Made a bug fix.
* Made several improvements and fixes.
* Fixed multiple bugs.
* Improved usability and fixed bugs.
* Improved stability and performance.
* Updated the UI and fixed minor bugs.
* Improved the UI and fixed issues.
* Implemented various improvements, including bug fixes and stability enhancements.
* Fixed bugs and improved performance.
* Resolved some bugs and made performance improvements.
* The latest version includes several bug fixes and performance enhancements.
* Fixed an issue causing crashes and improved loading speed.
* This update includes improvements to usability and stability.
* Made feature enhancements and bug fixes for a smoother experience.
* Fixed user-reported issues, added new features, and improved the ○○ feature.

ネットで調べると、Fixed minor bugs よりは語順を変えて、Minor bug fixes and Improvements.(軽微なバグ修正と改善)の方がいいと思いました。
ServerlessでサクッとEC2インスタンスを作成する

# 環境

```
> node -v
v14.17.4

> yarn -v
1.22.17
```

# 環境構築

プロジェクトの作成とTypescriptの追加

```
yarn init -y
yarn add typescript ts-node @types/node
```

tsconfig.jsonを追加

```json
{
  "compilerOptions": {
    "target": "esNext",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist", 
    "esModuleInterop": true,  
    "forceConsistentCasingInFileNames": true,
    "strict": true, 
    "skipLibCheck": true
  },
  "exclude": [
     "dist",
     "node_modules"
  ]
}
```

serverlessフレームワークの導入

```
yarn add serverless @types/serverless serverless-deployment-bucket
```

# GithubにAWSのアクセスキーとシークレットを保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537831/f1ba39a3-9be8-1151-56dd-71037c5dc387.png)


# serverless.tsの作成

```typescript:serverless.ts
import { Serverless } from 'serverless/aws';

export const service: Serverless = {
    service: 'learn-serverless',
    frameworkVersion: '2',
    plugins: [
        'serverless-deployment-bucket'
    ],
    provider: {
        name: 'aws',
        runtime: 'nodejs14.x',
        region: 'ap-northeast-1',
        deploymentBucket: {
            name: 'learn-serverless-preparation',
        },
        timeout: 30,
        memorySize: 1024
    },
    functions: {
    },
    resources: {
        Resources: {
            "EC2Instance": {
                Type: 'AWS::EC2::Instance',
                Properties: {
                    ImageId: 'ami-00f045aed21a55240',
                    InstanceType: 't2.micro',
                    Tags: [
                        {
                            Key: 'Name',
                            Value: 'learn serverless',
                        }
                    ],
                },
            }
        }
    }
}

module.exports = service;
```

# Github actions　ワークフローの作成
```yml:deploy.yml
on:
  push:
    branches:
      - main

name: Serverless Deploy

jobs:
  deploy:
    name: Serverless Deploy
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master

      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node-version: '14.x'

      - name: Install Dependencies
        run: |
          yarn install

      - name: Deploy to aws
        run: yarn serverless deploy
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
```

# EC2インスタンスの確認
無事に作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537831/83690aa8-91d8-8f6e-473f-687fa15c4e5f.png)


# 参考URL

[ローカルに TypeScript の実行環境をサクッと構築する手順](https://t-cr.jp/memo/29b17a4c47f78c28e)
[CloudFormation入門 #1 「EC2インスタンスの作成」](https://qiita.com/nakaken0629/items/82ec60ac552bbe37db29)
[GitHub Actionsを使ってAWS Lambdaへ自動デプロイ (詳説＋デモ手順付きver)](https://qiita.com/homines22/items/412d4e81b24804d75205)
spark wordCount

```scala
import org.apache.spark.rdd.RDD

// 这里的下划线"_"是占位符，代表数据文件的根目录
val rootPath: String = _
val file: String = s"${rootPath}/wikiOfSpark.txt"

// 读取文件内容
val lineRDD: RDD[String] = spark.sparkContext.textFile(file)

// 以行为单位做分词
val wordRDD: RDD[String] = lineRDD.flatMap(line => line.split(" "))
val cleanWordRDD: RDD[String] = wordRDD.filter(word => !word.equals(""))

// 把RDD元素转换为（Key，Value）的形式
val kvRDD: RDD[(String, Int)] = cleanWordRDD.map(word => (word, 1))

// 按照单词做分组计数
val wordCounts: RDD[(String, Int)] = kvRDD.reduceByKey((x, y) => x + y)

// 打印词频最高的5个词汇
wordCounts.map{case (k, v) => (v, k)}.sortByKey(false).take(5)
```

>![wordCount](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/0ad9fcab-d9e8-4143-bb8b-f3bc4497c690.png)

---


```python
from pyspark import SparkContext
sc = SparkContext.getOrCreate()

textFile = sc.textFile("./wikiOfSpark.txt")

wordCount = (
    textFile.flatMap(lambda line: line.split(" "))
    .filter(lambda word: word != "")
    .map(lambda word: (word, 1))
    .reduceByKey(lambda x, y: x + y)
    .sortBy(lambda x: x[1], False)
    .take(5)
)

print(wordCount)
sc.stop()
```

![pyspark](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/a4e9c80b-b353-66c5-e529-926edd6a7dbd.png)
html.cssによく使われる命名規則・ケース

html,cssを記述いていてclass名、id名は何かしら意図や統一性がないと可読性が低くクオリティが低いものになってしまいます。そこでよく使われるものを簡単にまとめてみました。参考になれば幸いです。

ケバブケース
例 box-area
単語と単語の間をハイフンで繋ぐ

スネークケース
例 box_area
単語と単語の間をアンダーバーで繋ぐ

パスカルケース
例 BoxArea
単語の先頭を大文字にする

キャメルケース
例 boxArea
2つ目の単語の先頭を大文字にする

まだまだ他にもありますがhtml.cssでは主にあるのはこの4つかと思います。
体感ではケバブケースとスネークケースが多くそれにキャメルケースが合わせてあるイメージです。
こちらの各ケースに
https://qiita.com/manabuyasuda/items/dbb76ed36970bec95470
こちらのを合わせると意味的にもわかりやすくいいと思います。

参考サイト
https://designsupply-web.com/media/development/4052/
【javascript】ループ分とブロックスコープ

# ブロックスコープ内のconst挙動について

## case1
* const変数は上書きできないが、ブロックスコープ内で上書きできているような挙動になっている。
* 厳密にいうと、上書きではなく1ループごとに内部的異なる変数として評価されている。


```js

for(let i = 0; i < 5; i++){
    const j = i * 2;
    console.log(j)
}

>>> 0
>>> 2
>>> 4
>>> 6
>>> 8
```

## case2

* setTimeoutをしようして1秒後にjを出力する。
* 変数はvarを使用する。
* 8が5回出力された。


```js
for(let i = 0; i < 5; i++){
    var j = i * 2;
    setTimeout(function(){
        console.log(j)
    }, 1000)
}
>>> ⑤8

```

#### なぜか？

* varはブロックスコープをとらない
* setTimeoutで1秒後に出力されている間に、`var j = i * 2;`が5回処理されて、処理の最後、すなわち8が5回出力されることになる。

以下の書き方と同じような結果になる。

```js

var j;

for(let i = 0; i < 5; i++){
    j = i * 2;
    setTimeout(function(){
        console.log(j)
    }, 1000)
}

>>> ⑤8
```
google colab でログ出力無しで進捗を表示する

1.はじめに
　**google colab** でライブラリのインストールなどを行うとき、場合によっては長々とログを出力することがあります。これはスマートでないですが、ログを出力させないと今度は進捗が全く分からない。では、どうすれば良いか。

2.対策
　**tqdm.notebook** と　 **io.capture_output()** を下記のように組み合わせます。処理ブロックがA〜Dの４つだとしたら、各ブロックの終わりに **pbar.update(*)** で進捗率を記載し、合計100になるようにしておけばOKです。
　各ブロックが終わると **pbar.update(*)** で設定した分プログレスバーが増えますので、大体の進捗が１行で分ります。


```python
from IPython.utils import io
import os
import subprocess
import tqdm.notebook

TQDM_BAR_FORMAT = '{l_bar}{bar}| {n_fmt}/{total_fmt} [elapsed: {elapsed} remaining: {remaining}]'

try:
  with tqdm.notebook.tqdm(total=100, bar_format=TQDM_BAR_FORMAT) as pbar:
    with io.capture_output() as captured:
      # -------
      #    A
      # -------
      pbar.update(8)

      # -------
      #    B
      # -------
      pbar.update(10)

      # -------
      #    C
      # -------
      pbar.update(2)

      # -------
      #    D
      # -------
      pbar.update(80)
except subprocess.CalledProcessError:
  print(captured)
  raise
```
![コンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/ef885fd4-532e-4007-108b-cda2359c9cf7.png)
Heorkuで2FA用デバイスを紛失した際の対応方法

#背景
1.2FA用デバイスを初期化してしまった
2.リカバリーコードもありません:fearful:


#解決方法
 support@heroku.comにメールを送信する
[参考URL](https://help.heroku.com/7IDU8QZZ/what-should-i-do-if-i-m-locked-out-of-my-heroku-account)
#実際に送信してみた
###まずは2FAデバイスにアクセスできなくなったことを伝えます
```
メール本文
I have lost access to the MFA device and recovery code
Please reset the MFA device.
```
#####あなたのデプロイしたアプリの情報・Githubの情報を教えてねと返信がきました

```
Hi,

We can provide a temporary Recovery Code for you to log in with. However, account security is not something we take lightly. As such, we would need you to verify as much of the following information before pursuing this request further.

Names of 2 apps deployed on Heroku

The git SHA of the most recent commits deployed to 2 separate apps, including the date of the deployment

If your account is connected to GitHub, please provide:

the name of the GitHub account
the app or pipeline name of a connected GitHub repository
the repository name
```
#####わかる範囲でいいので以下の質問に対して回答します。
- デプロイしたアプリ名を教えて！
- デプロイしたアプリのハッシュ値を教えて！
- Githubのアカウント名を教えて！
- リポジトリ名を教えて！

#####以上で無事に2FA用デバイスをリセットすることができました！！！
PandasでJSON形式の列データを複数列に展開


#レコードの中がJSONフォーマットから要素を抽出したい#
データの中の列データがJSON 文字列だったのでその前処理をするため下の記事を参考にやってみました

https://www.soudegesu.com/post/python/flatten-json-column-with-pandas/

#やりたいこと#
| id | label | 
|:-----------|------------:|
| 123      | {'a':1,'b':2}    | 
| 456    | {'a':6,'b':10}| 
| 789 | {'a':4,'b':5} |
元データがこんな感じだったので

| id | label | a |b |
|:-----------|------------:|:------------:|:-----------|
| 123     | {'a':1,'b':2}  | 1    | 2| 
| 456     | {'a':6,'b':10}| 6      |10 | 
| 789        | {'a':4,'b':5} | 4  |5 |
にしたい

#実装#
とりあえず試してみる

```
import pandas as pd

data = {
    'json_col': ['{"a": 1, "b": 2}', '{"a": 6, "b": 10}','{"a": 4, "b": 5}']
}

df = pd.DataFrame(data)
df.head()
```

上記の記事を参考に
 
```
from pandas.io.json import json_normalize
import json 

df_json = json_normalize(df['json_col'].apply(lambda x: json.loads(x)))
df_json.head()
```
うまくいったので自分のデータ(CSVファイル)でやってみると
``AttributeError: 'list' object has no attribute 'items'``
とエラーが出ました。

#エラーの原因#
いろいろ調べて下記の記事を見つけました。
どうやらlist型やdict型を含むレコードがあるCSVは読み込んだ時にstr型になってしまう仕様らしい。。。
 
https://upura.hatenablog.com/entry/2019/09/03/191234

```
import ast

df['hoge2'] = [ast.literal_eval(d) for d in df['hoge']]
```
こいつを使ってstr型をlist型/dict型にして要素ごとに抽出しました。