OmniAICreator/Qiita-1.07M huggingface dataset:
Aeのマットについて真剣に考える日

#マットは使える
・画面の好きなところから登場させる
・Psにある「クリッピングマスク」みたいなもの

#(1) トラックマット

・**Bodymovin出力でも再現できる**
・タイムラインで操作できるがデフォルトの状態では表示されていないときもあるので
　左下のアイコンをブルー(アクティブ)にする
![スクリーンショット 2019-12-12 12.18.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/73e62079-bd66-b0bf-6f2f-b0c07e776241.jpeg)
基本構造
<img width="767" alt="スクリーンショット 2019-12-12 12.44.57.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/9be87ff0-e3fc-d801-479b-9a0eda5b1e47.jpeg">


#(2) エフェクト＞チャンネル＞マット設定

・**Bodymovin出力で再現されない**
・(1)の方法ででやれなくもなさそうだが
　隠す範囲にアニメーションなどを付与したい場合など結構大変かも

基本構造
<img width="748" alt="スクリーンショット 2019-12-12 12.57.03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/644d44c9-821d-446b-cd46-1fa85101bdc3.jpeg">
<img width="352" alt="スクリーンショット 2019-12-12 12.57.14.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/a69a398a-dd09-1480-a58a-c7a2d583df69.jpeg">
![IMG_5660.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/1da311a4-d73e-9dc9-d6cd-d11e071adbca.jpeg)
NestJS Response ヘッダー 変え方

