OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel Dusk でautoload.phpが開けないエラーが出た

Laravel Duskを使ってみたら、エラーが出たので、残しておきます。

## 環境

・Laravel5.4
・Docker
・php 7

## 事象

```
$ php artisan dusk 
```

を実行したら、以下のエラーが表示された。

```
$ php artisan dusk
PHPUnit 6.5.12 by Sebastian Bergmann and contributors.

Cannot open file "/＊＊＊＊＊＊/bootstrap/autoload.php".
```

## 解決策

autoload.phpファイルを作成

```
$ vi bootstrap/autoload.php
```

中身はこちら。

```
<?php
  
define('LARAVEL_START', microtime(true));

require_once __DIR__.'/../vendor/autoload.php';
```
Macを再起動したらMySQLが動かなくなったので頑張った

たぶんありがちな話。

でも似たような話がいろいろ転がっていて、どれが自分の症状なのかよくわからなかったので手間取ったorz

# 現象
1. なんかMac重いなーと思って再起動
2. 再起動完了！さー開発するぞ
3. あれ？ローカル開発環境立ち上がらない・・・
4. MySQLにログインできない・・・だと・・・😂

# 症状
これで落ちてた。なんでだ。

```
ERROR 1045 (28000): Access denied for user 'root'@'localhost'
```

# 環境
OS: macOS High Sierra 10.13.6
MySQL: 5.7.19

# 解決
事象が起こった要因は結局よくわからなかったが、自分の場合は下記をやることで解決した

### そもそもなんで怒られてるのか
``Access denied``なので、まあ権限まわりがおかしくなっているんでしょうと推測

### であれば、権限なしでも使えるようにしてやればよい
#### mysqlを止める
```
sudo mysql.server stop
```

#### 権限なしで動かせるようにする
```
sudo mysqld_safe --skip-grant-tables &
```

#### mysqlにログイン
```
mysql -u root
```

#### mysql db の users table をチェック
```
select host, user, authentication_string from user;
```

#### passってなんぞ。。。
```
+-----------+---------------+-------------------------------------------+
| host      | user          | authentication_string                     |
+-----------+---------------+-------------------------------------------+
| localhost | root          | pass                                      |
| localhost | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| localhost | mysql.sys     | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
+-----------+---------------+-------------------------------------------+
```

#### 消したれ
```
update user set authentication_string = null where user = 'root'
```

#### 通常モードで起動し直す
```
sudo mysql.server stop
sudo mysql.server start
```

#### 入れた
```
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.19 Homebrew

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

# まとめ
よくわからず使っているのは良くないなと思いました。
ちゃんと勉強しよう。。
io.Reader の進捗状況

(io.Reader).Read を「フック」することで、Read の進捗状況を監視する方法の紹介です。

例えば、HTTP でのファイルダウンロードの進捗状況を画面に表示したいという場合に使えます。

# 方法

(段階的に解説します)

手始めに `io.Reader` をラッピングするような構造体を定義します。
Go では、構造体のフィールド（無名）として構造体やインターフェイスを埋め込むと、埋め込んだ側の構造体が埋め込まれた側のメソッドの実装を引き継ぐことができます。

`io.Reader` を埋め込んだ構造体は、自身が `io.Reader` を実装したかのように振る舞います。

## 無名フィールドとして埋め込む

```go
type MyReader struct {
    io.Reader
}

func a() {
    file, _ := os.Open("hoge.txt")
    defer file.Close()

    r := MyReader {
        Reader: file,
    }

    content, _ := ioutil.ReadAll(r) // r.Read が実装されていることになっている
}
```

`MyReader.Read` というメソッドは実装していません。
しかし `MyReader.Reader` として `io.Reader` を埋め込んでいるため、`MyReader` に対して `ioutil.ReadAll` を呼び出せます。

`MyReader.Reader` として埋め込まれた `*os.File` のメソッド `Read` が呼び出されます。

## 埋め込み先でフックする

ここで、メソッド `MyReader.Read` を定義してみます。

```go
func (r *MyReader) Read(p []byte) (n int, err error) {
    return r.Reader.Read(p)
}
```

ここでは、埋め込んだ `Reader` のメソッド `Read` を明示的に呼び出しているだけです。
当然、この状態の `MyReader` も `ioutil.ReadAll` に渡せます。

そして、`r.Reader.Read(p)` の前後に処理を挟むことで、加工やらフィルタリングやら、進捗状況の更新やらができるようになるわけです。

# 作ってみた

例によってパッケージを作ってみました。

[progio](https://bitbucket.org/shu_go/progio)

```go:利用例
progreader := progio.NewReader(
    response.Body,
    func(p int64) {
        fmt.Printf("%d%%  ", p)
    },
    progio.Percent(response.ContentLength, 5/* % ごとに上のfuncを呼び出す */),
)
```

ちなみに Writer もあります。
Item 40: Consistently use the Override annotation

# 40.一貫してOverrideアノテーションを使うべし

Javaライブラリはいくつかのアノテーションを提供してるが、多くのプログラマにとって、```@Override``` が一番重要だろう。
一貫して```@Override``` を使用していれば、バグが起こりにくくなる。
以下の[bigram](https://www.weblio.jp/content/bigram)を模したクラスを例に見ていく（バグあり）。

```java
package tryAny.effectiveJava;

import java.util.HashSet;
import java.util.Set;

//Can you spot the bug?
public class Bigram {
    private final char first;
    private final char second;

    public Bigram(char first, char second) {
        this.first = first;
        this.second = second;
    }

    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }

    public int hashCode() {
        return 31 * first + second;
    }

    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}
```
このプログラムは26を出力すると思いきや、260を出力する。
原因はequalsをOverrideするつもりがOverloadしてしまっていることにある。```Object.equals```の引数はObject型であり、シグニチャが違う。
こういった誤りを防ぐために、Overrideするメソッドには```@Override```をつける。そうすると以下のコードはコンパイルエラーとなる。

```java
@Override public boolean equals(Bigram b) {
    return b.first == first && b.second == second;
}
```
正しくは以下のようになる。

```java
@Override
public boolean equals(Object o) {
    if (!(o instanceof Bigram))
        return false;
    Bigram b = (Bigram) o;
    return b.first == first && b.second == second;
}
```

このようなことから、**親クラスのメソッドをOverrideするときは@Overrideをつけるべきである**。
これには一つ例外があって、具象クラスにおいて、親の抽象メソッドをOverrideするときは、そもそもOverrideしないとコンパイルエラーが出るので、```@Override```の記述の必要はない（記述による害もない）。
cmdで今日の日付のフォルダを作る＋昨日の一部ファイルをコピーしておく

# コマンドプロンプトでフォルダ作る＋コピー
メモ帳なので自由に書かせてもらいます
Win環境で毎日メモしていく際のバッチです

月の切り替わりと週明けに対応してないです
存在チェックやってなければ更にマイナスとかやったらいいんだろうけど

```
# 作業用フォルダへ移動
cd "W:\tmp\"

# 本日の日付文字列と昨日の日付文字列を取得
# 20180824とかの文字列になる
set /A DATE_FORMAT=%date:~0,4%%date:~5,2%%date:~8,2%
set /A YESTERDAY_FORMAT=%DATE_FORMAT%-1

# 今日のフォルダを作る
mkdir "W:\tmp\%DATE_FORMAT%"
# 昨日のタスクをコピーしてくる
copy "W:\tmp\%YESTERDAY_FORMAT%\task.txt" "W:\tmp\%DATE_FORMAT%"

# 開いて終わり
explorer "W:\tmp\%DATE_FORMAT%"
```

タスクくらいクラウドで管理しなさいよと思うけど
旧態依然としたOA環境だとそういうの使えない辛さよ
Fatal error: Call to a member function ~ on a non-object

# 概要

Fatal errorまとめその１。
タイトル「~」の箇所にはメソッド名が入る。

# なんのエラーか

日本語にすると「XXXというメンバー関数はオブジェクトにありません」という意味。 
このエラーが出ている行（実際のエラーメッセージには、エラーになったクラスと行数が出力されている）で

```php:Sample.php
$obj->XXX();
```

のようなメンバー関数呼び出しをされている。
「XXXという関数」が無いと言われる。 

考えられる原因としては

1. 本当にその関数が無い
2. オブジェクトが生成されていない

が有力。これ以外にもあるよという方は教えてください。

## 確認手順

1. スペルミスのチェック
2. オブジェクトが生成されているかをvar_dump
3. 2. のチェックで生成されている場合は、そのあとのコードでオブジェクトが削除されていないか

### 1. スペルミスのチェック

1. そもそもスペルがあっているか
2. 大文字・小文字があっているか
3. 全角・半角があっているか
4. 余計なスペースがメソッド名に入っていないか

### 2. オブジェクトが生成されているかをチェック

以下のようにvar_dumpしてチェックする。

```php:Sample2.php
$obj = new YYY();
var_dump($obj);
$obj->XXX();
```

もしvar_dumpの結果がNULLならオブジェクトの生成がうまくいっていないということになる。
実戦ではこんなに近くに書いていないがために気づいていないということもある。
そのため、このエラーが出た場合には、オブジェクトが生成されている箇所の直後に
var_dumpをチェックする。


もし、このXXXという関数がYYYというクラスオブジェクトに定義されているのであれば、事前にYYYクラスオブジェクトを生成する必要がある。

## 3. 2. のチェックで生成されている場合は、オブジェクトが削除されていないか


```php:Sample3.php
$obj = new YYY();
var_dump($obj); // YYYのオブジェクトが生成されていることを確認

