OmniAICreator/Qiita-1.07M huggingface dataset:
tensorflowで同じコードなのに結果が異なる。再現性のある機械学習がしたい。

##結果が異なる理由
１．理由は乱数を使っているから。
計算の度に乱数が異なるため結果が異なる。
２．GPUを使っているから。
GPU内部での演算順序が非決定的であるためGPU演算の結果は安定しない。
##１解決策
下記のコードでnumpyとtensorflowの乱数を固定する。


```python
import numpy as np
import tensorflow as tf
import random as rn

# The below is necessary in Python 3.2.3 onwards to
# have reproducible behavior for certain hash-based operations.
# See these references for further details:
# https://docs.python.org/3.4/using/cmdline.html#envvar-PYTHONHASHSEED
# https://github.com/keras-team/keras/issues/2280#issuecomment-306959926

import os
os.environ['PYTHONHASHSEED'] = '0'

# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.

np.random.seed(42)

# The below is necessary for starting core Python generated random numbers
# in a well-defined state.

rn.seed(12345)

# Force TensorFlow to use single thread.
# Multiple threads are a potential source of
# non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/which-seeds-have-to-be-set-where-to-realize-100-reproducibility-of-training-res

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)

from keras import backend as K

# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see: https://www.tensorflow.org/api_docs/python/tf/set_random_seed

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

# Rest of code follows ...
```
参考
https://keras.io/ja/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development

##２解決策
なし

参考
https://qiita.com/TokyoMickey/items/63c4053740ab1f3f28a2
コマンド一発でMacのターミナルで生成したUUIDをクリップボードに転送する

# これは何？
MacのターミナルでUUIDを生成するよ。
何度もuuidgenして、ターミナル上に表示されたUUIDをマウスで選択してコピーがめんどくさい人向け。

# やりかた
下のコマンドを実行

```
$ uuidgen | tr -d '\n' | pbcopy
```

# 簡単な解説
1. uuidgenはUUIDを生成して標準出力に出力。この時改行が最後に含まれている。
2. uuidgenの標準出力をパイプ(|)を使ってtrコマンドに転送。
3. trコマンでuuidgenから転送されてきた出力内容から改行コードである「\n」を削除する。
4. trコマンドで改行コードを削除したUUIDをpbcopyコマンドへ転送してクリップボードへ。

# 注意点
改行コードが\nじゃない環境にしている人は、削除する改行コードを適宜変更してください。

以上です
Swift学習ページまとめ

色々調べながら出会った、Swift初心者の学習に役立つサイトをまとめました。
随時更新していきます。
他にもおすすめサイトがありましたら教えてください。