この記事は NestJS Advent Calendar 2019 11日目の記事です。前日は [@euxn23](https://qiita.com/euxn23) さんによる「NestJS 循環参照」の予定でしたが、都合により遅れるとのことです。かくいう私も担当の日付を勘違いしていて、1日遅れの投稿となってしまったことをお詫び申し上げます。
本日は NestJS においてレスポンスのヘッダーを変える方法について紹介します。 
## Content-Type を変更する
特定のエンドポイントだけ返すコンテンツの種類が異なり、特定の Content-Type を設定したいなどのシチュエーションは往々にしてあると思います。
今回は例として、NewsController というコントローラ以下の feed という関数の担当するエンドポイントに対して、RSS フィードの Content-Type である `application/rss+xml; charset=UTF-8` を設定する方法を例に解説したいと思います。
これの要件に対し、NestJS では2通りの解決方法があります。
### `@Header` デコレータを用いる方法
NestJS では、コントローラ内のエンドポイントに対して `@Get`, `@Post` と同様に `@Header` というデコレータを用いることによってヘッダーの特定プロパティの返り値を上書きすることができます。
以下の例ではエンドポイントが返すレスポンスのヘッダーが常に `application/rss+xml; charset=UTF-8` になります。

```ts
import { Controller, Get, Header } from '@nestjs/common';

@Controller('news')
export class NewsController {
  @Get('/feed')
  @Header('content-type', 'application/rss+xml; charset=UTF-8')
  feed(): string {
    return feedContent;
  }
}
```

ただしこの方法を用いると、**関数内でエラーが発生しエラーレスポンスが json で返されたとき**も指定した Content-Type で上書きされてしまいます。
### Response オブジェクトに設定する方法
こちらは関数の引数として Response オブジェクトを受け取り、それに直接 Content-Type を設定する方法です。Express などを既に使ったことがある方にはおなじみの方法ではないでしょうか。
以下の例ではエンドポイントが返すレスポンスのヘッダーが生成処理の成功時のみ `application/rss+xml; charset=UTF-8` になります。

```ts
import {
  Controller,
  Get,
  Res,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { Response } from 'express';

@Controller('news')
export class NewsController {
  @Get('/feed')
  async feed(@Res() res: Response) {
    try {
      // RSS フィードを生成する関数が存在すると仮定
      const generatedFeed = await feedGenerator.generate();
      res.set({
        'content-type': 'application/rss+xml; charset=UTF-8',
      });
      res.send(generatedFeed);
    } catch (error) {
      throw new HttpException(
        'Internal server error',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}
```

ただ、上記コードを見てもらえばわかるように、NestJS では引数として受け取った部分をハンドリングしてやる必要があります。
今回は Response オブジェクトをヘッダーの設定のために呼び出しているので、そのオブジェクトに対して**レスポンスを設定する部分まで面倒を見る必要があります**。
デコレータで設定したときのように return でレスポンス内容を返してもタイムアウトしてしまう点に注意が必要です。

## おわりに
本日の記事では、NestJS においてレスポンスヘッダーを書き換える方法を、設定したシチュエーションに合わせて2通りの手法で紹介しました。

明日の担当は [@euxn23](https://qiita.com/euxn23) さんです。
【Rails】Rails g devise 〇〇でin `block in load_missing_constant': uninitialized constant User (NameError)が出てきた時の対処法

#現象
Userモデルを作成するため、

```
rails g devise User
```
上記コマンドを入力。
ところが

```
/Users/hogehoge/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/active_support.rb:79:in `block in load_missing_constant': uninitialized constant User (NameError)
```
というエラーが出てきた。

# 原因
すでに下記のようにroutes.rbにdevise_for :usersというコードを入れており、ルーティングおかしくなってrailsコマンドがうまくいかなかった。

```config/routes.rb
Rails.application.routes.draw do
  devise_for :users
  root 'top#index'
end
```

#解決策
config/routes.rb内の devise_for :usersを一旦消して、rails g devise Userをするとエラーが出ずに、Userモデルを作成できた。

参照
https://happy-teeth.hatenablog.com/entry/2018/07/21/163123
https://qiita.com/imotan/items/c73fab5ee230114a08b6
ようやくメダル取れそうなので、初心者の頃からの振り返り【Kaggle】

# はじめに
　[kaggleのタイタニックコンペで0.808](https://qiita.com/yuya-8/items/4e4eaed43698ec5280fd)という記事を書いてから８ヶ月ほど経ちました。

　まだ確定ではないのですが、NFLコンペのFinal submission deadline時点で2038チーム中189位でギリギリ銅メダル。

　答え合わせの2/4が終わった今の時点で少し順位が上がって125位(12/12現在)です。本当は順位が確定してからがよかったのですが、Advent Calenderのネタがなかったので書かせていただきます...
<img width="992" alt="スクリーンショット 2019-12-12 11.16.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401707/f1f30217-fe77-fadc-2b6c-a5e51ffb99e4.png">

（追記）　順位が確定し、118位で銅メダルを取ることができました！！

　世の中には初参加のコンペでメダルを取ってしまう方もいらっしゃるようですが、僕は文系学部2年生のひよっこで、プログラミングも機械学習も0からのスタートであったためか、かなり時間がかかってしまいました。

今回は上記の記事を書いた頃の僕のような方に向けて、Kaggleのコンペにおいて意識した方がいいことについて綴りたいと思います。

# 結論
**• わかりやすいカーネルを選ぶ**

**• 過去のコンペを参考にする**

**• 一次情報を得る**

一つ一つ説明していきます。
## わかりやすいカーネルを選ぶ
　おそらく、ベースラインを作成するときにはカーネルを参考にすると思いますが、その選び方についてです。

　カーネルを　sorted by して　Most Votes で選んでる方は大方間違い無いと思いますが、Best Score　で選ぶのはやめた方がいいです。

　Best Score で選ぶと、いきなり上位にいけるので魅力的ではあるのですが、なぜその特徴量なのか？とか、そもそもプログラムで何をしているのかわからないということになってしまって、そこからスコアが伸びずらくなってしまいます。

　一連の流れを理解できるようなカーネルを選んでから、自分なりに特徴量を足すなどの工夫をしていった方がいいです。classとかいきなり大量に定義されても正直わからないですよね...

## 過去のコンペを参考にする
　そもそも、上位陣の方達と僕らの違いを決定づけるものはなんでしょうか？

それは経験(Kaggleの過去のコンペ、仕事)です。

仕事の経験はどうにも埋めがたいのですが、彼らの今までのコンペ経験というものは、過去のコンペの上位陣のSolutionを読むことなどで多少は補えると思います。

　というのも、今回のNFLコンペでは、Transformer ?という手法が有効だったようですが、僕はその存在自体を知りませんでした。少し前のコンペで話題になっていたようなので、過去の似たような位置情報を含むデータのコンペを漁っていればと反省してます。

　この反省もあり、このコンペの復習は丁寧にしました。

## 一次情報を得る
　これは僕の成功体験でもあるのですが、一次情報は頑張って集めた方がいいです。

　特に僕のようなモデルの実装力が無い人は特徴量で差を付けるしか無いので、重要な部分だと思います。同様にEDAも重要ですね。

　実際に僕もNFLコンペに取り組んでいるときはアメフトのプレイ動画を見まくり、スペースが重要なんじゃね？とか、結局ボール持ってる人の優秀さだよなーとか思って特徴量づくりをしました。

# おわりに
　色々と書いてしまいましたが、やっぱり楽しみながらやるのが一番ですよね！
僕ももっと精進して、まずはKaggle Expertになりたいと思います！！
OneSignalで管理画面からUserを削除してしまった際にRestAPIで400が出続ける際の対応法


PWA Advent Calendar 2019 12日目の記事です。

PWAというよりもOneSignalがメインの記事です。
OneSignalでUserを削除した際の対応方法の話です。

# 結論

cookieを消す

## はじめに

OneSignalで管理画面からUserを削除して、その後RestAPIで独自タグを設定しようとすると
`400 Bad Request: Put "https://onesignal.com/api/v1/player/${playerid}" `
こんな感じの400エラーが出る。

試しに別の端末から同じ操作をしたら普通に登録できた。
OneSignalで管理画面からUserを削除するとどうも同じplayeridからリクエストを受け付けてくれないっぽい。

色々考えたて、OneSignalの公式ドキュメントを読むと
[Audience](https://documentation.onesignal.com/docs/users#section-when-does-the-onesignal-player-id-change-)

```
When does the OneSignal Player Id change?
OneSignal makes a best effort to keep the same Player Id on all devices that are assigned. Some circumstances that may cause it to change:

WEB PUSH - When the user clears their cookie data for your site.

ANDROID - If the user has opted out of the Google Advertising Id, uninstalls the app and re-installs.

iOS - If the user does not have any other apps installed that have your IFV (identifierForVendor), then uninstalling your app and re-installing it, will give them a new Player Id.

The IFV is used to keep the ID the same after a full re-install, but only if the user has another one of your apps installed.
```

cookieを消せばいいとのこと。

そしたらば、`400 Bad Request: Put "https://onesignal.com/api/v1/player/${playerid}" `
が出ずに独自タグ設定できるようになりました。


管理画面からUserを削除するのは基本的にやらないほうがいいですね。
パスワードが合っているのにエラー(Access denied for user 'root'@'localhost' using password: YES)


自分がlaravelの勉強していて何日も詰まった部分がありましたのでここで共有します。

mysqlのログイン方法先はいくつも存在していたということです。


1.コンピューター名:~ ユーザー(普段の表示)
2.vagrant ssh=の環境から入る方法

これらは別々でログイン後、DBやユーザーの存在は違うので初心者の方は要注意です。

つまり1.2.どちらにも同じDB名のtestを作ったとしたら接続したいDBの方で接続しなければタイトルの用なエラーとなります。



1.

```
rooter:my_slim ユーザー名$　mysql -u root
```

2.

```
[vagrant@localhost ~]$ mysql -u root
```
【Ruby】merge, merge!

#mergeメソッドについて
2つのハッシュを統合するレシーバhashと引数other_hashのキーと値を集め、新しいハッシュに入れて返す。重複するキーが有るときは、ohter_hashの値が使われます。

```
image1 = { :src => "monkey.jpg", :alt => "monkey" }
image2 = { :width => 320, :height => 240 }
image3 = image1.merge(image2)
puts image3[:src], image3[:width]
```

```
monkey.jpg
320
```

### 使い方
```
hash.merge(other_hash) {|key, oldval, newval| block }
GCPのIAMロールまとめ

*本記事の目的
GCPのIAMロールを理解しづらいだったため、自分の理解を整理する*

GCPのサービス利用権限はIAMロールで決められる。
個別アカウントにロールを付与して、アクセス権限を管理する。


IAMロールは基本３つタイプがあります。

- Primitive roles（基本の役割）
- Predefined roles（事前定義された役割）
- Custom roles（カスタムの役割）

各種のロールと付与方法は下記でまとめます。


## 1. 　Primitive roles（基本の役割）
基本の役割を使ってアクセス権限管理は一番簡単です。
広い範囲の権限を付与することとなるので、広い範囲のユーザーに付与するのはあまりオススメない。

アカウントにロール付与方法

```sh
# 下記のコマンドを実施するため、オーナー権限必要
# 例：editor権限付与
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member user:[USER_EMAIL] \
  --role roles/editor

# またはowner権限付与
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member user:[USER_EMAIL] \
  --role roles/owner
```

## 2. 　Predefined roles（事前定義された役割）
GCP中に各種サービスごとの事前定義されたロールを個別付与する方法。

必要なサービスを個別に付与する。
例えば、クラウドストレージを利用する場合、「storage.admin」ロールを付与します。

```sh
# storage.admin」ロール権限付与。下記のコマンドを実施するため、オーナー権限必要
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member user:[USER_EMAIL] \
  --role roles/storage.admin
```

各種サービスごとの事前定義されたロールはここでご参考
[https://cloud.google.com/iam/docs/understanding-roles](https://cloud.google.com/iam/docs/understanding-roles)


## 3. 　Custom roles（カスタムの役割）
事前定義された役割の付与方法より、もっと細かい権限設定できます。
カスタムの役割を定義して、必要な権限のみを付与する。
権限追加は必要の時、ロール定義ファイルに追加して、カスタムの役割を更新する必要です。

必要な権限を "custom_role_define.yaml"のファイルをまとめます。

```sh
title: "My Custom Role"
description: "For Test User"
stage: "ALPHA"
includedPermissions:
- storage.buckets.create
- storage.buckets.update
- storage.buckets.delete
- storage.buckets.list
- storage.buckets.get
- storage.objects.list
- storage.objects.get
```

この定義はストレージのバケツ作成とobjects参照権限があるロールの定義です。
カスタムの役割を作成実施

```sh
# カスタムの役割を作成実施。下記のコマンドを実施するため、オーナー権限必要
gcloud iam roles create my_custom_role --project [PROJECT_ID] \
--file custom_role_define.yaml

# 作成できたカスタムの役割を確認
gcloud iam roles describe my_custom_role --project [PROJECT_ID]
```


権限を修正・追加する場合、カスタムの役割の更新を実行する必要です。

```sh
# カスタムの役割を更新実施。下記のコマンドを実施するため、オーナー権限必要
gcloud iam roles update my_custom_role --project [PROJECT_ID] \
--file custom_role_define.yaml
```

それから、ユーザーアカウントにロール付与

```sh
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member user:[USER_EMAIL] \
  --role projects/[PROJECT_ID]/roles/my_custom_role
```

<br>
ご覧して頂き、どうも有難う御座います!
DSS Ben
gzファイルにgrepかけよう!

UNIX ライクなシステムにおいては, gzip (gz) で圧縮されたファイルを目にすることが多いです.
それらのファイルに検索したいときと思ったとき, どうするか.

`zgrep` コマンドを使います. 
たいていのUNIX/Linuxディストリビューションにおいて, 標準で使える機能です.

```shell
$ zgrep -nH "KEYWORD" FILENAME
```

ところで, いくつものファイルがgz圧縮されていることがあります.
ログファイルなど.

ふつうのテキストファイルが複数あるような場合には, grepコマンドを用いた検索,
`grep -rnHI "KEYWORD" DIRECTORY` で対応できます.

しかし, zgrepファイルには, `-r` オプション (再帰探索?) がない.

どうするか.

find/xargs コマンドを組み合わせて解決しましょう.

```shell
$ find DIRECTORY -type f -name "*.gz" -print0 | xargs -0 zgrep -nH "KEYWORD"
```

ここでは理由を割愛しますが,
findコマンドの `-print0` と xargsコマンドの `-0` はあってもなくてもいいですが,
つけておいたほうが無難です.
【備忘録】コンピュータの性能などを調べる

#Windows10で性能を調べる#
##OS, CPU, RAMを確認##
「コントロールパネル」を開いて, 「システムとセキュリティ」をクリックです.

![コントロールパネル.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/e35df36b-3c4a-08e9-0a6f-30896dd5f36e.png)

いろいろ出た中の「システム」をクリックします.

![システムメニュー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/4380fd23-cef9-f7e9-e0a1-3ff99f7f5044.png)

無事確認できました!

![システム性能.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/fbc211ce-cce5-40f9-6359-c89d78e0e7e4.png)

##ストレージを確認##
「設定」→「システム」→「ストレージ」で確認できる(雑)
[もっとわかりやすいページはこちら](https://pc-karuma.net/windows-10-storage-spaces/)

##RAMとかROMってなんゾってなったらこちら##
[パソコンのスペックを確認する](https://www.pc-master.jp/sousa/s-spec.html)
[知らないと恥ずかしい？　メモリの「RAM」と「ROM」の違い](https://www.itmedia.co.jp/news/articles/1706/01/news051.html)

##IPアドレスとMACアドレスを調べる##
コマンドプロンプトで`ipconfig /all`を入力
ネットワーク関係の情報がいろいろ出てくる
MACアドレスは物理アドレスのこと
[もっとわかりやすいページはこちら](https://www.atmarkit.co.jp/ait/articles/0109/29/news005.html)
Bind call and apply


They are functions which function objects have. 
Allows you to create preset function with arguments. 

- Call: Allows you to set *this* variable.
- Apply: Similar to call but expects arguments as an array.
- Bind: Also allows you to set the *this* variable. However, it does not execute the function immediately but generates a copy of the function which can be stored.

```JavaScript
var john = {
  name: "John",
  age: 26,
  job: "Teacher",
  presentation: function(style, timeOfDay) {
    if (style === "formal") {
      console.log(
        "Good " +
          timeOfDay +
          ", Ladies and gentlemen! I'm " +
          this.name +
          ", I'm a " +
          this.job +
          " and I'm " +
          this.age +
          " years old"
      );
    } else if (style === "friendly") {
      console.log(
        "What's up? My name is " +
          this.name +
          ", I'm a " +
          this.job +
          " and I'm " +
          this.age +
          " years old"
      );
    }
  }
};

var emily = {
  name: "Emily",
  age: 35,
  job: "designer"
};

john.presentation("formal", "morning");

john.presentation.call(emily, "friendly", "afternoon");

// This is currying
var johnFriendly = john.presentation.bind(john, "friendly");

johnFriendly("afternoon");
```

## Currying ##
Creating a function from another function but with some preset parameters.
hello world!を出力する ❏Vue.js❏

まずはここからですよね！
HTMLやRubyを初めて学習した時のことを思い出します。感慨深い。

開発環境は`JSFiddle`を使います。
参考はこちら
https://qiita.com/ITmanbow/items/9ae48d37aa5b847f1b3b

<br>

```html:html
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <p>
    {{ message }}
  </p>
</div>
```

```javascript:javascript
new Vue({
  el: "#app",
  data: {
    message: "hello world!"
  }
})
```

【出力結果】
`hello world!`

![ダウンロード (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529651/7cb8cab9-98dd-aa9f-4e0a-7254ba8bfad0.png)


#解説
１：`CDNでVue.jsを読み込む`
公式サイトのインストールの項目に載っているのでコピペ

２：`idをつける`

３：`new Vueでインスタンスを宣言`

４：`el: "#app"で指定`

５：`dataの中にプロパティを書く`
今回はmessage: "hello world!"

６：`二重中括弧で表示したいものを囲う`
{{ message }}

<br>
無事`hello world!`が表示されました！
感動。。これから新たな旅がハジマル〜！！

<br>
ではまた！
Rails6 のちょい足しな新機能を試す111（uniqueness validation with belongs_to編)

# はじめに

Rails 6 に追加された新機能を試す第111段。 今回は、`uniqueness validation with belongs_to` 編です。
Rails 6 では、 `belongs_to`, `has_many` の関係があるModel で、 `uniqueness` 制約がある場合に `save!` メソッドで例外が発生しないバグが修正されました。
(なお、 後述しますが、 `accepts_nested_attributes_for` を組み合わせた場合のバグは修正されていません。)

Ruby 2.6.5, Rails 6.0.1 で確認しました。 (Rails 6.0.0 で修正されています。)

```shell
$ rails --version
Rails 6.0.1
```

今回は、Author モデルと Book モデルを作って、スクリプトで動作確認してみます。

# Rails プロジェクトを作成する

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# Author モデルを作る


```shell
$ bin/rails g model Author name
```

# Book モデルを作る

Book モデルを作ります。 Book は、 `title` と `isbn` と `Author` モデルへの参照を持つようにします。


```shell
$ bin/rails g model Book title isbn author:references
```

# Author モデルを修正する

Author モデルに `has_many` を追加します。

```ruby:app/models/author.rb
class Author < ApplicationRecord
  has_many :books, dependent: :destroy
end
```

# Book モデルに validation を追加する

Book モデルに `uniqueness` の Validation を追加します。 `uniqueness` であることが重要です。

```ruby:app/models/book.rb
class Book < ApplicationRecord
  belongs_to :author

  validates :isbn, uniqueness: true
end
```

# スクリプトを作成する

Author と Book のデータをDBに保存するスクリプトを作成します。uniqueness 制約にひっかかるように、Book は2件作成します。

```ruby:scripts/save.rb
author = Author.new(name: 'Dave Thomas')
author.books.build(title: 'Pragmatic Programmer', isbn: '123')
author.books.build(title: 'Agile Web Development with Rails 6', isbn: '123')
author.save!
p author.persisted?
```

# DB マイグレーションを実行する


```shell
$ bin/rails db:create db:migrate
```

# スクリプトを実行する

スクリプトを実行します。 `ActiveRecord::RecordInvalid` が発生します。

```shell
bin/rails runner scripts/save.rb
...
/usr/local/bundle/gems/activerecord-6.0.1/lib/active_record/autosave_association.rb:419:in
`block in save_collection_association': Validation failed: Books is invalid (ActiveRecord::RecordInvalid)`
```

# Rails 5では

エラーにならず、保存されてしまいます。

# 補足1

`uniqueness` 以外の validation では、Rails 5 でも Rails 6 でも例外が発生します。

# 補足2

`Author` モデルに、 `accepts_nested_attributes_for :books` を追加すると、例外が発生しなくなってしまいます。
(`uniqueness` 以外の validation では、例外が発生します。)

この事象については、既存の [issue が見つかりました](https://github.com/rails/rails/issues/20676)。

```ruby:app/models/author.rb
class Author < ApplicationRecord
  has_many :books, dependent: :destroy
  accepts_nested_attributes_for :books # https://github.com/rails/rails/issues/20676
end
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try111_save_with_associated

# 参考情報

* [Fix: ActiveRecord::RecordInvalid is not raised when an associated record fails to #save! due to uniqueness validation failure](https://github.com/rails/rails/pull/36210)
* [accepts_nested_attributes_for breaks the uniqueness with scope validation](https://github.com/rails/rails/issues/20676)
YAML のタグ (!Ref など) を Ruby で扱う

AWS の CloudFormation ではリソースの管理を YAML でできるんだけど、そこでは下記のような記法が使える。


```yaml
# See: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
InstanceId: !Ref ApplicationServer
```

この `!Ref` のように `!` で始まる文字列は YAML の仕様にある[タグ](https://yaml.org/spec/1.2/spec.html#id2761292)と呼ばれるもので、値の型を示すために使われる。
しかし、このような YAML を Ruby の標準ライブラリで読み込むとタグの情報は抜け落ちてしまう。

```ruby
require "yaml"
yaml = "InstanceId: !Ref ApplicationServer"
parsed = YAML.load(yaml)

pp parsed
# {"InstanceId"=>"ApplicationServer"}

puts parsed.to_yaml
# ---
# InstanceId: ApplicationServer
```

YAML でタグを扱う方法を調べてみた。

## YAML.add_domain_type
タグ付きの値を特定のクラスのオブジェクトとして読み込むだけならこれが楽そう。
下記は `!Ip` タグをつけた文字列を IPAddr オブジェクトとして読み込む例。

```ruby
require "yaml"
require "ipaddr"

YAML.add_domain_type("", "Ip") do |type, value|
  IPAddr.new(value)
end

yaml = "ip: !Ip '127.0.0.1'"
parsed = YAML.load(yaml)
p parsed["ip"]
# #<IPAddr: IPv4:127.0.0.1/255.255.255.255>
```

ただし、これを dump すると普通に Ruby オブジェクトを dump した場合と同じになり、元のかたちにはならない。

```ruby
puts parsed.to_yaml
# ---
# ip: !ruby/object:IPAddr
#   family: 2
#   addr: 2130706433
#   mask_addr: 4294967295
```

dump した場合の挙動を変更したい場合は値のクラスに `encode_with` インスタンスメソッドを定義する。

```ruby
class IPAddr
  def encode_with(coder)
    # 第 1 引数はタグ、第 2 引数は値
    # 値がスカラーなので represent_scalar メソッドを使っている
    # リストなら represent_seq、マップなら represent_map を使う
    coder.represent_scalar "!Ip", to_s
  end
end

puts parsed.to_yaml
# ---
# ip: !Ip 127.0.0.1
```

## YAML.add_tag
`YAML.add_domain_type` では YAML での値 -> オブジェクトの変換処理をブロックで指定していたが、値のクラスに持たせることもできる。
この場合は `YAML.add_tag` でタグとクラスの対応付けを行う。

```ruby
require "yaml"
require "ipaddr"

class IPAddr
  # YAML の読み込み時に Class.allocate でオブジェクトが生成されたあと、このメソッドが呼ばれる。
  # Class.allocate では initialize が呼ばれないので initialize を呼ぶのが楽。
  def init_with(coder)
    # coder.scalar でスカラー値が得られる。リストなら coder.seq、マップなら coder.map。
    # coder.tag でタグを得ることもできる。
    initialize(coder.scalar)
  end

  # 上例と同じ
  def encode_with(coder)
    coder.represent_scalar "!Ip", to_s
  end
end

YAML.add_tag("!Ip", IPAddr)

yaml = "ip: !Ip '127.0.0.1'"
parsed = YAML.load(yaml)
p parsed["ip"]
# #<IPAddr: IPv4:127.0.0.1/255.255.255.255>

puts parsed.to_yaml
# ---
# ip: !Ip 127.0.0.1
```

# CloudFormation のテンプレートでの実例
CloudFormation のテンプレートではタグを省略のために使っているだけなので、書き戻す必要がないのであれば、読み込み時に省略しないかたちに変換してしまうのが一番楽。

```ruby
require "yaml"

YAML.add_domain_type("", "Ref") do |type, value|
  {"Ref" => value}
end

yaml = "InstanceId: !Ref ApplicationServer"
parsed = YAML.load(yaml)

pp parsed
# {"InstanceId"=>{"Ref"=>"ApplicationServer"}}

puts parsed.to_yaml
# ---
# InstanceId:
#   Ref: ApplicationServer
```

書き戻す必要があるならクラスを作って `YAML.add_tag` 使うのがよさそう。

```ruby
require "yaml"

class Ref
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def init_with(coder)
    initialize(coder.scalar)
  end

  def encode_with(coder)
    coder.represent_scalar "!Ref", value
  end
end

YAML.add_tag("!Ref", Ref)
yaml = "InstanceId: !Ref ApplicationServer"
parsed = YAML.load(yaml)

pp parsed
# {"InstanceId"=>#<Ref:0x00007ff04009b838 @value="ApplicationServer">}

puts parsed.to_yaml
# ---
# InstanceId: !Ref ApplicationServer
```
マンガでわかる Proxy

![BD80C244-7D68-4C25-8295-143BE1F22B5B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/a5f42690-c31b-d096-e5dc-c2c9a9de38df.png)

これ最後、「ただいま混み合っておりますのでもう一度おかけ直しいただくか、このまましばらくお待ち下さい」ってなるアレですね。混み合ってるっていうのは、たぶんボス戦の最中でポーズできないとかの理由でしょうけど。

インターフェースが同じ軽量なオブジェクトを挟むことで、何らかの負荷対策を行うのが Proxy パターンです。めもりーちゃんの発明した電話対応ロボは、本当に必要になるまで実体へのアクセスを行わないことで、負荷対策に役立っています。

ほかにも、データ構造にいちいち実体を生成するのではなく、軽量な Proxy を差し込んでおいて、それが遅延評価したり、同じ重量級オブジェクトを参照するようにする、といった手も考えられます。これは Proxy が [Flyweight](https://qiita.com/tanakahisateru/items/393fb970bf01c81953b4) パターンの実現手段となるパターンです。

逆に、混み合うリソースへのアクセスを分散する Proxy も考えられます。単純にメモ化してキャッシュもありですね。結果さえ返せれば、Proxy の先は何でもいいのです。(GoF のみなさん「その他」でまとめてサボりたかったのかな)

Proxy は [Adapter](https://qiita.com/tanakahisateru/items/866f8938781984c98ef6) や [Decorator](https://qiita.com/tanakahisateru/items/d20be921079496c3aef5) とは目的が異なり、かならずしもラップ対象に委譲するわけではない、というのがポイントです。Adapter / Decorator の目的が「本来の機能への委譲」「本来の機能の拡張」なのに対して、Proxy の目的は「対外的な結果を変えずに、いかに本来の機能をサボるか」なのです。

Decorator パターンと意味区別が難しい局面もあるので、実装に対して、明確にどちらのパターンだと言い切れないこともあります。それは裏を返せば、デザインパターンで大事なのは、形ではなく意図なんだということですね。
Vue-cliでlocalhost:8080が接続エラーになる件の原因と解消［macとeset使用の場合］


#あらすじ
勉強がてらVueの開発環境を一から自分で作ってみたい！
と思い立ったある日のこと。
いろいろ調べるうちに便利そうなのあるやんと、Vue-cliを発見。

ネットサーフィンをしながら情報を集めて、いろいろ設定を進めると無事に出来上がった模様。
（立ち上げ方はネットに死ぬほど落ちてるので、本記事では割愛）

えっめっちゃ楽やん！とか思ってました。
ただ、まだこの時はどハマりするとは思っていませんでした...。


設定完了後、黒い画面(console)に

```
  App running at:
  - Local:   http://localhost:8080/ 
  - Network: http://***.***.***.***:8080/ //<- *の部分は自分のIPだよ
```

ここに接続して確認するのね。と、クリックすると接続エラー画面を連発、、、
表示してくれ！と願いを込めて押すリロードボタンは空回るばかり。
どちらもダメです。
たまに時間を置くと、まぐれで画面が表示するけど、またしばらくすると接続エラー...。

不安定すぎて、開発できねーよ(T-T)、、、とか思いながらいろいろ調べたけど解消できず、半日が経過。
精気を全て奪われ、社内のインフラ担当に相談して無事に解決した件を忘備録。


#原因は2つありました。


### 社内のセキュリティーにesetを使用していた。
まずこれ！
単にlocalhost:8080の接続を許可していなかった。
これは僕の方で設定できなかったので、権限がある人に許可できるよう追加設定してもらいました。
するとlocalじゃなくて、Networkのほうのリンクは効く！画面が表示されました。
「ほほう、新人インフラくんやるやん！」と褒めてあげます。
ただまだ肝心のhttp://localhost:8080が接続エラー。

### IPv6の設定が邪魔してる？
すると新人くんまたまたファインプレー。
試したいことがあります。と言って
黒い画面を召喚。

```
$ sudo vi /private/etc/hosts
```

魔法のコマンドを発動。
sudo（アカウントの権限）でetcディレクトリのhostsファイルをviで編集するという意味のようです。
その後パスワードを求められるので、アカウントのパスワード（パソコン自体やつね）を入力。

すると！
こんな画面が表示されます。

```
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
***.***.***.***  localhost
***.***.***.***  broadcasthost
::1              localhost
```
※IPは*で隠してます。

Host Database...よくわかりません。
新人インフラくん曰く、IPアドレスに名前をつけておく管理ファイルのようです。

原因はここ。

```
***.***.***.***  localhost
***.***.***.***  broadcasthost
::1              localhost
```
この部分の3行目が悪さしてました。
あんまりよく理解してないので、間違っていたらご指摘・補足を。

1行目のlocalhostはIPv4です。
3行名のlocalhostはIPv6です。

簡単に説明するとIPV4は0〜255を.で4つ繋いだもので、よく見るIPアドレス。
これが枯渇してきている問題があるので、新しいIPフォーマットを作ろう！
というので出てきたのがIPv6。

実際にはまだ使っていないのですが、使っているMacでは設定箇所が効いてる模様。

```
::1              localhost
```
これを

```
# ::1            localhost
```
このようにコメントアウトします。
（viの入力モードはaキーを押します。入力モード解除はescキー）

そのあと:wq(wは保存/qは終了)と打って元の画面に戻ります。

改めて画面を確認すると、無事にVueの画面が表示されてました。よき。
※強めのキャッシュが効いている可能性もあるので、本当に変わっているかどうかを確認するには違うブラウザで試してみるといいですよ。

Ipv6はこれから徐々に浸透していくみたいです。
でもまだ使う予定はないので、今はまだコメントアウトしておくほうがいいかもしれないですね。

ちなみにMacのシステム環境設定 -> ネットワーク画面にある右下の詳細からIPv6の設定がありますが、
ここの設定をいじっても ちゃんと表示できませんでした、、、なぜ？
Closures

#What is a closure?#

```JavaScript
function retirement(retirementAge) {
  var a = " years left until retirement";
  return function(yearOfBirth) {
    var age = 2019 - yearOfBirth;
    console.log(retirementAge - age + a);
  };
}

var retirementUS = retirement(66);
retirementUS(1970);
retirement(66)(1970);
```
In the example code above, the outer function is still able to access variables and arguments from the outside function (scope) even when the outside function has stopped its execution (returned). 

**An inner function has always access to the variables and parameters of its outer function, even after the outer function has returned.**

Closures are used for data privacy.

## Why does it work?##
Even if the function execution is removed from the execution stack, the function scoope still remains in the scope chain. The variable object of the outer function remains within
【Ruby】条件分岐

## then
thenは任意でつける事が可能。つけた場合に処理を1行で書ける。

```ruby
if n.zero? then puts '0です' else puts '0ではない' end
```

## 後置if
else説にあたる分岐がなければ、後置ifがつかえる

```ruby
puts '0だった' if n.zero?
```
kotlinメモ > 文字列→ ZonedDateTime 拡張関数


メモです



## 例

以下のような文字列を

```
"2019-10-31T09:00:00+09:00"
```

以下のようなZonedDateTimeに変換する拡張関数

```
ZonedDateTime("2019-10-31T09:00:00+09:00")
```


## 実装

```
fun String?.toZonedDateTime(formatter: DateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME): ZonedDateTime? {
    if (this==null) return null
    val result = kotlin.runCatching {
        ZonedDateTime.parse(this, formatter)
    }
    if (result.isFailure) return null
    return result.getOrNull()!!
}

```

ZonedDateTime.parseが失敗することも考慮して`kotlin.runCatching`で処理してます。
DateTimeFormatterでフォーマット変更が可能にしています。


## 使い方

```
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()
```

## 文字列のフォーマット指定

unit testでの使用例

```
@Test
fun toZonedDateTime_Format_Test1() {
    val expected = ZonedDateTime.parse("2019-12-31T23:59:59+09:00")

    var actual = "2019/12/31T23:59:59+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyy/MM/dd'T'HH:mm:ssXXX"))
    Assertions.assertThat(actual).isEqualTo(expected)

    actual = "2019/12/31 23:59:59+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ssXXX"))
    Assertions.assertThat(actual).isEqualTo(expected)

    actual = "20191231 235959+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMdd HHmmssXXX"))
    Assertions.assertThat(actual).isEqualTo(expected)

    actual = "20191231 235959 JST".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMdd HHmmss zzz"))
    Assertions.assertThat(actual).isEqualTo(expected)

    actual = "20191231235959JST".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMddHHmmsszzz"))
    Assertions.assertThat(actual).isEqualTo(expected)
}

```


## タイムゾーンのフォーマットの切り替えが必要な場合

タイムゾーンの切り替え


```
//｢同じ瞬間の別タイムゾーンの時刻に変えたい場合
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()?.withZoneSameInstant(ZoneId.of("America/Chicago"))
結果
2019-12-31T08:59:59-06:00[America/Chicago]



//｢同じ時刻の別タイムゾーン｣ に変えたい場合 (ローカル日付/時間を保持したまま、別のタイムゾーンを使う場合)
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()?.withZoneSameLocal(ZoneId.of("America/Chicago"))

結果
2019-12-31T23:59:59-06:00[America/Chicago]

```


```
@Test
fun toZonedDateTime_Change_Timezone_Test1() {
    val dateString =  "2019-12-31T23:59:59+09:00"

    var expected = ZonedDateTime.parse("2019-12-31T08:59:59-06:00")
    var actual = dateString.toZonedDateTime()?.withZoneSameInstant(ZoneId.of("America/Chicago"))
    Assertions.assertThat(actual).isEqualTo(expected)

    expected = ZonedDateTime.parse("2019-12-31T23:59:59-06:00")
    actual = dateString.toZonedDateTime()?.withZoneSameLocal(ZoneId.of("America/Chicago"))
    Assertions.assertThat(actual).isEqualTo(expected)
}
    
```
Unity で"Native error= Access denied" でIL2CPPビルドがコケる

なんか、AndroidのIL2CPPビルドって、いっつもなんか問題ありません...?
上記のようなエラーでビルドがコケまくる場合、
とりあえず

```
$ sudo chmod 0777 /Applications/Unity/Hub/Editor/{UnityVersion}/PlaybackEngines/AndroidPlayer/SDK/tools/bin/sdkmanager
```
のパーミッションを変更したら(0777にしちゃった)、ビルドが通りました。
うーむ。。。

Unity 2019.2.0f1。
Immediately invoked function expressions (IIFE)

#Characteristics#
- IIFE is not reusable as it is not assigned to a variable
- You can obtain data privacy and not be impacted from outside scope.

```JavaScript
// IIFE
function game() {
  var score = Math.random() * 10;
  console.log(score >= 5);
}
game();

(function() {
  var score = Math.random() * 10;
  console.log(score >= 5);
})();


(function(goodLuck) {
  var score = Math.random() * 10;
  console.log(score >= 5 - goodLuck);
})(5);
```
GoからGmailAPIで送信する時の文字化けに対応する

# はじめに
[前回](https://qiita.com/siro33950/items/7c129ffbd67d717d8646)GoからGmailを送信したが、そのままだと送信者名と題名に日本語を指定すると文字化けしてしまった
対応方法のメモ

# 原因
現状のメールの仕様上、ヘッダーは標準でASCII文字にしか対応していないが、Goは文字列をUTF-8で扱っている
そのため、本文以外でエンコードをした上で文字コードとエンコード方式を教えてあげる必要がある

# 対応
日本語をBase64でエンコードした上で

```
=?文字セット?エンコード方式?エンコード後の文字列?=
```
の形式で記述する

今回やりたいことに対応するためには以下の処理が必要

```go

subject := base64.StdEncoding.EncodeToString([]byte("メールの題名"))
suportedSubject := "=?UTF-8?B?" + subject + "?="
```


# 実装

```go

func createMessage(senderName string, senderAddress string, toAddress string, subject string, body string) gmail.Message {
	// body以外に日本語を指定したい場合はエンコードが必要
	fromStr := "From: =?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(senderName)) + "?= <" + senderAddress + ">\n"
	toStr := "To: " + toAddress + "\n"
	subStr := "Subject: =?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(subject)) + "?=\n"
	contentType := "Content-Type: text/plain; charset=UTF-8\n"
	bodyStr := "\n" + body

	var message gmail.Message
	// 全体をURLエンコードしてRawに入れる
	message.Raw = base64.URLEncoding.EncodeToString([]byte(fromStr + toStr + subStr + contentType + bodyStr))
	return message
}
```

# 参考
[日本語メールの仕組み](https://sendgrid.kke.co.jp/blog/?p=10958)
[Goでgmail APIを叩いて下書きを作成する](http://takayukinakata.hatenablog.com/entry/2018/03/06/201244)
インターネットの可用性を考えたシステム作り

## はじめに

[Leverages Advent Calendar](https://qiita.com/advent-calendar/2019/leverages) 19日目担当の ham です。
若干バズった [10日目](https://qiita.com/tak_ham/items/6243ebc0db467329a8bc)に引き続き 2度目の投稿です。

Leverages で、セキュリティの責任者としてセキュリティ意識の啓蒙や全社に関わるシステムの改善をしています。
また、前職では、SOC、NOC、BGPの運用などを行っていました。

タイトルに「可用性を考えた」とありますが、「冗長化しようぜ」とか「AutoScalingしようぜ」みたいな話は出てきません。

また、この記事の中はなんとなく理解することが目的のため、概念的なところが多いです。技術的な話はググってください。

## なんの話するのか

もし故障もしない、メンテもしない可用性 100% の Webサイトを構築できたとして、このサービスの可用性は 100% でしょうか？そう、100% ではないですね。

Webサイト側ではコントロールできない、サイトにたどり着くまでの部分の可用性が影響してきます。

そう、インターネットの可用性です！

## インターネット

### インターネットの管理人
インターネットは interconnected network  に由来するとおり、ネットワークとネットワークの接続の集合体であり、インターネットを管理している人はいません。
（IPアドレスを管理する人がいたり、接続するためのルールがあったりはします）

各組織によって管理されたネットワーク(ASと呼ばれる) が接続されて、奇跡的にインターネットが成り立っています。

### BGP
インターネットは、BGP(Border Gateway Protocol) というプロトコルで構成されています。

BGPの細かい話はここではしませんが、IT があって当たり前の世の中とは思えないほどひ弱な仕様です。

故意や作業ミスで嘘の情報を流して通信の邪魔したり、AS同士の接続が切れた時に経路情報の更新に時間がかかって通信が迷子になったりします。割とカジュアルに。

作業ミスで世界的にインターネットがおかしくなったのだと、 [2017年08月25日](https://www.google.com/search?q=2017年08月25日+インターネット)が思い出されますね。

また、オンプレの東京のサーバにアクセスするのは、経由する AS の数が少ないので(隣の AS に行くだけ、とか) AS同士の接続が切れてもそこそこすぐに情報が伝わって通信が復旧するけど、クラウド利用だと実は海外のサーバで経由する AS の数も多くオンプレより復旧に時間がかかることがあります。

### SLA
インターネットには管理人がいないので当然 SLA はありません。あなたが見ている SLA は、あなたが契約している ISP(プロバイダ) との SLA です。

あなたが契約している ISP1 に繋がっている ISP2,3, ... が全滅したとしても、ISP1 のなかが問題ないなら SLA は守られていることになります。


## まとめ

### 開発者へ
インターネットはひ弱です。

サイトの可用性の 9 を増やすことも大事ですが、インターネットの可用性を考慮に入れてそのコストをより良いものを作ることに回す選択肢もありかと思います。

### 経営者へ
インターネットはひ弱です。

自社や委託先のコントロールできる部分に何も問題なくても、ユーザが Webサイトへアクセスできなくなることがあります。また、コントコールできないので、「なんとかしろ」と言われても何もできません。
目に見えないかもしれませんが[この状況](https://www.google.com/search?q=福岡+陥没+コンビニ&tbm=isch)で客が来ないのと同じです。



## 最後に

BGPが義務教育になって、インターネットをきちんと理解してくれる人が増えることを願っています。
こくご、さんすう、せいかつ、BGP
Functions returning functions

```JavaScript
function interviewQuestion(job){
  if(job === 'designer'){
    return function(name){
      console.log(name + ', can you please explain what UX design is?');
    }
  } else if (job === 'teacher'){
    return function(name){
      console.log('What subject do you teach, ' + name + '?');
    }
  } else {
    return function(name){
      console.log('What do you do?');
    }
  }
}

// A function is assigned to teacherQuestion since interviewQuestion returns a function
var teacherQuestion = interviewQuestion('teacher');
teacherQuestion('John'); // 'What subject do you teach, John?'
interviewQuestions('teacher')('John') // 'What subject do you teach, John?'
```
This is possible because functions are always first class functions. The functions are infact an object.

**A language is said to have first class functions when the functions can be treated like any other variable. These first class functions can be assgined to a variable, passed to a function as an argument or be returned from a function.**
Goのフレームワーク「echo」でCORSの設定を行う

# 概要

フロント側はポート番号`8080`、サーバーサイド側はポート番号`8008`で立てた際に**ローカル環境でもCORSが起こった**のでCORSの設定を行う

以下エラー発生時のChromeのコンソール部分
![コメント 2019-11-21 130116.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/74d37940-e7d4-c1bb-142b-427fd2efeba6.png)

# サーバー側のサンプルコード

単純にパラメータ`name`を`POST`すると`tasks`テーブルnameを登録できるというアプリです。
**※実際にはトークンなども必要ですがここでは割愛します**

```main.go
package main

import (
	"database/sql"
	"log"
	"net/http"

	_ "github.com/go-sql-driver/mysql"

	"github.com/labstack/echo"
)

func main() {

	e := echo.New()

	e.POST("/task", task)

	e.Start(":8008")
}

type TaskParam struct {
	TaskName string `json:"name"`
}

func dbConnect() *sql.DB {
    db, err := sql.Open("mysql", "root:your_db_password/your_db_name")
    if err != nil {
        panic(err.Error())
    }
    return db
}

func task(c echo.Context) error {
	param := new(TaskParam)
	if err := c.Bind(param); err != nil {
		return err
	}

	db := dbConnect()

	// insert
	ins, err := db.Prepare("INSERT INTO tasks(name) VALUES(?)")
	if err != nil {
		log.Fatal(err)
		panic(err.Error())
	}
	ins.Exec(param.TaskName)

	defer db.Close()

	return c.HTML(http.StatusOK, "INSERT OK")
}
```

# 通常のCORS設定

単純な`GET`とか`POST`、`PUT`、`DELETE`を許可させる場合は以下のように`e.Use(middleware.CORS())`を追加すればとりあえずローカル環境だけの場合はOKでした。

```main.go
func main() {

	e := echo.New()

	// CORSの設定追加
	e.Use(middleware.CORS())

	e.POST("/task", task)

	e.Start(":8008")
}
```

`import`に`github.com/labstack/echo/middleware`を以下のように追加

```main.go
import (
	"database/sql"
	"log"
	"net/http"

	_ "github.com/go-sql-driver/mysql"

	"github.com/labstack/echo/middleware" // 自動追加されてなければ追加する
	"github.com/labstack/echo"
)
```

# 厳密なCORSの設定

まだ試してないのですが公式のドキュメントに以下のコードを追加し、`AllowOrigins`と`AllowMethods`を適切に設定することで異なるドメイン間でもやり取りできるように設定できるみたいです。

```main.go
func main() {

	e := echo.New()

	// 厳密にCORSを設定する（以下公式のサンプルコード）
	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
		AllowOrigins: []string{"https://labstack.com", "https://labstack.net"},
		AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
	}))

	e.POST("/task", task)

	e.Start(":8008")
}

type TaskParam struct {
	TaskName string `json:"name"`
}
```

# 参考URL

- [CORS Recipe | Echo - High performance, minimalist Go web framework](https://echo.labstack.com/cookbook/cors)
【Go】.envファイルをGolangでも使用するためのライブラリ「godotenv」

# godotenv

要は`.env`ファイル（環境変数定義）を使用するためのライブラリ

## インストール

```
go get github.com/joho/godotenv
```

## importに以下を追記

```.go

pckage main

import "github.com/joho/godotenv"

```


## .envファイルを作成

ディレクトリ構成は以下

```.bash
/
|- .env
|- .env.example   //git管理用のサンプル.env
|- server/
      |- main.go
```

デフォルトでは普通の`.env`が読み込まれるようです

## .envファイル作成後に中身を記述

```.env
ENV=local
DB_USER=root
DB_PASS=pass1234
DB=test_db
```

ちなみに`.env.example `には環境ごとに代わる値は空にしておく

## .envに定義した値を取得

```main.go
package main

import (
	"fmt"
	"os"

	"github.com/joho/godotenv"
)

func main() {
	err := godotenv.Load(fmt.Sprintf("../%s.env", os.Getenv("GO_ENV")))
	if err != nil {
		// .env読めなかった場合の処理
	}

	env := os.Getenv("ENV")
	DB := os.Getenv("DB")
	DBUser := os.Getenv("DB_USER")
	DBPass := os.Getenv("DB_PASS")

	fmt.Println(env)     // local
	fmt.Println(DB)      // test_db
	fmt.Println(DBUser)  // root
	fmt.Println(DBPass)  // pass1234
}

```

## 実行して確認

```
$ go run main.go
```

で.envの設定が読み込まれるか確認

## 参考URL
- [godotenvを使ったGolangでの環境変数の設定方法 - ブロックチェーンエンジニアとして生きる](https://tomokazu-kozuma.com/how-to-set-environment-variables-in-golang-using-godotenv/)
Functions are like Objects

##A function is similar to objects##
- A function is an instance of the Object type
- A function can be stored in a variable
- A function can be passed as an argument to another function

First class function?


##Passing a function as an argument##
```JavaScript
var numbers = [1,4,6,1,9]

function arrayCalc(arr,fn){
  var arrRes = [];
  for (var i = 0; i < arr.length; i++){
  arrRes.push(fn(arr[i]));
  }
  return arrRes;
} 

function calculatePower(num){
  return num**2;
}

//Calculate power without brackets since it is a call back function
arrayCalc(years,calculatePower);
ESP-32でアナログ入力を使うときの注意点

##前書き
僕「ESP32って、Wi-FiとBLEがついててスペックもそこそこいいし、Arduinoの環境でコード書けるし、1500円とお買い得！買ってみますか」ポチ
---ESP到着--
僕「アナログピンにマイク繋いでみますか...」
シリアルモニター君「A/D変換値は**1800**だよ」
僕「ん？分解能は12bitだから中心電圧のA/D変換値は4096/2=2048前後になるはずなのに、あれ..?」
僕「線形じゃないのかな？電源装置繋げて調べてみるか..」
#ESP32のアナログ入力
ESP-32のADCは12bitでの最大値は3.6Vを示しているようです。by スイッチサイエンス
前書きに書いたように誤差が大きいようです。

実施に電源装置で測定した結果が以下の通りです。

| 電圧       |      A/D変換値 |   
|:-----------------|------------------:|
| 0             |              0 | 
| 0.1           |            3 |       
| 0.2             |              83 |    
| 1.0               |                1093 |    
| 1.6             |             1842 |         
| 2.0          |           2337 |    
|2.9             |             3597 |         
| 3.1          |           4031 |    
| 3.3          |           4095 |  

(実際には0.1V刻みで33点取っています。)

グラフで描画すると

<img width="1006" alt="スクリーンショット 2019-12-12 11.35.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68536/d32e5787-5a26-ae28-1974-6a45c8d0a051.png">

0.1V~3.0Vまでなら直線的な近似ができそうだなと思い最小二乗法でフィッティングすると

<img width="1094" alt="スクリーンショット 2019-12-12 11.42.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68536/7dd52428-82d3-5c89-eb54-09dd489b3cfe.png">

$$y=1260x-161$$
となり決定係数も0.994と使えそうな値が出ました。
他のピンでも同様の実験を行なった結果、同じような値が出ました。

↓HTMLで最小二乗法を行うプログラムを書いたので、もしよかったら使ってください↓
https://github.com/klme/fitting
##総評
時間をあけて行なってもほぼほぼ同じ結果がでました。
しかし、違う個体だと差が出ました。
ESP-32ではアナログリードを使うときは、まずこの特性実験をして傾きと切片をもとめることが大事ですね。

＊ESP-32では、アナログ入力とWi-Fiと並行して使うことはできないみたいですね。注意しましょう！


>##参考
スイッチサイエンスさん--ESP-WROOM-32に関するTIPS
https://trac.switch-science.com/wiki/esp32_tips
公式スレッドにて
https://esp32.com/viewtopic.php?f=12&t=1045
議論1
https://github.com/espressif/arduino-esp32/issues/92
議論2
https://github.com/espressif/esp-idf/issues/164
NotionでSQLを管理する

[アルプ株式会社](https://thealp.co.jp/)でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2019](https://qiita.com/advent-calendar/2019/notion) 12日目のエントリです。
11日目は[Notionで記事をスクラップする](https://qiita.com/pictiny/items/745cfcf562c6429a3efc)でした。

# クエリを書く
Notionでクエリを書く場合はコードブロックを使うとよいです。
コードブロックは言語を選ぶことでシンタックスハイライトをかけることができます。
SQLもシンタックスハイライトに対応しています。コードブロックの右下から言語を選択できます。

<img width="872" alt="クエリ1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/004bf4b4-035e-b068-c75f-af70f63a2883.png">

# クエリを見やすくする

クエリは条件を追加していくと1行が長くなりがちです。
コードブロックの右上のメニューから**Code Wrap**もできるのですが改行されるのも微妙です。

## スタイル設定

ページ右上のメニューから`Small Text`と`Full Width`を切り替えることができます。

<img width="265" alt="クエリ2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/2a684c37-bc62-3d81-9a87-9e698e7b9b72.png">

この2つを有効にすることで1行が長いコードの見通しがよくなります。

<img width="1266" alt="クエリ3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/9bb84cdd-3434-4618-3324-8e5e8fc31a6a.png">


# まとめ

SQLを管理しやすくなるコードブロックとスタイル設定の使い方を紹介しました。
公式ドキュメントは[Styles & customization](https://www.notion.so/Styles-customization-bfb379c2fa6d43f18d4aed9fd126b2cc)にありますので、そちらもご覧ください。
ホワイトボックススイッチにOcNOSを乗せてちょっと運用してみた

この投稿は「[さくらインターネット Advent Calendar 2019](https://qiita.com/advent-calendar/2019/sakura)」の13日目の記事です。

# OcNOSを利用してみた

ベンダー様よりプレスリリース[^1][^2]も出されているのですが、一部のデータセンタサービスのネットワークとしてEdgeCoreスイッチ、NOSとして[OcNOS](https://www.ipinfusion.com/products/ocnos/)を採用しました。

[^1]: https://www.apresia.jp/news/2019041101.html
[^2]: https://prtimes.jp/main/html/rd/p/000000198.000011476.html

ホワイトボックススイッチというとL3Closのような構成で利用されることが多いかなと思うのですが、今回はL2スイッチとしての利用が主で、VLAN/LAG/MLAG...といった機能の利用がメインです。（念のため、OcNOSにL3機能が無いわけではないです。実際、L3スイッチとしてOcNOSを利用している箇所もごく少ないですがあります。）

# なんでOcNOSなの
そもそもは「ホワイトボックスを利用したい」という意図があったわけではなく、機能要件に見合ったからです。

要件としては、ざっくり以下の3点です。
※もちろん、これ以外の具体的な機能要件がたくさんあります。

 * MLAGができるL2スイッチであること
 * コストメリットがあること
 * 設定/操作自動化のための手段が用意されていること

要件を満たす製品をいくつか検証してみましたが、結果としていくつかの候補の中からホワイトボックススイッチ/OcNOSを採用することとなりました。

# こんなところがいいよ

ホワイトボックスやOcNOSに限った話ではないものもありますが、良いところは以下のような部分です。（個人的な主観が大いに含まれます）

## 光モジュール類の柔軟性
ホワイトボックススイッチ全般にいえることですが、SFP等の光モジュール類でベンダーロックインされなくなります。これによりスイッチの導入コストの低下が期待できます。
ただし、その分自前でモジュールベンダーとやり取りする必要があるため、多少運用コストが増えるとも言えますが、ベンダーロックインの排除というメリットはデメリットを補って余りあるでしょう。

## 「ホワイトボックス」っぽくない
ホワイトボックススイッチというと、「インターフェースがいっぱいついてるLinux」みたいなイメージを持たれている方が多いんじゃないかと思うんですが、OcNOSの設定や操作は業界標準CLIなので、触るだけであればLinuxの知識は一切不要です。そのため、例えばCiscoしかさわったことないネットワークエンジニアでも十分操作できるOSであると言えます。
ただしその反面、Linuxのシェルを経由したオペレーションは基本的にはできないため、「スイッチにあれやこれやインストールして動かしたい」とか「サーバーのように管理/運用したい」といったことはできません。

同じホワイトボックス向けOSであるCumulusLinuxは「サーバエンジニアより」のOSかなと思いますが、OcNOSは「ネットワークエンジニアより」のOSであると言えます。どっちが良いというわけではく、それぞれにメリット/デメリットがある話かと思いますが、今回は「ネットワークエンジニアより」という点が運用をしていく上でプラスになりました。

## プロビジョニングの自動化
ホワイトボックス特有のOSインストール機能であるONIEと、OcNOSがもっているゼロタッチプロビジョニングの機能を利用し、箱から出したスイッチにケーブルを接続して電源投入するだけで、全自動でのOSのインストール/設定の適用まで可能ができました。ONIEやゼロタッチプロビジョニングはいずれもDHCPサーバを用意すれば実現可能なため、こういった環境の構築も（比較的）容易です。

## NETCONF/YANG
今回は設定を動的に変更していくという要件があったため、そういった操作はすべてNETCONFで行っています。OcNOSはGithubでYANGモデルが公開されているため、このモデルを利用してGoのコードを自動生成して利用しています。

https://github.com/IPInfusion/OcNOS/tree/1.3.8/yang-files


# さいごに

ホワイトボックスというと、「Linuxの知識が必要なんだろうな」とか、なんとなくハードルが高いと感じている方もいるんじゃないかと思います。その中でもOcNOSは（ネットワークエンジニア的に）扱いやすいOSだと思います。


本稿のようなパブリックな場所に書きにくいネタもあるので、どこかでお話できるといいですね！
自作PCオタクのビジネスPC選定のお話

# はじめに
はじめましての方はじめまして。私は社内でヘルプデスクを業務をしております。
平たくヘルプデスクと言っても業務は多岐にわたり、今年はWindows7からWindows10への切り替えが大きなミッションとなったため、それをネタに記事にしようと思います。

# 自作PCとビジネス(業務用)PCの違い
■自作PCは目的に応じた様々な仕様のPCをパーツを選んで組み上げます。

* ハイスペックPC（動画エンコード特化、ゲーム特化PC）
* エコPC（省電力、必要十分なローコスト、ロースペックPC）
* 小型PC　or 静音化PC　or テレビ録画用PC　などなど

ハイスペックPC コダワリパーツ 
エンコード用　最速CPU：[Intel Core-i9 10980XE Extreme](https://kakaku.com/item/K0001217270/) 参考 ￥148,000
ゲーム用　最速GPU：[NVIDIA GeForce RTX 2080 SUPER](https://kakaku.com/item/K0001179208/) 参考 ￥99,000
テレビ録画用 大容量 14TB HDD：[WesternDigital　WD140EFFX](https://kakaku.com/item/K0001215996/) 参考 ￥62,800

**おサイフの許す限り、コダワリのパーツをかき集めて自分だけの1台を組み上げるのが自作PCです。**


■ビジネス(業務用)PCには次のようなものがあります。

* 一般事務用PC（システムクライアント、MS Officeクライアント）
* 営業用モバイルノート　
* 特定用途用PC（大画面、CAD用途 などなど）

**業務に不足ないスペックでかつローコスト　また大量導入に向くPCが理想です。
PCは定期的に更新されます。PCの更新のしやすさもポイントです。**


# 選定ポイント
### スペック
自作PCは目的のためのスペックを追求しますが、ビジネス用PCは違います。
高スペック＝高コストとなるため、ただ高性能であれば良いとは限りません。
Core-i9やRyzen-9で"ベンチマークヒャッハー！！"なPCはビジネスには過剰です。
逆に、ただローコストを求めたPCではビジネスの足を引っ張る恐れがあります。

* CPUは **Core-i5 か Core-i3 がおすすめ**です。
 ※現行のデスクトップ用Core-i3（第8世代以降）は4コアになりましたので十分動きます。
* メインメモリは 8GB　ストレージは 512GB-SSD　がおすすめです。
* 運用期間が長いので **高耐久な本体**が理想です。
* 外部モニタの接続端子が多いものが理想です。

### 入手性
自作PCは一点物で "今買えれば良い" ものですが、ビジネスPCは違います。
数百台、数千台の導入と運用管理を考慮し、製品ライフの長いものを選ぶ必要があります。
長く入手できれば、イメージ作成や動作検証をする種類が減り、作業のコスト減につながります。

* 大手メーカー製かつ、**次のモデルチェンジまで6ヶ月以上のもの**がおすすめです。
* **特価品はNG**です。社内承認が遅れた場合・追加購入の場合に製品がない！となります。
* 特定のCPUが生産不良で不足する場合があります。(メーカーの担当営業から情報を得る必要があります。 弊社では2018年も2019年もCPU不足に泣かされました。。。)

### 保守・保証
運用期間（購入であれば減価償却期間も）を考慮した保守・保証期間が必要です。
自作PCのように壊れたら交換すれば良いとはなりません。
2年程度で修理ができなくなるショップPCは避けるべきです。

* **4年程度の保守期間**がローコストで契約できるよう、メーカー営業と交渉しましょう。
* 破損や故障に備え、**アクシデントサポートを契約**しましょう。
* 過去の故障率を計算し「故障はx%以下が見込まれるから安く！」と交渉しましょう。
* **修理費用は予算化しにくい**ため、故障の際に非常に手間がかかります。

#いまのおすすめPC
弊社では現在、次のPCを導入しています。
ビジネスPCとしておすすめできるものです。
デスクトップPC： [DELL OptiPlex 3070 Micro](https://www.dell.com/ja-jp/work/shop/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/optiplex-3070-micro/spd/optiplex-3070-micro?~ck=bt)シリーズ
ノートPC： [VAIO ProPK](https://vaio.com/business/pk11/)シリーズ

詳細スペック・価格は伏せさせていただきますが、
カスタマイズして下記要件を満たすようにしています。
・Core-i5 or Core-i3　/　8GBメモリ　/　十分なストレージ
・デスクトップはDP/HDMI/VGA/DVIの各接続端子がある
・ノートはHDMI/VGAとUSB Type-Cがあり拡張性を確保
・4年のアクシデト保証を破格で付与されておりローコストかつ十分な保証

**企業によりPCにかけられるコストは変わるかと思いますが、
初期コストだけでなく、保守・保証、機材管理まで含めた機材検討が必要だと考えます。**
簡単なTypeScriptの型一覧

# TypeScriptの型

- `boolean`型
  - `true` or `false`
- `string`型
  - 文字列 
- `number`型
  - JS同様にTSの数値は**浮動小数値**
  - 2,8,10,16進数のリテラルもサポート
- `tuple`型
  - 固定数の型がわかっている要素を定義できる **ex) `let x: [string, number]`**
- `any`型
  - 型が不明な場合に用いる型。コンパイルでエラーがでない
  - 型チェックが通るので推奨されない
- `unknown`型
  - `any`型より少し型安全なany
  - 値の代入には寛容（ok）だが値の利用には厳しい （error）
- `void`型
  - 名前の通り型がない
  - `null`か`undefined`しか代入できない
- `null`型
  - `null`
- `undefined`型
  - `undefined`
- `never`型
  - 発生しえない値の型。戻り値が得られない場合の型として指定
- `object`型
  - 非プリミティブ型（`string`,`number`,`boolean`,`symbol`,`null`,`undefined`以外）
  - ブレース（`{}`）で定義するとエラーが得られない **ex) `let objBrace: {}`**
- `symbol`型
  - ユニークな識別子を持つ型で`Symbol()`でのみ生成可能
  - **それ自身とのみ等しい**という特性を持つ

# 参考
- [実践TypeScript ~ BFFとNext.js&Nuxt.jsの型定義~ ](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5TypeScript-BFF%E3%81%A8Next-js-Nuxt-js%E3%81%AE%E5%9E%8B%E5%AE%9A%E7%BE%A9-%E5%90%89%E4%BA%95-%E5%81%A5%E6%96%87/dp/483996937X)
ES Modules形式をCommonJS形式でも利用できるようにする

YAMAP エンジニア Advent Calendar 2019 の12日目になります。
YAMAPで、フロントエンドエンジニア？として活動中の @issyxissy です。
フロントエンドエンジニアと言っても、他にもいろいろなことやっています。

YAMAPでは、Nuxt.js + Vue.jsを使ったフロントエンドの開発を行っています。
( https://yamap.com をみていただければと〜）

最近、ちょっと悩んだことがあって、解決できたので、まとめてみました。

## ケース
Node.js と Vue.jsで、共通関数を使いたい・・・

## 問題
Node.jsは、CommonJS 形式 (module.exports / require() )
Vue.js (ブラウザ環境) は、 ES Modules 形式 (export / import ) となるため、
共通関数をES Modules 形式で書くと、Node.js側で怒られるし、かといって、CommonJS 形式で書くと、Vue.js側で怒られる、どっちつかずな状況になります。

Node.jsのバージョンを上げたり、npmパッケージを作ったり　https://blog.hiroppy.me/entry/node-esm#ESM-in-Nodejs な感じで、ごにょごにょしたら出来ると思いますが、既存環境を壊したくないし、コストかけたくないし、悩んでいました。。。

あるあるなヤツです・・・( ꒪⌓꒪;

## 解決
どうにか出来ないかと、試行錯誤していましたが、esmという超便利なライブラリがありました。
https://github.com/standard-things/esm

このライブラリ、ES Modules形式を CommonJS形式で利用可能にする便利なヤツです。
(世の中には、便利なものを作る人たちがたくさんいて、素晴らしいと思います・・・感謝です）

```console
$ npm install esm
or
$ yarn add esm
```

hogehoge.jsは、ES Modules形式で書いて、Node.jsには、↓のようにして、CommonJSに変換して利用できます(ノ ꒪⌓꒪)ノ

```js

const requireEsm = require('esm')(module);
const { xxxx } = requireEsm('./hogehoge.js');
```

## まとめ
- ES Modules形式で書いて、esmライブラリでCommonJS形式で変換してくれる便利なヤツ
- もっとエレガントに解決できる方法あったらいいなー
Googleフォームの内容を指定のアドレスにメール送信するGAS

#自己紹介
新卒で入社した会社で金融系のゲートウェイ開発を3年間行っていました。
fix電文を来る日も来る日も朝日がのぼるまでひたすら解読する毎日・・・

現在はランスタッドヘルプデスクとしてインフラ業務をかじったり、ときにはPCを解体したり刺激的な毎日を過ごしています。

#はじめに
弊社ではクライアントへ依頼のメールを以下の手順で実施していました。
その手順を効率化するために組んだGASを記事にしようと思います。

業務内容は以下です。
①Excelに依頼NOや依頼者、指定の作業内容などを手動記載
　（例）依頼no△△｜依頼者　××｜作業内容
②メールで上記の内容をクライアント指定のメールアドレスに手動送付
　（例）お疲れ様です、○○会社××です、以下の依頼をお願いします。
　　　　依頼no△△・・・

同じ内容を①Excel記載/②メールと2回記載している部分を効率化できないか検討した結果、Googleフォームを利用して依頼をだすことでExcelの転記とメール送付を自動化しました。

①依頼内容をGoogleフォームで送信
②自動でスプレッドシートに転記
③Googleフォームの送信をきっかけにして、依頼メールをクライアント指定のメールアドレスに送付

③の手順を自動化する際に組んだGASを記事にしたいと思います。

#Googleフォームの内容を指定のアドレスにメール送信するGAS

```send_Mail(e)
function send_Mail(e){
  //アドレス①TO宛先””の中身を編集すれば宛先変わります。
  var address1="××@××.co.jp";
  //アドレス②CC宛先””の中身を編集すれば宛先変わります。
  var address2="○○@○○.co.jp";

  //変数に値を格納※アンケートの項目名を””の中に入力↓
  var list1=e.namedValues["1. 依頼者"];
  var list2=e.namedValues["2. 依頼No."];
  var list3=e.namedValues["3. 指定内容①"];
  var list4=e.namedValues["4. 指定内容②"];

  //件名入力↓
  var subject="件名"
  
  //メール本文編集↓
　　var body="××株式会社"+"\n"+"ご担当者様"+"\n"+"\n"+"いつもお世話になっております。"+"\n"+"○○株式会社　"+list1+"です。"+"\n"+"下記の作業をお願い致します。"+"\n"+"\n";
　　body+="①依頼No."+"\n"+"　⇒"+list2+"\n";
　　body+="②指定内容①/指定内容②"+"\n"+"　⇒"+list3+"　　"+list4+"\n";

  //メールの送信↓
  MailApp.sendEmail({to:address1,cc:address2,subject:subject,body:body});
  }
```

#おわりに
簡単ですが、作成した後も継続利用できているものです。
様々な場面で利用用途があるかと思います。
【JavaScript】 reduce()について

学校の先生が、一人の生徒のテストの合計を算出するプログラムを作るといったときに、
forやwhileではなくreduce()を使うことでも算出できたので備忘録として記載します。

例えば、テストの点数が
国語：60点
英語：100点
数学：80点
理科：70点
社会：80点
だとします。

これを配列にすると

```javascript:reduce.js

let points = [60,100,80,80,70,80];
```

です。

forを使うと

```javascript:for.js

let sum = 0;
for(let i=0; i<points.length; i++){
  sum = sum + points[i];
}
```

reduce()を使うと以下のコードになります。

```javascript:reduce.js
let sum = 0;
sum = points.reduce(function(acc, cur) {
  return acc + cur;
});
```

とすることで合計が算出されました。