OmniAICreator/Qiita-1.07M huggingface dataset:
BigQueryで空白だったら更新する方法

マスターのテーブルにデータが入っているのにupdateで元のデータが消えないように
データが入っていない場合のみアップデートできる方法を調べていました。

[参考にした公式ドキュメント](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)


まず下記でデータを用意

```SQL
create table `table1`
(id string,
name string,
romaji string,
score int64);

insert into `table1`
select '1', '佐藤', 'sato', 20;
insert into `table1`
select '2', '田中', 'tanaka', 25;
insert into `table1`
select '3', '加藤', 'kato', 30;
insert into `table1`
select '4', null, null, null;
insert into `table1`
select '5', null, null, null;

create table `table2`
(id string,
name string,
romaji string,
score int64);

insert into `table2`
select '4', '山田', 'yamada', 40;
insert into `table2`
select '5', '佐々木', 'sasaki', 25;
insert into `table2`
select '6', '金子', 'kaneko', 35;
```

table1
![2020-02-19_14h13_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/2884d89e-98a2-d7f2-a8db-688f8fdcb136.png)


table2
![2020-02-19_14h13_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/4664ffcf-593b-d776-e23c-6fe416e9db2f.png)



``` SQL:

MERGE `table1` AS T -- アップデートするターゲットのテーブル
USING `table2` AS S -- データソースとなるテーブル
ON T.id = S.id -- Tのid とSのid が一致するかを判定

-- ONの条件がTRUEの場合
WHEN MATCHED THEN

  -- 各項目で空白だったら更新、空白でなかったら既存データを入れる処理
  UPDATE SET
  T.name = CASE WHEN T.name IS NULL THEN S.name
  ELSE T.name
  END,
  T.romaji = CASE WHEN T.romaji IS NULL THEN S.romaji
  ELSE T.romaji
  END,
  T.score = CASE WHEN T.score IS NULL THEN S.score
  ELSE T.score
  END

-- ONの条件がWALESの場合
WHEN NOT MATCHED THEN
  -- INSERTで指定したカラムにVALUESで指定したカラムのデータを追加する
  INSERT (id,name,romaji,score)
  VALUES (id,name,romaji,score)

```





最初、下記でいけると思って実行していたのですが、
下記のWHEN MATCHEDの使い方だと一番最初に該当する内容のみ実行されて
以下の処理は飛ばされてしまいました。

``` SQL
MERGE `table1` AS T -- アップデートするターゲットのテーブル
USING `table2` AS S -- データソースとなるテーブル
ON T.id = S.id -- Tのid とSのid が一致するかを判定

WHEN MATCHED AND (T.name is null or T.name = '-') THEN -- ※1.上記のONがTRUE且つTのnameが空白か「-」の場合
  UPDATE SET T.name = S.name
WHEN MATCHED AND (T.romaji is null or T.romaji = '-') THEN -- ※2.上記のONがTRUE且つTのromajiが空白か「-」の場合
  UPDATE SET T.romaji = S.romaji
WHEN MATCHED AND (T.score is null) THEN -- ※3.上記のONがTRUE且つTのscoreカラムが空白の場合
  UPDATE SET T.score = S.score
WHEN NOT MATCHED THEN -- 上記のONがFALSEの場合
  INSERT (id,name,romaji,score) -- INSERTで指定したカラムにVALUESで指定したカラムのデータを追加する
  VALUES (id,name,romaji,score)
```

実際に実行してみると下記のようになり

![2020-02-19_14h16_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/a40b1201-2c0b-a255-37d3-176e69e3dc88.png)


最初のWHENの条件(下記部分)のnameが空白という条件処理はされているが、
それ以降のromajiｈが空白の時の処理が実行されていません。

```` SQL
WHEN MATCHED AND (T.name is null or T.name = '-') THEN
```



もう一度実行すると
![2020-02-19_14h16_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/9d56fd28-25d6-ad53-3165-4023b8d10b44.png)

```` SQL
WHEN MATCHED AND (T.romaji is null or T.romaji = '-') THEN 
```

上記の条件での処理だけされます。
MeCab: ユーザー定義辞書に新しい単語を追加する（Windows）

# SAMPLE
```python
私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
姉 名詞,一般,*,*,*,*,姉,アネ,アネ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
芥川龍之介 名詞,固有名詞,作家,*,*,*,芥川龍之介,あくたがわりゅうのすけ,アクタガワリュウノスケ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
本 名詞,一般,*,*,*,*,本,ホン,ホン
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
よく 副詞,一般,*,*,*,*,よく,ヨク,ヨク
読ん 動詞,自立,*,*,五段・マ行,連用タ接続,読む,ヨン,ヨン
で 助詞,接続助詞,*,*,*,*,で,デ,デ
いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル
。 記号,句点,*,*,*,*,。,。,。
 BOS/EOS,*,*,*,*,*,*,*,*
```

