OmniAICreator/Qiita-1.07M huggingface dataset:
復旧確認するまでが、透過的データ暗号化だから！！

暗号化できたわーいわーいで終わらせないで！
いろいろ気を付けないといけない事あるよ！

## TL;DR

* 透過的暗号化は、設定だけなら超簡単
* でも設定して終わりじゃなくて、復旧確認するまでが透過的暗号化設定！  
[そこの認識をごまかす輩は生涯地を這う！](https://matome.naver.jp/odai/2147255639965287001#2147255922867611403)
* 透過的暗号化は、製品によっては超高いライセンス費が発生する
* ファイルの暗号化であって、SQLインジェクション対策ではない

## 透過的暗号化は、設定だけなら超簡単

MySQLなら、`/etc/my.conf`に3行追加して、`chown`と`chmod`して`mysqld`を再起動するだけ
詳細は[こちら](https://qiita.com/hmatsu47/items/476d446887244de17ae4)

SQLServerなら、こんなクエリ流すだけ

```sql
USE master;  
GO  
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<UseStrongPasswordHere>';  
go  
CREATE CERTIFICATE MyServerCert WITH SUBJECT = 'My DEK Certificate';  
go  
USE AdventureWorks2012;  
GO  
CREATE DATABASE ENCRYPTION KEY  
WITH ALGORITHM = AES_128  
ENCRYPTION BY SERVER CERTIFICATE MyServerCert;  
GO  
ALTER DATABASE AdventureWorks2012  
SET ENCRYPTION ON;  
GO  
```
詳細は[こちら](https://docs.microsoft.com/ja-jp/sql/relational-databases/security/encryption/transparent-data-encryption?view=sql-server-2017#using-transparent-data-encryption)

OracleとPostgreSQLは知らんけど、まぁ簡単なんじゃないの？しらんけど。

## ただし実際運用するとなると、簡単ではない

### 1. 必ず復旧試験をしないといけない

そもそも透過的データ暗号化とは何を防ぐ目的で存在するのか？
それは、データベースファイルが盗まれても、
キーファイルやキーフレーズを持っていない人に中身を読み取られないようにするため。

つまり透過的データ暗号化を行ってしまうと、
バックアップファイルからデータを戻すのにこれまで不要だった
キーフィアルやキーフレーズを指定するという一手間を追加するということになります。

実際暗号キーを適切に管理していれば、すぐ復旧できるじゃん？と思うかも知れないけれど、
人間とは間違いを犯すものであるという原則に立つなら、
「作った暗号キーを取り違えていた」とか
「キーフレーズをコピペするまでにキーボードに手があたって、変な文字列が追加/削除されていた」
ということがないとは言えないわけで、
そうすると、
障害等でストレージが逝ってしまった場合や、サーバ筐体変更とかしようとするときに、
データが取り出せないという事態になってしまう。

ホットスワップ設定をしたら、ちゃんと障害時に切り替わるかを確認するように、
無停電電源装置を入れたら、電源切れたときにちゃんと継続稼働してくれるか確認するように([^1])、
透過的データ暗号化をしたら、別筐体でデータ復旧できるかキチンと確認しないといけない。

**復旧試験するまでが透過的データ暗号化設定だからね！**
良い子のみんな、約束だよ！

[^1]: AWSでも無停電電源装置の切り替えに[失敗している](https://japan.cnet.com/article/35018865/)

### 2. キーの管理が大変

透過的データ暗号を行うと、キーフレーズだったり、キーファイルだったりが生成される、もしくは指定します。
そのキーフレーズ・キーファイルをどこに保管するのかというのは結構やっかいな問題です。

データベースファイル奪取への対策としての透過的データ暗号化ですが、
そもそも巨大になりがちなデータベースファイルの流出ケースが、

* 内部犯行者が、サーバからコピー
* 内部犯行者が、バックアップ先のストレージから奪取
* 外部の人間が破棄したHDDなどから復元

などになります。

つまり、データベースファイルと同じ筐体に置くことはもちろん、
共用ファイルサーバに置くことも、内部犯行者にとって全くセキュリティ強化になりません。
一方で、ストレージ障害時に迅速に復旧できるよう、
サーバ管理者からは即時アクセスできる場所に保管する必要があります。

なお、サーバ管理者から内部犯行者が絶対出ないという保証もありません。

暗号化はできても、そのキーフレーズ・キーファイルをどう保管するか、
迅速な復旧を諦めるのか、セキュリティの穴をある程度許容するのか、
あるいは上手い方法を考える必要があります。

### 3. 一部の製品はライセンス費がめっちゃ高い

透過的データ暗号化を行うには、どれもEnterprise Editionを使う必要があり、
ライセンス費が、SQLServerは桁が2つ違うし、Oracleも桁が一つ違う。

MySQL ~~とPostgresQL~~ は透過的データ暗号化しても現時点では無料。([^2])
なお、Oracle傘下のMySQLの将来は心配。

[^2]: 不正確な記載を改めました。PostgresQLは、NECさんのOSSを使えば無料でやれるだけで、標準では付いてませんでした。指摘をくれた @niharu さんありがとうございます！

### 4. SQLインジェクション対策とかにはならない

あくまで、データベースファイルを奪取されたとき対策であって、
透過的データ暗号化してもSQLインジェクションは普通に起きてしまいます。
DBに関する他のセキュリティ対策が不要になるわけではありません。

「暗号化」というワードで辺に勘違いする人がいますが。

## まとめ

[TL;DR](#tldr)に書いた。
[学習用]実装して失敗したとき。戻したいときに覚えておきたいGit

実装の実験の為、commitしないでVagrantサーバーでテストしたが、
エラーが戻らなくなったので、実装前に戻したくなった。

しかし残念なことに戻らなかった。

#自分でやった、出来たけど間違っている方法
※まだbranchは学習してない
pull heroku master , git reset --hard もその前に試したが
ファイルが戻らず混乱した為、強行した内容。

```
１：Vagrant 内の.git 以外を全削除
２：$ git clone https://git.heroku.com/アプリ名.git
３：$ bundle install
４：$ rails db:migrate
５：$ rails s
６：.git の config ファイルが変だったので修正する
　　※git push heroku master がエラーで出来なかった為
```

##修正した config

```
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "heroku"]
	url = https://git.heroku.com/アプリ名.git
	fetch = +refs/heads/*:refs/remotes/heroku/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
```

[remote "heroku"]とrefs/remotes/heroku/が origin に
なってたのでheroku へ修正した。

#branchを試す
こういうときの為にbranch がある様です。

```
git checkout -b 任意の名前
とすると、master に干渉しないラインが出来上がります。
そこで作業して、heroku へは
git push heroku 任意の名前
```

で出来る様です。


#ブランチを作成する
```
1:$ git checkout -b testbranch
　Switched to a new branch 'testbranch'
2:作業して
  $ git add .
  $ git commit -am "testbranch"
3:$ git checkout master
4:$ git merge testbranch
  ※この時点でtestbranchで管理しているコードが masteに反映される
5:$ git add .
6:$ git commit -am "comment～略～"
7:$ git push heroku master
8:$ heroku run rails db:migrate
```

これで無事にアップ出来ました。
本来は、複数人で開発する場合、それぞれのブランチで開発して、
管理者がmasterブランチに取り込んでいくという使い方をする様です。
GPSの研究　その39

#概要
GPSを理解したかった。
電子基準点データを落としてみた。

#近くの基準点を探す。

http://jsdo.it/ohisama1/gGNk

#通算日を求める。

http://jsdo.it/ohisama1/8LK4

#セッション番号を求める。

9時が、a。xは、8時。

#urlを求める。

ftp://terras.gsi.go.jp/data/G_2.11/2018/190/0198190k.18n.gz
ftp://terras.gsi.go.jp/data/G_2.11/2018/190/0198190k.18o.gz

2018は、年。
190は、通算日。
0198は、基準点の下4桁。
kは、19：00から20：00
18nは、navファイル。
18oは、obsファイル。

以上。
AWS Cloud9 Python3の環境でvenvを使って仮想環境を構築する方法

#Pythonの仮想環境とは
Pythonで開発を行う際には多くのパッケージをインストールして開発します。
Pythonの仮想環境を構築すると、それらのパッケージをプロジェクトごとに管理することが可能です。
Pythonの仮想環境を構築するツールは複数ありますが、今回はAWS Cloud9に最初から用意されている「venv」を利用して説明を進めます。

#AWS Cloud9 Python3 環境の確認
python及びpipは下記のバージョンを利用しています。

```
$ python -V
Python 3.6.5

$ pip -V
pip 9.0.3 from /usr/lib/python3.6/dist-packages (python 3.6)
```

#プロジェクト用ディレクトリの作成
下記のコマンドでプロジェクト用のディレクトリを作成し、作成したディレクトリに移動してください。

```
$ mkdir MyProject
$ cd MyProject/
```

#仮想環境の作成
venvコマンドで仮想環境を作成してください。
venvコマンドの後には仮想環境の名前を指定します。下記の例では「venv」という名前で仮想環境を作成しています。

```
$ python -m venv venv
$ 
```

仮想環境が正常に作成されると下記のように仮想環境名「venv」のディレクトリが自動的に作成されます。
![01_仮想環境の作成.png](https://qiita-image-store.s3.amazonaws.com/0/131520/e7773c58-2658-2bbe-bc90-a21b2655de15.png)

#仮想環境の有効化
下記のコマンドを実行することで仮想環境を有効化することができます。
仮想環境の有効化が成功すると仮想環境の名前がコンソールの前に表示されるようになります。

```
$ source venv/bin/activate
(venv) $ 
```

#仮想環境の状態確認
仮想環境上で状態を確認してみましょう。「pip」のパッケージ保存先が変更されていることが確認できるはずです。
仮想環境をアクティブにした状態で「pip」利用してパッケージインストールを実施すると、下記に表示されているディレクトリにインストールされます。

```
(venv) $ python -V
Python 3.6.5

(venv) $ pip -V
pip 9.0.3 from /home/ec2-user/environment/MyProject/venv/lib64/python3.6/dist-packages (python 3.6)
```

#仮想環境のパッケージを確認
仮想環境にパッケージが何もインストールされていないことを確認しましょう。
下記のコマンドを実行すると「pip」でインストールされているパッケージの一覧を表示することができます。

```
(venv) $ pip freeze
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```

#仮想環境のpipをアップグレード
pipのバージョンが最新版ではないという警告が出ているので、pipのバージョンを最新バージョンにアップグレードしておきます。

```
(venv) $ pip install --upgrade pip
Cache entry deserialization failed, entry ignored
Collecting pip
  Downloading https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 963kB/s 
Installing collected packages: pip
  Found existing installation: pip 9.0.3
    Uninstalling pip-9.0.3:
      Successfully uninstalled pip-9.0.3
Successfully installed pip-10.0.1

(venv) $ pip -V
pip 10.0.1 from /home/ec2-user/environment/MyProject/venv/lib64/python3.6/dist-packages/pip (python 3.6)
```

#仮想環境へのパッケージインストール
仮想環境にパッケージをインストールしてみましょう。
今回の例では「django」をインストールし、正常にパッケージがインストールされたことを確認しています。

```
(venv) $ pip install django
Collecting django
  Downloading https://files.pythonhosted.org/packages/ab/15/cfde97943f0db45e4f999c60b696fbb4df59e82bbccc686770f4e44c9094/Django-2.0.7-py3-none-any.whl (7.1MB)
    100% |████████████████████████████████| 7.1MB 6.0MB/s 
Collecting pytz (from django)
  Downloading https://files.pythonhosted.org/packages/30/4e/27c34b62430286c6d59177a0842ed90dc789ce5d1ed740887653b898779a/pytz-2018.5-py2.py3-none-any.whl (510kB)
    100% |████████████████████████████████| 512kB 13.1MB/s 
Installing collected packages: pytz, django
Successfully installed django-2.0.7 pytz-2018.5

(venv) $ pip freeze
Django==2.0.7
pytz==2018.5
```

#仮想環境の無効化
仮想環境を無効化するためには、下記のコマンドを実行してください。
無効化が成功するとコンソールの(venv)という表示が消えるはずです。

```
(venv) $ deactivate
$
```

#仮想環境の削除
仮想環境を削除する場合は、venvのディレクトリをのまま削除すれば問題ありません。
下記のコマンで削除を行うことができます。

```
$ rm -rf venv/
```

以上です。
PythonでCSVから折れ線グラフを作る

これまではExcelを使ってCSVファイルをグラフ化していましたが、見た目の調整やそもそもセルの範囲が正しく選択されているかを確認するなど、かなり手間がかかっていました。Python（pandas）を使うと簡単にグラフ化できたため、手順をまとめてみました。


GitHub：https://github.com/unhurried/python-csv-to-line-graph


```python
# Generate a fake csv file.

import datetime
import random

file = open("data.csv", "w")

# header
file.write("date,data1,data2\n")

# data
date = datetime.datetime.now()
data1 = 0.5
data2 = 0.5

for i in range(100):
    date = date + datetime.timedelta(seconds=1)
    data1 = data1 + random.uniform(-0.01,0.01)
    data2 = data2 + random.uniform(-0.01,0.01)
    
    file.write(date.strftime("%Y/%m/%d %H:%M:%S"))
    file.write(",")
    file.write(str(data1))
    file.write(",")
    file.write(str(data2))
    file.write("\n")

file.close()
```


```python
# A function that draws a line graph from a csv file.

%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import os

def draw_line_graph_from_csv(file_name, x_axis, y_axes=None):
    df = pd.read_csv(file_name)
    filter = [x_axis] + y_axes

    title = os.path.basename(file_name)
    df[filter].plot(x=x_axis, title=title, grid=True, rot=10, figsize=(6, 4))
```


```python
draw_line_graph_from_csv('data.csv', 'date', ['data1'])
```


[![output_3_0.png](https://qiita-image-store.s3.amazonaws.com/0/186068/1aab0ca0-8560-d847-7b49-356f6103eb2c.png)



```python
draw_line_graph_from_csv('data.csv', 'date', ['data1', 'data2'])
```


![output_4_0.png](https://qiita-image-store.s3.amazonaws.com/0/186068/71a58800-ce48-3277-f5f1-32f2987341ee.png)
組み込みエンジニア歴13年がキャリアプランを考え直してみた

キャリアプランに悩むエンジニアが、納得感を持って最初の第一歩を踏み出せたらいいな、という想いで書きました。

初投稿です。温かいお気持ちで読んでいただけたら幸いです。

大手メーカー勤務、組み込みエンジニア歴13年、33才の私は、恥ずかしながら未だにキャリアプランに悩んでおります。
悩んだ末にやっと、「やりたいこと」が見えて具体的な行動が起こせています。
そこに至る過程を公開いたします。

# 要点
**「自分にはできないことから逃げること」**ことが、私のやりたいことだとわかった。
そんな私にとっての第一歩は、現在の会社の仕事の、責務と時間をなるべく減らして、自分でWebサービスを立ち上げてみること、だとわかった。

# 目次
1. 「やりたいこと」を見つけるの難しい
2. 「やりたいこと」に比べて「できないこと」はわかりやすい
3. **「できないことから逃げること」** が 「やりたいこと」
4. 私がたどり着いた「やりたいこと」（逃げたいこと）
5. 逃げた先でも「できないこと」がたくさんある危険性
6. まとめ

# 1.「やりたいこと」を見つけるのは難しい　

私、大手メーカーでソフトウェアエンジニアをしており、10年以上勤続させていただいております。

皆さんご存知の通り、ソフトウェアエンジニアといっても多岐に渡り、インフラエンジニア、組み込みエンジニア、ネットワークエンジニア、アプリエンジニアなど様々です。また、PM、要件定義、アーキテクチャ設計、品質保証（テスト）など、様々なキャリアを選択することができます。

私は、「なんでもできるけど、実は何にもできない」みたいな、よく言う、今後生き残っていけるの？系なエンジニアです。
そんななか、職場にて「結局あなたは何がやりたいの？」と聞かれることが多いです。
  
僕自身、恥ずかしながら３３才で未だに「自分はこれがやりたいんだ！」という覚悟を持った答えが見つかっていおりません。
ただし、はじめの一歩は模索しながら徐々にでもわかってきたような気がしており、理想に近づいている感覚があります。


# 2.「やりたいこと」に比べて「できないこと」はわかりやすい

逆転のアプローチで「できないこと」とか「やりたくないこと」をリストアップしてみてみました。
私はネガティブなことのほうが出しやすい性格なんです。意外と多いんじゃないかな？とおもいます。

**私ができないこと**

- ユーザーの喜ぶ姿が想像できない製品開発に力を注ぐこと
- 興味が無い人、嫌いな人　と長時間、密に接すること
- 社内の組織上の問題に対して力を注ぐこと
- 物は作れなくとも、社内政治が上手い人が偉くなる場所で頑張ること


いわゆる一般的な日本の大手企業に入ると、だいたい上記が求められるんじゃないかな。
私にはうまくできなかった。それにやりたくもない。

# 3.**「できないことから逃げること」** が 「やりたいこと」

「できないこと」がわかったら、「じゃあこれをやらずに済むにはどうしたらいいんだろう？」と考え出てみる。
「やりたいこと」をダイレクトに見つけるよりも、だいぶやりやすくなりました。

私としては「組織に縛られる時間」から逃げてみようと思っています。
完全なる脱出は難しいですが、少しづつ試しながら進めていっております。
この活動は自分の中でもしっくり来ており、「あぁ、これがやりたいことなのかもしれない」という納得感もあります。

# 4. 私がたどり着いた「やりたいこと」

やりたい事は会社ではやらず、帰宅後や休日にやる。
そのかわり、会社の仕事の負担（責任＆業務量）を減らしてもらえないか、上司に相談する。

サービス/プロダクトの企画、開発、試験、営業、運用の全てをリードする。
「身近な友人」が助かるサービス/プロダクトを開発する。
会社という名刺が無くなった自分の力が、どのくらい市場価値があるのか、試してみたい。

## 具体的にやっていること 

- ダンススタジオの業務改善システム構築
    - 作業効率UPとデータの矛盾発生を防ぐ
    - ExcelVBA
    - 現在運用中
    - 成果が出たあとでそれに合う対価のお金をもらう予定
 
- 友達のダンスサークルのWebSiteを作成（無料）
    - https://soulspice.tokyo/
    - HTML + CSS + JavaScript
    - サークルメンバーの意見を反映済み。
    - 運用開始直前
- 楽しい場所を探すWebサービス　FunSpotの作成（無料）
    - Ruby On Rails + Swift
    - 現在技術検討中
        - ドットインストール
        - Udemy
    - ミニマムな要件定義をして2018年7月31日までに一般公開を目指す

## 今後の想定
 
- プロジェクトに応じて必要な人材を5〜6人集める。
- プロジェクトが終わったら解散。
- Give & Takeの関係が成り立つ人とは再度仕事を行う
- 成り立たない人とは疎遠な付き合いをする。

## 会社の業務について

- 上司に相談して会社の仕事の負担（責任＆業務量）を減らしてもらう。
- 昇給を諦める
- 会社にやりがいは求めない。

## 現状
まだお金にはなっていないものの、未来へのつながりを感じながら充実した日々をおくっています。


# 5. 逃げた先でも「できないこと」がたくさんある危険性

結局、逃げた先でも同じように苦しい目にあうんじゃないの？というご意見があると思います。
そうですね。ありえるパターンだと思います。

これを避けるためには、「自分が何ができないか」を的確に、素直に捉える必要があります。
また、「それができなくても良い世界」をしっかりと探し当てる必要があります。

また、逃げた先でも自分の観察をやめないことが大事だと。
それでまた、もっとコアな「できないこと」がみつかったら、それをどう回避すればいいか、探してみるのがいいとおもいます。

たくさんの経験、自己分析、自分の感覚を客観的にとらえる、などさまざまなこのあたりの工夫については、次回以降で記載したいと考えています。
    

# まとめ

**「できないことから逃げること」** を 「やりたいこと」にしてもいいんじゃないでしょうか。
Railsでエラーが出た時 初心者

Railsでエラーが出た時は、再起動
基本的には、コードを保存するだけで更新されるが
そうはいかない時がある。

コードを変更しても前回の出力と変わらない場合は、サーバーの再起動で解決する

## サーバーの再起動
railsのサーバー(puma)のprocessidを調べる

```
$ ps ax | grep puma
```

停止

```
$ kill -2 {processid}
```

(デーモン化で)起動

```
$ rails s -b 192.168.33.10 -d
```
Oracle Databaseバックアップ方針検討


# Oracle Databaseバックアップ方針検討
以下ASMディスクグループ構成を前提にストレージバックアップやファイルバックアップをどのように実施すべきか検証する。
※各ASMディスクグループ単位でバックアップ・リストアができるものとする。
※ASM/DBSPFILEと制御ファイルは個別にファイルバックアップ。
※ファイルバックアップとストレージバックアップいずれからも戻せれば、DG再作成&ファイルバックアップを選択する。


ASM DG00  ASMSPファイル格納
ASM DG01  制御ファイル・オンラインREDOログ①系格納
ASM DG02  制御ファイル・オンラインREDOログ②系格納
ASM DG03  表領域、DBSPFILE格納
ASM DG04  アーカイブREDOファイル格納

## 単一障害時の復旧方法
| NO.| 障害部位 |復旧方法|
|:-------|:---------------------------|:------------------|
| ①| DG00|DG再作成。ASMSPファイルをファイルバックアップからリストアして復旧|
| ②| DG01|DG再作成。冗長化しているDG(DG02)から制御ファイル、オンラインREDOログを戻して復旧|
| ③| DG02|DG再作成。冗長化しているDG(DG01)から制御ファイル、オンラインREDOログを戻して復旧|
| ④| DG03|DGをストレージ機能でリストア実行。必要に応じてロールフォワード|
| ⑤| DG04|DGをストレージ機能でリストア実行。|

## 複合障害時の復旧方法
※DG00は他のDG格納コンポーネントと依存関係ないため複合パターンは考えない。

| NO.| 障害部位 |復旧方法|
|:---------|:---------------------|:---------------------------------------------|
| 1| DG01/DG02|DG01,DG02再作成&制御リストア後、DG0３ストレージリストアして不完全リカバリ|
| 2| DG01/DG03|単一障害時②→④|
| 3| DG01/DG04|単一障害時②→⑤|
| 4| DG02/DG03|単一障害時③→④|
| 5| DG02/DG04|単一障害時③→⑤|
| 6| DG03/DG04|DG03,04をストレージリストアしてリカバリ|
| 7| DG01/DG02/DG03|DG01,DG02再作成&制御リストア後、DG0３ストレージリストアして不完全リカバリ|
| 8| DG01/DG02/DG04|DG01,DG02再作成&制御リストア後、DG0３,DG04ストレージリストアして不完全リカバリ|
| 9| DG01/DG03/DG04|単一障害時②→DG03,DG04をストレージバックアップから戻しリカバリ|
| 10| DG02/DG03/DG04|単一障害時③→DG03,DG04をストレージバックアップから戻しリカバリ|
| 11| DG01/DG02/DG03/DG04|DG01,DG02再作成&制御リストア後、DG0３,DG04ストレージリストアして不完全リカバリ|
Cygwin + Vagrant + Node.js + Express の環境構築めも

備忘用。

##CentOS7.5用のboxセットアップ
`mkdir <centos75みたいなの>`
`vagrant init <centos75みたいなの>`

```shell
$ cat Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
  end
  config.vm.box = "bento/centos-7.5"
  config.vm.network "public_network"
  config.vm.network "forwarded_port", guest: 3000, host: 3000, id:"http"
  config.vm.network "private_network", ip: "192.168.xxx.yyy"
  config.vm.synced_folder "main","/home/vagrant/main", owner: "vagrant", group: "vagrant", mount_options: ["dmode=777", "fmode=777"]
end
```

・ユーザ / パスワード は、下記になる。
`vagrant / vagrant`

##ホスト側の共有フォルダ作成
`mkdir main`

##box初期化と接続
`vagrant up`
`vagrant ssh`

##タイムゾーン変更
`sudo timedatectl set-timezone Asia/Tokyo`

##CentOS7.5 最新化
`sudo yum -y update`

##日本語化
```shell
sudo localectl set-locale LANG=ja_JP.utf8
sudo localectl set-keymap jp106
source /etc/locale.conf
```

・確認
`echo $LANG`
ja_JP.utf8　になっていることを確認。

`passwd`
なんかのコマンド打って日本語になっていることを確認する。

##VagrantのboxのGuest Additionsのアップデート
共有フォルダのエラー対策

```shell
vagrant plugin install vagrant-vbguest
vagrant vbguest
```

・インストールされたバージョンの確認
`vagrant vbguest --status`
`vagrant reload`

##nodeの設定
```shell
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash
vi .bash_profile
 以下を追加
    # nvm設定
    if [[ -s ~/.nvm/nvm.sh ]];
     then source ~/.nvm/nvm.sh
    fi
source ~/.bash_profile
nvm install v8.11.3
nvm alias default v8.11.3
nvm use v8.11.3
```

##Express設定
```shell
npm i -g express-generator
cd main
express -e (expressのひな型を作成)
ls
npm install express --no-bin-links　(必要なmoduleをインポート)
DEBUG=node-test:* npm start (アプリの立ち上げ)
```

※Windows環境でnpm installでエラーが発生する場合の対処法

```
npm ERR! EPROTO: protocol error, symlink '../mime/cli.js' -> '/home/vagrant/project/node_modules/.bin/mime'
```
とでたら
`npm install express --no-bin-links`
とする。

##Express見る
http://localhost:3000/
Linebot+ Python+ Herokuでオウム返し(サンプル)を動かしてみました。

Linebot+ Python+ Herokuに関する知見。

参考：
https://qiita.com/akabei/items/38f974716f194afea4a5
https://qiita.com/cfiken/items/0715bb945389bc9ca682
https://developers.line.me/ja/docs/messaging-api/building-bot/

##　Who am I
https://qiita.com/Senple/items/b47374e68e4d8d26d0cb
いつも通り↑を見てください。
環境などもこちらに記載してあります。

##　Herokuで事故った点
https://devcenter.heroku.com/articles/getting-started-with-python#introduction
Herokuに関しては↑をもとに書いています。
忘れそうなので簡単な備忘録を…。


```
heroku ps:scale web=0
#中止にするコマンド
heroku ps:scale web=1
#起動するコマンド

heroku ps
#現在いくつdynoが残っているのか、その他の情報などが書いてある。
```
web=0：URLを見ると、Application Errorとなる。
web=1：起動していて実行できる。
dynoについては、[こちら](https://codezine.jp/article/detail/8344)を見てください。
~~詳しくわかってない~~
dynoはお金に関することなので、大事！

## LineBotで事故った点

LineBotに関しては、
https://qiita.com/akabei/items/38f974716f194afea4a5
http://cppx.hatenablog.com/entry/2017/10/31/165128
こちらをめちゃくちゃ参考にしたのですが、二点わかりづらかったところを…。


####1、Procfileの作り方
Procifleについては、テキストファイルを最初に作って、ファイルに↓を記述したのち、保存する。

```Pyhon:Procfile(拡張子なし) 
web: python main.py
```

そして、ファイル名をProcfileにする(.txt←拡張子を消去する)


####２、Webhookが言うこと聞かない！
https://developers.line.me/console/ のwebhookの部分でURLが期待通りの返答を返していないと再三注意されて意気消沈していたのですが、「ええい、ままよ」とか叫んでQRコードで確認したら、期待通りの動きを示してくれたので、みんなは意気消沈せずにまずは、Lineアプリ上で確認してみてください。


ものすごい勢いで書きなぐりました。
後で清書します。
~~今日(2018年7月9日)はもう寝ます。~~
toggleを使用した要素の表示、非表示の実装

<h2>Ruby,Rails初学者の私が今日悩んだ点、最近分かったことなど知識をまとめています:wink:</h2>

<p><strong>目的:</strong></p>
<ul>
<li>自己理解</li>
<li>情報共有:sweat:</li>
<li>情報整理</li>
</ul>

<p>トピックス<p>
<ul>
<li>ログイン、ログアウト時のviewの実装</li>
<li>toggleを使用した要素の表示、非表示の実装</li>
</ul>

<h2>
ログイン、ログアウト時のviewの実装
</h2>
<p>deviseでログイン機能が実装されており、ログインボタンを押すとログインボタンがユーザのアイコンになる仕様になる。
</p>
<ol><p>作業の過程</p>
<li>まずは取り掛かり安さでユーザアイコン用のhaml,scssを実装(ファイルは新しく作らず、ログイン機能ボタンのあるviewファイル内で作業をし、コメントアウトなどを活用しいつでも戻せる状態を保ちました。)</li>
<li>ユーザがログインしていない時は<code>unless user_signed_in?</code>をログインボタンの直前に実装、ログインしているときは<code>if user_signed_in?</code>を実装した。</li>
</ul>

<h2>toggleを使用した要素の表示、非表示の実装</h2>
<ol><p>ログインしているときのユーザアイコンをクリックした時にメッセージやログアウトなどのリンクが表示されるパネルをjQueryのtoggleメソッドを使用し実装</p>
<li>アイコンの要素に対しクリックメソッドを追加した。</li>

```bash:index.html.haml

$(function(){
  $('img').click(function(){})
})

```

<li>クリックした時にパネルの要素が表示され、サイドクリックすると隠れる機能を<code>toggle</code>を使用し実装した。</li>

```bash:index.html.haml

$(function(){
  $('img').click(function(){
     $('.header__right-panel').toggle();
  })
})

```
</ul>


<h2>
実装の感想〜toggleにたどり着くまで
</h2>
<ul>
<li>実装自体は大したコードではないのですが、たどり着くまでにきづいたら1日費やしていました。:joy:</li>
<li>ログイン、ログアウトの実装はどこに対して何を変化させたいのかを改めて紙に書いたりして考えました。</li>
<li>jQueryを使った実装では、gemやっていファイルの記述、bundle install して、、など実装周りの調査、実装時のメソッドで<code>remove, append, hidden, unwrap... どれ使えばいいんだ</code>など。なのでtoggleを発見したときは凄いメソッドキタ！て思いました。。:disappointed:</li>

</ul>

<h2>
to be continued...
</h2>
<p>”この瞬間から集中する”みたいな集中する時間を意識的に作り、疲れるまで考え、休む。とことんできないことで落ち込んだりしてまた考える...といった風に効率よく作業をしていきたいです。:thinking: :) </p>
Mbed(LPC1768)でGPSのデータを取得する

#はじめに
LPC1768をつかってGPSを取得するやり方の備忘録。

#使うもの
Mbed LPC1768
https://www.switch-science.com/catalog/250/
GPS AE-GPS　
http://akizukidenshi.com/download/ds/akizuki/AE-GPS_manual_a.pdf

#手順
##➀配線する
<img width="282" alt="mbed_GPS.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/253009/7e73bfc7-0cb0-f9aa-bccd-ba31d770dff1.png">

今回はp9,p10のピンを使ったけれど、LPC1768はSerialピンを3セット持っているのでp13,p14やp28,p27でもよい。

##②コードを書く

```GPSscript.cpp
#include "mbed.h"
#include "math.h"

#define TIME_GAP      6.0   
 
Serial           gps(p9,p10);   //ピンを指定

Timer  timer_open;
Timer  timer_log;
Ticker tic_open;
Ticker tic_log;

float   _DMS2DEG(float raw_data);
int     _input(char cha);
 
float Time;
char  gps_data[256];
int   cnt_gps;
int   Cnt_GPS=0;
 
int main(){
    while(1){     
        if(gps.readable()){
            gps_data[cnt_gps] = gps.getc();
            if(gps_data[cnt_gps] == '$' || cnt_gps ==256){
                cnt_gps = 0;
                memset(gps_data,'\0',256);
            }else if(gps_data[cnt_gps] == '\r'){
                float world_time, lon_east, lat_north;
                int rlock, sat_num;
                char lat,lon;
                if(sscanf(gps_data,"GPGGA,%f,%f,%c,%f,%c,%d,%d",&world_time,&lat_north,&lat,&lon_east,&lon,&rlock,&sat_num)>=1){
                    if(rlock==1){
                        lat_north = _DMS2DEG(lat_north);
                        lon_east = _DMS2DEG(lon_east);
                        printf("%s\r\n",gps_data);
                        printf("Lat:%f,Lon:%f\r\ntime:%f,sat_num:%d\r\n",lat_north,lon_east,world_time,sat_num);
                    }else{
                        printf("%s\r\n",gps_data);
                    }
                }
            }else{
                cnt_gps++;
            }
            
        }
        if(timer_log.read()>=30.0*60.0) timer_log.reset();
    }
}

float _DMS2DEG(float raw_data){
    int d=(int)(raw_data/100);
    float m=(raw_data-(float)d*100);
    return (float)d+m/60;
}
```

参考 http://www.hiramine.com/physicalcomputing/general/gps_nmeaformat.html?iframe=true&width=1040&height=620

#③Tera Termで表示

<img width="498" alt="GPS_result.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/253009/27a7bd58-21d6-a36f-f38e-42137f34ae0e.png">

電波がんばれ...。
rails モデルのカラム名(論理名)を定義してviewやcsvヘッダ名に使う

フォーム作成時のフィールドのラベルやView内でのテーブルヘッダ、CSV出力時のヘッダを別ファイルで定義して呼び出す。i18nというgemを使用する。

## 利用シーン
いくつかの場面で、定義を呼び出せるようになっています。

### form_for
・呼び出し方法
```f.label :カラム名```

```html:xxx.html.erb
<%= form_for(@user, url: users_path) do |f| %>
  <div>
    <%= f.label :email %>
    <%= f.label :name %>
  </div>
<% end %>
```

### CSVのヘッダ名
・呼び出し方法
`モデル.human_attribute_name("カラム名")`


```ruby:xxx.csv.ruby
CSV.generate do |csv|
  cols = [
    User.human_attribute_name("email"),
    User.human_attribute_name("name"),
    User.human_attribute_name("address"),    
  ]
```

### view内でのモデル名やカラム名の呼び出し(CSVのヘッダ名の例と呼び出し方法は同じ)

・呼び出し方法
`モデル.human_attribute_name("カラム名")`

```html:xxx.erb.html
<table>
  <tr>
    <th><%= User.human_attribute_name("email")</th>
    <th><%= User.human_attribute_name("name")</th>
  </tr>
</table>
```

## 定義

ここでは[i18n](https://railsguides.jp/i18n.html)という多言語対応を目的としたgemを利用することで、日本語の辞書を作成し、それを呼び出すようにします。

### 手順1
config/application.rbに以下をセット

```ruby:application.rb
config.i18n.default_locale = :ja
```

※セットしない場合はdefaultはen(英語)なので、のちに定義するja.ymlが呼び出されません。


### 手順2
config/locales/ja.ymlを作成し定義を書く

```ruby:ja.yml
ja:
  activerecord:
    models:
      want_list: 欲しいもの
      user: ユーザ
    attributes:
      user:
        name: 名前
        email: メールアドレス
        address: 住所
        password: 新しいパスワード
        password_confirmation: パスワード確認用(新しいパスワードを入力)
        current_password: 現在のパスワード
      want_list:
        id: id
        product: 欲しいもの
        url: URL
        comment: コメント
        want_lists_count: いいね
```

以上です。
Pythonのクラスのインスタンスメソッドを動的に追加する

ある抽象クラスの継承先で、メンバ変数のリスト内の文字列に応じてインスタンスメソッドを作るという設計をしました。
新規追加メソッド作成のロジック自体は自明なので、文字列の数分いちいちメソッドを書き下すのは冗長だし時間がかかる。
そこで外からインスタンスメソッドを代入するという方法を思いついた。
その思考錯誤が結構面白かった。


### 失敗例
```python


# ある変数のゲッターを作る
def make_getter(variable_name):
    def f(self):
        return getattr(self, variable_name)

    return f

class Parent(object):
    def __init__(self, variable_list):
        # ゲッターを代入する
        for variable in variable_list:
            setattr(self, 'get_'+variable, make_getter(variable))


class Child(Parent):

    def __init__(self):
        variable_list = ['hoge', 'fuga', 'piyo']
        super().__init__(variable_list)

```

まず上記の例だと、`Child`のインスタンスでは`child.get_hoge()`を呼ぶと素っ頓狂なエラーが返ってくる。
`TypeError: f() missing 1 required positional argument: 'self'`

なにをいってるんだ。Pythonのインスタンスメソッドの第一引数には暗黙的に自身が指定されるはずだろう。
と思うものの、素っ頓狂なことをしているのはPythonのインタプリタではなくてやっぱり自分でした。

インスタンスメソッドとして認識されるのは、**インスタンスの持つ関数ではなくて、その型であるクラスに登録された関数**のみ。
イニシャライズの途中にselfに関数を代入したからといって、インスタンスメソッドにならないということですね。いわゆるstaticmethodを追加するならこのやり方でよいということになります。

### 成功例

このため、下記ケースでは`child.get_hoge()`を想定通り実行することができる。

```python


# ある変数のゲッターを作る
def make_getter(variable_name):
    def f(self):
        return getattr(self, variable_name)

    return f

class Parent(object):
    def __init__(self, variable_list):
        # ゲッターを代入する
        for variable in variable_list:
            setattr(self.__class__, 'get_'+variable, make_getter(variable))


class Child(Parent):

    def __init__(self):
        variable_list = ['hoge', 'fuga', 'piyo']
        super().__init__(variable_list)

```

インスタンス化最中のselfオブジェクトの型クラスにsetattrして改造するということをしています。
まあ邪道実装極まりないのですが、また一つPythonに詳しくなれたのでよかったです。
Goで２つのスライスのうち片方のみに存在する要素を400倍くらい速く取り出した

https://qiita.com/Sekky0905/items/1afa6a78f0aa7354f290

これ、流石にほっとけないので400倍くらい速くしてみましたが、眠くてお手上げなので私ができたところまで解説。きっと親切な人がまさかりがてらもっと保守性が高くて速いコードを教えてくれるはず。

## 問題の内容

> Goで2つのSlice(A、B)のうち、Aにだけ存在し、Bには存在しない値を持ったSliceを生成する

大分曖昧ですが、詳細は元記事を。元記事のコードは二重ループを使う典型的な遅くなるやつだったので改造に取りかかる。
基本的には、元記事のコードと同じ要件を満たすようにする。
ただし、元記事には書いてない条件として、配列はソートされた状態で出力するものとする。

## 結果

```
BenchmarkQiita-4   	       1	2127655888 ns/op	 2303264 B/op	      28 allocs/op
BenchmarkMine0-4   	     200	   6466429 ns/op	  524352 B/op	       3 allocs/op
BenchmarkMine1-4   	     100	  18598037 ns/op	 8514379 B/op	    2432 allocs/op
```
400倍くらい速くなりました。配列長くすればもっと（相対的に）速くなります。ループもメモリ消費も実装0ベースで考えていけば良さそう。

## 私の実装0

```go
func checkDup(sliceA, sliceB []int) []int {
	s := make([]int, 0, len(sliceA))
	sort.Ints(sliceA)
	sort.Ints(sliceB)
	for i, j := 0, 0; i < len(sliceA) && j < len(sliceB); {
		if sliceA[i] == sliceB[j] {
			i++
		} else if sliceA[i] < sliceB[j] {
			s = append(s, sliceA[i])
			i++
		} else {
			if j == len(sliceB)-1 {
				s = append(s, sliceA[i:len(sliceA)]...)
			}
			j++
		}
	}
	return s
}
```

汚いコードだな…。保守性低そうですが、私が書いた中ではこれが一番速くてメモリ使いませんでした。ソートして合計一週ずつするだけの非常にシンプルな考え方。
工夫のしどころはまだまだありそうですが、眠いのでこんなもので。

## 私の実装1（map利用、遅め）

```go
func checkDup1(sliceA, sliceB []int) []int {
	s := make([]int, 0, len(sliceA))
	m := make(map[int]int, len(sliceA))
	for _, n := range sliceA {
		m[n] += 1
	}
	for _, n := range sliceB {
		m[n] -= 1
	}
	for n, count := range m {
		if count > 0 {
			for i := 0; i < count; i++ {
				s = append(s, n)
			}
		}
	}
	sort.Ints(s)
	return s
}
```
map作ってみたけど流石にソート済みには勝てなかったよ…

## テストコード

```go
func makeSlices() [][]int {
	l := 65536
	s := make([][]int, 2, 2)
	s[0] = make([]int, 0, l)
	s[1] = make([]int, 0, l)
	for i := 0; i < l; i++ {
		s[0] = append(s[0], i*3)
		s[1] = append(s[1], i*5)
	}
	return s
}

var cases = makeSlices()
```

とりあえずこんなので生成してます。
これもなんかもう少し速いやり方あった気がする…

## まとめ

二重ループに気をつけよう
層圏トポス: p29の可換性を満たす写像hが連続、すなわち射であることを示す補題



# 補題
$X$, $A$, $B$ を位相空間とし、
局所同相写像

```math
f: A \rightarrow X \\
g: B \rightarrow X
```

が存在するとする。

ここで、写像

$$
h: A \rightarrow B
$$

が存在し、

$$
f = g \circ h
$$

となると仮定する。

このとき、$h$ は連続関数である。

# 証明

任意の開集合 $W \subset B$ に対して、 $h^{-1}(W) \subset A$ が開集合であれば、 $h$ は連続である。

以下これに従って、 $h$ が連続関数であることを示す。


任意の $z \in h^{-1}(W) \subset A$ について、

$f, g$ が局所同相であることから、

```math
f|_{V'}: V' \rightarrow X_f \\
g|_{W'}: W' \rightarrow X_g
```

が同相写像となるような
$z$ の近傍　$V' \subset A$
$h(z)$ の近傍 $W' \subset W \subset B$
$f(z) = g(h(z)) \in X$ の近傍 $X_f \subset X$ および $X_g \subset X$
を得ることが出来る。

また、 $X' := X_f \cap X_g $ と置いてやると、


```math
f|_{V''}: V'' \rightarrow X' \\
g|_{W''}: W'' \rightarrow X'
```


が同相写像(①)となるような $z$ および $h(z)$ の近傍

```math
V'' \subset V' \subset A \\
W'' \subset W' \subset W \subset B
```

を得ることが出来る。

ここで、①より、 $V''$ と $X'$ と $W''$ が同相であり、

```math
g|_{X'}^{-1}: X' \rightarrow W''
```

という同相写像がとれるため、


$f = g \circ h$ より $h(V'') = g|_{X'}^{-1}(X') \subset W'' \subset W$

したがって、以上より、

任意の開集合 $W \subset B$ に対して、
任意の点 $z \in h^{-1}(W) \subset A$ について、 $z$ の近傍 $V'' \subset h^{-1}(W)$ を取れるため、
$h^{-1}(W) \subset A$ は開集合であり、$h$ は連続である。
DonkeyCar の製作（Pololu Zumo）（旧バージョン2.5.1）

![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/263672/cf5b668d-8c55-41ae-4770-6a881ac20e79.jpeg)
https://youtu.be/YkRAuzBT3Yg
![RIMG0249.JPG](https://qiita-image-store.s3.amazonaws.com/0/263672/a4735d34-40f9-91a9-6f31-2c94bbff8869.jpeg)
![RIMG0250.JPG](https://qiita-image-store.s3.amazonaws.com/0/263672/01a80f6b-34ee-fbae-ef3d-1f83f8292289.jpeg)
![RIMG0252.JPG](https://qiita-image-store.s3.amazonaws.com/0/263672/09f042e0-0f39-c399-69c2-923f8de8bdba.jpeg)
Arduino用ユニバーサルシールドに5VレギュレータとPCA9685(I2C-PWM)を搭載
#回路図
![zumosch.jpg](https://qiita-image-store.s3.amazonaws.com/0/263672/fb7ab7cf-91c0-2272-c02c-ebb02fc19b04.jpeg)
$ sudo apt-get install python3-rpi.gpio
#プロジェクトの生成
筆者のgithubからファイル一式を入手
$ git clone https://github.com/mituhiromatuura/donkey
テンプレートにzumoを指定
$ donkey createcar --template manage_zumo ~/mycar
設定ファイルもzumo用をコピー
$ cp donkey/donkeycar/templates/config_zumo.py ~/mycar/config.py
PHPで学ぶプログラミングの基礎_100DaysOfCodeチャレンジ21日目(Day_21:#100DaysOfCode)

# はじめに

この記事はTwitterで人気のハッシュタグ`#100DaysOfCode`をつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した21日目の記録です。

## 動作環境

* PHP 7.1.16 (cli)

## 本日学んだこと

* Progate_PHP学習コース1

## PHP

文字列や数値を出力するには、echoを使う。

```php
<?php echo 'Hello, World!'; ?>
```
Rubyでいうところのputs。

変数の定義は次のように行う。

```php
<?php
  $変数名 = 代入したい値;
?>
```

Rubyでは$はつけずに、変数を定義する。Javascriptでは`let`や`const`を使う。

計算の省略は以下の通り

```php
$x = $x + 1; (右の式は左の式と同じ) $x++;(++$x;のように書くと、出力前に加算される)
$x = $x - 1; (右の式は左の式と同じ) $x--;(--$x;のように書くと、出力前に減算される)

```

メソッドの定義方法は以下の通り

```php
function メソッド名(引数){
  //実行させたい処理
}

呼び出しは次のように行う。

メソッド名(引数);
※引数がなくても呼び出しに()は必要。
```

この形式はjQueryと同じ。Rubyだと`def メソッド名 end;`で行う。

メソッドを定義する時に、PHPでは仮引数として`$引数名`として定義する。

```php
function printsum($sum1, $sum2){
  echo $sum1 + $sum2;
}
```

## データの種類

* 文字列 => 「""」や「''」のようなクォーテーションで囲まれた単語
* 数値 => 1や32などの数字

## 変数とは？

データを格納しておく箱のようなもの。プログラムのコードは短ければ短いほど、バグが少なく、読みやすい。
だから変数という箱を用意して、コードを書く量を少なくする。

また、プログラムはその時々で変更されることがあるので、変数を用意しておけば、変更が最小限になるので、後々楽にすることができる。


## 組み込み関数

関数はメソッドとも呼ばれる。プログラミング言語自体に標準で使えるようになっている関数を、組み込み関数と呼ばれる。
jquery smooth scroll


```html:html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Document</title>
<!--<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>-->
<!--<script src="https://code.jquery.com/jquery-2.0.0.min.js"></script>-->
<script src="https://code.jquery.com/jquery-1.5.2.min.js"></script>
<script>
$(function($) {
  $('a[href*="#"]').click(function(e) {
    var speed = 300,
        easing = 'swing',
        anchorTop = '#' + $('body').attr('id'),
        noscrollClass = 'is-noscroll',
        noscroll = $(this).hasClass(noscrollClass) || $(this).parents('.' + noscrollClass).length,
        $scrollElm = $(document.scrollingElement || document.documentElement),
        url = location.href.split('#')[0],
        href = this.href.split("#")[0],
        target = this.hash;
    if(!noscroll && url == href && target && !target.match(/\//) && $(target).length) {
      var targetOffset = $(target).offset().top,
          historyHash = target == anchorTop ? url : href + target;
      $scrollElm.animate({scrollTop: targetOffset}, speed, easing);
      window.history.pushState(null, null, historyHash);
      e.preventDefault();
    }
  });
});
</script>
</head>
<body id="pagetop">

<p><a href="./#/test">テスト</a></p>
<p><a href="./?mode=0#test" class="is-noscroll">テスト</a></p>

<p><a href="#test">テスト</a></p>
<p class="is-noscroll"><a href="./#test">テスト</a></p>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
ho
ge
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div id="test">test</div>
<br>
<br>
<a href="#pagetop">トップ</a>
</body>
</html>
```

以上、ありがとうございました。
PHP_Cording_20180709

# 三日坊主にならないように
PHPのコメントアウトはCやC++と同じ。

```php:comment_sample.php
<?php
    echo 'テスト1'; //コメント1
    /* 複数行のコメント
　　　　複数行のコメント　*/
    echo 'テスト2'; #コメント1
?>
```

連想配列から値を取り出す。

```php:array_sample.php
//連想配列
$num = array(
  array('alpha' => 'A', 'number' => 1),
  array('alpha' => 'B', 'number' => 2),
  array('alpha' => 'C', 'number' => 3)
);

foreach($num as $samp){
    foreach($samp as $samp2){
        echo $samp2 //'A'、1、'B'、2、'C'、3の順で表示される
    }
}

```
1.初めのforeachでは$numのarrayを取り出す。
2.2番目のforeachでは上記arrayの中のarrayを3つ順番に取り出す。
スマホのスクリーンショットの保存場所まとめ

# __スマホのスクリーンショットの保存場所まとめ__

## 【経緯】
 仕事でAndroidのスクショをPC取り込みしたいことがありました。
 XperiaとGalaxyを並行で作業していて、保存先が違ってちょっと悩んだのでこの機に調べたのでメモ。
 でもあんまり情報が出てこない不思議（Windowsなら右クリック＞画像とビデオのインポートで済むからだろうか・・・）
 ※基本的には機種、OSは2018/07/06時点で新しめのもの前提です。昔の機種、OSでは違う可能性大

## 【Android】
最近の有名どころだけ。さらっと調べた感じは下記の感じでした。
Androidは機種によって解像度やらカメラやらと差が激しいが、Galaxyはそれが顕著な気がする。
何とか統一化してくれると開発も楽になるのでなってくれるといいなあ・・・

* Galaxy（昔のGalaxyはまた違っているらしい？）

> スマホ本体（内部ストレージ） ＞ DCIM ＞ Screenshots　  

* Xperia
* Nexus
* Huawei系
* AQUOS 

> スマホ本体（内部ストレージ） ＞ DCIM ＞ Screenshots　  
  
* ZenPhone

> スマホ本体（内部ストレージ） ＞ Internal storage ＞ Screenshots

## 【iOS(おまけ)】
（そもそも右クリック＞画像とビデオのインポートとかiTunesとかで取得するのが正攻法なんでしょうが）
iOSにはスクショ画像とかダウンロード画像とか、Androidみたいに画像種別ごとの保存先というものがないっぽい。
そういうのは関係なく、画像（ファイル？）1000単位で「100」から連番＋「APPLE」という名前のフォルダが一つ作成されるようです。
ので、最新スクショの保存先は下記になる模様。

> スマホ本体（内部ストレージ） ＞ Internal storage ＞ DCIM ＞ 「n」APPLE（100～の番号。一番大きい数字のディレクトリの中）
>

* 例  

> スマホ本体（内部ストレージ） ＞ Internal storage ＞ DCIM ＞ 103APPLE ＞ IMG_3038.PNG
[fish shell メモ] for loop ワンライナー

###bash だと

```bash
for i in {1..5}; do echo $i; done
1
2
3
4
5
for i in 2{1..5}; do echo $i; done
21
22
23
24
25
```



### fishだと

```bash
for i in (seq 5); echo $i; end
1
2
3
4
5
for i in 2(seq 4); echo $i; end
21
22
23
24
```


### hostコマンドなどで比較

- bash

```bash
for i in 192.168.10.{1..5}; do echo $i; done | xargs -n1 host
```

- fish

```bash
for i in 192.168.10.(seq 5); echo $i; end | xargs -n1 host
```
nem-libraryを利用してJavaScriptでXEM送金する

今日からTipSLACKの中身を解剖していきます。

まずはもっとも基本となるXEM送金についてです。
比較的簡単と言われるNEMを利用したアプリ開発ですが、そのライブラリの最高峰とも言えるnem-libraryはTypeScriptの使用を推奨しており、やはり敷居が高いと言わざるを得ません。

今回はnode.js を利用した完全なピュアJavaScriptでの実装方法を紹介します。

環境構築にはこちらの記事を参考にしてください。
[amazon linuxでNode.jsのNEM開発環境を爆速で整える](https://qiita.com/nem_takanobu/items/39231820416a8a58b99a)

ライブラリは以下のようにrequireします。

```JavaScript:require
const nemlibrary = require('nem-library');
const NetworkTypes  = nemlibrary.NetworkTypes;
const Account = nemlibrary.Account;
const Address = nemlibrary.Address;
const TimeWindow = nemlibrary.TimeWindow;
const XEM = nemlibrary.XEM;
const PlainMessage = nemlibrary.PlainMessage;
const TransferTransaction = nemlibrary.TransferTransaction;
const TransactionHttp = nemlibrary.TransactionHttp;


```

メインネットへの接続は以下の1行で終わり。これは便利です。

```JavaScript:bootstrap
nemlibrary.NEMLibrary.bootstrap(NetworkTypes.MAIN_NET);
```

そして肝心の送金部分です。


```node.js

const PRI_KEY = "aaaaaaaaaaaabbbbbbbbbbbcccccccccccccc";
const address = "NXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZZZZZZZ";
const amount = 1;
const message = "これはテストです";

const transferTransaction  = TransferTransaction.create(
	TimeWindow.createWithDeadline(),
	new Address(address),
	new XEM(amount),
	PlainMessage.create(message)
);

const account = Account.createWithPrivateKey(PRI_KEY);
const signedTransaction = account.signTransaction(transferTransaction);

const transactionHttp = new TransactionHttp();
transactionHttp.announceTransaction(signedTransaction)
.subscribe(
	value => {console.log( "リクエスト結果：\n" + value.message);},
	err => {console.log( "失敗：\n" + err.toString());}
);

```

まず、TransferTransaction.create()でトランザクションを作成します。
引数に指定するのは、締め時間、送信先のアドレス、XEM量、メッセージです。

次に送金したい人の秘密鍵からAccountクラスを生成します。
そして、先ほど作ったTransactionをAccountクラスのsignTransactionで署名します。

ネットワークに乗せるにはTransactionHttpクラスを利用します。announceTransactionを呼び出すと、その結果をsubscribeで捕捉することができます。第一引数に成功時のメッセージ、第二引数に失敗時のメッセージが格納されるので、キャッチして画面に表示してください。


どうですか？とっても簡単ですね！
これを読んでもっと多くの方がNEMアプリ開発に興味をもっていただけると嬉しいです！

次はmosaicの送金にチャレンジします。ちょっと難しくなりますが、マスターすれば可能性はもっと広がりますよ！お楽しみ！
VSCodeをつかってみる

# VSCodeとは
正式名称は**Visual Studio Code**といい, Microsoftが提供しているコーディングエディタです.

# 特徴
あくまで個人的な感想です.

- 軽くて動きが機敏
- GitHubとの連携が比較的簡単
- 統合ターミナルというものが標準で使用できる
- いろいろなカラースキームを使える
- 綺麗
- 拡張機能が豊富で, 導入が簡単

# インストール
1. VSCodeのダウンロードサイト([リンク](https://code.visualstudio.com/))からインストーラーをダウンロードする.
2. インストーラーを起動する.

~また追記しようと思います~

# 統合ターミナル
おすすめはWSLを統合ターミナルとして用いることです.
事前にインストールして使用可能な状態であると良いと思います.
[WSLのインストール](https://qiita.com/ryoi084/items/104a86775c966e897630)
ショートカットキーである**Ctrl+@**を押すと統合ターミナルが開きます.
初めに統合ターミナルを開いたときに, どのコンソールを使用するかを問われます.
ここでWSLを選択しておくことで, Bashをターミナルとして使用できるようになります.

![vscode.png](https://qiita-image-store.s3.amazonaws.com/0/269455/30f07daf-b749-b21c-15a5-29b26aeeebe5.png)

## WSLのパスについて
確定的な情報ではないのですが, ワークスペースに登録しておいているフォルダで作業をしている場合は, 統合ターミナルとしてWSLを開いたときに自動的にパスがそのフォルダまで通ります.
この機能がだいぶ便利なので, 助かっております.

# 拡張機能
VSCodeは様々な拡張機能を簡単に導入できます.
左にある拡張機能のボタンを押し, 検索フォームに欲しい機能を入力することでインストールできます.
![vscode.png](https://qiita-image-store.s3.amazonaws.com/0/269455/627fffe1-6b65-ba10-6786-0b8b74988dba.png)
## 私が入れている拡張機能
### Vim
エディタの部分がVimと同様の操作になります.
```.vimrc```での設定は反映されませんが, 近い設定をすることは可能です.
さらに(干渉していなければ)VSCodeの標準のショートカットもそのまま使用できます.

### Python
Pythonコードのハイライトを行ってくれる上に, 保存時に構文チェックもしてくれます.

### Latex Workshop
VSCode上でTexを編集するために使えます.
Latexmkを用いたコンパイル環境が用意されていれば, 容易に実装可能です.
SourceTree使うのを辞めてよかったと思うこと

## はじめに
皆さんはGitを何で操作していますか？
SourceTreeの方もいれば、Git-cliの方もいるかと思います。(他のツール知らないです...
私は、長くSourceTreeを利用していましたが、1年ほど前よりGit-cliを利用するようになりました。
双方使ったうえで、個人的にGit-cliに変えて良かったな〜と思った事をまとめたいと思います。



## 良かった事
### 慣れると早い
単純に慣れるとGit-cliの方が操作が早いと感じました。
考えるより前に手が動く感覚です。

### Git自体に集中できる
git自体をあまり知らないうちに、SourceTreeを使うとSourceTree自体の仕様も覚えないといけません。
逆に、gitの事を知っていてもSourceTreeを覚えないといけないので、二度手間に感じます。
また、SourceTreeはバージョンが上がるごとにUIが割とドラスティックに変わるので、追いついていくのが大変と感じた事がありました。 Git-cliはコマンド仕様がドラスティックに変わることはありません。

### ググった時に情報の絶対量が多い
SourceTreeを利用した時は、やりたい事を検索した際にSourceTreeでの操作が載っているページを血眼になって探していましたが、Git-cliにしてから、そのストレスはなくなりました。

### 手順の展開の容易さ
個人ではなく、チーム開発における場面でとても感じた事です。　プロジェクト用のwikiなどに、手順をまとめる際にキャプチャ等は不要で、コマンドを貼り付けるだけで済みます。
チャットにも、このgitコマンドでこういうgit操作してください -> コマンドペター　で済むため、コミュニケーションコストが少なく済みます。

### Git操作を覚えられる
SourceTreeは非常に良く作られていて、UIにのっとって操作していけば、様々なgit操作が行えます。　　そのため、SourceTreeの操作を感覚で覚えてしまい、今自分でgitに対して何をしようとしているのか？を脳死で操作しがちなのと、裏で何のgitコマンドが動いているかを意識しづらい点があります。

### エラーが起きた場合のリカバリーが容易
Git-cliの場合、クリックだけでは操作できないので、もちろん自分で今からしたいgit操作を考え、コマンドに起こし、実行します。そのため、途中でエラーになった場合でも、どこでつまづいたのかを特定するのが容易です。
SourceTreeの場合、良くも悪くも、`よしな`にワンクリックで様々な操作をしてくれるので、途中でこけた時のリカバリーが不透明な事が多々ありました。　また、そのリカバリー自体のUI操作も覚えておかないといけません。


## 最後に
SourceTreeにも良いところ(Git-cliを知らなくても直感的に操作ができる。diffが見やすい。...etc)　はあると思いますし、使いたいものを使えば良いと思うので、否定をしているわけではありません。
ですが、今現在SourceTreeを利用している/これからgitを使おうとしている方が、この記事を読んでGit-cli良さそうだな！と感じてくれて、興味を持ってくれる方がいれば嬉しいです！

また、Git-cliを利用するなら以下のツールを利用すると捗ると思います。是非導入してみてください！快適ですよ！
[「Git補完をしらない」「git statusを1日100回は使う」そんなあなたに朗報【git-completionとgit-prompt】
](https://qiita.com/varmil/items/9b0aeafa85975474e9b6)
GraphQLの旅(3) Node-REDから一瞬でGraphQLをたたく

## 解：便利なプラグインを使う

GraphQLはREST、gRPCに加えて登場したデータ取得・登録向けAPI形式ですが、GraphQL形式のAPIをGraphiQLなどの専用クライアント以外で簡単に触れる方法を紹介します。
[graphqlプラグイン](https://www.npmjs.com/package/node-red-contrib-graphql)をNode-REDにインストールします。

Node-REDのメニューの「パレットを管理」→「ノードを追加」→"graphql"を検索し上記プラグインを追加します。

図の左側にあるように、「機能」パレットにgraphqlというノードが追加されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/88e1ca4b-45b5-0359-8b67-3e26fddd90df.png)

## 使用したフロー例

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/4dfe6921-ad24-c9ef-a95b-fea7938a675c.png)

Endpointには、Graphqlサーバを設定します。
今回は[graphql-yogaを使った簡単なサーバ](https://qiita.com/Hiroyuki_OSAKI/items/cabc086cac06787be18e)が稼働しているhttp://localhost:4010を利用しています。

Queryには、GraphiQLなどで設計したクエリを記載します。
図では単純にuserのnameとidを取り出しリストアップするクエリを実施しています。

結果は下記の通りです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/3e984ac7-d1e7-7d44-3440-ab9651cf00c8.png)

このノードはとてもシンプルで素敵です。
DCGANでガッキー生成を試みた

最近GANの勉強をはじめました。
GANの勉強には以下が参考になりました。

[今さら聞けないGANシリーズ](https://qiita.com/triwave33/items/1890ccc71fab6cbca87e)
この方が書かれているGANのシリーズは本当にわかりやすく、分かっていない人を分からせる書き方をしてくれており、理解の助けになりました。

[DeepLearningモデルDCGANでアイドルの顔画像を生成してみた](https://qiita.com/NakaokaRei/items/0551dbfc0ac14176b876)
こちらもとても参考になりました、というか今回の実験の手法やソースコードはこちらの方のものをほぼそのまま拝借させていただきました。
こちらはデータのクローリング方法も記載してくれており、大変参考になりました。

## 実装
上記の「[DeepLearningモデルDCGANでアイドルの顔画像を生成してみた](https://qiita.com/NakaokaRei/items/0551dbfc0ac14176b876)」をほぼそのまま拝借しましたので、ここでは割愛させていただきますが、opencvの顔認識特徴量ファイルhaarcascade_frontalface_alt.xmlの場所が私の環境では
/Users/*****/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/cv2/data/haarcascade_frontalface_alt.xml
にありました。

## データセット
集めたガッキー画像は以下の45枚です。
<img width="965" alt="スクリーンショット 2018-07-09 23.41.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/240999/a98ded04-044f-1c2e-51cc-1538fa6edc5f.png">

##　結果
#### 1epoch
ガッキー誕生
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/670464c4-101c-10df-9739-ee751d35b805.png" width=50%>
#### 100epoch
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/18df5c76-47c0-ed17-76eb-3e136be7bc4d.png" width=50%>
#### 500epoch
カラフルは砂嵐
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/c1a28065-c4e0-633a-6e3e-f1055e97a99b.png" width=50%>
#### 1000epoch
輪郭っぽいものが見えてきた
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/bf88dd60-0612-7804-edd2-9d923e1a130b.png" width=50%>
#### 1200epoch
前髪が目にかかってる感じ？
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/2dcaffac-bcd7-9931-2907-778b90a103a9.png" width=50%>
#### 1350epoch
犬的なものに変化しはじめた？
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/8b775764-da33-b6cb-5ead-b14c6d9cddff.png" width=50%>
#### 1400epoch
禿げた...
<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/1f96ecf3-0f30-6b3f-daf4-8e90e6233985.png" width=50%>

これ以上は変わり果ててゆくガッキーは見たくなかったので、ここで処理を強制終了しました。



## まとめ

- いくらなんでもデータセット45枚は少なすぎると思いました。もっと真面目にデータを集めます。　（過学習？）
- 処理に時間がかかりすぎました。（上記までを生成するのに１０時間以上かかりました。）
処理速度をあげる方法を検討したい
- 禿げはじめてしまった原因は少ないデータ数の中に前髪をあげている画像がちらほらあるから？

まずはデータ収集のし直しから。
うまくいったらまた投稿します。

## 追記（2018/07/16）
以下の方のロジックを参考（丸パクリ）させていただいたら、同じデータセットでも出力に大幅な改善が見られました。
[GANについて概念から実装まで　～DCGANによるキルミーベイベー生成～](https://qiita.com/taku-buntu/items/0093a68bfae0b0ff879d)

<img src="https://qiita-image-store.s3.amazonaws.com/0/240999/85305498-6ca1-aae5-5526-c45c120f68d3.png">
一番左上とかガッキーっぽい気がする
3000epochまで回しましたが、2000epochくらいからほとんど精度が変わらなかったので、現状の少ないデータではこれくらいが限界なのかなと思いました。

ここまで出力に違いが出た理由は調査中...
MongoDBでAsync/Await


Node.jsでMongoDBの公式ドライバーでAsync/Awaitを使う例です。

※ 2019/3/23: エラー処理を追加してコードを見直しました。

```js
const transaction = async () => {
  let client;
  try {
    client = await mongodb.MongoClient.connect("mongodb://127.0.0.1:27017", {
      useNewUrlParser: true
    });

    const db = client.db("DATABSE_NAME");

    const res = await db
      .collection("COLLECTION_NAME")
      .save({ key: "value" });

    const docs = await db
      .collection("COLLECTION_NAME")
      .find({})
      .toArray();
    return docs;
  } catch (error) {
    console.log(error);
  } finally {
    client.close();
  }
};

transaction();
```

## まとめ

- エラー処理をfinally句で行えるので楽
- 同期APIと非同期APIが混在しているので注意
CC2531でZigBeeキャプチャを行う方法

# 概要
- ZigBee(IEEE802.15.4)通信をCC2531チップ搭載のUSBドングルでパケットキャプチャする方法をまとめました
- ハードウェアは、[CC2531 USBドングルZigbeeワイヤレスモジュールプロトコルアナライザ](https://www.amazon.co.jp/Q-BAIHE-ANN-CC2531-USB-DONGLE-JP-USB%E3%83%89%E3%83%B3%E3%82%B0%E3%83%ABZigbee%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%82%A2%E3%83%8A%E3%83%A9%E3%82%A4%E3%82%B6CC2530-Q2531UD/dp/B06ZYMB6JK/ref=pd_lpo_sbs_147_img_1?_encoding=UTF8&psc=1&refRID=GQKNZ4XQQ060AQZTZJJX)を使用しました
- ソフトウェアは、Ubuntu-16.04, python2.7, https://github.com/mitshell/CC2531 を使用しました。
- パケットキャプチャの対象はXStick(コーディネータ)からXBee S2Cへの通信となります。
 
# インストール
```shell=bash
$ sudo apt-get install libusb-dev
$ sudo pip install libusb1 PySerial
$ wget https://github.com/mitshell/libmich/archive/master.zip
$ unzip master.zip
$ cd libmich-master
$ sudo python setup.py install
$ wegt https://github.com/mitshell/CC2531/archive/master.zip
$ unzip master.zip
$ cd CC2531-master
$ sudo python setup.py install
```

# パケットキャプチャ実行
```shell=bash
$ cd /usr/local/lib/python2.7/dist-packages/CC2531
$ python sniffer.py
[GPS_reader][ERR]?cannot open /dev/ttyUSB0
[CC2531][25238] driving CC2531 USB Dongle @ USB bus 3 & address 5, with serial 25238
[receiver][3:5:25238] start listening on channel(s): [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
[+] frame received (FCS OK): 2018-07-01 22:48:55
channel: 22, 2460 MHz
RSSI: -24
IEEE 802.15.4 frame: 41882e47ffffff61610810ffff00001d1e67b7a34000a2130008e8110005c1e8c935
IEEE 802.15.4 MAC:
[[[ IEEE 802.15.4 ]]]
### [MAC] ###
 <[Res] : 0b0>
 <[IntraPAN] : '1 : True'>
 <[AckReq] : '0 : False'>
 <[FramePending] : '0 : False'>
 <[Security] : '0 : False'>
 <[Type] : '1 : Data'>
 <[SrcAddrMode] : '2 : 16-bit address'>
 <[FrameVers] : 0b00>
 <[DstAddrMode] : '2 : 16-bit address'>
 <[Res] : 0b00>
 <[SeqNum] : 46>
 <[DstPANID] : 0xff47>
 <[DstAddr] : 0xffff>
 <[SrcPANID] : 0x>
 <[SrcAddr] : 0x6161>
        ### [Data] ###
         <[RawData] : 0x0810ffff00001d1e67b7a34000a2130008e8110005c1e8c935>

```

# 次やること
- xbeeプロトコル解析
Zsh on Ubuntu on Windows 

WSLのシェルをbashからzshに乗り換えてみたので、その手順と感想
###1.zshをインストール
まずはzshをインストール

```shell

sudo apt install zsh
```

###2.oh-my-zshをインストール
公式通りにインストール https://github.com/robbyrussell/oh-my-zsh

```shell

curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
```
###3.zsh-completionsをインストール
こちらはgithubから公式通りにインストールする https://github.com/zsh-users/zsh-completions

```shell

git clone https://github.com/zsh-users/zsh-completions ~/.oh-my-zsh/custom/plugins/zsh-completions
```

zsh-completionsをzshが読み込むよう、.zshrcに以下を記述

~~~shell:.zshrc
plugins=(… zsh-completions)
autoload -U compinit && compinit
~~~
###4.ログインシェルをzshに変更
`which zsh`でzshのパスを取得し、それをコピー（多分`/usr/bin/zsh`と出るからそれをコピー）
次にchshと入力。すると、

```shell

Password:
Changing the login shell for <username>
Enter the new value, or press ENTER for the default
        Login Shell [/bin/bash]:
```
と出てくるので、先ほどコピーしたパスを入力。もう一度WSLを立ち上げると、シェルがzshになってる

###まとめ
bashからzshに移行した途端WSLの使い勝手がすごく増したので、WSLを使っている方は迷うことなくはやくzshに乗り換えたほうがいい！

###参照
[Ubuntuのシェルをzshに変更する](https://qiita.com/sayama0402/items/ac9e078b024c3287f99f)
[初心者向け：Zshの導入]
(https://qiita.com/iwaseasahi/items/a2b00b65ebd06785b443)
VS Code1.25の新機能 - アウトラインビュー

# Visual Studio Code 1.25の新機能・アウトラインビュー
https://code.visualstudio.com/updates/v1_25#_outline-view

IDEでよくあるアウトライン表示機能が追加された。ファイルエクスプローラーのビューの１つとしてデフォルトで表示され、アクティブなエディタのアウトラインが表示される。

![outline.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/1ea3fe3a-5db1-76b6-eb65-a5ea4a6b806f.gif)

ソート順は位置、名前、種類が指定できる。

![outline_sort.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/cfcb8341-72f3-e124-d20b-4fbe7d2428a0.jpeg)

アウトラインの要素をクリックするとその項にジャンプする、逆にエディタのカーソル位置をアウトラインに追従させることもできる。

![outline_chase.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/89561ab4-5d07-0f06-e6c5-6772fd916723.gif)

キーワードを入力して該当要素をハイライトしたりフィルタングしたりできる。

![outline_filter.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/204e093f-522b-f8ab-72b4-79ca937f621a.gif)

設定でアイコンの表示/非表示、エラーや警告の表示方法を変更できる。

![outline_option.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/0f02002a-f9af-5cc1-6d90-9818929b4a6f.gif)
IE11でcookieのパラメータを確認する方法

IE11の開発者ツールで設定したcookieのパラメータを確認することが出来なかった。
ハマった末に、開発者ツール以外の方法で解決したため、メモする。

# 事象
javascriptでcookieのパラメータ(expires等)を設定する処理を書いたが、
IE11の開発者ツールから確認した結果、パラメータが設定されていないように見える。  
下記質問と同じような状態

- [Cookie - IE11に保存されているcookieの有効期限を確認する方法(94119)｜teratail](https://teratail.com/questions/94119)

```console.log(document.cookie);``` してみたけど、パラメータまでは表示されない。

# 確認方法
結論。 下記方法で、IE11からcookieをエクスポートすることで、パラメータを確認することができた。

- [主要ブラウザでCookieを編集する方法 – Webトピッ](https://webtopi.net/archives/23)

エクスポートしたcookie.txtの読み方は以下を参考にした。

- [Cookie.txtの内容 - mfumiの日記](http://d.hatena.ne.jp/mFumi/20100223/1266904044)


# 原因考察
- IE11の開発者ツールはcookieの送信時にはcookieのパラメータが表示されないっぽい
    - cookieの受信時はcookieのパラメータが表示されていた
- javascriptで書いたcookieの設定処理は、ページへのアクセス毎にcookieの有効期限を更新して送信していたために、開発者ツールに表示されなかったのかも

---
問題は解決できましたでしょうか?
より詳しくご存知の方がいたら、教えてください(´・ω・`;)