OmniAICreator/Qiita-1.07M huggingface dataset:
Alibaba Cloud MVP Global Summit 2019 参加報告

こちらはMVP Global Summitの報告になります。Apsara Conference自体の報告は別記事として掲載予定です。


## Alibaba Cloud MVP Global Summit とは

アリババの年次大会である云栖大会(Apsara Conference)の前日に開催される
世界からアリババクラウドMVPが集う会合です。
参加者は８０名ほど、その殆どが中国人ですが外人も２０名弱が世界各地から。。
今年はアリババクラウドさんに自分もMVPに選出いただき自分も参加させて頂きました。
<A HREF=https://www.alibabacloud.com/blog/alibaba-cloud-mvps-at-the-apsara-conference-2019---leading-sharing-and-changing_595422 target=_blank>公式レポートはこちらから</A>。それで十分足りそうですから個人的に感じたことを書き綴ります。


## キャンパスの中で開催

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/02b7d46c-7456-a3de-e0d2-4c0ae073b471.jpeg)
入り口は普通にキャンパスの中。
どや顔をして入ります。
中に入ると。。

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/eb0530bd-e5cc-e986-9c71-545d7582506d.jpeg)
アリババクラウドとMVPの歴史が書かれた大看板が。
MVP制度が開始されまだ２年ほど。これから発展していくようです。

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/98aa0a08-84f7-9ab8-0977-1d9c68daa6e4.jpeg)
カンファレンスは基本的に中国語で行われます。
こちらの西洋人MVPもなんと流暢な中国語を話していました。
我々も負けてはいられません。精進せねば。。

![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/6dfe838a-01f0-d831-e2fb-71260c734a9d.jpeg)
テーマは自由でMVP各人がそれぞれ話したい事を語ります。
中国はIoT先進国で中国人のMVPからは彼らが自ら手がけた産業用IoTの話をされていました。

時が過ぎるのは早く、夜になったら晩餐です。
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/28c9c7a0-7c96-4734-8467-ada67acc4f5e.jpeg)
なにやら看板は豪華なのですが。。

![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/8a72ae2e-6eee-ea81-1f18-d58644e5a779.jpeg)
会場はなんと社員食堂。
普通にみんなで並んで食事を取り食べました。

そんな中、中国らしいのを発見。
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/c3ff065d-e09f-5b9f-2882-642a11feebf6.jpeg)
なんとその場で麺を作っています。
なかなか入る機会のない社員食堂、これはこれで楽しめました。


## サービス開発者とのラウンドテーブル

カンファレンス期間中の夜、ラウンドテーブルが設定されます。
その前に、飯。
![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/87211ed6-f355-036f-d44c-66b98f35b7a6.jpeg)
同じキャンパス内なのですが今回は広めの場所でした。
フードコートのようになっていて他にも店が並んでいます。
![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/7de01d32-e5db-3a93-e49b-5515e17155f0.jpeg)
食べ終わったら教室へ。

![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/39177dfe-c8cd-588d-b6ca-e49cf3290cc4.jpeg)
これがMVPとして一番のベネフィットでしょう。
各サービスの開発者が座っているテーブルへ自由に座り、質問をしたり想いを伝えたりできます。

![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/b29fbe26-7b0c-1dc9-d53a-0f1c87e3a863.jpeg)
各テーブル共に盛り上がり、２時間半の時はあっという間に過ぎました。


## MVPインタビュー・ウェビナー

希望者はインタビューを収録したりウェビナーを開催出来ます。
自分も最初は希望したのですが英語のみと知り断念。
海外向けのコンテンツらしく中国語ではだめらしいです。。
しかしです。来年は通訳を用意することを検討してもらえることになりました。
自分の戯れ言が英語になって拡散される日は近い！？


## MVP VIPブースツアー
MVP向けに英語の通訳付きで展示ブースを回るツアーが開催されました。
![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/c64376b6-8ceb-209a-7277-8e0cb2dc75a4.jpeg)
自分は日本からのツアー参加者のアテンドで参加できず。次回こそ！



## トイレにて
![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/90871665-9a12-0582-ab9c-c563095c3197.jpeg)
なかなか良い事が書かれています。
アマゾンのリーダーシッププリンシプルに通ずる物が有りますね。
やはり良い企業は皆良い行動規範を持っているようで。


## まとめ

サービス開発者と直接対話する機会があるのは大変良いです。
例えばAWSではそのサービスの重要顧客になればEBCという会議を設けてもらえますが通常は話す機会などありませんからね。
来年もAlibaba Cloud MVPとして参加できるよう精進したいと思います。
ads.txtが含まれていないサイトがありますと出た時の対処法

Googleアドセンスで下記のようなエラーが出た場合の対処法を解説します。
> 要注意 - ads.txtが含まれていないサイトがあります。収益に重大な被害が出ないよう、この問題を今すぐ修正してください。
>> Google Adsense

## ads.txtを作成する
メモ帳かテキストエディタを開き、ads.txtという名前のファイルを作成します。

```txt:ads.txt
google.com, pub-0000000000000000, DIRECT, f08c47fec0942fa0
```
pub-0000000000000000の部分には、ご自身のGoogleアドセンスのサイト運営者 IDを記述してください。

## アップロードする
サイトのURLのpublic_htmlの直下に先ほど作成したads.txtをアップロードして対処完了です。
時間を置くとエラーが消えます。
ゼロから始めたAWS認定 Xxx アソシエイト 教材メモ

# 目的

AWS認定試験を３つやっと取れました。
これらの資格の対策において学習及び対策で使用した（している）情報をまとめる。

未経験者でも勉強すれば取れる！というのは残しておきたかった。
基本土日オンリーで学習しておりました。

## 取得した資格

- SAA(ver C01) 2ヶ月 : score 836
- SOA(ver C01) 1ヶ月 : score 794
- DVA(ver C01) 2ヶ月 : score 805

# Iam...

System Engineer !
But, I have never used CloudService before.

Q. Why are you studying for a certification exam.
A. I was very free on Saturday & Sunday.

# これから取得する人へ

どこかでSAAが一番難しいと言われてたけれども**SAAが一番楽**。
簡単・難しいではなく**「楽」**である。

