OmniAICreator/Qiita-1.07M huggingface dataset:
もそ、プログラミングを学ぶ【PHP&Laravel】〜ファサードってなんだ？〜

Qiita読者のみなさま、大変ご無沙汰しております。もそです。

史上最長のGWが明け、休暇に慣れきった身体を引きずりながら出社されている方も多いかと思います。
ちなみに私は10連休など**まっったく**関係なく、むしろ~~出勤奴隷~~働いておりました。

出勤奴隷以外では何をしていたかと言いますと、

なんと...
**PHP&Laravelを勉強していました。**

本来であれば学習しながらこの記事を書きたかったのですが、学習スケジュールが結構ぎちぎち&自分の習得スピードに自信がなかったためQiitaを少しお休みしておりました。

一度Railsを習得していたおかげでおおよその流れは把握できたのですが、理解が追いついていない部分もまだたくさんあります。
なのでこれからもどんどんアウトプットをしていこうと思います！


さて今回はLaravelのファサードについて書いていきます。

##ファサードってなんだ

Laravelを学ぶ中で突如現れた**"ファサード"**というワード。

この言葉が登場したとき、もそは戸惑いました。

なぜならファサードという言葉は建築業界では当たり前に使われる言葉。
仮にも建築を学んだものとして言葉は知っているのですが、

「え、ファサードってあのファサード？プログラミングなのになんで？？」

と、なんとなく概念が掴めずにいました。


**Laravelにおける"ファサード"は、構築物（プログラム）の呼び出し部分**のような機能をもちます。

大抵あるひとつのプログラムの中に、様々な機能をもつ別のプログラムが複数存在します。
その複数の機能を、いちいち一つずつ呼び出すのは効率が悪いですよね。

そこで複数の機能を呼び出すための総合入り口を設置します。
つまり、構築物の正面玄関のような感じです。

これが転じて"ファサード"になった、というわけです。


![無題1236.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372174/b9089807-3367-c7ba-325a-5d32ab265a16.jpeg)


##どこで使うの？

Laravelには[標準定義されたファサード](https://laravel.com/docs/5.4/facades#facade-class-reference)があります。

そのなかでもよく使うのが**Route::**
どこで使われているかというと、

```routing.php
Route::get('/', function () {
    return view('welcome');
});
```

このようにルーティングの設定でファサードを使っています。
このほか**ログイン機能を実装するAuth::**や**ファイルの保存をおこなうStorage**などもよく使われるので、覚えておくと便利かもしれません。

--

LaravelはRailsを参考に作られていることもあり、楽しく学習できています。
記述量が増える部分も少しありますが、圧倒的に処理の流れが見やすいのでRailsより好きかもしれない...！

とはいえRailsも忘れないように、ごちゃまぜにしないように学んでいこうと思います。
...もその学習はまだまだ続く。
初めてJavaに関する写経

結論：eclipseが開いているまま、ソースの更新はできません。

経緯：今日はeclipseが開いているうちに、ソース更新をしたんだ。結局eclipseでその更新内容を確認することはできなかった。eclipseはソースを開いて、更新バージョンと競合したわけでした。
指定したView で Snackbar を回避する

やりたいこと
----

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49585/19892899-839d-a306-da20-20949adda85e.gif" width=300>


方法
----

回避したい View を `CoordinatorLayout` の内側に配置して `app:layout_dodgeInsetEdges` を指定する

```xml
<CoordinatorLayout>
  <!-- 回避したいView -->
  <View app:layout_dodgeInsetEdges="bottom" />
</CoordinatorLayout>
```

調べた
----

- 24.2.0 のバージョンで `CoordinatorLayout.Behavior` を継承してカスタムする方法から `app:layout_dodgeInsetEdges` を設定する方法に変わったようです。

- 下から以外の他の方向からの Inset に対応したい場合は `all` を設定する方法があります。

https://twitter.com/yuichi_araki/status/766129341382078468
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">あと FAB が Snackbar をよける動作を一般化した app:layout_dodgeInsetEdges (よける) と app:layout_insetEdge (よけさせる) も使って欲しい。</p>&mdash; Yuichi Araki (@yuichi_araki) <a href="https://twitter.com/yuichi_araki/status/766129341382078468?ref_src=twsrc%5Etfw">2016年8月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- つまり、 Snackbar には `app:layout_insetEdge` の属性が付与されているということみたいです。

この機能が実装されてから随分経つはずですが、知りませんでした。

参考になった記事 :bow: 
-----
- http://roid-droid.blogspot.com/2016/09/coordinatorlayoutapplayoutdodgeinsetedg.html
- https://medium.com/@rusinikita/simple-view-dodging-with-coordinatorlayout-f13cc32e0de6
Webアプリケーションの自動テストとKatalonStudio

# Webアプリケーションの自動テスト

## 既存機能に対するテスト
Webアプリケーションに限りませんが、アプリケーションに機能を追加する場合、既存機能に影響がないことを確認するテストが必要です。
これはレグレッションテストといわれますが、これを人が毎回行うと多くの工数がとられてしまいます。
レグレッションテストを行わなかった場合、機能追加をした部分以外のところで不具合が発覚し、リリース後に緊急の修正リリースが必要になることも多々あります。

## 人がテストするのは大変
機能追加するときに作成したテストケースを毎回人が行う場合、機能が増えるに従いテストの工数が単純に増加していきます。
少なくとも正常系のシナリオ程度は自動的にテストを行うことができれば、開発者は自動化が難しいテストだけを行うことで工数削減することができ、また本来のアプリケーション開発に時間を割くことができます。

## SeleniumIDEのアップデート終了と新プロジェクト
数年前は Selenium と SeleniumIDE を使い、SeleniumIDEでブラウザの操作を録画し、これを自動テストパターンとして使う方法がよくつかわれていました。
（それと同じぐらい、Selenium WebDriver を使って、直接コードでテストケースを作成する人も多かったと思います）

SeleniumIDEは当時 Firefoxのプラグインとして配布されていましたが、Firefoxのバージョン55以降で SeleniumIDEが動作しなくなってしまいました。

これまでSeleniumIDEでテストを作っていた人たちは、このためだけにFirefoxのバージョンアップを止めていたことも多かったと思います。
しかし、ブラウザのバージョンアップを止めることはセキュリティの観点で好ましくありませんでした。

しかし、現在は SeleniumIDEは[新しいサイト](https://www.seleniumhq.org/selenium-ide/)でプロジェクトを再開し機能拡張が進むようになっています。

新しくなった SeleniumIDE はまだ機能が少ないようで、これからテストケースを効率よく作成するには機能不足と感じたため、今回は テスト作成環境が整っている KatalonStudioを使うことにしました。


# KatalonStudioのインストール
[Katalon社のサイト](https://www.katalon.com/)からアプリケーションをダウンロードします。

ダウンロードするにはアカウントを作成する必要があります。
まだアカウントを作っていない場合は、ここでアカウントを作成します。
アカウントを持っている場合は Sign in からログインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270324/bb9c29ab-412e-ec5f-af69-e455ce8ffbae.png)

ログインするとトップページに 「Download Now」ボタンが表示されるので、ここからアプリケーションをダウンロードします。
Windows64bit/32bit, MacOS, Linux のうちご自身の環境にあったものをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270324/ee9b1dfe-86a6-7122-88e2-8eb14e330e8a.png)

この後は Windowsでインストールした例です。

Windowsの場合は zipファイルがダウンロードされるので、ダウンロード後、好きな場所にファイルを展開します。
展開後のフォルダにある katalon.exe をダブルクリックしてアプリケーションを開始します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270324/fbce595d-0735-c456-7949-1cb3ef2c5b22.png)

アプリケーションを起動すると、Windowsファイアウォールのブロック許可を確認するダイアログが表示されます。
ご自身の環境に合わせてチェックをONにしてアクセスを許可します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270324/26675d63-d7c5-e380-33c8-edcf1266e937.png)

アプリケーションが起動すると、Katalonのアカウント情報を入力するダイアログが表示されるので、最初に作ったアカウント情報を入力してアクティーベートを完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270324/6e90b0bf-f2e4-9ed0-e0c6-bbe90b5c4a4b.png)

次回は新しいテストプロジェクトを作成します。
Academic テーマで hugo server すると TOCSS のエラーが出る

# Academic テーマで hugo server すると TOCSS のエラーが出る

自分のポートフォリオサイトを作りました。こちらです。
https://segurvita.github.io/

