OmniAICreator/Qiita-1.07M huggingface dataset:
C# >  CSV取り込みを劇的に簡単にするCsvHelper



CSV取り込みしたのち、クラスにマッピングしてくれるライブラリ「CsvHelper」
NugetからCsvHelperを取得後、以下のように使う


## 列名を指定する方法

```csharp


using System;
using CsvHelper.Configuration.Attributes;
public class CsvEntity
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}


using CsvHelper;
public static List<CsvEntity> GoLoad(string csvFileFullPath)
{
    var result = new List<CsvEntity>();
    using (var reader = new StreamReader(csvFileFullPath)){
    using (var csv = new CsvReader(reader))
    {
        csv.Read();
        csv.ReadHeader();
        while (csv.Read())
		{
            var record = new CsvEntity
            {
                Field1 = csv.GetField("ColumnName1"),
                Field2 = csv.GetField("ColumnName2")
            };
            result.Add(record);
        }
    }
	return result;
}
```


## Attributesを使用する方法

```csharp
using System;
using CsvHelper.Configuration.Attributes;
public class CsvEntity
{
    [Name("ColumnName1")]
    public string Field1 { get; set; }

    [Name("ColumnName2")]
    public string Field2 { get; set; }
}


using CsvHelper;
public static List<CsvEntity> GoLoad(string csvFileFullPath)
{
    var result = new List<CsvEntity>();
    using (var reader = new StreamReader(csvFileFullPath))
    {
        using (var csv = new CsvReader(reader))
        {
            csv.Read();
            csv.ReadHeader();
            var records = csv.GetRecords<CsvEntity>();
            foreach (var record in records)
            {
                 result.Add(record);
            }
        }
    }
    return result;
}
```


## Shift_JIS

Shift_JISでCSVを読み込む必要がある場合には、
System.Text.Encoding.CodePagesをNugetから取得したのち、

```csharp
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var reader = new StreamReader(csvFileFullPath, Encoding.GetEncoding("Shift_JIS")))
```


# 参考

[CsvHelper](https://joshclose.github.io/CsvHelper/examples/reading/enumerate-class-records/)
シェル上で CPU のコア数をカウントする

# Shell

Linux

```sh
$ grep -ce '^processor\s\+:' /proc/cpuinfo
```

macOS

```sh
$ sysctl -n hw.ncpu
```

# Python

```sh
$ python -c 'import multiprocessing as m; print(m.cpu_count());'
```

# R

```sh
$ R --slave -e 'message(parallel::detectCores())'
```
【BluePrism】オブジェクトからプロセスに例外をエスカレーションするデバッグのコツ

##概要
オブジェクトの例外を親プロセスにエスカレーションするデバッグを実行したい場合の方法です。
ちょっとコツがあります。

##方法
親プロセスの任意のステージにてSet Next Stageして、ステップインでオブジェクトの中に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/2689efd5-8676-0ef8-2100-c350174a5cf9.png)

ここがコツです。
オブジェクト内の**例外ステージの直前**にSet Next Stageします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/7de47caf-0e40-385c-a53d-b914244805a1.png)
例外ステージの中身はこんな感じです。
例外詳細として「検索結果画面表示エラー」を返すようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/c249520a-0c6b-059c-7a0c-63654d431990.png)


親プロセスに戻って、復元ステージにブレークポイントを張っておきます。
そしてGoボタンをクリック。
すると、ブレークポイントを張っていた復元ステージに遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/cc142a7a-6551-de6b-3786-5d589a54a59c.png)

オブジェクトからエスカレーションされた例外の詳細は、ExceptionDetail()で取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/ed0a5db1-e551-1d6b-6a3b-80a5998e4c7c.png)
オブジェクト側からエスカレーションされた例外の詳細内容↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/1581af8a-8871-4bcc-935f-f1dfcaff77eb.png)
【Rails】ヘルパーのcheck_boxで複数選択を登録

備忘録用。 rails 5.2.3

Bookモデルにgenre(ジャンル)を
↓こんな感じで**チェックボックスから複数選択して登録**できるようにしたい。
<img width="209" alt="スクリーンショット 2019-04-16 19.09.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/4755198b-9a42-19e5-81a9-d7ada6200e50.png">
↑
SFとドラマにチェックが入っているので、
ジャンルは**`SF & ドラマ`**ということになる。

##view
ジャンルのリストは**`@list_genre`**に配列で格納されているとする。

```new/edit.html.erb
<%= form_for(@book, class: 'form-horizontal', role: 'form') do |f| %>

・・・　〜略〜
        <% @list_genre.each do |genre| %>
          <div>
            <%= f.check_box :genre,
                            { multiple: true,
                              checked: @book.genre.present? ? @book.genre.split(",").include?(genre) : false },  #・・・①
                              genre, nil %>
            <span><%= genre %></span>
          </div>
        <% end %>
・・・　〜略〜

<% end %>
```

##controller
```books_controller.rb

  def new
    @book = Book.new
    @list_genre = LIST_GENRE
  end

  def create
    @book = Book.new(book_params)
    params[:book][:genre] ? @book.genre = params[:book][:genre].join(",") : false #・・・②
    if @book.save
      redirect_to book_path(@book.id)
    else
      @list_genre = LIST_GENRE
      render :new
    end
  end
```
edit,updateも似たような感じで・・・

##補足
①： `checked:` によりeditの時、マッチしていればチェックが入る。
　　stringのinclude?では部分一致でマッチしてしまうのでsplit(",")でArrayにしている。
②：genreはデータ型がstringなのでjoin(",")して**`"SF, ドラマ"`**という形で格納させる必要がある。

##思っていること
Stringにしてsaveしたり、split(",")でArrayに戻したりと、ゴテゴテしていて美しくない気がする。
もっとうまいやり方はないものか。
↑
結論：これ使えばいいのかもhttps://qiita.com/RaimuEr/items/58971510735c6b906c50


参考：https://qiita.com/tomoima525/items/22c215db90cc9a9b09cc
set(CPACK_GENERATOR DEB) 使用時の注意点

本日この件で盛大に時間をつかいました…

```cmake
set(CPACK_GENERATOR DEB)
```

`CMake` で Debian packages を作成する場合は、この一行があったほうがいいかもしれません。

```cmake
set(CPACK_DEBIAN_ARCHIVE_TYPE "gnutar")
```

