OmniAICreator/Qiita-1.07M huggingface dataset:
【Google Cloud Schduler API】 Firebase functionsで使ってみた

# きっかけ

大学の研究で進化計算というものを行っており、進化の処理を行うために利用しました。

本記事では、firebaseプロジェクトの作成、functionsの設定まで済んでいるというところをスタート地点として説明していきます。

# 自動でタスクを実行する流れ

今回は、firestoreにドキュメントが作成されたら、その情報を元にスケジュールを作成するサンプルを作成します。
流れとしては、

1. 定期的に実行したいfunctions.pubsubを作成
2. スケジュールの作成、削除
3. functions.onCreateでスケジュールの作成、削除を発火

pub/subを利用する理由として、httpsだと誰からでも起動できてしまうため、セキュリティ的なデメリットがあるからです。
また、スケジューラと紐付ける時に相性がいいです。

では、順を追って説明していきます。

## pubsubの作成

今回のサンプルではスケジューラで送られてきたメッセージをログに表示していきます。

```js
const locationId = "asia-northeast1"; // region
const projectId = "scheduler-api-sample"; // firebaseのプロジェクト名
const topicName = "sample-pubsub"; // pub/subの名前
const jobName = "sample-job"; // スケジューラのジョブの名前

...

exports.samplePubSub = functions.pubsub
  .region(locationId)
  .pubsub.topic(topicName)
  .onPublish(message => {
    const messageBody = message.data ? message.data : null
    console.log("messageBody:", message.data)
  })

...
```


## スケジュールの作成、削除

### モジュールの追加

`yarn add @google-cloud/scheduler`
でモジュールを追加します。

注意点として、`プロジェクト/package.json`でなくプロジェクト`/functions/package.json`に対して追加してください。

### 初期化

```js
const scheduler = require("@google-cloud/scheduler");

const client = new scheduler.v1beta1.CloudSchedulerClient({ projectId });
```

projectIdを渡して、どのプロジェクトに対してジョブを追加するか予め設定しておきます。

### ジョブの作成

```js

const formattedParent = client.locationPath(projectId, locationId);
const formattedJobName = client.jobPath(projectId, locationId, termDocId);

const registerJob = () => {
  
  const interval = `0 0 * * *`; // crontab or App Engine Cron

  const req = {
    parent: formattedParent,
    job: {
      name: formattedJobName,
      schedule: interval,
      pubsubTarget: {
        topicName: `projects/${projectId}/topics/${topicName}`,
        data: Buffer.from('published').toString("base64")
      }
    }
  };

  client
    .createJob(req)
    .then(res => console.log(res[0]))
    .catch(e => console.error(e));
}

```

`formattedParent`　=> `projects/[PROJECT_ID]/locations/[LOCATION_ID]`
`formattedJobName` => `projects/[PROJECT_ID]/locations/[LOCATION_ID]/jobs/[JOB_ID]`
を生成してくれます。

パラメータについては公式サイトに詳しく載っていますので、もっと知りたい方は以下のリンクを参考にしてください。
登録済みのジョブのリストや更新などについても載っています。


> 公式サイト
> https://cloud.google.com/nodejs/docs/reference/scheduler/0.1.x/google.cloud.scheduler.v1beta1?hl=ja#.Job

### ジョブの削除

```js
const unRegisterJob = () => {
  const req = {
    name: formattedJobName
  };

  client.deleteJob(req).catch(e => console.error(e));
};
```

こちらはジョブの名前を指定するだけで削除ができます。

## functionsで追加する

```js
exports.sampleFirestoreOnCreate = functions
  .region(locationId)
  .firestore
  .document("samples/{docId}")
  .onCreate((snap, context) => {
    registerJob();
  }
```

これで`samples`コレクションにドキュメントが作成されたらジョブが設定されるようになりました！
`0 0 * * *`間隔に設定しているので、毎日0時0分になったら`publishTarget.data`で渡したメッセージ(`published`)をログで出力します。

いろいろ試していて、ジョブの名前が重複していると登録ができなかったので、自動で追加する場合にはfirestoreで自動生成されるドキュメントIDなどを使うといいかもです。
僕は`docId`を`registerJob`に渡して`jobId`として登録することで重複を避けました。


## 所感

schedulerのAPI利用については記事があまり無いのでこのモジュールにたどり着くまで結構時間がかかりました。もっとGCPを使いこなしたいですね。

みなさんよいfirebaseライフを！

※ 間違いや動かないぞ！ということがありましたらコメントにお願いします。
衛星情報利用の著作権取り扱いまとめ

#sentinel-hub
###元ページ
　　https://sentinel-hub.com/tos#dataset

###条件
合法である限り、以下の使用を目的として、コペルニクスのデータへの無料アクセスを許可
　a) reproduction;
　b) distribution; 
　c) communication to the public; 
　d) adaptation, modification and combination with other data and information; 
　e) any combination of points a to d

###クレジット
　 Contains modified Copernicus Sentinel data [Year] processed by Sentinel Hub

#Landsat
###元ページ

 https://landsat.gsfc.nasa.gov/news/media-resources/

###クレジット
“Landsat imagery courtesy of NASA Goddard Space Flight Center and U.S. Geological Survey”
or 
“USGS/NASA Landsat”

#tellus
###元ページ

https://www.tellusxdp.com/ja/dev/data

###条件
 tellus内では自由に利用可能
 ユーザーが作成した二次成果物は自由に利用
 元データを再現可能な状態でのtellus外への複製不可

###クレジット
|衛星|　クレジット表記 |
|:-----------:|:------------:|
|ASNARO-1|　Original data provided by NEC|
|AVNIR-2/ ALOS　|不要|
|ASNNARO2|　Original data (c) NEC Corporation|
|PALSAR-2/ALOS-2|　Original data provided by JAXA|
|SHIROP / SLATS| 　Original data provided by JAXA|
時間表示は切りのいい時間で表示するのではなく切りの悪い時間のほうがそれっぽい

# 初めに
タイトルの通りで、更新タイミングを１００などの切りのいい数字よりも悪い数字のほうがそれっぽくみえるという記事です。

# 100ms更新の場合
![100.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/b928d263-8ff8-43cb-aee0-27824775662f.gif)

# 129ms更新の場合
![129.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/7ce4c651-db9c-5146-6e31-b3804fad9e6c.gif)
bootstrapでcheckboxをtoggleにする

就活のために個人アプリを使っている中で、bootstrapを使っていて、性別の登録をbootstrapのtoggleボタンにしたら面白そうだと思ってやってみました。
忘れないようにメモにしておこうと思って残しておきます。

## 環境
Rails 5.2.3
bootstrap4

## 留意点
bootstrapはbootstrap-railsで導入。
cssとhtmlとJSはそれぞれscssとhamlとjQueryで記述。

## コード
### Bootstrap Toggleを使うために
```application.html.haml
%link{:href => "https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css", :rel => "stylesheet"}
%script{:src => "https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"}
```

### 表示方法(2パターン)
#### 1. JSも使う場合(こっちは正常に動く)
```new.html.haml
= f.check_box :gender, { :checked => "checked", id: "sign_up-toggle" }, "男性", "女性"
```
```toggle.js
$(document).on('turbolinks:load', function() {
  $(function() {
    $('#sign_up-toggle').bootstrapToggle({
      on: '男性',
      off: '女性',
      offstyle: 'danger',
      width: '150',
    });
  });
});
```

#### 2. hamlだけで表示する場合(こっちはリロードしないと表示されない)
```new.html.haml
= f.check_box :gender, { :checked => "checked", "data-toggle" => "toggle", "data-on"=> "男性", "data-off"=> "女性", "data-offstyle"=> "danger", "data-width" => "150" }, "男性", "女性"
```
form_forで登録しているので、f.check_boxの書き方にしています。
gender　が登録するカラム。
"男性", "女性"がそれぞれチェックがON, OFFの時に登録される値。
{}の中身の解説についてはあとでまとめて記載します。
ざっくり言ってしまえば、{}の中身をjsに記載するか、hamlに直接書くかの違いでしょうか。
なぜか、2. のやり方だとリロードしないと使えないです。
どなたか教えていただけたら助かります。

#### {}の中身について
パターン1の方で説明します。

```new.html.haml
= f.check_box :gender, { :checked => "checked", id: "sign_up-toggle" }, "男性", "女性"
```

```toggle.js
$(document).on('turbolinks:load', function() {
  $(function() {
    $('#sign_up-toggle').bootstrapToggle({
      on: '男性',
      off: '女性',
      offstyle: 'danger',
      width: '150',
    });
  });
});
```
・sign_up-toggleはtoggleを設定するcheckboxに付与するidです。
jsではここをイベントの発火点にしています。
・checked => "checked"　は初期状態がチェック(ON)されている状態にします。
今回だとON：男性、OFF:女性で、ページを表示した時に男性が選ばれている状態です。
・on ONの時のボックスのテキスト
・off OFFの時のボックスのテキスト
・offstyle　OFFの時のスタイル、デフォルトではdefault
・width　　ボタンの幅

