OmniAICreator/Qiita-1.07M huggingface dataset:
Trying to do OpenCV with C# UWP

For these few days I have been researching on UWP(Universal Window Platform) and I am trying to use openCV in UWP with c# but it seem not easy at all. So today I will list down everything about what I have research.

#<b>PROBLEM</b>
As we all know Open CV only has C++, Python and Java interfaces so If we want to use it with <b>C#</b> we have to use OpenCV wrapper and here is the problem , Most of the c# wrapper only support Window Form Application , It doesn't support Universal Window Platform.


#<b>List Of .Net OpenCV Wrapper</b>

###<b>1. OpenCV Sharp</b>
It is one of the .Net OpenCV Wrapper. It work great but the problem is It is only support Window Form Application. Below is their github repository.
https://github.com/shimat/opencvsharp

###<b>2. OpenCV dotNet</b>
This is also one of .Net OpenCV Wrapper but this wrapper doesn't actively maintenance the last update is from 2016 and it is only support Window Form not UWP.Below is OpenCV.net link
https://www.nuget.org/packages/OpenCV.Net/

###<b>3. Emgu</b>
This is the most popular .Net OpenCV Wrapper. This wrapper is good to use and well maintenance by the developer. This wrapper has two Version.
1. <b>Open Source</b> : It is a free version of Emgu CV
2. <b>Commercial License</b>  : This is a charge version.
You may wonder what is the difference right? Ok please see below picture.

<img width="1253" alt="Screen Shot 2018-06-25 at 2.20.36 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/211896/66a0eb52-e701-5c9f-8276-5b8aa69c30bd.png">

Above picture is the difference between the Free version and Commercial version. It seem like the free version only support Windows Form not UWP.
Below is Emgu Website.
http://www.emgu.com/wiki/index.php/Main_Page

- Anyway after I keep doing the research , I have find one c# UWP sample project with openCV. It create by Microsoft. below is their github link.

https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraOpenCV
There isn't much documentation but when I go through where code it seem like they are using something call OpenCV Bridge which convert headerfile from c++ to use in c# uwp.
[UWP] SerialDeviceのDisposeが終了しない場合の回避策

# 概要
Raspberry Pi 3 + Windows IoT + UWPの環境において、SerialDeviceのDispose()が終了しない問題が発生した。
この回避策を述べる。

#発生した環境

- Raspberry Pi 3 Model B
- Windows 10 IoT 
- Microsoft.NETCore.UniversalWindowsPlatform 6.0.6 & 6.1.5
- USB-UART変換ケーブル

# 現象
Raspberry Pi 3 + Windows IoT + UWPの環境において、以下のコードを定期的に実行しながら、そのUART0に向けてシリアル通信で外部から送信を続けると、時折、`serialDevice.Dispose()`が終了しないということが発生する。

```csharp:hang.cs
var serialDevice = await SerialDevice.FromIdAsync(id);
serialDevice.BaudRate = ...
serialDevice.DataBits = ...
serialDevice.Parity = ...
serialDevice.StopBits = ...
serialDevice.Handshake = ...

var dataWriter = new DataWriter(serialDevice.OutputStream);
var dataReader = new DataReader(serialDevice.InputStream);

uint size = await dataReader.LoadAsync(256);
if (size > 0)
{
	var buffer = new byte[size];
	dataReader.ReadBytes(buffer);
}

System.Diagnostics.Debug.WriteLine("Disposing");
serialDevice.Dispose();
dataWriter.Dispose();
dataReader.Dispose();
System.Diagnostics.Debug.WriteLine("Disposed");
```

また、`Dispose()`の順序を`DataWrtier`/`DataReader`を先にした場合、先にDisposeした部分で同様の問題が発生する。

# 解決策
Dispose前で100ms待機する。

```
await Task.Delay(100);

serialDevice.Dispose();
dataWriter.Dispose();
dataReader.Dispose();
```

これを追加して以来、Disposeが終了しない問題は起きていない。
なぜこれで解決するのかはわからない。興味がある人は下記リンクにあたってほしい。
ひとつめのリンクが100ms待機するという対応を教えてくれたソースであり、その情報が根拠としているのがふたつめのリンク(こちらはUWPではない.NET環境のSerialPortクラスの情報)になっている。

# 参考にした情報
Windows IoT BackgroundTask Async/Await
https://stackoverflow.com/questions/44893263/windows-iot-backgroundtask-async-await

Why Thread.Sleep() before SerialPort.Open and Close?
https://stackoverflow.com/questions/6434297/why-thread-sleep-before-serialport-open-and-close/14313505
【Ruby】個人的に面白かった点

#概要
Rubyの学習をしていて何回か何気なく間違えた点をまとめました。中身は順不同で内容もとてもランダムです。
他の人から見たら当たり前すぎて気にも止めないことかもしれません。

# 1.メソッド内で定数は定義できない。

