OmniAICreator/Qiita-1.07M huggingface dataset:
Slick+MySQLでdatetimeやtimestampをjava.time.*に変換したい【Slick3.3以降】

# はじめに
この間怒りに任せてあげた[Slickでいつの間にかjava.time.*がサポートされてた話](https://qiita.com/lightstaff/items/773ff36275c6e368178b)ではMySQLの`datetime`や`timestamp`は`java.time.LocalDateTime`に相互変換されませんって話でした。
しかも以前はサポート対象外だったおかげて暗黙の変換を書いておけば問題なかったんですが、3.3以降、自分の環境では`java.time.*`系の変換を書いちゃうとどっかで衝突すんのかコンパイルが通らなくなってしまいました（上記前記事参照）。

という訳で今回はどうにかして変換できるようにしてみます。

## 環境
scala: 2.12
slick: 3.3

# 型を作ってしまおう
しょうがないので間に型を咬ませます。
代表して`datetime`をサポートしてみます。

```scala
case class MySQLDateTime(value: String) {

 def toLocalDateTime: LocalDateTime =
    LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
}
```

回りくどい気もしますが、値として`datetime`を`String`で保持し、`LocalDateTime`として出力できるようにしています。

# テーブルではこんな感じ


```scala
class TestTable(tag: Tag) extends Table[Test](tag, "test") {
  // 抜粋
  def testDate = column[MySQLDateTime]("test_date")
  // 抜粋
}

```

このままでは当然`MySQLDateTime`型は変換できないのでコンパイルは通りません。

# 暗黙の変換
上記テーブルに下記の暗黙の変換を追加します。

```scala

implicit lazy val mySqlDateTimeType: JdbcType[MySQLDateTime] with BaseTypedType[MySQLDateTime] =
  MappedColumnType.base[MySQLDateTime, java.sql.Timestamp](
    t => java.sql.Timestamp.valueOf(t.value),
    u => MySQLDateTime(u.toLocalDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
  )

```

テーブルからは`java.sql.Timestamp`として受けて相互変換可能としています。`DateTimeFormatter...`云々はどこぞに固定値として生やした方が良いでしょう。

# おわりに
`timestamp`や`date`、`time`も同様に書くことができると思います。
VuforiaのImageMarkerをターゲットにする場合に認識精度を上げるためのTips

今時マーカーよりもマーカーレスな世の中ですが、VR空間で手に持つ物体のトラッキングなど限定された環境下ではマーカーの方が扱いやすい場合があります。そういったときの設定の仕方をまとめています。
主に以下の抄訳です。

## 参考
Image Targets
https://library.vuforia.com/content/vuforia-library/en/articles/Training/Image-Target-Guide.html

Optimizing Target Detection and Tracking Stability
https://library.vuforia.com/articles/Solution/Optimizing-Target-Detection-and-Tracking-Stability.html

サポートされる画像：JPG,PNGでグレースケールもしくはRGB。サイズは2MB以下
Unityで自身のプロジェクトに入れる方法は以下が分かりやすいです。

https://qiita.com/takako_sudou/items/ec2081cc4d9c4abb1c8f

主にWebカメラなどで撮影するので周辺の環境はほどよく明るくスポットライトのような一部に光が集中しているよりも拡散している方がよいです。

## Extended Trackingとは
これは、マーカーの周囲の特徴も使ってARカメラのトラッキングを行うモード出会って、ARマーカーを動かして使いたいときには必ずOffにする。

アップロード時の画像は横幅320ピクセル以上を推奨。320ピクセル以下だとアップロード後にサーバーサイドでスケーリングが行われて画像の持つ特徴量が減ってしまうことがあります。

### 画像のレーティング
画像は1から5つ星でレーティイングされますが、細かいものが写っていること、コントラストが良好なこと、繰り返しパターンがないことがレーティングの基準となっています。

### トラッキング用カメラの設定
カメラは常にピントが合うことが重要なのでコンティニュアスオートフォーカスモードがあればそれを使うこと。VuforiaでもAPIを提供しているので以下を参照のこと。
https://library.vuforia.com/articles/Solution/Working-with-the-Camera.html

カメラと対象のターゲットとの距離を10で割ると印刷する画像の最小サイズを見積もることが出来ます。例えば距離が2Mであれば20CM幅必要になるということです。もちろん目安なので実際に試してみることが重要です。


以下のサイトとかでprofiles.xmlを設定してるけどインポートしただけでは存在しないし、入れても反映しない。今は無効化されてる？
https://gitlab.cs.ucl.ac.uk/vania/team27website/blob/d8e1335d1a77dd9a6ce215ada1b08e0bd479e51a/project/Assets/Vuforia/Editor/WebcamProfiles/profiles.xml

フォーラムの以下に回答がありました。ファイルの場所と名前が変わっているようです。現在は「webcamprofiles.xml」が以下のフォルダに入っています。（2017.4.1f1現在）
Unity\Editor\Data\PlaybackEngines\VuforiaSupport\VuforiaResources
【WordPress】特定の期間内に投稿された記事、更新された記事を取得する方法

特定の期間に投稿&更新された記事の取得方法を備忘録として書いていきます。

## 記事取得にはget_posts()を利用する

今回は、`get_posts()`を利用して期間内の投稿データを取得します。`query_posts()`は非推奨なので利用しないようにしましょう。

### `query_posts()`が非推奨な理由

get_posts() は単にデータを取得するだけで、グローバル変数`$wp_query`には影響を与えないのに対して、query_posts() はグローバル変数`$wp_query`を変更します。つまりメインループに影響を与えるということです。なので、`wp_reset_query()`の記述を忘れると、他のページのクエリも書き換わってしまうなどの意図しない結果が表示される危険性があったりします。
現在は、サブループでは`WP_Query()`か`get_posts()`を使うことが強く推奨されています。

## 特定期間に投稿された記事取得

特定の期間内に投稿されたデータを取得するには、`date_queryパラメータ`を利用します。`date_queryパラメータ`の値に配列で情報を付与することで期間内のデータを取得することができます。

```php
<?php
//パラメータを指定
$args = array(
    'posts_per_page' => 10, //記事を10件表示
    'date_query' => array(
        'after' => '2019-1-1',
        'before' => '2019-2-28',
        'inclusive' => true //afterとbeforeに指定した日を含めるかどうか
     )
);
//get_posts()を使って投稿データの配列を取得
$period_posts = get_posts($args);

foreach ($period_posts as $period_post): setup_postdata($post);
?>
    <h3><?php the_title(); ?></h3>
<?php
endforeach; 
//メインクエリの投稿データを復元
wp_reset_postdata(); 
?>
```

## 特定期間に更新された記事取得

特定の期間内に更新されたデータを取得するには、条件の連想配列に`column`キーとして`post_modified`を指定すればいい形となります。
ちなみに、`column`には下記の6つの値が指定できるようです。

- post_date（デフォルト値）
- post_date_gmt
- post_modified
- post_modified_gmt
- comment_date
- comment_date_gmt


```php
<?php
//パラメータを指定
$args = array(
    'posts_per_page' => 10, //記事を10件表示
    'date_query' => array(
        'after' => '2019-1-1',
        'before' => '2019-2-28',
        'column' => 'post_modified', //更新日時を検索対象に指定
        'inclusive' => true //afterとbeforeに指定した日を含めるかどうか
     )
);
//get_posts()を使って投稿データの配列を取得
$period_posts = get_posts($args);

foreach ($period_posts as $period_post): setup_postdata($post);
?>
    <h3><?php the_title(); ?></h3>
<?php
endforeach; 
//メインクエリの投稿データを復元
wp_reset_postdata(); 
?>
```
ssh ProxyJump と DynamicForward でシアワセな接続ライフを掴みとる

こんにちは。シアワセですか? 笑顔でお仕事してますか?
ワタクシは元気です。牛丼は大盛りです。


## 概要
接続制限のある環境には ProxyJump と DynamicForward を使おう


## ProxyJump
出尽くした感のあるサーバへの SSH 接続時の TIPS ですが、接続制限のある場合などの踏み台設定がより簡単になっています。
やっておくと便利なのでオススメです。

```
Host dest dest-via-ext
  HostName ssh.example.net
  User user
  Port 22

Host *-via-ext
  Protocol 2
  ProxyJump doday
  ProxyCommand ssh -W %h:%p doday

Host doday
  HostName relay.example.com
  Protocol 2
  User user
  TCPKeepAlive yes
  IdentitiesOnly yes
  ForwardAgent yes

  DynamicForward localhost:5963
```

こんな設定しておけば、

```
$ ssh dest-via-ext
```

ってやれば踏み台サーバ(doday)経由で接続してくれます。

`ProxyCommand ssh -W ...` でも十分シアワセなのですが、イマドキの ssh クライアントであれば ProxyJump という設定ができます。
とくにこれ、コマンドラインオプションである -J を用いて

```
$ ssh -J doday another-destination.example.org
```
とかその場で書けるので今まで以上に接続がカンタンにできるようになっております。超シアワセ
カンマ区切りで多段プロクシも乗り越えてくれる。弩シアワセ

ちなみに ProxyJump 定義を ProxyCommand 定義よりも先に書いておけば ProxyJump 定義が使用されます。
なお、踏み台サーバの sshd_config で `AllowTcpForwarding=no` されているとダメです。
ProxyJump 定義も ProxyCommand 定義もこの設定では使用できませんので、なにか別なシアワセのカタチを見つける必要があります...


## DynamicForward
踏み台を使うということは ウェブの確認なんかも制限されていることが多いので、
そんな場合には Chrome の Proxy SwitchyOmega というプラグインが便利です。

このプラグインを利用すれば、ウェブの確認が踏み台サーバ経由でできます。
詳しい設定方法は他のサイトさまにお任せするとして... こんな感じで...
![xb_01.png](https://qiita-image-store.s3.amazonaws.com/0/356520/47d183bc-2286-358d-3580-5811e2a4e94e.png)
> Profile :: proxy > Proxy servers
>>  Protocol: SOCKS5
  Server: localhost
  Port: 5963

![xb_02.png](https://qiita-image-store.s3.amazonaws.com/0/356520/21620d63-e780-f113-3166-28b5fccaf614.png)
> Profile :: auto switch > Switch rules
>> Condition Type: Host wildcard
  Condition Details: *.example.net
  Profile: proxy

とかで登録します。

そのうえで画面上部のナビのところで `auto switch` にしておけば、よりシアワセになれることでしょう。
![capt_pso_003_02.png](https://qiita-image-store.s3.amazonaws.com/0/356520/14769348-e4b3-35b6-6bd3-484bc13394d4.png)


この状態で Chrome から www.example.net にアクセスすると
先ほどの ssh_config の `DynamicForward localhost:5963` の箇所が使われて踏み台経由となります。
このおまじないであなたのSSH接続は SOCKS proxy にもなりました。あらまぁなんとゆうことでしょう。

`DynamicForward` 設定は SOCKS プロトコルに対応していればいいので、
やんごとなき理由で FTP する場合などでも lftp とかがあればシアワセに暮らすことができます。

## 参照
- man page ssh_config section 5
https://euske.github.io/openssh-jman/ssh_config.html

- OpenSSH/Cookbook/Proxies and Jump Hosts
https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts

- Proxy SwitchyOmega
https://github.com/FelisCatus/SwitchyOmega

----
### We're hiring!
AIチャットボットを開発しています。
ご興味ある方は<a href="https://www.wantedly.com/projects/284955">Wantedlyページ</a>からお気軽にご連絡ください！
Pythonで部分的なコードの実行時間を測る

Pythonで部分的なコードの実行時間を知りたい時のtipsです。
すぐに忘れるので、メモを兼ねて共有します。

## 実装
まず、contextmanagerでデコレーターを作っておきます。

``` py
from contextlib import contextmanager
import time

@contextmanager
def timer(title):
    start = time.time()
    yield
    print("{} - done in {:.3f}s".format(title, time.time() - start))
```

### 使い方

``` py
with timer('hello world'):
    # 処理
```

関数内に関数を定義して、ラッパーを用いることでも実装できるのですが、
contextlibのcontextmanagerを使うことでより簡潔になります。

デコレータ内の「yield」でwithステートメント内の処理が実行されて、時間を計測できるようになっています。
部分的なコードの実行時間を測りたい時に便利なので、使ってみてください。
Kotlin 1.3のCoroutineのキャンセル②（協力的なキャンセル）

# 検証環境
この記事の内容は、以下の環境で検証しました。

* Intellij IDEA ULTIMATE 2018.2
* Kotlin 1.3.0
* Gradle Projectで作成
* GradleファイルはKotlinで記述（KotlinでDSL）

# 準備
詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa

# Cancellation is cooperative
[前回](https://qiita.com/naoi/items/8b2d9747d07eff2778d6)に引き続き、[公式サイト](http://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#cancellation-is-cooperative)を読み解いていきます。

今回のタイトルは日本語にすると意味がわかりません。
内容を理解すれば、理解できるかもしれません。
早速読み進めます。

> Coroutine cancellation is cooperative. A coroutine code has to cooperate to be cancellable. 
>All the suspending functions in kotlinx.coroutines are cancellable. 
>They check for cancellation of coroutine and throw CancellationException when cancelled. However, if a coroutine is working in a computation and does not check for cancellation, then it cannot be cancelled, like the following example shows:

訳してみると

> コルーチンはキャンセルに処理に対して協力的です。また、コルーチンのコードはキャンセルに対して、協力的でなければなりません。
> kotlinx.coroutinesパッケージに存在するすべてのsuspend関数はキャンセルできます。
>それらの関数はキャンセル状態かどうかを常にチェックしています。キャンセルが発生するとCancellationException例外が発生します。
>しかし、コルーチンで、計算処理の最中などの場合は、キャンセルができません。

なるほど、タイトルの本質は、コルーチンに関する関数は常にキャンセルされているかチェックしているから、キャンセルに対応できている（協力できている）という意味だったんですね。

でも、キャンセル出来ない場合もあるそうで、そのサンプルコードも掲載されているので確認してみます。

```kotlin
fun main() = runBlocking {
    //sampleStart
    val startTime = System.currentTimeMillis()
    val job = launch(Dispatchers.Default) {
        var nextPrintTime = startTime
        var i = 0
        while (i < 5) { // computation loop, just wastes CPU
            // print a message twice a second
            if (System.currentTimeMillis() >= nextPrintTime) {
                println("I'm sleeping ${i++} ...")
                nextPrintTime += 500L
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
//sampleEnd
}
```

実行結果

```text
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
main: I'm tired of waiting!
I'm sleeping 3 ...
I'm sleeping 4 ...
main: Now I can quit.
```

前回との大きな違いはrepeat関数を使わずにwhile文を使用しているため、キャンセルのチェックが行われていません。while文は確かに通常の計算処理と同じため、キャンセル出来ていない事が確認できます。

公式サイトには、最後にこんな一文が載っています。

> Run it to see that it continues to print "I'm sleeping" even after cancellation until the job completes by itself after five iterations.

訳してみると

> 実行し見ると、コルーチンはキャンセルされているにもかかわらず、ジョブが完了するまで、表示をしているね。

確かにそのとおりです。

# まとめ
このブロックで理解できたことは以下のことだと思います。

* kotlinx.coroutinesパッケージ内の関数はキャンセルをチェックしていること
* 上記以外はチェックしていないこと
Avast!のせいでAlexa Devceloper ConsoleのAlexaシミュレータが動かない件

ブラウザを変えて(Firefox,Chrome,Safari)もうまく動作しなかったので
サポートに聞いてみた

> ファイヤウォール、アンチウィルスソフト、ブラウザのプラグインによりHTTP2通信がブロックされている場合、シミュレータが使用できない現象が発生致します。
> 一度他のパソコンにてテストいただけますでしょうか。

と言われた。
確かにメインPCでやると正常に動作する。

Mac で HTTP2が動作しない症状を探してみるとAvast!いれているとダメなようだ。

> https://ah-2.com/2016/09/04/osx_browser_http2.html

ESETに変えよう
[Amazon Connect] 会社の固定電話をLEXを使って個人に転送し、転送できない場合は録音メッセージを残す仕組みを作ってみた～電話番はもう嫌だ！！～

## 1 はじめに

Amazon Connect（以下、Connect）を使用して、会社の固定電話にかかってきた電話をLEXを使って個人に転送して、LEXで個人を認識できない場合は録音メッセージを残してメールで連絡する仕組みを作ってみました。
（会社の固定電話からAmazon Connectへの転送はPBXで設定）

## 2 ユーザシナリオ

ユーザシナリオは以下の通りです。

Connect）お電話ありがとうございます。こちらは〇〇株式会社です。
Connect）お話になりたい担当者の名前を浅野、佐々木、田中のようにおっしゃってください。

＜登録済の担当者の場合＞
User）佐々木さん
Connect）佐々木におつなぎします。
Connect）※個人電話への転送

＜登録されていない担当者の場合＞
User）中田さん
Connect）認識できませんでした。電話を転送させていただきます。
Connect）留守録にメッセージを残していただければ折り返しご連絡させていただきます。
Connect）20秒以内にメッセージをお話しください。
User）※メッセージを録音
Connect）メッセージをお預かりしました。電話をお切りください。
Connect）※S3に通話録音が作成されたらML（Mailing List）へメールで連絡

##3 構成イメージ

全体の構成は以下のようなイメージです。

![概要図.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/e396aad6-bd70-a215-851d-a408e20dad8a.png)

##4 問合せフロー

今回の仕組みでは、2つの問合せフローが使用されています。

1つ目のフローで、代表電話にかかってきた電話をLEXを使って個人に転送して、2つ目のフローでLEXで個人を認識できない場合の録音メッセージを残す仕組みを実装しています。

### ①1つ目の問合せフロー

![フロー1.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/1f5aef29-1c4c-ff8a-ffc6-f0c2943f1601.png)

### ②2つ目の問合せフロー
![フロー2.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/471e2399-4bc4-0d2e-7822-586574e89ac1.png)

##5 LEX設定

LEXは日本語対応していないので、担当者の名前をローマ字で intents に担当者の名前を登録します。
作成したLEXはConnectの問合せフローから呼び出します。

![LEX.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/f9cc1723-b0be-1488-b777-9c647f53a07f.png)

##6 Lambda設定

ConnectからS3に通話録音のファイル（Wavファイル）が保存されたタイミングで、Lambdaを起動するように設定します。

![Lambda1.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/342bf84c-7e46-c739-a755-f1163eecd90b.png)

![Lambda3.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/c9b4f6c8-3f8d-023f-4e10-45cdbf82090d.png)

今回のLambdaはPython3.6で作成してます。SNSのトピック、メッセージ、件名を設定します。

```lambda_function.py
import boto3
import datetime

now = datetime.datetime.today()

sns = boto3.client('sns')
TOPIC_ARN = u'arn:aws:sns:ap-northeast-1:999999999999:xxxxxxxxSendMail'
msg = u'〇〇株式会社の代表電話に通話が録音されました。録音内容を確認してください。\nAmazonS3/connect-xxxxx/connect/xxxxx/CallRecordings'
subject = u'〇〇株式会社の代表電話に通話が録音されました'

def lambda_handler(event, context):
    request = {
    'TopicArn': TOPIC_ARN,
    'Message': msg,
    'Subject': subject
    }
    response = sns.publish(**request)
    return 'Successfully mail processed records'
```

##7 SNS設定

トピックを作成し、サブスクリプションで代表電話のMLにメールを送信する設定を実施します。

![SNS.PNG](https://qiita-image-store.s3.amazonaws.com/0/367936/b3182263-abd5-d0a2-01ba-d57163b9ee26.png)

##8 最後に

今回は、Connectと日本語対応していないLEXを組み合わせて担当者への電話転送する機能、および担当者に転送できない場合の留守録機能を実装しました。

通話録音のファイル（Wavファイル）をGoogle Speech APIなどを用いてテキスト化してメールに添付してあげればわざわざ留守録内容を聞かなくても良くなりますが、そこまでの実装は今後実施していく予定です。

##9 参考にさせていただいたリンク

https://dev.classmethod.jp/cloud/aws/amazon-connect-voice-message/
https://qiita.com/ai-2723/items/dab1df52eda4d57f7539
UnityPurchasing: InitializationFailureReason.PurchasingUnavailable

The official document says that when this error happens it means
>**IAP may be disabled in security settings**: iOS devices only
>**The system purchasing library may be outdated**

My case did not fall into any of the above but simply because *I have not logged into my Google account on the test device yet*.
If you encounter the above error on Android, it may help to check if the Play Store has been set up properly before trying anything else.
PhpStormのBookmarksショートカット

# ブックマークを登録したい

### 方法1

|OS|ショートカットキー|
|:----- |:--------|
|Mac|option + F3|
|Windows/Linux|Ctrl + F11|

任意の行でこのショートカットを使うと0~9またはA〜Zをブックマークとして割り当てることができる。

### 方法2
Toggle Bookmark

|OS|ショートカットキー|
|:----- |:--------|
|Mac|Control + Shift + 0..9|
|Windows/Linux|Control + Shift + 0..9|

この方法でショートカットのみでブックマークを登録できる。

※MacのShiftは　⇧
※MacのCommandは　⌘
※MacのControlは　^
※Macのoptionは　⌥

# 設定したブックマークリストを見たい

|OS|ショートカットキー|
|:----- |:--------|
|Mac|command + F3|
|Windows/Linux|Shift + F11|

これでリストを表示してブックマークへ飛ぶことができる。

# ブックマークに飛びたい

|OS|ショートカットキー|
|:----- |:--------|
|Mac|Control + 0..9|
|Windows/Linux|Control + 0..9|

ショートカットキーだけで飛べる。
Sidekiqで処理待ち、処理中のjobを取得する

`ActiveJob`でqueue adaptorに`Sidekiq`を使ってて、ジョブの状況を確認したいので調査しました :bulb: 

## 環境
sidekiq (5.1.1)


## コード

```rb
# 処理中のjob
workers = Sidekiq::Workers.new
workers.each do |_process_id, _thread_id, work|
  p work
end

# 処理待ちのjob
queues = Sidekiq::Queue.all
queues.each do |queue|
  queue.each do |job|
    p job.klass, job.args, job.jid
  end
end
```

以上です :hugging: 

## 参考
- [ruby on rails - Sidekiq list all jobs [queued + running] - Stack Overflow](https://stackoverflow.com/questions/48348723/sidekiq-list-all-jobs-queued-running)
- [mperham/sidekiq: Simple, efficient background processing for Ruby](https://github.com/mperham/sidekiq)
celeron搭載の低スペックPCでは、本当にプログラミングは出来ないのか？

qiitaの投稿にハマり始めた駆け出しエンジニアです。

今日の投稿は、PCにちょっとだけ知識があった未経験新人エンジニアが実体験した記事です。
普段はPCでネットサーフィンをする位だけど、今回初めてLINUXに挑戦してみるよ！という方向けの記事になります。
プロの方から見たら恥ずかしい内容かもしれませんが、個人的にすごく達成感があったので誰かのお役に立てればと思い投稿してみました。



それでは、低スペックPCでプログラミングは出来ないのか？という課題について解決してみたいと思います。

対象PCスペック
mouse computer製 LB-C240E-S-MA
CPU celeron N3160 64bit
メモリー 3.8GB

プログラミングでは仮想環境を構築することが多いと思いますが、スペック不足で仮想環境が構築できないことがあると思います。
※上記スペックで仮想環境を構築したらPCがフリーズしました…汗笑

ここまでくるにあたり、色々と試してみました↓↓
・fedora(初心者には難しかった)、
・CentOS(上に同じ)、
・Kari Linux(そもそも初心者が手を出してはいけなかった...笑)、
・Linux mint(エディター使用時、chmodでもファイル変更権限が解決できない問題)、
・AWS cloud9(オンライン環境でしか使用できない。でもすごく便利)　

結果、一番しっくりくるのものがUbuntuで最低限のパッケージをインストールする方法でした。


記事の内容では、既存のOSを削除してLINUXのみをインストールしています。windows、macOSは無くなりますのでご注意下さい。


以下方法です。


-手順①LINUXの入手-
-

LINUXのディストリビューション(配布という意味)入手します。
Ubuntu japanese team : https://www.ubuntulinux.jp/

「Ubuntuのダウンロード」と進み、
↓
「日本語Remixイメージのダウンロード」と進み、
↓
「ubuntu-ja-18.04.1-desktop-amd64.iso（ISOイメージ）」をダウンロードさせて頂きました。


-手順②USB起動ディスクの作成-
-

用意するもの
・Rufus　を使用させて頂きました。
　Rufus : https://rufus.ie/
・USBメモリー(手元にあった16GBの物を使いました) 

先ほどのISOファイルを使います。
使い方は製作者様のHPに記載がありますのでここでは割愛します。

ここまでで、Ubuntuの起動ディスク(が入ったUSBメモリー) が完成します。


-手順③BIOSの設定-
-

予め、先ほど作成したUSB起動ディスクを対象のPCにセットしておきます。

次に対象のPCのBIOSを起動します。

今回インストールしたPCは電源を入れた後、F2連打でBIOS画面に移りました。どのボタンを連打するかはPCによって違うみたいです。

初めてBIOSを見ると「大丈夫かな・・」となると思いますが、慣れると面白いです。


BIOS起動後、Bootタブを選びます。

「Boot Option Priorities」という文があり、その下に4行程なにやらあると思います。

これが、起動時に選択をしているところです。

ここを、先ほど作成したUSB起動ディスクから起動できるように設定を変更します。

「enter」で選択した後、USB起動ディスク以外の項目を全て「Disabled」に変えてしまいます。
 
終わりましたら「Save & Exit」タブを選択し「Save Changes and Reset」を選択して「Yes」を押すと再起動します。


-手順④LINUXのインストール-
-
Ubuntuの説明通りにインストールすれば問題なく進めることが出来ると思います。

途中、「フルパッケージを入れるか？最低限のものにするか？」的な事を聞かれます。
今回の対象PCはスペックが低い為、最低限のインストールパッケージを選択しました。

またまた途中で、「現在あるOSを削除します」的な選択が出てくると思います。
今回の記事では既存のOSを削除してLINUXのみをインストールしたいので、
少し緊張しますが、ここで既存のOSに別れを告げ、新たにUbuntuさんを迎える準備をして下さい。

順調にいけばこのまま進めると思います。

インストール完了後、PCログイン画面が表示され、ログインしたら可愛いビーバーさんが表示されていると思います。

これで、USBはもう外して大丈夫です。

-手順⑤BIOSの設定変更-
-

最後に、BISOの設定を元に戻しておきます。

BIOSを起動した後、手順③で設定したUSB起動ディスクを「Disabled」にしておきましょう。
<br>
<br>
これで無事Ubuntuがインストール出来ると思います。

自分はこの低スペックPCにUbuntuをインストールし、Java環境構築とeclipseエディター使い正常に使えています。
新しいハイスペックPCを購入して仮想環境を構築する方法も解決策としてありますが、こういった形で解決するという方法もあります。
(自分はただお金がないだけでしたが・・・笑)

初めての挑戦は何でも怖いです。僕はちょっと前まで右も左も分かりませんでした。
しかし、知らないものに挑戦することに価値があると思います。
出来ないことが出来る様になる、という事はとても楽しい事だと思いますので、
興味のある方は是非挑戦してみてください。
<br>
<br>
<h1>結論「 LINUX は すごく 楽しい。」

※但し、スクール等で勉強中は、仮想環境構築出来るスペックのPCを買った方が効率が良いです。
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
最後に、ここまで協力してくださった方々、ソフトウェアの開発者様にこの場を借りてお礼を申し上げます。
ありがとうございます。
bitcoinjs-lib v4を使ったhdwalletスニペット

# bitcoinjs-lib hdwallet

* 階層的決定性ウォレット
* この記事はbitcoinjs-lib@4系です
* バージョン３系と後方互換性がなくなっています

# v3との簡単な違い

* モジュールの名前空間変更　HDNode -> bip32
* address取得方法の変更
* bip32周りのメソッド名の変更

# install

```sh
npm i bip39 bitcoinjs-lib
```

# mnemonic generate

## 12 word

```js
const mnemonic = bip39.generateMnemonic();
```

## 24 word

```js
const mnemonic = bip39.generateMnemonic(256);
```

# mnemonic to masternode

```js
const mnemonicToM = (mnemonic, password, network) => {
    const seed = bip39.mnemonicToSeed(mnemonic, password || "")
    const m = bitcoin.bip32.fromSeed(seed, bitcoin.networks[network || "bitcoin"])
    return m
}
```

# master extended private key

```js
m.toBase58()
```

# extended private key

```js
m.deriveHardened(44).deriveHardened(0).deriveHardened(0).toBase58()
```

```js
m.derivePath("m/44'/0'/0'").toBase58()
```

# extended public key

```js
m.deriveHardened(44).deriveHardened(0).deriveHardened(0).neutered().toBase58()
```

```js
m.derivePath("m/44'/0'/0'").neutered().toBase58()
```

# bitcoin address

## address

* address生成用のラッパーを作ったほうが楽です

```js
const getAddress = (node) => {
    return bitcoin.payments.p2pkh({ pubkey: node.publicKey }).address
}
getAddress(m.derivePath("m/44'/0'/0'/0/0"))
```

## private key

```js
m.derivePath("m/44'/0'/0'/0/0").toWIF()
```


# とりあえず実行してみる


```js
const bitcoin = require("bitcoinjs-lib")
const bip39 = require("bip39")

const mnemonicToM = (mnemonic, password, network) => {
    const seed = bip39.mnemonicToSeed(mnemonic, password || "")
    const m = bitcoin.bip32.fromSeed(seed, bitcoin.networks[network || "bitcoin"])
    return m
}

const getAddress = (node) => {
    return bitcoin.payments.p2pkh({ pubkey: node.publicKey }).address
}

const mnemonic = bip39.generateMnemonic();
const m = mnemonicToM(mnemonic, '', 'bitcoin')
console.log(mnemonic)
console.log(m.derivePath("m/44'/0'/0'").toBase58())
console.log(m.derivePath("m/44'/0'/0'").neutered().toBase58())
console.log(getAddress(m.derivePath("m/44'/0'/0'/0/0")))
```
Nuxt.jsのroutingで/indexページを作る

たまにはゆるい記事を書こうかなと思ったので、今回はurlで/indexへのroutingをnxut.jsで作ることに関して書こうと思います。

あまりないと思いますが`http://hogehoge/index`というurlにアクセスできるようにするため、nxut.jsではpageディレクトリに新しくフォルダを作ります。

nuxt.jsではpageディレクトリに新しいフォルダを作ると、router.jsが自動で更新されます。

例えば`/top`というパスを作るとします。
その場合はpageのディレクトリは

```
app/pages/
├── top
│   └── index.vue
├── README.md
```

というディレクトリ構造になります。


routingは以下のような形になります。

```router.js
export function createRouter() {
  return new Router({
    mode: 'history',
    base: '/',
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,

    routes: [{
      path: "/top",
      component: _7f4019b2,
      name: "top"
    }],

    fallback: false
  })
}
```

次に`/index`のroutingに関してです。

上記と同じような感じで作ると

```
app/pages/
├── index
│   └── index.vue
├── README.md
```

となると思われますが、これだと以下のように`path: "/"`の子要素として作られてしまいます。

```router.js
export function createRouter() {
  return new Router({
    mode: 'history',
    base: '/',
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,

    routes: [{
      path: "/",
      component: _5cc8436a,
      children: [{
        path: "",
        component: _3929db26,
        name: "index"
      }]
    }],

    fallback: false
  })
}
```

なので、対応としてはディレクトリ名の頭文字を大文字に変えることで対応することが可能です。

```router.js
export function createRouter() {
  return new Router({
    mode: 'history',
    base: '/',
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,

    routes: [{
      path: "/Index",
      component: _b0046b66,
      name: "Index
    }],

    fallback: false
  })
}
```

### まとめ
あまり`/index`というpathを作る機会はほとんどないかと思われますが、何かの参考になれば幸いです。
【React知見】条件分岐（IF文）とそのネスト

# 背景
Reactを最近触り始めたのだが、
React(jsx)で条件分岐（if文）をネストする方法がよく分かってなかったのでまとめた


# ifのネスト
便宜上if文で説明します。
ifの中にifがあることですね。

```php
if (A) {
     if (b) {
     }
}
```

正確には「if文にネストされたif文」とかかもしれんけど、
いざこうやって言語化すると難しい。

# 要件
条件A、条件BといったBoolがあるとする

- Aかつ!BならばAと（ブラウザ上に）表示
- AかつBならばBと表示
- !AならばCと表示

この条件分岐を実現するにはJSXでどのような記法が使えるのか。

# 前提

JSXの条件分岐はこんな感じで表現できる

```react:sample.jsx
class Sample extends React.Component {
    public render() {
        return (
            <>
                {conditionA && (
                    <p>A</p>
                )}
                {!conditionA && (
                    <p>Aじゃない</p>
                )}
            </>
        )
    }
}
```

もしくはシンプルにしたいので三項演算子で

```react:sample.jsx
class Sample extends React.Component {
    public render() {
        return (
            <>
                {conditionA ? (
                    <p>A</p>
                ) : (
                    <p>Aじゃない</p>
                )}                
            </>
        )
    }
}
```

よくある`if~else`　みたいな構文は直接かけません（後述）




# 記法

### 三項演算子入れ子パターン
こんな風に普通に入れ子にして書くのが多分一番綺麗なのかもしれません。
が、なぜかこんな風にできるのを最近まで知らなかった。

```react:sample.jsx
class Sample extends React.Component {
    public render() {
        return (
            <>
                {conditionA ?
                    (!conditionB ?
                        (<p>A</p>) :
                        (<p>B</p>)
                    ) :
                    (<p>C</p>)
                }
            </>
        )
    }
}
```


#### ネストしないパターン
最初は結構こんな感じで書いてた。
ネストせずに普通に順番に判定していくパターン

```react:sample.jsx
class Sample extends React.Component {
    public render() {
        return (
            <>
                {conditionA && !conditionB && (
                    <p>A</p>
                )}
                {conditionA && conditionB && (
                    <p>B</p>
                )}
                {!conditionA && (
                    <p>C</p>
                )}
            </>
        )
    }
}
```

#### 関数にしちゃうパターン
無名関数生成して、関数内部で判定させちゃうパターン。
処理自体は馴染みやすいけど、括弧多くて気持ち悪い

```react:sample.jsx
class Sample extends React.Component {
    public render() {
        return (
            <>
                {
                    (() => {
                        if (conditionA)
                            if (!conditionB)
                                return <p>A</p>
                            else
                            return <p>B</p>
                        else
                        return <p>C</p>
                    })()
                }
            </>
        )
    }
}
```


# 雑感
雑だけど締めます。
色々書き方あるけど、混ぜると混乱するので、プロジェクト毎に統一しよう。

（ああ！ネストしないのが一番見やすいッ！）
TabControl配下にあるタブ欄の高さを取得する

## 最初に

`TabControl`を動的に作る際に「配下にあるタブ欄」の高さが欲しいことがありました。「タブストリップ」と言うらしいです。

タブストリップの高さを取得する情報が見つけられなかったのでこの記事を作成しました。
ベストな道かはいまいち判断できませんが、同じことを実装されたいと考えた方々の参考になれば幸いです。

## 用語の意味
タブ･･･`TabControl`の上部に表示されるタブページを表示するためのコントロール（`TabPage`のことではない）
タブストリップ･･･タブを選択する一覧のこと（詳細は下記）
タブページ･･･`TabControl`の下部に表示される選択したタブと対応付けられたページのこと(`TabPage`オブジェクトのこと)
`TabControl`･･･タブストリップとタブページを持ち合わせた`Control`オブジェクト

## タブストリップとは？

次の画像に表示されているタブの一覧のことを指します。

![tab.png](https://qiita-image-store.s3.amazonaws.com/0/246829/b1c66476-f337-561f-b31c-c4706da10918.png)
※タブの名称がバラバラなのは気にしないでください

赤線が指している高さは**TabControl配下のタブページの数とTabControlのWidthなどに依存する**ので、多ければ行が増えタブストリップの`Height`は高くなり、少なければ行が減りタブストリップの`Height`は低くなるはずです。

## そもそもタブストリップの高さが必要になった背景は？
`TabControl`を親コントロールへ追加する際に、次の2点の実装を行いたかったことがきっかけです。

- `TabControl`の全て(タブストリップ・タブページ含め）が表示されるようサイズを変更
- 親コントロールは子コントロール(`TabControl`)のサイズを元にサイズを調整する

1点目の実装で、`TabControl`のサイズを決めるためにはタブストリップの高さが必要になりました。

## 実装
難しいことを考える必要はありませんでした。
「タブの高さ」と「タブストリップの行数」さえ分かれば取得できます。

次のように実装しました。

```C#
TabPage tabPage = new TabPage();
TabControl tab = new TabControl();
//「タブの高さ」×「タブストリップの行数」＋「タブページの高さ」でtab全体を表示するための高さを取得
tab.Height = tab.ItemSize.height * tab.RowCount + tabPage.Height;
```
Laravel5.7で前回のTwitterOAuthを使ってツイートやらハッシュタグやらユーザーやらの取得方法一覧（投稿あり）

TwitterOAuthでツイートやらを取得する記事はいくらでもあるが、中々取得する一覧みたいのがなかったので、~~完全自分用に~~書いていく。



[前回](https://qiita.com/namizatop/items/439c0604ca15c1ef00cd)で設定したTwitterOAuthを使って色々取得してみる。



>参考リンク
[【前回】Laravel5.7でTwitterOAuthを使って認証やらツイート取得やら](https://qiita.com/namizatop/items/439c0604ca15c1ef00cd)



以下任意のコントローラーで試してください
この記事ではSampleController.phpというファイル名で使用します。
**※全てdump()でjsonデータを表示するだけの処理**



###任意のキーワードを検索する
キーワードを複数指定する場合は半角スペース区切りで入力する
**※ツイートしたばかりだと少し時間を置かないとツイートを取得できない(約3分ほど？)**




```php:SampleController.php
    public function sample()
    {
        //"TwitterOAuthを使って検索するよ"というツイートを10件取得する
        $search_word = \Twitter::get("search/tweets", array("q" => "TwitterOAuthを使って検索するよ", 'count' => 10));

        dump($search_word);
    }

```



###任意のハッシュタグを検索する
上記のキーワード検索に`#ハッシュタグ`をつけるだけ



```php:SampleController.php
    public function sample()
    {
        //"TwitterOAuthを使って検索するよ"というツイートを10件取得する
        $hash_tag = \Twitter::get("search/tweets", array("q" => "#TwitterOAuthを使ってハッシュタグを検索するよ", 'count' => 10));

        dump($hash_tag);
    }

```



###自分のタイムラインを取得



```php:SampleController.php
    public function sample()
    {
        // 自分のタイムラインを10件取得
        $time_line = \Twitter::get('statuses/home_timeline', ['count' => 10]);

        dump($time_line);
    }

```



###フォロワーを取得
自分のフォロワーを取得する



```php:SampleController.php
    public function sample()
    {
        // フォロワーを10件取得
        $follower = \Twitter::get('followers/list', ['count' => 10]);

        dump($follower);
    }

```



###任意のユーザをIDで検索する
とりあえず僕のTwitterIDを取得する（フォローしてほしいだけ）



```php:SampleController.php
    public function sample()
    {
        // @以降のuser_idを指定してください
        $search_user = \Twitter::get('users/show', ['screen_name'=> '@namizatop']);

        dump($search_user);
    }

```



###ツイートする
`TwitterOAuthを使ってツイート`とツイートしてみる
※2回投稿すると`Status is a duplicate.`というerrorが吐かれるので注意。

```php:SampleController.php
    public function sample()
    {
        //　"TwitterOAuthを使ってツイート"とツイート
        $tweet = \Twitter::post('statuses/update', ['status'=> 'TwitterOAuthを使ってツイート']);

        dump($tweet);
    }

```




###任意のツイートをリツイートする
僕の投稿の`TwitterOAuthを使ってリツイートするよ`をリツイートしてみる




```php:SampleController.php
    public function sample()
    {
        //　僕の投稿の"TwitterOAuthを使ってリツイートするよ"の投稿をリツイート
        $retweet = \Twitter::post("statuses/retweet/1100242514680807424");

        dump($retweet);
    }

```




###任意のツイートをいいね！する
僕の投稿の`TwitterOAuthを使っていいね！するよ`をいいね！してみる




```php:SampleController.php
    public function sample()
    {
        //　僕の投稿の"TwitterOAuthを使っていいね！するよ"の投稿をいいね！
        $favorite = \Twitter::post("favorites/create", ['id' => '1100245496159821825']);

        dump($favorite);
    }

```




以上！~~僕のTwitterのステマでした！~~



参考リンク
>参考にさせていただきましたm(_ _)m
[Twitter APIでつぶやきを取得する](https://qiita.com/yokoh9/items/760e432ebd39040d5a0f)
Elixir: 満年齢を計算する － タプルの比較とビット演算

満年齢は英語で何というでしょう？欧米には「数え年」がありません。"age"としかいいようはないのです。むしろ、[数え年を英語で](https://ejje.weblio.jp/content/%E6%95%B0%E3%81%88%E5%B9%B4)説明する方が難しいでしょう。さておき、お題はElixirで満年齢を計算することです。こちらは、さほど難しくありません。ただ、ちょっとしたポイントをご紹介します。


# タプルの比較を使う
現在の2019年から生まれた年を引けば、今年中になる歳が求められます。誕生日前のときは、1差し引けばよいということです。関数は、単純に年月日をふた組、都合6つの数値を引数とします。

```elixir
def calculate_age(birth_year, birth_month, birth_date, year, month, date) do
  age = year - birth_year
  if {birth_month, birth_date} > {month, date} do
    age - 1
  else
    age
  end
end
```

ポイントは、`if/2`の条件において月日をタプルで比べていることです。タプルの大きさはつぎの2段階で決まります(「Operators」の「[Term ordering](https://hexdocs.pm/elixir/operators.html#term-ordering)」参照)。

1. まず、サイズ([`tuple_size/1`](https://hexdocs.pm/elixir/Kernel.html#tuple_size/1))の大きさ。
2. つぎに、要素同士を先頭から順に。

したがって、`{月, 日}`のタプルを比べれば、どちらが先の日付ががわかるのです。


# ビット演算を使う
マクロ[`Bitwise`](https://hexdocs.pm/elixir/Bitwise.html)を使えば、2進数のビット演算ができます。コンピュータが、もっとも得意とするシンプルな処理です。ビット演算で満年齢はつぎのように求められます。

```elixir
def calculate_age(birth_year, birth_month, birth_date, year, month, date) do
  use Bitwise
  birth = birth_year <<< 9
    ||| birth_month <<< 5
    ||| birth_date
  current = year <<< 9
    ||| month <<< 5
    ||| date
  (current - birth) >>> 9
end
```

使ったビット演算子は、つぎのとおりです。

- [`<<</2`](https://hexdocs.pm/elixir/Bitwise.html#%3C%3C%3C/2): ビットの左シフト。2進数の桁を左に指定数移します。
- [`>>>/2`](https://hexdocs.pm/elixir/Bitwise.html#%3E%3E%3E/2): ビットの右シフト。2進数の桁を右に指定数移します。小数値は除かれます。
- [`|||`](https://hexdocs.pm/elixir/Bitwise.html#%7C%7C%7C/2): 排他的論理和(XOR)。両辺をビット毎に調べ、どちらか一方のみが1のとき1、他は0になります。

考え方は10進法を使った場合で見た方がわかりやすいでしょう。排他的論理和(`|||`)は、この場合和(`+`)に置き替えても構いません。

```elixir
# 誕生日: 1999年3月1日
birth = 1999 * 10000
  + 3 * 100
  + 1
# = 19990301
# 現在: 2019年2月28日
current = 2019 * 10000
  + 2 * 100
  + 28
# = 20190228
# current - birth = 199927 <- 下4桁に意味はない
div(current - birth, 10000)  # = 19
```

引き算したあとの下4桁の数値は意味がありません。けれど、日が足りないときは月から、月が足りないときは年から「借りてくる」繰り下がりが重要になります。その結果、誕生日前には年が1差し引かれる結果になるのです。


# 関数に複数の句を加える
実際に関数を使う場合には、整数6つの引数は勝手がよくないかもしれません。そういうときは、関数に引数の異なる句を加えて、パターンマッチングさせればよいでしょう(「[Elixir入門 09: 再帰]」の「[再帰によるループ](https://dev.to/gumi/elixir-09--1a0p)」参照)。たとえば、[`Date`](https://hexdocs.pm/elixir/DateTime.html)またはタプルで日付を渡せるようにする場合、定めるふたつの句はつぎのとおりです。

```elixir
def calculate_age(
  %Date{year: birth_year, month: birth_month, day: birth_date},
  %Date{year: year, month: month, day: date}) do
    calculate_age(birth_year, birth_month, birth_date, year, month, date)
end

def calculate_age(
  {birth_year, birth_month, birth_date},
  {year, month, date}) do
    calculate_age(birth_year, birth_month, birth_date, year, month, date)
end
```
raspberry pi 3 wifi のpower management について

# rasberry pi 3 でのwifi power managementの表示
```
$ iw wlan0 get power_save #power managementの状態表示
$ iw wlan0 set power_save off #power managementをオフにする
```

## OS起動時に wifiのpower managementをoffにする
```/etc/rc.local
iw wlan0 set power_save off # exit 0の前に挿入
exit 0
```

## raspi-configの設定
```
sudo raspi-config
"Wait for Network at Boot" -> " Slow Wait for network connection before completing boot"
にしないと/etc/rc.localは動作しない。
```
ASP.NET CoreをNginxで動かす場合に必要なコード（メモ）

## ASP.NET Core 構築で必要なコードのメモ

Nginxなどのプロキシーを通して配信する場合
日本語を含むコードの場合

そのほか、現在コーディング中においてのメモ他

# 日本語対処用コード

日本語と言うよりUTF8による2byte以上の文字の場合にHTMLエンティティされる問題を解決するおまじない

```C#
        public void ConfigureServices(IServiceCollection services)
        {
            // UTF8文字コード設定
            services.Configure<Microsoft.Extensions.WebEncoders.WebEncoderOptions>(options =>
            {
                options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
            });

            ... 以下略
```

# プロキシー設定

プロキシーを通す場合のおまじない

```c#
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ... 以下略

            // リバースプロキシー設定用
            app.UseForwardedHeaders(new Microsoft.AspNetCore.Builder.ForwardedHeadersOptions
            {
                ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto
            });

            ... 以下略
```

# 設定情報

設定情報系の読み込み用のおまじない（まだ意味の把握全容が出来ていない）

```C#
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

... 以下略

        public Microsoft.Extensions.Configuration.IConfigurationRoot Configuration { get; }

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();

            ... 以下略
```

途中です。
JPAでまんまの値でJoinできないとき

以下、値に接頭辞をつけてJoinする例

```
@ManyToOne(fetch = FetchType.EAGER)
@JoinFormula(value = "CONCAT('＜接頭辞＞', ＜こっちのカラム名＞)", referencedColumnName = "＜向こうのカラム名＞")
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private Group group;
```
GASで文字列の前方一致、後方一致判定をする

# tl;dr

* GASに startsWith, endsWith なんてものは今のところない（2019/02/26）
* なので自作してまとめておく

# メソッドにしておく

何度も同じ判定処理を書くのもアレなのでメソッドにしておく。（メソッド名はそのままとしたが、必要に応じて修正してください）

なお、意図した挙動をしているように見えるが、あんまりテストしてない。

なので、テストコードとかもうちょいまとめたら GitHub にリポジトリ作っておくかも。

## 前方一致

```js
function startsWith(target, pattern) {
  return target.indexOf(pattern) === 0; 
}
```

## 後方一致

```js
function endsWith(target, pattern) {
  return ((target.lastIndexOf(pattern) + pattern.length) === target.length)
         && (pattern.length <= target.length);
}
```

# 参考にしたサイト

* https://qiita.com/aqril_1132/items/9f69575bfbcf24bdf7b5
    * 説明が丁寧でわかりやすい
    * startsWithはもっと短く書けるらしい
* https://vba-gas.info/gas-match
    * 正規表現使うのもありかなーと思いつつ、前方・後方一致見るにはリッチすぎるかなと思った
Mecabインストールメモ (Ubuntu + Apache + PHP)

## 環境
Host OS: macOS High Sierra 10.13.6
Virtual Machine: VirtualBox 5.2.26 r128414
Guest OS: Ubuntu 18.04.1.0 LTS amd64
PHP： PHP 7.2

## Mecabのインストール方法

### VM, Apache, PHPの用意
今回は、VM, Apache, PHP設定の詳細は省きます。
気が向いたら追記したいと思います。
とりあえず、導入したパッケージは記載しておきます。

```
sudo apt install apache2 -y
sudo apt install php7.2 -y
sudo apt install php7.2-dev -y
sudo apt install php-mbstring -y
```

### mecab本体の用意
```
sudo apt install mecab -y         
sudo apt install mecab-ipadic -y
sudo apt install libmecab-dev -y 
```

### php-mecabの用意 
(展開場所はお好きに)

```
sudo mkdir -p /opt/php-mecab
sudo git clone https://github.com/rsky/php-mecab.git
phpize
sudo ./configure
make
make install
```

mecab.iniを作成

``` /etc/php/7.2/mods-available/mecab.ini
extension=mecab.so
```
+ phpコマンド単体でMecabが使えるようにさっきのファイルにシンボリックリンクを貼る

```
ln -s /etc/php/7.2/mods-available/mecab.ini /etc/php/7.2/cli/conf.d/20-mecab.ini
```

+ apache2で利用できるようにする
 
``` 
ln -s /etc/php/7.2/mods-available/mecab.ini /etc/php/7.2/apache2/conf.d/20-mecab.ini
sudo service apache2 restart
```
bitnami版 redmineのパスワード強制変更(Windows)

# 参考サイト
* [bitnami版 redmineのパスワード強制変更](https://qiita.com/chess/items/d8046196c182652f260c)
* ほぼ参考サイトの通りだけど、個人的にもう少し補足を以下に付加する。

# 概要
- Redmineはrailsで作らていて、パスワードは
  Userテーブルのpasswordに保存されている。
- 対象ユーザーレコードのpasswordを更新することで、パスワードを変更する。

# コンソールの起動
- Bitnami Redmine Stack を起動

# パスワードの変更
- htdocsフォルダに移動

```
C:\Bitnami\redmine-4.0.1-0>cd apps/redmine/htdocs
C:\Bitnami\redmine-4.0.1-0\apps\redmine\htdocs>
```
- railsコンソールにログイン

```
C:\Bitnami\redmine-4.0.1-0\apps\redmine\htdocs>ruby bin/rails console production
Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that
should be used instead of the Bundler-generated `rails` binstub.
　：
DEPRECATION WARNING: Passing the environment's name as a regular argument is deprecated and will be removed in the next Rails version. Please, use the -e option instead. (called from load at bin/rails:16)
Loading production environment (Rails 5.2.2)
irb(main):001:0>
```

- 任意の変数tempUser に対象ユーザーのレコードをセット

```
irb(main):001:0> tempUser = User.find_by_login('対象ユーザーのログインID')
=> #<User id: 1, login: "対象ユーザーのログインID", hashed_password: "6d03efcf4c2c21b7c564d2fee4c98f3deaa85fca", firstname: "xxxxx", lastname: "xxxxx", admin: true, status: 1, last_login_on: "2019-02-26 01:50:38", language: "ja", auth_source_id: nil, created_on: "2019-01-24 05:32:19", updated_on: "2019-02-26 01:49:16", type: "User", identity_url: nil, mail_notification: "all", salt: "471c595ab17d7f1f781ade3401611bc8", must_change_passwd: false, passwd_changed_on: "2019-02-26 01:45:57">
irb(main):002:0>
```

- tempUser.passwordに新しいパスワードをセット

```
irb(main):002:0> tempUser.password = '新しいパスワード'
=> "新しいパスワード"
irb(main):003:0>
```

- 更新した対象ユーザのレコードをコミット

```
irb(main):003:0> tempUser.save!
=> true
irb(main):004:0>
```

# 以上
STS(Spring Tool Suite)の日本語化を解除する

## 概要

[勢いで日本語化してしまった](https://qiita.com/segur/items/f9d7b5cdbc02531ffbb0#spring-tool-suite-%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96)STSの日本語化を解除する。

## STS.iniを修正する

```
❯ vim /Applications/STS.app/Contents/Eclipse/STS.ini
```

```
-javaagent:../Eclipse/dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
```

のような記載があるのでコメントアウトする

```
mv /Applications/STS.app/Contents/Eclipse/dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades /Applications/STS.app/Contents/Eclipse/dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades-backup
```
設定のキャッシュみたいなのが残るのでリネームしておく
hamlでclass名を動的に設定する


hamlのdivは%divを省略することができるが、

```haml:div
%div.alert
.alert

```

class名を動的に設定するなら、
%div記法を使わないとできない。

```haml:flash
- flash.each do |message_type, message|
    %div{class: "alert alert-#{message_type}"}
     =message
```
Ruby　チュートリアル bcryptエラー

こんにちは。Railsチュートリアルの6章でRails Tコマンドを叩いたところ、たくさんのエラーがでました。

Error:
ApplicationHelperTest#test_full_title_helper:
LoadError: cannot load such file -- bcrypt

エラー文のほとんどがこれでした。

gem uninstall bcrypt を実行
gem uninstall bcrypt-ruby を実行
gem install bcrypt --platform=rubyを実行
Gemfileにgem 'bcrypt', '~> 3.1.11'を記載
bundle installを実行

ネットには対処法が落ちてたのでこの方法を試したのですが、最初のgem install bcryptで引っかかってしまいます。

このような表示が出てきます


You have requested to uninstall the gem:
        bcrypt-3.1.12

devise-4.6.1 depends on bcrypt (~> 3.0)
If you remove this gem, these dependencies will not be met.
Continue with Uninstall? [yN]  

ここでエンターを押すと

You have requested to uninstall the gem:
        bcrypt-3.1.12

devise-4.6.1 depends on bcrypt (~> 3.0)
If you remove this gem, these dependencies will not be met.
Continue with Uninstall? [yN]  
ERROR:  While executing gem ... (Gem::DependencyRemovalException)
    Uninstallation aborted due to dependent gem(s)

どなたか詳しい方教えてください。

You have requested to uninstall the gem:
        bcrypt-3.1.12

devise-4.6.1 depends on bcrypt (~> 3.0)
If you remove this gem, these dependencies will not be met.
Continue with Uninstall? [yN]  
ERROR:  While executing gem ... (Gem::DependencyRemovalException)
    Uninstallation aborted due to dependent gem(s)
bert-as-serviceを使って日本語BERTの文エンベディング計算サーバーを作る

# はじめに

本記事では[bert-as-service](https://github.com/hanxiao/bert-as-service)を使い、[日本語BERT](https://github.com/yoheikikuta/bert-japanese)によって文表現ベクトルを計算するサーバーを作ります。

# 準備
[日本語BERTの事前学習済みモデル](https://drive.google.com/drive/folders/1Zsm9DD40lrUVu6iAnIuTH2ODIkh-WM-O)をディレクトリ `bert-jp` にダウンロードします。
ダウンロード後のディレクトリの中身は以下のとおりです：

```bash
$ ls bert-jp
graph.pbtxt                             model.ckpt-1400000.index                wiki-ja.model
model.ckpt-1400000.data-00000-of-00001  model.ckpt-1400000.meta                 wiki-ja.vocab
```
次に、`bert-as-service`でモデルをロード出来るようにするために、ファイルを編集します。
ファイル名を変更します:

```bash
mv model.ckpt-1400000.index bert_model.ckpt.index
mv model.ckpt-1400000.meta bert_model.ckpt.meta 
mv model.ckpt-1400000.data-00000-of-00001 bert_model.ckpt.data-00000-of-00001
```
語彙ファイルを作成します（2019/04/20: 先頭行を `<unk>` から `[UNK]`に置換する処理を追加）:

```
cut -f1 wiki-ja.vocab | sed -e "1 s/<unk>/[UNK]/g" > vocab.txt
```
以下の内容のBERT設定ファイルを作成します:

```json:bert-jp/bert_config.json
{
    "attention_probs_dropout_prob" : 0.1,
    "hidden_act" : "gelu",
    "hidden_dropout_prob" : 0.1,
    "hidden_size" : 768,
    "initializer_range" : 0.02,
    "intermediate_size" : 3072,
    "max_position_embeddings" : 512,
    "num_attention_heads" : 12,
    "num_hidden_layers" : 12,
    "type_vocab_size" : 2,
    "vocab_size" : 32000
}
```
これで日本語BERTモデルの準備が出来ました。

最後にライブラリをインストールします。

```bash
pip install --upgrade
pip install tensorflow-gpu
pip install bert-serving-server  # server
pip install bert-serving-client  # client, independent of `bert-serving-server`
```

# サーバーを立ち上げる
以下のコマンドのように、事前学習済みモデルが含まれるディレクトリと、ワーカーの数を指定して、サーバーを起動します。

```bash
bert-serving-start -model_dir ./bert-jp -num_worker=4 
```

# クライアントからサーバーを叩く
サーバーに文の配列を送り、それぞれの文に対応するエンベディングの配列を受け取るクライアントを実装します。クライアントコードは以下の通りです。今回はローカルホストにサーバーを立てたので、ipを`0.0.0.0`にしています。また、日本語文の分かち書きには事前学習に使われたものと同じ`sentencepiece`のモデルを利用しています。

```python:client.py
from bert_serving.client import BertClient
bc = BertClient(ip='0.0.0.0')

import sentencepiece as spm
s = spm.SentencePieceProcessor()
s.Load('./bert-jp/wiki-ja.model')

def parse(text):
    text = text.lower()
    return s.EncodeAsPieces(text)

texts = ['液体の水は、惑星上における生命の前提条件である。',
        '火星は地球型惑星に分類される。']

parsed_texts = list(map(parse,texts))

print(bc.encode(parsed_texts,is_tokenized=True))
```

クライアントコードを実行します。

```
$ python client.py 
[[-0.01896668  0.20814717 -0.229494   ...  0.10796983  0.31211707
  -0.59373856]
 [-0.22285977  0.04470082 -0.48112744 ...  0.11185268  0.02520958
  -0.0751629 ]]
```
無事、エンベディングを受け取ることが出来ました。

# 感想
BERTは最近大きな話題を集めていますが、ファインチューニングしたモデルを使う場合には、推論時にも高性能なコンピューティングインスタンスが必要になり、用途によってはコストが高すぎることもあります。

この記事で紹介したようなエンベディング計算サーバーを立てれば、ファインチューニングは行わず、エンベディングを特徴量としてのみ利用することで、GPUが無い安価な推論インスタンスでもBERTを利用することが出来るようになります。
Karabiner-Elementにてwindowsのように角全角キーで英数かなをトグルできるように

# 目的
windows上がりの人には、
半角全角キーにて英数、かなを切り替えられたほうが嬉しい場合もあるので。

# 設定例
半角全角位置のキー割当を英数にします。

```
{
    "from": {
        "key_code": "grave_accent_and_tilde"
    },
    "to": {
        "key_code": "japanese_eisuu"
    }
}
```

条件付き入力設定をします。

```
  "title": "自分用の設定",
  "rules": [
    {
      "description": "半角全角キーで英数かなをトグルできるようにします",
      "manipulators": [
        {
          "type": "basic",
          "description": "入力ソースが英字の場合、ひらがなにする（入力ソース>がひらがなの場合、上書きの必要なし）",
          "from": { "key_code": "japanese_eisuu" },
          "to": [ { "key_code": "japanese_kana" } ],
          "conditions": [
            {
              "type": "input_source_if",
              "input_sources": [ { "language": "en" } ]
            }
          ]
        }
      ]
    }
  ]
}
```
python packaging の editable と develop mode のこと

python パッケージのツールはdistutils, setuptools, pip, pipenv といろいろあって、用語が混乱してきたのでまとめてみた。

easy_install (setuptools)

- easy_install -e の editable mode はバージョン解決をしてダウンロードするところまで。
    - パッケージ名指定で、pypi で名前解決する。URL不可。
    - editable mode での展開ディレクトリは明示的に指定しないといけない。
- setup.py develop で symlink を使った install が行われる (egg-link)

pip

- pip install -e の editable mode は setuptools の develop mode に相当
    - pypi での名前解決不可で、ローカルあるいは git (VCS) 管理の URL を使う。
        - （pip install git+https://.... みたいな）
    - 展開ディレクトリ（`--src` で指定可）は、デフォルトの位置が用意されている

pipenv

- pipenv install -e の editable mode は egg-link でインストールを行う。
    - pypi での名前解決可能で、パッケージ名指定できる。
    - git (VCS) 管理の URL も使える。VCS 経由のものは[editable にすべき](https://pipenv.readthedocs.io/en/latest/basics/#a-note-about-vcs-dependencies)。
    - editable として展開されている場所は pip 同様規定値が使われる。
- `--dev` は [dev-packages] に区分けされて Pipfile に入る。egg-link とは関係ない。
    - `--dev` は他の環境でインストールするときに効く。
    - pipenv install --dev で packages と dev-packages の両方が入る。
    - 典型的には `tests_require` で指定していたようなパッケージが該当する


## 補足
pypi は python package index で、[PEP 503](https://www.python.org/dev/peps/pep-0503/) に仕様がある。simple repository APIという、たいへん検索しにくい名称。中身は API というよりは、ファイルレイアウトの規則になっている。

dev-packages や tests_require といった「条件によってインストールするか決める」というものは、これらの特別なオプションを使わずに、[extras](https://www.python.org/dev/peps/pep-0508/#extras) の一つとして設定するという方法もあります。

pip の dependency resolver が[変更](https://github.com/pypa/pip/issues/9217)されて、egg-link を使いにくい状況になってきています。pipenv の editable mode も時と場合によって使い分けたほうがよさそう。
Slackの絵文字をimport/exportする方法

# 概要
Slackのカスタム絵文字(emoji)にまつわる問題を解決します。

* ある人が作った絵文字を一括ダウンロードしたい
* 絵文字をまとめてアップロードしたい
* あるワークスペースの絵文字を別の場所でも使いたい

# 背景
ある人の退職に伴い、絵文字の引継ぎをしたいと思ったのが背景です。
Slackのカスタム絵文字はアカウントと紐づいているため、それを作成したアカウントが退会するとただの文字として表示されるようになってしまいます。そこで絵文字をバックアップできるツールを探していました。しかし、"特定ユーザの作成した絵文字"ではなく、ワークスペースにある絵文字全部を取得してしまうツールがほとんどで、6000個余りのカスタム絵文字が存在する弊社では不要な絵文字が多すぎ、役に立ちませんでした。

そこで特定ユーザの作成した絵文字をバックアップできるツールである[emojme](https://github.com/jackellenberger/emojme)を見つけたので紹介します。

# emojme
https://github.com/jackellenberger/emojme

## 何をするツール？
ユーザ別に絵文字を取得したり、取得した絵文字をアップロードしたりするツールです。

## なぜ動くの？
Slackの公開APIである [emoji.list](https://api.slack.com/methods/emoji.list)ではなく、非公開のAPIであるemoji.adminListを叩いて絵文字リストを取得するため、ユーザ別で取得できるようになっています。
したがって動作にはUser tokenが必須になっており、bot用のトークンでは動作しません。

## 動かし方
### 導入
`npm install -g emojme`

## 動作に必要なAPIトークンの取得方法(https://github.com/jackellenberger/emojme#slack-for-web)
`${SUBDOMAIN}`にSlackのワークスペースのサブドメイン名が入っているものとします。
1. `https://${SUBDOMAIN}.slack.com/messages` にアクセスします。
2. 右クリックして「検証」→上のタブの「Console」→下の文字列を入力しEnter
```window.prompt("your api token is: ",/api_token: "(.*)"/.exec(document.body.innerHTML)[1])```
3. APIトークンが表示されるので、これをコピーします。

### ある人が作った絵文字を一括ダウンロードしたい
`emojme download --subdomain $SUBDOMAIN --token $TOKEN --save $USER`
  * `$SUBDOMAIN`: Slackのワークスペースのサブドメイン名
  * `$TOKEN`: APIトークン
  * `$USER`: ユーザのスクリーンネーム(@〜 ではなく表示される名前)
カレントディレクトリ以下にbuild/$subdomain/$userというディレクトリが作られ、その中に絵文字がダウンロードされます。

### 絵文字をまとめてアップロードしたい
`emojme add --subdomain $SUBDOMAIN --token $TOKEN --src $DIR`
  * `$SUBDOMAIN`: Slackのワークスペースのサブドメイン名
  * `$TOKEN`: APIトークン
  * アップロードしたいディレクトリ名

### これ以上の使い方については[README](https://github.com/jackellenberger/emojme)を参照してください。