OmniAICreator/Qiita-1.07M huggingface dataset:
【バグ紹介】vscode C++のブレークポイント設定について

# 環境  
- WSL2(Ubuntu)
- vscode + C++(cppgdb)  

# 目的  
ブレークポイント設定時のバグについて紹介する。  
# 結論  
if文のところで条件付きブレークポイントを設定すると、コード実行が進まなくなるので注意。  

# Add Conditional Breakpoint  
vscodeのデバッガ機能では、ソースコード内にブレークポイントを設定することができ、コード実行を自分の好きな場所で止めることができます。さらにブレークポイントに条件を付与することで、その条件が真となったときに、実行を停止させることが可能です。以下に例を示します。  
### ソースコード  

```cpp
#include <bits/stdc++.h>
#include <bitset>
#include <fstream>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int INF = 2147483647;
// 9,223,372,036,854,775,807
const ll INFL = 9223372036854775807;


int main(){
    for(int i=0;i<3*pow(10,7);i++){
        if(i==10000000){
            cout << i << endl;
            cout << "hello" << endl;
        }
        if(i == 2*pow(10,7)){
            cout << i << endl;
        }
    }
}
```  
### デバッグ設定時  
図１
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898251/e5639651-fbbb-ff45-26b6-581bba227b2d.png)  
### デバッグ実行時  
図2  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898251/125ad2af-4d62-9b7d-c4a4-dacca0e65a2a.png)
 
図2のvariables explorerを見ると、i=10000000の時に実行が停止していることが確認できます。  

### やってはいけないブレークポイントの設定  
以下のようにブレークポイントを設定するとデバッガーが正常に動作しません。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898251/f6091add-de46-df9c-5b0d-4b3a6fb3f023.png)

# 所感  
if文のところにブレークポイントはおかないこと。  

ありがとうございました。
【Rails】ルーティングの個人的よく使う小技集

# はじめに
ルーティングが無いとアプリケーションは動かないですよね。それくらい重要な要素ですが、意外と知られていない機能があるのです。それを使いこなすことで、より便利で分かりやすいルーティングを定義できると思うので、小技を習得していってください！

# 小技集

## リソースフルなルーティングを一括定義する
`resources :テーブル名`のような定義方法をすることで、リソースフルなルーティングを一括定義することが可能です。

```ruby
resources :users
```

※定義されたルーティングは以下の通りです。

| HTTP動詞 | パス | コントローラ#アクション |
|:-:|:-:|:-:|
| GET  | /users  | users#index  |
| GET  | /users/new  | users#new  |
| POST  | /users  | users#create  |
| GET  | /users/:id  | users#show  |
| GET  | /users/:id/edit  | users#edit  |
| PATCH  | /users/:id  | users#update  |
| DELETE  | /users/:id  | users#destroy  |

## 単数形リソースの定義
idを必要としない(1つしかない)リソースには単数形リソースで定義することができます。
※単数形リソースは複数形のコントローラに割り当てられます。

```ruby
resource :user
```

## 名前空間を利用して用途を明確化する
コントローラを名前空間によってグループ化することもできます。

```ruby
namespace :admin do
  resources :users
end
```

※定義されたルーティングは以下の通りです。

| HTTP動詞 | パス | コントローラ#アクション |
|:-:|:-:|:-:|
| GET  | /admin/users  | admin/users#index  |
| GET  | /admin/users/new  | admin/users#new  |
| POST  | /admin/users  | admin/users#create  |
| GET  | /admin/users/:id  | admin/users#show  |
| GET  | /admin/users/:id/edit  | admin/users#edit  |
| PATCH  | /admin/users/:id  | admin/users#update  |
| DELETE  | /admin/users/:id  | admin/users#destroy  |

## ルーティングの「concern」機能
concernを使うことで、他のリソースやルーティング内で使いまわせる共通のルーティングを宣言できます。
※concernはルーティング内のどの場所にでも配置できます。

```ruby
# concernの定義
concern :commentable do
  resources :comments
end

# 下記ルーティングと同義
resources :messages, concerns: :commentable

# 上記ルーティングと同義
resources :messages do
  resources :comments
end
```

## 名前付きルーティングを使用する
`:as`オプションを使うと、どんなルーティングにも名前を指定できます。
`指定した名前_path`で、名前付きヘルパーメソッドを呼び出せます。

```ruby
get 'exit', to: 'sessions#destroy', as: :logout
```

## URLフォーマットを特定の形式に制限する
`:constraints`オプションを使って、動的セグメントのURLフォーマットを特定の形式に制限できます。

```ruby
# 「/photos/A12345」にマッチするもののみ許可
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
```

## ルーティンググロブ(ワイルドカードセ)を使う
`*`を用いることでワイルドカードを利用できます。

```ruby
get 'photos/*other', to: 'photos#unknown'
```

## コントローラを指定する
`:controller`オプションは、リソースで使うコントローラを明示的に指定します。

```ruby
resources :users, controller: 'staffs'
```

※定義されたルーティングは以下の通りです。

| HTTP動詞 | パス | コントローラ#アクション |
|:-:|:-:|:-:|
| GET  | /users  | staffs#index  |
| GET  | /users/new  | staffs#new  |
| POST  | /users  | staffs#create  |
| GET  | /users/:id  | staffs#show  |
| GET  | /users/:id/edit  | staffs#edit  |
| PATCH  | /users/:id  | staffs#update  |
| DELETE  | /users/:id  | staffs#destroy  |

# 終わりに
現場でもよく使われるルーティングの技術だと思うので、「知らなかった。。」と恥をかかないように、今のうちに知っておきましょう！

