OmniAICreator/Qiita-1.07M huggingface dataset:
bashで竹内関数

bashで竹内関数を計算してみます。

## まず通常版
```bash:tarai01.sh
#!/bin/sh
tarai() {
  if [ ${1} -gt ${2} ]; then
    echo -n $(tarai $(tarai $(( ${1} - 1 )) ${2} ${3}) \
                    $(tarai $(( ${2} - 1 )) ${3} ${1}) \
                    $(tarai $(( ${3} - 1 )) ${1} ${2}))
  else
    echo -n ${2}
  fi
}

tarai ${1} ${2} ${3}
echo
```
再帰呼び出しのたびにサブシェルを起動しています。悪い予感がプンプンします。

```console
$ sh tarai01.sh 10 5 0
```
返ってきません。別の端末からプロセスを見てみると

```console
$ ps u -C sh
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nihongi   5805  0.0  0.0 113176  1440 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   5806  0.0  0.0 113176   384 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   5807  0.0  0.0 113176   640 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   5808  0.0  0.0 113176   612 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   5809  0.0  0.0 113176   644 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   5810  0.0  0.0 113176   624 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   9947  0.0  0.0 113176   660 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi   9948  0.0  0.0 113176   636 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  19318  0.0  0.0 113176   668 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  19319  0.0  0.0 113176   652 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  20209  0.0  0.0 113176   680 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  20210  0.0  0.0 113176   664 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  20211  0.0  0.0 113176   692 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  20212  0.0  0.0 113176   676 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
nihongi  20213  0.0  0.0 113176   704 pts/0    S+   02:26   0:00 sh tarai01.sh 10 5 0
以下省略
```
たくさんプロセスが上がっているので、動いているのは間違いないようです。

## 何が起きているのか
関数が呼び出されたときに、入力パラメータをエラー出力に表示する処理を追加して、何が起きているか見てみます。

```bash:tarai02.sh
  echo "${1} ${2} ${3}" >&2
```

```console
$ sh tarai02.sh 10 5 0
10 5 0
9 5 0
8 5 0
7 5 0
6 5 0
5 5 0
4 0 6
3 0 6
2 0 6
1 0 6
0 0 6
-1 6 1
5 1 0
4 1 0
以下省略
```
(10, 5, 0)では無理なので(5, 2, 0)くらいに日和ります。

```console
$ sh tarai02.sh 5 2 0 2> tarai.log
5
$ wc -l tarai.log
149 tarai.log
$ sort -u tarai.log | wc -l
37
```
149回の呼び出しがあり、ユニークなものは37回であることがわかりました。結果をキャッシュすれば改善が期待できます。

## キャッシュできるか？
無理です。前に見たように再帰呼び出しが別プロセスに展開されてしまうので、同じ連想配列をそれぞれのプロセスから参照することができません。

根本的に処理を見直す必要がありそうです。次回、「再帰しない竹内関数」をお楽しみに。
Linux Mint 19 にAtomインストール

Linux MintにエディターのAtomをインストールするには
Software Managerからインストールする事も出来ますが
後々シェルスクリプトで実行環境の設定を一発で出来るスクリプトを自作したいので
コマンドラインでのインストール作業を整理しておきます。

やることは単純
コマンドラインから2行を打つだけ

```
$wget https://atom.io/download/deb -O atom.deb
$sudo dpkg -i atom.deb
```

atomコマンドで起動します。

```
$atom
```

![Atom.png](https://qiita-image-store.s3.amazonaws.com/0/104856/0a1fdeec-b305-80ad-9cb5-0f5fe2e61f3e.png)



参考
How to Install Atom Text Editor on Ubuntu, Debian and LinuxMint
https://tecadmin.net/install-atom-editor-on-ubuntu-debian-and-linuxmint/
Ruby環境構築４

# はじめに
前回はRuby、rubygems、Gem、bundlerについてまとめた。いよいよrbenv（＋ruby-build）を使う場合についてまとめる。

# 概要
rbenvはサーバーの中で複数のrubyバージョン環境を構築できるようにしてくれる。ruby-buildはrbenvのプラグインであり、rbenv配下で実際にrubyを導入してくれる。

# ディレクトリ構成とインストール
## ディレクトリ構造
これまでとはrubyの場所が違うので、改めて全体について１枚絵にする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269452/0841c440-ad0c-bbaf-9704-7f4ef681e7c9.png)

## インストール
1. rbenvとruby-buildの配置（紺色）
    `git clone https://github.com/sstephenson/rbenv.git ~/.rbenv`コマンドで、rbenvのファイル一式を**配置**する。`git clone`なのであくまで配置するだけだ。ruby-buildも同様に`git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build`コマンドで配置する。

2. .bash_profileの設定（水色）
`rbenv`コマンドはrvenb/bin/にあるがここにはパスが通っていない。そこで`echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile.`コマンドを実行し、ログイン時に毎回パスが通るようにする。併せて、`echo 'eval "$(rbenv init -)"' >> ~/.bash_profile`コマンドで`rbenv init -`の実行結果も.bash_profileに書き込む。'rbenv init -'については、内容がちょっと難しいのでここでは割愛する。（versionsフォルダも作成される。）
.bash_profileを設定し終わったら、`exec $SHELL --login`で再ログインし、.bash_profileを実行する。'rbenv --version'でパスが正しく通ったか確認する。

3. rubyのインストール（緑色）
`rbenv install --list`でインストールできるRubyバージョンの一覧を表示し、`rbenv install -v 2.6.0`とバージョンを指定しインストールする。インストール後、 `rbenv versions`を実行し、インストールされたrubyを確認する。今回は2.6.0と2.4.0をインストールした。
インストール後は`rbenv rehash`コマンドを実行する。これも難しいので割愛するが、Rubyのバージョンをインストールしたとき、コマンドのあるgemを導入したときは必ず実施する必要がある。
https://github.com/rbenv/rbenv#rbenv-rehash

4. ディレクトリで使用するrubyの設定（黄色）
ディレクトリに対して使用するrubyのバージョンを設定する。最初に`rbenv global 2.6.0`コマンドでglobalなrubyバージョンを設定する。これを設定すると、ディレクトリにrubyバージョンが設定されていない場合に利用されるrubyのバージョンを指定できる。具体的には、.rbenv/配下にversionファイルができ、そこにバージョンが書き込まれる。

    一方で、特定のディレクトリにバージョンを設定する場合は、設定するディレクトリに移動し、`rbenv local 2.4.0`コマンドで設定する。設定するとディレクトリに.ruby-versionが作成され、そこにバージョンが書き込まれている。

5. 確認
最後に、きちんと設定されているか確認する。確認は各々のRubyアプリケーションディレクトリで実行する。まず`rbenv versions`でディレクトリで利用されるrubyのバージョンを確認する。そして`ruby -v`、`gem -v`、`bundle -v`を実行し、それぞれが利用可能なことを確認する。（bundlerについては、Rubyのバージョンによって入っているものと入っていないものがある。）

* RubyAPP1/の場合

    ```bash
[ec2-user@ip-10-0-1-14 ~]$ cd RubyAPP1
[ec2-user@ip-10-0-1-14 RubyAPP1]$ rbenv versions
  2.4.0
- 2.6.0 (set by /home/ec2-user/.rbenv/version)
  [ec2-user@ip-10-0-1-14 RubyAPP1]$ ruby -v
  ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux][ec2-user@ip-10-0-1-14 RubyAPP1]$ gem -v
  3.0.1
  [ec2-user@ip-10-0-1-14 RubyAPP1]$ bundle -v
  Bundler version 1.17.2
```
* RubyAPP2/の場合

    ```bash
[ec2-user@ip-10-0-1-14 RubyAPP2]$ rbenv versions
* 2.4.0 (set by /home/ec2-user/RubyAPP2/.ruby-version)
  2.6.0
[ec2-user@ip-10-0-1-14 RubyAPP2]$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
[ec2-user@ip-10-0-1-14 RubyAPP2]$ gem -v
2.6.8
[ec2-user@ip-10-0-1-14 RubyAPP2]$ bundle -v
rbenv: bundle: command not found
The `bundle' command exists in these Ruby versions:
  2.6.0
```

# まとめ
rbenvによって、アプリケーション単位でruby,rubygems,bundler,gemが分かりやすく管理できる。Rubyはバージョン間の互換性が低いプログラム言語であるゆえに、こういった形になったらしい。rbenvのinitとrehashを読み解ければほぼほぼクリアになるが、それはまた別の機会にする。
mybatisテーブルカラム名とフィールド名との対応付け

# 前提

MyBatisでテーブルカラム名と、コード中で使うフィールド名とを対応付けている仕組み（マッピング）を解説する。

対応付けの方法は、4種類。現場では、そのうちの1つを選択することになる。

1. 標準の自動マッピング機能を利用する
2. AS句で1つ1つ対応付ける
3. キャメルケースの自動マッピング機能をONにする
4. resultMapタグで管理する

# 1. 標準の自動マッピング機能を利用する

MyBatisの標準設定では、「小文字大文字の違いを無視して、対応付ける」仕様になっている。

以下のような例は、自動で対応付けされ、動作する。

`例：（テーブルカラム名）A_COLUMN　→　（フィールド名）a_column　や　a_Column`

# 2. as句で1つ1つ対応付ける

SQL文を記述する際、AS句で対応を記載する。

```:SQL文
SELECT
    A_COLUMN AS "aColumn",
    B_COLUMN AS "bColumn",
