OmniAICreator/Qiita-1.07M huggingface dataset:
nokogiriのインストールで An error occurred while installing nokogiri (1.8.4), and Bundler cannot continue.と出た時の対処法



[こちら](https://leanpub.com/everydayrailsrspec-jp/read#chapter-2)に沿ってrspecの勉強をしようと思い、手順にしたがって作業をしていたところ

**みんな大好きnokogiriのエラーが発生しました(´・ω・)**

```sh
$ bundle
```
ここのコマンドを叩いたら

```sh
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
（中略）
An error occurred while installing nokogiri (1.8.4), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.8.4' --source 'https://rubygems.org/'` succeeds before bundling.
```

とのエラーが。

あるあるなのですが、結構解決策がわからなくなってしまったりするのでメモ。

まずは[公式の手法](https://nokogiri.org/tutorials/installing_nokogiri.html)に沿ってやってみよう。

```sh
$ gem update --system
$ xcode-select --install 

$ gem install nokogiri
```

とある、、ふむふむ。
しかし会社のPCで色々制限があり、この方法は取れなさそうなのでパスしました。

もう少し読み進めていくとhomebrewを使っているならこれでもいけるよ、的なことが書いてありました

### 公式に載っている手法1

```sh
brew unlink xz
gem install nokogiri # or bundle install
brew link xz
```

### 公式に載っている手法2

```sh
brew install libxml2
# If installing directly
gem install nokogiri -- --use-system-libraries \
  --with-xml2-include=$(brew --prefix libxml2)/include/libxml2
# If using Bundle
bundle config build.nokogiri --use-system-libraries \
  --with-xml2-include=$(brew --prefix libxml2)/include/libxml2
bundle install
```

ほう…

ただ、gemはinstallできているようなので、

```sh

$ bundle config build.nokogiri この後ろのオプションをごにょごにょ
```
をすることでビルドオプションを指定してみました。

### 手順

1. $(brew --prefix libxml2)でlibxml2がインストールされているファイルパスを取得。

```sh
$ echo (brew --prefix libxml2)
```


僕の場合は

```
/Users/user_name/homebrew/opt/libxml2
```
と返ってきました。

2. 上記のパスを使ってビルドオプションを指定

```
$ bundle config build.nokogiri --with-xml2-config=/Users/user_name/homebrew/opt/libxml2/bin/xml2-config --with-xslt-config=/Users/user_name/homebrew/opt/libxslt/bin/xslt-config
```

長ったらしいですが

```
--with-xml2-config
```
と

```
--with-xslt-config
```
のオプションにパスを指定しています。

3. bundle installする

これで正常にnokogiriがインストールされました！

ちなみに[こちら](https://qiita.com/thunders/items/101c6b329830fb1fb27d)に書いてあったのですが、localをつけるとglobalでなくても設定できるようです

```sh

$ bundle config --local build.nokogiri
```

参考になれば幸いです。
SPIFFSの設定ガイドを日本語訳(意訳)


## はじめに
これは[pellepl/SPIFFS](https://github.com/pellepl/spiffs)の[Configure spiffs](https://github.com/pellepl/spiffs/wiki/Configure-spiffs)を翻訳(意訳)したものです。
SPIFFSはMITライセンスで配布されています。

SPIFFSとは、マイコンにSPI接続されたSPIフラッシュにファイルシステム載せられるものです。
通常、SPIフラッシュにはアドレスにデータを格納するRawなデバイスでしかありませんが、
ファイルシステムを用いることで、`fopen`や`read`などのモダンなファイル操作関数が使えるようになります。
本ガイドは、SPIFFSを任意のプラットフォームに移植する際のガイドを日本語意訳したものです。

### pellepl/SPIFFS
Copyright (c) 2013-2017 Peter Andersson (pelleplutt1976<at>gmail.com)
Released under the MIT license
https://github.com/pellepl/spiffs/blob/master/LICENSE


## ファイルシステム構造
はじめに、使おうとしているSPIフラッシュの大きさ、そのページサイズ(以後、物理ページサイズ)とセクター/ブロックサイズ(以後、物理ブロックサイズ)を知る必要があります。これらはデータシートから見つけることができます。

これを用いて、最初に大体どれくらいのSPIフラッシュの領域をspiffsに与えるか決める必要があります。

次にspiffsの論理ブロックサイズを決定する必要があります。
これは物理ブロックサイズの整数倍である必要があります。あなたのフラッシュメモリが4kB,16kBまたは64kBの物理ブロックサイズならば、論理ブロックサイズはnを整数とし、`n*4kB`,`n*16kB`または`n*64kB`になります。最も一般的なのは論理ブロックサイズをいくつかの物理ブロックサイズの総量と同じにセットすることです。ファイルシステムサイズのは論理ブロックサイズの整数倍になります。

それではspiffsの論理ページサイズを定義しましょう。これは論理ブロックサイズは論理ページサイズの整数倍にしなければいけないことと関係しています。あなたはおそらくフラッシュを効率よく利用するためにブロックあたり複数(>16)のページにしたいでしょう。一つの論理ページはspiffsにおける最も小さなデータ保持要素です。

64kBの論理ブロックサイズと決定し、256バイトを論理ページサイズとして使いると、256個の論理ページが１つの論理ブロックあたりに作り出されます。もし1バイトをフラッシュのspiffsのファイルに格納しようとすると、少なくとも１つの論理ページが使われます。また、一般的には物理ページサイズと論理ページサイズを同じにします。論理ページを大きくするとHALレイヤーのコードの記述が増えるため、物理ページサイズを超えないようにします。

それぞれのブロックとページにはいくつかのメタデータが来ます。そのため、すごく非常に小さいページまたはブロックはデータ/メタデータ率が極端に低くなります。非常に大きなページサイズはフラッシュの多くの領域を非利用にしてしまうでしょう。また、大量のページを持つとspiffsに多くの読み込みをさせるため遅くなります。

以上はすべて、どんな種類のファイルを通常格納し、どんなパフォーマンスを要求するのかに依ります。

はじめは、最も簡単に論理ページ/ブロックのサイズを物理ページ/ブロックのサイズに合わせることです。それが動いた後に必要に応じて実験できます。__論理ブロックまたは論理ページのサイズを変更すると、ファイルシステムの構造が変わるので再フォーマットが必要になることに気をつけてください。__

## ビルド時設定

すべてのビルド時設定は`spiffs_config.h`にあります。


### 以下書いてます
関数型プログラミングの魅力：数学式に近い表記で関数定義が可能

「関数型プログラミング言語を使うと、数学式に非常にちかい表記でプログラムが実装できる」ということが実感できた例

# フィボナッチ数列

フィボナッチ数列とは、0, 1, 1, 2, 3, 5, 8, 13, 21, ・・・のようにつづいていく数列です。最初の2項以外の項は、直前の2項の和として定義されます。

``` math
\begin{array}{l}
a_0=f(0) = 0
\\a_1=f(1) = 1
\\a_2=f(2) = f(1) + f(0) = 1
\\a_3=f(3) = f(2) + f(1) = 2
\\a_4=f(4) = f(3) + f(2) = 3
\\a_5=f(5) = f(4) + f(3) = 5
\\a_6=f(6) = f(5) + f(4) = 8
\\a_n=a_{n-1}+a_{n-2} = f(n-1) + f(n-2) 
\end{array}
```

0番目からはじまるときのフィボナッチ数列のn番目の要素 $f(n)$ は、数学的には以下のように表現されます。

``` math
f(n) = \left\{
　\begin{array}{ll}0 & (n = 0) 
  \\1 & (n = 1) 
  \\f(n-1) + f(n-2) & \{n | n\geq 2, n \in \mathbb{Z}\}
  \end{array}\right.
```

ここで、$\mathbb{Z}$ は整数集合になります。

# F#でフィボナッチ数列を求める関数を実装

上で示した数式に似た表記で関数`fib`が実装できます。すごい。

``` FSharp:code.fs
  let rec fib n:int =
    match n with
    | 0 -> 0
    | 1 -> 1
    | n when n>=2 -> fib(n-1) + fib(n-2) 
    | _ -> raise (Exception("未定義"))
  
  printfn "f(%d)=%d" 3 (fib 3) // 数列の3番目の要素  
  printfn "f(%d)=%d" 5 (fib 5) // 数列の5番目の要素  

  printfn "%A" <| List.map fib [0 .. 10] 
```

実行結果

```
f(3)=2
f(5)=5
[0; 1; 1; 2; 3; 5; 8; 13; 21; 34; 55]
```
EJSとSassとgulpで静的HTMLサイトを作る

# EJSとは

Embedded JavaScript templating.
埋め込みJSテンプレートということらしく、HTMLを構築するときに、パーツ化、変数化をJavascriptを書くことができます。
PHPとかCMSとか使えない静的なHTMLの構築のときに、Dreamweaverのテンプレートみたいなことがgulp環境化で実行できるので、とても便利です。gulp下でできるので、いつもつかっているSassとかと組み合わせると静的HTMLのコーディングがとてもラクになります。

- 静的なHTMLサイトを構築するときに、EJSをつかうとヘッダ・フッタの共通パーツを一つのファイルで管理できたり、それでいてタイトルやmeta要素などをページごとに変えたりとかできるので便利です。
- なによりJavascriptなのでWeb（とくにフロント）の人にはいじりやすいのではないかと思います。
- Webサイト構築に必須なSassと組み合わせると、静的HTMLの制作がとても楽になりました。
- それから、gulpが4になって書き方が変わってたりして少し躓いたのでそれも一緒に備忘録。

# 最低限必要なもので環境構築

## インストール

```
$ yarn add gulp gulp-sass gulp-autoprefixer gulp-ejs --dev
```
もしくは

```
$ npm install gulp gulp-sass gulp-autoprefixer gulp-ejs --save-dev
```

どちらかお好みでどうぞ。
`package.json`はこんな感じになります。

```json:package.json
{
  "devDependencies": {
    "gulp": "^4.0.0",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-ejs": "^3.3.0",
    "gulp-sass": "^4.0.2"
  }
}

```

## gulpfileを書きます

```js:gulpfile.js
var gulp = require("gulp");
var sass = require("gulp-sass");
var autoprefixer = require("gulp-autoprefixer");
var ejs = require("gulp-ejs");

// 監視　※gulp4の書き方です。
gulp.task( "default", function () {
    gulp.watch( "sass/**/*.scss", gulp.series( "sass" ) ); // sassディレクトリ以下の.scssファイルの更新を監視
    gulp.watch( "ejs/**/*.ejs", gulp.series( "ejs" ) ); // ejsディレクトリ以下の.ejsファイルの更新を監視
});

// Sass
gulp.task( "sass", function () {
    return gulp.src( 'sass/*.scss' )
        .pipe( sass().on( 'error', sass.logError ) )
        .pipe( autoprefixer( {
            // ベンダープレフィックスをどこまでつけるか（基本2バージョン前、IEは9以降・・・）
            browsers: [ 'last 2 version', 'ie >= 9', 'iOS >= 7', 'Android >= 4.2' ],
        }))
        .pipe( gulp.dest( './css' ));
});

// EJS
gulp.task( "ejs", function () {
    return gulp.src(["ejs/**/*.ejs", '!' + "ejs/**/_*.ejs"])
        .pipe(ejs({}, {}, { ext: '.html' }))
        .pipe( gulp.dest( "./" ) );
});
```

## フォルダ構成

```
.
├── css/
│   └── style.css
├── ejs/
│   ├── index.ejs
│   └── parts/
│       ├── _footer.ejs
│       └── _header.ejs
├── gulpfile.js
├── node_modules
├── package.json
└── sass/
    └── style.scss

```

- `ejs/`下のファイル（●●.ejs）を更新するとルートに●●.htmlで書き出されます。
- `_`で始まるejsファイルは、書き出されません。（パーツとして利用するなど）
- `sass/`下のファイル（●●.scss）を更新すると`css/`に書き出されます。

## 実行
上記が揃ったらgulpコマンド実行

```
$ gulp
```
あとは制作してくだけです。

---
（19/02/04 20:54追記）
ちょっと書き直しました。(^^
Swiper.jsを使ってみた

シンプルに画像のスライダーを設置したかったので試しに[Swiper](http://idangero.us/swiper/)を使ってみたときのメモ

ベースとなるhtmlは[こちら](http://idangero.us/swiper/get-started/)
今回はCDNで利用したので[ココ](https://cdnjs.com/)でバージョンをチェック


##### 設置
```html:head内
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.min.css">
```
```html:body内
<div class="swiper-container">
    <div class="swiper-wrapper">
        <!-- スライド -->
        <div class="swiper-slide"><img src="/img/img01.jpg"></div>
        <div class="swiper-slide"><img src="/img/img02.jpg"></div>
        <div class="swiper-slide"><img src="/img/img03.jpg"></div>
    </div>
    <!-- ページネーション -->
    <div class="swiper-pagination"></div>

    <!-- ナビゲーションボタン -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.min.js"></script>
<script>
var mySwiper = new Swiper ('.swiper-container', {
	loop: true,
	slidesPerView: 2,
	spaceBetween: 10,
	centeredSlides : true,
	breakpoints: {
		767: {
			slidesPerView: 1,
			spaceBetween: 0
		}
	},
	navigation: {
		nextEl: '.swiper-button-next',
		prevEl: '.swiper-button-prev',
	},
	pagination: {
		el: '.swiper-pagination',
	},
})
</script>
```

##### 使用したパラメータ概要
|パラメータ|初期値|説明|
|:---------|:---------|:---------|
|loop|false|trueの場合、最後のスライドまで行ったのち、次のスライドは最初のものに戻る。|
|slidesPerView|1|指定の枚数分が表示される。<br>2の場合は中央に１枚、左右に半分ずつ見切れたものが表示される。|
|spaceBetween|0|スライドとスライドの隙間<br>単位：ピクセル|
|centeredSlides|false|trueの場合、対象のスライドで中央寄せ<br>falseは左寄せ|
|breakpoints||ディスプレイ幅で表示を切り替えるために使用する。<br>今回の実装では767px以下の場合<br>・表示スライドを1枚<br>・スライド間の隙間を0px<br>と指定している。|
|navigation||「次へ」「前へ」のナビゲーションボタン表示するときに記述する。|
|pagination||ページネーションを表示するときに記述する。<br>今回はデフォルトの円だが、さらに色々なtype指定できる。|
[パラメータ詳細](http://idangero.us/swiper/api/)

今回は初使用だったのでほぼデフォルトの使用だったが、色々指定できるから幅広く対応できそうな予感。
PHPでPostgreSQLに接続する方法

# はじめに
 `CentOS`上のメールサーバが受信したメールを`PHP`で解析して、内容を`PostgreSQL`データベースに書き込む処理を作成することとなったため、備忘録としてやったことを残す。

# 実行環境
 - CentOS 6.9
 - Apache Http Service 2.4
 - PHP 7.2.14
 - PostgreSQL 9.5

# 環境構築
上記実行環境の環境構築は今回省略する。

### DB接続用ドライバのインストール
`PHP`から`PostgreSQL`データベースへのアクセスを可能にするための`PHP Data Objects (PDO)`をインストールする。

```yum install --enablerepo=remi-php72 php-pdo php-pgsql```

※別の接続方法として、`pg_connect`を使用する方法もあるらしいが、PHP初心者なので詳細な違いは不明。
　PDOを使用すると、DBの種類などを隠蔽でき、使用しているデータベースが何であるかにかかわらず、同じ関数を使用してクエリの発行やデータの取得が行えるとのこと。
参考：http://php.net/manual/ja/intro.pdo.php

# サンプルコード
ドライバや設定、接続確認用のシンプルなサンプル。
（とあるテーブルの全レコードを取得して指定した列名を一覧表示するプログラム。）

```
<?php

$DBHOST = "x.x.x.x";
$DBPORT = "xxxxx";
$DBNAME = "x";
$DBUSER = "x";
$DBPASS = "x";

try{
  //DB接続
  $dbh = new PDO("pgsql:host=$DBHOST;port=$DBPORT;dbname=$DBNAME;user=$DBUSER;password=$DBPASS");
  print("接続成功".'<br>');

  //SQL作成
  $sql = 'select * from x';
  //SQL例
  //$sql = 'select * from "SchemeName"."TableName"';

  //SQL実行
  foreach ($dbh->query($sql) as $row) {
      //指定Columnを一覧表示
      print($row['ColumnName'].'<br>');
  }

}catch(PDOException $e){
  print("接続失敗".'<br>');
  print($e.'<br>');
  die();
}
//データベースへの接続を閉じる
$dbh = null;
?>

```

# 実行結果
ブラウザでPHPを表示した結果を以下に示す。
1行目に「接続成功」が出力され、2行目以降に取得したColumnNameの値が一覧表示される。
![php_result.png](https://qiita-image-store.s3.amazonaws.com/0/226319/4a20fbb1-8ff3-4ba6-6a2c-bc5cab656538.png)

# まとめ
PHPからPostgreSQLに接続してデータ取得するところまでを行った。

どこかでメールの解析等も残したいなぁ。
NginxでWordpress5 の新エディタを使うときにエラーが出る場合の注意

## Nginx+PHP-FPMを使い、Wordpress5でパーマリンク構成をするときの注意

Wordpress5から、新たに Gutenberg という新しい新エディタが登場しました。そして、この新エディタ周りにいろいろ実装が施された結果、Wordpress4の時のように構成してしまい、エラーを吐いて動いてくれないという結果に...

パーマリンクを使わない場合は、素でPHPたたくと思うので、あまり問題にならないのですが、パーマリンクを使う場合は、index.phpへパースする必要があるので、そこでの設定ミスにより使えなくなるようです。

```nginx
location / {
    try_files $uri $uri/ /index.php$args;
 }
```

いつもは、この設定をしているのですが、これがだめなようです。

```nginx
location / {
    try_files $uri $uri/ /index.php$is_args$args;
}
```

これで動きます。

ただ、固定ページでは上でもOKでしたが、投稿ページだけエラーになっていたのが腑に落ちないのですが。

何故でしょう。
Processor中でCamelコンポーネントの利用方法


- ***Processor***とは、データ加工用部品、Apache Camelにて提供されている[メッセージの加工やルーティングを行う][1]ための部品です。
  *注意: ここでは、カスタム開発したProcessorを指します。*

- ***Camelコンポーネント***とは、外部接続用部品、Apache Camelにて提供されている[設定でいろいろなシステムに接続できる標準で実装されている部品][2]です。

[1]: https://jcug-oss.github.io/article/why-do-we-have-to-learn-camel-q
[2]: https://qiita.com/daikuro/items/39644d0af26318bb7281


## 背景

Camelの使ったComposite Serviceの開発標準化していく中で出てきた話題がありました。

Camel Routeは、[VETROデザインパターン][3]の処理フローの制御に適合しますが、プログラミング要素の強いロジックがやはり[Processor(データ加工用部品)][5]が一番適任だと感じました。

そして、Processorでも[Camelコンポーネント(外部接続用部品)][6]が使えると便利ですねという発想が生まれました。

と言うわけで、Processor中でCamelコンポーネントの利用する方法を調べました。

**結論は、[ProducerTemplate][4]を使えば簡単にできました。**

[3]: https://qiita.com/jian-feng/items/2ebaf103e50a24f8cfcc
[4]: http://camel.apache.org/producertemplate.html
[5]: http://camel.apache.org/processor.html
[6]: http://camel.apache.org/components.html


## ProducerTemplateとは

**[ProducerTemplate][4]** とは、Camelで用意されたインタフェースです。

このインタフェースを利用することで、Javaコード([Processor][5], Bean)の中でCamelが用意された豊富な[コンポーネント][6]を簡単にインスタンス化し、外部システムと送受信できるようになります。


今回実装したサンプルでは、[Processor][5]の中で、HTTPコンポーネントを使ったリクエストレスポンスの実現方法を紹介します。

サンプルのMavenプロジェクトは、https://github.com/jian-feng/producer-template-sample に置いてあります。

## 実装方法

### 1. camel-context.xml

camelContext内で`<template>` (ProducerTemplateのこと)を初期化します。  
また、MyProcessorはこのtemplate、とendpointUriで初期化します。

```xml
<bean id="myprocessor" class="org.mycompany.MyProcessor">
	<property name="producer" ref="myTemplate" />
	<property name="endpointUri" value="http://inet-ip.info/ip"/>
</bean>
<camelContext id="camel" ... >
	<template id="myTemplate" />
	...
</camelContext>
```

### 2. MyProcessor.java

```java
@Override
public void process(Exchange exchange) throws Exception {
	
	// camel-contextにて初期化されたProducerTempalteを使ってリクエストレスポンスを実行します。	
	String respBody = producer.requestBody(endpointUri,"test message from myprocessor", String.class);
	LOG.info("respBody={}", respBody);
	
	// ProducerTemplateから得られたレスポンスを現在処理中のExchangeにセットします。
	exchange.getIn().setBody(respBody);
}
```

### 3. camel-context.xml

camelContext内のCamel Routeは以下に定義します。

```xml
<route>
	...
	<log id="log1" message="body before myprocessor >>> ${body}" />
	<process ref="myprocessor" />
	<log id="log2" message="body after myprocessor >>> ${body}" />
</route>
```

## 実行方法

	mvn spring-boot:run

このサンプルを実行すると、１０秒間隔で、MyProcessorの中から指定のendpointUri([Camelコンポーネント][3]が使われる)にアクセスし、endpointのレスポンスをログに出力します。

	[Camel (camel) thread #1 - timer://foo] INFO  simple-route - body before myprocessor >>> Hello World from camel-context.xml
	[Camel (camel) thread #1 - timer://foo] INFO  MyProcessor - respBody=xx.xx.xx.xx
	[Camel (camel) thread #1 - timer://foo] INFO  simple-route - body after myprocessor >>> xx.xx.xx.xx

- 1行目のログは、simple-routeがMyProcessor実行前Bodyの出力
- 2行目は、MyProcessorの中でendpointのレスポンスをログに出力
- 3行目は、simple-routeがMyProcessor実行後Bodyの出力
- 1 - 3は、同じスレッドで処理されていること
pg_snakeoilを調べてみた

2019年2月2日の [PostgreSQLアンカンファレンス](https://pgunconf.connpass.com/event/115553/) で喋った内容をこちらにも書いておきます。

# pg_snakeoil

先月末（28 Jan 2019）に PostgreSQL Announce メーリングリストに、面白そうな拡張モジュールのリリースアナウンスがありました。その名も pg_snakeoil。名前も変（snakeoil=いんちき膏薬、的な意味）ですが、提供する機能が興味をそそります。[pg_snakeoil](https://github.com/credativ/pg_snakeoil) はオープンソースのウイルス対策ソフトClamAV を PostgreSQL から利用できるようにしたものです。

# PostgreSQL とウイルス対策ソフト

PostgreSQLは何しろウイルス対策ソフトと相性がよくありません。PostgreSQLはデータディレクトリの中をウイルス対策ソフトがスキャンすると、しばしば競合を起こします。特にファイルの同時オープンに厳しい Windows において顕著です。そしてウイルス対策ソフトは Windowsの場合に特に導入が要請されるものです。そのため、PostgreSQLのデータディレクトリはウイルス対策ソフトの検査対象外に指定しておくというのが、ベストプラクティスになっています。

![img1.PNG](https://qiita-image-store.s3.amazonaws.com/0/152412/5d41cfb9-547e-e7ad-7d25-5ec5c27bb25e.png)

ところが、そうすると攻撃者にとってPostgreSQLのデータディレクトリが都合の良いファイルの退避地になってしまいます。こうした理由から、PostgreSQLの動作と協調しながら、データディレクトリ内を検査してくれるツールを必要とされていました。

というわけで、pg_snakeoilのアナウンスを見て、まさにこれだと思ったわけです。ところがドキュメントを良く読むと・・・

# コレジャナイ

わたしが欲しいのはバックグラウンドで PostgreSQL配下のデータベースクラスタやテーブルスペース内のファイルを、PostgreSQL本体と競合せずに検査してくれる機能です。ところが、pg_snakeoilが提供するのは、引数の文字列やバイナリ列についてウイルスチェックするSQL関数でした。

````
postgres=# SELECT so_is_infected('Not a virus!');
 so_is_infected
----------------
 f
(1 row)

postgres=# SELECT so_is_infected('X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*');
 so_is_infected
----------------
 t
(1 row)
````

どちらかというと論理レベル、すなわち INSERT、UPDATEされるデータを検査する用途を指向しているようです。とはいえ、前述の希望する機能を作るときのお手本としては有用そうです。

# ビルドできない

手元の CentOS7.5 / PG10.6、そして、epelリポジトリから入手した clamav 0.101.1 で実際に使ってみようとしましたら・・・

````
pg_snakeoil.c: In function 'scan_data':
pg_snakeoil.c:163:93: error: 'CL_SCAN_STDOPT' undeclared (first use in this function)
  result.return_code = cl_scanmap_callback(map, &result.virus_name, &result.scanned, engine, CL_SCAN_STDOPT, NULL);

pg_snakeoil.c:163:2: error: too few arguments to function 'cl_scanmap_callback'
  result.return_code = cl_scanmap_callback(map, &result.virus_name, &result.scanned, engine, CL_SCAN_STDOPT, NULL);
````

エラーです。clamAV のバージョンが合っていないようです。しかし、README にはどのバージョンの clamAV をサポートしているかも書いていません。とりあえず、githubで作者にエラー報告をしました。

と、ここまででアンカンファレンス発表の時間です。上記のような話をしました。
「モノがウイルス対策ソフトなのだから、epelで何も考えずに導入される最新版に対応していないのでは困るよね」などと言ったりして。
その後、githubサイトを見ると・・・

# 速攻直してくれた

![img2.png](https://qiita-image-store.s3.amazonaws.com/0/152412/542869dd-f5df-06e7-5b8e-75dbd60c7a7d.png)

すばらしい。無事動作しました。
次は Windowsでのビルド、そしてバックグラウンドでファイルレベル検査に応用することを目指します。
Ruby.学習その１

#### 投稿目的
- 個人の学習目的で投稿していきます。
- Rubyの入門を読みながら自分なりの思考で記述しています。

#### 参考資料

[ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)](https://www.amazon.co.jp/ゼロからわかる-Ruby-超入門-かんたんIT基礎講座-五十嵐/dp/4297101238/ref=sr_1_3?ie=UTF8&qid=1549614126&sr=8-3&keywords=ruby+入門)

## Rubyとは？
- オープンソースの動的なプログラミング言語でシンプルさと高い生産性を備えている。
- Rubyではファイル名は小文字を使うのが一般的。

## Ruby実行
- エディターでプログラムを書いてファイルに保存。
- Rubyでプログラム記述したプログラムのファイル名の末尾には拡張子.rbを付ける。
- ターミナルでプログラムを保存したファイルへcdコマンドで移動。

```shell
$ cd　[ファイル名]
```

- ターミナルでRubyのプログラムを実行。

```shell
$ ruby　[ファイル名]
```


## putsメソッド
- putsは文字を画面に表示するメソッド(命令)。
- 整数、文字列、計算式などでも表示することができる。

```ruby
puts "hello"  
```

## 計算
- Rubyでは整数と少数は別のものとして扱われ、整数同士の計算の結果は整数になるルールがある。

```ruby
puts 5 / 2 　# 結果: 2
```

- 少数点の結果を求めるには両方または一方を少数にすることで可能。

```ruby
puts 5 / 2.0   # 結果: 2.5
```

## 変換
- 文字列と数値を計算するとエラーになる。
- 修正方法としてto_sメソッドとto_iメソッドを利用する。
 
```ruby
puts 10 + "10"   # エラー
```

- to_sメソッドで整数を文字列に変換。
 
```ruby
 puts 3.to_s + "3"   # 結果: 33
```

- to_iメソッドで文字列を整数に変換。
 
```ruby
 puts 3 + "3".to_i  # 結果: 6
```

## オブジェクト
- オブジェクト = 物
- オブジェクトには整数オブジェクト、少数オブジェクト、文字列オブジェクトなど種類が様々存在する。
- オブジェクトに対して何かをするメソッドは下記の形になる。
 
```
[オブジェクト.メソッド]
```

## コメント
- #を先頭に付けることでコメントと認識されてプログラムとして実行されない。
 
```ruby
# コメント内容
```

- 複数行をコメントにする場合は=beginと=endで囲んだ範囲がコメントと認識されプログラムとして実行されない。

```ruby
=begin
コメント内容1
コメント内容2
コメント内容3
=end
```

## 変数
##### 変数とは
- 変数とはオブジェクトに付ける名札.

##### 変数のルールと記述
- = は代入演算子、左辺に右辺を代入する。
- 変数名は原則として英字、数字、_(アンダースコア)を利用する、ただし頭文字は英字、アンダースコアを利用する.
 
```ruby
hensuu_ruby(変数名) = 値
```

## 定数
##### 定数とは
- 変数と意味は一緒だが定数は値を固定したい時に利用する。
 
##### 定数のルールと記述
- 定数は変数と同様値を代入することはできるが値を上書きして変更することはできない。
- 定数は先頭の文字を大文字にすると定数となる。
 
```ruby
Const_Ruby(定数名) = 値 
```

## 式展開
- #{}を利用することで文字列に計算式を埋め込んで結果を表示できる、これを式展開という。

```ruby
puts "3 + 5の答えは#{3 + 5}です"   # 結果: 3 + 5の答えは8です
```

- 式展開に変数も利用することができる。

```ruby
fruit = メロン   / fruit変数
puts "fruitには#{変数名}が入っている"  # 結果: fruitにはメロンが入っている 
```
###### 補足: 計算式と変数の他にも様々なプログラムを埋め込むことができる.

## getsメソッド
- getsメソッドを利用することでターミナ上から値を入力することができる。
- 条件分岐を使えば入力した値から結果を変えるプログラムを作ることができる

## pメソッド
- pメソッドはデバッグをする際に便利なメソッド。

```ruby
p 変数やオブジェクト
```

###### 補足: バグは問題があって動かない部分、デバッグはバグの原因を調べて正すこと.

## irb(Interactive Ruby)
- ターミナル上でirbを利用することで1行ずつ結果を見ながらプログラムを実行していくことができる。

```ruby
$ irb  # 実行すると下記の表記になる
$ irb(main:001:0)> 1 + 2(プログラムを入力) # 実行
=>3  # 結果が返ってくる
```

##### プログラムの途中で一時停止してirbを使用
- [require"irb"]と[binding.irb]を利用することでプログラムの途中で一時停止してirbを使うことができる

```ruby:test1.rb
ruby:test1.rb
require "irb"
hensuu = 100 
binding.irb   # ここで一時停止
puts hensuu   # まだ実行されない
```

```shell:ターミナル
$ ruby test1.rb   # test1.rbファイルを実行
$ irb(main):001:0> hensuu = 50   # hensuuに50を上書  
=>50  
$ irb(main):001:0> exit   # irbを抜けてる
=>50   # [puts hensuu]が実行される
```

###### 補足:Ruby2.3以前の場合はターミナルで

```shell
$ gem install pry   
$ sudo gem install pry   # Macに初期インストールされたRubyを使用している場合
```

###### を実行してインストールするとirbの替わりにpry(irbの代替)を使用する.

## エラーの読み解き
- [hi2.rb:1:]はどのファイル名の何行目かというメッセージ。
- [undefined method 'put' for main:Object]はエラーメッセージの本文。
- [Did you mean?  puts putc]はRubyからの提案。

```ruby
$ ruby hi2.rb
hi2.rb:1:in `<main>': undefined method `put' for main:Object (NoMethodError)
Did you mean?  puts
               putc
```
SalesforceトリガでのSOQL対象オブジェクトレコード数制限(20万件)

# Apexトリガでエラー発生
Apexトリガ内でSOQLを発行しているとき、対象オブジェクトのレコード数が200,000件以上で以下のエラーが発生しました。
System.QueryException: Non-selective query against large object type (more than 200000 rows)

上記は以下の状態のときに発生するようです。

> - 対象オブジェクト上のレコード件数が 200,000 レコード以上
> - SOQL の WHERE 句に使用されている項目に 外部ID / カスタムインデックスが付与されていない
> - 外部ID / カスタムインデックスが付与されていたとしても、インデックスが有効に動作する条件に合致していない

【参考】https://help.salesforce.com/articleView?id=000176875&language=ja&type=1

# 対応内容
簡単なのは、[設定]→[オブジェクトマネージャ]→[オブジェクト名]→[項目とリレーション]より、項目の編集を実施して「外部 ID」にチェックを入れる方法です。
ですが、項目の性質上外部IDに設定したくない場合があるかと思います。(一意にならないなど)
その場合はSalesforceサポートに以下の内容で問合せを行い、対象の項目にカスタムインデックスを付与してもらいましょう。

> a.組織ID
> b.対象のSOQL全文
> &nbsp;※SOQL に変数がふくまれている場合には、具体的な値を記載して下さい。
> &nbsp;例) SELECT Name FROM Account WHERE Test__c = 'TEST'
> c.実行ユーザ名(メール形式)
> &nbsp;※ログイン時に利用するメール形式のユーザ名となります。
> d.カスタムインデックスの有効性を確認した後、即時に付与を行って良いか [ はい/いいえ ]
> e.対象オブジェクトのAPI名
> &nbsp;※取引先オブジェクトであればAccountとなります。
> f.対象項目のAPI名
> &nbsp;※項目名が取引先の電話番号だった場合はPhone、カスタム項目にて項目名をTestと指定した場合はTest__cとなります。

【参考】https://help.salesforce.com/articleView?id=000193930&language=ja&type=1
独学スタート

# はじめまして

元・SEで、現・専業主婦をやっております、しっぽと申します。
この度、Unityの独学を始めました。

ようやく開発環境が整備できたので
備忘録および情報交換の目的でQiitaも始めてみます。
今までrom専だったQiitaに参加するのは、少し緊張感がありますがｗ

とりあえず、整えた開発環境は以下になります。

## 開発環境
OS：Windows 10 Pro
Unity：2018.3.3f1 
外部エディタ：VisualStudio2017 Community
バージョン管理：Bitbucket＆Sourcetree


---
グラフィック関連は経験ナシですし、数学も苦手ですし。
一抹の不安はありますが、せっかく自由な時間を手に入れたので
これを機会に、やりたいことをやってみようと思いまして。

主婦のやりたいこと＝コーディング

・・・って言うのも、シュールな感じはいたしますが（汗
よろしくお願いいたします。
Docker buildの際にgithubのprivate repoを持ってくる


# create key

```
ssh-keygen -t rsa -C hellp@mail.com -f deploy_rsa
```

# githubのrepoにkeyを登録

![image.png](https://qiita-image-store.s3.amazonaws.com/0/9294/bc7b216d-1ae4-f955-ee08-301eb11d7ffa.png)


# build docker 

keyをコピー -> ssh-agent起動 -> git clone -> (Optional) keyを消しとく

### Dockerfile

```bash
FROM your/repo

RUN apt-get update && \
    apt-get install -y openssh-server

RUN mkdir /root/.ssh
ADD ./deploy_rsa /root/.ssh/
RUN echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config
RUN SSH_KEY_PATH=/root/.ssh/deploy_rsa && \
    chmod 600 ${SSH_KEY_PATH} && \
    eval "$(ssh-agent -s)" && \
    ssh-add -k ${SSH_KEY_PATH} && \
    git clone git@github.com:contaconta/example.git example && \
    rm ${SSH_KEY_PATH}
```
数値の0、文字の"0"は true か false か。未定義値は何と一致するか。javascript と perl。

javascript(クライアント側)とperl(サーバ側)で、JSONデータやり取りする。
…というコードを、一人で同時に書いている時に、うっかり間違えたのでメモ。

Javascriptで、文字列の `"0"` は `true` だ。

```js:javascript
var num = 0;    // これは false
var str = "0";  // こっちは true
var emp = "";   // 文字列で言うなら、これが false
var undf;       // 未定義も当然 false

// 文字の "0" をifに放り込むと
if (str) {
    print "これが通る。";
}

// このケースが勘違いの元。
// 勝手にキャストされる。
if (str == 0) {
    print "文字列 str と数値の 0 が一致";
}
// こうすれば通らない
if (str === 0) {
}
else {
    print "===は型まで見るから一致しない";
}

// 空文字については
if (emp == 0) {
    print "数字の0と一致するのが面白い";
}
if (emp == "0") {
}
else {
    print "当然、空文字と文字の0は一致しない";
}

// 未定義値は何とも一致しない
if (undf == 0) {
}
else {
    print "undefindは0ではない";
}
if (undf == "") {
}
else {
    print "undefindは空文字とも違う";
}
```

一方、perlだと以下のようになる。
変数の型じゃなく、使う演算子で判断してる。

```pl:perl
my $num = 0;    # これは false
my $str = "0";  # これも false、0っぽいから。
my $emp = "";   # これももちろん false だし
my $undf;       # 当然 false

# 文字の "0" をifに放り込むとfalse。
if ($str) {
}
else {
   print "0っぽいからfalse";
}

# 演算子を見て良きにはからってくれる。
if ($str == 0) {
    print "数値比較した結果、文字の0は数値の0と一致";
}
if ($num eq '0') {
    print "文字比較した結果、数値の0と文字の0が一致";
}

# 空文字についても同様。
if ($emp == 0) {
    print "空文字ってことは数値で言えば0";
}
if ($emp eq "0") {
}
else {
    print "でも文字で言えば、0とは違う";
}

# 未定義とかも、あんまり考えなくていい。
if ($undf == 0) {
    print "値がない、ということは、数値で表せば0";
}
if ($undf eq "") {
    print "文字で言えば空文字";
}
# わざわざ未定義を判別したいこととかある？
if (!defined($undf)) {
    print "どうしてもと言うなら、defined()で";
}
```

# 雑談

perlはそもそも変数に型とか無い。
型制限したいなら、そのように書く方法もあるけど、デフォルトはなし。

perl式の気の利き方に慣れると、コーディングがやたら快適だけど、特殊なんだろうなとは思う。

javascriptは、いっそ勝手にキャストしたりしないでくれたら、最初からそのつもりで書くのに。
それはそれでやっぱり面倒くさいから、現状のようになってるのかなぁ。
【Oracle】複数項目から同一値を検索したいっ！

こういうテーブル（RECIPEテーブル）があります。

|MENU_ID| MENU_NAME | INGREDIENT1 | INGREDIENT2 | INGREDIENT3 | INGREDIENT4 | INGREDIENT5 |
|:-----:|:---------:|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
|1      |カレー     |ニンジン     |ジャガイモ   |お肉         |ルー         |             |
|2      |肉じゃが   |ジャガイモ   |お肉         |しらたき     |             |             |
|3      |味噌汁     |わかめ       |豆腐         |油揚げ       |             |             |
|4      |ハンバーグ |卵           |お肉         |玉ねぎ       |パン粉       |             |

このテーブルの中から、『材料に「お肉」を使っているもの』を検索したい！

# こう書く？

```SQL:パターン１
SELECT MENU_NAME FROM RECIPE
WHERE (INGREDIENT1 = 'お肉'
    OR INGREDIENT2 = 'お肉'
    OR INGREDIENT3 = 'お肉'
    OR INGREDIENT4 = 'お肉'
    OR INGREDIENT5 = 'お肉')
```

# こう書ける！

```SQL:パターン２
SELECT MENU_NAME FROM RECIPE
WHERE 'お肉' IN (INGREDIENT1
                ,INGREDIENT2
                ,INGREDIENT3
                ,INGREDIENT4
                ,INGREDIENT5)
```

# とはいえ…
実際はどっちのほうが良いんでしょう。
「お肉」をたくさん書かなくて済むから後者の方が見た目は良い…？
（そもそもINGREDIENTテーブル作ったら良いじゃんって思うんだけど…）
他に書き方があったら教えてください。

# ちなみに
左辺に定数を記述するスタイルのことを「ヨーダ記法」と言うそうです。
May the Force be with us...
EC2からRDSへの接続

#EC2からRDS(mysql)に接続
前回EC2内にデータベースを作成してデータの参照を行ったが今回は
RDSを使用してデータの参照を行うようにした

参考[PHPでPDOを利用してMySQL(RDS)に接続する](https://qiita.com/dxtomochika/items/ee6a056b2686a7e7fb64)

PODの設定

```
$pdo = new PDO(
        'mysql:host={エンドポイント};dbname={データベースの名前};charset=utf8',
        'マスターユーザの名前',
        'マスターパスワード'
    );
```

*データベースのセキュリティグループのソースを変更すること

RDSへのログイン

```
mysql -h wcup2006.cxzzbjlelesy.ap-northeast-1.rds.amazonaws.com -P 3306 -u root -p
```

sqlのインストール
sudo yum install mysql
【Go言語】GinでTemplateパッケージにCSS等のファイルを適用させる

# 背景
Webの画面をGoで作りたく、ただ、フルスタックの[Beego](https://github.com/astaxie/beego)を入れるほどリッチにはしたくないなと、ってことで[Gin](https://github.com/gin-gonic/gin)をいれて作っていた。
※紛らわしいことにコンパイルのauto-reloadをやってくれる同名のGINというパッケージもある

ここでは、CSS等をhtmlに適用させる際に学んだことをつらつら書いていきたいと思います。

# CSSを適用させる
main.goがあったとする。というより、こう書けば静的ファイルをインポートできる。

```main.go
package main

import "github.com/gin-gonic/gin"

func main() {
        r := gin.Default()
        // 静的ファイルの
        // router.Static("URL", "静的ファイル格納場所")
        router.Static("/assets", "./assets")
        router.LoadHTMLGlob("templates/*/**")        
        HTML(http.StatusOK, "index.tmpl", gin.H{
            "title": "XXX",
        })
        r.Run()
}
```

ちなみにフォルダ構成はこんな感じ

```
root/
　├ main.go
　├ templates/main/index.tmpl
　| // ここに静的ファイルを置く
　└ assets/
    ├ images/xxx.png
    └ css/xxx.css
```

んで、テンプレート

```(index.tmpl).html
//↑.htmlって書かないとQiitaのスタイルが適用されないので...
<html>
<head>
    <title>{{.title}} </title>
    <style type="text/css" media="screen">
      @import url("/assets/css/xxx.css");
    </style>
</head>
<body>
    <h1>TEST</h1>
</body>
</html>
```
Mac で Raspberry Pi 用のディスクをフォーマット（ diskutil 編）

# 概要
  
Raspberry Pi で使用するための、microSD カードをフォーマットします。購入したばかりの microSD カードは、特に初期化しなくても、Raspberry Pi で、すんなり動作する場合が多いのです。  
  
しかし、一度使用した microSD カードだと、うまくいかない場合もあります。そんな時は、ディスクをまっさらな状態にフォーマットしましょう。  
  
# 関連サイト
  
[Mac で Raspberry Pi 用のディスクをフォーマット その 1 -- diskutil](https://stangler.hatenablog.com/entry/2019/02/04/113016)
  
# ホスト

## Mac

* [MacBook Pro ( 13-inch, Early 2011 )](https://support.apple.com/kb/SP619?locale=ja_JP&viewlocale=ja_JP) 魔改造済み

* メモリ: 16 GB

* ストレージ: SSD 512 GB

* OS: macOS Sierra 10.12.6
  
# カード確認
  
まず、ターミナルを起動し、フォーマットするディスクを確認します。以下の diskutil コマンドを実行してみましょう。  
  
```
% diskutil list
```
  
すると、Mac 場で稼働しているディスクのリストが表示されます。  
  
```
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *512.1 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage Macintosh HD            511.3 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3

/dev/disk1 (internal, virtual):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           +510.9 GB   disk1
                                 Logical Volume on disk0s2
                                 7677XXXX-5XXX-49XX-9291-46DFXXXXXXX
                                 Unlocked Encrypted

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.6 GB    disk2
   1:             Windows_FAT_32 BOOT                    15.6 GB    disk2s1
```
  
今回の例では、/dev/disk2 (external, physical) というのが、microSD カードとなります。  
  
# フォーマット
  
それでは、disk2 をフォーマットしてみます。以下のコマンドを実行してください。今回は、ディスクの名前を「 RPI 」としました。名前を好きなものを適宜つけてください。  
  
```
% diskutil eraseDisk MS-DOS RPI disk2
```
  
以下のように「 Finished 」が表示されていれば OK です。  
  
```
Started erase on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s2 as MS-DOS (FAT) with name RPI
512 bytes per physical sector
/dev/rdisk2s2: 30006624 sectors in 1875414 FAT32 clusters (8192 bytes/cluster)
bps=512 spc=16 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=30035968 bspf=14652 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2
```
  
以上です。
[JS]ファイルを読み込んでハッシュ化しよう

#:pencil2:前書き:writing_hand_tone5:
ローカルのファイルを読み込んでそれをハッシュ化するという機能を実装する機会があったの方法をまとめておきます

ブロックチェーンのハッカソンとかで使う機会があるかもしれないです
#:relaxed:create-react-app:frowning2:

```console
$ npx create-react-app hash
$ cd hash
$ npm start
```

#:fist:js-md5:raised_hand_tone5:
今回はMD5というハッシュ関数を使ってファイルをハッシュ化します
js-md5という簡単にハッシュ化できるライブラリがあったのでそれを使います
[js-md5へのリンク](https://github.com/emn178/js-md5)

```console
$ npm install --save js-md5
```

#:airplane:実装例:airplane:
App.jsを書き換えましょう

```jsx:App.js
import React, { Component } from "react";
import md5 from 'js-md5';

class App extends Component {
  constructor(props) {
    super(props);
  this.state = {
    hash: null
  }
}

 getMd5 = () => {
   const element = document.getElementById('file');

   //ファイルが選択されたか
   if(!(element.value)) return;

   //FileReaderクラスに対応しているか
   if (!(window.FileReader)) return;

   //0番目のファイルオブジェクトを取得
   const file = element.files[0];

   //FileReaderオブジェクトを生成
   const fileReader = new FileReader();

   //読み込み時に実行されるイベント
   fileReader.onload = function () {
     const res = fileReader.result;
     //MD5ハッシュ関数でハッシュ化
     const hash = md5(res);
     this.setState({hash})
   }.bind(this); //関数をbindしないとhashをsetStateできない

   //読み込みを開始する(ArrayBufferオブジェクトを得る)
   fileReader.readAsArrayBuffer(file);
 }

 render() {
   return (
     <div className="App" align="center">
       <input type='file' id='file' onChange={this.getMd5}></input>
       <p>{this.state.hash}</p>
     </div>
   );
 }
}
export default App;
```

#:sunny:結果:snowman2:
<img width="313" alt="スクリーンショット 2019-02-04 16.53.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/326169/891939b4-4e15-bc0c-2424-a490a0cf9da6.png">


こんな感じでファイルのハッシュ値が表示されます
楽しいですね！！
GoogleDataPortalを使った日本地図の表示


本家のリファレンスが分かりにくかったのでもっと優しく書く。

前提条件として、参考先データベースとの連携が終わっていること。

#グラフの追加

まずは<b>GoogleDataPortal</b>にアクセスして新しいレポートを作成。

右上にある<b>グラフを追加</b>を押す。
![スクリーンショット 2019-02-04 16.18.04.png](https://qiita-image-store.s3.amazonaws.com/0/354659/5c1b6fd3-a313-de03-2092-d512a1a80aeb.png)

次に<b>地図</b>を選択。

以下のような画面が表示される。

![スクリーンショット 2019-02-04 16.31.08.png](https://qiita-image-store.s3.amazonaws.com/0/354659/d8439788-2594-7ed0-631a-2c90dec34224.png)

#参考データの反映

表示されているグレーの部分をクリックすると右側に以下のような画面が表示される。

![スクリーンショット 2019-02-04 16.38.29.png](https://qiita-image-store.s3.amazonaws.com/0/354659/7b08e383-275a-37f1-1a53-efe7220a5435.png)

ディメンションの欄に国名が格納されたカラムをドラッグ&ドロップで追加すると以下のような画面が表示される。

![スクリーンショット 2019-02-04 16.42.11.png](https://qiita-image-store.s3.amazonaws.com/0/354659/cdbbad20-3244-94dc-d3fe-4edcb1d30974.png)

世界地図が現れる。

次にディメンションの<b>編集マーク</b>をクリックする。

![スクリーンショット 2019-02-04 16.46.35.png](https://qiita-image-store.s3.amazonaws.com/0/354659/f94706aa-4a05-30f4-3b24-4da202281907.png)

<b>タイプ</b>を選択し<b>地域</b>を選択して<b>地域</b>を選択する。

![スクリーンショット 2019-02-04 16.51.36.png](https://qiita-image-store.s3.amazonaws.com/0/354659/2c9119d2-d2bb-2e59-764b-fff8049e547d.png)



次に<b>エリアをズーム</b>を押す。

![スクリーンショット 2019-02-04 16.49.55.png](https://qiita-image-store.s3.amazonaws.com/0/354659/880353a7-235a-f430-4cba-a1fa5e46e62d.png)

選択ツールが現れたら<b>日本</b>を選択すると日本地図が表示される。

![スクリーンショット 2019-02-04 16.53.01.png](https://qiita-image-store.s3.amazonaws.com/0/354659/b556d9ce-a29c-0549-102b-e49f02d88fc3.png)

都道府県ごとのデータがあるとヒートマップにも反映される。

![スクリーンショット 2019-02-04 16.53.58.png](https://qiita-image-store.s3.amazonaws.com/0/354659/0ac7497e-037c-034f-8f95-8478c691c0d5.png)
[Redux] Reducerでのstateの更新方法まとめ

#概要
今回はReducerでのstateの更新方法についてみていきます。
例えば配列のstateに要素を追加したい場合は

```javascript
const exampleReducer = (state = [], action) => {
  switch (action.type) {
    case 'EXAMPLE_ACTION':
      return [
        ...state,
        action.payload
      ];
    default:
      return state;
  }
};
```
上記のようなコードになると思います。
state.push(action.payload);のようにしてはいけません。
重要なのは更新の際、新たな配列を作るということです。
じゃあ削除は？入れ替えるのは？オブジェクトの場合は？と疑問になったのでそれらをまとめていきます。
#更新方法まとめ
先に配列の更新方法をみていきましょう。以下になります。

| 種類       |       bad!! |    good!!    |
|:---------:|:-----------:|:------------:|
| 削除       | state.pop() | state.filter(el => el　!==　'xxx')   |
| 追加       | state.push('xxx')| [...state, 'xxx']   |
| 入れ替え    | state[0] = 'y' |  state.map(el => el === 'y' ? 'xxx': el)       |

'xxx'にはそれぞれ削除したいもの、追加したいもの、入れ替えたいものが入ります。
次にオブジェクトの更新方法をみていきましょう。

|種類|bad!!|good!!|
|:-----:|:-------:|:-------:|
|削除|delete state.name|{...state, name: undefined}|
|追加|state.name = 'xxx'|{...state, name: 'xxx'}|
|入れ替え|state.age = 10| {...state, age: 10}|

オブジェクトの場合、追加と入れ替えは同じような書き方なります。
削除に関してはlodashを使って以下のように書くこともできます。

```javascript
_.omit(state, 'name')
```
lodashについてはまだあまり調べきれていないので別途記事にできればと思っています。
#まとめ
今回はReducerのstateの更新方法についてまとめました。
参考になれば幸いです。
pythonでjsonをtsvに




```python
import glob
import json

def listArray(key,arr):
	for a in arr:
		if type(a) is list:
			listArray(key, a)
		elif type(a) is dict:
			listDic(key, a)
		else:
			print(key, a)


def listDic(key,dic):
	for k,v in dic.items():
		if type(v) is list:
			listArray(key+"\t"+k, v)
		elif type(v) is dict:
			listDic(key+"\t"+k, v)
		else:
			print(key+"\t"+k, v)

for fpath in glob.glob("./*.json"):

	print(fpath)
	f=open(fpath, 'r')

	dic=json.load(f)

	for key,val in dic.items():

		if type(val) is list:
			listArray(key, val)
		elif type(val) is dict:
			listDic(key, val)
		else:
			print(key, val)
```

keyはスタックしていきます
【Pandas】Pandasをインポートする際のエラー対応

##はじめに
皆さん、こんにちは。[@Raphael_de_murl](https://twitter.com/Raphael_de_murl)です。今回の記事は理論的な情報共有よりはエラーメッセージの対応についてご紹介させて頂きたいと思います。

##どんなエラーなのか？
記事のタイトル通りPandasに関するエラー対応になります。機械学習を勉強している方なら一度はやる株価データの解析です。その中でPandasをインポートする際発生するエラーです。

```python:pandas_error
froma pandas.io.data import DataReader
```
このモジュールをインポートするとこういうエラーが出て来ます。

```python:error_messege
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-8-ddc8504c263b> in <module>
----> 1 from pandas.io.data import DataReader

ModuleNotFoundError: No module named 'pandas.io.data'
```

##エラーの原因
じゃあ、そもそも何が原因でこういうエラーが発生したのかを見てみましょう。
[pandas-datareaderドキュメント](https://pandas-datareader.readthedocs.io/en/latest/index.html)

>Starting in 0.19.0, pandas no longer supports pandas.io.data or pandas.io.wb, so you must replace your imports from pandas.io with those from pandas_datareader:

なるほど...以前までは<b>pandas.io</b>の名前でサポートしたんですが、pandasの0.19.0以降のバージョンではサポートが終了したんですね。その代わりに<b>pandas_datareader</b>というライブラリーをインストールすることで解決できるらしいです。やってみましょう。

##対応
エラーの原因が把握できたところで残りはそれの対応ですね。公式ドキュメントを見ながら対応して行きます。まず、pandas_datareaderのライブラリをインストールします。

```python:install
pip install pandas-datareader
#こちらはgithubからの最新バージョンのインストールです。
pip install git+https://github.com/pydata/pandas-datareader.git
```
インストールを完了したらインポートします。

```python:import
from pandas_datareader import DataReader
```
するとエラーは解決されたはずです。

##確認
エラーが出ないから問題が解決されたとは言い切れません。ちゃんとインポートされて使いたいライブラリーがちゃんと動くのかまで確認することがエンジニアの基本です。一つの例としていくつかの企業の情報を取得して行きたいと思います。ちなみにテスト環境はjupyter NoteBookです。

```python:sample
import pandas as pd
import numpy as np 
from pandas import Series, DataFrame
```
```python:sample
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
%matplotlib inline
```
```python:sample
from pandas_datareader import DataReader
from datetime import datetime
```
```python:sample
tech_list = ['AAPL', 'GOOG', 'MSFT', 'AMZN']
```
```python:sample
end = datetime.now()
start = datetime(end.year - 1, end.month, end.day)
```
```python:sample
for stock in tech_list:
    globals()[stock] = DataReader(stock, 'yahoo', start, end)
```
```python:sample
AAPL.describe()
```
ここまで入力して確認したら
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/ac3830ba-40c5-2b25-954f-f53df356ffdd.png)
こういう風にデータがちゃんと見えたら成功です。

##まとめに
エンジニアがエラーの解決がめんどくさいとかやりたくないというのはダメです。ちゃんと見て原因を把握して解決するのがかっこいいです！そうじゃないでしょうか？筆者はそう思います（笑）

↓筆者が運用しているツイッターでございます。興味ある方はぜひぜひフォロワーお願い致します。
[AI/機械学習のお兄ちゃんのツイッター](https://twitter.com/Raphael_de_murl)
analytics.jsからgtag.jsに移行したお話：クリックカウント編

###旧トラッキングコードとクリックカウント
```:旧トラッキングコード
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'GA_TRACKING_ID', 'auto');
ga('send', 'pageview');
</script>
```
```:旧クリックカウント
ga('send','event','カテゴリ','アクション','ラベル','値')
```

###新トラッキングコードとクリックカウント
```:新トラッキングコード
<!-- Global Site Tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'GA_TRACKING_ID');
</script>
```
```:新クリックカウント
gtag('event', 'アクション', {
  'event_category': 'カテゴリ',
  'event_label': 'ラベル',
  'value': '値'
});
```

新も旧もですが、値は任意でいいと思います。

####参考サイト
>・[gtag.js を使用してアナリティクスのトラッキングを設定する](https://support.google.com/analytics/answer/1008080?visit_id=636848487824787933-23349271&rd=1)
>・[Google アナリティクスのイベントをトラッキングする](https://developers.google.com/analytics/devguides/collection/gtagjs/events)
独自ドメインを取得し、メールアドレスを作成する

#目的
Route53で独自ドメインを取得し、独自のアドレスを作成する

なかなか自分の目的に対して何を使い、どんな環境で動かせばいいかわからず、作業に移れません、、、

WorkMailを活用すると簡単に、メールの送受信を行うことができるようになった。


WorkMail
参考[AWS WorkMailを使ってみたら想像以上に便利だった](https://qiita.com/ysKey2/items/2b019337772f8499beec)



alias 別名
GASを使ってGmailの内容をHangoutsChatに通知する

はじめに
----
メールに通知するよう設定していること多いですよね？
でも頻繁に確認していないし気づくのが遅くなってしまう…
ということでメールの内容をHangouts Chatに送るスクリプトを作成しました。
非常に簡単なものですし、汎用的なものになりますので色々応用できると思います。
今回はGsuiteアップデートブログを通知していきたいなと思います。

準備
----
・Gmail
・Hangouts Chat(以下チャット)
・Google Apps Script

webhookの設定
----
今回はwebhookという、何らかのイベントをきっかけにHTTPで通知する仕組みを使います。
通知を受けたいルームでwebhookの設定を開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/312018/240f55e9-4195-8a0d-b10f-e87a94b6d0a1.png)

webhookの追加をクリックして追加するwebhookの名前を入力します。
アバターのURLは省略可能なので今回は省略します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/312018/fe5a89d9-7bcf-d23f-14be-82513a6a5400.png)

新しいwebhookが追加されました。
後で使いますのでクリップボードにコピーしてどこかに張り付けておいてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/312018/b86cc22e-78c2-5f55-5a06-7aa499492aea.png)

これでチャット側の設定は完了です。

Google Apps Script
----
https://script.google.com/u/0/home/my
新しいプロジェクトを作成して下記スクリプトをはりつけてください。

```javascript