これは不本意な代入を防ぐ為でしょうか？メソッド内で定数は定義できません。エラーが起こります。
[Rubyリファレンスマニュアル（変数・定数）](https://docs.ruby-lang.org/ja/2.1.0/doc/spec=2fvariables.html)

```ruby
def method1
  CONST = 'I wanna be defined,plz,,,;_;?'
end
p method1 #=>code.rb:2: dynamic constant assignment
```

#2.unless節でelsifは使用できない。
以前にif節と同じノリでelsifを使用したらエラーになりました。それもそのはず、unless節ではelsifは使用できません。

```ruby
def method1
  best_hitter = 'Aaron Judge'
  best_pitcher = 'Clayton Kershaw'
  unless best_hitter == 'Hank Aaron'
    'Study some history boy!'
  elsif best_pichter == 'Clayton Kershaw'
    'He could be the greatest picher of all time'
  end
end
p method1 #=>syntax error, unexpected keyword_elsif, expecting keyword_end
```

#3.パーセント記法の文字列の配列には「,」も「""」もいらない。

私はパーセント記法で配列を書くときに、ついついいつもの文字列配列のノリで「""」や「''」で囲みがちです。

```ruby
great_singers = %w(Adele Beyoncé EdSheeran JohnLegend)

p great_singers #=>["Adele", "Beyoncé", "EdSheeran", "JohnLegend"]
```

#4.Stringクラスに「+」や「*」はあっても「-」や「/」は定義されていない。

Stringクラスで定義されている計算記号は「+」と「*」だけで、「-」や「/」は定義されていません。

```ruby
p 'Chris' + 'Brown' #=>"ChrisBrown"
p 'Chris' * 3 #=> "ChrisChrisChris"
p 'Chris Brown' - 'Brown' #=>  undefined method `-' for "Chris Brown":String (NoMethodError)
p 'Chris Brown' / 3 #=> undefined method `/' for "Chris Brown":String (NoMethodError)
```

#5.メソッドと変数の探索順位は変数が先
同名のローカル変数、メソッドが存在する場合は変数が先に優先させて表示されます。

```ruby
world_cup = 'soccer'

def world_cup
  p 'Go Mexico!!'
end

p world_cup #=> 'soccer'
```
#6.再代入と破壊的メソッド
再代入はあくまでの入れ物（変数）に違う値を入れ直すだけ（＝別の変数を作り直すようなもの）なので、元の変数に影響は与えない。しかし、破壊的メソッドは元の値に変更を加えるのでその値をもつ全てのオブジェクトに影響を与える。

```ruby
#再代入の例
var1 = 'Soccer'
var2 = var1
var2 = 'Baseball'

p var1 #=> "Soccer"
p var2 #=> "Baseball"

#破壊的メソッドの例
var1 = 'Soccer'
var2 = var1
var2.gsub!(/Soccer/, 'Baseball')

p var1 #=> "Baseball"
p var2 #=> "Baseball"

```

#7.大文字で始まるメソッドの「()」は省略できない
Rubyにおいてメソッド名は`hello_world`のように`スネークケース`で定義するのが一般的です。
しかし`HelloWorld`のように`キャメルケース`で命名しても間違いではありません。
その場合、メソッドの呼び出しの際に「()」を省略することができません。

```ruby
def HelloWorld
  puts 'Hello World'
end

HelloWorld() #=> Hello World
HelloWorld #=> code5.rb:5:in `<main>': uninitialized constant HelloWorld (NameError)

```

#8.「::」を仕様したメソッドの呼び出し
メソッドの呼び出しには`.`以外にも`::`を使用することが可能です。

```ruby
p Time.now #=> 2018-07-18 13:02:46 +0900
p Time::now #=> 2018-07-18 13:02:46 +0900
```

#9.クラスメソッドはクラスオブジェクトに定義された特異メソッド
タイトル通りクラスメソッドはクラスオブジェクトに定義された特異メソッドです。
つまり、メソッドがどのクラスを参照しているかわかるかさえすればクラス外でも定義可能です。

```ruby
class ClassA
end

def ClassA.class_method
  puts "Hello World"
end

ClassA.class_method #=> Hello World
```
Google Colaboratoryで最初に確認する事(コード編)

# はじめに
Google Colaboratory(以下、Colab)で、Googleドライブのデータを読み込む処理や、手元のデータをアップロードする方法等を知りたい場合、Webから検索する事が多いかと思います。

しかし、Colabの標準機能にはコード スニペットが実装されていて、そこにはニーズが高い(と思われる)コード スニペットが多数存在しています。

他にも、これを使用する事でノートブックにコードを入力する手間も省けます。

以上の事から、まずはここから確認すべきと思いましたので記事にしました。

# 操作方法
上部メニューの「ヘルプ」-「検索コード スニペット」をクリック。
![01.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/384231b0-f2db-75e8-7674-aa8963dceaeb.png)

画面左側にコード スニペットの一覧が表示されるので、目的のものを一覧の中から選択して、「挿入」ボタンをクリック。
(下図画面では`Importing data from Google Sheets(Spread Sheatのデータを読み込み、DataFrameに変換するコード)`を選択)
![02.png](https://qiita-image-store.s3.amazonaws.com/0/128060/37737563-0e32-bddb-4f04-2d128de511aa.png)

ノートブックに選択したコード スニペットが追加される。
![03.PNG](https://qiita-image-store.s3.amazonaws.com/0/128060/51ef7e20-2fb5-0ee3-5b60-fa791c79d990.png)

あとは、読み込みたいスプレッドシートの名前など、個人の環境に依存する値を入力して、上から順番に実行すればOK。

## 最後に
コード スニペットにはBigQueryやGoogle Cloud Storageとの連携など、様々なコードが用意されていました。

情報の精度や新鮮さを考えると、まずはコード スニペットから目的のコードを探すのがベターではないかと思います。
Qiitaの海外版にあたるDev Communityの調査

Qiitaの完全英語版を探している人は多かったと思うけど、これがもしかしたら答えになるかもしれないです。この調査を進めていきます。

うまく投稿ができたようですね。

やっぱり海外のサービスを使っているとどんどん英語で調べていきたいので日本語変換をたくさんしていると、速度が遅くなってきますよね。
最適な日本語見つからない　知らないなど


https://dev.to/sheenbanach/first-post-3ile
スマホでSSHポートフォワーディング

私は、スマホでVNCサーバーを使って、リモートデスクトトップを使っています。
VNC通信のセキュリティを高めたくて、SSHポートフォワーディングを使っています。

私は、SSH接続できるアプリを使って、サーバーに、接続しています。
でも、このアプリでは、SSHの細かな設定が出来ないので、Linuxパソコンのように使えるアプリを探していました。

その中で、Termuxを見つけました。
https://play.google.com/store/apps/details?id=com.termux&hl=ja
SSHはもちろんですが、root化しなくてもサーバーのように使うことが出来るので、プログラム開発環境をスマホで作ることが出来ると書いてある記事もあり、私も期待しています。

インストールは、こちらの記事を参考にしました。
https://linuxfan.info/termux

SSHの設定は、こちらも参考にしました。
https://linuxfan.info/termux-sshd/amp

私は、Androidからサーバーに接続したいので、こちらの記事を参考にしました。
https://termux.com/ssh.html

このTermuxを使えば、Androidをウェブサーバーとしても使えます。
ボートが、設定されています。

#端末内のファイルのバックアップを先に
Termuxのインストールの前に、スマホ本体に記録されている画像などのファイルを必ずバックアップしてください。

##Termuxは、ファイル操作します
Termuxをインストールして、まず最初にTermuxのアップデートをします。
そのあとに、ストレージの設定をします。
端末のダウンロードフォルダ等にリンクを設定して、Termuxと他のアプリとやり取りできるようにします。
この設定については、インストールに参考にした記事で確認してください。

```
termux-setup-storage
```

このコマンドを実行すると、ダウンロードフォルダ等各フォルダに、シンボリックリンクが設定されます。

この影響なのか、私の操作が原因なのか不明ですが、ダウンロードフォルダやドキュメントフォルダなとのファイルが、関連アプリからアクセス出来なくなり、ファイルが無くなったと同じ状況になりました。

私は、Android5を使っています。
Android6以降は、ファイルにアクセスする許可を求めてくるそうです。

Termuxをインストールする前に、必ずファイルのバックアップを行ってください。

#SSHポートフォワーディング出来た
SSHのSSHポートフォワーディングの設定のあとに、VNCのアプリでlocalhostのアドレスとボート指定で、SSHポートフォワーディングでアクセス出来ました。
スマホでも、SSHポートフォワーディング出来ました。

SSHポートフォワーディングは、こちらの記事を参考にしました。
http://www14.plala.or.jp/campus-note/vine_linux/server_vnc/vnc_portforwarding.html
Kotlin: 文字列変換 先頭を大文字・小文字に / キャメルケース・スネークケース

Kotlin で文字列を変換するコードを書きました。 今回やったのは次の4つです。

* 先頭を小文字にする
* 先頭を大文字にする
* スネークケースの文字列をキャメルケースにする
* キャメルケースの文字列をスネークケースにする

GitHub で公開しており、 build.gradle に記述することでプロジェクト内で使用可能です。
https://github.com/KenjiOhtsuka/kotlin-case-changer

いずれも拡張関数で書いています。

## コード

### 先頭を小文字にする

```kotlin
fun String.beginWithLowerCase(): String {
    return when (this.length) {
        0 -> ""
        1 -> this.toLowerCase()
        else -> this[0].toLowerCase() + this.substring(1)
    }
}
```

正規表現を使う方法もありますね。

### 先頭を大文字にする

```
fun String.beginWithUpperCase(): String {
    return when (this.length) {
        0 -> ""
        1 -> this.toUpperCase()
        else -> this[0].toUpperCase() + this.substring(1)
    }
}
```

使いみちはないかもしれませんが、小文字にするメソッドがあったので大文字にするメソッドも作りました。

### キャメルケースにする

```
fun String.toCamelCase(): String {
    return this.split('_').map {
        it.beginWithUpperCase() } .joinToString("")
}
```

もともとスネークケースのものに対してのみ有効です。

### スネークケースにする

```kotlin
fun String.toSnakeCase(): String {
    var text: String = ""
    var isFirst = true
    this.forEach {
        if (it.isUpperCase()) {
            if (isFirst) isFirst = false
            else text += "_"
            text += it.toLowerCase()
        } else {
            text += it
        }
    }
    return text
}
```

もともとキャメルケースの文字列に対して有効です。 正規表現も考えましたがすぐには思いつきませんでした。

## Java から呼び出す場合は？

Java から呼び出す際は、 `CaseChanger.method(StringObject)` という形にします。

(<a href="http://improve-future.com/kotlin-string-conversion-change-first-letter-and-camel-and-lower-case.html" target="_blank">拙ブログ</a>にあった記事をほぼそのまま移しました。)
Elixirで再帰呼び出しを使ってリストの加算関数をつくる

(この記事は、「[fukuoka.ex x ザキ研 Advent Calendar 2017](https://adventar.org/calendars/2873)」の8日目です）

昨日は@takasehidekiさんの「[ElixirでIoT#1.3.2：プロセッサコアの動作周波数を揃えて比較評価してみた](https://qiita.com/takasehideki/items/ac3bdb8c66a5b6710d11)」でした．

---

#はじめに
　前回の記事「[Elixirのリストの仕様をまとめてみた](https://qiita.com/hisaway/items/dd25158b2a51832109c7)」では，以下のようにリストの仕様をまとめました．

- リストは先頭から操作すると速い
- リストのループは再帰呼び出しでする

この記事では，Elixirで再帰呼び出しを使い，リストの操作を行う方法について説明します．

# 追記　2019/02/24
fukuoka.exではリストの操作(ループ)に再帰ではなく，Enum.map/reduceを推奨しています．

## map/reduceメリット

- 可読性がよくなる
- パイプライン演算子が使いやすい
    - 副次的な効果としてパイプライン演算子を使うために関数の設計規則が自然と統一される
- 並列プログラミング処理系「Hastega」の恩恵を受けられる(予定)
    - [ZEAM開発ログ: Elixir マクロ + LLVM で超並列プログラミング処理系を研究開発中](https://qiita.com/zacky1972/items/cc88260a3c93c9f71317)

読み進める方は上記のメリットを踏まえて，なお再帰呼び出しをしなければならないときに参考にしていただければと思います．

# 関数呼び出しの条件
Elixirでは，**リストでなくとも**，再帰呼び出しでループを行います．
詳細は，[9 再帰 - Reccursion](http://elixir-ja.sena-net.works/getting_started/9.html)を参考にしてください．　
一般的な再帰呼び出しの例を示します．以下は，与えられた数の階乗を計算する関数です．

```c:factorial.c
int factorial(int num){
  if(num > 1)
    return num * factorial(num-1); 
  else
    return 1;
};
```

次に，Elixirで記述した例を示します．

```elixir:factorial.ex
defmodule Test do
  def factorial(num) when num > 1 do
    num * factorial(num-1)
  end
  def factorial(num), do: 1
end
```
(Elixirでは，関数が1文で済む場合は，`do:`を使って記述できます．後に空白が必要です．)
比較すると以下のような違いがあります．

- `if`,`else`のような制御文`when`が関数名の後ろについている　
- 関数が再定義，オーバーライドされているように見える

`when`のように条件を指定，拡張するものを**ガード句**といいます．これもパターンマッチングの1つとなります．呼び出す条件を変えた関数を複数定義し，呼び出すことで再帰呼び出しを行います．

上記のようにElixirでは，**関数を定義する際に呼び出す条件を設定**することができます．
条件を設定する方法としては，ガード句の他に引数にパターンマッチングを使用する方法があります．

# 引数のパターンマッチ
引数がリストであるなら，変数に`[　]`をつける，`hd`と`hl`を使うなどができるため，`is_list`のようなガード句は省略できます．一気に処理内容も書いてしまいます．

```elixir:add.ex
defmodule Test do
  # 引数がリストである
  def add([a_hd | a_tl], [b_hd | b_tl]) do
    [ a_hd + b_hd | add(a_tl, b_tl) ]
  end
  # 引数がリストで，空である
  def add([], []), do:[]
end
```
引数にパターンマッチングを使用したことで，関数の中で`(hd a)`と書かずに引数として与えられた`a_hd`をそのまま使用できます．また，空リスト`[ ]`に`hd`や`tl`を使用するとエラーになりますので，`add([],[])`と呼び出した場合にも対応させています．

# 完成？
これでリストの加算関数が完成...ではありません．
まだ1次元リストにしか，対応していません．

```elixir:iex
iex(1)> Test.add([1, 2, 3], [4, 5, 6])
[5, 7, 9]
iex(2)> Test.add([[1, 2], [3, 4]], [[5, 6], [7, 8]])
** (ArithmeticError) bad argument in arithmetic expression
    (test) lib/test.ex:29: Test.add/2
```
NumPy相当というからには最低でも2次元，できれば3次元にも対応したいところです．  
2次元リストはガード句と合わせて，実装する必要があるため，次回の記事で扱いたいと思います．

# まとめ
以上で，1次元リストの加算関数を実装しました．  
要点をまとましょう．

- Elixirでは，関数の呼び出し条件を設定できる
- 関数の引数にもパターンマッチングを使用できる
  
  
明日は @Takeshi-Kogu さんの「[Elixirでファイルの入出力をしてみた](https://qiita.com/Takeshi-Kogu/items/1e75e27bf906a54bce23)」 です。お楽しみに！
オフラインリアルタイムどう書く E16 の実装例( Go )

オフラインリアルタイムどう書く E16 の実装例( Go )

問題 : http://nabetani.sakura.ne.jp/hena/orde16nontri/
実装リンク集 : https://qiita.com/Nabetani/items/3525da55601bdf55316e

順当に https://qiita.com/Nabetani/items/c2e4a0ee80bcd28c1636 を移植した。

```go:実装
package e16

import (
	"math"
	"strconv"
	"strings"
)

func impl(num int64) int64 {
	sb := strconv.FormatInt(num, 2)
	zero3 := strings.Index(sb, "000")
	one3 := strings.Index(sb, "111")
	if zero3 < 0 && one3 < 0 {
		return num
	}
	if zero3 < 0 {
		zero3 = math.MaxInt32
	}
	if one3 < 0 {
		one3 = math.MaxInt32
	}
	if zero3 < one3 {
		head := sb[0:zero3]
		tail := strings.Repeat("0", len(sb)-zero3-3)
		newnum, _ := strconv.ParseInt(head+"001"+tail, 2, 64)
		return impl(newnum)
	} else {
		head := sb[0:one3]
		tail := strings.Repeat("1", len(sb)-one3)
		newnum, _ := strconv.ParseInt(head+tail, 2, 64)
		return impl(newnum + 1)
	}
}

func solve(src string) string {
	num, _ := strconv.ParseInt(src, 10, 64)
	return strconv.FormatInt(impl(num+1), 10)
}
```

```go:テスト
package e16

import (
	"testing"
)

func Test(t *testing.T) {
	var tests = []struct {
		name  string
		input string
		want  string
	}{
		{"0", "1441", "1444"},
		{"1", "1", "2"},
		{"2", "2", "3"},
		{"3", "3", "4"},
                // 中略
		{"40", "1072693248", "1227133513"},
	}
	for _, test := range tests {
		got := solve(test.input)
		if got != test.want {
			t.Errorf("%v: solve(%q)=%q, want %q\n", test.name, test.input, got, test.want)
		}
	}
}
```

ruby では正規表現だった部分を `strings.Index` に変更した。

`"000"` と `"111"` のどちらが左側にあるのかの処理がちょっとわかりにくい感じなのがよろしくないように思うけど、ほかにいい方法が思いつかなかった。

`math.MaxInt32` や `math.MaxInt64` はあっても `math.MaxInt` がないのが残念。
【Python】.whlファイルをpipでインストールしようとして「○○.whl is not a supported wheel on this platform.」エラーが出た時の対応

# はじめに
numpy+mklのwhlファイルをpip installでインストールしようとしたときに、
「○○.whl is not a supported wheel on this platform.」
というエラーが出たので、その解決方法を備忘録として記事にしてみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/eb668747-4519-3df3-abdc-b61303363273.png)


# 環境
Windows 10
Python 3.5.2
pip 10.0.1

# エラーの原因
pipに対応していないバージョンのwhlはインストールができません。

例えば、**cp27**に対応していないpipの場合、
numpy-1.14.5+mkl-**cp27**-**cp27**m-win_amd64.whlをインストールしようとすると

>numpy-1.14.5+mkl-cp27-cp27m-win_amd64.whl is not a supported wheel on this platform.

というエラーが表示され、インストールに失敗します。

# pipが対応しているcpの確認
**get_supported()**を実行することでpipが対応しているcpの一覧を確認することができます。

pip10.0.1の場合は以下のコマンドを実行することで対応cpを確認できます

```powershell:Python上でのコマンド
>>> from pip._internal.pep425tags import get_supported
>>> get_supported()
```

```python:結果
[('cp35', 'cp35m', 'win_amd64'), ('cp35', 'none', 'win_amd64'), ('py3', 'none', 'win_amd64'), ('cp35', 'none', 'any'), ('cp3', 'none', 'any'), ('py35', 'none', 'any'), ('py3', 'none', 'any'), ('py34', 'none', 'any'), ('py33', 'none', 'any'), ('py32', 'none', 'any'), ('py31', 'none', 'any'), ('py30', 'none', 'any')]
```

# pipに対応する.whlファイルのダウンロード
whlファイルは以下からダウンロードできます。
https://www.lfd.uci.edu/~gohlke/pythonlibs/

pipが**cp35**、**cp35m**、**win_amd64**に対応している場合は以下をダウンロードします。
numpy‑1.14.5+mkl‑**cp35**‑**cp35m**‑**win_amd64**.whl


# .whlファイルのインストール
whlファイルが置いてある場所で以下のコマンドを実行します

```powershell:.whlのインストール
> pip install .\numpy-1.14.5+mkl-cp35-cp35m-win_amd64.whl
```

Successfully installed ○○というメッセージが出ればインストール成功です
Alexa 


## VUIデザイン
## 処理ロジック

### AWSプロモーションクレジット

### アカウントリンク（OAuth2）

### スキルの種類
+ カスタム・スキル
+ スマートホーム・スキル
+ フラッシュブリーフィング・スキル
	+ RSSを読ませる

#### カスタム・スキル
決まったパターンで呼びかける必要がある

##### 

ウェイクワード → スキル・呼び出し名 → 起動フレーズ

##### ワンショット
ウェイクワード → スキル・呼び出し名 → つなぎの語 → 発話

#### インテントとスロット
##### インテント
5つ以上のパターンを登録
20〜30のパターンを登録するのがオススメ

##### スロット
アルファベット → 小文字
数字 → 漢数字
句読点 → 省かれる

### スキル開発
#### 設計
アイデア出し

+ 使われるスキルとは
	+ 日々使うユースケース
	+ 会話フローがシンプル/音声の方が楽
	+ コンテンツが最新
	+ 特別な体験
		+ スキルからでしか体験できないサービス
	+ 覚えやすいスキル呼び出し名
	+ できることが明確
		+ スキルの名前はわかりやすく
	+ エラーがないこと

##### スキルの人気ランキング

##### ダイアログスケッチ
ハッピーパスを記入する（正常処理）
ユーザーとAlexa役でロールプレイしてみる

##### スキルフロー・デザイン
フロー図をしっかり作ること

##### リテンション
スキルを公開したら、実際に使われているか確認する


#### 開発
#####スキルの開発
なるべくシンプルに

##### 開発者コンソール
今年になって新しいより良いものに改善された

##### ASK CLIとAWS Cloud9で上級者開発

##### インテント履歴
開発者コンソールから、ユーザーがどのような言い方をしているか、確認できる
→ そこから改善できる

##### ビルトインスロット

##### 同義語
ちいさな、ちっちゃな、ちいさめの etc

##### アクセス権限
+ デバイスアドレス
	+ 端末の住所を取得可能
+ リスト
	+ リストへの読み書きが可能
+ プッシュ通知（デベロッパープレビュー）

##### ダイアログモデル

##### SSML
サウンドライブラリも使える。
より自然な発話ができる


#### 品質テスト

#### テストと認証

## 宣伝
### 子供向けスキルの開発ができるようになりました！
### Tシャツキャンペーンもあるよ！
### Alexa AWSプロモーションクレジット
### ハンズオントレーニング
### マネタイズ、Amazon Payが使える（アメリカのみ）
AWS IoT


## MQTT プログラミング

### MQTT 通信方式
Publisher → Broker(Topic) → Subscriber(IoT rule/Operater)

BrokerとSubscriberは常時接続なので、ほぼリアルタイムでの通信が可能（一方向）
双方向にするには、PublisherとSubscriberを入れ替えて両方実装

#### SDK実装でpub/subをどう表現するのか？
keepAlive Time は個々の事例による

#### AWS IoT Core で利用できるQoS
QoS 0 or 1

対応していないが、QoS2もある
確実に1度だけ送信する機能

#### サンプルアプリ
SDKの中にサンプルがあるので、それを活用する

#### 必ずMQTTを使う必要はない
ニアリアルタイムの双方向通信 = MQTT
データ送信のみ = MQTT or HTTP

コストでの分類
固定回線 = MQTT or HTTP
SIM = メッセージ頻度が高い場合はMQTT

MQTT をポート443で利用できるようになったので、B2Bでも利用可能な可能性が高くなった


## IoT Core 活用
### アンチパターン
shadowに全センサー共通のtopicを参照するような設計

shadowを使うと有効なケース：結果整合性で同じ状態になってほしい場合
pub/subを使うと有効なケース：メッセージング

### ルールエンジンの組み込み関数
##### thing名の取得方法
+ payloadのjsonの中にthins名を入れる
+ MQTT接続の際に使ったclientIDをルールエンジンで取得する
+ MQTT topicを利用する

ルールエンジン、topicを有効活用することで、皇族のLambdaの処理を軽減することができる

## デザインパターン
AWSを使った動画配信入門


## Agenda
+ 動画配信の基本知識やトレンド
+ なぜクラウドなのか
+ AWSのメディア配信サービス

## 動画配信 基本のキ
### 動画配信とは
コンテンツプロバイダーから配信ネットワークを使ってプレイヤーに配信するもの

+ オンデマンド配信 VOD（収録済みのものをいつても自由に見る）
+ ライブ配信 LIVE（ほぼリアルタイムに配信）
+ リアルタイム（双方向性）配信（インタラクティブな動画配信、テレビ会議など）

### 技術動向
#### 専用プロトコル
##### メリット
+ コンテンツ保護
+ 遅延が少ない
+ 細やかな再生制御

##### デメリット
+ 専用プレイヤー
+ 専用サーバ

#### HTTP
##### メリット
+ 標準プレイヤーやプラグインで再生可能
+ WebサーバでOK

##### デメリット
+ VODのみ
+ 細やかな再生制御ができない
+ コンテンツ保護

#### HTTPストリーミング
##### メリット
+ 標準プレイヤーやプラグインで再生可能
+ WebサーバでOK
+ LIVEにも対応

##### デメリット
+ 標準化がまだされていない（現在進行系）

##### 概要
+ メディアコンテナファイル
+ マニュフェストファイル

プレイヤーは、先ずマニュフェストを要求し、そのマニュフェストに記載されているコンテナファイルを要求-配信する

### トレンド
+ 視聴環境の多様化
	+ プレイヤー
	+ ネットワーク

#### Multi Bitrate / Adaptive Bitrate

#### サポート状況
プラグインが必要なものは減り、OSネイティブなものが増えている
普及競争から標準化へ。

## なぜクラウド（AWS）なのか
### マルチデバイス/マルチビットレートへの対応
→ クラウドの「必要なときに必要なだけ低価格」という部分の親和性が高い

### 初期投資/余剰設備
→ スモールスタート＆成長に合わせたスケールが可能なクラウド
変化に強いインフラを
マネージドインフラの利点

### スパイクアクセス体制/対障害性
+ ライブ配信は開始と同時に一斉にアクセスが発生
+ Design for Failure
+ マネージドサービス

### 豊富なサービス群

### 豊富なお客様事例

## 構築例
### オンデマンド配信
+ 素材ファイル
	+ S3 フルマネージドオブジェクトストレージサービス
+ ファイルベーストランスコード、VC
	+ AWS Elemental MediaConvert
	+ Lambda
	+ AWS Step Functions
	+ EC2 秒単位での課金
+ 配信用メディアファイル
	+ S3
+ CDN
	+ CloudFront

### ライブ配信
+ ライブチャンネル
+ ライブエンコーダ
	+ AWS Elemental MediaLive
	+ AWS Elemental MediaPackage
+ 配信用メデイアファイル
+ CDN
	+ CloudFront

## イベントについて
Blackbelt
MySQL でメモリ不足が発生したときのパラメータチューニング

```
$ mysql
Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug
```

上記のエラーが発生して MySQL に接続できなくなった場合、MySQL がメモリ不足となっている可能性があります。

## メモリ使用量の計算
MySQL のメモリ使用量は、以下のような計算式で調べることができます。

```
メモリ使用量 = グローバルバッファ + (スレッドバッファ * コネクション数)
```

このメモリ使用量が物理メモリサイズを超えると、メモリ不足が発生する可能性が高まるので、
物理メモリサイズを超えないように、バッファサイズとコネクション数を調整します。

### グローバルバッファの設定
MySQL のバッファには、グローバルとスレッドの2種類があります。

グローバルバッファは MySQL 全体で1つ確保されます。
グローバルバッファサイズに関連するパラメータは下記のとおりです。

- key_buffer_size
    - MyISAM で使用するバッファサイズ
    - MyISAM を利用してなければ小さくてもOK
- innodb_buffer_pool_size
    - InnoDB で使用するバッファサイズ
    - 搭載メモリの80%程度
- innodb_log_buffer_size
    - InnoDB で使用するログバッファサイズ
    - innodb_buffer_pool_sizeの25%程度(最大でも64MB)
- net_buffer_length
    - 送受信するパケットを格納するパケットメッセージバッファサイズの初期値

### スレッドバッファの設定
スレッドバッファはスレッド (コネクション) 毎に確保されます。
スレッドバッファに多くのメモリを割り当てると、コネクションが増えた際にすぐメモリ不足になってしまうので注意が必要です。
スレッドバッファサイズに関連するパラメータは下記のとおりです。

- sort_buffer_size
    - ソート処理に利用される
- read_buffer_size
    - インデックスを使わないテーブルフルスキャン時に利用される
- read_rnd_buffer_size
    - インデックスを利用したソートに利用される
- join_buffer_size
    - インデックスを使わない結合に利用される
- myisam_sort_buffer_size
    - MyISAM テーブルのインデックス作成に利用される

### コネクション数

- max_connections
    - 最大コネクション数

## 確認方法
以上を踏まえた計算式で、現在の設定を確認するクエリがこちらになります。

```
mysql> select
  @@global.key_buffer_size + @@global.innodb_buffer_pool_size + @@global.innodb_log_buffer_size + @@global.net_buffer_length as global_buffer_size,
  @@global.sort_buffer_size + @@global.myisam_sort_buffer_size + @@global.read_buffer_size + @@global.join_buffer_size + @@global.read_rnd_buffer_size as thread_buffer_size,
  @@global.key_buffer_size + @@global.innodb_buffer_pool_size + @@global.innodb_log_buffer_size + @@global.net_buffer_length
  + (@@global.sort_buffer_size + @@global.myisam_sort_buffer_size + @@global.read_buffer_size + @@global.join_buffer_size + @@global.read_rnd_buffer_size) * @@global.max_connections as total_memory_size;
+--------------------+--------------------+-------------------+
| global_buffer_size | thread_buffer_size | total_memory_size |
+--------------------+--------------------+-------------------+
|          159399936 |            9306112 |        1564622848 |
+--------------------+--------------------+-------------------+
1 row in set (0.00 sec)

```

この場合、`total_memory_size` は 1564622848 / (1024 * 1024 * 1024) で約 1.45 GB となります。
例えば RDS の db.t2.micro だと、物理メモリサイズは 1 GiB = 1073741824 bytes で約 1.07 GB であるため、最大コネクション数までコネクションが増えた場合にメモリ不足になる可能性が高くなります。

## 参考
- [MySQL 5.7 Reference Manual - 8.12.4.1 How MySQL Uses Memory](https://dev.mysql.com/doc/refman/5.7/en/memory-use.html)
- [5分でできる、MySQLのメモリ関係のチューニング！](http://dsas.blog.klab.org/archives/50860867.html)
- [MySQLのパラメータチューニング](http://canalize.jp/1621.html)
- [MySQL最低限のメモリ設定](https://qiita.com/zaburo/items/65bac3b8e0a635ada68c)
- [MySQLのメモリ関係のシステム変数](http://tetsuyai.hatenablog.com/entry/20111006/1317873012)
コンピュータには画像がどう見えているのか？

あるセミナーで、うちのチームの親分が『コンピュータが見ている画像は人が見ている画像とは異なって解釈して特徴をとらえている。』と説明していたのだけど、イマイチ参加者の方々がピンと来ていないような感じだったけどオイラ的には『ビビビ！！！』って感電してメチャわかりやすい説明やん！！！って思った。
コンピュータにとっての画像とは、色を数値化して、その色が画像(X,Y軸)上のどこにあるか？っていうただの数値の配列でしかありません。なのでコンピュータは、こんな感じにでも特徴をとらえてるんじゃね？っていうサンプルとして、画像データを分解して、どの色がどのように含まれているかRGB色を mplot3d の scatterplot で3D散布図として描いてみました。

## 処理概要
画像ファイルをnumpyの配列に入れて、1pix毎の情報を[R,G,B]のリストとして得て、ループ処理で１つ１つ取得した色で、X 軸に R、Y 軸に G、Z 軸に B として、プロットしていく。
 


## 入力画像
画像処理の世界ではお決まりのレナさん。
ちなみに、この画像が載っていた1972年11月号の「PLAYBOY」誌は 7,161,561部も販売され（発行部数ではなく、実売部数）いまだ破られていない最多販売部数として記録されているそうですよ。すげ～
http://www.lenna.org/ ←詳しくはこちらを参照

![lena.jpg](https://qiita-image-store.s3.amazonaws.com/0/255677/90ee669d-6076-2b7c-d19b-3bf4ab3eb9f5.jpeg)


## ソースコード
画像は512 × 512 ピクセル = 262,144 回のループ処理で3Dグラフにマッピングしているため<font color="Red">激しく遅いです。
画像を出力するまでマックスくん環境のPC( Corei7-7700HQ/GeForce GTX 1060)で15分くらいかかります。</font>GPUは使っていません。出力されたグラフも回転させてさまざまな角度から見ることができますが遅くて気が遠くなります。

~~~py

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import datetime # 遅いから不安なので時間を出してみた。

# today()メソッドで現在日付・時刻のdatetime型データの変数を取得
d = datetime.datetime.today()
print (d.strftime("%x %X") )

# 画像→配列変換
img_path = 'lena.jpg' # レナさん画像
img = Image.open(img_path)
imgArray = np.asarray(img) # PILToNumpy

# 画像サイズ取得
maxcol, maxrow = img.size # get img size

# 画像サイズの出力この回数ループ処理が走る。
print ('input img size : ',str(maxcol) ,'*',str(maxrow),'=', str(maxcol * maxrow))

# numpy配列を書き換え可否の設定。
imgArray.flags.writeable = False # 今回の処理ではどちらでもよいが特に書き換える必要がないのでFalseにした。

# Figureのインスタンスを生成
fig = plt.figure()

# Axes3D のインスタンスを生成(描画領域の設定)
ax = fig.add_subplot(111, projection='3d') #111 は、1x1グリッド、第1のサブプロットを意味しています。

# プロットするRGBカラーの初期化
RGB_R = 0.0
RGB_G = 0.0
RGB_B = 0.0

# 画像サイズぶん回すよ！
for i in range(maxrow):
    for j in range(maxcol):

        # 1つ1つピクセルのRGB色を分解して取得してます。
        X = imgArray[i,j][0] #R
        Y = imgArray[i,j][1] #G
        Z = imgArray[i,j][2] #B

        # プロットする色を出すために計算してます。
        RGB_R = X*1.0/255.0
        RGB_G = Y*1.0/255.0
        RGB_B = Z*1.0/255.0

        # プロットする色を作ってます。
        RGB_color = (RGB_R,RGB_G,RGB_B)

        # XYZの位置にプロットする。 c は色、s はプロットした点のサイズ。
        ax.scatter(X, Y, Z, c=RGB_color ,s=1 )

# XYZ軸のラベルをRGBにする。
ax.set_xlabel('R')
ax.set_ylabel('G')
ax.set_zlabel('B')

# today()メソッドで現在日付・時刻のdatetime型データの変数を取得
d = datetime.datetime.today()
print (d.strftime("%x %X") )

# 3Dプロットした画像の出力する。実はこれも時間かかる。激しく重い処理のようだ。
plt.savefig("mplot3d_scatterplot.png")

# today()メソッドで現在日付・時刻のdatetime型データの変数を取得
d = datetime.datetime.today()
print (d.strftime("%x %X") )

# 3Dプロットした画像を画面に出力する。実はこれも時間かかる。激しく重い処理のようだ。
plt.show()


~~~

## 出力結果
こんな感じ。
レナさん画像はこのような色の配置パターンとなっています。
もしかしたらコンピュータは、この色の配置で女性らしさというパターンを解釈して特徴点としてとらえいるかもしれません？:thinking:

![mplot3d_scatterplot.png](https://qiita-image-store.s3.amazonaws.com/0/255677/6daa1bd1-9b40-f42b-20e9-1155967d7c96.png)




## 参考資料
http://effbot.org/zone/pil-changes-116.htm
https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#scatter-plots
システムの復元でログインパスワード未設定の頃を指定し復元すると、パスワード無しでログイン出来る。

パスワードかかっているから安心、というものでもない様子。

windows10にて確認。

OSインストール直後からパスワード未設定のままで、
今日、パスワード設定した。

[システムの復元](https://121ware.com/qasearch/1007/app/servlet/relatedqa?QID=017721)を行うとパスワードも設定前のものに戻る。

その後SHIFT押しながらOS再起動し、`システムの復元`を前の日を指定すると、パスワードも未設定になる。
WSL で fakeroot

## <i class="fa fa-paw fa-fw"></i>困ったのでメモ
`WSL` では `SYSV IPC` が実装されていないので，`fakeroot-tcp` を使用する．

```bash
$ update-alternatives --set fakeroot /usr/bin/fakeroot-tcp
```

TeXLive のダミーパッケージ作成時に遭遇しました(equivs-build 実行時)．
How to Install .NET Core 2.1 SDK (v2.1.301) in Ubuntu 18.04 LTS?

# 1. Download .NET Core SDK
https://www.microsoft.com/net/download/linux


# 2. Register Microsoft key and feed
```
$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
$ sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
$ sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
$ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
```

# 3. Install
```
$ sudo apt-get update
$ sudo apt-get install apt-transport-https
$ sudo apt-get install dotnet-sdk-2.1
```

# 4. Check .NET Core SDK Version
```
$ dotnet --version
2.1.301
```

# 5. Create and Run Project
```
$ dotnet new console -o myApp
$ cd myApp
$ dotnet run
Hello World!
```

https://www.microsoft.com/net/learn/get-started/linux/ubuntu18-04
Kubernetes（GKE）でHTTPS通信する方法

### 本記事について
Google Cloud Platform のKubernetes(GKE)でHTTPS通信する方法についてまとめました。

## はじめに
Kubernetesが外部と通信できるようにするには

- Serviceによる方法
- Ingressによる方法

の2通りのやり方があります。

- https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip?hl=ja
- https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer?hl=ja#background

Serviceによる方法では、外部IPはGCPのロードバランサーに直接接続され、外部からのデータはロードバランサーの機能により、KubernetesのServiceに分配されます。ロードバランサーは単純にデータを分配するだけで、外部からのデータはそのままServiceに流されるため、HTTPSの処理はデータを受け取ったKubernetesの内部のPodで処理する必要があります。

Ingressによる方法では、外部IPはIngressというKubernetesのルーティングを行う所に接続され、Ingressは設定に応じて、KubernetesのServiceにデータを分配します。Ingressは内部的にはnginxで作成されており、外部からのHTTPSをHTTPに変換してServiceに流すといった、通信内容に応じたルーティングが可能になります。

本記事では、Ingressを使ったHTTPS通信を行い、IngressでHTTPSをHTTPに変換し、KubernetesにはHTTPを送るように設定します。

## 手順
### 外部IP
Ingressの外部IPは「global」である必要があり、「regional」では動作しません。そこで「global」なstatic IPを用意します。

### シークレットの作成
証明書と鍵のセットをシークレットとしてKubernetesに登録し、そのシークレットを参照する形でIngressを作成します。
まずは、シークレットの作成を行います。

```sh
kubectl create secret tls <シークレット名> \
    --key <鍵ファイル> \
    --cert <証明書ファイル>
```

### Ingressの作成
```yaml:ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
    name: ingress
    annotations:
        kubernetes.io/ingress.allow-http: "false"
        kubernetes.io/ingress.global-static-ip-name: "<外部IP名>"
    labels:
        app: ingress
spec:
    tls:
    - secretName: ＜シークレット名>
    backend:
        serviceName: <接続先Service名>
        servicePort: <接続先ポート番号>
```
（HTTPSのみを許可し、HTTP通信は不可としています）

「ingress.yaml」でIngressを作成

```sh
kubectl create -f ingress.yaml
```

### ヘルスチェックの確認
以上でIngressが作成され、外部からHTTPSで通信できるようになります。
Ingressが作成されると、Kubernetesはロードバランサーを作成し、ヘルスチェックの設定も行います。

- [GCP]-[ネットワークサービス]-[負荷分散]-[<ロードバランサー名>]-[ヘルスチェック]

でヘルスチェックの詳細が見れます。

このヘルスチェックをパスしないと、Ingressへデータが流されず、動作しませんので注意が必要です。
デフォルトのヘルスチェックはHTTPで「/」アクセスをチェックしていますので、接続先ServiceでHTTPで「/」にアクセスできるようにしておく必要があります。

## 関連記事
- [Kubernetes（GKE）でHTTPS通信する方法（Ingress編）](https://www.kwbtblog.com/entry/2019/01/03/112619)
【事前準備用】ansible実行専用ユーザー作成からSSH接続できるようになるまで

インフラエンジニア歴約2か月弱、Ansibleのモジュール開発を行う事になったのでその事前準備をしました。
Ansibleは設定を流したいサーバーにssh接続さえできれば、OSの設定やパッケージのインストールなどの重要作業が複数のサーバーに同時に実行できますが、それは誤った作業をすればクリティカルな問題を引き起こす要因にもなりえるという意味にもなります。

ですので、誤操作対策のためにAnsible実行専用ユーザーを作成し、必要に応じて都度特権を与えるという運用にします。

※参考資料：https://www.amazon.co.jp/Ansible%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-impress-top-gear/dp/4295003271

<操作環境>
ansibleサーバー：ubuntu18.04
処理対象サーバー：centos7.4

手順①：AnsibleサーバーにAnsible実行用のユーザーを作成する。
       以下の操作をAnsibleサーバー(今回の場合だとubuntuの方)で行う。

```
[root@username ~] hostnamectl set-hostname ansible-user 　#ansible-userは任意。ここではansible用なのでansible-userとしました。
[root@username ~] useradd -s /bin/bash -m ansible-user
[root@username ~] passwd ansible-user　#任意のパスワード設定
```

以下の操作を処理対象サーバーに対しても行う。

```
[root@username ~] useradd -s /bin/bash -m ansible-user
[root@username ~] passwd ansible-user　#任意のパスワード設定
```

ここまでできたら、公開鍵と秘密鍵をAnsibleサーバーに作成し、処理対象サーバーに接続できるようにします。

```
[root@username ~] su - ansible-user #Ansible用のユーザーになってから鍵を作成する。
#ログは省略
[ansible-user@username ~] ssh-keygen
[ansible-user@username ~] ssh-copy-id -i ~/.ssh/id_rsa.pub localhost 
[ansible-user@username ~] ssh-copy-id -i ~/.ssh/id_rsa.pub 処理対象サーバーのipアドレス
```

鍵は処理対象サーバーごとに配布していきます。私の場合、処理対象サーバーは5台ありましたので、処理対象サーバーにansible-userを作成＆鍵配布(ssh-copy-id -i ~/.ssh/id_rsa.pub 処理対象サーバーのipアドレス)×５をやりました・・・。

##考えた事##
これからAnsibleを導入しようとする場合、大規模システムだとサーバーが何百台もあるので、もしssh接続をやっていない状態だったらどうやってssh接続できるように設定していくのか悩みどころかと思いました。(上記作業を台数分やるのは骨が折れる・・・)
どのように導入ているのかは、海外事例も参考にしながら検討していくのが良さそうですね。

以上、自分のメモ用＆誰かの参考になれば幸いです。
ご指摘などあればどしどしお願いしますm__m
How to Install Visual Studio Code in Ubuntu 18.04 LTS?

# 1. Download VS Code
https://code.visualstudio.com/Download


# 2. Install
```
# sudo dpkg -i <file_name>.deb
```

#3. Troubleshooting (Optional)
```
Selecting previously unselected package code.
(Reading database ... 154365 files and directories currently installed.)
Preparing to unpack code_1.24.1-1528912196_amd64.deb ...
Unpacking code (1.24.1-1528912196) ...
dpkg: dependency problems prevent configuration of code:
 code depends on libgconf-2-4; however:
  Package libgconf-2-4 is not installed.

dpkg: error processing package code (--install):
 dependency problems - leaving unconfigured
Processing triggers for desktop-file-utils (0.23-1ubuntu3.18.04.1) ...
Processing triggers for gnome-menus (3.13.3-11ubuntu1) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Errors were encountered while processing:
 code

# sudo apt install libgconf-2-4
Reading package lists... Done
Building dependency tree       
Reading state information... Done
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
 libgconf-2-4 : Depends: gconf2-common (= 3.2.6-4ubuntu1) but it is not going to be installed
                Recommends: gconf-service
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).