FROM
    MY_TABLE
WHERE
    A_COLUMN = "test"
```

```:フィールド名
Public Class myTableDto {
    String aColumn;
    String bColumn;
}
```

# 3.キャメルケースの自動マッピング機能をONにする

コンフィグファイル（例：mybatis-config.xml）の中で、

```:mybatis-config.xml
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
```

を指定すると、アンダーバー付のカラム名を、自動でキャメルケース（2番目の単語の最初を大文字にする）に対応させてくれる。

`例：（テーブルカラム名）A_COLUMN　→　（フィールド名）aColumn`

# 4. resultMapタグで管理する

コンフィグファイルから呼び出す Mapperファイル の中で、resultMapタグを使い、対応付けを記述する。

```:testMapper.xml
<mapper namespace="org.apache.ibatis.example.Mapper">
    <resultMap type="org.apache.ibatis.example.dto.myTableDto" id="testmap">
        <result column="A_COLUMN" property="aColumn"/>
        <result column="B_COLUMN" property="bColumn"/>
    </resultMap>
    
    <select id="getAll" resultMap="testmap">
        SELECT * FROM MY_TABLE
    </select>
</mapper>
```

# 雑感

個人的には、SQL文を見たときに書き漏らしがないかすぐ分かる、AS句で書くのが好きかも。
GitHubでよく使うコマンドの種類

#作業環境
Windows10
#よく使うコマンド集
- **ファイルまたはディレクトリの削除**  
ファイルを削除の場合は`$ git rm`だが、ディレクトリの削除の場合は`$ git rm -r`する。    
`$ git rm [-r] db`
- **コミット履歴**  
`$ git log`
- **addしてるファイルを見るとき**  
`$ git status`
- **コミットまで**  
`$ git add [ファイル名]`  
`$ git commit -m "[メッセージ]"`   
- **commitの取り消し**  
`$ git reset --soft "HEAD^"`
- **addの取り消し**   
`$ git reset HEAD [ファイル名]`

#個人作業の場合
- **pushするとき**  
`$ git push origin master`

#共同作業の場合
- **pushするとき**  
`git push -u origin "[ブランチ名]"`
- **ブランチの作成**  
   `$ git checkout -b [ブランチ名]`
- **場所の確認**  
`$ git branch`
- **masterのものを手元に持ってくる**  
自分の手元で変更したものがある場合は一度`git stash`で退避してから`git pull`する必要がある。  
`$ git stash`   
`$ git pull origin master`  
`$ git stash apply`  
または  
`$ git checkout master`  
`$ git pull`  
- **コミットするファイルの名前を見る(自分で変更したファイルの一覧)**  
`$ git diff --name-only`
初めてのGCP(google cloud platform)  part0 (git関連) 

gcp使用する上でgitは不可欠なのでメモ
どっかからgit cloneしたときの話

◆自分のgitリモート環境にpushしたい

```
①git clone どこかの.git
②ローカルでごにょごにょ
③自分のgitリポジトリ作成
④git remote add origin【自分のgitリポジトリ.git】
※ここでエラーでたら現在 origin環境に別環境がセットされてるので削除するー
⑤git remote rm origin
→これでスッキリ
⑥　もういちど④を行うとリモートリポジトリ先変更(追加)完了
⑦cat .git/configとかで確認できるよー。
```
メモを取れよバカ野郎！

#目的
仕事や伝達を何とか別の方にやり切って頂くためには、どうするべきか？

#結論
「君に頼みたいのは雑用ではなく、仕事の大切なプロセスであり、君にとっても信頼を築く一歩となるため、何とかしてやり遂げてほしい」と伝える。
そうすると、自然とメモ取ったり、段取りを確認したくなっちゃうようだ。

#議題
・学ぶ場と勘違いしていないか？
・「はいはい雑用ッスね」と思われているのではないか？

#切掛
30歳を超え、かわいい後輩/できる後輩にも囲まれる機会が増えてきた。
同世代と飲んでいて、「なぜメモを取らないのか！あのバカは。。」と嘆く友人もいた。
"メモを取る" ことは、目的ではないが、忘れないために私もよくとる。
その差はなぜ起こるのか、どうすれば、メモを取ろうと思うのか考えてみた。

#検討
###・学ぶ場と勘違いしていないか？
　社会人1年生とお話する中で、根本的な意識の違いを感じるポイントはここかなぁ。
学校では、
1.（課題を決める＞学ぶ＞試験＞次のステップ）  を繰り返す。
社会人は、
2.（課題を決める＞成果を出す＞次のステップ）  と「学ぶ」フェーズが、業務外にくる。

学ばせてくれる会社もあるが、それは費用負担というのが一般的で、「業務時間」は、成果を出すために使うことが望ましいと私は考えている。
（自分のことは棚に上げてます笑）
　学校経験をそのままと勘違いしていると「成果を出す時間＝試験」であることをインプットしないと、"今はどうするタイミングか？"が、良く分かっていない1年生が大半だ。残念ながら、何歳になってもそういう人がいるが、そのままでは、本人もチームも非常に危険だろう。。。

　主題とは異なるが、「学ぶ」フェーズを自分の時間で取れない人は、漠然とした不安を感じるようだ。"何からしたらいいか分からない" "なんか不安" というのは、「課題を決める」フェーズを運良く？深く考えずにこれた秀才タイプに多いと感じた。１年生のうちに、"解決すべき課題は何か？"と考え、「課題を決める」フェーズを自分の力でクリアできるようになると、評価がうなぎのぼりだろう。

###・「はいはい雑用ッスね」と思われているのではないか？
1年生とお話する中で、「雑用もしっかりこなして、一人で仕事できるようになりたいです！」と心意気を出してくれる方もいる。
少し注意して欲しいのは、雑用という言葉だ。
もし、1年生が、"雑用＝大事なようではない" と勘違いしていたら、周りが是正すべきだろう。
1年生としても、仮にも人様にお願いする用事なのだから、難易度は低いかもしれないが、意味のある作業だと考えて欲しい。
ここで大切なのは、自分で"何を解決するための作業か？" を考え、先輩に答え合わせしてもらおう。時間がない方、会えない方もいると思うので、その場合は、相手の背景と立場になって、どういう意図か考える癖をつけてみよう。

#余談
私が学生時代に教授から奥義を教わった。
それは、「人が出社する前に先輩のデスクとコップを綺麗にし、先輩が出社したら飲み物を出すんだ」というものである。意図は詳しく覚えていないが、この奥義を10年くらい忘れられない。
私はバカなので、何も考えずにトライしてみた。
デスク整理と飲み物だしたったそれだけだが、どうしてなかなか難しい。
勝手に触るな！とか、今はいらない、とか、ベストフィットなかなかさせられない。

それは、人によって、クリーンデスクしている方や雑多に見えるけど分類したデスクの方、デスク上は綺麗なんだけど机の下はぐっちゃぐちゃなど、色んな方がいるから。また、コップを洗うことで、普段どんなものを飲んでいるか分かる。飲み物を出すことで、いつ飲むか、生活リズムも分かってくる。

教授の奥義を私なりに理解した「雑用の意味」は、先輩の仕事や情報を集めること、仕事の仕方（いつ息を抜くのか）を理解すること、先輩との話の切掛を作ること、を学ぶための雑用だと理解している。
お陰様で、部署を移動して２年経つが、今だに相談に乗って頂け、仕事の相談も頂ける素晴らしい関係が続いている。ひとえに、奥義を使って、相手を理解し、自分を売り込めた成果だと思う。

いつか、答え合わせができるといいな。
三項演算子（?:）どうやって書いていますか

三項演算子（?:）は可読性が上がる下がるという議論があります。
私は書き方次第で、読みやすいと感じています。
可読性の話はよくあるので、実際どう頭に馴染ませるかという話を書きます。

### 三項演算子（?:）は、読みやすいけど、書きづらい？
可読性が高い三項演算子の書き方を後輩に伝えたところ、（言語はJava）
「前に調べて、確かに見やすいんですけど、書くときわすれちゃうんですよね。毎回調べて考えて書きます。」
と言われたので、自分がソースを書くときにどのように書いているか話しました。
それなりに良かったみたいなので記事にします。

私は、以下の感じでコーディングしていますが、皆さんいかがでしょうか。

### 例： 10以上だったらAプランで、5上だったらBプランで、それ以下ならCプラン
いろいろ書き方はありますが、コーディングスタイルとしては例えばこんな風にかきますね。


``` Java
String plan = count > 10 ? "A" :
              count > 5  ? "B" :
              /* other*/   "C" ; 