function gsuiteUpdateBlog() {
  //対象のメールの件名
  var subject = 'G Suite アップデート情報';
  var mailMax = 500;
  var chatMessage;
  var threads = GmailApp.search(subject, 0, mailMax);
  var messages = GmailApp.getMessagesForThreads(threads);
  
  var url = 'クリップボードにコピーしたwebhookのURL';
  
  for(var i = 0;i < threads.length; i++){
    for(var t = 0;t < messages[i].length; t++){
      //メール本文取得
      //chatMessageを加工してメール本文から一部を抜き出して通知することも可能
      //chatMessage = messages[i][t].getPlainBody();
      chatMessage = 'Gsuite アップデートブログが更新されたよ！';
      
      var botMessage = { 'text' : chatMessage}
      var options = {
        'method': 'POST',
        'headers' : {
          'Content-Type': 'application/json; charset=UTF-8'
        },
        'payload':JSON.stringify(botMessage)
      }
      var result = UrlFetchApp.fetch(url, options);
    }
    threads[i].moveToTrash();
  }
}
```
※最初に実行すると権限の承認やスコープの承認があると思いますがすべて承認して進めてください。

大まかな流れとしては、以下となります。

1．メールの件名で検索
2．スレッドごと、メールごとにループ
3．メールごとにチャット通知
4．スレッドを削除

今回のサンプルではメールの件数だけ「Gsuite アップデートブログが更新されたよ！」という通知が送信されるようにしておりますが、Gsuite アップデートブログの本文を取得すると一度のチャットの最大文字数を超えるため本文の内容は送りませんでした。すみません。

実際は本文中のURLやタイトル等を取得して送ることになるかと思います。```chatMessage = messages[i][t].getPlainBody();```chatMessageに本文が格納されていますので加工して使ってください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/312018/b70b2226-cbf3-fb99-6974-fa1ce18dc11b.png)
このように通知がきました。非常に簡単！

まとめ
----
Gsuiteってすばらしい。
Firebase Crashlyticsで.dSYMを手動アップロードする

## はじめに
Firebase CrashlyticsのiOS版では.dSYMをアップロードしていないとクラッシュログの内容を確認することができません。
自動アップロードしていればよいのですが、設定できていない場合の手動アップロードの仕方を説明します。

## 方法
.dSYMファイルを取得する方法はいくつかあるが、うまくいかなかったパターンもあるのでそのどちらも紹介しておきます。


### 失敗
Xcodeでプロジェクトを開く -> Window -> Organizer -> Archives -> 対象のデータを選択-> Show in Finder->対象の.xcarchive選択 -> パッケージの内容を表示-> dSYMsフォルダがあるのでこれをzipに圧縮してCrashlytics側にアップロード。

これがなぜかアップロードしても認識してくれない。

### 成功
App Store Connect -> マイ App -> アクティビティ -> すべてのビルド -> 対象のバージョンを選択 -> dSYM をダウンロード リンクを選択 -> ダウンロードしたappDsymsをzipに圧縮してCrashlytics側にアップロード。

無事認識してクラッシュログが表示される。
vscodeでanaconda+djangoのチュートリアル【覚え書き】

## 仮想環境について

- 仮想環境が必要な理由  
複数の環境を使い分けることで  
最小限のライブラリで開発環境をつくる（環境がきれい）  

1. 仮想環境の作成

~~~bash
conda create -n test-env
~~~

（ここでは仮想環境名をtest-envとしている）

2. 作成した仮想環境の確認

~~~bash
conda info -e
~~~

3. 仮想環境の起動と終了 

~~~bash
activate test-env
~~~

起動 

~~~bash
deactivate
~~~
 
終了

## 仮想環境下でdjangoのstartup

- 前提(作成した仮想環境下で作業)  

~~~bash
activate test-env
~~~

1. インストールしたいライブラリを検索 

~~~bash
conda search django
~~~

2. ライブラリが存在することが確認できたらインストールする 

~~~bash
conda install django
~~~

3. インストールされたライブラリのversion確認し、プロジェクトを開始 

~~~bash
python -m django --version
django-admin startproject mysite
~~~

4. プロジェクトフォルダに移動し、サーバー起動 

~~~bash
cd mysite
python manage.py runserver
~~~

5. ブラウザでアクセス
<http://127.0.0.1:8000/>にアクセス

6. アプリの作成

~~~bash
python manage.py startapp polls
~~~

7. 作成されたアプリのviewを編集する
<https://docs.djangoproject.com/ja/2.1/intro/tutorial01/>を確認

8. URLconfを編集
<https://docs.djangoproject.com/ja/2.1/intro/tutorial01/>を確認

9. サーバー起動し、ブラウザで確認

~~~bash
python manage.py runserver
~~~

<http://localhost:8000/polls/>にアクセスして確認

## メモ
- vscodeの拡張機能のpythonについて 
拡張機能のpythonのpyLintでimportのエラー 
vscodeの環境を確認する 
Ctrl + Shift + Pでpython:select interpreterを選択 
現在のactive仮想環境（test-env）を選択 

- プロジェクトとアプリの違い 
アプリ→Webアプリケーション 
プロジェクト→それぞれのアプリケーションをまとめたもの 

## 参考  
<https://docs.djangoproject.com/ja/2.1/intro/tutorial01/>
<https://code.visualstudio.com/docs/python/environments#_choosing-an-environment>
Asciinemaを試す


- [記事にAsciinemaを埋め込むことができるようになりました](https://blog.qiita.com/update-article-asciinema/)

というのを見たので、試してみる。

## 導入

- [Getting Started](https://docs.asciinema.org/getting-started/#__tabbed_1_4)

macOSではHomebrewでAsciinemaのクライアントが導入できる。

```shell
brew install asciinema
```

Asciinemaのアカウントを作成しなくても使えるが、クライアントとアカウントを関連づけていない場合は、アップロードした動画を管理できず、7日間で自動的にアーカイブされる。なのでアカウントを作成したほうが便利と思われる。

[アカウントを作成](https://asciinema.org/login/new)し、以下コマンドを実行して表示されるURLを開くことで、クライアントとアカウントが関連づけられる。

```
asciinema auth
```

## 使い方

```shell
asciinema rec
```

で録画を開始して終わったら`Crtl-D`で止める。

Qiitaへの埋め込みは録画された後に表示される`https://asciinema.org/a/hogehoge`のようなページを訪れ、Shareボタンを押して表示される「Embed the player」の内容をQiita記事内にコピペするだけ。「Make public」しなくとも、Privateのままでも表示される。

