OmniAICreator/Qiita-1.07M huggingface dataset:
社員のお弁当の注文を取りまとめて、FAX 送信する LINE WORKS ボット #3

以下の URL の記事の続きです。
https://qiita.com/iwaohig/items/d66a0c2c1663122f9f84
https://qiita.com/iwaohig/items/ac0f13eb657ea312109c

注文書を作成して、お弁当屋さんに FAX 送信します。

##注文書 Excel ファイル生成

Microsoft Flow で [スケジュール] をトリガーに指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/4231bc04-e4ad-dd07-162a-30a83369368c.png)

スクリーンショットのように発注する日時を指定します。ここでは平日の 18 時に発注処理を行う想定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/5d9e299f-7afc-8036-0ec8-2710eddfa496.png)

注文受付用の Excel の集計テーブルの値を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/0e91fda1-dcce-714f-de8a-905d4e25246a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/2aaf2f32-00bf-5a28-5bb0-b9eb33e72e3b.png)

注文書フォーマットの Excel ファイルを別途、OneDrive for Business 上に作成しています。書式は任意のもので良いです。送付先のお弁当屋さんの指定があれば、それに合わせたものを作りましょう。

注文書上の数量の記載箇所に、先ほど取得した発注数量を反映します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/a4287dac-5382-036d-6591-a9521a09d422.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/8467f2a1-3168-eb36-36ff-87b1002c6263.png)
##Twilio で Fax 送信

発注先のお弁当屋さんの注文方法が電話か FAX というのはありがちかと思います。
ここでは Twilio の API で FAX 送信します。

こちらの記事も参照してください。

TITLE: Dropbox にPDF ファイルがアップロードされたら Twilio で FAX 送信
URL: https://qiita.com/iwaohig/items/b46834d60015249e9358

Twilio の API で FAX 送信できるファイルは PDF です。また、URL でアクセスできる場所に置く必要があります。

OneDrive for Business 上の Excel ファイルを直接送ることができません。
このため、Excel ファイルを PDF に変換し、Web サーバーに FTP 転送した後に Twilio の API を実行します。ちょっと、まどろっこしいですね。。

手順は以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/0747c911-c08c-cd57-c81f-648cc2944e8f.png)
PDF に変換を行い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/872c8ece-2bf3-a135-4b54-c7bd2866605b.png)
変換したファイルを格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/e78e503a-0e4e-ffee-42a2-d3b1aab7ed64.png)
Web サーバーに FTP 転送
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/bcdc934c-05e4-e440-532b-d10e03400466.png)
Twilio API 用 AzureAutomation を実行

AzureAutomation の Runbook は次のように記述しています。
PowerShell の Invoke-RestMethod コマンドレットで Twilio の API を実行します。

```
Param
(
  [Parameter (Mandatory= $true)]
  [string] $filename
)

$USER = <Twilio の アカウントSID>
$PASS = <Twilio の AUTHTOKEN>
$secpasswd = ConvertTo-SecureString $PASS -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($USER, $secpasswd)

Invoke-RestMethod -Uri "https://fax.twilio.com/v1/Faxes/" -Credential $cred -Method POST -Body @{To=<宛先番号>; From=<Twilio で取得した番号>; MediaUrl="http://example.com/$filename"}

```
## 注文のとりまとめと発注完了

- お弁当屋さんの Tweet をトリガーに、社員にメニュー通知
- 社員は Bot への応答で注文
- スケジュールに基づき注文集計
- 注文書の FAX 送付

の仕組みができました。
必要に応じて、発注完了の通知を発注者や担当者に送ってもいいと思います。
【Brackets :エラー解決】PHPランタイムが見つかりません。PHPランタイムを設定して.....



