OmniAICreator/Qiita-1.07M huggingface dataset:
RubyのLintであるonkcop/pre-commitを入れたら、個人開発が幸せになった話


## はじめに

最近個人開発している際に、レビュワーから

「そろそろlint指摘するのしんどいから、rubocop入れるといいよ。特にonkcopオススメ。」

とのお達しが来たので、この機会に導入してみることに。

本記事は、onkcopとpre-commitの導入手順をまとめたものです。

## この記事の対象者

* Rubyを学びはじめて3ヶ月くらいの初心者
* rubocop/onkcop/pre-commitの導入方法について知りたい方

## onkcopを導入する

onkcopとは、 rubocop を拡張したgemです。

基本的には、公式リポジトリのREADMEに沿ってやればOK。

https://github.com/onk/onkcop

Gemfileに、onkcopとrubocop-railsを追加します。

```rb
gem "onkcop", require: false
gem “rubocop-rails”
```

その後、bundle installしましょう。

```bash
bundle install --jobs=4
```

bundle installができたら、今度はonkcop設定用ファイルを作成します。

```bash
bundle exec onkcop init
```

そうすると、プロジェクト直下に`.rubocop.yml`というファイルが作成されるので、次のように書き換えます。

```rb
require:
  - rubocop-rails

# 2020/11/8現在、onkcopそのままのファイルを利用すると、LayoutやNaming、Styleのルール名変更によるエラーが出るので、独自で作ったファイルを継承して指定する
inherit_from:
  - "config/rubocop/rubocop.yml"

inherit_gem:
  onkcop:
    - "config/rails.yml"
    - "config/rspec.yml"

AllCops:
  TargetRubyVersion: 2.5
  TargetRailsVersion: 5.1
  Exclude:
    - "vendor/**/*" # rubocop config/default.yml
    - "db/schema*.rb"
    - "node_modules/**/*"
    - "db/migrate/**/*"
```

ここでは、`rubocop` の設定で、`onkcop` を継承して、`onkcop`内の`config/*`を使うかどうかをコメントインアウトして決めています。

また、Excludeの箇所は、onkcopによるチェックの対象外となるファイルをリストアップしています。

もし、大規模な開発だったり、元々rubocopを入れているという場合には、

`inherit_from: ./config/rubocop.yml`

のように継承元となる`rubocop.yml`を明記するのも一つの手ですね。

判断基準としては、

**一つのファイルで管理していたが、見通しが悪くなったので分割する**

くらいでしょうか。

ここまで設定できたら、一旦rubocopを走らせてみましょう。

```bash

bundle exec rubocop -a
```

これは、rubocop.ymlで設定したルールに基づいて、自動的に修正してくれる便利なコマンドです。

ただ、自動修正しきれない箇所もあるので、それについてはもう一度rubocopをパトロールさせて手動修正します。

```bash

bundle exec rubocop
```

```bash

Yutas-MacBook-Air:qiita_clone ushijimayuuta$ be rubocop
Inspecting 57 files
..................................................C......

Offenses:

spec/controllers/api/v1/articles_controller_spec.rb:20:5: C: RSpec/EmptyLineAfterHook: Add an empty line after before.
    before { @article = attributes_for(:article) }
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

57 files inspected, 1 offense detected
```

こんな感じの実行結果になるので、適宜修正してください。

まとめると、`onkcop`の導入手順としては、次の通りです。

1. `gemfileにonkcop追加`
1. `bundle install`
1. `bundle exec onkcop init`
1. `.rubocop.yml`の修正
1. git管理しないものは、`rubocop.yml` or `.rubocop.yml`にexclude

## いちいちrubocopをパトロールさせるのがめんどくさい、そんなあなたに！

rubocopは便利なんですが、コード書いた後にいちいちrubocopを走らせるのは面倒ですよね。

そんな時は、pre-commitというライブラリを導入しましょう。

これは、git commitを走らせた際に設定した処理を自動的に実行してくれる、便利なライブラリです。

導入方法については、以下のサイトが非常に参考になりますので、紹介されている手順に沿ってやってみてください！

https://dev.classmethod.jp/server-side/pre-commit-rubocop/


## 自動化は正義

レビュワーにとっても、細かいlintをいちいち指摘していたら面倒ですし、見逃すこともあります。

また、個人開発をしているエンジニアにとっても、コマンド一発で自動的にコードを診断してくれるので、かなり便利なんじゃないでしょうか。

レビュワーがいない環境だと、自分の書いているコードが「きれい or きたない」なんてあまり気にしないですしね。

でも、rubocopを使えば、ある程度コードの可読性を担保できるので、そういう意味では、導入する価値はあるでは？と思いました！
Gulp + yarn シンプルJQuery構成

# 動機

- jQueryのライブラリっていつもダウンロードしてくるの疑問に思ってた。
- jQueryのライブラリのバージョンっていつも同じではないよね。
- bowerの更新がストップしたとのことなので、yarnでパッケージ管理をする。
- webpackいまいちわかんね。

# やりたいこと

- yarnでJSのパッケージ管理
- 旧体制（Only gulp または bower）からの脱却

# Dir 構成

```text:Dir構成
dist　→　書き出し先
```

```js:gulpfile.js
const paths = {
    "css": "./src/assets/css/",
    "cssf": "./src/assets/css/**/*.css",
    "js": "./src/assets/js/",
    "jsf": "./src/assets/js/**/*.js",
    "scss": "./src/assets/scss/**/*.scss",
    "sass": "./src/assets/scss",
    "img": "./src/assets/img",
    "html": "./src/**/*.html"
}
```

## Gulp task

（注意）開発者によっては、特定のフォルダであればライブラリをダウンロードして来てもらってもいいので、
concat＜結合＞はしない。

```js:gulpfile.js
// npmで入れたフロントエンドライブラリをlibsに移す
gulp.task('vendor', () => {
    return gulp.src([
        "node_modules/jquery/dist/jquery.min.js",
    ])
    .pipe(plumber({
        errorHandler: (error) => {
            notify('vendor', error);
        }
    }))
    .pipe( gulp.dest( paths.js + '/libs' ));
});
```

## どうなるか
gulpfile.jsの中でJSのライブラリを管理することになる。
ディレクトリ構成を見れば途中でプロジェクトに参加してきた人も何使ってるかわかるけど、新しくインストールするときにはちょっとめんどくさい。

（手順）

1. yarnでインストール
2. gulpfile.jsに記述
3. htmlでライブラリ読み込み

## 知ったこと
npmを使いやすくした（※1）のがyarnらしく、npmでインストールしていたgulpなどのパッケージもyarnで管理できるっぽい。

※1 : ダウンロード時間を短くした、一度使ったライブラリはオフラインでも使える、癒やしの絵文字

