OmniAICreator/Qiita-1.07M huggingface dataset:
【HeartCoreRobo】何度も使用する処理はプロシージャ化しよう

#HeartCoreRoboのプロシージャは何度も使用する処理の管理が簡単

RPAの開発が進んでくると、似たような処理を違う処理で使いたい場面が出てきます。

その際、前に作った処理からコピーして新しい処理に使いがちなのですが、そうすると修正が必要な場合に、コピー前後の二つとも修正をしなければならず、開発が進むほどメンテナンスが大変になってきます。

HeartCoreRoboでは、プロシージャという機能を使って、違う処理から以前の処理を呼び出すことが簡単にできます。

私は他のRPAツールもある程度使ってみたことがあるのですが、下記のような共通処理に対して変数の指定が思ったようにいかず、共通処理側に変数が渡らない、処理後の変数が返ってこないというように苦労することがありました。その点、HeartCoreRoboでは変数の指定が簡潔に行え、スムーズに開発を進めることができました。

#プロシージャを使用しない記述例

例えば、画面上に２つのボタンがあり、どれか一つを選択した後に検索実行する処理があるとします。この場合、ボタンＡをクリックしてから検索実行する処理をHeartCoreRoboで実現すると、

```
//処理１　ボタンAをクリック
click "image" template="comp1021-1"　　
//処理２　検索ボタンをクリック
click "image" template="comp1021-2"　　
```
といった処理になります。ボタンＢをクリックしてから検索実行する処理は

```
//処理１’　ボタンBをクリック
click "image" template="comp1021-3"
//処理２　検索ボタンをクリック
click "image" template="comp1021-2"
```

となります。この処理は同一システムでいろんなメニューで使われているもので、その都度設定しているとすると、そのボタンの形が変わった場合、この処理が使われているスクリプト一つひとつを修正する必要が出てきてしまいます。

#プロシージャを使用する記述例

上記の処理をプロシージャを使ってまとめると

```
//変数{1}：クリックするボタンを指定する。
procedure buttonclick {
 　//処理１　ボタン{1}（変数で指定）をクリック
     click "image" template="{1}"
 　//処理２　検索ボタンをクリック
     click "image" template="comp1021-2"
}

//ボタンAをクリックする場合は、プロシージャ名の後ろに「comp1021-1」
buttonclick comp1021-1
//ボタンBをクリックする場合は、プロシージャ名の後ろに「comp1021-3」
buttonclick comp1021-3
```

のように半角スペース区切りで、クリックするボタンのテンプレートイメージを指定すれば、前後の処理は同一で、クリックするボタンだけを変更する処理を簡潔に実装することができます。

#変数が複数ある場合

```
buttonclick comp1021-1 paramA paramB
```

のように半角スペース区切りで並べれば、呼び出し元のプロシージャ側で順に{1}、{2}、{3}のように指定することで受け取ることが可能です。

#プロシージャを別スクリプトとしておくことも可能

また、procedure部分だけを保存したスクリプト（仮に「プロシージャ集.tpr」とする）を作成し、他のスクリプトで使用したい場合は、

```
include プロシージャ集.tpr
buttonclick comp1021-1
```

のように、include関数を使って他のスクリプト内のプロシージャを読み込み、その後でプロシージャを実行することができ、呼び出す側のスクリプトをシンプルにすることができます。

#私の実際の使用例

上記のようなプロシージャは、今のところ
・ネットバンキングから口座ごとの入出金明細をダウンロードする際、口座番号の選択だけ異なるが、その後のダウンロード処理は同一。
・検索画面で検索条件を指定する際、条件指定のパターンは複数あるが、検索前後の処理が同一。
といった処理に、非常に役立っています。

エンジニアの方なら[リファレンス](https://www.heartcorerobo.com/hcrobodesktop/docs/scripting/commref.html#procedures "")を読めば理解できるのでしょうが、私のような非エンジニアの者には少々抵抗があるため、同じような境遇の方が参考にしていただければ幸いです。
コントローラーをなるべく活用してビューを綺麗にする(随時更新)

#なるべくビューから情報を消したかった。
一度作ったwebサービスがあるのですが、あまりにも汚かったので、初心者なりにリファクタリング中です。
やっていて感じたことが、コントローラーで取れる情報は、コントローラーで取り、ビューから取れるものはビューから取るというものです。

##current_user.idはコントローラーで取れる
初心者なんで許していただきたいですが、今まで自分はいちいちcurrent_user.idをviewから取得していましたが、よくよく考えたらコントローラーでも取れますよね。

```example.html.erb
<%= link_to "POST", new_post_path(post_id: id, user_id: current_user.id), :method => 'post' %>
```

みたいな感じで書いていたのですが、user_id: current_user.idがいらなかったなあと。

```example.html.erb
<%= link_to "POST", new_post_path(＠post) %>
```

```posts_controller.rb
post = Post.find(params[:id])
Post.create(id: post.id, user_id: current_user.id)
```

といった感じでできてしまいますね。。


##selfはレシーバのidを取れる

レシーバであるインスタンスの情報をコピーできるselfですが、これも最初の頃は全く使っていませんでした。
本当はこのselfすら省略できるそうですが、自分の勉強のために明示的に書いています。

例えばいいね機能を作るときなどに。。。。

bookテーブルとuserテーブルがあり、中間テーブルとしてbook_userテーブルがあるとしたら。。。。

```
def like
　bookuser = 　BookUser.find(params[:id])
　bookuser.create(user_id: current_user.id, book_id: self.id)
end

などで使えます。
IronRubyで起動中のExcelのシートを編集するGUIつきマクロを作る

# 概要
IronRubyで起動中のExcelのシートを編集するマクロを作ります。
GUI画面を持ち、パラメータを指定することができます。

# 前提
RubyとExcelのマクロについてある程度知っている方向けです。
本記事のテーマはRubyやExcelマクロの文法やコーディング作法ではなく、Ruby(IronRuby)とExcelを連携させるときのテクニックです。

# 環境
Windows 8.1（64ビット）
IronRuby 1.1
Excel 2010

# 開始ボタンのみの例
最初は最もシンプルな例として、開始ボタンのみの画面のあるコードを紹介します。

## コード

````excel_set_random_with_gui_01.rb
# coding: utf-8

require 'PresentationFramework'

include System::Windows
include System::Windows::Controls

# 起動中のExcelのプロセスにアタッチする
begin
	excel = System::Runtime::InteropServices::Marshal::GetActiveObject("Excel.Application")
rescue
	abort "No Excel process."
end


window = Window.new
window.title = "IronRuby"
window.AllowDrop = true
window.Width="300"
window.Height="300"

button = Button.new
button.MinWidth = 150
button.Content = "乱数書き込み"
window.Content = button

button.Click do |sender, e|
	# カーソルが当たっているセルに1～100の乱数を書き込む
	excel.ActiveCell.Value = rand(100) + 1
end

app = Application.new
app.run(window)
````

## 実行方法

[1] Excelを起動します

[2] DOS窓を開き、`excel_set_random_with_gui_01.rb`を実行します

```
> "C:\Program Files (x86)\IronRuby 1.1\bin\ir.exe" excel_set_random_with_gui_01.rb
```

[3] 実行すると"乱数書き込み"というボタンのあるウィンドウが表示されます

[4] ボタンを押すとA1のセルに1～100の乱数が入力されます（カーソルがA1のセルにあるため）
![excel_set_random_with_gui_01.PNG](https://qiita-image-store.s3.amazonaws.com/0/304851/1a10ba1e-f425-8b9f-306d-61b4c083771e.png)


[5] ボタンを連打するとA1のセルの値が次々と変化するはずです

# パラメータを指定できる例
次に、ボタンに加えてテキストボックスも配置して、パラメータを指定できるコードを紹介します。

## コード

````excel_set_random_with_gui_02.rb
# coding: utf-8

require 'PresentationFramework'

include System::Windows
include System::Windows::Controls

# 起動中のExcelのプロセスにアタッチする
begin
	excel = System::Runtime::InteropServices::Marshal::GetActiveObject("Excel.Application")
rescue
	abort "No Excel process."
end


window = Window.new
window.title = "IronRuby"
window.Width="200"
window.Height="100"

label = TextBlock.new
label.Text = "↓接頭辞を入力"

textbox = TextBox.new

button = Button.new
button.Content = "乱数書き込み"
button.Click do |sender, e|
	# カーソルが当たっているセルに1～100の乱数を書き込む
	excel.ActiveCell.Value = "#{textbox.Text}#{rand(100) + 1}"
end

panel = StackPanel.new
panel.Children.Add(label)
panel.Children.Add(textbox)
panel.Children.Add(button)

window.Content = panel


app = Application.new
app.run(window)
````

## 実行方法

[1] Excelを起動します

[2] DOS窓を開き、`excel_set_random_with_gui_02.rb`を実行します

```
> "C:\Program Files (x86)\IronRuby 1.1\bin\ir.exe" excel_set_random_with_gui_02.rb
```

[3] 実行するとテキストボックスとボタンが1つずつあるウィンドウが表示されます

[4] テキストボックスに適当な文字を入力します

[5] ボタンを押すとA1のセルに[4]で入力した文字と乱数が入力されます（カーソルがA1のセルにあるため）
![exec_result_02.PNG](https://qiita-image-store.s3.amazonaws.com/0/304851/8f2a2d68-bdc6-7fc4-76ea-80e652306fe9.png)

[6] ボタンを連打するとA1のセルの値が次々と変化するはずです

# 何がうれしいの？
Excelのマクロ実行環境のGUIエディタを使わずに、GUIつきマクロを作ることができます。
WPFで作った画面はリサイズが可能であるなど柔軟性があります。
Sassでeachを用いた色管理でハマった（Always quote color names when using them as strings）

## やりたいこと

webサービスのデザインにルールを設けるために、色をあらかじめ決めておくのはあるあるだと思います。
その管理を楽にすべく、Sassで変数に色コードを指定しておくのもまたあるある。

```sass
$main-color: #e73562;
$sub-color: #14be6b;
```

こんな感じですね

そして、これらをいろんな部分で`background-color`や`color`に用いることも多く、一気に管理する方法としてSassで`@each`を利用する方法もあります。

```sass
$red: #e73562;
$blue: #4169e1;
$green: #14be6b;

$app-colors: (
  red: $red,
  blue: $blue,
  green: $green
);

@each $name, $color in $app-colors {
  .bg-#{$name} {
    background-color: $color;
  }
  .text-#{$name} {
    color: $color;
  }
}
```

一気に定義できて便利ですが、実はこのコードは期待通りに動きません。

## 起きたエラー（Warning）

エラーではなくWarningなのでコンパイルはできますが、期待した通りには動きません。
こんなメッセージが表示されます。

```
WARNING on line 37, column 4 of /hoge/coupon_rep/app/assets/stylesheets/common/_color.scss:
You probably don't mean to use the color value `red' in interpolation here.
It may end up represented as #ff0000, which will likely produce invalid CSS.
Always quote color names when using them as strings (for example, "red").
If you really want to use the color value here, use `"" + $name'.
```

