OmniAICreator/Qiita-1.07M huggingface dataset:
Using Cloud SQL with Go Tutorial で デプロイできないエラー

# Google Cloud Platform チュートリアルエラー

Google Cloud Platform から Go を使ったチュートリアルが出ていたので、Go と GCP をいっぺんに学べるいい機会だと思い始めました。
チュートリアル：https://cloud.google.com/go/getting-started/tutorial-app

##問題発生

チュートリアル通り進めると、デプロイ段階で失敗した。
データベースに接続できないらしい。

```sh
$ gcloud app deploy

=======
省略
=======

Updating service [default] (this may take several minutes)...failed.                                                                                                                               
ERROR: (gcloud.app.deploy) Error Response: [9] 
Application startup error:
2019/06/10 06:36:23 mysql: could not connect to the database: dial unix /cloudsql/groovy-environs-243305:asia-northeast1:library: connect: no such file or directory
```

##原因
Cloud SQL Admin API が有効になっていなかった。

チュートリアルでは [Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy) を使ってDBに接続します。この時 Cloud SQL Admin API が必ず有効になっていなければならないのですが、チュートリアルでは 「詳しくはこちら」 で済まされていてちょっとハマりました。

有効にしておくことが必要な他の API はチュートリアル本編に書かれていますが、これだけ書かれていないので注意です。