# 参考
[Rails のルーティング]
(https://railsguides.jp/)
【論文紹介】塩分を用いない塩味味覚感度制御ー陰極刺激の提示と停止による飲食物の味覚変化における評価

#論文紹介
論文：塩分を用いない塩味味覚感度制御ー陰極刺激の提示と停止による飲食物の味覚変化における評価 Controlling Saltiness without Salt: Evaluation of Taste Change by Applying and Releasing Cathodal Current 
著者：中村 祐美, 宮下 芳明
https://research.miyashita.com/papers/I9/paper.pdf
https://research.miyashita.com/papers/J13/paper.pdf


#どんなもの
　塩味の味覚感度を制御することによって”塩分”ではなく”塩味”与えることで塩分の抑制をするシステムの開発。実験の結果、塩味味覚感覚制御において、塩味が提示前と提示中よりも停止後に濃感じられること、金属味、酸味は提示前と提示中よりも停止後に味を濃く感じられることがわかった。

#先行研究と比較してすごいところ
　これまでの研究は、他の調味料を追加して調理で加工を施していたが、この論文では塩味を減らさずに塩分を抑えるシステムを開発した。


#技術や手法のキモ
　陰極刺激提示装置と飲食行動検知機構を使って、被験者の舌に陰極刺激の提示と停止を行う。(これによって刺激停止後に塩味が強まった感覚を得られる)
　<font color="gray">Hettingerの実験で刺激提示中は塩味は阻害され、停止後には塩味を強く感じさせられるとわかっている。
→飲食直後に陰極刺激を提示、飲食中に陰極刺激を停止する</font>

#検証方法
　魚肉ソーセージを使って、陰極刺激を提示する前(普通の状態)、陰極刺激提示中、陰極刺激提示提示後のそれぞれで味を評価した。基本味(塩味、酸味、苦味、甘味、旨味)と金属味として、0~10までの均等目盛り(0:全く感じない, 10:強く感じる)で評価させた。
　
#議論
　味覚の個人差、食生活に合わせて調整は可能なのか。

#気になった論文
　食べテルミン(中森さん)：フォーク型のデバイスを用いた飲食による音響生成、制御システム
　拡張現実感を利用した食品の見た目の操作による満腹感のコントロール：飲食した利用者の満腹感に影響を与えるシステム(鳴海先生)
【shell基礎】loop;if文;連続した数字;標準入力を変数に代入

#連続した数字

```bash
echo {1..100}

1 2 3 4 5 6 7 8 .... 100
```


# for loop

```bash
for i in 1 hello *
do
echo $i
done

#一行で書いた場合
for i in {1..99}; do echo $i; done 
```

#if 

```bash

if [ 条件式 ];
#true
then
  echo hello　
#false
else
  echo world
fi

```




##1~99の奇数を出力

```bash
for i in {1..99};
do
if [ $(($i % 2)) = 1 ]; then
echo $i
fi
done

1
3
5
...
99
```

##標準入力を変数に代入

```bash

#!/usr/bin/sh

read name
echo "Welcome $name"
```
```
input
Dan
output
Welcome Dan
```
最初書いていたname=\`cat\`よりも
read name
のほうがよさそう。
catはctr＋ｄを押さない限り入力を待ち続けるから


##x,yに標準入力を代入、四則演算の結果を出力

```bash
read x; read y  #x=5, y=2
for i in {+,-,\*,\/}
do
echo $((x $i y))
done

7
2
10
2 #(小数点以下は表示されない)
```
DeployGate で配信後、Google認証しようとすると「ApiException:10」になる時の対処法

DeployGate で配信後、Google認証しようとすると「ApiException:10」になる時の対処法

#参考
[Google認証で ApiException:10 が発生 - Qiita](https://qiita.com/kurei_brz86/items/34041a804de3a1bb8388)

#やったこと
release側のフィンガープリントが足らないため出たエラーでした。
リリースビルドを実行しました。

releaseバリアントに変更
![WS001163.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/2ee9851a-1c62-ff28-e662-0c43ef0c34ff.jpeg)

![WS001164.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/ce08f8e0-43bf-98fe-0491-6f704ad138ce.jpeg)



```build.gradle
android{
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}
```

[署名付きrelease.apkの作成](http://hihi.sakura.ne.jp/android/signedapk.html)
こちらを参考にrelease.apkを作成しました。
![WS001165.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/ea8f6c43-9539-d61c-839f-800eac80f349.jpeg)

![WS001167.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/2cd60cce-0080-6f68-f6ee-de564301e0ee.jpeg)

![WS001168.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/45731a4c-2ac8-239b-85a5-f943bd3b5cc0.jpeg)

![WS001169.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/dbe7bd56-29cb-6c28-3e54-017c76d542ba.jpeg)

最後に下記を参考にフィンガープリントを取得しました。
[How to get the SHA-1 fingerprint certificate in Android Studio ...](https://stackoverflow.com/questions/27609442/how-to-get-the-sha-1-fingerprint-certificate-in-android-studio-for-debug-mode)
Chrome拡張機能のYouTube自動翻訳読み上げ機能がステキすぎる

初投稿です。今まで見る専門でしたが、アウトプットのために投稿もしていこうと思います。

---
機械学習やpythonのリファレンスなどを探しているとき、日本語の情報が見当たらず、英語リファレンスを読むことが多くなってきました。
PCの前に座っているときはChromeのGoogle翻訳機能を使って、英語の意味が理解しづらい部分を ドラッグ > 右クリック > Google翻訳 で翻訳しながらで切り限りリファレンスの内容を理解できる様に努めていましたが、PCの前に座っていない時でも耳から情報を入れたいという欲が出てきて、ここ最近自動翻訳の読み上げ機能がないか調査していました。

本日、以下のChrome拡張機能を見つけ、思わずガッツポーズをしてしまいましたので皆様にも共有いたします。
まだ不安定な部分がある様ですが、活用できると思います。
# 紹介するChrome拡張機能
[字幕プレーヤー - ビデオYouTubeの翻訳](https://chrome.google.com/webstore/detail/subtitles-player-translat/heiglcoakfdagibicjljgcaggfejijga)
既に2万人以上のユーザーに使われています。（[ポーランドの企業](https://int.harpo.com.pl/)が提供している様です）

# 使用方法
通常のChrome拡張機能と同様です。

#### ①上記「字幕プレーヤー - ビデオYouTubeの翻訳」のリンクページへ飛んで「Chromeに追加」をクリック。
![スクリーンショット 2021-06-06 12.52.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/1d17b8e5-86fd-ac67-d353-3954e1fd8935.png)
---
#### ②アクセス許可を求めるアラートが表示されるので「拡張機能を追加」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/97666cfc-dc0c-8d7f-0b91-5469c0c7e103.png" width="500px">
---
#### ③追加した拡張機能のアイコンをクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/f70db0e9-25c3-70ad-0fd5-c6de2af6737e.png" width="300px">
---
#### ④ボイスのプルダウンをクリックし「」を選択（ご利用の環境によって表示が異なる可能性があります）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/0cd1f856-c304-f931-78e5-35fcaac8299f.png" width="300px">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/a068fdf2-65cf-34dd-9226-54b20cabfd60.png" width="300px">
---
#### ⑤[YouTube](https://www.youtube.com/)にアクセス。翻訳したいコンテンツを再生する。
※「字幕」が設定されているコンテンツじゃないと自動翻訳読み上げされない様です。（⚙マークをクリックして「字幕」が表示されるコンテンツ）
うまく再生されないときはChromeが最新バージョンになっているか？などを確認してみてください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711755/e3a3ec44-fbee-897c-76e9-9767e8ecb3ab.png" width="300px">

---
私が使ってみた感想ですが、通常の再生スピードだと、読み上げが追いつかず、後から猛スピードで読み上げすることがありました。再生スピードを0.5にすると、いい感じで読み上げてくれました。

以上、Chrome拡張機能「YouTube自動翻訳読み上げ」の紹介でした。

余談ですが、私は車での移動中など、耳が空いているときは、音楽ではなく、ニュースや自分が興味のある開発情報のWebページを「色々なスマホアプリ」の読み上げ機能を使って聴いています。
以下、使っているスマホアプリです。
 
①[Voicy](https://voicy.jp/)
　言わずと知れた音声プラットフォームです。毎朝お世話になっています。
 
②[Googleアプリ](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox&hl=ja&gl=US) & [Goole翻訳]()（GoogleChromeアプリとは[異なります](https://enjoy.sso.biglobe.ne.jp/archives/difference_gc/)）
 　Googleアプリで、翻訳 & 読み上げたいWebページを開いて、画面上部に表示される「日本語」をクリックするとテキストが日本語に翻訳されて、画面下部の再生ボタンを押すことで日本語以外のWebページのテキストを日本語で読み上げることが可能です。
　私の使っている環境だとAndroidはうまく機能します。残念ながらiosのGoogleアプリだと表示上の日本語翻訳まではできますが読み上げ機能は翻訳前のテキストを読み上げてしまいます。

以上、皆様の情報収集の参考になれば幸いです。
OS初学者の学習記録 〜2. プロセス(その1)〜

# プロセスとは？
実行されるプラグラムの単位。

例

* Webブラウザ
* 電子メールリーダー
* Excel
* テキストエディタ

### 並列処理と並行処理
* OSは、複数のプロセスの生成・実行・消滅を管理し、プロセスの「並行処理」を実現する。(マルチプログラミング、マルチタスク)
* 複数のプロセスを、複数のプロセッサで実際に同時に実行することを「並列処理」という。(ややこしい、、)

### プリエンプション

プロセスは、入出力をもつものが多いので、入出力まち状態のときにプロセスを切り替えることで、上記の「並列処理」を実現できる。

しかしこれでは、入出力がないプロセスでは、そのプロセスが終わるまで他のプロセスにプロセッサを割り当てられない、、
↓
プロセスの「割り込み」によって解決。このOSの仕組みを「プリエンプション」という。
逆に、プロセス自身が明示的に「もういいよ、次の人(プロセス)に変わってあげる」とOSに制御を渡す仕組みのことを「ノンプリエンプティブ」という。


# プロセスの構造
OSではプロセスをどのような構造で扱っているのか？？

1. プログラムを、コンパイラでプロセッサが理解できる機械語に変換
1. 機械語に変換されたプログラム(オブジェクトプログラム)をもとにプロセスを生成

### プロセスのメモリ構造

##### ・コード領域 (静的)
オブジェクトプログラムに相当。

##### ・データ領域(静的)
プログラムを実行する際にはじめから存在し、プログラム全体で利用されるデータを入れる領域。

プログラム全体で利用されるデータを入れる領域には、

* 初期化変数領域
* 未初期化変数領域
がある。


##### ・ヒープ領域(動的)
プログラム実行中に、明示的に確保されるメモリ領域。
メモリ領域は、プログラムの実行状況によって動的に割り当てられる。


##### ・スタック領域(動的)
関数の引数、ローカル変数、関数の戻り先の番地などが格納される。


##### ヒープ領域とスタック領域の使い方
ヒープ領域やスタック領域には上限はあるが、それぞれどの大きさが使用されるかわからない。
そこで、この2つの成長方向を逆にして、start位置を領域の両端におくことで、最大限効率的に使えるようにする。(ヒープ小さくてスタックめっちゃでかいときや、その逆で活躍する)


# プロセス記述子(プロセス制御ブロック)

プロセス識別子、優先度等のスケジューリング情報、資源利用情報などが格納されている。
また、「プロセッサ」の状態も格納されている。

### プロセッサの状態

##### ・プログラムカウンタ
次に実行する機械語命令のアドレス

##### ・スタックレジスタ
スタックの現在のアドレス(後入れ先出しなので、新しいのが入るたびに、その値に更新)

##### ・フラグレジスタ
演算結果の状態を保持



# プロセスの状態

### 状態の種類
以下の3つの状態のいずれかを取る

##### ・実行可能状態
他のプロセスがプロセッサを使用しているために、一時的に中断している状態

##### ・実行中状態
プロセッサ使用中の状態

##### ・まち状態
外部事象の発生まちのために実行できない状態


### 実行するプロセスの切り替え

実行中のプロセスを実行中の状態から実行可能状態にうつし、他のプロセスを実行中状態にすることを「ディスパッチ」という。ディスパッチにより処理を切り替えることを「コンテキスト切り替え」という。
また、実行中のプロセスを強制的に実行可能状態に戻すことを「プリエンプション」という。(前でも出てたね)



# スケジューリング
実行するプロセスを決めるプログラムを「スケジューラー」という。


### スケジューリングアルゴリズムが満たすべき要件

##### ・公平性
各プロセスになるべく公平にプロセッサを割り当てる

##### ・プロセッサの利用率
CPUの動作時間をなるべく長くする
(切り替えやりすぎると落ちる)

##### ・スループット
単位時間あたりに完了するプロセス数をなるべく大きくする

##### ・ターンアラウンド時間
プロセス実行欲求から完了するまでの時間をなるべく短くする



### アルゴリズムの例 (準備中)

##### ・到着順


##### ・処理時間順


##### ・残余処理時間順


##### ・ラウンドロビン


##### ・優先度順


##### ・多重フィードバック



# スレッド

1つのプロセスの中に複数個存在する、並行処理の単位。
「ユーザーレベルスレッド(ユーザー空間で実現されるため、OSの介入はない)」と
「カーネルレベルスレッド(プロセスと同様、OSによってスケジュールングされる)」に分けられる。
Visual Studio Codeでremote SSHできない

こちらを参考に、VSCodeでremote SSH接続しようとしたところ、ハマったのでメモ。
https://qiita.com/nlog2n2/items/1d1358f6913249f3e186
.ssh/configの設定を最小限にしたところできた。

#.ssh/configに設定を追記
/Users/ユーザ名/.ssh/config に以下のように追記した。

```
Host remote(適当に名前を付ける)
  HostName <接続先のPCのipAddress>
  User <接続先のPCのユーザ名>
  Port 2222
  UserKnownHostsFile /dev/null
  PreferredAuthentications publickey
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/ユーザ名/.ssh/<ファイル名>
  IdentitiesOnly yes
  LogLevel FATAL

```

#接続をしようとしたところ、エラー

```
プロセスが、存在しないパイプに書き込もうとしました。
（省略）
```

#.ssh/configの設定を最小限に修正

```
Host remote(適当に名前を付ける)
  HostName <接続先のPCのipAddress>
  User <接続先のPCのユーザ名>
　IdentityFile /Users/ユーザ名/.ssh/<ファイル名>
```
再度接続し直したところ、無事接続できた。
pythonのバージョンを変更する方法（古くする、ダウングレード）

# 初めに
　タイトル詐欺的な感じになっちゃうと思いますが、申し訳ありません。この記事では、"異なったversionのPythonを新たに入れる"解説をします。変更とは違いますが、おそらくここに来た人は、何らかの原因で古いバージョンのPythonの環境が必要になった人だと思います。その目的は達成できる記事だと思います。それと、Anacondaとかcondaとか使わずに書きます。未来の自分のためにも書いておきます(^^)/

# 誰向けの記事？
　この記事は、

・pythonのバージョンを変えたい人（特に、古くしたい人必見）
・anacondaとか使わずに、好きなバージョンを入れたい

人向けです。Anacondaとかだと、ポチポチするだけで、2.7系とか入れられますが、入れられるバージョンが限られています。ここで紹介する方法は、python公式から入れる方法なので、公開されているバージョンであれば、すべて入れることが可能です。

# step1 好きなバージョンのinstallerをダウンロードする
　以下のサイトから、好きなバージョンのページまで行きましょう。今回は、最古の2.2.0をダウンロードしてみます。（2.0.1はなんかダメでした）
・pythonの公式サイト（installer）：https://www.python.org/downloads/
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/52f380a7-db6f-8a76-712d-3289a0a03ec5.png">
</div>
　そして、下のほうにあるinstallerをクリックして、ダウンロードしましょう。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/4964005c-b0e0-d8cd-e6ae-dcfef00f259a.png">
</div>
# step2 インストールする
　インストーラがダウンロード出来たら、実行しましょう。実質最古のver2.2、インストール画面はこんな感じです。歴史を感じますね。保存先は自分で選ぶらしいので、事前に作っておきましょう。私はPython3がある場所にフォルダ作りました。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/b41b22f6-6768-1bb0-911c-a79a3763082a.png">
</div>
そして進めると、インストールが始まり、インストールは終了です。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/a30172d9-1918-90f2-4c1c-7a3442525270.png">
</div>

# step3 実行ファイル名を変え、パスを通す
　pythonがインストールされてないPCなら問題ないですが、さっき入れた`python.exe`実行ファイル名を変えないと、参照できない可能性が高いです（ほかのバージョンと被ってるのが原因？）。
　という事で、さっきインストールしたPython2.2.0の`python.exe`ファイル名を、`python22.exe`に変更します。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/94c18683-b337-6697-da75-c3e0065499c9.png">
</div>
そして、環境変数からパスを通すと、、、このように！python2.2.0が実行できる環境が整いました！
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/f2a786a5-9c4a-4e7d-b6d2-4d4f8bd7ad8a.png">
</div>

# 終わりに
　もちろん、他のバージョンでもできました（試したのはver2.7.18）。以前、pythonのバージョン切り替え（ダウングレード）する際、Anacondaを想定した記事が多い印象でした。確かにAnacondaは簡単ですが、重いですし、余計にアプリが増えるのは嫌なイメージがありました。
　なので、今回の方法を記事にまとめました。この方法なら、コマンド`conda`を使わなくていいですし、好きなバージョンを入れることができます。私からしたら、すっきりした方法です。
　それじゃ！
LaTeX の数式内で複数の行列を改行して書く


# LaTeX の数式内で複数の行列を改行して書きたい

Latex の数式内で数式を改行する場合のコマンドは, 
ご存じの方が多いだろう. 
そこで, 本記事では, 数式内で複数の行列を縦に並べるコマンドを記します. 
使用する package は, "\usepackage{amsmath,amssymb}"です.

## "equation"での数式改行
"equation"内で"split"を使用する. 
まず, 下図がソースコード例.
![split.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/ec1a4158-c702-6eb9-9a31-b28eafbb5542.png)
これを, コンパイルすると下図. 
![split_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/b4601270-bdf8-c505-30c9-b12a8a760912.png)


## "equation"での行列表示
"equation"内で"array"を使用する.
まず, 下図がソースコード例.
![array.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/f2de670b-3df3-5123-0c8f-aad06e8efcb5.png)
これを, コンパイルすると下図. 
![array_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/4ef834e9-e8f2-94f9-d7ba-a359920511c2.png)

## "equation"における複数の行列の表示
"equation"内で"split"と"array"を組み合わせる. 
まず, 下図がソースコード例.
![split_array.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/4d78ba25-26a3-3eb2-241c-06759b01e2a7.png)
これを, コンパイルすると下図. 
![split_array_imag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584806/56418c33-a58d-599b-53c5-4ee85f637858.png)
ちなみに, "equation"の直後に"*"をつけると, 数式番号の参照が表示されないです. 

## 粗末なまとめ
- "equation"内の改行は"split"
- "equation"内の行列表示は"array" 
-  "equation"内の行列の改行は"split+array"

まあ, "equation"を使用した数式はあまりよろしくない説がありますが, 
そこはよしなに取り計らってください. 

cf) 数式例で使用したものは, 連立 Riccati 微分方程式の終端条件です. 

以上, potato-san でした.
Node.js: ndjson の使い方

こちらにあるデータをサンプルとして使います。
[新型コロナワクチンの接種状況（高齢者等）](https://cio.go.jp/c19vaccine_dashboard)
「都道府県別接種回数詳細」 です。

prefecture.ndjson　をダウンロードします。
これを、栃木県の　2021-06-05 だけのものにします。

```bash
awk '/"prefecture":"09"/{print $0}' prefecture.ndjson > tochigi.ndjson
awk '/"date":"2021-06-05"/{print $0}' tochigi.ndjson > tochigi_jun05.ndjson
```

```text:tochigi_jun05.ndjson
{"date":"2021-06-05","prefecture":"09","gender":"F","age":"-64","medical_worker":false,"status":1,"count":28}
{"date":"2021-06-05","prefecture":"09","gender":"F","age":"-64","medical_worker":false,"status":2,"count":2}
{"date":"2021-06-05","prefecture":"09","gender":"F","age":"65-","medical_worker":false,"status":1,"count":1380}
{"date":"2021-06-05","prefecture":"09","gender":"F","age":"65-","medical_worker":false,"status":2,"count":245}
{"date":"2021-06-05","prefecture":"09","gender":"M","age":"-64","medical_worker":false,"status":1,"count":28}
{"date":"2021-06-05","prefecture":"09","gender":"M","age":"-64","medical_worker":false,"status":2,"count":4}
{"date":"2021-06-05","prefecture":"09","gender":"M","age":"65-","medical_worker":false,"status":1,"count":1031}
{"date":"2021-06-05","prefecture":"09","gender":"M","age":"65-","medical_worker":false,"status":2,"count":192}
{"date":"2021-06-05","prefecture":"09","gender":"U","age":"UNK","medical_worker":false,"status":1,"count":1}
```

必要なライブラリーのインストール

```bash
sudo npm install -g ndjson
```

```js:ex01.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	ex01.js
//
//						Jun/06/2021
// ---------------------------------------------------------------
'use strict'

const ndjson = require('ndjson')
var fs = require("fs")

const file_in = 'tochigi_jun05.ndjson'

fs.createReadStream(file_in)
  .pipe(ndjson.parse())
  .on('data', function(obj) {
    // obj is a javascript object
	console.log(obj)
  })

// ---------------------------------------------------------------
```

実行

```bash
export NODE_PATH=/usr/lib/node_modules
./ex01.js
```
Caused by: java.lang.VerifyError: Verifier rejected class com.sun.mail.handlers.handler_base: java.awt.datatransfer.DataFlavor[] com.sun.mail.handlers.handler_base.getTransferDataFlavors() failed to verify: java.awt.datatransfer.DataFlavor[]が出た時の対処法

#AndroidMail(SunMail)を使うときに以下のエラーが出た時の対処法
Caused by: java.lang.VerifyError: Verifier rejected class com.sun.mail.handlers.handler_base: java.awt.datatransfer.DataFlavor[] com.sun.mail.handlers.handler_base.getTransferDataFlavors() failed to verify: java.awt.datatransfer.DataFlavor[] com.sun.mail.handlers.handler_base.getTransferDataFlavors(): [0x4]  can't resolve returned type 'Unresolved Reference: java.awt.datatransfer.DataFlavor[]' or 'Reference: javax.activation.ActivationDataFlavor[]' (declaration of 'com.sun.mail.handlers.handler_base' appears in /data/app/xxx


#参考
[Android Studio VerifyError rejecting class text_plain from ...](https://stackoverflow.com/questions/64650611/android-studio-verifyerror-rejecting-class-text-plain-from-javamail-api)


#結果
TargetSdkVersionを29にするとエラーは出なくなりました。

```build.gradle
android {
    compileSdkVersion 29
    defaultConfig {
        
        targetSdkVersion 29
    }
}
```
Windows -> Linux へssh接続で公開鍵認証を実装

2021.06.05
Windows から Linux へssh接続時に公開鍵認証を実装できたので備忘録として。

TeraTermもしくはPowerShellを使うのが一般的らしいが、ひねくれているのですべてコマンドプロンプトで実行してみた。

【参考】
■Windows10で公開鍵認証の鍵ペアを生成してサーバーにSSH接続する
https://onoredekaiketsu.com/generate-key-pair-for-public-key-authentication-in-windows10-and-connect-to-server-with-ssh/

■manページ  — SSHD_CONFIG
https://nxmnpg.lemoda.net/ja/5/sshd_config

■SCPコマンドでローカルのファイルをサーバにアップ＆サーバ上のファイルをDL
https://qiita.com/ritukiii/items/c724f09fe66fedf2618b

■openssh-serverが入っているのにsshでログインできない
https://killingout-n-bita.hateblo.jp/entry/2018/07/08/162520

# 1.Windows 側で公開鍵・秘密鍵を作成。

まずは鍵を入れておくためのフォルダを作成する。
コマンドプロンプトを起動し、以下のコマンドを実行。
（ついでにcdコマンドでカレントディレクトリを作成したフォルダにしておく）

```
C:¥Users¥hemuwan> mkdir .ssh
C:¥Users¥hemuwan> cd .ssh
C:¥Users¥hemuwan> .ssh
C:¥Users¥hemuwan¥.ssh> 
```

次に公開鍵と秘密鍵のペアを作成する。

```
C:¥Users¥hemuwan¥.ssh> ssh-keygen
```

`ssh-keygen`コマンドを実行すると、パスフレーズの入力を求められる。
任意のパスフレーズを2回入力。（忘れたらまた作り直しになるよ）

`-t`オプションで鍵の方式を指定できるけど、今回はお試しでデフォルトのRSAを使ってみる。

パスフレーズを入力したら、`dir`コマンドなどで`C:\Users\hemuwan\.ssh` 配下に

- id_rsa
- id_rsa.pub　

が生成されたことを確認する。
「id_rsa」が秘密鍵、「id_rsa.pub」が公開鍵となる。

ユーザー認証で公開鍵認証を用いるために、「公開鍵」の方をSSHサーバーとなるLinuxへ送り付ける。

「秘密鍵」はログイン時に使う。

# 2.Linux側のユーザに「公開鍵」を送付
`.ssh`フォルダで、以下コマンドを実行。

```
C:¥Users¥hemuwan¥.ssh> scp -P <ポート番号> id_rsa.pub <ユーザ名>@<IPアドレス>:ClientPubKey
```

`scp`コマンドを使い、「id_rsa」を<ユーザ名>のホームディレクトリに「ClientPubkey」と名前をつけて送付している。
（最近ではプロトコルが古くなり、scpコマンドの使用は推奨されていないらしい。OpenSSH開発プロジェクトではsftpやrsyncの利用が増えているとか）

# 3.Linux 側で、もらった公開鍵を.sshに配置
もらった公開鍵を.ssh 配下に、authorized_keys という名前で配置する。
（これの名前間違えててハマった。必ずauthorized_keysにするかconfig変えるかをする）

以下のコマンドはホームディレクトリに移動した後、`cat`コマンドで表示するものを`>>`でリダイレクトし、`.ssh/`配下に`authorized_keys`という名前のファイルにして保存するというコマンド。

```
$ cd ~
$ cat ClientPubKey >> ./.ssh/authorized_keys
```


# 4./etc/ssh/sshd_config を編集。
最終的にこうした、というのだけ書く。

```
Port <任意のポート番号>
```
	
デフォルトは22。セキュリティ的にデフォルトの番号から変えた方がよいとのこと。
（今回の公開鍵認証の実装に関しては変えても変えなくてもどっちでも）

```
HostKey /etc/ssh/ssh_host_rsa_key
```

これないとホスト認証ができない。
ないときは`sudo dpkg-reconfigure openssh-server`とかすると、再作成してくれるはず。
（参考：https://killingout-n-bita.hateblo.jp/entry/2018/07/08/162520 より）

```
PubkeyAuthentication yes
```

公開鍵認証を許可するかどうか。デフォはno。

```
AuthorizedKeysFile	.ssh/authorized_keys .ssh/authorized_keys2
```

ユーザ認証のさいに使われる公開鍵を格納しているファイル名を指定。
（設定はそのまま。コメントアウトの＃消しただけ）

```
PasswordAuthentication no
```

パスワード認証を許可するか。デフォはyes
（なぜかnoにしても公開鍵認証の設定終わるまでパスで入れていた。どうして、、)

```
PermitEmptyPasswords no
```

パスワード認証が許可されているとき、パス文字が空のアカウントに対し、　サーバがログインを許可するかどうかを指定。デフォはno。

```
PermitRootLogin no
```

ssh を使って、rootがログインできるかどうかを指定。デフォはno。

```
AllowUsers <任意のユーザ名>
```

ssh接続を許可するユーザ。
デフォルトでは書かれていないので必要に応じて末尾に書く。

```
Protocol 2
```

サポートするプロトコルのバージョンを指定。引数は１，２のみ。
デフォルトでは書かれていないので必要に応じて末尾に書く。

以上の設定が終わったら、読みこみなおす。

```
$ sudo systemctl restart sshd
```

# 5.Windows側から接続を試みる。

コマンドプロンプトから以下のコマンド実行。

```
ssh <IPアドレス> -l <ユーザ名> -p <ポート番号> -i C:¥Users¥henuwan¥.ssh¥id_rsa
```

ログイン時、鍵を作った時のパスフレーズ求められる。
（テラタームでも成功した。）

二回目以降は、`-i` オプション以降なくてもパスフレーズを求められ、入力するとログインできた。

# おわりに

ようやく公開鍵認証を実装できた。
（なんやかんや行き詰ったりして1日つぶれた）
今の状態だと、パスワード同様にパスフレーズを忘れてしまうと、
ログインできなくなる。ssh-agent などを使って、自動ログインできるようにしたいところ。
主要RDB の JDBCドライバは Maven Repository からダウンロード可能

> * Java, JDBC, Maven 関連記事です。
> * ちょっとした小ネタです。

主要RDB の JDBCドライバの多くは [Maven Repository](https://mvnrepository.com/) からダウンロードすることができるようになっています。
つまり JDBC ドライバは `pom.xml` などにおける依存関係の指定によって自動ダウンロードすることが可能なのです。

Java 経験の長い人ほど、あるいはオンプレの仕事がメインの方にとっては、この状況が意外かも知れません。私自身、プロプライエタリ系のJDBCドライバが Central から入手可能になったのには驚きました。(昔は状況がまるで違っていた)
このような傾向は、クラウド前提など時代の要請から実現されているのかもしれません。これは、クラウド上でのビルドの際に、Maven Repository Central に依存および解決できることが望まれるためかも知れませんね。
理由や経緯はともかく、JDBC ドライバを Maven Repository からダウンロードできるのは利便性良くとても快適です。

## 主要なRDBのJDBCドライバ

主要な RDB の JDBC ドライバの Maven Repository ランディングページを以下に示します。
(*) 他にも主要RDBはいろいろありますが、記述はここまでで割愛します。

| RDB | JDBC |　License | 
| --- | ---- | ------ | 
| PostgreSQL | [https://mvnrepository.com/artifact/org.postgresql/postgresql](https://mvnrepository.com/artifact/org.postgresql/postgresql) | BSD 2-clause |
| MySQL | [https://mvnrepository.com/artifact/mysql/mysql-connector-java](https://mvnrepository.com/artifact/mysql/mysql-connector-java) | GPL 2.0 | 
| Microsoft SQL Server | [https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc](https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc) | MIT |
| Oracle | [https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc11](https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc11) | Oracle Free Use Terms and Conditions (FUTC) |
| IBM DB2 | [https://mvnrepository.com/artifact/com.ibm.db2/jcc](https://mvnrepository.com/artifact/com.ibm.db2/jcc) | International Program License Agreement (IPLA) |

## pom.xml 記述組み込み例

Maven Repository 上の JDBC ドライバを 実際の Maven `pom.xml` に記述する例は、たとえば以下のような記述になります。

* [JDBC ドライバを pom.xml に記述する例](https://github.com/igapyon/oiyokan-initializr/blob/v1.1.20210603/src/main/resources/oiyokan-web-template/pom.xml#L44)

> * 初出: 2021-06-06
Laravelのパスワードリセットをemail以外のカラムで行うようにする

# はじめに
Laravelの標準のAuthのパスワードリセットでは、emailのカラムを元にリセットを行いますが、別のカラムを元にリセットをしたい場合など、パスワードリセットの機能をオーバーライドする必要が出てきます。
今回はパスワードリセットの機能についてつまづいた部分を書き留めておきたいと思います。

なお、本記事ではemailではなくmail_addressというカラムを使って実装していますので、適宜置き換えて実装してもらえればと思います。

使用しているLaravelのバージョンは5.7.29です。

# ForgotPasswordControllerのオーバーライド
emailではなくmail_addressというカラムを使うようにForgotPasswordControllerのオーバーライドします。

email.blade.phpで送られるパラメータをmail_addressに変更します。

```PHP:resources/views/auth/passwords/email.blade.php
<form method="POST" action="{{ route('password.email') }}">
    @csrf

    <div class="form-group">
        <label for="mail_address">{{ __('メールアドレス') }}</label>
        {{ Form::text('mail_address', null, ['class' => 'form-control']) }}

        @if ($errors->has('mail_address'))
            <span class="invalid-feedback" role="alert">
                <strong>{{ $errors->first('mail_address') }}</strong>
            </span>
        @endif
    </div>
    {{ Form::submit(__('送信'), ['class' => 'btn btn-primary']) }}
</form>
```

mail_addressの項目を使うようにsendResetLinkEmailをオーバーライドします。

```PHP:app/Http/Controllers/Auth/ForgotPasswordController.php
public function sendResetLinkEmail(Request $request)
{
    $this->validate($request, ['mail_address' => 'required'], ['mail_address.required' => 'メールアドレスを入力してください。']);
    $response = $this->broker()->sendResetLink(
        $request->only('mail_address')
    );
    if ($response === Password::RESET_LINK_SENT) {
        return back()->with('status', trans($response));
    }

    return back()->withErrors(
        ['mail_address' => trans($response)]
    );
}
```

ここまでで、リクエストパラメータのバリデーションとユーザー検索の処理を `mail_address` を使って行えようになります。
次に `password_resets` テーブルにinsertするパラメータの取得を `email` から `mail_address` に変更します。

```PHP:app/User.php
public function getEmailForPasswordReset() {
    return $this->mail_address;
}
```

最後にメール送信するパラメータの取得を変更します。

```PHP:app/User.php
public function routeNotificationForMail() {
    return $this->mail_address;
}
```

これでメール送信までできるようになりました。

# ResetPasswordControllerのオーバーライド
最後にパスワード変更を行なっているメソッドのをしていきます。

下記のようにreset.blade.phpで送るパラメータをmail_addressに変更します。

```PHP:resources/views/auth/passwords/reset.blade.php
<input type="hidden" name="mail_address" value="{{ $email ?? old('email') }}" required autofocus>
```

ResetPasswordControllerのcredentialsをオーバーライドしてmail_addressを元にユーザーの検索を行うようにします。

```PHP:app/Http/Controllers/Auth/ResetPasswordController.php
protected function credentials(Request $request)
{
    return $request->only(
        'mail_address', 'password', 'password_confirmation', 'token'
    );
}
```

これだけだとemailのバリデーションに引っかかるので、バリデーションのルールをオーバーライドします。

```PHP:app/Http/Controllers/Auth/ResetPasswordController.php
protected function rules()
{
    return [
        'token' => 'required',
        'mail_address' => 'required|email',
        'password' => 'required|confirmed',
    ];
}
```

これで、emailではなくmail_addressを使って機能するパスワードリセットの実装ができました。
Kotlin CoroutineのFlowで一定期間データが取得できない場合のタイムアウト処理を書くには

# 背景

例えば株価をリアルタイムに画面に表示することを考えてみます。
ネットワークの調子が悪いときに現在の価格を消して「取得できません」と出したいようなときどう書くのがシンプルか考えてみました。

# 方法

## suspend funの場合のタイムアウト

まず普通のsuspend funであれば簡単です。
withTimeoutやwithTimeoutOrNullで囲んでやればタイムアウト処理を書けます。

```kotlin
    withTimeout(1000L) {
        delay(2000)
    }
```

## Flowの場合のタイムアウト

ではFlowの場合はどうすればよいでしょうか？

ぱっと見てぴったりな標準関数は見当たりませんが、select { } を使えば簡単に実現できます。

以下説明用のため汎用性はありませんがFlow版のwithTimeoutを作ってみました。

```kotlin
fun Flow<String>.withTimeout(coroutineScope: CoroutineScope, timeMills: Long) = flow {
    val receiveChannel = produceIn(coroutineScope)

    while (coroutineScope.isActive) {
        select<Unit> {
            onTimeout(timeMills) {
                emit("タイムアウトしました")
            }

            receiveChannel.onReceive {
                emit(it)
            }
        }
    }
}
```

# サンプルコードと実行結果

全体のコードとしては以下のようになります。

```kotlin
package example

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.produceIn
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.select
import kotlinx.coroutines.withTimeout
import kotlin.coroutines.EmptyCoroutineContext

suspend fun main() {
    val job = SupervisorJob()
    val coroutineScope = CoroutineScope(EmptyCoroutineContext + job)

    coroutineScope.launch {
        val exampleFlow: Flow<String> = flow {
            delay(5_000)
            emit("1")
            delay(1_000)
            emit("2")
            delay(5_000)
            emit("3")
            emit("END")
        }

        exampleFlow
            .withTimeout(coroutineScope, 2_000)
            .distinctUntilChanged()
            .collect {
                println(it)

                if (it == "END") {
                    coroutineScope.cancel()
                }
            }
    }.join()
}

fun Flow<String>.withTimeout(coroutineScope: CoroutineScope, timeMills: Long) = flow {
    val receiveChannel = produceIn(coroutineScope)

    while (coroutineScope.isActive) {
        select<Unit> {
            onTimeout(timeMills) {
                emit("タイムアウトしました")
            }

            receiveChannel.onReceive {
                emit(it)
            }
        }
    }
}

suspend fun aa() {
    withTimeout(1000L) {
        delay(2000)
    }
}
```

出力のサンプルは以下です。

```
タイムアウトしました
1
2
タイムアウトしました
3
END
```
Angluar CLIをインストール後にngコマンドが見つからないと表示された場合

# Angluar CLIをインストールした後、ngコマンドを叩いたが「ng: command not found」と表示された場合の対処法


MacのターミナルからAngularのプロジェクトを作成するために、npmツールを使って、Angular CLIをインストールしました。

```
npm install -g @angular/cli
```

その後、ngコマンドを叩いたところ、下記のようなエラー(ngコマンドが見つからない)が表示されました。

```
mymac:test user$ ng
zsh: command not found： ng
```

## aliasで一時的にPATHを通す

これは、ngコマンドを実行する際に、PATHが通ってないだけなので、AngularのCLIがインストールされた場所を確認して、以下のコマンドを実行します。

```
alias ng="/user/Desktop/angular/angular/.npm-global/lib/node_modules/@angular/cli/bin/ng"
```

これで、パスを通すことができます。

上記の「ng="〜"」は、インストールした場所によって変わるため、「npm install -g @angular/cli」を実行時にインストール場所がターミナルに表示されているはずなので、それを入力する必要があります。


## TATHとは？

コマンドプロントであるフォルダを実行したい、例えばgitコマンドを実行したい場合、コンピュータはgitコマンドが何処にあるか、分かりません。なので、このフォルダを探してください ＝ PATHで場所を指定することができます。



以上となります。
SharePoint Onlineのモダンページに画像を張り付ける際の便利なことと不可解なこと

SharePoint のモダンページで、テキストの Webパーツ上に、クリップボードから画像をコピペすると、SiteAssets/SitePages/(ページ名)/ の下に、適当なファイル名をつけて png で自動で保存してくれるのはとても便利です。
例えば、以下のページのテキストの Webパーツ上で画像をコピペします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467348/382cbad0-443d-6ea6-bff9-98a9eff37926.png)
すると、画像のWebパーツが勝手に追加されて、画像が張り付きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467348/b9a86409-1b33-85e9-f463-ab2a56ea240e.png)
この画像は、実は、リソースファイルのフォルダの下に画像ファイルとして保存されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467348/7668fd77-9d0d-263c-77ff-fe7ebeb871ca.png)
いちいち画像をアップロードする必要がなく、他のページでも再利用できるので地味にうれしいです。
けれども、SiteAssets にアクセス権がないユーザが、このページにアクセスすると、

（SharePoint の個人ユーザページの例）
　https://XXXXXXXXX-my.sharepoint.com/_api/v2.1/drives/

または、

　https://spoprod-a.akamaihd.net/files/sp-client/

のような、akamai のよくわからないサイトへのリンクが張られていて、画像が表示されず、エラーになります。
そのユーザにアクセス権を与えると SiteAssets の下へのリンクに変わって、正しく画像が表示されるようになります。
不可解な動き。
 
ちなみに、テーブル(表) の中にも、クリップボードで画像が張りることができます。でも、その場合のリンクは、以下のパスのままで、SiteAssets へのパスにはなりません。テーブル内への画像の貼り付けは推奨されないのかな？

https://XXXXXXXXX-my.sharepoint.com/_api/v2.1/drives/
[Ruby] クラスをさらに深ぼる

## はじめに
前回はクラスの基本的な概念をアウトプットしました。
今回はもう少し踏み込んだ内容について書かせていただきます。

## クラスの継承
前回のタイヤキの話でクラスは共通部分を再利用できるので効率がいい。例えば新商品が出ても元のタイヤキをアレンジするだけでいい、それが共通部分を再利用できるということです。

みたいなわかりにくい説明してたと思うんですが、その話を踏み込んでいきます。


クラスというのは親子関係を作ることができるのです。
元々あるクラスの情報をもとにして新しいクラスを作るということです。これを「クラスの継承」と呼びます。

元となったクラスのことはスーパークラスと言います。
スーパークラスをもとに作られた新しいクラスはサブクラスと言います。
クラスの継承を使うと共通部分をまとめることができるので非常に効率的なのです。

今回は車を例に説明をしていきたいと思います。
例えば、パトカー、消防車、救急車のクラスを作る時には、自動車という三つともに共通する情報があるクラスを作成し、そこから派生をする形でそれらの三つのクラスを作成した方が効率的ですよね。

一から設計図を書き直すより、エンジンの構造とかアクセル、ブレーキの構造など同じ部分があるならそれは継承してあげた方が楽っていう話です。

## 継承の仕組み

継承の仕方は
新しいクラス < もとになるクラス
です。

```Ruby
class PoliceCar < Car

end
```

クラスを継承するとサブクラスに**親のインスタンス変数**と**親のインスタンスメソッド**が引き継がれます。

下記にCarクラスを継承したPoliceCarクラスの作成するコードを示します。

```Ruby
class Car
 def initialize(car_type, capacity)
   @name = car_type
   @capacity = capacity
 end

 def info
   puts "車種：#{@name}　乗車定員：#{@capacity}人"
 end

end

class PoliceCar < Car

end

police_car = PoliceCar.new("パトカー", 5)

police_car.info

# ターミナル出力結果
# 車種：パトカー　乗車定員：5人
```

PoliceCarの中身には何も記述していないのにもかかわらず、継承元のCarクラスのインスタンス変数とインスタンスメソッドを使うことができています。

## インスタンスメソッドの追加

もちろんサブクラス独自のインスタンスメソッドを追加することもできます。
特に深く考えずにサブクラス内に普通にメソッドを定義してあげれば問題ないです。
下記が例です。

```Ruby
class Car
 def initialize(car_type, capacity)
   @name = car_type
   @capacity = capacity
 end

 def info
   puts "車種：#{@name}　乗車定員：#{@capacity}人"
 end

end

class PoliceCar < Car

 def siren
   puts "ウゥ〜ウゥ〜"
 end

end

police_car = PoliceCar.new("パトカー", 5)

police_car.siren

# ターミナル出力結果
# ウゥ〜ウゥ〜
```

新たなsirenメソッドを定義してそれを実行しています。このようにして、各々のサブクラスの個性を出してあげます 笑

## オーバーライド
親クラスに既に存在するメソッドと同じ名前でサブクラスでメソッドを定義すると、上書きすることができます。
これを、そのままですが**オーバーライド**と言います。

例えば下記のコードを見てください。

```Ruby
class Car
 def initialize(car_type, capacity)
   @name = car_type
   @capacity = capacity
 end

 def info
   puts "車種：#{@name}　乗車定員：#{@capacity}人"
 end

end

class PoliceCar < Car

 def info
   puts "車種：#{@name}　乗車定員：#{@capacity}人　パトロール時間：24時間"
 end

 def siren
   puts "ウゥ〜ウゥ〜"
 end

end

police_car = PoliceCar.new("パトカー", 5)

police_car.info

# ターミナル出力結果
# 車種：パトカー　乗車定員：5人　パトロール時間：24時間
```

スーパークラスのCarクラスで定義されているinfoメソッドと同じ名前のinfoメソッドがサブクラスのPoliceCarクラスにも定義されていて、さらにpolice_carに対してそれを使うと、見事にサブクラス側で定義された結果が出力されます。

## 最後に
クラスに関してはなんとなく頭でわかっていても、継承したりすると、なんだか記述が似てきたりして混乱することがあります。
この考え方は他の言語にも存在するのでよく理解しておきたいです。
デプロイ後、トップページは表示できるのにユーザー登録画面に行けない

## 環境
Ruby 2.6.5
RailsRails 6.0.3.6

## 状況
ユーザー登録機能をdeviseで実装したオリジナルアプリを、Herokuにてデプロイ。
アクセスすると、トップページは表示されますが、トップページから「新規登録」や「ログイン」をクリックすると、エラーが出るという状況です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402996/aefc9d4f-e63b-7a92-d2b1-ce8e72bfae29.png)

## 結論
Heroku上でのマイグレーションがうまくいっていないことが原因でした。

## 解決までの過程
① heroku logs --tail --app <<アプリケーション名>>　でログを確認

[![Image from Gyazo](https://i.gyazo.com/f638732455916c299b4f56703c093905.png)](https://gyazo.com/f638732455916c299b4f56703c093905)

ログの最下部にstatus=500とあります。500番台は、サーバーがブラウザからのリクエストの処理に失敗した状態です。
調べてみると、DBに関わる場合が多いとわかり、heroku run rails db:migrateでもう一度マイグレーションを試みます。

② マイグレーション中のログ内にエラーを確認

[![Image from Gyazo](https://i.gyazo.com/feb420d5abe2857f585b8c38f4742fe3.png)](https://gyazo.com/feb420d5abe2857f585b8c38f4742fe3)

「No such column: posts.genre」
postsテーブルにgenreというカラムが存在しないことにより、

「all later migrations canceled:」
マイグレーションがキャンセルされた

ということがわかりました。

③ 問題解決のための仮定
postsテーブルを確認すると、genreカラムではなくgenre_idカラムが存在していました。
初めはgenreカラムを作成しましたが、設計を変更し、genre_idカラムに書き換えました。
そのためのファイルが以下です。
[![Image from Gyazo](https://i.gyazo.com/d2af0d38ee64b5b1b97bf61ab3a35a93.png)](https://gyazo.com/d2af0d38ee64b5b1b97bf61ab3a35a93)

このファイルがある状態でHerokuにマイグレーションを行おうとすると、genreカラムの存在が確認できず、エラーが出ると考えました。

④　仮定の検証
genreカラムをgenre_idカラムに変更したファイルを削除し、再度heroku run rails db:migrateを実行しました。

⑤ 問題の解決
マイグレーションが完了し、アプリも正常に作動しました。

## まとめと疑問点
エラーは、ログからエラー内容の確認、原因の特定、修正の流れが大切だと再認識しました。

ただ今回の場合、そもそも「新規登録」や「ログイン」のボタンをクリックしても情報入力ページに行くだけなので、DBはまだ関係ないのではと疑問が残りました。
情報入力後、「登録する」や「ログインする」のボタンをクリックするとエラーになるのなら納得できるのですが・・・
この点も含め、より理解が深まるよう、今後も学習を継続したいと思います。
リーダブルコードを読んで特に大事だと感じた事５選

エンジニアとして現場デビューして改めてリーダブルコードを読んだのでためになったことなどを５つ選んでまとめておきたいと思います。

## 1　コードの意図をコメントに残す
現場実務に入って最も重要だと感じたことの一つにコードのコメントがあります。
関数や処理にその実装の意図などのコメントが記載されているれば、一つ一つの細かい処理は理解できなくても、同じような処理であれば、調べながら実装を進めることができます。コメントがあるだけでコードのみやすさは全然違います。確かにあまり必要のないコメントをするのは良くないとされていますが、今は基本的にはコメントは積極的に書いておき、コードレビューなどでフィードバックをもらった時に最適化していくスタイルにします。

## 2　名前に情報を詰め込む

基本的には変数名とか関数名のことですかね。これもコードの可読性をあげるには必要不可欠だと思っています。例えば、今ぼくが業務でメインで使用しているScalaではOption型といものがなって変数でOption［Int］型というものがあった時にnumOptと書いておけばこの変数にどんな値が入っていて次にどんな処理が想定されるのか一発でわかります。
リーダブルコードでは名前を付与する時は以下の６つに意識すると良いと書いてあります。

- 明確な単語を選ぶ
    - 処理に合わせて単語を選ぶ。例えば、処理を停止する関数があった場合、単にStop()という命名でも良いが、動作に合わせて明確な名前をつかたほうがいい場合もある。例えば、取り消しができないような重い処理であれば、Kill()という名前にするなど、処理に応じて具体的な命名を意識する。
     
- 汎用的な名前を避ける
    - エンティティの値や目的を表した名前を選ぶ。
    - 逆にループイテレータとして使用する変数にはi jなどを使用しても問題ない。
    - イテレータが複数ある時はインデックスに明確な名前を付与する

- 変数名に大切な情報を追加する
   - 変数名に詰め込める情報は多くないが、名前につけた情報は変数を見るたびに目に入ってくるので、大切な情報は変数名に込める。
   - ミリ秒を表す変数名には、後ろに_msをつけるなど。
  

- スコープの大きな変数名には長い名前をつける
    - スコープが大きければ、名前に十分な情報を詰め込んで明確にする必要がある。

- 名前のフォーマットで情報を伝える
    - クラス名はキャメルケース、変数名はlower_caseなど、コードに統一感がでて可読性が向上する。

## 3　ネストを浅くする
if文などの条件式においては、読み手のコストが非常に高くなるし、自分がどの条件ブロックにいるのか常に確認する必要がある。
ネストが深くなっている場合、関数を早めに返して、ネストを削除したり、「ガード節」などを設けてたりする　。
   

## 4 巨大なコードを分割する
複雑なロジックがある場合は説明変数を導入する。

- 巨大な式を分割できる。
- 簡潔な名前で式を説明することで、コードを文書化することができる。


## 5　縦の線を揃える
これは単純にコードの見やすさという点ですが、自分自身縦のラインを合わせてコードを書くというのはこれまで意識していなかったことですが、実務のコードは縦のラインがきっちりそろっているので非常に見やすくなっています。
これはコードを書くときの当たり前の習慣にしいたいなって思っています。


リーダブルコードでは可読性を上げるために必要なことがたくさん書かれていますが、ここでは最低限自分が特に普段から意識しておきたいことを挙げました。
pyinstallerがインストールできない

# 誰向けの記事？
　この記事は、

・`pyinstaller`をインストールしたいが、 `pip install pyinstaller`で躓いた人

向けです。（あくまで解決方法の一つなので、原因に当てはまらない場合は、何の参考にもなりません）

# 原因
　原因はpythonのバージョンでした。私の場合、python3.9がインストールされています。しかし、以下のバージョンじゃないとpyinstallerはインストールできません。現時点2021/06/06では、pyinstaller 4.3が最新です。

・python 3.6 - python 3.8
（参考：[https://pypi.org/project/pyinstaller/](https://pypi.org/project/pyinstaller/)）

# 解決法
　つまり、対応するバージョンのpythonを入れ、そのバージョンで`pip install pyinstaller`を実行すれば良いという事です。

## python3.8.9をインストールする
　以下のサイトから、python3.8.9のインストーラをダウンロードし、インストールしましょう。なお、インストール時にパスを指定しておくと便利です。

・python3.8.9：[https://www.python.org/downloads/release/python-389/](https://www.python.org/downloads/release/python-389/)

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/51f9b2aa-d48a-027a-7db4-41d124a29799.png">
・python3.8.9のダウンロード（win64）
</div>

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/df18f8c3-8b8d-a592-73e3-a689d4b5147a.png">
・インストール時にパスを追加する
</div>

## pythonのバージョンを指定しながらインストールする
そして、以下のコマンドにより、python3.8.9からpyinstallerをインストールしましょう。これでインストールできるはずです。

```ruby:install_pyinstaller_by_python3.8
py -3.8 -m pip install pyinstaller
```

# おわりに
　pyinstallerのインストールに躓いたのもありますが、pythonのバージョンを変えて実行する当たりが、他にも活きるのかなぁと思って書きました。pythonってバージョンによるエラーとかがあるからちょっと面倒な側面もありますよね。
　あと関係ないですが、先日投稿した[PythonのSeleniumを使って、起動済みのブラウザを操作する。](https://qiita.com/mimuro_syunya/items/2464cd2404b67ea5da56)が地味に伸びててびっくりしました。どっかのランキングに乗ったおかげかな。内定もらった次にうれしい出来事です(*'ω'*)
　それじゃ！
ブラウザバックでのページ表示時処理

ブラウザバックで動くJSの処理について質問されて、正確な情報を伝えられなかったのがきっかけで掘り下げました。

# ページ表示時に動くJS処理は何があるか？
|イベント|内容|
|---|---|
|DOMContentLoaded|HTML解析完了時|
|load|全リソースの読み込み完了時(***キャッシュの場合は対象外***)|
|pageshow|全リソースの読み込み完了時(***キャッシュの場合も対象***)|
参考：[ブラウザ関連のJavaScript - Qiita](https://qiita.com/takeshisakuma/items/f0e1a755229034294480)
ちなみに呼ばれる順番は、①DOMContentLoaded → ②load → ③pageshowです。

# 各ブラウザでのブラウザバックで動くJS処理
## 確認方法
A.html
↓ リンク押下
B.html
↓ ブラウザバック
A.html  ←***このタイミングで動くページ表示時処理***
### キャッシュから表示された場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/50857358-10ac-70f3-f7a0-2b1c524d3f84.png)
Firefox、Safariは、キャッシュから復元されるとDOMContentLoaded, loadが動かない。
リクエストはキャッシュから復元されているので送らない。

### キャッシュされないように指定した場合（cache-control: no-cacheをレスポンスに指定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/2b81272c-4562-e8ea-adc9-b9b67f0b9463.png)
Firefoxは、キャッシュから復元されたかの有無でDOMContentLoaded, loadが動いたり・動かなかったりする。

（2021年06月06日時点）
***Safariは、cache-control: no-cacheを指定してもキャッシュから復元してしまう。***
[【Safari】no-store がついていてもbfcacheが有効になる - UGA Boxxx](https://uga-box.hatenablog.com/entry/2020/06/20/000000)

## pageshowイベント
ブラウザバックで安定して呼ばれるのは、pageshowイベント。
pageshowイベントの引数でPageTransitionEventを受け取ります。
PageTransitionEvent.persistedのtrue or falseでキャッシュから表示されているのかを判定できます。

```javascript
window.addEventListener('pageshow', function(event) {
  if (event.persisted) {
    console.log('キャッシュから表示');
  } else {
    console.log('新しいページを受信して表示');
  }
});
```
[Window: pageshow イベント - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Window/pageshow_event)
[PageTransitionEvent.persisted - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent/persisted)


# ブラウザバックに関連するキーワード
## bfcache
bfcacheは、Back Forward Cacheのこと。
Firefox 1.5では、訪問したページ全体をJavaScriptの状態も含めてメモリ内にキャッシュすることで、ページ間の戻る、進む時のページロードが不要にしている。
[Using Firefox 1.5 caching - Mozilla | MDN](https://developer.mozilla.org/ja/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching)

## HTTPヘッダ cache-control: no-cache
レスポンスのHTTPヘッダにcache-control: no-cacheを指定するとブラウザにキャッシュさせたくないことを指定できる。
> no-store:
> 　レスポンスをキャッシュに保存することはできません。他のディレクティブを設定することもできますが、最近のブラウザーではレスポンスがキャッシュされることを防ぐために必要なディレクティブはこれだけです。 
> [Cache-Control - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control)

# まとめ
現状はブラウザバック後でも、動かしたいJSの初期処理がある場合はpageshowイベントを使う方が望ましい。
rel="noopener"ってなんですか？

# はじめに
こんにちは。メルカリでハヤテのごとく！全52巻が売れたのですが、2か月くらい支払いがされておらず、今に至ります。皆様もそういうユーザにはご注意くださいませ:pray: 

さて、今回はLigthHouseで指摘されていたことについて記載しようと思います。

# 指摘されていたこと
別タブで開くaタグ（**target="_blank"**）には、**rel="noopener"**か**rel="noreferrer"**をつけてくださいとのこと。
![Lighthouse-Report-Viewer (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/fc1e72af-9d50-ff2e-90c2-03831bbdcbeb.png)

とりあえず付けたけど、これって一体何者なのさ？

# rel="noopener"ってなんですか？

結論、**<font color="red">つけないとセキュリティ的よくないぜ！</font>**って感じです。

ただ、現在**target="_blank"**のリンクには、暗黙的に**rel="noopener"**付加されるので、明示的につけなくても上記は問題ないと思います。

MDNには以下のような記載があります。

https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/noopener
>リンクを新しい閲覧コンテキストで開き、リンク元の文書へアクセスできないようにすることをブラウザーに指示します。つまり、新たに開いたウィンドウで Window.opener プロパティを設定しません（null を返します）。

## つまりこういうこと
1. rel="noopener"がない場合、開いた新しいタブで、**Window.opener**を用いてリンク押下元のタブにアクセスできる。
1. 1により、開いた新しいタブで`Window.opener.location = 'https://google.com'`で、リンク押下元のタブをgoogleに飛ばすことができる.
1. **rel="noopener"**をつけておけば、1と2ができなくなる:+1:

いやー、怖い...。フィッシング詐欺とかできそう...。

# LightHouseでは明示的に指定しないとだめぽみたい。
LightHouseでは明示的に指定しないと指摘されちゃうので、ちゃんと指定してあげてください！

# おわりに
今まで知らなかったことですが、便利な機能があるんですね！
使い方によってセキュリティ問題に発展するケースだと思います。
LightHouseのScoreが気になっている方は、ちゃんと指定してください:smile:

ちなみにこれで**Best Practices**のスコアが7上がりました:+1:
![Lighthouse-Report-Viewer (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/f6027a82-e6ff-91b4-7585-b36bb2ef9406.png)


それでは！
RTP とは

## 勉強前イメージ

わからん・・・
英語3文字はいっぱいありすぎる

## 調査

### RTP とは

Real-time Transport Protocolの略で、
動画などの用にデータをリアルタイムに伝送するためのプロトコルの1つ。
UDPを使用するのが特徴で、
到着順の保証や欠落時の再送制御をしない代わりに高速に伝送できる


### 特徴

- UDPを使用する

リアルタイムに送るため、TCPでは向いておらずUDPを使用しています。
TCPのように通信エラーが起きてもシーケンシャルに同じ送信レートで送信され続けます

- 受信側でパケットを並び替える

UDPではシーケンス番号の項目がないので送信時と同様の順序でデータの並び替えが出来ないので
RTPパケットにタイムスタンプとシーケンス番号を書いて送り、受信側で並び替えを行っています。

- タイムスタンプの記載

↑で少し話しましたが、
UDPにはTCPの用に送った順番が確認できるものがないので、
RTPでタイムスタンプを持つことで順番が確認できるようになっています。

- 1対多の通信が可能

TCPは1対1しか対応していませんが、UDPは1対多の通信に対応しているので、
マルチキャスト通信などが出来ます。

### ユースケース

リアルタイム性のを重視する通信でし利用されています。
ストリーミング配信や、ビデオ通話、VoIPなどで利用されています。

## 勉強後イメージ

UDPを使用してるんだなーって思ってたけど、
リアルタイムのプロトコルもあるのね

## 参考

- [RTP 【Real-time Transport Protocol】](https://e-words.jp/w/RTP.html)
- [RTPはUDP上で動作する！5つの仕組み解説や活用事例を紹介](https://www.fenet.jp/infla/column/technology/rtp%E3%81%AFudp%E4%B8%8A%E3%81%A7%E5%8B%95%E4%BD%9C%E3%81%99%E3%82%8B%EF%BC%815%E3%81%A4%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E8%A7%A3%E8%AA%AC%E3%82%84%E6%B4%BB%E7%94%A8%E4%BA%8B%E4%BE%8B%E3%82%92/)
実務未経験でエンジニア転職して感じること。〜2ヶ月目〜

##はじめに
皆様、お久しぶりでございます。
入社して1ヶ月の時点で投稿し、次回以降は技術的な部分も投稿します、、と言っていたら
気づいたら6月でした。時が経つの早すぎる。。

1ヶ月目に投稿した記事のリンクは**[こちら](https://qiita.com/makky/items/7fff5aeb1005ce6caf44)**ですので、
もしお時間あれば読んでいただければと思います。
ということで2ヶ月目もサクッと振り返っていけたらと思います！よろしくお願いします！


##この１か月（入社後1ヶ月〜2ヶ月）で感じたこと
**壁にぶつかりつつ、でもちょっとだけ前に進んでる。**そんな感覚でした。
1ヶ月目では、実務で使う以前の知識が足りない、
何がわからないかをまず洗い出すことからスタートしていたのですが、
点の知識が少しは（ほんとに少し）線になって、手を動かせる部分が増えてきたかなと思います。
自分が手を動かして、同じ事業部のメンバーから感謝されると、ほんと嬉しいです。（泣）
直接お客様と関わる機会は少ない分、同じ事業部のメンバーからの言葉が嬉しかったりします。

１つインプットした時に「この場合は？」「あの場合と同じ考え方？」と想起することも増えたり。
ゼロからスタートした分、壁にぶつかる機会も多いですが知った、できるようになったの幅が大きいのは貴重です。


1ヶ月でおもしろかった、勉強になった記事TOP３です。
・**[世界の創り方](https://note.com/katsuakisato/n/n3f482a846b0d)**
・**[良いコードとは何か](https://note.com/cyberz_cto/n/n26f535d6c575)**
・**[【新人プログラマ応援】学習用のプログラムと仕事で書くプログラムは何が違うか](https://qiita.com/jnchito/items/c9ca22efa270ff1b7f3d)**
どんどんキャッチアップして、前に進むスピードをもっと加速させたいです。




##１番印象に残ったトピック
ついに**本番環境で人的ミスで障害を発生させるという大事件。**
そうです。1ヶ月目の時にこんなことを書いていました。

>テスト環境だったからまだ良かったものの、（もちろん復旧する仕組みはありますが）
本番環境でこんなことをしてしまったらと思って、パニックになった１日でした。。

フラグ回収の伏線だったわけもなく、冷や汗が止まらない時間でした。
幸いにも先輩方が即刻対応してくださったおかげで大きな影響はなく復旧されました。。








![pose_syazai_sliding_dogeza_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883905/86a11240-f68e-7827-5e4c-6f9544fbd7f8.png)






前回は凡ミスof凡ミスでしたが、今回は認識不足&**ミスが起こりやすいような環境で
作業をしていた**ことが原因でした。もちろん大反省ですし二度と同じミスで障害は発生させないです。が、今回もいろんなことを学ばせていただいたなと。
障害が発生した後の対応の仕方や、そもそも発生し得ないような仕組みを作るには、等
身を持って経験したからこそ、腹落ち具合というか理解度が全然違います。身にしみるううう

後は変化として、各社の障害報告にかなり寛容になりました。
障害のニュースを見ると「頑張れ、、！」、
復旧するとおつかれさまでした、、！（拍手）という気持ちに。（誰目線なんでしょうか）
報告の仕方が気になってHPを見に行ったり、セキュリティや障害の記事も見るようになり、
関心の幅も増えたかなと思います。


毎月のトピック、今のところ大事件しかないので、そろそろ良いトピックもお届けしたいです。


###雑談
1ヶ月目の時点で私はスラムダンクにハマりましたが、今もなお継続中です。
ハマるまでは気づかなかったですが、ここまで人気のものだと
何かと**話のきっかけ**になりますね。しかも楽しい。
自分たちの世代（20代半ば〜後半）は世代的にはドンピシャではないですが、
それでも好きな人が多かったり。ドンピシャ世代の人とはかなり盛り上がったり。発見でした。
「スラムダンク好き？」ではなく「（スラムダンクの中で）誰が好き？」から始まり、
どの選手が好きかで、あ〜そういうタイプねと盛り上がる。いいことしかないです。

しかも同期がスラムダンク好きで漫画を持っているという最強な感じでした。感謝。
なので、今は漫画をお借りして、毎日少しずつ読むのを楽しみにしています。
相変わらず三井くんが好きで、でもどこまでも報われない藤真くんを応援したくなったり
初心者から始めた花道に感情移入することもあったり忙しいです。
ふと、もしかして、**安西先生ってすごい、、？**（←何を今更）と思ったり。
読み直すとまた違う感情も出てきそうです。
インターハイに行ってからじゃないと話せないと言われることが多いので、早く読み進めます。

（あれ、雑談長くない？と思った方。正解です。これでも抑えております。お許しを。。）



##最後に
1ヶ月目より更に技術面ゼロでのお届けになりました。（あれ？）
冷や汗止まらない1日もありましたが、基本的には楽しくしております。
開発環境の構築も終わったので、次回以降こそ何か書けたら、、！と思っています。

自分が前に進んでいる感覚を持つことができるのも、質問や相談がしやすい環境だったり、
やってみたいと思ったことを伝えると、いいね！と言ってくれる環境だからこそだと思います。
感謝、はもちろんですが、ガンガン成長してお返しできたらなと。

未経験から転職したエンジニアがどうなっていくのか、、、~~乞うご期待！~~