## 解決方法

```sass
$app-colors: (
  red: $red,
  blue: $blue,
  green: $green
);
```

↑これを
↓こうします。

```scss
$app-colors: (
  'red': $red,
  'blue': $blue,
  'green': $green
);
```

## どういうわけか

sassのgithubリポジトリでissueが立っていました。[参考](https://github.com/sass/sass/issues/1687#issuecomment-94936031)

> This is not a bug. As the warning says, an unquoted color name refers to the color object, not the string. Use quotes for your map keys.

とあるように、クオーテーションで囲まれていない色の名前があったとき、それは「red」という文字ではなく、「#ff0000」という**redの色コード**として扱われるそうです。
ということは、最初の指定方法でコンパイルすると以下のようになるということですね。

```css
.bg-#ff0000 {
  color: #ff0000;
}
```

Warningを出してくれてありがたいですね！
みなさんも気をつけてください！
MacOS mojaveでpyenvを使ってpythonがインストールできない時

役に立つ人がいるかもしれないので簡単にメモ

いろんなサイトを見ると`xcode-select --install`をすると治るのらしいですが、治りませんでした。

## brew doctor

とりあえず`brew doctor`して指摘された点を全部なおす。

http://ichibariki.hatenablog.com/entry/2018/03/24/213524

このサイトを参考にすればいけました。

## 追加のSDK

https://github.com/pyenv/pyenv/wiki/Common-build-problems

ここに書いてあるように

```
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```

これを実行するとインストールができるようになりました。
Effective Java 6章34～35

# 6章.ENUMとアノテーション

# 34.intの定数の代わりにenumを使うべし

* enumをいつ使えばよいか？→コンパイル時に明らかになっている定数のセットが必要な時はいつでも！
* constant-specific methodは馴染みがなくてしっくりこなかった。。以下の説明が分かりやすかった。

<http://d.hatena.ne.jp/hageyahhoo/20091115/1258258461>

# 35.ordinalよりもインスタンスフィールドの値を使うべし
* そもそもordinalメソッドはEnumSetやEnumMap用に使われるものであって、大半のプログラマは使わないものである。
Item 30: Favar generic methods

# 30.ジェネリックメソッドを選択すべし
* Collectionsの中のアルゴリズム系のメソッド（バイナリサーチやソート）はジェネリックメソッドである。
* ジェネリックメソッドを書くことはジェネリック型を書くのと似ている。以下のようにrawタイプで書くとwarningが現れる。

```java
// Uses raw types - unacceptable! (Item 26)
public static Set union(Set s1, Set s2) {
    Set result = new HashSet(s1);
    result.addAll(s2);
    return result;
}
```

warningを消して、タイプセーフにするにおいては、メソッド修飾子とメソッドの返り値の間に型パラメータを書いて以下のようにする。

```java
// Generic method
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
    Set<E> result = new HashSet<>(s1);
    result.addAll(s2);
    return result;
}
```

* immutableであるけれど、たくさんの異なる型に適応できるオブジェクトが必要となる場合があるかもしれない。
ジェネリックスはerasureによって実装されているので、求められるすべての型パラメータに対して、1つのオブジェクトで対応できるが、繰り返し、求められる型のオブジェクトを生成するstaticなファクトリメソッドを書く必要がある。このパターンは、generic singleton factoryと呼ばれ、関数オブジェクト（Item42）生成などに用いられる。
* 自分自身を返す関数が必要だとすると、Fuction.identityメソッドを用いれば事足りるが、説明にはもってこいなので下記に記す。
```IDENTITY_FN```を```UnaryOperator<T>```にキャストするときにwarningがでるが、```identity```関数は引数を変更せずに返却するので、warningを抑制することができる。

```java
package tryAny.effectiveJava;

import java.util.function.UnaryOperator;

public class GenericsTest7 {
    public static void main(String[] args) {
        String[] strings = { "jute", "hemp", "nylon" };
        UnaryOperator<String> sameString = identityFunction();
        for (String s : strings)
            System.out.println(sameString.apply(s));
        Number[] numbers = { 1, 2.0, 3L };
        UnaryOperator<Number> sameNumber = identityFunction();
        for (Number n : numbers)
            System.out.println(sameNumber.apply(n));

    }

    // Generic singleton factory pattern
    private static UnaryOperator<Object> IDENTITY_FN = (t) -> t;

    @SuppressWarnings("unchecked")
    public static <T> UnaryOperator<T> identityFunction() {
        return (UnaryOperator<T>) IDENTITY_FN;
    }

}
```

* 型パラメータが自身の型変数を含んだ表現で定義されている場合を、再帰型境界という。再帰型境界は```Comparable```インターフェースと関係がある。

```java
public interface Comparable<T> {
    int compareTo(T o);
}
```

* ```Collection```の並べかえ、ソート、最大最小導出のメソッドでは、```Comparable```を実装した要素を使っている。これらのメソッドでは互いに比較可能な要素が必要となるが、それを以下のように表現してる。

```java
// Using a recursive type bound to express mutual comparability
public static <E extends Comparable<E>> E max(Collection<E> c);
```
```<E extends Comparable<E>>```の表すところは、「自身と比較可能なあらゆる要素E」である。
以下が再帰型境界を使ったmaxメソッドとなる。

```java
package tryAny.effectiveJava;

import java.util.Collection;
import java.util.Objects;

public class GenericsTest8 {
    // Returns max value in a collection - uses recursive type bound
    public static <E extends Comparable<E>> E max(Collection<E> c) {
        if (c.isEmpty())
            throw new IllegalArgumentException("Empty collection");
        E result = null;
        for (E e : c)
            if (result == null || e.compareTo(result) > 0)
                result = Objects.requireNonNull(e);
        return result;
    }

}
```

上記のメソッドはlistが空の時にIllegalArgumentExceptionを発生させる。良い代替案としては、戻り値を```Optional<E>```とすることがあげられる。

* 再帰型境界はもっと複雑になりえるが、まれである。本章で扱ったイディオムと、ワイルドカードを用いる場合（Item31）と、simulated self-type（Item2）を理解すれば、実際に直面する大体の再帰型境界は扱うことができる。
Item 27: Eliminate unchecked warnings

# 27.unchecked warnings は削除せよ

* コンパイラが出すunchecked warningsを全部消すことができれば、そのコードはタイプセーフ、つまり、実行時にClassCastExceptionを発生させることがなくなる。よって、unchecked warningsは全て消すようにするべきである。
* すべてのwarningは消すことができないが、タイプセーフであることを証明できた場合は```@SuppressWarnings("unchecked")```アノテーションを付与する。
タイプセーフであることを証明する前にこのアノテーションを付与してしまうと、コンパイル時にunchecked warnings はでないのに、ClassCastExceptionは出ることとなり、エラー解消を困難にしてしまう。
* ```@SuppressWarnings("unchecked")```の付与はできるだけ小さいスコープにするべきである。

```java
package tryAny.effectiveJava;

import java.util.Arrays;

public class GenericsTest4 {

    private int size;
    transient Object[] elementData; // non-private to simplify nested class access

    public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            @SuppressWarnings("unchecked")
            T[] result = (T[]) Arrays.copyOf(elementData, size, a.getClass());
            return result;
        }
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }
}
```

* ```@SuppressWarnings("unchecked")```を使用するときは、なぜそれが安全なのか理由を記載すべき。
記載することによって、コードの理解の助けになるし、誰かが安全でない演算となるような変更を加える機会は減る。
Item 26: Don't use raw types

# 26.raw タイプは使ってはならない

* rawタイプとは、型パラメータなしで宣言されたジェネリック型のことを指す。例えば、List< E > に対する、List のようなものをrawタイプと呼ぶ。
* rawタイプを用いると、型パラメータを明確にして宣言したジェネリクス型であればコンパイル時に検出できた誤りが、実行時まで検出されなくなる。

```java
package tryAny.effectiveJava;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class GenericsTest1 {

    public static void main(String[] args) {
        final Collection stamps = Arrays.asList(new Stamp(), new Stamp(), "");
        // 以下のコードだとコンパイルエラーとして検出してくれる。
        // final Collection<Stamp> stamps = Arrays.asList(new Stamp(), new Stamp(), "");
        for (Iterator i = stamps.iterator(); i.hasNext();) {
            Stamp stamp = (Stamp) i.next(); // 3つ目の要素をキャストするときにエラー送出。実行時に初めてわかる。
            System.out.println("cast success");
        }
    }

    static class Stamp {

    }
}
```

* Listのようなrawタイプを使うべきではないが、任意の型を許容する、List< Object > のようなジェネリック型は使用してもよい。
大まかに、この2つの違いは、前者はジェネリックに適応していないが、後者はコンパイラに明確にどのような型も許容すると明確に示している。
例えば、List< String >をList型に入れることはできるが、List< Object >に入れることはできない。

```java
package tryAny.effectiveJava;

import java.util.ArrayList;
import java.util.List;

public class GenericsTest2 {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        unsafeAdd(strings, Integer.valueOf(42));
        String s = strings.get(0); // Has compiler-generated cast
    }

    private static void unsafeAdd(List list, Object o) {
        // 以下のコードにするとコンパイルエラーにしてくれる。
        // private static void unsafeAdd(List<Object> list, Object o) {
        list.add(o);
    }

}
```

* 要素となる型が何であれ構わない場合にはrawタイプを使いたくなるかもしれないが、**?**のワイルドカードを使うべきである。
これらの違いも型安全性にある。

```java
package tryAny.effectiveJava;

import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class GenericsTest3 {

    public static void main(String[] args) {
        Set<?> s1 = Stream.of("2", "b", 1).collect(Collectors.toSet());
        Set s2 = Stream.of("2", "c", 1).collect(Collectors.toSet());

        // s1.add("c"); // このコードはコンパイルエラーとなる
        s2.add("b");

        System.out.println(numElementsInCommon(s1, s2));
    }

    // Use of raw type for unknown element type - don't do this!
    static int numElementsInCommon(Set<?> s1, Set<?> s2) {
        int result = 0;
        for (Object o1 : s1)
            if (s2.contains(o1))
                result++;
        return result;
    }
}
```

* rawタイプを使うべきでないという規則の例外が少数ある。
  * クラスのリテラルに型パラメータを使ったジェネリック型を指定することはできない。つまり、List.classやString[].classは許されるが、List< String >やList< ? > は許されない。
  * instanceof を型パラメータを使ったジェネリック型に対して使うことはできないので（Unbounded wildcard type除く）、その時はrawタイプで検査する。

```java
// Legitimate use of raw type - instanceof operator
if (o instanceof Set) {       // Raw type
    Set<?> s = (Set<?>) o;    // Wildcard type
    ...
}
```
Office365で使うレジストラはSRV使えなくてもNS使えれば大丈夫ぽい

Office365で独自ドメインを使う場合「**Office365で独自ドメインを使うには、SRVレコードに対応しているレジストラを探さなきゃいけない！**」、そんな風に思っている人多いのではないでしょうか？私もそう思っていました。

しかし先日、たまたまOffice365のドキュメントを見ていた時に以下の記述を発見しました。

> メールなどのOffice 365 services を使用してドメインをセットアップするには、ドメインレジストラーでドメインのネームサーバー (または NS) レコードを変更して、 Office 365プライマリとセカンダリのネームサーバを参照します。その後、 Office 365は dns をホストしているため、サービスに必要な dns レコードが自動的に設定されます。
> （引用元） https://support.office.com/ja-jp/article/a8b487a9-2a45-4581-9dc4-5d28a47010a2#bkmk_nameservers

えっ！うん？ネームサーバー（又はNSレコード）が変更できればいいの？ってことはSRVレコードが使える使えないとか関係ないじゃん。ふーん。

ということで半信半疑ながら試してみました。

試してみたところ…本当ぽいです。実際にSRVレコードに関係するであろうSkype for Business Onlineは使って試してみませんがDNSレコードをみる限りでは大丈夫かなって思います。既に運用しているドメインの場合は簡単にネームサーバー（又はNSレコード）変更という訳にはいかないとは思いますが、これから新規取得する場合なら検討価値はあるんじゃないかなって思います。

ポイントは「オンラインサービスの設定」画面でした。**ここでデフォルトのまま「自分の代わりにオンラインサービスを設定する（推奨）」を選択すればいい。**がポイントとなります。というわけでそのまま「次へ」をクリックします。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/128670/4af2cd8b-8107-dfdd-bf02-ebc13d3d01b1.png)|
|---|

