OmniAICreator/Qiita-1.07M huggingface dataset:
アクセス修飾子のprivateの用途・メリット

## はじめに

アクセス修飾子のprivateについての基本的な解説です。

var, let, constのように特徴やメリットがあり、開発の品質にも直接関わってくるものですのでしっかりと用途を考えて使えるように改めてまとめました。
<br>

## privateはクラス外からアクセスできない

Rubyの源流であるオブジェクト指向の三大原則の一つ「**カプセル化**」は、あるクラスの変数やメソッドを他のオブジェクトから呼び出せないようにする考え方です。

これにより必要のない変更操作などを防ぐ**安全性が担保**できます。

Rubyにおいてprivateアクセス修飾子のついた(また修飾子以降に書かれた)メソッドは全てクラスの外からアクセスができなくなります。
クラスの中から呼び出される形でのみ使用することができます。

```ruby:例
class House

  private def getAsset
# 財産を手に入れるメソッド
  end

end
```

<br>

## 外からアクセスできないメソッドを定義する理由はなんなのか？

理解していないうちはprivateなんていらないかと思う人もいますが、privateはセキュリティの観点から見て必要不可欠な機能です。

もしアクセスできる領域が限定されているべきなのに限定されていない値があったとしたら、例えば以下のようなことが想定できます。

- **銀行口座インスタンスの残高を外部から自由に書き換えできる**
- **RPGにおいてキャラクタインスタンスのステータスを外部から好き勝手に書き換えられる**
- **ActionModelクラスの属性を、正規の手順を踏まずに好き勝手書き換えられる**
- **あるユーザがSNSで他ユーザのパスワードをのぞき見できる**

いずれも非常に危険で、アプリケーションの存続が危ぶまれるケースです。
<br>

## 追記
### privateについて

カプセル化を実現した代表的な言語であるJava等と違い、Rubyにおけるアクセス修飾子は以下のような挙動をします。

Rubyリファレンスマニュアルによると、privateは以下のようにあります。

**「private に設定されたメソッドは関数形式でしか呼び出せません。」**

つまり`インスタンス.privateメソッド`の形式では呼ぶことができないということですね。

このときメソッドを呼び出されるインスタンスのことを、**「“メソッドを実行しろ“というメッセージを受け取っている対象」**と解釈して**「レシーバ」**と呼んだりします。

クラス内で直接privateメソッドを呼び出すことができるけれども、レシーバ形式での呼び出しが不可能になります。

```ruby
class A
 
  def call_private
    private_method    # 関数形式での呼び出し(できる)
  end
 
  def call_private_with_reciever
    self.private_method    # レシーバ（self）形式での呼び出し(できない)
  end
 
  private
   
    def private_method
       p "只今privateメソッドテスト中!"
    end
 
end
```

a = A.new
a.call_private #呼び出せます
a.call_private_with_reciever #エラーになります
また、呼び出そうと思えばクラスの外からもsendメソッドでprivateなメソッドを呼び出せてしまいます。
よって、Rubyのアクセス修飾子は厳密なカプセル化を実現する目的とはまた違うみたいですね。

```ruby
a.send(:private_method) # 呼び出せます
```

※やろうと思えばKernel#exitを呼び出して、アプリケーションを強制終了させることも外部から可能になってしまうので、外部から引数として変数名を入力させるアプリケーションは大変危険ですので実装すべきではないです。
<br>

### protectedについて

また、protectedについてはリファレンスによるとこうあります。

**「protected に設定されたメソッドは、そのメソッドを持つオブジェクトが selfであるコンテキスト(メソッド定義式やinstance_eval)でのみ呼び出せます。」**

つまり、同一クラス(および継承先クラス)からならレシーバ形式`self.protectedメソッド`でも呼び出せるということですね。

```ruby
class Sample
  def == other #==の処理を独自に更新しようとしています。Rubyでは==をはじめ全ての演算子が関数オブジェクトとして扱えるので、このような更新が可能です。
    if self.class == other.class
      internal == other.internal
    else
      super
    end
  end
  protected
  def internal; :sample; end
end

Sample.new == Sample.new #=> true
```

## まとめ

privateの重要性は現実世界では大切なものを守るとき、例えば家に置いてある財産を泥棒に取られないようにするために「**家の出入り口に鍵をかける**」ことと考え方は同じです。

「**大切なものに対するアクセスは得てして不自由である方が扱いやすい**」のです。
<br>

## 参考
この記事は「CodeShip」内での実際の質疑応答や指導・アドバイスの一部を基に作成しています。
Microsoft Azure資格 (AZ-300) を取得するまでにやったお勉強のお話

# はじめに
Microsoft Azure の資格の一つである AZ-300 を取得したので、
勉強した内容&所感についてメモします
（試験内容には触れていません)

Microsoft 資格: Azure Solutions Architect Exprt の必須要件の一つとなる資格です

# AZ-300について

https://www.microsoft.com/ja-jp/learning/exam-az-300.aspx
こちらを参照のこと

# 事前知識
- 普段はオンプレミス仮想化技術(vSphere/Hyper-Vなど)を触っています
- Azure/AWSは個人的にも興味があり、趣味レベルでクラウドサービスを使ってます
- Azure含め、パブリッククラウド上の構築経験はありません
- Azure ポータルはAZ100/101取得時に触っていたレベルです

# やったこと
- Microsoft Learn
  - 普段利用していない部分(私の場合はWeb App/コンテナ周り)を中心にざっくりお勉強しました   
    (非常に膨大な量があるため、全部はやりきることを最初の目標にするのは厳しいと思います)
  - 以降は、以下記載の問題集を解いた際に理解が不足していると感じた項目を抜粋して確認しました
- 練習用のWeb問題集(Udemy)を解きました
  - 私が利用した講座は、「AZ-300 Azure Architecture Technologies Practice Test」というものでした  
    (https://www.udemy.com/course/az-300-azure-architecture-technologies-practice-test/)
  - 不明点は実際にAzureアカウントを用意して構築してみたり、Microsoft ドキュメントを読んだりして解消しました

# 試験が終わった後の個人的な所感
- Expert資格の試験ということもあり、私は試験時間かなりぎりぎりまで使いました
  - 以前受けたAZ-100/101の時と違い日本語試験が追加されたので、大分楽になったはずなのですが、、、  
    (ちょいちょい訳に問題はあるため、英語と見比べながら解きました)
Slack ワークフロービルダーで遊んでみた。PRをもっと簡単に、マージ通知も簡単に。

# 初めに

おそらく slack の GitHub の App でできることだと思います...。

やりたいことを書いて、
やり方を書いて、
最後に成果物を貼り付けています。

## やること

2つの ワークフローを使って、

* 作業者が、PRを出しやすい
* レビュワーが、マージしたことを通知しやすい

この2つを実現していきます。

### PR用ワークフロー

全体図はこんな感じ、

![写真ライブラリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/871ccd94-9c25-f04d-ebf4-5865387a770c.png)


1. 作業者が PR を作ったら、ワークフローを開始
2. 入力フォームに、内容などを入力し、送信
3. PR がレビュワーに通知される

フォームの作成図
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3332313238322f31626564393436642d313835642d383263392d336231302d3066626132336237336636612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/4b9165b0-3ff2-e5b4-5f6c-f98a2cc8cd67.png)
<img width="1136" alt="スクリーンショット 2019-10-22 15.01.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/48425fe9-c6fe-f822-a6b4-7c446aae5002.png">


入力フォーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/c09c55d0-60a3-efbb-903f-79f42820782f.png)

送信後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/686b41e1-fe84-6bd0-ba7d-dacea6bf7584.png)

レビュワーの箇所は適宜変えてもらえれば、と思います。


### マージ通知用ワークフロー

これがすごい楽しかったです。

トリガーが、絵文字

メッセージに対して、指定した絵文字が送られた時、ワークフローが開始されるというもの。

**注意**
**事前に、 merged っぽい絵文字を作っておく必要があります！！！！**



全体像はこんな感じ

<img width="1136" alt="スクリーンショット 2019-10-22 15.01.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/66d92ed9-af09-1918-f74f-ca234c12ad74.png">

動きは

絵文字が選ばれると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/19982522-e733-f48c-e8db-0ccfe38e5b6d.png)

メッセージを送信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321282/a4e201b8-34e5-594b-d5ff-07aca14d0bba.png)


以上！！

## 成果物

- PR 入力フォーム  
https://gist.github.com/yasudanaoya/abc7c88213fe4c7bfea9e6cbf3c00390
- マージ通知  
https://gist.github.com/yasudanaoya/4f2f5c299800ea45a391066e276c0991

適宜 チャンネル名を変えていただければ使えます。

もっともっと面白くて楽しい使い方を発明したいです！！！

新機能のリリースが待ち遠しい...
CENTOS8.0にCmake3.15.2を使ってGPU で高速演算ができる( CUDA10.1使用 ) Gromacs2018.3をインストールする。

