OmniAICreator/Qiita-1.07M huggingface dataset:
[扱いにくいコードについて考える] パラメータへの代入

# パラメータへの代入をやめる

## （What）パラメータへの代入とは何か？
### パラメータとは？
「パラメータ」は本来、振る舞いの特性を表す変数のこと。
「パラメタライズ」とは、パラメータを利用して振る舞いを制御する設計のこと。

ただしパラメータは引数というインターフェースを通して受け渡されることが多いので、パラメータと引数は混同されることが多い。


### パラメータへの代入とは？
メソッドに渡されたパラメータが参照するオブジェクトを変更すること。
メソッドに渡されたパラメータオブジェクトに対して、処理をすることとは異なる。

### 具体例は？
```パラメータへの代入をしている
private int calculate(boolean val, int year, int price, int taxRate) {
    if ( year > 2014) taxRate = 1.08;
    return price *  taxRate;
}
```

```これはパラメータへの代入ではない
private void multiplyQuotaBy(int multiplier, List<Salesman> list) {
  for (Salesman s : list) {
    int result = s.getQuota() * multiplier;
    s.setQuota(result);
  }
}
```

## （How）解決策？
```パラメータへの代入を解消した
private int calculate(boolean val, int year, int price, int taxRate) {
    int tax = taxRate;
    if (year >= 2014) tax = 1.08;

    return price *  tax;
}
```

## （Why）なぜパラメータへの代入が良くないのか？
まず、メソッド内でパラメータへ値を代入しても、メソッド外に変更が引き継がれない。
1. 明確さの欠如
2. 「値渡し」と「参照渡し」という混乱を招く元である

### 1. 明確さの欠如 
与えられたものの特性を表すためだけにパラメータを使用した方が、責務がはっきりしている。
代入を許可すると、以下のように責務が一つではなくなる。
1. パラメータとして特性を表す
2. メソッドの処理結果を表す

### 2. 「値渡し」と「参照渡し」という混乱を招く元である
ここはあまり説明がしっくりこなかったため、自分なりの考察です。

副作用的にオブジェクトを生成したり、値を操作したりする場合は引数を明示して返してあげた方が読みやすいため。

```処理内容が瞬間的にはわかりにくい
public static void main(String[] args) {
  List<Salesman> salesGuys = getSalesmen();
  multiplyQuotaBy(2, salesGuys);
  .
  .
  .
}

private void multiplyQuotaBy(int multiplier, List<Salesman> list) {
  for (Salesman s : list) {
    int result = s.getQuota() * multiplier;
    s.setQuota(result);
  }
}
```

```処理内容が瞬間的にわかりやすい
public static void main(String[] args) {
  List<Salesman> salesGuys = getSalesmen();
  List<Salesman> salesGuysWithNewQuotas = multiplyQuotaBy(2, salesGuys);
  .
  .
  .
}

private List<Salesman> multiplyQuotaBy(int multiplier, List<Salesman> list) {
  List<Salesman> resultList = new ArrayList<>(list);

  for (Salesman s : resultList) {
    int result = s.getQuota() * multiplier;
    s.setQuota(result);
  }
  return resultList;
}
```
Builderパターン

# Builderパターンとは
コンストラクタに対して数多くのパラメータをセットする必要がある時に、代わりに使うことが推奨されている実装方法。

ただしこれが推奨されるのは、コンストラクタに設定されるパラメータの内必須のものが少数である時に限られそうです。
理由は、実際に実装方法を見てから振り返って見ます。

# 様々なBuilderパターン
メジャーな実装方法に以下の二つがあります。それぞれ実装方法を見ていきます。
1. Effective Java
2. GoF

## そもそもBuilderパターンを使わない時のコンストラクタ

```
class People {
  String name;
  String sex;
  int age;
  
  People(String name, String sex, int age) {
    if (name == null || sex == null) throw new NullPointerException();

    this.name = name;
    this.sex = sex;
    this.age = age;
  }
}
```
#### Builderを使いたくなる理由
1. 引数が多くなると、順番を正確に覚えておくのが難しくなる。
    - つまり引数の渡し間違いが発生しやすくなる
2. 任意の値があると、適当な値をわざわざ渡す記述を書く必要がある。
    - つまり記述量が無駄に多くなる
    - ↑の例でいうと、 `age`は任意の値です。任意だけど、コンストラクタに引数として与えなければならない以上記述はしないといけないですね。無駄なことです。


## Effective Java
```
class People {
  String name;
  String sex;
  int age;
  
  static class Builder {
    String name;
    String sex;
    int age;
  
    Builder(String name, String sex) {
      if (name == null || sex == null) throw new NullPointerException();
      
      this.name = name;
      this.sex = sex;
    }
    
    Builder age(int age) {
      this.age = age;
      return this;
    }

    People build() {
      if (name == null || sex == null) throw new NullPointerException();

      return new People(this);
    }
  }
}
```

↑を使うクライアントのコードは↓になります。
```全てのフィールドに値を設定する場合
People person = new People.Builder("Test", "male").age(100).build();
```

```必須フィールドにのみ値を設定する場合
People person = new People.Builder("Test", "male").build();
```
任意のフィールドへの値の設定記述が、対象のフィールドを明確にできているのでわかりやすいです。
さらに、必須フィールドにのみ値を設定することもできるので余計な記述を減らせています。

## GoF
```
class People {
  String name;
  String hobby;
  int age;
  ...
}

class Director {
  private Builder builder;
  
  Director(Builder builder) {
    this.builder = builder;
  }
  
  void construct() {
    builder.name("Test");
    builder.age(100);
    builder.hobby("Tennis");
  }
}

interface Builder {
  void name(String name);
  void hobby(String hobby);
  void age(int age);

  Object getResult();
}

class PeopleBuilder implements Builder {
  private People people;
  
  PeopleBuilder() {
    this.people = new People();
  }

  @Override
  public void name(String name) {
    people.setName(name):
  }

  @Override
  public void hobby(String hobby) {
    people.setHobby(hobby):
  }

  @Override
  public void age(int age) {
    people.setAge(age):
  }

  @Override
  public Object getResult() {
    if (people.getName() == null || people.getHobby() == null) {
      throw new NullPointerException();
    }
    return this.people;
  }
}
```
↑を使うクライアントのコードは以下のようになります。
 ```
Builder builder = new PeopleBuilder();
Director director = new Director(builder);
director.construct();
People people = (People) builder.getResult();
```

こっちのBuilderパターンは、同じ方法でオブジェクトをなんども作成する時に便利そうです。
`Director#construct()`でどのようにオブジェクトを作成するかが定められているためです。

記述量が多くなってしまうのが特徴ですね。

# Builderパターンはどんな時に使えそうか？
やはりオブジェクトに与えるパラメータが以下の時には、あまりBuilderパターンは使えそうにないです。
1. とても多い
2. 全て必須

EffectiveJavaのパターンだと、必須パラメータをXXX.Builder()のコンストラクタ作成時に全て渡さなければならないことに変わりないです。
GoFのパターンだと、毎回決まったオブジェクトが作成されてしまうので、ユーザの情報によってオブジェクトのフィールド値を変更したい時は使えそうにないです。

ただ、引数がたくさんあるが、任意のものが多い時。同じオブジェクトを複数作成したい時はBuilderパターンが使えそうです。
[扱いにくいコードについて考える] 理解しにくいのってどんな時？

# なんのための記事か
ここでは自分が考える扱いにくいコード例を列挙し、それに対して自分なりに理由付けします。