すると次の画面で「Webサイトのレコードの追加」が表示されます。これは後からでも追加できますので、そのまま「次へ」をクリックします。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/128670/e7b0d390-0ac2-87c2-3ed0-6af6464d336f.png)|
|---|

すると次の画面でOffice365のDNSサーバーのアドレスが表示ます。今回の場合は4つ表示されました。表示されたアドレスをレジストラのネームサーバー変更のところで設定し反映されるのを待って「確認」ボタンをクリックします。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/128670/000b86b3-345c-8268-4614-b66773880059.png)|
|---|

まぁなんということでしょう！これだけで終わってしまいました。反映されるのを待って、念のため host コマンドで確認をしてみます。 nslookup の場合は `nslookup -query=ns **********` のような感じで同等のことができます。

```text:DNS情報の確認（Ubuntu）
domain=********　#********はドメイン名（例:qiita.com）
host -t ns $domain
host -t txt $domain
host -t mx $domain
host -t cname lyncdiscover.$domain
host -t cname autodiscover.$domain
host -t cname sip.$domain
host -t srv _sip._tls.$domain
host -t srv _sipfederationtls._tcp.$domain
```

```console:DNS情報の確認結果（Ubuntu）
$ domain=********
$ host -t ns $domain
******** name server ns3.bdm.microsoftonline.com.
******** name server ns4.bdm.microsoftonline.com.
******** name server ns1.bdm.microsoftonline.com.
******** name server ns2.bdm.microsoftonline.com.

$ host -t txt $domain
******** descriptive text "v=spf1 include:spf.protection.outlook.com -all"
******** descriptive text "mscid=********************************"

$ host -t mx $domain
******** mail is handled by 0 ********-net01e.mail.protection.outlook.com.

$ host -t cname lyncdiscover.$domain
lyncdiscover.******** is an alias for webdir.online.lync.com.

$ host -t cname autodiscover.$domain
autodiscover.******** is an alias for autodiscover.outlook.com.

$ host -t cname sip.$domain
sip.******** is an alias for sipdir.online.lync.com.

$ host -t srv _sip._tls.$domain
_sip._tls.******** has SRV record 100 1 443 sipdir.online.lync.com.

$ host -t srv _sipfederationtls._tcp.$domain
_sipfederationtls._tcp.******** has SRV record 100 1 5061 sipfed.online.lync.com.

```

