OmniAICreator/Qiita-1.07M huggingface dataset:
WKWebViewのallowsBackForwardNavigationGesturesとnavigationControllerのジェスチャーを両立させる

# 概要
最近UIWebViewで書いていたコードをWKWebViewに書き換える機会があり、どんな違いがあるかを調査しました。
その中にWKWebView内の履歴をスワイプで戻れる機能を発見。
ここでふと、「WKWebViewとnavigationControllerのスワイプ、どっちが優先されるのか?」と言う疑問が出てきたので、実際に検証してみました。

# 検証方法
1. 最初の画面にてきとーにボタンを配置して、押したらWKWebViewが入っているviewControllerに遷移
2. webView内でページ遷移(今回はGoogleにアクセス→検索をしてみた)
3. スワイプで戻ってみる

# 検証結果

結論から言うと
画面ごと戻ることもあれば、履歴だけ戻ることもあった。
どちらが優先ということはなく規則性はないように見えた。

# 両立させてみた
* 以下の動作をするように変更してみた
  * webViewの履歴があれば履歴を戻す
  * なければ画面を戻す

``` Swift
import UIKit
import WebKit

class WebViewController: UIViewController {
    
    let webView = WKWebView()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(webView)
        
        // スワイプで履歴を戻る/進む有効化
        webView.allowsBackForwardNavigationGestures = true
        
        // navigationControllerのスワイプジェスチャーを制御できるようdelegateにselfを指定
        navigationController?.interactivePopGestureRecognizer?.delegate = self
        
        webView.load(URLRequest(url: URL(string: "https://google.co.jp")!))
    }
}

extension WebViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        // webViewの履歴がなければnavigationControllerのスワイプジェスチャーを有効化
        return !webView.canGoBack
    }
}
```
bashのショートカット備忘録

# Bashのショートカットキー

ネットで多くの方が載せていますが、自分なりに整理してみます。
今回載せる内容はbashのマニュアルから抜粋した内容がほとんどですので、
そちらを見たほうが確実です（あくまで私の備忘録です）

C - x:Ctrlとxの同時押し
M - x:メタキーとxの同時押し（メタキー：Esc,Altなど）

## 移動コマンド

|コマンド|操作|
|:--:|:--|
|C - a|現在の行の先頭に移動|
|C - e|現在の行の末尾に移動|
|C - f|一文字進む|
|C - b|一文字戻る|
|M - f|次の単語の最後に進む|
|M - b|現在or直前の単語の最後に戻る|
|C - l|現在の行を画面の一番上にして画面をクリア|

## 履歴操作

|コマンド|操作|
|:--|:--|
|C - p|履歴リストから前の行を取り出す|
|C - n|履歴リストから次の行を取り出す|
|M - <|履歴の最初の行を取り出す|
|M - >|履歴の最後の行を取り出す|
|C - r|現在の行を起点に履歴を遡って検索（インクリメンタル検索）|
|C - s|現在の行を起点に履歴を下って検索（インクリメンタル検索）|
|M - p|現在の行を起点に履歴を遡って検索（非インクリメンタル検索）|
|M - n|現在の行を起点に履歴を下って検索（非インクリメンタル検索）|
|M - ./M - _|前のコマンドの最後の引数を挿入|

## テキスト編集のためのコマンド

|コマンド|操作|
|:--|:--|
|C - d|次の一文字を削除|
|M - t|カーソル下の単語とカーソル前の単語を入れ替える|
|M - u|カーソルから単語の最後まで大文字にする|
|M - l|カーソルから単語の最後まで小文字にする|