```

とか

``` Java
String plan = count > 10 ? "A" 
            : count > 5  ? "B"
            : /* other*/   "C" ; 
```
上の書き方は、「:」が行の最後にあり、「まだ条件が次の行に続くぜ」感があって、
私は好きなのですが、よく見かける書き方は下ですね。

### 唱えながらコーディング
私は、次のようには頭で唱えながら書きます。括弧内を頭の中で唱えています。

一度慣れると自然使えるようになります。
この唱えながらコーディングするのを、3,4回くらい繰り返すと、
それ以降は脳ミソが三項演算子の文法に費やす時間が少なくなり、
自然にコーディングできるようになります（・・・と思います）。


``` Java
(プランは） count > 10 (の場合は？) "A" (・・・で)
　　　　　count > 5  (の場合は？) "B" (・・・で)
        （それ以外の場合は、）      "C" ; 
```

| 実際に書く文字/読む文字       |       頭で唱える言葉 |
|:-----------------|------------------|
| ?             |              の場合は？ |
| :           |            ・・・で、 |
| /* other */           |            それ以外の場合は、 |

## 雑感
 * 唱えながらコーディングに慣れると三項演算子の文法を頭で考えなくて済む。頭はもっと全体の構成とかそういったことに使ったほうがいい。
 * 唱えながらコーディングをするとコーディングにリズムができる。新人さんにはいいかもしれない。
 * 多分コーディングが早い人はこんなことやらなくても自然にコードが浮かんできてる。
itext7でPDFを作成する～HelloWorld～

#itext7でPDFを作成
itext7というPDFを作成するライブラリがあるのですが、日本語のドキュメントが少ないので、まとめていこうと思います。
eclipse+gradleでやっていこうと思います。

#build.gradleの設定
```build.gradle
dependencies {
～略～
    // itext7を追加
    implementation 'com.github.itext.itext7:layout:7.1.4'
    // itext7用日本語フォントを追加
    implementation 'com.github.itext.itext7:font-asian:7.1.4'
    // slf4jを追加
    implementation 'org.slf4j:slf4j-log4j12:1.7.21'
}
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
```
「slf4j」も読み込んでおかないと以下のようなエラーが出ます。
> SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
> SLF4J: Defaulting to no-operation (NOP) logger implementation
> SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

#HelloWorldを実行
```HelloWorld.java
import java.io.File;

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;

public class HelloWorld {
    public static void main(String[] args) throws Exception {
        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(new File("HelloWorld.pdf"));
 

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);
 
        // Initialize document
        Document document = new Document(pdf);
 
        //Add paragraph to the document
        document.add(new Paragraph("Hello World!"));
 
        //Close document
        document.close();
   }
}
```


#次回：日本語を出そう
さて、チュートリアルの"Hello World!"部分を日本語に置き換えてみると・・・
あれ？真っ白け？
[次回](https://qiita.com/naverut/items/74eb2476b825382a13c8)はその辺りから！
Windows Subsystem for Linux でファイルを開くワンライナーを、macOS と共通化

## 結論

```bash
$ file=mydir/index.html && if type cmd.exe; then cmd.exe /c start ${file}; else open ${file}; fi
```

## 環境
- Windows 10 Pro 17133.1 (April 2018 Update)
- macOS High Sierra 10.13.4

以下「Windows Subsystem for Linux」を **wsl** と略します。

## ファイルを開く方法
`explorer.exe`にファイルを渡せば、そのファイルを開いてくれます。

```bash:wsl
$ explorer.exe index.html
```

### Windows Subsystem for Linuxでない環境にも対応
Macでは`explorer.exe`等は無く、代わりに`open`コマンドを使います。

```bash:mac
$ open index.html
```
なので、`type`コマンドで`explorer.exe`の有無を確認する必要があります。

こんなイメージです。

```bash
file=index.html
if type explorer.exe; then
  explorer.exe ${file};
else
  open ${file};
fi
```

ワンライナーにすると以下です。

```bash:wsl/mac
$ file=index.html && if type explorer.exe; then explorer.exe ${file}; else open ${file}; fi
```

## ファイルパスを変換する方法
上記の方法でファイル名を指定することができますが、ディレクトリ階層を含むパスは無効になってしまいます。ディレクトリ階層の区切り文字がWindowsとLinuxとで異なるためです。

wslには`wslpath`というコマンドがあり、wsl上のLinuxファイルパスをWindowsの形式に変換してくれます。

```bash:wsl
$ wslpath -w mydir/index.html #=> mydir\index.html
```

### Windows Subsystem for Linuxでない環境にも対応
先程のif文の中に`wslpath -w`を含めます。こんなイメージです。

```bash
file=mydir/index.html
if type explorer.exe; then
  explorer.exe `wslpath -w ${file}`;
else
  open ${file};
fi
```

ワンライナーにすると以下です。

```bash:wsl/mac
$ file=mydir/index.html && if type explorer.exe; then explorer.exe `wslpath -w ${file}`; else open ${file}; fi
```

ただしここまで書いたあとに気付いたのですが、`explorer.exe`ではなく`cmd.exe /c start`を使えば、ファイルパスを変換してくれるため`wslpath`は不要なようです。
参考: [WSLでmacのopenコマンドみたいなこと \- Qiita](https://qiita.com/chez_sugi/items/603a0ba8016aaae9ef98)

## まとめ
冒頭に書いたようなコマンドになります。

```bash:wsl/mac
$ file=mydir/index.html && if type cmd.exe; then cmd.exe /c start ${file}; else open ${file}; fi
```
URL等も、これで開くことができます。

```bash:wsl/mac
$ file='https://www.google.co.jp/' && if type cmd.exe; then cmd.exe /c start ${file}; else open ${file}; fi
```

## 参考
- [Windows で WSL \+ Hyper \+ fish shell 環境を再構築する \- Qiita](https://qiita.com/kikuchi_kentaro/items/9dc441f64c17a38aad96#_reference-34a0bda6b3375a025668)
GitHubでSSH接続するときPermission deniedと言われる

# 起こったこと
GitHubだから云々というわけではないけど
リモートリポジトリにプッシュしようとしたところ以下のメッセージが出た

```
$ git push origin filling-in-layout
The authenticity of host 'github.com (192.30.255.112)' can't be established.
RSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/Users/xxxxxxxxxxxx/.ssh/known_hosts).
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

