OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 18.04でvagrantを使ってCentOS 7の仮想マシンを立ち上げる

# はじめに

簡単にLinuxの検証環境を作りたいと思い立ちました。
以前は、Virtualboxをインストールして、Linuxディストリビューションのインストールイメージをダウンロードして、インストールして、といった手順を踏んでいました。
最近、vagrantなるものがあるらしいと知り、使わない手はありません。

本記事ではvagrantを使ってLinuxの検証環境を立ち上げます。
Ubuntu 18.04上でCentOS 7の仮想マシンを作成します。
プロバイダにはlibvirtを利用します。

# 手順

## パッケージのインストール

aptコマンドで必要なパッケージをインストールします。

```
$ sudo apt update
$ sudo apt install vagrant ruby-libvirt qemu libvirt-bin ebtables dnsmasq libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev
```

## Vagrantfileの作成

ディレクトリを作成し、そこに作成する仮想マシンの設定ファイルであるVagrantfileを作成します。

```
$ mkdir centos7
$ cd centos7
$ vi Vagrantfile
```

下記のようなVagrantfileを作成します。

```
$ cat Vagrantfile 
Vagrant.configure("2") do |config|
  config.vm.provider :libvirt do |libvirt|
    config.vm.box = "centos/7"
  end
end
```

## 仮想マシンの作成・起動

vagrant upコマンドを使って仮想マシンの作成と起動を行います。
事前にプロバイダをlibvirtに設定しておきます。

```
$ export VAGRANT_DEFAULT_PROVIDER=libvirt
$ vagrant up
```

## 仮想マシンへのログイン

起動が完了したら、vagrant sshコマンドで仮想マシンにログインします。

```
$ vagrant ssh
```

## 確認

CentOS 7が起動できたか確認します。

```
$ sudo yum install lsb
$ lsb_release -d
```

CentOS Linux release 7.xと表示されればOKです。

# 参考情報

- vagrant-libvirt/vagrant-libvirt
    - https://github.com/vagrant-libvirt/vagrant-libvirt

# 最後に

Ubuntu 18.04でVagrantを使い仮想マシンを立ち上げることができました。
Vagrantfileを変更して、仮想マシンのコア数やメモリ容量、ネットワークなどの構成を変更することもできます。
また、AnsibleやChefなどの他のツールとの連携もできるみたいです。
ngrok的なことをsshだけでできるServeoに感動した

