OmniAICreator/Qiita-1.07M huggingface dataset:
Javaにおけるインターフェースについて

 <h2>Javaにおけるインターフェースとは</h2>
→「定義が曖昧すぎて、特別扱いされた抽象クラス」のこと。
例：Creature(生き物)クラス
→形、生態はさまざま。
　　生きるために、「run(逃げる)」くらいしかできない。

<br>
<b>＊特別である理由＊</b>
・内部実装（メソッドの処理動作）を一切定義しない
→同じ階層の親メソッド同士がぶつからないため、<font color = red >多重継承OK</font> とされている。

<h4>特徴</h4>
①すべてのメソッドが、抽象メソッドであること
②フィールドは基本的に持たない
③もし、インターフェース内でフィールドを宣言すると、自動的に「public static final」が補われ、定数を宣言したことになる
④多重継承OK
⑤defaultを用いれば、抽象メソッドの実装が可能(java8〜)　→ 実装がぶつかる恐れがあるので、基本的にはしない
⑥インターフェースに宣言されたメソッドは、自動的に「public」かつ「abstract」になる。　→「public abstract」は省略OK

※abstract = このクラス（メソッド）は抽象クラス（メソッド）ですよ、という意味を表す

<h4>正しい継承ツリーを上に辿っていくと起こる現象</h4>
抽象メソッドが現れる
→抽象メソッドばかりになる
→抽象メソッドが減りはじめる
→抽象メソッドだけになる　＝　インターフェース

インターフェースは、クリーニング店のメニューみたいなもの。
ユーザーには、どのようにして洗うか明示されない。

<h4>インターフェースの宣言</h4>
```
public interface インターフェース名 {
 //anycode
}
```

<h3>インターフェースの実装について</h3>
・インターフェースで定義されたメソッドは、全て抽象メソッドなので、
　それぞれオーバーライドする必要がある
・具体的な処理内容を実装する

※オーバーライド：親クラスのメンバを子クラスで上書きすること

<h4>インターフェースの実装</h4>
```
public class クラス名　implements インターフェース名 {
 //anycode
}
```
※implements ＝　実装する

<h4>インターフェースの効果</h4>
・同じインターフェースをimplementsする複数の子クラスたちに、共有のメソッド群の実装を強制できる
・インターフェースが定めたメソッドを、共通で持たせることができる

<h3>インターフェースによる多重継承</h3>
```
public class　クラス名 implements 親インターフェースA , 親インターフェースB　{
 //anycode
}
```

<h3>インターフェースの継承</h3>
<h5>親インターフェース　Creature　</h5>
```
public interface Creature {
   public abstract void run();
}
```
<h5>上記の Creatureインターフェースを継承した、Humanインターフェース</h5>
```
public interface Human exetends Creature {
   void walk();
   void eat();
  //さらに、親インターフェースからrun()を継承する
```


<h2>まとめ</h2>

<h4>抽象クラス</h4>
・具体的な中身を決定できない曖昧なメソッドには、「abstract」をつけて、抽象メソッドとする
・抽象メソッドを一つでも含むクラスは、「abstract」をつけて、抽象クラスにしなければいけない
・抽象クラスは、インスタンス化不可
・抽象クラスと抽象メソッドを活用した「継承の材料」として、親クラスを開発すれば、イレギュラーなインスタンス化やオーバーライドを忘れる心配がない

<h4>インターフェース</h4>
・抽象クラスのうち、基本的に抽象メソッドしか持たないものを「インターフェース」として定義OK
・インターフェースは、多重継承OK
・インターフェースを親に持つ、子クラスの定義は、「implements」を使用する
Kotlinについて徹底的に客観的に分析してみた

先日開催されたJJUG CCC 2021 Fallにて『Kotlinを研究する』というタイトルで発表しました。
その中でいくつか面白さを感じていただけそうな部分をピックアップして紹介していきたいと思います。

# 元発表

**スライド**
https://speakerdeck.com/doyaaaaaken/kotlinwoyan-jiu-suru

**動画**
https://youtu.be/T6cS67VEGO4

# 内容概要

現状のKotlinについて徹底的に客観的に分析した内容になります（そういった背景から”研究する”というタイトルにしました）。
基本的には発表は個人的な見解として行うものですが（例：『Kotlinの拡張関数という機能はイケてる！』）、世の中の公開データを元に2021年末現在のKotlinについてなるべく主観を排除して分析してみたら有用な知見になりそうだと感じこのテーマにしました。

# ピックアップポイント

## 1. Kotlinは2016年にv1リリースされた若い言語

