OmniAICreator/Qiita-1.07M huggingface dataset:
ルーティング　コントローラ　ビュー　

#ビュー
見た目に関するHTMLファイル
単語の意味そのまま
#コントローラ
ブラウザに返すビューをviewsフォルダの中から探し出す
# ルーティング
対応表
どんな？
送信されたURLから、どのコントローラのどのアクションで処理するかを決める
デフォルト引数に空配列を設定すると無限ループが発生する

# 背景
Hooks を使って管理していた key の値が無限に増幅され、無限に再レンダリングが発生するという事象に直面しました。

実装されていた処理を簡略化して記載すると下記のような形です。

```typescript

const ParentPage: () => {
  ...
  return (
    <ChildComponent />
  )
}

const ChildComponent = ({ input = [] }) => {
  const [key, setKey] = React.useState(0)
  const [something, setSomething] = useSomething(input)

  const f = () => {
    setSomething(...)
    setKey(prev => prev + 1)
  }

  React.useEffect(() => {
    if (...) {
      f()
    }
  },[something]}

  return <SomethingComponent key={key} />
}
```
※一部、処理を省略してしまっており、読みにくくて申し訳ありません。

やりたかったのは、何かの処理の時に `SomethingComponent` を再描画させるために key の更新です。

ですが、このケースで無限ループが発生しました。

# 原因と解決策

### 原因
お気づきの方もいると思いますが、この記法だと eslint の `exhaustive-deps` で警告が出ます。
ただ、今回のケースはこの deps で実現したいものだったのでそこは変えないようにします。

それを考慮した上で、今回の事象の原因は引数 input に与えたデフォルト引数に問題がありました。

input の値が `string` や `number` の場合は再レンダリングは発生しません。
`ParentPage` で利用する際に `<ChildComponent input={[]} />` のように prop として渡しても再レンダリングは発生しません。

ですが、デフォルト引数として `[]` や `{}` を渡した場合、無限に再レンダリングします。

### 解決策

トップレベルに変数を用意して、その内容をデフォルト引数に渡します。
この方法なら、 `ChildComponent` を別ファイルに切り出しても再レンダリングを防ぐことができます。

```typescript
const defaultInput = []
const ChildComponent = ({ input = defaultInput }) => {
...
}
```

# まとめと所感

### まとめ
実際に利用していたケースでは処理がもう少し複雑だったので、原因究明に時間がかかりました。
デフォルト引数のインスタンスが再生成されるタイミングの理解不足でした。

1. useState により状態が更新
2. ChildComponent 関数が再度実行される
3. useEffect の deps が状態の変化を判定

という流れになりますが、デフォルト引数でオブジェクトを指定している場合、 2. では毎回新たなインスタンスが生成されるため 3. で useEffect の処理が実行されてしまいます。
結果、再度 1. になりめでたく無限ループ…という流れでした。

### 所感

デフォルト引数は [Airbnb のコーディングガイド](https://github.com/airbnb/javascript#es6-default-parameters) の good ノウハウにも載っているので便利なテクニックです。
今回のケースのように React コンポーネントの props として利用する場合、かつ React 内部で Hooks と依存性を持たせる場合は無限ループにならない書き方ができているかを意識する重要性を感じました。


記載内容に不備・誤り、または指摘やアドバイスなどがありましたらコメントまでお願いします！
Golangでzipファイルを解凍する

こんにちは。初投稿です。どうぞお手柔らかにm(__)m。

Go言語に触れ始めて数か月、それほどガッツリ書いてるわけではないですが、少しわかってきた気がします（危険な時期）

さて、タイトルの通りZipファイルを解凍するのですが、よくあるZip解凍ツールのように「ファイル名を展開先のディレクトリ名に使う」のってよくありませんか？ないですかそうですか。

例えば「test20210318.zip」であれば「test20210318」というディレクトリを作って、その下層に展開する、というものです。
実際に業務でニーズがありまして、同じファイル構成でzip圧縮されたファイル群を、繰り返し解凍するような仕組みです。

作ったサンプルがこちら。

```Go:sample/unzip/main.go
package main

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
)

// unZip zipファイルを展開する
func unZip(src, dest string) error {
	r, err := zip.OpenReader(src)
	if err != nil {
		return err
	}
	defer r.Close()

	ext := filepath.Ext(src)
	rep := regexp.MustCompile(ext + "$")
	dir := filepath.Base(rep.ReplaceAllString(src, ""))

	destDir := filepath.Join(dest, dir)
	// ファイル名のディレクトリを作成する
	if err := os.MkdirAll(destDir, os.ModeDir); err != nil {
		return err
	}

	for _, f := range r.File {
		if f.Mode().IsDir() {
			// ディレクトリは無視して構わない
			continue
		}
		if err := saveUnZipFile(destDir, *f); err != nil {
			return err
		}
	}

	return nil
}

// saveUnZipFile 展開したZipファイルをそのままローカルに保存する
func saveUnZipFile(destDir string, f zip.File) error {
	// 展開先のパスを設定する
	destPath := filepath.Join(destDir, f.Name)
	// 子孫ディレクトリがあれば作成する
	if err := os.MkdirAll(filepath.Dir(destPath), f.Mode()); err != nil {
		return err
	}
	// Zipファイルを開く
	rc, err := f.Open()
	if err != nil {
		return err
	}
	defer rc.Close()
	// 展開先ファイルを作成する
	destFile, err := os.Create(destPath)
	if err != nil {
		return err
	}
	defer destFile.Close()
	// 展開先ファイルに書き込む
	if _, err := io.Copy(destFile, rc); err != nil {
		return err
	}

	return nil
}

func main() {
	// パスを取得
	rootPath, _ := os.Getwd()
	rootDir := filepath.Dir(rootPath)
	fmt.Println(rootDir)

	zipPath := filepath.Join(rootDir, "downloads", "test20210318.zip")
	destDir := filepath.Join(rootDir, "reserves")

	if err := unZip(zipPath, destDir); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	os.Exit(0)
}
```

main()のzipPathとdestDirはお好みで。

```bash
$ go version
go version go1.14.6 linux/amd64
$ go run sample/unzip/main.go
```

Windowsユーザーなので、VSCodeで書いて、ターミナルをWSLにして実行しています。
Goの環境設定などは先人の記事を参考にしてください。

実はもっと無意味に複雑なことをしていましたが、あちこち記事を漁るうちに気が付いたことがあります。

##zipファイル内のディレクトリを毎度作成する必要はない

zip.Fileを走査中、ディレクトリがあっても無視して構いません。

```Go:
	for _, f := range r.File {
		if f.Mode().IsDir() {
			// ディレクトリは無視して構わない
			continue
		}
```

なぜかというと、zip.File.Nameにパスが含まれているからです。
後続処理のファイル作成時にディレクトリも作成すれば済みます。

```Go:
	// 子孫ディレクトリがあれば作成する
	if err := os.MkdirAll(filepath.Dir(destPath), f.Mode()); err != nil {
		return err
	}
```

os.MkdirAllは既にディレクトリがあってもエラーを返しませんので、そのまま後続処理に流れます。
ついでに、zip.File.Mode()を使えば、zip内のパーミッションを引き継ぐことができます。


##io.Copyを使う

以前はバッファにいったん全読み込みして、ファイルに書き出すような処理を書いていました。

```Go:以前のコード
		buf := make([]byte, f.UncompressedSize64)
		_, err = io.ReadFull(rc, buf)
```

これだとメモリを無駄に消費してしまうため、readerからwriterに直接よしなにしてくれるio.Copyが良いそうです。
また、io.CopyNというのもあります。これは書き込み時にバイト数を指定できるものです。
出自のわからないzipファイルを解凍するような場合は、zip爆弾を回避するためにも利用は必須かと思います。
ファシリテーターは会議を目的ゴールまで上手く導くこと。　　　ではない！！！！

0.はじめに
　開発全般、ものづくりしてたら避けては通らない会議

　本記事は、そんな会議のファシリテーションを依頼されたときに、
　最初に読み返すべきポイントをまとめています。
　自分でも陥りがちな罠や会議中に気を付けるべきポイントを振り返り
　少しでも意味のある会議を実現するためのノートです。

　いろんな意見があるかと思いますが
　私の一例として記述しています。

　メモ書きがてら殴り書きなので、後で体裁整えたりやろうかなと思います。

記事のアジェンダ
1.ファシリテータの極意
2.会議前の事前準備の極意
3.会議中の留意点

-------------------------------------------------------

1.ファシリテータの極意
ファシリテータの極意とは、会議の目的までメンバーをうまく導くこと

ではない!

ファシリテーションを行うときのモチベーションは


メンバー全員に目的を腹落ちさせて、やる気を引き出し、
自らの意思で考え行動する気持ちをいかに高められるか。
これがすべて！

これが高いほど良いファシリテータ！！！


このモチベーションを忘れてしまうと、
ただの意見の押し付け。
会議の場では「わかりました」と回答を得られても
いつまでたっても行動に移らないことが起こる。

-------------------------------------------------------

2.会議前の事前準備の極意
会議前の下準備はファシリテータにとって最も重要です。
事前準備は以下の工程に沿って行いましょう。

2-1.会議の目的と到達点を考える
2-2.会議の出発点を定める
2-3.論点の洗い出し


2-1.会議の目的を考える。

　目的とはそもそも会議を行う目的。
　到達点とは、目的を達成するための通過点。
　
　
　目先の通過点ではなく、導きたい最終像を考えること。

　言い換えると、会議とは一回で終わるものではなく
　複数回重ねた先に見据えている目的を捉えるように。

例：
　　「A商品の品質を上げるために意見を集めたい。」
　という目的は、実は、
　　「全社の商品売り上げを上げるための施策を検討したい。」
　というのが本当の目的かもしれない。

　そのための通過点として、
　「A商品の品質を上げて、A商品の売り上げを上げる」
　施策を打ちたいのかもしれない。

　その場合、
　目的「全社の売り上げを上げるための施策を検討したい。」
　としたうえで、次回の会議の会議の到達点は、
　「どの商品に対してどのようにテコ入れをすべきか決める」
　というステップになる。


　目的は、一度の打ち合わせで達成困難かもしれない。
　到達点は一度の打ち合わせで達成できそうなところに置く通過点。


------------------

陥りがちな罠ポイント
会議の目的が会議の目指すべき到達点だと勘違いしてしまう。
そのため、無理な目的を設定し、結局無理やり結論を押し付けてしまう結果に。

会議の目的は一度で達成しなくてもいい。

全体の会議の目的を捉えつつ、
次回の会議でどこまでを到達点をすべきかを考えることが大事。

------------------

2-2.会議の出発点を定める
会議に収集したメンバーの持っている情報のちがいを認識する。

会議のメンバーに以下のメンバーを集めた場合それぞれ見ている背景や大事にしているポイントが異なる。
・営業メンバー
・開発メンバー
・経営メンバー

会議前に意見を事前に収集して見えている前提条件の違いを認識しておくこと。
例えば、
営業メンバーは、より早く売り上げが上がることを大事にするかもしれない。
開発メンバーは、リリース後の品質を大事にするかもしれない。
経営メンバーは、対外的な世間からの印象を大事にするかもしれない。


それぞれが見ている前提条件の違いを共有しながら進めることが大事。

2-3.論点の洗い出し
メンバーの出発点が判明し、事前の意見が収集できた後は、
論点を洗い出す。

--------------------------
論点とは、
メンバーから出てきた意見が答えになるような問いかけを考える

--------------------------

論点をすべて網羅しておくことは現実的には
非常に難しいけど

可能な限りやっておくことが大事

----------------------------------------------------


3.会議中の留意点

ポイント①
会議中は自分の意見を話す場ではなく、
相手の発言を引き出す場であることを意識して。

質問は、何か意見ありませんか？ではなく、
具体的な質問の仕方を意識する。

事前に考えていた論点を参考にできるものがあるかも。
XXさん商品Aの品質について何か課題は感じていることはありませんか？
XXさん商品Aを売るにあたってお客様から頂いているお話とかありませんか？


ポイント②
話が出てきたら以下の行動を意識する。
①聴く
②発言を繰り返す
③自分の理解を確認する
　→主張の目的と主張の根拠を意識。
④参加者全員が理解するように繰り返す。

ポイント③
意見の対立が発生したときは、
それぞれの意見の「論点」を考えて
それぞれの論点で整理する。

------
論点とは、
メンバーから出てきた意見が答えになるような問いかけを考える

------

ポイント④
意見の対立は以下の観点を整理
　①認識の違い
　　→論点が異なる。
　　 論点を整理して、それぞれの論点に対して意見を求めるように促す。
　②解決策の違い
　　→それぞれのメリデメを整理して解決策を検討する。
　③判断基準の違い
　　→大事にしているポイントの違い。
　　 先に見据えているあるべき姿が異なっている場合がある。

ポイント⑤
会議の流れは以下を意識してファシリテート
　会議初期
　　会議に安心感を出して、発言しやすい雰囲気づくり
　会議中期
　　議論の対立から相互理解を導く
　会議終盤
　　団結した集団の形成
　　それぞれの立場で全員が協力的に動きあう形を形成

ポイント⑥
当初の到達点に達しそうにもないとき。
　無理に結論を出そうとしない。
　会議は一回で終わらない前提があるので、到達点は必達ではないことを忘れない。

　以下を整理して、次につなげることで、
　本当の最終目的までの道を作る。

　①合意できたこと、結論
　②合意できなかったこと
　　→合意に必要なことを明確に
　　ToDo：合意に必要な情報を整理して
　　　　　誰が、どうやって集めるかを定める


---------
最後になってしまいましたが、総括

ファシリテータの極意

自分の意見は述べる役回りではない、メンバー団結させて
最終的な目的に向けて、組織全体を動かすことが大事

---------
Git~作業管理と鍵~

Gitの概要がわかったところで、バージョン管理の流れを学習していきます。



#共有リポジトリー
共有リポジトリーとは、チーム開発を行う上での一番最初のリポジトリーとなります。
ここでは作業用フォルダなどはないシンプルな構造のもののことを言います。
リポジトリーってそもそも何だっけ？ソースコード等の管理対象を保存する場所をリポジトリーと呼びます！


#①作業ディレクトリー
こちらは、個人の作業用スペースになります。自由に使うことができます。

#②ステージングエリア
こちらは簡単に言うと、ファイルを一時的に置いとくとこです。ここに上げるだけでは、まだGitにアップしたことにはなりません。

#③リポジトリ
 1)リモートリポジトリ