## キルとヤンク
|コマンド|操作|
|:--|:--|
|C - k|カーソルから行末までキル|
|C - u|カーソルから行頭までキル|
|M - d|カーソルから単語の最後までキル|
|C - w|カーソルから単語の最初までキル|
Fラン大学生のウェブ制作日記2 (PHPによるログイン画面の作成）

はいどーも！本日３度目の投稿になるハルちゃんです！
前々回は画像の投稿画面について、前回はMySQLでよく忘れるカラム制約のあれこれについて投稿いたしました。
今回は簡易的なログイン画面を製作したいと思います。
<h1>ログイン画面の作成方法</h1>
- テーブルの作成、カラム（マスタデータ）の作成
- ログイン画面の作成
- ログイン処理

以上を作っていきたいと思います。
それではまず、テーブルを用意します！
<img width="580" alt="スクリーンショット 2018-03-17 23.08.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/73228059-dd62-2d63-88ce-d0067427eb20.png">

こんな感じでprimary keyをセットでつけてあげて
ログイン画面の処理ですねー

<img width="476" alt="スクリーンショット 2018-03-17 23.13.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/a30be548-d9c7-2ef3-c657-e790e97afa8e.png">

画面はこんな感じになると、、、

<img width="453" alt="スクリーンショット 2018-03-17 23.17.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/354d9989-033c-952c-e99e-66d2b1d8967b.png">

処理です。
<img width="689" alt="スクリーンショット 2018-03-17 23.18.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/bb8ceb3d-3c29-0254-80e4-a5df6697f258.png">
$dsn = データベース名とホスト名を記載（これは自分のデータベースの名前を入れてあげます。）
$user = データベースを使っているユーザー名を記載
$password = データベースのパスワードを記載
上記3つがどれか違う場合try...catchで例外を処理します。

$password_verify でハッシュ化したパスワードと入力したパスワードの一致を調べ、OK であれば認証成功します。

ハッシュ化するにはpassword_hashという関数を使うことー。
この記事読んでコメントがある方はよろしくお願いします！
ご静聴ありがとうございました。
Railsで初めてHTMLとCSSを書いて、得た反省(コツの参考に)

最近自分が作っているサービスのベータ版が、完成間近になってきました。
最初はサーバーサイド、後からフロントっていう形で書いているので最近はもっぱらフロントです。

一通り、htmlとcssを経験できたので、こうしとけばよかったなあというものを自分なりにまとめました。
もちろんまだまだ初心者なので、浅い反省かもしれませんが参考にしていただければと考えています。
列挙した反省要素にまとまりは特にありません。
以下反省です。

#classの命名超大事
これはフロントに限らないかもしれませんが、class命名は大事です。パッとみたときに画面のどこをさしているのかわかると、ストレスなくコーディングできます。chromeの検証使って毎回探しに行くのは本当にしんどい。。。
しかもclass名が被っていることを知らずに、同じclass名書いていたなんてこともありました。。。
自分は以下の２つを気にして書いています。
1.controllerの名前を最初につける
user_controllerのhtmlであれば、class名にuser_hogehogeとか書くべき。わかりやすいし、class名が被ることも防げます。
2.長くなってもいいから詳細に書く
これはリーダブルコードにも書いてあった気がしますが、わかりづらいくらいなら、長いクラス名にしてしまった方がいいです。
#アクションごとにcssも分ける
railsにおけるcssはこのファイルに記述しなければならないみたいな決まりはありません。htmlとcontrollerはありますけど。。
次からは、アクションごとにcssファイルを分けようと思います。user_controllerのshowアクションはshow.scss、newはnew.scssという感じです。
#どのhtmlに対応しているかをコメントで記述する
cssはプロパティごとに行が変わるため、縦に長いコードになりやすいです。
そうなるとこのhtmlに対応しているセレクタどこだっけ？みたいなのによくなります。
なので、コメントを逐一書きましょう。
例えばコメントはこんな感じです。=> /*ここから先はレスポンシブ対応*/
そうすることでレスポンシブはここから先だということが一発でわかります。
#styleは基本使わない
htmlに直書きでcssを記述できるstyleですが、レスポンシブに全く対応できません。
styleは書かず、極力cssファイルに記述するようにしましょう。
#大きい枠から作る
html、cssを書くときは紙やペンで一度構成を絵にしてからがいいです。さらに実装するときは大きい枠から先に作っていきましょう。そうしないと、大きい枠を変えたら、小さい枠もその度に変えていかなければなりません。大きい枠が小さい枠を囲んでいれば、大きい枠を動かせば小さい枠も同時に動きます。絵を描くことで、どの枠にどの枠を入れ込むかを考えやすくなります。
#画像はバンバン使っていいと思う
htmlやcssで作ることができない（そんなことはないのでしょうが、自分のレベル的に。。）要素が時々ありました。
例えば、横の黒一本線をただ引くって、cssだと結構難しいです。なのでsketchで作っていました。もちろんそれが正しいコーディングかは賛否両論あると思いますが、スピード重視であれば良いかなと思います。



上に書いたやり方は正しくないかもしれませんし、もっと良いやり方があるかもしれません。
それはこれから勉強していきます！
BasicObjectで雑なテンプレートエンジンみたいなものを作る

テキストで雛形を作って、てきとーにそこに値を埋め込みたい。
埋め込む値は、どっか他から与えられる。

どうすんのかなぁ、と思って、試しに雑に作ってみた。

```my_template.rb
class MyTemplate < BasicObject
  def initialize(template, parameters={})
    @template = template
    @parameters = parameters
  end

  def compile
    instance_eval("\"#{@template}\"")
  end

  def method_missing(name, *args)
    return @parameters[name] if @parameters.key?(name)
    super
  end
end
```

使い方は、こんな感じ。
第一引数にテンプレートの文字列、第二引数に埋め込みたい値を持ったHashを与える。

```sample_code1.rb
template = MyTemplate.new('Hello, #{name}!', { name: 'World' })
template.compile #=> Hello, World!
```

埋め込みたい値の名前はマルチバイト文字列もやろうと思えばできる。

```sample_code2.rb
template = MyTemplate.new('Hello, #{名前}!', { %s"名前": 'World' })
template.compile #=> Hello, World!
```

`BasicObject`の`instance_eval`を使うことで、他の定数やクラスは見えない。
そのため、ある程度は悪いことはできないようにできていそう。

```sample_code3.rb
template = MyTemplate.new('Hello, #{Dir.glob("./**/*.rb")}!', { name: 'World' })
template.compile #=> NameError (Dir cannot be autoloaded from an anonymous class or module)
```

実際のテンプレートエンジンのソースを読んだことないので、これと近いことをしているのかはわかりません。
【 Swift4】高さが可変のUIViewを実装する

## 実行環境
【Xcode】Version 9.2
【Swift】Version 4.0.3

## 概要
ドラッグ(パン)で高さが変わるUIViewを実装する。

![Untitled3.gif](https://qiita-image-store.s3.amazonaws.com/0/238595/cf772494-69a5-f758-7ec5-051906d3e221.gif)

## 実装

```swift
let testView = UIView()

override func viewDidLoad() {
    super.viewDidLoad()
        
    //対象のUIViewを作成する
    self.testView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height / 2)
    self.testView.backgroundColor = UIColor.green
        
    //panジェスチャーのインスタンスを作成する
    let gesture = UIPanGestureRecognizer(target: self, action: #selector(panGesture(_:)))

    //ジェスチャーを追加する
    self.testView.addGestureRecognizer(gesture)
        
    //Viewを追加する
    self.view.addSubview(self.testView)
}
    
@objc func panGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
    //移動量を取得する
    let move = gestureRecognizer.translation(in: self.view)
        
    //y軸の移動量をviewの高さに加える
    self.testView.frame.size.height += move.y
        
    //移動量をリセットする
    gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)
}
```

## おまけ
`UIPanGestureRecognizer`の `state`を使うと、ドラッグ中や指を離した時の処理を分けることができます。
`gestureRecognizer.state`は、`.began`→`.changed`→`.ended`と変化します。

```swift
@objc func panGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
    //これを追加する
    switch gestureRecognizer.state {
    case .changed:
        self.testView.backgroundColor = UIColor.blue
    case .ended:
        self.testView.backgroundColor = UIColor.green
    default:
        break
    }   

    //移動量を取得する
    let move = gestureRecognizer.translation(in: self.view)
        
    //y軸の移動量をviewの高さに加える
    self.testView.frame.size.height += move.y
        
    //移動量をリセットする
    gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)
}
```

![Untitled3.gif](https://qiita-image-store.s3.amazonaws.com/0/238595/2b31ecdb-3850-1504-514f-ba4b481386a9.gif)
PYNQで無線LAN接続ができなかった話

PYNQ-Z1で無線LANが使えると便利だなと思って始めたこと。
PYNQと言えど所詮Ubuntuだろうと、タカをくくってやってみましたが、できなかった話です。
PYNQのアーキテクチャがarmだし一筋縄にはいかなかった、という結論。

PYNQ内のNotebookによると、
http://pynq:9090/notebooks/common/usb_wifi.ipynb
Raspberry Piで使われるRAlinkのwifiドングルを使ってね、的なことが書いてる。
それもそのうち買ってみるか。

なので、以下はやったけどできなかった。というお話になります。
けどそこに至るまでにやったことをメモとして残しておく。

---
調べてみると16.04.2にすればなんかできるっぽい。
PYNQのUbuntuのバージョンを調べてみると、

```
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
```

と、16.04だったので、なんかいけそう。
ということでやってみる。

# まずはaptができるようにMacBook経由でインターネットに接続？
なんかいきなり回り道しているような気がするが、とりあえずやってみる。

構成を簡単に書くとこんな感じ。
PYNQ-Z1(1) <-Ethernet-> (2)MacBook(3) <-Wi-Fi-> (4)Router経由のインターネット
それぞれのIPアドレスは
1. 192.168.2.99
2. 192.168.2.1
3. 192.168.1.7(DHCP)
4. 192.168.1.1
となっています。

# PYNQのネットワーク設定。
シリアル接続でPYNQに繋いででネットワークの設定を変えていきます。
シリアル接続の方法は[前回の投稿](https://qiita.com/sachioksg/items/218dc622388250434088)を参照

```shell:/etc/network/interfaces.d/eth0 
auto eth0
iface eth0 inet dhcp

auto eth0:1
iface eth0:1 inet static
address 192.168.2.99
netmask 255.255.255.0
gateway 192.168.2.1 # 追記
dns-nameservers 192.168.1.1 # 追記
```

上記の変更後↓

```shell
sudo service networking restart
```

という感じで、DefaultGWをMacBookにしたり、nameserverをMacBookの先のRouterにして、
networkサービスを再起動します。

# MacBook側の設定。
MacBookで、EthernetからWi-Fiに流す設定をします。設定はシステム環境設定の共有から。
<img width="780" alt="スクリーンショット 2018-03-17 16.35.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/154693/ebe5e3c9-e36b-51d9-6695-112e8d2dc4be.png">
インターネット共有を選択して、

* 「共有する接続経路」はWi-Fi
* 「相手のコンピュータでのポート」はEthernet（図ではUSB 10/100/1000 LAN）
* 左側の「インターネット共有」のチェックボックスをON

<img width="780" alt="スクリーンショット 2018-03-17 21.37.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/154693/ec30b164-9fe8-874d-71c4-8cc503259d64.png">
上記のようなダイアログが出るので「開始」をクリック。

# PYNQ側で疎通確認。
ここまでの設定で、MacBook経由でPYNQがインターネットに接続できるようになったはず。
疎通確認のためPYNQから`ping 192.168.1.1`を実行して、Routerに接続できることを確認。
さらに`ping ports.ubuntu.com`を実行して、名前解決もできることを確認。

# いよいよupdate, upgrade。
準備は整ったので、16.04.2にバージョンアップしてみます。

```shell
xilinx@pynq:~$ sudo apt update; sudo apt upgrade;
Hit:1 http://ports.ubuntu.com/ubuntu-ports xenial InRelease
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
xilinx@pynq:~$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
```

デーン。出来てない。

# どうしてもできない。
しょうがないので地道にやっていく。
`lspci`で無線LANデバイスを確認しようにも、まず`lspci`が入っていないので、
`sudo apt install pciutils`でインストール。やっぱり何も出ない。。。

今度は`lshw`で確認するために`sudo apt install lshw`でインストール。
`lshw`で見ても、無線LANデバイスは認識されていないご様子。

`lsusb`で見ても、そもそも認識されてない。。。。これはだめか。。。
ということで諦め。

# 使った無線LANデバイス
使ったのはどちらも家に余ってたPLANEXのもの。
[GW-US300MiniS](http://www.planex.co.jp/product/wireless/gw-us300minis/)
[GW-USNano](https://www.planex.co.jp/product/wireless/gw-usnano/)
※自分が持っていたのはGW-USNano2ではなくて、GW-USNanoでした。GW-USNano2であればPYNQ-Z1で使えるようです。
Raspberry Piに固定IPアドレスと一緒に複数DNSを設定する

Raspberry Pi 3B（Raspbian Jessie）に固定IPアドレスを指定する方法はインターネット上にちらほら散見されるが、なぜか複数DNSを設定する方法が見つからなかったので共有する。
非常に単純であるが、以下のようにdomain_name_serversに半角スペースで区切って指定すれば良い。

``` /etc/dhcpcd.conf
interface eth0
static ip_address=12.34.56.78/24
static routers=12.34.56.1
static domain_name_servers=12.34.56.2 12.34.56.3
```
raspberrypiのVoiceKit組み立て準備

# raspberry piのVoiceKitが気になった。
![D3174D64-A1F1-4A86-B0CA-151C7A365223.jpeg](https://qiita-image-store.s3.amazonaws.com/0/35048/1908b0d1-15b8-cc33-9fd8-05b54c3462bc.jpeg)

## 秋月電子に買いに行った。
- Google AIY Voice Kit
![8EFC41C5-E0B0-41B0-A994-E82FE13F1350.jpeg](https://qiita-image-store.s3.amazonaws.com/0/35048/356eb43b-9478-e43b-2a64-ac3f2705d040.jpeg)
![C2C82F3D-D712-4340-B2A2-7219058136CF.jpeg](https://qiita-image-store.s3.amazonaws.com/0/35048/c7313f7f-0ceb-32a8-6f18-489e7182b7f5.jpeg)


- Raspberry pi3 Model Bとアダプタ
![802A760E-D259-4B1B-92F0-C70DEADC73CC.jpeg](https://qiita-image-store.s3.amazonaws.com/0/35048/5fbf2057-d330-3509-b4f9-6de080588fd3.jpeg)

- microSD 16GB


## 家にあるもので流用するもの
- キーボード
- マウス
- HDMIケーブル
- モニタはテレビを使う。

## （無くてもいいかもだけど）買い忘れたもの
- ヒートシンク（Amazonで後ほど購入）
- ![uploading-0]()
kubernetes/client-goでのクライアント初期化

## TL; DR 

`clientcmd.BuildConfigFromFlags(masterUrl, kubeconfigPath string)`はクラスタ内/クラスタ外での実行問わず使えるよ

## `clientcmd.BuildConfigFromFlags`の中身

実は`clientcmd.BuildConfigFromFlags`は引数の`masterUrl`と`kubeconfigPath`が空だと`restclient.InClusterConfig()`を呼んでくれるようになってます。

*なお、client-goのバージョンは`kubernetes-1.9.4`を参照しました。*


#### 該当箇所のソース(抜粋)


```go
func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config, error) {
	if kubeconfigPath == "" && masterUrl == "" {
		kubeconfig, err := restclient.InClusterConfig()
		if err == nil {
			return kubeconfig, nil
		}
	}
	return NewNonInteractiveDeferredLoadingClientConfig(
		&ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
		&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
}
```

>ソースコード全体:
https://github.com/kubernetes/client-go/blob/kubernetes-1.9.4/tools/clientcmd/client_config.go


なので`masterUrl`と`kubeconfigPath`はコマンドラインオプションなどで受け取っておき、常に`clientcmd.BuildConfigFromFlags`を呼ぶようにしておけばシンプルです。

### 実例

[`kubernetes/sample-controller`](https://github.com/kubernetes/sample-controller)に実例があります。

#### 該当箇所のソース

```go
func main() {
	// [...中略...]

	cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
	if err != nil {
		glog.Fatalf("Error building kubeconfig: %s", err.Error())
	}
```

ローカルでのテスト時はコマンドラインオプションで渡す/クラスタ内で実行する際はコマンドラインオプションは明示しないとすることで分岐処理など書かずともシンプルに実装できますね。

以上。
ActiveRecord はそのインスタンスを create したのか update したのか

ある record を save したときに、 create のときだけ次に何かを処理したい（しかも、コールバック以外で）ということがありました。


とりあえず思いついた方法は

```ruby
> record.id_previously_changed?
=> true
```

Rails のコードを読むと

```ruby
    def create_or_update(*args, &block)
      _raise_readonly_record_error if readonly?
      return false if destroyed?
      result = new_record? ? _create_record(&block) : _update_record(*args, &block)
      result != false
    end    
```

https://github.com/rails/rails/blob/78d47aa4bf0bf33a216cc7d9f1c6eeb182f178f4/activerecord/lib/active_record/persistence.rb#L701-L706

ということなので、 create / update を分離しているだけで、それぞれの中を読んでも、特に区別するためのデータはなさそう。
bash: 対象ディレクトリ以下のファイル一覧を更新時間でソートして取得する

# やりたいこと
主題。
ただし。`.git`/`.cache` といった `.` から始まるディレクトリ以下のファイルは除外する。


# 環境
- Linux (Ubuntu 16.04)
- Bash


# Command
```
$ find /var/log -type d -name '.*' -prune -o -type f -printf '%T+ %p\n' | sort | tail -n 3
2018-03-17+11:53:37.7748230000 /var/log/dpkg.log
2018-03-17+11:53:37.8845731000 /var/log/apt/term.log
2018-03-17+11:53:37.8965736000 /var/log/apt/history.log
```

`-type d -name '.*' -prune` で `.` から始まるディレクトリを除外する。
`-type f -printf "%T+ %p\n"` でファイルのmodification time付きでファイル一覧を出す。

```
       -printf format
              True; print format on the standard output, interpreting `\' escapes and `%' directives.  Field widths and precisions can be specified as  with
              the `printf' C function.  Please note that many of the fields are printed as %s rather than %d, and this may mean that flags don't work as you
              might expect.  This also means that the `-' flag does work (it forces fields to be left-aligned).  Unlike -print, -printf does not add a  new‐
              line at the end of the string.  The escapes and directives are:

              %Tk    File's last modification time in the format specified by k, which is the same as for %A.

                     +      Date and time, separated by `+', for example `2004-04-28+22:22:05.0'.  This is a GNU extension.  The time is given in  the  cur‐
                            rent timezone (which may be affected by setting the TZ environment variable).  The seconds field includes a fractional part.

              %p     File's name.
```

対象ディレクトリを引数に指定できるよう関数化したもの:

```bash
function lastmodified() {
    local dir_path=$(readlink -f "$1")

    if [ "${dir_path}" = "" ]; then
        echo "Usage: ${FUNCNAME[0]} DIR_PATH" 1>&2
        return 22
    fi

    \find "$dir_path" -type d -name '.*' -prune -o -type f -printf '%T+ %p\n' | sort
}
```
Chrome拡張機能 を使って Webシステムをカスタマイズ ＝開発環境構築編＝

#はじめに
クラウドサービスが普及し、会社の業務システムもブラウザから利用するようなることが多くなった今日このごろ。各会社の事情に合わせてカスタマイズができるようなサービスも多いですね。

ただ、拡張性はあってもそれが使いやすいかというと・・・。
管理すべきデータの構築に重点が置かれてしまい、操作性が悪く、生産性が落ちてしまうこともあります。

「この処理、ワンクリックでできれば！」
「この項目自動入力してくれれば！」
「この画面、並べて表示できれば！」
と、思うことありませんか？

既存システムのソースを解析してみると、
ここにJavaScriptで処理を加えれば 便利になるのに！！
と思ったことがきっかけでChrome拡張機能を使って
社内の業務システムをカスタマイズしてみることにします。

#Chrome拡張機能とは？
Chromeに新機能を追加し、ブラウザ環境をパーソナライズできる簡易プログラムです。

##Chrome拡張機能で何ができますか？
###ブラウザに機能追加
Chromeに便利な機能を追加できます。
すでに先人たちがたくさんの便利機能を提供してくださってます。
https://chrome.google.com/webstore/category/extensions

### Webサイト/Webシステムをカスタマイズ
Webサイトの表示内容を変更したり、イベントに応じて処理を追加することで、既存システムのカスタマイズを行うことが可能です。

## Chrome拡張機能を開発するには？
###どのように開発しますか？
GUI は HTML/CSS で 処理は JavaScript で 作成します。

###開発に必要なものは？
テキストエディタとChromeがあればOK

#まずは開発環境を整えてみよう！
## プログラムを準備しましょう
### 作成するもの
- マニフェストファイル（manifest.json）
    - JSやHTMLが書きやすく読みやすいものがおすすめ
    - 筆者は [Brackets](http://brackets.io/)を使用しています
- 拡張機能の処理を書くJavaScriptファイル（test.js）

今回はこの2つのみ この2つを 「src」フォルダに入れてください。

### マニフェストファイル（manifest.json）
```json:manifest.json
{
  "name": "TestChromeAddon",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "Chrome拡張機能 Hello World",
  "content_scripts": [
    {
      "matches": ["https://www.google.co.jp/*"],
      "js": ["test.js"],
      "run_at": "document_idle"
    }
  ]
}
```
UTF-8 で 保存してください。
（各項目の詳細は次回記載します。）

### JavaScriptファイル（test.js）
```javascript:test.js
var mode = ["hidden","visible"];
var img = document.getElementById("hplogo");
var count = 0;

if(img != null ){
   blinking();
}

function blinking(){
    img.style.visibility = mode[count];
    count = (count+1) % 2;
    setTimeout("blinking()", 500);
}
```
HTML の 中の ID hplogo の要素を点滅させるプログラムです。

## プログラムを登録してみましょう
1. Chromeで[chrome://extensions/](chrome://extensions/)を開きます
2. 「デベロッパーズモード」にチェックを入れます。
![02＿インストール.png](https://qiita-image-store.s3.amazonaws.com/0/240814/8e663298-cf55-1a2e-6ff8-0b48e1abaa70.png)

3. manifest.json、test.js を保存した 「src」 フォルダを Chromeにドラッグ＆ドロップします

![03＿インストール.png](https://qiita-image-store.s3.amazonaws.com/0/240814/dafac50c-8829-0837-0aaf-55d1a94f453e.png)

4. Chrome拡張機能 TestChromeAddon が登録されます。
![04＿インストール.png](https://qiita-image-store.s3.amazonaws.com/0/240814/27f90f6e-a627-5824-c5d3-e5a5b93404df.png)

## 実行してみよう！
https://www.google.co.jp/ を開いてみてください。
Googleのロゴが点滅しているかと思います。
（IDが変更されていないことを祈ります:pray:）

今回はここまで。
micro:bitを教える際の環境選択に関する考察

#きっかけ

子供達に教える場合の環境について聞かれたので相性診断風(?)にまとめてみました。

#Javascript Block Editor で子供達に教える場合の環境選択（案）

micro:bitは、他のデバイスに比べて教える側の事を考え抜かれており、教える際の負担が非常に低いデバイスの一つだと言えます。とは言え、決められた時間内で多くの子供達に教えなければならない場合は出来る限り、トラブルのリスクが少ない方法を選択する必要があります。
以下の図はあくまでも私案です。教える側の思想・スキル・現場の環境・与えられ時間で大きく異なると思います。

![micobit環境選択案.png](https://qiita-image-store.s3.amazonaws.com/0/44523/c3417a01-0604-cec3-1ebb-c06ceebc4564.png)

※1 Wi-Fi接続の場合、端末の台数分の同時接続実績が無い場合は事前調査が必要です。また、見学者が多数訪れたり、イベント会場で行う場合は、事前調査で大丈夫でも、本番ではチャンネルが輻輳して使えない場合があります。また、子供達がノートPCを持ってくるような場合、古いノートPCだと2.4G帯しか対応しておらず、つながりにくい状況になる可能性があります。このような場合は、有線LANを保険で用意するか、インターネットが確保できないのを前提で準備をする必要があります。

※2子供達がソフトのインストール出来るスキル及び時間的にゆとりがある。もしくは教える側で全端末に事前準備ができる余裕がある場合は、インストールしてしまった方が無用なトラブルで時間を食われずに済む可能性があります。ただ、子供達が自宅に帰ってどんな環境でも続きが出来るようにしたい場合は、ソフトは入れずにブラウザのみで教えた方が良いと思います。

※3 対応ブラウザについては https://makecode.microbit.org/browsers 参照。

※4 dockerを使う方法については https://qiita.com/asondemita/items/76c927a8824a0b6e3af7 参照

※5 Microbit.Uploaderを入れるとダウンロードと同時にインストールしてくれるので便利です。ただ、常駐するタイプなので、PCを再起動しても常に常駐させるようにするには、OS側の設定のひと手間が発生します。https://qiita.com/asondemita/items/a425f1ebd6e117c1e6f2 参照

※6 https://www.microsoft.com/ja-jp/store/p/makecode-for-micro-bit/9pjc7sv48lcx 参照

※7 http://microbit.org/ja/guide/mobile/ 参照。始めのころはBluetoothのペアリングがうまくできない現象が多く発生していましたが、2017年末のリリースあたりからは比較的できるようになってきたようです。ただ、Bluetoothといえどもチャンネル数に限界があります。40人ぐらいで１つの教室で一斉にペアリングを行う実験はした事がありません。電波強度・部屋の大きさ・同じ2.4GHzを使うWi-Fiの状況次第で答えは異なると思いますが、このあたり実際に行われた方がいらっしゃいましたら結果を教えていただけると助かります。

※8※9 ブラウザだけで教える場合の罠としては、ブラウザ種別IE,Edge,Firefox,Chrome,etc 及びOS環境によって、ダウンロードからインストールまでの手順が異なる事です。先日、ある小学校であったのが、Windowsのタブレットモードのブラウザで「ダウンロード」を押した後「保存フォルダを開く」ボタンが表示されないケースがありました。小学校への配備が急速に進んでいるWindowsタブレットの設定によってはこのトラブルで時間を食われる可能性があります。事前調査をし手順を確認しておいた方が良いと思います。

#注意

2018.3.17現在の状況での案です。micro:bitを取り巻く環境は常に変化していますので最新の情報を参照してください。
家庭内の定期的なタスクについてもWunderlistで管理したい(その２)


## 〇まったく役に立たない回答が返ってきた。
前回問い合わせてみた件についての回答が返ってきた。
・[家庭内の定期的なタスクについてもWunderlistで管理したい(その１)＠調査](https://qiita.com/ryo_naka/items/f9fb74a7b442640fbe70#%E3%80%87%E8%AA%BF%E6%9F%BB)

> <回答>
> 私たちに手を差し伸べていただきありがとうございます。
> 期限は可能ですが、時間がないので、我々は、ユーザーが彼が電子メールを送信するときにどこにあるかわからないので、時間帯は異なります。
> 私は私の答えがあなたを助けることを望む。あなたのサポートに感謝し、私たちは良い一日をお祈りしています!
> 
> Thank you for reaching out to us.
> The due date is possible but time is not, since we are not sure where the user is when he sends the email, thus the time zone is different.
> I hope my answer helps you. Thank you for your support and we wish you a good day!


日本語と英語の両方が記載されているのは親切だなとは思ったけど、回答としては何一つ役に立たなかった。


## 〇前回まで
・[家庭内の定期的なタスクについてもWunderlistで管理したい(その１)](https://qiita.com/ryo_naka/items/f9fb74a7b442640fbe70)
→メール送信による登録を調査

## 〇今回の概要
・設定した期間に合わせて、自動で送信する処理を作成
※最終的には画面で設定できるようにする予定だが、
まずはファイルに対して直接書き込んだものをWunderListに設定する部分だけを作ってしまう。


## 〇バックエンド処理
・DBを用意するのがめんどくさいのでファイル読み書きにする。
・１タスクごとにJsonのレコードを作って、設定情報を読み書きする。
・タスクごとにタスク登録日かを判定して、登録対象の場合はメール送信で登録。
　送信した場合は次回タスク登録日を更新

データ項目としては以下を持たせてみる

    ・タスク名
    ・担当名
    ・タスクとタスクの間隔
    ・期限とタスク登録の間隔
    ・次回期限日
    ・前回期限日
    ・次回タスク登録日

・とりあえずサンプルとしていくつかのパターンを設定。
これで思った通りに送信されるかちょっと様子を見てみる。
※本当はこのタイミングでしっかり試験をすればいいんだろうけど、プライベートだとテストをしっかりやるのがめんどくさいので試してダメなら直していく方向で。
隔週、毎週、隔日あたりが思った通りにタスク登録されればたぶん大丈夫でしょ。
２～３日動かしてみた感じだとあってそうな感じ。

ざっくり書くとこんなイメージ

    var list = GetTaskData();
    var now = DateTime.Parse(DateTime.Now.ToString("yyyy/MM/dd"));

    // 通知処理
    var UpdateFlg = false;
    foreach (var TaskData in list)
    {
        if (now <= TaskData.NextNoticeDateTime && TaskData.NextNoticeDateTime <= now.AddDays(TaskData.NoticeToLimit))
        {
            //登録する
            SendMail.Send(TaskData.TaskName + " #" +TaskData.Person+ " " + TaskData.NextLimitDateTime.ToString("yyyy年MM月dd日"));

            //データ更新
            TaskData.LastLimitDateTime = TaskData.NextLimitDateTime;
            TaskData.LastLimitDate = TaskData.LastLimitDateTime.ToString("yyyy/MM/dd");
            TaskData.SetNextDate();

            UpdateFlg = true;
        }
    }
    if (UpdateFlg)
    {
        //一件も更新しなかったときは保存しない
        Write(list);
    }

もちっときれいに書けそうだが、リファクタリングするのもめんどくさいのでこのままにしておく。

## 〇次回以降
・あとはこれらの設定を簡単に登録/更新できる方法を考える。
→たぶんWebAppを作ることになるかな。
【swift 4】△年○月1日は何曜日か？がわかるアプリ

iOSでカレンダーアプリを作る場合、「△年○月1日は何曜日か？」を始めに求めなければいけません。カレンダーのレイアウトに関しては、いろんなサンプルが出ていますので、各月の1日が何曜日かがわかるシンプルなアプリを作ってみました。

![weekdayOfFirstDay.gif](https://qiita-image-store.s3.amazonaws.com/0/193431/90a02b5a-5301-e822-bccb-8fbb84ac9120.gif)

LabelをdateLabel
「<前月」をzengetsuButton、
「次月>」をjigetsuButtonとしました。

```swift

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet var dateLabel:UILabel!
    @IBOutlet var zengetsuButton:UIButton!
    @IBOutlet var jigetsuButton:UIButton!
    
    let now = Date()
    var cal = Calendar.current
    let dateFormatter = DateFormatter()
    var components = DateComponents()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        cal.locale = Locale(identifier: "ja")
        dateFormatter.locale = Locale(identifier: "ja_JP")
        dateFormatter.dateFormat = "yyyy年M月d日EEEE"
        components.year = cal.component(.year, from: now)
        components.month = cal.component(.month, from: now)
        components.day = 1
        calculation()
    }
    
    func calculation(){
        let firstDayOfMonth = cal.date(from: components)
        dateLabel.text = dateFormatter.string(from: firstDayOfMonth!)
    }
    
//<前月 を押した時のAction
    @IBAction func myActionZengetsu(){
        components.month = components.month! - 1
        calculation()
    }
    
//次月> を押した時のAction
    @IBAction func myActionJigetsu(){
        components.month = components.month! + 1
        calculation()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}
```
実際に起動させると、年をまたいでも正確に1日の曜日が求められることが分かります。
fzfを使いMacのアプリを簡単に起動する

# 前提条件

+ macOS 11.4
+ bash 4.4.12
+ fzf 0.17.1

# ターミナルから（一般的な方法）
　Macでターミナル（端末エミュレータ）を使い込んでいくとGUIアプリをコマンドラインで起動したいと考えないだろうか。
（GUIアプリを起動したしても、その操作はマウスを使わなければならない。すくなくともターミナルで引きこもりたい人間からすれば相当気持ち良いはずである。）
　MacのGUIアプリは以下のコマンドで起動できる。

```bash
> open -a <アプリの名前>
```

　システム環境設定の場合、以下のようになる。

```bash
> open -a "System Preferences"
```

　`.bashrc`に以下の記述しエイリアスを作成し、

```bash:.bashrc
alias syspref='open -a "System Preferences"'
```

　タイプ数を短くしてもよい。

```bash
> syspref
```

　上記方法はタイプ数も多く、エイリアスを張ったとしてもあまりスマートでない。とはいえ、アプリ起動するのに専用のランチャーアプリの導入をするのには躊躇いがある。

# 選択的インターフェイス
　ターミナルを使っている方には選択的インターフェイスを提供する（easy finder）というジャンルのソフトを利用している方もいるのではないだろうか。ディレクトリパスを移動したり特定のファイルを書き換えたり、なにかと便利である。
　以下のスクリプトを`.bashrc`に加えると簡単に選択的インターフェイスを使ったランチャーが実現できる。

```bash:.bashrc
  # app - osx appluncher
  app() {
    app_path=$(find /Applications -maxdepth 3 -type d  | grep '\.app$' | sed 's/\/Applications\///' | sed 's/\.app$//' | fzf --query="$1" --prompt="App > " --exit-0)
    if [ -n "$app_path" ]; then
      open -a "/Applications/$app_path.app/"
    fi
  }
```

最近の macOS ではフォルダの構成が変わっているため以下のほうが使いやすいかもしれない

```bash:.bashrc
  app() {
    sapp_list=$(find /System/Applications -maxdepth 3 -type d |
                 grep '\.app$' |
                 sed 's/\/System\/Applications\///' |
                 sed 's/\.app$//' |
                 sed 's/^/S::/')
    aapp_list=$(find /Applications -maxdepth 3 -type d |
                 grep '\.app$' |
                 sed 's/\/Applications\///' |
                 sed 's/\.app$//' |
                 sed 's/^/A::/')
    uapp_dest="/Users/$(whoami)/Applications"
    uapp_dest_sed="s/\/Users\/$(whoami)\/Applications\///"
    # echo $uapp_dest_sed
    uapp_list=$(find $uapp_dest -maxdepth 3 -type d |
                 grep '\.app$' |
                 sed $uapp_dest_sed |
                 sed 's/\.app$//' |
                 sed 's/^/U::/')
    # echo -e $uapp_list
    app_path=$(echo -e "$sapp_list\n$aapp_list\n$uapp_list" | fzf --query="$1" --prompt="App > " --exit-0)
    if [ -n "$app_path" ]; then
      open_path_u="s/U::/\/Users\/$(whoami)\/Applications\//"
      open_path=$(echo "$app_path" |
                    sed 's/S::/\/System\/Applications\//' |
                    sed 's/A::/\/Applications\//' |
                    sed $open_path_u)
      # echo $open_path
      open -a "$open_path.app"
      # preventing open command returns not 0
      :
    fi
  }
```

　上記設定を行うと、

```bash
> app
```

と入力すれば以下のようなインターフェイスで、アプリが起動できる。

<img width="397" alt="スクリーンショット 2018-03-17 20.54.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/147870/18e53131-a8fe-11d4-fd49-9d4a179235ea.png">

## 補足
　fzf以外の選択的インターフェイスを実現する方法でも同様のことが実現できる。

fzf：https://github.com/junegunn/fzf
WiFi電波の強度をヒートマップで可視化できる「NetSpot」を使ってみたら楽しかった

オフィスのWiFiルータが破損したので、ついでに社内インフラを良くするため強いWiFiルータと、コンパクトな中継器に置き換えることになった。作業前と作業後で電波の入り具合が気になっていたのでNetSpotというWiFiマッピングツールを使って可視化してみた。特にスキャンする作業が楽しかった。インフラ案件で活用したい。

![](https://cdn.suin.io/575/0.png)

ヒートマップは赤いほどWiFiの電波の入りがいい。

## NetSpotについて

[NetSpot](https://www.netspotapp.com/jp/)は間取り図にWiFiの電波の強さをヒートマップで可視化してくれるツールで、macOSとWindowsで使える。単体で買うとお値段が、Homeが49ドル、Proが149ドルと高い……。なので今回は、[SetApp](https://go.setapp.com/invite/c079d6d8-8141-4af1-a0e9-01127e935342)(月額9.99ドル)のサブスクリプションで使えるPro版を使ってみた。NetSpotの機能の概要については公式の紹介ビデオを見てもらったほうが分かりやすいと思うので、そちらに丸投げする(マッピングの流れは1分20秒〜を参照):

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/Hw0qs4dTby">https://t.co/Hw0qs4dTby</a></p>&mdash; suin (@suin) <a href="https://twitter.com/suin/status/974965265157926912?ref_src=twsrc%5Etfw">2018年3月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## マッピングのやりかた

### 間取り図を用意する

オフィスや自宅の間取り図を用意する。これが一番の難所ではある。賃貸なら募集図面があるといいが、入居時に捨ててしまっていたので、Google画像検索で探した。運良く見つかったのでそれを使った。

### 間取り図をNetSpotに読みこませる

NetSpotを起動し「Start a new survey」を押す。

![](https://cdn.suin.io/575/1.png)

* 「New project name」は物件名など適当にいれる。
* 「First zone name」は部屋番号など適当に入れる。
* 「Zone's area type」は物件の特性に合わせて選ぶ。
* 「Load from file」を選択し「Choose file」ボタンを押して、間取り図を読みこませる。

![](https://cdn.suin.io/575/2.png)

間取り図のスケールを決めるために、表示された間取り図に2点ピンを立て、その距離を入力する。

![](https://cdn.suin.io/575/3.png)

「Network selection」では特に何もせず「Continue」。

![](https://cdn.suin.io/575/4.png)

### 屋内を歩き回ってスキャンする

MacBookなどを持ち歩きながら、自分が立っている地点にピンをどんどん立てていく。これが結構楽しい。

3点以上、隣接してスキャンすると「STOP SCAN」が押せるようになる。「STOP SCAN」を押すとヒートマップが見れる。

![](https://cdn.suin.io/575/5.png)



### できあがったヒートマップからレポートを作る

ヒートマップができたら、左ペインでレポートに出したいWiFiアクセスポイントを選び、「EXPORT」を押す。レポートは業務業務したPDFレポートや、PNG画像など様々な形式で出力することができる。

![](https://cdn.suin.io/575/6.png)

## 後記

ガチな商用利用は[Airmagnet](https://enterprise-jp.netscout.com/products/airmagnet-survey)がデファクトという情報を頂きました。ありがとうございます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">商用でガチなものだとAirmagnetがデファクトだと思うけど、ライトユーズならこれでもいいかも。 <a href="https://t.co/fedGi5I8op">https://t.co/fedGi5I8op</a></p>&mdash; nakasuji (@takenakasuji) <a href="https://twitter.com/takenakasuji/status/974981755881996288?ref_src=twsrc%5Etfw">2018年3月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
IBM Cloudの無料枠（ライトプラン）にDb2が登場!

いままで有料しかなかったDb2のクラウドサービス（Db2 on Cloud）が、ライトプランという無料枠で使えるようになっています。
ちょっと前はdashDB for transactionsと呼ばれていたサービスです。
https://www.slideshare.net/ibm_analytics_japan/ibm-cloud-87161147

![スクリーンショット 2018-03-17 20.42.13.png](https://qiita-image-store.s3.amazonaws.com/0/119378/3cdea2f7-bc61-524c-1549-3d9720d5d9b0.png)

ためしにデプロイ。Liteを選んで画面一番下の「作成」をクリック。
１００メガまでデータ入れられて、同時接続数は５まで、あと評価用というか開発onlyの用途だそうで。

![スクリーンショット 2018-03-17 20.43.17.png](https://qiita-image-store.s3.amazonaws.com/0/119378/e8a06b4b-5957-1ab3-63f5-a03026bf98ed.png)

できあがりました、Open Consoleしてみます。
![スクリーンショット 2018-03-17 20.50.48.png](https://qiita-image-store.s3.amazonaws.com/0/119378/c2a6cf67-4be8-e23f-932b-f0784acd0f24.png)

あとはデータロードしてクエリして。。必要に応じてアプリから接続して。。ですね。youtubeに便利なのがあったので貼っときます。
https://www.youtube.com/watch?v=8JX5EplVG-M

ちなみに、左のメニューからRun SQLという画面にいくと、updateやinsertなど基本的なSQLはサンプルが用意されていました。どうやって書けばいいのかはとりあえずこれみれば大丈夫そうです（ま、普通のSQLですけど）
![スクリーンショット 2018-03-17 20.54.01.png](https://qiita-image-store.s3.amazonaws.com/0/119378/400a5cb0-9ffc-e49a-ad46-b19662811e62.png)


ちなみに、DWH系のサービスもあります。詳細はこちら。

## （ご参考）最初からデータウェアハウス系のを試したかったらこちら
https://qiita.com/azzeten/items/e993bb3954c2c9a98dab
https://qiita.com/azzeten/items/c1d5eb7774f9d14953e8
https://qiita.com/azzeten/items/2e38472994ba77ef1aff
丸いボタンを作った

この世でいくつ目の車輪だろうかと思いつつ、作った。

https://github.com/mayahiro/CircleButtonSample

# 出来上がり

![circle_button.gif](https://qiita-image-store.s3.amazonaws.com/0/69858/613e84b5-cd46-09b0-ff88-247c7bd60743.gif)

# こういう場合

- ソースコードをペタペタ貼り付けるべきなのだろうか。
  - Github見てもらって、Issueとか書いてもらえる方が正直嬉しい。
32bit、メモリ2GBの私のPCでもEclipseを使えた方法

使用しているノートPCは、32bit、メモリ2GBでWindowsを使用しているのだが、WindowsにそのままEclipseをインストールしてもメモリがいっぱいになり、動作させることができなかった。
どうにかEclipseでjava開発を行いたいと考え、ノートPC内のVMwareにEclipseをインストールして動作検証をしてみた。

##環境
VMware Player6.0.7
CentOS6.9
Eclipse-4.7.2


##Eclipseインストール
インストール媒体のダウンロード
[eclipse](https://eclipse.org/downloads/)

アクセスしたらDownload Packagesをクリック
[![https://gyazo.com/3f108801d67505f1281370501a5d4a8f](https://i.gyazo.com/3f108801d67505f1281370501a5d4a8f.png)](https://gyazo.com/3f108801d67505f1281370501a5d4a8f)

右上のWindowsとなっているプルダウンをLinuxに変更
[![https://gyazo.com/82c09810a9b90840fa20674c4db8c831](https://i.gyazo.com/82c09810a9b90840fa20674c4db8c831.png)](https://gyazo.com/82c09810a9b90840fa20674c4db8c831)

対象bitを選択してダウンロード
[![https://gyazo.com/a9b9dcd4c1aa3fb5cb985ea952461643](https://i.gyazo.com/a9b9dcd4c1aa3fb5cb985ea952461643.png)](https://gyazo.com/a9b9dcd4c1aa3fb5cb985ea952461643)

ダウンロードしたtar.gzファイルをサーバに転送し、/optに配置
転送方法が不明の場合は[これ](https://qiita.com/shimatter/items/6a9f1f0fcd8d0680a69e)を参考に。

```
sudo tar xzvf eclipse-dsl-oxygen-2-linux-gtk.tar.gz -C /opt
```

今後の管理の為にディレクトリ名にバージョンをつける

```
sudo mv /opt/eclipse /opt/eclipse-4.7.2
```

設定ファイルを作成し、GUI画面からアイコン選択できるようにする

```sudo vi /usr/share/applications/eclipse-4.7.2.desktop```

```
[Desktop Entry]
Version=1.0
Name=Eclipse oxygen(4.7.2)
Name[ja]=Eclipse oxygen(4.7.2)
Comment=Eclipse oxygen
Comment[ja]=Eclipse oxygen
Exec=/opt/eclipse-4.7.2/eclipse
Icon=/opt/eclipse-4.7.2/icon.xpm
Terminal=false
Type=Application
Categories=Development;
```

##Java環境構築
インストール

```
sudo yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel
```

バージョン確認

```
$　dirname $(readlink $(readlink $(which java)))
/usr/lib/jvm/jre-1.8.0-openjdk.i386/bin
```

先ほどのパスを/etc/profileに設定

```sudo vi /etc/profile```

```
export JAVA_HOME=/usr/lib/jvm/jre-1.8.0-openjdk.i386
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
```

設定反映

```
source /etc/profile
```

##起動
アプリケーション→プログラミング→eclipse
[![https://gyazo.com/21844421a37da2e346ccc4698f8dfb33](https://i.gyazo.com/21844421a37da2e346ccc4698f8dfb33.gif)](https://gyazo.com/21844421a37da2e346ccc4698f8dfb33)

無事、起動出来た。
その後は、日本語対応を入れて、無事に新規プロジェクトで動かせた。
仮想環境上だと、余計なアプリを入れてない分、確保したメモリの中で、軽快に動くようだ。
また、Eclipseは元々、Unix系で動作していたので、Windowsとの相性も悪かったらしい。

参考
http://zero-config.com/centos/eclipse-luna-001.html

http://home1.cyber-labo.co.jp/jamwiki-0.8.4/e-wiki/eclipse%E3%81%A7%E3%81%84%E3%81%93%E3%81%86%EF%BC%81
PythonでPHPにおけるfor(foreach)ループの実装

# 概要
PHPのforeachやforに相当するコードをPythonで実装する

# バージョン
- PHP 7.0.27
- Python 3.6.0

# foreach
PHPでよく使う「配列の先頭から一つずつ処理し、配列の長さだけ繰り返す」foreachループ処理

```php:foreach.php
<?php
$array = ['value1', 'value2', 'value3'];

foreach ($array as $value) {
    print($value . "\n");
}

/*
value1
value2
value3
*/
```

Pythonでリスト(list)型を使って同等のものを実装する場合は以下のようなコードになります

```python:for_list.py
my_list = ['value1', 'value2', 'value3']

for value in my_list:
    print(value)    # python3
    # print value   # python2

# value1
# value2
# value3
```

forでは文では[シーケンス型](https://docs.python.jp/3/library/stdtypes.html#typesseq)が使用可能なので、list以外にもtupleやrangeが使用可能です

```python:for_tuple.php
my_tuple = ('value1', 'value2', 'value3')

for value in my_tuple:
    print(value)    # python3
    # print value   # python2

# value1
# value2
# value3
```

phpの連想配列でkeyとvalueを順に取得しながらループ処理する場合

```php:key_value_foreach.php
<?php
$array = ['key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'];

foreach ($array as $key => $value) {
    print($key . ":" . $value . "\n");
}

/*
key1:value1
key2:value2
key3:value3
*/
```

Pythonで同等のものを実装する場合はマッピング(dict)型を使用して以下のようなコードになります

```python:for_dict.py
my_dict = {'key1' : 'value1', 'key2' : 'value2', 'key3' : 'value3'}
  
for key, value in my_dict.items():
    print(key + ':' + value)    # python3
    # print key + ':' + value   # python2

# value1
# value2
# value3
```

# for
PHPでもあまり使わない「ループカウンタを変化させながら繰り返す」ループ処理

```php:for.php
<?php
for ($i = 0; $i < 10; $i++) {
    print($i . "\n");
}

/*
0
1
2
3
4
5
6
7
8
9
*/
```

Pythonではrange型に対してループ処理を行うことで同様の処理が行えます

```python:for_range.php
for i in range(10):    # 0から9までのrange型
    print(i)           # python3
    # print i          # python2

# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
```

# 参考
https://docs.python.jp/3/tutorial/controlflow.html?highlight=for#for-statements
API GatewayのCognito UserPools AuthorizerでCognitoのcustom attributesを取得する

API GatewayでCognitoのカスタム属性(custom attributes)を使用したくなる場合があります。

<img width="657" alt="スクリーンショット 2018-03-17 19.53.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/50056/61efa80c-e2b6-0369-7d3f-aba2e4a0aa3c.png">
⬆ここにカスタム属性を含められればそのままLambdaへ渡せるので便利。

Cognito UserPools Authorizerを使用する方法自体は以下が参考になります。

- [API GatewayでCognito UserPools Authorizerを使う](https://qiita.com/kazup0n/items/19697cb51746195b817c)

今回はここにCognitoのカスタム属性を含める方法を記載します。

# 手順

## カスタム属性を作成する
- Cognito > ユーザープール > 属性 > カスタム属性の追加

## カスタム属性に値を格納
AWS CLI を使用して`custom:my-address` というカスタム属性に値を格納する例。

```bash
aws cognito-idp admin-update-user-attributes \
  --user-pool-id ap-northeast-1_XXXXXXXX \
  --username foobar \
  --user-attributes "[{\"Name\":\"custom:my-address\",\"Value\":\"0x9A84E702e8D82Ac4522d4E0790C141696d89d324\"}]" \
```

## アプリクライアントの属性への読み取り権限を付与する
- Cognito > アプリクライアント > 詳細を表示 > 属性の読み込みおよび書き込みアクセス権限を設定する
<img width="1248" alt="スクリーンショット 2018-03-17 19.38.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/50056/bb4320f9-ba22-fc08-60cd-f92387b8f0a3.png">

## 対象のクライアントでアクセストークンを生成
- 詳細割愛

## オーサライザーで確認
<img width="652" alt="スクリーンショット 2018-03-17 19.52.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/50056/0ba6ae5d-22d3-c608-8062-94cb46c693e2.png">

- :warning: トークンは取得し直さなければ反映されない場合あり

以上。
読書メモ：［試して理解］Linuxのしくみ ～実験と図解で学ぶOSとハードウェアの基礎知識 

## ツール
- ldd: リンクしてるやつ
- readelf: ELFバイナリの情報
- sar: CPUの使用状況
    - IO: -d -p
    - ページフォールト: -B
    - メモリ： -r
- taskset: CPUを指定してプロセスを走らせる　sched_setaffinity() system call を使っている
- ps ax: STAT
    - S: sleep (interruptible)
    - D: IO待ちなど (uninterruptible) 数msで終わる
    - R: runnig/in queue
- ps -eo pid, comm, time, etime: CPU使用時間、起動してからの時間
- free: 使用中のメモリ
<br>

- /sys/devices/system/cpu/cpu0/cache - CPU0のキャッシュ情報
- /proc/\<pid\>/maps - プロセスのメモリマップ (man 5 proc)
- /proc/cpuinfo

## カーネル

- OOM killer - available なメモリがなくなった時、適当なプロセスを選んでkill.
    - sysctl の vm.panic_on_oom で disable 可
- スリープ状態のプロセスはイベント/入力/デバイスの書き込み終了/データ送受信の終了待ち
- fork 時メモリはCOW
    - すべての書き込み権限を無効化し、page fault 時にページエントリをコピー
-  プロセスのページテーブル(仮想アドレスと物理アドレスのマッピング)が大きくなると、それをコピーするためforkに時間がかかる。mitigation としてhuge page がある
-  TLB: Translation lookaside buffer ページテーブルのキャッシュ
-  ページキャッシュ - カーネルメモリ上のディスクキャッシュ
    -  ライトバックはデフォルト5秒 (sysctl dirty_writeback_centisecs)
-  CPUのキャッシュ

```
$ for i in 0 1 2 3; do cat /sys/devices/system/cpu/cpu0/cache/index$i/{type,level,shared_cpu_list,size,coherency_line_size} | xargs; done
Data 1 0,4 32K 64
Instruction 1 0,4 32K 64
Unified 2 0,4 256K 64
Unified 3 0-7 8192K 64
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,4
```
cpu0 は 32K の L1 Data,Inst キャッシュ、256K の L2 キャッシュ、8192K の L3キャッシュを持つ
L1, L2 はハイパースレッドのペア cpu4 とキャッシュを共有。L3 はすべてのCPUで共有

## ファイルシステム

- キャラクタデバイス: シークはできない
    - 端末、キーボード、マウス
    - ps で表示されるTTYはそれにひもづくcharacter device. pts/1 なら /dev/pts/1
- ブロックデバイス：ランダムアクセス
    - ブロックデバイス層を通してアクセス。マージやソートをしてスループットを上げる(特にHDD)
    - ブロックデバイス層 -> ドライバA -> デバイスA

- procfs (man 5 proc)
    - /proc/sys 以下のファイルは sysctl, /etc/sysctl.cnf と一対一に対応
- sysfs
    - /sys/devices - デバイス情報
    - /sys/fs - ファイルシステム情報
- cgroupfs
    - CPUやメモリの制限を特定のプロセスグループに課す。docker や仮想マシンで利用

## C 言語

- register 指定子 - なるべくレジスタに割り当てる
【Ruby】引数の数が不定のメソッドのメモ(*)

- 引数の名前の頭に*を付けると不定の引数を取る
- 引数と引数の間に挟むと、固定の引数以外の値を取る（hoge2)
- ２つ続けるとエラーになる（hoge3)

```ruby
# 引数の数が不定の場合、*をつける。配列で受け取る
def hoge(*args)
  p args # => [1, 2, 3]
end

hoge(1,2,3)

def hoge2(arg1, *args, arg2)
  p arg1 # => 1
  p args # => [2,3,4]
  p arg2 # 5
end

hoge2(1,2,3,4,5)

#エラー
def hoge3(arg1, *arg2, *arg3, arg4)
end

hoge3(1,2,3,4,5,6,7)
```
【Swift4】キーボードに追従するツールバーを実装する

## 実行環境
【Xcode】Version 9.2
【Swift】Version 4.0.3

## やりたいこと
キーボードの動きに合わせて動くツールバーをUIScrollViewを使わずに実装する。

![Untitled3.gif](https://qiita-image-store.s3.amazonaws.com/0/238595/fc626d2a-fb09-3be6-afbf-de3270240b91.gif)


## 下準備
まず、`Text Field`と`UIView`を`storyboard`に配置します。

Text Field → 今回は適当。
UIView → left,right,bottomを0、heightを50にしてます。

この時の`UIView`がツールバーになります。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/238595/a8b8ae38-2b90-1ed2-435c-c8798e7a6121.png)

次に、`UIView`と`bottom`の`constant`を`IBOutlet`にします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/238595/1551c539-d50b-e426-1956-c63a1626d4e6.png)


この制約をキーボードの表示と非表示に合わせて変化させることによって、ツールバーがキーボードについてくるように見せます。

## 実装

```swift
   @IBOutlet weak var toolbar: UIView!
    @IBOutlet weak var toolbarBottomConstant: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //キーボードが現れるときに通知するメソッドを登録
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillBeShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        
        //キーボードが閉じるときに通知するメソッドを登録
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillBeHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }
    
    //キーボードが開くときの呼び出し
    @objc func keyboardWillBeShown(notification: NSNotification) {
        
        if let userInfo = notification.userInfo {
            if let keyboardFrameInfo = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
                
                //ツールバーの最大Y座標と、キーボードの最小Y座標の差を計算
                let diff = self.toolbar.frame.maxY -  keyboardFrameInfo.cgRectValue.minY
                
                if (diff > 0) {
                    //ツールバーのbottomの制約に差分をプラス
                    self.toolbarBottomConstant.constant += diff
                    
                    //レイアウトを更新
                    self.view.layoutIfNeeded()
                }
            }
        }
        
    }
    
    //キーボードが閉じるときの呼び出し
    @objc func keyboardWillBeHide(notification: NSNotification) {
        //ツールバーのbottomの制約を元に戻す
        self.toolbarBottomConstant.constant = 0.0
        
        //レイアウトを更新
        self.view.layoutIfNeeded()
    }
    
    //テキストフィールド以外をタッチしたとき
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //キーボードを閉じる
        self.view.endEditing(true)
    }
```
ImageMagickで出力ファイル名を指定する・変える

## 目的
ImageMagickで画像を一括処理する時に、ファイル名を各々変えるにはどうしたら良いのでしょうか...
色々漁ってたどり着いたので、備忘録として残しておきます。

っと思ったら、先人がいました....
[ImageMagick 出力ファイル名指定](https://qiita.com/hsagae/items/0c7d18481cfae0d0c498)

## 結論
-set filename:を使いましょう!!
例えば、フォルダ内のjpegファイルを幅150pxにリサイズして、名前は"prefix"+元のファイル名にしたい場合は、
```magick convert *.jpg -set filename:test 'prefix%t' -resize 150x '%[filename:test].jpg'```
のように書きます。その他にも、ファイル形式等をファイル名に入れることもできます。その場合は以下を参照してください。
[Format and Print Image Properties @ ImageMagick](https://www.imagemagick.org/script/escape.php)
これは間違い⇒VirtualBoxのCentOSでFessを使う場合は、CentOS 6にした方が良いみたい

ローカル環境のGoogle検索サイトを立ち上げるため、[Fess](https://fess.codelibs.org/ja/index.html)をVirtualBox下のCentOSにインストールしてみたのですが、CentOS 7.4ではクライアントから接続できない問題が発生しました。

これは、接続できないのではなく、起動に時間がかかっているだけでした。じっと待ち続けると、いつの間にか接続できていました（クライアントにページが表示されました）

この時のセットアップ手順は以下の通りです。

```console
yum -y localinstall elasticsearch-6.2.1.rpm
echo configsync.config_path: /var/lib/elasticsearch/config >> /etc/elasticsearch/elasticsearch.yml
yum -y localinstall fess-12.1.1.rpm
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-fess:6.2.1
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-ja:6.2.1
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-synonym:6.2.1
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-configsync:6.2.2
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-dataformat:6.2.3
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-langfield:6.2.1
yes | /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-minhash:6.2.1
 
systemctl daemon-reload
systemctl enable elasticsearch
systemctl enable fess
```


<del>
私の場合、CentOS 7.4でなく、CentOS 6にすると動作しました。

ベアメタル上のCentOS 7.4では問題がないので、VitualBox固有の環境に問題があるものと思われます。

## 現象

CentOS 6.9と、CentOS 7.4の両方で、以下に示すインストール手順で[Fess](https://fess.codelibs.org/ja/index.html)をインストールしたのですが、CentOS 7.4では、ウェブサーバから応答（レスポンス）が返らない（デッドロック）しました。

```bash:CentOS7ではCtrl+Cで止めた
curl http://localhost:8080/
# CentOS 6.9では期待通り、検索ページが応答（レスポンス）される
```

### インストール手順

```bash:インストール手順（詳細は省略）
sudo yum -y localinstall jdk-8u161-linux-x64.rpm
sudo yum -y localinstall elasticsearch-6.2.1.rpm
su
echo 'configsync.config_path: /var/lib/elasticsearch/config' >> /etc/elasticsearch/elasticsearch.yml
exit
sudo yum -y localinstall fess-12.1.0.rpm
su
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-fess:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-ja:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-synonym:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-configsync:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-dataformat:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-langfield:6.2.1
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-minhash:6.2.1
exit
```

## 原因

解りませんでした。最初はElasticsearchのプラグインのバージョンの相性とか、Fessのバージョン、Elasticsearchのバージョンを疑ったのですが、どれも違うようでCentOS 7.4では同じ現象でした。

```bash:ポート番号8080でLISTENはしている
netstat -an | grep LISTEN
# tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
```

</del>

## 環境

  * ホストOS :　Windows 10 Pro Version 1709
  * 仮想化　：　VirtualBox 5.2.6
  * ゲストOS ： CentOS 6.9 / CentOS 7.4
  * Fess ： Fess 12.1
  * Elasticseach ： 6.2.1
google cloud sdk





Mac用のCloud SDKをダウンロード

[Mac OS X 用のクイックスタート  \|  Cloud SDK のドキュメント  \|  Google Cloud Platform](https://cloud.google.com/sdk/docs/quickstart-mac-os-x?hl=ja)


解凍した後、任意のところに配置。
今回は書類フォルダ配下に置いた

/Users/xxxxx/Documents/google-cloud-sdk


## パスを通す


```
vi ~/.bash_profile
```

PATHを通す

.bash_profileの更新

```
source ~/.bash_profile
```



echo $PATHでPATHの確認

PATHの確認

```
echo $PATH
```


## インストール
カレントフォルダを以下であることを確認
/Users/xxxxx/Documents/google-cloud-sdk

```
sh install.sh
```


うまくいけば以下のように表示される。

```

Welcome to the Google Cloud SDK!

To help improve the quality of this product, we collect anonymized usage data
and anonymized stacktraces when crashes are encountered; additional information
is available at <https://cloud.google.com/sdk/usage-statistics>. You may choose
to opt out of this collection now (by choosing 'N' at the below prompt), or at
any time in the future by running the following command:

    gcloud config set disable_usage_reporting true

Do you want to help improve the Google Cloud SDK (Y/n)?
```


Yがデフォルトで選択されているのでそのままEnterキーを押す




SDK の初期化


コマンド プロンプトで次のコマンドを実行します。
gcloud init


ブラウザ経由でGoogle認証が走ります。

![スクリーンショット 2018-03-09 23.21.44.png](https://qiita-image-store.s3.amazonaws.com/0/49910/686c04f2-c542-a166-43dc-2a9dc5ccf934.png "スクリーンショット 2018-03-09 23.21.44.png")


![スクリーンショット 2018-03-09 23.21.54.png](https://qiita-image-store.s3.amazonaws.com/0/49910/1b98a664-0c19-3baa-95ea-fab7ccf8caed.png "スクリーンショット 2018-03-09 23.21.54.png")

![スクリーンショット 2018-03-09 23.22.34.png](https://qiita-image-store.s3.amazonaws.com/0/49910/d3a558e8-bb3c-6a38-b4e1-9c76dcd7b318.png "スクリーンショット 2018-03-09 23.22.34.png")


すごい


再度テーミナルにフォーカスが移ります


Compute Engine のデフォルト ゾーンを選択となります。

まずはプロジェクトの選択になります。プロジェクトIDになるので、コンピュートエンジンの画面でプロジェクト名に対するIDを確認します。

```
Pick cloud project to use:
 [1] vast-dock-1231
 [2] test1-878a1
 [3] vast-dock-181211
 [4] Create a new project
Please enter numeric choice or text value (must exactly match list
item):
```

その後、ゾーンを指定になります。
接続したいサーバーが配置してあるゾーンを選択します。


```
Which Google Compute Engine zone would you like to use as project
default?
If you do not specify a zone via a command line flag while working
with Compute Engine resources, the default is assumed.
```
Google AIYキット 日本語対応版のインストール（Mac版）


環境：Mac（High Sierra）



# SDカードのセットアップ

## image

以下のページからイメージファイルをダウンロードします。
真ん中くらいにダウンロードリンクがあります。
[AIY Projects](https://aiyprojects.withgoogle.com/)

[最新イメージの取得](https://dl.google.com/dl/aiyprojects/aiyprojects-latest.img.xz)

[Voice](https://aiyprojects.withgoogle.com/voice/#assembly-guide-1-get-the-voice-kit-sd-image)



## Wifi, VNCサーバーの設定

は、以下に書きました。

[Raspberry Piの初回設定、wifi自動設定、VNCサーバー起動（Mac） \- Qiita](https://qiita.com/sugasaki/items/8f73b4cb239744ac2570)




## スピーカー、音声チェエック

デスクトップにある、Check audioをダブルクリックして、音声チェックを開始します。

![Kobito.f8sBio.png](https://qiita-image-store.s3.amazonaws.com/0/49910/3ed78dde-1375-2915-716e-3d705bba331e.png "Kobito.f8sBio.png")



## GOOGLE CLOUD PLATFORM の設定
以下からコンソールに入る。
[Cloud Console](https://console.cloud.google.com/)



APIとサービス＞認証情報画面から、OAuth2.0クライアントのダウンロードリンクをクリック。
ダウンロードされたファイルをassistant.jsonにリネームし、　/home/piの直下に移動します。

![Kobito.8cIlzs.png](https://qiita-image-store.s3.amazonaws.com/0/49910/6d2015a8-52da-a0fb-3408-d5b3225561e9.png "Kobito.8cIlzs.png")