きちんと作成されているようです。面倒なレコード編集はほとんどすることなく設定ができてしまいました。
Effective Java 3章

# 3章.全オブジェクト共通のメソッド

* この章ではObjectsのメソッドオーバーライド方法を中心にまとめられている。

# 10.equalsのoverrideは一般契約（general contracts）に従うべし

* 一般契約とは、反射性（reflexive）,対照性（symmetric）,推移性（transitive）,整合性（consistent）,非 null 性（non-null）のこと。
* googleのAutoValueを使えば、うまくequalsのオーバーライドを行ってくれる。

# 11.equalsをオーバーライドする場合はhashcodeもオーバーライドせよ

* hashCodeの一般契約によると、等しい2つのオブジェクトは等しいhashCodeの値を返さねばならない。よって、equalsをオーバーライドして、論理的に等しいが同じ参照ではない場合も等しいとする場合には、hashCodeをオーバーライドしないままだと異なった値を返すことになってしまう。



* 性能を気にする場合は、hashCodeで計算された値をキャッシュしておく。

# 12.常にtoStringをオーバーライドせよ

* Thread.javaのtoStringは以下のよう。

```java
    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                           group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]";
        }
    }
```

# 13.cloneをオーバーライドするときは注意せよ

* super.cloneを呼んでキャストをする。mutableな変数がある場合はdeepcopyして対応する。

* 大体の場合において、cloneメソッドでオブジェクトのコピーを作るよりも、コンストラクタやファクトリメソッドで作るほうが容易である。唯一、配列のコピーはcloneのほうがうまくやれる。


# 14.Comparableを実装することを考慮せよ
* Javaライブラリの値クラスは、enumも含めておおむねComparableを実装している。
* BigDecimalについて、equalsではBigDecimal("1.0")とBigDecimal("1.00")は異なる扱いになるが、compareToでは同じ扱いになる。そのため、HashSetにこれらの2つを入れたときには、2つの要素が残るが、TreeSetに入れた場合には、1つになる。
* compareToの中で、不等号を使って比較を行うことは冗長で、エラーの要因となりうるので、プリミティブ型のラッパークラスのcompareを使うべき。
* 複数キーでのソートを考える場合、Comparatorのコンストラクションメソッドを使うことを考慮に入れる。1つずつ比較して、if文で分けていくよりもこちらのほうが性能が良いらしい。


```java
package tryAny.effectiveJava;

import static java.util.Comparator.*;
import java.util.Comparator;
import java.util.stream.Stream;

public class CompareTest {
    public static void main(String[] args) {
	Stream<PhoneNum> s = Stream.of(new PhoneNum(111, 222, 333), new PhoneNum(111, 222, 222),
		new PhoneNum(111, 333, 111), new PhoneNum(000, 999, 1));
	s.sorted().forEach(System.out::println);
    }
}

class PhoneNum implements Comparable<PhoneNum> {
    int areaCode;
    int prefix;
    int lineNum;

    public PhoneNum(int areaCode, int prefix, int lineNum) {
	this.areaCode = areaCode;
	this.prefix = prefix;
	this.lineNum = lineNum;
    }

    private static final Comparator<PhoneNum> COMPARATOR = comparingInt((PhoneNum pn) -> pn.areaCode)
	    .thenComparingInt(pn -> pn.prefix).thenComparingInt(pn -> pn.lineNum);

    @Override
    public int compareTo(PhoneNum pn) {
	return COMPARATOR.compare(this, pn);
    }

    @Override
    public String toString() {
	StringBuilder sb = new StringBuilder();
	sb.append("areaCode:").append(areaCode).append(",prefix:").append(prefix).append(",lineNum:").append(lineNum);
	return sb.toString();
    }
}
```
Effective Java 2章

# 2章.オブジェクトの生成、削除

# 1.コンストラクタの代わりにstaticなファクトリメソッドの作成を考慮すべし

# 2.コンストラクタの引数が膨大になるときはbuilderを使うべし

* telescoping constructor と JavaBeansパターンなるものと対比させている。
* インスタンス生成において、パラメータが片手で数えられるよりも多くなるような場合にはbuilderパターンでのインスタンス生成を考えたほうが良い。
* JavaBeansパターンとするときの欠点の説明がよく分からなかった。複数回の呼び出しがあるから不整合が起きうる、みたいな話だが具体的にどういうこと？

# 3.シングルトンなクラス設計をするにおいては、コンストラクタをprivateにするか、ENUMを用いる手法とせよ

* ENUM型使ったシングルトンみたことないが。。

# 4.インスタンス化を抑制したいクラスには、privateコンストラクタを作成せよ

* utilityクラス等はインスタンス生成を抑制したいので、その時に使う模様。

# 5.リソースのハードコーディングを行うより、Dependency Injectionを行うべし
* 大きな規模になった場合には、フレームワークのDIの仕組みを使うべき。
* Factoryパターンを使う。
* この項目は第2版にはなかったよう。

# 6.不必要なオブジェクト生成は避けるべし
* defensive copyが必要な場合はその限りでない。defensive copyってなんだ？

# 7.使わなくなった参照は廃棄すべし
* 廃棄しないとメモリリークが起きる。
* キャッシュやコールバックを持つクラスで起こりがちな問題らしい。
* 弱参照？→以下が分かりやすい。弱参照は他からの参照（弱参照以外の参照）がなくなると、GCの対象となる。
<http://www.ne.jp/asahi/hishidama/home/tech/java/weak.html>

# 8.finalizerとcleanerの使用は避けるべし
* これらの短所は、どのように動くかの予想がつきにくいことにある。
* finalizerはパフォーマンスに深刻な悪影響を与える。
* finalizerの使用はセキュリティに悪影響を与える。以下に詳しく乗っていたが、正直よくわからん。。
<https://www.ibm.com/developerworks/jp/java/library/j-fv/index.html>
* これらの使用の代わりに、AutoClosableの実装とtry-with-resourcesを用いていく。

# 9.try-finallyよりもtry-with-resourcesを使うべし
* try-finallyでtry句とfinally句で同時に例外発生した場合、try句のほうがかき消されてしまう。
R for Data Science 学習記録 #1 ggplot2

# 挨拶
レンウッドといいます。Hadley Wickham氏のR for Data Scienceを学習するにあたり、記録を残していこうと思います。
ここ誤解してるよ、とか、こうした方がいいよ、とかアドバイスあったらありがたいです。
R for Data Science: http://r4ds.had.co.nz/
# 基本構文
```
ggplot(data = <DATA>) + 
  <GEOM_FUNCTION>(
     mapping = aes(<MAPPINGS>),
     stat = <STAT>, 
     position = <POSITION>
  ) +
  <COORDINATE_FUNCTION> +
  <FACET_FUNCTION>
```
## 各要素の(自分なりの)説明
- `<DATA>`  
グラフの元となるデータ