// 何か長いコードがある・・・

$obj = null; // こんな感じのとかあったらビンゴ。違うパターンもあるので、そこはvar_dumpしながら。

$obj->XXX(); // Fatal error ~ on a non-object
```

# まとめ


ソースコードを最後は追うしかないが、自分が書いたコードなら自分に責任がある。他の人の書いたコードでも、今は自分が関わっているため、しっかり読んで修正を加えていくしかない。頑張ろう。
reduce で Promise を返す関数を配列に詰め込んだやつを順番に一定間隔を空けて実行していこうぜ。

reduce()でうまいこと処理したろっと思ったJava Script歴1週間の僕が、なんかこう最低限でまとまってるのを見つけられなかったのでここに殴りがいておきます。
他の誰かの役に立ちますように...

Java Script歴1週間なのでお手柔らかに。
右も左もマジでわかんないので間違っているとこがあればdisらずに優しく教えてください...

また、決まり文句みたいなもんですが、ここに書いてるプログラムは最低限動くやつなので、各自でエラー処理とかバリデーションのとかする前提ですのでよろしくお願いします。

順番もキレイに並ぶのでwebスクレイピングなんかと相性がいいと思います。

# こう書くのだ！
```javascript:hoge.js
//関数で処理したいデータ
var array = ['a','b','c','d'];

//並べたいな〜と思っている関数
function Func(param){
  //処理
}

//Func()を呼び、Promiseを返す関数
//引数とかは適当に変えて使える
function returnPromiseFunc(hoge){
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      //ここへやりたい処理を書く
      Func(hoge);
      resolve();
    }, 1000);
    //setTimeout()の第二引数にはインターバルにしたいﾐﾘ秒を入れる。
  });
}

//処理する関数を配列に詰める
var funcArray = Array();
$.each(array, function(index, param){ //jQuery
  funcArray.push(function(){ return returnPromiseFunc(param)) });
});

//reduce()で配列を処理していく
funcArray.reduce(function(previousValue, currentValue){
  return previousValue.then(currentvalue);
},Promise.resolve());
```

# `reduce()`の引数
さっきの例を引用して...

```javascript
functionArray.reduce(function (previousValue, currentValue, currentIndex, array){
  return previousValue.then(currentvalue);
});
```
`previousValue`は初周は素のPromise。2周目以降は前回返ってきたPromiseさんがいます。
コイツを`return`で返して行くことで処理をつなげていけるっぽい。

`currentValue`もその名前の通り、手元にあるべき関数が入ってます。
それを実行して僕らは幸せになることができるってわけです。嬉しい。

`currentIndex`はループが何周目かを表す整数が入っています。

`array`は.reduce()が処理している配列が入っています。たぶん。
（consoleで見たら全部`f()`でよくわからんかったごめん。）

# 最後に
[Promiseについて0から勉強してみた](https://qiita.com/toshihirock/items/e49b66f8685a8510bd76)にいい感じにまとまってたので、Promiseを使うことになったときに一読すれば結構スッと入ってくると思います。

# 参考資料
[Promiseについて0から勉強してみた](https://qiita.com/toshihirock/items/e49b66f8685a8510bd76)
[Promiseを返す関数の直列実行におけるreduceの利用と注意点](https://qiita.com/berlysia/items/3aeb1f0ab2494de9e24e)
SQLについて

#<b>データベースとは？？</b>
データ形式をあらかじめ決めて、データを管理する構造のことを指します。
また、データを管理するプログラムとしてDBMS(Database Management System:データベース管理システム)というものがあり、DBMSに命令を与えるのがSQLなどになります。

#<b>SQL</b>
##クエリとは？
クエリ(query)とは、英語で「問い合わせ（る）」、「訪ねる」などの意味を持つ英語の単語で、ITではソフトウェアに対するデータの問い合わせや要求などを一定の形式で文字に表現することを意味します。 
クエリを通じて、データの検索や更新、削除、抽出などの要求をデータベース（DBMS)に送信することができます。

簡単に言うと、データベースへの命令みたいな感じです

##SQLとは？
SQL(Structured Query Language)はRDBMSと対話するための言語です。
クエリが命令でSQLが言語です。

ex)

|| 具体例 |
|:----|:---|
|クエリ|おいデータベース！！〇〇の値とってこいや|
|SQL| SELECT 〇〇 FROM △△ ~~|

##どんな命令があるの？
SQLでデータベースに対するデータの読み書きは、<b>「登録」「読み出し」「更新」「削除」</b>の４つに分類できます。

|操作| 内容 |
|:----|:---|
|登録|新たなレコードを書き込むこと|
|読み出し|既存のレコードを取得すること|
|更新|既存のレコードの内容を部分的に変更すること|
|削除|既存のレコードを消し去ること|

今回は具体例として下のような大学生の名簿のレコードがあったとしましょう。

|名前|学年|性別|住所|出身高校|
|:----|:---|:---|:---|:---|
|山田|4|男|東京|W高校|
|田中|1|女|神奈川|K高校|
|斎藤|3|男|神奈川|T高校|
|小林|3|男|千葉|J高校|
|吉田|2|男|埼玉|S高校|

日常生活での表現をデータベースでの「登録」「読み出し」「更新」「削除」に当てはめてみると、
・新しい生徒が入学する　→　<b>名簿への「登録」</b>
・3年生の一覧を見る 　→ <b>名簿の読み出し</b>
・山田さんの住所を変更する　　→ <b>名簿の山田さんのレコードの更新</b>
・斎藤さんが退学した　→ <b>名簿の斎藤さんのレコードの削除</b>

みたいな感じになります。

##実際のSQL文はどんな感じなの？？
実際にSQLを紹介していきます。イメージはかなり英語に近いので、あまりプログラミングをしたことがない人でも何をしているのかだいたいつかめると思います。

|操作| 命令 |例|
|:----|:---|:---|
|登録|INSERT|INSERT INTO 名簿 VALUES('前田','3年', '女', '東京', 'S高校' )|
|読み出し|SELECT|SELECT 名前 FROM 名簿 WHERE 学年='3年'|
|更新|UPDATE|UPDATE 名簿 SET 住所='埼玉' WHRER 名前='山田'|
|削除|DELETE|DELETE FROM 名簿 WHERE 名前='斎藤'|

１つ目の登録は「名簿に名前が前田、学年が3年、性別が女、住所が東京、出身高校がS高校のユーザーを登録する」
２つ目の読み出しは「名簿から、学年が3年の人の名前を取得する」
3つ目の更新は「名前が前田のレコードの住所を埼玉に更新する」
4つ目の削除は「名簿から名前が斎藤のレコードを削除します」　

##よく使うオプション
###WHERE
WHEREは条件を指定することができます。

```
SELECT 名前 FROM 名簿 WHERE 性別="男"
```
意味：名簿から「 性別="男"」という条件で名前を読み出せ

```結果.
山田
斎藤
小林
```

###LIKE
LIKEを使うと、任意の文字列を指定することができます。

```
SELECT 名前 FROM 名簿 WHERE 名前 LIKE '%田'
```
意味：名簿から指名が任意の文字列で末尾が「田」であるという条件で指名を読み出せ

```結果.
山田
吉田
```

###ORDER BY
SELECT命令で読みだしたデータを整列させることができます。ORDER BYの後に、整列の対象となる列名を指定し、昇順(ASC)、降順(DESC)を指定します。

```
SELECT 名前, 学年 FROM 名簿 ORDER BY 学年 DESC 
```
意味：名簿から名前と学年を読み出し、学年の大きい順に整列せよ。

```結果.
山田 4
斎藤 3
小林 3
吉田 2
田中 1
```

###INNER JOIN
INNER JOINは内部結合をします。内部結合とは、指定したそれぞれのカラムの値が一致したものを結合することです。
例えば、名簿に乗ってる人たちのテストの点数のテーブル「得点表」があるとしましょう。

|名前|数学|英語|国語|
|:----|:---|:---|:---|
|斎藤|99|60|45|
|落合|3|5|100|
|山田|80|70|70|
|小林|87|32|57|
|清水|60|100|100|

```
SELECT * FROM 得点表 INNER JOIN 名簿 名簿.名前=得点表.名前
```
意味：得点表から、名簿と得点表のテーブルの、それぞれの名前が一致したものの情報をすべて読み出す

```結果.
斎藤 99 60 45
山田 80 70 70
小林 87 32 57
```
ちなみに、結合した時に、それぞれの名前が一致しなかった場合はnullが入ります。


これからもう少し修正を加えていい記事にしていきます
Docker+自前のPostfixでRedmineを構築する

# 環境・要件

CentOS Linux release 7.5.1804 (Core)

* Redmine3.2.0を使いたい（移設のためバージョンちょっと古めです）
* DBはMySQL
* チケット更新時にはメールを飛ばしたい
* http://IPアドレス でアクセスしたい（SSL化はとりあえずやらない）
* Dockerを使ってみたい
* 本当はDockerfileを書いてやりたかったけどエラーでうまく立ち上がらず挫折

# 作業開始

### Dockerインストール&イメージ取得
redmineのバージョンは古いのを指定しています

```
$ sudo yum install docker
$ docker pull sameersbn/redmine:3.2.0
$ docker pull sameersbn/mysql:latest
```

### データストア作成
コンテナが落ちてもデータは残るようにするため（永続化というやつ）
/home/docker に作ってしまったのですが普通は /srv/docker に作るみたいですね…

```
$ mkdir -p /home/docker/redmine3.2.0/mysql
$ mkdir -p /home/docker/redmine3.2.0/redmine
```

### SELinuxの設定
これをやらないとdocker run で Permission denied のエラーが出てハマります

```
$ chcon -Rt svirt_sandbox_file_t /home/docker/redmine3.2.0/mysql
$ chcon -Rt svirt_sandbox_file_t /home/docker/redmine3.2.0/redmine
```

### コンテナ作成

```
$ docker run --name=mysql-redmine -d --env='DB_NAME=redmine' --env='DB_USER=redmine' --env='DB_PASS=password' -v /home/docker/redmine3.2.0/mysql:/var/lib/mysql sameersbn/mysql

