OmniAICreator/Qiita-1.07M huggingface dataset:
create-react-appで作った雛形のコードがService Workerで何をしているのか

create-react-appコマンドを実行すると、React.jsプロジェクトの雛形を作れます。
その雛形のsrcディレクトリ以下にregisterServiceWorker.jsというファイルがあります。
また、ビルドするとservice-worker.jsというファイルが生成がされます。

雛形のコードがService Worker上でしている事と、上記ファイルについてまとめてみました。

# Service Workerについて
Service Workerとは、リッチなオフライン体験・定期的なバックグラウンド同期・プッシュ通知など、いわゆるPWAの機能を実現するために基盤となる技術です。
（詳しくはGoogleのドキュメントにて解説されています。[Service Worker の紹介](https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja)）

Service Workerによって実現できる機能は様々ですが、create-react-appで作った雛形にはキャッシュの機能があらかじめ実装されています。
この機能によって、作ったReact.jsプロジェクトの静的ファイル（HTML、JavaScript、CSS、画像ファイル等）をブラウザ側のCache Storageという場所にキャッシュしてくれるようになります。
キャッシュされた静的ファイルとService Workerの組み合わせによって、次のことを実現することができます。

* 訪問時にキャッシュしたファイルを利用して、ページが高速に読み込まれるように
* ネットワークがオフライン状態になってても、キャッシュしたファイルを利用して動作するように
* アップデートされたファイルは、バックグラウンドでダウンロードしキャッシュされるように
* 基本的にキャッシュされたファイルを利用するようになるため、通信量を抑えることができる

# registerServiceWorker.jsについて
このファイルは閲覧しているブラウザにService Worker上で動くスクリプトを登録するスクリプトです。
Service Worker上で動くスクリプトというのはservice-worker.jsを指します。

この中にはService Workerの登録に関する処理があらかじめ書かれています。

registerServiceWorker.jsはsrc/index.jsから呼び出されており、以下コードで実行されています。

```javascript:src/index.js
import registerServiceWorker from './registerServiceWorker';

/* 中略 */

registerServiceWorker();
```

