OmniAICreator/Qiita-1.07M huggingface dataset:
シンプルなggplot作図設定

私が論文に載せる図を描くときに使っているggplot2の設定。条件は
・ 背景は白
・ 枠線は四方ありでちょっと太め、色は黒
のみ。
ggplot2のデフォルトだと次のようになる。

```plotiris.R
library(ggplot2)
ggp <- ggplot(data=iris) +
  geom_point(aes(x=Sepal.Length, y=Petal.Length))
print(ggp)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100982/6e207d43-128a-3213-083d-73397290ab9c.png)

背景が灰色だしなんか見にくい。そこで次のようなtheme()を書いてやる。

```plotiris.R
ggp <- ggplot(data=iris) +
  geom_point(aes(x=Sepal.Length, y=Petal.Length)) +
  theme(
        axis.text = element_text(size = 20, colour = "black"), #目盛の数字
        axis.title = element_text(size = 20), #軸タイトル
        panel.grid.major = element_blank(),   #グリッドは入れない
        panel.grid.minor = element_blank(),   #グリッドは入れない
        panel.background = element_rect(fill = "white", colour = "black", size = 1.2) 
#fillは枠内の色、colourは枠線の色、sizeは枠線の太さ
        )
print(ggp)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/100982/0cc23504-05aa-1663-c75f-3c1f0b9bd087.png)

これで論文に載せる図もバッチリ！
PythonからDLLを使う（classを使ってみる）


# はじめに

前回の[PythonからDLLを使う](https://qiita.com/satoysan/items/890b542a28e163a96e0d)の続き
クラスはどうやって使うのかなって思ったので、調べながら進めました。

# C++でDLLの準備

VS2017で、前回のようにDLLのプロジェクトを作る。今回のプロジェクト名は「DLLTestClass」としました。

```cpp:DLLTestClass.h
#pragma once

#ifdef DLLTESTCLASS_EXPORTS
#define DLLTESTCLASS_API extern "C" __declspec(dllexport)
#else
#define DLLTESTCLASS_API extern "C" __declspec(dllimport)
#endif // DLLTEST_EXPORTS

class Hoge
{
private:
	int m_count;
public:
	Hoge();
	const wchar_t* showMessage(const wchar_t* message);
	void count();
	void showCount();
};

DLLTESTCLASS_API const wchar_t* showMsg(const wchar_t* mes);
DLLTESTCLASS_API void countData();
DLLTESTCLASS_API void showCount();
```

```cpp:DLLTestClass.cpp
// DLLTestClass.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//

#include "stdafx.h"
#include "DLLTestClass.h"
#include <iostream>
#include <string>

Hoge::Hoge()
{
	m_count = 0;
}

const wchar_t* Hoge::showMessage(const wchar_t* message)
{
	return message;
}

void Hoge::count()
{
	m_count = m_count + 1;
}

void Hoge::showCount()
{
	std::cout << m_count << std::endl;
}

/* ラッパー */

Hoge hoge;
const wchar_t* showMsg(const wchar_t* mes)
{
	return hoge.showMessage(mes);
}

void countData()
{
	hoge.count();
}

void showCount()
{
	hoge.showCount();
}
```

```cpp:stdafx.h
// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、
// または、参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Windows ヘッダーからほとんど使用されていない部分を除外する
// Windows ヘッダー ファイル
#include <windows.h>


// プログラムに必要な追加ヘッダーをここで参照してください
#include "DLLTestClass.h"
```

C++側の実装はこんな感じ。そのままビルド通ると思います。
よくわかってない中進めていたのですが、ラッパー関数を作ってあげないと、うまく使えないっぽい？？（こういうもんなんですかね？）
何か別のライブラリを加えれば、python側でスマートに呼べるみたいなのだけど、、、、ちょっと何を言ってるのかわからないです。

とりあえず、python側でcountData()を呼べばカウントがガシガシ行われるようにしてみました。（恐る恐る）

# Python側を作る

VSでビルドしたDLLをPython側の環境に持ってきます。(DLLTestClass.dll)

```python:test.py
# coding: utf-8

from ctypes import *

dll2 = cdll.LoadLibrary("DLLTestClass.dll")

# 文字列セット
txt = u"あいうえ"
dll2.showMsg.argtypes = [c_wchar_p]
dll2.showMsg.restype = c_wchar_p
print(dll2.showMsg(txt))

# 加算
dll2.countData()
dll2.countData()
dll2.countData()
dll2.countData()

# 表示
dll2.showCount()
```

# 実行結果

```
> py test.py
あいうえ
4
```
テキスト入力して、返ってきて、ちゃんとカウントが４回行われて、表示されました。

ほんと、c_wchar_pの書き方とかググるだけでは本当によくわからなくて時間かかりました。
文字列を受け取って、返す流れとか文字化けとかの戦いでした。検索ワードがよくなかったのかなあ。。

クラスを実行するのよりマルチバイト文字列のところが時間かかりました。

何が正しくて何が正しくないのか謎でしたが、今回ひとまず動いたのでヨシとしようと思います。
Django チュートリアル: 地域図書館ウェブサイト　（その６）

こちらで作成したページの続きです。
[Django チュートリアル: 地域図書館ウェブサイト　（その５）](https://qiita.com/ekzemplaro/items/31296adfaad63de8da8a)

作者の Create,Update,Delete 機能をつけ加えます。

次のページの後半部分です。
[Django Tutorial Part 9: Working with forms](https://developer.mozilla.org/ja/docs/Learn/Server-side/Django/Forms)
>Generic editing views からです。

1) catalog/views.py に次をつけ加えます。

```py:catalog/views.py
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy

from catalog.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = '__all__'
    initial = {'date_of_death': '05/01/2018'}

class AuthorUpdate(UpdateView):
    model = Author
    fields = ['first_name', 'last_name', 'date_of_birth', 'date_of_death']

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('authors')
```

2) テンプレートの作成

```html:catalog/templates/catalog/author_form.html
{% extends "catalog/base_generic.html" %}

{% block content %}
  <form action="" method="post">
    {% csrf_token %}
    <table>
    {{ form.as_table }}
    </table>
    <input type="submit" value="Submit">
  </form>
{% endblock %}
```

```html:catalog/templates/catalog/author_confirm_delete.html
{% extends "catalog/base_generic.html" %}

{% block content %}

<h1>Delete Author</h1>

<p>Are you sure you want to delete the author: {{ author }}?</p>

<form action="" method="POST">
  {% csrf_token %}
  <input type="submit" value="Yes, delete.">
</form>

{% endblock %}
```

3) catalog/urls.py の最後へ追加

```py:catalog/urls.py
（省略）
urlpatterns += [  
    path('author/create/', views.AuthorCreate.as_view(), name='author_create'),
    path('author/<int:pk>/update/', views.AuthorUpdate.as_view(), name='author_update'),
    path('author/<int:pk>/delete/', views.AuthorDelete.as_view(), name='author_delete'),
```

4) 開発サーバーを起動して、
http://127.0.0.1:8000/catalog/author/create にアクセス
![create_mar1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/0fa25892-1091-35ca-1bbb-ad5f35c1daf3.png)

