OmniAICreator/Qiita-1.07M huggingface dataset:
iPhoneの通信速度をXcodeから一時的に変更する方法

デバッグの際などにiPhoneの通信速度を変更したい場合、iPhoneの設定アプリにあるNetwork Link Conditionerを使用することがあると思います。
これはとても便利なのですが、使用中においてそれを表す表示がないこともあり、切り忘れることがよくありました。

そこで、Xcode11かつiOS13からはiPhoneのNetwork Link Conditionerを切り忘れることがないように、通信速度を変更できる方法が提供されているので紹介します。

iPhoneをMacに接続しXcodeを開き、Xcode > Window > Devices and Simulatorsを選択します。
開いたウィンドウ内にDEVICE CONDITIONSというセクションがあり、そこでConditionをNetwork Linkにすることによって、通信速度を変更することができます。
<img width="906" alt="スクリーンショット 2020-07-21 17.49.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151036/d5f3d749-7cb7-7c73-5f12-7fad8513b441.png">


ここで通信速度を変更すると、Mac上でシミュレートの開始と停止ができます。
通信速度のシミュレート中はiPhoneのステータスバーが一部グレーに変更されます。そのグレーの部分をタップすると選択中のProfileが表示され、停止することができます。またiPhoneとMacの接続を切っても同様に、通信速度のシミュレートは停止されます。
![IMG_5240.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151036/911d4382-2103-dfc0-0c32-6db13973f56a.png)
![IMG_5241.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151036/4f0adfab-b7fa-7484-4d87-0b1eff1353a2.png)

以上です。この方法を使うと通信速度の変更を戻し忘れることがなくなると思います。ぜひ試してみてください。
【vue】 あまり使わないと思うが、postscribeを使ってtemplateタグ内部にscriptタグを埋め込む

# はじめに

あまり使うことはないかもしれないが、vueのtemplateタグ内部にscriptを埋め込んで、src内部を実行させて結果をもらうということをしたいときに、困ったときのメモ。

通常、vueのtemplateタグにscriptを埋め込むとエラーとなり実行をしてくれない。
そこで、何とかしてscriptを埋め込む方法&ライブラリはないかと探っていたら、「postscribe」なるものがあることがわかった。

# 結論

まずは、インストール

```
npm i --save postscribe
```

次に読み込みと実行

```vue
<template>
    <div id="main">
        <div id="data-script"></div>
    </div>
</template>
<script>
import postscribe from 'postscribe'

export default {
    methods: {
        dataInfo: function(){
            postscribe('#data-script', `<script src="http://hogehoge.com"><\/script>`, {
                done: function() {
                    console.info('Dblclick script has been delivered.');
                }
            })
        }
    }
}
</script>
```

# 参考

https://www.npmjs.com/package/postscribe
error TS1192: Module '"fs"' has no default export.

モジュール '"fs"' に既定エクスポートがありません
error TS1192: Module '"fs"' has no default export.

のようなエラーが出た時の対処法メモ

## はじめに
これはnode.jsのデフォルトモジュールの`fs`が原因で起こるエラーでは有りません。
TypeScriptの仕様によるものです。
tsconfig.jsonのオプションでこのエラーを解決する方法があります。

## 結論

`tsconfig.json`に`"allowSyntheticDefaultImports": true`を追記する

```json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true
  }
}
```
または

```js
// error TS1192: Module '"fs"' has no default export.
import fs from 'fs'

// no error
import * as fs from 'fs'
```

## 解説（tsconfigのオプション追加は省略）
TypeScriptでES6のデフォルト構文を使うとエラーでコンパイルエラーが起きます。

そういう時は下記の様な構文で指定ファイルの全てをインポートしてあげましょう。

```js
import * as fs from 'fs'
```

### エラーが出ないもの

また、下記の様に個別に`export`されたものをimportする場合はエラーが出ません。

```js
// hogeModuleファイル
export const hoge = () => {}
```

```js
import { hoge } from 'hogeModule'
```

上記と同様に`export default`が指定されているものもエラーになりません。

```js
// hogeModule
export default class hoge {}
```

```js
import hoge from 'hogeModule'
```

## 記事のもと
https://github.com/microsoft/TypeScript/issues/3337
https://qiita.com/bouzuya/items/edf5274241b50f32c621
https://qiita.com/alfas/items/539ade65926deb530e0e
Swift歴半年、初めてのアプリ公開までの道のり

#はじめに
タイトルの通りです。少し大袈裟に書いたのは、自分にとってアプリを公開するということは、実務でバリバリSwift書いてる人や一部の秀才たちにのみ許された聖域のように見えていて、なかなか踏み出せなかったからです。(つまりただイモってただけ)
でも、やってみたら案外あっさり承認されたのでもっと早くやってればよかったとちょっと後悔しています。
なので、同じように悩んでいる人がいたら、とりあえずさっさとApple Developer Accountにお金払ってアプリを公開しましょう！って背中を押したいのでこの記事を書いてます。

#公開したアプリ 【復習サイクル】

