OmniAICreator/Qiita-1.07M huggingface dataset:
チームの習慣を変えた見える化を3つ紹介します

# 概要

導入した見える化の中で、チームの習慣となったものを3つ紹介します。
また、これらの見える化を、どのような観点で導入したかを最後に説明します。

# 朝会内容をslackに事前に記入する

朝会用のチャンネルをslackに作り、そこに毎朝投稿してもらうようにします。
(本記事では朝会はデイリースクラムと同義とする)

例は以下です。
![スクリーンショット 2020-12-05 23.12.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/c1d988d7-922b-34cf-55d8-fccb050db8ea.png)

## タイミングと見えるようになったもの
* **毎朝**、朝会の発言内容が文字で見えるようになった

## 身につく習慣
* 事前に朝会内容を考える
* 事前に朝会内容を記入する
* 1日のはじめに朝会チャンネルにチームが行くようになる

## 良い点

* 欠席時に情報共有できる
* 過去内容を振り返られる
* 言い忘れを防止できる
* 書くことで困りごとが言いやすくなる
* （出社時）周りが煩くても、相手の言いたいことが理解できる
* （リモート時）音声が悪くても、相手の言いたいことが理解できる

## 悪い点
* 書く手間がかかる
* （出社時）チームに向かって話すのではなく、ディスプレイを読んでしまう

# ベロシティーをslackに投稿する

直近のベロシティと予測値の棒グラフをslackに投稿します。
例は以下です。

![スクリーンショット 2020-12-06 0.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/82426451-b8c7-6d88-252b-6d325dd49b5d.png)



## タイミングと見えるようになったもの
* **振り返り前に**、直近スプリントのベロシティグラフが見えるようになった

## 身につく習慣
* ベロシティの変化を意識するようになる
* 見積もりと次のスプリントのタスク数を意識するようになる
* どのようにすればスプリント内でタスクを完了できるか考えるようになる

## 良い点
* ベロシティー起点での議論がレビューや振り返りで増える
    * 「チームで、なぜここまで見積と実績で解離が出るのか？」とチームで議論されました。
    * 「タスクを完了しやすくするにはどうすれば良いか？」とチームで議論されました。
* POにチームの平均ベロシティを知ってもらえる
* Webページに行かなくても、ベロシティが見られる
* 平均ベロシティの計算の手間がなくなる
    * 我々は、過去3スプリント平均を次スプリントの予測値としています

## 悪い点
* 実装・メンテナンスコスト
    * JIRAのAPIをPythonプログラムで叩いています。

# カレンダーを表示する

例は以下です。
実際はslackBotが投稿します。

![スクリーンショット 2020-12-06 0.08.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/ebe49372-408b-754f-87ee-bf19502c3550.png)


## 身につく習慣
* カレンダーを毎日見るようになる
* カレンダーに予定を入力するようになる

以前はslack勤怠用チャンネルで休みの連絡をしていましたが、
カレンダーの自動表示でslackをさかのぼる必要がなくなりました。

カレンダーを毎朝slackに自動表示するだけで、
**ルールとして決めなくても**チームはカレンダーに予定を入力するようになります。

## タイミングと見えるようになったもの
* **毎朝**、チームとチームメンバーの予定が見られるようになった。

## 良い点
* カレンダーのページに行かなくて良い
* 予定忘れの防止になる
* チームのリリース予定などが確認できる
* 不在の理由がわかる
* 朝会のファシリテータが覚えるプロセスが１つ減る

## 悪い点
* 実装・メンテナンスコスト
    * ConfluenceのURLをPythonプログラムで叩いています

# 実行時の考え方

以下3点を意識しています。

* 1clickを省略する
* 必要な時に必要な情報を
* 行動を誘発する

## 1clickを省略する

Webページを見に行くより、slackに流れた方が楽です。
1クリックという行動を**自動化**してしまうイメージです。

勝手に情報が流れてくると言うのも、透明性を上げるために重要です。


## 必要な時に必要な情報を

slackには、適切なタイミングで表示するのが重要です。
トヨタ生産方式の**ジャスト・イン・タイム**のイメージを持っています。

例えば、チームのベロシティの情報は、チームのプロセス改善をスプリントレトロスペクティブのタイミングでだけ必要です。


## 行動を誘発する

チームに誘発したい行動から打ち手を考えます。
情報の**透明性**によりチームの行動を誘発させるイメージです。


今回の例では以下を目的としました。

|見える化|誘発したい行動|
|---|---|
|朝会内容記入|朝会の発言内容を事前に考えていて欲しい<br>朝会チャンネルを見て欲しい|
|カレンダー表示|カレンダーに各自の予定を入力して欲しい|
|ベロシティ表示|ベロシティの情報を使ってレトロスペクティブで議論して欲しい|


# 終わりに：勝手に入ってくる情報に注目する

slackに流れる情報によって、チームの行動や発言内容が変わるのを見るのは面白いです。
是非お試しください！
sox で .raw ファイルを .wav ファイルに変換

# 基本形

例）`input.raw` を `output.wav` にしたい場合

```shell
sox -t raw -e signed-integer -b 16 -r 44100 input.raw -t wav output.wav
```

基本形は↓のように、各ファイルにオプションを付つける形です。出力ファイルのオプションは入力と同じなら省略可能です。

```
sox [inputオプション] [inputパス] [outputオプション] [outputパス]
```


| オプション | 意味 |
|:---|---|
| `-t`, `--type` | ファイルの種類（raw, wav, など)  |
| `-e`, `--encoding` | エンコーディング (`signed-integer`, `unsigned-integer`, `floating-point`, など) |
| `-b`, `--bits` | 量子化ビット数 |
| `-r`, `--rate` | サンプリング周波数(Hz) |