[[14.04] CPack builds broken DEB](https://ubuntuforums.org/showthread.php?t=2316865) に述べられていることが、言いたいことのすべてです。

## 問題点

CPack (CMake) で作成した deb ファイルを `dpkg -i` でインストールしようとすると、

```txt
root@64383d0c06d6:/dpkg# dpkg -i XXX.deb
(Reading database ... 31898 files and directories currently installed.)
Preparing to unpack .../XXX.deb ...
Unpacking XXX (0.4.0) ...
dpkg: error processing archive XXX.deb (--install):
 corrupted filesystem tarfile - corrupted package archive
dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)
Errors were encountered while processing:
 XXX.deb
```

`corrupted filesystem tarfile - corrupted package archive` というエラーになってしまいます。

## 原因と思われる点

- `dpkg` が管理する deb ファイルは [ar](https://linuxjm.osdn.jp/html/GNU_binutils/man1/ar.1.html) 形式
- 書庫の中に data.tar.gz という .tar が入っています
- これ [tar](https://linuxjm.osdn.jp/html/GNU_tar/man1/tar.1.html) を使って展開するのかと思ったらそうではなく、自力でデコードしています… [tarfn.c](https://github.com/guillemj/dpkg/blob/1da502d98ca40a9495172a95a49fdbf0f27ec4de/lib/dpkg/tarfn.c#L444)
- で、tar header に不明な typeflag のモノが存在し、遭遇すると、[ここ](https://github.com/guillemj/dpkg/blob/b08068d4bdaf60b2c15556de4da52c0dc9da5fa9/lib/dpkg/tarfn.c#L524)でエラーになる模様。`Bad header field` とでも表示されるべきですが、表示されず…
- 具体的には `XHDTYPE  'x'            /* Extended header referring to the
                                   next file in the archive */` が使用されていました。
- dpkg の 1.19.3 でこの問題が修正された模様です。
- dpkg の 1.18.x (1.18.25 が最新) では未修正…

dpkg 1.19.3 の [Changelog](https://launchpad.net/debian/+source/dpkg/1.19.3) にはさらっと書き流してある…

```txt
  * libdpkg: Detect unsupported tar entry types to give better error messages.
```

これですね!

という訳で、お互い気を付けましょう!
プログラミング学習記録59〜C言語〜

##今日やったこと
- C言語についてざっくり学ぶ

大学の講義でC言語に触れました。
まだ、本当に「触れた」という程度です。

C言語は難しい、挫折者が多いと聞いていたので、今まで見たことすらありませんでした。

ただ、C言語は多くの言語の土台であり、Webだけでなく、家電などの様々なデバイスでも利用されることから、とても大事であることがわかりました。

Webプログラミングよりもロボット、ドローン、家電などのIoTの分野に興味があるので「これも学ぶ必要があるのかな？」と思いました。

今のところそこまでがっつり学ぶつもりはないですが、いい機会ですので、C言語の基礎の基礎の基礎ぐらいは固めれたらと思います。

あと、今日スヌーピーのぬいぐるみを見て「子犬サイズのスヌーピーが立って歩いたらもっとかわいいな…」と思いました。

ゴミを拾うロボットが街中で活躍してくれる未来があるなら、癒してくれるスヌーピーが街中で歩いている未来もあるかもしれません。
あったらいいなと思います。

おわり
Railsチュートリアルメモ

# Railsチュートリアルメモ
※随時更新　備忘録のために

半分自分の備忘録のために書いていますが、チュートリアルを始めたばかりの方々も対象にしています。
私がチュートリアルをやった際にあまりに用語と用語の関係性が分からなかったので、
用語と用語の関係性が分かるように用語の意味を書き留めている記事です。

routes.rbファイル内ルーティング
` root 'controller名#アクション名'`

###テスト駆動開発
keep green
※3章後編
答えが分かった状態でその状態を目指す。
~~テストに先に求めたい動きをあらかじめ書いといて、~~
~~それが実装した後にちゃんと動くかどうかを確認しながら~~
開発する方法
↑※先に書くか後から書くかは場合による※




###リファクタリング
※３章後編
冗長さをなくすこと。
まとめられるところはまとめる。

###コントローラ
Railsのコントローラは、ApplicationControllerを継承したRubyのクラスであり、他のクラスと同様のメソッドが使えます。アプリケーションがブラウザからのリクエストを受け取ると、ルーティングによってコントローラとアクションが指名され、Railsはそれに応じてコントローラのインスタンスを生成し、アクション名と同じ名前のメソッドを実行します。
出典：RAILS GUIDES
https://railsguides.jp/action_controller_overview.html#%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9%E3%81%AE%E5%91%BD%E5%90%8D%E8%A6%8F%E5%89%87

###クラス(RUBY)
クラスとは、インスタンスの元となる、オブジェクト指向の設計図のようなものです。
出典:テックアカデミー
https://techacademy.jp/magazine/9720

####クラスの書き方


```
class User
  def initialize(name)   #←メソッド（関数）
    @name = name
  end

  def put_name　　　　#←メソッド（関数）
    p @name
  end
end
```

（クラスの中に複数のメソッド）

####Rubyのメソッド
正確には、Rubyはすべてがオブジェクトといえる。
記法

```
"foobar".length
⇒6
```
"foobar"というオブジェクトに対して、lengthというメッセージが渡される。
その結果(lengthで長さを聞いているので)6という結果が返ってくる。
※オブジェクト指向言語はすべてのオブジェクトにメッセージが送れる。
　→すべてのメッセージに対して返答が返ってくる。

####Rubyにおける?の意味

true or falseを返してくる

####メソッドチェーン
メソッドを何回も繰り返す

記法

```
メソッド.メソッド.メソッド
```
前のメソッドに対して、後のメッセージを投げる。
返ってきたメッセージ対して後のメッセージを投げる。

####Ruby公式リファレンスマニュアル

るりま
https://docs.ruby-lang.org/ja/

####Rubyの文法や構文に関して

4章見るべし

####アクションとメソッド違い

もはや同じだけど、通常アクションはrailsでの使われ方で
メソッドはRubyでの使われ方の違い。

####アクティブレコード

DBの言語をRailsを通して扱えるようにするもの。
コントローラで変数を定義してもローカル変数だから、一度そのコンソールから出ると、
データが残らず変数が消えてしまうけど、アクティブレコードを使って保存するコマンドを使うと
コマンドを抜けても変数は保存されるようになる。

####モデル作成の際

ほぼほぼ議論の余地がないくらいにテスト駆動開発が先に書かれる。

####インスタンス変数とローカル変数

インスタンス変数はメソッド外からも呼び出せる。

ローカル変数はメソッド内からのみ呼び出せる。

記法

```
#インスタンス変数
※メソッドの外側からも呼び出せる

def show
    @user = user.find
end

#ローカル変数
※メソッドの内側でのみ有効

def show 
    user = user.find
end 

```
Mac OS(Mojave)でpygameの表示が出力されない

#はじめに

Macを使い始めたばかりの人間が、Pythonをインストールして
pygameを動かしてみようとしたところ、公式が用意しているサンプルプログラムさえ
うまく動作しなかったので、それを解決した方法を紹介。

（pythonのインストールや環境構築については多くの人がWEBにて紹介しているのでこの記事では割愛します）
（brewやpyenvでpython3.7.3がインストール出来るようになったらこの記事は不要になるかと。。。）

#きっかけ

pythonでデスクトップアプリでも作ってみたいと思い、下記の本にある
「ゲーム作りで学ぶPython」
をまずは写経。
[日経ソフトウエア 2019年 3 月号](https://www.amazon.co.jp/%E6%97%A5%E7%B5%8C%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A8%E3%82%A2-2019%E5%B9%B4-3-%E6%9C%88%E5%8F%B7/dp/B07KZKK724)

写経も終わり、ターミナルから実行してみたところ、
ウィンドウは作成されるが期待した表示がされない。
（白に近い背景色の空白ウィンドウが出てくるだけ）

（2019/4/17追記）
この時点でのバージョンは下記（だったはず）。

```:terminal
(venv) mbp:~ hoge$ python -V
Python 3.7.2

(venv) mbp:~ hoge$ python
///中略///
>>> import pygame
pygame 1.9.4
Hello from the pygame community. https://www.pygame.org/contribute.html
```

#解決までの道のり

とりあえず、写経で間違っていないかをチェック。
　→　ソースコード上は問題なし

pygameのアンインストールとインストール
　→　結果は変わらず

python3のアンインストールとインストール
　→　結果は変わらず

[pygameの公式サイト](https://www.pygame.org/wiki/GettingStarted)
に書いてあるサンプルゲームの実行コマンドも試してみる
　　`python3 -m pygame.examples.aliens`
　→　結果は変わらず。むしろ音だけ出て絵が出てこないので余計に意味不明。

色々と調べていくうちに、下記のページを発見
[Pythonのmatplotlibで画面が白くなり描画（表示）されない場合の対処法(Mac)]
(https://murabitoleg.com/mac-matplotlib/)
　→　現象的に近いかなと思ったが、対処の方法が分からず断念。

もうダメかと思い、下記記事を参考に環境を再構築してみた。
[荒れ果てたpython開発環境を再構築する](https://kandai.hatenadiary.jp/entry/2018/07/16/105940)
　→　結果は変わらず。

ここまでやって、一旦諦めの境地へ。
tkinterかkivyを試してみようかな〜なんて考えたり。
が、ある日ふと閃いたことを実行してみたら即解決！

#解決策

[Python公式サイト](https://www.python.org/downloads/)
から最新版のバージョンをダウンロードしてインストールするだけ。
執筆時点（2019/4/16）では「3.7.3」が最新。
解決したのは2019/3/30

　*解決策へのヒント*
　[Blank screen on macOS Majave #16](https://github.com/HuangJunye/QPong/issues/16)
　[Pygame not compatible with MacOS Mojave #555](https://github.com/pygame/pygame/issues/555)


#おわりに

既存の記事通りにインストールするだけじゃなく、公式HPも大事だということがわかった。
リモートでビルド【Win→Linux】【HotReloadもどき】【VSCode】

## 記事のターゲット
- WindowsでLinux用のプログラムを作る。
- 最終的にはLinux側でビルドしなくてはならないため、出来ればLinux上でビルドをしながら開発したい。
- デバッグはプリント文いれて何とかする。
- VSCodeで開発したい。


## 最終目標
以下のGif画像のようなになればOK！
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184925/0ec0d27d-89c3-7bb8-bcc7-0f972643fdf3.gif)

## 手順
1. VSCodeをDL・インストールする。
2. Remote Workspaceというプラグインを入れる(リモート先をワークスペースに出来る)。
3. HotReloadっぽいことをやるために、ソースファイルを監視させるプロセスを作る。※ソースの変更を感知したら、`make && ./hello`を実行してもらう。`※ファイル監視　→　変更を感知　→　ビルド`
4. ファイル監視プロセスを起動しながら、ソースを変更していく。

### 1. VSCodeをDL・インストールする
https://code.visualstudio.com/

### 2. Remote Workspaceというプラグインを入れる

Remoto Wrokspaceを入れたら

``` .remote.code-workspace
{
  "folders": [
    {
      "uri": "sftp://user:pass@localhost:2222/home/",
      "name": "Test"
    }
  ]
}
```
`.XXX.code-workspace`を作る。その後VSCode上部の`ファイル＞ワークスペースを開く`から選択をすると、リモート先のディレクトリが見れるようになる（権限があれば編集も可能）

↓この方が詳しくまとめてくれています。
https://qiita.com/jerrywdlee/items/b239958d3df04364875d

### 3. HotReloadっぽいことをやるために…

> ファイル監視　→　変更を感知　→　ビルド

上記を実現するために、今回はPythonの`watchdog`を用いた。以下、ソース

```dir_watch.py
# -*- coding: utf-8 -*-

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer

import os
import time
import sys
import subprocess
import hashlib

hashes = {}
target_dir = ""
cmd = ""

class ChangeHandler(FileSystemEventHandler):
    def on_modified(self, event):
        filepath = event.src_path
        filename = os.path.basename(filepath)
        with open(filepath, 'rb') as f:
            checksum = hashlib.md5(f.read()).hexdigest()
        if filename not in hashes or (hashes[filename] != checksum):
            # コマンド実行
            subprocess.Popen(cmd, shell=True)
        else:
            # ハッシュが既存のものと変更していない
            pass

if __name__ in '__main__':
    args = sys.argv
    target_dir = args[1]
    cmd = args[2]
    while 1:
        event_handler = ChangeHandler()
        observer = Observer()
        observer.schedule(event_handler, target_dir, recursive=True)
        observer.start()
        print("Start!")
        try:
            while True:
                time.sleep(0.1)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()
```

```dir_watch.sh
ARG1="./src"
ARG2="
make && 
echo ++++++++++++++ && 
./bat/hello && 
echo ++++++++++++++"

python3 dir_watch.py $ARG1 "$ARG2"
# ./dist/dir_watch $ARG1 "$ARG2"
```

引数１で渡されたPathの`./src`下を監視して、ファイルに変更があれば、引数２で渡されたコマンドを実行している。
また、`pyinstaller`を使うと、ワンバイナリに出来るため、Pythonが入っていない環境でも、HotReloadもどきの事が出来るようになる。
**※監視対象とするPathに実行ファイルを生成しようとすると、大変なことになる！！！なので、実行ファイルを生成する場所は別ディレクトリにする。**

```
pyinstaller dir_watch.py --onefile
```

### 4. ファイル監視プロセスを起動しながら…
VSCodeのターミナルから、sshでリモート先に入り、`3.`で作成したプログラムを実行する。
その状態でソースの変更＆保存をすると、HotReloadもどきの動きをしてくれる。


## 参考URL
https://qiita.com/jerrywdlee/items/b239958d3df04364875d
https://qiita.com/hirohiro77/items/466e411fa41f144c8b2a
https://python-minutes.blogspot.com/2017/06/python.html
http://ur0.work/ahCv
#docker  で #ruby gem の redcarpet / reverse_markdown を使って 標準出入力から #Markdown #HTML 変換を行う例

# Dockerfile

```
FROM ruby

RUN gem install reverse_markdown redcarpet
```


# Exe
```
docker build . -t ruby-gems
```

```
$ echo '<h1>hey</h1>' | docker run -i ruby-gems  reverse_markdown
# hey
$ echo "abc" | docker run -i ruby-gems redcarpet
<p>abc</p>
```

 # Maybe badcase

```
$ docker run ruby-gems /bin/bash -c "echo '<h1>head</h1>' | reverse_markdown"
# head
$ docker run ruby-gems /bin/bash -c "echo '# h1' | redcarpet"
<h1>h1</h1>
```

# ref

[| Docker Documentation](https://docs.docker.com/engine/reference/run/)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Neovimのデフォルト設定

# はじめに
Neovimでは、今までvimrcに当たり前のように書いていたオプションがデフォルトで設定されています。
`:h vim_diff.txt`の出だしに載っているものを紹介します。

#機能
## Syntax highlighting
デフォルトで有効。

## :filetype plugin indent on
デフォルトで有効。

# オプション
## autoindent
改行時にインデントが保持される。

## autoread
vimで開いているファイルが外部で変更されたときに自動で読み直す。

## background
デフォルトで`dark`。

## backspace
デフォルトで`indent,eol,start`。バックスペースの挙動をよくあるように。

## backupdir
デフォルトは`~/.local/share/nvim/backup`。
`'backup'`がオンの場合、ファイルを上書きする前にバックアップが作られる。

## belloff
デフォルトで`all`。全てのイベントでベルが鳴らない。

## complete
vimのデフォルトである`.,w,b,u,t,i`から`i`を除いた`.,w,b,u,t`がNeovimのデフォルト。
キーワード補完の対象から、インクルードされるファイルが除かれている。
残った対象はバッファとタグ。

## cscopeverbose
デフォルトでオン。cscopeのデータベースに情報を追加するときメッセージが表示される。
cscopeはctagsのようなツール。

## directory
デフォルトは`~/.local/share/nvim/swap//`。スワップファイル用のディレクトリ。

## display
デフォルトは`lastline,msgsep`。

|||
|---|---|
|lastline|ウィンドウの最後の行ができるだけ多く表示される。謎。|
|msgsep|メッセージが`'cmdheight'`より長いとき、画面全体ではなくメッセージ行だけスクロールする。|

## encoding
デフォルトは`UTF-8`。Neovim内部とRPC通信に使われるエンコーディング。
RPCはリモートプラグインで使われる。

## fillchars
デフォルトは`vert:│,fold:·`。垂直分割の区切り文字と畳込んだ所の文字。

## formatoptions
デフォルトは`tcqj`。自動整形の方法を決める。vimに対して`j`が追加されている。

|||
|---|---|
| t | `'textwidth'を使ってテキストを自動折返しする`             |
| c | 同上。コメントだったらコメント開始文字を自動挿入する        |
| q | `gq`でコメントを整形する                                 |
| j | 複数行のコメントを連結する際に、余計なコメント開始文字を消す |


## fsync
デフォルトでオフ。vimではオンになっている。
オンになっていると`:write`の後などにOSのfsync()が呼ばれ、メモリからストレージに書き込まれる。
Neovimの場合、`CursorHold`イベントやNeovimが異常終了したときなどに書き込まれるためオフになっている。

## history
デフォルトで10000。EXコマンドと検索パターンの履歴数。

## hlsearch
デフォルトでオン。検索文字がハイライトされる。

## incsearch
デフォルトでオン。インクリメンタルサーチ。

## langnoremap
デフォルトでオン。Neovimではdeprecated。気にする必要なし。

## langremap
デフォルトでオフ。`'langmap'`を無効にする。
`'langmap'`は、キー入力をギリシャ語等の言語に切り替えることができるオプション。

## laststatus
デフォルトで2。ステータスラインを常に表示。

## listchars
デフォルトは`tab:> ,trail:-,nbsp:+`。nbsp`。nbspはnon-breakable spaceで0xA0やU+202F等。
'list'`モード時の表示文字で、`'list'`はタブ文字や行末を文字で表示するオプション。

## compatible
デフォルトでオフ。vi互換を無くす。
vimはvimrcがあればオフになっていたが、Neovimでは常にオフ。

## nrformats
デフォルトは`bin,hex`。`i_CTRL-A`,`i_CTRL_X`を使うときの進数。
vimから`octal`が除かれており、0始まりを8進数とみなさない。
0x,0bから始まる数をそれぞれ16進数、2進数と認識する。

## ruler
デフォルトでオン。カーソルの位置を表示する。

## sessionoptions
vimに対して、`"options"`が除かれている。
`:mksession`にオプションとマッピングが含まれない。
その場限りのオプションの変更やマッピングは保存しないということ。

## shortmess
デフォルトは`"F"`。Neovimの様々な表示を短くするオプション。
`"F"`はコマンドに対する`:silent`のように、ファイル編集中にファイル情報を表示しない。

## showcmd
デフォルトでオン。右下にコマンドが表示される。

## sidescroll
デフォルトで1。水平スクロールの刻み幅。vimでは0。

## smarttab
デフォルトでオン。`'shiftwidth'`,`'tabstop'`,`'softtabstop'`,`'expandtab'`をみてタブを快適に扱える。

## tabpagemax
デフォルトで50。タブページの最大数。vimでは10。

## tags
デフォルトは`./tags;,tags`。tagコマンドで使うファイル名。

## ttimeoutlen
デフォルトで50。キーコードの完了を待つ時間。ミリ秒。
vimとは違いマッピングとは関係がない。

## ttyfast
常にオン。Neovimでは削除されている。

## undodir
デフォルトは`~/.local/share/nvim/undo`。アンドゥファイル用のディレクトリ。

## viminfo
デフォルトで`"!"`が含まれている。アルファベットの大文字で始まり、小文字を含まないグローバル変数を保存・復元する。

## wildmenu
デフォルトでオン。コマンドライン補完で候補が表示される。
## wildoptions
デフォルトで`"pum,tagfile"`

|||
|---|---|
| pum | コマンドライン補完が挿入モードの補完と同じポップアップメニューになる。 |
| tagfiles | `c_CTRL-D` でタグの一覧表示をするとき、タグの種類とファイル名が表示される。        |
【Android】MutableLiveDataとObservableFieldの違い

DataBindingの際にどっちを使えばいいのかわからなくなって調べたときのメモです:angel:

# MutableLiveDataの特徴

```Kotlin
// こんなやつ
val animal = MutableLiveData<String>()
```

ActivityやFragmentのライフサイクルに応じて、ほぼ自動で購読管理をしてくれる。
→意図しないクラッシュ防ぐことができる

>LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services.

 [公式ドキュメント#livedata](https://developer.android.com/topic/libraries/data-binding/architecture#livedata) 

## ObservableFieldの特徴

```Kotlin
// こんなやつ
val animal = ObservableField<String>()
```
DataBindingをするときに使う。
ライフサイクルには対応しておらず、購読管理を自動ですることはできない。

# 違いについて
両方ともDataBindingに使えるオブジェクトですが、**ActivityやFragmentのライフサイクルに対応することができるかどうか**が大きな違いのようでした。

どちらを使うべきかはケースバイケースですが、基本的にはこれまで通り`ObservableField`を使いつつ、ライフサイクルと蜜に連携する必要があるときには`MutableLiveData`を使おうかなと思っています。
　
Googleの公式ドキュメントでは

>In Android Studio version 3.1 and higher, you can replace observable fields with LiveData objects in your data binding code.

のように、`ObservableField`を`MutableLiveData`に置き換えることができるよと言っているので、GoogleはLiveData推しなのかもしれません。

# 参考
[android - ObservableField or LiveData? Which one is the best? - Stack Overflow](https://stackoverflow.com/questions/51436189/observablefield-or-livedata-which-one-is-the-best)
 [公式ドキュメント#livedata](https://developer.android.com/topic/libraries/data-binding/architecture#livedata) 
[LiveData について勘違いしていたことをいくつか - Qiita](https://qiita.com/amay077/items/6e1c94305420a41ff7ed)
令和へ対応せよ！元号のアルゴリズム

#令和へ対応せよ！
2019年05月01日より元号は`平成`から`令和`へと変わります。
ですが悲しいかな、荒く組まれたシステムの中には元号が`平成`しか想定されていないものが…。
そんな可愛そうなプログラムを`令和`を感じることが出来るようにさせてあげましょう！

ちなみにこの記事のプログラミング言語はjavaScriptです。
しかし仕組みはどの言語でも通用すると思います。

##そもそもどうやって元号を判別する？
今回は`昭和`、`平成`、`令和`を判別出来るプログラムを組んでいきます。
問題はどうやって判別するのか？という所です。

###元号の定義を知ろう。
`昭和`は1926年12月25日から1989年01月07日(昭和61年)。
`平成`は1989年01月08日から2019年04月30日(平成31年)。
`令和`は2019年05月01日から～～～。
となります。

###ということは…?
今の西暦の日付と元号の定義を比較すれば判別出来そうですね。
雑に頭の中に浮かぶのは

```javascript
//判別したい日付の定義。
const now_year=2019,
      now_month=4,
      now_day=1;

//年・月・日を全て比較する。
if(1926>=now_year && now_year<=1989 && now_month>=12 && now_month<=1 && now_day>=25 && now_day<=7){
  console.log(`昭和`);
}
```

のような感じ。
なるほど、年・月・日をそれぞれ比較する感じにしてますね。
**が、流石にこれはガバガバです。**
`now_month>=12 && now_month<=1`とか冷静に考えなくてもバグバグの実の能力者かな？って感じですね。

###じゃぁじゃぁ…
じゃぁもっと繊細なプログラミングをしてみましょうか。

```javascript
//判別したい日付の定義。
const now_year=2019,
      now_month=4,
      now_day=1;

//まずは年の比較
if(1926<=now_year && now_year<=1989){
  //次に特定の西暦の場合の月・日の比較。
  if(now_year==1926){
    if(now_month>=12 && now_day>=25){
      console.log(`昭和`);
    }
  }else if(now_year==1989){
    if(now_month<=1 && now_day<=7){
      console.log(`昭和`);
    }
  }else{
    console.log(`昭和`);
  }
}
```

こんな感じに組み上がりました。
これで`昭和`が判別出来るはずです。
…でもなんかスマートじゃない気がしませんか？
まぁ日本独自の仕組みだし、こんなものかな…。

###Youのプログラムは無駄が多いZE!
と頭の中のメリケンが煽ってきます。
いけません、もっとクールにジャパンのシステムをビルドしなくては！
実はいい方法があるんです。

```javascript
//判別したい日付の定義。
const now_year=2019,
      now_month=4,
      now_day=1;

//西暦の計算（結果20190401）
const now_ad=now_year*10000+now_month*100+now_day;

//西暦の比較
if(19261225<=now_ad && now_ad<=19890107){
  console.log(`昭和`);
}
```
仕組みは割と単純で
年・月・日を`年*10000+月*100＋日`と計算することで
西暦のYYYYMMDDが求められます。
あとはその西暦を元号の期間と比較するだけです。

使ったif文は1つだけ！
比較演算子も2つしか使っていません！！
クール！！！

##出来上がったプログラムがこちら。

```javascript
//判別したい日付の定義。
const now_year=2019,
      now_month=4,
      now_day=1;

//西暦の計算（結果20190401）
const now_ad=now_year*10000+now_month*100+now_day;

//元号の判別。
if(19261225<=now_ad && now_ad<=19890107){
  console.log(`昭和`);
}else if(19890108<=now_ad && now_ad<=20190430){
  console.log(`平成`);
}else if(20190501<=now_ad){
  console.log(`令和`);
}else{
  console.log(`異常`);
}
```

これで`令和`の次の元号が発表されても簡単に対応出来るプログラムが書き上がりました。

###まぁ他にも良い方法はあると思う。
今回は暗に
・年と月と日の整数値だけがある。
・時間を処理できる関数を使わない。
でプログラミングしてました。

実際は色んな便利な関数があるはずなので、その言語に合わせて実装してみてください。

後は、現在の西暦YYYYに元号の始まりのYYYYを引き算すると年度が求められたりするので
頑張って新元号に対応してください。

#編集後記
入社12日目。
平成から令和への修正案件をやったので書きました。
まぁグーグルIMEですら「れいわ」と打って「令和」に変換できないので焦る必要ないと思います笑
「れい」と打って「令」を、そして「わ」と打って「和」を…
なんだか日本の生産効率性って一周回って笑えます。
【Windows】プロキシ設定が正常に反映されないときの対処法

# 2019.7.1 更新

もうちょっと詳しく書いた記事を出しましたので，こちらを参照してください．
https://qiita.com/t_asa/items/1557b5fd2d99d6e28307

# はじめに
Windows 10の「設定」アプリでプロキシを設定しても，一部のアプリケーションでは正しく反映されないことがある．<br>そこで，コマンドプロンプトによる操作で，対処する．

# 操作

1. 通常通り，「設定」アプリからプロキシの設定．
2. 管理者権限でコマンドプロンプトを開き，以下のコマンドを実行．

```bat:proxy.bat
netsh winhttp import proxy source=ie
```

コマンドについてはバッチファイル化して，デスクトップなりに置いておくと便利．
javascript ES6 {} で変数にオブジェクトを代入する書き方

```js
const obj = {
  a:1,
  b:2,
  c: {cc:3}
}
//分割代入。オブジェクトのプロパティを指定してあげる
const {b, c} = obj;


console.log(b) // 2
console.log(c); // {cc:3}
console.log(d); //d is not defined
```
分割代入というES6での新しい書き方。
慣れないうちは違和感を覚えたので簡単にメモ。
PyCharmでのvirtualenv環境

# 概要
- Pycharmでプロジェクト毎にPython環境を切り替え、プロジェクト固有のライブラリをシステムのpython環境を汚すことなくインストールしたい。
- pythonのvirutualenvで可能となるが、Pycharm環境ではどう設定するか？

# PyCharm環境
- virtualenvはバンドルされており、インストールは不要　
    -  https://pleiades.io/help/pycharm/creating-virtual-environment.html)
- プロジェクト作成時に、pythonインタープリタとしてvirtualenvを指定できる。
- プロジェクトのTerminalは、既にvirtualenvがactivateされている。

# 実例
## プロジェクト作成
- New environment usingで「Virtualenv」を指定
- Base interpreter:で使用するPythonランタイムパスを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/19a38b4e-0d11-aef1-42f0-51eb8c75e52c.png)

## プロジェクトを開く
- ターミナルは以下のようにvirtualenv(Hoge)にアタッチ済
- pythonバージョンは指定した3.6になっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/37a5baed-569d-bf2b-30b6-01a3659d7da2.png)

## プロジェクト固有のライブラリをインストール
- プロジェクトの端末からpipでscapy 2.4.0をインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/fe92893a-5e51-f57f-f7f8-797623e3b395.png)

- プロジェクトのScriptsフォルダにscapyライブラリがインストールされている。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/58a9661e-36c2-ac6c-9954-8af9f9744c5a.png)

- システムのPython3.6環境はクリーン（scapyライブラリはインストールされていない）
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/a163992f-7878-0345-8d9c-013cfb7ae575.png)
CakePHPのController::redirectがhttpに飛ばすのでbeforeRedirectでhttpsに飛ぶようにしてみた

先に結果
基底のController等があればそこに追加で

```
public function beforeRedirect(Event $event, $url, Response $response)
{
    // httpsにリダイレクトするように設定
    $response = $response->withLocation('https://' . $_SERVER["HTTP_HOST"] . Router::url($url));
    return $response;
}
```

Controller.beforeRedirectのオーバーライドして
Controller::redirectの動作に割り込みをかけます。
元のメソッドはreturn null;
してるだけなので気にせず書き換えます。

$this->redirect(['controller' => 'Login', 'action' => 'index']);

こんな感じで書くと元々httpにリダイレクトされてましたが
それをhttpsに書き換えています。
Cognos Analytics レポートでタイムスタンプや日付列から「年」や「年月」を生成する

#「年」や「年月」の生成
タイムスタンプや「日付」のデータから、「年」や「年月」を抽出する関数の紹介です。
「年月」のやり方は、タイムスタンプではなく、文字列データからの部分抽出も可能です。
![010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/218afc16-fbfd-2471-bced-36607bb1767d.jpeg)


#手順
新規にレポートを作成し、「GO データウェアハウス(クエリー)」パッケージを選択。
リストを配置。
![001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/c0de14de-865d-2779-c104-fdff72f7fea4.jpeg)

「クエリー1」に移動し、「クエリー計算」を追加し、名前に「年」、式の定義に「extract(year,[販売 (クエリー)].[時間].[日付])」を記載。
※[日付]は、赤枠の左端のタブから「時間」の下の「日付」を取得
※extractの第一引数の「year」は、タイムスタンプから「年」を抽出するという意味。monthやdayなども指定可能。
![002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/9e7772fd-5767-49b6-d3b0-93b9526bd2eb.jpeg)

赤枠の「検証」ボタンをクリックすると、計算式の書き方に問題ないかチェックできる。
![005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/6b2e946d-6ca6-327c-60d7-794fe33637cd.jpeg)

「数量」もクエリー1に追加。
![003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/55130ce5-0760-c426-d79b-dd4786a58eac.jpeg)

「ページ1」に移動し、「年」と「数量」をリストに配置。
![004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/7b772660-6bce-78f8-af40-95447e7031d6.jpeg)

レポートを実行すると以下のイメージ。
![006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/40b6cf32-a920-9690-23a1-eae9f63533b2.jpeg)

リストに「日付」を置いてみると。
![007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/adeb36b1-4eb3-6b86-7ab4-03d432fd464c.jpeg)

この様に、ちゃんと「年」が抽出できている事がわかる。
![008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/eb844967-847d-e123-e72d-7f122d1812b8.jpeg)

次に「年月」を抽出してみる。

「クエリー1」に戻り、「クエリー計算」を追加し、名前に「年月」、式の定義に「substring([日付],1,7)」と記載。
※substringの「1」と「7」は、[日付]の1文字目から7個文字を切り出す、という意味。
![009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/92e920c9-52b3-91a3-8d23-23c4fcbc147c.jpeg)

リストに配置しレポート実行。「年月」が抽出されていることがわかる。
![010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/69d59cf9-30c4-f631-c858-c5d7d2dc81a6.jpeg)

A11.Reportとして保存。

#自己学習記事一覧
**Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト**
https://qiita.com/shinyama/items/95885c7246dc413b6448
Mac OSのApacheでRedmineいれようとしたら[~~~~ fork() was called.]とかいって怒られたときの対処法


# 大目標
MacOS High Sierraで社内Redmineを立てる

## 今回のミニマム目標
Apacheのエラーログに出てきた下記エラーコードの解決

```
objc[1195]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
```

## 解決方法
/System/Library/LaunchDaemons/org.apache.httpd.plist に、
下記の変数を追加

```
<key>EnvironmentVariables</key>
<dict>
  <key>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</key>
  <string>YES</string>
</dict>
```

自分のorg.apache.httpd.plistファイルにはすでに`<key>EnvironmentVariables</key>`が用意されていたので、<dict>内に追加するだけでした。


そのあとは、

```
sudo apachectl restart
```

してあげれば、OKです。


### 経緯

`may have been in progress in another thread when fork() was called.`をそのままググると
https://qiita.com/ybiquitous/items/b43ffd2389e66a3a1c32
にヒットしました。**これ、どこに貼るんだろう?**

変数?環境変数かな? ~/.bash_profileかな??
→ **解決されず**



うちのHigh Sierra死んでるのかな?と諦めかけたときに
https://github.com/phusion/passenger/issues/1986
この記事をよくよく読み込むと

> Set the OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES env var to the apache launchd plist (requires disabling SIP)

なるほど、**to the apache launchd plist**ね。

書き方がわからなかったので、さらに
https://github.com/apache/whimsy/blob/master/MACOSX.md
をチェック。なるほど、こう書くのか。

思い当たる
**/System/Library/LaunchDaemons/org.apache.httpd.plist に追記して解決！！**


という流れでした。めでたしめでたし。。


### おまけ

High Sierra以降で起こるバグのようです。
Mojaveでは解決されているのかな?

10年前にリリースされた化石のようなMacを社内サーバー化したので、真偽は知れず。(Mojaveにアップグレードできない)
RedmineとSlackのもっとも簡単な連携

# きっかけ
私と違う方法でSlackとRedmineの連携を実現する人がいて
「ああああーーーーーーーーーーーーーーーーーーーΣ(ﾟДﾟ)」
となった。

ついこないだ[Gmailを使った連携](https://qiita.com/asuzuki2008/items/1a310d66959e06376911)をやったから。。。

# やること

## RedMine側

チケットとか、活動とか必要なチケットの状況が更新されそうなページの一番下にある、`Atom`のリンクからURLを取得する。（右クリック→URLコピーとか）
詳しいのは[ここ](http://blog.redmine.jp/articles/opc/slack/)。

## Slack側

[RSSのプラグイン](https://get.slack.help/hc/ja/articles/218688467-Slack-%E3%81%AB-RSS-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)インストール。

インストールした後、連絡を受けたいチャンネルで
`/feed subscribe RedmineのAtomのURL`
を実行すると登録完了。

削除する場合は
`/feed list`
で購読IDを確認して
`/feed remove 確認した購読ID`
で削除できる。

非常に簡単だ。。

# だがしかし。。
新規作成されたチケットの時しか飛んでこない。。なんでかな。
RSSに詳しくないので、この辺の対応がぱっとわからない。
仕方ないので、前回のGmail版で対応しているという。。。。
値が制約を満たしていることを型で保証する

URLをあらわす文字列であるとか、0以上であることが要求される整数であるとか、値が何らかの制約を満たすことを要求される場面は多くあります。

たとえば、男女2頭のヤギさんの角の本数を引数にとって、**その2頭のヤギさんが愛し合って交尾して子どもを作っても問題ないか**を判断する関数を定義します。

```elm
canMakeLove : Int -> Int -> Bool
```

それぞれの角の数を引数にとって Bool型を返す自然な設計ですね？

でも、ちょっとまってください！
有角のヤギさんは2本しか角を持っていません。
そのため、ヤギさんのとりうる角の数は**以下のいずれかしかありえない**はずです。

* 0本: 生まれつき無角のヤギさんか、有角の仔ヤギちゃんの角芽を焼きごてで焼いた（断末魔のような悲鳴がする）
* 1本: 有角の仔ヤギちゃんの角芽を焼いたけど不十分で1つだけ残った（断末魔の悲鳴が無駄になった😱）
* 2本: 生まれつき有角
* 3本以上: 染色体に異常があるので、ここではヤギとは見なさない

つまり、`canMakeLove` の引数に 3以上の整数を与えると動作が保証されなくなってしまいます。

でも、関数を使う側が「気をつけて使う」なんて、現代のプログラミングではありえないですよね？
ちゃんと技術を使って解決しましょう！

![sakura0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16345/d098570d-2ff2-cbbf-5153-cc29928444d7.jpeg)


## Horn型の導入

このように、何らかの制約を持つことが値に要求される場面でよく使われるテクニックがあります。
型によって値が制約を持つことを保証してしまうのです。

さっそくやってみましょう！

```elm
module Horn
    exposing
        ( Horn
        , fromInt
        , toInt
        )


{-| 角の本数をあらわす専用の型
-}
type Horn =
    Horn Int


{-| `Horn` 型の値を作成する唯一の方法

    fromInt 3
    --> Nothing

    fromInt 2
    --> Just (Horn 2)
-}
fromInt : Int -> Maybe Horn
fromInt n =
    if (0 <= n && n <= 2)
        then
            Just (Horn n)
        else
            Nothing


{-| `Horn` 型の値を整数に変換する唯一の方法
-}
toInt : Horn -> Int
toInt (Horn n) = n



{-| オスとメス（順不同）の角の本数から、その2頭が交尾しても問題ないかどうかどうかを判定する関数
-}
canMakeLove : Horn -> Horn -> Bool
canMakeLove = ...
```

まず注目していただきたいのは、`Horn`が [Opaque type](https://qiita.com/arowM/items/54fd76ee3965ddc86455) になっていることです。

```elm
module Horn
    exposing
        ( Horn(..)
        , ...
```

と記述すれば

```elm
Horn : Int -> Horn
```

という**コンストラクタ**もこのモジュールの外で使えますが、ここでは `Horn` という**型**のみを公開しているため、このコンストラクタはこのモジュール内部でしか使えません。

すると必然的に `fromInt` 以外に `Horn`型を作成する手段がありませんから、
「`Horn`型の値は必ずヤギさんの角の本数としてValidである」と保証されます。

では、実際に `canMakeLove` 関数を作ってみましょう！

```elm
{-| オスとメス（順不同）の角の本数から、その2頭が交尾しても問題ないかどうかどうかを判定する関数
-}
canMakeLove : Horn -> Horn -> Bool
canMakeLove (Horn n) (Horn m) =
    -- 無角同士の場合、無性のヤギが生まれてしまう可能性があるため交尾させない方が無難
    not (n == 0 && m == 0)
```

このライブラリを使う際にはこんな感じになります。

```elm
import Horn exposing (Horn)

type alias Model =
    { horn1 : Int
    , horn2 : Int
    }


message : Model -> Html Msg
message model =
    let
        horn1 : Maybe Horn
        horn1 = Horn.fromInt model.horn1

        horn2 : Maybe Horn
        horn2 = Horn.fromInt model.horn2

        mresult : Maybe Bool
        mresult = Maybe.map2 canMakeLove horn1 horn2
    in
    div
        []
        [ text <|
            case mresult of
                Nothing ->
                    "入力値が不正です"

                Just False ->
                    "無性のヤギが生まれる可能性があり、避けたほうが良いでしょう"

                Just True ->
                    "ふたりの愛をはばむものは何もありません"
        ]
```

家族がふえるよ！ やったね、ヤギさん


[さくらちゃんのツイッターをフォローする](https://twitter.com/arowM_)
[他の記事を見る](https://qiita.com/arowM)
[さくらちゃんの写真集を手に入れる](https://amzn.to/38DyjWr)
![sakura.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16345/9ce3f8d4-de0f-1d71-16c3-74bfc131c9d2.jpeg)
今更ながらFirebaseのCloudFunctionsを使ってみた@Firestoreのトリガーで

# はじめに

Cloud Firestoreの書き込みをトリガーに、Cloud Functionsでバックエンドコードを実行してみたいと思います。



今回は例として、チャットのメッセージ(messages/)が書き込まれた時にルーム(rooms/)に最新メッセージを書き込むようにしてみます。

（ルーム一覧で最新メッセージをチラ見せさせたい。）



# 準備

firebase-toolsをインストールしていない場合は下記でインストール。

```
npm install -g firebase-tools
or
yarn global add firebase-tools
```

```
firebase init
```

今回はTypeScriptを選択。

# 実装

Firestoreのイベントのトリガーは下記4つになります。

|イベント|トリガー|
|:---- |:-----|
|onCreate|ドキュメントが最初にトリガーされた時に呼ばれる|
|onUpdate|すでに存在してるドキュメントの値が変更された時に呼ばれる|
|onDelete|データを含むドキュメントが削除された時に呼ばれる|
|onWrite|onCreate、onUpdate、onDeleteがトリガーされた時に呼ばれる|

今回はメッセージが追加される度に処理したいので「onCreate」を利用します。

## コード

functions/srcディレクトリの下にあるindex.tsに処理を追加します。

```js:functions/src/index.ts
import * as functions from "firebase-functions";

export const setLatestMessage = functions
  .region("asia-northeast1")
  .firestore.document("rooms/{roomId}/messages/{messageId}")
  .onCreate(async (snap, context) => {
    const msgRef = snap.ref;
    const roomRef = msgRef.parent.parent;
    if (roomRef !== null) {
      await roomRef.set(
        {
          latestMsg: msgRef // 最新メッセージとして登録
        },
        { merge: true } // 追加書き込み
      );
    }
  });
```



## 補足

```js
functions.region("asia-northeast1")
```

"asia-northeast1"で東京リージョンになります。

FireStoreをトリガーにするときは、Firestoreのリージョンと合わせた方が良いみたいです。



```js
const roomRef = msgRef.parent.parent;
```

- messageドキュメントのparent == messagesコレクション
- messagesコレクションのparent == roomドキュメント

これでroomのドキュメントを取得することができます。



## デプロイ

```
yarn deploy
or
npm run deploy
```



無事にデプロイできたら後はメッセージが追加される度に作成したFunctionが実行されると思います。



# 感想

今回初めてCloudFunctionsを利用してみたのですが、思ってたよりもすごく簡単に実装できてびっくりしました。

もっと早く利用しておけば良かったと後悔。。

HTTPリクエスト経由でも実行できるみたいなので、今度そちらも試してみたいです。



# 参考

<https://firebase.google.com/docs/functions/get-started>
http.ListenAndServe() をインターネットに公開してはいけない

http.ListenAndServe() を使ったサーバーをプロダクションに投入していたのですが、海外からのアクセスが多くなったころにリソースリークが発覚しました。

[ListenAndServeのドキュメント](https://golang.org/pkg/net/http/#ListenAndServe)

ListenAndServeのソースを見るとこうなっています。

```go
func ListenAndServe(addr string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}
```

addr, handler 以外は http.Server のnil値がそのまま使われている事がわかります。この構造体にはいくつかのタイムアウト値がありまが、nil値で初期化されるとタイムアウトなしの状態になってしまいます。

[Server型のドキュメント](https://golang.org/pkg/net/http/#Server)

```go
        // ReadTimeout is the maximum duration for reading the entire
        // request, including the body.
        //
        // Because ReadTimeout does not let Handlers make per-request
        // decisions on each request body's acceptable deadline or
        // upload rate, most users will prefer to use
        // ReadHeaderTimeout. It is valid to use them both.
        ReadTimeout time.Duration

        // ReadHeaderTimeout is the amount of time allowed to read
        // request headers. The connection's read deadline is reset
        // after reading the headers and the Handler can decide what
        // is considered too slow for the body.
        ReadHeaderTimeout time.Duration // Go 1.8

        // WriteTimeout is the maximum duration before timing out
        // writes of the response. It is reset whenever a new
        // request's header is read. Like ReadTimeout, it does not
        // let Handlers make decisions on a per-request basis.
        WriteTimeout time.Duration

        // IdleTimeout is the maximum amount of time to wait for the
        // next request when keep-alives are enabled. If IdleTimeout
        // is zero, the value of ReadTimeout is used. If both are
        // zero, ReadHeaderTimeout is used.
        IdleTimeout time.Duration // Go 1.8
```

今回問題になっていたのはTCPハンドシェイクをしたあと全くリクエストを送ってこないクライアントでした。 ReadTimeout も IdleTimeout も設定していなかったのでずっとTCP接続がESTABLISHEDのままじわじわ溜まって行きました。接続数に伴って利用している fd 数も増え続け、いつかは上限に到達します。

上記のドキュメントにあるとおり、ReadTimeout と WriteTimeout は http handler 側で制御することができますが、 **ReadHeaderTimeout** だけは絶対に設定しておきましょう。 IdleTimeout は nil 値でも ReadTimeout か ReadHeaderTimeout と同じ値になるので、 ReadHeaderTimeout を設定してあればずっとたまり続けることは無いはずです。
Ubuntu git ~ github連携まで

参考にさせて頂いた資料
[資料](https://qiita.com/forest1/items/234026f7a305bf45f01a)


##gitを設定する

###インストール
`sudo apt install git `

###ユーザー設定

```
$ git config --global user.name [名前]
$ git config --global user.email [メールアドレス]
```

##Github連携

###ssh-keyの作成
Githubを連携させるには公開鍵が必要なので作成する
`ssh-keygen -t rsa -C "メールアドレス"`

ディレクトリに`~/.ssh/id_rsa`が作成される

###Githubに公開鍵の設定

クリップボードに鍵をコピーする
`$ cat ~/.ssh/id_rsa.pub | clip.exe`

###Githubで登録
Githubのページに移りアカウント設定の"SSH and GPG keys"を選択
> 右上の"New SSH key"を押し、
- Titleに自分が分かる名前
- keyにクリップボードから公開鍵をペースト
- "Add SSH key"を押す
で完了です。

###接続確認
ubuntuに戻り`$ ssh -T git@github.com`と入力
yesと入力

##git pushの問題
githubからコードをcloneしファイルを更新

```
git add -A
git commit -m "~~~"
git push -u origin master
```
このときUsernameとPasswordの確認が表示されることがある
###解決

**~/.netrc**にユーザー名とパスワードを書く
ファイルを作成し
`touch ~/.netrc`

```:.netrc
machine github.com
login username
password xxxxxxx
```
でおｋ

###それ以外にも
Githubからcloneする時点で対処できるかも

> "Clone or download"ボタンからcloneする時に、"Use ssh"を選択しておき、
urlが git@ から始まるアドレスになっていることを確認します。
httpsだと、普通のパスワード認証になってしまい、pushする際に毎回IDとパスワードが聞かれてしまいます。

これでいいのかも、？
WSL（ubuntu）のapache2に接続できなくてハマる

###WSLでbash環境を整えている
私は元来 windows を利用している。
職場がずっと windows だったからなのだけど、周りの開発者はみんな mac なわけで、話を聞いてみると

> bashがそのまま利用できるから
> aptってやれば、なんでもすぐに手に入るから

それって、linux環境が手軽に利用できるからということですかい？

ということで、windowsにもWSL(Windows Subsystem fo r Linux)なるものがあるので、こいつを使えば、俺も開発者と言っていいのか？と思い、使い始める。

###インストールは超簡単

プログラムと機能 > Windowsの機能の有効化または無効化 > Windows Subsystem for Linux 
を有効にして、Microsoft Store から 「wsl ubuntu」で検索して出てくる「ubuntu」をインストールするだけ。

手始めのインストールはとても簡単でした。

基本的なユーザ設定、ロケール設定などを済ませ、

```
sudo apt install apache2
sudo service apache2 start
cd ~
wget http://localhost/index.html
```

などと、動作確認してみると

```
Connecting to localhost (localhost)|127.0.0.1|:80... failed: Resource temporarily unavailable.
```

おやおや、動作していないじゃないか。

色々ウェブを読み漁り、ubuntu再インストールなどなど、やりつくしたところで気付く。
> ファイアウォールじゃん？

Windowsの（あるいはインストールされているファイアウォールアプリの）設定で
TCP 80 ポート　をローカルIPからは受け付けられるように設定してあげたら、いとも簡単に解決・・・・

この問題で１日使っちゃったよ・・・・
Cognos Analytics レポートで前年差異や累積の計算を行う

#前年比や累積計算
リストにおいて、特定の数値データの、前年差異や累積合計の計算式を作成する手順を学びます。
![007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/789833cc-f4b0-30f6-13e9-f3e905b38c16.jpeg)



#手順
A1.Reportを開始点とする。
クエリー1に、「クエリー計算」を追加し、名前に「前年差異」、式の定義に「running-difference ([数量] for [製品ライン])」を記載。
※running-differenceのような関数は、赤枠で示す「f{x}」タブで、Cognosで使用できる関数の一覧が表示されている
※for [製品ライン]の意味は、後ほどレポート実行時に説明する
![001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/2a7fc570-123d-1c71-df92-ab84cb5bcec7.jpeg)

ページ1に戻り、作成した「前年差異」をリストに配置。
![002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/1583733b-811a-d21f-6344-df7971fd0b2f.jpeg)

「製品ライン」の本体を選択し「グループ化」
![003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/d89646da-f625-0d81-1464-55ed9da64da6.jpeg)

レポートを実行してみる。
「前年差異」列に、前年との差分の数量の値が表示されている事がわかる。
それぞれの製品ライン、例えば「アウトドア用保護用品」の中での年ごとの差分が計算されている事がわかる。これが計算式で定義した「 for [製品ライン] 」の意味。
![004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/a9bfa4a4-3701-d9eb-95d9-fad0677bbee8.jpeg)

次に「累積合計」を作成する。
式の定義は「running-total([数量])」で、「for [製品ライン]」を入れてない事に注目。
![005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/f6e89a74-e446-3902-ded1-28a300fc8693.jpeg)

リストに「累積合計」を配置。
![006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/c8737f65-32b9-6cab-ccaf-a748c90f853c.jpeg)

レポートを実行してみる。
「累積合計」列が表示されるが、「for [製品ライン]」を指定していないので、「製品ライン」のグルーピングは無視して一気通貫で累積されていく事がわかる。
![007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/ce99e4c8-83ce-e117-8cf5-7c17d756ce7e.jpeg)

A10.Reportとして保存。

この様に、「f{x}」タブの関数を使いこなすと、表現の幅が広がりますので、色々と関数を使用してみてください。


#自己学習記事一覧
**Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト**
https://qiita.com/shinyama/items/95885c7246dc413b6448
【Java】MacOS 基本的なコマンドプロンプト

#コマンドラインプロンプト#
MacOS前提

```
カレントディレクトリ
cd /Users/ユーザー名/Desktop/
cd ~/Desktop/

フォルダ内の一覧(list)
ls -la

ファイルのコピー(copy)
cp コピー元のファイル名 コピー先のファイル名

ファイル名の変更(move file)
mv 現在のファイル名 新しいファイル名

ファイルの削除(remove)
rm ファイル名

ファイルの作成(make directory)
mkdir ファイル名
```

#Javaを実行する時#
```
クラスファイルの作成
javac Main.java

実行
java Main
```

#参考書籍#
[スッキリわかるJava入門 第二版]
(https://www.amazon.co.jp/dp/B00MIM1KFC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
付録A Pp.214-220
【Dockerfile】Debianのコンテナに新しいバージョンのFFmpegを入れたい

## 概要

- 本記事は自分用メモでございます。
- debianで素直にaptコマンドでFFmpegをインストールするとバージョンが低いので、新しいバージョンをインストールする。
- FFmpegの新しいバージョンは脆弱性対応がされているらしい。
    - （別の都合であるぱいんalpineからでびあんdebianに変更することになったなんて言えない・・・）

## 前提

## Dockerファイルの作成

39行目から84行目くらいが今回の内容。その他はRuby on Railsで使うための設定だったので気にしなくて良いです。
`FFMPEG_VERSION` の部分でFFmpegの好きなバージョンを指定しています。
rubyのバージョンが古い。→→ごめんバージョンアップ対応まだできてない
余分なパッケージも含まれている。→→勉強中でございます精進します

``` dockerfile:Dockerfile
FROM ruby:2.4

LABEL maintainer="nagait84 <nagai@hanoi.jp>"

# ビルド時の作業ディレクトリ
WORKDIR /app

# 文字コードUTF-8を使用。
ENV LANG C.UTF-8

# bundler インストールパスの指定
# ENV BUNDLE_PATH /app/vendor/bundle
ENV BUNDLE_APP_CONFIG /app/.bundle

# aptコマンドの警告を消す
ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NOWARNINGS yes

# 必要なパッケージをインストール
# @note 警告が出ます。aptコマンドを&&で繋いでいるため。コマンド数削減のため無視。
RUN apt -y update && \
    apt -y upgrade && \
    apt -y install \
        bash \
        curl \
        git \
        imagemagick \
        libmysql-cil-dev \
        libxml2-dev \
        libxslt1-dev \
        libyaml-dev \
        mysql-client \
        nodejs \
        ruby-dev \
        ruby-json \
        tzdata \
        zlib1g-dev

# ffmpegをインストール。脆弱性対応があるため3系で最新のものを使用。(2019/04/09時点)
# yasm, nasm, x264 など、依存パッケージのインストールが事前に必要らしい
# makeコマンドの際にいくつもwarningが発生している。これも解決するべきでしょうか。→→deprecatedなのでとりまスルーしてます。
RUN apt -y install \
        libass-dev \
        libmp3lame-dev \
        libopus-dev \
        librtmp-dev \
        libtheora-dev \
        libvorbis-dev \
        libvpx-dev \
        libx264-dev \
        libx265-dev \
        nasm \
        x264 \
        x265 \
        yasm && \
    FFMPEG_VERSION=3.4.6 && \
    DIR=$(mktemp -d) && \
    cd ${DIR} && \
    curl -s http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz | tar zxvf - -C . && \
    cd ffmpeg-${FFMPEG_VERSION} && \
    ./configure \
        --enable-version3 \
        --enable-gpl \
        --enable-nonfree \
        --enable-small \
        --enable-libmp3lame \
        --enable-libx264 \
        --enable-libx265 \
        --enable-libvpx \
        --enable-libtheora \
        --enable-libvorbis \
        --enable-libopus \
        --enable-libass \
        --enable-libwebp \
        --enable-librtmp \
        --enable-postproc \
        --enable-avresample \
        --enable-libfreetype \
        --enable-openssl \
        --disable-debug && \
    make && \
    make install && \
    make distclean && \
    rm -rf ${DIR}

# 3001番ポートを指定
EXPOSE 3001

# pumaソケットのnginx接続用マウント
VOLUME /puma_sokets_*******
```

## 参考にしたサイト

- http://thr3a.hatenablog.com/entry/20180718/1531920275
- https://github.com/opencoconut/ffmpeg/blob/master/Dockerfile
    - こちらはalpine
cordovaのimagePicker pluginのグラフィックバグを治す

こんにちわ。
eee_nbnbです。 

今回CordovaのImagepicker使う機会が合ったので導入して試してたんですけど、
悲しいことにiOSの方でラベルがずれたりプレビューの画像が大きくなったりと頭を抱えて悲しい気持ちでふて寝しました。
いわゆるバグと言うやつです。

まあ `<input type="input" multiple>`　を使えば複数選択できるしそれでも良いかなと思ってたんですけど枚数の指定などをしたかったのでこのプラグインを使うことにしました。

### とりあえずソースコードを見る
objective-cを書いたことがないしがないエンジニアでしたがswiftでiosのアプリを作ってたことがあってなんとなくiosのUIKit周りは覚えていました。

#### ズレるラベルたち
最初に対面したバグはUITableViewのセルを選択したときに中のラベルがずれるバグです。
<img width="160" alt="47414149-928fb280-d770-11e8-815e-9ae34f927b0b.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43232/aa612304-65c1-c1a4-6369-c53d6157a084.png">
多分セル側の問題だろうとのことでいろいろ見てたら `GMAlbumsViewCell.m` がTableViewCellなのがわかりました。
`setSelected`あたりが問題な気がしたのでとりあえずアニメーションを消します。


```GMAlbumsViewCell.m
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    //[super setSelected:selected animated:animated];
    // Configure the view for the selected state
}
```

とりあえずラベルはずれなくなったのですが今度はハイライトの時ずれるのでハイライト時のコードを付け足します。

```GMAlbumsViewCell.m
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    if( highlighted ) {
        [self setBackgroundColor:[UIColor lightGrayColor]];
    } else {
        [self setBackgroundColor:[UIColor whiteColor]];
    }
}
```

overrideしてすべてを無にして上書きですね。最高です。

#### なんか大きくなる画像達
何度か画像を選択したり外したりしてるとなんか画像が大きくなって表示が崩れます。結構地獄です。
<img width="160" alt="47414567-8d7f3300-d771-11e8-9bf6-8a4e83a604aa.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43232/684b6fc9-a689-f867-be92-4b7fdc05e781.png">
これはホントに謎過ぎてお家に帰りたくなりましたが、これはUIGridViewで作られていてどうやらまたセルが怪しい気がして `GMGridViewCell.m` を見ます。
`- (id)initWithFrame:(CGRect)frame` で何やらごちゃごちゃレイヤーを重ねていました。
リサイズされている気がしてUIImageViewには`autoresizingMask`と`translatesAutoresizingMaskIntoConstraints`いうプロパティがあるのでこの辺をコメントアウトします。

```GMGridViewCell.m
//_imageView.translatesAutoresizingMaskIntoConstraints = NO;
//_imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
```
なんかうまく行きました。なんか。

### 今後
もうちょいちゃんとしてからPR投げます。多分。
Amazon Web Services 基礎からのネットワーク&サーバ構築のまとめ　Chapter2

2章は実際にAWSを試してみる章です。

### 2-1 IPアドレスについて
####団体
IPアドレスはICANNという団体が管理している。その中でもアジア地域のIPアドレスはAPNICが管理していて、日本で絞るとJPNICが管理している。
ICANN > APNIC > JPNIC


####ネットワーク部とホスト部

IPアドレスは前半と後半に分ける必要がある。
前半をネットワーク部、後半をホスト部という。
分ける時の表記にはCIDR表記とサブネットマスク表記がある。

- CIDR表記
 - 192.168.1.0/16 
- サブネットマスク表記
 - 192.168.1.0/255.255.255.0

### 2-2~4

ここから実際にAWSを触る。
やる順番
VPCを作る -> VPNをサブネットに分割する -> インターネットゲートウェイを作成する -> ルートテーブルを設定する

#### VPCを作る
自分の使いたいネットワークの領域を決める。

#### VPCをサブネットに分割する
VPCを分割して複数のサブネットを作る。

- サブネットに分割する理由
    - 階や部屋ごとにサブネットを分けたい時がある。分けておくことで、どちらかに障害が起きても大丈夫。
    - サブネットを分けておくと、セキュリティを高めることができる。部署ごとでサブネットを分けてアクセスを制限するとか。

#### インターネットゲートウェイとルーティング

- インターネットゲートウェイ
 - インターネットと自分のネットワークを繋げる役割がある。
- ルーティング
 - パケットをどこに渡すか書かれた情報

パケットはTCP/IPで使われるデータの単位の事。ヘッダー情報とデータの情報が書かれている。 

### 感想
物理的に置いてたり、繋げたりする手間がなくて便利だし、場所も取らない。企業の間でクラウドが流行る理由が分かる気がする。簡単に構築できて便利だけど、コマンド叩かないからそっちの知識が付かないなーって感じた。
画像の数によって画像の大きさを変える

メルカリのコピーサイト作成中に、画像数によってCSSを変更したい箇所があり、
超基礎的な内容ですが、忘れてしまっていたので記録します。

#課題:weary:

画像をSlickを使ってスライドさせる仕様。
サムネイル画像が４個以上の時と５個以上の時で画像の大きさを変えたい。

↓４個以下の時<img width="1440" alt="スクリーンショット 2019-04-16 16.19.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/3aa228f0-50bd-d98d-66ac-7713d9f3b4f3.png">


#解決:innocent:
jQueryで当てるCSSを変更する

HTML

```haml
.individual__items__item__top__imagebox__image-thumb
  -if @item.photos.count > 1 #画像が１個以下の時は表示しない
   - @item.photos.each do |photo|
    = image_tag photo.image.url
```

CSS

```scss
&__image-thumb{
  width: 300px; margin: 0 auto;
  box-sizing: inherit;
   img{
    opacity: 0.5;
    outline-style: none;
    width: 25%;//基本は２５％にする
    height: auto;//高さはautoにする（変更する記述が少なくなる）
   }
```

jQuery

```js
$('.slick-list.draggable').children().each(function () {　
//slickを使うことでデフォルトのHTMLが生成されるため、セレクタが変になってます、、
  var num = $(this).find('img').length;
//imageの数をlengthメソッドで数える
  if(num>=5){
    $(this).find('img').css('width','20%');
//５個以上の時にimageに当たるCSSのwidthのみ20%に変更する
  }
});
````
かんせーい↓
<img width="1440" alt="スクリーンショット 2019-04-16 16.21.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/c2cc3b34-1839-f44a-a160-f9c2aa64bd24.png">

ちなみに上記HTMLの条件分岐でImageが１個の場合は表示されなくなっています↓
<img width="1440" alt="スクリーンショット 2019-04-16 17.02.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/7a3c26eb-33e4-bc87-f49e-a9a5e99ed943.png">


上記内容とは関係ありませんが、選択中のサムネイル画像だけopacityをあげています
かなり無理矢理感があるので良い方法があればご教示ください:relieved:

```js
$('.individual__items__item__top__imagebox__image-thumb').slick({
	slidesToShow: 10, //表示するスライドの数
	focusOnSelect: true, //フォーカスの有効化
	asNavFor: '.individual__items__item__top__imagebox__image', //ナビゲーション
	variableWidth:true, //画像の大きさ変更
});

$('.slick-list.draggable').children().on( 'mouseover', 'img', function() {
	$(this).click() //マウスオーバーでクリック
	$(this).css('opacity', 1); //選択した画像のopacityをあげる
	$(this).siblings().css('opacity', 0.5); //それ以外のサムネイル画像のopacityを下げる
});
```