他のモダンな言語であるRustやGoよりも後発。
[Goは2012年](https://go.dev/blog/go1)、[Rustは2015年](https://blog.rust-lang.org/2015/05/15/Rust-1.0.html)にv1をリリース。

## 2. 若い言語なのにも関わらず言語仕様として新しい発明はほぼない

Kotlinが新しく発明した機能・概念はごくわずか。
モダンな他の言語の良い点を取り入れ言語仕様が作られ、”Pragmatic”な言語を目指している（※後述）。

## 3. "Pragmatic（実用的）"という言語思想

**Pragmatic（実用的）**な言語を目指して作られており、他のモダンな言語の良いところを取り入れ、簡潔で安全に書けるようにしている。
エレガントさより、有用さを重視している。

”実用的”というのはコーディング中だけでなく開発者体験全体を指しており、例えば以下のような点にも気を使って開発されている。

* Javaとの相互互換性（＝Javaプロジェクトに混ぜられるため少しずつ置き換えができる）
* Javaの既存エコシステム（例：Javaライブラリ, Maven, Gradle）を利用可能
* IDEを使った開発者体験（補完・警告等）を重要視
* 学習コンテンツなどを用意・拡充している

## 4. 2017年のGoogle I/Oが転機で普及した

2017年のGoogle I/OでAndroidの開発言語としてサポートすることが発表され、それを機に一気に普及した。
（なおちょうどその2年後に、GoogleがAndroidの開発言語としてKotlinを第一言語として推奨する発表をした）

## 5.Android開発では現在支配的な地位を確立

Android公式ドキュメントによると、上位1,000件のAndroidアプリの80%以上にKotlinコードが含まれているそうです。

## 6. Android開発以外にもサーバサイド開発でも広く使われている

元々Jetbrains（KotlinやIntelliJを作ったチェコの会社）が社内のJavaアプリケーション（IntelliJなど）コードを置き換えていく用にKotlinを発明しただけあって、グローバルではAndroidに次いでサーバサイド開発でも広く利用されている模様。

ちなみに日本だと[Newspicksさんがサーバサイドの主要言語をJavaからKotlinに置き換えたり](https://tech.uzabase.com/entry/2021/09/15/154445)した事例が2021年にありました。
他のサーバサイドKotlinの国内事例は[こちらの記事](https://qiita.com/ptiringo/items/dd734ab8064f94139294)にもまとまっているようです。

## 7. 現在はコンパイラの書き直しや、Multiplatform対応を進めている

言語仕様としてはもう成熟しているので、現在はコンパイラの書き直しによるパフォーマンス向上や、Multiplatform対応（JVM以外のプラットフォームでも動かせるようにする対応）に注力している。

# まとめ

以上、発表内の重要な点をまとめてみましたが、ぜひご興味わいた方は元スライドのほうもご覧いただけますと嬉しいです！
それでは皆さん、よいクリスマスを！
Linuxコマンドを用いたシンボリックリンクの作り方

シンボリックリンクとは
-
他のファイルやフォルダを参照するためのショートカットのようなもの（というかwindowsOSのショートカットとほぼ同じ）です。

同じような意味合いの用語として`ハードリンク`というものもあり、場合によっては`フォルダはシンボリックリンク`、`ファイルはハードリンク`という使い分けがなされることもあるようです。

ただ、どちらに対するショートカットも同じコマンドで作成可能という性質上、本記事ではまとめてシンボリックリンクとして扱います。

コマンド
-

```shell
# ln -s リンク元の絶対パス リンクの作成先のパス
% ln -s /var/www/html/dir1/test.html /var/www/html/dir2
# dir2の中にtest.htmlへのリンクが作成される
% ls /var/www/html/dir2
>> test.html
```

注意点
-
リンク先の作成先のパスは相対・絶対のいずれでもOKです。

リンク元に関しては絶対パスしか受け付けないので注意してください。
sbt が cannot be cast to class xsbti.FullReload で起動しない

sbt を起動する際、以下のようなエラーが表示されました：

```log
[error] [launcher] error during sbt launcher: java.lang.ClassCastException: class java.util.concurrent.TimeoutException cannot be cast to class xsbti.FullReload (java.util.concurrent.TimeoutException is in module java.base of loader 'bootstrap'; xsbti.FullReload is in unnamed module of loader 'app')...
```

## よくある（？）原因

自分が経験した事象はおそらく特殊なケースですので、まず一般的な情報を記載します。

sbt の GitHub リポジトリに [#6592](https://github.com/sbt/sbt/issues/6592) という issue があり、`cannot be cast to class xsbti.FullReload` が発生するケースが投稿されています。

issue で報告された問題は順次解消されているようなので、まずは sbt を最新版に上げてみることをお勧めします。

## 経験した事象

起動に失敗するプロジェクトは、[VSCode の dev container](https://qiita.com/yokra9/items/351b9847c5f1e49a215c) 上で開発していました。

そのディレクトリをエクスプローラー経由で Windows から WSL2 に複製し、 WSL2 上の sbt を起動したところ、上記のエラーが発生しました。`target` 等の自動生成されるディレクトリを削除して再試行してみましたが、状況は変わりません。

問題の切り分けのため、WSL2 上にシンプルなプロジェクトを新規作成したところ、問題なく起動できました。そのため、原因はプロジェクト固有だと考えられます。

## 根本原因

プロジェクト配下の一部ディレクトリで所有者が `root:root` になっており、権限が不足していました。試しに、`sudo` を付けて無理やり実行すると起動することが確認できました。

```bash
sudo -E sbt
```

このような場合、`chown` で実行ユーザに所有者を変更すると起動できるようになります。

```bash
cd ../
sudo chown -R <ユーザ>:<グループ> <対象ディレクトリ>
cd <対象ディレクトリ>
sbt
```

パーミッション関係というありがちな事象なのですが、エラーメッセージから原因が特定しづらいため記事としてまとめることにしました。ご参考になれば幸いです。

## 参考リンク

* [java.lang.ClassCastException: class java.util.concurrent.TimeoutException cannot be cast to class xsbti.FullReload #6592](https://github.com/sbt/sbt/issues/6592)
* [sbtの密結合な内部アーキテクチャ](https://xuwei-k.hatenablog.com/entry/20131211/1386755890)：「そもそも `xsbti` って何？」という部分が分かりやすく解説されています。
自動車の品質管理からエンジニアになってみて

## はじめに
未経験からエンジニアに転職して、現在はフリーランスエンジニアとして活動しています。
エンジニアになった経緯などを書きますので、エンジニア転職を検討している方の参考になれば幸いです!

⬇️僕の経歴です

|年月|所属|
|---|---|
|2018/04~2020/04|自動車会社(新卒入社)|
|2019/05~2019/10|Progate, Railsチュートリアルで独学|
|2019/11~2020/02|ポテパンキャンプ|
|2020/04~2021/10|受託会社で正社員|
|2021/11~|自社開発会社でフリーランス|

ポテパンキャンプについてはこちらをご覧ください！
[ポテパンキャンプ - Webエンジニア輩出No1プログラミングスクール](https://camp.potepan.com/ga?sfid=0017F000024AzFwQAK)

## 1. 前職の内容
前職の自動車メーカーでは、海外の自動車のリコールなどを扱う品質管理の部門にいました。

品質管理といっても実際に、製品を扱ったり、図面を書いたりするわけではなく、
海外のお客様・研究所・部品メーカーの間に入って、スケジュールの調整を行う中間部門でした。

具体的には下記のような仕事の流れでした。

お客様から訴えがある
➡️ 過去に同じ問題がないかをデータで調べる
➡️ 同じ問題が多発していれば、研究所・工場や部品メーカーに原因追及・部品の修正を依頼
➡️ 問題が深刻な場合、リコールを実施する

### 前職を通して...
マイナスをゼロに戻すのが仕事だったので、いろいろ大変でしたが、
各地の工場や部品メーカー、海外出張に行けたのは良い経験だったと思います。

新卒一年目から、研究所や部品メーカーのお偉いさんたちがいる会議を進行していたので、
社会人としての基本的なマナーや年上の方を相手にする度胸はつきましたが、
今後活かせるスキルはあまり身についていない感じがしました。

また、10年以上先輩の社員の方も同じ仕事内容だったため、
このまま仕事を続けていても、仕事の幅は広がりにくいのも薄々感じていました。

## 2. エンジニアになろうと思ったきっかけ

憧れだった会社に入社できたので、一生懸命仕事をしていましたが
入社してから1年くらい経つと、下記を感じるようになってきました。

- 基本は年功序列なので、仕事を頑張っても評価されにくい
- 希望の部署に行きにくい
- 勤務地、仕事内容、給料が会社に決定される


このまま仕事を続けていても問題はないかもしれないですが、
「この先、何十年同じような仕事を続けていいのか？」と疑問を抱くようになりました。

<img width='200' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497683/1edfbe36-b458-6aad-9520-b12051e8aff3.png'>


### エンジニアに興味を持つ

それから、副業や転職についていろいろ調べていると、
エンジニアの情報をよく見かけ、エンジニアという職業に興味を持つようになりました。

そして、知り合いからフリーランンスとして活動しているエンジニアの方を紹介して頂いて、
実際に話を聞く機会を頂きました。

話を聞いてみると、

- 自分のスキルが評価される
- フリーランスでも案件は多い
- 会社に依存せず仕事ができる

ということがわかったので、エンジニアになることを決意しました。
そしてMacbookを購入し、ProgateやRailsチュートリアルでプログラミングを勉強しました。

### ポテパンキャンプを受講

ある程度独学で継続できたので、本格的にエンジニア転職を視野に入れ、プログラミングスクールを検討しました。
プログラミングスクールは数多くありますが、

- オンラインで受講できる(地方在住だったため)
- 現役エンジニアからのレビューを受けられる
- 転職サービスがついている

という特徴から**ポテパンキャンプ**の受講を決意しました。
そしてポテパンキャンプのカリキュラムも終えて、無事に受託会社に転職が決定しました！

<img width='200' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497683/29a36c21-316f-251b-025f-bcc13bdf47e0.png'>


## 3. エンジニアとして働いてみた感想（前職と比べてどう変わったか）
### 転職先での経験
転職後は1~2ヶ月の研修をしてから案件に配属になりました。
受託会社だったため、複数の案件に関わり、下記の経験を積むことができました。

- Railsを用いたAPIサーバーの開発
- React, Typescriptを用いたフロントの開発
- AWSを用いたインフラ構築
- SwiftでのiOSアプリ開発

### エンジニアになってみて...
そして、ここがみなさんが一番気になるところだと思いますが、
僕は未経験から**エンジニアに転職して本当に良かった**と感じています！！

エンジニア(特にフリーランス)になって

- 前職と異なり、会社に依存しないスキルが身についた
- 勤務地、仕事内容、給料を自分で決められるようになった
- Webアプリを作れるようになった

上記のように大きく変わりました。

特に、会社に依存しないスキルが身についたのは本当に良かったと思っています。
スキルがあればキャリアや生活環境を自分で決めることができるので、幸福度は上がりました。


## 4. 今後はどんなエンジニアを目指したいか
今後は下記のようなエンジニアになりたいなと思っています！

#### スキル面
- インフラ側もより詳しくなりたい(アプリ全体を把握したい)
- Go言語で開発したい
- サーバーレス開発をしたい

#### キャリア面
- より上流工程から関われるようになりたい
- エンジニアになりたい方を応援、サポートしたい

## 最後に
2年間挑戦し続けた結果、目指していた働き方・ライフスタイルを手に入れることができました。
キャリアチェンジを通して、確かに辛い時期はありましたが、エンジニアになって本当に良かったと思います。

エンジニア転職に悩んでいる方は、挑戦してみる価値はあると思うので、ぜひ挑戦してみてほしいです！
そしてプログラミングスクールを探している方は、ぜひポテパンキャンプを検討してみてください！
無料カウンセリングもありますので、一度ご覧になってみてください！
[ポテパンキャンプ - Webエンジニア輩出No1プログラミングスクール](https://camp.potepan.com/ga?sfid=0017F000024AzFwQAK)


この記事を通して、少しでも挑戦するきっかけになれば幸いです。
最後まで読んで頂きありがとうございました！
【TypeScript】KDTreeで最近傍探索

# KDTree

k次元ユークリッド空間中の点を分割するデータ構造であり、近傍探索に非常に有効です。今回は平面（k=2）の場合で実装を行います。

## KDTreeを用いた近傍探索アルゴリズム
探索木の深さに応じてxまたはy座標を閾値と比較して二分探索の要領で走査します。x,y座標の大小比較だけで済むのは普通にユークリッド距離が計算できるからですが、少し一般化すれば以下のような疑似コードで表現できます。

```ts
function kd-search(root: Node){
  var result = [] // 目的の近傍点のリスト
  search(root, result)
}

function search(node: Node, result: Array<Point>){
  result.push(node.point)
  result.sort // 距離計算
  var next1 = (最初に探索する子ノード) // node.left or node.right 
  search(next1, result)
  var next2 = (先ほど探索しなかった方の子ノード)
  if (next2に存在するかもしれない点との距離の最小値) <= (resultの距離の最大値) {
    search(next2, result)
  }
}
```

**ポイント**

- より近傍点がありそうな方を`(最初に探索する子ノード)`として上手く選択する  
    `next1`を上手く選択できれば`next2`の方の探索が不要となりより高速な探索が可能となります。
- `(next2に存在するかもしれない点との距離の最小値)`を適切に計算する  
    厳密な最小値を計算するのが難しい場合は、最小値以下の値（下限）で代用できます。ただし、適当に小さい値を渡すと不要な探索が増え計算時間が増大するので注意。

# 実装
## KDTree の構築

平面$(x,y)$上の点を木の深さに応じてxまたはy座標の大小で繰り返し二分割することでKDTreeを構築します。今回は話を単純にするため、すべてのデータが事前に与えられると仮定して平衡な二分木を最初につくっておきます。動的なデータに対応するには適切な平行二分探索木の実装が別途必要です。

```ts
interface Point2D {
  x: number
  y: number
} 

/**
 * 頂点自身がひとつの座標点をもつ
 * - left には自身より小さい座標点
 * - right には自身より大きい座標点が含まれる  
 * 座標点 Point2D の大小はは頂点の depth によって x,y 座標の大小で比較する
 */
interface SearchNode extends Point2D {
  depth: number
  left?: SearchNode
  right?: SearchNode
}

function getComparator(depth: number): Comparator<Point2D> {
  if (depth % 2 === 0) {
    return (a, b) => (a.x - b.x)
  } else {
    return (a, b) => (a.y - b.y)
  }
}

function buildTree(points: Point2D[]): SearchNode {
  return buildSubTree(points, 0)
}

function buildSubTree(points: Point2D[], depth: number): SearchNode {
  points.sort(getComparator(depth))
  const mid = Math.floor(points.length / 2)
  const p = points[mid]
  cons n: SearchNode = {
    x: p.x,
    y: p.y,
    depth: depth
  }
  if (mid > 0) {
    n.left = buildSubTree(points.slice(0, mid), depth + 1)
  }
  if (mid + 1 < points.length) {
    n.right = buildSubTree(points.slice(mid + 1, points.length), depth + 1)
  }
  return n
}
```

## KDTree による探索
```ts
interface MeasuredPoint extends Point2D {
  dist: number // 探索の中心点からの距離
}

interface EuclideanSearch {
  node?: SearchNode // 現在の探索対象
  query: Point2D // 探索の中心点
  k: number // k個の近傍点を探す
  result: MeasuredPoint[] // 近い順にソート
}

function searchEuclidean(state: EuclideanSearch) {
  const node = state.node
  if (!node) return
  const pos = state.query
  const d = measure(pos, node) // 普通のユークリッド距離
  state.result.push({
    x: node.x,
    y: node.y,
    dist: d,
  })
  state.result.sort((a,b) => a.dist - b.dist)
  while (state.result.length > k) state.result.pop()
  
  // 深さに応じてxまたはy座標で大小比較
  const compareX = (node.depth % 2 === 0)
  const threshold = compareX ? node.x : node.y
  const value = compareX ? pos.x : pos.y
  searchEuclidean({
    ...state,
    node: value < threshold ? node.left : node.right
  })
  // ここでは最小値を直接計算せず下限で代用
  // (探索しなかった方に存在するかもしれない点と点posの距離の最小値) 
  //   >= (点posと閾値thresholdが表す直線との距離)
  const dist2th = Math.abs(value - threshold)
  if (dist2th <= state.result[state.result.length - 1].dist) {
    searchEuclidean({
      ...state,
      node: value < threshold ? node.right : node.left
    })
  }
}
```
RaspberryPi Picoに液晶モジュールを付けて使ってみた

https://qiita.com/Toshiaki0315/items/dca96c71fee2c06ea325

の続き

# 色定義

液晶に色付きの表示をするために色コードを作ろうとサンプルコードを確認すると、色の設定は以下のような値になっていました。

```python:
        self.red   =   0x07E0
        self.green =   0x001f
        self.blue  =   0xf800
```

よく見ると普通のRGB888やRGB565だと

|色|コード(RGB888)|コード(RGB565)|
|---|---|---|
|red|0x00ff0000|0xf800|
|green|0x0000ff00|0x07e0|
|blue|0x000000ff|0x001f|

になるはずなのに、ソースコードだと以下のような16進で定義されていて2進に直すと以下のような並びでした。

|色|コード(16進)|コード(2進)|
|---|---|---|
|red|0x07e0|0000011111100000|
|green|0x001f|0000000000011111|
|blue|0xf800|1111100000000000|


並びと情報量を考えるとBRG565になりますね。
色のデータというとRGBやYMC、或いはYUVは扱ったことがあったのですが、BRGは初めてでした。

ということで、RGB888のデータをR/G/Bに分解して以下の式に入れてBRG565のデータを使って色を表示しました。

```python:
# Convert RGB888 to BRG565
brg = ((blue & 0xf8) << 8) | ((red & 0xfc) << 3) | (green >> 3)
```

色々と色データを使って表示させてみましたが、色が濃い感じでイメージした色にならなかったです。(^^;;

# キー入力

サンプルコードだと、無限ループでPINをポーリングしている形だったので割り込みを使ってキー入力をとる形のコードに変えてみました。
キーに対応しているPinを作成して、そのPinに割り込みハンドラを設定しています。

ちなみに割り込みハンドラなどの情報は参考にしています。

https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.Pin.html


```python:割り込みハンドラの設定処理
    keyA = Pin(15,Pin.IN,Pin.PULL_UP)
    keyB = Pin(17,Pin.IN,Pin.PULL_UP)
    keyX = Pin(19 ,Pin.IN,Pin.PULL_UP)
    keyY= Pin(21 ,Pin.IN,Pin.PULL_UP)
    
    up = Pin(2,Pin.IN,Pin.PULL_UP)
    down = Pin(18,Pin.IN,Pin.PULL_UP)
    left = Pin(16,Pin.IN,Pin.PULL_UP)
    right = Pin(20,Pin.IN,Pin.PULL_UP)
    ctrl = Pin(3,Pin.IN,Pin.PULL_UP)
    
    keyA.irq( handler=lambda t:sample(keyA, 208, 15, LCD.blue) )
    keyB.irq( handler=lambda t:sample(keyB, 208, 75, LCD.red) )
    keyX.irq( handler=lambda t:sample(keyX, 208, 135, LCD.green) )
    keyY.irq( handler=lambda t:sample(keyY, 208, 195, LCD.yellow) )
    up.irq( handler=lambda t:sample(up, 60, 60, LCD.purple) )
    down.irq( handler=lambda t:sample(down, 60, 150, LCD.cyan) )
    left.irq( handler=lambda t:sample(left, 15, 105, LCD.black) )
    right.irq( handler=lambda t:sample(right, 105, 105, LCD.black) )
    ctrl.irq( handler=lambda t:sample(ctrl, 60, 105, LCD.black) )
```

# 矩形描画

プログラムの処理としては、サンプルと同じようにキーが押されたら対応した場所に矩形を描くというものです。
サンプルプログラムでは矩形は全部赤でしたが、ある程度色を変えるようにしてみました。

```python:色の設定
        self.red     =   0x07e0
        self.green   =   0x001f
        self.blue    =   0xf800
        self.purple  =   0xffe0
        self.cyan    =   0xf81f
        self.yellow  =   0x07ff
        self.white   =   0xffff
```

矩形の描画の処理もまとめてみました。

```python:矩形描画
def draw_block(x, y, color):
    LCD.rect(x, y, 30, 30, color)

def draw_fill_block(x, y, color):
    LCD.fill_rect(x, y, 30, 30, color)

def clear_block(x, y):
    LCD.fill_rect(x, y, 30, 30, LCD.white)

def sample( p, x, y, color ):
    print( p.value() )
    if p.value() == 0:
        draw_fill_block(x, y, color)
    else :
        clear_block(x, y)
        draw_block(x, y, color)
    LCD.show()
```

これで、キー入力の制御と矩形の描画ができたので、テトリスなんかが作れそうな気がする。w
Mac デフォルトのPythonを3系しようとして反映されない時

# はじめに
macOSにデフォルトで搭載されているPythonの実行環境を３系へ変更したのに、ターミナルを新たに開いて確認するとまだ2系になっている。。。

なんてことはよくあることかと。。。

そんな時に参考にしていただければ幸いです:disappointed:


# 環境
・macOS Big Sur

・ターミナルのシェルは**zsh**

・Homebrewはインストール済み

・pyenvはインストール済み

# pyenvの設定としてパスを通す
## 確認

```console
$ pyenv -v
```

でpyenvが入ってるか確認してみましょう。
もし`pyenv: command not found`が出た場合は、記事最後の「参考」をご覧ください:sweat:

## パスを通す

```console
% echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc    
% echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
% echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.zshrc
```

echoコマンドを利用せず`.zshrc`ファイルをテキストエディタで開いて編集してもOKかと！（多分）
どちらにせよ、`.zshrc`ファイルは👇のようになります。

```tex:.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi
```

変更を反映させる

```console
$ source ~/.zshrc
```

![スクリーンショット 2021-11-27 13.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/b31914df-bcef-f130-bf44-ef491e6c5ce1.png)

# Pythonのインストール
pyenvを使ってPythonをインストール

```console
$ pyenv install --list
```

でインストール可能なバージョンを確認できます。
今回は「3.6.0」のPythonをインストールします！

```console
$ pyenv install 3.6.0
```

現在インストールされているPythonを一覧で確認すると、3.6.0が確認できます。

```console
$ pyenv versions
* system (set by /Users/gen/.pyenv/version)
  3.6.0
```

ただ、まだこの状態では`3.6.0`ではなく、Macに標準でインストールされているバージョン（つまり２系）のPythonを使用してしまいます。

```console
$ pyenv global 3.6.0
```

👆のコマンドで、今回インストールしたバージョンのPythonを使用するように設定を変更しましょう！

```console
$ pyenv versions
  system
* 3.6.0 (set by /Users/gen/.pyenv/version)
```
お、次はちゃんと「3.6.0」に`*`がついてる！！
**「3系」のPythonを使えるようになりましたか？？:heart_eyes:**

```console
$ python --version
Python 2.7.16
```

:unamused::unamused::unamused::unamused::unamused::unamused::unamused:

**いや、変わってないやんけ！！！**

# `.zprofile`にも編集が必要だったっぽい？

![スクリーンショット 2021-11-27 13.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/bc1eb8ad-9540-b6d3-4949-1f6f3664e240.png)

https://gallard316.hatenablog.com/entry/2020/11/24/185634




```tex:.zprofile
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
```

変更を反映させる

```console
$ source ~/.zprofile
```


```console
$ python --version
Python 3.6.0
```

よくわからんが、これでglobalでも反映できた！！:laughing:

# 参考

https://commte.net/7259

https://prog-8.com/docs/python-env
メモ：nodejsでGraphQLを返すサーバをexpress-graphqlで

[ここ](https://dev.classmethod.jp/articles/graphql-tutorial-nodejsexpress/)とか[ここ](https://circleci.com/ja/blog/introduction-to-graphql/)とか見ながらテスト。
とはいえ何処に採用するのかは要検討で、内部アプリケーション同士なら良いが外部公開はシェアの高いRestにする、といった方が今はいい気がする。
（データ連携ツールとかでもアダプタが用意されていなかったりするし）

WindowsServer2012+nodejs 16.x

# node.jsの準備
まずはnode.jsで使う分をインストール

```
npm install graphql express express-graphql -save
```

どうせならPostgresと連携させたいので、pgとかも入れておいた。
pool.jsは以前作ったものを流用。

```javascript
const express = require('express');
const app = express();
const dbpool = require('./pool.js');
const expressGraphql = require('express-graphql').graphqlHTTP;
const { buildSchema } = require('graphql');
const port = 3000;

var pgSelect = {
    text: 'SELECT id,name from test where id=$1',
    values: [0],
}

// GraphQL schema
// クエリとしてはidを指定するuserを作成する。返り値はidとnameのセット
// ここで複数指定する事が出来る。
// スキーマ指定で!を使う事で必須とする事も出来る
var schema = buildSchema(`
 type Query {
 user(id: Int!): User
 },
 type User {
 id: Int
 name: String
 }
`);

// これはDB検索をして、1行目を返すファンクション
var getUser = async function(args) { 
	const reqid = args.id;
	pgSelect.values = [reqid];
	try{
		result = await dbpool.tx(async client => {
			const res1 = await client.query(pgSelect);
			return res1;
		});
	} catch(err) {
		return;
	}
	//console.log(result);
	return result.rows[0];
}

// GraphQL Root resolver
// ここでuserクエリではgetUserファンクションを利用するという指定。ファンクションの引数にはクエリが入る
var root = {
 user: getUser
};

// Create an express server and a GraphQL endpoint
// /graphalというアドレスに対して、先ほど作成したスキーマとリゾルバを利用する指定を行う
// graphiqlをtrueにすると次のクエリのテストを画面で出来る
app.use('/graphql', 
	expressGraphql({
		schema: schema,
		rootValue: root,
		graphiql: true
	})
);

app.listen(port, () => console.log('Express GraphQL Server Now Running On localhost:port/graphql'));
```

最初`const expressGraphql = require('express-graphql');`で実行すると
`TypeError: expressGraphql is not a function`が出た。
`.graphqlHTTP;`にする必要があるらしい。
もしくは`const { graphqlHTTP } = require('express-graphql');`でも良さそう。


# クエリのテスト
http://localhost:3000/graphqlに繋ぐとクエリ送信テストの画面が出てくる。
出てきた画面の左上にクエリを作成する。

```javascript
query getSingleName($userID: Int!) { // 与えるパラメータを指定
 user(id: $userID) { //入力パラメータを使って実際のGraphQLのuserクエリに投げる
  id
  name
 }
}
```

このクエリに与えるパラメータを下に入力

```javascript
{"userID":1}
```

これで実行ボタンを押すと以下が返ってくる

```javascript
{
  "data": { // 仕様は見ていないが、dataという名称は多分固定
    "user": { // クエリ名称だと思われる
      "id": 1,
      "name": "one"
    }
  }
}
```

GraphQLでは欲しいデータを指定出来るのが利点の一つとなっているので、返ってくるデータをnameだけにするようにクエリを指定してみる。

```javascript
query getSingleName($userID: Int!) {
 user(id: $userID) {
		name
 }
}
```
この場合は次のようにnameだけ返ってくる

```javascript
{
  "data": {
    "user": {
      "name": "one"
    }
  }
}
```

実際に商用サービスとして作る場合にはapolloを使った方がいいのかも？
とりあえず今回はここまで。
PHPstormでdocker コンテナに入る


昨今、よくあるdockerコンテナでのシステム構成をとっている場合
コンテナ内で、コマンドを実行したいなどのケースが発生したりします。

Laravelだったら、artisanコマンドを実行したいとか

そんなときに使えるのがPHPstormのサービスツールです。


PHPstormにはサービスツールウィンドウというのがあり
開発上利用するツールに対してアクセスして操作ができます(docker, k8s, DBへの接続...)

https://pleiades.io/help/phpstorm/services-tool-window.html

# 使い方

## 1. サービスツールにdockerを追加する
デフォルト状態でありそうな気もしますが、無ければ [+]から追加をします。
Mac であれば ⌘8 で Servicesツールウィンドウが開きます

![スクリーンショット 2021-11-27 13.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/97724a8c-00d2-102f-786e-ab747bd657bb.png)

詳しくは [Docker サポートを有効にする ﻿](https://pleiades.io/help/phpstorm/docker.html#enable_docker)

## 2. dockerサービスに接続する
左上の再生ボタンを押してdockerサービスに接続します
![スクリーンショット 2021-11-27 13.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/a0d26b7b-b88a-00d0-37f1-c81b7eb300bf.png)

## 3. 対象のコンテナを選択する
入りたいコンテナを選択します。
docker-composeで立ち上げている場合、コンテナがリストでまとまっているので
階層から探してください。
![スクリーンショット 2021-11-27 12.53.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/ccc67854-2847-8a28-af7e-024033539247.png)

## 4. Create Terminal でコンテナに入る
右クリックから　[ Create Terminal ] を選択すると
![スクリーンショット 2021-11-27 12.53.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/0b5e5936-d336-5995-68d6-3eb015b211e1.png)


ターミナルのタブが開いて
コンテナに入れた様子が見れます

artisanコマンドも即打てる便利
![スクリーンショット 2021-11-27 12.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/a6c7c153-c46f-d071-7dfb-471c54080b72.png)
Linuxのcp, mv, rmコマンドについてまとめる

今回のお題
-
Linuxのcp, mv, rmコマンドについてまとめます。

lsコマンドについては以下の記事をどうぞ。

https://qiita.com/keishi04hrikzira/items/c9631994198679072899

cpコマンド
-
ファイル、フォルダのコピーをするためのコマンドです。

```shell:ディレクトリ状況
|-- dir1
|    |-- dir3
|    |-- test1.txt
|
|-- dir2
```

以下の作業については基本的にdir1で行います。

```shell:通常コピー
# cp コピーしたいファイルのパス コピー先のパス
% cp test1.txt ../dir2
# dir2の中にtest1.txtがコピーされる
% ls ../dir2
>> test.txt
```
```shell:コピーと同時に名前を変更
# cp コピーしたいファイルのパス コピー先のパス/コピー後のファイル名
% cp test.txt ../dir2/test2.txt
# dir2の中にtest.txtがコピーされ、test2.textとして保存される。
% ls ./dir2
>> test2.txt
```
```shell:同一フォルダ内へのコピー
# 同じディレクトリ内にコピーする場合にはファイル名の変更が必須
% cp test.txt test2.txt
% ls
>> test.txt test2.txt dir3
```
```shell:ディレクトリごとコピー
% cp -r ../dir1 ../dir2
# dir2の中にdir1のコピーが作られる
% ls ../dir2
>> dir1
```

```shell:ディレクトリの中身だけをコピー
% cd dir1
% cp -r . ../dir2
# dir1の中身だけがdir2にコピーされる
% ls ../dir2
>> test.txt
```

mvコマンド
-
ファイル・ディレクトリの移動や名前の変更に使います。

cpコマンドとは異なり、`-r`オプションは不要です。

```shell:ファイル名の変更
# mv 現在のファイル名 変更後のファイル名
% mv test.txt test1.txt
% ls
test1.txt dir3
```

```shell:フォルダ名の変更
# mv 現在のフォルダ名 変更後のフォルダ名
% mv dir3 dir4
# 他のカレントディレクトリ外のフォルダを操作する場合には、変更前変更後ともにパスを指定する
% mv ../dir2 ../dir2
```

```shell:ファイル/ディレクトリの移動
# mv 移動させたいファイル・ディレクトリ 移動先のフォルダのパス
% mv dir3 ../dir2
% ls ../dir2
>> dir3
```

### 注意
フォルダの移動と名称変更はともに

```shell
mv フォルダ名 フォルダ名
```

という書式になるため、フォルダ移動の際に移動先として存在しないディレクトリ名を指定してしまうとフォルダ名の変更として扱われてしまう。

rmコマンド
-
ファイル・ディレクトリの削除に用いるコマンドです。

```shell
# ファイルの削除は rm ファイル名
% rm test.txt

# フォルダの削除は rm -r フォルダ名
% rm -r ../dir2

# -fオプションで削除しても良いかどうかの確認を省略可能
$ rm -f test.txt
```
[VS Code] Pythonの venv 環境をデフォルトで読み込む

## はじめに
venv環境をactivateするときに下のコマンドをターミナルに毎回打ち込んでいたが、めんどくさくなった。

```
.\venv\Scripts\activate
```

VS Codeの機能を使えば自動で読み込んでくれるのではないかと思い、調べてみると案の定だった。


## 対象者
この記事は下記のような人を対象にしています。

- Python初学者

## 環境
Windows 10 home

## 結論
以下のような既存の記事を見ると解決するが、備忘録として残す。

https://tekunabe.hatenablog.jp/entry/2018/12/28/vscode_venv_default_rolad

## デフォルトで読み込まれるパス
- ワークスペースディレクトリ配下の venv など（ディレクトリ名は任意）
- 設定(setting.json)の python.venvFolders で指定したデフォルト値

```setting.json
// Folders in your home directory to look into for virtual environments.
  "python.venvFolders": [
    "envs",
    ".pyenv",
    ".direnv"
  ]
```
setting.jsonの開き方は以下の記事が詳しい。

https://qiita.com/y-w/items/614843b259c04bb91495

## 仮想環境の作成
VS Codeの上部のメニューから 「ターミナル」→「新しいターミナル」を選択し、新しいターミナルを起動します。
そして仮想環境を作成します。

```
python3 -m venv venv               # ワークスペースディレクトリ上
```

## コマンドパレットでインタープリタの設定
VS Code でワークスペースディレクトリ（ venv を含むディレクトリ）を開きます。
次に、「Ctrl」 + 「Shift」 + 「p」 でコマンドパレットを開き、Python Interpreter などと打ち込み
「Python: インタープリターを選択」 を選択します。

![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/80b500fd-daa0-8fb3-dd35-8bd7d4526be9.jpeg)

以下のように、環境が認識されてていることが確認できます。
律儀なことに星までついています。

![image2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/d26d4f51-d51a-05c3-9897-724bc6ef7f24.jpeg)

ここでは、「venv」を選択します。
左下の 使用インタプリターの表示で venv が選択されていることが確認できます。

![image3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/c7be30db-47f8-e6c3-7a5a-7573e45685ca.jpeg)

この状態でターミナルを起動すると、自動で該当の activate コマンドが実行され、仮想環境に入った状態になります。

![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/75c000bb-049d-5cca-82c5-3b35674a5fc5.png)


## うまくいかないときの処方箋
#### VS Codeの設定が英語で、「Terminal」ならあるが「ターミナル」なんて無いんだが？
日本語化すると作業がスムーズです。設定はいつでも戻せます。

https://www.javadrive.jp/vscode/install/index4.html

#### ターミナルで仮想環境を作成できないんだが？
pythonをインストールできていないか、パスが通っていません。
以下のサイトの手順に従ってください。

https://www.python.jp/python_vscode/windows/index.html

#### コマンドパレットで「Python: インタープリターを選択」が出てこないんだが？
- 前述のとおり、一番最初は python Interpreter まで入力する必要がある
- 拡張機能からpythonをVS Codeでインストールできていない(関係ないかも)

https://atmarkit.itmedia.co.jp/ait/articles/2106/25/news028.html

#### 作成したはずの仮想環境が候補に出てこないんだが？
以前にAnacondaなどを使用していた場合、仮想環境の候補がたくさん出てくる場合があります。
列挙された仮想環境のリストを一番下まで見てください。

## おわりに
次からはプロジェクトフォルダを開くと自動で仮想環境が読み込まれる。
数秒の時短とストレスの緩和に期待。
[Laravel]<Collection>→where()ってなんで書けるか分かる？

# 背景

例えば、以下のコードを書くと

```php
$user = User::get();
$thirtyUsers = $user->where('age', '30');

dd($userAttribute);
```

当たり前ですが、以下の結果が取得できる

```php
Illuminate\Database\Eloquent\Collection {#2035 ▼
  #items: array:3 [▶]
}
```

これを見て、当初は

> 「Illuminate\Database\Eloquent\Collectionにもwhereメソッドあるんだ～」

とのんきに思っていた。

---

そんなある日、同期から

> 「Collectionからwhereってなんで呼べるんだろ？」

という疑問を聞いたので

> 「Illuminate\Database\Eloquent\Collection継承してるっしょ」

と回答したところ、

> 「そこにはないぞ」

と一蹴された。。。

> 「まさか～」

と思い、見に行くとやっぱり`function where()`の記述はない。

ごめん。同期。

> 「じゃあどこだ？」

と気になったので、ジャンプし続けて見つけたので、メモ。

# 内容

## ファイルを読み込んでいく

- 前述の通り開発する上で一番よく見るCollectionである`Illuminate\Database\Eloquent\Collection`から始まる
- 正式のパスは以下なので、確認
    - 上述の通り、ここで`function where(`を検索しても見つからない

> vendor\laravel\framework\src\Illuminate\Database\Eloquent\Collection.php
> 

```php
<?php

namespace Illuminate\Database\Eloquent;

...
use Illuminate\Support\Collection as BaseCollection;
...

class Collection extends BaseCollection implements QueueableCollection
{
...
}
```

- ここで、冒頭のクラス定義時に`BaseCollection`を継承しているらしい
    - `BaseCollection`とは`Illuminate\Support\Collection`であるとのこと
    - 「ここにあるのか！」と高鳴る鼓動を落ち着かせつつ、ジャンプ
    - 実際にジャンプする先は以下でした
        - `vendor\laravel\framework\src\Illuminate\Collections\Collection.php`
        - 理由はnamespaceが`Illuminate\Support;`となっていたため

> vendor\laravel\framework\src\Illuminate\Collections\Collection.php
> 

```php
<?php

namespace Illuminate\Support;

...
use Illuminate\Support\Traits\EnumeratesValues;
...

class Collection implements ArrayAccess, Enumerable
{
    use EnumeratesValues, Macroable;
		...
}
```

- しかし、ここでも`function where(`を検索しても見つからない
    - 継承はこれ以上ないので、ここで怪しそうなのは`EnumeratesValues`と`Macroable`というトレイト
    - `Macroable`は関係なかったファイルを確認
    - そして`EnumeratesValues`へジャンプ

## 結論

ここにありました。

`vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php`

```php
/**
     * Filter items by the given key value pair.
     *
     * @param  string  $key
     * @param  mixed  $operator
     * @param  mixed  $value
     * @return static
     */
    public function where($key, $operator = null, $value = null)
    {
        return $this->filter($this->operatorForWhere(...func_get_args()));
    }
```

# 補足

`vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php`

- ここには、よくお世話になるコレクション操作用のメソッドがここにありました。
    - 公式でも紹介されている便利なやつです。

https://readouble.com/laravel/8.x/ja/collections.html#available-methods

- 同時に「だから、ここら辺のコレクションメソッド全部使えるのか～」と納得
- ドキュメントには今回の検証結果の途中まで記述されてました

https://readouble.com/laravel/8.x/ja/eloquent-collections.html#available-methods

> `Illuminate\Database\Eloquent\Collection`インスタンスを返します。ただし、`modelKeys`などの一部のメソッドは、`Illuminate\Support\Collection`インスタンスを返します。

- ただ、`EnumeratesValues`にある旨の説明は見当たらんかったですね。

## 所見

- 興味深かったのは、ドキュメントにないメソッドである`__toString`, `getCachingIterator`, `reduceWithKeys`, とかが見つかった点です。
    - なかなか使用ケースがマイナーかもですが、、、
- コレ知ったことにより、実務的に直接生きるかはまだわからないです。
- ですが、どこのメソッドを呼び出しているか意識して使うか否かで**想定外のエラーに対応できる**でしょう！（多分）
- やっぱり、コードを深く読み込んで理解するのって実務やってる中だと、なおざりにしがちなのでいい機会でした～
Dockerfile コマンド一覧

#Dokerfileとは
**Dockerイメージをコード化したもの**

- **メリット**
 - **ファイルを読むだけでインフラ構成が分かる**
 - **オリジナルにカスタマイズしたイメージを作成できる**
 - **設定ファイルなども変更できる**

#RUN
**DockerfileからDockerイメージにbuildするときに一回だけ実行されるコマンド**

```vim
# nginxをインストールする場合
RUN apt-get install -y nginx 
```

#CMD
**Dockerfileから作成したイメージをコンテナ化するときに実行されるコマンド**

```vim
# nginxをフォアグラウンドで稼働させる場合
CMD ["nginx", "-g", "daemon off;"]
```

:::note alert
exec形式の場合、json配列形式のため、コマンドは必ず「"」ダブルクォーテーションで囲うこと
:::

#COPY
**ファイルをイメージに追加するコマンド**

```shell
$ COPY <ホストのファイル名> <コンテナのパス名>
```

#ENV
- **環境変数の指定**
 - **DBユーザー名や動作環境名などの設定で使用される**

```shell
# 構文
$ ENV Key:Value

# アプリの本番環境を変数に設定
$ ENV APP_ENV="production"

# 環境変数の確認（ConfigのENV内に記述されている）
$ docker inspect <コンテナ名>
```

##参考教材

https://www.udemy.com/course/docker-startup
マイクラのサーバとアプリを同じPCで起動するとアプリからサーバに接続できない件

# はじめに
PCでマインクラフトのサーバを立てます。

同じPCでマインクラフトのアプリを起動して、先ほど立てたサーバに接続しようとしてもエラーになってしまって接続できないという問題が発生してしまったので調べてみました。

私が確認したのは統合版です。

# こういうことがしたい
図にするとこんな感じ。
Windows10のPCでサーバを立てて、LAN内の他のPCや各種ゲーム機、スマホなどからワールドにアクセスしたい。ついでにサーバを立てたPCにもマイクラアプリを入れて、同じサーバに接続したい。
![20211128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/1623a577-78a8-80da-03a2-97bca85a9015.png)
…んだけど、なぜだかエラーになってしまって接続できない。
他のPCやゲーム機からはアクセスできるのに、、ですよ。

# 接続できない理由
色々と調べてみたところ、
「Windows Store アプリはデフォルトでlocalhost（自分自身）に接続できない」
という制限があり、この制限により同一PC上のマイクラサーバに接続できないとのこと。

接続するには、この設定を解除してやる必要があるようです。

# 接続できるようにしてやる設定
管理者権限でコマンドプロンプトを開き、以下のコマンドを実行。

```shell:コマンドプロンプト
> CheckNetIsolation LoopbackExempt -a -n="Microsoft.MinecraftUWP_8wekyb3d8bbwe"
```

これで、ループバック（localhostへの接続）の除外リストにマインクラフトアプリが追加され、同一PC内のマイクラサーバに接続できるようになります。

# まとめ
最初はサーバ側の設定の問題かと思って色々と設定をいじくり回していたのですが、Windows Storeアプリの仕様の問題でした。

ループバック制限を除外する方法が見つかって、PCからもサーバに接続できるようになり、またマイクラライフが快適になりました。
[PHP] git commit 時に自動でコーディング規約チェック・コード整形・コード静的解析を実行してくれるようにする

### プロジェクトに各種ツールを導入

[コーディング規約チェック: PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer)
[コード整形: PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer)
[コード静的解析: PHPStan](https://phpstan.org/)

```
cd <Laravelプロジェクトパス>
composer require "squizlabs/php_codesniffer=*"
composer require friendsofphp/php-cs-fixer
composer require phpstan/phpstan
composer update
```

### git commit 時に呼び出される pre-commit の用意
```
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
```

### pre-commit の編集

```shell:.git/hooks/pre-commit
# 指定ブランチへのpush防止
while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = "master" ]]; then
    echo "Do not push to master branch"
    exit 1
  fi
done

IS_ERROR=0

# コーディング規約チェック・コード整形・静的解析
for FILE in `git diff-index --name-status $against -- | grep -E '^[AUM].*\.php$'| cut -c3-`; do
    if php -l $FILE; then
        # コーディング規約チェック
        <Laravelプロジェクトパス>/vendor/bin/phpcs --standard=PSR12 $FILE

        # コード整形
        <Laravelプロジェクトパス>/vendor/bin/php-cs-fixer fix $FILE

        # コード静的解析
        if ! <Laravelプロジェクトパス>/vendor/bin/phpstan analyse $FILE; then
            IS_ERROR=1
        fi
    else
        IS_ERROR=1
    fi
done

exit $IS_ERROR
```

これで git commit 時に自動でコーディング規約チェック・コード整形・コード静的解析を行ってくれるようになります。
git commit 実行時に --no-verify をつけると呼び出されません。

```
git commit -m "~~~" --no-verify
```
AWS の EC2 上で動作する Moodle の SELinux を有効にする(その3)

前回
[AWS の EC2 上で動作する Moodle の SELinux を有効にする(その2)](https://qiita.com/intrajp/items/7985f7bcbaa82f6f1219)
の続きです。

現在、disabled であるインスタンスを enforcing にしたいです。

まず、スナップショットをとりました。
これで、何かあっても、復旧可能です。

次に、設定で、permissive にしました。

さて、このまま再起動すると、壊れます。
以下のコマンドをやらないと、ラベルがちゃんとはられないようでした。

```
# touch /autorelabel
```

再起動して確認したところ、permissive になっていました。
yarn installでエラーが出た件

今回、個人開発している方のお手伝いでVueを使用することになり、環境構築時のyarn installでエラーとなってしまいました。
その際に解決策として行ったことを記録として残しておこうと思います。

#開発環境
PC：MacBook
エディター：VSCode

以前一度Reactの環境構築を行っているので、Nodeはインストールされていました。

#エラー発生時の状況
GitHubからダウンロードしたソースコードを開く。
下記のコマンドを実行

```VSCodeのターミナル
$yarn install
```

しかし下記のエラーとなり失敗しました。

```
The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.17.0 || >=15.0.0". Got "14.16.1"
02
error Found incompatible module.
03
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
```

nodeのバージョンが非互換であるので、互換性のあるnodeをインストールしてくださいとのこと。

#対処
1. **互換性のあるNodeのインストール**

下記のコマンドを実行して互換性のあるnodeをインストールしました。

```VSCodeのターミナル
$node install 14.17.0
```

Nodeのバージョンを確認

```VSCodeのターミナル
$node -v

v14.16.1
```

あれ？バージョンが変わっていない・・・



2. **使用するＮodeの切り替えコマンド実施**

```VSCodeのターミナル
$nodebrew use 14.17.0
```

その後、バージョンを確認

```VSCodeのターミナル
$node　-v 
14.17.0
```

バージョンが切り替わったことを確認しました。

しかしyarn installでのエラーの状況は変わらず下記のまま・・・

```
The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.17.0 || >=15.0.0". Got "14.16.1"
02
error Found incompatible module.
03
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
```

3.**パスを通す**

ググったところ、パスを通す処理をしていませんでしたので下記を実行。

- ~/.zshrcに下記の記載を追記し手保存します。

```~/.zshrc
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

- 下記のコマンド実行

```VSCodeのターミナル
source ~/.zshrc
```


##**これでyarn install 実行**
インストールが出来たことを確認！

**yarn serveコマンドを実行し、デバッグ環境が出来たことを確認しました。**



#参考サイト
- [参考qiita](https://qiita.com/whiteraccoon/items/0e12daa3ddd6eb816007)
- [yarn実行時に「 The engine “node” is incompatible with this module.」エラーが発生した場合の対処方法](https://choppydays.com/node-js-yarn-the-engine-node-is-incompatible-with-this-module/)
【図解解説】JOI2021-2022 一次予選 第1回 問題3 複雑な文字列

## 図解解説シリーズ
競技プログラミングを始めたばかりでAtCoderの解説やJOIの解説ではいまいちピンと来ない…という人向けに、図解を用いて解説を行います。

## 問題文
### 情報オリンピック日本委員会に掲載されている問題

https://www.ioi-jp.org/joi/2021/2022-yo1/2022-yo1a-t3.html

### AtCoderに掲載されている問題
入出力など実際に確認して自分の作成したプログラムを採点することができます。

https://atcoder.jp/contests/joi2022yo1a/tasks/joi2022_yo1a_c

## 図解解説
今年度の一次予選のC問題は、以下の４つのスキルを確認する問題になっています。
１．入力・出力を正しく利用できる
２．算術演算子を正しく利用できる
３．条件分岐（if）を正しく利用できる
４．繰り返し処理を正しく利用できる

問題文を整理するために、具体的な数字を用いて、図示して考えてみます。
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2211017/915fb580-ae47-af43-0054-1446887e35b3.png)
Pythonでの文字列は、1文字ごとに先頭から0,1,2,3,…と番号が割り当てられています。したがって、先頭の文字は「変数名[0]」と指定して取り出すことができます。この仕組みを利用して、文字列の先頭から1文字ずつ順番にA,B,C,D,Eのどの文字か確認していく作業を行います。

![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2211017/8caf21a1-c1e0-dcb8-15dd-70fcec533fbd.png)
確認したA,B,C,D,Eをどのように管理すればよいか考えてみます。さまざまな方法がありますが、ここでは２つの場合を示します。

変数a,b,c,d,eを用意し、初期値を0にします。文字列Sの中に文字Aが含まれていたら、変数aの値を1にします。含まれていなければ初期値のまま0とします。同様に、文字列Sの中に文字Bが含まれていたら、変数bの値を1にします。含まれていなければ初期値のまま0とします。この作業を、文字C、文字D、文字Eまで行います。この作業を行うと、それぞれ文字が存在すれば、変数の値は1になります。a+b+c+d+eを計算すれば文字列Sの中にA,B,C,D,Eの文字が何種類含まれているか確認することができます。

Pythonに含まれるcountメソッドを使用します。文字列Sに含まれる文字Aの数は、S.count('A')で確認できます。同様に、文字列Sに含まれる文字Bの数は、S.count('B')で確認できます。この作業を文字C、文字D、文字Eまで行えば、それぞれの文字が含まれているかどうか確認することができます。文字の種類数を管理する変数cntを用意し、初期値を0とします。S.count('A')>0なら変数cntに1を加え、S.count('B')>0なら変数cntに1を加え、…と繰り返せば、文字の種類数を求めることができます。

## 解答例
### 5つ変数を用意した場合

```c1.py
N = int(input())
S = str(input())
#それぞれの文字があるかどうかチェックするための変数を5つ用意
#それぞれ初期値として0をあてはめる
a = 0
b = 0
c = 0
d = 0
e = 0
#文字列の先頭から1文字ずつ確認を行い、文字S[i]がAならa=1、Bならb=1、…と処理を行う
for i in range(N):
  if S[i]=='A':
    a = 1
  if S[i]=='B':
    b = 1
  if S[i]=='C':
    c = 1
  if S[i]=='D':
    d = 1
  if S[i]=='E':
    e = 1
#5つの変数を足し合わせ、3以上ならYes、それ以外ならNoを出力する
if a+b+c+d+e>=3:
  print('Yes')
else:
  print('No')
```
[採点サイトに提出したプログラム](https://atcoder.jp/contests/joi2022yo1a/submissions/27505026)

### Pythonの機能を使った例
効果的に機能を活用すると、アルゴリズムを簡単にすることができます。

```c3.py
N = int(input())
S = str(input())
#Pythonの持つcountメソッドを利用してそれぞれの文字が含まれているかどうか確認する
#A,B,C,D,Eの文字の種類数については変数cntで管理する
#A,B,C,D,Eのそれぞれについて文字が含まれているかどうか確認し、
#含まれている場合(1文字以上ある場合)は変数cntの値を1増やす
cnt = 0
if S.count('A')>0:
  cnt = cnt + 1
if S.count('B')>0:
  cnt = cnt + 1
if S.count('C')>0:
  cnt = cnt + 1
if S.count('D')>0:
  cnt = cnt + 1
if S.count('E')>0:
  cnt = cnt + 1
if cnt>=3:
  print('Yes')
else:
  print('No')
```
[採点サイトに提出したプログラム](https://atcoder.jp/contests/joi2022yo1a/submissions/27504888)

なお、配列（リスト）と繰り返し処理を行うことで、短い行数で命令を記述することができます。

```c4.py
N = int(input())
S = str(input())
#Pythonの持つcountメソッドを利用してそれぞれの文字が含まれているかどうか確認する
#含まれている場合は、変数cntの値を1増やしてA,B,C,D,Eの文字の種類数を管理する
#リストmojiを作成し、A,B,C,D,Eの文字を格納しておく
#格納した文字を1つずつ取り出して、繰り返し処理を行うことで
#短い行数でプログラムを記述することができる
cnt = 0
moji = ['A','B','C','D','E']
for m in moji:
  if S.count(m)>0:
    cnt = cnt + 1
#変数cntの値を確認し、3以上ならYes、それ以外ならNoを出力する
if cnt>=3:
  print('Yes')
else:
  print('No')
```
[採点サイトに提出したプログラム](https://atcoder.jp/contests/joi2022yo1a/submissions/27504949)

## イラスト
スライド内で使用しているイラストはすべて「[いらすとや](https://www.irasutoya.com/)」の素材を利用しています。
Android12 targetSDKVersion31にしたら起きること

今働いている会社でそろそろtargetSDKVersion31への移行を行なっていく必要があり調査していて、発生したことをメモ書きしていきます。

https://developer.android.com/about/versions/12/behavior-changes-12?hl=ja


<h3>アプリで対応する必要があった項目</h3>
・コンポーネントのエクスポートの安全性を改善
・ペンディング インテントの可変性

<h4>コンポーネントのエクスポートの安全性を改善</h4>
インテントフィルタの設定が入っている場合にはexportedのフラグ設定が必須になりました。元々デフォルトでインテントフィルタ設定がされてたらONになっていたがそれを明示的に指定するように。
そもそも内部でしか利用しないようなパターンがあったときに、勝手にONになっていたため知らず知らずのうちにアプリを公開してしまうっていうのを防ぐのが目的っぽい。

ビルド時にエラーで怒られます。対象のAndroidManifest.xmlのタブで「Marged Manifest」をタップするとエラー確認できます。

![スクリーンショット 2021-09-20 17.03.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893524/10698df3-290e-3cde-5f7e-e60ecc65211f.png)

色々動かしていて分かったこととしては、システム側から起動されるような処理の場合、exported=falseでも問題なく動作したことです。基本的にアプリの外部から呼ばれるものはexported=trueにしなきゃいけないのかな？っと思っていたのですが、大丈夫そうでした。

利用しているライブラリでも影響を受けていたので記載
androidx.test:core:1.4.0 にアップデートで解消しました。


<h4>ペンディングインテントの可変性</h4>
PendingIntent利用時にPendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_IMUTABLEの設定が必要になります。
こちら、ビルド時ではなく実行時にException発生するので注意です。
アプリ側でも警告文は出るので、一度PendingIntentを利用しているところをチェックした方が良さそうです。

基本的にFLAG_IMUTABLEを設定するでOKですが、アプリ側との連携などが必要で起動先から情報を更新してもらうような機能の場合はFLAG_MUTABLEが必要になります。
説明で記載があるのはBubbleを使った例などでした。
notificationなどは特に変更など必要ないのでFLAG_IMUTABLEの対応で問題ないと思います。
アプリでMUTABLEに設定が必要だった箇所としてはジオフェンスで、その際に受信時にintentにデータを詰めているためMUTABLEを設定しないと受信時にデータがnullで返却するため動作しない状況でした。
あらかじめシステム側からデータが返却されることが分かっている場合、MUTABLEでの設定が必要かと思います。

また、ライブラリでは下記が影響を受けてました。下記のバージョンにアップデート。
androidx.media:media:1.4.3
androidx.work:work-runtime-ktx:2.7.0　
com.google.android.gms:play-services-analytics:17.0.1

<h3>サードパーティ製のライブラリが影響受けてそうな項目</h3>
・おおよその位置情報
ACCESS_FINE_LOCATIONとACCESS_COARSE_LOCATIONの両方を指定した場合はUI上でユーザがおおよその位置にするか正確な位置にするかを選択できるようになりました。そのため、正確な精度を強制するのはできなくなった感じです。

・フォアグラウンド サービスの起動に関する制限
基本的にはバックグラウンド時にフォアグラウンドサービスの利用ができなくなったので、WorkManagerを利用する必要がありそう。

・新しいBluetooth権限　
これだけメインのところに載ってなかった。権限が追加されているのでBluetoothを利用するアプリは追加が必要かも。

https://developer.android.com/about/versions/12/features/bluetooth-permissions?hl=ja

<h3>まとめ<h3>

今回のアップデート対応ではビルド時にエラーになる項目と、実行時にエラーになるパターンもあったので注意です。
ライブラリ側でもアップデートしないといけないところが多くて、意外と更新が必要だった印象です。
targetSDKVersion31にすることでSplashScreenAPIを使うことができるようになるので、アップデートが完了したらそちらも利用していきたいと思います。
mkdocs-materialとGitHub PagesでMkDocsを作成する

# Install

```
pip install mkdocs-material
```

# ｍｋdocs作成

1. MKDocsの初期化

    ```
    mkdocs new .
    ```

    <details><summary>結果</summary><div>

    ```
    tree
    .
    ├── docs
    │   └── index.md
    └── mkdocs.yml

    1 directory, 2 files
    ```

    </div></details>

1. テーマを`mkdocs.yml`で指定

    ```yaml:mkdocs.yml
    site_name: My Docs
    theme:
      name: material
    ```

1. ローカルで起動

    ```
    mkdocs serve
    ```

    ![スクリーンショット 2021-11-27 11.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/4572a9b0-3589-b63a-0ad1-d5dfb27423a5.png)

1. ビルド

    ```
    mkdocs build
    ```

    `site/` 以下に生成される

1. [GitHub Pagesで公開する](https://squidfunk.github.io/mkdocs-material/publishing-your-site/) (`gh-deploy` branchにPush)

    1. GitHub Pagesの設定: 以下のように`gh-pages`ブランチを指定する

        ![スクリーンショット 2021-11-27 11.29.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/65532ad5-73d2-fa8f-51f8-1ae4f1a8a599.png)

    1. GitHub Actions作成 (`main` branchにPushされたらDocsをビルドしてDeployする)

        ```yaml:.github/workflows/publish.yml
        name: publish

        on:
          push:
            branches:
              - main
        jobs:
          deploy:
            runs-on: ubuntu-latest
            steps:
              - uses: actions/checkout@v2
              - uses: actions/setup-python@v2
                with:
                  python-version: 3.9
              - run: pip install mkdocs-material
              - run: mkdocs gh-deploy --force
        ```
    1. GitHub Actionsを含めて、RepoへPush
    1. https://nakamasato.github.io/mkdocs-material-sample/公開された! (自分の場合は、カスタムDomainを使っているので nakamasato.comとなった)
1. [テーマ変更](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/)

    色などを変更できる

    ```yaml
    site_name: mkdocs sample
    theme:
      name: material
      palette:
        primary: cyan
    ```

    ![スクリーンショット 2021-11-27 11.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/bf862986-7e5a-80ab-8795-c4cb286371fe.png)



# Reference

- https://squidfunk.github.io/mkdocs-material/creating-your-site
- https://github.com/nakamasato/mkdocs-material-sample
Goで Quick Select を書いた

日本語の資料が乏しかったので,ここにまとめます。
必要な前提知識も多く、この記事単体では完結していないです。
詳しくは、参考文献等をご参照ください。
また、書かれているコードは、以下の問題で検証済みですが、
不十分であるため、コピペされる方は自己責任でお願いいたします。

https://atcoder.jp/contests/abc228/tasks/abc228_c

## Quick Select とは
「ある配列の中で、k番目に小さい値はいくつ？」に答えるアルゴリズム。
クイックソートの要領で pivot を選択し、pivotを元に、配列を分割しながら答えを探す。
愚直に考えると、ソートしてk番目をとればいいが、その場合は、最悪計算量がソートがボトルネックになり$O(nlogn)$になる。
一方、このアルゴリズムは、平均計算量$O(n)$で解くことができる。

## 実装方針
pivot の選択方法には、以下の方法があるが、今回は中央値の中央値をpivotにすることにした。

- 常に左の要素を採用する
- ランダムに取得した要素を採用する
- 中央値の中央値を採用する

また、pivotに対して、配列を並べ替える戦略が以下にあるが、効率がよい前者を採用した。

- Hoare partition scheme
- Lomuto partition scheme

## コード

```golang
func insertionSort(a []int, left, right int) {
	for i := left; i <= right; i++ {
		j := i
		for (j > left) && (a[j-1] > a[j]) {
			a[j-1], a[j] = a[j], a[j-1]
			j--
		}
	}
}

func median(a []int, left, right int) int {
	insertionSort(a, left, right)
	return a[left+(right-left)/2]
}

func partition(a []int, left, right, pivot int) int {
	i := left - 1
	j := right + 1

	for {
		i, j = i+1, j-1
		for a[i] < pivot {
			i += 1
		}
		for a[j] > pivot {
			j -= 1
		}
		if i < j {
			a[i], a[j] = a[j], a[i]
		} else {
			return j
		}
	}
}

func selectPivot(a []int, left, right int) int {
	if right-left < 5 {
		return median(a, left, right)
	}

	for i := left; i+4 <= right; i += 5 {
		insertionSort(a, i, i+4)
		a[i+2], a[left+(i-left)/5] = a[left+(i-left)/5], a[i+2]
	}

	n := right - left + 1
	return innerSelect(a, left, left+n/5-1, left+n/10-1)
}

func innerSelect(a []int, left, right, kth int) int {
	if left == right {
		return a[left]
	}

	pivot := selectPivot(a, left, right)
	pivotIndex := partition(a, left, right, pivot)
	if kth <= pivotIndex {
		return innerSelect(a, left, pivotIndex, kth)
	} else {
		return innerSelect(a, pivotIndex+1, right, kth)
	}
}

func QuickSelect(a []int, left, right, kth int) int {
	return innerSelect(a, left, right, kth)
}

```

## 参考文献

### クイックセレクトの考え方の元となるクイックソートの詳細
- https://en.wikipedia.org/wiki/Quicksort

### クイックセレクトの実装の概要
- https://en.wikipedia.org/wiki/Quickselect
- http://www.dais.is.tohoku.ac.jp/~shioura/teaching/ad09/ad09-05.pdf
- https://en.wikipedia.org/wiki/Median_of_medians

### 中央値の中央値のわかりやすい解説
- http://www.flint.jp/blog/?entry=109

### 実装がハマったときにみたサイト
- https://stackoverflow.com/questions/58331986/quickselect-with-hoare-partition-scheme
OpenCVでαチャンネルを含んだpng画像を読み込む時の注意

#はじめに

Pythonの画像処理の定番はOpenCVかPILでしょう。

今回、PNG画像をOpenCVで処理をしていた時にどうもうまく動かないことがあったので、備忘録として書いておきます。

ちなみにαチャンネルとは透明の部分です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/7000d193-8c49-a575-322b-1bac5d0c7005.png)


#要約

αチャンネルを含んだpngを`cv2.imread(img)`で読み込むとαチャンネルが削除されたndarrayになるよ

αチャンネルも読み込みたかったら`cv2.imread(frame, -1)`みたいに引数に-1を渡すよ

https://nekomosyakushimo.hatenablog.com/entry/2017/11/15/145242

opencvの全角文字非対応対策としてnumpyで読み込んでから変換したものはαチャンネルを含んでいるよ

opencvを使って動画を書き込む際はαチャンネルを含んでいちゃいけないよ


http://opencv.jp/opencv-2svn/c/reading_and_writing_images_and_video%20(ido-linux's%20conflicted%20copy%202010-06-07).html




#本文

現在画像を使って動画を作成しています。

https://qiita.com/yuki_2020/items/efe6eda433b09ec34203

私の環境ではフォルダに全角文字を使用しているので、普通の`cv2.imread(img)`ではパスに半角文字しか使えないため、画像を読み込めないです。
対策としてこのようにnumpyで読み込んでからRGBの順番を変更するという方法があります。
というのも`cv2.imread(img)`はnumpyのndarrayとして画像を扱うからです。

```.py
import cv2
import numpy as np
buf = np.fromfile(img_path, np.uint8)
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
```

https://imagingsolution.net/program/python/opencv-python/read_save_image_files_in_japanese/

しかし問題があり、`cv2.imread(img)`ではpngのαチャンネルを削除して読み込むのに対し、上のコードだとαチャンネルまで読み込んでしまいます。
具体的には、高さ720、幅528の画像を読み込んだ際、
`cv2.imread(img)`では(720,528,3)のサイズの配列となり、（3はRGB）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/48f41522-46d1-7c24-337d-834d7b514aae.png)

上のコードで読み込むと(720,528,4)のサイズの配列となります。（4はαRGB）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/18b9d226-88ae-6537-d273-8f6b3ea7559a.png)


さらに問題なのはopencvで動画を作成するときの画像はRGBでなければいけないということです。

そのためnumpyで読み込み、その後αチャンネルを削除する必要があります。
さらに問題なのは、__pngはαチャンネルを含むものと含まないものがあることです。__


これらを加味して、全角パスのpngを読み込んでRGBに変換するコードがこちらです。

```.py
buf = np.fromfile(frame, np.uint8)
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
if img.shape[2] == 4:
    img = np.delete(img, 3, axis=2)
```



#まとめ
opencvは便利な反面、全角文字に対応していないのが一番の弱点ですよね
初めて後輩を持ったら意識したい７つの習慣

## はじめに

来年初めて後輩を持つであろう自分のための覚書です。

## 第一の習慣「先輩だからと変に気負わない」

後輩もあなたが全部できるとは思っていません。無理なものは無理と言って、弱みも見せて欲しいと思っています。

例えば後輩から質問されたとき、何でも自分で対応しようとしてダラダラ話しをしていませんか？最初に言うべきは、あなたがわかるのか、パッとは分からないから一緒に考えるなのか、誰か他の人に聞いてほしいなのか、のどれかです。後輩が次のアクションが取りづらくなります。

## 第二の習慣「共感する」

新人時代の不安や悩みは、初めて後輩を持ったあなたがチーム内で一番覚えているはずです。１０個上の先輩と話していると勉強にはなりますが、不安や悩みを共感されることは少ないです。近しい存在であるあなたが、共感を示してくれるかで新人後輩の心の平和は決まるでしょう。

## 第三の習慣「曖昧な表現をできるだけ避ける」

初めてチームにアサインされた新人後輩は、プロジェクト内で使われる言葉１つ１つが未知の単語です。「それ、これ、あれ」などの指示語は一切使わないくらいの意識が大事です。

また、単語もできるだけ具体的に形容してあげると良いでしょう。例えば、話の流れで分かる場合でも、ただの「サーバー」ではなく「アプリサーバー」とか「データベースサーバー」とかまで言ってあげましょう。

## 第四の習慣「質問がしやすい雰囲気、態度でいてあげる」

テレワークで先輩の様子がさらに見えにくくなっています。後輩は、どんなにあなたから「いつでもいいよ」と言われても必ず気を遣います。そんなときに、質問対応を蔑ろにされると、質問しづらい状況に拍車がかかってしまうでしょう。

最初のうちは、ビデオ会議を常時つなげておき、いつでも質問できる状況を作ってあげるなどの対応をすると良いと思います。


## 第五の習慣「話は最後まで聞いてあげる」

新人だと、要点がまとまらずにダラダラと話してしまうこともあります。あなたからするとイライラの種でも、後輩はそんなあなたに伝わるように一生懸命に話していることがほとんどです。そんなときに、途中で遮られて指摘されるとどんなに正しくても快く受け入れられないでしょう。最後まで話を聞いてあげてその上で改善を促すほうが、前向きに改善ができると思います。

## 第六の習慣「タスクは明確な説明とともに振る」

タスクが発生した経緯、そのタスクの内容、タスクの完了状態、期限を意識してタスクを割り振りましょう。

正直これは、誰にタスクを振るときでも意識したいことです。ではなぜ取り上げたかというと、初めて後輩を持つあなたは「初めて他者に仕事を振る立場になる」からです。今までタスクを振られる立場だった人が振る立場になると、簡単なことも案外できなかったりします。

## 第七の習慣「自分の知識を伝えてあげる」

どんなに後輩と歳が近くても、業務経験はあなたの方があります。新人後輩は、ちょっとした便利ツールとか、あなたが当然と思っている業務知識も知りません。最初のうちは、後輩は「そもそも質問するための知識も持っていない」ことが往々にしてあるので、積極的に自分の経験を伝えてあげましょう。
AWSの知識まとめ（初級）

最近バックエンドエンジニアをしていても、インフラの知識が必須のようなイメージ
があるので実務では使ってないが少しずつ知識をためていこうと思う！

## 基本もろもろ

- ルートユーザーとIAMユーザーがあり、基本的にはIAMユーザーで作業を行う
- 操作ログはCloudTrailで追跡できる、S3に保存される
マイクがないためミュートボタンが押せないとき

#ミュートにできない
Webexでミュートになっていないが、マイクがないため音声は伝わっていない。
気になるためミュートにしたいが、手前にあるミュートボタンは無効になっていて押せない。

そんなときは「参加者」を開いて自分の名前の横のミュートマークでミュートしましょう。