$ docker run --name=redmine -d -p 80:80 --link=mysql-redmine:mysql -v /home/docker/redmine3.2.0/redmine:/home/redmine/data sameersbn/redmine:3.2.0
```

しばらく待つと http://IPアドレス でアクセスできるようになりました！とても簡単

## メールの設定

ここがかなりハマったところです…

まずは **ホストOS** 上にメールサーバーを立てます。
(最初Redmineコンテナにメールサーバーを立てようとしていてハマっていました…)


### PostfixのインストールとMTA設定
PostfixをデフォルトのMTAに設定します

```
$ yum install postfix
$ sudo alternatives --config mta
  選択       コマンド
-----------------------------------------------
 + 1           /usr/sbin/sendmail.postfix
*  2           /usr/sbin/sendmail.sendmail
（Postfixを選択する）
```

この時点で `$ sendmail foo@foo.com` コマンドでメール送信ができるようになるはず

### RedmineコンテナのIPを調べる

```
$ docker inspect redmine
(略)
"IPAddress": "172.17.0.3",
(略)
```
172.17.0.3 のようです。

### Postfixの設定&再起動

mynetworksにコンテナを含むIPを設定（172.17.0.0/16）
inet_interfacesにdocker0のIP？を設定（172.18.0.1）
よく理解できてないのですがとりあえずこれで動きましたというかんじです

```
# vi /etc/postfix/main.cf
mynetworks = 168.100.189.0/28, 127.0.0.0/8, 172.17.0.0/16
inet_interfaces=localhost, 127.0.0.1, 172.18.0.1

# systemctl restart postfix
```

### firewallの設定
コンテナからのアクセス（172.17.0.0/16）を許可します

```
# firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="172.17.0.0/16" service name="smtp" accept' 
# firewall-cmd --reload
```

### Redmineの設定

Redmineコンテナの中に入ります
`$ docker exec -it redmine bash`

configuration.yml を作成＆編集

```
$ mv  /home/redmine/redmine/config/configuration.yml.example /home/redmine/redmine/config/configuration.yml
email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: 172.18.0.1
      port: 25
```

exitして、redmineを再起動
`$ docker restart redmine`

http://IPアドレス/settings?tab=notifications から「テストメールを送信」で送信できることを確認しました！:v:


今度は SSL化 & DockerFileを書いてみたいです！
[Xcode]ビルドエラーが一部しかリストアップされない件の対応

#要求

- 発注先から、受納したソースファイルを取り込んだら、山の様にビルドエラーが発生している様だ。
- XCodeでビルドをかけても、一つのクラスでビルドエラーが発生したら、中断してしまい、全部で何件、ビルドエラーが発生しているのか分からない。
- ビルドエラー個所を全部リストアップしたい。

#環境
Xcode8.3.3
MacOSX10.13

#結論
Xcodeの環境設定
Generalタブの中の「Continue building after errors」にチェックを入れる事で実現可能

![スクリーンショット 2018-08-24 17.05.04.png](https://qiita-image-store.s3.amazonaws.com/0/235774/9f42dfa5-a36f-5c62-19e8-f2bfb4e7136b.png)
kubernetesのNodeNotReadyを再現させる

一部nodeがNodeNotReadyになる障害があって検証のために状況を再現させたかったのです

色々模索しましたがiptablesで遮断するのが一番お手軽でした

NodeNotReadyにさせたいnodeにログインして

```
# iptables -I OUTPUT 1 -j DROP -d [apiサーバのエンドポイント]
```

しばらくすると`NodeNotReady`になります
回復させたい時は

```
# iptables -D OUTPUT 1
```
としてください
追加する時にdnsで指定しているなら複数行追加されている場合もあるので`iptables -L OUTPUT`で確認しながら追加されたものを全部消します

今回はdestinationをapiサーバに絞ってあるので問題ないですが、
__SSHでログインしながらALLをDROPするとその瞬間から何もできなくなります__（1回やってしまった）

起こった障害になるべく近付けるためこの形にしましたがINPUTをDROPするのでも同じことになるかも？

正攻法っぽくapiでnodeのconditionsをPATCHしてもすぐにNodeReadyに回復するのでそっちでやるのは無理そうでした
Pandasを使って複数あるExcelシートを分ける

## 概要
pandasでexcelファイルを読み込むことは多々ある。
しかし、複数のシートが含まれたexcelファイルを読み込む際、重すぎて全シート読み込むのは嫌だった。

「１シートにつき1ファイル」に変更するためには、macであればNumbersでも同じことができる。([MacのためのNumbers: Numbers スプレッドシートを Excel または別のファイルフォーマットに書き出す](https://support.apple.com/kb/PH26057?locale=ja_JP&viewlocale=ja_JP))

But, excelファイルが大きすぎてNumbersではできず。。
[@stokes](https://qiita.com/stokes)さんの[【Python】pandasでExcelを読み込む](https://qiita.com/stokes/items/75aca6ce142ff9778003)を写経させていただき、Pythonでやるとファイルが大きくても、サクッとできたのでメモ。
## 環境
Python 3.6.2
anaconda 4.4.1
pandas 0.20.3

## 1. excelファイルの読み込み
今回は`hoge.xlsx`という複数のシートを持ったexcelファイルの読み込みを考えましょう。

```Python
multi_excel_sheets = pd.ExcelFile('hoge.xlsx')
```

ちなみに型は`pandas.io.excel.ExcelFile`。

```
type(multi_excel_sheets) #=> pandas.io.excel.ExcelFile
```

## 2. １シートずつ、excelファイルを作っていく
ここではsheet名をそのままファイル名にします。

```Python
for sheet_name in multi_excel_sheets.sheet_names:
    df = multi_excel_sheets.parse(sheetname=sheet_name) # sheet_nameのシートをDataFrameとしてdfへ
    df.to_excel('{}.xlsx'.format(sheet_name)) # excelに書き込み
