OmniAICreator/Qiita-1.07M huggingface dataset:
【PlayCanvas】Elementコンポーネントで日本語を表示するの補足

PlayCanvasで日本語を表示する方法は下記のリンクを参照してください。

[ここ](https://support.playcanvas.jp/hc/ja/articles/115012647588)

補足としまして使用する文字はあらかじめ定義しないといけなく、デフォルトで日本語は入っていません。

こちらに、ひらがな、全角かたかな、半角カタカナ、常用漢字を示しておきます。

```js:

あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽゃゅょアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポャュョｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜｦﾝﾟﾞ亜哀挨愛曖悪握圧扱宛嵐安案暗以衣位囲医依委威為畏胃尉異移萎偉椅彙意違維慰遺緯域育一壱逸茨芋引印因咽姻員院淫陰飲隠韻右宇羽雨唄鬱畝浦運雲永泳英映栄営詠影鋭衛易疫益液駅悦越謁閲円延沿炎怨宴媛援園煙猿遠鉛塩演縁艶汚王凹央応往押旺欧殴桜翁奥横岡屋億憶臆虞乙俺卸音恩温穏下化火加可仮何花佳価果河苛科架夏家荷華菓貨渦過嫁暇禍靴寡歌箇稼課蚊牙瓦我画芽賀雅餓介回灰会快戒改怪拐悔海界皆械絵開階塊楷解潰壊懐諧貝外劾害崖涯街慨蓋該概骸垣柿各角拡革格核殻郭覚較隔閣確獲嚇穫学岳楽額顎掛潟括活喝渇割葛滑褐轄且株釜鎌刈干刊甘汗缶完肝官冠巻看陥乾勘患貫寒喚堪換敢棺款間閑勧寛幹感漢慣管関歓監緩憾還館環簡観韓艦鑑丸含岸岩玩眼頑顔願企伎危机気岐希忌汽奇祈季紀軌既記起飢鬼帰基寄規亀喜幾揮期棋貴棄毀旗器畿輝機騎技宜偽欺義疑儀戯擬犠議菊吉喫詰却客脚逆虐九久及弓丘旧休吸朽臼求究泣急級糾宮救球給嗅窮牛去巨居拒拠挙虚許距魚御漁凶共叫狂京享供協況峡挟狭恐恭胸脅強教郷境橋矯鏡競響驚仰暁業凝曲局極玉巾斤均近金菌勤琴筋僅禁緊錦謹襟吟銀区句苦駆具惧愚空偶遇隅串屈掘窟熊繰君訓勲薫軍郡群兄刑形系径茎係型契計恵啓掲渓経蛍敬景軽傾携継詣慶憬稽憩警鶏芸迎鯨隙劇撃激桁欠穴血決結傑潔月犬件見券肩建研県倹兼剣拳軒健険圏堅検嫌献絹遣権憲賢謙鍵繭顕験懸元幻玄言弦限原現舷減源厳己戸古呼固股虎孤弧故枯個庫湖雇誇鼓錮顧五互午呉後娯悟碁語誤護口工公勾孔功巧広甲交光向后好江考行坑孝抗攻更効幸拘肯侯厚恒洪皇紅荒郊香候校耕航貢降高康控梗黄喉慌港硬絞項溝鉱構綱酵稿興衡鋼講購乞号合拷剛傲豪克告谷刻国黒穀酷獄骨駒込頃今困昆恨根婚混痕紺魂墾懇左佐沙査砂唆差詐鎖座挫才再災妻采砕宰栽彩採済祭斎細菜最裁債催塞歳載際埼在材剤財罪崎作削昨柵索策酢搾錯咲冊札刷刹拶殺察撮擦雑皿三山参桟蚕惨産傘散算酸賛残斬暫士子支止氏仕史司四市矢旨死糸至伺志私使刺始姉枝祉肢姿思指施師恣紙脂視紫詞歯嗣試詩資飼誌雌摯賜諮示字寺次耳自似児事侍治持時滋慈辞磁餌璽鹿式識軸七𠮟失室疾執湿嫉漆質実芝写社車舎者射捨赦斜煮遮謝邪蛇尺借酌釈爵若弱寂手主守朱取狩首殊珠酒腫種趣寿受呪授需儒樹収囚州舟秀周宗拾秋臭修袖終羞習週就衆集愁酬醜蹴襲十汁充住柔重従渋銃獣縦叔祝宿淑粛縮塾熟出述術俊春瞬旬巡盾准殉純循順準潤遵処初所書庶暑署緒諸女如助序叙徐除小升少召匠床抄肖尚招承昇松沼昭宵将消症祥称笑唱商渉章紹訟勝掌晶焼焦硝粧詔証象傷奨照詳彰障憧衝賞償礁鐘上丈冗条状乗城浄剰常情場畳蒸縄壌嬢錠譲醸色拭食植殖飾触嘱織職辱尻心申伸臣芯身辛侵信津神唇娠振浸真針深紳進森診寝慎新審震薪親人刃仁尽迅甚陣尋腎須図水吹垂炊帥粋衰推酔遂睡穂随髄枢崇数据杉裾寸瀬是井世正生成西声制姓征性青斉政星牲省凄逝清盛婿晴勢聖誠精製誓静請整醒税夕斥石赤昔析席脊隻惜戚責跡積績籍切折拙窃接設雪摂節説舌絶千川仙占先宣専泉浅洗染扇栓旋船戦煎羨腺詮践箋銭潜線遷選薦繊鮮全前善然禅漸膳繕狙阻祖租素措粗組疎訴塑遡礎双壮早争走奏相荘草送倉捜挿桑巣掃曹曽爽窓創喪痩葬装僧想層総遭槽踪操燥霜騒藻造像増憎蔵贈臓即束足促則息捉速側測俗族属賊続卒率存村孫尊損遜他多汰打妥唾堕惰駄太対体耐待怠胎退帯泰堆袋逮替貸隊滞態戴大代台第題滝宅択沢卓拓託濯諾濁但達脱奪棚誰丹旦担単炭胆探淡短嘆端綻誕鍛団男段断弾暖談壇地池知値恥致遅痴稚置緻竹畜逐蓄築秩窒茶着嫡中仲虫沖宙忠抽注昼柱衷酎鋳駐著貯丁弔庁兆町長挑帳張彫眺釣頂鳥朝貼超腸跳徴嘲潮澄調聴懲直勅捗沈珍朕陳賃鎮追椎墜通痛塚漬坪爪鶴低呈廷弟定底抵邸亭貞帝訂庭逓停偵堤提程艇締諦泥的笛摘滴適敵溺迭哲鉄徹撤天典店点展添転塡田伝殿電斗吐妬徒途都渡塗賭土奴努度怒刀冬灯当投豆東到逃倒凍唐島桃討透党悼盗陶塔搭棟湯痘登答等筒統稲踏糖頭謄藤闘騰同洞胴動堂童道働銅導瞳峠匿特得督徳篤毒独読栃凸突届屯豚頓貪鈍曇丼那奈内梨謎鍋南軟難二尼弐匂肉虹日入乳尿任妊忍認寧熱年念捻粘燃悩納能脳農濃把波派破覇馬婆罵拝杯背肺俳配排敗廃輩売倍梅培陪媒買賠白伯拍泊迫剝舶博薄麦漠縛爆箱箸畑肌八鉢発髪伐抜罰閥反半氾犯帆汎伴判坂阪板版班畔般販斑飯搬煩頒範繁藩晩番蛮盤比皮妃否批彼披肥非卑飛疲秘被悲扉費碑罷避尾眉美備微鼻膝肘匹必泌筆姫百氷表俵票評漂標苗秒病描猫品浜貧賓頻敏瓶不夫父付布扶府怖阜附訃負赴浮婦符富普腐敷膚賦譜侮武部舞封風伏服副幅復福腹複覆払沸仏物粉紛雰噴墳憤奮分文聞丙平兵併並柄陛閉塀幣弊蔽餅米壁璧癖別蔑片辺返変偏遍編弁便勉歩保哺捕補舗母募墓慕暮簿方包芳邦奉宝抱放法泡胞俸倣峰砲崩訪報蜂豊飽褒縫亡乏忙坊妨忘防房肪某冒剖紡望傍帽棒貿貌暴膨謀頰北木朴牧睦僕墨撲没勃堀本奔翻凡盆麻摩磨魔毎妹枚昧埋幕膜枕又末抹万満慢漫未味魅岬密蜜脈妙民眠矛務無夢霧娘名命明迷冥盟銘鳴滅免面綿麺茂模毛妄盲耗猛網目黙門紋問冶夜野弥厄役約訳薬躍闇由油喩愉諭輸癒唯友有勇幽悠郵湧猶裕遊雄誘憂融優与予余誉預幼用羊妖洋要容庸揚揺葉陽溶腰様瘍踊窯養擁謡曜抑沃浴欲翌翼拉裸羅来雷頼絡落酪辣乱卵覧濫藍欄吏利里理痢裏履璃離陸立律慄略柳流留竜粒隆硫侶旅虜慮了両良料涼猟陵量僚領寮療瞭糧力緑林厘倫輪隣臨瑠涙累塁類令礼冷励戻例鈴零霊隷齢麗暦歴列劣烈裂恋連廉練錬呂炉賂路露老労弄郎朗浪廊楼漏籠六録麓論和話賄脇惑枠湾腕

```

追記
・1361文字を超えるとProcess Fontボタン押下時にエラーになることを確認しました。
メソッドチェインできるrubyプログラムの書き方

元は[全部のファイルを結合するrubyプログラム](https://qiita.com/taroyanaka/items/5de919008edba37fa844)です

手元のエディタがおかしいのでインデントおかしくなってますが...

```ruby:method_chain_suite_all.rb
# coding: utf-8

class All
  def initialize
    @name = ""
		@files = []
		@new_files = []
		@all_txt = ""
  end

	def glob_by_extension(extension)
		@files = Dir.glob("**/*."+extension)
		self
	end

	def txt_add(file)
		File.read(file)
	end

	def make_all_txt
		@new_files.each do |file|
			@all_txt << self::txt_add(file)
		end
		self
	end

	def file_write
		File.write @name, @all_txt
	end

	def file_write_detail(name)
	  file = File.open(@name=name,"w")
	  file << @all_txt
	  file.close
		self
	end

	def delete_myself
		@files.delete(__FILE__) if @files.include?(__FILE__)
		@new_files = @files
		self
	end
end


All.new.glob_by_extension("txt").delete_myself.make_all_txt.file_write_detail("combining.txt")
All.new.glob_by_extension("rb").delete_myself.make_all_txt.file_write_detail("combining.rb")
```

参考
[rubyメソッドチェーンの作り方](http://mikamisan.hatenablog.com/entry/2016/04/18/235903)
LEDドットマトリクスパネル HUB75規格について調べてみた

追記(2019/10/20): 後日談ですが、当時結局この方法でC++のコードを書いたところ、うまく動きませんでした。おそらくどこかが間違っていると思われます。間違った情報をお伝えしてしまい、申し訳ありませんでした。


どうも、予定が一杯でリア充のかちおです（違

諸事情で秋葉原のピカリ館でHUB75型の32x32のLED Matrix Panelを購入し、いじろうと思ったのでメモ。調べても日本語情報全然出てこなかった。

どうやら通常はライブラリを使うらしいが、公式にはArduinoしか対応しておらず、なんとか汎用IOで操作したいため、データシートとにらめっこした。

公式のリファレンスとかデータシートとかサンプルコードを翻訳しながら書いていく。

## 画面構成

合計1024個のLED(とRGB)をすべて同時に光らせることは現実的ではないので、全16セクションに分けるとのこと。

32のLED、横に32列ある。
全部で32列。
1セクションは一番上の1列目と真ん中の17列目、2セクションは2と18列目…らしい。

> 余談ですが、32x16のパネルは1と9、2と10…って組み合わせらしい。まあそれが妥当。


| セクション | 列 |
|:-:|:-:|
|1|1と17|
|2|2と18|
|3|3と19|
|︙|︙|
|16|16と32|

1セクションは 32LED x 2列 で64LED。さらにRGBがあるので3を掛けて192。
なのでセクションごとにこの192bitを送ってあげればいいらしい。

人間の目からしたら残像だけど、実際には同時に1セクション(64LED)しか光らないらしい。
まあそうだよね。

## セクション(192個のLED)の光らせ方

まず接続端子にR1、G1、B1、R2、G2、B2、っていうピンがあると思う。もしかしたら1と2じゃなくて0と1の組み合わせかもしれない。ぼくの場合はそうだった。

ブルース展開でいうと{R,G,B}{1,2}か{R,G,B}{0,1}ですね。
とりあえず1と2で行きます。

これによって、同時に2つのLEDの状態を制御できます。RGB2つ分ですね。
で、セクションの上の列と下の列のLEDをそれぞれ同時に光らせることができます。

なので、一回のデータ送信で、セクションの上の列と下の列の一番左のLEDを光らせられるとのこと。これを32回繰り返します。

なので、たとえば1列目を白色に交互に点灯、17列目を赤青緑交互に光らせたい場合は以下のようになります。
ちなみに送信するごとにのクロックは、接続端子CLKから送るようです。これもSLCKとか色々呼び方があるようす。
あと、送信データは逆の値（負論理）、つまり光らせたかったらLOW、消したかったらHIGHらしいです。

|送信| 1 | 2 | 3 | 4 | 5 | 6 | 7 | … | 32 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| R1| 0 | 1 | 0 | 1 | 0 | 1 | 0 | … | 1 |
| G1| 0 | 1 | 0 | 1 | 0 | 1 | 0 | … | 1 |
| B1| 0 | 1 | 0 | 1 | 0 | 1 | 0 | … | 1 |
|上の色|白|消|白|消|白|消|白|…|消
|
| R2| 0 | 1 | 1 | 0 | 1 | 1 | 0 | … | 0 |
| G2| 1 | 0 | 1 | 1 | 0 | 1 | 1 | … | 1 |
| B2| 1 | 1 | 0 | 1 | 1 | 0 | 1 | … | 1 |
|下の色|赤|緑|青|赤|緑|青|赤|…|青


# セクションの選び方

これで同時に離れた2列を表示できるようになりました。次はセクションを選ぶ必要があります。
接続端子にABC(D)があると思うのですが、これがセクションを選ぶ4ビットになります。
2進数で、0000から1111です。これで1セクションから16セクションまでを選択するとのこと。

# 最終的なピンの操作順序

```bash

1. 全ピンをLOWにする。(最初だけ)


2. R1 G1 B1 R2 G2 B2をそれぞれ上に書いたようにLOWかHIGHにする。
3. CLKをHIGHにする。
4. CLKをLOWにする。これでLED2個分が書き込まれた。

5. これと同じように、2~4をあと31回繰り返す。これで1セクションのデータ分書き込み終わる。

6. ABCDの4bit使って送り込みたいセクションを決める。最初は0000とか。
7. OEをHIGHにする。画面表示有効のフラグらしい。
8. LAT(STB)をHIGHにする。これでLEDが光る。
9. LAT(STB)をLOWにする。
10. OEをLOWにする。

11. 以上、2~10をセクションを変えながら8回分繰り返す。これを高速で繰り返すことで画面を全部表示できる。ちなみに止めたらその瞬間消える（たぶん）

```

# 参考

https://hima-tubusi.blogspot.jp/2017/05/hub75_30.html
https://gist.github.com/CLCL/4509360739cccfca8f64
https://www.thingiverse.com/thing:1508087
https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf
PythonによるWebAPIからのデータ取得

#前置き
O'Reilly Japan の「PythonとJavaScriptではじめるデータビジュアライゼーション」を参考に、勉強をしています。

今回は、OECD（経済能力開発機構）の提供するデータセットを、OECDのWebAPIにより取得します。

#OECD APIについて
OECD API　は、HTTPメソッドGETにより取得操作を指定する RESTful APIだそうです。

##URLの例
```
http://stats.oecd.org/sdmx-json/data/QNA    # ONA(Quarterly National Accounts : 四半期国民経済計算)データセット
    /USA+JPN.GDP+B1_GE.CUR+VOBARSA.Q        # 位置、主題、スケール、頻度の4つの特製
    /all?startTime=2016-Q1&endTime=2017-Q1  # 期間
```
データセット名とドット区切りの特性でクエリを構築しています。
それぞれの特性は、+で区切って複数の値を指定することができます。
URLは標準的なHTTPパラメータの指定（?で始まり&で区切る）も可能です。

#requests で RESTful APIを使用した実装例
OECD（経済協力開発機構）の提供するデータセットを取得する関数

```py3:oecd_api.py
import requests

OECD_ROOT_URL = 'http://stats.oecd.org/sdmx-json/data'

#OECD API用のURLを作成してレスポンスを返す
def make_OECD_request(dsname, dimensions, params=None, root_dir=OECD_ROOT_URL):
    if params is None:
        params = {}

    dim_args = ['+'.join(d) for d in dimensions]
    dim_str = '.'.join(dim_args)

    url = root_dir + '/' + dsname + '/' + dim_str + '/all'
    print('Requesting URL: ' + url)
    return requests.get(url, params=params)
```

2016Q1 から 2017Q1 までの米国と日本の経済データを取得

```py3
>>> import oecd_api
>>>
>>> # データ取得
>>> response = oecd_api.make_OECD_request('QNA',(('USA', 'JPN'),('GDP', 'B1_GE'),('CUR', 'VOBARSA'), ('Q')),{'startTime':'2016-Q1', 'endTime':'2017-Q1'})
Requesting URL: http://stats.oecd.org/sdmx-json/data/QNA/USA+JPN.GDP+B1_GE.CUR+VOBARSA.Q/all

>>> # レスポンスのステータスコード
>>> response.status_code
200

>>> # エンコードされたURL
>>> response.url
'http://stats.oecd.org/sdmx-json/data/QNA/USA+JPN.GDP+B1_GE.CUR+VOBARSA.Q/all?startTime=2016-Q1&endTime=2017-Q1'

>>> # JSON形式で取得
>>> json_data = response.json()
```
##参考
OECDのWebAPIのドキュメントページ(API documentation (SDMX-JSON))
https://data.oecd.org/api/sdmx-json-documentation/

Requests クイックスタート
http://requests-docs-ja.readthedocs.io/en/latest/user/quickstart/#url
Pandasで数値の大きな順に列番号を取り出す


多クラス分類や多ラベル分類などで目的変数ごとに複数の確率値が出てきた場合、確率値の高い順に並べたいということはよくあるので、Pandasでのやり方を簡単に記載しておきます。

まず例として列ごとに各クラスの確率値が入ったDataFrameを作成します。ちなみにここで各クラス名を0,1,2にしているのは、このあと作成するインデックスの数字に合わせているためです。後ほど変換できるので、任意の名前で問題ありません。

```py
In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: pred = pd.DataFrame({"class0":[0.1,0.4,0.3], "class1":[0.5,0.2,0.4], "class2":[0.3,0.5,0.8]})

In [4]: pred
Out[4]: 
   class0  class1  class2
0     0.1     0.5     0.3
1     0.4     0.2     0.5
2     0.3     0.4     0.8
```

ここで`np.argsort`を使ってインデックスを貼ります。並び方が昇順になってしまうので`[::-1]`で降順になおしています。DataFrame自体のカラム名が変になりますが気にしない。

```py
In [5]: pred_rank = pred.apply(lambda x: np.argsort(x)[::-1], axis=1)

In [6]: pred_rank
Out[6]: 
   class2  class1  class0
0       1       2       0
1       2       0       1
2       2       1       0
```

例えば0行目は`pred`を見れば値を見ればclass1→class2→class0の順なので、きちんと左のカラムから順に大きなクラスの値が並んでいるのが分かると思います。あとは煮るなり焼くなり好きにします。

### 確率値の高い上位n位を取り出す

ここでは最も確率値の高いクラスを表示しています。複数の場合は`x[:1]`部分を任意のnに置き換えればOKです。

```py
In [7]: pred_rank.apply(lambda x: x[:1], axis=1)
Out[7]: 
   class2
0       1
1       2
2       2
```

### クラス名を付けて整形する
インデックスだけではよく分からないので、クラス名を付与して表示します。

```py
In [8]: pred_rank.apply(lambda x: " -> ".join(pred.columns[x]), axis=1)
Out[8]: 
0    class1 -> class2 -> class0
1    class2 -> class0 -> class1
2    class2 -> class1 -> class0
dtype: object

```

## 参考

- [numpy.argsort — NumPy v1.13 Manual](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html)
- [numpyで配列の要素とインデックスを降順に取り出す - Qiita](http://qiita.com/kaw/items/ba808bcc7b80bf7eb0df)
- [python - Is it possible to use argsort in descending order - Stack Overflow](https://stackoverflow.com/questions/16486252/is-it-possible-to-use-argsort-in-descending-order)
基本情報技術者試験の合格に向けて（当日の心得）

# はじめに
この世界には、「情報処理技術者試験」なるものが存在します。
情報系の国家試験です。合格すると立派な証書がもらえます。
詳細は公式HPをご覧ください。→ ( https://www.jitec.ipa.go.jp/ )

私は2017年4月に基本情報技術者試験 (以下、FE) を受験し、合格しました。
来る2017年10月には、応用情報技術者試験 (以下、AP) を受験する予定です。

そこで、試験合格のためにやるべきことを整理し、
この場に共有しておきたいと思います[^1]。
ほとんどの事項は、FE だけでなく AP にも適用できるはずです。

なお、本記事に書かれた内容のほとんどは私の主観です。
本記事の内容を実践する場合は、自己責任でよろしくお願いします。

試験対策の勉強は十分に実施したという前提で、
試験に向けて意識すべきだと思うことは以下の3つです。

>
1. 早寝早起き
2. 昼食は控えめに
3. 粘る

それぞれについて説明していきます。

# 1. 早寝早起き
FE受験者の朝は早い…
FE合格のために最も重要なことは、「早起き」であろう。
FEを「基本情報早起き試験」と呼ぶ人もいる[^2]くらいだ...

[2017/09/24: 追記]
「起床情報技術者試験」と呼ぶ方もいらっしゃいました。
[追記ここまで]

そこで、試験前の金曜日からリズムの調整をすることを提案します。
以下に例を挙げます。これは私の行動予定でもあります。

>**金曜**
・23時までには寝る
**土曜**
・6時までには起きる
・証明写真を受験票に貼る (忘れがち)
・昼寝をしない(←**重要**)
・翌日の朝食・昼食を準備しておく
・23時までには寝る
**日曜 (試験当日)**
・6時までには起きる
・朝食を摂る
・受験票、時計、筆記用具の確認
・8:30 までには会場に到着するように出発する

土曜にお昼寝をしてはいけません。
お昼寝をすることで夜に熟睡できなくなり、
翌日の朝がきつくなります。
そしてそのまま午後まで眠気を引っ張って、
試験当日のパフォーマンスは最悪になるでしょう。
**土曜のお昼寝は試験の敗北**を意味します。我慢です。

また、当日の朝に焦らなくていいように、
試験前日に当日の食事の準備をしておくと良いでしょう。

# 2. 昼食は控えめに
人間は、ごはんを食べると眠くなります。
しかし、ごはんを食べないと頭が働きません。
人間… なんと哀れで悲しい生き物なのでしょうか…

FEの午後試験の時間帯は、13:00〜15:30です。
早起きをして、午前の試験を受けて、お昼ごはんを食べて、
そこに追い打ちをかけるように、専門用語だらけの文章題が出題されます。
睡魔対策は、午後試験の肝になると言っても過言ではありません。

そこで、お昼ごはんです。
ごはんを食べると眠くなる原因は諸説ありますが、
>・満腹になると眠くなる
・炭水化物を摂りすぎると眠くなる

ということが広く言われています。一方で、

>・糖分が不足すると脳が働かなくなる

という話も耳にします。
以上のことから、
**「炭水化物(糖質)をかる〜く摂取する」**
くらいがちょうどいいと考えられます。
ちなみに、4月受験時の私の昼食は
「クリーム玄米ブラン、リポビタンD、飴玉」
のような感じだったと思います（うろ覚えですが…）。

必要な食事量に関しては個人差が大きいと思うので、
自分の体と相談しながら適切な量を摂取しましょう。

# 3. 粘る
精神論っぽいですが、実際に効果はあります。
特に、**午前試験は直前まで点数が伸び続けます。**
試験開始まで時間の許す限り、テキストや問題集を見直しましょう。
その中から2問くらいは出るかもしれません。

また、試験中も粘りましょう。
まったくわからない問題も、消去法で選択肢を絞りましょう。
すべてが4択から3択に変わるだけでも、点数の期待値はあがります。
あり得ない選択肢を消去して、正答確率を少しでもあげるべきです。

# その他のアドバイス 
## 午前
見直しを効率的に実施するために、
見直しが必要と感じた問題にはチェックをつけながら解きましょう。

特定の問題に時間をかけすぎないようにしましょう。
午前問題は、簡単だろうが難しかろうが、すべて1問1.25点です。
考えてもわからない問題は後回しにして、確実に取れる点を取りましょう。
ただ、計算問題は少し時間をかけてもよいかもしれません。

マークの記入欄にズレがないか、定期的に確認しましょう。
これはマーク式の試験全般で大切なことです。
10問おきに確認するなど、自分の中で基準を決めておくとよいでしょう。

時間が足りる人は、時間を気にしすぎず、いつもどおり解いてください
時間が足りない人は、時間配分に注意しましょう。
1問あたり1分30秒〜2分が目安です。
20問を30分で解くことができれば、80問を2時間で解くことができます。
そうすれば、残りの30分で見直しができます。
20問解くたびに時計を見るようにするといいかもしれません。

## 午後 
昼休みは徹底的に休むことをオススメします。
午後問題は、テキストを眺めても点数はあがりにくいです。
それよりも、試験中に眠くならないようにゆっくり休みましょう。

午後問題は、解く順番を変える工夫をすると良い場合があります。
先程も書きましたが、午後は食後&長文のために睡魔との戦いになります。
アルゴリズムとプログラミング (ともに必須) は、頭が働かないと解けません。
そこで、私の場合は以下のような順番で解きました。
>例 : アルゴリズム→プログラミング→セキュリティ→それ以外
・元気なうちに、得意分野を解いておきたい
・元気なうちに、頭を使う単元を消化しておきたい

あなたにあった順番で解くことをオススメします。

また、午後は午前よりも圧倒的に時間がシビアです。
時間配分を間違えると取り戻せないので、こまめに時間を確認しましょう。
以下は、午後の時間配分の一例です。2時間15分で完了する計算です。

| 問題番号 | 選択/必須 | 分野 | 時間 |
|:--------:|:-----:|:------------:|:------:|
| 1 | 必須         | セキュリティ   | 15分  |
| 2 ~ 7 | 4問選択 | いろいろ      | 各15分 |
| 8 | 必須 | アルゴリズム  | 30分   |
| 9 ~ 13 | 1問選択 | プログラミング | 30分  |

# まとめ
長くなりましたが、1文でまとめると
**「早起きして、お昼ごはん少なめにして、ギリギリまで粘りましょう。」**
ってことです。合格目指して頑張りましょう！

[^1]: 本記事は自分用のメモとする目的が強いです。
[^2]: 私を含めて、1人以上の存在を確認しています。
FizzBuzzクイズの実装例( ruby )


問題と実装例：https://qiita.com/sumim/items/f26902f2b813c075a619

私の実装：

```ruby
[[3, :fizz], [5,:buzz]].each do |base, name|
  Numeric.class_eval do
    define_method name do
      one = self % base==0
      if one
        r=name.to_s.capitalize
        eval(%Q!def r.val; #{self}; end!)
        r
      else
        self
      end
    end
  end
  String.class_eval do
    define_method name do
      self << name.to_s.capitalize if self.val % base==0
      self
    end
  end
end
```

解けてはいるものの、`eval` を使ったので負けっぽい。

この eval を避ける方法がわからなかった。

上記リンクの実装例を見て、なるほどと思うなど。

しかし、ruby 以外で実装できる言語は何があるだろう。python は有望かもしれないけど、python のマジカルな部分はよく知らないので私にはわからない。

で。
https://qiita.com/hadzimme/items/7f8d1c2458bcd2180d26
を拝見してなるほどと思い、 eval を使っていないバージョンを書いておく：

```ruby
[[3, :fizz], [5,:buzz]].each do |base, name|
  Numeric.class_eval do
    define_method name do
      if self % base==0
        name.to_s.capitalize.tap{ |x|
          this=self; # ここで this に受けるのがなんか悔しい
          x.define_singleton_method( :val ){ this }
        }
      else
        self
      end
    end
  end
  String.class_eval do
    define_method name do
      self.tap{ |this| this  << name.to_s.capitalize if self.val % base==0 }
    end
  end
end
```

要するに、私は define_singleton_method を見つけられなかったということ。
ぐぬぬ。
Golang と Line Notify を利用して API の証明書期限切れチェック #golang


API の死活監視と証明書の有効期限切れ（※）のチェックを golang を利用して行い、結果を Line Notify を使って通知します。
※ Let's Encrypt を利用してるけど 3ヶ月で有効期限切れになる

golang は会社で新しいプロダウトに利用する可能性があったので試しに使ってみることにしました。

# 前準備
* Golang の開発環境の構築（以下のサイト参考にした）
	* [Golang 本家サイト](https://golang.org/) 
	* [Intellij golang IDE](https://www.jetbrains.com/go/)
* Line Notify 準備
	* [コマンドラインから LINE にメッセージを送れる LINE Notify](https://engineering.linecorp.com/ja/blog/detail/88)

# 仕様
引数にチェック対象のエンドポイントの URI と Line Notify 用の Token を設定できるようにする

```sh
$ apichecker -endpoint=${エンドポイントURI} -token=${Line Notify 用 Token} 
```

# ソースコード
```sh
$ go version
go version go1.9 darwin/amd64
```

```go:apichecker.go
package main

import (
	"fmt"
	"net/http"
	"flag"
	"log"
	"net/url"
	"strings"
	"io/ioutil"
)

func main() {
	var endpoint = flag.String("endpoint", "", "check target Endpoint URL")
	var lineToken = flag.String("token", "", "LINE notify token")
	flag.Parse()

	var apiResult = getAPI(*endpoint)
	var result = postLINE(*lineToken, apiResult)

	fmt.Printf("LINE Post result [%t]\n", result)
}

func getAPI(endpoint string) string {
	if endpoint == "" {
		log.Fatal("not endpoint")
		return "not endpoint"
	}

	var result = ""
	resp, err := http.Get(endpoint)
	if err != nil {
		result = fmt.Sprintf("NG [%s]", err)
	} else {
		defer resp.Body.Close()
		result = fmt.Sprintf("OK [%s]", endpoint)
	}

	return result
}

func postLINE(token string, message string) bool {
	if token == "" {
		log.Fatal("not token")
		return false
	} else if message == "" {
		log.Fatal("not text")
		return false
	}

	data := url.Values{"message": {message}}
	r, _ := http.NewRequest("POST", "https://notify-api.line.me/api/notify", strings.NewReader(data.Encode()))
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	resp, err := http.DefaultClient.Do(r)
	if err != nil {
		log.Fatal(err)
		return false
	}
	defer resp.Body.Close()
	_, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
		return false
	}

	return true
}
```
※ [LINE NotifyをGoで送る](https://qiita.com/koki_cheese/items/6d577c644598c3c916df) を参考にしました。

# 実行結果

## OK の場合
```sh
$ go run apichecker.go -endpoint=https://www.yahoo.co.jp -token=${Line Notify 用 Token}
LINE Post result [true]
```
![スクリーンショット 2017-09-24 16.59.54.png](https://qiita-image-store.s3.amazonaws.com/0/203864/246c4cd1-3e27-d2a1-c426-6cbc4dbdfede.png "スクリーンショット 2017-09-24 16.59.54.png")

## NG の場合（証明書エラー）
```sh
$ go run apichecker.go -endpoint=https://www.yahoo.jp -token=${Line Notify 用 Token}
LINE Post result [true]
```
![スクリーンショット 2017-09-24 17.00.04.png](https://qiita-image-store.s3.amazonaws.com/0/203864/4f2c8a1d-4c88-5df8-3445-b806780ed041.png "スクリーンショット 2017-09-24 17.00.04.png")

# Appendix
* [ソースコード](https://github.com/ynozue/apichecker/tree/basic)
Node.jsとExpressとMySQLの簡単サンプル

# はじめに

今までnodeと言えば、npmでフロントで使うもろもろをinstallするためのJS実行環境くらいのイメージでしたが、webサーバーも作れるということなので作ってみました。



## スペック

- フロントエンドエンジニア
- node,npmはフロントエンド関連での利用あり
- インフラやサーバーの知識は少々
- MySQLの知識も少々

# Node.jsのみ

nodeが動く環境なら確認ができる。

## ソースコード

[置き場](https://github.com/tiwuofficial/node-sample/tree/master/raw-node)

index.js

```js
var http = require('http');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(1234);
```

## 結果

`node index.js`で実行し、localhost:1234にアクセス。

やってることは文字列を返しているだけですが、これだけでwebサーバーとして動くのにかなりびっくりです。

<img width="225" alt="スクリーンショット 2017-09-24 16.19.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/81308/d39e698e-e73e-9efa-4df4-49f53e43ffd9.png">


# Express

node.jsでwebサーバーを作ることが確認できました。

つまり、webサーバーを簡単に作るフレームワークがたくさんあるということです。

Expressはそんなフレームワークの1つです。

[公式サイト](http://expressjs.com/ja/)

## インストール

`npm install express --save`

## ソースコード

[置き場](https://github.com/tiwuofficial/node-sample/tree/master/simple-express)

index.js

```js
var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

```

## 結果

`node index.js`で実行し、localhost:3000にアクセス。

これも文字列を返してるだけですが、簡単に作れました。

さすがフレームワーク。知らなくても、なんとなくソースコードが読める。

<img width="222" alt="スクリーンショット 2017-09-24 16.24.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/81308/cbfd5f66-13e9-1622-0ce2-42ef7fb1d66c.png">


# MySQL

webサーバーということはDBからデータを取って表示したいですよね？

そう、node.jsならそれができます。

npm経由でmysqlをinstallすればJSからMySQLの操作ができます。

※個人的にはJSでMySQLを操作なんて驚き

## インストール

`npm install mysql --save`

## データの作成

全てmysqlログイン後

`create database NodeTest;`

`use NodeTest;`

`create table test_table(id int(11),name varchar(255));`

`insert into test_table values(1,'testname');`

## ソースコード

[置き場](https://github.com/tiwuofficial/node-sample/tree/master/mysql-express)

index.js

```js
var express = require('express');
var app = express();

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : 'root',
  database : 'NodeTest'
});

app.get('/', function (req, res) {
  connection.query('select * from test_table', function (error, results, fields) {
    if (error) throw error;
    res.send(results[0]);
  });
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

```

## 結果

`node index.js`で実行し、localhost:3000にアクセス。

無事MySQLからデータを取得し表示できました。

<img width="221" alt="スクリーンショット 2017-09-24 16.15.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/81308/44da4f7f-885a-1f59-c8ac-d8e2dfe65462.png">

# 所感

簡単にwebサーバーが作れて、しかもMySQLから簡単にデータを取得できてました。

簡単な個人用のサービスとかならこれで作れる幅が一気に増えそう。

今回はただの文字列を返しましたが、次回はHTMLを返すようにしてみます。
material-auto-rotating-carousel でbuild error


```
ERROR in ../~/material-auto-rotating-carousel/lib/index.js
Module build failed: TypeError: Plugin 0 specified in "..\node_modules\material-auto-rotating-carousel\.babelrc" was expected to return a function but returned "undefined"
    at Function.normalisePlugin (..\node_modules\babel-core\lib\transformation\file\options\option-manager.js:148:15)
    at ..\node_modules\babel-core\lib\transformation\file\options\option-manager.js:184:30
```

というエラーが出てしまい、これも解決方法が分からないので
とりあえず、対象ファイルを無効にして逃げました

```
material-auto-rotating-carousel/.babelrc
↓
material-auto-rotating-carousel/.babelrc.old
```

.babelrc で必要な設定自体は、webpack側で指定していたので
とりあえず、削除で良いかなーとおもってやったら動いた。
8bitバイナリを7bitバイナリ列にする

#MIDIメッセージのデータ
MIDIの通信で使われるMIDIメッセージは1バイトづつシリアルで送られます。この中で命令を指すステータの部分はbit7 がHi ,データ部分はbit7がLo と決められています。bit7=Hiのバイトのデータはそのままでは通信に使えません。

##システムエクスクルーシブ
MIDIのメッセージに任意のデータ列を送るためのシステムエクスクルーシブメッセージがあります。他のメッセージと同じく F0h で始まり F7h で終わる一連のバイト列ですが、その間のデータ部分も必ずbit7=Loでないといけません。送りたいデータ列が普通のバイナリデータでもbit7をLoにした変換処置をして送出／受取しないといけないわけです。

##8bit->7bit , 7bit->8bit

今回YMF825boardを使ったシンセサイザモジュールを作るにあたり、音色データをシステムエクスクルーシブメッセージで送る様な機能がどうしても必要になると考えました。
このため8bitデータ列を7bitデータ列に変換／戻す処理が必要になるわけです。この手の処理コードは以前は雑誌の記事か、どこかのサイトに転がっていたと記憶するのですが、最近は用途もない様で検索しても見つかりませんでした。そこで改めてコードを書いてみました。何か役に立てれてばとお思います。無保証ですが自由にお使い下さって結構です。

### int encode87(unsigned char* src,unsigned char* dst,int n)

8bitデータ列 7バイト分を7bitデータ列8バイトへ変換します

src : 変換元ポインタ
dat : 変換先ポインタ
  n : 変換データバイト数

### int decode87(unsigned char* src,unsigned char* dst,int n)

7bitデータ列 8バイト分を8bitデータ列7バイトへ変換します

src : 変換元ポインタ
dat : 変換先ポインタ
  n : 変換データバイト数

やっている事は 7バイトのデータ列の各々8bitめを8バイト目の各bit0-bit6へ格納して一連のデータ列に変換しています。デコード時はその反対の処理を行います。
これで任意のバイナリーデータをMIDIシステムエクスクルーシブメッセージの中に入れ込む事ができます。


```byt78.c

/*

	8bit Binary String  <->  7bit Binary String

	Ringoro

*/

#include <stdio.h>

unsigned char indata[]={0x85,0x85,0x85,0x81,0x85,0x82,0x88,
			0x71,203,135,230,122,232,0x80,
			0x71,203,135,230,122,232,0x00,
			0x81,110,120,230,100,100,0xFE,
			0x81,0x92,0x12};

unsigned char outdata[sizeof(indata) * 8 / 7 + 1];
unsigned char decoded[sizeof(indata)];

int encode87(unsigned char* ,unsigned char* ,int );
int decode87(unsigned char* ,unsigned char* ,int );

int main()
{
	int max,c,i,j,n,pt;
	unsigned char b8;
	
	max=sizeof(indata);		// max input data count
	pt = 0;					// data out point
	
	n = encode87(indata,outdata,max);
	
	
	puts("");
	for(i=0;i<max;i++){
		printf("%02X",indata[i]);
		if( (i % 7)== 6)
			{printf("  ");}
	}
	puts("");
	for(i=0;i<=n;i++){
		printf("%02X",outdata[i]);
		}
	
	n = decode87(outdata,decoded,n);

	puts("");
	for(i=0;i<n;i++){
		printf("%02X",decoded[i]);
		if( (i % 7 ) == 6 )
			{printf("  ");}
		}
	puts("");
	
	
}

/*
	encode 8bit x 7  to 7bit x 8
	src : input data ponter.
	dst : output data pointer.
	max : input data bytes.
	return : encoded data bytes.
*/
int encode87(unsigned char *src,unsigned char *dst,int max)
{
	int n,i,pt;
	unsigned char b8;
	pt = 0;
	n=0;
	while(n < max){
		b8=0;
		for(i=0; i<7 && n < max;i++,n++){
			*(dst+pt)=*(src+n) & 0x7F;
			// printf("%02X ",*(src+n));
			pt++;
			b8= b8 | ((*(src+n) & 0x80) >> 7) << i;
			// printf("%02X ",b8);
			}
		*(dst+pt++)=b8;
		//printf("%d ",pt);
	}

	return pt-1;
	
}

/*
	decode 7bit x 8 to 8bit x 7
	src : input data ponter.
	dst : output data pointer.
	max : input data bytes.
	return : encoded data bytes.
*/
int decode87(unsigned char *src,unsigned char *dst,int max)
{
	int n,i,j,pt;
	unsigned char b8;
	pt = 0;
	n=0;
	while(n < max){
		for(i=0; i< 7 && n < max;i++,n++){
			*(dst+pt)=*(src+n);
			pt++;
			}
		b8=*(src + n++);
		// printf("n:%d  B8:%02X \n",n,b8 );
		for(j=0;j<i;j++){
			*(dst+pt-i+j) = (*(dst+pt-i+j)) | ((b8 >> j) << 7);
			}
	}

	return pt;
	
}

```
Google Chromeで.devなどの開発DomainがHTTPSに変更される。 

#変更Log
```
#2017/12/11 現在 63.0.3239.84（Official Build）安定版（64 ビット）
追記＋背景等を追加

#2017/10/08 現在 63.0.3235.0（Official Build）canary
.appドメインがhttpsに強制Redirectされるようになりました。
```
#追記
Chrome 安定版がv63になったため情報共有。
.app .devでHTTPSを強制されることを確認

##新たな解決法
下記推奨ドメインに変更
ChromeからFirefox等の他のブラウザに変更

>変更が推奨されているドメイン
.test
.example
.invalid
.localhost

##背景
以前は.comから始まりドメインが少なかったわけですが、今ではいろんなドメインが使われるようになりました。
その中で.devや.appがgTLDとしてGoogleが購入をしたみたいでその影響をうけていると下記のリンクで紹介されています。
うん。率直にやめてほしいね。笑

>参照リンク
https://iyware.com/dont-use-dev-for-development/
https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/
https://laravel-news.com/chrome-63-now-forces-dev-domains-https


#はじまり
突然Chrome Canaryで.devドメインがHTTPSにリダイレクトされだしたのでシェアします。
Chrome Canary 63.0.3222.0
Twitterで飛んできた情報で恐縮です。

#結論
Chrome to force .dev domains to HTTPS via preloaded HSTS
https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/

##解決法
方法は3つぐらいある？

1. Laravel Valetのようなプロキシ動作するシステムの導入する。
2. 自己署名証明書でHTTPSに対応する。
3. .dev .app => .testなどのドメインに変更する。

まぁ3番が無難なのかもしれないけど、なんでこんなめんどっちいことするんよｗって愚痴でした。
ローカル開発環境ぐらいHTTPでいいやんかΣヽ(｀д´；)ﾉ うおおおお！って話でした。

あ。もっといい方法あるよってある方はコメントいただけたら嬉しいです。

Chrome Stable channelでなったら本格的に何かしないといけないc(`Д´と⌒ｃ)つ彡 ﾔﾀﾞﾔﾀﾞ

#あとがき
もしよかったら私のブログでも同じようなこと書いてるので来てくれたらうれしいです。
https://lara-bell.com
Module build failed: TypeError: fileSystem.statSync is not a function

```
ERROR in ../~/react/react.js
Module build failed: TypeError: fileSystem.statSync is not a function
    at module.exports (..\node_modules\babel-loader\lib\utils\exists.js:7:25)
    at find (..\node_modules\babel-loader\lib\resolve-rc.js:13:9)
    at Object.module.exports (..\node_modules\babel-loader\lib\index.js:113:132)
 @ multi vendor
```

というエラーが消せない
http://otiai10.hatenablog.com/entry/2016/04/17/211145
https://stackoverflow.com/questions/32832179/using-webpack-with-nodejs-native-modules

こちらの記事を読むと、解消したみたいだけどおいらは全然ダメｗｗ

https://github.com/babel/babel-loader/issues/505
元々は、こっちの記事だったと思っているので、なぜか消えない

で、勝手にコードを書き換えて逃げているｗｗ

```**javascript:babel-loader/lib/index.js:113**
  // Handle options
  var loaderOptions = loaderUtils.getOptions(this) || {};
  var fileSystem = this.fs ? this.fs : fs;
  fileSystem = fs;  ＜－－　これ入れて逃げた
  var babelrcPath = null;
  if (loaderOptions.babelrc !== false) {
```

-- 2019/03/26 追記 --
バグの理由を見つけたんだけど...あれ？忘れちゃったなー
client or server(nodejs)どちらか利用できないケースで利用しているのが理由だったような気がする
外部プログラムからSQLServerに接続するための設定

SQLServerに外部プログラムからJDBC等で接続するためには、SQLServerへのTCP/IP接続を
有効にする必要があります。

# 環境
OS : Windows10 pro 64bit
SQLServer : SQLServer2016 Express Edition


# 手順

画面左下のWindowsロゴを右クリック
↓
"コンピュータの管理"を選択
↓
左のメニューツリーから"サービスとアプリケーション"を選択
↓
"SQLServer構成マネージャ"を選択
↓
"MSSQLSERVERのプロトコル"を選択
↓
"TCP/IP"を右クリックして、有効にする。
↓
コンピュータを再起動する

完了
LinkStation に載せた debianが再起動しなくなったのでそのときにやったことをメモ

# 3行で書くと...
* rebootしたらsshも繋がらず、共有ディレクトリにもアクセスできない。
* RAID1の二台のHDDを外し、別PCで確認し、xfs_repairでxfsを修復。
* 元に戻したら動いた。

# 環境
LS-WVLのHDDが一台壊れたのでどうしようと考えていたところ、下記を見つけたので、新たにWD RED(3TB)を購入して debian をインストールした(作成者様に感謝...m(_ _)m)。
http://tokyodebian.alioth.debian.org/pdf/debianmeetingresume201605-presentation-roger.pdf

# 発生したこと
apt-get でupdateした後再起動したらsshでログインできなくなった。

# 確認したこと
* ping は有効。
* ssh では入れない。
* ネットワーク上のMacから、共有フォルダを認識できない。
* nmapで確認したらポートは開いていない。

# やったこと
* RAIDはそのまま。一台をSATA/USB I/Fを用いて、別PC (ArchLinux) で動かすが、パーティションを認識しない(sdbはみつかるがsdb?は見つからない)。別のHDDでも同じなので、SATA/USB I/Fが壊れたと判断。
* そういえば2台のHDDを同時に繋げられる下記を購入していたので、2台抜いて試す。
http://www.kuroutoshikou.com/product/case/original/kuro-dachi_clone_u3/
* Debian化で作成したパーティション md124, md125, md126, md127があることを確認。
* sambaのディレクトリがあるxfsのパーティション(md124)のみmountできないことを確認。写真やビデオが入っているのでかなり焦る。
* xfs_repair を行う。mountしてないのでmountしろという旨のメッセージを確認。だからmountできないんだってば。さらにmountできなければ-Lでxfs_repairしろとの指摘を確認。
* xfs_repair -L を行う。xfsが修復され、中のファイルも無事確認。
* /var/logを確認するが、おかしなログはなかった、というよりその周りの時間のログがない。
* 不安になりつつもHDDをLinkStationに戻し再起動。
* sshで入れることを確認。
* PDFを確認していたところ、インストール時にnetconsoleの指定をしていなかったので、次回再発時に起動時のログをnetconsoleで出力できるようにしておく。

# 不明点
* debianはmd124 (boot), md125 (root(/var/logもここ)), md126 (swap)に入っているはずなのに、md127のみの問題?でsshには入れなかったのがなぜかわからない。
* xfsを写真とかビデオとかの重要データの保存に使っていていいんだろうか...。
* LinkStationを使い続けていて大丈夫なんだろうか...(でも先立つものがないためもうしばらくは使いたい)。

# おまけ
* rebootコマンドが電源OFFになっていて少し焦った。あれ?前からだっけかな?。次回気をつけよう。
GIS関連ファイルのバックアップ用圧縮形式はどれが良いのか？

#はじめに
GIS関連(特にDEMファイル)によってHDDが逼迫してきたので、効率良いバックアップ方法を模索することに。
Webに比較記事は山ほどあれど、圧縮する対象によって圧縮率はそれなりに変わるのでやはり自分のニーズでのパフォーマンスを知りたい。
また最近台頭してきている速度を優先した圧縮形式(lz4, lzopなど)の実力も興味があって、比較してみることにした。

そこで今回は以下の[LiDARのDEMデータ](http://opentopo.sdsc.edu/datasetMetadata?otCollectionID=OT.032017.26911.1)をメインとしつつ、ちょっぴりその他のデータも入っているフォルダで実験してみた。
<img width="645" alt="fig1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/172235/fc3aebad-f1dc-bd81-c43d-b395523a1326.jpeg">

## 計測
- Windows 10 64bit / Core-i7 6700HQ / 16GB DDR4
- USB3.0 UARTで繋いだ外付SSD → SATA3.0で繋いだ内蔵2.5" HDD
- すべての圧縮方法で最も速度を優先するオプションを使用した。
- lz4(r128), lzop(1.03), 7zip/zip(17.01b), pigz(2.31), pbzip2(1.19), pixz(1.06), gzip(1.6), bzip2(1.06), xz(5.1.0)

7zipとzip以外は、Bash on Windowsからtimeを使って以下のコマンドラインの総所要時間を計測
**cp** -R ./US_Inyo /mnt/d
tar cvf - ./US_Inyo | **lz4** - /mnt/d/US_Inyo.tar.lz4
tar cvf - ./US_Inyo | **lzop -1** -o /mnt/d/US_Inyo.tar.lzo
tar cvf - ./US_Inyo | **pigz -1** > /mnt/d/US_Inyo.tar2.gz
tar cvf - ./US_Inyo | **pbzip2 -1** > /mnt/d/US_Inyo.tar2.bz2
tar cvf - ./US_Inyo | **gzip -1** > /mnt/d/US_Inyo.tar.gz
tar cvf - ./US_Inyo | **bzip2 -1** > /mnt/d/US_Inyo.tar.bz2
tar cvf - ./US_Inyo | **xz -1** > /mnt/d/US_Inyo.tar.xz

## 結論
クアッドコアの高速なCPUを使える場合はpigz(マルチスレッド化されたgzip)が非常に優れており、しかしCPU性能の低いPCで使う場合や、バックアップを行いながら他の作業もしたい場合はlz4/lzopが検討に値する、といった感じ。
<img width="509" alt="fig2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/172235/e5fe211d-fc3b-efb6-9882-dae260f146c0.jpeg">

### pigz (https://zlib.net/pigz/)
- 超古参のgzipがこれほど速いとは思わなかった(正直な感想)
- それがマルチスレッド化されてクアッドコアCPUで走るとlz4/lzopに猛烈に迫る値に
- 一般的なHDDのシーケンシャルライト性能に近い速度(100MB/s)を達成しているのも、バランスが取れていて無駄がなくポイントが高い。
- 圧縮レベルを上げても時間が伸びるだけで圧縮率は殆ど減らなかった

### [lz4](https://lz4.github.io/lz4/) と [lzop](https://www.lzop.org/)
- 軽すぎてディスク側がボトルネックに(下のベンチマーク参照)。
- 圧縮率はイマイチで、70%近いのはちょっと残念。圧縮レベルを上げても殆ど改善しなかった。データ構造が向いていないのかもしれない。
- 性能の低いCPU(Core-m3など)で使う場合や、バックアップしながら同時に重い作業もしたい場合などには有効か。
- 今回は検証しなかったが、解凍速度的にlzopよりlz4にアドバンテージがあるらしい。
<img width="602" alt="fig2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/172235/6adc8f23-5a9a-2a27-05f5-794b5846c5b6.jpeg">

### zstd (http://facebook.github.io/zstd/)
- 新鋭の圧縮規格らしい。pigzを上回るスループットを誇る。今後の普及に期待。
- 対応した[7zipの派生版](https://github.com/mcmilk/7-Zip-zstd/releases)もある。

### 7zip (http://www.7-zip.org/)
- 今まで使っていたやつ。比較した中では最も高い圧縮率を達成し、マルチスレッド化されていて所要時間も悪くはない。
- しかしpigzが速すぎて霞んでしまう。
- WindowsでGUIが必要な場合はこれを使っておけば悪くはないか。

## 参考にさせてもらったページ
- [2016年のOSS圧縮ツール選択カタログ - Qiita](https://qiita.com/nishemon/items/818cc64dc2f8577edd87)
- [Quick Benchmark: Gzip vs Bzip2 vs LZMA vs XZ vs LZ4 vs LZO - CatchChallenger wiki](https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO)
Qiita APIのGET /api/v1/users/:user_id/items を GET /api/v2/itemsに移行する

# はじめに

不特定多数のQiitaユーザの記事取得に`GET /api/v1/users/:user_id/items`を使っていたが、2017年9月中にv1が廃止になるとのことでv2でそれっぽいのを探したところ、`GET /api/v2/items`が使えることがわかった。追記: /api/v2/users/:user_id/items が必要十分だった。

## なぜそもそもv1を使っていた？

`GET /api/v2/authenticated_user/items` が既にあったが、これは使えねーなと思ってv1を使っていたが、v1が廃止となってよくよく調べると`GET /api/v2/items`が使えそうだった。


- ❌ `GET /api/v2/authenticated_user/items`
    - トークンが必要っぽいので認可済みユーザの記事でないと無理なのでこれは使わない
- ⭕ `GET /api/v2/items`
    - パラメータなしだと全ユーザ対象だがパラメータ query でユーザ名を指定すればいけそう
    - 例: `"query":"qiita user:yimajo"`
- ⭕ `GET /api/v2/users/:user_id/items`
    - トークンが必要なくユーザの記事が取得できる


## 試す

## access_tokenを利用した際に限定共有を取得しないで済むか

`GET /api/v2/items`で利用制限をゆるくしたいためaccess_tokenを使いたいが限定共有記事を取得したくないのでcURLで試した（`GET /api/v1/users/#{qiita_id}/items`では限定共有記事を取得していた）

```
curl -X GET https://qiita.com/api/v2/items -d '{"per_page":"10", "query":"qiita user:yimajo"}' -H "Content-Type: application/json" -H ‘Authorization: Bearer ここがトークン‘
```

- 想定してた自分の記事が取得できた

# その他注意事項

APIの利用制限が変わっている

- v1
    - https://qiita.com/api/v1/docs#%E8%AA%8D%E8%A8%BC
- v2
    - https://qiita.com/api/v2/docs#%E5%88%A9%E7%94%A8%E5%88%B6%E9%99%90

v2ではaccess_tokenが無い/無効な場合に同一IPアドレスから1時間に60回までしかリクエストできない。つまり一回のリクエストで60sec待たなければいけなくなる。

そのため、最初は2secだけ余裕をもたせた62secだけsleepしてリクエストしていたがそれでも403 Rate Limitになってしまった。さらに余裕を持たせて70secに変更して運用することにした。
require()/importの副作用

JavaScriptでもモジュール化したプログラミングが定着してきましたが、モジュールの読み込みの際には副作用が発生することに気をつけないといけません。

# 副作用とは

「副作用」といっても、医薬品の場合は何がメインの作用で何が副作用かは相対的なものですが（風邪薬の「眠くなる」副作用をメインとした睡眠改善薬のように、状況によって何を主たる作用と考えるかは変わります）、プログラミング用語としては、「副作用」の意味は一定しています。

> ある処理が、引数と返り値以外に及ぼす影響

具体的には、以下の様なものがあります。

* 処理の実行を越えて残る変数への代入、破壊的変更
* 入出力、通信など、プログラム外部とのやり取り

例えば、「`alert()`でメッセージを表示させる」ようなことも、通常それを目的に行いますが、これも分類は副作用です。

# `require()`の動作と、副作用

Webpackなどでコンパイルするとわかりやすいですが、個々のファイル（モジュール）は、`require`や`module`などを引数として渡される関数、という形に変換されます。そして、`require()`を呼んだ場合には、以下のような処理が走ります。

0. モジュールリストから、当該のモジュールが用意されているかをチェックする。
1. **用意されていない場合**、モジュール定義をラップした関数を呼び出して、`module.exports`などの値を取得する
2. エクスポートされた値を返す

ということで、以下のようなことがわかります。

* モジュールに書いた、`exports`以外のコードが実行されるのは最大1回（次からはキャッシュされる）
* モジュールごとの実行順は**呼んだ順**

# どんなコードを書く？

もちろん、`module.exports = `以下の一文で済ませてしまう場合であれば副作用が発生する余地もありませんし、逆に「`require`しただけで`alert()`を吐く」ようなモジュールも、実用的ではないでしょう。ただ、現実には副作用として何か実行することも十分ありえます。

* 他のモジュールの`require`
* イベントの設定
* グローバルや他のモジュールによる変数の、破壊的な変更
 * コンポーネント系フレームワークの、コンポーネントの登録
 * jQueryプラグインの設定[^1]

[^1]: もっとも、セットしたプラグインが`require()`の結果にならないことを考えると、相性の悪さは否めません。

# 副作用をしっかり考えないといけない場合

これらの副作用の中で、比較的影響しうるのが、「イベント設定」です。状況によっては、イベント設定に際して「順番」を考えないといけない場面があります。

たとえば、`path/too/foo/first`を`path/too/foo/second`より先にセットしないとうまく動かない、となったとします。そんな場合には、「とりあえず`require`して読み捨て」で乗り切ることができます。

```path/too/foo/second.js
// firstの副作用が先に動くことを保証する
require('./first');

document.addEventListenr(....);
```

# `import`/`export`

`import`や`export`は何かしらの宣言文のようにも見えますが、「JavaScriptを実行して特定の値を取得する」という基本は、`require`/`exports`の組と同じです。ということで、副作用についても同様に考えないといけません。
VCRで複数のカセットを使う方法について悩んだのでPR出してみた話

# VCRってなんぞ？
github.com/vcrには

```ruby
# Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.
```
要約すると
テスト実行時にHTTPリクエストを送らないといけないとき最初の一回は本当にリクエストを飛ばすんだけどその時の通信内容を記録して２回目以降はHTTP通信をしないでテストができるようにするためのライブラリ。通信しないから早いし通信環境に左右されないテストができるよ。

今回はRailsでVCR使って思ったことや調べたことをまとめます。

想定読者
初めてVCR使うよ
複数のカセットを使う方法を探してるよ

## VCRの使い方
基本的な使い方は本家githubに書いてあるんだけど

```ruby

require 'rubygems'
require 'test/unit'
require 'vcr'

# 最初の設定する。
# 通信履歴の保存場所(VCRではカセットという。ややこしい(・ω・))
VCR.configure do |config|
  config.cassette_library_dir = "fixtures/vcr_cassettes"
  config.hook_into :webmock
end
# 初期設定はここまで

class VCRTest < Test::Unit::TestCase
  def test_example_dot_com
    VCR.use_cassette("synopsis") do
      response = Net::HTTP.get_response(URI('http://www.iana.org/domains/reserved'))
      assert_match /Example domains/, response.body
    end
  end
end
```

詳細

```ruby
# 基本的には下記のコードで良い
VCR.use_cassette('好きなカセット名') do
  #　-------------------------------------
  # この中にHTTP通信するコードを挟む
  # 複数のURLにHTTP通信する場合でも深く考えなければ一つのカセットに保存してくれる
  # もし複数の別々のカセットを扱いたい場合は後述
  #　-------------------------------------
end
```

## .use_cassetteメソッドには引数が３つある
`.use_cassette(name, options = {}, &block)`

nameはカセット名

optionsにはカセット実行時に使うoptionをハッシュで入れられるようになっている

- erb: {カセットにerb形式で何かを埋め込める。URLパラメータとか}
- record: {新しいHTTPリクエストを飛ばすときに使う} 
- match_requests_on {アクセスするURLパラメータが予想できない場合は正規表現などを使って処理をかける} 

&blockは実際の処理を書く

## 複数のカセットを使う
結論: 入れ子にして使えば良いとなる。
確証はないんだけどRailsかRubyかVCRのバージョンによっては入れ子の順番が正しくないとVCRが正しく機能しない可能性があるようで会社のMacではカセットの順番を入れ替えると正しく機能しないが自宅のMacではうまく動いたりした。＊知ってる方がおられたらぜひコメントください！

この入れ子の順番に関しては(この文は正しくないかもしれないです(・ω・))
処理する順番が中央に来る順序で記述すること
つまり

```ruby
def some_method
  http_request(1)
  http_request(2)
  http_request(3)
end

VCR.use_cassette('request_3') do
  VCR.use_cassette('request_2') do
    VCR.use_cassette('request_1') do
      some_method(
    end
  end
end
```
自分の会社の環境だとこれで動いていた。
ただこれについてはVCRのリファレンスでもその方法について見つけられなかったのでなんとも確証がないなぁ
https://github.com/vcr/vcr/issues/306
一応コードを分割した通信に関しては上のリンクの方法が使えるようだけど一つのメソッドで来るんであるHTTP通信とはちょっと違うし

## ネスト深くしたくない。メソッドを追加しよう！
Rubyはネストしてもそこまで読みにくいとは思わないけどネストはしたくない。
そこでVCRのコードをフォークしてなんとかネストしないで複数のカセットを使う方法を考えた。
そしてVCR.use_cassettesというメソッドをVCRに追加してみた
コード自体は大したことはしてないんだけども

```ruby

# use_cassette 's' がつくので複数形！
# namesはカセットの配列。処理の順番に頭から書いていけばよいです。
def use_cassettes(names, &block)
  return use_cassette(names.last) { block.call } if names.length == 1
  cassette = names.pop
  use_cassette(cassette) do
    use_cassettes(names, &block)
  end
end
```

まずnamesはカセットの配列を渡す
今回だと['request_1', 'request_2', 'request_3']
で&blockは今まで通り処理するメソッド。
メソッド内ではuse_cassetteメソッドを呼び出していてそれをカセットがなくなるまで再帰呼び出しする。
カセットが最後の１枚になったら&block引数に.callを付けて実際の処理を呼び出してreturn
これでネストせずに複数のカセットを利用したテストを書くことができる！

## 人生二回目のOSSへのPR
コードの出来に関してはあれだけど勉強の意味も込めてGemに含めてテスト追加して本家様にPR出してみた。
今のところなんのコメントもないんだけどなんか返信あったらいいなって思ってるです(*´ω｀*)

## 11/17追記
マージしてもらったので最新のVCRでこの機能使うことができます！
使い所は少ないですが一つのサービスクラスのメソッドで複数箇所に通信を行う場合は使ってみてください／(^o^)＼
Arduino-ESP32 I2C <LCD ST7032>

WROOM-32のArduino開発環境でI2Cを行う方法を確認します。
理解が必要な事項は以下です。

 - I2Cのデフォルトピンの確認
 - Wireライブラリ

# I2Cのデフォルトピンの確認

esp 32 のI2C ピンアサインは以下にあります。
https://github.com/espressif/arduino-esp32/blob/master/variants/nano32/pins_arduino.h

以下の表記があります。
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;

ここはWROOM-32のピンが各社のモジュール上でどこにアサインされているかで変わるのでモジュールの回路図などを参考にしてください。
ちなみに秋月のDev-Moduleであれば[ここ](http://akizukidenshi.com/download/ds/espressifsystems/ESP32-Core-Board-V2_sch.pdf)、Esprモジュールの場合は[ここ](https://s3-ap-northeast-1.amazonaws.com/switch-science.public/schematic/ESPr_Developer_32/ESPr_Developer_32.pdf
)
どちらも普通にIO21,22に表示されているので、特に問題はないです。

# Wireライブラリ
I2Cを使用するにはWireライブラリを使用します。
公式のリファレンスを参照しましょう。
https://www.arduino.cc/en/Reference/Wire

・使用するピンの設定はWire.beginでピン番号を指定します。
Wire.begin(21,22);　//Wire.begin(SDA, SCL)

・I2Cの動作周波数の指定はsetClock()でできます。設定できる値はスタンダード100kbit/s、ファスト400kbit/sがあるようです。デフォルト値はfrequency=100000となっています。
Wire.setClock(100000);

![image.png](https://qiita-image-store.s3.amazonaws.com/0/165672/484d2463-c0e3-3ad6-28dc-83941f8f838e.png)
[ESP32 data sheet ](http://espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) p.26

補足
・Wireライブラリではありませんが、内部プルアップの設定はpinModeで指定します。(外部プルアップの有無などに応じて設定が必要)

  pinMode(21, INPUT_PULLUP);  //デファルトのSDAピン21　のプルアップの指定
  pinMode(22, INPUT_PULLUP);  //デファルトのSDAピン22　のプルアップの指定

INPUT_PULLUPで内部プルアップ有効、INPUTで内部プルアップ無効です。
公式のpinModeマニュアルは[こちら](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2014)です。

♯注 ESP32の内部プルアップですが、GPIO34 から GPIO39では使用できないようです。→　[参考](https://qiita.com/no_clock/items/a3bc8a9816534cf8c930)


# I2C テスト　\<LCDコントローラ ST7032>
I2Cのテストとして、LCDコントローラのST7032で確認しました。
Arduinoのライブラリは作成してくださっている方がいましたので、以下を参考にしました。
http://ore-kb.net/archives/195

上記をそのまま使用するとエラーが出ました。
ESP32向けには若干の修正が必要なようで、以下を参考にさせていただきました。
http://blog.boochow.com/article/424685995.html

```Arduino\libraries\arduino_ST7032-master\ST7032.cpp

#include "ST7032.h"
#include "Arduino.h"
#include <Wire.h>
#if defined(__AVR__)　　←　追加
#include <avr/pgmspace.h>
#endif　　　　　　　　　　←　追加

```

サンプルで動作させたコード

```sample_st7032.ino
#include <Wire.h>
#include <ST7032.h>

ST7032 lcd;

void setup() {
  // put your setup code here, to run once:
  lcd.begin(8, 2);
  lcd.setContrast(30);            // コントラスト設定
  lcd.print("hello !");
}

void loop() {
  // put your main code here, to run repeatedly:

}
```

ST7032ライブラリの使い方を少し確認します。
READMEを確認すると、Examplesにサンプルがありました。
        - Autoscroll          (*)
        - Blink               (*)
        - Cursor              (*)
        - CustomCharacter     (*)
        - Display             (*)
        - HelloWorld          (*)
        - Scroll              (*)
        - SerialDisplay       (*)
        - setCursor           (*)
        - TextDirection       (*)

文字の操作などはArduino本家のLiquidCrystalライブラリのコマンドとして使えるようなので、操作方法はLiquidCrystalライブラリを確認しましょう。
https://www.arduino.cc/en/Reference/LiquidCrystal
[rancherOS]ネットワークのリスタートの方法

rancherOSでいわゆる`service network restart`とか`systemctl restart network`を実行する方法です。
※本記事はrancherOS 1.1.0で検証しています

# コマンド
```
sudo ros service restart network
```

実行例

```
[rancher@morihaya-rancher ~]$ sudo ros service restart network
ERRO[0000] non-200 http response: 404                   
INFO[0000] Project [os]: Restarting project             
INFO[0000] [0/19] [network]: Restarting                 
INFO[0001] [0/19] [network]: Restarted                  
INFO[0001] Project [os]: Project restarted     
```

`ERRO[0000] non-200 http response: 404` が出てますが特に影響なかったので気にしない。。。

# どんなときに必要になるのか
複数のNICを持ったサーバでrancherOSを起動したところ、一部のNICだけDHCPでIPが取れなかった時に「OS再起動するほどじゃないので、ネットワークだけリスタートしたい><」となりました。
PHP「1...10 === '10.1' は true」僕「えっ──！？」

論より証拠。

```php
<?php
assert(1...10 === '10.1');
```

こういうことらしい……。

```php
assert((1.) . (.10) === '10.1');
assert((1.) . (.10) === '10.1');
assert((1) . (.10) === '10.1');
assert(1 . (.10) === '10.1');
assert(1 . 0.1 === '10.1');
assert('1' . 0.1 === '10.1');
assert('1' . '0.1' === '10.1');
```
[rancherOS]rancherユーザのパスワードを設定する手順メモ

rancherOSで使用するユーザ"rancher"のパスワード変更の方法がわからず、rancherjp slackのqaチャンネルに質問したところ、 @yamamoto-febc と @FoxBoxsnet にさらっと解決頂いたので、備忘としてメモしておきます。

※本記事はrancherOS 1.1.0で検証しています

# 手順

最初にやり方を記載します。

```
sudo passwd rancher
-> 新パスワード設定
sudo ros config syslinux
-> "rancher.password=HOGEHOGE"の用に新パスワードを変更or追記
```

## ログイン中にオンラインで設定
```
sudo passwd rancher
```
ISOからの初回起動時やsshログイン後の変更はこちらで、ごく普通のlinuxのコマンドですね。
しかしこのままOS再起動をすると初期化されてしまうので、永続的な設定を行う必要があります(rancherOSはOS自体がsystem-dockerというdocker上で起動するためです)

## (永続設定)OSイメージのディスクインストール時に設定
```
sudo ros install -c cloud-config.yml -d /dev/<ディスクデバイス> --append "rancher.password=password"
```
@FoxBoxsnet さんの[[RancherOS で インストール後パスワードでログインする方法]](https://qiita.com/FoxBoxsnet/items/127354c03b55a161a35b)の記事にもあるとおりです。
rancherOSをディスクへインストールする際に、カーネルのブートパラメタとして設定します。

## (永続設定)カーネルのブートパラメタ設定
```
sudo ros config syslinux
-> カーネルブートパラメタの編集モードになるため"rancher.password=HOGEHOGE"を追記

例)APPEND printk.devkmsg=on rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait console=tty0 rancher.password=HOGEHOGE
```
カーネルのブートパラメタを変更します。反映は次回の再起動後になりますので、オンラインでの変更とセットで実行することになるでしょう。
公式ドキュメントはこちらです->[Kernel boot parameters](http://rancher.com/docs/os/v1.1/en/configuration/adding-kernel-parameters/)
(@yamamoto-febc さんに教えて頂きました、Thx!)

# なぜパスワードを設定する必要があるのか?
「パスワードなんて脆弱！sshなら鍵認証があるじゃろ」と思った方に、私もそう思って痛い目を見たのでお伝えしたい。
　　***『いざという時の為に設定しておいた方がいいよ(><)!』***
ネットワークが死亡するなどした際にいざという時にパスワード認証ができないと、コンソールログインしようにもパスワードがわからなくて詰みます。
私の場合はOS再起動後にDHCPでIPが何故か取れない事象が発生し、sshが出来ない状況に詰みました...orz

なお同様の事が[[Qiita:RancherOS on XenServer]](https://qiita.com/ryota_hnk/items/d0904862a24a420b1242)に記載されておりました。(私はハマるまでその必要性を理解していなかったので反省...）
秘伝の var_dump 関数を公開します。

様々なプロジェクトを渡り歩き少しずつ改良しながら使ってきた秘伝の var_dump() ラッパー関数です。

```php
function d()
{
    // 全引数の var_dump() の出力内容を変数に取り出し
    ob_start();
    foreach (func_get_args() as $arg) {
        var_dump($arg);
    }
    $dump = ob_get_clean();

    // 可読性のためインデント幅を2倍に (2 -> 4)
    $dump = preg_replace_callback(
        '/^\s++/m',
        function ($m) {
            return str_repeat(" ", strlen($m[0]) * 2);
        },
        $dump
    );

    // この関数の呼び出し元を取得 （ファイルパス・行番号）
    $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0];

    // ヘッダーの HTML を生成
    $header = sprintf('<pre style="%s">', implode(';', [
        'border: 1px solid #bbb',
        'margin: 2px',
        'padding: 6px',
        'solid: #bbb',
        'text-align: left',
        'background: #fdfdfd',
        'color: #000',
        'font-family: monospace,serif',
        'font-size: 12px',
    ]));
    $header .= sprintf('<span style="%s">%s:%d</span>',
        implode(';', ['font-weight: bold']),
        $caller['file'],
        $caller['line']
    );
    $header .= PHP_EOL;

    // フッターの HTML を生成
    $footer = '</pre>' . PHP_EOL;

    // ダンプ内容を出力 (CLI で実行された場合は HTML タグを取り除く)
    $isCli = (php_sapi_name() === 'cli');
    echo $isCli ? strip_tags($header) : $header;
    echo $dump;
    echo $isCli ? strip_tags($footer) : $footer;
}
```


## ポイント

- 関数名が一文字なので手軽です。
- HTML + CSS で見やすく装飾されます。
    - コマンドラインから実行した場合は HTML は取り除かれ plain なテキストでダンプされます。
- 可変長引数に対応しています。
    - 例: `d($var1, $var2, $var3);`
- ダンプ元のファイルパスと行番号も出力されるので、どこに書いたか忘れちゃっても大丈夫です。
    - 出力フォーマットは　`ファイルパス:行番号`　なので、そのままコピーして PhpStorm のファイルナビゲート欄 (Mac: `⇧⌘O` / Win: `Ctrl + Shift + N`) とかに貼りつければダンプ元にジャンプできます。

なんだかんだ PHP で一番頼りになるデバッグ方法は愚直な変数ダンプだと思ってる。（個人の感想です。）

## 参考

- [var\_dump、var\_export、print\_r、デバッグ時に使うのがベストなのはどれ！？ \- Qiita](https://qiita.com/awesam86/items/1103079594fefc8e9f3f)
- [var\_dump\(\) で出力する内容を省略させない \- Qiita](https://qiita.com/captain-goblin/items/cce50fcc111e5964681f)
scrapyをpycharmでデバッグ

#概要

クローリング・スクレイピングのフレームワーク`Scrapy`の勉強中

参考にしている本は、`scrapy`コマンドで実行させているが
`pycharm`上で実行し、デバッグも行いたかったので備考録としてのメモ


#やりたいこと
scrapyの実行は

```bat
G:\pg_wk\python_study\my_scrapy>scrapy runspider myspider.py -o items.li
```

のように行うが、これと同様のことを`pycharm`上でやる

#やったこと
`メニュー > 実行 > 構成の編集` から起動構成を作成して実行

**下記に設定例**
・スクリプト
　scrapyのパッケージをインストールしたディレクトリを探せば見つかるはず。
　これで`G:\pg_wk\python_study\my_scrapy>scrapy `と同じ意味

・スクリプトパラメータ
　コマンド時と同様に渡したいパラメータを設定

・作業ディレクトリ
　scrapyコマンドを実行させたいディレクトリ

・後でコマンド・ラインを表示する
　これにチェックを入れないとなぜか`ModuleNotFoundError: No module named 'http.client'`と怒られる

# ![aaa.png](https://qiita-image-store.s3.amazonaws.com/0/31410/26e81663-e30c-9bda-b967-542bf888e5ff.png)




参考：https://stackoverflow.com/questions/21788939/how-to-use-pycharm-to-debug-scrapy-projects
YAMAHA RTX3000設定覚書

#YAMAHA RTX3000を設定した覚書

##使用したもの

メルコUSB シリアル変換ケーブル
http://buffalo.jp/products/catalog/supply/cable/usb/change/src06us/

CenterCOM GS908M
https://www.allied-telesis.co.jp/products/list/switch/gs900m/catalog.html

##経緯
もともとRTX1100をつかっていたんですが
せっかくのGiga回線がもったいなくてRTX3000を仕入れてまいりました
RTX1100は、調子の悪い実家ルーターRT58iと置き換えようかと・・・・
https://network.yamaha.com/products/routers/rt58i

##手順
Windows10Proをつかうばあい
USBシリアル変換ケーブルのドライバーをダウンロードしてきて
デバイスマネージャーからインストール

RTX3000を繋いで電源オン！
```show config
```
するとファームバージョンが
```9.00.40
```

うん、古いねん

```
ip lan1 address 192.168.13.1/24
tftp host 192.168.13.124
```
とりあえず、適当にIP設定して
ダウンロードしてきたファーム書き換え
```D:\>tftp -i 192.168.13.1 put rtx3000.bin exec
```※tftpとtelnetはプログラムの機能で有効にしておきましょう！



再起動したら
とりあえず
```no tftp host```
をして
tftpを無効に

##くコ:彡設定

LAN側
```ip lan1 address 192.168.13.1/24
nat descriptor type 1 masquerade
pp select 1```
WAN側
```pppoe use lan2
pp auth accept chap pap
pp auth myname aaaaaaa@ssssss.com ********
ppp ipcp ipaddress on
ppp ipcp msext on
ip pp nat descriptor 1
ppp lcp mru on 1454
ip pp mtu 1454
ppp ccp type none
pp enable 1
pp select none```
ルート
```ip route default gateway pp 1
dns server pp 1
dns private address spoof on```
DHCP設定するぉ
```dhcp service server
dhcp scope 1 192.168.13.101-192.168.13.200/24```

めでたく完了

が、やはりプロバイダーがネックか・・・あまり早くねぇ
新しい削除時の仕組みを考えてみた。

Symfonyで管理画面を作っている際に、Ajaxで1レコードの削除を実装した時に考えた削除の確認仕組みメモ。

ダイアログ出すのもいいんだけど、マウス動かすのめんどくさいよね？（そうでもない？）

#仕組み

削除ボタン押下→待機中になる(1秒間)→もう一度押下で削除

凄くシンプルです。間違ってクリックした時に誤って削除するのも防げるのでこれでも十分かなと。

アイコンはFont Awesome　を使ってます。
[fontawesome.io](http://fontawesome.io/icons/)

```js
//Row Delete Ajax Axtion
$(document).on('click','button[aria-label=RowDelete]',function(){
  var $button = this;

  //削除ボタン初期アイコン
  var $iconDef = 'fa fa-remove fa-2';
  //削除ボタン待機中アイコン
  var $iconInterval = 'fa fa-refresh fa-spin fa-2';
  //削除中アイコン
  var $iconDelete = 'fa fa-spinner fa-spin fa-2';

  //アイコンが初期の場合
  if( $($button).attr('class') == $iconDef){
      //アイコンを待機中に変更して1秒間待機状態に。
      $($button).attr('class',$iconInterval);
      var $timer = setInterval(function(){
          //アイコンが待機中の場合に時間が来たら初期状態に戻す。
          if( $($button).attr('class') == $iconInterval ){
              $($button).attr('class',$iconDef);
          }
          clearInterval($timer);
      },1000);

      //処理を終了する。
      return 0;
  }

  /* アイコンが待機中の場合削除を実行 */

  //タイマーを削除
  clearInterval($timer);

  //アイコンを削除中アイコンに変更
  $($button).attr('class') == $iconDelete;

  //対象行のボタン関連はすべて押下不可にする。
  $row.find('button').addClass('disabled').prop('disabled',true);

  $.post('action.php',function(){
      /* 削除完了後処理 */
      //アニメーションで行を消すなど
      ...
  });

}
```

複数件削除したいときに何回もダイアログでるのが嫌いな人は是非使ってみて下さい。
チャタリング起きてるマウスだと危険(!)