こちらの記事を参考にさせていただき、Hugo + GitHub Pagesを使ってみました。
[【初心者向け】Hugo + GitHub Pagesで静的なポートフォリオを作る](https://qiita.com/nkjzm/items/ab8595f185348de7ba7e)



こちらの記事にも登場する **Academic** というテーマを使ってみようとしたところ、 `hugo server` コマンドで以下のエラーが発生しました。

```bash
$ hugo server
Building sites … ERROR 2019/05/06 15:22:40 error: failed to transform resource: TOCSS: failed to transform "main_parsed.scss" (text/x-scss): this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information
Total in 70 ms
Error: Error building site: logged 1 error(s)
```

今回はこのエラーの解消について書きます。



# エラーが出た環境

エラーが出たのはWindowsのPCです。Macでは出ませんでした。バージョンは以下の通りです。

- OS： Windows 10 64bit
- Chocolatey： v0.10.13
- Hugo： v0.55.5-A83256B9 windows/amd64

Chocolateyというのは、Windowsのパッケージ管理ソフトです。MacでいうところのHomebrewです。

以下のコマンドでHugoをインストールしました。

```bash
choco install hugo
```

Academic テーマのインストールは、こちらの公式サイトの `Install with Git` を参考にしました。

https://sourcethemes.com/academic/docs/install/

以下の手順です。

```bash
git clone https://github.com/sourcethemes/academic-kickstart.git My_Website
cd My_Website
git submodule update --init --recursive
```

これで、あとは `hugo server` をすれば、Academic テーマが適用されたサイトが構築されるはずでしたが、ここで、先ほどのエラーが発生しました！

ちなみに、Macでは発生しませんでした！Macだけでなく、Windowsでも作業がしたかったので、原因を調査しました。



# Hugo Extended が必要だった

エラー文言に https://goo.gl/YMrWcn への案内があるので、見てみました。ずばり `TOCSS ` に関するFAQがありました。どうやら Hugo の `extended` version というのが必要のようです。

Chocolatey のパッケージを調べたところ、 `Hugo Extended` というのが見つかりました。以下のサイトです。
[Chocolatey / Hugo Extended](https://chocolatey.org/packages/hugo-extended)



# Hugo Extended をインストールして再挑戦する

以下のコマンドでインストールできます。管理者権限が必要です。

```bash
choco install hugo-extended
```

ここで再度、サーバーを起動してみます。

```bash
$ hugo server
Building sites …
                   | EN
+------------------+----+
  Pages            | 39
  Paginator pages  |  0
  Non-page files   |  1
  Static files     |  6
  Processed images |  1
  Aliases          |  5
  Sitemaps         |  1
  Cleaned          |  0

Total in 508 ms
```

今度は無事に起動しました！


# さいごに

WindowsとMacでHugoの挙動が微妙に違うというのが知れて良かったです。
AWXをHTTPSで動かす（自己署名証明書使用） 

Ansible Tower の OSS 版とも言うべき位置づけにある AWX を試していた時にふと気になったことがありました。
デフォルトではブラウザから AWX に HTTP で接続する点です。

「HTTP ということは通信の暗号化はもちろんされていなくて、つまりこの状態で運用すると AWX へのログインはもちろん、 AWX に登録する鍵ファイルやパスワードさえ筒抜けなのでは……？」

SSL を導入して暗号化することにしましたがかなりの手間があったので、もっと簡単な方法で同じ目的を満たせるような手段等、ご存知であれば是非ご一報ください。

#作業手順
1.Github上のAWXリポジトリをクローンする。

```
$ git clone https://github.com/ansible/awx.git
```

2.inventoryファイルを編集する。

```
    $ cd awx/installer
    $ vi inventory
```

   host_port=80の行を以下の通り変更し、保存する。

```
    host_port=443
```

3.プレイブックを実行し、dockerコンテナをデプロイする。

```
    $ ansible-playbook -i inventor install.yml
```

4.dockerコンテナがデプロイされていることを確認する。

```
    $ docker ps
```

5.awx_webコンテナ内にアクセスする。

```
    $ docker exec -i -t <コンテナのID> /bin/bash
```
  　コンテナの中に入れていれば、プロンプトが`[root@awxweb awx] #`に変化するはずです。
6./etc/nginxディレクトリ直下に証明書用の新ディレクトリを作成する。

```
    # cd /etc/nginx
    # mkdir certs
```

7.証明書の作成を行う。以下のコマンドを実行。

```
    # openssl genrsa -out server.key 2048
    # openssl rsa -in server.key -out server.key
    # openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=awx.local'
    # openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
```

   作成が完了したことを確認する。

```
    # ls
    server.crt  server.csr  server.key
```

8.nginxの設定ファイルを編集する。

```
    cd /etc/nginx
    vi nginx.conf
```

9.server_name _;の行を以下の通り変更する。

```
    server_name awx.local;
```
10.keepalive_timeout 65;の真下の行に以下の内容を追記する。編集を終了して保存する。

```
    ssl_certificate           /etc/nginx/certs/server.crt;
    ssl_certificate_key       /etc/nginx/certs/server.key;
    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;
```

11.コンテナでの作業を中止する。

```
    # exit
```

12.awx_webコンテナを再起動する。

```
    # docker ps
    # docker restart <awx_webコンテナのID>
```

13.webブラウザ上で、アドレスバーに以下の通り入力する。

```
    https://<AWXをインストールしたサーバのIP>
```

作業は以上です。自己署名証明書なので chrome で接続した場合プライバシーエラーが表示されると思います。


#参考
How to add certificate for AWX login
https://www.youtube.com/watch?v=Ulrr9knCc_w
FirebaseのDatabaseリッスン終了メモ

[Firebase-RealtimeDatabase](https://firebase.google.com/docs/database/ios/read-and-write?hl=ja)で子のリッスンを終了したい時の`removeAllObservers()`の書き方のメモ。

#記述

```swift
var DBRef: DatabaseReference?

var name: [String] = [] {
    didSet {
        guard let database = DBRef else {return}
        //終了できてない
        database.removeAllObservers()
        //終了できてる
        database.child("a").child("b").child("c").removeAllObservers()
    }
}

override func viewDidLoad() {
        super.viewDidLoad()
        DBRef = Database.database().reference()
        DBRef?.child("a").child("b").child("c").observe(.childAdded) { [weak self](snap) in
            guard let wself = self else {return}
            if let nameSnap = (snaps.value as AnyObject).description {
                wself.name.append(nameSnap)   
            }
        })
}
```
パスを忘れずに書けばリッスンは終了する。
終わり。
VBAで意図的にエラーを発生させる。

備忘録として残します。

#■やり方
Err.Raise 任意のエラー番号

```vb
Err.Raise 99
```


**1点注意点があり`On Error Resume Next`の後にこのやり方でエラーを発生させてもエラーを無視して次の行が実行されるため、発火させる前は Resume Nextを無効にしましょう。**
Android studio(Java)でnumberPickerで文字配列を表示するソース

タイトル通りです。
自分用のメモなので、説明は割愛させていただきます。
行き詰まった箇所が多かったので、お役にたつかと思い、共有いたします。

開発環境：Android Studio 3.1.3 (Mac)
言語:java

```MainActivity.java
package com.example.ktakeda.numberpicker;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.NumberPicker;
import android.widget.TextView;

import android.content.res.Resources;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

import static com.example.ktakeda.numberpicker.R.array;

public class MainActivity extends Activity {

    NumberPicker numPicker;
    Button button1;
    TextView textView1;

    // initViews内で、strings.xmlから読み込むに変更
    // final String[] pref = {"tokyo", "chiba", "kanagawa"};


    // viewを生成？
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViews();
        initViews();
    }
    // vの要素を取得
    private void findViews(){
        numPicker = (NumberPicker)findViewById(R.id.numPicker);
        button1 = (Button)findViewById(R.id.button1);
        textView1 = (TextView)findViewById(R.id.textView1);
    }

    // 処理
    private void initViews(){

        // getResources
        Resources res = getResources();
        final String[] pref = res.getStringArray(R.array.pref_array);

        // 最初にnullを入れる、アプリが落ちるのを対策
        numPicker.setDisplayedValues(null);
        // 設定
        numPicker.setDisplayedValues(pref);
        numPicker.setMinValue(1);
        numPicker.setMaxValue(pref.length);


        button1.setOnClickListener(new OnClickListener(){
            // いる？
            @Override
            public void onClick(View v) {
                int idx  = numPicker.getValue();
                textView1.setText(pref[idx - 1]);
            }
        });
    }
}
```

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:textSize="30dp"/>

    <NumberPicker
        android:id="@+id/numPicker"
        android:layout_width="200sp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="OK"/>

</LinearLayout>
```

```strings.xml
<resources>
    <string name="app_name">numberPicker</string>
    <string-array name="pref_array">
        <item>東京</item>
        <item>神奈川</item>
        <item>千葉</item>
        <item>沖縄</item>
    </string-array>
</resources>

```
Deeplerning基礎知識おさらい活動 その2

#目的
Deeplerning基礎知識おさらい活動 第二回です!!
今回はニューラルネットワーク(3層)の推論処理に関してです!!
実際にニューラルネットがどのような手順で推論処理を行っているのかをコードを追いながら見ていきたいと思います!!
(今回のソースは「0から始まるDeeplearning」という著書を基にしています。)

#ニューラルネットワークの推論処理

```python:predict.py
def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']
    
    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)

    return y
```
早速、上記のコードを追っていきたいと思います。
まず、networkには既にラベル毎に('W1','b1'など)既に学習済みの重みが入っています。
それを各重み(W)、バイアス(b)に代入しています。それから各層のそれぞれの計算を行なっており、最後にsoftmax関数を用いて値を0~1に変換し、確率として表します!!

続いて以下のコードを追って行きましょう!!

```python:doing_predict.py
#データセットを代入(xにデータ、tにラベル)
x, t = get_data()
#networkに学習済みの重みパラメータを代入
network = init_network()

accuracy_cnt = 0
for i in range(len(x)):
    y = predict(network, x[i])
    #最も確率の高い要素のインデックスを取得
    p = np.argmax(y)

    if p == t[i]
        accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x))) 
