OmniAICreator/Qiita-1.07M huggingface dataset:
UbuntuでAnsibleインストールから動作確認まで

Ansibleをインストールして動作確認するまでの手順です。

## 1. 環境
Ubuntu 18.04 LTS
Python 2.7.15

## 2. インストール
[公式ページの手順](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#latest-releases-via-apt-ubuntu)を参考にaptでインストールします。

```
$ sudo apt update
$ sudo apt install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt update
$ sudo apt install ansible
```

インストールされているか確認。

```
$ ansible --version
ansible 2.6.2
  config file = /etc/ansible/ansible.cfg
(以下略)
```

## 3. 自機で動作確認
ここでは、簡単に自機で動作確認をします。
他に動作確認できるサーバなり、VMがある場合そちらでも良いです。
（その場合は、自機のIPアドレスを対象クライアントのIPアドレスに置き換えて実行してください）

```
$ ssh-keygen
$ cd ~/.ssh
$ ssh-copy-id [自機のIPアドレス]
```

※別のマシンでアカウント名が自機と異なる場合、最後は以下のコマンド。

```
$ ssh-copy-id [アカウント名]@[対象クライアントのIPアドレス]
```

hostsの設定をします。
/etc/ansible/hostsに以下を追記してください。

```text:/etc/ansible/hosts
[servers]
192.168.×.×   # 自機のIPアドレス
```

Ansibleのpingモジュールで設定がうまくいっているかを確認しましょう。

```
$ ansible [自機のIPアドレス] -m ping
#初回は接続を続けるかのyes/noを聞かれるので"yes"で続行

192.168.×.× | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

pingが成功すれば、準備完了です。
自機をAnsibleで環境構築できるようになりました。

## 4. ansible-playbookを使ったテスト

試しに、Playbookのファイルを作成して実行してみましょう。
以下の内容でtest.ymlを作ります。

```yaml:test.yml
- hosts: servers
  tasks:
    - name: Test ansible-playbook
      debug: msg="Hello world!"
```

ansible-playbookコマンドで実行してみましょう。
エラーが出ずに実行されれば、成功です。

```
$ ansible-playbook test.yml

PLAY [servers] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.×.×]

TASK [Test ansible-playbook] ***************************************************
ok: [192.168.×.×] => {
    "msg": "Hello world!"
}

PLAY RECAP *********************************************************************
192.168.×.×               : ok=2    changed=0    unreachable=0    failed=0
```
Laravel5.6 生成されたページに拡張子を付与する

## やりたいこと

`/posts/記事のID`のようにすればアクセス出来るページがあるとする。
それを`/posts/記事のID.html`でアクセスが出来るようにしたかった（訳あって）。

## 方法

`routes/web.php`を変更する

```php
Route::get('/posts/{id}.html', 'PostsController@show');
```

これで、`/posts/記事のID.html`でアクセスが出来るようになる。
こんな特異なことをしたい人の参考になれば...
Cognos Analytics 条件付きスタイルのレポート間コピー

#条件付きスタイルをレポート間でコピーする手順
Cognos Analyticsで、条件付きスタイルの指定されているオブジェクトを、レポート間でコピーする方法です。

コピー元のレポートで、こんな感じにリストの「数量」列の本体に条件付きスタイルが設定されている例です。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/16ed0690-9101-d1b4-3640-dc259320cb22.jpeg)

まず元レポートのクエリー・エクスプローラーからクエリーをコピーします。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/faddbec9-7d4d-3343-4702-d1530c6a1816.jpeg)

コピー先レポートのクエリー・エクスプローラーに、クエリーを貼り付けます。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/a80c57b3-a3fd-f4c0-1d39-0d7e14853a59.jpeg)

元レポートからオブジェクト、例ではページ自体をコピーしています。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/574dbafa-d104-2ff5-8230-1505b3ef3aa5.jpeg)

コピー先で、ページを貼り付けます。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/c814be91-7d5b-5537-b44a-b336b4c92e0e.jpeg)

コピー先で、ページ1を確認すると無事リストもコピーされていて、プロパティに条件付きスタイルが見えるので、内容を確認してみようとすると、画面のような"nodeNameは取得できません"エラーになります。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/af48b022-9f7f-2f20-fafa-b342b984233c.jpeg)

実は「条件付きスタイル」そのものの設定もコピーする必要があります。
元レポートの赤枠の「・・・」で「条件付きスタイル」を選択します。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/87ebefd6-07b2-a3bb-f800-9ec51224d332.jpeg)

このウィンドウが表示されるので、コピーしたい条件付きスタイルを選択し、Ctrl + C でコピーします。
![008.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/502d7148-06f8-11b0-2aaa-030ffaab7f96.jpeg)

コピー先で同様に「条件付きスタイルの管理」を開き、Ctrl + V で貼り付けます。
![009.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/b9c0b09c-3134-7e86-d829-15f21f3e44bd.jpeg)

これでOKです。コピー先レポートが問題なく実行され、条件付きスタイルも使用できている事がわかります。
![010.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/4359cca6-92f0-0003-bc71-3fd1cec079ba.jpeg)

ご活用下さい。
CanonMG6200seriesのドライバをUbuntu18.04にインストールする

#はじめに
Ubuntu16.04の頃は標準のドライバでイケたのに18.04にしてから動かなくなったので[メーカー製ドライバー](https://cweb.canon.jp/drv-upd/ij-mfp/linux-pd-mg6230-360.html)をインストールしようとしたのだが、うまくインストールできなかった。

#環境
Ubuntu18.04LTS
CUPS 2.2.7
CanonMG6200 series

#検証
Gdebiで依存関係を確認すると、libpng12-0とlibtiff4が無いって怒られたのでそれを入れる
[libpng12-0](https://packages.debian.org/ja/jessie/libpng12-0)
[libtiff4](https://launchpad.net/ubuntu/+source/tiff3/3.9.7-2ubuntu1/+build/4927087)
上のリンクからdebファイルをダウンロードしてインストールする。
そうして./install.shすると、うまく入りました！

#追記
PCの更新の際に再インストールしてみたところ、別のエラーが出てしまった。
cnijfilter-common のインストールに必要な libpango1.0-0 がインストールされないようで、とりあえずaptでインストールしてみたらうまく行きました。

```bash
sudo apt install libpango1.0-0
```

#原因
どうやらinstall.sh 内でエラーが出ていたようで、そのエラーの原因がlibpng12-0とlibtiff4がインストールされていなかったことだったよう。
両方リポジトリにいなかったので仕方なくdebファイルで対応したが面倒くさいなぁ
【jQuery】.hover( )を使うときの、当たり前かもしれない構文

#自分でドロップダウンメニューを作ってみたくなったのでやってみた。
そしてできたのがこれ。
いろいろネットで検索してあーでもないこーでもないとやってみた結果こうなりました。
参考 : [jQueryでプルダウンメニュー（たった5行で！）](http://www.finefinefine.jp/jquery/kiji1581/)

<p data-height="265" data-theme-id="0" data-slug-hash="oMrvEY" data-default-tab="html,result" data-user="kapeking" data-pen-title="ドロップダウンメニュー" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/oMrvEY/">ドロップダウンメニュー</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

一応内容を載せます。

```html:HTML
<nav>
        <ul>
          <li class="navTitle"><a>おっきいタイトルA</a>
            <ul class="subList">
              <li><a>ちっちゃいタイトル01</a></li>
              <li><a>ちっちゃいタイトル02</a></li>
              <li><a>ちっちゃいタイトル03</a></li>
              <li><a>ちっちゃいタイトル04</a></li>
            </ul>
          </li>
          <li class="navTitle"><a>おっきいタイトルB</a>
            <ul class="subList">
              <li><a>ちっちゃいタイトル01</a></li>
              <li><a>ちっちゃいタイトル02</a></li>
              <li><a>ちっちゃいタイトル03</a></li>
              <li><a>ちっちゃいタイトル04</a></li>
            </ul>
          </li>
        </ul>
      </nav>
```

```css:CSS
ul{
  list-style:none;
}
a{
  color:#fff;
  display:block;
  text-decoration:none;
}
nav>ul{
	display: flex;
  justify-content:space-around;
  background:red;
  width:500px;
  margin:0;
  padding:0;
}
.navTitle>a{
	margin-right: 20px;
	font-size: 18px;
	position: relative;
}
.subList{
	position: absolute;
	background-color: #ff142b;
	padding: 0 10px;
	z-index: 100;
	display: none;
}
.subList li{
	padding: 10px;
	border-bottom:dashed 1px #fff;
}
.subList li:last-child{
	border-bottom: none;
}
```

```java:jQuery
$(".navTitle").hover(function(){
				$(this).children('ul').slideDown("fast");
			}, function() {
				$(this).children('ul').slideUp("fast");
			});