※すべてのオプションは[公式ページ](http://sox.sourceforge.net/sox.html)で確認してください


# (メモ) サンプリング周波数を変更

出力オプションを与えることでサンプリング周波数の変換ができます。

例）48kHzのwavファイルを8kHzにダウンサンプリングする

```shell
sox -t raw -e signed-integer -b 16 -r 44100 input.raw -t wav -r 8000 output.wav
```

# (メモ) シェルを使って一括で変換

↓のように、`raw`フォルダの中身を、拡張子を変えつつ wav ファイルに変換したいとします。

```
.
├ raw
│　├ 001.raw
│　├ 002.raw
│　:
└ wav
　　├ 001.wav
　　├ 002.wav
　　:
```

次のように`for`を使ってワンライナーで書けます。

```shell
for f in $(ls ./raw/*.raw); do sox -t raw -e signed-integer -b 16 -r 44100 "${f}" -t wav "wav/$(basename $f .raw).wav"; done
```

# リンク集

* [SoXリファレンス（公式）](http://sox.sourceforge.net/sox.html)
* [soxコマンドで音声ファイルを編集する10の例](https://blog.asial.co.jp/885): 様々な音声処理の方法が紹介されている
position: fixed;で中央に揃える方法と、モーダル内の画像を縦最大に表示する

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ CSSの基礎知識が増える
・ `position: fixed;`で中央に揃える方法
・ モーダル内の画像を縦最大に表示する

## 例

モーダルウィンドウを例に挙げますが、必要箇所のみ記述しています

```haml:index.haml
.modal
  = image_tag src="isara_full.png",class:"modal-height"
```

```scss:index.scss
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.modal-height {
  height: -webkit-fill-available;
}
```

![スクリーンショット 2020-12-06 11.05.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/1e94576a-657d-b56f-bc51-5fd3dbfd24da.png)

![スクリーンショット 2020-12-06 11.06.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/5ff17562-6687-71e6-c0de-da3ca6ec39c6.png)

画像の高さと横幅に合わせて自動で中央に揃えてくれます。
【Swift】 絶対値に変換する方法【初心者】

#はじめに
絶対値にする方法がわからなかったので、調べた事をメモとして記録しておこうと思います。

#環境
macOS Catalina バージョン10.15.4
Xcode バージョン11.7
Swift5

###絶対値にする（Int型）
absを使用

```swift
//Int型
 let numberA:Int = -1
 print(numberA)//-1
 //絶対値にする
 print(abs(numberA))//1
```
###絶対値にする（Double型）
fabsを使用

```swift
//Double型
let numberB:Double = -1.0
print(numberB)//-1.0
//絶対値にする
print(fabs(numberB))//1.0
```

###絶対値にする（Float型）
fabsfを使用

```swift
 //Float型
let numberC:Float = -1.0
print(numberC)//-1.0
//絶対値にする
print(fabsf(numberC))//1.0
```

#全コード

```swift
import UIKit

class ViewController: UIViewController {

    //Int型
    let numberA:Int = -1
    //Double型
    let numberB:Double = -1.0
    //Float型
    let numberC:Float = -1.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        print(numberA)//-1
        //絶対値にする
        print(abs(numberA))//1
        
        print(numberB)//-1.0
        //絶対値にする
        print(fabs(numberB))//1.0
        
        print(numberC)//-1.0
        //絶対値にする
        print(fabsf(numberC))//1.0
        
    }
}
```

#終わりに
初学者のため、もし間違いがあれば教えていただければ幸いです。

[twitter](https://twitter.com/koara1237)
QAの大学生アルバイトが入社1年を振り返る

# はじめに
[「GLOBIS Advent Calender 2020」](https://qiita.com/advent-calendar/2020/globis)の6日目の記事です。

現在QAチームにてアルバイトをしている大学生です。
入社をして1年が経ちましたので、これまでやってきたこと、今後のことなどをアニュアルレポート風にまとめて振り返りました。

大きな実績を残したわけでも、成功を掴んだわけでもない、一般大学生アルバイトの「なんちゃってアニュアルレポート」に果たして需要があるのかは分かりませんが、読んでくださった方の何かしらお役に立つことができたら幸いです。

### 少し自己紹介
- 私立文系大学で経済と経営学を勉強している4年生
- 静岡からフルリモートで週3勤務
- 大学3年次の講義でプログラミングをする機会があり、「エンジニアがいる環境でもっとプログラミングの勉強をしたい」と思ったことからグロービスに応募

↓から本題です

# 私版アニュアルレポート
## 総評
自分の人生の中で一番悩み多き1年でした。
QAに関する事前知識もない状態で「開発がしたい」と意気込んで入社したものの、当時プログラミング歴3ヶ月程度だった自分は色々壁にぶち当たり、葛藤することがありました。
加えて「就活」というビッグイベントやコロナ自粛の影響で、自分の過去や将来と向き合う時間があり、とことん内省する1年だったなと思います。


## 活動概要
QA活動に関わる技術調査や開発をメインにやらせていただきました。
うち印象に残っている業務を3つ挙げます。

①GitHubとSlackの連携
入社して一番最初の開発業務です。
「GitHubに特定のラベルが付くと、Slackのチャンネルに通知が届く」というシステムを作りました。GASやWebhookなどを利用しての開発だったのですが、分からないことだらけでエラーを出しまくり、「楽しい」よりも「大変」というネガティブな気持ちの方が強かった記憶があります。自分が何日もかけて解決できなかったエラーを先輩社員が数分で解決してしまったときは、自分の力不足を感じてとても落ち込みました。。

②Androidアプリの自動化テストの実装
「グロービス学び放題」という動画学習サービスのE2E自動化テストの実装に取り組みました。
初めて実務でPRやブランチ機能を使い、感動したことを覚えています笑　個人開発の時には気にすることがなかったメソッドの命名やちょっとした文言など、細かなことにも気を配るところにエンジニアのプロフェッショナルを感じました。

③JiraとSlackの連携
「Slackにメッセージが投稿されると、投稿内容がJiraにチケットとして起票される」という仕組みを作りました。
相変わらずエラーや不具合を出しまくったものの、SlackやDiscordなどのコミュニケーションツールを活用して質問力を磨くことができたかなと思います。

こうした業務を通じて、QAで使われている技術や、世の中にあるクレームの実情を知りました。例えば、動画の再生速度やログインのプロセスなど、致命傷ではないクレームが多くありました。商品開発にはここまで気を配らなければならないのだということを実感しました。
また、自動化ツールを開発する過程で、業務フローに対する理解が深まり、フローに関わる人たちへの感謝の気持ちが強まりました。

## ビジョン・ミッション
一丁前に考えてみました。
### ビジョン
**多くの人が幸せを実感できる社会造りに貢献したい**
いきなり大層な夢ですが、究極的には、自分の周りにいる大切な人たちが幸せを実感できる毎日を送れるようにしたいです。




### ミッション
**働くことに誇りややりがいを感じることができる組織を作る**
何を幸せとするかは人それぞれだと思いますが、自分なりに考えた結果このミッションに辿り着きました。


## 行動指針
- **渦の中心になる**
自分の仕事を振り返ると、まだまだ周囲の人たちと協力し合えていないと感じます。渦の周りを回るだけでなく、積極性を持って周りを巻き込めるように精進します。。

- **こだわりをもつ**
情報過多で意思決定が難しい世の中になったと思いますが、自分軸を持って情報に踊らされない人間になりたいです。

- **土俵の真ん中で相撲をとる**
生来のマイペースな性格が災いして、今まで数々の失敗をしてきたので、常に余裕を持って行動できるようにしたいです。




## 主要データ
本来であれば財務諸表などを載せるのだと思いますが、そんなものはないので適当に数字を出してみました。

- 稼働日数：121日
- うち出社した日数：60日
- notion記事数：12本
- LTで話した回数（社外も含む）：5回
- 読書冊数：24冊
- Slack投稿数：100


# さいごに
最後まで読んでいただきありがとうございます。
自己満足のような記事になりましたが、アニュアルレポート自体は作ってよかったなと思います。振り返りツールとしておすすめです。
私は来年新社会人になるのですが、就活では就きたい職種で内定をもらうことができず落ち込んでいました。それでも、グロービスで学んだことを忘れず、置かれた場所で咲けるように頑張ろうと思います。
Python基本文法note（2）

#初めに
pythonを勉強中のメモです
色々今後追加していきます

#モジュールとパッケージ
##コマンドライン引数

~~~python3
import sys

print(sys.argv)
~~~

##Import文とAS
モジュールからImportするのが良い

~~~python
#書き方１
import lesson_package.utils

r = lesson_package.utils.say_twice('hello')
print(r)
#書き方２
from lesson_package import utils

r = utils.say_twice('hello')
print(r)
#書き方３(これはわかりづらいのであまり推奨されていない)
from lesson_package.utils import say_twice

r = say_twice('hello')
print(r)

#asも使えるが推奨されていない
from lesson_package import utils　as U

~~~

##絶対パスと相対パスのImport

~~~python
#絶対パス
from lesson_package.tools import utils
#相対パス(あまり推奨されていない)
from ..tools import utils
~~~

##アスタリスクのインポートと__init__.pyと__all__の意味

~~~python
#__int___.pyのファイルに読み込む記述をする

__all__ = ['animal']

#ディレクトリにあるファイルを読み込む（あまり勧められてない）
from lesson_package.talk import *
~~~

##ImportErrorの使い所

~~~python
try:
    from lesson_package import utils
except:
    from lesson_package.tools import utils
~~~

##setup.pyでパッケージ化して配布する

~~~python
~~~


##組み込み関数
https://docs.python.org/ja/3/library/functions.html

~~~python
import builtins

builtins.print()

ranking = {
    'A' : 100,
    'B' : 85,
    'C' : 95
}

print(sorted(ranking, key=ranking.get, reverse = True))
>>>['A', 'C', 'B']
~~~


##標準ライブラリ

~~~python
#適当な変数のなかに同じ値がいくつあるか調べるプログラム
s = "lsdkfgsdighsaaidjfglskjaadfglksjdfbgsd"

d = {}
for c in s:
    if c not in d:
        d[c] = 0
    d[c] += 1
print(d)


d = {}
for c in s:
    d.setdefault(c,0)
    d[c] += 1
print(d)

>>>{'l': 3, 's': 6, 'd': 6, 'k': 3, 'f': 4, 'g': 5, 'i': 2, 'h': 1, 'a': 4, 'j': 3, 'b': 1}
>>>{'l': 3, 's': 6, 'd': 6, 'k': 3, 'f': 4, 'g': 5, 'i': 2, 'h': 1, 'a': 4, 'j': 3, 'b': 1}

#pythonの標準ライブラリーを呼び出す
from collections import defaultdict

d = defaultdict(int)

for c in s:
    d[c] += 1
print(d)
>>>{'l': 3, 's': 6, 'd': 6, 'k': 3, 'f': 4, 'g': 5, 'i': 2, 'h': 1, 'a': 4, 'j': 3, 'b': 1}

~~~


##サードパーティーのライブラリ
https://pypi.org/

~~~python
import tarmcolor import colored

print('text')
~~~


##importする際の記述の仕方
importするものに対して一文ごとに書く
アルファベット順に記述する

~~~python
#サードパーティのライブラリーを読み込む際は一行空ける
import collections
import os
import sys

import termcolor

import config

#fileを使うとどこにあるかわかる
print(collections.__file__)
print(os.__file__)

#pathを見たい場合
print(sys.path)

~~~


##__name__と__main__

~~~python

print(__name__)
>>>__main__


~~~
LaravelでRailsみたいなデバックがしたい。（スクール卒業生向け）

#概要
巷にあふれる某スクール卒業生。
彼らがスクールで学ぶのはRuby on Railsなのだが他人との差別化を図る上でLaravelを用いてポートフォリオを作成する方々を散見する。

彼らがスクールで学んだ、デバック方法は「binding.pry」ほぼ一択。

Laraveでよく見かけるデバック方法は,var_dump(); や dd(); でちょっとモヤモヤしてる方向けの記事になります。

##結論
「binding.pry」みたいなことはLaravelでも出来る！！

```
eval(\Psy\sh());
```

処理を止めたいところに「binding.pry」のように書いて、ターミナルで確認するだけです。




恐らく、この説明でスクール卒業生は使いこなせると思います。
「大金払ってRuby on Railsを学び、実務で使うのはLaravelなんですか？」
という意見もあると思うのですが、個人的には自分が卒業生でlaravelエンジニアというのもあり応援したい気持ちです。
SpringBoot個人メモ

@controller アノテーションをコントローラクラスにつける
@GetMappingをメソッドにつける
引数にModelを追加する
model.addAtribute("変数名",値)

htmlタグの中にthymeleafのおまじないを追加する
htmlファイルのタグの中にth:text="${変数名}"を記述すると値を画面表示できる

画面表示のみならControllerクラスとhtmlファイルのみ追加すれば良い。
CodeceptJS のテスト実行結果を AllureReport でリッチにレポートする方法

#はじめに
テスト自動化ツール CodeceptJS のテスト実行結果を視覚的にカッコ良いレポートに出力するプラグインとして、Allue Report（アリュール）があるそうです。
今回は、CodeceptJS に Allue Report プラグインを追加し、テスト結果を html でレポート出力する方法について確認していきたいと思います。
CodeceptJS 本体の使い方については、この記事では取り扱っておりませんのでご留意ください。

##＜実行環境＞
+ Windows 10 Pro
+ Node.js Ver.14.15.1
+ CodeceptJS Ver.3.0.2
+ allure Ver.2.13.0

#Allure をインストールする。
```powershell
npm install -g allure-commandline --save-dev
```
#CodeceptJS の構成ファイルに、Allure プラグインを追加する。
```codecept.conf.js
plugins: {
    allure: {
        enabled: true
    }
}
```
常時利用ではなく、都度 allure を利用するか指定したい場合は構成ファイル `enabled: true` をコメントアウトしておき、テスト実行時に `--plugins` オプションで指定できる。

```powershell
npx codeceptjs run --plugins allure
```

プラグインが有効になっているか確認したい場合は、テスト実行時、`--verbose` オプションを指定すると詳細が確認できる。テストステップの詳細も確認できるので、デバッグ時にも便利なオプションです。

```powershell
npx codeceptjs run --verbose
```

#テストスクリプトを実行する。
```powershell
npx codeceptjs run
```

#`allure serve` で、Allure レポートが表示できる。
##＜内部動作＞
1. テストを実行すると、`output` フォルダーにテスト実行結果の xml が出力される。
2. `allure serve` の引数に指定したフォルダー内にある xml ファイルを解析し、一時フォルダーに html ファイルを生成する。xml ファイルが複数ある場合は、最新の xml ファイルが自動的に選択されるみたい。
3. Web サーバーを起動し、 html ファイルが表示される。 

```powershell
allure serve ./output
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302008/3520e309-3f7b-b8d4-b67c-8475403a03e5.png)

左下の「En」ボタンから「日本語」を選ぶと、なんと日本語表記もできちゃう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302008/778fa1e2-f00f-0585-08fe-5d5b46274200.png)

# まとめ
Allure をインストールし、 CodeceptJS の構成ファイルでプラグインの記述を追加するだけで、リッチなテストレポートを出力することが出来るようになりました。
問題点として、Allue の Web サーバーを起動しないとこのレポートを見ることが出来ませんでした（Allure で生成された html ファイルを直接開いても、レポート内容が表示されない） 。
過去のレポートを見たり、チームメンバーでレポートを共有するには、どうしたらよいのだろう。公式サイトのドキュメント読んでみたけど、わかりませんでした。

Selenium から Cypress に乗り換える予定で作業していたのだけれど、CodeceptJS の方が扱いやすいのかな。年末年始に時間作って、いろいろやってみたい。今回の記事はここまで。
最後までお読みくださりありがとうございました。
laravel リレーション関係

##データベーステーブルの関係は大体下記のように分けられます。

・1対1
・1対多
・多対多

##1対1
例：userとphoneの関係、基本一人には一つの番号しか持ってないですね。　

userでphoneを検索したいとき、二つの関係の定義：hasOne
phoneでuserを検索したいとき、二つは逆関係の定義：belongsTo

##1対多
例：articleとcommentの関係、一つの記事に複数のcommentが存在しますね。　

articleでcommentを検索したいとき、二つの関係の定義：hasMany
commentでarticleを検索したいとき、二つは逆関係の定義：belongsTo

##多対多
例：userとroleの関係、userが多くのroleを持ち、rolesも大勢のuserを持っています。　
二つの表の関係を別の表user_roleで結びつけます。

userでroleを検索したいとき、二つの関係の定義:belongsToMany

```:Models
Class User extends Model
{
 public function roles()
 {
   return this->belongsToMany('App\Role','role_user','user_id','role_id');
 }
}
```

roleでuserを検索したいとき、二つは逆関係の定義：belongsToMany

```:Models
Class Role extends Model
{
 public function users()
 {
   return this->belongsToMany('App\User','role_user','role_id','user_id');
 }
}
```
AWSアカウント初期設定周りを先人の教えに沿ってやってみた

<h1>ナニコレ

この記事は Ubiregi Advent Calendar 2020 6日目のエントリです。

AWSアカウントを作成した直後に、サーバ起動させるとか様々なサービスを利用する前にやるべきこと。

ほとんど@tmknomさんの記事で初期設定できた(と思っている)んですが、
個人的に初期設定で詰まったところや、理解するのに時間が掛かったポイントをまとめてみようと思います。
https://qiita.com/tmknom/items/303db2d1d928db720888

<h1>前提として

・本記事はAWSのアカウントがすでに作成されている前提の記事です:persevere:
・公式ドキュメントは全く読んでおりません！
・本来は読むべきですが、触りながら理解するスタイルの方が性に合っているのでわからないところを逐一読んでいくスタイルで進めました。
・理解が間違っていることは往々にしてあると思いますので、ご指摘いただければ幸いです！

<h1>そもそもなぜアカウントの初期設定をやる必要があるのか？

これは記事の中にも記載されているのですが、主にセキュリティ周りを強化することによって、クラウド破産なるものを防ぐのが目的。初期状態の場合、ユーザーIDとパスワードが合致してしまうと、ブルートフォースアタックなどで打ち破られる可能性もあり、お勧めできない。
おそらくAWSをこれから学ぼうという人は必見だと思われる。
ではここからは個人的に理解に時間が掛かった箇所を書いていく。

<h2>AWSアカウント？IAMアカウント？なんじゃこりゃ？

・私がドキュメントを読んでいないのが諸悪の根源w
・AWSアカウント=rootアカウント(=root is GOD！)
・これが乗っ取られたら詰み！
![gakkari_tameiki_man (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416692/46772945-82a0-5a6b-331b-60896aa2a83b.png)

・そういえばこの記事を書いていて思ったんですが、万が一乗っ取られてしまったらどうすれば良いんだろう・・・。アカウント停止すれば良いのかな？

<h2>仮想MFA認証コードが2つ必要

仮想MFA認証(Google Authenticatorなど)で認証コードを<b>2つ</b>入力する必要があるんですが、
「えっ、2つもコード無いんだけど・・・」となりました。

![スクリーンショット 2020-12-06 10.07.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416692/20e977eb-8795-0e00-ae2a-3b7105f761e2.png)

ドキュメント見ていない自分がダメ過ぎただけなんですけど、これは認証アプリを開いた時に表示された数字 + 30秒ぐらい経過した後の更新された数字をいれるだけでOKです。Qiita記事だけではなく、公式ドキュメントがいかに大事かがわかりました・・・。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html

<h2>セキュリティステータスが表示されていない

これは予想なんですが、現在はダッシュボードにある「ベストプラクティス」の項目がそれに該当するのではないでしょうか。あまり深く考えても仕方ないので、ここは適当に読み替えて進めました。
![スクリーンショット 2020-12-06 10.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416692/f60db293-2507-8fdc-f96b-e171cc05bbd7.png)

<h2>知らない用語がとにかく多い

こればかりはもう調べながらふんふんと理解するしかないと思いますが、AWSはサービス豊富ですね(白目)

<h2>AWSマネージメントコンソールの不正アクセス検知の構築が難しそう

自分も平穏な生活を送りたいwのとせっかく会社でslackを使っているので、試しに導入してみたいという気持ちで絶賛格闘中です。Lambdaってなんだよ・・・からです。

<h2>最後に

今年も非エンジニアではありますが、アドベントカレンダーイベントに参加させてもらえるということで、今学習中のAWSに関する記事を書かせてもらうことにしました！
大した記事にはなりませんが、その辺りはご愛敬でw
しかしながら記事を書くというのは難しいですね・・・
VSCode拡張 Tomcat for Java でDocker上のTomcat を登録できない時の対処法

## これは何
vscodeでtomcatの開発環境を構築する際，**Tomcat for Java**にDocker上のtomcatを登録できずハマったときのメモ．

## 環境
- Windows10pro
- Docker Engine - Community  Version:          19.03.13
- WSL2
- 使用イメージ tomcat:9.0.40-jdk11-openjdk-buster
- Visual Studio Code  1.51.1
 - Tomcat for Java  v0.11.3
 - Remote Development  v0.20.0




## 現象
Tomcat: Add Tomcat serverでtomcatのインストールされているディレクトリである**/usr/local/tomcat**を指定するも，うんともすんとも言わない．permissionの問題だと思い chmod で権限の変更を試みるものの，改善しない．

## 原因と暫定対処
現時点では不明
私の環境では**devcontainer.json**に以下のような設定をしていました．
しかしコンテナを起動してから拡張機能を無効→リロード→有効 と操作することでtomcatを追加できました．

```
"extensions": [
        "vscjava.vscode-java-pack",
        "gabrielbb.vscode-lombok",
        "adashen.vscode-tomcat"
    ],
```
よって対応としては

- ↑の設定から**adashen.vscode-tomcat**を削除
- コンテナのビルド後に手動で**Tomcat for Java**を追加



一応動作させることはできているのですが原因が不明のままです．
【初心者が作る】競技プログラミングの備忘録

# この記事の目的
　競技プログラミングを始めてみました。軽く触って見た感じはすごく楽しいです。しかし、段々とストレスに感じることが出てきました。それは、一度調べたことを調べ直すことです。
　いちいち検索し直すのもめんどくさいので、リスト化してみようと思います。言語はPythonです
　ついでに、記事を発信する練習も兼ねています。
# 標準入力
##### １行内に書かれた一つの数字を取得する
`return int(sys.stdin.readline().rstrip())`

##### １行内に書かれ、空白で区切られた複数の数字を取得する（配列にする）
`return list(map(int,sys.stdin.readline().rstrip().split()))`

##### １行内に書かれた一つの文字列を取得する
`return sys.stdin.readline().rstrip()`

##### １行内に書かれ、空白で区切られた複数の文字列を取得する（配列にする）
`return list(sys.stdin.readline().rstrip().split())`

# 値の操作
##### 数値を文字列に変換　文字列を数値に変換
`str(数値)　int(文字列)`
##### 値を１文字ずつ区切る（配列化）
`list(値)`
##### 値を１文字ずつ区切って数値化）
`list(map(int, list(str(数字))))`

# 値の取得
##### 配列の長さを取得
`len(配列)`

# 値の処理

##### 割り算の答えを整数のみにする（pythonは割り算するとfloat型になる）
`a // b`

#繰り返し処理

##### 回数指定の繰り返し
```
for i in range(回数):
```

##### 配列のループ処理（index無し）
```
list1 = ['item1', 'item2', 'item3']
for item in list1:
    print(item)
```
##### 配列のループ処理（index有り）
```
list1 = ['item1', 'item2', 'item3']
for index, item in enumerate(list1):
    print("インデックス：" + str(index) + ", 値：" + item)
```

# 参照

[Python配列のループ処理](https://qiita.com/motoki1990/items/d06fc7559546a8471392)
VMware ESXi on NUC自宅検証環境セットアップメモ (前編 - 物理セットアップ編)

# 1. はじめに
Intel NUCでVMware仮想環境(vSphere, vCenter, ESXi)の検証環境を自宅に構築してみたので備忘録です。Intel NUC上ではNested ESXi (ESXi on ESXi)環境を構築しました。vCenterは一層目ESXi上にアプライアンスvCenterをデプロイします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/87d742b7-94f2-1946-74f0-287426b92eab.png)


本記事は前編(物理セットアップ)と後編(ソフトウェアセットアップ)の2編に分けています。

https://qiita.com/sanjushi/items/75a5c428a01dd2123fde

## 最終構成
物理レイヤー： Intel NUC *1台
仮想化1層目： VMware ESXi 7.0 u1
仮想化2層目： VMware ESXi 6.5
vCenter: VMware vCenter 7.0u1a

Intel NUC、私が組み立てたのは第10世代でしたが現在は最新が第11世代になっています。
[Intel公式サイト - インテルNUCキット](https://www.intel.co.jp/content/www/jp/ja/products/details/nuc/kits.html)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/5364f23e-27a6-9ff2-8702-975b63364bea.png)


# 2. まずは調達しよう
まずは各種モジュールを用意します。↑のIntel NUCはベアボーン(CPU付きの筐体)なので、別途RAMとDisk、と電源コードを購入する必要があります。ソフトウェアの方は今後の検証も考えて"VMUG Advantage"(後編で説明)でライセンスキーも入手しました。
(私の場合は下記セットを組み上げるのに総額で10-15万円ぐらいかかりました。物理機器の方は値段が上下するので型番だけ控えて値下がりした時に調達するか、予算に合わせてRAM/Diskはスペック下げてもよいかもしれません。)


### 物理機器について
リンクはAmazon (or楽天) のページに遷移します。また記載していませんが、セットアップにあたって別途モニター、有線キーボードとUSBメモリが必要になります。
Intel NUC: [Intel BXNUC10I7FNH NUC ベアボーン Core i7-10710U搭載](https://www.amazon.co.jp/dp/B086L69QMB/ref=cm_sw_em_r_mt_dp_3JXKW1G1EB3ME3GVTY5J?_encoding=UTF8&psc=1)

RAM: [Crucial DDR4ノートPC用 メモリ Crucial 64GB(32GBx2枚)](https://www.amazon.co.jp/dp/B07ZLCVKPV/ref=cm_sw_em_r_mt_dp_FTXSD9H3FCRTPW977XP9)

Disk: [Western Digital WDS100T2B0B [1TB/SSD] WD Blue SATAIII接続 / M.2 2280 64層3D NAND](https://www.amazon.co.jp/dp/B07SL4S84C/ref=cm_sw_em_r_mt_dp_XTB84HWC4RG1KVFESM8E)

電源コード: [電源コード 1.8m ミッキー型 3pin(ミッキー型) - 2pin(コンセント)+アース線](https://item.rakuten.co.jp/icon-shop/4938591072402/?s-id=ph_pc_itemname)

(検証環境増強のために、後から追加購入) NAS: [Synology DiskStation DS918+](https://amzn.asia/d/3hh9P4w)

# 3. 組み立ててみよう
非常にわかりやすい写真付き組み立て解説があったのでこちらを参考にどうぞ。RAMをカチっと刺すのは結構強めに押すのですが、割れそうでちょっとドキドキしました。
HDMI出力してモニターにIntelのBios設定画面が出てきたらひとまず成功です。


https://www.pizaman.com/entry/intel-nuc10-review-nuc10i3fnk/#toc28

# 4. 続きは後編に

https://qiita.com/sanjushi/items/75a5c428a01dd2123fde

# 5. 関連記事

https://qiita.com/sanjushi003/items/ba6426b202215f39ba22
見せたくないGutenberg（ブロックエディタ）のブロックパーツを隠す

#ユーザーには使ってほしくないブロックパーツを隠す
会員サイトを使ってユーザーが自由に投稿できる仕組みをした時に、記事の投稿で使ってほしくないブロックエディタのパーツを隠す方法

#ブロックマネージャー
ダッシュボードの右端の3個の点を展開すると、ブロックマネージャーという項目があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820683/d52fb80c-d2e2-447f-a5e4-6116eae45440.png)

#不要なブロックのチェックを外す
今回、Stripe Paymentsプラグインを間違えて使われると困るので、こちらのチェックを外しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820683/a66d90c5-4067-6b19-3bec-9f8d7d866c3a.png)

#すべてのページで適応される
この設定は全てのページで適応されます。固定ページでも適応されるんです。
Stripe Paymentsプラグインはショートコードを使えば出力が出来るので、勝手に商品購入ボタンを追加されてしまう危険性を考えると、ブロックエディタからは隠して、必要な個所にはショートコードで入力するという流れになりました。

投稿権限のユーザーだけに適応させる方法など、条件分岐出来る方法を知っている方いたら教えてください！
EKSでMattermostを構築した話：改善点の洗い出し

## はじめに
- 今年はEKSでMattermostを構築するという機会を頂き、ひとまずMattermostを最低限動かす、というところまでは以下にまとめました。
    - [EKSでMattermostを構築した話：0.概要編 - Qiita](https://qiita.com/tnagano1981/items/555301cecd3ed309fa43)

## 課題いっぱい
- `最低限動かす`ことはできましたが、課題や改善点が盛りだくさんの状況です。まずは課題を洗い出していきたいと思います。
- 課題を明確にできれば、あとはコツコツ手を動かしていくだけですからね。

### EKSMattermostの課題
1. EKSのバージョンアップをするにはどうすればいい？
2. Mattermostのバージョンアップをするにはどうすればいい？
3. pod、nodeのオートスケーリングはどうすればいい？
4. 監視はどうすればいい？
5. helmの管理から外れて、独自に構築してしまった部分をどう管理すればいい？


### EKSMattermostの課題:深堀り
1. EKSのバージョンアップをするにはどうすればいい？
    - これはk8sを使う上での最大の課題なのではないでしょうか。でも、そろろそろベストプラクティスが出てきているのではという感じもしています。この辺りは検証しながら自分なりのベストプラクティスを語れるようになりたいですね。
    - で、バージョンアップするには、バージョンを上げた新しいノードグループを作成して、そちらにpodを移動する、というような動きになると思っていて、それを可能にするには、Nodeを指定してpodを移動するとか、このNodeにはこのpodがいてほしいとか、そういった制御もできるようになれればいいなあと思っています。
2. Mattermostのバージョンアップをするにはどうすればいい？
    - この課題にはアプリケーションに影響を与えずにアップデートするにはどうすればいい？という問題も含まれていると考えます。なので、podをローリングアップデート(最終的にはブルーグリーンも)できればいいのかなと思います。
    - そのためには、deploymentのstrategyを編集するのかなと当たりをつけています。
    - ブルーグリーンはhelmでもバージョン戻すこともできますが、もうちょっとgitops的な手法もできるようになりたいですね。
3. pod、nodeのオートスケーリングはどうすればいい？
    - オートスケーリングはHorizontal Pod AutoscalerやCluster Autoscaleの設定になってくると思うのですが、クラスター作成時にすでにCluster Autoscaleは設定できているのでは？と思っています。が、まだ挙動などは理解できていないので、深堀りしないといけません。
4. 監視はどうすればいい？
    - これはPrometheusとkibanaでダッシュボード見て最低限の確認ができればいいかなと考えています。実現方法もなんとなく見えてはいるのであとは検証できればというところですね。
    - でも最低限の監視では不足しているところも出てくると思いますが、次の課題を見つけるためにもまずは構築してみようかなというところです。
5. helmの管理から外れて、独自に構築してしまった部分をどう管理していく？
    - これはKustomizeを利用することで対応しようとしているのですが、まだ何にもわからん状態です、、、
    - とはいえ数ヶ月前まではhelmだって何にもわからん状態だったので、まずは触ってみるところからですね。でも` helmの管理から外れてしまった`という問題点は明確になっているのでここを解決する方法を探すという観点で進めていけばなんとかなりそうな感じもしています。

## まとめ
- 課題を上げただけになってしまいましたので、最後に個人的なEKS学習方法を1つ紹介します。
- それは`Udemyで学ぶ！`です。
    - [米シリコンバレーエンジニア監修！AWS EKS KubernetesハンズオンBest Practices (2020) | Udemy](https://www.udemy.com/course/aws-eks-kubernetes-docker-devops-best-practices-2020/)
    - 日本で普通に生活していてシリコンバレーのエンジニアさんにEKSを教わる機会はなかなかないと思うでの、Udemyで学びましょう。EKSに直接は関係してこないですが、普通に打ち込んでいるコマンドとかも勉強になりますし、説明は日本語なのですが、用語は英語的な発音なのでかっこいい発音を学ぶ機会にもなります。
- あとは、こうしてEKSに触れる機会を得られることは大きいと思います。個人でEKSを試すとなると料金が気になって作ってはすぐ壊して、となってしまいなかなか運用的な課題にまでは行き当たらないのかなと思います。
    - ということなので、会社でお試しの環境がある人は是非がんがん手を動かしてEKSぶっ壊しながら学んでいきましょう。
duplicate key value violates unique constraint "XXXXXX"の解決方法

ruby "2.6.4
rails", "~> 6.0.0"
postgressql


```ruby
bin/rails db:drop
```
```ruby
bin/rails db:create
```
```ruby
bin/rails db:migrate
```
```ruby
bin/rails db:seed
```

あとは
ファイル名、英語のスペルが間違えていないか確認
クロスサイトリクエストフォージェリ（CSRF）概要

* クロスサイトリクエストフォージェリ（CSRF）についてまとめる。

## CSRFとは

* 本来拒否すべき無関係なWebアプリからのリクエストを受信・処理し、ユーザーが意図しない処理を行わせる攻撃手法。

## CSRF発生の流れ

![CSRF_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/bd9c3282-1422-5fda-c27a-482008efb17c.png)


## CSRFがもたらす被害

* **ユーザーの意図しないWebアプリ上の処理の実行**
  * 本来はログインユーザーのみが許可される記事の投稿処理など。

## CSRFへの対策手段

* **ワンタイムトークンの利用** ※推奨
  * 正規の送信元かどうかを割り当てたワンタイムトークンによって判定する。
  * 処理の流れ
     * WebアプリAは、リクエスト前にクライアントに対してワンタイムトークンを生成する。
     * クライアントは、指定されたワンタイムトークンを付与してリクエストを実行する。
     * WebアプリAは、セッションに格納したワンタイムトークンと送信されたワンタイムトークンが一致しているかを確認する(一致しない場合、リクエストを受け付けない)。

* **ユーザー再認証**
  * 重要な操作の前に、再度ログイン認証をさせるステップを追加する。
     * ユーザービリティは低下する。
* **リファラ（参照元URL）チェック**
  * HTTPリクエストヘッダーのリファラを確認し、許可する送信元からのリクエストかを確認する。
     * リファラは書き換え可能。



## 参考情報

* [CSRF（クロスサイト・リクエスト・フォージェリ）とは？その仕組みと対策方法について](https://viral-community.com/security/csrf-8291/)
* [CSRF対策をひよっこエンジニアがまとめてみた(随時更新予定)](https://html-coding.co.jp/knowhow/security/csrf/)
[WIP][iOS]テストケース作成

#### 異常系テスト

典型的には通信処理（API呼び出し処理）の失敗時など。

Moyaの[StubProvider](https://qiita.com/satoru_pripara/items/6b637ebf7dddd7cbad67#stubproviderの利用)を使うと良い。

#### 同値分割

同値分割とは「入力を意味のあるグループ（同値クラス）に分け、各グループから代表値を選ぶ方法」。数値の入力値のほか、その他にも応用はできる。

##### 画像サイズ 

iPhoneの[画像サイズ](https://qiita.com/pe-ta/items/b3b754bde584abc98f44)は11種類くらいあるので、使う中で最小、最大、中くらいのサイズの端末で試すなどし、レイアウト崩れがないか試す事が考えられる。

##### OSバージョン

対象となるバージョンで最低一個ずつ試す（iOS12, 13, 14）など。



#### 参考

[WRブログ - テストケース作成のポイント](https://webrage.jp/techblog/testcase_point/)
[テストケースの作成](https://qiita.com/salvage0707/items/b15412af6951da2069ba)
[Qangaroo - 失敗しないテストケースの作り方と、効率よくテストを進める方法](https://qangaroo.jp/info/test-case-plan-do/#i-3)
Run OpenVINO-2021.1, OpenCV-4.5.1-pre on M1 MacBook Air with Intel Neural Compute Stick 2 (homebrew)

# Introduction

2020-12-06時点の記録。

この時点でhomebrewのpythonのApple Silicon(M1)対応は不完全で、numpy 等々をインストールできません。なので、C++ で動いています。pythonでやりたいなら[こちら](https://qiita.com/kose3/items/171c9a3477303ec1bfdf)。

Work!! Intel Neural Compute Stick 2 (MYRIAD X) on Apple Silicon (M1) MacBook Air !!
![MBA-NCS2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154910/04f8117f-ad42-33d3-092d-d6a83eb9a980.jpeg)

# Environment
- Intel Compute Stick 2 (NCS2)
- MacBook Air 2020 (M1)
- OpenVINO 2021.1 (No support CPU:arm)
- OpenCV HEAD (tag 4.5.0-openvino fail)
- Homebrew: cmake python cython wget automake autoconf libtool
- MacPorts: libusb (Homebrew's libusb fail)

# build OpenVINO 2021.1
## source tree

NOTE: Don't work Homebrew's git-lfs yet. (2020-12-06)

download openvino-2021.zip from https://github.com/openvinotoolkit/openvino


```
unzip -x openvino-2021.zip
cd openvino-2021

git clone https://github.com/opencv/ade.git inference-engine/thirdparty/ade
git clone https://github.com/openvinotoolkit/oneDNN.git inference-engine/thirdparty/mkl-dnn
git clone https://github.com/openvinotoolkit/googletest.git inference-engine/tests/ie_test_utils/common_test_utils/gtest
git clone https://github.com/gflags/gflags.git inference-engine/samples/thirdparty/gflags
```

## build

```
mkdir openvino-2021/build
cd openvino-2021/build

cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DENABLE_PYTHON=ON \
    -DPYTHON_EXECUTABLE=/opt/homebrew/bin/python3.9 \
    -DPYTHON_LIBRARY=/opt/homebrew/Cellar/python@3.9/3.9.0_4/Frameworks/Python.framework/Versions/3.9/lib/libpython3.9.dylib \
    -DPYTHON_INCLUDE_DIR=/opt/homebrew/Cellar/python@3.9/3.9.0_4/Frameworks/Python.framework/Versions/3.9/include/python3.9 \
    ..

make -j 8
sudo make install
```


# build OpenCV

## source tree

```
git clone --depth 1 https://github.com/opencv/opencv.git opencv-master
```

## build

```
mkdir opencv-master/build
cd opencv-master/build

cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DWITH_INF_ENGINE=ON \
    -DENABLE_CXX11=ON \
    -DENABLE_PYTHON=ON \
    -DPYTHON_EXECUTABLE=/opt/homebrew/bin/python3.9 \
    -DPYTHON_LIBRARY=/opt/homebrew/Cellar/python@3.9/3.9.0_4/Frameworks/Python.framework/Versions/3.9/lib/libpython3.9.dylib \
    -DPYTHON_INCLUDE_DIR=/opt/homebrew/Cellar/python@3.9/3.9.0_4/Frameworks/Python.framework/Versions/3.9/include/python3.9 \
    ..

make -j 8
sudo make install
```

# Run with Intel Neural Compurte Stick 2
![hello_query_device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154910/21e6bb14-6faa-55cd-ab6b-f766180508ca.png)

# Reference
- OpenVINO wiki: [BuildingForMacOS](https://github.com/openvinotoolkit/openvino/wiki/BuildingForMacOS)

# Note
homebrew: don’t support yet: numpy, git-lfs (2020-12-06)
気がついたことがあれば教えてください。
Flash Advent Calendar 5日目 - Canvas2D -

将来的にはWebGLに移行する事になるのですが
初期はCanvas2Dを利用して描画を作っていました。
その中で得られた知見を書こうと思います。

# Flashの描画手法

Flashの描画は基本、一筆書きでです。
使われる関数も3つです。

* 移動(moveTo)
* 直線(lineTo)
* 曲線(quadraticCurveTo)

どれだけ複雑な表現でもこの仕様で実現されており
結構、男前な仕様だと思ってます。

ただ、この一筆書きがかなり難解でした。。。

[参考資料](http://codeazur.com.br/fitc/HackingSWF.pdf)
![https___qiita-image-store.s3.amazonaws.com_0_80502_d2e1ec26-1eea-d29d-7169-56186082bc7f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/983f0b21-3f11-bea9-3149-777c6a857a96.png)


Canvas2Dを利用した方であれば

え？
無理じゃない？？

っとなると思います。
実際、この仕様をCanvas2Dで再現するのにかなりの時間を使いました・・・

まずは、同じ色をまとめる事からはじめました。

# 分解と結合

[参考資料](http://codeazur.com.br/fitc/HackingSWF.pdf)のDefineShapeの描画を分解すると、こんな感じになります。

※ s=開始点、e=終点
![https___qiita-image-store.s3.amazonaws.com_0_80502_96813b1a-6124-378e-657e-0e101425f416.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/1ff6706f-72fe-9baa-ec1b-a583d4b60074.png)

一筆書き問題は、この分解と結合する事でCanvas2Dに描画することができました。

# non-zero rule
次にぶつかった問題は中抜きの描画

※ s=開始点、e=終点
![https___qiita-image-store.s3.amazonaws.com_0_80502_b59cdf68-8962-ef09-705f-44084c9ee47b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/bb389e71-c3e7-9df0-7ef8-de73e0c237c5.png)

でも・・・
![https___qiita-image-store.s3.amazonaws.com_0_80502_eac22fc7-9451-c66c-b320-d5bd0c3296f3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/eaaf28d8-00f6-8c2d-121a-033419bf90e4.png)


いろいろ調べた所、中抜きするには`non-zero rule`という仕様を利用するしかない。
という事がわかりました。



Canvas2Dの描画は時計回りの描画を`+1`とし、反時計回りを`-1`とし
`0`の部分は描画しないという仕様でした。

時計回り(+1)のデータが重なる部分は2となり、描画される。
上の画像だと時計回り(+1)のデータが重なる部分は2となり、描画されていました。
![https___qiita-image-store.s3.amazonaws.com_0_80502_58577b92-850b-3cd2-2738-449857892665.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/419a12f4-351e-f067-c580-dc02a4fc7194.png)

なので、片方の描画を反時計回りに反転させます。
![https___qiita-image-store.s3.amazonaws.com_0_80502_69fe9e2a-5014-8ef2-9cf6-cff8f34f8f9b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/15b3f235-3c2a-30a6-6fe2-bcc8485764f6.png)

Flashの描画はこの`分解と結合`と`non-zero rule`で
無事に描画する事ができましたので、今日はこの辺で終わろうと思います。

明日はクロージャのスコープ問題に関して、書こうと思います。
MySQLデータベースに絵文字を保存する

MySQLでは、デフォルトで絵文字を取り扱うことはできず、保存しようとするとエラーが発生します。
理由は、MySQL上で設定されている文字コードがUTF-8であるのに対して、絵文字はutf8mb4という文字コードでコードされているためです。
よって、MySQLで使用する文字コード設定をutf8mb4に変える必要があります。

実行環境
・Mac OS Catalina 10.15
・MariaDB 10.5.8

##文字コードの確認
次のコマンドで文字コードの設定を確認できます。

```sql
MariaDB [database]> show variables like 'character%';
```



```sql
>
+--------------------------+--------------------------------------------------------+
| Variable_name            | Value                                                  |
+--------------------------+--------------------------------------------------------+
| character_set_client     | utf8                                                |
| character_set_connection | utf8                                                |
| character_set_database   | utf8                                                |
| character_set_filesystem | binary                                                 |
| character_set_results    | utf8                                               |
| character_set_server     | utf8                                               |
| character_set_system     | utf8                                                   |
| character_sets_dir       | /usr/local/Cellar/mariadb/10.5.8/share/mysql/charsets/ |
+--------------------------+--------------------------------------------------------+

```
これをut8mb4に変えます。

##文字コード設定の変更
/usr/local/etc/my.cnfに MySQLの設定ファイルがありますので、これに書き込みます。

```/usr/local/etc/my.cnf
[mysqld]
character-set-server = utf8mb4
[client]
default-character-set = utf8mb4
```

my.cnfが見つからない場合は、次のコマンドで探しましょう。

```terminal
$ mysql --help | grep my.cnf
```

MySQLサーバーを再起動し、設定を改めて確認します。

```sql
MariaDB [training]> show variables like 'character%';
>
+--------------------------+--------------------------------------------------------+
| Variable_name            | Value                                                  |
+--------------------------+--------------------------------------------------------+
| character_set_client     | utf8mb4                                                |
| character_set_connection | utf8mb4                                                |
| character_set_database   | utf8mb4                                                |
| character_set_filesystem | binary                                                 |
| character_set_results    | utf8mb4                                                |
| character_set_server     | utf8mb4                                                |
| character_set_system     | utf8                                                   |
| character_sets_dir       | /usr/local/Cellar/mariadb/10.5.8/share/mysql/charsets/ |
+--------------------------+--------------------------------------------------------+

```

実際に追加してみます。（user_idとcontentという要素を持つPostsテーブルがあるとします）

```sql
MariaDB [database]> INSERT INTO posts (user_id, content) VALUES (4, '😀');
Query OK, 1 row affected (0.003 sec)
```
できました。
クロスサイトスクリプティング(XSS) 概要

* クロスサイトスクリプティング(XSS)の概要情報をまとめる。

## XSSとは

* ユーザーのアクセス時に表示内容が生成される動的なWebページの脆弱性、もしくはその脆弱性を利用した攻撃手法を指す。
  * 動的なWebページが表示内容生成処理を行う際、Webページに悪意のあるスクリプトが仕掛けられ、Webサイトを閲覧したユーザ環境で紛れ込んだスクリプトが実行される。

## XSS発生の流れ

![XSS_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/3776e2ed-b29c-1542-040a-2f9eb24707eb.png)


## 悪意のあるスクリプトがもたらす被害

* Cookie情報の抜き取り

  * Cookieに含まれているセッション ID を抜き出し、利用者になりすますことで、個人情報を取得する(セッションハイジャック攻撃)。

* Webページの改竄
  * 改竄例
     * ユーザーが入力するフォームの送信先を別の URL に書き換え、入力内容を別のサイトに送信させる。
     * 無関係なコンテンツを埋め込み、本物と違和感のないデザインに仕立てることで、ユーザーをフィッシングサイト（罠サイト、不正サイト）へ誘導する。
      
など

## XSSへの注意が必要なWebアプリの特徴

* 基本はすべてのWebアプリで注意が必要になる。
* Cookieを利用してログインセッション管理を行う、フィッシング詐欺の攻撃ターゲットになりやすいページ（ログイン画面、個人情報の入力画面等）を持つようなアプリは、特に注意が必要になる。
* ユーザーの入力した文字列を Web ページ内に表示する部分で、入力内容のエスケープ/バリデーション処理を適切に行っていない実装をしている場合、非常に危険である。

## 対応手段

### 画面表示において

* **エスケープ（サニタイズ、サニタイジング）処理を行う。**
  * 特殊記号を純粋な文字列として扱う。
* **特定文字列のみ表示を許容する。**
  * 「http://」や 「https://」で始まるURLのみを表示する、など。

### 入力内容に対して

* **入力内容に対してバリデーション処理を行う。**
  * 特殊記号などをなるべく許容しないようにする。
* **入力されたHTMLテキストから、スクリプトに該当する文字列を排除する。**



など

## 参考情報

* [クロスサイトスクリプティング（XSS）とは？Webアプリにおける対策方法について](https://yamory.io/blog/about-xss/)
* [安全なウェブサイトの作り方 - 1.5 クロスサイト・スクリプティング](https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_5.html)
Mac版 Eclipseの外部ブラウザをChromeに設定する簡単な方法


###はじめに
Mac版のEclipseの外部ブラウザをChromeに設定する方法を探したのですが、
ネット上になかったので簡単な方法を紹介します。

#Eclipseの外部ブラウザをChromeに設定する簡単な方法
* 事前準備
    * Google Chrome インストール

* 手順
    1.上のメニューバー [Eclipse]から[Preferences...]<font color="Gray">(設定)</font>をクリック
![eclipse_Chrome1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/aa4a82bb-f557-f890-5cb4-f5395b6ec7a2.jpeg) ![eclipse_Chrome2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/297e85bd-2cb9-f5d8-8c76-c7de3b626c67.jpeg)


    2.ウインドウ左側の枠内の一般を選択した後、Webブラウザーを選択
![eclipse_Chrome3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/23351de2-4576-0d7d-2a0c-48245a8c1cfb.jpeg) ![eclipse_Chrome4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/e034b787-3f60-e24a-258a-aeb9b2def6c8.jpeg)



    3.外部Webブラウザーを使用にチェックし、[新規...]をクリック
![eclipse_Chrome5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/c578a3b5-296f-5160-62f3-af57cb76b07f.jpeg)


    4.ウインドウ右側の[参照...]をクリックし[Applications]<font color="Gray">(アプリケーション)</font>フォルダを選択
![eclipse_Chrome6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/84f0247d-b984-c48f-233f-bbe3176d6870.jpeg) ![eclipse_Chrome7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/ba63f0fc-4d5f-29b7-a032-bfd1a3e8ec12.jpeg)


    5.中からGoogle Chrome.appを選択し、右下の[Open]<font color="Gray">(開く)</font>をクリック
![eclipse_Chrome8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/d08704db-270f-9dc8-940d-887b50641719.jpeg)


    6.名前に適当な文字を入力(例:Chrome)、右下の[OK]をクリック
![eclipse_Chrome9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/faba2d6e-e06d-f384-2485-1c186bfad256.jpeg)


    7.ウインドウが閉じたら、6で入力したものが増えているのでチェックを入れて[適用して閉じる]をクリック
![eclipse_Chrome10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/d828ffa6-2d20-8da5-ac56-52c29e36eb9a.jpeg)


###結果
   これでHTMLなどをサーバーで実行する際、このようにChromeブラウザが立ち上がるようになります。
![eclipse_Chrome11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/f31412cd-00f2-6b43-39a4-33da001b5a43.jpeg) ![eclipse_Chrome12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/9019d1f9-1188-0c97-0bc0-4bda4a322e62.jpeg)
<font color="Salmon">（＊）初回起動の場合、警告や許可を求めてきた場合は、[OK]クリックで進めて良いと思います。</font>
Windows10 Home で Docker Desktop の Error response from daemon のエラー対応

# Windows10 Home で Docker Desktop の Error response from daemon のエラー対応

## 症状

Docker Desktop で下記のエラーが発生していました。

```
Error response from daemon: open \\.\pipe\docker_engine_linux: The system cannot find the file specified.
```

下記のリンクでも同様の症状が発生している方がいらっしゃるようです。
（英語が苦手なので解決したのかどうかは不明です）

[https://github.com/docker/for-win/issues/4495](https://github.com/docker/for-win/issues/4495 "https://github.com/docker/for-win/issues/4495")

## 解決方法

Windows10 で Docker を使用する場合、複数の実現方法があるようです。
Windows10 Home + Docker Desktop の環境では、下記の組み合わせでないと動かないようです。
この組み合わせにしたらエラーが出なくなりました。

* Windows Insider Program
* Docker Desktop for Windows (Edge)

### Windows Insider Program

Windows10 の「設定」から「更新とセキュリティ」を開きます。
左下の「Windows Insider Program」の設定をします。
設定後、PCの再起動もしておきます。

![docker_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/bcbe3f3e-763f-e8d7-c330-6d61f1038cdb.png)

### Docker Desktop for Windows (Edge)

下記のサイトから右側の「Get Docker Desktop for Windows (Edge)」をクリックしてダウンロードします。
すでにstableのほうをインストールしていた場合は、アンインストールしてからEdgeのほうを再インストールします。

[hub.docker.com](https://hub.docker.com/editions/community/docker-ce-desktop-windows "hub.docker.com")

![docker_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/9d9a5d67-b168-8672-b0d1-beac1684f961.png)
セルフサービスBI管理者ツールについて②

アドベンティスト3日目で管理者のメールアドレスに集約するで、
エラーレポートを作成しましたが、あと２つ便利にすることができます！

(1)Power Automateで、関係者にメール送信
(2)Power Automate で、Teams の Listsアプリにインシデント起票

このあたりが運用で便利かなと思います。

#(1)Power Automateで、関係者にメール送信
これは、いままで、エラーになった場合は、個別レポート単位で設定していたものを、
レポート作成者・利用関係者に連絡するためのサービスになります。

まぁ、メールボックスに集約するなら、Outlookでやれよと言われそうな気がしますが、
Power Platformファミリーの「Power Automate」でやりましょう。
Power Automateでやるメリットしては
Teams連携なんぞもできるので、メールから切り替えるとなった場合に作成コストがかかるのもね。
また、Power Platformでも地味目（主観です。Power Automate Loveの方、ごめんなさい）の
Power Automateのスキルアップにもなるので、Power Automateでやるのがよいと思います。

こんな感じで、サクッとできるのもPower Automateの良いところですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/901500c4-9734-0716-151d-a6b2e0b590a0.png)


#(2)Power Automate で、Teams の Listsアプリにインシデント起票
これも、Power Automateの活用になりますが、
Teamsのタブの追加で「Lists」でのインシデント管理ができます！

Teamsのタブ追加で「Lists」があります！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/409e9433-ff6e-d906-0ee0-0b69ab5c02ff.png)

テンプレートにインシデントがありますので、追加しておきましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/8d6a6ad1-f6d5-7e96-9bed-d9eedcaa66eb.png)

この「Lists」ですが、おなじみのShare Pointのリストなのですよねー。
そして、ここからが、Power Automateの出番です。
（めっちゃ、活用してるやん。地味目といって、ごめん。）

こんな感じで、管理者のPower Automateで作成しましょう。
黒塗りのサイトのアドレスに関しては、Share Pointのアドレスを設定！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/e692a079-7480-8fd3-3a36-ac4a70a3b8ac.png)


Teams上でこんな感じで、インシデント管理できます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/91101e5a-6d11-f262-3eb1-a244a73c1f1a.png)


いかがでしょうか？参考になりましたでしょうか？
今回Power BI一切ないやんというツッコミ受けそうですが、
Power BIを長年運用していると出てくる課題かと思いますので・・
（Power AutomateのAdvent Calendarに書いてもよかったかな・・あれ？あるのかな）

宜しくお願い致します。
LaravelのBladeテンプレートにCSSやJavascriptを書かない理由はこれかな？

## はじめに
この記事は、私個人の意見を文章にしているだけの記事です。
そのため、コードサンプルや、技術の説明のような情報はありません。
もし、コードサンプルや技術説明をお探しであれば、別の方の記事を参考にしてください。


## Bladeテンプレートでの問題点
以前、次のような記事を書きました。

[LaravelのBladeテンプレートをVue.jsっぽく書いてみた](https://qiita.com/bearrabi0506/items/59789ae4c467104e6161)

この手法だと、部品毎で分割しやすく、コードも見やすくなると思っていたんですよね。
しかし、実際に開発していて大きな問題が１つ発生しました。
それは、__*JavascriptのUnitテストができないことです。*__

## 解決方法の検討

次のように解決方法を検討しました。

#### 1. Javascriptを外部のJSファイルに記述する
これは、Vue.jsやReact等の、フロントエンドのフレームワークを利用しない場合、当たり前の記述方法だと思います。
Laravelでは、Bladeテンプレートファイルの中でCSSやJavascriptを使用することは推奨されていません。
しかし、明確に理由まで記載してある情報ソースを見つけることができなかったので、自分は「盲目的にルールを守ること」はしませんでした。
その結果、問題点が発覚したので、反省が必要ですね。
とはいえ、Bladeテンプレート内に書くJavascriptのコードはほとんどがDOM操作です。
なので、外部ファイルにして単体テストをしたところで、どこまで信頼できるものかわかりませんね。
※DOM操作は他のUIに依存するものが発生しやすいので、結局は判定ロジックや、算出ロジックだけのテストになるのかと。。


#### 2. フロントエンドフレームワークを利用する
これは、ある程度大きなプロダクトでは、当たり前の話です。
しかし、技術選定時は、「できるだけ多くの人が参画しやすいようにする」をテーマに、Laravelを選定しました。
というのも、私が参画させていただいている案件は、企業したてのスタートアップ企業様の案件です。
そのため、スペシャリストよりも、フルスタックな人が必要だったんですよね。

経営を考慮しての技術選定だったので、現段階でLaravelを選定したことについては仕方なかったと思っています。
しかし、Unitテストができないというのは、品質を担保する指標が１つなくなること。
なので、後々はフロントエンドのスペシャリストに参画していただき、Vue.jsやReactを採用してUnitテストができる状態も必要なのかなとも思います。
その時は、売り上げが拡大されてきた時ですかね。
※余談ですが、VueやReactを使えばSPAも簡単に実現できますし、付加価値は付けやすいでしょう。


####  3. Integrationテストの仕組み構築に尽力する
現段階では、これが一番現実的なのではないかと考えています。
ここまでは、Unitテストのことしか考えていませんでした。
しかし、Integrationテストでしっかりテストをする仕組みがあり、かつ、デバッグがしやすいのであれば問題ないかと思っています。
というのも、Integrationテストでバグが発生したらUnitテストからやり直しになることも多々あります。
また、網羅率100%のUnitテスト用コードを目指すと、テストをすることが目的になる可能性もあるんですよ。
そうなると、無駄なことに工数をかけてしまい、ビジネス的にはよろしくないですよね。
なので、今回はこの方向性が一番有効かと思います。


## 最後に
この記事では、設計による問題の解決手法を検討した内容を記載しました。
今回の場合だと、予算が潤沢にある企業様だとしても「技術選定からやり直し」や、「Unitテストのためだけの設計変更」はするべきではないと思います。
というのも、出戻りばかりしていたら、リリースまでたどり着けないからです。
スタートアップの企業様ですと収益化できない期間が長くなるのは、より苦しいですよね。
そのため、今回は、「出戻りはしない」かつ、「品質は落とさない」のどちらにも配慮して検討してみました。
もし、本当に設計変更やフレームワークの導入をするのであれば、スケールして、予算に余裕が出てきた時で良いと思います。

最後まで読んでいただき、ありがとうございます:relaxed:

**私は、参画させていただいている企業様に心より感謝し、プロジェクトの成功に尽力致します。そして、自分のスキルアップに尽力することが、お世話になる企業の関係者様の利益になると信じています。**
人事システム「COMPANY」のバッチ処理の裏(側) の話 - 番外編

[人事システム「COMPANY」のバッチ処理の裏(側) の話](https://qiita.com/e99h2121/items/d9a83a6e47a53dcfbfbd) の補足を人知れずメモしているもの。最新の仕様を説明した正式なものではないので、そういう時代があったのだなという参考程度に。

## キューはどこからやってくるのでしょう

[人事システム「COMPANY」のバッチ処理の裏(側) の話](https://qiita.com/e99h2121/items/d9a83a6e47a53dcfbfbd)
「キュー管理サービス」というもの。キューは文字通りのQueueなのだがどうやって順番を管理しているかというとJava内のほかにもう一つ投入口が用意されている。下位互換的にそういう仕上がりになっている。「キュー受付テーブル」と一旦呼ぶ。

```manager.java
//「キュー受付テーブル」にレコードが入る。
//　　　↓
//「キュー管理スレッド」がそれを検知。
//　　　↓
//　ジョブ処理待ちへ
```

これはこれでただのバッチ処理機構の内輪の話で「キュー受付テーブル」にレコードを投入するには投入するための関数を使ってやるのが「お作法」である。

```manager.java
//　★投入関数で呪文をとなえる（いくつか呪文には種類がある）
//　　　↓
//「キュー受付テーブル」にレコードが入る。
//　　　↓
//「キュー管理スレッド」がそれを検知。
//　　　↓
//　ジョブ処理待ちへ
```

さてこれが仕様であるとしてこの「バッチ処理」を使いたい使用者（各種プロダクトやサブシステム）がどうしているか。

### 例外その1

★に代わる（使用者にとって）良い感じの投入関数を自分で作っている。

作っている。なぜそうされたかはわからないが自作されている。★で提供している関数が機能不足だったのだと思われる。それで動いているのだから絶するが、歴史は奥深い。


### 例外その2
「キュー受付テーブル」にレコードを突っ込む。

関数をいくら隠ぺいしてもテーブルはPublicなので、その仕様を理解した上で練られた技と考えられる。


## コンウェイの法則

[コンウェイの法則](https://www.yamdas.org/column/technique/19laws.html)

> ソフトウェアのどの部分であれ、それを作った組織の構造を反映する。
Any piece of software reflects the organizational structure that produced it
備考：原文ではこれの応用として「コンパイラを4つのグループで作れば、4パスコンパイラになる」というのが紹介されている

オープンな組織である。


## 本来キューイングシステムとは

[Messaging Brokers as a Single Point of Failure - Ciaran O’Donnell’s Blog](https://ciaranodonnell.dev/posts/message-broker-as-spof/)

[キューイングシステムとは](https://udemyfun.com/python-queueing-system/)
[メッセージキューイング（MQ）とは - 意味をわかりやすく - IT用語辞典 e-Words](https://e-words.jp/w/%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%AD%E3%83%A5%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%B0.html)

> メッセージキューはその名の通りキュー（queue/待ち行列）構造となっており、複数のメッセージを預かる場合は先に書き込まれた方から順に読み出すFIFO（First-In First-Out：先入れ先出し）方式でメッセージを送り出す。受け渡しが完了したメッセージは消去され、次のメッセージの送受信に備える。


> ブローカー、いわゆる仲介ですが、ブローカーなしのキューイングシステムとブローカーありのキューイングシステムがあり、ブローカーなしの場合、リクエストがあったらすぐにリクエストに答えるのに対し、ブローカーありは、タスクを受けて、バックグラウンドでサーバーに処理をスケジュールして、スケジュールに応じた処理を返すという感じです。

> ブローカーなしだとすぐにレスポンスを返せるのですが、タスクが保存されていないので、何かあった場合は処理が完結しないのに対して、ブローカーありは処理に時間がかかるものの、タスクが保存されているので、何かあってもその処理を最後まで実行できます。

[ZOZOTOWN カート投入の分散キューイングシステム 〜 プロダクションレディまでの歩み - ZOZO TECH BLOG](https://techblog.zozo.com/entry/production-ready-zozotown-cart-queueing-system)
[Amazon SQS（サーバーレスアプリのためのメッセージキューサービス）| AWS](https://aws.amazon.com/jp/sqs/)
[Amazon Kinesis Data Streams（リアルタイム分析向け大規模データを収集）| AWS](https://aws.amazon.com/jp/kinesis/data-streams/)
[Queue Storage | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/storage/queues/)
[Event Hubs - リアルタイムのデータ インジェスト | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/event-hubs/)

### Open Sourceなら
#### Kafka
https://kafka.apache.org/

[Apache Kafka 入門 - Qiita](https://qiita.com/keikesu0122/items/48be51a65d34d90c11e9)

#### Rabbitmq
https://www.rabbitmq.com/

#### Celeryq
https://docs.celeryq.dev/en/stable/

#### Nsq
https://nsq.io/


まだまだ勉強できそうだ... 
以上休日にゆるりと楽しんでいただきたい小話でした。
やがてelixirになる

この記事は、[fukuoka.ex Elixir／Phoenix Advent Calendar 2020](https://qiita.com/advent-calendar/2020/fukuokaex) 6日目です。
前日は、 [hisaway](https://qiita.com/hisaway)さんの [[Elixir]匿名関数をパターンマッチする](https://qiita.com/hisaway/items/db0d6cefc5ac46a73ec4) でした。

最近もくもく会でやっていた事を紹介します。
配列の要素数をカウントする関数です。

```python
def listlen(l):
	if (l == []):
		return 0
	else:
		return 1 + listlen(l[1:])

print(listlen([1,2,3,4]))
```
やってしまいました。
elixirの割にendが無いと思ったらpythonですね。
書き直します。

```rb
def listlen(l)
  if l == [] then
    0
  else
    1 + listlen(l.drop(1))
  end
end

puts(listlen([1,2,3,4]))
```

endをつけてreturnが不要になりました。
(最後の行の値は暗黙にreturnされる)
でもelixirはdefmoduleの中でしか関数定義できないので
これはrubyのコードです。

```cl
(defun listlen (l)
  (if (null l)
    0
    (+ 1 (listlen (cdr l)))))

(listlen (list 1 2 3 4))
```

今度こそ！・・・括弧が沢山増えてしまいました。
common lispです。

```erl
-module(listlen).
-export([listlen/1]).

listlen([]) -> 0;
listlen([_|T]) -> 1 + listlen(T).
```

うーん、括弧は減りましたがちょっとサッパリしすぎです。
これはerlangです。
`erlc listlen.erl`でコンパイル後に
erlで対話モードを起動して
`listlen([1,2,3,4]).`で実行します。
erlangでは`;`は行の区切りではなく
この行の関数の引数、
`listlen([]) -> 0` の `([])`
に一致しない場合は次のlistlenを実行すると言う意味です。
最後に実行するlistlenには`.`を末尾につけて
これが最後のlistlenだよとerlangに教えます。

```elixir
defmodule ListLen do
  def listlen([]) do
    0
  end

  def listlen([_|tail]) do
    1 + ListLen.listlen(tail)
  end
end

ListLen.listlen([1,2,3,4])
```

ようやくたどり着きました。
<del>こいつがりんごろう</del>
これがelixirのコードです。
`elixir listlen.exs`で実行します。

<h2>あとがき</h2>
そこはかとなくオライリー風に。
最初マクロについて書こうとしたけど
elixirマクロの記事そこそこあったんで
こっちにしました。
行番号のセパレータを変更するnlコマンドのsオプション

nlコマンドはsオプションを指定することで、行番号と入力行のセパレータ文字列を変更することができます。

# sオプションの使い方

まずはマニュアルを参照してみましょう。説明の差はほとんどありません。`-s`の後に`文字列`を指定することで、セパレータを変更できるようです。そしてデフォルトは`タブ`です。


## info nl (GNU coreutils)

```console
‘-s STRING’
‘--number-separator=STRING’
     Separate the line number from the text line in the output with
     STRING (default is the TAB character).
```

## man nl (BSD)

```console
     -s sep       Specify the characters used in separating the line number and
                  the corresponding text line.  The default sep setting is a sin-
                  gle tab character.
```

## busybox nl --help

```console
	-s STRING	Use STRING as line number separator
```

## POSIX

> -s  sep
Specify the characters used in separating the line number and the corresponding text line. The default sep shall be a \<tab\>.

出典：https://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html


# sオプションを試す

それでは[最初の記事](https://qiita.com/Carol_815/items/d1081ff7a7d3f9971edc)で使用したテキストファイル「utl-kita」で実際に試してみましょう。
まずは、セパレータをタブから`,`カンマに変更して出力をCSVにしてみます。[-wオプションで駅ナンバリング表示](https://qiita.com/Carol_815/items/fa16e4875ba7bc19de86#%E9%A7%85%E3%83%8A%E3%83%B3%E3%83%90%E3%83%AA%E3%83%B3%E3%82%B0%E8%A1%A8%E7%A4%BA%E3%81%AE%E9%A7%85%E7%95%AA%E5%8F%B7%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B)したときのコマンド入力を流用します。

```console
$ nl -n rz -w 2 -s , utl-kita | sed 's/^/JU/'
JU01,東京
JU02,上野
JU03,尾久
JU04,赤羽
JU05,浦和
JU06,さいたま新都心
JU07,大宮
```

これで駅ナンバリング表示のCSVデータを作成することができました。元からあるCSVデータに通し番号のIDを振るときにとても便利なオプションです。

さらに、-sに指定できるのは文字（character）ではなく文字列（string）となっているため、長い文字列を挿入することもできます。

```console
$ nl -n rz -w 2 -s ',宇都宮線・高崎線,' utl-kita | sed 's/^/JU/'
JU01,宇都宮線・高崎線,東京
JU02,宇都宮線・高崎線,上野
JU03,宇都宮線・高崎線,尾久
JU04,宇都宮線・高崎線,赤羽
JU05,宇都宮線・高崎線,浦和
JU06,宇都宮線・高崎線,さいたま新都心
JU07,宇都宮線・高崎線,大宮
```

路線名の列を簡単に付加することができました。


---

# 余談

オプションのデフォルトがタブというのは以外にありがたいことのようにな気がしてきました。というのは、`echo -e`のように、`nl -s '\t'`としても残念ながらタブと識別されません。

```console
$ nl -s '\t' utl-kita 
     1\t東京
     2\t上野
     3\t尾久
     4\t赤羽
     5\t浦和
     6\tさいたま新都心
     7\t大宮
```

ターミナルでは`Ctrl+v` `Tab`などと入力すればタブがそのまま入力できるのですが、めったに使わないのでいつも忘れてしまいます。

```console
$ nl -s '     ' utl-kita 
     1	東京
     2	上野
     3	尾久
     4	赤羽
     5	浦和
     6	さいたま新都心
     7	大宮
```

「難読化シェル芸」勢の方々は、もっとおもしろいタブの入力をやりそうです。なにかあればまた追記したいと思います。