理由は日本語の情報が結構有るため。
残りの2つは日本語の教材はほぼ無いと思って良い。(私は見つけられなかった）

全く触ったことが無い人であればまずはSAAを取得を目指し、その過程でAWSを触って楽しんで下さい。
その楽しみがこの先の残り2つの支えになります。

教材メインでやっていて、一応 black belt. white paperは読まなくても取れている。
比較的お金をかけていると思われるけれどもまずはレールに乗りながらやった方が初心者には良いと思う。
（クラスルームが一番お金かかる...これは最終手段...）

# 教材情報

私はこれで資格取得出来た。
Qiitaで色々情報を下さった様々な方に感謝です。**(:DTZ**

## 対 AWS 認定ソリューションアーキテクト – アソシエイト

大体２ヶ月で取得。内訳は以下。

- AWS学習（ハンズオン&書籍) : １ヶ月
- 問題集 : １ヶ月

私は以下の教材で取得できた。

### ハンズオン教材

私と同様に触ったことない人はまずは触ろう。
触ってから勉強した方が吸収率が良いと思う。

ただ、**試験勉強が上手い人は触らなくてもSAAは取得出来る**と思う。
個人的には資格勉強と実体験が欲しいので推奨。

Q&A見れば判るけれども模擬問題は割り切り。

[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（初心者向け21時間完全コース）](https://www.udemy.com/course/aws-associate/)

### 書籍

ハンズオンと平行してこの書籍を見ていた。
どちらかというと復習に近く、「これ進研ゼミに出てた！」的な感じだった。
ハンズオンで実施した内容の復習に読むと良いと思う。

[AWS認定資格試験テキスト　AWS認定 ソリューションアーキテクト-アソシエイト](https://www.amazon.co.jp/gp/product/B07R1H87Y1)

### 問題集

言わずとも。問題数が多いのでお勧め。
[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)

## 対 AWS 認定 SysOps アドミニストレーター – アソシエイト

職業上、一番勉強しないといけない。
けど勉強したく無い(さっさとLambdaを勉強したかった)から資格取得目的で勉強。故にハンズオン無し。

取った理由は前述の問題集にSOAも込み込みで、問題がSAAと似ているという噂だったから。
**実際は同じと思えない内容だった(多分噂の適用先は過去バージョンの方...?)**

ただし、SAAから特定範囲を深く掘り下げるイメージのため、SAAの次はSOAの方が良いと思う。

敗戦処理しながら受験していたら普通に受かってた。（多分次は受かる自信無い）
１ヶ月で取得

- 問題集 : 1ヶ月

### 問題集

SAAの問題契約したらSOAも含まれている。
問題集はSAAと比較したら少なめだが、SAAベースの自分がSOA差分を拾うのには丁度よかった。
[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)

もう1つの問題集。買った理由は今回は「足りない」と感じたため。
全編英語でお楽しみ頂けます...
最終的にはこちらの問題集をメインに復習（数周）していた。
[AWS Certified SysOps Administrator Associate Practice Exams](https://www.udemy.com/course/aws-certified-sysops-administrator-associate-practice-exams-soa-c01/)

## 対 AWS 認定デベロッパー – アソシエイト

「クラウド環境を使って具体的にどういうことが出来るか？」という事と
開発を行う上での基本的に考えないといけない事など、資格勉強の中で一番収穫がある。

**ただし、英語の教材しか見つからなかった。（＝＝；**
TOEIC３２０点くらいの私には苦行にしか他ならない。でもLambdaは楽しい
SAAの浅い知識＋DVAの深い知識が必要と判断して、ハンズオン教材を新たに購入。
実際に手を動かして勉強した。途中から問題集も並行して実施。

- ハンズオン : 2ヶ月
- 問題集 : 1ヶ月（ハンズオンと並行してやった)

### ハンズオン教材

英語教材だけどこれはいくつか紹介されていて、まさに勉強になりました。
良いところは以下の2つ。ステファン先生大好きっす（：DTZ

- SAAの入り口程度の基本的なリソースの使い方のおさらいをしてから、実際の試験範囲を学習する構成になっていること。
- 勉強だけではなく、実際の開発者視点のtopicも補足を入れてくれていること

[Ultimate AWS Certified Developer Associate 2019 - NEW!](https://www.udemy.com/course/aws-certified-developer-associate-dva-c01)

### 問題集
今回は以下の２種類。

ステファン先生の問題集。おすすめ
[AWS Certified Developer Associate 2019 [4 Practice Tests]](https://www.udemy.com/course/aws-certified-developer-associate-practice-tests-dva-c01/)

whizlabsの問題集も購入。理由は個人レベルの問題集もいいけど
企業、団体レベルの問題集の方が色々試験問題からパクってる感が高いと思ったから。
**実際、試験問題と似たような印象を持つ問題が２問以上あった**
もう1つの理由はSAP向けに英語圏の問題集探索をしておきたかったから。
[AWS Certified Developer Associate](https://www.whizlabs.com/learn/course/aws-cda-practice-tests/)
【Ruby】数の切り上げ、切り捨て、四捨五入

少し調べたので備忘録として

#切り捨て : floor


#切り上げ : ceil



#四捨五入 : round

```
$ 1.4.round
=> 1

$ 1.5.round
=> 2

$ 1.2345.round(0)
=> 1

$ 1.2345.round(2)
=> 1.23

$ 1.2345.round(3)
=> 1.235

$ 123456.round(-2)
=> 123400



```
macOS Catalina にアップデートしたらログインシェルが bash から zsh に移行して .bash_profile が使えなくなった

先日リリースされた [macOS Catalina](https://www.apple.com/jp/macos/catalina/) にアップデートしたら、デフォルトのログインシェルが zsh になりました。そのためこれまでお世話になっていた bash からの卒業を迫らました。結果的に ~/.bash_profile や ~/.bashrc に記述していた設定が使えなくなりました。これまでの人生で zsh を使ったことのある方なら移行は簡単でしょう。しかし自分はそんな経験がなかったので困りました、途方に暮れました。
さすがに Git 周りがターミナルに表示されないのは不便なので調べていると [デフォルトのログインシェルが bash から zsh に変更されることについてまとめてくださっている記事](https://applech2.com/archives/201910-macos-10-15-catalina-default-shell-zsh.html) に出会いました。
最終的に [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) というプロジェクトに辿り着き、以下のコマンドをターミナルで実行することで、zsh の設定が完了しました。

```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
```

コマンドを実行すると ~/.zshrc という zsh の設定ファイルができていました。とりあえずはこのまま過ごし、余裕ができたら設定をいじろうと思います。
リーダブルコード　第２章　＜名前に情報を詰め込む＞　まとめ

#2.1明確な単語を選ぶ
動作に合わせて、より明確な単語を使用する。
例）
get() →　DownloadPage(),FetchPage()
stop() →　Kill(), Pause()

 
#2.2汎用的な名前を避ける
良い変数名は、変数の目的や値を表す。
ただし、生存期間が短く、一時保管的な役割の変数には、汎用的な名前を意図的につける場合もある。
ループイテレータに対しても、複数ある場合には明確な名前をつけ判別しやすくすることで、バグを減らせる。

#2.3具体的な名前を使い、物事を詳細に説明する
メソッドであれば、そのメソッドの機能、動作を明確に表現できる名前を定義する。
直行する概念に対しては、まとめようとはせず、それぞれ別の名前をつける。


#2.4変数名に大切な情報を追加する
1.時間、バイト数などの計測できるものは、変数名に単位を追加する。
例）
delay → delay_secs
size　→ seize_mb
limit　→ max_kbps
angle　→ degrees_cw

2.基本的には、変数の意味を理解してほしいところには属性を追加する。
3.特に、変数の意味を誤って解釈しバグになりそうなところで追加する。
例）
password　→ plaintext_password
comment → unescaped_comment
#2.5スコープの大きな変数には長い名前をつける

識別子のスコープが大きければ、名前に十分な情報を詰め込んで明確にする必要がある

>スコープが小さければ短い名前でもいい

必要な情報が近くにあるため。

>長い名前を入力するのは問題ではない

エディタの補完機能を使用すれば、正確に素早く利用できる。

>頭文字と省略形

チームで共有できる場合に、単語を省略する。
ただし、プロジェクト固有の省略形は使用しない。新しく入るメンバーが読めたいため。

#2.6大文字やアンダースコアなどに意味を含める
>名前のフォーマットで情報を伝える

クラス名はCamelCase(キャメルケース)
変数名はlower_separeted(小文字をアンダースコアで区切ったもの)
規約を定めておけば、メンバー変数とローカル変数を明確に区別できる
例）
stats.clear()
"_"がないため、ローカル変数であるとわかる

#まとめ
「名前に情報を詰め込む」ことで、情報を読み取れるようにする。
Flutter webで外部リンクを開く

# Flutter とは？
Flutterは１つのコードでiOSとAndroidアプリケーションを作成することができるGoogleのUIフレームワークです。
以下のような特徴があります。
- モダンなリアクティブフレームワーク
- 速い2Dのレンダリングエンジン
- 速く開発するためのツール
- 既製のウィジェット

全体を体系的に学ぶには、[Udacity](https://udacity.com) のFlutterのコースがオススメです。GoogleのFlutter開発支援チームの方が講師として教えてくれます。

# FlutterはWebに対応した！
> Flutterは１つのコードでiOSとAndroidアプリケーションを作成することができる

と言いましたが、WebのUIとしてもビルドすることができるようになりました。
とは言っても以前から `flutter_web` というpackageによって、webで利用することはできました。
<a href="https://github.com/flutter/flutter_web"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/flutter/flutter_web.png" width="460px"></a>

しかし、このようなブラウザをサポートするプラグインを入れなくても、webで動くようになります。

> In future, we plan to generate PWA configuration files to support Progressive Web Apps.

将来的にはPWAのサポートもされるようになるようで、これからさらにFlutterは熱くなりそうです。

## Flutter webを使えるようにする
まず Flutter のインストールは以下を参考にします。
https://flutter.dev/docs/get-started/install

次に、Webアプリが構築できるようにします。以下を参考にします。
https://flutter.dev/docs/get-started/web
やることは簡単で、以下をするだけ。

```bash
 $ flutter channel master
 $ flutter upgrade
 $ flutter config --enable-web
```
おそらく、Webアプリとしてビルドできるようになると以下のようになると思います。

```bash
$ flutter devices
2 connected devices:

Chrome          • chrome          • web-javascript • Google Chrome 77.0.3865.90
Headless Server • headless-server • web-javascript • Flutter Tools

```

デバッグには、Chromeが必要なのでChromeが入ってない場合はインストールが必要です。

Webアプリを実行する時は

```bash
$ flutter run -d chrome
```

ビルドする時は、

```bash
$ flutter build web
```

です。

# Flutter web で 外部リンクを開く
Flutterでは外部リンクを開く際に、 `url_launcher` というパッケージを利用することが多いと思います。
https://pub.dev/packages/url_launcher

> Supports iOS and Android.

しかし、現在[2019-10-14]では、Webで使用できないと思われます。実際使用しましたが、使用できませんでした。

redditのFlutterDevでも質問がありました。やっぱりFlutter webでは使えないっぽい。
https://www.reddit.com/r/FlutterDev/comments/brar5u/how_can_i_open_the_link_in_flutter_for_web/

そして、このFAQにWebでの使い方の代替案がありました。 `dart:html` パッケージを使用します。

```dart

import 'dart:html' as html';

_launchURL(url) {
  html.window.open(url, '');
}
```

この関数をInkWellやbuttonのonPressedなどに当てることで同様の処理ができるようになりました。

`dart:js` パッケージでもいけます。

```dart
import 'dart:js' as js;

_launchURL(url) {
  js.context.callMethod("open", [url]);
}
```
Ryzen5+RTX2070SuperにUbuntu1804をインストール

# はじめに
新しいマシンにUbuntu18.04LTSをインストール完了したので、動作確認情報を共有します。構成にこだわったのでインストールできるか不安でした。他の方のPC選択時に参考になればと思います。

# PC構成
お金が無いが強いGPUが欲しかったのでRyzenにしました。構成は以下。

```plaintext:machine
AMD Ryzen 3600X
GeForce RTX 2070 SUPER
```

ディアルブート環境にするために同一ドライブを使いたくなかったので、m.2のWindows用ドライブとは別にSATA SSDを準備した。

# まずWindowsでしたこと
Windowsはほとんど使わないと思うので、基本的な初期設定だけ済ませた。しかし、いざというときに困らないためにお気に入りのブラウザはインストールした。

```plaintext:windows_setup
・初期状態の修復メディアの作成
・Vivaldiのインストール
・[Rufus](https://rufus.ie)を用いてUbuntu18.04.3のライブUSBの作成
・パーティションの管理から、Ubuntu用ドライブのボリュームを削除
```

# インストールするための準備
マシン起動時にBIOS（UEFI?）へ移行し、以下の設定をします。ブートの優先順位を変更する必要があったりするので、注意してほしい。

```plaintext:setup_for_ubuntu_install
・Secure Bootを無効化（これ忘れるとNVIDIA Driverをインストールできない）
```

# インストール
先程作成したライブUSBを指してマシンを起動すると、ライブ起動用の選択画面が出た。
`try ubuntu without install`を選択し、Ubuntuが無事動作するのかを確認。ここで、オプションを変更せずに起動しようとするとフリーズするため、`try ...`でエンターを押す前に`e`を押してオプションで

```plaintext:change_option
quiet splash
↓
nomodeset
```

と変更し、`F10`で起動すると、Ubuntuのデスクトップ画面が表示された。デスクトップにおいてある、インストール用アプリケーション（？）を起動し、OSのインストールを始める。その後は、言われたとおりに進むと良い。少々時間を置くと無事インストールが完了したようで、再起動を促されるので再起動する。

# 起動して初期設定
そのままUbuntuを起動しようとしても、ライブUSB時同様に起動しなかった。そこで、GRUBの起動オプションを先ほどと同じ変更すると起動した。

日本語入力の設定が面倒なため、私は日本語リミックス版のUbuntuをインストールするようにしている。しかし、ターミナルの出力が日本語だと何かと不便である上、ディレクトリ名が日本語だと不便であるので、以下の変更をした。

まずはディレクトリの英語化のために以下のコマンドを実行する。

```sh:directory_convert_english
$ LANG=C xdg-user-dirs-gtk-update
```
次に英語環境化だが、`etc/default/locale`を以下にする。

```plaintext:/etc/default/locale
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
```
また、CapsLockキーが嫌いなため、`/etc/default/keyboard`に以下の変更を加える。

```plaintext:change_for_capslock2ctrl
XKBOPTIONS=""
↓
XKBOPTIONS="ctrl:nocaps"
```

# NVIDIA DRIVERのインストール
ここがなんとなく難しい。このままではGPUが機能していないので、[NVIDIAの公式サイト](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)からGPUにあわせたドライバをダウンロードしてインストールする。

インストールする際、イマイチ意味はわかっていないが、GUIの停止をするらしい。

```sh:stop_gui
$ sudo service lightdm stop
```

その後、仮想コンソールモードでログインする。`F1~F3`あたりを押すとでき、ユーザ名とパスワードを順に入力するとよい。ログイン後に先ほどインストールしたNVIDIA DRIVERインストーラを起動し、終了する。このとき、実行権限を付与するコマンド(`chmod`）を使用しなくてもインストーラは起動できる。

```sh:install_nvidia_driver
$ cd Downloads
$ sudo bash ./NVIDIA-Linux-*.run
```

途中警告が出るが、インストールが完了したら再起動する。

```sh:reboot
$ reboot
```

# ブートオプションの固定
起動時に毎回オプション変更するのは骨が折れるので、`/etc/default/grub`に以下の変更を加える。(`quiet splash nomodeset`としてもよい)

```plaintext:grub_change_option
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
↓
GRUB_CMDLINE_LINUX_DEFAULT="nomodeset"
```

変更後、以下のコマンドを実行し、GRUBを更新する。

```sh:update_grub
$ sudo update-grub
```

# おわりに
以上で、Ubuntuのインストールが完了しました。
ただ、GRUBメニューの動きが非常に遅いので、何かわかる方がいたらヒントをくださると幸いです。

# 参考ページ
- https://www.petitmonte.com/python/ubuntu_nvidia.html
    - NVIDIAドライバインストール時の処理(guiサービスの停止)
- https://www.dell.com/support/article/jp/ja/jpdhs1/sln306327/linux起動用の手動-nomodeset-カーネル-ブート-ライン-オプション?lang=ja
    - GRUBオプションの更新方法
公開鍵認証を使ってリモートサーバーにSSH接続する

# 注意

環境はMacOSです。

また、以下ではクライアントとリモートサーバーという言葉を次のような意味で用います。

- クライアント...接続元のサーバー(あなたの使ってるPC)
- リモートサーバー...接続先のサーバー

# 手順

この記事では以下の手順で公開鍵認証を使ってリモートサーバーにSSH接続する方法を説明します。また、上手くいかない時は一番下の補足を参照ください。

1. `ssh-keygen`コマンドを使ってクライアント側で秘密鍵と公開鍵を生成する。
2. `ssh-copy-id`コマンドを使ってクライアント側で生成した公開鍵をリモートサーバーに登録する。

# 秘密鍵と公開鍵の生成

クライアント側でターミナルを開き、以下のコマンドを実行します。

```
ssh-keygen
```

すると、どこに鍵を保存するかを聞かれます。そのままエンターを押すと()内に記載され場所に保存されます。

```
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/{ユーザー名}/.ssh/id_rsa):
```

次に以下のようなメッセージが出ます。これは秘密鍵自体にパスフレーズ(パスワード)を設定するか聞いています。そのままエンターを押すとパスフレーズ無しで設定されます。

```
Enter passphrase (empty for no passphrase):
```

次に以下のメッセージが出ますが、これは設定したパスフレーズの確認ですのでもう一度同じパスフレーズを入力してください。

```
Enter same passphrase again:
```

これで秘密鍵と公開鍵の生成は完了しました。`id_rsa`が秘密鍵で`id_rsa.pub`が公開鍵です。保存したディレクトリに移動して確認してください。

# 公開鍵をリモートサーバーに登録する

先ほどクライアント側で生成した`id_rsa.pub`の内容をリモートサーバーの`.ssh/authorized_keys`に追記する必要があるのですが、以下のコマンドをクライアント側で叩くだけでそれができてしまいます。

```
ssh-copy-id {ユーザー名}@{リモートサーバーのホスト名}
```

# 接続できるか確認

SSH接続ができるか確認してみます。以下のコマンドを叩きパスワードを聞かれずに接続できれば成功です（秘密鍵にパスフレーズを設定した人はその入力をする必要があります）。

```
ssh {ユーザー名}@{リモートサーバーのホスト名}
```

# 補足

うまくいかない時はこちらを参照ください。

## `ssh-copy-id`ができない

以下のコマンドではデフォルトで`.ssh/id_rsa.pub`を探しにいきます。

```
ssh-copy-id {ユーザー名}@{リモートサーバーのホスト名}
```

以下のようにオプション`-i`を付けてファイルを指定する方が確実です。

```
ssh-copy-id -i {公開鍵までのパス} {ユーザー名}@{リモートサーバーのホスト名}
```

## ssh接続ができない or パスワードを聞かれる

こちらも同様以下のコマンドではデフォルトで`.ssh/id_rsa`を探しにいきます。

```
ssh {ユーザー名}@{リモートサーバーのホスト名}
```

以下のようにオプション`-i`を付けてファイルを指定する方が確実です。

```
ssh -i {秘密鍵までのパス} {ユーザー名}@{リモートサーバーのホスト名}
```
Firebaseでデプロイしたサイトを削除する方法

#結論

```linux
firebase hosting:disable -y
```
で削除できる

#エラーが出たら

```linux
Error: Authorization failed. This account is missing the following required permissions on project project-id:
```
と表示されたら

```linux
firebase list
```
で表示された「Project ID / Instance」で

```linux
firebase use project-id 
```
を先に実行すること
weather:bitとMetabaseで温度、湿度、気圧を可視化

# 何をしたのか？
[以前](https://qiita.com/m_ryusei/items/ec7b6c97f5f4929b43be)、利用した micro:bit に weather:bit をドッキングさせて温度、湿度、気圧（ついでに環境光）の値を取得。
その値を MySQL に蓄積し Metabase で可視化してみました。

micro:bit では湿度、気圧などの値は取ることが出来なかったため、拡張基盤の weather:bit で取ることにしました。スイッチサイエンスにて約2,000円くらいです。さらにオプションセンサを購入すれば土壌水分、土壌温度、風速なども測ることもできるみたいです。

前回は Ambient にて可視化をしましたが、今回は Rate Limit など気にすることなく、お手軽に可視化できるツール、 Metabase を使うことにしてみました。

# weather:bit
https://www.switch-science.com/catalog/3383/
https://www.sparkfun.com/products/14214

# Metabase
https://www.metabase.com/

# 構成図
絵的には、こんな感じです。
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12487/99300c85-f325-fd8a-1425-4cdaad76ad61.png)

1. micro:bit & weather:bit から温度、湿度、気圧、環境光の値を60秒間に1回送信
2. USB接続されたPC（Mac）に python のアプリを常駐させて温度、湿度、気圧、環境光の値を受信、そのまま MySQL に蓄積
3. MySQLに蓄積された値を Metabase で可視化

写真だと、こんな感じです。
![Image from iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12487/7db82e60-ab65-95fd-1958-346d79970caf.jpeg)

## 1. micro:bit & weather:bit から温度、湿度、気圧、環境光の値を60秒間に1回送信
micro:bit(weather:bit)のコードはこんな感じです。
![スクリーンショット 2019-09-22 8.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12487/014ba71e-6048-bfd5-bf70-191e09d1aee6.png)

https://learn.sparkfun.com/tutorials/microclimate-kit-experiment-guide/about-the-weatherbit
コードの組み方などは weather:bit のガイドが参考になります。

## 2. USB接続されたPC（Mac）に python のアプリを常駐させて温度、湿度、気圧、環境光の値を受信、そのまま MySQL に蓄積
python のコードはこちらです。

```python:qiita.py
"""
weather:bit で温度、湿度、気圧を取得してDB(MySQL)に値を蓄積する
（可視化はmetabaseで確認）
"""

import serial
import pymysql.cursors

conn = pymysql.connect(host='localhost',
                    db='sandbox_db',
                    user='root',
                    charset='utf8mb4',
                    cursorclass=pymysql.cursors.DictCursor)
HYPHEN = '-'
line = ''
microbitdata = ''

# MacでUSBシリアルポートの名前を調べるコマンド
# ls -l /dev/tty.*
ser = serial.Serial('/dev/tty.usbmodem1412', 115200)
microbitdata = ''
while True:
    line = ''
    line = str(ser.readline(), 'utf-8')
    if HYPHEN == line.strip():
        data = microbitdata.split(':')
        with conn.cursor() as cursor:
            cursor.execute(
                "INSERT INTO environment (humidity, temperature, pressure, ambient_light) "
                "VALUES (" + data[1] + ", " + data[3] + ",　" + data[5] + ", " + data[7] + ")"
            )
            conn.commit()

        microbitdata = ''
    else:
        microbitdata = microbitdata + line.strip() + ':'

ser.close()

```

## 3. MySQLに蓄積された値を Metabase で可視化
温度と湿度を可視化してみました。
![スクリーンショット 2019-10-14 21.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12487/888e7922-7c26-2d7f-3570-e0f30238d743.png)

お手軽に環境が作れて可視化ができる Metabase はいいっすね ♪
以上です！
Redisインストール ( Mac Rails VScode)

今回は人から貰ったRedisを使用したWebアプリを
私のローカル環境で見れるようにしたいので､
Redisをインストールします｡
[Redis公式サイトはこちら](https://redis.io/)

###Redisとは
超高速データベース
部分的に使われる
リアルタイムランキングなどに使用される

###インストール
まずはRedisのインストール

```ruby:
$brew install redis
```

```:インストール完了
==> Downloading from https://akamai.bintray.com/1c/1cf97b4ba2f47029f76979b430c76c760ce467786d85907031a86b58fd4b4960?__gda__=exp=1571060074~hmac=4f9428de0396e8
######################################################################## 100.0%
==> Pouring redis-5.0.6.mojave.bottle.tar.gz
==> Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==> Summary
🍺  /usr/local/Cellar/redis/5.0.6: 13 files, 3.1MB
```
```:バージョン確認方法
$redis-server --version
Redis server v=5.0.6 sha=00000000:0 malloc=libc bits=64 build=7a57e483d6f8b275
```

###起動
貰ったディレクトリを開いて
`$bin/rails db:migrate`と`bundle install`をして

```:puma起動
$bin/rails s
```
※railsサーバー起動用と､Redis起動用の2つターミナル使いました｡新しいターミナル追加するボタンを押してターミナル2つにしてください｡(一番下にスクショ)

```:Redis起動
$redis-server
55517:C 14 Oct 2019 22:44:35.927 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
55517:C 14 Oct 2019 22:44:35.928 # Redis version=5.0.6, bits=64, commit=00000000, modified=0, pid=55517, just started
55517:C 14 Oct 2019 22:44:35.928 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 5.0.6 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 55517
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

55517:M 14 Oct 2019 22:44:35.945 # Server initialized
55517:M 14 Oct 2019 22:44:35.946 * Ready to accept connections

```
`* Ready to accept connections`と出ているのでRedis起動OK

これでローカルでWebアプリが見ることができます｡

###終了
終了する時はpumaとredisそれぞれ`Ctrl+C`で終了してください｡
(Redisの終了の仕方は､他の方法もあるようですが､今回はCtrl+Cで簡単に終了する方法をとりました｡)

###ターミナル追加ボタン VScode
<img width="985" alt="ターミナル追加.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333998/fd670266-081f-e4f7-bfb9-27c943139457.png">
DiscordPHP の sendFile で reply する

Message オブジェクトの `$message->author` を使用する。

```php:
$message->channel->sendFile(__DIR__ . '/image.jpg', 'image.jpg', "{$message->author} reply message");
// または
$message->channel->sendFile(__DIR__ . '/image.jpg', 'image.jpg', $message->author . ' reply message');
```

#公式ドキュメント
https://discordphp.readme.io/docs/channel#sendfilefilepath-filename-content-tts
人事自動化 ATS Talentio の API で候補者一覧を取得する - GAS 編

```JavaScript
function testTalentioAPI() {
  // Talentio の Token の取得方法については後述の資料を参照
  var token = getTalentioAPIToken();
  var headers = {
    'Authorization': 'Bearer '+ token
  };
  var options = {
    'method': 'GET',
    'headers': headers,
  };
  // サンプルなのでページ数をハードコードしています
  var response = UrlFetchApp.fetch('https://talentio.com/api/v1/candidates?page=24', options);
  var candidates = JSON.parse(response.getContentText());
  Logger.log(candidates);
}

function getTalentioAPIToken(){
  // Talentio の Token はスクリプトプロパティに TALENTIO_API_TOKEN という名前で保存する
  return PropertiesService.getScriptProperties().getProperty('TALENTIO_API_TOKEN');
}
```

## 資料
* [APIの利用 | Talentio Help Center](https://intercom.help/talentio/ja/articles/1957111-api%E3%81%AE%E5%88%A9%E7%94%A8)
* [【初心者向けGAS】スクリプトプロパティを操作してそのデータを取り出す方法](https://tonari-it.com/gas-properties-script-property/)

## 関連
* [人事自動化 ATS Talentio の API で候補者一覧を取得する - Ruby 編](https://qiita.com/tbpgr/items/c4347aba8106781425e2)
NiftyCloud、monacaで、Androidで、PUSH通知

ちょっと興味があったので、Android端末のNiftyCloudのPUSH通知のチュートリアルをやってみました。
実際行ったチュートリアルは、[【アプリにプッシュ通知を組み込もう！】](https://github.com/NIFCloud-mbaas/MonacaPushApp)です。

チュートリアル自体がしっかり作られているので、チュートリアルどおりに進められば問題ないです。
が、詰まったところと、プラス＠で調べたことをご紹介します。

# 参考資料
- [アプリにプッシュ通知を組み込もう！](https://ja.monaca.io/)
- [Monaca 会員登録](https://qiita.com/t_imagawa/items/47fc130a419b9be0b447)
- [ニフクラ mobile backend 会員登録](https://mbaas.nifcloud.com/)
- [Firebaseプロジェクトの作成とAPIキーの取得についてはこちら](https://mbaas.nifcloud.com/doc/current/tutorial/push_setup_android.html)
- [google-services.jsonとFirebase秘密鍵の設定方法についてはこちら](https://mbaas.nifcloud.com/doc/current/common/push_setup_fcm_json.html)
- [ニフクラ REST API リファレンス](https://mbaas.nifcloud.com/doc/current/rest/push/pushSearch.html)

# 詰まったところ
## 「0. プッシュ通知機能を使うための準備」でちょっと詰まる。
[アプリにプッシュ通知を組み込もう！](https://ja.monaca.io/)の手順どおり進めていくと、
 「0. プッシュ通知機能を使うための準備」があります。

その手順で、「FireBase」と「NiftyCloud(mobile backend)」を繋げます。
具体的には、「Firebaseの秘密鍵」を「mobile backendに設定」することで、
「FireBase」と「NiftyCloud(mobile backend)」が繋がります。

ただ、手順の途中に「google-services.jsonを発行してアプリに登録」があります。
これは、何かというと、「Firebase」と「スマホにインストールするアプリ」を繋げます。

これを行うことにより、

「スマホにインストールするアプリ」と「Firebase」と「NiftyCloud(mobile backend)」が繋がります。

で、何に詰まったかというと、「google-services.jsonを発行してアプリに登録」です。

登録する方法は、firebaseで「google-services.json」をダウンロードします。
その後、アプリに登録がハマリました。。

今回は、Monacaでアプリを作るのですが、Monaca自体もよく分からない状態だったので、ハマリマシタｗ
後半の手順「2. Monaca でアプリの準備」で、Monacaにチュートリアルアプリを展開します。

で、Monaca上で、展開したアプリの「直下」に「google-services.json」をアップロードします！
※ 直下というのは、Readme等と同じ階層です。

これが、「google-services.jsonを発行してアプリに登録」です！

この「直下にアップする」ということが分からず、ハマリマシタ。

# 調べたこと
## プッシュ通知の検索のレスポンスって何があるんだろう。。
JavaScriptでアプリからニフクラにアクセスして、色々出来るらしいのですが、
そのうちの1つの機能[【プッシュ通知の検索】](https://mbaas.nifcloud.com/doc/current/push/basic_usage_javascript.html#%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E9%80%9A%E7%9F%A5%E3%81%AE%E6%A4%9C%E7%B4%A2)
を試していました。

上記リンクの例に「pushs[i].message」があり、message以外って何があるんだろう・・って思い調べて見たところ、
ちゃんと、ドキュメントが用意されていました。
[ニフクラ REST API リファレンス](https://mbaas.nifcloud.com/doc/current/rest/push/pushSearch.html)

上記に全てが載っています。

# 余談
## monacaについて
スマホアプリがこんな簡単に作れて、実機で試せるとは！っと素直に感動でした。
無料プランだと、1日のビルド回数が限られていますが、Web上のプレビューで動作確認できるので全然問題ないです。

裏側はcordovaなので、何となく納得。

## firebaseとニフクラについて
無料プランで色々作成できるのが改めて、すごいなって感じました。
どういうものだろうって思ったときに、サクッと登録して作れて試せてしまう。
そんな時代になった事を改めて感じます。

ちなみに、この作業はトータル3時間くらいです。
（google-services.jsonを発行してアプリに登録で、だいぶ時間を食い、途中、心が折れそうになりましたがｗ）
dockerコンテナ上で puppeteerを動かす

docker上でpuppeteerを動かすにあたって、なんだかすごく時間がかかった。

# 前提
docker+Express環境を立ち上げ済み

# やること
dockerfileを適切に記述して、あとは普通に立ち上げるだけです。
ゾンビプロセスのせいで凄まじくゴミが溜まるので、それ用にdump-initも入れています。

## Dockerfile
```Docker
FROM node:8-slim

# See https://crbug.com/795759
RUN apt-get update && apt-get install -yq libgconf-2-4

# chromeをダウンロード
RUN apt-get update && apt-get install -y wget --no-install-recommends \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst ttf-freefont \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get purge --auto-remove -y curl \
    && rm -rf /src/*.deb

# ゾンビプロセス対策に必要
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init

RUN npm i puppeteer

# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser /node_modules

# Run everything after as non-privileged user.
USER pptruser

ENTRYPOINT ["dumb-init", "--"]
CMD ["google-chrome-unstable"]

# 環境変数設定
ENV NODE_ENV="development"

# 作業ディレクトリ作成&設定
WORKDIR /src

```

## puppeteer起動
``` main.js
    const browser = await puppeteer.launch({
      args: [
        // Required for Docker version of Puppeteer
        '--no-sandbox',
        '--disable-setuid-sandbox',
        // This will write shared memory files into /tmp instead of /dev/shm,
        // because Docker’s default for /dev/shm is 64MB
        '--disable-dev-shm-usage',
      ],
      executablePath: 'google-chrome-unstable',
    })

    const page = await browser.newPage()
```

以上。


# (余談)$$evalの注意点
``` js
page.$$eval('.hogeclass', elm =>{...})
```
余談ですが、$$eval内の関数はchrome上で実行されるもので、この中で事前に定義した変数とか使おうとするとエラる。
これが、util is not definedという謎なお返事を返してくれる。
参考：https://stackoverflow.com/questions/49429488/error-evaluation-failed-referenceerror-util-is-not-defined/49429927

## 失敗例
``` js
const lololo = "aaa"
page.$$eval('.hogeclass', elm =>{
 console.log(lololo) //ここでエラー
})
```

## $$eval内は、dom取得意外に余計な処理を行わない
複数要素取得したい時は、取得後、なんかしらの処理を加えたいときが多いと思うので、

`const elm = await page.$$('.hogeclass')`

で要素を取得して、取得後にループ。

単一の要素の場合は、

```js
let hogehoge = await page.$eval(‘.hogeclass’, (item) => {
 return textContent
})
```

みたいな感じで。とにかくeval内でゴネゴネやらなければOk。
【JavaScript】制御構文まとめ

## 目次
1. if
2. else
3. for
4. while
5. switch
6. continueとbreak

## 1. if
記述の仕方

```javascript:js
if (条件式) {
  // 処理
}
```
条件式が`true`だった場合中にある処理を実行する。

```javascript:js
let number = 5;

if (number < 5) {
  console.log("５未満です");
}
```
`実行結果:5未満です`


## 2. else
先ほどのif構文の条件式を満たさなかった場合の処理を`else`で書くことができます。

```javascript:js
if (条件式)　{
  // 処理
}
else {
  // ifがfalseだった場合の処理
}
```
上記のif構文が`false`だった場合

```javascript:js
let number = 5;

if (number > 5) {
  console.log("５未満です");
}
else {
  console.log("5以上です");
}
```
`実行結果:5以上です`


## 3. for
繰り返し(ループ)の構文になります。
ループする回数が決まっている場合はこちらの`for`を使います。

```javascript:js
for (条件式) {
  // 処理
}
```
`条件式`にはループが続く条件を記述します。
一般的に`for`では変数`i`をループカウンタとして宣言して条件式を書きます。

```javascript:js
for (let i = 0; i < 5; i++) {
  console.log(i);
}
```
`実行結果
0
1
2
3
4`

条件式の`()`の中は
`( ループカウンタの宣言; ループが続く条件; 変数の更新 )`で記述します。
今回の場合みたいなコードだと変数の更新をしないと、無限ループになってしまうので忘れずに。


## while
こちらも繰り返し(ループ)の構文になります。
`for`とは違って主に、ループする回数が明確ではない場合に使用します。

```javascript:js
while (条件式) {
  // 処理
}
```
条件式の内容が`true`の間中処理を繰り返します。

```javascript:js
let number = 0;
while (number < 5) {
  console.log(number);
  i++;
}
```
`実行結果
0
1
2
3
4`

`for`の時は条件式の中で変数の更新ができましたが、
`while`では処理の中でしなければなりません。


## switch
複数の条件分岐を書く場合に`switch`が便利。

```javascript:js
switch ( 式 ) {
  case 値:
    // 処理
    break;
 
  case 値:
    // 処理
    break;
    
  case 値: 
    //必要なだけcaseを追加
}
```
式の値ごとに処理を書いていきます。
`break`については後述します。



## continueとbreak
`continue`と`break`はそれぞれループを抜けるためのものになります。

- `continue`は処理を中止して、次の処理を行います。

```javascript:js
let number = 5;

while (number < 5) {
  number++;

  if (number % 2 === 0) continue;
  console.log(number);
}
```
`実行結果
1
3`

上の結果はnumberの値が偶数の時だけそれ以降の処理を行わないというものになります。
なので、出力結果は奇数だけになります。

- breakは処理を中止してループから抜けます。
continueと違って次の処理に行くわけではなく、ループから完全に抜けます。

```javascript:js
let number = 5;

while (number < 5) {
  number++;

  if (number % 2 === 0) break;
  console.log(number);
```
`実行結果:1`

numberの値が偶数だったら処理を中断してループから抜けます。
なので、numberが2になった途端にループから抜けるので出力結果が1だけになります。
Pythonでネットワーク分析 -- ネットワーク分析用ライブラリ（networkx）で簡単なグラフを書いてみる --

#１．始めに#
「networkx」とは、Python用のネットワーク分析用ライブラリです。
各種ネットワークのクラスタリングや中心的な要素を発見するための分析に用いられます。

ネットワーク分析は実際に以下のような分野において応用されています。

- **ソーシャルネットワーク**
　例）SNSのインフルエンサーを分析

- **企業間ネットワーク**
　例）企業間の取引データから自社の強みとなる分野を分析　

- **交通ネットワーク**
　例）流通における最短経路や最安経路の特定、派生して流通経路の最適化の分析

本稿では、「networkx」ライブラリを利用して簡単なネットワーク図を描画するまでの過程を紹介します。
なお、ドキュメントはバージョン2.3を参照しています。
[参照したドキュメントのリンク](https://networkx.github.io/documentation/stable/)

#２．参照する関数など#
- **networkx.Graph()**：頂点（ノード）も辺（エッジ）も存在しない空のグラフを生成します。
- **Graph.add_node(ノード)**：単一ノードを追加します。
- **Graph.add_nodes_from(ノードリスト)**：複数ノードを追加します。
- **networkx.drawing.layout.spring_layout(グラフ)**：グラフ描画アルゴリズムの一つで、呪文と思ってください（無くても問題ありません）
- **networkx.draw_networkx_nodes(グラフ,描画位置,ノードリスト,ノードの色,ノードの大きさ,透過度)**：ノードを描画します。
- **networkx.draw_networkx_edges(グラフ,描画位置,エッジリスト,エッジの太さ,透過度,エッジの色)**：エッジを描画します。
- **networkx.draw_networkx_labels(グラフ,描画位置,文字の大きさ)**：ラベルを描画します。

#３．サンプルコード#
```
#「networkx」のインポートと出力用に「matplotlib」もインポート
import networkx as nx
import matplotlib.pyplot as plt

# ノードの数を指定せず初期化
G = nx.Graph()

# ノードの追加（単一）
G.add_node(0)

# ノードの追加（複数）
G.add_nodes_from([1 ,2 , 3, 4])

# ノードを描画する位置を決定
pos = nx.spring_layout(G)

# グラフの描画
# draw_networkx_nodes()でノードの描画
nx.draw_networkx_nodes(G, pos, nodelist=[0, 1], node_color='red', node_size=100, alpha=1)
nx.draw_networkx_nodes(G, pos, nodelist=[2, 3], node_color='blue', node_size=100, alpha=1)
nx.draw_networkx_nodes(G, pos, nodelist=[4], node_color='purple', node_size=100, alpha=1)

# draw_networkx_edges()でエッジの描画
nx.draw_networkx_edges(G, pos, edgelist=[(0, 1), (0, 2), (1, 3), (2, 1), (3, 0)], width=1, alpha=1, edge_color="black")
nx.draw_networkx_edges(G, pos, edgelist=[(2, 4), (4, 2), (4, 1), (4, 3)], width=3, alpha=1, edge_color="black")

# draw_networkx_labels()でラベルの描画
nx.draw_networkx_labels(G, pos, font_size=16)

#グラフの出力
plt.show()
```
#４．サンプルコードの出力結果#
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513505/a89f33ac-4f7a-65f2-14dc-924834eb9064.png)
vue-routerのタイトル・メタタグを反映するmixins

健康診断でバリウムを飲んだ後はその日一日中腹痛で仕事になりゃしません。あれどうにかならないんですかね。

それはさておき、最近一般に公開されるような業務が少なくてつい忘れがちだったのですが、そういや普通はdescriptionも設定する必要あるんだよな、と思ってmixinsを作って満足したので備忘録として残しておきます。最近はmeta keywordsはもうほぼ意味がないとのことで自身でもとんと設定した覚えがないのですが、恐らく同じ形で設定出来るかと。

# routerでmeta情報をもたせておく

`/router.js`または`/router/index.js`などこの辺はプロジェクトによって違うと思いますが、持たせ方は変わりません。`title`、`description`と~~考えるのが面倒~~一般的な名前でここでは持たせましたが、わかりやすければ何でもいいと思います。

```js:router/paths.js
export default [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/Home.vue'),
    meta: { title: 'pageTitle', description: 'This is page description.' },
  },
];
```

# mixinsとして作る

routerに書くにもなんですし、`App.vue`に書くのも不躾な気がするので、mixinsにおいてしまいましょう。`main.js`に宣言を忘れずにしておきます。

```js:main.js
Vue.mixin(globalMixins);
```

## titleタグを更新するmixinsの用意

```js:mixins/index.js
/**
 * ページタイトル設定
 * @param pathTitle
 * @returns {string}
 */
export const setTitle = pathTitle => {
  const siteTitle = 'WebPage';
  const pageTitle = !pathTitle ? siteTitle : pathTitle + ' | ' + siteTitle;
  return (window.document.title = pageTitle);
};
```
タイトルタグがルーティングで指定されていれば「`ページタイトル | サイトタイトル`」、タイトルタグの指定がなければサイトタイトルのみをtitleタグに反映するようにします。この辺はプロジェクトに合わせて整形して渡してあげます。サイトタイトルはここで指定するのではなく、どこかで一元管理するのが正解かと思われますが、取り急ぎはこんな形で。

## descriptionを更新するmixinsの用意

```js:mixins/index.js
/**
 * Description設定
 * @param pathMeta
 */
export const setDescription = pathMeta => {
  const defaultDescription = 'This is initial description.';
  const description = pathMeta ? pathMeta : defaultDescription;
  document
    .querySelector("meta[name='description']")
    .setAttribute('content', description);
};
```

こちらも考え方は同様に。留意点として、`public/index.html`でdescriptionのフィールドを作っていないとこけます。最初ものの見事にハマってました。

## exportする

```js:mixins/index.js
export const globalMixins = {
  methods: {
    setTitle,
    setDescription,
  },
};
```
exportしておきます。

# router側の制御

```js:router/index.js
import { setTitle, setDescription } from '@/mixins';

router.beforeEach((to, from, next) => {
  setTitle(to.meta.title);
  setDescription(to.meta.description);
  next();
});
```

先程作ったmixinsをimportしておいて、ルーティング時に[ナビゲーションガード](https://router.vuejs.org/ja/guide/advanced/navigation-guards.html)で呼び出して、タイトル、ディスプリプションの更新を行ってから遷移するようにします。

# 確認

`META SEO inspector`で見てみたところ、無事反映されているようです。

![スクリーンショット 2019-10-07 1.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141352/1a5e1567-4c65-59bf-d29a-0e039109217e.png)

処理の置き場に困ったらとりあえずmixinsみたいな発想も我ながら雑だとは思いますが、やってること自体は特にそれ以上でもそれ以下でもない感じなので、今回はこのへんで。
pythonを始めたい！ json出力したいと思った時 ファイルパス指定の部分にエラーが出て困った話

初めて書くので変なところあったらすいません。


pythonでexcelの中身をjsonに出力るようになればゲームのパラメータ管理とか楽になりそうなのでやってみようとはじめました。


excelに触るためにpythonのopenpyxlが必要と色んなサイトであったのでインストールしました。
やり方は`pip install openpyxl`をコマンドプロンプトで実行するだけでした。

で、タイトルのエラーが出た部分なのですが
エクセルのファイル名をtest.xlsxにしてしまい、/tが引っかかってしまったみたいでした。

```
openpyxl.load_workbook("C:\test.xlsx")
```
今回自分が試した解決策が
raw文字列という`/`が特別な意味を持たない文字列にする方法で解決出来ました。

```
openpyxl.load_workbook(r"C:\test.xlsx")
```

書き方は""の前にrかRをつけるだけです。

これに気づかずに1時間くらい悩んでました...

成長記録をつけるために些細なことでも書いていこうと思います。
[読書記録]Adapter Pattern

# Chap2 Adapter Pattern
## Adapterパターンとは
- adapter:提供側と利用側の間に入り、両者をつなぐ(値を変換する)役割
  - 電流の例であれば、「交流200ボルト」(提供側)と「直流12ボルト」(利用側)をつなぐACアダプターのようなもの
- Adapterパターンには２種類存在する
  - パターン1:クラスによるAdapter(継承を利用する)
  - パターン2:インスタンスによるAdapter(委譲を利用する)
  
### どんなときに使えるのか
- すでに提供されている(実装されているクラス)のメソッドがそのままでは使えない時や使いづらい時に利用する
- 既存のクラスを継承もしくは委譲で利用するためすでに実装されている部分はテストしなくてすむ(テスト工数が減る)
- 既存のコードの書き換え(破壊的変更)をせずに機能を拡張できる

## パターン１ クラスによるAdapter(継承を利用する)
![2019-10-14-22-19-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179132/0d428815-d389-44a4-3799-667f25270709.png)

### Bannerクラス
- インスタンス生成時に表示する文字列をパラメータとして受ける
- メソッドによって表示するパターンが異なる

```python:Banner
class Banner():
    def __init__(self, string):
        self._string = string
    def show_with_pattern(self):
        print("({})".format(self._string))
    def show_with_aster(self):
        print("*{}*".format(self._string))
```

### Printインタフェース
- Mainクラスが利用するインタフェース

```python:printインタフェース
class Print(metaclass=ABCMeta):
    @abstractclassmethod
    def print_weak(self):
        pass
    @abstractclassmethod
    def print_strong(self):
        pass

```

### PrintBannerクラス
- Bannerクラスを継承する
- showWithParenメソッドおよびshowWithAsterメソッドを拡張する

```python:PrintBanner
class PrintBanner(Banner, Print):
    def __init__(self, string):
        Banner.__init__(string)
    def print_weak(self):
        self.show_with_paren()
    def print_strong(self):
        self.show_with_aster()
```

### Main
- PrintBannerインスタンスを作成し、文字列を表示するだけ
- Bannerクラスのメソッド「show_with_paren」「show_with_aster」がmainメソッドから隠蔽されている

```python:Main
def main():
    p = PrintBanner("Hello")
    p.print_weak()
    p.print_strong()
```

### 実行結果

```shell:実行結果
Air% python adapter_pattern.py
(Hello)
*Hello*
```

## パターン2 委譲を使ったパターン
- PrintBannerクラスのフィールドにBannerインスタンスが含まれる
- PrintBannerクラスはprintWeakメソッドが呼ばれた時に、Bannerクラスに実際の処理を委譲する
    - 具体的な処理はBannerに任せる
    
![2019-10-14-22-42-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179132/a0a3f2fc-9b28-3fe5-e4f8-f2a65d8a08d3.png)

### Printクラス
- 継承を利用するパターンではインタフェースで宣言しているが、委譲ではクラスとして宣言する
    - PrintBannerクラスが継承する

### コード全体

```python:委譲を使ったパターン
from abc import ABCMeta, abstractclassmethod

class Banner():
    def __init__(self, string):
        self._string = string
    def show_with_paren(self):
        print("({})".format(self._string))
    def show_with_aster(self):
        print("*{}*".format(self._string))

class Print(metaclass=ABCMeta):
    @abstractclassmethod
    def print_weak(self):
        pass
    @abstractclassmethod
    def print_strong(self):
        pass

class PrintBanner(Print):
    def __init__(self, string):
        self._banner = Banner(string)
    def print_weak(self):
        self._banner.show_with_paren()
    def print_strong(self):
        self._banner.show_with_aster()

def main():
    p = PrintBanner("Hello")
    p.print_weak()
    p.print_strong()


if __name__ == "__main__":
    main()
```

## 所感
- すでに作られているプログラムや前バージョンのAPIを拡張する場合に利用できると考える
    - 既存コードを変更せずに機能拡張できるところが大きい
UnityのWebGLビルドをFirefox 68.0 以降でローカル実行する方法

# ※追記

`Build & Run`をするとUnityが自動でローカルサーバーを立てて実行してくれるようです。ビルドのたびに異なるポート番号が割り振られていることを確認しました。

# はじめに

UnityでWebGLビルドしたファイルをローカル上で実行しようとするとこのようなメッセージが表示されます。

> It seems your browser does not support running Unity WebGL content from file:// urls. Please upload it to an http server, or try a different browser.

「このブラウザはローカルファイルのWebGL実行は対応していないと思われるので、サーバーにアップするか別のブラウザを試してください」という旨が書かれています。

以前はFirefoxでは動作していたのですが、Firefox 68.0以降で変更があり設定が必要になったので紹介しようと思います。

# 環境

- macOS 10.14.6
- Firefox 69.0.3 (64 ビット)

# TL;DR

**※ セキュリティに関する設定なので、自己責任でお願いします。**

1. Firefoxを開いてURL欄に`about:config`と入力する
2. 検索欄で`file_unique_origin`と入力する
3. ダブルクリックで値を`false`にする

<img width="513" alt="スクリーンショット 2019-10-14 23.00.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/9316bc61-8f7f-fb63-862f-831b98736ac6.png">


## どんな設定？

セキュリティに関する設定だそうです。

> **CVE-2019-11730: Same-origin policy treats all files in a directory as having the same-origin**
> A vulnerability exists where if a user opens a locally saved HTML file, this file can use file: URIs to access other files in the same directory or sub-directories if the names are known or guessed. The Fetch API can then be used to read the contents of any files stored in these directories and they may uploaded to a server. Luigi Gubello demonstrated that in combination with a popular Android messaging app, if a malicious HTML attachment is sent to a user and they opened that attachment in Firefox, due to that app's predictable pattern for locally-saved file names, it is possible to read attachments the victim received from other correspondents.
https://www.mozilla.org/en-US/security/advisories/mfsa2019-21/#CVE-2019-11730

Webはあまり詳しくないのですが、同一ディレクトリやサブディレクトリ内にアクセスできると意図せずデータがアップロードされることがあるため、デフォルトでアクセス出来ないようにした変更のようです。

# その他: ローカルサーバーを立てる方法

Macではターミナルで以下のコマンドを打って実行できました。

```.bash
# WebGLビルドで生成されたindex.htmlがあるディレクトリに移動します。
$ cd move/to/path

# python3がインストールされていない場合は実行(Homebrewが必要)
$ brew install python3

# サーバー実行
$ python3 -m http.server 8000

# ローカルホストの指定ポートにアクセスすれば実行することが出来ます。
# http://localhost:8000/
```

# 参考

- [ローカルUnity WebGLを実行できません（file：// url）Edgeを除くすべてのブラウザー！ -Unityフォーラム](https://forum.unity.com/threads/unable-to-run-local-unity-webgl-file-url-all-browsers-except-edge.709490/)
- [Issues with latest Firefox 68.0 - previewing sites locally - Mobirise Forums](http://forums.mobirise.com/discussion/21485/issues-with-latest-firefox-68-0-previewing-sites-locally)
- [Unity WebGLでビルドしたものが再生できない - Qiita](https://qiita.com/Sabanna-Hirokazu/items/8e644932571c9d05917e)
CentOS 6にNginx stable最新版をインストール（公式repository）

# はじめに

公式repositoryを利用してCentOS6にNginx stable最新版をインストール
親記事：[Nginxの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/df4a0baaaad9c932ea30)
参考：[nginx: Linux packages](https://nginx.org/en/linux_packages.html#RHEL-CentOS)

## サポート

本手法で導入した場合、nginxの開発が停止するまでサポートされると思われる。
特定のバージョンを指定しなければ、stable最新版が常に提供されると思われる。

## LOG

### レポジトリ登録

```shell-session
# vi /etc/yum.repos.d/nginx.repo
```

```shell-session:/etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
```

### インストール

```shell-session
# cat /etc/redhat-release
CentOS release 6.10 (Final)

# yum install -y nginx
... 略
```

### nginx起動/停止

```shell-session
# service nginx start
Starting nginx:                                            [  OK  ]

# service nginx status
nginx (pid 107) is running...
```

```shell-session
# service nginx stop
Stopping nginx:                                            [  OK  ]

# service nginx status
nginx is stopped
```

### nginx自動起動設定/設定解除

```shell-session
# chkconfig nginx on

# chkconfig --list nginx
nginx           0:off   1:off   2:on    3:on    4:on    5:on    6:off
```

```shell-session
# chkconfig nginx off

# chkconfig --list nginx
nginx           0:off   1:off   2:off   3:off   4:off   5:off   6:off
```

### 各種確認

```shell-session
# which nginx
/usr/sbin/nginx

# nginx -v
nginx version: nginx/1.16.1

# yum info nginx
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
Installed Packages
Name        : nginx
Arch        : x86_64
Version     : 1.16.1
Release     : 1.el6.ngx
Size        : 2.6 M
Repo        : installed
From repo   : nginx-stable
Summary     : High performance web server
URL         : http://nginx.org/
License     : 2-clause BSD-like license
Description : nginx [engine x] is an HTTP and reverse proxy server, as well as
            : a mail proxy server.
```
CentOS 6にNginx mainline最新版をインストール（公式repository）

# はじめに

公式repositoryを利用してCentOS6にNginx mainline最新版をインストール
親記事：[Nginxの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/df4a0baaaad9c932ea30)
参考：[nginx: Linux packages](https://nginx.org/en/linux_packages.html#RHEL-CentOS)

## サポート

本手法で導入した場合、nginxの開発が停止するまでサポートされると思われる。
特定のバージョンを指定しなければ、mainline最新版が常に提供されると思われる。

## LOG

### レポジトリ登録

```shell-session
# vi /etc/yum.repos.d/nginx.repo
```

```shell-session:/etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
```

### インストール

```shell-session
# cat /etc/redhat-release
CentOS release 6.10 (Final)

# yum install -y nginx
... 略
```

### nginx起動/停止

```shell-session
# service nginx start
Starting nginx:                                            [  OK  ]

# service nginx status
nginx (pid 107) is running...
```

```shell-session
# service nginx stop
Stopping nginx:                                            [  OK  ]

# service nginx status
nginx is stopped
```

### nginx自動起動設定/設定解除

```shell-session
# chkconfig nginx on

# chkconfig --list nginx
nginx           0:off   1:off   2:on    3:on    4:on    5:on    6:off
```

```shell-session
# chkconfig nginx off

# chkconfig --list nginx
nginx           0:off   1:off   2:off   3:off   4:off   5:off   6:off
```

### 各種確認

```shell-session
# which nginx
/usr/sbin/nginx

# nginx -v
nginx version: nginx/1.17.4

# yum info nginx
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirror.fairway.ne.jp
 * extras: mirror.fairway.ne.jp
 * updates: mirror.fairway.ne.jp
Installed Packages
Name        : nginx
Arch        : x86_64
Version     : 1.17.4
Release     : 1.el6.ngx
Size        : 2.6 M
Repo        : installed
From repo   : nginx-mainline
Summary     : High performance web server
URL         : http://nginx.org/
License     : 2-clause BSD-like license
Description : nginx [engine x] is an HTTP and reverse proxy server, as well as
            : a mail proxy server.
```
【sass】scssの変数ファイル

##開始タグ
独学でSass（scss）を学んでいるけれども、自分なりに変数ファイルをまとめたのでメモ。
scssのコンパイルはGulpで行なっています。

##方法
変数ファイルは下層のscssファイルでもimportで読み込むため、ファイル名の冒頭には`_`をつけておきます。
ディレクトリ構造はこんな感じ。

```:project構造
Project
|
|--common
  |
  |--css
    |
    |--partial
       |
       |--_variables.scss
```
※コンパイル先のディレクトリでは、同ディレクトリ構造になるようにしています。

変数ファイルの中身はこちら。

```scss:_variables.scss
@charset "UTF-8";

// ---------------------------------------------------------------------------
//  font
// ---------------------------------------------------------------------------
$ff_notosan: 'Noto Sans CJK JP', sans-serif;

// ---------------------------------------------------------------------------
//  Responsive Style
// ---------------------------------------------------------------------------

// ----- デバイス ----- //
$pc: 950px;
$sp: 768px;
$sp480: 480px;
$sp414: 414px;
$sp375: 375px;
$sp320: 320px;

// ---------------------------------------------------------------------------
//  Basic Style
// ---------------------------------------------------------------------------

// ----- ベースの値 ----- //
$base_color: #1886cc;
$base_color02: #b5d81e;
$base_f_color: #1a1a1a;
$base_f_family: 'Noto Sans CJK JP', 'ヒラギノ角ゴ W3', 'メイリオ', Meiryo,
	'ＭＳ Ｐゴシック', 'MS PGothic', Arial, Helvetica, Verdana, sans-serif;
$base_f_size: 1.6rem;
$base_l_height: 1.7;

// ----- SP ----- //
// $base_f_color_sp: #333;

// ---------- Link ---------- //
$base_l_color: #333;
$base_opacity: 0.7;

/* ------------------------------------------------------------------------ */
/* Responsive Style
--------------------------------------------------------------------------- */
// ----- デバイス ----- //

@mixin pc {
	@media screen and (max-width: ($pc)) {
		@content;
	}
}
@mixin tab_min {
	@media screen and (min-width: ($tab)) {
		@content;
	}
}
@mixin tab_max {
	@media screen and (max-width: ($tab)) {
		@content;
	}
}
@mixin sp {
	@media screen and (max-width: ($sp)) {
		@content;
	}
}
@mixin sp480 {
	@media screen and (max-width: ($sp480)) {
		@content;
	}
}
@mixin sp414 {
	@media screen and (max-width: ($sp414)) {
		@content;
	}
}
@mixin sp375 {
	@media screen and (max-width: ($sp375)) {
		@content;
	}
}
@mixin sp320 {
	@media screen and (max-width: ($sp320)) {
		@content;
	}
}

// ---------------------------------------------------------------------------
//  Other
// ---------------------------------------------------------------------------
$wid_con01: 1200px;

// ---------------------------------------------------------------------------
//  Animation
// ---------------------------------------------------------------------------
$ani_fast: all 0.1s ease-in-out;

// ---------------------------------------------------------------------------
//  Common Original
// ---------------------------------------------------------------------------
```
用途に応じて編集・削除は行いますが、現状これをベースにしています。
色や行間、fontfamilyなどよく使いそうなものはまとめました。
必要であれば計算式などはここでまとめることが多いです。

##閉じタグ
まだまだ物足りない感は否めないですね。
「こんな記載もしておいた方がいいよ」などございましたら、ご指摘いただけるとありがたいです！