OmniAICreator/Qiita-1.07M huggingface dataset:
Rust でしっかりとダイナミックリンク

# はじめに

Rustのビルドシステムでは、Rustの世界ではスタティックリンク、OSの標準ライブラリとはダイナミックリンクが基本になっている。これは、Rustの標準ライブラリぐらいはダイナミックリンクにして、バイナリをスリム化するための備忘録である。

# 環境

+ macOS Sierra 10.12.6 (16G2011)
+ rustc 1.36.0-nightly (e305df184 2019-04-24)
+ Apple LLVM version 9.0.0 (clang-900.0.39.2)

# ダイナミックリンクを指定する方法

rustc のコード生成時のオプションとして `-C prefer-dynamic` を指定すればよい。cargo を使う場合、rustc のフラグを指定する方法には以下の３つがあるようだが、それぞれ、ちょっとしたデメリットがある。

1. `cargo rustc` のコマンドラインで指定
    + `cargo build` ではないサブコマンドを使わないといけない
    + いちいち指定するのが面倒
    + これでビルドしても、`cargo run` すると、通常の `cargo build` が走ってしまう
2. `.cargo/config` の `rustflags` に記述
    + ビルドするターゲットごとに指定することはできなさそう
    + "Cargo.toml" と同様の TOML フォーマットで記述すればよいのだが、`"` をエスケープすることができないので、指定にちょっとコツがいる
3. 環境変数 `RUSTFLAGS` で指定
    + いちいち指定するのが面倒（だが、これが一番お手軽な気がする）

ちなみに、ダイナミックリンクされているライブラリが何かを知るためには、`otool -L バイナリファイル名` とすればよい。

## 例 1. `cargo rustc` のコマンドラインで指定
```
# ビルド
$ cargo rustc -- -C prefer-dynamic

# 起動（Rust標準ライブラリのパスを環境変数で設定）
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge
# もしくは
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge

# 起動（rustup経由）
$ rustup run stable ./target/debug/hogehoge
# もしくは
$ rustup run nightly ./target/debug/hogehoge
```
## 例 2. `.cargo/config` の `rustflags` に記述
```
# config 設定
$ mkdir .cargo
$ cat <<EOF >.cargo/config
[build]
rustflags = ["-C", "prefer-dynamic"]
EOF

# ビルド
$ cargo build

# 起動
$ cargo run
```

## 例 3. 環境変数 `RUSTFLAGS` で指定

```
# 環境変数の設定
$ export RUSTFLAGS="-C prefer-dynamic"

# ビルド
$ cargo build

# 起動
$ cargo run
```

# 結果

結果は以下の通り（Swift については、2019/8/14 追記）。

|   | unstripped | stripped |
|---|-----------:|---------:|
| Rust (-C opt-level=3) |276,272 bytes | 178,856 bytes |
| Rust (-C opt-level=3 -C prefer-dynamic) | 9,048 bytes | 8,656 bytes |
| C (-Oz)  | 8,432 bytes | 8,440 bytes |
| Swift (-Osize) | 8,960 bytes | 8,824 bytes |

比較のためのプログラムは以下の通り。

```rust:hello/src/main.rs
fn main() {
    println!("Hello, world!");
}
```

```c:hello/c/hello.c
#include <stdio.h>

int main() {
	   printf("Hello, world!\n");
}
```

```swift:hello/swift/hello.swift
print("Hello, world!")
```

