OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonプログラミング動くおっぱい関数を作ったよ

はいどうも、乙pyです。




自分の大好きなOPを求める数式があると言うことなので
関数化してみました。

動画はこちら
https://youtu.be/cHMndW5VvQo

もととなる数式はこちら


$$\Large
X = \frac{1.5\exp\left(\left(0.12\sin t-0.5\right)\left(y+0.16\sin t\right)^2\right)}{1+\exp\left(-20\left(5y+\sin t\right)\right)} +
$$

$$\Large
\frac{\left(1.5+0.8\left(y+0.2\sin t\right)^3\right)\left(1+\exp\left(20\left(5y+\sin t\right)\right)\right)^{-1}}{1+\exp\left(-\left(100\left(y+1\right)+16\sin t\right)\right)} +
$$

$$\Large
\frac{0.2\left(\exp\left(-\left(y+1\right)^2\right)+1\right)}{1+\exp\left(100\left(y+1\right)+16\sin t\right)} +
$$

$$\Large
\frac{0.1}{\exp\left(2\left(10y+1.2\left(2+\sin t\right)\sin t\right)^4\right)}
$$

Yの値から
Xを求めると言うものです。

いくらかの部位に別れていますねえ。

早速Pythonのコードに直してみると

```
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider, IntSlider
%matplotlib inline
 
def oppai(y,t):
    x_1 = (1.5 * np.exp((0.12*np.sin(t)-0.5) * (y + 0.16 *np.sin(t)) ** 2)) / (1 + np.exp(-20 * (5 * y + np.sin(t))))
    x_2 = ((1.5 + 0.8 * (y + 0.2*np.sin(t)) ** 3) * (1 + np.exp(20 * (5 * y +np.sin(t)))) ** -1)
    x_3 = (1+np.exp(-(100*(y+1)+16*np.sin(t))))
    x_4 = (0.2 * (np.exp(-(y + 1) ** 2) + 1)) / (1 + np.exp(100 * (y + 1) + 16*np.sin(t)))
    x_5 = (0.1 / np.exp(2 * (10 * y + 1.2*(2+np.sin(t))*np.sin(t)) ** 4))
    x = x_1 + (x_2 / x_3) + x_4 + x_5
    return x

t = FloatSlider(min=0.1, max=5.0, step=0.1, value=0)
y = np.arange(-3, 3.01, 0.01)

@interact(t=t)
def plot_oppai(t):
    x = oppai(y,t)
    plt.figure(figsize=(10,9))
    plt.axes().set_aspect('equal', 'datalim')
    plt.grid()
    plt.plot(x, y, 'black')
    plt.show()
```

これで出来上がりです。

動かしてみると
![スクリーンショット 2019-07-20 17.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379626/6031e7c9-6a75-59d2-9cfa-902e7d68c3ca.png)

はーいこんな感じになります。

Tを動かしていただくと
動きまーす。

ただ、それだけです。

お好きな人は
yを作る部分を
好みの形にしていただくと
いいと思います。



それでは。
RaspberryPi 3B+ (Ubuntu Mate 16.04LTS) をPS4 DualShockコントローラで動かす

# 目的
RaspberryPi 3B+ (Ubuntu Mate 16.04LTS) をPS4 DualShockコントローラで動かした際の備忘録です

# 準備

