OmniAICreator/Qiita-1.07M huggingface dataset:
python3のzipfileで相対パスを指定する時の注意

複数のファイルをzipに圧縮するためのpythonスクリプトを作った際に相対パスを使った時のメモです。

結論として**「相対パス"../"は使っちゃダメだよ」**というお話です。

## 環境
python 3.6.1
Windows 10

## zipfileを使ったサンプルプログラム
例えば「あるディレクトリ配下のファイルを全てzipにする」プログラムは、こんな感じでしょうか。

```python
# -*- coding:utf-8 -*-
import os
import zipfile

TARGETPATH='ここにzipしたいファイルのパス'
with zipfile.ZipFile('test.zip','w',compression=zipfile.ZIP_STORED) as new_zip:
    for f in os.listdir(TARGETPATH):
        new_zip.write(os.path.join(TARGETPATH,f))
```

注意点は`new_zip.write`の部分。writeメソッドは第1引数（filename）に圧縮対象のファイルパスを渡しますが、**第2引数（arcname）が無い場合は第1引数のパス構成がzipファイルに引き継がれます。**

## 圧縮対象パスごとの違い
前述の第2引数（arcname）を指定しない場合に、サンプルプログラムの`TARGETPATH`に設定したパスによるzipファイルの違いを示します。

### 絶対パスの場合
```python
# -*- coding:utf-8 -*-
import os
import zipfile

TARGETPATH='C:/test/dir' #絶対パス
with zipfile.ZipFile('test.zip','w',compression=zipfile.ZIP_STORED) as new_zip:
    for f in os.listdir(TARGETPATH):
        new_zip.write(os.path.join(TARGETPATH,f))
```


完成した圧縮ファイルは**絶対パスの構成がそのまま引き継がれます。**

```
test.zip
 └─test
    └─dir
       ├─a.png
       ├─b.png
       └─c.png
```

### 相対パス「./」の場合

```python
# -*- coding:utf-8 -*-
import os
import zipfile

TARGETPATH='./dir' #同じ階層のディレクトリを指定する
with zipfile.ZipFile('test.zip','w',compression=zipfile.ZIP_STORED) as new_zip:
    for f in os.listdir(TARGETPATH):
        new_zip.write(os.path.join(TARGETPATH,f))
```

これもおおよそイメージ通りで**`./`以降のパス構成が引き継がれます。**

```
test.zip
 └─dir
    ├─a.png
    ├─b.png
    └─c.png
```

### 相対パス「../」の場合
**これが上手くいかないパターンです。**

```python
# -*- coding:utf-8 -*-
import os
import zipfile

TARGETPATH='../dir' #一つ上のディレクトリを指定
with zipfile.ZipFile('test.zip','w',compression=zipfile.ZIP_STORED) as new_zip:
    for f in os.listdir(TARGETPATH):
        new_zip.write(os.path.join(TARGETPATH,f))
```

**完成したzipファイルの中身が空になってしまいました。**展開することもできません。

```
test.zip
 └─(empty)
```

<br/>
ということで**相対パスで上位のディレクトリからファイルを持ってきて圧縮したい場合は`zipfile.write`の第2引数（filename）を必ず指定しましょう。**

例えば第2引数にファイル名だけ渡すとディレクトリ無しでzipファイルが作られます。

```python
# -*- coding:utf-8 -*-
import os
import zipfile

TARGETPATH='../dir' #一つ上のディレクトリを指定
with zipfile.ZipFile('test.zip','w',compression=zipfile.ZIP_STORED) as new_zip:
    for f in os.listdir(TARGETPATH):
        new_zip.write(os.path.join(TARGETPATH,f),f) #単純にファイル名だけ指定する
```

```
test.zip
 ├─a.png
 ├─b.png
 └─c.png
```

一番良いのは相対パスを使わないことかなと思います。ディレクトリ丸ごとの圧縮なら`shutil`モジュールを使うのも良いですね。
Microsoft Graph を使ってみよう : インテリジェント機能 - 人物と洞察リソース

# ソーシャルインテリジェンス

人のつながりは、複数のコミュニケーションとコラボレーション パターン、およびビジネスのリレーションシップを基に構築することができ、Microsoft Graph ではそのような関係を取得するための API を提供しています。

これは組織構造による人の関係とは全く異なった視点でつながりを見れる、ユニークな機能です。

## 人物リソース

人物は、個人の連絡先、ソーシャル ネットワーキングの連絡先、組織のディレクトリ、最近 (メール、Skype などで) 連絡した人などになるため、社外の人物も含まれます。

## 主なシナリオ

- 一覧を表示する
- 特定の人物を取得する

## 人物の操作
いくつか代表的な操作を以下に紹介します。

**関係する人物の一覧を表示する**

GET: https://graph.microsoft.com/v1.0/me/people

```csharp:C#
await graphClient.Me.People.Request().GetAsync();
```

**人物を取得する**

GET: https://graph.microsoft.com/v1.0/me/people/{id}

```csharp:C#
await graphClient.Me.People["id"].Request().GetAsync();
```

**人物を検索する**

GET: https://graph.microsoft.com/v1.0/me/people?search=検索ワード

```csharp:C#
await graphClient.Me.People.Request(new List<Option>()
{
    new QueryOption("search", "検索ワード")
}).GetAsync();
```

**他のユーザーの関係を取得する**
People.Read.All 権限があれば、他の人の関連を見ることも出来ます。

GET: https://graph.microsoft.com/v1.0/users/{id}/people

```csharp:C#
await graphClient.Users["id"].People.Request().GetAsync();
```

# 洞察リソース
Microsoft Graph では、高度な分析と機械学習を活用し、ユーザーに関連するインサイトを収集しています。このインサイトにアクセスする API が公開されていますが、この記事を公開している時点ではまたベータ機能となります。

## 主なシナリオ

- ユーザーに関連する人気上昇中のドキュメントを取得する
- ユーザーが参照したり編集したドキュメントを取得する
- ユーザーに共有されたドキュメントを取得する

## 洞察リソースの操作
いくつか代表的な操作を以下に紹介します。尚、C# SDK では洞察リソースがサポートされていないため、HttpClient を利用してください。

**人気上昇中のドキュメントを取得する**

GET: https://graph.microsoft.com/beta/me/insights/trending

**参照したり編集したドキュメントを取得する**

GET: https://graph.microsoft.com/beta/me/insights/used

**共有されたドキュメントを取得する**

GET: https://graph.microsoft.com/beta/me/insights/shared

# まとめ
この機能のポイントは、膨大なデータを分析してこそ分かるデータを、簡単に入手できるところです。得られたデータを他のシナリオに追加するとより面白くなりますので是非試してください。