```

##なんでこれでちゃんと動くのかわからない。
jQueryのhoverがうまく動かなくて、最終的にhoverのとこは参考URLからコピペしてこうなったんですが・・・
slideDownのとこまではわかるけど「},function()・・・」ってどういう意味？

##自分的正解

<p data-height="265" data-theme-id="0" data-slug-hash="PBroYd" data-default-tab="html,result" data-user="kapeking" data-pen-title="ドロップダウンメニュー（if文）" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/PBroYd/">ドロップダウンメニュー（if文）</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ってif文使うんなら意味わかるんだけど、なんで上のは使わなくても動くの？

##jQo.hover( function, function )は構文だった。

さらに調べたらありました。

>マウスカーソルが要素内に入ったり出たときの時の処理を設定返値：jQueryオブジェクト
>jQo.hover( function, function )
>引数に２つのfunctionをとりマウスカーソルが要素内に入ったり出たときの時の処理を設定します。

引用元 : [デザイナーにも分かりやすいjQuery入門講座|jQueryの使い方](http://www.jquerystudy.info/reference/events/hover.html)

**構文だったんかーい。**
意味めっちゃ考えたんに・・・。if文しか知らん自分が悪かった。

ひとつ賢くなったよ。やったね。

###更新履歴
コメントより、アニメーションの動きが不十分だったことが発覚。
調べてさらに記事追加しました。
さらにひとつ賢くなりました。コメントありがとうございました。
[【jQuery】.hover()を高速移動するとアニメーションが蓄積されてよくわからないことになる問題を解決する](https://qiita.com/kape/items/6ba140d55968835466c0)
一歩

<br>
　　アルバイトのドタキャンを機に、知識ゼロからプログラミングをスタートする。
<br>
　　:pencil2:　Swift Playgrounds ( iPadでの学習 )
　　:books:　Terateil ( Q&A )
　　:baby_tone1:　Qiita ( まとめ )<br>
　　 ◎　言語は一つに絞る
　　 ◎　沼にハマらない
　　 ◎　インプットしたらアウトプット
<br>
　　とりあえずやる　→　Qiitaに記録　→　ノートにも記録
　　アプリゲーム作りたい。
システムクロックを手動設定、ハードウェアクロックと同期

update 2018/06/16
検証OS： CentOS7.5

## ハードウェアクロックとシステムクロックの関係について

```
Linuxの時計には、「ハードウェアクロック」と「システムクロック」という２つのクロックがある。

ハードウェアクロック..... マザーボードが持つ内部時計であり、BIOS クロックやCMOS クロックとも呼ばれている。
システムクロック....Linux がカーネル内部に持っている時計であり、OSの画面上で見るのはこのシステムクロックである。

Linux はシステムが起動する時に一度だけハードウェアクロックを参照し、その時刻をシステムクロックに設定する。
これは起動するたびに行われる、つまりハードウェアクロックの時刻が狂っていると
システムクロックも同様に狂ってしまう。

システムクロックの値がおかしいからと言って、システムクロックだけを設定しなおしても、
ハードウェアクロックを書き換えない限りは、再起動するたびにシステムクロックを再設定し直さなければなりません。
```

## こんな時に使う

1. 仕事で物理サーバを買ってきてラックにマウントする。
2. PXEbootでOSを入れる
3. 作業用のLANをつないだままAnsibleでアプリインストールやOS設定をする
4. 商用のケーブルをつなぐ

ちょうど、2と3の間でやる作業。

## システムクロックの時刻を設定する

- 現在のハードウェアクロックとシステムクロックの時刻を確認

```
# clock ; date
Tue 08 Apr 2014 04:39:28 AM JST  -0.906231 seconds
Tue Apr  8 13:39:28 JST 2014
```

- 手動でシステムクロックを設定

オフライン環境などで、秒単位で正確でなくてもいいのでとりあえず時刻を合わせたい場合などに実施。

- 書式

```
# date MMDDhhmmYYYY
```

- 設定例

```
# date 011415192016
Thu Jan 14 15:19:00 JST 2016
```

その後、オンラインになったらntpdateコマンドでntpとシステムクロックを同期させる。

- システムクロックの時刻をハードウェアクロックに書き込む

**システムクロック →　ハードウェアクロック**

```
# clock --systohc
```

## ハードウェアクロックとシステムクロックの同期を確認

```
# clock ; date
Tue 08 Apr 2014 01:39:48 PM JST  -0.687756 seconds
Tue Apr  8 13:39:48 JST 2014
```
※ サーバをrebootもさせてみて上記のように同期しているかを確認する。

・clockコマンドはhwclockにシンボリックが貼られているだけの様子

```
# ll /usr/sbin | grep clock
lrwxrwxrwx. 1 root root           7 Jan  8 05:05 clock -> hwclock
-rwxr-xr-x. 1 root root       45304 Nov 20 21:37 hwclock
```
How to Install ThinkPHP5.1 in LEMP?

OS : Ubuntu Server 16.04.5 LTS
MySQL : [How to Install MySQL 8 and phpMyAdmin via Docker?](https://qiita.com/shaching/items/12d1429ccd663290ea92)
ThinkPHP: It's a China made PHP framework.

# Install php nginx
```shell
$ sudo apt install php7.0 php7.0-mysql nginx
```

# Error 1
```
Call to undefined function Think\imagecreate()
```

# Solution 1
```shell
$ sudo apt install php7.0-gd
``````

# Error 2
```
call not undefined function Think\simplexml_load_string() 
```
# Solution 2
```shell
$ sudo apt install php7.0-xml
```

# Error 3
```
Call to undefined function mb_strimwidth()
```

# Solution 3
```shell
$ sudo apt install php7.0-mbstring
```

# Modified nginx configuration
```shell
$ vim /etc/nginx/sites-available/default
```
```diff
-- index index.html index.htm index.nginx-debian.html;
++ index index.html index.htm index.php;

location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
++      if (!-e $request_filename) {
++              rewrite ^(.*)$ /index.php?s=/$1 last;
++              break;
++      }

        try_files $uri $uri/ =404;
}

-- # fastcgi_pass unix:/run/php/php7.0-fpm.sock;
++ fastcgi_pass unix:/run/php/php7.0-fpm.sock;

-- # location ~ /\.ht {
-- #         deny all;
-- # }
++ location ~ /\.ht {
++        deny all;
++ }
```

# Restart Nginx & php7.0-fpm
```shell
$ sudo systemctl restart nginx
$ sudo systemctl restart php7.0-fpm
```

# Put php file in /var/www/html/
```
$ vim /var/www/html/index.php
```

```php:index.php
<?php phpinfo(); ?>
```

# Git clone ThinkPHP5.1 files in /var/www/html/
```
$ cd /var/www/html/
$ git clone https://github.com/top-think/think tp5
$ cd /var/www/html/tp5
$ git clone https://github.com/top-think/framework thinkphp
$ git checkout 5.1
```

https://www.kancloud.cn/manual/thinkphp5_1/353948
https://websiteforstudents.com/install-nginx-mariadb-and-php-7-1-lemp-with-ubuntu-16-04-lts-server/
https://gist.github.com/GhazanfarMir/03bd1f1f770a3834d47274586d46ea62
[Progate] Rails自分用


マイグレーションファイルを作成した場合は必ず`$ rails db:migrate`を実行する必要があります。
# モデル, マイグレーションファイルの作成
`$ rails g model Post content:text`

- Post: モデル名
- content: カラム名
- text: データ型

# コンソールを起動
ターミナル上で`$ rails console`。`> quit`でコンソール終了。

# データベースの posts テーブルに、データを追加
1. new メソッドで Post モデルのインスタンスを作成
2. posts テーブルに保存

# posts テーブルに保存されているデータを取得
posts テーブルの最初のデータを取得

```ruby
$ rails console
> post = Post.first
> post.content # Post.firstで取得したデータから投稿内容を取得
```

```ruby
$ rails console
> post = Post.all # すべてのデータを取得
> post = Post.all[0] # インデックス番号で要素を指定して取り出す
> Post.all[0].content # 投稿内容を取得
```
Ciscoルータ PAT(NAT NAPT)環境でのNTPのポート変換について

