OmniAICreator/Qiita-1.07M huggingface dataset:
Project Euler 51をPythonでやってみる

最近趣味としてやっているProject Eulerの自分なりの解答です。問題 50までは結構解答あったので51からやります。コード読みづらくてすいません…
# 問題 51
□3の第1桁(□の部分)を置き換えることで, 13, 23, 43, 53, 73, 83という6つの素数が得られる.
56□□3の第3桁と第4桁を同じ数で置き換えることを考えよう. この5桁の数は7つの素数をもつ最初の例である: 56003, 56113, 56333, 56443, 56663, 56773, 56993. よって, この族の最初の数である56003は, このような性質を持つ最小の素数である.
桁を同じ数で置き換えることで8つの素数が得られる最小の素数を求めよ. (注:連続した桁でなくても良い)
# 解答
今回の使ったポイントは次の3つです。
1. □の数は3の倍数個である必要がある。
2. 条件を満たす素数は4桁以上である必要がある。
3. 素数が8個出るには□が0,1,2のいづれかであるとき素数である必要がある。

1について少し解説します。
なぜ３の倍数個でなければいけないのか？
結論から言ってしまうと、３の倍数個でないときでは置き換えによって現れる10個の数字のうち3つ以上が素数ではなく(具体的には3の倍数)になってしまうからだ。
3の倍数になるかどうかの判定として各桁を足して３の倍数となるかどうかというものがある。
ここで置き換えにによって現れる数字の各桁をを足すと次のようになる。
$$b \cdot n+c$$
ただし、$b$は□の値、$n$は□の個数、$c$は□以外の桁の和
ここで$n$(□の個数)を３の倍数でないとすると次の２パターンのどちらかになる。

```math
\begin{align}
b \cdot n+c &= b \cdot (3k+1)+c \\
&= 3bk+b+c
\end{align}
```

```math
\begin{align}
b \cdot n+c &= b \cdot (3k+2)+c \\
&= 3bk+2b+c
\end{align}
```
$3bk+b+c$も$3bk+2b+c$も3つごとに３の倍数になるので置き換えによって３の倍数が３個または４個現れることになる。よって□の個数は3の倍数である。

話は戻って1,2,3を取り入れコードを書く。

```python:ProjectEuler51.py
import sympy as sym
from itertools import combinations

def make_num(n,star_pos,star_num):
    n_list = list(n)
    for i in star_pos:
        n_list[i] = star_num
    return int(''.join(n_list))

def make_star_pos(n_list,x,star_tpl):
    x_num = 0
    star_pos = list()
    for pos in range(len(n_list)):
        if n_list[pos] == str(x):
            if x_num in star_tpl:
                star_pos.append(pos)
            x_num += 1
    return star_pos


def main(number):
    n_max = 8
    for k in range(4,n_max):
        prime = [i for i in sym.primerange(10**(k-1), 10**k)] # k桁の素数
        for n in prime:
            n_str = str(n)
            n_list = list(n_str)
            for x in range(3): # 0,1,2が3つ以上必要
                a = n_str.count(str(x))
                if a >= 3:
                    for i in range(3, a+1, 3): # i:*の数
                        for star_tpl in combinations(( j for j in range(a)), i):
                            star_pos = make_star_pos(n_list,x,star_tpl) 
                            num_sum = 0
                            for star_num in '0123456789':
                                if star_pos[0] == 0 and star_num == '0':
                                    continue
                                made_num = make_num(n_list,star_pos,star_num)
                                if made_num in prime:
                                    num_sum += 1
                            if num_sum == number:
                                return n


print(main(8))
```
各桁数の素数のリストを作り、それを下から調べて行った。
15.353 seconds

1桁目は□にならない
ということに注意するともうちょっと速くなるはずなのですが書いているときは気づきませんでした。

ちなみに□の位置を先に決めて残りの数字埋めるアルゴリズムも考えたけど条件に合う数字が出た瞬間に最小性が確定しないのでやめた。
What is object in object-oriented programming

*A memorandum for myself. Focused on understanding at the cost of accuracy.*


# An object is
**a package of data and programs to process the data.**

In object-oriented programming (OOP), almost everything is an object. A user interacts with each object to proceed the program.
An important thing is that data and methods to deal with those data are combined in one object. So the user can complete the process related to the data within the object.
You can also make multiple objects interact each other.
![Picture1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345318/45f8ad55-47c5-5ee1-09fd-cbe2ce1aaead.png)


# For example
Here is a glass of water. The water in the glass is the data. With a glass, you can turn the glass to pour, you can shake the glass, you can swirl the glass or turn over it etc. You can use these methods to manipulate the water.
If you have other objects, you can use those method with water to make some effects on other objects. 
![Picture1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345318/b87bc918-9eca-9767-97bf-6d9f8c1d4a78.png)

For example, if there's another empty glass, you can do
`method: pour`
`data: water`
on the empty glass.
Then, the empty glass will be filled with water. This will be the output of your program.

# Reference
https://www.youtube.com/watch?v=OEfSFrk_KEI
http://www.differencebetween.net/technology/difference-between-oop-and-pop/
現在ログインしているユーザーid情報をDBに保存する実装について

#1．テーブルにカラムを追加する
ツイートにユーザーの情報を追加する場合、テーブルに新しくuser_idというカラムを作成し、そこにツイートを投稿したユーザーのidを入れる。
ターミナル上で以下のコマンドを実行する。

```
$ rails g migration AddUserIdToTweets user_id:integer
```

このコマンドにより、マイグレーションファイルにuser_idがinteger型(整数型)のカラムで設計される。

次に、設計したマイグレーションファイルを以下のコマンドで実行する。

```
$ rake db:migrate
```

#2．ツイート保存時にユーザー情報を追加する処理を記述する

ツイート保存時であるから、コントローラのcreateアクションに以下のようなコードを記述する。


```ruby

class TweetsController < ApplicationController

    def index
      @tweets = Tweet.all
    end

    def create
      Tweet.create(name: tweet_params[:name], text: tweet_params[:text], user_id: current_user.id)
    end

    private
    def tweet_params
      params.permit(:name, :text)
    end
  end

```
createメソッドの引数()内に現在ログイン中のユーザーのidと名前とテキスト(ツイートの内容)を記述する。
また、現在ログイン中のユーザーのidの記述の際は、**current_user**を記述する。これは、現在ログイン中のユーザーのレコードをuserクラスのインスタンスとして取得することができるヘルパーメソッドである。例えば、usersテーブルでのidカラムの値が1のアカウントでログインしている場合、current_userはUser.find(1)と同じ意味を持つ。
また、このメソッドは、deviseでログイン機能を実装すると使用できる。


#3．ツイート保存時にユーザー情報も保存できたか確かめる

最後に、実際にツイートを投稿し、テーブルに保存されたレコードを確認し、user_idに現在ログイン中のユーザーのidが保存されていれば実装は完了する。

　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　以上
玉花火っぽいすくり

なつが近づいてきました
打ち上げ花火の玉花火っぽいスクリです
ただそれだけ

ではみなさんお楽しんでね！！

> タッチでオンオフ
 パブチャで /999 start で開始 /999 stop で停止でも おっけー
 

```
/*
    花火っぽいスクリ
                                        13 Jun . 2019    esforco
*/
float gap;
float time = 3;  // タイマーの時間
integer ch = 999;
integer listen_handle;
integer start_flag = FALSE;

ctrl(float gap)
{
    // 引数が0なら タイマーと パーティクルを停止
    llSetTimerEvent(gap);
    if (gap == 0)
    {
        llSetPrimitiveParams([ PRIM_GLOW, ALL_SIDES, 0 ]);
        llParticleSystem([]);
    
        llOwnerSay("■ stop firework");    
        return;
    }
    
    llOwnerSay("▶ start firework");
}

perticle()
{
    vector color;  // 色用にベクトル型変数を定義
    color.x = llFrand(1);  // ０〜１までの乱数を
    color.y = llFrand(1);  // 変数のR、G、Bに
    color.z = llFrand(1);  // 入れる

    llParticleSystem([
        PSYS_PART_FLAGS,
        PSYS_PART_INTERP_SCALE_MASK| PSYS_PART_INTERP_COLOR_MASK |
        PSYS_PART_EMISSIVE_MASK,
        PSYS_PART_MAX_AGE, 2,
        PSYS_SRC_PATTERN,
        PSYS_SRC_PATTERN_EXPLODE,
        PSYS_SRC_BURST_RATE, time,
        PSYS_SRC_BURST_PART_COUNT, 300,
        PSYS_PART_START_SCALE, <0.1,0.1,0>,
        PSYS_PART_END_SCALE, <0.1,0.1,0>,
        PSYS_PART_START_COLOR, color,
        PSYS_PART_END_COLOR, <1,0.5,0>,
        PSYS_PART_START_ALPHA, 1.0,
        PSYS_PART_END_ALPHA, 1.0,
        PSYS_PART_START_GLOW, 0,
        PSYS_PART_END_GLOW, 1
    ]);
}

do_firework()
{
    // １つめのわっか
    perticle();
    llSetPrimitiveParams([ PRIM_GLOW, ALL_SIDES, 0.2 ]);        
    llSleep(0.1);
    llParticleSystem([]);
    llSleep(0.2);
    // ２つ目のわっか
    perticle();
    
    llSleep(0.5);
    llSetPrimitiveParams([ PRIM_GLOW, ALL_SIDES, 0 ]);
    llParticleSystem([]);
}

default
{
    state_entry()
    {
        llParticleSystem([]);
        // 透明にします
        llSetAlpha(0, ALL_SIDES);
        listen_handle = llListen(ch, "", NULL_KEY, "");
    }

    touch_start(integer n)
    {
        if(start_flag == FALSE)
        {
            ctrl(time);
            do_firework();
            start_flag = TRUE;
        }
        else
        {
            ctrl(0);
            start_flag = FALSE;
        }
    }

    listen( integer channel, string name, key id, string message )
    {
        if(message == "start" && start_flag == FALSE)
        {
            ctrl(time);
            do_firework();
        }
        else if(message == "stop")
        {
            ctrl(0);
        }
    }

    timer()
    {
        do_firework();
    }
}
```