```
（今までこんなの出たかったんだけどな、、、AWSいじってみた時に何かやらかしたのかな、、、）

GitHubとのSSH接続の確認のために以下も実施してみるも同様のメッセージ
（ただ、IPが違う？？）

```
$ ssh github.com
The authenticity of host 'github.com (192.30.255.113)' can't be established.
RSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/Users/xxxxxxxxxx/.ssh/known_hosts).
xxxxxxxxxxx@github.com: Permission denied (publickey).
```

とりあえず「権限がないよ〜」とのことなので、
色々ググった結果「id_rsa」の権限でコケることがあるよとのこと
ふむふむ

```
$ sudo ls -al ~/.ssh
total 32
-rw-r--r--   1 xxxxxxxxxx  staff   223 12 29 19:43 config
-rw-------   1 xxxxxxxxxx  staff  1766  2 26  2018 id_rsa
-rw-r--r--   1 xxxxxxxxxx  staff   409  2 26  2018 id_rsa.pub
-rw-------   1 xxxxxxxxxx  staff     0 12 29 19:39 known_hosts
```
いけてそうだぞ？？

ってことは「~/.ssh」自体の権限が違うんじゃね？？

```
dr--------    7 xxxxxxxxx  staff    224 12 29 19:43 .ssh
```

怪しい
ググる→権限変更の必要ありそう

```
$ sudo chmod 700 ~/.ssh
$ sudo ls -al ~
drwx------    7 xxxxxxxxxx  staff    224 12 29 19:43 .ssh
```

完了
どうだ！？

```
$ ssh -T git@github.com
The authenticity of host 'github.com (192.30.255.113)' can't be established.
RSA key fingerprint is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+---[xxxxxxxx]----+
| xxxxxxxxxxx     |
|xxxxxxxxxxx      |
|xxxxxxxxx        |
|xxxxxxxxxxxx     |
|xxxxxxxxxxx      |
|xxxxxxxxxxxx     |
|xxxxxxxxx        |
| x     x         |
|                 |
+----[xxxxxx]-----+
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.255.113' (RSA) to the list of known hosts.
Hi esaki11! You've successfully authenticated, but GitHub does not provide shell access.
```
いけた！
【メモ】vscodeにvimプラグインを入れる

##なぜこれをやるのか
コマンドプロンプトとvimでRubyのコードを書いていたのですが、ファイルを開くときにいちいちvimで:eと打っていたので、以下の画像のようにディレクトリの中身が左側に表示されるようにしたい！と思いました。ネットの方のアドバイスでvscodeを使っているならvimを使えるはずとご助言をいただき、今回このような表示ができるように模索してみました。

![スクリーンショット (268).png](https://qiita-image-store.s3.amazonaws.com/0/256858/77e9b0e4-9ecc-cb21-2be8-f2a99bf53e0d.png)




##前提
・vscodeをインストール済であること

1 vscodeを開き、拡張機能の検索にVimと入力し、一番上に出てくるプラグインをインストールし、再読み込みする。検索するといくつもVimと名前のついたものが出てきますが、インストール数が最も多いものをインストールしてみました。これで基本的なVimの操作はできるようになります。

![スクリーンショット (269)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/256858/6087e95f-c011-b983-a69a-f8811ae47832.jpeg)


![スクリーンショット (270)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/256858/3321baed-896a-9c49-ee87-9fbdd5d21df0.jpeg)


[Visual Studio CodeをVim風味にする](http://ctrlrobot.hatenablog.com/entry/2018/04/08/214734)によると、以下のようにカスタマイズする方法もあるようですが、私にはさっぱりわかりませんので今は置いときます。

>ctrl + shift + pを押してコマンドパレットを開き、"Open User Settings"と打ち込み、ユーザー設定を開く。
こんな画面がでてくるので（この画面は既に右側に設定が付け足されているが）、右側（settings.json）に自分の好みのキーバインドになるように書き足していく。（settings.jsonはC:\Users\なんちゃら\AppData\Roaming\Code\User\settings.jsonにある。） 



##vimの操作を確認
表示から統合ターミナルを開き、該当のディレクトリに移動したあと、vimと打ちます。

![スクリーンショット (273)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/256858/51500532-a62a-d714-6ef2-c9743707b9c5.jpeg)

vimの画面が開きました！
![スクリーンショット (276).png](https://qiita-image-store.s3.amazonaws.com/0/256858/59971779-768e-bb6c-8396-2fc79c1d2b95.png)

##ワークツリーを表示する
ファイルタブを開き、「ワークスペースにフォルダを追加」し、自分の開きたいフォルダをクリックする。

![スクリーンショット (274)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/256858/2d3bc92b-1dbf-92e6-67c4-67034c5535df.jpeg)

表示できました！

![スクリーンショット (275)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/256858/a207dade-0369-d021-0bb7-a868289ea46d.jpeg)


##最後に
今は、左のフォルダをクリックすると開くことで、ファイルを開くことができるので、vimはどのタイミングで必要なのかわからなくなってしまいました…（今までvimで:eでファイルを開いていたため）
たしかにvimのコマンド（カーソルモードでマウスなしで上下左右に動いたり）は使えるのですが、これ以外にも活用できそうです。
vimをプラグインにする理由はいろいろ機能を追加していくくらい慣れていないとわからないと思うのですが、とりあえずワークツリーが表示できたのでこちらの記事は完結したいと思います。

今Rubyを扱うためにvimを使っていたのですが、vscodeでできるならわざわざvimでする必要ないですよね・・・理解しきれていない中での記事で申し訳ないですが、どなたかのお役にたてれば幸いです。
何かご指摘・ご助言がありましたらコメント欄にいただけると嬉しいです。


##参考
[VSCode の Vim プラグインにコントリビュートした！](https://qiita.com/Maxfield_Walker/items/b9724fe5622184904069)
[Visual Studio CodeにVimプラグインを入れる](http://1d1og.hateblo.jp/entry/2018/01/14/154746)
[VS Codeのワークスペース](https://qiita.com/YuichiNukiyama/items/ef16a0219f46ea03a045)
Go + Graphviz で抽象構文木をグラフにしてみる



* [Pythonの抽象構文木をGraphvizで可視化する]( https://qiita.com/kaityo256/items/e83b369ba7518da0a519 ) ( 
@kaityo256 さん )
* [Ruby2.6 + Graphvizで抽象構文木をグラフにしてみる]( https://qiita.com/Nabetani/items/7904651fae1f925129c7 ) ( 私 )

のシリーズを、Go で。

Go で AST を触るのは初めて。こちらもまあそれらしいツリーが出力できたからいいかなと思っている

ソースコード。

```go:go1.11.4
//  go build goast.go && ./goast sample.go | dot -Tpng -ogoast.png
package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"strings"
)

func nodeToString(node ast.Node) string {
	switch x := node.(type) {
	case *ast.Ident:
		return "Ident(" + x.Name + ")"
	case *ast.BasicLit:
		return "BasicLit(" + x.Value + ")"
	case *ast.BinaryExpr:
		return "BinaryExpr(" + x.Op.String() + ")"
	case *ast.UnaryExpr:
		return "UnaryExpr(" + x.Op.String() + ")"
	case *ast.IncDecStmt:
		return "IncDecStmt(" + x.Tok.String() + ")"
	case *ast.AssignStmt:
		return "AssignStmt(" + x.Tok.String() + ")"
	default:
		return strings.Replace(fmt.Sprintf("%T", x), "*ast.", "", -1)
	}
}

func main() {
	fmt.Println(`digraph{graph [dpi=288];`)
	fset := token.NewFileSet()
	flag.Parse()
	f, err := parser.ParseFile(fset, flag.Arg(0), nil, 0)
	if err != nil {
		fmt.Printf("Failed to parse file\n")
		return
	}
	parents := []*ast.Node{}
	fmt.Println(`n0x0[label="ROOT"]`)
	ast.Inspect(f, func(node ast.Node) bool {
		if node != nil {
			var p *ast.Node
			if len(parents) != 0 {
				p = parents[len(parents)-1]
			}
			fmt.Printf("n%p->n%p\n", p, &node)
			fmt.Printf(`n%p[ label=%q ]`+"\n", &node, nodeToString(node))

		}
		if node == nil {
			parents = parents[:len(parents)-1]
		} else {
			parents = append(parents, &node)
		}
		return true
	})
	fmt.Println(`}`)
}
```

`nodeToString` が不十分かもしれない。

食べさせたコードはこんな感じ：

```go:go
package main

import (
	"fmt"
)

func main() {
	for x := 0; x < 10; x++ {
		if x == 0 {
			fmt.Println(123, -456)
		} else {
			fmt.Println("foo", []string{"bar"})
		}
	}
}
```

複雑過ぎたかな。

出てくる絵はこんな感じ：

![image.png](https://qiita-image-store.s3.amazonaws.com/0/6854/228c76f8-dcc6-e27a-4ad6-f119a433e8e9.png)

なかなかおもしろい。
console.logをスタイルでデザインできる！（Chrome検証）

Chrome最新版で検証済み。他ブラウザでは未確認です。

先ずはコンソール出力の結果から。

<img width="452" alt="スクリーンショット 2018-12-30 11.45.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/118906/a4b63db8-ecc9-6e89-bc4f-b885d70c6d9e.png">


ソースは以下の通りです。変換指定文字列%cをつけることで、スタイルを割り当てることができます。
最終行はリンクのため、スタイルが当たらず空にしています。（←もしかしたらできるかもしれませんが）

```js
console.log(
  '%c copyright %c tsuzuki557 %c https://qiita.com/tsuzuki557',
  'padding: 5px 0; background-color: red; color: #fff;',
  'padding: 5px 0; margin: 0 10px; background-color: pink; color: #000;',
  ''
);
```

制作物をコンソールログで出力しているおしゃれな会社、海外ではたまに見かけますが良いですね。
DevTools tips — day 11: スタイルエディタ(続き)

この記事は[Tomek Sułkowski](https://medium.com/@tomsu)さんによる
フロントエンドエンジニア向けアドベントカレンダーの翻訳記事です。
とても勉強になったので許可を得て翻訳させていただきました。元記事は[こちら](https://medium.com/@tomsu/devtools-tips-day-11-style-editors-continued-7ac0e2cd873e)。
 
---

*休暇まであと24日です。私はこれからDevToolをより効果的に、そしてもっと楽しく使うためのコツを紹介する短い記事を書いていきたいと思います。[昨日](https://qiita.com/rena_m/items/ddf761376e6d72d0c6f2)はカスタムフォーマッターで楽しみましたね。今日は目で見て楽しめるものをテーマにします。使うものは…*

# 30. シャドウエディタ
あまり良い響きではありませんが、今日扱うものは、先日取り上げたカラーピッカーのようなちょっとしたウィジェットで、さらにシンプルなものです。Stylesパネルのbox-shadow, text-shadowプロパティの近くに表示されるシャドウのついた四角いマークをクリックすると表示されます。
![1.gif](https://qiita-image-store.s3.amazonaws.com/0/318825/c0f18e84-4396-d4d9-5a02-aeadad00d2cf.gif)


# 31. Timing function editor

Cubic bezierエディタとしても知られています。3次ベジェ曲線はアニメーション中のcssアニメーションの速度変化を定義する3つの数字です。私たちはそのCSSプロパティを`transition-timing-function`、`animation-timing-function`という名前で呼んでいます。

カラーピッカーやシャドウエディタと同じように、先ほど述べたプロパティ(またはその省略形：transition, animation — ちなみに、マーク`timing function value`が省略形に設定されていないと表示されません)の横にある曲線のマークをクリックすると現れます。

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/318825/927b6f3a-cc11-c89e-baaf-5e5355ded3e4.gif)
3Dアニメーションをまだ使ったことがない人へ：これは簡単に利用できます。`container element`の`perspective`プロパティを設定するだけです。この場合、私は`perspective: 200px;`をbodyに設定しています。

# 32. style rulesボタンを挿入する
style selector領域の終端の近くでホバーすると、瞬時にカラーエディタやシャドウエディタを利用するCSSプロパティを追加できるボタンが現れます。

- `text-shadow`
- `box-shadow`
- `color`
- `background-color`
そしてそれぞれに対応するエディタが開きます。

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/318825/82c9162f-a39f-fc98-15e3-92097a036604.gif)


---

いつも通り、**なにか新しいことを学べたらぜひ**
→ もっと多くの人の目に止まるように**拍手👏ボタンをお願いします！**
→ 他の投稿も見逃さないように**[Twitter (@sulco)をフォロー](https://twitter.com/sulco)**してください！
先週一週間のデータを消すスクリプト

#### はじめに
毎週、週明けに過去1週間分のデータを手作業で削除していた人から自動化を依頼されたときに作成したコードです。
以下のファイルを適当な場所に格納後、タスクスケジューラで以下の引数を指定して起動します。

第一引数：先週一週間のデータを全部消す対象フォルダパス
　　　　　例）"C:\test\"
第二引数：削除対象ファイルの拡張子。すべてのファイルを対象とする場合は「**」
　　　　　例）"***"

```vb
Option Explict