　　専用のサーバーに複数人で共有することができるリポジトリです。
 2)ローカルリポジトリ
　　ユーザー一人が利用するためのリポジトリです。
　　基本的に個人でやってく場合はこのリポジトリです！
#公開鍵と秘密鍵
Git上で作業を進めていく中でソースコードが漏れるようなことはあってはいけませんね😅（よくコード漏洩とかありますね🥲）
そこで必要となるのが以下の２つです！
#公開鍵
公開かぎとは、そのプロジェクトに入るための鍵穴です。まずこれがないと入れませんので。

#秘密鍵
こちらは、先程の公開鍵の対になるものです。この鍵は、チーム開発に関わるユーザのみが持っていて、その暗証番号を入力することにより中に入ることができます。
開発者Aさんがプロジェクトの公開鍵を作ったとします。それをチームのB,C,Dさんに送ります。B,C,Dさんたちはそのプロジェクトに入るために秘密鍵を作り無事に入り、作業開始ってな感じです😊
[Rust] GitHub上にあるcargo.ioにないクレートを使用する(main branch ver.)

## TL;DR

GitHubのブランチが`main`になっており、cargoは指定しない場合は`master`を参照するため明示してあげる。

```toml
[dependencies]
name = { git = "https://github.com/sample", branch="main" }
```
ディレクトリをパスワード付きzipでアーカイブする

初めましてshoです。
シェルスクリプトの学習、練習メモです。

***内容「ディレクトリをパスワード付きzipでアーカイブする」***

詳細
　・アーカイブ名は日付で保存
　・引数にディレクトリ指定して実行
（※学習記録やメモ書き目的で始めました。ほぼ初学者レベルなので理解が浅いところや誤りがあるかと思いますがよろしくお願いします。またアドバイス等コメントいただけるとすっごく嬉しいです。）

#コマンド
zip（zipコマンドがインストールされていること前提）

（zipコマンドの使い方は　***"zip [オプション]　圧縮ファイル名　 圧縮対象ファイル"***

##使用オプション
-e　＝圧縮時にパスワードを設定できる
-r　＝ディレクトリを再帰的に圧縮する


#スクリプト

```

#!/bin/sh


date=`date "+%Y%m%d"`
zip -er "$date".zip "$@"

```

#実行結果
実行は　***”スクリプトファイル名　[対象ディレクトリ] [対象ディレクトリ]”***

```
#ls
dir1  dir2
#t-zipdir.sh dir1/ dir2/
Enter password: 
Verify password: 
  adding: dir1/ (stored 0%)
  adding: dir1/file2 (stored 0%)
  adding: dir2/ (stored 0%)
  adding: dir2/file2 (stored 0%)
  adding: dir2/file3 (stored 0%)
#ls
20210316.zip dir1 dir2
```

#解凍
解凍は　***unzip***　コマンドで解凍する。

```

#rm -rf dir1/ dir2/ （確認のためテストディレクトリを削除）
#ls
20210316.zip
#unzip 20210316.zip
Archive:  20210316.zip
   creating: dir1/
[20210316.zip] dir1/file2 password: 
 extracting: dir1/file2              
   creating: dir2/
 extracting: dir2/file2              
 extracting: dir2/file3         
#ls
20210316.zip dir1 dir2


```


以上です！
raspberrypi 3でWindowsアプリを動かしてみた