# sudo apt --fix-broken install
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
  gconf-service gconf-service-backend gconf2-common libgconf-2-4
The following NEW packages will be installed:
  gconf-service gconf-service-backend gconf2-common libgconf-2-4
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
1 not fully installed or removed.
Need to get 845 kB of archives.
After this operation, 8,050 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

# sudo dpkg -i <file_name>.deb
```

# 4. Launch VS Code
![Welcome - Visual Studio Code_001.png](https://qiita-image-store.s3.amazonaws.com/0/150367/77f6b073-0778-a4a4-d7df-5fdbdf41eae3.png)
「(new HttpClient()).GetStringAsync("https://略");」が失敗する場合の対処

# 現象

.Net Framework 4.5.2 on Windows 10.0.17134.112 で。

```c"
HttpClient cli = new HttpClient()
string body = await cli.GetStringAsync("https://略");
```

とやったら、`GetStringAsync` で例外 `System.Net.Http.HttpRequestException` が発生した。
メッセージは「**この要求の送信中にエラーが発生しました。**」。
HRESULT は 0x80131500 。

innerException は `System.Net.WebException`。
メッセージは「**接続が切断されました: 送信時に、予期しないエラーが発生しました。**」。
HRESULT は 0x80131509 。

そのまた innerException は `System.IO.IOException`。
メッセージは「**リモート パーティがトランスポート ストリームを終了したため、認証に失敗しました。**」。
HRESULT は 0x80131620 。

同URLを Chrome や Edge でアクセスするとちゃんと見えるし、証明書もちゃんとしている。
リモートパーティとは何なのか。なぜ認証に失敗するのか。

# 効果のあった対策( 私の場合 )

で。

効果のあった対策は `new HttpClient()` の前に

```c#
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
```

を実行することだった。

例外が出た環境の `ServicePointManager.SecurityProtocol` の値は `Ssl3|Tls` になっていて、**TLS 1.2** が含まれていない。
一方今回アクセスしたサーバーは **TLS 1.0** や **TLS 1.1** をサポートしておらず、 **TLS 1.2** をサポートしていた。

`SecurityProtocolType.Tls12` を `|=` することで **TLS 1.2** を 有効にしたら例外が出なくなり、ちゃんと `body` に値が入った。

というか。
 https://qiita.com/tanj/items/31a0fd6b188952886de5
を発見したおかげで解決した。ありがとう！
Node.jsで自力でWake-on-Lan

こんにちわ。

Wake-on-Lanをしたくて、自力でUDP Socketやらバイト配列やらをゴニョゴニョした後に[wake-on-lan](https://www.npmjs.com/package/wake-on-lan)とか言うモジュールを見つけてしまったので、大した量じゃないですけど、作ったやつを供養として乗っけておきます。

jsでのバイト配列の勉強にはなったし無駄では無かった...無かった...

```javascript:WoL.js
const dgram = require("dgram");