## Swift
- [Swift言語を学ぶ](https://tea-leaves.jp/swift/)
 辞書的に使えるページ。
超初歩から解説されているので、初心者でもとても勉強になります。

- [Documentation(公式)](https://swift.org/documentation/#the-swift-programming-language)
全て英語ですが、Swiftのプログラミングに必要なことは全て網羅されている（はず）

- [日本語ドキュメント（公式）](https://developer.apple.com/jp/documentation/)

- [Swiftとイニシャライザ](https://qiita.com/shtnkgm/items/8b7979fc84a3cc065238)
イニシャライザについて大変わかりやすくまとめられており、本を読んでもなかなか理解できなかったのですが、こちらのQiitaを読んでかなり理解できました。@shtnkgmさんありがとうございます！

## UIKit
- [公式ドキュメント](https://developer.apple.com/documentation/uikit)
- [逆引きSwift](http://docs.fabo.io/swift/)

## 参考
https://qiita.com/wataoka/items/0f38208750cc676f4377
【CSS】メモ


##dev要素をmarginを使って中央配置にする

containerというidを持つdiv要素を画面中央に置きたい場合、次の通りしていする。
`margin:0 auto;`で上下が0、左右がオート算出で中央に置かれる。

```css
#container {
      width: 960px;
      height: auto;
      margin: 0 auto;
    }
```

##カーソルがリンクに当たった時浮かび上がらせる

```css
    a:hover{
      text-decoration: none;
      color: #c7c7c7;
    }
```

```html
<li><a href="#">NEWS</a></li>
<li><a href="#">PROFILE</a></li>
<li><a href="#">DISCOGRAPHY</a></li>
<li><a href="#">MEDIA/LIVE</a></li>
<li><a href="#">CONTACT</a></li>
```
`sudo xcode-select -s` の度にパスワードを打つのが面倒な人へ

`xcode-select` の実行時のみ `sudo` のパスワード入力をスキップできるように `visudo` で1行付け加えるだけ

```sh:visudo
# root and users in group wheel can run anything on any machine as any user
root            ALL = (ALL) ALL
%admin          ALL = (ALL) ALL

{input-your-user-name}           ALL = NOPASSWD: /usr/bin/xcode-select # この1行を追加

```

# 注意
特にいじっていない初期状態のファイルであれば、
`# User specification`というブロックがあるが、ここではなくその下の
`# root and users ~`のブロックの一番下に書くこと。
(`# root and users ~`直下の設定で上書きされるっぽい？)

# 参考
[sudo のパスワードを入力なしで使うには](https://qiita.com/RyodoTanaka/items/e9b15d579d17651650b7)
[MacOSで「sudo」コマンドをパスワードなしにする方法](https://ex1.m-yabe.com/archives/2721)
[Java EE] MVCとは？簡単にまとめてみた

#MVCとは
次の３つの頭字語。

- Model
- View
- Controller

GUIのデザインパターンであり、サーブレットクラスやJSPファイルの使い分け基準になる。

### Model
『処理』, 『データの保存』
Javaのクラスを使う。

### View
『ユーザに対する画面表示』
JSPを使う。

### Controller
『リクエストをモデルに送り、結果をビューで表示させる。』
サーブレットを使う。
WindowsにPython2.7とPython3.8が共存できるようにChocolateyでインストールする

# はじめに

新しいPCを購入し、Python2.7とPython3.8（2019/10/25時点の最新版）をインストールすることになりました。

最近、WindowsのアプリはChocolateyでインストールするようにしているので、その方法を調べてみました。

Chocolateyではなく、インストーラーを使ってGUIでインストールしたい場合は、こちらをご覧ください。
[WindowsにPython2.7とPython3.7が共存できるようにインストールする](https://qiita.com/segur/items/23f276320216c3aa7cf7)



# Chocolateyをインストールする。
Chocolateyがインストールされていない場合は、インストールしましょう。

以下の記事がとてもわかりやすいです。
[Windows向けのパッケージ管理ソフト「chocolatey」が便利 / chocolateyのインストール](https://qiita.com/tomokin966/items/7c7f444d74a5cb7ef596#chocolatey%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

認証プロキシ配下の場合は、以下の記事がとてもわかりやすいです。
[認証プロキシ環境下でのchocolateyインストール](https://qiita.com/geotrader/items/33b5db1832bb42979ba9)



# Python2.7 をインストールする。

管理者権限でコマンドプロンプトを起動し、以下のコマンドを実行します。

```bash
choco install -y python2
```

これで `C:\Python27` に Python 2.7 や pip2 等がインストールされます。
このパスは、環境変数 `PATH` に自動で追加されるようです。



# Python3.8 をインストールする。

管理者権限でコマンドプロンプトを起動し、以下のコマンドを実行します。

```bash
choco install -y python
```

これで `C:\Python38` に Python 3.8 や pip がインストールされます。
やはり、このパスも、環境変数 `PATH` に自動で追加されるようです。



# Pythonの切換確認
2.7系と3系の切り替えができるか確認します。コマンドプロンプトを起動し、以下のコマンドを打ちます。

```bash
rem Python 3系が起動することを確認
py

rem Python を終了
exit()

rem Python 2.7系が起動することを確認
py -2

rem Python を終了
exit()
```

Pythonの2.7系と3系が共存していることが確認できました。



# pipの確認

pipがインストールされているか確認します。pipというのは、Pythonのパッケージ管理ソフトです。外部パッケージのインストール等で利用します。

コマンドプロンプトで以下を実行してみてください。

```bash
rem Python 3系が起動することを確認
pip --version

rem Python 2.7系が起動することを確認
pip2 --version

rem Python 3系が起動することを確認
pip3 --version
```

これで応答にバージョン番号が表示されれば、pipは正常にインストールできています。
次に、コマンドプロンプトで `pip list` を実行してみてください。

```bash
Package    Version
---------- -------
pip        19.2.3
setuptools 41.2.0
WARNING: You are using pip version 19.2.3, however version 19.3.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
```

警告文が表示されています。どうやらpipのバージョンが古いので、バージョンアップを勧められているようです。表示されているコマンドを実行してみます。

```bash
python -m pip install --upgrade pip
```

新しいpipのインストールが始まります。

```bash
Collecting pip
  Downloading https://files.pythonhosted.org/packages/00/b6/9cfa56b4081ad13874b0c6f96af8ce16cfbc1cb06bedf8e9164ce5551ec1/pip-19.3.1-py2.py3-none-any.whl (1.4MB)
     |████████████████████████████████| 1.4MB 2.2MB/s
Installing collected packages: pip
  Found existing installation: pip 19.2.3
    Uninstalling pip-19.2.3:
      Successfully uninstalled pip-19.2.3
Successfully installed pip-19.3.1
```

こんな風になればインストール終了です。 `pip list` を実行しても、警告が表示されなくなりました。



# pip設定ファイルの作成

今後のために、 `pip.ini` を作成します。 `pip.ini` はpipの設定ファイルです。

以下に新規作成します。

```
C:\ProgramData\pip\pip.ini
```

今後、pipの設定を変更したい場合は、この `pip.ini` を編集していきます。



# プロキシの設定
プロキシ配下の場合は、プロキシの設定を `php.ini` に追加します。

```ini:pip.ini
[global]
# プロキシ設定
proxy = http://＜ユーザー名＞:＜パスワード＞@＜ホスト名＞:＜ポート＞
```



# さいごに
以上で終了です。以前、インストーラーでやったときよりも手順が減ってかなり楽になりました。
本記事作成にあたり、以下のサイトを参考にさせていただきました。ありがとうございました。

- [Chocolatey / Python 2.x](https://chocolatey.org/packages/python2)
- [Chocolatey / Python](https://chocolatey.org/packages/python)
docker-compose 覚え書き

# 覚え書き

## スケールを増やして起動する方法

```
docker-compose up -d —scale [service=scale_num]
```

上記コマンドでスケールを増やしてコンテナ起動ができます。
```version: ‘3’```以降
```container_name```は使用できないので注意。
他のコンテナとhost名で解決している場合は

```
docker-compose -p [project_name] up -d —scale [service=scale_num]
```

project_nameを指定してあげると
[project_name]\_[service_name]\_[scale_num]で立ち上がる

## 例

``` docker-compose.yml
version: '3.7'
services:
  app:
    image: image_name
```

```shell
$ docker-compose -p exampleproject up -d --scale app=2

##################
# exampleproject_app_1
# exampleproject_app_2
# が立ち上がる
```

## 注意

* プロジェクト名に\_を使用しても\_は自動的に消えてしまう  
  example_project → exampleproject
* ```docker-compose down```ではコンテナは削除されないが```-p [project_name]```を指定するとdownされる
【Laravel】Eloquentモデルからテーブル名を取得する方法

基本的にはEloquentモデルを使っているので、テーブル名をハードコードすることはないけれど、実装を進めてく中で時にはテーブル名を書かないといけないケースに出くわします。

テーブルを結合する時とか、そのテーブル同士に同じカラム名があってどっちのカラムか明示的に示さないといけない時とか。


テーブル名のハードコードは、できるならモデル内のメンバ変数`$table`のみにしたいものです。

ということで、ちょっとしたメモ。

#方法その１

```php
$userModel = new User();
$userTableName = $userModel->getTable();

//一行で書くなら
$userTableName = (new User())->getTable();
```

#方法その２

```php
$userTableName = User::make()->getTable();
```

#まとめ
どちらもモデルのインスタンスを生成してテーブル名を取得してます。
テーブル名が欲しいだけなのにnewするのはなんだかなーとは思いますが、他に方法を思いつきませんでした。

#参考

- <a href="https://qiita.com/okumurakengo/items/0670ce39d758ed65e8e7">100行ぐらいのSQLをLaravelのEloquent/Query Builderで頑張る</a>
CakePHP2で"/"がキーに入った値をPOSTすると"."に置き換わる

CakePHP2ベースのNetCommons3をいじってて気が付いたんですが、フォームで"/"がキーに入った値をPOSTすると"."に置き換わりますね…


例）

こんな "/"が入ったキーを設定してるフォーム

```html
<input type="hidden" name="data[SiteSetting][Security/deny_ip_move][0][id]" value="84" id="SiteSettingSecurity/denyIpMove0Id" autocomplete="off">
```

これをPOSTすると ```$_POST['data']['SiteSetting']``` は

```
array (
  'Security/deny_ip_move' => 
  array (
    0 => 
    array (
      'id' => '84',
    )
  )
)
 ```

と、ちゃんと"/"がはいった"Security/deny_ip_move"のままなんですが、```CakeRequest::data```をみると


```
array (
  'Security.deny_ip_move' => 
  array (
    0 => 
    array (
      'id' => '84',
    ),
  ),
)
```

こんな風に "/" が "." に置換され "Security.deny_ip_move" になります。

なんでこんな仕様なのかはわからないですが、知らなくてちょっとハマったのでメモ残しておきます^^;
ActiveRecordで絶対値(abs)orderのやり方

## やり方

``` ruby
User.select("name, ABS(point) AS point_abs").order(:point_abs :desc)
```

## データ内容補足
### 並び替え前

``` sql
User  name    point
   1  neko    10
   2  dog     -20
   3  usagi   30
```

### 絶対値での並び替え後

``` sql
User  name    point_abs
   3  usagi   30
   2  dog     -20
   1  neko    10
```

## 注意点

ActiveRecord::Relation上、列別名付けたカラムが表示されなくなる

``` ruby
User.select("name, ABS(point) AS point_abs").order(:point_abs :desc)
=> #<ActiveRecord::Relation[
     #<User id: 3, name: "usagi">,
     #<User id: 2, name: "dog">,
     #<User id: 1, name: "neko">]>
```

でもちゃんと項目としては存在している

``` ruby
User.select("name, ABS(point) AS point_abs").order(:point_abs :desc).to_a.first.point_abs
=> 30
```
【Rails】フォームの共通化後、サブミットの文字内容を切り替え方法

## 環境
Ruby 2.6.5
Rails 5.2.3

## 目的
フォームを共通化した場合、submitの文字内容を自動的に変換します。

## サブミットの文字列を切り替え方法
#### 方法１：ヘルパーに条件分岐で定義します。
action_nameメソッドを使うと、Action名を取得できます。

```ruby:app/helpers/feeds_helper.rb
  def button_text
    if action_name == "new"
      "シェアする"
    elsif action_name == "edit"
      "更新する"
    end
  end
```

```ruby:app/view/feeds/_form.html.erb
<%= form_with(model: feed, local: true) do |f| %>
  <div class="field">
    <%= f.label :content %>
    <%= f.text_area :content %>
  </div>
  <%= f.submit button_text %>
<% end %>
```
#### 方法２：ビューに条件分岐で定義します。
request.path_infoを使って、現在のURLを参照して文字を切り替えます。

```ruby:app/view/feeds/_form.html.erb
<%= form_with(model: feed, local: true) do |f| %>
  <div class="field">
    <%= f.label :content %>
    <%= f.text_area :content %>
  </div>
  <% if request.path_info == new_feed_path %>
    <%= f.submit "シェアする"%>
  <%else%>
    <%= f.submit "更新する"%>
  <% end%>
<% end %>
```
#### 方法３：renderに引数を渡します。
```ruby:app/view/feeds/_form.html.erb
<div class="field">
  <%= f.label :content %>
  <%= f.text_area :content %>
</div>
<% if local_assigns[:new_flag].present? %>
  <%= f.submit "シェアする"%>
<%else%>
  <%= f.submit "更新する"%>
<% end%>
```

それぞれのビューを編集します。

```ruby:app/view/feeds/new.html.erb
<h2>新規投稿</h2>
<%= form_with(model: @feed, local: true, url: {action: :create}) do |f| %>
  <%= render 'form', f: f, new_flag: true %>
<% end %>
```

```ruby:app/view/feeds/edit.html.erb
<h2>投稿編集</h2>
<%= form_with(model: @feed, local: true, url: {action: :update}) do |f| %>
  <%= render 'form', f: f %>
<% end %>
```

#### 方法４：日本語化します。

```ruby:config/initializers/locale.rb
I18n.config.available_locales = :ja
I18n.default_locale = :ja
```

さて、日本語の辞書ファイルを作成します。
config/locales/ja.ymlというファイルを作成しましょう。
ソースコードは以下のURLを参照してください。
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml

ダウロードしたら、ヘルパーのところで表示させたい文字に変更します。

```ruby:config/locales/ja.yml
---
ja:
  # 略
  helpers:
    select:
      prompt: 選択してください
    submit:
      create: シェアする
      submit: 保存する
      update: 更新する
```

## 参考文献
https://guides.rubyonrails.org/form_helpers.html
https://qiita.com/seiya1121/items/fba02afcd8d54f1628ba
【MySQL】usersテーブルから年代別のユーザー数を取得する

## 年代別にどれくらいのユーザー数がいるのか調べたい

サービスの利用ユーザーはいったいどれくらいの年齢層が使っているのか、GoogleAnalyticsを利用するのではなく、自社データ内で調査する際に使用しました。

使用するテーブルは

```
mysql> select * from users;
+----+-----------+------------+
| id | name      | birthday   |
+----+-----------+------------+
|  1 | 比屋根    | 1987-06-20 |
|  2 | 川端      | 1987-10-16 |
|  3 | 山田      | 1992-07-16 |
|  4 | 畠山      | 1982-09-13 |
|  5 | 高井      | 1984-06-25 |
|  6 | 大引      | 1984-06-24 |
|  7 | 荒木      | 1987-07-26 |
|  8 | 中村      | 1990-06-17 |
|  9 | 小川      | 1990-05-16 |
| 10 | 真中      | 1971-01-06 |
+----+-----------+------------+
```

このようなシンプルな構成にしています。

## 最終的なクエリ

```
mysql> SELECT
    ->   SUM(IF(age < 20,1,0)) as 'Under 20',
    ->   SUM(IF(age BETWEEN 20 and 24,1,0)) as '20 - 24',
    ->   SUM(IF(age BETWEEN 25 and 29,1,0)) as '25 - 29',
    ->   SUM(IF(age BETWEEN 30 and 34,1,0)) as '30 - 34',
    ->   SUM(IF(age BETWEEN 35 and 39,1,0)) as '35 - 39',
    ->   SUM(IF(age >=40, 1, 0)) as 'Over 40',
    ->   SUM(IF(age IS NULL, 1, 0)) as 'Not Filled In (NULL)'
    -> FROM
    ->     (
    ->         SELECT
    ->             TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS age
    ->         FROM
    ->             users
    ->     ) as derived;
+----------+---------+---------+---------+---------+---------+----------------------+
| Under 20 | 20 - 24 | 25 - 29 | 30 - 34 | 35 - 39 | Over 40 | Not Filled In (NULL) |
+----------+---------+---------+---------+---------+---------+----------------------+
|        0 |       0 |       3 |       3 |       3 |       1 |                    0 |
+----------+---------+---------+---------+---------+---------+----------------------+
```

こんか結果を取得します。

## 簡単に解説
まずサブクエリでユーザーの年齢一覧を取得しています。

```
mysql> SELECT
    ->     TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS age
    -> FROM
    ->     users;
+------+
| age  |
+------+
|   32 |
|   32 |
|   27 |
|   37 |
|   35 |
|   35 |
|   32 |
|   29 |
|   29 |
|   48 |
+------+
```

年齢は`TIMESTAMPDIFF`を利用して一覧を取得します。
この一覧がでたらあとは`SUM(IF(age BETWEEN 20 and 24,1,0)) as '20 - 24',`というselectをしていくことで年齢がbetweenに含まれたら1としてsumを出します。

簡単でしたが、もっと簡単に出せると思っててちょっと苦戦したのでメモしておきます。
使えそうなソースとコンパイル実行結果を黙々と書くメモ-java

```java:sample
Stream.iterate( 5, i -> i++ )
	              .limit(10)
	              .forEach(System.out::print);

```



コンパイル→実行：結果
5555555555

```java:sample
	        Stream.iterate( 0, i -> i++ )
	              .limit(5)
	              .forEach(System.out::println);
```

コンパイル→実行：結果
0
0
0
0
0

```java:sample
 	          Stream.iterate( 1, i -> ++i )
	              .limit(10)
	              .forEach(System.out::print);
```
コンパイル→実行：結果
12345678910
Evernote デベロッパートークンを入手する。

まずデベロッパートークンというものを取得します。
私はもとからあるEvernoteが壊れてしまうのが怖いので、練習のため新しいアカウントを作成して、デベロッパートークンを入手しました。
本来は元のデータを壊さないためにデベロッパートークンを使うのですが。ほかのデータがあると何が何だか分からなくなるかと思った
のも一因です。

[Developer token](https://dev.evernote.com/doc/articles/dev_tokens.php)を開き、Sandboxをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273281/af58ace7-619e-c2d8-8ec3-534388b8f1b0.png)
すると以下のページに移動するのでrevoke your developer tokenをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273281/411c5f16-05fb-d8c7-9f29-3e6991ae974e.png)

Create a developer tokenをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273281/14ad73f5-b3dd-7222-f01b-b3c2eead3368.png)

表示された［Developer Token］を控えておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273281/08ebd53f-87d3-faee-cd8a-b5eea913fdb1.png)

これで、デベロッパートークンの準備は完了です。

次はpythonを使って、Evernoteにノートブックやノートを作ってみようと思います。
レイヤードアーキテクチャの視点

「<a href="https://qiita.com/kichion/items/151c6747f2f1a14305cc" target="_blank">ValueObjectという考え方</a>」でDDDの片鱗について書かせていただきました
今回はDDD本のなかでも少し抽象度の高い「レイヤードアーキテクチャ」について深堀っていきます


# レイヤードアーキテクチャとは

レイヤーアーキテクチャ・レイヤードアーキテクチャと呼ばれているこのアーキテクチャ指向です
DDDは特定技術へ依存しているわけではないのでDDD=レイヤードアーキテクチャ！とならないように気をつけましょう

上位互換の思想として以下のものがあります

* ヘキサゴナルアーキテクチャ
* オニオンアーキテクチャ
* クリーンアーキテクチャ

基本的にどのアーキテクチャも一貫して**責務を適切に設定して依存関係を明確にする**という目的があります

一番原始的（？）なレイヤードアーキテクチャはその名の通り
責務を適切に設定した塊＝層（レイヤー）をイメージします

![Untitled1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66063/648ce07f-b1bc-86b3-90fc-098920b2ce9a.png)

これだけじゃなんのことやらって感じですね
更に技術っぽい責務を割り振って**依存の方向**を一方方向にします

![Untitled-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66063/af109d5b-744e-1be9-64b9-1d98b935ccc6.png)

これがレイヤードアーキテクチャの基本的なイメージ図です
DDD本内ではもっとユビキタスな表現を使って以下のような層を定義しています

* UI層
* Application層
* Domain層
* Infrastructure層

### UI層

**表示における関心事**を取り扱う層です
Webアプリケーションで扱うhttp requestやquery paramといった「表示に関するテクノロジー」はこの層から漏れ出ないようにします
また、ドメインの情報を書き換えるといった操作はすべてApplication層を介して行い、直接ドメインオブジェクトに影響を与える操作はUI層で行わないようにします

### Application層
ユースケース毎に**ドメインオブジェクトのコーディネートの関心事**を取り扱う層です
UI層からのリクエストに対してCRUD・ELTを行う層とも言えます
依存関係からUI層のテクノロジーを認知しなくてもいいように実装されます
また、ドメインの情報を書き換えるといった直接的な操作はドメインオブジェクトの振る舞いを介して行い、直接ドメインオブジェクトの値を変える操作はApplication層で行わないようにします
DBなどの永続化への影響のある操作も行いません

### Domain層
**ビジネスルール・仕様の関心事**を取り扱う層です
ここでようやくユースケースやユーザストーリーといったビジネスモデルの表現を行います
ドメインの情報を書き換えるといった直接的な操作を行います
UI層やApplication層の実装・テクノロジーを知らなくてもいいように実装されます

### Infrastructure層
**永続化テクノロジーの関心事**を取り扱う層です
DB、メモリ操作といったテクノロジーに関する実装をこの層にまとめます
また、ドメインオブジェクトに対してデータをパースしたりマッピングを行うこともします
他の3層の実装を知らなくてもいいように実装されます

---

# レイヤードアーキテクチャの利点

ここまで見ているとなんだか複雑かつルールがややこしいように見えるだけですが
大きな利点は**関心事の分離**にあります
仮にUI層にスポットを当てて考えましょう

例） `Webアプリを作っていたあるプロダクト が Nativeアプリを作ろうとする`

大変そうですね
しかし、レイヤードアーキテクチャを採用・実践できていれば追加実装はUI層にとどまります

![Untitled-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66063/077613a4-599a-ae20-ab97-9f4bc760db13.png)

更に永続化で使用しているDBを変更したい事案が発生！

例） `MySqlとPostgre両方で使用したい！`

![Untitled-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66063/d85e23fb-0746-d329-df32-e24834424876.png)

変更箇所は明確ですね
コードの影響を調査する手間も減ります

（まぁ、現実問題は開発言語の問題やらetc... でココまでうまくいかないですが…）

このように層で整理されているので変更に対して強く、影響をイメージしやすくなります

---

# レイヤードアーキテクチャの弱点

上記で利点を述べましたが弱点もあります

* ストアドチックなコードより記述量は増える
* チーム開発で共通認識を作るのが大変
* ドメインロジックがテクノロジーの変更により影響を受ける

### ストアドチックなコードより記述量は増える

将来に渡り変更が軽微な場合や検証段階ではオーバーテクノロジーになりますね
用法用量を守る必要があるのはアーキテクチャ採用の常なので意識する必要があります

### チーム開発で共通認識を作るのが大変

習熟度により差が生まれるのは設計・チーム開発のツラミでもあります…
頑張って共通認識をつけるしかないですね（ぇ

### ドメインロジックがテクノロジーの変更により影響を受ける
依存方向を見ると明らかですね
これは**依存性の注入(DI)**を利用することで解消できます
DIについての詳細はまた別の機会に

---

いかがでしたか？アーキテクチャを意識していなかった方が興味を持つきっかけになれば幸いです
実践できれば長期的に良い影響があり、ビジネス的な課題に寄り添っていけると思います

# その他

[軽量DDDでもやったほうがいい理由、けどやらない理由](https://qiita.com/kichion/items/b830ceffd08d3f6cfc9e)
[ValueObjectという考え方](https://qiita.com/kichion/items/151c6747f2f1a14305cc)
[Serviceクラスの意義と勘所](https://qiita.com/kichion/items/983e8330cd2651540d9c)
[集約で境界を正しく表現する意味](https://qiita.com/kichion/items/3826277eb372826a313e)
DonkeyCar タミヤTT-02のカスタマイズ

#フルベア化
標準では回転部分の摩擦が大きい
OP.1476 TT-02 フルベアリングセット
![54476_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/218fda5c-3aa8-bd9b-f7cc-c7b1f9cbf1e9.jpeg)

#後輪2駆化
四駆は曲がらない
前輪のドライブシャフトを除去
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/5fbbc8e8-4d1d-c9c3-bea1-4241beb785e3.jpeg)
路面によってはスピンしやすくなるのでステアリングジャイロを付けると良い

#ホイールベース，車高，車幅
組み換えが可能
![無題2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/eac78f22-4de8-17c7-50cc-42529aa640ac.jpeg)

#ステアリング
標準ではトー，キャンバー，アッカーマンの調整が出来ない
OP.1752 TT-02アップグレードステアリングセット
![54752_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/40a73125-7874-f22b-4272-8ecc9ac3481d.jpeg)
OP.1874 TT-02 アジャスタブルアッパーアームセット
![54874_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/68d27f74-aa9f-4eb0-1cf3-bf89f4d152e8.jpeg)

#サーボ
反応速度の速いハイスピードサーボに交換

#モーター
標準モーターはドラッグブレーキが効かない
Tの数字が大きいモーターに交換
トップスピードが下がるので注意

#ピニオンギヤ
歯数を少ないギヤに交換して低速でのトルクを増やす
トップスピードが下がるので注意
![54464_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/c8c25d40-68be-728e-7295-00ae922bfed5.jpeg)

#電圧安定化
満充電から使用するにつれて電圧が下がり走りが変わる
フィードバック無しの自動運転では致命的
バッテリーとESCの間に降圧レギュレータを入れて電圧を一定にする
レギュレータの電流容量に注意

#リポバッテリー
取り扱いに注意（爆発，発火，ガス発生による膨張）
リポバッグが必要
過放電防止に電圧監視アラームを併用
![61ALIrE6h6L._AC_SL1001_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/83f1e6d4-2a28-2c6d-b1c0-1f22a0d8b074.jpeg)

#タイヤ
路面に合わせて選択
前を高グリップ，後を低グリップにしてコーナーリング性能を高める

#ボディ
速く走らせる場合は空力も考慮
Salesforce が不得意なこと（苦手なこと）、できないこと（2019年10月現在）

#Salesforce は何でもできるのか
Salesforce ができることや夢のような話はよく聞きますが、ネット検索しても苦手なことやできないことについては記事を見かけない。おそらく部分的にアジャイルで導入して全体最適を試みて結果として無理かなあと思った際はその時点で終わってしまい、わざわざそれをまとめてアップロードする人がいないからだろう。こうしたらできたという事例はあっても、これは無理というものがなかったので自分なりに整理してみた。ここでいうSalesforceスコープはapex, visualforce, classic / lightning 等でカスタマイズを作り込む俗に言うEnterprise EditionやUnlimited Editionに代表されるforce.com, Sales Cloudの話をしており、Marketing Cloud等はあまり重きを置いていない。カスタマイズというよりコンフィグレベルのノンコーディングでビジネスアプリが作成できる反面、「今後」を考えてできないことは知っておいた方が良い。
**情報に誤りがある場合はご教示ください！**
#Salesforce (SFDC) 苦手なこと、できないこと（一般的なカスタマイズの範疇を超えているか汎用モジュール自体が存在していない機能、ビジネスプロセスなど）
●ERPで特に会計、SCM (物流) の機能。会計仕訳や原価計算（加重平均、他）、固定資産管理（償却管理）は無理と考えた方が良い。財務会計（制度会計）、税務会計、管理会計（簡単な予実管理除く）どれも非現実的。倉庫業務のWMSとしても不向き。人、物、金の三代ERP分野で人の管理は所属異動や勤怠管理（ICカードと連携というよりPCから出退勤をクリックさせる方法であれば）何とかSalesforceで作り込めばできることが多いが物と金では管理対象が膨れ上がると難しい。（Commerce Cloud の EC上での在庫表示という意味ではできなくもないが、中規模以上の倉庫内の在庫管理や配送伝票系まで網羅しようとするときつい、市販された別製品（クラウド含め）の方が楽）・・・　 
 **ある時点のデータが何であったかのスナップショット機能がない（例えば3月31日時点の締め日のデータが何であったかみたいな話、決算では必須なんですけどね、だからお金や物の管理が無理という話）**

●会計にも重なるが、**基幹トランザクション処理システム** としては不向き。記録方法にもよるが、制限値が厳しいケースが多い。検索結果表示にもタイムアウトの制限があり、運用がままならない。ファンクションキーやショートカットキー、一気にコピペ、リアルタイムのデータチェックのようなオペレーションに慣れていると標準GUIやvisualforceで大量のフィールドに対しデータを入れてチェック（しながら）するのはしんどい。データ変更履歴（Audit Trail）のフィールド数にも制限がある。
https://resources.docs.salesforce.com/206/latest/en-us/sfdc/pdf/salesforce_app_limits_cheatsheet.pdf
や
https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm

●保存ボタン押下前のデータ整合性チェックや自動保存、同一データを共有しながらリアルタイム更新/表示はできない (俗にいうGoogle Online SpreadsheetやExcel Onlineのような使い方はできない)

●文字や数字を置き換え、変換させながら出力させるレポートやダッシュボード（入れているデータをそのまま出力させることはできるが、標準のレポート機能で変換させながら出力はできない）、一つの親に対して４つ以上の子を結合させたレポートや、子に対して更に子を結合させるレポートはできない

●CRM/お客様関係の情報と言えども俗にいうWindows共有フォルダ、Google Drive、OneDrive / SharePointなどの置き換えとしては無理（ファイルを添付することはできるが軽量が前提、前述の制限値を参考のこと）・・・ Google Drive / OneDrive / SharePoint では当たり前の画像ファイル検索時のAIの検索は無い（例として花とキーワードを入れた場合に花の写真結果を返す機能）

●CRM/お客様関係の情報と言えどもテレカンや議事録・音声データの自動記録はできない（ChatterをSkype代わりにはできない、いわゆるSNSなので）

●全文検索時の近似検索は一部可能なものはある（大文字小文字など）が、Google検索に代表される近似レベルは期待できない（ひょっとして・・・？といった結果提案はされないので、利用者入力ミスで時々システム管理者を悩ませる）

●（こちらは運用はできるものの開発者を悩ましている問題）一つのSalesforceログインIDで複数のインスタンス（異なるorg）にアクセスできない　・・・　典型的な問題として開発会社の担当が一つのSalesforceログインで複数の開発先のサイトにシングルサインオンすることはできない（開発しているorgが増えれば増えるほどログインのIDが増えてしまい管理が煩雑、ログイン後にorg選択させれば良いのでは？と思いますが・・・）

スコープを広げたり大規模になると使えないことがある。
特に上限値、制限については一般の企業はお金を追加で払ってどうこうなる話ではないので注意が必要。
アジャイルには確かに向いているが…

複数システムをSalesforceで統合したい、入力箇所をまとめたいといった企業でどこでも一番大きな課題として私が出会しているのは**金と物の管理には向いていないというところ。**
phpenv/php-build で拡張がすこし入れやすくなりました

## PHP拡張を追加でいれるのは少々めんどくさかった

phpenv および php-build で、PHP拡張を同時に入れようとすると、今までは次のような手順をふまないといけませんでした。

1. `php-build/share/php-build/extension/definition` に行を追加してビルド方法を指定する
2. 環境変数 `PHP_BUILD_INSTALL_EXTENSION` で拡張名とバージョンを指定する

`php-build/share/php-build/extension/definition` はこんなファイルです。

- https://github.com/php-build/php-build/blob/master/share/php-build/extension/definition

```
"name","url-dist","url_source","source_cwd","configure_args","extension_type","after_install"
"apc","http://pecl.php.net/get/APC-$version.tgz","git@git.php.net:/pecl/caching/apc.git",,"--enable-apc","extension",
"apcu","http://pecl.php.net/get/apcu-$version.tgz","https://github.com/krakjoe/apcu.git",,,"extension",
"igbinary","http://pecl.php.net/get/igbinary-$version.tgz","https://github.com/igbinary/igbinary.git",,,"extension",
"imagick","http://pecl.php.net/get/imagick-$version.tgz","https://github.com/mkoppanen/imagick.git",,,"extension",
"memcache","http://pecl.php.net/get/memcache-$version.tgz","git@git.php.net:/pecl/caching/memcache.git",,,"extension",
"memcached","http://pecl.php.net/get/memcached-$version.tgz","https://github.com/php-memcached-dev/php-memcached.git",,"--disable-memcached-sasl","extension",
"uprofiler",,"https://github.com/FriendsOfPHP/uprofiler.git","extension",,"extension","uprofiler_after_install"
"xcache","http://xcache.lighttpd.net/pub/Releases/$version/xcache-$version.tar.gz",,,"--enable-xcache","extension",
"xdebug","http://xdebug.org/files/xdebug-$version.tgz","git://github.com/xdebug/xdebug.git",,"--enable-xdebug","zend_extension","xdebug_after_install"
"xhprof","http://pecl.php.net/get/xhprof-$version.tgz","git://github.com/facebook/xhprof.git",,,"extension","xhprof_after_install"
"zendopcache","http://pecl.php.net/get/zendopcache-$version.tgz","https://github.com/zendtech/ZendOptimizerPlus.git",,"--enable-opcache","zend_extension","zendopcache_after_install"
```

phpbrew だとバリアントを指定すれば拡張を簡単に追加できるのに比べると少々めんどくさかったんですよね。

## 柔軟性があがる pull-req が取り込まれた！

この状況が今回取り込まれた pull-req で少し柔軟性が上がりました。

- https://github.com/php-build/php-build/pull/586

これ、修正内容を見ただけではなにが良くなったか分かりづらいですが、次のようなことが可能になりました。

- PECL( https://pecl.php.net/ )で普通に配布されている拡張であれば、`php-build/share/php-build/extension/definition` に行を指定しなくても、環境変数 `PHP_BUILD_INSTALL_EXTENSION` に指定すれば良くなった

例えば、PECLで配布されているyaml拡張とredis拡張を同時にbuildしたければ次のように環境変数を指定すれば良くなります。

```
export PHP_BUILD_INSTALL_EXTENSION="yaml=2.0.4 redis=5.0.2"
```

指定方法は、拡張名とバージョンを `=` でつなぎ、複数指定する場合は空白で区切っていけばOKです。

この環境変数が設定されている状態で、phpenvやphp-buildでインストールすれば、ついでに拡張がはいるということになります。

これでPECLで配布されている標準的な拡張であれば同時にビルドしやすくなる(もちろんそのためにいろいろ xxx-dev みたいなものを入れとかないといけないですが)ので、だいぶ楽になりますね。
ValueObjectという考え方

以前、DDD（ドメイン駆動開発）を経験した流れでいくつかのことを学びました
その中でDDDの神髄を垣間見たのでかいつまんで紹介できればと思います

# 記事のターゲット
DDDを学び始めた人
値オブジェクト・ValueObjectとはなにか、その片鱗を知りたい人

# Value Objectとは
値オブジェクトとしてエリック本(青本)では紹介していますね

## Value Objectの特徴
特徴として以下のような内容があります

* 一意性を持たない
* 計測／定量化／説明を責務とする
* イミュータブルオブジェクト
* 交換可能
* ふるまいに副作用がない

### 一意性を持たない

オブジェクト毎に `hogehoge_id` のような一意性を表現するプロパティを含まず、一意性がない特徴です
逆にIDを持つようなオブジェクトは「*Entity*」といいます

この特徴の意味するところは**オブジェクトをプリミティブライクに扱えること**だと考えられます
これについては後述します

### 計測／定量化／説明を責務とする

小難しく書いていますが、例として「商品価格」「名称」といった
本来コードでは `int` や `string` といったプリミティブ型で表現していた内容を取り扱うということです

ここで「オブジェクトをプリミティブライクに扱える」意味が出てきます
具体的には以下のように扱うイメージです

```ruby
class ProductPrice
  def initialize(price)
    @price = price
  end
end

class FullName
  def initialize(fullname)
    @fullname = fullname
  end
end
```

オブジェクト化することになんの意味があるか？と思われるかもしれないですが、後に大きな意味を持つようになります

### イミュータブルオブジェクト

**不変性**とも言います
オブジェクトが生成された時点でオブジェクトの値が変わることを禁止しています

```ruby
p = new ProductPrice(100)

# p.price = 2000 # これはダメ！！
p = new ProductPrice(2000) # 値を変える場合はオブジェクトの再生成で変更します
```

イミュータブルオブジェクトの利点は「オブジェクトの安全性」「スレッドセーフ」などいろいろありますが
DDDではEntityがValueObjectを多く抱えたりするので
その際に**オブジェクトの状態を予想しやすくする**のが重要だと捉えています

### 交換可能

イミュータブルの説明コードにあったように、値を変更する際にオブジェクトを交換することで実現しますが
その操作が可能である特徴です

一意性がないが故に交換可能であると言いかえることもできます 

### ふるまいに副作用がない

副作用とは「操作により状態が変化すること」を指しています
ValueObjectはイミュータブルである必要があるのでふるまいにより値を変更してはいけません

```ruby
class ProductPrice
  attr_reader :price

  def initialize(price)
    @price = price
  end

  def add_price(add)
    # @price = price + add # ダメ！ぜったい！
    @price + add
  end
end
```

これも安全性の観点で非常に大事な特徴です
クラス利用者はメソッドを呼ぶときに変な気苦労をする必要がありません

---

つらつらと特徴について説明しましたが、あくまでValueObjectの規約みたいなもので
その価値についてはまだ触れていませんでした

## Value Objectの利点

あえてプリミティブ型を使わずにオブジェクトでやる理由がほしいですね
誤解を恐れずにいうと**値の持つビジネスルール（仕様）を豊かに表現できる**ことが最大のメリットです

先ほどの例でメリットをみてみましょう

```ruby
class ProductPrice
  attr_reader :price

  def initialize(price)
    @price = price
  end

  def add_price(add)
    ＃ @price = price + add # ダメ！ぜったい！
    @price + add
  end
end
```

これだけではただの使いにくい値ですが、表示や複雑な計算をするようになると一変します

```ruby
class ProductPrice
  attr_reader :price

  def initialize(price)
    @price = price
  end

  def add_price(add)
    # @price = price + add # ダメ！ぜったい！
    @price + add
  end

  # 税を含めた価格を取得する
  def tax_included_price(tax=0.08)
    @price * (1 + tax)
  end

  # 価格3桁毎にカンマを入れて表示用にする
  def display_text
    @price.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\1,').reverse
  end
end
```

表現力が増してただの値ではどうしようもないところもカバーできるようになりました
上記は単純なプロパティのみですが、実務では更に複雑なふるまいも増えてきますのでより効果的ですね

更にTaxとかもValueObjectにすることで税部分が複雑になっても切り分けて扱ったりできるので広がりも大きいです

---

なかなかイメージしにくいですが、ValueObjectは実践できればコードの見通しが良くなるので
知らなかった方は意識してコードを書いてみてはいかがでしょう？
（かくいう私もまだまだ実践できていないので精進します…）

# その他

[軽量DDDでもやったほうがいい理由、けどやらない理由](https://qiita.com/kichion/items/b830ceffd08d3f6cfc9e)
[レイヤードアーキテクチャの視点](https://qiita.com/kichion/items/aca19765cb16e7e65946)
[Serviceクラスの意義と勘所](https://qiita.com/kichion/items/983e8330cd2651540d9c)
[集約で境界を正しく表現する意味](https://qiita.com/kichion/items/3826277eb372826a313e)
JavaScriptとHTMLの裏側の話

#JavaScriptとHTMLの関係

例えば、画面Aと画面Bがあり、それぞれの画面で使用されているXXX.jsあった場合、共通化という意味合いで、HTML上にscriptタグとして記載することはあまり良しとされない。
ブラウザから画面が読み込まれる時、HTMLの読み込みとJSの読み込みが行われる。
画面Aを10KB、画面Bを7KB、JSが3KBであった場合、合計は20KBとなる。

◯　画面A(10KB) + 画面B(７KB) + JS(３KB) = 20KB　となり、
×　 画面A(10KB) + 画面B(７KB) + JS(３KB) + JS(３KB)= 23KBでは無い。

このように共通化するメリットがあるためだ。
これはブラウザ上にJSがキャッシュされるため画面Aから画面Bに遷移した場合、画面AでXXX.js、画面BでXXX.jsとはならない。
※キャッシュしたJSのロードはされます。
この際、画面Aでしか使用しないものも、画面Bに遷移してときにロードされる。

そのため、各画面のHTMLではどのJSを読み込むかハンドリングし、処理をJSに書くようにすれば余分なJSはロードされなくなる。

###メンテナンス性から考えると...
画面Aと画面BがありXXX.js、YYY.js、ZZZ.jsを読み込んでいたとする。
この場合、HTML上にscriptタグでどのJSを読んでいるか記載が無いと、どのJSが呼ばれているか分からない。
クラス名や関数名などgrepして絞り込んでいくしかない。
上記の例はjsが3つだが10個以上となるとHTMLから追うには時間と労力を要する。
その場合、scriptタグで記載した方が良いと思われる。
【AWS】cron実行結果をSlackに通知する

サーバーのシステム状態を定期的に確認したいけどツールを入れる程でもないので
cronを使ってshellファイルを自動的に実行するようにしました

ついでにSlackのIncomingWebhooksを使ってBotが自動的に呟いてくれるようにしてみました

# Slack Incoming Webhookの登録
まずはSlackのIncoming Webhookを準備します
Slackの設定にある `その他管理項目` というところから `App管理` を選択してください
![スクリーンショット 2019-10-25 10.01.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354659/90b674b6-1a42-9662-9bdb-499bb16bce4d.png)
ブラウザが開いて管理画面が出るので検索窓で `Incoming` と入力すると一番上に `Incoming Webhook` という項目があると思うので選択してください
![スクリーンショット 2019-10-25 10.02.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354659/5c8283c4-ccb1-22dd-4a97-6230fce5ef64.png)
Incoming Webhookアプリの詳細画面の `Slackに追加` を選択します
![スクリーンショット 2019-10-25 10.03.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354659/aa8230f1-a8fa-a599-ae9d-10b1ddb05336.png)
Botがつぶやくチャンネルを選択して `Incoming Webhookインテグレーションの追加` を選択してください
![スクリーンショット 2019-10-25 10.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354659/937683f9-ccf3-9ba9-7454-852168b1893b.png)

追加した時に `Webhook URL` というものが生成されます
このURLにhttpアクセスしたのをトリガーにBotが呟く仕組みになっています

# Slack連携Shellファイルの作成
次にSlackにhttpアクセスを飛ばすShellを用意します
基本的にコピペでいいと思います
以下の3つだけは自分の情報に書き換えてください

* 生成したWebhook URL
* slack 送信チャンネル
* slack 送信名


```webhook.sh
#!/bin/sh

set -eu

#Incoming WebHooksのURL
WEBHOOKURL="生成したWebhook URL"
#メッセージを保存する一時ファイル
MESSAGEFILE=$(mktemp -t webhooksXXXX)
trap "
rm ${MESSAGEFILE}
" 0

usage_exit() {
    echo "Usage: $0 [-m message] [-c channel] [-i icon] [-n botname]" 1>&2
    exit 0
}

while getopts c:i:n:m: opts
do
    case $opts in
        c)
            CHANNEL=$OPTARG
            ;;
        i)
            FACEICON=$OPTARG
            ;;
        n)
            BOTNAME=$OPTARG
            ;;
        m)
            MESSAGE=$OPTARG"\n"
            ;;
        \?)
            usage_exit
            ;;
    esac
done
#slack 送信チャンネル
CHANNEL=${CHANNEL:-"#送信するチャンネル名"}
#slack 送信名
BOTNAME=${BOTNAME:-"送信するBotの名前"}

if [ -p /dev/stdin ] ; then
    #改行コードをslack用に変換
    cat - | tr '\n' '\\' | sed 's/\\/\\n/g'  > ${MESSAGEFILE}
else
    echo "nothing stdin"
    exit 1
fi

WEBMESSAGE='```'`cat ${MESSAGEFILE}`'```'

#Incoming WebHooks送信
curl -s -S -X POST --data-urlencode "payload={\"channel\": \"${CHANNEL}\", \"username\": \"${BOTNAME}\", \"text\": \"${WEBMESSAGE}\" }" ${WEBHOOKURL} >/dev/null
```

このファイルを任意の場所に作成しましょう
今回は `/etc/webhook.sh` に作成しました

基本的にパイプで渡せるものはすべて出力できるはずです
以下コマンドで動作を確認してみましょう

```
$ sudo echo test | /etc/webhooks.sh
```


# cronの登録
cronの登録は簡単です
`/etc` に移動して `cron` の設定を開きます

```
$ cd /etc
$ sudo crontab -e
```

cronの設定が開いたら任意の処理を記入してください
今回は1時間毎に `vmstatコマンド` を実行したいので以下のように記入して `:wq` で編集を終了します

```
0 * * * * vmstat | /etc/webhooks.sh
```

以下コマンドを実行して登録が完了しているか確認できます

```
$ sudo crontab -l
```
ActiveRecord::Baseを継承したクラスに登録されているコールバックを調べる方法

例えば`Topic`というモデルクラスに登録されているコールバックを調べる場合、`_*_callbacks`（`*`には`validation`や`save`が入る）というメソッドを呼び出すことでコールバックの一覧を取得することができます[^1]。返り値はActiveSupport::Callbacks::CallbackChainのインスタンス。

## 例）before_saveまたはafter_saveで登録されているコールバックを取得する際の例

`_save_callbacks`を呼ぶと`ActiveSupport::Callbacks::CallbackChain`のインスタンスが返ります。

```ruby
Topic._save_callbacks
# => #<ActiveSupport::Callbacks::CallbackChain>
```

`ActiveSupport::Callbacks::CallbackChain`は`Enumerable`なので、`first`などで要素を取得すると`ActiveSupport::Callbacks::Callback`のインスタンスが返ります。

```ruby
Topic._save_callbacks.first
# => #<ActiveSupport::Callbacks::Callback>
```

ざっくりコールバック名の一覧を取得したいときは以下のようにします。

```ruby
# 登録されているコールバック名を取得（※表示している配列は一例です）
Topic._save_callbacks.map{ |c| c.filter }
# => [:store_previous_changes_for_image, :store_image!, :autosave_associated_records_for_site, :write_image_identifier]
```

beforeコールバックで絞り込みたい場合は`kind`の値で絞ります。

```ruby
# beforeで絞り込む
Topic._save_callbacks.select{ |c| c.kind == :before }.map{ |c| c.filter }
# => [:autosave_associated_records_for_site, :write_image_identifier]
```

afterコールバックについても同様です。

```ruby
# afterで絞り込む
Topic._save_callbacks.select{ |c| c.kind == :after }.map{ |c| c.filter }
# => [:store_previous_changes_for_image, :store_image!]
```

とあるafterコールバックが登録されているかどうか？を調べる場合は以下のようにすると良さそうです。

```ruby
Topic
  ._save_callbacks
  .select{ |c| c.kind == :after }
  .map{ |c| c.filter }
  .include?(:store_image!)
```


[^1]: [Active Record Callbacks](https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html)のDebugging callbacksにて詳しい説明がある
android版minecraftのアプリケーション内セーブデータを脱獄なしで取り出す方法

minecraftのセーブデータをアプリケーションに指定した場合
外部から参照できないフォルダに格納されて取り出しが難しくなリます。
脱獄してない端末の場合セーブデータのフォルダにアクセスできないからです。

以下のコマンドを順番に実行します。
1. adb backup -nocompress -f backup.ab com.mojang.minecraftpe
2. java -jar abe.jar unpack backup.ab backup.tar
3. tar xvf backup.tar
4. cd apps\com.mojang.minecraftpe\r\games\com.mojang\minecraftWorlds

[Android Backup Extractor](ttps://sourceforge.net/projects/adbextractor/)のabe.jarを使用しています。

adbのバージョンは以下です。
　Android Debug Bridge version 1.0.41
　Version 29.0.4-587166６

adbを使うためあらかじめ端末側の設定とAndroid Studioのインストールが必要です。

テストはマックとandroid10で実施しました。
koalaの研究

# 基本的な使用方法

graph, user, friends
https://github.com/arsduo/koala/blob/3c7037eea67062f05eccb16836bebec403ddbfec/lib/koala/api/graph_api_methods.rb#L22

実際にhttpリクエストを送っている所
https://github.com/arsduo/koala/blob/3c7037eea67062f05eccb16836bebec403ddbfec/lib/koala/api/graph_batch_api.rb#L25

batch_callsにためている？
https://github.com/arsduo/koala/blob/3c7037eea67062f05eccb16836bebec403ddbfec/lib/koala/api/graph_batch_api.rb#L30

# エラー処理のマインドマップ図式
![koala.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53267/9bcc768d-7caf-cdf4-ff54-f14171c5bad3.png)
ColaboratoryでOpenCV


# 概要
ColaboratoryでOpenCVをやってみます。
画像を選択アップロード、Colaboratoryで画像を表示まで
## Colaboratory とは
>Colaboratory は、完全にクラウドで実行される Jupyter ノートブック環境です。設定不要で、無料でご利用になれます。Colaboratory を使用すると、コードの記述と実行、解析の保存や共有、強力なコンピューティング リソースへのアクセスなどをブラウザからすべて無料で行えます。

Webブラウザから使うことができるGoogleが提供している機械学習用のプラットフォームです．利用料は無料です．どういうスペックのマシンが使えるというと


>n1-highmem-2 instance
Ubuntu 18.04
2vCPU @ 2.2GHz
13GB RAM
(GPUなし/ TPU)40GB, (GPUあり)360GB Storage
GPU NVIDIA Tesla T4 16GB または Tesla K80 12GB

これが無料で使える
すごい！！！

## 実装


``` python
%matplotlib inline
import cv2 #　OpenCVのインポート
import matplotlib.pyplot as plt # matplotlib(描画用)
```

``` python
from google.colab import files
#ファイルアップロード
uploaded = files.upload()

# アップロードしたファイル名取得
file_name = list(uploaded.keys())[0]
# アップロードしたファイルを参照
img = cv2.imread("./" + file_name)
# cvtColorでBGRとRGBを変換
show_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 結果表示
plt.imshow(show_img)
```

## 結果
<img width="656" alt="スクリーンショット 2019-10-31 0.07.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/0d17354a-ea27-a6f0-b037-bcccbb258228.png">

# 顔検出もやってみる
## 参考記事
[OpenCVで顔認識をしてみた](https://qiita.com/K_M95/items/f1a3e7c47800adb94095)

## 事前準備
https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
上記URLのファイルをダウンロードして
<img width="428" alt="スクリーンショット 2019-10-31 0.32.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/3b61791f-0ffd-be70-771c-c4d77f58670a.png">
メニューを開いてファイルをアップロード
<img width="355" alt="スクリーンショット 2019-10-31 0.31.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/89553ba5-9c89-6ded-e8b8-6c00a16baa36.png">



``` python
%matplotlib inline
import cv2 #　OpenCVのインポート
import matplotlib.pyplot as plt # matplotlib(描画用)
from google.colab import files

#ファイルアップロード
uploaded = files.upload()

cascade_file = "haarcascade_frontalface_alt.xml"

# アップロードしたファイル名取得
file_name = list(uploaded.keys())[0]
# アップロードしたファイルを参照
img = cv2.imread("./" + file_name)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cascade = cv2.CascadeClassifier(cascade_file)
face_list = cascade.detectMultiScale(img_gray, minSize=(150, 150))
if len(face_list) == 0:
  print("Fail recognise")
  quit()

for (x, y, w, h) in face_list:
  print("顔の座標 =", x, y, w, h)
  color = (0, 0, 225)
  pen_w = 8
  cv2.rectangle(img, (x, y), (x+w, y+h), color, thickness = pen_w)


cv2.imwrite("after.jpeg", img)
result_image = cv2.imread("./" + "after.jpeg")
result_image = cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB)
# 結果表示
plt.imshow(result_image)
```
<img width="890" alt="スクリーンショット 2019-10-31 0.28.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/4830111c-8944-8c94-25af-4fc86500ec24.png">
HHKB US配列のスペースバー押下時の「カチャカチャ」音問題について


# 先に結論！
スペースバーを取り外したときに出現するスプリングを取り除く事で解決

## カチャカチャ音とは？

スペースバーを押下した時の異音。不快音。
海外サイトなどでは、「HHKB spacebar rattle」等として取り上げられている。
https://www.youtube.com/watch?v=OTL6vtIh-nE

## 解決に至るまでに実施したこと
1.スペースバーのスイッチ部両脇のパーツに対してグリスを塗布する
→ 押下圧が増しただけ。

2.スペースバーを上下逆さに取り付ける
→ 押しにくいし手首が痛くなった。

3.静音ゴムを取り付ける
→ タイピング音が静かになった。

4.洗ってみた
→ 綺麗になった！

5.スペースバーを取り外すと出現するスプリングを取り外してみた
→ 「カチャカチャ」しなくなった！とても心地よい「スコスコ」になった！

## まとめ

海外の掲示板を見てても割と多くの人が発生している現象みたいです。
色々な解決方法が議論されていましたが今回の解決方法が一番手軽でリスクが少ないと感じます。
是非、同じ悩みを持っていてスペースバーの音に不快な思いをしている方がいたら実施してみてください。
【Laravel】タイムゾーンの設定を変更する

# 設定方法

`config/app.php` に定義されているキー `timezone` の値を変更する。
バージョン6.3では、デフォルト値として `UTC` が設定されている。

```php:app.php
<?php

return [
    :
    'timezone' => 'UTC',
    :
```

UTC（協定世界時）は日本標準時と9時間の時差があるため、
日本国内を対象としたアプリケーションであれば `Asia/Tokyo` を指定する。

```php:app.php
<?php

return [
    :
    'timezone' => 'Asia/Tokyo',
    :
```

`Asia/Tokyo` 以外の設定が必要な場合は、
PHPがサポートしているタイムゾーンの一覧を確認の上で適切な地域を指定する。
[PHP: サポートされるタイムゾーンのリスト - Manual ](https://www.php.net/manual/ja/timezones.php)

# 備考： `date_default_timezone_set()` でタイムゾーンを指定した場合

`date_default_timezone_set()` で `config/app.php` と異なるタイムゾーンを指定した場合、
以降の日時処理は新たに指定したタイムゾーンに基づいて行われる。

```php
// config/app.php でタイムゾーンに 'Asia/Tokyo' を指定しているなら
$datetime_jst = date('Y-m-d H:i:s');    // タイムゾーン'Asia/Tokyo'で現在日時が取得される

date_default_timezone_set('UTC')
$datetime_utc = date('Y-m-d H:i:s');    // タイムゾーン'UTC'で現在日時が取得される
```
SQLServerで特定セッションの一括削除

# 問題
本番DBにつなぎパ

# DB管理者に無視されたが、できることをやろう
定期的にPCからのセッションのみをぶった切る。特定セッションを掃除。
幸いPC名は命名規則のルールがあるので特定できる。
なお、更新中の処理もあるのでリクエスト終了時間から1時間後を条件に加える。

## ストアドプロシージャ
```sql
CREATE PROCEDURE [dbo].[up_CleanSession]
AS
BEGIN
	SET NOCOUNT ON;

	Declare @cnt int, @i int, @ssid int
	Declare @tbl table(ID int identity(1,1), ssid int);

	INSERT INTO @tbl(ssid)
	SELECT session_id 
    FROM sys.dm_exec_sessions
	WHERE host_name like 'PC-%'
      and is_user_process = 1
      and status = 'sleeping'
      and datediff(MINUTE, last_request_end_time, getdate()) > 60


	SELECT  @cnt = Count(*) FROM @tbl
	SET @i = 1

	WHILE @i <= @cnt
	BEGIN
		SELECT @ssid = ssid FROM @tbl WHERE ID = @i

		--ごめんなさい。もう家に帰りなさい。
        EXEC ('KILL ' + @ssid);

		SET @i += 1
	END
END
```

## メンテナンスプラン
定期でストアドプロシージャ実行

# ・・・
本番DBに接続したまま一日を過ごすモンスターが増えている。新人は先輩の背中を見る。
Macユーザも増え、見たことないツールで接続したままに。
帰りにPC電源切ってくりゃ、仕方ないとするが、つけっぱなしの有り様。環境にもワルイ。

障害調査中にモンスターセッションが非常に気になるのでDB管理者に相談したが。
何が悪いですかと聞かれ、過去にあったデットロック事件や接続ツールバグでTEMPDB枯渇事件などを説明したが、証拠がないからと却下された。
妙に証拠を求める時は何かを隠している（に違いない）。おっとDB管理者もつけっぱモンスターの仲間だった。
円満に納得させたいが。

# 参考
https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-sessions-transact-sql?view=sql-server-ver15

https://docs.microsoft.com/ja-jp/sql/t-sql/language-elements/kill-transact-sql?view=sql-server-ver15
[ 機械学習 ] 社内輪講 Week9 〜 異常検知 〜

## はじめに

[スタンフォード大学 Andrew Ng氏による機械学習の講義動画](https://www.coursera.org/learn/machine-learning)を各週社内メンバーで持ち回りで受講し、学んだことを発表、Qiitaで共有しています。

[【機械学習】社内輪講はじめました -Qiita](https://qiita.com/aoki-k/items/a25fe5e9d504f90f72f3)

第9週は以下の内容でした。

- Anomaly Detection

主に、異常検知を説明していきます。

## 目次
- 異常検知
- 特徴量ごとに独立に正規分布に従う場合
- 多変量正規分布に従う場合

## 異常検知

例えば工場で作られた製品の重さ, 大きさ、飛行機のジェットエンジンの音や温度などを測定する。それらのデータから製品が不良品かどうか、エンジンに異常が起きているかどうかを判断したい。

正常データ, 異常データが共に十分な数が用意できるならば、ロジスティック回帰などの二値分類を行えば良い。

しかし工場の不良品も、エンジンの異常状態も正常のものより極端に少ない。これではデータ量が少なく分類は難しい。（例 : 正常 10,000 個, 異常 20 個など...）



そこで、

「正常データを"正常カテゴリ"に分類、異常データを"異常カテゴリ"に分類」という考えではなく、

「"正常" とは何かを定義し、そこから外れるものを "異常" とするような考え方で異常検知を行ってみる。

※ ここでは説明のため、二次元データを使用する。



## 特徴量ごとに独立に正規分布に従う場合

例えば以下のようにデータが分布していたとする。 ( $x1, x2$ には例えば製品の質量, 体積などである。 )

<img width="559" alt="1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502808/1ff5ae45-b005-afff-3c97-f5bf0e582cab.jpeg">

黒い点が正常データで、赤い点が異常データである。

これらを訓練データとして、異常検知モデルを作りたい。

$x1, x2$ がそれぞれ独立に正規分布に従うとする。平均, 分散がそれぞれ $\mu_1$, $\mu_2$, $\sigma_1$, $\sigma_2$ として確率密度関数は
$$
f_1(x_1) = \frac{1}{\sqrt{2\pi\sigma_1^2}}\ e^{-\frac{(x_1-\mu_1)^2}{2\sigma_1^2}},
\ \
f_2(x_2) = \frac{1}{\sqrt{2\pi\sigma_2^2}}\ e^{-\frac{(x_2-\mu_2)^2}{2\sigma_2^2}}
$$
となる。正規分布は

- 平均の前後で確率は対称
- 平均から離れるほど確率は低くなる

という性質を持っている。上記の積
$$
\phi(x_1, x_2) = f_1(x_1) \ f_2(x_2)
$$
は以下の図の青い枠の外側に行けば行くほど値は小さくなっていく。（青枠は $ \phi $ の等値線）

ここでパラメータ $a$ を用いて

- $\phi(x_1, x_2) \ge a$ のとき
  - $ (x_1, x_2) $ は正常データ
- $\phi(x_1, x_2) < a$ のとき
  - $ (x_1, x_2) $ は異常データ

と分類する。

<img width="552" alt="2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502808/4fe9e7c0-1dd5-d6a5-7199-81b82236f995.jpeg">


モデル決定の流れは

- 訓練データで $\phi$ を定義
- CVデータで $a$ を定義
- テストデータで $a$ が良く定義されているか確認

である。

この方法は各特徴量が全て正規分布に従うことを前提としている。よって

- 正規分布に従う特徴量
- 変数変換して正規分布に従う特徴量

のいずれかを使用する。



## 異常検知 〜 多変量正規分布に従う場合 〜

次の図のように分布していたとする。

<img width="536" alt="3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502808/68714249-5481-a000-1e64-b5197413f2f6.jpeg">


先ほどとは違い、傾いた楕円形に分布している。これを上記の
$$
\phi(x_1, x_2) = f_1(x_1)f_2(x_2)
$$
で分類すると

<img width="540" alt="4.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502808/8d5e4f7f-5e78-0c24-eeb9-7fff5ad52ba5.jpeg">

のように中心からの距離が同程度の正常データと異常データの $ \phi(x_1,x_2) $ の値が近くなってしまい、うまく分類できない。

ここで $x = (x_1,x_2)$ が多変量正規分布に従うとすると確率密度関数は
$$
\psi(x) = \frac{1}{\sqrt{4\pi^2|\Sigma|}}\ e^{-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)}
$$
である。ただし以下を満たす。

- $\Sigma$ は分散共分散行列
- $\mu = (\mu_1, \mu_2)$

この関数で、パラメータ $a$ を用いて

- $\psi(x) \ge a$ のとき
  - $ x $ は正常データ
- $\psi(x) < a$ のとき
  - $ x $ は異常データ

と分類する。

今回の関数 $ \psi $ は以下の図の青い線が等値線となるような分布である。図のようにうまく、分類がうまくいっている。

<img width="534" alt="5.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502808/4196fe30-b6e0-2677-a348-82b8bf868cdd.jpeg">


以上になります。
GCCの警告オプション設定

## オプション一覧

* 参考: [gcc の警告オプションを調べてみた。](https://gist.github.com/tosihisa/2585404)

```sh
gcc -Q --help=warnings
```

にて確認ができる。出力例は以下

* [CentOS 7 の compat-gcc 4.4.7](https://github.com/tukiyo/centos8-gcc/blob/master/docs/gcc447.txt)
* [CentOS 8 の gcc 8.2.1](https://github.com/tukiyo/centos8-gcc/blob/master/docs/gcc821.txt)

## 特定の警告を一時的に無効にする

* [宇宙の晴れ上がり: GCCで特定の警告を一時的に無効にする](http://transparent-to-radiation.blogspot.com/2014/12/gcc.html)

* [Man page of GCC](https://linuxjm.osdn.jp/html/GNU_gcc/man1/gcc.1.html)

```sh
# 全ての警告メッセージを抑制したい場合
export CFLAGS="-w"
export CXXFLAGS="-w"

./configure
make
```

```sh
# -Wnoを指定すれば、その警告は無効できる

## c
# 暗黙の関数宣言
export CFLAGS="-Wno-implicit-function-declaration"
# 廃止予定(deprecated)
export CFLAGS="$CFLAGS -Wno-deprecated-declarations"
#
export CFLAGS="$CFLAGS -Wno-stringop-overflow"

## cpp
# intからポインタへの変換
export CXXFLAGS="-Wno-int-to-pointer-cast"
#
export CXXFLAGS="$CXXFLAGS -Wno-class-memaccess -Wno-conversion -Wno-sign-conversion"

# configure より前に CFLAGS を指定しておく必要がある。
./configure
make
```
JavaScriptのreduce()やfilter()を使って配列をスマートに扱うTips

[reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) を使うと、ある配列から各要素ごとに処理を実行、一つの結果にまとめることができます。   

[filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) はある配列から条件にマッチした要素だけを抽出できます。



簡単な例として「Number配列の中から偶数だけを取り出してその合計を求めたい」場合を想定します。
先に `forEach()` を使った場合を書いてみましょう。

## `forEach()` を使う場合

```js

const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let result = 0
myArray.forEach(value => {
  if (value%2 === 0) {
     result = result + value
  }
})
console.log(result)
```


結果:

```
=> 20
```

このようにかけますね。

## `reduce()` , `filter()` を使う場合

`filter()` はわかりやすいですが `reduce()` の使い方は、

```
myArray.reduce(reducer, initialValue)
```

のように使います。
reducerはcallbackを渡して、initialValueはaccumulatorの初期値になります。

`reduce()` にはreducer関数（純粋関数）と言われるものを渡します。   
そして reducer関数の中は第一引数にaccumulatorが渡ってきます。    
これは蓄積された値、つまり要素の数だけreducer関数を実行した時に、前の関数でreturnされた値が入ります(下の例だと 2 → 6 → 12 → 20 の順)。  
第二引数は実行される現在の値(下の例だと 2 → 4 → 6 ...の順)になります。   


```js

const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]

const isEvenNumber = value => value%2 === 0

const reducer = (accumulator, currentValue) => accumulator + currentValue

const result = myArray.filter(isEvenNumber).reduce(reducer, 0)

console.log(result)

```

結果:

```
=> 20
```

結果は同じですね。


## まとめ

`forEach()` の例と比べるとわかりますが、 `reduce()` や `filter()` 、 `map()` を使うとループ処理部分を別関数として切り出しやすくなります。
これによってロジックを共通化できたり、テストが書きやすくなるというメリットがあるので、`reduce()` や `filter()` 、 `map()` を積極的に使っていきたいですね。
DonkeyCar ラジコン用ジャイロでスピンを回避する

#RCカー用ステアリングジャイロ
滑りやすい路面ではコーナーでスピンする事がある．
ラジコンカー用にヨーを感知して自動でカウンターステアを当てるジャイロが販売されている．
２駆のドリフト走行で良く使用される．
![71Hx3w3xrEL._AC_SL1500_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/7a08e71b-96a8-2e2f-be63-ef7e5af20e6d.jpeg)

#取付
両面テープで固定．
PWMボードとステアリングサーボの配線に割り込ませる．
ステアリングサーボの動作方向によってリバース/ノーマルを切り替える．
![71x7mtn0xuL._AC_SL1500_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263672/88ea2efe-c156-9bd9-07f0-53cdf2125119.jpeg)

#ゲイン調整
路面の滑り具合に合わせて調整用ボリュームを回して調整する．
0％のときは機能しない．
ゲインが高すぎると曲がらなくなる．
PWMでゲインを変更出来るのでDonkeyCarのソフトウェアを改造すればコントローラーから変更が可能になる．

#注意
床に置いてステアリングをニュートラル合わせてから駆動系の電源を入れ，数秒間は動かさない．
lodashメモ

# 概要
配列やオブジェクトの取扱を手軽にした関数群

[公式](https://lodash.com/docs/
英語表記だがあらかた乗っているので確認するならここ
`_.metod`みたいな形式で書かれているので
この記載を見たら公式で確認すると良い
anacondaで作成した環境を切り替えてSpyderで作業する

前回
・[Windows10 anaconda環境にpython2.7環境を追加する](https://qiita.com/positive_023/items/12746e9ad9fec746e993)
で作成した仮想環境をSpyderを使ってみます。

仮想環境下でSpyderを使用するには、まず使用したい仮想環境をanaconda promptから起動した後に、Spyderを立ち上げます。
前回作成した仮想環境はpython2.7が入ったpy27という名前にしたので

```
(base) C:\Users\(省略)> conda activate py27
```
と入力すると、

```
(py27) C:\Users\(省略)> 
```
とpy27環境に移行できます。

現在このpy27にインストールされているものを確認するため


```
(py27) C:\Users\(省略)>conda list
```
と打ち込むと

```
(py27) C:\Users\(省略)>conda list
# packages in environment at C:\ProgramData\Anaconda3\envs\py27:
#
# Name                    Version                   Build  Channel
certifi                   2019.9.11                py27_0
pip                       19.3.1                   py27_0
python                    2.7.16               hcb6e200_0
setuptools                41.4.0                   py27_0
sqlite                    3.30.0               h0c8e037_0
vc                        9                    h7299396_1
vs2008_runtime            9.00.30729.1         hfaea7d5_1
wheel                     0.33.6                   py27_0
wincertstore              0.2              py27hf04cefb_0

(py27) C:\Users\(省略)>     
  
```

Spyderがインストールされていないので、condaでインストールする

```
(py27) C:\Users\(省略) conda install spyder
```

するといろいろインストールが始まるが、インストールが完了するとコマンドプロンプトが表示されるので、

```
(py27) C:\Users\(省略) Spyder
```
と打ち込むとSpyderが立ち上がる。

ウインドウの左上のタイトルがSpyder (Python2.7)と表示されており、Python2.7の環境でSpyderが開けていることがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273281/28bbd7ab-525e-c144-acfa-da289b26821c.png)






注意点

ここでpip でインストールするとspyderは立ち上がらないので、必ずcondaでインストールすること(←間違えて失敗した人)