- `<GEOM_FUNCTION>`  
グラフの種類を決める。以下代表的なもの  
geom_point: 散布図  
geom_jitter: 散布図に、点が重ならないようノイズを加えたもの  
geom_smooth: なめらかな線  
geom_bar: 度数の棒グラフ  
geom_col: 度数ではなく、別の変数の値を取れる棒グラフ  
geom_boxplot: 箱ひげ図  
など

- `<MAPPINGs>`  
グラフの要素を指定する。変数や色など。

- `<STAT>`  
グラフに使われる計算。geomと対応しているものもある。

- `<POSITION>`  
グラフの棒や色などの配置方法。identity, fill, dodge, jitterなどがある。

- `<COORDINATE_FUNCTION>`  
グラフを横にしたり、極座標に変えたりする。

- `<FACET_FUNCTION>`  
カテゴリごとにグラフを分けることができる。

# よくわからなかったところ
`geom_area()`が何をやるものなのかよくわからなかった。  
```
ggplot(data = mpg) + geom_area(mapping = aes(x = displ, y = cty, group = class, fill = class))
```
の結果が、
<img width="363" alt="geom_area_result.png" src="https://qiita-image-store.s3.amazonaws.com/0/303832/2cef575d-dfc4-c20b-3a79-fc57120d8e47.png">

何これ？  
後で分かったら記事にするかも。
Python学習

# 参考にした書籍
わかるPython[決定版] 

# インストール関連
## ダウンロードしたバージョン
2018/10/21時点の最新バージョン
https://www.python.org/downloads/windows/
python-3.7.1-amd64.exe

## インストール確認
コマンドプロンプトを起動して

```patch
python ←エンター

C:\xx>python
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
これがでればOK
抜けるときは、「ctrl + Z」
bash のスクリプトが環境変数でパスが通ったディレクトリにいるか確認・判断する（カレントディレクトリ）

macOS や RaspberryPi（Raspbian）のシェル・スクリプト（bash）で、**スクリプトのディレクトリがパスの通ったディレクトリにあるか確認したい**のです。

[「`bash カレント ディレクトリ 環境変数 パス 確認`」と Qiita 記事に絞ってググって](https://www.google.co.jp/search?q=site%3Aqiita.com+bash+%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%88+%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA+%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0+%E3%83%91%E3%82%B9+%E7%A2%BA%E8%AA%8D)も出てこなかったので、俺様ググラビリティの備忘録として。

## TL;DR

環境変数のパス（`$PATH`）を配列で取得してループ処理

```bash:bash
#!/bin/bash

# 環境変数のパスを配列で取得
IFS=: eval 'list_path=($PATH)'

# 配列をループ
for e in "${list_path[@]}"; do
    if [ $e = $SCRIPT_DIR ] ; then
        echo $e
    fi
done
```

## TS;DR

使いやすいように関数化してみました。もっとスッキリした書き方がある気もします。

```bash:bash
#!/bin/bash

is_pwd_in_path() {
    IFS=: eval 'LIST_PATH=($PATH)'
    DIR_SCRIPT=$(cd $(dirname $0); pwd)
    
    for e in "${LIST_PATH[@]}"; do
        if [ $e = $DIR_SCRIPT ] ; then
            return 0
        fi
    done
    
    return $BASH_LINENO
}

if is_pwd_in_path ; then
    echo 'Is in path'
else
    echo 'Not in path'
fi
```

## 動作確認済み環境

- macOS HighSierra（OSX 10.13.6）
    - `bash --version`: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
- Raspbian GNU/Linux 8 (jessie)
    - `bash --version`: GNU bash, バージョン 4.3.30(1)-release (arm-unknown-linux-gnueabihf)

## 参考文献

- 「[環境変数$PATHの見難い文字列をリストでキレイに表示するシェルスクリプト](https://qiita.com/kenji0x02/items/80e505f3a776574db272)」@ Qiita 
- 「[配列のデータを参照する | bash 配列まとめ](https://qiita.com/b4b4r07/items/e56a8e3471fb45df2f59#-%E9%85%8D%E5%88%97%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%82%E7%85%A7%E3%81%99%E3%82%8B)」@ Qiita
- 「[[bash] 実行スクリプトの絶対パスの取得](https://qiita.com/koara-local/items/2d67c0964188bba39e29)」@ Qiita
- 「[bashでIFSを使わずにsplitする方法](https://qiita.com/tommarute/items/0085e33ac9271fbd74e1)」@ Qiita
[Ruby]基本的な文法、変数、条件分岐などについて

RubyはWEBアプリケーションの「システム」をつくるためのプログラミング言語です。
ｃRubyを動かす
***Rubyを実行する***
`puts "○○"`
・文字列はクォーテーション（ ' もしくは " ）で囲みます。
・数値は文字列と違いクォーテーションで囲みません。
足し算には「+」、引き算には「-」、掛け算は「*」(アスタリスク)、割り算は「/」(スラッシュ)という記号を用います。また「%」を用いると、割り算の余りを計算できます。
・行の先頭に「#」を書くと、その行がコメントになります。
#変数を使う
***変数の使い方***
`変数名 = "文字列"or値`
「=」は「等しい」という意味ではありません。プログラミングの「=」は「左の変数に右の値を入れる」という意味で、これを代入といいます。
`puts 変数名`
変数を使う時に変数をクォーテーションで囲みません。
***変数名のルール***
Rubyではいくつか命名のルールがあります。
・英単語
・2語以上を組み合わせた変数名をつけるときは、アンダーバー（_）を用いる
***変数の更新***
1.変数の値を変更する
`number = x`
`number = y`
一度値を代入した変数に、その後再び値を代入すると、後に代入した値で変数の中身が上書きされます。
2.自分自身に代入する
`number = x`
`number = x + 値`　→ `x += 値`(省略形)
`number = x * 値`　→ `x *= 値`(省略形)
***変数展開*** 
変数が数値の場合、文字列と足し算で連結することはできません。
`number = x`
`puts "文字列#{変数名}文字列"`
注意点：ダブルクォーテーションを使った文字列の場合しか変数展開はされません。
#条件分岐
***if文***
`if条件式
　puts "○○"
end`
***比較演算子***
1.真偽値
`score = 70
puts score > 60`
→true
`score = 55
puts score > 60`
→false
※if文と真偽値
`score = 70
if true
　puts "○○"
end`
2.比較演算子の一
`socre 90
puts score < 60
puts score <= 90
puts score > 90
puts score >= 99`
3.比較演算子の二
`socre 70
puts score == 100
puts score != 80
name = "Jess"
puts name == "Jess"
puts name != "Jess"`
***else***
`if条件式
　puts "○○"
else
  puts "○○"
end`
***elsif***
`if条件式
　puts "○○"
elsif条件式
　puts "○○"
else
  puts "○○"
