OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Piでcronが実行されるが権限に阻まれる場合の対処法


## Raspberry Piでcronが実行されるが権限に阻まれる場合の対処法

RasPiで、自作スクリプトなどの実行をcronに設定した際、以下のエラーに悩まされましたので、報告します。

※なお、全てのコマンドは、管理者権限で実行しています...

```
systemctl status cron

> pam_unix(cron:session): session opened for user root raspi

```


参照先:
[[SOLVED] What would cause constant "(cron:session): session opened/closed for user root" in auth.log][link01]


```
apt install systemd-cron
```

### 結果...
無事実行が確認できました。
補足:
パッと見だが...
実行内容を見たら、cronの内容をコピーして、systemd用の実行に変換して、
指定時間に実行されてるみたいだった...

[link01]:https://www.raspberrypi.org/forums/viewtopic.php?t=255121#p1556892
Tabulatorで文字コードを指定してCSVダウンロード機能を実装する

# 前提条件
http://tabulator.info/ 　⇒ V4.5
https://github.com/polygonplanet/encoding.js

# 参考
https://gist.github.com/somy-jp/593f603c386b49840b52
https://github.com/polygonplanet/encoding.js
https://qiita.com/weal/items/3b3ddfb8157047119554

# 内容
Tabulatorにはダウンロード機能が存在するが
公式には文字コードを指定する方法が見当たらなかったので
備忘録として。

# CSVダウンロード機能
http://tabulator.info/docs/4.5/download#csv
ダウンロード機能はとても簡単。
ボタン押下時のイベントに以下のコードを書けば終わり。

```javascript
table.download("csv", "data.csv");
```

# 実際に問題を再現
試しに実装しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260251/3ff7708c-0eac-f42c-d86d-49e49e70d4ec.png)

ダウンロードすると...
６行目にしっかり文字化けが...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260251/1f81cfcb-8ea4-b44d-d50c-9e760eff84eb.png)

# 解決策

ライブラリの中身を見ていくとdownloadReadyでblobにする処理を自前で書けるみたい。
以下のコードを検索かけると見つかる。

```javascript:tabulator.js
blob = this.table.options.downloadReady.call(this.table, data, blob);
```


ライブラリを追加するのとTabulatorのインスタンス作成時に
downloadReadyの処理を追記

https://github.com/polygonplanet/encoding.js

```html
  <script src="./js/encoding.js"></script>
```

```javascript
    var table = new Tabulator("#example-table", {
      height: 205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
      data: table_data, //assign data to table
      layout: "fitColumns", //fit columns to width of table (optional)
      columns: [ //Define Table Columns
        { title: "Name", field: "name", width: 150 },
        { title: "Age", field: "age", align: "left", formatter: "progress" },
        { title: "Favourite Color", field: "col" },
        { title: "Date Of Birth", field: "dob", sorter: "date", align: "center" },
      ],
      // ここを新規に追記
      downloadReady: function (data, blob) {
        var str_array = Encoding.stringToCode(data);
        var sjis_array = Encoding.convert(str_array, "SJIS", "UNICODE");
        var uint8_array = new Uint8Array(sjis_array);
        var newBlob = new Blob([uint8_array], { type: 'text/csv' });
        return newBlob;
      }
    });
```



これで解決
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260251/473597c2-1ff5-1688-045c-72997b8a0ced.png)
Pythonで文字列の連結を複数行で記述する方法

Pythonで文字列の連結を複数行で記述する方法を確認したところ何パターンかあったので、利用可能な「良いパターン」と実行エラーとなる「駄目なパターン」を整理してみました。

## 良いパターン

- ` \[改行]`の後に文字列

```py
val = 'abcde' \
'12345678'
```

- ` + \[改行]`の後に文字列

```py

val = 'abcde' + \
'12345678'
```

- ` + \[改行]`の後に関数

```py
val = 'abcde' + \
str(12345678)
```

- ` + \[改行]`の後に文字列 `+` 関数

```py
val = 'abcde' + \
'1234' + str(5678)
```

- ` +[改行]`で区切って括弧`()`で囲む。

```py
val = ('abcde' +
'12345678')

# インデントも使えるようになる
val = (
  'abcde' +
  '12345678'
)
```

## 駄目なパターン

- ` \[改行]`の後に関数

```py
val = 'abcde' \
str(12345678)
```

実行がSyntaxErrorとなる。

```shell
{
  "errorMessage": "Syntax error in module 'hoge': invalid syntax (hoge.py, line 2)",
  "errorType": "Runtime.UserCodeSyntaxError",
  "stackTrace": [
    "  File \"hoge.py\" Line 2\n        str(12345678)\n"
  ]
}
```

以上
Sipeed Lichee Zeroを買ったのでとりあえずセットアップしてみた

#Sipeed Lichee Zeroのセットアップ

スイッチサイエンスで小型LinuxボードのLichee Zeroを買っみた。
https://www.switch-science.com/catalog/5704/
セットアップをしようとしたが中国語の公式しか情報が無かったので自分の備忘録の意味もかねてメモ

##まず準備
OSイメージをダウンロード
https://dl.sipeed.com/LICHEE/Zero/Images/dd_img
ここからmindb_dd.tar.gzをダウンロードして展開
Win32DiskImagerでSDカードに書き込み。
イメージファイルは700MB程度だったので余っていて使っていなかった2GBのSDカードを使った。書き込んだままだと残りの1.3GB程度が未使用で空き容量がほとんどないのでパーテーションを拡張する。自分は面倒くさがってUbutuのPCでGParted使って拡張。


##起動
一番ってとり早いのは基板上のマイクロUSBからの給電。
このUSB仮想イーサーネットとして使えるのでPCから給電すれば給電と操作が1本で出来そうだが初期設定だとIPアドレスが未設定なので使えない。
なのでシリアルコンソールでしか操作できないという事でUSB-シリアル変換をUART0とGNDに繋ぐ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599350/b1b3751a-eb2a-46b1-9bc4-936602e4397b.png)

ボードそのままでは繋ぎにくいので自分はピンヘッダをはんだ付けしてブレッドボードに差して繋いだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599350/ccfe8c83-35fa-a534-58fc-c74c8e599a03.png)

ボーレートは115200でいけた。
ユーザーは「root」
デフォルトパスワードは licheepiかtoortoorのどちらかとなっていたが自分はtoortoorの方だった。



今回はここまでにして次回環境を整えよう



##その他
公式ドキュメント:http://zero.lichee.pro/index.html


 
 
 
###続き
[Sipeed Lichee Zeroをネットに繋ぐ](https://qiita.com/17_kitano/items/4eba9cc8e6714838ad57)
Firebase storage Web版（js)の超個人的メモ

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)

## firebase storageって何？
Firebase備え付けの画像保存サービス。
aws S3のfirebase版
s3より簡単


## 画像をアップロードする

画像のアップロードに必要なのは
1. storageへの参照を作成する。
2. blobを作成する
3. putメソッドに、ファイルか、blobを渡す。

```js
const firebase = require('firebase')
const storage = firebase.storage()

// 参照を作成
const storageRef = storage.ref()

const blob = ...

// putメソッドにblobを渡す
storageRef.put(blob)
```

以上！
firebaseコンソールのStorageを見ると、画像がアップロードされている。

## アップロードした画像のurlを取得する	

```js
const imageRef = storageRef.child('image.jpg')
const url =　await imageRef.getDownloadURL()
```
画像urlの取得もとても簡単です。

## 色々な参照の作り方

firebase storageへの参照の作り方。
Images/space.jpgというファイルの参照を作成しよう。

```js
const imagesRef = storageRef.child(‘images’);

const spaceRef = storageRef.child(‘images/space.jpg’)
```

このように階層的にアクセスが可能。

Parentやrootプロパティには、親フォルダや、ルートフォルダへのアクセスが可能

```js
const imagesRef = spaceRef.parent
const rootRef = spaceRef.root
```

また、child, parent, rootはチェインさせて書くことも可能

```js
const earchRef = spaceRef.parent.child(‘earth.jpg’)
const nullRef = spaceRef.root.parent

// fullPath, name, bucketというプロパティがある。

spaceRef.fullPath
spaceRef.name
spaceRef.bucket
```
pip install hogehogeで" ERROR: Command errored out with exit status 1:"と出た時の解決策メモ


Python初心者です。
Pythonの開発環境構築時に ```pip install``` コマンドのエラーでつかえたので、
解決策をメモとして残します。


## 起こったこと

- テキストファイルにインストールしたいライブラリを列挙し、ローカル環境でpip installをしようとした(下記リンク(1)参照)ところ、wordcloudというライブラリのインストーリング中に以下のエラーが出力された。

```
C:\Python\Python38 >>  pip install -r requirements.txt
>>
(中略)   
ERROR: Command errored out with exit status 1:
(中略)
ERROR: Command errored out with exit status 1: 'c:\python\python38\python.exe' -u -c 'import sys, setuptools, tokenize; 
sys.argv[0] = '"'"'C:\\Users\\わたし\\AppData\\Local\\Temp\\pip-install-dm1mwd6_\\wordcloud\\setup.py'"'"'; 
__file__='"'"'C:\\Users\\わたし\\AppData\\Local\\Temp\\pip-install-dm1mwd6_\\wordcloud\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', 
open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\わたし\AppData\Local\Temp\pip-record-20xrbjk9\install-record.txt' --single-version-externally-managed --compile Check the logs for full command output.


```

 

