OmniAICreator/Qiita-1.07M huggingface dataset:
Firebase Crashlyticsの導入

## 思ったこと
- Firebaseのドキュメントが古かった。
    - https://firebase.google.com/docs/crashlytics/get-started?hl=ja
    - 最初にみたドキュメントが古くて、同じことを2回やる羽目に
- Xcodegenの対応
    - XcodegenだとprebuildScriptsのscriptがcocoapodsのスクリプトよりも前に呼ばれて、エラーが出る問題
    - https://qiita.com/gin0606/items/3935027fef9597ddf6e7
    - W/A的に対応したけど、もっといい方法がありそう。。。


## ドキュメント
- 一番新しいやつスタートガイドライン
    - https://firebase.google.com/docs/crashlytics/get-started-new-sdk?platform=ios&authuser=1
- Fabricから移行するとき
    - https://firebase.google.com/docs/crashlytics/upgrade-sdk


## 感想
FirebaseのコンソールからCrashlyticsの導入を始めるのが一番手っ取り早いと感じた。最新のドキュメントを探さなくても、途中途中でドキュメントが出てきたためwww
GoogleスプレットシートのデータをWordPressのMySQLにコピーする方法【PHPでまるっと処理】

Googleスプレットシートのデータを、WordPressのMySQLにコピーする方法を説明します。

#スプレットシートのデータをWordPressのMySQLにコピーする方法
PHPファイルでまるっと処理しますが、スプレットシートを公開してJSONファイルでデータを取得可能にした上で、WordPressのサーバからJSONを取得しにいって、MySQLにデータを流し込んでいくというのが大まかな流れです。

#前提（データセットとスプレットシートの下処理）
**【例として扱うデータセット】**
過去記事でも扱っているGoogleフォームで募った会議参加者の情報を管理することを例にあげます。