```

get_data()はデータとラベルを返す関数です。
networkに学習済みのパラメータを保存します。

そしてfor文の中の処理を見て行きましょう。
iには一つのデータの番地が入っています。そのi番目のデータを先ほどのpredict関数にかますことによって確率としてyが得られます。
pにはyの最も確率の高かったインデックスが入りそれとラベルと比較をします。
正しければaccuracy_cntに1が加算されます。
この工程を繰り返しデータの個数で割ってあげることで正解率(推論結果)を出します。

#まとめ
実際の推論処理の工程を見て行きましたがラベルとの差分→繰り返す→確率を出すという順番でしたね。
推論の説明が難しくコードを用いて説明して見ました。
なかなか難しかったです。。
いかがでしたでしょうか！！
またお願い致します!!
Future<dynamic>はFuture<XXX>にキャストできない

DartではdynamicからStringやintなどの型へのキャストは自動的に行えるが、Future<dynamic>からFuture<String>やFuture<int>などへのキャストはエラーになる。

```dart
main(List<String> args) async {
  print(await getBool());
}

Future<bool> getBool() {
  return getDynamic();
}

Future<dynamic> getDynamic() {
  return Future.value(true);
}
```

## 実行結果

```
Unhandled exception:
type 'Future<dynamic>' is not a subtype of type 'Future<bool>'
```

## 解決方法

Future<dynamic>を取得する処理をawaitしてdynamicからの自動キャストとすると正しく処理できる。

```dart
void main(List<String> args) async {
  print(await getBool());
}

Future<bool> getBool() async {
  return await getDynamic();
}

Future<dynamic> getDynamic() {
  return Future.value(true);
}
```

## 実行結果

```
true
```
本番環境、ローカル環境にカテゴリーをあげる(CSV)

## はじめに
カテゴリー機能があるアプリを本番環境にデプロイしたけどカテゴリーってどうやってあげるの？ enumでやるの？って迷ったことがある人のための記事です。

## どうやるの？
とても簡単です。

app/db内にcsvファイルを作成するだけです。
<img width="142" alt="スクリーンショット 2019-05-09 16.42.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/d4c03e27-06f0-a2ad-b533-2d548a968cbb.png">

## CSVファイルって何？
CSVとは"Comma Separated Value"の略でデータをカンマ（,）で区切った値のこと。
この形式で保存されたファイルをCSVファイルと言います。

## 設定

```ruby:seed.rb
#csvが使えるようにこの行をはじめに書いてください。
require "csv"

#今回はdb/category.csvを読み込むので以下のように書きます。
CSV.foreach('db/category.csv') do |row|
  Category.create!(name: row[1])
end
```

```ruby:category.csv
1 1,HTML
2 2,CSS
3 3,Ruby
4 4,Python
5 5,JavaScript
```

後は以下で反映させることが出来ます。

```
#基本構文
$ rails db:seed

#herokuを使う場合
$ heroku run rails db:seed
```
pythonのif文を使った条件分岐

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている山田です。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

pythonは、「if」「elif」「else」を使うことで条件分岐できます。
それぞれの書き方は、以下の通りです。
if　条件式:
　　条件式がTrueの時の処理:
(elif　条件式:
　　条件式がTrueの時の処理:)
else:
　　以上のどれにも当てはまらないときの処理:

elifというのは、else ifのことで、追加の条件になります。
そのため、複数でも1つもなくてもif文は成り立ちます。

条件式の書き方

条件式は、比較演算子を使うことができます。
<,>の不等号のほか、<=,>=で以上、以下を表します。
また、==で両辺が等しい、!=で等号否定を表します。
条件に当てはまる場合、Trueを返します。
Nim始めました（環境構築編）

#始めに
新しい言語を使えるようになりたいとふと思い、どうせなら他の人があまり使っていないマイナーなものにしようかと、それでイキリちらかそうと思ってNimに手を出しました。
処理がクッソ速くて正直ビビってます！！！！！

#環境構築を始める
よし、やるぞ
##環境
OS : MacOS Mojave Version10.14.4
##構築を行う
環境構築はとても簡単です。

```
brew install nim
```
これだけ。
HomeBrewインストールしてない人はそっちを先にしてください。
バージョン確認（環境構築できてるかのチェックも兼ね）

```
nim --version
```
2019年5月現在は0.19.4が最新になっています。
##エディタ環境をつくる
エディタはVSCodeかKDevelop(IDE)がいいと思います。

#コンパイル＆実行

```
nim c -r ファイル名.nim
```

##リリース向け

```
nim c -d:release ファイル名.nim
```

-d:releaseを付けないでコンパイルするとデバッグ情報が付加されるため、動作が遅くなります。

#まとめ
Nimのコード美しいから頑張ろう。ご褒美はお寿司でも😂
foreign keyを付与する際に作ったindexの更新をする方法

タイトルのまんまです
結構ハマったので備忘録もかねて書いておきます
例えば、既存のindexを更新する場合は、以下のように書けばうまく行くと思います

```
class AddIndexSample < ActiveRecord::Migration[5.2]
  def change
    remove_index :users, :type_id
    add_index :users, :type_id, unique: true
  end
end
```

これはすでに`users`テーブルの`type_id`というカラムに対して、indexが貼られていて、そのindexを更新するための方法です

ですが、foreign_keyが貼られている場合はindexを削除しようとするとエラーが出てしまいます
なのでforeign_keyを削除してからindexを削除して更新するとうまくいきます

```
class AddIndexSample < ActiveRecord::Migration[5.2]
  def change
    remove_foreign_key :users, :types # 第二引数はテーブル名
    remove_index :users, :type_id
    add_foreign_key :users, :types
    add_index :users, :type_id, unique: true
  end