- ```pip install wordcloud``` を試しても同じエラー文が吐き出され、状況変わらず

## 取り組んだこと
- エラー文がナンノコッチャよくわからなかったので、同様に困っている人がいたのではと調べたところ、やっぱりいた(下記リンク(2)参照)


## 解決策
- インストールができなかったライブラリのwheelファイル(.whl)というものを、下記リンク3からダウンロードする
    - Pythonのライブラリが配布される時に用いられるファイルの拡張子だそうです(要確認)
    - 例：wordcloud-1.6.0-cp38-cp38-win_amd64.whl
- Pythonを管理しているフォルダに移動させる
    - (私の場合、C:\Python\Python38でした)
- そのフォルダにて、```pip install hogehoge.whl``` を実行してインストールする
- (今回の私の場合、テキストファイルに記述されていたwordcloudの部分をコメントアウトし、 ```pip install -r requirements.txt``` を再度実行して完了した。)


## リンク集
- [(1) 【windows10】Python3.7をインストールしてpathを通して、pipでパッケージを入れる] (https://karupoimou.hatenablog.com/entry/2019/04/29/064646)
- [(2) Failed building wheel for wordcloud #105](https://github.com/amueller/word_cloud/issues/105)
- [(3) Unofficial Windows Binaries for Python Extension Packages](https://www.lfd.uci.edu/~gohlke/pythonlibs/)
ALB or ACLで特定IPのブロック


# なにこれ？
AWS上で稼働するWEBサービスへ特定のIPからのアクセスを遮断したい。
調べたことをメモとして記事にします。

# どうする？
選択肢としては

- ALBで特定のIPからのアクセスの場合は固定レスポンスを返す
- ネットワークACLでVPCに来たらその先に通さずにブロックする



## ALB編

### やること
1. アクセスをブロックしたいALBのルールを開く
2. 送信元IPが特定IPだった場合に固定レスポンスを返す設定を追加
![alb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142518/2af18f57-7a4b-b923-57b7-30925e42f521.png)


### 注意点

ALBは上から順番に評価されるので、攻撃ブロック時の設定は必ず1番目に設定しましょう

## ネットワーク ACL編

VPCの設定で特定IPを拒否することも出来る
ここで拒否をすると宛先サーバが見つからなかったと表示される
ACLでブロックされると↓のような画面が表示される
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142518/a1814bc3-22fc-f415-e2a3-1d0fce3595a4.png)


### やること
1. VPCダッシュボード->左メニューから「ネットワーク ACL」を選択
2. 到達させたくないVPCを選択
3. インバウンドルールにブロックする設定を追加
    1. ルール#: `99以下`
    2. タイプ: すべてのトラフィック
    3. 送信元: ブロックしたいIP
    4. 許可/拒否: `DENY`

![acl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142518/8ecfa26a-1e66-2bb5-ce2c-d4b94dac3fdb.png)

この設定でアクセス拒否が出来ます

### 注意点
- ルール番号が若い順に評価されているので、かならず99以下に設定する必要がある
- ブロックしたいので `DENY` を選択


# 参考記事

[AWS環境で特定IPからのアクセスを拒否する](https://blog.e2info.co.jp/2020/01/10/aws-ip-networkacl/)
[Ruby]Enumの値を１つのキーに対し複数持たせる方と特定キーの値のみ全取得する方法

# はじめに
## この記事について
RubyでEnumのキーに対して複数の値を持たせる記述方法が分からず、個人的に苦戦しましたので備忘録として残しておきます。
また、複数持たせた値をRailsのValidatesの `in` に利用する(`特定のキーの値のみ全取得する`)方法も不明でしたがわかりましたので、併せて書きます。

## 筆者実行環境
- ruby 2.6.3
- rails 6.0.2

# やりたかった事
例えば、給料を表すEnumがあったとして、以下の要件を満たす必要があります。

要件：キー１つに対し、複数のバリューを持たせる。

- Key
    - 役職
- Value
    - 毎月の給与
    - ボーナス

また、API開発などで、ラジオボタンやセレクトボックスに特定の業務用の種別を持たせ、選択させリクエストされた文字列や値が、サーバー側で想定している定義値と合っているかを確認することがあった場合に `in` で利用できないと困るので、試行錯誤してみました

# で、どうやんの？
以下でいけました
※金額は適当です :smile:

### 定義方法
```ruby
  enum salary: { shinjin: {base: 160000, bonus: 200000},
                 ippan: {base: 200000, bonus: 400000},
                 butyo: : {base: 400000, bonus: 800000} }
```

### 使う時
inspectで見たところ、定義時と同様で中身はハッシュのハッシュになっているようなので、以下の要領で取得しないといけないようです

```ruby
salary[:shinjin][:base] # 160000が返却される
```

### validetesの `in` に利用する方法
前述したように単一のものであればEnumはハッシュのハッシュであるため `salary[:shinjin][:base]` で取得ができましたので、純粋に `salary.map { |s| s[:base] }` としてあげれば `[160000, 200000, 4000000]` として取得ができると思い込んでいたのですが、mapで展開すると `s` は `["shinjin", {"base"=>160000, "bonus"=>200000"}]` と内部的にはなっているようで、mapし終えた後は通常通りの取得方法では取れないようなので、以下のようにすれば取得できます。
型の異なる二次元配列になっているになっているため、 `s` の1番目はKeyで2番目は複数の値をもったハッシュである。ということですね。

```ruby
  # s[1][:base]で [160000, 200000, 4000000] が取得でき、inに対応できる
  validates :salary, inclusion: { in: salary.map { |s| s[1][:base] } }, if: Proc.new { |f| f.salary.present? } 
```


# (おまけ)他の言語での複数Enum値の書き方と使い方
筆者はJavaやSwiftをやっているので、この記事に辿りついた方がどちらかの言語習得者で私と同じ境遇であった場合に役立つように、今回のケースと同じことをJavaとSwiftで表現します(その逆もしかり)

## Java
Javaは定義順(コンストラクタのArg順?)で列に対応するフィールドが決定されるので、以下の書き方ができます。

### 定義方法

```java
public enum Salary {
    SHINJIN(160000, 200000),
    IPPAN(250000, 400000),
    BUTYO(400000, 800000),
    ;

    private final int base;
    private final int bonus;

    private Type(final int base, final int bonus) {
       this.base = base;
       this.bonus = bonus;
    }

    public String getBase() {
        return this.base;
    }

    public int getBonus() {
        return this.bonus;
    }
}
```

### 使う時
```java
Salary.SHINJIN.base // 160000が返却される
```

## Swift
Swiftはいろいろな書き方があるようですが、computed propertyで定義する

### 定義方法
```swift
enum Salary: Int {

  case shinjin
  case ippan
  case butyo

  var base: Int {
    switch self {
    case .shinjin:
        return 160_000
    case .ippan:
        return 250_000
    case .butyo:
        return 400_000
    }
  }

  var bonus: Int {
    switch self {
    case .shinjin:
        return 200_000
    case .ippan:
        return 400_000
    case .butyo:
        return 800_000
    }
  }

}
```

### 使う時
(javaと同じ)

```swift
Salary.shinjin.base // 160000が返却される
```

# 最後に
いかがでしたでしょうか。同じような境遇にある方の助けに少しでもなればと思います。
また、私はRubyとRails初心者なので、もっといい書き方や理解が足りていないことがあれば教えていただきたいです。

# 参考文献
[rbenvでrubyのバージョンを管理する
](https://qiita.com/ozackiee/items/17b91e26fad58e147f2e)
OCP 4.3をお弁当箱に全自動インストールする - 1. 概要編

**1. 概要編（本記事）**
[2. 準備編①- ESXiインストールメディアの作成]()
[3. 準備編②- CentOS自動インストールメディアの作成](https://qiita.com/hmiyakoshi0803/items/e5b1786d96010f9a172d)
[4. NUC構築編](https://qiita.com/hmiyakoshi0803/items/0bbbfce6b9411ac16c79)
[5. ESXiインストール編]()
[6. ESXi Virtual Network構築編]()
[7. VCSA構築編]()
[8. 踏み台サーバ構築編① - VM構築]()
[9. 踏み台サーバ構築編② - ミドルウェア構築]()
[10. 踏み台サーバ構築編③ - MatchBox構築]()
[11. OCP4.3 インストール編]()

# はじめに
- 昨年くらいから、Openshiftをよく使うようになり自前の検証環境が欲しくなった
- Openshiftは結構マシンリソースを使うため、クラウド上に立てるとコストが辛い。。。
- 思い切って自宅サーバを構築しようと思い立ち、小型でお手軽なIntel NUCをポチった

# 小型のお弁当箱（Intel NUC）とは
- Intelが作ってる小型のサーバ（正式名称: Next Unit of Computing）のこと
- 小型ながら、メモリやSSD拡張して、それなりのスペックにできるため、検証用途としては申し分無し
- 手の平サイズのため、自宅に設置しても場所に困らない。デモする際にカバンに入れて持ち運びもできる
- 写真の比較対象はiphone 7の小さい方 （~~微妙にうちの本棚が写ってるw~~）
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_245534_8f88e4d6-b102-17f3-c074-c8a00dd133de.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245534/8591aee0-dd0e-6cba-dc70-896820c9d23c.jpeg)


# こだわりポイント
- 全てトライアルライセンスで動かしているため、期間が過ぎたら簡単に作り直せるように徹底的に自動化
- Ansibleはもちろん、Kick StartやPXE bootも活用
- NUCにESXiをインストールしてSSHを有効化したら、そこから先はAnsibleが全てやってくれる


# 環境構成概要
## Software stack
- NUCにESXiをインストールし、その上にRHCOS VMを構築しOpenShiftをインストールしている
- OpneShiftと外部NWを通信させるためのjumpboxを構築している
- VMware関連の自動構築を行うためにVCSA (vCenter Server Appliance）を構築している
![OCP4.3_software_stack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245534/67226a3d-ad3a-ea16-b826-870de606bbcb.png)


## システム構成図
- NUCには物理NICが一つしか無いため、ExternalとInternalのNWを構築し、External側に物理NICを割り当てる
- JumpBoxサーバを構築しExternalとInternalをNATさせる
- Openshiftの各ノードはJumpBox経由で外部と通信可能なように構成する
![system_arc_diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245534/d0354992-5969-c456-0f6b-c8591c9cf40d.png)


# 手順概要
- かなり長い手順となるため、下記の通りいくつかに記事を分割して記載予定
- 大部分がOCP４.３インストールに入る前の準備の手順となる

**1. 概要編（本記事）**
[2. 準備編①- ESXiインストールメディアの作成]()
[3. 準備編②- CentOS自動インストールメディアの作成](https://qiita.com/hmiyakoshi0803/items/e5b1786d96010f9a172d)
[4. NUC構築編]()
[5. ESXiインストール編]()
[6. ESXi Virtual Network構築編]()
[7. VCSA構築編]()
[8. 踏み台サーバ構築編① - VM構築]()
[9. 踏み台サーバ構築編② - ミドルウェア構築]()
[10. 踏み台サーバ構築編③ - MatchBox構築]()
[11. OCP4.3 インストール編]()
GoのEchoを自動リフレッシュしてくれるスクリプト

# はじめに
GoのEchoを少し触っていて、Flaskのように変更適用時に自動でリフレッシュしてくれる機能があれば便利だなと思いました。特に、ソースコードに影響を及ぼさずに外部から環境を構築することが、ミスを減らすために重要だと感じ、シェルスクリプトを書きました。コイツは、カレント以下の変更を検知するようにしてあるので、`./module/`等の変更にも対応してくれます。

まあまあ便利なものができたなと思っているので、よかったら使ってみてください。

# 実行環境
`fswatch`を使います。

```bash:
# Mac
$ brew install fswatch
# Ubuntu
$ sudo apt install fswatch
```

# シェルスクリプト 
`Makefile`で`make run`を設定していれば、当スクリプトを同一ディレクトリに配置してそのまま実行すると良いです。

```bash:autoreloader.sh
#!/bin/bash

function cleanup()
{
	app_pid=`/bin/ps -fu $USER| grep "make run" | grep -v "grep" | awk '{print $2}'`
	if [[ ${#app_pid} != 0 ]]
	then
		kill ${app_pid}
	fi
}
trap cleanup EXIT

while :;
do
	make
	make run &
	app_pid=`/bin/ps -fu $USER| grep "make run" | grep -v "grep" | awk '{print $2}'`
	fswatch_result=$(fswatch -1 .)
	kill ${app_pid}
done
```
Python 画像を分割し横に並べる

## 背景
数独アプリを作成しています。
その途中のプロセスで何となく、画像を分割して、横に並べてみたいなっておもい、ググりながら作成しました。
誰かの参考になると幸いです。


##サンプルコード

```Python:split_img_and_layout_Horizontally.py
import numpy as np
import cv2

# 入力画像を読み込み
img = cv2.imread("sudoku_wiki.png")
#wiki https://en.wikipedia.org/wiki/Sudoku

#分割サイズを定義
vertical_split = 9
horizonal_split = 9

#リサイズを指定
size = (vertical_split * 200, horizonal_split * 200)
img = cv2.resize(img, size)

#リストの初期化
split_img = []

#縦と横に分割
[split_img.extend(np.hsplit(img, horizonal_split)) for img in np.vsplit(img, vertical_split)]

#分割した画像群を横に配列
img_list = [split_img[i] for i in range(len(split_img))]
merge_img = cv2.hconcat(img_list)

#画像を保存
cv2.imwrite('merge_img.jpg', merge_img)
```

##実行結果

対象画像：sudoku_wiki.png

![sudoku_wiki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503403/e3ceea5c-854c-f94c-8d13-797259a4ef77.png)


実行結果：merge_img.jpg
見づらいので、拡大してみてください。。。
![merge_img.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503403/c9d63837-54b9-194a-5809-c7fa5ba9a12c.jpeg)

## 更なる改善点
・数字との境界線を消すと見やすくなる
→直線検出をし、白塗り

・数字の画像からで文字列化
→MNIST(機械学習)を取り入れる

それぞれ取り組んだんですが、あまり良くない精度だったので、
改善でき次第、載せられたらいいかな。
[scss]mixin実はよくわかってなかった件。わかると便利。使い方は？ 初心者

## Mixinとは？
ざっくりお伝えすると、書き方の注意は２つ
***①***
***＠mixinで定義を決める***
「＠mixin　`panda`（好きな名前）{color:red;みたいな定義}」で書く

***＠mixinのscss当てる***
「当てたいクラス名{＠include　`panda`(mixinと同じ名前じゃ無いとダメ)；}」
これで＠mixinで書いた定義がまるまるこのクラスに反映されます。

***②***
Mixinをかくときはあちこちに＠mixinを書くのではなく`「_mixin.scss」`を作り
その中にまとめてapplicationに＠importをされた方が管理しやすいかと思います。

ちなみにですが***mixinを当てたいページより上にmixinのファイルを＠importする***だけで下のscssファイルでは`＠include`が当たるようになります

## 例文
こちらはわかりやすいように同じページに「mixin」と「include」を記述しますね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/f23ab4a9-4bfd-cbef-5f88-bdd8a9324516.png)

```scss:_mixin.scss(例)
// items/new.html
// 商品出品ページ
@mixin dropzone{
  background-color:#f5f5f5;
  border: dashed 1px #ccc;
  color:#333;
  vertical-align: middle;
  padding: 20px;
  cursor: pointer;
  padding: 40px;
  position: relative;
  text-align: center;
  width: 100%;
  margin: 0 10px 0 auto;
  }
// 画像詳細ページ
@mixin item{
  width: 60px;
  height: 60px;
  img{
    width: 60px;
    height: 60px;
    }
}
```

```scss:_item-up-to.scss(例)
.dropzone-area{
  @include dropzone;
//必ず末尾にセミコロン『；』を忘れないように気をつけてください
  p{
    cursor: pointer;
  }
}
//中略
.box-photo{
      box-sizing: border-box;
      width: 300px;
      height: 420px;
      margin-right: 20px;
      &__photo{
        width: 300px;
        height: 420px;
        font-size: 0;
        img:nth-child(1){
          width: 300px;
          height: 300px;
        }
        img{
        @include item;
        }
      }
    }
```
＠include終わりの
`セミコロン(;)こんなやつ`すごい大事！！

## 参照ぺージ 
[クリエイターボックス](https://www.webcreatorbox.com/tech/sass-mixin)
[Sassで@mixinを作る時に知っておきたい基礎知識](https://qiita.com/nekoneko-wanwan/items/c8498a21ae0e2b2198be)

[アンパサンド＆もわかると便利よね](https://qiita.com/noqua/items/adc24c28c13e9b74d3ad)

## 終わりに
本当の初心者が真似っこでできるのを目指して書きました。
参照ページ載せますが、記述方法プラスOverwriteしたりと
もっともっと便利なサイトはございますので、慣れましたらぜひご活用ください。
mixin以外の定義方法が参照ページには載ってますが
定義となる部分範囲が異なっていたり、ケースバイケースで
より効率の良い使い方の実例となっておりますので
一緒に学んでいけたらと存じます。

わたくし自身初学者のため
、不備やアドバイス等がございましたらご指摘いただけますと、これ喜びわっしょいでございますので、どうぞよろしくお願いいたします。
最後までご覧いただき

ありがとうございます。
あたまのなかの整理メモ(Java - 例外編)

## My Java環境
* Java11

## `try-catch-finally`

* `try-catch-finally`の順で記載する。`catch句`はなくてもOK。
* `try句`と`finally句`は1つずつしか記載できない。`catch句`は複数書ける。
* `catch句`と`finally句`の両方に`return文`を書いた場合の例↓

```java

public class Test {
    public static void main(String... args) {
        System.out.println(getException());
    }

    private static String getException() {
        try {
            throw new Exception();
        } catch (Exception e) {
            return "catch!";
        } finally {
            return "finally!";
        }
    }
}
```

実行結果は

```
finally!
```

## 例外クラス

* 継承関係

```
Throwable
        -> Error
        -> Exception
            -> RuntimeException
```

### `Error`

* プログラムでは対処できない事象
* サブクラスに`StackOverFlow`などがある
* エラーに分類されるには`Error`を継承していること
* `try-catch`と`throws`は強制されない、書くことはできる

### `Exception`と`RuntimeException`

* プログラムが対処できる事象

#### `Exception`

* 検査例外
 * 例外処理を記述したかをコンパイラが検査する
 * `RuntimeException`とそのサブクラスを除く
 * `try-catch`しているか、`throws`しているかどちらかを強制する

#### `RuntimeException`

* 非検査例外
 * 例外処理を記述したかをコンパイラが検査しない
 * `try-catch`と`throws`は強制されない、書くことはできる
Node.js を完全にアンインストールする

過去に [Mac nodebrew で Node.js をインストールする手順](https://qiita.com/ucan-lab/items/517ee13a2f8769ab866c) の記事を書きました。

現在の私の環境では[nodebrew](https://github.com/hokaccha/nodebrew)は削除して、[Node.js](https://nodejs.org/ja)は[nodenv](https://github.com/nodenv/nodenv)で管理し、nodenvは[anyenv](https://github.com/anyenv/anyenv)で管理してます。

追記: 記事書きました。

https://qiita.com/ucan-lab/items/ce35bcaf2562054917a8

追記: さらに記事書きました。

https://qiita.com/ucan-lab/items/0b854cfaa9d7c8ede106

## グローバルパッケージの確認

削除前に再インストールしたいパッケージがあれば確認しておく。

```
$ npm ls -g
```

## アンインストール手順

```
$ brew uninstall nodebrew
```

```
$ curl -o uninstall-node.sh https://gist.githubusercontent.com/nicerobot/2697848/raw/uninstall-node.sh
$ chmod u+x uninstall-node.sh 
$ ./uninstall-node.sh 
  空Enter でアンインストール処理を進める
$ rm uninstall-node.sh
```

この辺のディレクトリもあったら消す

```
$ sudo rm -rf /usr/local/include/node
$ sudo rm -rf /usr/local/lib/dtrace
$ rm -rf ~/.node-gyp
$ rm -rf ~/.npm
$ rm -rf ~/.sourcemint 
```

```
$ which node
/usr/local/lib/node

$ rm -rf /usr/local/lib/node
```

```
# 診断コマンドを実行
$ brew doctor

# 必要に応じて...
$ brew prune
$ brew cleanup
```

## anyenv のインストール方法

別記事にまとめています。
[Mac を買ったら必ずやっておきたい初期設定](https://qiita.com/ucan-lab/items/c1a12c20c878d6fb1e21#anyenv)
普段kerasしか使わない人のためのtf.Tensorの値の確認の仕方

kerasでlabel_smoothingを試そうと思って調べたらtf.keras.losses.categorical_crossentropy(y_true, y_pred, label_smoothing=0)と引数に用意されていて、簡単に実装できるようになってました。
この場合自作関数で渡すのですが、「実際のところこれってどう動作してるんだ」とちょっと確かめてみたところ、Tensorで出力されて普段kerasしか使わない身としてはどう値を確認すればいいかすぐにはわからなかったのでその時のメモです。

#自作損失関数について
自作の損失関数は(y_true, y_pred)を受け取って値を返す処理を作ればいいだけです。

```python
import tensorflow as tf

#普通の'categorical_crossentropy'はこの動作
def normal_cross_entropy(y_true, y_pred):
    loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred, label_smoothing=0)
    return loss

#smooth labeling、0/1じゃなくて正解以外の分類にもわずかに確率を与えるようにする。
def smooth_label(y_true, y_pred):
    loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred, label_smoothing=0.1)
    return loss
```
こんな感じです。そんな難しくないでしょう。

#出力を確認する
これに単純に結果を入れても

```python
true = [[0, 0, 0, 1], [0, 0, 0, 1]]
ans = [[0, 0.01, 0, 0.99], [0, 0.1, 0, 0.9]]
print(smooth_label(tt, ans))
# Tensor("Neg_1:0", shape=(3,), dtype=float32)
# 値がわからない！
```

となって値を確認したくてもできません。なのでtensorflowで値をSessionする必要があります。

```python
tt = [[0, 0, 0, 1], [0, 0, 0, 1]]
ans = [[0, 0.01, 0, 0.99], [0.04, 0.03, 0.03, 0.9]]
with tf.Session() as sess:
    print(sess.run(normal_cross_entropy(tt, ans)))
    print(sess.run(smooth_label(tt, ans)))
# [0.01005033 0.10536055]
# [0.93033063 0.3532583 ]
```
こんな感じですね。sess.runが必要なだけでわりかし単純。
0.99と当てるより0.9と当ててほかは平均的にしたほうがlossは低くなります。
これが学習の上でホントにいいかというのはまた別の話。

#まとめ
まあ普通にSessionでrunすればいいということだけですが、基本kerasしか使わない身としてはtensorflowはハードル高くて気後れします。
ちなみにmixup,cutmixみたいな教師データを0,1以外にするとどうなんだろうと試したらちょっと不思議な結果でした。normalの方でもぴったり当ててるのにそんなにlossが小さくない・・・何でだ？

```python
tt = [[0, 0.2, 0, 0.8], [0, 0.2, 0, 0.8], [0, 0.2, 0, 0.8]]
ans = [[0, 0.3, 0, 0.7], [0, 0.2, 0, 0.8], [0, 0.1, 0, 0.9]]
with tf.Session() as sess:
    print(sess.run(normal_cross_entropy(tt, ans)))
    print(sess.run(smooth_label(tt, ans)))
#[0.52613455 0.5004024  0.54480547]
#[1.3184421 1.3020815 1.3564284]
```

softmax_cross_entropy_with_logits_v2_helperあたりまでは辿ったけどよくわからなかったので、ちょっと保留。
FlutterでAPIリクエストを行う（初心者向け）

最近ネイティブアプリに興味が湧いてきたのでFlutterを触りはじめました。

今回はFlutterでAPIリクエストの実装例を紹介します。
基本的に以下のドキュメントを読めば実装できるのですが、複数件取得の場合の例がのってなかったので私同様、初心者の方に参考になればと思います。
https://flutter.dev/docs/cookbook/networking/fetch-data

## 対象のAPI

キャッシュレス店舗情報が取得できるAPIです。
`https://api.cashless.go.jp/location/xn7/6uq.json`

```
// エンコードされたデータ
{"13872":{"id":13872,"name":"\u30ab\u30e9\u30aa\u30b1\uff2f\uff2e\uff25\u9280\u5ea7\u5e97","addr":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a\u6709\u697d\u753a\uff11\u4e01\u76ee\uff12\uff0d\uff11\uff11\u3000\u30aa\u30fc\u30ad\u30c3\u30c9\u30b9\u30af\u30a8\u30a2\u30d3\u30eb\uff14\u3001\uff15\uff26","lat":35.6726177,"lng":139.7600767,"tel":"03-5510-1181","category":"115"},"29892":...

// デコードされたデータ
{13872: {id: 13872, name: カラオケＯＮＥ銀座店, addr: 東京都千代田区有楽町１丁目２－１１　オーキッドスクエアビル４、５Ｆ, lat: 35.6726177, lng: 139.7600767, tel: 03-5510-1181, category: 115}, 29892:...
```

## モデルを作成

とりあえずlib/modelsにsotre.dartを作成しました。

``` lib/models/store.dart
class Store {
  final String id;
  final String name;
  final int addr;
  final double lat;
  final double lng;
  final String tel;
  final String category;

  Store({
    this.id,
    this.name,
    this.addr,
    this.lat,
    this.lng,
    this.tel,
    this.category
  });

  factory Store.fromJson(Map<String, dynamic> json) {
    return Store(
      id: json['id'],
      name: json['title'],
      addr: json['title'],
      lat: json['lat'],
      lng: json['lng'],
      tel: json['tel'],
      category: json['category'],
    );
  }
}
```

Dartでよく使うBuilt-in typesです。（TypeScriptから頭を切り替える時に混乱するので自分用メモ）

|タイプ |表記  |
|---|---|
|数値  |int, double  |
|文字列  |String  |
|真偽  |bool  |
|配列  |List  |
|セット  |Set  |
|Key/Value  |Map  |

## JSONをデコード

``` main.dart
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert' show json;
@JsonSerializable()
...
Future<List<Store>> fetchStores() async {
  final response = await http.get('https://api.cashless.go.jp/location/xn7/6uq.json');
  if (response.statusCode == 200) {
    Map<String, dynamic> decodedJson = json.decode(response.body);
  }
  ...
```

JSONをデコードするだけなのにimportするものが多いと感じましたが、こういうものなんでしょう。

## モデルのリストを返す

デコードしたJSONの型が`Map<String, dynamic>`なので`forEach`で回し、モデルのリストを生成して返しました。

``` main.dart
import 'dart:async';
import 'package:http/http.dart' as http;
import 'models/store.dart';
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert' show json;
@JsonSerializable()

...

Future<List<Store>> fetchStores() async {
  final response = await http.get('https://api.cashless.go.jp/location/xn7/6uq.json');
  if (response.statusCode == 200) {
    List<Store> stores = [];
    print(response.body);
    Map<String, dynamic> decodedJson = json.decode(response.body);
    decodedJson.forEach((key, value) => 
      stores.add(Store.fromJson(decodedJson[key]))
    );
    return stores;
  } else {
    throw Exception('Failed to load album');
  }
}
```

期待通りの結果が返ってきてますね。

``` main.dart
_stores = await fetchStores();
print(_stores);

> [Instance of 'Store', Instance of 'Store', ...]
```

以上です。
競技プログラミング用の自動実行環境つくった

# はじめに
競技プログラミングを、データ構造とアルゴリズムの勉強のためにやろうと思っていて、最近は開発ツールの開発に精神を持っていかれてしまいました。まあまあ使いやすいものになったので、よかったら使ってみてください（改善点等あれば是非教えてください！）。[こちら](https://qiita.com/ysuzuki19/items/b817ecaa780595502d10)に掲載したテストスクリプトと組み合わせることで、自動テストスクリプトとなります。その内１つのページにまとめるかもしれません。

# 環境構築
ファイル更新検知のために`fswatch`というコマンドを用いる。

```bash:environment
# Mac
  $ brew install fswatch
# Ubuntu
  $ sudo apt install fswatch
```


# 組み合わせたもの
スクリプト実行ディレクトリに`test.sh`を配置することで、ファイル更新時に自動で入力をテストしてくれる。また、正解データと出力を上下に並べて表示するため、簡単に正解かどうか確認することができる。

```bash:autoreloader.sh
#!/bin/bash
while :;
do
	./test.sh
	res=$(fswatch -1 . >/dev/null)
done
```

# 自動コンパイル実行だけを使用したい方向け
`test.sh`に関係なく自動更新する場合は、以下のようにコンパイルコマンドと実行コマンドを記述することで自動実行できる。

```bash:autoreloader.sh
#!/bin/bash
while :;
do
  g++ -o main.out main.cpp
  ./main.out
  res=$(fswatch -1 . >/dev/null)
done
```
GAN入門(1)〜GANとは〜

# はじめに
最近、業務GANの一種を応用するニーズが出てきた。
せっかくだからGANについての知識をきちんと整理しようと思い、最終的にはNLPや音声認識に応用することを目標にGANについて学習・実装していこうという試み。
今回はざっくりと知識の整理をしてみる。
実装編は次回からしていく。


# GANについて基礎知識
敵対的生成ネットワークのこと。
細かいところは割愛するが、AI関係のいろんなフィールドでかなり期待されているらしい。

生成器(Generator)と識別器(Discriminator)からなるNNのモデル。
生成器と識別器が競争的に学習する。

- 生成器
より識別器を騙せるような本物っぽいデータを生成するように学習
乱数ベクトルzを入力とする

- 識別器
生成器からくるデータをより正確に見分けられるように学習
本物サンプル(訓練データ)と偽物サンプル(生成器から生成された)を入力とする

学習プロセスにおいて、ナッシュ均衡状態という以下のような均衡状態にたどり着くまで学習する。

- 本物と偽物のサンプルが見分けがつかなくなる
- 識別器の正答率が50%になる


## GANにおける損失関数
通常のNNとGANの大きな違い。
GANでは識別器と生成器で異なる損失関数を持つ。
生成器の損失には識別器のパラメータも寄与しているが、生成器の学習においては生成器のパラメータしか更新できない。(逆も然り)
識別器と生成器で対立する目標に向かってナッシュ均衡まで学習していく。

# まとめ
GANについてまとめてみた。
実装がないとピンとこないので、次回からpytorchを使っていろんなGANを実装していこうと思う。
Alloyでパズル (8) 石取りゲーム（別解）

発想を変えて、`util/ordering`を使わずにやってみよう。
今度はプレイヤーの行動ではなく、取られた石の方に着目する。

# 考え方

ゲーム終了時、各石にはどのターンで取られたかが記されていることにする。

```alloy
sig Stone { taken: Int }
```

石に記されたターンの一覧は`Stone.taken`や`taken[univ]`で得られる。

```alloy
let turns = Stone.taken
```

パスはできないので、`turns`で得られる結果は`(1+2+3+...n)`と決着ターンまですべて含んでいるはず。
Int についてはこれまで使ってきた`min`, `max`の他に、[ソース](https://github.com/AlloyTools/models/blob/master/utilities/types/integer.als) を見るとわかるように `next`, `prev`, `nexts`, `prevs` といった便利関数が使える。
対象数未満をすべて含む集合`prevs[Int]`を使うと、上の内容はこう表せる。

```alloy
fact { turns = prevs[(#turns).next] - prevs[1] }
```

# リスト

結果が見やすいように、パラメータと結果を`Game`にまとめた。

```alloy
// 石取りゲーム（別解）

// 石には何ターン目で取られたかが記される (1〜)
sig Stone { taken: Int }

one sig Game {
    players: 3,     // 参加者数
    minTake: 1,     // 一度に取れる最少石数
    maxTake: 3,     // 一度に取れる最多石数
    turn: Int,      // 結果： 何ターンで決着したか
    winner: Int     // 結果： 勝ったのはどちらか (1..players)
} {
    turn = #turns
    winner = turns.max.player
}

// ターン一覧
let turns = Stone.taken

// ターンプレイヤー (1〜Game.players)
let player[turn] = turn.prev.rem[Game.players].next

fact {
    // パス不可： turnsには 1～最終ターンまで全て含まれる
    turns = prevs[(#turns).next] - prevs[1]

    // １ターンに取れる石の数
    all t:turns | (Game.minTake =< #taken.t) && (#taken.t =< Game.maxTake)
}

run {} for 6 int, exactly 9 Stone


// 勝ちパターンを狙う取り方
fun takeToWin[turn:Int] : Int {
    let leftStone = #(Stone - taken.(prevs[turn])) |
        max[ Game.minTake + leftStone.rem[Game.minTake+Game.maxTake] ]
}

// 先手は勝ちパターンを狙う
pred p1WantsToWin {
    all t:turns | t.player=1 => #taken.t = takeToWin[t]
}
run p1WantsToWin for 6 int, exactly 29 Stone

// 「先手必勝」を崩せるか
check { p1WantsToWin => Game.winner=1 } for 6 int, exactly 29 Stone
```

# 結果
（９石、３人、考えない例）
　　<img width="384" alt="スクリーンショット 2020-03-09 0.44.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20005/f44b81cb-842a-1ef4-8a69-e2e366b52cd1.png">

# 補足：`+`,`-`の誤用について

`leftStone.rem[Game.minTake+Game.maxTake]`の場合`rem[]`の引数だから`+`は整数加算なのかと思うかもしれないが、実は違う
ここでの`+`も集合の和である
いったん２要素の集合になった上で、暗黙に`sum[]`で合計値が求められている

> 通常の算術演算式は以下の組み込み関数を使って、関数適用の構文（すなわちボックス演算子またはドット演算子）で構成される。
　plus [a,b] aとbの和を返す
　minus [a,b] aとbの差を返す
　mul [a,b] aとbの積を返す
　div [a,b] aをbで割った結果を返す
　rem [a,b] aをbで割った剰余を返す
これらの関数の引数に対してはsum関数が暗黙に適用される。

Evaluator で確認してみよう
`rem[]`の引数だから`+`, `-`が算術演算になるのなら、`rem[5, 1+3] = 1`, `rem[5, 3-1] = 3`になるはずだ。
　　<img width="108" alt="plusminus.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20005/2877b1a0-8ccc-5982-8d91-d2edec8c5254.png">
`+`の方は`1+3 = {1,3}`のため**たまたま**整数加算と同じ結果になっているが、`-`の方は`3-1 = {3}`であるため整数減算と同じ結果にはならない。
（`1+3`だから同じ結果になったが、`1+3+3`だったらどうか）
　
数値の加減算を書きたいときについ`+`や`-`を使ってしまうことがあるが（実のところ今回の例もそうだ）、謎挙動に悩まされないためにも意識して`add[]`, `sub[]`もしくは`plus[]`, `minus[]`を使おう。

# 参考

- Daniel Jackson：[抽象によるソフトウェア設計 ―Alloyではじめる形式手法](https://www.amazon.co.jp/dp/B07BKRG85J)
自分を忘れない事の大切さ

# 記事を書こうと思った理由
趣味で８年近くずっとC#でプログラミングをしてきて、前職を辞めた事もあって、2018年12月にプログラマーとして今の会社に入社しました。

今は会社の事業部のリーダーとして、未経験者の教育メインに色々やってます。

そこで、事業部の課題に使うサンプルを作る事になりそこで、僕が陥った事を、今後の自分が二度と陥らない様にと、これから先プログラマーに興味を持ち入社した未経験者の人達に参考になるかなぁと思い書いております。

## 自分が陥った事
先に述べたとおり、課題サンプルを作っている間に、コードを書くのが怖くなってきました。

怖いという表現があっているかはわかりませんが、これが一番近いのかなと思うので、怖いと表現しています。

別にコードを書くのが嫌いになったとかではありませんし、今の現場でコードを書くのは楽しいです。

元々、趣味でやってきて興味を持って、自分で始めた仕事です。
嫌いになったり嫌になったりなんてしていません。

だけど、家に帰ってきてサンプルを書こうとすると手が進まないんです。

サンプルを作る事が嫌になった訳ではありません。

仕事中だって、通勤時だっていつだって
「これをこう書いたらどうだろう」とか考えてワクワクしています。

なのに、いざ家に帰りPCの前についてコードを書こうとすると一文字も書けないんです。

なぜかは、なんとなく気づいていました。

**サンプルだから自分を捨てて書かなくてはいけない**

これに僕は、ハマってしまっていたのです。

### 自分を捨てて書こうとしていた
やはり仕事です。
サンプル作成だって仕事ですから、趣味の頃に好き勝手に書いていたあの頃とは違います。

それはわかってるんですよ。
そしてプログラミングは極論中の極論　動けば正解です。
ですが、これはあくまで極論です。

我々の仕事は、多数のメンバーでコードを書いてる事が多いはずです。
なので、好き勝手には書けません。
可読性とか考えて書いていかなければいけません。

ですが、その中でも人によって書き方なんて変わってきますよね。
僕も現場では、可読性や今度の改修などしやすい様にを意識して書いていますが、その中でも自分の書き方で書いています。

なのにです。
サンプルだからと、完全に自分を捨てないと行けないと、思い込んでしまったんです。

なので自分ならこう書くけど、これで本当に良いのか？っとなってしまい、コードが書けなくなっていました。

それに気づいたのが、知人の先輩プログラマーからの言葉でした。

####正解なんて無いんだから悩みすぎ
まぁ、正確には違いますが、意味合いはこういう内容の事を言われました。

プログラミングなんて、正解は無い
確かに書物やブログなどなど、色々ありますが、それを見たって同じ事をしていても、みんなそれぞれ違います。

なんで、それを忘れていたのかと自分自身に問いかけたくらいです。

今教えてる事業部の後輩にも何度も自分でも言ってきた事だったのに、自分がそれをできていなかったんですね。

#####　何が言いたいのかと言うと
長々書いてましたが、言いたい事は唯一つ

**自分を忘れることなかれ**
プログラミング活動記録

#3月8日の進捗
・ウェブ活の無料HTMLCSSこうざでレッスン１５まで完了（それ以降は有料のためできず。）

##学び
・htmlのタグでgoogle検索のヒットの仕方が変わるということ
・positionプロパティのabsoluteは絶対位置指定、staticは特に変化なし、relativeは相対位置指定、fixedはスクロールしても位置固定で表示される関数
駆け出しエンジニアによるProgateとN予備校の比較感想

プログラミングを始めて約1ヶ月の駆け出しによる、ProgateとN予備校を比較した感想。

結論から書くと、N予備校の方が圧倒的に良い。というか私にあってた。Progateをやってた2週間強より、N予備校を始めたこの1週間の方が圧倒に成長を感じている。(Progateも手軽で分かりやすくて良い教材なんだけども…ごめんね)

●現段階でどこまでやってるか

Progate:
・無課金&アプリでできるところ全て(HTML&Css, Javascript, Java, Ruby, Python, PHP, GO, SQL,コマンドライン, Gitの触り) 
・HTML&CSSの講座終了・道場編初級 
・JavaScriptの講座終了

N予備校:
【プログラミング入門 Webアプリ】第2章終了。
学習順は第2章→第1章(学習開始時は第1章の内容がProgateと割と被ってるのかな？と思っていたため)


●N予備校の良いところ

・とにかく開発環境が実践的

第2章では初っ端からVS CodeとUbuntu、iTermをダウンロードして、PCに開発環境を構築していく。Ubuntuのインストールはとにかくよくわかってないままやったのだけれど、自力だとめちゃくちゃ大変だったろうなと確信した。

実際のプログラミングと同じ開発環境でプログラムを作成し、web上に公開するところまでやるので楽しい。

GitHubにローカルからプッシュ/プルしたり、プルリクを送って模擬ソーシャルコーディングしたりする課題も実務に即していて勉強になる。




・勉強内容に纏わる情報紹介が素晴らしい

勉強する技術の背景知識や周辺情報、その技術を使ってどんなものが作られているのか、外部サイトへのリンクとともに解説がされていて勉強になる。

更なる勉強を深めるのに役立つサイトやググり方もどんどん教えてくれる。

ITパスポートで勉強する内容もちょいちょい挟まっている。机上の話として勉強したものが、実務にどう繋がってるか見えて楽しい。




・実装内容に、実践的な内容が凝縮されている

HTML, CSS, JavaScriptの全てを使って動かすサイトを作るので、それぞれのファイルをどう組み合わせてモノをつくるのかがよくわかる。

「HTML, CSS, JacaScriptはProgateでやったから余裕でしよw」という慢心は木っ端微塵になった。

「あなたの良いところ診断」の作成では、見本のコードを理解して進めるのに結構苦戦。どの課題も、実装内容は他にも応用が効くもの、試してみたくなるものが多く勉強になる。

例としては、
JavaScriptの、「生まれてから何日？」カウントダウンを自己紹介ページにも組み込んでみたりとか。FizzBuzzゲームと、ボタンを押したらスタートする仕組みを合わせて、ボタンを押すと『3の倍数でアホになるナベアツ』が作動すらすサイトを作るとかができた。この調子で何か作りながら復習していきたい。



・これを走りきればかなり力がつくな、と確信するところまで講座が用意されている

プログラミングコースとして用意されているコース内容が豊富かつハイレベル。webアプリ開発コースまでいくとScalaを使って実装とかするんだ？！機械学習やコンピュータサイエンスの項目も充実してそうだし、これを終える頃にはレベルアップ間違いないなという期待感が強い。先は長いがモチベーションが上がる。


●Progateの良いところ

・とにかく丁寧

N予備校を走りきれたのはProgateで一段階積んでたからというのもあると思う。N予備校ではいろんな機能をどんどん詰め込んでいくので、基礎的なところの解説や演習はProgateの方が充実してるのかな？

N予備校で分からなかったところや、ざっとしかやらなかったところを補完する補助教材としては、これからもProgateを使っていく予定。

・手軽

移動中とかに、アプリでパッと勉強できるところが良い。コース自体もそこまで難しく設定されてないので、短時間で得られる小さな成功体験のサイクルをグルグル回しながら勉強できる。

・コマンドラインのお役立ち知識。

「ターミナルでコマンドラインを打つとき、打ってる途中でTabキーを押すと文章補完をしてくれる」って話はProgateでしかしてくれてなかったはず。

・Rubyがある

N予備校はRubyを使っての開発はしないみたい。未経験エンジニアがWeb系転職するのに1番ポピュラーな道はRubyエンジニアから入ることのようなので、Rubyがないのは残念。

Progateには用意されてるので、N予備校→Progate→Ruby on Railsの順で学習していく予定。



●Progateの惜しいところ
・Progate上でしかやらないので実践にどう繋がるのかがわかりにくい。

「実際の開発環境を整えよう」って内容の記事を用意してくれてはいるものの、やはりメインはアプリまたはサイト内でのコーディングになるから少し物足りない。

PC版にしかないGitのコースとかも、Progateの解説だと実際のGitHubには触らず説明が終わってしまうのが勿体ない。



●総括

駆け出しエンジニアにオススメの学習サイトといえば、Progateとドットインストールが二大有名どころだけど、N予備校めっちゃ良いじゃん？！もっと早く出会いたかったけど、このタイミングで出会えてよかった。

無料公開してくれたおかげでN予備校の存在と価値を知ることができたし、無料公開期間が終わっても続けると思う。ありがとう……！
Qiitaに登録！


アウトプット&備忘録用として、Qiita デビュー。

:thumbsup:

勝手にスライドになってすごーーーい！

投稿内容編集画面に「差分」ってタグがあるのが、いかにも技術ブログって感じ！
スライドモードの編集方法がわからない:innocent:
julia v1.3から始めるJupyter Notebook



[前回](https://qiita.com/doorei/items/91a52a31f917b9d7bb84)、juliaをインストールしたPCが不調になり、新型PCを導入したのでJuliaをインストールしようとしたらjuliaのバージョンが上がっていて少しだけ前回通りではいかなかったので再度書いてみる。
※[Julia1.5対応版](https://qiita.com/doorei/items/c0916f0866bfc2859c2f)はこちら

# やってみた環境
- Windows 10 Home (64bit) Ver 1909
- julia v1.3 (64bit)

# やり方
0. juliaがインストール済みの前提
1. juliaのコンソールを起動(緑字のプロンプト)
2. `]`キーを押してパッケージモードへ(青字のプロンプトになる)
3. `add IJulia`を実行(Cloning～となり、しばらく時間がかかる)
4. `build IJulia`を実行(Building～となり、しばらく時間がかかる)
5. バックスペースでパッケージモードを抜ける(緑字のプロンプト)
6. `using IJulia`を実行(Precompilingされる)
7. `notebook(detached=true)`を実行
8. 「install Jupyter via Conda, y/n? [y]:」と聞かれるので`y`を入力
9. 関連パッケージがダウンロードとインストールされる。(結構時間がかかるので気長に待つ)
10. Jupyterが起動する！「New」のプルダウンにはJulia 1.3.0とpython 3が出てくる

juliaからインストールしたcondaはjulia専用(?!)なのでDisk容量がもったいないといえばもったいないけど、面倒なことを考えないでJupyterが使えるようになるのでまずやりたいことをやる！という場合にはいいんではないでしょうか？

ちなみにjuliaからインストールしたcondaでインストールしたパッケージの確認などは次のようにします。

```julia
julia> using Conda                    
Julia> Conda.list()                   # Condaでインストールしたパッケージ一覧 
Julia> Conda.update()                 # Condaでインストールしたパッケージのアップデート
Julia> Conda.install("package_Name")  # Condaで"package_Name"をインストール⇒「conda install -y package_Name」を実行
```

上記の`using Conda`でエラーが出る場合は一回だけ次のようにパッケージを追加する必要があります。

```julia
Julia> Pkg.add("Conda")
```

# 普段のjupyter起動
念のためですがインストールが終われば次からは下記だけでjupyter Notebookが起動します。

```julia
julia> using IJulia
julia> notebook(detached=true)
```
Windows環境でpythonを動かす

windows 10環境でpythonを触りたくなったので手順をまとめておく。

## 環境

Windows 10 
python 3.8.2

## pythonをダウンロードしてインストール

下記のサイトより最新版の3.8.2をダウンロード
https://www.python.org/downloads/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272635/b92dfb61-d5a3-08e1-c0cf-8b48dcac4ac6.png)


ダウンロードしパッケージ実行
このときに[Add Python 3.8 to PATH]にチェックをし、Install nowをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272635/f16048f5-df06-0c51-9f3b-01c31df0d827.png)


完了するとこちらの画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272635/6004049d-1ea6-39ca-25d8-d31ab394e13f.png)

## 確認
git bashなどインストールしている場合はbashからpyを実行して確認

```
$ py
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
MECEとは？格安simをMECEの観点で考えてみた。

<h2>概要</h2>
資料作成などで意識すべき点としてMECEというフレームワークがあります。
このフレームについて紹介していこうと思います。

ビジネスフレームワークをまとめた記事もあるのでぜひこちらも見てもらえればと！
https://qiita.com/harumaki_dayo/items/f3d24f2d42a58f46736b

<h2>目次</h2>
・MECEとは？
・格安sim比較

<h2>MECEとは？</h2>
MECE(ミーシーorミッシー)とは「<b>M</b>utually <b>E</b>xclusive and <b>C</b>ollectively <b>E</b>xhaustive」の頭文字をとったものです。

Mutually（お互いに）
Exclusive（重複せず）
Collectively（全体に）
Exhaustive（漏れがない）

ざっくり言うと、「漏れなく、被りなく」のことです。

例えると、商品などを顧客に対して提案する資料で「この商品は顧客の要望を<b>漏れなく</b>満たせており、顧客の今のリソースと<b>被ることがない</b>。つまりは<b>最適</b>である」ということを一目でわかるようにするみたいな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402218/116a3dba-7e03-a478-4dc5-3c716cc439a5.png)


<h2>格安sim比較</h2>
UQmobileを使い始めて2年経つのですが2年前の契約だと、2年目以降月々の基本料金が上がるということで、更新すべきか乗り換えるべきか悩みました。そこでMECEの考え方を使用し、格安simを比較し検討しました。

<h3>1.「携帯会社に求めているもの」をリストアップ。</h3>
まず、前提となる携帯会社に求めているものを「必須」「できれば」に分けて洗い出します。
MECEを意識するうえで、何に対して「漏れなく、被りなく」を意識するのかをリストアップする必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402218/8a8132a9-3224-e7a3-8c85-edf114ece5b6.png)

<h3>2.比較対象のリストアップ。</h3>
次に比較対象をリストアップします。
目的としては「どの格安simが最も自分の求める格安sim」に近いのかを考えるため。
言い換えると「どの格安simが最も自分の理想から<b>漏れがなく</b>、自分にとって<b>無駄なサービス</b>がないか」を考えるためです。

実際にはもっと多くの格安simの会社があったのですが、あまりに比較対象が多くなるので絞って比較しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402218/a7aa17b5-5174-95a3-8e74-3ed8b3185475.png)

というわけで自分であればmineoが<b>最適</b>ということがわかりました！

<h2>まとめ</h2>
ビジネスではもちろんのことプライベートでも使えるので、MECEを習慣化して身に付けていきましょう。
aspidaでGETパラメータをリクエスト直前にシリアライズする

## GETパラメータに配列が含まれているとリクエストに失敗する

[SwaggerをTypeScriptに変換してAPIリクエストで型チェックを有効にする](https://qiita.com/m_mitsuhide/items/9ce4e048749075845655)という記事の補足です
[GET: /pet/findPetsByStatus](https://petstore.swagger.io/#/pet/findPetsByStatus)のリクエストを行うと失敗します
（常に空の配列が返ってくる）

```typescript:index.ts
import axiosClient from '@aspida/axios'
import api from "./apis/$api"

;(async () => {
  const client = api(axiosClient())
  const pets = await client.pet.findByStatus.$get({ query: { status: ['available', 'pending'] }})
  console.log(pets) // []
})()
```

原因は、GETパラメータのstatusプロパティにあります
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63528/a80fe4bd-045c-2d89-72d5-0bf6d081c0d0.png)
画像の通り、型は `'available' | 'pending' | 'sold'`の配列です
`@aspida/axios`はaxiosの仕様に則りGETパラメータの配列を`&status=[%22available%22,%22pending%22]`という形式で送信します

一方で、SwaggerのRequest URLを見ると、`&status=available&status=pending`という形式で送信する必要があるとわかります
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63528/f5ba3600-1b78-8a12-3963-ec6d4d9a7b80.png)

そこで、aspidaにaxiosの拡張機能を適用してGETパラメータをシリアライズします

## qaxiosConfig#paramsSerializerでシリアライズ

### 設定ファイル
```javascript:aspida.config.js
module.exports = {
  openapi: {
    inputFile: 'https://petstore.swagger.io/v2/swagger.json'
  }
}
```

### 型定義ファイル生成
```bash
$ npx openapi2aspida --build
```

### インストール
--save-dev付けるとか付けないとかあるけどとりあえずまとめてインストール

```bash
$ npm init -y
$ npm install @aspida/axios axios ts-node @types/node
```

### APIリクエスト
axiosClientの第2引数にaxiosの[Request Config](https://github.com/axios/axios#request-config)を渡せます

```typescript:index.ts
import { stringify } from 'querystring'
import axiosClient from '@aspida/axios'
import axios from 'axios'
import api from "./apis/$api"

;(async () => {
  const client = api(axiosClient(axios, { paramsSerializer: (params) => stringify(params) }))
  const pets = await client.pet.findByStatus.$get({ query: { status: ['available', 'pending'] }})
  console.log(pets)
})()
```
作成したTSファイルを実行するnpmスクリプトを追加

```json:package.json
{
  "scripts": {
    "start": "ts-node index.ts"
  }
}
```
実行

```bash
$ npm start
```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63528/6789c4e1-4ef1-b1cb-cae1-0beb1515da66.png)

無事取得できました

### まとめ
ブラウザでリクエストする場合はquerystringの代わりに[qs](https://www.npmjs.com/package/qs)をインストールすると良いです
バグとか不足機能があれば日本語でいいのでQiitaのコメントかGitHubのIssueに投稿してください

aspida日本語ドキュメント：https://github.com/aspidajs/aspida/tree/master/packages/aspida/docs/ja
Mac Audacity(オーダシティ)のインストール後にアプリが起動しない話

# 目的

- Audacity(オーダシティ)のインストール時後の初回起動時にアプリアイコンをクリックしても起動しないことを解決した話をまとめる

# 症状

- Dockに追加されたAudacityのアイコンをクリックしてもアイコンがピョンと跳ねるだけでウインドウが起動しない。
    ![スクリーンショット 2020-03-05 20.51.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c42be133-ad51-f1e7-d58f-e6ba5a75374c.png)

# 解決方法

1. オフィシャルサイトから最新のインストーラを再ダウンロードを行い再度インストールを行った。
1. 筆者の場合、オフィシャルではないサイトからダウンロードしたバージョン2.2.2のインストーラだとAudacityが起動しなかった。
1. 下記のリンク先のオフィシャルサイトから最新版の2.3.3のインストーラをダウンロードしてインストールしたら解消された。
【rails】チェックボックスを使った検索フォーム（ビュー）

railsでチェックボックスを使って検索フォームの実装しました。

### 前提条件
・rails 5.2.4.1
・メモアプリで、メモに紐づくタグをチェックボックスで選択し、絞り込み検索を実装する。
・メモとタグのモデルは多対多。

```ruby
        = form.check_box :tag_ids, { multiple: true, include_hidden: false, class: "wrapper__contents__right__ul__search-form__list__checkbox" }, user_tag.id
        -# form.check_box :配列名, { 複数のチェックボックスをひとまとめに扱うか, uncheck時に0の自動取得を回避, class:"クラス名" }, "チェック時に取得する値"
```

### 留意点
multiple: true ... 選択した複数のチェックボックスの値を配列で取得するオプション
include_hidden: false ...　チェックなしの場合に配列["0","0",...]を取得するデフォルト設定の無効化


```ruby:_contents_right_haml.html.haml

%ul.wrapper__contents__right__ul
  .wrapper__contents__right__ul__title
    = "タグリスト"
  = form_with(url: search_tags_path, local: true, method: :get, class: "wrapper__contents__right__ul__search-form") do |form|
    - @user_tags.each do |user_tag|
      %li.wrapper__contents__right__ul__search-form__list
        = form.check_box :tag_ids, { multiple: true, include_hidden: false, class: "wrapper__contents__right__ul__search-form__list__checkbox" }, user_tag.id
        -# form.check_box :配列名, { 複数のチェックボックスをひとまとめに扱うか, uncheck時に0の自動取得を回避, class:"クラス名" }, "チェック時に取得する値"
        = form.label user_tag.name, class:"wrapper__contents__right__ul__search-form__list__name"

    = form.submit 'Search', class: 'wrapper__contents__right__ul__search-form__submit'
  %br
  = "※AND条件で絞り込み検索します。"

```


コントローラのストロングパラメータにて、チェックボックスの第一引数に記載した配列名で値を受け取ることができる。

```ruby:Tags_controller.rb
  def selected_tags_params
    params.require(:tag_ids)
  end
```

チェックボックスからDBに登録するための情報はいろいろあったけど、検索の場合はあまりなくちょっと苦労しました。

<img width="1680" alt="スクリーンショット 2020-03-13 23.43.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564329/e2f1687d-20bf-cf74-eadf-405a4bb981cf.png">


### 参考
https://qiita.com/tomoima525/items/22c215db90cc9a9b09cc
https://qiita.com/akk11_k/items/2943c94cac6b91d75467
https://qiita.com/chocoken517/items/6efb9c5a1b035f9a50fa
【Git】Git commitでエラー発生。エディタ登録に原因あり！

#はじめに
はじめまして、りゅういちです！
Qiitaは閲覧オンリーだったのですが、
　・アウトプットして知識定着
　・誰かのお役にたてば
と思い、書き始めてみます。

#この記事は
UdemyのGitコースで学習中にエラーが発生したので、その内容と解決方法を書きました。

#環境
- mac
- Visual Studio Codeをインストール済み

#前提
標準のテキストエディターは設定済み。
ちなみにVSCodeを設定する際のコードは下記の通りで、
お使いのエディタによって"code --wait"は変更必要です。

```
git config global core.editor "code --wait"
```

#ターミナルからエディタが起動できない
「ターミナルからgit commitを実行し、VSCodeを起動して・・・」の際に、
下記エラーが発生してVSCodeが立ち上がらず。

```
code --wait: code: command not found
```

#解決方法
Mac環境ではPATHをを通す作業が必要なようです。
以下の手順を実行します。
1. Visual Studio Codeを起動
2. コマンドパレットを開く(表示タブ→コマンドパレット or cmd+shift+p)
3. シェルコマンド: PAHT内にVS Codeをインストールします (Shell Command: Install code command in PATH)」を選択する
<img width="1439" alt="スクリーンショット 2020-03-08 23.25.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240297/714f0270-078b-3f44-a608-ec28ad72d555.png">
4.インストールを行います。成功すると、「シェルコマンド'code'がPATHに正常にインストールされました。」と表示されます。

#参考文献
- https://qiita.com/ayatokura/items/69c96306e3dee501e19b
- https://qiita.com/noto_web/items/eb5d6a904c459b8c6dea
- http://shoyan.hatenablog.com/entry/20120506/1336314128
「単体テストが面倒くさい」に立ち向かう ―5つの弾丸

やらなきゃいけない。
でもやる気が起きない。
そんなときがありますね。

特に単体テストは、プロダクションコードの進捗に直接は寄与しませんし、技術的にもチャレンジングなところはありませんから、モチベーションを上げるのに苦労するのも無理はありません。

そこで対処方法を挙げてみました。

# リファクタリングする

[AAA (Arrange, Act, Assert)](https://docs.microsoft.com/ja-jp/visualstudio/test/unit-test-basics?view=vs-2019#write-your-tests) の **Arrange** が面倒で、立ち尽くすことがあります。

チャンスです。
面倒なのはメソッドが複雑な証、リファクタリングしましょう。
具体的には、[メソッドの抽出](https://www.jetbrains.com/help/resharper/Refactorings__Extract_Method.html)、[クラスの抽出](https://www.jetbrains.com/help/resharper/Refactorings__Extract_Class.html)を検討しましょう。

本筋から外れる依存処理を外部に切り出すことができれば、単体テストも簡素化でき、変更時に受ける影響も限定的になります。

単体テストを書くのは変更時のリスクを減らすためでもあります。
変更の影響が広範囲のテストコードに及んでしまっては元も子もありません。

簡素化できれば実装も楽しくなる、一弾二狼[^1]です。

# Act を先に書いちゃう

これ私よくやります。
リファクタリングは施した（あるいは見送った）。
それでもなお（あるいは当然に）、**Arrange** を面倒に感じてしまうことはあります。
人間ですから気持ちの波もあるでしょう。

そんなとき、まず **Act** を書いてしまいます。
考えなくてよいこと、迷う余地のないことから始めるのです。
そこに必要なコードを足していきます。

渡す引数が準備できなければコンパイルエラーになるでしょう。
いいんですそれで。
プログラマはエラーが嫌いです。
問題を放置できません。
本能的に反応します。
ああ、解決しなきゃ。
引数はどう準備したらいいだろう。
いったん解決欲に火がついたら、テストが通るまで我には返れません。
モチベーションはそれまで安泰です。

プログラマの性を利用して、自分を巧みに引き込む作戦です。
やや大げさでしたが、意外に功を奏しますので、ぜひ一度お試しを。

# モック処理を共通化する

毎回同じようなことを書いてる気がする。
決まったことに手数とコードが費やされる。
これらは悪い徴候、つまり改善のチャンスです。

モック化の肝要な点は `Setup` ですが、変数宣言、インスタンス生成、`VerifyAll` など定型的なコードが増えがちです。
テストメソッド間で共通する定義や処理は、テストクラスに共通化することもできるでしょう。
ただし、一部のメソッドでしか使わない依存オブジェクトまでやみくもにモック生成するのは無駄です。
また、テストクラスにフィールド定義するのも疲れますし、フィールドが増えて追加するのも面倒です。

DIコンテナを活用してモック化の枠組みを構築することで、こうした煩わしさから解放されることができます。
[前記事](https://qiita.com/CodeOne/items/352a88901a33d0074230)に引き続き、手前リンクで恐縮ですが、一例としてご紹介します。

- [[.NET] 単体テストがさくっと書ける！モック化の枠組み（Moq + Unity）](https://qiita.com/CodeOne/items/7231ade6050588751ec6)
- [[.NET] 単体テストがさくっと書ける！モック化の枠組み（Moq + Autofac）](https://qiita.com/CodeOne/items/04541f1dda346d7dd9f6)

プロジェクトにあわせた仕組み化を検討しましょう。
単体テストにかける（結果的にかかる）工数の大きさと、単調なことに費やす心理的負荷の生産性への影響度を考えれば、どうすれば効率化できるか、時間をかけて吟味する価値は十分にあると思います。

# カバレッジの数値目標を立てる

ゲーム的な達成感がやる気のアクセルになります。

ただし、ノルマ化には注意が必要です。
義務感でかえってやる気を損ねかねません。
うまくポジティブな目標に落とし込むことが大切かなと思います。

また、数値稼ぎが目的になってしまうおそれもあります。
乱雑なテストコードを書き殴ったり、形式的で意味の薄いケースが氾濫してしまうのは避けたいところです。
単体テストのリファクタリングは、プロダクションコード以上に意図を汲み取るのがたいへんで苦労することがあります。

数値は極度に単純化された一つの指標にすぎず、品質を直接に担保するものではありません。
わかりやすいから重宝されるだけで、あくまで事実はソースコードの中にあります。
補助的に使用しましょう。

# 機械になる

脳のメモリを消費しない。
対象メソッドのロジックを上から追いながら、機械的にテストコードに変換していく。
処理の意味など考えない。

実はこれ、だめです。
単体テストは、想定漏れや不適切なクラス構成、命名に気づく貴重な機会です。
せっかくの機会を、プロダクションコードの正当性を表明するためだけに費やすのはもったいない。

これはリファクタリングにも通じることですね。
デッドコード、はい、消します。
気持ちがいいのはとてもよくわかります。
でもちょっと待ちましょう。
メソッドを作って呼び間違えているだけでは？
単に余分なだけなら運がいいと思わなければいけません。
リファクタリングが必要なコードベースを相手にしていることを忘れずに。
せっかく臭いを発してくれているわけです。
リファクタリング自体は既存の動作を保持するのが基本ですが、その過程で潜在的な不具合が見つかることは多々あります。
機械的に処理してしまうのはもったいないです。
まずは嗅ぎましょう。
そして臭いの元を突き止めましょう。

戻りまして。
機械的な作業は機械がやってくれます。
人間がやっているとしたら分担が間違っています。
人間でいましょう。

[^1]: ごめんなさい。