' ** 共通メッセージ **
Const I_001 = "ファイルを削除しました。"
Const I_002 = "削除するファイルはありませんでした。"
Const W_001 = "引数が正しく設定されていません。"
Const W_002 = "指定したフォルダが存在しません。"

' ** 共通メッセージ end **

If Wscript.Arguments.Count <> 2 then
    Wscript.Echo W_001
    Wscript.Quit
End If

Dim delTargetDir
Dim fso, fl, ext

Dim week
Dim today, targetDate, compDate
Dim isDelTargetExist

Set fso = CreateObject("Scripting.FileSystemObject")
delTargetDir = Wscript.Arguments(0)
ext = Wscript.Auguments(1)
today = FormateDateTime(Now, 2)

If not fso.FolderExists(delTargetDir) Then
    Wscript.Echo W_002 & "=[" & delTargetDir &"]"
    Wscript.Quit
End If

' 曜日区分を取得
week = Weekday(today)

If week = 1 then
    ' 日曜日の場合
    ' 今週月曜日の日付を格納
    targetDate = DateAdd("d", 1, today)

ElseIf week = 2 then
    ' 月曜日の場合
    ' 今日の日付を格納
    targetDate = today
Else
    ' 火曜日以降は今週月曜日の日付を格納
    targetDate = DateAdd("d", -(week - 2), today)
End If

isDelTargetExist = False

' フォルダ内のファイル情報を順次取得し、
' 今週月曜より手前のデータを削除
For Each fl in fso.GetFolder(delTargetDir).Files
    compDate = FormateDateTime(fso.GetFile(fl.Path).DateLastModified, 2)
    If not fl.Name = "Thumbs.db" and _ 
    (ext = "*" or fso.GetExtentionName(fl) = ext) and _
    DateDiff("d", compDate, targetDate) >= 1 then
        On Error Resume Next

        fso.MoveFile fl.Path, "C:\test\"

        If Err.Number = 0 Then
            isDelTargetExist = True
        End If
        Err.Clear
    End If
Next

' サブフォルダ情報を順次取得し、今週月曜よりも前のデータを削除
For Each fl In fso.GetFolder(delTargetDir).SubFolders
    compDate = FormateDateTime(fso.GetFolder(fl.Path).DateLastModified, 2)
    If ext = "*" and DateDiff("d", compDate, targetDate) >= 1 Then
        On Error Resume Next

        fso.MoveFolder fl.Path, "C:\test\"

        If Err.Number = 0 Then
            isDelTargetExist = True
        End If
        Err.Clear
        
    End If
Next

If isDelTargetExist Then
    Wscript.Echo I_001
Else
    Wscript.Echo I_002
End If

Set fso = Nothing
```
エンジニアのアウトプット学習のサービス選定。#GoogleDocs @yumainaura まとまった単体の資料文書を永久保存、シェアするのに良いかも知れない。

# まとめ、まとむ、まとむなら、まとむとき

# 永遠

永遠に亡くならない、Goggleが亡くなるまで、たぶん
Googleでも終了するサービス
Githubよりも永遠性、サービス継続性は高いと思うnever die

# Googleing

Google検索にひっかけるためには工夫が必要
とりあえずはてなブックマークに入れて様子見中
Twitter拡散はするけどTwitter自体がそもそもぐぐれないしな

# Platform

プラットフォームやソーシャルではないので他の記事へのリンクはないし、記事一覧もない
本当に単体で存在して良い資料、記事の保存、拡散、共有、記録、思い出づくりには良いかも知れない

# Theme

Github Issueにはエンジニアリング的な記事しか置いてはいけない気がするし、用途が違うし
永久保存用としては第一候補として浮かび上がった
エンジニアリングに限らず一般的内容もこちらで書ける


![image](https://user-images.githubusercontent.com/13635059/50543881-38571600-0c27-11e9-8afb-5e6530649a7b.png)


# Etc

気分に応じてMediumやはてなブログに同じ記事をポストしても良いかも
Docksにリンクを張るとなおよし
MacBookなどでの爆速アウトプット環境設定は望まれる

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










<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【rails5】リクエストパラメータについてのメモ

##リクエストパラメータについてのメモ

**リクエストパラメータとは、WEBブラウザからWEBサーバーに送るパラメータを、URLの末尾に特定の形式で表記したもの。**

URLへの書き方

１、URLの末尾に？を付ける。
２、続いて「〇〇〇=値の形式で記述する。
※複数の値があるときは＆で区切る。

```
http://malanka.com/?hobby1=srilanka&hobby2=dance
```

ブラウザ側からの送り方

１、postリクエストで送る。htmlのform要素をsubmitする。
２、getリクエストで送る。URLの？以降に情報を含めることで送る。
？のついたURLにブラウザからアクセスするか、form要素のmethod属性にgetを指定して、form要素のsubmitを通じてリクエストを送る。

コントローラー側での受け取り方

paramsメソッドを使うことで、httpリクエストがgetでもpostでも関係なく、ハッシュのような感覚で取得出来る。

他には、送られてきたURLに含まれる、ルーティングで定義した可変部分もリクエストパラメータとして利用できる。

ルーティングに'edit/:id'と定義し、'edit/1'というURLが送られてきたとする。

送られてきたURLの'1'という部分と、ルーティングの':id'がマッチするので、1という値をparams[:id]という形式で取得出来る。
iPhoneの機内モード切り替えでXcodeでのデバッグが切れる問題

## 問題

iPhoneの実機でオンラインとオフラインの切り替え確認をするために機内モードのオン・オフを切り替えたところ、Xcodeで以下のアラートが表示され、デバッグが切れる問題が発生しました。

<img width="449" src="https://qiita-image-store.s3.amazonaws.com/0/149856/178917da-8996-5acf-85f2-c2cba3429c90.png">

```
Lost connection to "実機名"

Restore the connection to "実機名" and run
"ターゲット名" again, or if
"ターゲット名" is still running, you can
attach to it by selecting Debug > Attach to Process > 
ターゲット名.
```
## 解決

解決方法は簡単、iPhone側のインターネット共有をオフにするだけです。

## 参考文献

[stack overflow][1]
[1]:https://stackoverflow.com/questions/35535255/xcode-lost-connection-to-iphone
Linux Mint 19にGitをインストール

Linux Ming 19　を使っていますがデフォルトでgitは入っていませんでした。
gitバージョンを確認するとaptで入れろと言われます。

```
$ git --version

Command 'git' not found, but can be installed with:

sudo apt install git

```

いちおうapt updateしておきます。

```
$ sudo apt update
```

でaptでインストール
sudo apt -y install git だと何故か動作しなかったので
-yオプションを最後に持ってきたけど特殊なやり方かも

```
$ sudo apt install git -y
```

もう一回バージョンを確認してみると2.17.1が入っていますね

```
$ git --version
git version 2.17.1
```



アンインストールする場合

```
$ sudo apt remove git -y
```


環境

```
$ uname -srvpio
Linux 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64 x86_64 GNU/Linux