end
```
MacでChrome74（headless）を動かすとテストに失敗する（with ChromeDriver）

# tl;dr
Railsの開発（テスト）で、Chromeのヘッドレスモードを利用していますが、Chromeが74にアップデートされて以降、正常に動作しなくなる現象が発生し、2日くらい苦しんだので同じく困ってる人（いればの話ですが）に向けたメモです。

ちなみにこの問題はMacでしか発生しません。

# 環境
MacOS 10.14.4(Mojave)
Chrome : 74.0.3729.131（Official Build） （64 ビット）
ChromeDriver : 74.0.3729.6

# 詳細
## 現象１
Rspecを実行していると、あるタイミングでキーチェーンの入力を求められることがある。
※決まった場所で発生しますので、発生しないテストもあります
![スクリーンショット 2019-04-26 17.12.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124906/897ea054-1df1-05c3-e23f-50ae02b65bab.png)

そもそも自動テスト中に、ダイアログが出ること自体違和感しかないのですが、一応これ自体もChrome側の問題らしいです。
`常に許可` `拒否` `許可` どれを選んだとしても、問題は解決しません。

## 現象２
テストが完了せずに`Net::ReadTimeout`が発生する。
これは読んで字のごとくですかね。テストが正常に終了しているように見えるんだけど、Timeoutが発生して失敗に終わります。

# （多分）原因
確定ではありませんが[chromedriverのissue](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2885&q=&colspec=ID%20Status%20Pri%20Owner%20Summary)コメント#14に書かれていました。
chrome74のheadlessモードでは、cookieの削除処理が正常に行えない問題があるようです。（headlessモードじゃなければ大丈夫）

> Headless Chrome version 74 on MacOS appears to have trouble deleting cookies. The following Python code hangs at the call to driver.delete_all_cookies(). Sometime it may also display a dialog: Google Chrome Helper wants to use your confidential information stored in "Chrome Safe Storage" in your keychain. The code hangs regardless of the answer to this dialog.

google翻訳↓
> MacOS上のHeadless Chromeバージョン74では、Cookieの削除に問題があるようです。 次のPythonコードはdriver.delete_all_cookies（）への呼び出しでハングします。 ダイアログが表示されることもあります。GoogleChrome Helperは、キーチェーンの「Chrome Safe Storage」に保存されている機密情報を使用したいと考えています。 このダイアログに対する答えに関係なく、コードはハングします。

ハング！ハング！ハング！

# 対策（workaround）
上記のissueのコメント#16にも記載されていますが、headless Chromeの起動オプションに以下を追加してあげるだけです。

```ruby
--enable-features=NetworkService,NetworkServiceInProcess
```

※実際はこんな感じですかね（書き方は色々あるので、環境に合わせてください）

```ruby
options.add_argument('--enable-features=NetworkService,NetworkServiceInProcess')
```

# 最後に
とりあえずChrome側で問題が解決するまでの回避策なので、修正され次第このオプションも不要になります。

# 追記(2019/05/13)

chromedriver v74で、さらに別のバグも発生しているようです。
[chromedriver 74, possible bug with click on item hidden by position:sticky on top](https://groups.google.com/forum/#!topic/chromedriver-users/0Pu-TPvlu18)

このバグをざっくり説明すると、`position:sticky`のように、画面上部に固定表示させる要素（メニューなど）の下にクリックしたい要素が存在すると、クリックに失敗してエラーになる問題です。（画面下の方を表示中に一気に画面上部の要素をクリックしようとしたりすると発生します）

どちらもv74にアップデートしたタイミングで起きるので、問題の切り分けが難しいです。

とりあえず、どちらも報告されているようなので、根本的な解決がされるまではchromedriverのバージョンダウンが妥当な回避策かと思います。（chromedriverのv73はchrome73を要求してくるので、2.46まで下げる必要があると思います）

# 追記（2019/05/28）

上記issueがアップデートされ、`The fix will be in Chrome v75 and above.`（修正はChrome v75以降で行われます。）とのコメントが追加されました。
"以降"というワードが入っているのが気になりますが、しばらくはこのバグとうまく付き合うしかなさそうです。

# 追記（2019/06/06）

[Google Chrome75がリリース](https://chromereleases.googleblog.com/)されました。
これに伴い、chromedriverも最新化することで、最新環境でも無事テストが実施できるようです。（現在テスト実行中...）
Cloud SDK のインストールのパスが上手く行かなかったのでメモ

# はじめに
Cloud SDK のインストールでパスを通すのに手間取ったのでメモ

## 環境
- mac os Mjave 10.14.4
- シェル:fish

# 手順
ドキュメント通り
対話型インストーラ部分と同様にコマンドを打つ

```
$curl https://sdk.cloud.google.com | bash
```

ここで私はfishを使っているため
`~/.config/fish/config.fish`の中身は

```:.config/fish/config.fish
#rbenvのPATH
set -x PATH $HOME/.rbenv/shims $PATH
set -x PATH $HOME/.nodebrew/current/bin $PATH



#Fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showstashstate 'yes'
set __fish_git_prompt_showuntrackedfiles 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_color_branch yellow
set __fish_git_prompt_color_upstream_ahead green
set __fish_git_prompt_color_upstream_behind red

# Status Chars
set __fish_git_prompt_char_dirtystate '⚡'
set __fish_git_prompt_char_stagedstate '→'
set __fish_git_prompt_char_untrackedfiles '☡'
set __fish_git_prompt_char_stashstate '↩'
set __fish_git_prompt_char_upstream_ahead '+'
set __fish_git_prompt_char_upstream_behind '-'

```
このような内容だったのか

```:.config/fish/config.fish

#rbenvのPATH
set -x PATH $HOME/.rbenv/shims $PATH
set -x PATH $HOME/.nodebrew/current/bin $PATH


#Fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showstashstate 'yes'
set __fish_git_prompt_showuntrackedfiles 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_color_branch yellow
set __fish_git_prompt_color_upstream_ahead green
set __fish_git_prompt_color_upstream_behind red

# Status Chars
set __fish_git_prompt_char_dirtystate '⚡'
set __fish_git_prompt_char_stagedstate '→'
set __fish_git_prompt_char_untrackedfiles '☡'
set __fish_git_prompt_char_stashstate '↩'
set __fish_git_prompt_char_upstream_ahead '+'
set __fish_git_prompt_char_upstream_behind '-'

# The next line updates PATH for the Google Cloud SDK.
if [ -f '/Users/nakagawa/google-cloud-sdk/path.fish.inc' ]; . '/Users/nakagawa/google-cloud-sdk/path.fish.inc'; end

```

下の方に三行ほど自動で追加されている
しかしパスの通りがうまく行っておらずコマンドを打てなかった

### 解決策
`set -x PATH $HOME/google-cloud-sdk/bin $PATH`を一応追記しておく

```
#rbenvのPATH
set -x PATH $HOME/.rbenv/shims $PATH
set -x PATH $HOME/.nodebrew/current/bin $PATH
set -x PATH $HOME/google-cloud-sdk/bin $PATH


#Fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showstashstate 'yes'
set __fish_git_prompt_showuntrackedfiles 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_color_branch yellow
set __fish_git_prompt_color_upstream_ahead green
set __fish_git_prompt_color_upstream_behind red

# Status Chars
set __fish_git_prompt_char_dirtystate '⚡'
set __fish_git_prompt_char_stagedstate '→'
set __fish_git_prompt_char_untrackedfiles '☡'
set __fish_git_prompt_char_stashstate '↩'
set __fish_git_prompt_char_upstream_ahead '+'
set __fish_git_prompt_char_upstream_behind '-'

# The next line updates PATH for the Google Cloud SDK.
if [ -f '/Users/nakagawa/google-cloud-sdk/path.fish.inc' ]; . '/Users/nakagawa/google-cloud-sdk/path.fish.inc'; end
```

### 最後にイニシャライズを行った

```
gcloud init
```

ログインして、プロジェクトを選ぶところまでできた
Pandas の transform と apply の基本的な違い

Pythonのデータ分析ライブラリpandasのgroupby オブジェクトに使う transform と apply の違いについて、整理したいと思います。ドキュメンテーションなんでちゃんと書いてないねん！

書く際には以下のstack overflowのサイトを参考にしています。

>https://stackoverflow.com/questions/27517425/apply-vs-transform-on-a-group-object

下のデータを使っていきます。


```python
import pandas as pd
import numpy as np


df = pd.DataFrame({'Year': [1997, 1997, 1997, 1998, 1999],
                   'Japan': [100, 100, 300, 200, 100],
                   'USA': [200, 100, 300, 400, 500],
                   'Canada': [400, 300, 200, 100, 400]},
                  index=['1', '2', '3', '4', '5'])
df
```


Out:

|  | Year | Japan | USA | Canada |
|--:|--:|--:|--:|--:|
| 1 | 1997 | 100 | 200 | 400 |
| 2 | 1997 | 100 | 100 | 300 |
| 3 | 1997 | 300 | 300 | 200 |
| 4 | 1998 | 200 | 400 | 100 |
| 5 | 1999 | 100 | 500 | 400 |


# Pandas の groupby オブジェクトに使う apply
イメージとしては、グループされたものをグループごとに圧縮してしまう感じ。

```python
import numpy as np
df.groupby('Year').apply(np.sum).drop('Year', axis=1)
```

|  | Japan | USA | Canada |
| :-- |:--|--:|--:|
| Year |  |  |  |
| 1997 | 500 | 600 | 900 |
| 1998 | 200 | 400 | 100 |
| 1999 | 100 | 500 | 400 |

5行あったのが3行に圧縮されたのがわかると思います。


#Pandas の groupby オブジェクトに使う transform
イメージとしては、グループされたものにグループ内の要素分に情報を一個ずつ足す感じ。

```python

df.groupby('Year').transform(np.sum)
df
```

|  | Japan | USA | Canada |
|--:|--:|--:|--:|
| 1 | 500 | 600 | 900 |
| 2 | 500 | 600 | 900 |
| 3 | 500 | 600 | 900 |
| 4 | 200 | 400 | 100 |
| 5 | 100 | 500 | 400 |

1行目、2行目、3行目は全て同じ合計となり、applyのように圧縮されない。
なので下のように列をもとのgroupbyする前のデータフレームに足すことも可能です。


```python