そのほかにもオプションを色々と設定できるみたいなので参考サイトを見てみてください。

**注意点**
オプションについては、jsで書くときとhtmlで書くときで少し異なります。

- js
  - on
  - off
- haml
  - data-on
  - data-off

htmlの方に「data-」が頭に付くと思ってください。

## 実行結果
![demo](https://gyazo.com/444ebd9db0dec539b3a63622650c6fce/raw)

こんなかんじになります。
データベースに値も保存できるので色々なことに使えそうです。

## 参考サイト
[Bootstrap Toggle](https://www.bootstraptoggle.com/)
じゃんけん問題

###Pythonじゃんけん問題

```python
import random

def gu():
    if num == 0:
        print("あなたの手:グー, わたしの手:グー")
        print("あいこで")
    elif num == 1:
        print("あなたの手:グー, わたしの手:チョキ")
        print("あなたの勝ちです")
        exit()
    elif num == 2:
        print("あなたの手:グー, わたしの手:パー")
        print("あなたの負けです")
        exit()

def choki():
    if num == 0:
        print("あなたの手:チョキ, わたしの手:グー")
        print("あなたの負けです")
        exit()
    elif num == 1:
        print("あなたの手:チョキ, わたしの手:チョキ")
        print("あいこで")
    elif num == 2:
        print("あなたの手:チョキ, わたしの手:パー")
        print("あなたの勝ちです")
        exit()

def pa():
    if num == 0:
        print("あなたの手:パー, わたしの手:グー")
        print("あなたの勝ちです")
        exit()
    elif num == 1:
        print("あなたの手:パー, わたしの手:チョキ")
        print("あなたの負けです")
        exit()
    elif num == 2:
        print("あなたの手:パー, わたしの手:パー")
        print("あいこで")

def naiyo():
        print("その値は無効です")

while True:
    print("最初はグー、じゃんけん...")
    print("0=グー　1=チョキ　2=パー")
    pon = int(input(''))
    num = random.randint(0,2)
    
    if pon == 0:
        gu()
    elif pon == 1:
        choki()
    elif pon == 2:
        pa()
    else:
        naiyo()
```
How to MyBatisで値オブジェクトを持ったクラスへのマッピング

# やりたいこと

最近、オブジェクト指向の設計についてお勉強中なのですが、
ドメインオブジェクトを使っているとデータベースの都合のクラスの存在がやっかいに感じ、
データベースから取得した値を直接ドメインオブジェクトの形で受け取れたらなぁと考えていました:frowning2:


自分もまだまだ勉強中なので、1つの解決方法としてMyBatisを使ってみましたが、
データベースから値を取得する時のいい方法があれば教えていただきたいです:bow:

## 環境
- Java 8
- Spring boot 2.1.9
- MyBatis Spring boot starter 2.0.1
- MySQL 5.7.1

## MyBatisでSELECTしてみる
MeetingRoomクラスをMyBatisを使って取得をする

```java
public class MeetingRoom {
    private int id;
    private String name;

    ...
}
```

```java
@Mapper
public interface MeetingRoomMapper {

    MeetingRoom findById(int roomId);
}
```
```xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.tutorial.MeetingRoomMapper">
    <select id="findById" resultType="com.spring.tutorial.MeetingRoom">
        SELECT
            room_id as id,
            room_name as name
        FROM
            meeting_room
        WHERE
            room_id = #{room_id}
    </select>
</mapper>
```
ってな感じでMapperクラスのfindByIdの戻り値と、MapperファイルのResultTypeにMeetingRoomを指定してあげるとMeetingRoomの形で返してくれます。
また、カラム名とプロパティ名が一致している必要があるので、AS句で指定しています。

## 値オブジェクトを使う
MeetingRoomのIDをint型からIdクラスへ変更します。

```java
public class MeetingRoom {
    //値オブジェクトに変更
    private Id id;
    private String name;

    ...
}
```
```java
public class Id {
    private static final int MIN = 1;
    private Integer value;

    Id(int value) {
        if (value < MIN) throw new IllegalArgumentException("不正な値です。 value:" + value);

        this.value = value;
    }
 
     ...
}
```

ResultMapを使ってIdクラスとMeetingRoomクラスの設定をします。

```xml
    <resultMap id="IdMap" type="com.spring.tutorial.Id" >
        <id property="value" column="room_id" />
    </resultMap>

    <resultMap id="MeetingRoomMap" type="com.spring.tutorial.MeetingRoom">
        <result property="name" column="room_name" />
        <association property="id" resultMap="IdMap"/>
    </resultMap>
    
    <select id="findById" resultMap="MeetingRoomMap">
        SELECT * FROM meeting_room WHERE room_id = #{room_id}
    </select>
```
SELECTのResultTypeをResultMapに変更し、MeetingRoomのResultMapを指定します。
ResultMap内でResultMapを使うときは**association**を使います。
同じオブジェクトのプロパティにresultがいる時、associationを下に記述しないとエラーが出るので気をつける:point_up_2_tone1:
> 要素タイプ"resultMap"のコンテンツは"(constructor?,id*,result*,association*,collection*,discriminator?)"と一致する必要があります。

## まとめ
データベースの都合のクラスを増やさなくていいからMyBatisはいい:relaxed:

### 参考
[現場で役立つシステム設計の原則](https://gihyo.jp/book/2017/978-4-7741-9087-7)
[mybatis - Mapper XML ファイル](https://mybatis.org/mybatis-3/ja/sqlmap-xml.html)
Golang コンパイラのバージョン管理


# Goのバージョン管理

Goのコンパイラごと
バージョンを切り替えたくなったことが何度かありました。
面倒になったのでコンパイラのインストールをshellscriptにしました。
原始的ですが割と高速にインストールできます_(:3 」∠ )_
これでwgetして自動インストールができるように(/'ω')/

スクリプトは長くなってしまったので [Github](https://github.com/xcd0/go_compiler_install/blob/master/go_compiler_install.sh) に置きました。
wgetやcurlでとる場合

```shell
wget https://raw.githubusercontent.com/xcd0/go_compiler_install/master/go_compiler_install.sh
```
で取れます。

使い方はそのままたたくとヘルプが表示されますのでそれに従ってください。
何も考えずただコマンド1つでインストールしたい場合は、

```shell
./go_compiler_install.sh -v go1.13.7 -d $HOME/work/go -f -p
```
のようにしてください。バーションなどは書き換えて使用してください。

まためちゃくちゃ丁寧なインタラクティブモードを用意しています。

```shell
./go_compiler_install.sh -i
```
を実行してください。

<details><summary>以下長い説明</summary><div>
## 推奨
gvmというのがあるらしいのでそちらをお勧めします
https://techte.co/2018/01/23/golang-gvm/

どうしても原始的に管理したい場合のみどうぞ

この記事の方法の一応の利点として、
gvmと比べるとインストールが早いです。
gvmはソースコードからビルドするためマシンパワーと処理時間が必要です。
私の方法ではビルド済みのものをダウンロードしてくるため時間短縮になります。

CPUが2014年発売のIntel(R) Celeron(R) CPU G1840 @ 2.80GHzである
非力な私のサーバーでgo1.13.4をインストールした場合、
下記のよく使うパッケージのインストールまで含めて

```
real    1m6.921s
user    0m10.417s
sys     0m3.201s
```
となりました。
(ただし回線速度は速いです。)

## 注意
宗教上の理由により、 私はプログラム関係のデータを
`$HOME/work`以下にディレクトリを掘って保存しています。
なのでGoのインストールも$HOME/work/go以下にすべて配置します。

`GO_INSTALL_DIR` という変数を2か所設定して使っています。
読み替える場合、これを書き換えてください。

## 説明

今回複数バージョンのコンパイラを管理するため、
ディレクトリが深くなっています\_(:3 」∠ )\_
`$GO_INSTALL_DIR` 以下にバージョンごとの環境を保存し、
使いたいバージョンのディレクトリに対して
`$GO_INSTALL_DIR/go` からシンボリックリンクを張ります。

最終的に以下のようになります。

```
$GO_INSTALL_DIR
├── go -> go1.13.3     <- これはシンボリックリンク
├── go1.12.12
│   ├── bin
│   ├── go             <- これがgo1.12.12のコンパイラ
│   ├── pkg
│   └── src
└── go1.13.3
    ├── bin
    ├── go             <- これがgo1.13.3のコンパイラ
    ├── pkg
    └── src
```

## 環境変数について

Goで使用される環境変数を設定します。

|変数名|説明|設定値|
|:---:|:---:|:---|
|GOPATH|作業ディレクトリ|$GO_INSTALL_DIR/go|
|GOBIN |バイナリが置かれる場所|$GO_INSTALL_DIR/go/bin|
|GOROOT|goのインストール場所|$GO_INSTALL_DIR/go/go|

`.bachrc` or `.bash_profile` などに下記を記述して環境変数を設定します。  

```sh
# 読み替える場合、これを書き換える
GO_INSTALL_DIR=$HOME/work/go

export GOPATH=$GO_INSTALL_DIR/go
export GOBIN=$GOPATH/bin
export GOROOT=$GOPATH/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
```

## Goのインストール

OSにかかわらず、$HOME/work/go/以下に、
バージョン名のディレクトリを掘ってインストールしています。

インストールには以下に記載するシェルスクリプトを使っています。
適当に保存してください。

インストール場所を読み替える場合は、

```sh
GO_INSTALL_DIR=$HOME/work/go
```

の部分書き換えてください。
</div></details>

以上です。やさしめのマサカリ待ってます\_(:3 」∠ )\_
Google App Engine Ruby FlexibleでDockerイメージをいろいろカスタマイズする方法

## 概要

Google App Engine Ruby Flexible環境で、Pythonや機械学習など、Ruby以外のなにかを使いたい場合に、Dockerイメージをカスタマイズできると便利です。

その方法はドキュメントに記載されていませんが、以下を読むとわかります。

https://github.com/GoogleCloudPlatform/ruby-docker/blob/master/ruby-generate-dockerfile/app/Dockerfile.erb

その解説です。

## 環境変数

以下のように環境変数を設定できる。

```yaml

runtime: ruby
env: flex
service: api-production

env_variables:
  LC_ALL: C.UTF-8
  LANG: C.UTF-8
```

### PATHは設定できないので注意

PATHの変更は禁止されている。
PATHを変更すると、デプロイ時のバリデーションが失敗して、デプロイができない。

## ubuntuパッケージ

以下のようにubuntuパッケージをインストールできる。

```yaml
runtime: ruby
env: flex
service: api-production

runtime_config:
  packages:
    - postgresql
    - tmux
    - vim
```

## カスタムインストールスクリプト

以下のようにすると、カスタムインストールスクリプトを実行できる。最後のほうで実行される。

```yaml
runtime: ruby
env: flex
service: api-production

runtime_config:
  build:
    - 'sh script/install_python.sh'

```

### 注意

Ruby FlexibleのDockerイメージはステップに分かれてビルドされるので、最終的なイメージには、/app配下しか残らない。/app配下にインストールする必要がある。 

参考: https://github.com/GoogleCloudPlatform/ruby-docker/blob/master/ruby-generate-dockerfile/app/Dockerfile.erb#L191

## ビルドタイムアウト

### 問題

ubuntuパッケージやカスタムインストールスクリプトを設定するとDockerのビルド時間が長くなって、App Engineのビルドタイムアウトにひっかかってしまう。

以下のようなエラーが出る。

```
ERROR: (gcloud.app.deploy) Cloud build failed. Check logs at https://console.cloud.google.com/xxxxxxxx/ Failure status: UNKNOWN: Error Response: [4] DEADLINE_EXCEEDED
```

### 解決策

以下のコマンドでビルドタイムアウトを伸ばせる。1000の部分は好きな秒数に設定。

```bash
gcloud config set app/cloud_build_timeout 1000
```

### 注意

以下の記事では、上記の解決策が使えないようなことが書いているが、使えた。

>cloud_build_timeout is 10 minutes. I tries to set it to more than 10 min but it doesn't work. – AsmaG Mar 15 at 15:31

https://stackoverflow.com/questions/50046545/google-app-engine-build-timed-out-during-deployment

## 独自のDockerfileを使う方法との比較

独自のDockerfileを直下に配置すれば、そのDockerfileでDockerイメージをビルドできますが、cloud_sql_instancesなども自前で実装しないといけないので、面倒です。

App Engineの作法に則ってカスタマイズするほうが楽だと思います。
kubectl get/delete all は"全"ではない

#背景

kubectlって意外と長い。。。こんなすごく省略したものもあるけど https://containerized.me/600-kubectl-aliases-for-devops-ninjas/
うちではkubectlをkubeに+カスタムコマンドでデプロイとデストロイを使ってマネージしてます。
最近cronjobsを追加したりモニタリングを入れてfalse alertが出るようになってしまったので今まで使っていたコマンドを見直すことに。この過程でkubectl get/delete allが全部じゃないことに気付いたのでメモ。

##original destroy/deploy command

1) **"kube destroy namespace" - namespaceごと消す**

``` 
kubectl delete -R -f path/to/the/file/
```

2) **"kube destroy namespace app" - アプリだけ消す**

```
kubectl delete -R -f path/to/the/file/(appN)/
```

3) **"kube deploy namespace" - アプリの起動する順番を考慮してるのかとりあえずsleepしてたが、
最近入れたモニタリングでこれだけではうまくいかずアプリNのfalse alertが出てしまうようになり見直すことに**

```
kubectl apply -R -f path/to/the/file/namespace/
kubectl apply -R -f path/to/the/file/(appA)/
kubectl apply -R -f path/to/the/file/(appB)/
time.sleep(5)
kubectl apply -R -f path/to/the/file/(appN)/
...
```

##improved destroy command

**destroyにing追加**

```
1) kubectl delete namespace/
2) kubectl delete all,ing -l name=appN -n <namespace>
``` 
 
**さらにdestroyにcm追加**

```
2) kubectl delete all,ing,cm -l name=appN -n <namespace>
``` 

**最終的に"kube destroy namespace app"はbackend appにlabelをつけて先に消すことに。これでfalse alertが出なくなった。**

```
2) kubectl delete all,ing,cm -l type=backend -n <namespace>
```

##improved deploy command

**deployにwait追加、これによってappB podのconditionがreadyになるまで待機させる。**

```
3) kubectl wait --for=condition=ready --timeout=1h -l name=appB'
``` 
 
**上だけでは不十分だったのでさらにdeployにuntil追加。**

```
3) until kubectl wait -n <namespace> --for=condition=ready --timeout=1h -l name=appB ; do echo "waiting for pod" && sleep 5; done
```


##参考にしたもの
- https://medium.com/@reuvenharrison/how-to-wait-for-a-kubernetes-pod-to-be-ready-one-liner-144bbbb5a76f
- https://stackoverflow.com/questions/47691479/listing-all-resources-in-a-namespace
- https://github.com/kubernetes/kubectl/issues/151#issuecomment-402003022

kubectl get/delete all ではなくkubectl api-resourcesを使う以下の方法が薦められてます。

```
kubectl api-resources --verbs=list --namespaced -o name \
  | xargs -n 1 kubectl get --show-kind --ignore-not-found -l <label>=<value> -n <namespace>
```

##学んだこと
- kubectl get/delete all
- kubectl api-resources
- kubectl wait
rsyncが遅い (macOS??)　データ転送が遅い、時間がかかる。

##rsyncがとっても遅いときがあります。
いろいろと調べてみると、多くの場合は、自分の周りのネットワークが原因ですが、こんな場合もあるようです。

###rsyncのバージョンが古い。

macOS(14.14, Mojave)の標準的なrsyncは、、、、

```$ /usr/bin/rsync -v
rsync version 2.6.9 protocol version 29```

!!!

えっ、古！！

macportsなどでrsyncを入れ、そちらを使うだけで、データ転送が快適になるかもしれません。
```$ port install rsync```
OpenStackについて調べてみました。

##あらすじ

案件の異動に伴い、OpenStackを使っていた現場から離れることになりました。
忙しいあまり背景や仕組みを調べずに業務に使っていたので、整理として概要を調べてみました。

##目次

- あらすじ
- OpenStackとは
    - 沿革
    - 特徴
    - OpenStackを使用している企業
    - 活用例
- クラウドで実行されるアプリケーションの特徴
- OpenStackの特徴
    - 
 

##OpenStackとは

簡単に言うと…
・クラウドコンピューティングのためのオープンソースソフトウェア
・IaaSを構築するためのソフトウェアの集まり
である。

####沿革
・2010年7月にプロジェクト開始
　2012年9月にOpenStackFoundationが設立
　2019年現在、最新版は「Queens」と呼ばれている
　　（次回のリリース名はRockyの予定）

###特徴
・Amazon Web Serviceに似た機能を持つ。
　　→　パブリッククラウドに必要な機能が盛り込まれている
　　　　例）複数のユーザーの利用、
　　　　　　ユーザーごとの利用状況の測定

###OpenStackを使用している企業
　AT＆T、ドイツテレコム、KT、インテル、
　SONY(SCE America)、Paypal、Yahoo!、HP、GMOインターネット、Rackspace、SoftLayer、MercadoLibre、Sina、WebEX、
　サイバーエージェント、国立情報学研究所、NECTER、CERN

###活用例
　KT：商用ストレージサービス
　SONY：ゲーム開発環境をAWSからOpenStackへ移行
　GMOインターネット：お名前.com VPSサービスをOpenStackで構築・運用
　Paypal：vCloudからOpenStackにサービス基盤を移行
　Sina(Weiboの運営会社)：自社サービスのAP基板をOpenStack　上で運用
　サイバーエージェント：Amebaの基盤をVMwareベースから置き換え

##クラウドで実行されるアプリケーションの特徴
（AWSを代表とするパブリッククラウド）
　インフラ環境の自動操作を目的とした設計
　・アプリケーションのSLA≠サーバ（仮想マシン）のSLA
　　　→一部のマシンが停止しても、アプリケーションは停止しない

　・必要に応じて仮想マシンを追加・削除する機能が前提
　　　→性能要件の変化に対応
　　　→仮想マシンの障害時などに新しいマシンを追加して対応が可能

　・仮想マシンのライフサイクルは数時間～数か月
　　　→1つの仮想マシンを永続的に利用することを前提としない

　・永続データをアプリケーションと分離
　　　→オブジェクトストアに保存して、仮想マシンとデータを分離

##OpenStackの特徴
　・APIで操作できる「Programmable Infrastructure」の提供
　　　既存のGUI、ワークフローに縛られたくないユーザー層の獲得
　　　プログラムによるインフラ環境の自動構築・変更に対応

　・スケーラビリティを意識した疎結合アーキテクチャ
　　　コンピューティングノードの追加が容易
　　　コントローラの負荷分散が可能
　　設計、運用管理にはこれまでと違うノウハウが必要

####IaaSを構築するためのソフトウェアの集まり
　主な機能
　　・CPU、メモリ、ストレージ、NWなどのリソースの仮想化
　　・利用者の権限に基づいてリソースを割り当てる
　　・操作するGUI画面の提供
　　・役割ごとにコンポーネントをもつ「モジュラーアーキテクチャ」を採用している。

####OpenStackのコンポーネント(とAWSの類似機能)
　Nova：仮想マシンの管理(Amazon EC2)
　Glance：マシンイメージの管理(AMI)
　Neutron:ネットワーク機能(AmazonRoute 53,VPC,ELB)
　Cinder:ブロックストレージ機能(Amazon EBS)
　Swift：オブジェクトストレージ機能(Amazon S3)
　Keystone：認証機能(IAM)
　Horizon：Web管理機能。GUI（マネジメントコンソール）

####OpenStackの操作
　操作方法は大きく分けて3つ
　　①REST形式のAPIをコールする方法
　　②REST APIをラップ下コマンドラインを利用する方法
　　③ダッシュボード機能でブラウザから操作する方法
　　　→仕事で主に用いたのは②REST APIをラップしたコマンドラインを利用する方法でした。
　特徴として以下があります。
　・OpenStackコマンドを使用して操作する。
　　　→コンポーネント毎にコマンドが用意されている。
　　　 ユーザーがどのコンポーネントを利用するかを意識できる
       仮想マシンの操作を行うときは、novaコマンド、
     　NW関連の操作を行うときはneutronコマンドを利用
  ・helpコマンドを利用することで、オプションを確認できる

以下、仮想マシンの立ち上げによく用いたコマンドです。
仮想マシンを作るとき

```
# openstack server create
```

仮想マシン(VM01)を停止・起動するとき

```　
# nova start VM01
# nova stop VM01

```

現状の仮想マシンの状態をイメージとして保存するとき

```
# nova image-create [指定のマシン] [イメージファイル名] 
# nova image-create VM01 VM01_Image 
```

保存したイメージをファイルとして保存するとき

```
# glance image-download --file [ファイル名] [イメージのID]
# glance image-download --file VM01_Image [VM01_ImageのID]
```

NWを作成するとき

```
# neutron net-create
```

サブネットを作成するとき

```
# neutron subnet-create
```

##参考資料
OpenStackクラウド基盤構築・ハンズオンセミナー講義資料
http://enakai00.hatenablog.com/entry/20140106/1388978670

OpenStackによる、実践オンプレミスクラウド
https://www.slideshare.net/thatsdone/q-con-tokyonttdataopenstackdist2?qid=3207b677-5c4e-4dc1-80de-c2ea356e1526&v=qf1&b=&from_search=9

OpenStack勉強会 ― slideshare
https://www.slideshare.net/obara13/open-stack-16166193?qid=3207b677-5c4e-4dc1-80de-c2ea356e1526&v=qf1&b=&from_search=4
macos spotlightのインデックス再構築（たびたび重い原因）

macを使っているとスポットライト（検索）がうまく検索されなくなることがある。多くの場合は、spotlightのためのindexが何らかの問題がある。

その場合は、以下の方法で、再構築できる。

ターミナルを開く。

一度、spotlight検索のインデックス化をやめる。
```$ sudo mdutil -i off /```
spotlight検索のインデックス化を再開。このときに再構築されるようだ。
```$ sudo mdutil -i on / ```

多分上の方法が確実だが、appleは以下の方法も紹介している。
（ターミナルが苦手な場合は、以下の方が、簡単かもしれないが、私はうまくいきませんでした。上の方法を推奨します。）

https://support.apple.com/ja-jp/HT201716
MacでNFDな文字列でもNFCにリネームしたい！

```ruby
path = "㌧㌦ベイビー.txt"

p nfd_path = path.unicode_normalize(:nfd)
p nfd_path.each_char.to_a
# => "㌧㌦ベイビー.txt"
# => ["㌧", "㌦", "ヘ", "゙", "イ", "ヒ", "゙", "ー", ".", "t", "x", "t"]

p nfc_path = nfd_path.unicode_normalize(:nfc)
p nfc_path.each_char.to_a
# => "㌧㌦ベイビー.txt"
# => ["㌧", "㌦", "ベ", "イ", "ビ", "ー", ".", "t", "x", "t"]

# ついでにnfkcも
p nkfc_path = nfd_path.unicode_normalize(:nfkc)
p nkfc_path.each_char.to_a
# => "トンドルベイビー.txt"
# => ["ト", "ン", "ド", "ル", "ベ", "イ", "ビ", "ー", ".", "t", "x", "t"]

# File.renameか何かリネームしてもよし
# File.rename(path, path.unicode_normalize(:nfc))
```

## ちゃんと知りたい人は

Unicode正規化 https://ja.wikipedia.org/wiki/Unicode%E6%AD%A3%E8%A6%8F%E5%8C%96
【初心者】CSS　復習／Flexbox【備忘録６】

## 10/20～10/21での復習

### 上級編の実践練習
- ＠media(max-width:1000px ){　　～～　   }
　上記のように書く際に、;を付けてしまったのが何度かあったので今のうちから変な癖がつかないように気を付ける。

- ページを作成する際に＜.top-wrapper＞や＜main-wrapper＞などで部分分けをしているが、＜.top-wrapper＞の＜btn＞部分だけ、幅を変更したいなどの場合の書き方を今まで認識していなかった。使用するタイミングがあるかと思うのでしっかり漏れなく覚えておく。

[ex]⇒.top-wrapper .btn{width:100%}


## 10/21～10/23で勉強したこと

### Flexbox
- まずは基本的に使用しそうな物のみ勉強。
- レスポンシブデザインで行ったような、タブレット／スマホでのアイコンの表示分けの際に簡単に書くことができるようなので、使いこなせるようにしていきたい。
- 基本的には親要素に⇒display:flex;　／　幅を伸ばしたい要素に⇒flex:auto;
- 折り返しで並べたい場合は親要素に追記で⇒flex-wrap:wrap;　／　折り返したい要素に⇒width:50%;
- スマホ表記などで１列表記にする場合親要素に⇒flex-direction:column;＜つづり注意！＞
　１列で表したい要素に⇒margin:0 auto;　でしっかり中央寄せに調整する。


## ふりかえり
- AtomをインストールしたのでGoogleで表示させながら何度か自分でオリジナルでページ作成を試していきたい。もう１つ、GitHubにも登録したのでページの使い方など触って慣れていこうと思う。
pythonで指定拡張子を一括移動

colabを使っていて、拡張子がpngやjpgといった画像ファイルを一括で移動させたかったので、書いてみました。

```move.py
import os
import shutil
import re

DIR = 'moved_dir' # 移動後のディレクトリ
EXT_LIST = ['.png',".PNG",".jpg"] # 移動させたい拡張子のリスト

# 移動後のディレクトリがなかったら作成
if not os.path.isdir(DIR):
    os.mkdir(DIR)

# 上のディレクトリにファイルを移動
for file_name in os.listdir(): # 現在いる場所のファイルやディレクトリをリストで取得（もっと効率のいい方法がありそう）
    for ext in EXT_LIST:
        m = re.search(r'.*' + ext, file_name) 
        if m != None:
          shutil.move(m.group(), INPUTDIR) # 各々の拡張子にマッチするファイル名があったら、移動させる
```

globのノリでワイルドカード使ったら、shutil.moveでは使えないんですね。

以上、個人的備忘録でした。
【備忘録】RecyclerViewで一覧表示されない 【AndroidStudio】


#RecyclerViewで実装したい画面
![8aeae633e6ae12a9e6deca30fc431e1b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463548/402d1b6c-d01b-c5ba-166e-b8e039be96d5.png)

↑このように
Item0
Item1
Item2 ... 
とRecyclerViewを一覧で表示したかったわけですね。

#そもそもRecyclerViewとは？
RecyclerView(リサイクラービュー)とはいったい何なのか。
それは、**一覧表示する際に使用するListViewの改良版**という認識でよいみたいです。
柔軟にリストを表示する機能ということですかね。

#失敗画面とその詳細、試してみたこと
![232cedbff78ac07b94668f8154a6ed75.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463548/0075c54f-a6b5-fb00-9f5e-b74749019219.png)
↑これが失敗していた画面です。
<dl>
<div align="center">主にやったこととしては</div>
<dd>・**Constraint Widgetの上下左右のMarginを0で引っ付ける。**</dd>
<dd>・**Layout_width Layout_heightをmatch_constraintに設定する。**</dd>
<dd>・**紐づいているkotlinファイルのソースコード内にあるonCreateメソッド内にAdapterクラスをぶち込む。**</dd><br>
といったところ。
</dl>

#RecyclerViewを詳しく調べて解決

どうやらRecyclerViewのクラス自体、処理していないらしい。。
どういうことかというと、RecyclerViewのサブクラスにそれぞれ役割が設定してあり、必要に応じてそれを使いなさいよ、ということらしい。

今回、一覧表示できていなかった原因はRecyclerViewのレイアウトを管理するLayoutManagerクラスを記述していなかったというとこにありました。

ということで、xmlファイルのTextに
<div align="center">
`app:layoutManager="androidx.recyclerview.widget.LayoutManager"`</div>
LayoutManagerクラスを追加して見事、一覧表示に成功した。という備忘録でした。
<br>
Laravelのphpunitでfactoryで作成したモデルにIDがなくて泣いた


## 概要
phpunitでテストを書いているときに、factoryでモデルを作ってそのIDを利用するみたいなコードを書きました。

```php
$user = factory(User::class)->create();
$id = $user->id;
```

しかしなぜかidがないよ！と怒られたり、idが0になっていたりしました。DBにはきちんと保存されているのに。

## 結論
モデルにはきちんと`incrementing`プロパティを指定しましょう。

## 説明
id(PK)は基本的にオートインクリメントになるように設定していると思いますが、テーブルによってはオートインクリメントしていないものもあります。

オートインクリメントしないモデルには`$incrementeng = false`を指定しましょう。（デフォルトでは`true`になっています。）

また、中間テーブルでオートインクリメントを指定している、かつ`Pivot`を継承している場合は`true`を指定しましょう。`Pivot`はデフォルトでは`false`に設定されています。

## 余談

なんでidが0になったりするかというと、`$incrementing`の値で処理を分けていて、

```php
if ($this->getIncrementing()) {
    $this->insertAndSetId($query, $attributes);
}

// If the table isn't incrementing we'll simply insert these attributes as they
// are. These attribute arrays must contain an "id" column previously placed
// there by the developer as the manually determined key for these models.
else {
    if (empty($attributes)) {
        return true;
    }

    $query->insert($attributes);
}
```

オートインクリメントのときはレコードをinsertした後に設定されたidを取得してくるという動作をしています。

`insertAndSetId`のなかに`insertGetId`という処理があり、最終的にPDOの`lastInsertId`というメソッドを呼んでidを取得しています。

`lastInsertId`というメソッド名だけ見ると、オートインクリメントじゃなくてもidを取ってきてくれそうですが、このメソッドはDBの種類によって挙動が変わるっぽいです。

mysqlだとauto_incrementが設定されていないとだめみたいです。

なので、idをオートインクリメントにしていないのにモデルが`$incrementing = true'の状態だと、`lastInsertId`が呼ばれますがidは0で返ってくることになります。(postgresは未検証)
Dockerをwindowsに設定する

#注
Windows10 Homeだとできません！
7や10 Homeの場合VirtualBoxを使いましょう。

#動機
Dockerを導入する練習をやりたい！Rubyの開発環境に導入したい！と思ったのでやってみることにしました。

#Docker Desktop for Windowsをインストールする
[DockerTop](https://hub.docker.com/)からDOCKER CEをインストール
会員登録終了後下記の通りインストールする
![InkedSnapCrab_Onboarding Tutorial - Google Chrome_2019-10-25_0-53-40_No-00_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515135/4ed6b9d0-55c1-8604-c1cf-76ea12308dff.jpeg)![InkedSnapCrab_Explore - Docker Hub - Google Chrome_2019-10-25_0-54-56_No-00_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515135/b9f1fc45-8bd7-8bc9-f3eb-ff81ed9be2be.jpeg)
![InkedSnapCrab_Docker Desktop for Windows - Docker Hub - Google Chrome_2019-10-25_0-55-13_No-00_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515135/74116d58-7c14-9595-7b9c-149984dadbf4.jpeg)
インストール中は特に設定を変えずにインストールします。

PowerShellで下記コマンドを実行してバージョンが表示されていればOKです。

```PowerShell.(管理者)
> docker -v
Docker version 19.03.4, build 9013bf5
```
#Hyper-Vをインストールする
必ず管理者として実行してください

```PowerShell.(管理者)
> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
```
終了後再起動します。

```PowerShell.(管理者)
> DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V
```
[Windows の機能の有効化または無効化] から
[Hyper-V] を選択して、[OK] をクリックします。

#コンテナ作成
Docker DesktopからSettingsを選択

使用するドライブを選択する
![SnapCrab_Settings_2019-10-25_1-24-41_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515135/4962c3c7-a11a-def2-c07a-65bc8d7d4bf7.png)

"experimental": falseを下記へ変更
![SnapCrab_Settings_2019-10-25_1-25-6_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515135/9de1a109-96a9-028f-890f-f868d281775b.png)

##Dockerイメージの導入（Ruby）
```PowerShell.(管理者)
> docker pull ruby:2.5.3
```
導入できているか確認する

```PowerShell.(管理者)
> docker image ls
```
###コンテナの作成
```PowerShell.(管理者)
> docker container run -it --name [コンテナの名前] -p [ホストポート番号]:3000 -v [ディレクトリパス]:/var/www/ ruby:2.5.3 /bin/bash
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Mount denied:
The source path "C:/Users/user/Documents/src"
doesn't exist and is not known to Docker.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'
```
エラーが発生しました…ssh側のディレクトリは自動的に作成してくれるんですが、Windows側のディレクトリは自分で切らなくてはならないそうです。
The source path "C:/Users/user/Documents/src"に記載されているディレクトリを切れば実行できます。

```PowerShell.(管理者)
> mkdir C:\Users\user\Documents\src"
```
####再度実行！

```PowerShell.(管理者)
> docker container run -it --name [コンテナ名] -p [ホスト側ポート]:3000 -v [ディレクトリパス]:/var/www/ ruby:2.5.3 /bin/bash
Unable to find image 'ruby:2.5.3' locally
2.5.3: Pulling from library/ruby
hogehoge: Pull complete                                                                                                                                                                                         Digest: sha256:hogehoge
Status: Downloaded newer image for ruby:2.5.3
root@hoge> 
```
成功しました！！

#Dockerfileを取り込む
拡張子無し、ファイル名「Dockerfile」でファイルを作成

```PowerShell.(管理者)
> docker build [ディレクトリパス]
```
これで成功しました！

拡張子あり、ファイル名適当だと登録できませんでした。

#最後に
個人的にVagrantやVirtualBoxより設定しやすかったです。
これからどんどんDockerを使っていこうと思います！
[SwiftUI]ビューのデフォルトの挙動を変更する

例えば、UITableViewは`keyboardDismissMode`というオプションがありこれを指定することでスクロールするとキーボードを隠すことができるようになったりします。
しかし、SwiftUIでは`keyboardDismissMode`のようなOSに依存したパラメータはほとんど無いため設定することが出来ません。
`UIViewRepresentable`などでUIKitをラップして使えるようにするなど工夫の余地はありますが、SwiftUIの利点を失う事とトレードオフであることもあります。

そこで、SwiftUIもiOS13の世界ではUIKitをビューとして利用している点を利用してMethodSwizzleでデフォルトの挙動を差し替えてみましょう。

```swift
extension UITableView {
    static var nfs_DefaultKeyboardDismissMode: KeyboardDismissMode = .none
    
    static func setDefault(_ mode: KeyboardDismissMode) {
        nfs_DefaultKeyboardDismissMode = mode
        let from = class_getInstanceMethod(UITableView.self, #selector(getter: UITableView.keyboardDismissMode))!
        let to = class_getInstanceMethod(UITableView.self, #selector(getter: UITableView.nfs_keyboardDismissMode))!
        method_exchangeImplementations(from, to)
    }
    
    @objc var nfs_keyboardDismissMode: KeyboardDismissMode {
        UITableView.nfs_DefaultKeyboardDismissMode
    }
}
```

これをAppDelegateなどのUIKitをimportしているところで

```swift
UITableView.setDefault(.interactive)
```

といった具合に呼べばアプリ全体のUITableViewの挙動が変わるはずです。
個別に指定できませんが、全体で変わっても良さそうなものならこのような手を使ってUXを変えることもできます。
サーバに JupyterHub をインストールして複数名で使えるようにする

# やりたいこと

リモート (AWS とか Azureとか) に1台のサーバを立てて、
その中で複数名で同時に Jupyter Notebook を使えるようにしたい。
それには JupyterHub が使いやすいらしいので試す。



# やったこと
### 1. JupyterHub のインストール
以下のページを参考にした
https://medium.com/hi-optimus/how-install-optimus-and-jupyterhub-on-digital-ocean-1f80b7d143a3

ただし、システムにインストールしたいので、`npm` と `pip3` のコマンドのところには `sudo -H` を付けて実行した。
これで、 `/usr/local` にインストールされる。

その後、サーバの 8000ポートの接続を許可し、リモートアクセスを許可するため、
`/etc/jupyterhub/jupyterhub_config.py` のファイルの `bind_url` を以下のように変更する。

```python

c.JupyterHub.bind_url = 'http://0.0.0.0:8000'
```

### 2. ユーザの作成
ターミナルから、サーバにユーザアカウントを作っておく。
これが JupyterHub のログインIDとパスワードになる。


# 注意すること

これらは注意すべきだが、この記事では扱わない。

* どこからでもアクセスできるので、アクセス制限が必要。
* HTTP でデータは暗号化されないので、HTTPSにするとか、VPN を通すとかの対策が必要。

# 参考ページ
https://medium.com/hi-optimus/how-install-optimus-and-jupyterhub-on-digital-ocean-1f80b7d143a3
https://github.com/jupyterhub/jupyterhub/issues/394
要素を中央に配置したいときのサムシング

HTMLの要素を中央に配置したいときって度々ありますよね

そんなとき私がよく使用する方法を紹介します！

```html
<div class="parent">
  <div class="child"></div>
</div>
```

```css
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
```

以上！

<img width="206" alt="スクリーンショット 2019-10-21 15.11.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174833/2b26d908-276b-3656-80bd-d23639e49bfc.png">


# 解説

`top`や`left`は親要素を基準に計算します

```css
left: 50%;
```

<img width="210" alt="スクリーンショット 2019-10-21 15.04.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174833/8cb1db58-2ac6-23d1-f99c-d4fe6ccce10d.png">

それとは対照的に、`transform: translate()`は自身を基準に計算します

```css
transform: translateX(-50%);
```

<img width="257" alt="スクリーンショット 2019-10-21 15.04.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174833/82cf6eaa-042d-9f36-80b2-d44f63e5439b.png">

これを組み合わせることでセンタリングを実現しているわけです！


[CodeSandbox](https://codesandbox.io/embed/demo-element-centering-vb3nn)

いろいろな制約により使用できない場合はありますが、

お役に立ったら嬉しいです！
【隣接行列】令和元年秋期　基本情報技術者試験　午前問３の解き方

# きっかけ
今年の基本情報技術者試験に隣接行列の問題が出題されました。
ちょうど読んでいた[蟻本](https://www.amazon.co.jp/dp/B00CY9256C/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1"蟻本")にグラフの説明が載っていたので、まとめてみました。

# グラフとは
物や状態といった対象同士の結びつき方を表すための表現法。
グラフは頂点（ノード）と辺（エッジ）からなります。

辺に向きがないグラフを無向グラフ、辺に向きがあるグラフを有効グラフといいます。

![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338556/544a6d2d-feab-3d98-7c60-6902d219e6e3.jpeg)


#隣接行列と無向グラフ
隣接行列では｜V｜×｜V｜の二次元配列ｇでグラフを表現します。g[i][j]はi番目の頂点とj番目の頂点の関係を表すことができます。

無向グラフの場合は「i番の頂点とj番目の頂点が辺で結ばれているか」の情報さえあればいいので、g[i][j]とg[j][i]の値を頂点iと頂点jが辺で結ばれているなら１、そうでなければ０となることで無向グラフを表現します。

有向グラフでは頂点から頂点へ方向を表すため、g[i][j]＝g[j][i]とはならない。
⇒無向グラフではg[i][j]＝g[j][i]となります。
行列に対角線を引くと対象になり、同じ内容になります。


例　4×4の隣接行列

|i \ j |1  |2 |3 |4 |
|---|---|---|---|---|
|1  |0  |1  |0  |0  |
|2  |1  |0  |1  |1  |
|3  |0  |1  |0  |0  |
|4  |0  |1  |0  |0  |

例　上記の無向グラフ

![無向グラフ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338556/c5c6fe73-0c20-f243-6804-0958a6a6f691.jpeg)

#令和元年秋期　基本情報技術者試験　午前問３　
【問題】　
　ノードとノードの間にエッジの有無を、隣接行列を用いて表す。ある無向グラフの隣接行列が次の場合、グラフで表現したものはどれか。ここで、ノードを隣接行列の行と列を対応させて、ノード間にエッジが存在する場合は１で、エッジが存在しない場合は０で示す。

![mondai2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338556/248d3d63-6798-cd22-2edc-cced61067b94.jpeg)

【解き方】
左からノードの繋がりを確認して、不正解を除外していく。
・[b][c]=[c][b]=1、[b][d]=[d][b]=1より、ノードｂはノードｃとｄに繋がっている。
　⇒　選択肢：ア　不正解
・[c][d]=[d][c]=1、[c][e]=[e][c]=1より、ノードcはノードｂ以外にｄとeに繋がっている。
　⇒　選択肢：イ　不正解
・ノードｄはｂとｃ以外に繋がりはない。
　⇒　選択肢：エ　不正解

　⇒　答え　選択肢：ウ

# 読んでいた本
[プログラミングコンテストチャレンジブック [第2版]](https://www.amazon.co.jp/dp/B00CY9256C/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1"プログラミングコンテストチャレンジブック [第2版]")

# 最後に
前回より間が空きましたが、今回が２回目の記事になります。
時間があれば、実際にプログラミングをしてから記事を加筆します。

記事の内容に誤りや問題等がありましたら、訂正します。

よければコメントお願いします。
[tensorflow]データセットの読み込み時のエラー対処

#エラー内容(EOFError)
以下のコードの実行時に

```python
from keras.datasets import fashion_mnist
(x_train, t_train), (x_test, t_test) = fashion_mnist.load_data()
```

以下のエラーが発生した.
EOFError : Compressed file ended before the end-of-stream marker was reached

#対処法
[参考]https://stackoverflow.com/questions/40877781/eoferror-compressed-file-ended-before-the-end-of-stream-marker-was-reached-mn

これはデータセットからのfasion mnistのダウンロードが, 何かしらの理由で不完全に止まってしまい, 中途半端なものがダウンロードされていることに原因があるようだ. 

そこで, ターミナルで以下のコマンドを打つ(mac環境).



```
cd ~/.keras/datasets/
ls                    # ディレクトリfashion-mnistが表示されているはず.
rm -r fashion-mnist   # これをディレクトリごと消去する.
```
これを実行すれば, データセットからのfasion mnistのダウンロードが可能になる. イメージとしは, 不完全にダウンロードしたfasion mnistを全て消去して, その上で再び１からダウンロードをすれば良い.
【Rails】 Kaminariを使ってページネーションの実装手順

## 環境
Rails 5.2.3
Ruby 2.6.5

## 実装済みイメージ
<img width="584" alt="Screen Shot 2019-10-25 at 9.12.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519582/22ad8554-4cee-d0e8-7eb2-7705b5340531.png">

## 手順
###Gemをインストール
```ruby:Gemfile.rb
gem 'kaminari'
```

```terminal:terminal
$ bundle
```

### ページ数を指定する
##### 方法１：モデルで設定します。
```ruby:app/models/blog.rb
class Blog < ActiveRecord::Base
  paginates_per 10
end
```
```app/controllers/blogs_controller.rb
class BlogsController < ApplicationController
  def index
    @blogs = @blogs.page(params[:page])
  end
end
```
##### 方法２：コントローラーで設定します。
```ruby:app/controllers/blogs_controller.rb
class BlogsController < ApplicationController
  PER = 10

  def index
    @blogs = Blog.page(params[:page]).per(PER)
  end
end
```

### Viewを編集する
```ruby:app/view/blogs/index.html.erb
<%= paginate @blogs %>
```

### 日本語化する
```ruby:config/locales/ja.yml
ja:
  views:
    pagination:
      first: "&laquo; 最初"
      last: "最後 &raquo;"
      next: "次 &rsaquo;"
      previous: "&lsaquo; 前"
      truncate: "&hellip;"
```

### Bootstrap 4を導入する
以下のコマンドを実行すると、viewファイルを自動的に作成します。
erb以外にhamlとslimも指定できます。

```terminal:terminal
$ rails g kaminari:views bootstrap4 -e erb
```

<img width="220" alt="Screen Shot 2019-10-25 at 9.20.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519582/21676e97-aae0-ac2c-862a-4edecd7f50dd.png">

###　参考文献
https://github.com/kaminari/kaminari
https://github.com/amatsuda/kaminari_themes
VPSに ssh出来ないときやることメモ

CentOSに急にsshできなくなったと言われ調べたときのメモ
不適切な点がありましたらご指摘お願いいたします

# サーバーの起動確認
サーバー料金払い忘れていて止まっているかもしれません。

#sshにオプションを付けてデバッグ

```
ssh 〇〇　-v
```

出るメッセージを翻訳&ググる

#sshdの起動確認
基本的にコンソールがVPSの管理画面にあるはずなので、そこから

```
sudo systemctl restart sshd.service

sudo systemctl status sshd.service
```
を実行する。

失敗している場合、sshd_configの記載にエラーがないか確認

```
/usr/sbin/sshd -t
```

何も表示されなければ問題ない

エラーの確認、ログの確認

```
journalctl -xe

/var/log/messages

/var/log/secure
```

パーミッションをデフォルトから変えていないか
`chmod -R 777 /etc`とかで間違って変更してしまった場合も起動に失敗する
<details><summary></summary>
chmod 440 /etc/sudoers
chmod 440 /etc/sudoers.d/README
chmod 755 /etc/sudoers.d
chmod 640 /etc/shadow /etc/gshadow
chmod 600 /etc/ssh/*_key
chmod 600 /etc/ssh*key
chmod 710 /etc/ssl/private
chmod 710 /etc/cups/ssl
</details>
`ssh`で影響あるものをデフォルトに戻してみる

```
sudo chmod 600 /etc/ssh/*_key
```

セキュリティ上微妙だが
`/etc/ssh/sshd_config`の
`ChallengeResponseAuthentication`の行をコメントアウトする

#firewallの確認

```
sudo firewall-cmd --list-all
```
ポートが開かれているか


結局今回は`etc`配下に`-R`で`chmod`していた模様
【勉強用】VirtualBoxを利用した仮想環境の構築を初心者視点から

##免責事項
この記事は初心者視点でザックリとした説明をしています。正確性に欠ける可能性がございますが、ご了承ください。「明らかに違うよ」ということがありましたら、ご指摘くださると幸いです。

##環境
OS：最新版ではないMacOS
VirtualBox：5.2.26
Vagrant：2.2.6
Ubuntu：ubuntu/bionic64 v20181129.0.0


##目次
1. 仮想環境とは
2. VirtualBoxとは
3. Vagrantとは
4. 仮想環境の構築（Linuxの構築）
5. Ubuntuの操作

#1. 仮想環境とは
仮想環境とは簡単に言えばあるコンピューターの中に仮想的に作られた別のコンピューターのことです。

例えば、「MacでWindowsを利用したい！」と思ったらWindows用のPCを買ったりしないといけません。
しかし、また新しいPCを買うのは金銭的に負担になります。
そこで、今使っているMacの中にWindowsを利用できる環境を仮想的に作り出すことで、その負担を減らすことができます。
（チーム内で開発用のPCとしてWindowsを使っている人とMac使っている人がいる場合でも、同じ環境（OS）などの仮想環境でプログラムを実行するようにすると便利ですよね。）

このようにPCの中に仮想的に別のPCを作りたいときは、仮想環境構築ソフトを使います。今回はVirtualBoxという仮想環境構築ソフトを使います。

#2. VirtualBoxとは
VirtualBoxはメジャーな仮想環境構築ソフトの1つです。オラクルというアメリカの大きな会社が作っています。Windows、Linux、MacOSに対応しています。無料で使うことができます。

###VirtualBoxのインストール
インストールについては日本語で解説しているサイトがあるので、参照してみてください。

VirtualBoxのインストールが終わったら、Vagrantという仮想環境の構築・管理を簡単にしてくれるソフトウェアもインストールしましょう。
Vagrantがなくても仮想環境は作れますが、Vagarantを使うと初心者でも簡単に仮想環境を使うことができるようになります。

#3. Vagrantとは
Vagrantは先ほども説明しましたが、仮想環境の構築・管理を簡単にしてくれるソフトウェアです。構成情報を設定ファイル (Vagrantfile) に記述すれば、仮想環境の構築から設定までを自動的に行ってくれるので、仮想環境の立ち上げがすごく楽になります。

###Vagrantのインストール
インストールについては日本語で解説しているサイトがあるので、参照してみてください。

#4. 仮想環境の構築（Linuxの構築）
VirtualBoxとVagrantのインストールができたら、仮想環境の構築はすぐにできます。VirtualBoxの操作はターミナル/コマンドライン等のCLIで行います。今回はMacでLinuxを立ち上げていきます。

###①Linuxを立ち上げるためのディレクトリの作成

```
//mkdirで新規ディレクトリを作成
//-pで親ディレクトリがない場合は親ディレクトリも一緒に作成
mkdir -p ~/vagrant/Linuxを起動するディレクトリ
//cdでLinuxを起動するディレクトリ上に移動
cd ~/vagrant/Linuxを起動するディレクトリ
```
Linuxを起動するディレクトリの名前はなんでも良いです。

###②Ubuntu（Linuxディストリビューション）をインストール
まず、Linuxディストリビューションとして、Linuxを起動するディレクトリにUbuntuをインストールします。
※コンソールから Vagrant を実行して Ubuntu をダウンロードし、仮想環境にインストールしています。

```
vagrant box add ubuntu/bionic64 --box-version 20181129.0.0
```
 次に、以下のコマンドで仮想マシンの設定ファイルを作成します。

```
vagrant init ubuntu/bionic64
```
次に、以下のコマンドでUbuntuを起動します。

```
vagrant up
```

コンソールに、”Machine booted and ready!”という文字が発見できたらインストールの完了です。

お疲れ様でした。

#5. Ubuntuの操作
Ubuntuを操作するにはいくつか方法があります。
今回はSSHという通信プロトコルを使いターミナルで操作します。
※VirtualBoxにはGUIの機能もあります。

ちなみにSSHとは、リモートコンピュータと通信するためのプロトコルです。認証部分を含めネットワーク上の通信がすべて暗号化されるため、安全に通信することができます。
SSHを利用して遠隔のコンピューターと接続する場合、SSHクライアントと呼ばれるソフトウェアが必要です。Macには標準で搭載されており、以下のようにコンソールから利用できます。

```
vagrant ssh
```
以上のコマンドでVagrantが管理する仮想マシンの情報がセットされた状態でSSH接続されます。

sshを終了するときは、

```
exit
```
vagrant（仮想環境）を終了するときは、

```
vagrant halt
```



##補足（Ubuntuの日本語化について）
```
//スーパーユーザで日本語環境を作成
sudo locale-gen ja_JP.UTF-8
//起動時に日本語環境の設定で起動される
echo export LANG=ja_JP.UTF-8 > ~/.profile
//sourceコマンドで設定をいますぐに反映
source ~/.profile
//タイムゾーンを日本時間に設定
sudo timedatectl set-timezone Asia/Tokyo
```


##参考
「N予備校 プログラミングコース」
https://www.nnn.ed.nico/
「「仮想環境」とは何か？メリットや仮想マシンについても解説」
https://biz.trans-suite.jp/12393
「Mac で Windows を使う6つの方法」
https://pc-karuma.net/how-to-run-windows-on-mac/
「【初歩の初歩】Vagrantのインストールと使い方を簡単解説」
https://eng-entrance.com/linux-vagrant-install
「Vagrantって流行ってるらしいけど何が便利なの？」
https://dev.classmethod.jp/server-side/virtual-box-vagrant/
「用語集｜SSH」
https://www.idcf.jp/words/ssh.html
CentOS ソースからインストールしたPostgreSQL削除及び別バージョンインストール

centosにおいて都合によりソースインストールしたアプリケーション(PostgreSQL,Apache,php等)を削除別バージョンをインストールする際の削除処理と再いインストール処理のメモ
PostgreSQL削除
pgAdmin等で存在するデータベース削除
ソースディレクトリーへ移動Makefiles存在確認
cd /usr/local/src/postgresql-8.1.1
make uninstall
今回の場合/usr/local/pgsql/dataを削除
rm -rf /usr/local/pgsql/data
./configureからやり直し
cd postgresql-8.1.1
./configure --enable-multibyte=EUC_JP --without-readline --without-zlib
make
make install
su - postgres
initdb -E EUC_JP --pgdata=/usr/local/pgsql/data
postmaster -D/usr/local/pgsql/data -S -i
exitしてrootに戻りpg_hba.confとpostgresql.conf等設定
cd /usr/local/pgsql/data/
vi pg_hba.conf
vi postgresql.conf
ここでlinux再起動するがapacheが起動できない！！
phpとの依存関係でphpも再インストール
phpも./configureからやり直し。
MySQL Read Replica に対して負荷をかけてオートスケーリング動作を確認する

# モチベーション

Amazon RDS (ここではAuroraを選択) のリードレプリカに対するオートスケーリングが正常に動くかどうかを確認するためにリードレプリカに対して負荷をかけたい。
ぱっとぐぐってもピンとくるものがなかったのでメモ。

# 方針

[Sysbench](https://github.com/akopytov/sysbench) を利用して、以下の方針で負荷をかける。

1. マスターDBに対してテスト用データを書き込む (リードレプリカには書き込んだ直後にコピー・反映される）
2. リードレプリカに対して読み取り専用の負荷試験を行う

インストール手順は上記 Github を参照してください。

# 手順

各種DBツールはインストールしているものとします。 DBは今回はAurora 5.6互換を利用しましたが、それ以外のバージョンでも行けるはずです。
DB接続時のユーザーはデータベースとテーブルを作れる権限を持っていることを前提とします。

```bash
# DB作成 (パスワードはコンソールに入力)
$ mysqladmin create benchmark -u <接続ユーザー> -p -h <マスターDBのホスト名>
# テストデータ挿入 (oltp_read_write 部分は 
# oltp_read_only でも oltp_write_only でも OK) 
$ sysbench --db-driver=mysql /
    --mysql-host=<マスターDBのホスト名> \
    --mysql-user=<接続ユーザー> --mysql-password=<接続パスワード> \
    --mysql-db=benchmark oltp_read_write prepare

# 負荷テストをリードレプリカに対して readonly で実施
# 同時接続数32, 負荷時間300秒
$ sysbench --db-driver=mysql /
    --mysql-host=<リードレプリカのホスト名> \
    --mysql-user=<接続ユーザー> --mysql-password=<接続パスワード> \
    --mysql-db=benchmark oltp_read_only run \
    --threads=32 --time=300

# 不要な場合、終わった後は該当テーブルを削除
$ mysqladmin drop benchmark -u <接続ユーザー> -p -h <マスターDBのホスト名>
```

# 実施結果

t2.small 1台のリードレプリカに対してCPU利用率50%程度まで上昇し、スケールアウトすることと、負荷が無くなってからしばらくたつとスケールインする両方を確認できました。
【Chrome】Slackのリアクションボタンが小さすぎて不満だったからChrome拡張機能の開発練習がてらに、くそでかボタンにしてみた。

#はじめに
自身の備忘録として記事の投稿をしました。
内容は大したことないですが、めちゃくちゃ簡単なので、エンジニアじゃない方でも、少しだけHTML周りが分かるよという人であればすぐに業務効率に導入できると思います。
#なぜでかくしようと思ったか。
まずは下図を観てください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/cbbf24eb-92b5-068d-59f7-7123c728e8dd.png)
私が敬愛するFF14のプロデューサー吉田Pのリアクションがこんなに小さいなんてことあります？
吉田Pの隣はサーバルちゃん、さらに隣がうんこくんです。
小さすぎる。
不満すぎてでかくしてやろうと思った。
これだけです。
この後紹介しますが、プラグインの中身は本当に大したことしてません。
最終的には拡張機能により下図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/003d3773-2b03-4ae2-f9e7-a9a7faa026ba.png)
満足。


#■開発しよう
###1.フォルダ作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/e63cf5a6-c585-efaa-6fdd-670df358c4ba.png)

###2.「manifest.json」ファイルを作成
```manifest.json
{
  "manifest_version": 2,
  "name": "Slackリアクションボタンくそでか",
  "version": "1.0.0",
  "description": "Slackのリアクションボタンをめっちゃでかくするプラグインです。",
  "content_scripts": [{
    "matches": ["https://app.slack.com/client/*"],
    "css": ["style.css"]
  }]
}
```
上記のように最低限の設定をします。
文字コードはUTF8で保存先は1で作ったフォルダ直下に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/8ba934ca-5711-fb0b-c172-d70095a4f8cd.png)

###3.「style.css」ファイルを作成
```style.css
/*ボタンを糞でかにする*/
.c-reaction_bar {
    zoom:2.0;
}

/*ボタンに影を付けてそれっぽくする*/
.c-reaction, .c-reaction_add {
    box-shadow: -2px -1px 2px grey;
}
.c-reaction--reacted{
    box-shadow: 2px 1px 4px 2px #ccccccbf inset !important;
}

```
ボタンの表示コンテナをでかくして、ついでにボタンっぽくちょいと加工。
こちらも文字コードはUTF8で保存先は1で作ったフォルダ直下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/1095f658-beeb-b832-a082-ec7aee3b6cce.png)

開発はこれで完了です。

###4.プラグインをChromeにインストール
URLバーに`chrome://extensions/`を入力して拡張機能画面を表示。
右上ののデベロッパモードをONにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/17add76d-dcd4-8aba-eee5-4826bff5e0e9.png)

手順１で作成したフォルダをこの画面にドラッグ＆ドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/e852c28d-1115-66b3-b86f-583bf3d25492.png)
インストールが正常に完了したら下図のようになります。（左上）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/ff3795e3-1bae-3427-347b-f69ee51745e2.png)
これですべて完了。

#おわりに
めちゃくちゃ簡単に作れたので、私自身びっくりしています。
今度はJSでガチャガチャしてみようかなと思ってます。
Trusted Proxy とは

## Trusted Proxy とは

Truested Proxyを設定することでProxyを介した際の、正しいURLの生成、リダイレクト、セッションハンドリング、ロギングが可能となる。

### プロキシが背後のサーバに伝達するためのHeaderについて

ロードバランサなどのプロキシを介すと、その背後にあるサーバは元のリクエストがどのようなものだったのか具体的にわからなくなる。そのため、プロキシはデファクトスタンダードである`X-Forwarded-*`ヘッダを用いて、背後のサーバに元のリクエスト情報を伝達する。

- X-Forwarded-For - クライアントのIP
- X-Forwarded-Host - クライアントによってブラウザにアクセスされた際のホスト名
- X-Forwarded-Proto - クライアントによって指定されたスキーマやプロトコル（http/httpsなど）
- X-Forwarded-Port - クライアントによって指定されたポート番号（80/443など）

プロキシによってはすべてのヘッダーを設定してくれるわけではない。例えば、AWS ELBの場合`X-Forwarded-Host`は取得できない。

## それを使わない場合どのような問題が起き得るのか？
サーバの前段にプロキシがある場合、アプリケーションが以下の問題に陥ることがある。


- リダイレクトやサーバサイド言語が発行したURLが、アドレス、プロトコル、そしてポートなどの点において不正確となる
- 個別のセッションが各ユーザに作られなくなり、不適切なアカウントへのアクセスや、ログインができないことが起こり得る
- ロギングや他のデータ収集処理において、プロキシからの情報のみが伝達され、個別のクライアントからのトラフィックやアクションが区別できなくなる


## 例えば、Laravelにおいて

Laravel 5.5以降においてはデフォルトで同梱されており、外部ライブラリなどは必要としない。設定も簡単である。以下参照。
https://readouble.com/laravel/5.8/ja/requests.html#configuring-trusted-proxies

例えば、AWS ELBの場合は特別な設定がある。


>Tip!! AWS Elastic Load Balancingを使用している場合、$headersの値はRequest::HEADER_X_FORWARDED_AWS_ELBに設定する必要があります。$headersで使用する内容の詳細は、Symfonyのtrusting proxiesドキュメントを参照してください。

また、クラウドサービスなどを使っている場合は、ロードバランサのIPアドレスが変化することがあるため、本来プロキシのIPアドレスを設定する場所でアスタリスクを設定する。アスタリスクが二つになると、最も近いプロキシだけでなくすべてのプロキシを信頼する。

```php

<?php

return [
     'proxies' => '*',
];
```


5.4以前のバージョンは以下を使う。
https://github.com/fideloper/TrustedProxy
超初心者がLaunch screens may not have triggered seguesと出た時の対処法

まずはじめに私は初心者であるため参考にならないであろうことを断っておきます。
優しい方々は間違いを指摘していただけると大変助かります。

##きっかけ
某〜インストールというプログラミング学習サイトで " iPhoneアプリ開発入門 " の９つ目の
" セグエで画面遷移させてみよう " という動画を見ながら言われた通りにやっていたにも関わらず、
エラーが出てきたため

その動画の更新日が2017年5月18日であるため、動画のバージョンが
xcode 8.3 / Swift 3.1
であることで少々仕様が異なることも要因の一つだと考えられる
　　
現在私が使用しているバージョン　　※（2019年10月25日現在）
xcode 11.1 / Swift 5.1.1

<img width="271" alt="スクリーンショット 2019-10-24 23.58.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416413/fde921a8-c9e9-29a4-d0d2-b7cd332c88c9.png">
このようなエラーが出る

##改善方法

こちらのチェックを外すことでエラーは改善できました
<img width="260" alt="スクリーンショット 2019-10-25 0.02.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416413/36e83e7d-fbf2-0d17-2977-84d577f25e83.png">

###参考
[Xcode初心者Run時のエラーまとめ](https://qiita.com/gojin1107/items/5adbc39cbe5a921ceb28)


###最後に
稚拙な文章で申し訳ありません。
多くの方の参考にはならなかったと思います。
拝読いただきありがとうございました。