OmniAICreator/Qiita-1.07M huggingface dataset:
.Net CoreプロジェクトでC#のバージョンを変更する方法

#はじめに
`.Net Core`プロジェクトでコンソールアプリを開発するときに、C#の言語バージョンを変更したいときがあります。

例えば、コンソールアプリでMainメソッドに`async`をつけたいときです。
しかし、Mainメソッドに`async`をつけられるのはC#7.1からです。
現時点（2019年1月8日）におけるメジャーバージョンは7.0であり、プロジェクト作成時にはデフォルトでこのメジャーバージョンが選択されるため、Mainメソッドには`async`をつけることができません。

Visual Studioを使っているのであれば、以下のようにプロジェクトの`プロパティ`から`ビルド`タブの一番下の`詳細設定`をクリックすると、言語バージョンを選択することができます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/1a8f42fd-ee13-e8a3-5d55-9da3638809af.png" title="" alt="image.png" width="60%" height="" >

しかしながら、`.Net Core`はWindows以外の環境で開発することもあるため、この方法は使えません。

#やりかた
`.csproj`ファイルを編集します。
プロジェクトフォルダの中に`プロジェクト名.csproj`というファイルがあります。
これを開くと以下のようになっています。

```xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

      <!--省略-->

</Project>
```

この中の`PropertyGroup`要素の中に以下の要素を追加します。今回は言語バージョンを`7.1`にするものとします。

```xml
    <LangVersion>7.1</LangVersion>
```

追加後の全体としては以下のようになります。

```xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <LangVersion>7.1</LangVersion>
  </PropertyGroup>

      <!--省略-->

</Project>
```

これでC#7.1の機能を使うことができます。

指定できる言語バージョンとそれぞれの説明については[公式のこちらのページ](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/configure-language-version)を参照してください。
Djangoのforms.pyでメソッドを使ったフォームのバリデーション

#環境
- Django2.1

#特定のカラムに対してバリデーションする
特定のカラムに対してバリデーションするメソッド名の命名規則はclean_\<fieldname>() となる。
したがって、slugカラムについてのバリデーションする場合のメソッド名はclean_slug()となる。