>To use the proxy, you must meet the following requirements:
- The Cloud SQL Admin API must be enabled.  <= これ
- You must provide the proxy with GCP authentication credentials.
- You must provide the proxy with a valid database user account and password.
- The instance must either have a public IPv4 address, or be configured to use private IP.
The public IP address does not need to be accessible to any external address (whitelisted).
[Requirements for using the Cloud SQL Proxy / Google Cloud Platform](https://cloud.google.com/sql/docs/mysql/sql-proxy#requirements)





##解決方法
チュートリアルを展開しているプロジェクト内で、Cloud SQL Admin API を有効にする。

##どーでもいいこと
自前でこんなに充実したチュートリアルを出せる Goolge さんの器のでかさに惚れ惚れします。
古いAndroid Studioを入手する方法

下記のリンクから好きなVersionをダウンロードすればOK

[https://developer.android.com/studio/archive.html](https://developer.android.com/studio/archive.html)


利用したいシーンとしては最新版を使っていて、他のプロジェクトを開発するために古いバージョンが必要になった！とかだと思います。

複数version共存で開発できるので困った時はアーカイブからダウンロードしましょう！
「作業ファイルを作成できません。環境変数TEMPの設定を確認してください。」の解決

#Wordの保存ができなくなった．
Wordを起動すると「作業ファイルを作成できません。環境変数TEMPの設定を確認してください。」というエラーが出て，保存ができなくなった．また，Outlookを起動できなくなった．エラーメッセージ通り，環境変数TEMPのパスを確認してみる．

![190610_tempPath_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369267/f413b6f8-2ec4-6947-b0ea-d811f5941e72.jpeg)

[【Windows 10対応】WindowsのTEMP／TMPフォルダの場所を変更する](https://www.atmarkit.co.jp/ait/articles/0402/14/news024.html)によると，TEMPのパスは合っていそうだ．

##解決した
[Microsoftコミュニティ](https://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_word-mso_win10-mso_2010/%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0temp%E3%81%AE/506c87d7-ae09-4d5b-afe8-4de4f3e63b58?messageId=ae676205-ea23-4703-a9af-a36d0f004582&fbclid=IwAR0QzuMxgPPTF64hfZTW5rYCuyTHw7llNMB0CUPQuF9KwroRJSnW2jz2zCU)を参考にした．
一時ファイルの場所は「C:\ユーザ\\<ユーザ名>\AppData\Local\MicrosoftWindows\INetCache」となっていたので，おかしくはなさそうだったが，「C:\ユーザ\\<ユーザ名>\AppData\Local\Microsoft\Windows\Temporary Internet Files」でも大丈夫とのことだったので，Temporary Internet Filesに設定することにした．
　しかし，Temporary Internet Filesを選択すると，「フォルダを移動できません。選択した場所についての情報が収集できません。別の場所を選択するか、その場所へのアクセス権を確認してください。」というメッセージが出て，設定が失敗した．後で分かったが，Temporary Internet Filesは補完されるので，1つ上のディレクトリの「C:\ユーザ\\<ユーザ名>\AppData\Local\Microsoft\Windows」を選択すれば，無事に一時ファイルの場所を設定できた．

一時ファイルの場所を設定すると，無事にWordやOutlookが使えるようになった．
AWS CLIを用いてのECRへのDockerイメージのpush

###### 経緯
CircleCIを用いて、githubにpushしたコードを自動的にAmazonECSにデプロイされるようにしてみたかったので、いろいろ調査しました。
その過程で、AWS CLIを用いてのECRへのDockerイメージをpushする必要があったので、その調査結果を記録しておきます。


###### 前提
AWS-CLIがインストール済みであることを前提とします。インストールされていない場合は、インストール方法はこちら。
[公式ドキュメント：AWS CLI のインストールと設定(https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)](https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)
```インストール確認（バージョン表示）
aws --version
```
戻り値：aws-cli/1.16.164 Python/3.7.3 Darwin/18.6.0 botocore/1.12.154など。

###### 本編
以下、ECRへログインして、Dockerイメージをpushするまで。
[公式ドキュメント：Amazon ECR で AWS CLI を使用する(https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ECR_AWSCLI.html)](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ECR_AWSCLI.html)


１. AmazonECRレジストリへのDockerログインコマンドを取得（１２時間有効らしい）

`aws ecr get-login --region ap-northeast-1 --no-include-email
`
ap-northeast-1は自分の使っているリージョン名に置き換えてください。


２. 以下のような戻り値が帰ってくるので、それをそのままコピペして実行。

`docker login -u AWS -p eyJw...............................jh9 https://999988887777.dkr.ecr.ap-northeast-1.amazonaws.com 
`
**ただし、以下のようにすると、上記１、２を一度に実行できるので、上記１、２は不要です。**
`eval $(aws ecr get-login --region ap-northeast-1 --no-include-email)
`

３. テスト用イメージをローカルPCにPull。今回は、nginx公式シメージを使いました。
`docker pull nginx
`

４. ECRレポジトリ作成。手動で作っておけばよいのですが、ついでにaws cliからやってみました。
`aws ecr create-repository --repository-name nginx-test
`
nginx-testのところは自分が作りたいレポジトリ名に置き換えてください。

戻り値
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:999988887777:repository/nginx-test",
        "registryId": "999988887777",
        "repositoryName": "nginx-test",
        "repositoryUri": "999988887777.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test",
        "createdAt": 1560058104.0
    }
}

５. レポジトリにPush用にタグ付してPush
`docker tag nginx:latest 999988887777.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:latest
`
前の方のnginx:latestのところ(tagの直後）は、ローカルのDockerイメージなので、適当な名前、タグ名に変えてください。
後ろの方のnginx-test:latestは先ほど作成したECRレポジトリ名と、pushするイメージに付けたいタグ名なので、適宜変えてください。
999988887777のところは、自分のIamユーザのACCOUNT_IDで置き換えてください。
ap-northeast-1は自分の使っているリージョン名に置き換えてください。

`docker push 999988887777.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-test:latest
`
以上です。
set -- `getopt -u -o vhp:e:s:u: -l version,help -- "$@"` でなんかオプション追加するときには

set -- `getopt -u -o vhp:e:s:u: -l version,help -- "$@"`
　　　　　　　　　　　　　　　　↑に追加するっ

というのをメモ失礼します。m(_ _)m
AWS SESの送信クオータ監視

#問題

Zabbixを3.0から4.2にアップグレートしてから、SESの送信クオータ監視アイテムが「取得不可」になっていた。
4.2へアップはOS自体が古かったため、そのままではできず最新AMIから構築した。

Amazon Linuxでは基本設置だった「/opt/aws/bin/ses-get-stats.pl 」がAmazon Linux2では見当たらない。
復元が目的だったのでses-get-stats.pl をなんとか復活しようとperlライブラリを入れたり（相当インストール）したが、また足りないメッセージが出る。
やめときなさいことですー

ses-get-stats.plの検索で古い情報しか出てこないところで気づくべきだった。
Amazon Linux2が進化したか他の理由で不用になったはずだと。

```bash
# aws ses get-send-quota
{
    "Max24HourSend": 50000.0,
    "MaxSendRate": 14.0,
    "SentLast24Hours": 0.0
}
```

## bash

[事前にprofileを設定しておく](https://qiita.com/itooww/items/bdc2dc15213da43a10a7)

```bash
#!/bin/bash

export AWS_DEFAULT_REGION="us-east-1"

prm=$1
ret=0

case $1 in
"1")
  ret=`aws ses get-send-quota --profile aws4 | jq '.Max24HourSend'`;;
"2")
  ret=`aws ses get-send-quota --profile aws4 | jq '.SentLast24Hours'`;;
"3")
  ret=`aws ses get-send-quota --profile aws4 | jq '.MaxSendRate'`;;
esac

echo $ret

#aws ses get-send-quota | jq '.SentLast24Hours / .Max24HourSend * 100'
```

これで余計なスクリプト（perl）は不用になった。

#メモ
しかし、これもすでに4年前の書き込み。ということは・・・
ま、いいでしょう。素敵な先輩と出会えたことで。

#参照
https://gist.github.com/toshihirock/55791628bcb215fad85b
PythonとかJavaScriptとかJavaで先頭と末尾の空白を削除する

機能ごとに先頭と末尾の空白を削除しなければならないことがあったので、
言語毎の削除方法を調べてみました。

##Python

###stripメソッド
引数に任意の文字列を指定することで文字列の先頭と末尾からその文字列を削除することが出来ます。
引数を省略すると、文字列の先頭と末尾の空白やタブを削除することが出来ます。
文字間の空白は削除されません。


使い方
先頭に半角空白、末尾にタブを入れています。

```Python
str = ' Hello World	'
print(str.strip())
```

結果

```
Hello World
```

先頭を削除したい場合は、
lstripメソッドを使用します。
先頭にタブを入れています。

```Python
str = '	Hello World　'
print(str.lstrip())
```

結果

```
Hello World　
```

末尾を削除したい場合は、
rstripメソッドを使用します。
末尾に全角空白を入れています。

```Python
str = ' Hello World　'
print(str.lstrip())
```

結果

```
 Hello World
```

##JavaScript

###trimメソッド
文字列の先頭と末尾の空白やタブを削除することが出来ます。
文字間の空白については削除されず、
~~片側だけの空白を削除することは出来ません。~~
※出来ました。ご指摘ありがとうございます。
片側だけの空白を削除する場合は、trimStart()とtrimEnd()を使用することで可能です。今回はChromeで試したのでエイリアスのtrimLeft()、trimRight()を使用しています。

使い方

```JavaScript
let str = ' Hello World	';
console.log(str);
console.log(str.trim());
```

結果

```
 Hello World	
Hello World
```

全角も削除されます。

```JavaScript
let str = '　Hello World　';
console.log(str.trim());
```

結果

```
Hello World
```

trimLeftメソッドで先頭の空白をtrimRightメソッドで末尾の空白を取り除きます。

MDN web docsによると、

trimLeftメソッド
> String.prototype.padStart のような関数との一貫性を持たせるため、標準メソッドの名前は trimStartに設定されています。

>しかし、ウェブの互換性の観点から、 trimLeft は trimStartのエイリアスとして残されます。 いくつかのエンジンでは以下のように解釈されます:
String.prototype.trimLeft.name === "trimStart";

trimRightメソッド
> String.prototype.padEnd のような関数との一貫性を持たせるため、標準メソッドの名前は trimEnd に設定されています。

>しかし、ウェブの互換性の観点から、 trimRight は trimEndのエイリアスとして残されます。 いくつかのエンジンでは以下のように解釈されます:
String.prototype.trimRight.name === "trimEnd";

とのことですので、
ブラウザによって対応、非対応が存在し、
エイリアスを使用する場合もあります。

```JavaScript
let str = '　Hello World　';
console.log(str.trimLeft());
console.log(str.trimRight());
```
結果

```
Hello World　
　Hello World
```

※IE9以下ではtrimメソッドは使用出来ないので、
replaceメソッドを使用する必要があります。

##Java
trimメソッドを使用します。
※Java11からはstripメソッドを使えば全角も削除できるようです。

使い方

```Java
String str = " Hello World	";
System.out.println(str);
System.out.println(str.trim());
```

結果

```
 Hello World	
Hello World
```

Javaのtrimメソッドでは全角の空白を削除出来ません。

```Java
String str = "　Hello World　";
System.out.println(str);
System.out.println(str.trim());
```

結果

```
　Hello World　
```

全角の空白を削除する場合は、
replaceAllメソッドを使用して、
正規表現で置換してしまいます。

以下は、末尾に全角空白があった場合です。

```Java
String str = "Hello World　";
System.out.println(str.replaceAll("[　]+$", ""));
```

結果

```
Hello World
```

##参考

https://engineer-club.jp/java-trim

https://uxmilk.jp/12804

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/trim

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight
ZooKeeper(Standalone) を Vagrant で構築した


Solr Cloud を構築するには ZooKeeper を構築する必要があります．
そこで Vagrant で ZooKeeper を構築しました．
ZooKeeper のバージョンは 3.4.14 です．
Vagrant の使い方は [Vagrant 入門](https://qiita.com/maitake9116/items/be27706a15f3a96a2209) をご覧ください．


## ZooKeeper???

Solr Cloud を構築する上で必須なサービスです．
Solr Cloud では collection を 複数の shard に分けることでインデックスを分散し，さらに shard を replication により複製し冗長構成をとることで可用性を向上させます．
ZooKeeper は分散アプリケーションの管理をおこない，Solr Cloud において shard の replica が格納された Solr の各 node の状態を管理します．

## 構成

ZooKeeper の構築はシェルでやることにしました．

```text
D:\vagrant\zk
┣Vagrantfile
┗create_zk.sh
```

### Vagrantfile

- OS は CentOS 7 を使用します．
- プロビジョナでシェルを実行します．

```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.33.10"

  config.proxy.enabled  = true
  config.proxy.http     = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.https    = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.no_proxy = "localhost,127.0.0.1"

  config.vm.provision :shell, path: "./create_zk.sh"
end
```


### create_zk.sh

- Java をインストールします．
- ZooKeeper のアーカイブを取得して展開します．
- ZooKeeper で使用する Port を開放します．

```bash
# Java をインストールする
yum install -y java-1.8.0-openjdk

# ZooKeeper を構築する
cd /var/tmp
yum install -y wget
wget http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz
tar xvf zookeeper-3.4.14.tar.gz
cp -ar zookeeper-3.4.14 /opt/
ln -s /opt/zookeeper-3.4.14 /opt/zookeeper

# ZooKeeper 用のユーザを作成する
groupadd zookeeper
useradd -g zookeeper -d /opt/zookeeper -s /sbin/nologin zookeeper
chown -R zookeeper.zookeeper /opt/zookeeper/*

# ZooKeeperの設定ファイルを用意する
cd /opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg

# dataDir を tmp から var に変更する
mkdir /var/lib/zookeeper
chown zookeeper.zookeeper /var/lib/zookeeper
cd /opt/zookeeper/conf
sed -i -e 's#dataDir=.*$#dataDir=/var/lib/zookeeper#' zoo.cfg

# ZooKeeper を起動する
cd /opt/zookeeper
bin/zkServer.sh start

# Port を開放する
systemctl enable firewalld.service
systemctl start firewalld.service
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --reload
```

## ZooKeeper を構築する

```powershell
> pwd
D:\vagrant\zk
> vagrant up
```

## 動作確認

サービスの状態を確認します．

```powershell
> vagrant ssh -c "sudo /opt/zookeeper/bin/zkServer.sh status"
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: standalone
```

nc(netcat) で ZooKeeper に Are you OK? と聞きます．

```powershell
> vagrant ssh -c "yum install -y nc"
> vagrant ssh -c "echo ruok | nc localhost 2181"
imok
```

I'm OK と答えたので問題ないです．
Redmine(trunk) + Ruby2.6 でプラグインの動作確認をした

Redmine 4.1 に向けて、trunk + ruby 2.6 でプラグインの動作確認をしてみました。

確認した環境は以下の通り

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63464/e1af4f81-4ea6-929d-52a7-31daa3a682a8.png)


|プラグイン|バージョン|ruby2.6対応|備考|
|:----------------|:----------------:|:-----:|:-----|
|[redmine_absolute_dates](https://github.com/suer/redmine_absolute_dates)|0.0.4|○||
|[redmine_banner](https://github.com/akiko-pusu/redmine_banner)|0.2.0|○||
|[redmine_code_review](https://github.com/haru/redmine_code_review)|1.0.0|○||
|[redmine_group_watchers](https://github.com/wenzhixin/redmine_group_watchers)|0.0.1|○||
|[redmine_issue_templates](https://github.com/akiko-pusu/redmine_issue_templates)|0.3.4|○|チケットテンプレート画面のリンク表示にアイコンがかぶる(※1)<br>0.3.3→0.3.4で解消|
|[redmine_jstoolbar_ext](https://github.com/tleish/redmine_jstoolbar_ext)|0.2.1|○||
|[redmine_jstoolbar_ext_buttons](https://github.com/tleish/redmine_jstoolbar_ext_buttons)|0.2.1|○||
|[redmine_jstoolbar_ext_coderay](https://github.com/tleish/redmine_jstoolbar_ext_coderay)|0.2.0|△|エラーにはならないが反応無し(4.0+ruby2.5でも同様)<br>CodeRayボタンは標準であるので不要と判断|
|[redmine_message_customize](https://github.com/ishikawa999/redmine_message_customize)||○||
|[redmine_persist_wfmt](https://github.com/pinzolo/redmine_persist_wfmt)|2.0.1|○||
|[redmine_vividtone_my_page_blocks](https://github.com/vividtone/redmine_vividtone_my_page_blocks)|2017/07/05|○||
|[redmine_wiki_extensions](https://github.com/haru/redmine_wiki_extensions)|0.9.0|○||
|[redmine_wiki_index_tree_view](https://github.com/basyura/redmine_wiki_index_tree_view)|0.0.1|○||
|[redmine_wiki_lists](https://github.com/tkusukawa/redmine_wiki_lists)|0.0.9|○||
|[redmine_wiki_page_tree](https://github.com/ledsun/redmine_wiki_page_tree)|0.0.2|○||
|[redmine_work_time](https://github.com/tkusukawa/redmine_work_time)|0.4.0|○||
|[redmine_xls_export](https://github.com/two-pack/redmine_xls_export)|0.2.1.t11|○||
|[view_customize](https://github.com/onozaty/redmine-view-customize)|2.2.0|○||

* ※1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63464/ecea62c1-65be-31a9-6128-d850058ac1ed.png)

4.0 → 4.1 のアップデートはrubyも含めて一気にいけそう！
Swift5.1で追加されそうなDynamic Replacementについて

[SwiftUI](https://developer.apple.com/xcode/swiftui/)の機能説明に

> Xcode can swap edited code directly in your live app with  “dynamic replacement”, a new feature in Swift.

という言葉があり、気になっていたので探していたのですがどこにも記述がなく、どういった感じで実現しているのかわからなかったのですが、先日Swift Forumsにスレッドを見つけたのでメモ。

[How does the hot-reloading work in XCode11? - Source Tooling - Swift Forums](https://forums.swift.org/t/how-does-the-hot-reloading-work-in-xcode11/)

なお、この機能は将来的に変更になる可能性が**多分に**あります。

#### Versions
- Xcode 11.0 beta (11M336w)
- swiftc: Apple Swift version 5.1 (swiftlang-1100.0.38.29 clang-1100.0.20.14)


## 使い方

使い方は非常に簡単です。
まずModuleAで`dynamic`修飾子をつけた関数`foo`を宣言します。

```swift
// ModuleA
public struct A {
  public dynamic func original() -> String {
    return "ModuleA"
  }
}
```

次に別のModuleBで`@_dynamicReplacement(for: original())`をつけた拡張関数`replacement`を宣言します。

```swift
// ModuleB
public extension B {
  @_dynamicReplacement(for: original())
  public func replacement() -> String {
    return "ModuleB"
  }
}
```

あとは`dlopen`(ライブラリを動的に読み込む命令)なりなんなりでModuleBを読み込めば、`A().original()`は`ModuleB`に置きかわります。

```swift
// ModuleBを読み込んでいないとき
print(A().original()) // → "ModuleA"
// ModuleBを動的に読み込み
_ = dlopen("ModuleB.dylib", 0)
print(A().original()) // → "ModuleB"
```

## 試してみた

スレッドにあるサンプルコードではswiftcを使ってコンパイルをしてたのですが、~~めんどくさかった~~とりあえずお手軽に置き換わるのか見たいので、`iOS Framework`プロジェクトをUnit Test込みで作り、以下のコードを書きました。

```swift
// SampleDynamicReplacement

public struct SampleObject {
    public init() {
    }

    public dynamic func original() -> String {
        "original"
    }
    
    public dynamic var foo: String {
        "original property"
    }
}
```

```swift
// SampleDynamicReplacementTest

extension SampleObject {
    @_dynamicReplacement(for: original())
    func replacement() -> String {
        "replacement"
    }
    
    @_dynamicReplacement(for: foo)
    var bar: String {
        "replacement property"
    }
}

class SampleDynamicReplacementTests: XCTestCase {
    func testExample() {
        XCTAssert(SampleObject().original() == "replacement")
        XCTAssert(SampleObject().foo == "replacement property")
    }
}
```

実際に実行してみるとテストが通ります。


関数でもプロパティでも置換できる模様。

ただ`SampleObject.foo`を`let`にしたら

```
Replaced accessor get for 'foo' is not explicitly defined
```

で怒られました。
しかし、

```swift
public private(set) dynamic var foo: String = "original property"
```

にしたらビルドが通ったので、なかなか危険な香りがしますね...！！(まあdynamicつけなければいい話なんですが)

また、extension側で`replacement`の戻り値を`Int`など`original`に適合してない型に変えるとコンパイルエラーになるので、しっかり型チェックが働いていることがわかります。

ちなみに試しに

```swift
extension SampleObject {
    @_dynamicReplacement(for: original())
    func replacement() -> String {
        "replacement"
    }
    
    @_dynamicReplacement(for: original())
    func replacement2() -> String {
        "replacement2"
    }
}
```

としたところ、コンパイルは通り、テストには失敗しました。
`replacement`の宣言の順番を逆にしたらテストは通ったので置き換わるのは読み込んだ順なんですかね・・・？
ここもなかなか危険な香りが・・・！！

## まとめ
簡単にですがDynamic Replacementについて紹介しました。
この機能だけで、(protocolでいいですが)テスト時のMock差し替え、SwiftUIなどのHot Reload、またAppleの規約的にアウトまたは実際にストア配布のバイナリではできないかもしれませんが、バイナリを直接アプリに送りつけることでReact Nativeなどで使えるHot Code Pushができるかもと思うと、夢が膨らみますね！
MySQLでInsert処理をはやくする

##はじめに
何番煎じ感ありますが、一行ずつInsertする場合とまとめてInsertを比較してみた結果

##前提

###データベース
DBMS Aurora
バージョン 5.7.12
InstanceType db.r5.2xlarge
vCPU 8
メモリ 64GB

###クライアント
InstanceType r5a.2xlarge
Python 2.7.14

##事前準備

###データ作成

```
$ perl -e 'for my $num (1..40000){print "${num},name\n";}' > input.csv
$ head input.csv 
1,name
2,name
3,name
4,name
5,name
```

###mysqlに接続してテーブル作成

```
mysql -u admin -h ******-cluster.cluster-*********.ap-northeast-1.rds.amazonaws.com -p
use mydb
create table emp(
    -> id INT(5),
    -> name VARCHAR(10),
    -> PRIMARY KEY (id));
```

###接続先の指定

```
$ cat rds_config.py
db_username = "<user>" #ユーザ
db_password = "<password>" #パスワード
db_name = "<mydb>" #作成したDB名を記載
```

##1行づつInsert
```python
import sys
import rds_config
import pymysql
import csv

rds_host  = "******-cluster.cluster-*********.ap-northeast-1.rds.amazonaws.com" #Auoraの接続先エンドポイント
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)

def main():
    f = open ("input.csv", "r")
    reader = csv.reader(f)
    cur = conn.cursor()
    for line in reader:
        QUERY = "INSERT INTO emp (id, name) VALUES(" + line[0] + ", " + '"' + line[1] + '"' + ")"
        cur.execute(QUERY)
    conn.commit() 
    cur.close() 
main()
```

結果

```
$ time python insert.py 

real	0m11.503s
user	0m2.746s
sys	0m0.329s
$ time python insert.py 

real	0m11.618s
user	0m2.614s
sys	0m0.511s
$ time python insert.py 

real	0m11.229s
user	0m2.888s
sys	0m0.470s
```

##まとめてInsert

```python
$ cat insert_multi.py 
import sys
import rds_config
import pymysql
import csv
#rds settings
rds_host  = "******-cluster.cluster-*********.ap-northeast-1.rds.amazonaws.com" #Auoraの接続先エンドポイント
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
rows = []

def main():
    f = open ("input.csv", "r")
    reader = csv.reader(f)
    cur = conn.cursor()
    for line in reader:
        EmpID = line[0]
        Name  = line[1]
        rows.append((EmpID, Name))

    cur.executemany("INSERT INTO emp (id,name) VALUES (%s,%s)", rows)
    conn.commit() 
    cur.close() 

main()
```

結果

```
$ time python insert_multi.py 

real	0m1.028s
user	0m0.726s
sys	0m0.016s
$ time python insert_multi.py 

real	0m1.046s
user	0m0.741s
sys	0m0.028s
$ time python insert_multi.py 

real	0m1.049s
user	0m0.733s
sys	0m0.020s
```

##結論

```
$ python
Python 2.7.14 (default, Jul 26 2018, 19:59:38) 
[GCC 7.3.1 20180303 (Red Hat 7.3.1-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> (1.028+1.046+1.049)/3
1.041
>>> (11.503+11.618+11.229)/3
11.450000000000001
>>> 11.450000000000001/1.041
10.999039385206533
```

##その他

前半２つが一行ずつ
後半３つが一括
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/b0883dfa-5af7-850a-b9fc-e940a7002cb3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/3e582937-8d0a-5ead-5e5f-c81ffd3b432d.png)



##投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
Itanium C++ ABIのManglingルールについて - 基礎構文編

　Manglingルールは、ソースコード上での名前をエンコードし、プログラム全体で一意な名前を生成するためのルールである。関数名や型名などで適用され、名前の衝突を防ぐことができる。コードの構造からファイルシステムで言うフルパスのようなものを求めると考えてもいいかもしれない。エンコード(Mangle)したものは「シンボル」と呼ばれる。C++で開発されたアプリケーションをリバースエンジニアリングするにあたってこのルールについて学んだのでまとめようと思う。

# Itanium C++ ABI
　Application Binary Interfaceは、言語をコンピュータ上で動作させるための実装方法を定める。また、アプリケーション同士の互換性についてもバージョンによる変更を含めて定義されることがある。C++ではABIはコンパイラによって異なり、[Itanium ABI](https://itanium-cxx-abi.github.io/cxx-abi/)はGCCで使用されている。この記事ではドキュメントの[External Names](https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling)を見ていく。
**※ベンダー向けに提供されている構文は無視します**

# Symbol
　異なるファイルに存在する関数などを呼び出すためアドレス解決が必要になる。このような実行時にアドレス解決を行う必要がある場合にシンボルが使われる。C++ではCと違い、多重定義や実行時型情報が存在するためソースコード上での名前をそのままでは使用できない。コンパイルして生成されたオブジェクトファイルをリンクする際にアドレス解決が行われるため、通常実行ファイル自体にシンボルは必要無い。シンボルは主にライブラリで使用される。

# Mangling Rule
BNF記法で記述されている。ドキュメントでは純粋なBNFから表現が一部拡張されているので注意。

* 非終端記号は<>で囲まれている
* 非終端記号においてイタリック体で記述されている部分は無視する
    * \<_function_ **name**>は\<**name**>と同じ。(ここでは判別しやすいよう記号の名前は太字にしてます)
* スペースは無視する。見やすさのためにスペースを入れてるだけ
* #から行末まではコメント
* []で囲まれた部分は省略可能
* ()で囲まれた部分はグループ
* +, *は正規表現のリピートと同じ
* 上記以外の文字はすべて終端記号で、その文字自体が記述される。

## General Structure
\<**mangled-name**> ::= \_Z \<**encoding**>
全てのシンボルは"\_Z"から始まる。マングルされたC++のシンボルを識別するために使おう。encodingがシンボルの本体と言える。


\<**encoding**> ::= \<_function_ **name**>\<**bare-function-type**>
\<**encoding**> ::= \<_data_ **name**>
\<**encoding**> ::= \<**special-name**>
encodingは3つのパターンがある。さっそくここでBNF記法の曖昧な部分が襲ってくる。デマングルのためのパーサを開発する際はメモ化などで対処しよう…
1つ目の構文は、関数を表す。
2つ目の構文は、クラスや変数などの関数以外の名前を表す。
3つ目の構文は、vtableと実行時型情報に関して表す。

# Terminal 
非終端記号に深く入る前に終端記号を確認しておこう。

\<**number**> ::= [n]<_non-negative decimal integer_>
整数値を表す。先頭に'n'をつけると負の数値になる。

\<**float**> ::= <_fixed-length lowercase hexadecimal string_>
浮動小数点数は16進文字列でビッグエンディアンで表記する。

\<**source-name**> ::= \<_positive length_ **number**>\<**identifier**>
\<**identifier**> ::= <_unqualified source code identifier_>
identifierは_a-zA-Z0-9からなる文字列。source-nameは実際に名前を保持するエンティティ。

# Non-Terminal
非終端記号とは構文の中に別の終端記号または非終端記号を含む記号である。

## Names
\<**name**> ::= \<**nested-name**>
\<**name**> ::= \<**unscoped-name**>
\<**name**> ::= \<**unscoped-template-name**>\<**template-args**>
\<**name**> ::= \<**local-name**>
encodingの次に重要な非終端記号である。
名前空間やクラスのように親を持つ名前はnested-nameで表される。よって、グローバルスコープまたはstd名前空間で宣言された名前はunscoped-nameとして表される。また、unscoped-template-nameはunscoped-nameの拡張である。ローカルクラスのメンバを含む関数内で宣言でされた名前はlocal-nameで表される。

\<**unscoped-name**> ::= \<**unqualified-name**>
\<**unscoped-name**> ::= St\<**unqualified-name**>
\<**unscoped-template-name**> ::= \<**unscoped-name**>
\<**unscoped-template-name**> ::= \<**substitution**>
nameは基本的にunqualified-nameで構成される。Stは"::std::"の省略で、St6vectorは::std::vectorとなる。std名前空間は特別扱いされていて、nested-nameを用いるより短く表記できる。シンボル内に同一の名前が複数存在する場合subsutitionによって省略される。subsutitionには番号がつけられていてパースの順番に依存しているので注意が必要である。

# おわりに
マングルされたシンボルに必ずと言っていいほど出現する基礎構文は以上だ。次回があればシンボルのディテールを表現する非常に細かく定義された構文を解説したいと思う。
Revitのプラグインをつくるとき最初のセットアップの忘備録

Revitのコマンドをつくるとき最初のセットアップの忘備録

App.csをつくる。

```c#
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FirstRevitPlugin;

namespace FirstRevitPlugin
{
    public class App : IExternalApplication
    {
        public Result OnShutdown(UIControlledApplication application)
        {
            return Result.Succeeded;
        }

        public Result OnStartup(UIControlledApplication application)
        {
            var rp = AppHelpers.AddRibbonPanel(application, "TabName", "PanelName");
            AppHelpers.CreateButton("Hello World", "FirstRevitPlugin.MyFirstCommand", "This is saying hello",rp, "icon.png");
            
            return Result.Succeeded;
        }
    }
}
```


AppHelper.cs
AppHelpersというクラスで、コマンドをつくるときにボタンをつくる機能をつくる。

```C#
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;

namespace FirstRevitPlugin
{
    internal class AppHelpers
    {
        internal static RibbonPanel AddRibbonPanel(UIControlledApplication application, string tabName, string panelName)
        {
            if (!ComponentManager.Ribbon.Tabs.Any(t => t.Id == tabName))
            {
                application.CreateRibbonTab(tabName);
            }
            var ribbonPanel = application.CreateRibbonPanel(tabName,panelName);
            return ribbonPanel;
        }

        internal static void CreateButton(string cmdName, string cmdClassName, string toolTip, RibbonPanel ribbonPanel, string iconName)
        {
            var assemblyName = Assembly.GetExecutingAssembly().Location;
            var buttonData = new PushButtonData(
                $"cmd{cmdName.Replace(" ","")}",
                cmdName,
                assemblyName,
                cmdClassName
                );
            var pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
            pushButton.ToolTip = toolTip;

            var image = new BitmapImage(new Uri($"pack://application:,,,/FirstRevitPlugin;component/Resources/{iconName}"));
            pushButton.LargeImage = image;
        }
    }
}
```

ここのネームスペースの名前を間違えないように注意。ここでは、FirstRevitPlugin。

```C#
var image = new BitmapImage(new Uri($"pack://application:,,,/FirstRevitPlugin;component/Resources/{iconName}"));
            pushButton.LargeImage = image;
```



FirstRevitPlugin.addinをつくる。ClientIdはTools>CreateGUIDでつくる。

```
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
  <AddIn Type="Application">
    <Name>FirstRevitPlugin</Name>
    <Assembly>FirstRevitPlugin\FirstRevitPlugin.dll</Assembly>
    <FullClassName>FirstRevitPlugin.App</FullClassName>
    <ClientId>6ce00684-f989-4e2b-9410-9ea14625730c</ClientId>
    <VendorId>3831249A-33B2-4A9C-A1C5-15EFC086DB2B</VendorId>
    <VendorDescription>yishizu, yukoishizu.com </VendorDescription>
  </AddIn>
</RevitAddIns>
```
【Rails】view側にvalidationをかける

#modelじゃなくてviewにvalidationをかけたい

下のコードをコピればvalidationが実装できる


```html.erb
<%= label_tag :name, 'なまえ (必須)' %>
<input type="text" name="name" id="name" required placeholder='Your name'>
```



参考
https://qiita.com/oh_rusty_nail/items/e08f6b323d526fab3d55
【Javascript】ワンライナーで0から10の値を持つ配列を作る方法7つ！PHPやPythonのrange的な何か。

## JavascriptにはPythonのrange的なものがなかった

PHPにはrangeが、Pythonにもrangeがあってそれぞれ連続した任意の数の配列を作れる。[参考](https://hydrocul.github.io/wiki/programming_languages_diff/list/range.html)

一方、Javascriptさんはというと...ない！？

「いやでもえっと、for(let i = 0; i < 10; i++){hogehoge}で10回ループまわして、えっと...」

ダサい。

すごくクールな記法はライブラリを使うしかないようだが、まあせめてワンライナーでこれを実現したい。そんな人に向けて記事にまとめておきました。

## Javascript でワンライナーで0から10の値を持つ配列を作る

### 1つ目

```javascript
[...Array(10)].map((v, i)=> i)
```

new Array(n)で配列風の何かが作れる。でスプレッドして分割、10個の要素を持つ配列(中身はundefined)ができ、それについてmapしてインデックスを取り出しそれを連続する要素とする方法。

すごく妥当。

### 2つ目

```javascript
Object.keys([...Array(10)])
```

1つ目とコアな部分は似てる。まずは10の配列風の何かを作ってスプレッド、それらのキー(つまりインデックス)を取り出すと丁度連番になっているというもの。

こちらは1つ目とは異なり、1つ1つの要素が文字列となる。(Object.keysなんで)

使い分けかな。

### 3つ目


```javascript
Object.keys(Array.apply(null, {length: 10}))
```
こちらは、ちょっと不思議な記法。

Function.prototype.applyの[説明](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)を見ると、

> apply() メソッドは与えられた this 参照値と、配列 (もしくは配列風のオブジェクト) の形で与えられた引数を用いて関数を呼び出します。

ここでミソなのが、どうやらこのapplyは"配列風"というのをlengthプロパティを見ているようで、その仕様を用いたもの、と思われる。ネットで調べていたら出てきた。気づいた人すごい。

Array.apply(...)を用いて10の要素を持つ配列を生成し、最終的にObject.keysでインデックスを取り出すというもの。

2つ目と同様に、こちらも戻り値の1つ1つの要素は文字列になる。


### 4つ目

```javascript
Array.apply(null, {length: 10}).map((v, i)=> i)
```

3つ目と1つ目の合わせ技。割愛。


### 5つ目

```javascript
Array.apply(null, {length: 10}).map(Number.call, Number)
```

途中までは4つ目と同じ。最後が...ちょっと説明して欲しい笑

stack overflowで誰かに対する回答として挙げられていた。なにこれ。

###6つ目

@htsign さんより

```javascript
Array.from({ length: 10 }, (_, i) => i)
```

Array.from方式です。[Array.from](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from)は、配列風なオブジェクトを配列をもとに配列を返してくれますが、第2引数を与えるとそれをmapfunctionとしてくれるので、最終的にindexを取り出して返却するmapfunctionを仕掛けることで配列を得るというものですね。クールや...

### 7つ目(これが一番クールか！？)

@ttatsf さんより

```javascript
[...Array(10).keys()]
```

これですね。一番シンプルでした。おみそれしました。これからはこの書き方でいかせていただきます。

## lodashすれば一発だけどね。

### lodash#range

```javascript
_.range(10)
```

他の要件でlodashその他ライブラリを入れているのであれば間違いなくこっちを使うべきですね。
dockerのCentOS7上でEC-CUBE4を動かす

以下のDockerFileで動かすことができました。

最後のENTRYPOINTの　0.0.0.0:8000の指定がポイント
これがないとコンテナ外部から見れなかった

```docker:Dockerfile
FROM centos:7
RUN yum update -y && yum install -y \
        git \
        zip \
        unzip \
        epel-release \
        && rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
RUN yum install -y --enablerepo=remi,remi-php72 \
        php \
        php-intl \
        php-pdo \
        php-xml \
        php-mbstring \
        php-zip
WORKDIR /var/www/html/ec-cube4
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
        && php composer-setup.php \
        && php -r "unlink('composer-setup.php');" \
        && mv composer.phar /usr/local/bin/composer
RUN composer create-project ec-cube/ec-cube ec-cube "4.0.x-dev" --keep-vcs
WORKDIR /var/www/html/ec-cube4/ec-cube
EXPOSE 8000
ENTRYPOINT bin/console server:run 0.0.0.0:8000
```

上記のファイルを作成したら
下記コマンドを実行

```docker
docker build -t ec-cube4 ./
docker run -d -p 8000:8000 ec-cube4 
```

ブラウザでlocalhost:8000を開くとみることができました
ライフサイクルポリシーでGlacierに移行するのは実は損？？


### 概要

S3のライフサイクルポリシーを利用することで、指定した期間を超えたオブジェクトをGlacier、または低料金のストレージタイプへ移行することができ、運用の手間をかけることなくストレージ料金の削減を見込むことができます。
しかし、よくドキュメントを読んでみると、「GlacierへのPUTリクエスト（リクエスト1,000件ごとに0.055USD）」の記載があり、GlacierへのPUTリクエストも課金対象であるため、１オブジェクトのサイズが小さく、オブジェクト数が多いようなケースでは、Glacierへの移行によるコストメリットが得られない場合があります。

今回ライフサイクルポリシーの適用を検討していた、ALBのアクセスログの出力先S3バケットのオブジェクト数とサイズ推移から、スタンダードのみで運用した場合とGlacierに移行した場合のコスト比較を行いました。



### 現状のオブジェクト数、サイズ推移

当該環境で実際に運用しているALBのアクセスログの出力先S3バケットのオブジェクト数、サイズの推移は以下になります。

| 期間 | オブジェクト数 |     サイズ（GB） |
|------- |-----------: |-------------: |
| 1ヶ月目    |     2,575,000 |           160.48 |
| 2ヶ月目    |   4,900,000 |           261.6 |
| 3ヶ月目    |   7,170,000 |           341.4 |



### 各料金の算出式

##### <span style="color: rgb(0,0,0);"><span>GlaicerへのPUTリクエスト料金(1000件単位で0.055$)</span></span>

<span style="color: rgb(0,0,0);"><span>(オブジェクト数 / 1000) * 0.055USD</span></span>

##### <span style="color: rgb(0,0,0);">Glaicerのストレージ料金</span>

<span style="color: rgb(0,0,0);"><span>サイズ(GB) * 0.004USD</span></span>

##### <span style="color: rgb(0,0,0);">Standardのストレージ料金</span>

<span style="color: rgb(0,0,0);"><span>サイズ(GB) * </span></span>0.023USD

### コスト比較

上記のオブジェクト数、サイズの推移からGlacierに移行した場合とStandardのみで運用した場合のコスト比較を行っていきます。
今回は1ヶ月目のオブジェクトをGlacierに移行した場合を考えてみます。


各料金|   Glacierに移行した場合（＄）| Standardで運用した場合（＄）|
---------------- | -------------:| -------------:|
GlaicerへのPUTリクエスト料金    |      141.625 |         -|
Glaicerのストレージ料金  |       0.64192 |       -|
Standardのストレージ料金 |       4.16116 |       8.1936|
合計               |      146.42808 |      8.1936|


今回のようにオブジェクト数が多く、１ファイルサイズが小さい場合はGlaicerのストレージ料金の削減効果よりもPUTリクエスト料金の方が大きく上回り、Glacierに移行せずに運用した方が安く運用できることがわかります。
今回のケースでは１ファイルあたり約50KBでしたが、Glacierに移行した方がコスト削減に繋がるファイルサイズはいくつなのでしょうか。損益分岐点となるファイルサイズを追っていきます。



###ファイルサイズの損益分岐点

計算を単純化するために月に追加されるファイル数を1000に固定し、１ファイルあたりのサイズを変動させてシミュレートしました。計算式は割愛しますが、上記と同じ計算方法を使っています。

１ファイルあたりのサイズ  |   Glacierに移行した場合（＄） | Standardで運用した場合（＄）|
---------------- | -------------:| -------------:|
1MBの場合               |      0.105 |      0.069|
2MBの場合               |      0.155 |      0.138|
2.9MBの場合               |      0.2 |      0.2001|
3MBの場合               |      0.205 |      0.207|



### 結論

上記の通り、Glacierに移行する際にコスト削減効果が得られるのは１ファイルのサイズが2.9MB以上という結果になりました。
AWSのコスト計算は複雑化しており確認が面倒に思うこともあるのですが、コスト削減を目的とした設定が実はコスト増の原因となっていた、、、という本末転倒なことにならないよう、事前に確認することの大切さを再確認しました。



### 参考

https://aws.amazon.com/jp/s3/pricing/
ターミナル　変更　実行　操作内容　が保存されない　時の対処法

#解決方法
以下のコマンドをターミナルで続けて実行

```ターミナル
touch ~/.bashrc
```

```ターミナル
touch ~/.bash_profile
```


```ターミナル
echo "if [ -f ~/.bashrc ] ; then . ~/.bashrc fi" >> ~/.bash_profile
```


■状況
Mac osでターミナルを利用
phpのバージョンの切り替えをしたのにターミナルを閉じると元に戻ってしまう
環境変数を編集して保存したのにターミナルを閉じて再度開くと編集前の値に戻っている
ターミナルで行なった作業を保存したい

■原因
.bashrcファイルと.bash_profileがなかった

■解説
.bashrcファイルと.bash_profile　とは...

bashrcは
`ターミナルの設定ファイル。いろんな設定を記憶するところ`

.bash_profileは
`ターミナルを起動するときにbashrcを読み込みする`

だそうです。

ちなみにこれらのファイルたちはルートディレクトリにあります。

※macでのルートディレクトリとはfinderを開いたときの家マークのところ（自分の名前が書いてある）

※.bashrcファイルと.bash_profileは隠しファイル扱いのため通常では見れません
※見るためにはfinderを開いた状態で　Shift + command + .

■コメント
こいつらがないといつまでも行なった作業が保存されなくる

デフォルトではこのファイルはあるはずなんだが間違って削除したのか自分のパソコンの中では消えていました。
SQLの基本操作４選

#はじめに
こんにちは。
私は、現在大学生４回生でプログラミングを猛勉強中です。
未来電子テクノロジーのプログラミング開発コースで、インターンを行なっています。
今回は、SQLを学んでいた時によく使った基本操作４つについてお話しします。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#SQLとは
SQLとは、データベース言語の１つで、データベースの定義や命令を行うことができます。
SQLの略はなく、SQLという言葉が、完成しています。
また、SQLには、３つの種類があります。

- データ定義言語
- データ操作言語

- データ制御言語
この３つによってデータベースを活用していきます。


#基本操作4選
基本操作は、以下です。

- INSERT
（これは、追加を行う命令です。）

```
INSERT INTO テーブル名() VALUES();
```

- SELLECT
（これは、参照を行う命令です。）

```
SELLET　カラム名　FROM　テーブル名
```

- UPDATE
（これは、更新を行う命令です。）

```
UPDATE  表名 SET 列名 = 値 WHERE　更新する行を特定する条件;
```

- DELETE
（これは、削除を行う命令です。）

```
DELETE  FROM  表名 WHERE　削除する行を特定する条件;
```

#まとめ
SQLを勉強しましたが、まだまだ勉強不足です。
これからプログラミングとともにSQLも勉強していきたいと思います。
【RSpec】FactoryBotのモデル作成でバリデーションをスキップする方法


テストコード用のインスタンスを作成する際、モデルにバリデーションが設定されているとバリデーションエラーによりインスタンスが作成できないときがあります。

**バリデーションのチェックはスキップしていいので、とりあえずテスト用のデータを作りたい**という場合は以下のようにFactoryBotでバリデーションをスキップする`trait`を定義してあげるとうまくいきます。


```diff:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    email 'xxx'
    ...
    ...

+   trait :skip_validate do
+     to_create {|instance| instance.save(validate: false)}
+   end
  end
end
```

```diff:spec/models/user_spec.rb
require 'spec_helper'

describe User do
-  let(:user) { create(:user) }
+  let(:user) { create(:user, :skip_validate) }
   ...
   ...
end
```

- 参考: 
[Factory-girl create that bypasses my model validation](
https://stackoverflow.com/questions/9322353/factory-girl-create-that-bypasses-my-model-validation)
elixir v1.9ではdetachedオプションは非推奨になる

phoenixをdaemon化させるときに、公式ドキュメント記載の

```
MIX_ENV=prod PORT=4001 elixir --detached -S mix do compile, phx.server
```

これ実行すると思いますが、elixirのバージョンあげると、警告が出るようになる。

```
[twintaro@phoenix hello]MIX_ENV=dev PORT=4001 elixir --detached -S mix do compile, phx.server
warning: the --detached option is deprecated
```

公式ドキュメント確認すると、確かに記載あり
https://hexdocs.pm/elixir/master/compatibility-and-deprecations.html

```
v1.9	--detached in CLI	--erl "-detached" (v1.0)
```

バージョン1.9以降は--erlの方を使いなさいよ、と。
なので、今後はこうする

```
MIX_ENV=prod PORT=4001 elixir --erl "-detached" -S mix do compile, phx.server
```

実行すると、警告は消えましたという話でした。


参考
https://hexdocs.pm/phoenix/deployment.html#starting-your-server-in-production
https://hexdocs.pm/elixir/master/compatibility-and-deprecations.html
[Node.js]DialogflowのIntentをAPIで取得する

DialogflowのIntentのRESTで実装しようとしたとき、
webhook接続の解説記事ばかりで、API接続の解説記事が少なかったので、備忘録として残します。
#モジュールのインストール
APIの接続にはモジュール版のdialogflowを使うのでnpmでインストールします。

```
npm install --save dialogflow
```
#実装
実装する際のソースコードサンプルです。
##接続部分
Dialogflowの接続情報を設定してSessionを作成します。

```javascript
const dialogflow = require('dialogflow');

module.exports = class DialoglowAPI {
    constructor(){
        // Dialogflowの接続情報を設定
        let client_option = {
            project_id: prject_id, // DialogflowのProject ID
        }
        client_option.credentials = {
            client_email: client_email // DialogflowのService Account
            private_key: private_key // GCPで生成したprivate key
        }
        
        this.sessionClient = new dialogflow.SessionsClient(client_option);
        this.sessionPath = this.sessionClient.sessionPath(prject_id, project_id);
    }
}
```

###Dialogflowgへの接続情報
project_id、client_emailはDialogflow Consoleから歯車マーク押した先に。
private_keyはService AccountからGCPに飛んで、そこから生成します。
※接続情報の取得に関しては、いっぱい記事が転がっているので詳細は割愛します。

###注意
client_emailとprivate_keyは、xxxx.credentialsの中に入れてあげないとエラーとなるので注意しましょう。

##Intentの取得

```javascript
    async get_intent() {
        // requestを作成
        const request = {
            session: this.sessionPath,
            queryInput: {
                text: {
                    text: "Intentを特定する為の文言",
                    languageCode: "ja",
                },
            },
        };
        // 呼び出し
        return await this.sessionClient.detectIntent(request);
    }
```

[responseのデータ形式はこちらに記載されています](https://dialogflow.com/docs/fulfillment/how-it-works)

##まとめ
DialogflowとLINE等のメッセンジャーを直接Webhookで繋げるのは簡単ですが、
複雑な実装を行う場合は、サーバーを経由する機会も多いと思います。
APIでの接続は小さく実装できるので、Nluを機能の一部で実装したい等の場合はとても便利に使うことができると思います。
Docker for MacのDockerホストにログインする

Docker for Mac を起動して、Mac から Docker ホストに接続してみます。
Terminal で `screen` コマンドを実行します。

```sh
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty 
```

`root` でログインできました。Mac なのに Linux が動いています。

```
Welcome to LinuxKit

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""___/ ===
          {                       /  ===-
           ______ O           __/
                          __/
              ___________/

linuxkit-025000000001 login: root (automatic login)

Welcome to LinuxKit!

NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
System services are namespaced; to access, use `ctr -n services.linuxkit ...
```

`ps`・`ifconfig`・`df` をみると、何やら賑やかです。

```
linuxkit-025000000001:~# cat /etc/os-release 
PRETTY_NAME="Docker for Mac"

linuxkit-025000000001:~# uname -a
Linux linuxkit-025000000001 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux

linuxkit-025000000001:~# netstat -rn
Kernel IP routing table
Destination   Gateway       Genmask       Flags MSS Window irtt Iface
0.0.0.0       192.168.65.1  0.0.0.0       UG      0 0         0 eth0
127.0.0.0     0.0.0.0       255.0.0.0     U       0 0         0 lo
172.17.0.0    0.0.0.0       255.255.0.0   U       0 0         0 docker0
172.19.0.0    0.0.0.0       255.255.0.0   U       0 0         0 br-836bbfxx
172.20.0.0    0.0.0.0       255.255.0.0   U       0 0         0 br-b1063fxx
192.168.32.0  0.0.0.0       255.255.240.0 U       0 0         0 br-8d7390xx
192.168.65.0  0.0.0.0       255.255.255.0 U       0 0         0 eth0

linuxkit-025000000001:~# nslookup docker.for.mac.host.internal
Name:      docker.for.mac.host.internal
Address 1: 192.168.65.2

linuxkit-025000000001:~# free
             total       used       free     shared    buffers     cached
Mem:       4042244    3404440     637804       1116     422824    2039440
-/+ buffers/cache:     942176    3100068
Swap:      1048572          4    1048568
```

Docker for Mac の設定画面で、ホスト側のメモリを 4GB、Swap を 1GB に設定した状態なので、それが反映されています。

screen からは `control`+`a`→`k`→`y` で抜けられます。
Railsのpresent? blank? presence あたりの定義

自分用メモ。

https://github.com/rails/rails/blob/v5.2.3/activesupport/lib/active_support/core_ext/object/blank.rb

Rails 5.2.3のソースだと

```activesupport/lib/active_support/core_ext/object/blank.rb
class Object
  # An object is blank if it's false, empty, or a whitespace string.
  # For example, +false+, '', '   ', +nil+, [], and {} are all blank.
  #
  # This simplifies
  #
  #   !address || address.empty?
  #
  # to
  #
  #   address.blank?
  #
  # @return [true, false]
  def blank?
    respond_to?(:empty?) ? !!empty? : !self
  end

  # An object is present if it's not blank.
  #
  # @return [true, false]
  def present?
    !blank?
  end
```
【VB.NET】ADO.NET

# ざっくり基本形

```vb
Dim commandText As New StringBuilder
commandText.Append("SELECT * FROM table1 ")
commandText.Append(" WHERE col1 = @param1 ")
commandText.Append("   and col2 = @param2 ")

Using con As New SqlConnection(connectionString)
    con.Open()

    Using comm As New SqlCommand(commandText.ToString, con)

        comm.Parameters.Add("@param1", SqlDbType.Decimal).Value = param1
        comm.Parameters.Add("@param2", SqlDbType.Char).Value = param2

        Using reader = comm.ExecuteReader()

        End Using

    End Using
End Using
```

# ExecuteNonQuery, ExecuteReader, ExecuteScalarのどれを使うべきか？

- ExecuteNonQuery
    - 結果が必要ない、更新系のSQLに使用する。
- ExecuteReader
    - 結果が複数行あり、1行目から順次読み取るときに使用する。
- ExecuteScalar
    - 結果が1行のみ＆1列のみの場合に使用する。

[ExecuteNonQuery、ExecuteReader、ExecuteScalar 操作の SQL アダプターを使用しての実行 - BizTalk Server | Microsoft Docs](https://docs.microsoft.com/ja-jp/biztalk/adapters-and-accelerators/adapter-sql/executenonquery-executereader-and-executescalar-using-the-sql-adapter)
RailsとDjango の違い　～インストール編

##RailsとDjangoの違いを、実際にアプリを組み立てながら紹介していきます！！
※rubyとpythonがインストールされている前提で話を進めていきます。

新規アプリの作成編



アプリを作成したいディレクトリに

```
$ cd ~~
```
で移動し、指定したディレクトリ上でアプリの作成を行います。
RailsもDjangoも同様に行います。


###・Rails

コマンド

```
$ rails new アプリ名
```

でアプリを新しく作成することが出来ます

今回はrailbook というアプリ名で、作成していきます。

![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/e520ddfd-7763-ac03-4bf4-372e4a99f1ec.png)


いっぱい出てきましたね笑


![スクリーンショット (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/5e85ed02-1ecc-d7a8-3a04-f83536a26a8d.png)

GemファイルにSqlite3が含まれてない？？
Sqlite3をインストールして、再度

```
$ rails new アプリ名
```

のコマンドを入力してRailsのアプリの初期作成は完了です！

指定したディレクトリにアプリが作成されてますね♬
![スクリーンショット (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/7b7fa8fb-0670-5e4f-e70f-782b4852e576.png)


###・Django

Djangoも同じく、

```
django-admin startproject アプリ名
```

でアプリを作成することが出来ます。mysiteというアプリ名で作成することにしました。

![スクリーンショット (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/999eeffd-f67d-94c9-f11e-676a919aca7e.png)

Djangoは一瞬でできあがっちゃいましたね！

![スクリーンショット (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/7bf21f45-8155-7063-83ef-43a35919ed75.png)

railsに比べると、ファイルの数も少ないです。。

>mysite/
 >>   manage.py
 >>   mysite/
 >>>        __init__.py
 >>>       settings.py
 >>>       urls.py
 >>>       wsgi.py

という作られ方をしてますね！

これは面白そうな予感がします笑

続きの記事もアップしていくので、ぜひ読んでください～
Vunitでのテスト実行ファイルの作成

# はじめに
Vunitのテスト実行ファイルの作り方になります
開発環境は[過去記事](https://qiita.com/ryo_i6/items/7d1bf7ecdc3edd69d0b0)と同様です

# ディレクトリの構造
私は下記のようなディレクトリ構造にしています

今回はベンダIPライブラリとしてXilinx ISEを使用しています
コンパイルの仕方は"[GHDLでベンダのVHDLライブラリをコンパイルする](https://qiita.com/ryo_i6/items/54cba24458b6799b4f8a)"を参考にしてください

テストの実行とは無関係ですが、以下のような命名規則にしています
* パッケージファイルは`pkg_*`
* テストベンチファイルは`tb_*_{test_num}`


```:ディレクトリ構造
root
├─ run.py # テスト実行ファイル
├─ src 
│  ├─ foo
│  │  ├─ pkg_foo.vhd
│  │  ├─ name1.vhd
│  │  └─ name2.vhd
│  └─ bar
│     ├─ pkg_bar.vhd
│     ├─ name3.vhd
│     └─ name4.vhd
├─ test
│  ├─ foo
│  │  ├─ tb_name1_0.vhd
│  │  ├─ tb_name1_1.vhd
│  │  └─ tb_name2_0.vhd
│  └─ bar
│     ├─ tb_name3_0.vhd
│     └─ tb_name4_0.vhd
├─ vendors # ベンダIP
│  └─ xilinx-ise # GHDLで事前に必要なベンダIPをコンパイルする
└─ vunit_out # テスト結果
```

# 実行ファイルの書き方
[Vunit - User Guide](https://vunit.github.io/user_guide.html)とほぼ同じ内容です

ベンダIPライブラリを追加する場合は`add_external_library`を使います

```python:run.py
from os.path import join, dirname
from vunit import VUnit

root = dirname(__file__)
project = VUnit.from_argv()

# ベンダIPライブラリを追加 
project.add_external_library("xilinx-ise", join(root, "vendors", "xilinx-ise"))

# コードをライブラリに追加
lib = project.add_library("lib")
lib.add_source_files(join(root, "src", "*", "*.vhd"))
lib.add_source_files(join(root, "test", "*", "*.vhd"))

# テスト実行
project.main() 
```

## 参考
* [Vunit - User Guide](https://vunit.github.io/user_guide.html)
ローカル開発でコマンド一発で色々なサーバーを立ち上げる

ローカル開発している時にフロントエンドやらバックエンドやらバッチやら、一つずつサーバー立ち上げるのが面倒くさいので、コマンド一発で複数立ち上げるようにしました。
以下のようなスクリプトを実行すると、Terminalのタブを複数開いてそれぞれでコマンドを実行してくれます。地味に便利です。（実行する時に権限が足りない時は、システム環境設定>セキュリティとプライバシー>プライバシー>アクセシビリティからターミナルの権限にチェックを入れてください。）

```
#!/bin/sh
  
osascript -e 'tell application "Terminal" to activate' -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down'
osascript -e 'tell application "Terminal" to do script "cd ~/myproject && rails s" in selected tab of the front window'
osascript -e 'tell application "Terminal" to activate' -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down'
osascript -e 'tell application "Terminal" to do script "cd ~/myproject && npm run dev" in selected tab of the front window'
```
AHK(AutoHotkey)を使い　Shift + マウス右　→　aキー　→　パスとしてコピー　を　Alt + ;　で実現する

IMEGetstateOFF(){
    DetectHiddenWindows, ON
    WinGet, vcurrentwindow, ID, A
    vgetdefault := DllCall("imm32.dll\ImmGetDefaultIMEWnd", "Uint", vcurrentwindow)
    vimestate := DllCall("user32.dll\SendMessageA", "UInt", vgetdefault, "UInt", 0x0283, "Int", 0x0005, "Int", 0)
    DetectHiddenWindows, Off
    If (vimestate=0) ;imeがoffなら
    {
    ;Offだから何もしない
    }
    else
    {
    Send, {vkf3}
    }
    return
}



IMEGetstateON(){
    DetectHiddenWindows, ON
    WinGet, vcurrentwindow, ID, A
    vgetdefault := DllCall("imm32.dll\ImmGetDefaultIMEWnd", "Uint", vcurrentwindow)
    vimestate := DllCall("user32.dll\SendMessageA", "UInt", vgetdefault, "UInt", 0x0283, "Int", 0x0005, "Int", 0)
    DetectHiddenWindows, Off
    If (vimestate=0) ;imeがoffなら
    {
    Send, {vkf3}
    }
    else
    {
    ;Onだから何もしない
    }
    return
}


;------------
;Shift + マウス右　→　aキー　→　パスとしてコピー
!;:: ; Alt+;
;------------

IMEGetstateOFF()
Sleep,300

Send {Blind}{Shift Down}
MouseClick, right
   Sleep,300
Send ,a
   Sleep,100
Send {Shift Up}

IMEGetstateON()
Sleep,300

MsgBox, Ctrl + v で「貼り付け」してください。


Return

【IMEのON,OFF操作を参考にさせていただいたサイト】
https://qiita.com/neokix/items/83ac2ac8e1dd405528b0
UITableView セクション表示

なんでセクションが下に付くのだろうと数時間なやんでしまったのでメモ。。。
Header Footer って書いてあるのに気づかなかったorz

```
/// フッターにつく
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?

/// ヘッダーにつく
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
```
【PhpStorm】PHPのバージョン設定

## PHPのバージョン設定

### 概要
PhpStormでの開発時に、PHPのバージョンを設定する方法は通常では「手順１」を使用する。
PhpStormは自動的に、composer.jsonを読み込みPHPのバージョンを設定する、その場合PHPのバージョン設定が修正できない場合がある。
composer.jsonの設定を無視してPHPの開発バージョンを設定したい場合は「手順２」の方法を使用する。

#### 環境
+ PhpStorm 2019.1.2
+ Windows 10

---

### 手順１（「PHP language level」が変更できる場合）
1. File > Settings（Ctrl + Alt + S でも可）
2. Languages & Frameworks > PHP
3. 「PHP language level」を開発するバージョンに合わせて「OK」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/5c06b43b-bc91-0ecf-3bc4-0834f64c77df.png)

### 手順２（「PHP language level」が変更できない場合）
1. File > Settings（Ctrl + Alt + S でも可）
2. Languages & Frameworks > PHP > Composer
3. 「Syncronize IDE Setting with composer.json」のチェックボックスのチェックを外し「OK」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/d9c9ee2d-6875-9de8-4f1e-63940f45448e.png)
4. 上記の手順により手順１のバージョンを変えることが可能となるので手順１を対応する
JavaScript(ES6) Objectのプロパティのそれぞれの値が存在するか確認する

```javascript
needClear() {
  return (Object.values(this.form).filter(elem => elem).length > 0)
}
```

---
コメントを頂いたので `some` パターンを追記。すっきり〜

```javascript
needClear() {
  return (Object.values(this.form).some(elem => elem))
}
```

---


ユースケースは、Vue.jsなどで

```vuejs
<input v-model="form.name">
<input v-model="form.email">
<select v-model="form.lang">
<checkbox v-model="form.loveMe">
```
のような簡単なフォームをつくったとき、**どれかに値が入っていたら**クリアボタンを表示したい。みたいな時。


（以下はVueの場合のバインディングの仕方）

```vue
<button v-show="needClear">clear</button>
```

としてる。

JavaScriptの真偽判定では、 `0` `false` もfalseとなってしまうが、↑のユースケースなら `<input type="number">` でも文字列が入ってくるし、checkboxでもfalseならクリアする必要がないことがほとんどなのでとりあえず問題はない。

もし `0` や `false` にも対応したい場合は

```javascript
needClear() {
  return (Object.values(this.form).filter(elem =>{
    (elem === false || elem === 0 || elem) return elem
  }).length > 0)
}
```
とかなら対応可能。

けど、走査しちゃうしこんなのでいいのかな。同じ前提条件でももっといい感じの方法がありそう。
（そもそも `form.name` みたいに入れ子にするなよ、というのはごもっとも）
SwiftUIのチュートリアル日記3

# この記事は何
[前回](https://qiita.com/chino_tweet/items/fe2e3b7dc464a3fced3e)からの続きです。

## セクション:3 スタックを使って、ビューを結合する
### 手順1
### 手順2
### 手順3
### 手順4
### 手順5
### 手順6
### 手順7
### 手順8
### 手順9

## セクション4: カスタムイメージビューをつくる
### 手順1
### 手順2
### 手順3
### 手順4
### 手順5
### 手順6
### 手順7

## セクション5: UIKitとSwiftUIを同時に使用する
### 手順1
### 手順2
### 手順3
### 手順4
### 手順5

## セクション6: 詳細ビューを構成する
### 手順1
### 手順2
### 手順3
### 手順4
### 手順5
### 手順6
### 手順7
### 手順8

## 理解度を確認する
ご丁寧に選択形式のクイズで、チュートリアルの理解度を確認できるようになっていました。
SwiftUIを開発者に使って欲しいというAppleの意気込みや気遣いが感じられます。