OmniAICreator/Qiita-1.07M huggingface dataset:
postgreSQLでよく使うコマンド（随時更新中）

ごっちゃになりがちなpsqlで使用するコマンドをまとめました。
自分の忘備録となるので、随時増やしていきます。

### テーブルスペース関連

テーブルスペース作成
※前もって、テーブルを作成する場所にはディレクトリを作詞しておく必要がある。

```sql
postgres=# CREATE TABLESPACE test_data LOCATION 'D:\bw_data';
CREATE TABLESPACE
postgres=#
```
テーブルスペースの確認

```sql
postgres=# \db
                テーブル空間一覧
       名前        |   所有者    |     場所
-------------------+-------------+--------------
 pg_default        | postgres    |
 pg_global         | postgres    |
 test_data           | postgres    | D:/test_data/
(3 行)
```

テーブルスペースの削除

```
 drop TABLESPACE <TABLESPACE_NAME>;
```

### スキーマ関連

```sql
postgres=# select current_schema;
 current_schema
----------------
 public
(1 行)
```








### データベース関連

データベースの選択

```
\c [データベース名]
```

データベースから出る

```
\q
```

データベースの削除

```
 drop database <DATABASE_NAME>;
```

データベースの作成

```
CREATE database <DATABASE_NAME>;
```


### テーブル関連
テーブルを作成する
※テーブルスペースと紐づかせた記述です。

```
 CREATE TABLE テーブル名(カラム、データ型) TABLESPACE テーブルスペース名;
```

テーブルを削除する

```
DROP TABLE テーブル名;
```

テーブルの確認

```sql
postgres-# \dt
postgres-# \dt　（テーブル名をフルで記入）；
```

テーブルカラムの確認

```sql
postgres-＃\d tablename

                         テーブル"tabelname"
           列            |          タイプ          | 照合順序 | Null 値を許容 | デフォルト
-------------------------+--------------------------+----------+---------------+------------
 red                     | bigint                   |          | not null      |
 yellow                  | character varying(10000) |          | not null      |
 blue                    | character varying(10000) |          | not null      |
 green                   | character varying(10000) |          | not null      |
 orange                  | numeric                  |          | not null      |
 black                   | integer                  |          | not null      |
 white                   | character varying(10000) |          | not null      |
```
[コード] モジュールとPythonバージョンの出力

