OmniAICreator/Qiita-1.07M huggingface dataset:
備忘録　－　プロキシサーバーの話　－　その2（フォワードプロキシとリバースプロキシ）

[前回](https://qiita.com/nagashi_ma_w/items/6f06813b731337baf7f6)からの続き。
今回は機能とかに触れていきたさがある。
ざっくり「何かの代理となるサーバーだよ」ってのは前回触れたので、今回はもうちょい突っ込んだお話。

##フォワードプロキシについて

LANにいるクライアントの代わりに、webサーバーにデータを取りに行くヤツ。
ブロードバンド登場以前のインターネットは今のように高速ではなく、ローカルにいるクライアントの代わりにデータを取りに行きプロキシサーバーにキャッシュを保管することで、2回目以降に同じwebサーバーにアクセスする際に、クライアントがより高速にデータを閲覧することが可能になる。
これはプロキシサーバーを経由してWANと通信する全てのクライアントに当てはまるので、
もしプロキシサーバーが自宅にあったら、おうちの人がYahoo!とか見た後に自分でアクセスするとサクッと表示してくれる。

またプロキシが代理でデータを取得するという構成であるから、送信元IPアドレスを秘匿することができ、攻撃を受けた際にプロキシサーバーが身代わりになる。
_____________________
主にキャッシュを保管するという部分のデメリットがとして、
第一に、プロキシサーバーを経由する通信経路になるため、初回のアクセスではプロキシサーバーがない構成よりも遅延が発生する。
次に、webサーバー上のデータが更新されたとき、キャッシュも同時に更新されるというわけではないので、クライアントが最新のコンテンツを閲覧できないことがある。

高速なインターネットが普及している現在では、メリットよりデメリットのほうが大きく、
奇特な人でない限りは一般家庭では使用されていない（と思う。）
_____________________
というのも[前回](https://qiita.com/nagashi_ma_w/items/6f06813b731337baf7f6)で言及した、インターネット接続サービスが一般ユーザーに提供され始めたときのインターネットはメチャクチャ高級品。
月額で__ウン十万円__とかかかっていたし、そもそも帯域が全然違う。
今どき、スマホで通信量制限に引っかかると128kbpsまで制限されるけど、当時はベストエフォートでそれくらい。
効率よく使うのは非常に大事だったとか。
また、今と違ってwebサーバー上のコンテンツ更新はだいたい手動だから頻度も高くない。

ここらへんの理由が相まって、常に最新のコンテンツを閲覧することよりも、インターネットそのものを効率よく使うために出てきたもの。


昨今のフォワードプロキシ事情では、webフィルタリングを搭載したりプロキシ繋がないと環境に接続させないとかで、よりセキュアなブラウジングをさせているイメージ__（主観）__

##リバースプロキシについて
こいつが出てきたからフォワードプロキシという単語が生まれたと言っていいらしい。

###そもそもなぜリバースプロキシが登場したのか
人気のあるサイトってアクセスが集中するけど、サービス提供側からするとサーバーがダウンするのってそれだけでビジネスの機会損失になっちゃうからなるべく落としたくない。ソシャゲも落ちてると叩かれたりするし。

んで最初のころはDNSラウンドロビンなんかで負荷分散してたらしいんだけど、それだと権威DNSサーバーからISPとかが持ってるキャッシュサーバーに浸透するまでラグがあり、
サービスのリニューアルとか変更をユーザーが使えるようになるまでにタイムラグが発生してしまってよくない。
※DNSの浸透という表現が正しいかどうかは置いとく
_____________________
そこで出てきたのがロードバランサー！（リバースプロキシはもうちょい先）
1つのグローバルIPでも複数のHTTPサーバーが動かせるようになったということ。

とはいえ昔は文字だけのサイトだったものが、画像載せたり動画載せたり認証機能つけたりと、どんどんリッチになってきたせいでHTTPサーバーだけでは処理できないのが今どき。
そこでフロントエンドとバックエンド側（アプリケーション、データベース）とでサーバーを分割しましたとさ。

そんでもってそれぞれのサーバー間で、より効率よくデータのやり取りをしたい！
ということで、特に画像なんかの静的コンテンツは一回見に行ってキャッシュしておけばいいので、フロントエンドとバックエンドの間に、バックエンドでデータを持ってるデータをキャッシュしておいて、フロントエンドがより高速にデータを見れるようにしました。
これが__リバースプロキシ__というわけ。

##雑な説明
フォワードプロキシ：クライアントがより高速にデータを受信するために使う。
リバースプロキシ：サーバーがより高速にデータを配信するために使う。

_____________________
###感想
リバースプロキシってロードバランサみたいなモンでしょ？とか思ってた時代が私にもありました.....
フォワードでもリバースでも、キャッシュを持たせることによって、より高速にクライアントへコンテンツを配信する。
という思想なのかなあ。それは変わってないんだろうなあ。と思いましたん。

具体的なパラメータとかは出せないので悪しからず....
Goで比較明合成してみた


## 画像読み込み

ファイルパスから`image.Image`を作る。

```go
func decode(file string) (image.Image, error) {
	reader, err := os.Open(file)
	if err != nil {
		log.Fatal(err)
	}
	defer reader.Close()

	img, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}

	return img, nil
}
```

## 輝度計算

輝度はピクセルの明るさのことです。
以下のサイトを参照して計算していますが、比較明合成では実際の輝度の値ではなく、大小関係が知りたいだけなので、小数にせずに整数にして計算しています。

[osakana.factory - HSB 値と輝度の求め方](https://ofo.jp/osakana/cgtips/hsb.phtml)

```go
func luminance(color color.Color) uint32 {
	r, g, b, _ := color.RGBA()

	return 298 * r + 586 * g + 114 * b
}
```

## 合成

画像のピクセルを一つずつ見ていき、色情報を取り出す。
輝度を計算し、大きい方の色を出力画像のピクセルとして書き出しています。

```go

func blend(img1, img2 image.Image) image.Image {
	width := img1.Bounds().Max.X
	height := img1.Bounds().Max.Y

	out := image.NewRGBA(image.Rect(0, 0, width, height))
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			color1 := img1.At(x, y)
			color2 := img2.At(x, y)

			if luminance(color1) >= luminance(color2) {
				out.Set(x, y, color1)
			} else {
				out.Set(x, y, color2)
			}
		}
	}

	return out
}
```

## main関数

最後にmain関数。
コマンドライン引数で合成用の画像ファイルと出力先を指定。

```go
func main() {
	img1, err := decode(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	img2, err := decode(os.Args[2])
	if err != nil {
		log.Fatal(err)
	}

	if img1.Bounds() != img2.Bounds() {
		log.Fatal()
	}

	out := blend(img1, img2)

	writer, err := os.Create(os.Args[3])
	if err != nil {
		log.Fatal(err)
	}
	defer writer.Close()

	jpeg.Encode(writer, out, &jpeg.Options{100})
}
```

# コード全文

[tkt989/golang-blend](https://github.com/tkt989/golang-blend)

# 実行例

撮った写真でいくつか実行してみました。

---

<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/78a93250-ad7f-6e2d-0bc4-f951b1f83b4a.jpeg" width="300">
<p>+</p>
<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/79c47651-6f06-801f-6951-9698c951d523.jpeg" width="300">
<p>=</p>
<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/3fac06fd-9b90-28ca-1af6-527a74479a69.jpeg" width="300">

---
<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/7cd56d07-e872-6ed9-ed16-4fb20c1e386f.jpeg" width="300">
<p>+</p>
<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/dd5b7511-2fae-0165-f3f8-26c339f29ae8.jpeg" width="300">
<p>=</p>
<img src="https://qiita-image-store.s3.amazonaws.com/0/94929/75617ff4-a479-5bc9-8778-52d12cc9c12f.jpeg" width="300">
Eclipseでの初めてのJava開発

EclipseでJava開発をしました。HelloWorldを出力するだけの初心者向けサンプルプログラムのメモです。
SAP関連の開発をしようとして、インストール時にEclipseとJDK以外もありますが、以下の記事に記録しています。

- JDKのインストール：[Java初心者でもできるPCへのJCoを使ったSAPシステム接続環境構築](https://qiita.com/FukuharaYohei/items/d1f367a0fb6e6670378f)
- Eclipseのインストール：[Java初心者でもできたJSP + Eclipse + Jetty開発環境構築](https://qiita.com/FukuharaYohei/items/03c41b58f8a2e2f30a39)

#手順
##1. プロジェクト作成
Project Explorerで右クリックして New -> Project を選択。
![10.CreateProject01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/b5a270af-cd42-350f-de59-6976a111e11e.jpeg)

「Java Project」を選択。
![10.CreateProject02.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/713a6ebb-88df-04f8-df10-ceb19aa9b0f3.jpeg)

項目「Project name」を入力して終了。
![10.CreateProject03.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/9cd8202a-cc9f-3987-8359-c935ea1ffc68.jpeg)

JavaのPerspective(Eclipseの画面表示設定)に変更しておきます。
![10.CreateProject04.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/844a11ad-2cd1-497e-79e2-cf47d09389d2.jpeg)

##2. パッケージとJavaプログラム作成
"src"フォルダで右クリックして New -> Class を選択。
![20.CreatePackage01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/329a426b-7cbc-5b34-2970-317394486449.jpeg)

パッケージ名とクラス名を入力して終了。
![20.CreatePackage02.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/8df96236-3ecb-47cd-2327-f126c9fccb3c.jpeg)

以下のソースコードで保存。

```Java:HelloWorld.java
package test00;

public class HelloWorld {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Hello, world");

	}

}
```

#実行
メニューの Run -> Run で実行するとコンソールにHello Worldが表示されます。
![30.RunResult01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/23b15295-b23d-4733-c6fe-0c7ae240c866.jpeg)
Flowtype と TypeScript で両方動きそうなコードを書く

最初に知るべきこととして、Flow も TS も型システムのセマンティクスがよく似ている。

[Redux & Typescript typed Actions with less keystrokes](https://medium.com/@martin_hotell/redux-typescript-typed-actions-with-less-keystrokes-d984063901d) の 記事のかなり魔術的なコード、実は flow でも ts でもそのまま動いたりする。

自分は両方頻繁に使うので(flow寄りだが)、どういうコードを書くと手戻りが少ないか、考えながらコードを書いてるか書き出してみる。

## お断り

flowtype と typescript の、特に typescript 的なベストプラクティスに反する可能性がある。
完全にコンパチにするのは不可能だが、極力似たイディオムを使う。

どれも「極力頑張る」という感じで原則禁止というわけではない。大事なのは相互にコードを持ち出す時のポータビリティ。最悪なのは型がないという状態。

あと自分は TypeScript の非標準なモジュール拡張を非常に MS 的な所作だという理由で嫌っている自覚があるので、その辺の温度感も差し引いてもらいたい。


## TypeScript: strictNullChecks を有効にする

```
{
  "compilerOptions": {
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "alwaysStrict": true
  }
}
```

こっちのほうが flow の挙動に近い。

## TypeScript: internal-module を使わない

```
// NG
module MyInternalModule.Helpers {
  export class MyClass {}
}
// OK
// helpers/MyClass.ts
export class MyClass {}
```

ES Modules を 使えば不要なはず。

tslint なら `no-internal-module: true` と `no-var-require: true`


## TypeScript: namespace を使わない

コードは略。 internal module と同様、 ES Modules にそんなものはない。
非標準なモジュールシステムを使わないという点で一貫する方が良い。

tslint なら `no-namespace: true`

## TypeScript: private/public を使わない

```
// NG
class MyClass {
  private foo: string = 'FOO'
}

// OK
class MyClass {
  foo: string = 'FOO'
}
```

JSにそんなものはないし、 むしろ private field は `#foo` になりそう。

[tc39/proposal-private-fields: A Private Fields Proposal for ECMAScript](https://github.com/tc39/proposal-private-fields)

stage3 に入って、 typescript が対応したら考える。

そもそも、ここしばらく React の componentDidMount 以外で目的で class を使った記憶がない。 最近はかなりFP厨気味なコードを書いている自覚があり、 class もオブジェクトへの副作用もそもそも不要だと思ってコードを書いている。

## TypeScript: enum を使わない

```
// NG
enum Color { RED = 'red', GREEN = 'green', BLUE = 'blue' }

// OK
type Color = 'red' | 'green' | 'blue'
```

union type で十分。

探したが tslint に `no-enum` なかった。誰もそんな発想をしていないっぽい。

## FlowType: nullable syntax を使わない

```
// NG
let nullableValue: ?string = null

// OK
let nullableValue: string | null = null
```

この表現の差として下の方では undefined が弾かれてしまうが、これとは別に、自分は明示的に空である値 を代入する際は null を使うというルールを採用しているので、問題ない。

## FlowType: TypeScript 共通:  組み込み型をできるだけ使わない

`$Keys<T>` とか `keyof<T>` とか使い込むと持ち出せなくなる。

これらをヘビーに使うコードはライブラリ型定義だと思われるので、そういう場合はコードの共通化を諦めて両方書いて `flow-typed` や `@types` の仕組みに乗せる。

## どうあがいても無理な import type と nested module

Flow は 型情報はコンパイル時に完全に消去され、インスタンスと型が明確に区別されている。主にこれが理由で enum がない。

`import type {...} from '...'` または `import {type ...} from '...'` を TypeScript で表現する方法はない。

また、逆に TypeScript の型定義で使われる表現で、次のようなものはFlowで上手く表現する方法がない。

```
module A {
  module B {
    export class C {...}
  }
}
```

これは flow の 型定義構文の module が入れ子にならないので、一旦複数の module に分解し直さないと同等の表現ができない。昔これが理由で flow への `.d.ts` 変換器を書くのを諦めた。


## おまけ: 両者の Pros/Cons

Flow Pros: 導入コストが本当に低い 
Flow Cons: flow server の プロセスが頻繁に行方不明になる / 追っていこうにも ocaml でソースが辛い

TS Pros: IDEが安定している
TS Cons: 非標準な割れ窓が沢山ある / スクラッチ以外の導入が困難
特殊メソッド__missing__を使ってLeetを変換

# 背景
Pythonでコンストラクタは`__init__`を呼び出す. このようなメソッドのことを, 特殊メソッドとよび、例えば演算子オーバーロードなどが実現できる. ここでは, `__missing__`を使ってLeetをやってみる.

# 特殊メソッド`\_\_missing__'
まずはドキュメントより。
>`object.__missing__(self, key)`
> `self[key]` の実装において辞書内にキーが存在しなかった場合に、 `dict` のサブクラスのために `dict.__getitem__()` によって呼び出されます。
> Python言語 リファレンス 3.データモデルより引用
> [https://docs.python.jp/3.5/reference/datamodel.html](https://docs.python.jp/3.5/reference/datamodel.html)

つまり, 辞書内にキーがない場合に呼び出される特殊メソッドである. 実例がないとよくわからないし, 実装してみないと身にならないので, Leetで使ってみる.

# Leet
Wikipediaより
>__leet__（リート、__1337__、__l33t__）は、主に英語圏においてインターネット上で使われるアルファベットの表記法である。__leetspeak__（リートスピーク）とも呼ばれる。
> Wikipedia Leetより引用
> [https://ja.wikipedia.org/wiki/Leet](https://ja.wikipedia.org/wiki/Leet)

例えばAは4, BはI3, Sは5というように変換する.  
ここでは, 定義された文字だけLeetにして, ほかはそのまま返すようにする. つまり,   
O='0', I='1', S='5', T='7', E='3'  
と定義すると,  
「NOW IS THE TIME」 = 「N0W 15 7H3 71M3」  
と変換するようにする.  

# 解答例

```python3:
class LeetDict(dict):
    def __missing__(self, key):
        return key

leet_dict = LeetDict(
    O='0',
    I='1',
    S='5',
    T='7',
    E='3',
)

question = 'NOW IS THE TIME'
question_list = list(question) # リストにしなくてもOK(shiracamusさんありがとう!)

answer_list =  [leet_dict[k] for k in question_list]

print(''.join(answer_list)) # N0W 15 7H3 71M3
```

# 参考
[http://diveintopython3-ja.rdy.jp/special-method-names.html](http://diveintopython3-ja.rdy.jp/special-method-names.html)
pandas基本　個人メモ


pythonの基本ライブラリ pandas についての個人的メモ。
初歩的なことばかりです。都度更新していく予定。
見たものをメモしていくので、使用頻度はバラバラかも。


## pandas
行列データを扱いやすくしたり、集計を行うライブラリ。

### 慣習
pandas はimportする際、慣習的に pd と名づける。

```python:import
import pandas as pd 
```

### DataFrame
pythonでデータを行列として扱う時の型。
pandasの DataFrame() メソッドを用いることで、新規のデータセットを生成できる。
DataFrame型は二次元の配列であり、カラム毎に異なる型のデータを入れることができる。

```python:DataFrame()
sample = pd.DataFrame({'A':[1,2,3],
                       'B':[4,5,6],
                       'C':[7,8,9]})
```
|   |A  |B  |C  |
|---|---|---|---|
|0  |1  |4  |7  |
|1  |2  |5  |8  |
|2  |3  |6  |9  |

- pythonでは [] で囲んだものはリスト型として扱われ、値が順序づけられて管理される
- pythonでは {} で囲んだものはディクショナリ型として扱われ、キーと値が紐づけて管理される
- したがって上記のコードでは、'A'列に対して[1,2,3]の値をもつ行が紐づけられている

*others*
*pandas.Series型*
一次元配列。dictionary的だが、index指定による要素へのアクセスも可能。
*numpy.ndarray型*
多次元配列。配列内要素は全て同じ型でなければいけない。処理が高速。DataFrameやSeriesを引数に指定して、最終的にndarrayにするという使用が多い。らしい。

### read_csv
csvをロードする。読み込んだデータは DataFrame 型として扱われる。

```python:read_csv()
sample2 = pd.read_csv('sample.csv') 
```

### shape
データのサイズを測る。
引数なしではデータセット全体の行数と列数を、引数に列番号を指定するとその列に属する行数がわかる。

```python:shape()
sample.shape     #全ての行と列の数を数える
sample.shape[0]  #0番目の列、即ちA列に属する行数を数える
```
*→ (3,3)*
*→ (3)*

### columns
データセットの全ての列を表示する。

```python:columns()
sample.columns()
```

*→ Index(['A', 'B', 'C'], dtype='object')*

### query
指定した列に対しての条件に合致する行を取り出す。条件式はシングルクォーテーションで囲む。

```python:query
sample.query('A == 3') #A列の値が3未満であるデータを取り出す
```

|   |A  |B  |C  |
|---|---|---|---|
|0  |1  |4  |7  |
|1  |2  |5  |8  |


### describe
データセットの統計量を表示する。

```python:describe()
sample.describe()
```


|     |A    |B    |C    |(意味)|
|-----|-----|-----|-----|-----|
|count|3.0  |4.0  |7.0  |件数   |
|mean |2.0  |5.0  |8.0  |平均   |
|std  |1.0  |1.0  |1.0  |標準偏差|
|min  |1.0  |4.0  |7.0  |最少   |
|25%  |1.5  |4.5  |7.5  |第一四分位数|
|50%  |2.0  |5.0  |8.0  |中央値|
|75%  |2.5  |5.5  |8.5  |第三四分位数|
|max  |3.0  |6.0  |9.0  |最大  |


*第一四分位数：中央値以下のデータの平均*
*第三四分位数：中央値以上のデータの平均*


### join
二つのデータセットを結合する。
結合の種類は多くあるが、一番単純な例。

```python:join()
sample = pd.DataFrame({'A':[1,2,3],'B':[4,5,6],'C':[7,8,9]})
sample2 = pd.DataFrame({'D':[10,9,8],'E':[7,6,5],'F':[4,3,2]})
sample.join(sample2)
```

|   |A  |B  |C  |D  |E  |F  |
|---|---|---|---|---|---|---|
|0  |1  |4  |7  |10 |7  |4  |
|1  |2  |5  |8  |9  |6  |3  |
|2  |3  |6  |9  |8  |5  |2  |




<br><br><br>
//2018.1.23 ここまで。
C言語で「if (a == 1 && a == 2 && a == 3) を true」 にする

流行り(2018/01/23)に乗って、C言語版を作ってみた。少しインチキしている。

```c
#include <stdio.h>
#define a ++num
void main(void) {
  int num = 0;
  if (a == 1 && a == 2 && a == 3) puts("true");
}
```

こう言うのって、コロンブスのたまご的ですね。
[Windows10] VMwareでUbuntu環境整えてみる

最近研究室でUbuntuに触れる機会が多くなってきたので
自宅PCにもUbuntu入れてみる。

授業用Ubuntu環境整えられなかった1年の頃を思い出すなぁ。。。
その頃はUSB Bootで頑張ってたし、それも後ほどまとめる。

#必要なもの
- Windows PC
- [VMware Workstation player](https://my.vmware.com/jp/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/14_0)
- [Ubuntu](https://www.ubuntulinux.jp/japanese) isoファイル(今回はUbuntu 17.10)

#目次
    1. 必要なものリストのURLからダウンロード
    2. Ubuntuのインストール

#作業内容
...といっても大したものではないので、簡潔に。
1. VMwareのインストール
　※無償版VMwareは商用利用では利用できないことをお忘れなく

　設定はデフォルトでOK。
　なので、カット。

2. Ubuntuのインストール
　ダウンロードしてきたisoファイルをインストールする。

　これもユーザ設定とかだからカット。
　暇なときに修正する。
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい

```text:出力結果
true
```

```java:実装
import java.io.PrintStream;

public class Main {
    public static void main(String[] args) {
        int a = args.length;

        if (a == 1 && a == 2 && a == 3) {
            System.out.println("true");
        } else {
            System.out.println("false");
        }
    }












































    static {
        PrintStream org = System.out;
        System.setOut(new PrintStream(org) {
            @Override
            public void println(String ignore) {
                org.println(true);
            }
        });
    }
}
```

ほんとすんません。

**元ネタ**

[(a == 1 && a == 2 && a == 3) を常に真にできますか？ - Qiita](https://qiita.com/Morichan/items/4894d7d92ecab7a3afd8)
変数の中身をファイルに保存する

VBAには値型の変数の中身をファイルに保存する機能が備わっています。

VBScriptでは使えない、構文がちょっと面倒といった欠点はありますが、簡単な情報の保存には使える気がします。

# 使用するもの

今回使用するのは以下のステートメントです。

>[Open ステートメント](https://msdn.microsoft.com/ja-jp/VBA/Language-Reference-VBA/articles/open-statement "Open ステートメント")
[Put ステートメント](https://msdn.microsoft.com/ja-jp/VBA/Language-Reference-VBA/articles/put-statement "Put ステートメント")
[Get ステートメント](https://msdn.microsoft.com/ja-jp/VBA/Language-Reference-VBA/articles/get-statement "Get ステートメント")

## Open

`Open`はファイル操作を開始するためのステートメントです。
`Mode`として`Binary`を指定することで、バイナリデータの入出力が可能になります。

## Put

`Put`は変数をファイルに書き出すためのステートメントです。
値型であれば、ユーザー定義型や配列も保存することが出来ます。

## Get

`Get`はファイルの中身を変数に読み込むためのステートメントです。
PutとGetは対として使用します。

# サンプルコード

tempフォルダに適当なファイルを作って保存し、そのファイルからデータを読み込むサンプルです。

コードにもあるように、数字・文字列・日付といった値型の要素であれば問題無く保存、読み込みが可能です（二次元配列も問題無く保存することが出来ます）。

```vbnet
Sub VariableSaveTest()
    Dim tmpPath As String
    tmpPath = Environ$("tmp") & "\vba_temp.bin"
    
    Dim saveData As Variant
    saveData = Array(1024, "abc", Now)
    
    '保存
    SaveVariable tmpPath, saveData
    
    '読込
    Dim loadData As Variant
    loadData = LoadVariable(tmpPath)
    
    Stop '中身確認
End Sub


Sub SaveVariable(filePath As String, var As Variant)
    Dim fNo%: fNo = FreeFile()
    
    Open filePath For Binary As fNo
        Put fNo, , var
    Close fNo
    
End Sub

Function LoadVariable(filePath As String) As Variant
    Dim fNo%: fNo = FreeFile()
    
    Open filePath For Binary As fNo
        Get fNo, , LoadVariable
    Close fNo
    
End Function
```
ransackやkaminariで任意のパラメータを送る方法

#ransackやkaminariで任意のパラメータを送る方法

##環境
Windows8
Rails 5.1.4
ruby 2.4.1

##なぜこの記事を書いたのか
学校でRailsを使ってグループ開発をしている時に任意のパラメータを埋め込んで送る方法がわからず意外と詰まったので、私と同じ状況の人がいたら助けになると思って書きました。

後、自分が忘れないためです。

##概要
ransackやkaminariで任意のパラメータを送る方法が存在します。
それを、ここに記します。

##ransackとkaminariについて

### ransack
Tableのソートが簡単にできたり、Viewの検索フォームが簡単に作れる便利なgemです。
ransackの使い方に関しては、下記のサイトが非常に分かりやすかったので是非参考にしてください。
[Ransackで簡単に検索フォームを作る73のレシピ]
(http://nekorails.hatenablog.com/entry/2017/05/31/173925)

### kaminari
ページネーションが簡単にできる便利なgemです。
ページネーションは、情報量が多くてページが縦に伸びる時に便利です。
kaminariの使い方に関しては、下記のサイトが非常に分かりやすかったので是非参考にしてください。
[kaminari徹底入門]
(https://qiita.com/nysalor/items/77b9d6bc5baa41ea01f3)

## 本題
ransackやkaminariを使ったViewで任意のパラメータを送る方法を書いていきます

### ransackのソート機能で任意のパラメータを送る方法

下のView部分で使われているプログラムのようにsort_linkにparamsを埋め込みます。

```html+erb:ransackを使ったView
<%= sort_link(@q , :name, "名前",params: {:param => "test"}) %>
```


paramsを埋め込んだ状態のリンクをクリックしてログを見てみます。
するとParamtersに任意のパラメータであるtestが送られている事がわかります。

```bash:ログ
Parameters: {"param"=>"test", "q"=>{"s"=>"name asc"}}
```

ちなみに絶対、params:　{:param =>"任意のパラメータ"}の形式ではないと、駄目というわけではないです。下のようにもできます。

```html+erb:ransackを使ったView
<%= sort_link(@q , :name, "名前",tests: {:test => "param"}) %>
```

```bash:ログ
Parameters: {"q"=>{"s"=>"name asc"}, "tests"=>{"test"=>"param"}}
```

### kaminariのページネーション機能で任意のパラメータを送る方法

kaminariの場合もransackの時とほぼ変わらないです。

```html+erb:kaminariを使ったView
 <%= paginate @user,params: {:param => "test"}%>
```

```bash:ログ
Parameters: {"page"=>"2", "param"=>"test"}
```


### おまけ
短くなりそうなのでkaminariのパラメータに関してもう少し書きます。
実は、kaminariのパラメータの"page"という名前は変更する事が可能です。


下のように:param_name => "変更する名前"とします。
今回、変更する名前をtestにしています。

```html+erb:kaminariを使ったView
 <%= paginate @user,:param_name => 'test'%>
```

この状態でページネーションの２を押下します。

```bash:ログ
  Parameters: {"test"=>"2"}
```

pageがtestに変わりました。

タブを使っていたりして複数のページネーションが一つのページに存在する画面を作る際などに需要があると思います。

以上です。
Pythonのスクレイピングコードでsend_keysエラー発生


## 事象

以下のようなpythonのheadlesschromeのスクレイピングコードで、send_keysでエラーが発生しました。


```:sample.py
#!/usr/bin/python3

import os

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

# headless chrome

options = Options()
options.binary_location = '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary'
options.add_argument('--headless')
options.add_argument('--window-size=1280,3000')

driver = webdriver.Chrome(chrome_options=options)
driver.get("https://example.com")
driver.find_element_by_xpath("//*[@id='email']").send_keys("hoge@example.com")
driver.find_element_by_xpath("//*[@id='password']").send_keys("hogehoge" + Keys.RETURN)
```

## エラー内容

```
 File “sample.py”, line 28, in <module>
   send_keys(‘john@example.com’)
 File “/Users/:user/.pyenv/versions/anaconda3-4.3.0/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py”, line 479, in send_keys
   ‘value’: keys_to_typing(value)})
 File “/Users/:user/.pyenv/versions/anaconda3-4.3.0/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py”, line 628, in _execute
   return self._parent.execute(command, params)
 File “/Users/:user/.pyenv/versions/anaconda3-4.3.0/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py”, line 312, in execute
   self.error_handler.check_response(response)
 File “/Users/:user/.pyenv/versions/anaconda3-4.3.0/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py”, line 237, in check_response
   raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: call function result missing ‘value’
 (Session info: headless chrome=66.0.3329.1)
 (Driver info: chromedriver=2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2),platform=Mac OS X 10.13.3 x86_64)
```

## 対応

どうやら ``ChromeCanaryの66.0.3329.1版``（2018/1/23時点で最新）で、該当エラーが発生するようなので、ダウングレードして、
``バージョン: 63.0.3239.132（Official Build） ``
にすればエラーが回避できました。
Scalaでチャットワークに通知する


## 下記コマンドでプロジェクト新規作成

```
sbt new sbt/scala-seed.g8
```

Chatworkへの通知には[chatwork4s](https://github.com/k4200/chatwork4s)を利用する

```scala
"tv.kazu" %% "chatwork4s" % "0.2.5.2",
```

chatwork4sはscala2.11はサポートしているとの記載があるのでbuild.sbtの下記部分でバージョンを指定した。

```scala
scalaVersion := "2.11.8",
```

試しにRoom情報を取得してみる

```scala
 11 object Main {
 12   val token: String = sys.env("CHATWORK_TOKEN")
 13   val client = new ChatWorkApiClient(token)
 14   val f: Future[Room] = client.room([your room id])
 15
 16   f.onSuccess { case room: Room => println(room) }
 17   f.onFailure { case t: Throwable => println(t.getMessage()) }
 18   println(f.isCompleted)
 19
 20   Await.ready(f, Duration.Inf)
 21 }
```

Roomに対して投稿するのは下記の通り。


```scala
  3 import scala.concurrent._
  4 import ExecutionContext.Implicits.global
  5 import scala.concurrent.duration.Duration
  6 import tv.kazu.chatwork4s.ChatWorkApiClient
  7 import tv.kazu.chatwork4s.ChatWorkApiResponse
  8 import tv.kazu.chatwork4s.models._
  9 import scala.concurrent.duration.Duration
 10 import scala.util.{ Try, Success, Failure }
 11
 12 object Main with App {
 13   val token: String = sys.env("CHATWORK_TOKEN")
 14   val client = new ChatWorkApiClient(token)
...
 22
 23   val f: Future[ChatWorkApiResponse] = client.post("/rooms/[your room id]/messages", Seq(("body", "hoge")))
 24
 25   f.onSuccess { case res: ChatWorkApiResponse => println(res) }
 26   f.onFailure { case t: Throwable => println(t.getMessage()) }
 27   println(f.isCompleted)
 28
 29   Await.ready(f, Duration.Inf)
 30 }
 ```
 
 無事に「hoge」を投稿することができた。
 
 全部入りのjarファイルを作って実行したかったので、project/assebly.sbt に下記を追加してsbt-assemblyを追加。
 
```scala
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
```

下記のsbtコマンドでjarパッケージを作成する。

```
sbt assembly
```

jarファイルを実行できることを確認

```
java -jar target/scala-2.11/Sample-assembly-0.1.0-SNAPSHOT.jar
```
Failed to authenticate on SMTP server with username

#Failed to authenticate on SMTP server with username "メアド" using 2 possible authenticators

英語のサイトしか、問題解決が無かったので。
てか、凡ミスすぎて、みんなしないと思うが。

**.env**
>MAIL_DRIVER=smtp
MAIL_HOST=host
MAIL_PORT=465
MAIL_USERNAME=username
MAIL_PASSWORD=password
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=fromaddress
MAIL_FROM_NAME=from名

この部分のUSERNAMEもしくはPASSWORDが間違っていると思います。
自分は正しいPASSWORDにしたらエラーがなくなりましたm(__)m
Windows7に今必要な容量はどれくらいか

WindowsVista以降WindowsUpdateで膨れ上がる容量のせいで
Windows7 **64bit**の容量がどれくらい必要かわかりにくいで検証してみました。
12月のWindowsUpdateのせいで再インストールを検討している人もいるのではないでしょうか。

結論から書くと2019初頭パッチ適応で26.5GiBに収めるのが現在の限界です。

#順番
シナリオとしては以下でしょうか。
前提としてC:\より大きいD:\ドライブは作成されていることとします。
1. Winsows7SP1のクリーンインストール
2. 大量のWindowsUpdateを実施
3. KB2852386の適応とクリーンアップ
4. WindowsUpdateサービスの停止
5. CBS.logの削除
6. DataStore.edbの削除
7. Windows Updateを実行
8. 環境変数のTEMPとTMPの変更
9. システム変数のTEMPとTMPの変更
10. 仮想メモリの無効なしは削減
11. システム/環境変数の旧TEMPとTMPを削除
12. ハイバネーションの無効化
13. ダウンロード、デスクトップ領域の移動
14. ディスクのクリーンアップ

1と2は説明不要だと思います。
##3. KB2852386の適応とクリーンアップ
WindowsUpdateのクリーンアップを行うパッチになります。
標準では入っていない環境が残念ながらあります。
[こちら](https://support.microsoft.com/ja-jp/help/2852386/disk-cleanup-wizard-addon-lets-users-delete-outdated-windows-updates-o)
よりダウンロード、インストールください

[スタートメニュー]-[アクセサリ]-[システム ツール]-[ディスク クリーンアップ]を起動し、(c:)→[OK]
システム ファイルのクリーンアップをクリック(c:)→[OK]
"Windows Update のクリーンアップ"チェックボックスをON→[OK]

"Service Pack のバックアップ ファイル"も0バイトでなければ"チェックボックスをON→[OK]

##4. WindowsUpdateサービスの停止
[スタートメニュー]-[プログラムとファイルの検索]にてcmdを入力
cmd.exeを右クリックし、[管理者として実行]
`NET STOP WUAUSERV`を実行

##5. CBS.logの削除
%windir%\Logs\CBS\内を全て削除

##6. DataStore.edbの削除
%windir%\SoftwareDistribution\DataStore\内を全て削除
念のためこのタイミングで再起動を推奨します。

##7. Windows Updateを実行
CBS.logとDataStore.edbを再構築するためにWindows Updateを実施します。
もしインストール除外するパッチがある場合
その設定が全てリセットされてますので改めて指定して下さい。

再起動しない場合は先に`NET START WUAUSERV`を実行

##8. 環境変数のTEMPとTMPの変更
ウィンドウズキー+R→`control sysdm.cpl`を実行
[詳細設計]-[環境変数]
TEMPとTMPの値をディレクトリをウィンドウズキー+R→貼り付けで開き
とりあえずお気に入りに登録しましょう
D:\TMPを作成し
TEMPとTMPをダブルクリックしD:\TMPと入力し[OK]

##9. システム変数のTEMPとTMPの変更
8の操作のまま
[システム環境変数]のTEMPとTMPの値をディレクトリをウィンドウズキー+R→貼り付けで開き
とりあえずお気に入りに登録しましょう
TEMPとTMPをダブルクリックしD:\TMPと入力し[OK]-[OK]

メモリが潤沢にあるのでしたらRAMDISKを作成し指定してもいいでしょう。

##10. 仮想メモリの無効なしは削減
ウィンドウズキー+R→`control sysdm.cpl`を実行
[詳細設計]-パフォーマンス[設定]-[詳細設計]で
"すべてのドライブのページング ファイルのサイズを自動的に管理する"のチェックボックスをON
どれかのドライブを選択し仮想メモリ[変更]
カスタムサイズのラジオボタンをクリック、"16"をそれぞれ入力[設定]-[OK]-[OK]
このタイミングで指示通りに再起動がこの後の作業で必須です。

仮想メモリなしでも構わないのですがWindowsバージョン次第で性能劣化があったと聞いたことがあります。
環境次第で800Mやメモリ以上に指定して構いませんが
メモリが4G未満でない限り不要かと
16以外の数字の場合極力C:\以外にしましょう。

##11. システム/環境変数の旧TEMPとTMPを削除
8と9の作業で保存したお気に入り開き
全てのファイルを削除します。

##12. ハイバネーションの無効化
ハイバネーションが何かは他のサイトを検索下さい。
メモリの分だけ容量が減らせます。
[スタートメニュー]-[プログラムとファイルの検索]にてcmdを入力
cmd.exeを右クリックし、[管理者として実行]
powercfg.exe /hibernate off


##13. ダウンロード、デスクトップ領域の移動
ウィンドウズキー+R→`%USERPROFILE%｀
ダウンロードを右クリックし、切り取りD:\へ貼り付けます。
デスクトップを右クリックし、切り取りD:\へ貼り付けます。

##14. ディスクのクリーンアップ
Cドライブのプロパティを開き、
ディスクのクリーンアップ→システム ファイルのクリーンアップ
Windows Updatのクリーンアップを行う。
他のファイルも膨れ上がらないのでしたら削除して構いません

以上です。いかがでしたでしょうか。
画像が欲しい？反響がそれなりならやります。

##どれくらいCドライブを確保すればいいのか
Cドライブにしか保存できないファイルがない限り
**基本領域
26.5G+スワップファイル+消さなかった容量+他のインストール**
消さなかった容量とはスワップファイルやハイバネーションの無効化を行い場合の容量になります。
###HDDの場合は
**基本領域\*150%以上**
でしょうか。
###SSDの場合
TRIM領域を十分に確保する場合は容量の50%程度確保のため余裕を見て
**基本領域\*300%**
TRIM領域をそれなりに確保する場合は容量の34%程度確保のため余裕を見て
**基本領域\*200%**
TRIM領域を性能が低下ギリギリ(15%程度)にする場合は容量の20%程度確保のため余裕を見て
**基本領域*150%**

##推奨は
スワップファイル16M、ハイバネーション抜きでざっくり
**50GiB**です。
40GiBだと今後のパッチとかC:\必須な領域考えると辛いかな。
32bitなら40GiBでいいと思います。
[APIKit]暗号化した値を設定した際の落とし穴

### はじめに
queryParanetersに暗号化した値を貼り付けたらencode処理で怒られた、という個人的な備忘録です。

### 経緯
・普段暗号化処理は[CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)を使っているのですが、今回それを使わずに以下の記事を参考に暗号化処理を実装していました。

[PEM形式の公開鍵を使ってRSA暗号する処理をSwiftでやってみた](https://qiita.com/dq-shuhei-ohno/items/7fda2a35e811a6c11721)
[iOSで Swiftから暗号化ライブラリを使う](https://qiita.com/kunichiko/items/a57e4707e455f814d671)

・値を準備出来たので、[APIKit](https://github.com/ishkawa/APIKit)のqueryParametersに値をブチ混んでみたら、response内のエラーメッセージで「decode出来んよ」と言われてしまいました。

・それだけなら暗号化処理を疑って終わりなのですが、作った値を[Advanced REST Client](https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo)で叩いてみたら正常値を返すので、APIKitを疑って覗いてみた次第です。

### 何が悪かったのか
・今回実装した通信処理で使う某APIのドキュメントに、暗号化処理の実装サンプルがあったので写経していたのですが、最後のaddingPercentEncoding()が余計でした。

```DataManager.swift
    func makeEcryptData() -> String? {
        // 〜色々割愛〜

        var pubKey = self.publicKey
        let plainBuffer = [UInt8](plainString.utf8)
        var cipherBufferSize = UInt(SecKeyGetBlockSize(pubKey))
        var cipherBuffer = [UInt8](count:Int(cipherBufferSize), repeatedValue:0)      

        // 暗号化
        let status = SecKeyEncrypt(pubKey,
            SecPadding(kSecPaddingPKCS1),
            plainBuffer,
            UInt(plainBuffer.count),
            &cipherBuffer,
            &cipherBufferSize)
        if (status != errSecSuccess){
            return nil
        }
        let data = NSData(bytes: &cipherBuffer, length: Int(cipherBufferSize))
        // base64でEncodeする分には問題無し
        let encryption = data.base64EncodedSteing(options: NSData.Base64EncodingOptions.lineLength64Characters)
        
        // ⭐️これは余計🌟
        let rasHogeInfo = encryption.addingPercentEncoding(withAllowdedCharacters: NSCharacterSet.alphanumerics)!
        return rsaHogeInfo
    }
```

この処理をして、APIKitのqueryParametersにセットすると、以下のencode処理が実施され、最終的に作られるURL文字列には更にencodeされた文字列が入るので怒られるというオチでした。

```Request.swift
    public func buildURLRequest() throws -> URLRequest {
        // 割愛

        // ここ！
        if let queryParameters = queryParameters, !queryParameters.isEmpty {
            components.percentEncodedQuery = URLEncodedSerialization.string(from: queryParameters)
        }
 
    }
    
```

### 反省と改善策
・最終的に叩くURL文字列とBodyの中身はDEBUG時にはログを毎回出すようにする(自戒)

・APIKitを今のプロジェクトで初めて使っているのですが(Alamofireばかりだったので)、これを機に中身を勉強してみたいと思いました。

・ドキュメントに用意された実装サンプルを無闇に信じない
　-> ここ問題は無いという決めつけが地味に痛かった。。

### さいごに
通信時にログを用意していれば気づける問題ですが、同じように詰まっていた人の助けになれば幸いです。
guard let `self` = self ... を使おうとしているそこの貴方！ちょっとお待ちください！


## 20181106追記
4.2でimplementedになったようです
https://github.com/apple/swift-evolution/blob/master/proposals/0079-upgrade-self-from-weak-to-strong.md

このような書き方ができるようになりました

```swift

{ [weak self] response in
  guard let self = self else {
    return
  } 
  self.reload(response)
}

```

## ↓は4.1以前の内容

-----

weak self参照を↓のようにアンラップするパターンが多いかと思いますが

```swift

{ [weak self] response in
  guard let `self` = self else {
    return
  } 
  self.reload(response)
}

```


これができてしまうのはバグだそうです
https://github.com/apple/swift-evolution/blob/master/proposals/0079-upgrade-self-from-weak-to-strong.md

> AppleのChris Lattnerは「これはコンパイラのバグです」と述べています。
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html

self を使ってしまうと、このバグが修正されて使えなくなったとき、どこを直せばいいのかわかりにくいので、 strongSelf, me, などなどわかりやすい別名を使ったほうが良さそうです
電子工作 > 抵抗E系列 | 電子工作の問題点 | 抵抗の整理案 v0.4

### 抵抗E系列

抵抗の値というのはE12系列やE24系列などがあります。
[E6系列 E12系列 E24系列 E48系列 E96系列 E192系列の一覧表と概略計算方法](http://sim.okawa-denshi.jp/keiretu.htm)

@ トランジスタ技術 SPECIAL for フレッシャーズ No. 102
抵抗&コンデンサ活用ノート
1-4 抵抗の系列とカラー・コード

> E6の6は等比級数の公比を表します。

(注記: 完全な等比級数ではありません。詳細は関連図書を参照してください。)

### 電子工作の問題点

個人で電子工作をする場合の問題は以下のようなループに陥ることです。

https://ideone.com/cASM1c

```loop_electric_180123.py
# coding rule: PEP8

alist = [
    'have an idea',
    'go to shop',
    'buy resistor',
    'go back home',
    'soldering'
]

NUM_LOOP = 5  # arbitrary
for idx in range(NUM_LOOP):
    for elem in alist:
        print(elem)

```

このループに加えて、所持している抵抗の集合からその時々に必要な抵抗を短時間で取り出せるか、という問題があります。
（必要な技術情報の探索と同じですね。見つからない情報は持っていないのと同義ですね）。

## 抵抗の整理案 v0.4

### 必要条件

以下のようなものを検討していました。

- 透明なケース
- 抵抗を折り曲げることなく、そのまま収納できること
    - intact
- 一つのケースにE12系列の6種類程度を収めることができること
- その６種類から必要な抵抗を短時間で見つけることができること
    - 収納スペースの縮小に貢献
- ケースの再入手性が良いこと
    - discontinueにならない
- 必要な抵抗だけを取り出しやすいこと
- ケース準備の工作が短時間(10分程度)で可能なこと

検討記事: [PyQt5 > 描画 > 円と線を描く + 備考](https://qiita.com/7of9/items/32f83b88e5f81a10b9aa)

### 案 v0.4

v0.3は[こちらでした](https://qiita.com/7of9/items/029b5ac009ccc78b16a8)。

下記の左から４つ目の紫色のケース(ラムネ菓子の容器)に底上げ用の用具を加えました。

![IMG_0976.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/6520510f-ba2f-83fc-9caf-0bdaf23a8b6b.jpeg)

この例では、4.7k, 2.0k, 8.2k, 1.1k, 10kの抵抗が入っていることが見えますね。
![IMG_0979.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/272eb6ad-034e-c091-1367-3280356aba7c.jpeg)

フタを取って、底上げ機構で上に上げた状態です。これで、必要な抵抗だけを取り出せます。
![IMG_0980.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/3d3655bb-e62b-7689-5f69-8b049051d78d.jpeg)

抵抗の最大収納数は78本でした。

### BOM: Bill of Materials

- ラムネ菓子の容器: 58円
- ゴム (0.5mm厚 x 2cm高さ x 63cm幅)
    - 0.5mm厚 x 10cm高さ x 100cm幅のもの(300円?)から切りました
        - NRゴムロール GR-02
        - [天然ゴム](https://www.monotaro.com/s/pages/productinfo/gomu_feature/)
        - WAKI SANGYO CO.LTD
    - 高さは適当です
    - 幅は容器の大きさに合わせて適宜トリミングします
- カラーテープ (赤色の部分)
    - ゴムを止めるために使います
- 竹串 (15cm長さ)
    - 手順(下記)の通り、適宜切ります
    - 串焼き、おでんなどの串料理に最適
        - 所感: 確かに

### 作り方

1. 竹串にゴムを巻きます
    - 串にゴムがしっかりつくように適宜引っ張ります
2. 巻いたゴムが容器の内径にあうか確認しながら、大きければ、ゴム幅をトリミングして調整します
3. カラーテープでゴムを止めます
4. 下側の串の長さを切って調整します
    - 今回の試作では下側は1.2cm程度にしました
5. 上側の串の長さを切って調整します
    - 今回の試作では透明ケース上端から1.6cm出た状態にしました

以上です。

### 改善結果

https://ideone.com/q1takh

```py
# coding rule: PEP8

alist = [
    'have an idea',
    'go to shop',
    'buy resistor',
    'go back home',
    'soldering'
]

NUM_LOOP = 5  # arbitrary
for idx in range(NUM_LOOP):
    for elem in alist:
        if 'shop' in elem or 'go' in elem or 'buy' in elem:
            continue
        print(elem)

```
Go言語の並列処理 goroutineとchannel

##はじめに
Go言語と言えば、並列プログラミングということでgoroutine、channelに触れてみようと思います。

##goroutine
goroutine は go 文で関数を実行すると起動できます。

```go:goroutine.go
package main

import (
	"log"
	"time"
)

func f() {
	log.Println("goroutine")
}

func main() {
	go f()
	log.Println("main")
	time.Sleep(time.Second)
	log.Println("finish")
}
```
**実行結果**
```2018/01/23 20:35:46 main
2018/01/23 20:35:46 goroutine
2018/01/23 20:35:47 finish```
**go f()**が実行されてから、すぐに**log.Println("main")**が実行されていることが分かると思います。
こんなに簡単に並列処理ができるのはすごいですね...(まだ、使いこなせる気はしないですが)
goroutineは**並列処理している関数が終了した時に終了されます。**
##channel
channel は goroutine 間での変数の受け渡しができます。
<- (オペレータ)を使って、値の受け渡しをするのですが、どういう型の値を扱うのか宣言できたりもします。
また、値の受け渡しがされてから、値が届くまでブロックしてくれるので、待ち時間を設ける必要がありません。

```go:channel.go
package main

import (
	"fmt"
	"log"
	"time"
)

func f(c chan string) {
	time.Sleep(10 * time.Second)
	c <- "well come"
}

func main() {
	c := make(chan string)
	log.Print("started")
	go f(c)
	w1 := <-c//go f(c)実行後、即座に呼ばれていない
	log.Print("finished")
	fmt.Println(w1)
}
```
**実行結果**
```2018/01/23 21:52:47 started
2018/01/23 21:52:57 finished
well come
```
**go f(c)の実行後、w1 := <-cが即座に呼ばれていない**ことがわかると思います。
これらをより上手く使うために、**select**といった機能があります。
##select文
「select」文は、複数のチャネルを待機する場合に使用します。構文は「switch」文と同じく「case」を使用します。
「case」に指定したチャネルのうち、どれかを受信するまで待機します。

```go:select.go
package main

import (
	"fmt"
	"log"
)

func printa(a chan string) {
	a <- "a"
}

func printb(b chan string) {
	b <- "b"
}

func printc(c chan string) {
	c <- "c"
}

func main() {
	a := make(chan string)
	b := make(chan string)
	c := make(chan string)
	log.Print("started")
	go printa(a)
	go printb(b)
	go printc(c)
	for i := 0; i < 3; i++ {
		select {
		case msga := <-a:
			fmt.Println("finished", msga)
		case msgb := <-b:
			fmt.Println("finished", msgb)
		case msgc := <-c:
			fmt.Println("finished", msgc)

		}
	}

	log.Print("finished")

}
```
**実行結果**
```2018/01/23 21:50:33 started
finished c
finished a
finished b
2018/01/23 21:50:33 finished
```
配列を連結してあたらしい配列を返す

いろいろな書き方、流儀があるけれど、初学者が書くのが `concat1`。
ポインター使えるようになりました！　STL 読んだことあります！　ってのが書くのが `concat2`。
ちゃんと C を書けるようになったら `concat3` にたどり着く。

```c
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

static inline int* concat1(const int *a, size_t alen, const int *b, size_t blen) {
  int *const p = malloc(sizeof(int) * (alen + blen));
  int i, j;
  i = 0;
  for (j = 0; j < alen; ++j, ++i) {
    p[i] = a[j];
  }
  for (j = 0; j < blen; ++j, ++i) {
    p[i] = b[j];
  }
  return p;
}

static inline int* concat2(const int *a, size_t alen, const int *b, size_t blen) {
  int *const p = malloc(sizeof(int) * (alen + blen));
  int *it;
  for (it = p; it != p + alen; ++it) {
    *it = a[it - p];
  }
  for (/* it = p + alen */; it != p + alen + blen; ++it) {
    *it = b[it - (p + alen)];
  }
  return p;
}

static inline int* concat3(const int *a, size_t alen, const int *b, size_t blen) {
  int *const p = malloc(sizeof(int) * (alen + blen));
  memcpy(p, a, sizeof(int) * alen);
  memcpy(p + alen, b, sizeof(int) * blen);
  return p;
}

#define LENGTH(array) sizeof(array)/sizeof(*array)

static inline void dump(const int *array, size_t size) {
  const int *const end = array + size;
  while (array != end) {
    printf("%d ", *array++);
  }
}

int main() {
  int a[] = {1,2,3,4};
  int b[] = {8,9,10};

  int *const p1 = concat1(a, LENGTH(a), b, LENGTH(b));
  int *const p2 = concat2(a, LENGTH(a), b, LENGTH(b));
  int *const p3 = concat3(a, LENGTH(a), b, LENGTH(b));

  dump(p1, LENGTH(a) + LENGTH(b));
  puts("\n----");
  dump(p2, LENGTH(a) + LENGTH(b));
  puts("\n----");
  dump(p3, LENGTH(a) + LENGTH(b));

  free(p1);
  free(p2);
  free(p3);

  return 0;
}
```
プロキシ環境下のHyper-Vが利用できないWindows7でDockerを使うときのメモ

# 経緯

ローカルの検証環境としてDockerを利用したかったのですが、複数の問題があり苦戦しました。そのときのメモです。

# 状況

* プロキシ環境下(こいつのせいで苦労を…！)
* 支給されているPC(Windows7)がHyper-Vが利用できない

# ツールの選定

Hyper-Vが利用できない為、[Virualbox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp)+[Dockertoolbox](https://github.com/docker/toolbox/releases)の組み合わせを選定しました。
使えていれば、Docker for Windowsを使えば済んだ気がします。

# セットアップ

## 各ツールのインストール

デフォルト設定でインストールすれば大丈夫でした。

## Dockerマシンの作成

プロキシが絡んでいるので、少し手を加える必要があります。

### start.shの編集

Dockertoolboxのインストール先(デフォルトはProgramFile配下)にstart.shというスクリプトがあるので、スクリプト冒頭部分でプロキシ用の変数を宣言します。

```shell
#!/bin/bash

export HTTP_PROXY=http://[プロキシホスト]:[プロキシポート]  # 追記
export HTTPS_PROXY=${HTTP_PROXY}                    # 追記
```

### docker-machine create

コマンドプロンプトで実行します。(ここ重要)

```winbatch
> SET HTTP_PROXY=http://[プロキシホスト]:[プロキシポート]
> SET HTTPS_PROXY=http://[プロキシホスト]:[プロキシポート]
> docker-machine create -d virtualbox default
```

start.shのプロキシ設定がきちんと働いていれば、無事に作成されるはず。
一旦、コマンドプロンプトを終了します。

### Docker Quickstart Terminalの設定

今後は一緒にインストールされたこっちのターミナルで作業することにします。
とりあえず、このターミナルにもプロキシ設定を導入してあげます。
ターミナルを起動します。

```bash
$ vi .bash_profile
--- 以下を追記 ---
export HTTP_PROXY=http://[プロキシホスト]:[プロキシポート]
export HTTPS_PROXY=${HTTP_PROXY}
export NO_PROXY=localhost,127.0.0.1,192.168.99.100
--- ここまで ---
$ source .bash_profile
```

上記で `NO_PROXY` に指定してる `192.168.99.100` はDockerマシンの仮想環境が利用するIPです。(docker-machine lsで確認可能)

### 仮想マシンのプロキシ設定も更新

```bash
$ docker-machine ssh
--- 仮想環境に入る ---
$ sudo vi /var/lib/boot2docker/profile
--- 以下の追記 ---
export HTTP_PROXY=http://[プロキシホスト]:[プロキシポート]
export HTTPS_PROXY=$HTTP_PROXY
export NO_PROXY=localhost,127.0.0.1,.sock
--- ここまで ---
$ sudo /etc/init.d/docker restart
$ exit
--- 仮想環境から抜ける ---
```

## やっとDockerが使える…が

docker buildで通信するときに死にます…。
ので、Dockerfileでyumとか使う場合は、以下の記載をお忘れなく！

```docker
ENV HTTP_PROXY http://[プロキシホスト]:[プロキシポート]
ENV HTTPS_PROXY ${HTTP_PROXY}
ENV http_proxy ${HTTP_PROXY}
ENV https_proxy ${HTTP_PROXY}
```

小文字の変数も用意してあげないと、rpmやらyumやらでコケるようです。

# あとがき

同じような環境で導入に苦しんだ方のヒントになればと思います。
結構、試行錯誤したので、誤っている内容があるかもしれませんが、大体の設定した箇所のメモとなります。
UbuntuのLaravelが.envを読み込まない

ようやくLaravelとの戦いもほぼ終焉。デプロイするだけなのに。。。

# .env読まない問題。

.envにどれだけ書いていても、app.nameはLaravelに。
app.nameだけならいいけど、いろんなところに定数使ってるのでちょい困る。

もちろん、config.phpでも代用できるけど、できれば.envで管理したい。

## 権限の問題？

755とか、777とかまで試してみたけど、変わらない。

## キャッシュのせいの人も多いっぽい

```
php artisan config:clear
```

```
php artisan config:cache
```

どちらか使おう。したは、さらにcacheも作っておいてくれる。

僕はだめだった。

## envファイルの書き方が悪い？

envファイルの書き方（とくに空白の使い方）が悪いと、影響が出るらしい。


`SITE_NAME=My website`
ではなく
`SITE_NAME="My website"`

と書こう。ただ、これは既に知っていた上で上手く行ってない。


## php artisan serveで対処法があるらしい

```
php artisan serve --port=8000 --host=0.0.0.0 &
```

これでいけるとの噂
プロセスが立つので、チェックしよう。

```
ps awux | grep -v grep | grep php
```

僕はこれでいけた。env反映。

ダメだった人はkillしよう。

```
kill プロセスID
```

## 参考

https://stackoverflow.com/questions/34420761/laravel-5-2-not-reading-env-file
document.allという名の亡霊

JavaScriptは、「Don't break the web」ということを念頭に、仕様拡張なども構成されていっているのですが、時として妙なものも発生してしまいます。

# falsyな値

JavaScriptにはfalsyな値が7つ（`0`、`-0`、`NaN`、`false`、`null`、`undefined`、`''`）ある、ということは有名かと思います。…で、[MDN](https://developer.mozilla.org/ja/docs/Glossary/Falsy)を見てみると、8つ目の値が存在します。それが、`document.all`です。

# 仕様としての挙動

通常のJavaScriptにfalsyとなるオブジェクトは存在しませんから、明らかに目立つ挙動なのですが、[WHATWGの仕様](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlallcollection-interface)を参照してみると、さらにすごい挙動をするとのことでした。

* `typeof document.all === 'undefined'`
* `document.all == null`、`document.all == undefined`（`===`では等価になりません）
* `document.all(引数)`のように呼び出すこともできる

「配列のようなオブジェクト」は数多くありますが、`document.all`はさしずめ「`undefined`のようなオブジェクト」、ということになってしまいます。

## どうしてこうなった？

かつてはIE独自プロパティとして知られた`document.all`ですが、使い方として（あまりよろしくない面もありますが）2通りのコードが存在していました。

* `if(document.all)`のように判定してIEの処理に分岐するもの
* 存在チェックをせずに`document.all`を使うもの

後にIE以外のブラウザでも互換上`document.all`が実装されることとなったのですが、`if`チェックに対応するために、本来のJavaScriptの仕様にはない「falsyなオブジェクト」として実装された、とのことです。あまりに特殊なこともあって、ECMAScriptの仕様書にまで[追加仕様](https://tc39.github.io/ecma262/#sec-IsHTMLDDA-internal-slot)が書かれています。

> There are no other known examples of this type of object and implementations should not create any with the exception of `document.all`.

そりゃそうだ、こんなオブジェクトが他にあったら泣きたくもなるし。

# 結論

「Don't break the web」のためにはECMAScriptの仕様まで曲げてしまう、ときもある。
Ruby on Rails でメモアプリを作ってみた　（1：概要編）

  たかが「メモ」、されど「メモ」。ちょっとしたメモから、思わぬ発見があったりアイデアが膨らんだりすることがあるので、それを何とか形にして自分用に作ってみたいと思って挑戦しました。
 

 
#   :arrow_right:  概要
 
 　 あくまで**「メモをする」**という位置づけでその行為に集中できるようにするため、同期や締め切り、タグ付け等といった高度な機能を極力省き、必要最小限の機能を搭載したアプリを作る。主な機能は二つに絞って開発を進めた。
  


- メモ機能
　
 　メモアプリのメイン機能。「タイトル」と「内容」の二つの入力項目を設けている。「メモ」ではあるが、アイデアを膨らませたりまとめたりできるよう、内容の項目に関しては `textarea` タグでたくさん書けるようにした。
  　
　

- コメント機能
　
 　メモアプリのサブ機能。作成されたメモの詳細画面に行くと、コメントが入力できるようになっている。メモ内容に書くまでもないちょっとしたことを書くスペースで、いわゆる仮置き場のような感じ。**とっさに思い付いたものを素早く入力できること**に重点をおいているので、入力したコメントは編集を行わず削除のみとした。




#   :pager: 機能

|機能 | 項目 | 
|:------------:|:------------|
|メモ      | 新規、一覧、詳細、編集、削除|
|コメント     | 新規、削除、※（詳細）|
|その他 1    | メッセージ（サクセス、エラー、確認） |
|その他 2   | バリデーション(必須項目、文字制限) |


※ 詳細画面を経て削除を行う


#:paperclip: MVC

 
###**Model**

　モデルは Memo と Comment の二つを用意しカラムは以下のようにする。（id ,created_at,updated_at は自動的につくので割愛）
　

| Model | title |content|comment |memo_id|
|:------------:|:------------:|:------------:|:------------:|:------------:|
|Memo     |○ |○ |　 |　| 
|Comment |　 |   |○ |○ |

### :link: データの紐づけ
 
  Memo の id と Comment の memo_id  を紐づけることで、各メモごとに対応したコメント表示することができる。


###**View**


　各機能に応じたビューを作成するが、ヘッダーの部分はメモ一覧にリンクしたタイトルとメモの新規作成のみとし、それをテンプレートとして使用する。Rails での開発なのでスタイリングに関しては触れないこととする。



###**Controller (routes)**

　コントローラーは memo , comment を用意し、アクションに応じてデータやメッセージの受け渡しを行うこととする。用意するアクションは下図の通り。
 
| | index|new|create|show|edit|update|delete|
|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
|memo      |○ |○ |○ |○|○ |○ |○ |
|comment |    |   |○ |○ |    |　 |○ |　


---

　これは開発した後のメモアプリを整理して書いたものになります。最初から設計して開発したということではありませんのでご了承ください。

　今は一通り完成してあり、特に問題なく使えているので個人用として使用しています。

---

※ 参考にしたもの

機能　→　ドットインストール
コードの組み立て　→ Progate がメイン
Fortranで(a==1 && a==2 && a==3)を真にする（別解）

# 概要
(a ==1 && a== 2 && a==3)が真になるようなプログラムを，静的変数を使って実装したので投稿します．
Fortranの静的変数の宣言に驚くことと思います．

# 背景
[前回の記事](https://qiita.com/implicit_none/items/a925a077d56f78c4ccc0)において，StackOverFlowで話題になっていた(a ==1 && a== 2 && a==3)が真になるようなプログラムをFortranで作りました．Fortranの規格あるいはコンパイラの実装の穴をつくような方法でしたので，別解として，穴をつかない方法で実装しました．この実装には静的変数を使いますが，Fortranでは静的変数の宣言の方法がC言語系統の言語とは異なります．配列が1始まりであるとか列優先であるとかで移植の際に色々と論争を巻き起こしますが，この静的変数の方が奇妙だと思っています．

# 実装
前回の記事と同じく派生型StrangeIntを使い，比較演算子`==`をオーバーロードします．比較演算を実行する型束縛手続`Equals`内では，正直にStrangeIntの値を変化させるのではなく，静的変数を宣言してその値と右辺値を比較するようにします．細かい実装については[前回の記事](https://qiita.com/implicit_none/items/a925a077d56f78c4ccc0)を参考にしてください．

```Fortran:class_StrangeInt.f90
module class_StrangeInt
    implicit none
    private
    
    type,public :: StrangeInt
        integer :: value

        contains

        procedure,private,pass :: Equals
        generic :: operator (==) => Equals
    end type StrangeInt

    contains

    function Equals(this,criterion) result(isEqual)
        implicit none
        class(StrangeInt),intent(in) :: this
        integer,intent(in) :: criterion

        logical :: isEqual
        integer :: i = 0

        i = i + 1
        isEqual = (i == criterion)
    end function Equals
 end module class_StrangeInt
```

戻り値を格納する論理型変数`isEqual`の下に整数型変数`i`を宣言し，1を足し，`(i == criterion)`で右辺値と比較した結果を返します．特に難しいことをしているわけではありませんが，C言語系統に習熟している人が見ると，おや？と思うのではないでしょうか．

## Fortranの静的変数
おや？と思うのは`i`の変数宣言の所だと思います．C言語では，型名だけで宣言すると自動変数となり，変数が存在している関数が終了すると自動で解放されます．そして，宣言時に代入をしていると，実行毎にその値で初期化されます．関数を抜けても値を保持するようにするには，`static`を付けて静的変数として宣言する必要があります．つまり，

```C
    int a = 0; //自動変数．寿命は関数が終わるまで．呼び出される度に0で初期化される．
```

```C
    static int a = 0; //静的変数．寿命はプログラムが終わるまで．0で初期化されるのは1度だけ．
```
という違いがあります．

Fortranでは，**関数・サブルーチン内で変数宣言時に値を代入すると，その変数は静的変数になります．**つまり，

```Fortran
    integer :: a = 0 !静的変数．寿命はプログラムが終わるまで．0で初期化されるのは1度だけ．
```

```Fortran
    integer :: a !自動変数．寿命は関数が終わるまで．
    a = 0        !関数が呼び出される度に0で初期化される．
```
ということです．

複数の言語をさわる人は知っておいた方がよい知識でしょう．
ちなみに，Fotranには明示的に静的変数を宣言する`save`属性があるので，

- 基本的には変数宣言時に値を代入しない
- save属性を付与して静的変数である事を明示する場合のみ，宣言時に値を代入する

というルールを設けた方がよいと考えています．

# 動作テスト
前回の記事と同じメインルーチンを書いて実行してみましょう．

```Fortran:main.f90
program main
    use class_StrangeInt
    implicit none

    type(StrangeInt) :: a

    if(a==1 .and. a==2 .and. a==3)then
        print *,"TRUE"
    end if
end program main
```

StrangeInt型の変数`a`の値は全く参照しないので，代入すらしていません．
実行すると

```console
 TRUE
```
と表示され，この方法でも`(a==1 .and. a==2 .and. a==3)`を真にすることができました．

# まとめ
前回の記事に引き続き，`(a==1 .and. a==2 .and. a==3)`が真になるようなプログラムのFortranで実装しました．派生型を宣言して比較演算子`==`をオーバーロードし，比較演算を実行する型束縛手続内で静的変数と右辺値を比較するようにしました．
併せてFortranではローカル変数の宣言時に値を代入すると静的変数になるということも説明しました．古いFORTRAN/Fortranプログラムを他言語に移植しなければならず，四苦八苦している人の一助になれば幸いです．
Gethで同期している時に特定のブロックが壊れてしまった時の対策

題名通り。
再度同期しなければならないのか... と悩んでたんですが、有識者の方に質問したら「消せばいいんじゃない？」との意見あり気が付きまして、調べたところ方法有りましたのでー。

# 症状

`BAD BLOCK` と出ているためブロックが壊れているようだ。

```
ERROR[01-17|05:30:55]
########## BAD BLOCK #########
Chain config: {ChainID: 1 Homestead: 1150000 DAO: 1920000 DAOSupport: true EIP150: 2463000 EIP155: 2675000 EIP158: 2675000 Byzantium: 4370000 Engine: ethash}

Number: 4891520
Hash: 0xf1921222bd4ded689c16bdb995744a762e47c45d5f4c4d4ded721ad9ff9a3ab2


Error: nonce too high
##############################

WARN [01-17|05:30:55] Synchronisation failed, dropping peer    peer=9de1cabecb6526cd err="retrieved hash chain is invalid"
ERROR[01-17|05:31:10]
########## BAD BLOCK #########
Chain config: {ChainID: 1 Homestead: 1150000 DAO: 1920000 DAOSupport: true EIP150: 2463000 EIP155: 2675000 EIP158: 2675000 Byzantium: 4370000 Engine: ethash}

Number: 4891520
Hash: 0xf1921222bd4ded689c16bdb995744a762e47c45d5f4c4d4ded721ad9ff9a3ab2


Error: nonce too high
```

# 対策
壊れたブロックを消すか再度同期して正しいものにすればいい。

consoleモードで起動すること。

## 方法

Headを動かす方法

```
> debug.setHead('0x16E360')
```

`0x16E360` の箇所はBlockNumberを16進数で書く必要あり。

参考: https://github.com/ethereum/go-ethereum/issues/14435


以上φ('ᴗ'」)
Rails5.0：アプリの名称を変更する



`rails new`コマンドで作成したアプリの名称を変更したい時に、変更するファイル。

## 環境

* Rails：5.0.3
* Ruby：2.4.2

## 変更箇所

下記の2箇所。

* config/application.rb

```ruby
module Sampleapp	<------------
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.
  end 
end
```

* config/initializers/session_store.rb

```ruby
Rails.application.config.session_store :cookie_store, key: '_sampleapp_session'	<------------
```
Drupal8の拡張機能（基本的なもの）

#External Links
https://www.drupal.org/project/extlink
![2018-01-23_12h51_41.png](https://qiita-image-store.s3.amazonaws.com/0/174634/683a607c-140b-6548-c14a-04ddf630c80a.png)

/admin/config/content/formats/manage/basic_html
URLをリンクに変換にチェック

#CSS Editor
https://www.drupal.org/project/css_editor
テーマの設定でCSSが書けるようになる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174634/4ec7cd4d-8e87-597f-a3e1-bbaf97207cdd.png)

#PHP Authentication shield
https://www.drupal.org/project/shield
サイトにBasic認証をかける

#Google Analytics
https://www.drupal.org/project/google_analytics
Google アナリティクスのコードを有効にする

#CKEditor CodeSnippet
https://www.drupal.org/project/codesnippet
文章中にコードを貼り付ける

1. https://ckeditor.com/cke4/addon/codesnippet からプラグインをダウンロードする
2. ルートに/librariesディレクトリを作成し、codesnippetをディレクトリごとアップロードする
3. 機能拡張からCodeSnippetを有効にする
4. /admin/config/content/formats から設定をクリックし、CodeSnippetのボタンを加える
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174634/cdeb17fb-0811-4c92-d1e8-a6f5ea1fa1e5.png)

プラグインの設定をする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174634/5a2461c8-d49e-c04c-9d0f-d7ec6bfe80d7.png)

#CKEditor Upload Image
https://www.drupal.org/project/ckeditor_uploadimage
エディタにドラッグアンドドロップで画像を貼れるようにする

1. 以下のCKEditorプラグインをダウンロード
http://ckeditor.com/addon/uploadimage
http://ckeditor.com/addon/uploadwidget
http://ckeditor.com/addon/filetools
http://ckeditor.com/addon/notification
http://ckeditor.com/addon/notificationaggregator

2. /libraries/ckeditor/pluginsのディレクトリを作成。
解凍し/libraries/ckeditor/plugins/にフォルダごとアップロードする

3. CKEditor Upload Imageモジュールをインストールする
4. /admin/config/content/formatsにアクセスし、設定をクリック
5. プラグインの設定をする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174634/43ba722c-f5e8-5a34-d9ed-2a54062baf1b.png)

6. このサイトにある画像に制限する、のチェックを外す
7. 許可する HTML タグを制限し HTML のまちがいを修正するが有効な場合、フィルター設定のimgにdata-cke-saved-src data-cke-upload-id data-widget data-cke-widget-keep-attr data-cke-widget-data class data-image-style data-responsive-image-styleを加える