[目次に戻る](https://qiita.com/kenakamu/items/6a1ca508dc093779eefa)

# 参照

[Microsoft Graph の People API を使用した最も関連のある人物に関する情報の取得](https://developer.microsoft.com/ja-jp/graph/docs/concepts/people_example)
[ソーシャル インテリジェンス:複数の人物](https://developer.microsoft.com/ja-jp/graph/docs/api-reference/v1.0/resources/social_overview)
[Microsoft Graph での洞察操作](https://developer.microsoft.com/ja-jp/graph/docs/api-reference/beta/resources/insights)
同値関係とトートロジーの違い

あまり詳しくないので命題論理に限って真理値表を使って簡潔にまとめます。
#トートロジーとは
論理式で、それを構成する命題(atomic units)の任意の組み合わせに対して、1となる論理式のことを指します。例えば¬A∨A とか(A∧B)→Aのことです。例として、真理値表を使って(A∧B)→AがA,Bの値によらずに常に１となることを示します。

|A |B |A∧B | 
|:-:|:-:|:-:|
|1 |1 |1    |   
|1 |0 |0    |   
|0 |1 |0    |   
|0 |0 |0    | 

| A | B | A→B | 
|:-:|:-:|:-:|
| 1 | 1 |    1    |   
| 1 | 0 |    0    |   
| 0 | 1 |    1    |     
| 0 | 0 |    1    |  

|A |B |(A∧B) |(A∧B)→A |
|:--:|:---|:--:|:--:|
|1 | 1 |1    |      1         |
| 1 | 0 |    0    |      1         |
| 0 | 1 |    0    |      1         |
| 0 | 0 |    0    |      1         |


#同値とは
理論や用語の定義によって異なりますが・命題Aと命題Bが同値であるとは(A→B)∧(B→A)がトートロジーであることを指します。

一番下の表のように一般に(A→B)∧(B→A)がトートロジーである、つまり常に1となるとは限りません。

| A | B | A→B | 
|:-:|:-:|:-:|
| 1 | 1 |    1    |   
| 1 | 0 |    0    |   
| 0 | 1 |    1    |     
| 0 | 0 |    1    |
  
| A | B | B→A | 
|:-:|:-:|:-:|
| 1 | 1 |    1    |   
| 1 | 0 |    1    |   
| 0 | 1 |    0    |     
| 0 | 0 |    1    |  

|A |B |A∧B | 
|:-:|:-:|:-:|
|1 |1 |1    |   
|1 |0 |0    |   
|0 |1 |0    |   
|0 |0 |0    | 

|A |B |(A→B)∧(B→A) | 
|:-:|:-:|:-:|
|1 |1 |1    |   
|1 |0 |0    |   
|0 |1 |0   |   
|0 |0 |1    |
rspecとfactorybotを導入するときにハマった時に確認したこと

# railsでrspecとfactorybotを動かそうとしてハマったので確認したことをメモ

最終的には以下のサイトを参考にさせていただきうまくいきました
https://qiita.com/Ushinji/items/522ed01c9c14b680222c

# うまくいかないときにやったこと

## ターミナルから実行してみる(IDEから試している場合)

IDEを使っている場合は、ターミナルから実行した場合も同様の結果か確認する。
RubyMineやその他のIDEを使っている場合にハマりやすいのが、IDEの方の設定に引きずられてエラーになっているだけというパターン。  
IEDだけエラーする場合は、IDEの設定を確認する。パスや実行方法がminitestになっていないかなど。

```ターミナルからまず確認しよう:rspec
bundle exec rspec ./spec/controllers/test_spec.rb
```

## 実行するテストファイルの名前は**_spec.rbになっているか

読み込みに失敗する例：test_rspec.rb
test_spec.rbなどのように**_spec.rbとファイル名がなっているか確認する

## factory botでのエラー

#### Factory already registered: xxx

- 同じfacotryが二つある可能性がある。
factory xxxで検索して同一のものがないか確認しあれば削除か名前を変更。

- 設定がおかしくてロードが2回走る？
初めに設定を行った際、以下ファイルを作成していたところ、一つしか定義していないfactoryに対して、
factory already registerdのエラーが`config.before(:suite)`の箇所で出ていた。
rails_helperで `config.include FactoryBot::Syntax::Methods` を指定しているので、これがなくてもいいと思い、
思い切ってファイル(spec/support/factory_bot.rb)を削除することで自分の場合は一旦解決。
ファイルはgithubのfactorybotにあった。
https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#rspec

```ruby:factory_bot.rb
# spec/support/factory_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

# RSpec without Rails
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

  config.before(:suite) do
    FactoryBot.find_definitions
  end
end
```

## その他のエラー

- rails c で試して動くか確認してみる

```ruby:console
rails c
FactoryBot.build(:user)
```
- springのせいで動かない可能性？

springが起動しているか確認

```terminal:terminal
spring status
Spring is not running. # この場合は起動していないのでこの対処は不要なはず
```

ググってたときにspringのせいで動かない可能性もあるとの書き込みをいくつか見つけた
https://masawada.hatenablog.jp/entry/2018/01/06/012845


# 上記の手順をやっても解決できないとき

rspceが動作するときどのファイルを使用して、どういう順序で動いているか整理して、原因の切り分けをする。
以下にまとめてみました。 
以下を参考にして`bundle exec rails generate rspec:install`からするのも検討してみると良いかもです。

### rspecを動作させる際に必要なファイル

.rspec
spec
 |------spec_helper.rb
 |------rails_helper.rb (テストファイルでrequireが必要)
 |
 |------factories
 |　　　　            |------user.rb(モデルのテスト用ファイル)
 |
 |------xxxxx(例. controllers)
 　　　　            |------test_spec.rb(テストロジックを記載したファイル)

### 上記ファイルの実行順序

以下コマンドを実行した場合
```bundle exec rspec ./spec/xxxxx/test_spec.rb```

1.　.rspecが読み込まれる

```ruby:".rspec"
--require spec_helper
```

2.　.rspecでrequireされたspec_helperが呼ばれる

3.　spec/xxxxx/test_spec.rbが呼ばれる

```ruby:test_spec.rb
require 'rails_helper'

describe 'test' do
  let!(:test) { build(:user) }
  it 'should do something' do
   p test
  end
end
```

4.　spec/rails_helperが呼ばれる
5.　spec/factories/user.rbが呼ばれる

```ruby:user.rb
FactoryBot.define do
  factory :user do
    email "bbb@com"
    created_at Time.now
    updated_at Time.now
  end
end
```

```terminal:結果
bundle exec rspec spec/controllers/show_list_spec.rb 

#<User id: nil, email: "bbb@com", created_at: "2018-05-20 14:34:28", updated_at: "2018-05-20 14:34:28">
.

Finished in 0.04037 seconds (files took 3.17 seconds to load)
1 example, 0 failures
```
jQuery フォームボタンに応じて遷移先を変更する。

## 背景

1つのフォームタグの中に、更新ボタンや削除ボタン果てはアップロードボタンまで1つのフォームの中に入って来るデザインが来ます...。このデザイン...マジか。このデザイン受領したくない。よし、これはネタになる。

## 目的

1つのフォームタグの中で押下したボタンに応じて、action、method、enctypeを動的に変更させます。
aタグでPOSTする要件がなぜかあります。

PUT, DELETEなどの時は hidden タグを生成して、 _method に値を入れる。

## 実装

### HTML

```html
<form>
    <button type="submit" class="change-action" data-action="/" data-method="GET">一覧へ</button>
    <a href="javascript:void(0)" class="change-action" data-action="/update/1" data-method="PUT">更新</a>
    <button type="submit" class="change-action" data-action="/images" data-method="POST" data-enctype="multipart/form-data">ファイルアップロード</button>
    <button type="submit" class="change-action" data-action="/images/1" data-method="DELETE">画像削除</button>
</form>
```

### JavaScript

```javascript
"use strict";

$(function () {
    /**
     * ボタンのdata属性からフォーム属性を変更
     */
    $(".change-action").on("click", function (event) {
        // デフォルトアクションを抑止
        event.preventDefault();

        let form = $(this).parents("form");

        // action
        if ($(this).data("action")) {
            form.attr("action", $(this).data("action"));
        }

        // method
        if ($(this).data("method")) {
            if ($.inArray($(this).data("method"), ["GET", "POST"]) == -1) {
                // PUT, DELETE
                var element = $("<input />", { type: "hidden", name: "_method", value: $(this).data("method") });
                form.append(element);
                form.attr("method", "POST");
            } else {
                // GET, POST
                form.attr("method", $(this).data("method"));
            }
        }

        // enctype
        if ($(this).data("enctype")) {
            form.attr("enctype", $(this).data("enctype"));
        }

        // debug用
        console.log(form.attr("action"));
        console.log(form.attr("method"));
        console.log($("[name=_method]").val());
        console.log(form.attr("enctype"));

        // submit
        form.submit();
    });
});
```

## デモ

https://ucan-lab.github.io/jquery-sample/form-change-action

## 今後の課題

1つの画面で色々詰め込み過ぎてるデザインのため、HTMLのフォームバリデーションは全て外す必要がありました。
HTMLバリデーションとの共存が今後の課題ですが...
押下されたボタンに応じてバリデーション付けたり外したりする対応はあまり現実的ではなさそうです。

サーバーサイドでバリデーションチェックされていれば、とりあえずは...。

## さいごに

1日7記事書くとか...もう絶対やりません。
最近、[魔性のjQuery本](https://kauplan.org)に感化されてjQueryの話が書きたくなりました。
POG上達のためのデータ解析5　〜測尺データをSVM

# はじめに
　POGのシーズンがやってきました。
　知らないうちに某競馬サイトが測尺データを公開するようになっていたのでこれを使って活躍馬を予想できるか試してみました。

# 手順
　1. 測尺データを収集。とりあえず2012年〜2016年生まれを対象とした。
　2. POG期間(2歳〜3歳ダービー終了までの期間)の獲得賞金を算出。
　3. 獲得賞金をクラス分け。{0:0万, 1:700万以下、2:3000万以下、3:3000万以上}
　4. 説明変数を測尺データ（馬体重とか体高とか）、目的変数をクラス分けの数値　とし、2012〜2015年生まれの馬のデータからSVMで分類モデルを作成。

# 結果
解析元データはこんな感じ。
![Screenshot-2018-5-20 5 SelectHorse.png](https://qiita-image-store.s3.amazonaws.com/0/96262/6f9c4251-9d4f-bb5c-6649-a6a7da1be640.png)

※18/5/26訂正　モデルの学習の際に学習用データではなく、データ全体を与えている凡ミスに後で気がついた。。
訂正して学習等データを与えたところ、正解率は0.33程度に下がってしまった。これでは使い物にならなさそう。


~~SVMで学習＆推測　わりと精度が高い気がする。~~

![Screenshot-2018-5-20 5 SelectHorse(1).png](https://qiita-image-store.s3.amazonaws.com/0/96262/5ac0c009-e78f-df55-42a0-58173472d40a.png)

~~クラス3と推測された馬はたしかにちゃんと活躍している。~~
![Screenshot-2018-5-20 5 SelectHorse(2).png](https://qiita-image-store.s3.amazonaws.com/0/96262/3b38df88-9aad-6b4f-3f78-ef002d6c5d75.png)

# まとめ
~~活躍馬を予測できそう。~~

ただ測尺データが公開されている馬の数は全体の数に比べてかなり少ないため、POGより一口馬主向きの解析かもしれない。

# おまけ
　説明変数同士の関係性を可視化してみた。凡例が賞金クラス。
　賞金クラスが高いほど各変数のばらつきが小さい。
　バランスの取れた体型の馬がよく走るということだろうか。
![scale_2012_2015.png](https://qiita-image-store.s3.amazonaws.com/0/96262/1340e249-3be5-2b4c-06bc-78a1290c3edf.png)
SmartRF Protocol Packet Snifferで取得したZigbeeのパケットキャプチャデータをPCAPファイルに変換するツール

#Zigbeeのパケットキャプチャツールについて
無線通信のパケットキャプチャツールである以下を使ってZigbeeのデータを取得できます。

SmartRF Protocol Packet Sniffer
http://www.tij.co.jp/tool/jp/packet-sniffer


#SmartRF Protocol Packet Snifferの問題点
Zigbeeのプロトコルには、セキュリティ機能のメッセージがあるのですが、そのメッセージを識別することができません。またツールからpcapファイルに出力することができません。
そのため非常に解析しづらかったので、SmartRF Protocol Packet Snifferで取得したデータ（.psd）ファイルをWiresharkなどで読める.pcapファイルに変換するツールを自作することにしました。

#事前準備
- Wiresharkをインストールしてあること
- 環境変数PATHにWiresharkのexeフォルダのパスを入れてあること（text2pcap.exeを変換に使用します）

#PSD to PCAPファイル変換ツール
以下のアプローチでツールを作成
- pcapへの変換はWiresharkの標準ツールであるtext2pcapを使う
- text2pcapで読み込めるtext形式にpsdファイルのパケットデータから出力する

```psd2pcap_for_zigbee.py
import sys
import os

def main():
    #読み込みファイル名取得
    if(len(sys.argv)>1):
        filename = sys.argv[1]
    else:
        filename = raw_input('file name:')

    #PSD file読み込み
    fp_r = open(filename,"rb")

    #変数定義
    ct_payload = 0
    head_flg = 0
    head_cnt = 0
    payload_flg = 0
    null_flg = 1
    data = []
    data_all = []
    d_str_old = ""
    while True:
        d = fp_r.read(1)
        if len(d) == 0:
            break
        else:
            pass
        d_str = '%02x'%ord(d)
        d_int = int('0x'+d_str,16)

        if (null_flg==1) & (d_str_old.find("03")==0) & (d_int==head_cnt+1):
            null_flg = 0
            head_flg = 14
            head_cnt = head_cnt + 1
        elif (head_flg==1):
            ct_payload = d_int
            head_flg = 0
        elif (head_flg > 1):
            head_flg = head_flg -1
        elif (ct_payload > 0):
            data.append(d_str)
            ct_payload = ct_payload - 1
        elif (null_flg == 1):
            pass
        else:
            null_flg = 1
            #dataをまとめる
            data_str =""
            for i in range(0,len(data)):
                data_str = data_str+data[i]
            data_all.append(data)
            data = []

        d_str_old = d_str
    fp_r.close

    #pcap変換用txt作成
    export_txt(filename.split(".")[0]+".txt",data_all)
    #pcap生成
    os.system("text2pcap -l 195 "+filename.split(".")[0]+".txt "+filename.split(".")[0]+".pcap")
    os.system("del " + filename.split(".")[0]+".txt")

#Zigbeeデータをpcap変換用txtに出力
def export_txt(filename,data_all):
    fp = open(filename,"w")
    for i in range(0,len(data_all)):
        cnt=0
        for j in range(0,len(data_all[i])):
            if ((j%16)==0):
                fp.write("%03x"%(cnt)+"0"+" "+data_all[i][j])
                cnt=cnt+1
            elif ((j%16)==15):
                fp.write(" "+data_all[i][j]+"\n")
            else:
                fp.write(" "+data_all[i][j])
        fp.write("\n")
    fp.close

if __name__ == '__main__':
    main()
```

#Wiresharkの設定
最後に、Wiresharkの設定で、いくつか変更が必要になります。
- 「編集」→「設定」→「Protocols」→「IEEE802.15.4」の"TI CC24XX FCS format"にチェックを入れる
- 「編集」→「設定」→「Protocols」→「IEEE802.15.4」のSecurity Suiteを適切な値に合わせる
UbuntuでPowerPointドキュメントを作成する

# はじめに

普段からLinuxで作業している人は、PowerPointドキュメントの作成を依頼された時に困った経験はないだろうか。

Microsoft Officeの製品はLinuxには対応していない。

もう数年前からLinux対応版が出るという噂を聞くけど、未だにリリースされていない。

というか、そもそも会社の利益を上げることに熱心なMicrosoftが、わざわざシェアの低いLinux OSに対応させるなんて考えにくい。

UbuntuにはLibreOfficeというソフトが付属していて、PowerPoint形式で保存することもできる。しかしながら、そのファイルをWindowsで開くと必ず体裁が崩れる。

というわけで行き着いたのが、[WPS Office for Linux](http://wps-community.org/)というソフトウェアである。

このソフトはPowerPointとの互換性を重視しており、実際このソフトでPowerPointドキュメントを作成してWindows側で閲覧しても、体裁は全く崩れていなかった。

というわけで今回は、WPS Officeの導入方法を説明する。

## 自分のPCのスペック

OS: Ubuntu 18.04, Windows 8.1 (デュアルブート)
PC model: dynabook T55 (東芝)
CPU: Intel Core i3 (64bit)

# WPS Officeのインストール

## ダウンロード

[WPS Officeのダウンロードページ](http://linux.wps.com/)に行き、それぞれの環境に合ったパッケージをダウンロードする。
例えばUbuntuの64ビットを使用している場合、「Deb Package」を選択する。

## ソフトウェア本体のインストール

パッケージのインストール方法はOSにより異なるが、大体の場合はファイルマネージャからダブルクリックとかで行けるはず。

Ubuntuの場合は端末でパッケージがあるディレクトリに移動し、以下のコマンドでインストールできる。

```bash
$ sudo dpkg -i <パッケージ名>
```

その後、端末で`wpp`と入力しWPS Presentationが起動したら成功だ。

![Screenshot from 2018-05-20 22-57-24.png](https://qiita-image-store.s3.amazonaws.com/0/171615/ac7c240e-93f1-0370-4768-c7271e097af0.png)

日本語化する方法もあるそうだが、自分は英語で十分なので日本語化などはしていない。

ちなみに`et`コマンドでWPS Spreadsheetsが、`wps`コマンドでWPS Writerが立ち上がるのでよく覚えておこう。

# MSゴシックを試してみる

このままでも十分使い物になるのだが、Windowsの標準フォントであるMSゴシックを使ってみたくなったので、試しに使ってみる。

**ちなみに、MSゴシックのWindows以外での使用はライセンス違反になる可能性があるので、試用後は必ずフォントを削除してください。**

Windowsを立ち上げ、エクスプローラを起動する。

左側にコンピュータという項目があるのでクリックし、C:\Windows\Fontsというディレクトリに移動。

その中にあるmsgothic.ttcをUSBなどにコピーし、再びLinuxを立ち上げる。

その後、`mkdir -p ~/.fonts/`というコマンドで.fontsディレクトリを作成し、そこにmsgothic.ttcをコピーする。最後に、以下のコマンドを打って終了。

```bash
fc-cache -vf ~/.fonts
```

これで、MSゴシックが使えるようになる。

試しにMSゴシックでプレゼン資料を作り、Windows側で開いてみると、体裁が全く崩れていない！

## フォントのアンインストール

当然ですがMSゴシックを試用した後は必ずアンインストールすること！

以下のコマンドでアンインストールが可能。

```bash
rm -f ~/.fonts/msgothic.ttc
fc-cache -vf ~/.fonts
```
Qtでツールチップを表示する際に気をつけること

Qt Creator で作成したばかりのGUIアプリケーションはこんな感じ。

最初のたたき台です。

``` MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);
}

MainWindow::~MainWindow()
{
	delete ui;
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/43792201-007d-dc1e-1003-6fce7871d599.png)

ツールチップを表示するだけなら簡単です。

``` MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	setToolTip("Hello, world");
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/ac23484b-a24b-e618-881f-2389ff9851d6.png)

リッチテキスト（簡易HTMLタグ）で装飾することもできます。

``` MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	setToolTip("<i>Hello</i>, <b>world</b>");
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/466f3b17-3c27-5025-f204-0ab7f7b2feb6.png)

しかし、時には、`<`や`>`や`&`などをそのまま表示したいこともあります。

``` MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	QString s = "<i>Hello</i>, <b>world</b>";
	setToolTip(s.toHtmlEscaped());
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/7cb8b637-56a5-b02c-e77b-a08a092f1863.png)

HTMLエスケープすることで、記号も表示されるようになりました。でも待ってください。なぜか途中で改行が入ってしまいますよ！

改行せずに1行で表示したいです。そんなときは一手間かけなくてはいけません。

``` MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	QString s = "<i>Hello</i>, <b>world</b>";
	s = "<p style='white-space:pre'>" + s.toHtmlEscaped() + "</p>";
	setToolTip(s);
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/2475a3bb-e9d8-a556-99b9-971093a3a3b4.png)

めんどくさいですね。なんかバグっぽい気もしますが、そういう仕様らしいです。
http://doc.qt.io/qt-5/qtooltip.html

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61222/f11d74d7-06da-6be7-d032-267daca53da2.png)

ワードラップしたくなければ `<p style='white-space:pre'>` で囲みなさい、だそうです。
Lubuntu のバージョンを18.04 にアップグレードする

Ubuntu の軽量OS であるLubuntu の最新のバージョン18.04(2018年5月現在)が、2018年4月にリリースされたとのことで、バージョン16.04 からアップグレードを試みた。

# 環境
- Lubuntu 16.04

# アップグレード方法
ターミナルからコマンドで行う。

/etc/update-manager/release-upgrades をスーパユーザ権限で任意のエディタで開き、`Prompt=lts`になっていることを確認する。
`lts`は長期(5年)のサポートがついているバージョンを意味する。`Prompt=normal`もあるが、これは長期サポートがついているか関係なく、最新のOS のバージョンにアップグレードすることを意味している。

```.release-upgrades
Prompt=lts
```
スーパユーザ権限で、下記のコマンドを実行する。下記のコマンドは最新の安定版OS をアップグレードするためのコマンドである。
安定版のOS ではないバージョンにアップグレードするときは、`-d`オプションをつける(今回は不要)。

```.zsh
sudo do-release-upgrade
```
コマンド実行後、アップグレードに必要なパッケージのインストール処理、アップグレード処理が走る。インストールしているアプリケーション等によって異なるので、聞かれたらyes かNo で答えてアップグレードを進めていく。
例えば、Apache をマシンにインストールしている場合、apache2.conf(Apache の設定ファイル)を書き換えるのか、そのままにするのか聞いてくるので、個人の開発環境に合わせて答えること。
そして、時間はそこそこかかる。

# アップグレード後
アップグレード処理が終わり、ターミナルで下記のコマンドを実行し、最新のOS になっていることを確認する。

```.zsh
cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04 LTS"
VERSION_ID="18.04"
(以下省略)
```
# 参考URL
Lubuntu のリリースについて
https://lubuntu.me/bionic-released/

アップグレード方法について
https://eng-entrance.com/what-is-ubuntu

この記事の大半は下記のURL を参考にしました。ありがとうございました。
https://qiita.com/TsutomuNakamura/items/bbd712e3afe5f4bacfac
jQuery フォームクリアボタンを作る。

## 背景

検索条件の多い検索フォームでは入力内容をクリアしたいという要望がよくあります。
HTMLのresetでは初期値に戻るため、検索条件をクリアできない...！

## 目的

クリアボタン押下でフォームの値をクリアする(初期値に戻すのではない)

- input, select, textareaがクリア対象。
- button, submit, reset, hiddenはクリア対象外。
- ラジオボタンは任意の値を初期値に設定する。

## 実装

### HTML

```html
<form action="#" method="POST">
    <input name="email" class="input" type="email" value="test@example.com">
    <input name="name" class="input" type="text" value="奥 華子">
    <input name="password" class="input" type="password" value="">
    <input name="age" class="input" type="number" value="40">
    <div>
        <input name="sex" type="radio" value="0" data-default> 指定しない
        <input name="sex" type="radio" value="1"> 男
        <input name="sex" type="radio" value="2" checked> 女
    </div>
    <div>
        <input name="sweets" type="radio" value="1"> きのこの山
        <input name="sweets" type="radio" value="2" checked> たけのこの里
    </div>
    <div>
        <label class="checkbox">
            <input name="hobby[]" type="checkbox" checked> 音楽
        </label>
        <label class="checkbox">
            <input name="hobby[]" type="checkbox"> 映画鑑賞
        </label>
        <label class="checkbox">
            <input name="hobby[]" type="checkbox"> 読書
        </label>
    </div>
    <div>
        <select name="prefecture">
            <option value="">選択してください</option>
            <option value="1">北海道</option>
            <option value="12" selected>千葉県</option>
            <option value="47">沖縄県</option>
        </select>
    </div>
    <textarea name="message" class="textarea"></textarea>
    <input name="hidden" type="hidden" value="この要素はクリアされないよ！">

    <div>
        <button name="action" value="send" type="submit">送信</button>
        <button name="action" value="clear" type="button" class="clear-button">クリア</button>
    </div>
</form>
```

### JavaScript

```javascript
"use strict";

$(function () {
    $(".clear-button").on("click", function () {
        clearForm(this.form);
    });

    function clearForm (form) {
        $(form)
            .find("input, select, textarea")
            .not(":button, :submit, :reset, :hidden")
            .val("")
            .prop("checked", false)
            .prop("selected", false)
        ;

        $(form).find(":radio").filter("[data-default]").prop("checked", true);
    }
});
```

## デモサイト

https://ucan-lab.github.io/jquery-sample/form-clear

## ソースコード

https://github.com/ucan-lab/jquery-sample/tree/master/form-clear

## 補足

`data-default` のdata属性の付いたラジオボタンはクリアボタン押下時に選択されるようにしています。
ClassからTypeElementとTypeMirrorを取得する

Annotation Processingにおいては、処理対象のクラスはElement及びTypeMirrorでのみ扱うことができ、Classとして扱うことができない。
なので、処理対象でないクラスと比較する場合(対象のクラスが特定のクラスを継承しているか判定するなど)、ClassからTypeElementもしくはTypeMirrorを取得する必要がある。
TypeElementを取得できれば`Element#asType()`でTypeMirrorを取得できるので、ClassからTypeElementを取得できれば解決する。

使うメソッドは `java.lang.model.util.Elements#getTypeElement(CharSequence name)`
`java.lang.model.util.Elements`はインターフェースである。
`ProcessingEnvironment#getElementUtils()`でインスタンスが取得できる。
よって、AbstractProcessorを継承したクラス内でprocessingEnvを参照して取得すればよい。
よって、コードは以下のようになる。
ちなみにJavaはJava8。

```java:ExampleProcessor.java
Elements elementUtils = processingEnv.getElementUtils()
TypeElement element = elementUtils.getTypeElement("java.lang.String")
```

```kotlin:ExampleProcessor.kt
val elementUtils = processingEnv.elementUtils
val element = elementUtils.getTypeElement("java.lang.String")
```

これで、elementは`java.lang.String`クラスのTypeElementになる。
ヨドバシカメラの書籍コーナーがすごかった！！！！

お話の主題
---
ご存知の方もいらっしゃると思いますが、
ヨドバシカメラの書籍コーナーが充実していたので、感動してこの記事を書きました。
ちなみに私はヨドバシカメラの回し者ではありませんので、悪しからず。
  
### 本屋なんか行かないで、ネットで電子書籍買えばよくね？
---
まったくもって同感です。
持ち歩くと重いし嵩張るし、通勤中の電車内で読みにくいし。
当たり所悪かったら、人を殺めてしまいそうなものまでありますよね。 
ただ、以下の理由から本を買う際には実物を手に取って買うようにしております。


 1. 自分と合わない本を買ってしまう 
 よく技術ブログ等でおすすめの書籍が記載されていて「面白そうだな」とか、「今後役に立ちそうだな」と思って購入した本が「あれ？なんか思ってたんと違う」ってなることが結構ありました。
せっかく買ったんだし、お金もったいないからと無理に読み進めるのですが、大抵内容が頭に入らず、時間もお金も無駄にしてしまうことがありました。
　　
 
 2. 本を共有しづらい
何故かよくわからないのですが、よくOJTやメンティー、新人向けの技術研修にアサインされます。
彼ら、彼女らの成長に合わせて、おすすめの本を紹介しているのですが、電子書籍だと「これ読んでみな？」ができなくて歯がゆく感じます。
もちろん、自ら買ってくれるのがいいのですが・・・。なかなか難しいですよね。

これはポリシーのようなものです。
### なぜヨドバシカメラ？
---
たまたま別の用事でヨドバシカメラ錦糸町店に行ったところ、2階フロアの一角に書籍コーナーがありました。 
興味本位で立ち寄って見たら…
![20180520_172454.jpg](https://qiita-image-store.s3.amazonaws.com/0/224142/5f23c9d7-ab02-c418-493e-2da2badd5f7e.jpeg)
書籍コーナーでオライリー本を取り扱っているだと・・・・。

さぞ、書籍コーナーに力をいれているんだろうなと思い、
フロアガイドを確認すると
<img width="775" alt="錦糸町.png" src="https://qiita-image-store.s3.amazonaws.com/0/224142/73aff2ec-a143-b959-8532-71c65efe2bca.png">

書籍というジャンルすらなかったです。

ちなみにオライリーの本は販売特約店に卸されるので、大きい本屋ぐらいでしか見つける事が難しいです。

オライリーの取扱書店リストにはヨドバシカメラ錦糸町店がのってました。
<img height="500" src="https://qiita-image-store.s3.amazonaws.com/0/224142/b5a1048b-70e6-3941-18dd-80a7a03c35ac.jpeg">


これだけの扱いがあるなら、もう少しアピールすればいいのになと思いました。
もったいない！！！
【読書メモ】この一冊でソフトウェアテストの基本がわかる！【途中】

テストの役割・目的
---
 - **不具合をなくし品質を高める**
    - (仕様書通りに)正し**く**製品が作られているか
    - (顧客からみて)正し**い**製品が作られているか

### 不具合とは
 - **顧客**の要求を満たさないもの


テストを計画的に行うワケ
---
 - →完璧に不具合をなくすのは不可能
    - よって効率よく品質が保たれるようなテストを行う必要性がある
        - テストを計画的に・効率よく行えるような

テストフェーズのプラクティス
---
### 登場人物
1. テスト管理者 ... 進捗.不具合件数など確認・管理しテストフェーズを円滑に回す
2. テスト設計者 ... 担当箇所の仕様を理解し、必要なテストを設計(作成)する
3. テスト実施者 ... 設計者が作成した設計書を元に実際に手などを動かし実施する

### 手順(成果物)
1. テスト計画 (テスト計画書)
 
```
テスト計画書の項目
    1. 目的
    2. テストアイテム(テスト対象)
    3. テスト概要
    4. アプローチ(テスト方法)
    5. テスト非対象
    6. 終了判定基準
    7. 参照資料
    8. 成果物
    9. 必要機材
    10. テスト体制
    11. コミュニケーション
    12. スケジュール
    13. 特記事項
```

2. テスト設計(テスト仕様書)

```
テスト仕様書の項目
    1. テストの目的
    2. テスト対象機能
    3. テストアプローチ
    4. アプローチ詳細
```

4. テスト実施(テストケース作成)
5. テスト実施(4.を実施)
6. テスト報告
CloudFrontとS3のCORS対応

2021/2/6追記: [新コンソールではS3でのCORS設定はJSONで記述する必要がある](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html)

## CORSとは何か
Cross-Origin Resource Sharing、オリジン間リソース共有。
ブラウザで閲覧しているページと違うドメインからのリソースの取得を許可する仕組み。
ちゃんと知りたい場合は、[W3C勧告](https://www.w3.org/TR/cors/)を読むのが早い。

## なぜCORSがあるのか
他のサーバーからデータを取得して、任意のコードを実行される等のセキュリティ上の問題があるから。
ただし、これらはブラウザの実装であり、例えばサーバー同士で直接遣り取りする場合は関係無い。
また、他ドメインからのデータ転送を防いだからと言ってセキュリティ上の問題が無くなるわけでは当然無く、どちらかと言うと「そういう仕組みがあるんだな」という捉え方でいるほうが良いと思われる。
CORS対応はデータを呼ばれる側で行う。

## S3のCORS対応
CORS設定したいS3バケットのPermissions > CORS Configurationsに以下のような設定をする。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>
```

```json
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
```

上記は全ドメインからのクロスオリジンのGETリクエストを許可するもので、緩めの設定になっている。
リクエスト元URLを指定する場合は、`<AllowedOrigin>http://www.example.com</AllowedOrigin>`のようになる。
詳しくは[公式ヘルプ参照](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/cors.html)。

<img width="500" alt="cors-a.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/7331c6ea-86d4-6725-fd96-f52c0b050639.png">


ちなみにS3については、ぱっと見ると設定がデフォルトでされているように見えるが、見えているのはサンプルであって、デフォルトでCORSが適用されているわけではない。

サンプル例（※これを設定するのではない）
<img width="400" alt="cors-s3.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/a373bc57-7ee4-f6bb-9f21-1bf8d03e0694.png">


## CloudFrontのCORS対応

CloudFront > CORS設定したいDistribution > Distribution Settings > Behaviors > Editから、以下設定を行う。

- `Cache Based on Selected Request Headers`を`White List`に
- `Whitelist Headers`で`Origin`をAdd

<img width="500" alt="cors-cf.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/f57c5027-c458-633c-3c40-cb2b143a3d7b.png">


## 参考

- [Cross-Origin Resource Sharing（W3C勧告）](https://www.w3.org/TR/cors/)
- [オリジン間リソース共有 (CORS) - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/HTTP_access_control)
- [リクエストヘッダーに基づいてオブジェクトをキャッシュするように CloudFront を設定する - Amazon CloudFront](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-cors)
sageでFontAwesomeの設定を行う方法

# 概要
wordpressのボイラープレート[sage](https://roots.io/sage/)をテンプレート開発で使い始めたので、
その設定を色々書きたいと思います。
今回はFontAwesomeの設定です。
以下では全てまとめてimportしていますが、本来は個別に使うものだけimportするほうがパフォーマンスが良いと思います。

# 手順
## 1. moduleの追加
yarnで必要なモジュールを追加します。 
以下themeディレクトリにて。。

```bash
// baseファイル 必ず必要
$ yarn add @fortawesome/fontawesome
// 以下必要に応じて追加
$ yarn add @fortawesome/fontawesome-free-brands
$ yarn add @fortawesome/fontawesome-free-regular
$ yarn add @fortawesome/fontawesome-free-solid
```

## 2. 読み込み設定の追記
main.jsに以下を追加するだけでOKです。
以前は必要だったscssのimport設定とかもいらず本当に簡単ですね。

```js:resources/assets/scripts/main.js
// base package 必ず必要
import fontawesome from "@fortawesome/fontawesome";

// icons 必要に応じて選択
import faSolid from "@fortawesome/fontawesome-free-solid";
import faRegular from "@fortawesome/fontawesome-free-regular";
import faBrands from "@fortawesome/fontawesome-free-brands";

// add the imported icons  必要に応じて選択
fontawesome.library.add(faSolid, faRegular, faBrands );

```

## 3. 実行
最後buildして確認しましょう。

```bash
$ yarn build
$ yarn start
```
macにpyaudioをインストールできない時

自分用のメモ。
pythonで音楽を鳴らそうと思い

```python
pip install pyaudio
```
をしたけどエラーが出たので調べてみたら、こちらの記事
https://qiita.com/musaprg/items/34c4c1e0e9eb8e8cc5a1
の通りにやったら入りました。

```
brew update
brew install portaudio
brew link --overwrite portaudio
pip install pyaudio
```

ありがたや...!
d3.jsのbrushを使ってみた v5

## はじめに

d3.jsのbrushを使う機会があったのでメモ。

## brush

svg領域を領域選択することができる。種類は3種類。
尚，選択できる領域を
`brush.extent([[a, b], [c, d]])`
で指定できる。

1. 縦横に選択領域を広げられるbrush
2. x軸方向にのみ選択領域を広げられるbrushX
3. y軸方向にのみ選択領域を広げられるbrushY

ex) 1. brush
<p data-height="265" data-theme-id="0" data-slug-hash="GdzqRr" data-default-tab="js,result" data-user="Keyhoh" data-embed-version="2" data-pen-title="GdzqRr" class="codepen">See the Pen <a href="https://codepen.io/Keyhoh/pen/GdzqRr/">GdzqRr</a> by Heyhoh (<a href="https://codepen.io/Keyhoh">@Keyhoh</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ex) 2. brushX
<p data-height="265" data-theme-id="0" data-slug-hash="erxzmx" data-default-tab="js,result" data-user="Keyhoh" data-embed-version="2" data-pen-title="erxzmx" class="codepen">See the Pen <a href="https://codepen.io/Keyhoh/pen/erxzmx/">erxzmx</a> by Heyhoh (<a href="https://codepen.io/Keyhoh">@Keyhoh</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ex) 3. brushY
<p data-height="265" data-theme-id="0" data-slug-hash="wjNWaP" data-default-tab="js,result" data-user="Keyhoh" data-embed-version="2" data-pen-title="wjNWaP" class="codepen">See the Pen <a href="https://codepen.io/Keyhoh/pen/wjNWaP/">wjNWaP</a> by Heyhoh (<a href="https://codepen.io/Keyhoh">@Keyhoh</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## brushのイベント

`brush` は "start", "brush", "end" の三つのタイミングでイベントを拾うことができる。
`brush.on("end",function(){})`
でイベントを定義できる。
ex) brush.on
<p data-height="265" data-theme-id="0" data-slug-hash="wjNaWW" data-default-tab="js,result" data-user="Keyhoh" data-embed-version="2" data-pen-title="wjNaWW" class="codepen">See the Pen <a href="https://codepen.io/Keyhoh/pen/wjNaWW/">wjNaWW</a> by Heyhoh (<a href="https://codepen.io/Keyhoh">@Keyhoh</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## API

より詳細な操作は[公式API](https://github.com/d3/d3-brush)を参照のこと。

## おわりに

初投稿です。
間違いや質問等頂ければとても嬉しいです。

## 改稿履歴

2019/07/08 - 体裁を整える
MSwordをgitで管理する方法

[docx2txt](https://sourceforge.net/projects/docx2txt/)(0.7)  - A pure python-based utility to extract text and images from docx files.

# 環境
Archlinux(on vagrant)

# docx2txtをインストール

```shell-session
$ pacman -S docx2txt
# または
$ pip install docx2txt
# または
# $ apt install docx2txt # ubuntuなら
```

# 管理方法

## 概要
ここでは仮に`XXX管理文書.docx`の差分を管理していくこととします。
docx形式はバイナリ形式なので`git diff`コマンドなどでは差分表示してくれません。

`docx2txt`はdocx形式をtxt形式に直してくれるので、そのtxtをgitに管理させていきます。


## docx -> txt

```shell-session
$ docx2txt XXX管理文書_180514.docx
# XXX管理文書_180514.txtが生成される
```
まず、管理したいdocxファイルを`docx2txt`を使用してtxtファイルに書き下します。

## txtをリネーム
```shell-session
$ mv -f XXX管理文書_1805??.txt XXX管理文書.txt
# 日付なしのマスターtxtファイルに上書きする
```

次に、gitで差分管理できるように管理するtxtファイル名に上書きします。上の例では`XXX管理文書.txt`の差分を見ていこうとしています。

`mv`するときに、正規表現の'?'をうまく使うことで、日付が変わってもヒストリを汚さず、繰り返し同じコマンドが使用できます。


## .gitignore

```:.gitignore
/old/
~*
```
スワップファイル~の無視とoldディレクトリの無視。
oldディレクトリはgit使えない人用に、古い日付のdocxをoldにコピーしておきます。古き良き管理方法．．．

```shellscript
cp XXX管理文書_1805??.docx old/
```

~~もっと良くするために、ハッシュタグつきでoldフォルダに保存すれば、~~
~~同じ日付で変更が重なってoldフォルダに重複ファイルが~~
~~コピーされることはなく、どのハッシュのdocxか(自分だけは)わかります。~~
> 時間も記録すればいいよな。gitのハッシュタグによる管理は複数の人が同時刻にcommitする可能性があるし、ファイルの微妙に変えられている可能性もあるからハッシュを見るわけで、ここで一人で管理するならハッシュ使わなくてもいいよね

```shell-session:cp_to_old_with_hash
cp XXX管理文書_1805??.docx old/XXX管理文書_1805??$(git rev-parse --short HEAD).docx
```

> `git rev-parse --short HEAD`はHEADのハッシュタグ最初の7文字を返してくれるコマンド。

## git commit
最後にコミット

```shell-session
$ git add XXX管理文書_1805??.docx XXX管理文書.txt
$ git commit -m '課長の朱書き直した'
```
## git diff
`git diff`や`tig`で差分表示すると`XXX管理文書.txt`の差分が表示されます。
ATOM 1.27.0 x64 で pen-paper-coffee-syntax を使う

メニューをどのようにして日本語設定したか記憶にないけれども備忘録
どこにも手順書が無かったので作成

環境は Windows8.1 Pro
多分日本語メニュー化以外はデフォルトのまま


- [ファイル]→[環境設定]
- [インストール]をクリック
- テキストエリアに [pen-paper-coffee-syntax] と入力し[テーマ]をクリック
- [install]をクリック

一旦Atomを終了

- [テーマ]をクリック
- [シンタックステーマ]で[Pen Paper Coffee]を選択

以上
【Ruby】Array#mapの小さなサンプルメモ


```ruby
arr1 = [1,2,3]
p arr1.map{|i| i + 1} #=> [2, 3, 4]

arr2 = [[1,2], [3,4], [5,6]]
p arr2.map{|i,j| i+j} #=> [3, 7, 11]
```
個人的に気になっているJavaScriptビューライブラリをまとめてみた

個人的に気になっているJavaScriptビューライブラリをメモ程度にまとめてみた。
今回まとめたのは下記の4つ。

- Angular(2.x~)
- React
- Vue.js
- Hyperapp

また、以下の観点でそれぞれのライブラリを比較してみる。

|観点|説明|
|:---|:---|
|CLIの有無|ライブラリ用のCLIが用意されていて、雛型の作成が簡単か。|
|CDNの有無|ライブラリのCDNが用意されていて、HTMLにURLを書くだけで使用できるか。|
|学習コスト|学習コストがどれだけかかるか。|
|ネイティブアプリの開発|ネイティブアプリ(スマホ)の開発が可能か。|
|GitHubのスター数|GitHubのスター数から人気を見る。|
|Googleトレンド検索|トレンド検索から注目度を見る。|

## CLIの有無

Hyperapp以外はCLIが提供されている感じ。
ちなみにHyperappを動かすための最小構成が用意されている[hyperapp-one](https://github.com/selfup/hyperapp-one)というものはあった。

||名称|公式ページ|
|:---|:---:|:---|
|Angular|Angular CLI|[https://cli.angular.io/](https://cli.angular.io/)|
|React|create-react-app|[https://github.com/facebook/create-react-app](https://github.com/facebook/create-react-app)|
|Vue.js|vue-cli|[https://github.com/vuejs/vue-cli](https://github.com/vuejs/vue-cli)|
|Hyperapp|-|-|

## CDNの有無

Angular以外はCDNで提供されている感じ。ちょっとお試ししたい時とかはCDNのほうが楽かも。
ちなみに[AngularJS(Angular1.x)](https://docs.angularjs.org/misc/downloading)はCDNが提供されていた。

||CDNの有無|公式ページ|
|:---|:---:|:---|
|Angular|無|-|
|React|有|https://reactjs.org/docs/cdn-links.html|
|Vue.js|有|https://jp.vuejs.org/v2/guide/installation.html|
|Hyperapp|有|https://github.com/hyperapp/hyperapp|

## 学習コスト

個人的には出来ることが多くなると学習コストが高くなるイメージ。

||学習コスト(主観)|説明|
|:---|:---:|:---|
|Angular|高そう|フルスタックFWと言われているだけあって色々な機能があるため。(ルーターなど)|
|React|普通|Angularとは異なり必要最低限の機能しか備わっていない。必要となったら拡張していくイメージ。|
|Vue.js|普通|Reactと同じ。|
|Hyperapp|この中では一番低いかも|Hyperapp自体のコードが1KBのため、頑張れば読むことも可能なため。|

## ネイティブアプリの開発

||開発可能か|説明|
|:---|:---:|:---|
|Angular|可能|IonicやNativeScriptといったプラットフォームを用いることで可能。|
|React|可能|ReactNativeというプラットフォームを用いることで可能。|
|Vue.js|可能|NativeScriptというプラットフォームを用いることで可能。|
|Hyperapp|?|不明。Monacaとか用いればできそうな気がする……。|


## GitHubのスター数(2018/5/10 時点)

||スター数|GitHubのリポジトリ|
|:---|:---:|:---|
|Angular|36,073|[https://github.com/angular/angular](https://github.com/angular/angular)|
|React|95,431|[https://github.com/facebook/react/](https://github.com/facebook/react/)|
|Vue.js|93,687|[https://github.com/vuejs/vue](https://github.com/vuejs/vue)|
|Hyperapp|12,254|[https://github.com/hyperapp/hyperapp](https://github.com/hyperapp/hyperapp)|

## Googleトレンド検索(2018/5/10 時点)

### 世界
![image.png](https://qiita-image-store.s3.amazonaws.com/0/252241/7d385d5d-6190-1140-2eca-1fe0bf5b5f76.png)

### 日本
![image.png](https://qiita-image-store.s3.amazonaws.com/0/252241/016112df-1bbb-c823-cbff-c608e48eea3a.png)
gccの基本をはじめから

#gcc
gccコマンドは特に指定をしない場合、プリプロセス→コンパイル→アセンブル→リンクという処理を一括してくれる。
オプションを指定することでこれらを個別に実施することができる（リンクは除く）のだが、よくオプション名を忘れてしまうので、その備忘録

##プリプロセス　
** 結果は標準出力へ出力される。

```shell
$gcc -E <FILE.c>
```

##プリプロセス&コンパイル
** .sのファイル(アセンブリ言語のコード）が生成される。

```shell

$gcc -S <FILE.c>
```

##アセンブル or プリプロセス&コンパイル&アセンブル
** .oのファイル(マシン語のコード）が生成される。

```shell

$gcc -c <FILE.s>
```
#参考：#defineで内部で定義される文字列
内部的に#defineで定義されている文字列の多くは＿＿(アンダースコア2つ)で始まるが、たまにそうでないものもある。たまにこれらと自分で定義した変数の名前が衝突して、意図しないプログラムの書き換えを引き起こすことがある（環境依存）。内部的に#defineで定義されている文字列を知っておけば、これを予防できる。
###内部的に#defineで定義されている文字列を一覧で表示
**標準出力へ出力

```shell

$gcc -dM -xc -E /dev/null
```
slickでのPlainSQLからケースクラスへのマッピングメモ

## テーブル定義
```
CREATE TABLE table1(
  table1_primary,
  table1_name,
  table2_primary,
  PRIMARY KEY(table1_primary)
);
CREATE TABLE table2(
  table2_primary,
  table2_name,
  PRIMARY KEY(table2_primary)
);
```

## entity

``` entities.scala
package com.exsample.models

import slick.jdbc.GetResult

package entities {

  case class Table2(
    table2Primary: Int,
    table2Name: String
  )
  object Table2 {
    implicit val table2Result = GetResult(r =>
      r.<<,
      r.<<
    )
  }

  case class Table1(
    table1Primary: Int,
    table1Name: String,
    table2: Table2
  )
  object Table1 {
    implicit val table1Result = GetResult(r =>
      r.<<,
      r.<<,
      r.<<[Table2]
    )
  }
}
```

## Repository

``` SlickRepository.scala
package com.exsample.repositories

import scala.concurrent.Future
import slick.driver.MySQLDriver.api._
import slick.jdbc.JdbcBackend.Database
import slick.jdbc.GetResult
import com.exsample.entities.Table1

trait SlickRepository {

  def selectAll(): Future[Vector[Table1]]
}

class SlickRepositoryImpl(db: Database) extends SlickRepository {

  override def selectAll() = db.run(Sqls.selectAll())
}

object Sqls {

  def selectAll() =
    sql"""
      SELECT
        t1.table1_primary,
        t1.table1_name,
        t2.table2_primary,
        t2.table2_name
      FROM
        table1 t1
      JOIN
        table2 t2
      ON
        t2.table2_primary = t1.table2_primary
    """.as[Table1]
}
```

詳しくは↓

- http://krrrr38.github.io/slick-doc-ja/v3.0.out/Plain+SQL%E3%82%AF%E3%82%A8%E3%83%AA.html
- http://slick.lightbend.com/doc/3.0.0/api/index.html#slick.jdbc.PositionedResult
【Ruby】Array#zipの小さなサンプルメモ

# サンプル

```ruby
arr1 = [1,2,3]
arr2 = [4,5]
arr3 = [6,7,8]

p arr1.zip(arr2)
p arr1.zip(arr2, arr3)

```

# 実行結果

```sh
[[1, 4], [2, 5], [3, nil]]
[[1, 4, 6], [2, 5, 7], [3, nil, 8]]
```
BIOとNIOの違いついてのまとめ

#初めに
前回はBIOとNIO転送路それぞれを作りました、今日はBIOとNIOの違いについてまとめてみます。

#通信方式の比較
##通信フロー

簡単に言うと、
BIOはI/Oをする際(read,write)に、処理が**ブロックされる**こと。
NIOはI/Oをする際(read,write)に、処理が**ブロックされない**こと。

通信フローは、以下になります。

>BIO：
>![Untitled Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/255229/1679e76a-2e9f-d212-5bfc-17ad3605ae67.png)

*****

>NIO：
>![Untitled Diagram (1).png](https://qiita-image-store.s3.amazonaws.com/0/255229/704cfab4-24e4-8135-7456-316cec710c02.png)


##どの処理がブロックされるか
サーバー側に対して、以下のことをやらないといけません：
-　step1：クライアントから送られたデータをもらうこと（IO処理がこの段階で発生）
-　step2：もらったデータを何か処理を行い、クライアントにリスポンスすること

**BIOとNIOに対して、step2の処理がほぼ同じですが、step1の処理が違います。**
-　BIOのstep1：ブロッキング。１リクエストに対して１threadで処理する。スレッドの上限数がボトルネックになります。
-　NIOのstep1：ノンブロッキング。１リクエストに対して１threadで処理するではなくて、Selectorに任せます。そして、Selectorが随時に任されたsocketをチェックします。socketの生成が終わったら、threadに連絡して、step2に移行するという流れです。


#まとめ
BIOに比べて、NIOはI/Oリクエストをブロッキングさせないものです。既存のI/O処理(BIO)を改善でき、数万以上のクライアントを同時に相手にする必要があるシステムでは、NIOの方がいいと言われています。
マルチプロセスで圧縮するpigzをatoolから使う

pigzはgzipをマルチスレッドで行ってくれるツール。
pigzのインストールは

```shell-session
$ pacman -S pigz
```


atoolという圧縮解答のラッパーツールを使用するので、これもインストール

```shell-session
$ pacman -S atool
```



**atoolのmanによると、`~/.atoolrc`に次のように書き込めば、シングルプロセスのgzipではなく、マルチプロセス使って圧縮したpigz使ってくれる。**


```:~/.atoolrc
use_tar_z_option 0
use_pigz 1
```


2.4GBのh5形式のファイルを普通のgzipとpigzで圧縮してみた時の差は次の表

|コマンド   |実行時間 |
|----------|--------|
|tar + gz  |4:42.37 |
|tar + pigz|1:23.81 |


```shell-session:gzip_vs_pigz_use_atool
# gzip使用
$ apack someting_mean.tar.gz someting_mean.h5
237.50s user 27.97s system 94% cpu 4:42.37 total

# pigz使用
$ apack someting_mean.tar.gz someting_mean.h5
246.75s user 38.13s system 339% cpu 1:23.81 total
```

> ~/.atoolrcに設定を書き込むので、実行するコマンドは同じです。

実行時間が3分18秒早くなった!3倍超の速度で処理してくれた!!
RubyでBoxのファイルを取得する

[Box](https://www.box.com/ja-jp/home)はストレージサービス。
BoxからAPIを用いてRubyでファイルを取得する。

## Boxアプリを作る
非公開のBoxアプリを作る。

Box Developersにアクセスし、「アプリの新規作成」
<img width="300" alt="a.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/64e56c78-399c-d046-5696-f75ddb84534a.png">

種類は「カスタムアプリ」にしておく
<img width="500" alt="b.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/fb4c6cfb-2b96-c9fa-1fe9-bed4540bcda2.png">

認証方法はとりあえずオススメの「JWTを使用したOAuth 2.0(サーバー認証)」
<img width="400" alt="c.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/7de88462-5d8f-15da-a7b7-6f2232c13265.png">

アプリ名は適当で可（使われた事があるものはNGになる模様？）
<img width="500" alt="d.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/1de6f670-435f-3d66-c115-75838edfdec6.png">

成功です！
<img width="300" alt="e.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/cc1c1b7a-1c6e-7b18-99f1-6a8e38a26fdf.png">

## gemをインストールする
Box用のgemは[Boxr](https://github.com/cburnette/boxr)という（公式）。
`gem install boxr`する。

## トークンを取得する
Box Developersの以下の箇所からトークンをメモする。
使用中のアプリケーション＞（作ったアプリ）＞構成＞Developerトークン
<img width="500" alt="f.png" src="https://qiita-image-store.s3.amazonaws.com/0/9104/3ff08959-ac12-7203-c6d7-df32f28a6d12.png">

※書かれている通り、60分毎にトークンが無効になる。無かったらボタンを押して新しいトークンを生成する。

## コードを書く
Excelを1ファイル取得するコードを書いてみる。

```rb
require "boxr"

# 先程メモしたトークンを貼り付ける
BOX_DEVELOPER_TOKEN = "hogetoken".freeze

client = Boxr::Client.new(BOX_DEVELOPER_TOKEN)

# フォルダのオブジェクトを取得
folder_obj = client.folder_from_path("/hoge/fuga")

# フォルダ内を検索する
results = client.search("abc", file_extensions: ["xls", "xlsx"], ancestor_folder_ids: [folder_obj.id], content_types: ["name"], type: "file")

# 検索結果をループする
results.each do |file|
  # 類似性のあるファイルがたくさん検索にかかるので、
  # 本当に対象のファイルなのかの判断は検索結果を見つつ調整する必要がある
  if file.name =~ /abc.xlsx?\z/
    open(file.name, "w") do |out|
      # ファイルをダウンロードする
      out.write(client.download_file(file))
    end
  end
end
```

これで対象のExcelファイルが取得できた。


## リファレンス
[公式のリファレンス](https://developer.box.com/reference)と[BoxrのREADME](https://github.com/cburnette/boxr)に用意されているが、1ページでひたすら長く、分かりやすいとも言えず、色々試してみないと分からない点もある。
MySQLでテーブルがあるのにテーブルが無いエラーが出た時の対処法

## 症状

テーブルが見えているのにテーブルが無いとエラーが出る。

```
Mysql2::Error: Table 'table_name' doesn't exist: SHOW FULL FIELDS FROM `table_name`
```

テーブルを作ろうとすると以下のようなエラーが出る。

```
ERROR 1050 (42S01): Table 'table_name' already exists
```

## 対処法

### 1. MySQLサービスを停止する

```sh
mysql.server stop
```

### 2. 対象のテーブルファイルを削除する
`brew`でインストールするとだいたい`/usr/local/var/mysql/db_name`の辺りにある。

```sh
rm table_name.ibd
```

### 3. MySQLサービスを起動する

```sh
mysql.server start
```

### 4. 改めてテーブルを作る
`create table`する
Twilio Functionsを使って、現在の天気を取得する

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

ハッカソンイベントなどでは、ときどき天気を取得したいときがあります。
天気を取得するためのAPIはいくつかありますが、今回はOpenWeatherMapというサービスを利用して、Twilio Functionsから天気を取得するコードを紹介します。

## 準備

[OpenWeatherMap](https://openweathermap.org/)に移動し、[サインアップページ](https://home.openweathermap.org/users/sign_up)からアカウントを作成します。サインアップは無料です。

サインアップが完了したら、API keysタブに移動し、Keyの値をメモ帳に記録します。
![OpenWeatherMap.png](https://qiita-image-store.s3.amazonaws.com/0/86046/095d6609-7776-8cd1-c292-3469ece48b6a.png)

## Functionsの作成

- Twilioの管理コンソールにログインします。
- **Runtime**メニューの**Functions**を選択し、さらに**Manage**を選びます。
- 新しくFunctionを作成します。テンプレートはBlankで構いません。
- **FUNCTION NAME**と**PATH**欄は適当に入力します。
- **ACCESS CONTROL**のチェックボックスは外しておきます。
- **CODE**欄に以下のコードを貼り付けます。

```lang:Function
const https = require('https');

exports.handler = function(context, event, callback) {
    const HOST = 'api.openweathermap.org/data/2.5/weather';
    const CITY = 'Tokyo';
    const APPID = 'ここにOpenWeatherMapのAPP Keyを貼り付けます';

    let result = {};
    const req = https.request(`https://${HOST}?q=${CITY}&APPID=${APPID}`, (res) => {
        res.on('data', (chunk) => {
            result = JSON.parse(chunk);
        });
        res.on('end', () => {
            console.log(`${CITY} is a ${result.weather[0].description}.`);
            callback(null, result);
        });
    });

    req.on('error', (e) => {
      console.error(`problem with request: ${e.message}`);
      callback(e.message);
    });

    req.end();

};
```

- ６行目に先程控えておいたKeyを書き込みます。
- **SAVE**ボタンを押して、Functionを保存します。
- デプロイが完了した旨のメッセージが表示されたら、**PATH**欄のURLをコピーして、ブラウザで実行してみます。
- Functionの画面には、以下のようなメッセージが表示されれば成功です。

<img width="695" alt="スクリーンショット 2018-05-20 21.37.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/c043f0bc-45bc-cf4a-f50f-8495924dcf1d.png">

ちなみに、天気データの詳細は[こちらのページ](https://openweathermap.org/weather-conditions)を参照してください。

このFunction自体は、以下のような天気データをJSON形式で返しますので、たとえばTwilio StudioなどでこのFunctionを呼び出し、必要なデータだけを取得することもできます。

```lang:JSON
{"coord":{"lon":139.76,"lat":35.68},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":288.45,"pressure":1020,"humidity":51,"temp_min":286.15,"temp_max":290.15},"visibility":10000,"wind":{"speed":4.1,"deg":160},"clouds":{"all":75},"dt":1526817600,"sys":{"type":1,"id":7619,"message":0.0045,"country":"JP","sunrise":1526758342,"sunset":1526809383},"id":1850147,"name":"Tokyo","cod":200}
```

Happy Hacking!
自分用AWS クラウドサービス活用資料集メモ Auto Scaling編


#### [Auto Scaling](https://aws.amazon.com/jp/autoscaling/)

情報元: [AWS Black Belt Online Seminar 2017 Auto Scaling](https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-auto-scaling)

* 動的スケーリング3種
    * ChangeInCapacity
        * 指定したインスタンス数だけ容量を増減
        * ex. アラームが起きたら2台増やす
    * ExactCapacity
        * 指定したインスタンス数に容量を変更
        * アラームが起きたら2台にする
    * PercentChangeInCapacity
        * 指定したインスタンス数に容量を変更
        * 現在のサイズから20%増やす
* 負荷が予想できるなら: スケジュールベース
* 予定された負荷の対策: 手動スケーリング
* 予測できない緩やかな負荷: 動的スケーリング
* ヘルスチェック
    * EC2: ステータスがrunning以外の状態を以上と判断
    * ELB: ELBのヘルスチェックを利用
* クールダウン: スケーリングアクション実行後、指定した時間ないは次のスケーリングアクションを実行しない仕組み
    * シンプルスケーリングポリシーのみ対応
* ターミネーションポリシー: スケールイン時どのインスタンスから終了するか定義
    * OldestInstance / NewestInstance
    * OldestLaunchConfiguration
    * ClosestToNextInstanceHour (次の課金が始まるタイミングが最も近いインスタンス)
    * Default (OldestLaunchConfigurationとClosestToNextInstanceHourを順に適用し、複数インスタンスが残ればランダム)
    * インスタンス保護対象は除外
* インスタンスのアタッチ・デタッチ
    * インスタンスのアタッチ: Auto Scaling Groupに追加できる。Desired Capacityが自動で追加される
    * インスタンスのデタッチ: Auto Scaling Groupから取り除ける。Desired Capacityは変更されないため、新規インスタンスが追加される
    * どちらもELBとは連動する。
* スタンバイ: ELBからデタッチされ、トラフィックが流れないようになる
    * Desired Capasityも自動で変更される
* ライフサイクルフック: Auto Scalingによるインスタンス起動・終了を待機させ、起動時または終了時にカスタムアクションを実行できる仕組み
    * インスタンス起動・終了処理を待機させ、メッセージを通知。SNS、SQS、CloudWatchイベントに送られる
    * 待機時間にカスタムアクションを(初期化・終了処理）を実行
    * ライフサイクルの終了または待機時間延長コマンドを実行
* 突発的なスパイクには向いていない
    * CloudFrontにオフロード
    * API Gatewayでスロットリング
    * サイトを静的ページに切り替える
* アーキテクチャとしてはSQSやECS、Blue Green(ASGをCloudFormationで自動作成)等が挙げられる。
* Application Auto Scaling: Auto Scalingと似たUXでAWSリソースの自動スケールを実現
    * ECS
    * Spot Fleet
    * EMR
ofThreadを指定したfpsで動かす

## ofThreadで作成したスレッドの実行速度は不定
ofThreadで作成したスレッドの実行速度は不定で、`ofSetFrameRate()`でも制御できない。


## `ofTimer`を使う
[forum.openframeworks.ccでofTimerを利用した方法](https://forum.openframeworks.cc/t/running-a-function-every-250us-microseconds-on-ras-pi-2/21250/3)があった。
60fps(16ms)。で動かしたい場合は、以下のようにする。


```C++
class ThreadedUpdate : public ofThread {
public:
    
    void setup() {
        timer_.setPeriodicEvent(16666666); //引数の単位は、ns
        startThread();
    }

    void draw() const {

    }

private:
    void threadedFunction() {
        while(isThreadRunning()) {
            timer_.waitNext();
            if(lock()) {
                //...do something
                unlock();
            } else {
                ofLogWarning("threadedFunction()") << "Unable to lock mutex.";
            }
        }
    }

    ofTimer timer_;
};
```
[Angular] Pipe を Typescript コード中で使う

Angularにおいて、 Pipe は、 `html` 内で利用して、各種表示用の変換を行ってくれます。
しかし、たまに `html` の外で使いたい（Typescriptのコード内で使いたい）ということがあります。

そういう場合は、特に何も考えず、インスタンス化してメソッドを使うと良いです。

↓例

```.ts
new PhoneNumberPip().transform(value)
```

簡単ですね。