[Raspberry Pi 3 Model B+](https://www.amazon.co.jp/dp/B07R7M7N3P/ref=cm_sw_r_tw_dp_U_x_7bykDbQ32KV4P)
[PS4 DualShockコントローラ](https://www.jp.playstation.com/ps4/peripheral/cuhzct2j13.html)


下記コマンドでSony DualShock4 ドライバをインストール

```
$ sudo pip install ds4drv
```

# テスト

PS4コントローラの「PSボタン」「SHAREボタン」を同時押してコントローラとRaspberryPiをペアリングする。

```
$ sudo ds4drv
```

サンプルコードは下記サイトのものを利用させて頂きます。
> [PS4のコントローラの値をLinuxで表示](https://ppdr.softether.net/ps4-controller)


```
$ g++ -o testps4drv testps4drv.cpp 
$ ./testps4drv 
0 ：　コントローラからの入力がないと0
1 ：　コントローラからの入力があると1
```

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">raspberrypi3B+をPS4コントローラで動かす <a href="https://t.co/Jwc1btHAFX">pic.twitter.com/Jwc1btHAFX</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1150681218750353408?ref_src=twsrc%5Etfw">July 15, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 備考
互換品のDualShock 4 コントローラで上記の通りペアリングを行った記事が見付かりませんでした。
電子工作用途であっても正規品DualShock 4を利用した方が良いかもしれません。（BT通信フォーマットの差分が影響している？）

# 参考
[A Sony DualShock 4 userspace driver for Linux](https://github.com/chrippa/ds4drv)
[PS4のコントローラの値をLinuxで表示](https://ppdr.softether.net/ps4-controller)
[ホイール欲しい ハンドル欲しい](https://wlog.flatlib.jp/archive/1/2014-2-25)
[eleccelerator DualShock 4](http://eleccelerator.com/wiki/index.php?title=DualShock_4)
Laravel ide-helperでモデルのIDE保管用コメントを作成する

[LaravelでIDE補完されやすくする](https://qiita.com/jack-oat/items/c54c9a95e82a1afd9007)ではide-helperの導入とLaravelの基本クラスのIDE保管用ファイルの作成方法を紹介しました。

今回はide-helperを使用してEloquentクラスを継承したモデルのプロパティなどをテーブルから作成してくれる機能を紹介します。

使用するテーブルとモデルは[Laravelでマイグレーションしてモデルファイルを作成する](https://qiita.com/jack-oat/items/e387302bc1ce0e28b7a8)の記事でご紹介したshopsテーブル/Shopモデルを使用します。

# doctrine/dbalのインストール
ide-helperでモデルにコメントを入れる機能を使用するには[doctrine/dbal](https://github.com/doctrine/dbal)の追加が必要になるので下記コマンドでインストールします。

```shell
composer require --dev doctrine/dbal
```

# コマンドの実行
インストールしたら下記コマンドを実行すると書くモデルファイルに対してIDE補完用のコメントが追加されます。

``` shell
php artisan ide-helper:models
```

コマンドを実行すると上書きしていいか聞かれるので、__yes__と入力してenterを押下します。

するとこのような何の記述もないモデルファイルが

```php5
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Shop extends Model
{
    //
}
```

このようになります。

```php5
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * App\Shop
 *
 * @property int $id
 * @property string|null $name 店舗名
 * @property string|null $sub_name 支店名
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop query()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop whereSubName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Shop whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class Shop extends Model
{
    //
}
```

もし__プロジェクトルート/app__配下以外にモデルファイルを作成している場合（例えば__app/Models/Shop.php__みたいな場合は）

```shell
php artisan ide-helper:models App\\Models\\Shop
```

のようにnamespaceを指定してあげると反映されます。
【Linux】固定長ファイルをsortコマンドでキー指定してソートする

## はじめに
たとえばCSVファイルなら何番目のフィールドをソートしたいというのが明確に決まっているのでキー指定は簡単だけど、区切り文字なしの固定長のファイルってどうしたらsortコマンドでソートできるだろうと思ってちょっと試しました。
結果的に以下のやり方でできました。

## ソートするファイル
こんなファイルを用意する。
15文字の固定長ファイル。

```bash:ファイルの中身
~ $ cat test.txt
1FF11111AAA 100
1AB22222ZZZ  90
1BD33333AAA  60
2BC55555BBB  60
6BB55555AAA  60
7QQ55555AAA 001
9GG55555AAA
9CC55555AAA  30
123456789012345
~ $
```

このファイルに対して以下をソートキーとしてソートしたい。

 - 第1キー：**12文字目から15文字目**を**数値扱い**で昇順
 - 第2キー：**2文字目から3文字目**を昇順

## sortコマンド
こんなオプションでソートできた。

```sh:
sort -t$'\t' -k1.12,1.15n -k1.2,1.3 test.txt
```

### tオプション
区切り文字の指定。ここで指定された区切り文字でフィールドが分割される。
固定長のファイルなので存在し得ない文字を指定し、1行＝1フィールド扱いにする。
ここではタブ文字を指定している。

### kオプション
キーを指定する。
「-k3」で3つ目のフィールドをキーとしてソートする。
あまり知られていないが(少なくとも自分は知らなかった。。)、実はフィールド内の文字位置を指定できるのでこれを利用して固定長ファイルのソートをする。
**「-k[開始フィールド番号].[開始文字位置],[終了フィールド番号].[終了文字位置]」**

### nオプション
数値扱いでソートする。
複数キー指定する場合はnの位置に注意すること。

```sh:これだと後ろのキーオプションが効かなかった
-nk1.12,1.15 -k1.2,1.3
```

```sh:これだと後ろのキーオプションも効く
-k1.12,1.15n -k1.2,1.3
```

## 確認
環境を用意するのが面倒なので以下のWEBサービスを利用。
http://s-macke.github.io/jor1k

```sh:実行結果
~ $ sort -t$'\t' -k1.12,1.15n -k1.2,1.3 test.txt
9GG55555AAA
7QQ55555AAA 001
9CC55555AAA  30
6BB55555AAA  60
2BC55555BBB  60
1BD33333AAA  60
1AB22222ZZZ  90
1FF11111AAA 100
123456789012345
~ $ 
```

空白以降(12～15文字目)と2～3文字目でソートされていますね。

## 参考
https://kazmax.zpp.jp/cmd/s/sort.1.html
https://linuxcommand.net/sort/
RaspberryPi 3B+(UbuntuMate16.04LTS)上のGazeboでturtleBot3を動かそうと思いましたがスムーズに動きませんでした

# 目的
RaspberryPi3B+(UbuntuMate16.04LTS)上のGazeboでturtleBot3を動かそうと思いましたがスムーズに動きませんでした。（おそらくスペック不足？）
インストール自体は成功したので備忘録です。

# 準備
RaspberryPi3B+
GAZEBO

# コード

公式サイトに従って環境構築します。
> [emanual.robotis.com turtlebot3 simulation](http://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/)


```
sudo apt-get update
sudo apt-get install ros-kinetic-joy ros-kinetic-teleop-twist-joy ros-kinetic-teleop-twist-keyboard ros-kinetic-laser-proc ros-kinetic-rgbd-launch ros-kinetic-depthimage-to-laserscan ros-kinetic-rosserial-arduino ros-kinetic-rosserial-python ros-kinetic-rosserial-server ros-kinetic-rosserial-client ros-kinetic-rosserial-msgs ros-kinetic-amcl ros-kinetic-map-server ros-kinetic-move-base ros-kinetic-urdf ros-kinetic-xacro ros-kinetic-compressed-image-transport ros-kinetic-rqt-image-view ros-kinetic-gmapping ros-kinetic-navigation

cd ~/catkin_workspace/src
git clone https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git
git clone https://github.com/ROBOTIS-GIT/turtlebot3.git
git clone https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
git clone https://github.com/ROBOTIS-GIT/turtlebot3_gazebo_plugin.git
cd ~/catkin_workspace
catkin_make_isolated  -j 1

export TURTLEBOT3_MODEL=burger
echo "export TURTLEBOT3_MODEL=burger" >> ~/.bashrc
```


# テスト

turtlebot3 をGAZEBO上に出現させることは可能ですが動きがカクカクしておりました。（おそらくスペック不足？）

```
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch
```

RaspberryPi 3B+ でシミュレータを動かすのは難しそう


# CodingError対策

```
roslaunch turtlebot3_fake turtlebot3_fake.launch
RROR: cannot launch node of type ibEGL warning: DRI2: failed to authenticate
[rviz-4] process has died [pid 5578, exit code -7, cmd /opt/ros/kinetic/lib/rviz/rviz -d /home/pi/catkin_workspace/src/turtlebot3_simulations/turtlebot3_fake/rviz/turtlebot3_fake.rviz __name:=rviz __log:=/home/pi/.ros/log/0502ca66-a7e4-11e9-8c56-b827eb70ff4d/rviz-4.log].
log file: /home/pi/.ros/log/0502ca66-a7e4-11e9-8c56-b827eb70ff4d/rviz-4*.log
```

catkin_makeが正しく成功しているか再確認
→ 確認したら失敗していたので -j 1オプションつけて再ビルドして解決（だったはず）

```
catkin_make_isolated  -j 1
```

# 参考
[【ROS】 Turtlebot3 のシミュレーション環境を構築してみた](http://ogimotokin.hatenablog.com/entry/2018/06/08/215044)
[ROS MelodicでTurtlebot3をGazeboで動かしてついでにSLAMする](https://qiita.com/protocol1964/items/1e63aebddd7d5bfd0d1b)
[ROS講座26 シミュレーターを作る](https://qiita.com/srs/items/f1a7c8abe577eaf3d0b9)
[ROS練習用のロボットを作る](https://qiita.com/yoneken/items/ed2e5edf3aa4e0d8d2e3)
[emanual.robotis.com turtlebot3 simulation](http://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/)
[Can I install Gazebo in Raspberry Pi 3 (Raspbian)?](http://answers.gazebosim.org/question/15589/can-i-install-gazebo-in-raspberry-pi-3-raspbian/)
[ROS2でカメさん制御してみる](https://qiita.com/l1sum/items/bc93a7c0ce9fb291fca4)
[[コラム]ROSで始めるロボティクス（12） ー ROSの入門機に新しくTurtleBot3が加わります](http://bril-tech.blogspot.com/2017/06/ros12.html?m=1)
カメがまっすぐ進むだけのROSノード（Python）
[ROSの基本的な開発](https://kazuyamashi.github.io/ros_lecture/ros_study_py.html)
勘違いしがちなメールの規格(MIME-BASE64)

# 勘違いしがちな内容

> メールは __Base64でエンコードして送信すれば良い__

さて、これのどこに勘違いがあるでしょうか？

まず、MIMEとBase64は以下の通り、全く別々のものだということです。

## MIMEとは

Mutipurpose Internet Mail Extensions
(多目的インターネットメール拡張仕様)
→メール通信に使用される規格のこと

この通信規格において、 __Base64を用いて件名をエンコードすること__ が定められている。

## Base64

文字列を __アルファベット(26)__ ✕ 2(大文字・小文字)と __数字(0-9)__ 、特定の記号(?,=など)の合計64文字のみで表した文字列に変換するエンコード手法のこと
→環境依存文字やマルチバイト文字などを使用できない環境に送信する際、文字化けなどを防ぐために利用される規格



## よくある問題(改行コード問題)

__メールの件名が長すぎて、文字化けを起こしてしまった！！__

よく聞く話ですが、Base64には以下の仕様があります。
### Base64
> ・エンコード後の文字列は998文字を超えてはいけない(MUST)

→仕様を策定した当初、998文字を超えると入出力上の最大文字数を超えてしまう危険性が高かったためだそう

> ・エンコード後の文字列は一行あたり78文字であるべきである(SHOULD)

→これは画面上に表示する際、78文字を超えると表示に崩れが発生する可能性が高かったためだそう

エンコードを行うにあたって __使用している言語によって異なります__ が、76文字や78文字で改行コードを挿入するのが一般的なエンコード方法になっているようです。


### MIME
> メール(Base64エンコード後)に以下の文字列を含んではいけない
> ・スペース
> ・タブ
> ・改行コード

一方でMIMEは、 __エンコード語の文字列に改行コードが含まれることを想定していません。__


## 結論

> メールは __Base64でエンコードし、禁則文字(スペース、タブ、改行コード)を削除したデータを送信すれば良い__

・Base64のエンコードは __あくまでもBase64の仕様に則って行われるもの__ (MIMEとは関係ない)
・MIMEはBase64を利用しているだけ

Base64でエンコードした上で、MIMEの仕様に沿ったデータ(改行コードを含まない)に加工する必要があるのに、__Base64でエンコードして送信すればいい__ というのは __誤り__ です。
クロムブックで FireFox を使う

次のページを参考にしました。
[ChromebookでLinuxを動かす。Chrome OS 69でC101PAは完璧なLinuxノートになる。](https://www.xmisao.com/2018/09/02/run-linux-on-chromebooks-using-crostini.html)

まず、xeyes が動くところまで持っていきます。

```bash
sudo apt update
sudo apt upgrade
sudo apt install x11-apps
xeyes
```

それから、Firefox のインストールです。

```bash
sudo apt install firefox-esr
```

Firefox を動かします。
　（文字化けを起こしています。）
　バージョンは 78 です。

```bash
firefox
```

![Screenshot 2019-07-27 at 15.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/233722f0-f616-5fac-341a-b1e78fcb4473.png)

>文字化けをなくすには、

>```bash
sudo apt install fonts-ipafont
```

ping を使えるようにするには

```bash
sudo apt install iputils-ping
```

dig を使えるようにするには

```bash
sudo apt install dnsutils
```

次のバージョンで確認しました。

```text
$ uname -a
Linux penguin 5.4.109-26077-g12746d86825a #1 SMP PREEMPT Mon May 17 21:44:06 PDT 2021 x86_64 GNU/Linux
```
ActiveSupportのslice!メソッドがトリッキーな動きをする

# 経緯
ActiveRecordの[validationメソッド](https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activemodel/lib/active_model/validations/validates.rb#L107)を読んでいて出てきたActiveSupporの`slice!`メソッドがトリッキーと自分には感じる動きをしたので書いた。
Railsはv5.2.3。
【PR】ちなみにこういうったコードリーディングの勉強会をよく開催しているので興味ありましたら[こちら](https://x-hack.connpass.com/)のリンクを見てね！過去開催例は[こちら](https://x-hack.connpass.com/event/140887/)。

# 概要
- `slice`メソッドの動作はこうなります。引数に渡されたkeyをHashとして返します。またもちろんレシーバーには影響はありません。

```ruby
[43] pry(main)> require 'active_support'
=> true
[44] pry(main)> require 'active_support/core_ext'
=> true
[60] pry(main)> some_hash = {
[60] pry(main)*   key_a: "some content",  
[60] pry(main)*   key_b: "some content",  
[60] pry(main)*   key_c: "some content"  
[60] pry(main)* }  
=> {:key_a=>"some content", :key_b=>"some content", :key_c=>"some content"}
[61] pry(main)> some_hash.slice(:key_a, :key_b)
=> {:key_a=>"some content", :key_b=>"some content"}
[62] pry(main)> some_hash
=> {:key_a=>"some content", :key_b=>"some content", :key_c=>"some content"}
```

- 一方`slice!`メソッドはこうなります。引数に渡されたkeyをHashとして返ってきて、渡されなかったものがレシーバーから消されるのかな、と思ったら**その逆**でした。**渡されなかったkey**のHashが返ってきて、返ってきたものはレシーバーから消されます。言い換えると、引数には**レシーバーに残したいkeyを指定する**ということになります。

```ruby
[63] pry(main)> some_hash.slice!(:key_a)
=> {:key_b=>"some content", :key_c=>"some content"}
[64] pry(main)> some_hash
=> {:key_a=>"some content"}
```

# コードを見てみる
[sliceメソッドのコード](https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activesupport/lib/active_support/core_ext/hash/slice.rb#L23)と、[slice!メソッドのコード](https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activesupport/lib/active_support/core_ext/hash/slice.rb#L32)を見るとそう書いてあるので、なるほどという感じ。

# 参考
https://qiita.com/mah_lab/items/ed10bae99105ea2fd8bd
画面表示（ｽｸﾘｰﾝｼｮｯﾄ）から、QRｺｰﾄﾞを読み込んで、ﾃﾞｺｰﾄﾞするC#の単体ｱﾌﾟﾘです


画面表示（ｽｸﾘｰﾝｼｮｯﾄ）から、QRｺｰﾄﾞを読み込んで、ﾃﾞｺｰﾄﾞする

C#の単体ｱﾌﾟﾘです

※同様の機能のﾌｫｰﾑｱﾌﾟﾘはこちら
https://qiita.com/santarou6/items/d1090338def65f3af5bc


```c#:screen_qr_decode.cs
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:QRCodeEncoderDecoderLibrary.dll /target:winexe screen_qr_decode.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using QRCodeEncoderDecoderLibrary;

public class screen_qr_decode
{
 public static void Main(string[] args)
 {
	try{
    QRDecoder	QRCodeDecoder;
    Bitmap		QRCodeInputImage;
    QRCodeDecoder = new QRDecoder();
    QRCodeInputImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);

    Graphics g = Graphics.FromImage(QRCodeInputImage);
    g.CopyFromScreen(new Point(0, 0), new Point(0, 0), QRCodeInputImage.Size);
    g.Dispose();

    QRCodeInputImage.Save("temporary.png", System.Drawing.Imaging.ImageFormat.Png);
    
    byte[][] DataByteArray = QRCodeDecoder.ImageDecoder(QRCodeInputImage);
    
    //string Result = System.Text.Encoding.GetEncoding(932).GetString(DataByteArray[0]);
    string Result = System.Text.Encoding.UTF8.GetString(DataByteArray[0]);
    //string Result = System.Text.Encoding.GetEncoding(51932).GetString(DataByteArray[0]);
    
    MessageBox.Show(Result);

	}
	catch(Exception ex){
		MessageBox.Show("読み取りエラー\n\n"+ex);
	}

 }

}
```


実行例
<img width="628" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/5d75ae13-961e-4bc4-8980-6bef27b41d0c.png">



※ライブラリは以下参照
QR Code Encoder and Decoder .NET Class Library
https://www.codeproject.com/Articles/1250071/QR-Code-Encoder-and-Decoder-NET-Class-Library-Writ

QRCodeEncoderDecoderLibrary.dll
Electron でダイアログを開いてファイルを開く／保存

# Electron でダイアログを開いてファイルを開く／保存

> pify を使用してPromise化した。

``` js
const fs = require('fs')
const pify = require('pify')
const { BrowserWindow, dialog } = require('electron').remote

/**
 * ダイアログで任意のファイルを開く
 * @param dialogOptions
 * @param fileOptions
 * @returns {Promise<undefined>}
 */
export const openFileDialog = async (dialogOptions, fileOptions = 'utf8') => {
  const win = BrowserWindow.getFocusedWindow()
  const fileNames = await pify(
    dialog.showOpenDialog(win, {
      ...dialogOptions,
      properties: ['openFile'],
    })
  )
  return fileNames ? readFile(fileNames[0], fileOptions) : undefined
}

/**
 * ダイアログで任意のファイル保存
 * TODO: openFileDialog と同様に pify を使用して Promise化して実行結果を返したい。
 * @param data
 * @param options
 */
export const saveFileDialog = (data, options = {}) => {
  const win = BrowserWindow.getFocusedWindow()
  dialog.showSaveDialog(win, options, fileName => {
    writeFile(fileName, data)
  })
}

/**
 * 指定したファイルを読み込む
 * @param path
 * @param option
 * @returns {Buffer}
 */
export const readFile = (path, option) => {
  return fs.readFileSync(path, option)
}

/**
 * fileを保存（Pathと内容を指定）
 * @param path
 * @param data
 */
export const writeFile = (path, data) => {
  return fs.writeFileSync(path, data)
}
```
MySQL Workbench8.0で既存のDBからER図を作成する方法(2019/07)

# これはなに

MySQL Workbench8.0でDBからER図を作成する流れをふわっと紹介します。
細かい話はしません。

いろんな方がER図作成のための記事を書いてくださってますが、
Workbenchのバージョンが違うせいか、ER図作成に至る操作が分かりづらかったので記事を書きました。

# ER図作成方法

## DBからインポート

Workbenchを起動し、Home画面を表示します。
左側の赤枠で囲ったアイコンをクリックします。

<img width="1136" alt="スクリーンショット 2019-07-27 2.36.19 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/ed81d449-8e72-7e50-4813-406abe39e701.png">

Models画面に遷移しました。
<img width="1136" alt="スクリーンショット 2019-07-27 2.41.00 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/28070073-c4b2-6cd9-5cfd-5945ae7b7f8a.png">
すでに`sakila_full`というModelがありますが、サンプルとして元から入っているもの（だと思う）ので無視して構いません。

赤枠のアイコンをクリックするとメニューが現れるので、DBから直接データを取ってきてER図を作成したい場合は、`Create EER Model from Database`をクリックします。
Export(Dump)したSQLファイルから作成したい場合は`Create EER Model from Script`を選びましょう。

<img width="359" alt="スクリーンショット 2019-07-27 2.41.04 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/7eb30ac6-3786-5cbe-8935-212c6164002a.png">


今回は、前者のDBから直接作るケースを前提とします。
<img width="685" alt="スクリーンショット 2019-07-27 2.41.11 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/de6e35d2-2523-dd56-8663-b6e37a8c8ddd.png">



DBの接続情報を入力します。
すでにDBを登録済みの方は`Stored Connection`から接続先を選ぶことができます。

<img width="1012" alt="スクリーンショット 2019-07-27 2.45.40 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/9aaf2ae6-0769-7ae3-bf45-81473b0479cc.png">

入力したら`Continue`ボタンをクリックで進みます.

パスワードの入力が求められたら、入力しましょう。

ER図にしたいテーブルを選択します。
<img width="1012" alt="スクリーンショット 2019-07-27 2.50.20 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/1d22b519-18ed-4010-04e0-d5f6f2dce33d.png">

オブジェクトのインポート画面に遷移します。
DBのテーブルを全部取り込みたい場合は、そのまま`Execute`でOKです。
除きたいテーブルがある場合は`Show Filter`から選択できます。
インポートしても、ER図から削除することは可能です。

<img width="1012" alt="スクリーンショット 2019-07-27 2.53.51 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/b4537d7e-12db-165e-c17d-5f3d407fa3f8.png">

`Place imported objects on ad diagram`というオプションは、
インポートしたオブジェクトをER図に配置する設定です。
ONで、勝手に配置してくれます。OFFだと、自分で配置しなければいけません。

今回はONで行きます。

<img width="1392" alt="スクリーンショット 2019-07-27 3.11.30 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/9107f01e-2aeb-946d-343d-f31678baa062.png">

はい、できました。

## ER図をカスタマイズする

自動だと配置が微妙なので、手動で並び替える必要がありそうです。
（今回はテーブルが少ないので分かりにくいですが）

サンプルのER図を見た感じだと、 色分けしたり、グルーピングして枠で囲ったりできるようですね。

（いじったことないので実際のやり方は省略します。）

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/641d33dc-f288-7990-75ae-b671ee825004.png)

## ER図を出力する

<img width="1280" alt="スクリーンショット 2019-07-27 3.11.57 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/d3a0037e-3ae9-4af0-5b35-0a6d1e616e20.png">

`File>Export>Export as XXX`でファイル出力できます。
出力ファイルは`PNG`,`SVG`,`PDF`,`PostScript`に対応しています。
`PostScript`はAdobeの印刷物用のファイルのようです。

以上です。

# 余談

WorkbenchではER図のことを`EER Diagram`というようです。
`EER`とは、`Enhanced entity–relationship`のことだと思います。
詳しくはWikipedia（英語）へ
https://en.wikipedia.org/wiki/Enhanced_entity%E2%80%93relationship_model
メモ: OpenGL入りなアプリケーションをリモートで実行する（クライアント側での表示なし）

# やりたいこと
やりたいことはリモートサーバーにSSHでログインして，レンダリング含んだシミュレーションの実行するということ．OpenGLを使うアプリケーションを使いたい場合，エラーが出てきて困っていた．
X11 Forwardingなどを利用して，クライアント側でOpenGLアプリケーションが**表示**できるようにする手法は出てくるのだが，Windows Subsystem for Linuxを使っているため，OpenGLのバージョンをそろえたりすることが難しいであろうことが容易に想像できる上に，結果の動画だけscpなりで引っ張ってこれれば十分なためより簡素な方法を探していた．

# 原因
SSHすると出力先がクライアント側のディスプレイになるらしく，`DISPLAY`という変数を書き換えてやったらいけた．
whoで立ち上がっているセッションを確認し，一番上にあった，`:1`というアドレスに以下のように`DISPLAY`変数を書き換える．

```
export DISPLAY=:1
```

https://unix.stackexchange.com/questions/406891/run-x-application-remotely-run-gui-on-remote-host

#原理
https://sites.google.com/site/teyasn001/ubuntu-12-10/huan-jing-bian-shudisplay
を見ると，ディスプレイの表示は，アプリケーションがDISPLAY変数で定義されたサーバーに実行を要求するという，ク
ライアントサーバー方式を使っているらしい．このような仕組みを取ることで柔軟に画面が出力できるようになっているようだ．
変数を書き換える前はクライアント側のディスプレイが出力先になっており，クライアント側にOpenGLの対応物がないと，エラーが出るということになっていたのだろう．

なお`DISPLAY`のシンタックスは

```
DISPLAY=（ホスト）:（ディスプレイ）.（スクリーン）
```

である．
rplider A2M8をROSで動かす



8万ほどのお手軽LidarであるRPLIDAR A2M8を動かす機会があったのでROSでセットアップを行った．

RPLIDARをPCに接続（USB経由で電源も供給される）したら以下のコマンドを実行する．


```
# packageのインストール
sudo apt-get install ros-kinetic-rplidar-ros

cd ~/catkin_ws/src
git clone https://github.com/robopeak/rplidar_ros.git

cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash

# 読み書きの権限を付与
sudo chmod 666 /dev/ttyUSB0

source /opt/ros/kinetic/setup.bash
```
これで設定が完了した．

動作の確認は以下のコマンドを実行する．

```
roslaunch rplidar_ros view_rplidar.launch
```
これでrvizがうごいて動作確認できる．

![Screenshot from 2019-07-27 15-17-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149593/c875dbfb-0ded-8342-aa70-62ab9fe6467a.png)


参考サイト
https://answers.ros.org/question/256509/error-cannot-launch-node-of-type-rplidar_rosrplidarnode-cant-locate-node-rplidarnode-in-package-rplidar_ros/
sourceTreeを使ってgit cloneしたリポジトリを別リポジトリにpushする

#problem
現プロジェクトのソースを利用して別プロジェクトを始める時
`$git clone` するとpush先がclone元になってしまう。
回避する方法で時間がかかったのでまとめておきます。

SourceTreeを使うとすごく簡単でした:angel:

#example

clone元
`https://example@bitbracket.org/example/example_moto.git`

保存先
`https://example@bitbracket.org/example/example_saki.git`

とします

#solution

#####1. 何はともあれgit clone

```
$ git clone https://example@bitbracket.org/example/example_moto.git
```

#####2. 保存先を確認

```
$ git remote -v
origin	https://example@bitbracket.org/example/example_moto.git (fetch)
origin	https://example@bitbracket.org/example/example_moto.git (push)
```

push先がclone元になっています（めっちゃ当たり前ですけど。。。）


#####３.sourceTreeでいじっていきます

pushしたいbranch/プッシュ先/originをクリック！
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3332353539342f34373266633664372d386161332d663261322d383035662d6466323838663739666437612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/3fe26f5b-356e-4fee-da7a-5e2f1d676ee5.png)

#####4.保存先を変更
別ウィンドウが出てきて、プッシュ先のリポジトリをカスタムに変更すると後ろのURLをいじれるようになります。
内容はclone元のリポジトリになっているはずです。
<img width="649" alt="スクリーンショット 2019-07-26 10.07.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/79e41a83-6f31-c2e2-1725-8e4bf3605ec9.png">

↓
URLを保存したい先に変更してOKをクリック
<img width="649" alt="スクリーンショット 2019-07-26 10.07.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/4c302d26-3de1-f331-3036-2fe140d8dc66.png">
↓
pushすると保存したいリポジトリにpushされているはずです！

Gitは怖いですがbranch切っとけば最終なんとかなる精神でやってます:innocent:
早くGitと友達になりたい

#参考資料
http://undersourcecode.hatenablog.com/entry/2017/10/31/072124

そして職場の先輩に助けてもらいました。最高に感謝です。
AWS Chatbot(beta版)を使ってみた

AWSがチャットボートサービス「AWS Chatbot」のβ版を更改(2019/7/24)されました。
https://aws.amazon.com/jp/chatbot/
公式に簡単なハンズオン(英語)があったので、日本語で手順を書いておきます。

## AWS ChatBot概要
Amazon Simple Notification Service(SNS)を使って、SlackやAWS Chimeにメッセージ通知を行える。

## 連携可能なサービス
現時点(7/27)で連携可能なサービスは以下。
https://docs.aws.amazon.com/ja_jp/chatbot/latest/adminguide/related-services.html
- Amazon CloudWatch
- AWS Health
- AWS Budgets
- AWS Security Hub
- Amazon GuardDuty
- AWS CloudFormation

## 料金
AWS Chatbotは無料(7/27時点)

## ハンズオン(15分程度)
公式でお試し設定方法が書いてたので試してみました。
https://docs.aws.amazon.com/ja_jp/chatbot/latest/adminguide/setting-up.html
公式は英語なので、日本語で手順書きます。
今回はSlackへのメッセージ通知をやります。

### 概要
CloudWatchアラームを設定し、アラーム通知をSlackチャンネルに送ります。

### 0.事前確認
- Slackチャンネルの用意
- AWS SNSのトピック設定(DynamoDBなど使ってる人はデフォルトで設定されてます)

### 1.IAMユーザ作成
**Adminレベルのユーザを作ります。**
1. IAMコンソール( https://console.aws.amazon.com/iam/) 開く
2. 「ユーザ」選択
3. 「ユーザを追加」選択
3. ユーザ名：Administrator
4. 「AWS マネジメントコンソールへのアクセス」をチェック
5. コンソールのパスワード：カスタムパスワード
6. パスワード入力
7. 「パスワードのリセットが必要」チェック外す(どっちでもOK)
8. 「次のステップ：アクセス権限」選択
9. 「グループの作成」選択
10. グループ名：Administrators
11. 「ポリシーのフィルタ」を選択
12. 「AWS 管理のジョブ機能」をチェック
13. 「AdministratorAccess」をチェック
14. 「グループの作成」を選択
15. 「次のステップ：タグ」を選択
16. 「次のステップ：確認」を選択
17. 「ユーザの作成」を選択

### 2.ChatBotの設定
**AWS ChatBotを設定します。**
1. ChatBotコンソール(https://console.aws.amazon.com/chatbot/) を開く
2. 「Configure new client」を選択
3. Slackの連携ページが開くので、連携先Slackワークスペースを選択して「confirm」を選択
4. Slack Channel：連携したいChannelを選択
5. IAM permissions(RoleName)：適当なロール名を入力(なんでもOK)
6. SNS topics(SNS Region)：どこでもOK(SNSトピックがあるとこ)
7. SNS topics(SNS topics)：どれでもOK
8. 「configure」を選択

### 3.CloudWatchアラームの設定
**アラームを設定します。**
1. CloudWatchコンソール(https://console.aws.amazon.com/cloudwatch/) を開く
2. 「アラーム」を選択
3. 「アラームの作成」を選択
4. 「メトリクスの選択」を選択
5. 検索欄：SNS
6. SNS＞トピックメトリクス
7. 適当なトピック名をチェック(どれでもOK)
8. 条件(しきい値の種類)：静的
9. 条件(アラーム条件を定義)：以下
10. 条件(しきい値を定義します)：1
11. 「次へ」を選択
12. 通知(アラーム状態)：アラーム状態
13. 通知(SNSトピック)：既存のSNSトピックを選択
14. 通知(通知の送信先)：適当に選択
15. 「次へ」を選択
16. アラーム名：なんでもOK
17. アラームの説明：なんでもOK
18. 「次へ」を選択
19. 「アラームの作成」を選択

### 4.結果を確認
Slackチャンネルをみましょう。3分くらい待てば通知が来るはずです。
<img width="664" alt="aws-chatbot.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174816/6bb5a34d-e78e-ac48-0cd1-ed88464f378d.png">

## おわりに
今までチャットボットはLambdaなどで手作りでしたが、これだと設定だけで簡単にBotが使えますね。
GuardDutyの不正アクセス通知とかは欲しかったので試してみようかと思います。
今後の機能拡張に期待です。
rbenvの使い方まとめ

Ruby初学者なので、rbenvの基礎的な使用方法から自分用にまとめます。

基本的には[公式リポジトリ](https://github.com/rbenv/rbenv)を見ながら書いていきます。

# rbenvとは？

Rubyのバージョン管理を行ってくれるツール。
開発環境に複数バージョンのRubyをインストールし、切り替えることができます。

# インストール・設定

以下、Macを前提で記載します。

```bash
# インストール(ruby-buildも入れておく)
$ brew install rbenv ruby-build
```

`~/.bash_profile`に以下の内容を追記します。

```bash
eval "$(rbenv init -)"
```

```bash
# 変更内容を適用
$ source ~/.bash_profile

# インストール確認
$ rbenv -v
```

# 基本的な使い方

## Rubyのインストールとバージョン切り替え

Rubyのバージョンを指定してインストールします。

```bash
# まずはインストール可能なバージョンを調べる
$ rbenv install -l
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
  1.8.6
 ...

# 記載時点では2.6.3が安定版のようなので、2.6.3を入れる
# ※[-dev]や[preview]と書いていない
$ rbenv install 2.6.3

# 私の環境ではエラーになりました。。。
BUILD FAILED (OS X 10.14.5 using ruby-build 20190423)
# オプションつけると通るらしい
$ RUBY_CONFIGURE_OPTS="--disable-dtrace" rbenv install 2.6.3

# インストールされているバージョン一覧
$ rbenv versions
2.6.3

# 使用するRubyのバージョン指定
$ rbenv global 2.6.3
```

上記の場合は全体で使用するRubyのバージョンを設定しますが、
任意のディレクトリ配下だけ別のバージョンを使用することもできます。

```bash
# 全体のバージョン
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

# 任意のフォルダに移動
$ cd hoge

# hogeの中だけ2.6.0(オプションは割愛)
$ rbenv install 2.6.0
$ rbenv local 2.6.0

# .rbenv-version が作成される
$ ls -a
.               ..              .ruby-version

$ ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin18]
```

## その他機能

### shell

コマンドラインで使用するRubyのバージョンを一時的に変更します。

```bash
# 現在のバージョン
$ rbenv versions
  system
  2.6.0
* 2.6.3 (set by /Users/iwakura/.rbenv/version)

$ rbenv shell 2.6.0

# 確認
$ rbenv versions
  system
* 2.6.0 (set by RBENV_VERSION environment variable)
  2.6.3

# 元に戻す
$ rbenv shell --unset
$ rbenv versions
  system
  2.6.0
* 2.6.3 (set by /Users/iwakura/.rbenv/version)
```

### which

rbenv内にインストールされているコマンドのフルパスを表示します。

```bash
$ rbenv which gem
/Users/iwakura/.rbenv/versions/2.6.3/bin/gem
```

### whence

引数に指定したコマンドがインストールされているバージョンを表示します。

```bash
# 現在2.6.3と2.6.0がインストールされている
# rackupは2.6.3にのみ存在
$ rbenv whence rackup
2.6.3
```

## 環境変数

rbenvで使用する環境変数について記載します。

|名前|デフォルト値|説明|
|:--|:--|:--|
|RBENV_VERSION||rbenv shellで使用するRubyのバージョンを設定|
|RBENV_ROOT|~/.rbenv|rbenvでインストールした各バージョンのファイル等が配置されるパスを指定|
|RBENV_DEBUG||デバック情報を出力するらしい(rbenvの挙動確認用？)|
|RBENV_HOOK_PATH||[rbenv hooks](https://github.com/rbenv/rbenv/wiki/Authoring-plugins#rbenv-hooks)用らしいけど何かよく分からない|
|RBENV_DIR|$PWD|`.ruby-version`の検索先|

# まとめ

一部雑な記載になってしまいましたが、基本的なことは学べました。
今後Rubyを使用して仕事することになるので、言語仕様も含めてしっかり学びたいです。
【基礎知識】RESTとは

#はじめに
RESTの概念についてはWEBの基礎知識を勉強する中で知りましたが、非常に理解に苦しみました。ということで自分用のメモ＋同じことで「？？？」となっている方の助けになればいいなぁという思いでまとめます。

#本題：RESTとはなんなのか

REpresentational State Transferの略で、WEBにおける設計思想のことです。
この設計思想は以下の４つの項目から成り立っています。

###①全てのリソースに一意なURLでアクセスできる

全てのアクセスの目的語をリソースとして定義し、
その全てのリソースに一意な識別子を持たせることで、
リソースそれぞれにアクセスができます。

リソースってそもそもなんなの？というと、
このQiitaにあるそれぞれの記事だったり、通販サイトの各商品だったり、
情報ひとかたまりを指します。

通販サイトを例にとると、
その通販サイトが持つすべての商品を"items"というリソースとして定義し
その服に1,2,3...15といった識別子をそれぞれ一つずつ持たせる、ということです。


###②HTTPメソッドベースでリソースにアクセスする

識別子をもったリソースにアクセスするときには、
HTTPメソッドGET、POST、PUT、DELETEのいずれかの方法を利用します。
この４つのメソッドにより、リソースに対して何らかの操作を行うのです。

|	HTTP メソッド	|	リソースに対して行う操作	|
|	:-:	|	:-:	|
|	POST	|	リソースの作成	|
|	GET	|	リソースの取得	|
|	PUT	|	リソースの更新|
|	DELETE	|	リソースの削除|

###③ステートレスである
クライアント側とサーバ側のやりとりは一回ごとに完結し、状態管理を行いません。
このおかげで、同じリクエスト（あるリソースに、あるメソッドでアクセスする）に対するレスポンス（アクセスした結果）は常に同じになります。

例えば、通販サイトの商品の一つを閲覧したいとします。
このリソースへのURLは　”http:///通販.com/items/1”、
閲覧の場合、HTTPメソッドにはGETが使われます。

このページにアクセスするまでに、クライアント側でどのようなリクエスト・レスポンスが行われていたとしても、GETメソッドでhttp:///通販.com/items/1にアクセスした場合は商品の閲覧ページが表示される、ということです。

###④リソースへの接続性

各リソースに接続できることです。（そのまま）
ユーザがすべてのURLを知っている必要はありません。
実際、「あの通販サイトのあの商品はこのURLだったよね。。。」といちいち覚えることはできないですよね。
次の情報にアクセスするためのURLをハイパーリンクの形でクライアント側に伝えることで、
ユーザが各リソースに（いずれかのHTTPメソッドで）アクセスすることができます。


##おまけ：RESTfulなサービスとは

上記RESTの考え方に基づいて設計されたサービスを指します。

##最後に

以上、RESTの概念についてまとめてみました。
お気軽にご指摘やコメントをいただけたら幸いです！
【VMware】ゲストOSからネットワーク接続／teraterm接続を行う為の設定手順　※GUI

## 対象
・VMwareにCentos、かつGNOMEをいれている方。
・ゲストOSからインターネット接続したい方。
・ホストOSからゲストOSにteratermで接続したい方。

## 環境
|ホスト| VM |ゲスト|
|:--:|:--:|:-----:|
|Windows10|[VMware Workstation 15 Player](https://my.vmware.com/jp/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/15_0)|[Centos7](http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso)|

## 全体の流れ
VMware上のゲストOSに固定IPを割り当てて、外部ネットワークとの接続を可能にします。

1. VMwareのネットワークアダプタ(VMnet1)の設定
2. VMwareのネットワークアダプタ(VMnet8)の設定
3. 仮想マシンのネットワークアダプタの設定
4. ゲストOSのIPv4セッティングの設定
5. ゲストOS再起動
6. 疎通確認

※参考サイト
https://kyakujin.hatenadiary.org/entry/20130420/1366457068

# 1. VMwareのネットワークアダプタ(VMnet1)の設定
***ステップ1***
「VMware Bridge Protocol」のチェックが外れていることを確認します。
※「コントロールパネル」→「ネットワークとインターネット」→
　「ネットワークと共有センター」→「アダプターの設定変更」→
　「VMware Network Adapter VMnet1」→「プロパティ」
<img width=400 alt="VMnet1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/418905ea-b35d-6c89-7273-322505e5c991.gif">

***ステップ2***
ホストOS上でコマンドプロントを開き、「ipconfig」と入力。
自身のIPアドレスを確認します。

***ステップ3***
ホストOSのIPアドレスと同じセグメントのIPアドレスを設定します。
ここでは仮として、IPアドレス「172.16.10.100」で振っています。
<img width=400 alt="インターネットプロトコルバージョンipv4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/0d7712ce-8511-80b0-481d-7d738771fb7b.gif">
<img width=400 alt="インターネットプロトコルバージョンipv4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/76fc6167-48b3-6d6d-6df9-28e291047b0f.gif">

# 2. VMwareのネットワークアダプタ(VMnet8)の設定
***ステップ1***
「VMware Bridge Protocol」のチェックが外れていることを確認します。
※「コントロールパネル」→「ネットワークとインターネット」→
　「ネットワークと共有センター」→「アダプターの設定変更」→
　「VMware Network Adapter VMnet8」→「プロパティ」
<img width=400 alt="VMnet8" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/6a5ebf31-f292-d238-f298-558036beee6c.gif">

# 3. 仮想マシンのネットワークアダプタの設定
***ステップ1***
ゲストOSのネットワーク接続方法をブリッジに変更します。
※ゲストOSにログイン後、
　「Player(P)」→「管理」→「仮想マシン設定」→「ネットワークアダプタ」
<img width=400 alt="ネットワークアダプタ設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/dbf56de0-a69f-113a-8d4a-fa5e42ba7a5a.gif">

# 4. ゲストOSのIPv4セッティングの設定
有線のIFに手動でIPv4アドレス設定を行います。
アドレス、ネットマスクにはホストOSと同じセグメントのIPアドレス、ネットマスク
ゲートウェイには無線ルーターのIPアドレスを設定します。
※ゲストOSにログイン後、
　「アプリケーション」→「システムツール」→「設定」→「ネットワーク」
<img width=500 alt="ネットワークアダプタ設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377129/b2a57365-c86c-407f-5234-0c6ed5c803d4.gif">

# 5. ゲストOS再起動
端末を開き、「shutdown -r now」を入力してください。

# 6. 疎通確認
ゲストOSから無線ルーターのIPにPingが通るか確認
ホストOSからゲストOSにPingが通るか確認

Pingが通ったら、teratermからのログインも可能となるので
No.4で設定したIPアドレスを指定してログインを試してみてください。
SourceTreeでプッシュ前のコミットメッセージを修正する方法【Ver. 2.5.5】

※この記事は https://kunosu.qrunch.io/entries/mg083ztf4r2Pm8hv に移動しました。

---

編集できるコミットログは **puth** 前のみです！
puth してしまった場合は諦めましょう

※Windows版SourceTree のバージョンが**2.5.5**のときの情報です。

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

この場合は簡単です

1. コミットメッセージを書く画面に移動
	* 下の「ファイルステータス」タブをクリック
1. 右下の時計マークの隣にある「オプションのコミット」をクリック
1. 「最後のコミットを上書き」をクリック
1. 確認ダイアログが出るので「はい」
1. コミットメッセージを書く欄に直前のコミットメッセージが入力されます
1. コミットメッセージを修正
1. 「コミット」をクリック

## 2つ以上前のコミットメッセージを修正

ここからがメインです。 
今回は下記画像の「【ここのコミットメッセージを修す】」を修正します。
![変更対象のログが「直前のログ」でないためオプションのコミットから修正できない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316183/f871a8ba-05a7-9daa-aedd-c80d2139f237.png "変更対象のログが「直前のログ」でないためオプションのコミットから修正できない")

1. 変更したいコミットメッセージの **1つ前** のログを右クリック
1. 「xxxxx(選択したログのコミット番号)の子とインタラクティブなリベースを行う」をクリック<br>
	![変更したいコミットメッセージの1つ前のログを右クリック](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316183/f4d05b86-6fb5-8b9f-0746-2db285c2fd7b.png "右クリックメニュー")
1. 「Interactive rebase from xxxxx」ウィンドウが出ます
1. 変更したいログ全てにチェックをつけ、「OK」をクリック<br>
	![「Interactive rebase from xxxxx」画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316183/3d91a515-d854-798c-c964-4181a929b1f4.png "「Interactive rebase from xxxxx」画面")
	* 「Amend Commit ?」列にチェックボックスがある
	* 下にあるボタン「メッセージを編集」は使いません。
1. 「説明」列のチェックをつけたログに「HEAD」があることを確認
1. 上記で説明した[直前のコミットメッセージを修正](#直前のコミットメッセージを修正)と同様に修正
	* ここでは「【修正完了】」へ変更
1. コミットすると、別のブランチが始まります<br>
	![別のブランチが始まる](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316183/5e6601ef-7c89-bce6-36b5-be0b9723ba1d.png "別のブランチが始まる")
1. メニューの「操作］→「リベースを続ける」をクリック
1. 複数のログにチェックをつけた場合は、続けてコミットメッセージを修正→「リベースを続ける」を繰り返す。
1. チェックをつけたログを全て修正すると分岐したブランチが元に戻り、修正完了です。<br>
	![修正完了](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316183/441282dd-6af3-83ca-fbb8-571a1123f05d.png "修正完了")
Dockerについて調べながら勉強したやつを書いてみました

こんにちは！
未来電子テクノロジーでインターンをしているものです。
今回はDockerについて全く理解していないなぁと感じたので、勉強をした結果学んだことを書いていこうかと思います。

##そもそもDockerって何？
Dockerとは`コンテナと呼ばれるOSレベルの仮想化環境を提供するオープンソースソフトウェアである。`（wikipediaより）らしいです。

これでは正直よくわかりません。

分かりやすい説明やすくいうと、Dockerを使用するとOSとアプリがインストールされた環境を閉じ込めて保存しておき、いつでもその環境を立ちあげることができるそうです。（今から説明することは[こちら](https://qiita.com/rawHam/items/80ba13d2d2d56dba411e)を参考にしました）

##用語の説明
###Dockerイメージ
OSとアプリがインストールされた環境を閉じ込めたファイル
###コンテナ
解放されたOSとアプリの環境
###Dockerfile
Dockerイメージ作成時に実行するコマンド等を列挙したファイル

上記のような感じなります
そして上記の説明は[Dockerについてなるべくわかりやすく説明する](https://qiita.com/rawHam/items/80ba13d2d2d56dba411e)をコピペしただけなので、こちらをご覧ください。

##Dockerの特徴

***1.システム導入の高速化***
Dockerを利用することです
ぐにプログラムを適用し導入スピードを高速化できます。これの理由としてはOSを共有しているので、それに関する設定を省略することができるからです。

***2.起動時間の短縮化と多くの処理実装が可能***
DockerではすでにOSが立ち上がっているので、その分サーバーの起動時間を短くでき、サーバーへの負荷が低く、一度に多くのプログラム処理を実装できるそうです。

***3.コンテナ設定の再利用が可能***
一度作成したコンテナは、Dockerイメージを作成して、他のコンテナに適用することで再利用が可能です。

##参考文献
[Dockerとは何かを入門者向けに解説！基本コマンドも](https://udemy.benesse.co.jp/development/web/docker.html)
R.swift 追加したリソースが更新されない時~

# R.swift でリソースが更新されない時

表題の事象が発生した場合、どうしたら良いか困ってしまいました。

対応策は`DerivedData`を全て消してしまいましょう

```
rm -rf /Users/(ユーザーの名前)/Library/Developer/Xcode/DerivedData/
```

さすれば更新されます。
RDPのポート番号を変更しても接続できない

## 事象
セキュリティ向上のため、RDPのポート番号を変更したのだが、うまいこといかない。

## 結論
次のコードを打つとうまくいった。
※（new portnumber）に変更後のポート番号を入れる

```powershell:
netsh advfirewall firewall add rule name=”RDP” dir=in action=allow profile=Public,Private localport=(new portnumber) protocol=tcp
netsh advfirewall firewall add rule name=”RDP” dir=in action=allow profile=Public,Private localport=(new portnumber) protocol=udp
```
ラズパイからADと連携したRADIUS認証が必要な無線LANに接続する (WPA2-EAP)

## 【内容】
Raspberry PiからActiveDirectoryと連携したRADUIS認証(WPA2-EAP)が必要なのWifiアクセスポイントに接続出来るようにします。

## 【設定】
いろいろはまりましたが、結果`/etc/wpa_supplicant/wpa_supplicant.conf` を以下のように設定したら安定して接続できるようになりました。

```/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
    ssid="<SSID名>"
    scan_ssid=1
    priority=1
    key_mgmt=WPA-EAP
    pairwise=CCMP
    auth_alg=OPEN
    eap=PEAP
    identity="<ドメインユーザID>"
    password=hash:<ハッシュ化されたパスワード>
    phase1="peaplabel=0"
    phase2="auth=MSCHAPV2"
}
```
`<SSID名>`、`<ドメインユーザID>`、`<ハッシュ化されたパスワード>`を自分のものに置き換えてください。
ここで問題になるのは「ハッシュ化されたパスワード」の取得方法です。
ubuntuなどのLinux環境がある場合は、以下のコマンドで取得できます。

```bash

echo -n <パスワード> | iconv -t utf16le | openssl md4
```
上記コマンドを実行した場合、パスワードの平文が履歴に残るので、履歴を消しておいたほうが良いです。

また、Python2.7を実行できる環境の場合は`smbpasswd`というモジュールをインストールすることで、パスワードのハッシュ化が可能です。

```bash
pip install smbpasswd
python
```
```python
import smbpasswd
print (smbpasswd.nthash("<パスワード>"))
```

なお、`scan_ssid=1`はステルスモードのSSIDに対し、接続できるように設定しています。
PHPでデータベース接続（PDO）

PHPでデータベース接続する時、PDO周りは不明な用語が沢山出てきて混乱しがちな為、
単語や情報を一つずつ整理してロジックを組み立てる必要がある。


###データベース接続の流れ
データベースの接続　→　データベースの操作　→　データベースとの接続終了
という流れが基本的な鉄則。

例えるなら、
本棚から必要な本を見つけ手に取る（接続）
本の中から必要な情報を探す（操作）
本を閉じ、本棚にしまう（接続終了）
と行った所。

###書き方　判例
接続方法自体は色々あるが現在は、PDO（PHP Data Object）が主流。

下記判例を示すと、

```php:php
<?php
//まず登録項目３点を変数化する。
$dsn = 'mysql:dbname=指定のテーブル;host=指定のホスト名;charset=utf8';
$user ='RDBMS登録のユーザー名（rootとか）';
$password ='RDBMS登録のユーザーパスワード（rootとか）';

//例外処理
try{
   $dbh = new PDO($dsn, $user, $password);  //ここが接続の文
   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $sql = "SELECT * FROM recipes";
   $stmt = $dbh->query($sql);
   $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
   echo $result;
   $dbh = null;
}catch(Exception $e){
   echo"接続失敗：". htmlspecialchars($e->getMessage(),ENT_QUOTES, 'UTF-8') . "<br>";
   die();
}

?>
```

こんな所でしょうか？
初心者がいきなりこれを見ても、は？って感じになりますよね。
いろんな部分が、は？って感じですよね。
何回写経した所で、一つ一つの箇所が理解出来ない事には、このPDO周りの部分は毎回大きく時間が取られてしまいます。

そこで一つ一つパーツごとに切り分けて、ロジックを噛み砕いていかなくてはいけません。

・new PDO・・・PDOで接続。newはそのまま「新たに」って意味で、ここはもうそういう書き方をしないといけないと思うようにしましょう。
　　　　　　new PDOの後に、接続情報やユーザー名、パスワードなどを指定して準備していく。
　　　　　　ここまでの固まりを「$dbh」という変数に格納する。
          今後データベースの機能を使う場合には、この変数「＄dbh」を指定する。

・$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
       ・・・生成したPDOオブジェクトに対して、setAttribute()メソッドで設定を行い、
　　　　　　データベース接続の設定（エラーモードの設定）をこの行でやっている。
　　　　　　setAttribute()メソッドは、データベース接続時の設定や、SQL文実行時の挙動など、
　　　　　　データベースハンドルの属性を変更するためのメソッド。

 $stmt = $dbh->query($sql);
　　　・・・①$dbhはデータベースの接続を設定した変数
　　　　②queryは問い合わせ、質問するといったイメージ
　　　　③$sqlはSQL文の内容
　　　　という流れから、この文は、SQL文を実行して結果を問い合わせるという意味が入っている。
　　　　->query()とする事で、PDOの機能の問い合わせを実行する事が出来た。

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
　　　　・・・SQL文の実行結果をカラム名をつけた配列として取り出す。
　　　　　配列として全て取り出す命令はfetchAll()という関数。
　　　　　PDO::FETCH_ASSOCは、実行結果をつけた配列として返す。
　　　　　



・$e->getMessage()
   　・・・catch時にExceptionを代入する変数$eを用意する。Exceptionは例外という意味。
　　　　$eの中にあるメッセージを取得する命令getMessage()は、$dbhで指定した時と同様に、
　　　　->(アロー演算子)で指定する。
　　　　$e->getMessage()とすれば、エラー発生時のメッセージを取得できる。


こうやって一つ一つ要約していくと、順序立てて処理が進んでいる事が分かる。

まずデータベース接続する。
エラー設定をする。
SQL文を発行する準備をする。
SQL文を発行して問い合わせる。
SQL文の実行結果を取り出す。
データベース接続を切断する。

といった流れとして、翻訳が成り立つ。
PDOstatementの所はもう少し詳細が欲しい所なので、それはまた次の機会にまとめる。
C++とメモリリークと仮想デストラクタ Delete called on '~~' that is abstract but has non-virtual destructor

#メモリリークとは? 事の起こり
動的領域に確保したメモリを解放し忘れることです(笑)。極論ですが、C言語では、**mallocしたらfree**を守っておけばメモリリークを防げます。C++でも同様に**newしたらdelete**を徹底するとかスマートポインタを使うとかすればメモリリークは防げます!! ・・・と思っていた時期が私にもありました。実際はこれだけでは防げません(泣)。C++には言語仕様に根ざしたメモリリーク要因が多数存在するからです。今回は、多数の要因の中から、仮想デストラクタに起因するメモリリークをご紹介します。

#抽象クラスを利用した時のメモリリーク
今回皆さんに紹介するコードはこちらです。このコードの振る舞いは非常に簡単です。クラスの構成は抽象クラスmyAbstractを派生クラスのmyConcreatに継承しているだけです。**main関数では無限ループ内で派生クラスのインスタン生成し、抽象クラスでキャストした後、deleteで解放を繰り返しています。**

```cpp:myClass.hpp
#ifndef myClass_hpp
#define myClass_hpp
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

//抽象クラス
class myAbstract{
public:
    virtual void method1(void) = 0;//仮想関数の定義
};

//抽象クラスの派生クラス
class myConcreat: public myAbstract{
private:
    //そこそこサイズの大きいメンバを用意
    vector<long> B{1000,2000,3003,4000,50000,50000};
public:
    void method1(void){
        cout<<"Hello World"<<endl;
    };
    ~myConcreat(){//デストラクタ
       //本クラスが解体された時のメッセージを表示
        cout<<"派生クラスは解放済"<<endl;
    }
};
#endif /* myClass_hpp */
```

```cpp:main.cpp
#include <iostream>
#include "myClass.hpp"

int main(int argc, const char * argv[]) {

    while(1){
       //派生クラスのインスタンスを動的領域に確保し、抽象クラスでキャスト
        myAbstract* A = new myConcreat;
        delete(A);//①ここでワーニング //実は解放されていない
    }
    return 0;
}
```

また、myConcreatクラス内でデストラクタを定義しており、myConcreatクラスがデストラクタにより解体された時は"派生クラスは解放済"とメッセージが表示されるようにしています。C++では基本的に動的領域に確保したものは、それを確保したブロックの終わりに解体されるので、今回のコードではwhileループが終わるたびにmyConcreatクラスのデストラクタが働き、コンソールに、

```
派生クラスは解放済
```
と無限に表示され続けるはずです。しかし、このコードを動かすと何も表示されません。また、プログラム動作中のメモリの使用率は右肩上がりに上昇し、メモリリークが発生していることが確認されます。

#今回のメモリリークへの対策
実は上記のコードは①delete(A)の部分でWarning

```
Delete called on 'myAbstract' that is abstract but has non-virtual
```

が出てきています。ざっくり訳すと、**deleteはmyAbstractは抽象クラスから呼ばれるけど、抽象クラスは仮想デストラクタを持ってないよ**と言っています。このwarningに従って、上記のコードを修正し、myAbstractに仮想デストラクタを定義してやります(下記コード)。この仮想デストラクタは働いた時、"抽象クラスは解放済"というメッセージを出すようにしてあります。

```cpp
class myAbstract{
public:
    virtual void method1(void) = 0;//仮想関数の定義
    //仮想デストラクタを追記
    virtual ~myAbstract(){
        cout<<"抽象クラスは解放済"<<endl;
    }
};
```

このように修正した上で、問題のコードを実行すると・・・

```
派生クラスは解放済
抽象クラスは解放済
派生クラスは解放済
抽象クラスは解放済
・・・以下無限ループ
```

と言う結果になり、while(1)ループごとに動的領域に確保した派生クラスが解放され、メモリリークが解消することができました!! メモリ使用率も見てみたのですが、メモリ使用率は一定で上昇しないことが確認されました!!

#今回のメモリリークの原因
とりあえず、**仮想デストラクタを書いたらメモリリークを解決したけど、どうしてだろう??** この疑問の答えを解説します。**答えをいうと、C++がそういう仕様だからです!!**

C++では、仮想デストラクタを定義せずに今回のコードのように、

```cpp
myAbstract* A = new myConcreat;
```
派生クラスを抽象クラスでキャストすると**ブロックの終わりに、myConceatクラスのデストラクタを呼びだすということを暗黙的に行ってくれません。(未定義なことは実行できない)**なぜなら、そういう言語仕様だからです。
仮想デストラクタを定義すると、派生クラスをデストラクタも呼んだ後、抽象クラスのデストラクタを呼んでくれます。ただ、それだけのことなんです。それだけのことを怠るだけでメモリリークが発生するのがC++なんです。

#まとめ
こんな簡単に、言語に由来したメモリリークが起こるなんて寒気がしました。C++で改修に改修を重ねる内に、メモリリークするプログラムを作り込んでしまっても何ら不思議はないと思います。仮想デストラクタ以外にもメモリリークを引き起こす要因がC++にはまだまだあるので今後調べていきたいです。
HomeBrewを特定ユーザーのみで使用する方法



# 概要

- やりたいこと
  - Mac OS Xを複数人で使用するので、自分のアカウントだけにHomeBrewをインストールし、パッケージを（他のユーザーに影響しないように）管理したい
- 問題
  - 公式ドキュメントの方法でHomeBrewを特定アカウントのホームディレクトリ以下にインストールしようとすると「そのレポジトリdeprecatedだよ」と言われる
- 解決方法 
  - 新しいレポジトリを参照する

# HomeBrew のtarball展開によるインストールがdeprecatedになっている


以下の記事を参考に homebrew をインストールしようとすると、何故かREADME.mdだけが作成されました。

[複数人で使用しているPCでのhomebrewの正しい使い方 (Qiita)](https://qiita.com/snowman_mh/items/de021e32fc3967741f67)


```md:README.md
# Homebrew (Legacy)

This repository was deprecated and split into two repositories:

- Homebrew formulae/packages: [Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core) (former contents of `Library/Formula`)
- Homebrew package manager: [Homebrew/brew](https://github.com/Homebrew/brew)
```

指定したレポジトリは既にdeprecated で、「formulae」と「brew」の二つに分かれたと言われています。

HomeBrew公式ドキュメントの項目：[インストール](https://docs.brew.sh/Installation)を見ても、同じ方法（以下の通り）でやれと書いてあります。

```bash
cd ~
mkdir homebrew & curl -L https://github.com/Homebrew/homebrew/tarball/master | tar xz --strip 1 -C homebrew
```

どうやら公式ドキュメントも情報を更新していないようです。

# 解決策

## HomeBrewインストール

`README.md`内部にあった

```
- Homebrew package manager: [Homebrew/brew](https://github.com/Homebrew/brew)
```
を参考に、`https://github.com/Homebrew/brew/tarball`をcurlで取得し、展開することにしました。

```bash
cd ~
mkdir homebrew & curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
```

これによって、~/homebrew内に必要なファイルが作成されます。


## パスを通す

`.bashrc`に以下の行を追加します。

```bash:.bashrc
export PATH=~/homebrew/bin:$PATH   # 追加する行
```

`.bashrc`をログイン時に自動で読み込む方法などは省きます。


## HomeBrew動作確認

以下のコマンドを実行し、git の最新版をインストールしてみましたが、無事成功しました。

```bash
brew install git
```

### 管理者権限が必要になる場合もある

以下の二通りの方法でOpenJDK 8 をインストールしようとすると、管理者権限が必要になりました。

```bash
# 1
brew cask install caskroom/versions/zulu8
# 2
brew cask install adoptopenjdk8
```

# 別の道？

まだ試していませんが、[linuxbrew](https://docs.brew.sh/Homebrew-on-Linux)がMac 上で動くなら、そちらの方がいいかもしれません。

ただ、Mac はあくまでUNIX系なので、動作するかはやってみないと分からないです。
NeustarでJSONをPOSTする

ハマったので備忘。
APIにJSON渡して、戻ってきたJSONを受け取ってまたゴニョゴニョしたいときなどに。

```javascript
var client = test.openHttpClient();
client.setFollowRedirects(false);

test.beginTransaction();
test.beginStep("Step-001");

// Request
var url = 'https://example.com/api/getName';
var request = client.newPost(url);
request.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");

var json = {
   id:'hoge'
};
var strJson = JSON.stringify(json);
request.setRequestBody(strJson);

// Response
var response = request.execute();
var code = response.getStatusCode();
test.log(code);
var body = response.getBody();
test.log(body);

var obj = JSON.parse(body)
test.log(obj.name);

test.endStep();
test.endTransaction();
```
node.jsで簡易データベースとしてExcelファイルを使う

# node.jsで簡易データベースとしてExcelファイルを使う
MySQLを使うほど大袈裟にせず手軽にデータベースを使いたい場合、簡易データベースとしてExcelを導入するのも良い手だと思います。
ExcelならわざわざSQLを書かずに使い慣れたUIでデータ更新ができるので手軽というメリットがありますね。
そこでnode.jsでExcelファイルを読み書きできるライブラリを探しました。
できればヘッダなどは色付けしておきたいので書式情報は維持したまま保存したい前提です。

## SheetJS
高機能なのですがPro版でないと書式情報が保存されないので今回はパス。
[公式ページ](https://sheetjs.com/)

## xlsx-populate
xlsx-populateなら書式情報を維持しながらExcelファイルを読み書きできます。
[Github](https://github.com/dtjohnson/xlsx-populate)

### インストール方法
```
npm install xlsx-populate
```

### 使い方
```javascript
const XlsxPopulate = require('xlsx-populate')

XlsxPopulate.fromFileAsync("./Input.xlsx")
    .then(book => {
        const sheet1 = book.sheet("Sheet1")
        sheet1.cell("A2").value(10)
        sheet1.cell("B2").value(20)
        sheet1.cell("C2").value(30)
        book.toFileAsync("./Output.xlsx")
    })
```
## xlsx-populate-wrapper
xlsx-populateをラッピングしたxlsx-populate-wrapperを使うとさらに使いやすくなります。この方法が一番おすすめです。

[Github](https://github.com/juniorCitizen/xlsx-populate-wrapper#readme)

### インストール方法
```
npm install xlsx-populate-wrapper
```

### 使い方

```javascript

const xPopWrapper = require("xlsx-populate-wrapper")
const path = require("path")

const filePath = path.resolve('./sample_data.xlsx')
const workbook = new xPopWrapper(filePath)

workbook.init()
  .then(wb => {
    // シート名の一覧を取得
    console.log(wb.getSheetNames())
    // => ['Sheet1', 'Sheet2', 'Sheet3']

    // シート名を指定してヘッダ一覧の取得
    console.log(workbook.getHeadings('Sheet1'))
    // => ['Title1', 'Title2', 'Title3']

    // シート名を指定してJSONデータとして取得
    const jsonData = workbook.getData('Sheet1')
    console.log(jsonData)
    /*
      [
        {
          'Title1': '1',
          'Title2': '2',
          'Title3': '3',
        },
        {
          'Title1': '5',
          'Title2': '6',
          'Title3': '7',
        },
        {
          'Title1': '11',
          'Title2': '12',
          'Title3': '13',
        }
      ]
    */

    // データを書き換える
    jsonData[0].Title3 ='a'
    jsonData[1].Title3 ='b'
    jsonData[2].Title3 ='c'

    workbook.update('Sheet1', jsonData) // 更新

    return workbook.commit() // ファイルに書き込み
  })
  .catch(error => {
    throw error
  })
```
### 書き換え前のExcelファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331674/7ff013d8-933d-27b5-b56d-73a2c991fe3a.png)
### 実行ログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331674/e7a5e4e8-bc0b-b789-04b8-1647597eb2e1.png)

### 書き換え後のExcel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331674/4b4a22f7-0c72-954f-30ca-e0d71a2770a4.png)

ExcelデータをJSONデータとして扱えるのでjQueryやunderscoreを組み合わせるとwhere検索や絞り込みが行えるのでかなり使えるノウハウと思います☺

エンジニアに役立つ情報をTwitterでも発信していますので宜しければTwitterの方もフォローをよろしくお願いします！
[Twitterへのリンクはコチラ](https://twitter.com/mr_t_free)
mbed講座-第１回　DigitalOut-デジタル出力

## 概要

ピンを出力に設定し、HighまたはLowを出力します。

主にLEDなどに用いられます。



## 初期化

今後もそうですが、ピンを実際に使用するにはそのピンをどのように使うのか宣言をする必要があり、これを初期化と言います。これは通常書き方が決まっており、mbedでは

`用途 名前(使用するピン名)`

という形で書きます。



**DigitalOut name(pin);**

name: 名前（自由に決めて良い）
pin: ピン名（p5～p30、LED1～LED4）

mbed基板上のLEDを点灯させる場合はLED1～LED4を指定します。



## 出力

**name = 0;**

**name = 1;**

0:Low(0V)、1:High(***3.3V***)を出力します。

注意する点は、マイコンによって3.3vのものと5vのものがあります。

例を挙げればArduino Unoは5v駆動です。

ここで、3.3v用の回路に5vの入力を与えると壊れてしまう可能性があります。

使用する前にマイコンの電圧と制御する対象の電圧が一致している確認しましょう。



## 実際に使ってみよう

```c++
#include "mbed.h"
 
DigitalOut myled(LED1);
 
int main() {
    while(1) {
        myled = 1;
        wait(0.25);
        myled = 0;
        wait(0.25);
    }
}
```

このコードをオンラインコンパイラ（またはオフラインコンパイラ）に貼り付けてコンパイルしてみましょう。

オンラインコンパイラの場合、エラーがなければ***.binというファイルがダウンロードされます。このファイルをUSBにつないだmbedにドラッグ&ドロップしましょう。

ここでもう一つ注意点です。mbedはファイルを**コピーするだけでは動いてくれません**。コピーした後に一回リセットする必要があります。リセットするにはmbedの中央にあるボタンを押しましょう。

さて、リセットするとどのような動作をするでしょうか？

おそらく左端のLEDが点滅するはずです。



### 課題

LEDの点滅周期を1秒にするにはどのようにすればいいでしょうか？