OmniAICreator/Qiita-1.07M huggingface dataset:
【Spring】Model, ModelAndView, ModelMapの違い


■やりたいこと
  ModelAndView, Model, ModelMapの違いについて知りたい。
  
■各オブジェクトについて
ModelMap
・LinkedHashMap<String, Object>である。

ModelAndView
・ViewとModelを両方追加できる。
・addObjectをすると内部で保持するModelMapに追加される。
・addAttribute

ExtendedModelMap (Model)
・Modelインターフェースを実現している。
・ModelMapを継承している。
・ハンドラの引数はこれをさらに継承した「BindingAwareModelMap」である。

■構造
　　BindingAwareModelMap
　　　┗　ExtendedModelMap
　　　　┗ModelMap, Mode

　　ModelAndView
　　　┗ModelMap

---
①インプット情報(Form)が「model」にセットされるのか。
②チェック結果情報(BindingResult)が「model」にセットされるのか。

```java:Test.java

	@PostMapping("entry1")
	public String entry1(Model model, @Validated TestForm form, BindingResult result) {
		return "output";
	}

	@PostMapping("entry2")
	public String entry2(ModelMap model, @Validated TestForm form, BindingResult result) {
		return "output";
	}

	@PostMapping("entry3")
	public String entry3(ModelAndView model, @Validated TestForm form, BindingResult result) {
		return "output";
	}
```
①，②の結果
 Model    : される。 
 ModelMap : される。
 ModelAndView : されない(ModelMapがNull)。

---
③@ModelAttributeのオブジェクトは「model」にセットされるのか。

```java:Test.java

	@ModelAttribute
	public EchoForm getForm() {
		return new EchoForm();
	}
	@GetMapping("show1")
	public String show1(Model model) {
		return "input";
	}
	@GetMapping("show2")
	public String show2(ModelMap model) {
		return "input";
	}
	@GetMapping("show3")
	public String show3(ModelAndView model) {
		return "input";
	}
```

③の結果
 Model    : される。 
 ModelMap : される。
 ModelAndView : されない。(ModelMapがNULL)

---
④セッション情報はModelにセットされるのか。
 (SessionBeanをDIした場合)

これについては勘違いしていた。
@ModelAttributeを使用する場合はModelにセッション情報をセットする必要があったが、
@SessionScopeの場合、それは必要なく、直接
コントローラクラスのフィールドにDIされたオブジェクトを操作すればよいのだ。
よってセッションBeanはModelには設定されない。

---
■まとめ
・ModelAndView - Modelのデータを保持する。
・Model        - Modelのふるまいを定義する。
・ModelMap     - Modelのデータ自身である。
　⇒ 細かいことを抜きにすれば、いずれもデータは「ModelMap」型で保持している。
【Rails勉強ネタ】　destroyアクションもPOSTメソッドを送信してる??

前回updateアクションの時、送信されているhtmlリクエストが`POST`だったのを確認したので、
destroyアクションではどうなのか確認してみた。

#実際に確認
Noticeというモデルがあるとする。
indexページから
①`button_to`で削除する場合と
②`link_to`で削除する
パターンを見たいので以下のような見た目になった
↓（左が削除ボタン、右が削除リンク）
<img width="973" alt="スクリーンショット 2019-04-14 1.31.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/c2b90b07-8cc2-1c7c-e4c0-bb554b19904d.png">


###view テンプレート
```index.html.erb
・
・
<% @notices.each do |notice| %>
  <tr>
　　〜〜〜略〜〜〜
    <td><%= button_to "削除", notice_path(notice),
                                           class: 'btn',
                                           method: :delete %>
    </td>
    <td>
      <%= link_to "削除", notice_path(notice), method: :delete %>
    </td>
  </tr>
<% end %>
・
・
```

###HTML
`右クリック→ページのソースを表示`で見てみると。


```
①削除ボタン
<td><form class="button_to" method="post" action="/notices/14">
  <input type="hidden" name="_method" value="delete" /><input class="btn" type="submit" value="削除" /><input type="hidden" name="authenticity_token" value="bvoKobmo3Zvj6jysAJAmuxv49+WX+EqiG+bBSqWibDm9+lc44shUlU3mAau9H6WGR5z7rucUmICmobTOplLT0w==" /></form>
</td>
```

```
②削除リンク
<td>
  <a rel="nofollow" data-method="delete" href="/notices/14">削除</a>
</td>
```