## 概要

CiscoルータでのPAT(NAT)環境で配下のPCからNTPを使おうとしたらハマったのでそのメモです。
PAT(NAT NAPT)環境でのポート変換でなぜかウェルノウンポートにして外に通信してしまう事象が発生しました。

NTPに限らずこの仕様で動くようなので気をつけておかないといけません。

## 構成
NTPサーバ(NICTやmfeedなど) ――― インターネット ――― Ciscoルーター ――― クライアント(PCなど)複数台  

- NTPサーバのIP : 1.1.1.1(仮)  
- GlobalIP(NAT後のIP) : 2.2.2.2(仮)  
- クライアントのIP : 10.0.0.1-100  

グローバルIPは1つしかないのでクライアントからNTPサーバ宛のアクセスは全てマスカレードしています。  

## 普通のPAT(NAPT)の挙動
show ip nat translationsで確認   

| Inside global | Inside local    |      備考                                                                                                                       |
|--------------|---------------|----------------------------------------------------------------------------------------|
|1.1.1.1:47289|10.0.0.1:47289|ポートが空いていれば内部ローカルと同じポート番号で外に出ていく                    |
|1.1.1.1:47290|10.0.0.2:47289|ポートが埋まっている場合は別のポート番号(ウェルノウンポート以外)で出ていく|

## NTPアクセス時の挙動
show ip nat translationsで確認  

| Inside global | Inside local    |      備考                                                                                                                       |
|--------------|---------------|----------------------------------------------------------------------------------------|
|1.1.1.1:123    |  10.0.0.1:123 | ポートが空いていれば内部ローカルと同じポート番号で外に出ていく                    |
|1.1.1.1:20      |10.0.0.2:123   |ポートが埋まっている場合は別のポート番号(ウェルノウンポート)で出ていってしまう|

※IPは例えです。

## 問題点
クライアントの送信元ポートが123(NTP)の場合なぜかウェルノウンポートに変換されます。  
この123以外のウェルノウンポートを使って出ていくのが結構やっかいで、NTPサーバによっては時間を取得させてくれません。
今回の例で20番ポートに変換されてしまったクライアントは123番ポートが空くまでひたすらエラーを繰り返しました。

## 結論
Ciscoルータの動作仕様だそうです。  
これの対策はstatic natを使用するしかないとのことできちんとした対処ができません。