df['Canada Yearly Sum'] = df.groupby('Year').transform(np.sum)['Canada']
df
```

|  | Year | Japan | USA | Canada | Canada Yearly Sum |
|--:|--:|--:|--:|--:|--:|
| 1 | 1997 | 100 | 200 | 400 | 900 |
| 2 | 1997 | 100 | 100 | 300 | 900 |
| 3 | 1997 | 300 | 300 | 200 | 900 |
| 4 | 1998 | 200 | 400 | 100 | 100 |
| 5 | 1999 | 100 | 500 | 400 | 400 |

データフレームは圧縮されないのでこのようにデータフレームに値を1行ずつ足して行くことも可能


#終わりに
transform, apply ともにうまくやれば頭良く問題を解決できそうですね。これからもちょっとこの二つのアルゴリズムで試行錯誤していこうと思います。
[物体検出]YOLOv3を動かしてみよう！

##はじめに
こんにちは！
今回は今までに引き続き、プログラミングを始めたての僕みたいな人でも視覚的にプログラミングを実感できる記事を書いてみました！
テーマは「YOLOv3」。熟練者にはすでに馴染みのある名前だと思いますが、初心者には聞き慣れない言葉ですよね、、、。

それではまずYOLOv3がどういうものなのかを説明していきます。

##YOLOv3ってなに？
YOLOv3のYOLOとは「You Only Look Once」の略であり、日本語にすると「一目見るだけで良い」という意味になります。
2016年に発表されたものであり、それまでの物体検出には無かった**1つのCNNで物体検出からクラス分類まで全て行う機能**を実装した画期的なモデルなんです。
かの有名なTEDで発表された際も聴衆に多大なインパクトを与えたそうです。
では、そんなYOLOv3を誰でも簡単に試せてしまうやり方を確認していきましょう！
##筆者の開発環境

・macOS Mojave バージョン10.14.3
・MacBook Air(11-inch, Early 2015)
・プロセッサ 1.6 GHz Intel Core i5
・Python 3.7.1

これで問題なく動きました！

##手順
①まずterminalを開き 「mkdir yolov3」と打ち込んでenterキーを押し、yolov3のフォルダを作成します。

②続いて「git clone https://github.com/pjreddie/darknet」 と打ち込みenterキーを押します。
するとダウンロードが始まりますので気長に待ちましょう。

③次に「cd darknet/」と打ち込んでenterキーを押し、次に「make」と打ち込みます。するとまた長々と処理が始まりますので気長に待ちましょう。

④処理が終わったらインターネットで「https://pjreddie.com/darknet/yolo/」 と検索し、ページの下の方にある「here(237MB)」をクリックして必要なモデルをダウンロードします。ダウンロードが完了したら先ほど作ったyolov3フォルダの中のdarknetの中に保存しましょう。保存し終わったらそのyolov3フォルダをデスクトップに配置しちゃいます。

⑤そしてまたターミナルを開き、先ほどの続きから「./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg」と打ち込みます。この dog.jpg というのは　darknetというフォルダの中にあるdataフォルダに入っている画像なのですが、この画像を使って試しに物体検出をしてみます。

⑥処理が終わったら結果がterminalに表示され、検出済みの画像がprediction.jpgとしてdarknetに保存されています。
dog.jpgを使った場合、こんな画像になります。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134363434382f36383061303132632d656361622d613631362d326632662d6439643630643363633462332e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405324/52132709-1b5d-eec5-e63c-bfb68bb116e7.png)


##終わりに
いかがだったでしょうか？
こんな感じで簡単に物体検出ができちゃいます！
始めたてだと、何か視覚的にプログラミング結果が出た方が絶対面白いのでとてもオススメです。
プログラミング歴に関係なく本当に簡単なので、自前のjpg画像で試してみると面白いですよ！

では、また次の記事で！
Five common criteria of the Test coverage

Test Coverage
===
1. Statement Coverage  
the coverage by every line of code  
the coverage is 100% != all clear of the test
2. Loop coverage  
the coverage by every loop in the code
3. Branch Coverage  
the coverage by every if or else statement of code
4. Function Coverage  
the coverage by every function in the code
5. Condition Coverage   
the coverage by every logical test in the code
Rails + Nuxt + GraphQLでSSR対応のSPAを作る場合の俺的ベストプラクティス

個別のライブラリについての記事はたくさんありますが、
どれをどう組み合わせれば楽に作れるか？の情報がなかったので、書きました。
それぞれについての詳しい情報はぐぐってください。

この記事で紹介するライブラリを組み合わせると以下のことができます。

## 実現できること

- SSR対応のSPA
- 各ページ一回のリクエストで描画に必要なデータをすべてもってこれる
- N + 1問題を防げる
- つなぎこみのコードが少なくて済む(サーバーのコントローラーやクライアントのストア)

## ライブラリ

- rails
- graphql-ruby
- graphql-batch
- search_object
- search_object_graphql
- nuxt
- vuex-orm
- vuex-orm graphql plugin
- isomorphic-fetch

## graphql

railsなのでIDのタイプはBigIntにしようとしたが、
idがstringになってしまうので
Floatにした。53bitまで

## graphql batch

graphqlのtypeは遅延評価で書いていく。
N + 1問題を防げる。
単純な関連だけではなく、computedなカラム(ユーザーが持つ記事の数など)も高速にserializeできる

## search_object + search_object graphql plugin

フィルタ付きのgraphql resolverをかんたんに書ける。
でもちょっとしか使っていないので、こいつが本当に良いのかはあまり良くわかっていない。

## クライアント側のデータ管理

各ページのasyncDataで、そのページに必要なデータをすべて取得する。
GraphQLで関連を一気に取得して少ない回数で取得する。

## vuex orm

マジで快適。
いちいち検索するコードとかを書く必要がなくなる。

モデルにcomputedなカラムもかんたんに追加できる。
いちいちモデルをimportするのが面倒なので

this.$store.models.User

みたいに$storeにmodelsを無理やりはやした。

railsはincludesしなくても必要になればロードしてくれるが、こいつはwith(includes相当のもの)をつけないと、nullになるので要注意。小一時間ハマった

もう一個のハマりポイントは、
モデルにはやしたインスタンスメソッドがタイミング次第で呼べないことがある。

- ブラウザリロード直後 -> ちゃんと表示される (SSR)
- ブラウザリロードして少し後 -> 表示が崩れる (インスタンスメソッドを呼べてない)
- リロードせずに遷移 -> ちゃんと表示される (インスタンスメソッドを呼べている)

vuex ormのfindとかはstoreのデータを返しているだけ。
返すときにdecorateしたりとかはしないらしい。

https://github.com/vuex-orm/vuex-orm/blob/5cd4049caa4b1706e9268713b3062a4c70274748/src/model/Model.ts#L317

vuex ormを改良するか、インスタンスメソッドではなくstaticメソッドで、
Model.myComputedColumn(instance)とするかが良いと思う。

多分ここでは？
https://github.com/vuex-orm/vuex-orm/blob/eab95aabe805b39244ac8ca7eb2096330cd56ab7/src/query/Query.ts#L558

eager loadのカラムが一つもないと、生データが返ってしまう。

仮説

- リロード直後はSSRで渡されたplain objectがstoreに入っている
- vuex orm初期化時にはhydrateされない
- 更新時にhydrateされる
- 遷移時には更新されるのでhydrateされてplain objectからモデルに変換されるから、遷移時には正しく表示される
- findでも関連がある場合に限りhydrateされる <- こいつを強制すれば良い

-> なおった
https://github.com/contribu/vuex-orm/compare/master...feature/fix_hydrate

あと、これって二重にhydrateされていないか？
動作に問題はないと思うが、
hydrateIfNeeded的な仕組みにすればすっきりすると思う

## vuex orm graphql plugin

取得系はマジで快適

- 取得クエリがかんたん (vuex ormのモデル定義からクエリ生成)
- ネストしたモデルを自動的にvuex ormに書き込んでくれる

Eager loadは工夫する必要がある。
railsのincludesみたいに、取得するときにどの関連を含めるか含めないかを調整できれば良いが、その機能は無くて固定。
だから、取得前にモデルのeagerLoadを書き換えて、取得後に戻すやり方にした。

vuex orm graphql pluginのmutationは、InputTypeが元のモデルのタイプと一致することを要求するので、使いづらい。
ここは自前でmutationとのつなぎこみを書いていく。

vuex orm graphql pluginの代替や、vuex orm graphqlでうまくやる方法を知っていたら教えてください。

isomorphic-fetchを使うとSSRできる。

## サーバーのエラー処理

rescue_fromでActiveRecordのエラーなどをGraphQL::ExecutionErrorに変換していく。詳細はぐぐって

## サーバーのgraphqlのテスト

request specとして書いていく。graphqlは生で書く
(こんな感じになる https://selleo.com/blog/testing-graphql-mutations-in-ruby-on-rails-with-rspec)
と思ったが、クエリーを作るのが意外と面倒。

以下のやり方が良さそう。
https://medium.com/@RJrobinson/testing-graphql-ruby-mutations-with-rspec-f5c7d02b1e58
ベタ書き版: https://graphql-ruby.org/schema/testing.html

もっと良いやり方があったら教えてください
PythonでGoogleしごと検索の検索結果を取得する〜スクリーンショットも添えて〜

今年に入ってから、社内／個人案件でSeleniumを使って色々とスクレイピングしまくって( # ´Д｀)ﾊｧﾊｧしてたのですが、その流れで[Googleしごと検索](https://developers.google.com/search/docs/data-types/job-posting?hl=ja)をスクレイピングしてみることにしました。

今までは[facebook/php-webdriver](https://github.com/facebook/php-webdriver)でやっていたのですが、今回はPythonでやることに。

## 環境

| macOS | python | pip |
|:-----:|:------:|:---:|
| High Sierra 10.13.6 | 3.6.4 | 19.0.1 |

## おソース

jobs.py

```python
import sys
import time
import datetime
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException

# コマンドライン引数を受け取る
words = sys.argv
# 第二引数をwordに格納
word = words[1]

print('"' + word + '"' + 'で検索...')
print('----------------------------------------------')

# setting user agent
ua = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0',
]
    now = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')

# init Options
options = Options()
options.add_argument('-headless')
options.add_argument('-user-agent=' + ua[0])

geckodriver = 'geckodriver'

# set Options / chromedriver
driver = webdriver.Firefox(firefox_options=options)
# set window size
driver.set_window_size(450, 3320)
# set default wait
driver.implicitly_wait(6)

# go to URL
driver.get('https://www.google.com/search?ie=UTF-8&ibp=htl;jobs&htivrt=jobs&q=' + word)
# wait for rendering
time.sleep(5)

elements = driver.find_elements_by_css_selector('.tab-sel ul > li')
# print(elements)

if elements:
    for i, li in enumerate(elements):
        h1 = li.find_element_by_css_selector('.gsrt').text
        print(str(i+1) + '位 ' + h1)
        for item in li.find_elements_by_css_selector('.gsrt + div > div'):
            print('- ' + item.text.replace('\n', '、'))
        print('----------------------------------------------')
    driver.save_screenshot('sr_' + now +'.png')
else:
    print('要素がありませんでした...')

driver.quit()
```

## 検索方法

1. python／pipの実行環境を構築（適当にググってください
1. `pip install selenium` でseleniumをインストール
1. OS／環境に合わせて[geckodriver](https://github.com/mozilla/geckodriver/releases/tag/v0.24.0)をDL、解凍後、カレントディレクトリに配置
1. カレントディレクトリで `python jobs.py "キーワード"` を実行

## 検索結果（例

```zsh
❯ python jobs.py "渋谷　求人　エンジニア"
"渋谷　求人　エンジニア"で検索...
----------------------------------------------
1位 【渋谷】【時短相談可】サイバーセキュリティエンジニア
- パーソルテクノロジースタッフ株式会社
- 東京都渋谷区
- 提供元: リクナビ派遣
- 1 日前、1 時間 ￥4000
----------------------------------------------
2位 【渋谷！3100円～】ネットサービス会社でのNWエンジニア
- パーソル パナソニック HRパートナーズ株式会社　テクニカル事業本部
- 東京都渋谷区
- 提供元: リクナビ派遣
- 1 日前、1 時間 ￥3100～￥3300
----------------------------------------------
3位 【6月スタート】渋谷駅チカ♪交支給☆セールスエンジニア
- ヒューマンリソシア株式会社
- 東京都渋谷区
- 提供元: リクナビ派遣
- 6 時間前、1 時間 ￥3100
----------------------------------------------
〜〜 略 〜〜〜
----------------------------------------------
20位 システムエンジニア（SE）,サーバーサイドエンジニア
- 社名非公開
- 東京都渋谷区
- 提供元: フューチャリズム
- 1 か月以上前、月 ￥70万～￥80万
----------------------------------------------
```

取れた！！

一応整合性取れてるかを確認したかったので、スクショも取るようにしてみました。

## まとめ

Seleniumすごいよ( # ´Д｀)ﾊｧﾊｧ
アプリ内課金(定額課金)停止(iOSメイン、Androidも少し)

App内課金(今回は定期購読)の取り下げについて
あまり説明がないので記載します。
iOSは簡単です、iOSは。

1.App Store Connect > マイAppで該当アプリ選択 > 機能 > App内課金
で該当のApp内課金を選択する。
2.配信可否?という項目の下に、配信可能のチェックボックスがあるのでチェックを外す。
サインインしているAppleIDの権限によっては、このチェックボックスの制御ができない(チェックを外せない)
ので注意！
チェックボックスを外すと下記のアラートが表示される。

![スクリーンショット 2019-05-09 14.30.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74276/759fcf81-1b82-6775-84b8-7b31b20d10eb.png)

3.上記アラートのチェックをつけると、配信から削除を選べるようになるので
配信から削除ボタンを押す。

4.下記のように、「ディベロッパによりストアから削除済み」が表示される。
![スクリーンショット 2019-05-09 14.55.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74276/f3e9f673-c87e-afe1-26e2-266ccb22f558.png)

5.App Storeの反映は2時間程度でした。
年齢の下に記載されている
App内課金　あり
との表示は消えていました。

Androidの方は
こちらの方が書いているように
「１度有効にした定期購入アイテムは無効にできない」
そうです。
対応としてはアプリのUPDATEで
課金する箇所を無くしてしまう
&
すでに定額課金ユーザーは
Google Play Console > 注文管理
で一件ずつ
定期購入を解約
をポチポチ押しました。
https://qiita.com/84d010m08/items/ed116296bfd21f26e0ee
Ruby  module_function

## module_functionとは

- モジュールで定義されているメソッドを、**モジュール関数**として扱えるようにするためのメソッド。
- 引数にメソッド名が指定された場合はそのメソッドがモジュール関数になる。
- 指定されなければ`module_function`の定義以降に定義されたメソッドがモジュール関数になる。

指定しなければメソッドは**private**で定義される。

##### 定義例
Ruby技術者認定試験合格教本 p298

`module_function`で指定したメソッドを同クラス内で呼び出せるようにしている。

```ruby
# 引数指定

module M
  def bar
    puts "OK"
  end

  def foo
    puts "BAD"
  end
  
  module_function :bar # 引数にはシンボルでメソッド名を指定
end

M.bar # => OK
M.foo # => undefined method `foo' for MyMethods:Module (NoMethodError)
```

```ruby
# 複数指定

module M
  def bar
    puts "OK"
  end

  def foo
    puts "BAD"
  end
  
  def hoge
    puts "HOGE"
  end
  
  module_function :bar, :foo # 複数指定する場合
end

M.bar # => OK
M.foo # => BAD
M.hoge # => undefined method `foo' for MyMethods:Module (NoMethodError)
```

```ruby
# 引数を指定しない

module M
  def bar
    puts "OK"
  end
  
  module_function

  def foo
    puts "BAD"
  end
end

M.foo # => BAD
M.bar # => undefined method `foo' for MyMethods:Module (NoMethodError)
```
---

##### クラス内で使用する

```ruby
class TestClass
  module M
    def hoge
      puts "Hello"
    end

    module_function :hoge
  end

  # Mクラスのインスタンスメソッド「call_hoge」内でモジュール関数「hoge」を呼び出し

  def call_hoge
    M.hoge
  end

  # Mのクラスメソッド「hogehoge」内でモジュール関数「hoge」を呼び出し
  def M.hogehoge
    M.hoge
  end
end

a = M.new

puts a.call_hoge      # => Hello
puts M.hogehoge   # => Hello
```

##### クラス内でincludeして使う

```ruby
module M
  def hoge
    puts "World"
  end
  
  module_function :hoge
end

class C
  include M
  
  def piyo
    hoge
  end
end

hoge = C.new

# module_functionでモジュール関数として指定しているのでトップレベルで呼べる
M.hoge # => World

# Cクラスのインスタンスメソッド内で呼んでおりますので呼べる
hoge.piyo # => World