## 表示例

<script id="asciicast-Tsl5VfqCfSFnWqjTpKQJOFKys" src="https://asciinema.org/a/Tsl5VfqCfSFnWqjTpKQJOFKys.js" async></script>

## 感想

けっこう簡単なので、Qiita記事内で効果的そうなところではたまに使ってみてもいいかなと思いました。

## 参考

- https://asciinema.org/
- [Mac | asciinemaでターミナルの操作動画を記録・再生・シェアする (コピペも出来る)](https://qiita.com/YumaInaura/items/19afa1b504423bd859e6)
- [Asciinema の紹介](https://qiita.com/ka_/items/f1ebdde1e7fdf41c80a3)
MySQLのCSVデータをインポートできなかったが, 文字コードが原因だった.

こんにちは, 就職先でDBを扱うという事で,最近SQLを頑張ろうとしている者です.
(なお研究の進捗はひどい模様)

先日から始めている[勉強サイト](http://mysqlweb.net/category/4005373-1.html)の中で, 通し番号と都道府県の組のデータを読み込ませるものがあり, 
既存データを読み込ませる際に, 

```sql
ERROR 1366 (HY000): Incorrect integer value: '\FEFF1' for column 'pref_cd' at row 1
```

が発生してしまいました.

そこで, 現在のMySQLに於ける文字コードの設定？を確認してみたところ,

```sql
mysql> show variables like "chara%";
+--------------------------+---------------------------------------------------------+
| Variable_name            | Value                                                   |
+--------------------------+---------------------------------------------------------+
| character_set_client     | cp932                                                   |
| character_set_connection | cp932                                                   |
| character_set_database   | utf8mb4                                                 |
| character_set_filesystem | binary                                                  |
| character_set_results    | cp932                                                   |
| character_set_server     | utf8mb4                                                 |
| character_set_system     | utf8                                                    |
| character_sets_dir       | C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\ |
+--------------------------+---------------------------------------------------------+
```
となっています.

## 「FEFF」はBOMありのUTF-8に注目する

エラーコードの**「FEFF」**に注目すると,
これは, 文字コードの**UTF-8**というもの中でも**BOM**(Byte Order Mark)があるものです.

BOMとは, ファイルの先頭に付いている16ビットの値ということで, これによって**データがどの文字コードで書かれているかを識別する**役割をもっているようです.(違ってたらスミマセン！）

そこで, [utf8のことを検索したら似ているページ](https://qiita.com/YusukeHigaki/items/2cab311d2a559a543e3a)が出てきていて, そこで,

>character_set_system : システムの使用する文字セットで常にutf8が使用されている

と記載されて, MySQLではUTF-8(これはBOMなし)を利用しないとダメなんだ！という事が判明しました.
というわけで, 読み込むデータをUTF-8(BOMなし)にしていきます.

## じゃ, どうすればUTF-8(BOMなし)にできるの？
一番簡単な方法としては, TeraPadというものがオススメです.

こちらでは, 文字コードを選択して保存することができます.

逆にいうと, **windows標準のメモ帳は文字コードが選択できず, UTF-8(BOMあり)で保存していることになります(ここも間違ってたらスミマセン）**

という事で, [こちらのサイト](https://www.1-firststep.com/archives/2258)を参考にしながらメモ帳のデータを再保存しまして処理を行ったところ, 
エラーなしで処理が完了しました. めでたしめでたし！

## 備考

(本投稿は[teratailで筆者が質問した内容](https://teratail.com/questions/172553)をまとめています)

## 参考ページ
[mysqlで文字コードをutf8にセットする](https://qiita.com/YusukeHigaki/items/2cab311d2a559a543e3a)
[バイトオーダーマーク
](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF)
[UTF-8のBOMにはまった話
](https://qiita.com/MuriNishimori/items/a89fe986e28909208e30)