```

これでいちいち全シートを読み込まなくても、特定のエクセルファイルだけ読み込めば良い環境ができた。


## 参考
* [MacのためのNumbers: Numbers スプレッドシートを Excel または別のファイルフォーマットに書き出す](https://support.apple.com/kb/PH26057?locale=ja_JP&viewlocale=ja_JP)
* [【Python】pandasでExcelを読み込む](https://qiita.com/stokes/items/75aca6ce142ff9778003)
少人数～大人数の勉強会には「sli.do」を！

# はじめに
最近いくつかの勉強会で「sli.do」を利用しているのを見かけます。
これは質疑応答に特化したサービスで、質問が匿名でできるんですよね。

日本語の記事があまり多くなかったんで、メリデメと使い方について自分なりの備忘録としてもまとめておきます。
※無料利用範囲についての記事となります。

https://www.sli.do/
![slido_user_top.png](https://qiita-image-store.s3.amazonaws.com/0/210886/b6965ff3-1931-ee08-65d6-8c2c3bca1157.png)


# sli.doとは

+ 勉強会や会議の質疑応答に特化したサービス
+ 匿名でもニックネームでも質問ができる
+ 共感できる質問については「like」ボタンで共感の意思表明ができる
+ 簡単な投票機能もあり、結果が回答者にリアルタイムで反映される

# メリット（期待効果）

+ 匿名で質問できるので大人数の場でも質問しやすい！
+ みんなの質問が集まってLikeボタンで質問が厳選されるので有意義！
+ （常識的に）テキストでの質問なので支離滅裂な質問が飛んでこない！
+ いいねが多くもらえると「良い質問したんだな」って質問者の満足度が高まる
+ いいねを押すだけで参加意識や参加満足度が高まる

# デメリット＆注意事項

## 参加者側の制約
+ 質問の文字数制限は160byteまで。簡潔な質問をしましょう。
+ 参加者の名前設定は一度設定すると１時間変更出来ない
+ ページヘのJOINや使い方に慣れていないと参加が出来ないので、会のアイスブレイクに練習するとよい。

## 管理者制約
+ アンケートは３問まで作成可。それ以上の場合は古い質問を消して作成が必要。予め準備しておきましょう。
+ 管理画面に入れるのは１人まで。共有アカウントなど作って解決させる必要あり。
+ 無料利用の場合、IDを知っている人なら誰でも入れるのでIDの管理徹底が必要。


# 使い方：運営者編
## 事前準備
### イベントの作成
+ 「イベントの日付（開始・終了）」と「イベント名」を入力してイベント作成

### イベント情報編集
- 主に編集しそうなとこ

#### General	
Basic Information
イベント名、日付、イベントIDの編集ができる。
イベントコードは自動で発行されるが、気になる人は任意のコードに変更したほうが良い

#### Customization	
Present View
プレゼンテーションビューのテーマや表示質問数の変更ができる

### アンケートの準備
結果収集も行うなら、スプレッドなどに結果収集用の枠作っといたほうが良いかも

#### Multiple choice（単一・複数選択回答）
- 質問文
- 選択肢（複数設定可）
- 複数選択の可否
- 複数選択数の最大値設定

#### Text（記入回答）
- 質問文
- ワードクラウド変換の可否
- 複数回の回答可否

#### Range（点数回答）
- 質問文
- 点数最大値


## 開催中

### 質問管理機能
#### 質問を取り上げる
- 質問に対して回答する場合は「Highlight question」機能を使って取り扱うと親切

#### 質問へ回答する
質問に対して管理画面から回答結果をレスする
#### 質問をアーカイブする
- 次の話に進んだなど、質問が場にふさわしくなくなった場合はアーカイブする
- 不適切な質問はすぐにアーカイブや削除する（監視が必要）

### ライブ投票管理機能
#### ライブ投票を行う
- 「Create poll」で必要な項目を入力しライブ投票を作成する
- 「Activate poll」でライブ投票を有効にする

#### ライブ投票を終了する
- 「Delete」で削除する（無料利用の場合は３つまでしか作成できないので、都度作成が必要）
- 復活はできないので、削除前にデータ保存が必要

## 事後対応
### 統計画面
- 「Analytics」タブに統計情報が作成されます
  - Active users
  - Questions
  - Poll votes
- 必要なデータはテキストで別途保存しても良いかもですね。

### イベントの削除
残してても良いですが、削除してきれいに終わりましょう。


# 使い方：参加者編
## JOINする
- 「https://www.sli.do/」へアクセス
- 参加するイベントコードを入力して「JOIN」

## 質問する（質問タブ）
- 質問を入力し、匿名のままもしくは発言ユーザー名を入力して送信！
- 共感できる！いいなとおもった質問にはLIKEボタンを押す！

## ライブ投票する（ライブ投票タブ）
- 質問の回答形式に応じて回答する

# おわりに
以上で主要機能の説明完了となります。
実際コレを使いこなしながら進めるのは非常に大変だと思いますが、
参加者は楽しいとおもいますんで是非楽しい勉強会にしましょう！

Thankyou!
測地基準系と座標系から調べるEPSG

意外と、EPSG登録されてるJGD2011のまとまったもの見当たらなかったので調べてまとめた。epsg.io、見やすくて最高。

|  |Tokyo| JGD2000 | JGD2011 | WGS84 |
|:-------|-------:|-------:|-------:|-------:|
| 地理座標系 |-| 4612 | 6668 | 4326 |
| UTM投影座標系 |3092〜3096| 3097〜3101 | 6688〜6692 | 32651〜32656 |
| 平面直角投影座標系 |30161〜30179| 2443〜2461 | 6669〜6687 | - |
| 球面メルカトル図法 |-|- |-|3857|
0のみで構成された文字列

[PHP 型の比較表](http://php.net/manual/ja/types.comparisons.php)

'00'に迷ってしまったのでメモ。
文字列の`if($x)`と`empty($x)`では'0'のみ特殊なようです。

# PHP 関数による $x の比較

| 式 | empty() | boolean : if($x) |
| ---- | ---- | ---- |
| $x = ""; | TRUE | FALSE |
| $x = "0"; | TRUE | FALSE |
| $x = "00"; | FALSE | TRUE |

```
if ('00')
{
    var_dump('true');
}
else
{
    var_dump('false');
}

if (empty('00'))
{
    var_dump('true');
}
else
{
    var_dump('false');
}
```

```
string(4) "true"
string(5) "false"
```

# == による緩やかな比較

| | TRUE | FALSE | 1 | 0 | -1 | "1" | "0" | "-1" | NULL | array() | "php" | "" |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| "" | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | TRUE |
| "0" | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE |
| "00" | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE |

```
<?php
        //Enter your code here, enjoy!

if ('00' == TRUE)
{
    var_dump('"00" == TRUE', 'true');
}
else
{
    var_dump('"00" == TRUE', 'false');
}

if ('00' == FALSE)
{
    var_dump('"00" == FALSE', 'true');
}
else
{
    var_dump('"00" == FALSE', 'false');
}

if ('00' == 1)
{
    var_dump('"00" == 1', 'true');
}
else
{
    var_dump('"00" == 1', 'false');
}

if ('00' == 0)
{
    var_dump('"00" == 0', 'true');
}
else
{
    var_dump('"00" == 0', 'false');
}

if ('00' == -1)
{
    var_dump('"00" == -1', 'true');
}
else
{
    var_dump('"00" == -1', 'false');
}

if ('00' == "1")
{
    var_dump('"00" == "1"', 'true');
}
else
{
    var_dump('"00" == "1"', 'false');
}

if ('00' == "0")
{
    var_dump('"00" == "0"', 'true');
}
else
{
    var_dump('"00" == "0"', 'false');
}

if ('00' == "-1")
{
    var_dump('"00" == "-1"', 'true');
}
else
{
    var_dump('"00" == "-1"', 'false');
}

if ('00' == NULL)
{
    var_dump('"00" == NULL', 'true');
}
else
{
    var_dump('"00" == NULL', 'false');
}

if ('00' == array())
{
    var_dump('"00" == array()', 'true');
}
else
{
    var_dump('"00" == array()', 'false');
}

if ('00' == "php")
{
    var_dump('"00" == "php"', 'true');
}
else
{
    var_dump('"00" == "php"', 'false');
}

if ('00' == "")
{
    var_dump('"00" == ""', 'true');
}
else
{
    var_dump('"00" == ""', 'false');
}
```

```
string(12) ""00" == TRUE"
string(4) "true"
string(13) ""00" == FALSE"
string(5) "false"
string(9) ""00" == 1"
string(5) "false"
string(9) ""00" == 0"
string(4) "true"
string(10) ""00" == -1"
string(5) "false"
string(11) ""00" == "1""
string(5) "false"
string(11) ""00" == "0""
string(4) "true"
string(12) ""00" == "-1""
string(5) "false"
string(12) ""00" == NULL"
string(5) "false"
string(15) ""00" == array()"
string(5) "false"
string(13) ""00" == "php""
string(5) "false"
string(10) ""00" == """
string(5) "false"
```
CSVファイルをブラウザで開かせない方法

## 課題

例えば、'/csv/download'というリンクからCSVファイルをダウンロードさせるために、以下のようなコードをコントローラに書いたとします。

```ruby
def download
  csv = make_csv_file
  send_file csv
end
```

ブラウザにてリンクをクリックすると、(期待する動作は「CSVファイルがダウンロードされる」ですが)CSVファイルがブラウザで自動的に開かれ、内容が表示されてしまいます。

## 解決方法

リンクを'/csv/download.csv'と拡張子付きにする。
もっといい方法がありそうですが、見つけ切れませんでした。もしご存知の方がいればコメントで教えてください。(>_<)

## 前提

まず前提として、上記サンプルコードでは make_csv_file という関数で正常なCSVファイルへのパスを返しているものとします。
レスポンスヘッダを確認すると、

```
Content-Disposition: attachment; filename="hoge.csv"
Content-Transfer-Encoding: binary
Content-Type: text/csv
```

となっていました。

また、ブラウザの設定によってはダウンロードではなく開くのが既定の動作となる場合がありますが、そうではない状態とします。
参考リンク：[Chromeでダウンロードしたファイルを自動的に開かないようにする](https://moondoldo.com/wordpress/?p=476)

## 試したこと

### application/octet-stream

```ruby
send_file csv, type: "application/octet-stream"
```

と修正し、レスポンスヘッダが

```
Content-Type: application/octet-stream
```

となるようにしましたが、ダメでした。(自動的に開いてしまう。以下同様)

### download属性

リンクにdownload属性を追加してみましたが、ダメでした。

```
<a href="/csv/download" download>ダウンロード</a>
```

参考リンク：[究極のファイルダウンロード](https://qiita.com/kawasima/items/2231f607677af31234e7)

### デフォルトのMIMEタイプを指定

routes.rbに下記のように定義し、

```
scope :csv do
  get "download", to: "csv#download", defaults: {format: :csv}
end
```

コントローラ側を下記のように修正しました。

```
def download
  csv = make_csv_file
  respond_to do |format|
    format.csv { send_file csv }
  end