ここにある
---
[Serveo](http://serveo.webflow.io/)

見たらわかる、できること
---

:one:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/bc9772d4-2a50-a810-18a5-56c5f0dced95.png">

:two:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/9fd1944b-d466-e4d3-f440-0949bc9b1d5a.png">

感動した
---

Free, No installation, No signup
spring framework 簡易勉強メモ（二）：AOP

# spring framework 簡易勉強メモ（二）：AOP

### 本質

- 散在コードを本質処理から分離

### 考え方

- 散在処理を横断的に実装

### 代表的な応用場面

- ログ出力
- セキュリティチェック
- トランザクション
- キャシュー
- モニタリング
- 例外ハンドリング

### ソース例

```java
@Aspect
@Component
public class MethodStartLoggingAspect {
    @Before("execution(* *..*ServiceImpl.*(..))")
    public void startLog(JoinPoint jp) {
        System.out.println("メソッド開始:" + jp.getSignature());
    }
}
```

### Advice実装方法

- @Before
  - join point 前実施
- @AfterReturning
  - join point が正常終了後実施
  - 例外スロー時実施しない
- @AfterThrowing
  - 例外スロー時実施
  - join point が正常終了後実施しない
- @After
  - 例外スローにかかわらず終了後実施
- @Around
  - join point の前後で実施


### point cut 式

- join pointを選択する方法
- 例："execution(* *..*ServiceImpl.*(..))"
- 指定の方法
  - メソッド指定
  - クラス型指定
  - 名前などその他指定

### AOP常用アノテーション

- トランザクション
  - @Transaction
  - メソッド正常終了時コミット
  - メソッド異常終了時ロールバック
- 認証
  - @PreAuthorize
- キャシュー
  - @Cacheable
- 非同期処理
  - @Async
- リトライ処理
  - @Retryable
cocos2d-xのC++プロジェクトでLuaを組み込めるようにする為の手順

#cocos2d-xのC++プロジェクト（cocosコマンドでプロジェクトを作る際に-l cppとしたもの）でLuaを組み込めるようにする為の手順
cocos2d-xのC++プロジェクトで開発を行っていて、Luaを組み込みたくなった場合の手順。
色々ハマったのでメモ。
※１：cocos2d-x3.17現在の情報。
※２：Win32プロジェクト向けの情報。iOSやAndroidは手順が異なる（或いは増える）可能性あり。
※３：cocos2d-x 3.17がDドライブ直下にインストールされているものとする。

1:D:\cocos2d-x-3.17\cocos\scripting\lua-bindingsを、{ProjectDir}\cocos2d\scripting\にコピー。（scriptingディレクトリは自分で作成する。）
2:D:\cocos2d-x-3.17\external\luaを、{ProjectDir}\cocos2d\external\にコピー。
3:{ProjectDir}\cocos2d\cocos\scripting\lua-bindings\proj.win32\libluacocos2d.vcxprojをソリューションに追加。
4:プロジェクトの「参照」を右クリックし、「参照の追加」→「libluacocos2d」にチェックを入れる。
5:プロジェクトのプロパティを開き、「C/C++」→「追加のインクルードディレクトリ」に以下を追加する。
・$(EngineRoot)external\lua\lua
・$(EngineRoot)external\lua\luajit\include
・$(EngineRoot)external\lua\tolua
・$(EngineRoot)cocos\scripting\lua-bindings\manual
・$(EngineRoot)cocos\scripting\lua-bindings\auto
6:「C/C++」→「プリプロセッサ」→「プリプロセッサの定義」に「_USRLUASTATIC」を追加する。
7:「リンカー」→「入力」→「追加の依存ファイル」に「lua51.lib」を追加する。
8:ビルド。これで行けるハズ。

日本語のページで色々情報が出ているが、6の手順が海外のフォーラムにしか情報が掲載されておらず、結構ハマった。
JavaScriptももしかしたら似たような手順で行けたりするのかも。（未検証）
###参考にしたページ
http://shakezoomer.com/?p=1013
　└mac(XCode)での手順だがやってる事は大体同じ。（「C++でプロジェクトを作成する」のコマンドではLua向けのプロジェクトを生成しているが-l cppの間違いでは・・・？）

https://stackoverflow.com/questions/19536223/error-lnk2001-unresolved-external-symbol-in-cocos2d-x-lua-support
　└上述した海外のフォーラム。

http://giginet.hateblo.jp/entry/2012/10/10/070651
　└ここにまとめたような使用するまでの手順そのものは掲載されていないが、バインディングのやり方などが乗っているページ。
　 但しVer3.17現在、各クラスの接頭子「CC」が排除されている模様。（例：「CCLuaEngine」→「LuaEngine」）
Spring Boot の設定ファイルを理解する

大体この辺に書いてあるが難しいのでまとめる
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

## YAML で記述しても内部的には Java Properties になる

Spring Boot が内部的で Java Properties で保持しているため、最終的な表現は Java Properties ベースとなる。
以下はどちらも YAML であり、 YAML としてはまったく意味が異なるが Spring Boot の設定ファイルにおいては同じ結果となる。

```yaml
myapp:
    value: hello
```

```yaml
myapp.value: hello
```

よくある事例として `spring.profiles` を設定しつつ `spring.profiles.include` を設定したいときは以下のように記述できる

```yaml
---
spring.profiles: dev
spring:
    profiles:
        include:
            - local-db
```

## spring.profiles.active は一度しか読み込まれない

`spring.profiles.active` が未定義のときのみ、そのプロファイルの設定がロードされる。
以下のように指定すると include したプロファイルに記述したプロファイル `bar` をロードすることができるがやる意味は特にないしわかりにくくなるだけなので、 active を指定するのは applicaiton.yml と application-default.yml のみにとどめたほうがいいだろう。

```yaml:application.yml
---
spring.profiles: default
spring.profiles.include:
  - foo

---
spring.profiles: foo
spring.profiles.active: bar
```

## プロファイルはタグのように扱える

spring.profile.active は複数設定することができる。また、ここで指定した profile はそれに対応した設定ファイルが存在している必要もない。
これを利用すると DB の設定などを別プロファイルに切り離しておき、 active や include にそのプロファイルを追加指定することで切り替えたりするようなことができる。

例えばテストに用いるデータベースを手元で実行するときはローカルを、 CI で実行するときは特定の DB を使うなどとしたいときは以下のように記述できる

```yaml:application.yml
---
spring.profiles: default
spring.profiles.active: test

---
spring.profiles: test
spring:
    datasource:
        # local db settings

---
spring.profiles: ci
spring.profiles.include:
    - ci-db

---
spring.profiles: ci-db
spring:
    datasource:
        # ci db settings
```

CI のタスクで `SPRING_PROFILES_ACTIVE=test,ci` と指定することにより接続先 DB を CI 用のものに変更できる
上記では `test, ci, ci-db` がプロファイルとして spring boot に読み込まれる
このように記述していくことのメリットとして読み込まれたプロファイルが `@Profile` Annotation などで指定できるため細かく切り替えることができるようになる

logback-spring.xml においても springProfile タグを使って環境ごとにディレクトリや appender を変更することがままあるため非常に相性が良い
中間テーブルとは

## 中間テーブルとは
テーブルとテーブルの多対多の関係を表す関連テーブルです。

そう言われてもこの情報だけではさっぱりわからず。
先輩の説明を受けてスッキリ理解できましたので、以下に実例を踏まえてまとめます。

## 親子の関係
`user`と`school`の２つのテーブルがあるとします。

|id|user|
|---|---|
|1|a|
|2|b|
|3|c|
|4|d|
|〜|〜|

|id|school|
|---|---|
|1|A小学校|
|2|B中学校|
|3|C高校|
|4|D大学|
|〜|〜|

この２つのテーブルからユーザーの学歴を表現してみようと思います。
最終卒業の学歴を表すだけでいいのなら、`user`テーブルにカラムを足すだけで解決します。

|id|user|school_history|
|---|---|---|
|1|a|D大学|
|2|b|D大学|
|3|c|C高校|
|4|d|B中学校|

この時、それぞれの`user`が持っている`school`の情報は一つだけです。
`school`からみると、複数のユーザーを持つことができます。

この状態を指して、`school`が親テーブル、`user`が子テーブル、のように「親子関係」と呼びます。

親・・・相手のテーブルに対して複数情報を持つ
子・・・相手のテーブルに対してひとつ情報を持つ

## 多対多の関係
同じ例で、すべての学歴を表現しようとすると

|id|user|school1|school2|school3|school4|
|---|---|---|---|---|---|
|1|a|A小学校|B中学校|C高校|D大学|
|2|b|A小学校|B中学校|D大学|
|3|c|A小学校|B中学校|C高校|
|4|d|B中学校|
こんな感じになります。
カラムが一気に増えましたね。

`user`も複数の`school`を持っていて、
＜aさんはA小学校〜D大学＞
`school`も複数の`user`を持っています。
＜B中学校はaさん、bさん、cさん＞
このような状況を多対多の関係と呼びます。

ここで４年制大学卒業後、更に進学したユーザーを想定すると、さらにカラムが増えます。


|id|user|school1|school2|school3|school4|school5|school6|
|---|---|---|---|---|---|---|---|
|1|a|A小学校|B中学校|C高校|D大学|
|2|b|A小学校|B中学校|D大学|
|3|c|A小学校|B中学校|C高校|
|4|d|B中学校|
|5|e|A小学校|B中学校|C高校|D大学|E大学院|Foreign_University

こうなった場合に、以下の２つの問題が発生してきます。

#####1. 設計時にいくつカラムを用意しておけばいいか、想定が難しい。
 
このやり方では、卒業履歴がどこまで伸びるか完全に想定しきる必要があります。多くの場合、現実的ではありません。

#####2.データが入っていない項目が増えてきた

実際にデータを処理する際に空の情報はエラーの元となります。可能なら扱いたくありません。

## 中間テーブルのススメ
そこで、中間テーブルが大変便利です。
`user`

|id|user|
|---|---|
|1|a|
|2|b|
|3|c|
|4|d|
|〜|〜|

`school`

|id|school|
|---|---|
|1|A小学校|
|2|B中学校|
|3|C高校|
|4|D大学|
|5|E大学院|
|6|Foreign_University|
|〜|〜|


`user_school`　←中間テーブル　new!!

|id|user|school|
|---|---|---|
|1|a|A小学校|
|2|a|B中学校|
|3|a|C高校|
|4|a|D大学|
|5|b|A小学校|
|6|b|B中学校|
|〜|〜|

`user`にカラムを追加するやり方では、空欄たっぷりの表が学校情報の追加に合わせて際限なく伸びていましたが、
`user`と`school`の関係だけを記述していく「中間テーブル」を作成することで
・どちらかのテーブル情報が増えてもカラムを足す必要がない
・不要な空欄の発生が防げる
・中間テーブルを見ることで、それぞれのユーザーの学歴が表現できている

これで、データの種類が増えていく想定まで見越したデータベースが設計できました。




今日はこのあたりで失礼します。

## 


## 参考サイト
【初心者・独学者向け】Ruby On Railsで中間テーブルを作成し、多対多を実現する
https://programming-beginner-zeroichi.jp/articles/25

Rails Guide Active Record の関連付け (アソシエーション)
https://railsguides.jp/association_basics.html
Pepper animationをbehaviorに切り出してAnimated Sayから呼び出す

公式ドキュメントと一部重複する内容になりますが、詳細な利用方法についての投稿が無いようでしたので今回投稿いたします。

#この記事でできること
- Animated Sayボックス１つでアニメーションとスピーチのタイミングや同期をまとめて管理できます。
- アニメーションをビヘイビア名で呼び出して使用することで再利用性/保守性が向上します。

#呼び出すアニメーションを作成する
###アニメーション用ビヘイビアを作成する
プロジェクトファイルウィンドウから「新規Behavior」を選択します。
![behaviorを作成.png](https://qiita-image-store.s3.amazonaws.com/0/308614/6f6f821c-5593-4099-bb4b-9f0c868767df.png)
ビヘイビアの名前を付けます。
ここで付けた名前を使ってアニメーションを呼び出します。
![behaviorを作成2.png](https://qiita-image-store.s3.amazonaws.com/0/308614/82a7c48b-07dd-2ed1-ebcb-ae84c367c26f.png)

###タイムラインボックスを作成する
先ほど作成したビヘイビアにアニメーションを設定するためのタイムラインボックスを作成します。
![タイムラインボックスを作成.png](https://qiita-image-store.s3.amazonaws.com/0/308614/3ca6eaf0-0dcf-2d61-0b0f-2b1e4f259c38.png)
タイムラインボックスの名前に特に決まりはありません。
適当なものを設定します。
![タイムラインボックスを作成2.png](https://qiita-image-store.s3.amazonaws.com/0/308614/cc1c6ed5-536f-e2d2-e1cd-940a31012621.png)

###タイムラインボックスを設定する
他のアニメーションとの競合を防ぐためにリソースの設定が必要です。
タイムラインボックスを右クリックしてリソースの編集を行います。
![タイムラインボックスを設定.png](https://qiita-image-store.s3.amazonaws.com/0/308614/5b6a93ad-de25-f346-11e2-6e900b0dee90.png)
All motorsにチェック。
ボックスの開始時を待機1秒に設定します。
![タイムラインボックスを設定2.png](https://qiita-image-store.s3.amazonaws.com/0/308614/3a377a5f-9672-c31a-d35d-a61e27175318.png)
タイムラインボックスはビヘイビアのRootのStartとStopに接続します。
![タイムラインボックスを設定3.png](https://qiita-image-store.s3.amazonaws.com/0/308614/4e6e6066-1bd8-0204-ad35-9e73271bf4fd.png)
作成したタイムラインボックスで通常通りアニメーションを設定します。
設定はアニメーションのみで、behaviorレイヤーは追加しないでください。

以上で呼び出すアニメーションが作成できました。

#Animated Say から作成したアニメーションを呼び出す
###Animated Sayボックスの作成
メインのビヘイビアに戻り、Animated Sayボックスを作成します。

###作成したアニメーションを呼び出すビヘイビアパス
作成したアニメーションは以下のフォーマットで呼び出すことができます。
```[アプリID]/[作成したアニメーションのビヘイビア名]
```
###Animated Sayボックスの発話テキストからビヘイビアを呼び出す
以下の4つのフォーマットでアニメーションを設定します。

- 喋りながらアニメーションを実行  
```^start([アニメーションのビヘイビアパス])
```
- アニメーションが終了するまで待機  
```^wait([アニメーションのビヘイビアパス])
```
- アニメーションのみ実行（start + wait）  
```^run([アニメーションのビヘイビアパス])
```
- アニメーションを中断  
```^stop([アニメーションのビヘイビアパス])
```

以下の例の場合、手を振り始めると同時に発話を開始し、
発話終了後は手を振るアニメーションが終了するまで待機します。
```^start(animation_sample/shake_right_hand)
こんにちは、Pepperです。
^wait(animation_sample/shake_right_hand)
```
![Animated_Sayの設定.png](https://qiita-image-store.s3.amazonaws.com/0/308614/5e64e530-d2e0-a981-9a68-94053daaca05.png)
※Text EditボックスとAnimated Say Textボックスを利用した例

これで設定完了です。

#アプリをインストールする
この状態で再生ボタンでアプリを実行すると、作成したアニメーションのビヘイビアを呼び出すことができません。
「現在のプロジェクトをロボットにインストール」を実行し、アプリをインストールした後に再生ボタンでアプリを実行します。
![アプリをインストール.png](https://qiita-image-store.s3.amazonaws.com/0/308614/bd415a43-5622-fe66-6cd0-d55224fe80da.png)
Kotlinでソケット通信をするサーバを実装する

# はじめに
サーバ上にデータを渡すとき、ソケットを利用して通信しようとしました。ソケット通信については全くの素人だったので、そのときに重要だなと思ったことをざっくり書いていこうと思います
サンプルコードもありますのでぜひ見てください

# 通信の手順
- ソケットの生成
    - `socket()`
- ソケットの登録
    - `bind()`
- 接続準備
    - `listen()`
    - `java`?`kotlin`?上ではlisten関数が見当たらず、、、
- 接続待機
    - `accept()`
- 送信/受信
    - `read()`
    - `write()`
- 通信の終了
    - `close()`

基本的には、この6手順でソケットの通信が可能となります

# サンプル
ソースコードを見ながら読んでいただけると幸いです
- [tuvy22686/Socket-Server](https://github.com/tuvy22686/Socket-Server)
- [tuvy22686/Socket-Client](https://github.com/tuvy22686/Socket-Client)

# ソケットの生成

```kotlin
val serverSocket = ServerSocket()
```

# ソケットの登録

```kotlin
serverSocket.reuseAddress = true
serverSocket.bind(InetSocketAddress({ポート番号})
```
- １行目について、`reuseAddress=true`にすることで、再度同じポート番号を利用できるようになる。これを指定しないと一定時間(OSによる)そのポート番号がつかえなくなる
- ２行目について、ポート番号を登録している

# 接続待機

```kotlin
val socket: Socket = serverSocket.accept()
```
- 接続要求が来るまで待機する

# 受信
```kotlin
inputStream = socket.getInputStream()
bufferedReader = BufferedReader(InputStreamReader(inputStream))

while (inputStream.available() == 0) {}
val received = bufferedReader.readLine()
```

- while文で書かれている内容について、相手がいつデータを送ってくるかわからない。そのため、`available()==0`の間は待ち受けする必要がある

# 送信
```kotlin
printWriter = PrintWriter(BufferedWriter(OutputStreamWriter(socket.getOutputStream())))
printWriter.println("{送りたい文字列}")
printWriter.flush()
```

# 通信の終了
```
bufferedReader.close()
printWriter.close()
inputStream.close()
socket.close()
```
- クローズしなければ接続したままになる
- クライアント側、サーバ側のどちらかがクローズした場合、ソケット通信が終了する

# さいごに
今回の話とは関係ないのですが、`Thread`を使用しています。初めて使ってみたのですが、実行結果が面白いです
参考までに
<img width="262" alt="スクリーンショット 2018-10-30 18.45.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/209133/549feb68-778d-83a7-b9cd-fd1d91b3c5c0.png">
わかりにくいですが、ログの最後に書かれている数字が1つのThreadとして対応しています。待ち受けた順番と処理が終わった順番が異なっているところがわかります
ってだけです

# 参考
- [コネクション型通信：サーバプログラムの作成](http://research.nii.ac.jp/~ichiro/syspro98/server.html)
- [Java ソケット通信のサンプル](https://itsakura.com/java-socket)
- [知ったかぶりをしていたソケット通信の基礎を改めて学んでみる](https://qiita.com/megadreams14/items/32a3eed4661e55419e1c)
- [Javaでのソケット間通信サンプル](http://www.geocities.jp/xmldtp/jv_sock.htm)
- [Kotlin UDP ソケット通信](https://qiita.com/unpi/items/82385d19d0d973abe459)
- [簡単なソケットプログラミング (Java)](https://www.qoosky.io/techs/f8c35bb5d7)
- [Java Socket Programming Examples](http://cs.lmu.edu/~ray/notes/javanetexamples/)
- [Javaを用いたソケット通信　前編](https://qiita.com/akatsubaki/items/aaca7664c5b881415bf5)
- [ServerSocketクラス](http://java-code.jp/261)
シェルスクリプトの改行コードをCRLFにしてはいけない

ある日を境に、ディレクトリ名やファイル名に「^M」が付くようになった。
^Mは[調べたら](http://www.koikikukan.com/archives/2013/10/15-013333.php)CR（復帰コード）らしい。

このような現象が発生する原因は、ディレクトリやファイルを作成するシェルスクリプトの改行コードがCRLFになっていたからであった。

```
PATH="/var/log/apache2"
sudo mkdir ${PATH}
```

上のシェルスクリプトの改行コードがCRLFだと、作成されるディレクト名は次のようになる。

```shell
apache2^M^M/ 
```

改行コードをLFにしたら治った。


# 蛇足
ラズパイ起動時に/var/log/以下のディレクトリを自動生成させるserviceをsystemdで作成していたが、ある日を境にすべてのserviceのstatusがFAILEDになって動作しなくなった。

syslogを確認しても何のエラーも表示されていない。原因不明で困った。

Apache2も停止していることに気づく。Apache2が停止する原因は経験的にApache2のログファイル格納のためのディレクトリ（/var/log/apache2/）が存在しないことが多かったので、ちゃんとディレクトリが存在するか確認してみた。

```
root@raspberrypi:/# ls /var/log/
apache2??/ apt??/     fsck??/    lightdm??/ samba??/
```

ディレクトリに??が付いている。
Tabキーで予測させてみると以下のようになった。

```shell
root@raspberrypi:/# cd /var/log/(Tabキーを押す)
apache2^M^M/ apt^M^M/     fsck^M^M/    lightdm^M^M/ samba^M^M/
```

^M^Mと表示された。なんだこれは。調べたら改行コードが怪しいと判明する。そして冒頭へ。

どうやらWindowsのエディタでファイルを編集したとき、全ての改行コードがCRLFになっていたらしい。

Windowsで編集するときは気をつけよう。
コミットは怖くない！[取り消し、打ち消し、上書き]

# **最初に**
前回の引き続き、gitコマンドについて書いていきたいと思います。
gitの基礎知識を習得したい方は下記の記事にまとめています。

[初めてのgitは6ステップで完了](https://qiita.com/takuyanin/items/c6a097028a837052c90c)

# **コミットの取り消し**
コミット（セーブポイントを作ること）はしたものの取り消したいこともありますよね。
その時は下記のコマンドを叩けばOK。

```zsh
$ git reset --hard HEAD~
```
ここで下記のオプションが重要になってきます。間違えると大変なことになることもあるので気をつけましょう。

- `--hard`オプション: コミットを取り消した上でワークディレクトリの内容も書き換えたい場合に使用
- `--soft`オプション: ワークディレクトリの内容はそのままでコミットだけを取り消したい場合に使用


そして

```zsh
$ git log
commit 600bbffb4f794bd3930991e3a2eb31c3292f7daa (HEAD -> master, origin/master)
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Mon Oot 29 17:57:24 2018 +0900

    first commit
```

などのコマンドを叩くとよく見かけるHEAD。
`HEAD`は、今自分が作業している場所を示すポインタのこと。

- `HEAD` : 現在のコミット

- `HEAD^`: 直前（一つ前）のコミット

- `HEAD~{n}`: n個直前のコミット
 - `HEAD^`や`HEAD~{n}`の代わりにコミットのハッシュ値を書いても良い。(ハッシュ値とは上記の`git log`コマンド実行結果を参考に説明するとcomiitに後続している50桁ほどの英数字のこと、コミット番号のようなもの)

 - `HEAD~`と`HEAD^`と`@^`は同じ

 - `HEAD~2`と`HEAD~~`と`HEAD^^`と`@^^`は同じ

 - `HEAD~3`と`HEAD~~~`と`HEAD^^^`と`@^^^`は同じ

個人的には、**一番汎用性が高い**`HEAD~`の形を使うようにしています。他は知識として知っておけばいいと思います。

また、`^(キャレット)`の使い所に簡易しては、[こちら](https://backlog.com/ja/git-tutorial/stepup/03/)が参考になります。

# **コミットの打ち消し**
作業ツリーを指定したコミット時点の状態にまで戻しコミットを行う（コミットをなかったことにはせず、**逆向きのコミットをすることで履歴を残す**）には、

```zsh
$ git revert コミットのハッシュ値
```
を叩きます。
例えば、現在のgit logが

```zsh
$ git log
commit 49ac2a1a85840c3f44f827a95c2bf9ed1cfb52b1 (HEAD -> master)
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Tue Oct 30 18:25:51 2018 +0900

    Second commit

commit 600bbffb4f794bd3930991e3a2eb31c3292f7daa (origin/master)
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Tue Oct 30 17:57:24 2018 +0900

    first commit
```
であるとします。
すると`git revert 49ac2a1a85840c3f44f827a95c2bf9ed1cfb52b1`を叩くと、

```zsh
$ git log
commit 4cca74a43c23b13fb86e6f389f46eff5617c5447 (HEAD -> master)
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Tue Oct 30 18:26:52 2018 +0900

    Revert "Second commit"

    This reverts commit 49ac2a1a85840c3f44f827a95c2bf9ed1cfb52b1.

commit 49ac2a1a85840c3f44f827a95c2bf9ed1cfb52b1
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Tue Oct 30 18:25:51 2018 +0900

    Second commit

commit 600bbffb4f794bd3930991e3a2eb31c3292f7daa (origin/master)
Author: Furukawa Takuya <hogehoge@gmail.com>
Date:   Tue Oct 30 17:57:24 2018 +0900

    first commit
```

となり、過去のコミット履歴が消えることはありません。

# **コミットの上書き**

```zsh
$ git commit --amend
```

こちらのコマンドにより直前のコミットを上書きすることができます。
コミットをして次のコミットをするまでの間に微調整を加える必要性が生じた時などに重宝します。
また、コミットメッセージを変更したい時などにもよく使います。

# **関連記事**
[初めてのgitは6ステップで完了](https://qiita.com/takuyanin/items/c6a097028a837052c90c)


#**終わりに**
コミットの修正方法などについて書きました。よくある誤解として、commitしたら、その次はpushいなければいけないというものがありますが、commitをいくつか溜めたのちにpushすることも可能ですので、キリの良いところでこまめにコミットしていくことをお勧めします（そして、わかりやすい名前をつけましょう）。
fortranで文字列の配列を返す関数

fortranで文字列の配列を返すような関数を書こうと思ったら少し詰まったのでメモ。
コンパイラはgfortran
そもそもfortranで文字列の配列を宣言するのがちょっとめんどくさく

```fortran
character(10,3) strings
character,dimension(10,3) strings
```
なんてのがうまく通らなかったりした。結局文字列の配列は

```fortran
character*3 strings(10)
```

なんてので宣言できるんだが、これを返り値にしようとしたら、また一苦労。というのも、Cとかそのたぐいから入った人間なので

```fortran
integer function hoge()
      hogehoge
end function
```

みたいな形式しか知らず、この通りにさっきの型宣言を当てはめた

```fortran
character*3(10) function hoge()
end function
```

なんてのは当然通らないわけだ。これを解決するのが、関数内で関数の型を宣言する方法で、

```fortran
function hoge()
      implicit none
      character*3 hoge(10)
       ・・・・・・・
end function
```

とすれば関数の返り値を宣言できる。そしてメインプログラム内で使おうと思ったその時、更に壁が…
当然メイン内で関数の型を宣言しなくてはならぬのだ。
fortranは正直新しい情報をネットで見つけるのも一苦労で、externalで引用しようとしたが、やはりあの型の書き方だとうまくいかない。どうするかというと

```fortran
interface
      function hoge()
                  character*3 hoge(10)
      end function
end interface
```

をメインプログラム内にかく。このinterface宣言、引数の型も決めることができるので、現代はこっちが使われて、externalはむしろ仕様非推奨だそうだ。



fortranは後方互換性を切らないのは利点でもあるが、仕様やらなんやらが混在した闇のプログラムみたいなのが存在するのがなかなかに厳しい。特にimplicitまみれは…辛い…
【はじめてのMySQL】初心者がDB構築しながら調べたコマンド一覧

#はじめに

RDSでDBを構築することになったので、わからない・知らないコマンドを記載します。
EC2からRDSに接続→DB、テーブルを作成しデータの登録→確認。。の順序で都度調べたコマンドを並べています。

#環境
EC2インスタンスと同じセキュリティグループに構築したRDS（構築手順を記した記事を作成中です）
CentOS 7.5
MySQL 5.7.24

#コマンド一覧
##バージョン確認
```
$ mysqld --version
mysqld  Ver 5.7.24 for Linux on x86_64 (MySQL Community Server (GPL))
```

##RDSに接続

```
$ mysql -h エンドポイント -P ポート番号 -u ユーザ名 -p DB名
```

##DBとテーブルの新規作成、データの確認
```
・DB新規作成
mysql> create database データベース名; 
```

```
・テーブル新規作成①
mysql> create table; 
```

```
・テストデータ投入してselect文でデータの確認
mysql> start transaction;
mysql> insert into テーブル名(列名) values(値); 
       #例：values(01, '列名')

mysql> select 列名1,列名2 from テーブル名;
+-----------+-------------+
| 列名1      | 列名2       |
+-----------+-------------+
|        01 | 列名        |
+-----------+-------------+
1 row in set (0.00 sec) 

mysql> commit;
Query OK, 0 rows affected (0.01 sec)
#このコマンドの意味がまだよくわかってません。。
```

```
・テーブル新規作成② カラム、データ型、NotNull、ストレージエンジン、文字コードの指定＆主キーの設定
mysql> create table テーブル名 (
  column1 bigint(20) not null ,
  column2 int not null ,
  column3 varchar2(255) ,
  primary key (`column1`, `column2`) #左記のように主キーの複数指定が可能
)engine=innoDB default charset=utf8;
```

##DB、テーブル、カラムの検索

```
・DB一覧
mysql> show databases; 
```

```
・テーブル一覧
mysql> show tables; 

・DBの変更
mysql> use DB名 
```

```
・カラム一覧
mysql> desc テーブル名; 
```

##テーブルとデータの削除
```
・テーブルに格納されているデータをすべて削除
mysql> delete from テーブル名;
```

```
・テーブルの削除
mysql> drop table テーブル名;
```

```
・接続中のDBを表示
mysql> select database();
```

##テーブル名の変更
```
rename table 変更前のテーブル名 to 変更後のテーブル名;
```

##ユーザ作成
```
create user 'ユーザ名' identified by 'パスワード';
```


#参考書籍
[SQL 第2版 ゼロからはじめるデータベース操作 (プログラミング学習シリーズ)](https://www.amazon.co.jp/SQL-%E7%AC%AC2%E7%89%88-%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%93%8D%E4%BD%9C-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AD%A6%E7%BF%92%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798144452/ref=sr_1_4?ie=UTF8&qid=1542178500&sr=8-4&keywords=sql)
（QA）SAPー収録

#ABAP関連ホームページ
- [ABAP 入門 ](https://help.sap.com/doc/saphelp_nw70/7.0.12/ja-JP/54/57fe06786a11d194c90000e8353423/content.htm?no_cache=true)

- [SAP ABAP Tutorial](https://www.tutorialspoint.com/sap_abap)
- [baidusap](http://www.baidusap.com/abap/dialog/1516)

- [SAP Integration Hub](https://sapintegrationhub.com/abap/)
- [sap ecc 専門サイト](http://sapecc.insidekb.jp/doku.php/96/start)
- [sapyard](https://sapyard.com)
- [BPマスター](http://www.saphanacentral.com/2018/03/business-partner-in-s4-hana-customer.html?m=1)
#開発技術備考
## REPORT
- Q:どうやって特定な「ディクショナリ：ドメイン」の範囲構造を探しますか？
- A：Tr-Cd(SE11)で見つかった「例：会社コード（BUKRS）」

- Q:チェックボックスに対してはどのようにレベルを前へ挿せますか？
- A：デフォルトには

```ruby:ABAP
************************************************************************
* 前：チェックボックス　後：レベル
************************************************************************
PARAMETERS :
  P_AP AS CHECKBOX.

************************************************************************
* 前：レベル　後：チェックボックス
************************************************************************
SELECTION-SCREEN BEGIN OF LINE.

SELECTION-SCREEN COMMENT 1(14) TEXT-001.
SELECTION-SCREEN POSITION 33.
PARAMETERS :
  P_AP AS CHECKBOX."APサーバ

SELECTION-SCREEN END OF LINE.


```


## SMARTFORM
- Q:グループ単位で出力すると共に最後ページに契約情報のような固定テキストも出力できる機能の実装？
- A:SMARTFORMにグループの最後ページになったら、以下
→条件：SFSY-PAGE=SFSY-FORMPAGES
→タイプ：最後ページ

②CONTROLは以下のような制御にすること。
→

| NO_OPEN | NO_CLOSE |
|:-:|:-:|
|   | X |
| X | X |
| X | X |
| X |   |

#FI（財務モジュール）    
Q:「勘定●●●に割り当てられた明細カテゴリはありません」とは原因は何ですか？
A:
方案１
パス：SAPカスタマイジンングの導入ガイド（IMG）-財務会計（新規）ー総勘定元帳（新）ー取引ー分割ー分類：分割のG／L勘定
方案２
パス：SAPカスタマイジンングの導入ガイド（IMG）-財務会計（新規）ー総勘定元帳（新）ー取引ー分割ー有効化：分割
#移行
Q:ECC→HANAの差異点はどちらか？
A:
　- MATNR桁数→40桁
　- 無効TrCd：FD01,FK01

Q：ECC→HANAで得意先と仕入先の削除と復活の切り替え方法
[SAPのアドバイス](https://blogs.sap.com/2016/06/27/how-to-mark-business-partners-for-deletion-in-s4-hana/)

#外部技術連携
##Excel等のVBA
- [汎用モジュール実行](http://metro3.web.fc2.com/r3/excel1.html)
※sap analysis for officeで代わるかも
Git-flowを用いた開発のおぼえがき

# はじめに

エンジニアとして採用してもらって1ヶ月…やっとそれっぽい仕事をさせてもらえるようになりました。
Git-flowを用いて開発を進めているということなので、個人の備忘録もかねてよく使うコマンドや開発の流れをおぼえがきとしてまとめます。
できることが増えてきたら随時追加していきたい。
（というのを書いて1ヶ月くらい下書きで寝かせてありました…）

# Git-flowを用いた開発

今は機能の追加や改修をメインで作業しているので、5種類あるブランチのうち、主に使うのはdevelopとfeatureブランチとなります。

- master
  - 本番で稼働しているアプリケーションのコード
  - releaseブランチからしかマージされない
- develop
  - 開発環境
  - ここからfeatureブランチを切って作業する
- release
  - リリースのための準備ブランチ
- feature
  - 機能追加や修正ごとにdevelopブランチから切って作業する
  - 作業完了・レビューOKならdevelopブランチへマージされる
- hotfix
  - 緊急対応・バグ修正用
  - masterブランチから切って作業する

# 開発の流れ

## 導入
導入については駆け足だったのでほとんど覚えてないのです（すみません）

- Git-flowを入れて

```bash
$ brew install git-flow
```
- リポジトリをクローン

```bash
$ git clone git@github.com:xxx/xxxxxxxx.git
```
は、やりました。


## 開発作業開始

自社システムの機能の追加や改修をメインでやっています。
渡されたタスクごとにfeatureブランチをdevelopブランチから切って進めていきます。

## developブランチからfeatureブランチを作成

### 現在のブランチ確認

```bash
$ git branch
```
*が付いているのが現在のブランチ

```bash
$ git branch -a
```
とするとリモートのブランチも確認できます。

### ブランチの切り替え

```bash
$ git checkout <ブランチ名>
```
違うブランチにいたらdevelopへ移動します。

### リモートから最新のデータをPull

```bash
$ git pull origin develop
```
ローカルよりリモートが進んでいて新しいブランチが作れなかった時がありました。
（上記コマンド実行で解決）

```
Branches 'develop' and 'origin/develop' have diverged.
And branch 'develop' may be fast-forwarded.
```

### featureブランチの作成

```bash
$ git flow feature start <ブランチ名>
```
現環境ではタスクごとに番号が振られているのでその番号をブランチ名として作成します。

ブランチを作成したら早速開発に取り掛かります！（たのしい）

## ファイルの追加とコミット

開発が一区切りしたらこまめにコミットします。
コミットの粒度に気をつけて…ってそんなに大きな単位の作業はしていませんが、メッセージが一行で簡潔に書けるくらいを意識しています。

```bash
$ git add .
$ git commit -m "コミットメッセージ"
```
### ステータスの確認

ファイルの変更状況やコミット状況など確認できます。

```bash
$ git status
```

### コミットメッセージの修正

一旦コミットした後にメッセージを修正したいことがありました。。
（そしてvimで開いて焦る）

```bash
$ git commit --amend
#もしくは
$ git commit --amend -m "変更したいコミットメッセージ"
```
vimで修正する場合

- h：左に移動
- j：下に移動
- k：上に移動
- l：右に移動
- x：削除
- ZZ：上書きしてエディタ終了

## リモートへpush

開発が終わったらリモートへpushします。

```bash
$ git push -u origin feature/<ブランチ名>
```
`-u`はつけてもつけなくてもいいですが、つけておくと修正が入って再度pushするときに

```bash
$ git push
```
だけで同じブランチにpushすることができるそう。

参考：[git push -u オプションで”上流ブランチ”を設定 | WWWクリエイターズ](http://www-creators.com/archives/5204)


## プルリクエスト作成

何をやったか、必要ならMarkdownを使いながら相手にわかりやすいよう書きます。

## レビューを経てマージ

プルリクエストを作成したらレビューをしてもらい、修正があれば修正してファイルの追加とコミットから再度行います。
LGTMを頂いたらマージします（developへマージされる）。

# おわりに

勉強でオリジナルアプリを開発していた時はGitHub DesktopというGUIツールを使っていたのですが、今は色々覚えるべくコマンドでGitを使うことを心がけていますがなかなか難しいですね。
下書きの時点での現場は上司が不在（いるけどいない）、同僚もいないので一人寂しくあれこれ調べながら奮闘しておりましたが、この度チーム開発できる現場に行けそうなのでまた心機一転頑張りたい！と思って下書きのまま眠っていたこの記事を投稿してみました。
shell の while read で -r を付与して \（バックスラッシュ）によるクォートを防止する。


珍しくOracle Database以外のネタ、shell の while read に -r を付与して、
\（バックスラッシュ）によるクォートを防止してみるやで。彡(ﾟ)(ﾟ)

# 1. テスト用 の shell script

data.txt の内容を1行ずつ出力する単純なシェルです。

```shell

while_read.sh

#!/bin/bash

CNT=0;
cat data.txt | while read line
do
  CNT=`expr ${CNT} + 1`;
  echo "${CNT}:${line}";
done;
```

# 2. テストデータ（data.txt）

テストデータの中身です。
1行目の最終文字が\（バックスラッシュ）です。

```shell
cat data.txt

iii\
jjj
kkk
```

# 3. テスト用 shell script の実行結果

この状態での実行結果は下記の通りです。1行目の最終文字の
\（バックスラッシュ）で改行がクォートされてしまうため、
1行目と2行目が繋がって出力されてしまいますやね彡(ﾟ)(ﾟ)

```shell
./while_read.sh

1:iiijjj
2:kkk
```

# 4. read に -r を付与して実行

read に -r を付与して shell script を実行してみます。
改行がクォートされず、3行出力されましたやね彡(^)(^)

```shell
cat while_read.sh

#!/bin/bash

CNT=0;
cat data.txt | while read -r line
do
  CNT=`expr ${CNT} + 1`;
  echo "${CNT}:${line}";
done;

./while_read.sh

1:iii\
2:jjj
3:kkk
```

# 5. 参考

read コマンドの使い方 - 拡張 POSIX
シェルスクリプト Advent Calendar 2013 - ダメ出し Blog
https://fumiyas.github.io/2013/12/14/read.sh-advent-calendar.html
paizaで知った入力ファイルの取り方（Rubyで実装）

どうも，院生へなちょこプログラマーです．

今回は読み込んだファイルの扱い方についてです．

最近まで恥ずかしながら，
企業で実施されるWebテストでよくみる入力ファイルの読み込みで詰まっていました．

#読み込むデータについて
よくみる問題で渡されるデータがこちら．
><img width="727" alt="スクリーンショット 2018-10-30 17.56.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/299984/48bbd84f-621d-ff47-d92e-1fe60fc07e67.png">
https://paiza.jp/

上記のファイルを読み取る方法がよくわからなかったので，
調べて気づいたことをメモ書きいたします．

#paizaのサンプルコード

```paiza.rb
input_lines = gets.to_i
input_lines.times {
  s = gets.chomp.split(",")
  print "hello = ",s[0]," , world = ",s[1],"\n"
}
```

これを見た当時の僕
:値は配列で入っているのかな？
:そうであるなら改行とか空白はどうなるの？

getsを調べないとわからないなと思い，調べていくと少しづつわかってきた．

#結論
getsは一列目のデータを得る．
例えばサンプルであるならば，

```paiza.rb
#input_lines = 2　という１行目のデータが入る
input_lines = gets.to_i
 
#実際は 2.timesになっている
input_lines.times {　
　#sに２と５を配列で格納する(splitで,を消して分ける)
  s = gets.chomp.split(",")
  #s[0]には2,s[1]には5が入っているわけである
  print "hello = ",s[0]," , world = ",s[1],"\n"
}
```

コメントに記載した通り，上記のようになる．

#一言
paizaで勉強する際にはこの知識は前提ですね．
また，企業のWebテストを受ける前に必ず知っておくべきことだと思うので，
受ける際には，練習問題をやっておくことをお勧めします．
（筆者は練習も何もせず受けて，ぼこられました・・・）

最後に，「getsの考え方間違っているよ！」とか
「データの取り方はこれが便利だよ」とか
アドバイス等あれば，コメントよろしくお願いします！
abc105 D map 累積mod

```
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
#include<cmath>
using namespace std;
using ll = long long;
int main() {
	ll N;
	cin >> N;
	ll sum = 0;
	vector<int>V;
	for (int i = 0; i < 100; ++i) {
		for (int j = 0; j <= 1; ++j) {
			if (j == 0) {
				sum += pow(-2, i);
				V[i] = 1;
			}
			else {
				V[i] = 0;
			}
			if (sum == N) {
				break;
			}
		}
	}
	reverse(V.begin(), V.end());
	for (int i = 0; i < V.size(); ++i) {
		cout << V[i];
	}
	return 0;
}
```
えーなんで違うのー

C++では、

17を 5で割ったあまりは 2
−17を5で割ったあまりはマイナスをつけて−2

2 進法展開や 10 進法展開なら ここ に書いた通り。-2 進法になってもそう大差ない基本的には Nを -2 で割って、割ったあまりを答えに追加していくような感じです。-2 で割るとはどういうことかもう少し掘り下げてみます:N=(−2)q+rとしたときに、r
 が 0 か 1 になるようにqを調節するということになります。これ実はNが偶数なら r=0　
Nが奇数ならr=1とすればよいという感じなので、実は 
N
を単に 2 で割るのと変わらないです。ただし、ここに書いた通り、
N
 が負の数のとき
N% 2 の値は 0 か -1 になってしまうので、-1 になるならそれに 2 を足す
という風にする必要があります。

```
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
#include<cmath>
using namespace std;
using ll = long long;
int main() {
	int N;
	cin >> N;
	string str = "";
	while (N != 0) {
		int r = N % 2;
		if (r < 0)r += 2;
		N = (N - r) / (-2);
		str += (char)('0' + r);
	}
	reverse(str.begin(), str.end());
	if (str == "")str = "0";
	cout << str << endl;
	return 0;
}
```
D
数列Aが与えられる。閉区間[Al,Al+1,,,,Ar]の和がMの倍数になる区間の個数を求めよ
数列Aに対し、Aの先頭I項の和をBiとする。なお、便宜上B0=0としておく。
いま、Al+....+Ar=Br-Bl-1であり、Al+..+ArがMの倍数であることはBr,Rl-1をMで割ったあまりが等しいことと同値です。よって数えるべきはBi,Bjがmod Mで等しいような0<=I<=j<=Nの組の個数です。これは各x=0,,,M-1についてBiをMで割ったあまりがxであるようなIの個数を求めておくことで計算可能です。
（メモ）Gradleの力を借りて依存するライブラリのjarを一式取得する


いろいろな理由（）でGradleを使ってプロジェクトがビルドできないときに、予めGradleを用いて依存ライブラリ一式をまるっと手に入れる方法。

適当なJavaのGradleプロジェクトを作成してdependenciesとtaskを書くだけです。

サンプルはJasperReportsと専用のiText（とそれらが依存するライブラリ）を指定しています。

```groovy:build.gradle
plugins {
    id 'java'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral artifactUrls: [
        'http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts/'
    ]
}

configurations {
    // プロジェクトをビルドすることはないので、依存していることだけを示すconfiguration
    dependentLib
}

dependencies {
    dependentLib 'net.sf.jasperreports:jasperreports:6.6.0'
    dependentLib 'com.lowagie:itext:2.1.7.js6'
}

// 依存ライブラリーをコピーするtask
task ('copyLib', type: Copy) {
    from configurations.dependentLib
    into 'build/lib'
}
```

あとはgradlew copyLibでjar一式が得られます。
python3でcsvからjsonに変換する

# 目的
react(javascript)でcsvを扱うスマートな方法がなかったので、扱うcsvファイルをjsonに変換した時のめも。

具体的には[全国の駅情報](http://www.ekidata.jp/dl/)で落としたstation20180330free.csvというファイルの中身を読みたかった。
中身はこんな感じ↓

```station20180330free.csv
station_cd,station_g_cd,station_name,station_name_k,station_name_r,line_cd,pref_cd,post,add,lon,lat,open_ymd,close_ymd,e_status,e_sort
1110101,1110101,函館,,,11101,1,040-0063,北海道函館市若松町１２-１３,140.726413,41.773709,1902-12-10,,0,1110101
1110102,1110102,五稜郭,,,11101,1,041-0813,函館市亀田本町,140.733539,41.803557,,,0,1110102
1110103,1110103,桔梗,,,11101,1,041-0801,北海道函館市桔梗３丁目４１-３６,140.722952,41.846457,1902-12-10,,0,1110103
...
...

```

これを↓の感じにしたい

```station20180330free.json
[
 {
  "station_cd" : 1110101,
  "station_g_cd" : 1110101,
  ...
 },
  ...
]
```


pandas使えないよって人は↓
python3系入って入ればあるはず
https://qiita.com/Umibows/items/4a2ea0f3cc88efa877b2

# やったこと
csvファイル読み出し→連想配列に書き換え→ファイルにかく

かなりてきとーに書いたが以下の処理でやりたいことはできた。
ちょっとハマったとこめも。
・dict()は連想配列にしてくれるが、まさかの順番を維持してくれないという仕様(ver. 3.5)。
・station_hash = data_hash.copy()としないとだめ(station_hash = data_hash　ではだめ)
・'utf-8'指定しないと文字化ける



```csv2json.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import json
import codecs

stations = pd.read_csv('lib/station20180330free.csv')
columns = stations.columns  # header情報

data_list = []
for column in columns:
    data_list.append([column, ''])
data_hash = dict(data_list) # 各station dataのhashの雛形

stations_json = []
for station in np.array(stations):
    station_hash = data_hash.copy()
    for i in range(columns.size):
        station_hash[columns[i]] = station[i]
    stations_json.append(station_hash)


f = codecs.open('lib/station20180330free.json', 'w', 'utf-8')
json.dump(stations_json, f, indent=4, ensure_ascii=False)
f.close
```

for文を使いまくってるのはナンセンスだが、そんなでかいデータでもなかったしまあいいか。
chromeでprint-to-pdfのフッターが消せなくて困った

# フッターを消すオプションが無いっぽい

```zsh
chrome --disable-crash-reporter --disable-gpu --headless --print-to-pdf=xxx.pdf https://xxx.xxx.xxx
```

HTMLの適当な位置に`<footer>`タグを入れてcssで白帯にして回避。

```scss
    /* デフォルトのフッターを塗り潰す用 */
    footer {
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 4em;
        content:  '';
        background-color: white;
        z-index: -1;
    }
```

`displayHeaderFooter`とか`headerTemplate`、`footerTemplate`のオプションついてくれないかな...
https://cs.chromium.org/chromium/src/headless/app/headless_shell_switches.cc
Vue スタイルガイドに当てはまらないが、合理的だと思われるスタイル

Vue には公式スタイルガイドがある。スタイルガイドとはコーディングのスタイルのガイドだ。例えば具体的には、キャメルケースなのかケバブケースなのか、といったことがある。

https://vuejs.org/v2/style-guide/

しかし、公式スタイルガイドでは不便なところがあるので、今回のスタイルを提案したい。
以下のコードのようになる。

```vue:App.vue
<template>
  <div id="app">
    <HelloWorld 
      :superValue="'test value'"
      :IDTest="10101"
    />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld
  }
};
</script>

<style>
</style>
```

```vue:HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ superValue }} {{ IDTest }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: { superValue: String, IDTest: Number},
  data() {
    return {
      msg: "Welcome to Your Vue.js App"
    };
  }
};
</script>

<style scoped>
</style>

```

以下二つの項目について検討したい。

こちらは公式と同じスタイルを本記事でも採用した。
https://vuejs.org/v2/style-guide/#Component-name-casing-in-templates-strongly-recommended

こちらは本記事では異なるスタイルを採用した。
https://vuejs.org/v2/style-guide/#Prop-name-casing-strongly-recommended

## Component の名称のケーシングについて
https://vuejs.org/v2/style-guide/#Component-name-casing-in-templates-strongly-recommended

Single File Component では `<HelloWorld/>` というケバブケース以外のものを使っていい。これは公式通りである。

## props の名称のケーシングについて
https://vuejs.org/v2/style-guide/#Prop-name-casing-strongly-recommended

強い推奨の項目だが、本記事では採用しなかった。

公式スタイルガイドでは以下のように書くことになる。受ける側は公式通りである。
直感的にわかると思うが、この場合、ハイフンが増える。

```vue
<HelloWorld 
   :super-value="'test value'"
   :i-d-test="10101"
/>
```

```vue
<script>
export default {
  name: "HelloWorld",
  props: { superValue: String, IDTest: Number},
};
</script>
```

これを本記事ではこうすることを提唱したい。このスタイルは React, JSX と同じスタイルで、Vue でも問題なく動作する。

```vue
<HelloWorld 
    :superValue="'test value'"
    :IDTest="10101"
/>
```

## このスタイルの合理性について

まず JavaScript と HTML の name casing について検討したい。

JavaScript においては、変数名は基本的にキャメルケース (`const camleCase`) である。クラスの場合には、先頭が大文字のキャメルケースになる `class CamelCase {}`

コンポーネントは Class 扱いされているのか、Vue においても React においても、先頭が大文字のキャメルケースになる `<CamelCase/>`

問題は props である、React では基本的にキャメルケースだが、Vue スタイルガイドではケバブケースである。しかし、受け取るときにはどちらもキャメルケースである。

ケバブケースにすることによって、props を変数とは別のケーシングに書き換える手間が多く発生する。これが必要がない、という合理性がキャメルエースにはある。
instagram developerのclientの新規登録時に「入力されたキャプチャが間違っています。もう一度実行してください。」「Submission error: please fill out all required fields.」のエラーで登録できない問題の解決方法

instagramの投稿写真をWebサイト内に埋め込むために、「instagram developer」にて、Instagram APIのアクセストークンを発行する際に必要な、clientの登録ができず困っておりました。必要項目を入力しても、

>入力されたキャプチャが間違っています。もう一度実行してください。
>Submission error: please fill out all required fields.

とエラー表示され一向に登録されません。

ネットで情報を調べたところ、同様の不具合に悩んでいる方が多いのですが、
ブラウザにてエラーが出ており、「reCAPTCHA」絡みの問題のようです。

ブラウザの種類やバージョンによってうまくいくようなのですが、
Macやwindows、Google chrome／safari／Opera／Firefox／Edge／Android Browserのどれを試してもだめでした。
具体的な解決策はすぐには見つかりませんでしたが、英語のサイトで解決策がありました。

下記のGoogle Chromeの拡張機能をインストールし、
https://chrome.google.com/webstore/detail/disable-content-security/ieelmcmcagommplceebfedjlakkhpden
この機能を該当タブで有効化すれば、うまくいきました。

この不具合だいぶ放置されているみたいですが、なぜ修正をおこなってくれないのでしょうか。。。
npx で実行するか npm scripts で実行するかで glob パスの解釈が違う

自分が困ったので、備忘録として残す。

node_modules/ 内のモジュールを実行する際、対象ファイルの指定をマルチパス形式で「〜ディレクトリ配下すべて」と記述すると、npx と npm scripts で処理対象となるファイルが異なる。
（※今回はstylelintを例に説明）

## 事象
```package.json
"scripts" : {
  "stylelint": "stylelint resources/assets/sass/test/**/*.scss",
}
```

上記npm scriptsを用意した状態で実行する `npm run stylelint` と
`npx stylelint resources/assets/sass/test/**/*.scss` で、処理対象となるファイルに違いが出た。
npx はディレクトリを再帰的に掘って走査してくれるが、npm scripts では第一階層しか探してくれない。

これを、npm scripts でも配下すべてのディレクトリを再帰的に走査するようにしたい。

※再現環境
macOS 10.14
Node.js 10.9.0
npm 6.2.0

## 解決方法
パスをシングルクォーテーションで囲む。
つまり、以下のように記述する。

```package.json
"scripts" : {
  "stylelint": "stylelint 'resources/assets/sass/test/**/*.scss'",
}
```

## 事象の再現・調査
最初にキックされるJSファイルに console.log を仕込み、実際に対象になっているファイルの規則性を確かめる。

```node_modules/stylelint/bin/stylelint.js
#!/usr/bin/env node

"use strict";

console.log(process.argv); // この１行を追加

require("../lib/cli")(process.argv.slice(2));
```

この状態でそれぞれコマンドを叩き、結果を比較する。

↓出力結果（npm scripts）

```
npm run stylelint
> @ stylelint /Users/[プロジェクトディレクトリまでのフルパス]
> stylelint resources/assets/sass/test/**/*.scss

[ '/Users/[ユーザ名]/.nodebrew/node/v10.9.0/bin/node',
  '/Users/[プロジェクトディレクトリまでのフルパス]/node_modules/.bin/stylelint',
  'resources/assets/sass/test/pages/_style.4.scss',
  'resources/assets/sass/test/settings/_style.5.scss',
  'resources/assets/sass/test/settings/_style.6.scss' ]
```

↓出力結果（npx）

```
npx stylelint resources/assets/sass/test/**/*.scss
[ '/Users/[ユーザ名]/.nodebrew/node/v10.9.0/bin/node',
  '/Users/[プロジェクトディレクトリまでのフルパス]/node_modules/.bin/stylelint',
  'resources/assets/sass/test/_style.scss',
  'resources/assets/sass/test/pages/1/_style.1.scss',
  'resources/assets/sass/test/pages/2/2-1/_style.2.scss',
  'resources/assets/sass/test/pages/2/_style.3.scss',
  'resources/assets/sass/test/pages/_style.4.scss',
  'resources/assets/sass/test/settings/_style.5.scss',
  'resources/assets/sass/test/settings/_style.6.scss' ]
```

対象となるファイルに違いがあることが判明した。

## まとめ
- 勉強不足で Node.js の中の仕組みに詳しくなく、どうしてこうなるのかまではまだ理解できていません。。分かり次第追記したいと思います。
- 同じJSがキックされているのに解釈が違うので、stylelint 以外のnpmモジュールでも再現します。
- 学びとしては「npm scripts の中に書くパスはシングルクォーテーションでくくったほうが無難」という小さな内容ですが、気をつけていきたいです。
【WinActor】ブラウザの画面遷移時の初期処理

Yahoo!路線検索で路線検索実行後の画面でテキストを取得したい場合に、うまく取得できないことがよくありました。
それを回避する方法をメモしておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/bca925c7-5842-ecdc-9676-a194b40fba50.png)

##実装方法
###①「ウインドウ識別クリア」を実行
参考サイト
http://www.matchcontact.net/winactor_jp/faq.asp?faqno=JPN00214&sugtype=3

>WinActorはウィンドウ識別に合致するウィンドウ情報をキャッシュとして保持しています。
今回そのキャッシュ情報の更新タイミング(※)とウィンドウ情報の参照タイミングが合わなかったため、古いウィンドウ情報を参照してしまったと考えます。

とあり、前のキャッシュ情報で参照しにいって識別失敗することがあるようです。
なので、前のキャッシュ情報をクリアする処理を挟んだほうがよさそうです。

###②IE操作（読込完了待ち）を実行
画面を完全に読み込んだ後に画面要素をつかみたいので、「IE操作（読込完了待ち）」アクションを入れます。
これをしないと、↓のようなエラーが出ることがあり、動作が安定しません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/423127b9-923e-deb9-fa2b-70835a1d18e1.png)

##まとめ
画面遷移時は、初期処理として「ウインドウ識別クリア」「IE操作（読込完了待ち）」を入れておくと動作が安定します。
ローカル開発環境を用いたプログラミングの始め方とやめ方(Windows版)

プログラミングをするにあたって必要になってくるのが、**ローカル開発環境**。
自分で作った環境でプログラムを書くことができる。
インストールや各設定を行って構築をした後に
「どうやって始めればいいの？」
「やめる時にはどうすればいいの？」
といった疑問が生じて、調べてみました。

### ＊ 参考
[ローカル開発環境の構築[Windows編] ~ ドットインストール](https://dotinstall.com/lessons/basic_localdev_win_v2)


### ○ 始め方
まず、*Windows Power Shell* を開き、
```zsh
$ cd MyVagrant
$ cd MyCentOS
```
として、自分のローカル開発環境のファイルまでいく。その後、
```zsh
$ vagrant up
```
少し時間がかかるが、立ち上がる。

そうすれば、*putty* で仮想マシンにログインできるようになる。
*MyCentOS* をロードし、ログイン名、パスワード名を立ち上げてログインしてください。
(初期設定ではどちらも*vagrant*)

これで、自分で書いたプログラムの内容をブラウザに表示できる。
*cyberduck* を立ち上げてそこからファイルを開き、テキストエディタ(*VSCode, Atom*など)でゴリゴリ作業してください。

**＊補足**
*Windows Power Shell*：仮想マシンを外から*vagrant*コマンドで操作する。
*putty*：仮想マシンにログインして仮想マシンの中の処理をする。


### 止め方
ブラウザ、テキストエディタ、*cyberduck*はそのまま閉じてOK。
基本的には、始め方と逆のことをする。
*putty*で、
```
ctrl+c
```
として、今行っている作業を中止させる。
その後、
```zsh
$ exit
```
とすれば、*putty*が正常に終了する。
最後に、*Windows Power Shell* で、
```zsh
$ cd MyVagrant
$ cd MyCentOS
```
として、自分のローカル開発環境のファイルまで行き、
```zsh
$ vagrant suspend
```
で仮想マシンの動作を停止させられる。

これらの作業をせずにパソコンを閉じてしまっても、深刻な問題にはなりません。
ただ、毎回そのまま閉じているとパソコンに不具合が生じることも。
忘れずに行ってください。
【WinActor】アプリケーション操作前の初期処理

動作確認中によく起こっていた事象ですが、IEを起動する際に以下のようなエラーが出て怒られるケースが頻発しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/09cacdbf-ea10-9afc-d67e-d9948668b563.png)

何とかならないものかと試行錯誤した結果、IE起動前にIEプロセスを強制終了することにしました。
コマンドラインから以下コマンドを実行すれば良いです。

```
/c taskkill /im iexplore.exe /F
```

上記コマンドを**「コマンド実行」**というライブラリで実行するように実装してあげたらOKです。
コマンド欄には「cmd.exe」
オプションには先ほどのコマンドを設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/1e284b16-c7b5-7379-b81d-f2d90642311c.png)

ただ、プロセス強制終了後にIE起動してもたま～に実行エラーになるので、
念のため、以下のように例外処理フローに盛り込んでしまったほうが良いかもしれません。
ここでは、実行エラーの場合は5秒ほど待ってから再度プロセス強制終了⇒IE起動を実行するよう実装しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/40ea9ba3-22b4-d531-8e4e-dbb1e561bac6.png)

##まとめ
ロボットが操作するアプリケーションは、操作前に初期状態（プロセスを切る、ブラウザを再起動する等）に戻すこと。
3行でわかるKotlin v1.2.71からv1.3.0へのアップデート方法

# Android Gradle Pluginのバージョンを3.3.0-beta01にあげる
<img width="485" alt="スクリーンショット 2018-10-30 17.01.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/a519a776-3db4-5bf1-19b0-740c08ada03c.png">


任意のプロジェクト開くとダイアログが出てくる（はず
出てこない場合はAndroid Studioを再起動 or 最新版のAndroid Studioを取ってくると出てくる（はず

# kotlinのVersionをv1.2.71からv1.3.0に書き換えてSyncする

```groovy:build.gradle
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
-       classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.71" //削除
+       classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0"  //追加
        ...
    }
}
```

# Kotlin Migrationのダイアログから `Run migrations`を実行する
<img width="388" alt="スクリーンショット 2018-10-30 17.05.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/64d866a6-b578-b487-b657-1a939d776bcd.png">

# おわり！
なお、この手順は2018/10/30時点のものです
scrapyがpython3.7環境で動くようになったよ

3ヶ月ほど前、python3.7環境で動かした際に、下記参考ページに記載されているようなエラーが発生しました。
参考ページのリンク先にも説明がある通り、twistedがpython3.7に対応していないためのようです。

[[Python]Scrapyを動かした時にSyntaxError: invalid syntaxとエラーが出る場合の対処法](https://code-schools.com/python-scrapy-error/)


## 2018-10-10にtwistedがpython3.7に対応
めでたく、`2018-10-10`に、twistedがpython3.7に対応しました。

> Python 3.7 is now supported. (#9502)

[twisted/NEWS.rst at twisted-18.9.0 · twisted/twisted](https://github.com/twisted/twisted/blob/twisted-18.9.0/NEWS.rst)

Dockerfile :whale: に下記設定をしたところ、問題なく動きました。

```
FROM python:3.7

RUN pip install -U pip
RUN pip install scrapy
```

twistedが18.9になっていますね :ok_hand:

```
root@b4df9d560d37:/usr/src/app# pip freeze | grep -e Twisted -e Scrapy
Scrapy==1.5.1
Twisted==18.9.0
```
Kotlin Coroutines 1.3とRetrofit2を使うとAPIを叩いた瞬間にクラッシュする

Kotlin Coroutines 1.3 と Retrofit2を一緒に使った時にアプリ起動時にクラッシュしましたのでメモとして残しておきます。


## 解決法

`retrofit2-kotlin-coroutines-adapter` のライブラリがKotlin Coroutines 1.3に対応したものを導入する必要があるようです。

https://github.com/JakeWharton/retrofit2-kotlin-coroutines-adapter


- 変更前

```groovy
// coroutines
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0'
```

↓

- 変更後

```groovy
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
```


に変更すれば直ります。


## 原因

おそらくKotlin Coroutines 1.3 からパッケージ構成が変わったようでその対応ができてないだけかと思います。
現在(2018/Pull Requestもあげってますのでもう少ししたらマージされるはずです。
leafletを鍛える。その14

#概要

leafletを鍛えてみた。
マウスを追ってみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/s/X/T/sXTd.jpg?t=1540885962)

#サンプルコード

```
var map = L.map('map').setView([38.3748331, 139.9574997], 12);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var popup = new L.Popup({
    autoPan: false
});

map.on({
    mousemove: mousemove,
    mouseout: mouseout,
});

var closeTooltip;

function mousemove(e) {
    var layer = e.target;
    popup.setLatLng(e.latlng);
    popup.setContent('<div class="marker-title">on</div>' + e.latlng);
    if (!popup._map) popup.openOn(map);
    window.clearTimeout(closeTooltip);
    layer.setStyle({
        weight: 3,
        opacity: 0.3,
        fillOpacity: 0.9
    });
    if (!L.Browser.ie && !L.Browser.opera)
    {
        layer.bringToFront();
    }
}

function mouseout(e) {
    statesLayer.resetStyle(e.target);
    closeTooltip = window.setTimeout(function() {
        map.closePopup();
    }, 100);
}



```

#成果物


https://embed.plnkr.co/RaqQ5zi7d6KcgzOhdvSp/


以上。
keiganモーターをunityで動かしてみた。

プログラマブルなKeiganモーターというものがあります。
ブルートゥース、usbシリアル、I2C通信で動かせ、
0.05度単位での分解能センサー、回転数も変更可能という代物。

で、公式からC#サンプルが公開されていたのでunityから動かせるようにしてみました。

動かせるようにしたんですが、肝心のKeiganモーターのマイクロusbがもげたので
下書きはここで終わり。
FactoryBotでfixtureのデータを変更する方法



## はじめに
FactoryBotを使うにあたって、既に存在するファクトリーで定義されているものと違うファクトリーで試したい、または一部変更してテストしたい場面があった。
その際にいくつかやり方があったので残しておく。


## 環境
Ruby 2.5.1
Rails 5.1.6
Rspec 3.8
factory_bot_rails 4.11.1

## 前提

- Userモデルのモデルスペックを書いている
- 既に以下のファクトリーが作成済みで他のメソッドのテストで使用されている

  ```spec/factories/user.rb
  factory :user, class: 'User' do
    id { '1' }
    gender { nil }
    last_name { '鞘師' }
    first_name { '里保' }
    last_name_yomi { 'sayashi' }
    first_name_yomi { 'riho' }
    email { '' }
    phone_number { nil }
  end
  ```

- テストを追加するにあたって作成済みのファクトリーの属性の値を変更したい
  - 例） genderを`female` `male` に設定したい
  - 例） birth_atというモデルで定義されている属性を追加したい
  - 例） 属性の値がまるまる違うuser2を用意したい

## attributeの値を変更してテストを実行する方法3つ

上記で挙げたような要望を叶えるには主に3つやり方がある。

### classを指定して新たなファクトリーを作成

まずは例で3つめに挙げた**まるまる新たにファクトリーを作成する**方法
この方法を取る場合は、既にあるファクトリーが書かれているファイルに追記する形になる。
この際大事なのが、**対象のクラスを明記する**こと。通常モデル名を指定するところを自作の名前に変えているので、どのクラスでnewしてあげるべきなのかを明示しないと`uninitialize constant User2` というエラーが出る。

```spec/factories/user.rb
  factory :user2, class: 'User' do
    id { '2' }
    gender { 'male' }
    last_name { '勇気' }
    first_name { '須藤' }
    last_name_yomi { 'sudo' }
    first_name_yomi { 'yuki' }
    birth_at { Date.new(2000, 11, 12) }
    email { 'hoge@sample.com' }
    phone_number { '0X011112222' }
  end
```

ファクトリー側は準備ができたので、spec側の設定をする。
RSpec上で使う変数名とbuild(またはcreate)するファクトリーの名前は一致してなくても大丈夫。

```spec/models/smarthr_crew_spec.rb
let(:user) { build(:user2) }
```

### traitを使う

次に、属性定義の一部変更を纏めたい場合に使えるのが`trait`。
こちらはまるまる新たにファクトリーを作成しないので、ファクトリーのファイルがスッキリするし、テストでも使いやすい。

`:user`をbuildした後にuserをブロックで回して属性に値を指定できる。
複数の属性でもまとめられる。

```spec/factories/user.rb
  trait :male do
    after(:build) do |user|
      user.gender = 'male'
      user.birth_at = '1998,12,11'
    end
  end
```

spec側では、既に作成してあったuserに、`:male`を追加でtraitを指定する。

```spec/models/smarthr_crew_spec.rb
let(:user) { build(:user,:male) }
```

### spec側で指定

一番お手軽なのがこの方法だった。
spec側だけの設定で済むので楽で、可読性も高いように感じた。
属性と値をセットで引数として渡してあげる。

```spec/models/smarthr_crew_spec.rb
let(:user) { build(:user, gender: 'no_selected') }
```

## まとめ

それぞれ合うケース合わないケースがあると思うので適宜使い分けていきたい。
GoogleAppsScriptのウェブアプリケーション公開時の注意点 

#概要
企業でgmailを利用している場合、GoogleAppsScriptのウェブアプリケーションの公開範囲が制限されることがあるので、検証段階で確認しておこうねという話。

#状況
企業全体でgmailを利用しており、払いだされたメールアドレスで、G suiteログインして利用している。
セキュリティ要件により、ウェブアプリケーションの公開範囲設定を、「本人のみ」か「所属メールドメイン」しか設定できない。(匿名公開を禁止している)

#やりたかったこと
GoogleAppsScriptをウェブアプリケーション公開し、シェルからCURLによるスクリプトの実行をしたかった。

#動作検証結果
CURLで実施してみた結果、公開範囲の設定により認証画面をはさむためにログイン画面にリダイレクトしてしまう。

#結論
セキュリティリスクを許容できないので、別の方式を考えた。
Math.maxとMath.minで書く値の上限下限設定(まだif文使ってるの？)

#背景
皆さんはこれまで数値の上限設定する場合にどのように書いていましたか？ひよっこエンジニアの私はif文を使ってしていました。

例えば、1から5の間に制限したい場合....

```JavaScript
const maxNum = 5; 
const minNum = 1;
let num = 3; // 初期値を3としておく

// ------------
// 加算された場合
// ------------
num += 3; // この時点でnumは6
if (num >= maxNum){ //しかし5以上になっているので
  num = maxNum // numは5に書き換えられる
} 
console.log(num) // 結果：5（最大制限値に収まる）
// ------------
// 減産された場合
// ------------
num -= 3 //この時点ではnumは0
if (num <= minNum){ //numは0で1以下でこれに当てはまるので
  num = minNum //numは1にする
} 
console.log(num) // 結果：1（最大制限値に収まる）
```
最近までこの書き方をしていたのですが、メンターの方にかっこいい書き方を教わったので、紹介します！
#書き方

それがこちら！

```JavaScript
const maxNum = 5; 
const minNum = 1;
let num = 3;

// 1. 加算の場合
Math.max(minNum, Math.min(maxNum, num + 3));
// 結果: 5

// 2. 減算の場合
Math.max(minNum, Math.min(maxNum, num - 10));
// 結果: 1
```
すごくないですか？！`Math.max()`と`Math.min()`を組み合わせるだけで設定できちゃうんですよ！(え、知らなかったの僕だけ？ww)

ここで何が起きているか説明します。一つ目の式をサンプルとして見ていきます。

![Screen_Shot_2018-10-30_at_16_04_14.png](https://qiita-image-store.s3.amazonaws.com/0/252687/2af931f2-d670-2212-ed1b-6a7d5b5e06f8.png)
##説明
まず、① `Max.min()`の中身を見てみましょう。

```JavaScript
Math.min(maxNum, num + 3)
// ↓ つまり
Math.min(5, 3 + 3))
```
そうですよね。`maxNum`には`5`が入っていて、`num`には`3`が入っています。この場合、`Math.min()`で、`5`と`6(3+3)`を比較し、小さい方である`5`を取得しています。

次に②`Max.max()`を見てみます。

```JavaScript
Math.max(minNum, Math.min(maxNum, num + 3));
// ↓ つまり
Math.max(1, Math.min(5, 3 + 3));
// ↓ つまり
Math.max(1, 5);
```

`minNum`には`1`が入っております。そして後ろの`Math.min(maxNum, num + 3)`は先ほど見たように、結果として`5`が入ってきます。

ということは`Math.max(1, 5)`では、`1`と`5`を比較して、大きい方である`5`を取得します。

よって、結果として、こちらの式は`5`が結果として出てくるということになります。

計算式が減算の場合も同じようになります。

```JavaScript
// 2. 最小値の制限 
Math.max(minNum, Math.min(maxNum, num - 10));
// 結果: 1
```
![Screenshot_2018_10_30_16_38.png](https://qiita-image-store.s3.amazonaws.com/0/252687/5e7f3938-8ff3-e8fd-f629-7a793dc9c476.png)
まず、Math.min()の中身で、`5`と`-7(3-10)`を比較し、より小さい方の`-7`を取得します。次に外側の`Math.max()`で`1`と`-7`を比較し、大きい方を取るので、`1`が出力されることになりますね。


## 他の出力例

```JavaScript
const maxNum = 10;  //最大値
const minNum = 5;   //最小値
let num = 6;

let val = 2 //加算値が2の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 8
// Math.minで10と8を比べ、小さい方の８が取れる。
// そしてMath.maxで5と8が比較され大きい方の8が取れる。

let val = 8 //加算値が8の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 10

let val = -4 //加算値が-4の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 5

let val = 2 //乗算値が2の場合
Math.max(minNum, Math.min(maxNum, num * val));
// 結果: 10

let val = 4 //減算値が4の場合
Math.max(minNum, Math.min(maxNum, num - val));
// 結果: 5
```

計算式で、足し算、引き算、掛け算、割り算など何をしても同じですので、演算子を書き換えるだけでOKです。


#最後に
`Math.max()`ならびに`Math.min()`の中の最大値そして最小値に直接数字を書いてもいいですが、マジックナンバーとなってしまい、他の人がコードを見たときに分かりづらくなりますので、`const`で先に定義しております。

ちなみに`Math.max()`と`Math.min()`を入れ替えても大丈夫です。(外側に`Math.min()`内側に`Math.max()`)その場合はきちんと第二引数を間違えないように注意しましょう。

書きながら思いましたが、中々説明って難しいですね。。
言葉足らずな部分が多いですが、コメントで補足等頂けますと嬉しいです。