詳細はCisco社のFAQを参照ください。
[Network Address Translation（NAT; ネットワーク アドレス変換）に関する FAQ](https://www.cisco.com/c/ja_jp/support/docs/ip/network-address-translation-nat/26704-nat-faq-00.html)

## ワークアラウンド
NATテーブルの保持時間がデフォルトで10分(6000秒)なので、これを10秒など極端に短くすることでクライアント同士のNTP取得タイミングがかぶる確率を減らすくらいしかなさそうです。

## まとめ
NTPなどSource Portがウェルノウンポートになる可能性が高い通信はこの仕様を理解した上で設計しないとトラブります。
UIPopoverPresentationControllerで表示場所について試してみたこと

## はじめに

従来使っていた`UIPopoverController`クラスがiOS9で廃止され、新しいクラス(UIPopoverPresentationController)に入れ替える作業をしていましたが、ドキュメントを読んでも分からなかったことがあったのでメモしておきます。

## 分からなかったこと

Popover表示場所を決めるプロパティ `sourceView`, `sourceRect`になにを指定すれば良いのか。
Appleドキュメントにはこう説明が書いています。

<img width="800" alt="スクリーンショット 2018-08-16 10.31.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/32323/005ce26d-15ba-080b-ad64-a5d3fd352113.png">

https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller

うん。。。。

## コードを書いてみた

コメントに簡単な説明を書いてますが、yellowViewとredRectの関係を注目。

```swift:ViewController.swift
class ViewController: UIViewController {

    @IBOutlet weak var yellowView: UIView!
    
    let redRect = CGRect(x: 200, y: 100, width: 50, height: 10)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let testView = UIView(frame: redRect)
        testView.backgroundColor = UIColor.red
        yellowView.addSubview(testView)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func openPopover(_ sender: UIButton) {
        
        let contentVC = PopoverContentViewController(style: .plain)
        
        //Popoverスタイル
        contentVC.modalPresentationStyle = .popover
        
        //Popoverコンテンツのサイズ
        contentVC.preferredContentSize = CGSize(width: 150, height: 100)
        
        //場所を決める
        contentVC.popoverPresentationController?.sourceView = yellowView
        contentVC.popoverPresentationController?.sourceRect = redRect
//        contentVC.popoverPresentationController?.sourceView = sender
//        contentVC.popoverPresentationController?.sourceRect = sender.bounds
        
        //方向
        contentVC.popoverPresentationController?.permittedArrowDirections = .any
        
        contentVC.popoverPresentationController?.delegate = self
        present(contentVC, animated: true, completion: nil)
        
    }
}

extension ViewController : UIPopoverPresentationControllerDelegate {
    
}

```

そして結果を見ると、

<img width="800" alt="スクリーンショット 2018-08-16 10.33.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/32323/7795ae5f-9339-be9f-2c72-8df601355c28.png">


## 分かったこと

本当に簡単なことでした。
sourceViewはsourceRectの基準になる領域(View)になります。
そして、sourceRectはPopoverを表示する領域です。

少し考えなければいけないのは、もし、`sourceView`が`UIScrollView`または`UITableView`の`ContentView`の場合、`sourceRect`の指定にoffsetに基づいて指定することです。

例のコードでは書いてないですが、tableViewのcellをタップした場合、offsetを反映した`sourceRect`を指定したところ、想定通り表示されるのを確認しました。

以上。
WordPressで「データベース接続確立エラー」の障害が出た時の対処


# 状況

AWS EC2上でWordPressを構築し、数ヶ月間運用していたところ、突如「データベース接続確立エラー」の画面が表示されるようになってしまいました。
ブログ記事画面だけでなく、管理画面も同じ表示です。

# 要約

- EC2のメモリ使用量がいっぱいになり、MySQLプロセスが終了され、『データベース接続確立エラー』が発生
- EC2のインスタンス再起動・MySQLサービスの起動で対処。

# 原因調査・対応

## EC2にsshで接続

まずは **sshで接続** します。

```bash
ssh -i "EC2のPEMファイル.pem" ec2-user@EC2のアドレス.compute.amazonaws.com
```

## メモリ使用量チェック

しばらく使って突然発生、という状況なので、メモリがいっぱいになってないかをチェックします。

```bash
free -tm
```

used/freeの項目を見て、freeが少なくなっていたので、 **EC2インスタンスを再起動** します。

## 再起動後にメモリ使用量チェック

再びメモリ使用量チェック。

```bash
free -tm
```

freeの量はかなり多くなっています。しかし、ブログ画面は相変わらず『データベース接続確立エラー』のまま。

## MySQL診断

『データベース接続確立エラー』ということなので、データベースの状況を見ます。

### MySQLに接続できるか確認

```bash
mysql -u ユーザー名 -pパスワード
```

> ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

繋がらない・・・！
ちなみにMySQLのユーザー名とパスワードは `wp-config.php` に書かれてることが多いです。

### MySQLのプロセスが動いているか確認

```bash
ps -ef |grep mysqld
```

> ec2-user  2622  2522  0 01:01 pts/0    00:00:00 grep --color=auto mysqld

む、プロセスがやっぱりない。

### MySQLのポートが設定されてるか確認
```bash
sudo netstat -tnap|grep mysql
```

→レスポンスは空
ポートも使われてない

## MySQL起動

MySQLが起動していなかったので、 **MySQLを起動** させます。

```bash
sudo service mysqld start
```

> Starting mysqld:                                           [  OK  ]

## 結果

起動しました！

## まとめ

- EC2のメモリ使用量がいっぱいになり、MySQLプロセスが終了され、『データベース接続確立エラー』が発生した。
- EC2のインスタンス再起動することで、メモリをお掃除した。
- 再起動後、MySQLサービスが起動していなかったので、手動でMySQLサービスを起動した。
- 自動でMySQLも起動するように設定しておくとよい。
- t2.nano等のメモリが少ないインスタンスの場合、放置しているだけでメモリの使用量がいっぱいになり、『データベース接続確立エラー』が発生しやすい。
サクッとBCryptで文字列を暗号化する

コマンドライン引数で文字列をBCryptで暗号化するコード書いたのでメモしておく。  
Mavenなどのパッケージ管理ツール使わず、とにかくサクッとやる想定。

## パッケージダウンロード

利用するライブラリをサイトから手動ダウンロードする。

- [spring-security-core-5.0.2.RELEASE.jar](https://mvnrepository.com/artifact/org.springframework.security/spring-security-core/5.0.2.RELEASE)
- [commons-logging-1.2.jar](https://commons.apache.org/proper/commons-logging/download_logging.cgi)

*spring-security-coreだけだと実行時にcommons-loggingがないというjava.lang.NoClassDefFoundErrorが出力されるので、とりあえず追加。*

## 実装

これらのライブラリをlib配下に格納し、以下の2クラスを実装する。  
引数をBCryptで暗号化するCLBCryptPasswordEncoder.java。  

```java
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.apache.commons.logging.LogFactory;

public class CLBCryptPasswordEncoder{
  public static void main(String args[]){

    String textPassword = args[0];

    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    System.out.println(encoder.encode(textPassword));
  }
}
```

平文パスワードと暗号化済パスワードが一致するか確認するCLBCryptPasswordMatcher.java。

```java
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.apache.commons.logging.LogFactory;

public class CLBCryptPasswordMatcher{
  public static void main(String args[]){
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    String textPassword = args[0];
    String encryptedPassword = args[1];

    if (encoder.matches(textPassword, encryptedPassword)) {
      System.out.println("matched");
    } else {
      System.out.println("mismatched");
    }
  }
}
```

## ディレクトリ構成

ディレクトリ構造は以下のとおり。

- CLBCryptPasswordEncoder.java
- CLBCryptPasswordMatcher.java
- lib/
  + commons-logging-1.2.jar
  + spring-security-core-5.0.2.RELEASE.jar

## コンパイル

```bash
$ javac -cp "lib/*" CLBCryptPasswordEncoder.java
$ javac -cp "lib/*" CLBCryptPasswordMatcher.java
```
カレントディレクトリにクラスが生成される。

## 実行

暗号化と検証の実行。classpathにカレントディレクトリを追加。

```bash
$ java -cp "lib/*:." CLBCryptPasswordEncoder sonomirai
$2a$10$ALcXPgrpOQKXoIyrgS90huCbgR906LtWrH1dOsZmHtBZdSB19n9Bi
$ java -cp "lib/*:." CLBCryptPasswordMatcher sonomirai '$2a$10$ALcXPgrpOQKXoIyrgS90huCbgR906LtWrH1dOsZmHtBZdSB19n9Bi'
matched
$ java -cp "lib/*:." CLBCryptPasswordMatcher dummypswd '$2a$10$ALcXPgrpOQKXoIyrgS90huCbgR906LtWrH1dOsZmHtBZdSB19n9Bi'
mismatched
```

こんな感じでやりたかったことはやれた。
Pythonista 3 にStaSh をインストールする。

# StaShとは
Pythonista 3上でpipなどのコマンド操作ができるようになります。
名前はPythoni<b>sta Sh</b>ellを略したそうです。


**- 参考サイト -**
[StaSh - Shell Like an Expert in Pythonista | omz:forum](https://forum.omz-software.com/topic/1919/stash-shell-like-an-expert-in-pythonista)

# インストール
コンソールに以下をペーストして実行します。

~~~ python
import requests as r; exec(r.get('http://bit.ly/get-stash').text)
~~~
インストールが完了すると次のメッセージが表示されます。

```
Please Restart Pythonista and run launch_stash.py under the Home directory to start StaSh.
```
アプリを再起動して**launch_stash.py**を実行してStaShを起動して下さい。


~~ファイルリストlaunch_stash.pyとstash_extensionsが追加されます。~~
**Pythonista3 v3.2**ではファイルやディレクトリの構成が変わり次の場所に追加されます。
SCRIPT LIBLARY
　┗ This iPhone
　　┗ **launch_stash.py**

Python Modules
　┗ site-packages
　　┗ **stash** 



# 実行
**launch_stash.py**を実行するとコンソールの横にタブが追加されターミナルのような画面になります。

<img width="414" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/280129/d217d82f-8da0-56e0-5430-ae8f6663c348.png">


helpを実行すると使用できるコマンドがズラッと表示されます。

以下のコマンドが使えるみたいです。
[help(StaSh) v0.7.1 - Qiita](https://qiita.com/maboy/items/4de642ed7f7d93cdc432)
alias, cat, cd, clear, cowsay, cp, crypt, curl, cut, dropbox_setup, du, easy_config, echo, edit, exit, fg, find, ftpserver, gci, gh, git, grep, head, httpserver, jobs, kill, latte, ls, mail, man, mc, md5sum, mkdir, monkeylord, more, mount, mv, openin, pbcopy, pbpaste, ping, Usage, pip, printenv, printhex, ptinstaller, pwd, py-tree, python, python3, quicklook, rm, rmdir, scp, selfupdate, sha1sum, sha256sum, sort, source, sqlite, ssh, ssh-keygen, stashconf, tail, tar, telnet, totd, touch, umount, uniq, unzip, version, wc, webviewer, wget, whatis, which, wol, xargs, zip
Ruby on Rais  で心電図のGit Hub を作る

先日こんなことがありました。　　
　

とある病院での当直中、救急隊から、胸痛患者の搬送依頼がありました。救急車内でとった心電図 (12誘導取れるんですね。)　では、STが上がっているか自信がありませんとのこと。多分、STは大丈夫そうですと。。　
　
　
悩んだ挙句、受け入れました。　
　　

The 心筋梗塞でした。　
救急車から患者さんがおりた時点で心電図を渡され、そこには、はっきりした ST 上昇がありました。　
　
カテーテルができない病院であったため、速攻で最低限の対応を行い、転院調整を行いました。無事、vital sign の 変化なく転院搬送となりましたが、かかった時間は、、なんと30分。　
　

なんという無駄なやりとりであったことでしょうか・・・。この30分で、どれだけの心筋がやられてしまったことか・・。循環器内科医だというのに・・。


今の日本では、救急隊が、心電図などの画像を病院に送ることはできません。　
　
　
電話のみのやりとりしかできません！
　
この時代に！！！
　
この21世紀に！！　　
　

画像さえ送ることができれば！　
特に、命に直結する、心電図を送ることができれば。　
どれだけの人が救われるでしょう。　
　

救急隊だけでなく、心電図の読影に自信がない医師が、心電図を速攻でWeb にアップロードして、世界中の誰かが読影するものがあったら・・・。
　
　

ということで、こんな感じのWeb アプリケーションを作ります。心電図のGit Hub versionです。


<img width="1067" alt="スクリーンショット 2018-08-16 10.12.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/232715/9af441e1-b6b9-e2ad-7d4e-0ed20166da77.png">




半年以内に、臨床実験までできればと思ってます。　
　

興味があるエンジニアの方々、力を貸してください。　
(Ruby on Rails で作る予定です。)　
　
　
近い将来、心電図で悩むことのない世界を作ります。
よろしくお願いします。
Rails3.0.1 (Ruby1.8.7) 外部キー設定

# Rails3.0.1 (Ruby1.8.7) 外部キー設定

Rails3.0.1 (Ruby1.8.7) の環境だとmigrationで外部キーの設定が簡単にできなかったので,いろいろ試してみました。

## ①add_foreign_key
gemで外部キー設定を簡単に設定できるメソッドが用意されている。

```rb:Gemfile
gem 'foreigner'
```

```rb:migration
add_foreign_key(:students, :teachers)
```

### 結果
Rubyのversionが1.9.2以上でないと使えない。

```sh
bundle install
--
Gem::InstallError: foreigner requires Ruby version >= 1.9.2.
```


#### 参考
[Foreigner 雑記](https://qiita.com/satour/items/b1406b8745ca370a65a7)

## ②reference型を使う場合
migration時に以下の書き方で外部キーがつけられる。

```rb:migration
    create_table :teachers do |t|
      t.references :student, :foreign_key => true
    end
```

### 結果
外部キーつかず。原因不明

#### 参考
[Railsの外部キー制約とreference型について](https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47)

##③SQL

直接SQLを実行する。

```rb:migration
    con = ActiveRecord::Base.connection
    con.execute('ALTER TABLE teachers ADD FOREIGN KEY (student_id) REFERENCES students')
```

### 結果
うまくいきました。


##結論

SQLでしか方法が見つかりませんでした。
バージョンが古いと何かと不便ですね。
tomcat環境で作ったspring bootアプリがglassfish環境でうまく動かなかった

## 前書き
表題の通りです。glassfish触るのは初めて。
手抜き対応でなんとなく動いたので自分用にメモを残します。
※今回は実装の正らしさよりも、とりあえずglassfish環境で動かしてみることを最優先にしています。
　~~正らしさについては別途調べて更新しようと思います。。~~
　限定公開して2年経ったので備忘として全体公開します。

## 事象
1．そもそもアプリがデプロイできなかった。
2．APIに日本語でパラメータを渡そうとしたら文字化けした。
3．war内のライブラリが読み込まれない。

環境としてはたしか下記の通り。
- 開発環境(ローカル)
    - OS：Windows 10
    - JavaEEサーバ：tomcat v8.5
- 今回利用した環境
    - OS：Linux
    - JavaEEサーバ：glassfish4.x

## そもそもの話
デプロイするときにGlassfish上のライブラリの方が資材のライブラリよりも先に読み込まれてしまうらしい。
こちらの方は直接Glassfishのライブラリを最新化することで対応されています。
[Glassfish4.1上でJacksonを含むアプリを動かす際の注意事項](https://qiita.com/yukyu2nd/items/ca3c46b0075106ebc4b2)

ライブラリをﾍｧｯと変更できればよかったのですが、他の資材への影響が怖かったので設定ファイルを設けることで回避することにしました。
Guideを読むまで気づかなかったのはしんどいなあ。
[GlassFish Server Application Development Guide](https://javaee.github.io/glassfish/doc/4.0/application-deployment-guide.pdf)

## 対処
### 1．そもそもアプリがデプロイできなかった。
以下を参考にさせていただきました。
[Spring Boot App does not deploy on Glassfish 4.1](https://stackoverflow.com/questions/29431579/spring-boot-app-does-not-deploy-on-glassfish-4-1)

とりあえず適当なところにweb.xmlを作成し、mavenで組み込んでもらえるように記述します。

```xml:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
    metadata-complete="true" 
    version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
</web-app>
```

```xml:pom.xml
<!-- Spring boot deploy on Glassfish -->
<plugin>
	<artifactId>maven-war-plugin</artifactId>
	<configuration>
		<webXml>src/main/resources/web.xml</webXml>
	</configuration>
</plugin>
```
これで何とかエラーを吐かずにデプロイできました。


### 2．APIに日本語でパラメータを渡そうとしたら文字化けした。
glassfish-web.xmlを作って文字コードを指定します。

```xml:glassfish-web.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
    <parameter-encoding default-charset="UTF-8" />
</glassfish-web-app>
```

### 3．ライブラリが読み込まれない。
glassfish-web.xmlにクラスローダの設定を追加します。

```xml:glassfish-web.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
    <parameter-encoding default-charset="UTF-8" />
    <class-loader delegate="true"/>
</glassfish-web-app>
```
Rubyでbit全探索

# bit全探索

## サンプルコード

* bit全探索 is 何？
  * bitを利用して数え上げをする手法

（例）３つの要素がある集合から、任意の要素を選び出すすべての場合を列挙する。

**EDIT**

@scivola さんからコメントがありました。Array自体にbitの順列を列挙できるメソッドが生えているので、それを使ったほうが良さそうです。コメント欄参照。

* [元のサンプルコード(wandbox)](https://wandbox.org/permlink/KYB7sVkrFfQefJf1)
* [サンプルコード(wandbox)](https://wandbox.org/permlink/1Mc8NSKHkmSBQT3V)

```ruby:bit_search.rb
len = 3

[0, 1].repeated_permutation(len) do |bits|
  p bits
end

出力
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]
```

これで、１が立っていれば要素を選んだ。０であれば選んでないという列挙ができる。

## 使い方

* 列挙対象の集合とzipして合算するなど

* [サンプルコード(wandbox)](https://wandbox.org/permlink/dWSHrfkAVLSMqDC1)

```ruby:bit_search_sample.rb
SET = ["apple", "google", "amazon"]

cnt = 0
len = 3

while cnt < (1 << len)
  bit = cnt.to_s(2).rjust(len,'0').split("").map(&:to_i)

  sample = []
  SET.zip(bit).each do |test|
    item,b = test.first,test.last
    # bitが1だったら処理
    if b==1 
      sample << item
    end
  end

  p sample

  cnt+=1
end

出力
[]
["amazon"]
["google"]
["google", "amazon"]
["apple"]
["apple", "amazon"]
["apple", "google"]
["apple", "google", "amazon"]
```
Sphinxを利用したドキュメント開発環境の構築

# Sphinxを利用したドキュメント開発環境の構築方法

## 動作環境

- CentOS 7
- メモリは1GB程度でもOK
- Python 3.6

## 構築手順

### Python 3 + pip投入

```bash
$ sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo rpm --import /etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY
$ sudo yum install -y python36u python36u-devel python36u-libs

# python3と叩けばpython3.6を実行できるようにする
$ sudo ln -s /usr/bin/python3.6 /usr/bin/python3

$ sudo yum install -y python36u-pip
$ sudo yum makecache fast
```

### バージョン確認

```bash
$ python3  --version
Python 3.6.5

$ python3 -m pip --version
pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)
```

### Sphinx投入

```bash
$ sudo python3 -m pip install Sphinx
```

### Sphinxの各機能の投入

- 参考元
  - [Markdown support](http://www.sphinx-doc.org/ja/stable/markdown.html)
  - [sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme/)


```bash
$ sudo python3 -m pip install recommonmark
$ sudo python3 -m pip install sphinx_rtd_theme
```

## ドキュメント開発

次のリンク先を参照してドキュメントを作成します。

- [Sphinx > Getting Started](http://www.sphinx-doc.org/en/master/usage/quickstart.html)
- [Sphinxの最初の一歩](http://www.sphinx-doc.org/ja/stable/tutorial.html)

```bash
$ mkdirs <path-to-Sphinx-work-directory>
$ cd <path-to-Sphinx-work-directory>
$ sphinx-quickstart
```

sphinx-quickstartは対話型でsource/conf.pyを作成します。
そのとき、Getting Startedに沿って作業する場合、autodoc拡張機能については```yes```で答えます。

続いて、source/index.rstのtoctreeディレクティブにドキュメント化するファイルを追加したりしてから、最後に次のコマンドでHTMLドキュメントを作成してくれます。

```bash
$ make html
```
【GAS】Google Apps Scriptで注意すべきポイント！随時編集！(GASの勉強を始めた#2)

#1.GAS ≠ Javascript

GASはJSがベースですが、世間で一般に言われるJSとは同一ではありません。

GASで利用できるJavascriptは基本構文、制御構文、演算子、関数、組み込みオブジェクトなどの基本部分(コアJavascript)のみが対象です。
GASはそのコアなものに加えてGoogle Appsを操作するための数々のサービスによって構成されています。
ちなみにGASがベースとしているJSは、最新のECMAScriptではなく、Javascript1.6および一部の1.7と1.8の機能となっています。なので、新しいバージョンで追加された機能がGASで利用できないということはあります。

#2.ハード制限と容量制限

実行時間やデータサイズなどのハード制限と、
1日あたりの実行回数の容量制限(クォータ制限)が設けられています。
これらの制限は使用しているアカウントとその登録プラン、アーリーアクセスプログラムに参加しているかによって異なります。
制限を越えるとエラーになり、処理は終了します。
特に注意すべきは**スクリプトの実行時間**。

#3.GASのスクリプトには2種類ある！


|       |スタンドアロンスクリプト|    コンテナバインドスクリプト 　  |
|:-----------------|----------------:|:------------------:|
| スクリプトの保存        |              Googleドライブ単体のスクリプトプロジェクトファイルとして保存|        スプシュ、ドキュメント、フォームなどに紐づけて保存        |
| スクリプトの作成     |            Googleドライブから保存 |         スプシュ、ドキュメント、フォームなどのメニューから作成     |
| スクリプトのオープン     |              Googleドライブからプロジェクトファイルを開く |       スプシュ、ドキュメント、フォームなどのメニューから開く       |
| プロジェクトの保存数   |                一つのスクリプトプロジェクトファイルに対し、一つのプロジェクト |         親ファイルに対して複数のプロジェクトを保存可能         |
| スプレッドシートのカスタム関数  |             作成不可 |       作成可能       |
| メソッド|           ー |      紐づいたファイルに対するいくつかのメソッドが利用可能      |


###【コンテナバインドスクリプトのメリット】
・スプシュのカスタム関数の作成ができる
・紐づいたファイルを参照するgetActiveSpreadsheet,getActiveDocument、getUiなどのいくつかの便利なメソッドを使用可能。

###【コンテナバインドスクリプトのデメリット】
・スクリプト自体はGoogleドライブ上に表示されないので保存場所がわかりにくい。

#4.GASでは大文字と小文字は違う文字として認識される

タイトル通り！気をつけましょう！JavaScriptでは大文字と小文字は別の文字として認識されます。


#5.コンテンツアシストと単語補完

GASの入力支援→スクリプトエディタを開き空白行で「Ctrl」+「Space」キーを入力すると、リストが出てきます。
これはグローバルオブジェクトと呼ばれ、スクリプトのどこからでも呼び出すことが可能です。打ち間違えなども防止できますね。

#6.コメントアウト

一行をコメントアウトしたい時

```
 //コメント
```

複数行またいでコメントアウトしたい時

```
 /*
　複数行にまたがる
　コメントを入力する
 */
```

ショートカットキーは、Macなら「Command」＋「/」です。


#7.Javascriptの予約語

変数、定数、また関数などにつける名前を識別子と呼びます。JavaScriptでは識別子の名前を比較的自由に命名することが可能ですが以下の予約語を使用することはできません。これはJavaScriptであらかじめ定められた特別な意味を持つ単語です。

```
・break
・case
・catch
・continue
・debugger
・default
・delete
・do
・else
・finally
・for
・function
・if
・in
・instanceof
・new
・return
・switch
・this
・throw　
・try
・typeof
・var
・void
・while
・with
```
githubの通知が視覚的にわかるようにする(chrome拡張機能)

githubの通知に関するドキュメントっていろんなの見たけどちょっとわかりにくかったんですよね。。
なので、今回まとめてみましたよ！

chromeの拡張機能の「Notifier for Github」を使ってみました

# Notifier for Giuthubの使い方


**1.インストールする**

こちらでインストールしてください

https://chrome.google.com/webstore/detail/notifier-for-github/lmjdlojahmbbcodnpecnjnmlddbkjhnn


**2.こんな画面が出てきます**

tokenの部分だけ変更すればよいのですが、tokenを作る必要があります。次に進みましょう！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/5d342bf2-11f5-84b5-c8fa-4121134c7eb2.png)

**3.tokenの発行画面に移動**

github →　「setting」　→　「Developer Setting」

Developer Settingの画面はこんな感じです

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/f38fe491-6d07-663a-994f-05197dc10567.png)


ここからPersonal Acceess tokenをクリックしてください

**4.tokenを発行**

Generate tokenを押します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/0e8df9b9-805f-09e1-8cc2-d10d4aa160b6.png)


Token Descriptionは何でも良いです。自分がわかりやすい名前をつけましょう！
そしてrepoをクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/5fee2289-6d49-e6b1-3c7d-9b09e1d3f371.png)


あとは、下の方にあるgenerate tokenをクリック


**5.tokenを保存**

表示されたちょい眺めのtokenをどこかに保存してください。

**6.notifier for githubにtokenを貼り付け**


**7.できました**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238739/ab7cdaac-469f-d287-975c-6f6f1e364aaf.png)
Ubuntu18.04LTS にAlbertをインストールしたメモ

Ubuntu18.04LTSに対するalbertのインストール方法が見つからなかったのでメモ

## 結論: ソースからビルドする。

### 依存するパッケージを全ダウンロード
```
$ sudo apt update 
$ sudo apt install -y cmake g++ libmuparser-dev libqalculate-dev libqt5svg5-dev \
    libqt5x11extras5-dev python3-dev qtbase5-dev qtdeclarative5-dev unzip \
    virtualbox wget 
```

### 必要なVirtualBoxヘッダーを導入
```
$ mkdir /tmp/vbox 
$ cd /tmp/vbox
$ wget -q http://download.virtualbox.org/virtualbox/5.0.40/VirtualBoxSDK-5.0.40-115130.zip 
$ unzip VirtualBoxSDK-5.0.40-115130.zip 
$ mv sdk/bindings/xpcom/include /usr/lib/virtualbox/sdk/bindings/xpcom 
$ cd 
$ rm -rf /tmp/vbox 
```

### ソースコードをクローンしてきてビルド
```
# ソースコードをダウンロード
$ git clone https://github.com/albertlauncher/albert.git
# サブモジュールをダウンロード
$ cd albert
$ git submodule update --init --recursive
$ cd ..
# 一時ディレクトリを作ってビルド
$ mkdir albert-build && cd albert-build
$ cmake ../albert -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug  
make 
$ sudo make install 
# 掃除
$ cd ..
$ rm -rf albert-build
```


### おまけ
以下ソースコード導入でapplication switcherとしても使える

```
$ git clone git@github.com:albertlauncher/external.git "$HOME/.local/share/albert/"
```
1. 上記コマンド実行してalbertの設定画面からswitchappをONにする
2. prefixとして`(バッククウォート)をつけて実行する


### 追記
v0.14.0から上記の拡張が非推奨になっている、代わりに下記のスクリプトを実行して、albertの設定でExtensionsタブのPythonを有効にしてWindowSwitcherにチェックを入れればアプリ名でWindowの切替ができる

```
$ git clone https://github.com/albertlauncher/python.git "$HOME/.local/share/albert/org.albert.extension.python/modules"
```

### 追記2
ビルド手順を修正
PMS — プログラミングにおけるモチベーションのソース  (己を知れば百戦危うからず)

プログラミングに対するモチベーションの種類はひとつじゃない。

自分自身を知らないよりは、知っていたほうが良い。

実は、モチベーションは高めることは出来ない。その「源」に気づくことが出来るだけだ。
何をモチベーションの源にしても良いけれど、自分に合っているものでなければ意味がない。

## たとえばの話

たとえば「何か作りたいものがある人が、圧倒的に成長する」と言われたりする。

だけど自分にもそれが合っているとは限らない。
実は作りたいものなんか何もないかもしれない。
ただ手を動かして遊ぶのが好きなだけかもしれない。

たとえばリファクタリングに情熱をかけるエンジニアもいる。

だけど自分にもそれが合っているとは限らない。
散らかすのは得意だけど片付けは苦手なのかもしれない。
自分は遊ぶだけ遊んで、片付けが得意な他の人に任せた方が良いかも知れない。(それが許されるならばだけど)

## プログラミングは自己発見である

プログラミングが面白くなるということは、自分発見だ。
新規獲得ではなくて、あくまでも新規発見だ。

「人が振りかざしている何か」ではなくて「誰かどこかにいる空想のエンジニア」でもなくて、「自分自身が持っている源」に気づくこと。

スプリテュアルな話だと思うだろうか。

忘れがちではあるけれど、実はプログラミングというのは、人間の道具だ。
使い手が人間である以上、そこには必ず「人間的な性質」が大きく関係してくる。それが全てだとさえ言って良い。

## 私のモチベーション

たとえば僕の場合は、ただ単にキーボードを打ちながら、子供のようにプログラミングと遊んでいるのが好きだ。
何か世の中に価値を提供したり、サービスを作ろうとするよりも、ただたんに一瞬一瞬を遊びながら過ごしたい。

プログラミングの結果は、ただの結果だ。プログラミングしている瞬間だけが全てだ。そこに愛がある。

なのでプログラミング対象は価値提供でも、そうでなくても、Featureの作成でも、リファクタリングでも、なんでも良い。自分が面白いと思えることが大事だ。


## モチベーションの種類には何があるだろう

思いつくところを書いてみる。

### 創造

- サービスを作ること
- 機能を作ること

この場合、プログラミングは目的実現の手段に過ぎない。本来の目的は価値の提供にある。

### 手助け

- たとえばStackOverflowで他の人の質問に答えたりすること。
- たとえばチームメンバーにプログラミングについて教えること。

### ゲーム

- たとえばひとつのプログラミングに関して、他の人よりもいちはやく理解することにゲーム性を感じたり。
- PullRequestがマージされるのにRPGのボスを倒したときのような感覚を感じたり。

### コミュニケーション

- チームメンバーと喋りながら開発を進めるのが好き。
- PRを作ったり、Issueを作ったり、OSSに関わるのが好き。(僕はOSS開発はコミュニケーションの一種だと思う。脳がそう感じているならばそうだ)
 
### 経験

- プログラミングをスポーツのように、映画を観るみたいに、経験として楽しんでいる。
- たとえば Mac Book のキーボーを叩いてそのレスポンスを楽しんでいる瞬間が好き。


### 快適さ

- VIM とか IDE で快適に操作できる環境が好き。
- リファクタリング愛好家。
- [ボーイスカウト精神](https://deviq.com/boy-scout-rule/) がある。

## そして

こう考えてみるとプログラミングのモチベーションも「人依存」で、パーソナリティーがそのベースにあるように思えてくる。

パーソナリティーはプログラミングよりも大きい。前に来る。

僕らはプログラムをプログラミングしているかのように思えて、実は自分自身をプログラミングしているのかもしれない。

## あわせて読みたい？

- [システムエンジニアの弱点を武器にする方法 - Qiita](https://qiita.com/YumaInaura/items/c9de45727f64c6a367fe)

## 関連

- [What motivates you to programming? ( Understand about your source )](https://gist.github.com/YumaInaura/da0541dbe45ee3efd4a820b43ec7f185)









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
jQueryのライブラリ drawer.js のスクロールできない問題への対処法

下記にリストした参考URLにあるように、2018年になってiosデバイスでjQueryのライブラリ drawer.js で実装したメニューがスクロールできないという事象をよく耳にするようになった。

その対策として drawer.css に overflow:auto; を追記した。

```drawer.css
.drawer--top.drawer-open .drawer-nav {
  top: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

.drawer--left.drawer-open .drawer-nav,
.drawer--left .drawer-hamburger,
.drawer--left.drawer-open .drawer-navbar .drawer-hamburger {
  left: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

.drawer--right.drawer-open .drawer-nav,
.drawer--right .drawer-hamburger,
.drawer--right.drawer-open .drawer-navbar .drawer-hamburger {
  right: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}
```

元ネタの参考URL
[スマホのハンバーガーメニューでpositionにfixedを入れてスクロールできなくなる問題を解決](https://iritec.jp/web_service/13864/)

その他の対処法の参考
https://iritec.jp/web_service/13864/
https://teratail.com/questions/127838
https://tiltilmitil.co.jp/blog/891
https://sublimelife.hatenablog.com/entry/2018/06/21/183718
Item 36: Use EnumSet instead of bit fields

# 36.bitフィールドの替わりにEnumSetを用いるべし
  enum型の要素が集合に適用される場合、昔はint enumパターン（Item34）を用いて、各定数に2の何乗かを振り分けていた。

```java
// Bit field enumeration constants - OBSOLETE!
public class Text {
    public static final int STYLE_BOLD          = 1 << 0;  // 1
    public static final int STYLE_ITALIC        = 1 << 1;  // 2
    public static final int STYLE_UNDERLINE     = 1 << 2;  // 4
    public static final int STYLE_STRIKETHROUGH = 1 << 3;  // 8
 // Parameter is bitwise OR of zero or more STYLE_ constants
    public void applyStyles(int styles) { ... }
}
```
これらにOR演算をかけることによって、いくつかの要素を集合にまとめていた。（bit field）

```java
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
```
bit演算によって、結合や交差も実現できるが、この方法はint enum　の悪い点をすべて引き継いでいる。

  定数の集合を作るにおいては、```EnumSet``` クラスを使うべき。性能はbit fieldで処理する場合と遜色ない。
  上記の例をenum、EnumSetを用いたのが以下。

```java
// EnumSet - a modern replacement for bit fields
public class Text {
    public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
 // Any Set could be passed in, but EnumSet is clearly best
    public void applyStyles(Set<Style> styles) { ... }
}
```
```EnumSet``` インスタンスを渡す、クライアント側のコードは以下のよう。

```java
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
```
  上記の```applyStyles``` メソッドでは、```EnumSet``` ではなく、```Set``` を引数に取っている。たいていのユーザは```EnumSet``` を渡すであろうが、引数として実装クラスを受け付けるのではなく、インターフェースを受け付けるべき（Item64）という原則にしたがってこうしている。
anacondaでのccxtインストール失敗

https://note.mu/zephel01/n/n985c2fe0b6c6
こちらのサイトを参考にwindowsでccxtをインストールしようと試みているのですが
下記エラーで行き詰まっています。
環境はwindows8.1にanaconda3です。

試したこと
・lru-dictがどうやら失敗しているようなので単品でインストール→同じエラー
・「fatal error C1083: include ファイルを開けません。'io.h':No such file or 
directory」 原因わかららず。権限はあるもののio.hは存在しない→VS2017インストール
・pipアップデート

よろしくお願いいたします。

Failed building wheel for lru-dict
Running setup.py clean for lru-dict
Failed to build lru-dict
Installing collected packages: cchardet, pycares, aiodns, lru-dict, web3, ccxt
Running setup.py install for lru-dict ... error
Complete output from command c:\users\dq\anaconda3\python.exe -u -c "import
setuptools, tokenize;file='C:\Users\DQ\AppData\Local\Temp\pip-install-
c4afsz_d\lru-dict\setup.py';f=getattr(tokenize, 'open', open)(file);code=f
.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" i
nstall --record C:\Users\DQ\AppData\Local\Temp\pip-record-yi6dtr7k\install-recor
d.txt --single-version-externally-managed --compile:
running install
running build
running build_ext
building 'lru' extension
creating build
creating build\temp.win-amd64-3.6
creating build\temp.win-amd64-3.6\Release
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\
14.15.26726\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Ic:\user
s\dq\anaconda3\include -Ic:\users\dq\anaconda3\include "-IC:\Program Files (x86)
\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\ATLMFC\include
" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC
\14.15.26726\include" /Tclru.c /Fobuild\temp.win-amd64-3.6\Release\lru.obj
lru.c
c:\users\dq\anaconda3\include\pyconfig.h(59): fatal error C1083: include フ
ァイルを開けません。'io.h':No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Comm
unity\VC\Tools\MSVC\14.15.26726\bin\HostX86\x64\cl.exe' failed with exit
status 2
Googleドライブに置いた画像のURL取得方法 (オリジナルとサムネイル)

# 内容

Google Apps Scriptを使って、Googleドライブに置いた画像ファイルの本体とサムネイルへのURLを取得します。

# 背景

LINE Messaging APIで画像を送る際には、画像本体とサムネイル(240x240以下)へのURLが必要です。「本体はともかくサムネイルが必須って…」と悩んで調べ始めました。
https://developers.line.me/ja/reference/messaging-api/#image-message

- いまさらですが、リファレンスを見返すと、**画像本体サイズも1024x1024以下**となっていますね。
- ここでは **見なかったこと** にします。

# 必要なサービス

- Google Apps Script
    - DriveAppを使うにあたって、なにか許可が必要だったような、違ったような…

# スクリプトと解説

```js
// Googleドライブ上で共有設定した画像ファイルへのダイレクトリンク (本体とサムネイル)
var originalBase = 'https://drive.google.com/uc?export=view&id=';
var previewBase  = 'https://drive.google.com/thumbnail?sz=w240-h240&id=';
```

- 変数定義です。
- 出オチでバレている気がしますが、上記のURLにGoogleドライブのファイルIDをくっつけると、目的のURLができあがります。
- previewBase のURLで指定している `sz=w240-h240` は、サムネイルサイズの上限(240x240)を示しています。画像のアスペクト比を保ったまま、指定の範囲に収まるように表示されます。

```js
// 外部サーバにある画像のURL
var sourceUrl = 'http://xxxx/.../xx.jpg';
// Googleドライブに保存するファイル名
var fileName = 'hogehoge.jpg';

// 画像を取得してGoogleドライブに保存
var fileBlob = UrlFetchApp.fetch(sourceUrl).getBlob().setName(fileName);
var file = DriveApp.createFile(fileBlob);

// 保存した画像に共有権を設定する (リンクを知っている全員が閲覧可)
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);

// 画像のファイルIDを取得する
var fileId = file.getId();
```

- 画像を取得・保存 → 共有権を設定 → ファイルIDを取得する部分です。
- 外部サービス(LINE)から画像が参照できるように、共有権が必要です。

```js
// for LINE Messaging API
var pushLINE  = 'https://api.line.me/v2/bot/message/push';
var CHANNEL_ACCESS_TOKEN = 'xxxxxxxxxxxxxxxx';
var userId = 'xxxxxxxx';

// Googleドライブ上の画像をLINEへプッシュ
UrlFetchApp.fetch(pushLINE, {
  'headers': {
    'Content-Type' : 'application/json',
    'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
  },
  'method' : 'POST',
  'payload': JSON.stringify({
    'to'       : userId,
    'messages' : [{
      'type'              : 'image',
      'originalContentUrl': originalBase + fileId,
      'previewImageUrl'   : previewBase  + fileId
    }]
  })
});
```

- LINEへの画像送信部分です。
- 「originalContentUrl」と「previewImageUrl」に、件のURLとファイルIDを指定します。

```js
// 画像ファイル削除
file.setTrashed(true);
```

- 送信後は、すぐにファイルを削除しても構いません。(未読でも大丈夫)

# 最後に

悔しくて試していませんが、ここで苦労して指定したサムネイル項目、実はオリジナルの画像をそのまま渡しても問題ないらしいですね。悩んで損した気分ですが、勉強になったのでまぁヨシとします。
docker で build した別の image から COPY する

例えば、 laravel や Rails などで、 build(npm run prod(laravel の例)等) 済みの js とか css とかを nginx や apche 用の Container に COPY したいケースなどで使う方法のメモ。

- nginx や apache Container の docker build 前に laravel や Rails の Container で js や css は生成(build)済みとする。
- かつ、 laravel や Rails の Container の Image の名称は workspace とする
- かつ、 js, css は `/var/www/app/public/js/*`, `/var/www/app/public/css/*` に存在するとする

```Dockerfile
# ..snip..
COPY --from=workspace /var/www/app/public/js /var/www/app/public/js
COPY --from=workspace /var/www/app/public/css /var/www/app/public/css
# ..snip..
```

みたいに `COPY` 命令に `--from=IMAGE_NAME` で指定する。

※用語がごちゃごちゃかも。気が向いたらちゃんと書く。
value-domainのDDNSをHTTPSで更新

# 参考にさせていただいた記事

[Raspiで動かすvalue-domainのDDNSスクリプト](https://qiita.com/kouichirou/items/b89beaf27942aadd9307)
と
[シンプルだけどIP変更チェック付きのValue DomainのDDNSアップデートスクリプト](https://qiita.com/yuya_presto/items/cd6bcd36c6bb18dac8bf)

お二方が記事を書かれた当時、value-domainのDDNSを更新するURLはHTTPSに対応していなかったようです。
~~丸パクリして~~参考にさせていただき、HTTPSで更新するように`http://`に`s`を追記しました。それだけです。
全く新規性がありません。。。


# ドメインの情報

value-domainにアクセスし、ドメインとパスワードを確認します。
デフォルトだとパスワードがログインパスワードが入っているようなので、DDNS更新用にパスワードを変更します。
![スクリーンショット 2018-08-16 5.58.00.png](https://qiita-image-store.s3.amazonaws.com/0/231763/32a62d94-49ad-a18e-6b04-2efa435ff754.png)


# スクリプトを丸パクリ

```bash:/etc/update_ddns.conf
# Place this file on /etc/update_ddns.conf
# SECURITY: run `chmod 600 /etc/update_ddns.conf'
# to make it unreadable by non-root users.
DOMAIN=***.***
PASSWORD=**************
HOST=*
```

```bash:/etc/update_valuedomain_ddns
#!/bin/bash

CONFIG_FILE='/etc/update_ddns.conf'
IP_CACHE_FILE='/tmp/update_ddns_ip'
DDNS_CACHE_FILE='/tmp/update_ddns_result'

# sources DOMAIN= , PASSWORD= and HOST=
source $CONFIG_FILE

old_ip=`[ -e $IP_CACHE_FILE ] && cat $IP_CACHE_FILE || echo ''`
new_ip=`wget --quiet -O - 'https://dyn.value-domain.com/cgi-bin/dyn.fcg?ip'`
if [ "$old_ip" = "$new_ip" ]; then
    echo "NO CHANGE ($new_ip)"
    logger -t UPDATE_DDNS "INFO: NO CHANGE ($new_ip)"
    exit 0
fi

url="https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=$DOMAIN&p=$PASSWORD&h=$HOST&i="
result=0
wget --quiet -O - "$url" 2>/dev/null | tee $DDNS_CACHE_FILE | grep 'status=0' >/dev/null && result=1

if (( !$result )); then
    echo `date` 'FAILED'
    logger -t UPDATE_DDNS "ERROR: FAILED result:" `cat $DDNS_CACHE_FILE`
    exit 1
fi

echo $new_ip > $IP_CACHE_FILE

echo "UPDATED ($new_ip)"
logger -t UPDATE_DDNS "INFO: UPDATED with new IP:$new_ip"
exit 0
```

本当に丸パクリです。


# 権限変更してcrontabで実行

```bash
$ sudo chmod 600 /etc/update_ddns.conf
$ sudo chmod 755 /etc/update_valuedomain_ddns
$ sudo crontab -e
```

`*/8 * * * * sh /etc/update_valuedomain_ddns`を追記します。

```bash
$ sudo dmesg | grep DDNS
```

ちゃんと8分ごとにチェックしているか確認します。
動いています。
Qiitaの機能についての備忘録

# はじめに（概観）

Qiitaの使い方や機能について俯瞰したい人向けの公式情報は、ヘルプにある。

- [Qiita - Qiita:Support](https://help.qiita.com/ja/categories/qiita/)

# 記事の投稿・編集
## 下書き

- 自動保存
  - 未投稿のものはもちろん、投稿済みの記事を編集した場合も自動で下書きに保存される
- 下書きの破棄
  - 未投稿の下書きを削除すると、当然記事は消えてなくなる
  - **投稿済み記事の編集中の下書きを削除すると、下書きが破棄されるだけで、投稿済み記事はそのまま**

----

何かあれば随時加筆するかもしれません。
jQueryで実際にコード書いてみる

少しjQueryをかじったので、練習がてら課題をやってみる。

```
<!DOCTYPE html>
<html>
<head>
<title>Programming Study</title>
<meta charset="utf-8">
</head>

<body>
<h1>Programming study application form</h1>

<form id="application">
<table>
<tr>
<th>Name</th>
<td><input type="text" name="name" size="30" maxlength="20"></td>
</tr>

<tr>
<th>E-mail adress</th>
<td><input type="email" name="email" size="30" maxlength="20"></td>
</tr>

<tr>
<th>Password</th>
<td><input type="password" name="password" size="30" maxlength="20"></td>
</tr>

<tr>
<th>Password Retype</th>
<td><input type="password" name="repassword" size="30" maxlength="20"></td>
</tr>
</table>

<button type="submit">submit</button>

</form>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script>
// ここにjQueryのコードを書いていきましょう！！

// 課題1. Nameに何も記入していないままsubmitボタンを押したときに、警告（アラート）を出す

// 課題2. 同様に、「Email adress」, 「Password」, 「Password retype」も、何も記入されていない場合に警告（アラート）を出そう

// 課題3. フォームを全て記入した状態で、submitボタンを押すと、ボタンの下に以下の奴が出てくるようにする。

/*

<登録情報>

名前： 上で記入した名前
メールアドレス： 上で記入したメールアドレス
パスワード： 上で記入したパスワード

*/

</script>

</body>
</html>
```
この課題1,2,3をクリアする

課題１．

```
$('application').submit(function(){
   var name=$('input[name="name"]')val();
   if(!name){
     alert('Name is not filld in')
   }
```
・submit：ユーザーが送信ボタンをクリックした際に処理を実行するメソッド

・var：変数を定義する

・val：value値の取得

・alert：警報

課題２．

```
  var email=$('input[name="email"]').val();
  if(!email){
    alert('Email is not filld in')
  }
  var password=$('input[name="password"]').val();
  if(!password){
    alert('Password is not filld in')
  }
  var passwordRetype=$('input[name="repassword"]').val();
  if(!repassword){
    alert('password Retype is not filld in')
  }
```
課題２では課題１でやった延長で変数にそれぞれのname属性の値をval()で取って、if文でそれぞれ処理する。

課題３．

```
$('button').after(
  '<h1>登録情報</h1>
  <p>名前:${name}</p>
  <p>メールアドレス:${email}</p>
  <p>パスワード:${password}</p>')
  event.preventDefault();
```
・after：指定した要素の下に要素をだす。

・event.preventDefault()：処理の強制終了