```

このマシンのイメージ作り込む事が多そうなので
gitにスクリプト作って置いておこうと思います。
サービス課金の値段設定 Yahoo知恵袋の仮想通貨"的"コイン課金の謎 @yumainaura

知恵袋のコインは課金なしのコインではあるけども、設定の参考になるな

ベストアンサーに100枚-500枚
回答リクエストに100枚
匿名投稿のために300枚

謎の設定
匿名投稿の価値が高いと想定されている
そこまで名前を隠したいひとの需要が？

たしかに他のは代替手段があるけど、匿名投稿はない
「切実に必要とする人のため」に値段が釣り上げられている
必要としていな人にはなぞの値段設定でも、必要とする人には分かる設定

駆け込み需要？足元をみる？
なんていうんだっけこのニーズ


![image](https://user-images.githubusercontent.com/13635059/50543669-d3e58800-0c21-11e9-9574-33c29d8519cc.png)

![image](https://user-images.githubusercontent.com/13635059/50543671-d7790f00-0c21-11e9-90a0-7af395138cee.png)


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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
C言語でポインタ渡し・ポインタ演算をいろいろ試した

# はじめに

ポインタ渡し・ポインタ演算の復習というか勉強のためにいろいろ書いて試したことがあるので，それを公開しておきます．
自分の勉強ノートとしてと，初心者向けに「こう書くとこうなる」の例を紹介できればという記事です．

一連の関数へのポインタ渡しの話の最後の記事という位置付けでもあります．

- 第1弾: [C言語でユーザ定義関数にargvやFILEを渡したい（関数へのポインタ渡し）](https://qiita.com/Reed_X1319RAY/items/2577cb1e2eb670f4bd3f)
- 第2弾: [C言語でユーザ定義関数にargvやFILEを渡したかった（関数へのポインタ渡し）](https://qiita.com/Reed_X1319RAY/items/953469e6a487fd6ce034)

なお，以下の説明にはあまり自信がないので，鵜呑みにされるとまずいかも知れないですし，よく分かってらっしゃる方に「合ってる」「間違ってる」等コメントいただけると幸いです．

# まず変数のポインタ渡しをしてみた

まずは簡単と思われる方から．配列をあとでやります．

書いてみたコードはこれです．

```sample1.c
#include <stdio.h>

// int型変数のアドレスを受ける
void func1(int* pt){
	*pt = 5; // ポインタが指す先の変数の中身を5に
}

// int型ポインタのアドレスを受ける
void func2(int** pt){
	**pt = 6; // ポインタが指す先のポインタが指す先の変数の中身を6に
}

int main(void){
	int a = 0;
	func1(&a); // 変数のアドレスを渡す
	printf("call func1(&a)\n");
	printf("a=%d\n\n",a);
	
	int* b = &a;
	func2(&b); // 変数のアドレスを格納したポインタのアドレスを渡す
	printf("call func2(&b)\n");
	printf("a=%d *b=%d\n\n", a, *b);
	
	func1(b); // 変数のアドレスを格納したポインタを渡す
	printf("call func1(b)\n");
	printf("a=%d *b=%d\n\n", a, *b);
	
	return 0;
}
```

```:output1
$ ./sample1
call func1(&a)
a=5

call func2(&b)
a=6 *b=6

call func1(b)
a=5 *b=5
```

コードとコメントを見てもらえればだいたいわかってもらえるでしょうか．

`main()`内の最初の`func1()`には`pt`に変数`a`のアドレスを渡していて，`func()`内で`*pt`と書くことで変数`a`の中身を操作できます．

`func2()`では，`pt`がポインタ`b`のアドレスを格納し，ポインタ`b`が変数`a`のアドレスを格納しているので，`*pt`で`b`の中身を，`**pt`で`a`の中身を操作できます．

最後の`func1()`にはポインタ`b`を渡すことで`b`が格納している`a`のアドレスを渡しています．


# 次に配列をポインタ渡ししてみた，そしてポインタ演算もしてみた

配列についてはこんなコードを試してみました．

```sample2.c
#include <stdio.h>

// char型変数のアドレスを受ける
void func1(char* pt){
	pt[0] = '1';
	pt[1] = '2';
	pt[2] = '3';
}

// char型ポインタのアドレスを受ける
void func2(char** pt){
	// ポインタ演算
	**pt = '4';
	*(*pt + 1) = '5';
	*(*pt + 2) = '6';
}

// char型ポインタのアドレスを受ける
void func3(char** pt){
	// 添え字
	(*pt)[0] = '7';
	(*pt)[1] = '8';
	(*pt)[2] = '9';
}


int main(void){
	char a[4] = "000";
	func1(a); // 配列の先頭アドレスを渡す
	printf("call func1(a)\n");
	printf("a=%s\n\n",a);
	
	char* b = a;
	func2(&b); // 配列の先頭アドレスを格納したポインタのアドレスを渡す
	printf("call func2(&b)\n");
	printf("a=%s b=%s\n\n", a, b);
	
	func1(b); // 配列の先頭アドレスを格納したポインタを渡す
	printf("call func1(b)\n");
	printf("a=%s b=%s\n\n", a, b);
	
	func3(&b); // 配列の先頭アドレスを格納したポインタのアドレスを渡す
	printf("call func3(&b)\n");
	printf("a=%s b=%s\n\n", a, b);

	return 0;
}
```

```:output2
$ ./sample2
call func1(a)
a=123

call func2(&b)
a=456 b=456

call func1(b)
a=123 b=123

call func3(&b)
a=789 b=789
```

今度は配列なので`a`はchar型配列の先頭アドレスになります．
なのでポインタに代入する際，先ほどは`b = &a`でしたが，今度は`b = a`になっています．

コードとコメントから「こう書くとこうなる」を感じ取ってもらえるでしょうか．

ちなみに，`func2()`，`func3()`内の

```C:func2()
*(*pt + 1) = '5';
```

や

```C:func3()
(*pt)[1] = '8';
```

の`()`を書かないと，前者はコンパイル時にエラーになり，後者は実行時にコアダンプします．
演算に優先順位があり，それが変わってしまうからです．

`()`を書かなかった場合の優先順位を`()`で表現するとおそらくこうです．

```C:func2()
(**pt) + 1 = '5'; // 代入する式になっていない
```

```C:func3()
*(pt[1]) = '8'; // ptに2番目の要素はない
```

`func3()`の`pt`について，添え字が`0`の`*pt[0]`だけは`()`無しでも大丈夫です．

# まとめ

ポインタについていろいろな例を見てきました．
何かしら理解が深まったり発見があったりすれば幸いです．

ちなみに，ポインタ型の宣言は`int* b;`と`int *b;`の2通りの書き方がありますが，僕は前者が好きです．

以前は後者で書いていたのですが，どうも間接演算子の`*`（`*pt = 5`とかの`*`）と混同して覚えてしまっているような気がして，それからは前者で書いて自分に別物だと言い聞かせています．どちらで書いても構いませんが，別物だということを覚えておいてください．
BASIC認証の越え方

## ダイアログで入力する

一番、普通のやつ。
URLにブラウザでアクセスすると次のようなダイアログが表示される。
ダイアログのデザインはブラウザが異なると多少変わるが、*ユーザ名*、*パスワード*が求められるのは共通。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/32533/020886f8-b910-50ad-8b27-e833ad996067.png)

正しい*ユーザ名*、*パスワード*を入力するとURLにアクセスできる。

### cURLの場合

次のように`-u` オプションに*ユーザ名*、*パスワード*を`:`（コロン）でつないで設定してBASIC認証を越える。

```bash
$ curl -u <ユーザ名>:<パスワード> https://www.example.com/login
```

## URLに埋め込む

URLに次のように*ユーザ名*、*パスワード*を埋め込んでしまうという方法もある。

```
https://<ユーザ名>:<パスワード>@www.example.com/login
```

*ユーザ名*、*パスワード*に`@`を含む場合にはURLエンコードすれば良い。

BASIC認証に特に対応する機能を持たないアプリケーションからBASIC認証の向こうにあるAPIなどにアクセスする場合などに便利。
ただし、アクセス先のURLをログなどに出力する仕様になっているとパスワードも出力されてしまうため注意が必要。

## Authorizationヘッダで送る

プログラムからBASIC認証がかけられたURLにアクセスする場合には`Authorization`ヘッダーに*ユーザ名*、*パスワード*をセットしてリクエストする。

*ユーザ名*、*パスワード*は`:`(コロン)でつなぎ、BASE64でエンコードして、ヘッダ全体では次のようになるようにする。

```
Authorization: Basic <BASE64エンコードしたユーザ名:パスワード>
```

これで超えられる。

## 参考
- [ベーシック認証をURLに直接書く \- Qiita](https://qiita.com/ngkazu/items/6da021edf177f40e1f26)
php-master-changes 2018-12-29

今日は NEWS の更新だけだった！

# 2018-12-29
## weltling: [ci skip] Update NEWS
- https://github.com/php/php-src/commit/6896d2a6858231af3f03bef46c7e559f41741fb7
- [7.3~]
- [昨日の修正](https://qiita.com/sj-i/items/54c4e05b93301d06a1fb#weltling-fixed-bug-77346-webm-files-incorrectly-detected-as-applicationoctet-stream) の NEWS への追記
base64 encode and decode in command line


```sh
$ echo -n "credentials" | base64
Y3JlZGVudGlhbHM=