end`
***その他***
かつ　&&
または　||
TypeScriptでObject.valuesを使いたい

TypeScriptでObject.valuesメソッドを使いたい！・・・が使おうとしたらコンパイル時に
`Property 'values' does not exist on type 'ObjectConstructor'.`
とエラーが出て少しハマったので調べてみた。

## 原因と解決方法
Object.values()はES2017で追加されたメソッド。
ES2017で追加されたメソッドを使う場合、コンパイルに使うライブラリファイルをES2017以上にしないと正しくコンパイルすることができない。

ちなみに、ES2017で追加されたメソッドは以下の通り。

* [Object.values()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/values)
* [Object.entries()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)
* [Object.getOwnPropertyDescriptors()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors)
* [String.prototype.padStart()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/padStart)


解決するためには、tsconfig.jsonのcompilerOptionsのlibにES2017を加えてあげればOK。

```diff:tsconfig.json
{
  "compilerOptions": {
-    "lib": [ "es6", "dom"],
+    "lib": ["es2017", "dom"],
  }
}
```

これで、ES2017で追加されたメソッドが正しく動くようになりました。
Sequel ProでX2サーバーからRDSにDB移行

#他サーバーのダンプデータをRDSに引っ越し
稼働中のX２サーバーからDBをダンプして来たので新しく作ったRDSに移動します

##Sequel Proの起動
![Sequel_Pro.png](https://qiita-image-store.s3.amazonaws.com/0/303062/9198510d-f3cc-10e4-3f2a-f0e16ff99194.png)
[Sequel Pro](http://www.sequelpro.com/)
上記の公式サイトからダウンロード
Sequel Pro 1.1.2
![Sequel1.png](https://qiita-image-store.s3.amazonaws.com/0/303062/5ba3b641-62ff-6fb4-0eb7-7d56cb45216f.png)
開くとこんな感じなので
SSHに必要な情報を入れていく

**RDSの情報**
・　MySQLホスト（エンドポイント: *****.ap-northeast-1.rds.amazonaws.com）
・　ユーザー名(RDS作成時に設定したユーザー名)
・　パスワード(RDS作成時に設定したパスワード)
・　データベース（オプション）
・　ポート（オプション）

**EC2の情報**
・　SSHホスト（EC2インスタンスのPublic DNSかElasticIP）
・　SSHユーザ(ec2-userやubuntuなど)
・　SSH鍵（EC2 keypairの秘密鍵: ~/.ssh/key.pemなど）
・　SSHポート(オプション: 22)

##データベースを追加
左上の`データベースを選択`からデータベースを追加
エンコーディングと照合順序はデフォルトで

SQL形式でダンプしてきたDBを移行しようとしたがエラーが発生してしまったので、それの解決にかなり手間取ってしまいました
それは別のところで備忘録にします
[ダンプしたDBをRDSに移そうとしたらEncoding Error](https://qiita.com/BKO/items/e2d07b0efff8d2ecba75)

##終わりに
引っ越しのついでに古い形式からInnoDBに変更
もともとMyISAMだったので綺麗にしました
![Seq_pro.png](https://qiita-image-store.s3.amazonaws.com/0/303062/23ed11ff-d18c-0755-22d5-2ecfa8008f91.png)
`情報`から全部確認できました
Google ChromeでJSを1行ずつ実行させる

こんにちは（◞‸◟）
Google Chromeの検証がすごいって話をしたいです（◞‸◟）

---

こんなかんじのがあったとします

```HTML:HTM:
<button id="a">ボタンA</button>
```
```JavaScript:Jquery
$('#a').on('click',function(){
    console.log('アラート出すよ'); //1
    alert('ボタンAが押されたよ!!'); //2
});
```

押すと、ログが出て、アラートが出ます。そりゃそうだ

# このJSを１行ずつ実行する

<img width="723" alt="スクリーンショット 2018-10-21 18.53.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/123531/baaa381b-746c-0822-89ea-fa5814f67277.png">

`右クリック -> 検証 -> Sources`
そして、止めたいところの行をクリックすると青い矢印が出てくる😀

そしてボタンAをクリックすると、、、

<img width="1079" alt="スクリーンショット 2018-10-21 18.57.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/123531/e6e1f41a-39be-0c53-e6b7-926f86276e9b.png">

とまった!!!!
Consoleを見てみると。。。

<img width="1099" alt="スクリーンショット 2018-10-21 18.55.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/123531/4356adf1-e5d1-f8a7-fdde-5ce9b072e9d9.png">

アラート出すよ、というメッセージが出ています。
そこで止まっています。
ピンクの丸を押すと、次の行に進みます↓

<img width="1095" alt="２.png" src="https://qiita-image-store.s3.amazonaws.com/0/123531/74962a1b-dd50-ccdc-d678-da783ea0ba69.png">

---

### 嬉しいこと
#### ここのJS通ってるかな〜って調べるときに使える
通ってれば、そこの時点で止まってくれる！！
JSが入り組んでる時とかに使うとハッピーな気持ちになれる🐤

#### その時点でのオブジェクトの様子が見られる
Consoleでthisとか打つと、その時点でのthisがなんなのかとかがわかる！
この時点でのthisに何入ってるんだ🤔という状況や、
ちゃんとthisの中に自分の欲しいものが入ってるかどうかとかが調べられる！
（thisだけじゃなくて、変数でも調べられるけど、私はthisでめっちょ使った、、）

#### 関数の中に潜っていって、どの順番で通ってるか見られる
ここには例としてあげられないのですが、
自分がつけた青い矢印の関数の中に潜ることもできます！
順番もおうこともできます！！便利〜〜

---

検証でHTMLをみるだけしか使ってなかったので、多機能で驚いた、、
みんなも使おう🐰（すでに使ってるか）
略語辞書 for Excel

##これは何か
Excelで書かれた資料の中で知らない略語があったときに、そのセルを選択して[F10]キーを押すと、
ウィンドウ下部のステータスバーに意味が2秒間表示されるというマクロ
<img width="439" alt="png3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/164214/b0c4c75c-9def-065d-cb86-77f1dee1dfee.png">

##準備
辞書用ブックのシートに、略語とその意味を記しておく
（本当は辞書になかったらWikipediaを調べて辞書に追加するところまで作ろうと思ってた）
<img width="429" alt="png1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/164214/69195d7b-de77-9a43-dbb4-aee0311651e8.png">

##コード
・参照設定
  　　Microsoft Scripting Runtime
  　　Microsoft VBScript Regular Expression 5.5

```vb 
'thisworkbook.cls

Option Explicit

Dim MyDictionary As New Dictionary
Dim RYAK_EX As New RegExp
Dim RYAK_PA As New RegExp

Private Sub Workbook_Open()
    Application.OnKey "{F10}", "Thisworkbook.main"
    MakeDictionary
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Application.OnKey "{F10}"
End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    MakeDictionary
End Sub

Sub MakeDictionary()
    On Error Resume Next
    With RYAK_EX
        .Pattern = "^[A-Z][A-Z0-9\-]*[A-Z]$"
    End With
    With RYAK_PA
        .Global = True
        .Pattern = "[A-Z][A-Z0-9\-]*[A-Z]"
    End With
    Dim c As Range, ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        For Each c In ws.Cells.SpecialCells(xlCellTypeConstants)
            If RYAK_EX.Test(c.Value) Then
                MyDictionary(c.Value) = Join(Array(ws.Name, c.Value, ":", c.Offset(, 1).Value))
            End If
        Next c
    Next ws
End Sub

Function LookupDictionary(key As String) As String
    If MyDictionary.Exists(key) Then
        LookupDictionary = MyDictionary(key)
    Else
        LookupDictionary = key & " : "
    End If
End Function

Sub main()
    On Error Resume Next
    Dim str$
    
    Select Case TypeName(Selection)
    Case "Range"
        str = ActiveCell.Value
    Case "Rectangle", "TextBox"
        str = Selection.Text
    Case Else
        Debug.Print TypeName(Selection)
        Exit Sub
    End Select
    
    With Application
        Dim m As Match
        For Each m In RYAK_PA.Execute(str)
            .StatusBar = LookupDictionary(m.Value)
            Wait 2
        Next
        .StatusBar = False
    End With
End Sub

Function Wait(Optional n As Single = 3) As Single
    Wait = Timer + n
    Do While Wait > Timer
        DoEvents
    Loop
End Function
```
array_mergeの添字配列で苦しんだ

# array_mergeとゎ
http://php.net/manual/ja/function.array-merge.php

## question #1

```php
$a = ['a' => 'pyo', 'b' => 'pya'];
$b = ['b' => 'pyapya' , 'c' => 'tero'];

$c = array_merge($a, $b);

// var_dump($c); ??
```

## answer #1

```php
array(3) {
  ["a"]=>
  string(3) "pyo"
  ["b"]=>
  string(6) "pyapya"
  ["c"]=>
  string(4) "tero"
}
```
 - 配列同士がくっつく
 - 連想配列で同じキーであれば、引数が最初にある配列の方が優先される


## question #2

```php
$a = [0 => 'pyo', 1 => 'pya'];
$b = [1 => 'pyapya' , 2 => 'tero'];

$c = array_merge($a, $b);

// var_dump($c); ??
```

## answer #2

```php
array(4) {
  [0]=>
  string(3) "pyo"
  [1]=>
  string(3) "pya"
  [2]=>
  string(6) "pyapya"
  [3]=>
  string(4) "tero"
}
```

 - 添字配列の場合は、新たにキーが振られて配列になる!!


---

このことに気付かず30分時間を費やした（◞‸◟）
Could not create temporary directory: Permission deniedのエラーが表示される際の対処

# 筆者に起きた現象
Vueのプロジェクトをターミナルからrunする際にvscodeで上記のエラーが出た

# 原因
vscodeのキャッシュにアクセス権限がうまく設定されないことが原因のようで、
一度そのディレクトリを削除するとうまくできた

## 対処
```zsh:キャッシュの確認
 ls -la ~/Library/Caches/com.microsoft.VSCode.*/
