OmniAICreator/Qiita-1.07M huggingface dataset:
Ethereum Geth1.7(Megara)へのアップデート方法

【本文】
---

Ethereumの公式ブログでも[公表](https://blog.ethereum.org/2017/09/14/geth-1-7-megara/)されたように、Etereum Clientの一つGeth(go-ethererum)の最新バージョン'Megara'（v1.7)が使用可能になりました。
そこで、早速導入してみたのですが、その際の導入手順を簡単にまとめました。
（※導入方法は色々あるので、あくまで一例としてご参考ください。）

端的に言うと、Geth(v1.7)はGo1.7以上を前提としている為、

１）Goをv1.7以上にする
２）Gethをv1.7にする

と言う流れとなります。

【前提知識：Metropolisとの関係】
---

Geth1.7はEthererumの大型アップデートMetropolisに対応したバージョンとなります。Metropolisについては以下ブログが参考になります。

+ [「メトロポリスとは？」（by Ethereum Japan）](https://ethereum-japan.net/wiki/metropolis/)

Metoropolis自体が大掛かりなもので、ByzantiumとConstantinopleの2回に分けてハードフォークされることが計画されています。

【導入手順】
---

**1. Go1.7以上を導入**

Goは1.7以上であれば何でもよいみたい。なので以下リンク内ブログで紹介された手順をそのまま流用。

+ [「UbuntuへGo1.7をインストールする」（by OngaLog）](http://onga-tec.hatenadiary.jp/entry/2017/01/30/Ubuntu%E3%81%B8Go1.7%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)

注）既にGo1.6以下が導入済みを前提。
　　未導入の場合、先ず、Goを入れる。

>```:Go未導入の場合
$ sudo apt install golang-go
（注：Go未導入の場合のみ実施。今だと、v1.6.xが入るはず。）
>```

>```:Go1.7を導入（※例では、v1.7.4)
$ sudo apt-get update
$ sudo apt-get -y upgrade
$ wget https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz
$ sudo tar -xvf go1.7.4.linux-amd64.tar.gz
$ sudo mv go /usr/local
$ mkdir ~/gocode
$ echo export GOROOT=/usr/local/go  >> ~/.bash_profile
$ echo export GOPATH=$HOME/gocode  >> ~/.bash_profile
$ echo export PATH=$GOPATH/bin:$GOROOT/bin:$PATH  >> ~/.bash_profile
$ source ~/.bash_profile
$ go version
>```

以下、結果が返れば導入成功。
>```:version確認結果(Go1.7)
go version go1.7.4 linux/amd64
>```

**2. Geth1.7を導入**

GO1.7以上入っていれば、以下手順を踏むことで自ずとGeth1.7が導入されるはず。

>```:Geth1.7を導入
$ git clone https://github.com/ethereum/go-ethereum
(※もし、gitが未導入の場合、エラーメッセージが出力されるので、先ず「sudo apt install git」でgitを導入する。）
$ cd go-ethereum
$ make geth
>```

>```:version確認(Geth1.7)
$ ./build/bin/geth version
>```

以下、結果が返れば導入成功

>```:version確認結果(Geth1.7)
Geth
Version: 1.7.1-unstable
Git Commit: a92d8a26547c138953665387c57168e68bacdd13
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.7.4
Operating System: linux
GOPATH=/home/tomohata5/gocode
GOROOT=/usr/local/go
>```

なお、Geth1.7についてもパスを通しておけば、どの階層からでも、「geth」を必要に応じてオプション付きで打ち込めば起動可能になる為、出来ればパスを通しておきたいところ。

>```:PATHに設定(Geth1.7)
$ echo export PATH=$HOME/go-ethereum/build/bin:$PATH  >> ~/.bash_profile
$ source ~/.bash_profile
>```


**備考：端末再起動後にパスが上手く通らなくなっている場合**

環境によって違うと思われるが、「~/.bash_profile」に設定した場合、端末再起動後にパスが通っていない場合がある。詳しくは、以下のブログ記事が参考になる。

+ [「ユーザーの環境変数を設定するbashの設定ファイルと、カスタムプロンプトについて」（by OXY NOTES）](http://oxynotes.com/?p=5418)

その場合の対処法として、以下手順を実施する。
（※多分、これで端末再起動後もパスが通っているはず。）

>```:追加手順（Go+Geth)
$ cd $HOME
$ echo export GOROOT=/usr/local/go  >> ~/.profile
$ echo export GOPATH=$HOME/gocode  >> ~/.profile
$ echo export PATH=$HOME/go-ethereum/build/bin:$GOPATH/bin:$GOROOT/bin:$PATH  >> ~/.profile
$ source ~/.profile
>```

【終わりに】
---

今回は特に言うことはありませんが、既に説明した通り、Geth1.7はEthereumの大型アップデートMetropolisに対応したバージョンになります。
その意味では結構重要なバージョンとなる為、まだ正式版ではありませんが、今のうちにある程度使い込んでおくのも良いかもしれません。
TextViewにテキストを追加するとスクロールしてしまうのを回避する

メモとして残しておく


下記のメソッドを通せば解消できる


```swift

func insertTextView(_ insertingString: String, textView:UITextView) {
        var range: NSRange = textView.selectedRange
        let firstHalfString: String? = (textView.text as NSString?)?.substring(to: range.location)
        let secondHalfString: String? = (textView.text as NSString?)?.substring(from: range.location)
        textView.isScrollEnabled = false
        textView.text = firstHalfString! + insertingString + secondHalfString!
        range.location += insertingString.characters.count
        textView.selectedRange = range
        textView.isScrollEnabled = true
    }

```

誰かの力になれば
TypeAnnotationAwareMetaDataProvider : Constraints on the parameters of constructors of non-static inner classes are not supported if those parameters have a generic type due to JDK bug JDK-5087240.

> TypeAnnotationAwareMetaDataProvider : Constraints on the parameters of constructors of non-static inner classes are not supported if those parameters have a generic type due to JDK bug JDK-5087240.

と言われた。。。（`java version "1.8.0_25"` とか古いので起こる・・・？）

# 原因
`enum` の field に `@Valid` つけてた。generic type とは関係無いが、enum の実装によるもの・・・？
『難しそうなプログラミングをやさしく教えてくれる本』のPythonのプログラム

[『難しそうなプログラミングをやさしく教えてくれる本』](http://amzn.to/2jGteY0)のPythonのプログラムを写経します．
ちなみに，amazon で評価は低いのですが，その理由はタイトルの「やさしく教えてくれ」ていないからのようです．
逆に言えば，Qiita を見るような人には，データ構造，ポインタ，クラス，オブジェクト指向などについて丁寧に書かれている本書はなかなか良書のように思います．
もちろんステマではありません．


p.128 リスト1

```py3:ball.py
a=4/3
p=3.14
r=15/2
r3=r**3

print(a*p*r3)
```

p.129 リスト3

```py3:ball.py
a=4/3
p=3.14
r=15/2
r3=r**3

print(a*p*r3)

def show(name, val):
    return name + '=' + str(val)

print( show("a", a) )
print( show("p", p) )
print( show("r", r) )
print( show("r3", r3) )
```

p.129 図14

```pycon
>>> varNames = ['a', 'p', 'r', 'r3']
>>> for i in range(len(varNames)):
        print(varNames[i])
```

```pycon
>>> for d in varNames:
    print(d)
```
p.129 図15

```pycon
>>> varNames = ['a', 'p', 'r']
>>> varNames.remove('a')
>>> varNames
```

```pycon
>>> varNames.insert(0, 'a')
>>> varNames
```

```pycon
>>> varNames.append('r3')
>>> varNames
```

p.130 図B

```py3
import ui
import console

def button_tapped(sender):
    console.alert("Hello", "ボタンが押された", "OK")

button = ui.Button(title="ボタン")
button.action = button_tapped
button.present("sheet")
```

p.185 リスト1 ユークリッドの互除法を利用して最大公約数(Greatest Common Divisor, gcd)を計算する

```py3

def gcd(a, b):
    return a if b == 0 else gcd(b, a % b)
print(gcd(342, 162))
```
Write Code Every Day! 〜2年目Javaエンジニア、毎日コード書きます〜

##"Write Code Every Day"　始めました！

久しぶりのQiita更新。どんどん記事もアップしていきたい。

さて、Javaエンジニアになって早1年。最近やっと１人で作業することも苦にならなくなっていますが。その中でいて、"基礎的なこと"がまだまだ疎かにしていることを先輩に指摘され・・・もう一度基礎を見直す為にも、「毎日コード書くぞー！」ということで、コツコツやっていきたいと思います。

今のところ、一応毎日続いてるw
<b>GitHub</b>: kuro-channel → https://github.com/kuro-channel

コードを書くのに参考にしているサイトと書籍は以下。
<b>i) CodingBat</b> http://codingbat.com/java
↑Javaの練習問題が多く載っている & 解いてて楽しいw

<b>ii) Java本格入門</b>　http://gihyo.jp/book/2017/978-4-7741-8909-3
↑とても評判が良かった & JJUGの方が書いているということで買った本著。とてもわかりやすい & サンプルも多いので実行しながら進められる。

という2つを軸に、毎日30分以上は机でパソコンに向かってコードを書くというのを日課にしてます。（まだ2週間目ですがw）業務でもコードは書きますが、やはりプライベートで書くコードはなんだか新鮮で楽しい。まだまだ基礎が身についてないと痛感していますので、継続的にコードを書いていきます。
前々処理：サクサク使うSQL　sqlitebrowser インストール,sqlite

# CSVをSQL で扱うためのアプリケーション sqliteborwser をインストールする
- 2020/12/15更新

## 課題
- sqlite3 インストール　（簡単）
- kaggle からcsvデータダウンロード　（初めては少し手間）

## sqlite3インストール　
- [ここ](https://sqlite.org/download.html)からダウンロードしてインストール　簡単になりました。
- この画面が開けばオーケーです。
- ![sqlite.png](https://qiita-image-store.s3.amazonaws.com/0/48387/2e512158-0079-9c24-015b-9858f83baefc.png)

## kaggle から　データ取得
|No|リンク|内容|
|---|---|---|
|1|[Country](https://toukeibiz-my.sharepoint.com/personal/tadashi_toukei_biz/_layouts/15/download.aspx?docid=00401e76b6012445da92ac08187a2ea23&authkey=ATkDOOB7DCYS0r-034vnyoY)|日本語国名コード|
|2|[Country_eng](https://toukeibiz-my.sharepoint.com/personal/tadashi_toukei_biz/_layouts/15/download.aspx?docid=0bdae8803777147299087df835ba8a85a&authkey=AfjCbssuhP3PVMNtNF0wRV0)|英語国名コード|
|3|[custom](https://toukeibiz-my.sharepoint.com/personal/tadashi_toukei_biz/_layouts/15/download.aspx?docid=0475b5bcacd014135a5aa40d25a18b1b7&authkey=AeJZrzKNElXrStEYxoc6rE8)|税関コード|
|4|[ym_custom_latest.db](https://toukeibiz-my.sharepoint.com/personal/tadashi_toukei_biz/_layouts/15/download.aspx?docid=0c129360349d04d2695bcb551f1f53929&authkey=Abe8DWyyrW_4AvDoVaUWG10)|税関別データ　最新(2017 1-7 )|
|5|[ym_latest](https://toukeibiz-my.sharepoint.com/personal/tadashi_toukei_biz/_layouts/15/download.aspx?docid=057411d6c9a524057a3557fd4aa934779&authkey=Afq8tdfWTj2nCIYia7dvr5k)|全国データ　　最新(2017 1-7 )|

[次 CSV 読み込み ](https://qiita.com/zanjibar/items/9a0504d7a7cdc2117f80)
iOS 10.3.3 Webブラウザのユーザーエージェント (Safari, Google Chrome, LINE など)

## 概要

iOS 10.3.3 上で動作するWebブラウザやアプリ内ブラウザのユーザーエージェント (User-Agent, UA) 文字列を調べてみた。

## ユーザーエージェント文字列

### iPhone 6s + iOS 10.3.3 + Safari


Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1


### iPad mini 4 + iOS 10.3.3 + Safari


Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1


### iPad Air 2 + iOS 10.3.3 + Safari


Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1


### iPhone 6s + iOS 10.3.3 + Google Chrome 61.0.3163.73


Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) CriOS/61.0.3163.73 Mobile/14G60 Safari/602.1


### iPad mini 4 + iOS 10.3.3 + Google Chrome 61.0.3163.73


Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) CriOS/61.0.3163.73 Mobile/14G60 Safari/602.1


### iPad Air 2 + iOS 10.3.3 + Google Chrome 61.0.3163.73


Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) CriOS/61.0.3163.73 Mobile/14G60 Safari/602.1


### iPhone 6s + iOS 10.3.3 + Facebook 141.0


Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 [FBAN/FBIOS;FBAV/141.0.0.51.91;FBBV/71695290;FBDV/iPhone9,1;FBMD/iPhone;FBSN/iOS;FBSV/10.3.3;FBSS/2;FBCR/&#12477-&#12501-&#12488-&#12496-&#12531-&#12463-;FBID/phone;FBLC/ja_JP;FBOP/5;FBRV/0]


(「FBCR/&#12477-&#12501-&#12488-&#12496-&#12531-&#12463-」の部分は携帯電話キャリア「ソフトバンク」を示していると思われる)

### iPhone 6s + iOS 10.3.3 + LINE 7.12.0


Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 Safari Line/7.12.0


### iPhone 6s + iOS 10.3.3 + Yahoo! JAPAN 4.8.0


Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 YJApp-IOS jp.co.yahoo.ipn.appli/4.8.0

## 関連資料

- [iOS 14 / iPadOS 14 Webブラウザのユーザーエージェント \(Safari, Google Chrome, LINE, Twitter など\) \- Qiita](https://qiita.com/niwasawa/items/21b12f5fd0541837d887)
- [iOS 13 / iPadOS 13 Webブラウザのユーザーエージェント \(Safari, Google Chrome, LINE, Twitter など\) \- Qiita](https://qiita.com/niwasawa/items/df30ffddf2e709b2ca43)
- [iOS 12 Webブラウザのユーザーエージェント \(Safari, Google Chrome, Twitter など\) \- Qiita](https://qiita.com/niwasawa/items/a2b947b24121b30d5eb6)
- [iOS 11 Webブラウザのユーザーエージェント \(Safari, Google Chrome, LINE など\) \- Qiita](https://qiita.com/niwasawa/items/44aaae7a1f942b62b9c1)
Firebase Hostingを使ってアプリのお知らせページを実装

# やりたいこと
Androidアプリ内にお知らせページを作りたい。
お知らせページは更新頻度が高めなので、アプリの更新をしなくてもお知らせ情報だけ更新できるようにしたい。
サーバーは用意できない。

そこで思いついたのが下記の2つ。
1. Google Apps Scriptを用いてHTMLを生成・配信。
2. Firebase Hostingを用いてHTMLを配信。

# Google Apps Script（GAS）を用いてHTMLを生成・配信。
実際に試してみましたが、生成したHTMLをアプリのWebViewで表示するとなにやら上部に謎の表記が。。。
![Screenshot_1505659875 3.png](https://qiita-image-store.s3.amazonaws.com/0/136368/af95bb6c-6a19-d4a6-bd91-959987de1afa.png)

拡大してみるとこんな表記が。
`This application was created by another user, not by Google.`
`Report abuse - Terms of Service`
消し方が分からず、これを出しっぱのままアプリをリリースするわけにもいかないのでFirebase Hostingの方を選択してみました。

# Firebase Hostingを用いてHTMLを配信。
ここではFirebase Hostingの導入から、ホスティングした静的コンテンツ（HTML）を表示できるようにするところまでを紹介します。
前提として、Firebaseにてプロジェクトを作成済みであるとします。

## Node.jsとnpmのインストール
まずはNode.jsとnpmのインストールを行います。
https://nodejs.org/ja/
インストーラの手順に沿ってインストールを行ってください。

## Firebase CLI（コマンドライン インターフェース）のインストール
npmを用いてFirebase CLI（コマンドライン　インターフェース）のインストールを行います。
コマンドラインツールから下記コマンドを実行してください。
`npm install -g firebase-tools`

実行時に`Error:EACCES`というエラーが発生するかもしれません。
その場合は下記の記事を参考にしてください。
http://qiita.com/Gaddict/items/8c76d92bd0adec2bfb6a

## Firebaseへのログイン
ここからはFirebase CLIのコマンドを使って操作をしていきます。
まずはFirebaseへのアクセスを可能にするために下記コマンドでFirebaseのプロジェクトと紐付いたアカウントにログインします。
`Firebase login`

## Firebaseアプリの初期化
ログイン後、Firebaseアプリの初期化を行います。
ここでいうFirebaseアプリとは、Firebase Hostingで配信する静的コンテンツのことを指します。（たぶん。。。）
下記コマンドをアプリのルートディレクトリにて実行してください。
`firebase init`

私の場合はAndroidアプリをBitbucketで管理しているので、静的コンテンツも同じように管理したいと思いアプリのプロジェクト直下にディレクトリを移動してから上記コマンドを実行しました。

上記コマンドを実行すると、まずはじめにFirebaseのどの機能を利用するかを聞かれるので`Hosting`を選択します。
さらに、紐付けるFirebaseプロジェクトを聞かれるので、自分が設定したいプロジェクトを選択してください。
続いて、公開ディレクトリの指定を促されます。今後はこのディレクトリ内に静的コンテンツを配置していくことになります。そのままEnterを押すと`public`というフォルダが作成されその中に`index.html`が作成されます。
最後に、アクセスを全てindex.html経由にするかどうかを聞かれます。複数のHTMLを配置してそれぞれに直接アクセスできるようにしたい場合は`NO`、全てのアクセスをindex.html経由にしたい場合は`YES`を入力してEnterを押してください。ちなみにここで`NO`を選択すると、index.htmlが生成されたフォルダ内に404.htmlが生成されます。

これにて初期化は完了です。

## 静的コンテンツをデプロイする。
先ほど指定した公開ディレクトリの中身の静的コンテンツに外部からアクセスできるようにするには、このフォルダ内のコンテンツをデプロイする必要があります。
下記コマンドを実行することでデプロイできます。
`firebase deploy`

成功するとプロジェクト固有のドメインが表示されるので、そのドメインにアクセスするとindex.htmlの内容が表示されることが確認できると思います。

# 終わりに
Firebase Hostingを用いることでサーバレスでHTMLを配信することができました。
無料のアカウントだと保存容量が1GB、ユーザーアクセスによるダウンロードが10GB/月なので、個人開発のアプリやサイトであれば十分な容量ではないかと思います。
皆さんも是非、使ってみてください。
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第四章 ドメインを隔離する1

# ドメインを隔離する
> 思考を最適に働かせるには、モデル要素を見た時に１つの体系として理解できる必要がある。より多くのオブジェクトが入り混じった中から、モデル要素を拾い上げるように強制されることはあってはならない。・・・ドメインオブジェクトはシステムの他の機能から切り離す必要がある。(第二部 第四章より)

「より多くのオブジェクト」とか「システムの他の機能」とは、ソフトウェアシステムに関するオブジェクト。データベースアクセスやビューに関するオブジェクト。

複雑なのは、技術的なコードよりもユーザーの活動やビジネス、つまり、ドメインモデル。(「[まえがき3 複雑なのはドメインそのもの](https://qiita.com/YasuhiroKimesawa/items/e6912fb677e4d4766300)」参照)なので、ドメインと技術的な要素を切り離すことが大事になってきます。

> ドメイン関連のコードがそうした膨大な他のコードの中に拡散してしまうと、**コードを見て意味を理解する**のがきわめて困難になる

ドメインを他のコードと切り離し、プログラマはもちろん、ドメインエキスパートもソースから理解できるようにするのもドメイン駆動設計の目指すところです。(「[第一章 知識をかみ砕く5 ドメインエキスパートもコードが読める](https://qiita.com/YasuhiroKimesawa/items/dbf20e40c31df727c785)」参照)

# レイヤ化アーキテクチャ
> よく用いられるものではあるが、ドメインモデリングの原則を適用する上では決定的に重要(第二部 第四章より)

レイヤ化アーキテクチャ自体はDDDで新た定義されたものではないですね。
[PoEAA本](www.amazon.co.jp/dp/B01B5MX2O2)には既にレイヤ化として紹介されてますし、「三層レイヤ」・「多層アーキテクチャ」という形で以前から使用されてきたもの。
ですが、これがドメインと技術的なコードを切り離すのに役に立つということですね。

レイヤ化アーキテクチャの詳細はまた明日読みます。
herokuにアップしたRailsアプリでsytle、jsの更新が反映されないときにやること


commitする前に、以下のコマンドでキャッシュを削除する。

```
$ bundle exec rake assets:precompile assets:clean
```

その後普通にpushで反映される

```
$ git add .
$ git commmit
$ git push heroku master
```
Railsのコマンドショートカット

`$ rails generate`を`$ rails g`、`$ rails server`を`$ rails s`と略す。
他に何があるのかを調べてみた。

| コマンド | 省略形 | 使用例 |
|:-----------:|:------------:|:------------|
|server|s|`$ rails s`|
|console|c|`$ rails c`|
|generate|g|`$ rails g controller hoge`|
|destroy|d|`$ rails d controller hoge`|
|test|t|`$ rails test`|
|dbconsole|db|`$ rails db`|
|runner|r|`$ rails r`|
|gem install|gem i|`$ gem i hoge`|
|bundle install|bundle|`$ bundle` or `$ bundle inst`|
WebGLでGPGPUできる計算機を作ってみた話

#GPGPUとは
General-Purpose Computing on graphics Processing Unitsの略です
本来描画処理に利用するためのGPUを描画以外の計算にも利用してやろうって事ですね

#transformFeedback
今年(2017年現在)webGL2.0が有効化され，それによってtransformFeedbackという関数が使用できるようになりました
こいつは頂点シェーダでの計算結果をバッファにバインドできる関数です
つまりこいつを使うとGPGPUができます！

#transformFeedbackの使い方
まず頂点シェーダで計算した結果を出力するための変数をout修飾子を付けて定義しておきます

```glsl:
#version 300 es 
out float result;
void main(void){
result=2.0*3.0;
}
```
次にjavascript側でプログラムを作成する際に，gl.transformFeedbackVaryingsという関数を入れておきます
第一引数はリンクするプログラム，第二引数は頂点シェーダで計算した結果を保持している変数名，第三引数はとりあえず下記とします

```javascript:
var program = gl.createProgram();

gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.transformFeedbackVaryings(program, ["result"], gl.SEPARATE_ATTRIBS);
gl.linkProgram(program);
gl.useProgram(program);
```

いよいよ頂点シェーダでの結果をバッファにバインドします

```javascript:
var vTransformFeedback = gl.createBuffer();
var transformFeedback = gl.createTransformFeedback();

gl.bindBuffer(gl.ARRAY_BUFFER, vTransformFeedback);
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.BYTES_PER_ELEMENT, gl.DYNAMIC_COPY);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, vTransformFeedback);
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, 1);
gl.endTransformFeedback();
```
流れとしては頂点バッファを一度作成したバッファにバインドした後，その結果をgl.TRANSFORM_FEEDBACK_BUFFERにバインドしてやる，と言った感じです

上記のコードでgl.TRANSFORM_FEEDBACK_BUFFERに頂点シェーダでの計算結果をバインドすることができました

しかしこのままだとjavascript上でどのように結果を表示できるのかわかりません
バッファの計算結果を配列として取得できる関数としてgl.getBufferSubDataというものがあります

```javascript:
var arrBuffer = new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT);
arrBuffer = new Float32Array(arrBuffer);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, arrBuffer);
console.log(arrBuffer);
```

これでコンソールに頂点シェーダでの計算結果が出力されるはずです
この場合であれば2.0*3.0=6.0が格納されている配列として出力されると思います

#計算機作ってみた
ということでtransformFeedbackを利用してGPGPUができる計算機を作ってみました
https://ukeyshima.github.io/gpgpuCalculator/

webGL2.0をサポートしているブラウザでしか動きません

普通にjavascriptでする計算と切り替えることができます
わかりにくいですがGPUって表示されてるときはjavascriptで計算されてますね，CPUって表示されてるときにGPGPUしてます

手順としては2.0*3.6+5.3などの数式を文字列として定義し，イコールのボタンが押された際にその計算をする頂点シェーダと何も出力しないフラグメントシェーダでwebGLのプログラムを作成し，transformFeedbackを利用して計算結果をcanvasに出力する，といった流れです

ちなみに超絶どうでもいいですが計算結果を出力する部分はcanvas2Dで普通に書いていますが，それ以外は全部GLSLで記述してます(1とか2とか÷とかです)

どうでもいいです

#パフォーマンス
当たり前っちゃあ当たり前ですがGPUでこんな普通の計算してもなんの良いこともないです
イコールボタン押すたびにプログラム作成するわけですから普通に計算するより全然遅いです

しかし！つよいGPUを積んでいてめっちゃ長い計算だと普通にjavascriptで計算するよりも速い速度で計算ができます！
実際にGTX1080を積んでいるPCで動作を確認してみたところ，1.0を10万回ぐらい掛けた計算だと普通にjavascriptで計算するより速いよって結果が出ました
1000万回ぐらい掛けるともう二倍の速度ですね〜〜

#まとめ
webGLを利用してGPGPUできる計算機を作ったお話ですが，transformFeedbackの使い方が載っているサイトなどがほとんどなく，使えるようになるまですごい苦労しました
なのでついでに使い方とかも書いておきました
まだ使えるようになった程度なのでもっと効率化できる，とかこここうしないほうが良いだろ，とかこれ違くね？等の御意見ありましたらどんどんお願いします
今回のプログラムは[ABPro2017](https://abpro.jp/2017/)という発表会で発表してきたものです
MySQLクエリチューニング〜とりあえずEXPLAINする〜


スロークエリログを集計しやすくするツール
pt-query-digest

# 業務上での使用例
1日のスローログの件数を集計し、件数のみ通知する
→チューニングしやすいクエリの発見に役立つ

# とりあえずEXPLAINする
## クエリ
```sql
SELECT COUNT(some_column) FROM table WHERE some_column = '111'
```
## explain結果からインデックスが何が使われてるか
possible_keys (使えそうなインデックス) : `some_index`, `another_index`
keys (使っているインデックス)          : `another_index`

結局どっちのインデックスの方が良いかわからない....
↓
インデックスを効かせてみよう！！

## インデックスを効かせる
SELECT COUNT(column) FROM USE INDEX(some_index) table WHERE column = '111'


## 実際にクエリが読み込んだ行数を知る

```sql
# ステータスクリア
FLUSH STATUS

# 調べたいSQL文
SELECT COUNT(column) FROM USE INDEX(some_index) table WHERE column = '111'

# 読み込み行数を表示
SHOW SESSION STATUS LIKE 'Handler\_%'
```

`Handler_road_next` に読み取り行数が記述される
#### ちなみに
FLUSH STATUSの権限がなかったら以下のようなコマンドで追加してあげてね！
`GRANT RELOAD ON *.* TO '<user>'@'<host_name>';`

RELOAD権限についてはこちら
> https://dev.mysql.com/doc/refman/5.6/ja/privileges-provided.html

### Explainで見た行数と乖離している場合
統計情報を元にオプティマイザーが検査すべき行数を判断しているため、
統計情報の「サンプリング値」が実際にデータ分布と著しく乖離している場合間違っている可能性が高い。

```sql
# 再度サンプリングする
ANALYZE TABLE
```

それでも変わらない場合は以下の二種類が考えられる(InnoDBの場合)
* 前回の統計情報の更新から累計して、テーブル全体の10%以上が更新された場合、バックグラウンドで統計情報を再作成してくれるため、既に更新してくれていた場合
* インデックス一つに対して、のサンプリングする行数は指定されている(InnoDBではデフォルトでは16kB)ため、インデックスのサイズが大きくなると精度が悪くなる。
 - *インデックスの容量が増えると同時に、サンプリング数も増やすべき* `innodb_status_persistent_sample_page` オプションで指定する



## そのExtraは本当に望ましいものなのか?

> https://dev.mysql.com/doc/refman/5.6/ja/explain-output.html#explain-extra-information

### Extraでよく見にする3つ
#### Using filesort : 行のフェッチを評価の後に追加でクイックソートが発生していることを示す
Where句で絞れるだけ絞らなければ出力結果の数に応じて計算量が増えていく。
なお、クイックソートのオーダーはO(n log n)

#### Using index
インデックス上に書かれた情報だけで情報の取り出しを終了したと言う意味。

通常MySQLのインデックスはB+Treeであるため、通常は以下の順番で探すが、最初の処理だけで情報をとり出せる
1. インデックス上から条件にマッチするリーフを探す
1. リーフ上に書かれた情報から行の位置を探す
1. 行をフェッチする

#### Using temporary
 ソートのために、暗黙のテンポラリーテーブルを使用していることを示す
 (暗黙のテンポラリーテーブル: CREATE TEMPORARY TABLEステートメントで作成するテンポラリーテーブルのこと)

##### 使用する場合
* 集計関数を使用した結果でのソートは
* 昇順、降順が混じったソート

##### 使用しない場合
* 単にインデックスがないカラムや、関数や演算子を使用したソートではクイックソート。

##### デメリット
* 一定のサイズ( `max_heap_table_size`, `tmp_table_sizez` の小さい方)を超えるとMyISAM(5.7ではデフォルトでInnoDB)でストレージ上に固定されるため、性能が劣化する

### EXPLAINの注意点
#### 5.6の変更点
* DELETE, INSERT, REPLACE, UPDATEステートメントがEXPLAINできるようになった
* `EXPLAIN format=json` がサポートされるようになったため、出力がJson形式で帰ってくるように無っった。
#### 5.7の変更点
* EXTENDEDキーワードとPARTITIONSキーワードがデフォルトで指定された状態になった。
* `EXPLAIN FOR CONNECTION n` 構文がサポートされた。`n` に `show processlist` で出力される `id` を指定すると、実行中のステートメントをEXPLAINできる

## まとめ
* 実際に最適なインデックスを調べるためには、使えるインデックスを試して見ることが一番
* `Using filesort` , `Using temporary` は WHERE句で絞り込んだ後の結果セットが大きくなるほど、遅くなる
Visual Studio 2015のC++でHello World

#はじめに
Visual Studio 2015のC++でHello Worldする手順を丁寧に説明します。
画面を追えばできるはずです。
ただし、インストールとアクティベーションの工程の説明は省きます。

#VisualStudioを起動します。
スタートメニューから起動してください

#プロジェクトの新規作成
ファイル→新規作成→プロジェクト　をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/7f2b3a2d-32a4-0c81-7218-288d61bafe86.png)

#Win32コンソールアプリケーション
左のテンプレートより、「Visual C++」内の「Win32」をクリックし、
中央で「Win32 コンソールアプリケーション」をクリックして選択。

画面下部の「名前」にプロジェクトの名前を
「場所」にプロジェクトを作りたい場所を選択してください。(右側の「参照(B)...」を使用してください)
終わったらOKをクリックしてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/3be5e606-a216-31fc-7f34-cfc152a0ffd2.png)

#Win32アプリケーションウィザード
次へをクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/36414f48-ab0e-62e3-3d62-a03ff144b4f9.png)

「追加のオプション」の「空のプロジェクト」にチェックを入れ、
「Security Development Lifecycle(SDL)チェック」のチェックを外して、
「完了」をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/180dc064-45cb-596f-3989-93a8308687c3.png)

#ソースファイルの追加
ソリューションエクスプローラ(右側あるいは左側)の「ソースファイル」を右クリックし、
「追加(D)」→「新しい項目(W)...」をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/9bb020ef-ba53-b752-d90c-b342210ca259.png)

「C++ファイル(.cpp)」が選択されているのを確認したら、「名前」に適当な名前を入力するか、あるいはそのまま、
「追加」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/decd0d9c-31b7-49b4-9ecf-228b6c6d09f3.png)

#Hello World
あとは自動で開くので(開かない場合は、ソリューションエクスプローラ内の先ほど作成したファイルをダブルクリック)

Hello Worldしましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/a95bc928-bcaf-7495-3e43-af3da469f5bd.png)

```cpp:Source.cpp
#include <stdio.h>
int main()
{
	printf("Hello World\n");
	return 0;
}
```

#ビルド
終わったら、Ctrl + F5
あるいは、画面上方の「デバッグ」→「デバッグ無しで実行」をクリックすると
ビルドの後、実行されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/e2c6794b-53dd-b0c0-f809-61d65eeb2523.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191114/ac50e747-c592-bc7e-30b9-983f36952212.png)
python2 keysメソッド 「built-in method keys of dict object at 0x109475e88」と表示された時の対処法

#きっかけ
辞書型のキーを取得するため「keys」メソッドを使おうとした際
```
list=dict.keys
print list
```
「built-in method keys of dict object at 0x109475e88」
と出力されてしまい「？」となってしまいました．
#原因
「keys」メソッドに()つけてないというくだらない原因でした・・・
```
list=dict.keys()
print list
```
['Yamada', ‘Ueda’]
と無事出力されてしまいました．
#まとめ
メソッドには（）つけましょう！
配列を回しながら削除したい場合

ときおり、「配列に何かの処理をかけてから、1つ1つ削除していく」ような処理が必要となるかもしれません。ただ、うまくやらないと**ハマります**。

# 背景事情

Railsのフロントエンドの一部に、エレメントとしてRiotをはめ込んだようなアプリを作っていて、そしてTurbolinksでのページ遷移もかけていました。そうなると、ページ遷移の前にRiotをきちんと外しておく必要がありますので、以下のようなコードを書いていました。

幸い、マウント中のRiotタグの一覧は`riot.util.vdom`に配列として入っています。ということで、

```js
$(document).on('turbolinks:before-cache turbolinks:before-render', function(){
  riot.util.vdom.forEach(function(item){
    item.unmount(true);
  });
});
```

のようにしていたのですが…調べてみると、一部のタグが残ってしまっていたのでした。

# 原因究明

Riot自体のソースコードまで当たって調べてみると、タグを`.unmount`したのと同時に`riot.util.vdom`からも`.splice()`で削るようになっていました。そのため、

* 0番目のタグを`.unmount`
* `.splice()`で、もともと1番目に入っていたものが0番目に移る
* `forEach`が1番目に進んでしまう
* もと奇数番目だったものは、飛ばされて残ってしまう

という、単純な理屈でした。なお、JavaScriptの`.forEach`も、中身は[このように](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility)添字を回すのが基本です。

# 対策法
対策としては、いくつか考えられます。

## 後ろから回す
後ろから回していけば、順々に削除していっても番号がずれることはないので、そのような問題は生じません。Rubyの配列には`reverse_each`メソッドがありますが、JavaScriptでは添字を`for`で回していく他なさそうです。

## 配列をコピーする
操作対象となる配列とは別に、参照用に配列をコピーしておいて、そちらから操作する、という方法もあります。ただし、コピーのコストはかかります。

## 破壊的操作と要素の取り出しを一気に済ませる
配列から`.pop()`や`.unshift()`で要素を取り出しつつ削っていくようにできれば、「ループの位置」という概念も関係なくなりますし、全部終われば配列は自然と空になっています。
開いているエクセルファイルの格納フォルダを開く(エクスプローラーで)

# 開いているエクセルファイルが保存されているフォルダを開く

普段、履歴やショートカットからファイルを開くことが多くて
フォルダを辿ってファイルを開くことが少ない。

なのであるファイルをがどこにあるか思い出すのに、
「こないだのあのファイルが入ってるのと同じフォルダにあると思う」
みたいな思い出し方をすることも多く。

その時にエクセルファイル開いた状態から、そのファイルが入ってるフォルダ(パス)を開きたい。
っていう欲求がニョキニョキ出てきて調べて作ったサブプロシージャ
どことどこをパクったかは記憶がないけど。。

これを自分を実行すると、アクティブになってるファイルの格納パスがエクスプローラーで開かれる。こが、地味だけどわりと便利。


```vbnet:opne_activebook_path

Sub open_activebook_path

    Dim f_wsh As Object
    Dim f_exec As Object
    Dim f_cmd As String
    Dim f_myPath As String

    Set f_wsh = CreateObject("WScript.Shell") 
    f_myPath = ActiveWorkBook.Path
    
    f_cmd = "start " & f_myPath
    Set f_exec = f_wsh.Exec("%ComSpec% /c " & f_cmd)
	
    Set f_exec = Nothing
    Set f_wsh = Nothing

End Sub

```
ミニマップで比較する良いコードと悪いコード

良いコード(リファクタというか書き直したコード)と悪いコード(元のコード)をミニマップで比較してみました。

# 環境

- ソースはPython2.7
- PyCharmのCodeGlanceというプラグインでミニマップを表示
- カラーテーマ：Darcula
- ミニマップは横幅110桁、1行の高さは1ピクセルと3ピクセルで表示

# ミニマップ

AとB、どちらが良いコードでどちらが悪いコードでしょうか？

## 1行1ピクセルで表示

![minimap_1.png](https://qiita-image-store.s3.amazonaws.com/0/35192/4a054d30-993c-1951-e308-987787c45a30.png)

## 1行3ピクセルで表示 

A
![minimap_3_old.png](https://qiita-image-store.s3.amazonaws.com/0/35192/d3de5c50-aab5-cf5f-4531-e57984322cd7.png)

B
![minimap_3_new.png](https://qiita-image-store.s3.amazonaws.com/0/35192/fed51cb4-1169-2f51-6f5a-8f2181cbbb4f.png)

# 比較

## 全体の文字量

Aは全体的に文字がぎゅうぎゅうに詰め込まれている印象です。
空行が少なくて1行の文字数も多いからです。

Bは空行を適度に含んでいるためすっきりとした印象です。

## コードの左側

Aは左側に空白が多くて凸凹が目立ちます。
forやifのネストが深く、且つその中でダラダラと処理を書いている箇所が多いからです。

Bはネストが浅く左側が全体的にフラットです。

## コードの右側

Aは右側にも文字が多く、右端いっぱいまで文字がある行も目立ちます。
これは引数が多い関数の呼び出しなどが改行なしで1行で書かれている箇所が多いからです。

Bでは長い行には適切に改行を入れているので、右側に空白が目立ちます。

## 文字列リテラルの量

<font color="#008080">■■■</font>の色は文字列リテラルを表しますが、Aではこれが非常に多いです。
これはデータの格納にdictを使いまくっているからです。

Bではデータの格納にクラスを使用しているので文字列リテラルは少なくなっています。

# わかったこと

- 良いコードはミニマップで見ても美しい
- 悪いコードはミニマップで見ても汚さが滲み出ている
チェックボックスだらけのtableでチェックしやすくしたい

## やりたいこと
下記のような表を想定する。

||Col|Col|Col|Col|
|-----|-----|-----|-----|-----|
|Row|[x]|[x]|[x]|[x]|
|Row|[x]|[x]|[x]|[x]|
|Row|[x]|[x]|[x]|[x]|
|Row|[x]|[x]|[x]|[x]|

入力補助として下記を作りたい：

* チェックボックスを直接押さなくても同一セルなら押したことにする
* 上記表の「Row」を押すと、その行全部にチェックが入る。もう一度押すとその行全部からチェックが外れる
* 上記表の「Col」を押すと、その列全部にチェックが入る。もう一度押すとその列全部からチェックが外れる

## 制限
* nodejsが関連するいろいろは使わない。
* ライブラリ(jQueryとか)もできるだけ避ける。
* IE8で動くこと。

## 結果
https://jsfiddle.net/oafLnLz0/

何となくそれらしく動く。
コールバック祭りになってしまっている気がするけどどうしたらいいのかよく分からない。

## 書いたもの
### forEach風関数
``` javascript
// Array.prototype.forEach風
function forEachArrayLike(arrayLikeObj, func) {
	var len = arrayLikeObj.length;
	var i = 0;
	for (i = 0; i < len; i++) {
		func(arrayLikeObj[i], i, arrayLikeObj);
	}
}
```

### チェックボックスを直接押さなくても同一セルなら押したことにする
``` javascript
function setCellClickEvent() {
	var tds = document.querySelectorAll('td');
	forEachArrayLike(tds, function (tdElem) {
		var checkbox = tdElem.querySelector('input[type=checkbox]');
		if (checkbox === null) {
			return;
		}
		tdElem.addEventListener('click', function (event) {
			// チェックボックスを押したときにこれが発火すると
			// チェックがついてから即外れてしまうので
			if (event.target !== checkbox) {
				checkbox.checked = !checkbox.checked;
			}
		});
	});
}
```

### 上記表の「Row」を押すと、その行全部にチェックが入る。もう一度押すとその行全部からチェックが外れる
``` javascript
function setRowClickEvent() {
	var trs = document.querySelectorAll('tr');
	forEachArrayLike(trs, function (trElem) {
		var firstTd = trElem.querySelector('td');
		if (firstTd === null) {
			return;
		}
		var checkboxes = trElem.querySelectorAll('td>input[type=checkbox]');
		var isCheck = false;
		firstTd.addEventListener('click', function () {
			isCheck = !isCheck;
			forEachArrayLike(checkboxes, function (checkboxElem) {
				checkboxElem.checked = isCheck;
			});
		});
	});
}

```
このisCheckをキャプチャするのはどうなんだろうかと思いつつほかの書き方を思いつけなかった。

### 上記表の「Col」を押すと、その列全部にチェックが入る。もう一度押すとその列全部からチェックが外れる
``` javascript
function setColumnClickEvent() {
	var trs = document.querySelectorAll('tr');
	var ths = trs[0].querySelectorAll('th');
	forEachArrayLike(ths, function (thElem, thIndex) {
		var reactionCheckboxes = [];
		forEachArrayLike(trs, function (trElem) {
			var tds = trElem.querySelectorAll('td');
			forEachArrayLike(tds, function (tdElem, tdIndex) {
				if (tdIndex !== thIndex) {
					return;
				}
				var checkbox = tdElem.querySelector('input[type=checkbox]');
				if (checkbox === null) {
					return;
				}
				reactionCheckboxes.push(checkbox);
			});
		});
		if (reactionCheckboxes.length === 0) {
			return;
		}
		var isCheck = false;
		thElem.addEventListener('click', function () {
			isCheck = !isCheck;
			forEachArrayLike(reactionCheckboxes, function (e) {
				e.checked = isCheck;
			});
		});
	});
}

```
長いしネストが深いしHTMLが一番上の行`th`で書いていて残りを`td`で書いていることに依存しているし、
何か微妙な感じがする。ここもisCheck変数が出てきてなんかうーーん。
RPAツールUiPathで老技術者が日常を自動化していった話(2)　コマンドプロンプトからコマンド実行

#**概要**

こんばんは、老技術者です。
**UiPath**は無料でさっと使える唯一のRPAツール。
こいつを使って今宵もちょいといたずらしてみました。

前の記事へ>>[Webから取得した株価をcsv出力してメールで送りつける](https://qiita.com/tamtak18/items/48c628176fd6cfcdc82e)


##実行環境

    Windows10 Pro
    Office 2016 ProPlus

##目次

    1.　Webから取得した株価をcsv出力してメールで送りつける
    2.　コマンドプロンプトでいろいろやってみた
    2.　Excelシート間コピペ，csv出力
    3.　Outlookでメールの受信と送信

#**2. コマンドプロンプトからコマンド実行**
コマンドプロンプト…思い返せばこいつがまだ「DOS窓」って呼ばれてた頃は、ずいぶんお世話になったものです。
最近Pythonで遊ぶようになってまたちょこちょここいつを開くようになりました。
そしてRPAが降臨して、おバカなRPAの画像認識がOKボタンを探せないでいる様子を見かねて、老技術者は考えた。そうだこいつにコマンドプロンプトのたたき方を教えてやろう！
コマンドプロンプトにRPAがばんばんコマンドを打ちこめるのであれば、実にいろいろなことができます。例えば、schtasks.exeを使うことで、定時に再起動する、なんてことが簡単に実現します。

###**(1) コマンドプロンプトを開く**
Open Applicationをダブルクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/a59e56b1-4db4-9f3a-623f-258a165a2b52.png)
コマンドプロンプトを起動しておき、Indicate window on screenをクリックしてから、コマンドプロンプト上をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/7f546480-b28f-5c3a-17d0-0e3d308de65e.png)
　　　　　　　　　　　　　↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/75988fc3-8a6d-f9f0-8ea1-9d45e6910854.png)
ここで1回RUNしてちゃんとコマンドプロンプトが起ち上がるかチェックします。

###**(2) Open ApplicationのPropertiesをちょっと細工**
（これをやらないで実行すると「cmdが見つからねえ！」と言ってエラーになります。）

PropertiesのSelectorを編集
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/8b582793-6636-84ff-9ed5-40067c109855.png)

title以降・/の手前までを削除してOKを押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/d69097b6-36f1-4467-6c8b-a66f675b3988.png)
　　　　　　　　　　　　　↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/ae608adb-1d66-bd61-a43a-c24524b922cf.png)

###**(3) Type intoをDoにドラッグ**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/44d075f8-6004-768b-1dba-09f8f937fcc2.png)

###**(4) 実行するコマンドを書く**

書式は
"コマンド[k(enter)]"
です。
引用符と[k(enter)]を忘れずに！
コマンド実行できることは何でもできるというのは実はすごいこと。
UiPathからWinActorのシナリオ実行なんて変態なこともできてしまうはず。
いろいろやってみてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202911/32ff1fcf-bca6-3fd6-bbc1-307491fd4a25.png)
バックアップツールbupを使ってみた

Linuxでのファイルバックアップツールには、tar, rsync, unison等色々ありますが、ここでは`bup`というツールを試してみました。
日本語の情報があまりに少ないので、色々試してみた結果をメモ程度に残しておきます。

# `bup`とは

`bup`とは、`git`と互換性のあるデータ構造を用いてファイルのバックアップを行うツールであり、操作体系も`git`と似通っています。`git`との相違点として以下のような点があります。

- デフォルトでリポジトリがホームディレクトリ(`~/.bup/`)に置かれる。(バックアップ先がリモートサーバーの場合はリモート上の`~/.bup/`)
- 基本的にリポジトリがシステムごとに1個しか存在しないので、バックアップに名前を付けることができる。(この名前は`git`でいう`branch`に相当)

# `bup`を用いたバックアップ

## 通常のバックアップ手順

1. `bup init` ... システムに`bup`リポジトリを作成(1回のみ)
2. `bup index dir1/filename` ... ファイルを`INDEX`に登録
3. `bup save -n dir1 dir1` ... ファイルをバックアップ(コミットを作成)

## `bup init`

`bup init`を実行すると、ホームディレクトリに`~/.bup`ディレクトリが作成されます。このディレクトリはgitでいう`.git`ディレクトリと同じ構造であり互換性があります。

## `bup index dir1/file1`

以下のようなフォルダ階層を仮定します。

```
├── dir1
│   ├── dir3
│   │   └── file5
│   ├── file1
│   └── file2
├── dir2
│   ├── file3
│   └── file4
└── mnt
```

`bup index`では、バックアップを行いたいファイルを指定します。例えば`bup index dir1/file1`とすれば上記の`file1`がバックアップ対象として`INDEX`されます。また、`bup index dir1/dir3`のようにすれば`dir3`中のすべてのファイル、すなわち`file5`がバックアップ対象となります。バックアップ対象は同時に複数指定することもできます。

## `bup save -n dir1 dir1`

`bup save`では、`INDEX`されたファイルをバックアップします。この際、`~/.bup`に`-n`で指定した名前のブランチが作成され、変更内容のコミットが作成されます。このときのコミットメッセージは以下のようなものになります。

```
    bup save
    
    Generated by command:
    ['/usr/lib/bup/cmd/bup-save', '-n', 'dir1', 'dir1/']
```

なお、バックアップされるディレクトリは`INDEX`されたものの中で指定されたディレクトリ`dir1`以下のもののみとなります。すなわち、`dir2`以下のファイルを`INDEX`した状態で`bup save -n dir1 dir1`をしたとしても当該ファイルのバックアップは行われず、`INDEX`されたままになります。

## リモートへのバックアップ

`bup save`の際、リモートを指定することでリモートサーバーにバックアップを行うことが出来ます。

```bash
$ bup save -r host:path -n dir1 dir1
```
ここで`host`ではsshで接続する際のホスト名を指定します。`path`を省略するとデフォルトのパス(`~/.bup`)が使用されます。
ヘッドレスブラウザの Puppeteer を利用して WEB ページを PDF 出力してみる。

# 概要
ヘッドレスブラウザの Puppeteer を利用して、 WEB ページを PDF に出力してみました。

# 内容
## Puppeteer とは？
PhantomJS や NightmareJS と同じ GUIを提供していないブラウザです。
Chrome ベースで作成されており、提供元が GoogleChrome と同じなので、 PhantomJS の様に、開発・サポート終了などのリスクは少ないと思います。

[Puppeteer GitHub](https://github.com/GoogleChrome/puppeteer)

## 導入

- yarn の場合

```control
$ sudo yarn add puppeteer
```

- npm の場合

```control
$ sudo npm i puppeteer
```

## サンプルコード
ここでは、Google の TOP ページを PDF 出力するサンプルを用意します。

```js:outputPdf.js
const fs = require('fs');
const assert = require('assert');
const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // PDF出力対象ページ
  await page.goto('https://www.google.co.jp/');

  // PDF作成処理
  await page.pdf({
    path: 'google_top.pdf',
  });

  browser.close();
  console.log('PDF出力完了');
})();
```

## 実行

```control
$ node test.js
```

たったこれだけで、PDF が出来てしまいます。

## PDF出力機能チートシート
これだけだと味気なさすぎるので PDF 出力機能の チートシートも用意しました。

|パラメータ名|型|デフォルト値|説明|
|---|---|---|---|
|path|String|なし|PDF ファイルの出力パスで、指定しないと PDF 出力されない。|
|scale|Number|1|1=100%を基準に、印刷ページを拡大・縮小できる。|
|displayHeaderFooter|Boolean|false|ヘッダーとフッターを表示有無を設定できる。|
|printBackground|Boolean|false|背景画像の表示有無を設定できる。|
|landscape|Boolean|false|印刷用紙の向きを変更できる。|
|pageRanges|String|なし|印刷するページ範囲を指定できる。（指定例： '1-5,8,11-13'）|
|format|String|'Letter'|用紙フォーマットを指定できる。**width、heightオプションのほうが優先。**|
|width|String|なし|用紙の幅を指定できる。(指定例： '10cm')|
|height|String|なし|用紙の高さを指定できる。(指定例： '10mm')|
|margin|Object|none|用紙の余白。top、right、left、bottomでそれぞれの余白を指定できる。｜

### width、height、margin で利用可能な単位
- px（デフォルト）
- in
- cm
- mm

### format 指定種類
- Letter
- Legal
- Tabloid
- Ledger
- A0〜5

## 終わりに
公式のリファレンスがスゴくわかりやすく、ほとんどコードを書かずに PDF 出力が実現が出来てしまいました。
他のヘッドレスブラウザができる機能はほとんど網羅していそうなのと、今後スタンダードになっていきそうな気配があるので
また何かの実験結果を記事にしてみたいと思います。

[Puppeteerのリファレンス](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md)
Node.js上でWebSocketの400エラー

Node.js上でWebSocketを用いてサーバと接続する際に以下の不正リクエストエラーが帰ってくる場合の原因の一例についてのメモです。

```
HTTP/1.1 400 Bad Request
```
# RFC 6455 - The WebSocket Protocol
RFC 6455によるとWebSocketはリクエストのパラメータとして以下のようになっています。

```
リクエストに必要なパラメータ
- GET /ws HTTP/1.1\r\n
- Host: 192.168.12.145:22300\r\n
- Upgrade: websocket\r\n
- Connection: Upgrade\r\n
- Sec-WebSocket-Version: 13\r\n
- Sec-WebSocket-Key: ZQ0ZM3WA2Yqpb6Ne7d10iA==\r\n
オプション
- Origin: chrome---extension://pfdhoblngboilpfeibdedpjgfnlcodoo\r\n
- Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits\r\n
```
# 原因
WiresharkでNode.jsのクライアント側から送ったパケットを見てみると

```
- GET /ws HTTP/1.1\r\n
- Host: 192.168.12.145:22300\r\n
- Upgrade: websocket\r\n
- Connection: Upgrade\r\n
- Sec-WebSocket-Version: 13\r\n
- Sec-WebSocket-Key: ZQ0ZM3WA2Yqpb6Ne7d10iA==\r\n
```

であり、必要なパラメータは網羅しています。

ここでオプションを見てみるとOriginはブラウザクライアントの場合は必要であるとなっています（ RFC 6455: 4.2.1. Reading the Client's Opening Handshake ）。
今回はサーバ側がOrigin必須であるブラウザクライアントを想定して立てられたものである可能性が考えられます。
# 解決策
Originに適当な要素を与えることによって不正リクエストではなくなります。

Node.jsのwebsocketパッケージを使用して記述すると以下のようになります。
```
var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
var origin = "適当なクライアント名”;
ws.connect('ws://192.168.12.145:22300/ws',null,[origin]);
```
matzの写真を５秒間表示するサンプル【Selenium入門】

## Seleniumとは
Selenium（セレニウム）はブラウザのオートメーションツール
自動でブラウザを操作することでWebサイトの動作テストを行うことができる

##### **TL;DR**
matzの顔写真を５秒間表示するサンプル

![aaa.gif](https://qiita-image-store.s3.amazonaws.com/0/40799/ef4e8e19-e1af-389a-2b65-f801d32823c5.gif)

## 環境

```shell-session:terminal
Mac OS Sieera 10.12.6

$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin14]
```

## Install

```shell-session:terminal
$ brew install chromedriver
$ gem install selenium-webdriver 
```

## matzの顔写真を５秒間表示するサンプル

```ruby:test.rb
require "selenium-webdriver"

# Chrome用のドライバを指定
driver = Selenium::WebDriver.for :chrome

# Googleにアクセス
driver.get "http://google.com"

# name属性にqが設定されている要素を取得
element = driver.find_element(:name, 'q')

# 検索したい文字列を入力
element.send_keys("ruby wiki")

# name属性にbtnGが設定されている要素を取得
element = driver.find_element(:name, 'btnK')

# 取得した要素をクリック
element.click

# aタグのテキストを指定して要素を取得、クリック
driver.find_element(:link_text => "Ruby - Wikipedia - ウィキペディア").click

# wikiの検索窓に値を指定して検索
driver.find_element(:id, 'searchInput').send_keys("まつもとゆきひろ")
driver.find_element(:id, 'searchButton').click

# mazの画像をクリック
driver.find_element(:class, 'image').click

# sleep
sleep 5

# 終了
driver.quit
```

## 所感
ページのテストやダミーデータの登録処理の自動化にかなり使えそう！
実行状況が可視化されるのは良いですね

チートシート作ったので是非！
http://qiita.com/wMETAw/items/8ea0ff9c7a63ca6134b9

## リンク

seleniumメソッド一覧[（公式サイト）](http://www.rubydoc.info/gems/selenium-webdriver/0.0.28/Selenium/WebDriver)
[Webブラウザの自動操作 (Selenium with Rubyの実例集)](https://www.qoosky.io/techs/71dd2d67ea)
[Selenium の基本的な使い方のサンプル集](http://takuya-1st.hatenablog.jp/entry/2016/04/01/043149)
http://qiita.com/edo_m18/items/ba7d8a95818e9c0552d9
http://qiita.com/adebadayo/items/22134c00123663bc70b4
ansibleでパスワードによるSSH接続

概要
====
手っ取り早くansibleを使いたいとき、ターゲットのrootのログインパスワードを入力させて接続する方法です。セキュリティ的にあまりよろしくないので、外部に繋がっていない閉じた試験環境とか、そういったところでの利用を想定しています。

手順
====
`/etc/ansible/ansible.cfg`に、以下を設定する。

```ini:ansible.cfg
[default]
ask_pass = True
host_key_checking = False
remote_user = root
```

以上。
TH-wbRadStudio で php7.1をexe化 (python3.6も可)

## Download

* [Standalone Technique for [ PHP / Python ]: 平田寿浩](http://hirata-create.cocolog-nifty.com/)
    * [TH-wbRadStudio](http://hirata-create.cocolog-nifty.com/blog/TH-wbRadStudio.html)

## 1. VCRUNTIME140.dll のインストール

* [Visual Studio 2015 の Visual C++ 再頒布可能パッケージ](https://www.microsoft.com/ja-jp/download/details.aspx?id=48145)

![1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/d9488903-4a4e-ed7d-0c53-38b8a17b6cb8.png)

![スクリーンショット_2017-09-20_08-29-18.png](https://qiita-image-store.s3.amazonaws.com/0/25728/c4d1252a-ad3b-39c5-a628-4d435c4d90bd.png)

## 2. LIBEAY32.dll のインストール

* [Shining Light Productions - Win32 OpenSSL](http://slproweb.com/products/Win32OpenSSL.html) から`1.0.2L Light`をインストール。(1.1.0だと含まれていなかった。)
* libeay32.dll を TH-wbRadStudio のフォルダ直下にコピー

![スクリーンショット_2017-09-20_08-20-17.png](https://qiita-image-store.s3.amazonaws.com/0/25728/1fb875f3-61f5-e49c-6363-7c175af1859f.png)

![ssl.png](https://qiita-image-store.s3.amazonaws.com/0/25728/dbd27a24-2e86-9817-9e4e-27b927a6a543.png)

![スクリーンショット_2017-09-20_08-33-14.png](https://qiita-image-store.s3.amazonaws.com/0/25728/3aaaf4fb-6cfb-7c46-7ca1-1c860651d11e.png)

ビルドしたexeに php7ts.dll も一緒に置く。
ビルドしたexeが実行できることを確認。


## その他ためになりそうなサイト

* [PHP7をEXEにコンパイルする方法（PHP7＋WinBinder＋VBS） - tukihatuの技術日記](http://d.hatena.ne.jp/tukihatu/20151229/1451373607#phpexeuse)
* [WinBinder でデスクトップアプリケーション
 : PHPプロ！TIPS+](http://www.phppro.jp/phptips/archives/vol11/3)
    * http://winbinder.org/download.php
* [PHPをEXEにコンパイル – 伊藤清徳の垂直落下式ムーンサルトプレス](http://agilmente.com/blog/2012/11/27/phptoexe/)

```sh:抜粋
たとえば、テキストファイルを相対パスで指定したりする場合には、
インタプリタから見たパスの場所がずれるため、
通常どおりのパスが指定できない点を注意する。

この解決方法はRES://というURLスキーマを利用する。

$file = '../data/data.txt';
$usage_path  =  'res:///PHP/' . strtoupper(md5($file));
```

## 他の実装

* 参考: [将 php 转换/编译为 EXE - 正风三才的博客 - CSDN博客](http://blog.csdn.net/tty521/article/details/68955553)

### bamcompile

* [GitHub xZero707/Bamcompile](https://github.com/xZero707/Bamcompile)
* [PHPプロ！TIPS+](http://www.phppro.jp/phptips/archives/vol14/)

```
bamcompile hello.php hello.exe 
bamcompile project main.php result.exe

bamcompile -e:c:\php\extensions\php_mbstring.dll project main.php result.exe
bamcompile -e:php_mbstring.dll -e:php_gd2.dll ・・・
```

* [GitHub  peachpiecompiler/peachpie](https://github.com/peachpiecompiler/peachpie) (Phalangerの後継)
* [PHPc](https://sourceforge.net/projects/phpc/)
組込みC > 症状: 構造体の隣の値まで取得する

```txt:動作環境
とある16bit組込み開発環境
sprintf関数は低メモリ消費版ライブラリ使用
```

### 問題のコード

問題のあった状況を抽出すると以下のようなコードになる。

https://ideone.com/eUO7RY

```c
#include <stdio.h>
#include <stdbool.h>

typedef struct {
	float pi;
	bool yesno;
} MY_DATA;

int main(void) {
	MY_DATA adata;

	adata.pi = 0.0;
	adata.yesno = false;

	printf("1:%d\n", adata.yesno);
	printf("2:%Ld\n", adata.yesno);

	adata.pi = 3.141592;
	adata.yesno = false;

	printf("3:%d\n", adata.yesno);
	printf("4:%Ld\n", adata.yesno);
	
	return 0;
}
```

上記において、4番の値が0でない。
（例: 655360)

### 問題発生条件

以下の条件が全て成立する時だけ発生する。

1. 某開発環境のprintf関数使用時
    - gccなどにあるような一般的なprintf関数ではない
2. printf書式指定子の指定間違い
    - "%d"とするところを"%Ld"としていた
3. 構造体内の隣の変数piの値が0以外の時

### 起きたことの推測

構造体変数のメモリ配置は以下に例がある。
https://stackoverflow.com/questions/20737176/how-are-struct-members-allocated-in-memory

上記の構造体ではpiの後にyesnoが続いている。

```
| pi | yesno |
```

yesnoの値を問題のprintf()で"%Ld"として出力しようとした時に、piの領域も含めて読んだ値が出力され、655360のような値が出てきたように思われる。

"%d"に修正したところ、0が出るようになった。

### 予防措置

1. printf()の書式指定子間違いがないことを確認する
2. デバッグ時にyesno以外のメンバ変数にダミー値を入れて、yesno値に影響がないことを確認する
    - 変数全てに関して、同じ確認を行う
3. データ測定時の動作検証をする

「データ測定」がいつでも可能という状況でない場合、措置１，２できちんと対処しておくことで、措置3の検証時間を抑える。

### 補足

以下のprintfでは発生しない。

- ideone上のC (gcc version 6.3)
- gcc (version 4.4.7) on CentOS 6.8

書式指定子間違いがあっても、隣の値を読まないよう処理がきちんと実装されているのかもしれない。

書式指定子の指定間違いをきちんと警告として出す開発環境ならこういうミスは減るだろう。
例として、@fujitanozomu さんに[教えていただいた方法](http://qiita.com/7of9/items/1965c5e8d9e839652808#comment-f4d36d428c9911308cb2)。
https://ideone.com/RLp2fr

```
compilation info
prog.c: In function ‘main’:
prog.c:121:14: error: format ‘%Ld’ expects argument of type ‘long long int’, but argument 2 has type ‘int’ [-Werror=format=]
  printf("2:%Ld\n", adata.yesno);
              ^
prog.c:127:14: error: format ‘%Ld’ expects argument of type ‘long long int’, but argument 2 has type ‘int’ [-Werror=format=]
  printf("4:%Ld\n", adata.yesno);
              ^
cc1: some warnings being treated as errors
```

### 訂正
(追記 2017/09/20)

printf()でなくsprintf()を用いたchar 配列への代入で起きていた。
ideoneでsprintf()を試したが、同じ症状にはならない。
webpackerを導入したRailsアプリケーションをHerokuにデプロイした時にyarnのバージョンでエラーが出る問題


Railsにwebpackerが導入されてJavaScriptの資産を用いたフロントエンドの開発が行いやすくなりました。
実際にwebpackerを導入してローカルで動くアプリケーションが出来たので試しにHerokuにデプロイして動作確認しようとしてみたのですが、その際に以下のようなエラーが発生しました。

```
remote: -----> Installing node-v6.11.1-linux-x64
remote: -----> Installing yarn-0.22.0
remote: -----> Detecting rake tasks
remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        Webpacker requires Yarn >= 0.25.2 and you are using 0.22.0
remote:        Please upgrade Yarn https://yarnpkg.com/lang/en/docs/install/
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote:
remote:  !     Push failed
```

今回はこの問題についての対応方法です。

## バージョン

rails: 5.1.0
webpacker: 3.0.1

## 原因

webpacker3.0.1では0.25.2以上のバージョンのyarnが必要なのですが、Heroku側には0.22.0がインストールされているためエラーが出ているようです。
Heroku側で0.22.0がインストールされてしまう原因は、こちらの[コメント](https://github.com/rails/webpacker/issues/739#issuecomment-326578044)にありますが、heroku-buildpack-ruby（Heroku側でRailsアプリをビルドしてくれるツール）でyarnのバージョンがハードコードされているためです([該当コード](https://github.com/heroku/heroku-buildpack-ruby/blob/10f2f86e0fdf348e883ed0c0d54ecfd8e5cf4bd6/lib/language_pack/helpers/nodebin.rb#L22))。2017年9月19日現在、[そのバージョンを上げるPR](https://github.com/heroku/heroku-buildpack-ruby/pull/620)が上がっています。マージされれば、上記の問題も起こらなくなると思われます。

## 対応

[Heroku公式](https://devcenter.heroku.com/articles/ruby-support#installed-binaries)にありますが、heroku-buildpacksが nodejs -> ruby の順で実行されるようにすればデプロイできました。コマンドだと

```
$ heroku buildpacks:clear -a (アプリ名) # buildpacks を初期化する
$ heroku buildpacks:add heroku/nodejs -a (アプリ名)
$ heroku buildpacks:add heroku/ruby -a (アプリ名)
```

になります。これで、heroku-buildpack-nodejs側でyarnがインストールされました（バージョンは0.28.4でした）。
なお、バージョンを指定させたい時にはアプリケーションの package.json に

```package.json
"engines": {
  "yarn": ">= 0.25.2"
}
```

のように書くとheroku-buildpack-nodejs側でバージョンを指定してインストールしてくれるようです。
IT企業に内定!!必須の事前準備はこれ!!

# はじめに(In the beginning)
こちらに記載することは、あくまで一例です。必須と言えど、内定が決まった直後から必ずやれとなると士気も下がります。自分のペースで、自分の好きな分野から取り組むことをお勧めします。

# まずは英語に慣れる(First of all, let's study English!)
「英語を勉強しよう!」というよりは、「**英語に慣れておこう!**」の方が重要です:grinning:

IT企業に内定したから、プログラムをガツガツ勉強しておかなきゃ!!ということはありません。
もちろん、勉強しておいて損はないですが、今や新卒文系OKを出している企業も多いため、大学でプログラミングをちょっとやりましたよの学生では、当然ながら、現場では即戦力にならないです。(稀にそのような天才肌の方もおりますが:frowning2::frowning2:)

言語のドキュメントの最新版は、基本的に英語です。日本語訳ももちろん出ていますが、英語にアレルギーを出さずに、完全理解できないまでも読み解くことが必要です。
Google翻訳に頼ってもよいので、英語を読むことに慣れるようにしましょう:book:

# 一つの言語に集中を(Focus on one language.)
自分がどの現場に出されるかわからないから、Ruby もやらなきゃ、Java もやらなきゃ、PHP も・・・なんて、手を出し過ぎると何も身に付きません。
まずは、**一つの言語をコーディングしましょう! そして、自己レビューをする**ようにしましょう。一つの言語を理解できると、他の言語も自然と頭に入ってきます!!
理解できると自信にも繋がるので、焦らず一つの言語を書き上げるように意識をしておきましょう。

わたし自身は、Java研修のインストラクターを担当しておりますので、Javaの本を少しご紹介いたします。
ただし、**「本を読むだけでは意味がありません!! 手を動かすことが重要です!!」**
簡単なプログラムで構わないので、自分でコーディングをして実際に動かしてみて慣れていきましょう。


[「スッキリわかるjava入門」]
(https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BJava%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1-%E6%B8%85%E5%96%AC/dp/484433638X):blue_book:
![1113101090-520x.jpg](https://qiita-image-store.s3.amazonaws.com/0/196312/8716e784-2311-66f5-c022-1012a1e823a5.jpeg)

Javaの基本構文から、オブジェクト指向まで順を追って解説が載っており丁寧。

[「Head First Java」]
(https://www.amazon.co.jp/Head-First-Java-%E7%AC%AC2%E7%89%88-%E2%80%95%E9%A0%AD%E3%81%A8%E3%81%8B%E3%82%89%E3%81%A0%E3%81%A7%E8%A6%9A%E3%81%88%E3%82%8BJava%E3%81%AE%E5%9F%BA%E6%9C%AC/dp/4873112796):blue_book:
![51Gsycdh-TL._SX258_BO1,204,203,200_.jpg](https://qiita-image-store.s3.amazonaws.com/0/196312/5bb716fc-a52a-0857-b10d-db1e1c09630f.jpeg)

視覚的に Java の学習ができる。ある程度Javaを学習した人でも、また変わった視点で復習ができる。

# ビジネスマナーは大丈夫？(Do you know business Etiquette?)
「**IT企業に内定したからプログラムだけやっていればよい?**」そんなことはありません。
PCの前で作業することも多いですが、お客様とのやりとりも必要ですし、プロジェクトメンバーとの協力も必要です。
挨拶、メール、基本動作などは最低限押さえておくと、きっと役に立ちますよ！


# 調査力の強化(Let's improve your research ability)
英語も、プログラミングも、マナーもそうですが、ガツガツ勉強をするというよりは**毎日触れて慣れ親しむ**ことが重要です。
毎日触れていれば、知らないことを調べたくなる。ある意味、一番重要な事前準備は、常に「**Why it so?(なぜそうなる?)**」の考えを持ち調べようとする「**調査力の強化**」ではないかと最近感じています。

さいごに、冒頭にも記載しましたが、一番大切なことは自分のペースで自分の好きな分野からスタートすることです。そうすれば、自然と「習うより慣れる」こととなり、楽しみながら身に着けることができます。
それでは、
**Let's look forward to everything**:thumbsup:(全てのことを楽しみましょう:))
PHP7でphpspreadsheet:1.0.0-betaでインストール　エラー発生

初めて投稿投稿します
環境
・Centos7　PHP7.1　です
composer require phpoffice/phpspreadsheet:1.0.0-beta
これで実行するとエラー
下記の内容が発生します。どなたかご存知でしょうか？
Problem 1
 - Installation request for phpoffice/phpspreadsheet 1.0.0-beta -> satisfiable by phpoffice/phpspreadsheet[1.0.0-beta].
 - phpoffice/phpspreadsheet 1.0.0-beta requires ext-zip * -> the requested PHP extension zip is missing from your system.
【Linux】頭の悪いウェルカムメッセージを作った

![IMG_0796.JPG](https://qiita-image-store.s3.amazonaws.com/0/157454/06ce93af-f8c1-6e08-f6ce-bbb69d25d1d2.jpeg)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/157454/e49a105a-4966-a9ab-2306-a29fcc89845a.png)

# Linuxにログインした際に表示させることができるウェルカムメッセージの偏差値を下げてみました。

取り急ぎ以下のサイトにて詳しく記載！！

https://blog.vtryo.me/infra-engneering/linux-welcome-badbrain

ちなみにzabbixサーバをこんな風にすることも出来ます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157454/0cae6d4d-d0c6-9dda-8031-017b6b7d8ff8.png)
【メモ】Laravelで１つのテーブルに2つの外部キーを設定したEloquentモデルのリレーションの定義方法

二つの外部キーをそれぞれ第２引数に取るhasManyメソッドを定義することで実現できます。

```php
class User extends Authenticatable
{
    public function roomsFrom()
    {
        return $this->hasMany(Room::class,'from_user_id');
    }
    public function roomsTo()
    {
        return $this->hasMany(Room::class,'to_user_id');
    }

}
```
Ruby2.4未満でもInteger#digitsを使いたい!!

Ruby2.4に整数を1桁ずつ配列に入れて返すInteger#digitsメソッドが追加されました:tada:
便利なことに基数を指定するとn進数の1桁目,2桁目...を取得できます

```ruby
12345.digits #=> [5, 4, 3, 2, 1]
4.digits(2)  #=> [0, 0, 1]
```
詳しくは[こっち](https://bugs.ruby-lang.org/issues/12447)を見てね
[paiza](http://paiza.jp)やってたのですがRubyのバージョンが2.3.3でこのメソッドが使えない＞＜
なのでFixnum classをオープンして作っちゃいます

```ruby
class Fixnum
  def digits(n = 10)
    raise Math::DomainError, 'out of domain' if self < 0
    raise ArgumentError, "invalid radix #{n}" if n < 1 || n > 36
    self.to_s(n).chars.map(&:to_i).reverse
  end
end
```
ちょっとしたシーケンス図を書くのにatom-mermaidが便利すぎる話

# この記事のターゲット
・処理の流れを整理するためにシーケンス図が描きたい
・PowerPointやExcelは死んでもごめん
・エディターにはAtomを使っている


# mermaidって何よ
正確にはmermaid.js。JavaScriptのチャート作成ライブラリのこと。フローチャートからシーケンス図まで作れる優れもの。
https://mermaidjs.github.io


本来はブラウザで利用するものですが、個人的にAtomエディター上で描きたいところ。

# 偉大すぎる先人
同じことを考える人がすでにいて、Atom用のパッケージを作成してくださっていました。
感謝の意を込めていいねして利用させていただきました。

[MermaidのプレビューができるAtomパッケージを作った](http://qiita.com/takeyuichi/items/4b8ed40a598623026a9c)
https://atom.io/packages/atom-mermaid

# 利用方法
Atomでatom-mermaidというパッケージをinstallするだけ。
素敵。抱いて。

mermaidの文法も特に難しいものではないので普段プログラム書いてる人なら何の抵抗もないかと。
![スクリーンショット 2017-09-19 18.56.53.png](https://qiita-image-store.s3.amazonaws.com/0/177043/9d8c99ae-2d9c-81f7-8358-eca14966b62d.png)


# まとめ
頭の中を整理する程度の目的であれば何の問題もないです。
powerpointやexcel、その他グラフィックツールなどではちょっとの修正で全体をずらさなきゃいけないなど、作業コストが非常に高くなりがち（個人差あり）なので、テキストベースで作れると打ち合わせ中などにさっと作れて良いと思います。