$ echo -n "Y3JlZGVudGlhbHM=" | base64 --decode
credentials
```

> `echo -n` とせず `echo` としてしまうと、末尾の改行コードが変換結果に含まれてしまうため、意図した結果にならない。注意すること  
> $ echo "credentials" | base64
> Y3JlZGVudGlhbHMK
プログラマの最強Github Issue英語勉強法  下書き不要 @yumainaura @Medium @Twitter @Facebook @Qiita 

# まとめ

# Github issue に英語記事を書く
Google検索対策でMedium にインポート、Twitter Facebook 拡散

# Github issue に英語+日本語記事記事を書く
Google検索対策でMedium にインポート、Twitter Facebook 拡散

# Qiitaに日本語記事を書く
英語を削ったりして編集度を上げていく

# 完成！
この世界に3つの記事が生まれる
下書きから完成品へと、少しずつ編集度をあげてゆける

# Draft機能なんかいらなかったんや
すべてをスナップショット撮影的に世間に見せたら、誰もが幸せになれそうじゃないか

# はてぶも挟むと素敵

コンボしていこう！人生は格ゲー。エンジニアリングのアウトプットis格ゲーじゃないか。

Google対策、

# この記事にはDraftが四個も

何個作っても良い

ハードル上げすぎて賭けなくなる現象に注意

マインドフルネスの訓練していこう、エネルギーの管理

タイムトライアル、アスリート的な世界に飛び込んでいこう、日本エンジニア！

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

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

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


# tell you 

https://twitter.com/YumaInaura/status/1079180041857028102

![image](https://user-images.githubusercontent.com/13635059/50543352-b3b1cb00-0c19-11e9-95f2-718986b84e53.png)


# one English

Write article in Github issue for never lost your 
Service sustainability
in English

Import to medium for google indexing
and Tweet to twitter
And Share to Facebook

# two

article in github issue in Japanese and English
Improve edit level
Bridge Japanese to English
Learn English super method!

And also import to Medium and share on twitter and Facebook

# Three

Write article Japanese service Qiita 
Engineering blog service platform
Delete English and improve Japanese expression

# In this way 

3 articles born

# Becafule

this method maybe lot of your energy
Take mindfulness
Train meditation it is
Improve all of your speed










<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
2の補数の計算の2つの方法。

#2の補数の計算の2つの方法。

(1)
a=~a+1;     /* 各ビットを反転して1を加える \*/
(2)
a=~(a-1);   /* 1を引いて各ビットを反転させる */

証明　（３ビットで十分なので）
★方法（１）
値［１０進］　　各ビット反転　１を加算［１０進］
０００［　０］　１１１　　　　０００［　０］
００１［　１］　１１０　　　　１１１［ー１］
０１０［　２］　１０１　　　　１１０［ー２］
０１１［　３］　１００　　　　１０１［ー３］
１００［ー４］　０１１　　　　１００［ー４］
１０１［ー３］　０１０　　　　０１１［　３］
１１０［ー２］　００１　　　　０１０［　２］
１１１［ー１］　０００　　　　００１［　１］

★方法（２）
値［１０進］　　１を減算　　　各ビット反転［１０進］
０００［　０］　１１１　　　　０００［　０］
００１［　１］　０００　　　　１１１［ー１］
０１０［　２］　００１　　　　１１０［ー２］
０１１［　３］　０１０　　　　１０１［ー３］
１００［ー４］　０１１　　　　１００［ー４］
１０１［ー３］　１００　　　　０１１［　３］
１１０［ー２］　１０１　　　　０１０［　２］
１１１［ー１］　１１０　　　　００１［　１］
Alamofireを使ったメソッドで返り値を取得する

APIからjsonを取得しようと思った際に、なんども使うことになりそうなので、APIを叩く関数を作り、それを呼び出すようにしようと思いました。
調べたらswiftでjsonを扱うライブラリは[Alamofire](https://github.com/Alamofire/Alamofire)が有名らしいのでそれを使うことにしました。

# 環境
* MacOS Mojave 10.14.2
* Xcode10.1
* Swift 4.2.1

# 最初にやろうとしたこと
まず最初に、単純に関数内でapiを叩いてその値を返すようにしようとおもい下記のように書いてみました。

 ```swift
import Alamofire
import SwiftyJSON

func getJsonData(url: String) -> JSON {
    var json = JSON()
    Alamofire.request(url).responseJSON { response in
        print("in response") 
        switch (response).result {
        case .success(let Value):
            print("success")
            json = JSON(Value)
        case .failure(let Error):
            print(Error)
            json = JSON(Error)
        }
    }
    return json
}
```

URL文字列を取得して、JSONを返すことをしようとしています。これを使いたいところで呼び出してみたところ、

```swift
let jsonData = HandleDataUtil().getJsonData(url: requestURL)   // HandleDataUtilは上記関数を書いてるクラス
print(jsonData)
```

コンソールには下記のように表示されました。(全部の修正完了後に思い出し思い出し書いてるのでちょっと違うかも...)

```
in response
success
{

}
```

通信は成功してるけど、データが返ってきていません。レスポンスが返って来る前に関数の処理を抜けてしまっているようです。
どうすればいいのか調べていたら、[参考1](https://ja.stackoverflow.com/questions/41152/alamofire%E3%81%A7%E3%81%AE%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E7%B5%90%E6%9E%9C%E3%82%92%E8%BF%94%E3%82%8A%E5%80%A4%E3%81%AB%E3%81%97%E3%81%9F%E3%81%84)を見つけました。

つまりは、

* { response in ...} の部分は完了ハンドラとして渡される
* その完了ハンドラが渡されるのは通信完了後
* しかし、return jsonが実行されるのは通信完了前

ということみたいです。つまり上記でも言った「レスポンス返って来る前にメソッドを抜けてる」ってことです。

# どうするか

対処法は

* 自分で定義したメソッドも完了ハンドラパターンにする

つまりは

* 返り値と受け取りたい型を引数とするクロージャ型をメソッドの引数に追加
* Alamofireの完了ハンドラのなかで自前の完了ハンドラを呼ぶ

ことで解決できます。

最終的に下記のようなコードで実現できました。

```swift
func getJsonData(url: String, completion: @escaping (JSON) -> Void) {
    Alamofire.request(url).responseJSON { response in
        print("in response")
        switch (response).result {
        case .success(let Value):
            print("success")
            completion(JSON(Value))
        case .failure(let Error):
            print(Error)
            completion(JSON(Error))
        }
    }
}
```

呼び出し側は

```swift
var jsonData = JSON()
HandleDataUtil().getJsonData(url: requestURL) { json in
    jsonData = json
    print(jsonData)
}
```

となります。なんか、最終的にやりたいことと違くなってしまった・・・。

# 結論
ここまできてなんですが、最終的に思ったのが「メソッドにする価値がないな」です。理由は

1. 成功した場合、失敗した場合のハンドリングができない
2. 記述量に大差がない。結局クロージャを使ってるので、これならAlamofireベタ書きと大差ない
3. むしろAlamofireそのまま書いた方が処理の流れが見やすい。

そもそもAlamofire自体、非同期通信をSwiftで簡単にかけるようにしてくれるライブラリですから、そのまま使えばよかったんだなと反省してます。


# 参考
1. [Alamofireでのリクエスト結果を返り値にしたい - スタック・オーバーフロー
](https://ja.stackoverflow.com/questions/41152/alamofire%E3%81%A7%E3%81%AE%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E7%B5%90%E6%9E%9C%E3%82%92%E8%BF%94%E3%82%8A%E5%80%A4%E3%81%AB%E3%81%97%E3%81%9F%E3%81%84)
python から google spreadsheet 上のデータを取得 (service account) 

## 背景

- Google検索して上位に出てくる結果がネット上のサンプルコードがユーザのOAuth認証を前提としている。(GCP公式ドキュメント含め) 
- アプリケーション側から直接コールさせるので、サービスアカウントを利用したい。 
- ref: 
[Python with Google Sheets Service Account: Step by Step | Medium](https://medium.com/@denisluiz/python-with-google-sheets-service-account-step-by-step-8f74c26ed28e)


## 手順

1. GCPコンソール上でサービスアカウント作成
2. サービスアカウントに紐づくAPIアクセス用の credential をGCPから保存 (例: `credential.json` )
3. service accountのemailアドレスを任意のspreadsheetに共有設定する
3. 以下のコマンド群を書き込む


```python 
# install 
# pip install --upgrade google-api-python-client oauth2client

