OmniAICreator/Qiita-1.07M huggingface dataset:
Kubernetes IDEのLensを使ってみる

#1. Lensとは
[Lens](https://k8slens.dev/index.html)はKubernetesクラスターにリソースをデプロイ・モニタリングするためのIDE（統合開発環境）です。
OSSのソフトウェアでMac、Windows、Linuxで使用することが可能です。
[Github](https://github.com/lensapp/lens)のスターが5000以上、ユーザー数が27万人（2020年 6/19時点）と人気のツールとなっています。
![Image 2020-06-19 at 23.53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/a327f2d3-63d3-0292-7213-e4cc965bf6d1.jpeg)


#2. Lensの良い点
•　ダッシュボード上でKubernetesのコマンドを使用せず、リソースをデプロイすることができる。
（kubectlコマンドだとミスを犯しやすいし、リソースを監視しながらデプロイする場合では分かりづらいことも多々あリます。）
•　Prometheusと連携して、複数クラスターをモニタリングすることができる。
•　ダッシュボードがカッコよくて分かりやすい。特に、Kubernetesに慣れていない人にとってはGUIで網羅的にリソースを監視しながら、リソースをデプロイできるのはありがたいと思います。

#3. Lensの使い方
##3.1. Lensを開発用の端末にインストール
Lensのサイトからソフトウェアをダウンロード・インストール
 [Lensのサイト](https://k8slens.dev/index.html)からダウンロードすることができます。
##3.2. 開発・モニタリングを行いたいNodeを登録
インストールが完了したら、デプロイ・モニタリングしたいクラスターのconfigを選択します。
![Image 2020-06-20 at 0.09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/67d23fda-d203-125c-3b6d-a35c3ed99965.jpeg)


##3.3. Metrics用にPrometheusをインストール
CPUやメモリの使用率を監視したいのでPrometheusをKubernetesクラスターにデプロイします。
（ワンクリックでデプロイできるのでとても簡単。。）
<img width="864" alt="lens1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/79cbd520-b585-0769-185d-6b58d8e874c3.png">

##3.4. 試しにリソースをデプロイ・修正
新規にリソースをデプロイするには、アプリの下方にあるCreate Resouceを選択してマニフェストを記入しデプロイします。
<img width="864" alt="lens2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/e49780fc-c590-599c-a736-64967c4796ce.png">

デプロイ後にリソースを修正したい場合もReplicaSetの数ならクリックするだけで行うことができます。
<img width="864" alt="lens3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/6c05262c-9ee0-6ac1-ad2d-2a261d4c5cd1.png">

##3.5.　その他の画面
RBACの設定はコマンドからだと分かりにくい場合が多いのですが、GUIだと簡単に把握・設定することができます。
![Image 2020-06-20 at 0.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/687f0c1a-2ddd-c2b1-6fd7-26ee7acebd58.jpeg)

ついでにログ監視も
![Image 2020-06-20 at 0.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277773/43eeca53-3c72-e900-f5f4-24261e45353b.jpeg)

#4. 最後に
Kubernetesクラスターを実装する際には、kubectlコマンドベースでは分かりづらいことが多いと思いますがlensを使えば簡単にデプロイすることができます。 
Kubernetesをまだ扱い慣れていない方にもオススメです！
SAS 数値を有効桁数で四捨五入する関数(fcmpプロシジャ)

# 数値変数を、有効数字を指定して有効桁で四捨五入したい

SAS関数はなさそう...
(四捨五入するだけならround)
fcmpプロシジャで関数を作る

# fcmpプロシジャ

```sas
options cmplib = _null_;

proc Fcmp outlib = work.FUNC.A;
  function dig( HENSUU , DIG ) $100;
    length RESULT FMT $100 KETASUU ROUND_VAR 8;
    if HENSUU = . then RESULT = "";
    else do;
      if HENSUU = 0 then KETASUU = 0;
      else KETASUU = floor( log10( abs( HENSUU ) ) ) + 1;

      ROUND_VAR = round( HENSUU , 0.1 ** ( DIG - KETASUU ) );
      FMT = cats( "15." , max( DIG - KETASUU , 0 ) );

      RESULT = cats( putn( ROUND_VAR , FMT ) );
    end;

    return( RESULT );
  endsub;
run;
```


# 作った関数ためす 

```sas
options cmplib = work.FUNC;

data work.CHECK;
  input VAL;
  A = dig( VAL , 4 );
  cards;
12345
1.23
1234.5
123.4567
0.12345
0.00123
;
run;

%put %sysfunc( dig( 12345.67 , 4 ) );
```


https://go.documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.4&docsetId=proc&docsetTarget=n05uh9btv63kfkn11o7kml5tnhji.htm&locale=ja
AWS CLI ハンズオンでのメモ 

## 概要
先日AWS-CLIのハンズオンに参加したので
とりあえず簡単なメモ
随時追加予定
実施内容については別の投稿にするかも・・・

## 注意点
ハンズオン参加にあたっての注意点

* VPCの数について
    * VPCは１リージョン５個までなので他のハンズオンなどで作ったものがあれば削除自分で何かやっている場合はそこは残すように注意
     
* cloud9のインスタンスタイプ
    * 無料期間がある場合はデフォルトの `t2.micro` でよさそうですが、無料枠が終わっている場合は `t3.micro` の方が値段的にもあまり変わらないのでこちらを選択した方がよさそうです。

## ほかでも使えそうなTips

* 変数の設定値確認
    * AWS-CLI で引数でいろいろ設定するがその値を確認するためヒアドキュメントを使用すると必要なものがそろっているかが確認できてよさそうです。
    
```
cat << END 
# EC2_INSTANCE_ID=XXX-XXX-XXX
EC2_INSTANCE_ID="${EC2_INSTANCE_ID}"
END
```

のように使用予定の変数が正しくセットされているかを確認できるのでAWS-CLIに限らず何等かの手順で変数を設定してコマンドを実行するときに確認するのは使えそうです。
【Python】任意の数の標準入力をリストに入れる方法

atcoderで以下のような入力をうけとらなければならない問題があったのでメモ

```
3              //入力数N
2 4 6　　　　　 //A1 ・・・AN
```

という入力があるとき、このNとA1～ANをリストに格納する方法を載せます。

```
N=int(input())
array = list(map(int,input().strip().split()))
```

簡単！記事にする必要あったかという疑問...
HTML,CSSについての学習(通算1日目)

## HTMLについて
### タグの書き方
```
<要素名>書きたいこと</要素名>
↑開始タグ　　　　　↑終了タグ
```

### 見出し

- `<h１>〜<h６>`　まである
- それぞれ開始タグと終了タグを必ず入れる
- h6にいくほど文字は小さくなる

#### 見出しと段落の使い分け
- 見出し以外の分には`<p>`を使用
- 表示したくないコメントには`<！ーーコメントーー>`を使用

### リンク作成
- リンクの名前には`<a>リンク名</a>`を使用
- リンクのURLの貼り付け`<a href="貼りたいURL">`
- 1と２を合体`<a href="貼りたいURL">リンク名</a>`

### 画像挿入
- 挿入したいURLを貼る`<img src="画像URL">`
- 終了タグはいらない

### リスト作成
- 箇条書きにしたいものを`<li>`で囲む
- 必ず（箇条書き`<li>`子要素）の前後には`<ul>`を入れること
- `<ul>`要素は黒点が先頭につき`<ol>`要素は数字が連番でつく
- `<li>`を入れるときは必ず　→｜(インデント）をする


## CSSについて
### 文字の色を変える(color)
h１の色を変えたい場合

```
h１ { ←ここで改行
 color:#ff0000;
}
```

### colorの前のインデントを忘れない
表示したくないコメントには`<*コメント＊>`を使用

```
h１ {
 /*色を赤に指定＊/
 color:#ff0000;
}
```

### 文字の大きさを変える(font-size)
h1の文字の大きさを変えたいとき

```
h1 {
 color:red;
 font-size:10px;
}
```

### フォントの種類を変える(font-family)
フォントのデザインを変えたいとき

```
h1 {
 font-family:sarif;
}
```

### フォント名にスペースが含まれている場合("")を使用

```
h1 {
 font-family:”Avenir next";
}
```

### 背景色を変える(background)
h1の文字の背景に色をつけたいとき

```
h1 {
 background-color:#dddddd;
}
```

### 画像や文字の横幅(width)、高さを変える(height)
```
h1 {
 width:500px;
 height:80px;
}
```

### 箇条書きのうち１つだけ色をつけるとき(class)
htmlでは、色をつけたい要素に名前をつける（なんでも良い））

```
<li class="one＂>色をつける要素</li>
　　　　　　　↑つけたい名前　↑箇条書きの文
```

classはCSSでは、箇条書きにはドットがつくから名前の前にも入れるのを忘れない

## 1日目ふりかえり
プロゲートを学びながら大事だと思ったことや理解が難しかったことを書きました。
初級クリアできました！

<img width="1291" alt="スクリーンショット 2020-06-19 23.05.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658710/c8869835-0785-1cde-f92a-567a3d233eb5.png">


明日からも頑張ります(^｡^)
ffi-1.13.1でサーバーが落ちてしまうので応急処置

resoucesの活用やActiveAdminを実装した際にサーバーを立ち上げてアクセスするとサーバーが落ちて悩んでおりました。
その際の応急処置を備忘録として書きます。

PC環境

- macOS Mojave


- Ruby 2.5.1


- Rails 5.2.4

#ターミナル表示

```console:terminal
dyld: lazy symbol binding failed: Symbol not found: _ffi_prep_closure_loc
  Referenced from: /Users/ytanaka/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ffi-1.13.1/lib/ffi_c.bundle
  Expected in: /usr/lib/libffi.dylib

dyld: Symbol not found: _ffi_prep_closure_loc
  Referenced from: /Users/ytanaka/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ffi-1.13.1/lib/ffi_c.bundle
  Expected in: /usr/lib/libffi.dylib

Abort trap: 6
```

あまり内容は理解できていませんでしたが、どうやらgemのffiで問題が起こっていそうだと判断しました。
なので、**ffiのバージョン変更**はどうかと考えました。

#手順

```console:terminal
gem install ffi -v "1.12.1"
```
上記でgemのffiの古いバージョンをインストール

次にRailsのGemfile.lockのffiのバージョンを変更

```lock:Gemfile.lock
ffi (1.13.1) #削除
ffi (1.12.1) #追加
```
上記の処理でサーバーが落ちる事なく正常に動いてくれております。
Rubyでアルゴリズムを実装する:Day 3 -二分探索-

最近Ruby書いてて楽しいな。３日目。
2日目はこちら<[Rubyでアルゴリズムを実装する:Day 2 -バブルソート-](https://qiita.com/Atarubift/items/f9f3224dccc3c32c4741)>

# 二分探索とは
ソート済みのデータを半分に絞り込む動作を繰り返して素早く特定のデータを見つけるアルゴリズム。
とても有名で、イメージもしやすい。
というわけで、レッツコーディング

# binarySearch.rb

```rb
# 二分探索
def binarySearch(num, pat)
  start = 0
  len = num.length - 1
  half = (start + len) / 2
  mid = num[half]
  
  while mid != pat
    if half < 0 || half > num.length
      half = -1
      break
    elsif pat == mid
      break
    elsif pat < mid
      len = half - 1
    else
      start = half + 1
    end
    half = (start + len) / 2
    mid = num[half]
  end
  half
end

print "格納する数字:"
num = gets.split().map(&:to_i)
print "探す数字："
tar = gets.to_i
binary = binarySearch(num, tar)

if binary >= 0
  puts "#{binary+1}番目に見つかりました。"
else
  puts "数字はありません"
end
```

## 出力
```sh
格納する数字:1 2 3 4 5 6 7 8 9
探す数字：6
6番目に見つかりました。
```

## コード解説
binarySearch 二分探索を行うメソッドを定義
引数はデータと探索したい値
startとlenにはそれぞれ配列の始点と末端を代入
halfには配列の真ん中の値を示す数を代入
midにデータの中心の値を代入
中央のデータと調べたい値が同値になるまで繰り返す。

もしもhalfが０より下だったり、データの数より大きければhalfを-1で返す。
要はデータがなかったので、falseとして扱う。

中央のデータと調べたい値が同値ならばループ終了

中央のデータが調べたい値より大きければ末端をずらす

中央のデータが調べたい値より小さければ視点をずらす

halfとmidに値を入れなおす

ループ処理が終わればhalfを返す。

データを入力し、何番目にあったのかを出力する。


# 最後に
探索のイメージはすぐにできたのだが、実装には思いのほか時間がかかった。
始点と末端をうまく動かせずに探索に失敗することがよくあった。

二分探索はsortされたデータ探索しているため、前回実装したバブルソートと組み合わせた方がいいのかもしれない

コード自体に間違いはないと思うが、なんとなく無駄が多いようにも感じる。
というかもっといい方法あるよね

さて、次回は線形探索を実装します(どう考えても順番間違えた。)
Kotlin/NativeでLCD表示

## 目的

Kotlin/NativeでLチカが実行できたので、次はLCDの表示にチャレンジ
使うLCD 1602A。I2Cのよくあるやつです。

## 手順

1. raspberrypiでI2Cを使えるようにしておく
   
2. i2cdetect -y 1 をしてみて I2Cアドレス27がenableになっていることを確認する

3. コードはこんな感じ。
https://gitlab.com/hoso-study/raspberrypi/kotlinnative-lcd

4. 見た目はこんな感じ。時が飛ぶのはディアボロのせい
![kotlinnative-lcd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35185/8f997eb4-1258-6a36-55de-ec6f50ef9efc.gif)


## 今回のポイント

1. デフォルトで、液晶の表示が全く見えなかった。何も表示されないと思っていたら、見えなかっただけだった。ポテンショメータ(裏の青いやつ)でコントラストが調整できた。

2. Kotlin/Nativeで時刻の取得をするのがちょっと大変だった。
【メモ効率化】ScrapboxをApple純正メモ並みの手軽さで使う方法 （Chrome PWA & 拡張機能 )

(この記事ではPCでScrapboxを使うことを想定しています)

## Scrapboxとは
個人でもチームでも利用できる情報共有サービスです。階層構造で整理するのではなく、wikiのように情報同士をつなげて整理するというスタイルで、思考の流れに任せて自由に書けるのがいいところだと思います。

#### Scrapbox
https://scrapbox.io/product

## Scrapboxをもっと手軽に使いたい！
Scrapboxはクラウドツールなのでブラウザ上で使うのが基本です（サードパーティ製アプリを除く）。しかしブラウザから毎度アクセスするのも若干面倒なので今回はこの問題を解決したいと思います。

ChromeにはWebアプリをOSにインストールしてネイティブアプリのように使えるようにするProgressive Web Apps(PWA)という便利な機能があります。

## Scrapboxを独立アプリ化する。

1. Scrapbox（https://scrapbox.io/） にChromeでアクセスする
2. Chrome右上の「...」から "Install Scrapbox"を探してクリックします。（下の画像でInstall Qiitaになっているところです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542224/e2bca449-b03e-e230-01c1-1b304b779695.png)

これで独立アプリ化されているのでMacだとスポットライト検索[Cmd + Space]に引っかかるはずです。これでどこからでのScrapboxをひらけますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542224/22dde10f-5762-b2da-6cef-5b2b3822c1bf.png)

## ショートカットキーの追加

（追記 2021/12/31: 以下の手順でショートカットを自作しても良いですが、Vim風キーバインドでChromeを操作できる [Vimium](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=en) というプラグインがとても使いやすいのでおすすめです。）

起動は早くなったけど、ノートの新規作成までできれば簡単にやりたいですよね。次は、PWAでもChrome拡張機能が使えるので、Chrome拡張機能でScrapboxのショートカットを追加しましょう。

Chrome拡張機能とは言っても、ディレクトリを作成してその中に2つファイルを作るだけの簡単なものです。



```json:manifest.json(Chrome拡張機能の設定ファイル)
{
  "manifest_version": 2,
  "name": "myShortcutsScrapbox",
  "description": "Shortcuts for Scrapbox",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": [
        "https://scrapbox.io/*"
      ],
      "js": [
        "content.js"
      ],
      "run_at": "document_end",
      "all_frames": true
    }
  ]
}
```


```javascript:content.js

window.onload = function () {
    document.addEventListener('keydown', function (e) {
        if (e.ctrlKey == true) {
            switch (e.keyCode) {
                case 188:
                    // Key: (ctrl +) ","
                    document.getElementsByClassName('project-home')[0].click();
                    return false;
                case 190:
                    // Key: (ctrl +) "."
                    document.getElementsByClassName('new-button')[0].click();
                    return false;
            } 
        }
    });
}
```
僕が欲しかったのは「新規作成」と「ホームに戻る」の２つだけだったのでcontent.jsはこうなっていますが、自分に合わせて好きにカスタマイズしてください。

## Chrome拡張機能の読み込み
[chrome://extensions/](URL) にアクセスし、左上の方にある"Load Unpackd"（日本語だと「パッケージ化されていない拡張機能を読み込む」）をクリックして先ほど作成した2つのファイルが入ったディレクトリを選択し読み込みます。読み込むとScrapboxで自作新規作成ショートカット(Crtl + m)が効くようになっていると思うので、一度試してみてください。

## まとめ
少し工夫してみたのでQiitaにまとめてみました。良いScrapboxライフを!

＊参考＊
[ChromeのPWAでScrapboxを独立アプリ化](https://scrapbox.io/rashitamemo/Chrome%E3%81%AEPWA%E3%81%A7Scrapbox%E3%82%92%E7%8B%AC%E7%AB%8B%E3%82%A2%E3%83%97%E3%83%AA%E5%8C%96)

追記
2020/06/27：　既存のショートカットと被っていたので `ctrl + ,` と `ctrl + .` に変更しました。
2020/07/06: 少し補足。ScrapBoxは最終行の下に一行自動で追加してくれるので、Macの方は「Ctrl + m」で日本語変換確定、「Ctrl + n」で次の行へ移動。の2つを使えばEnterキーをあまり使わなくて済むので良いかもしれません。
[Android] LiveEventまとめ

`LiveData`をイベントの通知(トーストやダイアログを表示指示)として利用する、いわゆる`LiveEvent`の実装をまとめました。

## どれを使えばいいの？
結論から先に言うと、[hadilq/LiveEvent](#hadilqliveevent)または[最初の値を無視](#最初の値を無視)を使うといいと思います。その他に紹介している[SingleLiveEvent](#singleliveevent)、[Event](#event)、[SingleLiveEvent2](#singleliveevent2)は実装に問題があるので使わないほうがいいです。

## SingleLiveEvent
architecture-samplesのTODOアプリで昔使われていたやつ。`MutableLiveData`を継承し`setValue()`等で設定された値は一度だけ`onChanged()`に流れることを保証するクラス。

https://github.com/android/architecture-samples/blob/todo-mvvm-live-kotlin/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/SingleLiveEvent.kt

**問題点**
複数`Observer`が存在する場合に、一つの`Observer`だけにしか値が流れない。

## Event
`SingleLiveEvent`の改良。`MutableLiveData`を継承した独自クラスではなく、通常の`LiveData`に`Event`でラップした値を流す。  

https://github.com/android/architecture-samples/blob/todo-mvvm-live-kotlin/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/Event.kt
https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

**改善点**
一度だけ値を取得できる`getContentIfNotHandled()`と常に値を取得できる`peekContent()`の2種類のインターフェースを提供することで、Viewにイベントを通知しつつLoggerで毎回値を取得するようなユースケースは達成できるようになった。

**問題点**
`SingleLiveEvent`と同じく、イベントとして購読したい`Observer`が2つ以上ある場合には利用できない。
値をラップしないと使えないので若干冗長。

## SingleLiveEvent2
`SingleLiveEvent`の改良。`MutableLiveData`を継承した独自クラスで`Observer`の`MutableSet`を管理し、全ての`Observer`に対して一度だけ`onChanged()`が呼ばれるようにする。

https://medium.com/@star_zero/singleliveevent-livedata-with-multi-observers-384e17c60a16

**改善点**
`Event`で実現できない複数`Observer`に対するイベントの通知を実現。

**問題点**
最初に購読した`LifecycleOwner`のライフサイクルに、その後購読した全ての`Observer`が従ってしまう。  

## 最初の値を無視
`LiveData`でイベントを扱った時に起こる問題は最新の値がキャッシュされることに起因するので、それを排除するというアプローチ。`LiveData`と`observe()`の両方を拡張関数で手を入れることでキャッシュされる値を無視する。

https://satoshun.github.io/2018/05/singlelivedata/

**利点**
シンプルな拡張でイベントの通知を実現。

**問題点**
`LiveData`と`observe()`の両方が正しく揃うことで動作するので、他の実装に比べてバグが混入しやすい。

## hadilq/LiveEvent
`MediatorLiveData`を継承した独自クラスの内部で`Observer`をラップする`ObserverWrapper`を生成、その中で一度だけのイベント通知を実現している。

https://github.com/hadilq/LiveEvent

**利点**
ライブラリとして簡単に利用できる。

**問題点**
無さそうに思える。


## まとめ
|手法|複数Observer対応|イベントが発生した後の購読で値が流れない|
|:--|:-:|:-:|
|[SingleLiveEvent](#singleliveevent)|×|×|
|[Event](#event)|△|×|
|[SingleLiveEvent2](#singleliveevent2)|○|○|
|[最初の値を無視](#最初の値を無視)|○|○|
|[hadilq/LiveEvent](#hadilqliveevent)|○|○|
javac, jar, javaコマンドチートシート

# Javaでプログラムを作成後の実行までの順序。

1. compile。`javac`コマンドを使う。
1. jarファイルの作成。`jar`コマンドを使う。
1. run。`java`コマンドを使う。

# javacコマンド

## help

```
javac --help
```

`javac -help`, `javac -?`も同じ。
`javac -h`は別物。

## compile Java8以前 module不使用

```compile-java8-earlier-none-module.sh
javac -d /path/to/bin/directory \
--class-path /path/to/files1:/path/to/files2 \
--release 8 \
$(find /path/to/src/directory -name "*.java")
```

`--release`でversion選択。  
`$(find /path/to/src/directory -name "*.java")`で指定ディレクトリ内の`*.java`を全てコンパイルする。

## compile Java9以降 module使用

```compile-java9-later-with-module.sh
javac -d /path/to/bin/directory \
--module-path /path/to/module/dir1:/path/to/module/dir2 \
--release 11 \
$(find /path/to/src/directory -name "*.java")
```

# jarコマンド

## help

```
jar --help
```
`jar -?`, `jar -h`も同じ。

## create

```jar-create-simple.sh
jar -c \
-f /path/to/Export.jar \
-C /path/to/src/directory .
```

`-C`を使うときは、末尾に`.`を忘れないこと。

### create Executable-jar

```jar-create-executable.sh
jar -c \
-f /path/to/Executable.jar \
-e package.to.MainClass \
-C /path/to/src/directory .
```
`-e`でエントリーポイントを指定する。


# javaコマンド

## help
```
java --help
```

## run

```run.sh
java -cp /path/to/file1:/path/to/file2 \
package.to.MainClass
```

## run Executable-jar

```run-executable-jar.sh
java -cp /path/to/file1:/path/to/file2 \
-jar /path/to/Executable.jar
```

## run Java9以降 module使用

```run-with-module.sh
java --module-path /path/to/module/dir1:/path/to/module/dir2 \
--module name.of.module/package.to.MainClass
```

# build and run sample

## build and run Java8以前 module不使用

```build-and-run-none-module.sh
#!/bin/sh

path_src="/path/to/src/directory"
path_bin="/path/to/bin/directory"
path_export_jar="/path/to/Export.jar"
path_lib="/path/to/lib/*"
entry_point="package.to.MainClass"
version="8"

# compile
javac -d ${path_bin} \
--class-path ${path_lib} \
--release ${version} \
$(find ${path_src} -name "*.java")

# jar
jar -c \
-f ${path_export_jar} \
-C ${path_bin} .

# run
java -cp ${path_lib}:${path_export_jar} \
${entry_point}
```

# build and run Java9以降 module使用

```build-and-run-with-module.sh
#!/bin/sh

path_src="/path/to/src/directory"
path_bin="/path/to/bin/directory"
path_export_jar="/path/to/Export.jar"
path_lib="/path/to/lib"
entry_point="name.of.module/package.to.MainClass"
version="11"

# compile
javac -d ${path_bin} \
--module-path ${path_lib} \
--release ${version} \
$(find ${path_src} -name "*.java")

# jar
jar -c \
-f ${path_export_jar} \
-C ${path_bin} .

# run
java --module-path ${path_lib}:${path_export_jar} \
--module ${entry_point}
```
それでもNucleo+STM32CubeIDEを選ぶワケ

#既存プラットフォームの不満
色々なマイコンプラットフォームを触ってきましたが、どれも自分のやりたいことがすんなりできないという状況が続いてきました。

##Arduino
- 長く使えそうだと思っていた思っていたAruduino 101が、後継機種無しのディスコンになってしまった。(Intelの、いつものちょっと売れないと辞めちゃう悪い癖が出ただけでArduinoが悪いわけではないですが。)
- デバイスライブラリが弱く、I2Cデバイス等、少し凝ったデバイスを使おうとすると、D/Sを眺めながら一からプログラムしなければならない。(Arduinoの手軽さがイマイチ活きない。)
- MCUの性能を完全に引き出せない。(まあ、そういうプラットフォームじゃないので、批判するべき点ではないですが)

*それでも懲りずに、[Arduino nano BLE33 sense](https://www.chip1stop.com/view/dispDetail/DispDetail?partId=ARDU-0000801&mpn=ARDUINO+NANO+33+BLE+SENSE+WITH+HEADERS&keyword=Arduino+BLE+sense+)は触ってみようと思ってますが。

##MBed
- 仕事で使おうと思ったときに、メモリ書き込みでのプログラム実行はセキュリティのハードルが高い。
- ライブラリがオープンソースなので、メンテされてないことがままあり、それの調査で逆にプログラムの手間がかかる。(micro:bitはある程度仕方ないにしろ、STの加速度センサが動かないのは参りました...)

##micro:bit
- せっかくBLEチップが乗っているのに、標準開発環境では、フルに機能を引き出せない。(micro:bitの開発コンセプトとかけ離れているので、仕方がないですが。)

##M5Stack
- ハードウェアの電気特性が良くない。(ADC使うとスピーカーから音が出たり、BLE反応速度が悪かったり)

#Nucleoとは?
##特長
STM32という、シンプルな組み込み用ARM ICと、そのICにプログラムを書き込むツール、**デバッグツール**が一体になっているボードです。

##デバッグツールとは?
ざっくり言えば、
- マイコンのプログラムを逐次実行(止めながら実行)できる。
- プログラムを止めたとき、その時の変数が分かる。
ツールです。

ArduinoやMBedでプログラムのデバッグする場合は、問題になってそうな場所に、シリアルポートに変数を出力するコードを書くなどして、いろいろ試行錯誤すると思いますが、そのようなコードを書くことなく、かつ複数の変数を確認することができます。

##デバッグツールを使うには?
Nucleoでは、ArduinoIDEでもMBed IDEでも、プログラムを書くことができますが、このデバッグツールを活用することは出来ません。ARM専用のプログラミングツールを使う必要があります。

#STM32CubeIDEとは?
ST社純正のARM開発ツールです。

##特長
- フリーウェア
- ICのIOの設定やクロックの設定をGUIで設定することができる。
- Nucleoのデバッグツールを利用できる。

##短所
- GUIで生成したソースのどこを触っていいのか、分かりにくい。
- ツールや関数のリファレンスとなる情報が少ない。

#まとめ
自分のやりたいことが、音を扱うマイコンプログラミングという、MAKER界隈で、余り盛んでない分野(シンセ分野はアナログ回路が中心。マイコン界隈は、ロボットやIoTなど、そこまでリアルタイム性が問われない分野が中心)なのに、既存のお手軽ツールを使って何かしよう、という考えが間違ってた、ということに気づくのに、随分、時間がかかってしまいました。

何か面白いものが出来たら、また記事にします。
ランダムな点のアニメーション（regl + React 利用）

こんにちは。
[regl](https://github.com/regl-project/regl) (Functional WebGL, GitHub) + React を利用しランダムな点のアニメーションを描いてみました。定期的更新には [use-interval](https://github.com/donavon/use-interval) (GitHub) を用いました。

![regl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/75a59628-7b14-41fd-33e2-ddbc57edf281.jpeg)

```App.js
import React from 'react';
import createRegl from 'regl';
import useInterval from 'use-interval';

const App = () => {

  const pointSize = 14;
  const pointRandom = () => 
	      [2 * Math.random() - 1,  // x
	       2 * Math.random() - 1,  // y
	       Math.random(), Math.random(), 0];  // r, g, b
  const generatePoints = (nPoints) => Array(nPoints).fill(0).map(pointRandom);

  const regl = createRegl(document.querySelector('.canvas'));

  const frag = `
	  precision mediump float;
	  varying vec3 fragColor;
	  void main() {
	    gl_FragColor = vec4(fragColor, 1);
	  }
  `;
	
  const vert = `
	  varying vec3 fragColor;
	  attribute vec2 pos;
	  attribute vec3 color;
	  uniform float pointSize;
	  void main() {
	    fragColor = color;
	    gl_PointSize = pointSize;
	    gl_Position = vec4(pos, 0, 1);
	  }
  `;
  
  const drawPoints = regl({
    frag: frag,
    vert: vert,
    primitive: 'points',
    count: (context, props) => props.points.length,
    attributes: {
      pos: (context, props) => props.points.map(d => d.slice(0, 2)),
      color: (context, props) => props.points.map(d => d.slice(2, 5))
    },
    uniforms: {
      pointSize: pointSize,
	  points: regl.prop('points')
    }
  });

  const clearRegl = () => regl.clear({
        color: [0, 0, 0, 0],
        depth: 1
      });

  let i = 0;
  useInterval(() => {
      clearRegl();
      drawPoints({points: generatePoints((++i%2)*4+2)});
  }, 1000);

  return <div className='canvas'></div>;
};

export default App;
```
Djangoのテンプレート内で定数を扱う

# はじめに

Djangoのテンプレート内でドメイン名やサイト名などの基本的に固定となる定数値を扱いたいとき、Context Processorという機能を利用して、都度ビュー側から定数を渡さずにテンプレート内から定数のように扱うことができます。

## 環境
- Django 2.2

# Context Processor とは

Context Processorはビューからテンプレートへコンテキストオブジェクトを渡す際に変数を追加する処理を記述できる関数です。
テンプレート内で利用する`csrf_token`等がこの仕組みで実装されています。

## Context Processor の作成

Context Processorは`HTTP Request`オブジェクトを引数として、辞書型のオブジェクトを返す関数として定義します。

関数の名前は任意の名前で作成し、ファイルはアプリケーションのディレクトリ配下等に作成します。

```python:hogeapp/context_processors.py
def my_context_processor(req):
    return {
        'domain_name': 'https://hogehoge.com',
        'site_name': 'Hogehoge Site',
    }
```

上記の例では単純に辞書オブジェクトを返却しているのみですが、通常の関数同様に処理を記述することもできます。これを利用して外部ファイルに別で定義した定数を参照したり、環境変数の値から環境によって値を変える等の使い方も可能です。

## config.py設定

作成したContext Processorを利用するには、`config.py`への設定が必要になります。
`config.py`で定義されているTEMPLATESのOPTIONSにある`context_processors`へ前項で作成した関数を追加します。

```python:config.py
TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'hogeapp.context_processors.my_context_processor', # 追加
            ],
        },
    },
]
```

## テンプレートからの呼び出し方法

Context Processorで追加される変数は、テンプレート内から通常のコンテキストの変数と同じように利用できます。

```html:template.html
<link rel="icon" href="{{ domain_name }}/favicon.ico">
<title>{{ site_name }}</title>
```

# 参考

The Django template language: for Python programmers | Django ドキュメント | Django
https://docs.djangoproject.com/ja/2.2/ref/templates/api/#writing-your-own-context-processors
fetch template

phpでデータを取ってくる。

変数（parameter)と値（value)をsetDataに渡して、setDataToDB.phpでは例えばPDOでDBにデータをupdate(or insert)する。

setDataToDB.phpがもし戻り値としてデータセットを返す場合には```then((json)```の中で処理する。

```fetchSample.js
function setData(paramater, value) {
    var res = fetch("./setDataToDB.php", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            "value": value
        })
     }).then((response) => {
        if(response.ok)
        return response.json(); // レスポンスをテキストとして変換する
    }).then((json) => {
        //console.log(json[0]["someParameter"]);　//複数のデータセットが帰ってくる場合は０でない。
        //何らかの処理;
        return json[0]["otherParameter"]; //returnで返らない？
    });
}
```
fetchで取ってきた値を他の関数でも使いたい場合にはどうするの？

 受信するphp
- 
```setDataToDB.php
<?php
$str_json = file_get_contents('php://input');
$json_obj = json_decode($str_json, true);

//データベース接続ーーーーーーーーーーーーーーーー
$dsn = 'mysql:dbname=データベース名;host=localhost';
$user = 'ユーザ名';
$password = 'パスワード';
$dbh = new PDO($dsn, $user, $password);

//SQL処理ーーーーーーーーーーーーーーーーーーーーー
$dbh->beginTransaction();
$stmt = $dbh->prepare("update テーブル名 set カラム名=:mode;");
$stmt->bindParam(':mode', $json_obj["value"], PDO::PARAM_STR);
$stmt->execute();
$dbh->commit();
$result = $stmt->fetchall(PDO::FETCH_ASSOC);

echo $result; //結果
?>
```
FlutterでCrashlyticsにクラッシュレポートが反映されない時のチェックポイント

FlutterアプリでCrashlyticsでレポートを表示できるようになるまでに結構ハマったので確認ポイントをまとめておきます。

## フィルタがクラッシュになっていないか確認
  Crashlyticsダッシュボードでイベントの種類=クラッシュになっていないことを確認します。dart上のExceptionはクラッシュとしてレポートされず、非重大になります。

## Flutter Inspectorが有効になっているとレポートされない
  Flutter Inspectorが有効になっていると、Flutter Inspectorが例外をキャッチしてしまい、Crashlyticsがキャッチできないようです。IDEを使っていて意図したようにCrashlyticsのデバッグログが出ない場合は、コマンドラインで `flutter clean` から `flutter run` でアプリを起動すると、期待するCrashlyticsのログがでると思います。
  参考
  https://github.com/flutter/flutter/issues/41540#issuecomment-554659020

## runZoned内で `WidgetsFlutterBinding.ensureInitialized();` を呼ぶ
  ドキュメントでは以下のように書かれています。

```dart
runZoned<Future<void>>(() async {
    // ...
  }, onError: Crashlytics.instance.recordError);
```

なので、たぶんこんな感じに書くと思います。

```dart
runZoned<Future<void>>(() async {
    runApp(MyApp();
  }, onError: Crashlytics.instance.recordError);
```
これだと、非同期コード内でのクラッシュを期待通りに補足できませんでした。
以下のように書くことで、非同期コード内のクラッシュがレポートされるようになりました。

```dart
runZoned<Future<void>>(() async {
    WidgetsFlutterBinding.ensureInitialized(); // 追加
    runApp(MyApp();
  }, onError: Crashlytics.instance.recordError);
```

参考
https://github.com/flutter/flutter/issues/50188#issuecomment-583345958

## 初回ビルドはクラッシュレポートが送信されない
ソースが何か忘れてしまいましたが、SDKを導入した初回ビルドはレポートが送信されないみたいです。

  
以上
ブランチが壊れたときの修正方法

# ブランチが壊れた
なんかブランチが壊れた。
症状は、全てのファイルを新規ファイルと認識していて、スタッシュもチェックアウトもできない。
スタッシュをしようとすると、下記のエラーが出てきます。

```terminal
You do not have the initial commit yet
```

多分、プッシュしてる途中でPCが謎の再起動を始めたせい。

途中だったプッシュはgitlabに反映されているから問題ないように見えるけど、ローカルには問題しかない。
もう一度PC再起動してみたけど意味ありませんでした。

# 修正手順
まず、エラーを確認します。

``` terminal
$  git log
fatal: your current branch appears to be broken
```

がっつり、ブランチが壊れたって書かれています。

次に、gitのログを確認します。
※ブランチ名は`feature_20200619`とします

```terminal
$ ls .git/logs/refs/heads/feature_20200619
.git/logs/refs/heads/feature_20200619
```

慎重派なので、本当はディレクトリ1つずつ確認していって、ブランチのところまでたどり着きました。

とにかく、ログがあることを確認したので、開きます。

``` terminal
$ vim  .git/logs/refs/heads/feature_20200619
```

こんな感じのログファイルが開きました。
gitのログファイル初めて見た。
ハッシュは短く編集してます。

```
000000000000000 81df1698f65da66 {ユーザー名} <{メールアドレス}> {タイムスタンプ} branch: Created from HEAD
81df1698f65da66 cf3db6d02cf79e1 {ユーザー名} <{メールアドレス}> {タイムスタンプ} commit: コミットメッセージ１
cf3db6d02cf79e1 89afc1b749f3a6c {ユーザー名} <{メールアドレス}> {タイムスタンプ} commit: コミットメッセージ２
89afc1b749f3a6c aabf716e45789eb {ユーザー名} <{メールアドレス}> {タイムスタンプ} commit: コミットメッセージ３
```

コミットのカズだけログがあるっぽい。
最後のログの`aabf716e45789eb `をコピーします。

次に下記コマンドで別のファイルを開きます。

``` terminal
$ ls .git/refs/heads/feature_20200619
.git/refs/heads/feature_20200619

$ vim .git/refs/heads/feature_20200619
```

文字化けっぽい文字の羅列が表示されたので、それを消して先程コピーしたハッシュで上書きします。

``` terminal
$ git stash save test
No local changes to save
```

スタッシュしようとしたら変更点ないよって言われたので、復元成功です。

# 参考
- [Broken branch in git, fatal: your current branch appears to be broken - Stack Overflow](https://stackoverflow.com/questions/33012869/broken-branch-in-git-fatal-your-current-branch-appears-to-be-broken/48716529#48716529)
csvデータを取り出し、計算する

## csvデータを取り扱う

データ分析をするとき、cvsデータの扱い方を毎回忘れてしまうので、メモとしてまとめておきたいと思います。

## csvを読み込む


```python
import pandas as pd
pd.read_csv('data.csv')
```
`UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 0: invalid start byte`とエラーが出てきてしまいました。

```python
pd.read_csv('data.csv' , encoding='cp932')
```
`encoding='cp932'`を後ろに付けたらちゃんと表示されました。


## csvデータから列・行を取り出す
csvから１行または1列だけデータを取得

```python
df = pd.read_csv('data.csv' , encoding='cp932')

df.iloc[0,:] #1行目すべてのデータを取り出す
df.iloc[:,2] #3列目すべてのデータを取り出す
```

## pandas.DataFrameの行を取得

[行名・行番号のスライス]：　複数行を取り出す

```python
df[1:4] #1行目から３行目まで取り出す
```

## 列ごとに合計を計算する
1列のデータをすべて足して合計を出す

```python
df.iloc[:,3].sum() #４列目のデータの合計を出す
```

## csvデータをfor文で計算
csvデータの列データを一定の数で割りたいとき

```python
#csvデータの３列目の数値をそれぞれ２で割る
w = df.iloc[:,2]

for i in w:
    d = i / 2
    print(d)  
```
初めての執筆本

## はじめに
ホワイトカラーの現場働き方改革、組織風土改革の現場指導から、IT分野でのAgile開発、DevOps2.0、の導入や同手法によるプロジェクト支援を十数年実施してきました。その集大成といえる本[『チーム改革のスイッチ』本を執筆出版](https://manaslink.booth.pm/items/2147603)した。
64歳にて著書に自分の名が載る、ある意味では執筆活動の遅咲きである。
若いエンジニアの間では我々の年代のアドバイスを老害という輩もいるが、現場に身をおき改善活動を実践してきた老兵の経験値を綴っていきたいと思う。
## 日本の大企業の現状
![IMG_4994.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621379/48d6defa-6a12-def9-b944-5b9adb7ff88b.jpeg)
日本では『Agile開発は当たり前にどこでも実践している』状態にはなっていない、特に大企業では従来の古びたW/Fから抜けだせないでいる。言語もCOBOLという古い言語に頼っている。
全ての産業でITがビジネスモデルそのものを実現している時代で、このような状況では、世界の当たり前にいつしか取り残されてしまうだろう・・・
## TMS（Toyota way Management System)
私のメインスキルであるTMS（Toyota way Management System)について、その名にTOYOTAが付くように、Toyotaのマネジメントの中核となるシステムであり、人間性尊重をベースに仕事を通じて生き甲斐・達成感を味わえる職場作り、活動の見える化から始めて・・・価値の創造・・・利益の創造までに役立つマネジメント手法アーキテクチャなのです。

AgileのScrumやLeanはToyotaのマネジメントや働き方（TPS）を研究してそれを源に発生してきました。

しかし、それらの手法は古い20世紀のToyotaを真似ているもので、何世代も前の古いものを日本へ焼き直しして逆輸入しています。

私が所属しているTMS/TPS検定協会は進化し続けているToyotaのマネジメントをToyota以外の企業へ導入支援する為にToyotaのOBで組織されました。

### TPSをホワイトカラー等に応用

私はTOYOTA出身者ではありませんが、TMSの指導者として認定された数少ない講師の一人です。TPS(Toyota Production System)をソフトウエア開発やホワイトカラーへ如何に応用するノウハウ・経験を多く積んでいます。その実践した内容を書いていますが、ソフトウェアにはなじみがない用語を並べると、『自工程完結』・『一個流し』・『流水化』といった言葉についてもAgile開発などで、どのように実践するのかを、実践例から解説しています。

また、AgileやDevOpsでいわれるようになったバリューストリームマップ（VSM）も元々は工場の情報・人・物の流れを可視化して改善につなげる方法をソフトウエア開発へ応用したものです。本書でも解説しています。

### 本の全体像

私の知人でプレイングマネージャーとして信頼しているauカブコム証券の石川さん（ @ishiayaya ）がこの本に書いてあることを一枚の絵にまとめてくれています。![開発品質-スイッチ本 (1)_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621379/9cadee92-84d3-5d1b-9487-b8bc969fc004.jpeg)
この一冊がとても多くの範囲を網羅していることがわかります。

## おわりに

本を深堀し実践値の共有や相談できる[コンソーシアムもFacebook内に設立](https://www.facebook.com/groups/jpinnova/)しています。
これからは、きままにこの本をきっかけに起きた出来事や本をより深く理解するコメントを載せていきますので、よろしくお願いいたします。
エラー解決：vimrc が編集できない

# 問題 vimrcが編集できない

##結論
- ファイルが編集できない場合は編集権限を確認してみる

`実際の確認方法`

```
$ ls -a
```
- おかしい場合はファイルを削除、作り直してもう一度確認する


##エラー文

```
vim .vimrc
編集
".vimrc" E166: Can't open linked file for writing
```

# 原因 以前dotfileを作成しようとして失敗した。その時いじったシンボリックリンクが残っていた。

```
$ ls -al

lrwxr-xr-x    1 #{myname}  staff        38  5 21 21:02 .vimrc -> /Users/#{myname}/dotfiles/_vimrc
-rw-r--r--    1 root             staff      1166  6 19 22:34 .vimrc?
```


# 解決 `ファイル削除` `ファイル作成`

`ファイル削除`

```
mba-2:~ #{myname}$ sudo rm .vimrc
Password:
rm: .vimrc: No such file or directory
mba-2:~ #{myname}$ sudo rm .vimrc?
mba-2:~ #{myname}$ ls -al
```


`ファイル作成`

```
mba-2:~ #{myname}$ cd
mba-2:~ #{myname}$ touch ./.vimrc
mba-2:~ #{myname}$ vim .vimrc
```

```
mba-2:~ #{myname}$ vim .vimrc
#編集
#保存
#成功
```
MacOS Catalina ver 10.15.2 でNAS接続でハマったので対処の忘備録

echo “[default]” | sudo tee -a /etc/nsmb.conf 

-----------

echo “port445=both” | sudo tee -a /etc/nsmb.conf

なんか、セキュリティの都合とかでだるくなったらしい。同様の症状は多く出ているが、とりあえずこのコマンドをterminalで実行して再起動をかければNASにつながる。
forで配列・辞書要素の取り出し



for文で配列・辞書要素を取り出すときのメモとして記載します。
参考：
[Pythonのfor文によるループ処理（range, enumerate, zipなど）](https://note.nkmk.me/python-for-usage/)

```python
x=[7,4,1]
y=[8,5,2]
d={'a':9,'b':6,'c':3}

# 基本
for i in x:
    print(i)  
#>>> 7
#>>> 4
#>>> 1
```
####Dict（辞書型Key-Value）
```python
# Dict(辞書型)
for k,v in d.items():
    print(k,v)
#>>> a 9
#>>> b 6
#>>> c 3

#受ける変数を1つにするとTupleになる
for k in d.items():
    print(k)
#>>> ('a', 9)
#>>> ('b', 6)
#>>> ('c', 3)

#キーだけ取り出す
for k in d.keys():
    print(k)
#>>> a
#>>> b
#>>> c

#値だけ取り出す
for v in d.values():
    print(v)
#>>> 9
#>>> 6
#>>> 3
```
####zip

```python
#zipでまとめる
for i,j in zip(x,y):
    print(i,j)
#>>> 7 8
#>>> 4 5
#>>> 1 2

#受ける変数を1つにするとTupleになる。
for i in zip(x,y):
    print(i)
#>>> (7, 8)
#>>> (4, 5)
#>>> (1, 2)

#辞書型はTupleになる
for i,j,k,l in zip(x,y,d.items(),x):
    print(i,j,k,l)  
#>>> 7 8 ('a', 9) 7
#>>> 4 5 ('b', 6) 4
#>>> 1 2 ('c', 3) 1

#辞書型はTupleになるのでインデックス番号で分ける
for i,j,k in zip(x,y,d.items()):
    print(i,j,k[0],k[1])
#>>> 7 8 a 9
#>>> 4 5 b 6
#>>> 1 2 c 3

#受ける変数を1つにするとTupleになる。
for i in zip(x,y,d.items(),x):
    print(i) 
#>>> (7, 8, ('a', 9), 7)
#>>> (4, 5, ('b', 6), 4)
#>>> (1, 2, ('c', 3), 1)
```

####enumerate

```python
# enumerateを使ってインデックス番号を入れる
for i, j in enumerate(y):
    print(i,j)
#>>> 0 8
#>>> 1 5
#>>> 2 2

#受ける変数を1つにするとTupleになる。
for i in enumerate(y):
    print(i)
#>>> (0, 8)
#>>> (1, 5)
#>>> (2, 2)

#辞書型を入れる。辞書型はTupleになる。受ける変数を3つにするとエラーになる
for i, j in enumerate(d.items()):
    print(i,j)
#>>> 0 ('a', 9)
#>>> 1 ('b', 6)
#>>> 2 ('c', 3)

#Zipを入れてみる。受ける変数を4つにするとエラーになる。受ける変数は2つ。Zip内はTupleになる
for i, j in enumerate(zip(x,y,d.items())):
    print(i,j)
#>>> 0 (7, 8, ('a', 9))
#>>> 1 (4, 5, ('b', 6))
#>>> 2 (1, 2, ('c', 3))

#zip内の内容を受ける変数をTupleにすると個別に受け取ることができる
for i,(j,k,l) in enumerate(zip(x,y,d.items())):
    print(i,j,k,l)
#>>> 0 7 8 ('a', 9)
#>>> 1 4 5 ('b', 6)
#>>> 2 1 2 ('c', 3)
```
ゼロから始めるLeetCode Day61「7. Reverse Integer」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day60「1481. Least Number of Unique Integers after K Removals」](https://qiita.com/KueharX/items/78d5ec5a144597304f91)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。


# 問題
[7. Reverse Integer](https://leetcode.com/problems/reverse-integer/)

難易度はEasy。
32ビット符号付き整数`x`が与えられたとき、整数の逆数を計算するアルゴリズムを設計してください、という問題です。

>Input: 123
Output: 321

>Input: -123
Output: -321

>Input: 120
Output: 21


# 解法

Pythonの場合はスライスと`abs`を使えば要素の指定と絶対値の管理ができるので比較的解きやすいのではないかと思います。

他の言語については知りませんが、スタックを使って解くのが一般的なのかもしれませんね。

今回は32bit整数という前提があるため、処理に入る前に別の桁を追加してもオーバーフローしないかを事前に確認しておく方が良いでしょう。

Pythonではint型に最大値がないのでメモリの有る限りいくらでも計算できます。
なので以下のように自分で設定しておく必要があります。

```python
max_32 = 2**31 - 1
```

最初にこの値より`x`が大きかった場合は無条件で0を返すときちんと場合分けできていると思います。

そして、この後の分岐ですが、正の値ならば後ろから要素を取ってあげて、負の値ならば絶対値の逆から要素を取ってあげて代入する前に`-`を付けてあげます。

Pythonでは負の値ならば代入する要素の先頭に`-`を付けてあげると反転し直した後にも`-`がついた状態になります。

反転させたものを内包表記で書けば良くない？と思う方がいらっしゃるかもしれませんが、これだけで処理を終わらせてしまってはオーバーフローする可能性がまだ残っている可能性があります。

なので、最後の分岐に仮にオーバーフローしそうなら0を返し、それ以外の場合にのみ反転した値を返せば完成です。

これらの一連の流れをまとめたものが以下になります。

```python
class Solution:
    def reverse(self, x: int) -> int:
        max_32 = 2**31 - 1
        if abs(x) > max_32:
            return 0
        if x < 0:
            reverse_int = -int(str(abs(x))[::-1])
        else:
            reverse_int = int(str(x)[::-1])
        if abs(reverse_int) > max_32:
            return 0
        else:
            return reverse_int
# Runtime: 28 ms, faster than 86.13% of Python3 online submissions for Reverse Integer.
# Memory Usage: 14 MB, less than 9.77% of Python3 online submissions for Reverse Integer.
```


そういえば新しくブログを始めました。
Qiitaでも発信は続けて行く予定ですが、まったりとした内容で書ける技術・ガジェットブログみたいな感じで書く予定なので興味ある方はプロフィールからどうぞ。

今回はここまで。お疲れ様でした。
現代のフロントエンド開発シリーズ（7）- フロントエンドでもエンジニアリング必要があるのはなぜですか？

> ソフトウェアの品質を改善するために、定量化および標準化された方法でソフトウェアを開発する

では、なぜフロントエンドを体系的にする必要があるのでしょうか。私はいくつかの点があるかと思います：

1. 以前、フロントエンドの複雑さはそれほど高くなく、静的なページを表示するだけで十分でしたが、技術の進歩に伴い、エンジニアリングに役立つツールを導入しないと、多くのアプリケーションがますます複雑になっています（googleドライブ、facebookなど）。エンジニアリングの手法を導入しないと、プログラムの開発は管理しにくくなるでしょう
2. フロントエンドの開発が徐々に成熟しているため、フロントエンドエンジニアリング用のツール（gulp、webpackなど）を開発する余裕があります。

実際、フロントエンドエンジニアリングは、「ああ、エンジニアリングを今すぐやろう」みたいな流行語ではありませんが、開発中は「ああ、できるなら」のように感じられます。

今日は、フロントエンドエンジニアリングを行う際の一般的な概念と構築ツールをいくつか紹介します。

## [Webpack](https://webpack.js.org/)

大規模なフロントエンドプロジェクトの中で、`webpack`はほとんど不可欠なツールです。

JavaScript初期の頃は、モジュールを管理する適切な方法がなく、モジュール化にするには、いくつかの設計パターンとエンジニア自身の経験などにしか頼ることができませんでした。

例として、モジュールをファイルで分けると、すぐに次のような依存関係の問題が発生します。

```html
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
<script type="text/javascript" src="d.js"></script>
```
仮にdはa、b、cに依存するとして、順番が変更されるとバグが爆発します。時間が経つにつれ、全員が同じ場所ですべてをモジュール化することを望まなくなります。

依存関係メソッドを定義するCommonJSやRequireJSなどのいくつかのソリューションがあり、ライブラリを使用して依存関係の問題を解決できました。

ただし、まだいくつかの問題があります。

* 依存関係は自分で宣言する必要があります
* 動的インポート（Dynamic Import）を実行する場合、あまり解析する方法はない

`webpack`が登場した後、非常に強力なので、すぐに開発者に好まれました。

JavaScriptファイルに加えて、ローダーが設定されている限り、画像、フォントファイル、CSSなどをロードすることもできます。

## Tree Shaking

初めてこの言葉を見たときは、すごくかっこよくて、概念的に考えやすかったと思いますね。木を振ると枯れ葉が落ちてしまいました。

ここで、枯れ葉の実は不要なコードを指します。ツリーの揺れとは、プログラムを作成するときにモジュールコードの一部しか使用しないことがあるため、ファイル全体をバンドルする必要がないことを指します。バンドルサイズを小さくすることができます。

このコードがほかの部分も使用されていないことをどのように知るかのを問題です。

一般的な静的言語では、コンパイラーに依存してこれを行うことができますが、JavaScriptでは、自分自身にのみ依存できます。幸い、webpack2後、開発者のためにツリーシェーキング関数を追加しましたが、静的に分析できるようにするためにes6インポートの構文に依存しています。

## デッドコードの排除（dead code elimination）

以下のような絶対に実行しないコードを削除することができ、略してDCEと呼ばれます。

`` `javascript
if（false）{
  // コード
}
```

条件は`false`のため、コードをここで実行することはできず、トランスパイルを実行するときにプラグを抜くことができます。

詳細については、Danの[開発モードの仕組み](https://overreacted.io/how-does-the-development-mode-work/)を参照してください。

## コード分割（Code Splitting）

コード分​​割の主な目的は、アプリケーションのコードとサードパーティライブラリのコードを2つのファイルに分割することです。

通常、使用するThird Partyのコードは、バージョン番号が変更のない限りほとんど変更されません。これらのコードをパッケージに分解し、CDNにアップロードしてキャッシュを有効にすることができるため、変更がある部分がリロードすることができます。アプリケーション自体のコードだけ、将来バージョン番号が変わったときに、ハッシュメカニズムで簡単に更新できます。

## 最小化

開発中は、目的を理解するために他の人（そして私たち自身）が理解できるように変数に明確な名前を付けますが、本番環境のビルドでは必要ありません。このとき、変数名を最小限に抑えることができます。

前述のように、パラメーターを渡す方法により、パラメーターで使用されているパラメーターを明確に把握できるだけでなく、最小化するのにも便利です。

## 動的なインポート(dynamic import)

ユーザーがホームページをロードするだけの場合、プロファイルページに入る必要がない場合があります。
したがってホームページに関連するコードのみをロードし、ユーザーがプロファイルページにアクセスしたときにコードをロードします。

## まとめ

Webpack構成ファイルは、使いやすい構成ファイルを書き込むのは非常に困難で、テストとパラメーターの調整に多くの時間がかかります。

完璧な構築メカニズムが必要な場合は、さまざまなプラグインを研究するのに長い時間がかかることがあります。もちろん、時間をかけて作図ツールを勉強すれば異なる意見を持つでしょう。設定の時間を節約したい場合は、`create-react-app`または`vue-cli`やその他のエコシステム構築ツールを使用することもできます。

ほとんどの設定は実際には同じですが（フロントエンド開発セクションで）、ニーズと使用条件に応じて異なる調整が必要になる場合があります。

さらに、アップグレードは非常に面倒な場合があります。たとえば、webpackのアップグレード時に、重大な変更が頻繁に発生します（それほど重大ではありませんが）。構成ファイルを変更するための調査にさらに時間がかかります。

記事のタイトルはフロントエンドエンジニアリングに関するものですが、この記事では主に構築ツールとそれに対応する概念について説明しました。
まっさらなSSDにmint20betaをインストール

まず、editorなににしようかな？
この時間って、かなり至福な時間。


emacsとか、むかしのSSDもあるので、そこから.emacsを引っ張ってくれば
すぐに設定は終わると思いきや。。

まず、ちょうひさしぶりのosインストールから、さらにはeditor
時代が変わりすぎていた。

aptでとか思ったら、いまはsnapd? , flatpak?
なんじゃそれ？
なにげジェネレーションギャップを感じた

また、mintだけsnapdは、拒否られているさまｗ
あとからしらべてやっとわかったのだが、自分もsnapdのような文化はいやかもｗ
mintが拒否るのもしかたないというか、良い方向かもｗ

aptでなく、今回はgimpとemacsは、flatpakでいれてみた。

また、ここでジェネレーションギャップが。。
/usr/local/binあたりにemacsがあるのかな？と思ったら、
ちがうじゃんｗ

しかたないから、デスクトップにemacsをピンとめして、
そのファイルを見て、どこから起動してるかしらべるところからｗ

また、ここで、びっくりｗ
/usr/bin/flatpak その引数に　emacsやらgimpがｗ
まあ、かなりのジェネレーションギャップだなｗ

とりあえず、emacsはインストールできたっと。(このさい、spacemacsにもこころが行ったが、やめといた)
で、go-modeのライブラリーをgo get で、。。
え？？

なんか、様子がおかしいｗ

またここでｗ
”LSP”というあたらしい用語がｗ
さいしょemacsのLISP??のこと？とよぎったが、ちがったｗ

どんだけ世界が変わってるのだ？ｗ
language server？ｗ　emacsの起動時もしくは、go関連のファイルを開いたら
ネットにってｗ重くないか？ｗ

それも、goplsをgetしてとかよくわからないんだがｗ
emacsでちゃんとgoソースを開いて、autocompleteしてくれるまで、まだまだ道のりがながそうだｗ
Helm chart repositoryの見方&使い方

## はじめに

kubenetes を使う状況において、デプロイには Helm を使うことが多いのではないでしょうか。
また、公式の[Helm Chart](https://github.com/helm/charts)にはお世話になる方も多いのではないでしょうか。

ただ、この Chart の使い方、初見では分かり辛くないですか？
Helm 初心者だった私は見方が分からず色々と遠回りをしました。。。
ということで、私の理解した repository (主に Configuration) の見方の知見を記載します。

### 書くこと

Github の repository の個人的見方

### 書かないこと

Helm のコマンドなどの使い方

## repository の見方

[nginx-ingress](https://github.com/helm/charts/tree/master/stable/nginx-ingress)をサンプルに記載します。

### Configuration とは

Helm に与える設定値のことが記載されています(が、与え方とか記載があったりなかったりなんですよね。。。)。
なので、どのように与えるかを記載します。
何がどのような設定なのかは各 Chart の Description をご参照のこと。

#### 引数として値を与える方法

nginx-ingress には以下記載がありました。

```bash
helm install stable/nginx-ingress --name my-release \
--set controller.metrics.enabled=true
```

上記のように、 `--set key=value`として与える方法があります。
ただ、個人的にはどのように値を与えたか把握できるように、次のファイルから値を与える方法が良いと思います。

#### ファイルから値を与える方法

値を yaml ファイルで与える方法があります。
サンプルとなる yaml ファイルは、[values.yaml](https://github.com/helm/charts/blob/master/stable/nginx-ingress/values.yaml)にあります。
この`values.yaml`をベースに、対応する`key`に対して値を設定し、`values.yaml`を作り、以下コマンドで与えることができます。

```bash
helm install stable/nginx-ingress --name my-release \
-f values.yaml
```

### 記載されている Configuration に関して

#### templates との関係

Helm を作ったことのある方はご承知だと思いますが。。。
`values.yaml`は、[templates](https://github.com/helm/charts/tree/master/stable/nginx-ingress/templates)内のファイルで使われる形になります。

例えば、

```
controller:
  name: controller
```

であれば、以下ファイルの `{{ .Values.controller.name }}` で参照されています。
https://github.com/helm/charts/blob/master/stable/nginx-ingress/templates/controller-deployment.yaml#L66

#### 未定義部分

Configuration に記載はないが、templates 内のファイルでは使用するように定義されていることもあります。
なので 「該当する設定 key がないなー」と思われた方は templates 内の該当しそうなファイルを確認することをお勧めします。

## 参考

https://helm.sh/docs/topics/chart_repository/
https://github.com/helm/charts/tree/master/stable/nginx-ingress
[光-Hikari-のPython]＜補足＞06章-05 関数（引数と戻り値4）

#[Python]＜補足＞06章-05 引数と戻り値4
[06章-04](https://qiita.com/ko0821/items/0b40411b66ff944c6e2e)で関数における引数がリストだった場合について説明しました。

そのほかのデータ構造である、タプルやディクショナリを引数として受け取るもできます。今回はタプルとディクショナリを引数として受け取ることについて取り扱いたいと思います。

なお、この節は<font color="red">＜補足＞</font>としていますので、時間のない方は読み飛ばしていただいても構いません。なお、基本情報技術者試験では今後タプルやディクショナリの引数の扱いをするといった問題も出題されることが予測されるため、目を通しておきましょう。

##任意の数の引数～タプルで受け取る～
関数を呼び出す際に、実引数と仮引数の数は以下のプログラムのように一致させないといけません。<font color="#00cccc">chap06</font>の中に、<font color="#00cccc">samp06-05-01.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。

```samp06-05-01.py
def called_func(x, y, z):
    print('関数内で実行しています。')
    print(x, y, z)


#called_func(2) #←引数の数が一致していないので、関数を呼び出すとエラーとなります
called_func(4, -1, 2)

```
><font color="#090" bgcolor="black">【実行結果】</font>
関数内で実行しています。
4 -1 2

最初の関数の呼び出し**called_func(2)**では実引数の数が1個ですが、仮引数の数は3つとなっており、一致していません。そのため、このコメントを外すとエラーとなります。

次に呼び出している**called_func(4, -1, 2)**では、実引数と仮引数の数が一致しているため、呼び出すことができます。

しかし、Pythonの関数では、任意の数の引数を受け取ることができるのです。それが以下の方法です。先ほど書いたプログラム<font color="#00cccc">samp06-05-01.py</font>を修正して、以下のコードを書いてください。

```samp06-05-01.py
def called_func(*args):
    print('関数内で実行しています。')
    print(args)


called_func(2)    #←今度は呼び出せます
called_func(4, -1, 2)
```

><font color="#090" bgcolor="black">【実行結果】</font>
関数内で実行しています。
(2,)
関数内で実行しています。
(4, -1, 2)

仮引数に\*（アスタリスク）を付けると、タプルとして受け取っていることがわかります。
なお、関数内で**\*args**の中身を出力していますが、出力する際には\*は不要です。また**\*args**という仮引数名を使用していますが、実際は何でも構いません。ただし、ほとんどの方が（慣習的に）**args**を使用しています。
<font color=orange>※</font>argsはargumentの略では引数という意味です。

##任意の数のキーワード引数～ディクショナリの受け取り～
[06章-03](https://qiita.com/ko0821/items/cbc691f92d670dd27498)でキーワード引数について取り扱いました。実はこのキーワード引数を実引数で指定し、仮引数でまとめて任意の数を受け取ることができます。
<font color="#00cccc">chap06</font>の中に、<font color="#00cccc">samp06-05-02.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。

```samp06-05-02.py
def called_func(**kwargs):
    print('関数内で実行しています。')
    print(kwargs)


called_func(x=1, y=2, z=3)
```
><font color="#090" bgcolor="black">【実行結果】</font>
関数内で実行しています。
{'x': 1, 'y': 2, 'z': 3}

実引数にキーワード引数を、仮引数に\*\*（アスタリスク2つ）を付けると、ディクショナリとして受け取っていることがわかります。
なお、関数内で**\*\*kwargs**の中身を出力していますが、出力する際には\*\*は不要です。また**\*\*kwargs**という仮引数名を使用していますが、実際は何でも構いません。ただし、ほとんどの方が（慣習的に）**\*\*kwargs**を使用しています。

##最後に
引数の受け取り方は多種ありますので、押さえておきましょう。タプルやディクショナリとして受け取るといったケースは見かける機会はあまりないですが、こういったこともできるということは把握しておいてください。ただし、情報処理技術者試験では出題される可能性はありますので注意しましょう。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)
Scratchでとけいゲームを作る

# 背景
今年、子供が小学校に入学しましたが、時計に苦戦しています。ちょっと暇があったので、簡単なゲームをScratchで作ってみました。
Scratchで作ろうと思ったのは、子供が興味を持った時に説明する準備になるかな、と思ったからです。

# 作ったもの
ランダムにアナログで時間を表示して、ボタンで時間を回答する簡単なものです。
[これです](https://scratch.mit.edu/projects/406169480)

# ふわっとした解説
## 文字盤の描画
Scratchにはスプライトというオブジェクト（キャラクタ）が用意されています。スプライトはコスチュームを所有していて、見た目を変更することが出来ます。
さらに、クローンというスプライトのコピーを作る機能を利用します。
具体的には、スプライトに1 - 12に対応するコスチュームを作成します。idというプライベート変数を用意し、2に対応するコスチュームに変更→id=2、クローン作成、というようにして2-12をクローンとして作成し、自分自身は1のコスチュームにしておきます。
クローンされたら、idに応じて三角関数を用いて円周上に配置します。

## 短針、長針
timeというグローバス変数を参照して角度を設定します。

## その他つまづいたところ
適宜waitしないと描画がうまくいかないことがありました。
スプライトを押したときの判定が透明部分にはないということに気が付かず、時間を浪費しました。
角度はradianでなくdegreeですね。

# 感想
すごく簡単に作れました。さすがはScratch。スプライト（オブジェクト）毎にコードを書くのが面白いと思いました。
下の画像のようなブロックの入れ子のようなものを作るとき、うまくはめ込まれないことが多く、手間取りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/097d28d9-8b7a-889f-4ea4-1117b09cb7fe.png)
普段キーボードでごりごり書いていると、ブロックを探してきて配置する操作にもどかしさを感じますが、わかりやすさが重要なので仕方がないことだと思います。
ノンプログラマーの初心者がAtomでPythonを使う

JupyternotebookをAtomで使用してみる際の自分用メモ。

# 準備
* Atom
* Hydrogen
    * Atomでjupyternotebookを使用する際のパッケージ
* Jupyternotebook

# AtomでPythonを実行する
## Atomのプロンプトを使用
comand+shift+pでAtomのプロンプトを使用して、`Hydrogen:` と入力。
色々な動作が表示されるので、スクロールして、やりたいことを選択すればよい。
<img width="500" alt="スクリーンショット 2020-06-19 20.51.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/742f5d88-1b2c-2b90-b2bf-f17faf231f3f.png">


### 結果の表示場所を用意
ところで、Atom内でPythonを実行する際、そのままだとコード内で結果が表示されてみにくい
<img width="500"  alt="スクリーンショット 2020-06-19 20.49.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/b6835ecf-3679-0b4e-6a86-9b901bd2a084.png">

そこで、`Hydrogen: Toggle Output Area` を選んでおくと結果が表示される場所が別にできる。
こちらの方が見やすそう。
<img width="500
" alt="スクリーンショット 2020-06-19 20.48.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/3e2af40b-6475-978a-f516-43eac06811da.png">

そのほか： `Toggle Watch`
コード本体の方に変数を書き、`Toggle Watches` のサイドバーにグラフを主力するコードを書く。
結果はサイドバーに表示されるが、実行するたびサイドバーのコードは再度実行されなおすらしいので注意が必要？

1回目の出力
<img width="800" alt="スクリーンショット 2020-06-19 21.55.05.p
ng" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/eec581dc-866c-045a-082e-e3fbc671da2d.png">



もう一度4行目を実行すると
<img width="800" alt="スクリーンショット 2020-06-19 21.55.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/c73fb760-876e-286f-0304-85695bda00a1.png">
一回目の出力（はい！2回）をさらに2xしたはい！4回が出力されてしまう。

## キーボードショートカット
### 現在の行を実行
command+return

### 現在の行を実行して次の行に移る
shift+return

### すべて実行する
command+control+return

### 実行結果を消去
command+option+delete

### セルを分ける
コメントにIn[ ]:やを入れて区切る。

### 現在のセルを実行
command+option+return

### 現在のセルを実行して次のセルに移る
shift+option+return

```python:例
# In[]: 
print("hello, World")

# In[]:
print("hello, Japan")

#In[]:
```
Yarn Workspaces を後付けする

# Yarn Workspaces を後付けする

以下のような状況を想定します。

- 既存のワークスペース (Yarn Workspaces 未適用) が存在する
- 既存のワークスペース配下に追加をしたくない (上位ディレクトリなどに追加は大丈夫)
- 追加するワークスペースの内容を別途追加される兄弟ワークスペースが使用するが
    - 兄弟ワークスペースの Node のバージョンが違う・・・
    - でも同じコードを使用したりしたい

## 対応

### 共有する対象のコードの設置

共有するコードを `./src/` と同列の `./packages/` に設置します。
それぞれ配下には `package.json` を設置して `name` に `node_modules/` に格納される名前を指定します。

### Yarn Workspaces の設定

既存のパスを `packages` への指定にしつつ、追加のワークスペースを `./src/packages/` に設置します。

```json:package.json
{
  ・・・
  "workspaces": {
    "packages": [
      "./",
      "./src/packages/*"
    ]
  },
  ・・・
}
```

- 既存のパスを `"./"` にて指定
- 追加するワークスペースを `"./src/packages/*"` に指定

### `./src/packages/` に指定した内容を用意

`./packages/` に用意した内容をシンボリックリンクにより `./src/packages/` として設置します。

```bash:set-symbolic-link-packages
cd ./src
ln -s ../packages/ packages
```

「既存コードに変更を行いたくない」に反するような気がしますが、
まあ適当に空いている構造に設置するということで・・・

### `yarn install`

これによりこれまで通りのパスで `yarn install` を行うと、
`./src/packages/` に設置した内容が `node_modules/` に反映されました。

・・・もっといい方法があるかもですが。

## Yarn Workspaces の使用で Firebase に functions がアップロードできない場合

上記までのものを使用して Firebase の functions をアップロードしたところ、
Yarn Workspaces として設定した対象が `module not found` として解決できない事象に遭遇しました。

なんとか動かした対応として、

- シンボリックリンクでなくファイルのコピーに変更
- **Yarn Workspaces の指定を解除**
    - `package.json` を前述までの `workspaces` の記述を削除
    - `@test/` (仮) が `node_modules/@test/` に紐づいていたところを、  
      `@test/` を `src/packages/` に紐づけ直し
        - webpack.config.js
        - tsconfig.json
- `@test/` 配下で `dependencies` の指定があれば使用側の `package.json` に追加
かつて見たびっくりクソ コード

# 概要
@rana_kualu さんの記事に触発されて、
自分が今まで見かけたなかでもヤバめのクソ コードについて書いてみる。

(元記事)
・これまで見た中で最も汚いソースコード - Qiita
https://qiita.com/rana_kualu/items/2f3c40642836c11f5ddc

# クソ コード
## ① typedef
```C:再現コード.c
typedef void coid;
typedef void boid;
```
キーボードを見ると [**c**] [**v**] [**b**] が並んでいる。
即ちこれは、 **タイプミスを型名の再定義でカバー** しているというもの。
流石にコレは **プログラムではない**、と思った。

## ② マイナス1万
変数名はとりあえず適当。

```PHP:再現コード.php
$date0 = '20201122'; //画面からYYYYMMDDで文字列が来る
$date1 = $date0 -10000;
$year = substr($date1, 0, 4);
$month = substr($date1, 4, 2);
$day   = substr($date1, 6, 2);
```

なんだこの1万を引いている処理は・・・。
(当時の)同僚が保守中の仕組みからこのコード見つけ、一緒に悩んだ。
日付系処理では1万はキリが悪い。。。
幸いにも書いた輩が隣に居たので直接聞いてみた。

> 1年前を計算している

:thinking::thinking::thinking::thinking::thinking:

:astonished:なるほど！
:rage:書き直せ！:punch_tone2:

幸いにも書いた輩が高校から友人(同級生)だったので、とりあえず殴った。

日付操作は日付操作用の関数がちゃんとあるので、それを使いましょう。
(と言うか、私は静的型畑の人間なので、動的型変換の使い方にも膝が震えた。)

## ③ たこいかぱにっく

```java:再現コード.java
boolean checkNumber (str) {
  boolean isNumber = !NumberUtils.isNumber(str);
  if(isNumber) {
    //エラーメッセージ処理処理
  }
  return !isNumber;
}
```
ツッコミどころ

* 変数名が明らかに嘘をついている
* 結局この関数は、また反転して戻している
* じゃぁそもそも反転していた理由は何？？？

論理値(真偽値)がめちゃくちゃである。

<記載内容を削除しました>

論理値は非常に混乱しやすいので、扱いには本当に注意が必要。
私は、ポジティブな方を真、ネガティブな方を偽になる様に心がけている。


## ④ (追記) includeのチカラ！
[@fujitanozomu さんのサンプルコード](https://qiita.com/libraplanet/items/5fbe7d7d3b4f1906b4ad#comment-c189c5cad7740bbd8258) を見ていてなんとなく思い出したので追記します

```C:再現コード.c
int tbl[] = {
  #include <list.csv>
};
```
こ、、、こんな使い方。。。
コンパイルのプロセスを理解しているからこその荒業！？
って思いました。

プログラミング言語において、マクロ文化は基本悪法になりましたねー・・・。
(一部の機能は後発の言語でも残っていますが)


# 以上
クソコードを書かない様に日々精進したいものです。


# 追記① 2020/06/21(日)
思ったより閲覧数が多くてビビっています。
ちょっと角が立つ部分はプライベートで問題になりそうなので、
一部記載を消しました。


# 追記② 2020/06/21(日)
④を追記しました。
つい思い出してしまったもので(苦笑)
# 追記③ 2020/06/22(日)
@sakuro さんより情報を頂きました。
元々includeされることを想定されているファイル フォーマットがある様です。
・XPM - Wikipedia
https://ja.wikipedia.org/wiki/XPM
XPMはそれ自体がC言語のソースコードの体を成している様です。