OmniAICreator/Qiita-1.07M huggingface dataset:
インスタグラムの投稿に自動でイイネをつける方法 - Python

[これでできた](https://off.tokyo/blog/instagram%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e8%87%aa%e5%8b%95%e3%81%a7like%e3%81%99%e3%82%8b-python/)
Dockerを用いたcronでの定時処理

ここ最近、すべてのアプリケーションをDockerに閉じ込めることに嵌まっています。

cron程度であれば、ホストのLinuxでやってもいいが、せっかくなのでDockerでやってみた。

# 実行環境
Windows 10
WSL
Docker version 17.03.2-ce

# 完成品
とりあえず完成品

```Docker:Dockerfile
FROM alpine
COPY myscript.sh /bin/myscript.sh
COPY root /var/spool/cron/crontabs/root
RUN apk --update add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata && \
    rm -rf /var/cache/apk/*
RUN chmod +x /bin/myscript.sh
CMD crond -l 2 -f
```

```shell:myscript.sh
#!/bin/sh
echo "Hello Qiita"
```

```:root
* * * * * /bin/myscript.sh
```

[**すべてのコード**](https://github.com/MIDORIBIN/dockercron)
# Dockerfile
ベースはalpine
実行したいシェルスクリプトとcronの設定ファイルをコピー
タイムゾーンを日本に変更
実行したいファイルに実行権限を付与
crondを実行

# 実行
`docker run --rm -d cron`

実行しているかを確認するためにログを確認
`docker logs container_name`

# まとめ
定時処理をdockerで実行できるようになった。
冒頭で書いた通り、ホストのほうのcronでやってもあまり変わらない気がする。
ただ、プロジェクトに依存するような定時処理の場合、dockerを用いたほうが管理しやすい気がする。

# あとがき
最初はWindows for Dockerでやっていたが、全く動かず３時間以上無駄にしてしまった。
権限の問題なのか、全く同じコードでもWindows for Dockerでは動かなかった。
Windowsでやる場合は十分ご注意を。
Array.Empty<T> メソッドが見つからない例外が発生する罠

実際に業務で発生した事例ですが、レアケースなのか日本語情報が無いため
初投稿の練習と覚書も兼ねて共有します。

#古い .NET Framework でも動くようにした
経緯としては、担当しているパッケージシステムが元々 .NET 4.5.1 をターゲットにしていたところを
Microsoft のサポート終了に伴い .NET 4.6.2 に変更。
しかし複数の客先に納品しているため、一部運用環境では .NET 4.5.1(or 4.5.2) のまま稼働していました。

.NET アプリはビルド時のターゲットより新しいバージョンの環境では基本的にそのまま動作しますが、
古いバージョンの環境で動かそうとすると[App.configに`supportedRuntime`を記述](https://docs.microsoft.com/ja-jp/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element)する必要があります。

当然、動作させたい最低バージョンでサポートされるクラスやメソッドしか使えませんが、
それを意識したコードを書いていても実際に動かすと例外が発生するのです。

#コンパイラが地雷を仕込んできた件
結論から言うと、可変長引数([`params`](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/params))を省略した際にコンパイラが .NET 4.6 以降でしか使えない
[`Array.Empty<T>`メソッド](https://msdn.microsoft.com/ja-jp/library/dn906179(v=vs.110).aspx)で補完していることが原因でした。

いくら自分で書いたコードを眺めても原因が判明しないわけです…

#対策
自前で可変長引数なメソッドを定義する場合は可変長引数を持たないオーバーロードも
用意しておくことで使う側は特に意識する必要がなくなります。

それ以外の場合で引数なしオーバーロードも無い場合は、面倒ですが引数に
`new string[0]`のように空の配列を明示的に指定するしかありません。
（nullを渡すのは危険）

[`string.Format`メソッド](https://msdn.microsoft.com/ja-jp/library/b1csw23d(v=vs.110).aspx)や[`StringBuilder.AppendFormat`メソッド](https://msdn.microsoft.com/ja-jp/library/cazfhf32(v=vs.110).aspx)などの
フォーマット系は引数を省略するような使い方はほぼしないと思いますが、
文字列の[`TrimStart`メソッド](https://msdn.microsoft.com/ja-jp/library/system.string.trimstart(v=vs.110).aspx)/[`TrimEnd`メソッド](https://msdn.microsoft.com/ja-jp/library/system.string.trimend(v=vs.110).aspx)は[`Trim`メソッド](https://msdn.microsoft.com/ja-jp/library/system.string.trim(v=vs.110).aspx)と同じような
使い方をすることが多いのに引数なしのオーバーロードがありませんので要注意です。
MacでHaskellを始める

https://qiita.com/takehilo/items/7b65d32e47510cd1fe48

こちらを参考に

```
brew cask install haskell-platform
```

すると、

```
Cask 'haskell-platform' is unavailable: No Cask with this name exists.
```

そんなものはないと言われる。

`cask` 抜きで `brew install` すると、

```
brew install haskell-platform
Error: No available formula with the name "haskell-platform"
We no longer package haskell-platform. Consider installing ghc,
cabal-install and stack instead:
  brew install ghc cabal-install stack
```

`brew install ghc cabal-install stack` じゃない？ と言われたので、

```
brew install ghc cabal-install stack
```

Haskell環境をインストールできた。

```
ghci
GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
Prelude>
```

`ghci` で対話式コンソールを起動できる。

# 追記

コメントでstackの方が良いと教えて頂いたのでその場合。

```
brew install stack
stack setup
stack path
```
ここまで完了したら、`stack exec ghci` もしくは `stack ghci` でREPLを開ける。

```
stack exec ghci
GHCi, version 8.6.3: http://www.haskell.org/ghc/  :? for help
Prelude>
```
python pipenvによるパッケージ管理

# 概要
- 目的：pipenvによるパッケージ管理の基本
- 環境
    - windows10
    - VSCode
    - Python 3.6(32bit)
- 参考サイト
    - [1].[Windows + Python 3.6 + PipEnv + Visual Studio Code でPython開発環境](https://qiita.com/youkidkk/items/b6a6e39ee3a109001c75)
    - [2].[Pipenv: 人間のためのPython開発ワークフロー](https://pipenv-ja.readthedocs.io/ja/translate-ja/)

# インストールと設定
参考サイト[1]のPipEnvの項目通り
[Windows + Python 3.6 + PipEnv + Visual Studio Code でPython開発環境](https://qiita.com/youkidkk/items/b6a6e39ee3a109001c75)

# コマンドラインから基本的な使い方

```
プロジェクトのレポジトリをクローンまたは作成する:
> cd myproject
Pipfileがあった場合には、Pipfileの内容でインストールする:
新規の場合はpipfile, .env が作成される
> pipenv install
パッケージインストール
> pipenv install <package>
シェル有効化、Pythonのパスの確認
> pipenv shell
> python --version
> which python
↑仮想環境のPythonであることを確認
```
VSCodeの複数ファイル、複数行、置換について

# はじめに
初投稿になります。
普段見習いマークアップエンジニアとして仕事をしています。

~~今までずっとVSCodeをエディタとして使っていたのですが今回複数のファイルで、複数行のコードを、置換で削除したい、という場面に初めてあたり、とりあえずの解決策を自分用忘備録として残しておきます。~~

### ※October 2018 (version 1.29)にてMultiline search実装されました！！！
やっと標準機能として正規表現の改行などがファイル内検索で実装されました。
以下の文章は一応残しておきます・・・ 


## 単体のファイル内ではできるけど・・・
削除したい対象のコードが下記だとすると

```hoge.html
<div>
  <p>hogehoge</p>
  <p>hogehoge</p>
</div>
```
cmd + Fで検索置換画面を開き、正規表現を使うモードを選択して改行正規表現\nを使い

```
<div>\n  <p>hogehoge</p>\n  <p>hogehoge</p>\n</div>
```
これで一致出来ます。


## フォルダ内検索では使えない
shift + cmd + F のフォルダ内検索ではこの表記が使えなくて困りました。
vscodeのgithubを見てみると同じように困っている人がいるみたいですね。
https://github.com/Microsoft/vscode/issues/13155

# 結論
結果的に他のエディタでは普通にできるみたいなのでSublime Textで対応しました。
なぜVSCodeでは対応していないのでしょうか・・・
外部エディタを使うのはスマートではないのでVSCode好きな私にとっては早く対応してほしいです。
（2018/08/18現在）

いや実はできるよ、または拡張機能でできるよ的な情報があれば教えて頂けると幸いです。
Pure-ftpdでUmaskの設定方法

```
cd /etc/pure-ftpd/conf
echo 117 007 > Umask
```
ファイル、フォルダの順。
おしまい。

#Ref
https://wiki.hetzner.de/index.php/PureFTPd/en
http://blogpmenier.dynalias.net/docext/pureftpd/pure-ftpd.conf
Docker multi-stage buildsでのmaintainerとかのlabelの記述場所は少しだけ注意

[Docker multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) で、`LABEL maintainer="..."` を記述する位置に関するちょっとした注意点です。

以下のように最後の`FROM`の後に書く必要があるようです[^before_or_after]。

[^before_or_after]: `FROM`の前でもいいのかも？そこは未検証です。

```dockerfile
FROM ...

...

FROM ...
LABEL maintainer="..."

...

```

最初の`FROM`の後ろに`LABEL maintainer="..."`を書いてしまうと、ちゃんと`LABEL`が残らないことに気づきました。公式の<https://docs.docker.com/develop/develop-images/multistage-build/>では`LABEL`に触れていなかったので、僕と同じく気づかずに使っている人もいるかも知れないと思って記事にしました。（なんとなく`LABEL`は全体に反映されてくれるかなと思ってました。）

## おまけ: `LABEL`の確認方法

ビルドしたイメージの`LABEL`の確認方法は以下できました。

```
docker inspect --format "{{.Config.Labels}}" <イメージ名とかコンテナとか>
```

```:出力例
map[maintainer:Ryo Ota <メールアドレス>]
```

(参考：<https://stackoverflow.com/a/33884893/2885946>)
海賊版サイトへのDoS攻撃を考える

# 言いたいこと

誰にも迷惑をかけないDoS攻撃なんて無いので、安直に攻撃しようとか言うの良くないと思います

# 海賊版サイトへのDoS攻撃

2018年 8月 10日、インターネット上の海賊版対策として海賊版サイトへ "アクセス集中方式" による対策を行う、という資料 ([知的財産戦略本部･インターネット上の海賊版対策に関する検討会議への提案](https://www.kantei.go.jp/jp/singi/titeki2/tyousakai/kensho_hyoka_kikaku/2018/kaizoku/benkyoukai/siryou11.pdf)) が提案されました。

いろいろとツッコミどころのある
おもしろ
資料なのですが、実際に「アクセス集中方式」と称して悪質サイトへDoS攻撃を打ち込む場合に気にしなければならないことを考えてみました。

なお、法律的な領域でも多分にツッコミどころがあるかとは思いますが、法律については無知甚だしいので本記事では言及しません。

## そもそもDoS攻撃は有効なのか

いきなり大事なところですが、**たぶん有効じゃない**です。

海賊版サイトの構成について詳細に調べた記事 ([
漫画違法配信サイト「漫画村」の黒幕に迫る](https://blog.cheena.net/179)) がありますので、これを参考にさせてもらいます。

海賊版サイトは防弾ホスティングサービス (法律的に手が出しづらいホスティングサービス) 上にWebサーバを構築し、さらにCDNを利用してアクセス集中への耐性を高めています。
海賊版サイトはほぼ静的コンテンツで構成されており、リクエストはCDN事業者のサーバで終端してしまいます。

CDNを経由されるとDoS攻撃を成立させるのは非常に難しく、攻撃者であればCDNへ攻撃するのではなく、あの手この手でCDNを経由させず直接サーバへリクエストを届ける方法を考えるほうが多いのではないでしょうか。

![zu1.png](https://qiita-image-store.s3.amazonaws.com/0/31124/d3dd8820-13f0-9214-f358-b784c662b15a.png)


CDNを経由されると攻撃が難しい点は提案資料でも触れられており、アクセス集中方式への回避策として「CDNの利用」が挙げられています。 
ダメってわかってんじゃん……


![access.png](https://qiita-image-store.s3.amazonaws.com/0/31124/6ddf6e6f-c98d-7d75-a167-7e8d5580454b.png)
*知的財産戦略本部･インターネット上の海賊版対策に関する検討会議への提案 より引用*


## 「アクセス集中方式は迷惑をかけない」は真なのか

### CDN事業者のサーバを落としたら

前述のようにCDN事業者のサーバを落とすことは非常に難しいのですが、仮に落とせた場合はおそらくアクセス集中させたIPアドレスが「攻撃を行ったアドレス」としてブラックリストに入ることでしょう。
このようなブラックリストはCDNのみならず様々なファイヤーウォールにて共有される可能性があり、インターネットから閉め出される可能性があります。 **ブラックリスト入りする可能性があるIPアドレスを誰が提供できるのか？** という点は考えなければいけません。

また、落とされたCDN事業者を利用している別のWebサービスへ影響が出る可能性もあります。
CDN事業者は別に悪の組織でもなんでもありませんし、落とした場合は被害を受けた別のWebサービスから提訴される等の法的リスクがあるでしょうが、初めに述べたように法的リスクについては言及しません。

### 帯域を圧迫するDDoS攻撃を行ったら

仮にサーバへリクエストを到達させた場合、どのようなDoS攻撃を行うかで影響が変わります。
現在使われるDDoS攻撃手法の多くは帯域を圧迫する、ネットワークへの攻撃です。このタイプの攻撃はIPアドレスを偽装できるメリットが有り、アドレスを偽装すればブラックリスト入りすることもありません。

ただし、IPアドレスを偽装した攻撃は**インターネットのどこかへゴミパケットを投げつける**ことになります。
![zu2.png](https://qiita-image-store.s3.amazonaws.com/0/31124/22b2e7dd-2061-501f-6c09-140e6f9f2fe4.png)

このようなゴミパケットでどのような影響が出るかはなんとも言えませんが、あまり行儀の良い行いではないでしょう。
これらのゴミパケットを監視することでDDoSの発生を通知するセキュリティ専門家もおり、別の攻撃者にとって都合の良い目くらましのような働きをしてしまうかもしれません。

また、ネットワーク機器をターゲットにした攻撃ですので、当然のようにインターネット通信事業者(ISPの設備とか)には負荷がかかります。

# おわりに

400万人におよぶエンジニア集団の皆様は大変そうですが頑張ってください。
psqlコマンドでレコードの値だけをCSV形式で出力させる

# ペインポイント

* Ansible等でデータベース上の値だけをさっと取り出したいことがある。
* しかし他のオプションなしで `psql -c "${SQL}"` を実行すると下記のような出力になる。。

```
 pg_encoding_to_char | datcollate 
---------------------+------------
 UTF8                | C
(1 row)
```

# やりかた
```bash
psql --no-align --tuples-only -F, -c "${SQL}"
```

`-F,`は区切り文字を指定するオプションなので、「|」のままで良ければ不要。

もしくは、一文字オプションを使って

```bash
psql -At -F, -c "${SQL}"
```

e.g.

```bash
$ sudo -u postgres psql --no-align --tuples-only -F, -c "select pg_encoding_to_char(encoding), datcollate from pg_catalog.pg_database where datname = 'template1'"
UTF8,C
```
Rubyで時間を15分刻みで丸める ( 切り上げ / 切り捨て )


[rounding](https://github.com/brianhempel/rounding) という gem を使えば楽。

```ruby
# gem install rounding
require 'rounding'

Time.parse('2018/08/18 0:49 +09:00')
# => 2018-08-18 00:49:00 +0900

# 15分刻みで切り上げ
Time.parse('2018/08/18 0:49 +09:00').ceil_to(15.minutes)
# => 2018-08-18 01:00:00 +0900

# 15分刻みで切り捨て
Time.parse('2018/08/18 0:49 +09:00').round_to(15.minutes)
# => 2018-08-18 00:45:00 +0900
```

> Rounding is compatible with ActiveSupport's Time extensions, but also works fine without ActiveSupport.

`ActiveSupport` の `Time` とも互換性があるとのこと。

[rounding](https://github.com/brianhempel/rounding)  は時間だけでなく、数値全般を扱える強力な `gem` なのでとても便利そう。

## 参考

brianhempel/rounding: Round by any arbitrary step in Ruby.
https://github.com/brianhempel/rounding
私がプログラミングを始めて２ヶ月間勉強したこと！(webアプリケーション作成)

<h2>私は何者か？</h2>
<p>高卒20歳の至って普通の会社員です。プログラミングを始めたきっかけは、情報系の専門学校に通っている友人がマークアップ言語をやっていてそこに興味を惹かれたのが１つ。それでWebアプリケーションを作りたいと思う。<br>もう１つは、働き方です。その働き方の部分に関しては別の投稿で…<br>そんなこんなあり、プログラミングを勉強してエンジニアを目指しています！</p>
<p>１ヶ月を約４週間として書いていきます!後、筆者は会社員なので平日勉強時間に制限があります。</p>

<h3>初めの１～２周間</h3>
<ul>
 <li>オンラインプログラミング学習サービスを使用しHTML/CSSの基礎を勉強</li>
 <li>特にお世話になったのは、dotinstallその次にProgate</li>
</ul>
<p>ドットインストールで動画を見ながら実際にAtomエディタを使用して動画道理の内容を作る。<br>こうすることによって実際に手を動かしてコードを書くので自然とコードが書けるようになってくるし、要素の意味も分かってくる。この時点では完全に理解しなくていいけどレッスン中は分かっておいたほうが良い。<br>ドットインストールで書き終わったコードは自分でいじって遊んだほうがますます理解につながるのでgood!!!</p>

<h3>中間3～4周間</h3>
<ul>
 <li>ドットインストールでjavaScriptの基礎をざっとやる。if文だったりメソッド、関数etc...</li>
 <li>ドットインストールのレッスンでjavaScriptのモーダルウインドウ、スライドショーを作る。</li>
</ul>
<p>私がjavaScriptを学ぶ上で注意したことは、基礎を学ぶときもしくは処理を書く時に自分用にコメントを残すという事をしました。<br>コメントを残しておくメリットとしては、そのコードを見たときにどのような処理をしているかを明確にするため。<br>また、コメントを書いている際に自分がどの程度理解できているか理解度チェックにもなります。</p>

<h3>２ヶ月目１週間～２週間</h3>
<ul>
 <li>javaScriptが終わった段階でMacで環境構築を行う</li>
 <li>ドットインストールのローカル開発環境の構築をみて実際に構築する(キツイなって言う方はCloud9で！)</li>
 <li>UNIXコマンド入門を一通りやる(ここめっちゃ重要)</li>
 <li>ローカル開発環境でドットインストールのRubyレッスンをこなす</li>
</ul>
<p>ローカル開発環境の構築は初心者の方にはかなり難しいと思います…ですが、ここで開発環境の構築ができるとかなり成長できます！開発環境が整ったらその環境でUNIXコマンドの入門ができますし、後々役に立つこと間違いないです！</p>

<h3>２ヶ月目3週間～4週間</h3>
<ul>
 <li>ProgateにてRubyonRailsコースを完走</li>
 <li>Progateでも、参考書でもいいので写経をしてみる(丸パクリはダメよ)</li>
</ul>
<p>いま筆者がいる地点ですね、ProgateのRailsコース完走後Progateの写経を行っています！（道場コースというものがあり道場コースの情報のみでがんばっています。）ここではRailsで必要となるMVCの関係性などの理解を深めていっています。<br>写経が終わったらHTML/CSS/JSを中心にいじって遊ぼうかなと笑</p>

<h2>最後に！</h2>
<p>人生初ブログ？でしたが、かなり楽しめながら書けました笑<br>自分の中で分かっていると思うものを実際にブログなどで書くと、「あれ？分かってないじゃん！」と思うこともあり勉強不足だなと痛感しています…<br>ですが頭の中にある思いや、自分を振り返るのにこういった形で発信、記録できるのは素晴らしいと思っています！<br>まだ書き足りないのですが、今回はこのへんで！<p>
<a href="https://twitter.com/improve_in_Ruby" target="_blank">私のツイッターです！よかったら！</a>
ProgateのJqueryを完走して多くミスした点

# ProgateのJqueryを完走して多くミスした点
## ;を忘れる
僕はPythonを学習してからjsに触れたので初めて3日間ほどは本当に多く忘れました...

## });を忘れる
これも本当に多く忘れました...
ただVscodeに},)に色を付けてくれる拡張機能があるらしいので有効活用していきたい！

こんなの↓
![3793e3a7c6e3b22ca14891767ef1cfdb.png](https://qiita-image-store.s3.amazonaws.com/0/281860/e9fd4472-c0f3-ff7b-d1fd-e10f20443216.png)

## addClass,removeClassの引数で""を付け忘れる
```Javascript
$(function() {
  $("test").hover (
    function() {
      $("test").addClass(".show"); //←をよく
    },
    function() {
      $("test").removeClass(.show); //このように""を忘れてしまう
    }
  );
});
```
## まとめ&感想

Jqueryを学習したことでできる幅が大幅に広がったと思う。
これらのミスもガンガンコードを書いて少しずつでもいいから減らしていきたい(#^.^#)
とりあえずホームページ作ります！
最後まで読んでくれてありがとうございました！(´∀｀)
初めて書いたQiitaなので意見や感想をtwitterのリプで送ってくれたら本当に嬉しいです！
Angularで、ERROR TypeError: Cannot read property 'city' of undefined

#概要

[前回の【エラー解決】Angularでerror TS1005: ',' expected.のエラーの解決](https://qiita.com/SatoMaru/items/c774b11a1e09d43432e7)
に引き続き、Angularのエラーについて。

今回はGoogle Chromeのデベロッパーツール（検証モード）でエラーが出たので、その解決方法を書きます。

####エラー内容
<font color="OrangeRed">ERROR TypeError: Cannot read property 'city' of undefined</font> 

**'city'** の中は、人それぞれプロパティ命名が違うことに注意。

<img width="1303" alt="AngularStarter.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/3e0b422d-a463-a198-87f2-184167a9b8d2.png">

このエラーが出た場合は、以下のように解釈すると良い。

<font color="red">プロパティが存在しないため、<font color="red">city</font> プロパティを読み取れません。</font> 

<font color="red">つまり、cityプロパティの前の上位のオブジェクトを疑ってみる。</font>

このエラーの場合、Google Chromeのデベロッパーツール（検証モード）上で、(RentalListItemComponent.html:5)とあるので、このファイルの中から、
cityプロパティを探します。

<img width="856" alt="rental-list-item_component_html_—___bwm-project_bwm-ng.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/ada858c3-2b14-6bc5-9593-9b662b1c0790.png">

.（ドット）で繋いでいる、<font color="red">currentRental</font>が違っていたため、エラーが出ていた。

ここを変更して解決できました。
Github/Bitbucket で ssh 接続ができなくなった場合の対処法

# 対象読者
Github や Bitbucket で SSH 接続で普通に使えていたのに、急に SSH 接続ができなくなって対処に困っている方。言い換えると、public key が Github / Bitbucket 側に登録されているのに接続できない状況で困っている方。

# 原因及び対処法の概要
- 原因 
    - ローカル PC 側で private key を認識出来ていないこと。
- 対処法
    - ローカル PC の SSH Agent に private key を認識させれば良い。

# 具体的な対処法
- Windows --- PuTTY 前提
    - PuTTY のアイコンをダブルクリック
    - 表示される Key リストに private key が表示されていないことを確認する
    - 下部の Add Key ボタンをクリックして、Github 等のサービスに登録している public key のペアである private key を読み込む
        - Linux や Mac のように決まったパスに鍵が保存されているわけではないので注意
    - 表示される Key リストに private key が追加されたことを確認する

- Linux, Mac
    - terminal で `ssh-add -l` を実行し, private key が登録されていない事を確認する
    - terminal で `ssh-add ~/.ssh/<private_key_file>` のコマンドを実行する
        - Linux, Mac の場合は ssh key は ~/.ssh/ に保存されている
        - Github 等のサービスに登録している public key のペアである private key を読み込む
    - 再び `ssh-add -l` を実行し, private key が登録された事を確認する

# 参考リンク
- ここに書いてありました
[Troubleshoot SSH issues (Bitbucket の公式ページ)
](https://confluence.atlassian.com/bitbucket/troubleshoot-ssh-issues-271943403.html)

- SSH の基本知識　@tag1216 さんの記事が参考になりました
[インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識](https://qiita.com/tag1216/items/5d06bad7468f731f590e)
Mysql リファレンス

自分が学習していて主につまずいたこと、忘れないようにするための備忘録。
スペック　rails 5.0.6

起動
```$ sudo service mysqld start```
起動状況確認
```$ sudo service mysqld status```
停止
```$ sudo service mysqld start```

Mysqlへ接続
```$ mysql -u root```
切断
```mysql> exit```
データベース一覧の確認
```mysql> SHOW databases;```

データベースの作成
```mysql> CREATEデータベース名;```

データベースの削除
```mysql> DESTROYデータベース名;```

操作したいデータベースを選ぶ
```mysql> USE データベース名;```

テーブルの中身を確認
```mysql> describe テーブル名;```
技術書典のサークル位置をBrainf**kのAAで伝える方法

## 目的
技術書典5に出展するので、サークルの位置をわかりやすく知らせたかった。
プログラマーとしてプログラムで伝えよう。

## 参考文献

* [Brainfuck 派生言語 generator の Orenono gem で Brainfuck を構成する文字を基本命令とする Brainfuck 派生 Brainfuck 言語を作成し、 Brainfuck 派生 Brainfuck 言語 の Ascii Art のプログラムから Brainfuck で Brainfuck という文字列を出力するためのソースコードを標準出力する #ゲシュタルト崩壊 - Qiita](https://qiita.com/tbpgr/items/125b946c001b3c9d483a)

## U17を出力する Brainf**k のコード
```
++++++++++[>++++++++<-]>+++++.------------------------------------.++++++.
```

## Brainf**k のコードを生成する Ruby のコード
Ruby で Brainf**k のコードを生成します

```ruby
template = DATA.read.gsub("\n", '')
bit_template = template.chars.map { |e|e == 'X' ? 1 : 0 }

answer_bf = "++++++++++[>++++++++<-]>+++++.------------------------------------.++++++."
answer_bf_bytes = answer_bf.chars

dummy = '='
results = []
last = false
loop {
  bit_template.each do |char|
    c = (char == 0) ? ' ' : last ? dummy : answer_bf_bytes.shift
    results << c
    last = true if answer_bf_bytes.size == 0
  end
  break if last
}

print results.each_slice(24).map { |e|e.join + "\n" }.join

__END__

 XXX XXX    X     XXXXX 
  X   X   XXX     X   X 
  X   X     X         X 
  X   X     X        X  
  X   X     X        X  
  X   X     X       X   
  X   X     X       X   
  X   X     X      X    
   XXX    XXXXX    X    

```

## 出力コード
```
 +++ +++    +     +++[> 
  +   +   +++     +   + 
  +   <     -         ] 
  >   +     +        +  
  +   +     .        -  
  -   -     -       -   
  -   -     -       -   
  -   -     -      -    
   ---    -----    -    
                        
 --- ---    -     ----- 
  -   -   .++     +   + 
  +   +     .         = 
  =   =     =        =  
  =   =     =        =  
  =   =     =       =   
  =   =     =       =   
  =   =     =      =    
   ===    =====    =    
                        
```

## 実行結果
```
U17
```

* https://ideone.com/dHtTU5
Node.jsからC++のクラス・関数をSWIGを使って楽して扱う

Node.jsからC++の関数やクラスを扱いたいことがある。例えば、C++で書いたコードのGUIをElectronやNw.jsで書きたいときなど。

一般に、NodeからC++のコードを呼ぶ際は、Node-ffiが使われているようだ。しかしながら、[チュートリアル](https://github.com/node-ffi/node-ffi/wiki/Node-FFI-Tutorial)を読んでみると、何やら書く気が雲散霧消してしまう面倒さである。

PythonやRubyからC/C++の関数を呼ぶバインディングの作成ツールとしては、[SWIG](http://www.swig.org/)が知られている。実はこのSWIGを使えば、Javascriptのラッパも手軽に書くことができる。

## インストール
SWIGの安定版は3.0.12だが、これはNode 7以降に対応していない。[Github](https://github.com/swig/swig)の開発版を使おう。なお、ライブラリのビルドにはNode-gypが必要なので、なければnpmからインストールする。

    wget https://github.com/swig/swig/archive/master.zip
    unzip master.zip
    cd swig-master
    ./autogen.sh
    ./configure
    make
    sudo make install

## ラッパを書く
練習に、次のコードをNodeから読んでみよう。

complex.hpp:

    #include <string>
    
    struct complex
    {
        complex(double r=0,double i=0);
        double re;
        double im;
        double abs()const;
        std::string to_str()const;
    };

complex.cpp:

    #include <cmath>
    #include "complex.hpp"
    
    complex::complex(double r,double i): re(r), im(i) {}
    double complex::abs()const{ return std::sqrt(re*re+im*im); }
    std::string complex::to_str()const{ return std::to_string(re)+"+"+std::to_string(im)+"i"; }

例えば、このコードが以下のJSから呼べたら素敵ではないだろうか。

complex.js:

    const Complex=require('./complex.node').complex;
    
    let z=new Complex();
    console.log(z.abs()); // 0と表示してほしい
    z.re=3;
    z.im=4;
    console.log(z.abs()); // 5と表示してほしい
    console.log(z.to_str()); //3+4iのような表示を期待

SWIGを使えば、これだけのラッパを書くだけで良い。

complex.i:

    %module complex // 外から見えるモジュールを定義
    %{
    #include "complex.hpp" // この中の関数が外から見える
    %}
    
    %include "std_string.i" // これを書いとけばいい感じにstd::stringをJSの文字列にラップしてくれる
    %include "complex.hpp"

あとは、ビルド用にbinding.gypを書き、SWIGを実行してビルドするだけ。

binding.gyp:

    { "targets": [ { 
        "target_name": "complex",
        "sources": [ "complex.cpp", "complex_wrap.cxx" ]
    } ] }

実行する。

    swig -javascript -node -c++ complex.i
    node-gyp configure build

できたcomplex.nodeを適当な場所に移して、`node complex.js`を実行すると……

    0
    5
    3.000000+4.000000i

簡単！
Rails初心者_DB設計の基礎を学ぶ①

Railsを勉強して、いざwebサービスを開発しようとなった段階で、DB設計について何も分からない状態の自分に気づいたので、Railsと並行して勉強しているDB設計の基礎についてまとめていきたいと思う。

#そもそもデータベースの「データ」って何？
データベース設計を学ぶ前にそもそもデータって何？

データ＝あるフォーマットに揃えられた事実の事。

例えば、Userをデータ化しようとした時に考える事として、どのような属性を定義するかを考える必要がある。それは、氏名、年齢や職業、好きな食べ物や好きな音楽だったりする。

それら定義したデータをある文脈や視点から加工したり、集約したりしたものが「情報」となる。

自分は音楽が好きなので、「Spotify」のレコメンド機能を例に挙げると、ユーザーがストリーミング再生した音楽の履歴データそれ自身は「この日、このユーザーはこういう音楽を何分間聴いた」という事実を語っているに過ぎない。

しかし、サービス提供者は、次々とユーザーの好みの音楽を紹介し、アプリの滞在時間を伸ばして、サブスクリプション契約までコンバージョンさせたいと考える。

「このユーザーのアプリ滞在時間を伸ばし、サブスクライブする為に、どんな音楽をレコメンドすれば、良いだろう？」という問いがあったとして、それに対する答えが「情報」となる。

それはただ単にデータを眺めていても答えを導き出すことはできない。すなわちデータがないとそもそもその答えを導き出す仮説も生み出すことができない。

「このバンドが好きなユーザーは他にどんなバンドを好きになる傾向があるか」、「どのような時間帯にどんな音楽を聴くのか」など、データと分析、解釈を合わせて、初めて情報が浮かび上がってくる。

自分たちが日々使っているあらゆるwebサービスは自分自身のデータを提供しながら、色々な情報を受け取っている。

ユーザーに有益な情報を提供する為にもデータベース設計はちゃんと理解しないといけないなと思ったところで今回は終わります。
timeout-decoratorを利用して自作関数にタイムアウトを設定する

# やりたいこと
自作関数でタイムアウトを設定して、時間内に終了しなければ別の処理を実行させたい
ちょっと調べたら`timeout-decorator`に出会って使い勝手がよかったので、紹介したいと思います


# 前提
- python 3.5.2
- time_decorator 0.4.0

# インストール
`$ pip install timeout-decorator`

# 使い方
## 1. 固定値で関数にタイムアウトを実装
`@timeout(5)`というように値を設定すればよいだけ

```py3
#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
Time out test 1
"""

import time

from timeout_decorator import timeout, TimeoutError

@timeout(5)
def func():
    """func"""
    for i in range(0, 10):
        print("i :%d" % i)
        time.sleep(i)

def callback():
    """callback"""
    print("callback")

def main():
    """
    main
    """

    try:
        func()
    except TimeoutError:
        callback()

if __name__ == "__main__":
    main()
```

## 2. タイムアウト値を変数で受け取る場合
関数内関数を利用して、タイムアウト値を引数で変更できるようにしています。

```py3
#!/usr/bin/env python

"""
Timeout test
"""

import time

from timeout_decorator import timeout, TimeoutError


def run_func_with_timeout(timeout_sec, func, *args, **kargs):
    """
    run func with timeout
    """
    print("timeout sec: %d" % timeout_sec)

    @timeout(timeout_sec)
    def target(*args, **kargs):
        """target"""
        func(*args, **kargs)
    target(*args, **kargs)

def func_test(inputs):
    """
    test
    """

    print("inputs = %d" % inputs)

    for i in range(0, 100):
        print("i: %d" % i)
        time.sleep(1)

def callback():
    """callback"""
    print("callback")

def main():
    """
    main
    """

    try:
        run_func_with_timeout(func=func_test,
                              timeout_sec=5,
                              x=5)
    except TimeoutError:
        callback()

if __name__ == "__main__":
    main()
```
Dockerコンテナ内でVSCodeを起動する(Ubuntu)

#はじめに
dockerコンテナ内でVSCodeを起動することができたので、方法を記したいと思います。

VSCodeの拡張機能を使ってdockerコンテナで動くコードをリモートデバッグする方法は以下の記事に載っていますが、個人的には今回紹介するようにdockerコンテナ内でVSCodeを起動する方がシンプルで好みです。
https://qiita.com/Ryuichirou/items/6327ab5012ca1729d72f

#Dockerfile
Dockerfileの内容について説明します。

###ベースイメージとワークディレクトリの指定
この部分は本筋とは関係ないので、お好きなように。

```
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04

WORKDIR /root
ENV HOME /root
```

###apt-get

必要なパッケージをapt-getでインストールします。
gdebiは、debパッケージを依存関係を解決しながらインストールするためのツールです。

```
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    wget \
    git \
    libssl-dev \
    libbz2-dev \
    libsqlite3-dev \
    libreadline-dev \
    zlib1g-dev \
    libasound2-dev \
    libxss1 \
    libxtst6 \
    gdebi
```

###VSCodeのインストール
```
RUN wget -O vscode-amd64.deb https://go.microsoft.com/fwlink/?LinkID=760868
RUN yes | gdebi vscode-amd64.deb
RUN rm vscode-amd64.deb
```

###pythonのインストール
pyenvを使ってpythonをインストールします。
と言っても、本記事の内容はpython以外の言語にも簡単に適用できるでしょうし、また、pythonのインストールはpyenv以外の仕組みを利用しても構いません。

```
RUN git clone https://github.com/yyuu/pyenv.git ~/.pyenv
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
RUN pyenv install 3.6.6
RUN pyenv global 3.6.6
```

#dockerイメージのビルドとコンテナの起動
###イメージのビルド
```
nvidia-docker build -t kanosawa/vscode .
```

###コンテナの起動
以下の記事を参考にさせていただきました。
[Dockerコンテナの中でGUIアプリケーションを起動させる](https://unskilled.site/docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E4%B8%AD%E3%81%A7gui%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%95%E3%81%9B%E3%82%8B/)

```
xhost local:
nvidia-docker run -e DISPLAY=$DISPLAY \
                  -v /tmp/.X11-unix:/tmp/.X11-unix \
                  -it kanosawa/vscode
```

#コンテナ内でVSCodeを起動する
VSCodeをsuper userで起動する場合、以下のオプションが必要なようです。
起動した後は、ポップアップに従ってPython拡張機能をインストールすれば、デバッグ実行可能になります。

```
code --user-data-dir
```

#おわりに
以上の手順で、Dockerコンテナ内でVSCodeを起動できるようになります。

書いた後に読み返してみると、タイトル通りの内容というよりは「DockerfileでVSCodeをインストールする方法」と「Dockerコンテナ内でGUIアプリケーションを起動する方法」の合わせ技でしかないですね。。。
CSSで要素を上下方向に中央寄せしたいときにはFlexboxを使うと良い

Webメディアを開発しているとぶち当たるであろう「どうやって縦方向にセンタリングすればよいのかわからない」問題に対する処方箋です。

インライン要素であれば、`vertical-align: middle`で解決するかもしれません。
しかし、ブロック要素の縦方向での中央寄せは一筋縄にいかず、`table-cell`を利用した解決策などHackyなテクニックが生み出されてきました。

しかし、いまではFlexboxを使うことでとても簡単に実装できます。
現代のモダンブラウザには、ほぼすべてのブラウザにFlexboxが実装されているため、Flexboxを利用した方がよいと思われます。 [^1]

以下にコード例を示します。[^2]

```html

<div class="parent-elem">
  <div class="child-elem">
    ...
  </div>
</div>
```

```scss

.parent-elem {
  display: flex;
  align-items: center; /* 縦方向のセンタリング */
  justify-content: center; /* 横方向のセンタリングもついでに */
}

.child-elem {
  /* 特定の小要素だけをセンタリングしたい場合は親要素にalign-itemsを当てるのではなく、こちらを使うとよい */
  align-self: center;
}
```

[^1]: FlexboxにバグがあるIE11に対応する必要があるのならば、[polyfill](https://github.com/zloirock/core-js)をいれることをオススメします。
[^2]: [CodepenでSampleも書いておきました。](https://codepen.io/otakumesi/pen/WKVOme)
スクレイピングの学習 Python3系 その1

#とりあえず何か動かしたい
progateでPython入門を一通り終えたが、これだけで何か作れる感じがしない
↓
とりあえず何か動かそう
↓
ググった感じ簡単なスクレイピングなら出来そう

#やること
ニュースサイトから記事タイトルとリンク先urlを取得

#手順
- 環境はGoogle Colaboratory(ローカルに環境を整えなくても試せるから)
- ランタイムのタイプはPython3系(そっちのが良さそうだったので)
- 対象とするサイトを決定(日頃見てる[ニュートピ](https://newstopics.jp)にした)
- 各種モジュール等を使って取得していく

#書いたコード
```python:
# coding: UTF-8
import pandas as pd
from bs4 import BeautifulSoup
import requests

# アクセスするURL = ニュートピ
url = "https://newstopics.jp/"

# htmlを取得、BeautifulSoupで扱う
r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser') # BeautifulSoupの初期化

# aタグの中から、class=titleの含まれたものを取得
tags = soup.find_all("a", {"class": "title"})
# データフレームを作成。列名 name=記事名, url=url
columns = ["name", "url"]
df = pd.DataFrame(columns=columns) 

# 抽出したa要素を行列に入れ込む
for tag in tags:
    name = tag.string #　記事名の取得
    url = tag.get("href") #リンクの取得
    se = pd.Series([name, url], columns) # 行を追加
    print(se)
    df = df.append(se, columns)
```

# 補足
`# coding: UTF-8`←これよく分からない。必要っぽいのでつけた。

```python:
import pandas as pd
from bs4 import BeautifulSoup
import requests
```
必要な機能をimportしている。各モジュールの機能についてはググるとめっちゃ解説してるサイトが大量にある。

# 詰まったところ
- 頻繁に`invalid character in identifier`が出た。
日本語入力でスペースとか打ってるらしい。一旦消して書き直すとほぼ治る。
- コードには残らなかったが、リストを記事ごとに作られているdivから作った。for文でその中から再度aタグを取り出すなどした。でも普通にaタグから取得した方が無駄がないと思って切り替え。そしたら↓のエラー。
- 結構な時間`'NoneType' object has no attribute 'string'`でハマった。aタグしか入れていないリストの要素からaタグを取り出そうとしていたのが問題っぽい。

```python:
# エラーの出てたコード
name = tag.a.string #　記事名の取得
url = tag.a.get("href") #リンクの取得

# 解消したコード
name = tag.string #　記事名の取得
url = tag.get("href") #リンクの取得
```

# 次回への課題
- 法律周りの確認
- CSVでダウンロード
- 1時間に1回取得などの動き
- 重複する内容を取得しないようにする
- 次ページ以降の取得
- 元リンクを取得
- ローカル環境で動かす
Java Script  promptメソッド

**prompt**
ユーザーに入力を促すメソッド。JavaScriptだと入力用のダイアログボックスを表示する。console.logと違う点は、promptメソッドはユーザーがキーボードから何かを入力したら、その結果の文字列を返してくれるという点。
注意する点はpromptメソッドの戻り値は内容が数字であっても常に文字列で返ってくる点である。
なので整数化するためにはconsole.log(parseInt(変数)+数値);としなければならない。
RuntimeExceptionとLogicException

どちらもExceptionを継承したもの。

- RuntimeException
phpが実行されているときになげられるもので、運用で通常発生するエラー（バリデーションエラーなど）に使用。

- LogicException
本来発生しないエラーに対して使用。本来発生しないとは、プログラムを書き間違えたなどのバグ（不具合）のこと。

※フォームが入力されたかどうかのバリデーションではなく、DB接続できなかったときや、ファイルアップロードできなかった場合など、コードを実行されて初めてエラーになるかどうかわかるもの（成功する場合もエラーになる場合もあるもの）に対してつかう。

>[ウェブカツ！！](https://webukatu.com/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
phpMyAdmin on ECSからのRDS接続がとっても簡単

# はじめに

RDSはVPCで閉じられた環境のため、EC2などを踏み台にして、RDSに接続するみたいなことが多々あります。
また、MySQLをGUIで操作できる、phpMyAdminなんかをEC2に立てるとなると、
面倒だなぁ...と思い老けていたところ

あれ、これってもしかして...Dockerでできるんじゃ？？
しかもContainerのマネージドサービスなら、楽できる‼︎

ということを思いついて、やってみたらサクッと出来たので書き残してみました。

# 事前準備(と言う名の割と組んじゃってる)
* RDSの作成
* ECSクラスタ（同一VPC）の作成
* ECRの作成

こちらが完了しており、Container imageがPushできる状態であること。
（割とこの辺は他の記事でもよしなに書いてるのでそちらをorz）

※RDSのセキュリティグループ `port:3306`に、ECSのセキュリティグループIDを追加してあげれば大丈夫です。

# phpMyAdminのContainer imageをPull
[こちらの素晴らしい記事](https://qiita.com/furu8ma/items/50718efebee20fd24517)を参考に、phpMyAdminのContainer imageを作成していきます。

目的はあくまで、Container image作成ですので、phpmyadminの公式からpullしちゃいます。

```Dcoker:docker_run_command
docker run -it phpmyadmin/phpmyadmin:latest -p 80:80
```

動作確認として、Pull完了後に`http://localhost`でphpMyAdminのログイン画面が表示されたらOK

# ECRへPush

こちらは、ECRに、Push commandが表示されるので、詳しくは省略します...orz

# Task Definitionの作成
FargateでもEC2どちらのタイプでも動くはず...(私はECSでやりました）
Task Definition作成で、肝となるのが`Container Definition`です。
Add Containerを押下して、以下を記述します。

```
* Container name      : ユニークな名前でOK
* Image               : <ECR_URI:CONTAINER_IMAGE_TAG>
* Memory Limits (MiB) : 環境に合わせて設定
* Port mappings       : 80:80
* CPU units           : 環境に合わせて設定
* Env Variables       : 以下を入力(Key : Valueの形式)
　　PMA_ARBITRARY : 1
 PMA_HOST      : <RDS_ENDPOINT_URL>
 PMA_PASSWORD  : <RDS_USER_PASSWORD>
 PMA_USER      : <RDS_USER_ID>
```

環境変数をちゃんと入れておくさっくり動いてくれるのがいいですね。
（ECSのTask Definitionがdocker-composeライクなので、とっつきやすいのもGoodでしたｗ）

あとは、Taskを実行し、RUNNINGの状態になれば、RDSがphpMyAdminから繋がっちゃいます。

# まとめ

今回はAWSの環境でしたが、その他のパブリッククラウドで用意されているDockerのマネージドサービスでも利用できるんじゃないかなと。

ECS側にDBの接続情報を持たせられるのも良いですね(この辺がcomposeっぽい)

あと、画像が無くてすいません...orz
テキスト選択背景色を指定するCSS


デザイナーさんから指定が無くても設定しておきたいシリーズ

テキスト選択背景色を指定するCSSのコードです。
サイトのカラーに合った色を指定しておきたい。

# 内容

「::selection」擬似要素を使います。

# 利用できるプロパティ

- color
- background-color
- cursor
- caret-color
- outline およびその個別指定プロパティ
- text-decoration および関連プロパティ
- text-emphasis-color
- text-shadow


## 発見

- class指定も可能。
- 文字のみ／背景色で使用するとサイトの雰囲気にあった。



# デモ

<p data-height="265" data-theme-id="0" data-slug-hash="RBXVQo" data-default-tab="css,result" data-user="harumi-sato" data-pen-title="選択の背景色をCSSで指定" class="codepen">See the Pen <a href="https://codepen.io/harumi-sato/pen/RBXVQo/">選択の背景色をCSSで指定</a> by harumi-sato (<a href="https://codepen.io/harumi-sato">@harumi-sato</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考URL

- <a href="https://developer.mozilla.org/ja/docs/Web/CSS/::selection">::selection - CSS: カスケーディングスタイルシート | MDN</a>
- <a href="https://metrograph.jp/text_selection_style/">[CSS] テキスト選択時の文字色・背景色を設定する | metrograph.jp</a>
凡人がcourseraの機械学習コースを受けてみた

#要約
[courseraの機械学習コース](https://www.coursera.org/learn/machine-learning)ってやつがすごく勉強になるとは知っていても、なかなかハードルが高いですよね。だいたいやっている人ってみんな頭よさそうだし。
そんな機械学習コースを凡人が三か月くらいかけて完走したので、その報告をしたいと思います。
なかなか一歩踏み出せずにいる人の応援になればと思います。

#はじめに
coureseraの機械学習コースを受けた人の話をよんでると、**英語は比較的簡単**とか**数学は行列の簡単な計算ができれば十分**とかいうコメントをみます。なるほどそんなに難しくないのかと思って、その人のプロフィールなんかを見てみると、**東大生です！！**とか**某ベンチャーです！！**とか、はたまた、**某一部上場企業です！！**とか**某大学先生です！！**なんて書いてあるものだから、**そりゃあんたらからすれば簡単かもしれんけども！**と卑屈になってなかなかやる気が起きないわけです。~~いや、コンプじゃないよ、ほんとに。~~
その点、私は入った大学も偏差値50以下だったし、その中でも普通くらいの成績だったし、そもそも情報系でもないしで、彼ら優秀な人から見れば雑魚でも、それでも全体から見れば１σの範囲内だと思うわけです。英語はというと、大学時代にまじめにTOEICの勉強をして400点くらいしか取れない程度です。それから5年以上勉強していないので察してください。
逆に言えば、そんな人でも完走できたよという話です。

#英語について
で、まぁ、僕に限らず日本の普通の人は、そんなに英語が得意じゃないんじゃないかなと思います。だけど、プログラミング業界はどうやら英語能力が結構問われているみたいで、最近入門したばかりの私としてはたじろぐばかりです。
とはいえ、問われている以上、勉強しないわけにも行かないわけで、courseraは英語と機械学習を一度に学べて良い機械になるとも思います。そういうわけで、僕はなるべく文章は翻訳を使わずに読むようにしましたが、最終的には簡単な文章であれば、多少読めるようになった気がします。単語も比較的同じような単語が多いですし、何度か調べれば、徐々に覚えられます。僕レベルでこれですから、比較的簡単というのは本当なんだと思います。
**英語に自信がない人は、グーグル翻訳のアドインを入れることお勧めします。**ドラッグするだけで、翻訳してくれるので、そんなに困りません。疲れた時とか、やる気が出ないときはそんなことやってました。
ちなみに、動画はたまに遅れてたりなかったりしますが、基本的に翻訳あります。宿題とかクイズとかはありません。

#数学について
数学に関しては、優秀な人たちが言う通り、簡単な行列の計算ができれば、十分かと思います。僕は、１年くらい前に[ゼロから学ぶ線形代数](http://bookclub.kodansha.co.jp/product?item=0000148794)て本を読みました。~~途中までですが。~~
まったく知らないのなら、こういった本とか漫画で分かる系の本とかをあらかじめ読んでおくといいかもしれません。僕は、線形代数とベクトルと行列のイメージがつながらないレベル（~~今でも言語化は難しい~~）だったので少し読んでおきました。同レベルの人は参考になればと思います。
あとは、∑の式のイメージとかが苦手な人も少し大変かもしれませんね。これは、慣れるしかないかと思うけども。

#機械学習について
このコースは入門コースだけど、本当に初めて機械学習に触れるならば、入門本を読んだり、ネットの記事を読んだりしてからの方が良いかもしれません。いや、入門内容としてのレベルが高すぎるというつもりはないのだけども、やはり英語が苦手だったり、数式が難しかったりすると、意味が完全にすんなり入ってこなかったりするわけです。翻訳されている文章も倒置法が多様されて読みにくかったりとか。そういう場合を補完するためにも予備知識が少しでもあれば、あれについて言っているのねと入ってきやすくなるものだと思います。参考に自分が始める前に読んでた本の例を示します。

- [坂本真樹先生が教える 人工知能がほぼほぼわかる本](http://shop.ohmsha.co.jp/shopdetail/000000004963/) 読み物だけど、全く知らないならこういう本からでもよいと思う。
- [pythonによる機械学習入門](http://shop.ohmsha.co.jp/shopdetail/000000004794/)　実際に動かしてみたいなら、こういうのもよかったと思う。
- [ニューラルネットワーク自作入門](https://book.mynavi.jp/ec/products/detail/id=65933)　全然合わなかったけど、評価はまぁまぁたかい。

オライリーの魚の本とか読める人は、全然問題ないと思います。

#宿題について
普通にきついです。宿題にかかる見積もり時間が３時間とかって書いてあっても、僕はその倍以上は悩みました。英語が読めないっていうのもありますけど、僕はプログラミング初心者だからきついというのもあって、回答が正しくないときに、どこが間違っているのか見つけられないんですよね。機械学習初心者でもプログラミング自体はできる人であれば、その点は、良いのかなと思います。プログラムの行数がすごい多いなんてことはないですし、octaveは普段pythonつかっている私としては、特に違和感のないものでした。

#学習時間について
具体的な時間ではないですが、割と毎日のように１日２コマくらい進めて、土日にプログラミング課題をやってました。正直、僕はそういった時間が取れたので、完走することができましたが、社会人で時間が取れない人はこれが難しいかもしれません。けど、アプリをインストールすれば、動画をダウンロードして通勤時間等でも見れますし、一本１５分以下程度なので、多少忙しくてもなんとかやっていけるかとは思います。

#終わりに
以上で書いた通り、全く簡単だったよというつもりはありませんが、別にすごい優秀な人間でなくても、多少の準備さえすれば、courseraの機械学習コースは完走できますし、その内容もためになるものだと思います。個人的には、途中先生が挟むシリコンバレーネタが結構好きです。
興味のある人は、無料だし、ぜひやってみましょう。

お金払えば、こんなんももらえます。最後に先生から言ってもらえるコメントには感動しました。
<img width="522" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/257926/b8ef9cb4-316f-c037-86d8-f4eec8ee6f40.png">
QRコードリーダー起動時、初回の権限確認を許可するとアプリがクラッシュする

## きっかけ
Xamarin.Formsで開発したアプリがAndroidでQRコードリーダーを初回起動時に権限を許可するとアプリ自体がクラッシュするという不具合を修正した時の備忘録です。

## 原因
原因はZXing.Net.Mobile.Formsのバージョンが最新だとこの症状が出るバグみたいです。以下のページに書いてありました。
[App crash after requesting camera permission #750](https://github.com/Redth/ZXing.Net.Mobile/issues/750)

> 2.4.1（最新）をインストールした場合、初回時に許可が要求された後、スキャンを試みるが、スキャンはまったく実行されません。2回目はOKです。それは他の投稿でここに報告されたバグです。

との事。私の場合はパーミッションを要求された後、「OK」をクリックするとアプリがクラッシュしてしまいました。書いてある通りに初回時だけクラッシュして2回目からは普通にQRコードリーダーが使用できます。

> これは一度、2.3.1で修正されましたが、2.4.1に再び出るようになりました。この問題を解決するには、ZXing.Net.Mobileのバージョン2.3.1をインストールしてみてください。

との事だったので、早速、自分の使っている 'ZXing.Net.Mobile.Forms'と 'ZXing.Net.Mobile'をチェックしたところやっぱり2.4.1の最新だったのでとりあえず2.3.1にダウングレード 

そして、'ZXing.Net.Mobile.Forms'と'ZXing.Net.Mobile'をダウングレード しただけでは改善されないので、MainActivity.csのOnRequestPermissionsResult関数（Android6.0用パーミッション設定）を、

```
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult（requestCode、permissions、grantResults）;
```
から

```
ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult（requestCode、permissions、grantResults）;
```
へ書き換える。　書き換える部分は'ZXing.Net.Mobile.Forms'の'.Forms'を消すだけ。すると無事に初回時起動時でも動作するようになりました。

## まとめ
やはり日本語で書かれたドキュメントはほぼ公式のみで事例が少ないので原因が分かるまでTwitterで情報収集したり海外のサイトを見まくってやっと解決！
めっちゃ時間がかかってしまったし、結局、日本語で'ZXing.Net.Mobile.Forms'と'ZXing.Net.Mobile'のダウングレード を書いているサイトを見つけることができなかったので、今後もこう言う内容を備忘録として書いておこうと思った。（自分の記憶に全く自信なし！）
でも、結構、Twitterで色んな方に助けてもらえてすごく助かった！感謝！！
Xamarin初心者なので内容間違っているなどがあれば皆様、教えてくださいませ〜
Javascript 物件 - 基礎使用 By 彭彭 16+17


	5. 物件教學
		a. 基本物件設計

```ruby
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"></meta>
	<title>Javascript</title>
	<script type="text/javascript">
/*
	// 建立空白物件
		var point = new Object();
	// 建立物件的成員(屬性和方法)
		// 屬性
		point.x = 3;
		point.y = 4;
		// 方法(函數)
		point.getPosition = function(){
			alert(this.x + "," + this.y);
		}
	// 使用物件
		point.getPosition();
*/
		
	// 綜合範例:游戲中的玩家設計
	// 屬性是不動的 方法是動的
	var player = new Object();
	player.name = "florence";
	player.hp = 100; // hp血量
	// 玩家可以做什麽 動作行爲 程序來表達
	player.fight = function(){
		this.hp = this.hp - 2;
	}
	player.rest = function(){
		this.hp++;
	}
	player.report = function{
		alert(this.name + ":" + this.hp);
	}
	player.fight();
	player.rest();
	player.report();
	
	</script>

</head>
<body>	
</body>
</html>

```

	5. 物件教學
		b. 使用建構式

```ruby
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"></meta>
	<title>Javascript</title>
	<script type="text/javascript">
	/*
		// 游戲中的玩家設計
		// 建構物件
		var player = new Object();
		player.name = "florence";
		player.hp = 100;
		player.fight = function(){
			this.hp = this.hp - 2;
		}
		player.rest = function(){
			this.hp++;
		}
		player.report = function(){
			alert(this.name + ":" + this.hp);
		}
		// 物件的使用
		player.fight();
		player.rest();
		player.report();
*/
		// 建構物件的函數
		function Player(name,hp){
			// this 代表新建的空白物件
			this.name = name;
			this.hp = hp;
			this.fight = function(){
				this.hp-=20;
			}
			this.rest = function(){
				this.hp++;
			}
			this.report = function(){
				alert(this.name + ":" + this.hp);
			}
		}
		// 使用建構函數時 前面加new
		var player1 = new Player("florence",100);
		player1.fight();
		player1.report();
		var player2 = new Player("大寶貝",80);
		player2.fight();
		player2.report();
	</script>

</head>
<body>	
</body>
</html>
```
Pancake sorting implementation with python

```python
import sys 
import math

al = sys.argv[1:]
print("before:",al)
l = len(al)

"""
for i in range(0,l):
    print(al[i])
"""
for i in range(l-1,-1,-1):
    if int(al[i])!=i+1:
        #print(al[i],i+1)
        for j in range(0,i):
            if int(al[j])==i+1:
                if j==0:
                    end = math.floor(i/2)
                    #print("check:",al[j],j,i+1,end)
                    for k in range(0,end+1):
                        t = al[k]
                        al[k] = al[i-k]
                        al[i-k] = t 
                    print(al)
                else:
                    end = math.floor(j/2)
                    for k in range(0,end+1):
                        t = al[k]
                        al[k] = al[j-k]
                        al[j-k] = t 
                    print(al)
                    end = math.floor(i/2)
                    #print("check:",al[j],j,i+1,end)
                    for k in range(0,end+1):
                        t = al[k]
                        al[k] = al[i-k]
                        al[i-k] = t 
                    print(al)
                break
print("after:",al)
```

```
$ python 1.py 1 2 3 8 4 7 5 6 9
before: ['1', '2', '3', '8', '4', '7', '5', '6', '9']
['8', '3', '2', '1', '4', '7', '5', '6', '9']
['6', '5', '7', '4', '1', '2', '3', '8', '9']
['7', '5', '6', '4', '1', '2', '3', '8', '9']
['3', '2', '1', '4', '6', '5', '7', '8', '9']
['6', '4', '1', '2', '3', '5', '7', '8', '9']
['5', '3', '2', '1', '4', '6', '7', '8', '9']
['4', '1', '2', '3', '5', '6', '7', '8', '9']
['3', '2', '1', '4', '5', '6', '7', '8', '9']
['1', '2', '3', '4', '5', '6', '7', '8', '9']
after: ['1', '2', '3', '4', '5', '6', '7', '8', '9']
```
AWS Cloud9からDeep Learning AMI(Ubuntu)12.0に接続する

#前提条件
* 接続先は、アジアパシフィック(東京)リージョンに作成したDeep Learning AMI(Ubuntu)12.0
　(Cloud 9接続に必要なPython2.7はインストール済)

* 一つのAWSアカウントでAWS Cloud9を使用する(高速セットアップ)
※複数のユーザーで使用するチームセットアップは[こちら](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/setup.html)


#手順
接続先のEC2インスタンス表示画面で、パブリックDNS(IPv4)を控えます。
![01.png](https://qiita-image-store.s3.amazonaws.com/0/280437/dce8c977-d2b7-72b2-500b-8a48d2bf2dac.png)


AWS Cloud9コンソールを開きます。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/280437/5eef2917-9c0f-1e79-8330-8f1ca2c9d5d7.png)
2018年8月現在、東京リージョンは非対応のため、シンガポールなどに切り替えます。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/280437/73e73f84-d6b1-f522-914d-b1bb245a34bf.png)

「Create environment」をクリックします。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/280437/27b615b8-3e3a-0554-47e9-9d349081025a.png)

「Name environment」画面で、任意の名前を入力して「Next Step」をクリックします。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/280437/bc0bb5cd-58fb-2b9f-ba55-641c54c986a6.png)


「Configure settings」画面で、以下のとおり設定します。
　1. [Environment type]を"Connect and run in remote server (SSH)"にチェック
　2. [User]を入力(デフォルトは"ubuntu"）
　3. [Host]に、先ほど控えたパブリックDNS(IPv4)を入力
![06.png](https://qiita-image-store.s3.amazonaws.com/0/280437/eb314c45-7a65-7f36-3d1f-6dcdcf2a36d8.png)


「View public SSH key」のクリックで表示されるSSH keyを、「Copy key to clipboard」をクリックしてコピーします。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/280437/856da1a8-c1ef-5c58-52c4-1a8ca93024b5.png)


PuTTYなどのSSHクライアントで、Ubuntuインスタンスにコンソール接続します。
`$ editor ~/.ssh/authorized_keys`
コマンドで開いた「authorized_keys」ファイルに、先ほどコピーしたSSH keyを追記して保存します。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/280437/be98c1b8-2fc9-4ac9-cdcb-6d60878c6838.png)


以下のリンク先などを参考に、node.jsをインストールします。
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea
https://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b
https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04

`$ node -v`
コマンドで、AWS Cloud9に必要なバージョン0.6.16以降であることを確認します。


AWS Cloud9コンソールの「Configure settings」画面に戻り、「Next step」をクリックします。


「Review」画面が表示されたら、「Create environment」をクリックします。
![09.png](https://qiita-image-store.s3.amazonaws.com/0/280437/f504e592-6cc8-6dc9-0709-128fa04892cd.png)


「AWS Cloud Installer」画面が表示されたら、"Always install everything"にチェックを入れ、「Finish」をクリックします。
![10.png](https://qiita-image-store.s3.amazonaws.com/0/280437/6289d013-60e4-c505-de27-02ea04415ecf.png)


AWS Cloud9のWelcomeページが表示されることを確認します。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/280437/bb8e1680-f414-b8c3-e923-ed7c742ca145.png)

#補足
2018年8月現在、上記までの手順では、Terminalタブでコマンドが打てないなど動作が不安定です。
これを解消するには、再びUbuntuインスタンスにコンソール接続し、以下のコマンドを実行します。
`$ curl -L https://raw.githubusercontent.com/c9/install/master/install.sh | bash`


参照リンク：AWS Cloud9 のトラブルシューティング
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/troubleshooting.html
Jupyter Notebook + Ruby で CSV を加工して出力する

# この記事は？

Jupyter Notebook 上で CSV を読み込み、列と行を加工して、加工した CSV を出力する方法を記載します。Excel でやればいいとか、Jupyter Notebook 上でやるなら [Pandas](https://pandas.pydata.org/) (Python) でやればいいとかそういう声もあると思います。ただ Jupyter Notebook 上で CSV を加工しながら最終結果を出力したい、かつ Python ではなく使いなれた Ruby でそれを行いたいということもあるかもしれません。

# はじめに

Jupyter Notebook のインストール方法、ならびに Jupyter Notebook 上で Ruby を動かす方法については説明を省きます。後者は [SciRuby/iruby](https://github.com/SciRuby/iruby) の README.md が参考になります。

# 方法

まず [Daru](https://github.com/SciRuby/daru) をインストールします。Daru は Python における Pandas にあたるデータ分析用のライブラリで、これを使えば CSV を DataFrame という形式で読み込んで加工することができます。

```
$ gem install daru
```

ちなみに、これから記載する Ruby コードは全て Jupyter Notebook 上で実行してください。

```rb
require 'daru'
```

今回は例として [男女別人口－全国，都道府県 (大正９年～平成27年)](https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00200521&tstat=000001011777&cycle=0&tclass1=000001094741&stat_infid=000031524010) というデータセットの CSV を使います。

CSV は上記のリンク先からダウンロードします。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/6697/f95f5a4a-ba1d-c186-c1ec-fa0b444e9303.png)


あるいは次のコードでダウンロードします。

```rb
# CSV をダウンロードする。
require 'open-uri'

url = 'https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031524010&fileKind=1'
open(url) do |f|
  File.open(File.expand_path('~/Downloads/c01.csv'), 'wb') do |out|
    out.write(f.read)
  end
end
```

このままではこの CSV を Daru で扱えません。扱えるようにするには文字コードを変換して、かつ不正な行を取り除きます。

```rb
# CSV の文字コードを Shift_JIS から UTF-8 に変換する。また、不正な行を取り除く。
File.open(File.expand_path('~/Downloads/c01.csv'), 'rb:Shift_JIS:UTF-8', undef: :replace) do |f|
  CSV.open(File.expand_path('~/Downloads/c01_utf8.csv'),'w') do |csv|
    CSV.new(f).each do |row|
      # 末尾にコメントが 2 行あるのでそれを取り除く。
      next unless row.length == 9
      
      csv << row
    end
  end
end
```

これで Daru を使って CSV を読み込むことができます。

```rb
df1 = Daru::DataFrame.from_csv(File.expand_path('~/Downloads/c01_utf8.csv'))
```

Ruby のコードを実行すると、Jupyter Notebook 上に DataFrame の中身が出力されます。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/6697/7925f1bf-0ed9-0916-f7f5-b9609691227f.png)

末尾は以下のとおりです。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/6697/25309f71-5303-c71d-1a0a-65e91a6a1ff7.png)

まず列を加工してみましょう。

```rb
# 列を都道府県コード, '西暦 (年),  人口 (総数) だけに絞り込む。
df2 = df1['都道府県コード', '西暦（年）', '人口（総数）']
```

![04.png](https://qiita-image-store.s3.amazonaws.com/0/6697/07b83367-24aa-220d-6ef8-77c218edcd86.png)

次に行を加工してみます。

```rb
# 西暦 (年) が 2,000 以上の行だけに絞り込む。
df3 = df2.where(df2['西暦（年）'].gteq(2000))
```

![05.png](https://qiita-image-store.s3.amazonaws.com/0/6697/64e3da24-2230-7b8f-d5f3-9da12dbc69dd.png)

最後に、加工した DataFrame を CSV に出力します。

```rb
df3.write_csv(File.expand_path('~/Downloads/c01_utf8_updated.csv'))
```

これで完了です :tada:

# 最後に

もちろん Excel でも CSV の加工は可能ですが、Jupyter Notebook 上で対話的にデータをいじりながら加工できるのは便利です :blush:
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 5.3 ロジスティック回帰

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import pandas as pd
import numpy as np
from scipy.special import expit
import pystan
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
from matplotlib import colors
import seaborn as sns
%matplotlib inline
```

### データ読み込み

```python
attendance3 = pd.read_csv('./data/data-attendance-3.txt')
```

# 5.3 ロジスティック回帰
## 5.3.2 データの分布の確認

```python
pd.crosstab(attendance3['Weather'], attendance3['Y'])
```

## 5.3.6 Stanで実装

```python
data = dict(
    I=attendance3.index.size,
    A=attendance3['A'],
    Score=attendance3['Score']/200,
    W=attendance3['Weather'].map(dict(A=0, B=0.2, C=1)),
    Y=attendance3['Y']
)
fit = pystan.stan('./stan/model5-5.stan', data=data, seed=1234)
```

## 5.3.7 図によるモデルのチェック

```python
ms = fit.extract()

X = np.arange(30, 201)
q_mcmc = ms['b'][:, 0][:, np.newaxis] + ms['b'][:, 2][:, np.newaxis]*X[np.newaxis, :]/200
q_qua = expit(np.percentile(q_mcmc, (10, 50, 90), axis=0)).T
d_est = pd.DataFrame(np.hstack((X.reshape((-1, 1)), q_qua)), columns=('X', 'p10', 'p50', 'p90'))

plt.figure(figsize=figaspect(3/4.5))
ax = plt.axes()
ax.plot(X, d_est['p50'], c='k')
ax.fill_between(X, d_est['p10'], d_est['p90'], color='k', alpha=2/6)
sns.stripplot('Score', 'Y', data=attendance3.query('A==0 and Weather=="A"'), jitter=True, orient='h', color='k', ax=ax)
plt.setp(ax, xlabel='Score', ylabel='q', ylim=ax.get_ylim()[::-1])
plt.show()
```
![fig5-9.png](https://qiita-image-store.s3.amazonaws.com/0/103085/0c72bb33-070f-17e0-c58f-2684e9452363.png)

```python
d_qua = pd.DataFrame(np.percentile(ms['q'], (10, 50, 90), axis=0).T, columns=('p10', 'p50', 'p90'))
d_qua = pd.concat([attendance3, d_qua], axis=1)

plt.figure(figsize=figaspect(3/4.5))
ax = plt.axes()
ax.violinplot([d_qua.query('Y==@i')['p50'].values for i in range(2)], positions=[0, 1], vert=False)
sns.stripplot('p50', 'Y', hue='A', data=d_qua, jitter=True, orient='h', palette={0: colors.to_rgb('black'), 1: colors.to_rgb('gray')}, size=3, ax=ax)
plt.setp(ax, xlabel='q', ylabel='Y', yticks=(0, 1), ylim=ax.get_ylim()[::-1])
plt.show()
```
![fig5-10.png](https://qiita-image-store.s3.amazonaws.com/0/103085/d4782f2d-d6d9-32e8-27cc-668ab863d1d3.png)

```python
ms = fit.extract()

N_mcmc = ms['lp__'].size
spec = np.linspace(0, 1, 201)
probs = [10, 50, 90]

def roc(i):
    fpr, tpr, _ = roc_curve(attendance3['Y'], ms['q'][i, :], drop_intermediate=False)
    return np.interp(spec, fpr, tpr)

m_roc = np.array(list(map(roc, range(N_mcmc))))
d_est = pd.DataFrame(np.hstack((spec.reshape(-1, 1), np.percentile(m_roc, probs, axis=0).T)), columns=['X'] + ['p{}'.format(p) for p in probs])
```

```python
ax = d_est.plot('X', 'p50', figsize=figaspect(1), legend=False, c='k')
ax.fill_between('X', 'p10', 'p90', data=d_est, color='k', alpha=2/6)
lim = ax.get_xlim()
ax.plot(lim, lim, c='k', alpha=0.5)
plt.setp(ax, xlim=lim, ylim=lim, xlabel='False Positive', ylabel='True Positive')
plt.show()
```
![fig5-11.png](https://qiita-image-store.s3.amazonaws.com/0/103085/731116e1-acf2-6408-768c-a774a347b8fa.png)
Rails 5.2の情報のまとめ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42407/3ca76331-6454-009d-c931-940ff3f162d8.png)

Ruby on Railsで検索すると、個人のページが沢山ヒットします。が、「試して見た」系の記事も多くてどうしても「又聞き」になってしまうことは否めません。
なので、本家の仕様に当たるようにしています。
特に、Qiitaで記事を書こうとすると又聞きのままだとしょうが無いのでね。

結構、日本語で提供されているrailsの情報って、4.xで止まっていることが多そうな気もした。。

# リンク

* Ruby on Rails 言語仕様
    * https://guides.rubyonrails.org/ (日本語：https://railsguides.jp/)
* Ruby on Rails API仕様
    * https://api.rubyonrails.org/
* Ruby 言語仕様
    * https://docs.ruby-lang.org/ja/latest/doc/index.html

## Ruby on Railsガイド

* 日本語サイト：　https://railsguides.jp/
    * 日本語版はバージョンいくつなのかちょっと不明。多分v5.2なのかなと。リリースノートが5.2まであるので。。
* 原書：https://guides.rubyonrails.org/
    * v5.2.1 ベースでの言語仕様サイト
* 例えば、v5.1.6 ベースだとこちら:https://guides.rubyonrails.org/v5.1/
    * バージョン毎のマニュアル的なものを探るとしたらここをみるしかなさそう？



## Ruby on Rails API仕様（各メソッドの詳細)

ガイドだとどの様な機能が準備されているか分かるけど、細かい仕様が分からない
例えば、form_for の中で利用する text_filedの引数って何が取り得るとか調べるとなると
APIの仕様を見る必要がある

日本語だとv4.2.1：http://railsdoc.com/

API仕様 https://api.rubyonrails.org/

この検索窓にキーワードを入力するとすっと仕様が表示されるのでとっても便利

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42407/45cea2a4-6a22-8c83-bf0b-13103d2bc230.png)


例：

* [text_fieldの仕様](https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-text_field)
* [button](https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-button_tag)
* [active_viewのcollection_select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select)

## api.rubyonrails から読み解く仕様

### activerecord

https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

* 暗黙的な結合テーブルが使えるのは，[has_and_belongs_to_many](https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many)の関係の時だけ
* has_one / belongs_toはペアになるはずで、外部キーがある方は belongs_toとなる。