```python:forms.py
from django.forms import ModelForm, ValidationError


class NewsForm(ModelForm):
    class Meta:
        model = News
        fields = ('title', 'slug')

    def clean_slug(self):
        slug = self.cleaned_data['slug']
        existing = News.objects.filter(
            slug=slug
        ).exists()
        if existing:
            raise ValidationError({
                'symbol': ['このスラッグはすでに登録されています。']
            })
        return slug
```
[特定のフィールド属性をクリーニングする](https://docs.djangoproject.com/ja/2.1/ref/forms/validation/#cleaning-a-specific-field-attribute)

#複数のカラムにまたがってバリデーションする
clean()で複数のカラム（フィールド）によるバリデーションが可能である。
clean()は特定のカラムに対してバリデーションが実行された後に実行される。
>フォームの clean() メソッドが呼び出されるまでに、個別のフィールドのクリーンメソッドが呼び出されているので (上記 2 つのセクションで見た通りです)、self.cleaned_data にはこれまでのクリーニングで生き残ったデータが格納されています。したがって、検証しようとしているフィールドが、この個別フィールドのチェックを生き残っていない可能性を考慮する必要があります。

```python:forms.py
from django.forms import ModelForm, ValidationError


class NewsForm(ModelForm):
    class Meta:
        model = News
        fields = ('title', 'slug')

    def clean(self):
        cleaned_data = super(PersonForm, self).clean()

        existing = News.objects.filter(
            ...
        ).exists()
        if existing:
            raise ValidationError({
                'symbol': ['登録済みです。']
            })
        return cleaned_data
```
[互いに依存するフィールドをクリーニングして検証する](https://docs.djangoproject.com/ja/2.1/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other)
Yarn で windows-build-tools がインストールできなかった

Node.js でビルドとか Sass とか動かそうとすると Windows にないコマンドを使っているため実行できないことが多々あり、解消するために `windows-build-tools` というものがあるのですが、これがどうにもこうにも `yarn` でインストールできなかったので、インストールできた時の対処法を備忘録として残しておきます。

# 現象
兎にも角にも下記のような画面になり、`yarn global add windows-build-tools` が途中でハングアップしてしまいます。
![2019-01-08.png](https://qiita-image-store.s3.amazonaws.com/0/131358/3d9a764f-a510-717d-7954-6b1ca95c7b37.png)

# 回避策
調査方法は後述するとしてインストールできた手順を示します。

## 方法（い）
- `%USERPROFILE%\.windows-build-tools` フォルダを削除する。
- `Python27` を削除する。
    - Windows の `アプリと機能` からアンイストールする。
    - `Python27` がインストールされていたフォルダを探して削除する。（`C:\Python27` など）
- `yarn global add windows-build-tools` を `cmd.exe` もしくは `PowerShell.exe` で管理者権限で再実行する。（重要）

## 方法（ろ）
- [Python2.7](https://www.python.org) をインストールする。
- [Visual Studio Build Tools 2017](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) を下記を含む構成でインストールする。
    - デスクトップ用VC++ 2015.3 v14.00（v140）ツールセット（必須）
    - Node.js ビルドツール （多分必須）
- `yarn` のコンフィグを設定する。

```
$ yarn config python "C:\\python27\\python.exe" -g
$ yarn config msvs_version 2017 -g
```

- `yarn global add windows-build-tools` を `cmd.exe` もしくは `PowerShell.exe` の管理者権限で再実行する。（重要）

# 調査
回避策を見つけるまでの軌跡です。

ハングアップしたところで何が起きているのか見るために `--verbose` や `--debug` を追加してみる。
→ 特に追記された情報もなく再びハングアップする。

[本家](https://github.com/felixrieseberg/windows-build-tools) の issue を覗いて見る。
→ 下記の投稿を発見する。
https://github.com/felixrieseberg/windows-build-tools/issues/154

`npm install --global windows-build-tools` を試してみる。
→ `Python 2.7.10 is already installed, not installing again.` でハングアップする。
→ バグなので `Python` を削除せよという記事を見つける。
https://github.com/felixrieseberg/windows-build-tools/issues/147

再び `npm install --global windows-build-tools` を試してみる。
→ 今度は `Successfully installed Python 2.7` でハングアップする。
→ バグなので `%USERPROFILE%\.windows-build-tools` を削除せよという記事を見つける。
http://m-miya.blog.jp/archives/1071590052.html
https://github.com/felixrieseberg/windows-build-tools/issues/33

再び `npm install --global windows-build-tools` を試してみる。
→ インストールが完了する。

`npm` ではなく `yarn` でインストールしたいので上記、回避手順を実行してみる。
→ 無事、`yarn` でインストールが完了する。

---
再発し、過去の手順では上手く行かなかったので、再度調査をしました。

`windows-build-tools` を使わない手動インストールの方法（有名）を再度試す。
https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#prerequisites

本来インストールしたいツールを `yarn global add xxx` でインストールする。
→ 依存関係解決のため `windows-build-tool` インストールが実行されてしまい、下記の状態でハングアップする。

```
---------- Visual Studio Build Tools ---------- 
Still waiting for installer log file...
------------------- Python  -------------------
Successfully installed Python 2.7
```

うーん…と思いつつ、上記の手動インストールがあるページに、下記と書かれていることを見つける。
> Option 1: Install all the required tools and configurations using Microsoft's windows-build-tools by running npm install -g windows-build-tools from an elevated PowerShell (run as Administrator).

いちかばちか、愛用の `Msys2` ターミナルではなく、`PowerShell` で `yarn global add windows-build-tools` を実行する。
→ 無事、`yarn` でインストールが完了する。

# 所管
ハングアップの詳細が解ってから調査が捗ったのでログは大事だと痛感しました。
`yarn` でログを出す方法を学ばなければと思いました。

以上
SDLアプリコンテスト 八日目

#概要
SDLアプリコンテスト、見つけたので挑戦してみる。
プロトタイピングしてみた。

#写真

![device-2019-01-08-130231.png](https://qiita-image-store.s3.amazonaws.com/0/18104/ced66ddb-62ca-5603-f71a-503663535442.png)

#状況

加速度センサーの値を閾値で切って、採点してみた。
シーン毎の評価じゃないので、破綻してる。
画面の更新が早すぎ。


以上。
ロードバランサー配下のWebサーバーでアクセス元IPアドレスをログ出力

#ロードバランサー配下にあるWebサーバーのログ
ロードバランサーを経由してWebサーバーにアクセスする場合、アクセス元のIPアドレスとしてロードバランサーのIPアドレスがログに記録されます。
これはWebサーバーから見れば、ロードバランサーがクライアントとして見えるためです。

\#ロードバランサーによっては、設定次第でオリジナルのアクセス元IPを維持するものもあります

#アクセス元IPをログに残したい
しかし、アクセス元IPをログに残しておかないと、アクセス解析やトラブルシューティングに支障をきたすことになります。
そこで、今どきのロードバランサーはhttp/httpsアクセスであれば、httpヘッダーにX-Forwarded-Forヘッダーを追加してその値にアクセス元オリジナルのIPアドレスを設定することで、Webサーバーに知らせる方法を採っています。

そうすれば、Webサーバー側はX-Forwarded-Forヘッダーに設定されているIPアドレスをログに書き込むようにすれば良いわけです。

#実際の設定(Apache 2.4の場合)
Apache2.2でも設定は可能なのですが、面倒なのでここでは割愛。

前提条件としてVirtualHostディレクティブかグローバルディレクティブ内に記述する必要があります。
httpd.confに書いておくのが無難でしょう。

```
RemoteIPHeader X-Forwarded-For
````

この一文を書いておくだけで、アクセス元のIPアドレスをWebサーバー(Apache)は知ることとなるので、次にログフォーマットを設定します。

- 変更前

```
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
```

- 変更後

```
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
```

先頭部分の%hを%aとすることで、アクセス元のIPアドレスがログに記録されます。
また、IPアドレスによるアクセス制御にも、アクセス元IPを使用することができるようになります。

AWS ELBは当然ながらX-Forwarded-Forヘッダーに対応しているので、ELBを利用する場合は必ず設定しておきたいものです。
dotfilesの管理をbitbucketからGitHubにした話

#TL;DR
bitbucketで管理していた『非公開の（ここ大事）』dotfilesの管理を、GitHubに移行しました。


#目的
2019年1月8日、GitHubで無料アカウントでもプライベートリポジトリが使えるようになる更新がありました。
公開したくないプロジェクトは、無料アカウントでもプライベートリポジトリが使えるbitbucketで管理していた私にとっては大ニュースです（普段の業務はOrganizationで非公開にしてやってます）。
なので、毎回シンボリックリンクの設定を忘れるdotfilesの管理を、これを期にしっかりやってQiitaしようと思いました。

#手順

##1. bitbucketからGitHubへリポジトリインポート
まず、bitbucketにある対象のリポジトリからURLを取得します。
![スクリーンショット 2019-01-08 12.18.45.png](https://qiita-image-store.s3.amazonaws.com/0/131949/e82bbc21-da8d-483f-79d4-929da9dbd59c.png)
「クローンの作成」をクリック。
![スクリーンショット 2019-01-08 12.29.42.png](https://qiita-image-store.s3.amazonaws.com/0/131949/1712bfa9-8142-afc1-4c47-a821464a104a.png)
右上が「HTTPS」になっていることを確認して、下線部のURLをコピー。

以下のページに移動。
https://import.github.com/

![スクリーンショット 2019-01-08 12.33.50.png](https://qiita-image-store.s3.amazonaws.com/0/131949/2ae04cfd-3462-8b70-7e86-002c40fea8eb.png)
先ほどのURLをペースト。
Nameにはリポジトリの名前「dotfiles」を入力。
「Private」をチェックしてBegin import。

インポートが完了するとメールが届きます。

##2. GitHubからローカル環境へgit clone
GitHubでインポート完了したリポジトリを開く。
![スクリーンショット 2019-01-08 12.40.02.png](https://qiita-image-store.s3.amazonaws.com/0/131949/4c43cf56-5955-50f5-7cca-a5e7a07e66fb.png)
表示されるリポジトリのパスをコピー。
![スクリーンショット 2019-01-08 12.42.09.png](https://qiita-image-store.s3.amazonaws.com/0/131949/b59d7375-3ba6-dede-a51e-7cd474e6ea32.png)
ホームディレクトリで

```shell
$ git clone <コピーしたパス>
```
すると、ローカル環境に自分のリポジトリがクローンされてきます。

##3. シンボリックリンク設定
シンボリックリンクを張るコマンドは以下です。

```shell
$ ln -sf <リンク元のファイルパス> <リンク先のファイルパス>
```
ex)dotfiles内の.vimrcのリンクをホームディレクトリに配置

```shell
$ ln -sf ~/dotfiles/.vimrc ~/.vimrc
```

僕はファイルが多数あったので、shファイルにまとめて、dotfilesに含めてしまいました。

```sh:dot_update.sh
#!/bin/sh
ln -sf ~/dotfiles/_vimrc ~/_vimrc
ln -sf ~/dotfiles/.tmux.conf ~/.tmux.conf
ln -sf ~/dotfiles/.zsh_aliases ~/.zsh_aliases
ln -sf ~/dotfiles/.zshrc ~/.zshrc
ln -sf ~/dotfiles/.zshenv ~/.zshenv
```

コマンドは以下です。
dotfilesに移動して、shファイルを実行します。

```shell
$ cd ~/dotfiles
$ sh dot_update.sh
```

#その他
sshの設定等も必要ですが、それはまた後日。
Word/Excelで年賀状の宛名印刷

毎年苦労する年賀状の宛名印刷のメモを書きます。
今年は、下記のサイトを参考にさせていただきました。本当に助かりました。感謝しています。
https://www.becoolusers.com/use/directory1.html

Wordでの宛名印刷では、いつも連名がうまくできなかったのですが、今回は印刷設定（宛名印刷のテンプレート？）のしくみがわかりよかったです。Office365を使っています。

以下は、上記のサイトに従って行った私のメモです。
来年役に立つかな。^^;)

# Excel で住所録作成

- 郵便番号から住所が引ける。日本語入力で"００１－００４５"と入力してスペースキーを押すと候補に現れる。
- 住所の残りを別の列に書く。郵便番号からの自動変換と残りの部分を別の列に=B2 & B3 のように統合する
- PHONETIC関数を用いて、住所から郵便番号も引ける。
- PHONETIC関数で氏名をふりがなに変換できる。（そういえば正しく変換されているか確認していないな）
- 苗字と名前をそれぞれ別の列に分けて登録する。LEFT(), RIGHHT() 関数で氏名から切り出す。これは印刷のため。

はまった点

- 郵便番号を住所に変換する機能がMicrosoft IMUにある。全角で郵便番号を入力するのだが、変換候補に住所が出てこなかった。郵便番号の辞書も正しくインストールされているのにも関わらず。ふと「スペース」でなく「変換」キーを押したら、住所が候補に現れた。その後は、「スペース」キーでもよくなった。これが分かるのに４０分かかった。

# Wordで年賀状の宛名印刷

メニューバーにある「差し込み文書」--> 「はがき印刷」のアイコンで「宛名面の作成」の流れに従えば基本的なことはできます。追加として

- 連名にも対応する
- 印刷する項目や位置の調整

を行いました。

- 「差し込み文書」で「結果のプレビュー」で各要素（フィールドというらしい）がどの位置に割り当てられるか確認できる
- 「フィールドの対応」では、エクセルファイルのフィールドと宛名印刷で使用する要素の対応付けを確認できます。
- 「差し込みフィールドの挿入」は、wordの宛名印刷の画面で実際に挿入したい項目（連名とか）をその位置に当てはめることができます。ここでは「連名」と「連名敬称」を差し込みました。

はまった点

- 「差し込みフィールドの挿入」で挿入した項目がプレビュー画面で見にくく、２回も挿入されてしまった。プレビュー画面で確認しつつ直した。
- 文字の割り当てが何らかの理由で「均等割り付け」から「上揃え」になっていた。直した。
Jupyterでgraphvizを動かす

XGBoostのplotはGraphvizというライブラリを使っているらしい。
ちょっと触ってみた。

# 環境

以下の環境で実行しました。

- macOS High Sierra 10.13.6（17G4015）
- anaconda3-5.3.0
- Python 3.7.0

# 準備

予め必要なパッケージをインストールしておく

```
$ brew list graphviz
$ pip install graphviz
```

パッケージがインストールされていることを確認する


```python
!brew list | grep graphviz
!dot -V
!pip list | grep graphviz
```

    graphviz
    dot - graphviz version 2.40.1 (20161225.0304)
    graphviz                           0.10.1   


ライブラリが利用できることを確認する


```python
import graphviz
display(graphviz.__version__)
```


    '0.10.1'


# 実行


```python
# ライブラリ読み込み
from graphviz import Digraph
```


```python
# インスタンス作成
dot = Digraph()
```


```python
# ノードの属性を設定
dot.attr('node', shape='circle')
```


```python
# ノードを登録
dot.node('P', 'P')
dot.node('D', 'D')
dot.node('C', 'C')
dot.node('A', 'A')
```


```python
# エッジの属性を登録
dot.attr('edge', arrowsize='2')
```


```python
# エッジを登録
dot.edge('P', 'D')
dot.edge('D', 'C')
dot.edge('C', 'A')
dot.edge('A', 'P')
```


```python
# 生成されたソースコードを確認
print(dot)
```

    digraph {
    	node [shape=circle]
    	P [label=P]
    	D [label=D]
    	C [label=C]
    	A [label=A]
    	edge [arrowsize=2]
    	P -> D
    	D -> C
    	C -> A
    	A -> P
    }



```python
# 出力フォーマットを指定
dot.engine = 'circo'
dot.filename = 'PDCA'
dot.format = 'png'
dot.render(view = True)
```




    'PDCA.png'


![PDCA.png](https://qiita-image-store.s3.amazonaws.com/0/36022/1b7a712d-0ab8-557f-76ca-0805f9cd046c.png)

# 参考資料

- [Graphviz - Graph Visualization Software](https://www.graphviz.org/)
- [User Guide — graphviz 0.10.1 documentation](https://graphviz.readthedocs.io/en/stable/manual.html)
 - [Graphvizとdot言語でグラフを描く方法のまとめ](https://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d)
 - [graphviz メモ](https://qiita.com/miyagaw61/items/c3954bb51aa23a3ad13a)
- [Python Package Introduction — xgboost 0.81 documentation](https://xgboost.readthedocs.io/en/latest/python/python_intro.html#plotting)
 - [Python XGBoost の変数重要度プロット / 可視化の実装 - StatsFragments](http://sinhrks.hatenablog.com/entry/2015/08/27/000235)
【Android】Firebaseに紐づくメールアドレスをスマートに変更する方法

#目的
Firebaseにログインしているユーザのメールアドレスを画面上で再ログインさせることなく変更したい。

#方法
```java:HogeActivity.java
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    AuthCredential credential = EmailAuthProvider.getCredential(currentMailAdress, password);
    user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                user.updateEmail(newMailAdress).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()) {
                            user.sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
                                @Override
                                public void onComplete(@NonNull Task<Void> task) {
                                    if (task.isSuccessful()) {
                                        // 全部成功！！
                                    } else {
                                        // 認証メール送信失敗 task.getException()
                                    }
                                }
                            });
                        } else {
                            // メールアドレス更新失敗 task.getException()
                        }
                    }
                });
            } else {
                // 再認証失敗 task.getException()
            }
        }
    });
}
```

#ポイント
最初にreauthenticateで現在のメールアドレスで再認証をしておくことで、メールアドレス変更時、直近ログインしていないと例外が吐かれる問題を回避できる。

#参考
[Firebase でユーザーを管理する](https://firebase.google.com/docs/auth/android/manage-users?hl=ja)

#あとがき
実装変だったらコメントご指摘いただければと思います。
[Rails5]ransackってなんぞ？

# はじめに

Railsの勉強としてgem周りを触ってみる企画です。
今回は・・・

[ransack](https://github.com/activerecord-hackery/ransack)

を試してみようかと思います。

## どういうgemなの？

簡単にいうと検索機能を実装する時に使えるgemです。
使う機会は結構ありそうなので、覚えるためにも試していきましょう。

## 検証環境

以下の環境で実施しました。

```
[client]
・MacOS Mojave(10.14.2)
・Vagrant 2.2.2
・VBoxManage 6.0.0