もしくは
 ls -la ~/Library/Caches/com.microsoft.VSCodeInsiders.*/
```

```zsh:ディレクトリが空の場合、そのディレクトリを削除
sudo rm -Rf ~/Library/Caches/com.microsoft.VSCode.ShipIt
もしくは
sudo rm -Rf ~/Library/Caches/com.microsoft.VSCodeInsiders.ShipIt
```

#参考サイト
[Code won't update on macOS](https://github.com/Microsoft/vscode/issues/7426#issuecomment-301018371)
[Upgrade on MacOS not working](https://github.com/Microsoft/vscode/issues/43793)
Python 正規表現プチまとめ

自分向け記事です。
<pre>
import re
re.match():　パターンマッチング
pattern = re.compile() :　複雑なものは先にコンパイルしてからパターンマッチング
pattern.match()
</pre>

<pre>
match():先頭から一致
search():最初のマッチング（あれば）
findall():重なり合わないすべてのマッチリストを返す（あれば）
split():パターンにマッチしたところでソースを分割し部分文字列のリストを返す
sub():置換文字列を引数を取り、ソースのうちパターンにマッチするすべての部分を置換文字列に置き換える。
</pre>

<pre>
メタ文字	説明	例	マッチする例	マッチしない例
.	任意の一文字	a.c	abc, acc, aac	abbc, accc
^	文字列の先頭	^abc	abcdef	defabc
$	文字列の末尾	abc$	defabc	abcdef
*	０回以上の繰り返し	ab*	a, ab, abb, abbb	aa, bb
+	１回以上の繰り返し	ab+	ab, abb, abbb	a, aa, bb
?	０回または１回	ab?	a, ab	abb
{m}	m回の繰り返し	a{3}	aaa	a, aa, aaaa
{m,n}	m〜n回の繰り返し	a{2, 4}	aa, aaa, aaaa	a, aaaaa
[]	集合	[a-c]	a, b, c	d, e, f
|	和集合（または）	a|b	a, b	c, d
()	 グループ化	(abc)+	abc, abcabc	a, ab, abcd
</pre>

start(), end(),span() による位置情報が必要な場合は inter()を使う！
iterを使用するとstart(),end()などが使える。
findallはlistを返すのでstart(),end()を持っていない。

<pre>
m = re.finditer('[wsh]+', source)
for match in m:
    print(match.group(), match.start(), match.end())

# span()を使ってまとめてstart/endを取得
m = re.finditer('[wsh]+', source)
for match in m:
    start, end = match.span()
    print(match.group(), start, end)
</pre>


<pre>
I (Iとスペース)の後ろにwishが続くところを探す print(re.findall('I (?=wish)', source))
wishの前にI（Iとスペース）があるところを探す  print(re.findall('(?<=I) wish', source))
</pre>

<pre>
m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group(0))  # group(0)はマッチした部分全てを表す。
                   # つまり ' 'で囲った部分にマッチする部分をgroup(0)で受け取ることになる。
print(m.group(1))  # startはgroup(1）から  a dish
print(m.group(2))  # fish
print(m.groups())  # ('a dish', 'fish')
</pre>

(?P<name> expr)という形式を使うとexprにマッチした部分は
nameという名前のグループに保存される。

<pre>
m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
print(m.group('DISH'))  # a dish
print(m.group('FISH'))  # fish
</pre>


sedのような置換もできますね。
\1,\2がsedの置換方式と同じになります。なのであえて名前をつけて処理をしなくてもいいかな。。。という感触です。

<pre>
source1 = '''I wish I may, I wish I might Have a dish of fish tonight.'''
source2 = re.sub(r'(.*dish\b)(.*)(\bfish)(.*)', r'\1\2\4', source1)
log = '{} =>\n{}'
print(log.format(source1, source2))
</pre>

⇓結果
<pre>
I wish I may, I wish I might Have a dish of fish tonight. =>
I wish I may, I wish I might Have a dish of  tonight.
</pre>
git 

# git log

## ポイント

git log 

git checkout id

## 特定のコミットを探し出す

--grep

```
git log --grep=change

changeという言葉が含まれるものを
```

--until 日時によるオプション

```
git log --since 11/11/2018 --nutil 11/11/2019
```
## 差分の確認

```
git log --stat HEAD~..HEAD

git log --patch HEAD~..HEAD
```
[Git]基礎編

Webサイトなどを作る際に、複数人で協力しながら開発していくことがあります。
Gitを使うことでそのような共同開発をスムーズに進めることができます。
***Gitの準備***
`git init`
#共同開発の流れ
コードを変更する＞共有する準備をする＞共有する
共有の仕組み:アップロード→リモート→ダウンロード
***リモートの登録***
`git remote add リモート名 URL`
*一般的には「origin」とすることが多い*
***1.共有の準備***
`git add ファイル名`
***2.選択したファイルを記録する(Commit)***
`git commit -m "メッセージ"`
***3.リモートにファイルをアップロード***
`git push origin master`
***4.リモートにファイルをダウンロード***
`git pull origin master`

#変更の把握と選択
***変更したファイルの把握***
`git status`
add されたファイルが緑色、まだ add されていないファイルが赤色で表示される
***変更した内容の把握***
`git diff`
変更前のコードが赤色、変更後のコードが緑色で表示される。
***コミット履歴の表示***
`git log`＞コミットメッセージだけ
`git log -p`＞変更内容
`Q`キーを押すことで終了できる
TerraformでtfstateファイルをS3で管理する

# TL;DR
Terraformでの`tfstate`ファイルを管理するためにbackendとしてS3を使用する。

# 前提条件
- AWSアカウント
    - CLIから操作できる権限を持つユーザ & AWS-Cliに対するアクセスキーなどの設定
- Terraform
    - **v0.11.0** 以上を使用します。

# 手順
## tfstateファイルを格納するS3バケットを作成する

```:main.tf
terraform {
  required_version = ">= 0.11.0"
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}
```

実行
` $ terraform plan`
からの
` $ terraform apply`

## 作成したS3バケットでtfstateファイルを管理するよう設定する
```:main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state" # 作成したS3バケット
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}
```

`terraform` ブロック内に `backend` ブロックを追記する。

`backend` 設定をいじった後なので、
` $ terraform init` して、
ローカルの `tfstate` をS3にコピーするか聞かれるので `yes` と答えて完了。

## （オプショナル）state lockを有効化する
S3によって複数人でtfstateファイルを扱うことが可能になったが、逆にそれによってデータがコンフリクトしてしまう恐れがある。
そこで、TerraformではDynamoDB（S3の場合）を用いてtfstateファイルの一貫性を保つことができる機能を提供している。

### DynamoDBを作成する

```:main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state"
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

resource "aws_dynamodb_table" "terraform_state_lock" {
  name = "terraform_state_lock"
  read_capacity = 1
  write_capacity = 1
  hash_key = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}
```

これで ` $ terraform apply` する。

### DynamoDBをbackendに設定する

```:main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state"
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
    dynamodb_table = "terraform_state_lock"
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

resource "aws_dynamodb_table" "terraform_state_lock" {
  name = "terraform_state_lock"
  read_capacity = 1
  write_capacity = 1
  hash_key = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}
```

backendの設定を変更したので
` $ terraform init` してあげれば完了。

# 困ったこと
- [Terraform: Up and Running: Writing Infrastructure as Code](https://www.amazon.co.jp/Terraform-Running-Writing-Infrastructure-Code-ebook/dp/B06XKHGJHP)を読みながら学習しているものの、バージョンが古くて参考にならない。
- S3を作らずにbackend設定しようとすると怒られる。
    - `Error loading state: NoSuchBucket: The specified bucket does not exist`が発生する。
    - 関連するIssueの[comment](https://github.com/hashicorp/terraform/issues/16611#issuecomment-343327685)

# 参考資料
https://qiita.com/marshmallow911/items/e8c05f580d07451fcf5e
https://qiita.com/sinshutu/items/7d3cc7438871c50ea63c
databricks cloud上でmatplotlibとかseabornのグラフを表示するスニペット

## コード
こんな感じで `plt.subplots()` を使うと上手く可視化できる。

```.py
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
 
