OmniAICreator/Qiita-1.07M huggingface dataset:
katalon Studio 使ってみた

手軽にテストを自動化できるKataron Studioを使ってみました

↓のサイトからユーザ登録しダウンロードし手軽にPCにインストールしたらアクティベートして起動できる
https://www.katalon.com/

######◆起動してみるとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/ca533acc-7c02-2925-b552-a0cad6bcf7fd.png)


######◆Web操作を記録してみる
このボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/961141d6-5a94-88c4-6d33-600fd13ac4f3.png)

記録のダイアログが出る WebRecorder
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/940f2e50-42c8-e304-e5e5-17ccaab6e8bc.png)

URLを入力して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/e2071ddb-6563-3f34-db80-224181afc373.png)


このボタンを押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/0b2b9474-8c82-4a86-8f1d-83ed81debe1b.png)

ブラウザが起動するので操作して画面を遷移してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/c7b07e0e-767f-ad70-8833-3283c82f82a4.png)

操作が記録されていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/463b2f56-9486-c9b7-7d9d-808294d627c0.png)

このボタン押すと記録終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/fd98745c-e793-565c-6509-0f5f667015ff.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/ada3613a-bc10-b1d4-d2ff-7ac33b10c6e2.png)
OKして次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/b5188362-b7f7-fb9d-fa87-678aedc5ba35.png)
OKして次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/d72bbad8-5879-60f3-1634-b4fc1546d6b1.png)
さらにOK押すと...
記録した操作が保存されているようです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/9c520231-8082-af6b-327e-417996a52d65.png)

######◆記録したものを再生してみる
実行ボタンを押してみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/886c3971-445a-0619-bfff-29c6bc360ec2.png)

記録した操作が再生されてる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/9fa858c3-808c-1ec3-83a8-ab7a35eec98a.png)

再生完了！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222266/9df665de-7146-cfe0-991e-8378ecf07457.png)

導入から操作の記録とその再生までしてみましたが思いのほか短時間でできました。
今回 単純な記録再生しかしてませんが、わりと高機能そうなので他にも色々なことができそうですね。
変数が一定数になってもチンパンジーみたいにウキーとなるのはやめよう的な

業務で小一時間悩んでやっと得た答えの備忘録

【事象】
Pythonのfor文でリストの長さの分だけ繰り返し、要素を取り出していく作業。
その際、変数xがある一定の数（例えば５）に達したら、０に戻したい。
でも変数xを０に戻すという定義（x=0）にすると毎回０にリセットされてしまう。
だけど、変数xはfor文でリストの長さの分だけ加算されていき、リストの要素を参照するときにリスト[x]と設定しているものだから、0になったらまた振り出しにもどり、続きから動いてくれなくなる。
さてどうしよう…と小学生でもわかりそうな問題に非理数系出身のアラサーは頭を悩ませた。

【サルと思わしき人間が書いたサンプルコード】

list = ["apple", "orange", "banana", "pineapple"]

for fruit in range(len(list)):

    if fruit > 2:
        fruit = 0
        print(list[fruit])
        fruits += 1
    else:
        print(list[fruit])

「どおじでまたappleに戻っちまうんだよおおおおおおお」
（ほんとはpineappleを出力したい）

もはや藤原竜也のようにIDEの前でのたうち回り、あーでもないこーでもないと試す。
これをサルではなく本物の人間が書いているのだから始末が悪い。
サンプルコードなので多少強引でリアル感がないが、入れ子構造にif文やらfor文を重ねていくとどんどんわからなくなっていくのはもはやお約束だ。
これは初学エンジニアや非エンジニアだけどプログラミングを始めたおにーさんおねーさんなら思い当たることだろう。入れ子構造は頭の良さそうなコードに見えて、その実複雑なだけになっていく死の構文である。
本日最大の学びは、入れ子は重ねずにシンプルにone if, one solutionじゃないけど、if文は重ねずに素直に次のアルゴリズムに渡しちまった方が早い時がある、ということだ。
書いてる時はなんとかその構造の中で解決することがプログラマーとしての能力の見せ所や！と思いがちだが、真実はシンプルでわかりやすく、誰が見ても「ああ、ここが分岐点なのね」とわかるコードを書くことだ。
もし同じような問題にぶち当たっている方がいたら、別に必ずしもコードは一つの構文にまとめなくてもいいんだと頭を切り替えていただきたい。私と同じようなチンパンジーコードを書く必要はない。

【ゼロよ、俺を導いてくれ…という解決コード】
i = 0

for fruit in range(len(list)):

    if fruit > 2:
        print(list[i])
        i += 1
    else:
        print(list[fruit])


おわかりいただけたであろうか…。
いや、偉そうに言うつもりも俺SUGEEEEでもなく、シンプルに最初にまったく関係ない変数iに0を代入しておくことにより、わざわざn=1,2,3...くらいまで進んでいるfruitをリセットしてやらなくてもいいという話だ。
さらにif分岐が重なる場合は、ちょっとコードが雑になるけど、i以外にもjだのkだのを用意してやればいい。
そうすれば全く別の変数を0から使って、条件を満たしたら加算していって…というファインプレーができるようになる。
いかんせん、サンプルコードが単純なだけに想像がつきづらいかもしれないが、アルゴリズムというのは必ずしも一つのブロックを巨大化してその中で解決しなければならないわけではなく、ダメなら別のアイテムと次のブロックを用意してやればいいんだというシンプルな話である。
言うなれば、マトリョーシカの中身がどんどん小さくて扱いづらくなったら、始めから別に作ったマトリョーシカをまた用意して、その中でやり直せばいいみたいな感じである（そうか？）

ここまで書いておいて何だが、変数はわかりやすい名称をつけるといいよと思う。
なぜならIDEによっては予測変換で最初の数文字さえ打てばサジェストしてくれるので、下手に短すぎてもともと用意された定数なのか判断がつかなくなる心配もないからだ。

ちなみにチンパンジーですら吊るされたバナナをとるのに複数の道具を組み合わせるのだから、人間が一つの構文にウキーとこだわる必要はまるでないという人生訓である（大嘘）
nodeバージョンを8系->12系に上げた際にやったこと

先日、Webアプリの静的ファイルビルドで利用しているnodeのバージョンアップを行いました。

nodeといいつつrubyも一部使っていたため一緒に上げていますが、以下、node+関連ライブラリバージョンアップのメモ書きです。

# 更新前の各種ライブラリ概要
* node（v8.11.1）
* yarn（1.16.0）
* gulp（3.9.0）
* webpack（4.1.0）
* ruby（2.4.2、jekyll用）

# やったこと
## nodeバージョンアップ
```
$ ndenv install v12.4.0
$ npm install -g yarn
```

## rubyバージョンアップ
```
$ rbenv install 2.6.3
```

## 各種nodeライブラリバージョンアップ
記事下方の参考リンクを見つつ、以下のタスクを行いました。

* node_modulesを最新に更新

```
$ yarn upgrade --latest
```
* gulp 3系 -> 4系に伴う修正
  * gulpfile.jsの修正
* babel 6系 -> 7系に伴う修正
  * babel-core -> @babel/coreに置き換え
  * polyfillのimportをやめた
* スプレット演算子（...）でエラーになっていたコードを修正
* webpackのplugin関連修正
  * ES5で対応止まっているuglify-jsをterserで置き換え
      * 他候補のbabel-minifyよりもteserの方がuglify-jsに近い使い方ができそうでした
      * uglify-js-pluginで使用していたuglify-save-licenseがそのまま使えました（extractComments: saveLicenseのようにオプションで指定できた）

# かかった期間
他の作業もやりつつですが、7営業日程度でした。

# 参考リンク
* https://qiita.com/teinen_qiita/items/18ca1fb433914e09c9e4#yarn-upgrade---latest
* https://satoyan419.com/gulp-v4/
* https://qiita.com/tatsuo-iriyama/items/08ba4bd621b7fdedcc4e
* https://qiita.com/oreo3@github/items/b383c57949e0f117cbea
* https://babeljs.io/docs/en/babel-polyfill
* https://ginpen.com/2018/12/20/spread-syntax/
* https://stackoverflow.com/questions/42633716/unexpected-token-punc-expected-punc-when-creating-chunk-from-uglifyjs
* https://www.monotalk.xyz/blog/Remove-all-JavaScript-comments-when-compressing-Webpack-4/
* https://qiita.com/shinnn/items/57327006390f2181f550
Spring Boot アノテーション学習用

自分の学習用です。


今のプロジェクトでSpring使い始めました。


Java , Springの特徴であるアノテーションをよくわかってない=>
効率的な実装ができない。Springを有効活用できていない。


App.javaにあるやつ
@SpringBootApplication
このアノテーションがついているクラスはSpring Bootのアプリケーションクラスであることを示します。
Springをbootさせるrunメソッドがある。
実行時に様々な設定情報を追加したいときに使う。

@EnableScheduling
スケジュール機能を有効にする。->@Scheduledの使用を許可

@Scheduled
メソッドの実行時間を指定可能。
アノテーションに以下の引数をとることで定期実行ができる。 
cronも使える。
詳細⇒https://qiita.com/rubytomato@github/items/4f0c64eb9a24eaceaa6e

Lombok（GetterやSetterを自動的に作ってくれるやつ）関連のアノテーション
3種類あります。
<span>@</span>NoArgsConstructor,<span>@</span>RequiredArgsConstructor, <span>@</span>AllArgsConstructor