import httplib2
import os

from apiclient import discovery
from google.oauth2 import service_account

# configure
scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly']
secret_file = os.path.join(os.getcwd(), 'credential.json')
credentials = service_account.Credentials.from_service_account_file(secret_file, scopes=scopes)
service = discovery.build('sheets', 'v4', credentials=credentials)

# spreadsheet
spreadsheet_id = '1EoBDbH7QRVS5F8O7YNAiKWMzETLkNU6wIKKCJSSItnuS'
result = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range="'シート1'!A1:AC767").execute()
values = result.get('values', [])
```

## おわり

Jupyter Notebook 等からでもこの数行で動かせます
react + typescript + materialUI + etc の作業ログ

# 目的
Reactにtypescriptを導入して、よく使うモジュール（redux,router,materialUI）を加えた作業を備忘録的に書き起こします。

## 前提
create-react-appを使用して、プロジェクトを作成しています。

```
yarn global add create-react-app
```

## 作業ログ

- プロジェクトの作成

```
create-react-app appName --scripts-version=react-scripts-ts
```

- モジュールの追加  

```
yarn add react-redux react-router react-router-dom connected-react-router redux
yarn add -D @types/react-redux @types/react-router @types/react-router-dom
yarn add @material-ui/core
yarn add @material-ui/icons
```


## お好みで
tslint.jsonのruleをお好みで変更する

```json
  "rules": {
    "object-literal-sort-keys": false,
    "interface-name": false,
    "member-access": false,
    "ordered-imports": false
  },
```
課金ユーザー無料ユーザーの境界線を飛び越えさせる方法を考える @yumainaura #iPhone #App 

https://twitter.com/YumaInaura/status/1079174464129052672

# 最近物理世界のデコレーションが好きだ！

# Decorate Decorate Decorate !

![image](https://user-images.githubusercontent.com/13635059/50543269-99c2b900-0c16-11e9-9b2e-cdc79d5b880b.png)

![image](https://user-images.githubusercontent.com/13635059/50543271-a47d4e00-0c16-11e9-99db-5c1e0e61137c.png)

# Analog world decorate

i love them😍

# Before im not paid user

昔はhikakinユーザーだった
非課金

# But i was changed

だが変わった
その経験から考える

課金ユーザーと非課金ユーザーは何が違うのか
これはユーザーの属性のようで、無理矢理には変えられないように思う

# Lets devide 3 types

三種類にユーザーを分けて考える

デコレートを愛していてお金を払うユーザー
デコレートを愛し得ておらずお金を払わないユーザー
そのグレーゾーンのハーフ

# How make "half of them" user to "paid user"?

どうやってハーフを愛するものに変える？

デコレートを愛しているユーザーのアイテムをこれとばかりに見せつけるとか？
とにかくインパクトを残して、課金境界線を飛び越えさせたい
プランナーでもなんでもないSEが考えているだけのことなので、こんなこと当たり前ですよね

でもエンジニアも課金非課金のことが知りたいんですよ？🎉

# YES

can i tell you well?


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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
サービスの重要アクションのショートカットキーをユーザーが押しにくい「右手」に割り当ててはいけない #UI #UX @yumainaura


# Google Chrome Command/Control+Y shortcut is too great why dont you use it? 

Google の command + Y の履歴使ってる？

![image](https://user-images.githubusercontent.com/13635059/50543178-8bbf6900-0c13-11e9-8c65-ad313054ded6.png)

Y って押しにくい！！！！
だから使われてないんじゃない？
この偉大なるショートカットってさ

I think Y is difficult to push in keyboard
i think Y is rare shortcut key mapping
so user hard to find this so useful shortcut and features

# hey

UI語りたい。
もし重要アクションにショートカットキーを割り当てるなら
「ファボのFをとってFだー！」とかいう決め方をしてはいけない

いや、Fは押しやすい例だけどさ

lets talk about service interface
if you map shortcut to some important feature
do not think about head letter 

# e.g Favorite shortcut is Command + F

nO!!!!

ユーザーが押しやすいキーを需要アクションに割り当てようぜ

please map shortcut "User easy to push key"
What is Easer shortcuts to push?

# Left hand

PC キーボードなら 「左手エリア」とかさ！

![image](https://user-images.githubusercontent.com/13635059/50543192-0d16fb80-0c14-11e9-92fe-dacfb68c7705.png)









<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AR Guitar作ってみた

#はじめに

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ARギターできた！ <a href="https://t.co/TQQ28j28m6">pic.twitter.com/TQQ28j28m6</a></p>&mdash; a2kiti (@a2kiti) <a href="https://twitter.com/a2kiti/status/1043686332847902721?ref_src=twsrc%5Etfw">2018年9月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ギターの演奏に合わせてAR表示をしてみた。

フレットが青色に光り，押さえたボジションが丸く光る。
弾いたら音符が画面上の楽譜に飛んでいき自動的に採譜されるようになっている。

# 構成

##ハードウェア

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201397/3711bdfd-c9cb-a3fe-1b04-dddffa44fd69.png)



ギターに貼り付けたARマーカーをカメラで認識することでギターの位置と姿勢を取得し，カメラ画像上の指板に描画するために必要な情報を得る。
どのフレットを弾いているのかはギターシンセによりMIDI信号に変換することで取得している。ギターシンセからは1〜6弦のそれぞれのノート番号が出力されるため，下記のように各弦の開放音を引けばフレット番号になる。

1弦：ノート番号 - 64(E音）
2弦：ノート番号 - 59(B音）
3弦：ノート番号 - 55(G音）
4弦：ノート番号 - 50(D音）
5弦：ノート番号 - 45(A音）
6弦：ノート番号 - 40(E音）

ギターシンセ用ピックアップは弦ごとにマイクがあり，MIDI信号が個別に出力されるため，単音ではなくコードでも問題なく弾いているポジションを取得することができる。
ちなみに動画で使用しているギターはブリッジにピエゾが仕込まれており，外付けの専用ピックアップなしでギターシンセを使用可能。

##ソフトウェア
ソースは汚いけどgithubにあげた。
https://github.com/a2kiti/ARGuitar

プログラムにはアニメーションなどの描画に特化したProcessingを使用。
基本はJavaでPythonでも記述できるらしいが，ライブラリの使用等に制限がありそうだったのでJavaで書いた。大学の演習でブロックスを作ったの以来だったので，さっぱりだったけど。

ARマーカーの識別にはNyARToolkit for processing
https://github.com/nyatla/NyARToolkit-for-Processing
MIDI処理にはTheMidiBus
http://neralt.com/processing-midi-controller/
を使用した。

ARマーカーを認識すると姿勢がわかるがフレットの位置はマーカーを貼り付けたギターの位置によるため，手動で位置のキャリブレーションし保存できるようにしてある。

フレットの位置はナットからの距離を*l*，フレット数を*n*，弦の長さを*L*とすると

```math
l = 2^{(12-n)/12} \times \frac{L}{2}
```
で計算できる。

ギターシンセがMIDI信号を出力してくれるため，前述の通り各弦ごとに開放弦のノート番号を引くだけでどのフレットを押さえてるかわかる。

# 何に使えるか
オンラインでのギターのレッスンやレッスン動画を演奏動画を投稿しているyoutuberの人が使うといいかも。

もともとライブするときになにか演出に使えないかと考えていたのだが，このままだとカメラで撮影した動画にしかAR表示することができない。プロジェクターを使って実際のギターに投影したらなにかできるかもしれないので今後試してみたい。


今後試したいこととして
・プロジェクターでの投影
・通常の出力からのノート番号取得
現在はギターシンセによるMIDI信号への変換を使用しているが，ギターシンセ用のピックアップを持っている人はかなり少ないため，専用ピックアップではなく通常の出力からノート番号を推定できるようにしたい。ギターシンセとして使うにはレイテンシーの問題があり，ローランドが専用ピックアップを使って何年も開発してあの低レイテンシーを実現しているが，単に演出用・採譜用では数10msくらい遅れても問題はないため，ニューラルネットワークを用いた最近の手法を使えばなんとかなる気がする。学習データもギターシンセのMIDI変換ですぐ集められる。
・機械学習と組み合わせるためにPythonでの実行
OpenCVで最初描画しようとしたが処理速度が全然足りなかったので，openGLで描画も検討する。


また，すでに似たようなことをしている人がいた。
https://twitter.com/MatthewHallberg/status/1028725125363982337
こちらの人はunityで作っているようだ。