#### はじめに
raspberrypiでWindows用のアプリケーションを動かす必要がありました
wineを使用して動かすことも検討しましたが、直接Windowsを動かせるようにした方が使い勝手がよくなるのではと考え、Arm版のWindowsをインストールしてみることにしました
####方法
・Windowsのイメージファイルをダウンロードする
・イメージファイルを使用できるようにビルドする
・SDカードに書き込む
・立ち上げる
・Windowsの初期設定
・インターネットへの接続（ブリッジ接続）
・アプリケーションの実行

####使用機器
Windows10(note pc)
raspbery pi 3B+
LANケーブル（ネットワーク接続用）

####実際の手順
Arm版のWindowsをダウンロードします
[こちら](https://www.uupdump.net/)からOSをダウンロードしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/b49f30cb-5da2-6b89-5788-aee2c90bf646.png)
言語とエディションを選択してダウンロードします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/9bffc1ca-17c6-5bd5-2c11-c907c7800a70.png)
ダウンロードしてISOに変換するを選択して、create download packageをクリックしてダウンロードします

zipファイルでダウンロードされるので、すべて展開します
展開したファイルの中に、
uup_download_windows.cmd
というファイルがありますので、実行してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/dd9c4e04-cbb0-09ba-f6cd-112a7e4926e8.png)
このような画面が出ますが、詳細情報に入って実行します
変更を許可するかどうか聞かれますが、変更を許可するとコマンドプロンプトが開き自動で実行されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/9eef4ac7-b92e-c431-fbed-5d32c3772f00.png)
この実行には、少し長めの時間がかかりますので、気長に待ってください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/bdce2fbb-9ef2-ba11-128e-4013d87a1b59.png)
この処理はCPUのリソースをかなり使用するので、ある程度パワーのあるマシンで行うほうが良いと思います
処理が終わるとイメージファイルが作成されていますので、ファイルを探します
install.wim
という名前で作成されています

wimファイルとは、Windows Vista以降で導入されたインストールファイル形式であり、Windows OSを構成するファイルを1つにまとめて圧縮したアーカイブファイルのことです。

ここからはSDカードへの書き込みを行います
woa deployerというアプリケーションを使用する方法もありますが、今回はwindows on raspberypi imagerを使用して書き込みます
windows on raspberypi imagerは[こちら](https://www.worproject.ml/)からダウンロードしてください。
zipファイルでダウンロードされますので、すべて展開してexeファイルを実行します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/138b025f-3f69-b58f-cd23-9dd4f4116711.png)
アプリケーションが立ち上がったら、各種設定をして書き込みを行います
この時にストレージドライブの設定を間違うと大変なことになりますので注意してください。ドライバーやファームウェアは特にこだわりがなければ推奨設定を使用します。
設定もデフォルトで行います。
SDカードへの書き込みが終わったらraspberrypi本体にSDカードを入れて電源を入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/dcb3455b-d0dc-be02-d9b0-d62cc92aed0a.png)

rasbianが立ち上がって、次にWindowsが立ち上がります。
初回にWindowsを立ち上げるときは各種設定が必要になり、多少時間がかかります

Windowsが立ちあがるとデスクトップのWindowsと同じように使用することができます

私の場合はOSがWi-Fiを認識できていなかったので、イーサネットでネットワークに接続する必要がありました
LANケーブルでraspberrypiとPCを接続して、PC側のWindowsでネットワークの設定を行いブリッジ接続することで、無事にインターネットと接続することができました。

最初の目的であるアプリケーションの動作も確認することができました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/c88862bf-ad3e-4ddc-15a8-db0e0078139f.png)
####結果と考察
無事にraspberypi上でWindowsを動かすことができました
面倒な設定もなくWindowsアプリを使用することができて非常に便利です
この方法でWindowsを使用するときは動作がかなり緩慢になりますので、使用するアップリケーションは検討する必要はあると思います
Java Silver SE 11 合格体験記

新卒でweb系自社開発企業より内定をいただいており、どうやらJava言語による開発をしているぞということで、先ほど取得してきました。

大学では計量経済学による実証分析を専攻していたので、開発に対しては門外漢です。
研究でR使ってました〜程度です。

**使用教材**や**勉強方法**を以下に共有します。