![Snapshot_010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275884/eea041ac-63e3-ab48-dea7-bd56bc82d77c.png)
PowerShellでファイル作成監視ワンライナー

何度も使うと意外と覚えられます

## 監視登録

```powershell
$ Register-ObjectEvent -InputObject (New-Object System.IO.FileSystemWatcher("$HOME/Desktop")) -SourceIdentifier "test" -EventName Created {(New-Object -ComObject wscript.shell).popup("ファイル:" + $EventArgs.FullPath.toString() + "が配置されました。")}
```

デスクトップに新しいファイルが配置、作成されるとダイアログが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266455/1ca29714-dc9d-a1be-9a1b-14922161c7ef.png)

## 監視解除

```powershell
$ Unregister-Event -SourceIdentifier "test"
```
postgresql+slick+evolutionsでscala+playのデータベース周りの環境を構築する

## 概要
scalaのweb frameworkのデファクトとなっているplayでデータベース環境を構築する。
使用するのはpostgresqlでORM(ホントはFRMと言うらしい)はscalaを作っているlightbend作のslickを使う。
また、データベース運用で必須のマイグレーションツールはevolutionsを使用する。

## この記事で書くこと
1. playプロジェクトの作成方法
1. slickは環境構築まで
2. evolutionsの環境構築とマイグレーションの運用方法

## この記事で書かないこと
1. slickのモデル運用方法
2. evolutionsのマイグレーションファイルの詳しい書き方

## 環境
- Scala2.12.8
- Play 2.7.2

## 前提
1. Sbtのインストール
2. Scalaのインストール
3. postgresqlのインストール

## 1.playプロジェクトの作成
好きなディレクトリに移動した後、以下のコマンドを打つ。

```shell:shell
sbt new playframework/play-scala-seed.g8
```

すると、

```shell:shell
name [play-scala-seed]: 
```

と出るので好きなアプリ名を入力してエンター。
作成されたアプリ名のディレクトリに移動し、playを起動。

```shell:shell
sbt run
```

http://localhost:9000/ にアクセスし、以下の画面が出れば成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/7fbd0eb1-3856-bf81-5a5f-9a2e9a840781.png)


## 2.postgresqlでdbを作成する
ターミナルで以下のコマンドを打つ。

```shell:shell
create test-db;
```

その後、以下の用になれば成功。

```shell:shell
~ ❯❯❯ psql -d test-db
psql (11.3)
Type "help" for help.

test-db=#
```

## 3.slickの導入
プロジェクト直下の`build.sbt`を編集する。
以下を追記。

```sbt:build.sbt
...

libraryDependencies += "com.typesafe.play" %% "play-slick" % "3.0.1"
```

また、`conf/application.conf`も編集。
urlの設定で、portをpostgresのportにすることが必要。
以下のコードではデフォルトの`5432`を使用している。
また、urlの最後は作成したdb名にすることに注意。
`slick.dbs.A.~`で設定を書いた場合、`A`がslickの中でのdb名になる。


```conf:application.conf
...

slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/test-db"
slick.dbs.default.profile="slick.jdbc.PostgresProfile$"
slick.dbs.default.db.properties.driver = "org.postgresql.Driver"
```

ここまでした後に、`sbt run`でplayを再起動し、先ほどの画面が出れば成功。


## 4.evolutionsでのマイグレーション
`build.sbt`を編集。
公式ではjdbcも依存に加えているが、入れるとエラーが出て、入れなくても動くので削除。

```sbt:build.sbt
...

libraryDependencies ++= Seq(evolutions)
libraryDependencies += "org.postgresql" % "postgresql" % "42.1.4"
libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "3.0.1"
```

次に`conf/evolutions/default`ディレクトリを作成し、配下ににマイグレーションファイルを配置していく。
試しに、以下のファイルを`1.sql`という名前で作成する。

```sql:1.sql
-- Users schema

-- !Ups

CREATE TABLE User (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    email varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    fullname varchar(255) NOT NULL,
    isAdmin boolean NOT NULL,
    PRIMARY KEY (id)
);

-- !Downs

DROP TABLE User;
```

作成した後、playを起動すると以下のような画面が出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/309e8741-0db9-eb6d-5a64-d6c6cc1450b8.png)

`Apply this script now!`ボタンを押すと、マイグレーションファイルがdbに適用され、元のページに戻る。

その後、`2.sql`という名前で以下のファイルを`conf/evolutions/default`以下に作成する。

```sql:2.sql
-- Add Post

-- !Ups
CREATE TABLE Post (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    title varchar(255) NOT NULL,
    content text NOT NULL,
    postedAt date NOT NULL,
    author_id bigint(20) NOT NULL,
    FOREIGN KEY (author_id) REFERENCES User(id),
    PRIMARY KEY (id)
);

-- !Downs
DROP TABLE Post;
```

すると、先ほどのスキーマ適用画面が出るので同様に適用。

## まとめ
意外とこの構成でまとめられている記事はなかったので、何かの助けになれば幸いである。
逆にこれ以外のベスト・プラクティスがあればぜひコメントをお願いします。
AppleDeveloperProgramのメンバーシップ履歴の確認 ＆ 領収証 (請求書) の発行方法 2019

# 概要
- AppleDeveloperProgramのメンバーシップの履歴画面が存在する
- メールを紛失しても注文番号は分かる
- 紙の請求書の郵送は廃止された
- 請求書ではなく領収証になります
- 住所は記載なし
- 確認日：2019-06

# 対象
- AppleDeveloperProgramのメンバーシップの注文履歴を見たい

- 請求書を発行したい
 - 特に更新時のメールを紛失してWから始まる請求番号が分からない場合
 - メンバーシップ更新時に発行していない場合




# メンバーシップの注文履歴への導線

## Appleトップ
apple.comに行き、最下部までスクロールします。
![apple-top-order-status.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/d067989f-3882-eebc-4bb8-146a3cab30db.png)
`Order Status`をクリック
これは気付かなかった・・・

## Find your order画面
![find-order.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/2af2e7f0-efc3-852e-ae37-a9ee098c9dae.png)
- 左側：サインイン後注文一覧を表示可能
- 右側：注文番号から検索


注文番号から検索する場合もサインインが必要なので、一覧も見れるし左側がオススメです。

## 注文一覧画面
![order-history-list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/1a3f8574-4464-08ef-7856-a507c327bf28.png)
左から新着順に注文が表示されています。この画面はわかりにくい！

## 注文詳細画面
![order-history-detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/8cdc2456-6083-8f29-fa31-edce67ff0ec9.png)
詳細が見れます。
ここで注文番号が分かるので、領収証を発行するときの助けになります。

# 領収証の発行

Apple Store領収証発行依頼フォーム
https://www.apple.com/jp/feedback/aos/receipt_request.html

注文番号を入力すると、PDFの添付ファイルがメールで届きます。

- 紙の領収証を発行して欲しい
 - 2018年辺りからできなくなりました。
 - 電話で問い合わせたところメールのみだそうです。

- 請求先住所を記載して欲しい
 - 請求書に住所は記載してくれないようです。経理にそう伝えましょう。

# おわり
- 結構仕様が変化するので2020年にまた更新したいと思います💪
ボタン連打の防止について( _.throttle )

## こんな時、ないですか？
  * ボタン実行から、処理が完了するまで2度押しを防ぎたい。
  * ダブルクリックや複数回のクリックで余計な処理を走らせたくない。

こういったボタン連打・２度押しには、色々な対策が施されていますが、実際テストではちょこちょこと想定外の動作が見つかっているのが現状かと思います。