データを入れて、Submit
![create_mar1802.png](https://qiita-image-store.s3.amazonaws.com/0/179446/0fe98adc-0da3-4126-2565-94541fbd22ca.png)

![create_mar1803.png](https://qiita-image-store.s3.amazonaws.com/0/179446/438d6a21-f796-7fed-4f5b-8e615669f007.png)

没年を修正する
http://127.0.0.1:8000/catalog/author/5 で詳細が表示されたら、
http://127.0.0.1:8000/catalog/author/5/update
にアクセスする。
![update_mar1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/58f714e2-b965-1fd1-d463-77c4201ef7fb.png)

削除
http://127.0.0.1:8000/catalog/author/5/delete/ にアクセスする。
![delete_mar1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/adb3a58a-3d2c-40d2-1a47-dc2f0dc0d90d.png)
git submoduleの話(cloneしたら有るはずのものが無い空っぽのディレクトリが… etc)

個人的備忘録です。
# git submodule とは
乱暴に言うと、あるリポジトリのサブディレクトリ配下に **別のリポジトリ(プロジェクト)** を取り込み、そのまま管理するというもの。

## どこで使うの
たとえば static site generator である Hugo でテーマ(スキン)。
テーマそれぞれが git リポジトリになっていて、それを hugo の site配下で themes/ の下に持ってくる必要がある。

```bash
$ cd themes
$ git clone テーマ.git
```
一見これでも問題はない。でも、たとえば netlify を使うことになると、このhugoのsite以下をgitで管理する必要が出てくる。じゃあ、その中にあるthemesにどうやって持ってくるのか? そこでsubmoduleの出番になってくる。

## 小さな落とし穴
```bash
$ git submodule add サブモジュールとしてチェックアウトしたいなんとか.git
```
こうすると、とりあえずうまくいく。ファイルもばっちり取り出されている。これを、git addしてcommitしてpushして...

別のマシンなり環境なりで、この全体を git clone する。と、サブモジュールとしたディレクトリ配下が空っぽである。
あれ！？pushしたんじゃなかったの?

## 対策
のちに取り出した方の環境ではサブモジュールが有効になっておらず取り出せてもいない。詳細は割愛する。(.gitmodulesとかなんとか調べてください)

```bash
$ git submodule init
$ git submodule update
```
とするか、そもそも

```bash
$ git clone --recursive 自分のリポジトリ
```
とすれば良い。

# 余談
netlify で hugo なサイトを回している感じでは、clone --recursive されているようだ。実際チュートリアルにも submodule でやれよみたいなこと書いてあるし。

# 余談2
git submodule 「なにがどうなっているのか」を完全に理解しない限り奇妙に見える(たとえばcommit idに紐付いているとか) が、使う分にはすこぶる快適なのでオススメ

# 参照
- Hugo (https://gohugo.io/)
- netlify (https://www.netlify.com/)
CanvasとSVGの違い

CanvaとSVGの違い

## SVG

* ベクター形式で描画
* 拡張子は「.svg」
* 図形がDOM要素なのでJavaScriptとの相性がよい
* ベクター形式なので拡大、縮小で図形の劣化がない
* グラフィックスをXMLで表現する
* 円を描く場合は白紙にコンパスで円を表現するといった描画
* 高精細な円を表示できる
* SVGは単独で装飾や変形によるアニメーションが可能

## Canvas

* HTML5の機能の一つ
* ラスター形式(ビットマップ形式)で描画
* <canvas>要素で描画領域を確保してJavaScriptで描画する
* ビットマップ形式なのでピクセル単位での細かい描画が行える
俺のオススメする監視ツール5選！！


## 監視ツール

監視ツールと一概に言っても色々種類あるのですが、今回はコマンド等で手軽に実行できるリソース監視ツールを紹介します。
一部、あまりオススメできないのもありますので、デメリット等よく読んでから利用してください。


1. [top](#top)
1. [htop](#htop)
1. [ctop](#ctop)
1. [gtop](#gtop)
1. [conky](#conky)

## top

様々なOSにデフォルトで入っているかと思います。多分。

```bash
## 起動方法
$ top
```
![ubuntu-top.png](https://qiita-image-store.s3.amazonaws.com/0/275273/e822f4c6-b281-1898-4880-807ac17b9a08.png)
↑こんな感じになります。

- メリット
  - どのOSにも入っている(多分)
- デメリット
  - macだとtopコマンド自体がリソースを喰う。windowsは未確認です
  - ↑僕のPCだと8〜15%ほどCPU消費してました

## htop

`top`コマンドの強いバージョン。
[こちら](https://qiita.com/khotta/items/a998a52bc56c3bfe5f91)で紹介されているように、top使うくらいならhtop使いましょう。ってくらい良い感じのツールです。

```bash
## インストール方法
$ sudo yum install htop

## 起動方法
$ htop
```

![htop.png](https://qiita-image-store.s3.amazonaws.com/0/275273/11e39554-4a5c-e476-f5a8-4b905f68a852.png)

- メリット
  - 導入が簡単
  - 見た目もよし
- デメリット
  - 好きすぎて辛い

## ctop

Dockerコンテナのリソース消費量を確認するのが楽。
稼働中のコンテナのリソース、選択した単体のコンテナの詳細リソースまでを表示してくれます。導入が楽なのもポイント高い。

※Docker Desktop バージョン 4.18 以降、デフォルトのソケットを生成しなくなったようで、その影響でctopが機能しないようです。ctop自体もしばらく更新されてないので残念ですが使用は控えた方が良いですね

```bash
## インストール方法
$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.6.0/ctop-0.6.0-linux-amd64 -O /usr/local/bin/ctop
$ sudo chmod +x /usr/local/bin/ctop

## インストール方法(Macの場合)
$ brew install ctop


## 起動方法
$ ctop
```

![ctop.png](https://qiita-image-store.s3.amazonaws.com/0/275273/25da47cb-73b5-0fb1-b8b2-61f3cd98f4b5.png)
↑コンテナ一覧(1つしかないけど)

![ctop_2.png](https://qiita-image-store.s3.amazonaws.com/0/275273/557729ab-7fb7-c045-4744-c50514a8d3d1.png)
↑対象コンテナをEnterで選択で詳細モード

- メリット
  - 手間をかけずに導入できる
  - brewでmacにインストールできる ←ご指摘いただきありがとうございます！
- デメリット
  - ~~Linux用のバイナリなのでMacでは動作しない。 `docker stats` などを使いましょう~~

## gtop

グラフィカルな感じにリソース監視等ができます。
Node.JSで動作してるようなので自分好みにカスタムできそうです。

```bash
## インストール方法
$ npm install gtop -g

## 起動方法
$ gtop
```

![gtop.png](https://qiita-image-store.s3.amazonaws.com/0/275273/695e5b51-70f9-71b1-1426-b3bce00bcd15.png)
↑グラフィカルな感じがいい感じ

- メリット
  - Nodeが入ってたら手軽に導入できる
  - グラフィカルな感じがいい感じ
- デメリット
  - Nodeが入ってる前提なので入ってない場合導入ダルい

カスタム・自作方法は[こちら](https://github.com/yaronn/blessed-contrib)を参考にしてみてください。


## conky

ラズパイとかUbuntuで動かしてました。
導入方法とかは忘れたのですが、自分好みにカスタマイズできるので、興味ある方は是非。

https://github.com/brndnmtthws/conky

## まとめ

監視ツールって導入が大変だったり、設定が大変だったりしますが、単体のリソース監視をするのであれば上記で紹介したツールで十分ですかね。

個人的には`htop`と`ctop`が好きですが、`gtop`もなかなか可能性を秘めているので今後、うまく活用できれば良いかなと思います。

それとスタバで`htop`がカッコ良かったのも2年前の話ですね。
今風に行くなら`screen`コマンドで画面分割しながら、`Node.JS, blessed-contrib`を利用して自作したリソース監視ツールを起動させつつ`Docker`いじり倒すとか。今風がなんなのかわからないですが。

# おすすめ♪ リンク♪

- スタバ関連
  - [スタバで逆ナンされる方法(＊´・∀・＊)](https://qiita.com/joe_hirata/items/372212f1a5d9fd5b98cd)
【WordPress】分割された記事（投稿）の最後のページかどうかを判定する


# 記事分割した時、カスタムフィールドで追加した項目を記事の一番最後にだけ表示させる

記事を分割した際に、最後のページだけコンテンツを表示させるために、
記事の最後のページかを判定する関数が**WordPressの標準関数であるのかと思ったらなかった。**
（`is_paged()`がそうかと思ったらアーカイブページとかで使う用でした）
なんでそれ用の関数を作ってみました。

# ソース

テーマ以下の**functions.php**に以下を追加

```functions.php
// 投稿ページの分割ページの最後か
function is_post_page_end() {
	global $numpages;
	$paged = (get_query_var('page')) ? get_query_var('page') : 1;
	return $paged == $numpages;
}
```

# 使用例

分割された記事の最後のページだと`true`が返ります

```single.php
<?php if ( is_post_page_end() ) : ?>
<p>この記事はこのページで最後です。</p>
<?php endif; ?>
```

# おわり

- もしかすると調べ切れてないだけで標準関数あったりするんですかね？
はじめてのプログラミング　〜putsとは〜

##puts とは

puts とは、「（puts に続く文字や数字を）表示して」という意味のお願いです。

このお願いを「メソッド」と言い、puts に続く文字や数字を「オブジェクト」と言います。（文字オブジェクトとか整数オブジェクトと呼ぶ）

puts はRuby という言語で学ぶ一番最初のメソッドです。

##書き方
```
puts  "文字"
puts  数字
```

puts のあとに半角スペースが入ります。

また、文字オブジェクトの場合は“ ”（ダブルクォーテーション）で囲う必要があります。それにより文字情報と認識され、ダブルクォーテーションを除外し文字のみで出力されます。

```test.rb
puts "こんにちは"
puts 2020
```
↓出力（$ ruby test.rb）

```
こんにちは
2020
```

##計算もできる

putsのあとに計算式を入れることで計算結果を表示することが出来ます。

```calc.rb
puts 6+3
puts 6-3
puts 6*3
puts 6/3
```
↓出力（$ruby calc.rb）

```
9
3
18
2
```

下2つに見慣れない記号がありますが、計算結果を見ておわかりのとおり、

*　＝　×
/　＝　÷

という意味になります。
キーボードで×や÷がないので*と/で代用する形になります。

ちなみに+ , - , * , / は代数演算子といいます。

##puts , print , p

実はputs 以外にも後ろに続くオブジェクトを表示するメソッドがあります。それが「print メソッド」と「pメソッド」です。

どちらもputs と同じく「表示して」とお願いするためのメソッドですが、若干性質が異なります。

●puts → 出力のあと改行される。
●print → 出力のあと改行されない。
●p → 数値はそのまま表示、文字列はダブルクォーテーションで挟まれた状態で表示される。出力のあと改行される。

説明だと意味がよくわからないかもしれませんが、文字と数字の2つのオブジェクトで試すと違いが分かりやすいです。

```test.rb
puts 30,"歳"

print 30,"歳"

p 30,"歳"
```
↓出力（$ ruby test.rb)

```
30
歳

30歳

30
"歳"
```

pメソッドは基本「デバック」のために使われます。
「デバック」とは、問題があって動かない部分（バグ）の原因を調べて正すことを言います。


##まとめ
・putsは文字や数字のオブジェクトを「表示する」ためのメソッド
・putsは計算もできる（+ , - , * , / は演算子と言う）
・「表示する」メソッド
●puts → 出力のあと改行される。
●print → 出力のあと改行されない。
●p → 数値はそのまま表示、文字列はダブルクォーテーションで挟まれた状態で表示される。出力のあと改行される。
Windows10でMongoDB4.0.6を使う

## 構築環境
* Windows 10(64bit)
* MongoDB 4.0.6 


## 参考情報
[MongoDB4.0をインストール(Windows10)](https://qiita.com/takako_sudou/items/c48c360eca4d1488daee)

## MongoDBのダウンロード
ここからダウンロードを行います。
今回はMongoDB Community Serverをダウンロードします。
https://www.mongodb.com/download-center/community
![win10mongo01.png](https://qiita-image-store.s3.amazonaws.com/0/362279/00fb87ff-5b2e-da00-e685-f17108b77df7.png)

## インストール
こちらの情報を参考にインストールを行います。
[Install MongoDB Community Edition on Windows](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/)

1. ダウンロードしたMSIファイルをダブルクリックします。
2. Nextボタンをクリックします。
![win10mongo02.png](https://qiita-image-store.s3.amazonaws.com/0/362279/735ec87e-521e-d57f-8389-bb5a75939e30.png)

3. 「I accept the terms in the license Agreement」にチェックをつけてNextボタンをクリックします。
![win10mongo03.png](https://qiita-image-store.s3.amazonaws.com/0/362279/b2093f64-7a7a-e1d5-500f-bfe4670a4d3f.png)
4. Completeボタンをクリックします。
![win10mongo04.png](https://qiita-image-store.s3.amazonaws.com/0/362279/a295ab4f-b947-9dd4-63bd-4f43a5211a6e.png)
5. インストール先など適宜環境に合わせて変更してからNextボタンをクリックします。
今回の環境ではDドライブ直下にインストールしています。
![win10mongo05.png](https://qiita-image-store.s3.amazonaws.com/0/362279/1cd75c39-fa79-50b7-b501-35333a752c3c.png)
6. 初期表示設定のままNextボタンをクリックします。
MongoDB Compass を一緒にインストールします。
[？Compassとはなにか？](https://qiita.com/tomy0610/items/81391f74b51706b5c171)
![win10mongo06.png](https://qiita-image-store.s3.amazonaws.com/0/362279/4ad4eb7e-1a8b-b5ba-ca8d-ed4c3929e190.png)
7. Installボタンをクリックします。
![win10mongo07.png](https://qiita-image-store.s3.amazonaws.com/0/362279/89b7df0b-ab9e-f7ea-59a5-0dbbcb360edc.png)
8. 少々まちます。
私の環境では約３分くらいでインストール完了しました。
![win10mongo08.png](https://qiita-image-store.s3.amazonaws.com/0/362279/b23b9ae6-b359-560a-1aca-14284edea3bf.png)
9. Finishボタンをクリックします。
![win10mongo09.png](https://qiita-image-store.s3.amazonaws.com/0/362279/60971ffd-f276-8ed1-e8f4-debfc348fabb.png)
__以上でインストールは完了です__

## MongoDB Compass がインストールされていないように思うのですが・・・
インストール直後に画面上何も表示されない状況となりました。

* WindowsのサービスではMongoDB Serverサービスが実行中になっている
* インストール手順でMongoDB Compassインストールする設定にしたはずなのに・・・？

### 今回はこの手順でMongoDB Compassをインストールしました。

* なぜが、CドライブにMongoDB関連ファイルがありました。→ __C:\Program Files\MongoDB\Server\4.0\bin__

1. InstallCompass.ps1を右クリックして、PowerShellで実行をクリックします。  
実行ポリシーの変更等入力を求められるので、適宜環境に合わせて選択してください。  
__しばし待ちます。__  
2. インストール用exeのダウンロードが終わると、License Agreementが表示されるので、内容確認します。
3. ライセンスに同意したら、Agreeボタンをクリックします。
![win10mongo10.png](https://qiita-image-store.s3.amazonaws.com/0/362279/b6b00705-8470-b054-5175-d094cb94c9cb.png)
4.チュートリアルを進めて行きます。  
5.Privacy Settingsとして適宜設定を行い、Start Using Compassボタンをクリックします。
今回私は全てのチェックを外してみました。  
![win10mongo11.png](https://qiita-image-store.s3.amazonaws.com/0/362279/ebb43819-b3a3-c510-c345-e389d31f6910.png)  
6.デフォルトのままCONNECTボタンをクリックします。  
__以上でとりあえず使える状況までの作業は完了です__
VDSL でフェライトコア、ツイストペアケーブル、シールドって効果あるの？

# この記事について
この記事は、電話線でインターネットに接続する VDSL のケーブルをちょっと高性能なケーブルに交換したら、通信速度がどれくらい変わるのかを調べた記事である。

# まず最初に結論から (通信速度の変化)

### 測定方法および通信環境の概要

- 測定方法 : FAST powered by Netflix (https://fast.com/ja/)
- 交換後のケーブル : フェライトコアおよびシールドを備えるツイストペアケーブル (ELPA TEW-A010)
- プロバイダ : DMM
- インターネット接続 : Flets 光コラボ, V6プラス （= 光配線なら、数 100 Mbps の速度が出る）

### 測定結果

|測定項目|VDSL機器に同包されていたケーブル|ちょっと高性能なケーブル<br>(シールド、フェライトコア、ツイストペア)|交換後のパーセンテージ|
|:--|:--|:--|:--|
|DL 速度 (Mbps)           |88.5 Mbps|90.5 Mbps|102 %|
|UP 速度 (Mbps)           |46.0 Mbps|52.5 Mbps|114 %|
|レイテンシ (アンロード済, ms)|6 ms |6 ms |100 %|
|レイテンシ (ロード済, ms)|25 ms|13 ms|52 %|

### 結果に対する考察
アップロード速度とレイテンシ (ロード済) に改善が見られる。ダウンロード速度とレイテンシ (アンロード済) に変化は見られない。
物理回線の品質が低い場合 (理論値の 50 % など)、速度およびレイテンシの改善がされるのかもしれない。

# 用語の解説

### VDSL
VDSL とは、電話用メタルケーブル2対を利用した通信方式。建物の都合上、インターネット接続用光ケーブルを部屋まで配線することができないマンションやアパートで利用される。最大 100 Mbps の通信速度がよく利用される。
G.fast という、最大通信速度上り下り合計 830 Mbps の規格もサービス提供が開始されている （2018年10月）。しかし、2019 年3月時点では、ごく一部のマンションにのみ提供されており、普及されているとは言い難い。

### フェライトコア
磁石の周りにケーブルを通すことで、ノイズを抑える器具。

### ツイストペアケーブル
メタルケーブルのペアをツイスト （ひねる） ことで、ノイズを抑えたケーブル。

### シールド
メタルケーブルを金属の編み物で包むことで、ノイズを抑える仕組み・構造。

# 最後に （計測してみて感じたこと)

- 電気配線の品質測定や通信の品質測定が十分にできなかった。
- VDSL機器に、電気配線の品質を測定する機能が欲しいと感じた。
- 定期的に速度測定するアプリや様々な通信品質（パケットロスなど）を測定するアプリが欲しいと感じた。
- 結局、通信速度はあまり改善しなかった。（自己満足)
gifアニで画面収録する

たまーに、動画じゃないと伝えられない時がある
gitのissueとかで、伝えたい時に、
「giphy」を使うと便利

ここからダウンロード
https://giphy.com/apps/giphy

![giftest.gif](https://qiita-image-store.s3.amazonaws.com/0/87607/d7bd1bb5-53bf-9cb5-9609-0a7d3072e0f1.gif)
Vue cli3でVue + TypeScriptの環境を作成する

VueとTyspeScriptを利用した開発が始まるので、キャッチアップとしての環境作成を行ってみました。vue-cliを利用すれば。対話形式でプロジェクトテンプレートが作成されるので特に問題なく環境を作成することができました。

まずglaobalにvue-cliを落とします。Vue CLIはVue.js向けアプリケーションの開発環境をセットアップしてくれるコマンドラインツールのことです。Nodejsは既に手元の環境に設定されているものとします(v8.11.2)

```
$ yarn global add @vue/cli
```
installしたら環境が整ったことを確認してみます。

```
$ vue --version
> 3.5.1
```

vueコマンドで、vueプロジェクトを作成します。今回はportfolio用にプロジェクトを作成するので、vue create < project-name > で作成しました。

```
$ vue create portfolio
```

そうするとプリセットの選択を質問されるので、デフォルト(babel、eslint)かマニュアル(色々な機能を追加できる)を選択する。今回はTypeScriptを使用するので、マニュアルを選択する。

```
Vue CLI v3.5.1
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features 
```

必要な機能をspaceで追加してプロジェクトを作成します。必須としてい機能は、Babel,TypeScript,Linterくらいですが、今回は練習用のポートフォリオサイトなので全ての機能をオンにしています。

```
? Check the features needed for your project: (Press <space> to select, <a> to t
oggle all, <i> to invert selection)
❯◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
```

一応上からの機能軽くを調べてみる

- Babel:javascriptのバージョンの違いを解消する。
- TypeScript:型付nJavascript
- PWA support:PWAの機能使用をサポート
- Router: URL繊維を簡単に実現できるようになる
- Vuex: vueの状態管理用ライブラリ
- CSS Pre-processors: Sass,Scssなど使用できるように
- Linter: Linterを使用する
- UnitTesting:単体テスト
- E２E Testing:結合テスト

ここまで全て設定し、Enterを押すとプロジェクトが作成される。あとはディレクトリを変更し、サーバを起動する

```
 $ cd portfolio
 $ yarn serve
```

すると、ローカルサーバーが起動し、アクセスが可能となる。
[PC]
<img width="1016" alt="スクリーンショット 2019-03-18 18.16.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/205283/a09c5638-b7f3-6795-07c0-4a78e6a677b4.png">

[SP]
<img width="412" alt="スクリーンショット 2019-03-18 18.41.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/205283/be4b0595-a6cc-b18a-9c00-1e56edd4249e.png">

以上で、環境設定までが完了した。
ggplot2で内向きに目盛り線を描く

Rのggplot2パッケージは、デフォルトではグラフの目盛りは外向きになっていますが、向きと長さを変えることができます。この記事では、その方法を示します。
irisのグラフを使って、普通にグラフを描くと次のようになります。

```plotiris.R
ggp <- ggplot(data=iris) +
  geom_point(aes(x=Sepal.Length, y=Petal.Length)) 
print(ggp)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100982/19a981b6-33c9-202f-6212-cf41f02d1c6f.png)
グラフの目盛りは外側を向いています。
theme()を次のようにいじってやると、

```plotiris2.R
ggp <- ggplot(data=iris) +
  geom_point(aes(x=Sepal.Length, y=Petal.Length)) + 
  theme(
    axis.ticks = element_line(colour = "black"),
    axis.ticks.length = unit(-3, "mm"),
    axis.text.x = element_text(margin = unit(rep(8,4), "mm")),
    axis.text.y = element_text(margin = unit(rep(8,4), "mm"))
  )
print(ggp)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100982/f49ecb4d-dc83-7c06-42e8-68d76b03d33f.png)
目盛りは内向きになりました。
axis.ticks.length の数字をマイナスにすればいいです。ただし、その場合axis.text.x=~で目盛りと数字の距離を調整しないと適切な位置に目盛りの数字が表示されません。

僕はどっちかというと内向きのほうが好きです。
Puppeteerインストール

自分用メモ

```bash
# 依存ライブラリインストール for Ubuntu 18.04
sudo apt install -y gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
# for CentOS 7
sudo yum install -y pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc

# [蛇足] nodebrew をよく使っているのでインストール
curl -L git.io/nodebrew | perl - setup
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
nodebrew install-binary stable
nodebrew use stable
node -v # 正しくインストールされたか確認
npm i -g npm # npm アップデート

# インストール先を作成
mkdir foobar
cd foobar
npm init -y

# インストール
npm i puppeteer
```

以下のファイルを作成

```js:example.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  // CentOSの場合、Sandbox関係でエラーが発生。動かすだけが目的なので、以下のように変更
  // cf. https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
  // const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();
```

```bash
node example.js
ls
# example.png があることを確認
```

久々にCentOS触ったらなんかふわっとした気持ちになった。
Emacsのdiredでドットファイルの表示・非表示を切り替える関数を作った

# モチベーション

Emacsのdiredモードをよく使う。
このとき、ドットファイルが表示されてほしいときもあれば、表示されてほしくないときもある。
例えば、ホームディレクトリはドットファイルが大量にあるため、普段は隠したい。
一方で、Git管理のディレクトリでは、.gitignoreがあるのを見えるようにしておきたい。
そこで、diredモードが使うlsのオプションをいい感じに変えるようにした。

# コード

diredバッファのリロードをする関数が見つからなかったので自作した。
現在のドットファイルの表示状況は`[aA]`の簡単なマッチでする。

`-lgGhF`や`-lgGhFA`のところは、各自の好みで変えるとよい。
デフォルトは`-al`らしいです。

ドットファイルの切り替えなので`C-.`に割り当てた。
けっこう気に入っている。

```elisp
;; C-.でドットファイルの表示と非表示を切り替える
(setq dired-listing-switches "-lgGhF")
(defun reload-current-dired-buffer ()
  "Reload current `dired-mode' buffer."
  (let* ((dir (dired-current-directory)))
    (progn (kill-buffer (current-buffer))
           (dired dir))))
(defun toggle-dired-listing-switches ()
  "Toggle `dired-mode' switch between with and without 'A' option to show or hide dot files."
  (interactive)
  (progn
    (if (string-match "[Aa]" dired-listing-switches)
        (setq dired-listing-switches "-lgGhF")
      (setq dired-listing-switches "-lgGhFA"))
    (reload-current-dired-buffer)))
(define-key dired-mode-map (kbd "C-.") 'toggle-dired-listing-switches)
```

# （追記）use-package化したコード

use-package化したので、以下のようになった。

```emacs-lisp
(use-package dired
  :custom
  (dired-listing-switches "-lgGhF")
  :config
  ;; C-.でドットファイルの表示と非表示を切り替える
  (defun reload-current-dired-buffer ()
    "Reload current `dired-mode' buffer."
    (let* ((dir (dired-current-directory)))
      (progn (kill-buffer (current-buffer))
             (dired dir))))
  (defun toggle-dired-listing-switches ()
    "Toggle `dired-mode' switch between with and without 'A' option to show or hide dot files."
    (interactive)
    (progn
      (if (string-match "[Aa]" dired-listing-switches)
          (setq dired-listing-switches "-lgGhF")
        (setq dired-listing-switches "-lgGhFA"))
      (reload-current-dired-buffer)))
  :bind (:map dired-mode-map
              ("C-." . toggle-dired-listing-switches)))
```
MbedStudioでの開発環境構築（windows10）

この記事では、Mbedマイコンのオフライン開発環境の構築をMbedStudioを使って行い、Lチカを行うところまでを目標としています。

## MbedStudioについて
MbedStudioとは最近公式からリリースされたIDEで、Mbedマイコンのオフラインコンパイラとして使えます。また、デバッグ機能を有していたり、Gitに対応していたりもします。

## mbedCLIのインストール
MbedStudioにはmbedOSが必要なので、mbedCLIを先にインストールしておきます。mbedCLIのインストールは[この記事][1]を参考にしました。

## MbedStudioのインストール
次にMbedStudioをインストールします。割と時間喰います。

- [Mbed-MbedStudio][2]

## Lチカをやってみる
インストールが終わったらMbedStudioを起動してください。
起動したら最初の画面はこのようになってるかと思います。

<img src="https://qiita-image-store.s3.amazonaws.com/0/280822/4f6090ed-a510-8fae-bbd3-463f7baf9d93.png" width=80%>

次に、「Create Program => New Program...」を選択すると、以下のような画面が出てくると思います。
ここで「Select example program:」の項目は「empty Mbed OS program」を選択します。
Program名は何でもいいです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/280822/0798a26a-7909-dc7a-8c69-dfafd71be9de.png" width=80%>

「Add Program」を押すと、左側に作成したプログラムが出てきます。
ここまで来たら、自分が持ってるマイコンボードをPCに接続しましょう。
今回はLPC1768を使います。

<img src="https://qiita-image-store.s3.amazonaws.com/0/280822/abf8d6f6-64e9-2bb0-02e1-fed0685e0ebb.png" width=50%>

ボードを接続して、正しくmbedOSがボードを認識してくれれば「Target」の項目には自分のボード名が表示されているはずです。（上図参照）

確認が済んだら、main.cppの中に以下のプログラムを書いてビルドしてみてみましょう。ちなみにビルドはトンカチマークです。

```
#include "mbed.h"

DigitalOut myled(LED4);

int main() {
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}
```

……ビルドが長い。長すぎる。
やっとこさビルドが終わったら、binファイルの場所が下の「Output」のところに表示されてるので、そこにある.binファイルをmbedマイコンにコピーします。
コピーしたらマイコンのリセットボタンを押してLチカができてるか確認してください。

不具合や間違いなどありましたらコメントよろしくお願いします。

[1]:https://qiita.com/matsujirushi/items/bf4db4514a753f794643
[2]:https://os.mbed.com/studio/
PosgreSQLから 関数を 名前を指定して 関数毎に 別ファイルに エクスポートする

## 前段

``PoostgreSQL 10.6 (on docker)``で確認しています。
必要に迫られてDBからストアドファンクションのコードを取り出すことに。

``pg_dump``で一括確保！も考えたのですが、関数毎にファイルが分かれないのでダンプファイルを解析する必要があり、それはとてもとても面倒なのでやめました。

## 本題

- 対象の関数名を取得する

ぐぐってヒットした記事

> ユーザ定義関数情報の参照
http://yanor.net/wiki/?PostgreSQL/%E3%82%B9%E3%83%88%E3%82%A2%E3%83%89%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3/%E3%83%A6%E3%83%BC%E3%82%B6%E5%AE%9A%E7%BE%A9%E9%96%A2%E6%95%B0%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%82%E7%85%A7

も試してみたのですが、どうもpostgreSQL由来の関数も大量にヒットしてしまうため、やめました。
結局原始的に``pg_dump``で出力したダンプファイルを..

```sh
grep "CREATE FUNCTION" ./[ダンプファイル名].dump
```

という力技で解決。
シンプルが一番。

関数名さえとれればこっちのもの。

> PostgreSQL の psql で関数のソースコードを取得する
http://everything-you-do-is-practice.blogspot.com/2017/09/postgresql-psql.html

こちらの方法に従ってソースコードを取り出せます。
ただ、これだとヘッダに``psql``の余計な出力、各行の末尾にも余計なスペースと``+``がついてしまうので、sedで加工します。

```sh
sed -i -e "s/ *+$//" ./[エクスポートした関数].sql
```

これでそのままCREATEできるSQLができました。


以上の手順をまとめたスクリプトがこちら

```sh
#!/bin/bash
# export stored functions from database.
set -e

DB_HOST=[適切なホスト名]
DB_USER=[適切なユーザー名]
DB_NAME=[適切なDB名]

DB_CON="psql -t -h ${DB_HOST} -U ${DB_USER} ${DB_NAME}"

FUNCTIONS="\
    function_name_1 \
    function_name_2 \
"

for f in $FUNCTIONS
do
    echo $f;
    QUERY="SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${f}'));";
    echo $QUERY | $DB_CON > "${f}.sql"

    sed -i -e "s/ *+$//" ${f}.sql
done

```

ご参考まで。
【Kotlin】FragmentでViewPagerを使う時の注意点(再読み込みできない)

BottomNavigationViewのタブで切り替え表示をするFragmentのうちの１つで
ViewPagerを使って実装をしていて

#### BottomNavigationViewのタブを切り替えると実行されるはずの読み込み処理が実行されず、かつ直前に読み込んでいたデータも表示されなくなった

という現象が起きて嵌りました。

【画面構成（階層）】
MainActivity(BottomNavigationViewを使用)
　　|- ParentFragment(ViewPagerを使用)
　　　　|- ViewPager
　　　　　　|- ChildFragments(ViewPagerの各ページに表示するFragment達)


先に解決策の載せておきます。↓↓

## 解決策

ViewPagerにセットするFragmentPagerAdapterのインスタンスを生成する時に 
#### childFragmentManager
を渡す。これで解決しました。

```kotlin:FragmentPagerAdapter（解決後）

    val adapter = FragmentPagerAdapter(childFragmentManager)  //←　ここ
    viewPager.adapter = adapter

    class AroundPagerAdapter(fragmentManager: FragmentManager?) : 
            FragmentPagerAdapter(fragmentManager) {

        // 省略
    }

```
```kotlin:FragmentPagerAdapter（解決前）

    val adapter = FragmentPagerAdapter(fragmentManager)
    viewPager.adapter = adapter

    class AroundPagerAdapter(fragmentManager: FragmentManager?) : 
            FragmentPagerAdapter(fragmentManager) {

        // 省略
    }

```

## 実際に起きていたこと
BottomNavigationViewのタブから別タブに切り替えて再びそのタブに戻ってきたとき、

```
FragmentPagerAdapter#getItem() 
```
が呼ばれず、 ViewPager 内が再読込みされない現象が起きていました。

なぜ起きたのか、、、

**①FragmentPagerAdapterはメモリ上にViewPagerの子Fragment(ChildFragments)を全て保持する**
　→　タブを切り替えた時は以前のものが再利用される
　[FragmentPagerAdapter](https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter)

**②BottomNavigationViewのタブ切り替えだとParentActivityは生きたまま**
　→　FragmentManagerはViewPager内の子Fragment達(ChildFragments)を保持したままになり、 FragmentPagerAdapter#getItem() が呼ばれない


①②に対して、childFragmentManagerを使うと

#### 保持される ViewPager 内のChildFragmentsはParentFragmentのFragmentManagerで管理される。
#### →タブを切り替えたときにはParentFragmentのインスタンスを再生成するのでそのタイミングでFragmentManagerがリセットされる
#### →新しくChildFragmentsのインスタンスを生成するので「FragmentPagerAdapter#getItem()」 が呼ばれて再読込みが始まるようになる。


（余談）
ViewPager のスワイプが起きたときは ParentFragment が生きている限り、 FragmentManager 内で ChildFragments が管理されるので、通常通り効率的にスワイプできるようになる。

## まとめ
かなり嵌りましたが、解決してみるとあっけなかったですね　笑

以上です。
botocore の通信の中身を mitmproxy で確認

# Overview

ちょっと前にこんな記事が出てたので、s3 アクセス時の署名のバージョンを確認したい話。
https://dev.classmethod.jp/cloud/aws/s3-sigv2-abolition/

tcpdump だと ssl の中身見れないので、Man-in-The-Middle proxy 使います。

# 準備

以下とりあえずサンプルで `aws s3` で試してますが、
`aws ec2 describe-instances` とかでも使えます。

## [mitmproxy](https://mitmproxy.org/)

インストールとpemの設定は済ませておいてください。
mac の人は homebrew じゃなくても `pip install mitmproxy` で普通に入ります。

```bash
export MITMPROXY_CA=mitmproxy-ca-cert.pem
```

### 起動

```bash
mitmproxy -p 8000
```
`localhost:8000` で起動します（ポートはお好みで
あとでプロキシ経由でアクセスすると、ここに通信の中身が出ます。

## botocore

`awscli` も `boto` も中身 `botocore` を使用していて、`AWS_CA_BUNDLE` でオレオレ証明書をバンドルできるので、
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html

mitmproxy の証明書をバンドルしておきます。

```bash
export AWS_CA_BUNDLE=$MITMPROXY_CA
```

これを忘れると
`[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed` になるので注意。


# 挙動確認

awscli の設定は済ませておいてください。

```bash
$ python -V
Python 2.7.15

$ virtualenv .venv
(..snip..)

$ . .venv/bin/activate
```

## 署名v2（古いバージョン）

```bash:あかんやつ
$ pip install awscli==1.10.35
(..snip..)

$ aws --version
aws-cli/1.10.35 Python/2.7.15 Darwin/17.4.0 botocore/1.4.25
```

```bash
$ export HTTPS_PROXY=http://localhost:8000
$ export YOUR_BUCKET=your_bucket

$ aws s3 ls s3://$YOUR_BUCKET
```

![ng.png](https://qiita-image-store.s3.amazonaws.com/0/41925/88f9705f-3d6e-a6e7-a3c3-186deae8649e.png)


## 署名v4

```bash:OKなやつ
$ unset HTTPS_PROXY

$ pip install -U awscli
(..snip..)

$ aws --version
aws-cli/1.16.125 Python/2.7.15 Darwin/17.4.0 botocore/1.12.115
```

```bash
$ export HTTPS_PROXY=http://localhost:8000
$ export YOUR_BUCKET=your_bucket

$ aws s3 ls s3://$YOUR_BUCKET
```
![ok.png](https://qiita-image-store.s3.amazonaws.com/0/41925/9c6d53b5-09a3-7ad6-064d-1f28dc4f9bb3.png)


という話。


# おまけ

まぁ署名のバージョン知りたいだけなら `--debug` オプションで見れるんですけどね。

```bash
$ aws s3 --debug ls s3://${YOUR_BUCKET} 2>&1 | grep -A 1 -i 'signature'
2019-03-18 17:07:00,252 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2019-03-18 17:07:00,252 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
--
2019-03-18 17:07:00,252 - MainThread - botocore.auth - DEBUG - Signature:
466b9a9d3febd9940d5948b285b41516307c618ad024df36be331490350eb05e
```
エンジニアなら最低限しってインターネットの構造理解しようぜ

# インターネットの構造

## TCP/IP

インターネット通信で使われるプロトコルの総称。

※プロトコル（インターネット通信の複数からなる約束事）

## インターネット階層構造

インターネット通信はTCP/IPを中心にし、アプリケーションを実行する部分、ハードウェアが請け負う部分からなる4階層で捉えられ、これをインターネットモデルという

### アプリケーション層

プロトコル名：DNS,HTTP,SMTP,POP3,FTP  
使用例：ウェブサイト、メール、ファイル転送  
ルール：インターネットでのデータ形式と通信回線、データ送受信の回線経路に関するもの

### トランスポート層

プロトコル名：TCP、UDP  
使用例：TCPパケット（通信パケット）を確保
ルール：データにエラーがでても補正して通信の品質を守るもの

- UDPはテレビや映像を送信するためのもの

### ネットワーク層

プロトコル名：IP、ICMP、ARP  
使用例：IPパケットをMACフレームに格納
ルール：IPアドレスをMACフレームにつけてインターネットに送信するもの

- IPパケットはデータの送り先の情報などをデータにつけたもの
- MACフレームはLANなどでやり取りされるデータの単位を指す。データを入れる箱のようなもの。
- ICMPはIP通信にエラーが生じた際に使われるもの
- ARPはネットワークにつながっている機器の識別番号をIPアドレスへ変換するもの。

### リンク層

プロトコル名：Ethernet,PPP  
使用例：MACフレームを機器に送信
ルール：データを対象の機器にMACアドレスを付与して送信したり、物理的にケーブルとパソコンを接続するコネクタに関するものやケーブルの構造

- Ethernet(イーサネット)はLANの規格
- PPPは電話回線でTCP/IP接続を行うためのもの
- MACアドレスはネットワークに接続されているハードウェア固有のアドレスのこと。

## IPアドレスの役割

IPアドレスとはネットワーク機器間での通信に使われるもの  
（Internet Protocol）

### IPv4 (Internet Protocol version 4)

32ビットの数値でアドレスを表現している。  
8ビットずつ4つに区切られている  
127.000.001など10進数の数字で表現

アドレスとして多く利用されているが、最大43億しか表現できない

### IPv6（Internet Protocal version 6）

128ビットの数値でアドレスを表現している。  
fe80:212:daff:fe41:c81a:3290などの16進数の数字で表現

アドレスとして2の128乗個まで表現できるのでIPアドレスが不足することがまずなくなってくる

### プライベートアドレス

インターネットに接続するパソコン一つずつにIPを割り振っていたら枯渇する恐れがあるので個々のLANの中で使えるIPアドレスのこと。

### グローバルアドレス

インターネットで使われるIPアドレスのこと。  
同じLANの中のパソコンは同じIPが割り当てられる。

## ポート番号

IPアドレスではパソコンを識別できてもどのアプリケーションを使うかがわからないためポート番号を割り振りアプリケーションの種類を示す。

0～65535までの数字が用意されている

### ソケット

IPアドレスとポート番号を組み合わせたアドレスのこと。

### ウェルノウンポート

0～1023までの番号でアプリケーションにあらかじめ割り振られている番号

ウェブサイトでいうとhttpが80、SMTPが25など

### ユーザーポート

パソコンがデータをGETするときに自動的に未使用の番号を割り当ている番号

1024～49151までの番号

これにより一台のパソコンで複数のサイトをみることを可能にしている。

49152～65535は個人サーバーなどがデータを受け取るために使われている。

## まとめ

インターネットの構造は最低限エンジニアとして知っていなくてはいけないもの。
誤った解釈や、用語の使い方をすると脆弱性やエラーにつながりかねない。
もそ、プログラミングを学ぶ【Ruby on Rails】〜奥義！コントローラの継承〜

土日はしっかりバッチリ休息を取り、学習を再開させた もそ。
心身ともにリフレッシュして、これで勉強もスピードアップ！...なんてウマい話にはならず、頭を抱えながらカリキュラムと睨めっこをしています。

##コントローラの継承とは？

さて今日は、この無駄に語感のかっこいい"コントローラの継承"について書いていきます。
なんかゲーム後半の、師匠から主人公への必殺技伝授みたいですよね（？）

コントローラについては以前まとめた[MVCについて](https://qiita.com/moso/private/4a61da06c33fb019b7ab)こちらをご参照ください。

コントローラはルーティングの指示に従って、アクション（処理）した結果をビューに渡す役割があります。
そして**継承**とは、**継承元である他のオブジェクトのメソッドや特徴を引き継ぐ**ことです。

図でもう少し視覚的に説明していきますね。
継承元となるコントローラから、メソッドや特徴を引き継ぐとします。

![無題1148.jpeg](https://qiita-image-store.s3.amazonaws.com/0/372174/75f2843a-d0ca-bd6a-8d57-46468ebde244.jpeg)

そうすると、引き継いだ方は元のコントローラで定義された特徴やメソッドを使うことができます。
要はパワーアップする感じです。

![無題1148 2.jpeg](https://qiita-image-store.s3.amazonaws.com/0/372174/944d2fcb-e178-bcec-a837-40bba1006b19.jpeg)


ざっくりとしたイメージですが、これがコントローラの継承です。
コントローラの継承をすることで、たとえばあるAのメソッドと特徴をもった特定のコントローラだけに[before_action](https://qiita.com/moso/private/6ed35037fed1c004ea89)の処理をすることも可能です。
逆に言えば、**すべてのコントローラに共通した処理を行いたいときは継承元のコントローラに書き込む**ことで機能をもたせます。

つまり上の図で言うところの師匠コントローラにある処理を実行すれば、弟子コントローラたちすべてがそのメソッドなどを継承します。

--
いかがでしょうか？
相変わらずプログラミングには苦戦しているのですが、Qiitaに載せる用のイラストを短時間で描いて文を書いているうちに、若干イラストと文章のクオリティが上がっている気がします...
こういうのを本末転倒というのでしょうか...

イラストの質も上げつつ、プログラミングもしっかり理解をしていきたいです。
もそにもプログラミングを瞬時に理解できる機能を継承できたらいいのになあ。続く。
リーダブルコードを読んで思ったこと

# 感想
読んで良かった！
知っていること、自分で見つけたことも多くありましたが、全て独学だったので答え合わせのような感覚で読むことができました。
もちろん知らないこともたくさん載っていて、目からウロコの箇所が何度もありました。

冒頭に一週間から二週間で読んで欲しいって書いてあって、そんなに短期間で読めるかなぁ…と心配してました。
が、一週間程度で読破することができました。

Ruby on Railsを初めて触ったときの感動を言葉で説明されている感じでした。
オブジェクト指向の設計というのは、美しく、それ故に読みやすくなるのだなぁ、と思いました。

# 大事なこと
* やってみること
* 続けること
* 読み手を思いやること
* やりすぎに注意
* 大規模なコードは、自分の関わるところから、少しずつ改修していく

# わからなかったこと

* 最後の章のメモリ節約

最後の章でメモリを節約できる理由が理解できませんでした。
何度も読み直してみようと思います。

* ヒアドキュメントについての賛否

SQLのクエリを作成するような多重連結の例が、どこかにあったような気がするので、それも探してみようと思います。
zsh の起動の遅さに絶望して色々とゴソゴソ


単刀直入に。

before ~/.zshrc :

```.zshrc
export PATH="$PATH:$(brew --prefix coreutils)/libexec/gnubin"
export CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(xcrun --show-sdk-path)/usr/include"
export LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib"
```

この3行が活きていた頃、

```zsh
$ time ( zsh -i -c exit )
( zsh -i -c exit; )  3.62s user 2.59s system 44% cpu 14.076 total
$
```

after ~/.zshrc:

こう書き換えて計測

```.zshrc
#export PATH="$PATH:$(brew --prefix coreutils)/libexec/gnubin"
export PATH="$PATH:/usr/local/opt/coreutils/libexec/gnubin"
#export CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(xcrun --show-sdk-path)/usr/include"
export CFLAGS="-I/usr/local/opt/readline/include -I/usr/local/opt/openssl/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include"
#export LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib"
export LDFLAGS="-L/usr/local/opt/readline/lib -L/usr/local/opt/openssl/lib"
```

```zsh
$ time ( zsh -i -c exit )
( zsh -i -c exit; )  0.17s user 0.24s system 22% cpu 1.821 total
$
```

驚愕。
検索ヒット用に、zsh 起動 遅い 改善 brew を書いておきます。
Dockerコンテナ上でJavaプログラムを動かすときにLANG環境変数を設定すると日本語のファイル名が文字化けする問題

# 概要

CentOS の Docker コンテナ上で Java プログラムを動かしていたところ、日本語のファイル名を含むファイル一覧の取得で謎の文字化けが発生しました。

```Java:Sample.java
import java.io.*;

public class Sample {
   public static void main(String[] args) {
      // ファイル名が日本語のファイル「/sample/あいうえお.csv」を配置しておく
      new File("/sample").listFiles(new FilenameFilter() {
         public boolean accept(File dir, String name) {
            System.out.println(name);   // => ファイル一覧を取得すると日本語ファイル名が文字化けする
            return false;
         }
      });
   }
}
```

ちなみに、LANG環境変数を `en_US.UTF-8` とした場合は文字化けが発生せず、 `ja_JP.UTF-8` とした場合は文字化けが発生することが確認できています。

本記事では日本語ファイル名の文字化けの原因と対処方法について記載します。

# 原因と対処方法

まず、LANG環境変数へ `ja_JP.UTF-8` を設定すると文字化けが発生する原因ですが、これは Docker の **CentOS イメージに日本語ロケールが登録されていないため** です。

LANG環境変数に指定可能なロケールについては `locale -a` コマンドから確認することができます。
CentOS イメージのコンテナ内でコマンドを実行して確認してみます。

```
# locale -a
C
POSIX
en_US.utf8
```

上記の通り、Docker の CentOS イメージのコンテナ内には日本語ロケールが含まれていません。
このコンテナ内で以下のようにLANG環境変数を指定してJavaプログラムからファイル一覧を取得しようとすると日本語ファイル名の文字化けが発生します。

```
LANG=ja_JP.UTF-8
export LANG

java Sample
=> 文字化けした日本語ファイル名.csv
```

対処方法として、 `localedef` コマンドを使用して **日本語ロケールを追加する** ことで文字化けが解消します。
以下のコマンドを Dockerfile の RUN 命令として追加するかコンテナ内で実行します。

```
# localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
```

もう一度 `locale -a` コマンドで指定可能なロケールを確認してみます。

```
# locale -a
C
POSIX
en_US.utf8
ja_JP.utf8
```

`localedef` コマンドによって `ja_JP.utf8` が追加されました。
これでLANG環境変数を設定した場合も文字化けすることなく日本語のファイル名を扱えるようになります。

# 結論

* Docker の CentOS イメージのコンテナ内には日本語ロケールが含まれていない
* 日本語ロケールは localedef コマンドで追加できる
* 指定できない(環境に存在しない)ロケールをLANG環境変数から指定するとJavaプログラムで日本語ファイル名が文字化けする
Windowsで既定のアプリでの変更が効かないとき

# はじめに
Windows10から旧来の「コントロールパネル」での設定方法から「設定」での設定に代わり、
細かい設定がなくなったりで、エンジニアとしてはかなりつらいところです。

さて、プロファイルフォルダのEdgeの設定フォルダになんらか生じると、
Windowsの既定のブラウザの選択をすることができなくなります。

その時に役立てばと思います。

### 環境
Windows10 Pro Ver1809

# 現象
1. 既定のブラウザを「Edge」から「Chrome」すると、設定画面自体が落ちる。
2. 再起動しても、変更されない。

# 対応
レジストリキーをいじります。
※注意：レジストリキーはwindowsの様々なパラメータが入ってます。必要以上に触ると起動しなくなることもざらなので気を付けてください。
あくまで自己責任でおねがいします。

1. [レジストリエディター](https://pc-karuma.net/windows-10-open-registry-editor/)を開きます。
2. `HKEY_CURRENT_USER`を選択して、「ファイル」ー「エクスポート」を選択して、万が一のためにレジストリをバックアップします。
3. `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.htm\UserChoice` を開きます
4. `ProgID`の値が`ChromeHTML`になっていることを確認します。（なってなければ、変更。）
5. `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html\UserChoice` を開きます
6. `ProgID`の値が`ChromeHTML`になっていることを確認します。（なってなければ、変更。）
7. デスクトップ等にある.htmと.htmlファイルを開いて、chromeブラウザが開くことを確認します。
8. `HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice` を開きます
9. `ProgID`の値が`ChromeHTML`になっていることを確認します。（なってなければ、変更。）
10. `HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice` を開きます
11. `ProgID`の値が`ChromeHTML`になっていることを確認します。（なってなければ、変更。）
12. メールなどのリンクを開いてみて、Chromeが開くことを確認します。
13. 念のために再起動して動作を確認します。

注意：hashの値が入ってた場合、画面上で再度既定で開くアプリケーションを聞いてきます。
必ずChromeアプリを選んで「既定のアプリ」にチェックを入れてください。
ここを忘れると、またやり直しです。。。


# 終わりに
結局、UIがきれいになっても最後はレジストリキーに頼るしかないですね。バッチファイルは作りません！（すべての方でなるわけではないので）

もし付け加えてみることろ、変更するところがあれば教えてください。
検索したデータの形成　SQL

#　データの結合
- CONCAT関数

```ruby:ターミナル
SELECT CONCAT（family_name,first_name） FROM users;
#こうするとfamily_nameとfirst_nameが結合する。
#このようにいくつかのデータを用いて１つのデータを作りたいときにCONCAT関数を使う。
#ただ検索結果のカラム名はSQL文そのままとなっているので少し見にくくなる。
```

#　検索結果のカラム名の変更

- AS句

SELECT句でデータを取得するとき、AS句を併用するとそのカラムに別名をつけられる。

```ruby:ターミナル
SELECT CONCAT(family_name,first_name) AS "氏名" FROM users;
#こうすることでfamily_nameとfirst_nameが連結し、連結したカラム名が"氏名"になる。
#またAS句は省略することができる。

SELECT CONCAT(family_name,first_name) "氏名" FROM users;
#AS句を省略した記述。
```

#　重複する行の除外
- DISTINCTキーワード

```ruby:ターミナル
SELECT DISTINCT カラム名; #重複していれば一つしか表示しない。
```

#　レコードのグループ化
- GROUP BY句
指定したカラムが同じ値を持つデータを一つのグループとしてまとめることができる。

```ruby:ターミナル
GROUP BY カラム名;
#実行するとDISTINCTと同じような結果が返ってくるが、表示されていないだけで内部ではグループ化されたデータが存在する。
```

#　レコードの数を数える
- COUNT関数

COUNT関数はグループ化されたデータに対して使用することができる集計関数の一つ。
グループ化されたデータに使用できる集計関数は他に、AVG(平均を求める),MAX(最大値を求める),MIN(最小値を求める)がある。
COUNT関数はカラムを指定して使用することで、そのカラムの値がNULLでないデータの行数を取得することができる。
GROUP BY句を併用している場合は、各グループがレコードを何個持っているかというデータを取得することができる。

```ruby:ターミナル
SELECT COUNT(カラム名); #グループ化されているカラムを記述する。

SELECT COUNT(*); #ワイルドカードも使用できる。
```


# テーブルの結合

- JOIN

JOINを使用すると、指定したそれぞれのテーブルのカラムの値が一致するデータを結合することができる。
JOINはFROM句の後に記述し、結合の対象となるテーブルを指定する。

```ruby:ターミナル
FROM テーブル名１ JOIN テーブル名２ ON テーブル名１.カラム名１　= テーブル名２カラム名２;

#例えば
FROM shifts JOIN users ON shifts.user_id = users.id

#ONの後が冗長になるのでシンプルに書くなら
FROM shifts s JOIN users u ON s.user_id = u.id
#shiftsをs、usersをuと別名をつける。
#別名をつけることができるAS句は省略することができる。
```
例文
(わかりやすく短文で区切ります)

```ruby:ターミナル
SELECT
    CONCAT(family_name, first_name) "名前", #shiftsテーブルのfamily_nameと、first_nameを結合させ、名前という別名をつけ、表示させる。
    COUNT(*) "コマ数" #グループ化したデータの行数を表示する。(この場合user_idがグループ化されているので同じuser_idが何行あるのかが表示される。)ワイルドカード(*)を使用することでNULLであるレコードも含めて表示する。
FROM shifts s #shiftsテーブルから検索する。(shiftsテーブルにsという別名をつける。)
JOIN users u ON s.user_id = u.id #JOINで連結させたいusersテーブルを選択、ONで一致するカラムを選択し、連結させる。(usersテーブルにもuという別名をつけ、ONで別名を使用しカラム同士を連結させる。)
WHERE date = "2015-07-01" #dateカラムが2015-07-01のものを検索している。
GROUP BY user_id; #複数あるuser_idがグループ化される。
```

# 検索した結果からさらに検索
- サブクエリ

例えば

```ruby:ターミナル
SELECT DISTINCT user_id FROM shifts WHERE date = "2015-07-01";
```
のような検索結果があったとする。
まず上記のコードの説明。
FROM shiftsでshiftsテーブルを検索対象とし、WHEREでshiftsテーブルのdateカラムが2015-07-01のものを探し、SELECT DISTINCT user_idで重複しているuser_idを一つだけ表示させている。
つまり、dateカラムが2015-07-01に当てはまるuser_idを表示する。
この検索結果を踏まえて逆に2015-07-01に当てはまらないuser_idを調べたい。

その時の検索の仕方がこうだ。

```ruby:ターミナル
SELECT * #カラムを全て取得
FROM users #usersテーブルの検索
WHERE id NOT IN ( #NOT　IN()を使用し、()内の検索結果に当てはまらないレコードを取得する
  SELECT DISTINCT user_id
  FROM shifts
  WHERE date = "2015-07-01"
);
```

こうすることで()内に記述された検索結果に含まれないusersテーブルのレコードを取得できる。
ggplot2で太平洋が中心の世界地図を書く

太平洋での航海のデータをrでプロットしたいと思ったのだが、いわゆる経度0を中心とする地図では太平洋が分断されてしまって見辛い。
太平洋を中心に持ってくるような地図が書きたいと思ったが案外めんどくさく悩んだのでメモ。

調べてみるとみんな大好きstack overflowに回答が。
https://stackoverflow.com/questions/34011100/plot-pacific-ocean-and-continents-with-ggplot2borders


```r
library(ggplot2)
library(mapdata)

mp1 <- fortify(map(fill=TRUE, plot=FALSE))
mp2 <- mp1
mp2$long <- mp2$long + 360
mp2$group <- mp2$group + max(mp2$group) + 1
mp <- rbind(mp1, mp2)
ggplot(aes(x = long, y = lat, group = group), data = mp) + 
  geom_path()  + 
  scale_x_continuous(limits = c(110, 300)) + 
  scale_y_continuous(limits = c(-50, 70)) 

```

`map` を二つ作って無理矢理つなげている。

`fortify` は初めて知ったが、 `rbind` で結合するために `map` オブジェクトを `DataFrame` に変換するために使っているようだ。

`mp` の中身を `head()`で見るとこんな形になっている。

| long | lat | group | order | region | subregion |
|--:|--:|--:|--:|:--|:--|
| -69.89912 | 12.45200 | 1 | 1 | Aruba | NA |
| -69.89571 | 12.42300 | 1 | 2 | Aruba | NA |
| -69.94219 | 12.43853 | 1 | 3 | Aruba | NA |
| -70.00415 | 12.50049 | 1 | 4 | Aruba | NA |


とりあえず何も考えず手持ちの緯度経度のテーブルからプロットしてみる。

```r
library(ggplot2)
library(mapdata)
library(readr)
library(dplyr)

#サンプリング場所のデータ読み込み
merged_Metadata <- read_tsv('merged_data.tsv')
#group として 全て 1 のカラム を追加
ones <- numeric(dim(merged_Metadata)[1])
ones <- ones + 1
withOne <- cbind(merged_Metadata,new)

mp1 <- fortify(map(fill=TRUE, plot=FALSE))
mp2 <- mp1
mp2$long <- mp2$long + 360
mp2$group <- mp2$group + max(mp2$group) + 1
mp <- rbind(mp1, mp2)

ggplot(aes(x = long, y = lat, group = group), data = mp) + 
  geom_path(color="gray") + 
  scale_x_continuous(limits = c(110, 300)) + 
  geom_point(data = withOne, aes(x = LONGITUDE, y = LATITUDE, group = ones), color = "red", size = 0.01)



```

![download-2.png](https://qiita-image-store.s3.amazonaws.com/0/175646/c6b2bb61-5d36-5187-bb71-e5dd9ca2f5c9.png)

なるほど、経度に関しては-の部分を+360しないと表示されないのね。

```r
library(ggplot2)
library(mapdata)
library(readr)
library(dplyr)

#サンプリング場所のデータ読み込み
merged_Metadata <- read_tsv('merged_data.tsv')
#group として 全て 1 のカラム を追加
ones <- numeric(dim(merged_Metadata)[1])
ones <- ones + 1
withOne <- cbind(merged_Metadata,new)

LONGITUDE <- withOne[, "LONGITUDE"]
modLONGITUDE <- data.frame(modLONGITUDE = ifelse(LONGITUDE < 0, LONGITUDE + 360, LONGITUDE))

withModLongitude <- cbind(withOne, modLONGITUDE)

mp1 <- fortify(map(fill=TRUE, plot=FALSE))
mp2 <- mp1
mp2$long <- mp2$long + 360
mp2$group <- mp2$group + max(mp2$group) + 1
mp <- rbind(mp1, mp2)

ggplot(aes(x = long, y = lat, group = group), data = mp) + 
  geom_path(color="gray") + 
  scale_x_continuous(limits = c(110, 300)) + 
  geom_point(data = withModLongitude, aes(x = modLONGITUDE, y = LATITUDE, group = ones), color = "red", size = 0.01)


```


![download-3.png](https://qiita-image-store.s3.amazonaws.com/0/175646/e443ef11-1887-67d9-41b1-b0cf8ad7b353.png)

`rworldmap` とか他の世界地図描画できるパッケージも調べたけど、基本的に対応してないので似たようなトリッキーな方法でやることになりそう
Prometheusのすすめ - Grafanaでアラート発生時にジョブ実行  Python+Flaskでwebhook recieve-

Prometheusのすすめとか書いてますが、本記事はPrometheusについて一切触れていません。
Grafanaのアラート時のwebhookを受信してアラート内容に沿った処理をするwebhook recieveを作りました。

# Postされるjson内容
私の設定している環境ではGrafanaでアラート発生時にPOSTされるjsonの内容は以下になります。
※環境によってはtagsの箇所が違ったりするので、jsonの内容を見ながらpythonコードを書いた方がいいです。

```json
{
    'ruleName': 'CPU使用率アラートグラフ alert',
    'ruleUrl': 'http://XXX.XXX.XXX.XXX:XXXX/d/lCE6nYDmz/all-servers-alert?fullscreen=true&edit=true&tab=alert&panelId=4&orgId=1',
    'imageUrl': 'https://s3.ap-northeast-1.amazonaws.com/XXXXXX/69Ima6QI5KACp3NL3Grs.png', 'title': '[Alerting] CPU使用率アラートグラフ alert',
    'ruleId': 6,
    'state': 'alerting',
    'message': '【障害通知】CPU使用率',
    'evalMatches': [
        {
            'value': 96.23523011138367,
            'tags': 
                {
                    'instance': 'XXX-XXXXX-web01'
                },
            'metric': 'XXX-XXXXX-web01'
        }
    ]
}

```

# python実行環境(nginx+uwsgi)を用意する。

探せばいくらでも出てくるのでこの記事では割愛します。
[ここ](https://qiita.com/yasunori/items/64606e63b36b396cf695)が参考になります。

私の環境ではPrometheusと同じサーバに同居させていて
「http\://IPアドレス/dev」にアクセスするとpythonにwsgiプロトコル経由で実行されるように設定しています。


# コード

```python:app.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request, redirect, session , make_response
app = Flask(__name__)
import subprocess
import re


@app.route("/dev/webhook", methods = ["POST"])
def webhook():
    '''
    Grafanaのアラートからスクリプトを実行する為のWebHookRecive
    '''
    postjson = request.json
    if not request.remote_addr == '127.0.0.1':
        print("## not local request")
        return
    elif postjson['state'] == 'alerting':
        print("## state: Alerting")
        print(postjson)
        text = postjson['message']
        rulename = postjson['ruleName']
        if not postjson['evalMatches'][0]['tags'] == None:
            instance = postjson['evalMatches'][0]['tags']['instance']
            alert = re.match('ICMP',rulename)
            cmd = "sh /usr/script/grafana/"+instance+"_"+alert+".sh"
            #/usr/script/grafana/配下にインスタンス名（NameTag)_アラート名.shでスクリプトを配置する。
            #内容は再起動なり、SSHでリモートコマンドするなりのスクリプト
            subprocess.call(cmd.split())
        print(text)
    elif:
        print("## State: without Alert")
        print(postjson)
    return 'OK'

```
python: 配列の結合

pythonで配列を結合する方法

以下のように，ndarrayの場合はnp.r_[配列A, 配列B]で結合可能．
listの場合は + を用いることで結合可能．

```py
In [1]: import numpy as np

In [2]: a = np.array([1,2,3])

In [3]: b = np.array([4,5,6])

In [4]: np.r_[a, b]
Out[4]: array([1, 2, 3, 4, 5, 6])

In [5]: a = [1,2,3]

In [6]: b = [4,5,6]

In [7]: a + b
Out[7]: [1, 2, 3, 4, 5, 6]

```
Ansibleでプロキシを越えてyumを実行する

Ansibleのyumモジュールを使ってミドルのインストールを行ったとき、
プロキシ環境下での実行時に設定でハマったときのメモ

## proxy設定方法

`environment`にproxy情報を指定する（varsに切り出す必要はとくにない）
設定はplaybook全体に適用されるので、roles内に定義したtask等にも設定が反映される

```
- name: test
  hosts: localhost
  gather_facts: yes

  vars:
    proxy_env:
      http_proxy: 192.168.100.10:80
      https_proxy: 192.168.100.10:80

  tasks:
  -name: httpd install
   yum:
     name: httpd
     state: present

  environment: "{{proxy_env}}"
```