インストールは[こちら](https://apps.apple.com/jp/app/%E5%BE%A9%E7%BF%92%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB/id1524236844?l=en)
GitHubは[こちら](https://github.com/shinohara-san/RestudyCycle)

![スクリーンショット 2020-07-21 17.38.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586072/7c5ce396-d9ca-9458-ece9-03e75c0bd9f9.png)


機能的にはかなり薄っぺらいアプリです...

#流れ
流れとは言ってもただ参考にしたリンクの羅列になりそう。せめて体験談を踏まえながら書いていきます。

1. まずは[こちら](https://qiita.com/kenny_J_7/items/92378e2a09bee6080677)の1〜4を参考に下準備。ここでは特に何も困りませんでした。丁寧でとてもわかりやすい記事です、ありがとうございます。

2. 字を読んで理解するのが苦手なので、まずは[こちらのyoutube](https://www.youtube.com/watch?v=YPLs3xrDcm0&list=LLakH3H0T1ByDaXVELnQhsQg&index=5&t=1245s)を見て流れを掴む。英語ですが、とてもわかりやすくしゃぺってくれてます。

3. そして[App Store Connect](https://appstoreconnect.apple.com/)→マイAppにて、実際に必要事項入力していきます。基本的に全ての項目を入力していく感じです。僕が一番困ったのが電話番号入力。[こちら](https://itblogdsi.blog.fc2.com/blog-entry-190.html)を参考にして解決。"+81"というのが抜けていてずっとエラーが消えずめっちゃイライラしてました笑　それからスクリーンショットにも苦労しました。サイズが明確に決められていて、該当のスクショを選択→ツール→サイズを調整、鍵マークを外し指定のピクセルで入力します。
　![スクリーンショット 2020-07-21 17.43.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586072/b8d2ad48-b690-4669-21f3-e96166861215.png)
初めてこれをやったら、元の画像がめちゃくちゃ拡大されてびっくりしますが、それで問題ありません。ここで無駄に試行錯誤してました...

4. 個人情報の取り扱いについては[こちら](https://app-privacy-policy-generator.firebaseapp.com/)を使うと自動で取り扱いに関するリンクを作ることができます。すごい。これついて、何かトラブル等あった際の責任は一切取れませんので、ご自身でしっかり判断されてください。

5. アプリのアイコンはFigmaでそれっぽいの作って、それをスクショして、それを[こちらのサイト](https://makeappicon.com/)に投げれば自動で全部やってくれます！

6. アプリの審査してくれる方々はおそらく外国人なので、審査用の機能メモ欄は英語で書きました。Thank you in advanceと最後につけてちょっといい人を演じてみたりもしました笑 

#最後に
自分は24時間くらいしてokのメールをいただきました！これからどんどん公開していくぞ！そして早く転職活動終わらせたい...
Laravelでログを出し分ける【初級編】

#通常ログとは別ファイルにログを出力する

##はじめに
Laravelはデフォルトでログ出力機能が実装されていて、

```HogeController.php
use Log;

public function index()
{
    Log::debug('これはデバッグ行');
}

```

このように記述するだけでログとして出力されます。

```laravel-2020-07-21.log
[2020-07-21 00:00:00] local.DEBUG: これはデバッグ行
```

#ログ出力を個別で設定してみる
設定ファイルはsrc/config/logging.phpになります

```logging.php
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => [
                'daily',
                'hogelogs' //ここを今回は追加
            ],
            'ignore_exceptions' => false,
        ],
...
...
...
        // 指定するログチャンネル設定を記述
        'hogelogs' => [
            'driver' => 'daily',
            'path' => storage_path('logs/hogelogs.log'),
            'level' => 'error',
            'days' => 14,
        ],
```

初級編なので（自分が初級ですからね：-)
もっと複雑な設定も出来るでしょう。
とりあえず通常ログファイルに全部出たらエラーデバッグがやりづらい！
エラーを追うのが面倒！！！
という事で設定してみました。

#実際に出力してみよう

```HogeController.php
use Log;

public function index()
{
    Log::debug('これはデバッグ行');
    Log::channel('hogelogs')->error('これはhogelogsに出力されます');
}

```

```hogelogs-2020-07-21.log
[2020-07-21 00:00:00] local.ERROR: これはhogelogsに出力されます
```

簡単に出し分けられるのでsqlだけやAPI、batchで出力先を変えたいなど
遭遇する場面は多いと思います。


#終わりに
今回は簡単な手法での紹介になりましたが、
設定する値で変わる（どう変わるかはまだ知らない）
ので、これからも勉強ですね

皆さんも色々とログ周り触ってみて、環境にあったログ設計を試してみてください。

＃参考
https://qiita.com/K-Shuuun/items/37b7cc9a95030fe79494
https://qiita.com/hrdaya/items/b01d5621937a0710ca64
アルゴリズムパズルを解く【その1】

#目次
- [はじめに](#はじめに)
- [4. 兵士の輸送](#4-兵士の輸送)
    - [問題内容](#問題内容)
    - [考察](#考察)
    - [解答](#解答)
    - [感想](#感想)
- [5. 行と列の入れ替え](#5-行と列の入れ替え)
    - [問題内容](#問題内容-1)
    - [考察](#考察-1)
    - [解答](#解答-1)
    - [感想](#感想-1)
- [おわりに](#おわりに)

#はじめに
こんにちは、前回の[【その0】](https://qiita.com/pagos/items/6a033cc85736faed63ac)ぶりです。お久しぶりです。今回はキリよく? 5問目まで解いていきたいと思います。後、個人的に長くて読みづらいと思ったので目次をつけました。

#4. 兵士の輸送
##【問題内容】
- 25人の兵士が川を渡る
- 2人の少年が船で遊んでいるので借りる
- 船には少年2人か兵士１人が乗れる
- 兵士全員渡って、最後は少年2人が乗っている状態にしたい
- 何回往復する？

##【考察】
- 最初は動きが決まっている
- 1手目で向こう岸に少年2人で行って2手目で片方が帰ってくる
- ここで両岸に少年が1人ずついる状態が重要
- この状態でないと兵士は渡ることができない(兵士が往復するだけになるので)
- 3手目で満を辞して兵士が渡る
- 4手目で少年が帰ってくる
- この4手で兵士1人が渡り状態は元に戻った(1セット)

##【解答】
1. 少年が2人で向こう岸へ
2. 片方の少年が帰ってくる
3. 兵士が向こう岸に渡る
4. 向こう岸に残ってる少年が帰ってくる
以上の4手で1人の兵士が向こう岸に渡ることができた
よって4n(n:運ぶ兵士の数)で渡れる
今回は25人なので25*4=100手、50往復で完了する

##【感想】
小さなアルゴリズムを複数回繰り返すことで結果が得られるわかりやすい例。for文を使ったメソッド作るときにこういう考えになる。4問目にしてプログラミングちっくな問題だと思います。

#5. 行と列の入れ替え
##【問題内容】
|||||
|:--------:|:------------------:|:------------------:|:--:|
| 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 |
| 9 |10 |11 |12 |
|13 |14 |15 |16 |

|||||
|:--------:|:------------------:|:------------------:|:--:|
|12 |10 |11 | 9 |
|16 |14 | 5 |13 |
| 8 | 6 | 7 |15 |
| 4 | 2 | 3 | 1 |

- 行と列を入れ替えて上の図を下の図にできる?


##【考察】
- まず思ったのは全体の数字の合計は変わらないということ
- ただこのことは今回の問題にはあまり関係ない気がする
- 行と列の入れ替えというところに着目してみる
- とりあえず何回か行と列を動かしてみる
- 気づいたのは行と列の間で数字の組み合わせは変わらないということ
- 1行目に注目してみると行を動かしてももちろん組み合わせは変わらない、列を動かしても行の中で位置が移動するだけだ
- 他の行、列にも同じことが言える

##【解答】
できない
変わるはずのない行間列間の組み合わせが変わってしまっているため

##【感想】
ここまでの問題とは違って手の付けどころが難しかったです。意外とわからない人もいるのではないでしょうか。私はちょっと時間かかりました。

#おわりに
今日は2問解きました。ちょっと難しくなって来たかな?
こんな考え方もあるよっていう方がいましたらコメントくださると私が喜びます。
猛暑日のところも出て来ましたので体調には気をつけてお過ごしください。
今夜は勉強会参加して来ます。それでは。
STM32F3のOPAMPのフォロアのサンプル

以前、[STM32F3のDACで正弦波を出すサンプル](https://qiita.com/amutou/items/3d055f264e109abdcb2d)を書きました。その話題の続きです。

***

データシートによると、DACの出力範囲は0.2VからVDDA-0.2Vまでだそうです。見てみましょう!!

![2020-07-21_17-01-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/f36ad749-7212-37d8-aa12-8757b228f522.png)

結構端まで振れてますね。少なくとも0.2Vどころではありません。あくまでも0.2Vというのは保証できる範囲はここまで、という数値です。
ちなみに上の図は無負荷時です。4.7kくらいのRをつけると上はVDDA-0.2Vくらいまで落ちてきます。

***

DACの出力バッファを無効にすると0.5mVくらいまで振れるようです。見てみましょう!!

![2020-07-21_17-00-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/977ba8b8-a1a0-e5d0-916b-4555db147e90.png)

しっかりレールツーレールで振れてますね。
しかし、バッファがOFFなので少し大きめの負荷をかけるとあっという間に歪んでしまいます。これではキレイな波形の意味がない……

***

さて、STM32F3には便利なオペアンプが内蔵されています。これをフォロアモードにして使ってみましょう。
303RE Nucleoの場合、DAC1 ch1とOPAMP4 VIN+が共にPA4に出ているので、直結できます。OPAMP4はPB12に出ているので、これも合わせてオペアンプの初期化を行います。

```c
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_SYSCFG_CLK_ENABLE();

GPIO_InitTypeDef gpio = {
    .Pin = GPIO_PIN_12,
    .Mode = GPIO_MODE_ANALOG,
};
HAL_GPIO_Init(GPIOB, &gpio);

OPAMP_HandleTypeDef hopamp = {
    .Instance = OPAMP4,
    .Init = {
        .Mode = OPAMP_FOLLOWER_MODE,
        .NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO2,
    },
};
HAL_OPAMP_Init(&hopamp);

HAL_OPAMP_Start(&hopamp);
```

簡単ですね。

出力はこんな感じです。

![2020-07-21_17-16-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/ef3f616f-1cc5-ac06-7356-5d30a708e0c1.png)

ch1(黄色)がDACの出力、ch2(紫色)がOPAMP4の出力、DACは無負荷(OPAMPのみ)、OPAMPは4.7kΩでGNDに接続、という感じです。4.7kだと負荷とも思われていないのか、入力と出力がピッタリ重なって見えなくなっています。振幅もレールツーレールでしっかり振れています。

***

STM32F3はオペアンプが内蔵されていて、1倍、2倍、4倍、8倍、16倍の非反転増幅は外付けの抵抗類すらも不要で簡単に使えます。入力インピーダンスを高くしたいとか、振幅を少し増やしたいと言うときには結構便利です。今回はDACで使いましたが、オペアンプの出力をADCで読むこともできて、その場合はADCの入力インピーダンスを下げられたり振幅を増やしたりできるので、ADCと組み合わせると便利だと思います。
と、いうような話は以前に書いているので、そちらも合わせて御覧ください。
[STM32F3、ADCとFIRとDAC。ついでにタイマとオペアンプ。](https://qiita.com/amutou/items/b136d63643727a8f44b1)
DockerでRailsのセットアップ

①  develop > docker > app名(test)　を作成

②  test内に、'dockerfile'、'docker-compose.yaml'を作成

③ 'dockerfile'編集

```ruby:dockerfile
FROM ruby:2.6.6-stretch
```
>Docker は Dockerfile から命令を読み込んで、自動的にイメージをビルドします。 Dockerfile はテキストファイルであり、イメージを作り上げるために実行するコマンドラインコマンドを、すべてこのファイルに含めることができます。 docker build を実行すると、順次コマンドライン命令を自動化した処理が行われて、ビルド結果となるイメージが得られます。

④ 'docker-compose.yaml'編集

```ruby:docker-compose.yaml
version: '3'
services:
  app:
    build: .
    volumes:
      - ".:/app"
    ports:
      - "3000:3000"
    tty: true
```

⑤　ターミナル

```terminal
docker-compose up
# コンテナの起動・構築
```
6  コンテナを作成して起動からログインしてbashで操作

```terminal
docker exec -it SAMPLE_APP_1 /bin/bash
```


Dockerでよく使うコマンドまとめ
> https://designsupply-web.com/media/knowledgeside/3325/


チートシート
>https://qiita.com/eighty8/items/0288ab9c127ddb683315
Nuxtのマイナーアップデートに手こずった件


## 結論

Nuxtをv2.13系にアップデートするときは.envディレクトリを使わないこと

## 事の発端

`v2.12 → v2.13` にアップデートしようと思うと以下エラーに遭遇する

```
 FATAL  EISDIR: illegal operation on a directory, read                                                                                                                                                                                                                17:10:04

  at Object.readSync (fs.js:564:3)
  at tryReadSync (fs.js:349:20)
  at Object.readFileSync (fs.js:386:19)
  at loadEnv (node_modules/@nuxt/config/dist/config.js:4622:38)
  at Object.loadNuxtConfig (node_modules/@nuxt/config/dist/config.js:4539:15)
  at loadNuxtConfig (node_modules/@nuxt/cli/dist/cli-index.js:2725:32)
  at NuxtCommand.getNuxtConfig (node_modules/@nuxt/cli/dist/cli-index.js:2848:26)
  at Object._listenDev (node_modules/@nuxt/cli/dist/cli-dev.js:70:30)
  at Object.startDev (node_modules/@nuxt/cli/dist/cli-dev.js:53:25)
  at Object.run (node_modules/@nuxt/cli/dist/cli-dev.js:47:16)


   ╭───────────────────────────────────────────────────────────╮
   │                                                           │
   │   ✖ Nuxt Fatal Error                                      │
   │                                                           │
   │   Error: EISDIR: illegal operation on a directory, read   │
   │                                                           │
   ╰───────────────────────────────────────────────────────────╯
```

## 原因


v2.13で.envがサポートされた
> Built-in .env support and runtimeConfig
https://ja.nuxtjs.org/guide/release-notes/#v2.13.0

たまたまうちのプロダクトで.envディレクトリ配下に各環境ごとのenvファイルを作ってたのが原因だった

```javascript:node_modules/@nuxt/config/dist/config.js
  // Load env
  envConfig = {
    dotenv: '.env',
    env: process.env,
    expand: true,
    ...envConfig
  };
  const env = loadEnv(envConfig, rootDir);
```

nuxt側ではファイル見にいくつもりなのに、同じ名前のディレクトリがあればそれは`Error: EISDIR: illegal operation on a directory, read `にもなりますよねぇ・・・

## 教訓

めんどくさくても、エラーわからなかったら中の実装(node-modules配下の)見に行こう
Talendを使ってSnowflakeにデータ更新する際の注意点

#Snowflakeの現在日時取得関数CURRENT_DATE()に戸惑う
Snowflakeで当日のデータを洗い替える為に、CURRENT_DATE()を使って当日データをDeleteしていたのですが、うまくいく場合とうまくいかない場合がありました。show parametersで現在のTimezoneを確認してみたところ、Timezoneの初期値がAmerica/Los_Angelesとなっていました。ここをAsia/Tokyoに変更することで正しく当日の日付が取得できることを確認しました。

```
show parameters
Alter session set TIMEZONE  = 'Asia/Tokyo'
```

　　![2020-07-21_16h21_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/592e20ec-4023-7df0-38be-821e2b0964a7.png)


#それでもTalendの日付がズレる
Snowflake側のCURRENT_DATE()の時間ズレは解消できましたが、Talendから処理を実行するとまだ日付がズレたままでした。私が使用しているTalendのバージョン(7.3.1)では、Snowflakeのコンポーネントをで東京リージョンが選択できない(2020年7月現在)為、米国西部を使用しています。これが原因となりCURRENT_DATE()が米国西部時間になっていたと考えています。

![2020-07-21_13h52_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/a3a80153-3214-99ec-f997-a94405a6c1d3.png)

現状では他に選択肢がない為、バッチの時間を変更して16時までにデータ洗い替えを終わらせるようにすることにしました。(16時までならCURRENT_DATE()+1で当日データとなる為)
もし、こちらの対応方法以外に良い方法があれば、ご意見を頂けると助かります。

#おまけ
###現在日付取得関数の違い
基幹システムDBにOracleを使っており、それ以外のマスタデータはSQLserverでデータを管理しています。今回DWHとしてSnowflakeを導入しました。
(Snowflake選定までの記事は別途記載します)

Oracle、SQLserver、Snowflakeで現在日付を取得する関数が違います。
　　・Oracle　　　 SYSDATE
　　・SQLserver　　GETDATE()
　　・Snowflake　　CURRENT_DATE()
8桁の日付文字列として扱う場合は下記のように扱います。
　　・Oracle　　　 TO_CHAR(SYSDATE,'YYYYMMDD')
　　・SQLserver　　SUBSTRING(CONVERT(VARCHAR, GETDATE(), 112),1,8)
　　・Snowflake　　TO_CHAR(CURRENT_DATE(),'YYYYMMDD') 

​以上
kubenetes.io のチュートリアルを読んだのでメモ

# kubenetes.io の前に
#### [Introduction to Kubernetes](https://cybozu.github.io/introduction-to-kubernetes/introduction-to-kubernetes.html)

サイボウズの入門記事がわかりやすい。ハンズオンで一気に全体を把握できるので、kubenetes.ioの前にやってもいいかも。

とくになにも知らない自分に、この対応関係がイメージをつかむのに役立った。

![スクリーンショット 2020-07-14 16.47.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/be27f5b9-8e51-b3cb-7481-19dcf1bb62b4.png)

# kubenetes.ioのハンズオン

#### [Kubernetesの基本を学ぶ](https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/)

ハンズオンしながら理解を深めていける。要所要所で出てくる図解も理解を助けてくれる。

### Minikubeを使ったクラスターの作成

#### [Minikubeを使ったクラスターの作成](https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/create-cluster/cluster-intro/)

- マスター: クラスターを管理する
- ノード: クラスターのワーカーマシンとして機能するVMまたは物理マシン

### Podとノードについて

#### [Podとノードについて](https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/explore/explore-intro/)

![スクリーンショット 2020-07-14 17.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/caeb8a52-94a9-1cc4-18b7-a6cf510dd5ba.png)

- Pod: 複数のコンテナ、ネットワーク、共有ストレージなどをもつ
- Node: マスターとノードの通信を担うkubeletやDockerプロセスをもつ

### Serviceを使ったアプリケーションの公開

#### [Serviceを使ったアプリケーションの公開](https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/expose/expose-intro/)

![スクリーンショット 2020-07-14 17.18.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/1578d0f5-97e6-4ca4-42e7-622bdc55321f.png)


- Service: Podの論理セットと、それらにアクセスするためのポリシーを定義する抽象概念
  - 一連のPodにトラフィックをルーティングし、アプリケーションに影響を与えることなく、KubernetesでPodが死んだり複製したりすることを可能にする
  - Serviceが対象とするPodのセットは通常、LabelSelectorによって決定される
自走エンジニアになるための重要な秘訣

本記事は[Coletiv](https://coletiv.com/)でフロントエンジニアとしてエンジニアをスタートした[Rui Sousa](https://twitter.com/HeyItzaMi?utm_source=notify_mailer&utm_medium=email&utm_campaign=new_reply_email)氏による記事「[Important tips for a self-taught developer](https://dev.to/coletiv/important-tips-for-a-self-taught-developer-1mn5)」を本人の許可を得て翻訳した記事になります。

誤訳等ありましたらコメント頂けると幸いです。

## はじめに
Web業界の会社に入社してジュニアデベロッパーとして働くのに向けて、基礎（多くは技術的な内容）を[指南する記事はいくつかある](https://www.freecodecamp.org/news/ace-your-first-year-as-a-junior-developer-with-this-advice-bbc68b6fe2d9/)。けれども本記事ではよりエンジニアとしてのパーソナリティ面に焦点を当てることにした（人間らしくあるよう言っているとあなたは思うかもしれない🤔）

記事の始めの方では自走エンジニアに重点を置くけれども、**実際はすべての人に**活用できる。自走エンジニアについて集中して話すのは、私も自走エンジニアの一人だからだ。

自己紹介を少しすると、私は心理学で修士を取った（完全にキャリアパスを変えた）自走できるフロントエンドエンジニアで、キャリアはPortoにあるソフトウェア開発会社[Coletiv](https://coletiv.com/)でフロントエンドエンジニアとしてスタートした😎。

本記事では、自分自身の向上に役立ったと実感し、エンジニアとしてのファーストキャリア（実はエンジニアに限らずどんな職種も）でより快適な経験をあなた自身と同僚が得られる**4つの秘訣**を紹介したい。

とりあえずやってみよう！

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567173/89901706-8b78-6559-5e77-649c7caf85c4.gif)


## 秘訣1：「知らない」と言う
誰もあなたが全てを知っていると期待はしていないけど、**知らないことは知らないと伝えることは期待されている**。自身のレベルや理解度をオープンにするのに抵抗を覚えないようにしよう。

**知らない**と言うことは、把握している知識には自信があってかつ、自信の弱みを理解していることを示せる。これがあるとメンターや同僚、仲間は話し方を調整できるし、もし「見せてくれますか？」とお願いしたらきっと資料を見せてくれるでしょう。そうすれば**「知らない」**を**「もちろん知ってるぜ」**に変えられる。

周りの人が何について話しているのかわからないのに、知ったかぶりをするのはやめよう。そこから何も学べないよ。全く答えがわからずたくさんの疑問が残るだけで、結局得られるのはちょっとしたエゴだけだ。

## 秘訣2：学習能力と学習意欲
### 学習能力
**自分にしっくりくる学習方法がまだわからない場合は、長時間粘って自分に合うやり方に沿う情報を見つけてみよう。**こうすれば車輪の再開発を避けつつ、専門的な助言や資料を得られる。

もしビデオ教材が合わないなら、書籍で探してみる。書籍が合わないなら、ドキュメントを確認してみる。ドキュメントが不十分なら、今まで学んだことに試すミニプロジェクトを実際にやってみる感じでね。

### 学習意欲
もちろん学習資料や完璧な勉強法なんてのは、困難に取り組む意思がないと何の意味もない。StackOverFlowの回答を読んで何回か困難から逃げれるかもしれないけど、**自分が取り組んでいることを心から理解して学ぼうと思おう**。私が思うに、これが進歩を得る唯一の方法だ。

仕事の合間を縫って勉強しよう。そして**自分のためにやろう**。仕事のためでなく、自分のためにやろう。だってもう既にいくらかの犠牲を払ってその立場にたどり着いたのでしょう？なんでそれを今やめちゃうの？

## 秘訣3：走り続けよう
自分が一番自分の弱みを知っている存在になろう。**貪欲に生きていないと、自分にどんな知識や経験が足りていないのかわからなくなる。**新しいものを探して読書リストを作ろう。新しく感じたもの（ただし自分の分野に関係のあるもの）は全てメモして、強みに繋がりそうなモノに優先順位をつけよう。

例えばReactを使っていてuseEffectの知識があやふやだと感じたら、他人に指摘されるのを待つ前に自分でなんとかしよう。

**Stay Hungry!**

## 秘訣4：一匹狼にはなるな
誰もあなたを反対していない。仮に誰かが反対しているとすれば、それは多分その人はどうでもいい人だろう。メンターや同僚、仲間はあなたと一緒に過ごして助けたいと思っている。そうでなかったら、そもそもあなたを雇ってないだろうからね。

自分をオープンにして働く環境をよりフレンドリーにしよう。そうすれば結果として助言を求めるときにスムーズにうまくいくし、人となりを知る良い方法にもなる。

我々はみんな一人で働くことに慣れているけども、冗談を言い合ったり知り合いを増やしたり、より良い関係を気づく知識やアイデアをシェアする機会を得たりできるんだ。

## まとめ
これら4つの秘訣はエンジニアとしての最初の仕事を乗り切るのに必要なことを網羅していると思う。もちろん他にもたくさん言えることはあるけども、私にとって**「貪欲であること」「謙虚であること」「人と接すること」**が知識のレベルアップや人との繋がりを増やすのに最も役立つと感じている。

だからもしこの記事を一言で言うとすれば、次のようになるだろう。

技術的なスキルを持つことも大切だけど、DO, TRY, FAILを厭わないことが重要だ。

他にあなたが重要だと思う秘訣はなんでしょう？ぜひコメントでシェアしてください！
GitHubでプルしようとしたらfatal: Could not read from remote repositoryになった話

作業しながらメモしていたので若干間違いがあるかもしれません.

#Pemssion Error

VScodeの```githistory```でリモートリポジトリからローカルリポジトリにプルしようとしたらPemssion Errorが発生.

![スクリーンショット 2020-07-22 14.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595139/0b3672c6-bcfa-1d70-c43b-46ad9c52e80e.png)

公開鍵の認証ができませんでしたということらしい.

```shell
Git: git@github.com: Permission denied (publickey).
```
GitHubにssh接続して認証すればいいのねってことで,

```shell
#ssh接続
ssh -T git@github.com
```

ってして認証したら

```shell
Git: packet_write_wait: Connection to <IP address> port 22: Broken pipe
fatal: Could not read from remote repository.
```

リモートリポジトリが読み込めないらしい.
ということでいろいろ調べてみたら以下の記事を発見した.

[fatal: Could not read from remote repository. の落とし穴](https://hayato8810noblog.hatenablog.com/entry/2019/04/21/002950)

プルの仕方が悪いのか?(確かに悪かった)と思ったのですが、プッシュもできないのでそうでもないみたい.
でよーく考えると...

***
**リモートリポジトリの名前変更してた**
***

何も考えていなかったですけどリモートリポジトリの名前を変えたり, プライベートリポジトリにしたりとGitHub上でいろいろ操作してました.
忘れてました.

```shell
git remote -v
```
で確認すると

```shell
origin  git@github.com:jamjamjam888/DOCI.git (fetch)
origin  git@github.com:jamjamjam888/DOCI.git (push)
```

となってました（github上でDOCI-projectに変更していた）.

いったんリモートリポジトリを元に（DOCI）に戻して、改めてローカルからリモートリポジトリの名前を変更しました.

```shell
git remote set-url origin git@github.com:jamjamjam888/DOCI-project.git
```

[リポジトリの名前を変更する](https://docs.github.com/ja/github/administering-a-repository/renaming-a-repository)

#参考記事
**-Gitのコマンドについて-**

[基本的なGitコマンドまとめ](https://qiita.com/2m1tsu3/items/6d49374230afab251337)


**-Permission Deniedについて-**
[Error: Permission denied (publickey)[公式ドキュメント]](https://docs.github.com/ja/github/authenticating-to-github/error-permission-denied-publickey)

ちなみに以下のコマンドで, キーが使用されていることを確認することもできる.
これでPermissionがうまくいっているか確認できる.

```shell
ssh -vT git@github.com
```
結果

```shell
#大量の処理
#:
#いけてる
>>>Authentication succeeded (publickey).
```

## おまけ
**2020/07/28追記**
リポジトリを作ってコミットしても草が生えていないので確認するとレポジトリにユーザーネームとメールアドレスを登録する必要があるらしい.

そこで以下のコマンドで登録してみた.

```shell
git config –global user.name <ユーザ名>
git config --global user.email <メールアドレス>
```
macOSでStatic Routeの永続化

# 環境
macOS Catalina(10.15.5)

# はじめに
macOSでStatic Routeを設定するのにroute addコマンドを使用します。
例）デフォルトゲートウェイが100.1.2.254であるネットワークで
10.0.0.0/8を192.168.1.254のルータに向ける場合

```sh:
#Static Routeの追加
$ sudo route add -net 10.0.0.0/8 192.168.1.254
#ちなみに削除する場合は以下
$ sudo   route delete -net 10.0.0.0/8 192.168.1.254
#確認
＄ netstat -rn
default            100.1.2.254        UGSc           en0       
10                 192.168.1.254       UGSc           en0 
```
しかし、再起動すると追加したStatic Routeは消えてしまいます。

ネットワーク設定の永続化のためにWindowsは-Pオプション、ubuntuだとnetplanに書くなどして対処しますが、macOSはありません（ガーン）。スクリプトで対応とかダサい。

# networksetupコマンド
ではどうするかというと、networksetup -setadditionalroutesで設定できます。

#### 一旦ヘルプを見ます

```sh:
$ networksetup --help | grep setadditionalroute
networksetup -setadditionalroutes <networkservice> [ <dest> <mask> <gateway> ]*
```
設定にはnetworkservice名が必要なので調べます。これもnetworksetupコマンドでできます。

```sh:
$ networksetup -listallnetworkservices
An asterisk (*) denotes that a network service is disabled.
Wi-Fi
Bluetooth PAN
Thunderbolt Bridge
```
無線LANのnetworkservice名は「Wi-Fi」ということがわかりました。

### ルーティングを追加
さきほどrouteコマンドで設定したものと同じルーティングを追加します。
これは再起動でも消えません。
例）デフォルトゲートウェイが100.1.2.254であるネットワークで
10.0.0.0/8を192.168.1.254のルータに向ける

```sh:
$ networksetup -setadditionalroutes Wi-Fi 10.0.0.0 255.0.0.0 192.168.1.254
#netstatで確認
$ netstat -rn | grep 10
default            100.1.2.254        UGSc           en0       
10                 192.168.1.254       UGSc           en0
```

### 削除する場合
networkserviceに引数をつけないと、今まで設定した静的ルーティングが削除されます。

```sh:
$ networksetup -setadditionalroutes Wi-Fi
```
## 注意点
ここで注意点ですが、networksetup -setadditionalroutesは一番最新のコマンドが優先されます。
例えば、以下のように連続して異なるルーティングの設定をしてしまうと後の172.16.0.0しか有効になりません。

```sh:
$ networksetup -setadditionalroutes Wi-Fi 10.0.0.0 255.0.0.0 192.168.1.254
$ networksetup -setadditionalroutes Wi-Fi 172.16.0.0 255.255.0.0 192.168.2.254
##確認(172.16.0.0のルーティングしか追加されていない)
netstat -rn | grep 192.168
172.16             192.168.2.254      UGSc           en0
```

### 複数のルーティングを設定する場合
ヘルプで見てみると複数のルーティングが設定できることがわかります。

```sh:
$ networksetup -setadditionalroutes <networkservice> [ <dest> <mask> <gateway> ]*
```
```sh:
$ networksetup -setadditionalroutes Wi-Fi 10.0.0.0 255.0.0.0 192.168.1.254 172.16.0.0 255.255.0.0 192.168.2.254
## 確認(複数のルーティングが追加された)
netstat -rn | grep 192.168
10                 192.168.1.254      UGSc           en0       
172.16             192.168.2.254      UGSc           en0
```
<dest> <mask> <gateway>の文字列を複数列挙する必要があります。
ヘルプのように配列リテラルのように記載してもNGです。

```sh:
### 以下はNGの例です。
$ networksetup -setadditionalroutes Wi-Fi [172.16.0.0 255.255.0.0 192.168.2.254] [10.0.0.0 255.0.0.0 192.168.2.254]
zsh: bad pattern: [172.16.0.0
```
また、CIDR表記（10.0.0.0/8)のようにしたい場合もNGになります。

```sh:
###これはsyntax errorとなります
$ networksetup -setadditionalroutes Wi-Fi 10.0.0.0/8 192.168.2.254
Route syntax: <dest> <mask> <gateway>
```

# 参考
[networksetupコマンドの使い方:ヘルプのみかた](https://takuya-1st.hatenablog.jp/entry/2018/07/05/000000_1)
[Mac OS Xのターミナル上でWi-Fiの設定を追加・削除する](https://qiita.com/nosu/items/65bf8e303a4a19340610)
【Nuxt.js】Nuxt文法編：$attrs

🎈 この記事はWP専用です
https://wp.me/pc9NHC-li

# 前置き
属性の受け継ぎに関する
$attrsをまとめました！

inheritAttrsと
v-bind="$attrs"の2種類があります🌟

# inheritAttrs とは
inherit
英語で「受け継ぐ」

親で与えられた属性を受け継ぐか
真偽値で決めることができます。

## inheritAttrs: true

![picture_pc_48118aa444ea32334dbe1db1befa80bc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/72960721-564d-5c32-7cf1-1c0792260565.gif)


リンク先が '/' で
新しいタブで開かれていますね！

これだけ見ると普通のリンクなのですが
解説・コードを見ると
奇妙に感じるかもしれません😨笑

【解説】

挙動を確認するために親子どちらでも
nuxt-linkタグのto属性でリンク先を指定しています🌟

to属性は子が優先されているのに
target属性は親のを引き継いでます。

もちろんtarget属性を子で指定すれば
子が優先されます！

が！

そもそも通常は親から子に何も使わず
何かを渡すことはできません。
属性に限らず、
テキストであれば
propsなりslotなり、何かを使います。
とっても変な感じがしますね😲

ちなみに属性を渡す場合は、
この後に解説するv-bind="$attrs"を使います🌟

うっかり何も使わず親で属性を渡しちゃってた！
ということは防ぎたいです。。。

```Link.vue
<template>
 <nuxt-link to="/">
   リンク！
 </nuxt-link>
</template>

<script lang="ts">
export default {
 inheritAttrs: true,
}
</script>
```

```index.vue
<template>
<div class="page">
  <Link
    to="/sample"
    target="_blank"
  />
</div>
</template>

<script>
import Link from '~/components/Link.vue'

export default {
components: {
  Link,
},
}
</script>
```

## inheritAttrs: false

![attrs.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/eedef77c-fefe-229b-9c33-fa91cb6f801c.gif)


inheritAttrs: true
この奇妙な状態を解決するために
falseにしておくのが無難です🌟

今度は親の属性を引き継がず、
子の属性のみが反映されていますね！

【コード】

inheritAttrs: trueのコードをfalseに変えるだけ

# v-bind="$attrs" とは
🎈 続きはWPでご覧ください👀
https://wp.me/pc9NHC-li
[C#]AWSの使用料金をAPIで取得する 

# AWSの使用料金がえらいことに･･･

思いのほかAWSの使用料金が上がっていて、青ざめた経験が誰しもあるはず。
定期的に請求ページを確認すればいいのですが、休日は見てなかったりして
気づいたときは多額の請求がきていた…なんてことも。

そこで、CostExplorer APIを使っていつどのくらい使用したのかわかるようにしてみました。
**※CostExplorer APIはリクエストごとに費用が発生するのでやりすぎに注意しましょう！
(記載時点で1回のリクエストにつき0.01ドル)**

#必要なもの
AWSのAccessKeyとSecretKey
AWSSDK.CostExplorerをインストール

# コード(Console)

```
            string awsAccessKey = "xxxxxxxxxxx";
            string awsSecretKey = "xxxxxxxxxxxxxxxxxxxxx";

            AmazonCostExplorerClient client = new AmazonCostExplorerClient(awsAccessKey, awsSecretKey, RegionEndpoint.USEast1);
            GetCostAndUsageRequest req = new GetCostAndUsageRequest();
            req.TimePeriod = new DateInterval();
            req.TimePeriod.Start = "2020-07-01";
            req.TimePeriod.End = "2020-07-20";
            req.Granularity = Granularity.DAILY;
            req.Metrics = new List<string>() { "AMORTIZED_COST" };

            GetCostAndUsageResponse cost = client.GetCostAndUsage(req);
            for (int i = 0; i < cost.ResultsByTime.Count; i++) {
                string start = cost.ResultsByTime[i].TimePeriod.Start;
                string end = cost.ResultsByTime[i].TimePeriod.End;
                foreach (string key in cost.ResultsByTime[i].Total.Keys) {
                    decimal amount = decimal.Parse(cost.ResultsByTime[i].Total[key].Amount);
                    string unit = cost.ResultsByTime[i].Total[key].Unit;
                    Console.WriteLine(start + "～" + end + " Amount=" + amount + " Unit=" + unit);
                }
            }


```


# 結果
```
2020-07-01～2020-07-02 Amount=47.6436917916 Unit=USD
2020-07-02～2020-07-03 Amount=47.2799385496 Unit=USD
2020-07-03～2020-07-04 Amount=0.0012009547 Unit=USD
2020-07-04～2020-07-05 Amount=0.001352335 Unit=USD
2020-07-05～2020-07-06 Amount=0.0013171085 Unit=USD
2020-07-06～2020-07-07 Amount=0.0013171085 Unit=USD
2020-07-07～2020-07-08 Amount=0.0013171085 Unit=USD
2020-07-08～2020-07-09 Amount=0.0013171085 Unit=USD
2020-07-09～2020-07-10 Amount=0.2201781931 Unit=USD
2020-07-10～2020-07-11 Amount=48.1395790234 Unit=USD
2020-07-11～2020-07-12 Amount=48.1393261349 Unit=USD
2020-07-12～2020-07-13 Amount=48.1394533349 Unit=USD
2020-07-13～2020-07-14 Amount=6.6676519934 Unit=USD
2020-07-14～2020-07-15 Amount=0.0009903077 Unit=USD
2020-07-15～2020-07-16 Amount=0.0009903077 Unit=USD
2020-07-16～2020-07-17 Amount=0.0009903077 Unit=USD
2020-07-17～2020-07-18 Amount=0.0009903077 Unit=USD
2020-07-18～2020-07-19 Amount=0.0009903077 Unit=USD
2020-07-19～2020-07-20 Amount=0.0009903077 Unit=USD
```

10日～13日にやらかしてますね…
この時、DocumentDBの検証をやっていてインスタンス落とすの忘れてて
土日放置してたようです。

あとは、このレポートを定期的/閾値を超えたらメールで送ったり
メッセンジャーに送ったりすれば被害を低減できるでしょうか。

そもそも自分でちゃんと管理しろと言われそうですがね。

自分用の雑なコンソールアプリです。
[閾値を超えたらメール送信するアプリ](https://github.com/with-leaf-tech/AWSBillingAlertMail)
Ansibleのtaskやplaybookの同時実行数はthrottleで簡単に制御できる

Ansibleの同時実行数は以前から`serial`で制御できましたが、playbookにしか適用できませんでした。Ansible 2.9からは`throttle`が追加され、playbookだけじゃなくtaskなども同時実行数を制御できるようになりました。
https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_strategies.html#id3

```yaml
- hosts: all
  tasks:
    - name: run
      command: hogehoge
      throttle: 1  # 同時に１つまで
```

便利。
Oracle Database In-Memoryが制限付きながらも無料になったよ

詳しくは以下のブログを見てほしいけれど、Oracle Database Enterprise Editionのオプションである**「Oracle Database In-Memory」**がオプションを購入しないでも使えるようになった。

* [Oracle Database In-Memory Base Level Feature](https://blogs.oracle.com/in-memory/oracle-database-in-memory-base-level-feature)
* [Mike Dietrich's Blog: Oracle Database In-Memory BASE_LEVEL Feature available since 19.8.0](https://mikedietrichde.com/2020/07/20/oracle-database-in-memory-base_level-feature-available-since-19-8-0/)

要点をまとめると以下のとおり。

* Release Update 19.8.0から利用可能
* EEで利用可能。SE2では利用不可
* CDBあたりIn-Memoriyのサイズは16GB
* RAC構成の場合、ノードあたり16GB

どのくらいのインパクトがあるかわからないけれど、Oracleブログでは喜びのコメントがついているし、Mikeのブログでも"Not bad"と書かれている。

Oracle社としてもIn-Memoryのライセンスユーザーは少ないから、無料にしてもレベニューインパクトは少ないだろうしね。今後マイナーなオプションは、どんどん無料になっていく予感。

**条件付きもしくは条件なしで利用可能になったオプション**

* Oracle Multitenant
* Rapid Home Provisioning改めOracle Fleet Patching and Provisioning
* Oracle Spatial and Graph/Advanced Analytics（SE2でも利用可能！）
* Oracle Database In-Memory
WaveGlow 推論を C++ で実装するメモ　

## 背景

いい感じの Text-to-speech をモバイルや IoT で動かしたい.
2019 年 12 月時点だと FastSpeech + WaveGlow が良さそう.

xcmyz's FastSpeech を CPU で推論して text-to-speech する
https://qiita.com/syoyo/items/c3ed70abf9ab6c37ac5d

Neural text to speech のメモ(2019 年 11 月 27 日時点)
https://qiita.com/syoyo/items/6b7faf99cbfc9e2e173a

-> WaveGlow を動かしたい.
 
libtorch mobile も出てきたが, 今後 mobile Vulkan などで動かすのを考えると, 一から C++ に移植しておきたい.

NVIDIA のオフィシャル実装(PyTorch)を移植していきます.

https://github.com/NVIDIA/waveglow

**現状方針だけです. 成果物はありません.**

## 方針

* なるべく header-only なライブラリだけ使い, Eigen など規模が大きめなライブラリに依存しないようにする.
* C++11 or later

## 参考情報


### Glow 関連　

Glowの論文を読んだので要約とメモ
https://qiita.com/exp/items/4f562ec788f2ac5241dc

Glow をきちんと理解するには RealNVP, RealNVP を理解するには NICE を読んでおく必要がありますが, 推論だけだと実装コード自体は以外と簡単です. とりあえず実装してから, 論文を読んだ方が理解が捗るかもしれません.

### CUDA 実装

CUDA + cuDNN + cuRAND での WaveGlow 推論実装
https://github.com/Saurabh-29/Waveglow_Inference_in_CUDA


## 移植についてのメモ

## 概要

* 学習時には matrix の invert などが必要ですが, 推論時は不要です.
  * weight_norm の処理も不要です(推論時はネットワークから削除している).


## PyTorch op 関連

Chainer で学習し TensorFlow-lite で推論するための準備メモ https://qiita.com/syoyo/items/e84d66b2a938843c1594 

が PyTorch 関連の op にも適用できて事前知識として役立ちます.
(細かいところでは, 引数の振る舞いが違うとかあるかもですが)

### torch.nn.ConvTranspose1d

いわゆる upsampling(画像で言えば拡大スケーリング)です. 1D なので, 自前実装は難しくはないです(実質フィルタ処理として書ける).

### torch.nn.Conv1d

これも 1D なので, 特に難しくないです.

## 正規分布乱数の生成

C++11 random に正規分布に従う乱数生成があります.

## データの変換とロード

* .wav : dr_wav を使います.
* npy, npz : https://github.com/rogersce/cnpy を使います. fork していくらか使いやすくしたのが  https://github.com/rogersce/cnpy にあります
* .pt からウェイトの取得 :  Waveglow_Inference_in_CUDA のツールを利用して, npy に変換します.

## text-to-speech への利用

WaveGlow は mel spectrogram -> .wav の部分なので, 
text -> mel の部分(FastSpeech, Tacotron2, etc)も別途実装が必要です.
(text の処理周り(python inflect module の C++ 移植とか)のほうが, inference の実装よりめんどいかも...)

特に FastSpeech は Transformer 系なので, これを実装することで副産物(?)として BERT などの NLP も pure C++ で動かすことができると予想できます. 


## TODO

* [ ] Mellotron を C++ 移植する
* [ ] FastSpeech(Transformer) を C++ に移植する(=> BERT などにも使える)
PHPとJavaScriptを使ったプルダウンを覚えたので記録しておく

#PHPを使ったプルダウンを覚えたので記録しておく。
一部分を抜き出しているので非常にわかりにくいかもしれませんが．．．
PHP、JavaScript、Ajax、jsonを使用。

PHPファイルその1

```php
<select name="category" size="1" id="category">
  <option value="大型犬" data-filter="大型犬">大型犬</option>
  <option value="中型犬" data-filter="中型犬">中型犬</option>
  <option value="小型犬" data-filter="小型犬">小型犬</option>
</select>
<select name="subcategory" size="1" id="subcategory">
</select>

```
サブカテゴリにデータを入れていきます。


PHPファイルその2

```php
<?php

if(isset($_GET['category']) == true){
  $category = $_GET['category'];
}

//json形式で項目を入力しておく
if($category  == '大型犬'){
  $array = "[{\"name\": \"ゴールデンレトリバー\", \"value\": \"ゴールデンレトリバー\"},{\"name\": \"ラブラドールレトリバー\", \"value\": \"ラブラドールレトリバー\"},{\"name\": \"サモエド\", \"value\": \"サモエド\"}]";
}else if($category == '中型権'){
  $array = "[{\"name\": \"コーギー\", \"value\": \"コーギー\"},{\"name\": \"柴犬\", \"value\": \"柴犬\"}]";
}else if($category == '小型犬'){
  $array = "[{\"name\": \"チワワ\", \"value\": \"チワワ\"},{\"name\": \"マルチーズ\", \"value\": \"マルチーズ\"}]";
}

header('Content-Type: application/json; charset=utf-8');
print($array);

```



```js

  //カテゴリ設定
  $('#category').on('change', function (event) {
    category();
  });
});

//カテゴリ設定の関数
function category() {
  $.ajax({
    url: '***ファイル名を入力***',
    type: 'GET',
    data: {
      category: $('#category').val(),
      select: 'subcategory',
    },
    dataType: 'json',
    cashe: false
  }).done(function (data) {
    const target_number = event.target.value;
    const subcategory = $('#subcategory');
    const data_sub = $('#category').children().eq(target_number).data(subcategory);
    subcategory.empty();
    for (let i = 0; i < data.length; i++) {
      let option = $('<option></option>');
      option.val(data[i]['value']);
      option.text(data[i]['name']);
      subcategory.append(option);
    }
  }).fail(function (data, textStatus, error) {
    alert('error');
  });
}

```
Django入門03（リリース編）

# 環境ごとに設定ファイル（settings）を変える

ローカル環境、開発サーバー、本番サーバーで設定を切り替える為の変更。
基本的に以下ページの通り。
[Djangoプロジェクト構造のカスタマイズ（分割と構造化）](https://qiita.com/aion/items/ca375efac5b90deed382)

## configディレクトリのリネーム

* settings.pyが含まれるフォルダの名前を変更する
* manage.pyの中の `os.environ.setdefault` を変更する

## settingsの分割

* settings.pyから共通部分を抜き出してbase.pyとする
* 共通ではない部分をdevelopment.pyやproduction.pyとする
* development.pyやproduction.pyに `from .base import *` を記述し、共通部分を読み込むようにする
* manage.pyの中の`os.environ.setdefault`を変更する

## Djangoサーバー起動時の設定ファイル指定方法

`--settings`で切り替える。
```
python manage.py runserver 0.0.0.0:8000 --settings=config.settings.production
```

# AWSで動かす場合の注意点

## 起動時は --daemon をつける

`--daemon` をつけないとEC2インスタンスにアクセスしているterminal（teratermなど）のプロセスを落とした瞬間にサーバー側のプロセスも落ちてしまう。

```
gunicorn config.wsgi --bind=0.0.0.0:8000 --env DJANGO_SETTINGS_MODULE=config.settings.development --daemon
```

https://stackoverflow.com/questions/13654688/what-is-the-correct-way-to-leave-gunicorn-running


## wsgiファイルにもmysqlライブラリをimportすべし

wsgiファイルにもmysqlライブラリ（pymysqlなど）をimportしておかないと、gunicornから起動する際にmysqlに接続できずにエラーになる。

```
import os
import pymysql
pymysql.install_as_MySQLdb()
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.development')

application = get_wsgi_application()
```

## staticディレクトリを参照する際の注意

### nginxの設定変更

`/etc/nginx/nginx.conf` にstaticの参照設定の追記が必要。
パスを書き込む際 (app name) までの指定でよく、`(app name)/static` までは不要。

```
location /static/ {
             root /home/ec2-user/(app name);
        }
```

設定変更後は nginx の再起動が必要。

```
sudo nginx -s reload
```
[MySQL5.6] rootユーザーの初期パスワード確認方法


`/root/.mysql_secret`に書かれている。

```
[root@hostname ~]# cat /root/.mysql_secret
# The random password set for the root user at Mon Jul 20 16:33:13 2020 (local time): 
g1R3DBjSLM6f3pec
```

```
[root@hostname~]# mysql -uroot -pg1R3DBjSLM6f3pec
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.6.47

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

しかし、

```
mysql> show databases;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
```

新しいパスワードをセットしないと怒られる。

```
mysql> set password for root@localhost=password("root");
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)
```
windows10でNEologdを導入する

#はじめに
既存の辞書ではまともに使えないのでNEologdを導入してみることにしたのだがどうにも上手く行かなかった。
とりあえず導入できたので記録する
##環境
python3.7
windows10
#参考
>https://qiita.com/zincjp/items/c61c441426b9482b5a48
gitを使わない方法で一番わかりやすいのはこの方法だった
導入できたはずなのだがどうにも辞書が反映されなかったので諦め

#できた方法
##以下の方法を参考
>https://mana.bi/wiki.cgi?page=%B7%C1%C2%D6%C1%C7%B2%F2%C0%CF%B4%EFMeCab#p6

本文にも書いてあるけど一応説明すると
- 有志が作ってくださったコンパイル済みのzipをDL、展開
- MeCabの辞書フォルダに移す
- 辞書の変更をmecabrcというファイルをメモ帳等で開いてpassを書き換え（コピペしてドンでOK）

こんだけ

#実行
```python:test.py
import MeCab
mecab = MeCab.Tagger(r"-Ochasen")
print(mecab.parse("進撃の巨人の発売日だ"))

進撃の巨人   シンゲキノキョジン       進撃の巨人   名詞-固有名詞-一般              
の       ノ       の       助詞-連体化          
発売日     ハツバイビ   発売日     名詞-固有名詞-一般              
だ       ダ       だ       助動詞     特殊・ダ    基本形
EOS
```
進撃の巨人がちゃんと認識できている
#おわり
VBAでIE操作した時にjavascript:alert()で止まる問題を乗り越える

VBAからIE操作してて、HTML上のボタンクリックでjavascript:alert()が表示されるとalert()を手動で閉じるまで、マクロの実行が停止してしまう問題。

調べても非同期がいいらしいということしか見つからず苦労したので答えをメモ書き。

```vb:ie.xlsm
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As LongPtr

'～中略～

Dim IE As InternetExplorer
Set IE = New InternetExplorer

'～中略～

'非同期でid:submitのボタンクリック
IE.document.Script.setTimeout _
        "javascript:document.getElementById(""submit"").click()", 1000
      
Sleep 1000
        
'IEをアクティブにする
SetForegroundWindow IE.hWnd
        
Sleep 1000
        
'Enterキー入力
SendKeys "{ENTER}"
```

* 注意点
    * wait入れるために `Do While IE.document.ReadyState <> "complete" `とかやるとcompleteにならないので止まる。= Sleep等でwaitを入れる。
    * アクティブ～キー入力までの間に、手動で他のウィンドウをアクティブにするとうまく動かない。＝裏でマクロ動かしつつ、並行して手作業はしないほうが無難。
PHPを使ったページネーション(ページング)を習得したので記録しておく

#PHPを使った恐らく1番簡単なページネーション(ページング)を習得したので記録しておく
今回は複数の画像を表示することを想定。
一部分を抜き出してきたためやや分かりにくいがメモ程度に。
$_GET取得です。
デザインしやすいようリストを使用。

```php
  //ページネーション設定
  $perPage = 6;//最大表示画像数
  $imgs = count($img);//画像数をカウント
  $maxPage = ceil($imgs / $perPage);
  
  if (!isset($_GET['page'])){
    $page = 1;
  } else {
    $page = (int)$_GET['page'];
  }
　
  $startNo = ($page - 1) * $perPage;
  $img = array_slice($img, $startNo, $perPage, true);


  //ページネーション表示
  if ($page > 1) {//最初以外のページにいる場合は最初のページをリンク表示
    print('<li><a href="./index.php?page=1"><< first</a></li>');
  } else if($page == 1){//最初のページにいる場合は表示しない
    print('');
  }
　//全ページをリンク表示
  for ($i = 1; $i <= $maxPage; $i++) {
    if ($i == $page) {//閲覧中のページはリンクなし
      print('<li>'.$i.'</li>');
    } else {//それ以外のページはそのページへのリンクを貼る
      print('<li><a href="./index.php?page='.$i.'">'.$i.'</a></li>');
    }
  }

  if ($page < $maxPage) {//最後以外のページにいる場合は最後のページをリンク表示
    print('<li><a href="./index.php?page='.$maxPage.'">last >></a></li>');
  } else if($page == $maxPage){//最後のページにいる場合は表示しない
    print('');
  }
```
CSS部分はこんな感じで中央寄せのページネーション。

```css

a{
  color: yellow;
  text-decoration: none;
}

li{
  color: white;
  list-style: none;
  text-align: center;
  padding: 16px;
  display: inline-block;
}
nodebrew使ってColorfulbox(レンタルサーバー)にNode.jsをインストールする

#参考記事

### XSERVER(エックスサーバー)にNode.jsをインストールするときはnodebrew使うと楽
https://qiita.com/yni17196791/items/f49b3e2f683cd06b3120
### Mac > node.jsをインストール
https://qiita.com/sugasaki/items/ad4d5d88965057840a04

#やってみる

```
$ wget git.io/nodebrew
$ perl nodebrew setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
```

確認

```
$ nodebrew -v
$ nodebrew install-binary stable
$ nodebrew ls
$ nodebrew use v8.7.0
```

```
$ node -v
```
Pythonで、いま実行中の関数名をPrint

何がしたかったか
-------------------------
関数には、可読性を高めるため、パッと見てどういう機能か分かる名前付けを意識しています。
となると、デバッグ等の際に、動いている関数名を取得して*Print( )*すれば、「**いま何をしてるか**」を見える化できると思いました。
いちいち毎回、「**今、こういった処理をしています**」を記述せずとも、「**今、{ }を動かしています**」とテンプレ化してしまいたい、ということです。

プログラム
-------------------------
*inspect*モジュールを使います。

```rb
import inspect

def add_values(a, b):
    cframe = inspect.currentframe()
    fname = inspect.getframeinfo(cframe).function
    print("Running '{}' function on {} and {}".format(fname, a, b))
    return a + b
    
add_values(1, 2) 
```

出力は：

```rb
Running 'add_values' function on 1 and 2
3
```

参考
-------------------------
[How can get current function name inside that function in python]
(https://stackoverflow.com/questions/33162319/how-can-get-current-function-name-inside-that-function-in-python)
EclipseでJavaFxを使う[Mac](最新版)

# EclipseでJavaFxを使う方法を紹介します。

まずはじめにJava11以降JavaFxはJDKに含まれなくなっているためEclipseでJavaFxを使用するのは初心者にとって簡単なことではありません。
解決策としては、OpenJFKからJavaFXのライブラリを拾ってくるか、 JavaFxを組み込んだJDKを使う必要があります。
ここでは後者のJDKを組み込む方を紹介していきます。

ここまで、かなり難しく聞こえるかもしれませんが、簡単なステップでできますので、是非最後までお付き合いください。

まず初めに、JavaFXを組み込んだJDKをダウンロードします。

https://jp.azul.com/downloads/zulu-community/?version=java-11-lts&os=macos&architecture=x86-64-bit&package=jdk-fx

こちらのサイトからダウンロードを行ってください。場所はどこでも良いです。
JavaPackageがJDKFxになっていることを確認してください。


次にEclipseを起動してください。
マウスを画面のトップにもてくると、一番左にりんごマークがある、メニューバーが出てくると思います。
そのりんごマークの隣の Eclipseを選択し、その中にある Preferences.を選択してください。
すると設定のウィンドウが出てくるかと思います。
フィルター入力というところに「jre」と入力して、インストール済みのJREを選択してください。

さらに左の追加=>標準VM=>次へ=>ディレクトリから先ほどダウンロードしたファイルを選択してください。
JRE名はなんでも良いです。設定したら、完了を押して、
インストール済みのJREのところで、今登録した名前を選択して「適応して閉じる」を押してください。

最後にプロジェクトのJDKを設定して終了です。

先ほどと同様にマウスを一番上に持っていき、ツールバーを表示させます。
今度はプロジェクト=>プロパティーを選択してください。
左の欄から、「JavaJavaコンパイラー」=>「Javaのビルドパス」を選択してください。

そして、右の画面の方のライブラリを選択してください。
モジュールパスの中にあるものを選択し、「編集」を選択して、代替JREの方から、先ほど追加したJREを選択して完了=>適用して閉じるをしてください。

そしたら、全て完了です！
Xilinx Zynqのブートシーケンスを、USBロジックアナライザとジャバスクリプトを使って確認する

新しいXilinx Zynq SoCシステムの開発過程では、ハードウェアの仕様を理解し、シグナルのタイミングをみることが重要である。残念ながら、ブートシーケンス内のQSPIのトランザクション速度の仕様は、明らかでない場合もある。Digilent Digital DiscoveryとHigh Speed Adapterシステムでは、100 MHz以上のはるかに速いクロック速度で起こるQSPI伝送を可視化できる。Digital Discoveryは512 MB DDRを搭載しているため、非常に大規模な収集を実行することが可能だ。そのため、エンジニアや開発者はブートシーケンスを可視化し、タイミングを特定することができる。

Digital Discoveryは、USBロジックアナライザ（USB Logic Analyzer）であり、プロトコルアナライザ（Protocol Analyzer）であり、またパターンジェネレーター（Pattern Generator）でもある。デジタル入力と出力は、単純なワイヤプローブまたはブレッドボードワイヤを使えば回路に接続することができる。あるいは、より高度なプロジェクト向けに、Digital Discovery High Speed Adapterとインピーダンス整合されたプローブを使い、入力と出力をつなげて利用することも可能だ。

Digilent ZYBO Zynq SoCプラットフォームのフラッシュメモリのブートシーケンスを見てみる。まず初めに、SOICクリップを使ってQSPIシグナルを取り出し、Digital Discoveryのロジックアナライザに取り込む必要がある。

![digitaldiscovery_zyboz7-demo-2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616703/f5881678-43ce-eb96-8e1d-2942ba318292.png)


次に、ジャバスクリプトを使ってデバッグテストを作成し、WaveFormsで信号をデータに変換する。これを行うには、Click to Add Channels -> Custom in the Logic Analyzerを選択する。

![WaveForms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616703/7624b191-54e5-949a-5b2d-debdcd8a6d91.png)

![WaveForms Logic Analyzer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616703/a0d7696c-6e3f-2829-0fa5-229092949915.png)

![WavForms Logic Analyzer Add Custom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616703/3872c0ea-60b7-743f-1864-0993e381068b.png)

Digilent ZYBOをオンにすると、指示がZynqからフラッシュメモリに送られる。その後、ロジックアナライザでブートシーケンスを可視化できる。アプリケーションノートは、Digilent Wikiで入手が可能だ。(https://reference.digilentinc.com/learn/instrumentation/tutorials/zynq-qspi-boot/start)
Nginx + Let's Encript

# SSL導入
自前でブログを立ち上げ、SSLを導入しました。

### 環境
- Nginx
- Let's Encript

### 証明書の取得

```
/usr/local/certbot/certbot-auto certonly --standalone -d [ドメイン名] -m [adminメールアドレス] --agree-tos -n
```

### Nginxの設定
```
server {
     ・
     ・
     ・
    listen       443 ssl;
    server_name  localhost;
    ssl_certificate     /etc/letsencrypt/live/www.rosyoki.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.rosyoki.com/privkey.pem;
     ・
     ・
     ・
```

### Nginxの再起動
```
# systemctl stop nginx
# systemctl start nginx
```
※CenbtOS7の場合です。

### 参考
- [Let's Encrypt で Nginx にSSLを設定する](https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9)
オンプレからAWSに移行した話

もう一年以上前の話ですが、エキサイトのWisteriaをAWSに移行した話を書こうと思います。

## Wisteriaとは
機械学習を使ったコンテンツレコメンドのシステムです、[紹介ページ](https://www.excite.co.jp/guide/wisteria/)

## システム構成
移行前のシステム構成はこんな感じ、MLの部分が重いのでキューの仕組みを入れて処理をしていました。
![wisteriaシステム構成 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525769/5f083cb0-aef2-0b95-2f36-16844f9bf380.png)

## 移行前の課題
- openstackが暴走する
- cassandraが安定しない
- zookeeperのファイルがよく壊れる
- stormがうまく立ち上がらない
- 色んなミドルウエアのバージョンが古い
- 障害時にサーバーが多すぎて、原因の特定が難しい（ログが色んな場所に点在）、zabbixも入れているがそれだけでは追いきれない

会社ではDevOpsが推奨されていたので、サーバー周りもアプリケションエンジニアが見ないといけない、3ヶ月に一度は障害が起きていたのでしんどい

## 移行の計画
オンプレでは運用上の色んな問題があり、せっかく移行するので問題を解決しつつ、クラウドに最適化した形で運用のコストを下げたいと言う思いがありました、そこで考えたプランは３つ

- プランA （色々最適化）
 - Front / Api / Tool / Batch はコンテナ(ECS)
 - MySQLはAurora
 - CassandraはDynamoDB
 - Kafka、StormはKinesis、Lambda
 - AutoScale、自動Deployなど
 
- プランB （問題になっている部分をなるべくマネージド）
 - Front / Api / Tool / Batch はEC2
 - MySQLはAurora
 - CassandraはDynamoDB
 - Kafka、StormはMSK、EC2
 - AutoScale、自動Deployなど

- プランC （ほぼ何もせずそのまま移行）
 - Front / Api / Tool / Batch / Cassandra / Kafka、Storm はEC2
 - MySQLはAurora
 - AutoScale、自動Deployなど

移行期間が2ヶ月と言うこともありプランAは現実的に無理、頑張ればプランBで行けるかもしれないということでプランBで行くことにしました。

## メンバー構成
初期メンバーは3名+途中から1名追加になり計4名で行いました、分担は以下の通り

- EC2を構築してアプリケーションを移行するメンバー
- CassandraをDynamoDBに移行するメンバー
- Kafka、Stormを移行するメンバー
- その他は手が開いた人がやる
 
みんなクラウド移行はほぼ初めてだったので、実際に移行を始めるといろんな問題が発生することになった

## 移行
### EC2編
オンプレ時代からansibleで構成管理していたので、スムーズにくと思っていたが…

- OS古い問題
   - Ubuntu16を使っていたがサポートが2021年で切れるため、やもなくUbuntu18へアップデート

　→ これにより諸々のパッケージのバージョンが上がる、フロント、APIをphpで書いていたので、アプリケーションのテスト工数が膨らむ、やもなくphpだけダウングレード

### Kafka/Storm編
- バージョンがあまりにも古い問題
 - Stormのバージョンがv0.9.xだったので、ec2でもこのバージョンをインストール、Amazon MSKと連携してみたが全くうまくいかない
 
　→ チーム内で協議
　①stomのバージョンをあげてMLのソースを書き直す
　②MSKを使わず、kafkaをec2で構築する
　③kafka/stormをやめる
　→ ③を選択し、kinesis/Lambdaにすることにしました。理由は、運用で悩まされていたkafka/stormをやめたかった、将来的にStormをやめるのにソースを書き直すモチベーションがわかないなど

### Cassandra編
- Cassandraのデータ移行に悪戦苦闘
 - マイグレーションツールを使って移行をする予定で進めていたが、Macだとツールが不安定で落ちたり、ツールの使い方も分からなかった部分もあり悪戦苦闘、ようやく進んだと思ったらcassandraとツールのバージョンが合わず、そもそも使えなかったりで１ヶ月溶かす
 
　→ 結局マイグレーションツールを使わず、cassandraのデータをダンプして、データパイプラインで入れることにしました。


## 移行後の構成
そんなこんなで移行後の構成はこうなりました。
![wisteria移行後 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525769/7102030b-7b13-fe69-e293-dfc540c82b4d.png)
当初想定していた構成とは若干異なりますが、ec2以外はマネージドにすることが出来ました。

## 感想
大変な部分もありましたが比較的順調に移行が行えました。
クラウドに移行したことにより、運用で問題になっていた部分もほぼ解消し、安定した運用が行えるようになりました。
費用も半分以下に抑えることができてよかったです。

サーバー周りのインフラ的なことから解放され、アプリケーションに専念できることが一番よかったとつくづく思います。
【de:code2020学習記録】2020 年の最新 Xamarin 概要

# はじめに

本稿は、de:code2020の以下のセッションで学んだ内容のメモです。

[【A07】2020 年の最新 Xamarin 概要](https://www.microsoft.com/ja-jp/events/decode/2020session/detail.aspx?sid=A07)

[動画がこちら](https://www.youtube.com/watch?v=X0f-6q59JAE)で公開されました。

# Xamarin 概要

- C# で iOS、macOS、Android向けのアプリを作るためのプラットフォーム
- Uno Pratoform や Mobile Bindings など他のクロスプラットフォームの土台としても使われる
- AndroidやiOSのネイティブのAPIをC#から呼べる
- 画面のネイティブの部品をそのまま利用可能
- iOSを開発するためにはMacのPCが必要
- iOSとAndroidのOSバージョンアップの対応は早い(iOSはOSリリースとほぼ同時、Androidは1ヶ月以内)

# Xamarin.Forms 概要

- C# で iOS、macOS、Android、Windows向けのアプリのユーザーインターフェイスをC#/XAMLで単一のコードで構築可能にしたUIフレームワーク

# Xamarin 新機能

- Android
  - Kotlinで開発されたライブラリのバインディングの改善
  - ダークテーマ対応
- iOS
  - iPad用の複数Windowサポート
  - ダークモード対応
- Xamarin.Forms
  - Shellコントロール(メニュー・タブ・検索ボックスなどのよくある基本機能を提供するコントロール)
  - Visual(コントロール全体の見た目を一気に変更できる、組み込みでマテリアルデザインを提供)
  - CollectionView(ListViewを置き換えるコントロール)
  - Gifアニメーションのサポート
  - C# Markup Extensions(Xamalを使わずC#だけで画面を作る)
  - Hot Reload(Xamalの変更時に即座にデバッグ中の画面に反映)

# 所感

Xamarinの最新情報をたくさん知れたので、とても有意義なセッションでした。

ちなみに、私はLT初心者が集まるコミュニティとして「Serverless LT 初心者向け」というコミュニティを運営しています。
[Serverless LT 初心者向け - connpass](https://serverlesslt.connpass.com/)

Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)
【備忘録】Missing host to link to! Please provide the :host parameterが出た

####自作アプリRailsチュートリアル方式でログイン機構とパスワードリセット機構を実装した時の話です。
11章のaccount activation機能を無視して12章を進めていました。

具体的にリスト12.10まで進めたところで、試しに再設定用ページからメール送信ボタンをクリックしたところ、
タイトルのエラーが出てしまいました。

```
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
```
「ホストへのリンクがないよー」といっているのはわかりますが、そのホストとは何のことを指しているのか全くわからなかったためググったところ、テストメールに使うドメインホストが抜けてるとのことでした。

```config/environments/test.rb
config.action_mailer.default_url_options = { host: 'example.com' }
```
（※実際のホスト名は自作アプリ向けに変えてます）
でいけました！ここ１１章できちんと説明されているのに飛ばしたからハマってしまいました...。


今回に限らず別のところでもよくハマるのですが、railsでアプリを作成するのに何が足りないとかなぜそのエラーがでてしまうのか、そのエラーは何を意味しているのか理解するのって難しいですね。