①削除ボタンは[update](https://qiita.com/yusaku_/items/54479e5744cd7af31f89)の時と同様、**`mothod="post"`**であるが、`_method`パラメータで**delete**を指定している。


②削除リンクは `data-method="delete"`という属性だけ付与されている。

#Wiresharkでキャプチャー
リアルなhttpパケットを見てみます。

###①削除ボタン
<img width="1341" alt="スクリーンショット 2019-04-14 1.58.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/d00935f8-085e-1585-b417-7d4ffd659388.png">

こちらも[update](https://qiita.com/yusaku_/items/54479e5744cd7af31f89)の時と同様、実際に送信しているhttpリクエストは**`POST`**メソッドだが、`Form item: "_method" = "delete"`となっている。

###②削除リンク

<img width="1345" alt="スクリーンショット 2019-04-14 2.06.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/eba785c0-1b07-3b98-ca45-56a9473e7c5d.png">

こちらも①のパターンと全く同じように見える。
つまり**`data-method="delete"`**属性だけで`_method`パラメーターが使えるようである。

#疑問に思ったこと
最終的なhttpリクエストの振る舞いが同じになるのであれば、①も`data-method="delete"`属性だけにすれば良いのではないのか？
FM RADIO — RADIOLY [CURRENT VERSION 2.6]

RadioLY — Live FM Radio brings you the best of the World Live Broadcast FM & AM stations

RadioLy is an excellent and hassle free way to listen to the online fm radio, AM radio and perhaps free internt radio stations.


We have a pool of over 35,000+ live fm radio stations which you can sit back and listen at the comfort of your home and office. RadioLy is one of the free radio app that give you the benefit to listen to fm radio stations from any given geographic location of the world.

It is quite easy to find any fm radio station through RadioLy App. It is quite easy to search through the genre such as news radio, sports radio, rock radio stations, pop radio stations to name a few. You can also search it by the country of your choice. Our aim is to simplify the radio listening experience to our users on the different mobile and web devices.

★★Why Install RadioLY — LIVE FM Radio ★★

★Clean User Interface

RadioLy offers a very clean and easy to navigate user interface and thus help you out in tuning FM radio and local radio. There is a lot of am & fm radio app that are too complex to operate while playing a radio station. With RadioLy, it will help you out to sort out all the above problems.

★No Interruptions or Buffering

RadioLy is serving more than 1 million listeners in a month. Our app helps you to offer great level of reliability and stability which helps us to stand out from the rest of the crowd. That is why we are trying to improve my radio listening quality as much as we can through our app.

★One Tap Access to Your Favorite Channel

With our application, you can easily navigate to the favorite channel of your choice in a quite fast and hassle free way. We are improving our app on a regular basis such that you can have a very smooth experience while you are using our radio station at home, office or in your car.

★★ Our App Features ★★

1. Classic design to display the stations listing
2. Add to Favorites
3. Featured list
4. Countries list (Select country and listen the Radio Station)
5. Search your favorite radio station or genre.
6. Share what you are listening to on Facebook, Twitter, G+ and Tumbler.

More features coming soon.

So, if you are having any kind of questions, then do get in touch with as at support@radioLy.app and one of the our representatives will reach out to you in a span of 24 hours.

If any one want to remove copyright radio station send mail at copyright@radioLy.app.

If any radio broadcaster want to add radio station at RadioLy — Live FM Radio app mail us support@radioLy.app

Thanks

★ RADIOLY — Live FM Radio ★

WHAT’S NEW
Add Sleep Timer Feature
Add Volume Feature In Full Player
Fix Bugs
Keep Listening Live Fm Radio — Radioly

ADDITIONAL INFORMATION
Updated — April 12, 2019

Size — 6.4M

Installs — 5,000+

Current Version — 2.4

Requires Android — 4.1 and up

Content Rating — Rated for 3+

Offered By — RadioLy

Developer — Visit website

support@radioly.app

Privacy Policy

Visit Here TO Download RadioLY App — https://play.google.com/store/apps/details?id=com.onlineradio.radiofm&hl=en_US
python仮装環境でbatファイル作るとき

## python仮装環境でbatファイル
Windows上にて、python仮装環境を利用してdjangoを構築した時、普通にactivateしようとしたところ、上手くいきませんでした。

```
Scripts\activate
```

## 解決策
この場合、callコマンドを前につける。

```
call Scripts\activate
```

よく気づいてなかったですが、activateコマンド自体もbatファイルとして用意されている様でして、
batファイルからbatファイルを呼ぶということになり、そのいった時はcallコマンドが必要となるみたいです。

## django起動するbat

```
cd c:\python\env1

call Scripts\activate.bat

cd django_sample

python manage.py runserver

pause

```

この内容のbatファイルをスタートアップフォルダに置けば、windows再起動時、
よしなにしてくれます。
![スクリーンショット 2019-04-14 2.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168441/1b84de42-a381-7c7c-e659-222e221c1bd0.png)

ちなみに、windows serverなどスタートアップフォルダ分かりづらい時は、
以下のコマンドで、

```
shell:Common Startup
```
![スクリーンショット 2019-04-14 2.13.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168441/9d1c4c79-7072-d1c2-57f3-3c21680512f5.png)

![スクリーンショット 2019-04-14 2.13.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168441/e99e86ba-c413-7006-0077-9782b2613526.png)
Raspberry Pi Zero W で Google Homeに喋らせる

普段はGHKitを使ってGoogle Homeへのプッシュを行っているのですが、先日、Raspberry Pi Zero Wを手に入れたので、以下の記事を参考に自前で作ってみようと思い立ちました。

が、結構躓いたので、自分への覚書としてまとめておきます。

- Google Homeを手軽に喋らせる仕組み(google-home-voicetext)を作った（Dockerにも対応）<br />https://qiita.com/sikkim/items/f03df7e2db13ea7f5a2b

# 使ったもの

- Raspberry Pi Zero W 
- raspbian strech 2018-11-13

# 躓いたこと

## api-server.jsが起動後、リクエストを受けると落ちる

いろいろ試していたので詳細はもう覚えてませんが、リクエストを受けると、ライブラリが見つからない、というエラーで落ちてしまいました。そのライブラリがインストールされているにもかかわらず、です。

原因がわからなかったのですが、nodeとnpmはraspbianのパッケージは使わずに、nodebrewで、node-8.11.4＆npm-5.6.0をインストールしてそっちでnpm installしなおしました。

## docker-composeがビルドできない

以下を参考に試してみたのですが、docker buildでコケる。いろいろ試してみたのだけど、どうしても解決できず。環境依存な感じもするし、本来の目的とは違うのでここに時間もかけてられない、ということで、諦めて手動で構築しました。

- Raspberry Pi用docker-composeの構築<br />https://qiita.com/tkyonezu/items/ceaaf41924df39254058

## firestore.jsが起動しない

illigal instructionとなって起動しませんでした。以下を参考にgrpcをnpm rebuildすることで解決しました。

- Raspberry Pi Zero Wのセットアップ<br />https://qiita.com/Satoshi_Takahama/items/02ae9b0eb9bc25f7f11e

# 感想

Raspberry Pi Zero W って、Raspberry Pi 3が単に小さくなっただけのものでしょ？ぐらいに思っていたので、こんなに躓くとは思ってませんでした。環境的にそもそも違うってことですね（当たり前）。まあとりあえず動いたので良しとします、VoiceTextの声も自然でいい感じです。
東大理IIIは本当に男子の合格率が高いのか？

# TL;DR

- 東大の理科3類の男子と女子の合格率の間に統計的に有意（p<0.05）な差はない。
- 鳥取大，島根大医学部の男女の合格率の間にも統計的に有意な差はない。

# 背景
https://www.u-tokyo.ac.jp/ja/about/president/b_message31_03.html

最近，上野千鶴子氏の東大での式辞が話題になっていて，その中に，以下のような一節があった。

> 文科省が全国81の医科大・医学部の全数調査を実施したところ、女子学生の入りにくさ、すなわち女子学生の合格率に対する男子学生の合格率は平均1.2倍と出ました。問題の東医大は1.29、最高が順天堂大の1.67、上位には昭和大、日本大、慶応大などの私学が並んでいます。1.0よりも低い、すなわち女子学生の方が入りやすい大学には鳥取大、島根大、徳島大、弘前大などの地方国立大医学部が並んでいます。ちなみに東京大学理科3類は1.03、平均よりは低いですが1.0よりは高い、この数字をどう読み解けばよいでしょうか。統計は大事です、それをもとに考察が成り立つのですから。

合格率の比が1.03というのは，東大理IIIは定員が少ないことを考えると，誤差の範囲内じゃないか？と直感的に疑念を持ったのがきっかけで，具体的に調べてみた。

# データ

文部科学省が2018年にまとめた以下のデータ（2013〜2018年度分）を使用。
http://www.gender.go.jp/kaigi/senmon/jyuuten_houshin/sidai/pdf/jyu17-15.pdf

コピペしてCSVに書き出した（以下のファイル）。
https://gist.github.com/nebuta/4a8a9968adc10be3700dbb723c5bf027

# 統計的検定の方法
2013年度〜2018年度までの６年分を大学ごとに合算して，以下の値を求めた。

- 男女それぞれの合格率の信頼区間
- 男女の合格率の差の95%信頼区間
    - 差の信頼区間が0をまたいでいれば有意差なし，いなければ有意差あり。
- カイ二乗検定（帰無仮説：「男女の合格率が等しい」）のp値
    - カイ二乗検定でp<0.05であれば，「偶然のせいで男女の合格率が等しくならなかった確率は0.05未満」ということになり，男女の合格率に有意差あり。

計算にはSciPyの`stats.chi2_contingency`, `stats.binom.interval`および以下のコードを利用した。 https://stackoverflow.com/questions/39239087/

全体のソースコードは以下の通り（殴り書きのため読むづらいです...）
https://gist.github.com/nebuta/fed447861b2e40ee8fcb122ff88b313a

# 結果
男女の合格率の差を大学ごとに表示した結果が以下のグラフである。

- 真ん中の丸が差の推定値で，バーが95%信頼区間。
- バーが0の完全に右にある場合（青で表示）は，男子の合格率が女子よりも有意に高い（p<0.05）
- バーが0の完全に左にある場合（赤で表示）は，女子の合格率が男子よりも有意に高い（p<0.05）
- それ以外の場合は，有意差なし。

![all_difference.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16716/b4f7df73-1f44-ebaf-c507-70644715b0e1.png)

東京大学（理科III類）に関しては，p値0.789で，95%信頼区間が(-0.040, 0.053)である。つまり，**男女の合格率に統計的有意差があるとは言えない**。

- 鳥取大 p値0.992，95%信頼区間が(-0.023, 0.023)
- 島根大 p値0.658，95%信頼区間が(-0.033, 0.021)

これら２つも**男女の合格率に統計的有意差があるとは言えない**

# 注意

- 有意差がないというのは「差があるとはっきりとは言えない」であって「差が無いとはっきり言える」ではない。
- 「入試で男女の合格率に差がない」としても，「入試で男女差別がない」とは言い切れない。
   - もし女子のほうが全体として二次試験の点数が良いのであれば，「合格率が同じ」は「同じ点数ならば女子が不利」を意味するため。
   - ただ，男女の入試本番における素点に関する客観的データは存在しないと思われるので，これは検証しようがない。

# 個人的感想
式辞の後半の内容は至極納得感があるだけに，導入部の誤った統計の使い方は研究者としては正確さand/or誠実さに欠けると感じ，残念。
Ruby 変数 ハッシュ

##変数
変数とは、、、オブジェクトに名前をつける役割があります。
箱に入れるようなイメージです。

```
fruit = 　"りんご"
```

```
age = 10
```

##ハッシュへ代入
ハッシュとは、、、一つの変数で複数のデータを持つことができるオブジェクトです。
ハッシュオブジェクトの中には、KeyとValueのデータを所持することができます。
また、文法は3つあることだけ覚えておいたほうが良いでしょう。

```
hash1 = {"name" => "けんじ"}
hash2 = {:name => "こうたろう"}
hash3 = {name: "しげる"}
```
ただし、hash3の文法は「バージョン1.9.3」以降しか使えないので注意。

##ハッシュへ複数代入する

```
people = {name: "tarou", age: 29, gender: "男"}
```
atcoderで緑になるまでやったこと

春休み二か月かけてやっとこさ緑になりました、どうもKyleです。忘備録として適当に流れを書きます。
![asdfasdgdsgag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369642/a2f56943-9d22-4acf-138a-66d5dac11647.png)
#プロフ
どっかの偏差値50の国立大学の情報系っぽい3年生です。受験業界の凡人です。
センター数学は数ⅠＡ69、数ⅡＢ81のゴミ屑でした。個人的にatcoderのC問くらいまでの正答率と数Ⅰの点数とは相関があると思っているので参考程度に。
pythonをメインに使ってます。歴は大学の授業を適当に聞いていた期間が一年半、本格的に始めたのが半年前くらいなのでトータルで二年くらいです。~~（高校生の頃に部活でC言語をやっていましたが、これがいつになったらモンハンになるんだとか言ってキレてやめました、アホか）~~
#atcoderを知ったきっかけ
最初はpaizaさんのスキルチェックで何でこれがTLEするんや～！！！答えもないのにわかるか～！！！！とキレ散らかしてpaiza関連でいろいろググっていたらpaizaとatcoderの難易度表みたいなqiitaの記事が引っ掛かり、そこからatcoderもやってみるかとなりました。
#初回のコンテスト
初回はABC117でした。
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369642/88fc4bd4-076b-fb01-a2fa-b90ccbe2357f.png)
御覧の通りペナルティを知らなかったので、ひどい有様でした。（
この反省を踏まえ精進を始めました。
#そこでどう勉強するのか and 茶色まで
とりあえず本を買うのは癪だったので、atcoder scoresの100～200点問題をやり、解けたか如何を問わずその問題のすべての提出タブから最短コードを探してpythonの書き方やモジュールを徹底的に覚えました。また、そのコードのbyte数を抜かせないかと色々考えました。それと、その最短コードの書いた主のtwitterをフォローするのも有効です。コンテスト終了後に解法が流れてきたり、別解法を知れたりします。これをやっていれば普通に茶色にはなれると思います。

#茶色から緑まで
ここからは二つ壁があります。まずはC問を解けるかどうかということです。C問は数学力に依存する問題があります。ABC117のStreamlineやABC123のFive Transportationsはかなり気づけるか気づけないかという問題だと思います。また、実装が重いものとしてARC103の/\/\/\/やABC 112 Pyramidがあります。この辺を解くと後のC問は簡単に見えてきます。

初見でやって30分かけて解けなさそうなら解説を見てもいいと思います。最初は何言ってんだこいつこんなのわかるわけないだろとかtwitterでぼやきまくってましたが、C問ACが50問を超えたあたりから嘘解法でも「見える！解法が見えるぞ！」となるようになりました。ここであきらめないことが肝心かと思います。

二つ目の壁は速度です。ここ最近のABCでは簡単な問題が出ており、参加者の増加も併せて一問でも間違えると茶パフォになったりします。ここで効いてくるのが最短コードを詰めたことです。コード長が短くなれば提出するのが速くなり、それだけ順位が上がりますから。また、サンプルを一通り回すことを心がけましょう、私も焦ってテストをせずサンプルで引っ掛かってWAやREをくらったことは指の数を超えています。（

こんな感じでやれば大体は緑になれるかと思います、感想はtwitterまで。では。
Node.js,Expressメモ①

やってみたいことがあって未経験のweb領域を探るメモ。

「python使い」だけどイメージがこれに近いのでnode.jsをインストールすることにしました。

最終的に組み込みたいモジュール
https://github.com/retejs/rete

とはいえnode.jsどころか何がわからないのかもわからない！
ということでexpressというフレームワークで何か作ってみることに。
※こちらの記事をなぞっているだけです。
https://rfs.jp/sb/javascript/node/05node-js-p01.html


# インストール
pc: xps13 windows10 pro

node.js 10.15.3
https://nodejs.org/ja/

ダウンロードしたものをインストールしただけ


# スタートアップ
Hallo worldの作成。
上の記事の通りapp.jsを作成、node.js command promptのカレントディレクトリをファイルがあるフォルダに
変更。
`node app.js`

なるほど。めちゃくちゃ簡単にできました。
導入が楽なのは助かります。

この参考ページの構成でライブラリの読み込み部分が最初に書かれているのは嬉しいです。
`require("./mod.js")`


# パッケージのインストール
上の通りにいれましたがexpressを使うのにexpress-generatorも必要でした。
`npm install express-generator`

-gという引数でグローバル環境に入れるということなのでテストだし汚したくないので
外して入れていたのですがそれだとexpressのテンプレート階層が作成できずexpressは
グローバルに入れ直すことに。
※おそらくパスが通ってないだけですが、フレームワークはいつでも使うものなのかな？という判断です。
`npm install -g express`
`npm install -g express-generator`

# フレームワークのテンプレート階層作成
例に倣ってテンプレ階層を作成。この時点でexp01がフォルダ名になると思っていましたが
ejsがフォルダ名になるんですね。
`express -e ejs exp01`

と思ったらejsはテンプレートのはずなのに機能していなくてプロジェクト名になってしまっているようです。

`express -h`でヘルプをみてなるほど-eか--ejsだけでテンプレートを使う指定なのかと書き直したところ
``warning: option `--ejs' has been renamed to `--view=ejs'``
とでるので再チャレンジ
`express --view=ejs exp01`

作成されたapp.jsをざっとみるとこんな記述があるのできっとうまくいっているんだなと思い進みます。
`app.set('view engine', 'ejs');`

# 実行
カレントディレクトリをexp01にして何も考えずに実行しましたがうんともすんともいいません。。
`node app.js`

サーバーが立ち上がった形跡がなくすぐに処理が終わります。

おや？と中身を見てみたらやっぱりサーバーっぽい記述がありません。
express node.jsでググってそれらしき一文を挿入するとlocalhost:3000にそれっぽいテキストが!
`var server = app.listen(3000, function(){console.log("Node.js is listrning to PORT:3000")})`

なんとか無事node.jsでページを作ることができました。

# 組み込み
さすがにじゃあ組み込むぞ！と意気込んでもまだ先に進めなそうです。
つづく
縦書きCSSで文庫本っぽいUIを作る

![VertivcalTextCSS.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127520/11953621-c744-c3bf-ae3b-271cd2920039.gif)

- `writing-mode: vertical-rl;` これを入れるだけで縦書きになります。
- 横スクロールで読書の視線を再現しています
- 1文字目はインデントで字下げしたのも書籍を意識しています。

↓ タイトルを除く、pタグの１文字目は上余白を空ける

```scss
  &:not(.title):first-letter {
   padding-top: 1.1em;
```

- あとは適宜文字詰めや余白などを調整していく。




## 実装コード

<p class="codepen" data-height="865" data-theme-id="0" data-default-tab="css,result" data-user="agdg" data-slug-hash="XQaYgR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="ザ縦書き">
  <span>See the Pen <a href="https://codepen.io/agdg/pen/XQaYgR/">
  ザ縦書き</a> by Asagiri (<a href="https://codepen.io/agdg">@agdg</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
職場のPCをWindows10にアップグレードしたら、SQL Server Management Studioのインポートウィザードでエクセルやアクセスのデータをインポートできなくなった 

Windows7のサポートが切れるので、職場のPCをWindows10にアップグレードしている人が増えていると思います。

そんな人の一人、職場の後ろの席の人が「あれれぇ～？」っと、アニメの主人公みたいな声を出してハマっていたので、そんな人が検索した時にヒットしそうなタイトルで書いておきます。

##症状
Office 365 ProPlusをインストールしているのに、SSMSのインポートウィザードにaccdbのデータソースが表示されません。
<img width="414" alt="012.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393811/b82d6ac1-6ff8-5b25-7bce-32f1662c52e5.png">
また、エクセルはインポートできそうな表示なのに、インポートしようとすると怒られてしまいます。
<img width="455" alt="013.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393811/5b5b9bc5-c8d5-1410-d6e0-321337193c82.png">

##原因
Office 365 ProPlusなどのクイック実行製品（Click-to-Runアプリケーション）は、Office以外の一部のアプリケーションからインストール場所を認識されない場合があるとのことです。

##みんながやりそうな対策
「じゃあ、Access Database Engineをインストールすればいいんじゃない？」って思うじゃないですか。
すると、Officeは32ビット版をインストールしているのに、いちゃもん的な内容で、また怒られます。
<img width="314" alt="014.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393811/9144e329-a5c3-6ca4-7d20-82f6d3aa8a24.png">

##対策
Access Database Engineを「/quiet」オプションを付けて実行してください。

<ファイルの場所>:\<ファイル名> /quiet
例: C:\AccessDatabaseEngine.exe /quiet

##この問題についての情報
この問題については、以前からマイクロソフトがサポート情報を提供してくれているんですが、日本語のページを読んでも、ちっとも頭に入って来ません。
英語のページを原文のまま読んだ方がよくわかると思います。


#####英語
https://support.microsoft.com/en-us/help/2874601/can-not-use-access-odbc-or-oledb-provider-outside-office-c2r-apps

#####日本語
https://docs.microsoft.com/ja-jp/sql/integration-services/import-export-data/connect-to-an-access-data-source-sql-server-import-and-export-wizard?view=sql-server-2017

#####参考
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_access-mso_win10-mso_o365b/odbc-driver-missing-for-access-accdb-after-office/8c04a3d7-00fc-4226-82eb-cbd043c575f4?auth=1
Firebase Hostingで旧バージョンの自動削除を設定する

# 概要

待望？の旧バージョンの自動削除機能がリリースされた模様。
それまでリリースしたら、もうロールバックしないだろうバージョンは手動でポチポチ削除していました:weary:
これを設定すればもう旧バージョンの管理は基本的に不要になります。
ドキュメントに追加されないので、簡単なものですが記事化します。

# 読者対象

- Firebase Hostingで旧バージョンをポチポチ削除していた方
- Firebase Hostingで旧バージョンを削除せずに放置している方
- これからFirebase Hostingを学ぶ方

# 設定

Hostingトップ画面のリリース履歴からメニューを表示すると設定画面が表示されます。

![バージョン履歴の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/0777b7b0-2c0b-77b6-a8a9-ea2e349be110.png)

いくつ前のバージョンまで残しておくか数値入力してOKを押すだけです。
どのタイミングで削除されたかは失念しましたが、設定すればいずれかのタイミングで設定値以上の旧バージョンは自動削除されます。
自動削除されると、”自動削除済み”の表示になります。

![バージョン履歴の設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/e06323bf-b05d-c807-d718-e1d0fa84bed1.png)

一点注意したいのはロールバック時。
記憶があいまいなので正確に把握したい方はご自身で確認してください。
記憶によると、ロールバックしてロールバック元のバージョンが削除された場合、再度そのバージョンへのロールバックはできなかったはずです。
ロールバックすると履歴の最新に積み上げられますが、ロールバックを実行できるのはロールバックの履歴からではなく、ロールバック元のバージョンから実行します。
例えば自動削除を5にしておいて、4つ前のバージョンにロールバックする場合、次にリリースしたらロールバック元が消えますので、その場合は一時的に自動削除を10あたりに設定する必要があると思われます。


# まとめ

ロールバック時の注意点はありますが、簡単に利用できる自動削除機能いかがでしょうか。
ポチポチ削除していた身としては非常にありがたい機能、ぜひ設定して旧バージョンの管理から解放されてみてください:laughing:
しいていうなら、あとはラベル追加できると申し分ないです。
ラベルがないとこれってどんなバージョンなんだろうと、リリースして数日もするとわからなくなるんですよね…
GitHubで管理すればいいんでしょうけど、Firebase Hostingで完結しないかなと思う今日この頃。
Cloud Code で GKE にアプリケーションをデプロイする方法


コンテナアプリ開発に便利な Visual Studio  Code と IntelliJ 用のプラグイン [Cloud Code](https://cloud.google.com/cloud-code/) で、[Google Cloud Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) クラスタにアプリケーションをデプロイできるようになりました。ここでは、Visual Studio Code 用を使って、サンプルアプリ Guestbook をデプロイしてみたいと思います。また、コンテナのビルドは [Cloud Build](https://cloud.google.com/cloud-build/) を使ってみしょう。

方法は、[QuickStart](https://cloud.google.com/code/docs/vscode/quickstart) を見ればだいたいわかりますが、日本語でもまとめてみました。

+ [QuickStart](https://cloud.google.com/code/docs/vscode/quickstart) を参考に、Docker と kubectl と Skaffold を入れておきます。ここでは Mac 環境での準備を参考に書いておきます。ちなみに、Skaffold は Kubernetes クラスタで、アプリケーションの継続的デリバリーを行うコマンドラインツールです。Skaffold を利用するには kubectl と Docker が必要になります。

 + [Docker Desktop（Mac 版）](https://hub.docker.com/editions/community/docker-ce-desktop-mac)をインストール
 + kubectl と skaffold をインストール

```console:
brew install kubernetes-cli
brew install skaffold
```

+ Cloud SDK を インストールし、gcloud 環境を初期化

```console:
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init
```

+ GCP コンソールより、 GKE クラスタを構築（Cloud Code を入れると、Cloud Code からも作成できるようです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/2c4e8b97-1ab3-3206-8bcc-bdf8f7afd7b3.png)

+ VS Code から、`Shift + Command + X` で拡張機能ビューを表示して、`Cloud Code` を検索しインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/32e1243a-c1b9-328c-88ea-3178e75ff80f.png)

+ `Shift + Command + P` でコマンドパレットを表示して、`Cloud Code: New Application`で、アプリケーションを作成。ここでは、`Node.js: Guestbook` を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/bb58ab65-f895-8987-c470-b7870f647cd5.png)

+ 新しいウインドウで、サンプルアプリのワークスペースがオープン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/29e5028c-1b16-e134-f527-48cb3d1f3348.png)


+ GKE クラスタが正しく構築されていると VS Code にこのように表示されます。左のアクティビティバーの下にある Cloud Code のアイコンをクリックすると、Kubernetes 環境が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/053840cf-3e63-aa8e-399e-df1de718caf3.png)


+ 作成された、GKE クラスタを右クリックし `Set as Active Cluster` をクリックし、Active Cluster に設定すると、Cluster Explorer に GKE クラスタが表示されます。

+ `Cloud Code: Deploy` でサンプルアプリケーションをデプロイ
 + `[default]` ローカルの Docker 環境でビルド
 + `cloudbuild` Cloud Build 環境でビルド （今回はこちらを選択）

+ Cloud Build 環境で、コンテナをビルドするときの注意
　+ [quickstart-docker](https://cloud.google.com/cloud-build/docs/quickstart-docker) を参考に、Cloud Build API を有効にしておきましょう。
　+ `getting google client: google: could not find default credentials. ` といエラーが出力される場合は `gcloud auth application-default login` で アプリケーションのデフォルトクレデンシャルを設定してみましょう。

+ Cloud Build でビルドの結果を、GCP コンソールから確認。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/fc4c881f-b861-d53e-ff1f-d57780c9a3d9.png)

+ 無事デプロイに成功すると、サンプルアプリの URL が表示れるので、そちらにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/ac423f42-d850-1a4a-4525-961f395ab7a1.png)