#エラー
PHPの学習を始めようと思い、サンプルコードを打ちながら進めていました。
エディタは[Bracket](http://brackets.io/)を使用しているのですが、PHPのコードを書こうと思ったら以下のエラーがでてきました。
👇
![aaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266096/deb03908-2fa4-db14-337d-043d5055e7db.png)


#解決
PHPのアプリケーションのフォルダパスを探して、自分の場合は以下のpath👇
`C:\\MAMP\\bin\\php\\php7.2.10\\php.exe`

あとは、以下のコードを　`brackets.json`ファイルに貼る。


```php

 "php": {
        "enablePhpTooling": true,
	"executablePath": "自分のPHPアプリのpath",
	"memoryLimit": "4095M",
	"validateOnType": "false" 
    }
```

解決！！！


#注意点

●上のコードを貼る際に、
　　✖　`defaultPreferences.json` ではなく、
　　:qiitan:　`brackets.json`（画像の青い部分）

●JSONファイルでは Key-Value的に書くので、**もともとのかっこ{}の中に`"php:{}"`を入れる**（画像青い部分を確認）


<img width="960" alt="2019-06-23 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266096/72769c42-7083-1f61-79ed-59045687f9be.png">
【便利すぎる】Bootstrapの一歩目

#フレームワークとは
フレームワークとはプログラミングの雛形を作ることで開発しやすくなるツールです。
代表的なものをあげますと

- Ruby ー Ruby on Rails
- PHP ー CakePHP
- Java ー Spring Framework
- JavaScript ー AngularJS
- Python ー Django
- CSS ー Bootstrap

このようにほとんどの言語はフレームワークを持っています。決して１つだけではないので気になった方は調べてみてください。

##Bootstrap とは
BootstrapはCSSの代表的なフレームワーク
私の印象ですとレスポンシブデザインが非常に使いやすそうで、WEBページを閲覧する端末の幅に合わせて柔軟に対応してくれます。
##レスポンスWEBデザイン
イメージしにくいと思いますので今見ているQiitaのページ幅を変えてみるとわかるかもしれません。
当たり前すぎて「は？」ってなる方はゴリゴリのZ世代ですね。

レスポンスがないページを探したのですが、モバイルフレンドリーではないのでGoogleの検索結果に基本的には出てきませんでした。
もし簡易的なページを自作した方ならイメージできると思います。できれば例としてURLをコメントしてください笑


##導入方法
Bootstrapの導入方法は公式的に３つあります。
-Installation
-BootstrapCDN
-Official Themes

この３つを簡単に説明します。
###Installation
ソースをダウンロードしてローカルで読み込む方法です。公式は全て英語で書かれているので[こちら](https://techacademy.jp/magazine/6270)を参考にしていただくといいかと

###BootstrapCDN
こちらはheadタグにリンクとしてコピペすることですぐに使えるようになります。

```html

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
```
こちらが[公式](https://getbootstrap.com/docs/4.3/getting-started/introduction/#css)が出しているリンクですのですぐに使えます。

### Official Themes
これは公式が販売しているテーマを買えってことですね。もちろん有料ですので見るだけでも十分だと思います。今風なデザインがたくさんみられるのでイメージとして[こちら](https://themes.getbootstrap.com/)からどうぞ

また無料で配布しているクオリティの高いテーマもたくさんありますのでググってみてください。質が高すぎて自分でデザインのコードを書くきにはなれないですね。

#終わりに
知れば知るほど、世の中がどれほど便利になっているか驚かされます。あまりにも素晴らしいので思考停止コピペ生活に陥りそうですね。
今回はBootstrapの紹介になってしまいましたが、これから触っていきますので、そのアウトプットも随時していきます。
プログラミング初学者なので間違った情報を発信してるかもしれません。もし見つけた方はどんどん指摘してください。
IoT初心者向け mosquittoでPub/Sub通信やってみた

ハロー！IoT 1年生　ひつじです。

前回はIoTの基礎用語について記載させて頂きました。

今回は実際にそれぞれの役割がどういう風に動くのか、オープンソースのmosquittoをインストールして
OS上での挙動を見てみましょう。

#mosquittoとは

Eclipse Foundationが展開してMessageBrokerのオープンソース(EPL/EDL licensed)です。
モスキートと発音するようですが、蚊の英語表記とはすこし表記が違います。

<img width="434" alt="i13.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/f455cb66-a9e1-d452-e8c9-91c187b769db.png">


前回の記事では、BrokerとはPublisherとSubscriberを仲介する役割としてお話したかと思います。

![i6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/0a467abb-4302-4d2f-f47a-779ae37e3ba7.jpeg)


また、mosquittoにはBrokerだけでなくPublisherとSubscriberとしての機能をもつmosquitto clientもあります。

**mosquitto      → Brokerとして動くよ
mosquitto client　→　Pub/Sub通信を提供するよ**

今回はこのソフトウェアつかって、MQTTによる通信をやってみたいと思います。

#mosquitto インストール

```
wget http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo -O "/etc/yum.repos.d/Mosquitto.repo"
yum install mosquitto mosquitto-clients
```

これですんなりインスコできればいいのですが、僕の環境だとconflictしてしまいました。
なので、必要であればepelなど競合するレポジトリを無効化(enable=0)して再トライしてみてください。



```
#epel enable=0のやり方
grep enable /etc/yum.repos.d/epel.repo
enabled=0
```

```
#repo指定してインストール
yum --enablerepo=home_oojah_mqtt  install mosquitto
yum --enablerepo=home_oojah_mqtt  install mosquitto-clients
```

そして最後は起動コマンドを実行しておきましょう。

```
 /etc/init.d/mosquitto start
```

これでインスコ作業は完了です。

#pub/sub通信してみる

まずはターミナルを２つ起動しておきましょう。
片方でSubscriberとして要求をだします。

```
#Subscriberとして要求
mosquitto_sub -d -t /client/abc
```

-t オプションでは、topicを指定しています。
ここでは任意の文字列なら何でもOKです。例では「/client/abc」としています。

次にSubscriberが要求しているTopicに対してPublishしてみましょう。

```
#Publisherとしてデータ送信
mosquitto_pub -d -t /client/abc -m "sheeptest"
```

-mにはペイロード（生のデータ）を記載しており、実際に送信するデータを記載します。今回は「sheeptest」という文字列をおくります。


では、Subscriber側のターミナルで状況を確認してみましょう。

<img width="559" alt="i12.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/fca6cd50-2214-6214-3687-258762117821.png">

ちゃんと受信できていますね。

#まとめ

いかがでしたでしょうか。
実際にmosquittoを使ってMQTTの通信を実施してみました。
なんとなくBrokerやPub/Subのイメージがわいたのではないでしょうか。

こんな流れでしたね。
<img width="481" alt="i11.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/e45dccc7-b088-e832-7d8d-2c6cdb23c7dc.png">

今回は1台のOSの中で通信を行いましたが、次回はいよいよクラウドサービスを使っての通信を試してみたいと思います。

それではご査収ください！
Go言語で書く値渡しとポインタ渡し

# 値渡しと参照(ポインタ)渡し

以前にPHPで値渡しと参照渡しについて書きましたが、同じ話題がGo言語の基礎を学習する際に再び出てきたのでその時に書いたソースコードを備忘録として載せておく記事です

```Go:Person.go
package main

import (
	"fmt"
)

func main() {
	RelativeCopyTest()
}

// 人の情報を表す構造体
type Person struct {
	Name string
	Age  int
}

func RelativeCopyTest() {

	//佐藤さんを定義
	sato := Person{
		Name: "佐藤",
		Age:  20,
	}

	fmt.Println("------------佐藤さんの定義-----------")
	fmt.Printf("佐藤さんの情報：%+v\n", sato) //ここでは、佐藤さんの情報が表示される

	/* -----値渡し---- */
	tanaka := sato //田中さんに佐藤さんのプロフィールをコピーして渡す
	tanaka.Name = "田中"
	tanaka.Age = 30

	fmt.Println("------------値渡し-----------")
	fmt.Printf("佐藤さんの情報：%+v\n", sato)   //佐藤さんの情報は書き変わらない
	fmt.Printf("田中さんの情報：%+v\n", tanaka) //田中さんの情報も表示される
	// NOTE: '%+v'と表記することで、構造体のフィールドと値を綺麗な形で出力してくれる

	/* -----ポインタ渡し----- */
	brian := &sato //Brianに佐藤さんのアドレス情報を渡す
	brian.Name = "ブライアン"
	brian.Age = 100

	fmt.Println("----------ポインタ渡し-------------")
	fmt.Printf("佐藤さんの情報：%+v\n", sato)  //佐藤さんの情報はBrianの情報に書き換わってしまう
	fmt.Printf("佐藤さんの情報：%+v\n", brian) //Brianの情報も保持されたまま
}

```

# 実行結果

```
----------佐藤さんの定義-------------
佐藤さんの情報：{Name:佐藤 Age:20}
----------値渡し-------------
佐藤さんの情報：{Name:佐藤 Age:20}
田中さんの情報：{Name:田中 Age:30}
-----------ポインタ渡し------------
佐藤さんの情報：{Name:ブライアン Age:100}
佐藤さんの情報：&{Name:ブライアン Age:100}
```
Swift エラーハンドリングの基本

# この記事は何？
Swiftプログラミングでのエラー処理について、調べました。
忘備録を兼ねて投稿します。
参考記事: [Swift Language Guide](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html)

## 実行環境
Swift5.x
Xcode11 beta2
macOS 10.14 Mojave

# ハンズオン
エラーを__定義して、スローする__プログラムを記述します。

## こんなクラスがあったとして
自動販売機をコードで表現しています。

````swift:自動販売機のクラス
// 商品の金額と残り個数
struct ItemInfo {
    var price: Int
    var count: Int
}

// 自動販売機
class VendingMachine {
    var inventories = [String: ItemInfo]()  // 在庫の商品
    var coinsDeposited = 0  // 預かり金
    
    // 商品を販売
    func vend(itemNamed name: String) {
        let selectedItem = inventories[name]
        coinsDeposited -= selectedItem.price
        
        var newItem = selectedItem
        newItem.count -= 1
        inventories[name] = newItem   // updating a value
        
        print("Dispensing \(name)")
    }
}
````

## 自販機のインスタンス
自動販売機のインスタンス `drinkStand` を生成して、`"Coke"` を買います。

````swift:自販機インスタンスを生成する
let drinkStand = VendingMachine()

// ドリンクを補填
drinkStand.inventories = [
    "Coke" : ItemInfo(price: 120, count: 7),
    "Soda" : ItemInfo(price: 80, count: 3),
    "Milk" : ItemInfo(price: 100, count: 10)]

// コーラを買う
drinkStand.vend(itemNamed: "Coke")
````


## 起こりうるエラー
この自販機プログラムでは、以下のようなエラーが発生するかもしれません。

- 無効な商品を選択
- 支払額が不足
- 在庫なし

__自販機で起こりうるエラー__ を列挙型を使って、コードで定義します。
このとき、`Error` プロトコルに準拠させておくと、Swiftが自動的にエラーハンドリングの対象にしてくれます。

````swift:エラーの定義
enum VendingMachineError: Error {
    case invalidSelection   // 無効な選択
    case insufficientFunds(coinsNeeded: Int)    // 支払額が不足
    case outOfStock // 在庫なし
}
````

### Error プロトコル
具体的な実装はなく、カラのプロトコルです。
準拠に適合するために、何か特別なことをする必要はありません。

## エラーをthrow(スロー)する
自販機クラス内のエラーが発生しそうな行で、__エラーをスロー__ します。
`throw` キーワードを使います。
どんなエラーが発生したかは、`VendingMachineError` 型を使って指定できます。
この時点で、`vend(itemNamed:)` メソッドはエラーを `throw` するかもしれないメソッドになりました。
メソッド宣言のパラメータ直後に `throws` キーワードを記述します。

````swift:エラーをスローする
class VendingMachine {
    var inventories = [String: ItemInfo]()
    var coinsDeposited = 0
    
    func vend(itemNamed name: String) throws {
        // 無効な商品を選択したら、エラーをスローする
        guard let selectedItem = inventories[name] else {
            throw VendingMachineError.invalidSelection
        }
        coinsDeposited -= selectedItem.price
        
        var newItem = selectedItem
        newItem.count -= 1
        inventories[name] = newItem
        
        print("Dispensing \(name)")
    }
}
````

### エラーをスローする関数の定義
`throw` キーワードと `throws` キーワードは間違いやすいので、気をつける必要があります。

````swift:スロー関数の宣言（例）
// エラーをスローできる関数の宣言 
func canThrowErrorsMethod() throws -> <ReturnType>
 
// エラーをスローしない関数の宣言
func cannotThrowErrorsMethod() -> <ReturnType>
````
JavaScriptとCSSのminifyを行う

## やりたいこと

- JavaScriptやCSSのバンドルはしたくないけど、余計なコメントやデバッグコンソール出力は消したい
- ライセンスコメントは記載したい
- JavaScriptはES6の文法を使いたい(IE11でも使える`const`などを利用したい)
- TypeScriptやSassは使わなくてもminifyはしたいのでソースマップは欲しい

## gulpfile.jsの例

```js
const gulp = require('gulp');
const del = require('del');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const header = require('gulp-header');
const sourcemaps = require('gulp-sourcemaps');
const cleanCSS = require('gulp-clean-css');

// コメントを消した後で再度付与するライセンスコメント. UglifyJSで一部のコメントを残すこともできるが
// 正規表現での記載が必要なので後から付与することとした
const banner = [
  '/** ',
  ' * Library xxx',
  ' * Author: xxx',
  ' * License: xxx',
  ' */',
  ''
].join('\n');

// 出力ディレクトリを一旦削除
gulp.task('clean', function () {
  return del('dest/**', {
    force: true
  });
});

gulp.task('minify-js', function () {
  return gulp.src(['js/*.js'])
    .pipe(sourcemaps.init())
    .pipe(babel({
      presets: ['@babel/preset-env']
    }))
    .pipe(uglify({
      compress: {
        drop_console: true // console出力を削除
      }
    }))
    .pipe(header(banner))
    .pipe(sourcemaps.write('../maps'))
    .pipe(gulp.dest('dest/js/'));
});

gulp.task('minify-css', function () {
  return gulp.src('css/*.css')
    .pipe(sourcemaps.init())
    .pipe(cleanCSS({})) // specialCommentという/*!から始まるコメントは残る
    .pipe(header(banner))
    .pipe(sourcemaps.write('../maps'))
    .pipe(gulp.dest('dest/css/'));
});

gulp.task('default', gulp.series('clean', gulp.parallel('minify-js', 'minify-css')));
```

## 利用したモジュール

```json
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"del": "^4.1.1",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean-css": "^4.2.0",
"gulp-header": "^2.0.7",
"gulp-sourcemaps": "^2.6.5",
"gulp-uglify": "^3.0.2"
```

## 実現できていないこと

- 拡張子を`.min.js`のように変更するためにgulp-renameを利用するとソースマップファイルの名前まで変わってしまったのでgulp-renameは利用していない

## 参照

https://github.com/hiromitsu7/html5-boilerplate
JWT認証を利用したスクラッチ組織切り替えのやり方が変わった

## 何があったか
2019年6月15日以降、`force:auth:jwt:grant`を実行してデフォルトスクラッチ組織の切り替えが出来なくなりました。

## Salesforce CLI のv46 アップデートが原因

2019年6月15日 あった `Salesforce CLI` の[v46 アップデート](https://developer.salesforce.com/media/salesforce-cli/releasenotes.html) で`force:auth:jwt:grant` の仕様が若干変わったことが原因です。

ただし、6月19日にRelease Noteを確認したところ、該当文句が記載されていましたが、
6月22日に再度確認したらその言及が消えてしまったので今後アップデート以前の仕様に戻ることも期待しています。

6月22日に既存切り替え方式で試したところ、相変わらず切り替えられなかったので、とりあえずメモも兼ねてここに記載させて頂きます。

# force:auth:jwt:grant の仕様が変わった

既存方式は、切り替え先のスクラッチ組織に対して `force:auth:jwt:grant (--setdefaultusername)` コマンドを実行してJWT認証が通ればデフォルトスクラッチ組織も変わる仕組みでした。

    // 組織A → default | 組織B → non-default
    > force:auth:jwt:grant --username 組織B --setdefaultusername (...) //組織B認証
    // 組織A → NON-DEFAULT | 組織B → DEFAULT

それが、新方式は切り替え対象のスクラッチ組織から `force:auth:logout` コマンドで１回ログアウトしてから`force:auth:jwt:grant`を実行しなければいけません。

    // 組織A → default | 組織B → non-default
    > force:auth:logout -targetusername 組織B                         //組織Bからログアウト
    > force:auth:jwt:grant --username 組織B -setdefaultusername (...) //組織B認証
    // 組織A → NON-DEFAULT | 組織B → DEFAULT


以上です。

またSalesforce CLIにアップデートがあれば、この記事も更新しておきます。
応用情報技術者試験 試験対策

#はじめに
平成31年春期試験で応用情報に合格できたので、記念として試験対策で行ったことをまとめる。
##受験歴
平成25年春期試験で基本情報に合格。
以降、応用情報に何度か挑戦するも不合格。
#試験勉強
##午前対策
午前対策は過去問を過去10年分3回演習した。
また、解いてみてわからない用語は調べ直した。

計算問題は解法を調べるものの、当日解ける気がしないので見直し程度にした。

午前で6割超えられないのはもったいないので、自信が持てるまでとにかく演習を繰り返した。
##午後対策
過去に不合格となった理由として、
- 知識の不足
- 読解力不足
- 解答の戦略
の3点が考えられた。そのため、上記3点を重点的に対策した。
また、過去問は過去問5年分を演習した。午後に関しては、問題形式に慣れるよう心がけた。
###知識の不足
試験対策をする中で、わかった気になっている技術、知識として知っているが技術として身についていない技術が多いことに気がついた。
そのため、アルゴリズムやデータベースなど、試すことができる分野に関しては実際に動かすことで理解を深めた。
また、ネットワークとセキュリティは覚える範囲が広いため、似ている用語をまとめて覚え、一連の動作や技術の歴史として説明できるように覚えた。
###読解力不足
応用情報では30字程度にまとめるよう出題されることが多い。そのため、何について問われているかをよく考え、1〜2個の理由や問題を記述できるよう対策をした。
また、問題中にヒントがあることが多いため、出題者の意図を読み取り、ヒントを拾うよう心がけた。
###解答の戦略
当日解答する問題を固定にせず、余った時間を使って他の問題を解くようにする。一見難しいように見えるが、文中に答えがあるような問題も存在するため、諦めずに解いてみる。
#最後に
上記の対策を行ったことで、私の場合は合格することができた。
また、今回選んだ午後問題は以下の分野である。
- 情報セキュリティ
- プログラミング
- ネットワーク
- 情報システム開発
- サービスマネジメント
"Social Hash: an Assignment Framework for Optimizing Distributed Systems Operations on Social Networks" を読んだ

Faceboook の 2016年の論文、[Social Hash: an Assignment Framework for Optimizing Distributed Systems Operations on Social Networks](https://research.fb.com/publications/social-hash-an-assignment-framework-for-optimizing-distributed-systems-operations-on-social-networks/) を読みました。

# どんなもの?

Social Hash という名前だけをみると MurmurHash のようなハッシュ関数の仲間のようですが、実際には「分散システムにおけるリソースを割り当てを、2段階にすると良いですよ」という手法の提案です。

論文では、リクエストのルーティングに適用してキャッシュのミスヒットを減らす、ストレージシステムに適用してレイテンシを減らす、という二つの応用が取り上げられています。

# 技術や手法のキモはどこ?

Social Hash では、ソーシャルグラフのような比較的安定した入力をもとにした、重い (計算に時間のかかる) 計算を前処理として行っておき、そこにホストの生死や忙しさのようなリアルタイムに移りかわる入力を組み合わせることで、最適なリソース割り当てを実現しています。

前者はそこまで頻繁に変わらないため、論文中では "Static Assignment" (静的な割り当て), 後者は頻繁にかわるため、論文中では "Dynamic Assignment" (動的な割り当て) と呼ばれています。

# どうやって有効だと検証した?

前述の通り、

* リクエストのルーティングに適用してキャッシュのミスヒットを減らす
* ストレージシステムに適用してレイテンシを減らす

という二つの応用でもって、その有効性を検証しています。

# 次に読むべき論文は?

そもそも Facebook はどうやってグラフを保存しているのか、という話を取り扱ったものに [TAO: Facebook’s Distributed Data Store for the Social Graph](https://research.fb.com/publications/tao-facebooks-distributed-data-store-for-the-social-graph-2/) が、Social Hash で提案している手法のうち、グラフを分割だけを掘り下げたものに [Social Hash Partitioner: A Scalable Distributed Hypergraph Partitioner
](https://research.fb.com/publications/social-hash-partitioner-a-scalable-distributed-hypergraph-partitioner/) があります。
mysqli の忘備録 -PDOとmysqliの違い-

PHP&MySQLを触り始めて半年。初めてmysqliというものを知ったので、調べて聞いて分かったことを残しておきたいと思います。

# mysqliとは？
PHPのリファレンスにちゃんとあります！（当たり前）
https://www.php.net/manual/ja/book.mysqli.php
mysqliは、PHP5.5以降で非推奨、7.0で削除となった[mysql_系のメソッド](https://www.php.net/manual/ja/book.mysql.php)の代替となるものです。
具体的にはPHPの拡張機能であり、PHPからMySQLデータベースを操作する時のインターフェースを提供する、つまりDBに接続してゴニョゴニョやる時に使うものです。

> どのAPIをつかうか- [PHPリファレンスより](https://php.net/manual/ja/mysqlinfo.api.choosing.php)

リファレンスによると、MySQLに接続するためのAPIは３種類あり、PDO、mysqli、そして残りは非推奨（削除）となったmysqlです。
ということでDBにMySQLを使う場合、インターフェースは、PDO vs mysqli の二択となります。
個人的にはPDO使っておけば大丈夫！と思っていたので別のメソッドあったんだー、と言う感じです。

上記リンク内で、PDO方式とmysqli方式の簡単な比較が一覧で示されています。
しかしながら、それを眺めてみて私はこう思いました。

**『え、ほとんど違いなくないっ？？（PDOでいいじゃん）』**

実際にパフォーマンス自体はほぼ同じ、と堂々と記述されていますし、速度についても『拡張モジュールの与える影響はごくわずか』ということでしたので間違ってはいないのですが、この微妙な違いが気になったのです。
なので、自分でググったり偉い人に聞いたりしたことをまとめておきます。

# mysqliの特徴（PDOとの違い）
PDOの特徴についてまとめた記事は、たくさんあるので割愛。mysqliの特徴だけまとめていきます！

1.　書き方が２種類。[手続き型とオブジェクト型](https://www.php.net/manual/ja/mysqli.quickstart.dual-interface.php)
2.　PDOより多くのことが実現できる
3.　PDOより高速らしい（が、影響は非常に限定的なので気にするべき違いではない）

### 書き方が２種類ある
これは非推奨（削除）となったmysql_系のメソッドからの移行を考慮してのことだと思われます。
リファレンスでも、オブジェクト型の記述の方が『より現代的であり、より体系化されたコードにつながるので、通常は好ましい』とされていますが、コストの低い移行方法として手続き型の記述を残しているようです。

```手続き型ver.php
// mysql_からの移行がしやすい（従来の書き方に近い）
$mysqli = mysqli_connect("example.com", "user", "password", "database");
if (mysqli_connect_errno($mysqli)) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$res = mysqli_query($mysqli, "SELECT 'A world full of ' AS _msg FROM DUAL");
$row = mysqli_fetch_assoc($res);
echo $row['_msg'];
```
```オブジェクト型ver.php
// インスタンスを生成する
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}

$res = $mysqli->query("SELECT 'choices to please everybody.' AS _msg FROM DUAL");
$row = $res->fetch_assoc();
echo $row['_msg'];
```


### PDOより多くのことができる

個人的に難しく感じたのは、2番目の特徴である『より多くのこと』の範囲です。
実際に[とあるサイト](https://websitebeaver.com/php-pdo-vs-mysqli)では、
> 初心者は理由がなければ便利だしPDOで良いよ、でも上級者でいろいろやりたい事あるならmysqliメソッドがオススメ！

って言ってます。

『より多くのこと』を具体的に挙げてみると、[非同期処理](https://php.net/manual/en/mysqli.reap-async-query.php)とか、[複数クエリ発行](https://www.php.net/manual/ja/mysqli.multi-query.php)とか、最新のMySQL固有の機能を使いたい時、とのこと。これはmysqliが、文字通りMySQL専用拡張機能だからと言えます。
ゴリゴリMySQLの機能を使い倒したいプロフェッショナルな方は、mysqliを使うと便利です！ってことです。

対して、PDO方式はMySQL以外にも対応しているので **汎用性が高く、一般的な処理の範囲であればわざわざMySQLiを使う理由はない** と言えます。PDOの方が出現回数が多くなるのも当然です。


# mysqliを使いたいなーと思ったら
実際の使い方は、日本語だとこの辺のがとても分かり易かったです。
PDOと微妙に違うので比較しながら見ると良いと思います！

https://qiita.com/yasumodev/items/bd2ba476f31804d527d3
https://gray-code.com/php/connection-db-by-using-mysqli/
https://www.petitmonte.com/php/php_mysqli.html


# まとめ
### PDO使った方がいい人
初心者、MySQL以外も使う人、一般的な利用

### MySQLi使った方がいい人
MySQL大好きマン、昔のメソッドから手っ取り早く移行したい人、強い人（学習コストに抵抗がない人）


ということで、偶然ソースコードレビューしていて遭遇したmysqliメソッドについてまとめました。こういう機会があるので人のコード見るのは勉強になります！
【swift】 バッテリ残量と充電ステータス表示

### 前置き
バッテリ残量とか、充電ステータスとかによって、
画面表示がいろいろ切り替わるような機能を作りたいと思って、
とりあえずまずはそのあたりを拾うコードの確認をしました。

### 開発環境
前回まで書いてなかったけど、これがすごく大事だな〜って最近すごく痛感してます。
端末:MacBook Pro/MacOS 10.14.5(Mojave)
Xcode:10.2.1
Swift:5

### 画面イメージ
|充電してる時|
|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/488037ff-4de8-3f6b-7cbf-aeca5bc53493.jpeg" width="300">|

|充電してない時|
|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/d2543f8c-b918-86be-1f3c-0276470523ca.jpeg" width="300">|

### ソース
※storyboardの設定は割愛します。
　UILabelを３つ配置した以外は何もしてないので。

```swift:viewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var lblBattery: UILabel!
    @IBOutlet weak var lblCharge: UILabel!
    @IBOutlet weak var lblChargeStatus: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        DispInitialize()
        
        timerFiring()
    }
    
    func timerFiring() {
        let timer = Timer(timeInterval: 1,
                          target: self,
                          selector: #selector(getBatteryStatus),
                          userInfo: nil,
                          repeats: true)
        RunLoop.main.add(timer, forMode: .default)
    }
    
    func DispInitialize() {
        lblBattery.isEnabled = false
        lblCharge.isEnabled = false
        lblChargeStatus.isEnabled = false
        lblCharge.text = "充電してるかって？"
    }
    
    @objc func getBatteryStatus() {
        UIDevice.current.isBatteryMonitoringEnabled = true
        
        let batRemain = UIDevice.current.batteryLevel
        lblBattery.text = NSString(format: "%.1f", batRemain * 100) as String + "%"
        let batStatus: UIDevice.BatteryState = UIDevice.current.batteryState
        switch batStatus {
        case .charging:
            lblChargeStatus.text = "充電中ですよ。"
        case .full:
            lblChargeStatus.text = "フルチャージ！！"
        case .unplugged:
            lblChargeStatus.text = "充電してないっす。"
        case .unknown:
            lblChargeStatus.text = "わかんね。"
        default:
            lblChargeStatus.text = "マジでわかんね。"
        }
        
        UIDevice.current.isBatteryMonitoringEnabled = false
    }
}
```

### まとめ
”実装”ってほどでもないけど、今回はてこずらずにサラッと第１段階はクリアできた。(いっつも何かとサンプル通りにソース書いても同じように動かなくて詰まることが多い。)

内容とは直接関係ないけど、画像の貼り方(サイズ調整と枠線のつけ方)を下記エントリを参考にさせて貰いました。markdownも使いこなしたい。

・Markdown の画像に枠線をつける
https://qiita.com/nori-dev-akg/items/b9f1709418f39a473d08

・markdownでの画像リサイズ
https://qiita.com/shti_f/items/b819d7fd8cb79ae29687
JavaScriptでScroll機能をざっくりと作ってみる

# はじめに

HTMLの表などをスクロールする機能が必要になりました。
そこでとりあえずざっくりと作ってみました。
所々詰めが甘いところがありますが、記事にしてみます。

# HTML および CSS

サンプルとして簡単ですが以下のようなHTMLとCSSを想定します。

## HTML

```html:HTML
<ul id="ul">
  <li id="0">item 0</li>
  <li id="1">item 1</li>
  <li id="2">item 2</li>
  <li id="3">item 3</li>
  <li id="4">item 4</li>
  <li id="5">item 5</li>
  <li id="6">item 6</li>
  <li id="7">item 7</li>
  <li id="8">item 8</li>
  <li id="9">item 9</li>
</ul>
```

## CSS

```CSS:CSS
ul {
  list-style: none;
  height: 64px;
  overflow-x: hidden;
  overflow-y: scroll;
}

li {
    height: 30px;
    border: black 1px solid;
}
```


# ソース

現状?では、以下の両者に違いはないようです。

- `scroll`
- `scrollTo`

相対位置に移動する以下は、今回の実装では使えませんでした。

- `scrollBy`

また、要素の高さを表すプロパティとして以下がありますが

- `clientHeight`
- `scrollHeight`
- `offsetHeight`

これらは、CSSやHTMLとの構造によって使い分けが必要そうです。
とりあえず以下のようにしてみました。
https://jsfiddle.net で検証してみたところ問題なさそうです。
と書きましたが初稿では問題があったようです。(´・ω・`)

```javascript:javascript
function getProperty(element, type) {
  return element[type]
}

function sumArrayToN(array, n) {
  let result = 0
  for (i = 0; i < n; ++i) {
    result += array[i]
  }
  return result
}

function getChildrenHeights(element) {
  const heights = []
  for (const child of element.children) {
    heights.push(child.offsetHeight)
    /*
    let result = {
      "clientHeight": getProperty(child, "clientHeight"),
      "scrollHeight": getProperty(child, "scrollHeight"),
      "offsetHeight": getProperty(child, "offsetHeight"), 
    }
    // console.log(result)
    heights.push(result)
    //*/    
  }
  return heights
}

function scrollUlTo(id, n) {
  const element = document.getElementById(id)
  const heights = getChildrenHeights(element)
  const scroll = sumArrayToN(heights, n)
  
  // element.scroll(0, scroll)
  element.scrollTo(0, scroll)
  // element.scrollBy(0, scroll) 駄目
}

scrollUlTo("ul", 8)
scrollUlTo("ul", 2)
```

# 最後に

あとは、実際に使ってみてより良いものにしていきたいと思います。
はじめてのC++ 【51日目】

# はじめに
operatorまじむずい。特にキャスト演算子。
## C++
###関数ポインタ
コメント欄で関数ポインタという話題がでてきて、詳しく知らなかったので調べる。

**関数ポインタとは**
関数をポインタ経由で呼び出すことのできる変数を宣言できる。ポインタ変数と同じようなもの。

**関数ポインタのメリット**
関数ポインタの例を調べてみましたが、わざわざ関数名を書いて呼び出さなければいけないところで、間接的に呼び出すことが可能になったこと。

**とりあえず書く**

```cpp

#include <iostream>

int a(int x){
  return x * 10;
}



int main() {

  int(*pf)(int) = a;

  std::cout << pf(10) << std::endl;

  return 0;
}
```
```:実行結果:
100
```
関数ポインタの宣言方法は、

```cpp
int(*pf)(int) = a; // 返り値(ポインタ変数名)(引数の型) = 使用したい定義した関数；
```
で表すことができる。

**ポインタ移動**

```cpp
#include <iostream>

int a(int x){
  return x * 10;
}

int b(int x){
  return x * 30;
}

int c(double x){
  return static_cast<int>(x) * 50;
}

double d(int x){
  return static_cast<double>(x) * 11.11;
}


int main() {

  int(*pf)(int) = a;

  std::cout << pf(10) << std::endl;

  pf = b;

  std::cout << pf(10) << std::endl;

  return 0;
}
```
一度ポインタ変数を作ると、 `同じ返り値`　と `同じ引数` なら再代入することができる。

**駄目な例**

```cpp
#include <iostream>

int a(int x){
  return x * 10;
}

int b(int x){
  return x * 30;
}

int c(double x){
  return static_cast<int>(x) * 50;
}

double d(int x){
  return static_cast<double>(x) * 11.11;
}


int main() {

  int(*pf)(int) = a;

  std::cout << pf(10) << std::endl;

  pf = b;

  std::cout << pf(10) << std::endl;

  pf = c; //コンパイルエラー
  pf = d; //コンパイルエラー

  return 0;
}
```
# 終わりに
今のところ関数ポインタはあまり使わないかなぁ
Netlifyで公開しているHugoサイトをNetlifyCMSに変更する方法

# Netlifyで公開しているHugoサイトをNetlifyCMSに変更する方法

## 誰に向けて書いている記事か？

- Netlifyにて、すでにHugoのサイトを公開している
- リポジトリとして、GitHubを使用している
- NetlifyCMSを使用して簡単に記事を書きたい

## 何ができるようになるか？

Netlifyで公開しているHugoサイトをNetlifyCMSで運用できるようになります。

## どうすればできるようになるのか？

### adminフォルダを作成

staticフォルダの下にadminという名称のフォルダを作成します。

### index.htmlの作成

adminフォルダにindex.htmlという名前のファイルを作成します。

中身は、下記をコピーします。

```
<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Content Manager</title>
</head>
<body>
  <!-- Include the script that builds the page and powers Netlify CMS -->
  <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>
```

### config.ymlの作成

adminフォルダにconfig.ymlという名前のファイルを作成します。

backendは、リポジトリの情報を記入してください。
media_folderは、hugoで使用しているimageフォルダのパスを記入してください。
public_folderは、実際に公開された時のimageフォルダのパスを記入してください。
collectionsは、管理画面から記事を作成した時の設定を記入します。

私の環境で使用している設定をサンプルとして公開します。

```
backend:
  name: github
  repo: XXX/YYY # GitHubのリポジトリ　「https://github.com/」の後ろの部分

media_folder: "static/images"

public_folder: "images/"

collections:
  - label: "Blog" # 管理画面のサイドバーで使う
    name: "post" # 管理画面のパスで使う　例：/admin/collections/blog
    folder: "content/post" # Markdownを保存するディレクトリ。Hugoのsectionにあたる
    create: true # 新しいページを作ることを許可する
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Markdownのファイル名　例：YYYY-MM-DD-title.md
    fields: # ページ作成画面で使う。Front Matterの値を書く
      - {label: "タイトル", name: "title", widget: "string"}
      - {label: "公開日", name: "date", widget: "datetime"}
      - {label: "サムネイル画像", name: "thumbnail", widget: "image"}
      - {label: "レーティング", name: "rating", widget: "number"}
      - {label: "本文", name: "body", widget: "markdown"}
```

### アクセス認証（GitHub）

NetlifyからGitHubにアクセスできるようにします。

1. GitHubにログインする。
2. ユーザメニューからSettingsをクリックする。
3. 上記に続けて、Developer settingsをクリックする。
4. 上記に続けて、OAuth Appsをクリックする。
5. 上記に続けて、New OAuth Appsをクリックする。

Application Name　任意
Homepage URL 公開サイトのRUL
Application description 任意
Authorization callback URL 固定https://api.netlify.com/auth/done

![New OAuth Application.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/63baa59f-2065-d68d-d999-63c271dc9180.png)

### アクセス認証（Netlify）

NetlifyからGitHubにアクセスできるようにします。
1. Netlifyにログインする
2. 公開しているサイトをクリックする
3. 上記に続けて、Site settingsをクリックする
4. 上記に続けて、Access Control、OAuthを順にクリックする
5. GitHubを選択して、先ほどGitHubで登録した時に表示されるClientIDとClient secret番号を入力する。

### サイトにアクセス

下記のURLでアクセスするとGitHubのログインが求められます。

```
公開URL/admin
```

GitHubのログインが成功すると、管理者画面が表示されます。

![Content Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/22e10a2b-67be-b873-8b80-48ea95e04c86.png)

無事表示されば、NetlifyCMSに変更することができました。

みなさんのお役に立てたら、是非この記事にいいねを教えてください。
今後の記事作成のモチベーションに繋がります！
FLASK ブラウザで掲示板の投稿フォームを表示する＜掲示板作成への道>【Windows.ver】

目標：ブラウザで下記の様な掲示板の投稿フォームを表示する
<img width="351" alt="2019-06-23 (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/a0ef57b8-6e80-c63f-3b81-a6d5e6316a69.png">

1.新規ファイルform.pyを作成する
<img width="470" alt="2019-06-23 (4).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/ff6144dd-ac00-213b-13a8-cc14a695ced7.png">

2.form.htmlを作成する
※すでにlayout.htmlのテンプレートを作成してあるのでそれを使う。
使い方については過去の記事<共通テンプレート作成>(https://qiita.com/Lavieestbelle/items/288c9234c9ab3dbef23c)
<img width="486" alt="2019-06-23 (5).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/7a40e9ff-6919-ebb3-9f5c-31db432937f1.png">


ブラウザで実行すると
<img width="351" alt="2019-06-23 (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/451cad30-5844-cf3f-de01-2e564036fa31.png">

これに投稿、名前を入れてもエラーが発生する。
次は投稿、名前を反映させる方法を見ていく


<img width="655" alt="2019-06-23 (8).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/d91c653b-7f3a-5da8-f5e7-45b7598ca426.png">

投稿欄と名前欄に入れた内容をブラウザに反映されるために次の指示を書いていく
まず、1行目のfrom flask import FLASK render_templateのところにrequestを追記する

@app.route("/result", methods=["POST"])☜POSTメソッドを指定する
article = request.form["article"]☜投稿欄に文字を入れたらその内容が表示されるようにする指示
name = request.form["name"]☜名前欄に名前を入れたらその内容が表示されるようにする指示

return render_template("form.html", message = message, article= article, name= name)


<img width="607" alt="2019-06-23 (9).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/ad2fdfc9-9b60-2e64-2f89-19935d466dc1.png">

投稿欄と名前欄に入れた内容をブラウザ上に出てくるように＜/form＞の下に指示を書く
＜p＞{{ article }}＜/p＞
＜p＞{{ name }}＜/p＞

ブラウザの投稿欄と名前欄に文字を入力すると、
<img width="260" alt="2019-06-23 (12).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/dc7d539a-04ee-3bf6-9d0e-1705a101fa56.png">

投稿欄、名前欄の下に入力した内容が表示されました！
<img width="310" alt="2019-06-23 (13).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/ddc701d2-c351-4dfc-e706-1939d05d9fc1.png">
Windows10にDocker入れて、jupyterlabを起動

# やりたいこと
* Windows上でpythonの実行環境(Jupyterlab)を構築する  
* マシンを汚したくないのでDocker上に構築する

#環境
* Windows10 Pro : DockerがHyper Vを使用するためProである必要がある。
* Docker Desktop Ver 2.0.0.3

# Dockerのインストール
Windows用のDocker Desktopをダウンロードします。ダウンロードが終了したら、実行して指示に従いインストールしてください。
ダウンロード元：[Docker Desktop](https://www.docker.com/products/docker-desktop)
Docker IDを取得し、設定しておきます。

# Jupyterlabコンテナの準備
Dockerリポジトリからjupyterがインストールされているイメージをpull(ダウンロード)します。Windows PowerShell を起動し、次のコマンドを実行してください。

```command:コマンド
docker pull jupyter/scipy-notebook
```
pullでエラーが発生する場合はネットワークの設定が影響しているかもしれません。コマンドプロンプトから ipconfig して、デフォルトゲートウェイを DockerのDNS Serverに設定してください。
[Settings]-[Network]-[DNS Server]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443524/9376f2d8-ce44-71d0-9951-e2baaa239e8c.png)
pullが成功したら、任意のフォルダにDockerfileを作成します。Dockerfileはバッチファイルのようなものです。
今回は、先ほどpullした"jupyter/scipy-notebook"をベースにpipをアップグレードして、jupyterlabをインストールしています。

```dockerfile:dockerfile
FROM jupyter/scipy-notebook

RUN pip install --upgrade pip
RUN pip install jupyterlab
RUN jupyter serverextension enable --py jupyterlab
```
Windows PowerShellに戻り、カレントフォルダを先ほど作成したdockerfileがあるフォルダに移動します。
移動したら、次のコマンドを実行し、dockerfileをビルドします。

```command:コマンド 
docker build -t jupyterlab:latest ./
```
ビルドが終了したら、コンテナを作成します。次のコマンドを実行してください。

```command:コマンド
docker run -p 8888:8888 --name jupyterlab -v ${pwd}:/home/jovyan/work jupyterlab:latest start.sh jupyter lab
```
すると画面に

```command:コマンド
Executing the command: jupyter lab
[I 14:45:57.953 LabApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
[I 14:45:58.870 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
[I 14:45:58.870 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 14:45:58.872 LabApp] Serving notebooks from local directory: /home/jovyan
[I 14:45:58.873 LabApp] The Jupyter Notebook is running at:
[I 14:45:58.873 LabApp] http://(57d0e8f9ed9f or 127.0.0.1):8888/?token=d7ccc6e3d36f48afdc64681c83021d998f10c48e24f39e72
[I 14:45:58.873 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 14:45:58.877 LabApp]

    To access the notebook, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/nbserver-6-open.html
    Or copy and paste one of these URLs:
        http://(57d0e8f9ed9f or 127.0.0.1):8888/?token=d7ccc6e3d36f48afdc64681c83021d998f10c48e24f39e73
```

上記のように表示されます。指示に従い、ブラウザのURLに入れてるとJupyterlabが起動します。

```url:URL
http://127.0.0.1:8888/?token=d7ccc6e3d36f48afdc64681c83021d998f10c48e24f39e73
```

# 起動と停止
コンテナの起動と停止にはCONTAINER IDを指定します。CONTAINER IDを確認するには下記コマンドを実行します。構築済みにコンテナすべてが表示されます。起動中のコンテナのみを表示させたい場合は、"-a"は不要です。

```command:コマンド　すべてのコンテナを表示
docker ps -a
```
コンテナの起動と停止は以下のコマンドを実行してください。

```command:コマンド　コンテナの起動&アタッチ(tokenを表示させるため)
docker start -a <container id>
```
```command:コマンド　コンテナの停止
docker stop <container id>
```
※マシンを再起動するとコンテナを起動できない場合があり、
その場合は docker を **Restart** してください。
【AWS】初心者がALB、ELBの設定でハマった時に

###対象読者
AWS初心者
ロードバランサー設定したいけどよくわからん
ロードバランサーの設定でハマった

自分がAWS ALBを初めて設定した時になんかあまりうまくイメージできずにハマったところの備忘録です



###やりたかったこと
- VPC内のプライベートサブネットにあるアプリケーションサーバー（２個）に負荷分散させたい
- インターネットからのアクセスを想定


###構成
 - アベイラビリティゾーン二つ
 - それぞれでパブリック、プライベートサブネットに分かれている


####ハマりどころ１:内部向け？インターネット向け？
ハマったというかよくわからなかったところ
僕がネットワークの知識に乏しかったからかもしれませんが、まずロードバランサを作る時にスキームを

インターネット向け、内部向け

どちらにするか迷って何回か作り直しました。

今考えたら当たり前やんって感じ満載ですが。

今回はインターネットから飛んでくるトラフィックをプライベートサブネット内のアプリケーションサーバに捌きたいので
スキームはインターネット向けです。
内部向けはVPC内で完結する通信を分散させたい時ですね。


####ハマりどころ２:サブネットの選択
ALBを置くアベイラビリティゾーン（AZ）を設定する時に各AZの中のどのサブネットにALBを置くか決める必要があるのですが、インターネット向けの場合はパブリックサブネットに置かないとインターネットからの通信が届きません。

これも考えれば当たり前でした、すいません


####ハマりどころ３:ヘルスチェック
最初設定した時ちゃんとセキュリティグループやルートテーブルの設定はしているのに一向にヘルスチェックに通らない時がありました。

原因はパスをうまく設定してなかったことでした。
ヘルスチェックのパスはデフォルトでは
/
ですが、サーバ側では
/health
になってました。
そりゃうまくいかんわって感じでした。

あともう一つはポートです。
ヘルスチェックの通信に使用するポートがあってなかったりするとダメです。
コンソールでヘルスチェックの欄にあるポートでサーバ側の開いているポートをしっかり指定しましょう。


####ハマりどころ４:ポート
またポートかよって感じで恐縮です。
これはローカルからロードバランサに対してcurlコマンドを打っていた時にハマりました。
ヘルスチェックは通ったのに...
ロードバランサにはちゃんと通信届いているのに...
ってなりました。

結局ターゲットに指定しているポートが違ったのが原因でした。
ヘルスチェック用とは別に指定する必要があります。
もちろんどちらも同じポートにすることは可能です。
HTTP通信のデフォルトの８０番を指定してたんですが、サーバ側では３０００番を開いてました...


####まとめ
よ〜く考えよ〜ポートは大事だよ〜
ってなりました。
多分一度経験しておくと何が原因かの目星もつけやすくなってすぐ解決できると思うのですが、最初はちょっとあれでしたね、うん、あれでした。
DockerfileでRUNコマンド実行時の注意点

Dockerfileからイメージを作成する際に、apt-getでインストールする時にハマったので、その備忘録です。


```dockerfile:Dockerfile
# 悪い例
FROM ubuntu
RUN apt-get update
RUN apt-get install -y ruby
RUN apt-get install -y python

# 良い例
FROM ubuntu
RUN apt-get update && apt-get install -y \
    ruby \
    python
```

RUN apt-get updateとapt-get installは、連結して書くようにしないといけません。
悪い例のように、連結せず別々に実行すると、apt-get install命令が失敗するからです。

イメージを構築後、Dockerはレイヤーを全てキャッシュします。
Dockerがファイルを冒頭から読み込んでいき、命令の変更を認識すると、前回に作成したキャッシュを再利用します。
そのため、installコマンドを編集していたとしても、apt-get updateコマンドは実行されずキャッシュされたバージョンが使われてしまいます。
そうすると古いバージョンがinstallされてしまいますー。

ちゃんと公式ドキュメント読まないとですね！

参考サイト：
http://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practice.html
Jetson Nanoで持ち運び可能な暗号化ディレクトリの使用

# はじめに

Jetson Nanoを外に持ち出す場合にデータを暗号化したい場合がある。JetPack 4.2はSDカードにイメージを焼くタイプなので、このSDカードをそのまま暗号化するのは面倒だ。そこで1つのファイル上に暗号化ファイルシステムを構築してマウントすることを考える。

# 概要

次の手順で使用することができる。

1. パッケージ`cryptsetup`のインストール
2. カーネルモジュール`dm-crypt`のインストール
3. (持ち運び用の)ファイルを用意
4. ファイルをマウント

上記を行うためのスクリプトは`github`に置いたので以下に使い方を説明する。

https://github.com/yamamo-to/jetson_nano/tree/master/crypt_example

## パッケージ cryptsetup のインストール

cryptsetupはaptを使ってインストールする。

```bash:ターミナル
sudo apt install cryptsetup
```

## カーネルモジュール dm-crypt のインストール

カーネルモジュール`dm-crypt`はカーネルの再コンパイルを要するので、コンパイル済みのものをgithubに置いた。またモジュールと共にインストール用のスクリプト`install.sh`を作成した。これを実行すればインストールされる。行っていることはモジュールの複製と`depmod -a`である。

```bash:ターミナル
git clone https://github.com/yamamo-to/jetson_nano.git
cd jetson_nano/crypt_example
sudo ./install.sh
```

## (持ち運び用の)ファイルを用意

持ち運び用のファイルを用意するのは少々面倒なのでこれもスクリプト`make_enc_file.sh`を作成した。
下記の例は、持ち運び用のファイル`cryptfile`を10MiBのサイズで作成する。

```bash:ターミナル
sudo ./bin/make_enc_file.sh cryptfile 10
```

作成する際にアルファベットの大文字で「YES」と入力する必要がある。
また暗号化用のパスワード(パスフレーズ)は3回入力することになる。1回目は最初の入力、2回目は確認用、3回目はフォーマット用である。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/jetson_nano/crypt_example$ sudo ./bin/make_enc_file.sh  cryptfile 10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.187049 s, 56.1 MB/s

WARNING!
========
This will overwrite data on /dev/loop1 irrevocably.
yamamo-to@jetson-nano:~/Documents/jetson_nano/crypt_example$ sudo ./bin/make_enc_file.sh cryptfile 10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.186083 s, 56.4 MB/s

WARNING!
========
This will overwrite data on /dev/loop1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/loop1: 
Verify passphrase: 
---
Start ext4 format
Enter passphrase for /dev/loop1: 
mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 8192 1k blocks and 2048 inodes

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
```

## マウント

作成した`cryptfile`を`/mnt/test`にマウントする。

```bash:ターミナル
sudo mkdir /mnt/test
sudo ./bin/mount_enc_file.sh cryptfile /mnt/test
```

## アンマウント

```bash:ターミナル
sudo ./bin/umount_enc_file.sh /mnt/test
```

# まとめ

- Jetson Nanoで暗号化ファイルシステムを作成しマウントした。
- 暗号化ファイルシステムを効率よく利用するために次の3つのスクリプトを作成した。
  - 暗号化ファイル作成スクリプト `make_enc_file.sh`
  - 暗号化ファイルマウント用スクリプト `mount_enc_file.sh`
  - 暗号化ファイルアンマウント用スクリプト `umount_enc_file.sh`
3Dモデリング初心者が学び方やTIPSをまとめる！

## はじめに

この記事はBlenderを触りはじめて一週間ほどの私が書くTIPS集です。

## モデリングの学び方

### 動画で学ぶ
YoutubeやUdemyなどで学ぶ方法です。
動画のメリットとしては実際にその人がどういう手順でモデリングを行っているのかが分かるところです。
デメリットは動画を見ながら写経をしているときに見逃した箇所があったら巻き戻さないといけないところですかね。

### 本で学ぶ
Blenderの学習本は何冊か出ていますが評判の良い本は少ない印象です。
今はネットでチュートリアルなどがたくさんあるので「本で勉強するのが好き！」という方以外は買わなくてもよいでしょう。

### 3Dモデルを見ながら学ぶ
こちらはネットに公開されている3Dモデルをダウンロードしてそれを見ながら学習する方法です。
ニコニコ立体などで配布されている3DモデルをBlenderで開いていろいろ研究してみましょう。
https://3d.nicovideo.jp/

ダウンロードする際はライセンスをしっかり確認してから使いましょうね！

### 失敗を恐れないこと
どんな勉強にも言えることですが失敗を恐れてはいけません。
先ずはひたすらにいじり倒してみましょう。
こういう操作をするとこういう結果になるというのを自分の中に貯めていくことが大切です。



## 初心者的、きれいに見せるコツ
初心者の時、フルスクラッチでモデリングしていて、
ある程度形になってきたときにこう思うと思います。

あれ？　なんか汚くね？　と、、、、、、


汚く見えてしまう要因は色々あると思いますが手っ取り早くきれいにする方法があります。
それは **頂点の位置を揃える**という方法です。

下記の画像をご覧ください。
上にあるのが私が初めて頭をモデリングした時の画像です。
一部揃っているところもありますが基本的に隣り合う頂点同士がぐにゃぐにゃしててきれいではありませんね。

|正面|横顔|
|-----------------|------------------|
|<img width="384" alt="スクリーンショット 2019-06-22 22.22.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/22c2acd1-9087-c923-823c-22b0063455d0.png">|<img width="410" alt="スクリーンショット 2019-06-22 22.22.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/1b2591c5-4d76-d8f7-5dc6-a6206effb321.png">|

下にあるこちらは私が2回目に顔をモデリングした時の画像です。
頂点同士を縦と横でピッシリとあわせることでとてもきれいに見えますね。
劇的ビフォーアフターです。

|正面|横顔|
|-----------------|------------------|
|![blender2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/4013e0eb-ec04-43b3-ba38-fdf29c751161.png)|![blender3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/a383fdce-889d-a044-49cb-58f3a2808856.png)|


やはり人間というものは左右対称など**揃っている**ものをきれいだと感じるようですね。


## モデリング中に意識していること

モデリングをしているとポリゴンがガタガタだったり自分の思い通りにいかないことがあると思います。
しかしそこに時間をかけているといつまでたっても終わらないし最悪途中でやめてしまうこともあるかもしれません。

そんなときはこの言葉を思い出しましょう。

**完璧を目指すよりまず終わらせろ**

かの有名なザッカーバーグ氏の名言です。
多少気に入らないところがあっても先ずは最後まで完成させることを意識してやってみましょう。
それに続けていれば必ず上達していくので最初は少しくらい凸凹しててもいいのです。

## まとめ

3Dモデリング最高！みんなもやろう！

次回は髪の毛を簡単にきれいに作る方法について書こうと思います！
テーブルの意外と知られていないタグ

今回は、HTMLのテーブルタグの中で使用できるタグについてです。

この間テーブル作成時にリファレンスをのぞいていると、今まで知らなかったタグの存在を発見し、使ってみると便利でした。
なので、それを基本的なタグと合わせて紹介していきたいと思います。

# 基本的なタグ
```history.html
<table>
  <tr><th>年月日</th><th>出来事</th></tr>
  <tr><td>2001年</td><td>Windows XP</td></tr>
  <tr><td>2007年</td><td>Windows Vista</td></tr>
  <tr><td>2009年</td><td>Windows 7</td></tr>
  <tr><td>2012年</td><td>Windows 8</td></tr>
  <tr><td>2013年</td><td>Windows 8.1</td></tr>
  <tr><td>2015年</td><td>Windows 10</td></tr>
</table>
```
実行するとこのようになります。
![スクリーンショット 2019-06-22 23.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401638/11c73865-3f8c-8852-c6ba-1836010d3cd4.png)


trタグは、表の横一行をを定義します。
thタグは、見出しを定義していて太字になります。
tdタグは、表の中のデータを定義します。

つまりこのプログラムでは、thタグで「年月日」「出来事」という見出しを作成し、その見出しの内容をtdタグで作成し、それらを行ごとに定義しているのがtrタグとなります。

# 意外と知名度がないタグ
上の３つのタグはテーブルを使用する時に必ず使うので最初にHTMLに触れた段階で習います。

```history.html
<table>
  <caption>
     <details>
        <summary>WindowsNT系の歴史</summary>
        <p>Windowsは、2000年に発売したWindows Me以降Windows9X系は発売せずWindowsNT系に一本化しました。<br>
           それ以降の歴史を見ていきましょう。
        </p>
     </details>
  </caption>
              
  <tr><th>年月日</th><th>出来事</th></tr>
  <tr><td>2001年</td><td>Windows XP</td></tr>
  <tr><td>2007年</td><td>Windows Vista</td></tr>
  <tr><td>2009年</td><td>Windows 7</td></tr>
  <tr><td>2012年</td><td>Windows 8</td></tr>
  <tr><td>2013年</td><td>Windows 8.1</td></tr>
  <tr><td>2015年</td><td>Windows 10</td></tr>
</table>
```
こちらを実行するとこのようになります。タイトルのようなものが表示されるようになりました。
![スクリーンショット 2019-06-22 23.40.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401638/aba1e3d4-d0fb-5f5a-4ff4-77b1e6693158.png)

そして黒塗りの三角をクリックすると説明が出てきます。

![スクリーンショット 2019-06-22 23.41.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401638/a684db08-5bf8-e583-d7c3-02275b60125e.png)


このように説明を隠したり表示したりできます。
このような表の説明は、capitionタグによって付け加えることができます。
今回はそのタグ内でdetailsやsummaryを用いてより分かりやすくしていますが、captionタグだけを用いて説明することも可能です。

# まとめ
テーブルにはただ表を作成する機能以外にも、より表を分かりやすくできるタグが用意されていました。
表の説明やタイトルを加えたい時には、captionタグを使用してみてください。
Vue.js + TypeScript + Jestでクラスをモックしてテスト

# 目標
jestでの単体テスト時にテスト対象クラスの依存先クラスをモックする。

# 環境
vue-cli 3.2.3
vue createでのプロジェクト作成時にTypeScript、単体テストフレームワークにjestを指定する。

# テスト対象
例として下記のようにユーザ情報を取得するリポジトリクラスとリポジトリクラスを利用するサービスクラスを作成する。

リポジトリクラス

```TypeScript:UserRepository.ts
export default class UserRepository {
  // 指定されたユーザIDのユーザ名を返す
  public async getUserName(userId: string): Promise<string> {
    // 本来はここでWeb APIを実行するなどしてユーザ情報を取得して返す。
    return "";
  }
}
```

サービスクラス

```typescript:UserService.ts
import UserRepository from "./UserRepository";

export default class UserService {
  private userRepository = new UserRepository();

  // リポジトリクラスで取得したユーザ名に"Hello "をつけて返す
  public async helloUser(userId: string): Promise<string> {
    const userName = await this.userRepository.getUserName(userId);
    return "Hello " + userName;
  }
}
```

サービスクラスの単体テストを行うために、リポジトリクラスをモック化する。今回の例のようにインスタンス化して利用しているクラスをモック化するには、ドキュメントにあるようにコンストラクタ関数をモックする必要がある。
https://jestjs.io/docs/ja/es6-class-mocks


テストクラスを以下のように作成する。jest.mockを使用しUserServiceの依存先であるUserRepositoryをモック化する。そしてjest.fnを使用しコンストラクタ関数をモック化する。

```typescript:test.spec.ts
import UserService from "@/UserService";

// モック化処理
jest.mock("@/repositories/UserRepository", () => {
  return jest.fn().mockImplementation(() => {
    return {
      // getUserName関数が返す値を引数userIdの値によらず、"hoge"に固定する
      getUserName: async (userId: string): Promise<string> => {
        return Promise.resolve("hoge");
      }
    };
  });
});


// テスト
describe("Test", () => {
  // 非同期処理のテストのためasyncをつけている
  it("helloUser test", async () => {
    const service = new UserService();
    // helloUser関数の返り値を検査
    expect(await service.helloUser("id1")).toEqual("Hello hoge");
  });
});

```
[Kotlin] 基本Typeを調べてみよう

# Kotlin???

最近、大学の先輩から「Kotlin」の話をよく聞いています。
少し、興味があったので、調べてみました。

Kotlinは、
JetBrainsから2011年に公開したプログラミング言語。
Android、Spring、Tomcat、JavaScript、Java EE、HTML5、iOSなどを開発する際に、使用することができる。
2017年にGoogleがAndroidの公式言語でKotlinを追加。
2018年にKakao TalkメッセージングサーバーにKotlinを使ってみた結果、コード量が飛躍的に減少し、生産性が大幅に向上。

# Kotlin Type定義

Kotlinは、Typeを使用します。Javaと比較してみると、すべて大文字で開始します。

|Java Type|Kotlin Type|Kotlin Type bit|
|:-------:|:---------:|:-------------:|
|double	　|Double     |64|
|float	　|Float      |32|
|long	　|Long	      |64|
|int	　|Int	      |32|
|short	　|Short      |16|
|byte	　|Byte	      |8|

```java_sample1.java
long a = 100;
int b = (int) a;
```

```kotlin_sample1.kt

val a: Long = 100
val b: Int = a // ERROR

val b: Int = a.toInt()
val b = a.toInt()
```

Typeを変換するためには、
toInt()みたいなオプションが必要です。

Stringの変換はこんな風にします。

```kotlin_sample2.kt
val string_sample: String = "123"
val int_sample = Integer.parseInt(string_sample)
```

次回は、基本的な文法について説明します。
nodenvで最新のNode.jsを入れてみる

lightsail起動して、nodenvでNode.js入れるまで。普通に**lithgsailのNode.js入ってるイメージ使えばいいんだけど**、何か色々の用途で使いたかったからプレーンなOSスタートだった。

## nodenvインストールする

https://github.com/nodenv/nodenv

この辺見ながら上からする。

```shell
% git clone https://github.com/nodenv/nodenv.git ~/.nodenv
% cd ~/.nodenv && src/configure && make -C src
```

使ってるshellはzshなので指示に従ってzshrcでPATHを通す。

```shell:~/.zshrc
export PATH="$HOME/.nodenv/bin:$PATH"
```

initしろって書いてあるからする。

```
% ~/.nodenv/bin/nodenv init
# Load nodenv automatically by appending
# the following to ~/.zshrc:

eval "$(nodenv init -)"
```

なぜzshrcにもう一度書き込まなきゃならないのか分からないけど、書いてあるからする。

```shell:~/.zshrc
export PATH="$HOME/.nodenv/bin:$PATH"
eval "$(nodenv init -)"
```

`nodenv-doctor` とやらが状態を見てくれるというのでする。これで全部OKって出るらしい。

```shell
% curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
Checking for `nodenv' in PATH: /home/ec2-user/.nodenv/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: not found
Unless you plan to add Node versions manually, you should install node-build.
Please refer to https://github.com/nodenv/node-build#installation

Counting installed Node versions: none
  There aren't any Node versions installed under `/home/ec2-user/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK
```

`nodenv install` が `not found` って言ってて急に裏切られた気になる。

## node-build入れる

Optionalって書いてあるけど、 `node-build` を入れなきゃだめみたいだ。

https://github.com/nodenv/node-build#readme

上記を見ると、インストール先が `/usr/local` になってる。今までec2-userでnodenv入れようとしてたけど、大丈夫なのかな？　PATHが通ってればいいのかもしれない。rootになって下記をした。

```shell
$ git clone https://github.com/nodenv/node-build.git /usr/local/src
$ PREFIX=/usr/local /usr/local/src/node-build/install.sh
```

実行しても何も表示されないけど、これでいいっぽい。**無慈悲**。ec2-userに戻って、doctorに聞いてみる。

```shell
% curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
Checking for `nodenv' in PATH: /home/ec2-user/.nodenv/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /usr/local/bin/nodenv-install (node-build 4.6.1)
Counting installed Node versions: none
  There aren't any Node versions installed under `/home/ec2-user/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK
```

あ、installが使えるようになったっぽい。

## 最新のnode入れてみる

インストールできるバージョン確認

```
% nodenv install -l
・・・
12.4.0
・・・・
```

インストール

```
% nodenv install 12.4.0
Downloading node-v12.4.0-linux-x64.tar.gz...
-> https://nodejs.org/dist/v12.4.0/node-v12.4.0-linux-x64.tar.gz
Installing node-v12.4.0-linux-x64...
Installed node-v12.4.0-linux-x64 to /home/ec2-user/.nodenv/versions/12.4.0
```

結構早く終わる。

```
% node --version
nodenv: node: command not found

The `node' command exists in these Node versions:
  12.4.0
```

**見つからないのか、見つかったのか、どっちなのか……。**で、これはきっとアレだと思った。 `use` とか `global` でバージョン指定してないからだと思った。`global` らしい。

```shell
% nodenv global 12.4.0
% node --version
v12.4.0
% npm --version
6.9.0
```

あ、できた。