const port = 9;
const address = "255.255.255.255";

const mac = "01-23-45-67-89-AB";

const packet = [
    "FF-FF-FF-FF-FF-FF", mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac, mac
].join("-").split("-");

packet.forEach((value, index, array)=>{
    array[index] = parseInt(value, 16);
});

const buffer = Buffer.from(packet);

const udp = dgram.createSocket("udp4");
udp.send(buffer, 0, buffer.length, port, address, (err, bytes)=>{
    console.log("MagicPacket has sent!");
    udp.close();
});
```
Perl DB定義書出力プログラム

## PerlでDB定義書エクセルファイルを作成
Perlモジュールを使ってエクセルファイルを作ります
ソースはこんな感じ。
設定を変えればPostgreSQL, MySQL 両方で使えます

```
#!C:\Perl\bin\perl
#!/usr/local/bin/perl

use strict;
use DBI;
use Jcode;
use Spreadsheet::WriteExcel;
use DBIx::DBSchema;

#設定
my $DSN	= 'dbi:mysql:DB名:サーバー名';
my $DB_USER = 'ユーザー名';
my $DB_PASSWD	= 'パスワード';
my $XLS_FILE	= '出力ファイル名';

my $dbh = DBI->connect($DSN, $DB_USER, $DB_PASSWD) or die $DBI::errstr;
my $xls = Spreadsheet::WriteExcel->new($XLS_FILE);
my $schema = new_native DBIx::DBSchema $dbh;

