OmniAICreator/Qiita-1.07M huggingface dataset:
react-native-webviewの導入でつまづいたとこ

react-nativeのWebViewが使えなくなるらしいので、代わりにreact-native-webviewを使えということなので
react-native-webviewのWebViewを使おうとして詰まってしまったので解決策を個人的な備忘録で載せときます。

<h1>バージョン</h1>
・Windows10
・Node.js 11.9.0
・Android Studio 3.3
・react-native-cli 2.0.1
・react-native-webview 5.0.5

<h1>エラー内容</h1>
react-native-webviewを手順通りにインストールして、対象のプロジェクトをコンパイルしようとすると
コンパイルエラーが発生。
setting.gradleが何やら問題があるらしい。

下記にエラーログ抜粋

```
FAILURE: Build failed with an exception.

* Where:
Settings file 'C:¥Users¥(ユーザ名)¥Desktop¥dev¥(プロジェクト名)¥android¥settings.gradle' line: 3

* What went wrong:
Could not compile settings file 'C:¥Users¥(ユーザ名)¥Desktop¥dev¥(プロジェクト名)¥android¥settings.gradle'.
> startup failed:
  settings file 'C:¥Users¥(ユーザ名)¥Desktop¥dev¥(プロジェクト名)¥android¥settings.gradle': 3: unexpected char: '¥' @ line 3, column 117.
     e_modules¥react-native-webview¥android')

```

<h1>エラー原因</h1>
問題のsetting.gradleの中身

```setting.gradle
rootProject.name = 'web'
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '..¥node_modules¥react-native-webview¥android')

include ':app'
```
エラー原因はログに出力されている通りに「¥」が原因でした。
開くエディタによっては「¥」が自動で/に置き換わってたので質が悪い。

<h1>解決策</h1>
「¥」を「/」に置き換えてあげる。

<h1>感想</h1>
Visual Studio Codeで開くと「¥」が「/」に置き換わって表示されていた。
サクラエディタで開くと「¥」のまま出力されていた。
解決するのに結構時間かかりました。ご注意を。
あとほかの解決策知ってる人は教えてください。
OMRON MEMS非接触温度センサD6T-44L-06をM5Stackにつないで遊ぶ(データ取得まで)