# モジュールのバージョン取得
*  [PEP 396 -- Module Version Numbers | Python.org](https://www.python.org/dev/peps/pep-0396/#id24)

## Pythonコード

```py

import sklearn
print('scikit-learn version is {}.'.format(sklearn.__version__))
```

## 出力

```shell

scikit-learn version is 0.22.
```

# Pythonのバージョン取得

* [sys.version --- システムパラメータと関数 — Python 3.9.1 ドキュメント](https://docs.python.org/ja/3/library/sys.html?highlight=sys%20version#sys.version)
* [platform.python_version --- 実行中プラットフォームの固有情報を参照する — Python 3.9.1 ドキュメント](https://docs.python.org/ja/3/library/platform.html#platform.python_version)
* [sys.version_info --- システムパラメータと関数 — Python 3.9.1 ドキュメント](https://docs.python.org/ja/3/library/sys.html?highlight=sys%20version#sys.version_info)


## Pythonコード

```py

import platform
import sys

# バージョン番号を示す 5 要素タプル:major, minor, micro, releaselevel, serial
print('python version is {}.'.format(sys.version_info))
# 'major.minor.patchlevel' 形式の文字列
print('python version is {}.'.format(platform.python_version()))
# (※非推奨）Python インタプリタのバージョン番号の他、ビルド番号や使用コンパイラなどの情報を示す文字列
print('python version is {}.'.format(sys.version))
```

## 出力

```shell

python version is sys.version_info(major=3, minor=6, micro=8, releaselevel='final', serial=0).
python version is 3.6.8.
python version is 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)].
```
ユーザー権限で使える memdisk(ramdisk) 領域 `/run/user/$uid` のメモ

## 背景

* 画像処理とかレンダリングや機械学習で, 中間の計算結果(数 MB ~ 数 GB)を多量に生成する必要がある.
* SSD だと読み書き頻繁にすると寿命が気になる...

Linux だと tmpfs で memdisk(ramdisk) を作ることができますが, root 権限が必要になります.

共有サーバとかで, ユーザ権限で memdisk を作りたいときがあります.

## systemd 環境(Ubuntu, CentOS 7+)

systemd 環境だと, `/run` が tmpfs でマウントさており, `/run/user/$uid` でユーザごとにアクセスできる領域があります.

https://unix.stackexchange.com/questions/162900/what-is-this-folder-run-user-1000

`df -h` で確認できます.

```
tmpfs           9.5G   24K  9.5G   1% /run/user/121
tmpfs           9.5G  8.0K  9.5G   1% /run/user/1000
```

インストール環境などにもよるかもですが, 概ね総メモリ量の 10% が確保されます.

この領域を使うとよいでしょう!

## `/dev/shm`?

Ubuntu 環境ですと `/dev/shm` も, ユーザ権限で直接読み書きできました(こちらは総メモリ量の半分が確保されている)

容量大きめなデータですとこちらを使ってみるのもよさそうです!

## その他

go とかで FUSE でユーザー権限で memdisk 作れるライブラリあるようです.

https://github.com/bbengfort/memfs
(2017 で開発止まっているので今だと動かないかも)
【Flutter】AndroidアプリをPlayストアで公開するときに「バージョン コード 1 の APK または Android App Bundle がすでに存在するため、別のバージョン コードを使用する必要があります。」と言われるときの対策

## 概要
Google Play Consoleでアプリのリリースを作成する際、バージョンコードが前回のリリース時の値と同じだとアプリをアップロードすることができません。
pubspec.yamlのバージョンの記述を変えてあげれば解決します。

## 解決方法
pubspec.yamlを編集します。

```.yaml:pubspec.yaml
# version: x.x.x+1
version: x.x.x+2
```

記事タイトルのように`バージョン コード 1 の APK または Android App Bundle がすでに存在するため、別のバージョン コードを使用する必要があります。`
と表示される場合は前回リリースの`バージョンコード`が1になっているということなので、`+1`を`+2`に変えてあげます。

## 仕組み

バージョンコードは`android/app/build.gradle`の以下の部分を参照しています。

```.gradle:android/app/build.gradle
android {
    defaultConfig {
        versionCode flutterVersionCode.toInteger()
    }
}
```

`flutterVersionCode`は以下のようにpropertiesから取得しています。
このプロパティファイルはビルド時に`pubspec.yaml`から自動生成されるので、解決方法に記載した通り、`version`の値を修正することで解決できます。

```.gradle:android/app/build.gradle
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
```

ちなみに`version`の書式は、

```
version: [バージョン名]+[バージョンコード]
```

です。
AWSでよく使うSQS+Lambdaの組み合わせで気をつけるべきこと

今回はSQS＋Lambdaを組み合わせて使う場合に気をつけるべきことについて書きました
サーバレスなアーキテクチャを考えた時に、何かと候補に上がる組み合わせだと思います
一部、自分が体験した失敗から学んだこともあるので、反省の復習をしつつ同じ失敗をする人が減ってくれれば良いなと思います

# なんでSQS＋Lambdaなのか？

そもそもこの組み合わせを選ぶのはなぜか？ということですが

* サーバレスなアーキテクチャを組みたい
* Lambdaを使用するにはトリガーとして全段にサービスが必要（SQS、APIGateway・・・など）
* Lambdaの処理が失敗した場合、再実行したい

このような理由からSQS＋Lambdaの組み合わせを選択します

# 【ケース①】SQSの標準キューはメッセージの配信を1回”以上”保証する

SQSの標準キューとはこれです

![スクリーンショット 2020-12-24 20.58.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198158/650c553e-9ea7-d89c-33d3-2dc33dd1d9bf.png)

「少なくとも１回の配信」とあります
複数回同じメッセージが配信されることもあります
そのため、Lambdaで２回以上同じメッセージが来ることを考慮する必要があります
``/tmp``にファイル保存したり、DB処理するときに「重複してるからダメよ」と言われないように、「2回目以降は処理しない」など回避方法を考える必要があります

# 【ケース②】SQSの標準キューは順序性を保持しない

ケース①と同じく標準キューの話になります
FIFOキューであれば順序が保持されるのですが、標準キューは順序が保持されません
[1, 2, 3, 4]という順序でメッセージが入っても[1, 2, 4, 3]と処理されることがあります
順序性が必要な処理を行う際は「データをファイルやDBに全部まとめる前処理を置く」などデータを繋げたり、順序性が不要なデータにするなど対処が必要です
※「FIFOキューにすればいいじゃないか」という話はあるのですが、S3バケットのファイルを処理したい時に標準キューしか選べなかったりします

![スクリーンショット 2020-12-24 21.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198158/1eb58f47-2f7b-eb00-7305-93ddf8ec7af8.png)


# 【ケース③】LambdaはSQSの複数メッセージを拾うことがある

LambdaはSQSのキューをポーリングして「処理するメッセージないかなー」と待っています
キューにメッセージが入ってくるとLambdaが処理を開始します
Lambdaが確認したタイミングでメッセージが複数存在すると複数のメッセージをLambdaの1起動分（プロセスと表現した方が良いのか？）で処理しようとすることがあります

``` python:lambda_function.py
import json

# "event"にメッセージが配列となって格納される
def lambda_handler(event, context):
```

Lambdaのタイムアウト、SQSキューの可視性タイムアウトの時間は「最大何メッセージを処理し、全体の処理時間は何秒か？」を考慮して設定する必要があります
また、途中のメッセージ（例えば10個中5個目）で例外などが発生した時に「次のメッセージを処理するのか？」など、ハンドリングを考慮する必要があります

1起動あたり何メッセージを取得するかはLambda側に設定します
Lambdaでトリガーを設定するところに「バッチサイズ」というのがあり、これが１バッチあたり何メッセージ取得するか？を決めています
Lambdaは1度に5バッチまで取得することが可能で、取得しきれないメッセージが存在するとLambdaの同時実行数が増えていきます
バッチはメッセージを入れる箱で、1度に箱に何メッセージ入れられて、箱を何個持てるか？持てない分は実行数を増やして箱を持つというイメージになります
AWS公式のドキュメントは[こちら](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-sqs.html)です

![スクリーンショット 2020-12-24 21.20.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198158/35a5abbe-a2ab-449d-47d9-3723109eb183.png)

# 【ケース④】SQSのデッドレターキューを使用する際はLambdaは例外をスローする

SQSのキューの機能でデッドレターキューというものがあります
キューのメッセージを処理していると当然異常が発生すると思います
異常が発生したメッセージをキューに戻すと異常が繰り返し発生することになります
異常が発生したメッセージを保存しておく場所としてデッドレターキューを作ります

``[キュー] → [Lambda(異常)] → [デッドレターキューにメッセージ入れる]``

デッドレターキューにメッセージを入れるにはLambdaで例外をスローして処理を終了する必要があります
pythonを例にすると``raise Exception``でfunctionの処理を終了すると自動的にメッセージがデッドレターキューに入ります


# さいごに

最近、AWSがLambdaに力を入れていると思いますので、もっとサーバレスなアーキテクチャを選択することが増えてくることになると思っています
気軽に使えるのは間違いないのですが、Lambdaの仕様（クセ？）がもちろんあるので、理解しながら開発を進めて行くのが大事だと感じています
今後もLambdaに触れる機会はどんどん増えるので、そこで経験した知見やしくじりを書いていこうと思います
かくつかないiOSアプリを作るために


## 自己紹介

Link-Uの原野です。iOS 50% / Web フロント 50%くらいで仕事をしてます。

## iOSにおけるカクツキとは

iOS では画面をスクロールした際に、滑らかにスクロールせず一瞬アニメーションが飛んでしまうフレーム落ちをするタイミングがあります。
これはユーザー体験によくない影響があり、iOS アプリでは改善の対象となります。

Appleも最近この辺に力を入れているっぽく、WWDCでも一大テーマとして多くのセッションがありました。

## iOS の描画の流れ

まずはカクツキの機序を知るために、iOSが描画のために何をやっているかをざっくり追っていきましょう。

### リフレッシュレート

iOS では画面の描画の処理は一定のリフレッシュレートで行われています。
その速度は iPhone/iPad では 60Hz(16.67ms/回)、最新の iPadPro では 120Hz(8.33ms/回)となります。
カクツキは描画のための処理がこのリフレッシュレート内で処理しきれない場合に発生します。

### RenderLoop

iOS では描画のための処理を RenderLoop と呼ばれ、大きく 3 つのフェーズに分かれています。

1. CommitPhase
2. RenderPahse
3. DisplayPhase

#### CommitPhase

ユーザーからの入力に応じて、変更が必要なビューを検知し、レイアウトや背景色などをまとめ描画可能な状態のデータ構造を作る

#### RnderPhase

CommitPhase 作成されたデータ構造を元に実際に表示可能な画像に変換する。主にGPUが頑張る領域。

#### DisplayPhase

最終的な画像を画面に表示する

## RenderLoopで見るカクツキの原因

iOS では各フェイズは並列なパイプラインと処理されます。
その各フェーズがリフレッシュレートの範囲内に完了しなかった場合、
最終的な画面が更新されず 、ユーザーにはカクツキという形で見えてしまいます。

この中で、カクツキの原因は大きく２つの要因になります。

1. CommitPhase のレイアウト計算に時間がかった
2. RenderPhase でビューをレンダリングするのに時間がかかった


## 実際にカクツキを減らすには

アプリのカクツキを減らすには上記のCommitPhase/RenderPhaseの処理を高速化する必要があります。
主に対処法としては以下があります。


### CommitPhaseの高速化

CommitPhaseの高速化にはレイアウト処理の高速化をする必要があります。
主に以下の方法があります。

* 不要なViewの削除
* AutoLayoutをやめてマニュアルレイアウトを用いる(残念ながらAutoLayoutのパフォーマンスはそこまでよくありません)
* レイアウトの自動計算をやめて、極力手動計算や固定値を用いる
* 一度高さを計算した値はキャッシュしておく

### RenderPhaseの高速化

RenderPhaseの高速化は主に以下の方法があります

* 角丸などCALayer上での処理を避ける
* 半透明なビューなど、重ね合わせの計算が大変なものを無くす
* 不要なビューを削除する

この辺は画面の見栄えに影響することも多く、デザイナーや企画の方などステークホルダーとの調整が必要なことが多くあります。

## アプリのカクツキ度合いを調べる

問題の発生や解決手段が分かったところで、実際に自分のアプリでその問題が発生しているかを判断するにはいくつかの方法があります。

### CodeOrganizer

XCode11からXCodeOrganizer上でHitchRate(フレーム落ちの割合、英語ではフレーム落ちをHitchと呼ぶそうです)を調べられるようになりました。
HitchRateは1秒間にHitchが発生した時間の割合が指定され、Appleでは5ms以下がユーザーがフレーム落ちを経験しない良いアプリであるとしています。
逆に10を超えると、ユーザーの体験はかなり悪いと判断して良いそうです。

まだ実際の案件で実用までいっておらず、今後取り入れていけたらなと思っています。

### XCTest

iOS14以上の環境ではXCTestでHitchRatioを計測できるようになりました。

```
func testPerformanceExample() throws {
    // This is an example of a performance test case.

    app.launch()
    let view = app.descendants(matching: .table).firstMatch
    let measureOptions = XCTMeasureOptions()
    measureOptions.invocationOptions = [.manuallyStop]
    measure(metrics: [XCTOSSignpostMetric.scrollDecelerationMetric], options: measureOptions) {
        view.swipeUp(velocity: .fast)
        stopMeasuring()
        view.swipeDown(velocity: .fast)
        // Put the code you want to measure the time of here.
    }
}
```

ただ・・・手元の環境で試したところ、なぜか計測できませんでした。
まだ新しい機能なこともあり情報が少なそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115076/22fd7884-225d-7f39-dbe4-a5e1ce17a9ea.png)
Appleによるとこの項目にHitchRatioが並んでいるらしい・・・。


### 性能の低い実機で目視

何やかんや現状今のところ一番利用されている手法です。
Link-U内部ではデバッグ時にiPodTouchで検証がされており、ひどいカクツキが発生する場合はエンジニアにフィードバックがあります。
エンジニアは何だかんだ最新機種で触っていることも多く、巷で使われている中の最低レベルの端末でのテストの大事さがよくわかります。

## まとめ

カクツキの機序・改善方法・計測の方法を見ていきました。
とりあえず、XCTestでHitchRatioの取り方が分かったら知りたい。

## 参考資料

* [Eliminate animation hitches with XCTest]( https://developer.apple.com/videos/play/wwdc2020/10077)
* [Explore UI animation hitches and the render loop ](https://developer.apple.com/videos/play/tech-talks/10855/)
【備忘録】引数【TypeScript】

# 引数

TypeScript,JavaScript 初学者が関数の**引数**について勉強したのでメモを残す。

## デフォルト引数

- 関数を呼び出す際に、引数を省略して実行するとデフォルト引数での処理が走る。

  ```typescript
  const plusOne(n=1) => n+1;

  plusOne(2)  // 3
  plusOne()   // 2
  ```

- 基本的にはデフォルト引数は、引数の後ろから書く。

  ```typescript
  const plusOne(n=1,m) => n+m+1;  // NG
  const plusOne(m,n=1) => n+m+1;  // OK
  ```

- falsy な値ついて
  - 引数に`undefined`を渡すとデフォルト引数は既定値のまま
  - 引数に`null`または`空文字`を渡すと`null`もしくは`空文字`に設定される

## 残余引数（レストパレメータ）

- `...`という接頭辞をつけることで**残り**の引数を JavaScript の標準の配列として受け取ることができる。

```typescript
const numbers = (num1, num2, ...rest) => {
  console.log(num1);
  console.log(num2);
  console.log(rest);
};

numbers(1, 2, 3, 4, 5, 6, 7);
//  1
//  2
//  [ 3, 4, 5, 6, 7 ]
```

# 参考

- [りあクト！ TypeScript で始めるつらくない React 開発 第 3 版【Ⅰ. 言語・環境編】](https://booth.pm/ja/items/2368045)
- [デフォルト引数 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters)
- [残余引数 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters)

_何か指摘等ございましたら、コメントでお願いいたします。_
何も知らないペーペーが研究室に所属して1年目でやったこと

本記事は[東京学芸大学 櫨山研究室 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hazelab)の24日目の記事になります
(クリスマスイブでも絶好調です⭐️)。

## はじめに
最近開発していく上で、とてもお世話になっているQiitaなるもので、先輩たちが何やらAdvent Calendarというものをやっていて、「はああー、こんな記事を書けるなんてすごいなー」と思っていた矢先に、「何か書かない？」と[神様](@wf-yamaday) に言われてしまったので、書いてみます:bangbang:

タイトルにあるように、私はペーぺーなので、大した内容は書けませんが、本研究室で**学部3年生が取り組ませていただいたこと**と**その感想**をざっくりまとめます。

「初心者で何からすればいいのか分からない。」「初心者に何をさせればいいのか分からない。」という方のご参考になれば幸いです。

初めて記事を投稿するので、暖かい目でご覧ください。

## 口をぽかんとさせている間に終わっていた環境構築
2020年はコロナ禍における遠隔での環境構築でした。
先輩の手厚いサポートのおかげで、コマンドを打つだけで、環境構築をすることができました。

その仕組みについては、こちらをご覧ください。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958595/1e9a7ad8-1a98-f29e-f82c-713f4de7a2f2.png)](https://qiita.com/wf-yamaday/items/48af75b8623298ecedbc)
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958595/37664233-4c38-96d7-e4e0-60bd7b0d7442.png)](https://qiita.com/wf-yamaday/items/f8305faf0291d671494f)

## 4月〜10月 チームでのWebアプリケーション開発
本研究室では、半年間かけて、チームでのWebアプリケーションを開発しています。
先輩たちの手厚いフォローがあるものの、それでもウォーターフォールモデルでの初めてのチーム開発では様々な問題が起こってしまいます。
アプリが完成して、発表会を終えたときには、達成感でいっぱいになりました。
私のチームは、〆切直前に、寝る間も惜しんで電話を繋ぎっぱなしにしながらコーディングしました (いや、直前までだらだらしていた自分たちが悪いのですが…:sweat_smile:)。この経験も今となってはとても良い思い出です✨
この開発を通して、チームメンバーと一気に仲良くなれました✨

## 4月〜7月 技術ゼミ
本研究室では、4年生の先輩たちが、Webアプリケーション開発に必要な知識と技術を与えてくれます。
大体、以下の内容です。

- 要求仕様書
- Git
- 進捗管理
- Webアプリケーション
- UML
- Java
- MYSQL
- MVC
- JSP Servlet
- Gradle
- Docker
- サーバ
- デプロイ方法
- Jenkins

学んだことをチームでの開発に活かせることと、新しい知識が入ってくることの喜びがありました:blush:

## 11月〜 Webアプリケーションのバグ報告、修正
~~先輩方~~クライアントからバグ報告があるので、随時バグ修正をしています。(バグあってごめんなさい:sob:)

## もちろん、研究に向けても…
- 4月〜7月 論文輪講
- 8月〜9月 研究テーマ模索

に取り組みました:exclamation:

- 10月〜2月 英文論文輪講、サーベイ調査

に取り組んでいます:exclamation:

## さいごに
以上が、何も知らないペーペーが研究室に所属して1年目でやったことです。
実際にやった身としては、一人では学べない内容を学べたと感じていて、とても満足しています。 
櫨山研究室にいると、もっともっと勉強しようと意欲をかきたてられるので、上記のこと以外にも、本研究室の3年生は各自それぞれお勉強しています:muscle_tone1:みんな頑張ろう:fist_tone1:
そして、初心者のみなさん一緒に頑張りましょう:bangbang:
最後に、行き詰まったときに、先輩から頂いたお言葉を載せておきます。

**『デキる人は、頭がいいだけではなく、頭の中に「エラーを起こした失敗経験」と、「それを解決した成功体験」の記憶の引き出しをたくさん持っている。つまり、「似たようなエラーで学んだ経験がある」のです。』**
OpenSiv3Dを使ってサウンドビジュアライズ

# OpenSiv3Dを使ってサウンドビジュアライザーの開発

この記事はSiv3D Advent Calendar 2020　24日めの記事です。

OpenSiv3Dを使ってサウンドビジュアライズをしました。
[ソースコード(Github)](https://github.com/HosodaMath/SoundProgramming2/blob/main/C%2B%2B/OpenSiv3D/ColorFullSnow/SnowSimurator4/Sound.h)

動画
[ColorFull Snow](https://www.youtube.com/watch?v=UYtYucGo5Ag&feature=youtu.be)

## Code

Sound.cpp

```cpp
#include "Sound.h"
const int SnowMax = 300;

Sound::Sound(Audio init_audio) {
	audio_data = init_audio;
}

void Sound::audioPlay()
{

	//デフォルトでは1.0
	double volume = 1.0;

	double speed = 1.0;

	audio_data.setLoop(true);

	if (audio_data.isLoop() == true) {

		std::vector<SnowParticle> snow_data;
		for (int count = 0; count < SnowMax; count++) {
			SnowParticle data;
			snow_data.push_back(data);
		}

		while (System::Update())
		{	

			//playボタンの追加
			if (SimpleGUI::Button(U"Play", Vec2(20, 200), 100)) {
				audio_data.play();
			}

			//pauseボタンの追加
			if (SimpleGUI::Button(U"Pause", Vec2(120, 200), 100)) {
				audio_data.pause();
			}

			//stopボタンの追加
			if (SimpleGUI::Button(U"Stop", Vec2(220, 200), 100)) {
				audio_data.stop();

			}

			//音量のボリュームを変える
			if (SimpleGUI::Slider(volume, Vec2(330, 200))) {
				audio_data.setVolume(volume);
			}

			//再生スピードを変える
			if (SimpleGUI::Slider(U"{:.2f}"_fmt(speed), speed, 0.1, 2.0, Vec2(460, 200))) {
				audio_data.setSpeed(speed);
			}

			//再生位置の変更  .setPosSample() or .setPosSec()
			//再生位置の変更 0に設定
			if (SimpleGUI::Button(U"再生位置を０に変更", Vec2(20, 300))) {
				audio_data.setPosSample(0);
			}

			

			for (auto count : step(SnowMax)) {
				snow_data[count].snow_render(abs(sin(audio_data.posSec())), abs(cos(audio_data.posSec())), volume, 1.0);
				snow_data[count].snow_step();
			}
			
		}
		

	}
}
```

Sound.h

```cpp
#pragma once
#include <Siv3D.hpp> 
#include "SnowParticle.h"
class Sound
{
private:
	Audio audio_data;
public:
	Sound(Audio init_audio);
	void audioPlay();

};

```

## まとめ
全体としてあまり出来が良いとは言えないと思います。問題点を適時改良していきたいと思います:blush:
【Swift】「クラスを継承する」ってなんなの

# 簡単にまとめると

**親からワザを引き継ぐ。**

```swift:ViewController.swift
// UIViewControllerを継承
class ViewController: UIViewController {

  // UIViewControllerのメソッドを使う
  override func viewDidLoad() {
    // superとは親クラスのこと
    super.viewDidLoad()
  }
```

はじめに `UIViewController` のクラスを継承している。
これによって UIViewController が持っているワザを使用できる。`UIViewController` の部分を右クリックとかして **Jump to Definition** を選択すると、ワザ（そう、メソッドのこと）のリストが出てくるが、`viewDidLoad` もその中にある。

## つまり

『剣を振り下ろす』というワザを親のクラスから継承して、それに『ジャンプしてから』という動作を追加（override）して自分流にワザをアレンジすることができる。
Rubyの入出力

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>)


# 出力

```el
print("hello world")
```

実行結果

```el
$ruby print.rb
hello world
```

改行されない
他のRubyの出力方法はいろいろある
[Commandまとめ](https://qiita.com/cyoukou/items/27ae8fe873157d31252b)に載せている


# 入力


## ARGV(argument vector)

```el
puts "hello #{ARGV[0]}"
```

とコーディングして

```el
$ ruby hello_name.rb Cyoukou
```

とすると

```el
hello Cyoukou
```

と出力される
putsで入力された文字列を取得し、Helloの後にくっつけている
他の入力メソッドは[Commandまとめ](https://qiita.com/cyoukou/items/27ae8fe873157d31252b)に載せている



------
 - **source** ~/grad_members_20f/members/wjswnsrud12/memo5.org
休日訓練　案

2021年　休日開催訓練構想（妄想レベル）

・訓練目的毎に分けてみる
・当日チームを作りチーム行動する
・本部とチーム構成とし訓練にリアリティを出していきたい

※高田橋の休日利用状況を知らないので、最初は現地調査が中心になると思います
　平日ばりに利用する人が少なければ良いですが・・・

【目的分類】
・ドロンバード実戦訓練
・固定翼機訓練
・回転翼訓練
・撮影訓練
・初めて訓練


（ドローンバード実戦訓練）
　ドローンバード隊員としてのリアル訓練を目標とします


（固定翼訓練）
　小型機によるマニュアル飛行訓練


（回転翼訓練）
　小型機によるマニュアル飛行訓練


（撮影訓練）
　ドローンバーとしての空撮訓練
　撮影ルールなど共有

（初めて訓練）
　ドローンバード訓練必須アイテムの説明と使い方
　チームの役割説明、ドローン体験を予定してます　


【チーム】
チーム編成については、バディーシステムを基本とした考え方で
必ず2名以上で行動

災害現場での活動に置いても、単独行動、単独飛行は無いと想像してます
チーム行動が基本と想定
また、チームと本部の状況連絡も大事ですので、訓練から体験しておきましょう

本部が無い、連絡が取れない時は、現場判断により活動することも想定されますが
使命感が強すぎるあまり、判断を誤り事故やトラブル、自身の安全確保を忘れてし
まうものです。チームで安全第一に行動訓練も重要だと考えます。


・２名以上で飛行を行う
　　
　　〔私が考える理想体制〕
　　　・パイロット１名、
　　　・飛行監視員（副パイロット）１〜２名
　　　・周辺見張り員１〜２名
　　　・メカニック、本部連絡員、住民対応　１名

（飛行前ミーティング内容例）
・体制確認
・飛行ルート確認
・離着陸ポイントの確認
・運行前点検　機体の点検から気象確認等
・着陸後の機体確認、データ解析
・飛行トラブルによる緊急着陸手順の確認
　　機体トラブル以外の要因もあるので、事前に状況を想定し中止状況を確認しましょう
「hello, world」と表示されるだけのなんちゃってOS（ブートセクタ）を作ってみた。5/5時限目

おりょうの寺子屋、教師兼生徒を務めますわたくし、
おりょうが、本日は出張授業ですよ～　なんちゃって。

#はじめに

[HTC Advent Calendar 2020](https://qiita.com/advent-calendar/2020/htc)の22日目を担当します。
ONEJAPAN HACKATHONに参加したチームHTCのメンバー、おりょうです。

今回は私が絶賛挑戦中のOS作成の一部分を切り取ってご紹介しようかなと思います。
OSってみんな知ってるけどいざ作るとなるとなんだかハードルが高く感じますよね？
でも実際ちょっと興味ありません？
少なくともここまでの前説を読んでくれているあなたは、
少なからずOSに興味があるから見に来てくれているのでしょう。

そんなあなただけに今回は！
めちゃくちゃ簡単な「なんちゃってOS（ブートセクタ編）」をご紹介いたします。
合計3回に分けて紹介する予定です。

早速見ていきましょう！

##概要
成果物：OS(フロッピーディスクで、フォーマットはFAT12）
アセンブラ：[NASK](http://hrb.osask.jp/wiki/?tools/nask)
想定対象読者：OS自作をこれから始めようとしている人。

##シラバス
[1時限目：アセンブリ言語でソースコードを書こう①（ORG命令～entryラベルまで）](https://qiita.com/meijisinger531/items/1c4cc1c3d8ce4443a106)
[2時限目：アセンブリ言語でソースコードを書こう②（putloopラベル）](https://qiita.com/meijisinger531/items/b6b1cafd8d7b95855242)
[3時限目：アセンブリ言語でソースコードを書こう③（finラベル～msgラベルまで）](https://qiita.com/meijisinger531/items/7205a07d410a33991eee)
[4時限目：出来たソースコードを機械語にアセンブルしてみよう。](https://qiita.com/meijisinger531/items/b324702f62516b6c714f)
5時限目：PC/ATエミュレータを使ってOSを起動させてみよう。←今日はここ！

#5時限目：PC/ATエミュレータを使ってOSを起動させてみよう。
###PCエミュレータとは
PCエミュレータとは、所定のコンピュータや機械装置の全機能を模倣する機構のことです。
エミュレータにもいくつか種類があって、有名なものだとPC98を模倣したモノや、
ゲーム機のエミュレータなんてのも存在します。

###早速やってみよう。
今回私が使用したのはQEMUという、フリーのPCエミュレータです。
QEMUは、Fabrice Bellardが中心となって開発しているオープンソースのソフトウェアです。
使い方は下記のサイト
[フリーのエミュレータQEMUを使おう＠謎の処理系 SunOS 4.1.4 with Linux/FreeBSD](http://www15.big.or.jp/~yamamori/sun/qemu/)
を参照してみてください。

やってみた結果、下記のような表示となれば成功です。
![hello os.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920050/03d1286b-8469-bf1b-45cf-78cf6a002ab3.png)

　
以上で5日間に渡る自作OS記事は終了です。
機会があれば、今度はより本物チックなOS作成に関する記事も書けたらいいなと思います。
是非皆さんも、トライしてみてくださいね。
[Windows版]Gitのコミットを元に1日のコード行数を取得する。


Gitのコミットログを元に自分の生産性（1日にコミットした行数）を確認したかったので、Powershellを用いてコマンドを作成しました。

## コマンド概要
```powershell
$author = "author_name"
$startDate = "2020/12/24"
$endDate = "2020/12/25"

$Time = " 00:00:00"

$startDate += $Time
$endDate += $Time

$lines = git log --numstat --pretty="%H" --author=$author --since=$startDate --until=$endDate --no-merges | sls "/";
$plus = 0
$minus = 0;
foreach ($line in $lines) {
    $splitLine = $line -split "\t"
    $plus += $splitLine[0]
    $minus += $splitLine[1]
}
$total = $plus + $minus

echo "${total} (+${plus} -${minus})"
```
### オプションの説明：

|変数名|意味|
|---|---|
|author|自分の名前|
|startDate |生産性を図りたい開始日付|
|endDate |生産性を図りたい終了日付|

※注意
　1日を図りたい場合は開始日付+1にしてください。
　例えば、2020/12/24の生産性を確認したい場合は

```powershell
$startDate = "2020/12/24"
$endDate = "2020/12/25"
```
　のような形です。
## 使用手順
1. 確認したいGitリポジトリ(.gitがあるフォルダ)に移動する。
2. 上記コマンドを"GitLogOutput.ps1"のような任意のファイル名(拡張子.ps1)で移動したフォルダ配下に新規作成する。
3. GitLogOutput.ps1を実行

ps1ファイルはそのまま実行するには、Powershellの実行権限を変更しないといけません。
私は面倒なのでVSCodeで直接ps1ファイルを開いて、VSCode内のターミナルで実行しています。
## 使用例
qiitaさんの2020年12月24日の生産性を図りたい場合

```powershell
$author = "qiita"
$startDate = "2020/12/24"
$endDate = "2020/12/25"
```

### 出力結果
```
852 (+561 -291)
```

## 参考文献
https://qiita.com/Night___/items/359ff81f358968567a45
TMS WebCORE　ローカルストレージの使い方

##最終日が、空白ままになっていたので、TMS WebCOREの追記させていただきます。

データ一時保存の方法が、不明だったのですが、TMSのフォーラムで質問すると、ご回答いただけましたので、コンパイルした実行部を、現在使用しているレンタルサーバーにアップしました。
<手元のテスト環境は、CentOS8 + Nginxでテストしています>
***
JavaScriptなので、デプロイメントが他の手法にくらべても、容易な気がしますので、その手順も簡単に記述します。
###1.　Delphi での画面![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/04b14999-19cd-3543-441d-8efa4d0cc02f.png)
###2.　実行します http：//localhost:8000/Project1/Project1.htmlで実行されます 　![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/92858e09-dfd9-2ee4-5c1a-938b4685050f.png)
###3.　プロジェクトのツリー構造です![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/4da17771-ae13-ce16-940c-210d8c49774d.png)
###4.　TMSWeb/DebugのDebugをコピーして、名前を付けます、今回はtms_test1とします![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/7f14f42e-aadb-936e-f7c4-2a5bbbaae12d.png)
###5.　このままでもよいのですが![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/6a8070d3-60e2-5e15-c6ac-f4a3dffbfa38.png)
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/cb375ab6-edd4-6779-9dbd-0114cb84fe93.png)
###6.　Project1.htmlをコピーして、index.htmlに変更します![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/69e3b25b-9470-4460-8a0f-341cf0ff73e5.png)
***
このtms_test1　をフォルダごと、Webサーバーの公開部にコピーします。
これで、2.で実行した、http://localhost:8000/Project1/Project1.html が、下のサイトのURLで実行可能となりました。
画面と同じものが実行されます。<レンタルサーバーは、たぶん FreeBSD+apacheだと思います>

こちらは、このテストのリンクです
[https://den6.jp/tms_test1/](https://den6.jp/tms_test1/)

使い方は、WebEditに入力して、ボタンを押してください。
緑の枠は、WebEdit1にだけに対して、ローカルストレージの処理を行います
青の枠は、WebEdit1～3に
赤の枠は、WebEdit1～3にをグリッドに、なります


[ご興味のある方は、このソースをプロジェクトごと、このリンクでダウロードできます](https://den6.jp/files/4616/0881/0749/071_TWebLocalStorage6.zip)

***

こんな感じで、デスクトップアプリの作成手順で、Web開発ができるので、デザイン力のある方なら、動的なWebサイトの構築も、容易になるように思います。

あとは、サンプルコードが、もっと増えれば、Delphi + TMS WebCORE　は、もっと活況となってもよい気がしています。

他の選択もある、Web Component PackソリューションでDelphiによるWeb開発を実現の情報が増えていくことを、願っています。
業務中の恥ずかしいミスの話

業務中に起きた恥ずかしいミスを備忘録としてまとめておきます。

#1.データの移行作業でのミス
あるプロジェクトで運用中のステージング環境を、別サーバのステージング環境へと移行することになりました。
移行する必要があったのは画像とDBのデータです。


画像ファイルとDBのダンプファイルをどうやって移行しようかなーと調べていた所、`scp`コマンドに行き当たりました。

`scp`はリモートマシンからローカルor他のリモートマシンへとファイルのコピーを行うコマンドで、通信にsshを使用します。

```
$ scp オプション ユーザ名@リモートサーバのIPアドレス:コピー元のパス  保存先パス
```




これで行けそうだと思い、とりあえず移行元サーバからローカルへファイルを落とそうと

```
$ scp user@192.0.2.0:~/sample.sql ~/
```
と実行するも、ローカルにそれらしきファイルがありません。

特に実行時にエラーを吐いている様子もなく、なんで？？？となっていたのですが、
ただ単に**ローカル側で実行する必要があるのにリモート側で実行していた**のが原因でした。
全く同じミスをやらかしている記事を見つけてようやく気付きました。
うーん恥ずかしい。

補足ですが、[OpenSSH公式によると][link-1]`scp`は非推奨のため、代わりに`sftp`や`rsync`を使うことが推奨されているみたいです。



[link-1]:https://www.openssh.com/releasenotes.html
#2.Ansibleでのミス
あるプロジェクトのローカル環境を構築することになったのですが、そのプロジェクトではDockerイメージの作成やAnsibleの適用は全て自動化されている為、Gitリポジトリをクローンし設定ファイルを少し書き換え、ビルド用のスクリプトを実行するだけで環境構築が済みます。

そのためすぐ終わるだろうと思っていたのですが......

####・ 何故かクローンでタイムアウト
リポジトリのサイズが大きいのか、サブモジュールのクローンの途中でタイムアウトが発生していました。

そのためgitの設定を

```
git config --global http.postBuffer 4M
```
とすることでバッファのサイズを調整を行い、合わせてShallow cloneを用いることでなんとかタイムアウトせずにクローンを完遂出来ました。

####・ 何故か特定のtaskでタイムアウト 
その後ビルド用のスクリプトを実行し、ansible-playbookのtaskが実行されるのですが、何故かphp7のインストールを行う箇所でタイムアウトが発生しました。
原因が判明せず、先輩に相談しphp7のインストールは一旦手動で行うことに。

```
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.2
```


手動で行なった所、普通にインストール出来てしまいました。
だったらplaybookのtaskも通りそうということで、もう一度ビルドを試してみるも同じ箇所でタイムアウト。

原因が全く分からず悩んでいたのですが、実はこの時、**１日前から社内VPNに繋がらない問題**が発生していました。その件について先輩に確認したところ、どうやら繋がらないのは自分だけらしく、ここで自宅の回線の問題説が出てきました。

試しにテザリングでVPNに繋ぐと......繋がりました。
その後、部屋のルータを再起動してからビルドを試してみるとplaybookでのphpインストールも通りました。

完全に自宅のネット環境が原因でしたね。恥ずかしい。
社内VPNに繋がらない問題を放置したことが1番の原因ですが、リポジトリのクローンの段階で違和感に気付けたら良かったですね。

#最後に
一番恥ずかしいのは18日担当のアドベントカレンダーを24日に書いていることです。
内容にミスや勘違いがある際には指摘していただけると幸いです。
Google Recruit

自然対数eの値で連続する10桁の数のうち、最初の素数を出力するプログラムです。

```ruby:本体
def prime?(number)
 if (number < 2) return false;
 elsif (number == 2) return true;
 elsif (number % 2 == 0) return false;
 end

 sqrt_num = Math.sqrt(number);
 3.step(sqrt_num,3) do |i|
  if number % i == 0
   return false
  end
 end

 return true
end

def read_exp
 exp = gets.to_s.chomp
end

exp = read_exp()

for i in 0..(exp.length - 10)
 number = exp[i..(i+9)].to_i
 prime = prime?(number)
 if prime 
  puts(number)
  break
 end
end
```

```:結果
1828182845
```



------
 - **source** ~/grad_members_20f/members/acoe5781/Google_Recruit.org
Hibernateでtsrange型のマッピング方法

Hibernateで、PostgreSQLの「tsrange型」をマッピングするサンプルクラス（Entityクラス）です。
「tsrange型」のマッピング方法についての記事が少なかったので、記載してみました。

```java:SampleEntity.java
package xxx;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import com.vladmihalcea.hibernate.type.range.PostgreSQLRangeType;
import com.vladmihalcea.hibernate.type.range.Range;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "xxx_table")
@TypeDefs({
    @TypeDef(
        name = "jsonb",
        typeClass = JsonBinaryType.class
    ),
    @TypeDef(
        typeClass = PostgreSQLRangeType.class,
        defaultForType = Range.class
    )
])
@XmlRootElement
@Data
@NoArgsConstructor
@NamedQueries([
    @NamedQuery(name = "SampleEntity.findById", query = "SELECT s FROM SampleEntity s WHERE s.id = :id")})
public class SampleEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "tsrange_col", columnDefinition = "tsrange")
    private Range<Date> tsrangeCol;
}
LiveCall for LINE WORKSでオンライン接客

2020年も早いもので年の瀬、今日はクリスマスイブです。

「LINEWORKS アドベントカレンダー」の本日のお題は、今注目を集めるオンライン接客について取り上げたいと思います。

私が所属しているスピンシェル株式会社では、『LiveCall』というオンライン接客プラットフォームを提供しており、リテールをはじめ、金融機関や自治体などの様々な業界で導入が拡がっています。

多くの企業や機関が活用しているLINE WORKSからオンライン接客ができたら便利！という思いから『LiveCall for LINE WORKS』が産声をあげ、2021年1月に一般リリースされる予定です。

LINE WORKSユーザー同士はビデオ通話ができますし、LINEユーザー同士もビデオ通話ができますが、LINE WORKSとLINEユーザー間はテキストのトークは出来つつもビデオ通話ができませんでした。

『LiveCall for LINE WORKS』は、LINE WORKSとLINEユーザー間のビデオ通話を橋渡しします。その仕組みは、いたってシンプルです。

![LC4LW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939327/afb60b29-4858-33e5-42b0-b9dc20bb087f.png)

まずは、LINE WORKSのトークルームから『LiveCall for LINE WORKS』ボットを追加するかたちで、ボットがオンライン接客までの道筋をナビゲートしてくれます。

(1) LINE WORKSのトークルームから『LiveCall for LINE WORKS』ボットを追加
(2) ボットからLiveCallの接客用画面にシングルサインオン
(3) お客様側が接客を受ける時にアクセスするURLを発行して、LINE上のお客様に送信
(4) お客様がURLをタップするとビデオ通話によるオンライン接客がスタート

LINE WORKSユーザーは、使い慣れた画面から開始できるので、オンライン接客のデビューに最適です。何よりもLINEユーザーと繋がることができるのは、すごく便利だと思います。


▼ トークルームから『LiveCall for LINE WORKS』ボットを選択
![IMG_1196.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939327/2c2eb1de-f098-2a26-fc41-cc39a6444cc1.png)


▼ ボットと会話しながらオンライン接客をスタート
![IMG_1200.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939327/d973480b-4559-e482-3577-371acf423c53.png)


LINE WORKSのライトプラン以上のユーザーがご利用いただけ、Developer ToolとAdmin Consoleから登録手続きをすることで、『LiveCall for LINE WORKS』ボットを追加できるようになります。現在、簡単に登録手続きができるダッシュボードも準備中です。

年が明けましたら随時詳報を発信していきますので、皆様も是非お試しください。
djangoのmodelで使用するon_deleteってなんぞ？

##djnagoのモデルで使用するon_deleteについて
表題について、書籍を勉強中に遭遇した疑問です。

実際のコードは以下のような感じでした。

```python:django.models.py

class Test_Model:
    user = models.ForeignKey(CustomUser, verbose_name='ユーザー', on_delete=models.PROTECT, null=True)
```

調べてみるとdjango2.0よりモデル同士を紐づけるときに必須の項目とのこと。
意味合いとしては**参照するオブジェクトが削除された時、紐づいているオブジェクトをどうするか**というものらしい。

model.〜には以下の種類がある。
・CASCADE
　紐づいたオブジェクトを全て削除

・PROTECT
　関連づけられたオブジェクトがあると削除が出来ない

・SET_NULL
　オブジェクトは残るが該当する項目がNullになる

・SET_DEFAULT
　オブジェクトは残り、該当する項目にデフォルト値が入るようになる。

・SET()
　オブジェクトは残り該当する項目に関数をセット出来る

・DO_NOTHING
　何も処理しない。

どのように処理するのが適切か考えて決めなければ、、、、

参考サイト
https://djangobrothers.com/blogs/on_delete/
外国人エンジニアと働いて学んだこと

僕は7月に未経験からエンジニアとして入社しています。

僕の会社には日本語がほとんど話せないバングラデシュ人エンジニアがいます。
なので会話は9割以上英語で話します。

その他にも部署は異なりますがフランス人や中国人も在籍しています（彼らは日本語は喋れます）


※ちなみに僕の英語力は片言の英語で喋れるぐらいです。
聞き取ってなんとなく理解はしているつもりです。
個人的な感じたことなので全ての外国人に当てはまるわけでは
ありあません。

だけど彼は英語で僕に技術のことだけでなく文化や考え方などいろんなことを日々学んでいます。

そんな中で学んだことや感じたことを記載します。


## 同僚には常に敬意を払い、謙虚で感謝の言葉を必ず述べる

意外と日本人にはできていない人が多いと聞きます。エンジニアは
意外とコミュニケーションを取りますし、複数人で開発しているところが多いと思います。
私が仕事している中で質問したり彼から僕に質問されることもしばしばあります。

彼は僕より年上でかつ先輩ですが必ず感謝の言葉を述べますし（もちろん英語ですが笑）
全体連絡でも必ずslackにスタンプを押してアクションをします。
僕の完全な偏見ですが、日本人って意外とslackのコメントやアクションをしない率が高いのかな
って感じています。

それに、彼は何か良い情報があったらURLを貼ってくれてslackで共有してくれたりもします。
僕にとってかなり有益なものばかりですが英語サイトがほとんどなので理解に時間がかかります笑

またリモートワークになって文字のやりとりになってもそこまで意思疎通に困ったことは
英語の意味がわからない単語があったぐらいです。（翻訳あるから）

常にお互いに感謝しあったり、信頼するからこそ円滑なやりとりができ生産性が向上できる要因だと
いふと感じました。

あと、たまーにコーヒーくれたりします笑（飲み物のこだわりはすごいですがｗ）

## できないことははっきりとできないということ

彼の母国はバングラデシュなので、食べ物とかでは無理なものは無理とはっきり断ります。
日本人はよくできないのにできないことはないというような
曖昧な言い方をして自分の首を絞めている人が多いのではないかと思います。

規模が全然違いますが、無理なものは無理とはっきり言ったりと
自分の意見をきちんと言うこと、納得ができないのならばそれは違うのではないかとと意見すること。
自分から提案したりとはっきりと物事を伝えます。

時には上司にも臆せず間違っていることは間違っていると指摘したりもしています。
（僕は恐れ多くてできませんが笑）

仕事をすることは「上から振られたことをこなすだけ」でなく、自分から提案したりして
主体的に行動し仕事は楽しんですることを重要性を改めて感じた言葉でした。

## 仕事と休息・リフレッシュのメリハリがはっきりしている

彼は昼休憩は絶対に会社の近くの家に帰って食べます。
休憩時間終了ギリギリになってオフィスに帰ってきます。
そして午後からバリバリ働きます。
私もたまに午後から眠くなることがありますが、
毎回ピンピンしています。そして彼らはほぼ定時で仕事を終わって帰宅します。

これは僕の外国人の社員だけかと思いますが、休日はかなりリフレッシュしまくります。なので金曜日の午後になるとテンションが高く月曜日は比較的テンションが低いです笑
それとよく休日の予定は？と聞かれますが僕は勉強か読書か寝ると答えます笑
面白くないな働きすぎだよって言われましたwww

ちなみに彼はゲームしたり、映画みたり、友達と遊んだりと物凄く休日を謳歌しまくっています笑


## 英語はコミュニケーションをとる手段の1つでしかない

外国人と話す時は基本的に英語で話します。日本にいるなら日本語覚えろよって思いますが、
逆の立場からすると日本人は英語を喋れない人が多すぎると・・（僕もですが笑）

エンジニアになると日々のエラーはほぼ英語で書かれているため
英語に向きあいます。日々何が書かれているかは現在はGoogle翻訳やDeepLを使ってコピペして修正してくれる
文明の利器があります。

バングラデシュ人の同僚はこう言ってました。英語が話せたら20億人ぐらいの人間と
コミュニケーションを取ることができるのにと

ただ、便利な物ばかり頼ってはいけないなと個人的には思っています。

エンジニアは技術情報はほぼ英語で来ることが多いと思うので今のうちから英語の記事を読める
訓練はしないといけないなとふと思いました。

## あまりにも人任せな部分が多い

これは英語のことが主ですが、私が会社にいて感じたことが
みなさん英語で話しかけようとしない人が多いという点です。
できる人に任せるのは良いかと思いますが、コミュニケーションの面においてはせっかくいい機会なのに
英語で話さないのはもったいないなと個人的に思います。

※何度も言いますが僕の英語レベルは片言レベルです。
それでも必死に言いたいことを文法めちゃくちゃでも彼はちゃんと意図などを受け取ってくれるので
次第にコミュニケーションが少しずつ取れるようになりました。

彼もなかなか日本語が難してわからないよって言っているのも理解できます。
少しずつ覚えていってると感じますし、僕も日々いろんな表現を駆使して彼とコミュニケーションを取っています。

お互いに英語がそこそこ話せるだけで彼の祖国の歴史やバングラデシュの魅力を教えてくれたり
料理を作ってくれたりもしました。（意外と辛すぎた）

※バングラデシュは母国語はベンガル語です。英語は小学生ぐらいからずっと学いるから喋れるようになるのは
当たり前だと言ってました。

最初は誰でもうまくいかないと思います。プログラミング言語を覚えるのもそうですがだんだん
慣れていってわかるようになると思います。

何歳になっても挑戦しつづける姿勢を持たないといけないなと同時に感じる出来事でした。

## まとめ
**・いつまでも相手をリスペクトする精神を持ち続けよう**
**・主体的に行動する**
**・英語は切っても切れないことを自覚すること** 
**・休む時は休む。働く時は最高のパフォーマンスで働く**
**・挑戦することは何歳になっても遅くはない**

というかなりあたり前なことだと思いますが、僕も含めてできていない状況です（反省）
特に英語で外国人と話す機会は全然なかったので
外国人と働くという経験がなかなかなかったので、ものすごく新鮮さを日々感じています。

同時に英語力も日々磨かないといけないなと思いました

最後まで読んでいただきありがとうございました。
Git 複数のgithookを呼び出して,用途別に切り分けてみた

# githookとは

gitのコマンドを叩いた時に走ってくれるshell.
commit前に中身をチェックしたりpush前にブランチをチェックしたりと自動化しておきたいことをまとめることができる.
これを設定しておくだけで,単純な手違いは減らせる.

スクリプトは`.git/hooks`の中にサンプルがあるため,それを参考に書きます.

しかし,各動きに反応するスクリプトは一つなので(多分),用途が増える度に継ぎ足ししていく形になる...
これだと使いまわすときに不要なチェックなどが入る可能性があるため,用途別にスクリプトを切り分けて,使いまわせるようにしたいと思いました.

# やったこと

割と単純だが,ベースのスクリプトが複数のチェック用のスクリプトを呼び出す形にしてみました.

`.git/hooks`の構造を以下のようにしています.

```terminal
.git/hooks/
...
├── pre-push # push前に呼び出されるスクリプト
├── ban-to-master-pre-push # masterへのpush禁止
├── build-test-pre-push # push前にビルドテストをする
...
```

配置した後は必ず実行権限を与えるようにしましょう.
`chmod +x .git/hooks/pre-push`
`chmod +x .git/hooks/ban-to-master-pre-push`
`chmod +x .git/hooks/build-test-pre-push`

例えばpushをする前に呼び出される`pre-push`の場合,

```shell
#!bin/sh

# .git/hooks内の[用途名]-pre-pushを全て呼び出して処理
for f in $(ls .git/hooks | grep -E "[-]pre-push$"); do
    sh .git/hooks/${f}
    # 実行した結果が異常な場合は止める
    result="$?"
    if [ "${result}" != 0 ]; then
        exit "${result}"
    fi
done
```

呼び出す順番が気になる場合は,`ls`で一覧を取ってくるため,ファイル名の頭に呼び出す数値を振っておくのもありだと思います.

masterへのpushを禁止する処理

```shell
#!bin/sh

while read local_ref local_sha remote_ref remote_sha; do
    # masterへのpushを禁止
    if [ "${remote_ref}" =~ ^.*/(master)$ ]; then
        echo "${remote_ref}には直接push禁止!"
        exit 1
    fi
done

exit 0
```

こんな感じで用途ごとにスクリプトを分けることで,案件ごとに必要なチェックだけを入れることができるようになりました.

# さらに別案

やったことで書いた方法だと`.git/hooks`が散らかる気がするため,処理タイミング別のフォルダに入れて,呼び出す側のファイルパスを変更したらすっきりするかもしれません.

```terminal
.git/hooks/
...
├── pre-push # push前に呼び出されるスクリプト
└── pre-push.d # pre-pushで呼び出すスクリプトまとめ
    ├── ban-to-master # masterへのpush禁止
    └── build-test # push前にビルドテストをする
...
```

`pre-push`を変更

```shell
#!bin/sh

# .git/hooks内の[用途名]-pre-pushを全て呼び出して処理
for f in $(ls .git/hooks/pre-push.d); do
    sh .git/hooks/pre-push.d/${f}
    # 実行した結果が異常な場合は止める
    result="$?"
    if [ "${result}" != 0 ]; then
        exit "${result}"
    fi
done
```
ソフトウェアエンジニアという仕事の意義、自分なりの再定義、目的。

ソフトウェアエンジニアとは、世の中の諸問題を抽象化し、プログラミング言語で翻訳し、実世界の理不尽、非合理、非効率を解決する21世紀で最もセクシーな仕事である。同時にたった一人で世の中の革命ができる仕事でもある。現代の高杉晋作になれるのだ。

故に、ソフトウェアエンジニアを楽しむためには実社会の社会構造やビジネス慣習、ビジネスモデルを知り、それによって生まれる問題を日々把握し、それを解決するためにはどうすればいいかに日々思いを馳せる必要がある。そして、問題を解決するためにはこうしたほうがいいという手札を日々蓄える必要がある。意識しながら。

この手札というのは「〜したい！」となった時に「AとBの技術を組み合わせればできる」と脳内に浮かぶ技術的解決手段の数を指す。そしてAの技術というのはコマンドやメソッドであったりするが、それらは遡れば昔に誰かが何らかに問題意識を感じて開発したコマンドやメソッドであるはずだ。

それを踏まえ、なぜコマンドやメソッドが生まれたのか。そしてそれらを現実世界の理不尽、非合理、非効率を解決するためにどう転用するかを考える。

そしてそれらをうまくこなすコツはITの世界にダイブし、その世界で使われている言葉、プロトコル、慣習、思想を知り、ITの世界のネイティブスピーカーになることだ。英語を身に付けるためにアメリカやイギリスなどの英語圏に移住する感覚に近いかもしれない。

我々は現実世界と仮想世界を繋ぐ翻訳家であり、2つの異なる世界に住居を構える新世代の住人でもある。我々が学んでるのは仮想世界の言葉でありプロトコルであり慣習であり思想である。

そして、技術を知ってるだけじゃダメだ。その知ってる知識でどう社会問題を解決できるのかを言語化し、繰り返し想像できなければ知識は1のままで、10にはならない。応用が効かない。

それ故に、先述の姿勢を持って日々仕事や勉強に励まなければならないと夜風がたなびくクリスマスイブの夜、私は固く誓うのだ。
JavaScript jQuery セレクタ指定の仕方

JavaScriptとjQueryのセレクタ指定の比較

|指定  |JavaScript  |jQuery|
|---------|------|------|
|class　　　|document.getElementsByClassName('class名')　　|$(".class名")|
|id    |document.getElementById('id名')|$("#id名")|
|tag    |document.getElementsByTagName('tag名')|$("tag名")|
Emotetとは

【Emotetとは？】

Emotet（エモテット）
＝メール経由で拡散するマルウェアのこと。

■マルウェアとは？
不正且つ有害に動作させる意図で作成された、
悪意のあるソフトウェアやコードの総称。
malicious software（直訳：悪意のソフトウェア）の略称。

■これまでのEmotetの活動
＜2014年＞
初めてEmotetが観測される。
当初はオンラインバンキングを標的とした、トロイの木馬型のマルウェアだった。

＜2015年以降＞
標的を拡大させ、モジュール型のマルウェアへ進化し続けている。
※何度も配布→休止を繰り返してきていますが長文になるので割愛。

＜2019年9月～2020年初め頃＞
Emotetの活動が活発化。日本での感染も拡大した。

＜2020年2月頃～2020年6月頃＞
Emotetが配布活動を休止。
この間にEmotetをZip付きファイルで送る方法を作り出した。
※Zip付きファイルだと不正なoffice文書が圧縮されるので、セキュリティ検知をすり抜けてしまう。

＜2020年6月頃～現在＞
Emotetが再度、配布活動を開始。
過去最大規模の感染となっている。

＜2020年12月21日＞
Emotetの感染メールの配布が観測される。
※2020年10月末頃からあまり観測されていなかった。
賞与支給、クリスマスなど年末に関連する件名や文面、ファイル名を使用し、
受信者を騙しやすくしている様子。

■Emotetに感染した場合に想定される被害
①情報流出
→受信メールの情報、感染端末の認証情報などが漏れる。
②次の攻撃のためのプラットフォーム化
→感染した自分の端末が次の攻撃の踏み台となって、他組織への攻撃メールを送信してしまう。
③他のマルウェアの感染
→Emotetに感染したことで漏洩した情報は、不正サーバへ飛ばされる。
⇒情報を他の組織へ売られたりレンタルされたりしてしまう。

■Emotetの感染フロー
①マルウェアスパムが着弾
②不正マクロの実行など
→EMTET本体がダウンロードされる。
③メールの内容、メールアドレスなどのデータを収集
④収集データを不正サーバへ送信
⑤収集データを元に更にマルウェアスパムを拡散
⑥なりすましメールなどに悪用される。

■Emotetの感染手法
Emotetは現時点※1で、
①ばらまき型マルウェアスパム
②「返信型」攻撃メール
のずれかで攻撃をしてきているとのこと。

①ばらまき型
→不特定多数に適当に送りつける。
自分には関係ない事柄や適当な文面・件名で送られてくるので、受信者に怪しまれやすい。

②返信型
→過去にメールのやり取りしたことがある人からの返信や転送という形式でメールがくる。
そのため受信者は不審なメールかどうか判断がしづらく、
うっかりファイルを開いたりマクロの有効化を実行してしまいやすい。

☆Emotetの侵入原因として最も多いのは、
メールに添付されているOfficeファイルの不正マクロを実行すること。

■感染への対策
・やり取りしたことのある人からのメールでも、ファイルの「コンテンツ有効化」を安易に押さない。
・企業として感染防止や早期検出のためのシステムを導入する。

※1　2020年12月24日時点
[CSS] 個人的CSSリファレンス(その1)

##個人的CSSリファレンス

引用文は、[HTMLクイックリファレンス](http://www.htmq.com/ "HTMLクイックリファレンス") 様から引用させて頂いております。

###box-sizing: border-box;

>パディングとボーダーを幅と高さに含める

###border-radius: 4px;

>border-radiusプロパティは、ボックスの４つのコーナーの角丸をまとめて指定する際に使用します。

###position: relative;

> (ボックスの配置方法が) 相対位置への配置となります。

###position: absolute;

> (ボックスの配置方法が) 絶対位置への配置となります。

###position: fixed;

>絶対位置への配置となるのはabsoluteと同じですが、スクロールしても位置が固定されたままとなります。

###float: left;

>指定した要素を左に寄せます。後に続く内容はその右側に回り込みます。

###display: block;

>ブロックボックスを生成する

###display: inline-block;

>要素全体としてはインライン要素のような表示形式だが、内部はブロックボックスで高さ・横幅などを指定できる。

###width: 25%;

>親ボックスに対する割合を％で指定

###box-shadow: 0px 7px #1a7940;

>box-shadowプロパティは、ボックスに1つまたは複数の影をつける際に使用します。
古いRuby環境と古いRailsを動かすのにすこしハマった

### 古い実行環境を構築する必要が発生した

Xcodeのアップデートや `brew upgrade` 等を行っていたら、
動いていた Rails アプリが動かなくなったので `rbenv` で Rubyからインストールし直した時にハマったメモです。
全然動かなくなったので `Gemfile.lock` も削除（リネーム）してから行いました。

#### 環境 

| プログラム | 動いていたバージョン | 動かなくなったバージョン | 現在のバージョン |
|:-:|:-:|:-:|:-:|
| bundler  | 1.13.2  | 2.2.3  | 1.13.2| 
| Ruby  | 2.3.0  | 2.3.0  |2.3.0 |
| Rails  | ~> 4.2  | ~> 4.2  | ~> 4.2|
| PostgreSQL  | 11  | 13  | 13|
| Xcode  | 11.x  | 12.3  | 12.3|


#### 最初の `bundler` インストール手順（動かなくなったバージョン）

```shell
% rbenv uninstall 2.3.0
% rbenv install 2.3.0
% gem install bundler # ← rubygems を新しくしろとエラーになるので
% gem update --system
% gem install bundler 
% cd MY_PROJECT
% bundle install --path vendor/bundle #　← budler のバージョン違いでエラー
```

ならば 古い`bundler` 入れれば問題ないだろうとインストール

```
% gem install bundler -v 1.13.2
```

やっぱりバージョン違いでエラーなので gem を見てみる

```
% gem list "^bundler$"

*** LOCAL GEMS ***

% bundler (default:2.2.3, 1.13.2)
```

下記リンクなどを参考に色々試したのですが、全然解消せず。。。
（というか `bundle` が動かなくなりました）
[How to change Bundler default version](https://stackoverflow.com/questions/54761120/how-to-change-bundler-default-version)

#### もう一度 `bundler` のインストール（バージョンエラーそのものは解消）

```shell
% rbenv uninstall 2.3.0
% rbenv install 2.3.0
% gem install bundler -v 1.13.2 # 最初から指定
% cd MY_PROJECT
% bundle install #　← bundle でのエラーは解消
```
エラーは解消できた。

#### bundle install 時の native extension 系(pg 等)のエラーが多発

function 名は違うかもしれませんが、結構多発しました。
原因はXcode 12にするとチェックが厳しくなるようです。

```
~snip~
Call.c:334:5: error: implicit declaration of function 'rb_thread_call_without_gvl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
~snip~

```

古いXcodeにすれば大丈夫という記事が多かったですが下記サイトを参考にコマンドを実行すればビルド出来ました。
[Postgresql gem install pg 0.18.4 passes, bundle install fails](https://stackoverflow.com/questions/36455625/postgresql-gem-install-pg-0-18-4-passes-bundle-install-fails)


```
bundle config build.pg '-- --with-cflags="-Wno-error=implicit-function-declaration"'
```

同様に`puma`,`nokogiri`,`libxml`等もエラーになる場合があるようですが下記のように追加すれば動く様です。

```
bundle config build.puma '-- --with-cflags="-Wno-error=implicit-function-declaration"'
```

`--`は必要性がちょっと解りませんでしたが。。。

#### ビルド出来た pg が PostgreSQL にアクセス時にエラー

```
（抜粋）
Add `gem 'pg'` to your Gemfile and ensure its version is at the minimum required by ActiveRecord

```
バージョン指定をしていなかったので pg 1.x が入ってしまっていました。

Gemfile を修正

```Gemfile
gem 'pg'
↓
gem 'pg', '0.18.4'
```

`Gemfile.lock`があるとはいえ、`Gemfile`に書く gem は基本的にバージョン指定しておかないと駄目ですね。。
SIGNATE CLI でデータセットをダウンロードする

### SIGNATEは、データサイエンティストのための統合プラットフォーム。
機械学習コンペを開催しています。
コンペのデータセットは公式ページからダウンロードできますが、**データセットはサイズが大きいので**
**コマンドラインからダウンロードできるとColabに直接ダウンロードできて便利。**
SIGNATE CLIでコマンドラインから操作できる。

# 手順

### １、SIGNATEのインストール

```shell
pip install signate
```

### ２、SIGNATE でアカウント登録

### ３、APIトークンのダウンロード

```shell
signate token --email=事前準備で登録したemail --password=事前準備で登録したパスワード
```
>The API Token has been downloaded successfully.


SIGNATEのページのアカウント設定からもJsonファイルでトークンを取得できます。

### 4、動作確認

```shell
signate --help
```

>Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

>Commands:
  download  Download the file of competition
  files     List file of competition
  list      List competition
  submit    Submit a result file to the...
  token     Download the API Token

### 5、signateでやっているコンペの一覧を取得

```shell
signate list 
```
![スクリーンショット 2020-12-24 20.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/52782485-662d-39f8-e48d-ce71f436b1ee.png)

### 6、コンペの提供データ一覧を取得

```shell
signate files --competition-id=<competition-id> 
```
![スクリーンショット 2020-12-24 20.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/64c90a09-60db-262c-6aa6-c705ff0e14a5.png)

### 7、データセットをダウンロード
デフォルトではカレントディレクトリに全てのファイルがダウンロードされます。とのことです。

```shell
signate download --competition-id=<competition-id> 
```
**僕はColabでやってエラー出ました。次の１ファイルずつダウンロードする方法で無事ダウンロードできました。**
>Traceback (most recent call last):
  File "/usr/local/bin/signate", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/dist-packages/signate/cli.py", line 205, in main
    response = json.loads(ae.body)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

JSONと書いてあるので、応募用サンプルのダウンロードでつまづいたのかと。。。

### 8、１ファイルずつダウンロード

書き込み先も指定できます。

```shell
signate download --competition-id=1 --file-id=1 --path=<保存先ディレクトリのパス>
```
### 9、Zipを解凍

Colab上で解凍できるように、おまけで書いておきます。
Google Driveをマウントして展開すると便利ですよ。

```python
import zipfile

with zipfile.ZipFile("./train_images_1.zip") as existing_zip:
    existing_zip.extractall('./')
```

### 10、コンペにファイルを提出

```shell
signate submit --competition-id=<competition-id> <提出ファイルのパス>
```



🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
画像アップロード時に画像を動的に表示・切り替える(JavaScript, jQuery, Laravel)

## 目標

[![Image from Gyazo](https://i.gyazo.com/c0353b5d0bb59f11e334ba09b5b005df.gif)](https://gyazo.com/c0353b5d0bb59f11e334ba09b5b005df)

jQueryを使用して、選択した画像を動的に変化させて、どの画像をアップロードするのかわかりやすくします。

## HTML

```html
<!doctype html>
<head>
     //使用するjQueryを定義
     <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
・・・
<form action={{route('hogehoge')}} method="post" enctype="multipart/form-data">
     //imgタグを設定(/image/Noimage.jpgのところは、publicディレクトリの配下の構成に応じて適当に変更してください。)
     <img id="img_prv" src="{{ asset('/image/Noimage.jpg') }}">
     //画像ファイルを選択するinputタグを設定
     <input id="img_upload" type="file" accept="image/*" name="image">
</form>
```

## jQuery

```javascript
<script>
        //画像が選択される度に、この中の処理が走る
        $('#img_upload').on('change', function (ev) {

            //コンソールタブで適切に処理が動いているか確認
            console.log("image is changed");

            //このFileReaderが画像を読み込む上で大切
            const reader = new FileReader();
            //--ファイル名を取得
            const fileName = ev.target.files[0].name;

            //--画像が読み込まれた時の動作を記述
            reader.onload = function (ev) {
                $('#img_prv').attr('src', ev.target.result).css('width', '150px').css('height', '150px');
            }
            reader.readAsDataURL(this.files[0]);
        })
</script>
```

これで、画像ファイルをアップロードするたびに、画像が動的に切り替わるはずです。
是非試してみてください。

## 最後に

不明点、質問などあれば、コメント欄にお願い致します。

もっと良い方法や、FileReaderの詳しい解説などあれば、是非教えていただきたいです。
アドベントカレンダー22日目：SREを読んでみた「リリースエンジニアリング」編③

前回は、リリースエンジニアの役割とその哲学について、学びました。
リリースにおいては、成果物に一貫性と再現性を担保する必要があり、またリリースを高速化するためのツールの開発や自動化が行われました。
今回は、継続的ビルドとデプロイメントについてです。
GoogleはRapidという自動リリースシステムを開発しました。これによりスケーラブルで信頼性の高い密閉型リリースを生成できるフレームワークを提供します。
Rapidとその関連ツールによる管理についてみていきます。

### ビルド
GoogleはビルドツールにBlazeを使っています。
Blazeはビルドするときに依存対象のターゲットを自動的にビルドします。ビルドターゲットはRapidから指定され、Rapidプロジェクト固有のフラグがBlazeに渡されます。すべてのバイナリはビルド日付、リビジョン番号、ビルド識別子を表示するフラグをサポートするので、あるバイナリから容易にビルドの記録をたどることができます。
ビルドの密封性が高まり、問題の検出速度が早まります。

### ブランチ
すべてのコードはメインブランチからチェックアウトされています。しかし、メインブランチから直接リリースが行われるのではなく、メインブランチからプロジェクトのブランチが切られています。そのブランチの変更はメインブランチへマージせず、バグフィックスがメインブランチへチェリーピックされます。これにより、無関係の変更をメインブランチへ取り込まれるのを防ぎ、各リリースの内容が厳密にわかります。

### テスト
継続的テストシステムにおいては、変更が投入されるたびにメインブランチに対して、ユニットテストが実行されます。それによりビルドやテストの失敗はすぐに検出されます。
リリースエンジニアリングにおいては、継続的ビルドの際にユニットテストが行われることが推奨されています。このようにすることでリリース時に実行されるビルドが失敗してしまう確率を下げます。

### パッケージ化
Googleにおいて、ソフトウェアは、Midas Package Manager（MPM）によって、プロダクション環境へ配布されます。パッケージは名前とユニークなハッシュによるバージョンが正当性の為に与えられます。Rapidは、ビルドIDを含むラベルを付けるので、パッケージ名とラベルを使えば、パッケージを一意に特定できます。

### Rapid
Rapidは、blueprintsというファイルで設定されています。ビルドのとテストターゲットの指定、デプロイメントのルール、管理情報を定義します。Rapidのプロジェクトに対して行えるアクションの権限設定は、ロールベースのアクセスコントロールで指定されます。

### デプロイメント
Rapidは、単純なデプロイメントを直接行うこともできます。blueprintsのデプロイメント定義と専用のタスクエグゼキュータで、新たにビルドされたMPMパッケージを使うように稼働中のBorgジョブを更新します。
また、複雑なデプロイメントをする場合は、ロールアウト自動化フレームワークのSisyphus（シシファス）が使われます。
Sisyphusにはダッシュボードが付いており、ロールアウトのコントロールと進行状況のモニタリングが行えます。

## まとめ
* リリースの主要部分の自動化は、開発を高速化する。

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　94-97
Amazon SNSを使ってみた

## 用語

- トピック
	- 配信対象をグルーピングし、配信対象に一斉に通知を配信するための機能です
- サブスクリプション
	- 作成したトピックと配信対象のエンドポイントを紐づけるデータ
- パブリッシュ
	- 通知を発信すること

## 設定

### トピックの設定

- トピックの作成を行います

コンソール > Amazon SNS > トピック へ移動して作成を行います

![Simple Notification Service 2020-12-19 14-28-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a74d4c34-40f6-4825-aa47-756debd86aaf.png)


- トピックの作成

タイプ : SMSを使用するので、スタンダード
名前 : 任意の名前を設定
表示名 : 任意の表示名を設定
記載を行ったら、 `トピックの保存` で保存を行います

![Simple Notification Service 2020-12-19 14-30-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/9f596ee5-7058-14d7-478d-e8d7cb0a24c5.png)


- トピックの設定完了

トピックの設定が完了しました

![Simple Notification Service 2020-12-19 14-31-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/310e2e40-d88d-1947-d858-5ff232f422cf.png)


### サブスクリプションの設定

- サブスクリプションの作成

コンソール > Amazon SNS > サブスクリプション から
サブスクリプションの作成を行います

![Simple Notification Service 2020-12-19 14-36-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8e12b588-3292-3a83-43fc-930f68487e1e.png)


- サブスクリプションの設定

トピックARNには、先程作成したトピックのARNを入れます。
選択肢が出てくるので、適切なトピックを設定ください。
プロトコルはSMSを使用するので、選択。
エンドポイントは携帯の電話番号を入れました。
記載を行ったら、サブスクリプションの作成で保存してください。

![Simple Notification Service 2020-12-19 14-37-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f04e98fe-5452-9768-f38e-20652485bb3c.png)


- サブスクリプションの完成

先程作成したサブスクリプションができました。

![Simple Notification Service 2020-12-19 14-39-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8a476ba0-ba88-9b2b-e2a4-2ac498535adc.png)

### パブリッシュ(発信)を行う

- メッセージの発信

Amazon SNS > トピック へ移動します。
適切なトピックにチェックを行い、メッセージの発行を行います

![Simple Notification Service 2020-12-19 14-44-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3c612639-6f2f-e7d8-9c52-3546330cf3c9.png)


- トピックへのメッセージの発行

件名はわかりやすいように書いておきます

![Simple Notification Service 2020-12-19 14-46-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/e9e78d0e-5ab6-0b8c-7845-12f2de59c4e5.png)

トピックにアタッチしているサブスクリプションの、どのプロトコルに送信するかを指定しますが、
今回はSMSのサブスクリプションしかアタッチしていないので、すべての配信プロトコルにしておきます。
そして、送信するメッセージを記載いたします。
その他はデフォルトで、記載が終わればメッセージの発行を行います。

![Simple Notification Service 2020-12-19 14-47-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/e98c8d74-83e7-4fbd-e4f2-1a75a9a58229.png)


## 確認

- SMSをスマホで確認

スマホで受け取ることができました

![Screenshot_20201219-145059.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/56ee0b17-ff1e-a9f4-3c2e-9055b400c6e7.png)


## 参考

- [Amazon SNSでプッシュ通知を送るための基礎知識](https://www.unitrust.co.jp/6182)
BASHTree - クリスマスツリーを表示するShell

メリークリスマス🎅！
Linux Advent Calendar 2020（Qiita）25日目のエントリーです。
在宅ワークで街中にろくにでれないまま迎えたクリスマス。

# コンソール上でもクリスマス気分を味わいたくて

探してみたらありました。


以下コマンドをTerminalで入力し、実行すると、、、

```
curl https://raw.githubusercontent.com/mikeelston/BASHTree/master/tree-EN.sh | bash
```

![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219486/ad57d825-922e-1376-b84f-540c2f43188e.gif)



for reference:
https://github.com/mikeelston/BASHTree![tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219486/0f45f87b-9650-64c3-04de-28f9627ec0e8.gif)