# privateメソッドなのでオブジェクトからは呼べない
hoge.hoge # => private method `hoge' called for #<TestClass:0x0000564bdaed4e10> (NoMethodError)
```

今回はここまで。

リファレンス: [Module#module_function](https://docs.ruby-lang.org/ja/2.6.0/method/Module/i/module_function.html)
eclipse起動しなくなった。

![Screenshot from 2019-05-09 15-44-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413217/975d23c9-8a79-9a8a-24ee-bccc9d5faea5.png)
![Screenshot from 2019-05-09 15-44-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413217/1271109d-3bdc-f4d7-3500-36e94d4ceb01.png)

java初心者です。
LinuxのcentOSを使っています。
昨日の夜JDKとJREの自動更新があり、今日eclipseを起動したらこのようなエラーが起きました。理由がわからず、調べたところJDKとJREのパスをEclipse内の.iniファイルに新しく書き直さないとダメなところまではわかりましたが、ファイル内のどこを書き直せばいいかイマイチわかりません。よろしくお願いします。
[ポートフォリオ] Outingについて

# はじめに
はじめまして。
現在就職活動中でポートフォリオを作成したのでそれの説明をしたいと思います。

# ポートフォリオのURL
https://outing-app.herokuapp.com/

email: tester@gmail.com
password: 111111

# 主な機能
○ [devise](https://qiita.com/k19911848/items/fe5f48b3d2c902ac07a2)を用いたユーザー管理機能
　・ 新規ユーザー登録機能
　・ ユーザーログイン機能
　・ ユーザー詳細機能
　・ ユーザー編集機能
　・ [deviseの日本語化](https://qiita.com/k19911848/items/8ed4225e9a99beb9b901)


○ 問題管理機能
　・ 問題投稿機能
　・ 問題編集機能
　・ 問題削除機能
　・ 問題検索機能(部分検索)
　・ 問題詳細機能
　・ 問題一覧機能

○ 問題集機能
　・ 問題集作成機能
　・ 問題集の中の問題タイトルをクリックすると問題、答えが見れる

○ 問題へのコメント機能
　・ 問題へのコメント(訂正要望)機能

○ 問題へのいいね機能
　・ [Ajaxを使ったいいね機能](https://qiita.com/k19911848/items/69cd7e5ab11e5240c1f5)

○ その他
　・ ページネーション機能(kaminari)
　・ fontawesome

# ポートフォリオ概要
新しい技術を学ぶエンジニアが繰り返し復習をして、知識の定着を図るアプリです。


# 何ができるのか
#### ・自分が学んでいることをタイトル、問題、答え、カテゴリーを付けて問題形式で投稿出来る。
![create_post.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/f6998670-013b-fcea-3420-e4b7c7af4ff3.gif)

#### ・問題詳細では「答えを見る」ボタンを押すと答えが表示される。

![comment_like.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/49051083-2a4a-b5da-159b-373d71eda4c0.gif)


#### 好きな問題を集めて問題集を作成することが出来る。

![create_folder.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/1c69c6e5-b749-2104-56db-8c59579288e4.gif)


#### カテゴリーで問題を探すことが出来る。

![category.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/bda9a38e-2007-ff84-9765-c061b37460c6.gif)


#### ユーザーページでは投稿した問題やいいねした問題、問題集を見ることが出来る。


![mypage.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/b794e60e-5dd1-3408-6fb0-9383d48979ca.gif)


# どうやって作成したのか

1. 必要な機能を洗い出す。

2. その機能を実現するために必要なテーブル、カラムを洗い出す。

3. ER図を作成
<img width="772" alt="スクリーンショット 2019-05-09 15.08.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297896/7b36f3fe-fb65-9733-7e10-9050a8d3875f.png">
 
4. 各リソースを追加
UserやPostといった核となるリソースから順に追加。

5. デバッグの繰り返し
binding.pryやrails cを何回も繰り返し、値が取れていなかったらなぜ取れていないのか仮説と検証を行った。


# 工夫したところ

#### 問題集機能

複数の問題を１つの問題集にまとめる作業に苦戦したので,Railsドキュメントでselectやcollection_selectについて調べました。

また、ある問題集に入っている問題を引っ張って来たかったので中間テーブルを作成し、そこから該当する問題を引っ張ることに成功しました。

#### カテゴリー機能
ローカル環境、本番環境にカテゴリーを反映する方法に悩んでいたのでdb/category.csvを作成し、rails db:seedとすることで反映させることに成功しました。

#### リファクタリング
コードの重複を少しでも無くすために、部分テンプレートを用いて複数箇所で使用することを意識していました。


# このアプリの課題
・ 問題集に問題を後から追加出来るようにする
・ コメント機能のAjax化
・ RSpecで対象リソースをテスト
・ レスポンシブ対応にしているものの少しPCとスマホでは挙動がおかしい箇所があるのでそこの訂正

# スペック
・Rails 5.2.3
・Ruby 2.5.1

# DB
・ローカル環境 mysql 5.6
・本番環境　pg

# サーバー
heroku

# 最後に
Github: https://github.com/katsu-2
twitter: https://twitter.com/k19911848
もう１つのアプリ: https://teachme-original.herokuapp.com/
今更ながらDocker マルチステージビルド

普段docker-compose以外使わないのにDockerの情報を追っていないので最近知った…
やってみるととても簡単にdockerイメージの軽量化が出来た


### マルチステージビルドとは
イメージの軽量化が簡単になる、実行用イメージのビルドが複雑にならない
こんな感じで捉えてる

### どう使うのか
FROMを複数回記述して、ステージを分ける
段階を踏んで書こうかと思ったけど簡単なので最終的なDockerfileを載せる

その前に各段階のイメージサイズ

```
multistagebuild  1.0.2  449a87da267a  32 minutes ago  5.53MB  // マルチステージビルド
multistagebuild  1.0.1  90ff9debf4c2  35 minutes ago  29.4MB  // apk addで色々入れてるマルチステージビルド無し
multistagebuild  1.0.0  8381b349a14f  40 minutes ago  5.53MB  // alpine:3.9.3そのまま
```

`1.0.0`はalpineをFROMで指定しただけのままでビルド
`1.0.1`はalpine+apk addで色々入れたやつ
`1.0.2`はalpine+apk addで色々入れてるのをビルドステージに指定して、実行コンテナをマルチステージビルドで指定 1ファイル追加してるだけなので`1.0.0`と同じサイズ(数KB増えてるはず)



マルチステージビルドを使ったDockerfile
ビルドステージで生成したファイルを実行用イメージにコピーしてその中身をcatするだけの実行イメージを作成

```dockerfile:Dockerfile
# ビルドステージ
FROM alpine:3.9.3 AS build_stage

RUN apk update && apk add openssh && apk add curl
RUN apk add git
RUN apk add htop
WORKDIR /tmp
RUN touch ttt.txt
RUN echo "multistagebuild copy from build_stage" >> ttt.txt

# 実行用イメージ
FROM alpine:3.9.3

WORKDIR /app

COPY --from=build_stage /tmp/ttt.txt /app/ttt_cp.txt

CMD ["cat", "/app/ttt_cp.txt"]
```


生成されたイメージを実行してみる

```
docker run --rm -it --name multistagebuild multistagebuild:1.0.2
> multistagebuild copy from build_stage
```
で、でたぁ〜
はい。



### まとめ
FROMだけで出来るなんてお前は何て優しいやつなんだ…
ビルドステージという単語を使ってるがそんな言葉があるか知らん、雰囲気で使っている



### 参考
[Docker docs - Use multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/)
IEEEの国際会議用LaTeXテンプレートを使って会議名を全ページのヘッダに付与

##使用したテンプレート
[Manuscript Templates for Conference Proceedings](https://www.ieee.org/conferences/publishing/templates.html)
Latex Template (ZIP, 700 KB) Updated July 2018

＃投稿時点で最新のテンプレート

解凍して出てくる以下のファイルを使用．

- conference_041818.tex
- IEEEtran.cls

#会議側の指示 
[Instructions for Authors](http://ipin2019.isti.cnr.it/instructions)
会議名を全ページのヘッダに入れてね．以下をコピペすればできるよ．

```
\confheader{
	\centering\parbox{18cm}{2019 International Conference on Indoor Positioning and Indoor Navigation (IPIN), 30 Sept. - 3 Oct. 2019, Pisa, Italy}
}
```

#エラー

```
    ! Undefined control sequence.