# REFERENCE
[MeCabの辞書への語彙追加方法【Windows 10, Ubuntu 18.04】](https://qiita.com/myaun/items/9f8fee924fdc3f7ef411)


# ユーザー定義辞書に新しい単語を追加する
## 辞書を用意する
csvファイルでutf-8として辞書を用意します。
ディレクトリ：C:\Users\ユーザー名\Desktop\MeCabUserDic
ファイル名：test_dic.csv

```csv
芥川龍之介,,,5543,名詞,固有名詞,作家,*,*,*,芥川龍之介,あくたがわりゅうのすけ,アクタガワリュウノスケ
太宰治,,,5543,名詞,固有名詞,作家,*,*,*,太宰治,だざいおさむ,ダザイオサム
```

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

左文脈IDおよび右文脈IDは、該当する単語をそれぞれ左・右から数えた時の内部ID
自動的に付与されるので空の状態で大丈夫だそうですが、私はエラー（しかも文字化け）してしまったので適当な値を振りました。

コストには似たような頻度で出現する単語と同じスコアを振ります。
コストが小さい程検出されやすくなります。

## ユーザー辞書をコンパイル
MeCab\dic\ipadic\mecab-dict-indexを実行します。
通常のコマンドプロンプトで実行するとpermission deniedになってしまってしまったので
下記コマンドで管理者権限のあるコマンドプロンプトを立ち上げます。

```shell
powershell start-process cmd -verb runas
```

下記のコマンドで用意したcsvファイルに基づいてdicファイルを新しく作成します。

```shell
mecab-dict-index -t utf-8 -t utf-8 -d "<MeCab辞書ディレクトリのパス>" -u <新しくdicファイルを作成するディレクトリのパス> <定義した辞書csvファイルのパス>
```

上記のコマンド例は下記。

```shell
mecab-dict-index -f utf-8 -t utf-8 -d "C:\Program Files\MeCab\dic\ipadic" -u C:\Users\yuri.kinoshita\Desktop\MeCabUserDic\test.dic C:\Users\yuri.kinoshita\Desktop\test_dic.csv
```

実行結果です。
done!

```shell
reading C:\Users\yuri.kinoshita\Desktop\MeCabUserDic\test_dic.csv ... 2
emitting double-array: 100% |###########################################|

done!
```

# HOW TO USE

```python
import MeCab

mecab = MeCab.Tagger (r"-Ochasen -u C:\Users\yuri.kinoshita\Desktop\MeCabUserDic\test.dic")

text = "私の姉は芥川龍之介の本をよく読んでいる。"
node = mecab.parseToNode(text)
while True:
	node = node.next
	if not node: break
	print(node.surface,node.feature)
```

実行例。

```python
私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
姉 名詞,一般,*,*,*,*,姉,アネ,アネ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
芥川龍之介 名詞,固有名詞,作家,*,*,*,芥川龍之介,あくたがわりゅうのすけ,アクタガワリュウノスケ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
本 名詞,一般,*,*,*,*,本,ホン,ホン
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
よく 副詞,一般,*,*,*,*,よく,ヨク,ヨク
読ん 動詞,自立,*,*,五段・マ行,連用タ接続,読む,ヨン,ヨン
で 助詞,接続助詞,*,*,*,*,で,デ,デ
いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル
。 記号,句点,*,*,*,*,。,。,。
 BOS/EOS,*,*,*,*,*,*,*,*
```
【Riot.js】【訂正版】cdnで楽々Hello World

[Riot.js](https://riot.js.org/ja/documentation/)の勉強をしています。
npmやwebpackを使う方法もあるのですが、より簡単なcdnを使う方法で学習を進めていきます。

まずは、任意のフォルダに``index.html``と``app.riot``を用意します。

```html:index.html

<!doctype html>

<html>
  <head>
    <title>Riot todo</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  </head>

  <body>

    <app></app>

    <script src="app.riot" type="riot"></script>
    <script src="https://cdn.jsdelivr.net/npm/riot@4/riot+compiler.min.js"></script>

    <script>
      riot.compile().then(() => {
        riot.mount('app', {
          title: 'Hello World',
        })
      })
    </script>
  </body>
</html>
```

```html:app.riot
<app>
  <h3>{ props.title }</h3>
</app>
```

このままhtmlファイルをchromeにおくと、``URL scheme must be "http" or "https" for CORS request.``といったエラーが出てしまうので、以下の手順でローカルサーバーを立てます。

```
$ npm install -g live-server
$ cd <index.htmlとapp.riotがあるフォルダ>
$ live-server .
# http://localost:8080/でブラウザからアクセス可能
```

これで画面にHello Worldと表示されます！！


[参考] 
https://github.com/riot/examples
[ChromeにてAjaxでローカルファイルにアクセス](https://qiita.com/cigalecigales/items/33afaa42f91542ffa62e)
docker環境のメールはmailhogで決まり

# docker環境でメールどうしよう問題
* 直接送りゃいいんじゃね?
 * いやいや、事故るっしょ。1万通とかメール送信してしもたら・・・
* そのためだけにsendgridとかmailgunとか
 * おおげさ
* postfixのコンテナあげる?
 * 環境つくるだけで一苦労しそう(docker-hubにあるけど)

# ということでいろいろ探してたらMailHogというものを発見しました
* メリット
 * 事故らない
 * いくらメール投げてもローカルにしかとどまらないので
 * 設定が簡単
 * WEB UIでメール確認ができる
* デメリット
 * 日本語メールは文字化けすることがある、UTF-8でおねがいしたい
 * なぜかdockerコンテナが死ぬことがある、まあコンテナのリスタートしてください

# Howto
## 1. docker-compose.ymlにはこれだけ追加するだけ

```docker-compose.yml
mailhog:
  image: mailhog/mailhog
  ports:
    - "8025:8025"
```

## 2. mhsendmailを入れてください
 * https://github.com/mailhog/mhsendmail
 * goで出来ています
 * yumとかaptでsendmailいちいち入れるの面倒なので、こいつをマウントしてやれば良い
* 例えばこんな感じ

```docker-compose.yml
volumes:
  - "./bin/mhsendmail:/usr/local/bin/mhsendmail"
```
## 3. phpの人向け
* webサーバのコンテナのphp.iniに追加(変更)しておくと、phpの標準mail関数でメール送信できますんで既存コードをいじらなくて済む

```php.ini
sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"
```

以上です、快適なdockerライフを!!
Amazon Linux2でLet's EncryptするのをItamae化

# はじめに
RailsアプリケーションのサーバーをItamaeで管理しているます。
環境構築時にELBを立てず、サーバー直接でアクセスさせる場合、サーバーへのSSL証明書の設定が必要になります。
サーバーはAmazon Linux2で、SSL証明書はLet's Encriptで取得するのをItamae化してみました。

nginx, Itamae, Certbotのインストール、構築は既に済んでいるものとします。

## 環境

- サーバー
EC2

- OS
Amazon Linux2

- バージョン
Rails: 5.x.x（複数プロジェクト）
Ruby: 2.x.x

## 手動構築手順

参照：
https://qiita.com/MysteriousMonkey/items/4d3d857c0e68d4bfff39[https://qiita.com/MysteriousMonkey/items/4d3d857c0e68d4bfff39]

簡単に説明すると、下記コマンドを打つ

```
$ sudo certbot --nginx
```

すると、対話式でメールアドレス、対象ドメイン、規約への同意などなどの確認があったのち、SSL証明書が作成され、nginx.confに自動的に設定される.

**その対話をコマンドオプション指定でなくすことができるかどうかが今回の争点！**

## 結論

- cookbooks/certbot/default.rb

```ruby

execute 'download EPEL7' do
  user 'root'
  command "wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/"
end

execute 'install EPEL7' do
  user 'root'
  command "rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm"
end

execute 'enable EPEL7' do
  user 'root'
  command 'yum-config-manager --enable epel*'
end

package 'certbot'
package 'python2-certbot-nginx'


execute 'SSL証明書を作成' do
  user 'root'
  command "certbot --nginx -d #{node[:dns][:server_name]} --agree-tos --register-unsafely-without-email -n"
end
```

### やったこと

- Amazon Linux 2 でEPEL7を使用可能にする。
- certbotとpython2-certbot-nginxをインストール
- 証明書の作成
    - オプション
        - -d example.com # => DNSを指定。nginx.confのserver_nameと同じにする
        - --agree-tos # => 規約に同意
        - --register-unsafely-without-email # => メールを登録しない（非推奨）
        - -n #=> 対話をなくす

certbot自体のオプションはそのまま流用可能なようなので、registerする場合は 

```
--email test@example.com
```
などの指定も可能。

これでめっちゃ手軽にLet's Encript生活！！

## 事後作業

証明書更新のCronの設定は適宜参照してください。===>> 上記URL



参考にさせていただいたサイト

- [Amazonドキュメント](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html#letsencrypt)
- [https://github.com/certbot/certbot/issues/3310](https://github.com/certbot/certbot/issues/3310)
- [https://qiita.com/noraworld/items/3d492a50ee43dfd3ae5a](https://qiita.com/noraworld/items/3d492a50ee43dfd3ae5a)
excel, js, 長期休暇の申請について、google先生と中二病患者の答えの比較。

　4才の時に幼稚園のお遊戯が大の苦手で、（音痴な歌声を伴いながら大人の動きの真似をするというこんなつまらない儀式に偽り以外の何物でもない笑みを浮かべる周りの子たちはきっと宇宙の悪魔か何かで、自分とは明確に異なる生き物でありその違いとは男女の性差よりも手前に来るおよそ決定的なものだ。。）と悟って以来の先天性難治性中二病自覚患者（ADHD Lv5）である私が、excel, js, 長期休暇の取得方法についての疑問に対する、google先生と拙の回答を簡潔に対比してみました。

　それぞれにメリットとデメリットがあると思いますので、ケースバイケースで取捨選択してみてください。

###Q1. 【excel】（c）が©️になってしまいます。

####　A1_1.google先生の答え
　　　「オートコンプリートをオフにします。」

####　A1_2.季節性中二病患者の答え
　　　「閉じカッコを全角にしてもバレません。」

####　A1_3.先天性難治性中二病患者の答え

　　　="(c"&")"

###Q2.書いたjsがIEのみ動作しません。何のエラーも出ません。

####　A2_1.google先生の答え
　　　「console.logの消し忘れに注意してください。」

####　A2_2.季節性中二病患者の答え
　　　&lt;script src=hoge>&lt;a href=//google.com/search?q=chrome>みんなが使ってるブラウザ&lt;/a>&lt;/script>

####　A2_3.先天性難治性中二病患者の答え
　　function cl(s){try{console.log(s)}catch(e){}}

###Q3.長期休暇を取りたいのですが、上司に切り出せずにいます。

####　A3_1.google先生の答え
　　　「上司には早めに伝えておきましょう。仲間同士で欠員を補い合う環境を普段から作っておくのも大事です。」

####　A3_2.季節性中二病患者の答え
　　　「『一昨年亡くなったのは生みの母の育ての母であり、昨晩救急車で運ばれたのは育ての母の生みの母です。』」

####　A3_3.先天性難治性中二病患者の答え
　　「『70年前に制定された日本国憲法でありますが、国民はやれ改憲だ護憲だと互いに喚き散らすばかりで、右翼、左翼ともども今目の前にある条文の中身を何一つ遵守しておりません。とりわけ男女平等の原則が盛り込まれた事は当時として画期的であったにも拘らず、現実社会は21世紀のこの期に及んで大手企業の接待費も殆どが男性役員、男性社員の為に使われ、サラリーマンの毎日のランチと比較して主婦の週一のランチを高いと申す割りにはゴルフだのノーパンしゃぶしゃぶだのにはしぶとく目を瞑り、管理職や重役の女性比率も世界最低ランクの域に成り下がっております。一国を覆わんとするこの巨悪の根元は男性の男性による男性のための論理によって共和的平等とは乖離したファシズム的平等の押しつけが罷り通る極東アジア固有の民族性にあり、その事を如実に裏付けするケースとして「長期休暇を取る者は管理職に成れない」という合理性の欠片もない悪しき慣習があります。30を超えたばかりの女性に出産か係長かの二者択一を迫るこの手の陰湿な間接的不平等はヘイトスピーチや不買運動の類いよりある意味で根深い差別問題であるばかりか、少子化問題、実力主義の否定といったの諸々の問題とも密接に結びつくものであり、愛する姪っ子がやがて大人になりリケジョとなり子育てをしながらエンジニアとして幸せに生きることを今より望み人生の糧とする下名としては到底看過できるものではなく、この際上長には率先して長期休暇を取って頂き、当部門、当社、ひいては愛する母国における男女平等の礎を築いて頂きたいところではありますが、しかしながら私めをはじめ、部下であり平社員である者共が長期休暇を取らない以上は上長もなかなか取得しづらいかと存じます。従いまして、下名が第一歩兵部隊の特攻隊員となり、あるいは開墾者として荒野の芝を刈り草を毟る事で上長の王道に花を添えんとする自らの使命を帰結し、来週の金曜より十七日間、カンボジアのアンコールワットへ嫁探しに参る事に致しました。お土産はストゥントレン県名産のコーヒー豆で宜しいでしょうか？』」
【Vue】radioボタンで初期値を設定する方法

# 普通に書いてみると、できてない

```html:
<input type="radio" v-model="ratio" value="600" checked>
<label>2倍</label>
<input type="radio" v-model="ratio" value="900">
<label>3倍</label>
<input type="radio" v-model="ratio" value="1200">
<label>4倍</label>

data(){
    return {
        ratio: null
    }
}
```

# dataの値と初期値として設定したいvalueを同じにする

https://vuejs.org/v2/guide/forms.html#Radio-1

```html:
<input type="radio" v-model="ratio" value="600">
<label>2倍</label>
<input type="radio" v-model="ratio" value="900">
<label>3倍</label>
<input type="radio" v-model="ratio" value="1200">
<label>4倍</label>

data(){
    return {
        ratio: 600
    }
}
```
[Mac] 動画を簡単にGIFアニメへ変換する

# TL;DR
MacOS標準アプリケーションの`Automator.app`を使う．
ffmpegを用いたAutomatorワークフローを作成．
GIFアニメにしたい動画を右クリックし，`Service -> Convert to animation gif`を実行．

ね？簡単でしょ？

![18d8d4a535ee786b4f9778bfdab1e664.png](https://qiita-image-store.s3.amazonaws.com/0/245014/87d4e1e0-bb95-2685-ef8f-941314d63bf5.png)

# Setup
まずはじめにGIFアニメに変換するためのツールを入れる．

```bash
$ brew install ffmpeg
```

# Create workflow
それでは，`Automator.app`で作っていく．
詳しくは[こちら](https://qiita.com/tkkrr/items/7f22a81eff5e7e269961)を参考にしてほしい．

最初の画面では「クイックアクション」を選択する．
![スクリーンショット 2020-02-19 12.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245014/5dcbde5b-c6da-ef48-034f-b9f32a05bd8d.png)

ワークフローのレシピは下の画像を参照．

![スクリーンショット 2020-02-19 12.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245014/0e827a2e-960e-7785-ca39-8337d8a1c5ed.png)

AppleScriptの部分はなくてもOK，
Shellスクリプトは以下をコピペ．

```bash
export PATH=$PATH:/usr/local/bin
dire=`dirname $1`
cd $dire
ffmpeg -i $1 output.gif
```

ここまで作ったら保存する．
あとは，好きな動画を右クリックで選択し，`Service -> Convert to animation gif`を選択する．

![スクリーンショット 2020-02-19 12.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245014/7f01d19e-6aa9-302d-233e-271da0b258ea.png)

画面右上に歯車が表示され，回転していれば成功．
![スクリーンショット 2020-02-19 12.38.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245014/88e913b5-660b-b3c0-68db-9af5ae096a69.png)
回転中は動画をGIFアニメに変換している．
回転が止まれば処理が終了し，`output.gif`というGIFアニメファイルが出来上がっている．


# Attach keyboard-shortcut
作ったワークフローをキーボードショートカットに登録するとさらにラクできる．
手順は簡単で，左上のマークから，`システム環境設定 -> キーボード -> ショートカット`から`サービス -> convert to animation gif`で好きなキーショートカットを登録する．

![スクリーンショット 2020-02-19 12.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245014/87553786-4fac-66bd-48fa-bd3edc37b5ed.png)

ショートカットからワークフローを実行する場合は，変換したいファイルをワンクリック（選択）してからショートカットを入力する．

ね？簡単でしょ？

# 参考記事
- [それFFmpegで出来るよ！](https://qiita.com/cha84rakanal/items/e84fe4eb6fbe2ae13fd8)
- [FFmpegで動画をGIFに変換](https://qiita.com/wMETAw/items/fdb754022aec1da88e6e)
- [MacでGIFの作り方](https://qiita.com/k-penguin-sato/items/63c1a526d5b176691221)
- [mov -> gif](https://qiita.com/macoshita/items/90222ab67440875a0a98)
Rails6 のちょい足しな新機能を試す 121（PostgreSQL index_exists?編)

# はじめに

Rails 6 に追加された新機能を試す第121段。 今回は、`PostgreSQL index_exists?` 編です。
Rails 6 (と Rails 5.2.4.1) では、 `index_exists?` が正しく動作しないバグが fix されています。

Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1, Rails 5.2.3, PostgreSQL 12.0 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)

```shell
$ rails --version
Rails 6.0.2.1
```

今回は、 name の属性を持つ User モデルを作り、インデックスを追加して確認してみます。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

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

# User モデルを作る

`name` 属性を持つ `User` モデルを作ります。

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

# インデックスを追加する

今回は2つのインデックスを作成します。 `lower(name)` を指定したインデックスと、単純に `name` カラムを指定したインデックスです。

```shell
bin/rails g migration add_index_lower_name_to_users
```

```ruby:db/migrate/20200207213234_add_index_lower_name_to_users.rb
class AddIndexLowerNameToUsers < ActiveRecord::Migration[6.0]
  def change
    add_index :users, 'lower(name)', name: 'index_lower_name'
    add_index :users, 'name', name: 'index_name'
  end
end
```

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

マイグレーションを実行します。

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

# rails console で確認する

`rails c` を実行します。

```shell
$ bin/rails c
Running via Spring preloader in process 344
Loading development environment (Rails 6.0.2.1)
```

`indexes` で登録されているインデックスを調べてみましょう。
（わかりやすいように表示は折り返してます。）

```irb
irb(main):001:0> User.connection.indexes(:users)
=> [
#<ActiveRecord::ConnectionAdapters::IndexDefinition:0x00005617bc6ef580 
@table=:users, 
@name="index_lower_name", 
@unique=false, 
@columns="lower((name)::text)",  # <=  ここに注目
@lengths={}, 
@orders={}, 
@opclasses={}, 
@where=nil, 
@type=nil, 
@using=:btree, 
@comment=nil>, 
#<ActiveRecord::ConnectionAdapters::IndexDefinition:0x00005617bc8c3be0 
@table=:users, 
@name="index_name", 
@unique=false, 
@columns=["name"],  # <= ここに注目
@lengths={}, 
@orders={}, 
@opclasses={}, 
@where=nil, 
@type=nil, 
@using=:btree, 
@comment=nil>
]
```

`index_lower_name` に対応する `@columns` が `'lower((name)::text)'` で String であるのに対して、 `index_name` に対応する `@columns` が `["name"]` とArray になっていることに注意してください。

`index_exists?` を使って `index_name` が存在することを確認します。

```irb
irb(main):002:0> User.connection.index_exists?(:users, "name", name: :index_name)
=> true
```

今度は、 `index_lower_name` が存在することを確認します。

```irb
irb(main):003:0> User.connection.index_exists?(:users, "lower((name)::text)", name: :index_lower_name)
=> true
```

# Rails 5 では

Rails 5.2.4.1 では、 Rails 6 と同じ動作ですが、 Rails 5.2.3 では、 `index_lower_name` の存在を確認したとき `false` を返します。

```irb
irb(main):001:0> User.connection.index_exists?(:users, "name", name: :index_name)
=> true
irb(main):002:0> User.connection.index_exists?(:users, "lower((name)::text)", name: :index_lower_name)
=> false
```

# 試したソース

https://github.com/suketa/rails_sandbox/tree/try121_index_exists_of_postgresql


# 参考情報

* [Fix index_exists? for PostgreSQL expression indexes](https://github.com/rails/rails/pull/36740)
Cloud Run × Flaskでお手軽にマイクロサービスを実現する

# はじめに

個人開発でアプリ作成中なんですが、バックエンドをrailsで作っていました。
そんなある日。。。　こんな記事を見ました。
[Firebaseでバックエンドエンジニア不在のアプリ開発　クックパッドが体感した、メリットと課題](https://employment.en-japan.com/engineerhub/entry/2018/08/30/110000)

<b>Firebaseならバックエンドエンジニアを必要としない開発ができる</b>

( ﾟдﾟ) ... マジカ

これに感化されてCloud Functionでバックエンドを作ってました。

が

ある理由でそれは辞めました。

#なぜ、Cloud Functionを採用しなかったか

今回マイクロサービスをアーキテクチャとして採用し、さらに各機能を自分が作るのは嫌なので、BaaSをサービスと定義して自分はBFFだけ作ってやろうという腹でした。

それだったら、BaaS単位で共通のライブラリファイル作ったほうが、<b>他のプロジェクト</b>を立ち上げる時に楽だよね？となり、クラウドファンクションにそういう共通化する機能があることを知り採用しようとしました。

しかし。。

めんどくさい(；´Д｀)

そもそもローカルでファンクション単位でしか実行出来ないのも嫌気が差して
これ、ローカル実行出来るフレームワークをクラウドファンクションみたいにサーバレスで動かせばよいのでは？
と発想。

cloud runというDockerでサーバレスに構築、しかもリクエスト単位の稼働で課金(データの永続化は出来ない)
という、正にクラウドファンクションの上位？互換のサービスがあることを知り今回採用しました。

#結局、何が言いたいの？

- マイクロサービス
- サーバレス
- リクエスト単位課金
- 低料金
- <b>自分で機能を作りたくない</b>
- <b>環境構築したくない</b>

これらを実現したい人向けにサンプル(土台)を作ったから、使ってね！
と言いたいです。

#作ったもの

以下です。

https://github.com/taiseiotsuka/Flask-On-CloudRun

readmeに全部構築手順書いたので、よければ使ってみてください。

※ DockerリポジトリはGoogle Container Registryを使うことを想定としています。
※ デプロイはGCPのマネコンから行うことを想定としています。
※ BaaSに当たる部分は今回サンプルとしてGoogle Firestore(Nosql DB)を使用しています。

使い方わからなかったら質問してね！

Bye
【bitrise】Undefined symbols for architecture x86_64が出る時に疑う事

自分がハマったのでtipsの共有です。

# 問題
bitriseで何回ビルドを行っても**<font color= #ff4500>「Undefined symbols for architecture x86_64」</font>**というエラーが出るので困り果てていたのですが、すごく些細な理由で問題が起きていました。

# 原因
XcodeのSchemeで、`Gather coverage for`にチェックマークしていないのに、bitrseの`Xcode tests for iOS`のステップで、`Generate code coverage files?`のオプションを`yes`にしていることが原因です。

bitriseのテストステップは内部でxcodebuildを使ってテストを実行しているのですが、これをyesにすると`GCC_GENERATE_TEST_COVERAGE_FILES`というオプションが`YES`でコマンドに渡されるようになります。

Gather coverage forをyesにすると、xcodeproj内のxcschemeの`codeCoverageEnabled`というフィールドがYESになるのですが、この項目がYESではないのに `GCC_GENERATE_TEST_COVERAGE_FILES=YES`のオプションを渡しているためエラーが発生したようです。

```bash:xcodebuild.sh
set -o pipefail && env "NSUnbufferedIO=YES" xcodebuild "-workspace" "Some.xcworkspace" "-scheme" "Some" "build" "COMPILER_INDEX_STORE_ENABLE=NO" "test" "-destination" "id=DDD6FC97-6DB4-40D9-89AB-0B9C5541B18B" "-resultBundlePath" "/var/folders/6q/wgy6jtp12w5gzgm9lzcglpqw0000gn/T/XCUITestOutput157008135/Test.xcresult" "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES" "GCC_GENERATE_TEST_COVERAGE_FILES=YES" | xcpretty "--color" "--report" "html" "--output" "/Users/vagrant/deploy/xcode-test-results-CanDO.html
```

# 解決
bitrseの`Xcode tests for iOS`のステップで、`Generate code coverage files?`のオプションを`no`に設定した発生しなくなりました。

そもそも収集していないのに生成しようとすると、タイトルの`Undefined symbols for architecture x86_64`というエラーが投げられるようです。

# Bitriseでハマった時のデバッグ
デバッグに効果的だった方法を書き残しておきたいと思います。

1. **ローカルとCIの環境がバラバラにならないように、パッケージ管理の仕組み(Bundlerなど)を使う**
2. **CIのログを読んで、ローカルで同じコマンドを実行してみる**

特に2番目は大事で、CIはVM立ち上げるのが遅いのでちょっと変えて試してがやりにくくて、デバッグはし辛いです。なので、手元で同じコマンドを打って、どのようなコマンド,オプションの渡し方をすればこの問題は解決するのか。というところから逆算でCIのステップを直していくのが効果的でした。
GitHubの基本的な使用方法

※使用環境:Windows10, Cloud9, GitHub

railsチュートリアルをCloud9上で進めるうえで必須なコマンドをまとめました。

#新規アプリの場合
####①ターミナル上でcdコマンドを用いて保存したいフォルダ階層に移動する(例はsample_appを保存したい場合)

```
$ cd Cloud9User:~/environment/sample_app
```
####②git initでセットアップ
リポジトリ作成に必要な作業

```
$ git init
```

####③git add -A
ステージングで変更したファイルを選択する。
-Aで現在のディレクトリのファイル全て選択できる。

```
$ git add -A
```

例えばREADME.mdのみ変更した場合は`git add README.md`とすればよい

####④git commit -m "変更コメント"
-mコマンドでメッセージを挿入

```
$ git commit -m "変更コメント"
```
####⑤GitHub上でリポジトリ作成
GitHubアカウント登録が必要です。（無料）
ログインして右上のアイコンをクリックして"Your repository"をクリックします。
"New"を選択し、"Repository name"にアプリ名（例の場合はsample_app）にして"Create repository"をクリックします。

####⑥GitHubをリポジトリのoriginとする


```
git remote add origin https://github.com/(gitHubユーザー名)/(リポジトリ名).git
```
####⑦ステージングで選択したフォルダ（ファイル）をプッシュする
以下のコマンドを入力します。
ユーザー名とパスワードが要求される場合があるのでGitHubのユーザー名とパスワードを入力します。（パスワード入力の文字は表示されないので注意）

```
$ git push -u origin --all
```

#途中から始める場合
ブランチ(branch、分岐)を利用すると途中で戻りたくなった場合に復元できます。

####branch作成
```
$ git checkout -b (baranch名)
```

####branch確認

```
$git branch
  master
* modify-README
```
*は現在使用しているブランチになります。

####Merge（マージ）
ファイル変更が終わってmasterに変更内容を反映させたい場合、Mergeを行います。
変更内容がわかるようにまずcommitでコメントを残してからmergeするとよいでしょう。

```
$ git commit -a -m "変更内容コメント"
$ git checkout master
Switched to branch 'master'
$ git merge (branch名)
```

#変更内容を確認
`git status`で現状の変更内容を確認できます。
`git log`でコミットメッセージの履歴を確認できます。

#前のbranchに戻りたい場合
```
$ git branch
* master
  modify-README
```
の状態で

```
$ git checkout modify-README
Switched to branch 'modify-README'
```
となるが

```
$ git checkout -
Switched to branch 'master'
```
とするとブランチを切り替える前の状態に切り替えられる。




#クラウドIDE上でHerokuをインストールするコマンド

```
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
```
標準機能だけでiPhoneをMacのタブレット画面ぽく使える！（連携スケッチ）

#知らなかった。。。

https://support.apple.com/ja-jp/HT204975#sketch

「SidecarはiPhoneから使えないのかよっ」って思ってその他の機能をチェックしてなかったけど、
グラレコのセミナー受けた後に、こんなことできないもんかなと探してたら標準で出来たという幸せ。

#実際にやってみるとこんな感じ
Macで操作している画面キャプチャです。右側はiPhoneの画面をMacのQuickTimeで出してるものです。
以下の操作をやってます。
1、（Mac上：画面左側）PPTの任意箇所で「2本クリック」->「スケッチを追加」
2、（iPhone上：画面右側）手でお絵描き -> 完了ボタン（ダークモードがすこぶる見づらい😂）
3、（Mac上：画面左側）取得した画像を移動
![連携スケッチtake2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116534/f5e16aaf-b00e-51c0-7d2b-ce6992ef35c8.gif)




#使ってみた感想

- 標準のメモでは問題なく使えた。
- PowerPointでは2本指クリックで使えた！
- Wordでは使えないっぽい。グレーアウトされてた。（でもPPT経由で持ってけば使えるからまぁよしとする）
- Excelではメニューすら出てこない。（同上。）
- 解像度は高くないっぽい＆ベクターじゃないので拡大するとザラザラ。
- 使えるペンとかはメモで使えるものとおんなじっぽい。
- 透過な画像形式だったので蛍光ペンとかはPPTに貼り付けたら背景が透けて見える（なんて言うのかな。アルファチャンネル？）
- 夕方超えるとダークモードになって背景真っ黒になるので蛍光ペンがすこぶる見えにくい。
- iPhone画面ロックした状態からでも使える。（ちょっと待たされるけど）

とまぁ知っているとポンチ絵作るときなんかとっても早くなるかもです。

こんな便利なの、早く教えてよAppleさん！🙌
UpdateではなくCoroutineで処理を行ってみる

初めに
---
この記事を書いた理由は[前回の記事](https://qiita.com/jerikkuxr/items/c53a0977eed90c71098e)で頂いたコメントを参考にちょっと処理を変えてみたからです。

前回の記事で頂いたコメントの内容は**「Update関数内でfadeの判定をしてしまうとfadeを望まないタイミングでもずっと判定してしまうので無駄が発生してしまうから別の処理に変えた方がいいよ！」**という内容でした。
改善してみた
---
Updete内で行っていた処理を全てコルーチンに置き換えてみました
以下プログラム

```c#:SceneFadeManager.cs

public class SceneFadeManager : MonoBehaviour
{
    //透明度が変わるスピード
    float fadeSpeed = 0.75f;
    //画面をフェードさせるための画像をパブリックで取得
    public Image fadeImage;
    //画像のRGBA値設定用
    float red, green, blue, alfa;
    //シーン遷移のための型
    string afterScene;
    //フェードイン用のコルーチン
    IEnumerator fadeInCoroutine;
    //フェードアウト用のコルーチン
    IEnumerator fadeOutCoroutine;
    // Start is called before the first frame update
    void Start()
    {
        fadeInCoroutine = FadeIn();
        fadeOutCoroutine = FadeOut();
        DontDestroyOnLoad(this);
        SetRGBA(0, 0, 0, 1);
        StartCoroutine(fadeInCoroutine);
        //シーン遷移が完了した際にフェードインを開始するように設定
        SceneManager.sceneLoaded += fadeInStart;
    }
    //シーン遷移が完了した際にフェードインを開始するように設定
    void fadeInStart(Scene scene,LoadSceneMode mode)
    {
        fadeInCoroutine = FadeIn();
        StartCoroutine(fadeInCoroutine);
    }
    /// <summary>
    /// フェードアウト開始時の画像のRGBA値と次のシーン名を指定
    /// </summary>
    /// <param name="red">画像の赤成分</param>
    /// <param name="green">画像の緑成分</param>
    /// <param name="blue">画像の青成分</param>
    /// <param name="alfa">画像の透明度</param>
    /// <param name="nextScene">遷移先のシーン名</param>
    public void fadeOutStart(int red,int green,int blue,int alfa,string nextScene)
    {
        SetRGBA(red, green, blue, alfa);
        SetColor();
        afterScene = nextScene;
        fadeOutCoroutine = FadeOut();
        StartCoroutine(fadeOutCoroutine);
    }
    IEnumerator FadeIn()
    {
        for (int i = 0; i < 360; i++)
        {
            //不透明度を徐々に下げる
            alfa = Mathf.MoveTowards(alfa, 0f, fadeSpeed * Time.deltaTime);
            //変更した透明度を画像に反映させる関数を呼ぶ
            SetColor();
            yield return null;
            if (alfa <= 0)
                StopCoroutine(fadeInCoroutine);
        }
    }
    IEnumerator FadeOut()
    {
        for (int i = 0; i < 360; i++)
        {
            //不透明度を徐々に上げる
            alfa = Mathf.MoveTowards(alfa, 1f, fadeSpeed * Time.deltaTime);
            //変更した透明度を画像に反映させる関数を呼ぶ
            SetColor();
            yield return null;
            if (alfa >= 1)
            {
                SceneManager.LoadScene(afterScene);
                StopCoroutine(fadeOutCoroutine);
            }
        }
    }
    //画像に色を代入する関数
    void SetColor()
    {
        fadeImage.color = new Color(red, green, blue, alfa);
    }
    //色の値を設定するための関数
    public void SetRGBA(int r, int g, int b, int a)
    {
        red = r;
        green = g;
        blue = b;
        alfa = a;
    }
}
```
感想
---
実際に処理を変えてみるとシーン内に余り物を置いていないので劇的に変わったとまではいきませんが、
シーンを切り替えたときにFPS値の減少が少なくなっていました。
ほぼ何も置いていないシーンで変化が起きたということは、もっと大きなゲームになると、とてつもない影響が出るのではないかと思いました。
これからゲームを作るときには処理をすぐにプログラムしてこれでいいやとするのではなく、もっといい処理方法がないか考えてプログラムしていこうと思います。
phpのshort_open_tagがOffの場合のエラー内容が分かりづらかった

phpでviewをテンプレートエンジンとして実装している際に以下のような記載をしたところ
以下のようにエラーになりました。

```php
<?php if ($is_ok): ?>
<p><?php echo $message1; ?></p>
<?php else: ?>
<p><?php echo $message2; ?></p>
<? endif; ?>
```

```php:エラー内容
Fatal Error - Method Fuel\Core\View::__toString() must not throw an exception, caught ParseError: syntax error, unexpected end of file in /XXX/XXX.php on line 0
```

調べてみると、
``<? endif; ?>``
この部分が誤字脱字でした。
``short_open_tag``の指定が必要でした。

## short_open_tagとは？

php.iniで``short_open_tag``をONにすると``<?php``を``<?``として省略できます。
が、このphp指定が抜けていたのでおかしくなったようです。

エラー内容が分かりづらい。。

ちなみにphp7.3でもデフォルト値はOnとコメント記載があったのに
設定自体はOffになっていました。

```php:デフォルト設定
; short_open_tag
;   Default Value: On
;   Development Value: Off
;   Production Value: Off
```

php7.4からは``<?``はDeprecatedとなりphp8からは廃止される予定のようなので変わったのかな？
完全二分木の根の高さがO(logn)となる理由

#完全二分木
完全二分木は根付き木の一つで，各頂点の子は多くても２個であるような木のことです．また，頂点は常に左に詰めて配置されています．ヒープ木も完全二分木の一つで，根の要素が最小値であるような木のことです．根から一番遠い子孫までの路の長さを根の高さと言います．下図の例では根の高さは3となります．<img width="816" alt="Screen Shot 2020-02-19 at 10.40.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391974/7a4a9159-f821-2e42-d1d5-56254d98dd2a.png">

##高さのオーダーは？
完全二分木は，根の高さによってその木の要素の最大数は決まっています．例えば，根の高さが3なら最大でも15個です．では，要素の数をnとすると根の高さはどうなるのか？各深さにおける最大の要素数は深さをdとすると，2^d個となります．つまり，根の高さがhの木の場合，**最大の要素数は(2^0+2^1+...2^h)個**になります．
ここで，
*2^0 + 2^1 + ... 2^n = 2^(n+1) - 1*
のように最大の要素数を表すことができます．根の高さがhの木の最大の要素数は*2^(h+1) - 1*個となります．
また，根の高さがh-1の木の最大の要素数は*2^(h) - 1*個となります
よってn個の要素を含む完全二分木の値の高さは，
***2^h - 1 < 2^h <= n < 2^(h+1) - 1 < 2^(h+1)***
***⇨ 2^h <= n < 2^(h+1)***
***⇨ h = O(logn)***
完全二分木の根の高さはO(logn)であることがわかりました．
minioクライアント(mc コマンド)の使い方

# はじめに
mcコマンドにより、minio(S3, GCS等でも可)をクライアント側からCUIで操作できる。インストール手順から簡単な使い方まで説明する。

# インストール方法
下記URLの通りだが、記載しておく。
https://docs.min.io/docs/minio-client-quickstart-guide.html#test-your-setup

## macOS
```bash
$ brew install minio/stable/mc
```

## GNU/Linux
```bash
# 64-bit Intel Architectureの場合
$ wget https://dl.min.io/client/mc/release/linux-amd64/mc
# 64-bit PPC Architectureの場合
$ wget https://dl.min.io/client/mc/release/linux-ppc64le/mc
$ chmod +x mc
```

## Microsoft Windows
下記から実行ファイルをダウンロードする。
https://dl.min.io/client/mc/release/windows-amd64/mc.exe

# 設定方法
立ち上げたminioの設定を~/.mc/config.jsonに記載して、mcコマンドが使えるようになる。
私の環境だと"lookup": "dns"とするとうまくいかなかった。

下記のようなminioの設定の場合で~/.mc/config.jsonを記載する。
host名 : hoge
ipアドレス or ドメイン : hoge.com
ポート : 9000
アクセスキー : minio
シークレットキー : minio123

```~/.mc/config.json
{
        "version": "9",
        "hosts": {
                "hoge": {
                        "url": "http://hoge.com:9000/",
                        "accessKey": "minio",
                        "secretKey": "minio123",
                        "api": "S3v4",
                        "lookup": "auto"
                }
        }
}
```

# コマンド
簡単な使い方を記載する。詳しくはhelpを参照。

```bash
# バケットを作成する
$ mc mb hoge/test
Bucket created successfully `hoge/test`.
```

```bash
# バケットとオブジェクトを確認する
$ mc ls hoge
[2020-02-19 11:07:39 JST]      0B test/
```

```bash
# ローカルからminioにコピーする
$ touch test.txt
$ mc cp test.txt hoge/test
$ mc ls hoge/test
[2020-02-19 11:10:27 JST]      0B test.txt
```

```bash
# minioからローカルにコピーする
$ rm test.txt
$ mc cp hoge/test/test.txt ./
```

```bash
# オブジェクトを削除する
$ mc rm hoge/test/test.txt
Removing `hoge/test/test.txt`.
$ mc ls hoge/test
```

```bash
# バケットを削除する
$ mc rb hoge/test
Removed `hoge/test` successfully.
$ mc ls hoge
```
【Windows】AnacondaのPATHの設定で躓く初学者の話。

#きっかけ
Rで解析してたら、Pythonも学習しようと声をかけられたので、いざPythonの環境を構築しようと頑張っていたら躓きました。

bashにもパスを通したいのに通ってくれない。。  
なんでだー。ってなったお話です。

#解決方法

- [AnacondaのPATHの設定](https://qiita.com/funabashi800/items/c13c4f742f43d9ebdd86)

ここを参考にすればだいたいおっけーのはずなのですが。。。

なぜか通らない。

```
$ conda -V
conda: command not found
```

を何回も見る羽目に笑

まず最初の課題はこれ。

```
bash: export　PATH=~/anaconda3/bin : No such file or directory
```

なんか見つからない。なんでだー。

よくわからんが、`""`でパスをくくってみる。

```
export　PATH="/Users/user_name/anaconda3/bin:$PATH"
```

そしたら、エラーしなくなりました。

vimのことよくわからないので誰かコメントで教えて下さい；

それからもう一回`source`コマンドを実行して追加したパスを反映させてみる。

```
$ conda -V
conda: command not found
```

なんでだーー。

解決方法 -> 深く悩む。

---終---

なんでやねん笑

もうちょっと調べると

- [python - Condaコマンドが見つかりません](https://tutorialmore.com/questions-1947319.htm)

>解決した方法 # 4
場合によっては、anacondaもインストールした後に端末を再起動しないと、このエラーが発生します。
>ターミナルウィンドウを閉じて再起動します。
>それは今私のために働いた！

とありました。

おかしいなーターミナル再起動したはずなんだけどなぁと思いながら、とりあえずPCを再起動笑

その結果、

```
$ conda -V
conda 4.7.12
```

感激。

詳しい原因は正直わかりませんが、一つの解決方法としてメモ残しておきます。
自作したrakeタスクをrailsが認識してないときに疑うこと

## 発生した問題

rake タスクを作成して実行しようとしたら、そんなタスク知らん（Don't know how to build task 'xxxxx'）と突っぱねられてしまいました。

```
$ bundle exec rails my_awesome_task
rails aborted!
Don't know how to build task 'my_awesome_task' (See the list of available tasks with `rails --tasks`)
```

確かに `rails --tasks` に挙がってない。

```
$ bundle exec rails --tasks | grep my_awesome_task
(該当なし)
```

なんとなく `rake -T` も試したけどやっぱり見つからない。

```
$ bundle exec rake -T | grep my_awesome_task
(該当なし)
```

以下がそのタスクです。

```lib/my_awesome_task.rb
desc 'すごいタスク'
task :my_awesome_task do
  puts 'すごいぞー \(^o^)/'
end
```

## チェック１：配置場所は正しいか？

`(Rails.root)/lib/tasks` 配下に置かないとダメでした。

```
修正前: lib/my_awesome_task.rb
           ↓
修正後: lib/tasks/my_awesome_task.rb
```

## チェック２：拡張子は正しいか？

Rakeタスクの拡張子は `.rake` じゃないとダメでした。

```
修正前: lib/tasks/my_awesome_task.rb
           ↓
修正後: lib/tasks/my_awesome_task.rake
```

この２つを直したら無事に動きました。

## ちなみに

タスクを作るときに `rails generate task` コマンドを使っていれば、こんな変なハマり方しなかったと思います。反省。

--

参考: [カスタムRakeタスク | Railsガイド](https://railsguides.jp/command_line.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0rake%E3%82%BF%E3%82%B9%E3%82%AF)
scpコマンドでEC2ストレージからファイルを取り出す

備忘録的に記述

# サーバー上でpwdを実行し、コピーしたいディレクトリまたはファイルを確認し、コピペ
```terminal
$ pwd
> /home/ubuntu/directory/to/folder
```

# ローカルに戻り、scpをssh接続しながら実行する
```terminal
$ pwd
> ペーストしたいディレクトリの確認、今回はデスクトップにコピペ
> /Users/username/desktop

$ scp -i ~/.ssh/filename.pem -r ubuntu@x.xxx.xxx.x:/home/ubuntu/directory/to/folder /Users/username/desktop
```

# ローカルのディレクトリと、ubuntu@以下の部分を逆にして書くと、ローカルのフォルダがサーバーにアップされてしまうため、注意！！！！
【cakephp】FormHelperのlinkメソッド

#linkメソッド

HtmlHelperのlinkメソッドは、アクションを実行したときに指定したURLへ移動するための機能

- 書き方

```php
$this->Html->link('タイトル', $URL, $オプション);
$this->Html->link('タイトル', ['controller' => 'コントローラ名', 'action' => 'アクション名', 引数1, $クエリ文字列オプション]);
```

- 具体例

```php
$this->Html->link( $this->Html->image('画像', array("alt" => '代替テキスト', 'width'=>'n', 'height'=>'n')), 'javascript:window.close()', array('escape'=>false));
```


これを実行すると画像が表示、クリックすると第二引数のjavascript:window.close()が実行されwindowを閉じることができる

javascript:という書き方ですが自分も初めて知ったので今度記事にします
簡単に説明するとjavascriptをリンクのように扱える書き方です

第三引数の'escape'=>falseはhtmlの特殊文字を変換しないようにしてます

以下のhtmlが作成されます

```html
<a href="javascript:window.close()">
 <img src="画像" alt="代替テキスト" width="n" height="n">
</a>
```
参考にしたサイト
[【CakePHP入門】linkメソッドの使い方(HtmlHelper)](https://www.sejuku.net/blog/27174)
[cookbook](https://book.cakephp.org/3/ja/views/helpers/html.html)
ActiveRecord::PendingMigrationErrorの解決方法

# 1.エラーメッセージの内容
下記のようなエラーの場合の解決方法を記載します
<img width="1267" alt="スクリーンショット 2020-02-19 7.45.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/779afd29-8b3f-be4a-3116-cf94b034da2d.png">

# 2.エラーの原因
エラーの理由はmigrateし忘れてますよというものです。
考えられる理由は下記の3つです

１.単純にrails db:createのあとrails db:migrateし忘れている
２.すでにmigrationが完了している(up)状態でマイグレーションファイルを更新しrails db:migrateしてしまった
３.マイグレーションファイルの中に入れた外部参照キーが参照するテーブルがない状態でrails db:creatしてしまった（マイグレーションファイルの記述に誤りがある）


# 3.エラーの解決方法
#### 1.単純にrails db:createのあとrails db:migrateし忘れている

マイグレーション実行の下記のコマンドを打ち込みましょう

```
$ rails db:migrate
```

#### 2.すでにmigrationが完了している(up)状態でマイグレーションファイルを更新しrails db:migrateしてしまった

方法１ 既存のテーブルを全削除し、再度マイグレーションの状態をupにする下記のコマンドを打ち込みましょう

```
$ rails db:migrate:reset
```

方法２ マイグレーションの最新のものだけ実行を取りやめて編集可能(down)にするコマンドrails db:rollbackののち、マイグレーションファイルの更新コマンドrails db:migrateを打ちましょう

```
$ rails db:rollback
$ rails db:migrate
```

※方法１と方法２の違いは処理速度（工程）の量の違いです。テーブルの数が多い場合は方法２としましょう。テーブルが数十程度なら方法１でも２でも大差はありません

※マイグレーションの状態を調べるコマンドは下記の通りです

```
$ rails db:migrate:status
```


#### 3.マイグレーションファイルの中に入れた外部参照キーが参照するテーブルがない状態でrails db:creatしてしまった

①-1外部参照されるマイグレーションファイルを作成し、app/modelの中のファイルにアソシエーションを追記（または修正）する
①-2マイグレーションファイルから不必要な外部参照キーを消す

②上記①のどちらかの修正のあとに下記コマンドを打ち込みましょう

```
$ rails db:migrate:reset
```

# 4.すでにデータベースにレコードを入れてしまい、それを残したまま修正する方法（補足）
新たに追加したい項目のテーブルを作成し、本来追加したかったテーブルのidを外部キーとする方法をとりましょう。

参考（railsガイド）：　https://railsguides.jp/active_record_migrations.html#%E6%97%A2%E5%AD%98%E3%81%AE%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B
dbpediaの研究 その32


#概要

dbpediaが難解なので、手出してみる。
im@sparqlのquery editor作ってみた。

#サンプルコード


```
PREFIX schema: <http://schema.org/>
PREFIX imas: <https://sparql.crssnky.xyz/imasrdf/URIs/imas-schema.ttl#>

SELECT DISTINCT ?o ?bust
WHERE {
	?s schema:name | schema:alternateName ?o;
	imas:Bust ?bust.
	FILTER (LANG(?o) = 'ja')
}
order by desc(?bust)

```

#成果物

http://embed.plnkr.co/G9VjiyQLkV3Grhz9ztld/

以上。
傾けた要素の周囲に付く細い線の消し方

# はじめに
CSS で吹き出しなどを作成する際に疑似要素などを用いて矢印を作成したりしますが、そのとき少し悩まされた現象があったので備忘録として。。

# 現象
傾きのある要素を別の要素に重ねると、傾きのある要素の周囲に細い線が見える。
よく見ないと気付かないのですが、`outline` でも `box-shadow` でもない何かが表示されてしまっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284587/ffb25a7c-70b7-bc52-400e-15fb1eb75c35.png)

# 解決方法
傾きのある要素に `backface-visibility: hidden;` を適用する。

[backface-visibility](https://developer.mozilla.org/ja/docs/Web/CSS/backface-visibility)

## 再現したコード
疑似要素の `backface-visibility` を切り替えてみると、適用前は疑似要素の周りがギザギザ？になっているのが分かります。
https://jsfiddle.net/yshrkn/9m17qL6a/


# さいごに
普段使用しないプロパティだったので30分ほどハマりました。
FlutterでDrawerのアイコンをカスタマイズする

## はじめに
Flutterで、例えばアイコンの下に文字を入れるなど、Drawerのアイコンをカスタマイズしたいときがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/8630fa1a-deac-21ff-d8bb-c18390c7f992.png)

こうしたときは、次のようにScaffoldStateを使うことで、カスタマイズできます。(ここでは、右側にボタンを配置するendDrawerで解説しています)

## 実装

```dart
class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
  }

  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

@override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        actions: <Widget>[
          // カスタムしたボタン
          InkWell(
            onTap: () => _scaffoldKey.currentState.openEndDrawer(),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Icon(Icons.menu),
                const Text(
                  'メニュー',
                  style: TextStyle(
                    fontSize: 14,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
      endDrawer: Drawer(),
    );
  }
}
```

ScaffoldにGlobalKeyを指定して、Scaffoldの状態を保持しているScaffoldStateを参照できるようにします。
Scaffoldのactionsにボタンを作成し、 タップ時に `_scaffoldKey.currentState.openEndDrawer()` でドロワーを開けるようにします。
こうすると、本来endDrawerにDrawerを指定すると生成されるボタンが生成されず、代わりにactionsで生成したボタンを通じてドロワーを開けるようになります。

## 参考
[Flutter Custom Drawer Icon (use keys) · GitHub](https://gist.github.com/kleinlennart/3e07133274ae8ac2d1187855ce2c7e51)
git-svnでSVNをgitで開発できるようにしてみた

# SVNが使いにくい・・・
現在、お仕事でSVNを使用しているのですがgitに比べるとやはり使いにくい。
特にローカルコミットができずに変更点をそのまま抱えておくのがすごく面倒くさいです。
というより1回間違ったファイルをコミットして嫌気が差したのでgit化できないかと調べてみたらたくさん出てきました。

というわけでやってみます。

# Gitリポジトリを作る
Gitリポジトリ用のディレクトリを作成した後、SVNリポジトリからGitリポジトリを作ります。

```
git svn init -s --prefix=svn/ http://hogehoge.com/svn
git svn fetch
```

リビジョンが多いと数時間はかかるので時間がある時や放置できそうなタイミングでやるのが良いと思います。
僕の環境では何も起きずに終わりましたがエラーが発生したらリビジョンを指定して`fetch`するのが必要になるみたいです。
正直ここまで出来たらほぼ終わったようなものです。

# ブランチを切る
この辺から通常のgit操作とほとんど変わらないです（コマンドが若干違うくらい）。
GitリポジトリのmasterブランチがSVNのtrunkになります。

```txt:masterからbranch作成
git checkout master
git branch hogehoge
git checkout hogehoge
```

# SVNリポジトリの変更を取り込む
masterブランチにSVNの変更点を取り込む場合、`svn rebase`をします（gitにおける`pull`みたいな感じ）。

```
git checkout master
git svn rebase
```

この時、ローカルに変更点があると次のエラーログが出ます。
> update-index –refresh: command returned error: 1

この状態になったら`stash`か`reset`してから`svn rebase`しましょう。

切ったブランチにmasterブランチの変更を適応したい場合は`marge`します。

```
git checkout master
git svn rebase
git checkout hogehoge
git marge master
```

# SVNリポジトリにコミットする
masterブランチに`commit`後、`svn dcommit`でSVNリポジトリにコミットすることができます（gitにおける`push`みたいな感じ）。
SVNリポジトリには「gitからコミットされた」みたいな余計な情報は付加されないので素直にコミットして大丈夫です。

```
git commit -m "こみっとこめんと"
git svn dcommit
```

# おしまい
これでSVNリポジトリをgit環境で開発することができます。やはりローカルブランチを切れるのは良い！
普段はVSCodeで開発をしており、GitLensをずっと使いたいと思っていたのでこれから捗りそうです。
構築にちょっと時間はかかりますが「SVNがヤダ！」って言う人はやってみる価値はあると思います。

何かあったらコメントください。

# 参考
[interprism's blog 現場がSubversionでつらい貴方へ…自分だけこっそりGitで開発する方法][1]
[のぶろぐ git-svnを使った開発の手順][2]
[Qiita:git-svnでSVN→Gitへの移行をやってみたログ][3]

[1]:http://interprism.hatenablog.com/entry/git-svn
[2]:https://nob-log.info/2011/12/26/gitsvn/
[3]:https://qiita.com/hidekuro/items/4727715fbda8f10b6b11
無料Python実行環境Google Colaboratoryメモ

# Google Colaboratoryとは
Googleのクラウドで実行される Jupyter ノートブック環境。
https://colab.research.google.com/notebooks/welcome.ipynb

無料で利用可能、環境構築不要であるため、Pythonの勉強などに便利です。

また、GPUやTPUの利用も可能で機械学習の実行時間も削減できます。

# 利用制限
無料で利用可能ですが、連続利用時間に12時間の制限があります。

12時間を過ぎると仮想マシンが切断されるため、機械学習で長時間利用する場合は注意が必要です。

また、アイドルタイムアウト時間放置した場合も仮想マシンが切断されます。

※アイドルタイムアウトの時間はFAQに記載されていませんが、現在は90分のようです
https://research.google.com/colaboratory/faq.html

# メモ
以下、利用メモ。

## GPU/TPUの利用
ランタイム > ランタイムのタイプを変更　から選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361616/1a32bf4f-29a6-1fcf-da79-b20c0f31f5d6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361616/ea9f7afc-1e0a-8d97-e3ef-38f7bd765630.png)

## Googole Driveのマウント
サイドメニューの「ドライブをマウント」を選択すると、マウントするためのコードが自動で生成されるので実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361616/710f511a-e999-127f-e366-c505a99cd56d.png)

## TensorFlowのバージョン変更
現在デフォルトは1.x系。以下を実行すると2.x系に変更できる。

```
%tensorflow_version 2.x
```
※試す際はTensorFlowのチュートリアル（ https://www.tensorflow.org/tutorials ）の各ページにある「Run in Google Colab」を開くと、2.x系に変更して動かすコードで記載されています。

以上
AWS セッションマネージャでSSH接続する際、認識しやすい名称で接続したい

※環境はMac前提

AWS環境のサーバ（EC2インスタンス）に接続する際
セキュリティを考慮して セッションマネージャーでトンネルしてSSHしているケースあるかと思います。

Cf： [AWS Systems Manager セッションマネージャーでSSH・SCPできるようになりました ｜ Developers\.IO](https://dev.classmethod.jp/cloud/aws/session-manager-launches-tunneling-support-for-ssh-and-scp/)

ただ、 `ssh ＜インスタンスID＞` って、historyみたときに、あれ？このサーバなんだっけってなりますよね？

いつもどおり `ssh production-server` とかしたいわけで。その方法。

`~/.ssh/config` を以下のように設定。

```
Host awesome.production
    HostName i-0xxxxxxxxxxxxxxxx    # <- ここにインスタンスID入れる
# 以下、必要な数だけ 同じプリフィックスつけて HostNameを定義する

Host awesome.* 
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

これで `ssh awesome.production` で接続できます。

## ホスト名を動的に解決したい

ただ、上の方法だと、EC2インスタンスが増減したときに `~/.ssh/config` を
手動でメンテしなければならず、すこぶる面倒ですよね。

EC2のNameタグを利用してアクセスできるようにするには、以下のように ProxyCommand で少し頑張ってみる。

※ EC2のNameタグに設定する名前には、ピリオド「.」が入っていない前提。そうでない場合は `$(echo %h | cut -d. -f2)` の箇所をよしなに修正してください
※ Mac Catalina バージョン10.15.3, シェルはzshで確認 

```
ProxyCommand $(EC2HOST=$(echo %h | cut -d. -f2);INSTANCEID=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$EC2HOST" --query "Reservations[*].Instances[*].[InstanceId]" --output text);echo aws ssm start-session --target $INSTANCEID --document-name AWS-StartSSHSession --parameters 'portNumber=%p')
```

## DBクライアントソフトの対応

MySQLWorkbenchや DataGrip など、DBクライアントソフトでSSHトンネルする場合
`~/.ssh/config` を考慮してくれるようなのですが（ProxyCommandも考慮してくれる）
ProxyCommand 内のコマンド展開 `$(echo %h | cut -d. -f2)` などは考慮してくれないようです。
また、`~/.ssh/config` は Includeキーワードで別ファイルを読めるのですが、これも考慮してくれないようです。
なので、DBクライアントのトンネリングには、踏み台となる特定インスタンスを `~/.ssh/config` に定義しておくしかなさそうです。

```
Host bastion
    HostName i-01xxxxxxxxxxxxxxx    # <- bastionのインスタンスID
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```
で、DBクライアントソフトのSSHホスト名を上で定義した「bastion」にすればOK。

※ DBクライアントによっては、session-manager-plugin をデフォルトでインストールしたときのパス `/usr/local/bin` が 環境変数 PATH に入って無くて読めないことがあるもよう。
その場合は、ProxyCommand にて PATHを設定するとうまくいく。

```
ProxyCommand sh -c "env PATH=/usr/local/bin:$PATH aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```


※ すべてのDBクライアントソフトを動作検証したわけではないので、これで繋がらない場合は
  先に記述したDeveloper.IOの記事にあるポートフォワードを試してみてください。
[Linux]自分のIPを変数に入れる方法

#概要
シェルスクリプト内などで、自分のIPを変数に入れたい場合のTips
IPv4のみ対応です。

##環境
```bash
$ cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
```
#
```bash
$ ip a|grep -e inet |grep -v inet6
    inet 127.0.0.1/8 scope host lo
    inet 192.168.1.1/24 brd 192.168.1.255 scope global dynamic eth0
    inet 192.168.2.1/24 brd 192.168.2.255 scope global dynamic eth1
$ hostname -i #eth0のみ表示
192.168.1.1
$ hostname -I #loを除く全てを表示
192.168.1.1 192.168.2.1
```

##コマンド
```bash
#一番シンプルな方法
$ MyIP=`hostname -i` 
$ echo $MyIP 
192.168.1.1

#IPが複数ある場合
$ MyIPeth0=`hostname -I | cut -f1 -d' '`
$ echo $MyIPeth0 
192.168.1.1
$ MyIPeth1=`hostname -I | cut -f2 -d' '`
$ echo $MyIPeth1
192.168.2.1

```
##コマンド2
hostnameコマンドは危険だから使うなって言われた場合はこちら

```bash
$ MyIPeth0=`ip -f inet -o addr show eth0|cut -d\  -f 7 | cut -d/ -f 1`
$ echo $MyIPeth0
192.168.1.1

$ MyIPeth1=`ip -f inet -o addr show eth1|cut -d\  -f 7 | cut -d/ -f 1`
$ echo $MyIPeth1
192.168.2.1
```

##補足
rootでhostnameコマンド実行時、'hostname -i'とするところを'hostname i'とすると
ホスト名がiになるので注意。

```terminal
$ hostname
hogehoge
$ hostname i
hostname: you must be root to change the host name

$ sudo su -
#

# hostname i
# hostname
i

# MyIPeth0=`hostname I | cut -f1 -d' '` 
# hostname
I
```

以上
【新米web制作者向け】webの勉強ってどうやってる？

会社の社内ブログに書いていた記事ですが、後輩に今でも参考にしてます！と言われるのでこちらにも記載します。

---

現在私は、チームの中では数少ないデザイナーとコーダーの中間みたいな立ち位置にいます。
勉強大変だよね。どうやってる？って声がたびたびあがるので記載します。

# 情報収集
私はslackをRSSリーダー代わりに使ってます。Chatworkでもできるようです。
ぼっちslackワークスペースを作って、そこに情報を流しています。
![1000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165868/f8de5157-4ade-56fb-dbfb-8406de18b0e8.png)

**やりかたはこちら**
Slack に RSS フィードを追加する
https://slack.com/intl/ja-jp/help/articles/218688467-Add-RSS-feeds-to-Slack
ChatworkにRSSの新着を通知する
https://qiita.com/yujiroarai/items/b831bec609707966c625

こういう普段使うツールに組み込ませて、**絶対に見る環境を作る**ことが大事だなと思います。
正直中身は全部見ていません。単語一つ覚えたり動向知ることができればそれでおっけー！

# SNS,Qiitaなどの情報サイト
回し者ではありません(笑)
それ用のアカウントやリストを作ってこちらも閲覧しています。
具体的な技術というよりは、流行を知る目的の方が大きいです。
コーダー・エンジニアは、Qiita, CodePenあたりは書くことがなくてもアカウントは持っていた方がいいです。**良い記事をストックするため**です。

# 良いサイトのストック
ギャラリーサイトは仕事の合間に適宜徘徊しています。
その時もダラダラ見ずに、良いサイトはEvernoteにストックするようにしています。
ここで大事なのは、タグでもコメントでもいいから、**なぜいいと思ったのか必ず記載する**ことだと思います。
後で見返して検索しやすくするためです。


# 勉強会
外部セミナーも参加しています。
ただあまり行きすぎちゃうと疲れるので、私は数か月に一回ペースにしています。
こういう勉強会は内容を学習するのももちろんですが、**業界や他の会社の動向を知ることができたり、参加者とのコミュニケーションをとることができること**が大きいなと感じます。

# なんでもいいから手を動かす
コーディングやプログラミングは書かなきゃ身につかない。でもネタがない！
そんなときは**学びたいことと好きなことを無理やり合わせて作ればいい**です！
楽しく学べれば最強じゃない？
~~私はふざけるのが好きなので~~内容はふざけて、技術はしっかりやったりしています。
デザイナーの同僚には「[技術の無駄遣い](https://codepen.io/seahorse-design/pen/JjoNpLj)」と言われました。

そしてそういうネタは思いついたらTodoistに溜めるようにしています。
実現可能か否かは置いておいて書き溜めておきます。
すぐに出来なくても未来の自分ができるかもしれません。
内容も自分がわかれば良い、雑でおっけーです。
![200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165868/c00c0351-32b5-0d8d-806e-5cf10a29f1c2.png)

---
これは私なりのやり方ですが、もちろんこれが正解ではなく**自分に合う方法を見つける**のが大事ですね。
何かの参考になればと思い記載しました！
どっかの入試問題の数学が考えるのがめんどくさくて結局pythonに任せた話

#はじめに
どっかの入試問題の数学の確率を解けと言われて、考えたくなくなって、pythonに任せたら一瞬だった話

#問題
1から20までの整数が書かれたカードが20枚のカードがある。17枚のカードを同時に取り出したカードの数字の和が3の倍数になる確率を求めよ。

#解決法
手で解こうとすると、組み合わせ考えて、、、3枚のカードが3のばいすうになればいいから、、、あぁめんどくさい、全部出してプログラムで書こう、、、

#コード
pythonで書きました。処理速度とかどうでもいいくらいの短さなので、for文使いまくり。

```python
import numpy as np
import random

calculuse = []
result = []
for i in range(1, 20):
    for k in range (i+1, 21):
        for l in range(k+1, 21):
            a = i+k+l
            print('(i, k, l) =',i,(','),k,(','),l,('sum='),i+k+l) 
            array = a
            calculuse.append(array)
            if a%3 == 0:
                print('true')
            else:
                print('false')
            arr = [a, a%3==0]
            if a%3 ==0:
               result.append(arr)
print(len(result)) 
print(len(calculuse)) 
```

これだけで、完了！

```terminal
(i, k, l) = 1 , 2 , 3 sum= 6
true
(i, k, l) = 1 , 2 , 4 sum= 7
false
(i, k, l) = 1 , 2 , 5 sum= 8
false
(i, k, l) = 1 , 2 , 6 sum= 9
true
(i, k, l) = 1 , 2 , 7 sum= 10
false
(i, k, l) = 1 , 2 , 8 sum= 11
false
(i, k, l) = 1 , 2 , 9 sum= 12
true
(i, k, l) = 1 , 2 , 10 sum= 13
false
(i, k, l) = 1 , 2 , 11 sum= 14
false
(i, k, l) = 1 , 2 , 12 sum= 15
true
(i, k, l) = 1 , 2 , 13 sum= 16
false
(i, k, l) = 1 , 2 , 14 sum= 17
false
(i, k, l) = 1 , 2 , 15 sum= 18
true
(i, k, l) = 1 , 2 , 16 sum= 19
false
(i, k, l) = 1 , 2 , 17 sum= 20
false
(i, k, l) = 1 , 2 , 18 sum= 21
:
:
:
:
384
1140
```

ということで、答えは
384/1140
になります！
って友達に出したら考えを知りたいんだがといわれた話。
HTML5 type="reset"はあくまでリセットするボタンだった

HTML5で`type="reset"`が利用できるようになり、JavaScript書く必要なくなると思っていたのですが、
リセットボタンはあくまで初期状態にリセットするボタンなんですね。
どうゆうことかというと、僕は勝手にフォームを、まっさらな何も選択(入力)されていない状態に戻してくれると思っていました。

```html
<input type="reset" value="リセット">
```

例えば、初期状態では何も選択(入力)されていない場合、
項目選択後に、リセットボタンを押すと、何も選択されていない状態に戻ります。
これは思っていた通り。

◻︎選択肢A ◻︎選択肢B

↓ポチポチ

☑︎選択肢A ◻︎選択肢B

↓リセット

◻︎選択肢A ◻︎選択肢B


しかし、初期状態で何かしら選択されている状態で、
状態を変更し、リセットすると、まっさらな状態になるのではなく、
最初の選択状態に戻ります。ワオ

☑︎選択肢A ◻︎選択肢B

↓ポチポチ

◻︎選択肢A ☑︎選択肢B

↓リセット

🙆‍♂️☑︎選択肢A ◻︎選択肢B
🙅‍♂️◻︎選択肢A ◻︎選択肢B

気をつけます。
Python 3 エンジニア認定基礎試験の合格と勉強法

# 概要
受験しました。

https://www.pythonic-exam.com/exam/basic

以下、上記リンクの抜粋

> ◆受験方法
受験日：通年
試験センター：全国のオデッセイコミュニケーションズCBTテストセンター
申込URL：http://cbt.odyssey-com.co.jp/pythonic-exam.html
受験料金：1万円（税別）　学割5千円（税別）
※申込み方法や受験方法に疑問がある場合は、オデッセイコミュニケーションズへ直接お問い合わせください。
※試験内容については公平を期すためにご質問へは一切回答致しません。

> ◆試験概要
試験名：Python3 エンジニア認定基礎試験
（英名：Python 3 Certified Engineer Basic Examination）
資格名：Python3 エンジニア認定基礎試験合格者
（英名：Python 3 Basic Grammar Certification）
概要：文法基礎を問う試験
問題数：40問（すべて選択問題）
試験時間：60分
合格ライン：正答率70％
出題範囲：主教材であるオライリー・ジャパン「Pythonチュートリアル 第3版」の掲載内容を出題範囲として、以下の比率で出題いたします。また、一般的な知識からも出題されます。
認定教材：こちらをご覧ください。
認定スクール：こちらをご覧ください。

# 勉強法
自分は、シェルスクリプトがかける程度で、Pythonは書いた経験なし、勉強用にjupyterの操作はできる程度。
試験範囲は、「Pythonチュートリアル 第3版」なものの、この本をひたすら読むのは退屈で勉強しづらいと感じた。
先行して合格した後輩からは下記の模擬試験をおすすめされた。また、無料の講座もある。
https://exam.diveintocode.jp/exam

1.上記リンクの無料講座で文法に慣れる
　jupyter環境を用意して、無料講座のコマンドを一通り試しました。
　
2.上記リンクの模擬試験を受ける＆「Pythonチュートリアル 第3版」を読むを繰り返す
　上記リンクの模擬試験を受ける。スマホで受けれる感じなので通勤中に勉強できた。
　「Pythonチュートリアル 第3版」は斜め読みで２〜３回読んで、後は模擬試験の問題の見直しで読む。


# 合格
７５０点で合格。余裕ではなかった。
模擬試験を繰り返して、ほぼ満点が取れて、解答の理由が分かるレベルなら、余裕ではないけど、合格点の７００点は安定して越えられるという印象でした。