end
```

UnknownFormatが出なかったので、意図通りcsvとして扱われているようですが、ダメでした。
【Game a Week】３週間目

# Game A Week
1. 一週間（月曜日から日曜日）に一本ゲームをリリースする。
2. 日曜日（まで）に制作したゲームを何らかの手段で公開する。
3. 制作したゲームはGame A Weekが終わるまで改変しては行けない。

# 前置き
先週の作品：[【Game a Week】２週間目](https://qiita.com/hota1024/items/a89c06a5f4cf6de386ba)

今週も諸事情により、金曜日（本日）にゲームを公開します。

# 今回作ったゲーム
皆さんは「15パズル」というパズルを知っていますか？

> 15パズルは、スライディングブロックパズル（Sliding puzzle）のひとつである。4×4のボードの上に4×4-1すなわち> 15枚の駒があり、1駒ぶんの空きを利用して駒をスライドし、駒を目的の配置にする。3×3のボード上で8枚の駒で同> > 様に遊ぶものは8パズルと呼ばれる。m×nのボードとm×n-1個の駒（m, n ≧ 2）に一般化できる。右下の隅または左上> の隅を空きとした配置を最終目標とするものが多い。
> Wikipedia

今回はこの15パズルを数字ではなくWebCameraを使った「PhofifPuzzle」というゲームを作りました。

# 使った技術
| 名前 | 説明 |
|:-:|:-:|
| [OpenSiv3D](https://scrapbox.io/Siv3D/)  | オープンソースなクロスプラットフォーム対応のフレームワークです。  |

# ゲームの詳細
今回作成したゲームはWebCameraを使ったゲームなので実画面は写せません。
実際に遊んでみたい方はGitHubのGistでソースコードを公開しているので遊んでみてください。
<https://gist.github.com/hota1024/d2469373b0046963e8f16ab452d3cead>

実行し、左に写っているのがパズルの本体で、右が完成後の写真です。
WebCameraで撮ってきた写真をリアルタイムで使用するのでかなり難易度が高いです。
コツとしては左上から少しずつ完成させていくとすぐにできます。

# ３週間目の感想
最近C++も触っていなかったのでいい機会になりました。
OpenSiv3Dもまだ勉強中なので公式のチュートリアルを見ながらこのゲームを作りました。

# 最後に
ここまで読んでいただきありがとうございます。
良ければアドバイスや質問よろしくおねがいします。
LambdaでElastiCacheサーバのprimaryとreplicaサーバのIPを取得してみよう

# Introduction

## 概要

AWSのLambda上で、ElastiCache(Redis)サーバのうち、primaryとreplicaのそれぞれのIPアドレスを取得してみます。

## 前提

* Redis用ElastiCacheを使用する
* クラスターモードはOFFである(つまりクラスターは使用しない)
* Multi AZによる自動フェイルオーバーを有効にしている
* 負荷分散の目的で、primaryサーバと、複数のreplicaサーバが存在する

## 動機(一つ目)

primaryサーバに障害が発生したとき、自動フェイルオーバーでreplicaサーバが自動的にprimaryサーバに昇格するのはとても便利!
しかも、primaryエンドポイントの名前にアクセスする限りは、ユーザはフェイルオーバーを意識する必要が無い (自動的にprimaryサーバを見てくれる)。

でも、replicaサーバにはそんな仕組みが無いので、primaryに昇格したサーバや、障害で切り離されたサーバを意識する必要があります。

## 動機(二つ目)

EC2から短期間に大量の名前問い合わせを行うと、DNSがロックアウト状態になってエラーを返すようになってしまうようです
(条件等は未確認だが、事実、現象として発生しました)。

したがって、上記のような状態が発生する環境下では、クライアントが都度問い合わせを行うのではなく、ある程度まとめて問い合わせを行うことでDNSへのアクセスを減らす必要があります。

## 対応

上記の二つの動機を満たすため、ElastiCacheのprimaryとreplicaサーバの状態を随時更新し、また、名前解決を行うlambdaを用意することにしたのです。

# Lambda

## 言語

今回はPython3系を使用しました (Python 3.6)。

## ロール

ElastiCacheの情報を読み込む必要がありますので、Lambdaには、AmazonElastiCacheReadOnlyAccess権限を含むロールを持たせる必要があります。 

## プログラム

```lambda_function.py
import boto3
import socket

# 対象となるElastiCacheのクラスター名
CLUSTER_NAME='your-redis-cluster-name'

def get_elasticache_info():
    # boto3のElastiCacheクライアントを取得
    cache_client = boto3.client('elasticache')

    # describeReplicationGroupsコマンドの発行
    info = cache_client.describe_replication_groups(ReplicationGroupId=CLUSTER_NAME)
    if 'ReplicationGroups' in info:
        if 'NodeGroups' in info['ReplicationGroups'][0]:
            # コマンドの結果を解析
            return parse_node_groups(info['ReplicationGroups'][0]['NodeGroups'][0])
    raise Exception('Unexpected AWS result')

def parse_node_groups(group):
    if 'NodeGroupMembers' not in group:
        raise Exception('No Node Group Members')

    primary_node_end_point = None
    replica_node_end_point = []

    # describeReplicationGroupsコマンド内のNodeGroupMembersを解析    
    for cluster in group['NodeGroupMembers']:
        if 'ReadEndpoint' not in cluster or 'CurrentRole' not in cluster:
            raise Exception('Unexpected node group member')

        # クラスターのendpointを取得し、名前解決を行う
        end_point = lookup(cluster['ReadEndpoint'])
        current_role = cluster['CurrentRole']

        # クラスターの種類(primary/replica)毎に情報を保存      
        if 'primary' == current_role:
            primary_node_end_point = end_point
        elif 'replica' == current_role:
            replica_node_end_point.append(end_point)
        else:
            raise Exception('Unknown role')

    if primary_node_end_point is None:
        raise Exception('No primary node')

    return [
        primary_node_end_point,
        replica_node_end_point
    ]

def lookup(endpoint):
    if 'Address' not in endpoint:
        raise Exception('No address in endpoint')
    address = endpoint['Address']

    # 名前解決
    return socket.gethostbyname(address)

def lambda_handler(event, context):
    servers = get_elasticache_info()
    
    return servers    