>（過去記事）
[Googleフォームで取得した画像をスプレットシートで表示する方法【セル内に画像で表示】](https://qiita.com/fuku_up/items/c99a6f711c5caa74961b)

>（参考）
今回扱うデータは[こちら](https://docs.google.com/spreadsheets/d/1SZCuyk2H7FBOxoeLp93imOlUxjBu2gBFhUpHk_PVaBc/edit?usp=sharing)にて公開しておりますので、必要に応じてコピペして使ってください。データセットとして｛image, name, birthplace, performance｝の4つを扱います。
![Screen-Shot-2019-12-08-at-19.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/d40d8606-9d3f-55da-871b-af2857a21642.png)

WordPress側の独自テーブルの作成にあたっては、必要に応じて以下を参照してください。`wp_member_list`という独自テーブルを作成しています。

>（その他 参考記事）
[WordPressのMySQL独自テーブルの作成と利用方法【wp-db.phpの更新必須】](https://qiita.com/fuku_up/items/28e7540cac7cfc1602f1)

**【スプレットシートの公開】**
スプレットシートに外部からアクセスできるように公開する必要があります。（取り扱うデータの観点から、公開先を限定する必要があれば`SpreadSheet API`を活用してください。）

![wordpress_mysql_from_spreadsheet_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/ad28fe4b-d370-84a4-87e9-6c2443bc111e.jpeg)

その上で、スプレットシートをJSONで取得できるURLを作成します。公開したスプレッドシートのIDを、`黄色下線部の部分`に指定してください。

<img width=100% alt="Screen Shot 2020-03-27 at 23.53.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/6cac1bcc-f479-4bab-f1c0-174009a605a4.png">

きちんとJSON取得用のURLになっていると、ブラウザでアクセスした際にスプレットシートの結果が返ってくることが確認できます。

![wordpress_mysql_from_spreadsheet_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/3b7e0ba7-c571-5687-9e22-a81db95691b9.jpeg)

#データをコピーするPHPスクリプト
以下のPHPコードにて、スプレットシートからデータ取得を行って、MySQLへデータを格納します。

```php:sample.php
<?php

require_once(dirname(__FILE__) . "../../../../wp-load.php"); //実行環境に合わせてパスを設定

// スプレットシートからJSONの値を取得
$data = "https://spreadsheets.google.com/feeds/list/1SZCuyk2H7FBOxoeLp93imOlUxjBu2gBFhUpHk_PVaBc/od6/public/values?alt=json";
$json = file_get_contents($data);
$json_decode = json_decode($json);
$names = $json_decode->feed->entry;

global $wpdb;

// スプレットシートの行ごとに処理を繰り返す
foreach ($names as $name) {

    // JSONからそれぞれの値を取り出す
    $m_image = $name->{'gsx$image'}->{'$t'};
    $m_name = $name->{'gsx$name'}->{'$t'};
    $m_birthplace = $name->{'gsx$birthplace'}->{'$t'};
    $m_performance = $name->{'gsx$performance'}->{'$t'};

    // JSONから取り出した値を独自テーブル(member_list)へinsertする
    $wpdb->insert($wpdb->member_list, array(
        'image' => $m_image,
        'name' => $m_name,
        'birthplace' => $m_birthplace,
        'performance' => $m_performance
        ), array('%s', '%s', '%s','%s',));
}
return;
```

正しく実行できていれば、準備しておいた独自テーブル（WordPressのホスティングサーバのMySQL内）の中に、スプレットシートから取得したデータが格納されていることが確認できると思います。

![b_spreadsheet_demo_insert.php_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/30a06a64-7784-6213-b4f0-806f050924fa.jpeg)

上手くいかない場合は、スプレットシートの公開設定や過去記事に記載した[WordPressのMySQLで独自テーブルを設定する方法](https://qiita.com/fuku_up/items/28e7540cac7cfc1602f1)について確認してみてくださいね。
dockerで立てたpostgresをposticoからみる

# やりたいこと

- dockerで立てたpostgresをlocalからGUIで中身を見たい

# postgresで見ようとした際にでたエラー

結構posticoでみるまでに苦労したのでかきに記しておく

https://teratail.com/questions/247008

上記のエラーが出た。原因を見つけるために下記を行う

# database.ymlとdocker-compose.ymlの設定

## passwordは必要？

https://docs.docker.com/compose/rails/

このドキュメントにはpassは省略してたが省略したら怒られた。たぶん必要。

## POSTGRES_PASSWORDなどの設定

```docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./docker/pg:/var/lib/postgresql
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: localhost
      POSTGRES_DB: test_db
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

上記のようにpassなどの設定をする。ここをdatabase.ymlと合わせる。

```database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: localhost
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
```

# psqlコマンドで開く

psqlのコマンドは下記

「psqlドキュメント」
https://www.postgresql.jp/document/9.2/html/app-psql.html

```
docker-compose run db psql -U localhost -d test_db -h db -p 5432
```

でposticoではなく直接みてみる。上記は下記の意味合い。

```
$ psql -U localhost（usernameの指定） -d test_db（dbnameの指定） -h localhost（hostnameの指定） -p 5433（portの指定）
```

# 詰まったときに助かったコマンド

## すべてを消すコマンド

```
# すべてを無に帰す
$ docker-compose down --rmi all --volumes
```

参考：
https://qiita.com/suin/items/19d65e191b96a0079417
yieldとproc

yieldとproc

今まで何度もブロックを使ってきた
しかし、今まで使ってきたのは既存のメソッド（each,mapなど）

自分でもブロックで使うメソッドは定義できるのか？

【結論】できる

ここからはブロックを利用するメソッドの定義、処理を引数や変数として渡す方法をまとめる

各エフェクトにｃaｌｌというメソッドを実装する

yield→ブロックを利用するメソッドの定義をする

渡されたブロックを実行するためにメソッドないでyieldを使う

```ruby
def greeting
  puts 'おはよう'
  yield
  puts 'こんばんは'
end

greeting do
  puts 'こんにちは'
end
```
```
=> おはよう
   こんにちは
   こんばんは
```

yieldは引数をブロックに渡したり、戻り値を受け取って出力もできる

ブロックを明示的にメソッドの引数として受け取るには？
→引数名の前に＆をつける

ブロックの引数はメソッド定義につき一つしか指定できない
また、他の引数がある場合はブロックの引数を必ず最後に指定する
UiPathでOCR機能を使ってみる（GoogleVisionAPI使用）

## この記事はなにか

RPAツールの`UiPath`と`GoogleVisionAPI`と連携させ、
`OCR機能`を使って画像に書かれた文字を読み取り、テキストに書き込むまでのやり方を記載しています。

<details><summary>結果はこちら！</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/ddf3efbe-dad1-0313-9e37-66fc633d57fa.png)
</details>

## 手順&イメージ

大まかな流れは以下のとおりです。

1. Google Cloud PlatformでGoogleVisionAPIのAPIキーを取得
2. UiPath.GoogleVision.Activitiesをインストール
3. GoogleVisionスコープにAPIキーを設定&その他設定
4. 実行！

UiPathのシーケンスのイメージはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/c51cc70e-c92b-397a-95a9-d90bfb9e28b9.png)

### 1.Google Cloud PlatformでGoogleVisionAPIのAPIキーを取得

[Google Cloud Platform](https://console.cloud.google.com/?hl=ja)にログイン後、`APIとサービス`⇒`ライブラリ`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/f5489c67-d3a6-696e-4713-b033d742519d.png)

次に開く画面で`vision`と打つと`Cloud Vision API`が出てくるのでそれをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/797ad284-6ddb-1339-9e22-cc9d07f62396.png)

`有効にする`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/0c26453e-f406-2045-0981-76238b982c7a.png)

`認証情報`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/5ad80d33-041f-edec-b96d-0b81fa67459e.png)

`認証情報を作成`⇒`APIキー`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/3d6fe9fe-f96e-f60e-56f4-784d1c504158.png)

APIキーが作成されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/dd8e49c3-81b2-8954-0ab7-b0d31b7ec6bd.png)

### 2.UiPath.GoogleVision.Activitiesをインストール

UiPathに移動し、`UiPath.GoogleVision.Activities`をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/9ad698d3-d2d8-019b-424f-fc4d4f92f4d4.png)

### 3.GoogleVisionスコープにAPIキーを設定&その他設定

シーケンスで以下のように組み立てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/c51cc70e-c92b-397a-95a9-d90bfb9e28b9.png)

各アクティビティをそれぞれ下の画像の様に設定します。
画像のパスは、解析したい画像の保存先を指定して下さい。
ちなみに、URLからだとうまく行かなかったので今回は`画像のパス`を選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/7918ecc0-853b-d086-7212-c7a31bc7ba71.png)

テキストをファイルに書き込みは以下のように設定しました。
ファイル保存先（ファイル名含む）は任意のパスで良いかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/b6f7376b-5d2b-0e26-0807-e3d6c5eeb15c.png)

### 4.実行！

さあ、実行します :arrow_forward:！結果はどうでしょうか…

## 結果

ローソンさんが報道機関向けに提供した増税の際のレシートを使用して読み取ってみます。

右と左を分けてしまっていますが、だいたい読み取れている感じですね。
通常の文章であれば全然大丈夫そうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/ddf3efbe-dad1-0313-9e37-66fc633d57fa.png)

ちなみに、[Google Keep](https://keep.google.com/)にもOCR機能があるのでやってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/dcb7823e-3d19-60d1-ea3e-172e21829bd9.png)

ん？Google Keepのほうが精度高くみえるぞ笑
おそらく日本語にしてなかったりしてたので設定の問題でしょうか。

## 所感

初めてやってみたのですが、思ったより簡単でした。
画像の簡単な文章のテキスト化や、うまくやれば伝票関係の処理とか自動化できそうですね。
初心者がweb-starter-kitを使おうとして躓いたことを共有したい

今更Reactを知り勉強を始めて3ヶ月目の初心者です。
いつも通り空き時間にググっていると『web-starter-kit』というgoogle製のひな形がある事を知りました。
絶対的なGoogle信者の私は神（Google）が勧めるものを使わないわけにはいきません。
[Google様のサイト](https://developers.google.com/web/tools/starter-kit?hl=ja)には誰でも簡単に出来そうに書いてあるので即舐めてかかりました。
しかし、実際やってみると。。。。

```
$ gulp serve
```

このコマンドが動くまでエラーだらけで凄い大変でした。
似たようなGoogle信者が同じ罠に嵌らないよう参考にしていただければ幸いです。

###環境
|ツール・環境|　　　　　バージョン　　　　　|
|:--:|:--:|
|ＯＳ|Windows10|
|Node.js|　v11.15.0　☚大事　|
|web-starter-kit|v0.6.5|



##結論
デフォルトのパッケージのを下記のものに書き換えたらやっと動作しました  

<br>.babelrc　を書き換える

```diff

{
-　　"presets": ["es2015"],
-　　// Remove the line below to enable ES2015 support.
-　　"only": "gulpfile.babel.js",
-　　"retainLines": true
+  "presets": ["@babel/preset-env"]
}

```
<br>package.json　を書き換える

```diff
{
  "devDependencies": {
-    "babel-core": "^6.14.0",
+    "@babel/core": "^7.9.0",
-    "babel-preset-es2015": "^6.0.15",
+    "@babel/preset-env": "^7.9.0",
+    "@babel/register": "^7.9.0",
+    "babel-jest": "^25.2.3",
+    "babel-loader": "^8.1.0",
+    "jest": "^25.2.3",
+    "node-sass": "^4.13.1",
+    "regenerator-runtime": "^0.13.5",
+    "sass": "^1.26.3"
   },
+  "resolutions": {
+    "babel-core": "7.0.0-bridge.0"
+  },
}

```



##エラーとやった事

>Uncaught SyntaxError: Cannot use import statement outside a module

最初に　gulp コマンドを走らせて　gulp.babel.js　を読み込む時に出たエラーです
上記の通り.babelrcを書き換えることで解消しました
理由は不明です:relaxed:
おそらくbabel7.0でバベると出てしまうと解釈しました
詳しい方、補足いただけると涙出ます

[参照記事：　babel-preset-es2015 -> babel-preset-env](https://babeljs.io/docs/en/env/)

<br>
>AssertionError [ERR_ASSERTION]: Task function must be specified

Node.jsとgulpがバージョンによって相性が悪いらしく、そのせいで出てしまったようです
初めはgulpを4.0に上げてみましたが、ほかのエラーが笑笑出たので最終的にNode.jsのバージョンを下げました
エラーと対策の詳細は参照記事でまとめて頂いているので、そちらをご覧ください

[参照記事：　Gulp環境構築にて「AssertionError [ERR_ASSERTION]: Task function must be specified」の原因はgulp v4にバージョンアップした事による仕様変更](https://qiita.com/shun_kominato/items/7c9777341a8045d863c2)

<br>
>Requires Babel “7.0.0-0” but was loaded with “6.26.3”

とにかくハマりました
依存関係が悪さをしているらしいです
下記の対策でようやく対処できました

- 『babel-＊＊＊』ってなってるバベる関係のパッケージを『@babel/***』に変えまくる（グローバルもやっちゃってたらそちらも）　
- package.jsonに"resolutions"を足す
- その他若干足す（上記のpackage.jsonに足したもの）
    - こちらも意味は理解していません:relaxed:　外人が楽しそうに会話してるのを雰囲気で真似してみました

[参照記事：　Requires Babel “7.0.0-0” but was loaded with “6.26.3” #8482](https://github.com/babel/babel/issues/8482)

##まとめ
上記の対策でやっとコマンド実行できました。
gulpって単語を初めて聞いたぐらいの初心者がやった事なので、間違った事や無駄なことも有るかと思います。
訂正させて頂きますので、気づかれた方ご指摘頂けると幸いです。
最後まで読んでいただき、ありがとうございました。
AtCoder 生活　8日目

[前回](https://qiita.com/flandrescarlet237/items/0fb88ed2b154c8c06741)

#8日目
今日は、ABC049からABC053のB問題を解きました

##ABC049_B
[たてなが]
(https://atcoder.jp/contests/abc049/tasks/abc049_b)

```c++

#include <bits/stdc++.h>
using namespace std;

int main() {
    int h, w;
    cin >> h >> w;
    string s, r;
    for (int i = 0; i < h; ++i) {
        cin >> s;
        r += s;
        r += "\n";
        r += s;
        r += "\n";

    }
    cout << r;

}
```

自力で解くことが出来なかった。

##ABC050_B
[Contest with Drinks Easy]
(https://atcoder.jp/contests/abc050/tasks/abc050_b)

```c++
#include<bits/stdc++.h>
using namespace std;

int main() {
	int N, M;
	cin >> N;
	vector<int> T(N);
	for (int i = 0; i < N; i++) {
		cin >> T.at(i);
	}
	cin >> M;
	vector<int> P(M);
	vector<int> X(M);
	for (int i = 0; i < M; i++) {
		cin >> P.at(i) >> X.at(i);
	}
 
	int sum = 0;
	for (int i = 0; i < N; i++) {
		sum += T.at(i);
	}
 
	for (int i = 0; i < M; i++) {
		int ans = sum + X.at(i) - T.at(P.at(i) - 1);
		cout << ans << endl;
	}
}


```


問題の意味を読み解くことが出来なかった。

##ABC051_B
[Sum of Three Integers]
(https://atcoder.jp/contests/abc051/tasks/abc051_b)

```c++

#include<bits/stdc++.h>
using namespace std;
int main(){
	int K,S;
  	cin >> K >> S;
  	int res = 0;
  	for(int x=0;x<=K;x++){
      	for(int y=0;y<=K;y++){
            if(0<=S-x-y && S-x-y<=K)res++;
        }
    }
  	cout << res << endl;
}

```

これに似た問題をよく見る気がする。

##ABC052_B
[Increment Decrement]
(https://atcoder.jp/contests/abc052/tasks/abc052_b)

```c++

#include<bits/stdc++.h>
using namespace std;
int main(){
	int N;
  	cin >> N;
  	string S;
  	cin >> S;
  	int x =0;
  	int y =0;
    for(int i=0;i<N;i++){
    	if(S[i] == 'I'){
          x++;
          y = max(x, y);
        }
      	else x -= 1;
    }
  	cout << y << endl;
}

```

ちゃんと昨日覚えたmaxを使えました！

##ABC053_B
[A to Z String]
(https://atcoder.jp/contests/abc053/tasks/abc053_b)

```c++


#include <bits/stdc++.h>
using namespace std;
int main(){
  string s;
  int a,z;
  cin>>s;
  for(int i=0;i<s.size();i++){
    if(s[i]=='A'){
      a=i;
      break;
    }
  }
  for(int i=s.size()-1;i>=0;i--){
    if(s[i]=='Z'){
      z=i;
      break;
    }
  }
	cout << z-a+1 << endl;
}

```

forにこんな使い方があったのかと驚きました

明日のABC160は、がんばってB問題までは正解したいです
アプリをおしゃれにデコレーションする Flutter パッケージ

最近は暇さえあれば [pub.dev](https://pub.dev/) を眺めている @kurararara です。
先日なんて一日で 130 ページもの Top packages を見続け、流石に疲れました(笑)

色々と見ていて、 **アプリがおしゃれになりそうなパッケージ** を見つけたので紹介したいと思います。



## はじめに

:link: [【Flutter】アプリ開発_初心者のアプリをプロっぽくする最強のpackageを紹介](<https://qiita.com/kazumaz/items/876e162cf429014661d8>)

こちらの記事でたくさん良いパッケージをみつけて、早速利用させていただきました！
ぜひ読んでみてください！
（この記事もその後に読んでほしいですが…… :face_with_rolling_eyes: ）



その上で、僕が紹介するのは上の記事に載っていないものに絞っています！
それではいってみましょう！！



## [flutter_staggered_animations](https://pub.dev/packages/flutter_staggered_animations)

![flutter_staggered_animations.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/7af76a66-0778-f733-2445-9fe630d448ed.gif)
ひとつ目はこちらです！

[flutter_staggered_animations](https://pub.dev/packages/flutter_staggered_animations) は普段は味気ない `ListView` `GridView` `Column` を、表示時にアニメーションさせてくれるパッケージです。
動きがあるだけでアプリのおしゃれさが増しますよね！

実装も `AnimationConfiguration` ウィジェットでラップするだけなのでお手軽に利用できるのでおすすめです :yum:



## [pull_to_refresh](https://pub.dev/packages/pull_to_refresh)

![pull_to_refresh.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/e4351a28-af3c-b30a-88a3-cdee9d2de903.gif)
続いてはこちら！

[pull_to_refresh](https://pub.dev/packages/pull_to_refresh) はモバイルアプリによくある下にスワイプしたら再ロードするやつ（名前あるのかな？）を様々なアニメーションでエフェクトできるパッケージです。

僕が開発しているアプリではローディングする要素が見当たらないのでまだ利用はしていませんが、 `WaterDropMaterialHeader` はいつか使ってみたいなーと思っています。
独自実装だと難易度高そうですしね(笑)



## [progressive_image](https://pub.dev/packages/progressive_image)

![progressive_image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/a2a32804-44ed-a096-f572-c8edc88efd05.gif)
みっつ目！

[progressive_image](https://pub.dev/packages/progressive_image) は画像の読込中にプレースホルダーとサムネイル画像を表示してくれるパッケージです。
モバイルアプリでの画像の利用は多いですが、デバイスの解像度は高く高画質なのに、大きな画像を使うとロード時間や容量の問題が出てくる……ジレンマですね。

直接的には解決できないまでも、このパッケージを利用することで利用ユーザーに与える印象は大きく変わるのではないでしょうか？



## [flutter_inner_drawer](<https://pub.dev/packages/flutter_inner_drawer>)

![flutter_inner_drawer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/59e96bb3-cf1f-1a86-558e-b53c9f4dd1ef.gif)
多すぎて内容が薄くなるのも嫌なのでこれで最後です！

[flutter_inner_drawer](<https://pub.dev/packages/flutter_inner_drawer>) はアプリでよく利用されるサイドバーをリッチに彩るパッケージです。
シンプルなサイドバーだけでなく一見変わったスライドをするものも作ることができて、他のアプリと差をつけられそうですね！



## おわりに

アプリをおしゃれに装飾する Flutter パッケージを紹介してきました。

上の記事でもたくさんの便利なパッケージが紹介されていましたが、 pub.dev にあるパッケージはたくさんあります。
（pub.dev は広大だわ）

みなさまにおいても、**自分のお気に入りを見つけられるといいですね！**

それでは良い Flutter ライフを～ :yum:
WordPressのMySQL独自テーブルの作成と利用方法【wp-db.phpの更新必須】

『WordPressのMySQLに独自テーブルを作りたい！！』というときに必要となる作業と、独自テーブルへの接続方法についての説明です。

#WordPressのMySQL独自テーブルの作成と利用方法
ということで、早速ですがMySQLへのテーブルを用意します。

**【前提（取り扱うデータ）】**
過去記事でも扱っているGoogleフォームで募った会議参加者の情報を管理することを例にあげます。

>（参考となる過去記事）
[Googleフォームで取得した画像をスプレットシートで表示する方法【セル内に画像で表示】](https://qiita.com/fuku_up/items/c99a6f711c5caa74961b)

管理するデータは以下になりまして、｛プロフィール画像URL、名前、出身地、主な実績｝をこれらを管理する独自テーブルを作ります。

<img width=100% alt="Screen-Shot-2019-12-08-at-18.15.34-1024x378.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/c73ccbf1-3f15-b1d9-2e6b-09231d04b6ff.png">

#データベースの作成とwp-db.phpの更新
早速ですが、お好きな手順で独自テーブルを作成してください。ホスティングサーバーの`phpMyAdmin`から作るのが手っ取り早いかと思います。

**【独自テーブルの追加】**
デフォルトだと、`wp_db`というデータベースが作成されていると思うので、その中に新しい独自テーブルとして`wp_member_list`を追加しました。

<img width=100% alt="wordpress_mysql_original_table_01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/8e6f84c3-8f4c-2fd0-3307-e43c5a7bae73.jpeg">

`wp_`の部分はプレフィックス（接頭辞）となりまして、他のテーブルの前にも規則的なプレフィックスがついていると思うので、そちらに合わせて独自テーブルのテーブル名の先頭に付与するようにしてください。（デフォルトでは`wp_`になっています。）

**【wp-db.phpへの独自テーブルの登録】**
[WordPressフォルダ] → [wp-includesフォルダ]の中に、`wp-db.php`というファイルがありまして、こちらに独自テーブルの情報を更新する必要があります。

当該のファイルを開いたら、`$tables`の配列（おそらく260行目あたりにあると思います。）に独自テーブル`member_list`を追加して更新してください。※この際にはプレフィックスを除いた文字列を追加するようにしてください（下記、最下行参照）。

```php:wp-db.php
var $tables = array(
    'posts',
    'comments',
    'links',
    'options',
    'postmeta',
    'terms',
    'term_taxonomy',
    'term_relationships',
    'termmeta',
    'commentmeta',
    'products',
    'member_list', //独自テーブルを新規で追加
);
```
#データベースへの接続
では、独自テーブルに接続できるかを確認したいと思います。疎通試験だけするスクリプトを用意しました。wordpressのテンプレートフォルダにconnection_check.phpというファイルを作っています。

私はMacでMAMP環境を整えているので、こんなパスになります。

```
/Applications/MAMP/htdocs/wordpress/wp-content/themes/twentytwelve/connection_check.php
```

**【独自テーブルへの疎通確認スクリプト】**
SELECT文で、データベースに繋げるかどうかを見ています。テーブルにデータが入っていなくても、データベースに接続さえできればSELECT結果0件として戻ってくるので、`$wpdb`の実行結果に値が入って接続成功となります。

データベースの接続にあたってWordPressの設定情報がいるので`require_once関数`で取得しています。wp-load.phpへの相対パスはお手元の環境に合わせて修正してください。

```php:wp-load.php
<?php

require_once(dirname(__FILE__) . "../../../../wp-load.php");

global $wpdb;
$rows = $wpdb->get_results("SELECT count(*) FROM $wpdb->member_list");

echo "<br> MySQLの独自テーブルへアクセス <br>";

if(empty($rows)){
    echo "<br> 接続失敗 <br>";
}else{
    echo "<br> 接続成功 <br>";
}

return;
```

**【phpファイルの実行】**
念の為ですが、上記の私の環境だと、phpファイルを置いたフォルダにアクセスすれば実行結果が得られます。（パスは適宜修正してください。）

```
http://localhost:8888/wordpress/wp-content/themes/twentytwelve/connection_check.php
```

その上で、以下の実行結果が返ってきたら接続に成功しています！！

>MySQLの独自テーブルへアクセス
接続成功

---
とうことで、WordPressのMySQL独自テーブルの作成と接続方法についての説明でした。`wp-db.php`の更新を忘れると、永遠に接続できないので注意してくださいね。
webAPI入門したと言いたい

# はじめに
webAPIとは何それ美味しいの？って感じだったので、今回少し触ってみました。

# やりたいこと
この[サイト](https://yesno.wtf/#)のAPIを利用してみる。
googleのAPIやqiitaのAPIを試してみようとしたが、ドキュメントが読めず挫折しました。また今度挑戦します。

# やったこと
1. `JsFiddle`で`vue.js`の環境を用意する。[サンプル](https://jsfiddle.net/boilerplate/vue)
2. `axios`メソッドを使用して、API通信をする。
3. `html`に取得したデータを表示する。
4. 以上！

## 参考
[完成版](https://jsfiddle.net/kurimaron/u3my0gn1/32/)


# 苦戦したこと
- `axios`に指定するURLがどれか分からなかった。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273913/e6f3d9ef-5da3-cc27-9056-64a1d4935291.png)

GETの横に`/api`と書いてあるので、既存のURLの末尾に追加すると`json`データが取得できた。

- APIで取得したデータから各プロパティを抽出する方法が最初分からなかった。
- cssの設定で、画像を中央に文字を重ねることができなかった。

# 最後までできなかったこと
- `css`の`transform: translate (-50%, -50%);`が機能しない。
- 一番やりたかったこと。取得した画像と文字を同時に表示させる方法。（是非教えて頂きたい・・・） 

# 最後に
この記事を書くまで、qiitaにJsFiddleを埋め込めれると思っていたが、できなかった。CodePenなら対応しているみたい。
今後は、CodePenを利用していこうとおもう。
[JavaScript] 動的にinput[type=file]を組み立てて画像をアップロードしたらBase64が手に入るコード

画像アップロードする時に、以下のように `display: none` をつかってブラウザ本来の `input[type=file]` をみえないようにした上で独自レイアウトのボタンで画像アップロードするような実装を時々みかけます。

```html
<label for="hoge">画像アップロード</label>
<input id="hoge" type="file" style="display: none">
```

で、 `addEventListener` でファイル変更検知を行ったりと。
けれど、上記のようにするとマークアップがある程度拘束されてしまいます。やりたいことはボタンをクリックしたら画像をアップロードしてBase64を手にいれるとかそういう話なので、クリックイベントを仕込んで以下のコードを実行すればOKです。

```html
<div style="width: 0; height: 0; overflow: hidden;">
  <input id="browserPhotoUploader" type="file" accept="image/*" />
</div>
```

```javascript
public getPictureFromBrowser() {
  /*
   * input[type=file] を組み立て
   */
  const inputFile: HTMLElement = document.querySelector('input#browserPhotoUploader');

  return new Promise(resolve => {
    /*
     * input[type=file] の変更（change）を検知したら、ファイルをアップロードしてresolveする
     */  
    inputFile.addEventListener(
        'change',
        (e) => {
          const file = e.target.files[0];
          const reader = new FileReader();

          reader.onload = (fileInput => {
            /*
             * アップロードされるファイルが画像かを簡易判定
             */  
            if (file.type.indexOf('image') < 0) {
              reject(null);
            }

            return (event) => {
              resolve(event.target.result);
            };
          })(file);

          reader.readAsDataURL(file);
        },
        false,
    );

    /*
     * input[type=file] をクリック
     * イベントリスナーよりあとに実行されるように
     */  
    inputFile.click();
  });
}
```

このコードだったらHTML側は

```html
<button (click)="getPictureFromBrowser()">画像アップロード</button>
```
だけで済みますね。 `display:none` せずにすむのでシンプル！

それでは、また。

### おまけ: TypeScript版
`any` 使ってるのちょっと何ですが・・・。

```typescript
public getPictureFromBrowser(): Promise<string> {
    const inputFile: HTMLElement = document.querySelector('input#browserPhotoUploader');
    return new Promise(resolve => {
      inputFile.addEventListener(
        'change',
        (e: any) => {
          const file = e.target.files[0];
          const reader = new FileReader();

          reader.onload = (fileInput => {
            if (file.type.indexOf('image') < 0) {
              reject(null);
            }

            return (event) => {
              resolve(event.target.result);
            };
          })(file);

          reader.readAsDataURL(file);
        },
        false,
      );
      inputFile.click();
    });
  }
```
LTTng Tracing Tips

# Overview

Here descibes ROS2 tracepoint related information, this is public info but not so organized well because this is mostly my own note to keep this in the mind. nobody blames on it. ROS2 tracepoint is actually depends on LTTng so knowing LTTng is to help to understand ROS2 tracepoint.

## LTTng

### Installation

```
$ sudo apt-add-repository ppa:lttng/ppa
$ sudo apt-get update
$ sudo apt-get install lttng-tools lttng-modules-dkms babeltrace liblttng-ust-dev liblttng-ctl-dev
```

### LTTng Modules

LTTng are the kernel modules, so that you can see a bunch of ko via lsmod command. Notable features are CTF(Common Trace Format) support, tracepoint, function tracer, monitoring and kprobes. LTTng is context aware so that able to attach context information to event in the trace.

### Required Kconfig

- CONFIG_MODULES
- CONFIG_KALLSYMS
- CONFIG_HIGH_RES_TIMERS
- CONFIG_TRACEPOINTS

### Tutorial

- [Tracing Linux Kernel](https://lttng.org/docs/v2.11/#doc-tracing-the-linux-kernel)
- [View and Analyze Data](https://lttng.org/docs/v2.11/#doc-viewing-and-analyzing-your-traces)
- [Trace User Application](https://lttng.org/docs/v2.11/#doc-tracing-the-linux-kernel)

![Hello Tracing](https://lttng.org/docs/v2.11/images/ust-flow.png)

### Trace Session Mode

- Local mode
  LTTng writes the traces to the file system of the machine it traces (target system).
- Network streaming mode
  LTTng sends the traces over the network to a relay daemon running on a remote system.
- Snapshot mode
  LTTng does not write the traces by default. Instead, you can request LTTng to take a snapshot, that is, a copy of the tracing session’s current sub-buffers, and to write it to the target’s file system or to send it over the network to a relay daemon running on a remote system.
- Live mode
  This mode is similar to the network streaming mode, but a live trace viewer can connect to the distant relay daemon to view event records as LTTng generates them.

and there are so far five tracing domains are supported,

  - Linux Kernel
  - User space
  - java.util.logging
  - log4j
  - Python

## License

|  Package  |  License  |
| ---- | ---- |
|  LTTng-tools  |  LGPLv2.1 and GPLv2  |
|  LTTng-UST  |  LGPLv2.1, the MIT license and GPLv2  |
|  LTTng-modules  |  LGPLv2.1, GPLv2 and the MIT license  |

## Reference

- [LTTng Official](https://lttng.org/)
- [LTTng PPA](https://launchpad.net/~lttng/+archive/ubuntu/ppa)
- [LTTng Module](https://github.com/portworx/lttng-modules/blob/master/README.md)
- [LTTng Getting Started](https://lttng.org/docs/v2.11/#doc-getting-started)
[docker] docker pull が途中で止まる時は "max-concurrent-downloads 1" を試してみよう 

# 概要

遅いインターネット回線で "docker pull" (docker build も同様)してたら途中で止まってしまった。タイムアウトなのか。遅い(重い)だけなのか。
Dockerの設定を変更して最大同時ダウンロード数(max-concurrent-downloads)を"1"にしたらうまくいった。

# 環境

Host OS: Windows 10 Home
- "Docker Toolbox" でDockerを利用

Docker: version 19.03.1

```
$ docker --version
Docker version 19.03.1, build 74b1e89e8a
```

# 背景

自宅PCでDockerを使っていたが、ある事情で家のインターネット回線を解約しました。
仕方なく、格安SIM(楽天モバイル)のテザリングでネットに繋いでいるので回線が重い。

すると、（今までそんなことなかったのに） `docker build` 等のコマンドでネットからファイル取得中に進まなくなる現象が多発するようになりました。


# 現象

例えば以下のような感じで、ファイルのダウンロード中で止まってしまう。

```
$ docker pull php:7.4-fpm-alpine
7.4-fpm-alpine: Pulling from library/php
aad63a933944: Downloading [==========================>                        ]   1.51MB/2.803MB
b61c449d5d91: Download complete
3fde16e1397a: Download complete
b1096698ab2a: Download complete
1b7b3153bac8: Download complete
c25256547bec: Download complete
47e7fc912cc2: Download complete
7ad4a4e5e343: Download complete
1739f6256835: Download complete
40c44c56af3f: Download complete
```

いくら待っても、これ以上進まない。
数回試したが、止まるファイルやどこまで進んだかが一定ではない。

# 解決策

色々調べると "Docker daemon" の起動時オプションで以下を追加するとうまくいきそう。
> --max-concurrent-downloads 1

("max-concurrent-downloads" オプションについては https://docs.docker.com/engine/reference/commandline/dockerd/ 参照)

Docker toolbox を使っている場合は、以下の手順で変更できるようだ。

### docker-machineに接続
```
$ docker-machine ssh default
```

### profileファイル編集
```
[docker@default]
docker@default: sudo vi /var/lib/boot2docker/profile
  # EXTRA_ARGS に "--max-concurrent-downloads 1" を追加する
docker@default: cat /var/lib/boot2docker/profile

EXTRA_ARGS='
--label provider=virtualbox
--max-concurrent-downloads 1
'
CACERT=/var/lib/boot2docker/ca.pem
DOCKER_HOST='-H tcp://0.0.0.0:2376'
DOCKER_STORAGE=overlay2
DOCKER_TLS=auto
SERVERKEY=/var/lib/boot2docker/server-key.pem
SERVERCERT=/var/lib/boot2docker/server.pem

docker@default: exit
```

### docker-machine再起動
```
docker-machine restart default
```

(https://github.com/boot2docker/boot2docker#docker-daemon-options 参照)

# 結果

上記設定変更作業すると以下のようになった。

- pull するファイルが3並列だったのが直列になった。
- 途中で止まらなくなった。

# まとめ

ネット接続が重い状態で `docker pull` が止まる場合、並列ダウンロードをやめると改善する場合がある。
【ターミナル】今後試したい便利なコマンド

#`top`

**【試したいシーン】　動作が重くなった時**

```ruby:ターミナル

$ top
```
`top`・・・実行中のプログラムを全て表示

##CPU使用率順に表示

```ruby:ターミナル

$ o #アルファベットの"o"
```
※enter keyは押さない

```ruby:

primary key [-pid]:
```
と表示されるので

```
$ cpu
```

を入力し、enter key押す

**↓実行結果**
<img width="1440" alt="スクリーンショット 2020-03-27 21.58.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584233/1346f1ca-c5cc-cfc2-3748-483c07c3451c.png">


**上からCPU使用率が高い順に表示される**


〜今後、ボチボチ追加予定〜
Pythonのbinaryデータの扱いで詰まった話

こんにちは。
この記事では、Pythonでバイナリーデータを扱う際に躓いた点を共有させていただきます。

##バイナリデータを扱う際のテンプレート文
はじめにバイナリーデータを開く関数を用意します。(numpy 読込済)
※本題ではありませんが、私の場合はdtypeのエンディアン設定でもよく躓きます。

```python
def open_grd(gpv_file):
  with open(gpv_file, 'rb') as ifile:
    data = np.fromfile(ifile, dtype='>f', sep = '')
  return data
```

##本命の部分
ここで返ってきたデータを図化するために、データを格子系に整形を行います。
前提条件として、下記の条件に則ってデータが格納されていると考えます。

```Python
data_info = {
  'nx' : 150,
  'ny' : 100,
  'data_path' : './your_data.grd'
}

data = open_grd(data_info['data_path']).reshape(
 data_info['ny'], data_info['nx'], order='C' #! or 'F'
)
```

これらのように行うと、配信データかFortranで自作したデータかによってデータ配列が同じにも関わらず、上手くできた場合とできない場合がありました。
解決策としては、最後の文の末尾reshapeで変換順序を指定する必要があることを確認しました。

```ndarray.reshape``` の変換順序の引数は、デフォルトでは```order='C'```となっています。
なので、Fortranなどで自作したバイナリーデータでは、```order='F'```とする必要があります。

同じような点で困った人の手助けになれたら幸いです。
最後まで見ていただき、ありがとうございました。

##参考
・NumPy配列ndarrayの形状を変換するreshapeの使い方
https://note.nkmk.me/python-numpy-reshape-usage/
Codeforces Round #318 [RussianCodeCup Thanks-Round] (Div. 1) B. Bear and Blocks 左右からの貪欲

https://codeforces.com/contest/573/problem/B

なるほど。両端からのDPか。

# 概要
- n列の柱があり、それぞれ$a_{1}, a_{2}, ... a_{n}$のブロックが積まれている
- 時間が1経つと、上下左右がブロックに囲まれていないブロックは崩壊する。尚、地面もブロックとするが、端にはブロックは存在しない(つまり、1列目とn列目のブロックは必ず1の時間の後に崩壊する)
- 時間がどれだけ経つとすべてのブロックがなくなるか述べよ
★図がないと分かりにくいので問題ページを見てください

# NGなアプローチ
題意通りに解こうとすると、1時間がたった時のxは$min(a_{x-1}, a_{x} - 1, a_{x+1})$の高さ となるのでこれをシミュレーションすることが考えられる。がTLEする。

# こう考えた
まず、題意では`上下左右`が囲まれていないと消えるが右側を忘れて`上下左`のブロックの存在のみを気にすることにする。こうすると$x$列目の消える時間$t_{x}$は以下の要素の最小値である。

- xが経過したとき(左端が迫ってきたとき)
- $a_{x}$が経過したとき(如何に左右が囲まれていても、上のブロックは1つずつ消えるので$i$このブロックは必ず$i$後に消える)
- $t_{x-1} + 1の時間が経過したとき(左端のブロックがすべて消える時間の次の瞬間には絶対に消える)

つまり、左端から順番に$min(x, a_{x}, t_{x-1} + 1)$を計算することで、`上下左`のブロックの存在のみを気にする際の各列が崩壊する時間が分かる。

同様に左を気にしない`上下右`のブロックの存在のみを気にすると、右端から同様に計算することで`上下右`を気にした時間が計算できる。

各列のこの`上下右`と`上下左`を考慮して崩壊するまでの時間の最小値を取ることでその列が崩壊するまでの時間が求められる。なぜならこれは

- `左端`か`右端`が迫ってくるまでの時間
- $a_{x}$が経過したとき
- `左のブロックが消えた次の瞬間`か`右のブロックが消えた次の瞬間`

の最小値を取ることに他ならないからである。

# コード
```Python
from pprint import pprint
import sys
#sys.setrecursionlimit(100000)
input = sys.stdin.readline

n = int(input())
dat = list(map(int, input().split()))

datl = [-1] * n
datr = [-1] * n
res = [-1] * n
for i in range(n):
    datl[i] = min(i + 1, dat[i])
    if i > 0:
        datl[i] = min(datl[i], datl[i - 1] + 1)

for i in range(n):
    datr[n-1-i] = min(i + 1, dat[n-1-i] )
    if i > 0:
        datr[n - 1 - i] = min(datr[n - 1 - i], datr[n - 1 - i + 1] + 1)

for i in range(n):
    res[i] = min(datl[i], datr[i])

print(max(res))
```
https://codeforces.com/contest/573/submission/74300719
【Java】Listの使い方【ArrayList】

#Listとは？
複数の要素を含み、順序のつけられたコレクションのこと。
インターフェースのため、実装することで使用可能となる。

コレクションとはなんぞや？ってことで調べてます。

コレクション：オブジェクトの集合を扱うための仕組み。以下の種類がある。

- List系
    - ArrayList　　配列を扱う。

    - LinkedList　 配列を扱う。挿入・削除が高速。
    - Vector　　　配列を扱う。パフォーマンスが悪いため現在ではあまり推奨されない。
- Set系
    - 	HashSet 　 値の重複を許さない順不同の要素集合。
    - 	TreeSet　　値の重複を許さないソートされたの要素集合。
- Map系	
    - 	HashMap 　キーと値の組からなる要素の集合。
    - 	TreeMap  　 キーと値の組からなる要素の集合。キーでソートされている。

今回はArrayListを使用してみます。

##ArrayListの使用例

```listtest.java

package listtest;

import java.util.ArrayList;
import java.util.List;

public class Listtest {
	
	public static void main(String[] args) {

		List<String> list = new ArrayList<String>();

		list.add("りんご");
		list.add("みかん");
		list.add("メロン");

		System.out.println(list);

	}
}
```

```実行結果.
[りんご, みかん, メロン]
```

ArrayListは実装クラスのため、以下のようにインスタンスが作成できます。

```.
List<String> list = new ArrayList<String>();
```

実は以下のものと同様の内容となっています。
listにStringクラスのオブジェクトを詰め込んでるということですね。

```listtest.java
		List<String> list = new ArrayList<String>();

		list.add(new String("りんご"));
		list.add(new String("みかん"));
		list.add(new String("メロン"));

		System.out.println(list);
```

ある一つの要素を取り出したい場合はgetメソッドを利用します。引数にはリストの取り出したい要素の番号を入れます。

```listtest.java
		List<String> list = new ArrayList<String>();

		list.add(new String("りんご"));
		list.add(new String("みかん"));
		list.add(new String("メロン"));

		System.out.println(list.get(1));
```

```実行結果.
みかん
```
要素が取り出せました！
【Googleアナリティクス】User ID機能を使ってユーザの動きをトラッキングする（WordPress登録済みユーザの追跡）

WordPressで会員サイトなどを活用しているときに、登録ユーザ毎のトラッキングを行う方法をご紹介します。

#User ID機能を使ってユーザの動きをトラッキングする（WordPress登録済みユーザの追跡）
WordPressのプラグインである`BuddyPress`を活用して会員サイト（みたいなもの）を作っているのですが、ユーザごとの行動をトラッキングしたいという要望がありました。

`BuddyPress`や`WP Security Audit Log`でもログイン履歴や編集履歴などは取得できるのですが、どのページにアクセスしたかという粒度でログ取りできるものが見当たらなかったのでGoogleアナリティクスの`User-ID機能`を使うことにしました。

>【Googleアナリティクス User-ID機能】
User-ID とは、個々のユーザーに永続 ID を付与し、そのユーザーのエンゲージメント データを、セッションやデバイスをまたいで識別する仕組みです。解析ソリューションが一意のユーザー ID によってユーザーを判別できるため、レポートに表示されるユーザー数の精度が向上します。
（[Googleアナリティクス ヘルプページ](https://support.google.com/analytics/answer/3123662?hl=ja)より抜粋）

今回はWordPressのユーザごとに割り振られているユーザIDを識別子として、各ユーザのアクセス履歴を管理できる状況を目指します。

#WordPressのUser-IDを指定
ということで、GoogleアナリティクスのUser-ID機能を利用していくわけですが、基本的には以下のページを参考に致しました。下記の手順に従って、まずはUser-IDを識別してログ取りできるところまでご調整をお願いいたします。

>（参考）
[【Googleアナリティクス】User ID機能を使って会員ごとの動きを見る](https://www.ginzaitlab.com/posts/7059168/)

**【WordPressのユーザIDを指定する】**
その上で、WordPressのヘッダーファイルの</header>の直上に以下を埋め込んでいます。

```html:header.html
<!-- For Track User Log -->
<script> 
window.dataLayer = window.dataLayer || [];
    dataLayer.push({
    'uid' : <?php echo get_current_user_id(); ?> 
    });
</script>
    
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','★コンテナスニペットを埋める★');</script>
<!-- End Google Tag Manager -->
```
\#14行目にはご自身のGoogleタグマネージャーのスニペットを指定してください。

5行目の`’uid’ : <?php echo get_current_user_id(); ?> `の部分にて、変数uidに対してページアクセスしているユーザのWordPress上のユーザIDを渡すようにしています。

無事に設定が終えたあと、[オーディエンス] → [ユーザエクスプローラ]を選択すると、以下のようにユーザID毎のログが出力されるようになります。

ユーザエクスプローラへのログ反映はほぼタイムラグもないため、数分立ってもログが出力されない場合は設定が間違っている可能性が高いので見直しを行ってください。


![ga_user_id.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/b464f21a-22d5-0987-cbb3-58656aa7f016.jpeg)

なお、それぞれのIDのリンクをクリックすると、ユーザごとに履歴をトラッキングすることができます。

![ga_user_id_track.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/0013a6ae-dad1-fa10-dcf6-e24e2fcb1477.jpeg)

**（参考）デバッグ用ツール**
Chromeの拡張機能である、[Tag Assistant (by Google)](https://chrome.google.com/webstore/detail/tag-assistant-by-google/kejbdjndbnbjgmefkgdddjlbokphdefk?hl=ja&gclid=CjwKCAjw7IbaBRBqEiwA6AyZgjGVojxLR2JEgcJQc8YvLb9ttuWZ7RGKRaXUO-I14rGy1ZIa2J8uvhoC5qQQAvD_BwE) をブラウザに入れておくと、User IDが意図するとおりに取得できているかなど確認できるので作業が捗るかもしれません。行き詰まったらまず入れてみてください。
初投稿です。これから０からプログラミングを学ぶおじさんの決意

ども。
本当に自分がダメで。
なんとか社会復帰したいです。
家でずっと暗い気持ちでいたりするのですが、
すこしだけ勇気をだして自分にも出来る事を考えて行きたいです。

今日わかった事。

プログラムには種類がある。
①ガチ系
　C、C＃、C＋＋、Java
②Web系
　HTML、CSS、Javascript
③サーバー系
　Ruby、PHP、
④アプリ系
　Swiftとか
⑤その他
　photoshop、イラストレーター、ライター、絵、写真、営業、工程管理

文章や学習記録はQiitaへ。
　　
Atcodar（競技プログラミング）がある。C++がいいらしい？
　色で実力を証明する。次回は土曜の２１時。とりあえず参加する。

学習方法
　書籍
　学習サイト（いまコロナで無料になってたりする）
　スクール（半年５０万円。現役プログラマーと話できたり転職の案内有り？）

とりあえず学習サイトで基本をやってみるつもり。
　ドットインストール
　paiza
　progate
　N予備校（より実践的らしい）
　子供のためのScratchでもいいのかもしれない。
カタカナから母音のカナに変換する【python】

#概要
「コンニチハ->オンイイア」みたいに、カタカナ文字列を入力したら、その母音を返す関数を作りました。
#変換ルール
「ン」「ッ」はそのままにする（例：ルンパッパ -> ウンアッア）
「ー」（長音）は直前の母音と同一にする（例：コーラ -> オオア）
「ゥ」は直前のカナが「ト」「ド」の場合、それと合わせて一つの文字とみなし、大文字と同じく扱う（例：ドゥッキ -> ウッイ、ゥアア -> ウアア）
「ャ」「ェ」「ョ」は直前がカナがイ段の場合、直前のカナと合わせて一つの文字とみなし、それ以外の場合は大文字と同じく扱う。（例：キャタツ -> アアウ、キェェ -> エエ）
「ュ」は直前のカナがイ段、「テ」「デ」の場合、それと合わせて一つのカナとみなし、それ以外の場合は大文字と同じく扱う（例：チュール -> ウウウ、デュワー -> ウアア）
「ヮ」「ァ」「ェ」「ォ」は直前のカナがウ段の場合、それと合わせて一つのカナとみなし、それ以外の場合は大文字と同じく扱う。（例：ウェーイ -> エエイ）
「ィ」は直前のカナがウ段、「テ」「デ」の場合、それと合わせて一つのカナとみなし、それ以外の場合は大文字と同じく扱う（例：レモンティー -> エオンイイ、ィエア -> イエア）
カタカナ以外の文字はそのままにする。
#環境
Google Colaboratory（2020年3月27日時点）およびmacOS Catalina, Python3.8.0での実行を確認しています。
#コード

```Python
def kana2vowel(text):
    #大文字とゥの変換リスト
    large_tone = {
        'ア' :'ア', 'イ' :'イ', 'ウ' :'ウ', 'エ' :'エ', 'オ' :'オ',
        'ゥ': 'ウ', 'ヴ': 'ウ',
        'カ' :'ア', 'キ' :'イ', 'ク' :'ウ', 'ケ' :'エ', 'コ' :'オ',
        'サ' :'ア', 'シ' :'イ', 'ス' :'ウ', 'セ' :'エ', 'ソ' :'オ',
        'タ' :'ア', 'チ' :'イ', 'ツ' :'ウ', 'テ' :'エ', 'ト' :'オ',
        'ナ' :'ア', 'ニ' :'イ', 'ヌ' :'ウ', 'ネ' :'エ', 'ノ' :'オ',
        'ハ' :'ア', 'ヒ' :'イ', 'フ' :'ウ', 'ヘ' :'エ', 'ホ' :'オ',
        'マ' :'ア', 'ミ' :'イ', 'ム' :'ウ', 'メ' :'エ', 'モ' :'オ',
        'ヤ' :'ア', 'ユ' :'ウ', 'ヨ' :'オ',
        'ラ' :'ア', 'リ' :'イ', 'ル' :'ウ', 'レ' :'エ', 'ロ' :'オ',
        'ワ' :'ア', 'ヲ' :'オ', 'ン' :'ン', 'ヴ' :'ウ',
        'ガ' :'ア', 'ギ' :'イ', 'グ' :'ウ', 'ゲ' :'エ', 'ゴ' :'オ',
        'ザ' :'ア', 'ジ' :'イ', 'ズ' :'ウ', 'ゼ' :'エ', 'ゾ' :'オ',
        'ダ' :'ア', 'ヂ' :'イ', 'ヅ' :'ウ', 'デ' :'エ', 'ド' :'オ',
        'バ' :'ア', 'ビ' :'イ', 'ブ' :'ウ', 'ベ' :'エ', 'ボ' :'オ',
        'パ' :'ア', 'ピ' :'イ', 'プ' :'ウ', 'ペ' :'エ', 'ポ' :'オ'
    }

    #ト/ド+'ゥ'をウに変換
    for k in 'トド':
        while k+'ゥ' in text:
            text = text.replace(k+'ゥ','ウ')
    #テ/デ+ィ/ュをイ/ウに変換
    for k in 'テデ':
        for k2,v in zip('ィュ','イウ'):
            while k+k2 in text:
                text = text.replace(k+k2,v)

    #大文字とゥを母音に変換
    text = list(text)
    for i, v in enumerate(text):
        if v in large_tone:
            text[i] = large_tone[v]
    text = ''.join(text)

    #ウーをウウに変換
    while 'ウー' in text:
        text = text.replace('ウー','ウウ')

    #ウ+ヮ/ァ/ィ/ェ/ォを母音に変換
    for k,v in zip('ヮァィェォ','アアイエオ'):
        text = text.replace('ウ'+k,v)
    
    #イー/ィーをイイ/ィイに変換
    for k in 'イィ':
        while k+'ー' in text:
            text = text.replace(k+'ー',k+'イ')

    #イ/ィ+ャ/ュ/ェ/ョを母音に変換
    for k,v in zip('ャュェョ','アウエオ'):
        text = text.replace('イ'+k, v).replace('ィ'+k, v)
    
    #残った小文字を母音に変換
    for k,v in zip('ヮァィェォャュョ','アアイエオアウオ'):
        text = text.replace(k,v)
    
    #ー（長音）を母音に変換する
    for k in 'アイウエオ':
        while k+'ー' in text:
            text = text.replace(k+'ー',k+k)
    
    return text
```
Google Apps Scriptを用いたSQL Serverへの接続方法【取得レコードをスプレットシートへコピー】

`Microsoft SQL Server`へGAS（Google Apps Script）を用いてアクセスして、Select結果をスプレットシートへコピーしてくる一連の流れをまとめています。


#GASを用いたSQL Serverへの接続方法
MicrosoftのSQL SeverへGASから接続したいなと思いまして、[GASのリファレンス（JDBC）](https://developers.google.com/apps-script/guides/jdbc)を調べてみると`Google Cloud SQL`、`MySQL`、`Microsoft SQL Server`、`Oracle databases`はサポートされているようでした。

ただ、SQLサーバーへの接続をしている、参考サイトが見つからなかったので試しにつないでみて、実際繋げましたよという報告です。

#Microsoft SQL Sever接続のスクリプト
ということで、公式のリファレンスの転用になりますが、以下の通りで接続することができました。JDBCでSQL Serverとのコネクションを張って、データをSelectしています。その結果は、予め用意しておいたスプレットシートへコピーするようにしています。

`データベース情報`、`クエリ`、`結果を出力するスプレットシートのID`は各自で設定するようにしてください。

```js:script.js
function SQLdb() {

    function readFromTable() {
      
    // データベースへの接続情報を記載
    var user = '【ユーザ情報を指定】';
    var userPwd = '【パスワードを指定】';
    var database = '【データベース名を指定】';
    var host_name = '【ホスト名を指定】';
    var port = '【ポート名を指定】';
    
    var connectionString = 'jdbc:sqlserver://'+host_name+':'+port+';databaseName='+database;
    
    // JDBCでデータベースへのコネクション確立
    var conn = Jdbc.getConnection(connectionString , user, userPwd);
    
    // 処理の開始時間を取得
    var start = new Date();
  
    var stmt = conn.createStatement();
      
    // デバッグ用（レコードの最大取得件数を指定できます。）
    stmt.setMaxRows(5);
  
    // クエリの実行
    var results = stmt.executeQuery("SELECT 【...クエリを指定】");
    
    // カラムの数を取得
    var numCols = results.getMetaData().getColumnCount();
  
    // 以下、スプレットシートへの結果のコピー処理
    var sheet = SpreadsheetApp.openById('【結果出力先のシートidを指定】').getSheets()[0];
    var cell = sheet.getRange(1,1);
    var row =0;
    
    // データのヘッターを指定（フィールド名）
    var fields=["id","name","price"];
    for(var i=0;i<fields.length;i++){
      //value[i]=values[i];
      cell.offset(row, i).setValue(fields[i]);
      Logger.log(fields[i])
    }
    
    row++;
      
    // クエリの結果をコピー
    while (results.next()) {
      var rowString = '';
      for (var col = 0; col < numCols; col++) {
        rowString += results.getString(col + 1) + '\t';
        cell.offset(row, col).setValue(results.getString(col +1 ));
      }
      row++
    }
    
    results.close();
    stmt.close();
  
    // 終了時刻の取得と、実行時間のログ出力
    var end = new Date();
    Logger.log('Time elapsed: %sms', end - start);
      
   }
   readFromTable();
  }
```

**（参考）スプレットシートへの出力結果**
出力件数はstmt.setMaxRows(5)で5件に指定しているため、5つのレコードを取得することができました。

<img width=50% alt="Screen-Shot-2019-12-08-at-17.44.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/00c134f0-c0c0-9e84-18c7-57f620739e43.png">


スクリプトで指定するスプレットシートのIDですが、スプレッドシートのURLの中の以下下線太文字部分となります。（下記では、IDの部分をダミー値にしています。）

>https://docs.google.com/spreadsheets/d/1P8UmWe1397llBlC0-EcYiSs2ds_psCdhodJT4dtjIdk/edit#gid=0

---
ということで、GASを用いたMicrosoft SQL Serverへの接続方法の説明でした。スプレットシートを用いるとサーバレスなデータベースっぽく扱うこともできるので重宝しています。よかったら参考にしてみてください。
ビルドをバッチ化

# 経緯

複数PJ間でSQLや設定等の一部のファイルを変えてツールを使いまわす際に
ミスなくビルドしたいので。

PJごとに分けて管理する方が良いと思うが、現状そこまで口出しできないので仕方ない。
以下SQLだけ差し替えたいな場合。

## メモ
* batから実行するようにしてもslnに設定したビルド前後イベントは反映できる。
* 

## ビルド前イベント
```Batch:
IF EXIST "$(TargetDir)SQL\" (
rd  /s /q $(TargetDir)SQL
)
```

## ビルド後イベント
```Batch:
xcopy /D /S /R /Y /I /K $(SolutionDir)SQL\*.* $(TargetDir)SQL\
```

## ビルドバッチ本体
```Batch:build.bat
set /p type= PLEASE TYPE SWITCH NO:

del /Q .\SQL\*.*

if %type%==1 ( 
	xcopy PAT1_SQL\*.sql SQL\ 
) else if %type%==2 ( 
	xcopy PAT2_SQL\*.sql SQL\ 
) else ( 
	echo do nothing
)

rem set VsDevCmd.bat
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"

rem build b MSBuild cmd
cd %~dp0
MSBuild .\buildtest.sln /t:clean;rebuild /p:Configuration=Release;Platform="x86"

pause

```
brew caskでフォントを入れる方法 #homebrew

#brew caskでフォントを入れる方法
`brew cask`でフォントを入れようとしたら...

```
λ brew cask install font-hasklig
Updating Homebrew...
Error: Cask 'font-hasklig' is unavailable: No Cask with this name exists.
```

怒られました...

調べると, [この記事](https://qiita.com/st44100/items/f3c5d9923145f555cf85)にあるように`brew tap`しないといけないらしい.

```
brew tap caskroom/fonts
Updating Homebrew...
Error: caskroom/fonts was moved. Tap homebrew/cask-fonts instead.
```

続・怒られました...

言われた通り`brew tap homebrew/cask-fonts`に修正して再度`tap`します.

```
λ brew tap homebrew/cask-fonts
Updating Homebrew...
==> Tapping homebrew/cask-fonts
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask-fonts'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 32835 (delta 4), reused 0 (delta 0), pack-reused 32823
Receiving objects: 100% (32835/32835), 5.57 MiB | 615.00 KiB/s, done.
Resolving deltas: 100% (23829/23829), done.
Tapped 947 casks (996 files, 7.2MB).
```

おっ！

では念願の...

```
λ brew cask install font-hasklig
Updating Homebrew...
==> Downloading https://github.com/i-tu/Hasklig/releases/download/1.1/Hasklig-1.1.zip
==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws.com/1848782
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'font-hasklig'.
==> Installing Cask font-hasklig
==> Moving Font 'Hasklig-SemiboldIt.otf' to '/Users/***/Library/Fonts/Hasklig-SemiboldIt.o
==> Moving Font 'Hasklig-BlackIt.otf' to '/Users/***/Library/Fonts/Hasklig-BlackIt.otf'.
==> Moving Font 'Hasklig-Bold.otf' to '/Users/***/Library/Fonts/Hasklig-Bold.otf'.
==> Moving Font 'Hasklig-BoldIt.otf' to '/Users/t***/Library/Fonts/Hasklig-BoldIt.otf'.
==> Moving Font 'Hasklig-ExtraLight.otf' to '/Users/***/Library/Fonts/Hasklig-ExtraLight.o
==> Moving Font 'Hasklig-ExtraLightIt.otf' to '/Users/***/Library/Fonts/Hasklig-ExtraLight
==> Moving Font 'Hasklig-It.otf' to '/Users/***/Library/Fonts/Hasklig-It.otf'.
==> Moving Font 'Hasklig-Light.otf' to '/Users/***/Library/Fonts/Hasklig-Light.otf'.
==> Moving Font 'Hasklig-LightIt.otf' to '/Users/***/Library/Fonts/Hasklig-LightIt.otf'.
==> Moving Font 'Hasklig-Medium.otf' to '/Users/***/Library/Fonts/Hasklig-Medium.otf'.
==> Moving Font 'Hasklig-MediumIt.otf' to '/Users/***/Library/Fonts/Hasklig-MediumIt.otf'.
==> Moving Font 'Hasklig-Regular.otf' to '/Users/***/Library/Fonts/Hasklig-Regular.otf'.
==> Moving Font 'Hasklig-Semibold.otf' to '/Users/***/Library/Fonts/Hasklig-Semibold.otf'.
==> Moving Font 'Hasklig-Black.otf' to '/Users/***/Library/Fonts/Hasklig-Black.otf'.
🍺  font-hasklig was successfully installed!
```

やったぜ！
Retrofit データクラスで地味にハマったこと

## 前提

APIは仮に以下のようにします。

```json
{
  "items": [
     {
        "id": 100,
        "number": 10,
        "content": "sample",
        "created_at": "2020/03/26 21:30",
        "updated_at": "2020/03/26 21:30"
     }
  ],
  "delete_questions": [
    {"id": 10}
  ],
  "status": "ok"
}

```


今まで毎回同じフォーマットで帰ってくるAPIのレスポンスデータしか扱って来なかったので、データモデルといえば以下のように実装していました。


```kotlin
data class Item {
    val items: List<ItemInfo>,
    @Json(name = "delete_items")val deleteItems: List<DeleteItemInfo>,
    val status: Int
}
```


## APIのフォーマットがレスポンスによって変わる場合


ところが実際にはAPIのレスポンスとしては以下のような場合もあるとします。

```json
{
  "items": [
    {
      "id": 1,
      "number": 1,
      "content": "sample",
      "created_at": "2020/03/26 21:30",
      "updated_at": "2020/03/26 21:30"
    },
    {
      "id": 2,
      "number": 2,
      "content": "sample",
      "created_at": "2020/03/26 21:30",
      "updated_at": "2020/03/26 21:30"
    }
  ],
  "status": "ok"
}
```

このようにdelete_itemsはあったりなかったりするAPIレスポンスの場合、上記のデータモデルではdeleteItemsがnullになりエラーとなりアプリが落ちてしまいます。

その場合、データモデルを以下のように変更します。

```kotlin
data class Item {
    val items: List<ItemInfo>,
    // deleteItemsをnull許可にする
    @Json(name = "delete_items")val deleteItems: List<DeleteItemInfo>?,
    val status: Int
}
```

これでレスポンスにdelete_itemsが含まれていても、いなくても、問題ありません。

自分だけかもしれませんが、データクラスの型にnull許可にするというのがあまり意識したことがありませんでした。
Scope(スコープ)

#Scope(スコープ)
インスタンスを保存できる領域。
スコープを経由させることにより、サーブレットクラスとJSPファイルの間でインスタンスを共有させることが可能になる。

##JavaBeans
スコープに保存する再利用しやすくするルールに基づいたクラス(インスタンス)
###直列化
###プロパティ
getter/setter

##リクエストスコープ
レスポンスが返されるまで利用可能
HttpServletRequest

###リクエストスコープにインスタンス生成

```php:記述
request.setAttribute("属性名", インスタンス);
```

###リクエストスコープからインスタンスを取得

```php:記述
取得するインスタンスの型　変数名 = (取得するインスタンスの型) request.getAttribute("属性名");
```

##セッションスコープ
保存インスタンスの有効期限は開発者が設定
リクエストをまたいでの使用可能

###セッションスコープの取得

```php:記述
HttpSession session = request.getSession();
```

###セッションスコープに保存

```php:記述
session.setAttribute("属性名", インスタンス);
```

###セッションスコープからインスタンスを取得

```php:記述
取得するインスタンスの型　変数名 = (取得するインスタンスの型) session.getAttribute("属性名");
```

###セッションスコープからインスタンスを削除

```php:記述
session.removeAttribute("属性名");
```

###セッションスコープを破棄

```php:記述
session.invalidate();
```

##アプリケーションスコープ
アプリケーション終了まで利用可能
高速アクセス

###アプリケーションスコープの取得

```php:記述
ServletContext application = this.getServletContext();
```

###アプリケーションスコープに保存

```php:記述
appliction.setAttribute("属性名", インスタンス);
```

###アプリケーションスコープからインスタンスを取得

```php:記述
取得するインスタンスの型　変数名 = (取得するインスタンスの型) application.getAttribute("属性名");
```

###アプリケーションスコープからインスタンスを削除

```php:記述
application.removeAttribute("属性名");
```
Qiitaからはてなブログに記事を一括インポートする

# 

![](https://i.imgur.com/ha0ETUm.jpg)

## 手順
1. [tenntenn/qiitaexporter](https://github.com/tenntenn/qiitaexporter) でQiitaの記事のmarkdownソースをダウンロードする
2. [x\-motemen/blogsync](https://github.com/x-motemen/blogsync) ではてなブログにpostする

## Qiitaの記事のmarkdownソースをダウンロードする

Qiitaの記事はURL末尾を `.md` にすることでmarkdown形式のテキストを返すAPIがあるため簡単なスクレイピングツールで手元にダウンロードしてこられます。

今回はtemplateを注入を利用してblogsync書式にするのがやりやすいためqiitaexporterを使いました(Qiita API v2を使って記事を取得してきます)。

Qiita記事をダウンロードするツールは他にもいくつか候補があります(例: [qiita\_export\_all](https://github.com/yumetodo/qiita_export_all))ので、必要に応じて代替策を講じてください。

qiitaexporterには画像ファイルをダウンロードして自分でホストできるようにimgタグを自動で書き換える機能があるのですが、はてなブログへの画像アップロードを実現するのが大変そうだったので、今回はタグの書き換えを無視するオプションを自分で追加しました。

```bash
git clone https://github.com/laiso/qiitaexporter.git
cd qiitaexporter/
go build
```

あとは [qiitaexporter](https://github.com/tenntenn/qiitaexporter) のREADMEに従いmarkdownファイルをダウンロードしてください。

書き出されるmarkdownファイルの形式を `blogsync.template` というファイルに定義します

```yaml
# blogsync.template
---
Title: {{.Title}}
Date: {{.Date}}T00:00:00+09:00
---

**この記事は[Qiita]({{.URL}})の記事をエクスポートしたものです。内容が古くなっている可能性があります。**

{{.Body}}
```

```bash

export QIITA=XXX
./qiitaexporter -imgignore -template blogsync.template
ls posts/
```

※前述のとうり`-imgignore` オプションはフォークで追加したものです

## はてなブログにpostする

[blogsync](https://github.com/x-motemen/blogsync#%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%82%92%E6%8A%95%E7%A8%BF%E3%81%99%E3%82%8Bblogsync-post) にはファイルを指定してはてなブログへ記事を投稿する機能があります。これを使いQiitaからダウンロードしたmarkdownファイルを指定して一括投稿します。

blogsync自体のセットアップはREADMEに従ってください。はてなブログの編集モードはあらかじめMarkdownモードに設定しておきます。

```bash
export BLOGURL=XXX.hatenadiary.jp
find posts -name "*.md" | xargs -I $ sh -c "blogsync post ${BLOGURL} < $"
```

一括投稿する前に `blogsync post ${BLOGURL} < posts/SOME.md` で1記事だけ試してみるとよいです。

## 免責事項
- 移行後も記事内の画像URLはQiitaのサーバー(Amazon S3)を参照しています
- blogsyncで大量にブログ記事を投稿するとロールバックがたいへん(新規記事として投稿される)なので検証環境を作ることをおすすめします