これらの３つは、lombokでgetter/setterを作る際のコンストラクタを自動生成してくれるアノテーションです。

<span>@</span>NoArgsConstructor  引数無しのデフォルトコンストラクタを生成。
<span>@</span>RequiredArgsConstructorは、finalがついたフィールドへ値をセットするための引数がついたコンストラクタを生成。
<span>@</span>AllArgsConstructor　全フィールドに対する初期化値を引数にとるコンストラクタを生成


RequiredArgsConstructorの挙動


```
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class Employee {

    private final int id;

    private String name;
}

```
生成されるコード

```
public class Employee {
    private final int id;
    private String name;

    public Employee(final int id) {
        this.id = id;
    }
}
//final修飾子がついていないnameはコンストラクタに含まれていない。

```
進行中のPJでは
<span>@</span>RequiredArgsConstructor(onConstructor = <span>@</span>__(<span>@</span>Autowired))の形で使われています。

onConstructor = <span>@</span>__(<span>@</span>Autowired))って何だ（？）と思ったので調べてみました。
Lambokの公式のドキュメントによると、生成されたコンストラクタにアノテーションをつけるために置いているらしいです(!?)
https://projectlombok.org/features/constructor
onX -> OnConstructorについては、以下のように書いてありました。
"we heard you like annotations, so we put annotations in your annotations so you can annotate while you're annotating."
"我々はあなたがアノテーションのことが好きだと聞いたので、あなたのアノテーションの中にアノテーションを入れておいた。なので、あなたは、アノテーションしている間もアノテーションできるのだ。"
MapViewに軌跡を引く

# MapViewに軌跡を引く

## はじめに

地図上に任意の地点を軌跡として線で結ぶ時に調べた内容をここに残したいと思います。

<img width="375" alt="mapLine.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/d57cb79c-94ff-23f6-58c4-81b899166aae.png">

## サンプルプログラム

Githubにアップしてありますので参考にしてください

* https://github.com/FromF/MapLineSwift

## MKmapViewに軌跡を引くポイント

### Step1.線を結ぶ位置をMKPolinelineでインスタンス化する

CLLocationCoordinate2D型の位置を配列として`MKPolyline`でインスタンス化します。

```
let coordinates = [pos1 , pos2]
let polyLine = MKPolyline(coordinates: coordinates, count: coordinates.count)
```

### Step2.MKMapViewにMKPolinelineインスタンスをaddOverlayする
MKMapViewにaddOverlayします

```
mapView.addOverlay(polyLine)
```

### Step3.MKMapViewDelegateメソッドで線の色と太さを指定する
addOverlayするとMKMapViewDelegateメソッドが呼ばれます。
delegateメソッド内に線の色と太さを指定します。
注意ですが、前もって`mapView.delegate = self`とする必要があります。

```
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if let polyline = overlay as? MKPolyline {
        let polylineRenderer = MKPolylineRenderer(polyline: polyline)
        polylineRenderer.strokeColor = .blue
        polylineRenderer.lineWidth = 2.0
        return polylineRenderer
    }
    return MKOverlayRenderer()
}
```
頭にアンダースコアが2つ付くメソッドを呼び出せなくて悩まされた。

実行環境 Python3系

雑だけど、以下みたいなコードがあったとする。

~~~Python:test.py
class Hoge(object):
    def __foo(self):
        print("call foo")

class Hogehoge(Hoge):
    def meta(self):
        self.__foo()

h = Hogehoge()
h.meta()
~~~

HogehogeでHogeを継承して(meta)で親クラスの(\_\_foo)を呼び出している。  
この結果はこうなる。

~~~bash
$ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    h.meta()
  File "test.py", line 7, in meta
    self.__foo()
AttributeError: 'Hogehoge' object has no attribute '_Hogehoge__foo'
~~~

(\_Hogehoge\_\_foo)って名前の属性はねえよってことらしい。 
(\_Hogehoge\_\_foo)ってなんだ?呼びたかったのは(\_\_foo)のはずでは?  
## アンダースコアが頭に2個つく属性は**マングリング**される   
マングリングされると属性名の前に(\_クラス名)が付与される。
つまりHoge内では(\_\_foo)は(\_Hoge\_\_foo)にマングリングされ、 
Hogehoge内では(\_\_foo)は(\_Hogehoge\_\_foo)とマングリングされる。  