```

このlambdaを呼び出すと、[primaryサーバのIPアドレス, [replicaサーバのIPアドレス, ....]]の結果を返します。

## 利用方法

API Gatewayと結びつけて、定期的にプログラムから呼び出すとか、そんな感じで(雑)。

# TO-DO

* フェイルオーバーの途中に呼び出したらどうなるか調べる
* 名前解決のretryとかいる?
* 直接関係ないけど、cloudwatchでフェイルオーバーやreplicaサーバの死亡を検知する方法も調べとく
* 例外のエラーメッセージが適当(ごめんなさい)
いざWEB運用。と、その前に。〜コンセプトダイアグラム〜

こんにちは、先日御殿場ルートで富士山アタックしたところ片道10時間もかかってしまいました。
8合目からが鬼門。

#WEB運用がしたい
これまでは自社サイトの企画立案・制作進行・デザイン・公開後の管理(保守)、といったことを続けてきましたが、いろいろあってB2B向け自社プロダクトサイトの運用・育成に注力することに。

一番の目標は**CV率を上げる=リードを作り出す**こと、それはわかる。
そのためにはサービスサイトを解析して課題点(と思しき部分)を洗い出し、仮説を立ててブラッシュアップ・必要に応じてリニューアルしていく、のだろう。多分。
他にもやらなくてはならないこと（WEBのPDCAを設定？広告を打つ？カスタマージャーニーマップを整える？）もふんわり思いつく。
しかしなにぶん運用経験がほとんどないので、どこから手をつければいいのやら。

と、ここで上司
**「ストーリーから考えましょう。コンセプトダイアグラム。」**

なんですかそれは〜！

#コンセプトダイアグラム
>コンセプトダイアグラムは、
> **顧客の心理変容と企業の施策を図解し、顧客の理解と施策の評価を行うフレームワーク**
>由来：元々はサイト設計の手法

参照元：[コンセプトダイアグラムとは - 清水誠メモ](https://makoto-shimizu.com/news/what-is-concept-diagram/) 

カスタマージャーニーマップと似ていますが、目的や描き方が少し違います。
簡単な流れは下記の通り。

1. ユーザーに望む「取ってほしい行動」と「気持ちの変化」をステップで図解する。
2. １で出した、行動や気持ちの変化を誘発するために伝えるべきことを各ステップごとに洗い出す。
3. 伝えるべき情報を掲載するコンテンツをそれぞれ割り当てる（概要ページなのか、機能説明なのかetc)

このように1で図解したものに、必要なコンテンツをマッピングしたものがコンセプトダイアグラム。

**詳しくはこちらの本をお買い求めください。わかりやすいです。**
[コンセプトダイアグラムでわかる [清水式]ビジュアルWeb解析](https://honto.jp/netstore/pd-book_26683149.html)

#結果
コンセプトダイアグラムを整理した結果、足りないコンテンツや不要なコンテンツが多かったため、今回はリニューアル。

他にも、「B2Cと違い、根気強くユーザーを育成しないとCVに繋がらない？」「そもそも課題を課題だと気付いていない？」「気付きを与えるためにどうしてもこのページに行ってほしい」などいろいろ課題を洗い出せたのが良かった点。

次回はGoogleアナリティクスとGoogleデータスタジオを用いて運用のための土台を作ります。
ほしいデータを集めたウィークリーレポートを作りたい。。

ちなみにアナリティクスの知識がほとんどないので、次も初心者向け。
データスタジオの存在も昨日知りました。（とても便利）

それではまた
AWSのEC2でインスタンスを作成する手順

# はじめに
AWSにインスタンスを作成する方法がよく分からない :disappointed:
⇒ とりまインスタンス作成しながらQiitaにまとめて見よう
<font color="Gainsboro">(これも一つのアイカツ)　</font>

# AWS EC2にインスタンス作ります
## Step.1 AWSにログイン
* <a href="https://console.aws.amazon.com/">AWS マネジメントコンソール</a>にてログイン

## Step.2 EC2のインスタンスを作成する
* <a href="https://us-east-2.console.aws.amazon.com/ec2/v2/home">Amazon EC2 ダッシュボード</a>に移動
![opera_2018-08-24_16-42-11.png](https://qiita-image-store.s3.amazonaws.com/0/278017/4cdd19f8-56c3-b4d8-8efc-7dd86cb996a5.png)

* 右上の「サポート」の左をクリックしてリージョンを選択する（画面では「オハイオ」）
![e18137af-4d51-423a-be75-cfad0f98a393.png](https://qiita-image-store.s3.amazonaws.com/0/278017/48de63f3-6776-121a-29d0-12f18f271dfa.png)

* 画面中央の「インスタンスの作成」を選択する

## Step.3 インスタンスを設定する
* 1.AMIの選択 - ソフトウェア構成を選択する画面（今回は「Amazon Linux AMI」を採用）
![opera_2018-08-24_16-58-51.png](https://qiita-image-store.s3.amazonaws.com/0/278017/956555f3-bfa1-b03a-86af-0bfd7b22398f.png)

* 2.インスタンスタイプの選択 - 仮想サーバーのスペックを選択する画面（今回は「t2.micro」を採用）
![opera_2018-08-24_16-59-44.png](https://qiita-image-store.s3.amazonaws.com/0/278017/dd0aeaf9-744e-a0d3-0cb2-6268567de1fa.png)

「確認と作成」を押すと一気に 7. まで飛ばされます、ストレージを増やしたい、外部に公開しない等の変更を行う場合は上の番号部分、又は右下の「戻る」から戻れますので、各自設定をしてください、その後 7. へ進んでください。（今回はとりあえず何も設定しない手順で進めます）

* 7.確認 - 作成するかの確認画面
![opera_2018-08-24_17-05-57.png](https://qiita-image-store.s3.amazonaws.com/0/278017/424d75e0-b5d4-96d5-0c51-9840cfd2f50f.png)
 * キーペアの作成をするか問われる画面が出てきます
 * 今回は「新しいキーペアの作成」を行います（既存のが有り、それを使用したい場合は「既存のキーペア選択」から使いたいキーペアを選択してください）
 * キーペア名を入力し、「キーペアのダウンロード」から.pemファイルのダウンロードを行います（注意書きにも書いてますが、再度ダウンロードは不可なので大切に！）
![opera_2018-08-24_17-23-12.png](https://qiita-image-store.s3.amazonaws.com/0/278017/f060ecd7-f5ee-2fa9-a679-488668e9ed13.png)

* インスタンスの作成を押したら、画面が切り替わりインスタンス作成中の画面に遷移します（数分かかります）
![opera_2018-08-24_17-25-13.png](https://qiita-image-store.s3.amazonaws.com/0/278017/d0af3cda-7c76-95e1-0e32-bf5df294cf7c.png)

* <a href="https://us-east-2.console.aws.amazon.com/ec2/v2/home">Amazon EC2 ダッシュボード</a>に戻り左側の、インスタンスのインスタンスから、作成したインスタンスを確認します
![opera_2018-08-24_17-52-34.png](https://qiita-image-store.s3.amazonaws.com/0/278017/a784ff8f-2c8c-c1e7-8243-3b541942073b.png)

* ここにある「IPv4 パブリック IP」がインスタンスのIPです（画像では隠しています）

## Step.4 インスタンスへの接続
* PuTTy,Tera Term,Xshell等クライアントソフトを使い、先ほどのIPに接続します
* 接続する際に、キーペアの設定をした方はダウンロードした「.pem」ファイル（この記事上では「example.pem」を認証に使用して接続をします）

```
IP : インスタンスの「IPv4 パブリック IP」
PORT : 22
```

# まとめ
本当に初歩的な事しか書いてませんが、分からない人は分からない（自分含め）ので画像を多めに貼って簡単？にまとめてみました。

この部分がよく分からない等があれば、編集を行いますので気軽にコメント宜しくお願いします。
### 以下を参考
* <a href="https://aws.amazon.com/jp/ec2/getting-started/">Amazon EC2 のご利用開始にあたって</a>
Kobito for mac の配信もサポートもとっくに終わってた...


- 別のマシンにKobitoを入れようとしたところ...

![kobito.png](https://qiita-image-store.s3.amazonaws.com/0/51116/92df6b5b-4ccf-64ff-b110-edfcdb7f2216.png "kobito.png")

あらま


理由が書いてありました。

- [Kobito for Mac / Windowsの提供及びユーザーサポートを終了します](https://blog.qiita.com/post/168180042619/kobito-for-mac-windowsの提供及びユーザーサポートを終了します)


この記事はKobito for macで書きましたw
Mac で Julia #6 Modules

前回に引き続きJuliaについてです。

[ドキュメント](https://docs.julialang.org/)に沿って試していきます。
...脱線気味です、今回はモジュールについて


## Summary of module usage

```julia
module MyModule

export x, y

x() = "x"
y() = "y"
p() = "p"

end
```

usingやimportの呼び出し方によってスコープに導入されるもの（What is brought into scope）とメソッドの拡張に利用可能なもの（Available for method extension）が変わるそうです。

MyModule.jlとして保存しました。

### あれ？モジュールが読み込めない...

```julia
julia> using MyModule
ERROR: ArgumentError: Package MyModule not found in current path:
- Run `Pkg.add("MyModule")` to install the MyModule package.

Stacktrace:
 [1] require(::Module, ::Symbol) at ./loading.jl:817

julia>
```

怒られちゃいました。モジュールのパス(perlでいうところのuse lib的な）の指定が必要だそうです。

### Module file paths

`push!`コマンドを使うそうです。

```julia
julia> push!(LOAD_PATH,"/PATH/TO/MOD_DIR")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "/PATH/TO/MOD_DIR"

julia> using MyModule

