OmniAICreator/Qiita-1.07M huggingface dataset:
optuna×svmでwine_quality

# はじめに
xgboostの性能評価のため、
[前回の実験](https://qiita.com/kuroneko-hornet/items/65e4cc746991323fe1e8)との比較実験として、アルゴリズムをSVMに切り替えてやってみた.
結果、制度は出なかった.
XGBoostよりやや精度が低いが、大差ない.

# 実行環境
* python 3.6.5
* XGBoost 0.81
* optuna 0.7.0

# 実装
## 方針
1. SVMだけ
2. optuna使う

## ライブラリ
```python:
import matplotlib.pyplot as plt
import pandas as pd
import optuna
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
```

## 方針1(SVMのみ)
### 前処置
データは1599個あるので、そのうちの1割をランダムにテストデータとして使う.
また、説明変数は正規化する（X_~_std）

```python:
def preprocess(df):
    X = df.drop(target_column,axis=1)
    y = df[target_column]
    X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 0.1, random_state = 666)
    sc = StandardScaler()
    sc.fit(X_train)
    X_train_std = sc.transform(X_train)
    X_test_std = sc.transform(X_test)
    return X_train_std, X_test_std, y_train, y_test
```

### main関数
```python:main.py
def main():
    global target_column
    df = pd.read_csv("winequality-red.csv")
    X_train_std, X_test_std, y_train, y_test = preprocess(df)

    params = {
        'kernel': 'rbf',
        'C': 5,
        'gamma': 0.1,
    }
    
    mdl = SVC(**params)
    mdl.fit(X_train_std, y_train)
    
    pred_train = mdl.predict(X_train_std)
    accuracy_train = accuracy_score(y_train, pred_train)
    pred_test = mdl.predict(X_test_std)
    accuracy_test = accuracy_score(y_test, pred_test)
    print('train score :',accuracy_train)
    print('test score :',accuracy_test)
```
target_columnはqualityです.
ハイパーパラメータは

* kernel = rbf 
* C = 5
* gamma = 0.1

それ以下のコードは学習データ、テストデータに対して評価しているだけ.

## 方針2(+optuna)
optunaで自動チューニングする時に必要なのが、

* 目的関数を最適化するobjective()関数
* objecitveの準備と実行(main関数内)
### objective()
```python:
def objective(X_train_std, X_test_std, y_train, y_test, trial):
    #目的関数
    params = {
        'kernel': trial.suggest_categorical('kernel', ['linear','rbf','sigmoid']),
        'C': trial.suggest_loguniform('C', 1e+0, 1e+2/2),
        'gamma': trial.suggest_loguniform('gamma', 1e-3, 3.0),
    }
    mdl = SVC(**params)
    mdl.fit(X_train_std, y_train)
    pred_test = mdl.predict(X_test_std)
    accuracy_test = accuracy_score(y_test, pred_test)
    return 1.0 - accuracy_test
```
objevtiveの目的変数(ハイパーパラメータ)の範囲は

* kernel = linear, rbf, sigmoid 
* C = 1 ~ 50
* gamma = 0.001 ~ 3.0

### main()(追加分)
```python:main.py
    #objective()に与える変数
    obj_f = partial(objective, X_train_std, X_test_std, y_train, y_test)
    #セッション作成
    study = optuna.create_study()
    #回数
    study.optimize(obj_f, n_trials=100)
```
これを`mdl = SVC()`の前に入れると、自動チューニングができる.
SVC()の引数は**pramsから**study.best_params(チューニングしたパラメータの値)に変更すること.

# 実行結果

## 結果1(SVMのみ)
|kernel|C|gamma|
|:-:|:-:|:-:|
|rbf|5| 0.1 |

|train score | test score |
|:----------:|:----------:|
|0.6692147324530924 | 0.61875 |

## 結果2(+optuna)
|kernel|C|gamma|
|:-:|:-:|:-:|
|rbf|24.258778854648092| 0.777764797855619 |

|train score|test score|
|:-:|:-:|
| 0.9986101459346769|0.65|

# まとめ
綺麗に過学習した.
optuna使うとちょっと精度上がる.
### 結論 ： 前処理が大事
mercarigo #6 スライドまとめ(個人用)

## はじめに
参加してきて非常にためになったので個人的な復習用に


<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">そういえば資料は数日後にまとめて会社のブログに投稿します。 <a href="https://twitter.com/hashtag/mercarigo?src=hash&amp;ref_src=twsrc%5Etfw">#mercarigo</a></p>&mdash; morikuni (@inukirom) <a href="https://twitter.com/inukirom/status/1100056169387716608?ref_src=twsrc%5Etfw">February 25, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

無い部分はまとめて頂けるようなので、後で追記します。

## JavaとGoの比較 
登壇者:@kentan
twitter: https://twitter.com/kentandx
スライド掲載なし

## yamlをテストする
登壇者:@babarot
twitter: http://twitter.com/b4b4r07
[Testing with YAML - Speaker Deck](https://speakerdeck.com/b4b4r07/testing-with-yaml)

## shallow　copyに気をつけろ
登壇者:@t-naritomi
twitter: https://twitter.com/ques0942
[sliceのコピーで起きた不思議な話 - Google スライド](https://docs.google.com/presentation/d/1Amjy6UZUCytPdpFeVxPIFa6D_YYYO7SAeZ0JNPEQ8Sw/edit#slide=id.p)

## コンパイラ書いた話
登壇者:@kitasuke
twitter:https://twitter.com/kitasuke
[Writing a compiler in go](https://www.slideshare.net/kitasuke/writing-a-compiler-in-go)

## コンパイラ書いた話（mapとheap)
登壇者:@dqneo
twitter: http://twitter.com/dqneo
[Goのmapとheapを自作してみた / How to create your own map and heap in Go - Speaker Deck](https://speakerdeck.com/dqneo/how-to-create-your-own-map-and-heap-in-go)

## ポメラニアン専用Goコンパイラ
登壇者:@tenntenn
twitter: http://twitter.com/tenntenn
[ポメラニアン専用Goコンパイラ - Google スライド](https://docs.google.com/presentation/d/1gwWeUcjJFyIv5IVEaPAvn_petS3VB68aw9kFtZvche4/edit#slide=id.g507bd0d240_0_148)

## Goのエラーハンドリング
登壇者:@morikuni
twitter: http://twitter.com/inukirom
[mercari.go #6 - Google スライド](https://docs.google.com/presentation/d/1wbEaKX9z5vyEonTt6qfnIjDICZk3nDHdG_Ky0gRXyXw/edit#slide=id.g4f4dc8ea07_1_19)
オンラインカードゲームのサーバーサイドを作った①

# はじめに？
学校の課題やら趣味のゲーム制作で結構頑張ってカードゲームを作ったので、投下しようと思いました。
今回作ったゲームは、[Black Poker](https://sites.google.com/site/blackpoker000/)というカードゲームです。
タグを見て来た方の中には、
「おいおい、TCGタグ付いてるくせにトランプゲームじゃねえか」
と思った方もいると思います。
ただこのゲーム、トレーディング要素はないものの、デッキを構築し、山札から引いたカードで攻撃しあうという最近のTCGの要素が詰まったゲームなのです。

# Black Pokerとは？
１人１セットのトランプを使ったターン制のTCG風トランプゲームです。
（公式サイトより引用）
お互いは山札を良くカットします。
山札の上から1枚捲り、数字・マークの大きい方が先攻となります。
お互いに山札から7枚引きます。
ターンプレイヤーは山札からカードを1枚引き、以下の行為を行います。
① ダメージを1点受け、手札からカードを裏向きで置く (ターン1)
② ダメージを1点受け、裏向きのカードを横に向け、手札からカードを表向きで置く (ターン1)
③ 自身の表向きのカードをn枚選択して、攻撃する (召喚酔いあり)
攻撃を受けたプレイヤーは、場のカードでブロックするもしくはダメージを受けます

ダメージを受けたプレイヤーは、山札からn枚のカードを墓地へ送ります。
デッキがなくなったプレイヤーはゲームに敗北します。

# まずはゲーム本体を作る
サーバーサイド開発ではありますが、通信などは置いておいて、まずはコンソールで動作する本体を作成します。

私は以下のような設計をしました

![UML図.png](https://qiita-image-store.s3.amazonaws.com/0/231661/dab3e927-80dc-dc03-75dc-036f91937473.png)

トランプのカード1枚1枚に対応するCardオブジェクトを生成し、Playerがメンバ内のCardを移動させていきます。

疲れたので今回はここまでです。
次回はカードクラスを書いていきます。

プログラムはGitHubにも置いておくので参考にしてください
[Black_Poker4j](https://github.com/Javakky/Black_Poker4j)

[次回はこちら](https://qiita.com/Kakky/items/c40d20251fe6f8f5d250)
コンパイラ、インタプリタ、アセンブラとは？

# コンパイル系高級言語、インタプリタ系高級言語、機械語に近い低級言語

ご存じの通り、コンパイル系、インタプリタ系、機械語に近い低級言語系によって、異なるプログラミング用語があります。
その軽～いお話（独自解）。

## ～言語、スクリプト？、アセンブリ

いわゆるソースコードと呼ばれる「人間が理解できる言葉で書かれた言語」です。

C言語、C#言語、Java言語、Ruby、Perl、PHPなどいろいろありますが、コンパイル系・インタプリタ系含め、人間の理解できる言葉に近いので「高級言語」と呼ばれます。
でも、最近の言語ってどちらかというと、特殊な人しか理解できなさそうな言語もあるのですが、それって中級言語とか呼ばないんでしょうかね？
ラムダ式やらLINQやら関数式やら、もはや特殊な人にしかわからないような気がするよ...
低級言語は「アセンブリ言語」の他に、中間言語も一応それに入りそうです。
人間にとって、理解しやすいか、しにくいかといったところの区別だけなので。

インタプリタ系で実行するプログラムは、スクリプトと呼ばれることが多々ありますが、どうなのでしょうか。
このあたりが結構曖昧な感じがします。
バッチ、スクリプトとか結構曖昧な感じもします。バッチスクリプト？スクリプト？...難しいです。
ちなみに、バッチというと単体で実行して直ぐに終わるような一過性の処理という意味合いで使われます。
データベースに書き込まれたデータを1日1回集計して別のデータベースへ突っ込むとか。
スクリプト（インタプリタ系の言語で書かれること）が多いのですが、C言語等でコンパイルされたもので動かすこともあります。
こちらもバッチと呼ばれますね。
うん、意味不明...。
プログラミング関係の用語はなかなかややこしいです。

ちなみに、アセンブリ言語はいくつも種類があります。当たり前ですが...。
CPUのアーキテクチャによって命令の形が違います。Intel 8086(x86), AMD64(x86-64), ARM, PowerPC, MIPS, RISC-Vなど、いろいろなアーキテクチャがあり、それぞれ機械語の命令が異なります。そのため、アセンブリ言語と行っても、環境が違えば全く違う構文になります。あと、同じアーキテクチャでもアセンブラが違うと、書き方が変わる場合がありますが、これはC言語等でもあることなので、それは環境差異という感じでしょうか。

「～級言語」の対義語は「機械語」や「ネイティブ」や「バイナリ」です。
機械語とは、CPUが理解できる 1 と 0 の数値の羅列になったもので、簡単に言えば、`CPUの理解できる言葉=機械語（ネイティブ）`ですね。


## コンパイラ、インタプリタ、アセンブラ

プログラマーが書いたソースコードを、他の言語や機械語に変換するソフトウェアのことです。
ちなみに、ソース（Source＝元の）、コード（Code=記号）という意味になります。
コンパイラやインタプリタについては、構文解析やら意味解析などいろいろあったり、ライブラリなどをくっつけるリンカー、最適化処理を行う機能などもあり、こちらはかなり複雑です。
一方のアセンブラは、基本は機械語と一対一の変換です。ただ、マクロという機能があり、その処理があったり、高級言語のような機能もあったりするので、一概に言えませんね。
基本、アセンブリは最適化がないはずですが、あるんでしょうか（並び替えとかするのかな？）


## コンパイル、何？、アセンブル

上のコンパイラやインタプリタやアセンブリが「行うこと」、つまりソースコードを別の記号や数字や文字列に置き換えることを言います。
ただ、インタプリタの場合はなんと言えばいいんでしょうか。翻訳？実行？

JITコンパイルやAOTコンパイルなどと、最近はコンパイルするタイミングが変わってきたので、用語が増えたような気がします。
アセンブリ、アセンブラは、良く聞くのですが、まぁ、実行する形態なのでアセンブルという言葉はあまり聞かないですね。
アセンブリ言語を扱える人がそれほど多くもないのも起因してたりしますが...

## まとめ

何故こんな記事を書いたかというと、仕事中に雑談程度に聞かれたからです（ぁ
Rasberry Pi3 Model B+起動

# きっかけ
Rasberry Pi3 Model B+を借りてきた。

# 目的
とりあえず触ってみよう

# 準備物
+HDMI対応ディスプレイ
+HDMIケーブル
+LANケーブル
+USBキーボード
+USBマウス
+PC
+MicroSD
+MicroSDリーダ(アダプタ+SDリーダでも可)
(+WiFiルータ)

# インストール

##1. PCにて

###OSダウンロード
https://www.raspberrypi.org/downloads/raspbian/
からOSダウンロード

今回は下記を選択。
Raspbian Stretch with desktop and recommended software
存外時間が掛かる…

###書き込みツールダウンロード
DD for Windows †
http://www.si-linux.co.jp/techinfo/index.php?DD%20for%20Windows

おお懐かしのddだ…って当たり前か。

###MicsoSDに DD使って書き込み。
かなり時間かかる。

##2. ラズパイセット

###いろいろ配線する。
MicroSDスロットどこやねんと思ったら、背面に付いてた。

###3. 起動
電源を挿すだけ。

####4. 経過
"Expand Filesystem"表示されて勝手にやってる。

パスワード入力画面になるので入力

タイムゾーン他聞かれるので、
・Japan
・Japanese
を選択。
なお、日本語キーボードの為、English Keyboard？にはチェックせず。

LANから接続するつもりでいたら、近くのWiFi拾った…
ついでなので、WiFi設定。

####結末

何もせずに起動した。
さてどうしたものか。
Dockerコンテナで起動したAngularをVSCodeでデバッグ

# Dockerコンテナで起動したAngularをVSCodeでデバッグ

VSCodeのlaunch.jsonで手間取ってしまったのでメモ。

## 前提
* アプリはdockerコンテナ内の __/app/front__ ディレクトリで公開
* 公開URLはlocalhostではなく __http://myapp.develop/__ で公開。npm hotelを使ってlocalhost:port に独自のローカルドメインを付与しているだけなので通常のlocalhost:4200でも特に問題ない。ちなみに __npm hotel__ は複数の案件を手がけなければならないときなど非常に便利です。各サービスごとに自由にドメインを設定できるし、今時ならローカル開発時からSSLでやるのも珍しくないでしょうから重宝します。


## VSCode launch.jsonの設定

VSCodeが生成するChrome用のデバッグ設定は以下のようになる。

```
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome against localhost",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceFolder}"
    }
  ]
}
```

私の環境の場合まず、独自ローカルドメインでホストしているのでurlを次のように変更する必要がある。

```
"url": "http://myapp.develop",
```

Angularは内部でwebpackを使ってソースをバンドルしてるため以下の追加設定をlaunch.jsonに追加する必要がある。

``` .vscode/launch.json
    "sourceMapPathOverrides": {
    "webpack:////app/front/*": "${webRoot}/*"
    }
```

VSCodeが自動で展開してくれる sourceMapPathOverrides のデフォルトは以下のようになる。
通常の開発では作業ディレクトリがそのまま公開URLのルートになるのでこのデフォルトのままでもいけるようだがdockerコンテナで公開している場合などは適宜ソースマップのパスを変換してやる必要がある。

``` .vscode/launch.json
      "sourceMapPathOverrides": {
        "webpack:///./*": "${webRoot}/*",
        "webpack:///src/*": "${webRoot}/*",
        "webpack:///*": "*",
        "webpack:///./~/*": "${webRoot}/node_modules/*",
        "meteor://💻app/*": "${webRoot}/*"
      }
```

最終的に出来があるlaunch.jsonは

``` .vscode/launch.json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome against localhost",
      "url": "http://myapp.develop",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "webpack:////app/front/*": "${webRoot}/*"
      }
    }
  ]
}
```

これでVSCodeでF5を押せばブラウザが起動してVSCodeでブレークポイントをおいたりデバッグが可能になる。

ソースマップのオーバーライドパスがよくわからない場合は、Chromeの開発ツールでsourceの箇所を開いて適当なソースファイルがどのようなパスになっているか確認してみればすぐ分かる。

![image01.png](https://qiita-image-store.s3.amazonaws.com/0/184118/bf7f32e6-9c8b-f605-b489-7f12a2796e5c.png)

![image02.png](https://qiita-image-store.s3.amazonaws.com/0/184118/af233ab5-1af8-9577-d743-e4c28f854d26.png)

この場合だと、__webpack:////app/front/__ をワークスペースのパスで置き換えるように指定してあげればよい。
typescript-eslintの拡張子設定

tslintが非推奨になり、[typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) 1.0がリリースされた今、あちこちで移行プロジェクトがはじまっていると思います。

それ自体の設定は公式に譲り、本記事では周辺ツールや開発環境における地味に必要な**拡張子**の設定について共有したいと思います。

ほかにもあれば編集リクエストでご協力ください。

## .eslintrcでできないの？

はい。これが理想ですが、現状ではoverrideオプションを使ってもできないらしいです。GitHubにIssueが上がっています。

<https://github.com/eslint/eslint/issues/2274>

## コマンドライン

eslintは *.js のファイルしかみないので、明示的な指定がいります。

--ext オプションで指定するか単純にglobでできます。

```bash
eslint --fix src/**/*.ts
```

が、globでやるとひとつもファイルがないとき（ボイラープレート作成直後とか）にエラーになってしまうので、--extオプションがよさそうです。

```bash
eslint --ext .js,.jsx,.ts,.tsx --fix lib/**
```

## VS Code

### vscode-eslintの設定

```json:.vscode/settings.json
{
    "tslint.enable": false,
    "eslint.enable": true,
    "eslint.validate": [
      "javascript",
      "javascriptreact",
      { "language": "typescript", "autoFix": true },
      { "language": "typescriptreact", "autoFix": true }
  ],
}
```

autoFix は明示的に設定する必要があります。でないと電球が出てきません。

#### 参考

- <https://github.com/Microsoft/vscode-eslint/issues/609>

## Webstorm

未対応のようです。

公式サイトのESLintのページに"Linting TypeScript code with ESLint"というセクションがあるのですが、ラインナップに"@typescript-eslint/eslint-plugin"の記述がありません。

動かす方法をご存知であれば教えてください。

### 参考

- <https://www.jetbrains.com/help/webstorm/eslint.html>

## Webpack

……tslint使っていた方なら書くまでもないですよね。 "eslint-loader" を enforce: "pre" の設定で使ってください。


## Gatsby

ちょうどGatsby使っているので。

gatsby-plugin-eslintを使います。

npmかyarnでインストールして

```bash
yarn add -D gatsby-plugin-eslint eslint-loader eslint
```

設定ファイルをにプラグインを追加します。

```javascript:gatsby-config.js
module.exports = {
  plugins: [
    "gatsby-plugin-sass",
    {
      resolve: "gatsby-plugin-eslint",
      options: {
        test: /\.jsx?$|\.tsx?$/,
        exclude: /node_modules|\.cache|public/,
        stages: ["develop"],
        options: {
          emitWarning: true,
          failOnError: false
        }
      }
    }
  ]
};
```

#### 参考

- <https://www.gatsbyjs.org/packages/gatsby-plugin-eslint/>
PowerShellでアプリの起動と終了をSlackへ投稿

#【Windows】incoming-webhookを利用してバッチファイル経由で投稿します
Windowsで特定のアプリを起動・終了するたびにslackにポスト。
curlとかnkfをダウンロードしなくてもいい方法を考えたけど、そっち使ったほうがバッチファイルのみで処理できます。

```slack.ps1
Param(
    [string]$username,
    [string]$channel,
    [string]$message
)

function Push-Notification($username,$channel,$message) {
   $webhookuri = "https://hooks.slack.com/services/~~~"
   $channel = "#" + $channel
   $text = @{
             text = $message
             channel = $channel
             username = $username
             }| ConvertTo-Json -Compress
   $payload = [Text.Encoding]::UTF8.GetBytes($text)
   Invoke-RestMethod -Uri $webhookuri -Method Post -Body $payload
}
#　>slack.ps1 "ユーザー名" "チャンネル名" "本文"
Push-Notification $username $channel $message
```
実行ポリシーを設定して実行

```hoge.bat
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -command .\slack.ps1 "わいです" "channel" "hogeが起動"
@echo off
call hoge.exe
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -command .\slack.ps1 "わいです" "channel" "hogeが終了"
```

特定のアプリはバッチファイルから起ち上げるようにします
Mysqlでカラム名を検索する

# コマンド

とりあえず、コマンドが分かれば検索できるので最初に書いときます。
※mysqlで動かしましたが他のDBでは動かしてません。

```mysql:sql
select
  *
from
  information_schema.columns 
where
	COLUMN_NAME = "カラム名"
	and table_schema = "データベース名"; 
```
これだけだと、表示されるselectが多いから適宜「*」を変えて検索 

#### 例

検索したいカラム名が含まれるテーブル名を検索したい時

```mysql:sql
select
  table_name, column_name
from
  information_schema.columns 
where
	COLUMN_NAME = "カラム名"
	and table_schema = "データベース名"; 
```

## 名称備忘
#### information_schema.columns

テーブル内のカラムに関する情報を表示してくれる。

以下のリンクが公式のサイト
[mysalServerの公式](https://dev.mysql.com/doc/refman/5.6/ja/columns-table.html)
each内でのrenderパーシャルをcollectionに変更し高速化

##問題

ビュー内で部分テンプレートをeachで呼び出す際に困ったこと。

例)ルート(welcome)画面でピックアップした商品一覧を表示(商品一覧は他の画面でも使うためパーシャル化)

```welcome_controller.rb
 @pickups = Product.all.where.not(pickup_at: nil).joins_i18n(locale_id: @current_lang.id).includes(countries: :country_i18ns).shuffle
```
```welcome.html.erb
    #問題点のみ抜粋
    <% @pickups.each do |p| %>
      <%= render partial: '/shared/products/index_item', locals: { p: p } %>
    <% end %> -->
```
```/shared/products/_index_item.html.erb
<div class="col-xs-6 col-md-3">
  <section class="product_list">
    <%= link_to product_maker_path(id: p.maker_id, product_id: p.id) do %>
      <div class="photo_box">
        <div class="photo_inner photo_contain" style="background-image:url(<%= asset_path p.main_image.thumb %>);" >
          <% p.campaigns.each do |camp| %>
            <div class="cam_lavel"><%= camp.i18n.label %></div>
          <% end %>
        </div>
      </div>
      <div class="pdt_list_ex">
#以下省略
```

<img width="1420" alt="スクリーンショット 2019-02-26 9.50.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/274935/972faced-44c9-a840-051a-994b76912417.png">

eachで回す度にパーシャルファイルを呼んでしまう。
読み込み速度が遅い。。。。。


##解決策

each内ではなく、collectionを使ってパーシャルをrenderする

```welcome.html.erb
 <%= render partial: '/shared/products/index_item', collection: @pickups, as: :p %>
```

パーシャルを呼び出すのは１回。

<img width="1437" alt="スクリーンショット 2019-02-26 9.59.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/274935/6ed3d553-2050-f939-a7d2-55a7dd949ac1.png">
catalyst3560にて設定されているconfigを名前を付けて保存する方法

catalyst3560の設定を名前を付けて保存したかったので、自分用メモとして残します。

最初にdir [保存したい領域]コマンドにて同じ名前が無いか、メモリーは十分に空いているか確認します。
問題ないことがわかったらcfgにて保存
![名前を付けて保存.PNG](https://qiita-image-store.s3.amazonaws.com/0/364683/59ace1ba-d01b-61af-d6d1-548da9197686.png)

中身を確認したいときはmoreコマンドを使用して確認する
![more.PNG](https://qiita-image-store.s3.amazonaws.com/0/364683/9dcc1a79-7af3-a36d-6265-2113f60c84e2.png)

削除するにはdeleteコマンドを使用する
![削除.PNG](https://qiita-image-store.s3.amazonaws.com/0/364683/6288e72e-cb6f-2a7c-0206-570a2781cff9.png)
ansible-playbook でタグ指定でロールの一部を実行したときだけハンドラを実行しない

例えば次のようなプイレブックで、

```yaml
# site.yaml

- hosts: all
  roles:
    - { role: hoge, tags: hoge }
```

hoge ロールの tasks と handlers が次の通り。

```yaml
# roles/hoge/tasks/main.yaml

- name: hoge config file
  copy:
    src: hoge.conf
    dest: /tmp/hoge.conf
  notify:
    - hoge restart

- name: hoge service start
  systemd:
    name: hoge.service
    state: started
    enabled: yes
```

```yaml
# roles/hoge/handlers/main.yaml

- name: hoge restart
  systemd:
    name: hoge.service
    state: restarted
```

このとき、`hoge config file` だけ実行したいけど `changed` でもハンドラは実行したくない、ということがたまにあります。

単に `hoge config file` にタグを付けるだけだとハンドラが実行されてしまうので、タグ指定したときにハンドラが実行されないようにする小ネタ。

---

`hoge config file` にそれっぽいタグを付けて、

```yaml
- name: hoge config file
  copy:
    src: hoge.conf
    dest: /tmp/hoge.conf
  notify:
    - hoge restart
  tags:
    - hoge_config # <--
```

`hoge service start` でそれぽぽい変数を登録します。

```yaml
- name: hoge service start
  systemd:
    name: hoge.service
    state: started
    enabled: yes
  register: hoge_service # <--
```

その変数を条件にハンドラを実行します。

```yaml
- name: hoge restart
  systemd:
    name: hoge.service
    state: restarted
  when: hoge_service is defined # <--
```

タグ `hoge` を指定して実行すれば `hoge service start` によって `hoge_service` が登録されるので `hoge config file` が `changed` ならハンドラが実行されます。

タグ `hoge_config` を指定して実行すれば `hoge config file` が `changed` のときにハンドラが実行されようとしますが、`hoge service start` が実行されないので `hoge_service` が未定義になるためハンドラは実行されません。
MSYS2でansible

# install

インストール時はMinGWではなく、MSYSのターミナル (`msys2.exe`) を起動。

```bash
$ env | grep MSYSTEM=
MSYSTEM=MSYS
```

## Python と pip を入れる
```bash
$ pacman -S python python3-pip

$ python -V
Python 3.7.1

$ pip -V
pip 18.1 from /usr/lib/python3.7/site-packages/pip (python 3.7)
```

## 依存ライブラリ/ツールとansible本体を入れる
```bash
$ pacman -S gcc make libffi-devel openssl-devel libcrypt-devel

$ pacman -S sshpass
$ sshpass.exe -V
sshpass 1.06

$ pip install ansible
### ビルドに1時間くらいかかった

$ ansible --version
ansible 2.7.8
  config file = None
  configured module search path = ['/home/pen/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.7.2 (default, Dec 26 2018, 08:10:46) [GCC 7.4.0]
```

# 動作確認(ローカル)

```bash
$ ansible localhost -m shell -a 'hostname'
localhost | CHANGED | rc=0 >>
gray2

$ ansible localhost -m setup -a 'filter=ansible_distribution*'
localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "MSYS_NT-10.0",
        "ansible_distribution_release": "2.11.1(0.329/5/3)",
        "ansible_distribution_version": "2018-09-10 14:19"
    },
    "changed": false
}
```

# 動作確認

```bash
$ cat inventory
[foo]
host1 ansible_host=xxx.xxx.xxx.xxx
host2 ansible_host=xxx.xxx.xxx.xxx
host3 ansible_host=xxx.xxx.xxx.xxx
host4 ansible_host=xxx.xxx.xxx.xxx
host5 ansible_host=xxx.xxx.xxx.xxx

$ cat ansible.cfg
[ssh_connection]
ssh_args = -o ForwardAgent=yes

$ ansible foo -i ./inventory -m shell -a 'cat /etc/*-release | head -n1' -o
host3 | CHANGED | rc=0 | (stdout) CentOS release 6.10 (Final)
host4 | CHANGED | rc=0 | (stdout) CentOS Linux release 7.6.1810 (Core)
host1 | CHANGED | rc=0 | (stdout) CentOS release 6.10 (Final)
host5 | CHANGED | rc=0 | (stdout) CentOS Linux release 7.6.1810 (Core)
host2 | CHANGED | rc=0 | (stdout) CentOS Linux release 7.6.1810 (Core)

$ ansible foo -i ./inventory -m shell -a 'rpm -qa | grep httpd-[[:digit:]] || true' -o
host3 | CHANGED | rc=0 | (stdout) httpd-2.2.15-69.el6.centos.x86_64
host4 | CHANGED | rc=0 | (stdout) httpd-2.4.6-88.el7.centos.x86_64
host5 | CHANGED | rc=0 | (stdout)
host2 | CHANGED | rc=0 | (stdout) httpd-2.4.6-88.el7.centos.x86_64
host1 | CHANGED | rc=0 | (stdout) httpd-2.2.15-69.el6.centos.x86_64

$ ansible foo -i ./inventory -m shell -a 'rpm -qa | grep ^mysql-.*server-[[:digit:]] || true' -o
host4 | CHANGED | rc=0 | (stdout) mysql-community-server-8.0.13-1.el7.x86_64
host3 | CHANGED | rc=0 | (stdout) mysql-community-server-5.7.24-1.el6.x86_64
host2 | CHANGED | rc=0 | (stdout)
host5 | CHANGED | rc=0 | (stdout)
host1 | CHANGED | rc=0 | (stdout) mysql-community-server-8.0.13-1.el6.x86_64
```

# 備考
過去に試したときは libffi が解決できず、CFLAGSを指定する必要があった。  
`2.7.8` では大丈夫になっていた。

```bash
CFLAGS=-I/usr/lib/libffi-3.2.1/include pip install ansible
```
php-master-changes 2019-02-25

今日はストリームラッパーでの未定義定数による SEGV の修正、break 2147483648 で SEGV を起こす問題の修正、コンパイラ警告の修正、一部テストケースの並列実行対応、getMessage() 等の getter を通して例外のプロパティへアクセスする際に参照だと正常動作しなかった問題の修正があった！

# 2019-02-25
## laruence: Fixed bug [#77664](https://bugs.php.net/bug.php?id=77664) (Segmentation fault when using undefined constant in custom wrapper)
- https://github.com/php/php-src/commit/4a72dd782df3089a0d944a7e51eabebdf1f1abc3
- [7.2~]
- 未定義定数を持つクラスをストリームラッパーに登録して利用しようとすると SEGV を起こす問題の修正

## laruence: Update NEWS
- https://github.com/php/php-src/commit/3b5475e9ee48c27f7164eb1d9cbe873d2704b571
- [7.3~]
- ↑の 7.3 用の NEWS エントリの追記

## laruence: Fixed bug [#77660](https://bugs.php.net/bug.php?id=77660) (Segmentation fault on break 2147483648)
- https://github.com/php/php-src/commit/1c22ace0582fb0a2ec581237fcf1c5b9c41edd04
- [7.2~]
- PHP の break はネストレベルを数値指定することでネストしたループを抜けられるが、`break 2147483648` を指定すると SEGV が起きる問題の修正
- 過剰ボケとかオーバーリアクションに通じる系の笑いでなんかクスっときた

## laruence: Update NEWS
- https://github.com/php/php-src/commit/fb3f078eeb4ecb2de783b7ee936dd583e6285d3e
- [7.3~]
- ↑の 7.3 用の NEWS エントリの追記

## laruence: Fixed compiler warning
- https://github.com/php/php-src/commit/4ac954ac3e1217864e592ebb1531b4f0f31e2264
- [7.3~]
- continue が switch に適用される際の警告メッセージで、フォーマット文字列 "%d" を ZEND_LONG_FMT にしてコンパイラ警告を修正

## nikic: Fix some port collisions in sockets tests
- https://github.com/php/php-src/commit/c937c55d7553a7fa99877998cd6617d9e82c7dd1
- ext/sockets のテストで、テストケース間のポート衝突の修正
- [7.4~]
- 並列実行対応

## nikic: Fix some directory collisions in dir tests
- https://github.com/php/php-src/commit/251e94894694ae8ccaa75a43b574f544f3a8c203
- [7.4~]
- ディレクトリ操作系のテストで、テストケース間のディレクトリ衝突の修正
- 並列実行対応

## nikic: Fix assertion in Exception::getMessage() if $message is a ref
- https://github.com/php/php-src/commit/af37d58cf7b77814b93ea97a8dcd2afb46c4424e
- [7.2~]
- [Exception::getMessage()](http://php.net/manual/ja/exception.getmessage.php) 等での例外の各プロパティへのアクセス時、プロパティが参照である可能性を考慮したコードに修正
- 参照ならデリファレンスするよう ZVAL_DEREF() を足してる
Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? can't activate sqlite3 (~> 1.3.6), already activated sqlite3-1.4.0. Make sure all dependencies are added to Gemfile. (Gem::LoadError)


`bin/rails g ...` する際に `sqlite3` のversion依存関係で怒られたので解決法を調べた。

# 解決方法

```Gemfile.
- gem 'sqlite3'
+ gem 'sqlite3', '~> 1.3.6'
```

```
$ bundle install
```

# 原因
リンク先に詳細が記載されている。
簡潔にいうと、Railsの指定している`sqlite3`のversionは`1.3.x`代
一方で、`sqlite3`自体の最新versionは`1.4.x`代
上記の後方互換性の指定`'~> 1.3.6'`は`1.4.0未満`を指定しているので、
Railsがサポートしている`sqlite3`versionの範囲で後方互換性を留められる。
gem versionによるエラーを避けられる。
- [Railsを始めてsqlite3まわりのエラーで躓いている人たちへ](https://qiita.com/Kta-M/items/254a1ba141827a989cb7)

[rails自体の修正]
(https://github.com/rails/rails/commit/6d5f2511e6d9b95a8ac8399c234aa6cd074af51d)

[>=の意味](https://qiita.com/homhom_star/items/0a401a1075060fe2de4b)
MakefileとCMakeでout-of-sourceをしてみる。

# 概要

Makefileでout-of-sourceしてるプロジェクトがあったので、cmakeに以降したらどれだけ楽になるのか試してみました。
CMakeの出力先の指定がまだわかってないので、わかり次第修正します。

Github : [maruwo/make](https://github.com/maruwo/make.git)

## 構成

- wsl ubuntu 4.4.0-17134-Microsoft
- cmake version 3.10.2
- GNU Make 4.1
- gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

## 各ディレクトリの概要

- lib
    - 独自ライブラリ

- app1
    - ソースファイルを指定してのビルドする
    - 独自ライブラリを使用する

- app2
    - ディレクトリ配下すべてをビルドする
    - 独自ライブラリを使用する


## Makefile

- 出力ディレクトリ
    - dir/build

- コマンド実行ディレクトリ
    - dir/

### 実行手順

```
make
```

### ツリー

```
 dir
  ├ Makefile
  ├ common.mk
  │
  ├ app1
  │  ├ Makefile
  │  └ app1.c
  │
  ├ app2
  │  ├ Makefile
  │  └ app2.c
  │
  └ lib
     ├ Makefile
     ├ mylib.c
     └ mylib.h
```


### 呼び出し順

1. dir/Makefile
2. dir/lib/Makefile
3. dir/common.mk
4. dir/app1/Makefile
5. dir/common.mk
6. dir/app2/Makefile
7. dir/common.mk


`dir/Makefile`では各ディレクトリを指定しています。
指定されたディレクトリ配下のMakefileでビルドを行うよう、-Cオプションディレクトリを指定してmakeします。

次に、各ディレクトリに入り、その中のMakefileが実行されます。
各ディレクトリのMakefileは基本的な部分に関しては同じものとなっていますが、フラグ関連を独立して持てるように分けています。

各ディレクトリのMakefileでは`./common.mk`をincludeして実行します。
`./common.mk`は実際のビルド処理を記載してあります。


### out-of-sourceのやり方

`./common.mk`に記載されてあるビルド手順で、ファイル名だけではなく、ディレクトリ名も含めてビルドしています。

```Makefile.一部抜粋
OBJS   := $(SRCS:%.c=$(OBJDIR)/%.o)
DEPS   := $(OBJS:%.o=$(OBJDIR)/%.d)
TARGET := $(TAGDIR)/$(TAGNAME)

$(OBJDIR)/%.o: %.c
	@mkdir -p $(dir $@)
	@$(CC) $(CFLAGS) -c $< -o $@ 

$(TARGET): $(OBJS)
	@mkdir -p $(dir $@)
	@$(CC) $(OBJS) -o $@ $(LDFLAGS)
```



## CMake

- 出力ディレクトリ
    - dir/build

- コマンド実行ディレクトリ
    - dir/
    - dir/build


### 実行手順

```
mkdir build
cd build
cmake ..
make
```


### ツリー

```
 dir
  ├ CMakeLists.txt
  │
  ├ app1
  │  ├ CMakeLists.txt
  │  └ app1.c
  │
  ├ app2
  │  ├ CMakeLists.txt
  │  └ app2.c
  │
  └ lib
     ├ CMakeLists.txt
     ├ mylib.c
     └ mylib.h
```

### out-of-sourceのやり方

参考
[CMake : out-of-sourceビルドで幸せになる](https://qiita.com/osamu0329/items/7de2b190df3cfb4ad0ca)

cmakeを実行するディレクトリをトップから移動することで対応している。


## まとめ

Makefileは記述が難しいが、トップディレクトリでmake一発でビルドできるので、運用が始まればあまり問題でもない？
小規模プロジェクトを短期間でやるにはMakefile作るのがめんどそう。
Makefile独自の変数($@など)が分かりづらい。

CMakeではトップディレクトリから１段下でmakeを実行するため、やる人によっては煩わしい？
（その辺はCIやらスクリプトで対応可能なのでなんとも言えないが。）
ビルドの進捗なども%表示され、出力もカラーとなるので、結果が見やすい。

個人的にはカラー表示や記述のしやすさでcmakeの方が良かった。



## 課題

- CMakeの出力がMakefileと同じにならない。
    - 最終出力のバイナリがbuildの各ディレクトリの配下にできてしまう。
- autotoolsとの比較
Error: qt@5.5: unknown version :mountain_lion

# 解決方法

`$ source ~/.bash_profile` を実行するとタイトルのエラーを出力したので解決方法を調べた。

```
cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git checkout 9ba3d6ef8891e5c15dbdc9333f857b13711d4e97 Formula/qt@5.5.rb
cd Formula/
grep mountain -rl ./
vi ./qt@5.5.rb
```
```qt@5.5.rb
25 - depends_on :macos => :mountain_lion
25 + # depends_on :macos => :mountain_lion
```

# 参考
- [Error: qt@5.5: unknown version :mountain_lion
](https://stackoverflow.com/questions/54499893/error-qt5-5-unknown-version-mountain-lion)

- [【find・grep】特定の文字列を含むファイルのリストを取得する方法。
](https://qiita.com/pokari_dz/items/0f14a21e3ca3df025d21)
【最新サービス試用④】Gitの差分を視覚的に楽しめて、イメージの手助けとなる、「Git History」を試用

- 日々輩出される素晴らしき最新サービスを素早く試して、不鮮明な先見性を堂々と誇示する記事第四弾。 
- あるドラマでの、「真似事でも、必死で見習えば、それは本物だから」という刺激的名言を、「山盛り解釈・少々捏造」の行為で、大量模倣の許可を得たと被害妄想。
- 今回は、GitHubの差分が、視覚的に楽しく把握できる「GitHistory」を試用することにしよう。

## 試用サービス名
### 「[Git History](https://github.com/pomber/git-history)」

## 概要
- 把握しづらい差分を、視覚的に動きをつけて表示してくれる。
- コミッターやメッセージも非常に見やすい。
- インストール不要で、GitHub上でURLを変えるだけでよい。
- 初学者がイメージをつかむのに適している

## 結果
- 下記の例は、GitHub上の「[Vue.js](https://github.com/vuejs)」の[package.json](https://github.com/vuejs/vue/blob/dev/package.json)ファイル
- バージョンの変化が把握できる。

![tes.gif](https://qiita-image-store.s3.amazonaws.com/0/336499/b598f105-f95c-0850-f3f4-8b772f99d987.gif)

## 基本手順
### 1. [GitHub](https://github.com/)へ行く。
### 2. 差分を表示したいファイルを開く。  
※GitHubアカウントを持っていない場合は、気になるオープンソースプロジェクトのファイルでも良い。  
※[GitHubのスター数（評価数）ランキングはこちら](https://github.com/search?utf8=%E2%9C%93&q=stars%3A%3E1)。
### 3. ファイルのURLを下記のように変更
※例では、「[Vue.js](https://github.com/vuejs)」の[package.json](https://github.com/vuejs/vue/blob/dev/package.json)を使用。

```
＜変更前＞ : https://github.com/vuejs/vue/blob/dev/package.json

＜変更後＞ : https://github.githistory.xyz/vuejs/vue/blob/dev/package.json
```
- 例のように、URLの「github.com」の部分を、「github.githistory.xyz」へ変更

### 4. 表示確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/314366af-750a-2c7b-2973-0fc426b9c5e0.png)

### 5. 左右矢印キーで、差分確認
※だいぶ奥深くでの変更等はわかりづらい。

### 6. 差分を詳細に見たい場合は、コミッター欄のリンクで、確認。
※各コミットファイルへアクセスできる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/6c322fa1-454f-ac70-4e93-84be442f96d7.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/212cd10e-7773-6c97-1938-fa64f32dc5ca.png)

### 7. 完了

## 試用感
- 差分を視覚的なアニメーションで楽しめる。
- 奥深くの差分や多くの量等の、一発では把握しにくいものもある。
- しかし、各個別の差分ファイルへのリンクがあるので良い。
- Git環境がなくても、簡単にできる。
- 初学者がGitの概念やイメージを把握しやすい。

## まとめ
- 今回は、差分表示の視覚的把握ということで、「将来、散髪や化粧・体重変化等が、鮮やかに把握できる視覚機器が出ないかな。」という、高等級男性の特徴的行動までも自己解決しない、底辺等級人の私。
- 「今回もJavaScript製とはね」という、この言語の多様性・可能性を身に染みて再認識。
- 試用後の恒例行事の「開発者への礼拝作業」に、今回は「全開発者への魅力サービス開発祈願」という、本来の意味を大きく逸れた礼拝を追加することにしよう。

## 参考
- https://www.moongift.jp/2019/02/git-history-%E3%83%93%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%AB%E7%9A%84%E3%81%AA%E5%B7%AE%E5%88%86%E8%A1%A8%E7%A4%BA/  
→こちらの紹介記事で知りました。毎度毎度大変お世話になっております。今回もありがとうございました。
ruby on rails でアンカーを付けてページにパラメーターを送るやり方

セレクターで選択した項目をそのまま保持してページ遷移した後もその項目に戻りたい時ってありますよね？

railsの場合、アンカーをサーバーに保存出来ない仕様なようで、そのまま`anchor`に記載するだけではコントローラーで`params`で取得はできません。

そこで取得したアンカーをajaxで送るようにしましたが、なぜかコントローラーには届かないようです（ajax通信は成功しているがコントローラーには反映されない）。

```
<!--<%# selector_view %>-->
<%= link_to '撮影', new_user_index_picture_path(@user, index.id, :anchor => #{@anchor1/@anchor2}) %>
```

```js
//ここからselector_viewから受けたアンカーをコントローラー側に渡す

		anchor = decodeURIComponent(location.hash);
		hash_split = anchor.split("/");
		var anchor1 = hash_split[0];
		var anchor2 = hash_split[1];
		$.ajax({
		    url: "/users/" + gon.user_id + "/indices/" + gon.index_id + "/pictures/new",
		    type: "get",
		    data: {
		    	   anchor1: anchor1,
		    	   anchor2: anchor2,
		    	  },
		    processData: false,
            contentType: false,
            datatype: "text",
		    success: function(data){
                    alert("success");
		    },
		    error: function(jqXHR, textStatus, errorThrown){
  		    alert(textStatus);
    		    alert(errorThrown.message);
    		    alert(jqXHR.status);
    		    alert(jqXHR.responseText);
    		    },
		});
```
こんな感じです。

何故かはわかりませんでしたが、他の方法を教えてもらいました。

```erb
<!--<%# selector_view %>-->
<%= link_to '撮影', new_user_index_picture_path(@user, index.id, params: { anchor1: @anchor1, anchor2: @anchor2 }) %>
```
上記のようにパスに`params`を付けることでコントローラーで値を取得できました。
Gitの大きいリポジトリを小さくする方法

`git gc`だけだと二週間がデフォルトなのですぐに消えない。
`now`をつけて即時削除する。

```
$ git reset HEAD
$ git reflog expire --expire=now --all
$ git gc --aggressive --prune=now
```
参考： https://blog.clock-up.jp/entry/2017/12/03/git-gc

これで`.git/`容量が 1.2GB -> 5.7MB になった。
【Python】PyPIエラー対応 User (username) has no verified email addressesの対処法

# 発生したエラー

`twine`を使って、PythonパッケージをPyPIに登録しようとしたところ、

`HTTPError: 400 Client Error: User '(username)' has no verified email addresses`

のエラーとなる。

```
$ twine upload --repository pypi dist/*
Enter your username: (username)
Enter your password: 
Uploading distributions to https://upload.pypi.org/legacy/
Uploading (packagename)-1.0.0-py3-none-any.whl
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 11.4k/11.4k [00:01<00:00, 9.14kB/s]
NOTE: Try --verbose to see response content.
HTTPError: 400 Client Error: User '(username)' has no verified email addresses, please verify at least one address before registering a new project on PyPI.See https://pypi.org/help/#verified-email for more information. for url: https://upload.pypi.org/legacy/
$
```

# 対処方法

原因は、PyPIアカウント登録時のメール認証実施漏れ。

PyPIアカウント登録時に登録したメールアドレスに、PyPIからのメールが届いているはずなので、そのメール本文の`click this link to verify your email address`をクリックしてください。

このメール認証を行わなくてもPyPIのサイトへのログイン等はできるのですが、パッケージを登録しようとすると上記のエラーになってしまいますので、忘れずにメール認証しておいてください。

# 環境

- Python 3.6.6
- twine 1.13.0
とあるエンジニアの問題意識 2019-02-25

# ポートフォリオに人間性を。

# 本当に体力がないエンジニア。
繊細すぎて困る。俺です。睡眠は命より大事。昼休みがないと死んでしまう。残業は大ダメージ。聴覚過敏で音にも弱い。とにかくあらゆる刺激やストレスが命取り。指で触られるだけで潰せると思う。そんな僕でも会社員を3年半やってられるのが奇跡かもしれない。 
# 人間は苦労したことに価値を感じやすい。直感に事実が反する。

この働きはあまりに強力。体感レベルで圧倒的な真実。

だが100倍苦労した事は100倍効率が悪いことかもしれない。100倍楽な事は100倍価値があるかもしれない。呪いを解くにはひたすら脳に言い聞かせる。反直感。

仕事 エンジニア <https://t.co/yfx9brGWiK> 
# 会社と社員は契約関係。取引先だ。

会社員の場合は圧倒的に情報のイニシアチブを会社が握っている。当たり前だが市場原理が働く。買い手は仕入値を最低限に抑えようとする。ここで自動的に洗脳の原理が働いてしまう。

個人の対抗策は何か。仲間作り。Twitterなどで判断材料の仕入れ。

エンジニア <https://t.co/PVkQsEB2HG> 
# Twitterの中の人が存在するか存在しないか。どちらでも良い。情報の種類にもよるが。

ツイートの一個ずつを思索の種にして自分の血肉にする。僕の目的はそれ。

もし存在非存在で価値が大きく変わるような情報摂取のやり方なら。自分自身が踊らされている可能性が高い。

エンジニア <https://t.co/SN5KLFkmVE>

# 低エネルギー戦略と高エネルギー戦略。
これを間違うとやばい。高エネルギーの人の戦略は低エネルギーの人には役立たない。そしてエネルギー状態は個人単位でも千差万別に変わる。高エネルギーな昨日の戦略は低エネルギーな今日には役立たない。たとえばの話。

# 低エネルギー戦略。
Qiitaで記事を呼んだ。人間は年を取ると学習効率か何かがガタ落ちすると。その下降曲線を見て戦慄した。僕の場合、昔から低エネルギーだ。体からエネルギーが溢れる感覚を覚えることがほとんどない。低エネルギー状態にはなかなかの親しみがある。たとえ曲線の最底辺でも動ける知恵を持っておきたい。

# プログラミングの手の速さ。
これは物理的なタイピングスピードに比例する部分がある。とにかく速い打鍵に体を慣らしなさいという教えがある。だが僕の場合はとにかく手が不器用だ。#脊柱管狭窄 のせいもあるのか最近手が動きにくい。なので脳の中で思考の手を動かす哲学モードを使う。どうにか自分の武器を使っていきたいものだ。

# 低エネルギー戦略。
昨日あれだけ低コスト・低刺激でエネルギーを保全したはずなのに何故か今日も極めて低エネルギーだというとき。エネルギー管理と実状に矛盾を見出すとき。逆に考える。昨日はあらゆる無限の対策をしなければならぬほどそもそも低エネルギーだったのだと。人生はだいたい逆説が真実。最近の座右の銘。

# 低エネルギー戦略。
5分だけ冷たい風に当たりながら遠くの景色を眺める。軽いストレッチをする。かなり体が癒された。だが根治ではないだろう。応急処置と根管治療を間違えてはいけない。まあ根本の問題は #睡眠 だろうなと思う。休日に長時間寝るのは賭けだがやってみようか。

# 月曜日は特に低エネルギーなことが多い。
誰でも同じようなものかもしれないが。午前から昼に向けてじわじわとエネルギー状態が高まる。ここで人は何か具体的な理由を探してしまうが真実は分からない。むしろ単に時間帯の推移による自然なバイオリズム的変化が大きいと思う。波には逆らえない。僕らは乗るだけ。

# デジタルワークの一番の敵が注意残余であるような気がしてきた。
たぶん当たっている。注意残余も必要だからこそ人間に備わっている。強烈な本能だ。もしこれがなくては一瞬でさっきまでの物事を忘れ外敵から実を守るのは難しいだろう。だが本能が現代的働き方にマッチしない。強すぎる働きだ。

# 生産性に関して価値観が似ている人とは働きやすい。
エンジニアリングは短距離走だ。時速1kmの生産性の悪い状態で8時間走り続けるよりも、時速100kmで1時間だけ走った方が遠くまで進める。ここで同意が取れる人でなければ一緒に働くのは難しい。まだ工業化時代の単一的な指標に溺れているエンジニアがいたらむしろ驚く。

# 耳栓にもいろいろな種類がある。
遮音性能のレベル自体はそこまで変わらないようだが高音域に強いものや低音域に強いものなどあるようだ。MOLDEXという耳栓の第一人者的ブランドのものを何種類か試す。違いがあるようでないようで。まだよく分からないけれど。

# 昼休み頃。
朝の死にかけていた体が変わる。エネルギー状態が変わるだけで全く別人になる。低エネルギーに取り込まれている時は絶対にそこから這い上がれないだろうと思う。高エネルギーに押し上げられている時は絶対にそこから滑り落ちないだろうと思う。だがそんなことはない。世界が変わる。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/633








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Swift：自作のCommand Line ToolでCSVファイルを読み込む方法

# Command Line Tool
iOSアプリしか開発しない人には縁がないかもしれませんが，Xcodeで新規プロジェクトを作る際，Command Line Toolのテンプレートを選択するとCUIベースのソフトウェアを作ることができます．普段からSwiftを使っていて，CSVの加工とかちょっとした文字列の加工処理などをしたいけれど，大きなGUIプロジェクトを立ち上げるほどでもないという状況にもってこいなので，どんどん使っていきましょう．今回はCommand Line ToolでCSVファイルを読み込むところまでを記述します．

# プロジェクト立ち上げ
Xcodeの`File` -> `New` -> `Project...` -> `macOS` -> `Command Line Tool`から立ち上げられます．野良の`.swift`ファイルを作ってVS CodeとかAtomとか外部のエディタでガリゴリ書いても良いのですが，やはりXcodeの強力な補完の恩恵は惜しいですからね．

# 実装
今回はこちらのダミーCSVファイルを読み込むこととします．
一行目は各列の項目名になっています．

```plaintext
valueA,valueB,valueC
1,3.14,pi
2,2.718,e
3,1.414,square root 2
```

それでは`main.swift`ファイルを編集します．

```swift:main.swift
import Foundation

struct Dummy {
    let a: Int
    let b: Float
    let c: String
    
    init(_ a: Int, _ b: Float, c: String) {
        self.a = a
        self.b = b
        self.c = c
    }
    
    var description: String {
        return "a: \(self.a), b: \(self.b), c: \"\(self.c)\""
    }
}

let input = FileHandle.standardInput
var data = [Dummy]()

func scan() -> String {
    let text = String(data: input.availableData, encoding: String.Encoding.utf8) ?? ""
    return text.trimmingCharacters(in: CharacterSet.newlines)
}

func main() {
    let filePath = scan()
    guard let file = try? String(contentsOfFile: filePath, encoding: String.Encoding.utf8) else { exit(0) }
    var first: Bool = true
    file.enumerateLines { (line, stop) in
        if first {
            first = false
        } else {
            let item = line.components(separatedBy: ",")
            data.append(Dummy(Int(item[0])!, Float(item[1])!, c: item[2]))
        }
    }
    data.forEach { (dummy) in
        Swift.print(dummy.description)
    }
}

main()
```

まず，CSVファイルに合わせて`Dummy`という構造体を用意しました．
`scan()`メソッドは標準入力を受け付けて改行を入力すると文字列を返します．
\main()`メソッドではCSVファイルの中身をUTF-8で読み込んで一行ずつ処理を行い，Dummyのデータを配列に追加し，最終的に出力しています．

# 実行
XcodeでRunしてもいいのですがXcodeのdebugエリアへの標準入力は文字が不可視となることがあり不安定なので，Terminal.appでmain.swiftを実行します．

```plaintext:Terminalコンソール
$ cd ~/Desktop/CommandLine/CommandLine/  <-- [main.swiftが入っているディレクトリのパス]
$ swift main.swift
./dummy.csv                              <-- [CSVファイルのパス]
a: 1, b: 3.14, c: "pi"
a: 2, b: 2.718, c: "e"
a: 3, b: 1.414, c: "square root 2"
$
```

CSVファイルをmain.swiftと同じディレクトリに入れておくと，ファイル指定が楽ですね．
ちなみに，コマンドライン引数をとりたい時は[こちらの記事](https://qiita.com/Kyomesuke3/items/06ad45e214d5305135f9)を参考にしてみてください．
『Google Apps Script 完全入門』を買って基礎入門①

今回はタイトル通り、
GASの記述ルールやお作法、変数、定数、型、配列や演算子など様々な基本を複数回に分けて書いていきます！


以下様々なGASの記事を紹介してます！
https://bzbot.work/

##紹介記事
今回紹介している記事は以下です！
https://bzbot.work/2019/02/25/gas-superbeginner/

##1.GASの超基本
GASを利用するにあたり、最低限覚えておいたほうがいい使用上のルールがあります。

###スクリプト実行時間
無料のGoogleアカウントの実行時間は6分 / 実行で、スクリプトの実行の際にこの制限を越えると、スクリプトはエラーとなって終了しちゃいます。
なので扱うデータ量が多かったり、処理速度を意識しないといけません！（笑）

ただ、6分の壁を越える処理を記述する方法もあるようなので、今後やってみたいなぁーと思ってます。

###記述のルール
```
1.英数字、記号は全て半角で入力
2.アルファベットの大文字と小文字は区別される
3.初めて実行するスクリプトは都度『承認』が必要
4.ステートメント *1 の末尾にはセミコロン（;）を付ける
5.識別子 *2 は先頭文字は数字、一部アンダースコア、ドル記号（$）をのぞいて記号は使えない
6.予約語 *3 は使えない
7.変数と関数名にはキャメル記法 *4、定数名にはスネーク記法 *5を使用

*1 ステートメント…処理の最小単位の事
セミコロンがなくても自動でステートメントを判断して処理されるけど、絶対ではないので非推奨です！
*2 識別子…変数、定数、関数などの事
*3 予約語…すでに特別な意味を持つ単語として定められているものの事（var や function など）
*4 キャメル記法…単語を連結した時に、2つ目以降の単語の頭文字を大文字にする記法（maxRow など）
*5 スネーク記法…単語をアンダースコア（_）で連結しつつ全てを大文字にする記法（TAX_RATE など）
```

##2.記述準備

###エディタ表示方法
『ツール』の中にある『スクリプト エディタ』を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/363116/46751c5b-df60-b705-4309-0c4d6e68ab45.png)

###コードの記述場所
![image.png](https://qiita-image-store.s3.amazonaws.com/0/363116/fbec1606-72c5-6f22-69f8-460c87b98e3d.png)


##3.変数と定数
###変数
スクリプト上で実行する為に必要な数値、文字列、オブジェクトなどのデータを格納する『データの箱』のことです。変数を使うことで、データを一時的に保管したり、データをわかりやすい名称で取り扱うことができます。

例えば以下が変数です。

```javascript:GAS
function myFunction() {
/*
*変数の値は基本上書きが可能
*/

//numという変数に『12345』という数値が入ってます
var num = 12345;
Logger.log(num);

//strという変数に『Hello ビジボット』という文字が入ってます
var str = 'Hello ビジボット';
Logger.log(str);

//numに1という値を上書きする
num = 1;
Logger.log(num);
}
```
ログ結果はこんな感じ。

```
[19-02-25 01:47:46:598 JST] 12345.0
[19-02-25 01:47:46:598 JST] Hello ビジボット
[19-02-25 01:47:46:599 JST] 1.0
```

###定数

変数は上書きが可能でしたが、上書きによる変更をさせたくない時があります。（例えば消費税とか）
そのような場合には『定数』を使います。定数は変数同様、名前を付けられる『データの箱』として使用できますが、一度値を格納したら値の上書きをすることができません。

例えば以下が定数です。

```javascript:GAS
function myFunction() {
/*
*定数の値は上書きが不可能
*/

//TAXという定数に『1.08』という数値が入ってます
const TAX = 1.08;
Logger.log(TAX);

//SITE_NAMEという定数に『ビジボット』という文字が入ってます
const SITE_NAME = 'ビジボット';
Logger.log(SITE_NAME);

//TAXに1.10という値を上書きする記述をしてみる...
TAX = 1.10;
Logger.log(TAX);
}
```

ログはこんな感じ。

```
[19-02-25 01:54:22:985 JST] 1.08
[19-02-25 01:54:22:986 JST] ビジボット
[19-02-25 01:54:22:986 JST] 1.08
```


他にも結果は以下サイトで載せてます！
https://bzbot.work
gsubで文字列変換



## gsub
gsubは、パターンにマッチした文字列を置き換えたい時に使います。
また、パターンには、正規表現が使えます。

使い方

```
文字列.gsub(パターン, 置き換え後の文字)
```

```rb
phone = '090-1234-5678'
phone.gsub(/-/, '')
``` 
結果

```rb
=>  "09012345678"
```

####＊ 2019/2/27追記
コメント欄にて、@scivolaさんにアドバイス頂いたので追記です！
単純な削除はString#deleteの方が良いとのこと。

```rb
phone = '090-1234-5678'
phone.delete('-')

=> "09012345678"
```
benchmark_driverというgemでベンチマークするとgsubよりdeleteの方が速いらしいです。
ベンチマーク載せた方が良い記事書けそうですね。勉強になりました。

## gsub!
gsubと同じですが、破壊的メソッドです。

```rb
phone = '090-1234-5678'
phone.gsub!(/-/, '')
``` 
実行した時の返り値もgsubと同じ

```rb
=>  "09012345678"
```
破壊的メソッドなので、レシーバであるphoneの中身も返り値と同じになります。

```rb
print phone
```
結果

```rb
=>  "09012345678"
```

## ブロックを使ったgsub

gsub、gsub!は、パターンにマッチした文字列をブロックに渡して加工出来ます。
ブロックを使うとどんな文字列にも加工できそうです。


```
文字列.gsub(パターン) { |ブロック| 処理 }
```

試しにスネークケースで書かれた```hello_world```の先頭のhと_の後ろのwを大文字にしてキャメルケースの```HelloWorld```にしてみましょう。



```rb
snake = 'hello_world'
snake.gsub!(/^.|(?<=_)./) { |camel| camel.upcase } # 先頭と_の後ろを大文字にします
snake.gsub!(/_/, '') # _を削除します
```
結果

```rb
=> "HelloWorld"
```

例題だとgsubじゃなくてscanとかでも出来そうですが、scanはまたの機会にまとめます。

参考
https://www.sejuku.net/blog/14685#gsub-3
https://www.sejuku.net/blog/60033
ハッシュ値を使ってディレクトリ内の変更を確認するshell script

1. ディレクトリ内のファイルを確認
================
```bash
   ~ $ cd /media/test/
   /media/test $ ls -1
   japan.wav  tone.wav  voice.wav
```

2. ファイルをアルファベット順にリスト化する
================
```bash
   /media/test $ ls -1 /media/test |sort |sed 's/^\(.*\)$/"\1"/g' > /media/file_list
   /media/test $ cat /media/file_list 
   "japan.wav"
   "tone.wav"
   "voice.wav"
```

3. ファイルごとのハッシュ値を求める
================
```bash
   /media/test $ cat /media/file_list |xargs sha1sum > /media/cache_list
   /media/test $ cat /media/cache_list
   2a81a44333cd78a4011131d7988682129499b5ab  japan.wav
   f6f9e50fe7414c8618a9a4a71172072b6915b060  tone.wav
   0a22fa706661d01348569199a68c37aa5373f3c3  voice.wav
```

★ハッシュ値はデータの中身が一つでも違うと異なる値になる


4. 一つのハッシュ値を求める
================
```bash
   /media/test $ sha1sum /media/cache_list |sed 's/\s\s*\/.*$//g' > /media/cache
   /media/test $ cat /media/cache
   5caaff923034a87e3416542c95608b17693bde0b
```

5. ディレクトリ内の変更を確認するスクリプト
================
4.で求めたハッシュ値が前回と異なっていれば変更アリ。同じであれば変更ナシとなる。

```bash
#!/bin/sh

# $1 - 前回のハッシュ値

TEST_DIRECTORY="/media/test"
FILE_LIST="/media/file_list"
CACHE_LIST="/media/cache_list"
CACHE="/media/cache"

cd $TEST_DIRECTORY

ls -1 $TEST_DIRECTORY |sort |sed 's/^\(.*\)$/"\1"/g' > $FILE_LIST
cat $FILE_LIST |xargs sha1sum > $CACHE_LIST
sha1sum $CACHE_LIST |sed 's/\s\s*\/.*$//g' > $CACHE

cd

EXPECTED_CACHE=$1
CURRENT_CACHE=`cat $CACHE`

if [ "x${EXPECTED_CACHE}x" = "x${CURRENT_CACHE}x" ]
then
	echo "Up-to-date"
else
	echo "Need to update"
fi
```

実行結果
============

```bash
   ~ $ /media/./test.sh 5caaff923034a87e3416542c95608b17693bde0b
   Up-to-date
   ~ $ /media/./test.sh aaa
   Need to update
```


参考
ls -1: https://kazmax.zpp.jp/cmd/l/ls.1.html
xargs: https://www.atmarkit.co.jp/ait/articles/1801/19/news014.html
sortコマンド: https://eng-entrance.com/linux-command-sort
sedコマンド: https://hydrocul.github.io/wiki/commands/sed.html
ハッシュ値：　https://eng-entrance.com/linux-command-sha1sum
tableview auto layoutのcellでreloadや遷移のタイミングでscrollのpositionがずれる

言葉じゃ伝えづらいので絵にしました。（力作）

![スクリーンショット 2019-02-26 3.27.46.png](https://qiita-image-store.s3.amazonaws.com/0/97817/9a273636-9c3a-0299-8b5e-864e7a91b899.png)

こんな感じでauto layout使用した可変の、それぞれの高さがだいぶ違うcellがあったとき。
上だとAのcellは300にもなるけどBは40みたいなとき

このとき画面遷移やreloadをするとcellがずれる事案が起こりました。。（力作2）

![スクリーンショット 2019-02-26 3.27.40.png](https://qiita-image-store.s3.amazonaws.com/0/97817/e69b6ab0-8a40-c112-9416-53cab60ba97c.png)


## なぜこうなる

どうやらestimatedHeightで決め打ちの高さを決めてもそこからサイズが離れすぎると起こる模様。

cellの高さを持ってあげて、estimatedHeightでそれらをしっかり返してあげればOK

```HogeViewController.swift

    private var cellHeightsDictionary: [IndexPath: CGFloat] = [:]

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        self.cellHeightsDictionary[indexPath] = cell.frame.size.height
    }
    
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height =  self.cellHeightsDictionary[indexPath] {
            return height
        }
        return UITableView.automaticDimension
    }
    
```
Vue.jsのフレームワーク

#はじめに
まずVue.jsに取り組もうと思った理由としては，友人とのプロジェクトの際にフロント開発をVue.jsを用いて開発していこうという話になったからである．名前は聞いたことはあるけど，使ったことはないし，jQueryとの違いも理解していないため，そこもとりあえず抑えていけるようにしていきたい．
また今回の課題の一つとしてはVue.jsのフレームワークである，"ElementUI"と"Vuerify"についても調べていき，今回の実装に関してどちらを用いるかまで検討していきたい次第である．

##Vue.jsについて
まずjQueryはセレクタ操作に特化したものであるため，HTMLの一部を少し弄る分には十分すぎる機能を持っている(そこまでしっかり使ったことはないため，そんな感じなのか，みたいなイメージです笑)．ただし，複数UIを連携させる場合などは，セレクタ操作であるため同期の面で困難が生じる．簡単な処理をする分には，低コストでの実装できるため，そこまでこだわる必要もないイメージを感じた．

次に肝心のVue.jsについてだが，仮想DOMを構成することにより，JSとHTMLを紐づけている様子．したがって，データ変更に対して勝手に表示するようになるため同期させる処理を書かなくてもよくなる．更新が多いページや状態管理が頻繁に起こるページなどに向いている．

##実際のコーディングの違い
実際のコーディングがどうなるのか，簡単なもので考えていく．

###jQuery
```HTML:HTML
<div>
  Hello <span id="message">World</span> !
  <button id="update">change</button>
</div>
```

```JavaScript:JavaScript
$(document).on('click', '#update', function() {
  $('#message').text('jQuery')
})
```

変更する部分をタグで囲むことによって，そこにJavaScriptを適用するようにしている．

###Vue.js
```HTML:HTML
<div id="app">
  Hello {{ message }} !
  <button @click="update">change</button>
</div>
```

```JavaScript:JavaScript
new Vue({
  el: '#app',
  data: {
    message: 'World'
  },
  methods: {
    update() {
      this.message = 'Vue.js'
    }
  }
})
```

変化させたい部分を変数として持っておく．
`@click="式・メソッド"`とかくと，jQueryの`$(element).on('click', ...)`と同じ動きをする．

##まとめ
Vue.jsについてはもう少し詳しく調べる必要がある．とりあえずはVue.jsの[公式ページ](https://jp.vuejs.org/v2/guide/)に記載．

#フレームワーク
本題としてフレームワークである"Element"もしくは"Vuetify"のどちらかを用いたい．
したがって，まずはフレームワークについてまとめる

##Element
フレームワークの一つであり，昔から使われているもの．コンポーネントを定義し，HTMLに記述することで利用することができる．コンポーネントにより，機能とUIを分離・再利用できるようになる．

###導入
`vue-cl`を使ってVue.jsをプロジェクトの準備をする．まずはグローバルにて`vue-cl`をインストールする．

`npm install -g vue-cli`

webpackベースのプロジェクトを作成する．

`vue init webpack my-project`

最終的に，`./my-project/`ディレクトリが作成され、Vue.jsがインストールされる．
そのままプロジェクトに含まれるパッケージ群もインストールしておく．

`cd my-project
npm install`

次に，待望のElementをインストールする．

`npm install element-ui -S`

これで利用可能となるため，`my-project/src/main.js`以下でElementを読み込み日本のロケールをセット，ElementのCSSをを読み込む．

```
import Vue from 'vue'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'
import 'element-ui/lib/theme-default/index.css'
import App from './App'

Vue.use(ElementUI, {locale})

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})
```

ここまでで準備が整ったため，`my-project/src/App.vue`でコンポーネントを利用することでElementを使うことができる．

###まとめ
簡単な機能などは，特に苦労することなく実装することができそうである．


##Vuetify
マテリアルデザインが浸透してきた現在でこそ，Vuetifyも最近使われてきている．VuetifyはVue.jsで使われるマテリアルデザインをベースとしたCSSのフレームワークである．ちなみに，同様のものとしてVue Materialもあるようだが，どうやらVuetifyの方がドキュメントの見やすさの点で優れている様子．

###まとめ
どうやら，マテリアルデザインが主流となってきている現状，どうやらVuetifyの方がよく使われるそうである．
引き続きそれぞれの利点や実際に使って見た感想などを見ていきたいところである．
git pushでsimpleでもcurrent

「`push.default = current` は楽だけど、ちゃんと tracking 設定したいなぁ。でも `push.default = simple` でいちいち `-u` つけるのは面倒だなぁ。」という人向けに zsh で `-u` 付きのコマンドを提案するようにする。

```shell
$ git push
git push -u origin feature/foo-bar is correct? [n,y,a,e]:
```

`.gitconfig` の alias で設定したいけど、 git のコマンドは存在するコマンドを上書きさせてくれないので zsh で変更する。

まず、 `setopt correct` や `correct_all` で修正を提示する感じをシミュレーションする。 `SPROMPT` にフォーマットが入っているので、 `read` で聞いて 0 から 3 の数値を返す。

```zsh
function ask_ynae {
	local prompt=${SPROMPT/\%r/$1}
	while true; do
		read -rsk \?"$prompt" ynae
		case $ynae in
		[Yy] ) return 0 ;;
		"" | [Nn] ) return 1 ;;
		[Aa] ) return 2 ;;
		[Ee] ) return 3 ;;
		esac
		echo -ne "\r"
	done
}
```

実際に git をラップする部分。 `\git` のようバックスラッシュを使うと、置き換え前のコマンドを使える。組み込みの `print` コマンドは `-z` で次の編集中のコマンドにできる。

```zsh
function in_git() {
	[[ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = "true" ]]
}
function wrapped_git() {
	if [[ "$*" = "push" ]] && in_git && ! (\git rev-parse --abbrev-ref @{upstream} >/dev/null 2>&1); then
		suggest="push -u origin $(\git rev-parse --abbrev-ref HEAD)"
		ask_ynae "git $suggest"
		exit_code=$?
		echo
		case $exit_code in
		"0" ) \git ${=suggest} ;;
		"1" ) \git $@ ;;
		"2" ) return 130 ;;
		"3" ) print -z "git $@" ;;
		esac
	else
		\git $@
	fi
}
alias git=wrapped_git
```