## なぜするのか
今[リファクタリング](https://www.amazon.co.jp/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0%E2%80%95%E6%97%A2%E5%AD%98%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%89%E5%85%A8%E3%81%AB%E6%94%B9%E5%96%84%E3%81%99%E3%82%8B%E2%80%95-OBJECT-TECHNOLOGY-Martin-Fowler/dp/427405019X)の本を読んでいます。

自分の経験に紐づけて読み進めようと思い、まずは扱いにくいコードって何かということについて考えることにしたためです。

# 扱いにくいにくいコードとは？（「読みにくい」含む）
1. インデントが深い
2. 条件分岐が多発している
3. メソッドが長い
4. メソッドに返り値がない
5. メソッドの名前から直感的に処理内容がわからない
6. 共通化されすぎている
7. 記述が横に長すぎる
8. 名前が長すぎる
9. 巨大なクラス
10. クラス変数がいたるところで参照されている
11. 引数が多い

# それぞれの理由
## 1. インデントが深い
これが読みにくい理由は以下の4点かと思います。
1. 記述が横に長くなる傾向になるから
2. 処理の内容に加えて条件についても考える必要があり、頭の中での処理内容が多くなるため。
3. 条件分岐で関係ないところについては、理解の度合いが関係あるところに比べて浅くなります。馴染みの浅いコードを見ると心理的に負担がかかるから？
3. 単純に条件分岐について考えるのは頭にかかる負荷が大きい？


通常の処理ならインデントはだいたい揃います。
インデントのずれが発生するのは、通常の処理ではなく条件分岐が発生している時が多いです。
例えば以下のような感じ。

```インデントが深くなる時.java
methodA();
methodB();
if (どこかの画面から遷移してきた時) {
  if (name != null) {
    switch(largeCategoryId) {
      case C:
        methodC();
        break;
      case D:
        methodD();
        break;
    }
  }
}
```
普通にありえそうですね。nullチェックとswitchを使うとインデント深くなっちゃうので、なんとかしたいです。

## 2. 条件分岐が多発している
1. 条件を判定する処理は頭に負担がかかる
2. 条件の組み合わせを覚えるのが大変
3. 記述が横に長くなっていく
4. 変更する時に、条件分岐を変更するのはかなりデリケート。単純に条件を追加するだけ？どこかの条件分岐が一緒になったりする？
5. コードが詰まっているように見える。（改行すれば解消されるかもしれないですが、変な改行を入れると無意味に見えるので、それはそれでコードが冗長に見えてしまう）

```条件分岐が多発している.java
if (age >= 20) {

  if (gender == male) { // この一行上の改行は意図がわからないので、冗長に見える
    methodA();
  } else {
    methodB();
  }
} else if (age == -1) {// かといって↓のように改行を全くしないと詰まって見えるので読みづらい
  if (gender == male) {
    methodC();
  } else {
    methodD();
  }
} else {
  methodE();
}
```
## 3. メソッドが長い
1. メソッドを読み終わるまで、内容を一通り覚えておく必要がある。メソッドが長いと、覚えておく必要があることが増えて脳に負担がかかる。
2. 読み始めるのにかなりの決意を必要とする。そのため心理的に負担がかかる。
3. 再利用が難しい。

## 4. メソッドに返り値がない
1. 何をするメソッドなのか内容を読まないとわからない。

```最終的にboolean値を返す処理の例（各メソッドに戻り値がない場合）
int sum = 1;
boolean result = false;
String value = "";

methodA();
methodB(value);
methodC(sum);

return result;
```

```最終的にboolean値を返す処理の例（各メソッドに戻り値がある場合）
int sum = 1;
boolean result = false;
String value = "";

value = methodA();
sum = methodB(value);
result = methodC(sum);

return result;
```

例としては全く適当なメソッドを並べただけですが、返り値があるだけでなんとなく各メソッドの処理内容が予想できます。
そのため、各メソッドを読み始める時の心理的負担が低くなります。

## 5. メソッドの名前から直感的に処理内容がわからない
1. メソッドの内容をきっちり覚える必要があるため、脳に負担がかかる
2. 軽く読み流したい場所でも、ちゃんと読まなきゃいけなくなるため、脳に負担がかかる

## 6. 共通化されすぎている
きちんと共通化できるところならいいのですが、無理やりやっていると以下のようなことが起こります。
1. 条件分岐が多くなる。
2. クラスの場合は、クラス、メソッドそれぞれ命名が最適化されないのでコードを読まないとわからないところが多くなる。
3. 条件分岐が多くなるので、不要な処理もそれだけ増えます。そのためクラスも肥大化しやすい。

## 7. 記述が横に長すぎる
1. 意識的に目で追う範囲を広げなければならないので、考えることに割くエネルギーがその分減る
2. 画面内に入らない場合には、画面を指で横スクロールしなければならないので、考えることに割くエネルギーが減る
3. 対象の行の行末を読んでいる時に、左に何が書いてあったかを意識する必要があるので、脳に負担がかかる

## 8. 名前が長すぎる
1. 記憶する情報量が多くなるので、脳に負担がかかる

## 9. 巨大なクラス
1. 読まなきゃいけない量が単純に多くなるので、脳に負担がかかる
2. 読み始めるために、かなりの決意が必要になるので、心理的に負担がかかる

## 10. クラス変数がいたるところで参照されている
1. コードを変更すると、思わぬところで副作用が発生する可能性がある


## 11. 引数が多い
1. 渡すべき引数を渡し忘れる可能性大
2. 渡すべき順番を覚えられない
3. 再利用しづらい
Javaの値渡しと参照渡し

## 基本型
Javaのメソッドの引数に与えられる値は基本的に値渡しです。
値渡しというのは、引数に与えられた値がコピーされるということです。
なので、メソッド内で引数に対して変更が加えられても、それは引数のコピーに対して変更を加えていることになります。

そのため、以下のような動きになることは理解できると思います。

```Java:値渡しを一番理解しやすいプログラム
int count = 8;
plus(count);
Log.d(count);

void plus(int value) {
    int result = value * 2;
    Log.d(result);
}
```

```text:結果
after applying plus 16
outside of method plus 8
```

## 参照型
参照型を引数に渡すと、参照値がコピーされます。

以下のコードで言えば、左辺が参照値で右辺が実際の値です。
左辺の参照値というのは例えていうと、右辺の実際の値が格納されているメモリの番地のことです。

```java
List<String> list = new ArrayList<>();
```

`東京都千代田区千代田１−１`には皇居があります。
`東京都千代田区千代田１−１`が参照値で、皇居が実際の値みたいな関係です。

上記を踏まえて、以下のプログラムを考えてみたいと思います。

```Java:メソッド内の変更が、メソッド適用後にも反映されているプログラム
List<String> japanese = new ArrayList<>();
japanese.add("すぎた");
plusElementJ(japanese);
Log.d(japanese.toString());

void plusElementJ(List<String> list) {
    list.add("おはよう");
    Log.d(list.toString());
}
```

```text:結果
[すぎた, おはよう]
[すぎた, おはよう]
```

上記のプログラムでは、一二行目で `東京都千代田区千代田１−１`に皇居があることを宣言しています。
メソッドに`東京都千代田区千代田１−１`の住所を渡します。
メソッド内では、受け取った住所に対して、増築を行いました。
すると、メソッドをでても、`東京都千代田区千代田１−１`には皇居とそれを増築した結果があるのは納得できましたね。

## Stringも参照型だけど。。。

```Java:メソッド内での変更がメソッド適用後に反映されていない
String name = "すぎた";
concatenate(name);
Log.d(name);

void concatenate(String name) {
    name = "おはよう、" + name;
    Log.d(name);
}
```

```text:結果
after applying concatenate おはよう、すぎた
outside of method concatenate すぎた
```

Stringは参照型ではありますが、immutableです。つまり変更不可能です。
そのため、この処理は内部的には以下のように新しいStringオブジェクトが作られているんじゃないでしょうか？

```java
name = new String("おはよう、"  + name)
```

そのため、以下のようなことが起こっていると思います。

1. コピーされている参照値 `name`には新しい参照値が代入される
2. `name`が新しく参照している参照値に新しくオブジェクトが作成される

## 参考

 [もう参照渡しとは言わせない](https://qiita.com/mdstoy/items/2ef4ada6f88341466783)
[Gitの使い方]ブランチ名の変更

# Why?
単純にブランチ名が適当じゃない時に、変更したいから。
例えば、以下のような状況がありえると思います。
1. チケットの作業する前にまずリファクタリングして見た。
2. そしたら思いの外リファクタリングが多くなった。チケット作業とリファクタリングを同時に出すのは違うなって思った。
3. チケット作業のためのブランチ名にしていたけど、リファクタリングのためのブランチ名にしたい。チケット作業用のブランチは別に作りたい。

# How
```change branch name
$ git branch -m <old_name> <new_name>
```
今開いているブランチ名を変更する時はもっと簡単で以下のようにするとできます。

```change current_branch name
$ git branch -m <new_name>
```
xlwings.Book 簡易リファレンス

# はじめに

これは xlwings 0.11.5 [本家xlwings.Books](http://docs.xlwings.org/en/stable/api.html#books) [本家xlwings.Book](http://docs.xlwings.org/en/stable/api.html#book) の簡易日本語リファレンスである。

# xlwings.Books

Books はアプリ環境に含まれるブックを管理する。
[VBA:Workbooks](https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/workbooks-object-excel) に相当する。

```python
import xlwings as xw
bks = xw.books       # アクティブアプリケーションのブック管理インスタンスを返す
bks.active           # アクティブブックを返す VBA:ActiveWorkbook
bks.add()            # 新規Bookインスタンス作成し返す
bks.open('ブック名')  # ブックを開く、すでに開いている場合はそのBookインスタンスを返す
bks['ブック名']       # bks[0] 添え字指定も可能 Bookインスタンスを返す
bks('ブック名')       # bks(1) インデックス指定も可能 Bookインスタンスを返す
bks.count            # Bookインスタンス数を返す
```
api プロパティーはない

# xlwings.Book

Book は単一のブックを管理する。
[VBA:Workbook](https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/workbook-object-excel) に相当する。

```python
xw.Book()                      # 新規ブックを作成する
xw.Book('ブック名')             # ブックを開く、すでに開いている場合はそのBookインスタンスを返す
xw.Book.caller()               # 呼び出しExcelのBookインスタンスを返す VBA:ThisWorkbook
bk.set_mock_caller()           # 呼び出しExcelのBookとして扱う
bk.activate(steal_focus=False) # ブックをアクティブにする

bk.fullname                    # フルパスブック名を返す
bk.name                        # ブック名を返す

bk.close()                     # ブックを閉じる
bk.save(path=None)             # ブックをセーブする

bk.open_template()             # 下記リンク先を参照

bk.app                         # xw.App() を返す
bk.names                       # xw.Names() を返す
bk.sheets                      # xw.Sheets() を返す

bk.api                         # ネイティブインスタンスを返す
```

[bk.open_template()](http://docs.xlwings.org/en/stable/api.html#xlwings.Book.open_template)
SAP Note を wget でダウンロードする。

# はじめに
SAP ABAPシステムに対して、SAP Note を**オフライン(SAPNETの接続なし)**で適用する場合、Tr-cd:`SNOTE` 向けにテキストベースのNoteをサポートポータルからダウンロードする必要がある。

Noteが1、2個であれば手動ダウンロードでも問題ないが、10個、20個だと手動ダウンロードは時間と手間がかかりつらい。

そこで、`wget` と SAP Passport(実態はクライアント証明書)を利用して、コマンドベースでNoteを取得する方法を探した。

※2018/01現在、有効な方法であることを確認

# 作業環境

```shell-session
# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

# rpm -qa | grep openssl
openssl-1.0.2k-8.el7.x86_64

# rpm -qa | grep wget
wget-1.14-15.el7.x86_64
```

#事前準備
## SAP Passport の入手
以下のサイトにアクセスし、SAP Passportを入手する。
（すでに発行済みでPKCS#12形式のクライアント証明書を保持している場合は省略可）

https://launchpad.support.sap.com/#/sappassport
※Sユーザでのログイン必須

## SAP Passport を作業環境へアップロード
入手に成功するとPKCS#12形式でクライアント証明書がローカルPCにダウンロードされる。
ダウンロードされたファイル（`<SID>.pfx`）を作業する環境にアップロードする。

※今回はLinux環境を使用しているが、Windowsでも同様のことは可能。なはず。。。（未検証）


## 証明書をPKCS#12形式からPEMに変換
`man wget` によると、`wget` はクライアント証明書、CA証明書、秘密鍵をそれぞれファイルで指定する必要がある。
形式はデフォルトが`PEM`、オプション指定で`DER`にも対応しているようだが、今回はデフォルトの`PEM`を利用することとする。


```shell-session
# SAP Passport ファイルの確認
$ ls -l
-rw-r--r--. 1 user uesr  3100 Jan 23 13:08 <SID>.pfx

# クライアント証明書
$ openssl pkcs12 -in <SID>.pfx -nokeys -clcerts -out client_cert.crt.pem
Enter Import Password: <SAP Passport入手時に入力したパスワード>
MAC verified OK

# CA証明書
$ openssl pkcs12 -in <SID>.pfx -nokeys -cacerts -out ca_cert.crt.pem
Enter Import Password: <SAP Passport入手時に入力したパスワード>
MAC verified OK

# 秘密鍵
$ openssl pkcs12 -in <SID>.pfx -nocerts -nodes -out client_cert.key.pem
Enter Import Password: <SAP Passport入手時に入力したパスワード>
MAC verified OK
```

# SAP Note(SNOTE向け)のダウンロード
`<NoteNo>` : ダウンロードするNote番号を指定する。 

```shell-session
$ wget --certificate=client_cert.crt.pem --private-key=client_cert.key.pem --ca-certificate=ca_cert.crt.pem -O <NoteNo>.SAR https://apps.support.sap.com/sap/support/lp/notes/hcp/down4snote/down4snote.htm?iv_num=<NoteNo>&sap-language=EN
```

# 仕上げに
後はシェル化して 
1. `NoteNo` を外部ファイルから読ませダウンロード
2. `SAPCAR` で展開
3. `unzip` で展開

等とすれば、面倒なSAPNETなしのNote適用も少しは楽になるかも。。。


**※くれぐれもクライアント証明書の管理には注意を払うこと。**
CloudSQLのcloud proxyを使って接続する方法 メモ

## TcpSocketの場合
```
./cloud_sql_proxy 
-credential_file=credential.json  
-instances=cloudsql-incetance=tcp:3306 &
```

## UnixSocketを使う場合
socketを配置する場所を決める
`mdkir /cloudsql && chmod 777 /cloudsql/`

```setup.sh
PORT=3306
INSTANCE="incetance"
CREDENTIAL="credential.json"
./cloud_sql_proxy -instances=$INSTANCE -credential_file=$CREDENTIAL -dir=/cloudsql &
```

こんなのを作りました。

確認方法
`/cloudsql/instance_name`があると思います。


sequel proでの接続方法

<img width="642" alt="スクリーンショット 2018-01-23 14.07.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/65606/0f97f515-12b3-845b-7daa-efa497835892.png">
(a == 1 && a == 2 && a == 3) を常に真にできますか？ その2

ちょこっとバズっているので、僕も遅れないように流行りに乗ってみました。

前回: [(a == 1 && a == 2 && a == 3) を常に真にできますか？](https://qiita.com/Morichan/items/4894d7d92ecab7a3afd8)

簡単なあらましなどは他のサイトをご覧ください。

元ネタ: [Can (a ==1 && a== 2 && a==3) ever evaluate to true?](https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true)

まとめ: [(a==1&&a==2&&a==3)を常にtrueにするStackOverflowの問題を解いたQiita記事まとめ](https://qiita.com/aimof/items/bb786c112f7dcc3be6c9)

個人的に面白かった解法です。

* [C言語でa == 1 && a == 2 && a == 3をtrueにしてみたい](https://qiita.com/fujitanozomu/items/e4ab6f20837ed8234cd3): 並行処理で真偽値判定中に変数を変えるという発想は変態的過ぎる！
* [(a == 1 && a == 2 && a == 3) を常に真にする C#編 ～プロパティのgetterに副作用を持たせてはいけない。～](https://qiita.com/Marimoiro/items/983a966a01da23e2fdea): デバッガのバグは恐ろしい...
* [Python2で(a == 1 and a == 2 and a == 3) を常にTrueと等しくする魔法の一文(演算子はいじらない系)(ソース4行)](https://qiita.com/aimof/items/abc8a5859c928b198dfc): Python2の魔術
* [（ａ＝＝１＆＆ａ＝＝２＆＆ａ＝＝３）をtrueにするRubyスクリプト](https://qiita.com/aimof/items/bd4acfd310bcabff1538): 解く気がないもの感は好き
* [PHP で (a == 1 && a == 2 && a == 3) を常に真（true）にできますか？](https://qiita.com/KEINOS/items/b16acf11e3fe7b2fc438): PHP怖い
* [Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(真っ黒編)](https://qiita.com/Wreulicke/items/425601e0d2b754e1251a): コンパイラを騙せばコードなんて必要ないんや！



# なぜ再びやろうと思ったのか

そもそもの問題を突き詰めてみました。

> `(a == 1 && a == 2 && a == 3)`を常に真にできるか？

この文章には、実は2つの意味を含んでいます。

* `(a == 1 && a == 2 && a == 3)`という文字列を変えてはいけない
* 常に真でなければならない

つまり、前回の僕の答えでは、答えになっていなかったのです！



# ということで作ってみました。

みんな大好きPerlでどうぞ。

```pl:do_function.pl
use strict;
use warnings;

my $count = 1;

sub a {
    $count = $count > 2 ? 1 : $count + 1;
}

if (a == 1 && a == 2 && a == 3) {
    print "True!\n";
}
```

```bash:実行結果
$ perl do_function.pl
True!
```

Perlでは関数であることを示すために、シジルとして`&`を付けるか関数名の最後に`()`を付けます。
組込み関数名と被らない限りは`&`を省略できます。
また、コードの意味が変わらないのであれば関数名の最後の`()`を省略できるというPerlの規則により`()`も省略できます。

つまり、`a`というのは変数ではなく関数呼び出しです。

次に`a`関数を見ると、単に変数をインクリメントしているだけでなく、3以上の場合は1を返すようにしています。

これにより、何度呼び出しても同じように真を返してくれます。

```pl:do_function_twice.pl
use strict;
use warnings;

my $count = 1;

sub a {
    $count = $count > 2 ? 1 : $count + 1;
}

if (a == 1 && a == 2 && a == 3) {
    print "True first!\n";
}

if (a == 1 && a == 2 && a == 3) {
    print "True second!\n";
}
```

```bash:実行結果
$ perl do_function_twice.pl
True first!
True second!
```

これにより、問題の本当の正解を得ることができました！



# 終わりに

みなさん面白い解法を思いついてくれて、勉強になりました。
こういう遊びみたいなところに技術力が試されるのかもしれませんね。

ここまで読んでくださってありがとうございました！

もしおかしい点、気づいた点がありましたら教えてください。
特に、もっともっと面白い解法がある場合はぜひ投稿してください！
PHPの開発全般にLaradockを使えばいいんじゃないかという話

#まずLaradockについて

[Laradock](http://laradock.io/)はLaravel(PHP製のWebフレームワーク)用の(開発用)実行環境で、その名の通りDockerを使用した仮想環境です。
これが非常に良く出来ており、Laravel以外のPHP開発でもガンガン使っていけるのではないかと思ったので紹介させて頂きます。
（実際に公式サイトでもLaravel以外でも採用されていると記載されています）

Dockerがないと使用できないのがハードルといえばその通りですが、以下の理由からDocker使ったこと無い方にもオススメです。

- 基本的な使い方ならDockerの知識はほぼ不要
- Docker自体が有用なのでLaradockをきっかけにDockerを覚えるくらいの気持ちで導入しても損は無い

ということでこの記事は以下の方針で書いています。

- 導入方法については割愛して機能的な部分について紹介
- Docker使ったことないよって方でも差し支えないように記載

#Laradockの特徴

主な特徴としては、

1. PHPの開発で使う一通りのソフトウェアに対応
2. プロジェクト毎の環境の切替が容易
3. 複数バージョンのPHPに対応（7.1/7.0/5.6）
4. 環境の共有がイメージではなくコードベースでできる
5. 一元化された設定ファイルで各機能の設定が可能
6. 各機能は複数のコンテナ(仮想環境)に分割されており必要なものを任意に実行できる
7. 各機能を個別にカスタマイズすることもできる

などなど...

以下、各特徴を掘り下げていきます。

## 1. PHPの開発で使う一通りのソフトウェアに対応

LaradockではApache/nginx、MySQL/PostgreSQLといった各サーバーはもちろん、

- Composer、npm
- phpMyAdmin、pgAdmin
- Xdebug

などの各種ツールも同時に導入することができます。
（これらのツールも仮想環境上で実行されます）

## 2. プロジェクト毎の環境の切替が容易

開発環境を仮想化するメリットは色々ありますが、中でも「プロジェクト毎に独立した環境を用意して相互干渉を回避できる」というのは特に重要な動機になります。
これはVMを使用した他の仮想化でも実現できますが、LaradockではVM環境のように巨大なサイズのイメージをコピーして...みたいな作業は不要です。
Githubで配布されているソースファイルをクローンし、ディレクトリをプロジェクト固有の名前にリネームして実行するだけでOKです。

## 3. 複数バージョンのPHPに対応（7.1/7.0/5.6）

「プロジェクトによってPHPのバージョンが違う」というのもよくある仮想化の理由ではないでしょうか。
Laradockは設定ファイルの一箇所を書き換えるだけでバージョンを変更できます。
（※設定ファイルに関しては後述）

## 4. 環境の共有がイメージではなくコードベースでできる

前述のとおりLaradockはソースファイルとして配布されていますので、チーム内で環境を共有する場合もコードベースでOKです。
単純な環境なら設定ファイルの共有だけで済ませることもできますし、
独自のカスタマイズや設定変更が多いならならGitなどでバージョン管理することもできます。
変更の反映も「最新ファイルを落としてね再構築してね」で済みます。

## 5. 一元化された設定ファイルで各機能の設定が可能

Laradockでは複数のソフトウェアを動作させることができますが、
基本的な設定は「.env」というファイルに集約されています。
「.env」はよくある`設定項目=設定値`形式の設定ファイルで、こちらを書き換えていけばDockerとしての構成はあまり意識せずに設定変更を行うことが出来ます。
（PHPのバージョンやインストールする拡張機能、各サーバーの使用ポートなどが設定できます）

## 6. 複数のコンテナ(仮想環境)に分割されており必要なものを任意に実行できる

Laradockでは様々なソフトウェアに対応していますが、実際に使用する機能は個別に選択することができます。
これはLaradock（を起動するためのDocker）を実行する際にコマンドライン引数として指定するだけです。

たとえば、NginxとPostgreSQLを使ったWebアプリの場合は以下のようなコマンドになります

`docker-compose up -d nginx postgres`

## 7. 各機能を個別にカスタマイズすることもできる

「.env」では変更できないカスタマイズが必要であれば、Dockerで仮想環境を構築するためのソースファイルである「Dockerfile」を編集することもできます。
これはDockerの知識が必要になりますが、「Dockerfile」はコンテナ毎に分割されていますし、やっていることはCUIで行うサーバーの操作相当の内容なので、そのあたりの経験があればすぐに理解できるのではないかと思います。

# 不便な所とか

最後にそんなLaradockの不便だなと思う点について

## 初回起動時のビルドが長い

Laradockは初回起動時にソースファイルからイメージをビルドする必要があり、そこで時間がかかります。
コードベースでやり取りするできるメリットとのトレードオフなので仕方ない部分ではありますが。
どうしても気になるならDockerの機能で配布用イメージを作って運用という手段も取れます。

## アップデートが頻繁で構成が変わる可能性がある
最近は落ち着いたかなーと感じていますが、少し前までは対応ツールや設定項目の追加で構成が頻繁に変わっていました。
それ自体は良いことなのですが、設定ファイルの互換が失われる為にチーム内でちゃんとバージョンを揃えないとエラーで起動できないなどのトラブルもありました。

## 設定でつまづく
慣れの問題もありますが、ちょこちょこ設定の不足で手戻りが発生します。
仮想環境の再起動で済めばそれほど手間ではないですが、再ビルドを行わないと反映されない設定もあります（ツールや拡張機能のインストールなど）
例えば初期設定ではDB接続用のPHP拡張が無効になっており、これを有効にするのを忘れると再ビルドとなります。
（コンテナが分割されているので該当コンテナだけ再ビルドすればいいのが救い）

# まとめ
一言でまとめれば、「良いところも悪いところもコードベース故に」というところです。

そしてお気づきの方もいらっしゃると思いますが、紹介させて頂いたLaradockの特徴のほとんどが「docker-compose」というDockerの構成管理の仕組みの話になります。
ただ、多数の機能が使いやすくまとめてあるのはLaradockの中の人たちに感謝という他ありません。

以上、拙い文章でしたが少しでもLaradockについて知って頂けたなら幸いです。
スペースシップ演算子についてのメモ

Rubyのsortメソッドを使用していると、`<=>`の表記をよく目にする。
これはスペースシップ演算子（又は、宇宙船演算子）と呼ばれるものらしい。
2つの値を比較して下記の値を返す。


* 左辺の値よりも右辺の値が大きければ負の数
* 左辺の値と右辺の値が等しければ0
* 左辺の値が右辺の値よりも大きければ正の数

```ruby
1 <=> 2		# => -1
1 <=> 1		# => 0
1 <=> 0		# => 1
```

## 使用例

* 各配列の数値を昇順に並べる。

```ruby
%w(100 300 200 500 400 200).map(&:to_i).sort { |a,b| a <=> b }
# => [100, 200, 200, 300, 400, 500]
```

* 各配列の文字列から文字数の少ない順に並べる。

```ruby
%w(Alice Bob John FooBar).sort{ |a,b| a.length <=> b.length }
# => ["Bob", "John", "Alice", "FooBar"]
```

## 参考

[パーフェクトRuby](https://www.amazon.co.jp/dp/B00P0UR1CA/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
q - Text as Data でどこまでCSVがパースできるのか

RDBにしてもBigQueryにしても、インターフェースファイルとして登場するのはCSV。まだまだCSVを使えないとダメ。

CSVをみるのはExcelをつかうのがいいのだけれど、大きなCSVを手元のPCに持ってくるのはしんどい。サーバーサイドでCLIでCSVを読み取りたい。そこで、q コマンド。

q コマンドはCSVに対してSQLを発行できる。
でもCSVって言っても、いろいろ機能がある。

- ダブルクォートで囲むとフィールド内にカンマが入っても大丈夫だよね
- フィールド内のダブルクォートはどうやってエスケープする？（Excelだとダブルクォートでエスケープ）
- ダブルクォートで値をくくると、改行もありになるよね

このあたり、一回テストしてみよう。答えが知りたい人には先にお知らせします。以上のCSVの機能は全部カバーされている。

## まずは最低限のオプション

- ヘッダー行をフィールド名にするには -H オプションを付ける
- デリミタをカンマにするには -d, をつける

ということで、最低限のサンプルはこちら

```
$ q -H -d, "select * from filename"
```

## LF改行のCSV

```
$ cat lf.csv 
id,name,age
1,john,30
2,paul,31
$ q -H -d, "select name from ./lf.csv"
john
paul
```

## CRLF改行のCSV

```
cat crlf.csv 
id,name,age
1,john,30
2,paul,31
$ q -H -d, "select name from ./crlf.csv"
john
paul
```

## フィールドの中にカンマがあるケース

```
cat quote_comma.csv 
id,name,age
"1","jo,hn","30"
"2","paul","31"
$ q -H -d, "select name from ./quote_comma.csv"
"jo,hn"
paul
```
一応、フィールドの中のカンマはフィールド区切りではなく値として扱ってくれている。

## フィールドの中にクォーテーションが有るケース（エスケープ済み）

```
cat quote_escape.csv 
id,name,age
"1","jo""hn","30"
"2","paul","31"
$ q -H -d, "select name from ./quote_escape.csv"
"jo""hn"
paul
```

## フィールドの中に改行があるケース

```
cat quote_newline.csv 
id,name,age
"1","jo
hn","30"
"2","paul","31"
$ q -H -d, "select name from ./quote_newline.csv"
jo
hn
paul
```

## SJISのデータをみてみよう

```
$ cat sjis.csv 
id,name,age
1,?W????,30
2,?|?[??,31
2,?W???`?W,29
$ nkf -u sjis.csv 
id,name,age
1,ジョン,30
2,ポール,31
2,ジョ〜ジ,29
$ q -H -d, -eSJIS "select name from ./sjis.csv"
ジョン
ポール
ジョ〜ジ
$ q -H -d, -eShift-JIS "select name from ./sjis.csv"
ジョン
ポール
ジョ〜ジ
```

見える見える。SJISとShift-JISの両方でいける。

## BOMがあっても大丈夫？

```
$ more bom.csv 
<U+FEFF>id,name,age
1,john,30
2,paul,31
q -H -d, "select id from ./bom.csv"
query error: no such column: id
Warning - There seems to be a "no such column" error, and -H (header line) exists. Please make sure that you are using the column names from the header line and not the default (cXX) column names
```

ダメ。一番左のカラム名をBOMつきで指定しないとダメ。そして入力しずらいので、運用には乗らない。ここは成約として諦める。

ちなみに、BOMつきのUTF8は、Excel日本語版でも最初からUTF8として認識してくれるので、便利なのです。BOMつきUTF8のCSVならダブルクリックでExcelで開いても化けない。

## バックスラッシュが混じっても大丈夫？

```
$ cat backslash.csv 
id,name,age
1,"jo\""hn",30
2,paul,31
$ q -H -d, "select name from ./backslash.csv"
"jo""hn"""
paul
```

これ期待と違う、本当は ``jo\"hn`` であって欲しい。Excel方式では、バックスラッシュは意味を持たないが、ものによってはバックスラッシュをエスケープ文字扱いにしているのもある。これを防ぐには、「バックスラッシュをエスケープ文字扱いにしないでね」ってオプションが必要。

```
q -H -d, --disable-escaped-double-quoting "select name from ./backslash.csv"
"jo\""hn"
paul
```

これで、期待通り。つまりExcelベースのCSVをパースしたかったら、

```
q -H -d, --disable-escaped-double-quoting SQL
```

というのが基本。（なげー！）
SwiftのUILabelのDefaultのLineHeightは約1.2っぽい

# 環境
Swift 4
Xcode 9.2 (9C40b)

# 本題

タイトルが全てですが、実際に計測してみての結果なので正確な情報ではありませんが参考までに。

**SwiftのUILabelのDefaultのLineHeightは約1.2っぽい**
簡単なLinuxカーネルモジュール同士の依存動作

# 始めに

”Linuxカーネルは一つの大きなバイナリで構成されたモノリシックなカーネル（一枚岩カーネル）である。”
この記述は目にタコができるほど様々な記事や資料に書かれています。また、リーナス氏とタネンバウム氏のカーネル設計の議論については
あまりにも有名です。しかしながら、自分を含めた多数の開発者は決してLinuxは単なるモノリシックカーネルだとは思ってはいません。Linux Kernel Module(LKM)を駆使することで、モノリシックカーネルとは対称的なマイクロカーネルの良い点を引き出しています。
マイクロカーネルという設計方法は、タネンバウム氏が開発しているMINIX、GNU HurdやQNXはこれを採用しています。
それぞれの設計方法によってメリットデメリットがありますが、カーネルの設計方法における解説は他の記事におまかせすることにします。
ここではLinuxがマイクロカーネル的な要素を引き出しているLKMにおける協調動作について書いていこうと思います。

この記事の対象者はLinuxモジュールを1回でも作ったことがある人です。（細かい解説は行っていないので）
# 環境
Linuxディストリビューション: Fedora27 Workstation 64bit
Linuxカーネル: 4.14.13
Cコンパイラ: GCC 7.2.1

# 期待する結果
今回のゴールは、モジュールを2つロードさせ、片方のモジュールからもう一方のモジュールに定義された関数を呼び出すことです。
これを応用して、様々なことができそうでワクワクします。

# 実験
以下に適当なカーネルモジュールのソースをおいておきます。

elder.c -> 呼び出される側
little.c -> 呼び出す側

```c:elder.c
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("Dual BSD/GPL");

static int eld_init(void)
{
        printk("<eld> init\n");
        return 0;
}

static void eld_exit(void)
{
        printk("<eld> exit\n");
}

/*
 * little.cによって呼び出される関数
 */
void __eld_public_function(void)
{
        printk("<eld> Hi. I'm elder module.");
}
EXPORT_SYMBOL(__eld_public_function);

module_init(eld_init);
module_exit(eld_exit);
```

```c:little.c
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("Dual BSD/GPL");

/*
 * 呼び出す関数のプロトタイプ宣言
 */
void __eld_public_function(void);

static int little_init(void)
{
        printk("<little> init\n");

        // here!!
        __eld_public_function();

        return 0;
}

static void little_exit(void)
{
        printk("<little> exit\n");
}

module_init(little_init);
module_exit(little_exit);
```

これをmakeしてそれぞれelder.ko、little.koを作ります。

次にモジュールをロードしていきます。
当たり前のことなのですが、呼び出される関数が定義されているelder.koを先にロードします。

```sh
$ sudo insmod elder.ko     # 先にロード
$ sudo insmod little.ko    # 次にロード
```

littleモジュールの初期化関数で、__eld_public_functionを呼び出しているので、ロードした時点でこの関数は呼び出されています。
早速確認してみましょう。

```sh
$ dmesg | grep '<eld>'
[14037.256420] <eld> init
[14054.951514] <eld> Hi. I'm elder module.
```
この通り、littleモジュールからelderモジュールの関数を呼び出すことができました。

また、lsmodコマンドで情報を見てみます。

```sh
$ lsmod | grep 'little'
little                 16384  0
elder                  16384  1 little
```

これを見ると、elderは1個のモジュールに依存されており、そのモジュール名がlittleモジュールであるということがわかります。

モジュールをアンロードするときは、依存しているlittle側からアンロードする必要があります。

```sh
$ sudo rmmod little       # 先にアンロード
$ sudo rmmod elder        # 次にアンロード
```

# 質素な解説
まず、elderでは自分以外のモジュールから自分が持つ関数を呼び出すことができるようにするため、EXPORT_SYMBOLマクロを使っています。
このマクロを使うことで、他モジュールからアクセス可能なシンボルを生成することができます。今回は、__eld_public_functionに対し、使用しています。

little側では、プロトタイプ宣言した関数を呼び出しているだけです。

# 終わりに
LKMはカーネルにロードされ、カーネル空間で動作します。したがって、使用できる関数や構造体はLinuxカーネルと同じものになります。つまり、手軽にLinuxカーネルの開発を行えるようなもので、非常に便利な機構です。Linuxカーネルにおけるデバイスドライバや静的にカーネルに組み込まれる必要が無いものは、カーネルモジュールとして開発されることが大半です。これによって、Linuxはモノリシックカーネル的な側面とマイクロカーネル的な側面をうまく両立させているのです。
スプレッドシートで覚えるブロックチェーン |「もしかして渡した値」「入れ替わってる！？」

Google スプレッドシート上でブロックチェーンの基本的な部分を作成してみました。
暗号方式はsha256でPoW が入っていないゆるい感じの説明です。

#「もしかして渡した値」「入れ替わってる！？」
ブロックチェーンの最大の特徴は、情報が改竄されにくいところにあります。
実装したスプレッドシートは、以下にあります。

https://docs.google.com/spreadsheets/d/1muiirzfygEoKxGl28XX8FICKQgw7apeIyyy_FFRCjcs/edit?usp=sharing
![スクリーンショット 2018-01-20 13.01.20.png](https://qiita-image-store.s3.amazonaws.com/0/104300/e74c0d0b-0e81-2eb2-c86d-46644c71c3fb.png)
スプレッドシートには、情報となる名前と、横のsha256にはハッシュ値が入っています。
chain欄は改竄されていなければ、TRUEとなっています。
名前が変わるとハッシュ値が変わります。
ハッシュの生成にはGoogle スプレッドシートのスクリプト作成しています。

```js
function SHA256 (input) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input);
  var txtHash = '';
  for (i = 0; i < rawHash.length; i++) {
    var hashVal = rawHash[i];
    if (hashVal < 0) {
      hashVal += 256;
    }
    if (hashVal.toString(16).length == 1) {
      txtHash += '0';
    }
    txtHash += hashVal.toString(16);
  }
  return txtHash;
}
```



#あんた今、夢を見とるな？
では、名前を入れ替えて、情報を改竄してみます。
名前を入れ替えるだけのちょっとした変更です。見た目では気づかないかもしれませんね。
ただし、ハッシュ値は違うものになり、FALSEとなりました。

![スクリーンショット 2018-01-20 15.28.34.png](https://qiita-image-store.s3.amazonaws.com/0/104300/3b909dbc-7904-9513-4f20-3dc01afac9d9.png)

chainは入力された時の生成されたハッシュ値と現在のハッシュ値とで比較しています。

```
=EXACT(B2,SHA256(B1&A2))
```
ここで、B1とA2が足しあわされてハッシュ値としていますね。
B1を見ると前のハッシュ値を示しています。これがブロックチェーンと言われる基本的な部分です。

#ブロックチェーンは組み紐のように繋がっている
ブロックチェーンと呼ばれるのは作成したブロックは、前の世代の情報を含んでいます。前の前の世代のブロックは、その前前前世のハッシュを含み繋がっています。
ハッシュは、情報によって固定した値が出力され、情報が違うと違う値が出力される性質があります。また、出力された値からは元の値には戻せない不可逆的な性質を持っています。

では、検証として、一部分だけ書き換えてchainをすべてTRUEにするにはどうしたらいいでしょうか。試しにハッシュも改竄してみましょう。同じ行のハッシュも再生成してこれで改竄完了ですね。
でも、待ってください。ハッシュの生成には前の行のハッシュを含んでいます。
ということは、ハッシュを書き換えると次の行でchainはFALSEになります。
つまり、一部だけ改竄ということはできなくて、書き込んだ以降の行をすべて改竄しないといけないことがわかります。書き込みがあるほど、過去の情報の改竄が容易でなくなりますね。

#組み紐を編む
Googleのスクリプトを使って、ハッシュ生成処理を組んでいます。Googleスクリプトでは、onEditで編集のカラムがわかります。そして、setValue で好きなカラムに静的な値を書き込むことができます。

```js
function onEdit(event){
  var ss = event.source.getActiveSheet(); 
  var ar = event.source.getActiveRange(); 
  if(ar.getColumn() == 1){//最初の列のみを処理
      cv = ar
      var chain = SHA256("" + cv.offset(-1,1).getValue() + cv.getValue())
         if( cv.offset(0,1).isBlank() ){
           cv.offset(0,1).setValue(chain); 
         }
  }
}
```
#まとめ
- ブロックチェーンで一部の改竄は容易でない。
- スプレッドシートでいちよ表現できる。
- 君の名は、もう一回見たい。(ステマではない)


#おまけ：複数人から過半数の同意を得るには？
実はこのスプレッドシートは、分散して管理するには完全ではありません。
スプレッドシートをコピーして値を追記していった場合はどれが本物でしょうか。
多数決にしたとして、１人で沢山コピーしてしまえば成り立ちません。
別の技術の一つとして、PoW(Proof of Work) という仕組みがあります。書き込み時に、ハードウェア限界性能で制限をつけてしまう方法です。
スプレッドシート上でも出来ないことは無さそうなので、気が向いたらと思います。

#参考と実際に使われているブロックチェーン情報
http://block-chain.jp/tech/bitcoin-blockchain/
Cakephp1.3から2.10にアップデート①

案件でCakePHPをバージョンアップする機会があったので、自分なりにまとめてみました。

##ダウンロード
バージョンアップ対象のCakePHPを[GitHub](https://github.com/cakephp/cakephp/tree/2.x)よりダウンロードする

##フォルダ・ファイルの確認
```
CakePHP1.3のフォルダ構成
mywebsite/
     app/
        controllers/
        models/
        views/
        ...
        webroot/
     cake/
     plugins/
     vendors/
     index.php
```
※不必要なフォルダ・ファイルがあれば削除してください。

##Upgradeシェル
```
実行コマンド　
./Console/cake upgrade all
確認用コマンド　
./Console/cake upgrade all --dry-run
プラグイン含む実行コマンド　
./Console/cake upgrade all --plugin YourPluginName
ヘルプ　
./Console/cake upgrade --help
```
1.3から2系へとアップデートを行うには*Upgradeシェル*を利用するといいです。
この機能があったので、3系ではなく2系へのアップデートを行う事に決めました。

##アップデート処理
フォルダ構成を以下のように調整してください。
app/index.phpとapp/webroot/index.phpはCakePHP2のものに変更してください。

```
mywebsite/
     app/                ->アプリ
        Console/         ->CakePHP2のConsoleフォルダ
        controllers/
        models/
        views/
        ...
        webroot/
            index.php
            ...
     app-backup/         ->CakePHP1.3のアプリのバックアップ
     cake/               ->CakePHPの1.3バージョン
     lib/                ->CakePHPの2.10バージョン
        Cake/
     plugins/
     vendors/
     index.php
```
フォルダ構成の調整が完了しましたら以下のコマンドを実行します。
`./Console/cake upgrade all --dry-run`
実行をするとアップデートで行われる処理の手順がコンソール画面へ表示されます。

確認を行い問題がない場合は以下のコマンドを実行し、アップデート処理を行います。
`./Console/cake upgrade all`
※プラグインを含むアップデートを行う場合は、プラグインが2系に対応しているかどうか確認が必要になるので注意してください。

##コマンド実行後
・.htaccessファイルの一部変更

```
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
↓
RewriteRule ^(.*)$ index.php [QSA,L]
```
・ファイル移動がうまくいかなかった場合
私の環境ではいくら試してもviewsフォルダのみファイルの移動に失敗しました。
結局ファイル移動と名前（キャメル型）の変更を手動で行うことになりました。

・設定ファイルのマージ
以下の設定ファイルは変更されないので、手動で変更を行ってください。
app/Config/bootstrap.php
app/Config/core.php
app/Config/routes.php

・ソース内調整
作業工程は多い為、別の記事で紹介致します。


##まとめ
作業自体は手順さえ把握していればそんなに時間が掛かる事ではないです。
但し、Upgradeシェルも完璧なものではないので手動での調整が必要な箇所もだいぶあります。
今回初めての作業だったこともあり、調べ物や作業手順などの確認事項が多かったので備忘録としてまとめてみました。



#参考にしたサイト
[2.0 移行ガイド](https://book.cakephp.org/2.0/ja/appendices/2-0-migration-guide.html)
[Upgrade シェル](https://book.cakephp.org/2.0/ja/console-and-shells/upgrade-shell.html#upgrade-shell)
[CakePHP2.x系のバージョンアップ手順](https://normalblog.net/system/cakephp2-x-version-up/)
[CakePHP1.3→2.6のアップグレード時に発生した作業や注意点について](http://tech.respect-pal.jp/upgrade-cakephp-13to26/)
Python > string > AAA,BB,CCCC,DDD形式のそれぞれ語の文字数を表示する > for loop, 内包表記, map(len(), ), list(map()), lambda

```txt:動作環境
CentOS 6.8 (64bit)
Python 2.6.6 for code v0.1, v0.2
Python 3.4.5 for code v0.2
```

### 処理概要

以下の形式の文字列が与えられる。

```
IN_TXT = "3.141592,2.817,6.022,1023"
```

それぞれの語の文字数を表示する。

### code v0.1

```string_counter_180123.py
# on Python 2.6.6
# on Python 3.4.5


def count_word_length_forloop(atxt):
    for elem in atxt.split(','):
        print(len(elem))


def count_word_length_comprephension(atxt):
    print([len(elem) for elem in atxt.split(',')])

IN_TXT = "3.141592,2.817,6.022,1023"

count_word_length_forloop(IN_TXT)
count_word_length_comprephension(IN_TXT)

```

```txt:run
$ python string_counter_180123.py 
8
5
5
4
[8, 5, 5, 4]
```

### 備考

「内包表記」という用語を思い出せなかった。僕自身があまり使わないからだろうか。

内表表記の表示は項目数が多いときに見やすそう。for loopでも頑張れば見やすい表記はできるだろうが。

### 検索用キーワード

- List comprehension

### link

- [Python > Comprehension / 内包表記 > List comprehension](https://qiita.com/7of9/items/aa04b15d00a058fa0cc0)

@shiracamus さん
> 内包表記には、リスト内包表記、辞書内方表記、ジェネレータ内包表記があります。

このあたりはまだ覚えてませんでした。。。

### code v0.2

@shiracamus さんの[コメント](https://qiita.com/7of9/items/9a40e0cfde254bafbd27/#comment-00f390778086d3da5d9b)にて教えていただきました関数２つを掲載しました。
情報感謝です。

Python3ではPython2用コードは実行しないようにしていますが、将来の参照用として。

https://docs.python.jp/3/tutorial/datastructures.html#list-comprehensions
にてlambdaの記載があったため、追加しました。

```string_counter_180123.py
# on Python 2.6.6
# on Python 3.4.5

import sys


def count_word_length_forloop(atxt):
    for elem in atxt.split(','):
        print(len(elem))


def count_word_length_comprephension(atxt):
    print([len(elem) for elem in atxt.split(',')])


def count_word_length_map_len(atxt):
    if sys.version[0] != "2":
        print("not for Python3")
        return
    print(map(len, atxt.split(',')))


def count_word_length_list_map(atxt):
    print(list(map(len, atxt.split(','))))


def count_word_length_lambda(atxt):
    print(list(map(lambda x: len(x), atxt.split(','))))

IN_TXT = "3.141592,2.817,6.022,1023"

count_word_length_forloop(IN_TXT)
count_word_length_comprephension(IN_TXT)
count_word_length_map_len(IN_TXT)
count_word_length_list_map(IN_TXT)
print('---')
count_word_length_lambda(IN_TXT)

```

Python2の場合。

```txt:run
$ python2 string_counter_180123.py 
8
5
5
4
[8, 5, 5, 4]
[8, 5, 5, 4]
[8, 5, 5, 4]
---
[8, 5, 5, 4]
```

Python3の場合。

```txt:run
$ python3 string_counter_180123.py 
8
5
5
4
[8, 5, 5, 4]
not for Python3
[8, 5, 5, 4]
---
[8, 5, 5, 4]
```

list, map, lambdaはまだ記憶だけではコーディングできません。精進いたします。
(Pythonista in the making)

- map
    - https://docs.python.jp/3/library/functions.html#map
    - > function を、結果を返しながら iterable の全ての要素に適用するイテレータを返します。
- list
    - https://docs.python.jp/3/library/functions.html#func-list
    - > list は、実際には関数ではなくミュータブルなシーケンス型で、 [リスト型 (list)](https://docs.python.jp/3/library/stdtypes.html#typesseq-list) と [シーケンス型 — list, tuple, range](https://docs.python.jp/3/library/stdtypes.html#typesseq) にドキュメント化されています。
SQLのCOUNT文で意図した件数が取得できなかった

ほんの少しハマったことを共有。
考えてみれば当たり前のことでしたが、**COUNT文なんて間違いようがないだろうと思っていると**ドツボにハマります。

（DBはOracleで再現しましたがどのDBMSでも同様かなと思います。）

# やりたかった事
nullのレコード件数を取得したかった。
例として以下のテーブルで、DATA2の列がnullのレコード件数を取得するということを考えます。

## テーブル例
EXAMPLE_TABLE

| ID|DATA1|DATA2|
|---|-----|-----|
| 1 |a    |A    |
| 2 |b    |null |
| 3 |c    |C    |


# 駄目だったSQL

```sql:bad.sql
select COUNT(DATA2) from EXAMPLE_TABLE where DATA2 is NULL; 
```
結果：0

# 正解SQL
こうあるべき

```SQL:good.sql
select COUNT(ID) from EXAMPLE_TABLE where DATA2 is NULL;
```
結果：1

# 結論
COUNT文に指定したカラムがnullの場合はカウントされません！
教科書的に、「COUNT文にはキー項目や*、定数（'x',1等）を指定しましょう」というのに従いましょう。
仕組みとしては、COUNT(NULL)と評価されて、NULLはいかなる真偽値検査もfalseとなるためCOUNTもされなくなります。
何の気なしに、where句で指定したカラム使っちゃえとしたのが間違いでした。
Jenkins で pengins -master is offlineになってしまったときの対応方法


本番環境へのソースコードのデプロイはansible経由で行っているのですが、コマンドライン上で各々にスクリプトを叩かせるのは事故のもとなのでjenkisからコマンドを発行してデプロイするようにしています。

jenkinsでのビルド（= デプロイ実行）時に、「pendings  -master is offline」になってしまったので対応方法をメモしておきます。

![jenkins_offline.png](https://qiita-image-store.s3.amazonaws.com/0/37873/0474e175-a810-377f-bcd4-9172cdcc88d1.png "jenkins_offline.png")


## 環境
* jenkins 2.48

## 対応方法

「pendings  -master is offline」は「待機中です。masterサーバーがオフラインです」という意味ですね。
ということで、masterサーバーをオンラインにしてやる必要がありそうです。

1. jenkinsホーム >> Jenkinsの管理 >> ノードの管理 からノードを選択します。
2. 該当するノードを選択
3. エラーを確認しつつ、オンラインに戻す


![jenkins_node.png](https://qiita-image-store.s3.amazonaws.com/0/37873/6fa26d18-ee50-30b5-a0df-4ca790a93dab.png "jenkins_node.png")


## エラーの原因
Jenkinsサーバーのディスク容量が逼迫していて、自動的に停止したようです。
AWSを使っていたので、ディスク容量を追加しました。簡単にできて良いですね。

![jenkins_error.png](https://qiita-image-store.s3.amazonaws.com/0/37873/441e4610-e3b4-5b7c-4f37-052f5c35f1fe.png "jenkins_error.png")
PyQt5 > 描画 > 円と線を描く + 備考

```txt:動作環境
Ubuntu 16.04 LTS desktop amd64
Python 3.5.2
PyQt5 v5.5.1
```

### 処理概要

円と線を描く。

### 参考

- [【PythonでGUI】PyQt5 -ペイント-](https://qiita.com/Nobu12/items/fec5c97bfbd6c3ff1f00)
- [Draw Circles (PySide/PyQT)](https://www.daniweb.com/programming/software-development/code/441810/draw-circles-pyside-pyqt)

### code

```test_kabaya_juicy_180123.py
import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Widget(QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(Qt.red)
        painter.setBrush(Qt.yellow)
        #painter.drawRect(10, 10, 100, 100)
        center = QPoint(100, 100)
        painter.drawEllipse(center, 50, 50)
        #
        len = 50
        painter.drawLine(100 - len, 100 - len, 100 + len, 100 + len)
        painter.drawLine(100 + len, 100 - len, 100 - len, 100 + len)
        painter.drawLine(100, 100 - len, 100, 100 + len)


def main():
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    w.raise_()
    app.exec_()

if __name__ == '__main__':
    main()

```

### 実行例

```bash
$ python3 test_kabaya_juicy_180123.py 
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/56616063-2ff3-455e-cb57-0f0c2de86f11.png)

### 備考

- 1965年から信頼性の高い容器を作成している
- 多くの人から慕われている
- 再入手性が高い
- 透明なので、内部の抵抗の色が読みやすい
- フレームを作れば、E24系列(E12系列?)のうちの6種類の抵抗を保管しやすい
    - 6等分にする機構
        - 凱旋門、放射状
        - ランナバウト 道路
    - 下から持ち上げる機構
    - 竹串 + スポンジ? 板? 紙?
        - or リード線で作る?
        - or 木をルーターで加工する?
            - http://variouskraft.com/AUDIO-4jisaku-SP-02_WV-00.html
        - ぜんまい形
            - 内径にフレキシブルにフィットする?
            - http://www.kodama-tec.com/case/use/spiralspring/


- **[仕事中には見ない方がよいリンク](https://www.kabaya.co.jp/catalog/juicy/)**
    - 疲れた時の糖分補給に良い

フレームをどう作るのか簡単だろうか。

別の利用例: [link](http://treeware.jp-help.net/tw01/HTMJC.HTM)
【今日から続けたい】Emacsでコミットメッセージにプレフィクスを簡単につけれるようにする

一人プロジェクトのコミットメッセージなんか git now で充分ぐらいに思っている意識の低い私が、

【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話 - Qiita
https://qiita.com/numanomanu/items/45dd285b286a1f7280ed

に感化されて長続きできるように行なったEmacsの設定です。

## 1. yasnippet で `:` を登録

Emacs ユーザーは全員 magit と yasnippet を使っているという前提で書いてしまいますが、magit からコミットメッセージ編集モードに入るとデフォルトでは text-mode になるので、そこに yasnippet の略語を登録しておきます。

docs の場合は ci を飛ばすことが多いので一緒に `[ci skip]` も入れときます。

```elisp:~/.emacs.d/snippets/text-mode/&#058;
# --
`(yas-choose-value '("feat" "fix" "[ci skip] docs" "style" "refactor" "perf" "test" "chore"))`: $0
```

これで `: <TAB>` と入力して、プレフィクスを一覧から選ぶだけで入力できるようになりました。

ところが、上の設定でしばらく使ってみて気づいたのですが、 magit の場合は `[xxx]` 形式にした方が良さそうです。というのも `[xxx]` 形式だとコミット一覧のとき色がついて見やすくなります。なので今は次の設定で使っています。

```elisp:~/.emacs.d/snippets/text-mode/&#058;
# --
`(yas-choose-value '("[feat]" "[fix]" "[docs][ci skip] Update" "[style]" "[refactor]" "[perf]" "[test]" "[chore]"))` $0
```

## 2. `:` の入力を忘れないようにする

yasnippet の略語すべてに言えることですが、何に登録したのか思い出せず、そのうち登録したことも忘れるという問題があります。

なので git のコミットメッセージのテンプレートに最初から書いておきます。

次のファイルを作って `git config --global commit.template ~/.gitmessage.txt` で ~/.gitconfig に反映します。

```:~/.gitmessage.txt
:
```

これならさすがに忘れることはないでしょう。

## 3. 毎回 TAB (C-i) を押すのも面倒になってきたので

`：` を見て毎回カーソル右してTABするのも面倒になってきたのでここも自動化しておきます。

```el:~/.emacs.d/init.el
(add-hook 'git-commit-setup-hook 'git-commit-prefix-select)
(defun git-commit-prefix-select ()
  (forward-char)
  (yas-expand))
```

これでコミットメッセージを書こうとしたとき、すでにプレフィクスの選択肢が出ているようになります。
コマンドプロンプトでバッチ処理が突然停止した件について　簡易編集モード (windows10)

# はじめに
windows10のコマンドプロンプト (ターミナル) 上で長時間のバッチ処理を行っていた時に、突然処理が止まってしまうことがあったので対策をメモしておきます

#バッチ処理　#停止　＃コマンドプロンプト　#選択

# 動作環境
Windows10

# 対応策
最初に **解決策** を書いておきます！
コマンドプロンプト上の白い部分であるwindow上で右クリックし、プロパティを選択、簡易編集モードのチェックを外してOKボタンでバッチ処理が止まることはなくなります。


![2.png](https://qiita-image-store.s3.amazonaws.com/0/229955/10b1e23b-6863-6bc5-834c-6d93327c44a4.png)

ちなみに、この簡易編集モード、チェックをつけているとコマンドプロンプトのメッセージをマウスドラッグで選択できます。また、選択状態で右クリックするとテキストコピーができて、選択していない状態で右クリックするとクリップボードにあるテキストをプロンプトにペーストできるようです。

しかしながら、この簡易編集モードはバッチ処理中に適当なテキストを選択するとバッチ処理が一時停止してしまうようです。コマンドプロンプト上で長時間バッチ処理を行うような場合は、間違って右クリックしてしまうことが起こりやすくなるためチェックを外しておいた方が無難です。

自分は、どうして止まったのかわからず戸惑っていましたが、右クリックをもう一度押すと処理が再開されます。右クリックの他、何らかのキーボード入力でも再開するようです。

# 参考文献
~~http://neos21.hatenablog.com/entry/2016/10/10/144115~~
~~http://memoryfolder.hatenablog.com/entry/2017/09/22/042558~~
https://softantenna.com/wp/tips/windows-10-command-prompt-no-stop/
https://neos21.net/blog/2016/10/10-01.html
https://github.com/nanopool/Claymore-Dual-Miner/issues/11
URLが存在しないものが増えたため、更新しました。(2021/07/07)
WordpressをさくらインターネットからCORESERVERに移行する方法

まだクライアント用のサイトが準備ができてない状況で、クライアントが先にDemoサイトを見たいと言うので
一時的にさくらインターネットのサーバにWordpressをサイト構築し、その後にCORESERVERにwordpressで構築したサイトを移行した時の方法です。

#まずさくらインターネット側で準備する
まずサーバーからwordpressのデータをダウンロードしておく。

さくらのコントロールパネルに入り
データベースの設定からphpmyadminにログインする。

phpmyadminに入ったら作成したデータベースをエクスポートする
![スクリーンショット-2018-01-23-11.52.53.jpg](https://qiita-image-store.s3.amazonaws.com/0/163786/588ca454-e122-9236-63ca-a0a9e64fcbb4.jpeg)

「DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT を追加」
のチェックは忘れずに

#次にCORESERVERの準備
CORESERVERのサーバーにWordpressのデーターをアップロードしておく。

CORESERVERの管理画面にログインし、
![スクリーンショット-2018-01-23-12.03.44.jpg](https://qiita-image-store.s3.amazonaws.com/0/163786/d515c77f-9934-0911-1439-79b1521b2b55.jpeg)
データベースをの新規作成

![スクリーンショット-2018-01-23-12.06.49.jpg](https://qiita-image-store.s3.amazonaws.com/0/163786/8d0925b1-971c-2306-7300-8e88ef297ae6.jpeg)
DB名とパスワードを作成してください。
文字コードはそのままUTF-8でいいです。

次にphpmyadminがインストールされてなかったらインストールしておいてください。
数分で完了します。

インストールしたらログインしてください。

CORESERVERのphpmyadminの中に入ったら作成したデータベースを選択肢し、インポートしていきます。

インポートが終えたら
wp-config.phpを書き換える
![スクリーンショット-2018-01-23-12.15.46.jpg](https://qiita-image-store.s3.amazonaws.com/0/163786/5845f6ee-2897-7bf5-2098-4ce0f48cd18e.jpeg)

①、②にはDB名/DBユーザー名共通を記入
③パスワードは DBパスワードを記入しておく
④ホスト名はlocalhost
⑤文字セットはutf8で

この辺が他のサーバーと違って他のでややこしかった。
下記を参考：
https://hostingstock.net/article/coreserver_jp/installing-wordpress/

この後はディレクトリーによっては.htaccessの変更
ディレクトリーの書き換えにSearch Replace DBを導入して書き換えるでOK。
いたって他の移行の仕方は変わらない。

参考：
http://www.jaskun.com/wordpress/wordpress-database-iten/
初PMで、プロジェクトの要件定義フェーズをEASYにまとめてみた

# 今回のモデルケース
- 既存案件のリプレイス案件(API実装のみ) + コンテンツ管理システムの新規案件
- 既存案件のリプレイスのフロント部分は、別チームが担当
- コンテンツ管理システムの画面遷移図は、すでに作成済み
- 体制
 - PM1(中堅), Member2(ベテラン, 若手)
 - 中堅(フルスタック寄, マネジメント初めて)
 - ベテランさん(設計等が強い)
 - 若手さん(プログラマー要員)
- 初めてのフレームワークを試してみる(Laravel)
- 初めてのVue.jsを試してみる(SPA→部分Vue)

# 要件定義フェーズ
## 大前提
***ユーザが幸せになれることを考える！***
***だけど、提示された要望に対して、すべて鵜呑みにしない！***
***なぜ、それを実現させたいのか、こだわるのかの理由を聞き出す！***

## 要件定義前に、テンプレート用意する
- 何を目的としたシステムなのか
- 何をするシステムなのか
- そのシステムには、どんな機能があるのか
- そのシステムは、どんな機器で動くのか
- どうやって、そのシステムを作っていくのか

## 要件を聞く時に、意識すること
- ユーザは、何がしたいのかをしっかり理解する。
- システムで実現できるのかを考える(あいまいなら汲み取って聞き出す)
- 聞きながら、プラン立てを考えておく（機能のやるやらないのようなもの）
- 機能一覧を裏で作りながらやっておくと整理しやすい
- 何をDB管理、何を定数管理、何をファイル管理などを想定しておくとDB設計時にスムーズ

## 要件定義のMTGが終わった後に整理/精査する時(MTGした分繰り返す)
- その要望の可否を検討する。
 - システム的に実現できる？できない？
 - そもそも本当に必要かどうか？
 - (既存システムなら)既存の機能でまかなえないか？
- その要望は誰が使用するのかを明確にする(工数的には省略したい)
 - アクターの整理をして、やり方(HOW)を決めていく
- 要望のリアルタイム性を確認する
 - データの鮮度が低いならば、バッチ処理などを提案する 

## 聞き出した要件を元に設計を行い、クライアントと都度MTGを行う
例)

- メール設計
- 処理概要設計
- DB設計
- プログラム構造設計
などなど

## 要件定義フェーズで失敗したこと
- 知識の足りなさの部分で自分からの提案ができなかったこと。(上司から助けてもらった)
- 設計すべきものが見通せなかった(設計漏れがあった)

## 大事だけど忘れがちなやつ
- 新しく人が参画されたときに、最新資料の情報共有（必ずまとめておく）
    - 何がどこにあって、どれが使い捨てで、どっちが正で、、、など
- 情報が、ゆるがないものは、mdファイルなどにまとめてしまう
xlwings.Sheet 簡易リファレンス

xlwings.Sheet 簡易リファレンス
# はじめに

これは xlwings 0.11.5 [本家xlwings.Sheets](http://docs.xlwings.org/en/stable/api.html#sheets) [本家xlwings.Sheet](http://docs.xlwings.org/en/stable/api.html#sheet) の簡易日本語リファレンスである。

# xlwings.Sheets

Sheets はブックに含まれる全シートを管理する。
[VBA:Worksheets](https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/worksheets-object-excel)

```python
import xlwings as xw
wss = xw.sheets               # アクティブブックのシート管理インスタンスを返す
                              # VBA:ActiveWorkbook.WorkSheets
wss.active                    # アクティブなSheetインスタンスを返す
wss['Sheet1']                 # wss[0] 添え字指定も可能 Sheetインスタンスを返す
wss('Sheet1')                 # wss(1) インデックス指定も可能 Sheetインスタンスを返す
wss.add(name=None, before=None, after=None) # 新規 Sheetインスタンス作成し返す
wss.count                     # Sheetインスタンス数を返す
```

api プロパティーはない

# xlwings.Sheet

Sheet は単一のシートを管理する。
[VBA:Worksheet](https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/worksheet-object-excel)

```python
import xlwings as xw
ws = xw.sheets.active # アクティブなSheetインスタンスを返す
ws.activate()         # シートをアクティブにする
ws.select()           # 選択状態にする
ws.delete()           # シートを削除する
ws.index              # シート番号を返す
ws.name               # シート名を返す
ws.book               # xw.Book を返す

ws.cells              # 全範囲を示すRangeインスタンスを返す
ws.clear()            # 全範囲の値と書式をクリアする
ws.clear_contents()   # 全範囲の値のクリアする
ws.autofit(axis=None) # 全範囲の高さ幅を自動調整する 'rows' 'r'  'columns' 'c'

ws[...]               # [0:1, :10] 添え字指定可能 xw.Range(...) を参照
ws.range(...)         # xw.Range(...) を参照

ws.names              # xw.Names() を返す
ws.charts             # 表管理インスタンスを返す
ws.pictures           # 画像管理インスタンスを返す
ws.shapes             # シェイプオブジェクト管理インスタンスを返す

ws.api                # ネイティブインスタンスを返す
```
決済でkomoju Hookをphpで受け取る

例によって検証用でございます。
公式サイトのシグネチャの説明がRubyでちょっと中身がわかりにく若干苦労しました。
管理画面で適宜URLやらトークンやらは設定してください。

```php:hook.php
$token = "管理画面で設定したトークン";
//headerの必要な情報を取得
foreach (getallheaders() as $name => $value) {
    //Komoju id
    if($name == "X-Komoju-Id"){
        $request_id = $value;
    }
    //シグネチャ
    if($name == "X-Komoju-Signature"){
        $request_signature = $value;
    }
    //イベント種別
    if($name == "X-Komoju-Event"){
        $request_event = $value;
    }
    echo "$name: $value\n";
}
//シグネチャはボディのハッシュになります
$body = file_get_contents('php://input');
$signature = hash_hmac("sha256",$body,$token);

//シグネチャの正当性を確認
if($signature === $request_signature){
    echo "Good request!\n";
    echo $request_id."\n";
    echo $request_event."\n";
/*
この後に決済完了とかそういうしょりをね、入れていくわけです
*/
}else{
    echo "Bad request!";
}

```
1行で書くmix ecto.gen.migrationのメモ

mix ecto.gen.migration → mix ecto.migrate する際の、priv/repo/migrations/【yyyymmddHHMMSS】_【ecto.gen.migrationで指定した名前】.exsの「def change」内に1行で書く書式

```elixir
drop table( :table_name )
alter table( :table_name ), do: add :column_name, :integer
alter table( :table_name ), do: remove :column_name
create index( :table_name, [ :column_name ] )
drop index( :table_name, [ :column_name ] )
rename table( :table_name ), table( :new_table_name )
```

ちなみに、以下は自動更新されないため、column removeしたときは、手動で修正するのをお忘れなく

```
lib/【PJ名】_web/templates/【スキーマ名】/form.html.eex
lib/【PJ名】_web/templates/【スキーマ名】/index.html.eex
lib/【PJ名】_web/templates/【スキーマ名】/show.html.eex
```
docker buildに失敗して量産されたイメージやコンテナの一括削除


docker buildに失敗しまくるとすぐにコンテナやイメージが溜まっていく。

tagがnoneなimagesを一括削除

```sh
$ sudo docker rmi $(sudo docker images  --filter "dangling=true" -aq)
```

コンテナがいるとimagesは削除できない。
そのため、以下のコマンドにて作成失敗してステータスが`Exited (1)`なコンテナのみ削除

```sh
$ sudo docker rm $(sudo docker ps -a --filter 'exited=1' -q)
```
Windows Server2016 RemoteDesktop Service リモートディスクトップライセンスモードが構成されていませんが出た場合

リモートディスクトップライセンスモードが構成されていませんとサーバログイン時に表示が出た場合

1.管理ツールから「RD ライセンス診断機能」を起動し診断結果を確認。

2.エラーとなる場合、ライセンスモード設定を確認するため　Powershellを管理者で実行し、下記コマンドを実行

(Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices)

結果でLicensingType の値を確認　

HomeDirectory                           :
InstallDate                             :
LicensingDescription                    :
LicensingName                           :
LicensingType                           : 5
LimitedUserSessions                     : 0

LicensingType の値が下記でない場合設定が必要
「接続デバイス数」に設定する場合 ：値が2
「接続ユーザー数」に設定する場合 ：値が4

3.Powerhellで接続モードを設定
「接続ユーザー数」に設定する場合
(Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).ChangeMode(4)

「接続デバイス数」に設定する場合
(Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).ChangeMode(2)

4.実行結果を確認
(Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices)
HomeDirectory                           :
InstallDate                             :
LicensingDescription                    :
LicensingName                           :
LicensingType                           : 4 or 2になってればOK
LimitedUserSessions                     : 0

5.管理ツールから「RD ライセンス診断機能」を起動し診断結果確認
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/232243/c831527b-64ba-b269-1a93-cc65d740acd2.jpeg)


エラーが表示がなく自分で設定したライセンスモードが反映していればOK