l.15 \confheader
                {
```

\begin{document}の上辺りに上記の部分をコピペしてコンパイルしても肝心のconfheaderが未定義と言われコンパイルできない．ちょっとInstructionとしては不親切と思う．

#無理やり定義する

IEEEtran.clsにはタイトルページ（IEEEtitlepagestyle）とその他のページ（headings）についてそれぞれスタイルが指定されているのでそれぞれについて会議名をヘッダに出すように上書き定義．

```
\makeatletter

\let\old@ps@IEEEtitlepagestyle\ps@IEEEtitlepagestyle
\let\old@ps@headings\ps@headings
\def\confheader#1{%
    % for the first page
    \def\ps@IEEEtitlepagestyle{%
        \old@ps@IEEEtitlepagestyle%
        \def\@oddhead{\strut\hfill#1\hfill\strut}%
        \def\@evenhead{\strut\hfill#1\hfill\strut}%
    }%
    \def\ps@headings{%
        \old@ps@headings%
        \def\@oddhead{\strut\hfill#1\hfill\strut}%
        \def\@evenhead{\strut\hfill#1\hfill\strut}%
    }
    \ps@headings%
}

\makeatother

\confheader{
    \centering\parbox{18cm}{2019 International Conference on Indoor Positioning and Indoor Navigation (IPIN), 30 Sept. - 3 Oct. 2019, Pisa, Italy}
}

\begin{document}
```


#参考にしたページ
[conference header is applied to all pages](https://tex.stackexchange.com/questions/375495/conference-header-is-applied-to-all-pages)

↑ではタイトルページにしか会議名出せなかったので改造した．


#おわりに

これでやっと投稿できそうだけどRejectされたら寂しい
Webシステムの構成

Webシステムについて改めてまとめてみました。

# Webシステムとは
インターネットを利用したシステム、インターネットを利用しているアプリケーションを構成するシステムなどのこと、ブラウザを介して利用するサービスのことを指す。

# 実際にどういった動きをするのか
Webサイトを閲覧する際の例を見てみる。
サイトにアクセスするとそのサイトのデータを要求するリクエストというものがサーバへと送られる。
そのリクエストに応じてサーバ側はデータを返すレスポンスが返ってくる。
ブラウザは受け取ったデータを画面に表示するレンダリングを行う。
上記のリクエストとレスポンスの部分がネットワークを利用して行われる。
ブラウザからネットワーク、そしてサーバ。
この３つの要素からWebシステムが成り立っている。

# ブラウザ
サーバにリクエストを送り、受け取ったデータを元に画面に表示させる役割を担う。
HTMLやCSS、JavaScriptなどの言語で書かれたプログラムを実行し表示させる。
ブラウザには種類があり、一般的に多く利用されているのがChromeだと思われる。
その他にもFirefoxやedge、Safariなどがある。

# サーバ
ブラウザから送られるリクエストに応じてレスポンスを返す役割を担う。
Webシステムを構成する主なサーバはWebサーバ、アプリケーションサーバ(Appサーバ)、データベースサーバ(DBサーバ)の３種類。

## Webサーバ
レスポンスを行うサーバ。
内容の変化しない静的なコンテンツのみを扱う。
では内容の変化するコンテンツ、例としてログインを行いユーザーによって表示が異なるものはどうなるのか。
そこで必要になるのがAppサーバになる。

## Appサーバ
動的なコンテンツを扱う。
Webサーバが受け取ったリクエストに応じて内容を構築する。
ここで必要になるのはどのページを求められているのかという情報とその内容を表示するためにはどんなデータが要るのかというところ。
そのデータを扱うのがDBサーバになる。

## DBサーバ
データの保存や集計、検索などを行う。
登録されているユーザの情報や他の情報など、データを扱っている。
Appサーバから要求された情報を返す。

それぞれのサーバがそれぞれの働きをすることによって一つのシステムを構成する。
システムの内容や規模によっては構成が変わる。

# まとめ
Webシステムはブラウザから利用できるサービスを提供するためのもの。
ブラウザ、ネットワーク、サーバの要素から成り立っている。
ブラウザがお客、Webサーバがウェイター、Appサーバがコック、DBサーバが農家で例えるとわかりやすいかもしれない。
すべてのプログラミング言語は機械語として認識するには

C言語を勉強しはじめて、PascalのコンパイラをC言語に書き直していた時、
「機械語はわかるんですがLISPはわからなくて」
と発言したら
「LISPも機械語だ」
との返事をいただいた。

まだ、LICP Machineなるハードウェアが存在した当時。
IntelのCPUが32bitでどんどん安価になりLISP Machineよりも費用対効果がよくなって、
結局LISP Machineが流行らなかった頃。

たしかにLISPは機械語だ。

その言語を直接処理できる機械があれば。

言語以外の機能が、できるだけハードウェアで設計してあれば。

あるいは、JAVAのようにVirtual Machine(VM)を前提にしたとしても、
そのVMをハードウェア化すれば、機械語だといばれる。

じゃ、どの言語の機械を作るのが難しいかで言語を考えてみれば、
言語の分類に役立つかも。

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
uGUI で RectTransform の Scale を拡大している場合に Stretch したい

# Anchor の Strech と Scale の拡大を併用したい

ドット絵でUIを作っていて、素材そのままだと解像度が小さいため素材を2倍の大きさで使いたい場面が多々あります。（つまり、widthやheight を2倍にして要素のサイズを大きくしたいのではなく、 要素に使われているSpriteの素材を大きく表示したい）

これを↓
<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/7f31396d-9362-495d-d10e-a54c6bf499f2.png">

こうしたい↓（Scale 2倍、要素サイズは上記と同じ）
<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/959fb733-7d56-d3b5-538e-b27973d9fe81.png">

## これを可変させたい

Anchorのプリセットを選ぶことで任意の方向に可変させることができますが、

<img width="300" alt="プリセット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/0ef541c5-d646-22d4-9b7c-9623c581a6a9.png">

例えばScaleが `(1, 1, 1)` の場合だと

![scale1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/f043b7c0-b9c0-758e-8c42-f06e69d8f63d.png)

期待通り引き伸ばされます。
が、Scale が `(2, 2, 1)` の場合だと、

![scale2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/2d211dd4-bfef-3ac6-ad12-29f46d36b868.png)

上記のように引き伸ばしが効き過ぎておかしなことに。


## 解決方法

Anchorの横方向stretchプリセットの内容は、 Anchors **MinX = 0、 MaxX = 1** です。
これはScaleが `1, 1, 1` のときにいい感じに動きます。 

これを 先の例のようにscaleが `(2, 2, 1)` で動くようにするには
**MinX = 0.25、 MaxX = 0.75** となります。

また `(4, 4, 1)` のときは
**MinX = 0.375、 MaxX = 0.625** という感じ。

![scale4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/36e97e9d-a5cf-7e1d-2cf4-42fbb3676089.png)


# まとめ

横方向に Stretch したい場合、下記の式でいい感じになりました。
（MinY、MaxY も同様）

**MinX = 0.5 - 0.5 / (拡大率)**
**MaxX = 0.5 + 0.5 / (拡大率)**

正直Anchorの値はほぼ触らないで開発してきましたがちょっと仲良くなれました。
Anchorっていうとピンとこないけど、 **0.5を中心にして伸びる比率** ということかな。
1（or 0） は最大に伸びる、 0.5は伸びない。（ちょっと説明が下手すぎるか。。。

例えばscale4倍で横方向の右側にだけ引き伸ばしたい場合は、pivotも右に固定し、
**PivotX = 0, MinX = 0.5、 MaxX = 0.625** でいけます。 （Minは左、Maxは右）

![scale4-b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49417/261a1726-1f09-4200-a50e-3a5a3ad1c3da.png)
SourceTreeでGithubが選択できない

### しばらくぶりのSourceTree
初めてgitを触った現場で**「概念を理解するのに`SourceTree`を使った方がいいよ」**ということで、
`Github`を使用していた現場で`SourceTree`を使っていました。

現場が変わり、VPNでお仕事することになりコマンドでgitの使い方を覚えてきたので`SourceTree`とはおさらば状態でした。
`Bitbucket`の現場でも`Github`の現場でも難なく`git`を使用しておりました。

しかし、`Github`を使ってる現場で**「ブランチ視える化して」**と依頼されたので
久しぶりに以下から`SourceTree`の**最新版**をダウンロードしてきました。
https://ja.atlassian.com/software/sourcetree
### SourceTreeでGitHubが設定できない！？
`SourceTree`の**最新版**はGUI上で`Bitbucket`と`BitbucketServer`しか選べず、
`Github`の選択肢が無くなっていました…

他の人みんな`SourceTree`使えてるのに何故…

###結論

`Github`の選択肢を使いたい人は、
以下のアーカイブから`Sourcetree_2.6.3`をダウンロードする必要があります。
https://www.sourcetreeapp.com/download-archives

どうやらバージョン2.7から無くなった模様です。