julia> MyModule.x()
"x"
```

できましたー。追加する```push!```関数に！マークが付いているのはLOAD_PATHを更新するからですね。

今日はこの辺で。
CarrierWaveの使い方

```:Gemfile
gem 'carrierwave'
```

```
$ bundle install
```

# uploaderを作成

```
$ rails g uploader image
```

app/uploaders/image_uploader.rbが作成される

```ruby:image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  # リサイズしたり画像形式を変更するのに必要
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url(*args)
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process scale: [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  # version :thumb do
  #   process resize_to_fit: [50, 50]
  # end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  # アップロードできる拡張子を制限
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  def filename
    "something.jpg" if original_filename
  end
end
```

画像用のカラムを追加
※今回はuserモデルに追加を想定

```
$ rails g migration add_image_to_user image:string
```

モデルに追加

```ruby:user.rb
class User < ApplicationRecord
	mount_uploader :image, ImageUploader
end
```

permitにimageを追加

```ruby:controller.rb
:image
```

入力側

```ruby:edit.rb
    <%= f.label :顔画像 %>
    <%= f.file_field :image %>
```

表示側

```ruby:show.rb
<img src="<%= @user.image %>" width="100">
```
【Java】初心者が文字列比較で失敗する等価比較。間違いに気づいていない可能性も！？

二つの文字列が等価かどうか判定しようとした時などに、直感的には`==`を使いたくなってしまうと思います。ですが、Javaでは文字列の比較の際に`==`ではなく`equalsメソッド`を使わないといけません。この理由を理解するためには、Javaでは**文字列はオブジェクト型(参照型)であるということと、Stringの特徴を理解していく必要があると思います。**

## オブジェクト型（参照型）の変数

オブジェクト型の場合、通常はオブジェクトの設計図であるクラスから`new演算子`を使用して必要なメモリ領域を確保してインスタンス生成を行います。そしてJavaの場合、オブジェクト型は**参照渡し（ポインタ渡し）** となります。つまり変数には値ではなく実際の値が格納されているメモリのアドレス値を格納しているということになります。ちなみに、intやbooleanなどはプリミティブ型といって、こちらの変数は値自体を保持しています。

### Stringオブジェクトの生成

```java
String str = "hoge";
```
通常はオブジェクト型の場合、`new演算子`を使ってオブジェクトの生成を行うのですが、Stringの場合は`new演算子`を使わずに生成できる便利な仕組みが用意されているので`= ""`だけで生成することができます。また、`= ""`で生成することで後述するString Constant Poolという仕組みの恩恵を受けることができます。

## String Constant Pool（文字列の再利用のための仕組み）

String Constant Poolとは、新しくStringオブジェクトを生成する際にメモリの節約をするための仕組みです。String定数プールという特別なメモリ領域に値が保持され、新たに文字列の生成が行われる際に、同じ内容のStringオブジェクトがないかプールをチェックして、あった場合は参照を再利用してくれます。この仕組みを利用するには`new演算子`を使わずに`= ""`でStringオブジェクトの生成をします。(`new演算子`を使った場合も明示的に利用する方法がありますが割愛させて頂きます)

```java:StringConstantPoolを利用した場合
// 1回目なので、通常通りメモリ領域が確保され生成される
String str = "hoge";
// すでに同じ値がString定数プールに存在するので、既存の参照先(アドレス値)と結びつける
String str_2 = "hoge";
```

```java:StringConstantPoolを利用しない場合
// 通常通りメモリ領域が確保され生成される
String str = new String("hoge");
// String Constant Poolが利用されないので、通常通りメモリ領域が確保され生成される
String str_2 = new String("hoge");
```
ちなみに、Stringが不変である理由はこの仕組みにあります。複数の同じ文字列が同じ参照をしている時に、どれかを変更してしまうと他の全てにも影響が出てしまうので変更不可となっているようです。

## ==でイケると勘違いしてしまうことがある

```java:==でイケてしまうケース
String str = "hoge";
String str_2 = "hoge";
//このif文の条件はtrueですが、それは値が同じだからではなく参照先(アドレス値)が同じだからです。
if(str == str_2){
    System.out.println("値は同じです");
}else{
    System.out.println("値は違います");
}
```
上記コードのif文の条件がtrueとなるので、値の比較ができているように錯覚してしまうかもしれませんが、これは参照先(アドレス値)の比較をして、String Constant Poolの再利用によって参照先(アドレス値)が同じだったためtrueとなるのです。なので、下記のような場合には成立しません。

```java:==でダメなケース
String str = "hoge";
String str_2 = new String("hoge");
//この場合は参照の再利用はされず、strとstr_2の参照先(アドレス値)は異なるため条件はfalseになります。
if(str == str_2){
    System.out.println("値は同じです");
}else{
    System.out.println("値は違います");
}
```

## きちんと値の比較をする方法
値自体を比較するためには、冒頭で書いた通り`equalsメソッド`を使うようにしましょう。

```java
String str = "hoge";
String str_2 = new String("hoge");
//equalsメソッドを使うことで、値自体の比較ができます。
if(str.equals(str_2)){
    System.out.println("値は同じです");
}else{
    System.out.println("値は違います");
}
```

## まとめ

Javaの場合の文字列比較をきちんとするための方法を紹介させて頂きました。ポイントは、String型はオブジェクト型であるということと、オブジェクト型は値ではなく参照先(アドレス値)を保持しているということだと思います。この二つさえ理解できれば`equalsメソッド`を使う理由が理解できると思います。ちなみに、比較的新しい言語のSwiftやKotlinでは`==`で値の比較ができるようですね。

## 参考

- [Stringとheap領域とconstant pool - Qiita](https://qiita.com/liguofeng29/items/16d6dbec471bc5269f0e)
- [【Java】参照型とは？をきちんと理解する - Qiita](https://qiita.com/shunsuke227ono/items/07c08cf5640564f7739c)
- [【Java】なぜ文字列リテラルは演算子で比較できる時があるのか - shogonir blog](http://blog.shogonir.jp/entry/2018/01/29/022046)
非情報系でもわかったほうが良いGit

# はじめに
私は情報系まがいのことをしているが基本的には非情報系である[^1]．
[^1]: そろそろ電気系を名乗るのも無理が出てきたと言わざるを得ない．
しかしながら，コードを書き，データを扱って暮らしているため，バージョン管理とか言うヤツとは常に戦ってきた．
これまでは

- １つのファイルをどんどん書き足し（書き換え）ながら開発する
- 大規模な変更を入れる場合はディレクトリごとコピーして名前を変え，書き直す

とくにこの2番目がクソと言わざるを得ないだろう．
デスクトップには同じような名前のフォルダが並んでおり，それらはファイル名末尾の日付と，私の記憶でしか判別できないのだ．
あとバックアップが取れていないので，ワークステーションが学会前にお亡くなりになったときはマジで死ぬかと思った．

Twitterでそんなことをつぶやいたらgitをつかいなさーい！と言われたので，gitを使ってみたのである．
その時の記録と，基本的な使い方くらいをまとめておこうと思う[^2]．
[^2]: ぶっちゃけ使い方とかはググればいくらでも出てくる．

# 準備
まずgitというのはバージョン管理するソフトウェアの名称（？）で，GitHubというのはバージョン管理する場所を貸してくれるサービスであるらしいことがわかった．

研究内容をオンラインの公開リポジトリに置いておくわけにはいかないので，privateリポジトリを作れるようにGitHubのアカウントをeducationにした．
[ここ](https://education.github.com/)から「Join education」を押してメールアドレスで認証した．

その他の作業は，基本的にこのサイトに書いてあるとおりにやった．
[今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説 - エンジニアHub｜若手Webエンジニアのキャリアを考える！](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)
相違点は，GitHubのアカウントを取得するところをすっとばして，リポジトリの作成をprivateにしたことくらい．
また，sshは通ったがgit cloneができなかったのでググったところ，ssh-agentとかいうのを設定しなきゃいけなかった．
参考：[Githubに接続できない時の対処法](https://qiita.com/nyanchu/items/32d65c4c36315b876d38)

追記：SSH agentくんは再起動のたびにパスフレーズを忘れてしまうらしい．
[ssh agentをパスフレーズ省略に応用する方法まとめ](https://qiita.com/onokatio/items/397a5899a0ec16c7e60a)

#　基本操作
gitは，以下の手順で操作する（と，私は思っている）．

1. 手元でファイルを作成・編集する
2. どのファイルを変更履歴に反映するかを選ぶ（add）
3. ローカルの変更履歴に反映する（commit）
4. ローカルの変更履歴をGitHub上のリポジトリに反映する（push）

1人で使ってるぶんには「ぷる」とかいうのはなさそうなのでよく知らない．

参考：Qiitaではこの記事がかなり良さそう→[【Git】基本コマンド](https://qiita.com/konweb/items/621722f67fdd8f86a017)


## git add
特定のファイルだけ変更履歴に反映するときは

```bash:
git add [ファイル名]
```

全部やるときは

```bash:
git add *
```

## git commit

```bash:
git commit -a -m "コメント"
```

コメントはあとから履歴を見たときに表示されるっぽいからなんとなくでも書いといたほうが良さそうにゃもね．

## git push

```bash:
git push [リモートリポジトリ名] [ローカルのbranch名]:[リモートのbranch名]
```

この記事のようにリモートリポジトリからcloneして作ったローカルリポジトリの場合，リモートリポジトリ名をoriginとしてよいらしい．
あとローカルとリモートでbranch名が同じ場合は入力は１回でよく，現在のbranchをpushする場合はまるごと省略も可能っぽい，よって

```bash:
git push
```
でもできてしまうにゃもね．

#　おしまい
これで，手元で作成したファイルの変更履歴をGitHub上に反映することができた．
今の所，ログを確認したり巻き戻したりという必要に迫られていないのでそのような操作は知らないが，必要になったらまたググるし，必要だと思ったらここに書くと思う．

参入障壁はそれなりに感じたけど，やはりファイルはスッキリ管理したいので，今後はgitを使っていきたいと思います．
Ubuntu 18.04 の Nautilus の右クリックメニューから「新しいフォルダーを作成する」や「ファイルの変名」が消えてむかついたので対処方法をメモする

# はじめに

@GORO_Neko です。
ご存知の方ご無沙汰してます。初めての方お初にお目にかかります。

まずお断りをば一言。

以下は、自分が所属する会社の意向を反映したものでもスタンスを示すものでもなく、単なる一個人の趣味の活動から産まれた記述です。

…てか、今回のこの記事、単なる技術的（？）調べ事のメモだったり。

# Nautilus の右クリックメニューから「新しいフォルダーを作成する」や「名前を変更する」が消えたぁ？

先日、個人的に使っていた Ubuntu のバージョンが古くなってきたので、18.04 LTS 版に入れ替えました。

で、GUI 操作で前の環境でも使っていた情報整理用のフォルダを適当な場所に作ろうと、Nautilus 上で右クリックをしてみたところ…

ない！　右クリックメニューの選択肢に「新しいフォルダーを作成する」がない！

ショボショボとネットをあちこち調べてみたんですが（情報のオリジナル度ほぼゼロ（苦笑））、自分的がっかり情報しか見つかりませんでした。

ショートカットを使うやり方に置き換わってしまったようです。

今後は以下のショートカットを使うしかない模様。

| ショートカット | 機能 |
|:----------- | :----------- | 
| Ctrl + Shift + N | 新しいフォルダーを作成する |
| F2 | 名前を変更する |

しょーとかっと、あらたに、おぼえるのかぁ…

では、また。
PyTorch で tensor をある軸に従って flip する方法

##目的
seq2seqなどのrnnモデルで学習する時、答えのシーケンスを逆転する必要があります。普通のnumpyでやればa[::-1]でできるが、pytorch がマイナスインデクシングをまだ実装してないのでやり方をまとめます。

##numpyの場合
```python
>>> import numpy as np
>>> a=np.random.rand(2,3,4)
>>> a
array([[[0.77035401, 0.24779618, 0.76642706, 0.05111546],
        [0.93068699, 0.63876274, 0.37042163, 0.09062927],
        [0.91439172, 0.91490527, 0.82236844, 0.74023026]],

       [[0.0294182 , 0.15135825, 0.22691598, 0.64636446],
        [0.58836392, 0.97549164, 0.39324753, 0.66243478],
        [0.38082428, 0.20068817, 0.42776323, 0.49329102]]])
>>> a[:,:,::-1]
array([[[0.05111546, 0.76642706, 0.24779618, 0.77035401],
        [0.09062927, 0.37042163, 0.63876274, 0.93068699],
        [0.74023026, 0.82236844, 0.91490527, 0.91439172]],

       [[0.64636446, 0.22691598, 0.15135825, 0.0294182 ],
        [0.66243478, 0.39324753, 0.97549164, 0.58836392],
        [0.49329102, 0.42776323, 0.20068817, 0.38082428]]])
```
## pytorch の場合

torch.arange(3,-1,-1) を使うことで、インデックスの逆転を通じてテンサーの軸を逆転します。

```python
>>> a = torch.rand(2,3,4)
>>> a
tensor([[[0.7077, 0.0939, 0.3385, 0.8469],
         [0.1563, 0.1077, 0.5764, 0.2502],
         [0.3548, 0.1774, 0.8615, 0.1192]],

        [[0.0571, 0.6192, 0.9620, 0.3761],
         [0.3884, 0.6482, 0.3567, 0.4959],
         [0.6242, 0.9567, 0.0100, 0.9072]]])
>>> a[:,:,torch.arange(3,-1,-1)]
tensor([[[0.8469, 0.3385, 0.0939, 0.7077],
         [0.2502, 0.5764, 0.1077, 0.1563],
         [0.1192, 0.8615, 0.1774, 0.3548]],

        [[0.3761, 0.9620, 0.6192, 0.0571],
         [0.4959, 0.3567, 0.6482, 0.3884],
         [0.9072, 0.0100, 0.9567, 0.6242]]])
```
【Unity】～SIerからゲーム業界へ～ 第4-2回 敵

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/0cf7c70c-0c12-db20-9c52-f1374f256eae.png)

####基本機能

・プレイヤーを追尾してくる
・一定距離内に入った場合のみ追尾とする
・プレイヤーの攻撃を受けたら消滅

####学んだ点

プレイヤー追尾のためにNavMeshAgentを使用した

```Ememy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Enemy : BaseBehaviour {

    public GameObject target;
    NavMeshAgent agent;
    private Vector3 pPos;
    private Vector3 ePos;

    // Use this for initialization
    void Start () {
        agent = GetComponent<NavMeshAgent>();
        agent.speed = 0;
	}
	
	// Update is called once per frame
	void Update () {

        // プレイヤーとの距離を算出
        pPos = target.transform.position;
        ePos = transform.position;
        var dist = Vector3.Distance(pPos, ePos);

        // 一定距離に近づいたら動き出す
        if (dist < 10)
        {
            agent.speed = 2;
        }

        // 敵オブジェクトの目的地を指定
        agent.destination = pPos;

    }

    private void OnTriggerEnter(Collider col)
    {
        if (col.gameObject.tag == "Fire")
        {
            Destroy(this.gameObject);
        }
    }
}

```
[Docker][初心者][メモ] 初心者がDockerをやってみたらめちゃくちゃわかりやすかったww

## はじめに
**[対象読者]**
**Dockerをやって見たいけどよくわからないという人**


今回は、Dockerの勉強をしてみました。　
以前、理論から入って挫折したんですが手を動かしてみたらめちゃくちゃわかりやすかったですww
Dockerやりたいけどわからない人はとりあえずやってみることをおすすめします。

内容的にはまだまだ途中なので随時更新していきます。

この記事は以下の記事をやりながら自分なりに勉強になった点をまとめて見た記事です。
めちゃくちゃわかりやすいのでぜひやって見てください！
macだとコマンドがちょっと違うので引っかかるかもしれませんが質問していただければわかる範囲で答えます！
[Docker入門　（第一回）　～Dockerとは何か、何が良いのか～](https://knowledge.sakura.ad.jp/13265/)

[Docker入門（第二回）～Dockerセットアップ、コンテナ起動～](https://knowledge.sakura.ad.jp/13795/)

[Docker入門（第三回）～各種dockerコマンドとDockerイメージ作成について～](https://knowledge.sakura.ad.jp/14427/)

[Docker入門（第四回）～Dockerfileについて～
](https://knowledge.sakura.ad.jp/15253/)

[Docker入門（第四回）～コンテナ間通信～
](https://knowledge.sakura.ad.jp/16082/)

[Docker入門（第四回）～Docker Compose～
](https://knowledge.sakura.ad.jp/16862/)


## Docker
#### Dockerイメージの取得、Dockerイメージ一覧

```
docker pull <Dockerイメージ名>
docker images
```

#### コンテナ起動、コンテナ一覧確認

```
# docker run -it -d -p <ホスト側ポート>:<コンテナ側ポート> -v <ホスト側ディレクトリ>:<コンテナ側ディレクトリ> --name <コンテナ名> <Dockerイメージ名>
# docker ps -a
```

#### コンテナへのログイン

```
docker exec -it <コンテナ名> bash
```

#### ファイルコピー

```
(ホスト→コンテナ内)
docker cp <ホスト側のファイル> <コンテナ名>:<コンテナ内のコピー先ディレクトリ>

(コンテナ内→ホスト)
docker cp <コンテナ名>:<コンテナ内のコピー元ファイル> <ホスト側のコピー先ディレクトリ>
```

#### コンテナからDockerイメージ作成

```
docker commit <コンテナ名> <作成するDockerイメージ名>
```

#### コンテナ起動と停止

```
docker start <コンテナ名>
docker stop <コンテナ名>
```

#### コンテナ削除

```
docker rm (-f) <コンテナ名>
※「-f」オプションを付けると、コンテナ起動中でも強制的に削除します。
```

## Dockerfile

* FROM
ベースとするDockerイメージを指定

* RUN   
OSのコマンドを実行する際に使用する

* ADD  
tar.gzファイルのコンテナへのコピーと、tarの展開を行います

* CMD  
コンテナ起動時に実行するコマンドを記述


## Dockerfileを書く際の注意点
- Dockerfileの各コマンドは、毎回コンテナを起動して実行している
- キャッシュを意識する(実行済みのコマンドはキャッシュが使用される)
- Dockerfileはコマンドごとにレイヤーが作成されるのでコマンドはまとめて実行する

## コンテナ間通信
コンテナ間の通信には二つある
①Dockerネットワークを作成してコンテナ名で接続できるようにする
②「--link」オプションを使用する(レガシーらしい）

## Dockerネットワーク



#### ネットワーク詳細を確認する

```
docker network inspect <ネットワーク名>
```

### ネットワーク一覧を確認

```
docker network ls
```

### ネットワークを指定してコンテナを起動する

```
docker run --name mysql --network wordpress-network -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7
```
## 最後に
最後まで読んでいただきありがとうございます！
編集リクエストなどあればどんどんお願いします！
他の初学者の学習の助けになる情報などもあればコメントでいただければ嬉しいです！
【Unity】～SIerからゲーム業界へ～ 第4-1回 プレイヤー

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/0cf7c70c-0c12-db20-9c52-f1374f256eae.png)

####基本機能
・キーボードでの操作
・[スペース]でジャンプ
・[F]で遠距離攻撃（fire)
・敵に衝突した場合に音を出す

####学んだ点
・プレイヤー、敵の判定を Tag を使って判定
参考にしたサイトがそうしてたけどもっと良いやり方あるのでは…

・当たり判定
参考にしたサイトではOnTriggerEnterを使用していたが、範囲内に入った時に一度しか流れない
OnTriggerStay へ変更することで継続ダメージが入るようにした
ただし判定が多すぎるのため、無敵レイヤーを用意しコルーチンでレイヤーを切り替えて一定間隔で当たり判定を行われるように修正
（ただ、複数の敵が一気に襲ってくるとおかしい、要修正 TODO）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/ff56550b-2f04-9c58-302f-ca3afd694dbe.png)

```Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : BaseBehaviour
{

    public Vector3 vector;
    public CharacterController chara;
    public GameObject preFire;
    public AudioClip soundFire;
    public AudioClip soundEnemy;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        // キーボードでの移動
        vector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * Time.deltaTime * 5;

        // 正面を向く処理
        var forward = Vector3.Slerp(transform.forward, vector, 360 * Time.deltaTime / Vector3.Angle(transform.forward, vector));
        transform.LookAt(transform.position + forward);

        // スペース：ジャンプ
        if (Input.GetKeyDown(KeyCode.Space))
        {
            vector.y = 3;
        }
        // F:攻撃
        else if (Input.GetKeyDown(KeyCode.F))
        {
            Fire();
        }

        // ジャンプの場合のために重力分下げる
        vector.y -= 9.8f * Time.deltaTime;

        chara.Move(vector);
    }

    /// <summary>
    /// 攻撃
    /// </summary>
    void Fire()
    {
        var posFire = new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y + 0.5f, this.gameObject.transform.position.z);
        Instantiate(preFire, posFire, transform.rotation);
        AudioSource.PlayClipAtPoint(soundFire, transform.position);
    }

    //void OnTriggerEnter(Collider col)
    void OnTriggerStay(Collider col)
    {
        if (col.gameObject.tag == "Enemy")
        {
            StartCoroutine("Damage");
        }
    }

    /// <summary>
    /// ダメージ処理
    /// </summary>
    /// <returns></returns>
    private IEnumerator Damage()
    {
        // 無敵用のレイヤーに変更
        // 当たり判定を一定間隔で行わせたいため
        gameObject.layer = LayerMask.NameToLayer("PlayerDamage");

        // 判定用に音をならす
        AudioSource.PlayClipAtPoint(soundEnemy, transform.position);

        yield return new WaitForSeconds(0.5f);

        // 元のレイヤーに戻す
        gameObject.layer = LayerMask.NameToLayer("Player");
    }
}

```