OmniAICreator/Qiita-1.07M huggingface dataset:
バッチファイルのテンプレート

# テンプレート

ありがちなbatファイルのテンプレートを作成した。

[template.bat](https://gist.github.com/kannkyo/f98b48236c8047b32eff46cb297dadb2)

```:template.bat
@echo off
setlocal enabledelayedexpansion

:main
	pushd %~dp0
	
	rem set arguments
	set arg1=%1
	set arg2=%2

	rem check arguments
	call :check_arg1 %arg1%
	call :check_arg2 %arg2%

	rem import ini files
	set ini=test.ini test2.ini
	for %%i in (%ini%) do call :import_ini %%i

	rem body
	echo arg1=%arg1%
	echo arg2=%arg2%
	echo temp=%temp%
	echo temp2=%temp2%
	
	popd
exit /b

:check_arg1
	if "%1" == "a" (
		rem something to do
	) else if "%1" == "b" (
		rem something to do
	) else (
		echo ERROR : wrong argument arg1=%arg1%
		exit
	)
exit /b

:check_arg2
	if "%1" == "a" (
		rem something to do
	) else if "%1" == "b" (
		rem something to do
	) else (
		echo ERROR : wrong argument arg2=%arg2%
		exit
	)
exit /b

:import_ini
	for /f "tokens=1,2* delims==" %%i in (%1) do (
		if not %%i == # (
			set %%i=%%j
		)
	)
exit /b

endlocal

```

# 解説
## コマンド実行非表示の設定
デフォルトだと実行したコマンドまでDOS窓に表示されてうざい。`echo off`で非表示にできる。このとき、文頭に`@`をつけないと`echo off`自体が表示されてうざい。

```
@echo off
```

## 遅延環境変数展開の設定
デフォルトだとforループ内で変数が使えなくて悲しい。遅延環境変数展開`enabledelayedexpansion`を設定すると、変数を利用できる。この際変数は`%val%`ではなく`!val!`と記述しなければならない。めんどい。

```
setlocal enabledelayedexpansion

（中略）

endlocal
```

## カレントディレクトリ移動
`%~dp0`で自ファイルの絶対パスを取得できる。`pushd`でディレクトリを移動する。`pushd`は`cd`とは異なり、移動先のディレクトリをネットワークドライブに設定してから移動するので、`\\xxx.xxx.xxx.xxx\path`のようなディレクトリでも問題なく移動できる。

```
pushd %~dp0

（中略）

popd
```

## 引数取得
引数は順番に`%1`、`%2`と記述すれば取得できる。

```
set arg1=%1
set arg2=%2
```

## サブルーチン化
タグ名`:check_arg1`と`exit /b`を使えばサブルーチンを定義できる。また、引数も渡せる。引数は順番に`%1`、`%2`と記述すれば取得できる。裏ワザっぽいけど。
また、サブルーチンは`call :タグ 引数`と記述して呼び出す。

```
call :check_arg1 %arg1%

（中略）

:check_arg1
	if "%1" == "a" (

（中略）

exit /b
```
## iniファイル読込

謎に充実した機能を持つfor文を駆使すれば、iniファイルも読み込める。`for /f "tokens=1,2* delims==" %%i in (%1) `は、ファイル内から一行読み出し（`/f`）しつつ、各行を`=`で2分割する（`"tokens=1,2* delims=="`）ということ。

```
set ini=test.ini test2.ini
for %%i in (%ini%) do call :import_ini %%i

（中略）

:import_ini
	for /f "tokens=1,2* delims==" %%i in (%1) do (
		if not %%i == # (
			set %%i=%%j
		)
	)
exit /b
```

iniファイルはこんな感じで書ける。

```ini:test.ini
# comment
param=value

```
php-master-changes 2018-08-04

朝の方が時間とりやすいので、どっかのタイミングで朝に前日分の更新、という形へ移行したい気はしている

# 2018-08-04
## kabel: Fix bug 76595: Update phpdbg man page
- https://github.com/php/php-src/commit/91996e7ee504311ff4eca9dbd5840114f75acbad
- phpdbg の man を修正
- 全オプションをカバーしていない古い情報が載っていたりした

## petk: [ci skip] Update NEWS
- https://github.com/php/php-src/commit/b71a5038448baa79cae72fadb22a4bfb4c2465a9
- phpdbg の man 修正を NEWS へ追加

## cmb69: Fix #76704: mb_detect_order return value varies based on argument type
- https://github.com/php/php-src/commit/c00f5e6531a3f72bb8f7c107d2c390fadad736a0
- mb_detect_order のバグを修正
- エンコードをカンマ区切りの文字列で渡すか配列で渡すかで、返り値が異なるというもの
- php_mb_parse_encoding_list() と php_mb_parse_encoding_array() の利用箇所で、成功判定を SUCCESS/FAILURE で行っているのに、実装は成功時に 1、失敗時に 0 を返すものとなっていた
- [ZEND_RESULT_CODE](https://github.com/php/php-src/blob/ab8094c666048b747481df0b9da94e08cadc4160/Zend/zend_types.h#L52) の SUCCESS は 0、FAILURE は -1
- なお、このコミットのコメントで phpdbg の man 修正で NEWS の追加場所が変、という会話が petk と cmb69 の間である

## cmb69: [ci skip] Fix NEWS
- https://github.com/php/php-src/commit/81ebe930f32102136b30f23167561b08e646518b
- phpdbg の man 修正が（すでにリリース済である） NEWS の 7.3.0beta1 の位置にあるのはおかしいので、beta2 用のセクションを設けてそちらへ移動

## petk: [ci skip] Update NEWS
- https://github.com/php/php-src/commit/fd0fc20d35d77728a434195210ba01cf5692cc77
- phpdbg の man 修正が RC のタグ打たれてリリースもされた 7.1.21 の方の NEWS に入ってるのはおかしいので、 7.1.22 のセクションへ移動
- 同様に 7.2 系も 7.2.9 の方へ入っていたので、7.2.10 用のセクションへ[移動](https://github.com/php/php-src/commit/827abb843f268b49d748d074913cbf0d4b45ae32)

## weltling: Fix possible stack buffer overflow
- https://github.com/php/php-src/commit/e1af7a794a25949a7929e7e77bfc215900b4e2a0
- ext/fileinfo でスタックオーバーフローの可能性があった箇所を修正
- WIN64 だと LLP64 で int が 32bit で SOCKET は 64bit で、みたいな奴かな
cc-rs crateでCUDAをコンパイルする

Rustには[cc](https://github.com/alexcrichton/cc-rs)というcrateがあって、`build.rs`内でC/C++のコードをコンパイルしてリンクするのに便利なのですが、これがCUDAもコンパイルできるらしいので試してみた記録（を発掘したので和訳）したものです。

発掘現場：https://github.com/termoshtt/link_cuda_kernel


CUDAサンプルにある`vector_add.cu`を`kernel.cu`としてコピーしてきます。

```cuda:kernel.cu
/** CUDA Kernel Device code */
__global__ void vectorAdd(const float *A, const float *B, float *C, int numElements) {
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < numElements)
    {
        C[i] = A[i] + B[i];
    }
}

extern "C" {  // CUDAはデフォルトでC++のマングリングを採用するのでそれを抑制する

/** この関数を静的ライブラリとして提供する */
int vectorAdd_main (void) {
    /* 長いので手元のCUDAサンプルを読んでね */
}

} // extern C
```

これを`libvector_add.a` のように静的ライブラリにして`build.rs`でビルドしましょう：

```rust:build.rs
extern crate cc;

fn main() {
    cc::Build::new()
        .cuda(true)               // CUDAをコンパイルします
        .flag("-cudart=shared")   // 以下3行はnvccの引数
        .flag("-gencode")
        .flag("arch=compute_61,code=sm_61")
        .file("kernel.cu")
        .compile("libvector_add.a");  // 静的ライブラリにコンパイルします

    /* Link CUDA Runtime (libcudart.so) */

    // Add link directory
    // - This path depends on where you install CUDA (i.e. depends on your Linux distribution)
    // - This should be set by `$LIBRARY_PATH`
    println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64");
    println!("cargo:rustc-link-lib=cudart");

    /* Optional: Link CUDA Driver API (libcuda.so) */

    // println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64/stub");
    // println!("cargo:rustc-link-lib=cuda");
}
```

CUDAにはGPGPU向けに公開されているCUDA Runtime (libcudart.so)に加えてCUDA Driver API (libcuda.so)があるので必要に応じてリンクフラグを追加します。このようにしてリンクした`vectorAdd_main`は普通にCのAPIとして呼び出せます：

```rust
#[link(name = "vector_add", kind = "static")]
extern "C" {
    fn vectorAdd_main();
}

fn main() {
    unsafe {
        vectorAdd_main();
    }
}
```

既存のC++製のCUDAコードの資産を使いつつRust使いたいみたいな状況があればお使いください(/・ω・)/
Windowsでgit cloneした時にca-bundle.crtエラーが発生する

# 対象者

- git cloneでエラーが発生する。


# エラー内容

```bash
fatal: unable to access 'https://github.com/xxx-user/repository-name.git/': error setting certificate verify locations:
CAfile: C:/Program Files/Git/mingw64/libexec/ssl/certs/ca-bundle.crt
CApath: none
```

# 原因
ca-bundle.crtファイルが存在しないため。

# 対処方法
1. http://curl.haxx.se/docs/caextract.html からcacert.pemをダウンロード
2. ~/.ssh/cacert.pemとか適当な場所へ置く
3. ~/.gitconfigに追加する。<br>
```bash
[http]
    sslcainfo = C:/Users/shwld/.ssh/cacert.pem
```
4. 再度、cloneを実施する！！
localStorageを利用した際にUncaught DOMExceptionが発生した場合の対処

## 事象
local環境でのHTML,Javascriptの開発時に以下のようなエラーが発生し、localStorageが利用できない。

## 発生条件
ApacheなどのWEBサーバーは使わず、「file:///Users/〜省略〜/index.html」の様に、ローカルファイルをChromeで開いた場合

## エラーログ

```
Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
```

## 原因

「サードパーティのCookieをブロックする」をONになっていた。

## 対処法
1. Chromeの設定画面にて「Cookie」で検索
2. 「コンテンツ設定」を開く
3. 「cookie」を開き、「サードパーティのCookieをブロックする」をOFFにする。

## 参考
[Failed to read the 'localStorage' property from 'Window': Access is denied for this document · Issue #106 · apollographql/apollo-client-devtools · GitHub](https://github.com/apollographql/apollo-client-devtools/issues/106)
org.apache.http.client で 任意のHTTPステータス時にHttpRequestをリトライさせるHttpClientの作り方

`org.apache.http.client` 使用して生成したHTTPクライアントからHTTPリクエストを投げて、
返ってきたHTTPステータス(200とか404とか503とか）によってリトライしたいな〜
と言う時があって、その時の解決方法。

（同プロジェクトメンバーに、「バージョンが書いてなくてつらい」って言われたので動作バージョンを一応書きます。）

* httpclient-4.5.1
* httpcore-4.4.3 

を使用した環境で動作確認済みです！

いつか誰かの助けになる事を願って、備忘録がわりに。

```java


RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).build();

final HttpClientBuilder hcBuilder = HttpClientBuilder.create()
		.setDefaultRequestConfig(requestConfig) 
		// HTTPのIO系エラー発生時のリトライ 
		.setRetryHandler(new DefaultHttpRequestRetryHandler()) 
		// HTTPリクエスト時に retryRequestの真偽値によってリトライするか否か変わる 
		.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
			@Override
			public boolean retryRequest(
					final HttpResponse response, final int executionCount, final HttpContext context) {
				int statusCode = response.getStatusLine().getStatusCode();
				return Arrays.asList(RETRY_HTTP_STATUSES).contains(statusCode)
						&& executionCount < MAX_RETRY_COUNT;
			}

			@Override
			public long getRetryInterval() {
				return RETRY_INTERVAL_MILLI_SEC;
			}
		});
return hcBuilder.build();
	
```


言わずもがな、ですが補足をすると
・`RETRY_HTTP_STATUSES`は`Integer型の配列`で、`リトライさせたいHTTPステータスコード群`を定義してくだしあ
・`MAX_RETRY_COUNT` は `リトライする上限数`を定義してくだしあ
・`RETRY_INTERVAL_MILL_SEC` は `リトライするインターバルのミリ秒`を定義してくだしあ

これで、コピペプログラマーでもリトライ処理が書けるよね！
Freeeでレシートを撮影して登録する時、決済方法を一括で「プライベート資金」にする

Freeeでレシートを撮影して登録する時、決済方法がデフォルトで「現金」になっているので、それをプライベート資金にしたい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103885/00948fd2-0d43-13cf-9a8e-528983ce317a.png)

Chrome コンソールを開いて、下記コマンドを入れればOK

```js
Array.from(document.querySelectorAll('#walletable')).forEach(x => x.value = '事業主借')
```

ID なのに複数要素があるのが疑問ではある。

自分用の Chrome 拡張作るか
Java 文字列の操作

# 始めに
少し複雑な文字列の操作について書いてみます

# やりたいこと
例えば
```a b c triple 4649 bd d  op ```
という文字列があったとき、
```triple 4649```
に含まれる半角スペースはトリムしたくないが、他の文字のスペースはトリムしたい
つまり、
```abc triple 4649 bddop ```
というようにしたい

# 実装のイメージ
```a b c triple 4649 bd d  op ```
を

```
a b c
 triple 4649 
bd d  op 
```
のように縦持ちにして
```"a b c" と"bd d  op "```
は半角スペースをトリムするけれど、
``` triple 4649 ```
は半角スペースをトリムしない、という方針を採用してみる
そのためには、文字列の分解や置換に関するルール付けが必要になるので、以下で説明する

# ルール付け
文字列の分解や置換に関するルール付けを以下のとおりとする

``` 文字列をリスト化するための区切りを'!',`、trimしたくない文字列は@で囲うようにする ```

上記の例だと

```a b c!@ triple 4649 @!bd d  op ```
となる

# Javaの実装
StreamAPIを使って、ごくシンプルに実装してみた

```ReplaceUtil.java
package stringutil;
import java.util.stream.Stream;

public class ReplaceUtil {
	
	public static String replacewhiteSpace(String target,String separator,String marker) {
		return Stream.of(target.split(separator))
		.map(s->replacer(s,marker))
		.reduce((s1,s2)->s1+s2 )
		.orElse("");
	}
	
	private static  String replacer(String target,String marker) {
		if(target.matches(String.format("%s[\\w| ].*%s", marker,marker))) {
			return target.replaceAll(String.format("%s([\\w| ].*)%s", marker,marker), "$1");
		}else {
			return target.replaceAll(" ", "");
		}
	}

}
```
gdbについてまとめてみました

業務でgdbを使う機会が最近あったので書いてみます。

##コマンドは略称で覚える
コマンドは、breakpointだったりcontinueと打つと効率が悪いので略称で覚えたほうが効率が良いです。
breakpointはbで打てますし、continueはcで打てます。

##TUIモードがなんだかんだ最強
gdbはデフォルトだと見づらいので、TUIモードで使うと見やすいです。
wh　というコマンドを打つと呼び出せます。ただこのモードは頻繁に画面が崩れるのでCntr + Lで画面を再描画しないといけません。pythonであれば、[GDB Dashboard](https://github.com/cyrus-and/gdb-dashboard)を入れると最高だと思います。

##gdbinitで設定を弄るべき
gdbには、起動時に読み込むgdbinitファイルがあるのでコマンドをdefineでまとめたり設定をここに書きましょう。githubに[僕のdotfile](https://github.com/koutakun/dotfile)をあげているので見てください。
多重継承したスーパークラスから同一名のメソッドを選択取得して動的メソッドオーバーライド、注意点

継承について書かれた記事にコメントしたのですが、記事を削除されてしまったようなので、新たな記事として投稿します。
車クラスを継承してスポーツカー、エコカー、自動運転車などのクラスを作った後、運転モードを指定することで選ばれたスーパークラスのメソッドを取得して自分のメソッドとして動的メソッドオーバーライドする多重継承クラスを定義しました。
しかし、実行結果が妙なのです。

```py
class Car(object):

    def __init__(self, name):
        self.name = name

    def display(self, text):
        print(self.name + ': ' + text);

    def run(self):
        self.display('run')


class SportsCar(Car):

    def run(self):
        self.display('run fast')


class EcoCar(Car):

    def run(self):
        self.display('run ecofriendly')


class AutomaticDrivingCar(Car):

    def run(self):
        self.display('run automatic')


class AutomaticDrivingSportyEcoCar(AutomaticDrivingCar, SportsCar, EcoCar):

    def set_mode_automatic(self):
        self.run = super().run

    def set_mode_sports(self):
        self.run = super(SportsCar, self).run

    def set_mode_eco(self):
        self.run = super(EcoCar, self).run

    def set_mode_normal(self):
        self.run = super(AutomaticDrivingCar, self).run


car1 = Car("Cedan")
car1.run()

car2 = SportsCar("GT-R")
car2.run()

car3 = AutomaticDrivingSportyEcoCar("Google")
car3.run()
car3.set_mode_sports()
car3.run()
car3.set_mode_eco()
car3.run()
car3.set_mode_normal()
car3.run()
car3.set_mode_automatic()
car3.run()
```

```text:実行結果
Cedan: run
GT-R: run fast
Google: run automatic
Google: run ecofriendly
Google: run
Google: run fast
Google: run automatic
```

処理の最後に Google の自動運転スポーティエコカーの運転モードを
自動運転⇒スポーツモード⇒エコモード⇒通常モード⇒自動運転モード
の順に切り替えたつもりだったのですが、実行結果をみると、
自動運転⇒エコモード⇒通常モード⇒スポーツモード⇒自動運転モード
の順で表示されてしまいました。

[インターネットで探してみた](https://stackoverflow.com/questions/26927571/multiple-inheritance-in-python3-with-different-signatures)ところ、superの引数にクラス名を指定した場合、スキップするクラスを指定したことになり、多重継承順序で次のクラスが取得されるようです。
なので、狙ったクラスの一つ前のクラスを指定するといいようです。

```py
class AutomaticDrivingSportyEcoCar(AutomaticDrivingCar, SportsCar, EcoCar):

    def set_mode_automatic(self):
        self.run = super().run

    def set_mode_sports(self):
        self.run = super(AutomaticDrivingCar, self).run

    def set_mode_eco(self):
        self.run = super(SportsCar, self).run

    def set_mode_normal(self):
        self.run = super(EcoCar, self).run


car3 = AutomaticDrivingSportyEcoCar("Google")
car3.run()
car3.set_mode_sports()
car3.run()
car3.set_mode_eco()
car3.run()
car3.set_mode_normal()
car3.run()
car3.set_mode_automatic()
car3.run()
```

```text:実行順序
Google: run automatic
Google: run fast
Google: run ecofriendly
Google: run
Google: run automatic
```

参考:
https://docs.python.jp/3/library/functions.html#super
> super([type[, object-or-type]])
> 探索の順序は、 type 自身が飛ばされるのをのぞいて getattr() で使われるのと同じです。

原文 https://docs.python.org/3.6/library/functions.html#super

> The search order is same as that used by getattr() except that the type itself is skipped.
IntelliJ IDEA で formatter:off が効かない時の対処法


ある時、フォーマットかけたくない箇所に、
`@formatter:off`
と記載していたのですが、指定箇所のフォーマット機能が無効になっていなかったことがありました。

下記の方法で解決したので、備忘録がわりに記載。

**Eclipse Code Formatter 未使用の場合は、原因は別**になるので、
他の解決方法をご参考ください。

---


`@formatter:off` が `Eclipse Code Formatter` の影響で 効かない場合は、
`{それぞれのリポジトリパス}/.settings/org.eclipse.jdt.core.prefs` に下記を追記すると
`@formatter:off`が有効になります。

```
　org.eclipse.jdt.core.formatter.disabling_tag=@formatter:off
　org.eclipse.jdt.core.formatter.enabling_tag=@formatter:on
　org.eclipse.jdt.core.formatter.use_on_off_tags=true
```

EclipseCodeFormatter か どっかのGithubで Issue化されていたので、そのうち直るといいですね。
pythonでエクセルを書いてみるよ(xlsxwriter)

人に見せるときはExcelになること多いので、pythonのxlsxwriterを使ってできるところは自動化していこうという試み。

[xlswriter](https://xlsxwriter.readthedocs.io/index.html)


###  importとかの初期宣言

```
import xlsxwriter

book = xlsxwriter.Workbook('test.xlsx')
```
Workbookで作成するファイルを指定する。基本的のこのbookをつかった変更がtest.xlsxに書き込まれていきます。


### ワークシートの追加
```
sheet = book.add_worksheet('NAME_OF_SHEET')
```
add_worksheetでシートの追加。引数に名前を入れてなまえを指定。名前がない場合はsheet1,sheet2,sheet3,..とデフォルトが入って行く。

### セルへの記述
```
line=0
row=0

sheet.write(line, row, 'test')
```
sheet.writeメソッドをつかってセルに書き込むことができる。 行、列番号を指定して、そのセルに指定した文字列を入れる。 上の場合、0行0列に文字列'test'を書き込む。


### セルのフォーマットの変更
```
format=book.add_format({'bold': True, 'font_color': 'black', 'font_size':'14', 'bg_color':'#FFB900'})

sheet.write(0, 0, 'test', format)
```

bookのadd_formatを使うと、セルの書式設定ができる。
add_formatから返却されたオブジェクトを、writeの第４引数にして渡すとその書式で記入してくれる。
上の例はフォントカラーがブラック、サイズが14px、セルの背景がオレンジ、文字のBoldをする。

### セルの幅を指定する
```
sheet.set_column(0,0, 20)
```

セルの幅を指定します。行、列の指定ではなくて、列の長さの指定になる。0,0であればA, 1,3であればB~Dの位置の幅が指定できる。

### サンプル
```
import xlsxwriter

#test.xlsxを作成
book = xlsxwriter.Workbook('test.xlsx')
#段落用のフォーマット
titleformat=book.add_format({'bold': True, 'font_color': 'black', 'font_size':'14', 'bg_color':'#FFB900'})
#通常の文字用フォーマット
textformat=book.add_format({'bold': False, 'font_size':'14'})

#ワークシートテスト用を作成
sheet = book.add_worksheet('テスト用')

sheet.write(1, 0, 'xlxswriteのテスト', titleformat)
sheet.set_column(1, 0, 50)
sheet.write(2, 0, 'こんにちはこんにちは', textformat)

sheet.write(4, 0, 'サーバ一覧とか', titleformat)
sheet.set_column(3, 0, 50)
sheet.write(5, 0, '192.168.0.1', textformat)
sheet.write(6, 0, '192.168.0.2', textformat)
sheet.write(7, 0, '192.168.0.3', textformat)
sheet.write(8, 0, '192.168.0.4', textformat)

sheet.write(10, 0, 'URLとか', titleformat)
#urlの入力
sheet.write_url(11, 0, 'https://www.yahoo.co.jp', string='Yahoo')
sheet.write_url(12, 0, 'https://google.co.jp')
sheet.write_url(13,0, 'https://xlsxwriter.readthedocs.io/index.html')

book.close()
```

<a data-flickr-embed="true"  href="https://www.flickr.com/photos/kyagyao/42866581144/in/album-72157676327477732/" title="xlsxwriter screenshot"><img src="https://farm1.staticflickr.com/931/42866581144_eae694332a_n.jpg" width="320" height="207" alt="xlsxwriter screenshot"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>

こんな感じになります。  
公式のexampleに結構な量が書いてあるので、そのまま使えそう。  
[Examples — XlsxWriter Documentation](https://xlsxwriter.readthedocs.io/examples.html)

基本操作はだいたいこんな感じで、グラフ、テキストボックスも使えるみたいなので、使うときになったら書いていこう  
データをtsv、csvにしてエクセルで読み込んでコピーとかがダルかったので積極的に使っていきたい。
第27話 エキゾチック球面

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第27話です。

```math
\#\{exotic\:7\:sphere\}=27
```
7次元球面のエキゾチック球面は27個ある、という意味です。
エキゾチック球面とは異界球面とも呼ばれ、通常の球面とは違う形をしている球面です。
通常の球面とは違う形が27個ですから、通常の球面も合わせて
8次元球の表面の形は28種類ある、と捉えてもいいでしょう。

我々が目にする球面は1種類しかありません。
大きさが違うだけで、球の形が違うということはないでしょう。
球は立体の基本的な形ですし、4次元や5次元でも特に変な挙動がなかったので、
何次元になっても同じ形と考えられていました。

球面、というのは球の表面です。
例えば、地球の表面は2次元球面です。
地表には果てはありませんが、地表の面積は無限でありません。

また、宇宙は3次元球面ではないかと言われています。
地表と同じく果てがなく、ループしていると考えられています。
すなわち地球や太陽系と言ったものが4次元球の表面にあると思われます。

4次元以上の空間は目に見えないので想像するしかありません。
そのため、いろんな計算をすることで高次元の特徴を捉えていきました。

その結果、7次元球面は同相だが微分同相でない28種類の微分構造を持つ、ということがわかりました。
要は球と呼んでいい形をしているのに、なんか違う形をしている、と捉えて下さい。

この球面の微分構造の数は、次の表のようになります。
11次元球面や15次元球面は種類が膨大に増えるのに、
12次元球面は再び1種類に戻るなど、不思議な形をしています。

| 次元数 | 微分構造 |
|:-:|:-:|
| 1  | 1  |
| 2  | 1  |
| 3  | 1  |
| 4  | 1(予想)  |
| 5  | 1  |
| 6  | 1  |
| 7  | 28  |
| 8  | 2  |
| 9  | 8  |
| 10  | 6  |
| 11  | 992  |
| 12  | 1  |
| 13  | 3  |
| 14  | 2  |
| 15  | 16256  |
| 16  | 2  |
| 17  | 16  |

4次元球面だけは資料によっては不明となっていたため、予想をつけています。

4次元空間は低次元問題と呼ばれる、厄介な特徴があり、
それより上の5次元以上では解決されているのに、
4次元だけ未解決という事がよくあります。

実際、4次元は微分構造が無限に存在するという特徴もありますし、
難問と言われたポアンカレ予想は、3次元球面(4次元球)だけが対象であり、
2次元球面は自明(我々の生きている世界ですから…)、4次元球面以上はすでに解明されていました。

ドラえもんでは四次元ポケットに入る描写がありますが、
本当に四次元に入ったらどんな世界になっているんでしょうね。
初心者向け ffmegを使って動画をタイムラプス風に変換する。（Macの場合）

# はじめに
タイムラプス加工を含めた動画変換には「ffmpeg」というソフトウェアを使います。

ffmpegは、Chromeやitunesのようにデスクトップでアイコンをクリックして起動するタイプのソフトウェアではなく、macOS標準でインストールされている「ターミナル」というソフトウェア上でコマンドを入力することで起動するタイプのソフトウェアです。

ffmpegのインストールはターミナルから行います。
インストールのためには事前にApp Storeから入手できる開発用ソフトウェア「xcode」と、ソフトウェア管理ツールである「homebrew」のインストールが必要です。
また、ffmpegで映像の処理を行う上で「imagemagick」というソフトウェアのインストールも必要です。

# 環境構築
## xcodeをインストール
App Storeからインストール
## homebrewのインストール
https://brew.sh/
ターミナルにて下記コマンドを実行。

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
## ffmpegのインストール
ffmpegは動画変換をするためのソフトウェア。
homebrewを使ってffmpegをインストールする。
ターミナルで下記コマンドを実行。

```
brew install ffmpeg
```
## imagemagickのインストール
imagemagickは画像処理用のソフトウェア。黒子的な役割。
homebrewを使ってimagemagickをインストールする。
ターミナルで下記コマンドを実行。

```
brew install imagemagick
```
# 普通の動画をタイムラプス風動画に変換する
```
ffmpeg -i [入力元ファイル名] -filter:v "setpts=PTS/[倍速]" -r [秒間フレーム数] -an [出力先ファイル名]
```
"-an:"はオーディオの削除する際につけるオプション。

オーディオを削除した上でフレームレートを15/sに、240倍速にする場合、ターミナルで下記コマンドを実行。

```
ffmpeg -i input.mp4 -filter:v "setpts=PTS/240" -r 15 -an out3.mp4
```
できあがり。
HttpClient でリクエストヘッダを設定する (C#)

# HttpClient でリクエストヘッダを設定する (C#)

備忘録として.
また、ググったら`HttpClient.DefaultRequestHeaders.Add`だらけでイラッとしたので.

ざっくり言えば`HttpRequestMessage`を作り`HttpRequestMessage.Headers.Add`して、`HttpClient.SendAsync`に渡す.

以下コード例.

```csharp
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Content-Type", "application/json");
request.Headers.Add("Authorization", $"Bearer {accessToken}");
var response = await client.SendAsync(request);
```
Unresolve reference :kotlinx

# 問題
android 開発中に layout.xmlからIDでviewを参照していたがなぜか知らないがエラーが発生していた。
(sync now をすると治るときもある）
# 環境
|  | バージョン |
|:-:|:-:|
|Android Studio   | 3.1.3  |
|Gradle   |  3.1.3 |
|kotlin   |  1.2.30 |
#解決法
Gradle Scripts build.gradle(Module:アプリ名)の　
buildscript-> ext.kotlin_version ="1.2.60"にする
つまり
kotlinのバージョンを上げる
![2018-08-04 22_48_52-MyApplication [C__Users_ookubo_AndroidStudioProjects_MyApplication] - MyApplicat.png](https://qiita-image-store.s3.amazonaws.com/0/150338/75ec3c2a-dfd1-fadd-38d2-34bdaf0ff72d.png)

#経緯
ここからはどうでもいいです
viewをIDから参照していると時々unresolve referenceになり、sync now をすると時々解決、時々解決しないのでgithubのissueを見たところ、
[https://github.com/gradle/kotlin-dsl/issues/377](https://github.com/gradle/kotlin-dsl/issues/377)

(![image.png](https://qiita-image-store.s3.amazonaws.com/0/150338/56c117f6-ad96-4a39-7411-09bf8ffad0d2.png)

でkotlinのバージョンを上げることで治ることが報告されていましたが1.2.50では治らず
[https://youtrack.jetbrains.com/issue/KT-23908](https://youtrack.jetbrains.com/issue/KT-23908)
で1.2.60にバージョンを上げると治りました。

以上です
ElasticCloudがなんさま安くなっていた！！

先月、可視化で遊んでランニングコストがかさむから一旦落としていたElasticCloudを再度立ち上げ。。。

ん？

![スクリーンショット 2018-08-04 8.39.29.png](https://qiita-image-store.s3.amazonaws.com/0/123239/b3aadac1-2bab-fe3f-014c-a34e30750e92.png)


Create deployment画面の様子が。。。
設定がえらい簡素化されてるし、右側にあったコスト表示もない！！
うぇ？サーバーサイズとかAZとかわからんぞ。。。どうしよう。

![スクリーンショット 2018-08-04 8.39.52.png](https://qiita-image-store.s3.amazonaws.com/0/123239/3f0be84f-7141-a516-5be0-f4cfd25dd7bf.png)

あ、ページ最下部にCustomize deploymentはけーん！
たぶんここだ！！

![スクリーンショット 2018-08-04 8.40.11.png](https://qiita-image-store.s3.amazonaws.com/0/123239/b10e1c6a-35ce-983d-ebcd-14a962a669a1.png)

ビンゴ！！
これこれ、とりあえず遊びで使うので最小構成にして。。。ぽちぽち。。。
AZを1つに減らしたらちょっと警告出るけど気にしなーい。

あれ？
(　ﾟдﾟ)。。。 
　 
(つд⊂)ｺﾞｼｺﾞｼ 
　 
(；ﾟдﾟ)。。。 
　 
(つд⊂)ｺﾞｼｺﾞｼｺﾞｼ 

(；ﾟДﾟ)。。。！？ 

![スクリーンショット 2018-08-04 8.40.30.png](https://qiita-image-store.s3.amazonaws.com/0/123239/8bf9795a-daf9-2fd8-cbca-02a124e32d31.png)

Monthly rate が$16.43 ！！！！
先月まで$45じゃなかったっけ？

あれ？

![スクリーンショット 2018-08-03 9.47.00.png](https://qiita-image-store.s3.amazonaws.com/0/123239/2b1c280f-c535-c0dc-9af9-8b54dd4c2f2e.png)


ぎゃぁ！！知らんうちに値下げされとった！！
なにしれっとやっとんですか！いや嬉しいけども！！！！

こりゃよかばい！

この金額なら1ヶ月立ち上げっぱなしでもいいなー。

。。。？\_(:3｣∠)_

\_(┐「ε:)_？。。。

MLが使えるようになってる！！
∑ヾ(;ﾟ□ﾟ)ﾉｷﾞｬｱｱｰｰ!!

![スクリーンショット 2018-08-04 8.41.18.png](https://qiita-image-store.s3.amazonaws.com/0/123239/248a2ffe-d8e7-92f2-0dd4-a1e8ee42677c.png)

しかも、追加料金なしっぽい！！！

どれどれ？

![スクリーンショット 2018-08-04 8.41.29.png](https://qiita-image-store.s3.amazonaws.com/0/123239/43c0594f-5cf2-af61-587a-98ce4e5d49be.png)

おお！Monthly rate変化なし！

取り急ぎ、ElasticCloudがなんさま安くなってMLまで使えるようになったよ！
っていう雑記でした！！

実際にML使う生地は後日！！
((ヾ(*´･ω･)ﾉﾞ))
ChromeOS (not developer mode) からSecure Shell Appを使ってGoogle Cloud Platform (GCP) にssh

# はじめに
Chromebookから、ラズパイとかGCPにsshする環境を試行錯誤した結果、最終的にSecure Shell Appを「ウィンドウとして開く」で開いて使うのが、一番快適なことがわかった。ショートカットとかクリップボード使うのに都合が良い。

[Secure Shell App - Chrome ウェブストア](https://chrome.google.com/webstore/detail/secure-shell-app/pnhechapfaindjhompbnflcldabbghjo)

「ウィンドウとして開く」のがみそ。右クリックして選択しておく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/e4749d82-e608-87e2-512d-9c70cdadc4a5.png)

`C-v`, `C-p`, `C-n`, `C-space`とかのショートカットをLinuxライク、Emacsライクに使える。ストレスレス。

ちなみに、Crosh Windowからsshする方法はなぜかうまくいかなかった。
Termux入れて使う方法はクリップボードが微妙やった。

# GCPの設定
下記サイトを参考に設定。
[Chromebook Secure Shell 公開鍵認証でCentOSにSSH接続する - designetwork](http://designetwork.hatenablog.com/entry/2017/02/02/public-ssh-on-chromebook)

ホストの秘密鍵もクライアントにコピーして使うっていう聞いたことない危険そうなやりかたやけど、Chromebookのdeveloper modeにならなくてもsshできるようになる。以下、自己責任で。


まず、ブラウザからGCPのVMインスタンスにsshする。
次に、GCPのVMインスタンス上でssh-keygenして、できた`id_rsa.pub`を`authorized_keys`に追加する。自分の公開鍵を追加するってなんなんやろって思うけど。

```
ssh-keygen
cd .ssh
cat id_rsa.pub >> authorized_keys 
```

パスフレーズは入力したほうがいいと思うけど、入力せずにEnter, Enterすると、パスフレーズ入力せずにsshできるようになる。
次に、`id_rsa.pub`と`id_rsa`をクライアント側にダウンロードする。
GCPのsshのコンソールの右上の設定ボタンからダウンロードできるので、それを使う。

![Screenshot 2018-07-31 at 10.34.16.png](https://qiita-image-store.s3.amazonaws.com/0/184221/b7992f43-16a2-eb9a-7a98-e6245baa400a.png)

パスの指定は絶対パスじゃないとだめやった。
`~`も使えなかった。
こんな感じでダウンロード
![Screenshot 2018-07-31 at 10.37.08.png](https://qiita-image-store.s3.amazonaws.com/0/184221/c920f65d-98ae-5bc4-5bd8-e048de729a6b.png)

# ChromeOSでの設定

さっきのファイルをローカルの`ダウンロード`フォルダに`ssh`ってフォルダ作って入れといた。

最後にSecure Shell Appを立ち上げる。user名、外部IPに加えて、`ID:`ってとこの`インポート…`ってところを押して、`id_rsa`と`id_rsa.pub`の両方を選んで設定する。
これで、sshできるようになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/629af9a7-46ed-a24e-28e4-cf162fecc1bd.png)

# おわりに
秘密鍵をクライアントに持ってくるのが気持ち悪いけど、快適な環境でGCP使えるようになった。
ラズパイもGCPも同じアプリから接続できるからいい感じ。
ReactNativeでTypescriptを使い始める

# typescriptのインストール

[Using TypeScript with React Native · React Native](https://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native)

## インストールと設定

```shell
# typescriptをインストール
yarn add --dev typescript
# typescriptのコードをReactNative用に変換するライブラリをインストール
yarn add --dev react-native-typescript-transformer
# 設定ファイル（tsconfig.json）を作成
yarn tsc --init --pretty --jsx react
# react-native-cliの設定ファイルを作成
touch rn-cli.config.js
# ReactとReactNativeの型定義をインストール
yarn add --dev @types/react @types/react-native
```

`tsconfig.json` のこの行のコメントを外す。

```js
"allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
```

`rn-cli.config.js` を開いて、↓これを書く

```js
module.exports = {
  getTransformModulePath() {
    return require.resolve('react-native-typescript-transformer');
  },
  getSourceExts() {
    return ['ts', 'tsx'];
  },
};
```

## 既存のソースコードを修正

### jsファイルの拡張子を変更する

エントリポイントになる `index.js` 以外はjsxの場合 `tsx` 、jsx以外は `ts`に変更する。

### `default export` と `named export` を同じ行でimportしてるところを別の行に変更する

```js
-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';
```

# Typescriptを始める

[TypeScript in 5 minutes · TypeScript](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html)

## 関数の引数に型指定できる

```js

// string型の値しか受け付けない
function greeting(person: string) {

}
```

- 使える型（基本） [Basic Types · TypeScript](https://www.typescriptlang.org/docs/handbook/basic-types.html)

## interfaceでオブジェクトのメンバーと型が定義できる

```js

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}
```

## Constructorの引数に `public` キーワードを使うことで、メンバー定義も一緒にできる

```js

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

const student = new Student('Yujiro', 'A', 'Arai');
console.log(student.firstName) //=> yujiro
```
ディレクトリ内のファイル名をまとめて変更（連番付与）する

## やりたいこと
ツール等で一括ダウンロードしたファイルをまとめて操作するために、WORD+連番の形式に一括で変換する。

## 元ファイル名
```
ls
>0-9876589.png 0987654678.png 234567.png 32456789654.png
```

## 変更後ファイル名
```
ls
>test001.png  test002.png test003.png test004.png
```

## やり方
```
ls | awk '{ printf "mv %s test%03d.png\n", $0, NR }'
```
上記コマンドで変更後のファイル名を一旦確認

```
mv 0-9876589.png test001.png
mv 0987654678.png test002.png
mv 234567.png test003.png
mv 32456789654.png test004.png
```

問題がなければ上記のコマンドの結果をパイプでshに流してコマンド（mv）実行

```
ls | awk '{ printf "mv %s test%03d.png\n", $0, NR }' | sh
```

### ※コマンド補足
```awk``` コマンドでテキスト加工をしてファイル名変更用のコマンドを生成する。
```mv %s test%03d.png¥n``` %sは文字列、%03dは３桁0埋めの数値文字列
```$0```でlsの表示結果（元のファイル名）
```NR```はawkの組込変数で現在処理しているレコード番号
Go言語でkubernetes APIをkubernetes clusterの外から呼び出す

# はじめに
kubernetes(以下k8s)のREST APIを呼び出す際にgo/python etc.のさまざまなクライアントライブラリが存在します。

この際、多くの実行例がk8sクラスタ内部またはk8sコンテナ上からAPIを呼び出す方法を解説しており、実際の作成物は最終的にはそうなるんでしょうが、開発途中の段階ではクラスタの外部からk8s APIを呼び出しながらコードを書きたいということでやり方を調べました。
接続先だけを設定した空っぽのconfigを作って、そこに必要な設定を上書きしていく感じですかね

# コード
BuildConfigFromFlagsに渡している IP は `https://10.0.1.44:32382` みたいな感じでk8sのAPIサーバのアドレスとポート
`BearerToken` に指定しているTOKENは secret で出てくる token（eyJhbGciOiJSUzI1NiIsImtpZCIとかなってる長い奴）

importはやや適当

```go:main.go
import(
	"fmt"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)
func main() {
	config, err := clientcmd.BuildConfigFromFlags("https://API_SERVER_ADDRESS:API_PORT", "")
	if err != nil {
		log.Fatal(err)
	}
	config.Insecure = true
	config.BearerToken = "YOUR TOKEN HERE"
	client, err := kubernetes.NewForConfig(config)

	if err != nil {
		log.Fatal(err)
	}

	pods, err := client.CoreV1().Pods("").List(meta_v1.ListOptions{})
	if err != nil {
		log.Fatal(err)
	}

	for _, pod := range pods.Items {
		fmt.Println(pod.Name)
	}

}
```

# 参考資料
https://qiita.com/dtan4/items/f2f30207e0acec454c3d
http://ks888.hatenablog.com/entry/2017/12/25/001259
Node.jsでつくるNode.jsミニコンパイラ - もくじ

# はじめに

「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」([ラムダノート](https://www.lambdanote.com/products/ruby-ruby), [Amazon](https://www.amazon.co.jp/dp/4908686017)) という本に感銘を受けて、自分でも[Node.jsでミニインタープリターを作りました](https://qiita.com/massie_g/items/3ee11c105b4458686bc1)。

そして [Turing Complete FM](https://turingcomplete.fm) というポッドキャストを聴くうちにコンパイラも作って見たくなり、LLVMを使ってチャンレンジしてみました。

## 前提環境

今回は私の環境である Mac OS X 10.12 Sierra を前提にしています。


# ミニコンパイラ編 目次

* [ミニコンパイラ - 01 : 仕様の検討と、LLVMの準備](https://qiita.com/massie_g/items/1bdede3016a53f366fec) ... LLVMをつかったコンパイラに着手
* [ミニコンパイラ - 02 : LLVM IRの下調べ](https://qiita.com/massie_g/items/7e2d2d742f1da49b8daf) ... LLVMの中間表現について調べます
* [ミニコンパイラ - 03 : 足し算(+演算子)を実現する](https://qiita.com/massie_g/items/8d5f7afa012b7ae76ab8) ... 整数と足し算をコンパイル
* [ミニコンパイラ - 04 : 四則演算と余りをサポートする](https://qiita.com/massie_g/items/07b2bec3d7266faf9785) ... 残りの演算子(-, *, / %)をサポート
* [ミニコンパイラ - 05 : ローカル変数を使う](https://qiita.com/massie_g/items/ef10b1a3b214516d6663) ... ローカル変数、複数行をサポート
* [ミニコンパイラ - 06 : 比較を行う](https://qiita.com/massie_g/items/fd309c8cada1b0d5a416) ... 比較演算子を実装する
* [ミニコンパイラ - 07 : 条件分岐を行う](https://qiita.com/massie_g/items/3f175c205470993eb548) ... if 〜 else をサポートする
* [ミニコンパイラ - 08 : Whileループを実装する](https://qiita.com/massie_g/items/80e9aedc613900c2de7d) ... while ループをサポートする
* [ミニコンパイラ - 09 : 文字列出力とFizzBuzz](https://qiita.com/massie_g/items/b84c7ede1a2b91f33bdd) ... ループを使ってFizzBuzzを実現
* [ミニコンパイラ - 10 : ユーザー定義関数](https://qiita.com/massie_g/items/7791d946de380b8b7f1e) ... ユーザー定義関数をサポートする
* [ミニコンパイラ - 11 : FizzBuzzとフィボナッチ数列](https://qiita.com/massie_g/items/3b73a8d7ab3324aba36e) ... ユーザー定義関数を使ってFizzBuzzとフィボナッチ数列を実現（再帰呼び出し）
* [ミニコンパイラ - 12 : いまさらテストを追加](https://qiita.com/massie_g/items/8ae4b61c63716a05b1ed) ... シェルスクリプトによる実行結果を確認するテストを用意

## 番外編

* [Extra01 : WebAssembly 化](https://qiita.com/massie_g/items/b5c449d4de8321a6bc68) ... emscripten を使って、LLVM IRからWebAssembly(.wasm)に変換
* （いつかやりたい）Node.jsとの互換性を高めるため、console.log()を使えるようにする
* （いつかやりたい）ミニRubyの中間表現から、LLVM IRを使ってバイナリを生成
* （いつかやりたい）LLVM IR を経由せずに、WebAssemblyのテキスト表現に直接変換

## ミニインタープリター編

* [ミニインタープリター編のもくじ](https://qiita.com/massie_g/items/3ee11c105b4458686bc1)

# 謝辞

「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」([ラムダノート](https://www.lambdanote.com/products/ruby-ruby), [Amazon](https://www.amazon.co.jp/dp/4908686017)) に感銘をうけて自分でもミニNode.jsを作って見ましたが、本を読んでいた時には気がつかなかったことが多々ありました。書籍の構成、ミニRubyの設計がとても優れていて、とても参考になりました。
素晴らしい書籍を作ってくださった作者の遠藤さんとラムダノートさんに改めて感謝します。ありがとうございました。


# ソースコード

今回作ったコードは GitHub で公開しています。

* [mganeko/mininode_compiler](https://github.com/mganeko/mininode_compiler)

# いつかやりたいこと

* （実施済み）LLVM IRから、WebAssemblyを生成する
先輩が忙しそうにしていても質問した方がいい理由

# はじめに

業務において、質問しようと思っても「あ、なんか忙しそう・・・:anguished:」って思って、質問するのやめちゃうときってないですか？
私、そのタイプです。
なので、何度も「もっと質問しなさい:exclamation:」って言われてきました。
「15分考えて、わかんなかったら聞きにきなさい」とも。
だけど、やっぱり「忙しそうだな～」って思って（以下無限ループ）。

しかし最近になって、質問される側の立場が増えてきました。
質問される側になって、ようやく「もっと質問しなさい」と先輩が言ってきたことがちょっとわかるようになってきたので、実体験に基づいて、先輩側・後輩側それぞれの視点で「質問した方がいい理由」をあげてみます:pig:

# 先輩側の理由
## 1. 進捗がわかって安心するから。

質問でも、確認でも。
話しかけてくれると、仕事の進み具合が伝わってきます。

本当は、適当に声をかけてあげたいなぁって先輩も思ってるんです。
だけど、忙しくてなかなか声をかけてあげられないときもあるんです。

そういうときに質問しに来てくれると、質問の内容から進捗具合を察することが出来ます。

- ここで悩んでるってことは、まだだいぶ最初じゃないか！
- 昨日とほぼ同じ内容だけど、進捗上がってないのかな？
- ずいぶん早いなぁ。順調そうなのかな？

とかとか。
そうすると、後輩から何も言わなくても、先輩の方で察してあげられます:smiley:
スケジュールや次のタスクの難易度を調整することも出来ます。

先輩は事前に察知出来て、後輩はプレッシャーから解放されるなら・・・。
両者win-winですよね:heart:

## 2.「信頼されてるなぁ」と感じてうれしくなるから。

個人的な感覚なんですが :droplet:
「この先輩に聞いてもわかるかなぁ？」って思う時は、ちょっと質問しにくいです。
けど、「ごめん！すぐにはわからないから調べるね！」であっても、さっと答えを返してくれる先輩には「何でも教えてくれる」という信頼感があると思います。

なので、質問される側としても、「後輩に信頼されてるんだなぁ」と満足感に浸れます:blush:
信頼されてると思うと、こまめに面倒を見てあげたくなります、私は！

# 後輩側の理由
## 1. 調べるより聞いたほうが早いから。調べるにしてもヒントがもらえるから。

先輩って、自分より経験が長いからこそ、持ってる知識や経験値が全然違う。
だから、ググるより先輩に教えてもらった方が早く答えが見つかる。
ググるにしても、ヒントを教えてくれる。
１回教えてもらったら、２回目以降は自力で頑張れる気がしませんか？
それはそれで１つの成長の仕方だと思います。

自分で悩んで考えて調べて・・・ってのも、大事なスキルの１つだと思いますが、でも質問の仕方もスキルの１つ！
不安なら、最初はシナリオ作って台本書いてもいいので、サクサク教えてもらいましょう :hibiscus:

## 2. 質問した後、解決するまで数日間サポートしてくれるから。

先輩は、たいてい後輩の質問内容を数日間気にかけてくれます。
「昨日質問してきたアレ、解決した？」みたいに。
そしてそれは、商用の不具合調査など、ほかの人が絡んでくるときに、すごく心強いものになります。

自分が先輩に説明しようとしてもなかなか難しいのに、（例えば）お客さんが納得できるような説明ができるわけがない（笑

そういうとき、一人で抱え込まずに先輩に相談しておくと、うまく説明ができずにオロオロしてる時に、後ろからそっと近づいてきてくれて、助け舟を出してくれます。
実際、私も助けてもらったことがたくさんあります:hatching_chick:

# まとめ

ありきたりですが、立場が変わると感じ方が全然違いますね:sweat_smile:
一番変わったのは、「質問されるとちょっとうれしい」と思ったことでした。
質問されるってのは、ちょっとでも信頼してもらっているという証なのかなぁと:arrow_left:ちょっと思い込みアリ？
そしたら、今までよりもラクに質問しに行けるようになりました。

「忙しそうだから・・・」って質問することを躊躇してたんですが、先輩・後輩どちらにもいいことがあるような気がします:four_leaf_clover:

というわけで、みんなどんどん質問し合えばいいと思います！
CKEditor 5の画像アップロードを実装する

CKEditorとは
---

リッチなエディターを簡単に作ってくれるライブラリです。
非エンジニア向けの管理画面を作るときに重宝します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83325/c614d65f-af1a-62db-3192-5a07ab816880.png)
https://ckeditor.com/ckeditor-5/

画像アップロードを簡単にやってくれるサービスもあるんですが、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83325/933d5794-bf1a-d921-3462-97824c485fbf.png)
https://ckeditor.com/ckeditor-cloud-services/

高いのであまり使いたくない・・・

ので、自分で画像アップロードAPIを作る方法を紹介します。

クライアント側の設定
---

`ckfinder`の`uploadUrl`にアップロード先を指定する

```js
ClassicEditor
    .create( editorElement, {
        ckfinder: {
            uploadUrl: '/path/to/image/upload'
        }
    } )
    .then( ... )
    .catch( ... );
```

https://docs.ckeditor.com/ckeditor5/latest/api/module_adapter-ckfinder_uploadadapter-CKFinderAdapterConfig.html

APIのレスポンス
---

ドキュメントのどこにも載ってない（ような気がした）ので、ソースコードを読んで返すべきレスポンスを特定します。

```js
		xhr.addEventListener( 'load', () => {
			const response = xhr.response;


			if ( !response || !response.uploaded ) {
				return reject( response && response.error && response.error.message ? response.error.message : genericError );
			}


			resolve( {
				default: response.url
			} );
```

https://github.com/ckeditor/ckeditor5-adapter-ckfinder/blob/9c19abd4c4afc15abdb8be8831aecf8852a4e327/src/uploadadapter.js#L144-L153

レスポンスはどうやらこんな感じで返せばよさそう

### 成功時のレスポンス

```json
{
  "url": "http://example.com/path/to/image",
  "uploaded": true
}
```

### 失敗時のレスポンス

```json
{
  "uploaded": false,
  "error": {
    "message": "Error message here"
  }
}
```
Clean Architectureで分からなかったところを整理する #3

# はじめに

[#2](https://qiita.com/gki/items/f601afbfada85fd8624e)ではクリーンアーキテクチャのクラス構成を考えてみました。
今回は[#1](https://qiita.com/gki/items/91386b082c57123f1ba0#1-%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E7%B5%B5%E3%81%AE%E5%8F%B3%E4%B8%8B%E3%81%AB%E3%81%82%E3%82%8B%E3%83%95%E3%83%AD%E3%83%BC%E5%9B%B3%E3%81%AE%E7%90%86%E8%A7%A3)で理解不足なところ３つ目にあげていた「アプリケーション全体の関心事」の処理について考えてみます。

# アプリケーション全体での関心事
iOS, Androidの場合、アプリの種類によっては無視できないイベントがいくつかあります。
アプリがバックグランドに入った／フォアグラウンドに復帰した、通信を行う場合インターネット接続が切れた／復帰したなどなど...

これらは「UIではないframework & driverからの入力」と考えば良い、と言う結論になりました。ちょうど本家の４つの円の絵には左上に「Devices」というのがあり、これがiOS、Android特有のそれらのデバイスイベントを監視、受け取る部分になります。それらがイベントを受け取ったらInterface Adapter経由でUsecase Interactorので処理させる、という流れです。

ここからはこの結論に至るまでの備忘録です。

## 処理の流れ
Usecase Interactorのイベントを検知するframework & driver層のクラスとイベントに応じて何か行う（UI操作とか）framework & driverをそれぞれ用意します。例えば

> 「スマートフォンがインターネット接続が切れたことを検知したら、アプリは、画面の特定エリアにワーニングメッセージを表示し続ける」
 「スマートフォンがインターネット接続が切断状態から復帰したことを検知したら、アプリは、画面の特定エリアに表示していたワーニングメッセージを消す」

のようなユースケース仕様だったら

1. インターネット接続状態を監視するframework & driverの実装
2. インターネット接続の切断／復帰のユースケースを担当するUsecase Interactorの実装
3. 画面の特定エリアのワーニングメッセージ表示／非表示を操作するframework & driverの実装

という３者で「イベント検知→画面更新」という処理を行います。
ざっくりなイメージはこんな感じ。

![cleanarchitecture example.png](https://qiita-image-store.s3.amazonaws.com/0/60457/629e84fa-ba26-55e9-9fde-1bd95c299c89.png)



## Usecase Interactorを介する必要性
上記の例の処理の流れを考えていると、この「インターネット切れた-> 画面に固定ワーニング出し続ける -> 復帰した -> ワーニング消す」という流れは、**iOS, Android特有のイベントの受け取り方をして、iOS, Android特有のViewの制御をするだけなので、はたして「Usecase Interactor」として扱うべきなのか？**という疑問が湧いてきます。

しかし、この疑問についてはやはり「Usecase Interactorを介すべき」という答えになりました。
上記の仕様例はインターネット接続が切断されたイベント発生時に行う処理が１つですが、Usecase Interactorを使わずに実装した場合、仕様変更によって複数の処理を扱うときに不都合が起きます。

例えば、Interactor未使用の実装をしていたとき、「スマートフォンがインターネット接続が切れたことを検知したら、アプリは、画面の特定エリアにワーニングメッセージを表示し続け、**かつ、アプリ内部にxxx(何か大切な値)を保存する**」という仕様変更があった場合、Usecase 「ワーニングメッセージ表示の画面更新にはUsecase Interactorを使わないけど、永続化処理のことはUsecase Interactorを使う」という実装をしてしまいそうになるのではないでしょうか。

![cleanarchitecture example (1).png](https://qiita-image-store.s3.amazonaws.com/0/60457/c843e48f-ab7d-085e-333d-bbf9502404cb.png)


ですが、これではUsecase Interactor以外の部分が「ユースケースの詳細（画面処理と永続化処理を操作する必要がある）」を知っていることになり、役割分担が崩れてしまいます。

将来に渡って各実装の責任範囲を明確に保つことを考えると、たとえその時点ではイベントを横に流すだけだとしても、Usecase Interactorを介するべきと思います。

![cleanarchitecture example (2).png](https://qiita-image-store.s3.amazonaws.com/0/60457/5971894b-618b-7e18-fbbd-197e2619ce4f.png)


# まとめ
今回は残っていた自分の疑問「アプリケーション全体の関心事」について考えをまとめました。[#1](https://qiita.com/gki/items/91386b082c57123f1ba0#1-%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E7%B5%B5%E3%81%AE%E5%8F%B3%E4%B8%8B%E3%81%AB%E3%81%82%E3%82%8B%E3%83%95%E3%83%AD%E3%83%BC%E5%9B%B3%E3%81%AE%E7%90%86%E8%A7%A3)の記事では

> おそらく外→内→外の部分は変わらず、内→外の箇所でどうやって「全体への周知」を行うか。ま、単純なcallbackではないような気はしている。

なんて書いてましたが、ちゃんと考えると結局外→内→外でしたね。。。

このエントリがどなたかの頭の整理に役立てば幸いです。
Swagger3.0でexampleを利用したモックを最速で立てる方法

#前書き
Swagger3.0に対応していてかつexampleを利用したレスポンスを返してくれるモックを求めていた。
Codegenなども調べたがスケルトンコードが出力されたのでほかの方法を模索

# 立て方
0. 以下からOSに合わせたバイナリをダウンロード
    * https://github.com/danielgtaylor/apisprout/releases

1. 解凍先でいずれかのコマンドを実行

```
apisprout 【対象ymlファイル】
```
```
apisprout 【対象ymlファイルのURL】
```

**たったこれだけ、以上！！**
デフォルトポートは8000

# yaml記述の注意
componentsセクションのexampleとして記述すること。
オブジェクトやプロパティのexampleとしてでは記述時点では反応しない

```
paths:
  /:
    get:
      responses:
        '200':
          content:
            application/json:
              examples: #←ここ
```

# 参考先
* https://github.com/danielgtaylor/apisprout
    * 今回のツール
* http://openapi.tools/
    * OpenAPIに対応したツールがまとめられており、ツールを発見した場所
* https://swagger.io/docs/specification/adding-examples/
    * exampleの記法リファレンス

### 感想
* ファイルを指定するだけでモックが起動できる最高！！
* ソースをあまり読めてないけれども、Golangの極めて短いコードで実現されていてすごい
CMake 3.12.0 インストール手順

#0. 古いバージョンのアンイストール
**新規でインストールする場合は、この手順は不要です。
手順1.から始めてください。**
今使っている、CMakeのバージョンが3.4より古い場合は、新しいバージョンのCMakeをインストールする前に、アンイストールを行ってください。
インストーラーがexeからmsiに変わってるみたいです。
コントロールパネル>プログラムと機能からアンイストールできます。

# 1. ダウンロード
以下からBinary distributionsにあるcmake-3.12.0-win64-x64.msiをダウロードする
(インストーラーを見た感じ、x86(32bit)がなくなってるみたいです)。
http://www.cmake.org/download/
![WS000000.png](https://qiita-image-store.s3.amazonaws.com/0/92978/89d38214-0844-5d3f-bd21-1f117bef7e00.png)

# 2. インストール
ダウンロードしたcmake-3.12.0-win64-x64.msiを実行しインストールを進めていく。
![WS000001.png](https://qiita-image-store.s3.amazonaws.com/0/92978/7c4cd379-92f9-5b48-9505-91503e430239.png)
「Next」を押す。
![WS000002.png](https://qiita-image-store.s3.amazonaws.com/0/92978/7b89ed72-a9ca-6a59-5d1d-24ea9da44bab.png)
「I accept the terms in the License Agreement」にチェックし、
「Next」を押す。
![WS000003.png](https://qiita-image-store.s3.amazonaws.com/0/92978/c3cf9817-6ef6-3b38-36f1-d69885efad20.png)
環境変数にPATHを追加しておくために、「Add CMake to the system PATH for all users」(全てのユーザーに追加)か「Add CMake to the system PATH current users」(現在のユーザーに追加)を選んでおく。「Create CMake Desktop Icon」(デスクトップにCMakeのアイコンを追加する)はデスクトップにアイコンを追加したい場合はチェックをしておく。これはどっちでもいい。
「Next」を押す。
![WS000004.png](https://qiita-image-store.s3.amazonaws.com/0/92978/3e3ef26f-2aae-3b23-02b8-4936af70480b.png)
インストールしたいフォルダを指定して「Next」を押す
(デフォルトは、C:\Program Files\CMake\)。
![WS000005.png](https://qiita-image-store.s3.amazonaws.com/0/92978/da8a4e94-fa8c-80d4-a77b-43bca81ae12a.png)
「Install」を押す。
インストール中に、ユーザーアカウント制御が出てきた場合は、「はい」を押す。
![WS000006.png](https://qiita-image-store.s3.amazonaws.com/0/92978/8f7178da-2935-eb80-8d8f-08da1b2d3924.png)
インストールが終わったので「Finish」を押す。
インストール後は、コマンドプロンプトからpathと入力するか、
Windowsスタートメニュー>コンピューター右クリック>プロパティ>システムの詳細設定>環境変数>システム環境変数>Pathから「C:\Program Files\CMake\bin」があるか確認してください。あれば、CMakeへのパスが通っています。なければ、「C:\Program Files\CMake\bin」を追加してください。
Vtuber関連の調べ物


VRアカデミアに入ってみたくて調べた。
#低価格VRの心得（技術指南）
https://qiita.com/Hirosaji/items/83777124823683766d96
http://realsound.jp/tech/2018/05/post-196677.html
https://entamevr.com/vtuber-vr
https://entamevr.com/vtuber-pctools
https://nancreator.com/vtuber_kizai-12360
https://riyaaaaasan.hatenablog.com/entry/2018/05/06/231901
http://it-rush.com/vtuber-smartphone
https://www.nemchan.com/2018/04/vtubertech.html

##バーチャルキャスト
https://www.infiniteloop.co.jp/blog/2018/04/virtualcast/
https://panora.tokyo/58761/

##Vカツ
https://mashironote.com/2018/07/30/vkatsu/

#VTuber生活の楽しみ・Vtuberコミュニティの現状
https://www.pipipipipi5volts.com/entry/nakanohito-virtual-youtuber
https://nojobslife.hatenablog.com/

うーん、高い！ｗ
[openFrameworks] ofDisableArbTex() の挙動

# `ofEnableArbTex()` / `ofDisableArbTex()`の挙動

`ofEnableArbTex()` / `ofDisableArbTex()`はテクスチャを生成する際のフォーマットを決めます。これらの関数はShader内でのテクスチャ参照方法に影響があるので注意が必要で、それぞれの挙動を以下にまとめます。

* `ofEnableArbTex()` を呼んだ後のテクスチャは `GL_TEXTURE_RECTANGLE_ARB` で生成される(デフォルト)
* `ofDisableArbTex()` を呼んだ後のテクスチャは  `GL_TEXTURE_2D` で生成される

| | `GL_TEXTURE_RECTANGLE_ARB` | `GL_TEXTURE_2D` |
|:--|:--|:--|
|特徴|Non-power-of-two sized (NPOTS)||
|glsl内のsampler型| sampler2DRect | sampler2D |
|テクスチャ参照座標|[ 0 ... w ] x [ 0 ... h ]　(非正規化座標、矩形座標) |[ 0 ... 1 ] x [ 0 ... 1 ] 　(正規化座標) |

# 関連する豆知識

* OpenGLにはたくさんのテクスチャフォーマットがあるが、openFrameworksでは基本的に上記2つのフォーマットのみ想定している

OpenGLの用意するテクスチャのフォーマットのenum値については、[ドキュメントに書いてあります](https://www.khronos.org/opengl/wiki/Texture)。Cube Map用のフォーマットや3次元テクスチャなど、様々な用途を想定して仕様策定されているのがわかりますが、oFの場合は上述の2つのみを利用する想定でデザインされています。（利用頻度的に問題ない、かつ、必要であればGLの関数をそのまま用いれば良い）

* `ofMesh::plane()`や`ofRectangle()`は正規化済みのテクスチャ座標が付与される

よって、デフォルトの`GL_TEXTURE_RECTANGLE_ARB`の状態で、`ofTexture::bind()`などでテクスチャをメッシュなどにバインドしようとしても参照方式が正規化座標ではないのでうまく動作しません。つまりデフォルトの状態では、テクスチャバインドは動作せず、 テクスチャ座標を矩形座標にあわせてつけなおすか、おとなしく`ofDisableArbTex()`を呼んでから生成したテクスチャをバインドする必要があります。これは仕様であり[フォーラムでも過去に議論されています](https://forum.openframeworks.cc/t/how-to-bind-offbo-texture-to-a-3d-object/27760)。
デフォルトで`ofRectangle()`などにテクスチャバインドが動かないのは不便だから、`ofEnableArbTex()`のときは、Rendererにわたすテクスチャ座標をゴニョってよしなにやろうよと[issueを投げたところ](https://github.com/openframeworks/openFrameworks/issues/6099)、それはダメと瞬殺でCloseされました…。一瞬のできごとでした…。

* Non-power-of-two sized (NPOTS)

`GL_TEXTURE_RECTANGLE_ARB`はNon-power-of-two sized (NPOTS)であり、その意味するところは、ピクセルサイズが2のべき乗でなくても再サンプリングしないテクスチャを指します。ドキュメントは[こちら](https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_rectangle.txt)。再サンプリングが無いためARBテクスチャの方が配置リソースの効率化が期待できますが、ラップ方式やミップマップの使用などに一部制約があります。

ちなみに接尾語の**ARB**とは、Khronos Groupとは独立して組織された(現在は合流)"Architecture Review Board"の略で、この団体から提案された仕様であることの名残とのこと。Arbitararyの略かなとか盛大に勘違いしていました。指摘してくださった2bitさんありがとうございます。。
(ただ、そうなるとArbTexとついた関数名は少し不適切なのではとも思う)

* どちらを利用すべきか？

個人的には、WebGL含むOpenGL ESでは、`GL_TEXTURE_RECTANGLE_ARB`がないことから、Shaderの移植性なども考慮し、`GL_TEXTURE_2D`に倒して（つまり、`ofDisableArbTex()`を必ず呼ぶ）をしたほうが少しは面倒くさくないのではと思います。
二進数の二の補数について

補数を使った減算
====
コンピュータで整数の減算を行う方法で現在最も普及しているのは、加算回路と二の補数を使う物でしょう。
IBMのSYSTEM/360で採用された事が普及のきっかけになったとされています。
減算回路の文脈で二の補数が出てきたのは、ノイマン先生の "First Draft of a Report on the EDVAC" が最初じゃないかと思います。
http://2908.work/Okiba/vnedvac.pdf
（8.0 CIRCUITS FOR THE ARITHMETICAL OPERATIONS）

実際に動作したのはEDSACの方が先ですが。

定義
====
>b進法において、自然数 a を表現するのに必要な最小の桁数を n としたとき、
>　b<sup>n</sup>-a を「b 進法における a に対する基数の補数（b の補数）」
>　b<sup>n</sup>-a-1 を「b 進法における a に対する減基数の補数（b - 1 の補数）」
>という。

[Wikipedia "補数" より](https://ja.wikipedia.org/wiki/%E8%A3%9C%E6%95%B0)

つまり、補数とはある数に加えると桁上がりする数の最小値や、桁上がりしない数の最大値です。
桁上がりがカギですから、何進数で考えるかが重要です。

二進数の補数は一の補数と二の補数があります。
同様に、三進数には三の補数と二の補数があります。
以下この記事では、単に二の補数と言った場合、二進数の二の補数を言います。

二の補数とは、ある数を二進数で表現した時の、ある数に加えた時桁上がりする最小の数です。

桁上がりなので、何桁の数についてなのか考える必要があります。例えば８桁の二進数で1101の二の補数の場合、8桁の0000 1101について考えます。桁上がりしたら1 0000 0000です（0は8個）。
この場合二の補数は 1 0000 0000-0000 1101=1111 0011 です。


求め方
====
二の補数の場合、各ビットを反転して１を足す、という便利な方法があります。
この求め方を「二の補数の定義」として紹介しているページがありますが、厳密に言うと定義ではありません。これは「コンピュータは加算しか出来ない」と説明してしまったから補数も加算で求めないと辻褄が合わないからでしょう。
しかし、１を引いてからビット反転しても同じ結果になります。何より補数はその定義から減算である事は明らかです。

ではなぜ反転して1を足す…　言い換えて、

　なぜ反転すると 二の補数-1 が求められるのでしょうか？

例として4桁の二進数1001について考えてみましょう。
まず、桁上がりした数の最小は5桁の10000です。2の補数の定義から、1001に足した時に10000になる数を求めればいいのですが、このままだと普通に減算が必要です。
そこで10000から1を引いた1111で考えてみましょう。この時に引いた1は**最後に足してあげます**。
1111-1001ですから各桁は 1-1 か 1-0 で、上の桁からの借りが発生しません。という事は下の桁への貸しもありません。各桁ごとに計算すれば答えを求めることが出来ます。

各桁は必ず1から引くので引かれる数が0の場合は省略します。

| 引かれる数| 引く数 |→| 結果 |
|---:|---:|---|---:|
|1|0|　|1|
|1|1|　|0|

ほら、「引く数」と「結果」が反転の関係になってるでしょ？
ということで1001を反転して0110です、そして、反転する前に引いた1を足して戻してあげれば2の補数です。

4桁の二進数1001の二の補数は
　答え:0111
です。

法n
====
4桁の0000は反転して1を足すと10000です。桁あふれは無視すると解説したページもありますが、4桁の二進数で表現できる数は16種類、法16のもとで10000と0000は合同であるから同じ、と考える事が出来ます（16は十進）。
だとすると、Aの補数は **Aに足して0になる数** と言い換える事が出来ます。まさに **Aの補数 = 0-A = -A** です。

つまり、二進数で二の補数を取るというのは、符号を反転する操作です。
符号反転だから加算<->減算は二の補数を利用して相互に変換可能です。

そして、補数はお互いが補数の関係です。Aの補数がBなら、Bの補数は必ずAです。


----
[コンピュータの動作原理（４）減算回路](https://qiita.com/niQSun/items/220215cbc3d298e07487)より。
FlaskとTwitter APIで、ツイッターのソーシャル分析アプリを作りました

# FlaskとChartjsで、データ可視化アプリ作った。

こんにちは、DAIです。
今回は、Twitterのアカウントの影響力を可視化できるアプリを作成しました。
ぜひ、使ってみてください。（ただしアルファアカウントを入れると処理落ちします）

https://top-tweets.herokuapp.com/

# 何ができるの？

ツイッターのアカウントを入れると、そのアカウントがここ最近したツイートのいいね数や、リツイート数が日時でグラフ化されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/134704/35a345a9-86b6-db97-99c9-d1749efa6b3b.png)

また、ツイッターAPI上でとれるすべてのツイートを取得し、日時でのいいね数とリツイート数を確認することができます。さらに、過去もっともリツイートされたツイートが、降順にソートされています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/134704/b912f72a-374e-6fc2-846c-d19337f9234e.png)

# 何がうれしいの？

アカウントを指定して、どんなツイートが伸びるのかを分析することができます。その結果、発信力を磨くためのヒントが得られます。

# どうやって作ったの？

PythonのFlaskと、Twitter API、Bootstrap、chartjsを利用して作りました。Pythonでデータを処理して、何らかのWebサイトで反映したいみたいなときに、サクッと可視化できたので、Flaskとchartjsの組み合わせはお手軽でよかったです。

# 詳細

以下noteに詳細を書きました。もし興味がある方はこちらから見てみてください。

Flaskチュートリアル - Pythonでツイッターの分析ツールを作ってディプロイしよう！（動画つき！）-
https://note.mu/daikawai/n/n233ef9662323
Visual Studio 2017 でVisual Studio Codeをエディタにする一番簡単な方法

タイトルの通りです。

ノンプログラマーなエンジニアにとっては
GitHubとの連携やソースコード管理にはVisual StudioのGUIがよくできていて
便利なのですが、実際にスクリプトなどを書くときには
Visual StudioよりもVisual Studio Codeの方が色分けなどが見やすいので、
この2つを連携して使っています。

[検索すると](http://d.hatena.ne.jp/toburau/20170716/1500222956)引数やコマンドを使って連携する方法が紹介されていますが。

たいぶん、この方法が一番簡単だと思うので、紹介します。

1.Visual Studioでファイルを選択して右クリック
[ファイルを開くアプリケーションを選択]をクリック
<img width="458" alt="2018-08-04_20h25_51.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/20489ffc-4430-4898-081e-205334e66471.png">

2.ファイルを開くアプリケーションで[追加]をクリック
<img width="401" alt="2018-08-04_20h26_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/89270926-3e2a-3d51-2c20-c0e0b621eb1e.png">

3.Visual Studio Codeを選択
<img width="293" alt="2018-08-04_20h26_18.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/0f22a64f-dcbd-50e6-8b07-0ed46268f671.png">

4.Visual Studio Codeを既定値に設定
<img width="401" alt="2018-08-04_20h26_26.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/d9a3d3b0-4e39-cf2b-6b60-fca10f7d8224.png">

これだけで、編集したいファイルをクリックすれば、Visual Studio Codeが起動してくるので、Visual StudioのデフォルトエディタがVisual Studio Codeになります。
VueJSで工事写真報告ツールをサーバレスで作ったけどだんだん辛くなってherokuに移行した話


https://sakeganaito.connpass.com/event/92540/
のLT資料です。

# 自己紹介
 - rsooo と申します
 - シェル(bash, zsh)が好きです。
 - BPM株式会社というところで不動産修繕系のサービス作ってます
 - レガシーな業界です。

----

### 背景
- 工務店と職人の工事の関係
<img width="669" alt="スクリーンショット 2018-08-04 16.26.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/18345/3176ccbb-2cc7-c3c5-b2e7-4cb223b4456d.png">

- 写真はLINEかデジカメ使ってメールで送る
- その後写真をエクセルに貼り付けて報告書作成してPDFに
 -> 直接職人さんから写真送ってもらうフォーム作ればいいんじゃね？

----

### 作ってみた(工事写真報告ツール)
![Untitled Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/18345/f6ad2397-ff2f-9822-ccb1-03222c1f54ca.png)

 - Lambda+S3
 - vueJSの静的ファイルをS3に置くだけ
 - データもS3にJSONで保存。DBすらない
 - 認証もない。案件IDをURLクエリパラメータにいれるだけ。

----
### 使ってみた
 - 意外に使ってもらえる
 - ややこしいボタンとかは評判悪いので排除
 - エイヤで作ったけど、現場で結構使われるように

----
### 辛くなってきた
 - 投稿件数の取得がしたい
 - ベーシック認証かけたい
 - ステージング環境がほしい
 - ログちゃんと残したい
 - babelかましたい

##### そんなこんだで最終的にはherokuに移行
 - herokuのpileline便利ですね。

---
### まとめ

 - VueJS, S3, Lamda+αでなんとなく動くものがすぐ作れる。
  - ただしセキュリティとか運用要件はほぼ無視 
  - あくまでトライアルとして
 - サーバレスというとかっけー感じするけど、実運用の要件取り込んでいくうちに、別にサーバレスじゃなくてもよくね？という感じになってきた。