なかなかいい線いっているという感じか。次は[スタティックリンクに挑戦](https://qiita.com/moriai/items/b1fa7d1b43d985d408cc)。

# 参考

様々な最適化フラグの比較については、下記が参考になる。
+ [Rustのバイナリサイズを削減する](https://qiita.com/hhatto/items/75d12de5a39ee37c5ddb)
Pandasで読み込むデータの在り処を指定する

## ファイルを読み込む
参考
https://note.nkmk.me/python-pandas-read-csv-tsv/

### tsvファイルを読み込む
tsvファイルとは、csvがコンマで区切られているのに対して、タブ(空欄)で区切られているファイル形式のこと。
read_csvで、区切り文字にタブ文字\tを設定する。
```
df= pd.read_csv('data/src/sample_header_index.tsv', index_col=0, sep='\t')
```

###データの在り処を指定して読み込む
FileNotFoundErrorが出た場合は、データの在り処が間違っているかもしれない。
https://qiita.com/Oz-Spade/items/7fa479fae7a0ea6fcddf
https://qiita.com/redAlgae/items/1d9788b6f0b6613bf711

osモジュールを使って、ファイルが存在するディレクトリに移動してみる

```
import os
//今いるディレクトリの確認
os.getcwd() 
//ディレクトリの移動
os.chdir("/Users/W5966QZH/desktop")
```

あとはread_csvを使用してファイルを読み込む

```
df=read_csv('ファイル名')
```
Rust combineのparse vs easy_parse

# はじめに

Rustのパーサコンビネータライブラリ[combine](https://github.com/Marwes/combine)にはパースを実行する関数として`parse`と`easy_parse`の2種類の関数があります。後者は人が読みやすいパースエラーを生成できるのですが、実行速度に結構差があることに気づいたので比較してみました。
もちろんパーサの書き方依存の部分も大きいと思うので、結果は参考程度です。

# 条件

- Rust: 1.33.0 stable
- combine: 3.8.1
- CPU: Xeon Gold 6134 @ 3.20GHz
- OS: CentOS Linux release 7.6.1810 (Core)

比較したパーサは以下です。

https://github.com/dalance/sdc-parser

# 結果

結果は以下のようになりました。横軸がファイルサイズで縦軸がスループットです。

![parse_vs_easy_parse.png](https://qiita-image-store.s3.amazonaws.com/0/84296/0d59b678-7177-1346-9524-05cba86dc29a.png)

ちょうどいいサイズのサンプルがなかったので間が空いてしまっています。100MB以下だけ拡大したものが以下です。

![parse_vs_easy_parse_100MB.png](https://qiita-image-store.s3.amazonaws.com/0/84296/304ccaac-6451-db12-2178-8bbe00809f7b.png)

これをparse / easy_parseの比率に変換したものが以下です。

![parse_vs_easy_parse_ratio.png](https://qiita-image-store.s3.amazonaws.com/0/84296/66487491-dfc2-6d85-dabf-bebc102692a6.png)

1個だけ`easy_parse`が異常に遅いケースがありますが、だいたい2倍程度違うようです。
Rust combineでand_then()を使うとき（訂正版）

# はじめに
「[Rust combineでand_then()を使うとき](https://qiita.com/dalance/items/41de4d1c84a0b8fbd003)」という記事を書いたのですが、結構間違っている部分があったので訂正版です。

まず、`and_then`を使う場合は`easy_parse`が必須と書いたのですが、これは嘘でした。
`parse`が返すエラー`combine::error::ParseError`が`std::error::Error`を格納できない、と思っていたのですが、実際には
`ParseError::StreamError::other()`で格納することができました。
ただし`From`は実装されていないので、自分で変換する必要があります。

これを踏まえて、`parse`でも`easy_parse`でも使える再利用可能なパーサは以下のようになります。

# `and_then`を使った再利用可能なパーサ（訂正版）

```rust
fn num<I>() -> impl Parser<Input = I, Output = i32>
where
    I: Stream<Item = char>,
    I::Error: ParseError<I::Item, I::Range, I::Position>,
{
    many1(digit())
        .and_then(|x: String| {
            x.parse::<i32>().map_err(|x| {
                <I::Error as combine::error::ParseError<char, I::Range, I::Position>>::StreamError::other(x)
            })
        })
}
```

`map_err`で自力で変換することで、前回記事のtrait boundに必要だった`From`はいらなくなっています。
また、途中に出てくる長いエラー型はtype annotation含めあちこちで使うのでaliasしておくと便利かもしれません。

```rust
type AndThenError<I> = <<I as StreamOnce>::Error as ParseError<
    <I as StreamOnce>::Item,
    <I as StreamOnce>::Range,
    <I as StreamOnce>::Position,
>>::StreamError;

fn num<I>() -> impl Parser<Input = I, Output = i32>
where
    I: Stream<Item = char>,
    I::Error: ParseError<I::Item, I::Range, I::Position>,
{
    many1(digit())
        .and_then::<_, _, AndThenError<I>, _>(|x: String| {
            x.parse::<i32>().map_err(|x| {
                AndThenError::<I>::other(x)
            })
        })
}
```

単にエラーメッセージを渡したい場合は

```rust
AndThenError::<I>::message_static_message("error!!!")
```

が使えます。

# おまけ

前回の結果で一段落したつもりだったところを再調査したのは`easy_parse`が結構遅いことに気づいたからでした。
折角なので`parse`と`easy_parse`の速度比較もしてあります。

[Rust combineのparse vs easy_parse](https://qiita.com/dalance/items/a98c3eb03cd6c753b228)
[HD44780] LCD初期設定から表示まで

キャラクタLCD用コントローラーとしてデファクトスタンダードとなっているHD44780の初期設定を行う関数を作成しました．

HD44780は現在流通しているほぼすべてのCLCDのコントローラーに用いられているものです．

![105652.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/bbbce2d8-4dcc-2552-afd0-450891e33027.jpeg)

使用したのは40行×2のLU3172　LCDモジュールです．

マイコンにはH8/3664を用いました．
ピン配置は以下の通りです．

![pin_assign.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/29982040-c035-e06f-4c88-13b231c03bd9.png)


初期化手順は

1．電源投入
2．15ms以上待つ
3．ファンクションセット(8bit_mode設定)
4．4.1ms以上待つ
5．ファンクションセット(8bit_mode設定)
6．100us以上待つ
7. ファンクションセット(8bit_mode設定)
8. ファンクションセット(8bit_mode設定)
9. ファンクションセット(各種設定)
10. 表示コントロール
11．表示消去
12．エントリーモードセット

となっております．7～12の間も命令に応じたウェイトをおきます．

#LCD_init()

初期化関数　LCD_init()です．

```LCD_init().c
/* LCDのイニシャライズ */
void LCD_init(unsigned char bus, unsigned char line, unsigned char font, unsigned char cursor, unsigned char blink, unsigned char add, unsigned char shift)//LCD_init(1,1,0,1,1,1,0);
{
	unsigned char data=0x00;		// 変数宣言

	
	_wait(1500);					// ウェイト
	
	data=0x30;
	LCD_IR(data);				// ファンクションセット1回目
	_wait(410);						//ウェイト

	data=0x30;
	LCD_IR(data);				// ファンクションセット2回目
	_wait(410);

	data=0x30;
	LCD_IR(data);				// ファンクションセット3回目
	_wait(410);					
	
	data=0x20;					// ファンクションセット(インターフェースデータ長8ビット)
	data   |= (bus <<4);		//バス幅　1:8bit 0:4bit
	data   |= (line << 3); 		//表示ライン 1:2行表示　0:1行表示
	data   |= (font << 2); 		//表示フォント 1:11ライン/行　0:8ライン/行　※11ラインはg,yなどが切れずに表示されるが2行モードが使えなくなる．
	LCD_IR(data);				
	_wait(40);					// ウェイト
	
	data=0x0c;					//表示ON/OFF
	data   |= (cursor <<1);		//下線カーソル　1：ON 
	data   |= blink;      	 	//ブロックカーソル　1:ON
	LCD_IR(data);				
	_wait(40);					// ウェイト
	
	LCD_IR(0x01);				//表示クリア
	_wait(40);					// ウェイト
	
	data	= 0x04;				// エントリモード
	data   |= (add << 1);		 //0:デクリメント　1:インクリメント
	data   |= shift;			//1：表示シフトあり
	LCD_IR(data);				
	_wait(400);					// ウェイト
	
	
}
```
_wait()は割り算をするなどして時間を稼いでください．
ただし，コンパイラによって処理時間が異なるのでそれぞれの環境に合わせて数値を変化させる必要があります．
(規定時間以上待てばよいので全体に影響の出ない範囲で大きな値にしてもよい)

引数として各種パラメータを設定できるようにしてあります．

#LCD_IR

LCD_IR()はインストラクションレジスターアクセス用関数です．

```LCD_IR.c
static	void LCD_IR( unsigned char data )
{
	
   	PDR7 &= 0xef;				//0 LCD_RS(0x10) レジスタをインストラクションレジスター(IR)にセット
    PDR7 &= 0xdf;				//0 LCD_RW(0x20) 0:書き込み　1:読み出し
	PDR7 |= 0x40;				//1 LCD_E(0x40) シグナル可能セット　
	
	PDR8 = data;				//LCD_PORT(Port8) データの書き込み
	_wait(410);					// 20usのウェイト
	
	PDR7 &= 0xbf;				// シグナル可能リセット(Eの立下りでレジスタの読み書きを行う)
	_wait(410);					// 20usのウェイト
}
```

LCD_init()が実行し終わるとセットアップ完了となります．

#LCD_DR

最後に表示用関数LCD_DR()です．

```LCD_DR.c
static	void LCD_DR( unsigned char data )
{
	
	PDR7 |= 0x10;				//1 LCD_RS(0x10) レジスタをデータレジスター(DR)にセット
    PDR7 &= 0xdf;				//0 LCD_RW(0x20) 0:書き込み　1:読み出し
	PDR7 |= 0x40;				//1 LCD_E(0x40) シグナル可能セット　
	
	PDR8 = data;				//LCD_PORT(Port8) データの書き込み
	_wait(410);					//ウェイト
	
	PDR7 &= 0xbf;				// シグナル可能リセット(Eの立下りでレジスタの読み書きを行う)
    _wait(20);
}
```
dataにはASCIIコードが入ります．

#表示例
```
char LCD_title[81]="Yellow_tracer        kiki0817 Yellow_IDE,H8/3664f, from2019_01_19  ";
```

```
for(i=0;i<80;i++){
	LCD_DR(LCD_title[i]);
	}
```

![105651.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/868b96ae-0bc4-87e6-07ec-985fa447d800.jpeg)
springbootとSQSをJMSで連携する際、spring-cloud-sluethの設定により例外が発生してメッセージが受信できない

# はじめに

- AmazonSQSを使用してJMSでメッセージを取得し、かつトレーサビリティ向上のためspring-cloud-sluethを導入することにした

# Dependencis

| プロダクト       |       バージョン |
|:-----------------:|:------------------:|
| springboot | 2.1.x |
| spring-cloud-slueth | 2.1.0 |
| amazon-sqs-java-messaging-lib | 1.0.5 |

# 実装
- `@JMSListener`を使用してSQSからメッセージ受信を行う。

# 結果
- 例外が発生してSQSからメッセージが受信できなかった。

# 対処
- メッセージが受信できないと困るため、spring.sleuth.messaging.jms.enabled=falseに設定して、ログへのTraceId、SpanId出力はあきらめた。

# まとめ
- amazon-sqs-java-messaging-libとspring-cloud-sluethは互いに仕様なのか、単なるバグなのか・・・・

| spring.sleuth.messaging.jms.enabled|`@JMSListener`でSQSからメッセージ受信|備考|
|:------------------------------------:|:------------------:|:------------------:|
| false |可|設定通りTraceId,SpanIdは付与・伝搬されない|
| true  |例外発生で受信不可||

# 参照元
- [Spring Cloud Sleuth](https://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.1.0.RELEASE/single/spring-cloud-sleuth.html)  
- [amazon-sqs-java-messaging-lib](https://github.com/awslabs/amazon-sqs-java-messaging-lib)
主キーが複合キーの場合のPK制約について

主キーが複合キー(複数列)の場合のPK制約についてのメモです。
###UNIQUEは複合キーの組み合わせに対して

SalesHistoryテーブル

| sale_date (PK)|item_no (PK) |    count    |解説        |
|---------------|-------------|-------------|------------|
| 2019/03/01    |101          |20          |             |
| 2019/03/01    |102          |7           |sale_dateだけ重複はOK|
| 2019/03/02    |101          |35          |item_noだけ重複はOK|
| ~~2019/03/01~~    |~~101~~          |50          |両方重複は×   |


###NOT NULLは複合キーそれぞれに対して

| sale_date (PK)|item_no (PK) |    count    |解説        |
|---------------|-------------|-------------|------------|
| 2019/03/01    |101          |20          |             |
| ~~null~~      |101          |35          |sale_dateだけnullでも×|
| 2019/03/02    |~~null~~     |35          |item_noだけnullでも×|
Herokuデプロイにおける、Dockerの動き

#利用環境
- Docker18.09.1 
- Rails5.2.2
- Ruby2.5.3
- Mac OS Mojave10.14.3


#dockerのherokuデプロイ
Railsとdocker環境を利用している場合、herokuへのデプロイのやり方は通常と少し異なります。
例えば、

```
heroku push origin master
```

上記は、おなじみのデプロイ方法かと思いますが、docker利用の場合は、使えません。
では、どうするか？

[@akirakudo](https://qiita.com/akirakudo/items/16a01271b0a39316e439)
さんの記事を参考にします。



#dockerのherokuデプロイ手順

まず、dockerコンテナを削除します。

```
docker-compose down
```

次に、herokuへログインします。

```
heroku login
```

herokuに登録がお済みでない方は、ここで登録をお願いします（クレジットカード情報の登録まで必要です）。

続いて、herokuコンテナへログインします。

```
heroku container:login
```

herokuにてアプリを作成します。

```
heroku create
```

そして、dockerイメージをビルドし、herokuアプリへpushします。
コンテナを削除しますが、ここでイメージをビルドするので、現時点の状態がherokuへ反映されます。

```
heroku container:push web
```

dockerのデータベースにPostgreSQLを利用しますので、herokuにてadd-onを取得します。
この辺りの感覚は、実際にherokuのアプリページをみた方がイメージしやすいかもしれません。

```
heroku addons:create heroku-postgresql:hobby-dev
```

hobby-devのadd-onは無料で使用できますから、ご安心ください。

そして、herokuにアプリをリリースします。

```
heroku container:release web
```

herokuアプリを起動します。

```
heroku open
```

#感じた疑問点
ここで、私が感じた疑問点は、以下の２つです。

- heroku.yml 

ネット上でdockerのherokuデプロイにheroku.ymlファイルを作成するやり方がありました。
これは、最近リリースされた機能のようで、こちらの方法でもデプロイできるようです。
[heroku公式](https://devcenter.heroku.com/articles/build-docker-images-heroku-yml)

- database.yml

あと、Railsのdatabase.ymlでのproductionに関する記述が、herokuで反映されていないことも疑問でしたが、どうやら、herokuがそこを書き換えるようです。


以上が、herokuでのdockerコンテナのpush方法でした。
次回は、heroku.ymlでデプロイしたいと思います。
AWSのElastic Beanstalkにtd-agent3をデプロイする

**目次**
1. はじめに
2. `.ebextension`内にtd-agent3の設定ファイルを作る
3. `.ebextension`内にtd-agent3のインストールファイルを作る
4. デプロイ

## 1. はじめに
環境
fluentd-v1.0(td-agent3)
Amazon Linux 1

## 2. `.ebextension`でtd-agent3の設定ファイルを作る
Elastic Beanstalk以下（eb）では、`.ebextension`という設定ファイルを追加することによって環境設定が可能です。

- 作成したファイルの拡張子は`.config`とし、YAMLもしくはJSON形式にします。
- 設定ファイルはアルファベット順に実行されます。

**(設定ファイル読み込み例)**
以下のように設定ファイルを作成した場合
`.ebextensions/01td-agent3.config`が先に読み込まれます。

`.ebextensions/01td-agent3.config`
`.ebextensions/02td-agent-install.config`

---

**(設定例 01-td-agent.config)**

設定の中身はバージョンによって書き方が異なるので注意が必要ですので、使用されるtd-agentのバージョン確認することをおすすめします。

例えばbufferプラグインでも書き方が全く異なります。

```td-agent2.config
buffer_type file
```

```td-agent3.config
<buffer>
　@type file
</buffer>
```

**(Amazon Linuxのバージョン確認方法)**
使用したいebに接続した状態で`$ cat /etc/system-release`と入力すると、
`=> Amazon Linux AMI release 2017.09`のように使用してるバージョン確認ができます。

下記は`01td-agent.config`の設定例です。
※設定内容は適当ですので、実際に設定したい内容に書き換えてください。

```ebextensions:設定例01-td-agent.config
files:
　"/etc/td-agent/td-agent.conf":
    owner: root
    group: root
    content: |

　　<match pattern1>
  　　<buffer>
    　　@type file
    　　path /var/log/fluent/s3
  　　</buffer>
　　</match>

　　<match pattern>
  　　@type s3

　　  aws_key_id YOUR_AWS_KEY_ID
  　　aws_sec_key YOUR_AWS_SECRET_KEY
  　　s3_bucket YOUR_S3_BUCKET_NAME
  　　s3_region YOUR_S3_BUCKET_REGION
  　　path logs/

　　  <buffer tag,time>
   　　 @type file
    　　path /var/log/fluent/s3
    　　timekey 3600
    　　timekey_wait 1m
    　　timekey_use_utc true
    　　chunk_limit_size 256m
  　　</buffer>
　　</match>
```


## 3. `.ebextension`でtd-agent3のインストールファイルを作る

```
# errors get logged to /var/log/cfn-init.log. See Also /var/log/eb-tools.log
commands:
  01-command:
    command: echo 'Defaults:root    !requiretty' >> /etc/sudoers

  02-command:
    command: curl -L https://toolbelt.treasuredata.com/sh/install-amazon1-td-agent3.sh | sh

  03-command:
    command: /etc/init.d/td-agent restart
```

インストールするURLはご自身の環境に合わせてください。↑はAmazon Linux 1の場合です。


## 4. デプロイ

eb環境がない方は`eb init`でEB上でアプリケーションを作成し、
`eb create`で環境を構築してください。この辺の説明は省きます。

すでにある方は`eb deploy`で設定内容反映させてください。
設定がおかしかったりすると、deployに失敗すると思うので原因はログで確認してください。

`eb ssh`で接続したあと起動確認しましょう。

```eb:便利コマンド
バージョン確認
$ rpm -q td-agent
$ td-agent --version

起動、停止、再起動、ステータス
$ sudo /etc/init.d/td-agent start
$ sudo /etc/init.d/td-agent stop
$ sudo /etc/init.d/td-agent restart
$ sudo /etc/init.d/td-agent status

コマンドライン上でS3プラグインがどんな設定項目を持っているか確認
td-agent --show-plugin-config output:s3
```

**参考**
[Installing Fluentd Using rpm Package](https://docs.fluentd.org/v1.0/articles/install-by-rpm#amazon-linux)
[設定ファイル (.ebextensions) による高度な環境のカスタマイズ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions.html)
[ AWS Elastic Beanstalk の詳細な環境設定 » 設定オプション
](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options.html#configuration-options-precedence)
Swift 5 で String Interpolation をカスタマイズする

記事の内容はこちらを参照してください。
https://mishimay.github.io/b4503b00134c26fb8f53/
<!--


## String Interpolation とは？

文字列リテラルの中に値を挿入（補間）できる機構のこと。
Swiftでは文字列リテラルの中に `\(foo)` という書き方でString以外の値を挿入（補間）できます。

* Interpolation = 挿入・補間の意。
* 語源的には inter(間) + polire(磨く) で「間に入れて修正する」というニュアンスがあります[^2]。
* String Interpolation は「文字列補間」と訳されるのが一般的です[^1]。


### 例

```swift
let age = 31
print("You are \(age)")
```

-> `You are 31`


## デフォルトの挙動を変える
```swift
extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Int) {
        appendLiteral("XXX")
    }
}

let int = 10
let string = "number is \(int)"
print(string)
```

-> `number is XXX`


## 引数を渡して出力を変化させる
```swift
extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Date, formatter: DateFormatter) {
        appendLiteral(formatter.string(from: value))
    }
}

let date = Date()
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
let string = "today is \(date, formatter: formatter)"
print(string)
```

-> `today is 3/30/19, 1:22 PM`


## 独自の型の出力を新しく定義する

```swift
struct User {
    let honorific: String
    let name: String
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: User) {
        appendLiteral("\(value.honorific)\(value.name)")
    }
}

let user = User(honorific: "Mr.", name: "Tom")
let string = "user is \(user)"
print(string)
```

-> `user is Mr.Tom`


## 環境
```
Apple Swift version 5.0 (swiftlang-1001.0.69 clang-1001.0.45.2)
Target: x86_64-apple-darwin18.2.0
```

## 参考
- https://docs.swift.org/swift--book/LanguageGuide/StringsAndCharacters.html 
- https://medium.com/@d_date/whats-new-in-swift-5-70225f063b87
- https://www.hackingwithswift.com/articles/163/how-to-use-custom-string-interpolation-in-swift 

[^1]: https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E5%88%97%E8%A3%9C%E9%96%93
[^2]: https://eng-etymo.com/archives/685


-->
Vue.js + Vuex + TypeScriptを使ってTodoListを作る

Vuexを使っての状態管理のやり方をいまいちイメージできていなかったので、実際に動かしながら作ってみた。

環境はvue-cli 3を使って構築しました。

詳しくは[公式サイト](https://cli.vuejs.org/guide/installation.html)を参照ください。

#環境
node: v10.15.1
npm:  6.8.0
vue:  2.5.22
vuex: 3.0.1
typescript: 3.0.0

成果物のpackage.jsonに環境周りが書いてあるので、ご参考までに

[成果物](https://shu1good.firebaseapp.com/todo)
[成果物github](https://github.com/shuichi0712/my-keiziban)

#そもそも、vuexって何？

vuexの公式サイトには、こう書かれています。

>Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。

詳しくは[公式サイト](https://vuex.vuejs.org/ja/)に詳しく載っています。

#ハマったポイント
1つコンポーネントを作成して、2つ目のコンポーネントを作った時に、片方のコンポーネントしか表示されないなぁって思いました。

原因が、componentsフォルダに入っているコンポーネントファイルたちには、```@Component```をつけないと、コンポーネントとして認識してくれない・・・それで少しハマりました。

```src/component/TodoList.vue
<template>
    <div>
        <h3>Todo List</h3>
        <ul>
            <li v-for="todo in todos" :key="todo.id">
                <p>ID:{{todo.id}}</p>
                <p>Text:{{todo.text}}</p>
            </li>
        </ul>
    </div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
import store from "@/stores/toDo";

@Component//←これをつけないと「コンポーネント」として、認識されない・・・
export default class TodoList extends Vue {
    get todos() {
        return store.getters.todos;
    }

}
</script>
```

##少し考えたところ
今回storeファイルをインポートする形式にしたのは、今後ページを増やす際に、store自体のファイルを増やす可能性が高かったので、storesフォルダを作成して、ページごとにファイルを分けることにしました。

#まとめ
ある程度vuexの流れがわかってきたので、今度はfirebaseを使って、データベース管理をどういう風にやるかを考えて、実装して、記事にしようと思います。

#参考
[Vue.jsとVuexでTodoListを作ってみた](https://qiita.com/tiwu_official/items/d66c5f3fe92794536d32)
Homebrew Caskで強制アップデートしようとするとinvalid 'depends_on macos' value: ":lion" Error

## 対象バージョン

Mac OS Mojave 10.14.3

```shell
$ brew --version
Homebrew 2.0.6
Homebrew/homebrew-core (git revision 59cd7; last commit 2019-03-29)
Homebrew/homebrew-cask (git revision 8c900; last commit 2019-03-30)
```

## 現象

Homebrew Caskでアプリを強制的に更新しようとしたが、下記エラーが出て実施出来ない。

```shell
$ brew cask upgrade --greedy
==> Upgrading 21 outdated packages:
Warning: Unexpected method 'accessibility_access' called on Cask alfred.
Follow the instructions here:
  https://github.com/Homebrew/homebrew-cask#reporting-bugs
Error: Cask 'spotify' definition is invalid: invalid 'depends_on macos' value: ":lion"
```

## 原因

Mac OS X Lionのシンボルが、[/Library/Homebrew/os/mac/version.rb](https://github.com/Homebrew/brew/blob/372a8d45325f53355c36c0f1b264b72cc186bcb0/Library/Homebrew/os/mac/version.rb#L6)
から消えており、[Casks/spotify.rb](https://github.com/Homebrew/homebrew-cask/blob/6794fe97bf7d2a5977673f70e353e7db50450cc5/Casks/spotify.rb#L10)から参照出来なくなっている様子。

## 対応

下記コマンドを実行

```
$ /usr/bin/find "$(brew --prefix)/Caskroom/"*'/.metadata' -type f -name '*.rb' -print0 | /usr/bin/xargs -0 /usr/bin/perl -i -0pe 's/depends_on macos: \[.*?\]//gsm;s/depends_on macos: .*//g'
```

## 確認

再度更新

```
$ brew cask upgrade --greedy

〜 省略 〜

🍺  vlc was successfully upgraded!
```

## 参考

* [Fix casks with `depends_on` that reference pre-Mavericks #58046](https://github.com/Homebrew/homebrew-cask/issues/58046)
グラデーションを使う

#グラデーションを使う
グラデーションには、2つあって、
1.線形グラデーション
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/380575/e3b7a314-9a4e-a5c7-8a67-cf367e6c87c6.png)
2.円形グラデーション
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/380575/800bf544-8859-51ee-056a-8f4ac5ad1982.png)
さらにリピートすることもできる。
基本的な書き方はこう、
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/380575/5036ed65-4d4c-86f6-ff3d-46e92d8b53d1.png)
ベンダープレフィックスと若干違うかな。
方向は、角度での指定もできて（90degみたいな）。
上2つのサンプルのコード載せますね。
1.![無題.png](https://qiita-image-store.s3.amazonaws.com/0/380575/2f117e9a-f547-8d34-99b6-b067c39535fb.png)
2.![無題.png](https://qiita-image-store.s3.amazonaws.com/0/380575/669b072c-f874-98a1-b6ef-66518c40642e.png)
Google Compute Engineサービスレベル契約（SLA）

[Google Compute Engineサービスレベル契約（SLA）](https://cloud.google.com/compute/sla)を日本語訳してみました。（ほとんどGoogle翻訳）

### 最終更新日：2019年3月28日

グーグルがお客様にグーグルクラウドプラットフォームを提供することに同意した契約期間中、対象サービスはお客様に対して少なくとも **99.99％** の月間稼働率を提供します（"サービスレベル目標" または "SLO"） GoogleがSLOを満たしていない場合、およびお客様が本SLAに基づく義務を履行している場合、お客様は以下に説明する財務クレジットを受け取る資格があります。このSLAは、GoogleがSLOを遵守しなかったことに対するお客様の唯一の法的な救済策を述べたものです。このSLAで使用されているがこのSLAで定義されていない用語は、本契約で規定されている意味を持ちます。本契約がGoogle Cloudのパートナーまたはリセラープログラムに基づくGoogle Cloud Platformの再販または供給を承認する場合、本SLAにおけるお客様への言及はすべてパートナーまたはリセラー（該当する場合）を意味し、影響を受けるのは、本契約に基づくパートナーまたはリセラーの注文の金融クレジットのみです。

### 定義
以下の定義がSLAに適用されます。

#### 対象サービス
* Google Compute Engineサービスの一部としてホストされているインスタンス
* Google Compute Engineサービスの一部である負荷分散

#### ダウンタイム
* 仮想マシンインスタンスの場合：インスタンスが同じリージョン内の2つ以上のゾーンにまたがって配置されているときに、実行中のすべてのインスタンスの外部接続または永続的なディスクアクセスが失われること
* ロードバランシングの場合：Googleのシステムの障害による、（すべての正常なバックエンドインスタンスとのロードバランシング転送ルールに関連付けられた外部IPアドレスを介した）外部接続が喪失すること。
* ダウンタイムには、次の結果としての外部接続の損失は含まれません。
  * （i）Googleが管理するVPNサービスが、そのサービス下のVPNトンネルに向けられたトラフィックを処理することに失敗した結果としてのダウンタイム。この種のダウンタイムは、VPN SLAでのみ解決されます。
  * （ii）ネットワークサービス層 - トラフィックを処理できない「Standard Tier」

#### ダウンタイム期間
* 1分以上連続したダウンタイムの期間を意味します。 1分未満の期間の分数または断続的なダウンタイムは、どのダウンタイム期間にもカウントされません。

#### リージョン
https://cloud.google.com/compute/docs/regions-zones/ に記載されている該当地域を意味し、随時Googleによって更新される可能性があります。

#### ゾーン
https://cloud.google.com/compute/docs/regions-zones/ に記載されている該当するゾーンを意味します。これは、Googleによって随時更新される可能性があります。

#### 金融クレジット
|月間稼働率  |SLOを満たさなかった場合に、影響を受ける地域の各対象サービスのその月の請求額のうち、次回以降の請求書に加算される割合  |
|---|---|
|99.00% - < 99.99%  |10%  |
|95.00% - < 99.00% |25%  |
|< 95.00% |50%  |

#### 毎月の稼働時間の割合
1か月の総分数から、1か月の全ダウンタイム期間に発生した休止時間の分数を引いたものを、1か月の合計分数で割ったものです。

#### 健全なバックエンドインスタンスとは
負荷分散ヘルスチェックに正常に応答しているインスタンスを意味します。

### 利用者は金融クレジットを要求する必要がある
上記のいずれかの金融クレジットを受け取るには、お客様が金融クレジットを受け取る資格を得た時点から **30日以内** に、お客様がGoogleのテクニカルサポートに通知する必要があります。お客様は、**外部接続エラーの消失とそれらのエラーが発生した日時を示すサーバーログファイル** もGoogleに提供する必要があります。お客様がこれらの要件を満たしていない場合、お客様は金融クレジットを受け取る権利を失います。このSLAに関して紛争が発生した場合、Googleはシステムログ、監視レポート、設定記録、およびその他の利用可能な情報に基づいて誠意を持って判断します。Googleはこれをお客様の要求に応じて監査できるようにします。

#### 最大金融クレジット
1ヶ月の請求月に発生する、停止期間中にGoogleからお客様に発行される金融クレジットの合計最大数は、該当する月の対象サービスに対してお客様が支払うべき金額の50％を超えることはありません。金融クレジットは、本サービスの使用に将来的に適用される金銭的クレジットの形で行われ、金融クレジットが要求されてから60日以内に適用されます。

#### SLAの対象外
*  （a）AlphaまたはBetaに指定された機能（関連資料に別途記載がない限り）
* （b）SLAから除外された機能（関連資料内）
* （c）エラーには適用されません。 
     * （i）Googleの合理的な管理の範囲外の要因によって引き起こされた。 
     * （ii）お客様のソフトウェアまたはハードウェア、サードパーティのソフトウェアまたはハードウェア、あるいはその両方に起因するもの。 
     * （iii）本契約に違反する悪用またはその他の行為によるもの。
     * （iv）システムによって適用されたクォータ、および/またはアドミンコンソールに表示されたクォータの結果。
正規化について

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/c7bfdc98-ddbe-27e1-3751-210c57223068.png)

こちらの本を読んでまとめ
正規化について

## 正規化とは
あるルールに従った形に整理すること

## 正規形とは
正規化には何段階かレベルがあり、それらを正規形と呼ぶ

## 第1正規形
1テーブルに1つのカラムに1つの値が入った状態

- **スカラ値**という状態

## 第2正規形
1テーブル内で主キー以外で主キーのような役割になっているカラムのグループを別テーブルへ切り出した状態

- **完全関数従属**という状態

## 第3正規形
1テーブル内で主キーと1対多の関係になる実用値が入るカラムを切り出した状態

- **推移的関数従属**という状態

## DB設計時
基本的には第3正規化までを行えば良い

## 実践メモ
ここからはあくまで個人的観測(他の書籍から得た知見も含む)

### 基本ステップ
- 業務概念を洗い出す
- 1つの概念に相当するデータ項目を洗い出す
- データ属性を定義する

### ポイント
- ある程度システムの全体像があって、必要なデータがイメージできるなら第1正規化から順を踏んで行う必要はない
- 第2、第3正規化を検討しながら繰り返す
- 概念として洗い出すのとテーブルやカラムとして洗い出すのを分ける考え方もあるが、一緒に考える
  - 設計を追加・改善する前提なため
  - ドキュメントの管理コストを減らすため
  - 設計は業務知識習熟度に依存し、経過によってより良い設計ができるため

### 業務概念を洗い出す
洗い出す際は大きく2つに大別して考える

- マスタ系
  - 実在する具体情報系 
- トランザクション系
  - 活動による記録情報系

概念はひとまずテーブル名として考える
項目はひとまずカラム名として考える

### 1つの概念に相当するデータ項目を洗い出す
データが活用される画面や業務をイメージしながら、そこで使われるデータが概念に含まれるか検討しつつ洗い出す

- 最初に洗い出した概念の中になさそうな場合は新しい概念を作成する
  - 非依存型のテーブル

- 最初に洗い出した概念の中に項目を洗い出していった後、更に細かい項目が出てきたら別概念として切り出す
  - 依存型のテーブル
  - 関数従属の関係
  - リレーションシップを引く

- 最初に洗い出した概念がある性質に特化した概念として、システム上重要度が高い場合は汎化型の概念として作成する
  - オブジェクト指向のサブクラスのようなイメージ

### データ属性を定義する
フレームワークやDB(サービス)によってよしなにできたり制約があったりするので、前提としてアーキテクチャの選定を行っておく
それに法って決める

## 雑感
データの設計ができるとシステム地盤ができて開発時に浮遊感がなくなる気がするので、初期にしっかり行う
Bitbucketで出たエラー


現在チュートリアル９章まで進めてますが、
改めて息抜きがてら１章からもう一度やろうとしたら
予期せぬエラー多発したので記事にまとめます。

（９章まで進んでるから大丈夫でしょ！と軽い気持ちで挑んだ自分が恥ずかしい・・）

#エラー①：
まずBitbucketのリポジトリの追加と、
プッシュができない。



```git remote add origin git@bitbucket.org:ユーザー名/hello_app.git
```
上記のコマンドを入力した際に、

```fatal: remote origin already exists. 
```
というエラーメッセージが出た。

こちらに関しては、一回消してね〜というような解釈みたいなので

```git remote rm origin```でoriginを削除して、

再度、以下のコマンドを入力
```git remote add origin git@bitbucket.org:ユーザー名/hello_app.git```で解決！


#エラー②：
次に```git push -u origin --all```を入力したところ、
画像のエラーが返ってきた。

![スクリーンショット 2019-03-30 10.12.56.png](https://qiita-image-store.s3.amazonaws.com/0/378334/fdc20383-38fe-3542-f821-e56fe40396df.png)

訳がわからなかったので、
色々ググった末にゼロから再スタートしてみました。

```git init```
①でやったことを再度繰り返したあとに、以下を入力。
```echo "アカウント名" >> contributors.txt```
```git add contributors.txt```
```git commit -m "first commit"```
```git push -u origin --all```

これで解決が出来ました。


ググれば、色々な方が試した方法が書いてあるので
取捨選択してとりあえず取り組んでみることにします。


#＊２０１９年３月３１日　追記

エラーになった原因としては、

BitbucketのSSH鍵を作成した際に、
ターミナルは~sshのままだったのが原因。
自分のいる場所が~sshのままgit add~をしていたからという凡ミス。

きちんとcdでhello_appに移動していれば何の問題もありませんでした。

これ多分、何気につまずく方いるのかな？
私は気づいた時にかなりスッキリしました。（くやしい！）
Evernote(無料版)でバックアップを効率よく行う

# はじめに

Evernoteの無料版を長年利用しています。ある日突然、Evernoteのクラウドサーバーがクラッシュして、重要なメモが全て取り出せなくなった！という事態はあまり考えられない話だとは思いますが、定期的にローカルにバックアップを取っておく事は重要な事だと思います。そこで大量のノートのバックアップを効率よく行う方法について書いてみました。
デジタル遺産の問題もあるだろうし、Evernoteのクラウドの容量の問題とか、経営的な問題で、突然、データを削除します！という事はありうる話だと認識しておいた方がいいでしょう。Google+もデータが削除された事だし。

# 環境

Windows10
Evernote Ver 6.17

# バックアップの取り方

　バックアップの取り方は簡単で、ファイル－エクスポートを選ぶだけでバックアップは取れます。しかし、普通にバックアップを取っただけであれば、現在選択されている１つのノートだけしかバックアップは取れません。

　１つのノートブックに存在する、複数のノート全てに対しバックアップを取りたい場合は、Ctrlキーを押しながら、全ノートを選択した状態にしてからエクスポートをすると、全ノートがバックアップされます。しかし、ノートブックの中に数十個のノートしか存在しない場合であれば、このやり方でいいのだが、数百ものノートが存在する場合、全てのノートを選択しなくてはいけなくなり、このやり方では結構面倒です。

　そこでお薦めなのが、複数のノートブックをスタックに入れて管理する方法です。スタックとは、複数のノートブックを束ねて管理できるディレクトリのようなものです。「スタック＞ノートブック＞ノート」の管理階層となります。因みに、スタックの配下にノートを直接保存する事はできません。

　スタックの作り方ですが、左サイドバーに表示されているノートブックを、別のノートブックの上にマウスでドラックすると作成されます。
《Befor》
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/c351cd46-3bba-3621-5641-67b87234efa7.png)
《After》
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/e65f47a4-d831-5e8e-6576-7bf17da7f330.png)
そして、スタックを右クリックして、「ノートをエクスポート」を選択すると、スタック単位でバックアップが取れます。つまり、スタック配下のノートブック、ノートが全て一括でバックアップが取れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/05012506-2e2b-3b16-9ce4-4579bdb9fea1.png)
これなら、大量のノートを保存していても、バックアップが簡単ですね。
外部ツール無し(iframe+contentsメソッドの組み合わせによる取得)で、Seleniumのような自動化を実現しよう

# はじめに
セキュリティ上の理由により、プラグイン等のインストールを実施できない中で、
なんとかSeleniumのような動作を実現できないか調査した所、
少し無理矢理ながらもできたので、メモを残したいと思います。

# 課題整理
単純に画面へJavascriptを埋め込むのでは、遷移時にクリアされてしまいます。
では、遷移する度に埋め込むのか？そのような事では自動化とは言えません。
ということで、iframeにて操作したい画面を描画し、
親画面からcontentsメソッドを使用して操作する事にしました。

# 問題発生
試しに以下のスクリプトを実行した所、エラーが発生しました。

```javascript:
// 流したスクリプト
$("#iframeのid").contents().find("#操作したいtextのid").val("hoge");

// エラーメッセージ
VM183:1 Uncaught TypeError:$(...).contents is not function
   at<anonymous>1:11
```

存在するはずのメソッドが使用できない、、、？なぜ？？
というわけで調査した所、どうやらクロスドメイン制約によるものという事がわかりました。
（参考サイト https://qiita.com/growsic/items/a919a7e2a665557d9cf4）

先人の方々も調査を行っているようで、既に対策も確認する事ができました。
（参考サイト http://shinimae.hatenablog.com/entry/2015/12/09/183057）

同じ方法でやってもなぁ、、、さて、どうするか。

# 斜め上の発想で対応
同一ドメインであれば問題ないのであれば、
一度、操作したいページを描画し、そのhtmlを書き換えてしまえばいいのでは？
※具体的にはbodyの中身をクリアし、そこへiframe要素を追加してそこで描画し、操作してみる。

というわけで試してみたところ、、、成功しました！
これはセキュリティ的に大丈夫なのか？という怪しい所を残しながらも突破できたので、とりあえずは良しとすることにしました。
※この手法を採用する際は、自己責任でおねがいします。

```javascript:
// 埋め込み時
$("body").html("<iframe id='hoge' src='操作したいurl' width='好きな幅' height='好きな高さ'/>");

// 操作時
$("#hoge").contents().find("#書き換えたいtextのid").val("test");

// 画面遷移判定
$("#hoge").load(function() {
  console.log("遷移完了");
}
```

# 最後に
アカウント情報等の利用者毎に事なる値を入力する運用に使用したい場合は、
html書き換え時にtext等を配置し、その値を使用するのも良いかと思います。
ただ、amazonなどは、iframeでの表示を制限した作りになっているようなので、注意ですね。
【CSS】CSSアニメーション でいろんなものを動かしてみる

#CSSを使っていろんなものを動かしてみる
例えばこんなの

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="Ryotokubo" data-slug-hash="ywjVza" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="border animation">
  <span>See the Pen <a href="https://codepen.io/Ryotokubo/pen/ywjVza/">
  border animation</a> by Ryoto kubo (<a href="https://codepen.io/Ryotokubo">@Ryotokubo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

よくwebサイトで見かけると思いますが、実はCSSだけなんですね。

こういうのもそう。
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="Ryotokubo" data-slug-hash="QPLmGX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="QPLmGX">
  <span>See the Pen <a href="https://codepen.io/Ryotokubo/pen/QPLmGX/">
  QPLmGX</a> by Ryoto kubo (<a href="https://codepen.io/Ryotokubo">@Ryotokubo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

全てCSSのみです。
これを使えば要素にカーソルを乗せたとき画像を少し大きくしたり、時間差で色を変えるなんてこともできます。

転職を志しhtmlとCSSを学び始めると、行き着くとこはポートフォリオ作成だと思います。

その過程の中で「少しでも見た目を良くしたい」「凝りたい！」みたいな気持ちもあるかと思います。
そんなときCSS アニメーション使ってみましょう

尚、ここではややこしいコードの説明は割愛します。

興味がある方はgoogleで

**「CSS アニメーション 」**
**「CSS animation」**
**「CSS animation まとめ」**

などと調べてみてください。様々なパターンが見れて「あっ！これもCSSでできるんだ」と思う動きがあるはずです。
尚、コードの詳細が知りたい方は

**「animation keyflames」**

と検索してみてください。
animationで動きの設定を作ってあげて、keyflamesでどう動くのかを設定してあげるといった感じなのですが、設定にも種類があり設定次第では様々な動きがつけられますので。

では。
SICP読書録 #26 練習問題2.33 - 練習問題2.36

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら](https://qiita.com/shuetsu@github/items/4a7828d3db18a91481cc)

### 練習問題 2.33

`accumulate`手続きを用いてリスト操作を定義する。

``` _.scm
; 再掲
(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

(define (map p sequence)
  (accumulate (lambda (x y) (cons (p x) y)) nil sequence))

(define (append seq1 seq2)
  (accumulate cons seq2 seq1))

(define (length sequence)
  (accumulate (lambda (x y) (+ y 1)) 0 sequence))
```

実行結果。

``` _.scm
gosh> (map square '(1 2 3 4))
(1 4 9 16)
gosh> (append '(1 2) '(3 4))
(1 2 3 4)
gosh> (length '(1 2 3 4))
4
```

### 練習問題 2.34

ホーナー法というアルゴリズムによって評価すると、以下の多項式は

``` math
a_nx^n+a_{n-1}x^{n-1}+...+a_1x+a_0
```

次の式と等価である。

``` math
(...(a_nx+a_{n-1})x+...+a_1)x+a_0
```

この式を評価する手続きを作ってみよう。

``` _.scm
(define (horner-eval x coefficient-sequence)
  (accumulate 
    (lambda (this-coeff higher-terms) 
      (+ (* higher-terms x) this-coeff))
    0 coefficient-sequence))
```

この手続きを用いて $x=2$ のときの $1+3x+5x^3+x^5$ を計算してみる。79になるはずだ。

``` _.scm
gosh> (horner-eval 2 '(1 3 0 5 0 1))
79
```

### 練習問題2.35

木の葉を数える手続き`count-leaves'を作ってみよう。

``` _.scm
(define (count-leaves t)
  (accumulate + 0
    (map (lambda (x)
      (if (pair? x) (count-leaves x) 1)) t)))
```

実行結果。

``` _.scm
gosh> (count-leaves '(1 (2 3 (4 5 (6) 7) (8 9))))
9
```

### 練習問題 2.36

`accumulate`手続きの亜種として`accumulate-n`というのを作ってみよう。3つ目の引数として、リストのリストを受け取るというものだ。

``` _.scm
(define (accumulate-n op init seqs)
  (if (null? (car seqs))
    nil
    (cons (accumulate op init (map car seqs))
      (accumulate-n op init (map cdr seqs)))))
```

実行結果。

``` _.scm
gosh> (accumulate-n + 0 '((1 2 3) (4 5 6) (7 8 9) (10 11 12)))
(22 26 30)
```
FirestoreでGraphQLを使う

ポートフォリオのデータベースをFirestoreで作っていて、クライアント側のリソース節約のためにGlaphQLの実装の仕方を調べたのでメモ。
ライブラリはapolloを使っていきます。

```typescript:index.ts
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as serviceAccount from './service-account.json'
import { ApolloServer, gql } from 'apollo-server-cloud-functions'

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount as any)
})

const typeDefs = gql`
type Query {
  workses: [Works]
}
type Works {
  name: String!
  thumb: String!
}
`

interface Works {
  name: string
  thumb: string
}

const resolvers = {
  Query: {
    async workses() {
      const workses = await admin
        .firestore()
        .collection('works')
        .get()
      return workses.docs.map(works => works.data()) as Works[]
    }
  }
}

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req, res }) => ({
    headers: req.headers,
    req,
    res,
  }),
})

export const apollo = functions.https.onRequest(server.createHandler(
////必要であればcorsもオフにできる
//{
//  cors: {
//    origin: false
//  },
//}
))
```

Firebase Functionsに上記のように記述し、デプロイすればURLが発行されてそれがGraphQLエンドポイントになります。
ちなみに、jsonファイルを型付でインポートするにはtsconfigで`resolveJsonModule`プロパティをtrueにする必要があります。
[Java1.8+]LocalDateで次の×曜日の日付を取得する

[TemporalAdjusters](https://docs.oracle.com/javase/jp/8/docs/api/java/time/temporal/TemporalAdjusters.html)の`next(DayOfWeek dayOfWeek)`メソッドが返す[TemporalAdjuster](https://docs.oracle.com/javase/jp/8/docs/api/java/time/temporal/TemporalAdjuster.html)のインスタンスを使って`LocalDate`の日付を次のx曜日の日付に変更できます。

サンプルコード

```java
LocalDate d = LocalDate.of(2019, 3, 25).with(TemporalAdjusters.next(DayOfWeek.MONDAY));
LocalDate d2 = LocalDate.of(2019, 3, 29).with(TemporalAdjusters.next(DayOfWeek.valueOf("MONDAY")));
LocalDate d3 = LocalDate.of(2019, 3, 31).with(TemporalAdjusters.next(DayOfWeek.of(1)));

 System.out.println(d.toString());
 System.out.println(d2.toString());
 System.out.println(d3.toString());
```

出力

```
2019-04-01
2019-04-01
2019-04-01
```

LocalDateの日付がすでにその曜日の場合、翌週の日付に設定されます。

`nextOrSame(DayOfWeek dayOfWeek)`を使用すると、LocalDateがすでにその曜日である場合何もしません。

サンプル

```java
LocalDate d = LocalDate.of(2019, 3, 25).with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
LocalDate d2 = LocalDate.of(2019, 3, 29).with(TemporalAdjusters.nextOrSame(DayOfWeek.valueOf("MONDAY")));
LocalDate d3 = LocalDate.of(2019, 3, 31).with(TemporalAdjusters.nextOrSame(DayOfWeek.of(1)));
```

出力

```
2019-03-25
2019-04-01
2019-04-01
```
Alexa ASK CLI コマンドで東京リージョンにデプロイする

#まえがき
alexaスキルを開発している際に、zipにしたり、AWSとAmazon開発者への行き来が面倒になりCLIを使ってみる事にしたので、その際の手順を記載したいと思います。

# 前提
[AWSアカウント](https://aws.amazon.com/jp/) への登録が完了している。
[Amazon開発者アカウント](https://developer.amazon.com/ja) への登録が完了している。
[AWS CLI](https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html) がインストール及び設定されている。
※設定時にリージョンは**region = ap-northeast-1**にしてください

# インストール方法
## インストール
```sh
$ npm install -g ask-cli
```
## インストール確認
```sh
$ ask -v
```
## 認証情報を設定
```sh
$ ask init
```
※AWS CLIで設定したプロファイルを選択
## 使用可能なプロファイルのリストを表示
```sh
$ ask init -l
```
## プロファイルの場所
```sh
$ cat ~/.ask/cli_config
```

# プロジェクトの作成方法
## プロジェクトの作成
```sh
$ ask new
? Please select the runtime Node.js V8
? List of templates you can choose Hello World
? Please type in your skill name:  alexa-skill-sample
```
## 不要なファイルを削除し以下の構成にする
```
alexa-skill-sample
├── README.md
├── hooks
│   ├── post_new_hook.ps1
│   ├── post_new_hook.sh
│   ├── pre_deploy_hook.ps1
│   └── pre_deploy_hook.sh
├── lambda
│   └── custom
│       ├── index.js
│       ├── node_modules
│       ├── package-lock.json
│       └── package.json
├── models
│   └── en-US.json
└── skill.json
```
## skill.jsonの修正（日本語化）
**skill.json** の **en-US** を **ja-JP** に変更する
## ja-JP.jsonの作成（日本語化）
**en-US.json** を **ja-JP.json** にリネーム

# プロジェクトをデプロイする
## コンフィグを修正
```sh
$ cat .ask/config
{
  "deploy_settings": {
    "default": {
      "skill_id": "",
      "was_cloned": false,
      "merge": {
        "manifest": {
          "apis": {
            "custom": {
              "endpoint": {
                "uri": "AlexaSkillSample"
              }
            }
          }
        }
      }
    }
  }
}
```
※デプロイすると **skill_id** の値など追加されます
## デプロイ
```sh
$ ask deploy
```

# 結果
AWS
![aws.png](https://qiita-image-store.s3.amazonaws.com/0/142542/24644569-53ed-950c-f222-398923e0428d.png)

ALEXA
![alexa.png](https://qiita-image-store.s3.amazonaws.com/0/142542/97e16a10-91c9-8039-f87a-931d28cd3c5d.png)

# まとめ
東京リージョンのデプロイが目的でしたので、必要最低限のことを記載しました。
設定関連（インテント等）についてはデフォルトのままにしています。必要に応じて修正してください。

また、ja-JP.jsonを直接を編集してスキルモデルを修正できる方はいいのですが、
私はAmazon開発者コンソールで編集した後、JSONエディターの内容をja-JP.jsonにコピペしたりしています。

今回使用したソースは[こちら](https://github.com/whoshino/alexa-skill-sample/tree/ask-cli)にあります。

# 参考
[Alexa Skills Kitコマンドラインインターフェース（ASK CLI）リファレンス](https://developer.amazon.com/ja/docs/smapi/ask-cli-command-reference.html)
[スキルマニフェストのスキーマ](https://developer.amazon.com/ja/docs/smapi/skill-manifest.html)
[WIP]PhperKaigi GMOペパボ endu さん [フレームワークを作りながらLaravelのアーキテクチャを学ぶ]

# タイトル

フレームワークを作りながらLaravelのアーキテクチャを学ぶ

[GMOペパボ endu](https://twitter.com/Fendo181) さん


# なぜフレームワークを作るのか

フレームワークの動きを学びたかった。



Phper人生


手段は本質よりも早く廃れる。
→ だから根っこの部分を知りたかった。
→ それが本質に当たる、ララベルのアーキテクチャがなぜそのアーキテクチャを採用したのかといったことを知りたかった。

Soku Framework 


ClassLoaderがなぜあるのか？
composer.loaderを自作したみたいなもん。

基本に忠実なMVCを作っている。
→ 名前解決が重要だと実感できる。
→ オレオレFWの簡単なテストを書くと良さげ！(これ研修にいかせそうだな)

# Laravelとオレオレフレームワークを比較

## DI

「依存性の注入」
言葉わかりにくくね？

「コンストラクタインジェクション」
ServeiceINterfaceクラスを作成し、そこからコンストラクタインジェクションを行う。

### 結論

必要なオブジェクトを外部から注入する

## DIコンテナ


注入する内容が多くなると面倒。醜い。
インスタンスのDIコンテナをやると、使うときに、インスタンスの生成を1行か2行に短縮できる。
事前にオブジェクトの生成をやる。

## サービスコンテナ

Laravelが提供しているのが、サービスコンテナ

bind → インスタンスの生成方法を登録する。 
resolve → サービスコンテナにおいてインスタンスを取得する

## ファサード

- ファサードクラス(config)の解決
- ファサードクラスのクラスメソッド実行
- サービスコンテナからインスタンスを取得
- インスタンスメソッドの実行

# 本題: Laravel

アーキテクチャあんまり変わってなくね？
→ 違うんですよ。

アーキテクチャの各機能が密結合だったんだが、
ファサードを使うと、全て単体になり、ファサードを使ってそれぞれの依存関係を疎にしてくれている。

# ファサード本当にいいのか？

便利ではあるが、依存関係が隠蔽されるので、使うすぎるとわかりづらくなってしまう。
クラス中心の責任が不明瞭になってしまう。

# 質問

## 何を伝えたかったのか

ファサードってどこからも呼べるので、目的に沿って必要な時のみ適切に使いましょうということ！

## DIコンテナのライブラリとかティンプル以外にもサンプルにしたものあるのか？

ティンプルしか使っていない。
そのあとにLaravelのものと見比べた。
github ことはじめメモ


## github使う時に最初にやること

```powershell
# 初期化
git init

# 設定
git config user.name ユーザー名
git config user.email eメールアドレス

##########################################
# ssh接続したい場合（HTTPSだと毎回ログイン情報を問い合わせられる)
# 1: ローカルで公開鍵と秘密鍵を生成します
#   -t: 暗号化方式 -b:鍵の長さ -C:コメント githubではメールアドレス
#   最初にsshキーの保存場所、次にパスフレーズの入力を求められます
ssh-keygen -t rsa -b 4096 -C "メールアドレス"

# 2: sshの保存先にid_rsa(秘密鍵)とid_rsa.pub(公開鍵)が保存されているので
#    公開鍵をgithubに設定する  
#    右上のアカウントメニュー→SSH and GPG keys→new SSH key


# 3: gitbashでgithubに接続する
ssh -T git@github.com

# 以下の内容を聞かれます
# yesを入力
Are you sure you want to continue connecting (yes/no)? yes
# パスフレーズを入力
Enter passphrase for key 'sshキーを保存した場所/.ssh/id_rsa':
#Hi xxxxxx! You've successfully authenticated, but GitHub does not provide shell access.
##########################################

# 追加 
git add -A   

# コミット
git commit -m "initialize repository"

# remote
git remote add origin リポジトリurl

# push
git push -u origin --all
```

```shell
# git addとcommitを同時に
git commit -a -m "Improve the README file"
```

## 間違って消してしまった場合

### 直前のコミットの内容でローカルリソースで上書き

```shell
git checkout -f
```

## branch作って、ソース編集 masterにマージ

```shell
# branch作成し、選択
git checkout -b ブランチ名

# branchの一覧を表示(確認用）
git branch

###### ソース編集

# add & commit
git commit -a -m "コミットメッセージ"

# masterに切り替え
git checkout master

# branchをmasterにマージ
git merge branch名

# branchを削除。ただし、残しておいても問題はない
# 
git branch -d ブランチ名

```

# Herokuにデプロイ

```
# 前提条件: 最初の手順でssh接続設定している
# heroku CLIをインストールしている

# ログイン
heroku login

# アプリケーション作成
heroku create

# herokuにデプロイ
git push heroku master
```
#shell script で標準入力を全て読む

# script

`cat /dev/stdin`

# exe

```
$ echo "A\nB\nC" | bash stdin.sh
A
B
C
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/992








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Windows CMD フォルダ内のバッチを数値順に実行

# 説明

いくつものバッチを順番に実行していくのが手間な時に、、、
バッチ以外も実行します。その際は、絞り込みを行えばOKです。

``` cmd
for /F %%a in ( 'dir /B /on') do (
    call %%a
)
```
ABCIの環境構築


産総研のスパコン，[ABCI](https://abci.ai/)のセットアップに関する記事．

参照：[ABCIユーザガイド](https://portal.abci.ai/docs/ja/01/)，[ABCI実行環境](https://docs.abci.ai/ja/03/)

# 0．ユーザ登録
[ユーザ登録](https://abci.ai/en/how_to_use/)．
ユーザ名が発行されたら，メールが届くのでパスワードを登録する．

次に[利用者ポータル](https://portal.abci.ai/user/)へログイン．

# 1．公開鍵
このサイトにローカルからABCIに接続する際の公開鍵を作成・登録する．登録はローカルマシンごとに行う．

```terminal
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "何かコメントをつけたかったらここに書く"
```

# 2．sshのconfigファイルを作成

```terminal
$ cd ~/.ssh
$ emacs config
```

```conf
# configファイルの中身
# abci
Host abci
    HostName es
    User 発行されたユーザ名
    ProxyCommand ssh -W %h:%p 発行されたユーザ名@as.abci.ai
```

# 3．実際にssh
上のconfigファイルのおかげで，ssh abciと打てば，ssh接続できるようになる．

```terminal
$ ssh abci (or ssh -L 10022:es:22 -l 発行されたユーザ名@as.abci.ai)
The authenticity of host 'as.abci.ai(...)' can't be established.
ECDSA key fingerprint is ....
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'as.abci.ai,...' (ECDSA) to the list of known hosts.
Connection closed by ... port 22
ssh_exchange_identification: Connection closed by remote host

$ ssh abci
# ここで秘密鍵のPWが求められる
```

# 補足(便利なコマンド)

## 1．ローカルディレクトリとSSH先を同期するコマンド

```terminal
# ABCIにあるresearchというディレクトリにローカルのabciというディレクトリを同期．
local-machine:~$ sshfs abci: ~/research abci
# ABCIに同期していたabciというディレクトリの同期を解除．
local-machine:~$ fusermount -u abci
```

## 2．ABCIのディレクトリにローカルからファイルをコピーするコマンド

1．以外の方法

```terminal
# ローカルからリモートへ
local-machine:~$ scp ~/test/test.py abci:~/research

# リモートからローカルへ
local-machine:~$ scp -r abci:[パス] .
```

## 3．インタラクティブノードに入る際のコマンド

一例として，GPUを保持する最小の計算ノードを例示した．その他の計算ノードの指定に関しては[こちら](https://portal.abci.ai/docs/ja/03/)を参照すること．

```terminal
発行されたユーザ名@es:~$ qrsh -g gグループ番号 -l rt_G.small=1

# インタラクティブノードに入ると`@`以下が`g00#(#は任意の自然数)`に変わる．
発行されたユーザ名@g0001:~$ 
```
PythonでURLエンコードする際の初歩的なミス

# 経緯
APIを使用するスクリプトの実装時にHPPTリクエスト（GET）を実行する必要がありました。
その際のパラメーターとして日本語を使用するので、
URLをエンコードする必要があったのですがその際にしてしまった初歩的なミスについて記載します。
※本当に情けないくらい初歩的なミスです。

# 初期実装
パラメーターをエンコードすればいいと思ったので以下のような実装をしていました。

```py
import requests

parameter = 'パラメーター'.encode('utf-8')
url = 'https://api.url?parameter=' + parameter
res = requests.get(url)
```
上記のようなパラメーターのエンコードでGETしたところエラーになりました。
エンコードしたパラメーターを出力してみると

```
b'\xe3\x83\x91\xe3\x83\xa9\xe3\x83\xa1\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\xbc'
```
のような形式で出力されていました。
これはさすがに違和感を覚えました。

# 修正後の実装
しかし、URLをエンコードする際はUTF-8でエンコードするのではなくパーセントURLでなければならないので、
以下のような実装でなければGETは通りません。

```py
import requests
import urllib.parse

parameter = urllib.parse.quote('パラメーター')
url = 'https://api.url?parameter=' + parameter
res = requests.get(url)
```
パラメーターの出力結果は以下のようにパーセントエンコードになります。

```
%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC
```
上記の実装に修正したことで正常にGETできるようになりました。
以上です。
[JavaScript] 正規表現

# 正規表現
今回は正規表現の基礎的な部分を説明していきたいと思います。

## 正規表現とは
特定の文字列などを切り取ったり、置き換えたり、検索したりする技術です。

特に多く利用するケースが

**・文字列を置き換える**
**・文字列を検索し抽出する**
**・条件にマッチしているか調べる**

かと思います。
今回は上記の際によく利用するreplaceメソッドとmatchメソッドについて説明していきたいと思います。

### replaceメソッド
replaceメソッドは読んだままの通り文字列を置き換える事ができます。
実際のコードで説明します。

```正規表現.js
var name = "私はゆーいちです"；
    name.replace(/ゆーいち/, "エンジニア");
   => "私はエンジニアです"
```

これで文字列を置き換える事ができました。
まずvarというのはJavaScript内で変数を定義するときの宣言のようなものです。
文字を置き換える時には、replaceメソッドの第一引数に置き換える部分の文字列を//の中に入れます。
そして第二引数に置き換えた後の文字列を指定します。

### matchメソッド
matchメソッドは文字列の中に特定の文字列があるかどうかを確かめてくれるメソッドです。
実際のコードで説明していきます。

```正規表現.js
var name = "私はゆーいちです";
    name.match(/ゆーいち/);
   => ["ゆーいち"]

    name.match(/エンジニア/);
   =>null
```

これで定義する事ができました。
特定の文字列を抽出する時には、matchメソッドの引数に抽出したい文字列を//の中に入れて定義します。
もしその文字列があればそのまま検索した文字列を配列で返し、なければnullを返します。

## 最後に
今回は正規表現の基礎的な部分を説明していきました。
今回説明したものは、とても簡単な例を紹介しましたが、実際はもっと複雑なものを抽出したりするので次回からもう少し掘り下げた内容を書いていきたいと思います。
ABC - 085- A&B&C

#AtCoder ABC 085 B&C
[AtCoder - 085](https://atcoder.jp/contests/abc085)


#A問題

 - 2017を2018にreplaceする

```java
	private void solveA() {
		Scanner scanner = null;
		String line = "";

		try {
			scanner = new Scanner(System.in);
			line = scanner.next();

			System.out.println(line.replaceAll("2017", "2018"));

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#B問題
コメントはfor文仕様

 - もちを小さい順にソートする
 - 同じ直径のもちは一つとしてカウントする

```java
	private void solveB() {

		final Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int[] wk = IntStream.range(0, n).map(i -> scanner.nextInt()).toArray();
		//			int[] wk = new int[n];
		//
		//			for (int i = 0; i < n; i++) {
		//				wk[i] = scanner.nextInt();
		//			}

		Arrays.sort(wk);

		int res = IntStream.range(0, n).reduce(0, (sum, i) -> {
			if (i == 0) {
				sum++;
			} else if (wk[i] != wk[i - 1]) {
				sum++;
			}
			return sum;
		});
		//			int res = 0;
		//			for (int i = 0; i < wk.length; i++) {
		//				if (i == 0) {
		//					res++;
		//				} else if (wk[i] != wk[i - 1]) {
		//					res++;
		//				}
		//
		//			}

		System.out.println(res);
		if (scanner != null) {
			scanner.close();
		}
	}
```

#C問題
計算量の削減の話

 - $i=10000,y=5000,k=1000$
    - Yが $\leqq2×10^7$ なので$i*10000$の最大値が決まる（continueではなくてbreak。。。）
    - $j$の最大値（5000円を使える枚数）は$\leqq n-i$枚まで
    - 今までの条件より、kの値は$k=n-i-j$と決まる
        - 上記以外のKは利用可能枚数の制限から外れるため計算不要。これでloopを削減できる

```java
	private void solveC2() {
		Scanner scanner = null;
		int n = 0;
		int y = 0;

		try {
			scanner = new Scanner(System.in);
			n = scanner.nextInt();
			y = scanner.nextInt();

			for (int i = n; i >= 0; i--) {
				if (i * 10000 > y) {
					continue;
				}
				for (int j = 0; j <= n - i; j++) {
					int k = n - i - j;
					if (i * 10000 + j * 5000 + k * 1000 == y) {
						System.out.println(i + " " + j + " " + k);
						return;
					}
				}
			}

			System.out.println(-1 + " " + -1 + " " + -1);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}

```

#C問題：遅い実装

 - for文を3回も重ねると間に合いません。
 - ただ、問題文どおりの素直な実装ではある。TLEだけど。

```java
	private void solveC() {
		Scanner scanner = null;
		int n = 0;
		int y = 0;

		try {
			scanner = new Scanner(System.in);
			n = scanner.nextInt();
			y = scanner.nextInt();

			for (int i = n; i >= 0; i--) {
				if (i * 10000 > y) {
					continue;
				}
				for (int j = 0; j <= n - i; j++) {
					for (int k = 0; k <= n - i - j; k++) {
						if (n == i + j + k && i * 10000 + j * 5000 + k * 1000 == y) {
							System.out.println(i + " " + j + " " + k);
							return;
						}
					}
				}
			}

			System.out.println(-1 + " " + -1 + " " + -1);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```