Gromacsインストールの前に以下の作業を行う。
**openssh-serverの開設 ( https://qiita.com/chemises/items/9b3368c5ce972df57c82 )**
**CUDA10.1のインストール ( https://qiita.com/chemises/items/f35b93d786d9121ac978 )**
**Cmake3.15.2のインストール ( https://qiita.com/chemises/items/efff39a67717e1ee2fb3 )**
**gccコンパイラ8.2.1のインストール (https://qiita.com/chemises/items/730a3d2dc527cc7cbc95 )**



**<font color="Red">wget</font>を使ってネットワークから<font color="Blue">Gromacs2018.3</font>のソースコードをダウンロードする。**

    $sudo wget http://ftp.gromacs.org/pub/gromacs/gromacs-2018.3.tar.gz

**zipファイルを展開**

    $tar -zxvf gromacs-2018.3.tar.gz

**Gromacs2018.3のディレクトリに入る**

    $cd gromacs-2018.3

**Bulidをするためのディレクトリを作成しそのディレクトリに入る。**

    $mkdir build
    $cd build

**<font color="Red">cmake</font>を使ってBuildを行う。**

    $cmake .. -DCMAKE_C_COMPILER=gcc ¥ 
     -DCMAKE_CXX_COMPILER=g++ ¥ 
     -DGMX_MPI=OFF ¥ -DGMX_DOUBLE=OFF -DGMX_OPENMP=ON ¥ 
     -DGMX_GPU=ON ¥ -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda
     -DBUILD_SHARED_LIBS=OFF ¥ -DGMX_PREFER_STATIC_LIBS=OFF ¥
     -DGMX_FFT_LIBRARY=FFTW3 ¥
     -DCMAKE_INSTALL_PREFIX=/usr/local/gromacs

**<font color="Red">make</font>を使ってインストールする。**

    $make -j4
    $sudo make install

**インストールが終わったらPATH指定を行う。**

    source /usr/local/gromacs/bin/GMXRC
GoogleスプレッドシートとQualityForwardを連携させよう

[QualityForward](http://bit.ly/34VvAV7)はクラウドベースのテストケース管理システムです。

テスト管理をクラウドに移行する前はExcel、Googleスプレッドシートを使っていたという事例はとても多いです。むしろExcelやGoogleスプレッドシートでの管理が煩雑になったり、無理が出てきたためにクラウドサービスに移行するのではないでしょうか。

しかしGoogleスプレッドシートなどはとても便利なサービス・ソフトウェアです。既存のシステムとの連携や、取得したデータをグラフで可視化するのに使うことを想定し、Googleスプレッドシートで動くGoogle Apps Script版のQualityForwardライブラリの開発をはじめました。

現在はプロジェクトの取得のみですが、今後バージョンアップを重ねていきます。

## インストール

Google Apps ScriptでのプロジェクトIDは `1ppRPLjuClG0MhtnXYbskdZ8uYGbyCFHv7MFhr0GYa-3IAKEh8B7lmTMb` になります。これを取り込んでください。以下はデフォルトの `QualityForward` として取り込んだ場合の書き方です。

## 使い方

以下のように使います。getCurrentProjectで現在のプロジェクトが取得できます。

```js
var apiKey = 'aaa';
var qf = new QualityForward.Client(apiKey);
var p = qf.getCurrentProject();
Logger.log(p ? p.name : qf.error);
```

pがfalseだった場合は取得失敗しています。qf.errorで直近のエラー情報を取得できます。この場合のエラーはAPIキーが違ったり、ネットワークエラー（QualityForwardがメンテナンス中など）になるでしょう。

## まとめ

スプレッドシートと連携してデータを定期的に取得したり、Googleドキュメントにレポートとして自動記述するのも良いでしょう。ぜひ皆さんのプロジェクト、テストで役立ててください。

[QualityForward](http://bit.ly/34VvAV7)
テスト管理システムの相違について

[QualityForward](http://bit.ly/2N8xBao)はクラウドベースのテスト管理サービスです。テスト管理（テストマネジメント）システムと言っても様々な種類があったり、似たような機能を持ったシステムもあります。今回はその種類と目的の違いについて紹介します。

## BTS（バグトラッキングシステム）

BTSがテスト管理としてあげられることが多いですが、これは発生した不具合（バグ）を報告、管理するためのシステムになります。[Bugzilla](https://www.bugzilla.org/)が有名です。一つずつの不具合に対して専用のURLを作成して、データベースで管理します。そしてディスカッションを通してバグの修正状態をモニタリングしたり、ソースコード管理と連携して修正内容が追えるようになっています。

BTSはリリースされた、もしくは開発者向けに公開されたソフトウェアをベースとしています。それを試したり、利用する中で発生した問題点について取り上げます。

## CI（継続的インテグレーション）

DevOpsの文脈の中であがることの多いCIは、テストを自動化するための仕組みです。ソースコードを更新したタイミングで実行され、その実行内容と結果を管理します。ソースコードレビューシステムと連携し、自動テストした結果に応じてソースコードの受け入れ（マージ）可否判定に使われます。

CIの結果としてテストが失敗するのは良くあることです。そのため開発者に対してテスト結果の通知はしますが、BTSに自動登録されるようなことはありません。また、CIは自動化されたテストを行いますので、マンパワーによるテストを管理するのには適しません。

## プロジェクト管理/課題管理

プロジェクト管理においては、各タスクをIssue（課題、チケット）といった単位で管理します。BTSのように不具合の内容を登録することもありますが、多くのプロジェクト管理はアサインされているメンバーしか投稿できません。BTSの場合は誰でも投稿できます。

BTSなどと連携するプロジェクト管理では、まず不具合の発生時にBTSに記述し、その内容がプロジェクト管理のタスクとして発生します。プロジェクト管理では開発だけでなく、他のステークホルダーとの調整や要望など、より広い範囲でのタスクを扱います。

## テストケース管理システム

システムをマンパワー（一部自動化も可）でテストする際にテストケースを作成します。入力値と期待値を羅列し、実際にその結果になっているのかをテストします。人が手入力を行う場合もあれば、Webブラウザを自動操作するなどして自動化する場合もあります。

テストケースは大量に作成されるので、プロジェクトを横断してコピーしたり、バージョンアップ時にリサイクルする、条件（WebブラウザやOSのバージョンなど）を変えて利用します。私たちの提供する[QualityForward](https://cloud.veriserve.co.jp/)もテストケース管理システムの一つです。

テスト結果は報告書にまとめられたり、プロジェクト管理システムと連携して直すべき不具合として登録されます。

## アプリケーション・ライフサイクル・マネジメント（ALM）

ソフトウェア開発と、その後の保守プロセスまで含めて管理するシステムです。ソフトウェア開発ライフサイクル（SDLC）と近い文脈で用いられますが、ALMの場合はより広く、運用フェーズも含めて管理されます。ALMの中にテスト管理、BTS機能を持っていったり、外部システムと連携するようになっています。

システムが大型なため、導入までの敷居が高くなってしまうのが難点です。数千〜数万人月を超えるような大型なプロジェクトでの利用が良いでしょう。

## ソースコードレビューシステム

開発チーム内でソースコードレビューを行うのに専用のシステムを用いる場合があります。例えばFacebookが開発している[Phacility](https://www.phacility.com/)ではレビュー結果とBTSを連携させています。GitHubのソースコードレビューはCIと連携していたり、課題管理に登録もできます。

ソースコードレビューシステムは名前の通り、開発工程や保守工程におけるソースコードの変更点を確認するためのシステムになります。今は自動レビューを行ってくれるシステムもあります。

## まとめ

[Wikipediaによればテスト管理といった場合にはテストケース管理システムを指し示す](https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)ようです。機能的に似通っていることもあり、どのツールをどのタイミングで導入すれば良いか分かりづらいという方も多いでしょう。また、システムによって開発フェーズのどこに適合するのか異なります。専門のツールもあれば、体系的に全体のプロセスに関わるものもあります。

いずれにしてもソフトウェアの品質を向上させ、安定した機能をユーザに届けるためにテストは欠かせません。これらのシステムを使いこなし、皆さんのシステム開発に活かしてください。

QualityForwardはクラウドベースのテスト管理サービスを提供しています。Excelを使ったテスト管理に不便さを感じ始めたら、ぜひQualityForwardをチェックしてください。

[QualityForward](http://bit.ly/2N8xBao)
PythonからQualityForward APIを利用する

[QualityForward](http://bit.ly/36IQWqk)はクラウドベースのテストケース管理システムです。

AI、機械学習の波もあって開発現場でPythonを利用することが多くなっています。システム全体でなくとも、ちょっとしたスクリプトをPythonで書くという人は多いですし、Jupyter Notebookを使って解析はPythonで行っている会社もあります。

そんな中でテスト管理のデータを役立てるべく、QualityForwardのPythonライブラリを開発しはじめました。現在はプロジェクトの取得のみですが、今後バージョンアップを重ねていきます。

## インストール

コードは[goofmint/qualityforward-py: QualityForwardのPythonライブラリです](https://github.com/goofmint/qualityforward-py)にあります。まだpipインストールには対応していません。

## 使い方

以下のように使います。get_current_projectで現在のプロジェクトが取得できます。

```py
from qualityforward.QualityForward import QualityForward

q = QualityForward("0aa...340") # APIキー
print(q.get_current_project().name)
```

## まとめ

Pythonスクリプトを使ってテスト結果のデータを取得したり、逆にプログラミングした内容でテストケースを自動作成するといった使い方も考えられます。今後のバージョンアップをお待ちください！

[QualityForward](http://bit.ly/36IQWqk)
CENTOS8.0にGCC8.2.1コンパイラをインストール。

**ソフトウェアをコンパイルする際に必要な<font color="Red">gccコンパイラー(ver. 8.2.1)</font>をインストールする。**

    $sudo yum -y install gcc
    $sudo yum -y install gcc-c++

**以下のコマンドでgccのバージョンを確認できる。**

    $gcc --verison
「エンジニアのためのマネジメントキャリアパス」を読んだ感想（完全自分用メモ）

[エンジニアのためのマネジメントキャリアパス](https://www.oreilly.co.jp/books/9784873118482/)

テックリードからCTOまで、エンジニア視点でマネジメントスキルについて書かれた本。

読んでいて思わず「そうそう！」とうなずいてしまったり、「なるほど、上司はそういう視点で部下を見るのか」とハッとなる内容がいくつもありました。

私が特にオススメなのは管理職とスペシャリストの仕事内容について書かれていた記事ですね。

どちらのキャリアパスを選ぶのかはエンジニアが一度は通る道だと思いますが、将来について迷っている人は「想像していた部下を持たないシニアエンジニアとその現実」「私の想像していた管理者とその現実」を読んでおいたほうが良いですよ。

以下は今の自分にとって重要だと思った箇所についての自分用メモになります（答えは全て本の中に出てきます）。

全部答えを暗記する必要はありませんが、こういう書き方のほうが自分は覚えやすい&振り返りやすいので、備忘録用に書き出していってます。

#1章 マネジメントの基本 

Q1.上司に求めるべき事を3つ挙げてください

#3章 テックリード 

Q2.優秀なテックリードなら必ず知っている、ある奇妙 な「コツ」 とは何ですか？

Q3.「プロジェクト管理の実務」で紹介されているプロジェクト管理における重要な指針を5つあげてください。

Q4.プロセスツァーとは何ですか？

Q5.優秀なデックリードと評価されるために、著者が特に重要だと思う点を4つあげて下さい。

#4章 人の管理 

Q6.人の管理人の管理で求められる主な仕事を4つあげてください

Q7.直属の上下関係で、部下と短期間で良好な関係を築くためのコツを5つあげてください

Q8.著者がチームメンバ ーとのコミュニケーションで効果的な方法としてあげているものはなんですか？

Q9.著者が1on1ミーティングで配慮すべきだと説明している点を5つあげてください

Q10.著者が説明している1on1ミーティングのタイプ4つと注意点2つをあげてください

Q11.ひどい上司が部下を細かすぎるくらい細かく管理するのに対し、すごい上司は部下をどう管理していますか？

Q12.筆者が本の中で説明している「効率よく仕事を任せる」ための実践的アドバイスを5つあげてください

Q13.著者が「継続的なフィードバック」を実践する上で有効だと指摘している対策を4つあげてください

Q14.管理者が勤務評価の要約を作成し、評価面談を行う際に役立つ指針を7つあげてください

#5章 チームの管理 

Q15.チームの意思決定を主導するコツを5つあげてください

Q16.チーム内の対立を解決しようとする際、するべき事とそうでない事を計8つあげてください

Q17.著者が説明している「チームの結束を乱す人」 タイプを3つあげてください

Q18.「管理者が担当すべき、より専門的なプロジェクト管理」について、著者が奨励している経験則を6つあげてください
古いパソコンを再生修理 詳しい方教えて下さい　質問

古いパソコンのハードディスクが壊れているのでインターネットにつながないで使おうと思います。

質問事項
　ハードディスクをマザーボードにつながないでフロッピーディスクドライブのみでbiosが起動するのかどうか？
　linuxのＯＳをフロッピーに入れる方法　windows98でパーツを増やしてもxp以降の性能にはならないです。
【PHP】「〜requires ext-gd * -> the requested PHP extension gd is missing from your system.」でパッケージがインストールできない時の解決法。

こんにちは！
現在、docker & Laravelでシステム開発を行なっています。
システム内に「データからグラフを作成してpdf出力する」という機能があり、必要なパッケージをインストールしようとしたところ、「requires ext-gd * -> the requested PHP extension gd is missing from your system.」と表示されてしまいインストールできなかったので、解決するまでを書きたいと思います。

```
開発環境
・docker
 - amazonlinux:2[nginx/php]
 - Mysql
```

# やりたいこと
PHPの拡張モジュール「gd」を有効にしたい！

# 解決策
`yum install php-gd.x86_64` を実行して必要なパッケージをインストール！

# やったこと
```
1： [composer require amenadiel/jpgraph]を実行。失敗。
２： gdが読み込まれていないことを確認。
３： [yum install php-gd.x86_64]を実行。
４： 無事にインストール完了。
```
## 1： `composer require amenadiel/jpgraph` を実行。失敗。
「データからグラフを作成してPDFで表示」という機能があり、実装のために「amenadiel/jpgraph」をインストールする必要がありました。そこで `composer require amenadiel/jpgraph` を実行したところ、下記のメッセージが表示されました。

```
Using version ^4.0 for amenadiel/jpgraph
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for amenadiel/jpgraph ^4.0 -> satisfiable by amenadiel/jpgraph[4.0.0].
    - amenadiel/jpgraph 4.0.0 requires ext-gd * -> the requested PHP extension gd is missing from your system.

  To enable extensions, verify that they are enabled in your .ini files:
    -
    - /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-pdo_pgsql.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

Installation failed, deleting ./composer.json.
```

**[google翻訳（一部抜粋）]**

```
-amenadiel / jpgraph 4.0.0にはext-gdが必要です*->要求されたPHP拡張gdがシステムにありません。
```

**ext-gd**が必要らしいです。
調べてみると「ext-gd」とはPHPの拡張モジュール「GD」のこと。GDはPHPでGIFとかJPEGなどを作成するために必要なモジュールみたいです。
参考：画像処理 (GD)/はじめに
https://www.php.net/manual/ja/intro.image.php

## ２： gdが読み込まれていないことを確認
`php -m`で読み込んでいるモジュールの確認ができます。
実行したところ、gdという単語が見当たりませんでした。どうやらgdライブラリをインストールする必要があるようです。

## ３：`yum install php-gd.x86_64`を実行。
`yum list`でyumを使ってインストール可能なパッケージの一覧を表示することができます。
gdに関するものを表示するために `yum list | grep gd` を実行。表示された一覧から関係がありそうな `php-gd.x86_64` をインストールするため `yum install php-gd.x86_64`を実行しました。

## ４：無事にインストール完了。
該当コンテナを再起動して、再度 `php -m` を実行すると「gd」が読み込めていました。
最後に `composer require amenadiel/jpgraph`を実行。無事にインストールが完了しました。

# つまづいた点
・ext-gdって何？
・拡張機能はどこから読み込んでいるの？
・php.ini のコメントを外しても有効にならないんだけど？

### ext-gdって何？
「gd」という拡張機能のことです。
`ext-gdが必要です*->要求されたPHP拡張gdがシステムにありません。`というエラーメッセージから「php ext-gd」で検索して、**「extはextensionか〜！グラフを画像にするためにイメージ作成のための拡張機能が必要なんだね！」**と理解して進めることができました。

### 拡張機能はどこから読み込んでいるの？
拡張機能のライブラリは、php.ini内の[extension_dir={Path}]に書いてあります。
僕の場合は `extension_dir => /usr/lib64/php/modules => /usr/lib64/php/modules` となっており、中には拡張子が「~.so」のファイルがありました。`php -m`で表示されるモジュールはこのディレクトリのファイルから読み込んでいるのだと思います。

### php.ini のコメントを外すだけで有効にはならない。
PHPの拡張機能を追加するために色々検索したのですが、最初に見つけたのが「php.ini」のコメントアウトを外すという記事。そこで、`php --ini`を実行してphp.iniファイルのあるディレクトリを探し、「extension=gd」のコメントアウトを外しました。しかし、「gdは使えないよ！」というメッセージが表示されたことから、そもそもgd自体入っていないから、コメントアウトを外しても意味がなかったのだと思います。
lftp で "Certificate verification: certificate common name doesn't match requested host name" というエラー

# 問題
あるサブドメイン形のWebホスティングサービスに lftp で接続しようとすると、ls コマンドを叩いただけで次のようなエラーが発生しました。

```
lftp ホスト名:~> ls
ls: Fatal error: Certificate verification: certificate common name doesn't match requested host name ‘（ホスト名）’ (IPアドレス)
```

# 解決方法
`~/.lftprc` に次の内容を追加します。

```
set ssl:check-hostname no
```

エラーメッセージの意味は、「SSL証明書に記載されているホスト名と一致しない」ということです。
今回使ったホスティングサービスでは、SSL証明書がワイルドカード型になっておらず、ホスト名が example.com （例）の形になっていました。そのため、サブドメインの qiita.example.com （例）とはホスト名が違うというエラーが発生していました。
要は業者の設定が悪いのですが、ホスト名が一致していないこと以外は問題なかったので、とりあえずホスト名のチェックを外すことで回避できます。


# 誤った解決方法
エラーメッセージでGoogle検索しても、残念ながら日本語の情報では、誤った情報しか出てきませんでしたのでご注意ください。

## 誤った方法1

```
set ftp:ssl-allow off
```

SSL を使わないというのは論外です。

## 誤った方法2

```
set ssl:verify-certificate no
```

SSL を使っても証明書をチェックしないのでは全く意味がありません。
oandapyV20を使って為替データを取得

為替の値動きを分析するためにpythonを使ってプログラミングしています。
今回は、リアルタイムの為替情報を取得するためのコードを紹介します。

---

##事前準備
コーディング環境としてjupyter notebookを使っています。
anaconda導入時にいろいろなライブラリが自動的に入っていると思いますので、
今回はoandaのライブラリのみインストールすれば良いです。

```python:APItest.py
!pip install oandapyV20
```
古い記事だとoandapyV20ではなく、oandapyをインストールしてますが、そちらをやってみると、インストールまではいけますが、APIの取得がなかなかうまくいきません。
下記のエラーメッセージが返ってきます
**AttributeError: module 'oandapy' has no attribute 'API'**

#以下は実際のコードです
##必要なライブラリ導入

```python:APItest.py
from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments
import pandas as pd
```

##APIアクセス用情報登録

```python:APItest.py
access_token = "XXXXXXXXX" #自身のaccess_tokenを記載
accountID = "XXX-XXX-XXXXXXX-XXX" #自身のaccountIDを記載
api = API(access_token=access_token)
```



##実際のデータ取得
```python:APItest.py
# 1時間間隔で500データ（ドル円）を取得
r = instruments.InstrumentsCandles(instrument="USD_JPY", params={"count": 500, "granularity": "H1"})
api.request(r)
```
instrumentは**通貨ペア**
countは取得する**データ数**（最大5000らしい）
granularityは**時間足**
を意味します。
IEでRefererが送信されなかった

# はじめに
AWSのWAFでRefererでセキュリティを強化しようとして、IE11で動かしたときだけ、想定通りにならなかった。

# 結論
IE11は、リクエストのヘッダーにRefererが送信されないようです。HTMLでなにも設定していない場合なので、タグを個別に設定したら送信されるかもしれません。

# 最後に
IEのために、いろいろな苦労をしている人の気持ちが少しわかりました。
kotlin > dozerでマッピング (作成中)




# sample


[bringmeister/dozer-with-kotlin: A demo project to show how to use Dozer with Kotlin.](https://github.com/bringmeister/dozer-with-kotlin)



# First Step




# API Mappings

[via API · GitBook](https://dozermapper.github.io/gitbook/documentation/apimappings.html)


以下、抜粋

>Since version 5.3 Dozer offers two ways for specifying explicit mappings. 
>API mappings are intended to solve all of the mentioned problems. 

>バージョン5.3以降、Dozerは明示的なマッピングを指定する2つの方法を提供します。
XMLマッピングの欠陥は動的に生成できないことです。
APIマッピングは、前述の問題をすべて解決することを目的としています。





```kotlin

@NoArgConstructor
class UserDto(name: String) {
    var name: String = name
}



class UserDto {
    constructor() {}
    
    lateinit var name: String
}


```
python初心者がimportエラー(ModuleNotFoundError)で詰みかけた話

#あらまし
インストールしたはずのモジュールがimport出来ない。
でもフォルダを見に行くと確かに存在している。
「何で読めへんねん！」をいったん解決できたのでまとめてみる。

pythonの本はたくさん読んでみたけれど、何故かこの手のエラーをちゃんと解説している本はまだ見ていない気がする。何でなんだ？初心者が一番躓く部分だと思うんだけど…。

##知っておくと便利だった事(上から重要順)
1.pip show [module]　…　moduleの在り処を教えてくれる
2.pip install [moudle]　と　import [module]　は必ずしも同一名ではない
3.sys.path　…　importが読みにいっているフォルダを教えてくれる
4.pprint　…　リストの整形

##1.pip show [module]
モジュールがどこに存在しているか教えてくれる、(初心者にとっては)結構な神コマンド。
使い方：コマンドプロンプト開いて探したいモジュールを[module]に入れる。
例えばpandasの場合

```
pip show pandas
```

####実行結果
```
C:\Users\xxxx>pip show pandas
Name: pandas
Version: 0.25.1
Summary: Powerful data structures for data analysis, time series, and statistics
Home-page: http://pandas.pydata.org
Author: None
Author-email: None
License: BSD
Location: c:\users\xxxx\appdata\local\programs\python\python37-32\lib\site-packages
Requires: python-dateutil, pytz, numpy
Required-by:
```

これでとりあえずLocationに存在していることだけは証明してくれる。
エラー原因が「存在していないから」ではなく、「存在しているけれど見つけられないから」ではないかと考えて、次へ進める。

##2.pip install [moudle]　と　import [module]　のmodule名は必ずしも同一名ではない
これ地味に何度もぶち当たってそのたびに困惑した。
例えばPyDriveをインストールする時は

```
pip install PyDrive
```

でいけるけど、それをimportしようとした時に

```
import PyDrive
```

ではいけなかった。ModuleNotFoundError: No module named 'PyDrive'を吐かれる。

正しい例は

```
from pydrive.auth import GoogleAuth
```

とか

```
from pydrive.drive import GoogleDrive
```

とすることだった。
これは「インストール時のモジュール名はインポート時にも使えて当然」と考えていたこちらの先入観に問題があった。使い方をろくに調べもせずに次に進んでしまう人は要注意。
(この手の記事って見かけないので、ハマったのって僕だけですか？）

##3.sys.path
pythonがimport時にどこを見に行っているか教えてくれる(僕にとっては)神コマンド。
単体でも結構便利だけど、後述のpprintとの併用がオススメ。

```
import sys
sys.path
```

####実行結果

```
['','C:\\Users\\xxxx\\Python\\Python37-32\\python37','C:\\Users\\xxxx\\Python\\Python37-32\\python37.zip','C:\\Users\\xxxx\\Python\\Python37-32\\Python37-32\\DLLs']
```

##4.pprint
リストを整形して出力してくれる、目に優しいコマンド。
先ほどのsys.pathと一緒に使った場合。

```
import sys
import pprint
pprint.pprint(sys.path)
```

####実行結果

```
['',
'C:\\Users\\xxxx\\Python\\Python37-32\\python37',
'C:\\Users\\xxxx\\Python\\Python37-32\\python37.zip',
'C:\\Users\\xxxx\\Python\\Python37-32\\Python37-32\\DLLs']
```

み、見やすい…。

#あとがき
pythonをプログラム初心者にお勧めしている記事や本をちょくちょく見かけるけれど、僕は環境構築問題が結構な壁になるんではないかと思う。文法とか内容がお勧めっていうのはその通りだと思うんだけど、環境が構築出来なかったら文法もクソもなくないですか？
その点でcoraboratoryとか神なんだけど、それだけ触っても出来ない事もそれなりにあるよねと。

などと思いつつ、環境構築で躓いている人の参考になったらいいなぁと思ってまとめました。それでは。
CENTOS8.0にcmake3.15.2をインストール

**ネットワークからソースコードを下ろすために<font color="Red">yum</font>を使って<font color="Blue">wget</font>とインストールする。また<font color="Blue">make</font>をインストールする。**

    sudo yum install wget
    sudo yum install make

**次に<font color="Red">cmake.org</font>からからソースコードをzipファイルでダウンロードする。**

    sudo wget https://cmake.org/files/v3.15/cmake-3.15.2.tar.gz

**zipファイルを展開**

    tar zxvf cmake-3.15.2.tar.gz

**cmakeのディレクトリに入る。**

    cd cmake-3.15.2

**Buildを行う。**

    ./bootstrap --prefix=/opt/cmake –-no-system-libs

**makeを行う。**

    make -j4

**インストール**

    sudo make install

**<font color="Red">bashrc</font>を編集してPATH指定を行う。**

    sudo vi /etc/bashrc

**キーボードで<font color="Red">a</font>をクリックすると編集作業ができる。最終行に以下の文を追加する。**

    PATH=$PATH:/opt/cmake/bin

**<font color="Blue">[esp]キー</font>をクリックし<font color="Red">:wq</font>で保存される。

**最後に以下のコマンドを入力する。**

    source /etc/bashrc
処理中をお手軽表示(Swift5)

## 概要
先に結論から言うとUIActivityIndicatorViewを使って簡単に実現できます。
数行ですけど、使うときにいちいち思い出したりコピペも面倒だし組み込みたいよねと言うことでextension使って標準機能っぽくしちゃいます。
論よりコードなので、早速サンプルコード


## サンプルコード
```ViewController.swift
//
//  ViewController.swift
//  Test
//
//  Created by hats on 2019/06/18.
//  Copyright © 2019年 hats. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    
    var testView :UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        
        // タップ操作の準備
        let tapGetsture = UITapGestureRecognizer(target: self, action: #selector(tapAction))
        self.view.addGestureRecognizer(tapGetsture)
        tapGetsture.delegate = self

        
        // TestViewを作成
        testView = UIView(frame: CGRect(x: 300, y: 300, width: 200, height: 100))
        testView.backgroundColor = UIColor.blue
        self.view?.addSubview(testView)
        
        // 表示！
        testView.waitingOpen()
    }

    @objc func tapAction(sender: UITapGestureRecognizer) {
        
        // 非表示！
        testView?.waitingClose()

    }

}



extension UIView{
    
    /// 処理中表示
    func waitingOpen(){
        // 通信中インジケーター表示
        let wating = UIActivityIndicatorView()
        self.addSubview(wating)
        
        // 制約で対象のUIViewの真ん中に出す
        let parent = self
        wating.translatesAutoresizingMaskIntoConstraints = false
        wating.centerXAnchor.constraint(equalTo: parent.centerXAnchor, constant: 0.0).isActive = true
        wating.centerYAnchor.constraint(equalTo: parent.centerYAnchor, constant: 0.0).isActive = true
        
        // 見た目を調整して表示
        wating.style = .whiteLarge
        wating.color = .white
        wating.startAnimating()
    }
    
    /// 処理中非表示
    func waitingClose(){
        // UIActivityIndicatorViewを探して消す
        let watings = self.subviews.filter{ $0 is UIActivityIndicatorView }.map({ $0 as! UIActivityIndicatorView })
        for waiting in watings{
            waiting.stopAnimating()
            waiting.removeFromSuperview()
        }
    }
    
}
```

## ちょっとだけ解説
表示するとUIViewに処理中でくるくる表示されてタップすると消えます。
![IMG_0057.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491285/d49b7bf1-0a7b-5813-9daf-205cca6a1060.png)


extensionを使ってUIViewにwaitingOpenとwaitingCloseという機能を追加してます。
UIViewの真ん中に決まった形式で表示されるだけの簡単機能ですが、呼び出し側が`UIView`.waitingOpen()とするだけで表示できるので使いやすいと思います。

どっちかというとextensionて便利っていう記事だったかも。
Ruby環境構築【Mac】

Rubyの環境構築方法を記載します。
## 【単語】
●Ruby
オブジェクト指向のインタプリタ言語
[Rubyコミュニティサイト](https://www.ruby-lang.org/ja/)

●Xcode
MacOSのIDE
今回は後述のCommand Line Toolsのために用意
[App Store](https://apps.apple.com/jp/app/xcode/id497799835?mt=12)

●Command Line Tooles
コマンドを入力して操作するアプリケーション

●Homebrew
macOS用パッケージマネージャー
[Homebrewに関しての参考Qiita記事](https://qiita.com/krtsato/items/ba567acacb93a7a02dd9)

●rbenv
Rubyのバージョン管理ツール
[rbenvに関しての参考Qiita記事](https://qiita.com/w-tdon/items/e034b560538e3442395c)

## 【確認】
MacOSでは、Rubyは既にインストールされています。
既にインストールされているRubyのバージョンを確認しましょう。


```
ruby -v
```

確認したら、環境構築に入りましょう。

## 【構築手順】
＊入力は全てターミナルで行います。

●Xcode,Command Line Tools
１：[App Storeからインストール](https://apps.apple.com/jp/app/xcode/id497799835?mt=12)
２：Xcodeインストール後、起動し、認証させる。
３：Command Line Toolesをインストールする

```
xcode-select --install
```

●Homebrew
１：Homebrewをインストール

```
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”
```

２:Homebrewを最新状態にアップデートする

```
brew update
```

３：Homebrewの問題がないかを確認する

```
brew doctor
```

●rbenv
１：rbenvをインストール
⇨インストール途中で、Enterボタン入力、ログインパスワード入力を求められます。

```
brew install rbenv
```

２：rbenvの設定を行う

```
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
```

●Rubyバージョン管理
１：rbenvで管理できるRubyの一覧を表示する

```
rbenv install —list
```

２：Ruby2.5.0ダウンロード

```
rbenv install 2.5.0
```

３：Ruby2.5.0に切り替える

```
rbenv global 2.5.0
```


以上の操作で、MacOS環境でRubyの環境構築を行います。
【python】 globとzipfileだけでzipファイルを作成する関数

# 以下の関数で出来ます

```python:フォルダをzipファイルにまとめる関数
import zipfile
import glob

def create_zip(folder_name):
    path_ary = glob.glob(f'{folder_name}/**', recursive=True)
    with zipfile.ZipFile(f'{folder_name}.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
        for path in path_ary:
            new_zip.write(path)
```

使う時はこんな感じです。

```python

folder_name = "path/to/folder"
create_zip(folder_name) # zipファイルが作成されます
```

参考にしたもの：
[PythonでZIPファイルを圧縮・解凍するzipfile | note.nkmk.me](https://note.nkmk.me/python-zipfile/)
[Python, pathlibでファイル一覧を取得（glob, iterdir） | note.nkmk.me](https://note.nkmk.me/python-pathlib-iterdir-glob/)

# なぜこれをやろうと思ったのか

Jupyter lab で、以下のコードでフォルダをzipファイルに固めようとしたら``[Errno 13] Permission denied: 'swapfile'``というエラーが出ました。

（このコードはここを参考にしました：[Pythonでディレクトリ（フォルダ）をzipやtarに圧縮 | note.nkmk.me](https://note.nkmk.me/python-zip-dir-shutil-make-archive/)）

```python
import shutil

shutil.make_archive('フォルダ名', 'zip', root_dir='/')
```

Jupyter serverの権限をいじるのは少し大変だなと思ったので、別の方法でやる事にした次第です。
kaggle APIをインストールしてkaggleコンペ一覧を取得する

# はじめに
kaggle APIを使えばwebへ行かなくても、データセットを取得したり
予測値の提出がAPI経由でできるって話を知り「こりゃ便利そう」ってことで
試してみた。

# 実行環境
## OS
Windows10 Home
## 言語
Python 3.7.3
## ツール
Anaconda Navigator 1.9.7
git bash
## アカウント
github.com

# 手順
手順はほかのAPIを利用するときと一緒。
1. kaggleAPIのインストール
2. kaggleAPI ークンのインストール
3. kaggleAPIの実行

# 1. kaggleAPIのインストール
1. anaconda promptを起動
検索窓から"ana"記入したらanaconda prompt(anaconda3)が出るのでクリックして起動
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/f67dc907-cbc7-c718-8d8a-2a3d28b9be8d.png)

2. kaggle APIのインストール
anaconda prompt上で以下のコマンド実行

```
pip install kaggle
```
![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/033f9184-d785-c1c8-c80d-da1d99b8705c.png)


# 2. kaggleAPI ークンのインストール
1. kaggle公式サイトのマイページへ移動して[Account]クリック
「・・・」に隠れているので注意。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8ff5e90a-b691-0156-04c6-09b9175a27ad.png)

2. 画面下のほうにあるAPI関連の項目で[Create New API TOken]クリック

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/c62f76ab-a927-77ff-ef7b-1512c3570128.png)
クリックすると、自動的にkaggle.jsonがダウンロードされる。
※windowsで何も考えなければ[ダウンロード]フォルダに保管される
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2b932028-949b-7270-4fcd-e697490c3d97.png)

3. トークンファイルのインストール
環境にもよるかもしれないけど、自分は以下の場所にフォルダを作って保管した

```
 C:\Users\watya\.kaggle\kaggle.json
```

git bashを起動して管理者のみ実行可能になるようchmodで設定した
（※git bashがあったからできただけかもしれない）

```
$ cd /c/Users/watya/.kaggle
$ chmod 600 kaggle.json
```

# 3. kaggleAPIの実行
実行はanaconda prompt上で実行した。

```
kaggle competitions list
```
実行結果はこんな感じ。
![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e1d55346-53ad-3899-bcb5-1fd1837fbd7f.png)

～おしまい～
np.transposeにおける勘違い

## 概要
この記事は、忘れっぽい筆者のためのメモです。
知らない人もいるかもしれないので、ぜひ読んでみてください。

## 3次元以上の np.array を操作するとき
形が **(5,6,7)** となっている変数の軸を入れ替えて、**(6,7,5)** にしたいとき、あなたならどうしますか？
つまり、次のように軸を入れ替えたいわけです。
5：0軸→2軸
6：1軸→0軸
7：2軸→1軸

### 間違った答え
賢明なみなさんなら間違えないと思いますが、私は間違えました。
次のコードは、間違いです。

```ex_mistake.py
import numpy as np
a = np.zeros((5,6,7))
a = a.transpose(2,0,1)
print(a.shape) # (7,5,6)
```
形は **(7,5,6)** になってしまいました。
**入れ替えた後の軸を指定するのは間違っています。**
今まで何度も間違えました。

### 正しい答え
次のコードが、正解です。

```ex_mistake.py
import numpy as np
a = np.zeros((5,6,7))
a = a.transpose(1,2,0)
print(a.shape) # (6,7,5)
```
入れ替え後の軸の位置に、入れ替え前の軸を指定するのが正しいです。
ここでは、0軸=5、1軸=6、2軸=7となっており、(5,6,7) から (6,7,5) に変形したい場合は、(0軸,1軸,2軸) から (1軸,2軸,0軸)としなければなりません。

## まとめ
(5,6,7) → (6,7,5) となるように軸入れ替えをするには？

よくやってしまう間違い：a.transpose(2,0,1)
(この軸は**2**軸に移動, この軸は**0**軸に移動, この軸は**1**軸に移動) という解釈

正解：a.transpose(1,2,0)
(元の**1軸**はここに移動, 元の**2軸**はここに移動, 元の**0軸**はここに移動) という解釈
JSONって何だ？

こんにちは

ぽんぽこです。
今回はJSONについて書きたいと思います。

では本編へ。

##JSONとは？
SONとはJavaScript Object Notationの略で、
XMLなどと同様のテキストベースのデータフォーマットです。

JavaScript内で複数の値をまとめる際の記法のことで、
それはコンピューターにも人間にも理解できる記法である。

##どんな時に使うの？
複数のデータを保存したり、データを送りたいときに使用します。

JSON形式を使う理由としてはJSON形式を用いることで

シンプルで軽量だからデータとして扱いやすく
人間にもわかるので楽に理解もしやすいデータ群を作成できるから。


```json
{
  "name": "Tanaka",
  "age": 26
}
```

上記のように表現されているため非常にわかりやすい！！！

##JSONの型
JSON では下記の型を使用することができます。

- 文字列 ("...")
- 数値 (123, 12.3, 1.23e4 など)
- ヌル値 (null)
- 真偽値 (true, false)
- オブジェクト ({ ... })
- 配列 ([...])

##JSONのエンコーディング
過去の仕様では単に Unicode が推奨され、先頭の 2バイトで UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE を見分けるとされていましたが、RFC 8259 で指定された仕様では、BOM 無しの UTF-8 で記述する(MUST)と定義されています。

以上がJSONの説明になります。

不備があればご指摘ください。

ではまた次回！！！
Cloud9環境でセッションすべて消すとローカルwebサーバーにアクセスできなくなる問題

# Railsチュートリアル8章「セッションの削除」

※本記事はRailsチュートリアルをCloud9環境で行っている人向けです。
※セッション消していなくても、「VFS connection does not exist」が出てサーバにアクセスできない場合は有効な可能性が大です。

Railsチュートリアル8章でログアウト機構実装前にセッションを削除することで、ログアウト状態となることを確認する演習があります。(8.2.3)

ここで、「ええい!よく分からないしすべて消したれ！」(画像の上の選択肢)
![all_delete_stupid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/5f1441c0-43f8-9b95-ee88-a1158612ad02.png)

とやると、ローカルwebサーバーにアクセスできなくなるので、絶対やらないようにしましょう(私はやりました)
![oops.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/5476ad3b-c4d0-3938-2611-2613cd05a238.png)

## 復帰方法
[Rails チュートリアルでテスト実行したら、「File to import not found or unreadable: bootstrap-sprockets」と出た時の対処方法](https://qiita.com/bigfirtreeman/items/844bbe7438a7a6d51919)の記事でもお世話になった、
[AWS インスタンスの再起動方法](https://qiita.com/at0arumati/items/2001a7d48384231d5e01)
を実行して、cloud9を再起動してください。

ここまでチュートリアルをやっている人間なら、「Oopsの画面が出るのはRailsサーバが起動していないときだ！」と考えて、Rails sコマンドを打ちがちですがサーバを起動しなおしても効果はないので、再起動してください。

## 原因
![2019-10-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/01ff85f6-588a-13d6-65ee-21a60eb46058.png)
おそらくですが、Cloud9で立ち上げたwebサーバはブラウザに対して接続情報をクッキー内に持っていて(preview9vfs以下)、これがないとブラウザからのアクセスを撥ねる仕組みになっているものと思われます。

FirefoxのCloud9環境でローカルwebサーバを立ち上げたときに、そのURLにChromeやIEからアクセスしても同じエラーが出るのはこのブラウザに許可する設定を持っていることが原因です。
FeatureScalingとはーーCourseraのMachineLeaningを完走したので復習するーー

#FeatureScalingとは
一言でいうと、featuresの取り得る値の範囲（スケール）を変化させ、全てのfeaturesの値の範囲を揃えること。


例: 家の価格予想（feature1:家のサイズ、feature2:部屋の数)
家のサイズ（feature1）と部屋の数（feature2）とでは取り得る範囲（スケール）が全く異なる。

```math
X=
\begin{pmatrix}
2014\ & 3\\
1600\ & 3\\
.\ & . \\
.\ & .\\
1416\ & 2\\

\end{pmatrix}
```
Xのcolumn1が家のサイズ（feature1）、column2が部屋の数（feature2）

このように大きくスケールの異なるfeaturesを用いるとき、FeatureScalingによって、それぞれfeaturesが取り得る値の範囲を一定に揃える。


#FeatureScalingを使う理由
大きく異なるスケールのfeaturesを用いる場合、学習（=GradientDescentの収束）に時間がかかったり、うまく学習できないということが起こり得る。ゆえにFeatureScalingによってfeaturesのスケールを前もって揃えておくべきなのである。

#FeatureScalingの方法(Mean Normalization)
FeatureScalingの際には全ての変数xの値がおおよそ$-1 \leqq x_i \leqq 1$の範囲に収まるようにする。

$x_i=\dfrac {x_i-\mu_i }{s_i}$
$x_i$：feature i
$\mu_i$ : $x_i$の平均
$s_i$ :feature Iの値の範囲（max-min）　もしくは　標準偏差（standerd division）
Goのポインタを学ぶ

# 変数とアドレス
ポインタを理解するための第一歩として｢変数｣と｢アドレス｣があります｡変数とは､**値を保存しておくためのメモリ領域に名前をつけて管理するもの**であり､アドレスとは､**変数がメモリ領域のどこに格納されているかを示すもの**です｡

コンピュータのメモリは､横一列に並べられた巨大なロッカーをイメージするとわかりやすいと思います~~(って偉い人が)~~｡ロッカーには端から端まで一意の番号が振られています｡ロッカーを探すとき､例えば8桁の番号で表されても面倒なのでロッカーには名前を書いておこうというわけです(実際には16進数で表されます)｡

```go
package main

import "fmt"

func main() {
	var hoge string
	hoge = "Hello"

	fmt.Println("hogeの値:", hoge)
	fmt.Println("hogeのアドレス:",&hoge)
}
```
```
hogeの値: Hello
hogeのアドレス: 0xc0000101e0
```
実行結果を見てみると､`Hello`という文字列が`0xc0000101e0`番地のメモリ領域に変数名`hoge`として格納されていることがわかります｡注意点として､変数が格納されるアドレスは実行環境によって異なります｡再実行してみると変数が別のアドレスに格納されることがわかると思います(変わらないこともあります)｡

このように変数とアドレスは切っても切れない関係にあります｡

# ポインタ
ポインタとは､**変数のアドレスを示す**ものです｡変数のアドレスを示す変数を｢**ポインタ変数**｣､その型を｢**ポインタ型**｣といいます｡

```go
package main

import "fmt"

func main() {
    var hoge string
    hoge = "Hello"
	
    var p *string
    p = &hoge

    fmt.Println("hogeの値:", hoge)
    fmt.Println("hogeのアドレス:",p)
    fmt.Println("pが指すアドレスの値:",*p)
}
```
```
hogeの値: Hello
hogeのアドレス: 0xc000092030
pが指すアドレスの値: Hello
```
ポインタ型を定義するには既存の型に`*`を付けます｡ここでは`string`型の変数のアドレスを保持したいので､`*string`と書きます｡また､変数のアドレスを取得したい場合には､変数にアドレス演算子`&`を用います｡ここで取得したいのは`hoge`のアドレスなので､`&hoge`と書きます｡つまり､ポインタ変数`p`は`hoge`のアドレスを保持していることになります｡

逆にポインタ変数からアドレス内の値を知りたい場合には､ポインタ変数に間接参照演算子`*`を用います｡実行結果は､`p`が指すアドレス`0xc000092030`には`Hello`が格納されていることを示しています｡

ちなみに､ポインタ変数のゼロ値は`nil`です｡そりゃそうだ｡

```go

	var p *string
	fmt.Println(p)
```
```
<nil>
```

# 変数とポインタ変数
変数とポインタ変数の使い分けについて考えたいと思います｡

```go
package main

import "fmt"

func main() {
	var hoge string
	hoge = "Hello"

	var fuga string
	fuga = hoge

	var piyo *string
	piyo = &hoge

	fmt.Println("hogeの値:", hoge)
	fmt.Println("fugaの値:", fuga)
	fmt.Println("piyoが指すアドレスの値:", *piyo)

	fuga = "World"
	fmt.Println("fuga更新後のhoge:", hoge)

	*piyo = "World"
	fmt.Println("piyoが指すアドレスの値更新後のhoge:", hoge)

	fmt.Println("hogeのアドレス:", &hoge)
	fmt.Println("fugaのアドレス:", &fuga)
	fmt.Println("piyoが指すアドレス", piyo)
}
```
```
hogeの値: Hello
fugaの値: Hello
piyoが指すアドレスの値: Hello

fuga更新後のhoge: Hello
piyoが指すアドレスの値更新後のhoge: World

hogeのアドレス: 0xc000088030
fugaのアドレス: 0xc000088040
piyoが指すアドレス 0xc000088030
```
`fuga`には単なる変数`hoge`を代入しています｡2つの変数は同じ値を保持していますが､それぞれの変数が格納されたアドレスを確認してみるとその値は異なっています｡これはメモリ上の別のアドレスに同じ値を持った2つの変数が存在していることを示しています｡当たり前ですが､2つは別の変数ですので`fuga`の値を変更したとしても､それが`hoge`へ反映されることはありません｡

`piyo`には`hoge`のアドレスを代入しています｡`hoge`が格納されているアドレスと`piyo`が指すアドレスは同じなので､間接参照演算子を用いて`*piyo`の値を変更すると､それは`hoge`へも反映されます｡

このような機能から､Goにおけるポインタは、構造体のメソッドで何らかの処理を行う場合にポインタレシーバを用いるケースが多く見られます｡引数やレシーバで何らかの値を受け取り､その処理を呼び出し元に反映させるにはポインタを用いる必要があるということです｡

# 参考リンク
https://golang.org/ref/spec#Pointer_types
https://tour.golang.org/moretypes/1
https://9cguide.appspot.com/05-01.html
https://9cguide.appspot.com/15-01.html
Raspberry Piに接続されたM5Stackのデバイスファイルを固定したい

Raspberry PiにM5StackをUSB接続してシリアル通信する時に`/dev/ttyUSB0`以外に接続されてしまう場合があるので対策する。

# TL;DR
- USB機器を複数接続するとき、接続順でdevファイルの名前が変わってしまうので場合によってはいつもと違う名前になる可能性がある
- `udevadm info`や`lsusb`でUSB固有の情報を取得し、`udev`の`/etc/udev/rules.d`にルールファイルを追加する
- 同じ機器を接続する場合は機器に固有に割り振られている`serial`まで使って判別する

# 機器情報の調べ方
## 現在の接続先を知る
```bash
ls -l /dev/serial/*
```

## 詳細を知る
udevadm infoやlsusbで調べる

```bash
sudo udevadm info -a -p $(sudo udevadm info -q path -n /dev/ttyUSB0)
```

# udev記入例
購入した時期によってハードウェア構成がよく変わるので注意すること。
ESP32製品は`Sillicon Lab`の`CP2104 USB to UART Bridge Controller`を使っているのが多いので、
同じESP32のボードを使っていると`serial`まで見ないとダメかもです。

## /etc/udev/rules.d/99-m5stack.rules

```udev
#for M5Stack
## M5StickC
KERNEL=="ttyUSB*",  ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{product}=="M5Stack Intf", SYMLINK+="ttyUSB_M5StickC"
## M5Stack Gray
KERNEL=="ttyUSB*",  ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{product}=="CP2104 USB to UART Bridge Controller" SYMLINK+="ttyUSB_M5Stack"
```

こんな感じに設定しておくと、M5StickCは`/dev/ttyUSB_M5StickC`に、M5Stackは`/dev/ttyUSB_M5Stack`に接続されます。

udevは再起動する必要はありませんが、ファイル名の末尾は`.rules`である必要がありますので注意してください。

また既に接続されているデバイスを再認識はしないので、設定を反映させたい場合、一度挿抜してください。


# 補足
- 純正のケーブルは認識があまりよくないみたいなのでそもそも認識しないケースもあります。
- 別途短めのケーブルを用意するとよいかもです。
- Raspberry Piから供給される電圧はかなり不安定です。AD変換が安定に読み取れないなどいくつか問題がありました。

# 参考
- [デバイス名を固定する - Qiita](https://qiita.com/ospy/items/3e6ff429ba782624def1)
- [udev - ArchWiki](https://wiki.archlinux.jp/index.php/Udev)
GIS×Python　〜ジオコーディングで位置情報取得〜

#1.　経緯
商圏分析するとき目標物や施設の位置情報が欲しかったりする。いちいち手入力して検索するのがちょいとめんどーなので、ジオコーディングを半自動化してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354874/925f10b7-cb31-bc24-f5ad-9a934d775ce7.png)

#2.　コード
さくっと1時間程度で書いたコードなんで特に難しいことはやってないし、もっと良い方法があればその都度更新してこ。
アクセスし過ぎると怒られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354874/90bf9c31-d88f-7318-e4bf-29e6f32d0774.png)


```geocoding.py
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import urllib.request
from bs4 import BeautifulSoup
from time import sleep
import numpy as np

driver = webdriver.Chrome(executable_path='./chromedriver')
driver.get("https://www.geocoding.jp/")

out = np.zeros((0,3))
#データフレームとかで検索リストを投げてもよい。
for text in ['カンプ・ノウ','ウェンブリー・スタジアム','スタッド・ドゥ・フランス','サンティアゴ・ベルナベウ','ルジニキ・スタジアム']:
    driver.find_element_by_id('q').send_keys(f"{text}")
    driver.find_element_by_xpath('/html/body/form/div/div[4]/input').click()
    sleep(4)
    next_url = driver.current_url
    html = urllib.request.urlopen(next_url)
    soup = BeautifulSoup(html, "lxml")
    latlon = soup.find("span")
    try:
        latlon_list = [i.string for i in latlon]
        lat = latlon_list[1]
        lon = latlon_list[3]
        out2 = np.hstack((text,lat,lon))
        out = np.vstack((out,out2))
        print(text)
    except:
        out2 = np.hstack((text,"NaN","NaN"))
        out = np.vstack((out,out2))
        print(f'{text}に該当する住所が見つかりませんでした。')

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354874/959d8f38-d9b0-3a11-95a5-56b70d6d6f93.png)


以上！！！
WindowsでMacみたいなキーボード操作を。

#Mac使いはWindowsのエディタ操作しづらい
Macをお使いの方は標準でctrl+fとかで移動できるので矢印キー使わないって人多いと思います。
あと、英字・かな変換をctrl+spaceとかに割り当ててあることも多いと思うのでwindows触ると「あ、capsか」とかなりますよね。

capslockを左ctrlとかに割り当ててIMEで英字・かな変換にする人もいます。
でも、そうするとctrl+fは文字検索のキーボードショートカットなんで移動できない。。
僕は左小指の隣のボタンで右に移動したいんです。。

とりあえず、同じこと考えてる人は多いので自分なりの最適解をメモっときます。
#'ChangeKey'を使ってキー配置を変更する
ChangeKeyはキーボードのキー配置を入れ替えたり無効化したりするフリーウェアです。
結構古いんですがwin10でも動作しました。
常駐するわけではなくレジストリを変更するので遅延とかは起きないです。
ただ、レジストリを変更するわけですので、管理者権限が必要ですし他によからぬ影響が出ないか少し注意が必要です。

編集箇所はregeditを開いて
`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout`
の中の"Scancode Map"なのでこれを削除すればキーボードは初期化されます。

私のようにcapslockをF13に割り当てたい方は以下をご参考ください。
1. 管理者権限でchangekeyを起動して、変更したいキー（今回はcapslock)を選択
2. 「どのキーに変更しますか？」と聞かれるので一番右上のscan codeを選択
3. F13のスキャンコード`0064`を入力
4. 上の方にある登録をクリックして再起動

**使用方法参考**
https://pc-plaza.com/remapping-keyboard/

**インストール**
https://forest.watch.impress.co.jp/library/software/changekey/
##キーのスキャンコード
変更するにあたりキーボードにないキー（F13とか）を割り当てたい人もいると思います。（まさにこの記事です。。）
そのためのキーマップです。

| キー       |       スキャンコード |
|:-----------------:|:------------------:|
| F13	|0x0064
|F14	|0x0065
|F15	|0x0066
|F16	|0x0067
|F17	|0x0068
|F18	|0x0069
|F19	|0x006A
|F20	|0x006B
|F21	|0x006C
|F22	|0x006D
|F23	|0x006E
|F24	|0x0076   


#'AutoHotKey'で機能割り当て
次にAutoHotKeyを使ってMacのようなキーボードショートカットを割り当てていきます。
AutoHotKeyはスクリプトを記述したファイルを常駐させることで理想のキーバインドを実現します。
**インストール**
https://www.autohotkey.com/

#ahkファイルの作成
インストールが完了したら、メモ帳なり何らかのエディタを開きます。
記述したら`.ahk`形式で保存しましょう。僕は`mykeyset.ahk`で作成しました。
スクリプトについての詳細は調べたら出てきます。

```ahk:mykeyset.ahk
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; capslock + なにか
; p : カーソルを上に移動
; b : カーソルを左に移動
; a : カーソルを先頭に移動
; e : カーソルを最後に移動
; h : バックスペース
; d : デリート
; f : カーソルを右に移動
; n : カーソルを下に移動
; space : 英字・かな変換
; ";" : エスケープ
;;;;;;;;;;;;;;;;;;;;;;;;;;;

F13 & N::Send,{Blind}{Down}
F13 & P::Send,{Blind}{Up}
F13 & A::Send,{Blind}{Home}
F13 & E::Send,{Blind}{End}
F13 & H::Send,{Blind}{BS}
F13 & D::Send,{Blind}{Delete}
F13 & Space::Send,{Blind}{vkF3sc029}
F13 & F::Send,{Blind}{Right}
F13 & B::Send,{Blind}{Left}
F13 & `;::Send,{Blind}{Esc}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; vimmer向け
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;F13 & L::Send,{Blind}{Right}
;F13 & H::Send,{Blind}{Left}
;F13 & K::Send,{Blind}{Up}
;F13 & J::Send,{Blind}{Down}
```
保存できたら右クリック→[Run script]を実行して動作を確認します。
##スタートアップに登録
しかしこのままではPC起動時にいちいちrun..を押すのは面倒です。
なのでスタートアップに登録しましょう！

1. ahkファイルを右クリック→[compile script]
2. 作成されたexeファイルをコピー
3. win+rを押して[ファイル名を指定して実行]を開く
4. `shell:startup`を記入してOK
5. 開いたフォルダにペースト

これで起動時も自動的にキーボードショートカットが可能ですね
#キーバインドTips
Windowsでは標準のショートカットキーで以下が有効です。

| キー       |       動作 |
|:-----------------:|:------------------:|
| ctrl+→	|右に単語移動
|ctrl+←	|左に単語移動
|ctrl+shift+→	|単語選択（右）
|ctrl+shift+←	|単語選択（左）
#参考
https://pc-karuma.net/windows-10-app-startup/
http://ahkwiki.net/Top
http://alfort728.hatenablog.com/entry/2019/03/29/041408
http://did2.blog64.fc2.com/blog-entry-371.html
簡易設計の方法

## 手順

- 必要な機能の洗い出し
- テーブル設計


## 必要な機能の洗い出し

- サインアップ/サインイン機能

```
ログイン機能
```

- プロフィール編集機能

```
編集
```

- マッッチング機能

```
いいねをお互いがした場合にマッチング
```

- チャット機能

```
メッセージが送れる
画像が送れる？
　- 画像の送り方などは？
```


## テーブル設計 

ER図的な？

```


@startuml

class ユーザー << User >>{
  ID <<id>>
  名前  <<name>>
  email <<email>>
}


class メッセージ <<Message>>{
 ID <<id>>
 メッセージ  <<message>>
 user_id <<user_id>>   
 chat_room_id <<chat_room_id>>
}

class チェットルーム <<ChatRoom>>{
 ID <<id>>
}

class チェットルームユーザー <<ChatRoomUsers>>{
 ID <<id>>
 chat_room_id <<chat_room_id>>
 user_id <<user_id>>
}

class リレーション <<Relation>>{
  ID <<id>>
  to_user_id <<to_user_id>>
  from_user_id <<from_user_id>> 
  status <<status>> 
}


ユーザー "1" -- "*" メッセージ

チェットルーム "1" -- "*" チェットルームユーザー
ユーザー "1" -- "*" チェットルームユーザー
チェットルーム "1" -- "*" メッセージ
ユーザー "1" -- "*" リレーション

@enduml
```
Gitでコンフリクトを起こした時の対応

## 初めての共同開発つまづきポイント
1. とりあえず、pushしてみる
2. コンフリクト解決できず
3. 作業ブランチにリモートのマスターブランチをマージするという誤認識
4. rubyのバージョンが違うために発生したと思われる膨大な数のコンフリクトに慌てる

## コンフリクト解決の流れ
1. ローカルで作業ブランチからマスターブランチへ移動する
2. ローカルのマスターブランチにリモートのマスターブランチをpullする
    - `git pull origin master`
3. 作業ブランチに移動してローカルのマスターブランチをmergeする
    - `git add .`
    - `git commit -m "〇〇"`
    - `git merge master`
    - ここでリモートのマスターブランチとrubyのバージョンが違っていたため？膨大なコンフリクト発生(2.の工程を実施したときにコンフリクトが発生しても良さそうな気もするが)
4. リモートマスターのバージョンに合わせたいので一括コンフリクト解消コマンドを実施
    - `git checkout --theirs .`

##  感想
初めて練習での共同開発なのでかなりGitの使い方で苦しんでいますが、良い経験になります。
loggerに独自のハンドラを設定する

Pythonには標準でLoggerというログ出力を行うためのクラスがあります。

このLoggerに独自のハンドラを追加することで、たとえばログの出力をGUIに表示するなどといったことができるようになります。

# まずはHandlerを継承したクラスを作る

まずはHandlerを継承したクラスを作りましょう。

```python:handler.py
class GUILogHandler(logging.Handler):
    def __init__(self, window, level=logging.NOTSET):
      logging.Handler.__init__(self, level=level)
      self._window = window

    def emit(self, record):
      if len(record.msg) > 0:
        msg = self.format(record)
      else:
        msg = ""
      try:
        js = "let l = document.getElementById('log_area');"
        js += "let item = document.createElement('div');"
        js += "item.classList.add('log_item');"
        js += "item.classList.add('{0}');".format(record.levelname)
        js += "item.textContent = '{0}';".format(escape_string(msg))
        js += "l.appendChild(item);"
        js += "item.scrollIntoView({behavior: 'smooth', block: 'end', inline: 'nearest'});"
        self._window.evaluate_js(js)
      except Exception:
        self.handleError(record)
```

ここでは、`emit()`というメソッドだけが、オーバーライド必要なメソッドとなります。

ログの出力処理などが行われた際、このメソッドが呼び出されますので、`self.format()`メソッドを使用してフォーマッタを通したログを、出力するという処理を行います(このコードでは、PyWebViewを使って作成したUIの、`log_area`というIDのdivに、ログを出力しようとしています)。

このフォーマッタを格納する領域は、Handlerの`__init__()`で作成されています。このため、もし独自の初期化処理を行う場合は、**必ず`logging.Handler.__init__(self, level=level)`として、スーパークラスの`__init__()`を呼ぶ**必要があります。

## `emit()`で引き渡される`record`パラメータの各値の意味
`emit()`メソッドで引き渡される`record`には、ログメッセージだけでなく、様々なログ情報が含まれます。

すべてのリストは、[公式のマニュアル](https://docs.python.org/ja/3/library/logging.html#logrecord-attributes)に載っていますので、そちらを参照してみてください。

ざっくりと、良く使うであろうパラメータは以下の通り。

* asctime: 事象が発生したときの時刻。ミリ秒単位
* filename: ログ出力を行ったファイルの名前
* funcName: ログ出力を行った関数の名前
* levelname: ログレベル(DEBUG, INFOなどの値)
* message: ログのメッセージ
* processName: プロセス名
* threadName: スレッド名

# ハンドラの追加と、余計なハンドラの削除について

このようにして作成したハンドラは、`logger.addHandler()`メソッドで追加可能です。

```py:main.py
import logging
# ...
logger = logging.getLogger(self.__class__.__name__)
logger.addHandler(GUILogHandler(window))
```

ただし、このようにしてLoggerに追加したハンドラは、logger内に登録されるため、上記のコードを二回以上実行するときなど、重複してハンドラが登録されてしまう場合があります。

そのような場合は、ロガーに登録されているハンドラを一度すべて消去する必要があります。

```py:main.py
# ハンドラーリストを動的に書き換えてしまうことになるので、forで回すと上手くループできません。
while len(logger.handlers) > 0:
  logger.removeHandler(logger.handlers[0])
```
githubにファイル(フォルダ)を上げる(最低限)

ignoreなどの細かいことなどは飛ばしてとりあえずgithubにファイル(フォルダ)を上げる

---

```:terminal 
cd  当該ディレクトリまでのパス
```

まずはターミナルで当該ディレクトリに移動。

---

```:terminal 
git init
```

リポジトリを作成。

---

```:terminal 
git add ファイル名 or フォルダ名
```

でインデックスにファイル or フォルダを追加

---

```:terminal 
git commit -m "コメント"
```

任意でコメントをつけてコミットして

---

```:terminal 
git remote add origin githubのURL
```

作っておいたリポジトリのurlを貼り付けてリモートリポジトリにインデックスを作成。

---

```:terminal 
git push origin master
```

コミットされたデータをリモートリポジトリに追加して完了。
Ubuntu19.10でブリッジを作る

## 設定ファイル
Ubuntu16.04でネットワークを設定する際は`/etc/network/interfaces `を編集していましたが、Ubuntu19.10環境では `/etc/netplan/50-cloud-init.yaml`を編集する必要があります。

## ブリッジを設定する
`/etc/netplan/50-cloud-init.yaml`を以下のように編集します。

```yml
network:
    version: 2
    ethernets:
        enp4s0:
            dhcp4: no
    bridges:
        br0:
            interfaces:
                - enp4s0
            dhcp4: no
            addresses:
                - 192.168.99.1/24
            gateway4: 192.168.99.254
            nameservers:
                addresses: [8.8.8.8,8.8.4.4]
            parameters:
                forward-delay: 0
                stp: no
            optional: true
```

## 設定を適用する
以下のコマンドで設定を適用します。ymlの書式に問題がある場合は問題がある場所が指摘されます。

```sh
sudo netplan apply
```