for my $table ($schema->tables()) {
    my $work = $xls->addworksheet("$table");
    
    $work->write(0, 0, 'INDEXES');
    my $index_ref = $dbh->selectall_arrayref("SHOW INDEX FROM $table");
    write_worksheet($work, $index_ref, 1);
    
    $work->write(3 + $#{$index_ref}, 0, 'COLUMNS');
    my $column_ref = $dbh->selectall_arrayref("DESCRIBE $table");
    write_worksheet($work, $column_ref, 4 + $#{$index_ref});
}

$dbh->disconnect;


sub write_worksheet {
    my($work, $ref, $offset) = @_;
    for my $row (0 .. $#{$ref}) {
        for my $col (0 .. $#{$ref->[$row]}) {
            $work->write($row + $offset, $col, $ref->[$row]->[$col]);
        }
    }
}
```
Cloud Firestore 動的にクエリを作る【Go言語】

#はじめに
今回は前回の[AppEngine GoからCloud Firestoreを使ってみる](https://qiita.com/IJN-Penguin/items/b6252cd461b3966d53ac)に続いて動的にクエリを生成する方法となります。

**この記事ではFirestoreの初期化やクライアントの生成などは取り上げません。**
Go言語(AppEngine Go含む)でのFirestore利用方法は[Firestore公式のドキュメント](https://firebase.google.com/docs/firestore/quickstart?hl=ja)か以前書いた[こちら](https://qiita.com/IJN-Penguin/items/b6252cd461b3966d53ac)の記事を参照して下さい。

##動的なクエリの作り方
この記事では『フォームデータの入力のあり、なしでクエリを変えたい』など、その都度違うクエリを発行したい場合を想定しています。

以下コード**(動的にクエリを作る部分以外かなり端折ってます)**

```go:main.go
import (
	firebase "firebase.google.com/go"
)
```

```go:main.go
/*
	ここでCloud Firestoreへの認証処理
	クライアントの生成など
*/

query := client.Collection("book").Query // コレクションBookへのクエリ

if title != "" { // フォームからのパラメタ'title'に値が入っていれば
	query = query.Where("title", "==", title) // クエリを追加
}

if author != "" {
	query = query.Where("author", "==", author)
}

if circle != "" {
	query = query.Where("circle", "==", circle)
}

// ctxの生成は context.Background()
// AppEngine Goであれば appengine.NewContext(r)

iter := query.Documents(ctx) //クエリを実行してiterに結果を格納
```

上記のように書くことで必要なクエリを動的に連結させる事が可能になります。
上のコードでは図書の検索フォームからデータを持ってきて入力されている項目に関するクエリのみを連結しています。
#あとがき
フォームのデータ入力の有無によってクエリを連結させる方法は検索しても出てこなかったためここにメモしておこうと思います。
間違っている点などありましたらコメントお願い致します。
Active Adminで出力されるCSVの文字コードをシフトJISにする

# 設定方法
version 1.0 からは以下の記述でシフトJISをCSVファイルに出力できます。
（Active Admin 1.3.0 で確認）

```ruby:app/admin/posts.rb
ActiveAdmin.application.csv_options = { encoding: 'SJIS' }
ActiveAdmin.register Post do
  csv do
    # ...
  end
  # ...
end
```
# 参考
[activeadmin/features/index/format_as_csv.feature]
(https://github.com/activeadmin/activeadmin/blob/master/features/index/format_as_csv.feature)
便利なruby関数each_slice

配列に対して、数項目ごとにグループ化してから何かの処理を行いたいときに、`each_slice`関数がぴったりです。

>
each_sliceメソッドは、引数nで指定した数の要素を繰り返し取り出して、ブロックを実行します。ブロック引数arrには、取り出した要素が配列で入ります。
要素数がnで割り切れないときは、最後に余りの要素を取り出します。nの数が要素数より大きいときは、すべての要素を取り出してブロックを1度だけ実行します。


```ruby
(1..8).each_slice(3).map {|arr| arr }
=> [[1, 2, 3], [4, 5, 6], [7, 8]]
```
CircleCIで.gitディレクトリをキャッシュしてチェックアウトを高速化する

最近でCircleCIおじさんになっているりんご（[@mstssk](https://twitter.com/mstssk)）です。

今やっているプロジェクトのgitリポジトリが大きくなりすぎて、CircleCIでの `checkout` の実行に何分もかかってしまっています。
以前は2〜3分だったのが、先日は8分もかかってました。

思い切って.gitディレクトリをキャッシュしてしまうようにして、10秒前後で済むようにしてみました。

**追記2019/02/19**
本記事の内容を試す前に、あなたがCircleCIで使っているDockerイメージにgitとsshがインストールされているか確認しましょう。
gitとsshが無い場合、CircleCIがFallbackしてチェックアウトを行ってくれるのですが、これはイメージ上のgitとsshを使うより遅いようです。
FallbackしているかどうかはCircleCIの各ジョブのページでCheckout codeステップのログを見ればわかります。

## 参考記事

やった内容は、下記の公式ドキュメントとクラウドワークスさんのエンジニアブログ記事を参考にしたものです。

- Caching Dependencies - CircleCI  
  https://circleci.com/docs/2.0/caching/#source-caching
- CircleCI 2.0に移行して新機能を活用したらCIの実行時間が半分になった話 - クラウドワークス エンジニアブログ  
  http://engineer.crowdworks.jp/entry/2017/04/04/202719

クラウドワークスさんの記事には、.gitのキャッシュではなく、shallow cloneすることでチェックアウトを高速化する手段が書かれていますが、私は.gitをキャッシュする方法を選択しました。
キャッシュの方法は公式ドキュメントに記載されているからというのもありますが、CircleCI上でshallow　cloneするには別途GitHubのアクセストークンを用意する必要があり管理上の手間が増えてCIの管理が属人化しすぎるのを嫌ったためです。

## CircleCIで .git ディレクトリをキャッシュする

実際のCircleCIの設定ファイルは以下のように記述しています。

```yaml:.circleci/config.yml
version: 2
jobs:
  foobar-job:
    steps:
      # 公式ドキュメントに書いてある.gitをキャッシュするやり口
      # https://circleci.com/docs/2.0/caching/#source-caching
      - restore_cache:
          keys:
            - dot-git-cache-{{ .Environment.CACHE_KEY }}-{{ .Branch }}-{{ .Revision }}
            - dot-git-cache-{{ .Environment.CACHE_KEY }}-{{ .Branch }}-
            - dot-git-cache-{{ .Environment.CACHE_KEY }}-
      # レストア時にワーキングディレクトリがcleanじゃないことがあったのでhard reset。echoはexit code食わせるため
      - run: git reset HEAD --hard || echo ng
      - checkout
      - save_cache:
          key: dot-git-cache-{{ .Environment.CACHE_KEY }}-{{ .Branch }}-{{ .Revision }}
          paths:
            - ".git"
```

- `restore_cache` の `keys` を複数指定しているのは、合致するキャッシュがなければ別コミット・別ブランチのCIのキャッシュを拾うためです。
- `{{ .Environment.CACHE_KEY }}` は任意にキャッシュをクリアするため。CircleCIで `CACHE_KEY` という環境変数に適当な文字列を入れておいて、キャッシュをクリアしたいときに値を変えることでキャッシュのキーを変えてしまっています。
- `git reset HEAD --hard || echo ng` は、レストア時にワーキングディレクトリがcleanじゃないことがあったためです。キャッシュをレストアしない場合は git reset が失敗するので、echoでexit code食わせてごまかしています。
- .gitディレクトリをキャッシュからレストアした状態で、CircleCIの `checkout` を使うと、ちゃんとレストアした.gitを使ってくれるので、差分だけの取得になり高速になります。

このやり方の注意点として、変なブランチ名の付け方をしてしまったときに、キャッシュ済みのリポジトリ情報と新しいブランチ名が衝突してうまくチェックアウトできない場合があります。
具体的には `feature/foo/bar` というブランチを作ったあと、それを消して `feature/foo` というブランチを作ると、キャッシュからレストアした.gitディレクトリに `feature/foo/` が既にいるので `feature/foo` のチェックアウトに失敗します。
めったにないことですし `CACHE_KEY` を変更すれば済むので、これについては特別な対応はしていません。
Mean_Encodeをやってみた

#概要
カテゴリカル変数の処理の仕方にMean_encodeというものがあります。
これは,カテゴリ別にターゲット変数の平均などの統計量を特徴量として渡すというもので、
それをPythonで実装した。

#疑似データ作成
sklearnで提供されているデータセットで
カテゴリ変数がいい感じに含まれているものがなかったので
適当に作成します

```py3:get_datasets

import pandas as pd
import numpy as np

target = np.random.randn(100)
fruit = ["apple", "banana", "strawberry", "peach", "orange"]*20
color = ["red","yerrow","red","pink","orange"]*20

df = pd.DataFrame({"value":target,"fruit":fruit,"color":color})

```


上位5件を見てみるとこんな感じです。

```py3:
df.head()
```

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/143479/845f6d92-2482-eef0-cd05-8b32ada71a42.jpeg)


#過学習を避けるために

Kaggleのコンペでの経験から、それぞれのカテゴリの出現頻度はかなり差が見られることが多いです。
観測母数が少ないデータではそのカテゴリでのターゲット変数の平均値がそのままターゲット変数になってしまい、
過学習する原因となってしまうので、少し工夫必要です。

よってKfoldを利用してデータを分けてenocdeするコードを書きます。


#Mean_Encode実装

こんな感じで関数は実装しました。

```py3:target_encode

def target_encode(train,df,target,categorical):
    for col in categorical:
        tmp = pd.DataFrame(train.groupby(col)[target].agg(["mean","sum","count","std","var","max","min","median"])).fillna(-999)
        tmp.reset_index(inplace=True)
        tmp.columns = [col,col+"_mean",col+"_sum",col+"_count",col+"_std",col+"_var",col+"_max",col+"_min",col+"_median"]
        df = pd.merge(df,tmp,how="left",on=col)
        del(tmp)
    return df
```


3行目を見るとわかると思いますが,平均だけではなく分散や中央値など様々な統計量を指定しています。
Lightgbmなどに代表される木系のアルゴリズムは比較的特徴を取捨選択してくれるので,作れるだけ特徴を作るようにしています。



```py3
from sklearn.model_selection import KFold

kf = KFold(n_splits = 10,shuffle=True)
categorical = ["fruit","color"]

dfs = []
for train_index, test_index in kf.split(df):
    tmp = target_encode(df.loc[train_index],df.loc[test_index],"value",categorical)
    dfs.append(tmp)

return_df = pd.concat(dfs,axis=0)

```
最終的にreturn_dfという名前のデータフレームに結果が返ってくるようにしています。


return_dfの先頭5行を見てみます。

```py3
return_df.head()
```

![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/143479/1853e274-9ab6-2d63-f4d3-390c075a6413.jpeg)

全ての列が入り切れていませんが、きちんと動いています。

#参考文献

https://ja.coursera.org/lecture/competitive-data-science/concept-of-mean-encoding-b5Gxv


#追記
https://www.kaggle.com/c/avito-demand-prediction/discussion/59881

こちらのDiscussionにあるように地域別やアイテム別の値段の平均などを取得し,レコードの値段がその集合内でどのような特徴をもつのかを組み込むと有効みたいな戦略がありました。こちらの記事を利用してできると思います。
Perl XML-RPC画像投稿の例

## XML-RPCを使って画像付きの記事をブログに投稿する例
シーサーブログやfc2ブログで運用実績あり

```pl
#!c:\perl\bin\perl
#!/usr/bin/perl
use　strict;
use　warnings;

use　IO::Handle;
use　Data::Dumper;
use　XMLRPC::Lite;
use　File::Basename;

{
　　　my　$blogid　　=　"ブログＩＤ";
　　　my　$username　=　"ユーザー名";
　　　my　$password　=　"パスワード";
　　　my　$proxyurl　=　"ブログのXMLRPC先";

　　　# 画像パス
　　　my　$filename　　=　"C:/images/xxxx.jpg";

　　　my　$bits　=　read_bin_file　($filename);

　　　# 
　　　# ここで画像を投稿する
　　　# いまのところ１枚単位
　　　# 
　　　my　$picresult　=　XMLRPC::Lite
　　　　　　->　proxy($proxyurl)
　　　　　　->　call('metaWeblog.newMediaObject',　$blogid,　$username,　$password,
　　　　　　{
　　　　　　　　'bits'　=>　XMLRPC::Data->type('base64',　$bits),
　　　　　　　　'type'　=>　"image/jpeg",
　　　　　　　　'name'　=>　basename($filename)
　　　　　　}
　　　　　　)
　　　　　　->　result;
　　　if　(!defined　($picresult))
　　　{
　　　　　　die　"failed　$!";
　　　}
　　　else
　　　{
　　　　　　#
　　　　　　#　本文の投稿
　　　　　　#
　　　　　　my　$msgresult　=　XMLRPC::Lite
　　　　　　　　　->　proxy($proxyurl)
　　　　　　　　　->　call('metaWeblog.newPost',　$blogid,　$username,　$password,
　　　　　　　　　　　　{
　　　　　　　　　　　　　　　'title'　　　　　　　　　　　　　=>　"this　is　the　title",
　　　　　　　　　　　　　　　'description'　　　　　　　=>　"and　this　is\n\n"　.
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　"the　body　and　a　link　to　the　picture\n\n"　.
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　"{'url'}　.　"\">\n\nthe　end　:-)\n",
　　　　　　　　　　　　　　　'mt_allow_comments'　=>　1,　　#　must　be　int,　not　string
　　　　　　　　　　　　　　　'mt_allow_pings'　　　　=>　1　　　#　must　be　int,　not　string
#　　　　　　　　　　　　　　'mt_convert_breaks'　=>　"",　#　string,　see　mt.supportedTextFilters　for　a　valid　value
#　　　　　　　　　　　　　　'mt_text_more'　　　　　　=>　"",　#　the　extended　entry
#　　　　　　　　　　　　　　'mt_excerpt'　　　　　　　　=>　"",
#　　　　　　　　　　　　　　'mt_keywords'　　　　　　　=>　"",
#　　　　　　　　　　　　　　'mt_tb_ping_urls'　　　=>　??,　#array　of　strings,　ping　URLs
　　　　　　　　　　　　},
　　　　　　　　　　　　1　#　1　=　publish
　　　　　　　　　　　　)
　　　　　　　　　->　result;
　　　　　　if　(!defined　($msgresult))
　　　　　　{
　　　　　　　　　die　"failed　$!";
　　　　　　}
　　　　　　else
　　　　　　{
　　　　　　　　　print　Dumper　($msgresult);
　　　　　　}
　　　}
}

# 
# 画像ファイル読み込み
#
sub　read_bin_file
{
　　　my　($filename)　=　@_;

　　　#　read　in　the　picture
　　　my　$fh　=　IO::Handle->new();
　　　open($fh,　$filename)　or　die　"$!";
　　　local($/)　=　undef;　　#　slurp
　　　binmode($fh);
　　　my　$bits　　=　<$fh>;
　　　close($fh);
　　　return　$bits;
}
```
【Swift】DateIntervalFormatterで日付や時刻の範囲を出力する

＊[前回の記事](https://qiita.com/tamadeveloper/items/b5eff5b43599bba3058a)ではDateFormatterを使った日付の出力について説明しました。

# 日時の範囲を表示する

例えば「2018年5月10日〜5月20日」「午前10時〜午前11時」のように日付や時刻の範囲を表示する場合には、`DateIntervalFormatter`を使います。

```swift
let date1 = Date()
let date2 = date1.addingTimeInterval(3600*24)

let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short

print(formatter.string(from: date1, to: date2))

// 出力：Jun 24, 2018, 8:20 PM – Jun 25, 2018, 8:20 PM（英語の場合）
// 出力：2018/06/24 20:20～2018/06/25 20:20（日本語の場合）
```

`dateTemplate`を使うとより細かく日付や時刻を指定できます。

```swift
let date1 = Date()
let date2 = Calendar.current.move(date1, byDays:30)

let formatter = DateIntervalFormatter()
formatter.dateTemplate = "yMMMd"

print(formatter.string(from: date1, to: date2))

// Jun 24 – Jul 24, 2018
// 2018年6月24日～7月24日
```

上記のように日付のみの範囲を表示する場合、同じ年であれば2018年は1度しか表示されない、など気の利いた表示をしてくれます。またシステム設定で和暦を指定している場合は、「2018年」の代わりに「平成30年」と表示されます。

また以下のように月が同じ場合は6月が1度しか表示されず、短くて分かりやすい表示になっています。

```swift
let date1 = Date()
let date2 = Calendar.current.move(date1, byDays:3)

let formatter = DateIntervalFormatter()
formatter.dateTemplate = "yMMMd"

print(formatter.string(from: date1, to: date2))

// Jun 24 – 27, 2018
// 2018年6月24日～27日
```

以下のようにして時刻のみの出力も可能です。

```swift
let date1 = Date()
let date2 = date1.addingTimeInterval(3600)

let formatter = DateIntervalFormatter()
formatter.dateTemplate = "jm"

print(formatter.string(from: date1, to: date2))

// 8:20 PM – 9:20 PM（英語）
// 20:20～21:20（日本語）
```

システム設定で12時間表示を指定している場合は、「午後8時20分~午後9時20分」と表示されます。
Visual Studio Codeが1.15版で認証プロキシに対応していた

メモ。使い始めたころにはいつも通り認証プロキシを超えるのに四苦八苦していたけど、以下のバージョンでプロキシ認証に対応していた。

* [Visual Studio Code July 2017](https://code.visualstudio.com/updates/v1_15#_proxy-server-authentication)

プルリクエストを見ると、以下のバージョンでも関連修正が入っているみたい。

* [Visual Studio Code August 2017](https://code.visualstudio.com/updates/v1_16)
* [Handle proxy authentication by joaomoreno · Pull Request #22369 · Microsoft/vscode](https://github.com/Microsoft/vscode/pull/22369)

VSCodeを1.14版から最新の1.24.1版に更新したら、次のような認証ダイアログが出て、認証プロキシ経由で簡単に拡張をインストールできた。プロキシサーバーの情報は、システム設定（WindowsであればIEやEdgeの設定）から自動取得されている。

![VSCode_Proxy_Auth.png](https://qiita-image-store.s3.amazonaws.com/0/55718/8a21683a-f1c3-6453-82e9-f213a993aeb7.png)

現在のドキュメントにはこうした形での[プロキシサポートが説明](https://vscode-doc-jp.github.io/docs/setup/network.html#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88)されているけど、使用しているバージョンがギリギリ古いことで動作しなくて、軽く悩んだ。これからの利用者ではまる人はいないはずだけど、去年の2017年6月より前にVSCodeをインストールしてまだ認証プロキシで消耗している人がいたら、VSCodeを更新するとよいです。
テキストがn文字以上の場合は切り捨てる

macOSのawkがUTF-8に対応してないようで、「日本語が含まれる文字列のn文字以降を切り捨ててかわりに`..`を付加する」みたいなことができなくて悲しい😢
`wc` `cut` `sed` は普通にUTF-8対応してるようだったので、これらを組み合わせて切り捨てをやってみることにしました。

```shell:truncate.sh
#!/bin/sh

max=${1}
read l
count=`printf ${l} | wc -m | tr -d ' '`

if [ ${count} -gt ${max} ]; then
  printf ${l} | cut -c 1-${max} | xargs printf '%s..'
else
  printf ${l}
fi
```

```shell-session:つかいかた
$ printf 'あいうえおかきくけこさ' | ./truncate.sh 10 | xargs echo
あいうえおかきくけこ..
```
head, tail, sedコマンドでファイルの中身を確認する

'context.txt'というファイルから先頭の100行目までを取り出すlinuxコマンド

```
head -n 100 'context.txt'
```

'context.txt'というファイルからページの後ろ100行目までを取り出すlinuxコマンド

```
tail -n 100 'context.txt'
```

'context.txt'というファイルから100行目から150目までを取り出すlinuxコマンド

```
sed -n 100,150p context.txt
```