OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFront から S3 へ出力されたログを、Athena で解析してみる

# ０．はじめに

先日、こちらの記事の対応を行ったんですが、

* [SSL 化済みの WordPress サイトに CloudFront を適用してみる \- Qiita](https://qiita.com/kusokamayarou/items/21e4bcdaa7c8dd8523ab)

S3 へ出力されたログを解析するのにいい方法が無いかと調べたところ、Athena で解析するのがいいみたいなので試してみました。

基本的には、以下のページの手順に従って進めました。

* [Amazon CloudFront ログのクエリ \- Amazon Athena](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/cloudfront-logs.html)

他にこちらの記事なども参考にさせて頂きました。

* [Amazon Athena で Amazon CloudFront のアクセスログを分析する \- Qiita](https://qiita.com/aibax/items/6aa8c08e39b824cf85f2)
* [Athenaを使ってS3のログを検索できるようにしたら運用コストが改善されたお話 \- Qiita](https://qiita.com/godgarden/items/69fc31b95d63200f2f3f)

こういった方々がノウハウをシェアして頂けることは、本当にありがたいですね♪

感謝!! 🙇‍♂️

# １．S3 のログファイルのデータを Athena でテーブルを作成して入れ込む

1. Athena のコンソールを開きます。
    * [Athena](https://ap-northeast-1.console.aws.amazon.com/athena/home?force=&region=ap-northeast-1#query)
1. 以下のクエリを実行して、テーブルを作成し、S3 のログファイルのデータを入れ込みます。
    * ※参考にしたサイトに記載されているクエリそのままです。S3 バケットを変えただけ。
    * ![FireShot Capture 004 - Athena - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/7916a3eb-ebde-6d4b-eed5-e19baf406aaa.png)

```sql
CREATE EXTERNAL TABLE IF NOT EXISTS default.cloudfront_logs (
         `date` DATE,
         time STRING,
         location STRING,
         bytes BIGINT,
         requestip STRING,
         method STRING,
         host STRING,
         uri STRING,
         status INT,
         referrer STRING,
         useragent STRING,
         querystring STRING,
         cookie STRING,
         resulttype STRING,
         requestid STRING,
         hostheader STRING,
         requestprotocol STRING,
         requestbytes BIGINT,
         timetaken FLOAT,
         xforwardedfor STRING,
         sslprotocol STRING,
         sslcipher STRING,
         responseresulttype STRING,
         httpversion STRING,
         filestatus STRING,
         encryptedfields INT 
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION 's3://[S3 のバケット名]/[CloudFront の Log Prefix]/' TBLPROPERTIES ( 'skip.header.line.count'='2' )
```

# ２．作成した Athena のテーブルへ、クエリを実行して必要なデータを抽出する

1. 以下の様なクエリを実行して、テーブルから必要なデータを抽出します。
    * 以下のクエリは、
        * [日付(YYYY-MM-DD)] より後の、　※画像では、2019-03-03
        * [URL パス] へのアクセスで、　※画像では、/portal/index.html
        * [IP アドレス] からのアクセス
    * となっています。
    * ![FireShot Capture 005 - Athena - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/4a1b1d7f-de47-69b0-3c6b-cd9f8de0ec5f.png)

```sql
SELECT * FROM default.cloudfront_logs
WHERE date > date '[日付(YYYY-MM-DD)]'
AND uri = '[URL パス]'
AND requestip = '[IP アドレス]'
```

# ９９．ハマりポイント

* そこまでハマりはしませんでいたが…、
<br><br>
* クエリの WHERE 句の、DATE 条件がわからなくてちょっと困りました…。

# ＸＸ．まとめ

CloudFront の導入で、運用や管理のやり方も変わってくるので、正直不安もありますが、こういったサービスがしっかりと用意されているのが、AWS の強みかと思います。

本当は、CloudWatch Logs に出力されると嬉しい気もしますが…、データ量が多すぎるとコスト量むし、このやり方がいい落としどころなのかもしれないですね。

何かご参考になれば嬉しいです!!

では♪
【baserCMS】お問い合わせページの分岐

お問い合わせページのスラッグとして「contact」を使うことが多いと思うんですが、
お問い合わせページだけを分岐する為に、固定ページの分岐と同じように

~~~php
<?php if (strtolower($this->BcBaser->getContentsName()) === 'contact'): ?>
〜contactページだけに表示したいコンテンツ〜
<?php endif; ?>
~~~
このように書いても効きません。
フォームページを分岐したいときは

~~~php
$currentContent = $this->BcBaser->getCurrentContent(); // 現在のコンテンツ情報を取得
var_dump($currentContent);
~~~
を使ってname値、plugin値、type値を用いて分岐させた方が、
フォームのURLが変わったときにも対応できるのでおすすめです。

書き方としては

~~~php
<?php
        $currentContent = $this->BcBaser->getCurrentContent(); 
        if($currentContent['name'] === "contact"){
       echo 'contactページだけに表示したいコンテンツ';
      }; ?>
~~~
こんな感じ。
逆にcontact以外のページに表記したいときは

~~~php
<?php
        $currentContent = $this->BcBaser->getCurrentContent(); 
        if($currentContent['name'] ！== "contact"){
       echo 'contactページ以外に表示したいコンテンツ';
      }; ?>
~~~
という感じになります。

ちなみにelseifを使いたい場合は

~~~php
<?php if ($this->BcBaser->isBlogSingle()): ?>
'ブログの詳細ページで表示したいコンテンツ'
<?php elseif($this->name == 'Mail'): ?>
'contactページだけに表示したいコンテンツ'
<?php endif; ?>

~~~

という感じで「Mail」を指定します。
LaTeXで画像挿入のエラーが出たときの対処法

# はじめに
LaTexで画像挿入をした際に次のエラーメッセージが出てしまった時の対処法です。
エラーメッセージ："Cannot determine size of graphic in image (no BoundingBox)"

ただし、前提として

\usepackage[dvipdfmx]{graphicx}

は入っているものとします。

# 対処法

画像の名前に"."が入っていないことを確認してください。
僕の場合は"."を削除することでエラーが出なくなりました。
プランニング・ポーカー　アジャイル開発でコンセンサスを得る方法

#プランニング・ポーカーとは
アジャイル開発においてチームが一丸となって常に同じ目標を持ちながら開発サイクルを進めていくのはとても重要なことです。
しかし違う思考を持った人間の集まりである以上、意見の相違や目標のとらえ方の違いが出てくるのは必至です。
それを防ぐためには全員で会議をするのが一番でしょうが、全員が均等に意見を出すことはとても難しいことですし、時間がかかって決して楽しいものではありません。
その一つの解決法になりうる手段がこのプランニング・ポーカーです。

ウェブサービスでもありますし、カードそのものも売っていますし、厚紙さえあれば容易に作れます。

#ルール
- チームのメンバーはプロダクトオーナーを除いて全員、それぞれに同じ枚数同じ内容のカードを受け取ります。(考案者はフィボナッチ数列になったカードを推奨)
- 議題としてバックログからユーザーストーリーを作り出します。
- そのユーザーストーリーを具象化するにあたって自分の評価に値するカードをメンバーが一斉に出します。
- 出されたカードの数字のうち最大のものと最小のものを出した人の意見を聞きます。
- その意見を聞いたのち、再度カードを出し合い、先ほど同様突出した数字のメンバーの意見を聞きます。
- 最終的にすべてのメンバーが同じカードを出したとき、コンセンサスが得られます。

#注意
このゲームでコンセンサスを得るうえで大事な注意がいくつかあります。
1. 一度のゲームで複数のユーザーストーリーを扱うこと。
2. 明確な一つの評価基準を設けないこと。
3. 安易に結果を平均化しないこと。

1.についてはコンセンサス獲得に向けて、それぞれ特化したものがあり、違う視点を持ったメンバーたちの意見を受けながら次のストーリー、また次へと進んで行くことでより高度なコンセンサス獲得の可能性を阻害しうるからです。

2.はいくらか3.にも共通するのですが、時間なり、技術なり、資源なりその他評価の基準になりそうなものを選んで一元化してしまったり、評価が一元的にならざるを得ないほど小規模なユーザーストーリーしか用意していなければ結論ありきのゲームになりかねません。

3.このゲームにおける最大の障害でもあるのですが、一人だけ評価が違う人物へ平均化するように雰囲気で圧力をかけてしまうことです。このゲームの目的はコンセンサス獲得であって議論が白熱しないように迂回することではありません。評価が譲れない人はその理由を皆に周知するべきですし、皆はそれに耳を傾けて自らの評価の足しになるか判断しなければなりません。
 
#最後に

チームが一丸となって同じ展望を持つというのは簡単なことではありません。
プロジェクトの開始とともにメンバーはそれぞれ展望をもっているでしょうが、それは自分の能力をベースにしているでしょうし、それはつまり無意識に自分が苦手とするものや興味の薄い分野での評価に高すぎたり低すぎたりする点を与えていることでもあり、いびつなものとなっています。
コンセンサスを得るにはこれのほかにもSwimlanes Wall方式などいろいろなやり方がありますが、個人的にこのやり方は楽しくて、しっくりきました。

ウェブサービスで行う場合以外、全員で囲めるテーブルなどがいる点はホワイトボードさえあればできるSwimlanes方式のほうにも利点がありますし、スクラムマスターの好み次第ですね。
Qiita(8)週５回の確認作業の流れ

Qiitaに記事を書かない日も含めて、週に５回接続することとした。
週休２日。

接続した際の手順を想定する。

# いいね　してくださった方の確認
いいね　をしてくださった方が、どういう記事を書かれているか。

その記事が、自分の記事と関連がある場合には、参考資料で参照させていただく。

まだ記事を書いていないが、近日中に記事を書きたい事項である場合には、下書きを作成し、参考資料として記録する。

記事を何も書かれていない方の場合は、他にどんな記事にいいねを押されているか確認させていただく。自分が興味のある記事の場合には、拝見し、参考資料として記録するかどうか検討させていただく。

自分の記事については、いいねをしてくださった方の視点で、わかりにくそうな事を編集したり、興味をもたれそうな事項を追記する。

段落によって方向性が違う場合があるのは、いいねをしてくださった方の方向性の違いの数だけ、本文にも方向性の違いが存在したままになる可能性がある。

プログラムの場合でも、作り手、使い手の方向性の違いによって正解はひとつとは限らない。

ver. 1.00, ver. 2.00など大改訂(maker revision)の時に、全文を読み直し、方向性の数を３つ程度に収束するように加筆する。

# コメント・編集リクエストの確認
編集リクエストは、なぜか、しばしばエラーになる。
編集リクエストをいただく項目は、当方でも編集している確率が高く、かつ時間が前後して複数回編集していると、矛盾があるという指摘とともに、保存できない状態になる。

コメントいただいた事項のうち、本文にも追記した方がいい事項は、返信に本文に追記する旨の記載をして本文を編集する。

編集リクエストに伴うエラーの対処方法はまだ体系化できていない。


#twitter, facebook, はてなブックマーク等のコメント
Qiitaでのコメント同様、本文を編集した方がわかりやすくなるかどうかで編集する。

コメントいただいた方で知り合いの場合は、その知り合いの立場、性格から判断して、何を書き足すとわかりやすくなるかを考える。

コメントいただいた方で、知り合いでない方の場合は、その方の書き込みや、いいねを押したものから推測して書き足す。

#記事の見直し

現在、views, いいねが多い方から見直している。

Qiita記事　いいね と views の関係
https://qiita.com/kaizen_nagoya/items/d30240b2a9adec288ca9


記事集計の結果、VIEWSの数が1000件以上で、VIEWS/GOODSの値が80より小さい記事を積極的に加筆する。
その次に、いいねが10以上で、VIEWの数が1000未満で、VIEWS/GOODSの値が100より大きい記事を加筆する。

Qiita(0)Qiita関連記事一覧（自分）
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 初稿 20190304
ver. 0.02 加筆して公開 20190305 朝
ver. 0.03 いいねをいただき加筆 20190305 昼 
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
ESP8266 + DS18B20（1wire温度センサ）でAmbientにデータを送る

#温度データをネット経由で取得するために絞ったコード
気温や土の温度を計測・記録したい

####Aruduino & Wifi : ESP8266
https://www.switch-science.com/catalog/2620/
以前買って手元にあったもの
ポート出力電流上限は12mA（だったような。要確認）

####温度センサ　:　DS16B20+
<選定時要望>
・センサ部を防水にして土中温度を測りたいため、TO-92パッケージみたいな足のついたものを利用したい
・高くないこと
・省エネ
　I2Cでは適当なデバイスみつからず。値段高め、防水しにくい形状
　アナログ：ESP8266はADCが1チャンネルのみ（0から1V）
　1チャンネルのみなのでとりあえず選定から外す
　　参考：LM60（2.7V～10Vで駆動）仕様は向いているのだけど
　　　出力1V超は92℃超なので気温や土温度の際はADC閾値は気にしない
　　　25℃時電流ドレイン最大110μA　0.11mA
　　　[LM60仕様](http://www.tij.co.jp/jp/lit/ds/symlink/lm60.pdf)
　DS16B20+
　　Active current MAX 1.5mA
　　Standby current MAX 1000nA 
　　一つのポートに複数接続可
　　今回は昔秋月で買ったもの利用（購入時値札300円、2019/3/5時点320円）
　　Amazonで10個1000円以下。防水加工済みコード付きも1個200円台

DS16B20+利用のためのArduinoライブラリ（OneWire用、DS16B20+用）
https://github.com/PaulStoffregen/OneWire
https://github.com/milesburton/Arduino-Temperature-Control-Library

DS16B20+接続
DQとVdd間を4.7kΩ抵抗でつなぐ
Vddは5.0Vでも3.3Vでも


####IoT croud : Ambient
以前トラ技でみたときにアカウントを作っていた
公式に日本語サンプル解説があって助かる
https://ambidata.io/


####ソース
```C

#include <OneWire.h>  //1wire
#include <DallasTemperature.h>  //DS18B20
#include <Ambient.h>

//-----------------------------------------------
const char* ssid = "  --- wifi ssid ---  ";
const char* password = "  --- wifi password ---  ";
unsigned int channelID =   --- Ambient channel id ---  ;
const char* writeKey = "  --- Ambient writekey ---  ";
float temp01;

//-----------------------------------------------

//WiFi
WiFiClient client;

//OneWire&DS18B20
#define ONE_WIRE_BUS 2 //Portは任意。今回は2番
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//Ambient
Ambient ambient;

//-----------------------------------------------

void setup() {

  WiFi.begin(ssid, password);
  ambient.begin(channelID, writeKey, &client);

  sensors.begin();

}

//-----------------------------------------------

void loop() {
  sensors.requestTemperatures();
  temp01 = sensors.getTempCByIndex(0);

  ambient.set(1,temp01);
  ambient.send();

  delay(30000);  //30秒間隔
}

```

####次の課題<優先度>
<高>センサを複数接続
<高>ESP8266単体で書き込み、駆動
<高>スリープモード利用
<低>1wireと、アナログ・I2Cとの併用
（特に温度湿度センサはI2Cの方が選びやすそう）
ブログや技術書用にスクリーンショットを取るためのサイトを作ってみた

## あらすじ

どうも、4/14の技術書典に出典することにした@scrpgilです。
現在、技術書を鋭意執筆中です。執筆は初めてなので苦労しながら楽しくやっていますが、ひとつだけ不満があります。それは技術書に載せるWebサイトの画像を用意するのが面倒だということです。

![Screen Shot 2019-03-04 at 0.04.23.png](https://qiita-image-store.s3.amazonaws.com/0/165335/1dd92955-84b9-f71f-2a09-2560eb7c1b10.png)

上はChrome DevToolsのスクリーンショット機能を使って作った画像になります。ご覧の通り枠線がないのでなんか不恰好ですよね。

こうならないために枠線つけたりなどの方法がありますが、個人的に一番綺麗だと思うのはMacのデフォルトのbox-shadowをつけてスクショを取る方法です。

![Screen Shot 2019-03-04 at 0.06.44.png](https://qiita-image-store.s3.amazonaws.com/0/165335/d469c7b0-0804-4fcb-76d4-0cad16600a20.png)

どうですか？先ほどより綺麗じゃないですか？できれば常にこういうスクリーンショットを撮りたいと思います。

が、しかし、このスクショを取るためには白背景を用意したり不要なウィンドウを閉じたりしないといけません。これが意外と面倒です...。ああ、なんとかしたい...。

![Screen Shot 2019-03-04 at 0.03.54.png](https://qiita-image-store.s3.amazonaws.com/0/165335/863cffd2-081a-fc59-3a39-ca16ce4c9feb.png)

## スクショを取るサイトを作ろう

というわけでChromeっぽい画面でスクショを取るためだけのサイトを作ってみました。

![Screen Shot 2019-03-04 at 2.08.25.png](https://qiita-image-store.s3.amazonaws.com/0/165335/2a1ccd7c-f7d0-aa7a-62a3-43d537c72f70.png)

[DEMO](http://chrome-like-iframe.herokuapp.com/)

制作時間はHerokuへのアップロード含めて小1時間ほどだったと思います。
[ソースコードはこちら](https://github.com/scrpgil/chrome-like-iframe)


## 他のサイトを読み込む
これはiframeでいけました。

```
<iframe src="<読み込みたいサイトのURL>"></iframe>
```

## URL、縦幅＆横幅のバインド

StencilとIonicを使ってます。
ion-inputにEventListenerを貼ってます。

```
  async componentDidLoad() {
    const widthInput: any = this.el.querySelector("#width-input");
    widthInput.addEventListener("ionInput", async ev => {
      if (ev && ev.target && ev.target.value) {
        this.width = ev.target.value;
      }
    });
    const heightInput: any = this.el.querySelector("#height-input");
    heightInput.addEventListener("ionInput", async ev => {
      if (ev && ev.target && ev.target.value) {
        this.height = ev.target.value;
      }
    });
    const input: any = this.el.querySelector("#url-input");
    input.addEventListener("ionInput", async ev => {
      if (ev && ev.target && ev.target.value) {
        this.url = ev.target.value;
      }
    });
  }
```

## Chromeっぽいタブバーを作る
「CSS Chrome like」でググったら最初の方に出てきました。
https://codepen.io/jcblw/pen/DxAJF

## サイトとして公開する
今回、１番のハマりポイントでした。当初Netlifyで公開してんですが、それだとiframeでlocalhostを表示できない。
どうやら今日日MixContent対策が進んでおりhttpsのサイトからhttpのサイトはほぼ開けないようでした。
仕方なくhttpで公開しようとしたんですが、これまた今日日無料かつhttpで公開できるサービスはパッと見当たりませんでした（Firebase Hosting、Netlifyは共に強制SSL通信）。

結局、Herokuを使うことにしましたが普段Herokuを使っていなかったのでハマってしまいました。結局、以下の記事に助けられて公開をすることができました。先人の知恵に感謝...。
[ionic frameworkで作ったアプリをherokuで公開する](https://qiita.com/imaimiami/items/c4006d3c08107c445001)

## まとめ

以上、Webサイトのスクショ用のサイトを作ってみたって記事でした。思ってたより簡単にできてしまったのでもっと早く作っていればよかったかな？と思っています。
ただ、僕は今回の技術書はすでに必要な画像を撮り終えているので使わないと思います。

最後になりますが自分が欲しいと思ったサイトも1時間後に作成することができるのでIonic、Stencilは本当に良いフレームワークだと思います。
興味がある方は是非ともマスターしましょう！それでは。

[Ionic - Cross-Platform Mobile App Development](https://ionicframework.com/)
[Stencil - The magical, reusable web component compiler](https://stenciljs.com/)
golangのembeddingによる継承(っぽい操作)で今更ながら思ったこと

今更ながら、こういう仕様だったのか・・・とハマったのでメモ。

goってextendがない代わりにembeddingによる継承っぽいことができますよね。

その際の継承先structの初期化で、 `えっ！？この操作できなかったんだ・・・` と今更ながら知ったのでメモです。

## まずエラーになるパターン

```go
package main

import (
	"fmt"
)

// 基のstruct。NameとDescriptionを持っている
type Base struct {
	Name        string
	Description string
}

// 拡張？したstruct。ExtraInformationというプロパティを足した
type Extended struct {
	Base
	ExtraInformation string
}

func main() {
	ext := Extended{
		Name:             "name",
		Description:      "description",
		ExtraInformation: "extra",
	}
	fmt.Printf("Struct: %#v", ext)
}
```

これだと、 `cannot use promoted field Base.Description in struct literal of type Extended` というエラーになります。

embeddingされている方のフィールドを `promoted field` と呼ぶようですね。

## うまくいくパターン

こうしないと駄目らしい。

```go
package main

import (
	"fmt"
)

// 基のstruct。NameとDescriptionを持っている
type Base struct {
	Name        string
	Description string
}

// 拡張？したstruct。ExtraInformationというプロパティを足した
type Extended struct {
	Base
	ExtraInformation string
}

func main() {
	ext := Extended{
		Base: Base{
			Name:        "name",
			Description: "description",
		},
		ExtraInformation: "extra",
	}
	fmt.Printf("Struct: %#v", ext)
}
```

もしくはこう。struct literal なるものから脱出さえしていればどうにでもなる系。

```go
package main

import (
	"fmt"
)

type Base struct {
	Name        string
	Description string
}

type Extended struct {
	Base
	ExtraInformation string
}

func main() {
	ext := Extended{}
	ext.Name = "name"
	ext.Description = "description"
	ext.ExtraInformation = "extra"

	fmt.Printf("Struct: %#v", ext)
}
```

普通にPythonとかで書いている人にとっては意外な仕様だったのでメモしておきました。
Kotlin 1.3のCoroutineのキャンセル③（計算処理でキャンセル可能にする）

# 検証環境
この記事の内容は、以下の環境で検証しました。

* Intellij IDEA ULTIMATE 2018.2
* Kotlin 1.3.0
* Gradle Projectで作成
* GradleファイルはKotlinで記述（KotlinでDSL）

# 準備
詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa

# Making computation code cancellable
[前回](https://qiita.com/naoi/items/2149dd2cf6bf46f52521)に引き続き、[公式サイト](http://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#making-computation-code-cancellable)を読み解いていきます。

前回は、キャンセルの裏側の話をしました。
しかし、キャンセルできない処理についても話しました。今回のタイトルはそれをひっくり返すような感じがしますね。

早速読み進めます。

> There are two approaches to making computation code cancellable. The first one is to periodically invoke a suspending function that checks for cancellation. There is a yield function that is a good choice for that purpose. The other one is to explicitly check the cancellation status. Let us try the later approach.
>
>Replace while (i < 5) in the previous example with while (isActive) and rerun it.

意訳込みですが（略）

> 計算処理にキャンセル処理を実装する方法は2種類あります。1つ目は、suspend関数を定期的に呼び出し、キャンセル状態を確認する方法です。その場合は、yeil関数を呼び出すとよいでしょう。
> 2つ目の方法は、キャンセル状態を明示的ににチェックする方法です。isActiveを呼び出すことによりキャンセルされているか確認できます。
> while(i<5)をwhile(isActive)に置き換えてみました。
ElmでサクッとBuilderパターンをする

[基礎からわかる Elm](https://www.amazon.co.jp/dp/4863542224)が発売されましたね！ Elmのノウハウがかなりマニアックかつ実用的なところが丁寧に書かれていて読み進めるのが楽しいです！ 本の中にあった所謂Builerパターンが便利かつElmに慣れていない人にとっては目から鱗だろうなと思って、記事として紹介してみます。

# Javaの場合

まずはJavaのケースで考えてみます。ものすごいコアな部分だけ取り出すと、フィールドの値を書き換えてビルダー自身(this)を返しています。ポイントとしてはビルダー自身はミュータブルなアプローチで書き換えて、必要なタイミングで値(Mailer)自身を作成したり、アクション(send)したりします。

```java
public class MailBuilder {
    private String fromAddress = "";

     public MailBuilder from(String address) {
        this.fromAddress = address;
        return this;
    }
    ...
}
```

# Elmの場合

Elmの[Record](https://elm-lang.org/docs/records)を利用するアプローチはとってもシンプルで簡単です。RecordはSetter(Update構文)を持っていて変更を反映した新しいRecordを作り出して返すので、Builderを経由せず、かつ、イミュータブルなアプローチで安全に値を生成することができます。

まずは、型の定義とデフォルトのレコードを用意します。

```elm
type alias Mailer =
    { fromAddress : String
    , toAddress : String
    , subject : String
    , body : String
    }


defaultMailer : Mailer
defaultMailer =
    Mailer "" "" "" ""
```

ビルダーのメソッドに当たる部分は、変えたい値を受け取って、RecordのSetterを呼び出すだけです。

```elm

from : String -> Mailer -> Mailer
from address mailer =
    { mailer | fromAddress = address }


to : String -> Mailer -> Mailer
to address mailer =
    { mailer | toAddress = address }


subject : String -> Mailer -> Mailer
subject s mailer =
    { mailer | subject = s }


body : String -> Mailer -> Mailer
body b mailer =
    { mailer | body = b }
```

すると、[パイプライン演算子](https://package.elm-lang.org/packages/elm/core/latest/Basics#(|%3E))を利用することで、簡単にBuilderパターンをすることができます。パイプは前の関数を評価した値を次の関数の最後の引数に渡す**単なる関数**です。これはJavaバージョンで見た`return this`をより直接的に書いた方法になります。また、fromやtoなどのBuilderメソッドの引数をすべて埋めずに第一引数のStringだけ埋めています。これは、Elmの関数がデフォルトでカリー化されており、部分適用しているためです。ここでは詳しい説明は控えておきますが、普段List.mapやfilterなどで自然にやっていることだと思うので、是非マスターしてみてください。

```elm
hogeMailer : Mailer
hogeMailer =
    defaultMailer
        |> from "hoge@example.com"
        |> to "hige@example.com"
        |> subject "Greeting"
        |> body "Hello, Mr. Hoge"
```

ソースコード全体です。

```elm
type alias Mailer =
    { fromAddress : String
    , toAddrees : String
    , subject : String
    , body : String
    }


defaultMailer : Mailer
defaultMailer =
    Mailer "" "" "" ""


from : String -> Mailer -> Mailer
from address mailer =
    { mailer | fromAddress = address }


to : String -> Mailer -> Mailer
to address mailer =
    { mailer | toAddreess = address }


subject : String -> Mailer -> Mailer
subject s mailer =
    { mailer | subject = s }


body : String -> Mailer -> Mailer
body b mailer =
    { mailer | body = b }


hogeMailer : Mailer
hogeMailer =
    defaultMailer
        |> from "hoge@example.com"
        |> to "hige@example.com"
        |> subject "Greeting"
        |> body "Hello, Mr. Hoge"
```
Twilioで開発を始める前に知っておくこと（ユーザー管理編）

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

みなさん、こんにちは。
Twilioエバンジェリストの高橋です。

今回は、これからTwilioを使う方（使い始めている方にも）に知っておいてほしい、チームでの開発手順などについて説明します。

事前にこちらの記事をお読みいただけると助かります。
- [Twilioで開発を始める前に知っておくこと（アカウント編）](https://qiita.com/mobilebiz/items/29f0e0faba0721f8a01e)

# プロジェクトのオーナー

先の記事にも書いてありますが、Twilioでアカウントを作成するとプロジェクトがひも付きます。このように自分自身で作成したプロジェクトは、自分が**オーナー**になります。
オーナーは、そのプロジェクトに対してすべての権限を保有しています。すなわち、課金に関する権限も、電話番号を購入・設定したり、削除することもできます。

Twilioをチームで開発するときに、メンバー全員でアカウント情報を共有して作業している姿を見かけます。これは以下の理由から避けてください。

- ログイン情報（メールアドレス、パスワード）を共有しなくてはならない。
- ログイン時の二要素認証が設定できない（誰かの端末がないとログインできなくなる）。
- メンバーが抜けたときにパスワードを変更する必要がでてくる。
- 全員がオーナー権限を持つため、間違った操作や不正な操作をされてしまうリスクがある。

ではどうすればよいのでしょうか。

# ユーザーのロール

プロジェクトのオーナーは、自分のプロジェクトに他のユーザーを招待することができます。
ここでいうユーザーというのは、Twilioのアカウントを保有している人を指します。ただし、招待されるユーザーはトライアルアカウントでも構いません。
ユーザーを招待するときに、以下の**ロール**を設定することができます。

- 管理者
- 開発者
- 経理

それぞれのロールでできることは以下のとおりです。

<img width="622" alt="スクリーンショット 2018-01-19 11.04.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/a9067149-054f-dfec-cd93-6197d03c7a5a.png">

また、それぞれのロールに応じてプロジェクトに関するメール通知が異なります。

<img width="600" alt="スクリーンショット 2018-01-19 11.06.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/cb1d699f-b93b-5e60-f9ea-95162d5c53c3.png">

この中で注意が必要なのが、**開発者はアカウントの設定権限を持たない**ことです。すなわち、開発者はサブアカウントを作成することができません。そのため、サブアカウントだけはオーナー、もしくは管理者の権限を持っているユーザーに依頼をしてください。
また、開発者ロールを持ったユーザーは、プロジェクトやその中に含まれるすべてのサブアカウントに関しても権限を保有します。特定のサブアカウントだけにアクセスできるような権限はありませんのでこちらも注意が必要です。

# ユーザーの招待方法

具体的な招待の方法は以下のとおりです。

- 管理コンソールにログインします。
- Dashboard（家のアイコン） > 設定 > ユーザー管理を選択します。
- 最初はオーナーのみがリストされていますので、赤いプラスアイコンを押します。
- **新しいユーザを追加**ダイアログが開くので、招待したい人のメールアドレスとロールを選択します。
![スクリーンショット 2019-03-05 09.25.24.png](https://qiita-image-store.s3.amazonaws.com/0/86046/a18120d3-e0ff-0bf8-305b-a4299f22c70b.png)


- **招待メールを送信**ボタンを押します。

先程も書きましたが、招待される側はトライアルアカウントでも構いません。その場合、トライアルアカウント自体で定期課金が発生してしまうと（例えば電話番号の購入）、やがてトライアルアカウントのポイントが0以下になってしまい、アカウントがサスペンド状態になりますので注意してください。

# 具体的な利用イメージ

- チームのPMがオーナーとなり、開発メンバーには開発者のロールを割り当てることでチーム開発を効率よく実施できます。
- システム開発を外注（もしくは受託）する場合に、依頼者がオーナーになり、ベンダーを開発者として招待することで、課金は依頼者、ベンダーには必要最低限の機能だけを提供することができます。
- 経理担当者が経理のロールで参加することで、間違った操作でシステムを壊してしまうリスクをヘッジすることができます。一方で、経理担当者は課金に関する操作やそのログを見ることができます。

# まとめ

- ユーザー一人に対して、アカウントは一つという使い方をしましょう。
- ユーザーを招待することで、複数人で開発したり、作業分担が可能です。
- 招待時にロールを設定することができます。
- ユーザーは、自身のログイン情報をセキュアに管理できます（二要素認証などを推奨しています）。
- 招待されるユーザーはトライアルアカウントでもかまいません。

---
### Twilio（トゥイリオ）とは

https://twilio.kddi-web.com
Twilioは音声通話、メッセージング（SMS/チャット）、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウドAPIサービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。
いまさらながら、Python3.7をCentOS/RHEL 7に導入する。

## 事前準備
下記コマンドを実行して、各パッケージを導入する

```bash
yum install gcc openssl-devel bzip2-devel libffi-devel
```
libffi-develは、7.3.1以降でインストール時に必要なパッケージ
 
## インストールするソースコード
Pythonの公式から拾ってくる。
Python.org：https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tgz
 
## ソースコードを展開
ここでは、次の場所に展開します。
ソースコード：/usr/local/src/Python-3.7.x
インストール先：/usr/local/Python3.7/default
※今後バージョンを変更することを考えてシンボリックリンク経由でインストールする
保存先：/usr/local/Python-3.7.1
 
## 展開～インストールまで
ファイルを解凍し回答先へ移動

```bash
mkdir /usr/local/src/Python-3.7.1
tar xzf Python-3.7.1.tgz -C /usr/local/src/Python-3.7.1
cd /usr/local/src/Python-3.7.1
```

バージョン変更を容易にするためのシンボリックファイル作成

```bash
mkdir /usr/local/Python3.7/Python-3.7.2rc1
ln -s /usr/local/Python3.7/Python-3.7.2rc1 /usr/local/Python3.7/latest
ln -s /usr/local/Python3.7/latest /usr/local/Python3.7/default
```

インストール

```bash:command
cd /usr/local/src/Python-3.7.1
./configure --enable-optimizations --prefix=/usr/local/Python3.7/default
make -j4
make altinstall
```

※ make の-jオプションはコンパイル時のCPUの数を指定できる、複数あるなら複数個指定、無いなら-jを付与しないで実行

# pipを使えるようにする
Pythonのモジュールを管理するツールにpipがあり、ほぼ必須といえる。3.4系以降のpythonを導入した場合は、pipが自動でインストールされるが、今回の方法だとパスが通らないので、次の手順を実施する。

```
echo "export PATH="/usr/local/Python3.7/default/bin:$PATH"" >> /etc/profile
ln -s /usr/local/Python3.7/default/bin/pip3.7 /usr/local/Python3.7/default/bin/pip
```

以下のコマンドを実行して、バージョンが出力されるか確認する

```
# pip -V
pip 10.0.1 from /usr/local/Python/lib/python3.7/site-packages/pip (python 3.7)
```

pythonのバージョンを確認する。

```
# su -
# python --version
Python 3.7.1
```

- Python 2.7.x と表示された場合
その環境には、別なpythonが導入されているため、そっちにパスが通っています。
ので、python3用のパスを通します。下記コマンドを実行してください。

```
ln -s /usr/local/Python3.7/default/bin/python3.7 /usr/local/Python3.7/default/bin/python
ln -s /usr/local/Python3.7/default/bin/python /usr/local/bin/python
ln -s /usr/local/Python3.7/default/bin/python /usr/local/bin/python3
```

- 使用可能なモジュールを確認しつつ、インストールが出来たか確認
下記を記述して実行する。

```
# cat help_modules.py
# -*- coding: utf-8 -*-
# prints a list of existing modules
print(help('modules'))
```

実行する。現在使用可能なモジュール一覧がでてくればインストール成功

```
# python help_modules.py

Please wait a moment while I gather a list of all available modules...
/usr/lib64/python2.7/site-packages/gobject/constants.py:24: Warning: g_boxed_type_register_static: assertion 'g_type_from_name (name) == 0' failed
  import gobject._gobject
BaseHTTPServer      cProfile            inspect             rpmUtils
Bastion             cStringIO           io                  runpy
CDROM               calendar            ipaddress           sched
CGIHTTPServer       cgi                 itertools           schedutils
ConfigParser        cgitb               json                select
Cookie              chunk               keyword             selinux
DLFCN               cmath               lib2to3             sets
DocXMLRPCServer     cmd                 liblzma             setuptools
：(以下略)
```
springで@Import対象は@Configuration扱いになる

springで```@Import```されるjava configクラスを作成していた。このとき、その設定クラスは```@Configuration```を付けなくても```@Import```すればクラス内の```@Bean```が登録されるのが、なんか不思議だったのでその辺を勉強するべくソースコードを見てみた。

```xml:pom.xml
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.3.RELEASE</version>
	</parent>
```

ソースを追ってみると、ApplicationContextの細かいところは省くが、```@Import```の処理をしているのはこの辺らしい。以下のメソッドではimport候補クラスのコレクションを渡されて、それを一つずつ処理している。

```java:ConfigurationClassParser
package org.springframework.context.annotation;

class ConfigurationClassParser {
	private void processImports(/*...(略)...*/, Collection<SourceClass> importCandidates, /*...(略)...*/) {
				// ...(略)
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// ...(略)
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// ...(略)
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass));

```

このとき、条件付きimportをする```@ImportSelector```と```@ImportBeanDefinitionRegistrar```が付与されていれば、それ専用の処理が行われる。しかし、それらアノテーションではない場合、コード内のコメントにあるように「import候補クラスがImportSelectorないしImportBeanDefinitionRegistrarでは無い場合は```@Configuration```扱いで処理する」となる。

なので、```@Import```対象クラスは```@Configuration```と見なされる、と考えても基本的には良さそうである。もちろん細かくは色々違いはあるだろうけど。
CloudFront を適用後、Windows アプリの Inline Frame (iFrame) でアクセス出来なくなった。。。

# ０．はじめに

先日、こちらの記事の対応を行ったんですが、

* [SSL 化済みの WordPress サイトに CloudFront を適用してみる \- Qiita](https://qiita.com/kusokamayarou/items/21e4bcdaa7c8dd8523ab)

ちょっとしたトラブルが発生したので、シェア♪

# ９９．ハマりポイント

* ある Windows アプリで該当サイトのページを　Inline Frame で表示していたんですが、CloudFront 適用後にページへのアクセスが出来なくなってしまいました。
* 結構わからなくて色々調べたところ、アプリが TLS1.0 でアクセスしていた為に CloudFront で弾いていたので、以下の設定をしてアクセスできる様になりました。
    * Security Policy : TLSv1_2016
    * ![FireShot Capture 003 - AWS CloudFront Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/7c5c6a6d-2e48-557c-597a-9f0cf1ff45fd.png)
* ただ、先々 TLS1.0 や 1.1 を廃止して、TLS1.2 以上にしよう、という流れがあるみたいなので、アプリ側の対応を行い、CloudFront の再設定を行った方がいいみたいですね。
    * [マイクロソフト、ブラウザーのTLS 1\.0 / 1\.1サポート終了へ。TLS 1\.2以降への移行を推奨 \- Engadget 日本版](https://japanese.engadget.com/2018/10/16/tls-1-0-1-1-tls-1-2/)
    * [大手4社のWebブラウザ、2020年にTLS 1\.0と1\.1を無効化 \- ITmedia エンタープライズ](https://www.itmedia.co.jp/enterprise/articles/1810/16/news077.html)
    * [「Chrome」「Edge」「IE」「Firefox」「Safari」で TLS 1\.0と1\.1を2020年に無効化 \- ZDNet Japan](https://japan.zdnet.com/article/35127062/)

# ＸＸ．まとめ

今回は結構ハマって大変でした…。

新しいことをすると何かと問題が発生するには、世の常…。

少しでもご参考になれば幸いです!!

では♪
【Git】トピックブランチからトピックブランチ

# はじめに

実装工程が過渡期に入っているプロジェクトがあり、
プルリクのマージが追い付かないらしいです。

そこで、トピックブランチからトピックブランチ(featureブランチからfeatureブランチ)って作っていいのかな？って相談されたのですが、
「やめた方がよい」と回答しました。

developにマージするときに競合が発生すると思ったから。

でも、手軽に実験できる環境があったので試しにやってみました。


# やること

1. developブランチからトピックブランチ(feature/AAA)を作成する。
1. トピックブランチ(feature/AAA)からトピックブランチ(feature/BBB)を作成する。
1. トピックブランチ(feature/AAA)からdevelopブランチにプルリク投げてマージする。
1. トピックブランチ(feature/BBB)からdevelopブランチにプルリク投げてマージする。

# 予想

競合が発生して「4.」 のプルリクが投げれない。

# 結果

普通にプルリク投げれてマージも出来た。

gitすごい。

feature/BBB 作った後に feature/AAA をいじいじした場合は、
feature/AAA から feature/BBB にプルした方がいいとは思う。（試してはいません）

以上
1日目  LinuxとShellscriptとPermission

**Qiita投稿は初で、殆ど自分用なので長文駄文は無視して戴きたい。**

#Linux

###メイン課題
1. ディレクトリ1を作成
2. ディレクトリ1の中にファイル1を作成
3. ディレクトリ2を作成
4. ディレクトリ2の中にディレクトリ3を作成
5. ディレクトリ1をディレクトリ3の中に移動

なお、ディレクトリ1/2/3をdir1/2/3、ファイル1をfile1とした。
最終的に簡潔になったコード。

```:code
mkdir dir1
touch dir1/file1
mkdir -p dir2/dir3
mv dir1 dir2/dir3
```
###コマンドのオプションが分からなくなった時

```
man コマンド名
```

###今回使用したオプション付きコマンド
```:terminal
mkdir -p
 # -p, --parents　no error if existing, make parent directories as needed

mv-O1-O2
 # O2が同ディレクトリ内に存在しないとき：リネーム
 # O2が同ディレクトリ内に存在するとき：移動

rm -r
 # -r, -R, --recursive
              remove directories and their contents recursively
 # recursive：再帰的：ディレクトリ内のものに一つ一つに対し処理

ls -la
 # manコマンドで調べると-la自体は無いが、-lと-aオプションが存在する。
 # -a, --all do not ignore entries starting with
 # すべてのファイルやディレクトリを表示する。
 #この時、隠しフォルダや。から始まるディレクトリも表示される。

 # -l  use a long listing format
 # ファイルの詳細を表示する。
```

# シェルスクリプト
OSのシェルまたはコマンドラインインタプリタ向けに書かれたスクリプト言語。拡張子は『.sh』。

```:terminal
#シェルスクリプト作成(例
touch test.sh

#シェルスクリプト内編集(先の課題のコードを記述してみる。
#!/bin/sh

mkdir dir1
touch dir1/file1
mkdir -p dir2/dir3
mv dir1 dir2/dir3
```
1行目は『シバン』と呼ばれ、UNIXのスクリプトの #! から始まる1行目を指す。起動してスクリプトを読み込むインタプリタを指定する。
インタプリタ（interpreter）とは、プログラミング言語で書かれたソースコードないし中間表現を逐次解釈しながら実行（英語版）するプログラムのこと。(※よくわからなかったので、あとで調べる）

このtest.shを活用することで、先の課題を自動的に行うことができる。

```:terminal
#起動方法
./test.sh
```

#Permission
###まず、先のtest.shに対する権限を確認。

```
#コマンド
ls -la test.sh
#表示結果
-rw-rw-r-- 1 vagrant vagrant 0 Mar  4 23:48 test.sh
#左のチャンクから、user:所有者、usergroup:vagrant、others:誰でも、を意味する。
#また、r＝read権限、w=write権限、ここでは見えないがx=execute権限(実行許可）を指す。
```

###権限編集方法
chmod=change mode

```
# すべてのユーザーに実行権限を与える／禁止する。
chmod +x test.sh　/ chmod -x test.sh
#グループに書き込み権限をその他のユーザーには実行権限を禁止する。
chmod g+w,o-x test.sh
```
###別の表示方法(数字）

```
# r、w、xにそれぞれ4，2，1を割り当て、表すことができる。
rw-r--r--    =>  644
r-xr--r--    =>  544
#数字表示での権限編集

#すべてのユーザーに書き込み権限と読込権限を与える。
chmod 666 test.sh
```
###P.S.  PermissionとPermitの違い（※プログラムはPermission
どちらも名詞で『許可』を意味するが、ニュアンスが違う。
日本語で説明するとズレるので、英英辞典で確認したい。
あと、Permissionのスペル注意。
2019/3/1発表のEgretEngineはどこからダウンロード？

# 公式コミュニティー内
https://bbs.egret.com/thread-54185-1-1.html

> Q: Egret Proどうなってんの？ 
> Best Answer:
> 2019/3/6の予定です

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/5d82526f-0207-02bc-17db-c6b15395ed6d.png)

つい1週間前に3/1言ってたのになんやねんそれw
"何回閉じても無駄ですよ〜"と無限にアラートを出す10の方法

<font color="OrangeRed">掲示板に書き込むと補導または書類送検されるので気をつけてください</font>

# while
これは定番ですね。

```javascript
while(1) alert('何回閉じても無駄ですよ〜')
```

# for
```javascript
for(;;) alert('何回閉じても無駄ですよ〜')
```

# setInterval
```javascript
setInterval(() => alert('何回閉じても無駄ですよ〜'))
```

alertだけでよければ、以下でも実行できます。

```javascript
setInterval(alert)
```

# setTimeout
```javascript
function f() {
  alert('何回閉じても無駄ですよ〜')
  setTimeout(f)
}
setTimeout(f)
```

# setImmediate
```javascript
function f() {
  alert('何回閉じても無駄ですよ〜')
  setImmediate(f)
}
setImmediate(f)
```

# queueMicrotask
```javascript
function f() {
  alert('何回閉じても無駄ですよ〜')
  queueMicrotask(f)
}
queueMicrotask(f)
```

# requestAnimationFrame
```javascript
function f() {
  alert('何回閉じても無駄ですよ〜')
  requestAnimationFrame(f)
}
requestAnimationFrame(f)
```

# requestIdleCallback
```javascript
function callback() {
  alert('何回閉じても無駄ですよ〜')
  requestIdleCallback(callback)
}
requestIdleCallback(callback)
```

# 再帰関数(Recursive function)
```javascript
function f() {
  alert('何回閉じても無駄ですよ〜')
  f()
}
f()
```

### toString
```javascript
({ toString(){ alert('何回閉じても無駄ですよ〜')+this }})+''
```

### getter
```javascript
({
  get m() { return alert('何回閉じても無駄ですよ〜')||this.m }
}).m
```

### setter
```javascript
({
  set m(msg) { this.m = alert(msg)||msg }
}).m = '何回閉じても無駄ですよ〜'
```

# 内部DSL(Internal Domain Specific Language)
```javascript
import('./何回閉じても無駄ですよ.js')
  .then(({何回閉じても無駄ですよ}) => 何回閉じても無駄ですよ())
```
<p class="codepen" data-height="331" data-theme-id="0" data-default-tab="js,result" data-user="04" data-slug-hash="KEgyPB" data-preview="true" style="height: 331px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="何回閉じても無駄ですよ〜">
  <span>See the Pen <a href="https://codepen.io/04/pen/KEgyPB/">
  何回閉じても無駄ですよ〜</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# イテレータ
```javascript
var iterable = {
  [Symbol.iterator]() {
    return {
      next() {
        return { done: false }
      }
    }
  }
}
for(var value of iterable) alert('何回閉じても無駄ですよ〜')
```

### 配列
```javascript
const a = [0]
for (const v of a) a.push(alert('何回閉じても無駄ですよ〜'))
```

おや、誰か来たようだ...
情報処理安全確保支援士 平成27年度春 午後1問2

下記の問題集を参考させていただいでおります。
[午後(I・II)に集中！情報処理安全確保支援士精選17問](https://www.amazon.co.jp/%E5%8D%88%E5%BE%8C-I%E3%83%BBII-%E3%81%AB%E9%9B%86%E4%B8%AD%EF%BC%81%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB%E7%B2%BE%E9%81%B817%E5%95%8F-%E6%9E%97%E7%A7%80%E6%A8%B9-ebook/dp/B07B7LHCVN/ref=sr_1_21?s=books&ie=UTF8&qid=1551168594&sr=1-21&keywords=%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB)

#設問1
**(1) FWのログで当該通信の記録を確認する**
何を確認してC&Cサーバとの通信が確かに発生していたのか確認する問題です。
ここが解答できれば設問1(2)のaも導き出せます。設問1(2)のaの答えは**FW**です。
通信の制御を行っているのはFWです。FWで通信の履歴を確認すれば実際に通信が行われていたかどうか確認できそうです。
私は「取得したログをすべてログ管理サーバへ送信する」と記載があったため「FWの通信記録をログ管理サーバで確認する」的な答えが正解かなと思ったのですが、図3の文章を見ると「(a:FW)のログから」とあるためFWのログを確認している様です。
また、他サイトの見てみるとログ管理サーバには大量のログが保存されているため直接FWのログを確認した方が効率的だという解説もありました。

**(2) a：FW**
aは設問1でも出てきましたが、NAPTを利用しているためインターネット側のポートはグローバルIPアドレスと何かしらのポート番号が設定されています。L社からインターネット向けに通信をする際の送信元はこのポートになります。

**b：プロキシサーバ**
表2FWのフィルタリングルールを確認すると、インターネット向け(HTTP)通信を許可されているのは項番4のプロキシサーバのみです。

**c：MACアドレス**
DHCPサーバのログから該当IPアドレスからC&Cサーバに通信を行っていたPCの特定を行えます。
DHCPのログにはIPアドレスを割り振ったPCの**MACアドレス**が紐づいて残っています。

#設問2
**(1) DNSによる名前解決ができず、TCP/IP接続要求が出ないから**
マルウェアはプロキシサーバを経由せずFQDNを利用し、C&Cサーバへの接続を試みます。
ということは、プロキシサーバへのHTTP要求が行われず、外部DNSサーバへの問い合わせを行わないということです。
外部DNSによる名前解決ができないのであれば、後行えるのは内部DNSサーバでの名前解決要求です。
しかし、内部DNSサーバはL社ネットワーク上の名前解決しか行いません。
そのためC&CサーバのIPアドレスがわからず、そもそもFWに通信要求が行きません。

**(2) プロキシサーバでC&Cサーバへの通信のURLをブラックリストに登録する。**
初期対応でFWによる当該C&Cサーバへの通信遮断を行っています。
しかしM部長はC&Cサーバへの通信を完全に遮断できない可能性があると考えます。
おそらくこれはIPアドレスを変換すれば再度攻撃が行われたとき同様にC&Cサーバへの通信が可能になるからだと思います。
ここで表1の主なサーバとその概要にあるプロキシサーバを確認すると、ブラックリスト型のURLフィルタリング機能を持っていることがわかります。これを使ってC&CサーバのURLを登録すれば通信を遮断できそうです。

#設問3
**(1) ファイル配信サーバからマルウェアを拡散する攻撃**
ファイルサーバはパッチの自動配信を行っているため、マルウェアに感染したファイル等がL社内に拡散される可能性があります。

**(2) Vさんの利用者IDの無効化**
3台のサーバは業務上停止できないサーバです。そのためすぐに行える対策としては今回感染していたVさんの利用者IDを無効化すれば対策として成り立ちそうです。
パッチを適用するのもアリかと考えましたが、WinUpdateとかは再起動が走るためNGですね。

**(3) ログ管理サーバに保存されているログとの比較**
各サーバでも直近3ヶ月のログは保存されていますが改ざんされている可能性もあります。
問題文を見るとログ管理サーバでも直近3ヶ月のログは保存されており、ポートもsyslog保存のポート以外閉じられているためリモートでのアクセスもできません。
このため、ログ管理サーバとのログを比較すれば改ざんされているかどうか確認できそうです。

**考え方**
設問3(2)はVさんの利用者IDの無効化でしたが、他にも方法はあるのでしょうか?
情報処理試験的にはこう言った回答方法を覚えておいた方が良い?
わかるかた教えていただけると幸いです。
Linuxのddコマンドで特定サイズのファイルを作る方法

# 実行方法
bsで指定した値とcountで指定した値を掛け合わせたサイズのファイルを作成する。

```
# dd if=<file> of=<file> bs=<block_size> count=<block_count>
```

# オプション説明
- if：inputのファイルを指定する。`/dev/zero` (よく使われる)を指定した場合はNULL文字を出力しつづける特殊なファイルを指定することになる。
- of：outputのファイル名を指定する。カレントディレクトリにファイルを生成する。
- bs：ブロックサイズを指定する。単位はk(キロ)、M(メガ)、G(ギガ)でも指定可。
- count：ブロック数を指定する。

# （ちなみに）ddコマンドで作ったファイルの中身の実体
lessコマンドで覗いてみたらバイナリ？データでした。
【不思議生活①】2019 / 01 / 08 から、ありとあらゆるものをGitHubで管理する生活の始まり

- 世に溢れる素晴らしきサービスやツールを、信念を持って、開発者の意図とは異なる使用を続ける生活を記述する記事第一弾。
- 「私って変わってるかな。普通だと思うけど」という、世間では距離を置かれる凡人思考を、きらびやかに発揮させる、凡人の熟練者。
- 今日は、2019 / 01 / 08から、生活が一変したことを書こう。

## 2019 / 01 / 08について
- GitHubの大英断の日。
- 内容として、「`プライベートリポジトリ作成が無制限に行えるようになった。`」
- 従来は、「プライベートリポジトリは一つしか作成できなかった」
- つまり、開発者のみならず、Gitで様々な文書を管理したい人達にとって、地殻変動の日。

## 結論
- **GitHub上で、大中小の大量の個人開発プロジェクトを、大量管理。**
- **「読書感想・献立レシピ・家計簿・推しアイドル分析・日記」等の、全ての日常生活書類を、GitHubで管理。**
- **自分の好きなようにページを改造。**

## 経緯
- 「作成プロジェクトを公開できるGitHubは、転職用としても管理用としてもやはりいいな。」
- 「でも非公開にしたい、稚拙と秘匿を兼ね備えた作成物もたくさんあるけど、非公開版は無料だと、1つしか作成できないしな。」
- 「しかも、Gitの理解もまだ到底及んでいないから、勉強がてらどんどん作成していきたいな。」
- こうした時、突如下記のニュースが降ってきて、初めて「神の存在を盲信する宗教」への参加を本気で考える。
    - [GitHub、無料ユーザーも無制限プライベートリポジトリを利用可能に](https://it.impressbm.co.jp/articles/-/17252)
- 「でも、実は機能制限があったりするのではないか。」
- こうした偏向思考のおかげで、素晴らしきGitHubを疑ってしまう。
- しかし、読んでみると全く同様に無制限で、きちんと非公開リポジトリが作成し放題らしい。
- これが「日常のGitHub管理生活」につながる。

## 実践
### **GitHub上で、大中小の大量の個人開発プロジェクトを、大量管理。**
- 趣味で個人開発をしている私にとって、個人基準の段階が3つある。
    - 大 : フレームワークやデータベースを用いた、本格的Webアプリ
    - 中 : 趣味で行っているBOT作成やスクレイピング。
    - 小 : 新言語や技術の学習メモや、サンプルアプリ
- それらの公開するまでにはいかないプロジェクト達を、全てprivateリポジトリとして、GitHubに集約。
- それぞれの課題(Issue)や進捗状況(Push)が把握できるように、しっかりと記述。

### **「読書感想・献立レシピ・家計簿・推しアイドル分析・日記」等の、全ての日常生活書類を、GitHubで管理。**
- 下記の理由で、技術関連以外で作成したものも、非公開リポジトリで管理したいと思う。
    - 「読書の内容や感想に関して、著作権の絡みなしに、綺麗に整理したいため。」
    - 「家計簿やレシピ管理を、アプリ作成やツール使用をせず、履歴も日時も自動的に管理したいため。」
    - 「好きなアイドルに関しての考察やテレビ番組出演時の感想などをまとめた書類を管理して、より良いオタク生活を満喫したいため。」
    - 「毎日の日記作成において、Qiitaへの執筆力向上と人生懐古を図りたいため。」

- そこで、それぞれ各Privateリポジトリを作成。
- 下記、例。
    - 読書管理 : book-management
    - アイドル管理 : idol-managemnt
    - 日記 : MyDiary



### **自分の好きなようにページをカスタマイズ。**
- 業務でGitを使用している私にとって、下記の点がどうしても気になる。
    - 「きちんと整理されたコミットメッセージ・履歴が、逆にかたい」
    - 「Git練習のために、どんどん様々なコマンドをうちたいのに、チャットと連携しているため、むやみにできない。」
    - 「README(手順書)の視覚性や分かりやすさ向上のため、ほんの少しおふざけをしたい。」

- そこで、これらの個人的わがままの理由を達成するため、privateリポジトリを活用し、自分好みに改造。
- 使用ツール・参考サイトは下記。
**※実際の改造ページは、稀に見る羞恥心を持っているため、お伏せ。**
    - [Shields.io](https://shields.io/)
    - [My Octocat](https://myoctocat.com/)
    - [Emojiで楽しく綺麗なコミットを手に入れよう](https://gist.github.com/nownabe/85d8595fd142adc426fbfaf2bab015e0)

## 結果
- **個人開発や学習の質が向上した。**
    - 学習メモも含めた、大中小の作成物を管理対象にしているため、「課題管理」「学習記録」が大幅にはかどる。
    - また、分かりやすいIssue(課題)や変更メッセージの作成を心がけるようになる。
- **Gitの知識や理解力が更に向上した。**
    - 「学習用リポジトリ」を作成して、そこでありとあらゆるGitコマンドをうちまくった。
    - そのことにより、更なる知識や理解力の向上に役立つ。

- **高質的な生活になった。**
    - 日常や趣味等の全ての生活を文書化（メモ）して、管理することで、「読書の仕方」「アイドル分析の質」「毎日の献立のアイデア」の質がどんどん高くなっていった。
    - 技術者でありながら、「効率的な生活」が私には腑に落ちなかったぶん、「`高質的な生活`」を手に入れることができた。

- **高揚気分で、開発や文書作成に臨めるよになった。**
    - 「ページ」「コミット履歴」「README(手順書)」等を自分好みにカスタマイズしたため、常に楽しく作業に臨める。
    - 飽きても、その都度変更すれば良いので、常に「学習始めたての高揚気分」で取り組める。

## まとめ
- 今回は、不思議生活ということで、「現代において更に加速する管理社会に耐性をつけるため」という壮大な目的は微塵もなく、「気取り屋・実験」という単純明快な目的を掲げながら、記事を書く。
- 「この非公開フォルダが公開されたら、人生が幕を閉じる」という、天文学をはるかに凌ぐ割合で有り得ない思考を、幸せそうに思考中。
- この生活で、「高質的・バージョン管理学習・資料作成術」が同時に学べることができていることに、感謝しながら今日も[材料探し](https://qiita.com/t_o_d/items/8a75e9c65484a00e5bda)にいくとしよう。

## 参考
- https://techacademy.jp/magazine/6235  
→GitHubのアカウント登録手順からリポジトリ作成手順です。
[OR-Tools] Cryptarithmetic Puzzles using CP-SAT Solver

OR-Toolsは便利？
検証中．
ものによって言語別サンプルが無いので，補間．

```python

''' OR-Toolsのサイトには，CP-SAT SolverでのCryptarithmetricが無かったので自作'''
#     S E N D
# + ) M O R E
# -----------
#   M O N E Y 
# 
# ANSWER:FISIBLE (最適かは不明) 
#     9 5 6 7
# + ) 1 0 8 5
# -----------
#   1 0 6 5 2 
# 


# 魔法のコトバ
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from ortools.sat.python import cp_model

def SendMoreMoney():
    # 問題モデルの宣言
    model = cp_model.CpModel()

    # 変数の宣言
    limit = 9
    s = model.NewIntVar(1, limit, 'S')
    e = model.NewIntVar(0, limit, 'E')
    n = model.NewIntVar(0, limit, 'N')
    d = model.NewIntVar(0, limit, 'D')
    m = model.NewIntVar(1, limit, 'M')
    o = model.NewIntVar(0, limit, 'O')
    r = model.NewIntVar(0, limit, 'R')
    # e
    # m
    # o    
    # n
    # e
    y = model.NewIntVar(0, limit, 'Y')

    # 全ての英語に割り当たる数字が異なるという制約を造るために変数のグループを作る
    letters = [s, e, n, d, m, o, r, y]

    # 各位を表すのに必要
    kBase = 10

    # Verify that we have enough digits
    assert kBase >= len(letters)

    # ソルバに全ての数字が異なるという制約を追加
    model.AddAllDifferent(letters)

    # 足し算の制約を追加
    # SEND + MORE = MONEY
    model.Add(s * kBase * kBase * kBase + e * kBase * kBase + n * kBase + d 
            + m * kBase * kBase * kBase + o * kBase * kBase + r * kBase + e
            == m * kBase * kBase * kBase * kBase + o * kBase * kBase * kBase + n * kBase * kBase + e * kBase + y)
    
    # Solverの宣言
    solver = cp_model.CpSolver()

    status = solver.Solve(model)

    print(solver.StatusName(status))
    print('s = %i' % solver.Value(s))
    print('e = %i' % solver.Value(e))
    print('n = %i' % solver.Value(n))
    print('d = %i' % solver.Value(d))
    print('m = %i' % solver.Value(m))
    print('o = %i' % solver.Value(o))
    print('r = %i' % solver.Value(r))
    print('y = %i' % solver.Value(y))

SendMoreMoney()
```
SimpleDateFormatでフォーマットする際のタイムゾーンの扱いでつまった

JmeterでAPIからのResponseを処理するときに詰まったのでメモ。

```
Fri Apr 4 00:00:00 UTC+0900 1902
```

このような日付の文字列をDateにフォーマットするには

```Java
new SimpleDateFormat("EEE MMM dd HH:mm:ss zZ yyyy", Locale.ENGLISH);
```

これです。

[公式のSimpleDateFormatのドキュメント](https://docs.oracle.com/javase/jp/8/docs/api/java/text/SimpleDateFormat.html)には、



>|  z |  タイムゾーン | 一般的なタイムゾーン  | Pacific Standard Time; PST; GMT-08:00  |
>|:-:|:-:|:-:|:-:|
>|  Z| タイムゾーン  | 	RFC 822タイムゾーン  | -0800 |

と書いていましたが、組み合わせが思いつかずでした。
全体のコードは下記になります。


```Java
import java.text.SimpleDateFormat;

String date = "Fri Apr 4 00:00:00 UTC+0900 1902";

// Original format to convert from
SimpleDateFormat formatFrom = new SimpleDateFormat("EEE MMM dd HH:mm:ss zZ yyyy", Locale.ENGLISH);

// Target format to convert to
SimpleDateFormat formatTo = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss zZ", Locale.ENGLISH);

// Parse original string, using original format
Date formatDate = formatFrom.parse(date);

// Convert to a target format
String newDate = formatTo.format(formatDate);

System.out.println(newDate);
```

参考:
https://stackoverflow.com/questions/47165086/how-to-convert-datetime-in-jmeter-using-beanshell-sampler
PythonとRの制御構造(for)

#####RとPythonの制御構造（for)
　いろいろなスクリプトを書いているとこの処理系はどういう制御構造だったかな？と迷うことがあります。まずはforループについて記述してみました。
　Python等のループは機能豊富で描ききれていないところも多くあります。今後少しづつ書き込んでいきたいと考えます。  
　
###ループ(for) Python
```python
for i in range(10):
  print(i)
```

Pythonの特徴として、字下げで一つのブロックを表すことです。他の処理系出身者が間違えやすいのが

```python
for i in 10:
  print(i)
```

と記述してしまうことです。
その理由は考え方の違いです。
#####Pythonの考え方
```python
range(10):
```
の意味は、0〜9の配列(リスト）を作りなさいという意味です。1〜１０出ないことに注意してください。  

　そのため、次のようなこともできます。

```python
char1 = 'test'
for char2 in char1:
  print(char2)
  
char3 = ['test1','test2','test3']
for char4 in char3:
  print(char4)
```



```実行結果
t
e
s
t
test1
test2
test3
```

###ループ(for) R

```R
for(i in 1:10){
  print(i)
}
```
　RもPythonと同じような考え方です。明示的に１〜１０を指定します。
forの対象となるのは{}の内部です。見やすくなるようにインテンドしていますが、Pythonと異なり、インデントに意味はありません。

PythonとRに共通するのは、最初に配列を作ってから、それに対してループを行うことです。
vim で文字数をカウントする方法， 標準コマンドを使用して

# こんなときに
- 日本語対応のフォーマットのファイルしか，文字数が出ない．
- ファイルの全文字数を知った上で，文章のある範囲の文字数が知りたい．

# よくある方法

[viで文字数をカウントする](https://qiita.com/Wollest/items/4d21a2e6026e5c40619e)

``` :コマンド 
:%s/./&/g
```

```:結果
1077 箇所を置き換えました．
```

- 長い，忘れそう．
- 全部ハイライトされる．
- 情報少ない．

# 標準機能としての方法

[ビジュアルモードでテキストを選択し加工する (3/3)](https://www.atmarkit.co.jp/ait/articles/1106/15/news127_3.html)

```:コマンド
g Ctrl-g
```

```:結果
列 19-13 / 111-75; 行 31 / 107; 単語 33 / 122; 文字 1077 / 3824; バイト 2403 of 8474
```

- めっちゃ楽！
- g Ctrl-g のように，行の移動に関係するコマンドで覚えやすい！
- 列，行，単語，文字，バイト と情報量多い！
 - ファイル全体で107行，そのうち，選択しているのは31行目．
 - ファイル全体で122文字，そのうち，選択しているのは33文字．

```
:help index.txt
```

と入力してヘルプを見ると，以下のように書いています．

```vim:index.txt          
|g_CTRL-G| g CTRL-G 
show information about current cursor position                                      
```

vimerの中での，このコマンドの既知率？は知りませんが，
とても便利なコマンドだと思います．
Jupyter notebookをリモートのDocker（Ubuntu)をサーバーにしてローカルのブラウザで見る方法

##要約
Jupyter notebookは便利です。Anacondaからインストールすると、ローカルのコンピュータをサーバーとして自作自演クライアントになる設定になっています。リモートをサーバーとしてupyter notebookを走らせることはできますが、セキュリティ面で心配です。そこで、sshで暗号化してhttpsでつながるようにすることにしました。jupyter notebookのコンフィギュレーションにちょっと鍵情報をたして、dockerにjupyter notebookを走らせるよう記述し新たなdockerをビルドします。
###注意点
実際にはここに書いてある以外にクライアントのブラウザでhttpsを受けるために証明書が必要です。ここには書いてないです。
このバージョンは完全な記述ではないです。
##手順
###joupyter notebookのconfigurationに鍵情報を書き込む。
jupyter notobookを常駐させたいdockerをリモートで走らせ、たうえで、

```ipython
In [2]: from IPython.lib import passwd
In [3]: passwd()
Enter password:
```

となるので、自分で決めたパスワードを入力する。

```
Verify password:
```

で同じのを入力する。すると、

```
Out[3]: 'sha1:*****
```

とshaのカギができるので、これを

```
editor ~/.jupyter/jupyter_notebook_config.py
```

とかやって、jupyter_notebook_config.pyを開き、編集する。上記ののカギを

```
c.NotebookApp.password = u’sha1***'
```

というようにeditする。```jupyter_notebook_config.py```ではコメントアウトしてあるはずなので、コメントアウトを解除しておく。

###jupyterを起動するためのシェルスクリプト
jupyterを起動するためのシェルスクリプトも書いておきます。

```jupyter_run.sh:
#!/bin/bash
jupyter notebook --port=9999 --ip=0.0.0.0 --allow-root --no-browser &
echo "Access from a local browser using URL: "
echo "https://123.45.67.890:9999/"
```

###dockerをコミットする。
このように設定したdockerを

```
docker commit e839bcb92clc6d user/mydocker:latest
```

として、コミットします。


Dockerfileとしては、

```Dockerfile
FROM user/mydocker:latest
MAINTAINER rk
RUN pip install scikit-learn
RUN mkdir /workspace/bin
ENV PATH $PATH:/worksapce/bin
RUN echo $PATH
ADD jupyter_run.sh /workspace/bin
CMD /bin/bash  /workspace/bin/jupyter_run.sh
```
というようにしておく。これを使ってdockerをビルドすればとりあえず完成です。
バグに気づきやすくなる`??`演算子を改造したカスタムオペレータ 【Swift】

# はじめに
`??`オペレータをむやみに使うとデバッグ段階で気づくべきバグに気付けなくなる可能性があるので，下記の記事で述べられていることは有意義に感じた．
しかし，毎回下記の記事に書いてあるように記述するのも大変そうなので，簡単に扱えるカスタムオペレータを作ってみた．

>安易な気持ちで `as? Int ?? 0` みたいなコードを書いてはいけません（戒め 
https://qiita.com/lovee/items/a82087f8c3663f207c7f

# 作ったカスタムオペレータ `!?`
二項演算子で表現した．
エラー文は関西人風味でお届け．これでバグを出ても決して苛立つ事は無くなるので一石二鳥である．ぜひ採用してみてほしい．

```swift
infix operator !?
func !?<T>(lhs: T?, rhs: T) -> T {
    return lhs ?? {
        assertionFailure("って，アンラップ出来んやないか~~~~い😂")
        return rhs
    }()
}

let text: String? = nil
// デバッグ環境ならエラー， プロダクション環境なら"hello world"が返却されます
print(text !? "hello world")

```

# 感想
プログラマが真にnil許容を許容している場合は`??`を，コンパイラに翻弄されてしまっている場合は`!?`を使う，といったような使い分けが出来ると良いと思った．
GithubAPI V4を試して見る

## 動機
GitHubのIssueとProjectを使ってTiDDしているが機能的に物足りないので
サマリを作る部分だけでも自動化したいと思っている

## GitHubAPI
- v3 https://developer.github.com/v3/
REST API

- v4 https://developer.github.com/v4/
GraphQL API

## V4を試して見る
0. API endpoint: https://api.github.com/graphql
0. GitHubの[PERSONAL ACCESS TOKEN](https://github.com/settings/tokens)が必要
0. 取得したらqueryのJSONをcurlでPOSTリクエスト

```sh
curl -H "Authorization: bearer ACCESS_TOKEN" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

{"data":{"viewer":{"login":"jxmtst"}}}
```
#### GitHub GraphQL API Explorer
- https://developer.github.com/v4/explorer/

GraphQLのリクエストを試せるツールがあったので試してみた
![image.png](https://qiita-image-store.s3.amazonaws.com/0/339816/7b783e0b-0bde-f83c-a93a-4e7b8cc365e4.png)


## 制限について
#### rate limit
- v3の制限は 5,000request/hour
- v4の制限はrate limit scoreというポイントで計算される
- rate limit scoreに関する説明の原文<br>
https://developer.github.com/v4/guides/resource-limitations/#rate-limit

負荷によって変わると書いて有るけど、結局具体的な数値は組んでいる段階では分からなそうに見える。
じゃあ実際のpointはどうやって知るかというと
queryにrateLimitを付加する事で分かる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/339816/ae40519d-179b-68e4-86f7-6359677523ef.png)

#### node limit
- GraphQLなのでNodeにもリミットがかかっている
- 一つのnodeは100件まで
- 1リクエストで500,000ノードまで

ノードが大きければその分rate limite scoreもあがるので実用するには色々考える必要がありそう

## Objects
リソースに関するドキュメントはこちら
https://developer.github.com/v4/object/

今日はここまで
Hinton Diagram

# Hinton Diagram
結合行列の視覚化を行います。ここでは、neuronの結合を想定しています。シミュレーションでは、1~Mがexcitatory neuronで、M~Nがinhibitory neuronとすると、左のほうにexcitatoryの結合が来て、右のほうにinhibitoryの結合が来るので見やすいです。
横軸が`pre`で縦軸が`post`です。

# メイン
以下の関数ではexcitatoryの結合を赤で、inhibitoryの結合を青で書いています。

```python:python
def hinton(matrix, max_weight=None, ax=None):
    """結合行列を描画"""
    ax = ax if ax is not None else plt.gca()

    if not max_weight:
        max_weight = 2 ** np.ceil(np.log(np.abs(matrix).max()) / np.log(2))
    N = len(matrix)
    ax.patch.set_facecolor('gray')
    ax.set_aspect('equal', 'box')
    ax.set_xticks(np.arange(1, N+1))
    ax.set_yticks(np.arange(1, N+1))
    ax.set_xlim([0.5, N+0.5])
    ax.set_ylim([0.5, N+0.5])

    for (x, y), w in np.ndenumerate(matrix):
        color = 'red' if w > 0 else 'blue'
        size = np.sqrt(np.abs(w) / max_weight)
        rect = plt.Rectangle([x+1 - size / 2, y+1 - size / 2], size, size,
                             facecolor=color, edgecolor=color)
        ax.add_patch(rect)

    ax.autoscale_view()
    ax.invert_yaxis()
```

実際に描画するときは`plt.style.use("ggplot")`でいい感じになるかと思います。
以下の`psp`はnd.arrayで`psp[i][j]`は`j -> i `の結合に対応します。

```python:plot
plt.style.use("ggplot")
plt.figure(figsize=(6,6))
hinton(psp.T)
plt.xlabel("pre")
plt.ylabel("post")
plt.savefig("hinton_diagram.pdf", bbox_inches="tight", pad_inches=0)
```
## 例
適当に乱数で結合行列を生成してhinton diagramで描画した結果です。結合の強さが四角の大きさを見るだけでわかります。
![hinton_diagram.png](https://qiita-image-store.s3.amazonaws.com/0/272975/7d37096b-64de-def9-ee8f-24beb8c5edb1.png)

# 参考
以下のコードを元に作成しました。
https://matplotlib.org/gallery/specialty_plots/hinton_demo.html
次の中からmutableなものをまとめたものとして適切なものを選びなさい

#はじめに
この記事はPython3初学者が、[DIVE INTO EXAM](https://diver.diveintocode.jp/exam#exam-list)のPython3エンジニア認定基礎試験の問題を引用し、解答するものです。間違い等があればご教示くださると嬉しいです。

## 設問
>
次の中からmutableなものをまとめたものとして適切なものを選びなさい


## 解答群
>
- リスト
- 該当なし
- タプルとリスト
- タプル

## 正解

- リスト

## 解説
[リファレンス](https://docs.python.org/ja/3/reference/datamodel.html?highlight=mutable)によると、シーケンスには変更可能(mutable)なものと変更不能(immutable)なものがある。mutable

### mutableなもの
- リスト型（list）
- 辞書型（dict）
- bytearray

### immutableなもの
- 数値型（int,float..)
- 文字列型(str)
- タプル型（tuple）
- 論理値型（bool）
- type(None)

##選択肢について
### リスト
正解

### 該当なし
リストはmutableであるため不正解

### タプルとリスト
リストはmutableであるが、タプルはimmutableであるため不正解

### タプル
タプルはimmutableであるため不正解