df = pd.DataFrame(np.arange(10).reshape(5,2)) # 元データを適当に作る
 
fig, ax = plt.subplots()
ax = sns.heatmap(df) # axにグラフオブジェクトを渡す(matplotlibでも一緒)
display(fig) # figの方をdisplayに渡す

# こんな感じに書いてもnotebook上にグラフは表示されない
sns.heatmap(df)
plt.show()
```

## 参考

[Matplotlib and ggplot in Python Notebooks](https://docs.databricks.com/user-guide/visualizations/matplotlib-and-ggplot.html)
gulp を使って自動でsass をコンパイルできるようにする

一体何番煎じになる記事だろうか…。
gulp を使ってsass を自動コンパイルできるようにした。

## 【重要】追記(2022/01/02)
gulpfiles.js で「gulp.task～」を使って記述する方法は、2018年12月から非推奨になっているため、この記事は参考程度に読んでください。というのを3年位経った2022年に気づきました…。
別途記事を投稿する予定です。

## ~~事前準備~~
~~gulp を使えるようにするには、予め以下をインストールする必要がある。~~

- ~~node.js~~ 
- ~~Ruby~~
- ~~sass~~

~~これらのインストールについてはOS によって異なるため、省略。~~
(2019年3月22日削除)

## npm init
node.js インストール後、gulp をインストールしたいディレクトリで以下のコマンドを実行する。

```
npm init
```
特に指定がない場合、そのままEnter/Return を押せばよい。
その後、package.json が生成される。


## gulp のインストール
以下のコマンドを実行してgulp をインストールする(グローバルと開発用)。

```.zsh
npm install gulp -g
```

```.zsh
npm install gulp --save-dev
```

gulp-sass も必要になるため、以下のコマンドを実行させてインストールする。

```.zsh
npm install gulp-sass --save-dev
```

## gulpfile.js の設定
gulpfile.js を作成し、.scss ファイルの格納場所やコンパイルしてできた.css ファイルをどこに出力させるか、などの設定を記述する。

今回の記述例は以下のとおり。参考URL をとても参考にした。

```.js
const gulp = require('gulp');
const sass = require('gulp-sass');

// sassとcssの保存先
gulp.task('sass', function(){
    gulp.src('./sass/**/*.scss')
        .pipe(sass({outputStyle: 'expanded'}))
        .pipe(gulp.dest('./css/'));
});

//自動監視
gulp.task('sass-watch', ['sass'], function(){
    var watcher = gulp.watch('./sass/**/*.scss', ['sass']);
    watcher.on('change', function(event) {
    });
});

gulp.task('default', ['sass-watch']);

```

gulp をコマンドで起動すると自動で.scss ファイルの監視が始まる。
sass ディレクトリに作成された.scss ファイルが編集されて更新された時、自動でコンパイルして.css を生成する。css ディレクトリにコンパイルした.css ファイルを出力するようにしている。出力された.css ファイルは、expanded 形式で出力。

## gulp の起動
package.json があるディレクトリ内で以下のコマンドを実行すると、.scss ファイルの自動監視が始まる。

```
% gulp
[17:18:43] Using gulpfile ~/hoge/gulpfile.js
[17:18:43] Starting 'sass'...
[17:18:43] Finished 'sass' after 6.81 ms
[17:18:43] Starting 'sass-watch'...
[17:18:43] Finished 'sass-watch' after 11 ms
[17:18:43] Starting 'default'...
[17:18:43] Finished 'default' after 21 μs

```

## 参考URL
ありがとうございました。
https://qiita.com/M_amourr/items/09c8bb4e2b2981cafe7a
WordPressのローカル開発環境にDocker(docker-compose)を用いて開発環境を構築

Wordpressのテーマをカスタマイズするにあたりローカルで作業する必要があったのですが、MAMPの調子が悪く、新しく開発環境を作らねばならなくなりました。 それならばDocker先生にお世話になろうとdocker-composeにてローカル開発環境を構築したのでここに記します。

## 作業環境
* OS: macOS High Sierra 10.13.2
* Docker Version: 17.09.1-ce-mac42 (21090)
* docker-compose version: 1.17.1, build 6d101fb

## 作業内容
```
$ mkdir work_dir
$ cd work_dir
$ vi docker-compose.yml
Note-----------------
以下を記述

version: '2'
services:
  db:
    image: mysql:5.7
    volumes:
      - "./.data/db:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    ports:
      - "3306:3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - ./public_html:/var/www/html
    links:
      - db
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: wordpress
-----------------------
$ mkdir .data public_html
```

作業自体は以上となります。 
後は解説なので気になる方だけ見てください。 
今回作成するコンテナは2つで、dbとwordpressそれぞれが立ち上がるものとなります。 どちらも公式のイメージを用い、

```
services:
  db:
    image: mysql:5.7

  wordpress:
    image: wordpress:latest
```
コンテナとホストでディレクトリを共有しています。

```
services:
  db:
    volumes:
      - "./.data/db:/var/lib/mysql"

  wordpress:
    volumes:
      - ./public_html:/var/www/html
```

また、環境変数は `.env`を作らず、ベタで書いています。 
今回はローカルでのみを想定しているため問題ないかな？という判断ですね。
後は以下のようにコンテナ立ち上げ時の順番を定義(depends_on)して、dbコンテナにwordpressコンテナからリンクを貼り参照できるようにした感じですね。

```
  wordpress:
    depends_on:
      - db
    links:
      - db
```
あまり複雑な事をせず、簡単な設定で仮想環境を立ち上げられるのは本当に便利ですね。 docker-compose感謝です。
kotlinで表にボタンやテキストビューを動的に生成する方法

# 初めに
Androidアプリを製作している途中で状況に応じて、表を動的に生成する必要が出たのでそのメモです。
kotlinを使用して、Androidアプリ上のtablelayoutの行にボタンやテキストビューを含めて動的に追加する方法について書き残します。

**※Android初心者が書いています。**

# 環境
- Kotlin
- Android Studio 3.2

# プログラム
下記のような構成になっています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212276/801d00c8-c6bb-d3cc-215b-4beb8e0cd7ea.png)

## MainActivity
getLayoutInflater().inflate()を使用します。

```kotlin

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val vg = findViewById<View>(R.id.tableLayout) as ViewGroup
        for (i in 0 until 5 ){
            getLayoutInflater().inflate(R.layout.table, vg)
            val tr = vg.getChildAt(i) as TableRow;
            //textviewに文字を格納
            ((tr.getChildAt(0)) as TextView).setText(i.toString())
            //buttonの動的追加と押されたときの処理の記載
            ((tr.getChildAt(1)) as Button)?.setOnClickListener {
            //この中に処理を書きます
            }
      }
    }
}


```

## activity_main.xml

```kotlin

    <TableLayout
        android:id="@+id/tableLayout"
        //この間は、layoutの情報//////////////////////
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ////////////////////////////////////////////
        android:stretchColumns="1">
    </TableLayout>

```

## table.xml
Layout直下にtable.xmlが入っており、どのような行を追加していくかを記述します。
今回はtextviewとbuttonを追加します。

```kotlin

<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingVertical="5dp">

    <TextView
        android:layout_width="149dp"
        android:layout_height="46dp"
        android:gravity="center_horizontal|center"
        android:textSize="18sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="153dp"
        android:layout_height="wrap_content"
        android:text="Button"
        android:textSize="18sp" />
</TableRow>

```

# これらを動かすと…
下記のようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212276/6f57183e-7406-72e2-0012-67dc18bec017.png)
【Mac】確認ダイアログの選択をキーボードのショートカットキーで操作する方法

**確認ダイアログ**とはポップアップで表示される以下のようなものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/140792/6bc617d2-056b-15be-ca5a-8bf059a7f168.png)

Macだとデフォルトではショートカットキーで確認ダイアログの選択肢を変更することができません。

しかし、『システム環境変数→ショートカット→キーボード』と進み、『すべてのコントロール』にチェックをつけるとキーボードで確認ダイアログを操作することが可能になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/140792/d97b9ed7-876c-d474-0341-1e8715db987f.png)

なお、確認ダイアログにおけるキーボード操作については、選択肢の移動はTabキー、決定はSpaceキーとなります。