#はじめに
オムロンの非接触温度センサD６T(とgrove変換基板)を手に入れたのでM5stackで遊ぼうと思いました。
[OMRON MEMS非接触温度センサD6T-44L-06](https://www.switch-science.com/catalog/1297/)
4×4で温度がわかるすごいやつ
![スクリーンショット 2019-02-06 18.45.32.png](https://qiita-image-store.s3.amazonaws.com/0/74404/026e6b7c-6d25-779d-ef6b-5427015bbffb.png)


#ハードウェアについて
GROVE対応の変換基板[(4×4非接触温度センサD6T 変換基板)](https://www.switch-science.com/catalog/5331/)があるのででM5stackにGROVE用のケーブル[GROVE - 4ピンケーブル 20cm (5本セット)](https://www.switch-science.com/catalog/798/)でつなぐだけで接続はOKです。カンタン！

#公式ライブラリ
GitHubに用意していただいています。スゴイ！
https://github.com/omron-devhub/d6t-grove-arduino
今回はArduino向けのライブラリを使用しました。

※ラズパイ向け(python)の[ライブラリ](https://github.com/omron-devhub/d6t-grove-raspberrypi)も用意していただいているので、M5Stackで開発するのであればMicroPythonを使えるようにしてこちらを使うことも可能です。(こちらの方がカンタンだったかもしれません)


#コーディング
M5StackをArduino IDEで使用するところまでは出来ている前提で書いていきます。
Qiitaにめちゃくちゃわかりやすい記事いっぱいあります。

###ライブラリをダウンロード
[GitHub](https://github.com/omron-devhub/d6t-grove-arduino)から公式ライブラリをcloneするなりZipでダウンロードするなりします。
(ダウンロードしたd6t-grove-arduinoというフォルダはArduino/librariesの中に置けばライブラリとして使用できるようになります。)

このままサンプルを使おうとすると**コンパイルエラー吐いた。**僕だけじゃないよね？

コンパイル出来た人はおめでとうございます。
**コンパイル出来なかった人は以下に対策書いてます。**
##Arduino向けの公式ライブラリをM5Stackに対応させる

###そのままだと上手くいかない理由

1. D6T-44L-06はI2C通信に35byte使う
1. ArduinoのI2C通信に使うライブラリ(Wire.h)は32byteまでしか対応していない(ESP32は128byteまでOK)
1. オムロンのライブラリはそれに対応するためのライブラリ(WireExt.h)が含まれている
1. しかし、そのライブラリ(WireExt.h)がESP32に対応していない
1. ライブラリの中で条件分岐で使わないようにしてるみたいだけど何故か反応してコンパイルに失敗する
1. 結果そのままでは使えない

###対応させた
(M5StackとArduinoのどちらでも使いたい場合はM5Stack用に編集したことがわかるように名前を変えておくと便利かもしれません。)

`d6t-grove-arduino`というフォルダの中の
`src`というフォルダにある`WireExt.h `と`WireExt.hcpp`を削除します。

![スクリーンショット 2019-02-06 20.25.57.png](https://qiita-image-store.s3.amazonaws.com/0/74404/4f6f17ca-2862-7b7a-acc6-9654b2076f89.png)

これでコンパイル通るようになるハズ。




#まとめ
動いた
![スクリーンショット 2019-02-06 21.17.46.png](https://qiita-image-store.s3.amazonaws.com/0/74404/a4df1c3f-a16c-cb8f-8401-1f4702e32e5e.png)
sampleはシリアルモニタで見れるハズ
これだとM5Stackでやる意味ないので**次回M5Stackの画面に色々表示する編**乞うご期待
Windows 10 Pro x64 + Excel2016 x86 VBA の Range.End プロパティ

#目的
コードで使用頻度は高いけど、全く覚えないのでメモっておく
##機能
・Range.End(xlDown).Row：下へ
・Range.End(xlUp).Row：上へ
・Range.End(xlToLeft).Row：左へ
・Range.End(xlToRight).Row：右へ
##サンプルコード
Worksheets("Sheet1").Range("B3:P8")にデータが存在する場合

```vb
With ThisWorkbook.Worksheets("Sheet1")
    Debug.Print .Range("B1").End(xlDown).Row
    Debug.Print .Range("B" & Rows.count).End(xlUp).Row
    Debug.Print .Range("A3").End(xlToLeft).Column
    Debug.Print .Range("B3").End(xlToRight).Column
End With
 3 
 8 
 1 
 16 
```
参考にしたのは以下のサイト
<a href="https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/range-end-property-excel">Range.End プロパティ (Excel)</a>
<a href="https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/xldirection-enumeration-excel">XlDirection 列挙 (Excel)</a>
VSCodeでTerraformを書くときの設定(2019/11/07追記: HCL2対応)

# 追記 :2019/11/07
ついにTerraform 0.12以降のHCL2に対応した模様です！

VSCodeのコンソールから
`terraform: install/update language server` -> 現在最新の `v0.0.9` を選択
`terraform: Enable/Disable Language Server` を実行
でHCL2記法の.tfファイルでもエラーが出なくなりました。
![スクリーンショット 2019-11-07 22.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174283/1a0d103b-c4b1-e0b7-c6d0-6771df86b510.png)

参照issue: [feat: Terraform 0.12 support (was hcl2 support) #157](https://github.com/mauve/vscode-terraform/issues/157)

# はじめに

VSCodeでTerraformを書くときに
最初にやっておいたほうが良いであろう設定を書いてみます。

環境

- macOS Mojave 10.14.1
- VSCode 1.30.2
- Terraform v0.11.11

# できること

全容はVSCodeの[Terraform Extensionのページ](https://marketplace.visualstudio.com/items?itemName=mauve.terraform)に書いてあるとおりです。

Extensionを素のままインストールするだけでも
シンタックスハイライトやオートコンプリートなどなど 一気に便利になりますが
他にも少し設定をいれることで

- linter([TFLint](https://github.com/wata727/tflint)による)
- ファイル保存時に自動でterraform fmtをかける

などが使えたりします。

# 設定

## ツールインストール
- [Terraform](https://marketplace.visualstudio.com/items?itemName=mauve.terraform) (VSCode Extension)
 - codeコマンドが使えないときはGUIで入れるか[こちらの記事](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)を参照してパスを通す
 
```
 $ code --install-extension mauve.terraform
```
- [TFLint](https://github.com/wata727/tflint)
  - Homebrewでインストール
  - ソースからビルドする方法もあり
 
```
$ brew tap wata727/tflint
$ brew install tflint
```


## 設定

素のままでもシンタックスハイライトなどは使えますが、以下設定を入れると吉

### オートfmt

↓ 例: 不要な改行やスペースをいれて、⌘Sで保存してみた図
![Feb-06-2019 21-15-49.gif](https://qiita-image-store.s3.amazonaws.com/0/174283/47b962d4-2568-53ea-aa4e-3bc324633869.gif)

ファイル保存時、自動で `terraform fmt` で整形してくれるパラメータです。
チェックで有効化されます。

- `editor.formatOnSave`

![スクリーンショット 2019-02-06 20.48.11.png](https://qiita-image-store.s3.amazonaws.com/0/174283/4d4136b4-acf9-6386-371a-9dd93a24cbd3.png)





### tflint

↓ 例: 3行目, 11文字目に余計な`=`がついているときの警告
![スクリーンショット 2019-02-06 21.02.13.png](https://qiita-image-store.s3.amazonaws.com/0/174283/2028b7cb-4432-6890-cbc1-57269b9af030.png)


文法エラーなどを検出してくれるtflintのパスを指定します。
（もともとログインシェルの方でパス通ってればコマンド書くだけでいいぽいです）

- `terraform.lintPath`
![スクリーンショット 2019-02-06 20.53.33.png](https://qiita-image-store.s3.amazonaws.com/0/174283/10e920eb-4557-92c3-8536-fc785044b2b3.png)

# おわりに

おすすめの設定があれば教えてください！
Medium #API で使えるトークンを設定する。サポートに問い合わせして有効化してもらった例。

MEdium #API で使えるトークンを設定する。サポートに問い合わせして有効化してもらった例。

# Settingsから取得可能

https://medium.com/me/settings

![image](https://user-images.githubusercontent.com/13635059/52331950-c00d1d00-2a3c-11e9-923d-22beb22ec3f0.png)

# 設定に表示されない？

Supportに問い合わせたら有効化してくれた。

![image](https://user-images.githubusercontent.com/13635059/52332059-02365e80-2a3d-11e9-857d-d1e21b65397b.png)

# Help

https://help.medium.com/hc/en-us/articles/213480768-Publishing-API

# 問い合わせ

https://help.medium.com/hc/en-us/requests/new

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Firestoreから取得した結果をKotlinオブジェクトに変換する方法

# モチベーション

1. Firestoreドキュメントからdata classのオブジェクトにしたい
1. Firestoreコレクションからdata classのリストにしたい

FirestoreのSDKとKotlinのdata classでハッピーになれます。

## まずはData Class

```kotlin
data class Book(
	val name: String,
	val isbn: String
)
```

こういう data class があったとして、

## コレクションからKotlinリストへ

```kotlin
val db = FirestoreClient.getFirestore()

val booksRef = db.collection("books")
val snapshot = booksRef.get().get()
val books = snapshot.toObjects(Book::class.java)
```

## ドキュメントからKotlinオブジェクトへ

```kotlin
val db = FirestoreClient.getFirestore()

val booksRef = db.collection("books").document("<BOOK_ID>")
val snapshot = booksRef.get().get()
val book = snapshot.toObject(Book::class.java)
```

やっぱり、Kotlinは気持ちいいですね
移動平均を求めるOracleのSQL

##移動平均を求めるOracleのSQL
時系列分析でよく使う移動平均について。

AVGの集計関数にOVER以下の分析関数コマンドを追加して求めます。
３日の移動平均の関数だとこちら。２日前のデータまで取ってきて平均値を求めています。

```SQL
AVG(数量) OVER(ORDER BY 日付 RANGE INTERVAL '2' DAY PRECEDING) 
```


ROW#の移動平均を求めるSQLはこのようになります。

```SQL
SELECT
  ROW_NUMBER AS ROW#
 ,ROW_DAY    AS DAY
 ,AVG(ROW_NUMBER) OVER(ORDER BY ROW_DAY  RANGE INTERVAL '2' DAY Preceding) AS "移動平均"
FROM
(
SELECT 
  ROWNUM            AS ROW_NUMBER
 ,SYSDATE + ROWNUM  AS ROW_DAY
FROM ALL_CATALOG WHERE ROWNUM <= 10
)
ORDER BY ROW_DAY DESC
```

上のSQLの実行結果。月単位のデータでしたら、DAYをMONTHに変えれば月の移動平均になります。

```DATA
ROW#	DAY	       移動平均
10	  2018-10-15	9
9	  2018-10-14	8
8	  2018-10-13	7
7	  2018-10-12	6
6	  2018-10-11	5
5	  2018-10-10	4
4	  2018-10-09	3
3	  2018-10-08	2
2	  2018-10-07	1.5
1	  2018-10-06	1
```
jsonの日本語文字化けを防いだ日【python】


<pre> hoge = json.dumps(fuga, ensure_ascii=False, indent=2)</pre>

##参考
[Python の json.dumps() で日本語が文字化けする場合のメモ]
(https://cortyuming.hateblo.jp/entry/20140920/p2)
[【python】Json書き込みで文字化けを防ぐ！]
(https://daily-fruit.com/programing/python/375/)

(https://pypython.hatenablog.com/entry/2018/08/01/044938)
MacTeX 2018 on Mojave でヒラギノ

備忘録。

## contrib レポジトリの追加

```
$ sudo tlmgr repository add http://contrib.texlive.info/current tlcontrib
$ sudo tlmgr pinning add tlcontrib '*'
```

## 必要なパッケージのインストール

```
$ sudo tlmgr install japanese-otf-nonfree japanese-otf-uptex-nonfree ptex-fontmaps-macos cjk-gs-integrate-macos
```

## cjk-gs-integrate

`cjkgs-morisawa-extra.dat` がないという Warning がでるが、これはミスで気にしなくていいらしい。

```
$ sudo cjk-gs-integrate --link-texmf --cleanup --force
cjk-gs-integrate: reading font database ...
cjk-gs-integrate [WARNING]: Cannot find cjkgs-morisawa-extra.dat, skipping!
cjk-gs-integrate: searching for Ghostscript resource
cjk-gs-integrate: going to clean up /usr/local/share/ghostscript/9.26/Resource
cjk-gs-integrate: cleaning up all links, snippets and cidfmap.local ...
cjk-gs-integrate: removing cidfmap.local from cidfmap file ...
cjk-gs-integrate: removing snippets and cidfmap.aliases for font aliases ...
cjk-gs-integrate: removing cidfmap.aliases from cidfmap file ...
cjk-gs-integrate: finished
```

High Sierra 未満の場合も、ディレクトリを掘れば必要な dat ファイルが出てくるので、それを使って実行する。

```
$ sudo cjk-gs-integrate --link-texmf --force --fontdef-add /usr/local/texlive/2018/texmf-dist/fonts/misc/cjk-gs-integrate-macos/cjkgs-macos-highsierra.dat
cjk-gs-integrate: reading font database ...
cjk-gs-integrate [WARNING]: Cannot find cjkgs-morisawa-extra.dat, skipping!
cjk-gs-integrate: checking for files ...
cjk-gs-integrate: searching for Ghostscript resource
cjk-gs-integrate: output is going to /usr/local/share/ghostscript/9.26/Resource
cjk-gs-integrate: generating links and snippets for CID fonts ...
cjk-gs-integrate: generating links, snippets and cidfmap.local for non-CID fonts ...
cjk-gs-integrate: adding cidfmap.local to cidfmap file ...
cjk-gs-integrate: cidfmap.local already loaded in /usr/local/share/ghostscript/9.26/Resource/Init/cidfmap, no changes
cjk-gs-integrate: generating snippets and cidfmap.aliases for font aliases ...
cjk-gs-integrate: adding cidfmap.aliases to cidfmap file ...
cjk-gs-integrate: cidfmap.aliases already loaded in /usr/local/share/ghostscript/9.26/Resource/Init/cidfmap, no changes
cjk-gs-integrate: finished
```

## mktexlsr

```
$ sudo mktexlsr
```

kpsewhich で処理系がヒラギノのファイルを見つけることができるかを確認できる。

```
$ kpsewhich HiraginoSerif.ttc
/usr/local/texlive/texmf-local/fonts/opentype/cjk-gs-integrate/HiraginoSerif.ttc
```

## kanji-config-updmap-sys

status コマンドで使える map ファイルを一覧で見ることができる。

```
$ sudo kanji-config-updmap-sys status
CURRENT family for ja: morisawa-pr6n
Standby family : hiragino-highsierra
Standby family : hiragino-highsierra-pron
Standby family : ipa
Standby family : ipaex
Standby family : toppanbunkyu-highsierra
```

```
$ sudo kanji-config-updmap-sys --jis2004 hiragino-highsierra-pron
```
Class 'App\Post' not found Laravelで作ったモデルクラスがないよと言われる

しょうもないミスで時間を使ってしまったので投稿。
ディレクトリModelsにモデルを作ったら当然ながらhasManyの引数にするときや、useするときにそのパスを書かないとクラスがないと言われる。

当たり前なんだけど、ドキュメントに載ってなくてそのままコピペでだめなケースもあるので手でコード書いていくって大切だと思う。

IDEを使うとuseのところとかうまく補完してくれそう。


```php
Class 'App\Post' not found
```

```php:app/Models/Post.php

class User extends Model
{
    /**
     * ユーザーの全ポストの取得
     */
    public function posts()
    {
        return $this->hasMany('App\Models\Post');
    }
}
```

```php:app/Http/Controllers/UserController.php

<?php

namespace App\Http\Controllers;

// 当然ながらここも
use App\Models\Post;

class UserController extends Controller
{
```

Laravel 5.7 Eloquent：リレーション
https://readouble.com/laravel/5.7/ja/eloquent-relationships.html#one-to-one
Python3 標準入力基本

備忘録的にpython3の標準入力をまとめてみました。



# 環境


virtualbox 5.2.26
vagrant 2.1.2
python 3.5.2
mac 10.14.2


## 1行取得
###文字列

```python:input.txt
string
```

```python:input.py
s = input()
```

```python:output.py
string
```



###数値

```python:input.txt
100
```

```python:input.py
n = int(input())
```

```python:output.py
100
```



###スペースで区切られた文字を文字列として

```python:input.txt
hage hoge hige
```

```python:input.py
s = input().rstrip().split()
```

```python:output.py
['hage', 'hoge', 'hige']
```



###スペースで区切られた文字を数値として

```python:input.txt
100 200 300
```

```python:input.py
n = list(map(int, input().rstrip().split()))
```

```python:output.py
[100, 200, 300]
```

###スペースで区切られた文字を数値に置き換え

```python:input.txt
5 1 2 1 A 3 A
```

```python:input.py
s = input().rstrip().split()
n = list(map(int, [i.replace('A', '5') for i in s]))
```

```python:output.py
[5, 1, 2, 1, 5, 3, 5]
```


## 複数行取得


###指定回数分の行を数値として

```python:input.txt
3
100 200 300
400 500 600
700 800 900
```

```python:input.py
n = int(input())
nums = [list(map(int, input().rstrip().split())) for i in range(n)]
```

```python:output.py
[[100, 200, 300,], [400, 500, 600], [700, 800, 900]]
```



###指定回数分の行を数値として（スペースで区切られたVer）

```python:input.txt
3 4 5
1 2 3
4 5 6
7 8 9
```

```python:input.py
Num, a, b = list(map(int, input().rstrip().split()))
res = [input().rstrip() for i in range(Num)]
```

```python:output.py
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
TensorFlowの高レベルAPIの使用方法：Kerasの使い方

TensorFlowのバージョンが2に上がった時に、これまで使っていたtf.layersがなくなるという予定を聞いた。ということで、別の高レベルAPIであるKerasを使ってみた。
tf.layersの記事は
「TensorFlowの高レベルAPIの使用方法：tf.layersの使い方と重みなどの取り出し方」
https://qiita.com/cometscome_phys/items/95ed1b89acc7829950dd
である。
この記事でやったことをKerasでもやってみる。

# バージョン
TensorFlow: 1.12.0
Keras: 2.1.6-tf

# 再現すべき関数
これは前と同じ。

```python:test.py
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

n = 10
x0 = np.linspace(-2.0, 2.0, n)
a0 = 3.0
a1 = 2.0
b0 = 1.0
y0 = np.zeros((n,1))
y0[:,0] = a0*x0+a1*x0**2 + b0 + 3*np.cos(20*x0)

plt.plot(x0,y0 )
plt.show()
plt.savefig("graph.png")
```

![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/246113/bb2c50d8-4795-0851-9644-8b8cb6c61694.png)

インプットは多項式であり、隠れ層が何もなければ多項式による線形回帰となる。インプットは

```python:test.py
def make_phi(x0,n,k):    
    phi = np.array([x0**j for j in range(k)])
    return phi.T
```
で定義しておく。

# モデルの構築
Kerasにはモデルの表記方法が二種類あり、Sequentialモデルとfunctional APIを使ったモデルがある。今後複雑なモデルを作ることを考えて、functional APIを使うこととする。
と言っても、tf.layersとか生のTensorFlowをいじったことがあるならば、functional APIは身構える必要はない。
モデルは、

```python:test.py
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import optimizers

def build_model(d_input,d_middle):
    inputs = tf.keras.Input(shape=(d_input,))  #インプットの次元を指定
    x = layers.Dense(d_middle, activation='relu')(inputs) #中間層の指定
    y = layers.Dense(1)(x) #最終層の指定
    adam = optimizers.Adam() #最適化にはAdamを使用
    model =  tf.keras.Model(inputs=inputs, outputs=y) #モデルのインプットとアウトプットを指定
    
    model.compile(optimizer=adam,
              loss='mean_squared_error') #modelの構築。平均二乗誤差をloss関数とした。
    
    return model
```
となる。
よって、

```python:test.py
k = 4
phi = make_phi(x0,n,k)
d_type = tf.float32
d_input = k
d_middle = 10
model = build_model(d_input,d_middle)
```
でmodelを作ることができる。

# 学習
学習はとても簡単で、

```python:test.py
history = model.fit(phi, y0, epochs=20000,verbose=0)
```
で良い。ここで、```verbose```を指定しないとログがepochごとに(20000個)出力される。

# 結果
結果を見るには、

```python:test.py
ytest = model.predict(phi)
```
で構築したモデルから出力されたyを作っておき、プロットすればよくて、

```python:test.py
plt.plot(x0,y0 )
plt.plot(x0,ytest,'o')
plt.show()
plt.savefig("graph.png")

plt.plot(history.history['loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train'], loc='upper left')
plt.show()
plt.savefig("train.png")
```
でグラフとlossを見ることができる。
結果は、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/246113/d8fe006a-3506-b12a-36b0-693dd92b6fc9.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/246113/4e2507df-c174-52d5-1f6b-e3020bada3cd.png)
となる。

# 学習したモデルの表示
モデルを表示するためには、

```python:test.py
model.summary()
model.get_weights()
```
とすれば、モデルの構造と、中身のWやbを見ることができる。
Polycom SoundPoint IP 331との戦の末に

戦の続き
---

[Polycom SoundPoint IP 331との戦は今も続いている](https://qiita.com/somainit/items/2f1d0d6f11829f266abf)の続編です。
前編ではPolycom SoundPoint IP 331の出荷時設定と最新バージョンアップができましたが、肝心のWebインターフェースが使えず途方に暮れました。
仕方がないのでひとまずIP電話機本体での設定を試みました。結果的にRasPBXだと発着信は問題なく使えるようになりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/781a48b6-32c4-a635-53b8-b898ffccc4c9.jpeg" width="70%">

戦術
---

####1.ネットワーク設定

|IPアドレス|192.168.3.100|
|:--:|:--:|
|**サブネット・マスク**|**255.255.255.0**|
|**ゲートウェイ・アドレス**|**192.168.3.1**|
|**DNSサーバ**|**192.168.3.1**|
|**SNTPサーバ**|**ntp.nict.jp**|
|**時差**|**+9時間**|


```text
Menu
　Settings
　　Advanced
　　　Admin Settings
　　　　Network Config
　　　　　Ethernet Menu
　　　　　　DHCP→【Disabled】→【Ok】
　　　　　　IP Address→【192.168.3.100】→【Ok】
　　　　　　SubnetMask→【255.255.255.0】→【Ok】
　　　　　　IP Gateway→ 192.168.3.1】→【Ok】
　　　　　DNS Server→【192.168.3.1】→【Ok】
　　　　　SNTP Addr→【ntp.nict.jp】→【Ok】
　　　　　GMT Offset→【9】→【Ok】
　　　　　Save Config?→【Yes】
```

####2.回線設定

|**RasPBX IPアドレス**|**192.168.3.11**|
|:--:|:--:|
|**RasPBX ポート番号**|**5060**|
|**内線番号**|**200**|
|**内線番号のパスワード**|**PASSWORD**|


```text
Menu
　Settings
　　Advanced
　　　Admin Settings
　　　　Line Configuration
　　　　　Line1
　　　　　　Display Name→【raspbx】→【Ok】
　　　　　　Address→【200@192.168.3.11】→【Ok】
　　　　　　Label→【200】→【Ok】
　　　　　　Server1
　　　　　　　Address→【192.168.3.11】→【Ok】
　　　　　　　Port→【5060】→【Ok】                                          
　　　　　　Authentication
　　　　　　　Domain→【192.168.3.11】→【Ok】
　　　　　　　User ID→【200】→【Ok】
　　　　　　　Password→【PASSWORD】→【Ok】
　　　　　Save Config?→【Yes】
```

####3.SIPサーバ設定

```text
Menu
　Settings
　　Advanced
　　　Admin Settings
　　　　SIP Server Config
　　　　　Server1
　　　　　　Address→【192.168.3.11】→【Ok】
　　　　　　Port→【5060】→【Ok】
　　　　　Save Config?→【Yes】
```

####4.再起動

```text
Menu
　Settings
　　Advanced
　　　Reboot Phone
　　　　Reboot Phone?→【Yes】
```

戦の末に
---

この後Webインターフェースはログインすらできなくなりましたが...^^;
[PowerApps Tip's]コンボボックスの初期値を操る際の注意点


前回”OData（odata.type）”を利用することで、PowerApps のコンボボックスへ初期値を設定する方法を紹介しました。詳細はこちら↓からご確認ください。

　■前回の記事
　　[コンボボックスの初期値を操る、たった2つの方法？](https://qiita.com/yamad365/items/74d44126cb53f5a7fdc1)

該当コントロールの［DefaultSelectedItems］プロパティへ下記のように指定することで初期値を設定しました。当方の周囲では所謂”おまじない”と呼ばれている方法です。

```DataCardVlue.DefaultSelectedItems

{    
'@odata.type':"#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference"
 ,Value: "※初期値にしたい値の文字列"
}
```

さて、前回のラストで引っ張ってしまった”おまじない”で注意しなければならないポイントとは？いったい何でしょう？

#結論
前述で示したJSonで書き換えるべき"※初期値にしたい値の文字列"に、データソースから生成されている**選択肢に存在しない値が設定できてしまいます。**そして、その状態では記事投稿時の仕様では PowerApps のアプリではエラーになりません。つまり、業務上では不正なデータをデータソース側（例えば SharePoint Online のリスト）へ書き込めてしまいます。

#現象の説明
どのような状況になるか？前回の記事で利用した SharePoint Online のリストと、そこから生成したアプリで検証してみましょう。

1. 選択肢に存在しない値を設定
![07.png](https://qiita-image-store.s3.amazonaws.com/0/215892/bbebaf9b-d1f6-912e-c106-27a0d5db9641.png)
存在しない値でも、コンボボックスに設定されてしまいます。

2. SharePoint Online リストと比較
![08.png](https://qiita-image-store.s3.amazonaws.com/0/215892/491dba46-ea89-b3a8-273b-6fb7fd771018.png)

3. アプリを起動してデータ登録
![10.gif](https://qiita-image-store.s3.amazonaws.com/0/215892/5e74aa22-e007-710a-30bf-059fbcf63d6d.gif)
上のイメージでもわかるように、PowerApps ではデータソース側の選択肢に存在しない値でもデータ登録できてしまいます。一覧表示、詳細表示、編集、全てエラーは発生しません。
そして、リストの該当アイテムも存在しない値で登録されてしまいます。ちなみに、このアイテムをSharePoint上で編集しようとすると、不正な値はブランクになります。

#まとめ
- OData を利用した”おまじない”は選択肢にない値も設定できてしまう
- 選択肢に存在しない値でも、PowerApps アプリとしては登録可能
    - データ登録時にエラーにならない、ということ
- データソース側でも、見かけ上はデータ登録されている
    - ただし、データソース側の仕組み（例えば、SPOのリスト機能）で編集する際どうなるか？はデータソース側に依存

おそらく、PowerApps 含めて”仕組み”としては問題無いデータなんでしょうね。なので、アプリケーションとデータソースとしてはエラーにならずに動作可能なのかと想定しております。（※公式な情報が無いため詳細は不明）
ただし、業務などの観点、つまり利用者からの視点からみると『意図しない値がデータソースに存在する』という状態になります。

この状態、気持ち悪いですよね？

PowerApps のアプリでデータ登録を実施し、データソース側にアイテムが登録されたら○○する、という Microsoft Flow が組んであったり、データソース側をそのまま何かに利用する、という状況を想像してください。

ね？気持ち悪いですよね・・・

と、いうことで”おまじない”を利用する際は、注意しましょう、というネタでした。

#おまけ：ドロップダウンの初期値を設定する方法
コンボボックスに初期値を設定する方法は説明しました。では、その兄弟というか、そっくりさんのドロップダウンに初期値を設定する方法は？

簡単です。［Default］プロパティにテキストを設定するだけです。
コンボボックスに初期値を設定する方法はテクニックが必要ですが、ドロップダウンは単純でわかりやすいですね。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/215892/7329b605-25fa-a097-63f2-631624c765f8.png)
それでは、皆さま、素晴らしい Power Platform Life を！
[fluentd]forest+rewrite_tag_filterでログ内容による動的なログ振分先指定を行う

# forest+rewrite_tag_filterでログ内容による動的なログ振分先指定を行う

---
### 概要
「forest」「rewrite_tag_filter」を組み合わせ、ログ中のメッセージ内容から動的にタグ名を変更し、タグごとのログファイルに振り分けする方法のメモ。
secureログ中のIPアドレスを拾い、IPアドレス別のログファイルに振り分けなおす例。

### 環境
```
・ OS:Red Hat Enterprise Linux Server release 7.6 (Maipo)
・ fluentd: v2.3.6
・ プラグイン: fluent-plugin-forest (0.3.3)
              fluent-plugin-rewrite-tag-filter (1.5.6)
```

---

### 設定
``` /etc/td-agent/td-agent.conf
<source>
  @type tail
  path /var/log/secure
  pos_file /var/tmp/secure.pos
  format /^.* ip-(?<ip>[\d]+-[\d]+-[\d]+-[\d]+) (?<message>.*)$/
  tag rewrite-test.host
</source>

<match rewrite-test.host>
  @type rewrite_tag_filter
  rewriterule1 ip ^(.*)$ host.$1
</match>

<match host.*>
  @type forest
  subtype file
  <template>
    path /var/log/message_${tag_parts[1]}
  </template>
</match>
```
---
### 解説
① \<source>
secureログ中のIPアドレスをkey「ip」に取得。tag名は「rewrite-test.host」とする。
② \<match rewrite-test.host>
tag「rewrite-test.host」のログに対してタグ名の動的書き換えを行う。
書き換え後のタグは「host.[ip]」とする。
③ \<match host.*>
tag「host.[ip]」のログに対し、forestの『tag_parts』プレースホルダーを使用して動的に書き出しパスを設定する。
vccwでWordPressを作ったら、記事インポートまで自動でやってしまおう！！

## vagrantによる環境共有時の問題点
git環境にvccwを含んだソースコードをコミットして、
gitから落としてきたソースコードをvagrant upしてローカル環境を作成している人も多いだろう。
だが、下記のようにREADME.mdなどに手動での環境作成の手順を記載しているケースが多くみられる。

> 3.vagrant upが完了したら、テーマを「original-theme」に切り替える
> 4.プラグイン「wordpress-importer」を有効化する
> 5.「import.xml」をインポートする

このように、vagrant up後の手順に手動でのテーマの切り替え、プラグインの有効化、記事のインポート含まれていて、完全に自動化されていないケースも多く見受けられる。

これらは「 provision-post.sh 」と「wp-cli」で解決することができる。

## provision-post.shとは
provision-post.shというファイル名で、Vagrantfileと同一階層にファイルを設置すると、
ファイルの中に書かれた処理を、初回のvagrant up後に実施してくれる。
この中に、環境作成後に手動でやっていた作業をシェルとして書いてしまえば、
もう手動で環境を設定する必要はない。

## wp-cliとは
wp-cliとは、WordPressの機能をコマンドライン側から実行するツールである。
テーマの切り替え、プラグインの有効化、記事のインポート、
他にもWordPressの管理画面側から行うような作業は一通りwp-cliからも実行ができる
ここでは、初期環境構築時に使いそうなコマンドに限って解説する。
### wp theme activate
テーマを有効化させる。初期インストール後は公式テーマが有効化されているので、
このコマンドを実行して自分の作成したテーマやインストールしたテーマに切り替える。
使用例：original-themeというテーマに切り替える
`wp theme activate original-theme`
### wp theme uninstall
テーマを削除する。
インストール直後のWordPressはデフォルトでテーマが追加されているため、
不要なテーマを削除する。
使用例：テーマ「twentyseventeen」を削除する
`wp theme uninstall twentyseventeen`
### wp plugin activate
プラグインの有効化を行う。
この後実施する記事のインポートに必要なwordpress-importerを有効化したり、
インポートする設定に紐づくプラグインをあらかじめ有効化しておく必要がある。
使用例：wordpress-importerを有効化する
`wp plugin activate wordpress-importer`
### wp plugin uninstall
プラグインを削除する。
インストール時、デフォルトで「Hello Dolly」がインストールされるため、
これを削除する設定を追加しておくとよい。
使用例：「Hello Dolly」を削除する
`wp plugin uninstall hello`
## wp import
WordPressへインポートを行う。
「wordpress-importer」のプラグインが有効化されている必要があるので注意。
管理画面の「ツール＞インポート」から行う作業と同じことができる。
「--authors=」オプションで、取り込んだ記事を所有者を変更できる。
存在しない所有者があったら作成する場合は「--authors=create」を指定する
使用例：Vagrantfileと同じ階層にある「import.xml」をインポートする。xmlに指定された所有者が存在しない場合は、所有者を作成する。
`wp import /vagrant/import.xml --authors=create`
##まとめ
上記で例示したコマンドをまとめて「provision-post.sh」に記載すると、下記のようになるだろう。
なお、シェルの中では#でコメントを入れることができる

```provision-post.sh
# original-themeを有効化し、不要なテーマを削除する
wp theme activate original-theme
wp theme uninstall twentyseventeen
wp theme uninstall twentysixteen
wp theme uninstall twentynineteen

# wordpress-importerを有効化し、不要なHello Dollyを削除する
wp plugin activate wordpress-importer
wp plugin uninstall hello

# import.xmlをインポートする
wp import /vagrant/import.xml --authors=create
```

こちらをベースに、自分のサイトに合わせて必要な処理を書き足していくとよいだろう。
SpringBootで国際化対応した際に特定ロケールが翻訳されずハマる

この記事は業務でSpringBootアプリケーションを国際化した際に、特定ロケールのメッセージプロパティファイルが認識されずハマった記録です。なお、SpringBootの詳細な説明はたくさんあるので省略します。

## 環境
- SpringBoot 1.5.19
- Java 1.8.0
- CentOS release 6.9 (Final)

## 前提条件
先方の要望でロケールの識別はURIに含めるケース（問題とは直接関係ないですがハマり街道の伏線なので）
**英語** : http://example.jp/en/foo
**韓国** : http://example.jp/ko/foo
**台湾** : http://example.jp/zh_tw/foo
etc...

## なぜ？
結論からいうと、`locale -a`で表示されるリストのロケール名をプロパティファイル名にする必要があるということです。前提条件で伏線としたURIの言語コード（小文字）をそのままファイル名に使ったことが問題でした。

誤 messages_**zh_tw**.properties
正 messages_**zh_TW**.properties

ローカル開発環境はmacでしたが、そこでは小文字でも問題なくファイルを認識していたんですね。何故macは問題なかったのかは[こちら](https://dev.classmethod.jp/etc/mac-apfs-ignore-case/)が参考になりました。

## 最後に
改めて記事にすると単なる凡ミスじゃーんという感じですが、解決にそこそこ時間を割いた問題でした。ニッチだと思いますがいつか誰かの助けになれば幸いです。
mysqlでJSONデータの一部削除(splice的なやつ)

# 概要
mysqlでJSON形式のデータの一部削除を行いたくなったのでちょっと調べてみました。
結論を先に書いておくと、現時点では削除したい要素が「文字列」の場合のみ下記のやり方でできます。
後、重複ない想定をしてます。複数ある場合は、複数回update文を流す必要しかないのか・・・な？

# やりかた
ObjectでもArrayでも操作は同じです。

## 検索値が文字列の場合
### Object
```sql
SET @json_data = '{ "hoge": "HOGE", "fuga": "FUGA"}';
-- valueとして"HOGE"を持つ要素を消したい場合
SELECT @json_data as before_removing, 
JSON_REMOVE(
  @json_data, 
-- JSON_UNQUOTEでJSON_SEARCHの結果を整形してJSON_REMOVEで使えるようにする
  JSON_UNQUOTE(
-- JSON_SEARCHで該当のデータのindexを取得
    JSON_SEARCH(@json_data, 'one', "HOGE") 
  )
) as after_removing;
```

##### 結果

|before_removing|after_removing|
|:---:|:---:|
|{ "hoge": "HOGE", "fuga": "FUGA"}|{"fuga": "FUGA"}|

### Array
```sql
SET @array_data = '["1", "2", "3"]';
-- "2"を消したい場合
SELECT @array_data as before_removing, 
JSON_REMOVE(
  @array_data, 
  JSON_UNQUOTE(
    JSON_SEARCH(@array_data, 'one', "2")
  )
) as after_removing;
```

##### 結果

|before_removing|after_removing|
|:---:|:---:|
|["1", "2", "3"]|["1", "3"]|

## 検索値が数値の場合

```sql
SET @array_data = '[1, 2, 3]';
-- 2を消したい場合
SELECT 
@array_data as before_removing, 
-- JSON_REMOVEの第2引数がnullの場合は、演算結果がnullになる
JSON_REMOVE(
  @array_data, 
  IFNULL(
    JSON_UNQUOTE(JSON_SEARCH(@array_data, 'one', 2)),
    CONCAT('$[', JSON_LENGTH( @array_data) + 1, ']') -- 検索結果が見つからない場合は、ありえない参照を渡す
  )
);
```

##### 結果
|before_removing|after_removing|
|:---:|:---:|
|[1, 2, 3]|[1, 2, 3]|

・・・消えないだと!!!

調べてみたら、[ここ](https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-search)に

```
JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
```

...search_strか。。。終わったorz
どうやら、JSON_SEARCHで検索できるのは文字列だけのようです。
[もしかしたらそのうちできるようになるかも](https://bugs.mysql.com/bug.php?id=90085)

# おわりに
JSONのデータをsqlだけでいい感じに削除したかったのだけれど、文字列の場合しかうまくいかなそうでした。
まあ、そもそもRDBでJSON使うのどうなの問題はありそう。
JSONを使ったほうがいい？ケースやアンチパターンがいまいちまだわからない。
GoogleAppsScriptでGoogleFormからアップロードされたファイルをあれこれする方法

# tl;dr

GoogleFormからアップロードされたファイルはGoogleDriveに管理されるが、そのファイルを使って添付メールを送るとか、何かしたいときの方法についてのメモ

# 通常のフォームの内容の受け取り方

まずは基本の受け取り方。

```javascript:コード.gs
function myFunction(e) {
  var responses = e.response.getItemResponses();
  var item;
  for (var i = 0; i < responses.length; i++) {
    item = responses[i];
    // 質問項目の取得 item.getItem().getTitle();
    // 質問の入力値   item.getResponse();
  }
}

```

のように取得できる。

# アップロードされたファイルで受け取ろうとすると...

```javascript:コード.gs
function myFunction(e) {
  var responses = e.response.getItemResponses();
  var item;
  for (var i = 0; i < responses.length; i++) {
    item = responses[i];
    console.log(item.getResponse());
  }
}
```

ログには

```
[1Sc2Ekxsep23l5Zdiu9z_2-QTxOe42Jku, 1Zy85-9jTm7wvM8OJF7fhh0aBs0B0hA_F]
```

のような配列が入ってきたりする。（ファイルが二個アップロードされた場合）

これらは、GooleDrive上にアップロードされたファイルで、`DriveApp.getFileById(id)` で取得できる。

# アップロードされた内容を区別する方法

```javascript:コード.gs
function myFunction(e) {
  var responses = e.response.getItemResponses();
  var item;
  for (var i = 0; i < responses.length; i++) {
    item = responses[i];
    console.log(item.getItem().getType());
  }
}
```

このように、getItem() して `Item` を取得し、`ItemType`からgetTypeすると、`FILE_UPLOAD` というコンソール出力を得る。

## しかし

https://developers.google.com/apps-script/reference/forms/item にあるように

```javascript
// Cast the generic item to the text-item class.
if (item.getType() == 'TEXT') {
  var textItem = item.asTextItem();
  textItem.setRequired(false);
}
```

なぜか `==で` 比較をしないと通らない様子。この item.getType() は typeof で調べると `object` のようだ。

`getType` で得られるのは、
https://developers.google.com/apps-script/reference/forms/item-type の `Enum ItemType` のようだが、ここには `FILE_UPLOAD` はない。`FormApp.ItemType.FILE_UPLOAD` も `undefined` になってしまう。

キャストして比較するしかないようだ。

# 結論

```javascript:コード.gs

function myFunction(e) {
  var responses = e.response.getItemResponses();
  var item;
  var files;
  for (var i = 0; i < responses.length; i++) {
    item = responses[i];    
    if (item.getItem().getType() == "FILE_UPLOAD") {
      files = item.getResponse();
      console.log(files);
      for (var j = 0; j < files.length; j++) {
          // files[j] を DriveApp.getFileById(files[j]); とかで処理すれば良い
      }
    }
  }
}
```

上記のようにしてアップロードされたファイルを取得するのがスジのようです。
就活の話とPaizaのSランクが全く意味なかったという話

記事は移動しました。
https://lanlib.com/2021/04/04/%e5%b0%b1%e6%b4%bb%e3%81%ae%e8%a9%b1%e3%81%a8paiza%e3%81%aes%e3%83%a9%e3%83%b3%e3%82%af%e3%81%8c%e5%85%a8%e3%81%8f%e6%84%8f%e5%91%b3%e3%81%aa%e3%81%8b%e3%81%a3%e3%81%9f%e3%81%a8%e3%81%84%e3%81%86/
Pentaho CE 8.2 (Pentaho Data Integration) インストール 備忘録

話題のBIだけどフリーで使えるのはなかなか無いので使ってみた。

##ダウンロード
https://sourceforge.net/projects/pentaho/

##オフィシャルインストールコメント
https://community.hitachivantara.com/docs/DOC-1009855-data-integration-kettle
>After unzipping the downloaded file, you can launch Spoon by navigating to the >folder /data-integration and double clicking Spoon.bat

##インストール
ダウンロードしたpdi-ce-8.2.0.0-342.zipを展開して
お好きな場所にフォルダを作って移動させる
今回は
C:\HitachiVantaraPendaho
に置いた
C:\HitachiVantaraPendaho\pdi-ce-8.2.0.0-342\data-integration
にあるSpoon.batをダブルクリックで起動するらしい

##環境について
###windows
Windows10 Pro 64bit
  バージョン 1803
###Java
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)  

##インストール後の手作業
###彩を添える
　せっかくなのでSpoon.batのショートカットを作成してデスクトップに置いた後、spoon.icoを指定した
![spoon.png](https://qiita-image-store.s3.amazonaws.com/0/345260/6f67a6fe-39b4-9dce-cd6a-b093a0afae66.png)

##まるで動いてないんじゃないかと誤解させられる
直接コマンドプロンプトで実行してエラーログっぽいものを確認

```cmd:紛らわしいメッセージ
C:\HitachiVantaraPendaho\pdi-ce-8.2.0.0-342\data-integration>Spoon.bat
WARNING: Using java from path
DEBUG: _PENTAHO_JAVA_HOME=
DEBUG: _PENTAHO_JAVA=javaw.exe
指定されたパスが見つかりません。
指定されたパスが見つかりません。
```
フォーラムを見ると定期的に動かないぞって報告される案件？。
どう見てもPENTAHO_JAVA_HOMEの設定に失敗していると思われがち。
このコマンドプロンプトが一瞬映って消えたら20秒待つ。

**待って下の画像が出てきたらさらに辛抱強く待つこと。**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/e39cf7a0-a6e8-4442-6ab6-d0df992b8e80.png)

せっかちな私はクリック連打して応答が無いって出て使えないと感じてしまったが
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/059555b8-a8ef-8262-4249-104c785ba1cc.png)

ほっといたらちゃんと動いた。起動が重いんだね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/02998a2d-2fa7-2fca-b4d5-43a6ea179f69.png)
バックグラウンド処理で初期化するとJavaの応答が無いとか言われないようにできるのかもしれないが
Javaはよくわからないのでごめんなさい。コミュニティに貢献はできそうにないです。
DataFrame API で、１つColumnを３つに分割するScalaコード

```scala
val viewsDF=spark.read.text("spark-labs/data/wiki-pageviews.txt")

val splitedViewsDF = viewsDF.withColumn("col1", split($"value", "\\s+").getItem(0)).withColumn("col2", split($"value", "\\s+").getItem(1)).withColumn("col3", split($"value", "\\s+").getItem(2))

splitedViewsDF.show
```

## Test

```scale
val viewsDF=spark.read.text("spark-labs/data/wiki-pageviews.txt")
viewsDF.printSchema
viewsDF.limit(5).show
val splitedViewsDF = viewsDF.withColumn("col1", split($"value", "\\s+").getItem(0)).withColumn("col2", split($"value", "\\s+").getItem(1)).withColumn("col3", split($"value", "\\s+").getItem(2)).drop($"value")

splitedViewsDF.printSchema
splitedViewsDF.limit(5).show
```

```scale
scala> val viewsDF=spark.read.text("spark-labs/data/wiki-pageviews.txt")
viewsDF: org.apache.spark.sql.DataFrame = [value: string]

scala> viewsDF.printSchema
root
 |-- value: string (nullable = true)


scala> viewsDF.limit(5).show
+------------------+
|             value|
+------------------+
|  aa Main_Page 3 0|
|  aa Main_page 1 0|
|  aa User:Savh 1 0|
|  aa Wikipedia 1 0|
|aa.b User:Savh 1 0|
+------------------+


scala> val splitedViewsDF = viewsDF.withColumn("col1", split($"value", "\\s+").getItem(0)).withColumn("col2", split($"value", "\\s+").getItem(1)).withColumn("col3", split($"value", "\\s+").getItem(2)).drop($"value")
splitedViewsDF: org.apache.spark.sql.DataFrame = [col1: string, col2: string ... 1 more field]

scala>

scala> splitedViewsDF.printSchema
root
 |-- col1: string (nullable = true)
 |-- col2: string (nullable = true)
 |-- col3: string (nullable = true)


scala> splitedViewsDF.limit(5).show
+----+---------+----+
|col1|     col2|col3|
+----+---------+----+
|  aa|Main_Page|   3|
|  aa|Main_page|   1|
|  aa|User:Savh|   1|
|  aa|Wikipedia|   1|
|aa.b|User:Savh|   1|
+----+---------+----+


scala>
```
XCodeでカバレッジ取得対象をアプリ本体のソースファイルのみにする

XCodeでカバレッジレポートを表示するには、以下の手順でカバレッジの取得を有効にします。

1. XCodeメニューから Product > Scheme > Edit Scheme... でScheme編集画面を開く
2. 画面左でTestアクションを選択する
3. Optionsタブ内のCode Coverageにチェックを入れる

![スクリーンショット_2019_02_06_9_09.png](https://qiita-image-store.s3.amazonaws.com/0/81715/4e0809fc-69b5-671d-d36c-07f8527d1e56.png)

これでテストを実行すると、カバレッジレポートを見ることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/9b07ebe7-7ce5-3436-1574-012c36152bd3.png)

## カバレッジの取得対象をアプリ本体に絞る
現状だと他のフレームワークのカバレッジも表示されてしまっているので、アプリ本体のソースファイルだけに絞ります。

先述の手順でScheme編集画面を開き、カバレッジの取得対象を`all targets`から`some targets`に変更し、アプリのターゲットを指定します。

![スクリーンショット_2019_02_06_9_20.png](https://qiita-image-store.s3.amazonaws.com/0/81715/6e241329-986c-63b1-15dd-eb89391667f2.png)

これでテストを実行すると、カバレッジレポートにアプリ本体のソースファイルのみが表示されるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/06d072f6-cded-d503-65f0-d104cbbe214c.png)

## [CocoaPods] Objective-Cベースのライブラリを除外する
カバレッジレポートにアプリ本体のソースファイルのみが表示されるようになりましたが、下図のように`FIREmailAuthProvider.m`などのライブラリのソースファイルもカバレッジ取得の対象となってしまっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/ea5c0719-77a3-8e8f-414e-c5fa1a2b23f9.png)

`Podfile`に以下を追記することで、これらを除外することができます。

```ruby
post_install do |installer_representation|
  installer_representation.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['CLANG_ENABLE_CODE_COVERAGE'] = 'NO'
    end
  end
end
```

これでアプリ本体のソースファイルのみがカバレッジ取得の対象となりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/22d1369f-d7c7-0242-294a-f31a1d40f246.png)

## 参考
- [How to exclude third party pods libraries from XCode UI test coverage report
](https://stackoverflow.com/questions/37569806/how-to-exclude-third-party-pods-libraries-from-xcode-ui-test-coverage-report)
vueでpugでslotメモ


# サイドバーなslotへユーザ一覧画面へのリンクをぶっ刺す

## ぶっ刺す方
```.pug
a(href="/users" slot='sidebar')
    span ユーザ一覧
```

## ぶっ刺される方
```.pug
.parent
  // サイドバー
  slot(name='sidebar')
```

## そして置き換わる
```.html
<div data-v-33d5dc43="" class="parent">
    <a data-v-162e1d05="" href="#/users" class="" data-v-33d5dc43="">
        <span data-v-162e1d05="">ユーザ一覧</span>
    </a>
</div>
```
InteliJでScalaの外部ライブラリを使う

#はじめに
Scalaを勉強し始めたので、学んだ内容を整理していきます。

InteliJでScalaの外部ライブラリの使い方が分からず、時間がかかったので備忘。

#作業手順
###1. `Ctrl+Shift+Alt+S` を押してProject Structureウィンドウを開く
###2. Librariesから `+`→`From Maven...`を選択する
![fromMaven.png](https://qiita-image-store.s3.amazonaws.com/0/308224/6776a036-2760-5a92-dafa-ccd534de229a.png)


###3. 任意のライブラリを検索して、`OK`をクリック
オンライン上から対象を検索するのに、時間がかかる様子。
少し待っていると候補がリストアップされます。
![libraries.png](https://qiita-image-store.s3.amazonaws.com/0/308224/9211809c-fc83-3362-effa-491ed133e99c.png)

[Maven Repository: Search/Browse/Explore](https://mvnrepository.com/)より利用可能なライブラリを検索可能。

#参考資料
[ライブラリを使って作業する - 公式ヘルプ | IntelliJ IDEA](https://pleiades.io/help/idea/library.html)
Python + Selenium + ChromeでWebスクレイピングをやってみる

Python + Selenium + Chromeを使ったスクレイピングのチュートリアルです。

## スクレイピングとは

プログラミングを駆使してWebページから情報を集めることを言います。
クラウドワークスなんかを見ていると、需要がちらほらある割に情報が少ないプチマニアックな分野です。

## なぜSeleniumが必要か

SeleniumはWebページの自動テスト等に使われているブラウザ自動化ツールです。

昨今のWebページはメインコンテンツをAjaxで取得しているケースが多々あるので、URLを叩くだけでは望む情報が取れなかったりします。
なので、普段閲覧している様に**ブラウザ上でJavaScriptを評価して出来上がったHTMLから情報を抜き出す必要があります。**
そのためにSeleniumを使ってブラウザをプログラムで操作してしまおう、ということです。

ちなみに、ブラウザを使用せずにスクレイピングしよう、もしくはヘッドレス(画面を描写しない)ブラウザを作ってスクレイピングしようという動きもちらほらあるのですが、大体の場合どツボにハマる事になります**(経験談)**

## 環境

Seleniumはあくまでブラウザ自動化ツールなので、ブラウザ本体とブラウザをつなぐもの(WebDriverといいます)が必要です。
今回はGoogle Chromeを使います。

- Mac: 10.14.2 
- Chrome: 71.0.3578.98
- Python: 3.7.1
- Selenium: 3.141.0
- chromedriver-binary: 2.46.0

## インストール

```bash
$ pip install selenium
$ pip install chromedriver-binary
```

## 実行

Googleのトップページからaタグを抜き出し、そのURLを抽出してみます。


```python
import time
import traceback
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary


options = Options()
# ヘッドレスモードで実行する場合
# options.add_argument("--headless")
driver = webdriver.Chrome(options=options)

try:
    driver.get("https://www.google.co.jp/")
    # 簡易的にJSが評価されるまで秒数で待つ
    time.sleep(5)

    # aタグを抽出
    elem_list = driver.find_elements_by_tag_name("a")
    for elem in elem_list:
        # attributeの中からhrefを抽出して出力
        url = elem.get_attribute("href")
        print(url)
except:
    traceback.print_exc()
finally:
    # エラーが起きても起きなくてもブラウザを閉じる
    driver.quit()

```

要素の抽出には`driver.find_elements_by_tag_name()`を使用していますが、クラス名、nameなど、抽出の仕方は柔軟に選べます。Docsを見て下さい。
https://selenium-python.readthedocs.io/locating-elements.html

※Chromeのパスはchromedriver-binaryが勝手に通してくれます。

## 結果

URLがずらっと出力されます。

```
https://mail.google.com/mail/?tab=wm
https://www.google.co.jp/imghp?hl=ja&tab=wi
https://www.google.co.jp/intl/ja/about/products?tab=wh
https://myaccount.google.com/?utm_source=OGB&tab=wk&utm_medium=app
https://www.google.co.jp/webhp?tab=ww
https://maps.google.co.jp/maps?hl=ja&tab=wl
https://www.youtube.com/?gl=JP
https://play.google.com/?hl=ja&tab=w8
https://news.google.co.jp/nwshp?hl=ja&tab=wn
https://mail.google.com/mail/?tab=wm
https://contacts.google.com/?hl=ja&tab=wC
https://drive.google.com/?tab=wo
.
.
.

```

## まとめ

簡単にWebスクレイピングが出来た。

応用として、ページ上でJSを実行したりクリックイベントを発火させたりして例えばログイン後のページの情報を取得したり、フォームにデータを入力してテーブルのフィルター、ソートを行うことも出来ます。
が、**サイトによってはかなりハマるので注意して下さい。(特にAngularを使っているサイト)**

ハマった場合はヘッドレスモードをやめて、デベロッパーツールを見てなぜ処理がうまくいかなかったのか調べてみて下さい。
vue+typescript+vscodeで「Experimental support for decorators…」のエラーを直す


## TL;DR

```tsconfig.json
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

```

ワークスペースのトップディレクトリに上記のファイルを追加しvscodeを再起動する。



## 原因

vue+typescriptで開発していると以下のようなエラーが発生する時があります。

<img width="682" alt="0206.png" src="https://qiita-image-store.s3.amazonaws.com/0/137148/b6b62612-42db-2225-be2a-ef9ba7a52ef6.png">


発生するとしないときがあり、鬱陶しかったので調べたところ、**ワークスペースのトップディレクトリ**のtsconfig.jsonの`compilerOptions.experimentalDecorators`がtrueではないことが原因らしいです。

vue-cliではなく、parcelで開発していても発生するかもしれません。(tsconfig.jsonが自動生成されないため)

## 参考

- [vue.js - TypeScript、Vue、experimentalDecorators - スタックオーバーフロー](https://stackoverflow.com/questions/50782749/typescript-vue-and-experimentaldecorators)
Rspec3でインスタンスメソッドの呼び出しをテストする

# はじめに
インスタンスメソッドがcontroller内で呼び出しているのかを確認するときに通常のallow, have_received形式の書き方で動かなかったのでメモです。

# 環境
ruby '2.5.1'
rails '5.2.1'
rspec-core '3.8.0'

# コード

## これでいけるだろうと思ってた書き方

```posts/publishes_controller.rb
class Posts::PublishesController < AdminController
  before_action :set_post

  def create
    @post.publish!
    redirect_to post_path(@post), notice: "記事を公開しました"
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end
```

```posts/publishes_spec.rb
RSpec.describe "Posts::Publishes", type: :request do
  describe 'POST create' do
    let!(:post) { create(:post) }
    let(:path) { post_publishes_path(ticket) }

    it 'calls post.publish! and redirect_to post_path' do
      allow(post).to receive(:publish!) { true }
      post path
      expect(post).to have_received(:publish!).once
    end
  end
end
```


## 実際に動いた書き方

```posts/publishes_controller.rb
class Posts::PublishesController < AdminController
  def create
    post.give_participation_award!
    redirect_to post_path(post), notice: "記事を公開しました"
  end

  private

  def post
    @_post ||= Post.find(params[:id])
  end
end
```

```posts/publishes_spec.rb
RSpec.describe "Posts::Publishes", type: :request do
  describe 'POST create' do
    let!(:post) { create(:post) }
    let(:path) { post_publishes_path(ticket) }

    it 'calls post.publish! and redirect_to post_path' do
      allow_any_instance_of(Post::PublishesController).to receive(:publish!) { true }
      post path
      expect(post).to have_received(:publish!).once
    end
  end
end
```

# 参考

[rspec3でメソッドが呼び出されたかテストする](https://qiita.com/_am_/items/398b0782fa3754ff3878)

[RSpecでメソッドを通るかどうかを確認する
](http://konifar.com/1224)
※ こちらに関してはそもそも古い記事なのでバージョンなどが違うかと思います。
ニューラルネットワークっぽい図を描いてくれるウェブサービス

`NN-SVG`というのがある。
http://alexlenail.me/NN-SVG/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103491/89520f08-d52d-a0c1-7cd1-db68b5e49063.png)

（いつも忘れるのでメモ）
Use php70 instead of deprecated homebrew/php/php70 になった場合


Mac OS(High Sierra)で、ターミナル起動時にWarningが出てしまっていた。

brew doctorで無効になったLink等を解決していたら発生。
直接の原因は不明だが、php@7.0をInstallし直せ、というエラーを解消した際に発生した様子。

bash_profile に phpのPathを指定していたので、
これを削除して解決。

Install時に上手くやってくれるようになったんだ！と思う。
Python concurrent.futuresのスレッド内の例外


「スレッドがなぜか止まる」
しかも、Tracebackの表示もされない。
何か問題が起きているはずなのに、場所がわからない。
そんな経験はないでしょうか。

スレッド内の処理で例外が起きても既存の手段では拾えません。
正しい手続きで、例外を掬い上げる必要があります。

今回はpythonのconcurrent.futures.ThreadPoolExecutorについて記します。

下記は結果を戻さないルーチン。
```func1```を１秒ごとに表示します。
動かす分には問題ありません。


```python:concurrent_test.py
import concurrent.futures
import time

def func1():
    while True:
        print("func1")
        time.sleep(1)


if __name__ == "__main__":
    executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
    func1_future = executor.submit(func1)

```
もし、func1()の中で例外が起きたらどうなるでしょうか。
意図的にraiseを置いてみます。

```python:concurrent_test.py
def func1():
    while True:
        print("func1")
        raise Exception('dummy1')  ## New !
        time.sleep(1)
```

この場合、```func1```を一回出力するのみで停止します。
例外で停止しているにも関わらずTracebackなど、何も表示されません。
実行結果からは**どこで止まっているか窺い知れない**のです。
ではどうするのか。

**future.result()**を使います。
future.result()はスレッド内の処理の戻り値を得るためのものですが、
func1()に対して使ってみましょう。

```python:concurrent_test.py
if __name__ == "__main__":
    executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
    func1_future = executor.submit(func1)
    func1_future.result()  ## New!!
```

実行結果

```
func1
Traceback (most recent call last):
File "concurrent_test.py", line 34, in <module>
func1_future.result()
File "/Users/mms/.pyenv/versions/3.4.2/lib/python3.4/concurrent/futures/_base.py", line 402, in result
return self.__get_result()
File "/Users/mms/.pyenv/versions/3.4.2/lib/python3.4/concurrent/futures/_base.py", line 354, in __get_result
raise self._exception
File "/Users/mms/.pyenv/versions/3.4.2/lib/python3.4/concurrent/futures/thread.py", line 54, in run
result = self.fn(*self.args, **self.kwargs)
File "concurrent_test.py", line 7, in func1
raise Exception('dummy1')
Exception: dummy1
```

無事、```Exception: dummy1```の情報を得ることが出来ました。
future.result()がException('dummy1')のraise を肩代わりするからです。
※他、future.exception()を利用する事でも例外の情報が得られます。この場合raiseではなくexception()の戻り値として渡されます。


### まとめ
戻り値として結果を求めない処理等は、future.result()を省かれるかもしれません。
future.result()かfuture.exception()を置く事で、例外を得る事が出来ます。
Page Builder by SiteOriginの設定方法

WordPressでトップページをかっこよく作りたいと思い、色々と調べていました。
そして、Page Builder by SiteOriginというプラグインを知りました。
一応日本語化できる方法もありますが、完全には翻訳できないそうです。
私は、日本語化出来ることを知らなかったので、そのまま使っています。

このPage Builder by SiteOriginは、簡単にレイアウトを設定できて、ウィジットも設置出来ます。
また、ひな形となるテンプレートも多数ありますので、デザインに悩んだら参考にすることもできます。

私は、Simplicity2というテンプレートを使っているため、そのままPage Builder by SiteOriginでページを作ろうとすると、Page Builder by SiteOriginのテンプレートがはみ出してしまい大変なことになってしまいます。
そのため、Layoutsでテンプレートを挿入するのではなく、列を設定してウィジットを設置していく方法で行いました。

![キャプチャ.PNG0206-5.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/e30910a2-64cf-ea53-2960-e8f78d5888ae.png)

今回は、画像にあるウィジットSiteOrigin Heroの設定方法をご紹介します。

ウィジットSiteOrigin Heroを設置して、右上のあたりにマウスのポインタを合わせてると、修正、削除といった項目が表示されます。
この修正をクリックします。
![キャプチャ.PNG0206-6.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/95b91000-15cc-0800-c57c-47def33e4f09.png)

画像のframeの右の下三角をクリックすると、文字を入力出来るエディタが出てきます。
![キャプチャ.PNG0206-1.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/10f48f2f-6cd6-bdee-9446-33ab09bfc477.png)

このような形で、文字を入力します。

![キャプチャ.PNG0206-2.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/6577e0dc-74dc-6239-18eb-fe1b71db6352.png)

このエディタをしたスクロールすると、このようにバックグラウンドの画像や色を設定できる項目が出てきます。
ここで、背景画像を設定します。
この画像では、ビットコインの画像がセットされています。
画像の横のChooseをクリックすると、WordPressのメディアにアクセスできます。
ここで登録されている画像を使ったり、画像をアップロードして設定することが出来ます。

![キャプチャ.PNG0206-3.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/2831a4fc-db8f-5637-8411-1ea70bf7fb95.png)

このあたりの設定をさわると、文字の影を設定できるようです。
影の設定を調整すると、文字を立体的に表示できます。

![キャプチャ.PNG0206-4.PNG](https://qiita-image-store.s3.amazonaws.com/0/20977/80d844a3-2132-a8f7-ab07-01e54a478497.png)

これが、今回の設定でプレビューした結果です。
簡単に、背景画像に文字を挿入することが出来ます。

この他にも、色々とウィジットがあるので、これからも色々と試していきたいと思っています。
AWS Transfer for SFTPを使ってみる

SFTPというレガシーだけど、今もよくシステムで使われる名前のついたサービスが目に止まったので、検証してみました。
発表されたサービス名はAWS Transfer for SFTP
terraformがこのサービスに対応してなかった（当たり前か^^;）ので、渋々マネコンでポチポチしました...

### 手順
#### SFTP Serverの作成
- `Custom hostname`に`Amazon Route53 DNS alias`を選択し、管理しているドメインを記述するとRoute53に自動定義されるようです。
- LDAP及びActiveDirectoryをAPIGateway経由で利用できるようです。
- タグも利用できるので、コストを任意の決済グループに紐付けることが可能ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/58788/91923ea8-48ca-1254-2551-4a7ef1adff06.png)


- ユーザ作成画面では接続に用いる任意のpublic-keyを貼り付けて、ユーザのホームディレクトリになるS3bucketを記述します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/58788/5af553e1-846c-f107-7fbc-e94919fc8ae3.png)

- Done
![image.png](https://qiita-image-store.s3.amazonaws.com/0/58788/f28701ec-ac97-231b-9e61-8e05565b77dc.png)


#### 接続確認
- レコードが定義されているか確認する

```sh
$ aws route53 list-resource-record-sets --hosted-zone-id xxxxxxxxxxxx  | jq '.ResourceRecordSets[].Name' | grep "xxxxxx"
"xxxxxx.org."
```

- 接続してみる

```sh
$ sftp -i ~/.ssh/transfer-key kazu@xxxxxxx.org
Connected to xxxxxxx.org.
sftp> ls -l
-rwxr--r--   1        -        -   test
sftp>
```

#### 料金
- EC2インスタンスが起動しているし、何よりもフルマネージドなので、それを考えたら妥当な価格かも。

| Pricing by region | Pricing is the same across all AWS regions where AWS SFTP is available |
|:-----------:|:------------:|
| Time your SFTP endpoint is provisioned | $0.30 per hour |
| SFTP data uploads and downloads | $0.04 per gigabyte (GB) transferred |

- 1GB使用の想定で24時間30日稼働させたとして...$228

<i>$0.30 * 24 hours * 30 days = $216</i>

<i>$0.04 * 1 GB * 30 days = $12</i>

<i>$216 + $12 = $228.</i>