## 皆さんは、ボタン連打の防止にどんなコード使っていますか？？
  * 今回 lodash に使えそうな機能を見つけたので、皆さんのご意見を伺えればと思い投稿します！
  * 皆さんも、もし有効なボタン連打防止策ありましたら教えてください :bow_tone1:  

## ボタン連打を防止できる便利な関数
  * [lodash.js](https://lodash.com/docs/4.17.11) (Undesrscore.js)
    * lodashはユーティリティ関数を集めたライブラリです。
    * あんまり詳しくですが、軽量で便利な関数が揃っているとのこと。
  * ボタン連打防止に使用した関数は、このlodashの中のthrottle関数を使用しました。  

```
 _.throttle(func, [wait=0], [options])
```

  * throttle関数を用いることで、実行されてから `wait[ms]`立つまで次の処理を待機させることができます。 
  * しかし、オプションを指定しない状態では`待機`してしまいます。
  * つまり、wait[ms]時間経過後にするするーっと次の処理が走り出します。。
  * そこで、1ボタンを確実に1度しか動作をさせたくないという場合には、trailing(後続処理)のオプションを明示的に定義する必要があります。

```
 _.throttle(func, [wait=0], {trailing: false})
```
  * これで、wait時間待機中に実行された後続処理が破棄されます。

## 実際のボタンクリックの対策例
```javascript
$('#id').on('click', _.throttle( function () {
    // １度のみ実行させたい処理
    hogehoge();
}, 1000, {trailing: false});
```

> コメントやここ違います等ありましたらお気軽にコメントお願いします。 :bow:
VRでサブカメラを実装する（備忘）

#はじめに

VR体験者の目線の映像ではなく、体験者を俯瞰した映像（所謂サブカメラ）を作るときの手順を備忘として書きます。
HTC VIVEを使用しています。

画像右上がサブカメラ。
![subcamera_001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/d0d7166a-c956-d86a-43e2-395dec681e13.jpeg)


#サブカメラを用意する
ヒエラルキーで右クリック > Camera を選択します。
インスペクターから、以下を設定します。
Viewport Rect ： X 0.6   Y 0.6   W 0.4   H 0.4
Depth ： 1
Target Eye ： None （Main Display）

![subcamera_002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/0b3a3911-ba49-e963-7021-4f934abbfec2.jpeg)


Viewport Rect は、カメラの表示位置（X, Y）と表示サイズ（W, H）を設定します。

Depth は深度という意味らしく、初期値が 0 です。
ここでの深度とは、「値が大きいほど手前に描画する」 「値が小さいほど奥に描画する」 ということを意味します。
~~メインカメラのDepthも初期値0のため、~~
Unityで新規プロジェクトを作成したときにヒエラルキーに配置されている Main Camera の Depth 値は -1 なので、サブカメラの Depth 値は 0 で良い気がしますが、Unityエディタ実行時サブカメラが表示されませんでした。しかし、Depth 値を 1 に設定することでサブカメラを描画できたので、今回は設定値 1 としています。

Target Eye の初期値はSteam VR pluginをインポートしている場合 Both ですが、サブカメラの内容は今回、HMD両眼のディスプレイに表示させる必要がないため、None （Main Display）を設定します。

#実行結果
メインカメラ（HMD）を動かしても、サブカメラは固定されたまま表示されています。
また、メインカメラ（HMD）にはサブカメラの内容は表示されていません。
![20190612_subcamera.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/cffca384-93d4-f256-23ce-7c2a24d691be.gif)
Nuxt.jsで外部JSを読み込みたい場合の対応メモ

## 概要
Nuxt.jsを触っていて、ふと外部のJSファイルを読み込むときどうすればいいんだろうと思って調べてみたのでメモとして残しておきます。

## 公式ドキュメントに記載の対応方法
[外部リソースを使うには？](https://ja.nuxtjs.org/faq/)に記載がある通り、アプリケーション全体で読み込む設定（グローバルな設定）とページ単位で読み込む設定（ローカルな設定）が可能です。

## 動的に読むスクリプトを変えたい場合の対応方法
あまりないケースかと思いますが、[vue.js – VueJSコンポーネントに外部のJSスクリプトを追加する方法](https://codeday.me/jp/qa/20190301/341325.html)の通りcreatedやmounted時にJSを読み込ませることもできます。私は[Yahoo! JavaScriptマップAPI](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/js/)を使う際にAPIキーをフロント側に書くの嫌だなと思って、この方法でJSを読み込んでみました。以下がサンプルコードです。

### Yahoo! JavaScriptマップAPIのJS読み込みサンプル

```SamleComponemt.vue
<template>
  <div id="yahoo_map" style="width:400px; height:300px"></div>
</template>
<script>
export default {
  async mounted() {
    let mapScript = document.createElement('script');
    // サーバサイド側で読み込み用のJSを取得してここで設定
    let src  = await this.$axios.$get("http://127.0.0.1:8000/api/map");
    mapScript.appendChild(document.createTextNode(src));
    document.head.appendChild(mapScript);
    let ymap = new Y.Map("yahoo_map");
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);
  }
}
</script>
```
ruby-引数

## 引数とは

引数とは、<u>メソッドに与える追加情報</u>のようなものと考えてください。

メソッドを呼び出すときに一緒に引数を渡すことで、「メソッドに変数の値を渡す」ことができます。

例えば、「"変数名(fruit)"を細かく砕く」という文字列を出力するmixerというメソッドを定義したとします。（ここではfruit = "リンゴ"とします）

これを引数を使わずに出力すると

```example.rb
def mixer
  fruit = "リンゴ"
  puts "#{fruit}を細かく砕く"
end

puts mixer
```

と書き

```ターミナル
リンゴを細かく砕く
```

と出力されます。

メソッド内では、メソッド内で定義した変数しか使えないため、「梨を細かく砕く」という文字列を書くメソッドに変更したい場合には

```example.rb
def mixer
  fruit = "梨"			#ここを変更する必要がある
  puts "#{fruit}を細かく砕く"
end

puts mixer
```

このようにメソッド内の変数を書き直す必要があります。

これだと、

```ターミナル
リンゴを細かく砕く

梨を細かく砕く
```

という2つ文字列を出力したい場合には、新たにメソッドを追加するかメソッドを2つ文字列を出力するように定義し直す必要がありコードが見づらくなったり、メソッドの役割が変わってしまいます。



そこで、<u>引数が登場</u>するわけです。



冒頭でも言いましたが、引数とはメソッドに与える追加情報のようなものです。

上記のように「リンゴ」「梨」をそれぞれ細かく砕く文字列を出力したい場合には

```example.rb
def mixer(fruit)				#仮引数
  puts "#{fruit}を細かく砕く"       #変数
end

puts mixer("リンゴ")				#本引数
puts mixer("梨") 			     #本引数
```

と書くことで

```ターミナル
リンゴを細かく砕く

梨を細かく砕く
```

のように出力することができます。

これならメソッドの役割は「"変数名(fruit)"を細かく砕く」という文字列を出力するまま変わっておらず、異なる引数を持つ puts mixer を追加するだけで良いのでコードもスッキリしています。



#### ｜本引数と仮引数｜

引数を使ったコードを見るとわかるかと思いますが、引数は「メソッドを呼び出す部分」と「メソッドを定義している部分」両方に書く必要があります。

このとき、メソッドを呼び出す際に書く引数を本引数と呼びメソッドの呼び出し時は、以下のように書きます。

```本引数
メソッド名（本引数）
```

上のコードで言うところの

```本引数
puts mixer("リンゴ")						#本引数
puts mixer("梨")						 #本引数
```

この部分ですね！



一方で、メソッドを定義している部分に書く引数のことを仮引数と言います。

メソッドを定義している部分には、以下のように仮引数を書きます。メソッドの処理の中では、引数として渡されたものを仮引数としてつけた名前で扱います。

```仮引数
def メソッド名(仮引数)
   実行する処理
end
```

上のコードで言うところの

```仮引数
def mixer(fruit)					#仮引数
	puts "#{fruit}を細かく砕く"		  #変数
end
```

この部分ですね！



## まとめ

- メソッドを呼び出すときに一緒に引数を渡すことで、「メソッドに変数の値を渡す」ことができる。
- 引数は「メソッドを呼び出す部分」と「メソッドを定義している部分」両方に書く
- 「メソッドを呼び出す部分」に書く引数と「メソッドを定義している部分」に書く引数の名前は、一致している必要はない
Laravelのdd()

# はじめに
自分の今までの``dd()``の使い方と最近知った使い方を紹介します。
[dd()の詳細](https://readouble.com/laravel/5.8/ja/helpers.html#method-dd)

##前提
- DBは``posts``
- Laravel + Vue.jsでの開発
- ``posts``を確認したい
- Google Chrome

# ブラウザで表示する

```PostController.php
// 一部抜粋
public function index()
{
    $posts = Post::all();
    dd($posts);

    return response()->json([
        'posts' => $posts
    ]);
}
```
``dd()``に``$posts``渡し、``index``を呼び出すURLを見ると

![posts_dd.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247466/c4a4f0a3-dc62-818d-594d-e86c07a8c99a.png)

のように見れます。▶をクリックするとより詳しく見れます。

# デベロッパーツールで確認
Laravel + Vue.jsでの開発でLaravelが頑なに500しか返してこず困っていた時、インターン先の社員の方に教えていただきました。(状況を忘れてしまったのでデベロッパーツールで確認する方法だけを紹介します。)

```PostController.php
// 一部抜粋
public function index()
{
    $posts = Post::all();
    dd($posts);

    return response()->json([
        'posts' => $posts
    ]);
}
```
これは同じです。
次にVue.jsのAPI呼び出しのURLに行きます。一応コードを。

```.js
// 一部抜粋
axios.get('/api/posts')
  .then(response => {
    this.posts = response.data.posts
    console.log(this.posts)
  })
  .catch(error => {
    console.log(error)
  })
```

F12を押しデベロッパーツールのConsoleタブをクリックしましょう。``dd()``を書いているのでもちろん``this.posts``は``undefined``です。↓
![console.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247466/c47f1d5a-5178-5bfb-94ae-538c42858f36.png)

目的は``dd()``で``$posts``を確認するでした。それでは赤で記されたNetworkタブをクリックしましょう。↓
![network.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247466/e7293531-6e59-33db-5fa5-85c47444a31f.png)

Webページでロードされるリソースに関するデータが見れます。さらにpostsをクリックしPreviewを確認すると、、、
![posts.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247466/679319d2-cdd3-d88f-9912-cb3c098c86d1.png)
Vue.js側からも``dd()``に渡した``$posts``が見れました。

# これからの意気込み
Laravel + Vue.jsでの開発は始めたばかりなのでいろいろなことを吸収し頑張っていきたい。

# 補足
``dump()``でも同じことができます。
[dump()の詳細](https://readouble.com/laravel/5.8/ja/helpers.html#method-dump)
また、今回は``GET``を確認しましたが、``POST``、``PUT``、``DLETE``などもデベロッパーツールで確認することができます。
MacOS システム拡張機能がブロックされました

# Googleドライブファイルストリームで「システム拡張機能がブロックされました」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197178/28b38295-5361-adfe-ab8b-a0871f11bdf1.png)
MacOS 10.14.5 でGoogleドライブファイルストリームがこんなメッセージを出して使えなくなったときの対処。
その後Vallumというファイアーウォールソフトもバージョンアップ実行後に同じメッセージを出した。
### 一般には...
メッセージにあるとおり、システム環境設定＞セキュリティとプライバシーを開いて「開発元Google.Incのシステム・ソフトウェアの読み込み」を許可するのだが、今回はそれが表示されていない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197178/0cc33fcc-159a-1536-642f-0c51841d1513.png)
# 解決方法： spctl kext-consent

``` 
spctl kext-consent add EQHXZ8M8AV 
```

1. Macを **リカバリーモード** で起動する（Command + R を押したまま起動）。
2. リカバリーモード起動したらメニューからターミナルを開く。
3. 上のコマンドを入力してEnter
4. Macを通常再起動する。

"EQHXZ8M8AV"という部分はGoogle.Incの開発者チームコード（Team Identifier）。
これはインストーラを起動して右上の鍵アイコンをクリックすると表示される。最初にこれメモってから上の手順やらないとね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197178/db6e2e1c-a52c-b233-5816-5b4696e1b6f0.png)
# 補足
今回やったこの方法は開発元Google.Incからのシステムソフトウェアを全面的に信頼するという設定。以下のコマンドで信頼済みの開発元を確認できる。信頼済みを取り消すにはspctl kext-consent remove <Team Identifier>。

```
$ spctl kext-consent list
Allowed Team Identifiers:
EQHXZ8M8AV
RNLG254GCK
```
CentOS 7 の Nginx に Let's Encrypt で SSL を自動設定する

Nginx をセットアップした CentOS 7 で [Let's Encrypt](https://letsencrypt.org/) の SSL を [Certbot](https://certbot.eff.org/lets-encrypt/centosrhel7-nginx) ACME クライアントで自動取得および自動設定する手順の解説。

## リポジトリの導入
```bash
yum epel-release
```
`certbot` パッケージは EPEL リポジトリで利用可能。

## Certbot と Nginx プラグインのインストール
```bash
yum certbot python2-certbot-nginx
```
2019年2月7日リリースの Certbot 0.31.0 がインストールされる。
`epel-testing` リポジトリを利用すると、2019年5月7日リリースの 0.34.2 がインストールされる。

## SSL 証明書の取得
```bash
certbot \
  --nginx \
  --agree-tos \
  --domain example.jp \
  --email 'admin@example.jp' \
  --no-eff-email
```
`certbot` コマンドのサブコマンドを省略するとデフォルトの `run` になる。
Nginx の設定ファイルまで自動設定する場合は `certonly` および `--standalone` や `--webroot` を指定しない。

`--nginx` オプションは Nginx プラグイン (`python2-certbot-nginx` パッケージ) がのインストールが必要。

`--agree-tos` オプションは ACME サーバーの [Subscriber Agreement](https://letsencrypt.org/repository/#let-s-encrypt-subscriber-agreement) への同意。

`--no-eff-email` オプションは [EFF](https://www.eff.org/) 等にメールアドレスを共有しない。共有する場合は代わりに `--eff-email` オプションを指定する。

## 自動更新の設定
```bash
systemctl start certbot-renew.timer
systemctl enable certbot-renew.timer
systemctl list-timers --all
```
Cron ではなく systemd の Timer を利用して自動更新を設定する。
プログラムど素人のprogate修行記録その1

別に情報処理系の仕事をしているわけじゃないけど、友人がそっちの道を進んでて楽しそうという理由でプログラムの勉強をしていこうと思った。
明日に控える腐れ上司とのクソ客先訪問イベントから逃げ出したい気持ちを込めて日記を書く。

自分は自作PCは好きだがプログラムについては素人もいいところだ。いきなり勉強がてらアプリ開発とかはじめたら30秒で飽きると思うので、今回はprogateを用いて勉強する。
PCでやろうと思ったが、5年目にして中古のマザボが急死したのでiPad mini4でやる。iOSアプリ版の方が寝ながらできていいよね。

男は黙ってHTMLかなと思ってやり始めていまここ↓
![14C1D4CC-B3C5-49E7-B8DA-BAFE9D2ECC79.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140173/ce67e1a7-7156-5f34-24b7-08872aedc11b.png)

HTMLとCSSでヘッダーとフッターが作れるようになった。
あと会社で、ブラウザでF12キー押して意味ありげにページのソース見ながら「へぇ……こんな風になってるのか……」みたいなことができるようになった。パソコンに関しては幼稚園児級の上司達になら本気で通用するだろう。


自分は飽き性だがこういった勉強には常に挑戦していかねばと強く思う。
年上の同僚にWordへの写真の挿入方法を聞かれるたびに、強く思う。貴様それ10回は教えてるぞ。
WooCommerce の注文請求者情報の関数【取得系】

#注文に紐づく請求者情報の取得
ここから記載する \$order は、[WooCommerce の注文関連の関数【取得系】](https://qiita.com/shoheitanaka/items/25a02fc8bf686a1ab33e)で取得したものとします。
バージョンは3.0.0以降の情報となります。【2019/06/12現在】

##請求者情報の取得

###請求者名

```php:functions.php
$billing_first_name = $order->get_billing_first_name();
```

###請求者姓

```php:functions.php
$billing_first_name = $order->get_billing_last_name();
```

###請求先会社名

```php:functions.php
$billing_first_name = $order->get_billing_company();
```

###請求先住所（国）

```php:functions.php
$billing_first_name = $order->get_billing_country();
```

###請求先住所（郵便番号）

```php:functions.php
$billing_first_name = $order->get_billing_postcode();
```

###請求先住所（都道府県/州）
こちらは、それぞれのコードになりますので、表示用にするには、ひと手間が掛かります。

```php:functions.php
$billing_first_name = $order->get_billing_state();
```

###請求先住所（市）

```php:functions.php
$billing_first_name = $order->get_billing_city();
```

###請求先住所（住所詳細１）

```php:functions.php
$billing_first_name = $order->get_billing_address_1();
```

###請求先住所（住所詳細２）

```php:functions.php
$billing_first_name = $order->get_billing_address_2();
```

###請求先住所（メールアドレス）

```php:functions.php
$billing_first_name = $order->get_billing_email();
```

###請求先住所（電話番号）

```php:functions.php
$billing_first_name = $order->get_billing_phone();
```

###請求先その他情報
$propを設定されているデフォルト以外の項目とした場合、これで取得できます。

```php:functions.php
$billing_first_name = $order->get_address_prop( $prop, 'billing');
```
既存のDockerコンテナのイメージを出力する方法

よく環境を破壊するのである程度うまく行っている時点でイメージを出力したいと思いました。

- 環境
  - Docker 20.10.5
  - Dockerホスト:Windows10 Pro バージョン1909
  - Dockerコンテナ:CentOS Linux release 7.9.2009 (Core)

```bash
# 1.`docker export`の使い方を確認する
$ docker export --help

Usage:  docker export [OPTIONS] CONTAINER

Export a container`s filesystem as a tar archive

Options:
  -o, --output string   Write to a file, instead of STDOUT

# 2.コンテナのIDを確認する
$ docker ps
CONTAINER ID        IMAGE       COMMAND             CREATED             STATUS              PORTS                  NAMES
{コンテナのID}        host-hoge   "/usr/sbin/init"    24 hours ago        Up 7 hours          0.0.0.0:80->8080/tcp   project1

# 3.イメージを出力する(ちょっと時間がかかるからじっくり待つ)
$ docker export -o /path/to/{イメージファイル名}.tar {コンテナのID}
```
GASを使ってGoogleカレンダーの内容をLINEに送る方法（10分前通知編）

#用途
Googleカレンダーの今日の予定を元に、ユーザへ10分前通知を送る。
（以前作ったQiitaの内容は「今日の予定は何があったかな？」レベルのリマインダーとしていた）

事前に必要なものは下記にて記載済みなので省略。
https://qiita.com/watarimaycry2/items/acf90142b32aa1fd8ba1

#コーディング
```remind.gs
var calenderSpreadSheet = SpreadsheetApp.openById("ここにスプレッドシートのIDを入れてね");
var calenderSheet = calenderSpreadSheet.getSheetByName("シート1");

//1日に1回、今日の予定を取得、スプレッドシートのセルへ登録
function dailyCalenderCheck(){
　var myCal = CalendarApp.getCalendarById("ここにGoogleカレンダーのIDを入れてね");
　var myEvents = myCal.getEventsForDay(new Date());

  //セルに追加する用。A列：時刻、B列：タイトルが入る
  var addCellList = [];

  for(var i = 0; i < myEvents.length; i++){
    var title = myEvents[i].getTitle();
    var startTime = Utilities.formatDate(myEvents[i].getStartTime(),'JST','HH:mm');
    if(startTime != "00:00"){
      //明示的に開始時刻が決められてるものだけ取ってくる
      addCellList.push([startTime, title]);
    }
  }

  //複数のカレンダーIDを使ってリマインダーを作ろうとすると時刻の順番が正しく並ばないので、ソートしてやるよ
　addCellList.sort(function(a, b){
    var aTime = a[0].split(":");
    var bTime = b[0].split(":");
    
    if(parseInt(aTime[0]) == parseInt(bTime[0])){
      //分を見てソート
      return parseInt(aTime[1]) - parseInt(bTime[1]);
    }else{
      //時を見てソート
      return parseInt(aTime[0]) - parseInt(bTime[0]);
    }
  });
  
  var addRange = calenderSheet.getRange("A1:B" + addCellList.length);
  addRange.setValues(addCellList);
}

//1分に1回実行
//「実行時の時刻の10分後（hh:mm）」とA1セルの値が同じであればメッセージをLINEに送る
function sendRemind(){
  var range = calenderSheet.getRange("A1:B1");
  var schedule = range.getValues();
  var time = schedule[0][0];
  var title = schedule[0][1];
  
  var tmpDate = new Date();
  tmpDate.setMinutes(tmpDate.getMinutes() + 10);
  var hour = tmpDate.getHours();
  if(hour < 10){
    hour = "0" + hour;
  }
  var minute = tmpDate.getMinutes();
  if(minute < 10){
    minute = "0" + minute;
  }
  
  var triggeredTime = hour + ":" + minute;
  if(time == "" || time != triggeredTime){
    return;
  }
  
  var sendText = "そろそろ予定が始まるよ\n" + time + "：" + title;
  sendLineMessage(sendText);

  //送信完了した予定のセルは消す（セルの一番上がなくなるので、「上方向に削除」を行う）
  range.deleteCells(SpreadsheetApp.Dimension.ROWS);
}

//LINEへメッセージを送信する
function sendLineMessage(sendText){
  var token = "ここにLINE notifyトークンを入れてね";
  var opt = {
    "method" : "POST",
    "payload" : "message=" + sendText,
    "headers" : { 
      "Authorization" : "Bearer " + token
    }
  };
  UrlFetchApp.fetch("https://notify-api.line.me/api/notify", opt);
}
```

#テスト結果
![qiita7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/39e902fb-f978-0a9e-eb65-24efe9cd8b7d.jpeg)

#備考
1日1回のカレンダーチェックの都合上、「0時0分～0時10分」の予定をリマインドすることはできないので注意。
予定に一定のパターンがあれば、「このタイプの予定は20分前に、他は10分前に」とかのアレンジはできると思う。

#終わりに
本当はTriggerBuilderというクラスを使って、1分ごとの処理を使わないようにしようと思ってた。しかし、トリガー実行時に、どのトリガーIDを使っているのかを取得できなかったので諦めた。
SSHのポートフォワーディングを使って非公開サーバーをブラウザで表示する

いまさらだけどsshのポートフォワーディングを知りました。
開発サーバーなどで80番ポート公開したくない場合に便利だなと思ったのでメモ書きだけど共有。

## リモートの80番ポートとhttp通信してページを表示する

### コマンド
```bash
ssh -N -L 8080:127.0.0.1:80 ユーザー@リモートサーバー
```

### 検証手順

リモートは、80番ポートでWebサーバーを起動しておく。
(今回はphpのbuilt-in web serverを利用)

```bash
$ php -v
PHP 7.2.19 (cli) (built: Jun 12 2019 13:51:06) ( NTS )
$ echo "<?php phpinfo();" > index.php
$ php -S 127.0.0.1:80
```

ローカルの`8080`とリモートの`127.0.0.1:80`を割り当てする。

```bash
$ ssh -N -L 8080:127.0.0.1:80 ユーザー@リモートサーバー
```

この状態でローカルのブラウザから`127.0.0.1:8080`にアクセスするとphpinfoが表示されます。

## リモートの9000番ポートと通信してxdebugを利用する

### コマンド

```
ssh -R 9000:localhost:9000 ユーザー@リモートサーバー
```

### 検証手順

PhpStormの公式ドキュメントにわかりやすく解説されています。
https://pleiades.io/help/phpstorm/remote-debugging-via-ssh-tunnel.html

以上
WooCommerce の注文関連の関数【取得系】 

#注文データ全体の取得
注文データ全体を取得する場合は、$post_idが分かっていれば、以下のコードで分かります。
Class WC_Orderから情報を取得することが出来ます。
バージョンは3.0.0以降の情報となります。【2019/06/12現在】

[wc_get_orderの説明原文](https://docs.woocommerce.com/wc-apidocs/function-wc_get_order.html)

```php:functions.php
$order = wc_get_order($post_id);
```

##表示用の注文IDの取得
上記の方法で取得した \$order から表示用の注文 ID を取得することが出来ます。注文IDは何もしなければ投稿 ID と同じなのですが、プラグインやカスタマイズで接頭辞などを付けることが出来ます。そういう処理をしていた場合は、このようにして取得できます。
何もしていなければ、基本的に \$post_id = \$order_id となります。

```php:functions.php
$order_id = $order->get_order_number();
```
##購入ユーザー ID 情報
購入ユーザーが登録ユーザーだった場合は以下の方法で顧客IDなどを取得します。
get_user_id() は get_customer_id()のエイリアスとなります。

```php:functions.php
$customer_id = $order->get_customer_id();
$user_id = $order->get_user_id();
```
##購入ユーザー情報
購入ユーザーが登録ユーザーだった場合、登録されているユーザー情報を Class WP_User で取得出来る情報となります。

```php:functions.php
$customer = $order->get_user();
```
その他の注文情報の取得方法を以下のページで説明します。

- [請求先情報](https://qiita.com/shoheitanaka/items/651a0669dc595506f702)
- 配送先情報（準備中）
- 決済情報（準備中）
- 配送情報（準備中）
- 商品情報（準備中）
- 払い戻し情報（準備中）
- その他情報（準備中）
【Android】定数の異なる複数のapkを一度にビルドする

# 環境
- Android Studio 3.4.1

# やりたいこと
- 本番サーバーと検証サーバー向けのapkを一度にビルドしたい
- 都度ソースコード（定数等）の変更はしたくない
- 検証サーバー向けの場合はapkのversionNameを変更して分かりやすくしたい

# やり方
## Gradle設定サンプル

`app/build.gradle`を修正します。

`buildTypes{}`の中に`release_stage{}`を追加します。（名称は任意）
サンプルでは基本的に既存の`release{}`のコピペですが、`buildConfigField`と`versionNameSuffix`を追加しています。

```gradle:app/build.gradle
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        buildConfigField "String", "PRODUCTION_MODE", "\"PRODUCTION\""
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        release_stage {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            buildConfigField "String", "PRODUCTION_MODE", "\"STAGE\""
            versionNameSuffix "_stage"
        }
    }
}
```

## `buildConfigField`とは

`buildConfigField`とは、BuildConfig.javaに定数を定義する設定であり、
書式は`buildConfigField "定数の型", "定数名", "値"`です。
デフォルト値（`release{}`で有効になる値）として`defaultConfig {}`にも`buildConfigField`を追加します。
今回のサンプルでは`BuildConfig.java`に以下の通り、定数`PRODUCTION_MODE`が追加されます。

```java:BuildConfig.java
public final class BuildConfig {

...省略

  // Fields from default config.
  public static final String PRODUCTION_MODE = "PRODUCTION";
```

今回のサンプルでの上記の定数`PRODUCTION_MODE`の値は、
`release{}`が反映されたapkでは`"PRODUCTION"`、
`release_stage{}`が反映されたapkでは`"STAGE"`になります。

今回はソースコード上で以下のように処理を分けました。

```java
void hoge() {
    switch (BuildConfig.PRODUCTION_MODE) {
        case "PRODUCTION"
            // 本番サーバー向けの処理
            break;
        case "STAGE"
            // 検証サーバー向けの処理
            break;
    }
}
```

## `versionNameSuffix`とは
`versionNameSuffix`とは、`versionName`の末尾に結合する文字列を定義する設定です。

今回のサンプルでの`versionName`は、
`release{}`が反映されたapkでは`"1.0"`、
`release_stage{}`が反映されたapkでは`"1.0_stage"`になります。

## apkビルド方法
`Build` ⇒ `Ganerate Signed Bundle / APK...`を選択
`APK`を選択して`Next`
![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402543/d9dc8d5e-e3b7-9f98-036f-dc1de623cc51.png)

Key storeを選択、passwordを入力し`Next`を選択。
![q2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402543/623827e6-5cab-8e0d-b366-7b0d04f16a66.png)

`Build Variants`で`release`と`release_stage`両方を選択し`Finish`を選択。
![q3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402543/a4bdce3b-cd1a-e1c8-21f3-009ad8a68ef2.png)

デフォルトでは`app`配下にディレクトリが作成され、環境ごとのapkが作成されています。
apkごとに前述の通り内部の定数やversionNameが変更されています。
![q4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402543/c69970ab-af6f-bb94-4cee-b56cf66c4e15.png)

# おわりに
今回は接続先サーバーを変更する用途でしたが、ほかにも応用はできそう。
もっと良い方法があればご教授いただけると幸いです。
Node.jsで明日を取得 (date-utils)


moment.jsではなくこちら([date-utils](https://jerrysievert.github.io/date-utils/))を使ってみたメモです。

ちなみに↓で後述する内容の通り、あまり見ない書き方で戸惑ったのでメモっておこうと思った感じです。

誤解の無いように最初に書いておくと普通はMoment.js使うのがいいと思います。(くどいけど最後にも書いた)

## 準備

```
$ npm i date-utlis
```

これでOK。ちなみに環境はNode.js v12.2.0です。

## Node.jsで明日

```app.js
'use strict';

require('date-utils');
let tomorrow = Date.tomorrow();
console.log(tomorrow);
```

このコードを見ると分かりますが、`require`するだけっていう使い方がNode.jsだとあんまり見ない気がしますね。
requireするともともとのDateオブジェクトが拡張される模様。

moment.jsで明日を取得だと、`moment.add('days',1)`こんな雰囲気なので、この書き方よりは`tomorrow()`は直感的に明日ってのが分かって分かりやすいですね。

## Node.jsで昨日

```app.js
'use strict';

require('date-utils');
let yesterday = Date.yesterday();
console.log(yesterday);
```

ちなみに昨日だとこんな感じ。これも直感的。

## 現在時刻

```app.js
'use strict';

require('date-utils');

let nowFormatted = new Date().toFormat("YYYY年MM月DD日 HH24時MI分SS秒");
console.log(nowFormatted);
```

## その他

こんな感じ感じの関数が使える模様です。

```
{
  today: [Function],
  UTCtoday: [Function],
  tomorrow: [Function],
  UTCtomorrow: [Function],
  yesterday: [Function],
  UTCyesterday: [Function],
  validateDay: [Function],
  validateYear: [Function],
  validateSecond: [Function],
  validateMonth: [Function],
  validateMinute: [Function],
  validateMillisecond: [Function],
  validateHour: [Function],
  compare: [Function],
  equals: [Function],
  equalsDay: [Function],
  getDayNumberFromName: [Function],
  getMonthNumberFromName: [Function],
  getMonthNameFromNumber: [Function],
  getMonthAbbrFromNumber: [Function],
  isLeapYear: [Function],
  getDaysInMonth: [Function]
}
```

## 所感

簡単な使い方ならこれで良さそう。でも計算とかしようとするとMoment.jsの方がよさげな印象ですね。

ちなみに、昔書いた記事（[Node.jsで現在時刻を取得](https://qiita.com/n0bisuke/items/dd28122d006c95c58f9c))を見つけたんですけど、こちらでもdate-utilsを使ってた模様。
moment.jsを知らなかったのかなんなのかは謎です。

全然関係ないけど、明日を取得するのにメソッド名が`tomorrow()`じゃなくて`getTomorrow()`とかにした方が明日を掴む的なノリでエモいのになぁと思ってしまった。

あまり見ない書き方になってるし既存のDateオブジェクトを拡張してる雰囲気が気持ち悪いみたいな声もありそう。

`tomorrow()`や`yesterday()`は分かりやすいけど`nextweek()`とかは無さそうだったので、明日か昨日だけを取りたいときとかしか使い勝手はよく無いかもしれない。

## 結論(?)

**特にこだわりなければ[Moment.js](https://momentjs.com/)使った方がいいと思います。**

あと最近は[dayjs](https://github.com/iamkun/dayjs)の方がmoment.jsより軽くていいよって話題もありましたね。
alexaハッカソン参加日記

先日、alexaスキルアワードのハッカソンに行ってきました。中の人や参加者の方々から学んだこと・思ったことをまとめます。

# 準備編

- [Visual Studio Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare)が便利（そう）
  - ぼっちでのコーディングだったので出番はありませんでしたが、複数人で手元のPCでコードシェアしながら開発できる。
- TypeScript
  - 補完できるのがやっぱり強い。`create-react-app`のような、alexa版の雛形プロジェクト作成ツールが欲しい。（ `ask new --template`あるから、最新のask-sdkなどをちゃんと追従するテンプレート作ればいけそうな気も。）
- Serverless Framework
  - 凝ったスキル作るを場合はDBや複数環境欲しくなると思うので、slsデプロイが良さそう。IAMの設定も手動でぽちぽちしなくて済む。（別途IAMの払い出しは必要）

準備に時間取られるのは勿体無いので、「宇宙の豆知識」がそれぞれで動く環境をサクッと作れたら準備編はよさそう。
というわけで、次回やるときは、VS + TypeScript + Serverless Framework + モデルやスロットはdeveloper console がいいかなーという感じ。


# alexa関連編
- S3とDynamoDBのPersistenceAdapterを同時に使うのはできない
  - 2種類のデータを保存したい要件が発生し（しかも主キーはそれぞれで異なる）、サクッと作りたいので手抜きできないかなと思って聞いてみたけどだめそうでした。結局、aws-sdkを使って自前でDynamoDBとの繋いで対応。
- alexa発でユーザーにお知らせする方法は４つある（話はできない）
  - [プロアクティブイベント](https://developer.amazon.com/ja/docs/smapi/schemas-for-proactive-events.html)
  - リマインダーAPI
  - 定型アクション（時間指定で任意の会話）
  - スマートホーム

定型アクションとスマートホームは裏技的な立ち位置。プロアクティブイベントも定義済みのイベントに限るし、リマインダーもalexaからの一方通行なので、キャッチボールできるかつalexa発で話をできる方法があると嬉しいよね :eyes: 

- SSMLでゆっくりやさしく話しかける
  - `<prosody>`のrateやpitchだけでなく、単語の間に`<break time="0.1s"/>`などを挟むことでより自然な会話になる。

- 言葉を考える
 - より自然な会話にするために、フィラー（えーっと、あのーなど）や相槌を設計する
 - ユーザーが答えやすいように正しく誘導する

- デバッグ
  - [音声入力の履歴](https://alexa.amazon.co.jp/spa/index.html#settings/dialogs)をブラウザ上で確認できる。リアルタイムで反映されるのですごく便利。
 
  - うまく発話が認識されない場合は、developer consoleの「テスト」 で、開発中と非公開をON/OFFしたり、実機の場合は手でalexaを持って話しかけると認識されるケースがある。（床に音が反射して、誤動作する？根拠はあまりない、体験談。）

 - SSMLのテストはdeveloper consoleの「テスト」の「音声と語調」が便利。声のトーンや効果音は割と軽視されがちですが、ちょっと装飾するだけでも雰囲気が変わるので積極的に使うのがよし。


# アイディア編
- 声や画面を超えた体験を提供するスキルが目立っていた
  - 全身を使ったゲーム（WiiFitみたいな）や[ボードゲーム](https://a093.jp/hackathon2019-01/)などをサポートするスキル
  - 結婚したり、童話を聞かせて続話は配送するスキル
  - HW組み合わせたスキル
- マルチデバイス連携に期待
  - alexa複数台を連携させて動作させるスキル
  - ゲーム（しりとりなど）で対戦できたらおもしろそう
  - マッチング（ペアリング）はアカウントリンクなどの外部で連携が現実的っぽい


# その他
- ハッカソンへの参加目的を整理しておくと良い
  - 技術を磨きたいのか、プロダクトを作りたいのか、ファシリテーションしたいのかなど
  - 目的に沿ったチーム・アイディアを選択することでより楽しめる
- 困ったらすぐにexpertの方々に質問できる＆フィードバックもらえる
  - こういうスキル作りたいんですけど、いいやり方ないですかねーという漠然としたもの
  - SSMLを使ってより自然な会話にする方法ないですか
  - handlerの設計ってこういう感じでどうでしょう


# 総括
- 技術的にも発想的にも、モチベーション的にもすごく上がったり、何より楽しかったので、今後も頑張っていきます。運営の方々、参加者の皆さん、本当にありがとうございました。
[Java & SpringBoot]  環境構築 for Mac

# 概要
MacOS Mojave でIntelliJを使って開発した際に、cloneしてきたプロジェクトが動かなかったので、それを動かした際のメモ書き。汎用性はありません。

# Procedure
- Javaのダウングレード
- IntelliJの設定

## Java8 Install
自分の環境の確認

```　bash
$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
```
という感じで、1.8.0_XXX　になっていればたぶんOK.

異なる場合は、次を実行。

``` bash
$ brew tap AdoptOpenJDK/openjdk
$ brew cask install adoptopenjdk8
```
`/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/` にDLされるはず。
`/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/` に java が置かれる。

次にversionを確認。

``` bash
$ /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
```
となればOK.
面倒だがこの`/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home` を直接指定して呼ぶ形で環境構築を行う。
（最初にIntelliJに設定しちゃえばそれ以降触ることはないので、その後は気にしなくて良いはず。）

# IntelliJ で設定
上のメニューバーの　[Run] -> [Edit Configuration] をクリック
<img width="1440" alt="Screen Shot 2019-06-12 at 23.41.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214093/15bdc8f0-96b9-0f0f-707e-8134b1ad520c.png">

JREを設定する。右側の[...]をクリック
<img width="1183" alt="Screen Shot 2019-06-12 at 23.36.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214093/0e698b09-b0c4-4b82-f872-ecb43e1039ae.png">

`/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/` を選んで[Open]をクリック。
（[Command + Shift + G] を押下すると、下の画像のようになってパス打つと出てくるよ。）
<img width="1183" alt="Screen Shot 2019-06-12 at 23.39.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214093/a2dbf561-4043-b11f-b7cc-3313b3beb0f2.png">

最後に `/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home` がちゃんと指定できていることを確認したら、[Apply]して[OK]!!
<img width="1183" alt="Screen Shot 2019-06-12 at 23.39.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214093/2e3daf7a-83e9-5f6a-769f-4acd30d34c22.png">


# MySQL
mysqlのバージョン確認（インストールされているか確認）

``` bash
$ mysql -V
```
MySQLはbrewでインストールできる最新版のVer 8.0.16 for osx10.14 でも使えたので気にしなくて大丈夫そう。

インストールされていなかったらinstall作業を行う

``` bash
$ brew install mysql
```

server start

``` bash
$ mysql.server start
```
Success!! すればok. 

# 終わり
以上で、実行可能になっているはず！なっているといいなあ。
numpyでの円周率の計算（モンテカルロ法）

備忘録として簡単に書くことにする。

## モンテカルロ法を用いた円周率の導出

```py
import numpy as np


# 基準とする数(大きくするほど正確な円周率が求まる)
base_number = 100000
# 0〜1の一様乱数を２つ用意する
random.seed(0)
sample_x = np.random.uniform(0.0, 1.0, base_number)
random.seed(1)
sample_y = np.random.uniform(0.0, 1.0, base_number)

# 座標の原点からの距離の二乗の関数
def sample_function(x, y):
    return(x**2 + y**2)

# 半径1の円の中にいくつ点が存在しているか
count = 0
for x, y in zip(sample_x, sample_y):
    if sample_function(x, y) <= 1:
        count += 1
# 確認
print("count=", count)

# 以下のように考えられる
# (半径1の円を囲む一辺2の正方形の面積):(半径1の円の面積) = 4:π
# (半径1の円を囲む一辺2の正方形の面積):(半径1の円の面積) = (base_number):(count)
# つまり、xとyは一様乱数なので、全体の点の個数と円の内部に含まれる点の個数との比がおよそ4:πになるはず、ということ
# 以上より、
print("π=",  4*count/base_number)
```

## 出力結果

```
count= 78654
π= 3.14616
```
ある程度正確な値を得ることができた。なお、今回は円の内部に存在するかどうかを原点からの距離の二乗の値が１より小さいかどうかで判断した。もちろん、ルートで実際の距離にして判断しても良いがこのままで何も問題がないのでこのままにした。もしも実際の距離を出したいのであれば、

```py
import math

math.hypot(x, y)
```
でxとyのそれぞれの二乗の和の正の平方根、つまり原点からの距離を計算できる。
Rubyで2つの変数を入れ替える

## 一時変数を使った（よくある方法）

一時変数（ここでは `tmp` ）を用いて、値を入れ替える方法。

```.ruby
foo = 'foo'
bar = 'bar'

# 入れ替え作業
tmp = foo
foo = bar
bar = tmp
```

## 多重代入を使ったやり方

[多重代入](https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html#multiassign)を使うと１行で複数の代入を行うことができます。
メリットとしては、一時変数が不要、３行→１行になるばかりでなく、入れ替える意図が明確になります。

```.ruby
foo = 'foo'
bar = 'bar'

# 入れ替え作業
foo, bar = bar, foo

# => [
#      [0] "bar",
#      [1] "foo"
#    ]

foo # => "bar"
bar # => "foo"
```
【Typora】ズームイン/ズームアウトのショートカットを変更する&Ctrl+マウスホイールを有効にする

#TL;DR
##ズームイン/アウトのショートカットを変更する

```json:conf.user.json
  // Custom key binding, which will override the default ones.
  "keyBinding": {
    "Zoom In": "Ctrl+-"
    "Zoom Out": "Ctrl+Shift+-"
  },
```
記載後に`Typora`の再起動が必要。

##Ctrl+マウスホイールで拡大縮小する

```ahk:typora_zoom.ahk	
; Ctrl+MouseWheel zooming in Typora.
; Please set "keyBinding" before use this script
#IfWinActive ahk_exe Typora.exe
    ^WheelUp:: Send ^-
    ^WheelDown:: Send ^+-
#IfWinActive
```
ちなみに`DELL`のノートPCの場合、タッチパッドの2本指ズームは`Ctrl + ホイール`として解釈されるらしく、これで効くようになる。

#環境
```
0.1. Typora for Windows/Linux
version 0.9.70(beta)

Windows 10 64bit
```


# 動機
つよつよMarkdownエディタとして流行りの[Typora](https://typora.io/)を導入してみた。流行るだけあって非常に完成度が高く、楽しく遊んでいたが、ふと「ズームイン」のショートカットキーが効かないことに気づいた。
というのも、初期設定の「ズームイン」は`Ctrl + Shift + =`に、「ズームアウト」が`Ctrl + Shift + -`に割り当てられていた。そして日本語キーボード(109キーボード)は`Shift + -`が`=`なので、どうやってもズームインできない状況に陥ってしまっていた。
どちらにしろ個人的に`Ctrl+マウスホイール`が基本的人権だと信じていることもあり、キーコンフィグとAutoHotkeyを組み合わせて拡大縮小を可能なようにした。

#詳細
##Typoraのキーコンフィグ
`conf.user.json`ファイルに追記すれば良いようだ。`"keyBinding"`項に例が載っているので分かりやすい。
割当先の名称は[Typora公式のショートカットキーページ](https://support.typora.io/Shortcut-Keys/)から検索できる。設定可能な数も大して多くないので悩むこともないだろう。今回は`ZoomIn`、`ZoomOut`に109キーボードで入力可能な`Ctrl + -`、`Ctrl + Shift + -`を割り当ててた。`-`で拡大は直観的でないので良くなさそうだが、`+`の入力が(とりあえず試した限りだと)上手く行かなかったので諦めた。後日しれっと更新するかもしれない。
記載後は保存して`Typora`を再起動すると有効になる。

##AutoHotkey
基本的には[以前書いたEclipse用の記事](https://qiita.com/YamEiR/items/b11fb072123390776679)を参照して欲しい。
やっていることは全く同じである。`^`が`Ctrl`を、`+`が`Shift`を表すことさえ判れば後は特に悩むところはないだろう。
`.ahk`ファイルのショートカットを`Windows`のスタートアップに置いておくと起動を意識しなくて良いので便利。
IntelliJで.eslintrc.jsをもとにコードフォーマットする方法

## IntelliJで.eslintrc.jsをもとにコードフォーマットする方法
ショートカットキー shift + option + command + P (Mac) を使いましょう。
通常のコードフォーマットのショートカットキーを押しても`.eslintrc.js`をもとにしたフォーマットは行われません。

この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
NumPyでデータ作成を始める

# NumPyとは？
なむぴー？なむぱい？
ナムパイ、ナンパイが正解らしい
`NumPy`は、行列、ベクトル、多次元配列を効率よく処理できるライブラリ！
Pythonだけでも辞書、リストとかで割と柔軟にデータを扱えるけど、実際のデータ量を相手にすると速度面で無謀なんだって...

（数ⅢCやってない文系出身の私は「行列」とか聞くと、スッと理解できるか不安・・・^^;）

pandasのベースのライブラリとされているので、データ分析の際に一緒に使われることが多い
しかも使い方もpandasと似ている
まぁなにはともあれ...

# 触ってみよう
内容が内容なので少しずつまとめていく
今回はNumPyを使ってリストから多次元配列を作る、そしてそのプロパティを知るところまで見る

## リストから多次元配列を作る
- `１次元配列`（*ベクトル*）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/39159101-b6bd-09a8-18f9-14fcce93ba35.png)
ウンウン、そのままの結果

- `２次元配列`（*行列*）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/9016cf95-3f54-70f3-2982-ecc5e516e050.png)
まぁ、そのままではある

- `３次元配列`（３次元以上： *テンソル*　　　Tensor!?）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/7d8cba90-ba0b-f568-0e3c-b085aa3e50fa.png)
って、これがどう使われるのかがわからんから、全然ピンと来ない！！
何をやってるんや...

### なぜ速くなるのか
`np.array()`で作られたデータは `numpy.ndarray`という型になっている
ndarrayは要素を全て同じ型で持つことによって処理速度を速めている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/d284482c-9350-8779-821d-5e2795c1f32a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/4792ae3f-5026-ef6c-57cd-4ebf0a80beaf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/51498887-15cc-480b-3d59-ba31abe04087.png)
### ndarrayの持つプロパティ
- `ndim`
    - 次元数を返す
- `shape`
    - 各次元のサイズをタプルで返す　２次元配列なら (行数, 列数)
- `size`
    - 要素数
- `reshape`
    - 配列を指定した次元（行数、列数など）で作り直した配列を返す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/8e322f42-a496-688c-db1a-929122fe7476.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/6cdc1ede-0c49-ed2d-ecd1-cdf5a35bc0bc.png)
reshapeの多次元から多次元への変換は感動度が高いな〜　楽チン

### ndarrayの持つプロパティ　難易度アップ
- `T`
    - 転地。行と列を入れ替えた配列を返す。３次元以上でも使える。　（Tだけ!?w）
- `itemsize`
    - １要素のバイト数を返す
- `nbytes`
    - 多次元配列全体のバイト数を返す　（ネーミング揃えてよ！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/de02e574-7959-280c-0745-551846e856a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/67c98858-519d-1d87-00c6-5a63a901ee08.png)

３次元の転地がもうヤバい・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/12ac56dc-e3b9-db09-25e6-ff0c430a75ea.png)


# 感想
行列、テンソルを頭で考えようとするとぐちゃぐちゃになってきそう・・・
まだなんか多次元の配列作ってるなぁ程度だけど、行列とかの考え方に慣れてきてないから難しそう〜〜
細切れにちょっとずつ進めよう
優れた開発者の習慣：Apple系ソフト開発者以外にもオススメのWWDC2019で発表されたセッション和訳

初投稿です。
先日、WWDC2019に行ってきたのですが、そこである素晴らしいセッションに出会いました。

_"Great Developer Habits" (優れた開発者の習慣)_
_by Josh Tidsbury_

SwiftUIでもなければ、iOS13の新機能でもない。
一見するとあまり花のないセッションタイトルでしたが、内容はとても素晴らしいものでした。
忘れ去られるにはもったいないセッションでしたので、トピックを要約・和訳させていただきました。

Apple系の開発者に依存しない内容がほとんどです。
ぜひ、自分の開発体制を見直したりする一助としていただければと思います。

## この記事の元セッション
[セッションのビデオ](https://developer.apple.com/videos/play/wwdc2019/239/)(約35分)


## 導入
私たちのチーム(Technology Evangelism)は真に素晴らしいアプリをデベロッパーの人たちに作ってもらうために存在している。
今日紹介するTipsを用いて、アプリの実装に気をかけてほしい(craft in care)

デベロッパーが真に気をかけていることは、アプリのカスタマーからは直接目に見えるものではない。ただそれらのことは、パフォーマンスや信頼性に大きく影響する。
今日はその中でも以下の8つに焦点を絞って紹介する。

## Organize(整理する)
雑然と物が散らかる作業場では、道具を探すのに時間がかかってしまうし、アクシデントも起こりやすい。
ソースコードのファイルや、ストーリーボードは種類ごとにまとめることで、シンプルになり、関係性がわかりやすくなり、不具合の修正にかける時間が減る

* グループを用いて、機能ごとにソースコードファイルをまとめよう
* プロジェクト構成とファイル構成を一致させよう
* 巨大なStoryboardsを分割しよう
* プロジェクトファイルやビルドシステムを最新のものにしよう
* いつか使うかもしれないと消さずにコメントアウトしたcode scraps(ゴミコード)は、すぐに消そう。(それらは決して使われることはないし、たとえ必要になったとしてもログから遡ることができる)
* Warningはワークアラウンドではなく、根本原因から直そう


## Track(追跡する)
* Gitなどの履歴管理システムを使おう
* 一つ一つのコミットは小さく・独立した内容にしよう
* 有用なコミットメッセージを未来の自分のために書こう
* バグ修正や機能追加のためにブランチを活用しよう


## Document(文書化する)
たまに、”I don’t need comments, my code is self-documenting”(私にはコメントなんて必要ない、コード自身がドキュメントだからね)とかいう人がいますが、私は賛同しかねます。

このような意味のないコメントと、何を指しているのかわかりにくい変数名の代わりに

```swift
// A constant string id value
let id = “xxxxx-xxxxx-xxxxx”
```
以下のように、その変数がここで定義されている背景や、なんのために使うのかという理由を書くようにしましょう。

```swift
// The permanent identifier for this application when interacting
// with the CMS, provided by the vendor of the CMS.
let cmsApplicationIdentifier = “xxxxx-xxxxx-xxxxx”
```

Xcodeを使っていれば、option + command + /(スラッシュ)で、自動的にドキュメントの下書きを生成してくれます。
あとは空欄を埋めるだけで完成です。

* コメントは将来の理解のために重要である
* 良いコメントは、背景や理由を含んでいる
* 叙述的な変数名や一意な名前を付けよう
* ドキュメントをソースコードに含めよう


## Test(テストする)
* 後悔しないために、ユニットテストを書こう
* コードをコミットする前に、ユニットテストを走らせよう
* CI(継続的インテグレーション)環境を構築しよう


## Analyze(分析する)
* Network Link Conditionerを使って、貧弱なネットワーク環境をシミュレートしよう
* SanitizersとCheckersを使おう(メモリ衝突やバッファオーバーフロー、データリソース、0除算、理由もなく毎回結果が変わるバグなどを検知する助けとなるツール)
* パフォーマンスと効率をDebug Gaugesを使って計測しよう
* Instrumentsを用いて問題を精査しよう

こうした細かな積み重ねが将来的なパフォーマンスと信頼性につながります


## Evaluate(評価する)
* コードレビューを開発の一環に含めよう
* エンバグする可能性を削減できる他にも、互いの知識を共有することで経験値を積むことができる
* 全ての変更行を理解しよう
* ビルドしよう
* テストを走らせよう
* 書式やスペル、構文の校正をしよう


## Decouple(切り離す)
* 機能的な区切れ目を特定し、切り離そう
* 成果を他のアプリでも使い回そう
* Extensionsを用いて、効率を上げよう
* 努力の成果をより広いコミュニティにシェアしよう
* ドキュメントは重要
* バイナリサイズの削減にも繋がる


## Manage(管理する)
* コミュニティやオープンソースプロジェクトは責任持って利用しよう
* 徹底的に依存性を理解しよう
* プライバシーの尊重を確保しよう
* 依存性がなくなったりメンテナンスされなくなったりした時のために、対策を練っておこう


## The Last 10%
* これらの1つ1つの作業には少しの時間が費やされるが、その一方で大きな時間の削減につながる
* これらのことを癖にして自動的にできる様になろう
* そして、もっと大切なことに頭を使おう