# Service Workerが登録される条件
Service Workerを閲覧しているブラウザに登録するためには、いくつかの条件があります。（[該当コード](https://github.com/facebook/create-react-app/blob/daf8df1ab3106ed0023dbfc1aba6fad830dfe4a8/packages/react-scripts/template/src/registerServiceWorker.js#L22)）

* 本番環境（process.env.NODE_ENVがproduction）であること
 * 開発中、ローカルで変更した内容がキャッシュによって確認し辛くなる事を防ぐため、本番のみ有効となっています
* ブラウザ側がService Workerに対応していること
 * 現在、全てのブラウザでサポートされていません。
 * ブラウザ側の対応状況については[こちら](https://caniuse.com/#search=service%20worker)で確認することができます。

# service-worker.jsについて
registerServiceWorker.jsはあくまでもService Workerに登録するだけのスクリプトで、Service Worker上で動いているのはservice-worker.jsになります。

このファイルはsw-precache-webpack-pluginのライブラリによってビルド時に生成されるスクリプトです。
中には静的ファイルをキャッシュする処理やキャッシュの管理、キャッシュしたファイルを利用する処理などが書かれています。

# Service Workerを無効にする方法
作成するWEBアプリケーションの内容次第ではService Workerのメリットが薄かったり、邪魔になる場合があります。
無効にする場合はsrc/index.jsにかかれている`registerServiceWorker()`の記述を削除します。
これにより、新しくService Workerが登録されることがなくなります。

また、１度でも本番環境でService Workerを有効にした場合は、既に登録されているService Workerを削除してあげる必要があります。
src/index.jsを以下のように変更します。

```javascript:src/index.js
import { unregister } from './registerServiceWorker';

/* 中略 */

unregister();
```

これでユーザーが再訪問したタイミングでService Workerが削除されます。
ただし、service-worker.jsは、キャッシュを無効にするまでに最大24時間かかる場合があります。

# 参考資料
[create-react-appのPWAに関するドキュメント（英語）](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app)
ArduinoでNTP取得(ESP-WROOM-02を使用)

Arduino本体の方で現在時刻を取得（誰か需要あるのだろうか…）

ちなみにESP-WROOM-02は単体でArduinoとして使用でき，
ライブラリによって直接NTPから現在時刻を取得できます．
[ESP8266のntpの設定は1行で](https://qiita.com/h_nari/items/d0374d1e1e36b9d988c0)


#回路構成
下の記事を参考に回路を組みます．
Arduino Leonardoで試しましたが，本体の3.3Vで駆動できました．
ただし，Software Serialがうまくいかなかったので10, 9番ピンに変更しました．
[【Arduino】ESP-WROOM-02( ESP8266 )を使ってWifiで無線通信する](http://nn-hokuson.hatenablog.com/entry/2017/04/09/091148)

#サンプルプログラム概要
1. ESP-WROOM-02でWiFi接続
2. NICTのjson形式のNTP情報をHTTP/GET
3. jsonを展開して現在時刻へ登録


#サンプルプログラム

```NTP.ino
#include <TESP8266.h> //ESP-WROOM-02ライブラリ
#include <TimeLib.h> 
#include <ArduinoJson.h>

// Wifi Config
const char* host = "ntp-a1.nict.go.jp";
const char* path = "/cgi-bin/json";
// Wifi
const char* ssid = "YOUR SSID";
const char* password = "YOUR WIFI PASSWORD";
TESP8266 httpClient(10, 9);

void setup() {
  Serial.begin(9600);

  // ESP-WROOM-02との接続確認(ATコマンドのテスト)
  while (true) {
    if (httpClient.statusAT(true)) {
      Serial.println("*** ESP-WROOM-02と接続しました。");
      break;
    }
    else Serial.println("*** ESP-WROOM-02と接続できません。");
    delay(1000);
  }

  // アクセスポイントに接続(DHCP)
  while (true) {
    if (httpClient.connectAP(ssid, password)) {
      Serial.println("*** アクセスポイントに接続しました。");
      break;
    }
    else Serial.println("*** アクセスポイントに接続できませんでした。 再試行中...");
    delay(1000);
  }

  // Wifi接続の確認
  while (true) {
    if (httpClient.statusWiFi()) {
      Serial.println("*** Wifi接続しました。");
      break;
    }
    else Serial.println("*** Wifi接続できません。");
    delay(1000);
  }

  ntp(); //本体へ登録　

}


void loop() {
  time_t t = now(); 
  char s[20];

  const char* format = "%04d-%02d-%02d %02d:%02d:%02d";
  sprintf(s, format, year(t), month(t), day(t), hour(t), minute(t), second(t));
  Serial.println(s);
  delay(1000);
}

void ntp() {
  StaticJsonBuffer<200> jsonBuffer;
  uint32_t filesize = 0;
  String resultString  = httpClient.get(host, path, filesize);
  JsonObject& root = jsonBuffer.parseObject(resultString);
  String ntp = root["st"];
  long unsigned int nt = ntp.toInt();
  setTime(nt);
}

```

#動作サンプル
<img width="856" alt="スクリーンショット 2018-07-08 20.08.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/188498/7764574d-81b0-bc6e-cc67-bd8778e41d92.png">
react-nativeプロジェクトを作成


## install

ターミナルを開いてプロジェクトを作成したいフォルダに移動します。
その後、以下コマンドを打つ

## react-nativeプロジェクトを作成

```
react-native init nativeLocation
```

```
cd nativeLocation
npm install --save react-native-location

```



## 実行

```
react-native run-ios

```
React-nativeをexpo.ioで実機デバッグ(CLI版)



[Expo — Learn how](https://expo.io/learn)


Node.jsを入れる。

## Get the command line tool

`npm install exp --global`



## Create your first project

### create app

```
exp init my-new-project
```

app start

```
cd my-new-project
exp start
```


```
? How would you like to authenticate? (Use arrow keys)
❯ Make a new Expo account
  Log in with an existing Expo account
  Cancel
```


input maill address

```
An Expo user account is required to proceed.

? How would you like to authenticate? Log in with an existing Expo account
? You are already logged in as xxxxxx. Log in as new user? Yes
? Username/Email Address: ```
? Password: [hidden]
```

```
Success. You are now logged in as xxxxxx.
12:13:30 [exp] Using project at /Users/xxxxxx/Documents/my-new-project
12:13:32 [exp] Warning: You are using npm version 5.6.0. There may be bugs in this version, use it at your own risk. We recommend version latest.
12:13:40 [exp] Starting React Native packager...
12:13:42 [exp] Loading dependency graph.
12:13:43 [exp] Dependency graph loaded.
12:13:44 [exp] Tunnel connected.
12:13:45 [exp] Expo is ready.

12:13:46 [exp] Warning: You are using npm version 5.6.0. There may be bugs in this version, use it at your own risk. We recommend version latest.

```


ここでQRコードが表示されるので、カメラで撮影してアクセスする。


起動しました

![IMG_7994.png](https://qiita-image-store.s3.amazonaws.com/0/49910/e17be556-b4b9-a364-e2c7-4e2b754628a5.png "IMG_7994.png")
react-native-background-timer



[react\-native\-background\-timer](https://github.com/ocetnik/react-native-background-timer)


react-native create

```
react-native init nativeBackgroundTimer
```

ここで一度実行する

```
react-native run-ios

```


## react-native-background-timer

```
npm i react-native-background-timer --save
react-native link
```


## add the following to your Podfile

```
pod 'react-native-background-timer', :path => '../node_modules/react-native-background-timer'
```


## pod install

```
cd ios
pod repo update
pod install
```


## build(実行)

```
react-native run-ios

```
フラスタ企画をもっと簡単にするRailsアプリ「ふらすたった〜」を作ってみたかった

#自己紹介
- くぎゅう10P (@kugyu10)
- 本業：水瀬伊織担当
- 副業：SE（すごくExcel使う人、の略） 3年目 Javaメイン。
- Ruby on Rails独学中。

---
# 皆さん！フラスタってますか？

---

# フラスタとは？

ライブとかで贈るお花、フラワースタンド
および、それをみんなでお金カンパしあって演者を応援するお花を贈る企画、フラスタ企画。

---


# フラスタ企画のめんどくさいこと〜集金〜

- 手渡し集金
  - 現地いける同士ならいいよね。
  - チケットをご用意することがry
- 銀行振込で集金
  - ハンドルと不一致な本名。集計の手間。
  - え？他銀行振込手数料432円？

⇛ システムにできない？

---
フラスタ企画のめんどくさいこと〜協賛者名〜

−Twitter名とイコールではない。
  − P専用垢じゃない人もいるし
  − @以下をコロコロ変える人も多いし
  − 誤字ったりしたら失礼だし

⇛ システムにできない？？

---

# オープンに、誰でも参加できて、決済や集計も楽ちんなフラスタ企画サービスって無いの？
---
# なら作っちゃおうぜ？
---
# フラスタ企画をもっと簡単に！WEBサービス「ふらすたった〜」を作ってみたかった

Ruby on Rails でHerokuで作ってます。

URL:
https://flow-statter.herokuapp.com/

Github:
https://github.com/kugyu10/flow_statter

---

- 7/7 プレゼン当日、デモ版動作する開発環境を壊してしまい、デモできず。ただただ小鳥さんばりの妄想力を垂れ流すだけのLTとなりました。
- 7/8 環境直りました。一応Twitter認証でログインし、フラスタプランを企画するとこまでデモできます。https://flow-statter.herokuapp.com/

---
# こんなことをやってみたい！

---
# 「ガチャ１回分で参加できる！」一口300円フラスタ

ガチャ１回分で参加できるフラスタ。クレカ決済なら振込手数料が少ないので実現可能。お互いが個人情報晒さずにできるので新規さんも参加しやすいフラスタ企画（をやる予定です）

１０口参加したら確定SR枠として協賛名が大きくなるとか面白いと思います。（やる予定です）

---
# お花屋さんへのお礼状機能

企画ページのコメントやTwitter検索などから
お花の感想を拾ってきて、簡素にまとめれば
それがそのままお花屋さんへのお礼レポートになります。（予定です）



---
# フラスタ特化ならではの機能

- 過去のフラスタ一覧（企画Pの実績がそのまま残ります）
- 入金アラート（通知OFF可） 入金締切日○日前に、あなたが未入金だったら通知してくれます。
- ○日までに○人集まらなかったら企画中止！機能。企画者の赤字回避。
- あるいは、「３万円のフラスタ発注するので、○日に集まった人数で割り勘！」
- 協賛者名の項目。
- レギュレーションURL入力欄。公式のフラスタレギュレーション、けっこう出るのが遅いので、出たり更新があったりしたら、参加者が誰でもすぐに確認できるように。
- 複数口参加可能。「1000円の企画だが、別に俺が10口参加してしまっても構わないのだろう？」
- 画像投稿機能「現地でフラスタ撮ってきました うp」
- 簡易会計報告機能

などなど。妄想ばかりですが。

---

# 課題

- ぼくの技術と時間不足。
- 決済関連
  - PAY.JP Platformを検討中だけど制約とか今ひとつ分からない。

⇛もう少し進展したらまたご報告させて下さい！

---

以上
ありがとうございました。
RubyとRails 初心者 インストールと起動

## Rubyのインストール

[Rubyのインストールはこちら](https://qiita.com/yusk24/items/299d373f589dff952e02)

## Railsのインストール

`$ gem install rails`
`$ rails -v`

### proxyの設定
プロキシの方は、設定してください
`$ vi ~/.gemrc`

```:~/.gemrc
http_proxy: http://71289840:a8612hrl@obprx.intra.hitachi.co.jp:8080
```

Node.jsもインストールしないといけない場合もある(CentOS)
Debianインストールする必要はなかった。
### nvm(Node.jsバージョン管理ツール)のインストール

`$ git clone git://github.com/creationix/nvm.git ~/.nvm`
`$ source ~/.nvm/nvm.sh`
インストール可能なバージョンの確認

`$ nvm ls-remote`
インストール（現在2018/07/08では、v8.11.3）
`$ nvm install v8.11.3`
バージョンの確認
`$ node --version`
nodeの初期設定ファイルの一番下に入れてください

```
$ vim ~/.bash_profile
~ ~ ~
# nvm設定
if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi
```

## 雛形を作成
必要なモジュールがいる

### sqlite3のインストール
デフォルトでは、DBがsqlite3
おそらくオプションでRDBMSを変えられる

Ubuntuの場合
`$ sudo apt-get install -y sqlite3 libsqlite3-dev`
CentOSの場合
`$ sudo yum install -y sqlite3 sqlite-devel`

### 雛形作成コマンド
`$ rails new [myapp]`

## 起動
通常のサーバー起動は、[s]か[server]

`$ rails s`
オプション
-b serverのhostを指定
-d デーモン（バックグラウンド）で起動

`$ rails s -b 192.168.33.10 -d`

バックグラウンドで起動した際は、pidからkillして終了

### サーバーのpidの調べ方
`$ cat tmp/pids/server.pid`

### 本当に動いているか確認
`$ ps ax | grep {調べたpid}`

もしくは、puma(railsのサーバー)で検索しても出てくる

`$ ps ax | grep puma`

### killする
オプションは、-2が[Ctrl+C]の割り込み終了なのでオススメ
それで無理ならオプションなしでkill

`$ kill -2 {調べたpid}`

## ブラウザで確認
オプションで設定した192.168.33.10だった場合
「`http://192.168.33.10:3000`」
をブラウザに入力する
ポート番号は、デフォルトで3000
おそらくNode.jsのデフォルトが3000なので関係している。

## ログの確認
`$ tail log/development.log`
[Review] Transition of DRL

## Introduction

## Agenda

## Transition
1. Value Function stands on MDP/POMDP
2. Model Based: Dynamic Programming by Richard Bellman in 1950s.
3. Model Free: TD Learning(Temporal Difference Learning) by Sutton et al., 1988.
4. SARSA/Qlearning introduced by Sutton and Watkins in 1992.
<img width="485" alt="Screen Shot 2018-07-08 at 14.27.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/ab1913dd-1027-e31e-7496-2a76149c097c.png">
5. Multi-step Bootstrapping: Introduction of $\lambda$ in TD/Q learning.
6. Evolution from Tabular System to large continuous space of environment, which is Function Approximation.
7. Linear Function Approximation
EX: [SARSA with Linear Function Approximation](http://artint.info/html/ArtInt_272.html)
8. Neural Function Approximation with RL by Bertsekas et al., 1996
JS基礎ーRxJSのObservable

# 初めに
今回はRxJSライブラリーのObservableについて整理してみます。

# 先ずは公式サイトの例

```javascript
var observable = Rx.Observable.create(function (observer) {
  observer.next(1);
  observer.next(2);
  observer.next(3);
  setTimeout(() => {
    observer.next(4);
    observer.complete();
  }, 1000);
});

console.log('just before subscribe');
observable.subscribe({
  next: x => console.log('got value ' + x),
  error: err => console.error('something wrong occurred: ' + err),
  complete: () => console.log('done'),
});
console.log('just after subscribe');
```
実行すると：

```javascript
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done
```
## Observableとは
Observableは**関数**である

>var observable = Rx.Observable.create(function(observer){}

上記のように、Observable関数を作成できる

## subscribe

***どうやってsubscribe？***
答えはObservableのsubscribe()関数
下記のようにsubscribe()でObservableを観察できる(観察者はobserver)

```javascript
observable.subscribe(observer);

var observer = {
  next: x => console.log('Observer got a next value: ' + x),
  error: err => console.error('Observer got an error: ' + err),
  complete: () => console.log('Observer got a complete notification'),
};
```
***※subscribe()するとobservableの関数構文がすぐに実行するされる***

## 多重subscribe

>observable.subscribe(observer2);

#まとめ
Observable：観察された側
Observer：観察側
Subscribe：観察関係の構築

#参考
[RxJS公式サイト](http://reactivex.io/rxjs/manual/overview.html)
【Android】ビルド時エラー

昔々に入れたAndroid Studioを久々に触ったらエラーが出たので対処法をメモ。


# 前提

- Android Studioは2年前に入れたものの、サンプルプロジェクトを作ろうとしたところで挫折
- 久々の学習だったので、ドットインストールを見ながら進めていたところ、ビルド段階でエラーが出た
 [レッスン一覧 Androidアプリ開発入門 #02 プロジェクトを作成しよう](https://dotinstall.com/lessons/basic_android_v3/43402)


# エラー文言
```
  Error:Execution failed for task ':app:preDebugAndroidTestBuild'.
> Conflict with dependency 'com.android.support:support-annotations' in project ':app'. Resolved versions for app (26.1.0) and test app (27.1.1) differ. See https://d.android.com/r/tools/test-apk-dependency-conflicts.html for details.
```

# 対処
- エラー文言の参照ページを見た
 [参照ページ](https://developer.android.com/studio/test/?utm_source=android-studio#dependency_conflicts)

- そもそも何を言っているかよくわからない段階なので日本語の記事を探した
 [同じ事象を発見](http://moonheights.hatenadiary.jp/entry/2018/05/07/050318)

- テストアプリと本番アプリのSDKバージョンが違う（？）らしい
- app > build.gradle 内のSDKバージョン記載を27.1.1に上げた。（テストSDKのバージョン下げ方がわからない）

# メモ
SDKバージョンよる差があまりわからないままバージョンを上げてしまったので、これが正解なのかよくわからない・・・
見たところ、[SDKバージョン26も27もOreo向けなので](https://akira-watson.com/android/sdk-version.html)大丈夫なのではないかと期待しつつ・・・
未だ「テストアプリ」とは？段階なので、後々正しい修正方法が分かり次第情報更新します。
crowi-plusサーバ移行


## volume mongoDBからexport
```
$ docker run --rm -v crowiplus_mongo_db:/data -v `pwd`/backup:/backup busybox sh -c 'tar -cOzf - /data' > volume-export_mongo_db.tgz

$ docker run --rm -v crowiplus_mongo_config:/data -v `pwd`/backup:/backup busybox sh -c 'tar -cOzf - /data' > volume-export_mongo_configdb.tgz

$ docker run --rm -v crowiplus_crowi_data:/data -v `pwd`/backup:/backup busybox sh -c 'tar -cOzf - /data' > volume-export_crowi_data.tgz

$ docker run --rm -v crowiplus_redis_data:/data -v `pwd`/backup:/backup busybox sh -c 'tar -cOzf - /data' > volume-export_redis_data.tgz

```

## volume mongoDBからimport
```
$ docker run -v crowi-plus_mongo_db:/data -v `pwd`:/import -e TARGETFILE=volume-export_mongo_db.tgz 74th/volumerestore
$ docker run -v crowi-plus_mongo_config:/data -v `pwd`:/import -e TARGETFILE=volume-export_mongo_configdb.tgz 74th/volumerestore
$ docker run -v crowi-plus_crowi_data:/data -v `pwd`:/import -e TARGETFILE=volume-export_crowi_data.tgz 74th/volumerestore
$ docker run -v crowi-plus_redis_data:/data -v `pwd`:/import -e TARGETFILE=volume-export_redis_data.tgz 74th/volumerestore
```


## mongoDB 
```
mongodump --archive=/tmp/corwi.20180710.gz --gzip --db crowi
# コンテナIDを調べる
$ sudo docker ps

$ sudo docker cp <コンテナID>:/etc/my.cnf my.cnf
docker exec -it crowi-plus_mongo_1 bash 
mongorestore --gzip --archive=/tmp/crowi.20180710.gz --db crowi

```
mongoDB
https://qiita.com/yuji0602/items/c55e2cb75376fd565b4e
pyenvで3.7系のインストールに失敗したときのメモ

# エラー内容

3.6系までは普通にインストールできていたのに、3.7をインストールしようとしたら次のようなエラーでインストールに失敗。
ちなみにOSはUbuntu 18.04です。

```console
$ pyenv install 3.7.0
Installing Python-3.7.0...

BUILD FAILED (Ubuntu 18.04 using python-build 1.2.3-79-gc057a80c)

Inspect or clean up the working tree at /tmp/python-build.20180708190520.14846
Results logged to /tmp/python-build.20180708190520.14846.log

Last 10 log lines:
  File "/tmp/tmppm_d6i5e/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/__init__.py", line 42, in <module>
  File "/tmp/tmppm_d6i5e/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/cmdoptions.py", line 16, in <module>
  File "/tmp/tmppm_d6i5e/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/index.py", line 25, in <module>
  File "/tmp/tmppm_d6i5e/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/download.py", line 39, in <module>
  File "/tmp/tmppm_d6i5e/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/utils/glibc.py", line 3, in <module>
  File "/tmp/python-build.20180708190520.14846/Python-3.7.0/Lib/ctypes/__init__.py", line 7, in <module>
    from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
Makefile:1122: recipe for target 'install' failed
make: *** [install] Error 1
```
# 解決方法
libffi-devを入れることで解決

```console
$ sudo apt install libffi-dev
```

CentOS系では以下`apt`の代わりに`yum`を実行します。

```sh
sudo yum install libffi-devel
```

# Macでつまった時の話
Macでは「opensslがない」みたいなエラーが出ました。[このブログ](https://blufflog.hatenablog.com/entry/2018/09/25/224259)が参考になりました。
どうやら、もとから入っているpythonはopensslなしでコンパイルされたものらしいです。
ノンプログラマの友達と遊べるDiscord BotをGoで作ってみた

最近話題のDiscord Botを作ってみたので、ノンプログラマの友達と遊べるDiscord Botという名目で公開しました。
[github.com/aimof/discat](https://github.com/aimof/discat)にソースをMITライセンスで公開中です。

## デモ

![Screenshot from 2018-07-08 18-40-54.png](https://qiita-image-store.s3.amazonaws.com/0/140543/9eab7034-3737-ec42-c52a-795d7c69fa0a.png)

一日の始まりは挨拶から！

というわけで、文書に予め決めておいたランダム返答を返します。

## 機能

* 人口無能的に決められた単語をトリガーに決められた返答を返す機能。
* 発言数に応じてレベルが上がっていく機能（下）

![Screenshot from 2018-07-08 18-39-35.png](https://qiita-image-store.s3.amazonaws.com/0/140543/4fbd2ffd-d524-8619-d319-585decd09794.png)

レベルが上がったり下がったりしているのはdockerのストレージ永続化に失敗しているからです。

## どの辺がノンプログラマーと一緒に楽しめるの？

なんとこのボット、セリフをGoogle SpreadSheetで編集できるようにしました。（自動デプロイはまだないので手動でcsvを移植する必要があります）

設定ファイルはこんな感じ

![Screenshot from 2018-07-08 18-48-48.png](https://qiita-image-store.s3.amazonaws.com/0/140543/20250391-b094-e27f-5576-5740fdff97b2.png)

## ライブラリ

ライブラリとしても利用でき、シンプルに上の機能だけ返すようになっています。

## 技術的ないろいろ

技術面で考えたことを書いていきます。あんまり難しいことはしていないので、書くことは多くないかも

### ライブラリのメイン

```discat.go
package discat

type Discat struct {
	speaker speaker
	level   level
}

func Init(dict [][]string, expMap map[string]int) Discat {
	return Discat{
		speaker: newSpeaker(dict),
		level:   level{exp: expMap},
	}
}

func (d Discat) Speak(input string) string {
	return d.speaker.speak(input)
}

func (d Discat) GainExp(name string, exp int) {
	d.level.gainExp(name, exp)
}

func (d Discat) ShowLevel(name string) (exp, level, rest int) {
	return d.level.showLevel(name)
}

func (d Discat) Output() map[string]int { return d.level.output() }
```

Goっぽく書くことを意識したらこうなったのですが、これでいいのだろうか…。ライブラリは、ただ文字列をもらって文字列や数字を返すだけのシンプルなものにしました。それ以上の機能はコマンド側で実装

### インタラプトを受け取るよくあるアレ

```main.go
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
_ = <-ch
err = session.Close()
if err != nil {
	log.Fatalln(err)
}
// 正常終了処理
```

インタラプトシグナルからセッションを正常に終了させるやつです。

### 話す部分は愚直に実装

```speaker.go
func (s speaker) speak(sentenceIn string) string {
	for key, value := range s.table {
		if strings.Contains(sentenceIn, key) {
			return value[rand.Intn(len(value))]
		}
	}
	return ""
}
```
入ってきた文章に対し、持っている単語とかぶっている箇所があれば、対応するレスポンスをリターンします。
同じ文言でもセリフが変わって楽しめます。

tableというフィールド名のmapがあるのは気持ち悪いですね…（今気づいた）

### docker-composeでボリュームをマウントできない問題

```Dockerfile
FROM golang:1.10.3-alpine

LABEL maintainer "aimof <aimof.aimof@gmail.com>"

RUN apk update --no-cache && \
    apk add --no-cache git && \
    go get -u github.com/golang/dep/cmd/dep

COPY . /go/src/github.com/aimof/discat/
WORKDIR /go/src/github.com/aimof/discat/cmd/discat/

RUN dep ensure && \
    go build

CMD ./discat
```

```docker-compose.yml
version: "3"
services:
  discat:
    build: .
    volumes:
      - /home/ubuntu/discat/cmd/discat/data:/go/src/github.com/aimof/discat/cmd/discat/data
    logging:
      options:
        max-size: "10m"
        max-file: "5"
volumes:
  data:
```

リポジトリをubuntuユーザーホーム直下に置く想定で、こんな`docker-compose.yml`を書いたのですが、なぜかボリュームのマウントに失敗。ローカルでは成功したのだが…

## まとめ

Discordボット開発楽しいです。プログラムかけない友達もセリフを考えるところなら参加してもらえるので、もしご興味あれば利用してみてください。
なお、まだプロト段階ですので、まだ使いづらいです。ちょっとずつ改善していきます。
初心者のリスト（List)メモ

前回のメモの配列を一つずつしか表示できないという悩みを解決するためにListViewを使うことにした。
そこでそもそもListとは何かということをまず調べてみた。
簡潔にまとめると
Listとは基本的に配列と同じように値を格納することのできるけど配列とは違い格納した後に簡単に値を挿入したり変更したり削除したりすることができる（らしい）。
また、ListViewはListの中にある要素をすべて表示させることができるため、とにかく表示させたいだけなら使える。
しかも配列と互換性？があるため配列からリストに、リストから配列の型に変えるのがとても楽である。
でもプログラミング初心者の人が使うときはちょっと注意が必要。、
もし配列からListに中身を入れ替えてListViewで表示させようとしたときにそのListの中に<strong>Null値</strong>が入っていればもれなくアプリが停止することが分かった。
いや、こんなミスするの僕だけかもしれないけどもし、もしListViewを使っている部分でアプリが停止したらListの中身にNull値が入っていないかSystem.out.println();かなんかで確認してほしい。
Null値が入っていればそれがアプリ停止の原因かもしれないよ。
Null値が入っていたらIf文で取り除けばきちんと動作するかも。
以上、超初歩的でだからこそ検索しても見つけられなかったことでした。（ただ検索が下手だっただけかもですが）


#PS
###初期化していない配列の初期値にはNULLが入ってるらしいので気を付けます。
#初期化、大事
[初学者]破壊的なメソッドを簡単に説明してみた

# 目的 
- 初学者にとって「破壊的」という言葉が何なのか理解しづらいので簡単に説明を書いてみた


# 目次
- 破壊的なメソッドとは
- 感嘆符(!)が付いていない破壊的メソッド一覧


# 破壊的なメソッドとは

破壊的なメソッドとは、一言で言うと

- <b><font color="Red">「レシーバーに変化を与えること」</font>
- <b><font color="Red">「オブジェクトの値を変更してしまうもの　(値が更新されて保存)　」</font>


```bash:irbで確認
# 変数を定義
a = 'kanemoto'

#　破壊的ではないメソッド
a.reverse      # aがレシーバ
=> "otomenak"  # reverseメソッドは逆から読まれる
# メソッド適用後,再度変数をみてみる
a
=> "kanemoto"　# オブジェクトは初期のまま

-----------------------------------------------------------

#　破壊的なメソッド
a.reverse!     # 感嘆符(!)が付く場合が多いが、必ずしも付くわけではない。
=> "otomenak"  # reverseメソッドは逆から読まれる
# メソッド適用後,再度変数をみてみる
a
=> "otomenak"　　# オブジェクトが更新されている

```

# 感嘆符(!)が付いていない破壊的メソッド一覧

| Stringクラス||
|:-----|:---------|
|  <font color="Red">insert</font> |[文字列の中で第1引数の位置に別の第2引数の文字列を挿入](https://ref.xaio.jp/ruby/classes/array/insert)|
|  <font color="Red">replace</font>|[文字列の内容を引数のもので置き換え](https://ref.xaio.jp/ruby/classes/string/replace)|
| concat| [<<の別名。文字列の末尾に別の文字列を加えます](https://ref.xaio.jp/ruby/classes/string/concat) |

| Arrayクラス||
|:-----|:-------|
| push |[配列の末尾に引数を要素として追加](https://ref.xaio.jp/ruby/classes/array/push)|
| concat |[配列の末尾に、引数の配列を結合](https://ref.xaio.jp/ruby/classes/array/concat)|
|  <font color="Red">insert</font> |[第1引数で指定した位置に第2引数を要素として挿入](https://ref.xaio.jp/ruby/classes/array/insert)|
| unshift |[引数を配列の先頭に要素として追加](https://ref.xaio.jp/ruby/classes/array/unshift)|
| fill |[配列のすべての要素を引数で置き換え](https://ref.xaio.jp/ruby/classes/array/fill)|
|  <font color="Red">replace</font> |[配列の内容を引数のもので置き換え](https://ref.xaio.jp/ruby/classes/array/replace)|
| delete_at |[配列から引数の位置の要素を削除](https://ref.xaio.jp/ruby/classes/array/delete_at)|
| delete_if |[要素の数だけ繰り返しブロックを実行し、ブロックの戻り値が真になった要素を削除](https://ref.xaio.jp/ruby/classes/array/delete_if)|
| delete |[配列から引数と同じ要素を探して、すべて削除](https://ref.xaio.jp/ruby/classes/array/delete)|
| clear |[要素をすべて削除し、配列を空にします](https://ref.xaio.jp/ruby/classes/array/clear)|
| shift |[配列の最初の要素を削除し、その要素を返します](https://ref.xaio.jp/ruby/classes/array/shift)|
| pop |[配列の末尾の要素を削除し、その要素を返します](https://ref.xaio.jp/ruby/classes/array/pop)|

| Hashクラス||
|:---------|:-------|
| delete |[ハッシュから引数と同じキーを探して、キーと値を削除](https://ref.xaio.jp/ruby/classes/hash/delete)|
| delete_if |[繰り返しブロックを実行し、ブロックの戻り値が真になったキーと値を削除](https://ref.xaio.jp/ruby/classes/hash/delete_if)|
| <font color="Red">replace</font> |[ハッシュの内容を引数のもので置き換えます](https://ref.xaio.jp/ruby/classes/hash/replace)|
| shift |[ハッシュからキーと値を1組削除](https://ref.xaio.jp/ruby/classes/hash/shift)|
| <font color="Red">update</font> |[merge!の別名。2つのハッシュを統合](https://ref.xaio.jp/ruby/classes/hash/update)|
| clear |[キーと値をすべて削除し、ハッシュを空にします](https://ref.xaio.jp/ruby/classes/hash/clear)|
Graphql の雰囲気を掴む (apollo-server)

# `Graphql` の雰囲気を掴む (`apollo-server`)

## 出来上がる物 & わかること
- 出来上がる物
  - https://github.com/baronTommy/apollo-server-pg

- わかること
  - mockの処理 と 実際の処理を併用
  - Graphqlのrelation(`GraphQL Voyager`)

- おまけ
  - `axios`で叩いてみる

## `Graphql` とは

### これです!!!!!!!!!

![GQL](https://pbs.twimg.com/media/DgsXLk_X4AEKiJJ.jpg "GQL")
> https://twitter.com/NikkitaFTW/status/1011928066816462848


### 作業

#### node_modules インストール
- https://github.com/baronTommy/apollo-server-pg/blob/master/package.json
> インストール

#### schemaを定義
- ディレクトリやファイル
  - `/graphqlSchema/schema.graphql`

- 補足
`type User{...}`,`type Company{...}`

> schema

`type Query {...}`

> schemaのデータの取得方法や、戻り値 のような定義

`type Mutation {...}`
> データ更新時の、戻り値, のような定義

```graphql
type User {
  id: ID!
  name: String!
}

type Company {
  id: ID!
  name: String!
}

type Query {
  user(id: Int, name: String): User,
  company(id: Int, name: String): Company,
  allUser: [User]
}

type Mutation {
  user(name: String): String!
}
```

#### mock処理の準備
- ディレクトリやファイル 
  - `/graphql/mock/mocks.js`
 
- 補足
schemaに一致させた準備
idは、未定義 mockの値が返却される

```js
export const User = () => ({
    // id: () => "2525",
    name: () => "mock 太郎"
  })
  
export const allUser = () => [
  User,
  User,
]
```

#### 実際の処理の準備
- ディレクトリやファイル
 - `/graphql/querys.js`

- 補足
  - 実際は、DBから取得したりなど

```js
export const company =  (_, req) => {
    if (req.id === 123) {
        return {id: "123", name: "google (ガチデータ)"}
    }
    return {id: "", name: ""}
}
```

#### サーバ
- ディレクトリやファイル 
  - `/src/index.js`

- 補足
上記で作ったファイルなどをとりこむ


```js
import express from 'express'
import bodyParser from 'body-parser'
import cors from 'cors'
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools'
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express'
import { importSchema } from 'graphql-import'
import { express as voyagerMiddleware } from 'graphql-voyager/middleware';
import { mocks } from '../graphql/mock'
import { resolvers } from '../graphql/resolvers'

const typeDefs = importSchema('graphqlSchema/schema.graphql')
const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
})

// mock 有効化
addMockFunctionsToSchema({ 
  schema,
  mocks,
  // mock と resolversの併用
  preserveResolvers: true,
 })

const app = express()
app.use(cors());

// end point
app.use('/graphql', bodyParser.json(), graphqlExpress({ schema }))

// GQL エディタ 
app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }))

// GQL relation
app.use('/voyager', voyagerMiddleware({ endpointUrl: '/graphql' }));

app.listen(3000, () => console.log(
  '/graphql',
  '/graphiql',
  '/voyager',
))
```

### 最後に
`yarn start` or `npm start`

- voyager 
  - http://localhost:3000/voyager
  - relationがみれます

- GQL エディタ
  - http://localhost:3000/graphiql

### おまけ
`axios`からたたく
> 他のクライアントもあるが、とりあえず

```js
axios({
    url: 'http://localhost:3000/graphql',
    method: 'POST',
    data: {
    query: `query {
        allUser {
        id
        name
        }
    }`
    }
})
```

### 参考にさせて貰いました
- https://qiita.com/mizchi/items/c078aea032cd00ba3e86
- https://ushumpei.hatenablog.com/entry/2017/12/12/000000
[Swift]SwiftのOptionalを理解する

<p>無</p>

<ul>
<li>Lispでは、無を表すものとしてnilを用意。</li>
<li>C言語では、空ポインタとしてNULLマクロを定義。</li>
<li>Objective-Cでは、空idとしてnilが用意され、画期的なのはnilにメッセージを送信しても無視されるだけでエラーにならない！</li>
<li>SwiftのnilはObjective-Cとの互換。Cocoaフレームワークを利用するためか。</li>
</ul>

<pre><code>var a : Int = 1
var b : Int? = 2
a = nil  // エラー
b = nil  // OK
b = Int(“abcd”)  // nil
var c : Optional<Int> = 3  // パラメータ付き型指定
</code></pre>

<p>開示（unwrap）</p>

<pre><code>var a : Int? = 1234
var b : Int = a - 2  // 型が異なるのでコンパイル・エラー
var b : Int = a! - 2  // 開示指定する
a = nil
b = a! - 2  // 実行時エラー
 
a = 5678
if a != nil {
    print(“\(a!)”)  // 開示指定が必要
}
print(String(describing: a))  // Debug目的で
</code></pre>

<p>オプショナル束縛構文 optional binding</p>

<pre><code>var num : Int? = 1234
if let n = num {
    print(“\(n)”)
}
 
if var n = Int(“1234”) {
    n += 5678
    print(“\(n)”)
}
 
if let n = Int(“1234”), let m = Int(“5678”) {
    print(“\(n + m)”)
}
 
var a : Int? = 1
while let n = a {
    a = nil
}
</code></pre>

<p>guard文</p>

<pre><code>guard 条件 else { /* breakやreturn */ }
 
func demo(_ num:Int?) {
    guard let n = num else { return }
    print(“\(n)”)  // 変数nが使える
}
</code></pre>

<p>nil合体演算子</p>

<pre><code>let n : Int? = 1234
 
let m = (n != nil) ? n! : 0
let m = n ?? 0
 
let a : Int? = nil
let b : Int? = nil
let c : Int? = 3
let = a ?? b ?? c ?? 0  // cの値
</code></pre>

<pre><code>func demo(_ p: inout Int?) {
    p = nil
}
var n: Int? = 1234
demo(&n)
print(n ?? “nil”)
 
func test(_ num: inout Int) {
    num = 0
}
n = 5678
test(&n!)  // nがnilだと実行時エラー
print(n ?? “nil”)
</code></pre>

<p>有値オプショナル型 (IUO)</p>

<pre><code>let n : Int! = 1234
print(“\(n)”)  // 開示指定は不要
 
var m : Int! = nil
m += 5678  // 実行時エラー
print(“\(m)”)
</code></pre>

<p>失敗のあるイニシャライザ</p>

<pre><code>struct Demo {
    var a = 0
    init?(_ n:Int) {
        if n < 0 {
            return nil
        }
        a = n
    }
    init() {
        a = 1234
    }
}
var p: Demo = Demo()
var q: Demo? = Demo(5678)
</code></pre>

<p>キャスト演算子</p>

<ul>
<li>式 is T <br />型/プロトコルTなら真</li>
<li>式  as T <br />型/プロトコルTにキャスト</li>
<li>式 as? T<br />型/プロトコルTのオプショナルにキャスト<br />失敗した場合はnil</li>
<li>式 as! T<br />型/プロトコルTにキャスト<br />失敗した場合は実行時エラー</li>
</ul>

<p>オプショナルチェーン optional chaining</p>

<pre><code>// 辿っている途中でnilがあれば、
// そこで止まり全体でnilとなる。
if let name = who?.club?.teacher?.name {
    print(name)
}
</code></pre>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/91202/">BUKURO.swift 2018-07</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
UIViewを燃やしてみた（swift）

#はじめに
[noppefoxwolf/Kitsunebi](https://github.com/noppefoxwolf/Kitsunebi)これをみてUIViewを燃やせるんじゃないかと思いつくってみました。

2019/04/21 せっかくなんでswift5.0対応しました

#GitHub

つくったものはここ
[AMBurnAnimation](https://github.com/adventam10/AMBurnAnimation)

#見た目
![burn2](https://user-images.githubusercontent.com/34936885/42418447-9ac241c8-82db-11e8-84f1-c3a6fa2eadd1.gif)

#機能
* 指定のUIViewを燃やすアニメーションが設定できる（下から上のみ）
* アニメーション時間が設定できる
* アニメーション終了時の処理が設定できる

#使い方
1. プロジェクトにextension追加
	
	gitからファイルをダウンロードしてプロジェクトにUIView+BurnAnimationフォルダのファイルを追加する

2. 指定のViewで下記のアニメーション設定メソッドを呼ぶ

```swift
targetView.burnAnimation(duration: 3.0,
                         completion: nil)

```
上記の例では3秒かけてtargetViewを燃やすアニメーションを設定している。	

#仕組み	
このクラスの仕組みについて少し説明しておきます。
下記のような仕組みでアニメーションを設定しています。

1. 対象のViewのキャプチャを作成する
2. CAEmitterLayerを使って炎を出す
3. 対象のViewのisHiddenをtrueにして非表示にする
4. キャプチャしたViewとCAEmitterLayerにアニメーションを設定する
5. アニメーション終了時に対象のViewのisHiddenをfalseにして表示する

炎の表示は[UIKit上でパーティクルエフェクトを表示する - Over&Out その後](http://d.hatena.ne.jp/shu223/20130315/1363298992)を参考にさせていただきました。

#さいごに
炎の表示は画像の作成を頑張れば（煙を出すとか炎の形を変えるとか）もっとカッコ良くなるような気がします。

特に使い道は考えていませんが、現実では燃やせない書類を燃やしてみるとかしてスカッとするとかどっかで使える気がしなくもないです・・・（ビューアアプリでファイル削除時に使うとか？）
![burn](https://user-images.githubusercontent.com/34936885/42418170-a7d0e802-82d5-11e8-8fe7-398935da3b33.gif)

私はほぼObjective-Cしか使ったことがないペーペーのプログラマーなので記事内容やgithubのコードにおかしなところがあればご指摘いただければ幸いです。

#つくったのまとめ
* [アナログ時計を描画してみた（swift）](https://qiita.com/am10/items/0222e6966d58062d2eca)
* [スピードメーターをつくってみた（swift）](https://qiita.com/am10/items/0fe8cffac7dd7659eb2a)
* [めくるカレンダーをつくってみた(swift)](https://qiita.com/am10/items/2a929ca8196f33cb1d4a)
* [グラフを描画してみた(swift)](https://qiita.com/am10/items/aee964a8a7a9712d66f8#_reference-ca2e5485de5acf8eca97)
* [ちからわざで日本地図を描いてみた(swift)](https://qiita.com/am10/items/26de3242ee33b4bd4aae)
* [カラーピッカーをつくってみた(swift)](https://qiita.com/am10/items/82a4adb2267979841c9e)
* [面積比がそれっぽいベン図を描いてみた(swift)](https://qiita.com/am10/items/858041f70be4d8de5090)
* [UIViewを燃やしてみた（swift）](https://qiita.com/am10/items/f7b32ea5725feeb1469f)

##動作確認用にまとめたプロジェクト
* [Carthageで入れたやつ](https://github.com/adventam10/TestCarthage)
* [CocoaPodsで入れたやつ](https://github.com/adventam10/TestCocoaPods)
TRUNCATEとDBMS間の違い

## TRANCATE とは
基本的にテーブルを削除するときは、`DELETE TABLE`を利用しますね。

```sql
delete from [テーブル名];
```

上記のクエリは**rollbackログ**を残す必要があるので、
対処のレコードが何百万、何千万になってしまうと、
レートデプレッションされたり、ランタイムエラーされたりします。
大容量の時**危険**なところですね。

その時のため、サポートしているクエリで `TRUNCATE`があります。

[PostgreSQL 8.4.4文書](https://www.postgresql.jp/document/8.4/html/sql-truncate.html)
`TRUNCATEはテーブル群から全ての行を素早く削除します。 各テーブルに対して条件指定のないDELETEコマンドの実行と同じ効果を持ちますが、実際にテーブルを走査しない分、このコマンドの方が高速です。 さらに、その後にVACUUM操作を行うことなく、このコマンドはディスク領域を即座に回収します。 このコマンドは、大きなテーブルを対象とする場合に最も有用です。
`

## 利用方法

```sql
TRUNCATE TABLE [テーブル名];
```
```php
// for CakePHP2
$this->query('TRUNCATE ' . $this->table . ';');
```

## **TRANCATE TABLE** と **DELETE TABLE** との違い

**TRUNCATE TABLE** と**DELETE TABLE**の違いは次の通りです。

・**TRUNCATE TABLE**はDML(Data Manupulation Language) ではなく、DDL(Data Definition Language)です。 そのため、DELETEとは別にトランザクション内に入れてもROLLBACKできません。

・**TRUNCATE TABLE**はAUTO_INCREMENT値も初期化されます。

・**TRUNCATE TABLE**はWHERE条件を利用できません。 単純にテーブルをスキーマだけ残してそのまま丸ごと空けます。

・**TRUNCATE TABLE**は個別レコードの削除に対してロギングせずに全てのレコードをテーブルから削除します。 なので、システムログ及びトランザクションログのリソースをより少なく利用して、もっとクエリが早いです。

## PostgreSQLは TRUNCATEもちゃんとトランザクションでROLLBACKできます。

OracleとMySQLとは違いに、PostgreSQLはTRUNCATEもちゃんとトランザクションでROLLBACKできます。
面白いのは、他のDDL(CREATE TABLEなど）もトランザクションが聞きます。

原理的な理由はまだ把握してませんが、DBMS間の こんな差は 注意が必要です！
[PostgreSQL 8.4.4文書](https://www.postgresql.jp/document/8.4/html/sql-truncate.html)
`テーブル内のデータという観点では、TRUNCATEはトランザクション的に安全です。 前後のトランザクションがコミットされなければ消去は安全にロールバックされます。`

👏
GitHub Edicationを使ってみる

課題プログラミングの制作や提出などの作業を通して、より実践的な実習環境で学ぶことを目的に、GitHub Educationを試用しています。

#GitHub Education
##公式サイト
GitHub Education
https://education.github.com/

##参考記事
###学生としての登録
GitHub Educationに登録
https://qiita.com/jellyfish21/items/1052a21a28cef82bd54e

今回は、先生１名がまず登録して学生数分の非公開リポジトリを作成しま。それをGitHubのアカウントに登録した学生が利用するは形でとりあえず運用することを考えました。

今回は諸事情ありこのような形にしましたが、できれば学生自身もGitHub Educationに登録すると、より多くのサービスが無償で受けられ望ましいと思われます。

##ローカル環境概要
過去記事：GitHub事始め
https://qiita.com/takako_sudou/items/52ddd588eb5516a9ff15
メモ書きですが簡単に環境をまとめてあります。

##感想
###Gitについて
バージョン管理は、一度慣れてしまえば非常に便利なツールだと思います。ただ、初めて使う人には聞きなれない単語や機能（フォーク、クローン、プル、プッシュ、リポジトリ、プロジェクト等々）が多いのも事実です。
特にクラス内で一斉に導入する場合は、最初はなるべく必要最低限の機能から始め、徐々に多くの機能を活用していくのが良いのではと思います。
###GitHubについて
クラウド上でソース管理ができるため、課題を最終定期に提出するためだけでなく、学生同士の共同プロジェクトの管理や、課題データのバックアップとしてなど、様々な活用やメリットが考えられます。
私自身がまだ機能の一部しか把握していないため、今回の試験運用を通してより理解し、授業での活用により望ましいやり方を探っていきたいと思います。
iPhone単体で動画をダウンロードする【pythonista】

1200円払えばios上で**無料**でPythonが使える[pythonista](https://itunes.apple.com/jp/app/pythonista-3/id1085978097?mt=8)というアプリがあります。標準モジュールとしてmatplotlibやnumpyが初めから入っているので、出先の暇つぶしには最適なアプリです。

今回はpythonistaと強力な動画ダウンローダーである[「youtube-dl](https://github.com/rg3/youtube-dl)」を使用してiPhone単体で動画のダウンロードをしていきます。shellコマンドで実行するのが基本的な使い方ですが、Pythonでモジュールとしてプログラムに組み込みこむという日本語の記事が無かったのでかいてみました。

youtube-dlはCUIで動くダウンローダーです。youtube以外にも多数の動画サイトに対応しています。[対応サイト](https://rg3.github.io/youtube-dl/supportedsites.html)

##はじめに
デフォルトの状態では外部モジュールをインストールすることができないので、pythonistaのコンソール画面（エディター画面を右にスワイプ）で以下のコードを実行して「StaSh」と呼ばれるpythonista専用のシェルを導入します。

```Python
import requests as r; exec(r.get('http://bit.ly/get-stash').text)
```
コンソール画面に再起動を促される文字列が表示されたら、アプリの再起動を行ってください。「launch_stash.py」というファイルが追加されていたら成功です。これを実行するとシェルが起動し、pipコマンドが使用できるようになります。外部モジュールをインストールする際はこちらを毎回起動する必要があります。

youtube-dlをインストールしていきましょう。StaShを起動して以下を実行します。

```
pip install youtube_dl #インストールする際は「-」ではなく「_」にする
```

##コード
早速組み込んでいきます。インストールしたyoutube-dlをインポートします。
作者様の[コード](https://github.com/rg3/youtube-dl)をすこし改変して引用しました。

```Python
import youtube_dl

ydl_opts = {}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])
```
オプション設定は何も記述しなくても動きますが、代表的なオプションとしてファイルネームの指定とフォーマットの指定（mp4/m4a）を紹介しておきます。[その他のオプション](https://github.com/rg3/youtube-dl/blob/054b99a33079dcc4755e46aaf588424b4bb12020/youtube_dl/YoutubeDL.py#L139)はAvailable options(117行〜265行目)を参考。


```Python
#mp4（動画ファイルの場合）
ydl_opts = {
  'outtmpl':fileName + '.mp4',
  'format':'bestvideo[ext=mp4]'
}

#m4a（音声ファイルの場合）
ydl_opts = {
  'outtmpl':fileName + '.m4a',
  'format':'bestaudio[ext=m4a]'
}
```
変数fileNameに適当な文字を入れてダウンロードします。outtmplを記述しない場合は動画のタイトルになります。

そのまま保存するとファイルがごちゃごちゃになってしますので、新しくフォルダ（yD_musicとyD_video）を作成しました。

<img width="375" alt="Photo_2018-07-08_13_51_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/213579/a25daeae-e38d-d590-1ce2-3aac81f4687c.png">

ダウンロードしたm4aファイルはyD_music。mp4ファイルはyD_videoに振り分けて保存できるようにします。

カレントディレクトリーを調べるために以下のコードをpythonistaのコンソール画面で実行します。

```Python
import os; os.getcwd()

#出力
'/private 〜 /Documents'
```
上記の出力の後ろに新しく作成したフォルダ名を付け足しておきます。

##全体像

```python
import youtube_dl,os

def dl(form,url):
	
	if form == 'm':
		path = 'yD_music'
		form = 'bestaudio[ext=m4a]'
		
	elif form == 'v':
		path = 'yD_video'
		form = 'bestvideo[ext=mp4]'
		
	os.chdir('your_path' + path)
	
	ydl_opts = {'format':form}
	with youtube_dl.YoutubeDL(ydl_opts) as ydl:
		ydl.download([url])
		
		
form = input('format > ')
url = input('url > ')
dl(form,url)
```
※your_path部分にgetcwdで取得したpathを記述

##操作
Twitterに上げた動画を参照してください。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">youtube-dl on pythonista <a href="https://t.co/dgU1adLY4U">pic.twitter.com/dgU1adLY4U</a></p>&mdash; メモ帳【☁️】 (@qxi_) <a href="https://twitter.com/qxi_/status/1015843086113468416?ref_src=twsrc%5Etfw">2018年7月8日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Composer入りDockerImage作成時スピードアップのためのTips


CircleCIの実行時間を短くするために、DockerImageの作成を行ったのですが、
どうせなら `composer install` も早くしたいと思って `@Hiraku`さんのプラグイン等を導入しています。

数十秒程度改善される場合もあるのでおすすめです。
なお、Laravelだと依存関係のパッケージが多いため10倍くらい早くなるらしいです。

以下、Dockerfileです。
[mshimao/php7.1-apache-postgres-composer-php-extensions](https://hub.docker.com/r/mshimao/php7.1-apache-postgres-composer-php-extensions/)で公開してます。

```
FROM php:7.1-apache

RUN \
  apt-get update \
  && apt-get -y install git unzip zlib1g-dev libpq-dev libicu-dev libpng12-0 libpng-dev \
      postgresql netcat

# extensions install
RUN \
  docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
  && docker-php-ext-install pdo pgsql pdo_pgsql zip intl gd mbstring

# composer install 
RUN \
  curl -sS https://getcomposer.org/installer | php \
  && mv composer.phar /usr/local/bin/composer

# make composer fast in japan
RUN  composer config -g repositories.packagist composer https://packagist.jp && \
    composer global require hirak/prestissimo

ENV LANG ja_JP.UTF-8
```

以下でcomposerの参照先を[packagist.jp](http://packagist.jp/)に変更しています。
```
composer config -g repositories.packagist composer https://packagist.jp
```

以下でcomposerを並列処理にする[hirak/prestissimo](http://blog.tojiru.net/article/432944706.html)を入れてます。
```
composer global require hirak/prestissimo
```

## おまけ1

Dockerhubへのpushは以下の3コマンドで終わるのでカンタンです

```
docker login
docker build -t username/hoge ./
docker push username/hoge
```

## おまけ2

Ansibleも作ったので貼ります。

```
---
# install composer
- name: check composer
  stat: path=/usr/local/bin/composer
  register: composer_bin
  tags: composer

- block:
  - name: download composer
    get_url:
      url: https://getcomposer.org/installer
      dest: /tmp/installer

  - name: install composer
    shell: cat /tmp/installer | php -- --install-dir=/usr/local/bin

  - name: rename composer.phar to composer
    shell: mv /usr/local/bin/composer.phar /usr/local/bin/composer

  - name: make composer executable
    file:
      path: /usr/local/bin/composer
      mode: a+x
      state: file

  - name: composer speed up(1/2)
    shell: /usr/local/bin/composer config -g repositories.packagist composer https://packagist.jp

  - name: composer speed up(2/2)
    shell: /usr/local/bin/composer global require hirak/prestissimo

  when: not composer_bin.stat.exists
  tags: composer
```
GKE で k8s クラスタ を消す時の ちょっとした注意点

GKE でのk8s クラスタの管理において、`Cloud Shell` 経由の操作と、ローカルPCからgcloud コマンドライン ツール での操作を混ぜると、context にゴミが残るというお話。

（もしかしたらcontext の情報をうまい具合にポーリング的に再読込させる？回避策があるかもしれないので、知っている人がいれば教えていただけるとめっちゃ嬉しいです。）

## 対象読者
* GCP ちょっとワカル
* k8s ちょっとワカル

※ 本当にちょっとワカルくらいの人を対象にしています。めっちゃワカル人は、間違いなどあればご指摘いただけるとうれしいです。

## `Cloud Shell`を知らない人へ
GCP には、`Cloud Shell`という仕組みがあり、ローカルPCからGCPをいじる環境がなくても、GCPのブラウザ画面から、GCPをいじいじできます。

https://cloud.google.com/shell/docs/features

## さっそくExample

ここに、ローカルPCからgcloud コマンドライン ツールでつくったk8sクラスタがあるじゃろ。

```
$ gcloud container clusters list
NAME      LOCATION       MASTER_VERSION  MASTER_IP        MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
nginxk8s  us-central1-a  1.9.7-gke.3     XXX.XXX.XXX.XXX  n1-standard-1  1.9.7-gke.3   3          RUNNING
```

```
$ kubectl get services
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
kubernetes   ClusterIP      10.XXX.XXX.XXX  <none>           443/TCP        2m
nginx        LoadBalancer   10.XXX.XXX.XXX  XXX.XXX.XXX.XXX  80:31152/TCP   4s
```

そのクラスタを、`Cloud Shell` からこうじゃ！！（クラスタ削除）

```
$ gcloud container clusters delete nginxk8s --zone us-central1-a
```

## オチ

で、ローカルPCから、context を確認すると、さっき`Cloud Shell`で消したクラスタのcontextが、以下のようにゴミとして残る。

```
$ kubectl config get-contexts
CURRENT   NAME                                CLUSTER                             AUTHINFO                            NAMESPACE
*         gke_XXXXXX_us-central1-a_nginxk8s   gke_XXXXXX_us-central1-a_nginxk8s   gke_XXXXXX_us-central1-a_nginxk8s   
          minikube                            minikube                            minikube                       
```

## ゴミそうじ

```
$ kubectl config delete-context gke_XXXXXX_us-central1-a_nginxk8s
```

おわり。
忘れた時のpythonでsyslog出力

#忘れた時のpythonでsyslog出力

pythonにも色々なログ出力のライブラリがありますが、監視システムの側としてはsyslogで出力してもらえると大変助かる!とのことで今回調べてます!!

よく自分が忘れるので、自分が使うようのメモとして書いてます。
環境:python2.x and python3.x

##インストール(https://pypi.org/project/syslog-rfc5424-parser/)

```
pip install syslog-rfc5424-parser
```



##出力設定

```
# coding: utf-8
import syslog
//出力設定
syslog.openlog(<アプリケーション名>,<ログオプション>,<ログファシリティ>)
例1) syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_MAIL)
例2) syslog.openlog('testprog',syslog.LOG_PID|syslog.LOG_PERROR,syslog.LOG_SYSLOG)

//ログ出力
syslog.syslog(<ログレベル>,<出力メッセージ内容>)
例1) syslog.syslog(syslog.LOG_ALERT,'TEST MESSAGE')
例2) syslog.syslog(syslog.LOG_ERR,'TEST MESSAGE')
例3) syslog.syslog(syslog.LOG_INFO,'TEST MESSAGE')

//ログを出力するファイルを閉じる
syslog.closelog()

```
<ログオプション>
LOG_PID
LOG_CONS
LOG_NDELAY


<ログファシリティ一覧>
LOG_KERN
LOG_USER
LOG_MAIL
LOG_DAEMON
LOG_AUTH
LOG_LPR
LOG_NEWS
LOG_UUCP
LOG_CRON
LOG_SYSLOG
LOG_LOCAL0 ~ LOG_LOCAL7


<ログレベル一覧>
LOG_EMERG
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
オフラインどう書くE25の問題

問題はこちら->https://mtsmfm.github.io/2018/07/07/doukaku-e25.html

90度回転移動の公式を使って解きました。
普通に解くと計算量の爆発があるとかの落とし穴があるのかとも思いましたが、
そういうこともありませんでした。
forループのネストを使いますのでJuliaで書きました。
問題に括弧がありましたので入出力が大変でした。
正規表現を使うのが良いのかもしれませんが、あまり使ったことがありませんし、
特にJuliaのそれはよくわかりません。

```Julia
str="0	4,7,(0,3)	(0,0),(3,0),(3,6)
1	4,6,(3,3)	(2,5),(0,4),(2,0)
2	1,1,(0,0)	-
3	2,2,(0,0)	-
4	2,3,(0,0)	-
5	2,3,(0,1)	(0,0),(1,0),(1,2)
6	2,3,(1,1)	(1,2),(0,2),(0,0)
7	2,3,(1,2)	-
8	3,4,(1,2)	-
9	4,3,(2,2)	(1,2),(1,1),(3,1)
10	7,7,(2,5)	(0,3),(2,1),(6,5)
11	8,7,(1,1)	(3,0),(4,2),(0,4)
12	9,7,(3,6)	(0,4),(2,1),(8,5)
13	10,7,(6,6)	(3,6),(3,3),(9,3)
14	10,11,(4,2)	(8,1),(9,5),(1,7)
15	10,12,(0,3)	(3,0),(6,3),(0,9)
16	10,13,(0,0)	-
17	10,14,(4,3)	(8,2),(9,6),(1,8)
18	15,15,(2,1)	(5,0),(6,3),(0,5)
19	16,17,(14,13)	(10,16),(7,12),(15,6)
20	19,7,(18,0)	-
21	20,7,(1,4)	(0,1),(3,0),(5,6)
22	25,11,(15,1)	(24,1),(24,10),(6,10)
23	26,12,(12,8)	(4,8),(4,0),(20,0)
24	27,13,(14,2)	(24,2),(24,12),(4,12)
25	28,14,(6,6)	-
26	30,30,(25,17)	(20,29),(8,24),(18,0)
27	35,36,(32,3)	(34,8),(29,10),(25,0)
28	150,130,(50,113)	(8,56),(65,14),(149,128)
29	180,120,(120,18)	-
30	200,200,(24,134)	(0,45),(89,21),(137,199)"

function solve(w,h,x,y,ans)
    function cal(w,h,x,y)
        for i in 1:w
            for j in 1:h
                dx=i-x
                dy=j-y
                x1=i-dy
                y1=j+dx
                if x1>0 && y1>0 && x1<w+1 && y1<h+1
                    x2=x1-2*dx
                    y2=y1-2*dy
                    if x2>0 && y2>0 && x2<w+1 && y2<h+1
                       dis=dx^2+dy^2
                       if dis>len
                           len=dis
                           kaz=1
                           pos=(i-1,j-1,x1-1,y1-1,x2-1,y2-1)
                       elseif dis==len
                           kaz=2
                       end
                   end
               end           
           end
        end
    end    
    len=0
    kaz=0
    pos=(0,0,0,0,0,0)
    cal(w,h,x+1,y+1)
    if kaz==1
       s="("*string(pos[1])*","*string(pos[2])*")"*","*"("*string(pos[3])*
       ","*string(pos[4])*")"*","*"("*string(pos[5])*","*string(pos[6])*")"
    else
        s="-"
    end          
    if s==ans 
       print("ok ")
   else
       print("no" )
    end
    println(s) 
end  

str0=split(str,"\n")
for s0 in str0
  s1=split(s0,"\t")
  s2=split(s1[2],",")
 solve(parse(Int,s2[1]),parse(Int,s2[2]),parse(Int,s2[3][2:end]),
        parse(Int,s2[4][1:end-1]),s1[3])
end
```
数式とPython式の対応関係をまとめてみた

# はじめに
Wikipediaの[数学記号の表](https://ja.wikipedia.org/wiki/数学記号の表)の一部をPython式で表現してみました。
標準ライブラリのみ用いて表現しています。
数式はよくわからんけど、Python式なら分かるって人もどうぞ。

## 記号論理
数式における $X$, $Y$ は命題、 $A$ は集合、 $P$ は述語を、
Python式における $X$, $Y$ は `bool` 型の値、 $A$ は iterable なオブジェクト、 $P$ は `bool` 型の値を返す関数を表すとします。

|意味|数式|Python式|
|---|---|---|
|論理積| $X \land Y$ | `X and Y` |
|論理和| $X \lor Y$ | `X or Y` |
|論理否定| $\lnot X$ | `not X` |
|論理包含| $X \Rightarrow Y$ | `not X or Y` |
|全称限量記号| $\forall a \in A, P(a)$| `all(P(a) for a in A)` |
|存在限量記号| $\exists a \in A, P(a)$| `any(P(a) for a in A)` |

`all`, `any` は組み込み関数で、結構便利です。

## 集合論
数式における $A$, $B$ は集合を、 $P$ は述語を、
Python式における $A$, $B$ は `frozenset` 型の値、 $P$ は `bool` 型の値を返す関数とします。
**注意**

* Markdownのテーブル記法と衝突するため、 `|` を `｜` で表現しています。
* `product`, `chain.from_iterable`, `combinations` は [itertools](https://docs.python.jp/3/library/itertools.html) で定義されている関数です。

|意味|数式|Python式|
|---|---|---|
|内包表記| $\\{a \mid a \in A, P(a) \\}$ | `frozenset(a for a in A if P(a))` |
|元である| $a \in A$ | `a in A` |
|元でない| $a \notin A$ | `a not in A` |
|部分集合| $A \subseteq B$ | `A <= B` |
|真部分集合| $A \subset B$ | `A < B` |
|積集合| $A \cap B$ | `A & B` |
|和集合| $A \cup B$ | `A ｜ B` |
|差集合| $A \setminus B$ | `A - B` |
|べき集合| $2^{A}$ | `frozenset(frozenset(s for s in S if s) for S in product(*((None, a) for a in A)))` |
|直積集合| $A \times B$ | `frozenset(product(A, B))` |
|最大値| $\max{A}$ | `max(A)`|
|最小値| $\min{A}$ | `min(A)`|
|濃度| $ \mid A \mid$ | `len(A)` |

べき集合を扱うことはほとんどないと思いますが、Python式で表現しようとするとしんどいですね。
`product` は `frozenset` に限らず `iterable` なオブジェクトにも適用可能なので、結構使えます。

## 定数
`pi`, `e` は [math](https://docs.python.jp/3/library/math.html) で定義されている値です。

|意味|数式|Python式|
|---|---|---|
|0| $0$ | $0$ |
|1| $1$ | $1$ |
|円周率| $\pi$ | `pi` |
|ネイピア数| $e$ | `e` |
|虚数単位| $i$ | `1j` |

Pythonでは、複素数を `4+2j` のように表せます。

## 代数学
数式における $n$ は自然数、 $A$ は集合, $f$ は $\mathbb{N} \rightarrow \mathbb{R}$ なる写像, $g$ は $A \rightarrow \mathbb{R}$ なる写像、
$m$ は非負の整数、 $x$, $y$ は実数、 $z$ は複素数、 
Python式における `n` は1以上の `int` 型の値、 $A$ はiterableなオブジェクト、 `f`, `g` は `float` 型の値を返す関数、 `m` は0以上の `int` 型の値、 `x`, `y` は `float` 型の値、 `z` は `complex` 型の値を表すとします。
**注意**

* `reduce` は [functools](https://docs.python.jp/3/library/functools.html) で定義されている関数です。
* `mul` は [operator](https://docs.python.jp/3/library/operator.html) で定義されている関数です。
* `factorial`, `ceil`, `floor` は [math](https://docs.python.jp/3/library/math.html) で定義されている関数です。

|意味|数式|Python式|
|---|---|---|
|総和| $\sum_{i=1}^{n} f(i)$ | `sum(f(i) for i in range(1, n + 1))` |
|総和| $\sum_{a \in A} g(a)$ | `sum(g(a) for a in A)` |
|総乗| $\prod_{i=1}^{n} f(i)$ | `reduce(mul, (f(i) for i in range(1, n + 1)))` |
|総乗| $\prod_{a \in A} g(a)$ | `reduce(mul, (g(a) for x in A))` |
|階乗| $m!$ | `factorial(m)` |
|天井関数| $\lceil x \rceil $ | `ceil(x)` |
|床関数| $\lfloor x \rfloor $ | `floor(x)` |
|絶対値| $\mid x \mid $| `abs(x)`|
|実部| $\Re{z}$ | `z.real` |
|虚部| $\Im{z}$ | `z.imag` |
|指数| $x^y$ | `x**y` |
|冪根| $\sqrt[m]{x}$ | `x**(1/m)` |

`reduce(二項演算子, iterableなオブジェクト)`　は総乗に限らず、二項演算を繰り返し適用する際に便利です。

## おわりに
標準ライブラリだけでも、多くの数式をきれいなPython式で表現できますね。
Git でサブコマンドを補完しようとしたときに Unknown option: --list-cmds と表示される問題の解決法

# 症状
本日新しい MacBook Pro が届き、早速、環境構築をしていたのですが、[git-completion](https://github.com/git/git/tree/master/contrib/completion) を導入したところ、Git の補完でエラーが発生してしまいました。

```bash
$ git com  # <- ここでタブキーを押して git commit を補完しようとしたら下記のようなエラーが発生
Unknown option: --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
```

# 原因
エラーの内容をコピペしてググったら以下の記事が一番最初に出てきました。

[.git-completion.bash producing error on macOS Sierra 10.12.6](https://apple.stackexchange.com/questions/327817/git-completion-bash-producing-error-on-macos-sierra-10-12-6)

アンサーを見てみると、どうやら Git 2.18 から新しく `--list-cmds` というオプションが追加されたようで、それが `git` コマンド側で認識されていないためにこのような原因が起こるようです。

このような問題が起きてしまった理由としては、ぼくの場合は、`git` コマンドを使用する際の Git (`/usr/bin/git`) と git-completion を使用する Git (`/usr/local/git`) が異なっていて、それぞれで別のバージョンを使用してしまったためでした。`git` コマンドを使用する Git のバージョンは 2.15.1 で、git-completion を使用する Git のバージョンが 2.18 だったので、2.18 で追加された新オプションを `git` コマンドを使用するほうの Git が認識していなかったためです。

# 解決策
原因がわかったらやることはシンプルで、単純に Git のバージョンをそろえてあげれば OK です。今回はとりあえず git-completion に新オプションが追加される前の v2.17.1 にダウングレードすればよさそうなので、v2.17.1 にチェックアウトしてみます。

```bash
$ cd /usr/local/git     # git-completion をクローンしたパスに置き換えてください
$ git checkout v2.17.1  # 補完はまだ効かないので注意！
```

チェックアウトしたらシェルを再起動します。

`git com` などと入力したあとにタブキーで補完して、エラーが出ずに `git commit` が補完されたら問題ないと思います。お疲れ様でした。