[virtual]
・CentOS 7.6
・Rails 5.2.2
・ruby 2.3.1
```

ご参考までに。

# ransack導入

**1.gemのインストール**

事前にRails勉強用に作成したプロジェクトで進めます。
各MVCは適当に掲示板アプリを想定してPostsコントローラーなどを生成済みです。
(index,show,editの空ページが見れる程度)

```余談
$ rails g model post
$ rails g controller posts index show edit
```

その前提のもと、Gemfileに以下を追記。

```ruby:Gemfile
# ransack
gem 'ransack'
```

追記したらインストール。

```
$ bundle install

-----------
Fetching ransack 2.1.1
Installing ransack 2.1.1
-----------
→無事に完了。
```

**2.ransackを使ってみる**

早速ransackを使って実装してみます。
(※DBには事前にダミーデータを適当に複数件突っ込んでます。)

```ruby:posts_controller.rb
def index
  # ransack
  @search = Post.ransack(params[:q])
  @posts = @search.result
end
```

```ruby:index.html.erb
<h1>Posts#index</h1>
<p>Find me in app/views/posts/index.html.erb</p>

<%= search_form_for @search, url: posts_index_path do |f| %>
  <%= f.label :name_cont, '名前' %>
  <%= f.search_field :name_cont %>
  <%= f.submit '検索' %>
<% end %>

<table>
  <thead>
    <tr>
      <th><%= sort_link(@search, :name) -%></th>
      <th><%= sort_link(@search, :content) -%></th>
    </tr>
  </thead>
  <tbody>
    <% @posts.each do |post| %>
    <tr>
      <td><%= post.name -%></td>
      <td><%= post.content -%></td>
    </tr>
    <% end %>
  </tbody>
</table>
```

**3.動作確認**

ではサーバーを立ち上げてページを見てみましょう。

![cap1.png](https://qiita-image-store.s3.amazonaws.com/0/335844/654fbe96-4b24-e1a8-0034-d39c58a0bc99.png)

このように有象無象のデータ群に対して

![cap2.png](https://qiita-image-store.s3.amazonaws.com/0/335844/f9d4a06a-7921-96ab-7905-cc9abd2bd708.png)

"hanako"で検索をかけるとしっかりと絞り込みが出来ました！
「Name」と「Content」のソートもポチっと押すと、
ちゃんとソートされているようです。
完成！

# 所感

何かしらのデータを一覧画面で表示するシステムは、
こういった検索機能は基本的にワンセットなことが多いですね。
手作業でロジックを組むと大変＆工数も無駄にかかってしまうので、
gemを活用していきたいと思います！

# おわりに

何かお気づきの点がありましたら、
ご指摘やアドバイス等頂けると大変助かります！
pandasでNaNと数値のdiffはNaN

2とNaNのdiffはNaN
NaNと4のdiffもNaN

```
>>> df = pd.DataFrame({'a': [1, 2, np.nan, 4, 5]})
>>> df.diff()

     a
0  NaN
1  1.0
2  NaN
3  NaN
4  1.0
```
2018.12バージョンのAnaconda3環境で、Openpyxlが動かない(ImportError: You must install PIL to fetch image objects)

###【発生した問題】
最新版のAnaconda3(Version 2018.12 | Release Date: December 21, 2018)をインストールして、Openpyxlを使用したPythonスクリプトを走らせると、PIL関連エラーが出て動作しない。
pillowをpip installしたりしても、何も変わらない。他の環境では動いているので、スクリプトの問題ではない。

###【解決策】
最新版Anaconda3ではなく、Anaconda3-5.1.0-Windows-x86_64.exeでインストールしたところ、問題解消した。


#####参考：【エラー内容詳細】
```python
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\openpyxl\drawing\image.py", line 27, in _import_image
    import Image as PILImage
ModuleNotFoundError: No module named 'Image'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\openpyxl\drawing\image.py", line 29, in _import_image
    from PIL import Image as PILImage
  File "C:\Anaconda3\lib\site-packages\PIL\Image.py", line 60, in <module>
    from . import _imaging as core