なぜそのような挙動になるのかはPythonのドキュメントに書いてある。
[9. クラス — Python 3.7.3 ドキュメント](https://docs.python.org/ja/3/tutorial/classes.html#private-variables)   
ややこしいのだが、Hogehoge内で(\_\_foo)と表記しているため、(\_Hogehoge\_\_foo)を呼び出そうとして、ないやんけって怒られていたのである。
以下のように親クラス名でマングリングされた属性名で呼べばアクセスすることができる。

~~~Python:test.py
class Hoge(object):
    def __foo(self):
        print("call foo")

class Hogehoge(Hoge):
    def meta(self):
        self._Hoge__foo() #<=ここが変わった

h = Hogehoge()
h.meta()
~~~

~~~bash
$ python3 test.py 
call foo
~~~

## オーバーライドはこう
ちなみに、マングリングされた親メソッドをオーバーライドしたい時もこう書ける。

~~~Python:test.py
class Hoge(object):
    def __foo(self):
        print("call foo")

class Hogehoge(Hoge):
    def meta(self):
        self._Hoge__foo()

    def _Hoge__foo(self):
        print("child call foo")

h = Hogehoge()
h.meta()
~~~

pipでインストールしたモジュールを無理やりオーバーライドしてカスタマイズしようとした時にこれで躓いた。

タイトルも微妙だし、理解はあってるか怪しいけどとりあえずこれで解決できます。

以上。
ec-cube.coでわかった、ショップオープンまでのつまづきポイント

# EC-CUBE関西ユーザーグループ勉強会(2019.6.20)

---

# 自己紹介

- 足立智広@株式会社イーシーキューブ勤務
- EC-CUBEエバンジェリスト
- ec-cube.coのサポート担当
- 5時になったら子供のお迎え
- twitter: [@chihiro_adachi](https://twitter.com/chihiro_adachi)

---

# ec-cube.coについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72858/8ba3ef9c-95c7-5caa-9e8a-ee708aaaddc9.png)

---

# ec-cube.coについて

- 2019年2月末にリリース
- ハードルが高かった、サーバの設定やインストールが不要なクラウド版「EC-CUBE」

---

# リリース以降

- 50社超の店舗さまにご契約
- 店舗さまと接してみて、共通のつまづきポイントがあることがわかりました

---

# ショップオープンまでめっちゃ時間かかる

- だいたい3ヶ月近く
- 場合によったらそれ以上

商品点数がそれほど多いわけではない(だいたい数100点くらい)

---

# オープンまでに必要な作業

- 商品登録
- 支払・配送方法の設定
- 特定商取引法や利用規約の設定
- デザインの調整

実際の作業にそんなに時間がかかるわけではない(長くても1週間くらい)

---

# 何に時間がかかるのか

- 決済の審査期間
- 本業が忙しい

---

# 決済の審査期間

- 決済代行会社さんによりピンきり
- 1ヶ月以上かかることも
- 書類のやりとりが必要になる場合もあるので準備が必要
  - 免許や許可証など

---

# 本業が忙しい

- 本業と兼務でecを始めるケースが多い
- 夢が広がってやりたいことがたくさん
- でも手を動かす時間がとれない

---

# ec-cube.coでお手伝いしていること

- キックオフミーティング 
- ゴールイメージのすり合わせ
- 要件の確認、タスクだし
- スケジューリング、進捗確認

---

# ec-cube.coでお手伝いしていること

![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72858/98c08016-1498-ff10-7753-596445769958.png)

---

# 自分ひとりで頑張るのはなかなか難しい

- ec-cube.coみたいなサービスを利用して支援を受ける
- 制作会社さんと相談する
- 自分だけでで頑張るのではなくなく、利用できるものは利用しましょう

---

# 一緒にお店を作っていきましょう

---

# fin
WiiリモコンをESP32で認識してみる（BTstack）

# はじめに
ESP32には、Bluetooth機能が内蔵されていますが、今回、そのBluetooth Classicを使って、[Wiiリモコン](https://www.nintendo.co.jp/wii/features/wii_remote.html)をESP32で認識してみます。Bluetoothスタックとして、[BTstack](https://github.com/bluekitchen/btstack)を使用します。

![remote_img2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/5ecc8765-52fd-e691-5de4-77c49516b540.jpeg)

> Wiiリモコンのプロトコル解析については、[Wiimote](http://wiibrew.org/wiki/Wiimote)を参照してください。



# 開発環境の準備
ESP32の開発環境をWindows10(64bit)のUbuntu上に準備します。
[⇒ ESP32 で Hello world! - Ubuntu (Windows Subsystem for Linux)](https://qiita.com/jp-96/items/63bc5d28bf78287b55d1)

# Bluetoothスタック（BTstack）の準備

```bash
cd ~/
git clone https://github.com/bluekitchen/btstack.git
```

```bash
cd ~/btstack/port/esp32
./integrate_btstack.py
```

# Wiiリモコンの認識

## MACアドレスの確認

Androidスマホのアプリなどで、WiiリモコンのBluetooth MACアドレスを確認します。
例えば、[「BTさがしてアドレス表示 + ペアリング for Bluetooth」アプリ](https://play.google.com/store/apps/details?id=com.jojoagogogo.bti)を起動し、WiiリモコンのAボタンとBボタンを同時に押し、アプリで検索すると「Nintendo RVL-CNT-01」などと表示されます。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/891fcd8c-ad13-491f-3f85-631b142d3cab.png)

【追記】スマホがない場合、BTstackに含まれているexample/gap_inquiryでも、確認することができます。
[⇒BTstackのexampleを使って、ESP32でWiiリモコンのBluetoothデバイスアドレスを取得する。](https://qiita.com/jp-96/items/080fa692e02dfc94ec90)

## サンプルソースコードの編集

hid_host_demo というサンプルを使用します。viエディタなどで、hid_host_demo.cを次のように編集します。

```bash
cd ~/btstack/port/esp32/example/hid_host_demo/main
vi hid_host_demo.c
```

remote_addr_stringの定義をスマホアプリなどで確認したWiiリモコンのMACアドレスに書き換えます。

```c
// MBP 2016
static const char * remote_addr_string = "00-1?-??-??-?2-52";
// iMpulse static const char * remote_addr_string = "64:6E:6C:C1:AA:B5";
```

packet_handler() 関数にあるswitch文のL2CAP_DATA_PACKETで、常に受信したパケットをダンプ出力するように行を追加します。

```c
            break;
        case L2CAP_DATA_PACKET:
            // for now, just dump incoming data
            printf_hexdump(packet, size); // この行を追加
```

## ビルド

### シリアルポートの設定

menuconfig というプロジェクト設定ツールを起動し、シリアルポートの設定を行います。

```bash
cd ~/btstack/port/esp32/example/hid_host_demo
make menuconfig
```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/98edd94d-d9c7-ab88-1ee9-8a5ab8b90702.png)

[Serial flasher config] → [Default serial port] で、ESP32と接続しているシリアルポートを設定します（例えば、/dev/ttyS14）。通信速度やオプション指定も図のように合わせてください。
設定後、< Save >で保存し、< Exit >で終了します。

### ビルドと書き込み

次のコマンドで、ビルドと書き込みを行います。

```bash
make flash
```

### モニター

次のコマンドで、ESP32とモニター接続します。

```bash
make monitor
```

## Wiiリモコンの接続

WiiリモコンのAボタンとBボタンとを同時に押し、下部の４つの青色LEDを点滅状態にします。そして、ESP32をモニター接続したまま、リセットボタンなどで再起動すると「HID Connection established」と表示され、接続状態になります。
Wiiリモコンのボタンを押したり離したりすると、L2CAP_DATA_PACKETが発生して、ダンプ出力されます。これで押したボタンを認識することができました。

```
[00:00:03.231] LOG -- l2cap.c.905: L2CAP_EVENT_CHANNEL_OPENED status 0x0
 addr 00:1?:??:??:?2:52 handle 0x80 psm 0x13 local_cid 0x42 remote_cid 0x53
 local_mtu 48, remote_mtu 185, flush_timeout 0
HID Connection established
A1 30 00 00
A1 30 00 10
A1 30 00 00
A1 30 10 00
A1 30 00 00
```

# おわりに
Wiiリモコンは、ハードオフのジャンクコーナーで入手可能です（324円くらい）。
安価なBluetoothデバイスであるWiiリモコンをESP32で認識してみることができました。
pythonでswitch文をdictで完全再現

#はじめに
Pythonにはswitch文は存在しません,if-elif-else文を使って同じことができるという理由から、switch文は採用していないとのことです。
今回はif-elif-elseではなく、`dict`の特性を活かしてswitch文を完全再現してみよう。

#switch文は何できるでしょう
お馴染みのPHPでswitch文の参考例をみてみよう

```php:switch.php
<?php
switch ($変数) {
    case $変数の値が0の場合:
        echo "$変数が0に等しい";
        ...
        break;
    case $変数の値が1の場合:
        echo "$変数は1に等しい";
        ...
        break;
    case $変数の値が2の場合:
        echo "$変数は2に等しい";
        ...
        break;
    default:
       echo "$変数の結果がどの値とも一致しなかった";
       ...
}
?>
```
とてもわかりやすい分岐処理です

- 変数の値によって実行するコードブロックが違う
  - 通常ブロックのコードは一行で終わるのが読みやすいですが、実際長々と書くことも可能ですので、そこも後でちゃんと再現する
- 変数の値がどれにも当てはまらない時にdefaultのブロックが実行されます

# Pythonのdictでswitch文を再現

```python:switch.py
# 変数を定義 
day = 6

# dickのvalueとして使用する関数を定義
def get_sunday():
    return "Sunday"

def get_monday():
    return "Monday"

def get_tuesday():
    return "Tuesday"

def get_unknown():
    return "get_unknown"

# dickを定義
switcher = {
    # dickのvalueに関数を渡しておく
    0: get_sunday,
    1: get_monday,
    2: get_tuesday
}
# 直接変数dayを渡すと、key存在しない場合エラーが返ってきます
# keyが存在しない場合もあるため
# 返り値指定可能のget()を使用 、パラメータにも関数渡しておこう
day_name = switcher.get(day, get_unknown)()
print(day_name)

# 出力結果
get_unknown   
```
switch文の機能完全再現、ブロックの操作が独立したことで、codeもある程度わかりやすい。

*Readability counts.*
*読みやすいことは善である。 --pythonの禅*
オレ「このシステム、RDBで開発していいのか？」

作ろうとしている業務システムの要件を整理していた。
・ビジネスマン向けニュースが毎日数万件追加される
・ユーザーは好きなニュースを閲覧できる
・もちろんカテゴリによる絞り込みやキーワード検索にも対応
・ある程度古い記事も読めるようにしないといけない
・会員制ではあるが非会員でもニュースは閲覧できる（一部機能制限あり）
…などなど

そんな中、非機能要件を考えているときにふと思った。
「これはRDBで開発していいのか？」

最近ではDynamoDBやneo4jなどRDB以外のそれぞれのソリューションに特化した様々データベースがリリースされている。
そんな中、思考停止して無条件にRDBを採用するのはいかがなものか。

というわけでRDBとNoSQLデータベースについて整理したうえでどちらを採用する方がいいのかを考察してみた。


## RDBとは
Relational Databaseの略称。
関係テーブルと呼ばれるカラム(列)×レコード(行)で構成された表で下図のようにデータが管理される。
代表的なものとしてMicrosoft SQL Server Oracle, PosgreSQLが挙げられる。

|    id    |    name    |    email    |    password    |
|:--------:|:----------:|:------------------:|:------------------:|
|   0001   |    Hiroro    |  hiroro@example.com |        hrr0001        |
|   0003   |    Harara    |  harara@example.com |       hrr0003       |
|   0012   |    Kiroro    |  kiroro@example.com |       krr0012       |


### 長所
データ構造が明確に定義されている時は強い
トランザクション処理ができる
検索が柔軟にできる

### 短所
スケールアウトができるようにはなっていない、スケールアップでは限界がくる
半構造データは不向き、スキーマ定義して格納するか検索や更新の利便性を犠牲にしてJSON形式で格納するしかない

## NoSQLとは
Not only SQLの略。No SQL(SQL不要)の意味ではない。最近はクエリが発行できるものも増えてきましたが。
RDB以外のデータベースを指し、Key-Valueストア(KVS)やドキュメントDB(DocDB)、グラフDBと様々なデータモデルがある。
ここでは導入可能性の高いDocDBについて考える。

DocDBは以下のように階層構造データをJSONフォーマットで格納することができるデータベース。
MongoDBやFirebase、Amazon DocumentDBがある。

```json
{
   "id": 0001,
   "name": "Hiroro",
   "email": "hiroro@example.com",
   "password": "hrr0001"
},
{
   "id": 0003,
   "name": "Harara",
   "email": "harara@example.com",
   "password": "hrr0003"
},
{
   "id": 0012,
   "name": "Kiroro",
   "email": "kiroro@example.com",
   "password": "krr0012"
}
```

### 長所
スケールアウトでき、これによりビッグデータを分散して高速に処理ができる
スキーマが定義されていなくても格納できる

### 短所
検索が弱い
整合性が保証されない
標準化されていない、技術者が少ない

## 判断のポイント
DB選定にあたり今回の要件で注目すべきポイントを踏まえて考えてみる。

### 1. スキーマの変更可能性
スキーマ定義をすることは可能で、破壊的変更が加わることはおそらくないと思われる。
なのでスキーマ課題についてはRDBを採用しても特に問題はない。

### 2. スケールアウトの必要性
スケールアウトする必要があるかどうかは保持するデータ量とユーザーからのアクセス量について考慮する必要がある。

まずデータ量だが、毎日50000記事アップロードされるとして、3年間だと
`50000 × 365 × 3 = 54,750,000` 記事で、1記事当たり平均1kBだとすれば必要な容量は大体54.75GB。

…思ったより少ない。
ここはデータの保存期間が3年なのか10年なのかで変わってくるし、1記事当たりの容量の変化でも変わってくる。それでも10倍の誤差があったとしても547.5GBである。
もちろんデータベースにはほかの情報も格納されているが、そのほとんどは記事データで占められると考えられるので記事データ量がこの程度であれば1サーバーに収まるだろう。画像や動画を管理することになると対策を考えないといけないかもしれないが。


次にユーザーからのアクセス量についてだが、ユーザーが増える可能性があるものの業務システムなのである程度予測可能。
世界展開することになれば話は変わってくるかもしれないが、そうでもなければスケールアップで裁くことは可能だと思われる。

以上よりスケールアウトしやすいDocDBのほうが安心だが、RDBを採用しても大丈夫そう。

### 3. 複数のand/or条件およびキーワードでの検索
DocDBは複雑な条件での検索ができない。RDBでならある程度可能となるが、キーワード検索となるとRDBの機能だけでは検索時間がかかりすぎる。
検索機能においてはRDBのほうがましだが、いずれも十分ではなく、SolrやElasticSearchといった全文検索エンジンを採用する必要がある。


### 4. トランザクション機能の必要性
ニュースサイトなのでユーザーを閲覧することがほとんど。プロフィール変更程度はあるもののトランザクションは必要としないため、ここはRDBでなくてもよい。
**ただし決済システムが導入されるとなると別問題。**決済は成功したが、決済中にサーバーエラーが発生して決済は行われたものの変更が適用されていないと大問題となるのでトランザクション機能が必須となる。


## 結論
今回においてはRDBを採用したほうが良いとみられる。むしろDocDBを採用するメリットが少ないことが分かった。
個人的にはスケールアウトの可能性について懸念していたが、試算すると大きな課題にはならなさそう。

そういえば、記事データはDocDB、それ以外はRDBといった具合にデータベースを使い分けるのはありなのだろうか？
MySQL8.0からはDocument Store機能がついて、RDBなのにDocDBとしても使うことができるとか。
調べてみる価値はありそうだ。
Mac版Unityでエディタ上のドラッグの挙動が2017.4.28から変わっていた

少々古い話になるが、まぁLTSとか現場によっていろいろなバージョン使っていると思うので参考になればと。

要旨：MacのUnity2017.4.28以前でドラッグのパフォーマンスが気になる場合はアップデートすると良いかも

# 環境

* OS: macOS Mojave 10.14.5
* Unity: 2017.4.8f1, 2017.4.28f1 (64bit)

# 検証用コード

```cs
using UnityEngine;
using UnityEditor;

public class TestWindow : EditorWindow
{
    [MenuItem("Window/TestWindow")]
    public static void Open()
    {
        var window = GetWindow<TestWindow>("Test Window");
        window.Show();
    }

    private void OnGUI()
    {
        switch (Event.current.type)
        {
        case EventType.DragUpdated:
        case EventType.DragPerform:
        case EventType.DragExited:
            Debug.Log(Event.current.type.ToString());
            break;
        case EventType.MouseDrag:
            Debug.Log(Event.current.type.ToString());
            DragAndDrop.PrepareStartDrag();
            DragAndDrop.paths = new[] { "/" };
            DragAndDrop.StartDrag("test drag");
            Event.current.Use();
            break;
        }
    }
}
```

# 変更前の挙動

例えばUnity2017.4.8f1で検証コードのウィンドウの中でドラッグを行うと、以下の2パターンが発生する。

## パターン1

* `MouseDrag`イベントがドラッグ中も継続的に発生する
* エディタ拡張が非常に軽いコードでも動作がカクつく

![rec1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171370/0007d00b-ed51-9f38-1d30-f8a202c05dec.gif)

## パターン2

カーソルを動かしながらドラッグを始めるとこちらのパターンが発生する様だ。

* `MouseDrag`イベントはドラッグ開始時だけ
* スムーズにドラッグできる
* ドラッグが終了してからログが出る

![rec2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171370/a3cf728f-ee6c-6de0-b46c-47daa72501cf.gif)

# 変更後の挙動

[Unity2017.4.28](https://unity3d.com/jp/unity/whats-new/2017.4.28)のリリースノートに

> Editor: Fixed Drag and dropping doesn't always work. (1136897)
> Editor: Fixed Mouse move events affect Editor UI performance. (973842)

という項目がある。このどちらかによってドラッグの処理が改善されたらしく、一貫して下のような挙動になっている。

* `MouseDrag`がドラッグ中に発生しない
* ドラッグはほぼスムーズ
* ログはドラッグ中に出続ける

![rec3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171370/29a22f47-2878-2eb9-2fe4-9e0fa7569214.gif)
RPAでエクセルに入力するときに困ったことと解決策

#はじめに
こんにちは、yusukeです。
今日はプロジェクトがようやく一区切りついたので、学んだことを記事にしていきます。
どちらかというと困ったことと解決策の記録といった感じです。（ツールはUipathです）を

##エクセルで入力先がめんどくさいところにある。
エクセルって普通業の下に入力することが多いので、

```"B" + (Datatable変数.Rows.Count+1).ToString```

で行けると思っていたんですよね、ところが見て驚き

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416305/4ee528a0-8341-e566-bcc1-31aee6d0f05e.png)

黄色くなってるところが入力したいところだったんですよね・・
（数字は適当なものに置き換えております）

それをROWSですると、別のところに書いちゃうし困っていたらこういうのを見つけました。

```"C" + （DataTable変数.Rows.IndexOf(row)+2).ToString```

こういう書き方をすると、ROWs(行数を数える）がB2を０としてカウントしてくれます。
（実際,ForEachしているので初めが0になります)

これで、今までの行数を数えてくれます。今回はそこに空白部分の１と０からはじまるのでその分の１を足して
+2にしないと理想のところ(黄色のところ）に値が入らないので、注意しないとだめですね。
（筆者はこの沼に1時間取られました泣）


##まとめ
調べても情報を整理するときにこれじゃなかったってことがよくあります。この沼を解決していきたいなと思ってます。
Heroku deploy 際へのエラー解消

# herokuへdeploy

herokuへdeployして，スケジューラが動いているか確認したら，

``` terminal
FileNotFoundError: [Errno 2] No such file or directory: 'geckodriver': 'geckodriver'
```

上記のようなエラーを吐いていた．

どうも，スクレイピングの際に使っていた ``` geckodriver ``` をherokuにもbuildさせないといけないらしい

## 対処法１
まだ， ``` heroku create ``` がまだである場合は．

``` terminal
$ heroku create [appname] --buildpack http://github.com/buitron/geckodriver-buildpack
```

とすれば，buildの際に一緒にやってくれる

## 対処法２
``` heroku create ``` をしてしまった場合

``` terminal
$ heroku buildpacks:add http://github.com/buitron/geckodriver-buildpack
$ git push heroku master
```

こうすれば，対処可能である．
スクレイピングの際によく使うやつだからつれつれと書いてみた

# 参考
[参考にしたサイト1](https://elements.heroku.com/buildpacks/buitron/geckodriver-buildpack)
[参考にしたサイト2](https://elements.heroku.com/buildpacks/notvad/heroku-buildpack-selenium)
[参考にしたサイト3](https://github.com/buitron/geckodriver-buildpack)
Rails erbをhamlに変換する方法

### 1. haml-railsをインストール（既にインストールしている場合は飛ばしてください）

```:Gemfile
gem 'haml-rails'
```
その後、bundle install

### 2. erb2hamlを実行（全てのerbをhamlに変換（hamlをデフォルトにする））
補足：erb2hamlをインストールしなくても、haml-railsだけで変換可能。

```ruby:ターミナル
$ bundle exec rails haml:erb2haml
```

　　
（変換後、ハッシュ記法の箇所をシンボル型に書き換えると実行速度が早くなる（深い話なので割愛）。
例　'class' => hoge　を　class: hoge　にする）

以上。
【非エンジニア向け】Salesforce ど素人からのはじめの一歩

#はじめに
私自身、半年ほど前にいきなりSalesforceに関わることになり、どこから手を付けたらいいのか困っていました。
その為、「とりあえず勉強しといて」と言われ困っていた、半年前の自分に向けて書いていきたいと思います。  

※私は、チュートリアルのTrailheadを進めていて、「Salesforceは本来どう使われることを想定しているのか。」が分からず挫折しかけました。

#Salesforceって何なの？
世界で15万社以上の会社に利用されているSaaSです。

半年間関わった印象では、Salesforceの強みは
"**難しいコーディングなし**(ほとんど無し)で、**社内システムを実装できる**。"
というものです。

**・コーディングなし**
・基本機能を操るシステム担当者の、技術の取得コストが低い。　
→基本機能を扱う分には、画面をポチポチするだけでできてしまいます。

・コストが低いから、外注せずに自社で開発できる。

・自社で開発できるから、現場の実務に即した開発ができる。
→簡単に実装できるので、もっとこんな機能あればいいのに、とか素早く反映できます。


**・社内システムを実装できる**
・簡単にデータの構築、連携ができる。
・取引先、商品、注文、契約etc...一般に社内システムで必要なものは標準オブジェクトとして存在する。
・独自のオブジェクトの作成や、項目追加、レコードのCRUDが画面からできる。 

※コーディングすれば独自の機能も自由に作れますが、年３回のアップデートがあるため、作りこみすぎると管理コストが高くなります。

それ以外にも、
・ログイン機能（パスワードの入力規則や、定期更新の設定など）
・ユーザー管理
・社内でのチャット機能
・レポートや帳票出力
・画面のスマホ対応（レイアウト調整）
などの機能を自動で行ってくれます。


#結論
まず一歩目としては、以下のことが出来ればいいと思います。
・カスタムオブジェクトの作成
・項目の追加
・入力規則と共有権限設定
・タブ追加して、標準画面のレイアウト変更

必要なデータを自由に用意できるようになれば、あとは社内で行っている営業活動の管理や、レポートで売り上げを出力したいとか、こんなことやりたいなーと思ったことは大体道筋を用意してくれています。

二歩目以降は会社の業務の理解を深めることが大事だと思います。
例えば営業向けシステムなら、「アポどり→関係構築→プレゼン→問題解決→クロージング→契約→フォロー」とか、業務フローはもちろん、そのとき何が大事なのか、理解が必要です。

半年前の自分に言いたいのは、「コーディングすれば何でもできるけど、それは本来の使い道じゃないぞ。」ということです。
皆さんも一緒に、**標準機能を使い倒しましょう**。

それはそれとしてTrailheadのやたらと多い自画自賛を減らしてもらえないですかね・・・
「重要な機能」「素晴らしい機能」「担当者は涙を流して喜ぶでしょう」とか何が重要かわからないです。
.basketファイルの作り方[Python3]

##アソシエーション分析とは
某大手通販サイトの「この商品を買った人はこちらの商品も買っています！！」というように物事の関連性を調べる分析です。
分析を扱う際には、**.basket**という拡張子のファイルが必要になります。
今回はその**.basket**ファイルをpythonから作るときのやり方を紹介したいと思います。

##.basketファイルとは
1. 一行に一回分の買い物（ひとまとまり）が入っており、それぞれが[,]で区切られています。
2. 行の最後の項目は[,]がつきません。

##python手順
今回は[[a,b,c],[c,d,e]]のように、リストの中にリストが入っている入れ子構造のものを.basketにしました。

1. .basketファイルを作成したいディレクトリ（フォルダ）に移動します。
2. 作成したいファイル名を下記コマンド１行目の（任意）に入力します。この際、拡張子は.basketにします。
3. 私の場合は、上記のようにリストの入れ子構造になっているので、for文でリストを取り出し、リストごとに,をつけるのか、,をつけずに改行するのかを指定しています。


`
with open('（任意）.basket', 'w', encoding = 'utf-8') as tb:
    for tw in list:
        if len(tw)>1:    #空のリストがたまに含まれていたので、リストの長さが1以上のものだけ処理
            a = ''
            for i in tw:
                a += '{},'.format(i)
            a1 = a[:-1]+'\n'
            tb.write(a1)
`

重要なのは**[,]で区切ること**、バスケットの**最後の項目は[,]をつけず改行すること**です。
Chokidarでglobパターンを使ってハマったこと

[Chokidar](https://www.npmjs.com/package/chokidar?activeTab=readme)はnode.jsのfs.watch, fs.watchFile, FSEventsをラッパーしたものです。ファイルやフォルダ監視をする際に、使いやすくて便利です。

Electronアプリを開発中に、chokidarを使う場面があり、ちょっとハマったところがあったので記録を残しておきます。

最初はこんな感じでchokidarを使っていました。環境はWindowsです。

```js:
const watchPath = 'C:\\user\\workspace\\download\\2019';
const watcher = chokidar.watch(watchPath, {ignoreInitial: true});
watcher.on('add', path => {
  /* 処理 */
});
```

上記の例ではwatchPathで指定したフォルダに対して、問題なく監視が行えていました。

次に、監視対象はglobパターンでも指定できるので、特定のファイルだけ監視ができるように変更しました。watchPathを以下のようにしました。

```js:
const watchPath = 'C:\\user\\workspace\\download\\2019\\*.json';
```

このようにしたところ、ファイル監視がうまく働きませんでした。

原因としては、バックスラッシュは特殊文字をエスケープするためにglobで予約されているため、バックスラッシュパスとglobパターンを組み合わせることはできないということでした。

以下のようにすれば問題なく動作しました。

```js:
const watchPath = 'C:/user/workspace/download/2019/*.json';
```

globパターンを使うときにはスラッシュパスを使いましょう。

# 参考URL
[On windows, cannot watch files with some glob patterns #714](https://github.com/paulmillr/chokidar/issues/714)
GitHubにpushする時にerror: failed to push some refs と表示されてpushできない時

GitHubにプッシュしようとしたらできなかった。
と思ったらエラーが表示された。

過去のコミットの履歴が書き換わってしまい普通にpushができなくなってしまってしまっているそうです。

書き換わってしまった経緯はいまから追うのはちょっとしんどい。
ということで強制push。

```ruby:コンソール
$ git push origin master
To https://github.com/〜〜.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/〜〜.git
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

こんな感じでエラーが出たらpushする時に

```ruby:コンソール
git push -f origin master
```

で解決しました！
CouchDBのAPI入門



CouchDBの操作やクエリに使用するAPIについてイメージを掴むためいくつかまとめ
公式ドキュメントにけっこう詳細に記載されてます。

検索はHTTPメソッドで行う

CouchDB内のURIは
severName/databaseName/documentName
であり階層ごとにAPIが用意されている。


#各階層ごとのAPIの例

###サーバー
ホストにあるCouchDBサーバの情報取ってくる

```
GET /
Accept: application/json
Host x.x.x.x:port
→　res サーバ情報
```
サーバ内のすべてのデータベース情報取ってくる

```
GET / _all_dbs
Accept: application/json
Host x.x.x.x:port
→ res サーバ内の全てのデータベース
```

キーで該当のデータベース取ってくる

```
POST /_dbs_info
Accept: application/json
Host x.x.x.x:port
Content-Type: application/json 

{
    "keys": [
        "countries",
        "planets"
    ]
}

→ res keysで指定されたデータベースの情報
 ```

###データベース

```
GET /{データベース名}
→ res 指定したデータベースの情報
```

新しいデータベース作る

```
POST /{データベース名}
→　res データベース情報
```
すべてのデータベースのクエリ

```
GET /{データベース名}/_all_docs
→ res 指定したデータベース内にある全てのドキュメントの情報
```
データベースの条件検索

```
POST /{データベース名}/_find
req
{
    "selector": {
        "year": {"$gt": 2010}
    },
    "fields": ["_id", "_rev", "year", "title"],
    "sort": [{"year": "asc"}],
    "limit": 2,
    "skip": 0,
    "execution_stats": true
}
→res 該当ドキュメントの情報
```
selector(json)・・・どのドキュメントを取ってくるのかの条件付
fields(array)・・・該当ドキュメントのどの情報を取ってくるかの条件付
sort(json)・・・ソートの条件
limit(num)・・・何件までとってくるか、デフォルトだと25件
skip(num)・・・最初の何件を飛ばすか、デフォルトは0
execution_stats(bool)・・・検索の際のログのようなものを返すか、デフォルトだとfalse



###ドキュメント

```
GET/{データベース名}/{ドキュメントID｝
→ res 該当ドキュメントの情報
```

新しくドキュメント作る

```
POST/{データベース名}/{ドキュメントID}
→ res ドキュメント情報
```


## 終わり
公式ドキュメントにAPIが載ってる。
https://docs.couchdb.org/en/2.2.0/api/document/common.html

APIが豊富で結構柔軟にいろいろな操作ができそう。


前回の記事
[１分でCouchDBまとめ](https://qiita.com/zaki_prog/items/27b4a08dec1395c864e)
association

#DB設計にあたりassociationの復習
- rails モデル

has_many　多くを持っている
belongs_to　に属する
を定義していく

例：twitter



#ユーザーテーブル　
|user_id|name|
|------|----|
|1|aaa|
|2|bbb|
|3|ccc|

#ツイートテーブル
|user_id|text|
|------|----|
|1|hello|
|2|good|
|1|thanks|
|2|bad|
|3|right|
|3|left|


ユーザーテーブルからみると、ユーザーはツイートテーブルに対して多くのツイートを持っている
user_id:1→hello
user_id:1→thanks
つまり
ユーザーモデル（テーブル)は
has_many:ツイートs ※複数形！！

ツイートテーブルからみると、ツイートは必ずどこかのユーザーに属する
right→user_id:3
left→user_id:3
つまり
ツイートモデル（テーブル)は
belongs_to:ユーザー
Windows Server 2019でWSLやHyper-V上のUbuntu18.04にCUDA環境を構築しようとして断念

NVIDIA GeForce RTX 2080 Ti x4なサーバにWindows Server 2019をセットアップした際の備忘録です．
(最初からLinuxで構築しろよという話はなしで)

# はじめに

本来やりたかったのは，「WindowsではJupyterHubが使えないので仮想環境内のUbuntuにJupyterHub入れて色々切り分けたJupyter Notebook環境を構築」でした．
Windows 10では無理なものの，Windows Server 2019ならDDA(Discrete Device Assignment)で仮想環境内のLinuxへGPU passthrough出来るんじゃないかと色々試したのですが，少なくとも2019年6月半ば時点では

Mother: ASUS WS Z390 PRO (BIOS 0603)
Memory: 64GB (16GB x4)
CPU: Intel Core i9-9900K
GPU: MSI GeForce RTX 2080 SEA HAWK X (x4)
OS: Windows Server 2019 Standard (1809)

において[後述](#hyper-v関連)のエラーにより実現できませんでした．

そうこうしているうちに
[完全なLinuxがWindows 10上で稼働する？　「WSL 2」とは](https://www.atmarkit.co.jp/ait/articles/1906/14/news019.html)
とかも出てきましたし，今後何かの拍子に動くようになるかもしれないので＆他所の環境なら動くかもしれないので手順メモ．
そこそこtrial and errorを繰り返したので微妙にメモが間違っているかも知れません．

ちなみに極力手間を減らすためにPython環境構築はAnaconda3(Python3.7)に任せます．
あと，CUDAは10.1を対象に入れていきます．
なお当然，以降全て選択肢があるものについては64bitで進めています．

# 本題

めちゃくちゃ長くなったので以下のように分けています．


## Windows Server 2019関連
[Windows Server 2019にPython環境を構築](https://qiita.com/fararrow/items/875c93cc3a2545bf90a7)

## WSL関連
[Windows Server 2019のWSLにUbuntu18.04をインストール](https://qiita.com/fararrow/items/1007c850d81022799420)
[Windows Server 2019でWSLのUbuntu18.04にJupyterHub環境を構築](https://qiita.com/fararrow/items/483f0f5a9d5092adead5)

## Hyper-V関連
[Windows Server 2019でHyper-V上にUbuntu18.04をインストール](https://qiita.com/fararrow/items/0bdc72ac4f80b4cb35c0)
[Windows Server 2019でHyper-V上のUbuntu18.04にJupyterHub環境を構築](https://qiita.com/fararrow/items/e2bba195f08096471d31)
[Windows Server 2019でHyper-V上のUbuntu18.04にCUDA環境を構築(断念)](https://qiita.com/fararrow/items/8df089dd17d1699b299c)

- - -
Qiita触るの初めてだ，こんな風に書くんだ:open_mouth:
Circleciに環境変数を設定する

AWSのクレデンシャルとか .circleci/config.ymlにハードコードしたくない物をContextを使って解決する

1. SETTINGS → Contexts → CreateContextを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/d5c50c3f-7010-0537-07f4-602805d21db3.png)

2. Contexts名を入れてエンター
3. Add Enviroment Variableを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/63c62433-b505-e54c-7a24-bcaac91dde49.png)

4. NameとValueを入れて環境変数を設定していく

5. .circleci/config.ymlで使う

```
workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build:
          context: [作成したcontext名]
```

こんな感じで使える

```
      - run:
          name: contextで設定した値を表示する
          command: |
            echo "${Value1}"
            echo "${Value2}"
```

## 参考
https://circleci.com/docs/2.0/contexts/
インスタンス生成とコンストラクタとフィールドとか

インスタンス生成（newの時）
①フィールド初期化
②コンストラクタの呼び出し
※コンストラクタが1つもない時は自動で作られる

Aaa o = new Bbb(100);
このようなインスタンスを生成した際、Bbbクラスのコンストラクタに飛ぶ

System.out.println(o.a);
フィールドの場合は型であるAaaクラスのフィールドに飛ぶ

o.sample()
メソッドを呼び出した場合はオブジェクトであるBbbのメソッドに飛ぶ

※フィールド　→　型
　メソッド　　→　オブジェクトと覚えよう
EV3とRaspberryPi間のシリアル通信方法_1

ここでは、EV3とRaspberryPiの間でシリアル通信する方法を紹介します。
この方法を応用することで、RaspberryPiでEV3のセンサーを扱うことができたり、RaspberyPiのカメラを用いることで、カメラを使った制御をEV3で行うことができます。

# 使用するもの
-   RaspberryPi3 Model B+
-   SDカード：RaspberyPi用
-   EV3Console
-   データ通信が可能なUSBケーブル (TypeA to MicroB USB2.0)
-   <font color="DarkGray">教育版レゴ マインドストーム EV3</font>
-   <font color="DarkGray">SDカード：EV3RT用</font>  
※灰色字のものは次章にて使用

# 1. RaspberryPiをインストールする
RaspberryPiの環境構築を行います。
今回はUbuntu MATE（18.04）を使用します。
[Download](https://ubuntu-mate.org/download/)  
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439737/6a7c9dd7-fe99-6762-fe34-9e7a5e171add.png)
「Rapberry Pi(recommended)」を選択します。  
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439737/cc857cdf-9d9b-9bc8-2e65-0ad40454bfed.png)
「18.04.2(Bionic)」を選択します。  
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439737/0212709a-f51a-e03e-7b68-b920346e9232.png)
「ubuntu-mate-18.04.2-beta1-desktop-armhf+raspi-ext4.img.xz」を選択してダウンロードを行います。
任意の場所に解凍します。

お好きなイメージライターで、SDカードに解凍したイメージファイルを書き込みます。
※今回は「Win32DiskImager」を使用しました。

# 2. RaspberryPiにEV3を認識させる  
RaspberryPiと EV3 を EV3Console を介して接続する際に RaspberryPi 側が接続
を認識するよう設定を行います。  
  
EV3Console 用の USB デバイスの設定ファイルをviエディタで編集します。

```
User@linux:~$ cd /etc/udev/rules.d/
User@linux:~/etc/udev/rules.d/$ sudo vi 70-mindsensors-ev3-console.rules
```

USB デバイスの設定ファイルを編集します。  

```
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="abb9", GROUP="users", MODE="0666", RUN+="/lib/udev/ev3console", SYMLINK+="ttyEV3"
```  

EV3Console が RaspberryPi に接続された際に通知するスクリプトを作成します。  

```
User@linux:~$ cd /lib/udev
User@linux:~/lib/udev/$ sudo vi ev3console
```

viエディタにて以下のように編集します。  

```
#!/bin/sh 

/sbin/modprobe ftdi_sio && \

echo 0403 abb9 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
```

作成したシェルスクリプトを実行します。  

```
User@linux:~/lib/udev/$ sudo sh ev3console
```

USBシリアルポートへのアクセス権限を得るために、ユーザーを「dialout」グループに追加します。  

```
User@linux:~$ sudo gpasswd -a $USER dialout
```

RaspberryPiとEV3consoleをUSBケーブルで接続します。
接続後、以下のコマンドを入力して、RaspberyPiがEV3consoleを認識していることを確認します。
2行目のような出力がでれば成功です。

```
User@linux:~$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 MM月 DD 00:00 /dev/ttyUSB0
```

  
EV3とRaspberryPi間のシリアル通信方法_2 では、実際の通信方法の例を紹介します。
[EV3とRaspberryPi間のシリアル通信方法_2](https://qiita.com/taguchi-n2310/items/1c1bc1d2b092eb16e552)
Oracleで大量データ扱うとき気を付けたこと

　大量データを扱うときによく話題になることのまとめ

# パーティション化
 最初から大量のデータが蓄積されると予想がついている場合は、パーティション・テーブルにしておくと便利。
データが増えて消さないといけない場合でも、パーティション化していればパーティション単位でDROP、TRUNCATEできるため管理が容易になる。
パーティション化してない場合、削除するときにDELETEだとUNDO領域やアーカイブ領域など枯渇しないように考えないといけなくなる。

```sql:CREATE文で日付ごとのレンジ・パーティション作成
CREATE TABLE ＜テーブル名＞ (
    ＜列名１＞        ＜データ型＞,
    ＜列名２＞        ＜データ型＞,
    ＜列名３＞        ＜データ型＞,
    ＜列名４＞        ＜データ型＞,    
    ＜列名５＞        ＜データ型＞)
    LOGGING
    PCTFREE    ＜空き領域割合＞
    PARTITION BY RANGE (＜列名１＞) (    
        PARTITION ＜パーティション名１＞ VALUES LESS THAN ( TO_DATE('＜年月日１＞','YYYYMMDD')) TABLESPACE ＜表領域名１＞,
        PARTITION ＜パーティション名２＞ VALUES LESS THAN ( TO_DATE('＜年月日２＞','YYYYMMDD')) TABLESPACE ＜表領域名２＞,
        PARTITION ＜パーティション名３＞ VALUES LESS THAN ( TO_DATE('＜年月日３＞','YYYYMMDD')) TABLESPACE ＜表領域名３＞,
        PARTITION ＜パーティション名４＞ VALUES LESS THAN ( TO_DATE('＜年月日４＞','YYYYMMDD')) TABLESPACE ＜表領域名４＞,
        PARTITION ＜パーティション名５＞ VALUES LESS THAN ( TO_DATE('＜年月日５＞','YYYYMMDD')) TABLESPACE ＜表領域名５＞)
    ENABLE ROW MOVEMENT;
```

# 統計情報の再収集
 Oracleは表・索引の統計情報をもとに実行計画を立てるので、試験時など大量のデータを一度に投入したときなど実態と統計情報がかけ離れてしまい、実態に合わない実行計画でSQLが発行されてしまうことがある。この場合レスポンスが悪くなってしまう。
データが増えたときは統計情報を再取集して最新化しておくとこれを回避できる。統計情報はANALYZEコマンドで収集できる。

```sql:ANALYZEコマンドでテーブル全体から統計情報収集
analyze table テーブル名 compute statistics;
```

# 表領域の使用率を下げる
表領域不足で使用率を減らしたいときはDELETEしても減らない。
ハイウォーターマーク（最高水位標）の概念があり過去最大の領域を記録している。
DELETEしてデータを消しても一度確保された表領域はハイウォーターマークのところまで未使用領域として残存してしまう。
未使用領域を減らして使用率を下げるには以下の方法がある。
#### ・TRUNCATEしバックアップからデータを復元
TRUNCATEで表を一旦まっさらな状態にして、予めEXPORTなどでバックアップしておいたデータを復元することで、無駄な未使用領域がなくなり使用率が下がる。

```linux:expコマンドで表データのバックアップ
exp ＜ユーザ名＞/＜パスワード＞ tables=＜テーブル名＞ file=＜出力ファイル名＞
```

```sql:TRUNCATEでデータ削除
TRUNCATE TABLE ＜テーブル名＞;
```


```linux:impコマンドで表データのリストア

imp ＜ユーザ名＞/＜パスワード＞ tables=＜テーブル名＞ file=＜出力ファイル名＞
```
#### ・ALTER SHRINK TABLE SPACEで断片化を解消
未使用領域を解放し縮小できる。※Oracle10g以降で可能
CASCADEオプションで索引などの表に依存するオブジェクトの断片化も解消される。

```sql:ALTER文で断片化解消
ALTER TABLE ＜テーブル名＞ ENABLE ROW MOVEMENT; 
ALTER TABLE ＜テーブル名＞ SHRINK SPACE CASCADE;
ALTER TABLE ＜テーブル名＞ DISABLE ROW MOVEMENT;
```
　

　
表領域の使用状況はビューで確認できる

```sql:DBA_TABLESPACE_USAGE_METRICSビューで確認
SELECT TABLESPACE_NAME,
       TABLESPACE_SIZE/1024/1024/1024 “TOTAL(GB)”,
       USED_SPACE/1024/1024/1024 “USED(GB)”,
       USED_PERCENT “USED(%)”
FROM DBA_TABLESPACE_USAGE_METRICS;
```
ラムダ式の基本

ラムダ式の構文

(型 引数名1,型 引数名2,…) ->{
処理1;
処理2;
  .
  .
  .
return 戻り値;
}

---------------------------------------------------------
public static void main(String[]args){

Runnable runner = () -> {
		System.out.println("Hello Lambda!");};
		runner.run();
}

---------------------------------------------------------
public static void main(String[]args){

IntBinaryOperator func = (int a, int b)->{return a-b;};

int a = func.applyAsInt(5,3);
System.out.println(a);
}
}
---------------------------------------------------------

インターフェースの場合

interface InterfaceTest{
public String method(String name,int n);
}
publicclass Main{
public static void main(String[] args){
InterfaceTest it = (name,n) ->{
return "Hello" + name + n + "!";
};
System.out.println(it.method("Java", 8));
}
}
---------------------------------------------------------

Stream API

.for Each → forループ文を手短に書いた場合
.filter   → 条件式を満たす場合の処理
.sorted   → ソート処理を行う
.map      → 引数を四則演算する方法

---------------------------------------------------------
for Eachの例

Integer[]num = {1,2,3,4,5}
List<Integer>l = Arrays,asList(num);

l.forEach(System.out.println);

こっちでもおｋ↓

l.forEach(i->
System.out.println(i));

----------------------------------------------------------
fillterの例

l.strem().filter(x -> x < 3)
.forEach(i -> System.out.println(i));

-----------------------------------------------------------
sortedの例

l.stream().sorted((x,y) -> y - x)
     .forEach(i-> System.out.println(i));
-------------------------------------------------------------
mapの例

l.stream().map(x -> x * 10 - 5)
     .forEach(i -> System.out.println(i));  
--------------------------------------------------------------
mapをもっとわかりやすく

List<Integer>list = Array.asList(-1,2,0,-3,8);
list.stream().fitter(i -> return i >= 0)
             .sorted((i1,i2) -> return i1 - i2)
             .map(i -> return "*" + i + "*")
             .forEach(s -> System.out.println(s + "));   
             
             
-----------------------------------------------------------
参照型変数とは

参照型変数とは
クラス型と配列型とinterface型の三種類

例
sample san1 = new sample     → sample1オブジェクト
sample san2 = new sample     → sample2オブジェクト

sample san1
sample san2

ここにsample = sam1と書けばsam2は消滅
　　　　　　　　　↓
sample san1 = new sample     → sample1オブジェクト
sample san2 = new sample     → sample1オブジェクト

san2が参照するところはsample1に変更される

NULLを代入すると参照先が無いという意味になる
Azure DevOps Boards(ボード)の超概要

Azure DevOps全体の概要については、こちらをご覧ください。
https://qiita.com/mstakaha1113/items/1cf45a5119e1397d0315


"Boards(ボード)"は、開発の根幹を成す大切なサービスです。
サービスとして何があるのかご紹介します。
超概要なので、具体的な画面の説明はありません。

# "Boards"のメニュー

![20190620-2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/53549476-a8b9-153e-e14b-3b5cc967f811.png)

かなりザックリした説明になります。あえて抽象的な言葉で説明しています。

- Work Items : 作業の一覧です。自分に割り当てられている作業をすばやく見つけたい時などに使います。
- Boards : 作業をカード型で提示し、ドラッグアンドドロップでステータス更新できます。付箋紙に書いた作業をホワイトボード上に貼りだしたような見せ方です。いわゆる"Kanban(かんばん)"と呼ばれているもので、作業の流れを可視化します。
- Backlogs : こちらも作業の一覧です。Work Itemsは"個人"に主眼を置いていますが、こちらは"プロジェクト全体"に主眼を置いています。どんな要求があるのか、どんな作業があるのか、どんな順番で実施するのかを確認したり整理するときに使います。
- Sprints : こちらも作業の一覧です。Backlogsとの大きな差としては時間軸があります。Backlogsが"大きな流れ"に主眼を置くのに対して、Sprintsは"短期間に何をするのか"に主眼を置きます。
- Queries : クエリですので、自分たちにとって有益な条件で作業を見えるように絞り込むのに使います。

# "Work Item(作業)"には種類がある
"Boards"は、プロジェクトを進捗させるために必要な様々なWork Itemを取り扱いますので、いくつかの種類が準備されています。
ここでは、とりあえず最初に覚えたい４つについて記載します。
![20190620-2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/a329e529-2460-e9bc-898e-e3b922b876bb.png)

- Epic : 最終的に何をなぜ提供したいのかを書きます。重厚長大なドキュメントを書くわけではなく、箇条書きにします。箇条書きの１項目を１Epicとして記載します。
- Feature : Epicを分解して、具体的な要求に落とし込みます。Featureを書いてみて、大きかったらEpicにしていく方が現実的です。
- User Story : Featureを形にする上で実際にやることが何なのか、実装ベースで記載します。アジャイル開発は短期間に小さな機能を完成させるという行為を繰り返します。この１単位期間でちょうど完成する程度の大きさを意識します。
- Task : User Storyを実現するための１つ１つの実際の作業を記載します。

はじめは、FeatureかUser Storyから書くことをおすすめします。自分の立ち位置が"想いを伝える側"であればFeatureから書き始め、Featureが大きいとか、複数の中身が詰まっていると感じたらEpicに変更して、さらに具体的な要求事項をFeatureとしてぶら下げるという順番で使いましょう。
自分の立ち位置が"形にする側"であればUser Storyから書き始め、それはどんな要求事項があるから存在するUser Storyなのかを考えてFeatureを書き出します。
場合によってはいくつかのFeatureの根幹が同じであることに気づくと思います。その時はFeatureをまとめるEpicを作成しましょう。

よくわからない場合は、全部User Storyとして書いてみてください。
記載内容をふんわりと眺めると、目線の高さが異なっていることに気づくと思います。
その違和感をベースにとりあえず各々の種別を変更します。
もう１度全体を眺めると、足りないピースが見えてきますので、埋めてください。

Taskは本当に実行する作業です。人が具体的に紐付くのは基本的にこのTaskです。


# コツ

## 機能を中心に書かない

WBSを書く際、よく機能名を羅列して、その機能名ごとのタスク(設計とか製造とか)を並べるというようなことをするかと思います。
アジャイル開発では、機能が揃うことは結果論であって、はじめから決まっているわけではありません。
想いがあって、それを実現する手段が機能であると考えます。予算や期間、ニーズの変動に伴い、同じことを実現するにしても実装方法はいくつも存在します。
例えば"ユーザーの新規登録"は新規登録画面だけが手段ではありません。明日からユーザー登録を受け付けなければならないと決まっているなら、例えば必要事項を明記してメールを送ってもらうというのも、良し悪しは別にして実現手段の１つになりえます。

## 具体的な数値目標を据えるが、絶対条件とはしない

要件定義を実施する場合、非機能要件を中心に具体的な数値目標を記載したことがあるのではないでしょうか。
たとえば、"画面のレスポンスは３秒以内"みたいなものです。
これは大切な要件です。アジャイル開発であっても具体的な目標とすべき数値は据えます。
具体的な数値目標を与えることで、どう実現すべきか(そもそも夢物語なのか)が見えてきます。

ただし、"この目標を達成しなければならない"という絶対的な条件にするかどうか別の話題です。
基本的には達成することを意識しますが、アジャイル開発では失敗も糧にします。
ただ批判したり、個人攻撃をしたり、ベンダーいじめをするための数値目標として記載するのではなく、なぜ達成できなかったのかを建設的に話し合うための材料にします。
そして改めて、達成することが大切なのか、他の方式をトライするのか、全員で協議します。

余談ですが、目標達成可否判断とリリース可否判断は完全一致しませんので、ご注意ください。
たとえば３秒目標が４秒になっても、儲かるからリリースするという判断もできます。

# まとめ
"Boards"をどう使うのかを学ぶと、アジャイル開発の基本的な考え方を学ぶことができます。
最初からうまくいくわけはありませんので、まずはUser StoryとTaskを使って実作業をまわしてみましょう。
SQLのメモ

・4大命令
構文
SELECT 列名 FROM テーブル名

UPDATE テーブル名 SET 列名＝値

DELETE FROM テーブル名
 
INSERT INTO テーブル名（列名）
       VALUES(値)
       

・対象行の絞り込み
WHERE

・検索結果の加工
　その他修飾


・ORDER BY 降順昇順 ASC DESC

・UNION 和集合を求める

構文
SELECT 文1
UNION(ALL)
SELECT 文2

「UNION」 ・・・重複は削除、1行にする
「UNION ALL」 ・・・重複も含める、すべて返す


・EXCEPT
別名MINS (ALLも使える)

差集合、最初の検索結果から次の検索結果と重複する
部分を取り除いたもの。
UNIONの逆の機能だと覚えてくれればいい


・INTRSECT (ALLも使える）

・積集合　2つの検索結果で重複するものを表示する


・グループ関数

SUM 各行の値の合計を求める
AVG 各行の平均値を求める
MAX 各行の最大値を求める 
MIN 各行の最小値を求める
COUNT 行数をカウントする

使い方
グループ関数(カラム名)

・SELECT HAVINGのみ
・SUM関数、AVG関数の列に
値が含まれる場合、DBMSごとに挙動が異なる


・DISTINCT
検索結果から重複行を除外する

構文
SELECT DISTINCT カラム名
FROM テーブル名

加工するキーワード
DISTINCT
ORDER BY
LIMIT
UNION
EXCEPT
INTERSECT


・テーブル結合

テーブルＡとテーブルＢ

構文
SELECT選択列リスト 
FOROM　テーブルＡ
JOIN  テーブルＢ
ON 両テーブルの結合条件
Pythonのfoo['a'], foo.a, foo.get('a')の違い

Python始めたてでふわっとしていたので自分なりにまとめてみました。

# 環境
- Python 3.7.3

# 色々試してみる
## dictの場合

```python

foo = {
    'a': 1, 'b': 2, 'c': 3
}

print(foo.get('a'))  # 1
print(foo.get('d'))  # None

print(foo['a'])  # 1
print(foo['d'])  # Exception has occurred: KeyError

print(foo.a)  # Exception has occurred: AttributeError
print(foo.d)  # Exception has occurred: AttributeError

# getだとExceptionが出ずに`None`を返してくれるので、if文とかで便利 
if foo.get('d') is None:
    print(True)
```

`foo['d']`でいけるなら`foo.d`でもいけそうな気がしてしまうjavascriptユーザー

## クラス・インスタンスメソッドの場合
`.`でのアクセスは、
Pythonではクラスメソッド・インスタンスメソッドへアクセスでのみ使うことができるらしい。
ついでに`get`はdictのメソッドなので使えない。

```python

class Foo:
    bar = 'bar'

    def __init__(self):
        self.baz = 'baz'

foo = Foo()
print(foo.bar)  # bar(クラス変数)
print(foo.baz)  # baz(インスタン卯変数)
print(foo.get('bar')) # Exception has occurred: AttributeError
print(foo.get('baz')) # Exception has occurred: AttributeError
```
仕事で全く役に立たないRコマンド

###はじめに

学習が全く捗らないので諦めて帰りたいのですが、帰るにはまだ時間もあるようなので、くだらない記事を投下してから帰ろうかと思います。

仕事では全く使わないでしょうが、もうどうにでもなろうぜ。

###funパッケージの導入

ネタを試すには`fun`パッケージを導入する必要があります。

```
# ライブラリ -------------------------------------------------------------------

pacman::p_load(fun)
```

####五目並べ

文字通り五目並べを行うことができるコマンドです。

```
#五目並べ
gomoku()
```

粋なネタですが欠点がありまして、5つ以上石を並べても続行することができます。
この**熱意があるのかないのかよくわからない中途半端なクオリティ**が素敵ですね。

![gomoku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/63d5e986-d924-6030-971b-c0cac1dcbc80.png)



####マインスイーパ

マインスイーパで遊べるコマンドです。

```
#width:横軸のグリッド数、height:縦軸のグリッド数、mine:地雷の数
mine_sweeper(width = 10, height = 10, mines = 20, cheat = FALSE)
```

![mine_sweeper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/adff49ad-edd4-9982-4ea9-05feba7a4343.png)


個人的に残念だった点はRでもマインスイーパで遊べるッ!ってウキウキしてたのに**this graphics device does not support event handling　ってエラーが出て遊べなかった**ことでしょうか。


####ライツアウト

ライツアウトで遊べるコマンドです。

```
#ライツアウト
#width:x軸のライト数、height:y軸のライト数、steps:パズル初期化のための「シード」ライトの数
#col.off:消灯時の色、seed:点灯時の色
lights_out(width = 5, height = 5, steps = 3, cheat = FALSE, col.off = "black", 
           col.on = "white", col.frame = "lightblue", seed = NULL)
```

![lightsout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/d86fd0f0-0e7c-1ee7-0187-d9e3f5ee6f4a.png)


残念ながらこれも**マインスイーパと同じエラーが出た**ので遊ぶのを断念しました。

####ハノイの塔パズルの実演

文字通りですね。

```
#ハノイの塔パズルを実演
tower_of_hanoi(n = 7)
```

![hanoi_tower.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/1a96a3f1-56b7-14b7-1788-1207c1dbcabf.png)


動作自体は確認できたので1秒くらい感動しました。
**虚しさを覚えたら動作を止めましょう。**

####アルツハイマーテスト

作った人のドキュメントに「医者じゃないのでテストの結果は気にしないでね」という**雑な注意書きが残してあった**ので、深く考えず気軽にやりましょう。

```
#アルツハイマーテスト
alzheimer_test()
```


###そして誰もいなくなった

```
#さようなら
shutdown()
```

このコマンドが何を意味するのか…お分かりですよね。
位置情報で日本を点描画

投稿練習がてら。

![__results___6_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163974/b7dc0322-4a2b-7815-3f26-ca4852c5dac0.png)


|address| lat       |       lon |
|:------|-----------------|------------------:|
|札幌市中央区南3条西11丁目| 43.055390           |            141.340980 | 
|札幌市北区北24条西6丁目1-1| 43.090691           |            141.340922 |
|....| ...           |            .... |


こんなデータ（dataj.csv）を用意して、pandasとseaborn,matplotlibで描画

```python:japan.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('../input/dataj.csv')
df.head()

x = df["lon"]
y = df["lat"]

plt.figure(figsize=(10,10))
plt.title("Cities Latitude and Longitude")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.scatter(x, y,s=1, alpha=1)
plt.show()
```

みたいな。市町村別のなんらかのデータ可視化をしたい。
【C#】TCP/IPサーバで通信の切断を検出する

TCP/IPサーバでクライアントと通信している時、クライアントとの接続が切れた場合の処理のまとめです。
接続が切れたとは、以下の場合です。

- クライアントが回線を切った
- クライアントが強制終了した
- ケーブルが外れるなど通信経路が切れた

# クライアントが接続を切った

クライアントが`shutdown`を実行して回線を切った場合、サーバーのNetworkStream.Read()は長さ０の通信を受け取って終了します。

```C#:normal_end
	int readsize = stream.Read( buf, 0, buf.Length );
	if( readsize == 0 )
	{
		// クライアントが切断したときの処理
	}
```

# クライアントが強制終了した

クライアントが`WSACleanup`を実行たり、`ExitProcess`して回線を切った場合、サーバーのNetworkStream.Read()は例外を投げて終了します。

```C#:forced_end
	try
	{
		int readsize = stream.Read( buf, 0, buf.Length );
		// クライアントからの受信処理
	}
	catch( Exception e )
	{
		// クライアントが切断したときの処理
	}
```

# ケーブルが外れるなど通信経路が切れた

通常は無反応です。
Keep-aliveの設定を行っておくと設定条件となった時、強制終了したときと同様にNetworkStream.Read()は例外を投げて終了します。

keep-aliveとは、接続している相手に定期的にプローブという通信を投げ応答があるかどうかを確認するもので、応答がなくなったら回線に異常が生じたと検出する手法です。
プローブのON/OFF、クライアントとの通信がなくなってからプローブを送信するまでの待ち時間、プローブを送信する間隔を設定します。

```C#:keep-alive_setting
	var clientSocket = listenerSocket.Accept();
	// keep-aliveをenableに設定
	clientSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true );

	// keep-aliveのパラメータ　Cで言うところの、unsigned int が３つです。
	byte[] tcp_keepalive = new byte[12];
	BitConverter.GetBytes( (Int32)1 ).CopyTo( tcp_keepalive, 0 );//onoffスイッチ.
	BitConverter.GetBytes( (Int32)2000 ).CopyTo( tcp_keepalive, 4 );//wait time.(ms)
	BitConverter.GetBytes( (Int32)1000 ).CopyTo( tcp_keepalive, 8 );//interval.(ms)
	// keep-aliveのパラメータ設定
	clientSocket.IOControl( IOControlCode.KeepAliveValues, tcp_keepalive, null );
```

待ち時間と間隔はミリ秒で設定します。
この例では、スイッチはON、待ち時間２秒、間隔１秒、です。Windowsでは１０回連続でプローブの応答がなかったら例外を発生するようです。

:exclamation:プローブはネットワークトラフィックを増やします。その点は注意。

参考URL
https://www.codeproject.com/Articles/117557/Set-Keep-Alive-Values