OmniAICreator/Qiita-1.07M huggingface dataset:
ゼロから始めるHDDフォーマット with Ubuntu

今まで使っていたPCのHDDを初期化したいと思った時のために手順をまとめます。

# あらすじ
フォーマットを、始めましょう。１から…いいえ、ゼロから！

# 使うもの
Ubuntu16.04 のLiveDVD
Ubuntuが入っているPC

# 手順
1. LiveDVDで起動し、「Ubuntuを試す」を選択します
![スクリーンショット (15).png](https://qiita-image-store.s3.amazonaws.com/0/183992/b2d82bbe-ac03-9796-7a2a-06db37b91bbb.png)
<br><br>
2. UbuntuメニューのSearch Your Computerから「gparted」と入力し、GParted Partition Editor を検索します
![スクリーンショット (16).png](https://qiita-image-store.s3.amazonaws.com/0/183992/74e1b0ab-1f81-664f-b23e-7f70f8bc78b6.png)
<br><br>
3. GParted Partition Editorを開きます
![スクリーンショット (17).png](https://qiita-image-store.s3.amazonaws.com/0/183992/4d0097d5-a0ae-6f43-6d15-bdbbf84b3e7c.png)
<br><br>
4. パーティションを右クリックしてメニューのDeleteを選択します
![スクリーンショット (18).png](https://qiita-image-store.s3.amazonaws.com/0/183992/bf606bac-d224-48cc-4660-7abf67dcff9b.png)
<br><br>
5. DeleteしたパーティションはUnAllocated(未割当)と表示されます
![スクリーンショット (19).png](https://qiita-image-store.s3.amazonaws.com/0/183992/506053aa-a21f-483b-1703-3c4400edd516.png)
<br><br>
6. Swap領域が確保されているパーティションは右クリックでSwapoffを選
択します
![スクリーンショット (20).png](https://qiita-image-store.s3.amazonaws.com/0/183992/a58049c6-6de2-50f2-6ae4-add6cee65359.png)
<br><br>
7. Swapoffした領域を右クリックしてメニューのDeleteを選択します
![スクリーンショット (21).png](https://qiita-image-store.s3.amazonaws.com/0/183992/ab81c7ed-f169-c4cf-0675-8a8becf96e55.png)
<br><br>
8. Delete出来たらUnAllocated状態になるので、パーティションをDelete
します
![スクリーンショット (22).png](https://qiita-image-store.s3.amazonaws.com/0/183992/f8068b32-4a7b-99f8-1514-10f11c0e9964.png)
<br><br>
9. 使っていたHDDのパーティションが全て削除されたら、画面上のApply ALｌ Operationsというチェックマークをクリックします
![スクリーンショット (23).png](https://qiita-image-store.s3.amazonaws.com/0/183992/82393296-28fa-f1d3-4a5a-414191e12384.png)
<br><br>
10. メッセージが表示されるのでApplyを選択します
![スクリーンショット (24).png](https://qiita-image-store.s3.amazonaws.com/0/183992/e43c07ff-e982-7c3e-8506-06dde72d97d5.png)
<br><br>
11. 処理が完了したらCloseボタンを選択します
![スクリーンショット (25).png](https://qiita-image-store.s3.amazonaws.com/0/183992/92810ab7-c766-c8e8-04a3-54fa2123978a.png)
<br><br>
12. PCの中にHDDが物理的に２つ以上存在する場合は、画面右上のコンボボックスで選べるので、項目4～11を繰り返します。何度でも。
![スクリーンショット (26).png](https://qiita-image-store.s3.amazonaws.com/0/183992/7d72a30d-b474-9ab5-2e24-b8c365d8544f.png)
<br><br>
13. 終わったらシャットダウンします。

<br>以上です

## 追記
CentOSのPCだとうまくいかない事象が発生しました。
あとで調べてまとめたいと思います。

<br><br><br>
UIViewAnimationOptions メモ


# はじめに
基本的なUIViewアニメーションについてのOptionsメモ。
とっても今更なので、[[公式ドキュメント]](https://developer.apple.com/documentation/uikit/uiviewanimationoptions)から随時更新していこうかと思ってます。

## 簡易アニメーション4種
  - curveEaseInOut
  - curveEaseIn
  - curveEaseOut
  - curveLinear

```swift:UIViewController
//ビューを時間をかけてどうこうしたい時
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut, animations: {
   // アニメーション
}, completion: { (success) in
   // アニメーション完了
})
```
![GIFイメージ-12A23F5E4B0B-1.gif](https://qiita-image-store.s3.amazonaws.com/0/235001/1869b07b-5d4f-8e33-2828-8245e0d26611.gif)

## 活用方法不明・・・
- layoutSubviews　

色々試してみたけれど、何がどう変わるのか今の所不明
【AutoLayout】systemLayoutSizeFittingSizeでもう悩まない！

systemLayoutSizeFittingSize
何度となく忘れるので書きます

以下２つについてです

```
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize;
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize 
        withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority 
              verticalFittingPriority:(UILayoutPriority)verticalFittingPriority;
```

公式
https://developer.apple.com/documentation/uikit/uiview/1622624-systemlayoutsizefittingsize

### 用途

AutoLayoutで設定したView群にコンテンツを設定した後、適切な高さ、幅を取得する際などに使います

## 基本

targetSizeには大抵
UILayoutFittingExpandedSize　か
UILayoutFittingCompressedSize を指定します

ExpandedSizeはできるだけ大きく
CompressedSizeはできるだけ小さくします

以上

...ってところまでは、ググればいっぱい出てきます
でも何かうまく動かないことが多いので、どういう仕組みか理解していきます

## UILayoutFitting？？

UILayoutFittingExpandedSize、UILayoutFittingCompressedSizeはCGSizeです
ログを出せばすぐわかります

UILayoutFittingExpandedSize は (width,height) = (10000,10000)でした
UILayoutFittingCompressedSize は (width,height) = (0,0)でした

```
systemLayoutSizeFittingSize:UILayoutFittingCompressedSize;
```
これはつまり

```
systemLayoutSizeFittingSize:CGSizeMake(0,0);
```
と等価です。

でもこれだけじゃよくわかりません。

## FittingPriority

UIView.hを見るとこう書いています

```
　- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize NS_AVAILABLE_IOS(6_0); // Equivalent to sending 　-systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: with UILayoutPriorityFittingSizeLevel for both priorities.
```

つまり、以下２つが等価です。

```
// これと
systemLayoutSizeFittingSize:targetSize;

// これ
systemLayoutSizeFittingSize:targetSize 
        withHorizontalFittingPriority:UILayoutPriorityFittingSizeLevel
              verticalFittingPriority:UILayoutPriorityFittingSizeLevel;
```

UILayoutPriorityFittingSizeLevelはUILayoutPriorityの一番低いやつです(=50)

## 状況

つまりこういう状況です

![joukyou.png](https://qiita-image-store.s3.amazonaws.com/0/20784/87e365a5-9858-e2f8-f7e1-4587b0e5b7e2.png)

例えばsystemLayoutSizeFittingSize:UILayoutFittingCompressedSize は
**(width,height)=(0,0)の赤枠に対象のViewを入れて、マージンをゼロにし、HorizontalとVerticalのLayoutPrioryを50に設定した時のAutoLayoutの結果サイズを返す**
という状態です

## うまく動かない時

AutoLayoutに慣れているなら、上記まで理解できればうまく動かない理由に思い当たるかと思います。

よくあるパターンとして、例えばHorizontalを固定で高さだけ取得したい場合は、横幅を固定にしてしまえばいいです

```
systemLayoutSizeFittingSize:CGSizeMake(self.view.frame.size.width,0)
        withHorizontalFittingPriority:UILayoutPriorityRequired
              verticalFittingPriority:UILayoutPriorityFittingSizeLevel;
```

（あってるよね？🤔 　ここよく混乱するのでミスなどあったらすいません）
00000から99999までの連番ファイル名で10万個のファイルを作成するコマンド

嫌がらせとかで使えます。

```shell-session
$ seq 0 99999 | xargs printf '%05d\n' | xargs touch
```

- `seq 0 99999` で0から99999までの連番を生成します（0 1 2 3 .... 99999）
- `xargs printf '%05d\n'` でseqが生成した数を5桁のゼロ埋め形式に変換します（123 -> 00123）
- `xargs touch` で標準入力から渡ってきた文字列をファイル名として空のファイルを作成します
NanoPi-NEO2用のkernel build

## 概要

NanoPi-NEO用のkernelはfriendlyarmが用意してくれていますが、最新のmainline kernelのバージョンは4.14.0です。ただ、私の執筆現在の最新のバージョン(kernel.org)は、4.14.15です。
i2sで音出しをするシステムをbuildrootで作っているのですが、friendlyarmのkernelにはi2sのドライバが用意されているのでこれを使いたいわけです。そこで、4.14.0を4.14.15へバージョンアップできないかと（無理矢理）考え、やってみたらできた、というのが今回のお話しです。

## 大まかな手順

1. friendlyarmからkernelのソース(4.14.0)を取ってくる。
2. kernel.orgからpatch-4.14.15を取ってくる。
3. kernel.orgからpatch-4.14.15-rt13を取ってくる。（rt-kernelにしたいから）
4. 1.に2. 3.のpatchをあてる。2.をあてるとrejが出るが、手修正できるものはやり、あとは影響ないと判断できるものは放置する。
5. makeする。

これだけのことです。私が今回試したのはNanoPi-NEO2ですがfriendlyarmが用意してくれているkernelなら同じ方法でできると思います。
TextureViewでonSurfaceTextureAvailableが呼ばれないときにチェックする事


ちょっとググってなかったので、自分用にメモ:memo:

TextureViewは```SurfaceTextureListener```を持っていて、そのInterfaceの１つ```onSurfaceTextureAvailable```は、TextureViewのSurfaceTextureが使用できる状態になると呼び出されます。たいていは、このコールバックが呼べれたときにカメラの初期等を行うかと思います。
今回は、タイトル通りこのコールバックが呼ばれない事象と遭遇しました。

## :four_leaf_clover:  検証環境

- Nexus 5X (8.0)
- Docomo Galaxy S8+ (7.0)

## :hammer: 解決法

```AndroidManifest.xml
...
<application
        android:hardwareAccelerated="false"
...        
```
この項目があると```onSurfaceTextureAvailable```リスナーが呼ばれず、いつまでのカメラの初期化処理を呼ぶ事ができずに、黒い画面が表示されてしまいます。

そのときにlogcatに

```logcat
W/TextureView: A TextureView or a subclass can only be used with hardware acceleration enabled.
```

というWarningが出るので、そこであたりはつけられると思います。

この事象で注意が必要な事は、端末の```開発者向けオプション```＞```ハードウェアアクセラレーテッドレンダリング```＞```GPUレンダリングを使用```にチェックが入っていると、描画されてしまう事です。
端末によって問題の切り分けが難しくなってしまいますので、気をつけてください。

という事で```android:hardwareAccelerated="false"```を削除したらプレビューが表示されました。

## :paperclip: Refs

- https://developer.android.com/reference/android/hardware/camera2/package-summary.html
- https://developer.android.com/reference/android/hardware/camera2/package-summary.html?q=textureview
pythonからfasttextを実行すると`failed to allocate the memory`に遭遇した。





環境
---

* python2.7
* docker

原因
---

下記のコマンドでいれたfasttextがダメだった。

```
pip install fasttext
```

この状態で以下を実行しても

```
model = fastText.load_model('test.bin')
```

エラーが発生する

```
Exception: fastText: Cannot load model.bin due to C++ extension failed to allocate the memory
```

解決方法
---

ちゃんとfacebook公式のfasttextの導入にしたがってやるべき
https://github.com/facebookresearch/fastText/tree/master/python

```
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ python setup.py install
```
bashで最新N件残して他を削除する話

実行時になにがしかを出力したりする際に、
`capistrano` みたいな _最新N件残して残りを削除_ をbashで。

```a.sh
EXPORT_PATH=./data/some_exports
TARGET_DATE=$(date +%Y%m%d_%H%M%S)

if [ -d ${EXPORT_PATH} ]; then
    # 最新から4件残し
    ls -td ${EXPORT_PATH}/* | tail -n +5 | xargs rm -rf
fi

mkdir -p ${EXPORT_PATH}/${TARGET_DATE}

cat <<-EOD > ${EXPORT_PATH}/${TARGET_DATE}/export.txt
this is sample ${TARGET_DATE}
EOD
```

実行と確認。

```sh
for x in {1..10}; do
  sleep 1
  bash a.sh

  tree ./data
  find ./data/ -name 'export.txt' -exec cat {} \;
done
```
オタク向け学習済みfasttextを公開しました

# 初めに
今回はfasttextでオタク向けのモデルを作ります。

# どのコーパスを使ったか

[アニヲタWiki](https://www49.atwiki.jp/aniwotawiki/)のほぼ全記事(841MB)を学習させました。
文字数は空白含み、445284415文字。
サーバーには負担をかけないようウェイトを10秒はさみました。
分かち書きにはmecab-ipadic-NEologdを使いました。
binとvec両方含んである物もあるのでお好みで使い分けてください。

# ダウンロード

[ダウンロード](https://github.com/PenguinCabinet/Aniota-Wiki-fasttext-model)
注意:両方含んだ方のzipファイルサイズは大きいです。

# 使い方

## gensimの場合
```python3
import gensim
model = gensim.models.KeyedVectors.load_word2vec_format('model.vec', binary=False)
```
paiza POH #paizajack


## 六村リオ開放

自分の情報しか見えないし、適当にがんばれば開放できるんじゃないかな。

## 六村リオバニー開放

相手の手札の情報が見えるので、とりあえず相手のスコア以下なら引く処理は必要。
あと、この段階までに、Aを1とも11とも扱う処理の実装は必須。

「以下」です。未満ではありません。注意。

## 六村リオ赤バニー開放

山札が見られる仕様。要するに現実であれば山札が表向きになっている。ブラックジャックとしてのゲーム性は皆無ですが、別のゲームとしては面白そうですねorz
(Aがない場合)山札から引けるなら必ず引く処理をこの段階で入れることを推奨します。勝率が目に見えて違います。勝率が高ければ連勝しやすいということです。

- あと、この辺からは、提出を自動化しないときついかもしれない。Seleniumとかのブラウザツールキット、もしくはUserScriptでできます。
    - まったくの余談ですが、この間少し話題になった「Chromeのheadless」は、UIを表示しないという意味であり、SeleniumからChromeを操作するときに画面が不要というのが利点の一つです。

### 緑川つばめ赤バニー

- 掛け金は連勝ごとに上げるようにしてください。たとえ少しであっても、指数関数の伸びは意外と大きいものです。固定するのは本当にもったいないです。
- 週間ランキングのチップ数が2\*\*31以上になるとき、ゲームが止まるのは仕様のようです。それ以上は当該週は勝利できません(提出はできますし、敗北するならゲームは進行しますが、意味がありません)。

## 六村リオ赤バニー

ディーラー別ランキングでもなく、累計ランキングですから、9999万賭けたいもの。
というわけで、所持チップが最低でも20億ない状態で挑むのは危険です。山札の状況を確認するコードを書かなくても六村リオ赤バニー開放にはこぎつけますが、ない状態で挑むと死にます( **私の所持チップが一回0になりました** )。

## ジャックポット

大事なことですが、 **指定順位は毎回変わります。** ということは、 **全部のディーラーに対して1勝だけするのが確率的に最善です。** この方法で私はアマギフを **8枚中3枚** 手に入れました。

## 答案

```rb:tyama_paizapoh13.rb
#!/usr/bin/ruby
#paizajack program by @cielavenir.

def score(cards)
	a,b=cards.partition{|e|e==1}
	(a.size+1).times.map{|i|
		10*i+a.size+b.reduce(0,:+)
	}.select{|e|e<=21}.max
end

cards_s=gets
match_s=gets
streak_s=gets
won_s=gets
dealer_s=gets
deck_s=gets

cards=cards_s.split.map &:to_i
if cards[0]==0
	#六村リオ赤に限り、以下をコメントアウトし、99990000に固定して提出します

	#take care of combo?
	if streak_s.to_i==0
		puts 10000 #cards[1]
	else
		puts (0.4 * won_s.to_i).to_i
	end
	exit
end

if score(cards).nil? || score(cards)==21
	#決着
	#todo:dealerも21になったら負けなので、bustさせるためにあえて引く場合
	puts 'STAND'
	exit
end

if !dealer_s
	#緑川つばめまで
	if cards.reduce(:+)>=16 || score(cards)>=18
		puts 'STAND'
	else
		puts 'HIT'
	end
elsif !deck_s
	#緑川つばめバニーまで
	dealer=dealer_s.split.map &:to_i
	if score(dealer).nil? || score(dealer)==21
		#決着
		puts 'STAND'
	elsif score(cards)>score(dealer)
		#todo: 余裕があるのにスタンドしうる
		puts 'STAND'
	else
		puts 'HIT'
	end
else
	#六村リオ赤バニーまで
	dealer=dealer_s.split.map &:to_i
	deck=deck_s.split.map &:to_i
	dealer_freeze=cards.size>dealer.size 
	
	if score(dealer).nil? || score(dealer)==21
		#決着
		puts 'STAND'
	elsif dealer_freeze
		#勝つまで引ける
		if score(cards)>score(dealer)
			puts 'STAND'
		else
			puts 'HIT'
		end
	elsif score(cards+[deck[0]]).nil? && score(cards+[deck[1]||99]).nil?
		#詰み
		puts 'STAND'
	elsif score(cards+[deck[0]])&&score(cards+[deck[1]||0])
		#引いて差し支えない
		if score(cards)<=[score(cards+[deck[0]]),score(cards+[deck[1]||0])].max
			puts 'HIT'
		else
			#けど、引かないほうがスコアが高くなるなぁ
			puts 'STAND'
		end
	# 1枚目か2枚目のどちらかは手札に加えて安全…さて、どう出るか。
	elsif score(dealer+[deck[0]]).nil?
		# ディーラーがbustするなら1枚目を引くことになりそうだよね
		if score(cards+[deck[0]]) && score(cards)<=score(cards+[deck[0]])
			puts 'HIT'
		else
			puts 'STAND'
		end
	elsif deck.size<2
		puts 'STAND'
	elsif score(cards+[deck[1]]) && score(dealer+[deck[0]]) && score(dealer+[deck[0]])>=score(cards)
		puts 'HIT'
	else
		puts 'STAND'
	end
end
```

## 終わりに

緑川つばめ赤バニーに提出するのは今週までです。以降は六村リオ赤バニーにしか提出しません。

##  謝辞

山札の処理で一部 @yuichi_sakurada 氏のコードを参考にさせていただきました.
【Xcode】スタートアップスクリーンでラベルを使う際の注意【InterfaceBuilder】

ラウンチスクリーンをInterface Builderで作成していた時の話。解決までに無駄に時間を食ったのでメモ。

環境：Xcode 9.2 beta

#### fontが`Custom`で、textが`Plain`だとアプリでエラーが発生して起動できない。
<img width="1485" alt="xxxx1.png" src="https://qiita-image-store.s3.amazonaws.com/0/151314/00775f3e-b633-f64f-c91c-fdc2158d3471.png">

↑の設定でビルドすると...

<img width="1491" alt="xxxx3.png" src="https://qiita-image-store.s3.amazonaws.com/0/151314/4ef4a6ca-2b79-bb94-57ca-e4ae7f99b521.png">

コケる。

#### fontが`Custom`の場合、textは`Attributed`にする。こうするとエラーは発生しない。
<img width="1491" alt="xxx2.png" src="https://qiita-image-store.s3.amazonaws.com/0/151314/8f569815-fab4-21c5-6bf1-1bc870fce78d.png">

ちなみに、`LaunchScreen.storyboard`のみの現象で、`Main.storyboard`だと発生しない。

(´・ω・｀)　なんだろう....
シェルの実行で`bad interpreter: /bin/sh^M: no such file or directory`と出る場合の対応


取り急ぎ書いておきます

## 対応1: Vimで対応
vimを開いて下記のコマンドをつっこむ

```
:set fileformat=unix
:wq!
```

```
:set ff=unix
:wq!
```

## 対応2: sedで対応

```
$ sed -i 's/\r//' <filename>
```


## 参考
[StackOverFlow
](https://stackoverflow.com/questions/2920416/configure-bin-shm-bad-interpreter)
[keras]各学習データの量が均一ではない場合の対処方

# 背景
kerasだけには限らないことですが、学習させたいデータの数が不揃いな場合がほとんどだと思います。
データ数がちょっとの差しかない場合はあまり問題にはなりませんが、何倍もの差がある場合は数の多いデータに対してのみ予測精度の高い学習器が出来上がってしまいます。
今回はkerasで画像を学習させる際にある程度量の差を緩和する方法を書きたいと思います。

# やり方
入力に重みを付けます。
データ数の多いラベルの物の重みを軽くし、データ数の少ないラベルの重みを重くします。
例えば、ラベルが3つあるデータの点数がそれぞれ、

|ラベル|データ数 |
|:-----------------|------------------:|
| データ１|100|
| データ２|200|
| データ３| 300 |

だった場合、重みのデータは

|ラベル|重み|
|:-----------------|------------------:|
| データ１|3|
| データ２|1.5|
| データ３|1|
となります。

# コード
fit_generator内に

``` python3
fit_generator(
#----省略----
class_weight=cal_weight(data), 
#----省略----
)
```
この項目を書き足します。
class_weightの部分はdictionary型です。
そのため、例に上げたような重みのデータは{0: 3.0, 1: 1.5, 2: 1.0}のような形で記述する必要があります。
次に重みを計算する部分ですが、ImageDateGeneratorデータの読み込み方(flowとflow_from_directory)によって変えなければならないです。

## flowを使用する場合
使用する学習データのラベル配列が必要となります。

class_id_listはラベルのリストをkerasのto_categoricalで変換したものを指します。
例えば６枚の画像のデータセットに対して猫と犬というラベルが付けられている場合は

```python3
from keras.utils.np_utils import to_categorical
class_name = ['猫','犬']
class_list = ['猫','犬','猫','犬','猫','猫']

def make_id_list (label):
    return class_name.index(label)

class_id_list = to_categorical(list(map(make_id_list, class_list)))
print(class_id_list)
#array([[ 1.,  0.],
#       [ 0.,  1.],
#       [ 1.,  0.],
#       [ 0.,  1.],
#       [ 1.,  0.],
#       [ 1.,  0.]])
```
なぜこんなめんどくさいことをしているかというと、kerasではラベルをバイナリベクトルで扱う方が都合がいい場合が多いからです。
このバイナリベクトルを入力とすれば以下の関数から重みを取り出せます。

```python3
def cal_weight(class_id_list):
    amounts_of_class_array = np.zeros(len(class_id_list[0]))
    for class_id in class_id_list:
        amounts_of_class_array = amounts_of_class_array + class_id
    mx = np.max(amounts_of_class_array)
    class_weights = {}
    for q in range(0,len(amounts_of_class_array)):
        class_weights[q] = round(float(math.pow(amounts_of_class_array[q]/mx, -1)),2)
    return class_weights
```
## flow_from_directoryを使用する場合
使用する学習データはクラス名が書かれた画像のフォルダを使用することを想定しています。
class_name_listに学習に使うクラスのlistを入力し、IN_DIRにクラス名が書かれた画像フォルダのディレクトリを入力してください。

``` python3
def cal_weight(class_name_list,IN_DIR):
    amounts_of_class_dict = {}
    mx = 0
    for class_name in class_name_list:
        class_dir = IN_DIR + os.sep + class_name
        file_list = os.listdir(class_dir)
        amounts_of_class_dict[class_name] = len(file_list)
        if mx < len(file_list):
            mx = len(file_list)
    class_weights = {}
    count = 0
    for class_name in class_name_list:
        class_weights[count] = round(float(math.pow(amounts_of_class_dict[class_name]/mx, -1)),2) #重み＝（データ数/最大値）の逆数
        count += 1
    return class_weights
```
Automatorで削除したファイルはゴミ箱から戻せない

アクションの「Finder項目をゴミ箱へ入れる」で削除したファイルは元の場所に戻せない。

戻せるようにしたい場合は、AppleScriptで削除する。

```applescript:AppleScriptを実行
on run {input, parameters}
  tell application "Finder"
    repeat with theFile in input
      delete theFile
    end repeat
  end tell
end run
```
djangoで新しいプロジェクトをつくるまで

2,3ヶ月程度開発できる時間が取れず色々とやり方を忘れてしまったので、メモ程度にプロジェクト作成までの流れを書きます。

#動作環境
 - Mac OS High Sierra 10.13.2
 - pyenv 1.1.5
 - pip 9.0.1
 - python 3.6.3

まだ`python`や`pyenv`等をインストールしていない方はこちらをご参考ください。
 - [pythonの環境を再構築！！【開発環境の構築編】](https://qiita.com/SonoT/items/091d2748deb16fb03653)

##本記事で用いている用語
- workspace : 作業用ディレクトリ名
- newProject : 新しく作成するプロジェクト用のディレクトリ名
- projectName : 新しく作成するプロジェクト名
- user : ユーザー名(自分のMacにつけている名前)

#新しいプロジェクトの作成
では早速、新しいプロジェクトを作っていきましょう。
今回の流れとしては、
1. 新しいプロジェクト用のディレクトリを作る
2. 仮想環境を作って適応させる
3. 必要なライブラリをインストール
4. djangoで新しいプロジェクトを作成
こんな感じでやっていきたいと思います。

##1.新しいプロジェクト用のディレクトリを作る
まず下準備として新しいプロジェクト用のディレクトリを作成します。

```bash:bash
$ cd ~/workspace

$ mkdir newProject

$ ls
newProject

$ cd newProject
```

これで下準備は完了です。
今作ったディレクトリの中に新しいプロジェクトを作っていきます。

##2.仮想環境を作って適応させる
今回のプロジェクトでは`python3.6.3`を使いたいのでこのバージョンで環境を作ります。

```bash:bash
$ pyenv virtualenv 3.6.3 projectName

$ pyenv versions
* system (set by /Users/user/.pyenv/version)
  2.7.14
  3.6.3
  3.6.3/envs/projectName
  projectName
```

これで仮想環境は作ることができました。ですが`*`このマークがついてるものが現在適応されているので、これを変更します。

```bash:bash
$ pyenv local projectName

$ pyenv versions
  system
  2.7.14
  3.6.3
  3.6.3/envs/projectName
* projectName (set by /Users/user/workspace/newProject/projectName/.python-version)
```

これで仮想環境の適応は完了です。

##3.必要なライブラリをインストール
続いて`pip`を用いてライブラリのインストールを行います。
今回はプロジェクトを作ることが目的なので`django`のみインストールします。

```bash:bash
$ pip list
pip (9.0.1)
setuptools (28.8.0)

$ pip install django
Collecting django
  Downloading Django-2.0.1-py3-none-any.whl (7.1MB)
    100% |████████████████████████████████| 7.1MB 219kB/s
Collecting pytz (from django)
  Using cached pytz-2017.3-py2.py3-none-any.whl
Installing collected packages: pytz, django
Successfully installed django-2.0.1 pytz-2017.3

$ pip list
Django (2.0.1)
pip (9.0.1)
pytz (2017.3)
setuptools (28.8.0)
```
`django`をインストールすると一緒に`pytz`もインストールされますが、このままで大丈夫です。

##4.djangoで新しいプロジェクトを作成
とうとうメインですね。と言ってもここが一番楽勝です。

```bash:bash
$ django-admin startproject projectName

$ ls
projectName
```

これで新しいプロジェクトを作ることができました。
もっと詳しいことが知りたい！！という方は参考にした記事を下に載せてるので、ぜひ読んで見てください！！
お疲れ様でした＼＼\٩( 'ω' )و //／／

#ちょっとした雑談
今回は自分が忘れないために書いた記事なので、結構大雑把になってますね...
次にdjangoについて記事を書く機会があったらもっと詳細に書けるよう頑張ってみましょうかね(*´ω`*)

#参考にした記事
[Djangoを始めよう！ 〜チュートリアル①〜](https://qiita.com/gctfuji/items/bff55a0b8ae1b76c0ca1)
[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/2.0/intro/tutorial01/)
androidでwaiting for debuggerがずっと出ててattachされない時

なぜかわからないけど、Module settingのBuild typeのDebuggableをtrueだとダメで、(true)だと動く。

謎。

![スクリーンショット 2018-01-31 18.16.57.png](https://qiita-image-store.s3.amazonaws.com/0/31237/3ca88382-5d8c-9f7d-7918-47e7670d0ea8.png)
Webを使った新人研修　～SQL基礎編～

##はじめに
新人研修で、SQLを新人に覚えさせたいというケースは非常に多いと思います。
そのSQL基礎教育をコストを掛けずに、Web上のサービスを使って行う方法を提案したいと思います。

###前提条件・環境
・インターネットに繋がるパソコン (or スマホ・タブレット)
・ブラインドタッチができ、基本的なネットリテラシーのある1年目社員

###学習させたい内容
・SQL基礎

###所要時間
SQL基礎：1コマにつき40分程度を想定

##Webを使った SQL基礎 の学習
第１回として、上記「SQL基礎」の学習方法を考えて見ます。

###SQL学習意義の意識付け
学習意欲向上を図る為、今から行う学習がいかに自分たちに役立つか説明します。

###覚えるべき項目
基礎としては、以下のようなところでしょうか

- SELECTクエリを用いて、データの検索ができる
- INSERTクエリを用いて、データの挿入ができる
- UPDATEクエリを用いて、データの更新ができる
- DELETEクエリを用いて、データの削除ができる
- CREATEクエリを用いて、ユーザ作成・テーブルなどエンティティを作成できる

###実践する
それでは、「実践する」をしましょう。
以下のWebアプリケーションを使って、学習を進めます。
- [Ideone](https://ideone.com/)
簡易なクエリの学習だけの為、[SQLite](https://www.sqlite.org/)で十分でしょう。

以下に、スケジュールしました。実際の研修の際は、前日の復習を織り交ざると良いと思います。
1日目：[Webを使った新人研修　～SQL基礎編・SELECTクエリでデータ検索～](https://qiita.com/fujisystem/items/a27bb204c9d766081fdc)
2日目：[]()未定
3日目：[]()未定

～ここまで
オフラインリアルタイムどう書く F09  の問題


オフラインでリアルタイムに「どう書く」をやるイベント( https://yhpg.doorkeeper.jp/events/69649 )を行っています。

問題は「縦横ローテーション」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/ordf09rotbox/
です。

出題者の気分としては、問題を読み始めてから解けるまで30分あればなんとかなると思ってますが、ひとそれぞれで。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。

似たような問題をもっと解きたいという方は、
https://nabetani.hatenadiary.com/entry/yhpg_list
に過去問リンク集がありますので、そちらをご覧になると良いと思います。
AWS LambdaのAlexa Skills KitテストでWarningが発生する

lambdaではAlexaスキル用ソースコードを生成してくれるのだが、そのままテストしてみたらログにエラーが。

```shell
 Warning: Application ID is not set 
```

調べてみるとstackoverflowに回答が
https://stackoverflow.com/questions/42179590/how-to-fix-warning-application-id-is-not-set


129行目くらいを変更してあげればいいようです

```js:index.js
alexa.appId = APP_ID;
```

保存しテストしてみると無事エラーは消えました
aws-sam-localでランタイムの設定が無視される

みなさん enjoy serverless してますか？
昨年aws-sam-localのβがリリースされたのでローカルテスト用に使ってみようとしたのですが
その際になぜかランタイムの設定が読み込めなかったので原因と対処法をメモしておきます。

## 何が起きていたか
複数lamnda functionを管理する上で、共通化できる箇所（メモリサイズやランタイムなど）はひとまとめにしたかったので、以下のようにGlobalを使って管理してました。（抜粋。実際はDynamoの設定や他にも関数があります）

```template.yml
Globals:
  Function:
    Runtime: python3.6
    Timeout: 15
    MemorySize: 256
    Environment:
      Variables:
        TABLE_NAME: !Ref SamSampleDynamoTable
Resources:
  UserIndex:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.lambda_handler
      Role: #{Arn}
      CodeUri: 'functions/users/index.py'
```

`sam local start-api` を実行すると以下のWARNINGが

```
Ignoring UserCreate (create.lambda_handler) due to unsupported runtime ()
Ignoring UserIndex (index.lambda_handler) due to unsupported runtime ()

WARNING: Could not find function for [GET] to /users resource
WARNING: Could not find function for [POST] to /users resource
```

あれ、[公式サイト](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/test-sam-local.html) をみても `python3.6` はサポートされてるって書いてあるけどな。。と思いいろいろ調べてみると以下のようなISSUEが切られてました。
https://github.com/awslabs/aws-sam-local/issues/226

## 原因
現状 `Global` セクションにランタイムの設定が書かれている場合、無視されてしまうようです。

ベータなので（ISSUEも切られてますし）これから対応されることが予想されますが、取り急ぎ開発を進めたい方は各ファンクションにランタイムの設定を書くことで上記エラー（正確にはエラーにはなっていないですが）を回避することができます。
Webを使った新人研修　～Javaを用いた基本的プログラミング編～

##はじめに
新人研修で、Javaを新人に覚えさせたいというケースは非常に多いと思います。
恐らく、メジャーで関わる案件が多く、情報が多いというのが理由かと思っています。
そのJava教育をコストを掛けずに、Web上のサービスを使って行う方法を提案したいと思います。

###前提条件・環境
・インターネットに繋がるパソコン (or スマホ・タブレット)
・ブラインドタッチができ、基本的なネットリテラシーのある1年目社員

###学習させたい内容
・Java基礎

###所要時間
Java基礎：1コマにつき40分程度を想定

##Webを使った Java基礎 の学習
第１回として、上記「Java基礎」の学習方法を考えて見ます。

###Javaの歴史や、学習意義の意識付け
学習意欲向上を図る為、今から行う学習がいかに自分たちに役立つか説明します。

###覚えるべき項目
基礎としては、以下のようなところでしょうか
・クラス
・メソッドとフィールド
・文の記述
・予約語

###実践する
それでは、「実践する」をしましょう。
以下のWebアプリケーションを使って、学習を進めます。
- [Ideone](https://ideone.com/)

以下に、スケジュールしました。実際の研修の際は、前日の復習を織り交ざると良いと思います。
1日目：[Webを使った新人研修　～Javaを用いた基本的プログラミング編・クラス～](https://qiita.com/fujisystem/items/593bd7ad5467d7a660cf)
2日目：[Webを使った新人研修　～Javaを用いた基本的プログラミング編・メソッドとフィールド～]()
3日目：[Webを使った新人研修　～Javaを用いた基本的プログラミング編・文の記述～]()


～ここまで
LINE BOTをGASで作成

##はじめに
### LINE BOTを作ってみた
* 面白いことをやってみたかった
* LINEという、普段使うツールで楽しさを求めてみた
* gasを使った事がなかったので、試してみたかった
* ***注意→最近gasでスクリプトを作成する場合は、申請？が必要になった***

## 必要なもの
* googleアカウント
* LINE developerアカウント

位でしょうか。。。
APIを使いたいなどあれば、別ですが、今回はこれだけで十分です。

## コーディング
* 今回は、特定の文字列が入力された際に、特定の返信を行えるように実装しました

```
//CHANNEL_ACCESS_TOKENを設定
//LINE developerで登録をした、自分のCHANNEL_ACCESS_TOKENを入れて下さい
var CHANNEL_ACCESS_TOKEN = 'YOU_ACCESS_TOKEN'; 
var line_endpoint = 'https://api.line.me/v2/bot/message/reply';

//ポストで送られてくるので、ポストデータ取得
//JSONをパースする
function doPost(e) {
  var json = JSON.parse(e.postData.contents);

  //返信するためのトークン取得
  var reply_token= json.events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  
  //送られたLINEメッセージを取得
  var user_message = json.events[0].message.text;  

  //返信する内容を作成
  var reply_messages;
  if ('かっこいい' == user_message) {
    //かっこいいと入力された際
    reply_messages = ['「' + user_message + '」ですね？\n' + '「' + user_message + '」はこちらになります。\n' + 'https://hogehoge.com',];

  } else if ('かわいい' == user_message) {
    //かわいいと入力された際
    reply_messages = ['「' + user_message + '」ですね？\n' + '「' + user_message + '」はこちらになります。\n' + 'https://hogehoge.com',];

  } else if ('普通' == user_message) {
    //普通と入力された際
    reply_messages = ['「' + user_message + '」ですね？\n' + '「' + user_message + '」はこちらになります。\n' + 'https://hogehoge.com',];

  } else {
    //かっこいい、かわいい、普通が入力されたときの処理
    reply_messages = ['「かっこいい」、「かわいい」、「普通」で入力してくださいね！'];
  }

  // メッセージを返信
  var messages = reply_messages.map(function (v) {
    return {'type': 'text', 'text': v};    
  });    
  UrlFetchApp.fetch(line_endpoint, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': messages,
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
```
上記で出来上がりです。
では実際にビルドしてみましょう。

* ファイル→保存
* 公開→WEBアプリケーションとして導入...
    * プロジェクトバージョン→新規作成
    * 次のユーザーとしてアプリケーションを実行→自分
    * アプリケーションにアクセスできるユーザー：全員（匿名ユーザーを含む）
    * 更新
* ここで表示される現在のウェブアプリケーションのURLをメモ
    * のちのWebhook URLで設定します

### 実装は以上です！！

## 次に、LINE developerの用意
* 色々なやり方があるみたいですが、現在は日本語に対応しているので割と簡単に登録が出来ます

## LINE developerの設定
* Webhook URLを設定する（要SSL通信）
    * Webhook URLはgasで作成したURLを設定します
        * LINE developerに登録をしてから、反映されるまで2~3時間位かかるみたいです
            * botにコメントを流して、レスポンスが返ってきたらOKです。
            * 次回以降は、ソースの更新を行えば、すぐに反映されます！
* 待っている間に、設定を進めましょう！
    * 設定値は下記の通りでbotが出来ます
        * アカウント設定 > bot設定 でまずは「APIを利用する」
        * Webhook送信 「利用する」
        * 自動応答メッセージ 「利用しない」（お好きにどうぞです！）

### 設定は以上です！！
あとはとにかく遊んでみて、色々修正してみて下さい！
AIのAPIなども使えるので、もっと面白いbotが出来ると思います。
そこらへんは、次回の更新で出来れば。。。
elasticbeanstalk keyを指定すると22番ポートがanyに解放されるのの対策

## SSHする必要性
そもそも elasticbeanstalk で立ち上げるのに `ssh` する必要はないと思いますが、必要な方へ。

## SSHキーを指定すると問答無用で22番ポートはanyに解放される
[eb create](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb3-create.html
) の`-k`パラメータ指定でも[eb ssh](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb3-ssh.html) でも `eb deploy` 時に `.ebextensions` で指定されててもanyに解放されてしまう。

## eb ssh はセキュリティグループのルールに従うが・・
`eb ssh` の仕様にあるように「セキュリティグループで22番ポートにルールが指定されていればそのルールに従い、なければanyで解放する」という挙動も create 時にはなさそう。

## .ebextensions とセキュリティグループの合わせ技で閉じる
下記ファイルでポートを閉じつつセキュリティグループで開けるという方法を取る。

```text:.ebextentions/010-autoscaling.config
option_settings:
  aws:autoscaling:launchconfiguration:
    EC2KeyName: {key-name}
    # keyを指定すると自動で開かれてしまうインスタンスの22番ポートを閉じる
    SSHSourceRestriction: tcp, 22, 22, 127.0.0.1/32
    # 22番ポートはsecuritygroupで管理する
    SecurityGroups: {security-group-name}
```
[参考](http://blog.tagbangers.co.jp/2017/08/14/beanstalk-deny-ssh-port)

## まとめ
`ssh`しなくてもいいように開発しましょう。
Macの画面操作をショートカット化する方法

## 前提条件

* ブラウザはChromeを利用
* OSのバージョンはmacOS High Sierra(10.13.2 2018/1/31時点)
* よく使うものを抜粋して記載

|表記|キー|
|:--:|:--:|
| ⇧ | Shift |
|⌥|Option(alt)|
|⌘|Command|
|^|Control|

## Chromeの操作
### タブ移動
　　⌥⌘ [左右矢印]
### タブ閉じる
　　⌘w

## 画面移動
　^[左右矢印]
　^[画面の数字に対応した数字キー]
　※設定が必要([macOSでディスプレイ1枚で作業する技術](https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60))

## ウィンドウ操作([Stactacle](https://www.spectacleapp.com/)を利用)
* ウィンドウを寄せる  
⇧⌘ [上下左右矢印]
* 最大化  
⌥ ⌘ F

その他良いショートカット等あればコメント欄にて教えてくださると助かります。
IBM MQ : AMQ7017 ログ破損エラーで起動できないキューマネージャを復旧する手順

# はじめに

IBM（WebSphere） MQキューマネージャが「AMQ7017：ログが使用できません。」で起動不能になった時、地味に対応に困るので、その復旧方法を覚書しておくことにした。

# AMQ7017:ログが使用できません
AMQ7017エラーは、IBM MQのトランザクション・ログが何らかの理由により壊れて使えない状態である。このエラーになるとキューマネージャは開始できず。完全障害状態となる。意外に元に戻すための情報がなく、ググってみると困っている人が結構いる。

```
strmqm IBMMQMGR

WebSphere MQ キュー・マネージャー '' を開始しています。
AMQ7017: ログが使用できません。
```

我がチームの開発サーバでこの状態が起きた。どうやらサーバのディスク不足との理由で、誰かが”ログ・ファイル”と思われるものを次々削除した模様。 大変なログ違いなのだが、MQを知らないとこうしたミスが発生する。多分、データベースのログであれば、こんな真似はしないだろうと思う。

IBM Knowledge Centerの解説によると、AMQ7017の対処は、キューマネージャはバックアップを取得しておくべきで、バックアップからリストアするのが正しい見解のようである。本番ならともかく、開発環境なので、バックアップがない。他に復旧方法がないか模索したところ、次を発見。

# ログ・エラーからキューマネージャを復旧する
AMQ7017エラーでMQが起動不能になったら、MQ-HAを作成する考え方が応用できそう。バックアップからのシステム・リストアよりも簡単なので、代わりに以下を行う。

## 1).キューマネージャの構成フォルダ(と配下のファイルすべて)を退避
AMD7017はMQログ・ファイルの破損であるから、ログだけなんとかすればいい。MQ構成は使用可能なので、構成はそのまま使えるよう、一旦構成を、別の場所に退避する。

```
cd /var/mqm/qmgrs
mv <キューマネージャ名> <キューマネージャ名>_org
cp -r <キューマネージャ名>_org <キューマネージャ名>
```

デフォルトは/var/mqm/qmgrsのキューマネージャ名で構成情報格納フォルダが作成されている。このフォルダをまるごと別のフォルダにコピーすれば構成退避できるが、できるだけオリジナルのまま残して起きたいので、オリジナルを別名に写し、更に元の名前でコピーし直す。

キューマネージャの作成（crtmqm）時、-md オプションで構成ファイルの場所を/var/qmgrs以外の場所に指定していた場合、/var/mqm/qmgrsと、-mdで指定したフォルダの両方に<キューマネージャ名>フォルダが出来上がっている（今回の場合もそうであった）。その場合、両方の<キューマネージャ名＞フォルダをバックアップしておく。

## 2).キューマネージャ・ログ・フォルダはそのまま（放置）
キューマネージャのコミット・ログは、デフォルトでは/var/mqm/logsに<キューマネージャ>フォルダの下に格納される。crtmqm時、-ldで別場所を指定していた場合は、指定先（のキューマネージャ名）にログ格納される。 いずれにせよ、AMD7017状態では基本的にはログ破損しているので、ログは特に残す必要はない。

## 3).キューマネージャを削除する
（一瞬躊躇するが、）構成はバックアップ済みなので、安心してキューマネージャを削除する。キューマネージャの削除にはdltmqmコマンドを使用する。MQ管理者権限を持つ、ユーザで削除を行う。
```
dltmqm <キューマネージャ名>
```

## 4).同じ名称で再びキューマネージャを作成する
同じ名前のキューマネージャを、あらためて作成する。<br>
MQ構成ファイルの格納場所やログ格納場所を前回と同一にする必要があるので、/var/mqm/qmgrs,/var/mqm/logsフォルダ以外を使用している場合は、-md,-ldオプションを忘れず指定する。

```
crtmqm <キューマネージャ名>    
crtmqm -md 構成フォルダ -ld ログ・フォルダ  <キューマネージャ名>

キュー・マネージャー ’’のデフォルト・オブジェクトを作成または置換しています。
デフォルト・オブジェクトの統計 : 作成 82、置換 0、失敗 0
設定を完了中です。
設定が完了しました。
```
キューマネージャの作成後、ここではキューマネージャを開始(strmqm)しない。

## 5).退避しておいたキューマネージャ構成を戻す
作り直したキューマネージャの構成を、1)で退避しておいたキューマネージャ構成に置き換える。

```
cd /var/mqm/qmgrs
mv <キューマネージャ名> <キューマネージャ名>_temp
mv <キューマネージャ名>_org <キューマネージャ名>

```
<キューマネージャ名>_tempに移したフォルダは必要ないので、頃合いを見て削除する。<br>
ログが格納されているフォルダは、何も処置しない。

## 6).キューマネージャを開始してみる
再作成したログ・ファイル（フォルダ）で、過去のMQ構成を使用してキューマネージャを開始する。

```
strmqm <キューマネージャ名>

WebSphere MQ キュー・マネージャー '' を開始しています。
ログのやり直しフェーズ中に、キュー・マネージャー '' で 50 ログ・レコードがアクセスされました。
キュー・マネージャー '' のログのやり直しが完了しました。
キュー・マネージャー '' のトランザクション・マネージャーの状態が回復されました。
WebSphere MQ キュー・マネージャー '' が V8.0.0.x を使用して開始されました。
```

キューマネージャ名が同じなので、新しいログ・ファイルを使って、旧構成のキューマネージャがうまく起動してくれるようである。ただし、循環ログの場合のみ確認。リニア・ロギングでうかく行くか不明。
もともと、循環ログ・ファイルの本数を増やして置いたのだが、リカバリー処理により、いい感じに数を戻してくれた。これまでと同じ状態で稼働した模様。

# おわり
心配なので、稼働後のキューマネージャ状態を確認。DISPLAY QMGR の内容OK、DISPLAY QL(*）の内容OK、CHANNEL、その他構成OK。大丈夫であった。

この方法は、Unix版、Windows版のMQで利用できる。 Windowsの場合は/var/mqm/qmgrsやlogsフォルダをC:¥ProgramData¥IBM¥MQ¥qmgrs,logsに読み替える。

IBM Knowlege Centerの推奨する方法、「そのファイルのバックアップ・コピーか、キュー・マネージャー全体を復元してください」が正式作法。自己判断、自己責任。

# リンク
IBM Knowledge Center
https://www.ibm.com/support/knowledgecenter/ja/SSFKSJ_9.0.0/com.ibm.mq.ref.doc/amq7.htm
JARファイル入門

本文では初学者用（自分用）に、JARファイルの作成から使用までをまとめていきたいと思います。

JARファイルは複数のJavaのクラスやパッケージを一つのファイルにまとめたものです。
これを作成するには、``jar``コマンドを用いるのが良いです。``jar``コマンドはJDKをPCにインストールしていれば使用できます。

## 1. 今回の開発環境
以下の条件で、jarファイルを作成していきます。

```
・マシン: MacBook Air 2017
・OS： macOS High Sierra(10.13.3)
・Javaバージョン: 9.0.4
```

また本来JARファイルは複数のJavaのクラスやパッケージを一つのファイルにまとめる際に便利なものなのですが、今回は簡単の為に、パッケージもクラスも一つのみを取り扱います。


## 2. JARファイルにまとめるJavaクラスの作成

まず今回の例に使用する``Test.java``を``~/Documents/test/``の中に作成します。
``test/``は自身で作成しました。
以下は作成したクラスの内容です。

##### Test.java
```java

package test;

public class Test {
 public static void main(String args[]){
    System.out.println("Hello World!");
  }
}
```

JARファイルは``.java``ファイルではなく``.class``ファイルを使用するので、``javac``コマンドでコンパイルする必要があります。

```
test username$ javac Test.java
```

今回はパッケージ指定しているので、このプログラムを``java``コマンドで実行して結果を確認する為には、``test/``ディレクトリではなく``Documents/``ディレクトリで以下のコマンドを実行する必要があります。

```
Documents username$ java test.Test
Hello World!
```

これで``~/Documents/test/``のなかに、``Test``クラスが作成されました。

## 3. JARファイルを作成
続いて``jar``コマンドでJARファイルを作成します。
``jar``コマンドについては[こちらのサイト](https://docs.oracle.com/javase/jp/1.5.0/tooldocs/windows/jar.html)にオプションなども含めて詳しく書いてあります。

では早速以下の``jar``コマンドでJARファイルを作成しましょう。

```
Documnets username$ jar cvf Test.jar test/
```
オプションの内訳としては

・c： JARファイルを新規作成する
・v：詳細な情報を画面に出力する
・f：JARファイル名を指定する

です。

つまり

```
Documnets username$ jar cvf [新規作成するJARファイルの名前] [JARファイルに含めたいJava
プログラムが入っているディレクトリ]
```

というふうになっています。
このコマンドを実行した後以下のコマンドを実行するとこのような感じの結果が表示されるはずです。

```
Documents username$ jar tvf Test.jar
     0 Wed Jan 31 16:20:16 JST 2018 META-INF/
    88 Wed Jan 31 16:22:12 JST 2018 META-INF/MANIFEST.MF
     0 Wed Jan 31 15:06:50 JST 2018 test/
   419 Wed Jan 31 16:06:06 JST 2018 test/Test.class
   122 Wed Jan 31 15:06:50 JST 2018 test/Test.java
```

これでJARファイルは作成されました。

## 4. JARファイルにメイン・マニフェスト属性を追加

早速JARファイルを``java -jar``コマンドを用いて実行してみましょう。
そうすると

```
Documents username$ java -jar Test.jar
Test.jarにメイン・マニフェスト属性がありません
```
というような結果が出力されるはずです。
これは、``java -jar``で実行された時に呼び出されるMainメソッドは、どのクラスのMainメソッドなのかを設定していないために起こります。

これが起こらないように``MANIFEST.MF``にメイン・マニフェスト属性を追加してあげる必要があります。
追加の方法としては、``.mani``というマニフェストファイルを、JARファイルが存在するディレクトリに作成したあと、そのファイルの中に以下のような内容を記述します。

```
Main-Class: test.Test
```
内訳としては、``Test.class``が所属しているパッケージの後に、呼びだしたいMainメソッドを保有しているクラス名を記述します。
今回は``Test.java``に``package test;``と書いたので``test``が``Test.class``が所属しているパッケージです。

このようにしてマニフェストファイルを作成した後、以下のコマンドを実行します

```
Documents username$ jar uvfm Test.jar Test.mani
```

これで``MANIFEST.MF``の中にメイン・マニフェスト属性が追加されました。
``MANIFEST.MF``の内容を確認してみると以下のようになっていると思います。

```
Manifest-Version: 1.0
Created-By: 9.0.4 (Oracle Corporation)
Main-Class: test.Test 
```

## 5. JARファイルを実行
ここまでくれば、``java -jar``コマンドでJARファイルを実行出来ると思います。

```
Documents username$ java -jar Test.jar
Hello World!
```

もしかしたらクラスパスを指定しないと実行できない場合があるかもしれません。
そういう時は、``~/.profile``に以下の文を追加します（ファイルがなかったら作成してください）

```
export CLASS_PATH=/Users/username/Documents/Test.jar
```


以上がJARファイルの基本です。
自分もまだまだ初学者なので、コメントでの本文に対するご指摘など、是非お願いします！
渡された数値をある範囲から別の範囲に変換する方法について

タイトルが長くなってしまいましたが、やっている事としてはProcessingで言う[map](https://processing.org/reference/map_.html)関数の実装です。
こちらの関数ですが、他の環境だと実装されていない事もあったりするので、自前実装する際の参考用に計算式をメモ。
※C#で記載してます。

```csharp
/// <summary>
/// 渡された数値をある範囲から別の範囲に変換
/// </summary>
/// <param name="value">変換する入力値</param>
/// <param name="start1">現在の範囲の下限</param>
/// <param name="stop1">現在の範囲の上限</param>
/// <param name="start2">変換する範囲の下限</param>
/// <param name="stop2">変換する範囲の上限</param>
/// <returns>変換後の値</returns>
float Map(float value, float start1, float stop1, float start2, float stop2)
{
    return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
}
```

関数についてザックリと説明すると表題にもある通り、
渡した値(`value`)をある範囲(`start1` ~ `stop1`の間)から別の範囲(`start2` ~ `stop2`の間)の相対的な位置に変換します。

例を記載すると下記のようなイメージ。

```csharp
float val, result;

// 変数valは範囲A(下記で言うと20～80の間)に収まる値が入る
val = 20f;
// 20～80の間の数値を100～200の間の数値に再マッピング
result = Map(val, 20f, 80f, 100f, 200f);
Console.WriteLine(result);                  // 100

val = 30f;
result = Map(val, 20f, 80f, 100f, 200f);
Console.WriteLine(result);                  // 116.6667

val = 50f;
result = Map(val, 20f, 80f, 100f, 200f);
Console.WriteLine(result);                  // 150

val = 80f;
result = Map(val, 20f, 80f, 100f, 200f);
Console.WriteLine(result);                  // 200
```



# 参考/関連リンク

- [map() \ Language (API) \ Processing 3+](https://processing.org/reference/map_.html)
- [ある範囲における数値を別な範囲における数値に変換する](https://qiita.com/QUANON/items/188baf469fd493a2f1e6)
JupyterLabでPlotlyのグラフを表示させる

# 問題
JupyterLabでPlotlyのグラフを表示させようとしても何も表示されない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/234668/1a28e8a6-0c66-886d-a70f-2ee767d329a2.png)

[Jupyter Notebookでは有効な対処手段](https://plot.ly/python/offline/#generating-offline-graphs-within-jupyter-notebook)である`init_notebook_mode`を使っても効果がない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/234668/e3734350-a350-9cbe-5057-9b2dbe61f949.png)

# 解決法
JupyterLabに[plotly-extension](https://github.com/jupyterlab/jupyter-renderers/tree/master/packages/plotly-extension)なるものがあるので、それをInstallする必要がある。

```bash
jupyter labextension install @jupyterlab/plotly-extension
```

[`npm`](https://nodejs.org/en/)に依存しているので、installされていない場合はinstallしてください

# 結果
グラフが表示されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/234668/84fc9d63-baf2-1d41-cb06-139f83c6f996.png)

# 余談
JupyterLabの拡張機能はJupyterHubのそれと異なりだいぶ数が少ないですが、GitHubに[jupyterlab-extension](https://github.com/topics/jupyterlab-extension)というTopicがあります。PlotlyのRendererもこちらのTopicに含まれています。

その中でも[jupyterlab-google-drive](https://github.com/jupyterlab/jupyterlab-google-drive)はRealTimeでGoogle Driveと連携できて素晴らしいと目を輝かせたのですが、

> As of November 28th, 2017, Google has deprecated their Realtime API. Existing realtime applications (such as those you may have set up according to these instructions) will still work until December 2018, but new applications will not be able to use the Realtime API. See the discussions here and here for more information.

かなしい…
android http通信

androidエミュレータからlocalhostに接続するときは下のipアドレスを指定する
10.0.2.2

androidで普通にhttp通信をしようとするとメインスレッドで通信を行おうとする方エラーが起きる
そのためansyncを使って非同期処理をさせる
その際 onPostExecuteメソッドの引数に onInBackGroundの結果（String)が入ってるから
通信後のレスポンスを画面に反映させたいときに利用する
Automatorにおけるスクリプトの入出力

# shell script
直前のアクションからはファイル/フォルダのフルパス(POSIXパス)が改行区切りで渡される。入力の引き渡し方法を「引数として」に変更すると以下のコードが自動で挿入されるので、ループの中でファイルに対し処理を行う。

後続のアクションに項目を受け渡したい場合は、`echo`で標準出力にフルパスを出力する。ミュージック関係のアクションでも、ファイルパスから該当のトラックを探し出して実行してくれる。

```bash:シェルスクリプトを実行
for f in "$@"
do
  echo "$f"
done
```

# AppleScript

直前のアクションに応じたオブジェクトが配列として`input`に入っているので、ループを回して処理する。

後続のアクションに項目を受け渡したい場合は、`input`をそのまま返す。自分で用意したオブジェクトを返す場合は、後続のアクションに合わせた種類のものを用意する必要がある。あるいは、フルパスを配列に入れて返しても良い。ちなみに、POSIXパスとHFSパスのどちらを返しても適宜処理してくれる。

```applescript:AppleScriptを実行
on run {input, parameters}

  (* Your script goes here *)

  return input
end run
```

# JavaScript

原則、AppleScriptと同じなので割愛。

```javascript:JavaScriptを実行
function run(input, parameters) {

  // Your script goes here

  return input;
}
```
vagrantでゲストOS側のフォルダをsambaで共有する

vagrant内のファイルをsambaでホストOSに共有する
===

最近phpstormでvagrant内のソースファイルを直接いじる機会が増えました。
ホストOSをwindowsとして使用していると共有フォルダのパーミッションがもともとwindowsのアレなのでゲストOsであまり融通がききません。
ゲストOS側で`chown`や`chmod`しても共有フォルダ内部では変更は無効となります。Vagrantfileで指定することも可能ですがファイルごとにという細かい指定まではできません。

そこで、ゲストOS側のフォルダをsambaで共有することでホストosからアクセスする方法を試しています。

## 環境

|            | バージョン                                |
| ---------- | ------------------------------------ |
| host       | windows 7                            |
| Vagrant    | 2.0.0                                |
| VirtualBox | 5.0.40 r115130                       |
| guest      | CentOS Linux release 7.4.1708 (Core) |

## インストールと起動と自動起動設定

```bash
$ yum install -y samba samba-client
$ systemctl enable smb nmb
$ systemctl start smb nmb
```

selinuxなどセキュリティ関連はゆるゆるにしておく。

## 共有フォルダ

開発用なので`/var/www`を共用にしてます。適宜変えてください。

```bash
$ vi /home/vagrant/sync/smb.conf
```

```
# See smb.conf.example for a more detailed config file or
# read the smb.conf manpage.
# Run 'testparm' to verify the config is correct after
# you modified it.

[global]
	workgroup = WORKGROUP
	security = user

	passdb backend = tdbsam

	printing = cups
	printcap name = cups
	load printers = yes
	cups options = raw

	unix charset = UTF-8
	dos charset = CP932

	hosts allow = 127. 192.168.
	map to guest = Bad User

	guest account = vagrant
[homes]
	comment = Home Directories
	valid users = %S, %D%w%S
	browseable = No
	read only = No
	inherit acls = Yes

[printers]
	comment = All Printers
	path = /var/tmp
	printable = Yes
	create mask = 0600
	browseable = No

[print$]
	comment = Printer Drivers
	path = /var/lib/samba/drivers
	write list = root
	create mask = 0664
	directory mask = 0775

[www]
	path = /var/www/
	writable = yes
	read only = no
	guest ok = yes
	guest only = yes
	create mode = 0644
	directory mode = 0755
```

smb.comfの元のファイルとのdiff

```diff
7c7
< 	workgroup = WORKGROUP
---
> 	workgroup = SAMBA
17,23d16
< 	unix charset = UTF-8
< 	dos charset = CP932
<
< 	hosts allow = 127. 192.168.
< 	map to guest = Bad User
<
< 	guest account = vagrant
44,52d36
<
< [www]
< 	path = /var/www/
< 	writable = yes
< 	read only = no
< 	guest ok = yes
< 	guest only = yes
< 	create mode = 0644
< 	directory mode = 0755
```
## クライアントの接続

ホストOSのエクスプローラーから`\\192.168.33.10\www`としたら見れます。

わたしはwindowsのコマンドプロンプトから下記コマンドでzドライブにネットワークドライブを割当してphpstormから使っています。

```bash
$ net use Z: \\vagrant\www
```

> 参考
> SambaでWindowsファイル共有を行う正しいやり方
> http://inaz2.hatenablog.com/entry/2013/07/07/054616
無料でSlackのbotをとりあえず作ってみたよ

#はじめに
まず最初に，この記事は超超超入門向けです．ご了承ください．

最近何かと話題なbot．

「自分も何か作ってみたい！」と思っても，調べてもよくわからないし何から手をつければいいのかわからない人も多いのでは？？

自分もそうでした．しかもなんかbotとかつくるのはサーバとか借りたりAWSでどうのこうのとかやって絶対お金がかかる物だと思ってました．

しかし，無料でとりあえず作って遊んでみたい程度であれば簡単に作れることがわかったので，どこから手をつければいいのかわからない人や，とりあえず手っ取り早く動くもの作りたい人に向けてまとめたいと思います．

# 準備
まずは，先にnodejsってやつを準備しておく必要があります．

[Node.js公式サイト](https://nodejs.org/en/download/)でインストールできるので自分のOSに合ったやつを選んでください．

次にSlack上での準備です．Slackの[Botの管理ページ](https://slack.com/apps/manage/A0F7YS25R-bots)に飛びます．

そして緑色の`Add Configuration`をクリック．

botのユーザ名を入力してください．今回僕はramちゃんbotを作ります．

そしたら，次の画面で出てくる`Integration Settings API Token`と書いてある欄の`xoxb-XXXXXXXXXX`って感じであるAPI Tokenをコピーしておいてください．

![slack_API](https://qiita-image-store.s3.amazonaws.com/0/185927/b7bba3df-6b43-236f-78dd-4d307deabd8b.png)

ここで`Customize Icon`とかでbotのアイコンを変えることができます．

こんな感じでね．

![ram_Icon](https://qiita-image-store.s3.amazonaws.com/0/185927/1e897ebf-2882-5ffd-1557-89b137bfe14c.png)


色々Slack側での設定が終わったら一番最後の`Save Integration`をクリックして保存しておいてください．


# 実装
それでは実際にやっていきましょう．

まずは

```
mkdir bot
cd bot
```

みたいな感じで適当にディレクトリを作ってそこに移動しておきましょう．

そしてそこで次のコマンドを打ち込みます・

```
npm init
```

これでとりあえずenter連打しておきましょう．

すると`package.json`というファイルができあがります．

そして次．どんどんいきます．

```
npm install --save botkit
```

今回は，botkitというフレームワークを使うのでそれをインストールしておきます．

そしたら次は実際にコードを書いていきます．

難しそうですよね．

でも簡単．

次から書くコードをコピーするだけです．

まずはターミナルでindex.jsを開きましょう．

```
vi index.js
```

そしたら次のコードを写します．

```js:index.js
var Botkit = require('botkit');
var controller = Botkit.slackbot();
var bot = controller.spawn({
  token: process.env.token
}).startRTM(function(err,bot,payload) {
  // 初期処理
  if (err) {
    throw new Error('Could not connect to Slack');
  }
});

//言われたことに対する返答
controller.hears(["こんにちは"],["direct_message","direct_mention","mention"],function(bot,message) {
  bot.reply(message, 'hello');
});
```

一応このコードで書いたbotの動作の説明をすると，Slack上で`こんにちは`とメンションをつけるか，botに直接DMで話しかけると`hello`と返してくれるような動作をします．

するとここまでしているうちに勝手にramちゃんがSlackにオフライン状態で居座っています．

![off_ram](https://qiita-image-store.s3.amazonaws.com/0/185927/b3a58ad7-1207-ab4c-3c31-e2e09f3e0b2a.png)



# 起動
それでは実際にramちゃんを動かしましょうか．

動かす方法もめちゃめちゃ簡単です．

ターミナルで

```
token=xoxb-XXXXXXXXXXXXXX node index.js
```

と打ち込むだけで・・・・・

てってれーん

![on_ram](https://qiita-image-store.s3.amazonaws.com/0/185927/98e226fa-dd64-04c7-a892-f3875cb5b12d.png)


ramちゃんログインしました．

話しかけてみましょう．


![ram_conv](https://qiita-image-store.s3.amazonaws.com/0/185927/0d7b6d12-9859-1695-8830-cdbff87a2809.png)


こんな感じでメンション付けて`こんにちは`というとちゃんと`hello`と返してくれました．

# さいごに
今回はbotkitとnode.jsで必要最小限のbotをとりあえず作ってみました．今はただ挨拶を返すくらいですが，ここからはあなたのアイデアと工夫次第でどんどん便利なbotが作れると思います．

僕は`今日の天気は？`などというと今日の天気予報が載っているwebページを返してくれるようなものも作りましたが，なかなか便利です．自分から検索バーに検索して知るよりも，ramちゃんに聞いて教えてもらった方がなんだかハッピーですよね．

皆さんも色々試してみてください．

最後まで読んでくださってありがとうございました．

# 参考
[botkit使って定期的につぶやくslackbot作る
](http://blog.duck8823.com/entry/2016/05/20/005734)
PayPal 決済画面をソーシャルログインのように使う方法

PayPalのREST APIには、[Indentity](https://developer.paypal.com/docs/api/identity/)という[OpenID Connect](https://ja.wikipedia.org/wiki/OpenID)に準拠した、いわゆるソーシャルログイン向けのAPIがあります。
このAPIを使えば会員サイトの登録やログインに応用できますが、決済とは別の実装をする必要があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/210396/90fcd154-1a6c-4996-3ab0-b60f61317dc0.png)

もう少し手軽に同様の機能を提供する方法として、PayPalの[API決済](https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7)の一部を応用した方法があるので、それをご紹介します。

# 事前承認決済を使った実装方法
1. [こちら](https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7#%E4%BA%8B%E5%89%8D%E6%89%BF%E8%AA%8D%E6%94%AF%E6%89%95%E3%81%84%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)に書いてある事前承認決済を使って実装します。

2. ログイン画面のように見せるために以下のようにカスタマイズします。

```javascript:決済ボタンをログインボタンのように見せるカスタマイズの例
<script src="https://paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&commit=false&disable-funding=credit,card"></script>
// Show a Continue button, not Pay Now.
// Hide other payment methods (e.g. cards)
...
paypal.Buttons({
      style: {
        layout:  'vertical',
        color:   'blue',
        shape:   'rect',
        label:   'paypal',
        tagline: false  // No sub messages
      },   
  ...
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/210396/11766a37-1def-e352-3647-fc82b11403fb.png)

3.ユーザーがログインした後の情報をJavaScriptで入手します。
[こちら](https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7#%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9)の**「PayPalアカウントの個人情報や配送先住所を取得する方法」**に書いてある方法で、ログインしたユーザーの個人情報や住所情報を取得します。

4.上記の情報を会員情報と紐付けて次回のログインなどに応用します。

**※事前承認決済を使った場合は、ログイン後の決済はサーバーサイドのAPI呼び出しのみでできるため、ワンクリック決済のような利便性の高い決済を実現できます。**
WSHでExcelのテキスト差分取得ツールを作るよ

#WSHでExcelのテキスト差分取得ツールを作るよ
以下の仕様

- セル内テキストを比較
- Drag & Dropで、2ファイルを比較
- 比較結果をCsv出力
- 比較結果で、改行は半角スペースで表現

<hr/>
#### 本体（XlsxDiff.wsf）
```html
// UTF-16LEで保存すること.
<job>
  <script language="JavaScript" src="CommonUtil.js"></script>
  <script language="JavaScript" src="XlsxUtil.js"></script>
  <script language="JavaScript">
    // 引数チェック.
    if ( WScript.Arguments.length !== 2 ){
        $.info( "2ファイルをD&Dしてください.", "エラー" );
        WScript.Quit();
    }

    // セル値取得.
    var leftPath = WScript.Arguments( 0 );
    var rigthPath = WScript.Arguments( 1 );
    var leftCellMap = getCellMap( leftPath );
    var rightCellMap = getCellMap( rigthPath );

    // making result.
    var result = [];
    for ( var key in leftCellMap ){
      if ( leftCellMap[key] != rightCellMap[key] ){
        result.push( getResultString( key, leftCellMap, rightCellMap ) );
      }
    }

    for ( var key in rightCellMap ){
      if ( !( key in leftCellMap ) ){
        result.push( getResultString( key, leftCellMap, rightCellMap ) );
      }
    }

    result.sort();
    result.unshift(
      "シート, セル位置, " + $.Fso.getFilename( leftPath ) + ", " + $.Fso.getFilename( rigthPath )
    );

    // CSV出力
    $.AdoDbStream.writeFile(
      $.Fso.getParentFolderName( WScript.ScriptFullName ) + $.FileSeparator + "result.csv",
      result.join( "\n" ), "utf-8"
    );

    // 終了.
    $.info( "done.", "end" );
    WScript.Quit();

    // cellMap.
    function getCellMap( path ){
      var tmpCellMap = {};
      $.Xlsx.withXlsx( path, function( ole, book ){
        $.mapX( book.Worksheets, function( sheet ){
          $.assignObject( tmpCellMap, $.Xlsx.range2AddressMap( sheet.name, sheet.usedrange ) );
        });
      });
      return tmpCellMap;
    }

    // resultString.
    function getResultString( key, leftCellMap, rightCellMap ){
      var sheetName = key.split( "!" )[0];
      var cellAddress = key.split( "!" )[1];
      var leftCellValue = getCellValue( key, leftCellMap );
      var rightCellValue = getCellValue( key, rightCellMap );
      return sheetName + "," + cellAddress + "," + leftCellValue + "," + rightCellValue;
    }

    // cell string.
    function getCellValue( key, cellMap ){
      var cellValue = cellMap[key] ? cellMap[key] : "<no value>";
      return cellValue.replace( /\r?\n/g, " " );
    }
  </script>
</job>
```
<br/>
#### 共通FW（CommonUtil.js）
[こちら](https://qiita.com/fujisystem/items/d0a347707eea116141a9#%E5%85%B1%E9%80%9Afwcommonutiljs)

<br/>
#### Excel用FWっぽいの（XlsxUtil.js）
[こちら](https://qiita.com/fujisystem/items/d0a347707eea116141a9#excel%E7%94%A8fw%E3%81%A3%E3%81%BD%E3%81%84%E3%81%AExlsxutiljs)


## 総括・ハマりポイント
- ExcelのDate型の取り扱いで、嵌った。
- ソースに美意識が足りなかった。
[WordPress] ターム（カテゴリー・タグ）の記事が指定件数以下なら一覧などに出力しない

「[WordPress] ターム（カテゴリー・タグ）アーカイブで記事が指定件数以下なら404扱いにしたい」
https://qiita.com/gatespace/items/a29b0814a308fa2d77d7

上記でアーカイブページを404にしたのだけど、投稿ページ（single.php）カテゴリーやタグの一覧や、ウィジェットのカテゴリーやタグクラウドなど、とにかくリンク自体も出したくない場合。

# 投稿に関する場合

`the_category()`, `the_tags()`, `the_terms()` など最終的には `get_the_terms()` で呼び出してるので大元のフィルターフックで改変。
https://developer.wordpress.org/reference/functions/get_the_terms/

```php:my_get_the_terms.php
<?php
// get_the_terms でタグに所属する投稿が指定した件数より少なかったら表示しない
add_filter( 'get_the_terms', 'my_get_the_terms', 10, 3 );
function my_get_the_terms( $terms, $post_id, $taxonomy ) {
	if ( is_admin() ) { // 管理画面だったら何もしない
		return $terms;
	}
	if ( $taxonomy != 'post_tag') { // 条件分岐はよしなに
		return $terms;
	}
	
	$new_terms = array();
	foreach ( $terms as $term ) {
		if ( $term->count >= 6 ) {
			$new_terms[] = $term;
		}
	}
	return $new_terms;
}
```

## 投稿に関係ないタームの一覧の場合

ウィジェットの「カテゴリー」や「タグクラウド」などなど、タームに関するものは`get_terms()` で呼び出してるので大元のフィルターフックで改変。
https://developer.wordpress.org/reference/functions/get_terms/

なお、4.5.0以降は `get_terms()` のパラメーターでタクソノミーの渡し方が変わってるので注意。

```php:my_get_terms.php
<?php
// get_terms でタグに所属する投稿が指定した件数より少なかったら表示しない
add_filter( 'get_terms', 'my_get_terms', 10, 4 );
function my_get_terms( $terms, $taxonomies, $args, $term_query ) {
	if ( is_admin() ) { // 管理画面だったら何もしない
		return $terms;
	}
	if ( $taxonomies[0] != 'post_tag' ) { // 条件分岐はよしなに
		return $terms;
	}
	$new_terms = array();
	foreach ( $terms as $term ) {
		if ( $term->count >= 6 ) {
			$new_terms[] = $term;
		}
	}
	return $new_terms;
}
```

# Advanced Custom Fields のタクソノミーフィールドの場合
https://www.advancedcustomfields.com/resources/taxonomy/
Objectsにしていた場合は `$term->count` で記事数が取れるのでよしなに条件分岐で弾いてください。
（IDの場合はしちめんどくさいので）

現場からは以上です。
Cloud Functionsの実行環境


headless chromeが使えるか調べたかったので、Cloud Functionsの実行環境を調べてみました。
調査時点ではCloud Functionsの実行環境は以下のようです。

Node.jsバージョン: v6.11.5
Dockerベースイメージ: Debianベースの実行環境で `gcr.io/google-appengine/nodejs` のDockerイメージのコンテンツを含む

参考
https://cloud.google.com/functions/docs/concepts/exec