ImportError: DLL load failed: 指定されたモジュールが見つかりません。

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "hosyoentyomitsumori.py", line 146, in <module>
    mitsumoribook = openpyxl.load_workbook('新品販売時保守契約見積テンプレート.xlsx', data_only=False)
  File "C:\Anaconda3\lib\site-packages\openpyxl\reader\excel.py", line 338, in load_workbook
    reader.read()
  File "C:\Anaconda3\lib\site-packages\openpyxl\reader\excel.py", line 301, in read
    self.read_worksheets()
  File "C:\Anaconda3\lib\site-packages\openpyxl\reader\excel.py", line 276, in read_worksheets
    charts, images = find_images(self.archive, rel.target)
  File "C:\Anaconda3\lib\site-packages\openpyxl\reader\drawings.py", line 47, in find_images
    image = Image(BytesIO(archive.read(dep.target)))
  File "C:\Anaconda3\lib\site-packages\openpyxl\drawing\image.py", line 51, in __init__
    image = _import_image(img)
  File "C:\Anaconda3\lib\site-packages\openpyxl\drawing\image.py", line 31, in _import_image
    raise ImportError('You must install PIL to fetch image objects')
ImportError: You must install PIL to fetch image objects
```
linux shell でカレンダー表記

# cal

知らなかった

![image](https://user-images.githubusercontent.com/13635059/50807905-84990900-133f-11e9-9467-9b9df10da94b.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ROC 曲線とは (自分用メモ)

* 例えば、真の値 [1, 1, 0, 0] があるとする。(0: 陰, 1: 陽)
* ある予測器にかけたスコアが [0.9, 0.4, 0.6, 0.1] だとする。値が大きいほど 1 の可能性が高い。
* この場合 0.6 と 0.4 の部分の予測は自信が無く、実際間違っている。

これを sklearn でプロットしてみる。ここで

* FPR: 偽陽性率。0 に近いほど間違って偽と判定してしまった割合が減って良い。分母は実際に偽だった数。
* TPR: 真陽性率。1 に近いほど正しく真と判定した割合が増えて良い。分母は実際に真だった物。

```python
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.metrics import roc_curve

y = np.array([1, 1, 0, 0])
scores = np.array([0.9, 0.4, 0.6, 0.1])
fpr, tpr, thresholds = roc_curve(y, scores)
print(f'FPR: {fpr}, TPR: {tpr}, thresholds: {thresholds}')
print(f'AUC: {auc(fpr, tpr)}')
display(pd.DataFrame({'fpr': fpr, 'tpr': tpr, 'thresholds': thresholds}))
plt.plot(fpr, tpr)
```

FPR: [0.  0.  0.5 0.5 1. ], TPR: [0.  0.5 0.5 1.  1. ], thresholds: [1.9 0.9 0.6 0.4 0.1]
AUC: 0.75

<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>fpr</th>
      <th>tpr</th>
      <th>thresholds</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>1.9</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0.0</td>
      <td>0.5</td>
      <td>0.9</td>
    </tr>
    <tr>
      <th>2</th>
      <td>0.5</td>
      <td>0.5</td>
      <td>0.6</td>
    </tr>
    <tr>
      <th>3</th>
      <td>0.5</td>
      <td>1.0</td>
      <td>0.4</td>
    </tr>
    <tr>
      <th>4</th>
      <td>1.0</td>
      <td>1.0</td>
      <td>0.1</td>
    </tr>
  </tbody>
</table>
</div>

![output_26_3.png](https://qiita-image-store.s3.amazonaws.com/0/35350/9d5266b9-7867-c4a3-8044-c04df8795541.png)

* 閾値が 1.9 だと全部 0 になってしまうので FPR も TPR も 0。
* 閾値を 0.9 にするとスコア 0.9 のやつだけが 1 と判定される。FPR は 0 のままだが TPR は 0.5 に上がる。
* 閾値を 0.6 にするとスコア 0.6 以上が 1 と判定される。3つ目の値が 1 と誤判定されるので FPR は 0.5 に上がる。TPR は 5 のまま。
* 閾値を 0.4 にすると。。。

というふうに FPR を低く保ったまま TPR を上げるのが難しいのが良くわかるグラフが出来上がる。より良い予測器はグラフの左下部分の面積が広い。その面積を AUC と呼び、予測器の評価に使う。

参考:

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html

個人的意見では FPR の定義が TPR と対称的で無いのが気に食わない。例えば TNR = 1 - FPR = TN / TN + FP として、TNR と TPR でグラフを描いた方が「TNR と TPR の両方同時に 1 に近いほうが良い」となって分かりやすいと思うのだが、決まっている物は仕方がない。
事前学習

プログラミング学習を始める前に、より学習の質を上げるための心構えやマインドセット、あとは学習に必要なソフトのダウンロードなどが事前学習にありました。やっぱり一人でPCに向かって黙々と作業ってなかなかきついかと思います:grinning: マインドセットの仕方で作業効率も変わってくるのでそこら辺意識しながらこれから取り組んでいこうかと思います！
Vuejsで子コンポーネントの表示内容をクリップボードにコピー

Javascriptはあまり詳しくないAndroidエンジニアが、Nuxt.jsとVuetifyでWebページを作成している。

## やりたいこと
HTMLで表示した内容をクリップボードにコピーしたい
（`data`や`props`で渡した値ではない）

## できたコード

これでいけた
div内の全pタグのテキストがクリップボードにコピーできた。

```vuejs
<template>
  <v-layout>
    <v-btn
      icon
      fab
      color="orange"
      @click="witeToClipboard()"
    >
      <v-icon>file_copy</v-icon>
    </v-btn>

    <div id="target">
      <p>コピーしたい文章1</p>
      <p>コピーしたい文章2</p>
      <p>コピーしたい文章3</p>
    </div>
  </v-layout>
</template>

<script>
export default {
  methods: {
    witeToClipboard() {
      const copyText = this.$el.querySelector('#target').textContent
      navigator.clipboard
        .writeText(copyText)
        .then(() => {
          console.log('テキストコピー完了')
        })
        .catch(e => {
          console.error(e)
        })
    }
  }
}
</script>
```

## 参考ページ
- An Example of the Async Clipboard API with Vue.js https://www.raymondcamden.com/2018/04/19/an-example-of-the-async-clipboard-api-with-vuejs
- https://jp.vuejs.org/v2/api/index.html#vm-el
GitHubによる主要認識言語を切り替える

ありがたいことに、[GitHubの無料ユーザーでも、プライベートリポジトリを無制限に使えるように](http://www.itmedia.co.jp/news/articles/1901/08/news051.html)なった。

ということで[GitのImport機能](https://github.com/new/import)を使って、Bitbucketから順次お引越し。
その中で幾つかGit側でリポジトリの主要言語が誤って認識されたので、訂正方法をメモ。
※
と言っても、GitHubが言語認識に用いているライブラリ（[github/linguist](https://github.com/github/linguist)）のTroubleshooting、Overridesを参照しただけだけれども。

## 前提

 - リポジトリ内部の統計バーをクリックすると、GitHub側が認識している言語統計を見ることができる（知らなかった）
 - 言語認識がうまくいかない場合は幾つか要因が考えられる
   - Linguistがその言語自体を扱っていない
   - 依存するファイル・ライブラリが直接置かれている
   - 拡張子が[languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml)と紐づいていない
   - 本来除外されるはずのドキュメントが統計対象となっている

![test.png](https://qiita-image-store.s3.amazonaws.com/0/152044/094452a5-94c0-890c-3895-c3b3beb6cae6.png)

依存するHTMLファイルが大量に存在するので、JavaScriptではなくHTMLが主要言語だと判定されてしまっている。

## 解決策
Vim/Emacs modelineファイルを使う方法もあるようだが、`.gitattributes`ファイルの作成のほうで解決する。（主要なのはどちらだろう）
そして下記を参考に記述。`.gitignore`みたいなものか。

```
*.ext linguist-language=Java  # ".ext"の拡張子をJavaとして検出

