OmniAICreator/Qiita-1.07M huggingface dataset:
インスタンスを起動したままEC2のEBSボリュームのサイズ変更する

# インスタンスを起動したままEC2のEBSボリュームのサイズを変更する手順メモ

サイトを落とさずにEC2インスタンスのEBSボリュームのサイズを変更出来た。
本手順を行う場合は各個人の責任でお願いします。

1.AWS管理画面にログイン。

2.EC2→インスタンス: 容量アップしたいインスタンスのインスタンスIDをコピー。
![2_.png](https://qiita-image-store.s3.amazonaws.com/0/97158/f716b234-5ef9-5c2e-b05d-ef630c32923b.png)


3.EC2→ELASTIC BLOCK STORE→ボリューム: 2.でコピーしたインスタンスIDで対象のEBSを検索する。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/97158/b09cbda2-6f4e-7da9-bf2d-6058a64c989d.png)



4.アクションボタン→ボリュームの変更。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/97158/2f695b0e-7052-76c9-c741-8d3f133cfdec.png)


5.サイズを任意の値に書き換える。
![volume.png](https://qiita-image-store.s3.amazonaws.com/0/97158/fcc0c083-9241-9ef2-f9f6-e0c9f7494135.png)


6.変更ボタンをクリック→確認ダイアログ表示→はいボタンをクリック。
![confirm (1).png](https://qiita-image-store.s3.amazonaws.com/0/97158/7d8b8f26-bec6-9adf-c955-2fdc978a5a18.png)

7.状態がcompleteになるまで待つ。
![confirm_after.png](https://qiita-image-store.s3.amazonaws.com/0/97158/ae424558-9082-cf17-b811-f61e8481ee70.png)




8.状態がcompleteになったら対象のEC2インスタンスにsshログイン

9.lsblkコマンドで容量が増えている事を確認。
しかし、この時点ではパーティションのサイズが変わっていない。
>[xxx@xxx ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  50G  0 disk 
└─xvda1 202:1    0   8G  0 part /

10.growparコマンドで拡張する。
>[xxx@xxx ~]$ sudo growpart /dev/xvda 1
CHANGED: disk=/dev/xvda partition=1: start=4096 old: size=16773086,end=16777182 new: size=104853470,end=104857566

11.resize2fs コマンドでファイルシステムをリサイズ。
>[xxx@xxx ~]$ sudo resize2fs /dev/xvda1
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  50G  0 disk 
└─xvda1 202:1    0  50G  0 part /

12.lsblk もしくは df -hコマンドなどでリサイズが反映されている事を確認。
Ubuntu zplug install

Ubuntuでやる方法
結構~/.zshrcが重要な気がする

```
curl -sL --proto-redir -all,https https://raw.githubusercontent.com/zplug/installer/master/installer.zsh | zsh
```

## ~/.zshrcを書く

```~/.zshrc
# zplug
source ~/.zplug/init.zsh
zplug 'zplug/zplug', hook-build:'zplug --self-manage'
# theme (https://github.com/sindresorhus/pure#zplug)　好みのスキーマをいれてくだされ。
zplug "mafredri/zsh-async"
zplug "sindresorhus/pure"
# 構文のハイライト(https://github.com/zsh-users/zsh-syntax-highlighting)
zplug "zsh-users/zsh-syntax-highlighting"
# history関係
zplug "zsh-users/zsh-history-substring-search"
# タイプ補完
zplug "zsh-users/zsh-autosuggestions"
zplug "zsh-users/zsh-completions"
zplug "chrissicool/zsh-256color"
# Install plugins if there are plugins that have not been installed
if ! zplug check --verbose; then
  printf "Install? [y/N]: "
  if read -q; then
    echo; zplug install
  fi
fi
# Then, source plugins and add commands to $PATH
zplug load

zstyle ':completion:*:default' menu select=2
source ~/.zsh_aliases
```

## zshにログイン
```
$ zsh
```
## zshを通常のシェルに
```
$ chsh -s /bin/zsh
```
再起動
LINE Bot SDK for Node.js で、 「はい」「いいえ」を確認するメッセージを送りたい

LINE のチャットボットで、テンプレートメッセージという、Botから選択できるUIがある。

こういうやつ

<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/103885/461bddd0-73bf-6c56-783f-a39d931768bc.png">

これを Node.js の SDK を使ってどうやればよいか、調べるのに時間かかったのでメモ。

LINEが公式で出している、 API Reference には、なかったので、ソースコードを読んだ。といっても TypeScript の型定義で事が足りた。

公式リファレンス https://line.github.io/line-bot-sdk-nodejs/pages/api-reference/client.html
ソースコード https://github.com/line/line-bot-sdk-nodejs/blob/b884dbaf0062429085a5ee6b830f526502ffab42/lib/types.ts#L383-L431



```typescript
import { Client } from '@line/bot-sdk'

const message = {
  type: 'template',
  altText: 'エラーが発生しました。',
  template: {
    text,
    type: 'confirm',
    actions: [
      {
        type: 'message',
        label: 'はい',
        text: 'はい',
      },
      {
        type: 'message',
        label: 'いいえ',
        text: 'いいえ',
      },
    ],
  },
}

const client = new Client({
  channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.LINE_CHANNEL_SECRET,
})

client.pushMessage('user_id', message)
```
Windows10からUbuntu16.04にGUIでリモート接続する

WindowsからUbuntuにリモート接続する例としてsshがあるが、GUIでの操作ができない。本記事では、GUI操作ができるような方法を紹介する。ただし、初心者が調べながらざっと書いただけなので、間違いがあれば指摘いただきたい。なお、初めは予備知識や色々な選択肢を書いているだけなので、すぐに試したい場合は「設定」の章からでおｋ。

# 接続方法の選択肢
## VNC
バーチャルネットワークコンピューティング。リモート接続ができるソフト。

## Vino
Ubuntuにデフォルトでインストールされている。バックエンドにはVNCが動いている。

## RDP/XRDP
リモートデスクトッププロトコル。RDPは、Windowsに標準搭載されている。バックエンドにはVNCが動いている。XRDPは、RDPのLinux版でオープンソース化されている。

# Ubuntuデスクトップの選択肢
## GNOME/Unity (Ubuntu)
いつも使っているUbuntuデスクトップ。リモート接続の際は5900ポートで接続。マシンのデスクトップでログインした画面に、そのまま接続できる。つまり、デスクトップ側とリモート側の画面が同期される。人によってはこちらの方が好みかもしれない。ただ、少し重いのが欠点。

## LXDE (Lubuntu)
リモート接続の際は、本体の画面とは全く別の画面に接続することになる。ポート番号は5901～。軽いのでオススメ。

## Xfce (Xubuntu)
試したことはないが、これも軽量っぽい。

## MATE (Ubuntu MATE)
最近流行っている？

# クライアント（Windows）側ソフトの選択肢
## UltraVNC
無料ソフト。接続方法に、VNCやVinoを用いた場合に使用する。

## リモートデスクトップ
Windowsにデフォルトでインストールされているソフト。接続方法に、XRDPを用いた場合に使用する。

# 設定
ここではVNC+LXDE+UltraVNCを用いた方法を紹介する。

## サーバ(Ubuntu)側
VNCサーバをインストールする。
```
sudo apt install vnc4server
```

LXDEをインストールする。ここで、LXDEを単体でインストールすると、なぜかうまくいかないので、Lubuntuでまとめて入れる。
```
sudo apt install lubuntu-desktop
```

LXDEを使えるように、以下の通り設定ファイルを編集する。
```
echo "lxsession -s LXDE -e LXDE" > ~/.xsession
```

以下設定ファイルも編集する。
```
sudo nano .vnc/xstartup
```
最終行を以下に変更する。
> /usr/bin/startlxde &

VNCサーバを起動する。ここで、クライアント側にあわせて、画面の解像度を指定する。
```
sudo vncserver -geometry 1920x1200
```

ちなみに、サーバの停止は以下のように行う。以下の例では、ポート5901を指定して停止している。
```
vncserver -kill :1
```

## クライアント側(Windows側)
UltraVNCをネットからインストールする。
https://forest.watch.impress.co.jp/library/software/ultravnc/

特に設定は不要で、UltraVNCから172.19.82.61:5901のように指定して、Connectをクリックすると接続できる。
Sparkでファイルを読み込む際にスキーマ検証する



読み込み時にoptionで'FAILFAST'を指定すればよい。
c.f. [DataFrameReader](https://spark.apache.org/docs/2.3.1/api/java/org/apache/spark/sql/DataFrameReader.html)

もし、入力データがスキーマに対して不適切な場合、
エラー時に、Py4JJavaErrorを出す。

```python:型判定
try:
    df = spark.read.format('org.apache.spark.csv').schema(schema).option('mode', 'FAILFAST').csv(file_path)
    df.show()
except py4j.protocol.Py4JJavaError as e:
    print(e.java_exception.getCause().toString())
```

Py4JJavaErrorは、Spark周りのエラーを色々拾ってしまうので、
エラー検出後にハンドリングする必要があることに注意。
CD法メモ

## Gibbs distribution
```math
\begin{eqnarray}
p(\bf{x}; \bf{\xi}) &=& \frac{e^{-E(\bf{x}; \bf{\xi})}}{Z}  \\
Z &=& \sum_{\bf{x}} e^{-E(\bf{x}; \bf{\xi})}
\end{eqnarray}
``` 

## likelihood
```math
\begin{eqnarray}
\frac{\partial}{\partial \bf{\xi}} \log \left( p(\bf{x}; \bf{\xi})\right) 
 &=& 
 \frac{\partial}{\partial \bf{\xi}} \log 
  \left( 
   \frac{e^{-E(\bf{x}; \bf{\xi})}}{Z}
  \right) \\
 &=& 
  - \frac{\partial}{\partial \bf{\xi}} 
   E(\bf{x}; \bf{\xi})
  - \frac{\partial}{\partial \bf{\xi}} \log(Z) \\
 &=& 
  - \frac{\partial}{\partial \bf{\xi}} 
   E(\bf{x}; \bf{\xi})
  - \frac{\partial}{\partial \bf{\xi}} 
   \log
    \left(
      \sum_{\bf{x}} e^{-E(\bf{x}; \bf{\xi})} 
    \right) \\
 &=&
  - \frac{\partial}{\partial \bf{\xi}} 
   E(\bf{x}; \bf{\xi})
  - \frac{1}{Z}
      \sum_{\bf{x}} 
     \frac{\partial}{\partial \bf{\xi}} \left(e^{-E(\bf{x}; \bf{\xi})} \right) \\
 &=&
  - \frac{\partial}{\partial \bf{\xi}} 
   E(\bf{x}; \bf{\xi})
  - \sum_{\bf{x}} 
   \frac{e^{-E(\bf{x}; \bf{\xi})}}{Z}
     \frac{\partial}{\partial \bf{\xi}} \left( -E(\bf{x}; \bf{\xi}) \right) \\
 &=&
  - \frac{\partial}{\partial \bf{\xi}} 
   E(\bf{x}; \bf{\xi})
  +  \left \langle
      \frac{\partial}{\partial \bf{\xi}} E(\bf{x}; \bf{\xi}) 
     \right \rangle_{\bf{x}} \\
\end{eqnarray}
``` 

## Contrastive Divergence method

- replace the second term sampling summations
- it is known that a few sampling trial works well empirically.
Material-UIとNext.jsを併用すると、Linkで困る。

## 背景
最近バイト先のプロダクトを、Next.jsをTypescriptでやりつつUIはMaterial-UIでよしなにするという技術スタックでやっています。

## 困ったこと
Material-UIの`Card`を配置してその中の`CardActions`のchildrenとしてNextの`Link`を渡したら`Link: unknown props found: className`と言われました。

## 原因
`CardActions`のchildrenには自動的に`className`が振られるらしい。しかし、Nextの`Link`に`className`を渡すと、上記の警告が出てしまう、ということらしい。

## 解決策
propsとして渡された`className`を`Link`ではなく`Link`の中のアンカーに渡してやるようなコンポーネントを作ってしまえばいい。今回の場合はMaterial-UIなので、そのアンカーは`Button`コンポーネントです。LinkのchildrenとButtonのhrefはこの場合は不要なので、Omitで省きます。

```tsx
import React from 'react'
import { Button } from '@material-ui/core'
import { ButtonProps } from '@material-ui/core/Button'
import Link, { LinkState } from 'next/link'

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

interface ButtonLinkProps {
  linkProps: Omit<LinkState, 'children'>
  buttonProps: Omit<ButtonProps, 'href'>
  className?: string
}

const ButtonLink: React.SFC<ButtonLinkProps> = ({ linkProps, buttonProps, className, children }) => (
  <Link {...linkProps} passHref>
    <Button className={className} {...buttonProps}>
      {children}
    </Button>
  </Link>
)

export default ButtonLink

```

## 追記
これをやったあと、CTOから、「`linkProps`、`buttonProps`わけずに普通に渡せるようにしたいっすね」と言われたので、変更です。

```tsx
import React from 'react'
import { Button } from '@material-ui/core'
import { ButtonProps } from '@material-ui/core/Button'
import Link, { LinkState } from 'next/link'

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

type ButtonLinkProps = Omit<ButtonProps, 'href'> & Omit<LinkState, 'children' | 'passHref'> & {
  className?: string
}

const ButtonLink: React.SFC<ButtonLinkProps> = ({
  href,
  as,
  prefetch,
  shallow,
  scroll,
  replace,
  className,
  children,
  ...otherProps
}) => (
  <Link href={href} as={as} prefetch={prefetch} shallow={shallow} scroll={scroll} replace={replace} passHref>
    <Button className={className} {...otherProps}>
      {children}
    </Button>
  </Link>
)

export default ButtonLink

```

## 最後に
もっといいやり方あったら教えて、、、
Visual Studio Communityのインストール手順

![solution-overview01.jpg](https://qiita-image-store.s3.amazonaws.com/0/245438/fac3d03c-eff1-f8b2-baba-2f5ed88594df.jpeg)

Windowsのデスクトップアプリケーションを作りたい場合、言語や開発環境はいろいろありますが最も簡単に作りたいと思ったらVisual Studioが最良の選択肢になると思います。
今回は、Visual Studioのインストールの手順を紹介します。
難しいことはゆくゆくネットで調べるとして、まずはVisual Studioでアプリケーションを作成できるところまで簡単に説明します。

#Visual Studioって?

Microsoft社が開発、提供している統合開発環境です。
じゃあ統合開発環境ってなに?ということになりますが、コーディングして、デバッグして、アプリケーションを配布するまでの一連の作業をこれ一つででき、そしてそれらの作業を効率的かつ快適に行うことのできる様々な便利機能が搭載されている開発用のアプリケーションのことです。
Visual Studioを使えばデスクトップアプリケーションを簡単に作れると考えてください。

#どのエディションをインストールしたらいいの
さて、現在(2018/03/26)、最新のバージョンはVisual Studio 2017で、エディションは以下の3種類があります。

- Enterprise
- Professional
- Community

小規模で利用する分には無料で利用できるCommunityを選択すれば良いでしょう。

#インストール手順
ではさっそくインストール手順について説明していきます。

### ダウンロード
[こちら](https://www.visualstudio.com/ja/downloads/?utm_source=mscom&utm_campaign=msdocs)のダウンロードページへ移動します。
Visual Studio Community 2017の「無償ダウンロード」ボタンをクリックして、インストーラをダウンロードします。
![2018-03-26_LI (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/245438/286b058d-9ec3-4d10-e697-5c28bec46b2d.jpeg)

### ダウンロードしたインストーラを実行
ライセンス条項への同意などおきまりのダイアログが表示されるので、それらに同意して「続行」していきます。

### ワークロード(開発のための機能セット)を選択
開発したアプリケーションに応じて必要な機能を選択します。
デスクトップアプリケーションの開発であれば、

* 「.NET デスクトップ開発」
* 「ユニバーサル Windows プラットフォーム開発」

の2つにチェックを入れておけば良いでしょう。
これらのワークロードは後からいつでも追加や削除ができるので、ここで先のことを考えてすべてインストールする必要はありません。

![2018-03-26 (2)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/245438/08382703-95b1-89fc-5eca-0f4ecf7b1421.jpeg)

### インストール開始
上のワークロードの選択画面において、右下の「インストール」ボタンを押すとインストールが始まります。
画像では「変更」になっていますが、初回インストールの場合は「インストール」となっています。


#おわりに
以上でVisual Studioのインストールは完了です。
統合開発環境というといろいろと設定したり難しそうなイメージがありますが、Visual Studioはインストーラを実行して必要な機能にチェックを入れるだけでOKです。
インストールが完了したら、もうアプリケーションを作り始めることができます。

次はデスクトップアプリケーションを作ってみましょう。
Luhn チェックおよびコード生成

## Luhn ってなんぞ
詳しくは [WikiPedia](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwiW1sGNyJvcAhWCGpQKHUzeDKwQFggoMAA&url=https%3A%2F%2Fja.wikipedia.org%2Fwiki%2FLuhn%25E3%2582%25A2%25E3%2583%25AB%25E3%2582%25B4%25E3%2583%25AA%25E3%2582%25BA%25E3%2583%25A0&usg=AOvVaw2ZcKZxZFu5XxQBJWfVj2bJ) 参照で。
ざっくり言えば、数字列の入力が正しいかどうかを検証する仕組みの簡易版。
クレジットカードの番号に使われてる。
このチェックで正しいと判断されても、間違っている可能性はあるので、厳密な判定が必要なケースには使えない。

## 車輪の再開発感
アプリで使用することがあったので。
多分 node なら既になんらかの便利なモジュールが存在するはず。
クーポンコードとして使いたかったらしい。

### 利用目的
管理画面から数字列を発行 -> ユーザに配布 -> ユーザがアプリに入力 -> 送信前にアプリ内で簡単に入力チェック -> サーバ送信

## 実装例

```js
export function check(numbers: string): boolean {
  const len = numbers ? numbers.length : 0
  let sum = 0
  let odd = true

  for (let i = len; i > 0; i--) {
      const num = Number(numbers[i - 1])
      sum += odd ? num : num * 2
      odd = !odd
  }

  return sum % 10 === 0 && sum > 0
}

export function generate(numbers: string): string {
    const len = numbers ? numbers.length : 0
    let sum = 0
    let odd = false

    for (let i = len; i > 0; i--) {
        const num = Number(numbers[i - 1])
        sum += odd ? num : num * 2
        odd = !odd
    }

    const checkNumber = ( sum % 10 ) > 0 ? 10 - ( sum % 10 ) : 0
    return numbers + String(checkNumber)
}
```
実は存在するいろいろなカーソルたち

※今回雑です。

##経緯
ゲームを作っているうえで、手のアイコンや左右の矢印アイコンなどを組み込んでいたら偶然見つけました。

##見つけ方
適当にプロジェクトを作成して、window.hをインクルードした状態で以下のコードを適当なところでもいいので書いてください。
実のところは「IDC_SIZENWSE」だけでいいです。

```
 cursor = LoadCursor(NULL, IDC_SIZENWSE);
 SetCursor(cursor);
```

そうしたら「IDC_SIZENWSE」を右クリックして「すべての参照を検索」というのをクリックして下に出てくるものの中に「WinUser.h」というファイルがあると思うのでそれを開いてください。

以下のような形で現れると思います。


![vdicon.png](https://qiita-image-store.s3.amazonaws.com/0/252485/47e97438-375c-3d8e-bb06-6b8357fcacf3.png)

この画像にある「IDC_~」がすべてアイコンです。
気になる方は上のコードを見て「LoadCursor」を調べて弄ってみてください。懐かしいものからなんだこれってものまでいろいろあります。
renderメソッドをもう一度呼ぶためにわざとsetStateする

# firebaseのrealtime dbを使用して開発しているときにハマったこと
firebaseのrealtime からデータを取得した後、setStateに成功していたがそれがrender メソッド呼び出してreturnする時までにstateが更新されていなくてもう一度renderメソッドを呼び出したかった。だからわざと必要もないstateを定義してsetStateを呼び出した。それによってrenderされたから目標は達成できた。
Kingfisherの詳しい使い方（チートシート+α)

# Kingfisherのキャッシュについて
* 原則キャッシュされる
* 自分でキャッシュする仕組みを作る事もできる 

# メモリだけで運用したい
## 読み込み時
```
imageView.kf.setImage(with: ImageResource(downloadURL: pictureURL), options: [.cacheMemoryOnly], completionHandler: { (image, error, cacheType, imageUrl) in
})
```

## キャッシュに存在するか
``` 
if (CacheType.none != ImageCache.default.imageCachedType(forKey: pictureURL.absoluteString) {
// ある
}
```

# その他
## 独自のImageCacheを作る
```
let cache = ImageCache(name: "longer_cache")
```

## ディスクキャッシュのサイズを変更
```
cache.maxDiskCacheSize = 60 * 60 * 24 * 30
```

## ディスクキャッシュの期間を変更
``` 
// 3日に変更。デフォルトでは7日間
cache.maxCachePeriodInSecond = 60 * 60 * 24 * 3
```

## キャッシュを利用せず強制的に読み込み&キャッシュ更新
```
imageView.kf.setImage(with: url, options: [.forceRefresh])
```

## キャッシュを指定
```
let cache = ImageCache.default
imageView.kf.setImage(with: url, options: [.targetCache(cache)])
```

## 今すぐキャッシュを消したい
``` 
ImageCache.default.clearMemoryCache()
```

# 参考
* [チートシート](https://github.com/onevcat/Kingfisher/wiki/Cheat-Sheet)
Rubyで線形探索法（リニアサーチ）を書いてみた

# はじめに

ITエンジニアなら、基本的なアルゴリズムは知っておきたいよねとか言われても、一つも知らなかった。

まず、なぜ知って起きたいほど重要なのかをハラ落ちさせたかったので色々調べてみた。

[エンジニアの面接でアルゴリズムを組ませる理由](https://j.ktamura.com/archives/1348)

この記事に、アルゴリズムが大事だという２つ理由がありました。

> 速く基本的なアルゴリズムが正しく組める人は、他のコードを書かせてもバグを入れにくいうえ、作業が速い。もちろん、アルゴリズムを組むのが遅くても、バグの少ないコードを書く人は沢山いる。でも、アルゴリズムを速く正確に組める人は概して他のコードを書かせても素早いし、バグを入れにくい。雇う側からすれば、バグが少なく開発スピードが速いに越したことはない。

もう一つは

> 効率的なアルゴリズムはコスト削減につながる。当然の話だが、同じ機能だったら出来る限り少ないリソースでできた方が、コストが減って儲けにつながる。ソフトウェアもビジネスなので、コストが低いに越したことはない。そこで様々なソフトウェアの最適化がされるのだが、多くの場合、もっとも大幅にリソース使用量を減らせるのが、より効率的なアルゴリズムを使うことだ。裏を返せば、効率的なアルゴリズムがちゃちゃっと組めないエンジニアは、コードを書く度に、それだけ会社に損をさせていることになる。

アルゴリズムを勉強すると、応用力が効くし、コードの安全性も増すことができるということだろう。よし、ハラ落ち。

次に、本屋で簡単そうなアルゴリズムの本を買ったので、それを今勉強中のRubyで書いてみようというのをやって行こうかと思います。

今回は...

## 線形探索法

教科書はp90にあります。

線形探索法（リニアサーチ）は、探索アルゴリズムの一種です。探索アルゴリズムとは、目的のデータを探し出すアルゴリズムのことです。検索エンジンもこのアルゴリズムを利用しているみたいです。

## 線形探索法（リニアサーチ）とは

線形探索法（リニアサーチ）とは、**単純にいうと先頭から順番に調べるアルゴリズム**です。ただし、アルゴリズムの単純さゆえ、探索効率が他のルゴリズムと比較するとそれほどいいわけじゃないみたいです。

箱に入ってるボールが、何個も横に並んでるとします。ボールには番号が書いてあって、自分からは見えない。それを左から順番に、確認していく、これが線形探索法（リニアサーチ）のイメージです。

## 線形探索法（リニアサーチ）のアルゴリズム

ポイントは3つ

- 配列に保存されたデータを先頭（左）から順番に探索する
- 探索処理は反復構造
- 反復構造では終了条件をわすれずに

です。

箱に入ってるボールが、何個も横に並んでるイメージはこんな感じです。

![S__96247812.jpg](https://qiita-image-store.s3.amazonaws.com/0/14191/1bd27aa2-25ba-7988-94b0-34f9fd0fa105.jpeg)

## 処理の流れ

それぞれの値は、配列名（`array`）と、index番号を使って表せます。

例えば

```rb
array [0]

=> 4
```

という感じ。

| 配列の要素 | 値 |
|-----------|------------|
| array [0]       | 4 |
| array [1]     | 2 |
| array [2]       | 3 |
| array [3]         | 5 |
| array [4]       | 1 |

線形探索法（リニアサーチ）はシンプルに、上から比較して、あればその数字を返す。なければ「無い」というだけの単純なアルゴリズムです。それでは、それをrubyで記述していきます。

## Rubyで線形探索法（リニアサーチ）を書いてみた

```rb

array = [ 4, 2, 3, 5, 1 ]
numbers_of_array = array.count

def linear_search(array, numbers_of_array, target)

  index = 0

  loop do
    if index == numbers_of_array
      return -1
    elsif array[index] == target
      return index
    end
    index += 1
  end
end

# 探したい値
target = 5

# メソッド（linear_search）
# array 引数 配列オブジェクト
# numbers_of_array 引数 配列の要素数
# target 引数
# result 戻り値の格納先
result = linear_search(array, numbers_of_array, target)

if result == -1
  puts "値:#{target}は配列内にありません"
else
  puts "値:#{target}のインデックス:#{result}"
end

```

`linear_search`というメソッドに３つの引数を指定して、処理させて任意の値があれば、メソッドの下にあるif分の`else`内を出力、なければ`result == -1`の結果を出力させてます。

以上です！行けてないコードであればご指摘ください。

# レポジトリ

https://github.com/ryosuketter/algorithms_in_ruby

# 参考図書

[伊藤静香. アルゴリズムを、はじめよう. 第3章. インプレス, 2012, p. 90-100. ](http://amzn.asia/e2TwMNK)

# 参考
- https://j.ktamura.com/archives/1348
- https://www.rubylife.jp/ini/for/index6.html
- https://chaika.hatenablog.com/entry/2016/03/19/083000
- https://book.mynavi.jp/manatee/detail/id=64253
- https://www.codereading.com/algo_and_ds/algo/linear_search.html
XcodeがサポートしていないiOSバージョンへの実機ビルド

iOS開発を再開しました。担当しているプロジェクトが増える度に、このような状況になってしまいます。

<img width="533" alt="スクリーンショット 2018-07-13 15.30.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/11156/d9f472f2-00fb-8186-0fda-987daa854642.png">


中でも困るのが、プロジェクトで採用されているXcodeのバージョンが古い場合です。最新のiOSがサポートされておらず、サポート外のOSがインストールされている端末での実機デバッグが出来ません。このような状態になります。

<img width="412" alt="スクリーンショット 2018-07-13 15.20.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/11156/93277db3-c7b6-a698-59b4-af8af8f987ea.png">


Xcodeのバージョンを上げて対応するのが良いですが、運営しているサービスによっては様々な理由で上げられないことがあります。そのような時、古いXcodeでも実機ビルドできるようにする方法の備忘録です。



# 新しいXcodeをダウンロード
ビルドしたい実機のiOSをサポートしているXcodeをインストールします。

Xcodeのダウンロードは[こちら](https://developer.apple.com/download/more/
)から出来ます。複数バージョンのXcodeを共存させることは可能なので上書きしないように気をつけてください。


# DeviceSupport
ダウンロードしたXcodeのDeviceSupportから求めているiOSのフォルダをコピーします。今回はXcode9.1でiOS11.4がインストールされた実機へのビルドをしたいため下記フォルダから`11.4 (15F79)`をコピーします。

```
cp -r /Volumes/Macintosh\ HD/Applications/Xcode9.4.1.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.4\ \(15F79\) /Volumes/Macintosh\ HD/Applications/Xcode9.1.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/.
```

# その他
画像付きのとても詳しい[記事](http://kan-kikuchi.hatenablog.com/entry/Could_not_locate_device_support_files)がありました。
rsyncで任意のファイルだけをコピーしたり削除したり

hoge.jpgを同サーバ内のdev→stgにコピーしたり削除したりする感じで。

# コピー
rsync -avz --include 'hoge.jpg' --exclude '*' /var/www/dev/htdocs/images/ /var/www/stg/htdocs/images/

# 削除
rsync -avz --delete --include 'hoge.jpg' --exclude '*' /var/www/dev/htdocs/images/ /var/www/stg/htdocs/images/
Rubyのtrueとfalseまとめ


#true,falseについて
Rubyが**true**を返すものか、**false**を返すものかをまとめました。

**true** ... 条件式が正立するとき。[真]つまりfalse, nil の時以外全て
　
**false** ... 条件式が成立しないとき[偽]。つまりfalse, nil の時

if文などで真偽値（true/false）を求める際、比較演算子が重要になってくる。

| == | a = b | aとbが等しい |
|:--|:--|:--|
| != | a != b | aとbが等しくない |
| > | a > b | aはbより大きい |
| >= | a >= b | aはb以上 |
| < | a < b | aはbより小さい |
| <= | a <= b | aはb以下 |


##存在しないキーを指定する
存在しないキーを指定した際nilが表示されます。（このときのnilはfalseではない）


```ruby:qiita.rb

user={name:"rika",age:26}
puts user[:height]  #=>nil
```

if文で存在しないキーを指定した際nilが表示されます。（このときのnilはfalseです。なぜなら条件式がなり立たなかったから）
ハッシュに[:height]があったら”へー”　、なかったら”ほー”　と返すように指示するように書きました。
このときハッシュに[:height]は存在しておらず条件式が成り立たない。

```ruby:qiita.rb

user = {name:"rika",age:26}

if user[:height]
　　　　　　puts "へー"　　　　　　　　　　　　#=>nil


else
  　　puts "ほー"

end  
```

実行結果↓

```
$ ruby sample.rb 
ほー
```




##補足：to_iメソッドとto_sメソッドについて
to_iメソッドは**文字を数値に**変換するもの、to_sメソッドは**数値を文字**に変換するもの

<to_iメソッドを用いる例＞
>1=="1"　　
 =>false

これは数値の１と文字列の１なので等しくない。
ですが
>1=="1".to_i
=>true

これはto_iメソッドを用いると数値の１と文字列の１で等しくなる。

（to_sメソッドも同じ考え方です）
 




##これらをふまえて
文字列や数値に変換しなければ最初に記載した通りにRubyがtrue,falseを返すが、変換できるものもある
~nilの場合~ nilは数値にも文字列にもなれる
nil.to_iは０になるのでtrue
nil.to_sは" "になるのでtrue

~true,falseの場合~　true,falseは文字列にだけなれる
true.to_iは数値に変換できずエラーが起こるのでfalse
true.to_sは"true"になるのでtrue
firewalld再起動後のDockerコンテナ起動失敗

トラブルシューティングとして備忘録的に書いてます

### 事の発端
firewalldで閉じるように設定されていたSSHポートがいつの間にか開いていた:scream:
原因は不明だが、firewalldが停止していた可能性があったためfirewalldを再起動したようです

その後、dockerで動かしてるredashのupgradeした時にコンテナが起動しなくなりました...:crying_cat_face:

### 現象
改めて現象を説明すると、redashをupgradeするため一旦コンテナを停止しました
この時はターミナル上は特にエラーもワーニングも出てなかったです

最新のredashイメージpullして、コンテナ起動した時に↓のエラーが発生して
コンテナ起動できなくなりました...:sweat_smile:
※ちなみにredashのDBはホストにあったため無事

```
Creating network "redash_default" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-c00823472107 -j RETURN: iptables: No chain/target/match by that name.
 (exit status 1))
```

iptablesが絡んでいるようなので
`docker`と`iptables`をキーワードに調べると
どうやらDockerデーモンと、iptablesを作成するfirewallデーモンの起動順序が重要らしい

[Why am I having network problems after firewalld is restarted?](https://success.docker.com/article/why-am-i-having-network-problems-after-firewalld-is-restarted)によると
1. iptablesはfirewallデーモンで作成される
2. iptablesは永続的ではなくシステムが起動するたびに作成される
3. dockerデーモンはコンテナ起動/停止時にネットワークを作成・破棄する
4. firewalldが起動・再起動するとき、iptalbesのDOCKERチェーンは削除される
ということが分かった。

上記1～4より起動順序を
　firewalldを起動
　　↓
　dockerデーモン起動
にしないといけないと分かった

### 結果
起動順序を
　dockerデーモンを一度停止
　　↓
　firewalldを起動
　　↓
　dockerデーモンを起動
にすることでdockerコンテナが起動できたことを確認しました
IE11でオブジェクトは 'from' プロパティまたはメソッドをサポートしていません。と言われたときは

## 環境

* Windows10
* IE11
* Babel-preset-es2015

## 状況

IE11で以下のようなエラーが出ました

```
オブジェクトは 'from' プロパティまたはメソッドをサポートしていません。
```

本当に何を言っているのかわかりません。エラーが出たとされる行も全く関係のない場所が指されていました

## 原因

僕の場合、このエラーの原因は**スプレッド演算子**でした

```js
[...files].map((file, index) => {
```

FileListをスプレッド演算子で配列にパースしようとした際のエラーでした

なので、これをfor文に書き換えれば、エラーは解消されました

めでたしめでたし

## おわりに

BabelがPolyfillした際に置き換わったコードで発生したエラーかと思われますが、IEのエラー表示が不親切すぎてデバッグが大変でした

似たようなエラーが出た方は、新しい構文のPolyfillがうまく言っていない可能性があるのでチェックしてみるといいかもしれません
Twitter4JをGradleで開発する

# Twitter4Jはmavenベース

```pom.xml``` をごにょごにょして ```mvn``` コマンドでビルドして ```jar``` 等を作ります。
残念ながら Android 開発で利用する ```AndroidStudio``` では 3.0 あたりから maven プロジェクトを扱えないため、別途 ```IntelliJ IDEA``` といった IDE と ```mvn``` コマンド自体のインストールを行わないと ```Twitter4J``` の開発が行えない状況でした。

# Twitter4JをGradleで開発する

https://github.com/takke/twitter4j を使ってください。```pom.xml``` を ```build.gradle``` に変更し、Gradle でビルドできるようにしてあります。

ビルド方法は https://github.com/takke/twitter4j/blob/master/BUILD_INSTRUCTION.md に書きました。

**(2018/7/24追記)**

https://github.com/takke/twitter4j は https://github.com/takke/twitter4a (Twitter4A) に変わりました。

```Twitter4A``` を使うか、```build.gradle``` を ```Twitter4J``` に持って行けば使えるはずなのでご利用ください。
Ruby初心者課題 return スコープ　メソッドについて

**課題を解いて学んだことを書いていきます:smiley:**



Q 以下のコードを実行すると、ターミナルにはなんと表示されるでしょうか？

```ruby:qiita.rb

 def rename(name)
  name = "#{name}::CAMP"
  return name
end

name = "TECH"
rename(name)
puts name

```


解答↓

TECH

メソッドの中で定義された変数（今回は2行目のname)はメソッドの中でしか使えない。（変数のスコープという）
メソッドの中でreturnを使うと、呼び出し元で値を受け取れるようになる。




**＜returnの性質＞**
返り値（戻り値）を返す
メソッドの処理を終了させる→returnの後にあるメソッドの処理は実行されない


※他の言語では関数の返り値はreturnメソッドで設定されることが多いが、Rubyでは**return**を省略することができ、メソッド内で最後に実行された値が自動的に入るという設計になっている。
RubyGems.org で開発中の 2FA を試す

npm で起きた下記のインシデントを見て RubyGems.org ではどうなっているのか確認してみたところ、Web UI 側の 2FA 機能が最近マージされていたのでメモしておく。
[2018/07/12 に発生したセキュリティ インシデント (eslint-scope@3.7.2) について](https://qiita.com/mysticatea/items/0141657e4478d9cf4614)

## 注意
- 投稿時点 (2018/07/13) の開発途中の情報であること
- アカウントの MFA が有効でも、`mfa_feature=true` の Cookie を持っていないと 2FA なしでログインできるため __今のところ効果はない__ こと
    - `gem cert` コマンドで署名する手はある [Security - RubyGems Guides](https://guides.rubygems.org/security/)

## 手順

### rubygems.org の Cookie を変更する
現時点では全ての開発は完了していないので隠されているらしい。
使うには Cookie でオンにする必要がある。

コンソールから `document.cookie='mfa_feature=true;path=/'` など。

### デバイスを設定する
上記の Cookie を持った状態でログインして、[edit profile] 画面を開く。
下の方に Multifactor authentication の設定項目ができているので、Google Authenticator や Authy などで設定する。
Recovery Token を忘れずに保管する。

### ログインする
Cookie を持った状態でログインする。
次の画面で OTP を聞かれる。

### 無効にするには
`mfa_feature=true` の Cookie を持った状態で [edit profile] を開いて、OTP か Recovery Code を入力することで無効化する。

## source
[RFC: Add 2FA auth to RubyGems.org · Issue #1252 · rubygems/rubygems.org](https://github.com/rubygems/rubygems.org/issues/1252)
[[RFC][GSoC] Two factor authentication of RubyGems · Issue #1725 · rubygems/rubygems.org](https://github.com/rubygems/rubygems.org/issues/1725)

[edit profile]: https://rubygems.org/profile/edit
AWS DataPipelineで RDS Auroraに接続するときはJDBCDatabaseを選択しましょう

###AWS DataPipelineで RDS Auroraに接続するとエラーが出る

RDSDatabaseを選択して、Activateだ！

`DriverClass not found for database:aurora`

えーっと、なんでだろ？

###サポートに連絡だ

```
■原因及び対応方法につきまして
「DriverClass not found for database:aurora」エラーは Data Pipeline に含まれる JDBC ドライバが
MySQL や PostgreSQL には対応しているものの、Aurora に対応していないことが原因でございます。
```

##Auroraに対応していない？ Auroraなのに？
ということでパイプラインではJDBCDatabaseを設定しましょう

###JDBC ドライバのダウンロード
- 下記 MySQL のサイトより、MySQL Connector をダウンロードします。

https://dev.mysql.com/downloads/connector/j/5.1.html

- 圧縮ファイルを解凍してS3へ

「mysql-connector-java-5.1.46.jar」を Data Pipeline から起動される EC2 インスタンスよりアクセス可能な S3 バケットへアップロードする。S3 へアップロードした JDBC ドライバはJDBCDatabase設定の時に指定する。

###パイプラインのJDBCDatabase 設定

- Type :JDBCDatabase
- Connection String: jdbc:mysql://【Auroraのクラスターエンドポイント】:3306/【データベース名】
- Password: 【RDS DB接続パスワード】
- Jdbc Driver Jar Uri: s3://【事前準備でjarファイルを配置したS3バケット・プレフィックス】/mysql-connector-java-5.1.46.jar
`「Jdbc Driver Jar Uri」は「add an optional field...」から追加`
- Jdbc Driver Class: com.mysql.jdbc.Driver
- Username: 【RDS DB接続ユーザ名】
さくらのクラウドでRancherOS(v1.4+)が起動しない場合の対応

2018/7/13現在、さくらのクラウドから提供されているRancherOSは`v1.4.0`となっています。

これを使ってサーバ作成すると問題が発生する場合がありました。

## 症状

コンソールに以下のような表示がされ、延々と再起動を繰り返す。


<img width="839" alt="ros_boot_fail.png" src="https://qiita-image-store.s3.amazonaws.com/0/20668/5870217c-4e54-d8c2-e9d0-0c39a84442b9.png">

## 原因

実はこのバージョンからメモリの要件が変わったらしく、`1280MB以上のメモリ`が必要とのことです。

#### RancherOSのドキュメント

> refs: https://rancher.com/docs/os/v1.x/en/installation/running-rancheros/workstation/boot-from-iso/
> You must boot with at least 1280MB of memory.

なので、さくらのクラウドの最小プランである`1コア/1GBメモリ`プランだとこの問題が発生する可能性があります。

## 対応

メモリ2GB以上のプランを使いましょう。

以上です。
reactのstateはsetStateした瞬間に更新されるわけではない😭

reactでsetStateした瞬間にstateが更新されると思われがちだが。。。（自分もそう思っていた）

実際は「renderメソッドが呼ばれて描画されるまでにはstateが更新されるようになっている」という認識に公式docを読んでから至った。

`
Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
`
https://reactjs.org/docs/state-and-lifecycle.htmlより
Pythonで世界地図-17（円や長方形などの図形を描画）

参考
Matplotlibで円や長方形などの図形を描画
https://note.nkmk.me/python-matplotlib-patches-circle-rectangle/

matplotlib.patches.Ellipseドキュメント
https://matplotlib.org/api/_as_gen/matplotlib.patches.Ellipse.html

matplotlib.patches.Rectangleドキュメント
https://matplotlib.org/api/_as_gen/matplotlib.patches.Rectangle.html

楕円・矩形はangleパラメータがあるので角度を付けることが出来ます。

```python:
#!/usr/bin/python3
# coding: UTF-8

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig = plt.figure()
ax = plt.axes()

map = Basemap(projection='ortho', lat_0=35, lon_0=135,
              resolution='l', area_thresh=1000.0)

map.drawcoastlines()

x,y = map(135.,35.)
x1,y1 = map(137.,33.)

c = patches.Circle(xy=(x, y), radius=1000000, fc='g', ec='r') #半径1000000mの円
e = patches.Ellipse(xy=(x1, y1), width=3000000, height=1000000, fc='b', ec='y') #楕円
r = patches.Rectangle(xy=(x, y), width=1500000, height=2000000, ec='#000000', fill=False) #矩形（塗り潰しなし）
ax.add_patch(c)
ax.add_patch(e)
ax.add_patch(r)

plt.axis('scaled')
ax.set_aspect('equal')

plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/cab8065f-6f16-3ebb-6229-9ece22b01f8f.png)

地図の中心を円の中心にして円を描画した場合、Googlemapで距離を測定すると同じような値になるが、円が地球の端にくると円の半径と距離が一致しません。

円の中心位置はmap(135.,35.)で変換して正確な位置にありますが、半径は長さを指定しているだけなので、端の方にくると全然違った値になります。
極端になると円が地球よりはみ出します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/ad313f88-06f9-ff6f-b2a2-cd7da787d023.png)
libstdc++.so.6: version `GLIBCXX_3.4.22' not found

## <INS>エラー文

```
...
/path/to/binary: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by /path/to/binary)
...
```

## <INS>最終目的

最終的に

```Bash
$ strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
```

この結果にGLIBCXX_3.4.22が含まれていれば良い。

## <INS>解決方法

```Bash
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test
$ sudo apt update -y
$ sudo apt upgrade -y
```

確認

```Bash
$ strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_DEBUG_MESSAGE_LENGTH
```

OK。
formでpostリクエストを送るが画面遷移しない

#解決方法
formヘルパー内で`local`属性を`true`に指定する
###例
`<%= form_with model: @model, local: true do |f| %>`

#以下詳細
(注意:根本原因にあたる「Ajax通信」についての知識が甘いため、見当違いのことを書いている場合があります。その場合はお手数ですがコメントでご指摘いただけると幸いです。)

##画面遷移しない状況
dbに取得した値を保存する際、「form->確認画面->result」というように確認画面をはさむと「form->確認画面」で画面遷移しなかった

##理由
railsのデフォルト設定ではformヘルパー内で`data-remote="true"`が指定されており、Ajax通信が行われるため。

##解決方法
form内で`local: true`を指定することでAjax通信(remote + unobtrusive XHR送信)が無効になる。

###Ajaxとは
(https://railsguides.jp/working_with_javascript_in_rails.html より引用)
>
Ajaxを理解するには、Webブラウザの基本的な動作について理解しておく必要があります。
>
ブラウザのアドレスバーにhttp://localhost:3000 と入力して'Go'を押すと、ブラウザ (つまりクライアント) はサーバーに対してリクエストを1つ送信します。ブラウザは、サーバーから受け取ったレスポンスを解析し、続いて必要なすべてのアセット (JavaScriptファイル、スタイルシート、画像) をサーバーから取得します。続いてブラウザはページを組み立てます。ブラウザに表示されているリンクをクリックすると、同じプロセスが実行されます。ブラウザはページを取得し、続いてアセットを取得し、それらをすべてまとめてから結果を表示します。これが、いわゆる「リクエスト-レスポンス」のサイクルです。
>
JavaScriptも、上と同様にサーバーにリクエストを送信し、レスポンスを解析することができます。JavaScriptはページ上の情報を更新することもできます。JavaScriptの開発者は、ブラウザとJavaScriptという2つの力を1つに結集させることで、現在のWebページの一部だけを更新することができます。必要なWebページをサーバーからすべて取得する必要はありません。この強力な技法が、Ajaxと呼ばれているものです。
可能な限り直近の日付を持つデータをソートしつつ取得する

意外と難しい
##例表(TIME_TABLE)

TIME_TABLE

| room_id | event_name | start_date | end_date |
|:--|:--|:--|:--|
| 1 | おもちゃ見本市 | 2017/1/10 | 2017/2/1 |
| 1 | A社臨時会議室 | 2017/3/11 | 2017/3/31 |
| 1 | D社株主総会 | 2017/4/20 | 2017/4/21 |
| 2 | おもちゃ見本市 | 2017/1/10 | 2017/2/1 |

dateは１時間単位でしか設定されない想定。

##例えば部屋を汚した利用者を特定する

過去データしか無いとわかってる場合は容易

```plpgsql
SELECT "部屋1を汚したイベント".event_name FROM (
  SELECT *  FROM TIME_TABLE
  WHERE 
    room_id = 1
    AND start_date <= SYSDATE
  ODER BY start_date DESC
) "部屋1を汚したイベント"
WHERE ROWNUM <= 1
```

##例えば部屋が利用不可にされたので前後の利用者を得つつ現刻から未来、今、過去で近い順に並べる
直後の利用者情報が一番ほしいけど現在利用中、過去利用中も後ろに表示させたい的な動作

難しい。オラオラで実装。ベターかはわからない。

```plpgsql
SELECT "部屋1利用するイベント".event_name FROM (
  SELECT  
    SIGN(SYSDATE - start_date) as sign_start_flg,/*過去日なら-1 今なら0 未来日なら+1*/
    SIGN(SYSDATE - start_date) as sign_end_flg,
    ABS(SYSDATE - start_date) as abs_start_dt,
    ABS(SYSDATE - start_date) as abs_end_dt,
    TIME_TABLE.* 
  FROM TIME_TABLE
  WHERE 
    room_id = 1
  ORDER BY sign_start_flg ASC, abs_end_dt ASC /*開始日が未来でかつ終了日が現在日から最も近いイベント*/
) "部屋1利用するイベント"
WHERE ROWNUM <= 10
-- AND sign_end_flg > 0 /*未来、使用中の部屋は拾わない*/

```

ORDER BYにSELECTで指定した4値の与え方でいろいろ使い回せるのが楽というのもある

##秘話
例からは想像できない化物SQLのリファクタリング結果で
もともとは4クエリ発行してたやつをプログラム上で加工してたのが遅すぎて、早くしろと言われた奴がUNIONで悪魔融合。
負荷テスト担当して目標性能の1/3だったのでNGだしたら、じゃあお前がなんとかしろ言われ作った苦肉のSQL。
性能60倍ぐらい改善した。
ParaViewはVTK ASCIIではなくBinaryでないとNaNを読み込めない

# NaNを含むデータをParaViewで表示するには

VTKライブラリを使ってVTK ASCII形式でファイルに出力すると「nan」と表示されます。このファイルをParaViewで開くと

> Unsupported cell attribute type: nan for file:（後略）

というエラーメッセージが表示されます。
どうすればNaNを取り扱えるのかと色々検索をかけてやっと[解答](https://public.kitware.com/pipermail/paraview/2013-October/029467.html)が見つかりましたので、備忘録として残しておきます。

> The reader for the VTK ASCII format does not handle non-finites like NaN. (It has to do with the standard C++ streams not supporting it, but I don't want to go into details.) However, if you write out something in VTK binary format, that should work.

Binary形式にすればちゃんと表示できるだけのことでした。

追記：[vtkMath](https://www.vtk.org/doc/nightly/html/classvtkMath.html)クラスにおいて、正・負の無限大およびNaNを返したり判定する関数

-`Inf()`
- `NegInf()`
- `Nan()`
- `IsInf()`
- `IsNegInf()`
- `IsNan()`
- `IsFinite()`

が提供されています。
GitLab サーバの構築方法 2018

最近の GitLab は Docker で動かせる & Let's Encrypt による証明書自動生成をサポートするようになり、昔と比べるとサーバ構築がかなり簡単になったので、あらためてイマドキの GitLab サーバの構築方法についてまとめる。

Docker で GitLab を動かす方法は公式ドキュメントにも詳しく書かれている。[^docs]

[^docs]: https://docs.gitlab.com/omnibus/docker/

## 環境
今回は以下のような環境を想定する。

- Docker が動く Unix サーバ
- sshd のポートがデフォルトの 22 から変更されている (GitLab がポート 22 を使うので)
- (Let's Encrypt 機能で SSL 証明書を取得する場合)
    - 使用するドメイン (今回は例として `gitlab.example.com`) の A レコードがあらかじめ設定されている
    - ポート 80 がインターネット全体に公開されている (ドメイン認証のため)

## Docker のインストール
何らかの方法で Docker をインストールする。

Ubuntu 18.04 LTS であれば、標準リポジトリの apt でもそれなりに新しいバージョンの Docker が入るので楽。

``` console
$ sudo apt install docker.io
```

## GitLab 用ディレクトリの作成
ホストに `/gitlab` というディレクトリといくつかのサブディレクトリを作り、これらをコンテナにマウントすることにする。

``` console
$ sudo mkdir -p /gitlab/{config,data,logs}
```

## 設定ファイルの記述
あらかじめ設定ファイルを記述して配置しておくことでそれを読み込んでくれる。

別に設定ファイルは無くても起動する。(自動生成される)

``` ruby:/gitlab/config/gitlab.rb
# URL の設定
external_url 'https://gitlab.example.com'

# タイムゾーンの設定
gitlab_rails['time_zone'] = 'Asia/Tokyo'

# SSL 証明書の設定
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['admin@example.com']

# G Suite アカウントでログインできるようにする設定
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['google_oauth2']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_providers'] = [
  {
    "name" => "google_oauth2",
    "app_id" => "YOUR_APP_ID",
    "app_secret" => "YOUR_APP_SECRET",
    "args" => {
      "access_type" => "offline",
      "approval_prompt" => "",
      "hd" => "example.com",  # ドメインを制限する場合
    },
  }
]
```

`external_url` と `letsencrypt['enable'] = true` を設定するだけで、あとは起動時に Let's Encrypt から SSL 証明書を発行してもらって配置するところまで自動でやってくれる。便利。[^letsencrypt]

[^letsencrypt]: https://docs.gitlab.com/omnibus/settings/ssl.html#let-s-encrypt-integration

## コンテナを起動する
GitLab の公式 Docker イメージ[^dockerhub]を使ってコンテナを起動する。

[^dockerhub]: https://hub.docker.com/r/gitlab/gitlab-ce/

``` console
$ docker run --rm -d --name gitlab \
        -p 80:80 -p 443:443 -p 22:22 \
        -v /gitlab/config:/etc/gitlab \
        -v /gitlab/logs:/var/log/gitlab \
        -v /gitlab/data:/var/opt/gitlab \
        -h gitlab.example.com \
        gitlab/gitlab-ce
```

起動時に `reconfigure` が実行されるので少し時間がかかる。

## 動作確認
設定したドメイン (今回の例では `https://gitlab.example.com/`) にアクセスしたら動いているはず。

簡単！
Node.jsでGmailを送信

Nodemailerを使ってGmailを送信してみる。
Gmailを使う場合は二段階認証がOFFで「安全性の低いアプリの許可」を有効にするのが一番簡単だった。

[安全性の低いアプリのアクセス](https://myaccount.google.com/lesssecureapps)

### nodemailerのインストール  
```
npm i -D nodemailer
```

### server.jsの用意
```
//server.js
var nodemailer = require('nodemailer')

// メッセージ
var message = {
  from    : '送信元アドレス',
  to      : '送信先アドレス',
  subject : 'タイトル',
  text    : '本文'
};

var smtpConfig = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true, // SSL
  auth: {
    user : 'hogehoge@gmail.com,
    pass : 'パスワード'
  }
};

var transporter = nodemailer.createTransport(smtpConfig);

transporter.sendMail(message, function(err, response) {
  console.log(err || response);
});

```

### server.jsの実行
```
node server.js
```
IT業界で働いてみた10日目の雑感（タスク管理について）

はじめまして。

わたしはつい最近、知人の紹介もあって、全くの未経験ながらIT業界に飛び込みました。

本投稿では、そんなITに関する知識ゼロな私が、IT系中小企業に入社10日目で、**実際にどのようなことを経験したのか、実感したのか**ということについて綴っていきます。

少しでも同じ境遇にいる人や、これからIT業界に身を置きたいという人の参考になれば幸いです。


#タスク管理の重要性

入社してすぐは、PC周辺環境を整えたり、仕事をする上で役に立つアプリのダウンロード、ITビジネスの全体像の俯瞰などを行いました。

その際、社会人経験ゼロの自分にとっては、改めて目から鱗だったことがあるので共有したいと思います。


##「Trello」

働きはじめてすぐに、チームリーダーから「Trello」というアプリを使ってタスク管理をする癖をつけるように命じられました。

考えてみれば、ビジネスをしている人にとっては当たり前の話かもしれませんが、自分のやるべき**タスクをなるべく細分化して可視化することで、やるべき作業を俯瞰しながら効率的に処理する**ことができます（わたしの場合、メモ書きにTo doリストを書くぐらいでした）。

色々方法はあると思いますが、自分の場合は、「To do」、「Doing」、「Done」の領域を作って、それぞれに作業をアサインしています。

個人的に「To do」だけじゃなく「Doing」と「Done」があるのが重要だと思っています（先ほど紹介した「Trello」なら簡単にアプリ管理できます。メモ書きだと面倒臭くてTo doリストぐらいしか作らないですよね）。

「Doing」で自分が今一体何を行っているのかを常に把握して、そのタスクを完遂させたら「Done」の領域に移動させるわけです。このプロセスと結果を可視化することが、人間の脳の報酬系に少なからず刺激を与えているように感じました（つまり、Doneの領域に、やり終わったタスクが積まれていくことを実際に目にすることで、脳内報酬系がアクティブになるのではないかということ）。

##ドラクエ的タスク

これを落合陽一なんかは「ドラクエ的タスク」と銘打ってるのを耳にしたことがありますが、まさにそれに当てはまると思います。

ドラクエのようなRPGゲームでは、モンスターを倒すことで、経験知を得られレベルアップすることができます。そうすると、さらに強いモンスターを倒せて、新たな洞窟や街へ冒険することができ、最終的にはラスボスを倒してエンディングを迎えることができます。

プレイヤーは「モンスターを倒す＝タスク」と「レベルアップ＝報酬」の行為を繰り返して、ゲーム内のキャラクターを成長させていくわけです。

この粛々とした「タスク処理（Doing）→報酬（Done）」の連鎖行為をリアル世界でも当てはめていくのが、とても意味のある行為なのではないかなと改めて思いました。


##ビジネス以外でも重要

この思考は何もビジネスマンだけに限らず、研究者やアーティスト、小説家などあらゆる職業にとって、意義があることだと実感しました。

わたしの場合は、プライベートでは音楽活動を行っているので、仕事以外の時間は音楽に関する様々なタスクと向き合うことになるわけです。

例えば、曲を一つ完成させる為にも様々なタスクがあります。大まかに仕分けすると、コード進行を考える、曲の構成を考える、歌詞を考える、アレンジを考える、などがあります。

また、上記のタスク（アウトプット）を行う為に必要なインプット（耳コピ、音楽鑑賞など）もタスクとして設定できるし、できた曲は演奏できないといけないのでその練習もタスクになります。

このように、曲を一つ完成させる為のタスクをなるべく細分化して管理ができると、「曲完成」というゴールまでの道のりが短くなるのではないかと思いました。

意外と、漠然と作業を行なっているだけだと、あっさり集中力が途切れてしまいます。タスク管理をこまめにし、自分が今していることの道しるべを持つことで、「タスク処理（Doing）→報酬（Done）」の連鎖が生まれ、モチベーションアップにも繋がるはずです。

#おわりに

いかがだったでしょうか。

IT業界に入社しての雑感が、タスク管理のテーマに終始してしまいましたが、ITの領域で働き始める人にとっても、非常に重要なことだと感じたのでシェアしました。

ビジネスマンとして働く人も、違う領域で何か結果を出さないといけない人も、改めてタスク管理の重要性を実感していただけると幸いです。

参考リンク
［リンク］（https://teruyastar.hatenablog.com/entry/2018/07/06/131509）
IBM CloudでNode-RED利用準備をする

#はじめに

2018年7月。IBM Cloudのカタログの装いが変わったということなので、Node-REDを立ててみることにした。

ログイン後に現れる画面で「カタログ」をクリックし、サービスの一覧であるカタログに移ります。
以前からいくつかカテゴリー名が変更になったものがあります。
Node-REDが入っているカテゴリーは以前は「ボイラープレート」というものでしたが、「Starter Kits」に変更になりました。(下図参照)
ここにある「Node-RED Starter」を使ってNode-RED環境を構築します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/737da881-297f-285e-514f-bfe861962314.png)

*他に特筆すべき点としては「Watson」が「AI」になっていることと「Cloud Foundry」が「Compute」の中に格納されたあたりでしょうか。

#Node-RED環境の構築
Node-RED Starterをクリックします。
「アプリ名」を入力し、プランや環境を確認したら右下の「作成」をクリックします。
この時、アプリ名はIBM Cloud上の既存のアプリと重複しないようにしなくてはいけませんのでご注意ください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/bd5508c7-2446-378a-8452-b39ecea63d25.png)

画面が変わった先で「開始中」というアニメーションが「実行中」に変わったら利用可能です。
「アプリURLにアクセス」をクリックしましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/ec21ab34-e65e-d30c-e7e8-46305e133435.png)


##ユーザー名とパスワードの設定
Node-REDの環境が他者に編集されないようにuser nameとpasswordを設定します。これらの設定はあなたのIBM Cloudのユーザー名やパスワードとは異なるものを設定して構いません。
![スクリーンショット 2017-04-20 18.38.46.png](https://qiita-image-store.s3.amazonaws.com/0/141025/450c313f-bb93-7019-4e24-93b0be8f5981.png)

ユーザー名とパスワードを入力してログインします。
![スクリーンショット 2017-04-20 18.40.33.png](https://qiita-image-store.s3.amazonaws.com/0/141025/e718a544-844e-d01a-d136-1e83de53bb6f.png)

これでNode-REDを用いたノンプログラミングの開発環境を利用することができます。
phpredisのインストール方法

# phpredis

## gitからクローンして展開する  

作業用ディレクトリに移動してから以下作業  

~~~
$ git clone https://github.com/nicolasff/phpredis.git
$ cd phpredis
$ phpize
$ ./configure
$ make
$ make install
~~~

## php.iniにredisの設定を行う

~~~
//php.iniの場所を探す
$ locate php.ini

//php.iniに以下を追記
extension=redis.so
~~~

インストールされたか確認

~~~
$ php -m | grep redis
~~~

## Apacheの再起動で反映

~~~
//ダウンタイムなしで再起動
service httpd graceful

//gracefulは反映されないこともあるので、その場合はrestart
service httpd restart
~~~

---
## 備忘

### phpize
拡張モジュールをビルドする低レベルビルドツール。autoconf等別途ビルドツールが必要。
これを使うと、ソースからの再コンパイルなしで拡張モジュールをビルドできる。

### configure
インストールを行うOS,CPUのバージョンチェックや必要な関連ツールの調査を行い、これらの状況を記述したMakefileを作成。

### make
configureにより生成されたMakefileを基にソースコードをコンパイルする。

### make install
makeで生成されたバイナリファイル等を規定のディレクトリにコピーする。コピー先はconfigureでパラメータを付与することで指定可能。
R初学者のチートシート（超初級編）

## はじめに
R初学者兼通常業務に組み込められてない筆者が
久しぶりに触るたびに検索していることをまとめた。

+ 回帰分析の書き方
+ プロットのきれいな書き方
+ データフレームって？

といったことは記載がないよ！

なので、日常的に触ってる方々には
「んなこと、知ってるよ！！」っていうことばかりで書いてあるのでご容赦を。
また、Rの基本的お作法を抑えたいって方もここには求めていることが無いかもしれない。
なお、筆者はmac・Windows両環境使いだが、mac準拠で記載している。
（随時更新）

## ディレクトリ操作
```ディレクトリの確認.r
getwd() # 現在の向いている作業ディレクトリの確認

setwd("~/hogehoge") # 現在向いている作業ディレクトリの変更

list.files() # 作業ディレクトリになんのファイルがあるか／Linuxコマンドのlsにちかい
```
##### **list.files() 引数の種類**
|引数|内容|
|:-----|:-----|
|recursive = True/False|サブディレクトリを含めてファイルパスを表示|
|pattern = "csv"|指定文字列が含まれるファイル名を表示/この場合だとファイル名に「csv」を含むもの|
|nrows = n|N行目までを読み込むかの指定|
|include.dirs = True/False|ディレクトリを含む|

## CSV読み込み
基本的にCSV（Comma Separated Value）信者なので、
これ以外に遭遇したら変換したくなるぐらい。
でも、遭遇する生データはタブ区切りもあるわけで……
細かい対処法は一旦抜き
※例えばカラム名が日本語だった場合文字化けしないようにするなど

```インポート.r
# 下記は基本型。引数で読み込む形式を指定
data = read.table("hogehoge.csv",sep=",",header = TRUE)

# 区切りがコンマだったらこれでOK/ヘッダーを含む
data = read.csv("hogehoge.csv")

# 区切りがタブだったら……/ヘッダーを含む
data = read.delim("hogehoge.csv")
```

##### **引数の種類**
|引数|内容|
|:-----|:-----|
|sep = ""|区切り文字の指定|
|skip = n|データの頭のからN行目までをスキップ|
|nrows = n|N行目までを読み込むかの指定|
|header = Ture/False|1行目に列名か書かれているか否か|
※細かい事例は抜き

## データフレーム内の特定カラムを指定する

```dataframe.r
# データフレーム内の特定カラムを指定
data$column
```
またデータフレームをいちいち指定するのも面倒。
なので、検索リストにデータフレームを登録することで、
カラム名のみの記載で済む。

```dataframe_abridgement.r
# 対象データフレームの指定
attach(data)

# データフレームの指定解除
detach()

# どんなデータフレームなどが今登録されているのか確認
search()
```
※データフレームを追加し続けることは可能だが、
 増えるとその分処理が遅くなるのでこまめにdetach()を実行すること。
## プロット描画
相関性があるかどうかをみるのに早いのは散布図や折れ線グラフを書くこと。
Rは恐ろしいぐらい高性能にすばやく描画できる関数、それがplot()。
ただし、高機能且つ多機能なので触りだけ。（というか理解していない）

``` plot.r
# 対象のデータフレームをすべてデフォルト設定の点プロットで描画してくれる
plot(date)

# 対象データフレームの特定カラム同士だけを描画したい
plot(data$column1,data$column2)

# 描画形式を制御したい
plot(data$column1, data$column2, type = "l")

```

##### **形式指定**
type = "○"と言った形で制御する。

|引数|内容|
|:-----:|:-----|
|p|点プロット|
|l|線プロット/折れ線グラフ|
|b|点と線のプロット|
|c|上記の点を描画しない|
|h|点と線を重ね書く|

##### **日本語が文字化けする場合**
フォントの指定をすると回避可能。
使用PCにインストールされているフォントを指定するということになるので、
PCにインストールされているフォントならOKらしい。

``` par.r
# グラフのパラメーター指定
par(family = "Osaka") # macOSではこれを推奨（と聞いた）
par(family = "HiraKakuProN-W3") # Windowsではこれを
```

##### **タイトルやラベルの制御**
引数で制御可能
なお、記載がない場合、「data$column1」のままプロットに表示される

|引数|内容|
|:-----|:-----|
|main = "メイン"|メインタイトル|
|sub = "サブ"|サブタイトル|
|xlab="X軸ラベル"|X軸ラベルの記載 / "" とすると非表示|
|ylab="Y軸ラベル"|Y軸ラベルの記載 / "" とすると非表示|

## クロス集計
``` table.r
# 基本型。データフレーム内のすべてのカラムをクロス集計する
table(data)
# 指定カラムのクロス集計
table(data$column1, data$column1)
```

----
## 参考サイト
統計解析フリーソフト R の備忘録頁
http://cse.naro.affrc.go.jp/takezawa/r-tips/r.html

総称ファミリ名分類のフォント名一覧
https://w3g.jp/sample/css/font-family
Google Spread Sheetのセルの更新時刻を表示する

# スクリプトを作る

1. Google Spread Sheet > ツール > スクリプトエディタ
2. エディタに以下のコードを記述します。

```gs
function insertLastUpdated() {
  var sheet =  SpreadsheetApp.getActiveSheet()
  var cell = sheet.getRange(sheet.getLastRow(), 2)
  if (cell.getValue() == "") {
    cell.setValue(Utilities.formatDate(new Date(), 'JST', 'HH時mm分ss秒'))
  }
}
```

<img width="770" alt="スクリーンショット 2018-07-13 12.59.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/7ee0ac16-402f-efd6-78a8-fedae92f03a9.png">



# トリガーを作る

1. スクリプトエディタのメニュー > 編集 > 現在のプロジェクトのトリガー
2. 以下の設定で保存します。

<img width="877" alt="スクリーンショット 2018-07-13 12.56.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/77133428-3d82-e0be-a08d-bdcb0d8c96da.png">

# 動作確認

スプレッドシートのA列の最終行のセルに値を書き込むと、B列に更新日が書き込まれるようになりました。

<img width="403" alt="スクリーンショット 2018-07-13 12.57.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/e690fca6-81ad-33e8-e8ff-32a99988130c.png">
今までプロジェクトの問題（1）

優先度を作る
初めてのタスクだが、その時ReactとReduxの知識は全然ないので、工夫しました。
問題点：
1. selectboxはonclickだが、selectboxの内容を変わることはonchange
2. Reduxとは
state(変数)をしっかり管理するためのライブラリ。特定の場所のみでstateの変更をすることで変なところでstateが変更され煩雑になることを防げる。
・component
reactを用いたUIの部品。memo.jsだったらメモ部分を担っている。ここでreduxのactionを呼び出す。

・action
関数を宣言し、中にreducerに渡す情報を設定してるところ

・reducer
actionから渡ってきた情報を元にstateを変更するところ

・middleware
reducerの処理の前後で処理を行う

・container
必要なstateやactionをcomponentに渡す

・store
stateの状態を記録している。また複数のreducerをまとめたり、middlewareを設定していたりするが、あまり触ることはない

3. propTypes
PropTypesとしてPropについての型などの制約を指定することが出来ます。
CentOS 6.9 上で gsutil コマンドを crontab から動かすまで

コマンドラインからは gsutil コマンドを含むスクリプトを実行できるのだが、そのスクリプトを crontab に登録して実行すると動いているようで実は gsutil がエラーを吐いていて実行されていなかったというオチでした。。。
いろんなサイトを検索しまくって断片的な情報を調べることになったので、まとめておきます。

現時点で、gsutil は python2.7 が必要。

ところが CentOS 6.9 では python 2.6 がインストールされており、しかも yum コマンドが python 2.6 で動いている。python 2.7 で動かすとエラーが出る。

OS確認
`# cat /etc/redhat-release
CentOS release 6.9 (Final)`

現在の バージョン
`# python -V
Python 2.6.6`

まずデフォルトのpythonをリネームして寄せておく
`# mv /usr/bin/python /usr/bin/python2.6.6`


python 2.7 をソースからインストールして差し替える形で配置
`# cd /usr/local/src`
`# curl -O https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tgz`
`# tar zxf Python-2.7.15.tgz`
`# cd Python-2.7.15`
`# ./configure`
`# make && make altinstall`
`# cp /usr/local/src/Python-2.7.15/python /usr/bin/python`

yum コマンドを実行する python を リネームしておいた 2.6.6 を指定
`# vim /usr/bin/yum の1行目`
`---------------------------`
`#!/usr/bin/python`
`↓`
`#!/usr/bin/python2.6.6`
`---------------------------`

動作確認
`# yum list`
⇒動いたので問題なし

ついでに

gsutil が動いたと思ったら sqlite3 が無いというエラーも出ました。。

sqlite を yum でインストールする
`# yum install sqlite-*`

以上で、Google Play Store のレポートデータを cron でゲットしてデータをゴニョることができました。

感想
CentOS はもう 7系を使えってことですかね。。
要素のfadein,fadeoutをjavascriptとcssで実装してみた

# 要素のfadein,fadeoutの実装したのでメモ

## 今回作ったもの
ページをリロードした瞬間に要素をフワ〜とfadeInで表示させ、
5秒後にフワ〜と消すものを実装した。

## コード
HTML

```.html
<div class="wrapper" data-wrapper="">
  <p class="text">これはサンプルです。</p>
</div>
```
CSS(sass)

```.css
@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

.wrapper {
  border: 1px solid #333;
  animation: fadeIn 2s;
  animation-fill-mode: both;
  
  &--fadeOut {
    animation: fadeOut 1.2s;
    animation-fill-mode: both;
  }
}

.text {
  margin: 0;
  padding: 12px;
}
```

javascript

```.js
const wrapper = document.querySelector('[data-wrapper]');

let i = 0;

const interval = setInterval(() => { // タイマー処理(第二引数に入ってる値ごとに処理を繰り返す)
  if (i < 5) {
  	i += 1;
  } else {
    wrapper.classList.add('wrapper--fadeOut');
  	clearInterval(interval); // タイマー処理(intervalを止める)
  }
}, 1000);
```
Clipkitの記事に公開日時をもとにNEWを付ける方法

公開日時が3日以内の記事の例

現在時刻から3日前の時刻を変数に保存しておく：

```
{% assign time_3days_ago = 'now' | date: '%s' | minus:259200 | plus:0 %}
```

比較して記事の公開日時（article.published_at）の方が大きければNEWを付ける：

```
{% assign time_published = article.published_at | date: '%s' | plus:0 %}
{% if time_published > time_3days_ago %}
<span>NEW</span>
{% endif %}
```

1日：86400
3日：259200
7日：604800

更新日時と比較したい場合は、published_atをupdated_atにしてください。
自宅VPN

# 自宅VPN

公衆無線LANってセキュリティ的にアレだからVPNするといいよという話は聞いていたけど、面倒だし難しそうだしで放置していたところ、とても簡単らしいpritunlというのに出会ったので設定しました。

自宅にDockerホストがある人なら１時間かからず設定できるので早くやらないとセキュリティがアレなのでどうぞ。


# 参考URL
このあたりを参考にやりました。

https://www.google.co.jp/search?q=pritunl+docker
https://qiita.com/loasnir/items/dd59cc82b1558b500cd0
https://github.com/jippi/docker-pritunl
https://qiita.com/cha2maru/items/e6efb976cc1cb6eb7f7a
https://qiita.com/to_obara/items/0622bdc5cacaa2758057
https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9#host


# 起動スクリプト
```vpn/start.sh
#!/bin/bash

datadir="$(dirname $(readlink -f "$0"))/data"
echo "datadir=$datadir"

mkdir -p $datadir/{mongodb,pritunl}
touch $datadir/pritunl.conf

docker run \
    --name=pritunl \
    --detach \
    --cap-add NET_ADMIN \
    --network=bridge \
    --restart=always \
    -v $datadir/mongodb:/var/lib/mongodb \
    -v $datadir/pritunl:/var/lib/pritunl \
    -v $datadir/pritunl.conf:/etc/pritunl.conf \
    -p 1194:1194/udp \
    -p 59443:443/tcp \
    jippi/pritunl
```

ポート番号は適当にかえてOK


# 設定手順メモ

- ブラウザで管理画面を開く https://dockerhost:59443/
- 管理者アカウント、パスワードの設定をする
- Organizationを作る
- Userを作る
- Serverを作る (ここでUDPポート番号設定)
- OrganizationとServerを紐付ける
- ダイナミックDNSで自宅アドレスを取れるように設定
- ルータにUDPの静的NAT設定(管理画面は外から使わないのでUDPだけ)
- https://client.pritunl.com/ からmac用のクライアントインストール
- Userリストから.ovpnファイル(tarだった)をダウンロードしてクライアントに設定
- 外部アドレスからテスト(テザリングでやった)
- iPhoneは https://itunes.apple.com/jp/app/openvpn-connect/id590379981?mt=8 これでできた。
- iTunesからovpnをiPhoneにいれて設定する
ズンドコキヨシ  for Excel VBA

今更にも程がある、とは思ったが、せっかくなので書き残しておこう。
####[できるだけ手短に]
```vb
Sub zd()
    Dim z, d
    z = 1
    Cells.Clear
    Do
        d = Round(Rnd())
        Cells(Len(z), 1) = IIf(d, "dk", "zn")
        z = z & d
    Loop Until Right(z, 5) = 1
    Cells(Len(z), 1) = "k.y.s!"
End Sub
```


####[別解]
記事を書いたあとで別の方法を思いついたので試してみた。
ついでに、せっかくExcelに出すのだからと、表示の仕方に小細工を。

![cap2.gif](https://qiita-image-store.s3.amazonaws.com/0/164214/38a6a604-bcc8-dcb0-5645-5e62a967ac0d.gif)

```vb
Sub zdk()
    Dim z, d, k As Range
    Cells.Clear
    For Each k In Cells.Resize(1)
        k.Activate
        wait 1
        d = Round(Rnd())
        k = IIf(d, "ズン", "ドコ")
        z = d * (z + 1) - (d - 1) * (z = 4)
        k.Resize(, 4).Font.Size = k.Font.Size + d * 2
        If z < 0 Then Exit For
        If z > 4 Or d = 0 Then Cells.ClearFormats
        Cells.Rows.AutoFit
    Next
    For z = 1 To 3
        wait 0.2
        With k.Offset(, z)
            .Value = Mid("キ・ヨ・シ！", 2 * z - 1, 2)
            .Activate
        End With
    Next
End Sub

Function wait(s)
    wait = Timer: Do: DoEvents: Loop Until Timer > wait + s
End Function
```