OmniAICreator/Qiita-1.07M huggingface dataset:
【2019版】ガートナーが国内ハイプサイクルを発表したので表にしてみた【DX】

#目的のようなもの

10/31に発表されたハイプ・サイクルに採用されている技術キーワードをピックアップして表に書き出して、普段業務で触れている技術がトレンド上のどの段階にあるのかを認識して1人のエンジニアとして中期、長期においてどの様にポジションを取っていくのがベターかを考える機会にしたいなと思います。

#2019年 国内版ハイプ・サイクル図

![20191031-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354022/2c35f7dc-e4bd-2a08-77d5-a9e9a7d987b2.png)

こちらが参照元
[ガートナー、「日本におけるテクノロジのハイプ・サイクル：2019年」を発表](https://www.gartner.com/jp/newsroom/press-releases/pr-20191031)

#そもそもハイプ・サイクルとは

ガートナー社が作り出した造語で、特定の技術の成熟度や採用度、社会への適用度を図で示したもの。また、ハイプ・サイクルには主に以下の5つの段階で構成されております。

**黎明期**
新しい概念や技術、商品が発表された段階

**「過度な期待」のピーク期**
「凄い技術が出たぞこれからの時代は○○だ」と、世間からの注目が集まり
本屋の棚には関連図書で溢れバズワードとして取り上げられるような段階

**幻滅機**
過度に期待された技術や概念が人気のピークを過ぎて人々が一時冷静さを取り戻す段階

**啓蒙活動期**
幻滅機を経て人々の関心が他所へ行ってもなお根気よく研究開発を続けていた事業が徐々に芽が出し始める段階

**生産性の安定期**
人々に技術が適切に理解され実際に広く利用されるようになる段階


#40キーワードを表にしてみた


|技術キーワード|主流までの年数|段階レベル|
|---|---|---|
|ベンダー管理オフィス|2~5年|啓蒙活動期|
|レガシーアプリケーションの近代化|5~10年|啓蒙活動期|
|クラウドコンピューティング|2~5年|啓蒙活動期|
|情報漏洩防止|2~5年|啓蒙活動期|
|ソーシャルアナリティクス|2年未満|啓蒙活動期|
|CRM顧客エンゲージメントセンター|2~5年|幻滅期|
|ウェアラブルデバイス|5~10年|幻滅期|
|クラウドソーシング<br>(アプリケーション開発)|5~10年|幻滅期|
|OTとITの融合|2~5年|幻滅期|
|ブロックチェーン|2~5年|幻滅期|
|API|5~10年|幻滅期|
|ロボティック・プロセス・オートメーション|2~5年|幻滅期|
|デジタルビジネスコンサルティングサービス|5~10年|幻滅期|
|サービスとしての統合プラットフォーム|5~10年|幻滅期|
|コラボレーティブワークマネジメント|2~5年|幻滅期|
|人工知能|5~10年|幻滅期|
|仮想アシスタント|2~5年|幻滅期|
|DevOps|5~10年|幻滅期|
|モノのインターネット|5~10年|幻滅期|
|ワークストリームコラボレーション|2~5年|幻滅期|
|モバイルアプリ開発プラットフォーム|5~10年|幻滅期|
|アクセラレータプログラム|2~5年|幻滅期|
|IoTプラットフォーム|5~10年|「過度な期待」のピーク期|
|ポストモダンERP|2~5年|「過度な期待」のピーク期|
|エッジコンピューティング|2~5年|「過度な期待」のピーク期|
|プレディクティブサポート|2~5年|「過度な期待」のピーク期|
|プライバシーバイ・デザイン|2~5年|「過度な期待」のピーク期|
|デジタルビジネス<br>テクノロジービジネス|5~10年|「過度な期待」のピーク期|
|市民データサイエンス|2~5年|「過度な期待」のピーク期|
|ベースレイヤアプリケーション戦略|5~10年|「過度な期待」のピーク期|
|アジャイルプロジェクトマネジメント|2~5年|「過度な期待」のピーク期|
|５G|5~10年|「過度な期待」のピーク期|
|デジタルエクスペリエンスプラットフォーム|5~10年|黎明期|
|IoTセキュリティ|10年以上|黎明期|
|セキュリティオーケストレーション<br>自動化/対応(SOAR)|5~10年|黎明期|
|スマートワークスペース|5~10年|黎明期|
|AIOpsプラットフォーム|5~10年|黎明期|
|コンポーザブルインフラストラクチャ|5~10年|黎明期|
|デジタルメッシュ|10年以上|黎明期|
|メインフレームトランスフォーメーション|10年以上|黎明期|

私がIT業界に入ってクラウドに関する業務に従事する以前、何年か前のニュースでのクラウドに対する企業側の見方はどちらかというと前向きとは言い難い姿勢の論調で見かける事が多かったかな〜と薄っすらと記憶しておりますが、ここ最近になってAWSを筆頭に積み上げられた実績によりクラウドファーストに向かっていっていると感じております。ハイプ・サイクル上でも**啓蒙活動期**を経てこれから**安定期**に乗る段階であるので肌感にギャップはないなという印象です。

とはいえクラウドファーストな時代だからこそ、クラウドやる人の需給バランスはすぐに整っていって少し出来る程度では相対的な価値は薄れていく姿が見えていますので、自分ならではのバリューが出せるように危機感を持ってが頑張らないと…がんばります。

また、開拓者が少ない分、需給にギャップがあるので5年後以降にも目線を向けてみるのも有りかもですね。まあ、頭がついていかないんですけども…。

日本はアメリカや中国と比較して先端技術の実装が遅いとよく言われていますが、それでもSFチックな風景が徐々にその片鱗を見せてくると思うとワクワクしますよね。出来れば近い場で立ち会えればいいなと思います。

#オチ
思いつきで書こうと思ったのでオチは特にないです。
あ〜そんなのあるんだ〜と誰かの気付きにでもなれば今夜はよく眠れる気がします。
GASにてキャレット自動セット、focus()もhtml5のautofocusも安定しないとき。

document.getElementById('ID').focus;

を
      
document.getElementById('ID').autofocus; 

として解決。

できなかった。。。安定しない。

Htmlのautofocusも画面をリロードすると安定しない。。。ぐぬぅ。
Spring Framework 5.2.0 - CORSハンドリング変更によるVary header重複

5.2.0.RELEASEにてSpring Securityを使用する場合、以下のVaryレスポンスヘッダーが重複することがある。

- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers

特にこんな感じで`@CrossOrigin`なControllerのテストを実行する際に重複してしまう。

```java
    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .apply(SecurityMockMvcConfigurers.springSecurity()).build();
    }
```

## 対象
Spring Framework 5.2.0.RELEASE (spring-web)
＋ Spring Security使用

## 原因
エンドポイントに対し、Spring SecurityのCORSの設定と`@CrossOrigin`アノテーションの両方を設定していると発生する。
これは`DefaultCorsProcessor.java`の`handleInternal`メソッドから`processRequest`メソッドにてVary headerを追加するように変更となったため。
Spring SecurityでのCORSとWebMVCでのCORSのFilterがかぶるようで2回実行されてしまうことがある。

```java:DefaultCorsProcessor.java
public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request,
        HttpServletResponse response) throws IOException {

    response.addHeader(HttpHeaders.VARY, HttpHeaders.ORIGIN);
    response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
    response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
    ...
```


[差分はこちら](https://github.com/spring-projects/spring-framework/commit/d27b5d0ab6e8b91a77e272ad57ae83c7d81d810b)

## 回避方法
Spring Security configで以下のように設定しているcorsの設定をやめる。

```java:SpringSecurityConfig.java
@Override
public void configure(HttpSecurity http) throws Exception {
    http...
        .cors()
            .configurationSource(this.corsConfigurationSource());
}

private CorsConfigurationSource corsConfigurationSource() {
    ...
}
```

これまではCorsFilterが2回走っても問題なかったが、ヘッダー付加の場所が変わってしまったため2回走ると重複するようになってしまった。

Spring SecurityのCORSの設定と`@CrossOrigin`の2つ設定しちゃだめなんですかね。。
なにか他に良い解決方法があれば。。。。。


ちなみに、その他変更点も結構ある。5.2.0怖
https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x
SQLのメモ

# なにこれ
やっほ
python経由でsqlite db遊んでたときに遊ぶどころじゃなくなった事案をメモするところ

# パラメータ指定
`?`と`:`のパヤーンがある。
特定のカラムの情報だけしか無いときに使う。(カラムいちいち全指定するの嫌)

    query = ('INSERT INTO table (columnA) VALUES (:columnA)')
    cursor.execute(query, {'columnA':'hogehoge'})

## 未確認
なんか~~`:=`~~ **`=:`**みたいな指定どっかで見たんだよなぁ・・・
こいつ使ったらパラメータで渡す内容、順番関係なく出来ないだろうか

    # 試してダメだったやつ
    query = ('INSERT INTO table (columnA, columnB) VALUES (columnA=:hogeA, columnB=:hogeB)')
    cursor.execute(query, {'hogeB':'hogehoge'.'hogeA':'hogege'})
 
> 追記 これ単純に `:` のパラメータを代入してるだけやんって気付いてしまった解決（追追記：してないかも）

## 参考
[Crane & to. > Python3でSQLite3を使う – 基本操作からエラー処理までサンプルコード付](https://www.craneto.co.jp/archives/1248/)
[Python公式のやつ](https://docs.python.org/ja/3/library/sqlite3.html#cursor-objects)
[stack overflow > sqlite-parameter-substitution-problem](https://stackoverflow.com/questions/228912/sqlite-parameter-substitution-problem)

# 最新のIDを割り振る
特定のカラムに同じ内容のfieldが存在してたらID被りだけをゴリ押しで回避する

    INSERT INTO table (id, content) SELECT IFNULL(MAX(id), 0) + 1, content="hogegenoge" FROM table WHERE content
Golangにおけるポインタについて

## ポインタって？
まず、ポインタという言葉の前にメモリについて理解をすることが必要です。

``` go

n := 200

``` 

変数nが定義された時に、200を一時的に保存する場所が ` メモリ`です。

メモリは、複数存在しそれぞれのメモリに番号が振られています。

この番号を `アドレス` と呼びます。

実際にアドレスを確認してみます。
Goでは、&を定義した変数の前につけることでメモリを確認することができます。

``` go

func main() {
	n := 200
	fmt.Println(&n)
    // -> 0xc000084000

```

つまり、アドレス`0xc000084000`に変数nの200が保存されていることになります。

アドレスとメモリについて理解したところで、` ポインタ `について考えていきます。

ポインタを調べると、このようにまとめらていました。

* メモリのアドレス情報のこと
* アドレス情報を格納するための変数のこと

もう少しこの２つを詳細に見ていきます。

Golangには、 `ポインタ型`と`ポインタ変数`

ポインタ型は、stringやintなどの方に*をつけることで定義します。

下では、nがポインタ変数にあたり、*intがポインタ型になります。

``` go
func main() {
	var pointer *int
	n := 100

	// 1.
	pointer = &n

	// 2.
	fmt.Println("pointerの中身：", *pointer)
}

```


1.  &nを使うことで、nのアドレスの番地をpointerに格納している
2. pointer型から値を取得するためには、*をつけることで値を表示することができる


## 実際にポインタ型を使う時
ポインタ型は、参照渡しを行う時に用います。

Swiftでは、inoutを使いますね。

``` go
func main() {
	a, b := 100, 100

	checker(a, &b)
	fmt.Println(a, &b)
        // -> 100 101
}

//1
func checker(a int, b *int) {
	a++
	*b++

}

```
1. 参照渡しを行うことで、呼び出しもとのbの値が変更される。

## まとめ
多言語からGolangを始める方、初心者の方はこのポインタ型におそらく苦労されると思います。（自分がそうだった）

そこで、実際に手を動かして書くことで少し理解が深まると思います！

ぜひ、この記事を読みながら実際にパソコンでも手を動かして欲しいなと思います。
Flutterでandroidビルドしたらgradleで落ちた(Flutter勉強1日目)

Flutterの勉強はじめてみました。
ほぼアプリ開発は未経験ですがつまづいたところをシェア。

# 環境
- Mac
- Android Studio 3.5.1
- Flutter 1.9.1

# 現象
Flutterで`$ flutter run -d all` するとandroid側のみエラーとなる。

# エラーログ
```shell
$ flutter run -d all

~省略~

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'android'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not download builder-test-api.jar (com.android.tools.build:builder-test-api:3.2.1)
      > Could not get resource
      'https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.2.1/builder-test-api-
      3.2.1.jar'.
         > Could not GET
         'https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.2.1/builder-test-a
         pi-3.2.1.jar'.
            > Connect to dl.google.com:443 [dl.google.com/216.58.197.206] failed: Bad file descriptor (connect
            failed)
   > Could not download layoutlib-api.jar (com.android.tools.layoutlib:layoutlib-api:26.2.1)
      > Could not get resource
~省略~

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 5s
  Command: /Users/yuta/dev/my_app/android/gradlew app:properties


Please review your Gradle project setup in the android/ folder.
```
# 修正内容
- android側のディレクトリで利用するGradleのバージョンを使っているAndroidプラグインの環境と合わせる

[突き合わせ表](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle)

```shell

# ファイルパス
/android/gradle/wrapper/gradle-wrapper.properties

#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

# 4.10.2を5.1.1に変える
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
```
strapiが僕の知ってるCMSではなかったのでドキュメントの見どころ紹介

CMSってデータベースのスキーマまで管理するのかい？

<img width="981" alt="スクリーンショット 2019-11-01 0.28.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343171/3a04e491-19a9-2eeb-7ae7-42b733f4e886.png">

とにかく言えるのは、「node rails like framework」なんて検索してる場合ではなかった。

さてドキュメントの見どころ紹介。

## チュートリアル
起動したらあとは画面上でポチポチやってるだけなのだ。。
https://strapi.io/documentation/3.0.0-beta.x/getting-started/quick-start-tutorial.html

### 多対多のリレーション定義
https://strapi.io/documentation/3.0.0-beta.x/getting-started/quick-start-tutorial.html#_4-create-a-new-content-type-called-category

中間テーブル名はcategories_restaurants__restaurants_categories。

スキーマ：

```
sqlite> .schema categories_restaurants__restaurants_categories
CREATE TABLE `categories_restaurants__restaurants_categories` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `category_id` int null, `restaurant_id` int null);
```

```sql
sqlite> select * from categories_restaurants__restaurants_categories;
1|1|1
2|2|1
```

### ロールとパーミッション
https://strapi.io/documentation/3.0.0-beta.x/getting-started/quick-start-tutorial.html#_7-set-roles-and-permissions

ここではfindとfindoneのみ許可。
クリックするとAdvanced settingsに表示されるけど、 `GET /resource` と `GET /resource/:id`

userに関してはmeのみ許可などもできるようだ。
制御に関連を利用したい場合とかについては[こんな感じ](https://github.com/strapi/strapi/issues/2161)の議論があった。現状では専用のコントローラを用意することになるのかなと。

それにしても、

> think of an HR system where normal employees can only see name and email (of the object "employee") whereas an HR can see the personal address and bank account.
> たとえば、通常の従業員は名前とEmailしか見れないが、HRは住所と銀行口座が見れるというような。

うん。そういうきめ細かいことを簡単にやっちゃいたいのよね。

### 生成されたAPI叩くとこ
https://strapi.io/documentation/3.0.0-beta.x/getting-started/quick-start-tutorial.html#_8-consume-the-content-type-api

ちゃんとjsonになってます。

## ディレクトリ構造
https://strapi.io/documentation/3.0.0-beta.x/concepts/file-structure.html

modelとかcontrollerとかserviceとかあります。
馴染み深〜い。

## コントローラ

https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html
ビジネスロジックを書きます。

## モデル
https://strapi.io/documentation/3.0.0-beta.x/concepts/models.html
<img width="301" alt="スクリーンショット 2019-11-01 0.45.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343171/4b69f345-721f-b7c3-1490-64fde50e005c.png">
jsの方はライフサイクル管理。フィールドの設定やらには `.settings.json` という感じ（ただしmongo以外はDBMSのほうですべしとある）。

## クエリ
https://strapi.io/documentation/3.0.0-beta.x/concepts/queries.html

ORMはBookshelf.js
https://bookshelfjs.org

## ポリシー
https://strapi.io/documentation/3.0.0-beta.x/concepts/policies.html

リクエストがコントローラに到達する前にisAdminとかisAuthenticatedとかのフィールドを設定できる。
ミドルウェア？ いや、違うっぽい？

## ミドルウェア
https://strapi.io/documentation/3.0.0-beta.x/concepts/middlewares.html

```
await next();
ctx.set('X-Response-Time', delta + 'ms');
```

みたいな。オニオンにできるのね。
※ポリシーもオニオン
https://strapi.io/documentation/3.0.0-beta.x/concepts/policies.html#advanced-usage

こっちのミドルウェアは `strapi.app.use` してるのが違いなのだと思う。。
ポリシーはroutesで設定。

## 感想
とりあえず感想を書けば締まると思っている。
【Excel】SUBSTITUTE関数を使って楽をする

##序文
###目的
Excelの関数を使って、めんどくさい変換を自動で処理して楽をする。
###前提条件
A1セルに変換元の値が入っている。
変換元の値には、文法的な間違いはない。
※5桁のコードに4桁しか入ってないとか。

##正規表現的なアレ「を」変換する
###要件
^(111_)+(222_)+(333_)+$　→　111+222+333+
###関数
`=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"^",""),"(",""),"_",""),")",""),"$","")`
###仕組み
`^`　`(`　`)`　`_`　`$`
の5つの記号を、SUBSTITUTE関数でnull置換する。それだけ。

##正規表現的なアレ「に」変換する
###要件
111+222+333+　→　^(111_)+(222_)+(333_)+$
###関数
`="^("&SUBSTITUTE(SUBSTITUTE(A1,"+","_)+(")&"★","(★","$")`
###仕組み
頭に`^(`をつけ、SUBSTITUTE関数で`+`を`_)+(`に変換して、末尾に`$`をつける。
だが、そのままだと末尾の`+`も変換されて、`^(111_)+(222_)+(333_)+($`になってしまう。最後の`(`が余分。

そこで、`+`を`_)+(`に変換した段階で、いったん末尾に`★`をくっつける。（★でなくても、変換元の値と競合しなければなんでもいい）
`^(111_)+(222_)+(333_)+(★`

末尾が`(★`になっているので、これを`$`に置換してやれば完成。

##コードと名称の分離
###要件
`　ER123　 株式会社ExampleRoom`
コードと名称がスペース(半角・全角)でつながっているデータから、コードと名称をそれぞれ取り出す。
スペースの数は不定で、コードの前にもスペースが存在する場合がある。コードは必ず英数5桁。

###関数
コードを取り出す
~~`=LEFT(SUBSTITUTE(SUBSTITUTE(A1," ",""),"　",""),5)`~~
`=LEFT(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1," ",""),"　",""),CHAR(160),""),5)`

名称を取り出す
~~`=MID(SUBSTITUTE(SUBSTITUTE(A1," ",""),"　",""),6,LEN(A1))`~~
`=MID(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A12," ",""),"　",""),CHAR(160),""),6,LEN(A12))`

#####2019/11/09 追記
ノーブレーキング・スペースなるものが含まれていてうまく置換されないことがあることを確認。
それを置換するため、CHAR(160)もnull置換するように修正。
参照：http://searched.jp/?eid=636

###仕組み
真ん中の部分で、半角・全角スペースをnull置換。
`ER123株式会社ER`
コードは左から5文字分なので、LEFT関数で取り出す。
名称は6文字目以降なので、MID関数で始点を6文字目、終点を十分に大きい数字に設定して取り出す。
十分に大きい数字は100でも1000でもいいのだが、「変換元の値の文字数」にしてみた。「変換元の値の文字数」＞「名称の文字数」なので。
reversing入門

せっかくreversingちょっとだけ解けるようになったので自分用メモとして書いておきます。

# reversingって？
渡された実行形式ファイルやバイナリファイルを解析してflagを入手するctfの問題のジャンルのこと。

# 覚えておきたいコマンドやツール
- stringsコマンド
- objdumpコマンド
- gdb
- IDA(デコンパイラ)
- dnSpy

このうち上3つはELFファイル(linuxの実行形式ファイル)で主に使う。下2つはPE(windowsの実行形式ファイル)で主に使う。

## stringsコマンド
言わずと知れた有名なコマンド。ファイルから文字列を取り出すことができる。これとgrepを組み合わせることでファイルから特定の文字列を検索することができる。

ex)strings a.out | grep -A 3 ctf{
//a.outから取り出した文字列のうち,ctf{を含む行とその後3行を表示する。

## objdumpコマンド
ファイルの情報を表示するコマンド。reversingでは主に-dオプションをつけて使う。
アセンブラがそのままだとAT&T記法で出力されるのでintel記法がいい人は-M intelをつけよう。

ex)objdump -d a.out -M intel
//a.outのアセンブラが出力される。

## gdb
プログラムを実際に動作させて解析するツール。

ex)gdb a.out //gdbを起動
set disassembly-flavor intel //(見づらい人は)アセンブラをAT&T記法からintel記法に変更する(デフォルトはAT&T記法)
b main //main関数のエントリーポイントにブレークポイントを貼る
r //プログラムをrun(実行)する。このあとmainのブレークポイントで一旦止まる。
b *0x8000602 //8000602番地にブレークポイントを貼る。*つけ忘れると変なとこに貼るので注意。
c //ブレークポイントまで処理を進める。
j *0x800060f //0x800060f番地の命令までjumpする。
i r //全てのレジスタの値を出力する。
x/s $rax //rax番地に格納された文字列を出力する。
x/5s *0x200000 //*0x200000~*0x200005番地に格納された文字列を出力する(?)

大体このくらい使えたらある程度のことはできるはず。

## IDA
僕はあんまり使ったことないけどデコンパイラとしてよく名前の上がる有名なやつ。
詳しくは[こちら](https://cyberforensic.focus-s.com/knowledge/articles_detail/573/)を参照。

## dnSpy
PEアプリケーションがデコンパイルできる。32bitか64bitかをあわせないとデコンパイルできないので注意。vscodeみたいなUIなので割とわかりやすいと思う。

# おわり
アセンブリが読みづらくて最初は混乱することも多いreversingだけど,低レイヤがわかるだけで重宝されるので,お手軽にハッカーみたいなことがしたい方はぜひチャレンジしてみてください。
AWS Lambdaでのコールドスタートのメモリの罠と、Invoke Lambdaでのタイムアウトの罠

# 問題の経緯
API Gateway経由、ALB経由でAPI化しているLambdaを構築していた。
ALB経由Lambdaの中には、VPCに含んでいるものもあった。
そのLambdaからは別のLambdaもいくつかInvokeしていた。
実装を一通り終わってテストしていると、どうもレスポンスが早いときと、遅いとき、酷いとタイムアウト（API Gatewayは30秒制約あるし。。）することがあった。

# 調査した結果
調査してみると、どうにもInvokeしている部分が怪しかった。
やっぱりVPC Lambdaだとコールドスタートのせいで遅いのかなぁと思いながらログから調査していった。
Invoke自体は実行されているが、何故かInvoke先のLambdaにログが来ていない。。。。
もしかして、コールドスタートから起き上がる前にタイムアウトしてる？？と思い、Lambda関連のドキュメントを漁りながら、やっぱりLambdaを定期実行して、コールドスタート回避するしかないのかなぁと思っていると下記の記事を発見。。。。
[VPC Lambdaのコールドスタートにお悩みの方へ捧ぐコールドスタート予防のハック Lambdaを定期実行するならメモリの割り当ては1600Mがオススメ？！](https://dev.classmethod.jp/cloud/aws/lambda-cold-start-avoid-hack/)

マジですか。。
Lambdaのメモリって単に必要分があれば良い程度にしか思ってませんでした。。
こんなことが出来るんですね。。。

ただ、上記設定してみても、それでも若干レスポンスに差がでる。
そこで、Invokeのタイムアウトについて調べると、以下の公式Docが。

[AWS SDK を使用して Lambda 関数を呼び出す際の再試行とタイムアウトの問題をトラブルシューティングする方法](https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-function-retry-timeout-sdk/)

なんと。。
私はNodeJSでSDKを使っていたのですが、デフォルトの接続タイムアウトはないと。。。
というか、接続でミスることあるのか。。。同じサービス(AWS)内じゃん。。。。何故。。。

とりあえず、下記のように設定したら、レスポンスは正常になりました。。
色々罠だった。。

```javascript:XXX.js
AWS.config.update({
  region: "ap-northeast-1",
  maxRetries: 2, // 最大再試行回数
  httpOptions: {
    timeout: 30000, // ソケットタイムアウト
    connectTimeout: 2000 // 接続タイムアウト
  }
});
```

# 結論
- LambdaをInvokeするときは必ず「最大再試行回数」「ソケットタイムアウト」「接続タイムアウト」を設定する
- Lambdaのメモリは多すぎず、少なすぎず、処理を必ず見てちょうど良いところで設定する（この時、Lambdaの実行時にENIもちゃんと見る）
[SerializeField]属性をプリプロセッサ（#if〜#endif）で括ったらどうなるのか

## 特に理由のない意地悪がUnity2019.2.2を襲う――！！

```c#
using UnityEngine;

public class IfDefIjiwaru : MonoBehaviour
{
#if PLATFORM_STANDALONE
    [SerializeField]
    private string Ijiwaru;
#endif
}
```

## 実験
まずは対象のプラットフォームで適当に値を入れてみます。
<img width="336" alt="スクリーンショット 2019-11-01 0.16.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/b8f406f7-772a-339a-bc44-e6846cac9ab4.png">
そしておもむろに対象プラットフォーム切り替え。
<img width="254" alt="スクリーンショット 2019-11-01 0.17.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/597b2872-53e0-f14d-fd38-3f25951c8e35.png">
フィールドが消えました。
<img width="336" alt="スクリーンショット 2019-11-01 0.16.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/a2240a7f-82a3-8791-5430-9af730b66055.png">
元のプラットフォームに戻すと、入力したはずの値が消えています。
<img width="339" alt="スクリーンショット 2019-11-01 0.21.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/c47f67b7-6b0e-e241-61a1-9e7e4ffbdce5.png">
ここで諦めてはいけません。
UnityのSceneファイルは`YAML`なので、[Sublime Text](https://www.sublimetext.com)などのテキストエディタで開けます。
見れば値そのものは残っている様子。
<img width="281" alt="スクリーンショット 2019-11-01 0.23.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/f2746b92-f89b-a1f4-8540-aa61b7d647a8.png">
ということで、シーンを一度閉じて読み込み直すとこのように値が復帰しました。
<img width="336" alt="スクリーンショット 2019-11-01 0.16.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146245/b8f406f7-772a-339a-bc44-e6846cac9ab4.png">

## まとめ
そうなんだ　そういうことも　あるんだね
Google検索オプション

#はじめに
　Google検索を使っているときに特定の言葉だけを検索したかったり、正確な検索をしたいと思う。そのときに役立つのが検索オプションだ。今回は自分用に検索オプションをメモしておく。

#Google検索オプションのメモ

* フレーズ検索（””）
* キーワードの除外（-）
* OR検索（OR）
* キーワードを本文にすべて含む（allintext:）
* 本文にあるキーワードを指定（intext:）
* タイトルを本文にすべて含む（allintitle:）
* タイトルにあるキーワードを指定（intitle:）
* 一部不明なフレーズの検索（＊）
* 関連サイトの検索（related:URL）
* まとめサイトやブログなど特定サイト内での検索（site:URL キーワード）
* ファイルを検索（filetype:拡張子）
* キーワードの類義語を含んだ検索（””~）
* 場所を指定した検索（near:）
* 地域を指定した検索（location:）
* 辞書（define:）
* 翻訳（translate to）

#簡単検索オプション
これらのサイトで簡単に検索オプションが使えます。

* [検索オプション](https://www.google.com/advanced_search)
* [画像の検索オプション](https://www.google.com/advanced_image_search)

#引用
* [必見！Google検索を効率的にする検索オプション13選](http://minto.tech/google-kensaku-option/)
* [Googleヘルプ 検索オプション](https://support.google.com/websearch/answer/35890?hl=ja)
Papaparseで、Excelで0落ちしないCSVファイルを作る方法

下記のようにCSVをExcelで読み込むと
電話番号の先頭の0が消えてしまいます。

```csv:元データ.csv
名前,電話番号
佐々木,08022222222
湯浅,08022222221
```

```csv:excelで読み込んだデータ.csv
名前,電話番号
佐々木,8022222222
湯浅,8022222221
```

## 解決策
区切り文字を`,=`にすれば、Excelでも先頭の0を表示することができるので
Papaparseで区切り文字を変更する方法を紹介します。

```
名前,=電話番号
佐々木,=08022222222
湯浅,=08022222221
```

ただし、ジェネリックではない~~Excelのクソ仕様です~~ので
**どうしても、ExcelでCSVを開きたい場合だけ使ってください。😇**


## 実装方法

unparseのオプションに`{ delimiter: ",=" }`を渡すだけです。

```javascript
  const data = Papa.unparse(json, { delimiter: ",=" })
```

### その他のオプション

その他のオプションは、公式のドキュメントからご確認ください。

[公式ドキュメント](https://www.papaparse.com/docs#json-to-csv)

## 注意点

papaparseのversion5以前は
delimiterに2文字以上の文字列を使えないのでご注意ください。
mac Git Github .DS_Storeを登録しないようにする

# 目的

- macで自動生成されるファイル.DS_Storeをgithubのリポジトリの管理から外す方法を記載する。
- 一回の設定で全てのリポジトリで.DS_Storeを管理から外す。

# 実施詳細

1. 下記コマンドを実行してHomeディレクトリに移動する。

    ```terminal
    $ cd
    ```

1. 下記コマンドを実行して.gitignore_globalファイルを作成する。

    ```terminal
    $ vi touch ~/.gitignore_global
    ```

1. 開いたtouch ~/.gitignore_globalファイルに下記の内容を記載して保存する。

    ```
    .DS_Store
    ```

1. 下記コマンドを実行して設定を反映させる

    ```
    $ git config --global core.excludesfile ~/.gitignore_global
    ```
Node.jsのCloud Tasksクライアントでタスク作成をリトライする

[Node.jsのCloud Tasksクライアント](https://github.com/googleapis/nodejs-tasks)を使っていると、たまにgRPCのエラーでタスクの作成に失敗することがありました。リトライのための設定がややわかりにくかったので、リトライする方法をまとめておきます。

## バージョン

- @google-cloud/tasks: 1.5.1
- google-gax: 1.7.5

## 設定方法

[ドキュメント](https://googleapis.dev/nodejs/tasks/latest/v2.CloudTasksClient.html#createTask)にあるように、 `CloudTasksClient.createTask()` の第2引数に [CallOptions](https://googleapis.github.io/gax-nodejs/interfaces/CallOptions.html) を渡すとリトライなどの設定を行えます。具体的な設定例は次の通りです。

```js
const client = new CloudTasksClient();

const request = {
  parent: client.queuePath(project, location, queue),
  task: {
    appEngineHttpRequest: {
      httpMethod: "POST",
      relativeUri: "/log_payload"
    }
  }
};

const options = {
  retry: {
    retryCodes: [
      13 // INTERNAL
    ], // リトライ対象のエラーコードを1つ以上指定する
    backoffSettings: {
      initialRetryDelayMillis: 100, // 最初のリトライ間隔（ミリ秒）
      retryDelayMultiplier: 1.3, // リトライ間隔の増加率
      maxRetryDelayMillis: 60000, // リトライ間隔の最大値
      initialRpcTimeoutMillis: 20000, // 最初のタイムアウト（ミリ秒）
      rpcTimeoutMultiplier: 1, // タイムアウトの増加率
      maxRpcTimeoutMillis: 20000, // タイムアウトの最大値
      totalTimeoutMillis: 600000 // 全体のタイムアウト（ミリ秒）
    }
  }
};

const [response] = await client.createTask(request, options);
```

`retry.retryCodes` に1つ以上のエラーコードを指定しないとリトライされません。エラーコードは実際にタスク作成に失敗したときの例外に `code` として含まれています。一覧は[google-gaxのソースコード](https://github.com/googleapis/gax-nodejs/blob/v1.7.5/src/status.ts#L38-L54)で確認できます。

`retry.backoffSettings` に書いているのは、`createTask()`の第2引数を指定しなかった場合に使われるデフォルト値です。ドキュメントに記載がなかったので、デバッグ実行して確認しました。このデフォルト値は[設定ファイル](https://github.com/googleapis/nodejs-tasks/blob/v1.5.1/src/v2/cloud_tasks_client_config.json#L13-L19)から生成されているようです。

## 終わりに

ちゃんとコードを読んだわけではないですが、タスクの作成は冪等な処理ではないので、安全側に倒して自動リトライしないのだと思われます。リトライする場合には、同じタスクが2個作られてしまっても問題ないような実装にするよう気をつけましょう。
Jetson nano memorandum

# Jetson nano memorandum

## Headless setup
悪魔に負けなかったのでJetson nanoを購入しました(2019.10.26)
Headless setupオタクなのでとりあえずやってみた
for Ubuntu 18.04.2LTS(2019.10.27)

### 必要なもの


| 項目 | 備考 | 
| -------- | -------- |
| Jetson nano     |      |
|電源アダプタ(5V4A推奨)|3Aでも行けた|
|ジャンパピン|j48をショートしDCプラグ電源を使用する|
|micro SD(32GB以上推奨)|のちのちを考えるとUHS-I U3 A2がよい|
|LAN環境(有線LAN xor wifiドングル)|RPiと異なりWiFiは付属しない|

### 実作業
1. [JetCardイメージ](https://drive.google.com/file/d/1wXD1CwtxiH5Mz4uSmIZ76fd78zDQltW_/view)をダウンロードする
1. コーヒーを入れる
2. マイクロSDカードの書き込み
    1. FAT32でSDカードの初期化を行う
    2. Etcherをインストールし,起動する
    3. ダウンロードした``jetcard_v0p0p0.zip``をイメージとして選び,SDカードに書き込む

3. Jetson nanoの配線作業
    1. J48をジャンパでショートする
    2. DCジャックにACアダプタを接続
    3. USBケーブルでPCと接続(これは有線LANを使用する際は必須ではない)

4. Jetson nanoへのssh
    1. Jetcardではデフォルトでsshサービスが起動している
    6. USB接続の場合:正常に動作していればネットワークアダプタとReadMeが含まれたディスクがPCにマウントされているはず.これはUSB Device Modeというものである.なおケーブルがデータ転送可能なものであるかをきちんと確認すること.
    7. USB接続の場合:`192.168.55.1`に対してsshで接続可能(user:`jetson`,pass:`jetson`)
    8. 有線sshの場合:ルーター設定みたり,ifconfigのぞいたりしてどうにかしてjetsonのipアドレスを特定してそこにsshする

1. (Wifiドングルを持っている場合)Wifi設定
    2. `lsusb`,`ifconfig`でwifiドングルを認識していることを確認
    3. `sudo nmcli device wifi rescan | sudo nmcli device wifi list`でSSIDの捜索
    4. `sudo nmcli device wifi connect <ssid> password <password>`で接続

1. ipの固定
    1. デバイス名(#NAME)の確認:``nmcli connection show``

    ```
    $ sudo nmcli connection mod "wired 1" \
    > ipv4.addresses "192.168.10.40/24" \
    > ipv4.gateway "192.168.10.1" \
    > ipv4.dns "192.168.10.1,8.8.8.8" \
    > ipv4.method "manual"
    ```
    2. ネットワークの再起動で確認

1. システムアップデート(いつもの)

```
sudo apt update
sudo apt upgrade
sudo apt dist-upgrade
sudo apt autoremove

sudo reboot
```
VBAでグラフの軸を1時間単位に設定

VBA グラフの軸を1時間単位に設定

```vb

Option Explicit

Sub set_x_axes()
    ActiveChart.Axes(xlCategory).Select

    ' 補助目盛りの幅を1分単位に設定
    ActiveChart.Axes(xlCategory).MinorUnit = 1 / 24 / 60

    ' 目盛りの幅を1時間単位に設定
    ActiveChart.Axes(xlCategory).MajorUnit = 1 / 24

　　' 横軸の最小値
'    ActiveChart.Axes(xlCategory).MinimumScale = 43737.0000115749
　　' 横軸の最大値
'    ActiveChart.Axes(xlCategory).MaximumScale = 43737.0416782438

    ' 目盛りラベルの角度を変更
    Selection.TickLabels.Orientation = 70

    ActiveChart.PlotArea.Select

End Sub
```
リソースの音声データを再生する

音声データを再生したいが、waveファイルやmp3ファイルを別ファイルで配布しないでリソースで同梱して扱いたい。というのを叶える方法を調べてみた。

+ 扱う音声データはwavとmp3（NAudioが扱えるものなら何でも良いはず）
+ wavはPlaySoundを使用し、mp3はNAudioを使用した

Visual Studio 2019を使っているが、昔のバージョンでもいけるはず。またusing変数宣言はC# 8.0の記法なので適宜置き換えて読んでほしい。
また、エラー処理や例外処理は端折っているので、適宜補うべし。


# ソリューション構成

C#のプロジェクトを作成し、あらかじめ音声データファイルをリソースに登録しておく。
wavの場合、リソースの種別は「オーディオ」となる。
mp3の場合、リソースの種別は「ファイル」となる。
これらは勝手に設定されて、変更できなさそう。（調査不足）

```
ソリューション
    |- SampleProj   ※C#プロジェクト名
        |- Properties
            |- aiueo.wav　※音声データ1
            |- dindon.mp3　※音声データ2
            |- Resources.resx
                |- Resources.Designer.cs
...
```

登録したリソースは、次のように自動的に実装が作られる。リソースの名前や定義に、拡張子は含まれないようだ。
これらのリソース定義を使用しても良いし、自分で```ResourceManager```を使って取得しても良い。リソース定義を使った場合は、wav（オーディオ）は```stream```で、mp3（ファイル）は```byte[]```で取得できる。
以下では、リソースを```string```等で選ぶことを考えて、自分で```ResourceManager```を使って取得する方法で記述している。

```c#:Resources.Designer.cs
namespace SampleProj.Properties {
    // ...省略...
    internal static System.IO.UnmanagedMemoryStream aiueo {
        get {
            return ResourceManager.GetStream("aiueo", resourceCulture);
        }
    }

    internal static byte[] dindon {
        get {
            object obj = ResourceManager.GetObject("dindon", resourceCulture);
            return ((byte[])(obj));
        }
    }
}
```

# PlaySoundによるwavの再生

winmm.dllからPlaySoundをインポートする。
引数で渡す予定のFlagも、別途```enum```で定義しておく。

```c#
[DllImport("winmm.dll", CharSet = CharSet.Auto)]
private static extern bool PlaySound(byte[] sound, IntPtr hMod, PlaySoundFlags flags);

[System.Flags]
public enum PlaySoundFlags : int
{
    SND_MEMORY = 0x0004,  // メモリの再生の意
}
```

再生はPlaySoundにbyte配列を渡すことで行える。
オーディオリソースはstreamなので、いったん別のbyte配列に読み込む。

```c#
using var target = SampleProj.Properties.Resources.ResourceManager.GetStream("aiueo");
byte[] buffer = new byte[target.Length];
target.Read(buffer, 0, buffer.Length);
target.Close();
// 再生
_ = PlaySound(buffer, IntPtr.Zero, PlaySoundFlags.SND_MEMORY);
```

停止も同じAPIで、第一引数を```null```に、第三引数を0にする。これ以上のPlaySoundの利用方法は省略。

```c#
// 停止
_ = PlaySound(null, IntPtr.Zero, 0);
```

# NAudioによるmp3の再生

NAudioは次で配布されているMs-PLライセンスの、.NET向け音声再生APIである。dll一つで扱える簡単さでありながら様々な音声形式に対応する。wav形式も対応しているので、PlaySoundではなくNAudioを使うこともできる。
https://github.com/naudio/NAudio

再生は、NAudioのAPIである```Mp3FileReader```に```MemoryStream```を渡すことで行う。
再生状態は```WaveOut.PlaybackState```で判別できる。これをnowaitでポーリングすると音声再生が乱れたのでwaitを入れている。多分ちゃんと調べる方法はある。（調査不足）

```c#
// WaveOutのインスタンスはクラスフィールドで持つなりする。
var player = new NAudio.Wave.WaveOut();  // 要Dispose

// リソースからデータの取得
byte[] buffer = (byte[])Properties.Resources.ResourceManager.GetObject("dindon");
using var stream = new MemoryStream(buffer)
{
    Position = 0  // 先頭位置からの再生を意味するが、streamを新規にnewするときは不要なはず
};
using WaveStream pcm = new Mp3FileReader(stream);
player.Init(pcm);
// 再生
player.Play();

// 待ち（ここ調査不足）
while (player.PlaybackState == PlaybackState.Playing)
{
    await Task.Delay(10);
}

```

停止は```WaveOut.Stop()```で行える。

```c#
// 停止
player.Stop();
```

# まとめ

exe単体ないしはdllの同梱のみで、音声データを再生する方法を調べた。
とにかく再生できれば良かったので、再生中かどうかを考慮したり音声デバイスを選んだりなどは本記事では省略している。

+ リソースで埋め込んだwave形式とmp3形式のデータを再生する
+ PlaySoundとNAudioの2つの方法で再生する
今噂のJuliaをUbuntuにインストールしてJupyter Notebookで使おう！

# 1. Juliaって何？
## 1.1 読み方
**長文です。読み飛ばして問題ありません。**
Juliaは「ジュリア」と読みます。Juliaは元来、女性の名前です。

ちなみに、Juliaに対応する男性の名前があります。Julianといいます。
わかりやすく言うと、Julian⇒太郎、Julia→花子みたいな感じですね。
ちなみに、（国の）言語によって読み方も違います。

|性別|アルファベット表記|英語      |ドイツ語|スペイン語|
|-----|---------------|---------|--------|--------|
|男性  |Julian         |ジュリアン|ユリアン  |フリアン |
|女性  |Julia          |ジュリア  |ユリア   |フリア   |

余談ですが... Google検索するときは気をつけましょう。
`julialang` で検索するのが無難です。
「わぉ♡」な女性が検索結果に表示されることがあります。笑

## 1.2 特徴
【[Julia 公式ページ](https://julialang.org/)】
Juliaは数値計算やデータサイエンスに強い言語です。
さらに、コンパイル言語なのでC並に高速で、Python並みに書きやすいことを特徴に掲げています。
また、動的プログラミング言語なので変数宣言の時に型の指定が必要ありません。

<div style="float: left;">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201801/a41177d7-2f7a-f668-6113-04897aea3d61.gif" width="45%">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201801/fabee2da-1322-4c34-9f91-6ee1a9811dd9.gif" width="45%">
</div>


## 1.3 歴史

MIT(マサチューセッツ工科大学)のAlan Edelman教授と彼の同僚が開発を始めました。

- `2009年` 開発がスタート
- `2012年` OSSとして公開
- `2014年` 初のJuliaConが開催！
- `2018年` Version 1.0.0が公開


# 2. 本題: Ubuntu 18.04で試してみよう！

## 2.1 インストールする環境

```terminal:terminal
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.3 LTS
Release:	　  18.04
Codename:	　　 bionic
```

## 2.2 Ubuntuにインストールする

前提が長くなりましたが、本題のインストールをやっていきましょう！

2019年10月31日現時点で、Juliaの最新バージョンは `1.2.0` ですが、安定版は `1.0.4` となっています。どちらをインストールしたいかで、インストール方法は異なります。

### Julia 1.2.0

一時的に、 `~/Downloads` にJuliaの実行ファイルをダウンロードします。
その後、 `/opt` に移動しシンボリックリンクで `julia` コマンドを有効にしていきます。

`https://~` の部分は、[公式のDownloadページ](https://julialang.org/downloads/)からリンクを持ってきて下さい。（赤枠部分）

<img width="1165" alt="Screen Shot 2019-10-31 at 22.41.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201801/6d9e4112-da94-0c79-6665-24f35fa581eb.png">


```terminal:terminal
cd ~/Downloads

wget -qO- https://julialang-s3.julialang.org/bin/linux/x64/1.2/julia-1.2.0-linux-x86_64.tar.gz | tar -xzv

sudo mv ~/Downloads/julia-1.2.0 /opt/

sudo ln -s /opt/julia-1.2.0/julia /usr/local/bin/julia
```

### Julia 1.0.4

[公式ドキュメント](https://snapcraft.io/install/julia/ubuntu)に沿ってインストールしていきましょう。
`--classic` が無いとエラーが出ます。

```terminal:terminal
sudo snap install julia --classic
```


# 3. JuliaをJupyterで使えるようにする

前提として、Jupyter Notebookの設定は完了しているものとします。
terminalで `$ julia` とコマンドを打ちます。

```terminal:terminal
$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.2.0 (2019-08-20)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> using Pkg

julia> Pkg.add("IJulia")
```

これで、Jupyter NotebookでJuliaが選択できるようになります。

<img width="1179" alt="Screen Shot 2019-10-31 at 23.30.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201801/d667c7d0-f6ef-704d-3267-024caa8cbc92.png">

# 4. 最後に

Juliaはコンパイル言語で数学や科学計算に強いので、AIの分野で今後発展していくと個人的に考えています。アーリーアダプターとして、Juliaにコミットしていくべく、今後もJuliaに関する情報を発信していきたいと思います。
Ubuntu 18.04 @ WSL にて Caffe 環境をビルド

Ubuntu 18.04 では ```sudo apt install caffe-cpu``` で導入できますが, チュートリアルを実行したいためにコードのビルドから実行

# 実行環境

- Windows 10 (1903)
- Ubuntu 18.4 on WSL
- No CUDA環境

# 環境構築

[Caffe](http://caffe.berkeleyvision.org)の各種情報を参考に環境構築
- [Installation](http://caffe.berkeleyvision.org/installation.html)
- [Ubuntu Installation](http://caffe.berkeleyvision.org/install_apt.html)

0. 必要なツールのインストール
Tutorialの環境のビルドのため```sudo apt install caffe-cpu```ではなくてmakeできる環境を準備します. 
http://caffe.berkeleyvision.org/install_apt.html を参考に

```bash
sudo apt-get install \
  libprotobuf-dev \
  libleveldb-dev \
  libsnappy-dev \
  libopencv-dev \
  libhdf5-serial-dev \
  protobuf-compiler \
  libgflags-dev \
  libgoogle-glog-dev \
  libatlas-base-dev \
  liblmdb-dev \
  libboost-all-dev \
  -y
```

0. caffeのビルド

```bash
git clone https://github.com/BVLC/caffe.git
cd ./caffe
cp -a Makefile.config.example Makefile.config
```

Makefile.configの修正内容 (```diff Makefile.config.example Makefile.config```)

```diff
8c8
< # CPU_ONLY := 1
---
> CPU_ONLY := 1
97,98c97,98
< INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include
< LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib
---
> INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
> LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/hdf5/serial
```
- 
```makefile
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include
```

```bash
make all
```

cv::imreadがないと怒られる...

```bash
CXX/LD -o .build_release/tools/caffe.bin
.build_release/lib/libcaffe.so: undefined reference to `cv::imread(cv::String const&, int)'
.build_release/lib/libcaffe.so: undefined reference to `cv::imencode(cv::String const&, cv::_InputArray const&, std::vector<unsigned char, std::allocator<unsigned char> >&, std::vector<int, std::allocator<int> > const&)'
.build_release/lib/libcaffe.so: undefined reference to `cv::imdecode(cv::_InputArray const&, int)'
collect2: error: ld returned 1 exit status
Makefile:635: recipe for target '.build_release/tools/caffe.bin' failed
make: *** [.build_release/tools/caffe.bin] Error 1
```

```USE_PKG_CONFIG=1``` を追加して再度makeしたら通った. 

```bash
make USE_PKG_CONFIG=1 all test runtest
...
[==========] 1162 tests from 152 test cases ran. (43754 ms total)
[  PASSED  ] 1162 tests.
```
Kotlinでフィボナッチ数列とfizzbuzzを書いてみた

# フィボナッチ数

```kotlin:
fun fib(n: Int): Int {
    return if (n < 2) n else fib(n -2) + fib(n-1)
}


fun main(args: Array<String>) {
    for (i in 0..10) {
        println(fib(i))
    }
}
```

実行結果

```shell-session
$ kotlinc fib.kt -include-runtime -d fib.jar
$ kotlin fib.jar
0
1
1
2
3
5
8
13
21
34
55
```

# FizzBuzz

```kotlin:

fun fizzbuzz() {
    for (i in 1..30) {
        when {
            (i % 15 == 0) -> println("FizzBuzz")
            (i % 3 == 0) -> println("Fizz")
            (i % 5 == 0) -> println("Buzz")
            else  -> println(i)
        }
    }
}

fun main(args: Array<String>) {
   fizzbuzz()
}
```

実行結果

```shell-session
$ kotlinc fizzbuzz.kt -include-runtime -d fizzbuzz.jar
$ kotlin fizzbuzz.jar
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
```
年末まで毎日webサイトを作り続ける大学生 〜13日目 try...catch...finallyに触れる〜

##はじめに
初めまして。
年末まで毎日webサイトを作っている者です。
今日もMDNを見て勉強していたんですが、中級編をやる前に見落としていたページがありました。
try...catch...finallyです。エラーを拾ってくれるのはわかったんですが、使い分けがいまいち分かっていません。果たしてtry文は乱用していいものなのか・・・？
扱う技術レベルは低いですが、同じように悩んでる初心者の方を勇気付けられれば幸いです。
今日は13日目。(2019/10/31)
よろしくお願いします。


##サイトURL
- https://sin2cos21.github.io/day13.html


##やったこと
冒頭にある通りtry...catch...finallyを触ってみました。
エラーを出すためにわざと宣言していない変数「random2」をthrowに投げています↓

```html
<input type="text" id="checkData2" placeholder="半角数字のみ入力可">
    <input type="button" id="checkButton2" value="送信"><br>
    <p id="output"></p>
```

```javascript
document.getElementById('checkButton2').addEventListener('click', function () {
            try {
                alert('tryです');
                let checkNumber2 = document.getElementById('checkData2');
                let random = Math.floor(checkNumber2) * 100;
                throw random2;
            } catch (e) {
                document.getElementById('output').textContent = ('例外: ' + e);
            } finally {
                document.getElementById('output').innerHTML += '<br>finallyです。使ってくれてありがとう！';
            }
        });
```
finallyはエラーがあろうとなかろうと表示されます。便利ですなぁ〜

##おまけ
入力した文字がちょうど3文字じゃないといけない入力欄も作りました。
ここ最近似たようなメソッドを多用していますが、そろそろオブジェクトをマスターしてもうちょっとアプリっぽくしたいな。

```html
 <input type="text" id="checkData" placeholder="3文字のみ入力可">
    <input type="button" id="checkButton" value="送信"><br>
```

そうです。lengthが活躍してくれました。そして関数は一つにまとめず機能は分離することを心がけました(clearnDataのこと)↓

```javascript

document.getElementById('checkButton').addEventListener('click', checkData);

        function checkData() {
            let checkNumber = document.getElementById('checkData');
            if (checkNumber.value.length !== 3) {
                alert('入力は3文字まで!');
                clearnData(checkNumber);
                checkNumber.focus();
            } else {
                alert(checkData.value + 'は3文字だね。いい感じ！');
                clearnData(checkNumber);
            }
        }

        function clearnData(checkNumber) {
            checkNumber.value = '';
        }

```

try...とおまけのgifです ↓
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/fe9358f9-adc4-44a3-f8d8-2a4746f16620.gif)

##感想
今日はオブジェクトもちらっと勉強したんですが強敵ですね・・・。ただ、関数あるのになんでオブジェクト使うの？という疑問は解消されました。
-  オブジェクト → 値を収める名前付きコンテナ
- 関数 → アプリケーションを実行可能にする手続き
我らがMDNのおかげでやっと関数が理解できた気がします。MDNありがとう・・・！

最後まで読んでいただきありがとうございます。
明日も投稿しますのでよろしくお願いします！

##参考
1. 制御フローとエラー処理 - JavaScript | MDN (https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling)

とても勉強になります。MDNさんありがとうございます！
Sipeed Maix M1 DockのカメラをOV2640からOV7740に変更してみる

Sipeed Maix M1 DockにはデフォルトでOV2640というカメラがついています。

OV7740(互換のHDF7740ですが…)を入手しましたので、カメラモジュールを入れ替えてみました。

#入れ替える前の準備：Firmwareのアップデート
OV7740を使うには、Firmwareをv0.4.0に入れ替える必要があります。

Firmwareを

　[ここ](https://github.com/sipeed/MaixPy/releases/download/v0.4.0/maixpy_v0.4.0_50_gcafae9d.bin)

からダウンロードして焼きましょう。

焼く環境については、@uzuki_aoba さんの

　[MaixPy/MF1/M5StickVのFirmware downloadツールについて]
(https://qiita.com/uzuki_aoba/items/e19dc092680d28a99560)

をご参照ください。
いろいろ検証してくださってます。

#カメラを入れ替える
OV2640を外してOV7740を付けるだけです。
入手したカメラのケーブル部分が長くてこんな感じになっちゃいました。

![IMG_0371.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129938/cd928247-8853-d94f-0abf-b7f2bf82a255.jpeg)

#find_face.pyにfps表示を仕込む
find_face.pyにfps表示を仕込みます。
あってるのかどうかはわからないけど…ｗ

```py
import sensor
import image
import lcd
import KPU as kpu
import time

clock = time.clock()
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
sensor.skip_frames(30)
task = kpu.load(0x300000) # you need put model(face.kfpkg) in flash at address 0x300000
# task = kpu.load("/sd/face.kmodel")
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
while(True):
    clock.tick()
    img = sensor.snapshot()
    fps = clock.fps()
    img.draw_string(2,2, ("%2.1ffps" %(fps)), color=(128,0,0), scale=2)
    code = kpu.run_yolo2(task, img)
    if code:
        for i in code:
            print(i)
            a = img.draw_rectangle(i.rect())
    a = lcd.display(img)
a = kpu.deinit(task)
```

上記をboot.pyとしてmicroSDカードに保存してMaix M1 Dockに挿しておくと楽ですね。

#動かしてみる
まずはデフォルトのOV2640
![IMG_0365.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129938/ecfed15a-a4da-4986-fe96-5fb7f92f137f.jpeg)

35fpsくらいでした。

次にOV7740に変更
![IMG_0370.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129938/83a8c3de-f3fb-06a1-a1c4-351686164b9e.jpeg)

40〜50台fpsくらいでした。
ちょっと速くなりました。
FlutterでFloatingActionButtonを上にあげたときのメモ

# FloatingActionButtonを上にあげたかった

Flutterを勉強中です。

<img width="449" alt="スクリーンショット 2019-10-31 23.22.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109158/7b7bf89d-0d8e-9ff6-661a-d6d01ef74b6c.png">

ScaffoldのfloatingActionButton:に、ただFloatingActionButtonを設置してしまうと、
上の画面のように広告バナーを置きたい時にボタンが重なってしまいます。
これを回避する為にPaddingをつけてFloatingActionButtonをchildにしました。

```dart
floatingActionButton: Padding(
  padding: const EdgeInsets.only(bottom: 50.0),
  child: FloatingActionButton(
    child: const Icon(Icons.add),
    onPressed: () {
      Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) {
                return BlocProvider<ScoreBloc>(
                  creator: (_context, _bag) => ScoreBloc(),
                  child: ScoreScene(),
                );
              },
              fullscreenDialog: true));
    },
  ),
),
```

padding:にEdgeInsets.only(bottom: 50.0),を書いてbottomから好きな位置までボタンが
あがるように数値を設定します。

<img width="448" alt="スクリーンショット 2019-10-31 23.35.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109158/a666e8ca-ad2b-fdad-2253-ab5e0edf4805.png">

ボタンが上にずれてバナーを邪魔しないようになりました。
Bulmaで画面いっぱいにLeafletの地図を表示

# `is-fullheight`の`Hero`を使う

[Hero](https://bulma.io/documentation/layout/hero/)

## HTML

`hero`クラスを持つ`section`を作成します。idは`map`にしました

```html
<section id="map" class="hero is-fullheight">
</section>
```

## JS



```js
var map = L.map('map').setView([51.505, -0.09], 13);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

L.marker([51.5, -0.09]).addTo(map)
    .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
    .openPopup();
```

![Screenshot from 2019-10-31 23-19-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79562/bc27a5f0-7054-1f70-15a0-16c52d8842c7.png)
毎日ブログ4日目

さて、ただ今の時刻は22:50

今日やったことは
「東京フリーランスさんの30daysトライアルのResponsive Bootstrap Website Start To Finish with Bootstrap 4, HTML5 & CSS3という海外のYouTuberが挙げているBootstrap 4のコーディング動画です。」
昨日のTo Do Listとは全然違う内容ですみません。いろいろブログとかで分析してみたんですけど、東京フリーランスさんのブログを主に参考にしていくことに決めました。なので、今回は海外の動画に取り組みました。

しかし、初めの段階で問題に直面しました。それは、その人の概要欄からファイルをダウンロードしたんですけど、Windowsの方では完成版が文字化けみたいな感じで見当たりませんでした。

まぁとりあえずやってみるかと思い始めました。



「全然わからん」英語は聞き取れないし、書いているコードもよく分かりませんでした。
とりあえず、わかんない箇所はメモし進めることにしました。

考えながらとくり組んだんですけど、ほとんどが写経で終わりました。
写経って本当に意味ないことだと認識していて、歴史の教科書一言一句書き移すと同じように意味ないと認識しています。
本当に時間の無駄。

なぜ、そのように認識しながらも取り組んだのは、全体像を把握するためです、一度やっておけば次の時には、前回より早く理解できるからです。

待てよ、プログラミングってカンニングし放題だから、写経って意味なくないかも。

多分写経は考えながらやり、それを復習すればとてもいいことに感じてきました。

結論、写経は有効。

・学んだこと
navbar-light、navbar-brandなどの右側は色みたいですね。これはドットインストールでやりましたね。

btn-outline-secondaryこれの右側が何かと思ったんでっすけど、色なんですよね。

data-ride="carousel"　そもそもcarouselとはなんじゃと思いました。調べてみると読み方は、カルーセルというらしいです。確かに言われてみれば読めるｗｗ

.carousel, .slide でカルーセル全体を、.carousel-inner でカルーセルの内部コンテンツセットを、.carousel-item で個々のコンテンツアイテムを示すみいたい。data-ride="carousel" を指定すると画面を読み込んだ時点でスライドを開始するみたい。デフォルトで 5秒毎にスライドするらしい。マウスを乗せている時はスライドしないと調べたら出てきました。

fixed-wrap　そもそもwrapという単語を知りませんでした。これは折り返すという意味みたいです。nowrapeだと一行に収めようとするのに対して、一行に収めない感じかな。これは調べてもよく分かりませんでした。

img-fluid　imgタグに .img-fluid を入れるとBootstrapの画像は、.img-fluid でレスポンシブになるみたいです。


これらが分かりませんでした。他にもあったと思いますが、忘れました。

反省点　
cssもあるんですけど、cssがどこに対応するのか確認せず脳死写経してました。情けない。一時間で終わりだと思いきや、cssがあるとは予測ができませんでした。本当にその30分間はだらけましたね。30分が1時間に感じるくらい進みが遅くてつらかった。

明日のTo Do List はもう一つの海外の動画をやります。そっちでは反省点を生かして、脳死写経は辞めます。

本当は模写したいんですけどね。アウトプットしないと本当に力になっている気がしませんね。

憧れているWebコーディングの人がいるので、その人に追いつくためにここら辺はパパっと終わらしたいんですけど、簡単にはいきませんね。

今日はもう眠いので、おやすみなさい！　明日も頑張りましょう！！

23:34
Eclipse MicroProfile Healthに触れ合う

# はじめに
今回は、前に[Eclipse MicroProfile](https://qiita.com/omix222/items/50804e30e43085ceb912)とはで概要を紹介したEclipse MicroProfile Healthを試してみたいと思います。

# 始め方
今回も、前に[Eclipse MicroProfileの始め方](https://qiita.com/omix222/items/923d788d6ce76e179d6a)で紹介した、
[MicroProfile Starter](https://start.microprofile.io/)を使っていきます。

<img width="1035" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/6eebf624-e98f-63c0-049d-0ed6620906d9.png">

こちらの設定でプロジェクトを作成、ダウンロードします。

ファイル構成は以下のようになっています。

<img width="430" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/ec357100-5a99-69c4-d16a-5e403087dd70.png">

ビルド、アプリ起動しlocalhost:8080へアクセスすると以下のようなTop画面が用意されています。

<img width="392" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/f71f1b4d-13ff-d0aa-3d66-08b02261fa8e.png">

Health status (with custom status ServiceHealthCheck) にアクセスすると以下が表示されます。

<img width="957" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/c628c29c-588d-3a66-ff04-8a45e499481c.png">

このままだと見にくいので、Firefoxで開きます。

<img width="328" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/ce17a17a-3123-97d5-83de-85cc64c163f8.png">

ヘルスチェック結果が応答できてますね！

## 実装の解説

```ServiceHealthCheck.java
import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

import javax.enterprise.context.ApplicationScoped;

// ヘルスチェックを行うことを示すアノテーションだが、最新バージョンでは非推奨となっている。このアノテーションをつける必要がなくなったもの
@Health
@ApplicationScoped
// HealthCheckを実装することにより、チェック項目と応答内容を定義することができる
public class ServiceHealthCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
// ServiceHealthCheckというヘルスチェック項目でUpとなっていることを応答する
        return HealthCheckResponse.named(ServiceHealthCheck.class.getSimpleName()).up().build();

    }
}

```

ここで、先ほどの応答内容のJsonを見ると、

- ServiceHealthCheck
- deadlock
- diskSpace
- heapMemory

の４つの項目が返却されています。ServiceHealthCheckについては上記で実装されたものとなりますが、それ以外の３つについては、実装されてませんので、予めHelidon側で用意されたヘルスチェック項目である、と言えます。

## チェックの種類
仕様としては、今回紹介した`@Health`以外にも以下が仕様として定義されています。

- Readiness チェックとして定義する`@Readiness`
    - アプリケーションがリクエストを処理する準備ができているかを確認する
- Liveness チェックとして定義する `@Liveness` 
    - アプリケーションが実行されているかどうかを判断する。これがDownを返却する場合、アプリケーションを破棄（終了、シャットダウン）できることを意味します

# まとめ

今回はミニマム構成での説明に止まりましたが、利用開始にあたっての容易さは理解できたのではないでしょうか？
次回はまた別の仕様を試してみたいと思います

## 参考リンク

- 公式ドキュメント

[MicroProfile Health](https://microprofile.io/project/eclipse/microprofile-health)
ant+をraspberry piで使う（node.js）

# ラズパイでant+を使います
参考
https://www.johannesbader.ch/2014/06/track-your-heartrate-on-raspberry-pi-with-ant/

#### 仕様物
- [AZ4U](https://www.amazon.co.jp/AZ4U-USB%E3%83%89%E3%83%B3%E3%82%B0%E3%83%AB-GARMIN%E4%BA%92%E6%8F%9B-ZWIFT-1%E5%B9%B4%E4%BF%9D%E8%A8%BC%E4%BB%98%E3%81%8D%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC%E6%AD%A3%E8%A6%8F%E5%93%81/dp/B07FZHFLD6/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=az4u&psc=1&qid=1572531900&s=amazon-devices&sr=8-1)
- [ForeAthlete 235J](https://www.amazon.co.jp/dp/B01E88SCV8/ref=emc_b_5_t)

## raspberry pi AZ4Uを扱う

```
sudo apt-get install -y libusb-1.0-0-dev libudev-dev
```

`/etc/udev/rules.d/garmin-ant2.rules` を新規追加

```rules:/etc/udev/rules.d/garmin-ant2.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1008", RUN+="/sbin/modprobe usbserial vendor=0x0fcf product=0x1008", MODE="0666", OWNER="pi", GROUP="root"
```

## nodejsのインストール

```
sudo apt install -y nodejs npm
sudo npm install n -g
sudo n stable
sudo apt remove --purge nodejs npm
```

## 適当にプログラムをかく

### set up

```
mkdir -p ~/project/ant
cd ~/project/ant
npm init
npm install ant-plus
```

## example
`index.js`に書く

```javascript:index.js
const Ant = require("ant-plus");
const stick = new Ant.GarminStick2();
const sensor = new Ant.HeartRateSensor(stick);
let count = 0;

sensor.on("hbData", function(data) {
  count += 1;
  console.log(count, data.DeviceID, data.ComputedHeartRate);
});

stick.on("startup", function() {
  console.log("on start up");
  sensor.attach(0, 0);
});
async function main() {
  if (!stick.open()) {
    console.log("Stick not found!");
    return;
  }
}
main();
```

## start
```
node index.js
```
ABC144 参加記録

公式の解説を見る前に記述しています。

## 先に補足
自作のテンプレートを更新したので載せておきます

```c++:my_template
#include <bits/stdc++.h>

#define INF 2e9

#define REP(i,n) for(int i = 0; i < n;++i)
#define REPA(i,a,n) for(int i = a; i < n; ++i)
#define REPR(i,a) for(int i = a; i >= 0; --i)
#define ALL(a) a.begin(), a.end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector< vector<int> > vvi;

int gcd(int a, int b){ return b ? gcd(b, a % b) : a; }
template<typename A> void psn(A a){ cout << a << endl; }
template<typename A, typename... B> void psn(A a, B... b){ cout << a << ' '; psn(b...); }

int main(void) {

    return 0;
}
```
psnは"print space ¥n"
ようはスペース区切り行末改行の略です。 


# AtCoder Beginner Contest 144
## A - 9x9
[問題](https://atcoder.jp/contests/abc144/tasks/abc144_a)

```c++:9x9.cpp
int main(void) {

    int A, B;

    cin >> A >> B;

    if(A < 10 && B < 10) psn(A * B);
    else psn(-1);

    return 0;
}
```
ABが１０以下の数字ならそのまま掛け算し、それ以外なら−１の分岐をすれば良い

## B - 81
[問題](https://atcoder.jp/contests/abc144/tasks/abc144_b)

```c++:81.cpp
int main() {

    int N;

    cin >> N;

    REP(i, 9){
        REPA(j, i, 9){
            if((i + 1) * (j + 1) == N) {
                psn("Yes");
                return 0;
            }
        }
    }

    psn("No");

    return 0;
}
```
九九に出てくる数字を全部出して与えられた数と同じ数があるかを調べる。
うまいやり方がないか少しだけ悩んだけど全探索で間に合うなら全探索すればいいやって感じ

## C - Walk on Multiplication Table
[問題](https://atcoder.jp/contests/abc144/tasks/abc144_c)

```c++:WalkonMultiplication.cpp
int main() {

    ll N, min = 1000000000001;

    cin >> N;

    double times = sqrt(N);

    for(ll i = 1; i < 1000001; i++){
        if(N % i == 0){
            if(min > i + (ll)(N / i) - 2){
                min = i + (ll)(N / i) - 2;
            }
        }
    }

    psn(min);

    return 0;
}
```
合成数Nは√N以下の約数を必ず持つので、
√N以下の値で全て割ってみて割り切れたマスの座標の中で一番近い場所の座標を調べる
一番近いかどうか=(a, b)のマスに到達するのにかかる歩数=(a-1)+(b-1)回で比較
計算量は_O(√N)_で最大10^6くらいなのでまあ間に合う

## D - Water Bottle
[問題](https://atcoder.jp/contests/abc144/tasks/abc144_d)
普通の数学の問題を出すな。俺は数学ができない。

```c++:WaterBottle.cpp
int main() {

    int a, b, x;

    cin >> a >> b >> x;

    double h = x / (a * a); // 水が溜まっている高さ
    double r = 45.0;

    double beta;

    if(b / 2 >= h){ // 半分か少ない
        beta = (b * 2) - (h * 2); // 現在の高さが半分の筒に延長する
    }

    double l = (x * 2) / sqrt(a * a + b * b);
    double t = sqrt(l * l - beta * beta);
    double cosl = (t * t + beta * beta - l * l) / (2 * l * t);

    psn(l, t, beta, cosl); // デバッグ文
    // 解けませんでした

    return 0;
}
```
水面が常に平行なことと入っている水の量は変わらないので体積は変わらないことから溢れる瞬間の注ぎ口(?)の高さを計算し求めたい角度を含む三角形の辺の長さが全てわかるので三角比が求まりあとは二分法でその三角比になる各θを求めればOK水が半分以下の時はその高さが筒の真ん中になるように筒を延長して...

とか必死に図に書いたメモを失くしたので現場からは以上です。