# 使用した教材
- [徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=asc_df_4295007625/?tag=jpgo-22&linkCode=df0&hvadid=342700130622&hvpos=&hvnetw=g&hvrand=246222853093982832&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=20636&hvtargid=pla-830348236008&psc=1&th=1&psc=1)
- [黒本著者が教える やさしくない!? Java](https://www.youtube.com/channel/UC42DlV-0RDb6fJ8A3IbAang)

# 試験に向けた勉強
大学4年の春休みということで可処分時間が多く、いろいろなことに手を出していたので、少しずつ学習していました。
悪く言えばダラダラと。

## どういった勉強スタイルだったのか

なんもわからん状態から、黒本を一周しました。
**1日1-2章くらいを目安に学習。**
不明点はgoogleで調べて解決。
でもぜんぜんわからん。

**その後はひたすら復習。**
とはいえ、ちょうどこの時期は長編小説を読むことに拘っており、けっこうダラダラやってました。
当初は2週間での取得を目標にしていましたが、黒本に飽きてしまいガス欠してしまい、結局2週間をオーバー。

しかし、**2-3回の復習によりだんだんとJavaがわかってきた感じがして**なんとかモチベーションは維持。

この期間に巻末の実力問題にも手をつけました。

【巻末問題①正答率】
**1回目:50%程度
2回目:90%程度
3回目以降は不正解経験のある問題のみ演習。**

【巻末問題②正答率】
**1回目:65%程度
2回目:80%程度
3回目以降は不正解経験のある問題のみ演習。**

## 試験直前数日間
黒本**泣きのもう一周**を終えた後、黒本の**不正解経験のある問題をひたすら反復**しました。

やはり直前の勉強は効きます。

# 試験当日
身分証を2点持参し、テストセンターへ。
もうすぐ学生証が使えなくなるなあということで、運転免許証+学生証という手札で臨みました。

都内のテストセンターは初めての利用でしたが、やや混雑という印象。
職員の方に案内していただきPCにて試験を受けました。

持ち込み可能なものは身分証のみでした。
PCデスクには雑音遮断用の耳当てがありました。

目薬・ハンカチ・ティッシュなどの持ち込みについては特にアナウンスされませんでした。
基本情報技術者試験のCBT方式の試験では、上記の持ち物の持ち込みは許可されましたが、~~おそらくORACLE系の試験ではNGなのでしょう。~~(確認とってないんで正確な情報ではありません)

`追記`：Java Goldの受検も同様のテストセンターで受けたのですが、その際は申告すれば目薬等持ち込むことができました。公式の受験案内にもその旨が記載されていました。

だいたい**20分ほどの時間を残して試験終了**。
油そば喰らって帰りました。

結果は試験終了直後に表示されました。
正答率92%で合格です。💮

# 総括
入社前に一定の学習ができてよかったです。
次はJava Goldに向けて努力します。
Vue.jsの状態管理パターンVuex、Fluxアーキテクチャについてまとめてみた。

Vuexを学習してて理解しづらかったので、概念をざっくりとですが、まとめてみました。
##Vuexとは
Vue.jsアプリケーションのための状態管理パターン+ライブラリです。

####Vuexを使用せず末端のコンポーネントから末端のコンポーネントにデータを渡す場合
![スクリーンショット 2021-03-18 15.54.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/c4a6939a-7877-69ba-9dfb-bb81a13f1edf.png)
\$emitで親にデータをあげて、もう一度$emitで親に上げて、propsでデータを子供に渡し、もう一度propsで子供にデータを渡す・・・というように、コンポーネントツリーが深くなればなるほど、末端のコンポーネント同士のデータのやりとりがしづらくなります。

#####Vuexを使用した場合
![スクリーンショット 2021-03-18 16.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/c42d09f0-f75a-d85b-2800-8cdb33c4c333.png)
Vuexを使用することで、親コンポーネントにデータを渡して・・といったことをせずとも簡単にデータのやり取りができるようになります。



##Vuexのデータの流れ
![スクリーンショット 2021-03-18 12.23.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/f5e553d7-13ab-912a-6c00-e8143821e296.png)
VuexはFluxに影響を受けているライブラリで、データフローが単方向になるように設計されています。



##Fluxとは
Facebook社が提唱してるクライアントサイドのWebアプリケーション開発のためのアーキテクチャです。
**単方向のデータフローを構築することで、開発規模が大きくなってもデータの流れを見失いづらいこと**が特徴です。
※[この記事](https://medium.com/samyamashita/%E6%BC%AB%E7%94%BB%E3%81%A7%E8%AA%AC%E6%98%8E%E3%81%99%E3%82%8B-flux-1a219e50232b)に詳しいこと書いてます！


![flux-react-mvc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/7340283b-daad-b636-7f74-f9301f5b0549.png)
MVCを例に見ると小さなアプリケーションでは適していますが、大規模開発になるとデータの流れが追いにくくなりデバックしづらくなるデメリットがあります。

そこで単方向のデーターフローを設計することでデータの変更を追いやすくしてくれてるのがFluxです！
![flux-react.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/e71de67f-b021-7a40-f8e0-912d31775cae.png)

##感想
Fluxの記事を読んでVuexに関しての理解が深まったかなと思いました！
Vuexは個人で作るような小規模なアプリだと返って記述がコードが冗長になるなどデメリットもあるようですが、仕組みを理解するためにも使っていきたいなと思いました！！
Gitとは？？

今回はGitについて学習していきます。

#Gitとは？？
現場でのチーム開発に入ると必ず耳にするとおもいます。
Gitとは簡単にいうとバージョン管理システムです。
ではGitを使うことによって何ができるのか。

#①ファイルの変更履歴を管理することができる
チームで開発をしていると、誰が何をいつどんな感じに変えたのかを管理するのが難しくなります。大きいプロジェクトではなおさらわかりにくくなります。そこで便利なのがGitです。いつ誰がどこの箇所をどう変えたのかを追うことができ、チーム開発がより効率的に進めることができますね！

#②過去のファイルに戻すことができる
作業を進めていく中で、このファイルじゃなくて前のファイルに戻したいなってときがありますね。そんなときにGit上で管理していることで古いファイルを戻すことができるのです！

#③チームで共有することができる
チームで作業していると、一人ひとり作業内容が変わってきます。AさんはフロントAの部分を、BさんはフロントBの部分の作業をしているとしましょう、それを共有することが簡単に行うことができるのがGitです。また、セキュリティ面で考えてもGitで管理するほうが安全かもしれませんね！！（非公開鍵と公開かぎに関しては後に学習していきます）

ではこのGitは何を使うのか。
いくつか方法はありますが、CUIを使って行きます。
CUIってなに？？って思った方はこちらの記事を見てみてください！！
▶https://qiita.com/akari_0618/items/9e223f91e1cd0da82fcb
（備忘用）Sequelize周りのデバックいろいろ

# チェック項目

* findAllやfindOneなどGet系の処理にtransactionを張っていないか？
    * transactionはUpdate系の処理に張る

## case1. 複数のテーブルをUpdateする処理を実行したときにTimeoutする

* `show full processlist;`とかで実行しているSQLを確認する。

* Updateをかけるテーブルが重複していないかを確認する。
    * 重複している場合、どちらかのUpdateのWhereの条件に、`$ne`オプションなどでUpdateがかぶらないように調整する。（Whereの条件ではじけばかぶらない。）

``` js
// 例）
_update_table_a(id, transaction) {
  return db.test_table.update(
    {
      status: 1
    },
    where: {
      id: id
    },
    transaction
  )
}

_update_table_b(id, transaction) {
  return db.test_table.update(
    {
      status: 2
    },
    where: {
      id: id
      status: { $ne: 1 } // (sequelize option) XXX以外を抽出
    },
    transaction
  )
}
```

## case2. transactionを渡さないとfindAllできない

* 複数の処理を同時に実行している場合（例：複数のユーザーに対して同じ処理を実行する）、findAllとupdateの処理がかぶって、エラーになる場合がある。
    * PromiseAllで実行していたら、awaitで1つずつ動かす処理に変更を検討する。
Serializerとmodelの使い方について（def__str__）

今日やること
・　データベースの正規化の理解
・　models:def__str__(self)の理解

#def__str__(self)とは？

まず結論から言うと、
`def__str__(self)により、管理画面に表示されるモデル内のデータ（レコード）を判別するための、名前（文字列）を定義することができる。`

def__str__(self)がない場合、管理画面の表示から、データを判別することができないため、管理が難しい。

#models.pyでのdef__str__(self)設定方法
models.pyでのdef__str__(self)の設定方法の解説。

models.py内でモデル、フィールをの定義ができたら、そのモデル内に以下のように`def__str__(self)`を追記する。

```python:
class GooglePlace(models.Model):
    info = models.JSONField(null=True, blank=True)
    place_id = models.CharField(max_length=1000)
    latitude = models.FloatField()
    longitude = models.FloatField()
    def __str__(self):
        return self.info['name'] if self.info else self.place_id
```
ここではGooglePlaceモデル内にinfo, place_id, latitude, longitudeフィールドが設定されており、def __str__(self)内では、infoフィールドを返すようにしています。

もし、infoフィールドがない場合、place_idフィールドを返すように設定する。（応用）

このreturnで設定するフィールド項目が管理画面でそのデータ（レコード）を判別できるように表示されます。

#管理画面での表示
それでは管理画面でどのように表示されるのか見ていきましょう。

まず__str__(self)がない場合ですが、以下のように表示されるため、Postモデル内のデータを判別することができません。

![スクリーンショット 2021-03-18 15.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/4d548cb8-16bb-8d74-420b-888291559bff.png)


次に__str__(self)をmodels.pyに追記した画面です。
以下画面表示を見ると、Postモデルのタイトルフィールドが表示されているので、どのデータが何なのか判別が簡単になりました。

![スクリーンショット 2021-03-18 15.24.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/d1c04988-0e46-e4a5-b099-9c2e729e55aa.png)

こちらの方が断然見やすいですね！

#Serializer
SerializerのなかにSerializerのフィールドを入れる.

次に勉強していくのはSerializerについてです。

以下のようなSeriaizerがある場合、リシアライジングされたクラスを次のようにして変数に格納することができる。

```python
class PostImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PostImage
        fields = ['id', 'url']


class PostSerializer(serializers.ModelSerializer):
    images = PostImageSerializer(source='postimage_set', many=True)
    class Meta:
        model = Post
        fields = ['id', 'user', 'google_place', 'type', 'permalink', 'message', 'ig_id', 'images']
```
sourceで定義した引数はFieldの引数に指定され、そのFieldに入るシリアライズされたデータの値に属性を指定できます.

#serializers.SerializerMethodField()

次に`serializers.SerializerMethodField()`について学んでいく
これはget_xxxとなっているメソッドをコールするフィールドである。

例えば、

```python
class GooglePlaceSerializer(serializers.ModelSerializer):
    image = serializers.SerializerMethodField()
    class Meta:
        model = GooglePlace
        fields = ['id', 'info', 'place_id', 'latitude', 'longitude','image']
    
    def get_image(self, obj):
        post_image = PostImage.objects.filter(post__google_place=obj).order_by('-id').first()
        if not post_image:
            return ''
        return post_image.url
```
Serializerのフィールドを動的に決めたい！！
SerializerMethodField がありますが、これは実際に動的に作成したい値を定義するフィールドです。 get_{フィールド名} として定義されているメソッドをコールします。 これらは共に出力専用属性です。

`serializers.SerializerMethodField()`を使うことにより,methodの結果によってフィールドの値を決めることができる。
Warning: You have unlinked kegs in your Cellar.の解消方法

# 概要

```console:terminal
[ユーザ]MacBook-Pro:~ [カレントディレクトリ]$ brew doctor
```

上記のように実行した際に、以下の[Warning]が発生しました。
今回は、その解消方法を投稿します。

# エラーの内容

```console:terminal
[ユーザ]MacBook-Pro:~ [カレントディレクトリ]$ brew doctor
Please note that these warnings are just used to help 
 the Homebrew maintainers with debugging if you file an issue.
If everything you use Homebrew for is working fine:
 please don't worry or file an issue; just ignore this. Thanks!

Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-trouble and cause brews that
 depend on those kegs to fail to run properly once built.
Run `brew link` on these:
  composer

```

大体こんな感じに解釈しました。

> 以下の様なWarningは、
> 何かしらの問題が発生した時に、Homebrewが行うデバッグを補助するためのものです。
> もし、Homebrewが正常に動作しているのであれば、このwarningは無視してください。
> 
> warning: Cellarにリンクされていないkegs(homebrewでインストールしたもの)があります。
> linkされていない状態が続くと、そのkegsと依存関係にあるbrew(package)の管理に、
> 不備をきたし、正常に動作させることができなくなります。それなので、
> `brew link` commandを実行し、以下のkegsのリンクを貼り直してください。
>　　composer

#解消方法

以下の様なコマンドを実行し、解消しました。

```console:terminal
[ユーザ]MacBook-Pro:~ [カレントディレクトリ]$ brew link --overwrite composer
Linking /usr/local/Cellar/composer/1.9.0... 1 symlinks created
```

`--overwrite` optionは、既存のリンクを上書きしてリンクを貼ることを意味する。

※　このoptionを付けないで実行した際に、`--overwrite`を付けるようにエラーが出たので、
　　付けました。
Polymorphism with Interfaces

https://play.golang.org/p/ojRqAxy5JYm

https://medium.com/technofunnel/polymorphism-with-golang-interfaces-b2f58a05b221

# work

```
package main

import (
	"fmt"
)

type Test interface{
	Run()
//	Debug()
}

type My struct{
	body string
}

func (m My)Run(){
	fmt.Println(m.body)
}

func main() {
	my :=  &My{body: "DOOOOOOOO"}
	fmt.Println("Hello, playground")
	testRun(my)
}

func testRun(t Test){
	t.Run()
}

```

↓

```
Hello, playground
DOOOOOOOO
```


# Error

```
package main

import (
	"fmt"
)

type Test interface{
	Run()
//	Debug()
}

type My struct{
	body string
}

func (m My)Run(){
	fmt.Println(m.body)
}

func main() {
	my :=  &My{body: "DOOOOOOOO"}
	fmt.Println("Hello, playground")
	testRun(my)
}

func testRun(t Test){
	t.Run()
}

```

↓

```
./prog.go:23:9: cannot use my (type *My) as type Test in argument to testRun:
	*My does not implement Test (missing Debug method)

```
2020/10以降のherokuへのpushについて。

なんてことはないのですが、gitの仕様変更に伴って起きたエラー。


## %git push heroku masterが使えなくなってしまった

### 遭遇したエラー
```
error: src refspec master does not match any
error: failed to push some refs to 'git@github.com:user-name/repository-name.git'

```

###???

2020/10以降、gitで自動生成するとmasterブランチではなく、mainブランチができることによるエラーでした。

```
%git push heroku main
```

とすることで無事通りました。
React入門(props)


#propsの渡し方

- 親クラスは`Blog.js`

- 子クラスは`Article.js`

```react:Blog.js
import React from 'react';
import Article from './Article';

class Blog extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <>
        <Article title={"React"} />
      </>
    )
  }
}

export default Blog
```


```react:Article.jsx
import React from 'react';
const Article = (props) => {
  return (
    <div>
      <h1>{props.title}</h1>
    </div>
  )
};

export default Article;
```
親クラスから`<Article title={"React"} />`を受け取って
子クラスで`props.title`を表示する


#おまけ
```
＄ create-react-app アプリ名
$ npm run build　//buildフォルダー生成
$ npm start //起動
```
- `npm run build` srcとpublicをまとめて出力する
テストコード一覧　@narimiya

#この記事について
サービスの品質を保つために必要不可欠なテストを実施しており、その実施内容についての記事を作成しております。

テストについて今まで記事にしてきた内容を、1つの記事にまとめてみました。

今後もテストは実施して参りますので、内容を追加・更新していきます！！

よろしければご参考ください。今後ともよろしくお願いします。

#テスト一覧

RSpecの導入からテスト実施するまでの手順書

https://qiita.com/narimiya/items/4fa4ee9a19935eba3b94

##単体テストコード

https://qiita.com/narimiya/items/8ec3cdc15b1134b04dce

https://qiita.com/narimiya/items/8876a9c43ec26ad65fd4

https://qiita.com/narimiya/items/301dd9a10f32e0061cff

https://qiita.com/narimiya/items/708023931f4590901f42

https://qiita.com/narimiya/items/a0595d237bf1185f8f4b

https://qiita.com/narimiya/items/11429a0064383fb177ee

https://qiita.com/narimiya/items/6f6a7d1d383d57512d06

##結合テストコード

https://qiita.com/narimiya/items/22d52976ee848c6952c4

https://qiita.com/narimiya/items/45a4561349f1039a9a65

https://qiita.com/narimiya/items/fa458dde5621f733ea06

https://qiita.com/narimiya/items/477e30fe9a3aeb747282

https://qiita.com/narimiya/items/13c7a9c3fe28e72ebaaa

https://qiita.com/narimiya/items/90500f984afd74b97f91

https://qiita.com/narimiya/items/53a956a265b99c58c309

https://qiita.com/narimiya/items/a22fdaf1ab71fb638b19

##その他

https://qiita.com/narimiya/items/819cc9acbeeff0210ce8

https://qiita.com/narimiya/items/1e4df7d2b31e566342cb

以上です。
ROSの画像メッセージをmapに格納する方法

## 経緯
ROSの画像メッセージを一定量格納しておきたいな、と思うことがあったので、その方法を共有します。

## やり方
C++のmapを使って画像データを格納します。注意点としては、**画像メッセージはImageConstPtr型ではなくて、Image型を格納するという点です。**最初、ImageConstPtr型で格納していたのですが、mapの格納した中身がすべて同じデータだったので、Image型を格納するようにしました。
以下がサンプルコードです。

```sample.cpp
std::map<int, const sensor_msgs::Image> stock_rgb;

void callback(const sensor_msgs::ImageConstPtr& rgb_msg) {
  // Stock rgb image
  int stock_id = std::stoi(rgb_msg->header.frame_id);
  stock_rgb.emplace(stock_id, *rgb_msg);

  int get_id = std::stoi(yolo_msg_.header.frame_id);
  sensor_msgs::Image get_rgb = stock_rgb.at(get_id);
}
```
この場合は画像のframe_idをkeyにして、画像メッセージを格納しています。取り出すときは、keyをもとにatを使えば取り出せます。格納するときにinsertを使うと、なぜかうまくいかなかったので、emplaceを使っています。mapについては[こちら](https://qiita.com/_EnumHack/items/f462042ec99a31881a81)の記事が詳しかったので参考にしました。

## まとめ
ImageConstPtrとImageでたまに混乱する。
【ABAP】PARAMETERS の変数名を変更する方法

> この記事は、ＳＡＰＧＵＩ７．５の環境について書かれています。
> 最新のＳＡＰ製品には該当しません。

# PARAMETERS とは
　ABAPには、プログラム実行者が任意の値を入力できる**選択画面**があります。
　**PARAMETERS**はそんな選択画面の１つで、主に変数の値を入力する際に使用されます。

こんな感じ↓↓

```abap:sample
PARAMETERS:
  TEXT(10) TYPE C,
  DETA TYPE D.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792942/ac412bae-e405-bba0-893a-821d4cb72df0.png)

この項目名を日本語で表示したい！


# 表示される変数名を任意に設定する

　**コーディングで設定はしません。**
　こちらの記事を参考にしました。[oknoblog-ABAP PARAMETERS](https://oknoblog.com/%E3%80%90abap%E3%80%91parameters/)
　PARAMETERS について詳しく書かれてあります。おすすめです！

### 選択シンボルの手順
 ジャンプ > テキストエレメント > 選択テキスト
![image.png](https://oknoblog.com/wp-content/uploads/2020/10/e9e76ed73600962358390c53af614046-1.png)
上のタブ 選択テキスト をクリック
対象の変数に表示テキストを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792942/21ffe888-838c-12d0-18eb-30aec7abd5a2.png)
入力後は忘れずに有効化をしましょう！

### 結果
再度実行してみると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792942/69cb34a6-55ad-7b83-b48b-1faafa0cfac4.png)
これでOK
Google Maps API




https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037


https://www.javadrive.jp/google-maps-javascript/

# 請求先アカウントの登録を忘れない事
https://developers.google.com/maps/documentation/javascript/error-messages?utm_source=maps_js&utm_medium=degraded&utm_campaign=billing#api-key-and-billing-errors
[SQLite3 + ruby] テーブル名とカラム名を取得する 



SQLite3をターミナルから操作すればテーブル名やカラム名は取得できます。
SQL文も調べればすぐ出てきますから、覚えるかメモしておけば問題はないでしょう。
ただ、もう少しお手軽にdbの中身を知りたいと思い、rubyで組んでおきます。
そうすることで、SQL文を忘れてもファイルの移動と実行だけなので楽になるかなと思いまして。

## 準備(rubyでSQLite3を扱う)
rubyでsqlite3を操作するためにデータベースオブジェクトを取得します。

```ruby
db = SQLite3::Database.new('ファイル名.db')
```

このオブジェクトに対して .execute(sql) で操作します。

```ruby
db.execute(xxxxxx)
```

xxxxxxのところにSQL文が入ります。

## テーブル名の取得
SQLでは下記の文でテーブルについての情報を取得することができます。

```sql
SELECT * FROM sqlite_master
```

rubyでは下記のようになります。

```ruby
tbls_info = db.execute('SELECT * FROM sqlite_master')
```

tbls_infoには配列が入ります。
配列の中には、さらに配列が入っています。配列の中に配列がある形ですね。
下記の５つの情報が入った配列が、テーブルの数だけ配列としてまとめられています。

1. type
1. name
1. tbl_name
1. rootpage
1. sql

今回はテーブル名を取得しますので、２番目の要素を抜き出します。

```ruby
tbls_info.each do |tbl|
  p tbl[1]
end
```

まとめると

```ruby
  require 'sqlite3'
  db = SQLite3::Database.new('ファイル名.db')
  tbls_info = db.execute('SELECT * FROM sqlite_master')
  tbls_info.each do |tbl|
    p tbl[1]
  end
  db.close
```

## カラム名を取得する
SQLでは下記の文でカラムについての情報を取得することができます。

```sql
PRAGMA table_info('テーブル名')
```

rubyではdb.execute(xxxxxx)を使います。

```ruby
cols_info = db.execute('PRAGMA table_info(テーブル名)')
```

カラムの情報も配列の配列で返ってきます。

1. cid
1. name
1. type
1. notnull
1. dflt_value
1. pk


２番目の要素にカラム名が入っているのでそれを出力します。
また、この処理にはテーブル名が必要なので、上記で取得したテーブル名を使います。

```ruby
  require 'sqlite3'
  db = SQLite3::Database.new('ファイル名.db')
  tbls_info = db.execute('SELECT * FROM sqlite_master')
  tbls_info.each do |tbl|
    p tbl[1]
    cols_info = db.execute("PRAGMA table_info(#{tbl[1]})")
    cols_info.each do |col|
      p col[1]
    end
  end
  db.close
```

## ファイル名の取得も含める
ファイル名を取得して、テーブル名とカラム名を表示します。

```ruby
require 'sqlite3'

def get_name_table(db)
  db.execute('SELECT * FROM sqlite_master').map{|e| e[1]}
end

def get_name_column(db, tbl_name)
  db.execute("PRAGMA table_info(#{tbl_name})").map{|e| e[1]}
end

Dir.glob('*.db').each do |fn|
  SQLite3::Database.new(fn) do |db|
    puts "[#{fn}]"
    get_name_table(db).each do |tbl_name|
      ar = get_name_column(db, tbl_name)
      puts "  #{tbl_name} (#{ar.join(' + ')})"
    end
    puts '-' * 36
  end
end
```

上記のファイルを実行すれば、同じディレクトリにある拡張子が.dbのファイルについて、テーブル名とカラム名をSTDOUTで表示します。

## 終わり
rubyもdbも勉強中です。
間違いがありましたらご指摘をお願いします。
また、全体的に拙いものですし、こうした方がいいよ的なものがありましたらご指摘いただければと思います。
文字コード関係


EXCELでtext形式で保存したら、perlファイルの読み込みでエラーになったので、調べてみると文字コードがあっていないと、コントロールコードとして読み取られてしまう模様。
fileの種類を調べて確認し、nkfを使ってperlのデフォルト文字列(UTF-8 BOMなし)に変換して読みむことで解決

# linux

## ファイルの種類を調べる

### file

```
$ file url*
urllist-utf.txt:  Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
urllist-utf8.csv: UTF-8 Unicode (with BOM) text, with CRLF line terminators
urllist-w80.txt:  UTF-8 Unicode text, with CRLF line terminators
urllist.csv:      UTF-8 Unicode (with BOM) text, with CRLF line terminators
urllist.txt:      Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
urllist.xlsx:     Microsoft Excel 2007+
```

## 文字コード変換

### nkf


```
$ nkf -w80 urlist.csv
```


オプション	文字コード
-j	ISO-2022-JP
-s	Shift_JIS
-e	EUC-JP
-w8	UTF-8 (BOMあり)
-w80	UTF-8 (BOMなし)
-w16	UTF-16 BE (BOMあり)
-w16B	同上
-w16L	UTF-16 LE (BOMあり)


参照 : [[Linux] 文字コードを変換する](https://blog.katsubemakito.net/linux/convert-character-encoding)
オブジェクト指向 Perl

まだ組んでみてないけど、わかりやすい解説。

[簡単！オブジェクト指向Perl](http://www15.plala.or.jp/h-kihara-home/prog/ooperl.html)



[perltoot - トムによる Perl オブジェクト指向チュートリアル](https://perldoc.jp/docs/perl/5.14.1/perltoot.pod)
WHFのメンタル管理


いまのところ単なるメモ

[在宅勤務の部下を襲う「コロナうつ」上司が取るべき4つのサポート](https://www.armg.jp/journal/141-2/)
[新型コロナウイルスによる不安やストレスなどの心の問題に対処するために](https://www.counselor.or.jp/covid19/covid19column10/tabid/516/Default.aspx)


[｢無駄な仕事｣を減らし効率よく働くための4ステップ](https://www.lifehacker.jp/2021/03/231194say-no-to-improve-productivity-matome.html?fbclid=IwAR1i3hFPJMDlOFMJjjZCFbiDcTGW857lhT48dR1hVXYKScCKvfh7sfPDg3I)
JCenterシャットダウンの影響調査中にハマった罠


BintrayやJCenterがシャットダウンされることになり、[jcenter, bintray 廃止で自分のAndroidアプリに対応したことのメモ](https://qiita.com/takke/items/67a7f21cdcec0f13d7c8)を参考に調査していた際に、jcenterにだけ存在するライブラリが含まれていても、エラーにならないことがあったので、原因を調査しました。

## jcenterの参照が外れない原因
担当しているアプリでは[groupie](https://github.com/lisawray/groupie)(移行してくれ頼む〜〜:bow:)を利用しているため、jcenterの依存を除外するとエラーになる想定でしたが、エラーになりませんでした。

```diff:jcenterの除外
repositories {
    mavenCentral()
    google()
-    jcenter()
}

```

```shell:実行してもエラーにならない.
$ ./gradlew assemble --refresh-dependencies

・・・

BUILD SUCCESSFUL in 1m 45s
36 actionable tasks: 36 up-to-date
```

最初に実行した時には、jitpackも利用していることかと思いましたが、jitpackを外しても参照が外れないため、少し調べるとStack Overflowにこんな記事を見つけました。

https://stackoverflow.com/questions/57628529/disable-jcenter-repository-in-gradle

どうやら**gradleプラグインが、jcenterレポジトリへの依存を追加する場合**があるようです。

## 対応方法
上述したStack Overflowを参考に、jcenterリポジトリを追加するプラグインを見つけるスクリプトを作り対応をしました。


```gradle:リポジトリを追加するプラグインを見つけるスクリプト
allprojects {
    repositories.all {
        if (url.host == 'jcenter.bintray.com') {
            new Throwable('jcenter repository was just added').printStackTrace()
        }
    }
}
```

このスクプリトを`./gradlew --init-script init.gradle help`で実行すると下記のようなエラーが表示されます。

```shell
java.lang.Throwable: jcenter repository was just added　
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
・・・
        at io.realm.gradle.Realm.apply(Realm.groovy:59)
        at io.realm.gradle.Realm.apply(Realm.groovy)
・・・
```

エラー内容から、推測出来るプラグインをコメントアウトして、再度`./gradlew assemble --refresh-dependencies`を実行すると期待通りにエラーが表示されました。

```shell
> Could not resolve all files for configuration 
         project :app
   > Could not find com.xwray:groupie:2.9.0.
     Required by:
         project :app
   > Could not find com.xwray:groupie-kotlin-android-extensions:2.9.0.
     Required by:
         project :app
   > Could not find com.xwray:groupie-databinding:2.9.0.
     Required by:
         project :app
   > Could not find com.google.android.exoplayer:exoplayer-core:2.13.1.
     Required by:
         project :app
   > Could not find com.google.android.exoplayer:exoplayer-hls:2.13.1.
     Required by:
         project :app
   > Could not find com.google.android.exoplayer:exoplayer-ui:2.13.1.
     Required by:
         project :app
```

### 最後に
今回この挙動を踏んでしまい、jcenterのシャットダウンの影響調査で少し困りました。
もしかしたら同じような罠にハマる方もいるかと思うので、一度影響調査してみてはいかがでしょうか。
【python:エラー】socket.error: [Errno 48] Address already in use

#対処法



```bash:bash
//以下のコマンドでプロセスIDを検索
ps -fA | grep python
// killする
kill processID
```




写真↓

![スクリーンショット 2021-03-18 15.22.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/2f1a8985-61ea-1013-0099-b83617bbd062.png)
【3層目：ネットワーク層】IPの基本的役割とは

##IPの役割

主な役割は、アドレスの管理と経路の選択。
つまり、終端のノード間における通信を実現する役割を担っている。

IPはOSI参照モデルのネットワーク層に該当する。TCP/IPの核ともいえる

ネットワーク層の下位層に位置するデータリンク層は、同一の直接リンクされたノード間での通信を行う。ネットワーク層がデータリンク層を制御し、パケットを送ることで、同一の直接リンクされていないコンピュータ間での通信が可能となる。

**用語**

* ノード：ネットワーク接続されている終端のコンピュータなどの機器を指す。
* TCP/IP：IPとTCPのふたつのプロトコルを指すのではなく、多くの場合は、IPを利用したり、IPで通信をするときに必要となるプロトコル群の総称として用いられる。
* OSI参照モデルは、あくまでモデルで通信の役割をそれぞれ概念的に理解しやすいようにしたもの。詳細なプロトコルの定義がされているわけではない。


##なぜネットワーク層とデータリンク層が分かれているのか

データリンク層：直接つながった機器での通信をおこなう。
ネットワーク層：直接接続されていないネットワーク間の通信を行う。

データリンクは、パソコンA～ルーターA、ルータA～ルータB、ルータB～パソコンBのように1区間で有効ごと（1区間を１ホップという。今回は3ホップで到達している）。
そしてネットワーク層は、そのデータリンクの区間ごとの通信で最終的にどこに行くかという全体の流れを司っている。

旅行で例えると、A駅からX駅に行きたい。というとき、その時の経路A駅、B駅、C駅で乗り換えてX駅に着くというときは、A駅からB駅までの1区間ごとに届ける役割がデータリンクであり、その全体の行程を制御して最終的にX駅まで到着するという目的を達成させるのがネットワーク層であるIPの役割である。

**IPは複数のデータリンク間の通信を実現するプロトコルである。**

##IPアドレスについて

インターネットに接続されるホストやルータは、必ずIPアドレスを設定しないといけない。IPアドレスの形式は、どのデータリンクでも全く同じ形式であり、ユニークでなければいけない（オンリーワン）。

データリンク内でもMACアドレスが使われている。これは、同一のリンク内つまり、LAN内で識別するために使われる。

##ルーティング（経路制御）

IPでもっとも重要な役割。これがあるから、地球のどこにいても目的の場所でデータを送ることができる。

####終点までのパケットはどう送られるか

IPではホップバイルーティングという方法が、利用されている。それは、行き当たりばったり（英語では"Ad Hoc"）と呼ばれている。

データ送信元のコンピュータは、送信先はどこかわかるがその送信先への経路はわからない。

ルータも全体でどのような経路かはわからないが、一つ先の経路までわかるようになっている。

ルータで逐一行先を告げることで、途中までの経路（1ホップ先）を教えてくれる。それが繰り返されていくことで、届けたい先に情報を届けることができる。

![ip.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162957/eebde2dc-df1e-e065-7ad5-ab19055c927c.jpeg)

すべてのルータは、経路制御表(ルーティングテーブル)という情報を持っている。
この表のおかげで、ＩＰパケットを次にどのルータへ送ればよいのかという情報がわかる。

![network.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162957/2173a30c-e62d-e396-f436-853457b48cdc.jpeg)

##フラグメンテーション（分割化処理）

データリンク間の通信を実現するプロトコルであるIPは、それぞれのデータリンクの違いを感じさせない抽象化する仕組みがある。
その一つが、最大転送単位（ＭＴＵ:Maximum Transmission Unit）である。データリンクごとに異なるものであり、データの大きさである。1度の通信での最大の大きさである。EthernetやFDDIなどのデータリンクごとに異なっている。
具体的には、イーサネットでは、1500バイト。FDDIでは、4352バイトとなっている。

IPの上位層は、このMTUよりも大きなデータを要求するかもしれない。そんな時は、フラグメンテーションを行う。

フラグメンテーションは、送るパケットを複数の小さなパケットに分割して、宛先のホストで再び1つにまとめられてIPの上位層に渡される。

IPの上位層からは、データリンクでのデータサイズの違いに関係なく、まとまった1つのデータが届くことになるので、上位層はネットワークの細かい構造を気にしなくてもよくなっている。

##コネクションレス型のIP

通信相手との間にコネクションの確立を行わない。
一方的にデータを流す。
コネクションレス型のデメリットは、
相手がいなくてもデータを送れる。
データを取りこぼしてしまう可能性がある。
以上のことから無駄が多くなる可能性がある。

しかしながら、機能の簡略化と、高速化をコネクションレス型は実現可能なのである。
通信するたびにコネクションを確立すると、そのたびにコネクション確立のための通信を行うので、処理速度の低下につながる。

IPは、信頼性が低いので、信頼性の高い通信を行う必要があるときは、ネットワーク層の上層であるトランスポート層においてTCPのプロトコルを用いて通信の信頼性を高い通信を行えるようにしている。

#####参考
マスタリングTCP/IP

データリンクやMACアドレスについてわからない人は以下を参考にしてください。

https://qiita.com/iyoshiha/items/cfaf984cb56d1277f8ae

TCPやコネクションについては、以下を参考にしてください。

https://qiita.com/iyoshiha/items/4e6c677f7473dc1eedb5
アプリからFinderを使ってファイル、またはディレクトリのパスを取得する

#注意
超雑ですごめんなさい。

# 対象
Flutterを使ってmacosようのアプリを作りたい人

# 概要
Flutterを使い、macos向けソフトウェアを開発する際、Finderを使って選択したファイルのパスを取得したい。で、これをどうやるか。
(イメージとしてはvscodeのメニューバーのファイルから「開く」を押した時のような感じ)

# 結論
Flutterのpluginを作ってswiftのコードを呼び出す

```swift
let dialog = NSOpenPanel();
dialog.showsResizeIndicator    = true;
dialog.showsHiddenFiles        = false;
dialog.allowsMultipleSelection = true;
dialog.canChooseDirectories = true;

let launcherLogPathWithTilde = rootPath as NSString
let expandedLauncherLogPath = launcherLogPathWithTilde.expandingTildeInPath
dialog.directoryURL = NSURL.fileURL(withPath: expandedLauncherLogPath, isDirectory: true)

if (dialog.runModal() ==  NSApplication.ModalResponse.OK) {
    let result = dialog.url
    if (result != nil) {
      let path: String = result!.path
          return path
    } else {
      // canncelled
      return nil
    }
} else {
   return nil
}
```
(動けばいいので適当)

# 本文
ファイルのみ、ディレクトリのみを選択する場合は、[公式のプラグイン](https://pub.dev/packages/file_selector)を使用すればよい
こちらを使えば、Finderが開き、ファイルのみ、ディレクトリのみのパスを取得できる。
なお、選択していない方は開けない。
ファイルのみ -> ディレクトリを選択できない。
逆も


今回は、vscodeの「開く」を想像していただきたく、ファイルでもディレクトリでも選べるような(Finderで開くボタンを押せる)ものを作りたい。

```> flutter create -t plugin --platforms=linux,macos,windows NAME```
これでデスクトップ向けプラグインのテンプレートが作れる。
example/にはアプリから呼び出す例が記述されてる。
lib/にはdart-swift間のクッションコードがある。
macOS/にはswiftのコードと、podspec(?)がある　<- ここのFILE.swiftをいじる
linux/にはヘッダーファイルがある <- linuxで何かしたい時はこっち

### 注意
アプリを動かす際、アプリ側のentitlementsにcom.apple.security.files.user-selected.read-writeを追加しておかないと起動できない。

この記事で登場する[ソースコード](https://github.com/x0y14/openFileDialog)
【Google API】OAuth認証時に毎回refresh_tokenを発行する

## はじめに

Google APIのOAuth認証時に毎回refresh_tokenを発行したい場合があると思います。
refresh_tokenは、下記の条件以外で2回目のOAuth認証時に受け取ることができません。受け取れない理由は、すでに発行したrefresh_tokenを再利用することを想定しいてるからです。

■[アクセストークンの有効期限の条件](https://developers.google.com/identity/protocols/oauth2#expiration)

- ユーザーが アプリのアクセスを取り消しました。
- 更新トークンは6ヶ月間使用されていません。
- ユーザーがパスワードを変更し、更新トークンにGmailスコープが含まれています。
- ユーザーアカウントが、付与されたアクセストークンの最大数を超えました。

## 結論

リクエストの認証パラメータに`prompt=consent`を設定します。
このパラメータを設定することでOAuth認証時に毎回`同意画面`が表示され、ユーザーが許可ボタンを押下すると、refresh_tokenを取得することができます。

こんな感じのリクエストです↓

```
https://accounts.google.com/o/oauth2/auth
?client_id=hogehoge
&redirect_uri=http://localhost
&scope=https://www.googleapis.com/auth/drive
&response_type=code
&access_type=offline
&prompt=consent
```

promptは、2回目の同意画面の関して制限できるオプションです。
■[promptの設定可能な値](https://developers.google.com/identity/protocols/oauth2/web-server#creatingclient)

|  値  |  説明  |
| ---- | ---- |
|  none  |  認証画面や同意画面を表示しないでください。他の値と一緒に指定してはなりません。  |
|  consent  |  ユーザーに同意を求めます。  |
| select_account | アカウントを選択するようにユーザーに促します。 |
【Vue】コンポーネント名は大文字あり？それとも小文字のみ？（命名規則まとめ）

Vueのコンポーネントをタグで呼び出す時に、大文字のパスカルケースを使っている場合と、小文字のケバブケースを使っている場合があったので、使い方を確認してみた。

##コンポーネントを呼び出す状況
コンポーネントの呼び出しは、（１）コンポーネントをグローバル登録する場合と（２）コンポーネントをモジュールとしてimportする場合が考えられる。


##コンポーネントをグローバル登録する場合
Vue推奨はW3Cのカスタムタグ命名規則に則った**ケバブケース**（小文字。ハイフンでつなぐ)。

```js:コンポーネント名(MyCompName.vue)
Vue.component('my-comp-name', { /* ... */ })
```

　↓ 呼び出し

```vue:
<my-comp-name />
```

###大文字（パスカルケース）
推奨は小文字のケバブケースだが、パスカルケースも使える。

タグ名として呼び出すときは、**ケバブケース（小文字）**でも**パスカルケース（大文字）**でもどちらでもいい。


```js:コンポーネント名(MyCompName.vue)
Vue.component('MyCompName', { /* ... */ })
```

　↓ 呼び出し

```vue:
<my-comp-name />

<MyCompName />
```

コンポーネント名を大文字にして、呼び出しを小文字にした場合に違和感があるが問題ない。



<br>
##コンポーネントをモジュールとしてimportする場合
importするときは、モジュール名は大文字（パスカルケース）を使う。ケバブケース（ハイフンでつなぐ）は使えない。

・`import モジュール名 from ファイルパス`

必然的に、`component`で定義する名前もパスカルケースになる。

```vue:.vue
<script>
 import MyCompName from ./MyCompName

 expoert default {
   components:{
     MyCompName
   }
 }
</script>
```

　↓　呼び出し

タグ名で呼び出すときは、**ケバブケース（小文字）**でも**パスカルケース（大文字）**でもどちらも使える。

```vue:
<my-comp-name />

<MyCompName />
```


<br>
タグ名で、ケバブケースの`<my-comp-name />`が出てきたら、`MyCompName`か`my-comp-name`のコンポーネントが使われている。



##命名規則一覧

| 名前 | 例 | 意味 |
|:--|:--|:--|
| ケバブケース  | my-comp-name  | ケバブ（焼き鳥のような食べ物）で串刺しで繋げる  |
| スネークケース  | my_comp_name  | ヘビが地を這うようにつなげる  |
| キャメルケース  | myCompName  | ラクダのコブ。スタート地点山ではない  |
| パスカルケース  | MyCompName  | 冒頭大文字。Pascalというプログラミング言語で使われていた。  |


`パスカルケース` = `アッパーキャメルケース`
`キャメルケース` = `ロワーキャメルケース`
予防接種実施計画の作成等の状況のPDFをCSVに変換

https://twitter.com/kantei_vaccine/status/1372048125687332865

[変換後のxlsxファイル](https://docs.google.com/spreadsheets/d/e/2PACX-1vQJxZC2h60oJPDSun4Ym4XBTCtlcB2sWg1Ar12tzed7gaFPcHhKpiIN7N2oD7CI-GY-8y7sL2RyZ9on/pub?output=xlsx)

修正箇所

※ 市町村が長い
426 ひたちなか市
435 かすみがうら市
440 つくばみらい市
813 南アルプス市
831 富士河口湖町
1369 山陽小野田市
1673 いちき串木野市

※ 計画のステータスが「接種会場など」->「接種会場等、」
795 鯖江市

※公表日が長い
640 目黒区　

※シミュレーション実施日が長い
1219　田原本町

```
wget https://www.mhlw.go.jp/content/000754414.pdf -O data.pdf
pip install pdfplumber
```

```python
import pdfplumber
import pandas as pd

table_settings = {
    # 垂直基準
    "vertical_strategy": "lines_strict",
    # 水平基準
    "horizontal_strategy": "lines_strict",
}

with pdfplumber.open("data.pdf") as pdf:

    dfs = []

    for page in pdf.pages:

        table = page.extract_table(table_settings)

        df_tmp = pd.DataFrame(table)

        dfs.append(df_tmp)

df = pd.concat(dfs)

df1 = df.copy().fillna("").astype(str)

df2 = df1.applymap(lambda s: "".join(s.split()))

df2.to_csv("data.csv", index=False, header=False, encoding="utf_8_sig")
```
pip install時にERROR: Could not install packages due to an OSError: [Errno 5] Input/output errorが出た

#はじめに
Python, pipでrequirements.txtを使ってパッケージ一括インストール
https://note.nkmk.me/python-pip-install-requirements/
を試みた際、表題のエラーでハマったので、備忘録として対処法を書き残しておきます。


#環境
Windows 10 Home
Docker 19.03 
```docker run -d -it --mount type=bind,source="$(pwd)",target=/app nginx:latest```
にて作成したコンテナ内で行いました。

#コマンドとエラーメッセージ
```
# pip3 install --user -r requirements.txt
Collecting tensorflow==2.4.0
  Downloading tensorflow-2.4.0-cp37-cp37m-manylinux2010_x86_64.whl (394.7 MB)
     |████████████████████████████████| 394.7 MB 10.4 MB/s eta 0:00:01ERROR: Could not install packages due to an OSError: [Errno 5] Input/output error
```

#原因と対処
ググるとRAMの不良などが原因との記事が出てくるのですが、
https://askubuntu.com/questions/65830/errno-5-input-output-error-when-trying-to-install-ubuntu
私の環境ではWindowsのボリューム不足が原因であり、不要なファイル削除により解決しました。

ちなみに、Dockerがボリュームを圧迫している場合には、以下の方法で消しましょう。
Macの記事ですが、Windowsでも利用できます。
https://qiita.com/shinespark/items/526b70b5f0b1ac643ba0
🧚‍♂️ブラウザ上でLaravelを実行する環境を作ったよ→Tinkervel🧚‍♂️

# [Tinkervel](https://tinkervel.com/)
というサービスを作りました！

![スクリーンショット 2021-03-18 14.25.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180411/d69d4e2f-1718-f935-7254-aa6b694a1384.png)


ブラウザ上でPHP製フレームワークのLaravelが動きます！
どうやって動いているか？については[こちら](https://zenn.dev/mikkame/articles/4926b4b3c0c58d)で

## 対応している機能

- [x] Laravelのヘルパー、Illuminateクラスなどの実行
- [x] モデルなどの定義 
- [x] データベース（SQLite）の使用
- [x] マイグレーション 
- [x] コードの共有

## 対応していない機能

- [ ] 外部へのアクセス（踏み台防止）
- [ ] HTTPアクセス（デーモンの禁止）

## これから対応する機能

- [ ] View関連の機能
- [ ] シンタックスハイライトの改善


### [laravelplayground](https://laravelplayground.com/) でよくね？

ごもっともです！リサーチ不足でした！かぶったものはしょうがないので差別化していきます！
ingressのログの正規表現を作ってみた

以下のフォーマットでingressのログがデフォルト出力します
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/log-format/

```
log_format upstreaminfo
    '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
    '$request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr '
    '$upstream_response_length $upstream_response_time $upstream_status $req_id';
```

これの正規表現を作ってみました。
うまくいっているかどうかはまだ検証中ですが、ご参考程度に


ログはこんな感じで出力されます

```
2021-03-09T05:56:19+09:00	{"message":"2xx.1xx.xx.xx- - [08/Mar/2021:20:56:19 +0000] \"GET /config/hoge?index=0 HTTP/1.1\" 400 256 \"-\" \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0\" 354 0.000 [] [] - - - - b6f884a586112950a00000d6bdea058b"}
```


作った正規表現

```
^(?<time_key>[^ ]*)\t*\"(?<host>[^ ]*) (?<blank>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] \\"(?<method>\S+[^\"]) (?<path>[^\"]*?) (?<protocol>[^ ]*) (?<code>[^ ]*) (?<size>[^ ]*) \\"(?<referer>[^ ]*)\\" \\"(?<agent>[^\"]*)\\" (?<request_length>[^\ ]*) (?<request_time>[^\ ]*) (?<proxy_upstream_name>[^\ ]*) (?<proxy_alternative_upstream_name>[^\ ]*) (?<upstream_addr>[^\ ]*) (?<upstream_response_length>[^\ ]*) (?<upstream_response_time>[^\ ]*) (?<upstream_status>[^\ ]*) (?<req_id>[^\"]*)
```

参考）
正規表現を作るのに便利
https://regex101.com/
markdownに目次を生成する方法

markdownにドキュメントを書いていて目次を作ろうとしたとき何か楽にできる方法はないかな？と思って探してたどりついた方法をメモしておきます。

## 目次生成ツール「doctoc」

__doctoc__　https://github.com/thlorenz/doctoc


なお、使い方の参考にさせていただいた記事はこちらです↓
[Markdownに目次\(TOC\)を表示させる \- tsunokawaのはてなダイアリー](https://tsunokawa.hatenablog.com/entry/2016/04/21/144537)

## 使い方

* 次のコマンドを実行してdoctocをインストールする
   * `npm` を使います

```bash
npm install -g doctoc
```

* markdownの目次を入れたいか所に以下を挿入する

```md
<!-- START doctoc -->
<!-- END doctoc -->
```

* markdownのディレクトリに移動してから、次のコマンドを実行して目次を生成する
  * 「README」のところは対象のmarkdownのファイル名を指定します

```bash
doctoc README.md --github
```

* リスト形式で目次が生成されます
* 見出しが増えたり減ったり変更になった利した場合は、再度上記コマンドを実行することで更新されます
ibmcloudコマンドの自動補完を有効化する方法

LinuxやMacではこれだけ。
https://cloud.ibm.com/docs/cli?topic=cli-shell-autocomplete

```shell
$ source /usr/local/ibmcloud/autocomplete/bash_autocomplete
$ echo "source /usr/local/ibmcloud/autocomplete/bash_autocomplete" >> ~/.bash_profile
```

これで、`ibmcloud`のところでTabを押すと以下のように候補がでたり、補完される。

```
[root@syasudacentos7 ~]# ibmcloud
account          cfee             cs               gt               key              login            region-set       service
api              cis              dev              help             key-ring         logout           regions          sl
app              cloud-functions  dns              iam              key-rings        network          registrations    target
billing          config           enterprise       import-token     keys             oc               resource         update
catalog          cos              fn               instance         kp               pi               sat              version
cf               cr               functions        is               ks               plugin           security         wsk
```