folder/* linguist-vendored  # vendored codeとして認識
file.js linguist-vendored=false  # vendored codeから除外

folder/* linguist-documentation  # documentationとして認識
file.rb linguist-documentation=false  # documentationから除外
```
documentation扱いとすることで言語統計からは除外される。
またvendored code扱いとすることで統計から除外され、さらにGitHubのdiffからも対象外となる。

![スクリーンショット 2019-01-08 11.53.21.png](https://qiita-image-store.s3.amazonaws.com/0/152044/39813d38-b553-0464-da7c-ef41993cfe5d.png)

ということで無事JavaScript:100%となった。
Ansible playbook の check mode = no 指定は「チェックモードが存在する？ No」と理解したい

- I wanna understand Ansible playbook check mode = no means "(This task) has check mode? " "No"
- Ansible playbook の check mode = no 指定は「チェックモードが存在する？ No」と理解したい


# I wanna make it rememberable

名前が直感と逆な気がして。覚えないと確実に忘れそう。

# Understanding

- Enable `check_mode` ? Yes / No ( if its no then task has no check mode so task always run )
- チェックモードは存在しますか ? Yes / No ( もし No であればチェックモード自体が存在しない扱いで、タスクは常に実行される )

# ref


[Ansibleのcheck_modeオプションでcheckモードを制御する ｜ DevelopersIO](https://dev.classmethod.jp/server-side/ansible/using_check_mode/)


 ---

https://twitter.com/YumaInaura

https://github.com/YumaInaura/YumaInaura/issues









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Terraform init実行時にプラグインエラーが発生した場合の対処方法

## 構成について

* OS: Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0a2de1c3b415889d2
* Terraform: v0.11.11

## Terraform init実行時にエラー

terraform initの実行時に以下のエラーが発生する場合は、プロバイダ用のプラグインがダウンロードできない場合に発生します。

```bash
$ terraform init -upgrade

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...

Error installing provider "aws": Get https://releases.hashicorp.com/terraform-provider-aws/: proxyconnect tcp: tls: oversized record received with length 20527.

Terraform analyses the configuration and state and automatically downloads
plugins for the providers used. However, when attempting to download this
plugin an unexpected error occured.

This may be caused if for some reason Terraform is unable to reach the
plugin repository. The repository may be unreachable if access is blocked
by a firewall.

If automatic installation is not possible or desirable in your environment,
you may alternatively manually install plugins by downloading a suitable
distribution package and placing the plugin's executable file in the
following directory:
    terraform.d/plugins/linux_amd64
```

手動でプラグインを配置することで回避することができます。
そのため、terraformを実行するディレクトリ配下に以下のディレクトリを作成し、ファイルを配置します。

```bash
$ mkdir -p terraform.d/plugins/linux_amd64
$ cd terraform.d/plugins/linux_amd64/
$ wget https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip
$ unzip terraform_0.11.11_linux_amd64.zip
```

Terraform initを再度実行し、問題ないことを確認します。

```bash
$ terraform init -upgrade
```

このケースは限定的な環境でしか起こらないと思いますが、もし誰かのお役に立てれば光栄です。
オライリージャパン　「ゼロからはじめるデータサイエンス Pythonで学ぶ基本と実践」を買った(個人的感想)

```
◎データサイエンスの基本知識とPythonプログラミング

全25章＋付録A　でじっくり基礎から学ぶことができます。

リスト・タプル・辞書といった初歩のPythonのやり方から、webスクレイピング・JSONの扱い方・APIの活用(事例としてTwitterAPIが取り上げられている)、また、重回帰分析やロジスティック回帰などの説明がしっかり解説されており、初心者でもなるほど！と思うことができる一冊です。

後ろのほうに既存ライブラリーの解説(Numpy, pandas, scikit-learn)がすこしだけあります。

```
AWS EC2 AutoRecoveryをPowerShellで設定する

#はじめに
PowerShellでDimensionの渡し方がわからなかったのでメモ。

#コード
##New-ObjectでDimension
Write-CWMetricAlarmのヘルプでは
-Dimension Amazon.CloudWatch.Model.Dimension[]
となっているのでそのとおりに作って渡す方式。

+ $Dimension.Valueを目的のインスタンスIDに変更すれば事足りますが、
EvaluationPeriodとThresholdは要件に応じて変更しましょう。

+ 設定対象とするリージョンを変更する場合はAlarmActionにリージョン名が入っているので此処も変更します。

```powershell
$Region = "ap-northeast-1"
$Dimension = New-Object 'Amazon.CloudWatch.Model.Dimension'
$Dimension.Name = 'InstanceId'
$Dimension.Value = 'i-xxxxxxxxxxxxxxxxx'

Write-CWMetricAlarm `
 -AlarmName 'AutoRecovery' `
 -AlarmAction "arn:aws:automate:${Region}:ec2:recover" `
 -AlarmDescription 'AutoRecovery Alarm' `
 -MetricName 'StatusCheckFailed_System' `
 -Namespace 'AWS/EC2' `
 -Statistic Maximum `
 -Dimension $Dimension `
 -Period 60 `
 -EvaluationPeriod 2 `
 -Threshold 1 `
 -ComparisonOperator GreaterThanOrEqualToThreshold `
 -Region $Region
```

##SplattingでDimension

PowerShellならではの書き方。

```powershell
$InstanceId = "i-xxxxxxxxxxxxxxxxx"
$Region = "ap-northeast-1"
$Param = @{
  AlarmName          = "AutoRecovery";
  AlarmAction        = "arn:aws:automate:${Region}:ec2:recover";
  AlarmDescription   = "AutoRecovery Alarm";
  MetricName         = "StatusCheckFailed_System";
  Namespace          = "AWS/EC2";
  Statistic          = "Maximum";
  Dimension          = @(
    @{
      Name  = "InstanceId";
      Value = $InstanceId;
    }
  );
  Period             = 60;
  EvaluationPeriod   = 2;
  Threshold          = 1;
  ComparisonOperator = "GreaterThanOrEqualToThreshold";
  Region             = $Region;
}
Write-CWMetricAlarm @Param
```
HandleFuncの構造（間違いの可能性あり）

まず、関数から関数の呼び出し

```golang
package main
import "fmt"

func test(f func(int, int) int, a int, b int) int{
    return f(a, b)   
}

func add(a, b int) int{
    return a+b
}

func sub(a, b int) int{
    if a > b { 
        return a - b
    }
    return b - a 
}

func main(){
    ans1 := test(add, 1, 2)
    fmt.Println(ans1) // 3
    ans2 := test(sub, 1, 2)
    fmt.Println(ans2) // 1
    ans3 := test(sub, 2, 1)
    fmt.Println(ans3) // 1
}
```

少し形を変えて

```golang
package main
import "fmt"

func MyHandleFunc(a int, f func(int, int) ) {
    f(a, 2)   
}

func hogehandler(a, b int) {
    fmt.Println(a + b)
}

func main(){
    MyHandleFunc(1, hogehandler) // 3
}
```

これと同じ構造が HandleFunc なのかな？
hogehandler の引数がなくても動作することが疑問だった。

```golang

// リクエストを処理する関数
func hogehandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello World from Go.")
}

func main() {
    http.HandleFunc("/hoge", hogehandler)

    http.ListenAndServe(":8080", nil)
}

```

また、handlerにパラメータを渡したい場合
以下のような実装を行うことで対応可能になる

```golang
package main

import (
  "fmt"
  "net/http"
  "log"
)

func hogeHandler(w http.ResponseWriter, r *http.Request, s string) {
    fmt.Fprint(w, "Hello World from Go. "+s)
}

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc{
    return func(w http.ResponseWriter, r *http.Request){
        fn(w, r, "パラメータ")
    }
}

func main() {
  http.HandleFunc("/hoge", makeHandler(hogeHandler))

  log.Fatal(http.ListenAndServe(":8080", nil))
}
```
AlertDialogのボタンタップでダイアログを閉じない方法

ダイアログのボタンをタップしたときに、ダイアログを閉じたくない場合があります。
しかし`AlertDialog.Builder#setPositiveButton`などを使用すると、ボタンタップ時に問答無用でダイアログが閉じてしまいます。
これを回避して閉じる/閉じないを制御するには次のような実装をすればよいです。
`onResume`でボタンを取得して`setOnClickListener`で振る舞いをオーバーライドしています。

```kotlin
class DummyDialogFragment() : DialogFragment() {
    companion object {
        fun newInstance(): DummyDialogFragment {
            val instance = DummyDialogFragment()
            val args = Bundle()
            instance.arguments = args
            return instance
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val layoutInflater = LayoutInflater.from(requireContext())
        val view = layoutInflater.inflate(R.layout.dialog_layout, null)
        return AlertDialog.Builder(requireContext())
                .setView(view)
                .setPositiveButton(getString(R.string.dialog_button_title_ok), null) // タップ時の振る舞いは`onResume`で設定される
                .create()
    }

    override fun onResume() {
        super.onResume()
        val alertDialog = dialog as AlertDialog
        val positiveButton = alertDialog.getButton(Dialog.BUTTON_POSITIVE)
        // positiveButtonの振る舞いをこのタイミングで実装する
        positiveButton.setOnClickListener {
            val name = (editText?.text?.toString() ?: "").trim()
            if (true) {
                // ダイアログを閉じる
                dismiss()
            } else {
                // ダイアログを閉じずに、エラーを表示するなど
            }
        }
    }
}
```

参考
https://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
新しいmacbookにインストるするアプリ一覧

## アプリ、開発ツール
 - [chrome](https://www.google.com/intl/ja_jp/chrome/)
 - [firefox](https://www.mozilla.org/ja/firefox/new/)
 - [CotEditor](https://coteditor.com/archives.ja)
 - kakao
 - line
 - [PyCham CE](https://www.jetbrains.com/ja-jp/pycharm/download/#section=mac)
 - [pyenv](https://qiita.com/niwak2/items/5490607be32202ce1314)[intel]
 - [pyenv](https://analytics-note.xyz/mac/python-apple-silicon/)[m1,m2]
 - [slack](https://slack.com/intl/ja-jp/help/articles/207677868)
 - docker 
 - [https://www.sourcetreeapp.com/](https://www.sourcetreeapp.com/)
- [iTerm](https://iterm2.com/)
 

## Macの設定
 - [MacBook Pro - トラックパッドで「3本指ドラッグ」を有効に](https://pc-karuma.net/mac-three-finger-drag-enable/)
 - [MacBook Pro - command + space 언어설정](https://bl6.jp/dev/computer/os-x-el-capitan-command-space-from-control-space/)
 - ターミナル追加
 - [모든폴더보기](https://itchipmunk.tistory.com/179)
 - Xcode update (xcode-select --install)
 - [ssh key](https://qiita.com/HamaTech/items/21bb9761f326c4d4aa65)
 - [brew](https://brew.sh/index_ja)
 - https://qiita.com/miriwo/items/67681165b0a89218ee61
 - [pyenv virtualenv](https://qiita.com/niwak2/items/5490607be32202ce1314)
 - [mysql5.6](https://weblabo.oscasierra.net/mysql-56-homebrew-install/) 最後の設定を行うこと！
 - [Macでミドルボタン](https://www.karelie.net/mac-mission-control/)
 - [git & npm install](https://chaika.hatenablog.com/entry/2022/10/03/083000)


## gitショットカット 
```
cat ~/.bash_profile
alias gp='git pull'
alias gc='git commit -a'
alias gs='git status'
alias gb='git branch'
```
[Rails5]kaminariってなんぞ？

# はじめに

Railsの勉強としてgem周りを触ってみる企画です。
今回は・・・

[kaminari](https://github.com/kaminari/kaminari)

を試してみようかと思います。

## どういうgemなの？

簡単にいうとページネーション機能を簡単に追加できるgemとのこと。
有名どころなのでしっかり使い方を覚えていきます。

## 検証環境

以下の環境で実施しました。

```
[client]
・MacOS Mojave(10.14.2)
・Vagrant 2.2.2
・VBoxManage 6.0.0

[virtual]
・CentOS 7.6
・Rails 5.2.2
・ruby 2.3.1
```

ご参考までに。

# kaminari導入

**1.gemのインストール**

事前にRails勉強用に作成したプロジェクトで進めます。
各MVCは適当に掲示板アプリを想定してPostsコントローラーなどを生成済みです。
(index,show,editの空ページが見れる程度)

```余談
$ rails g model post
$ rails g controller posts index show edit
```

その前提のもと、Gemfileに以下を追記。

```ruby:Gemfile
# kaminari
gem 'kaminari'
```

追記したらインストール。

```
$ bundle install

-----------
Fetching kaminari-core 1.1.1
Installing kaminari-core 1.1.1
Fetching kaminari-actionview 1.1.1
Installing kaminari-actionview 1.1.1
Fetching kaminari-activerecord 1.1.1
Installing kaminari-activerecord 1.1.1
Fetching kaminari 1.1.1
Installing kaminari 1.1.1
-----------
→無事に完了。
```

**2.kaminariを使ってみる**

これでkaminariが使えるようになったようなので、
早速コントローラーやビューを調整してみます。
(※DBには事前にダミーデータを適当に複数件突っ込んでます。)

```ruby:posts_controller.rb
def index
  # とりあえず基本形で表示してみる
  @posts = Post.page(params[:page])
end
```

```ruby:index.html.erb
<h1>Posts#index</h1>
<p>Find me in app/views/posts/index.html.erb</p>

<table>
  <thead>
    <tr>
      <th>name</th>
      <th>content</th>
    </tr>
  </thead>
  <tbody>
    <% @posts.each do |post| %>
    <tr>
      <td><%= post.name -%></td>
      <td><%= post.content -%></td>
    </tr>
    <% end %>
  </tbody>
</table>

<%= paginate @posts -%>
```

**3.動作確認**

ではサーバーを立ち上げてページを見てみましょう。

![cap1.png](https://qiita-image-store.s3.amazonaws.com/0/335844/b7567bbc-6351-7b62-eccb-aa973d682a37.png)

表示されました！めっちゃお手軽。
ダミーデータは３０件突っ込んでおいたのですが、
上記処理だとデフォルトは１ページあたり２５件になるようです。

**4.もう少し掘り下げてみる**

これで所感に入るのも味気ないのでもう少し触ってみます。

早速１ページあたりの表示件数を１０件に変更してみます。

```ruby:posts_controller.rb
def index
  # １ページの表示を１０件に絞る
  @posts = Post.page(params[:page])
end
```

あるいは

```ruby:post.rb
class Post < ApplicationRecord
  # この方法でも１ページあたりの表示件数の調整が可能
  paginates_per 10
end
```

そうすると、このように表示件数が制限出来ました。

![cap2.png](https://qiita-image-store.s3.amazonaws.com/0/335844/76b56e45-93a5-ee14-bc79-07f07ecba71b.png)

また、そもそもとしてkaminari自体の設定を調整して、
表示件数のデフォルト値を変更することも可能。

```
$ rails g kaminari:config
    create  config/initializers/kaminari_config.rb
```

上記コマンドにて設定ファイルが生成されました。

```ruby:kaminari_config.rb
# frozen_string_literal: true
Kaminari.configure do |config|
  # config.default_per_page = 25
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
  # config.params_on_first_page = false
end
```

ケースバイケースで使い分けすると良さそうですね。

また今回は手を出しませんが、

```
$ rails g kaminari:views default
```

のコマンドにて、kaminariのテンプレートが生成され、
見た目を調整するのに使えるようです。
さらに

```
$ rails g kaminari:views bootstrap
```

とした場合は、Bootstrapで適用が可能。
さらにさらに、i18nにも別途対応することも可能とのこと。
奥が深い。

# 所感

手軽にページングが追加出来るのは良いですね。
一覧画面を表示するシステムを作る機会もなかなか多いので、
是非活用していきましょう。

# おわりに

何かお気づきの点がありましたら、
ご指摘やアドバイス等頂けると大変助かります！
node.jsで画像入りExcelファイルを出力

## はじめに

このドキュメントは、node.jsから画像入りExcelファイルの出力をする方法を共有するためのものです。

こちらの記事に触発され、自分でもxlsxファイルの出力を試してみました。

[node.jsでxlsxファイルを読み込む:xlsxモジュールの使用](https://qiita.com/indometacin/items/020513f7801a040dab33)

### 対象とするユーザー

* node.js, npm, javascriptの基礎的な知識がある。
* node.jsからExcelファイルを出力してみたい。

### 前提とする環境

このドキュメントは以下の環境を前提としています。

- macOS 10.14.1
- node.js 8.11.4

*▼package.json*

```json
"dependencies": {
  "excel4node": "^1.7.0"
}
```

環境のバージョンが異なる場合、このドキュメントの内容をそのまま利用できない場合があります。

## 成果物

CLIで動作するnodeモジュールを作ってみました。

[images-to-xlsx](https://github.com/MasatoMakino/images-to-xlsx)

```bash
npm install https://github.com/MasatoMakino/images-to-xlsx.git
```
でインストールして

```bash
npx images-to-xlsx -i ./images
```
実行すると`./images`フォルダー以下の画像をリストアップした`images.xlsx`を出力します。

```bash
npx https://github.com/MasatoMakino/images-to-xlsx.git -i ./images
```
でインストールせずに一度だけ実行することもできます。

![リスト画像](https://www.evernote.com/l/AAlYD79BVuRLV7wPXBBY4XVUPWFw1w3EPpcB/image.png)

出力結果はこのようになります。

## excel4node

このモジュールでは、画像入りxlsxファイルの出力のために[excel4node](https://github.com/natergj/excel4node)を利用しています。

このライブラリは、xlsxのファイル生成に特化したライブラリです。xlsxの読み込み機能はありません。xlsxを読み込み、処理を行なった後に出力するなら[node-libxl](https://github.com/DirtyHairy/node-libxl)などをオススメします。

### 使い方

excel4nodeのREADMEから基本的な操作方法を以下に抜粋します。

```js
var xl = require('excel4node');

// ワークブックを作成
var wb = new xl.Workbook();

// ワークシートを作成
var ws = wb.addWorksheet('Sheet 1');

// セルに記入
ws.cell(2, 1)
  .string('string');

// ワークブックを保存
wb.write('Excel.xlsx');
```

セルに対して画像を追加する場合は以下のようになります。

```js
ws.addImage({
  path: './screenshot1.jpg',
  type: 'picture',
  position: {
    type: 'oneCellAnchor',
    from: {
      col: 1,
      colOff: '0.5in',
      row: 1,
      rowOff: 0,
    },
  },
});
```

画像のパスとセル番号、左上からのオフセット量を指定すると画像が挿入されます。

## 利点

Excelをマクロで操作するのと比較して、node.jsからxlsxファイルを操作するのには以下のような利点があります。

### Excel不要

実行環境にExcelがインストールされている必要はありません。実行環境を選ばず、またライセンス料も不要です。

### nodeモジュールの資産が利用できる

ファイルを収集する[glob](https://github.com/isaacs/node-glob)や画像ファイルのリサイズを行う[sharp](https://github.com/lovell/sharp)など、多くのnode.jsのライブラリ資産を利用できます。
普段からnode.jsに親しまれている方なら、高度な機能もライブラリの助けを借りて短期間で実装できます。

## 詰まったところ

### ライブラリの選択が難しい

npmで[xlsxを検索すると](https://www.npmjs.com/search?q=keywords:xlsx)大量のライブラリが見つかります。この中から、目的に合い、かつメンテナンスやドキュメントが充実しているライブラリを選定するのは骨の折れる作業です。

### セル指定は0からではなく1

セル番号の指定方法は、Excelに合わせて1からになります。0は指定できません。
配列を処理している時に、ついうっかり配列インデックスをセル番号にそのまま代入してしまい、しばらく詰まりました。

```console
(node:77237) UnhandledPromiseRejectionWarning: Error: TypeError: Cannot read property 'toUpperCase' of undefined
```

セル番号にゼロを指定すると上記のエラーが出て処理が停止します。
解決方法はexcel4nodeの[issue](https://github.com/natergj/excel4node/issues/139)に記載されていました。

### 非同期処理がすべて終了してからファイル出力

今回はセルに画像を挿入していますが、node.jsでの画像操作は非同期処理が多用されます。
非同期処理をPromiseやawait/asyncで処理しないとワークブックの保存処理が先に実行されてしまいます。結果、画像の挿入されていない空のxlsxファイルが出力されます。

以上、ありがとうございました。
Macの環境設定

# はじめに
仕事場がちょくちょく変わるのでメモ代わりに

# インストール
- [Chrome](https://www.google.com/intl/ja_ALL/chrome/)
- [Magnet](https://itunes.apple.com/jp/app/magnet-%E3%83%9E%E3%82%B0%E3%83%8D%E3%83%83%E3%83%88/id441258766?mt=12)
- [Alfred](https://itunes.apple.com/jp/app/alfred/id405843582?mt=12)
- [SublimeText](https://www.sublimetext.com/3)
- [Skitch](https://evernote.com/intl/jp/products/skitch)
- [SequelPro](https://sequelpro.com/download)

# ターミナルのテーマを変える
デフォルトのテーマが見辛くて...
テーマは[Iceberg](http://cocopon.github.io/iceberg.vim/)を使ってます。おすすめ(*´ω｀*)

# システム環境設定
#### 一般
- デフォルトのブラウザをChromeに設定
- 「クリックされた場所にジャンプ」にチェック
- 「書類を閉じるときに変更内容を保持するかどうかを確認」にチェック

#### デスクトップとスクリーンセーバ
- Arabesque
- 開始までの時間を「10分」
- 「時計と一緒に表示」にチェック
- ホットコーナーの右上を「スクリーンセーバを開始する」

#### Dock
- サイズと拡大はお好みで
- 「ウィンドウタイトルバーのダブルクリックで拡大縮小」にチェック

#### セキュリティとプライバシー
- 「スリープとスクリーンセーバの解除にパスワードを要求」にチェック
- 開始後：「すぐに」を選択
- 「AppStoreと確認済みの開発元からのアプリケーションを許可」を選択

#### ディスプレイ
- Night Shiftのスケジュールを「カスタム」を選択
- 「0:00 〜 23:59」
- 「今日の終了設定ま時刻までオンにする」にチェック
- 色温度「暖かく」に全振り

#### 省エネルギー
- ディスプレイをオフにするまでの時間「10分」に設定
- 可能な場合はハードディスクをスリープさせるにチェック

#### マウス
- 「ページ間をスワイプ」にチェック
- 「副ボタンのクリック」にチェック
- 軌道の速さはお好みで

#### サウンド
- 「メニューバーに音量を表示」にチェック
- サウンドエフェクトの再生装置から「内蔵スピーカー」を選択
- 主音量で「消音」にチェック

#### 日付と時刻
- 時刻のオプションで「秒を表示」「24時間表示にする」にチェック
- 日付のオプション全盛り
Googleでアメリカ市場調査をやる方法

Googleでふつうに検索すると、英語で検索したとしても、日本にカスタマイズされた情報しか出てきません。アメリカにカスタマイズして検索する方法です。

## 設定を英語にする

ブラウザの設定を英語にします。

## Regionを変える

以下からRegionを対象地域にします。
https://www.google.com/preferences?hl=en

## google.comを使う

以下から検索します。
https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0

## ブラウザが報告する場所情報をカリフォルニアにする

以下のChromeプラグインでFixed Locationでカリフォルニアに設定します。
https://chrome.google.com/webstore/detail/location-guard/cfohepagpmnodfdmjliccbbigdkfcgia?hl=en
奇妙な式を型で読み解く

色々な言語で[配列の最後の要素を取り出す](https://qiita.com/Nabetani/items/05bc8b1b27eb75fd0c89)という記事のコメントで、 C では [`*((&x)[1]-1)` という式で可能だという提案](https://qiita.com/Nabetani/items/05bc8b1b27eb75fd0c89#comment-490f95ca05ba7cec0f06)をしました。

この式は技巧的なので日常的に使う定型句としては適さないと思うのですが、初心者がしばしば引っかかりがちな考え方を含むので逆に題材としては面白いのではないかと考え、型を中心に解説を<ruby><rb>試</rb><rp>(</rp><rt>こころ</rt><rp>)</rp></ruby>みます。

変数 `x` が要素数 `N` で型 `T` の配列であるとき、つまり `x` が

```c
T x[N];
```

と宣言されているとき、 `*((&x)[1]-1)` という式の各段階の型はこうなります。

|式|型|備考|
|:--|:--|:-:|
|`x`|`T[N]`|-|
|`&x`|`T(*)[N]`|配列を指すポインタ|
|`(&x)[1]`|`T[N]`|ただし、暗黙の型変換で `T*` に読み替えられる|
|`(&x)[1]-1`|`T*`|-|
|`*((&x)[1]-1)`|`T`|-|

最終的に返ってくる値の型は、配列の要素の型となります。

このとき、重要な点として

- 配列は (いくつかの例外を除いて) <ruby><rb>暗黙</rb><rp>(</rp><rt>あんもく</rt><rp>)</rp></ruby>の型変換で配列の__先頭要素を指す__ポインタになる
- 配列の先頭要素を指すポインタとは別に配列を指すポインタが存在する
- 配列にアドレス演算子 (`&`) を適用したときは暗黙の型変換の例外となり、__配列の先頭要素ではなく配列を指す__ポインタとなる

を<ruby><rb>意識</rb><rp>(</rp><rt>いしき</rt><rp>)</rp></ruby>してください。

ポインタに対して `[1]` と付けたときには、指している先の次の要素を取り出すことはわかると思いますが、指している先が配列であれば__次の配列__を指し、更にその配列の__先頭要素を指すポインタ__に暗黙に型変換されるため、結果的に `(&x)[1]` は配列 `x` の最後の要素の次を指すポインタです。 そこから 1 を減算することで配列の最後を指すポインタになるわけです。

<ruby><rb>一見</rb><rp>(</rp><rt>いっけん</rt><rp>)</rp></ruby>してわかり難い式も規則に基づいて型を意識することで意味を理解しやすくなります。
gcloudでユーザー名を指定してログインしたい - $USERを使わせない方法

## やりたいこと
`gcloud compute ... ssh ...`するときにユーザー名を指定してインスタンスにログインしたいです。
デフォルトの挙動はホストマシンの`$USER`でユーザーを見てログインするぽく困っていました。


## 解決策

明示的にユーザー名を指定する方法は、`ユーザ名@インスタンス名`というふうにすればOKでした。

以下はコマンド例です。
<code>gcloud compute --project "myproject-xxx" ssh --zone "us-east1-b" **"myusername@**instance-1"</code>
（太字の箇所を「gcloudコマンドを表示」で出てきたコマンドに追加するだけでした）

## 参考

* [gcloud compute ssh  |  Cloud SDK  |  Google Cloud](https://cloud.google.com/sdk/gcloud/reference/compute/ssh)
今日からプログラミング学習

今までは無料オンラインサイトでの独学という形でプログラミング学習をしていましたが今日からは本格的に学習が始まります:smiley: 学んだ内容をアウトプットするとより理解が深まるということを聞いたことがあるので、ここにそれらを記していこうと思います:sunglasses: 不安もありますがコツコツ頑張っていこうと思います:runner_tone3:
php-master-changes 2019-01-07

今日は opcache 最適化バグの修正、ドキュメントの更新、タイムゾーン DB の更新、mysqlnd のコードへの const 指定追加があった！

# 2019-01-07
## nikic: Fix one issue reported in bug [#77310](https://bugs.php.net/bug.php?id=77310)
- https://github.com/php/php-src/commit/6f75890e7b8fee3584ec0fa7bd2017e8e75aea91
- [7.3~]
- ext/opcache で、最適化のバグにより配列への複合代入演算が正常に行われないケースがある問題の修正

## remicollet: [ci skip] fix NEWS
- https://github.com/php/php-src/commit/3e780d7f254570d08dc3cea543c8f695ad38dbe8
- [7.2~]
- NEWS の更新

## derickr: Updated to version 2018.9 (2018i)
- https://github.com/php/php-src/commit/1eedfe70aeb9c8b89af642ac00e0d2e0fe5b10e6
- [7.2~]
- ext/date で、タイムゾーン DB のバージョンを 2018.9 に更新


## cmb69: Fix NEWS
- https://github.com/php/php-src/commit/deb88f22697ec6051aca24e24cfac187e37a7732
- [7.3~]
- NEWS で、7.1 系へバックポートされた修正を反映し、リリース日を 1/10 へずらした


## derickr: Update tests due to data changes in tzdata 2018i
- https://github.com/php/php-src/commit/bd1d2c7bfefe4b173c9a7628ecc4dead72775a14
- [7.2~]
- ext/date で、タイムゾーン DB の更新に伴うテスト修正

## Andrey Hristov: Mark const what should not be changed
- https://github.com/php/php-src/commit/711e1fb33b06c9da7baed028ea912c189f33f442
- ext/mysqlnd で、const 指定を足した
pip installの際に依存ライブラリを入れたくない

## 困っていた状況

あるライブラリ(polytester)を導入する必要があるのだが、requirements.txtに記載されている

```
PyYAML==3.11
```
がエラーを起こすためにインストールできなかった。コマンドラインから試したところ、最新の3.13なら問題なくインストールできることがわかった。
requirements.txtを書き換えればインストールできるがそれは避けたい。

## 解決方法

requirements.txtに以下を記載

```
--install-option --no-deps polytester==1.2.0
```
--no-depsで依存ライブラリを自動的に取り込まなくなるのでrequirements.txtに以下を追記

```
PyYAML==3.13
clint==0.4.1
watchdog==0.8.2
```
Django の静的ファイルを S3 に置く

次のページの
[How to Setup Amazon S3 in a Django Project](https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html)
Working with static assets only と同じことを行いました。
相違点は、.env を使ったことです。

>プロジェクトは proj01
>アプリは home
>です。

コードは GitHub にあります。
[django_static_s3](https://github.com/ekzemplaro/django_static_s3)
>不具合があり、削除しました。

デプロイの手順

1) 依存ライブラリーのインストール

```bash
sudo pip install django-environ
sudo pip install boto3
sudo pip install django-storages
```

2) GitHub からクローン
>不具合があり、GitHub から削除しました。

```bash
github clone https://github.com/ekzemplaro/django_static_s3
```

3) proj01 (manage.py のあるフォルダー） に .env を作成

```text:proj01/.env
AWS_ACCESS_KEY_ID='AKIAISTHXOPXX333AAAA'
AWS_SECRET_ACCESS_KEY='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'
AWS_STORAGE_BUCKET_NAME='bucket01'
```

4) 静的なファイルを S3 にコピー

```bash
python manage.py collectstatic
```

>aws.amazon.com にログインして、S3 にコピーされていることを確認
![aws_dec0802.png](https://qiita-image-store.s3.amazonaws.com/0/179446/80edfa9f-843f-7ac2-6aa8-68823cff3ae4.png)


5) 開発サーバーを起動

```bash
python manage.py runserver
```

6) ブラウザーで http://127.0.0.1:8000/ にアクセス
![django_dec0801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b1cf269d-c0e9-a0b7-8333-00a65a78eb6e.png)
OpenCVで画像の色反転をしてみた

### ＜実装手順＞
Python4行で試せます！
1. ライブラリのインポート
2. 画像の読み込み
3. 色反転の処理を実行
4. 変換後の画像を保存

### 実際にやってみた
####1.ライブラリのインポート

~~~Python
import cv2
~~~

OpenCVのライブラリをインポートします。
※OpenCVをインストール済みの状態とします。

####2.画像の読み込み

~~~Python
img = cv2.imread('./data/pict/image1.jpg')
~~~
imread関数を使って指定したパスから画像を読み込みます。

####3.色反転の処理を実行

~~~Python
image2 = cv2.bitwise_not(img)
~~~
bitwise_not関数で色反転の処理を行います。


####4.変換後の画像を保存

~~~Python
cv2.imwrite('./data/pict/image2.jpg',image2)
~~~
imwrite関数で変換後の画像を保存します。


###実行すると

もとの画像
![image1.jpg](https://qiita-image-store.s3.amazonaws.com/0/317125/5490b0fe-53c8-0586-3b98-836b5c37cbd8.jpeg)



変換後の画像
![imageimage2.jpg](https://qiita-image-store.s3.amazonaws.com/0/317125/94f6ef90-9dbf-bb0d-3dcc-4a0151d7da7c.jpeg)

となることが確認できました。
Chromeでローカルのファイルを開いたらCORSポリシーエラー

# 現象
chromeでローカルのファイルを開いたらこんなエラーが出た。

```text
Access to XMLHttpRequest at '/file/to/something' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
```

# 原因
どうやら、chromeのセキュリティ設定のクロスサイトXX攻撃（スクリプトとかフォージュリとか）への対策で拒否されるらしい。

# 対策
chromeの起動オプションで一時的にセキュリティ設定をオフにできる。

```text
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security --user-data-dir --disable-features=CrossSiteDocumentBlockingIfIsolating
```