# 最近書いた記事
[Dockerで作るWordPressテーマローカル開発環境](https://qiita.com/KoichiSugimoto/items/fc993e2d52dbed39fc79)
[Gulp + Webpack + Babel + Vue.js で作るWordPressテーマ開発環境](https://qiita.com/KoichiSugimoto/items/d8a5563f197682dea0f4)
[Gulp + Webpack(+Babel)でシンプルJQuery構成](https://qiita.com/KoichiSugimoto/items/283d967169546c3f2dce)

# 参考サイト
[Bower は deprecated なので Yarn へ移行した](http://ohbarye.hatenablog.jp/entry/2018/01/15/224232)
[僕なりのフロントエンド開発環境2016年版](https://qiita.com/koh110/items/83cb29f8ecc2738ea8bb)
Flutter の実行時に Resolving dependencies... から進まないときの解決メモ

## `flutter run` したときに `Resolving dependencies...` から進まなくなった

```sh
Error retrieving device properties for ro.product.cpu.abi:
error: insufficient permissions for device.

Launching lib/main.dart on <myDevice> in debug mode...
Initializing gradle...
Resolving dependencies...
```

一回目のビルド・実行時には見られなかったが、
二回目以降でビルドが通らなくなった

## 対象読者

```sh
$ flutter analyze -v
```

を実行して

```sh
  error • The function 'test' isn't defined • workspace/dart/flutter/packages/fuchsia_remote_debug_protocol/test/src/runners/ssh_command_runner_test.dart:124:5
```

とかとかエラーがたくさん吐かれる方々

## 結論

[公式](https://www.dartlang.org/dart-2#migration)を参考に `dart2_fix` を突っ込みましょう

### dart2_fixって何者？

> A tool to migrate API usage to Dart 2

dart1.*系のコードをdart2.0.0(2018/08/20時点)にリファクタリングしてくれるツールだそうです

~~build:failedだけど大丈夫か~~

```sh
# Flutterアプリのrootディレクトリに移動
$ cd /path/to/flutter-project/root

# flutter パッケージの更新
$ flutter packages upgrade
```

[ここ](https://github.com/dart-lang/dart2_fix)を参考に

```sh
# dart2_fixをインストール
$ flutter packages pub global activate dart2_fix

# dart2_fixを実行後、自動的にFIX
$ flutter packages pub global activate dart2_fix
```

この状態で `flutter analyze` を実行すると

```sh
$ flutter analyze
Analyzing <project-name>...                                               
No issues found! (ran in 1.5s)
```

となれば成功

## `flutter run` してみる

```sh
Launching lib/main.dart on <myDevice> in debug mode...
Initializing gradle...
Resolving dependencies...
Running 'gradlew assembleDebug'...
Built build/app/outputs/apk/debug/app-debug.apk.
Installing build/app/outputs/apk/app.apk...
I/FlutterActivityDelegate(21630): onResume setting current activity to this
I/vndksupport(21630): sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
Syncing files to device <myDevice>...
```

無事、ビルド・実行できました

~~公式から配布されているものを安易に信用してはいけないことの何よりの証左でしたとさ~~
Python2のchr()がPython3では使えないという話


# chr()関数の挙動の2と3での違い？
きっかけは`chr(03)`という表記がPython2のコードにあったことだった。
これはPython3ではエラーになる。


## 03の0ってなんやねん
頂いたコメントによると03の0とは8進数を表すための前置きのようである。（どうもありがとうございます。）
0x1aとか0b0110の仲間だったのか。

Python2では使えるこの表記も

```
>>> chr(03)
'\x03'
>>> chr(3)
'\x03'
```

Python3では叱られる。正確には**0o3**と書く必要がありそうだ。

```
>>> chr(3)
'\x03'
>>> chr(03)
  File "<stdin>", line 1
    chr(03)
         ^
SyntaxError: invalid token
```

## 数値をバイトに変換する関数としての違い

[ここ](http://d.hatena.ne.jp/fgshun/20090901/1251818730)の記述によるとPython2ではchr()を数値からバイトへの変換に用いれたが，Python3ではそれはbytesという関数がそれを担っているらしい。

したがって，Python2で

```
>>> ''.join(chr(97))
'a'
```

と書いていたプログラムはPython3では

```
>>> bytes([97])
b'a'
```
というリストの形式で書かねばならないらしい。なお前についているbはバイト列であることを示すbである。

今まではencode()で対処してたりしていたが，[類似の事例](http://ism1000ch.hatenablog.com/entry/2013/10/22/090358)からきちんとシリアル送信の文脈ではchr()の代わりにbyte([])を用いたほうが良さそうである。
nodejs系パッケージのバージョンを操作する

## 発端
* かなり久しぶりにelectronのアプリをビルドしようと思った際にバージョンに起因するエラーが発生した。
* reactnativeやcordovaなど他の環境を触った際にnpm系のパッケージを最新にしたのが原因っぽい。
* 正常に動作する安定版のバージョンに変更する。

## 実行内容

* バージョンを確認

```
$ npm view {package名} dist-tags
ex)
$ npm view electron dist-tags
{ latest: '2.0.3', beta: '3.0.0-beta.1' }
```

* 指定したバージョンをインストールする

```
$ npm install {パッケージ名}@バージョン -g
ex)
$ npm install electron@2.0.3 -g
```
sympyで「双曲線関数(hyperbolic function)の方程式 cos(x)*cosh(x)=-1」を教えてもらった

```fullscript.py 
from sympy import *
x = symbols('x')
eq = cos(x) + 1 /cosh(x)
print(nsolve(eq, 0))
print({nsolve(eq, n) for n in range(-10, 10)})
# 7.85475743823761
# {4.69409113297418, -1.87510406871196, 7.85475743823761, -7.85475743823761, 1.87510406871196, -10.9955407348755, -4.69409113297418}
```


(参考)SymPy cannot solve the equation cos(x) = - 1 /cosh(x)
https://stackoverflow.com/questions/51878378/sympy-cannot-solve-the-equation-cosx-1-coshx

```
(google翻訳)
SymPyの "Sym"は記号を表します。 WolframAlphaは象徴的な解決策を見つけましたか？いいえ、それはしませんでした。それがないからです。だから、SymPyはどちらも見つけなかった。
あなたがWolframAlphaから得たものは、数値的な解決策です。それらを得るために、他のPythonライブラリ、特にSciPyがあります。
しかし、SymPyは、ボンネットの下でmpmathを呼び出すことで、数値的な解を得ることもできます。これはnsolveで行われます。それは2番目の引数、すなわちsolutionの探索の初期点をとり、1つの解を返します。

>>> nsolve（eq、0）
7.85475743823761
もっと必要な場合は、複数の出発点を試してみてください：
>>> {範囲（-10,10）のnのnsolve（eq、n）}
{4.69409113297418、-1.87510406871196、7.85475743823761、-7.85475743823761、1.87510406871196、-10.9955407348755、-4.69409113297418}
ここで私は20の出発点を試しました、いくつかの根は繰り返されました、それゆえ、反復を排除するセットの使用。
無限に多くのソリューションがあります。どんなツールが使われても、あなたはそれらのいくつかを得るだけです。しかし、大きなxに対して、1 / cosh（x）は事実上0であるので、根はcos（x）= 0とほぼ同じであり、pi / 2 + pi * k、任意の整数kである。
```

(参考)3.2. Sympy : Python での代数計算＞Sympy はバックグラウンドで mpmath を利用します,
http://www.turbare.net/transl/scipy-lecture-notes/packages/sympy.html
Springの@Asyncで利用するTaskExecutorを分ける

`@Async`での非同期処理において、`ThreadPoolTaskExecutor`をすれば同時実行数の制御が可能となります。
しかし、重要な処理と大して重要でない処理を同じThreadPoolで管理してしまうと、重要でない処理が大量に実行待ち状態になったとき、重要な処理を実行しようとしても、なかなか実行できないといった問題が発生します。

そこで、処理によって利用するTaskExecutorを分けて、別のThreadPoolで管理させようと思います。

# 実装方法

TaskExecutorを2つBean定義する。
どちらもThreadPoolTaskExecutorで、同時実行可能数は1にしています。

```java
@SpringBootApplication
@EnableAsync
public class TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class, args);
    }

    @Bean
    TaskExecutor importantTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(5);
        return executor;
    }

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(5);
        return executor;
    }
}
```

非同期処理を行う部分は以下のように実装します。（インターフェースは省略）
`@Async`で利用するTaskExecutorの名前を指定します。
処理の中で、10秒間のスリープを挟むことによって、実行待ち状態が発生するようにしています。

```java
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    @Async("importantTaskExecutor")
    @Override
    public void importantTask() {
        try {
            log.info("start important task");
            TimeUnit.SECONDS.sleep(10);
            log.info("end important task");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async("taskExecutor")
    @Override
    public void task() {
        try {
            log.info("start normal task");
            TimeUnit.SECONDS.sleep(10);
            log.info("end normal task");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
```

以下のコードで動作を確認しました。

```java
@RestController
@RequiredArgsConstructor
public class TaskAsyncController {

    private final TaskService taskService;

    @GetMapping("/")
    public String task() {
        taskService.task();
        taskService.task();
        taskService.task();
        taskService.task();
        taskService.importantTask();

        return "Success!!";
    }
}
```

実行すると、taskメソッドは1つ実行されますが、残り3つは実行待ち状態となります。
しかし、importantTaskメソッドは実行待ちにはならず、すぐ実行されます。

これで、別のThreadPoolTaskExecutorが利用できていることがわかります。
DBのテーブル結合など

1. テーブルをつなげて検索するにはJOIN（結合）を使用
2. JOINには「INNER JOIN」「RIGHT JOIN」「LEFT JOIN」がある
3. 検索では`*`は基本使わず、カラムを1つ1つ指定することで思わぬ情報漏えい防げる
4. SQL文内でカラム名やテーブル名のうしろに「AS」をつけて適当な別名をつけることができる。別名はSQL内で使え、データを取得したときのキーにもなる
5. 新たにカラムを追加する場合、既存のアプリケーションに修正が必要かどうかを調査する。調査は該当テーブル名でGrep（検索）して修正が必要か見極める

>[ウェブカツ！！](https://webukatu.com/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
[備忘録]Pythonでシェルコマンドを動かす

# Pythonでターミナル操作した時に詰まったところの備忘録

アドカレ2週目始まりました！！！
今日で１０回目となりますCSGアドカレ頑張って行きましょう！！
多分三回書くのかな．．．
今回はPythonでターミナルを動かしたのでその備忘録を．．．

最近RaspberryPiを使った時にPythonで全体的に制御しながら既存のJavaで組んだプログラムを動かしたいといったことになりました．その時に色々調べつつやったのですがすこし詰まったところがあったので，その備忘録程度に．．．

## Pythonからシェルコマンドを実行する

Pythonからシェルコマンドを動かすにはos,またはsubprocessを使うことになります．

まずosからシェルコマンドを実行してみましょう

```py
import os

os.system('ls')
```
これでlsコマンドを実行できます.
次にsubprocessからシェルコマンドを実行してみましょう

```py
import subprocess

subprocess.call('ls')
```
これでlsコマンドを実行できます

こういった風にシェルコマンドを実行することができます．
そして,シェルコマンドに表示されたものをpythonの変数に格納したいとなりました．

そこでsubprocessのPopenを用いて

```python
import subprocess
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True).communicate()[0]
```

として変数にとったのですがここで少し詰まってしまいました.

## Pythonでターミナルに表示された文字を変数に取り込む

先ほどの

```python
import subprocess
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True).communicate()[0]
```
でとるとバイト文字列になっていたため,それをうまく扱えないといったことになっていました．ここでバイト文字列を普通の文字列へ変換する必要がありましたので

```py
import subprocess

cmd = 'ls'
process = (subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True).communicate()[0]).decode('utf-8')
print('コマンドは\n'+process+'です')
```

となり,このようにutf-8にデコードしてあげることで通常の文字列として扱うことができます．

# つまり

```py
import subprocess

cmd = 'ls'#<=ここにコマンドを当てはめる
process = (subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True).communicate()[0]).decode('utf-8')
print('コマンドは\n'+process+'です')#何かしらの処理
```

としてあげれば別の言語で実行したプログラムの結果を出力して,Pythonから変数としてとったりも簡単に行えます.
角度値（経緯度など）を丸めて 32 bit でデータ格納

こんにちは。
角度値（経緯度など）を丸め、32 bit でデータ格納したい場合、典型的な手法を試しました。```lon_32 = math.floor(lon/180 * 2**31)``` と整数表現にします。経緯度に適用すると 2 cm の精度となります[^1] [^2]。

[^1]: [S2 Geometry Library](http://s2geometry.io/) の S2 cell でも、地理座標値を 32 + 32 bit に丸め、最小分解能は 1 cm を得ています。

[^2]: なお世の中で、経緯度値を丸め 32 + 32 bit でデータ格納し、数 m の精度となっている事例も見かけます（丸めすぎ？）。

```python
>>> import math
>>> lon = 135.0000001
>>> lon_32 = math.floor(lon/180 * 2**31)
>>> lon_32
1610612737
>>> lon
135.0000001
>>> lon_32 / 2**31 * 180
135.00000008381903
>>> dlon_32 = lon_32 / 2**31 * 180 - lon
>>> dlon_32
-1.6180962347789318e-08
```
WindowsのWSLで始める競技プログラミング(C++)

## はじめに
Windows10ではFall Creators Updateから**Windows Subsystem for Linux(WSL)**が使えるようになりました。
今回はUbuntuをインストールしてC++のコンパイラとテストツールの導入、テストツールの使い方を紹介します。
テストツールは[online\-judge\-tools](https://github.com/kmyk/online-judge-tools)を使っていきます。
参考:[競技プログラミングのための補助ツールを作った](https://kimiyuki.net/blog/2017/01/19/pr-online-judge-tools/)
## 開発環境
- Windows10(Fall Creators Update以降)

## セットアップ
WSLのインストールに関しては省きます。
インストール後、`sudo apt update`と`sudo apt upgrade`を実行しておきます(少し待つ)。
次に`g++`をインストールします。右クリックで貼り付けができます。

```bash
$ sudo apt install g++
```
これで`g++`を使ってC++のコンパイルができるようになりました。
次に`online-judge-tools`をインストールしていきますが、その前に`pip3`を使えるようにします。

```bash
$ sudo apt install python3-pip
```
これで`pip3`が使えるようになったので`online-judge-tools`をインストールします。

```bash
$ sudo pip3 install online-judge-tools
```
これで`oj`コマンドが使えるようになりました。

## 使い方
テストまでの操作を説明します。`oj`コマンドの詳しい使い方は参考ページを参照してください。
サンプルケースを取得します。URLに対応する競技プログラミングのサイトの問題ページのURLを入力してください。

```bash
$ oj dl URL
```
次にコンパイルとテストをします。
ワンライナーで書くと操作が楽になります。

```bash
$ g++ abc000z.cpp && oj test
```
同じディレクトリで他の問題のサンプルケースを取得するときは`--overwrite`を指定します。[^1]

```bash
$ oj dl --overwrite URL
```

## 終わりに
WSLはWindows環境でもLinuxのターミナルが使えるようになったので、Windows環境を気にせずにコンパイル等ができて便利になります。
WSL上ではWindowsのドライブが`/mnt`以下にマウントされています。Cドライブなら`/mnt/c`です。ホームディレクトリにシンボリックリンク等を作成しておくとアクセスがしやすいです。

[^1]: 問題数が減った場合にはファイルが残ってしまうので、気になる人は問題ごとにディレクトリを分けておくといいです。
GPS測位の種類とか予備知識

#注意書き
個人的まとめです。思い込みや勘違いが含まれてる可能性があります。
頭の中の整理も含めて書いてみます。

![L1andL1+L2_-100ms.gif](https://qiita-image-store.s3.amazonaws.com/0/181687/1052aa75-a468-e715-4abc-c6c78b430db5.gif)

Rover L1,Base L1+L2で３倍速録画

#忙しい人のために、先に結論

|製品名|利用可能範囲|精度|種類|LTEとかPC|FIXまでの時間|価格帯|備考|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|C94-M8P|1Km|1cm級|RTK|x|10分程度|5万円程度|内蔵LoRa回線が使えるが約200m程度|
|[トラ技のRTKキット](http://toragi.cqpub.co.jp/tabid/862/Default.aspx)   |１Km|1cm級|RTK|○|10分程度|5万円程度|WiFi,LTE,PCが必要|
|2周波受信機|10Km|1cm級|RTK|○|約1分|30万円程度x2|WiFi,LTEが必要|

#GPS測位の種類と課題

#電波の種類
大雑把に言ってL1,L2,L5という３種類がある。ちなみにL3は核爆発検知用,L4は電離層の研究用です。（GPSも軍事技術とはいえ、おっかねえなぁ・・）
海外フォーラムからの拾い物。
http://insidegnss.com/auto/popupimage/GLONASS%20spectrum%200408.jpg

##L1
カーナビやスマホなどの一般的なGPSといったら、このL1しか使わない方式。
放送されている中身は人工衛星の軌道データで、衛星の軌道位置から現在地を計算できるようなデータが放送されている。

##L2
電離層遅延の計算に必要なデータが放送されているだけなので、測位にはL1も必要。
現状ではプロの測量士が使っているような高価なもの（数十万円台）じゃないと、L1とL2を両方受信できない。

##L5
新しい人工衛星に搭載されている方式。QZSSは今年の４月から開始。
ここ数年の受信機しか対応しておらず、周波数も違うのでアンテナの対応も必要。
アジア通販で買える某大手の測量用GPS（10万円台）は対応していました。

##L6
日本のGPS衛星「みちびき」に搭載されている方式。
cm級の補強する信号。
http://qzss.go.jp/overview/services/sv06_clas.html
だが周波数が違うのと、現状では日本独自方式のようなので、アンテナと受信機は専用のものが必要。
ざっくり調べてみたけれどまだ実験用レベルらしく、両方揃えると２００諭吉さんほどの模様。

###まとめ
一言で言えば値段次第。
L1+L2ならば、アジア諸国が開発バブルになってるおかげで、ネット通販とかで買えば安いけども。それでもフル装備にしようとしたら３０万近くする。
値段的に考えても、一般人に普及するわけないよね・・。
低価格な受信環境が整わないと、今後も普及は難しいと思われる。

#測位する方式いろいろ

###Single
いわゆるカーナビなどに使われてる方式。精度は10ｍ程度。
安価なアンテナ１個だけで済むし、受信機も数千円程度のモジュール１個で済むのがポイント。

###DGPS
基地局で観測したGPSの情報と、基地局の位置情報を移動局に送ることで、移動局の位置情報を計算する方式。精度は１ｍ程度。
同じシステムが２台＋通信回線が必要。今はRTKがあるので使われてないと思う。

###RTK
前記のDGPSの応用技術。必要なシステムはほぼ同じだけど、受信機によってはアンロック（オプション料金）が必要だったり、色々条件があったりする。
原理の詳細は専門文献に譲るとして、大雑把に言うと本来のGPS計算のほかに別の計算式を解くことで、より高精度な位置がわかるというもの。
ただし計算式の原理的な都合により、少々時間がかかる。
L1+L2同士の場合であれば１分以内ぐらいが通常だけど、L1同士だと現状では運が悪ければ１０分程度かかる。
計算中をFloat解、計算が解けた場合をFIX解と呼ぶ。

##PPP
DGPSやRTKは原理的に基地局と移動局の２セットが必要だし、通信回線も不可欠なので設備や通信回線の維持などが高コストになりがち。
一方、PPPは単独で起動時に１０〜２０分くらい測量し続けることで、ｃｍ級を実現できるという方式。
いったん起動してしまえば、衛星を一定数見失わない限り精度は継続できる。
ただし高精度の補正情報が必須のため、現状ではネットから拾ってくる以外には方法がない。
http://www.satnavi.jaxa.jp/project/qzss/news/2014/140909.html
https://www.ipa.go.jp/files/000050351.pdf

###ざっくりまとめると
DGPSのメリットは無いけどPPPは一般人じゃ使えないぽい。現状ではRTKしか選択肢が無い。
RTKだと通信回線が必須になるけれど、wifiも届かないような距離になると、日本の電波法的には3GとかLTEを使う以外には、選択肢がない。

####有効範囲
L1の一周波RTKの場合、ネットにある文献では１−２ｋｍぐらいが限界らしい。
L1+L2のRTKの場合だと、１０ｋｍ超えるとFIX解が得られても間違いが多い。自分が実験した限りでは約14kmでFIXしても誤差4ｃｍ程度あるので、一周波RTKのほうがずっとマシなレベルでした。

#GPSあるあるFAQ
###なんで誤差があるの？
いろいろ要因はあるけど、自分が理解しているのは、おおまかに２つ。
1.電離層の影響。
地表から１０−５０ｋｍぐらいを電離層という。太陽風と地球の地磁気の影響で３６５日ずっと電子レンジが稼働してるような状態になっている。国際線飛行機などの無線は、この層の反射を利用している。
しかしGPSの電波の場合、電離層を通過する際にわずかに遅延するため、その遅延が誤差の原因。
対策としてL2があるのだけど、電子回路が複雑になるため高コストだし、精度も完璧とは言えないのが現状。

2.建物などの反射（マルチパス）や、木の陰などで衛星自体がアンテナから見て隠れてしまう状況。
特に木の陰は、半端なく電波の減衰があります。

###PPPって個人で使えないの？
https://ssl.tksc.jaxa.jp/madoca/public/public_application_en.html
JAXAの申し込み要項の詳細が全てです。

###FIXしないんだけど？
FIXすることをお祈りいたします。
RecyclerViewのViewTypeをlayoutIdにしていると起きること

大したことではないんですが、自分の中で1つの教訓となったので

# 状況
プロジェクトにこんなコードがありました。

```kotlin
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    return when (viewType) {
        RecyclerItemViewType.PROGRESS_BAR-> {
ProgressBarViewHolder(layoutInflater.inflate(viewType, parent, false))
        }
        else -> {
            HViewHolder(parent, viewType)
        }
    }
}
```

ここの `LayoutInflater::inflate()` の第一引数は `layoutId` になってますよね。
このコードではViewTypeとlayoutIdがイコールになってます。つまり

```java
public static final int PROGRESS_BAR= R.layout.recycler_item_progress_bar;
```

layoutIdをViewTypeとして使う固定値に突っ込んでます。
特にこれでも問題なく動くんです。確かに同一にしてると楽なときはたくさんあるし便利なときも多い。上記のように `onCreateViewHolder()` で *viewType* をそのまま *layoutId* として突っ込めばいいし。。
でも個人的にはなにか気持ち悪い。問題ないのかなとずっと思っていたんです。

# なにか起きた。
といっても問題ではないです。
コード書き換えて実行していたときにヌルポが発生したりしました。
よくよく見ていくと先程の `PROGRESS_BAR` のIDが変わっていてonCreateViewHolder()のviewType分岐をすり抜けた模様。


# つまり
新機能開発とbugfixのBranchを切り替えてビルドしての間にlayoutIdが変わったものと思われます。
クリーンビルドしたら直った。こういうのが *「なんだかわからないけどクリーンしたら直った」* につながっているのだと思います。今回はちょうど理解できたからいいですが、これが積み重なると「よくわかないときはクリーンしとけ」という神話になっていくのかなと。

個人的には便利なのでつかってもいいかなと考えてます。しかし、上記の前提を踏まえた上で。
以上、メモでした。
よくサンプルとしてある表示、非表示の簡単な処理

よくある表示、非表示サンプルを自分で作ってみました。
まずは小さな事からコツコツと。


１．まずはIDを取得してからstyleでdisplay = "none";を当てる。

２．関数で囲み、変数でidのbox1を取得。
次にif文の条件分岐で変数boxにdisplayがblockの場合は非表示にする。
処理を施すように命令。

3.次にその他の場合はdisplay blockを適用し、要素を表示させる。

4.inputのボタンで表示、非表示のイベントを発生させる。

![スクリーンショット 2018-08-21 22.36.33.png](https://qiita-image-store.s3.amazonaws.com/0/263583/298e5e40-9874-2ed3-66b0-2ab9bb12a48a.png)
![スクリーンショット 2018-08-21 22.36.16.png](https://qiita-image-store.s3.amazonaws.com/0/263583/ba7ded9a-9a93-95f9-a949-865f69f041f8.png)
![スクリーンショット 2018-08-21 22.44.01.png](https://qiita-image-store.s3.amazonaws.com/0/263583/26aff527-2af2-2d92-4ef4-0a24c7f12f0d.png)
![スクリーンショット 2018-08-21 22.44.07.png](https://qiita-image-store.s3.amazonaws.com/0/263583/5f4bacea-8723-d1c1-691c-882794cce7c5.png)
ラックマウント ワイン棚＆冷蔵庫

#CANFORD RACKWINE Winerack, rack mount 3U
https://www.canford.co.uk/Products/11-231_CANFORD-RACKWINE-Winerack-rack-mount-3U-black
> An essential addition to any wine lover’s rack, this sturdy 3U package offers storage for up to four bottles of your favourite vintage. Finished in black ash melamine coated particle board, these units are supplied ready assembled and ready to install. Maximum bottle diameter 98mm, so even accepts most Barolo, Chianti etc. Wine not included.


# CANFORD FRIDGE Rackmount 13U
https://www.canford.co.uk/Products/13-024_CANFORD-FRIDGE-Rackmount-13U-black
> Ideal for OB trucks, studio hospitality etc. 240V AC powered, 65 watts, energy consumption 0.76kWh/24h. 13U height. Depth required 383mm. Colour black.
f2pyことはじめ

# f2pyの簡単な使い方

## はじめに

科学計算を行う時など、fortranで書かれたコードに遭遇することは多いと思う。このような時、pythonの素晴しい可視化環境に慣れてしまった自分にとっては当然これを使いたいと思うわけだが、変数をいちいちテキスト出力してそれをpython側で読み込みなおして、なんてやってられない。
そんな時、[f2py](https://docs.scipy.org/doc/numpy/f2py/index.html)がおすすめ。
f2pyは、fortranソースをコンパイルして、pythonのモジュール化するもの、と理解しています。pythonで読み易くするためだけでなく、スピードもpythonネイティブより早くなるので、計算のコアをfortranで書き、その結果をpythonの豊富なモジュールを利用して解析・可視化する、という方法はとてもいいと思う。

## 使い方

### コンパイル

```
f2py --fcompiler=xxx -m モジュール名 -c hoge.f90
```

`--fcompiler`で何が指定できるかは、`f2py -c --help-fcompiler`で確認することができる。(-cが必要らしい)
モジュール名は例えば`hoge`など好きな名前を付けよう。

### fortranソースの方

これは至極簡単で`subroutine`で定義したものを用意する。例えば以下のようなもの。

引数は勿論`intent(in)`も使うことができる(と思う)が、python側からfortran側で計算した変数を読み込みたい時には、`intent(out)`で指定する。
また、引数に`intent(out)`で指定している変数を書かないとだめ。

```Fortran
subroutine cal_test(x,y,z)

   integer x,y,z
   intent(out) x,y,z

   x = 10
   y = x * 10
   z = y * 10

end subroutine cal_test
```

## 呼び出す時

上記のコンパイルが上手くいけば、`*.so`ができるはず。それをpythonのモジュールとしてインポートすれば呼び出せる。

また、定義した`subroutine`での`intent(out)`で指定した変数は返り値として返ってくるので、それを受けとるようにする。

```Python
#!/bin/python3
# -*- coding:utf-8 -*-

import test

x,y,z = test.cal_test()

print("x is ", x, ",y is ", y, ", z is ",z)
```

## 終わりに

もっと複雑なコードだとどうなるか分からないのですが、少なくとも一つの`subroutine`で済むような場合ではcythonより面倒さが少なくていいですね。
検証が不十分でつっこみ所満載かと思うのですが、とりあえず始めてみたいという方に参考になれば幸いです。今後も色々検討していきたいと思います。
FlutterでStatefullWidgetとStateを連携する

`State`のサブクラスから、`widget`フィールドを参照することで、`StatefullWidget`のインスタンスにアクセスすることができます。

使い方としてはonChangedなどのコールバック関数をStatefullWidgetのインスタンス作成時に渡しておき、Stateのサブクラスで値の変更があった場合などに`widget.onChanged()`を呼び出すといった具合です。

カスタムウィジェットを作る時に使えますね。
Ramda 利用時の注意事項

# ■ range には step がない

lodash には step があるのに:

```js
> R.range(1, 5, 2)
[ 1, 2, 3, 4 ]
```

# ■ range はエコでない
要素数が無限なループはジェネレータを使う必要あり:

```js
> // never do this: const input = R.range(0, Infinity)
> let input = (function* () { for(let i = 0; ; i += 1) yield i }());
> R.reduceWhile((acc, x) => x < 5, R.flip(R.append), [], input)
[ 0, 1, 2, 3, 4 ]
```

Immutable.js の Range を使うのがよい:

```js
> const { Range } = require('immutable')
> input = Range(0, Infinity);
> R.reduceWhile((acc, x) => x < 5, R.flip(R.append), [], input)
[ 0, 1, 2, 3, 4 ]
```

# ■ flatten より unnest
flatten は強力すぎる。多くの場合、unnest の方が適切:

```js
> R.unnest(R.range(0,3).map(x => R.range(x,3).map(y => [x, y])))
[ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 1, 1 ], [ 1, 2 ], [ 2, 2 ] ]
> R.flatten(R.range(0,3).map(x => R.range(x,3).map(y => [x, y])))
[ 0, 0, 0, 1, 0, 2, 1, 1, 1, 2, 2, 2 ]
```

# ■ unary を使え
これは Ramda の問題というよりも、JS の問題。**parseInt**, **console.log**, **fetch** などなど第二引数を受け取ることで挙動が変わる関数を、Array.prototype.map に渡すと意図しない結果になる:

```js
> ['1', '2', '3'].map(parseInt)
[ 1, NaN, NaN ]
> ['1', '2', '3'].map(R.unary(parseInt))
[ 1, 2, 3 ]
> R.map(parseInt, ['1', '2', '3']) // R.map ならOK
[ 1, 2, 3 ]
```

# ■ reduceRight に気を付けろ

Array.prototype.reduceRight の reducer と引数が逆！！！！

```js
> [1, 2, 3].reduceRight((acc, x) => x)
1
> R.reduceRight((x, acc) => x, 'init', [1, 2, 3]) // OK
1
> R.reduceRight((acc, x) => x, 'init', [1, 2, 3]) // NG
'init'
```

しかも `R.reduced` で打ち切れない

```js
> R.reduceRight(()=>R.reduced(100), 0, R.range(20))
{ '@@transducer/value': 100, '@@transducer/reduced': true }
```

# ■ split と負の引数は相性が悪い
配列の最後の 3 要素を取り出したいときは、若干トリッキー。むしろ使うのを避けた方がいい(`takeLast` を使う):

```js
> [1, 2, 3, 4, 5].slice(-3)
[ 3, 4, 5 ]
> R.slice(-3, Infinity, [1, 2, 3, 4, 5])
[ 3, 4, 5 ]
> R.takeLast(3, [1, 2, 3, 4, 5])
[ 3, 4, 5 ]
```

# ■ repeat には癖がある
repeat 対象は同一オブジェクトを参照している

```js
> arrs = R.repeat([1, 2, 3], 4)
[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
> arrs[0].pop()
3
> arrs
[ [ 1, 2 ], [ 1, 2 ], [ 1, 2 ], [ 1, 2 ] ]
```



# ■ 似ている関数に気を付ける
- `all` と `allPass`

```js
> R.all(x => x % 2 === 0)([2, 4, 6]) // Array.prototype.every と同等
true
> R.allPass([x => x > 0, x => x % 2 === 0])(2)
true
```

- `sum` と `add`: 適材適所。同様に、`product` と `multiply` も気を付ける。

```js
> R.sum([1, 2, 3])
6
> R.reduce(R.add, 0, [1, 2, 3])
6
```

- `not` と `complement`: `complement`を使うべきところを `not` にしがち（私だけ？)

```js
> R.not(false)
true
> R.complement(R.isEmpty)([1])
true
```

- `invert` と `invertObj`: `invertObj` の方が使う機会が多い

```js
> R.invert({ one: 1, two: 2 })
{ '1': [ 'one' ], '2': [ 'two' ] }
> R.invertObj({ one: 1, two: 2 })
{ '1': 'one', '2': 'two' }
```

- `head` と `init`: 同様に `last` と `tail` 

```js
> R.head([1, 2, 3])
1
> R.init([1, 2, 3])
[ 1, 2 ]
> R.last([1, 2, 3])
3
> R.tail([1, 2, 3])
[ 2, 3 ]
```
vbs でSQLServer から ADODBでデータを引っ張ってきたときに　ハマった話

## 発生した環境
Server WindowsServer2012R2
SQL SERVER 2012

## はじめに
夜中に vbsやbatを走らせてデータを集計することよくありますよね。 
メモ帳 Terapad等でささっとかいて業務改善
  
今回は1日1回 SQLでSELECTして該当した人にメールを飛ばすvbsです。
わけ合って、SchduleTableを as A と as B　として2回joinしてますが、今回の事象とは無関係かと思います。


## vbs
```sample.vbs
Set objWshShell = CreateObject("WScript.Shell")  
Set OBJa = CreateObject("ADODB.Connection")   
OBJa.Open "Provider=SQLOLEDB;User ID=idPassword=passwordr;Initial Catalog=cadi;Data Source=db"  

SQLQuery ="SELECT A.EMAILADDRESS as to_email ,B.EMAILADDRESS as cc_email,B.USERNAME as displayname "
SQLQuery =SQLQuery & "FROM (Table1 LEFT JOIN Table2 ON Table1.s_id = Table2.ID LEFT JOIN SchduleTable AS A ON A.USERNAME = Table1.huga) "
SQLQuery =SQLQuery & "LEFT JOIN SchduleTable AS B ON B.FULLNAME = Table2.hunsu "
SQLQuery =SQLQuery & "WHERE  huga ='joken'"

Set dr = OBJa.Execute(SQLQuery) 


'A.EMAILADDRESS as to_email 　//toのEメールアドレス
'B.EMAILADDRESS as cc_email   //ccのEメールアドレス
'B.USERNAME as displayname    //氏名

do until dr.eof
    '↓デバッグ用のecho
    'WScript.Echo dr("to_email") & "    " & dr("cc_email")  & "    " & dr("displayname")
    
    '~~~メールを飛ばす処理をここに書く~~~
    dr.movenext
loop
```  
  
とまあコレだとうまく通ります。



エラーが発生したソースは下記になります。

違いは　<font color="Red">**5行目**</font>  の　SELECT方法です。


```error.vbs
Set objWshShell = CreateObject("WScript.Shell")  
Set OBJa = CreateObject("ADODB.Connection")   
OBJa.Open "Provider=SQLOLEDB;User ID=idPassword=passwordr;Initial Catalog=cadi;Data Source=db"  

SQLQuery ="SELECT A.EMAILADDRESS  ,B.EMAILADDRESS,B.USERNAME "
SQLQuery =SQLQuery & "FROM (Table1 LEFT JOIN Table2 ON Table1.s_id = Table2.ID LEFT JOIN SchduleTable AS A ON A.USERNAME = Table1.huga) "
SQLQuery =SQLQuery & "LEFT JOIN SchduleTable AS B ON B.FULLNAME = Table2.hunsu "
SQLQuery =SQLQuery & "WHERE  huga ='joken'"

Set dr = OBJa.Execute(SQLQuery) 

do until dr.eof
        'ここでエラー
        'WScript.Echo dr("A.EMAILADDRESS") & "    " & dr("B.EMAILADDRESS")  & "    " & dr("B.USERNAME")
        
        '~~~メールを飛ばす処理~~~
dr.movenext
loop
```
違いは as で名前を変えているかどうかだけ。

SQLQuery ="SELECT A.EMAILADDRESS as to_email ,B.EMAILADDRESS as cc_email,B.USERNAME as displayname "
SQLQuery ="SELECT A.EMAILADDRESS  ,B.EMAILADDRESS,B.USERNAME "

ADODB　の レコードセットで table.column表記で要素をとろうするととれないかもよ！ということです。


長年この構文を使っていたので、動作はmsdn公式で確認する必要ありそうです。
https://msdn.microsoft.com/ja-jp/library/cc376797.aspx
JavaScriptループと条件分岐の組み合わせ

#はじめに
JavaScriptを学習していく中で自分の為にメモを書き残しておきます。
組み合わせをしていくと、単独で学習していた時より理解が難しくなってきたので。。。


#ループと条件分岐の組み合わせ
`〇`と`◎`を交互に25個表示させてみる。

```JavaScript
let circle = "";

```


変数`circle`に`"";`空を代入してあげる。

```JavaScript
let circle = "";
for(let count = 1; count <= 25; count++) {
    }
```

次に`for`にて、変数`count`に`1`を代入。
繰り返しの条件に25個表示するために`count <= 25`を入力。
ループ内の最後の処理として`count++`にて25回まで繰り返す為に１ずつ追加してゆく。

```JavaScript
let circle = "";
for(let count = 1; count < 25; count++) {
    if(count % 2 === 0) {
        circle += "〇";
    } 
```

for文の中にて条件分岐させる為に`if`を追加。
条件として`count % 2 === 0`にて偶数か、奇数かを判断。
偶数の場合`circle`に`〇`を追加する。

```JavaScript
let circle = "";
for(let count = 1; count < 25; count++) {
    if(count % 2 === 0) {
        circle += "〇";
    } else {
        circle += "◎";
    }
}
console.log(circle);
```

さらに、奇数の場合の判定として`else`を追加し、
奇数の場合、`circle += "◎";`にて偶数の場合と同じ処理をする。
最後に繰り返し範囲外にて`console.log(circle);`にて出力する。

最終的に下記のように出力されます。

```
〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇◎〇
```
xlsx-populateで取得した値がややこしいことになってた時に文字列だけを取り出す方法

RedmineとJavaScriptに身も心も捧げる8amjpです。

## xlsx-populate

さて、私の職場でもRedmineを導入したんですけど、今まで使っていたエクセル形式の帳票も継続して使わなきゃならんという事で、node.jsと[xlsx-populate](https://github.com/dtjohnson/xlsx-populate)というライブラリを使用して、エクセル帳票のインポート/エクスポートツールを作成して運用しているんです。
このxlsx-populate、JavaScriptからエクセルファイルを非常に高い精度で読み書きできる素晴らしいツール。しかもエクセルのインストールは不要です。ありがたいですねー。

ところが、運用しているうちに一つの問題にぶつかりました。

## ややこしい値

```
workbook.sheet("Sheet1").cell("A1").value();
```

xlsx-populateでは、こんな感じでセルの値を取得します。わかりやすいですね。
で、通常は数値やら文字列やら、とにかく単純な値が返ってくるんですけど。たまに、セルの一部の文字だけ赤字にしたり大きくしたりフォント変えたり、と余計な事する人いるじゃないですか。そういうセルの値を取得すると、ものすごくややこしいデータが返ってきます。
どれくらいややこしいかというと、こんな感じ。

```
[
  {"name":"r","attributes":{},"children":[
    {"name":"t","attributes":{},"children":["テキスト1"]}
  ]},
  {"name":"r","attributes":{},"children":[
    {"name":"rPr","attributes":{},"children":[
      {"name":"sz","attributes":{"val":11},"children":[]},
      {"name":"rFont","attributes":{"val":"ＭＳＰゴシック"},"children":[]},
      {"name":"family","attributes":{"val":3},"children":[]},
      {"name":"charset","attributes":{"val":128},"children":[]}
    ]},
    {"name":"t","attributes":{},"children":["テキスト2"]}
  ]},
  {"name":"r","attributes":{},"children":[
    {"name":"rPr","attributes":{},"children":[
      {"name":"sz","attributes":{"val":11},"children":[]},
      {"name":"rFont","attributes":{"val":"ＭＳ Ｐゴシック"},"children":[]},
      {"name":"family","attributes":{"val":3},"children":[]},
      {"name":"charset","attributes":{"val":128},"children":[]}
    ]},
    {"name":"t","attributes":{},"children":["テキスト3"]}
  ]},

  /* 中略 */

  {"name":"phoneticPr","attributes":{"fontId":2},"children":[]}
]
```

なんすかこれ。
まあ、エクセルはエクセルで、指定されたとおり忠実に再現しないといけないわけで、こんな律儀なデータになるんですけど。エクセルには罪はないんですけど。
でも、必要なのは単純なテキストだけなので、その部分だけ取り出したいんです。さて、どうしましょう。

## こたえ

必要な文字列は、「`name`プロパティの値が`t`であるオブジェクトの`children`プロパティの配列内」に入ってます。
で、そのオブジェクトは、「`name`プロパティの値が`r`であるオブジェクトの`children`プロパティの配列内」に入ってます。 
なので、それを上手いこと取り出せばいいんですね。
さあ、JavaScriptが誇る配列操作用の関数、`filter`と`map`関数の出番ですよ。

```
var value = workbook.sheet("Sheet1").cell("A1").value();
if (Array.isArray(value)) value = value.filter(prop => prop.name == 'r').map(r => r.children.filter(prop => prop.name == 't')[0].children[0]).join();
```

書いてて気持ちいいですねー、このコード。
特に細かく解説しませんけど、今まで説明したことをやってるだけですよ。

というわけで、xlsx-populateで取得した値がややこしいことになってた時に文字列だけを取り出す方法でした。

## 2019/9/13 追記

v1.20.0から仕様が変わりまして、[RichText](https://www.npmjs.com/package/xlsx-populate#rich-texts)オブジェクトがサポートされ、リッチテキストを使用しているセルの値を取得するとRichTextオブジェクトが返るようになりました。

```
const RichText = require('xlsx-Populate').RichText;
let value = workbook.sheet(0).cell('A1').value();
let text = value instanceof RichText ? value.text() : value;
```

とすれば、リッチテキストだろうがプレーンテキストだろうが文字列のみを取得できます。

……のはずなのですが、`instanceof RichText`としてもなぜか`false`が返ってきてしまうので、さしあたり


```
let text = value instanceof Object ? value.text() : value;
```

として逃げてます。
JavaScript で Ruby の ActiveSupport の Object#try のような書き方をするには

babel-plugin の [@babel/plugin-proposal-optional-chaining](https://www.npmjs.com/package/@babel/plugin-proposal-optional-chaining) を導入すれば、safe navigation 演算子が使えるようになります。「safe navigation 演算子」とは、たとえば Ruby の `&.` です（Rubyでは「ぼっち演算子」とも呼ばれています）。あるいは ActiveSupport の Object#try です。`hoge & hoge.fuga` を `hoge?.fuga` と記述できるようになります。この文法は 2018/8/21 の時点で [The TC39 Process](https://tc39.github.io/process-document/) の Stage 1 Proposal です。


導入環境の babel 関連パッケージのバージョンは以下です。scoped module の方を使っています。

```
    "@babel/core": "^7.0.0-beta.56",
    "@babel/runtime": "^7.0.0-beta.56",
    "babel-core": "^7.0.0-bridge.0",
```

インストール

```
npm install --save-dev @babel/plugin-proposal-optional-chaining
```

設定ファイルの変更は以下です。


▼ .babelrc

```
  "plugins": [
    [
      "@babel/plugin-proposal-optional-chaining"
    ]
```

▼ .flowconfig

```
[options]
esproposal.optional_chaining=enable
```


## リファレンス

- https://www.npmjs.com/package/@babel/plugin-proposal-optional-chaining
- https://github.com/tc39/proposal-optional-chaining
画像収集用のスクリプトプログラムを作った

##　作ったもの

``` :getImages.sh
  1 #!/bin/bash
  2
  3 keyword=$1
  4
  5 if [ -z $keyword ]
  6 then
  7     echo "put keyword like this"
  8     echo "\$ $0 \"ペンギン 空\" "
  9     exit
 10 fi
 11
 12
 13 echo ${keyword}
 14 keyword=`echo $keyword | nkf -wMQ | tr = %`
 15 echo $keyword
 16 url=http://www.heso.blue/\?text=${keyword}\&max_id=1
 17 echo $url
 18 wget -nd -r -l 2 -H -P ./images/ -A jpeg,jpg,bmp,gif,png $url
 19
 20 rm ./images/*.tmp*
 21
 22 echo "Complete."
```

##　使い方
＊事前に wget　をインストールしておきます。

ターミナル等で　"./getImages.sh 検索ワード" を入力で自動的に関連画像を取得して取ってきてくれます。

##　作った理由
一人前のプログラマーになるための通過点として ~~エロ~~画像を１００枚は自動的に取得できるようになることとの噂を小耳に挟んで。

##　つまづいた点
シバンを sh にしていたため、wgetがうまく動作しなかった。
wgetの一文をターミナルで直接叩くとうまく動くのに、スクリプトファイルに記述して動かそうとするとエラーが出てしまって壁に当たってしまった。

これは、wgetをインストールして使えるようにしたのbashであり、shにスクリプトを渡してもwgetが正常に読み込まれないために起こってしまっていたようだ。

下記質問参照
https://teratail.com/questions/140826


##　参考にしたサイト
https://www.garunimo.com/program/linux/linux16.php
http://capslook.hatenablog.com/entry/2015/07/12/235014
画像収集の根幹部分をここから学習

http://www.heso.blue/
上記検索サイトの検索結果を元に画像を調達。

https://www.m3tech.blog/entry/2018/08/21/bash-scripting
つまづいた箇所はこれを読んで気づくことができた。
任意のKubernetesクラスタからのGCRへのアクセス

自分用メモ

# 目的

任意のKubernetesクラスタからGCR上のDockerイメージをpullできるようにする。

# 設定手順

## GCP上の画面アクセス

![2018-08-21-19-08-41.png](https://qiita-image-store.s3.amazonaws.com/0/40692/01ee4cf5-ce2e-5917-f844-0d32ca3c173f.png)


**ストレージ -> ブラウザ** を選択。

![2018-08-21-19-12-47.png](https://qiita-image-store.s3.amazonaws.com/0/40692/b9d858d1-5576-30bf-ce57-1c6d675c53b0.png)


GCRのリポジトリに対応する**バケット**を見つけて**チェックボックス**を有効化する。
情報パネルリンクをクリックして表示する。

![2018-08-21-19-14-24.png](https://qiita-image-store.s3.amazonaws.com/0/40692/641238a0-5df3-3a38-0d7c-a360d3d7587d.png)


**アカウントのメールアドレス**を設定、**役割を選択ドロップダウンメニュー**から
ストレージを選択し、**ストレージオブジェクト閲覧者**を選択する。

## Kubernetesクラスタへの設定

```bash
$ kubectl create secret docker-registry シークレット名 \
  --docker-server=https://asia.gcr.io \
  --docker-username=_json_key \
  --docker-email=hogehoge@example.com \
  --docker-password="$(cat キーファイル.json)"
```

Dockerレジストリのシークレットを`kubectl`コマンドで作成する。

```bash
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test
      image: asia.gcr.io/プロジェクト名/リポジトリ名:タグ
  imagePullSecrets:
    - name: シークレット名 # <= ここ
```

k8sのマニフェストファイル内、Podのspecを記述しているところで、
`imagePullSecrets`を指定する。


# 参考文献

- https://cloud.google.com/container-registry/docs/access-control
- http://docs.heptio.com/content/private-registries/pr-gcr.html
Opusmodusでピッチに音程を追加する方法いろいろ

Opusmodusでなんだかんだで音程を単純にピッチに追加したいだけの時ってどうするんだっけ、ってよくなるので。

例えばこんな感じのフレーズがあったとして、

```clojure
(setf original '(c4 d4 e4 f4))
```

この上に機械的に完全4度乗せて

```clojure
'(c4f4 d4g4 e4 a4 f4bb4))
```
にしたいとき、

## 方法1
`gen-chord3`を使う。
Opusmodusには`gen-chord`, `gen-chord2`, `gen-chord3`という史上最悪な関数の命名の関数があって、開発者を恨みつつも、今のところこれが１番短くかけそう。
**使い方**

```clojure

(gen-chord3 original (gen-repeat (length original) '(5)))
```

## 方法2
`create-chord`という関数で定義した"オレオレコード"を`expand-chord`という関数で展開できるらしいので、（今回の例だと）完全4度の音程をコードとして定義してしまうとゴリ押しできる。

```clojure


(create-chord perfect-5th '(0 5))
(flatten 
 (mapcar 
  (lambda (tone)
   (expand-chord (list tone 'perfect-5th))
  )
  original
 )
)
```

## 方法3
`chord-interval-add`という名前そのままな関数あるのでそれを使う。
第一引数で足したい音程のリスト、第二引数で元のシーケンスを取るので、元のシーケンスの長さ分の音程のリストを作って渡せば良い。

```clojure
(chord-interval-add
 (gen-repeat (length original) '(5))
 original
)
```

長さ的にはシンプルに書ける反面、2つ以上の音程を追加するとかは無理っぽいので、シンプルに単一の音程追加したい時向け。

# まとめ
どの方法でも出てくるものは同じ。
Opusmodusの計算速度わりと遅いので、スピードを鑑みて使い分けよう。
Bigquery—クエリと結果はユニークなURLで自動保存される ( 共有しなくても )

## クエリを走らせる

自動的にユニークなURLが割り振られ、Webブラウザでのアドレスも書き換わるのが分かる。

![image](https://user-images.githubusercontent.com/13635059/44381220-421a8f80-a54a-11e8-9ba4-d1a53aa5c774.png)


URLのパターン例:

`https://console.cloud.google.com/bigquery?project=mb2jp-152723&pli=1&j=bquxjob_6947b1a0_1655c4e25ad&page=queryresults`

## クエリを編集して走らせる

するとURLも変わる。

![image](https://user-images.githubusercontent.com/13635059/44381226-49419d80-a54a-11e8-978b-49a5da0f2612.png)

URLのパターン例:

`https://console.cloud.google.com/bigquery?project=mb2jp-152723&pli=1&j=bquxjob_4c90e92f_1655c4f6584&page=queryresults`

## 最初のURLにアクセスし直す

最初のクエリと結果が保存されているのが分かる。

![image](https://user-images.githubusercontent.com/13635059/44381220-421a8f80-a54a-11e8-9ba4-d1a53aa5c774.png)

`https://console.cloud.google.com/bigquery?project=mb2jp-152723&pli=1&j=bquxjob_6947b1a0_1655c4e25ad&page=queryresults`

すごいぜBigQuery。

## 制限

URLの保持期間は？

確認はしていないがQueryHistoryの保持期間と同じかもしれない。
(QueryHistoryから辿れるURLも、自動割り振りのURLと同じものなので)

— 最大6ヶ月 / export や loadなど他処理とも合わせて1000件まで

>The job and query histories in the UI include all load, export, copy, and query jobs you submitted in the past 6 months (up to 1,000 entries). The limit of 1,000 jobs is cumulative across all job types.

[Using the BigQuery Web UI  |  BigQuery  |  Google Cloud](https://cloud.google.com/bigquery/docs/bigquery-web-ui#viewing_job_and_query_history)

## 共有

他の人とクエリを共有する場合は、たぶん明示的に共有する必要がある。( `Save Query` 機能で )



## 古いWebUIでは？

同じく自動的にユニークなURLが割り振られるっぽい。今まで気づいていなかった。

## Links

- [Gist](https://gist.github.com/YumaInaura/8cafb1a3542accaaf9813786495623d4)
- [Medium—imported](https://medium.com/supersonic-generation/bigquery-save-query-and-result-with-unique-url-by-automatic-without-specific-sharing-aa63b4ee8708)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
MacにMeCabを利用できる環境を整える

## はじめに
何番煎じかわかりませんが、MacにおけるMecabの環境構築方法についてまとめておきます。
OSのバージョンはOS X High Sierraです。

## Mecabについて
MeCabはオープンソースの日本語の形態素解析器です。
形態素解析の分析において必須のソフトウェアとなっています。
なお、形態素解析の精度を大きく左右するものに、日本語の辞書があります。
利用する辞書によって形態素解析の結果が大きく変わります。
特に、Twitterのツイート本文や検索ワードなど新語が多く登場することが想定される文章ではその性能差が顕著に出ます。
この記事では、MeCabで用いられる代表的な辞書であるIPA辞書とIPA辞書を拡張して開発されたneologd辞書をインストールして利用できるようにするところまでを解説します。

## MeCabのインストール
MeCabはHomebrewからインストールできます。
一緒にMeCabで利用する中で最もメジャーな辞書の一つ、IPA辞書をインストールしましょう。
予め[HomeBrewをインストールした](https://brew.sh/index_ja.html)上で、下記のコマンドを実行しましょう

```.sh
$ brew install mecab
$ brew install mecab-ipadic
```

## MeCabをPythonから利用する
続いて、下記のコードをターミナル上で実行して、PythonからMeCabを呼び出せるようにしましょう。

```.sh
$ pip install mecab-python3
```
インストールが完了した後コマンドラインで下記を実行し、エラーが出なければpythonからMecabを呼び出す準備ができています。

```.sh
$ python -c "import MeCab"
```

## neologdのインストール
ここまで完了したら、MeCabの性能を実用レベルまで引き上げるために、neologd辞書をインストールしましょう。
インストールの前には、下記が利用できることを確認しましょう。

* MeCab
* IPA辞書
* git
* curl
* xz

ただし、標準的なMacの環境であればgitとcurlはすでに利用できるはずですし、MeCabとIPA辞書のインストールはこの記事ですでに解説済みなので、問題になるのはxzくらいかと思います。
これらは全てHomeBrewからインストールできますので、足りないものがあればインストールしてください。

```.sh
$ brew install mecab mecab-ipadic git curl xz # 必要なもののみインストールする
```

さて、neologdをインストールしていきましょう。
[neologdのGitHubリポジトリ](https://github.com/neologd/mecab-ipadic-neologd)からcloneし、MeCabコマンドから呼び出せるところに辞書を配置するところまで実行します。

```.sh
git clone --depth 1 git@github.com:neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd -n
```

形態素解析の結果にneologdを利用する場合には下記のようにMeCabに`-d /usr/local/mecab/lib/mecab/dic/mecab-ipadic-neologd`というオプションをつけて実行する必要があります。
念のため、neologdの性能の違いを確かめてみましょう。
これだけでもneologdを利用することで、新語や固有名詞を的確に抜き出すことができるのが理解できるかと思います。

```.sh
# 通常の実行結果
$ echo "インスタ映え" | mecab
インスタ    名詞,一般,*,*,*,*,*
映え  名詞,一般,*,*,*,*,映え,ハエ,ハエ
EOS
# neologdによる実行結果
$ echo "インスタ映え" | mecab -d /usr/local/mecab/lib/mecab/dic/mecab-ipadic-neologd
インスタ映え  名詞,固有名詞,一般,*,*,*,インスタ映え,インスタハエ,インスタハエ
EOS
```

## おまけ:標準で利用する辞書をneologdに変更する
最後に、標準で利用する辞書をneologdに置き換える方法を説明します。
設定には`/usr/local/mecab/etc/mecabrc`(※)というファイルを編集します。
※ここに同名のファイルがない場合、mecabをインストールしたディレクトリを探してください。`(mecabをインストールしたディレクトリ)/etc/`以下に存在するはずです。
最初に開いた際は、以下のようになっているはずです。

```.sh
;
; Configuration file of MeCab
;
; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $;
;
dicdir =  /usr/local/mecab/lib/mecab/dic/ipadic
 
; userdic = /home/foo/bar/user.dic
 
; output-format-type = wakati
; input-buffer-size = 8192
 
; node-format = %m\n
; bos-format = %S\n
; eos-format = EOS\n
```
これの6行目を以下のように書き換えましょう。

```.sh
dicdir =  /usr/local/mecab/lib/mecab/dic/mecab-ipadic-neologd
```

これで、先ほどのように形態素解析を実施し、新語が正しく抽出でできていれば設定が正常に完了しています。

```.sh
$ echo "インスタ映え" | mecab
インスタ映え  名詞,固有名詞,一般,*,*,*,インスタ映え,インスタハエ,インスタハエ
EOS
```
go-ole で Excel を操作した場合と "tealeg/xlsx" で直接 xlsx ファイルを作った場合の違い

以前、

* [CSV を「安全」に Excel に読み込む Go プログラムを書いたー（pipe2excel.exe）](https://qiita.com/zetamatta/items/d6e6b1e09bbbbba18d90)

という記事にある pipe2excel.exe というCSVのExcel 変換プログラムを作ったわけだが…

これ、巨大な CSV の時にあまりに遅いので、"[github.com/tealeg/xlsx](https://github.com/tealeg/xlsx)" というライブラリで直接 xlsx を出力できるようにしてみた（`-o`オプションを使う）

**＞ はやい ＜**

とっても速い。一瞬だ。考えてみたら go-ole だとセル１マス書くだけでも Excel と COM 通信をするわけだから、そりゃそうだ。ただ、セルのデフォルト状態がいろいろ違った。

* フォントが MS-Pゴシック でなかった
* 改行を含む場合に自動で折り返し状態にならなかった
* 縦方向がセンタリングされなかった。

これらはプログラム的に [go-ole](https://github.com/go-ole/go-ole) 版と互換動作するよう修正した。これだけ書くと、"[github.com/tealeg/xlsx](https://github.com/tealeg/xlsx)"には非のうちどころがないように思えるが、一応注意事項を記しておこう。

* "[github.com/tealeg/xlsx](https://github.com/tealeg/xlsx)" は「既存の xlsx を読む」「新規の xlsx を作成する」場合はよいが、「既存の xlsx に追記・更新する」場合、画像とか諸々消えてしまう（らしい）

この場合は [go-ole](https://github.com/go-ole/go-ole) を使うか、あるいは "[github.com/loadoff/excl](https://github.com/loadoff/excl)" を使う方がよさそうだ。"[github.com/loadoff/excl](https://github.com/loadoff/excl)" は検証していないが、作者の人自ら紹介記事（[Go言語でExcel操作ライブラリを書いてみた - Qiita](https://qiita.com/tebakane/items/2f2ed2558357c274c478)）を書いているので、そちらを参照いただきたい。

* **xls（Excel 2007 より過去の Excel で読み書きできるフォーマット）を作成できない**

まぁ、ええやろ、xls は。Excel の方に xlsx を読み書きするアドオンを入れてもらった方がよろしい

* **go-ole だと、腐っても Excel 本体を動かしているので、おかしなデータを作成してしまう可能性が小さい**

以上
obnizでAmazon Dashボタン的なのを作る

obnizの新しい「ボタンを押してサーバーレス発動」を使ってみます。
ボタンを押すだけでサーバーでプログラムを実行できるので便利だし可能性が広がりますね！

今回は「押すだけでSlackに投稿する」というのをやってみました。

![switch_event.gif](https://qiita-image-store.s3.amazonaws.com/0/258216/6a88f7e5-6045-210e-f0ce-65c2fc159c3c.gif)


## obnizの用意

- [obniz](https://www.amazon.co.jp/dp/B07DD6FK8G)

obnizを電源につないで、Wifiにつないでおきます。[参考](https://obniz.io/doc/quickstart)
QRが出たらもうクラウドに繋がってます。

あとは動かすプログラムの用意と、イベントの設定が必要ですね。
イベントが作れるようにクラウド上にアカウントを作って、obnizを紐付けるところまでやっておきます。

## 動かすプログラムの用意。

ボタンが押されたらサーバー上で動かすプログラムを書かないといけないです。
Slackの鍵がばれないようにプライベートなプログラムをobnizクラウド上に用意します。

![Screen Shot 2018-08-21 at 19.24.02.png](https://qiita-image-store.s3.amazonaws.com/0/258216/85737321-cdc0-155c-7c71-2b893de228a8.png)

ボタンが押されたときにこのHTMLがサーバー内で開かれて実行されるので、
ここにjQueryを使って、Slackに対してGETメソッドでメッセージを投稿するプログラムを書きます。


```html
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<script>
  var url = 'https://slack.com/api/chat.postMessage';
  var data = {
    token: '自分のトークン',
    channel: '#general',
    username: 'obniz-bot',
    text: 'You Pressed the switch!!'
  };

  $.ajax({
    type: 'GET',
    url: url,
    data: data,
    success: function (data) {
      if (typeof done === "function"){
        done();
      }
    }
  });
</script>
</body>
</html>
```

プログラムが書けたら試しに、サイト上で「保存＆実行」を押せばちゃんとSlackに通知が！

もちろんSlackの方でWebhook用のトークンを作って、「自分のトークン」のところに書く必要があります。

## イベントの設定

あとは、obnizのボタンを押したときにこれが動くようにイベントを作ります。
クラウドのマイページで「イベントの作成」からさっき作ったプログラムを選んで、
きっかけを「ハードウェアイベント」で、自分のobnizの番号と、イベントで「Switch Pressed」を選びます。


![Screen Shot 2018-08-21 at 19.28.56.png](https://qiita-image-store.s3.amazonaws.com/0/258216/d1fea4c6-332f-f1a2-8eb4-acc20cf58dfb.png)

これで作成したら準備完了！
ボタンを押したらSlackに来るはず！

## 動かす！

やってみましょう。
obnizにQRが出ている状態で左上のスイッチを押したら押すたびにSlackに文字が！
ただ文字が出るだけで単純ですけど楽しいですね！インターネットを感じます。

![switch_event.gif](https://qiita-image-store.s3.amazonaws.com/0/258216/6a88f7e5-6045-210e-f0ce-65c2fc159c3c.gif)

これ、サーバー上でjavascriptで動かしてますから、天気を拾ってきてobnizの画面に出したりとかもできそうですね。

AWS Lambdaを用意しなくてもobnizのサイトだけで完結できるのが楽でいいです。
IKinema Orionのデバッグをするときに便利なアニメーションを送信する機能について

#はじめに
IKinema OrionはVive Trackerを使用したモーションキャプチャーシステムになります。
このシステムを利用して開発をするとき、自分にVive Trackerをつけてデバッグを行うのが難しいときがあります。
このノートでは初めから用意されていたモーションをOrionから送信してもらい
その状態でUnity側のつながりや、各種スクリプトのテスト等を行う方法を記載します。

#環境
IKinema Orion 1.0.8
Unity 2018.1.7f1
Windows10

#設定方法
IKinemaOrionを起動する。
「Options」ボタンを押す。
「INPUT」タグを選択する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36154/eb7dad53-2e33-6773-5f84-3cc57e8c4336.png)

「Playback VIVE Take」を選択してドロップダウンから好きなアニメーションを選択する。

この状態でUnity側で再生をすればIKinemaVRPNであらかじめ用意されたアニメーションを受信することができる。
Error in GnuTLS initialization: Failed to acquire random data. ( /dev/random がない)

最近は見かけないレベルらしいですが、Debian 系の OS で `git clone` が下記のエラーにより異常終了してしまうときの話

```
Error in GnuTLS initialization: Failed to acquire random data.
*** Error in `git-remote-https': double free or corruption (top): 0x00145320 ***
qemu: uncaught target signal 6 (Aborted) - core dumped
```

原因は、 `/dev/random` とか `/dev/urandom` がないこと (他にもあるかもしれないが、自分はこれだったもよう)

解決策としては http://kazmax.zpp.jp/cmd/r/random.4.html にあるように mknod を使って自分で作る。
udev をインストールすれば作られるっていう記事があったがそうはいかなかった
Mac で Julia #3 Functions


前回に引き続きJuliaについてです。

[ドキュメント](https://docs.julialang.org/)に沿って試していきます。

## Functions

```julia
julia> function f(x,y)
       x+y
       end
f (generic function with 1 method)

julia> f(1,2)
3

julia> f(x,y) = x + y
f (generic function with 1 method)

julia> f(2,3)
5
```

- function使わなくてもf=で関数定義できるんですね。数式みたいです。

```julia
julia> g(x,y)::Int8 = x * y
g (generic function with 1 method)

julia> g(1,2)
2

julia> g(1.2,2.2)
ERROR: InexactError: Int8(Int8, 2.64)
Stacktrace:
 [1] Type at ./float.jl:679 [inlined]
 [2] convert at ./number.jl:7 [inlined]
 [3] g(::Float64, ::Float64) at ./REPL[15]:1
 [4] top-level scope at none:0

julia> typeof(g(1,2))
Int8
```

- 戻り値を指定することもできます。

### Tuples と Named Tuples

```julia
julia> a = (1,2)
(1, 2)

julia> b= (1.0,"Hello" ,x->2x)
(1.0, "Hello", getfield(Main, Symbol("##19#20"))())

julia> b[3](2)
4
```

- 関数まで定義できちゃいましたw

```julia
julia> c = (name="John",age=30)
(name = "John", age = 30)

julia> c.name
"John"

julia> c.age
30
```

- 名前付きタプルもOKです。

### Multiple Return Values

```julia
julia> multi(a,b) = (a+b,a*b)
multi (generic function with 1 method)

julia> multi(1,2)
(3, 2)

julia> a , b = multi(1,2)
(3, 2)

julia> a
3

julia> b
2
```

戻り値が複数でもOKですね。

## Varargs Functions（可変引数）

```julia
julia> bar(a,b,x...) = (a,b,x)
bar (generic function with 1 method)

julia> bar(1,2)
(1, 2, ())

julia> bar(1,2,3)
(1, 2, (3,))

julia> bar(1,2,3,4)
(1, 2, (3, 4))

julia> bar(1,2,"a")
(1, 2, ("a",))

julia> bar(1,2,"a",1)
(1, 2, ("a", 1))
```

...を使うと可変引数が使えます。


### Optional Arguments

```julia
julia> opt(x,y=2,z=3) = x * y * z
opt (generic function with 3 methods)

julia> opt(1)
6

julia> opt(1,3)
9

julia> opt(1,3,-1)
-3
```

無指定の場合の値が設定できます。

### Keyword Arguments

```julia
julia> plot(x,y;width=1,color="black") = "$x , $y , $width , $color"
plot (generic function with 1 method)

julia> plot(1,2)
"1 , 2 , 1 , black"

julia> plot(1,2,color="red")
"1 , 2 , 1 , red"

julia> plot(1,2,width=100)
"1 , 2 , 100 , black"```
```

セミコロンで区切るとキーワード付きにできます。


ドットを使うとベクトルに対しての処理ができるようですがまだ使わないのでスキップ、ちなみにこんな感じだそうです。

```julia
julia> [1,2,3] .*2
3-element Array{Int64,1}:
 2
 4
 6

julia> sin. ([1,2,3])
3-element Array{Float64,1}:
 0.8414709848078965
 0.9092974268256817
 0.1411200080598672
```

今日はこの辺で。
graphql-ruby + apollo2 + ActionCableでsubscription

Railsでgraphqlサーバーを含めて完結させるのに手こずったので。
Railsを使って、Reactアプリを表示しつつ、ApolloでGraphqlに繋いで、さらにSubscriptionをも使いたい場合に参考にしてみてください。

# サンプルrepo

https://github.com/github0013/graphql_subscription_actioncable

# 躓いた点

- ActionCableでインスタンス違い（rails s -d / rails c）からの`broadcast`は`adapter: async`ではだめ

```diff:cable.yml
development:
-  adapter: async
+  adapter: redis
+  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/0" } %>
+  channel_prefix: compass_development
```

# 細かい内容

https://github.com/github0013/graphql_subscription_actioncable/commits/master
コミットログに走らせたコマンドも記載してます。