+ Guestbook が正常に展開されたことを確認 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42406/a8fb5fb0-fb4f-e9e0-0722-c5644caf26cd.png)
rubyコンソールからheroku login するときのエラー

$ heroku login

としたところ、

![2019y04m14d_005505736.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281914/619ecf6d-933e-bab0-3d08-63f98adcfa8e.jpeg)

となりログインできなかった。


$ heroku login --interactive

でメールアドレス、パスワードが聞かれるようになり、
ログインできた。
vectorの最大値とそのindex取得

# はじめに
c++のvector配列の最大値とそのindexの出し方がすぐに思いつかなかったため、備忘録として記述。

# ソースコード
## iterator
iterator自体に知識がなかったので[こちら](http://vivi.dyndns.org/tech/cpp/iterator.html)を参照しました。

- vector::iterator, array::iterator はランダム・アクセス可能
- list::iterator は両方向移動可能
- forward_list::iterator は前方向のみ移動可能

色んなiteratorの種類があるんすね。

## メイン処理
max_elementで最大要素を指す最初のイテレータを取得。
その後、iterator間の距離を求めるdistanceで要素の値を取得

```cpp
std::vector<int>::iterator iter = std::max_element(x.begin(), x.end());
size_t index = std::distance(x.begin(), iter);
```

## サンプルコード
```cpp
#include<iostream>
#include<vector>
#include<algorithm>

int main(){
  std::vector<int> x;
  for(int i=0;i<10;i++){
    x.push_back(i);
  }

  std::vector<int>::iterator iter = std::max_element(x.begin(), x.end());
  size_t index = std::distance(x.begin(), iter);
  std::cout << "max element:" << x[index] << std::endl;
  std::cout << "max element:" << *iter << std::endl;
  return 0;
}
```
# 最後に
修士課程に進学してから、プログラミングを本格的に始めました。
というか、Quita初投稿です!訂正やこうしたらいいよなどの提案、様々なコメント待っています！！

# 引用

[vectorの指定したiteratorの要素番号を取得する] (https://teramonagi.hatenablog.com/entry/20130225/1361793892)
Electronで任意のファイルを開く機能を実装する


ユーザーの視点からファイルを開く方法を考えると、3つの方法があると思います。

1.Menu,ショートカットキーでファイル選択ダイアログを開いてファイルを選択する
2.開きたいファイルをWindowにドラッグ&ドロップする
3.ファイルをダブルクリックしてElectronアプリで開く


この記事では1の"Menu,ショートカットキーでファイル選択ダイアログを開いてファイルを選択する"機能の実装方法について説明します。

自分の環境は[この記事](https://qiita.com/stupid_student2/items/2d9a27e6dac6f76e061b)を参照。UIの作成にReactを使っています。

情報が正しくなかったり、もっとスマートな実装方法があったりするかもしれませんがあしからず。

#1.成果物
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/bcfd6c2a-fd17-d24d-c53c-53c93358bcfc.gif)


#2実装方法

[Menu](https://electronjs.org/docs/api/menu)と[dialog](https://electronjs.org/docs/api/dialog)は基本的にメインプロセスでしか取扱えないらしいです。なのでメインプロセスでMenuの作成とdialogを表示する処理を行います。そしてdialogを表示したあとにレンダラープロセスにイベントを飛ばします。

メインプロセスとかレンダラープロセスとか何ぞ？という方は[こちら](https://electronjs.org/docs/tutorial/application-architecture)

``` main.js
const { Menu, dialog } = require('electron')

// メニューの作成
function createMenu() {
  const template = [
    {
      label: 'Electron',
      submenu: [
        {
          label: 'about'
        }
      ]
    },
    {
      label: 'File',
      submenu: [
        {
          label: 'Open..',
          accelerator: 'CmdOrCtrl+O', // ショートカットキーを設定
          click: () => { openFile() } // 実行される関数
        }
      ]
    }
  ]
  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu);
}

// ファイル選択ダイアログを開く
function openFile() {
  dialog.showOpenDialog({ properties: ['openFile'] }, (filePath) => {

    // レンダラープロセスにイベントを飛ばす
    mainWindow.webContents.send('open_file', filePath);
  })
}

// 未検証だけどMenuを作成するタイミングは別にここじゃなくても良い気がする。
app.on('ready', createMenu)

```


そしてレンダラープロセス側でイベントを受け取る。

``` App.js

import '../assets/css/App.css'
import React, { Component } from 'react'

const { remote, ipcRenderer } = require('electron')
const { Menu, MenuItem } = remote

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { path: '' }

    this.init();
  }

  init() {
    this.setup();
  }

  setup() {

    // イベントを受け取る
    ipcRenderer.on('open_file', (event, arg) => {

      // ファイルパスからファイル名を抜き取る
      let filePath = arg[0];
      filePath = filePath.split('\\'); 
      const fileName = filePath[filePath.length - 1];
      console.log(fileName);

      // Stateの更新
      this.setState({ path: fileName });
    })
  }

  render() {
    return (
      <div>
        <h1>Hello, Electron!</h1>
        <p>{this.state.path}</p>
      </div>
    )
  }
}

export default App


```

#ファイルじゃなくてフォルダを選択させたい場合

``` .js
  dialog.showOpenDialog({ properties: ['openDirectory'] }, (filePath) => {
       mainWindow.webContents.send('open_file', filePath);
  })
```

いろいろ設定できるみたいなので[公式のドキュメント](https://electronjs.org/docs/api/dialog)を参照してください。
【WordPress】個別ページとアーカイブページで記事情報を取得する方法

個別ページとアーカイブページで記事の情報を取得する方法について解説していきます。

## 個別ページ
have_postsという関数を用いて、以下のように記事情報を取り出すことができます。「もし記事を持っていれば、その記事の分だけ繰り返し処理を行う」という記述です。

```php
<?php
    if(have_posts()){
        while(have_posts()){
?>
            <h1><?= the_post(); ?></h1>
            <h1><?= the_title(); ?></h1>
<?php
         }
     }
?>
```

## アーカイブページ
上記詳細ページと同じようなやり方で取得することができます。

```php
<?php
    if(have_posts()){
        while(have_posts()){
?>
            <h1><?= the_post(); ?></h1>
            <h1><?= the_title(); ?></h1>
<?php
         }
     }
?>
```

また、\$postsという変数を利用して以下のように取り出すこともできます。変数\$postsには、記事の情報が入っています。var_dump(\$posts)とかして見て中身を確かめてみるといいと思います。

```php
<?php
    foreach( $posts as $client ){
?>
    <h1><?= $client->post_title ?></h1>
<?php
    }
?>
```

## have_posts()について
have_postsの関数について、定義は以下のようになっている。どうやら$wp_queryが持つメソッドらしい。

```php
function have_posts() {
    global $wp_query;
    return $wp_query->have_posts();
}
```


WpQueryクラスのメソッドを見ていくと以下のような記述がある。

```php
public function have_posts() {
    if ( $this->current_post + 1 < $this->post_count ) {
        return true;
    } elseif (
        $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
        /**
        * Fires once the loop has ended.
        *
        * @since 2.0.0
        *
        * @param WP_Query $this The WP_Query instance (passed by reference).
        */
        do_action_ref_array( 'loop_end', array( &$this ) );
        // Do some cleaning up after the loop
        $this->rewind_posts();
    } elseif ( 0 === $this->post_count ) {
        /**
        * Fires if no results are found in a post query.
        *
        * @since 4.9.0
        *
        * @param WP_Query $this The WP_Query instance.
        */
        do_action( 'loop_no_results', $this );
    }

    $this->in_the_loop = false;
    return false;
}
```

いろいろ書かれていてよくわからないが大きく、「最後のページ以外を取得する場合の処理」、「最後のページを取得する場合の処理」、「そもそも投稿がない場合の処理」に分かれているみたい。\$this->current_post + 1 < \$this->post_countの部分がtrueである限り、すなわち最後のページを取得するまで、ループを回すことができる。ループを回している間、the_titleとかを使って各ページの情報を取り出しているという感じですかね。


## リファレンス
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/have_posts
「お好きなランダム文字列」生成コマンドを組んでみた

こんにちは。久しぶりに投稿します。

# なにがしたいのか
パスワード生成とか、何かと需要のある**ランダム文字列**を、コマンド１つでターンと出力できるようなモノを実装したかった。

## 結果
先に結果を共有します。
<img width="438" alt="スクリーンショット 2019-04-13 23.54.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172185/123de977-961a-da80-ac58-f927671890a0.png">

使い方は単純で、
`rndstr`コマンドに必要に応じて以下のオプションを渡すだけ。
- `-n` 数字
- `-a` 英小文字
- `-A` 英大文字
- `-m` マイナス（「-」 <-ハイフンですよね...）
- `-u` アンダーバー（「_」）
- `-L 20` 長さ20の文字列を出力（省略すると長さ10）
- `-C 10` 10個の文字列を出力（省略すると1個）
このうち、`naA`のいずれかのオプションがないとエラーを吐きます。

ソースコードは[コチラ](https://github.com/up-tri/rndstr)

# 実装
## まず、shell scriptを書く。

### 1.標準の長さと標準個数を変数で用意
```sh
#!/bin/sh

LEN=10
CNT=1

```

### 2.`getopts`を用いてオプションを設定
`test` とか `[ ~ ]`で実装もできますが、今回は便利なコマンドを使います。
> 参考：[UNIX & Linux コマンド・シェルスクリプトリファレンス　様](https://shellscript.sunone.me/parameter.html#%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E8%A7%A3%E6%9E%90%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-getopts-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)

冒頭で挙げたオプションについてそれぞれフラグを設定しつつ、正規表現パターンに関する処理も行います。（パターンは後ほど使います。）
ちなみに引数付きのオプションは`$OPT`→`$OPTARG`といった形で持ってこれます。
> パターンを見ればわかりますが見間違いやすい文字を省いています。（数字の**0**と英字の**o**　とか）

```sh

while getopts naAmuL:C: OPT
do
  case $OPT in
    "n" ) FLG_NUMBER="TRUE" ; PATTERN="${PATTERN}12345678" ;;
    "a" ) FLG_small="TRUE" ; PATTERN="${PATTERN}abcdefghijkmnpqrstuvwxyz" ;;
    "A" ) FLG_LARGE="TRUE" ; PATTERN="${PATTERN}ABCDEFGHIJKLMNPQRSTUVWXYZ" ;;
    "m" ) FLG_MINUS="TRUE" ; PATTERN="${PATTERN}\-" ;;
    "u" ) FLG_UBAR="TRUE" ; PATTERN="${PATTERN}_" ;;
    "L" ) FLG_LENGTH="TRUE" ; LEN=$OPTARG ;;
    "C" ) FLG_COUNT="TRUE" ; CNT=$OPTARG ;;
  esac
done
```

### 3.エラー処理
フラグを利用して、「数字も英字もナシなんて許さないヨ」を実装します。

```sh
if [ -z "$FLG_NUMBER" ] && [ -z "$FLG_small" ] && [ -z "$FLG_LARGE" ] ; then
  echo "下記を最低１つ指定してください。"
  echo "[-n] 数字"
  echo "[-a] 英小文字"
  echo "[-A] 英大文字"
else
  # ...
fi
```

### 4.色々縛りをかける
変数`CONTAIN`に正規表現パターンを代入し、「数字指定したのに数字が含まれてない！」等を防止しています。

そして最後の１行で

- `cat /dev/urandom` ... 乱数文字列を取得
- `tr -dc ${PATTERN}` ... `$PATTERN`以外の文字を削除
    - Mac OSでは`LC_CTYPE=C`を付さないとエラーが起きます。
- `fold -w ${LEN}` ... `$LEN`行ごとに改行
- `grep -i "[${CONTAIN}]"` ... 「数字指定したのに数字が含まれてない！」防止
- `grep -e '^[12`...`YZ]'` ... 先頭が記号以外
- `head -n ${CNT}` ... 先頭`$CNT`行だけ取得

という一連の処理を行い、必要なランダム文字列を取得することができます。

```sh
if [ -z "$FLG_NUMBER" ] && [ -z "$FLG_small" ] && [ -z "$FLG_LARGE" ] ; then
  # ...
else
  if [ -n "$FLG_MINUS" ] && [ -n "$FLG_UBAR" ] ; then
    CONTAIN="\-_"
  elif [ -n "$FLG_UBAR" ] ; then
    CONTAIN="_"
  elif [ -n "$FLG_MINUS" ] ; then
    CONTAIN="\-"
  elif [ -n "$FLG_NUMBER" ] ; then
    CONTAIN="12345678"
  else
    CONTAIN="abcdefghijkmnpqrstuvwxyz"
  fi

  cat /dev/urandom | LC_CTYPE=C tr -dc ${PATTERN} | fold -w ${LEN} | grep -i "[${CONTAIN}]" | grep -e '^[12345678abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ]' | head -n ${CNT}
fi
```

## 次に、保存＆bashrc等に登録。
保存先は、ホームディレクトリに自作コマンド専用のディレクトリを作ってまとめておくと何かと楽です。
（今回は`~/cmds/rndstr.sh`に保存します。）

ここで重要なのが**権限**です。shファイルを作っても実行権限がないと動きません。

```bash
chmod +x ~/cmds/rndstr.sh
```

で付与しておきましょう。

次に`.bashrc`や`.zshrc`などにコマンドを登録します。

```
alias rndstr='~/cmds/rndstr.sh'
```

この１行を足します。

## おしまい。
JetBrains製IDEで保存時に Prettier で整形する

[Rails + TypeScript + webpack環境構築](https://medium.com/takeyuweb-tech/rails-typescript-webpack%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89-21c4402bbb01)

入れるべきプラグインは次の２つ。

- [File Watchers](https://plugins.jetbrains.com/plugin/7177-file-watchers)
    - ファイルの変更を検知して処理を行いたい時に役立つプラグイン。
- [Prettier](https://plugins.jetbrains.com/plugin/10456-prettier)
    - File Watchers で Prettier を使う設定テンプレを追加してくれる。
    - `Reformat with Prettier` アクションも追加してくれる。

## 設定

`Settings` => `Tools` => `File Watchers`

![file_watchers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7000/6b0a1fcc-a97f-83ea-46b9-7fde9f67103b.png)

File type に自動整形を行いたいファイルの種類をを選択。（ここでは  `TypeScript` ）
globalの `/usr/lib/node_modules/prettier`を使うなら Program を変更。
ほかは変更不要。

![new_watcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7000/689d8c84-e564-8f05-bd00-e8f9bcc165ad.png)

複数の種類で自動整形したいなら、ファイルの種類の数だけ設定すればOK。
railsプロジェクト作成時にsqlite3のインストールが原因でエラーとなってしまう


## エラー内容
以下のようにしてrailsプロジェクト作成時にエラーとなってしまう

```
$ rails new first_app
...
An error occurred while installing sqlite3, and Bundler cannot continue.
```

## 対応策
Gemgfileを開き、エラー文に記載されているバージョンを指定

```
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.2'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.3'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.3.10'
```

次に以下のようにBundlerをアップデート

```
bundle update
```

すると再度以下のようなエラーが

```
Using spring-watcher-listen 2.0.1
Fetching sqlite3 1.3.13
Installing sqlite3 1.3.13 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

...
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
```

sqlite-develをインストール

```
sudo yum install sqlite-devel
```

すると以下のようなエラー
※この辺記憶が曖昧なので順番が前後している可能性があります

```
An error occurred while installing sqlite3 (1.3.13), and Bundler cannot continue.
Make sure that `gem install sqlite3 -v '1.3.13' --source 'https://rubygems.org/'` succeeds before bundling.
```

エラー文に従いインストール

```
gem install sqlite3 -v '1.3.13' --source 'https://rubygems.org/'
```

するとまた以下のようなエラー

```
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
```

先程sql-liteはインストールしたが、libsqlite3-devをインストールしていなかったのでインストール

```
sudo apt-get install libsqlite3-dev
```

再度

```
gem install sqlite3 -v '1.3.13' --source 'https://rubygems.org/'
```

sqliteがインストールできた

```
Successfully installed sqlite3-1.3.13
Parsing documentation for sqlite3-1.3.13
Installing ri documentation for sqlite3-1.3.13
Done installing documentation for sqlite3 after 1 seconds
1 gem installed
```

改めてbundlerをupdate

```
bundle update
```

できたー

```
Using sqlite3 1.3.13
Fetching turbolinks-source 5.2.0
Installing turbolinks-source 5.2.0
Fetching turbolinks 5.2.0
Installing turbolinks 5.2.0
Fetching uglifier 4.1.20
Installing uglifier 4.1.20
Fetching web-console 3.7.0
Installing web-console 3.7.0
Bundle updated!
```

最後にDBを作成

```
rails db:create
```

## 追記
後日railsにてModel作成後、以下のコマンドでスキーマを確認しようとするとエラーとなってしまった

```
rails dbconsole

...
Couldn't find database client: sqlite3. Check your $PATH and try again.
```

上記手順にある「gem install sqlite3...」はあくまでrailsのsqlite3に関するパッケージをインストールしたにすぎず、
肝心のsqlite本体がインストールされていない?

以下でインストールし対応

```
sudo apt-get install -y sqlite3
```

以上
CentOS上にPHP7.3+Laravel5.7を構築

# Laravel環境構築
## はじめに
Laravel環境構築するために試した手順を書きます。
参考になれば幸いです。

## CentOS
前回構築したWindows10上のCentOSにPHP7.3とLaravel5.7環境を構築していきます。
[Windows10上にCentOS環境構築](https://qiita.com/k00j/items/8a631934e67b0c8bce68)

参考にした手順は下記です。
[【Laravel超入門】Laravel5.6 + PHP7.2 + centOS7 + Vagrant 環境構築](https://qiita.com/inexp_eng4432/items/ec818f151b8ad516988b)

## PHP7.3
参考ページ
[CentOS6／CentOS7にPHP5.6／PHP7をyumでインストール](https://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e)

### EPELリポジトリ
下記コマンドを実行

```
yum install epel-release
```

### Remiリポジトリ
下記コマンドを実行

```
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

### PHP7.3

```
yum install --enablerepo=remi,remi-php73 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt
```

### Composer

```
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```
composerがインストールできているか確認したい場合は「composer」とコマンドを打てば、アスキーアートが表示されます。

## Laravel

### インストール

```
composer global require "laravel/installer"
```
参考にしているページと同様に、なぜかphp-xmlがうまくインストールできていませんでした。
下記でインストール

```
yum -y install --enablerepo=remi-php73 php-xml
```
これでうまくLaravelがインストールできたはずです。

### プロジェクト作成

```
composer create-project --prefer-dist laravel/laravel [PJ名] "5.7.*"
```
権限回りでうまくいかない場合がありますのでお気を付けください。

## Apatch
### ドキュメントルートの設定
Laravelのindex.phpをルートにする設定を行います。

```
# ドキュメントルートを書き換える
DocumentRoot "/[project]/public"

# ルートディレクトリも変更する
<Directory "/[project]/public">
    # None → All
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>
```

これでうまくいったはずなので、curlコマンドなどでlocalhostに接続してみました。
が、なぜか404。接続できてない？
CentOSの80番ポートが開いてませんでした。

[CentOS 7のファイアウォールで80番ポートを許可する](http://inaba.hatenablog.com/entry/2017/02/26/040218)
ここを参考に80番ポートを空けました。

とりあえず、サーバにはつながりましたが、今度はログファイルが読み込めないとエラー画面に！

いろいろググったりした結果、下記ページが参考になりました。
[Laravel4、app/storageのパーミッショントラブル](https://kore1server.com/261)

下記コマンドで、appとstorageフォルダの権限を変更しました。

```
chmod -R 777 app
chmod -R 777 storage
```

さて、やっと初期画面が表示されるかなーと思っていたら。。。
キーがないと？

```
RuntimeException
No application encryption key has been specified.
```
[laravel プロジェクトで RuntimeException No application encryption key has been specified.](https://qiita.com/pugiemonn/items/641718fd241320384972)
keyを生成しないといけないみたいです。

```
php artisan key:generate
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3098/ad1259d9-359b-1a2b-b80d-4ddeac5bc9cd.png)


やっとこさ、初期画面が表示できました。
これからチュートリアルかなにかをやろうと思います。
Groovyで気軽にJUnit 5を試すサンプルと実行方法2つ

最近、Groovyの良さを再認識したので、Visual Studio CodeとGroovyで気軽にJUnit 5を試そうと思ったら、変な方向で苦労したので、自分の環境備忘録として残しておく。

今回やりたいのは、こんなこと。

- JUnit 5を使ってテストを書いてみるのを気軽に書き捨てたい
- 書き捨てだから、GradleとかIntelliJ IDEAを使わずに、.groovyファイル1つで動かしたい
- 使い慣れてきたVS Codeで書いて実行できたら良いな

結果的に、2つの方法で上記が満たせた。
両者に共通するのは、 **VS CodeでCode Runnerプラグインを使う** こと。

## JUnit 5をGroovyで書くサンプル
まず、Grabも使いながらJunit 5を試すGroovyは、こんな感じ。Grab便利。

```groovy
@Grab("org.junit.jupiter:junit-jupiter-api:5.4.1")
@Grab("org.junit.jupiter:junit-jupiter-engine:5.4.1")
@Grab("org.junit.platform:junit-platform-console:1.4.1")

import static org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.*

// テスト対象クラス
class Calc {
  def add(a, b) {
    a + b
  }
}

// テストクラス
class CalcTest {
  def calc

  @BeforeEach
  def before() {
    calc = new Calc()
  }

  @Test
  def addTest() {
    assertEquals(calc.add(1, 1), 2)
  }
}

class AtomicTest {
  @Test
  def test() {
    assertEquals(2, 1 + 1)
  }
}
```

## 方法1：junit-platform-console-standaloneを使ってファイルごと動かす
- Maven Central Repositoryから、junit-platform-console-standaloneのjarをダウンロード
- ダウンロードしたjarファイルを、 ```~/bin``` のような分かりやすいところに置く
- VS Codeの ```settings.json``` に以下を追記

```json
"code-runner.executorMap": {
    "junit5": "java -jar ~/bin/junit-platform-console-standalone-1.4.2.jar -f $fileName"
}
```

こうすると、 ```Control + Option + j``` (Macの場合)かコマンドパレットの Run by Languageから ```junit5``` を選択して実行できるようになる。
ただ、VS Codeの出力タブに出すとターミナル向けの制御文字が化けた感じになるのと、結果レポート出力のツリーが正常に動かないのがネック。

## 方法2：JUnit5Runnerクラスを使って1クラスのテストだけ動かす
こっちは、書いた.groovyファイル内に、こんなコードを追加すると動くようになる。

```groovy
import groovy.junit5.plugin.JUnit5Runner
new JUnit5Runner().run(テストクラス.class, new GroovyClassLoader())
```

これは、本当に.groovyファイル1つで完結して良いんだけど、標準出力が超最低限なのと、1クラスずつしか動かせないのがネック。
他の書き方もありそうな気はしてる。

----

個人的には、少し環境構築が必要だけど、方法1の方が使いやすいと思っている。
逆に、環境を汚さずにできるって意味では方法2もアリかなと。

ちなみに、 ```org.junit.platform.console.ConsoleLauncher``` クラスを使って動かそうとしたのは失敗した。
ちょっとよく分からないExceptionが出てお手上げ…。
長押しボタンを作ってみた【初期実装】

# はじめに

最近のゲームでボタンを長押しを要求するUXがより、それをWebでも使えないかと思い、作ってみました。

# 作ってみる

さっそく作ります。

### 長押しボタンの仕様

大きな仕様は以下2つです。

- 特定の秒数長押しするとアクションが発生する
- 途中で長押しをやめるとカウントが0に戻る

### 長押しの検知

マウスイベントには、長押しを検知するイベントがないため、 `mousedown` と `mouseup`、 `setIntervel` を組み合わせることで長押しを検知しました。

``` index.html 
<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
        <!--
            #button1 {
                width: 50px;
                height: 50px;
                border-radius: 50%;
                border: none;
                background-color: gray;
            }
        -->
        </style>
    </head>
    <body>
        <button id="button1"></button>
        <script>
            (function(){
                var LIMIT = 10;
                var timer;
                var count = 0;
                var button1 = document.getElementById('button1');

                var start = function () {
                    console.log("mousedown");
                    if (!timer) {
                        timer = setInterval(counter, 100);
                    } 
                }
                var stop = function () {
                    console.log("mouseup");
                    clearInterval(timer);
                    timer = 0;
                    count = 0;
                }

                button1.addEventListener('mousedown', start, false);
                button1.addEventListener('mouseup', stop, false);

                var counter = function(){
                    console.log(count++);
                    if (count > 9) {
                        console.log('OK');
                        clearInterval(timer);
                        timer = 0;
                        count = 0;
                    }
                }
            })();
        </script>
    </body>
</html>
```

簡単に説明すると、`mousedown` で呼ばれる処理で、setIntervalをセットし、 `counter` 処理を100ms毎に実行。
countが10以上になると処理を停止するという流れです。

### 右クリック禁止とmouseoutイベント時の処理

処理のクオリティをあげるために、ぐちゃぐちゃ操作していたら、右クリックと `mouseout` イベント時に処理が正常に動かなくなっため、制御をいれました。

```js:index.html
  var button1 = document.getElementById('button1');
  // 右クリック禁止
  button1.oncontextmenu = function () {
    return false;
  }
・・・
  button.addEventListener('mousedown', start, false);
  button.addEventListener('mouseup', stop, false);
  // mouseoutイベント追加
  button.addEventListener('mouseout', stop, false);
・・・
```

### 進捗の表示

長押し中にどのくらいの進捗なのかを表示するために、 秒数の表示とdiv要素を追加しました。

# 完成

ソースコードは以下githubにあがっています。
https://github.com/takuhou/smart-ui/blob/master/index.html

ただ、これだとクオリティがいまいちなので、
UXやモジュールとして提供するために、追加実装を続けております。

今回の記事で書いたプログラミングの様子をYoutube上にアップロードしておりますので、是非ご覧ください。

[【実況】長押しボタンをプログラミング【初期実装】](https://www.youtube.com/watch?v=nLd6yOnn1jY)
[えんじにぁ〜TV](https://www.youtube.com/channel/UCYCbtkuInmgpK0Hv3W2orEg)
SASS(SCSS)は必要なの？

<p>これまでHTML/CSSで普通に難なくコーディングしていたのだが、
Railsアプリのインターフェース作成時に、hamlとscssを使うことになった時に
思ったことが......</P>


<strong>わざわざhamlとscss記法を学習し直してまでやる必要あるのか！？！？

そこで今回は、なぜSASS(SCSS）で記述するのが良いのか考えていこうと思う。


<h2>SASSとは

まずSASSってなんなんだっていう話から

SASSは <strong>S</strong>yntactically <strong>A</strong>wesome <strong>S</strong>tyle <strong>S</strong>heet　の略称であり

簡単に訳せば「文法的にかっこいいスタイルシート」という意味になる。

つまりは、普通にcssを書くよりは見栄えがよくなるよっていうことなのかな

た

```
header {
   background-color: gray;
   height: 50px;
   width: 100%;
}

header .header__white {
   font-size: 20px;
   background-color: #fff;
   font-weight: bold;
}

header .header__black {
   font-size: 20px;
   background-color: #black;
   font-weight: bold;
}
```
となっていれば

```
header {
   background-color: gray;
   height: 50px;
   width: 100%;
     &__white {
         font-size: 20px;
         background-color: #fff;
         font-weight: bold;
     &__black {
         font-size: 20px;
          background-color: #black;
          font-weight: bold;
}
```

という風に、ネストを使ってコンパクトに記述できるというところがAwesomeなところのひとつであろう。


<h2>フォルダで分割管理

もうひとつAwesomeな点は、モジュールごとに必要なCSSをフォルダを分けて管理することによって、
１つ１つのフォルダを短くスッキリまてめる事ができる。

スタイルごとの管理もできるので、後からのデザイン変更や追加を行ないやすくなる。



<h2>でもコンパイルがめんくさい・・・


そもそもSCSSを書いたところで、そのままではHTMLに適用されないのです。
CSSファイルへのコンパイルをする必要があります。


でもいちいちCMDやターミナルにコマンドを入力するのは手間がかかるなあ・・・

それなら最初から直接CSSを書き込んでもよかったのでは・・・・とも思ってしまいます。


でもそんな心配なんぞご無用で、ちゃんとコンパイルを自動化してくれるアプリや拡張機能が多く出回っているのです。


自分はVSCodeを使用しているので、拡張機能の'<a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass">Live Sass Compiler</a>がとても便利！

<img width="979" alt="2963e49d2f579c075208cfdfddc6e54f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354080/650d708a-a7d4-fd7e-23e2-9fe9e3b12a19.png">


使い方、DL方法は下記リンク参照
https://asamone.com/2018/09/30/sass-vscode/



<h2>結論

今回はあまり深掘りができなかったが、まだSASSには色々な便利機能があって、試す価値は大いにあると思う。

自分が思うに、小規模なアプリを自分一人で作成する分には、SASSを覚える必要はないかもしれない。

しかしながら、チームで開発するとなった時のソース管理の複雑さを少しでも簡便にするためにも、
他の人のことを思い合って書くAwesomeなコードが書ける事が望ましいかもしれない。
Firebase Hostingでwww付きURLを正規URLにリダイレクトする方法

# 概要

Firebase Hosting（以下、FH）にはカスタムドメインが設定できます。
自分の好きなURLにFHを接続できるのですが、URLが```https://www.example.com```か```https://exmaple.com```かはサイトによってそれぞれだと思ます。
wwwの意味合いも薄れて、私も含めて後者が多くなっているとは思いますが、ユーザーが前者を入力することも十分考えられます。
そんなユーザーをwwwなしのURLに転送するにはどうすればいいかを説明します。
今回はwwwなしを正規URLとしますが、wwwありを正規URLとして、wwwなしをwwwありにリダイレクトする場合は設定を逆にすれば有効なはずです。

ただし、設定して結構時間がたつので、正直なところどのドキュメントを見てそう設定したのか忘れてしまいました:sob:
設定は正しいはずですが、その根拠についてはご自身で探してみてください。


# 読者対象

- 今後FHでカスタムドメインを設定する予定の方
- wwwのリダイレクト方法がわからず設定されてない方


# 実践

## Firebase Hosting側
まずは公式ドキュメントを読みましょう。
https://firebase.google.com/docs/hosting/custom-domain?hl=ja

安心してください。私も最初あまりのわけのわからなさにボー然としましたので:joy:
GUIに従って設定すれば、特に迷うことはないはずです。
設定の最後にDNSに設定するIPが表示されるのでコピっておきましょう。

![カスタムドメイン設定１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/66026614-8b4d-431d-6985-7a5d11ab2bc5.png)

設定終わると画像のようになりまして、ありがたいことにwwwへのリダイレクト設定を促すメッセージが表示されます:relaxed:
接続するを押すと以下の感じになります。

![カスタムドメイン設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/ca4120c1-cef2-ae6c-a119-27328e655adf.png)

wwwつきをwwwなしの正規URLにリダイレクトするだけの簡単な設定です。

![カスタムドメイン設定3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/4b4ea421-024e-2a46-84f2-1aec0569a8f3.png)

こうなればFH側の設定は終了です。


## Google Domains側

私はGoogle Domainsで購入したので、Google Domainsで設定を行います。
ドメイン購入元によって異なると思いますが、設定の本質は一緒だと思います。

wwwの転送設定として、正規URL用に設定した@のほうのIPと同じものを設定しています。

注意点としてIPを範囲指定するため二つ設定しなくてはならないのですが、デフォルトでは1つしか設定できないように見えるため、一つ設定したら赤の下線の＋ボタンを押し、2つ目のIP入力欄を表示するのがポイントです。

設定が終わったら、正規URLの方はかなり早く設定されたと記憶しています。
FHのステータスが”設定が必要です”から”接続されています”になればOK。
もちろんURL打ち込んでブラウザで表示されるか確認してもOK。
wwwの方については設定にてこずったので記憶があいまいですが、正しく設定した後1時間未満でリダイレクトできるようになったはず。


![GoogleDomains.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/92322319-c57e-803e-e839-3999f5e8e0df.png)

Google Domainsのヘルプへのリンクや？を見ながらこの設定にたどり着いたはずで、おそらく参考にしたのはこれ。
https://support.google.com/domains/answer/3251147?hl=ja
wwwの設定例があるので、IPv4用の設定を採用したのかなと。

そのほか参考として、詳細のアンカー先のレコードの関するドキュメント。
ここに＋ボタンを押下して入力欄を増やすことも書いてあります。
https://support.google.com/domains/answer/3290350?hl=ja

Google Domainsのウェブ転送機能を使えば、FHのリダイレクト不要かもしれないという記事。
FHがリダイレクトサポートしているので、利用しませんでしたがメモとして残しておきます。
https://support.google.com/domains/answer/4522141


おまけですが、Google Domains購入は@ezaqiitaさんの記事を参考にしました。
私も残しておこうと思ったのですが、ほぼ完ぺきだったのでストックさせていただいています。
https://qiita.com/ezaqiita/items/273fa46f7530836fe259
あえて補足するなら以下の二点
- 住所は英語入力のためローマ字で後ろから記入する形でググりました:sweat_smile:
- クレカ入力後のいずれかのボタン入力で1回目では画面変化が起きず2回押した。(1回目はクレカチェックか気のせい？)



# まとめ

Firebaseはシンプルなコンセプトで作られているため基本的には簡単ですが、ドメインについては購入元の設定が必要になるため、結構てこずったお話でした。
wwwのリダイレクト設定なくても、検索流入やリンクからユーザーが来る分には影響ないですが、しておくとさらにいいと思います。
困ってた方の助力にならたらこれ幸い:wink: