OmniAICreator/Qiita-1.07M huggingface dataset:
LabVIEW Tips: LabVIEW for Linux でヘルプを表示させる

# LabVIEW Tips: LabVIEW for Linux でヘルプを表示させる

LabVIEW for Linuxインストール後にヘルプ画面等から、関数(VI)のヘルプをみようとすると、「htmlview はどこ?」といった感じでファイルダイアログが開くだけで、ヘルプ表示されません。
htmlview というブラウザが存在していないのが原因なので、解決するには、Firefox や Chrome など、インストールされているWebブラウザへhtmlviewという名前でシンボリックリンク作成することで、htmlview の代わりに他のブラウザが呼び出させるようにします。

例) /usr/bin/にfirefoxがある場合

`# sudo ln -s /usr/bin/firefox /usr/bin/htmlview`

*firefox以外のブラウザをお使いの方は/usr/bin/firefoxの部分を修正してください。*

これで、ヘルプのへのリンクをクリックすると、Webブラウザが起動して
HTML形式のヘルプが表示されるようになります。


LabVIEW 2019 (for Linux)では、上記のような手間をかけなくても、ヘルプ表示されるようになっています。
pug+sassをparcelを使って爆速で始める


## はじめに
それなりにモダンなWeb開発をするならpugとsassは必須かなぁと思っていたのですが、環境を整えるのがすごくめんどくさそうなんで触らずにいました。
しかし、parcelを使えば簡単なんじゃね？って思い環境を整えたら**ものすごく簡単**で**爆速**で環境構築できたので書き残しておこうと思います。

ちなみに、parcel自体は昨年末に[この記事](https://qiita.com/bitrinjani/items/b08876e0a2618745f54a)を見て少し触った程度です。

## 手順
1. parcelをグローバルでインストールする

    ```bash
    npm i -g parcel-bundler
    ```
1. プロジェクトフォルダーを作り、以下のようなファイル構成にする

    ```
    project
    ├── index.pug
    └── style.sass
    ```

1. index.pugとstyle.sassを編集する

    ```pug:index.pug
    <!DOCTYPE html>
    html(lang="en")
        head
            meta(charset="UTF-8")
            meta(name="viewport", content="width=device-width, initial-scale=1.0")
            meta(http-equiv="X-UA-Compatible", content="ie=edge")
            link(rel="stylesheet", href="style.sass")
            title Document
        body
            div hello!
    ```

    ```sass:style.sass
    body
        font-family: sans-serif

    ```

    vscodeならpug上でもemmetが効くので`!`を入力しtabを押せば簡単に入力できます。

1. 以下のコマンドを実行

    ```bash
    parcel index.pug
    ```

以上でインストールから開発用サーバーの立ち上げまで全てやってくれます！！😊

ビルドする際は以下のコマンドを実行します。

```bash
parcel build
```

## 終わりに
はっきり言って想像を上回る簡単さで驚きました。
簡単な静的Webページならparcelでサクッと構築するのがいいかもしれません。

どうやら、以下の記事によるとVueも爆速で構築できるみたいなんで使ってみたいですね🤔

- [Parcelでvue.jsを使うときに、いつのまにかプラグインが不要になっていた件 - Qiita](https://qiita.com/kobaatsu/items/ed0dc0aaa739fd454a2b)
lazuritaでSerial

#概要
lazuritaでSerialやってみた。

#仕様
Serial1とSerial2とSerial3は、どれか一つ。

|     |Rx|Tx|
|:--|:--|:--|
|Serial|D0|D1|
|Serial1|D11|D12|
|Serial2|A0|A1|
|Serial3|A4|A5|

#嵌りポイント
printが、めちゃめちゃ。

##文字列の場合
Serial.print("ABC");

##一文字の場合
Serial.write_byte('a');

##数値の場合
Serial.print_long(12345, DEC);


以上。
UIImageを縮小率に応じてリサイズする

# overview

（小ネタです）

UIImageViewではなくUIImageの段階でリサイズしたい状況、まれにあったりする。
そのような時は、以下のようなExtensionで対応できる。

# detail

```swift:UIImage+Resize.swift
import UIKit

protocol ImageResizing {
    func resize(with ratioType: UIImage.ResizeRatioType) -> UIImage!
}

extension UIImage: ImageResizing {
    enum ResizeRatioType {
        case naviIconSize
        case tabIconSize
        
        var ratio: CGFloat {
            switch self {
            case .naviIconSize:
                return 0.9
            case .tabIconSize:
                return 0.75
            }
        }
    }
    
    func resize(with ratioType: UIImage.ResizeRatioType) -> UIImage! {
        return resize(
            with: CGSize(
                width: size.width * ratioType.ratio,
                height: size.height * ratioType.ratio
            )
        )
    }
    
    // MARK: - private
    private func resize(with newSize: CGSize) -> UIImage! {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}
```

### 注意点

> scale
> The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
> 
> [UIGraphicsBeginImageContextWithOptions(_:_:_:) - Apple Developer](https://developer.apple.com/documentation/uikit/1623912-uigraphicsbeginimagecontextwitho)

上記の通りで、Asset Catalogなどを利用しているのであれば `UIGraphicsBeginImageContextWithOptions` の第三引数 `scale` に0.0を渡しておく。
（これにより常に使用デバイスのメインスクリーンスケールが適用される）

# usage

通常：

```swift:
let image = UIImage(named: "star")?.resize(with: .naviIconSize)
```

Asset catalogから直に呼ぶ場合：

<img width="445" alt="スクリーンショット 2018-07-28 6.30.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/50584/b3684f1f-6a1b-50f3-99a9-e1d251c7e0cb.png">


[SwiftGen](https://github.com/SwiftGen/SwiftGen)の場合：

```swift:
let image = Asset.MaterialIcon.icClose36pt.image.resize(with: .naviIconSize)
```

# おまけ

## 使い道は？

- [こういったもの](https://github.com/google/material-design-icons)を元データには手を入れずにリサイズしたいときとか
- `UIBarButtonItem` など直接UIImageViewをいじりづらいときとかに、シュッと使うと吉
可読性よく正規表現で文字列取得【Python】

# コピペ用のpythonコード

コンパイルなし

```py
import re

target  = "https://qiita.com/lilacs/items/01f22081e3cb1650d01e"
expression = r"qiita.com/([^/]+)/items/([^/]+)"
m = re.search(expression, target)
username = m.group(1)       #lilacs
```

コンパイルあり

```py
import re

target  = "https://qiita.com/lilacs/items/01f22081e3cb1650d01e"
expression = r"qiita.com/([^/]+)/items/([^/]+)"
prog = re.compile(expression)
#　以下をループ内などで繰り返し使用
username = prog.search(target).group(1)     #lilacs
```


# はじめに

pythonの正規表現でグループ化・キャプチャのサンプルコードがあまり見つからなかったのでまとめました。

<!--
文字列取得はsplit()を使用したやり方でも記述できます。

**読みにくいコード**
　※　例がよくない。ありがたみのわかる例は？

```py
target  = "https://qiita.com/lilacs/items/01f22081e3cb1650d01e"
strArray = target.split('/')
username = strArray[2]    #lilacs
```

でも、目的の文字列が配列の何番目に来るかは場合によって変わるかもしれないし、もっと複雑な条件になるとsplit()関数だけでは対応できなくなってしまいます。
そこで正規表現を使うと、柔軟に可読性よく文字列取得ができます。
-->

# 文字列取得の正規表現のコツ
## 文字列取得のマッチングは文字（クラス）の否定が便利
　正規表現では「 ,=/」などで区切られた文字を取得することが多いです。マッチング対象の区切り文字の文字クラスを作って否定をとることで、取得したい文字にマッチングすると便利です。
　たとえば、URLなら「/」区切りなので「[^/]+」でマッチングするなど。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186338/630d2db1-92d0-e680-2b23-a475ba18e87a.png)

### 日本語文字のマッチングについて
日本語文字は定義済みの文字クラスがなく、環境依存があるためマッチングしにくいです。

- 対策１：文字クラスの否定を使う
 - [^\s]とか
- 対策２：黒魔術を使う
 - 「あいうえお１２３４５漢字」に対して、[^\x01-\x7E]
 - 参考： http://hodade.com/seiki/page.php?s_zenkaku

## 「グループ化・キャプチャ」が一度に複数文字列を取得できるため可読性が高い

正規表現の一部を()で囲むことでマッチングした文字列のグループ化・キャプチャをすることができ、以下のようにして マッチングした箇所を後から取得することができます。split()などで文字列分割を繰り返すよりは、 一度に複数の箇所をマッチングできるので可読性が高く保てると思います。

```py
expression = r"qiita.com/([^/]+)/items/([^/]+)"
re.search(expression, target).group(1)
```

# 例：Qiita記事URLからユーザ名・記事ID取得
以下の Qiita記事URLから ユーザ名・ 記事IDを取得してみます。

```
https://qiita.com/lilacs/items/01f22081e3cb1650d01e
```

Qiita記事URLの構造について以下のことがわかります。

- 取得したい文字の位置
 - https://qiita.com/（ユーザ名）/items/（記事ID）
- 区切り文字は「/（スラッシュ）」
 - つまりユーザ名と記事 ID には 「/」は含まれない <br> 
    →　「/」の否定でマッチングさせる

そこで以下のような正規表現を考えました

```
qiita.com/([^/]+)/items/([^/]+)
```

()でユーザ名と記事 IDを グループ化・キャプチャし、マッチング後に取得できるようにしました。 正規表現に URLほぼ全体とすべてのマッチング対象が含まれているので、（splitなどで文字列取得を繰り返すよりは）可読性が保たれていると思います。
Python コード全文は以下のようになります。

```py
import re

target  = "https://qiita.com/lilacs/items/01f22081e3cb1650d01e"
expression = r"qiita.com/([^/]+)/items/([^/]+)"
m = re.search(expression, target)
username = m.group(1)       #lilacs
articleId = m.group(2)      #01f22081e3cb1650d01e
```

# まとめ

- 正規表現による文字列取得では文字クラスの否定が便利
- ()で囲む「グループ化・キャプチャ」が一度に複数文字列を取得できるため可読性が高い

# 参考

正規表現の文字列集合（Google スライドへのリンク）
https://docs.google.com/presentation/d/1ZODbtitp2mt4_2VZz2TBKbi8j-pBXDU61AIu3SBKrXI/edit?usp=sharing

正規表現の基本
https://qiita.com/sea_ship/items/7c8811b5cf37d700adc4

グループ化とキャプチャ
https://qiita.com/ik_miyabi/items/12d1127056cdf4f0eea5
Push7でホームページの更新通知を拾ってもらう

# やったこと

ホームページに「購読する」というボタンを付けて、一般ユーザがホームページの更新通知を拾えるようにした。

RSSで拾ってよ、とか言ってはいけない。

自分にはSlackがお知らせしてくれる。（RSSを使ってる）


# [Push7](https://push7.jp)とは

- Webプッシュ通知を無料で設定できるアプリケーション
- PC/Android/iOSに対応
- ブラウザは非対応のもの有り（Google Chrome/Firefox対応済み、Safari未対応）
- 有料プランもあり、マーケティングに色々使えそう
- 英語が苦手な人は、ホームページに飛んだら、一番下までスクロールして「日本語」を押そう


# ホームページ（WordPress）に[Push7](https://push7.jp)を導入する

導入の手順は、下記参考サイトに従うのが良い。
ここでは手順は説明しない。

更新の対象を選択することができるので、通知を飛ばしたいカテゴリを選択する。
カテゴリ以外も設定できるのだが、今回はやらない。

![Push7の管理画面](https://lh3.googleusercontent.com/1Q2-w-spDgrIvNT7STAjnZlDOr-47Z3El9VuEYuKIViXV-3ZgjUGCkm8V4w3K0TwTZqaLa3YcKusgE3svg1dr7NSHAf2UJBdyETaRJQHinCcxASXPia6rlluRl31o8fV7MM1kIudLPYdr_x_FohPxgqtg9fqEzcVm95dxhz5V57jEDLsAFVeao4RiFqilQgUoyIEVaFA0yaum2h5CoIudQhe8pXpI1FHBg8NEPf8zLjclvD_zeHQToYYstsvbHK9OSbwUnlhBxZDg9F2kXHmPs6jywNE40zggIuGSgC72pRTu3RnccIICLj2TZxbyDFdFg0gnC7FPo6I5N8OetJyBtvTt97vu_iKzRXWXCnCljyc9SHQTgLMbe7kHAi0LwIO7GnKAAZE9xs4N29fcx8XZMuOsnEfSqkAraEV964Muh5gV79DpeUJnst4uwQ9G82wGyJlgUxZ5BvU1dtUBRcYs5xn6FNdBNk9QIQK4zLpGZpumnF9kGjKIz8skbduAAmr4WJuLdZweRpwYE1DGa8bxNvXcg0WMN641vBa-oS3cuW64VJwUaVrS4MxSmb4Bz55E-NwNj_of9AGVkTpFMiK7KiBlFIW6oXBNBeYjTY=w1115-h736-no "Push7の管理画面")
![カテゴリの選択](https://lh3.googleusercontent.com/ZPd7sJR-or0s8KyFdH6FElbrOD8fRc8qoBJ4qhaCcAJd0FiikPXg55iON3wiqfOL7-z6c9ZKruMQ5f9VoHNa26z9BvzUo46T-ytI7POok202LaFcxDNreuGXVV3WzLaaetlvuNrXVUxxezr_Y1ES1MPznl-nZH8nlunFozm91n2u5Z_GINYwhUiWpmVLj-Y0bt4cklTMH8KEHOEe3E8hSplc7a5EE4bnph-ESMJaK-tnIVsWXCOEc-Ds7kXVI8FBH0G4lgq4yFKfnQJ38aYssSSf1sAYrdmiNKA1BSuaVXyyRxp2LLe2-4GyiChv28IWpRbf3iSjmwlO0pFVLwxzh_1ttK-5MeWtqLlABv46hBr6Dae1ls51sVYMvODagJtxaB-pikHt4WXq6Dm3RVEOnzljqP7Fol-tTPg9DNbrDcwpByDbwqTaPlx-i6LSEU7XFMiuibaEkFWfDlz1Uf8w8zD4NTlUcOmHDOGotLNpA--xJvAoLvYUuvN1vABdy3REh6f-wY9ywXzhIsESN5sH5R00n7KQrJme_JnNOlyeV7px6eFkd6rCGfmXXPqOEBd-nAzusX-t0Xci8n2qmSsdy8uGzdu7LN9jTwHbGkI=w1115-h736-no "カテゴリの選択")

ヴィジェットのカスタムHTMLで「更新通知」を作成し、Push7のダッシュボードに出て来るボタンのタグを貼り付ければOK。

![ヴィジェットにボタンを作成](https://lh3.googleusercontent.com/CSi7_eVqVhS7O8bWfRa28xxkNCRODeS675QztbaY9xFLKtMsWE_nq5dWiHoCHztvPvCdD7VEkk8wPtlm9mYJJ4xXHBPd_92hR-D651cs0eHHW8PBvhIggoeVhVfqp8oNirOQ-CIemWkBRGwf5EGXieze_iZf-TZmYPOP2uNqELN8D9-BtF6OnIBHXMROt5H2xdx3Z52sY6LRVh18zfTCerTcpdegYwRji98vhXS5g_lUrtAOeNH0HdyZ2Ae_as2Vr128Abx3s249KH2ARY0j3pBz8jyW9RoALIOw3oNzFO7xd1opDKGDhMfR31XaqaY_-ar7RyViQkG73O_FU6q5h2BwGwtJKrUo1mggQQNBlUrfYERGWywpraZ-qqX6mzmxhpF3L2RzKZ4D1nDaM4xVBdhVRAmPhmRHi3LytYmVRFTYIqzhZddaECKLaZESGfqNMgUaNBqjRYzi9eT2Vjj5xlTIkqISqTpzauBqobU0aaOJcxUP7NKo-z94aHwosdsMWQoz8hja74KYvZP7qFHXPC-_ki2YbTZ77BozrMDLqDim8IBaIVQqc7gMcyMvsfSCZ7652xBdqa59nriA0hw2YT1NghPD3yvTPRIodEg=w1115-h736-no "ヴィジェットにボタンを作成")

Push7に新規登録してから、WordPressに組み込むまで、事前知識なしで20分くらい。
スクショなど撮っていたので、こんなもんかな？

思っていたよりも簡単に導入できた。
WordPressでサイトを作成していて、更新通知を投げたい（サイト購読者数を増やしたい）と思っている人は、一度試してみると良いかも。


# 参考

- [Push7を導入したので使い方を解説！wordpressから自動で通知を送りましょう。](https://webledge-blog.com/push7/)
Google Maps の「マイマップ 」で、テニスコート周りの情報を整理する

# やったこと

GoogleMapsのマイマップ機能を利用して、テニスコート周りの情報を整理してみた。

と言っても何も無いので、数少ないランチスポットと、コンビニくらい。

随時更新予定。（練習の合間に行けたらね・・・）

![テニスコート周りいろいろ](https://lh3.googleusercontent.com/qvS0s8EsC42Bq5-uKJQmpqDhTN9oF18G4raoKklP50b20Xz-rXi0kn1oqhLxAIZ5MD0TCsVLuyckejOyMS__tKAJEnHP1eyUPrRg57YhbUkTloIMIhuzFbfnbpRI2H-j7kepm8fNzsLree_6wEcnwYB97QZezATdvCd9VksiJf56Mlx_iToMp8dQwA3SVBDYsgJ1GBqXc1k-a73-8BbWJJ-b82MQQZhzuhiTvbWZa8b9HsNlPEeA7dKuMIS-8HM-LzJhgpERHAmB-I21L4Ru4ebvqYeoN3grxNDQzWeTDIxXF67Ck-JSNgcRGFeO_46kYM7WtI-O0ls4EjmhjQ_2K3V0UVeyFqApJ-4Mv4DihYrMDWvI6SRai0tYpkcaQBRsezdx9tBJEcQHcn3ZYgVn-b-o3IJ5dPIPtYUpOPHffjfT1dkUAFUJGwEwU6HmaNzW2au4v7QZvxy2qTUoU0TDRbLQeg1aDTUzbIwxINLM5KY1dXF72yHNfNqH-oagEWfcnnbd886Q0Cr1F983aPJ0JzRBediO_X67GeR-By3d6UkaKC8iD5fe5zIw2onJOCy_rkEJEFc-GLyw7HXAqCFdZAAcaybN6zDUu0y7dOwBHM4Gsqi30dOGPgScrNZAWW7Nwe6ozgq_NCHxG9XK4HQuWf0TPiYhPWVZ=w1264-h735-no "テニスコート周りいろいろ")

- [テニスコート周りいろいろ](https://drive.google.com/open?id=14GXvYexWHC5s-tLBt64WEHnl_O2jkP-w&usp=sharing)

- [管理しているホームページの固定ページ](http://icitysoft.wpblog.jp/access)の一番下に埋め込んだ

# 詰まったところ

Wordpressの固定ページにマップを埋め込むところ。

結果的に書き方は問題なかったのだが、プレビュー画面で地図が表示されず。

公開設定がおかしい？iframeの使い方が間違っている？とか色々考えたけど、他の人の公開済みのマップもプレビュー画面で表示されなかったので、「一旦公開してしまえ！」と思い公開に踏み切った。

そうしたらちゃんと表示されたので、「プレビューが悪い」という結論に達した。


# 参考

- [10分で作れる社員用ランチマップを紹介したい](https://qiita.com/kyogom/items/720a8c5023900b8e9b1f)


# その他

Qiitaに初めて投稿してみた。

画像をもっと用意しておけばよかったと反省。

あと、早くテニスコートがGoogleMapsに表示されると良い。（まだ何も無いことになっている）
【2018年7月】omniauth-facebookを使ってfacebook認証実装でハマったのでまとめておく

# ハマったことまとめ

## httpsのURLを設定する必要がある
facebook for developersの画面で
「有効なOAuthリダイレクトURI」を設定する際に
`http://localhost:3000/...` を設定するとHTTPSのURLを入力するように求められる。
開発環境でfacebook認証できないのか...？ と思った矢先に

### 解決方法
ngrokを使う。執筆者に感謝。
https://qiita.com/kent_ear/items/6fcc477392aaede175f4

## faceook認証URLリクエスト時に191エラーになってしまう

omniauth-facebook gemのバージョンを上げましょう
```
gem 'omniauth-facebook', '~> 4.0.0'
```

これでやたらはまった。バージョンが1.4.0だった。


# facebook認証実装時に参考にした記事
https://qiita.com/RYOSUKE310/items/2f9ec73aaecd4d80f997

これで実装できるはずです。
hover時のみスクロールバーが表示されるfixedサイドバー

# （ほぼ）HTML+CSSのみ
hover時のみスクロールバーが表示される、fixedサイドバーをHTML+CSSで作りました。

<p data-height="265" data-theme-id="0" data-slug-hash="NBaoPN" data-default-tab="html,result" data-user="mormormmmr" data-pen-title="fixed sidemenu" class="codepen">See the Pen <a href="https://codepen.io/mormormmmr/pen/NBaoPN/">fixed sidemenu</a> by mm (<a href="https://codepen.io/mormormmmr">@mormormmmr</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>


# js使ってるじゃん
footerに到達した時にスクロールがついている要素の高さを変える必要があったため、その部分だけjsを使用しています。
（親要素にpadding-bottomをつける、でもいいんですが…）

footerがなければ、jsは無視して大丈夫です。

# なんで作ったの
少し前に相談されて、その時はjs使わなきゃ無理かなと思ってたのですが、最近ふと:hoverで出来るじゃん、と気づきまして…。
むしろ何で相談された時に気づかなかったんだろう…。

scrollbarの出現時にtransitionはかかりませんが、背景色等が全て不透明なのであれば、

- sidebar__inner::beforeでスクロールバーの上にベースと同じ色を乗せておいてtransitionを設定
- sidebar__inner:hover::beforeで背景色なり不透明度なりを弄る

という手もあるかと思います。
SREとは何か

# 概要
近年、ソフトウェアエンジニアのポジション(職種)としてSREというものが増えている。本記事ではSREがどのような概念で、どういった仕事内容になるかを検証してみる。

# SREとは
SREはSite Reliability Engineeringの略語である。日本語に直訳すると、サイト信頼性工学になる。米Google社が2003年に作った概念で、スケールする巨大なITシステム(サイト)を運用していくための考え方である。

# SREのミッション
会社によって異なるが、基本的には「ITシステム(サイト)の信頼性を担保するための性能、可用性、拡張性、セキュリティなどを向上させる」ということがミッションになる。

# SREの仕事内容
会社によって異なるが、下記が挙げられる。
- インフラ(サーバー、ネットワーク)設計・構築
- 監視・アラート設計
- 障害対応
- スケールアウト(アップ)対応
- セキュリティ対策用緊急パッチ適用
- 運用の自動化
- その他自動化(開発環境、プロビジョニング、etc)
- SLI/SLOの管理
- ポストモーテムの運用
など

# まとめ
簡単にまとめるとSREの仕事内容は、伝統的なインフラエンジニア(サーバーおよびネットワーク)が担当していた役割を踏襲しつつ、運用・保守担当が手作業で行ってきた領域を自動化し、アプリケーションエンジニアが担当してきた領域も一部担当する、という感じになると思われる。

# 参考資料
https://github.com/devopsenterprise/2018-London/blob/master/Tuesday/Breakout%20Sessions/Throne%2C%20Stephen%2C%20Getting%20Started%20with%20Site%20Reliability%20Engineering.pdf
http://landing.google.com/sre/book/index.html
https://ja.wikipedia.org/wiki/%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0
https://tech.nikkeibp.co.jp/it/atcl/column/14/346926/030600869/
https://furien.jp/columns/327/
https://tech.nikkeibp.co.jp/it/atcl/column/14/346926/030600869/
https://tech.mercari.com/entry/2015/11/18/153421
https://tech.s-cubism.jp/blog/archives/3891
npmやらpackage.jsonやら

# はじめに
最近Reactを勉強していてnpmやらpackage.jsonがよく登場するので自分なりのメモとしてまとめます。

# npm
***Node Package Manager***の略で、その名の通りNodeのパッケージ管理ツール。

## npmの使い方

```
パッケージのインストール
$ npm install パッケージ名

パッケージのアンインストール
$ npm uninstall パッケージ名

インストール済みのパッケージを表示
$ npm list
```

## インストール時のオプション

```
--saveオプションをつけるとpackage.jsonのDependenciesに追記される
$ npm install --save パッケージ名

-save-devオプションをつけるとpackage.jsonのdevDependenciesに追記される
$ npm install --save-dev パッケージ名
```



# package.json


```
package.jsonの作成
$ npm init

package.jsonのDependenciesに記述されているパッケージをインストールしてくれる。
インストールされたパッケージはnode_modulesに入っている。
$ npm install
```

package.jsonをgitに公開しておいて、クローンした人がローカルで`npm install`して環境構築するのが一般的らしいです。

# おわりに
package.jsonはRailsのgemfileに似ていますね。
CentOS7でIPv6を完全に無効化する方法。

#よく忘れるのでメモ
<b>1.設定ファイル作成

```
# vi /etc/sysctl.d/disable_ipv6.conf
```

<b>2.以下の内容を記載します。

```/etc/sysctl.d/disable_ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
```

<b>3.以下のコマンドで設定を反映させます。

```
# sysctl -p/etc/sysctl.d/disable_ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
```

<b>4.無効化の確認

```
# ip addr
```
<b>5.OKならOSを再起動してみて確認。

```
# reboot
```

以上
Swift ライブラリKeychainAccessの利用例

### ライブラリKeychainAccess利用
https://github.com/kishikawakatsumi/KeychainAccess/
アプリを削除した後にもデータを残して、再インストールした後に使いたい、iCloud Keychain で値を保存しておきたい場合など

### 導入
インスタンス生成の際にキーが必要なのでBundleIdentifierをキーとしています。
もちろん任意の文字列が使えます。

```swift
import KeychainAccess

var keychain: Keychain {
    guard let identifier = Bundle.main.object(forInfoDictionaryKey: "CFBundleIdentifier") as? String else { return Keychain(service: "") }
    return Keychain(service: identifier)
}
```

### 保存
キーを指定して値を保存

```swift
do {
    try? keychain.set(value, key: "key")
} catch {
    // エラー処理
}
```

### 参照
キーを指定して値を参照
Stringの例
エラーが発生することもあるのでオプショナル型にしておくのが無難っぽい

```swift
var stringValue: String? {
    do {
        return try keychain.get("key")
    } catch {
        return nil
    }
}
```
ラズパイでwebカメラ画像撮影 fswebcam

RaspberryPiで画像撮影。
カメラモジュールより安いwebカメラ投げ売りされてたので撮影テストしてみました。
カメラモジュールより安いし丈夫、線長いので便利な場合あると思います。

**使用機器**
---

* RaspberryPi 3B+
* Webカメラ(BUFFALO BSWHD06M)

ビックカメラで積んであった安かったカメラ使って撮影します。
これでデバイス確認

```
$ lsusb
```

インストール

```
$ sudo apt-get install fswebcam
```

オプション付けて撮影。

```
fswebcam -r 680x480 -F 100 ./pic.jpg
```
1枚撮るだけならこれでOK

![pic.jpg](https://qiita-image-store.s3.amazonaws.com/0/260345/2adf7b5a-7502-d0b2-f6a1-279496b1e42d.jpeg)
ナス。

**cron で一定間隔で撮影**
---
一枚だけ撮っても意味ないので一定周期で撮影。

参考URLでいけました。
[webカメラ撮影](http://mugimugi.hatenablog.com/entry/2015/06/29/Web%E3%82%AB%E3%83%A1%E3%83%A9%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%90%E3%83%AB%E6%92%AE%E5%BD%B1)

```
crontab -e
```

```
*/1 * * * * /var/www/captureImage/captureImage.sh
```
これが1分おき。
[crontab書き方](https://www.server-memo.net/tips/crontab.html)のように時間指定して調整可能。

ついでに当然ですがコメントアウトすれば止まります。

**OpenCVで撮影する**
---

一応アップデートしてインストール

```
apt-get update
apt-get install python-opencv
```

```capture1.py
import sys
import cv2

cc = cv2.VideoCapture(0)
rr, img = cc.read()
cv2.imwrite('pic.jpg', img)

```

これだと1枚だけなので60秒おきにとれるように改良
日付をファイル名にしています。

```capture2.py
import sys
import cv2
import time
import datetime

while True:
    
    now = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")

    cc = cv2.VideoCapture(0)

    rr, img = cc.read()
    cv2.imwrite( now + '.jpg',img)
    cc.release()
    time.sleep(60)
```

※.release()しないと2回に1回ファイルがおかしくなるエラー発生。


まあ、とりあえずこれで普通に撮影することができましたので植物撮ってみたり、部屋の中撮ってみたりしてみましょう。

Opencv使っているので画像を使って他にも面白い画像処理、システム作れると思います。
カバレッジレポートを GitLab Pages にホスティングした

# はじめに

## やりたかったこと

コードカバレッジレポートを簡単に見れるようにしたい。

カバレッジのバッジから
![スクリーンショット 2018-07-28 0.20.44.png](https://qiita-image-store.s3.amazonaws.com/0/222294/31edbb1a-5c0d-bb0b-6c18-684b69d1128c.png)

こんなレポートページへ

![スクリーンショット 2018-07-28 0.23.42.png](https://qiita-image-store.s3.amazonaws.com/0/222294/a70f9b1a-6d34-2b28-891f-c4733cce79a2.png)

## やったこと

* [SimpleCov](https://github.com/colszowka/simplecov) を使って Rspec のカバレッジを計測 & レポートを作成
* GitLab CI を使って上記のカバレッジレポートを GitLab Pages に、ホスティング
  * バッジからのリンクを張る

# SimpleCov を導入する

まずはカバレッジレポートを生成するために [SimpleCov](https://github.com/colszowka/simplecov) を導入する。

1. SimpleCov を Gemfile に追記

	```ruby:Gemfile
	gem 'simplecov', require: false, group: :test
	```
2. `spec_helper.rb` で SimpleCov をロード＆起動

	```ruby:spec_helper.br
	require 'simplecov'
	SimpleCov.start 'rails'

	# Previous content of test helper now starts here
	```

これでテストを実行するとカバレッジレポート (`coverage/index.html`) が生成されるようになる。

# GitLab CI を構成する

生成したカバレッジレポートを GitLab Pages にホスティングするためのパイプラインを作る。
具体的には以下のような `.gitlab-ci.yml` になる。

```yaml:.gitlab-ci.yml
...

rspec:
  stage: test
  script:
    - bundle install
    - rspec
  artifacts:
    paths:
      - coverage/

pages:
  stage: deploy
  dependencies:
    - rspec
  script:
    - mv coverage/ public/
  artifacts:
    paths:
      - public
    expire_in: 30 days
  only:
    - master

...
```

* `rspec` ジョブ
  * `artifacts`: 生成したレポートをストア
* `pages` ジョブ 
  * `dependencies`: `rspec` ジョブで生成した artifacts をダウンロード
  * GitLab Pages は `public` ディレクトリ内を探しに行くので、ディレクトリ名は必ず `public` に
  * `only`: `master` ブランチの更新時のみレポートをデプロイする

# カバレッジレポートバッジにリンクを貼る

ここまでで、 master ブランチへのマージのたびに GitLab Pages にカバレッジレポートがデプロイされる状態。
あとはすぐ見に行けるように、 `README.md` のカバレッジバッジからのリンクを張る。

```md:README.md
[![coverage report](https://gitlab.com/APP_NAME/GROUP_NAME/badges/master/coverage.svg?job=rspec)](https://APP_NAME.gitlab.io/GROUP_NAME/)

...
```

* `Settings` > `CI /CD` > `General piplines` からバッジの Markdown を取得
    * デフォルトではリンク先が `commits` になっているので、これを GitLab Pages のページに変更する
* `job=rspec`: テストを実行するジョブ名を `rspec` 以外にしていたら置き換える
  * 上の例と同じように `.gitlab-ci.yml` を作成しているならこのままでよい

# 参考

* [Publish code coverage report with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/)
* [GitLab Doc ― Test coverage report badge](https://docs.gitlab.com/ee/user/project/pipelines/settings.html#test-coverage-report-badge)
TeamSpeak3サーバー立ち上げ

Ubuntuサーバー立ち上げの第一目的であるTeamSpeak3のサーバーをインストールしたので簡単な手順を残しておく．
Windowsで立ち上げたときよりもだいぶシンプルだった．

#1．新規ユーザーの追加
teamspeak3サーバーをインストールするためのユーザーを新規で作成．
ルートになれるユーザーでやるのはやめたほうがいいらしい．何が起きるかわからないからか．

```shell:
$ sudo adduser teamspeak

#useraddというコマンドもあるがこっちは同時に
#ホームディレクトリを作成してくれないのでadduserを使った
```
#2．アーキテクチャに合ったTS3をダウンロード
新規でOSをインストールしたら多分わかっているが，念の為32bitか64bitか確認するためにarchコマンドを使う．

```shell:
$ arch
x86_64
```
|出力|bit|
|:------------------:|:------------------:|
|x86_64,　amd64|64bit|
|i386,　i686,　x86|32bit|


下記のダウンロードページでLinux用(**自分の場合は64bit**)の「DOWNLOAD」のリンクを取ってくる．
[TS3ダウンロードページ](https://www.teamspeak.com/en/downloads.html#server)

```shell:
$ wget　http://dl.4players.de/ts/releases/3.2.0/teamspeak3-server_linux_amd64-3.2.0.tar.bz2
```
#3．解凍
それをteamspeakのホームディレクトリで解凍

| 拡張子  | 操作 | コマンド                         |
|------------|:----:|---------------------------------|
| **tar.gz** | 圧縮 | tar -zcvf foo.tar.gz directory  |
|            | 解凍 | tar -zxvf foo.tar.gz            |
| **tar.bz2**| 圧縮 | tar -jcvf foo.tar.bz2 directory |
|            | 解凍 | **tar -jxvf foo.tar.bz2**       |
| **tar.xz** | 圧縮 | tar -Jcvf foo.tar.xz directory  |
|            | 解凍 | tar -Jxvf foo.tar.xz            |
| **tar**    | 圧縮 | tar -cvf foo.tar directory      |
|            | 解凍 | tar -xvf foo.tar                |
| **zip**    | 圧縮 | zip -r foo.zip directory        |
|            | 解凍 | unzip foo.zip                   |

#4．起動
規約承諾のために解凍してできたフォルダ内に.ts3server_license_acceptedという空のファイルを作ってから，
以下のコマンドを打って初回起動完了．初回のみ管理者権限のトークン等表示されるのでどこかに書き残しておく．

```shell:
$ cd ~/teamspeak3-server_linux_amd64/
$ touch .ts3server_license_accepted
$ ./ts3server_startscript.sh start


#再起動はこれ
$./ts3server_startscript.sh restart
```
あとは**クライアント側で**サーバーに接続して，トークン入れて，管理者権限取って，設定いじって...

#5．ポートマッピング
ネットワーク外からteamspeak3のサーバーに接続しようとうしてもその通信をルーターがネットワーク内のどこに繋げばいいかわかってないといけない．
追加する．

|ポート番号|プロトコル|用途|
|------|------|------|
|9987|UDP|通話ポート|
|10011|TCP|クエリポート|
|30033|TCP|ファイル転送ポート|

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/239365/df72138b-4244-8968-2e08-fc026e7a3819.png)
2018年7月第4週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■3分で API を作って世の中にデプロイするライブコーディング〜今日から君もスピードスターエンジニア〜
https://qiita.com/numanomanu/items/7bb6542961a2c567f05c?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
これくらいのスピード感でアプリケーションを作っていかなきゃ技術の伸び率は上がってかないのだろうなぁ

##■データ復旧企業の「ひとり情シス」、ほぼ半年で基幹システムを刷新するの巻
http://www.itmedia.co.jp/enterprise/articles/1807/23/news004.html
技術力などの専門的な能力よりも提案力とかリードする力が無いと、それなりの会社で1人で半年ってのは無理だ。
特にリードして実行してしまう力が大事なのかなぁと。

##■週4日労働の話
「週4日労働」で従業員のストレスレベルと生活満足度が改善されたという報告
https://gigazine.net/news/20180723-four-day-week-work/
週休2日制は非効率だという証拠
https://gigazine.net/news/20140825-four-day-workweek/
自分の部の目標の週休3日が如何に良いかというお話。
特に2つ目の記事のシフト制を組むことで結果4連休を作るってのは良いなぁ。

##■2つのドアがあるバスルームでプライバシーと利便性を両立させる方法とは？
https://gigazine.net/amp/20180722-hotel-bathroom-puzzle
手段や現状に囚われすぎて本来最も重要な問題解決に向かうことを忘れてしまうのは、プライベートだろうが仕事だろうが本当によくある。
気を付けなきゃと思いつつ、なかなか。。。

##■寄り目を利用した「目diff」および「立体インデント」の考案
https://qiita.com/set0gut1/items/be9247910eb7c155d592?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
スゲーと思ってこれは使える・・・と思って、いや使えねーわってなる。
でも楽しい。

##■Amazonアプリの新機能によって、ネットで正しいネジが買えるように
https://www.gizmodo.jp/amp/2018/07/amazon-part-finder.html
大きさを判断させるのにコインを横に置かせるっていうのは発想がすごい

##■Microsoftは機械学習を利用してPC使用中にWindows10がアップデートするのを回避しようとしている
https://gigazine.net/news/20180726-machine-learning-stop-windows-update/
なぜそこまでして自動アップデートにこだわるのか・・・？

##■スマートスピーカー型「AI観光コンシェルジュ」で“言葉の壁”を超えた観光案内――昭文社ら、大分県別府市で実証実験へ
http://www.itmedia.co.jp/enterprise/articles/1807/26/news057.html
音声入力とグローバルってのはかなり相性良いんだなと記事を見て気付かされた

##■Google Chrome、全HTTPページに「保護されていません」警告を表示
https://tech.nikkeibp.co.jp/it/atcl/idg/14/481709/072600452/
HTTPが本格的に淘汰されてきて、色々と面倒なことが内部的に増えてきそう

##■[新機能]EC2やS3不要！ALBだけでメンテナンス画面を表示するなど固定レスポンスが返せるようになりました！
https://dev.classmethod.jp/cloud/aws/alb-fixed-response/
メンテナンス用のページやサイトを準備しなくて良いってのが素晴らしい

##■あなたは解けるか？　関西発、セキュリティクイズ大会に登場した“あんなこんな問題”
http://www.itmedia.co.jp/enterprise/articles/1807/27/news018.html
たぶんほとんど分からないと思うけど、チャンスがあれば出てみたい

##■世界中のプレイヤーやAIと対戦できる、駒がみずから動くスマート・チェス
https://www.gizmodo.jp/amp/2018/07/square-off.html
ゲームのオンライン対戦でいいじゃんとなりがちなんだけど、例えばカードゲームだったり、ボードゲームだったり、物理的なことに価値があり売りになるものは意外とあるはず。
このアプローチは面白い。
pg8000の導入とSelect文の発行

## 概要
PythonからPostgreSQLを参照する。

### 環境
* Python 3.6.6
* PostgreSQL 10
* pg8000 1.12.2
* atom-runner 2.7.1

## 詳細
### インストール
* Python, PostgreSQLのインストールは割愛
* pg8000はpipでインストール

```
pip install pg8000
```
condaからは新しいバージョンのパッケージをインストールできなかった……。

### テーブル
デモコードで使用するテーブルを作成しておく

|id (int)|name (varchar)|yomigana(varchar)|birth_place(char)|
|---|---|---|---|
|1|洲崎 綾|すざき あや|石川県 |
|2|西 明日香|にし あすか|兵庫県 |

### デモコード
#### インポート

```Python
import pg8000
```
#### コネクション生成  
接続情報を渡してコネクションオブジェクトを生成する。
渡す情報の種類とキーワードは以下の通り。
> pg8000.connect(user, host='localhost', unix_sock=None, port=5432, database=None, password=None, ssl=False, timeout=None, application_name=None)

デモでは`localhost:5432`のDBにアクセスするので以下のように設定。

```Python
conn = pg8000.connect(user='postgres', password='***', database='kurukuruz1')
```

#### カーソル生成
コネクションオブジェクトからカーソルオブジェクトを生成する。

```Python
cur = conn.cursor()
```
コネクションオブジェクトはDBとの物理接続を表し、トランザクション管理を行う。
カーソルオブジェクトはフェッチ操作のコンテキストを管理する。

#### 全レコード取得  
カーソルオブジェクトを介してselect文の発行し、結果を受け取る。

```Python
cur.execute('SELECT * from actors')
results = cur.fetchall()

for row in results:
    id, name, yomigana, birth_place = row
    print(id)
    print(name)
    print(yomigana)
    print(birth_place)
```
↓実行結果

```
1
洲崎 綾
すざき あや
石川県
2
西 明日香
にし あすか
兵庫県
```

#### クエリへのバインディング
いくつかのバインド記法が用意されており、`pg8000.paramstyle`で設定されている。
今回はJavaのPreparedStatement風に`?`にバインドするために、以下のように設定を変更する。

```Python
pg8000.paramstyle = 'qmark'
```
バインドするパラメータはexecute時にクエリとともに渡す。

```Python
cur.execute('SELECT * from actors where name = ?', ('洲崎 綾',))
results = cur.fetchall()

for row in results:
    id, name, yomigana, birth_place = row
    print(id)
    print(name)
    print(yomigana)
    print(birth_place)
```
↓実行結果

```
1
洲崎 綾
すざき あや
石川県
```

## 参考サイト
* [PythonからPostgreSQLに接続する方法 _ アシスト.html](https://www.ashisuto.co.jp/db_blog/article/20160308_postgresql_with_python.html)
* [GitHub - mfenniak_pg8000_ A Pure-Python PostgreSQL Driver](https://github.com/mfenniak/pg8000)
* [PEP 249 -- Python Database API Specification v2.0 | Python.org](https://www.python.org/dev/peps/pep-0249/)

## おまけ
atom-runnerをそのまま使うと2バイト文字がエラーになるので文字コード設定を追加する。
#### 参考
* [Atom-Runnerの文字コード - .reboot](http://limit6577.hatenablog.com/entry/2017/12/10/214616)
http://getnutritionshelp.com/activated-xtnd/

few se isn’t a minumum of one wonder. Activated Xtnd Where differs inside o rs the use of 's inlaws is generally 's “Sexual Effectiveness Blend” the usage of “Free will male hgh Boosting Matrix”. Here’s what’s taken w h just about each human beings: -Sexual Effectiveness Blend: L-C rulline, Catuaba Start out barking Get preserve of, Maca 

http://getnutritionshelp.com/activated-xtnd/
owncloudのインストールに失敗

下記のページを見ながらインストールしたつもりなのですが
https://qiita.com/kashikotuka/items/9a7e4c82126830415a10

ownclooudのインストールの項目で
# sudo apt-get -y install libapache2-mod-php5 php5 php5-gd php5-common php5-mysql php5-curl php5-intl php5-mcrypt php5-imagick php-apc

打ち込んでEnter すると、

sudo: apt-get: command not　found　と表示されます。

そこで、下記のページを見て
https://qiita.com/Sa2Knight/items/bdb6d821a3ac10088289

[解決] bash: sudo: command not found

# cd /
# find . -name sudo
./run/sudo
./etc/pam.d/sudo
./etc/selinux/targeted/active/modules/100/sudo
./var/db/sudo
./usr/bin/sudo
./usr/libexec/sudo
と表示されます。

記みたいにsudoコマンドがあるのに利用できない場合はパスが通ってないだけなので、パスを通す。

と書いてありますので、

# cd /
# find . -name sudo
#

と打ち込みました。…しかし
./run/sudo
./etc/pam.d/sudo
./etc/selinux/targeted/active/modules/100/sudo
./var/db/sudo
./usr/bin/sudo
./usr/libexec/sudo
と表示されます。

強引に　# apt-get update と打ち込んでみたら
-bash:apt-get:command not found と表示されます。

すみませんがアドバイスを宜しくお願いします。
csv 形式の数値データを配列へ変換（jq コマンド）

こんにちは。
jq コマンドを使って、csv 形式の数値データを配列へ変換しました。

####配列形の入力として処理する方法
入力の各行を Json 配列形```[]```へ格納した後、```jq``` コマンドへ渡します。

```console
$ echo -en "1,0\n2,0\n3,0\n" | perl -pe 's/.*/[$&]/' | jq -sc .
[[1,0],[2,0],[3,0]]
$ echo -en "1,0\n2,0\n3,0\n" | awk '{printf "[%s]\n", $0}' | jq -sc .
[[1,0],[2,0],[3,0]]
$ echo -en "1,0\n2,0\n3,0\n" | while read line; do echo "[$line]"; done | jq -sc .
[[1,0],[2,0],[3,0]]
```

####文字列の入力として処理する方法
文字列の入力として処理する方法です。データ末尾の ```\n``` の削除も必要です。

```console
$ echo -en "1,0\n2,0\n3,0\n" | jq -sRc '[split("\n")[]|split(",")|map(tonumber)][:-1]'
[[1,0],[2,0],[3,0]]
$ echo -en "1,0\n2,0\n3,0\n" | jq -sRc '[split("\n")[]|select(. != "")|split(",")|map(tonumber)]'
[[1,0],[2,0],[3,0]]
$ echo -en "1,0\n2,0\n3,0\n" | ghead -c -1 | jq -sRc '[split("\n")[]|split(",")|map(tonumber)]'
[[1,0],[2,0],[3,0]]
```
Bootstrapのグリッドってなんぞや？

#Bootstrapのグリッドとは
横幅いっぱいを12カラムとして、何カラム分の横幅を割り当てるかを指定できる仕組み。
グリッドは必要に応じて使えばよく、グリッドを一切使わずにページを作ってもOK。

#書き方　
書き方としては下記。
```col-[画面サイズ]-[カラム数]```
```col-md-3```⇦こんな感じ

画面がmdのサイズ（デスクトップ（中）以上）の時、３カラム分の幅ってこと。

たとえばcol-xs-6 col-md-4と指定すると、
スマートフォンとタブレット（xs〜sm）では6カラム、デスクトップ（中）サイズ（md）以上では4カラムの幅で表示されます。


#すき間を開ける
col-[画面サイズ]-offset-[カラム数]で、指定したカラム分の隙間が直前に挿入されます。
```col-sm-offset-2 col-sm-5```
2カラム空いて、5カラム幅。

こんな感じ。
R：欲しいパッケージのうち未インストールのパッケージのみインストールする

欲しいパッケージのうち、未インストールのパッケージのみインストールした時の備忘録\_φ(･\_･


# 環境
- Mac OS X 12.6
- RStudio 1.0.136

# 未インストールのパッケージのみインストールする
[パッケージが既にインストール済みか判定し、未インストールの場合実際にインストールする](http://d.hatena.ne.jp/teramonagi/20130823/1377291452)に掲載の関数をベースにさせていただきました。

```r:参考ページに掲載の関数
install.package.ifnot.exist <- function(name)
{
  is.exist <- name %in% rownames(installed.packages())
  if(!is.exist){install.packages(name)}
}
```

~~関数名考えるのが苦手なので、~~teramonagiさんの関数名を真似させてもらいつつ、
複数パッケージを処理できるように、以下のように手を加えました。

```r:未インストールのパッケージのみインストールする
install.packages.ifnot.exist <- function()
{
  p <- readline("type packages you want :")
  p <- gsub(" ","",unlist(strsplit(p, ",")),fixed=T)
  is.exist <- p %in% rownames(installed.packages())
  if(length(p[!(is.exist)])>0){
    install.packages(p[!(is.exist)])}
}

# 出力結果
# > install.packages.ifnot.exist()
# type packages you want :ggplot2,reshape2

#  There is a binary version available but the source version is later:
#        binary source needs_compilation
# ggplot2  2.2.1  3.0.0             FALSE

# installing the source package ‘ggplot2’

#  URL 'https://cran.rstudio.com/src/contrib/ggplot2_3.0.0.tar.gz' を試しています 
# Content type 'application/x-gzip' length 2847050 bytes (2.7 MB)
# ==================================================
# downloaded 2.7 MB

#  strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) で警告がありました: 
#   unknown timezone 'default/Asia/Tokyo'
# * installing *source* package ‘ggplot2’ ...
# **  パッケージ ‘ggplot2’ の解凍および MD5 サムの検証に成功しました 
# ** R
# ** data
# *** moving datasets to lazyload DB
# ** inst
# ** preparing package for lazy loading
# ** help
# *** installing help indices
# *** copying figures
# ** building package indices
# ** installing vignettes
# ** testing if installed package can be loaded
# * DONE (ggplot2)

# The downloaded source packages are in
	 
# ‘/private/var/folders/t9/xk2j5yln4_dfmh518_4xvyw80000gn/T/RtmpzpaHdt/downloaded_packages’
```

ひとまずこれで完成です。
今回、関数内で入力ラインを呼び出したかったので、ごちゃごちゃ書きましたが、もし引数としてパッケージ名を入力する場合は下記をご参考までに。（冒頭の関数とほぼ同内容です）

```r:未インストールのパッケージのみインストールする
install.packages.ifnot.exist <- function(name)
{
  is.exist <- name %in% rownames(installed.packages())
  if(length(name[!(is.exist)])>0){
    install.packages(name[!(is.exist)])}
}

# 使用例
# > install.packages.ifnot.exist( c("ggplot2","dplyr") )
```



たまにある、devtools使わないと落とせないパッケージには未対応です。
分岐文で書いていけば、できないことはなさそうですが・・今回はここまでです。
WindowsでのMinecraftのローカルセーブデータをバックアップする

#個人的なゲーム状況
私がMinecraftをする場合、基本的にはハードモードで実施する。
プレイヤーが死ねば、復活ポイントで再活動できるのが基本だが、たかがゲームだと思っているため、復活できないモードで遊んでいる。
ゲームを始める前や序盤は、その考えから変わらない。
しかし、ゲームが進むにつれて、一からやり直す気力がなくなってくる。
ゆえに、セーブデータを作って、やり直しポイントを自分で作った。

#準備物
* AutoHotKey　(バックアップ実施用のバックグラウンドソフトウェア)
* テキストファイル　(バックアップを作成するための目次)
* Minecraft本体　(当たり前)

#以下、AutoHotKeyを前提に動くバックアップソースコード
起動方法は、`Win+Alt+s`の組合せでバックアップが行われる。

```AHK:AHKMinecraft.ahk
#!s::
;		注意：ディレクトリ名にスペースがついている場合,圧縮されない.
;			そして,2GB以上は,きっと圧縮できないだろう.

	minecraftSaveFile := % A_ScriptDir . "¥savedataMinecraft.txt"
	todayYYYYMMDD := A_YYYY A_MM A_DD

	Loop, Read, %minecraftSaveFile%
	{
		;	コマンドプロンプトからzipは作成できないようだ.
		;		http://q.hatena.ne.jp/1184648250

		Run, PowerShell -Command "Remove-Item ¥"‾¥Desktop¥%A_LoopReadLine%%todayYYYYMMDD%.zip¥" -Force"
		Run, PowerShell -Command "Compress-Archive -Path ¥"%A_AppData%¥.minecraft¥saves¥%A_LoopReadLine%¥" -Destination ¥"‾¥Desktop¥%A_LoopReadLine%%todayYYYYMMDD%.zip¥""
	}
return
```

#バックアップ用のテキストファイルの用意
今回は、ソースコード上にファイル名をべた書きしている。
 `savedataMinecraft.txt`
このファイルに、ワールド名を記載する。
正確に表現するならば、savesディレクトリ配下に配置されるディレクトリ名を記載する。
このテキストファイルの配置場所は、ソースファイルと同じ場所に置けばいい。

![新規ワールド.png](https://qiita-image-store.s3.amazonaws.com/0/82414/8e18d8ec-8f0b-1a8f-9fec-854dba3cc939.png)
![テキストファイル.png](https://qiita-image-store.s3.amazonaws.com/0/82414/9e41be9c-5068-8945-c0d9-2e7de152936f.png)
![saves.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/66a95282-ab61-7357-069e-913f874a0494.jpeg)
※注意点：ワールドを作成するときの名前に、スペースを付けた場合、動かない問題が残されている。
スペース付きのディレクトリをPowerShell単体では認識するのだが、AutoHotKeyをかました場合動かないため、なかなか原因を突き止められず、今のところ放置している。
また、きっと2GB以上のデータは保存できない(PowerShellに問題がある)。こればかりは、対応可能な圧縮ソフトウェアを使う必要があるだろう。私の信念としては、できる限りWindows標準装備で実装したい思いがあるため、圧縮ソフトまで考慮しなかった。
すでに、AutoHotKeyを使っているわけだし・・・。
結構重要なことなのだが、遊びながらバックアップを動かすことは出来ない("おまけ"に画像有り)。ファイルをゲームがつかんでいるためだと思われる(私の環境では失敗した)。もしかしたら強制的に動かせるのかもしれないが・・・。

#バックアップファイル
デスクトップ上に配置されるはず・・・。
ワールド名に続けて、バックアップ年月日が追加した状態の名前になっている。
拡張子は`zip`だ。
例）新規ワールド20180727.zip

以上．

#おまけ
数年前に作ったバックアッププログラムは、WindowsOSで動かなかった。
　[minecraftのセーブデータを管理するPerlプログラム](https://qiita.com/chesscommands/items/bf0caf40e3e9c91952b4)
Mac専用なのだろう・・・。

以下の状態ではバックアップできない(PowerShellが動きはするが・・・)。
![2018-07-27_21.20.10.png](https://qiita-image-store.s3.amazonaws.com/0/82414/0d2a86b7-341a-d280-7845-f88f48886e31.png)

##さらにおまけ
復元は手動でお願いします。
Debian 9にLet's Encrypt + nginxでSSL対応サイトを構築する

無料でサーバ証明書を発行することのできる[Let's Encrypt](https://letsencrypt.org/)を使って、SSL対応にしていきます。
Let's Encryptについては非公式の日本語ガイドがあって助かった。[Let's Encrypt 総合ポータル](https://letsencrypt.jp/)


Let's Encryptの証明書は有効期間が90日、なので取得、自動更新のためにCertbotクライアントをインストール。
[証明書の有効期間が90日間な理由 - Let's Encrypt 総合ポータル](https://letsencrypt.jp/blog/2015-11-09.html)

## Certbotのインストール
[Certbot](https://certbot.eff.org/)でソフトウェアとシステムを選択。
![スクリーンショット 2018-07-26 12.08.32.png](https://qiita-image-store.s3.amazonaws.com/0/267695/515b1f1d-4c5f-132d-26d6-ec8bb2c0337e.png)
今回は nginx + Debian 9、順番通りに進めていく。

backportsの設定をしていなかったので、[Instructions](https://backports.debian.org/Instructions/)を参考に`sources.list`に以下の文を追加。

```
deb http://ftp.debian.org/debian stretch-backports main
```
保存したら `$ sudo apt-get update`

そしてインストール。

```
$ sudo apt-get install python-certbot-nginx -t stretch-backports
```

## 証明書の発行

```
$ sudo certbot --authenticator webroot --installer nginx
```

必要事項を入力して証明書を発行。ちなみにドキュメントルートを1回間違えて失敗した。
実行すると必要な設定はCertbotが自動で`/etc/nginx/sites-available/〇〇`に書き込んでくれるのでこれでOK!
個人的コメント基準 [Java編]

「どんな基準でコメントしてるの？」と聞かれたときのために。
だいたい30分ぐらいで書いたので抜け漏れいっぱいあると思うけど何となくこんな感じです。

# Javadoc
基本的につける。 private はやや優先度が落ちるが、特にそれがメソッドであるならできるだけつける。
Javadoc 側で用意された機構 (return とか) をふんだんに使い、タグもどきの類は絶対に使わない。

Q. private の Javadoc ってドキュメント生成の意味ないじゃん。バカなの？
A. 自動生成でパパっと勘所押さえんだよ。それに補完の Tips だって Javadoc 拾うだろうが。変数名で全部なんとかなるって言っていいのは全人類に叡智を授けてからだ。

# Normal
概ね以下のような基準で付ける。

* 最適解だと思えない/特異な/真っ当でない記述 → お気持ち表明程度[^1]
  * 仕様問題やバグのワークアラウンド
  * APIの制限に対処するもろもろ
  * 触れない/触りたくないクラス起因の問題
  * ほか
* 歴史的事情による記述 → 理由、参考資料へのリンク[^2]
  * 「諸事情により未だJava 6なので: http://~」
  * 「DBがEUC-JPなので」
  * 「バグが仕様になりやがったので: <チケット番号>」
  * ほか
* 一般的に「これを使うべき」とされるものの回避 → 理由、内容、参考資料へのリンク
  * ライブラリのバグや奇妙な仕様[^3]
  * 意図的な仕様違反[^4]
  * ほか

# Rewrite
以下のようなコメントは可能であれば書き換えるか排除する。
「**取得する**」「**設定する**」という言葉が出てきたら大抵は排除対象である。

* 無価値
  * getXXに"XXを取得" "To set XX"
  * setXXに"XXを設定" "To get XX"
  * XX に "XX"[^5]
  * ほか
* 冗長
  * [Function] とか [Description] とか[^6]
  * interface のコメントを実装側で "上書き" [^7]
  * ほか

[^1]: 愚痴半分になりがち。兎角短めに。
[^2]: 内容が内容なのでこれまた長くなりがち。資料を用意してそっちに書いておくべきだろう。
[^3]: Hibernate Validator とか。
[^4]: メールアドレスのバリデーションとか。
[^5]: 特に serialVersionUID に "serialVersionUID" と書いてあるのはほんと何考えてんだろう。何も考えてないのか。
[^6]: Javadoc の仕様とか読まないのかな。読まねえんだろうな。
[^7]: 幸い "interface 側に重要なことが書いてあるのに潰された" なんてことは意外と起きない。大抵コピペだからだ。
【Unity】カオスな連成振り子～リアルなモデルで薔薇が描けた♬

[前回は天使が出てきた](https://qiita.com/MuAuan/items/0ded603a81ba83e17a90)が、今回はバラが描けた。。。

###やったこと
（１）バラが描けた～アートとして。。鑑賞♪
（２）モデルとコード
（３）OculusGoで見る
###（１）バラが描けた～アートとして。。鑑賞
![plot_xp2omega2006-10000-001-m1.png](https://qiita-image-store.s3.amazonaws.com/0/233744/d2729b81-2a62-f0e7-40fd-be90ce1adbbd.png)
![plot_xp1omega2006-10000-001-m1.png](https://qiita-image-store.s3.amazonaws.com/0/233744/389c9cd6-0316-cd16-94e9-b8abb2f9b6ba.png)
![plot_xp1omega20125-400-001.png](https://qiita-image-store.s3.amazonaws.com/0/233744/ce517c47-d08e-51ca-8bfb-33159335a843.png)
![plot_xp2omega20125-400-0015.png](https://qiita-image-store.s3.amazonaws.com/0/233744/e73f6960-830b-e318-c1cc-31968ea04caa.png)
![plot_xp2omega20155.png](https://qiita-image-store.s3.amazonaws.com/0/233744/4b36d291-ff26-f8f5-7957-9c13ed5eab7b.png)
![plot_xp2omega20125-40-005.png](https://qiita-image-store.s3.amazonaws.com/0/233744/a5274f9c-61fe-1c13-6551-6dab407ec656.png)
![plot_xp2omega20125-400.png](https://qiita-image-store.s3.amazonaws.com/0/233744/ce9d64d6-30e0-b447-a47d-1a67f3897793.png)
###（２）モデルと[コード](https://github.com/MuAuan/LSTM/blob/master/dualPendulum.py)
連成振り子の一番簡単なモデルは以下の参考のようにひもなどで連結したものである。
・[連成振り子による非線形な振る舞いとカオス](http://www.phys.chuo-u.ac.jp/labs/taguchi/sotsuron/2000/fujita00/sotsuron.pdf)

```math
m_1l_1\frac{dω_1}{dt} = -m_1g\sin(\theta_1) - k\theta_{21}{}
```

```math
m_2l_2\frac{dω_2}{dt} = -m_2g\sin(\theta_2) + k\theta_{21}{}
```
この連立微分方程式をodeintするとパラメータによって上記のような絵が描ける。
コード例の主要な部分は以下のとおり

```py
def dualPendulum(y, t, b, c):
    theta1, omega1,theta2, omega2 = y
    #theta21=theta2-theta1
    dydt = [omega1, -b*omega1 - c*np.sin(theta1)-0.06*(theta2-theta1),omega2, -b*omega2 - c*np.sin(theta2)+0.06*(theta2-theta1)]
    return dydt

b = 0.001  
c = 5.0
y0 = [np.pi - 0.1, 0.0,0, 0.0]
t = np.linspace(0, 10000, 4001)
sol = odeint(dualPendulum, y0, t, args=(b, c))
x1, p1,x2,p2 = sol.T[0], sol.T[1], sol.T[2], sol.T[3]
```
###（３）OculusGoで見る
今回のポイントは、比較的簡単な相互作用であり、Unityでも同じような相互作用をすると想定できるので、同じような条件で降らせるとひょっとするとカオスが見られるかもしれない。。。

上記の描画を見ていると、比較的初期のころエネルギーをもらう側の振幅が小さいときにカオス的な振動が見られることが分かりました。
たとえば、以下のような振動の様子が観察されます。
![plot_thomega2vst20125-400g-0015.png](https://qiita-image-store.s3.amazonaws.com/0/233744/95e77897-eeec-8846-41c7-7a5d874a5625.png)
この振幅が小さい部分を拡大すると以下のような振動になっています。
※パラメータは少し異なりますが。。
そして、この振幅の小さい側の振動は[以前のカオスな振動の様子](https://qiita.com/MuAuan/items/fbb8fa208b88e1fe8473)とよく似ていることが分かります。
![plot_thomega2vst1006-100g-001-m10.png](https://qiita-image-store.s3.amazonaws.com/0/233744/978d4eff-2b3f-6ef0-0ef3-b33026acab76.png)


ということでやってみました。
結果は、以下のような動画が得られました。

[【OculusGo】リアルな連成振り子でカオスな運動をキャッチした♪](https://youtu.be/zEHLSyKcrAg)
<a href="http://www.youtube.com/watch?feature=player_embedded&v=zEHLSyKcrAg" target="_blank"><img src="http://img.youtube.com/vi/zEHLSyKcrAg/0.jpg" 
 </a>
※画像をクリックするとYouTube動画につながります

一応、上記動画では、止まっていた振り子が引きずられように触れ始めまた静止して動き始めるときが一番カオス的な振動に見えます。。。ってちょっと無理してますが、。。

###まとめ
・簡単な連成振り子でカオスな振舞をすることを微分方程式で見た
・位相空間の運動がまるで薔薇のような描画など多彩な描画ができた
・OculusGoでカオスな運動をVRできたと思う

・まだまだクリアな状況までの観察ができていない
・Flaskで計算した結果を渡すのも試みたが、初期動作が安定せず失敗したので実現したい
プログラミング初心者が壁にぶつかったときに乗り越える4つの方法

#「プログラミングでエラーがでて先に進めない・・・」

プログラミングをしていると、エラーが出て手が止まってしまうことが多くあると思います。

今回は、プログラミング初心者が壁にぶつかった時にどうすればクリアできるかをまとめてみました。

ここで紹介するのは主にWebサイト系です。

人に聞いたり他にも手段がとれる場合もありますが、Webサイトは孤独に戦う場合に有用な手段だと思います。

重要な「検索力」の一部だったりもします。

##Qiita（ココ）
https://qiita.com/

メジャーなところ。
多くの情報がのっていて、範囲もレガシーから最先端まで様々。
まずはここで調べるのがベター。

##Teratail
https://teratail.com/

質問がいろいろできるフォーラムみたいな場所です。
回答率90%以上！と打ち出していて、解決率は高い。
ただし、ニッチな質問をすると回答がつかないこともある。
迷ったらとりあえず聞いてみよう。

##StackOverflow
https://stackoverflow.com/

超大手のグローバル質問サイト。
とはいっても日本語でのスレッドも多数あるので使いやすい。
情報量が少ないものは英語でしかなかったりするので、英語で調べる・質問することが必要。
わからなければ翻訳しちゃえばいいと思います。

##オフィシャルサイト
ほとんどの言語はオフィシャルがあるので、そこを活用しましょう。
日本語の場合と英語の場合があります。

サイトの構成によってアンサーを探しづらいことが多いですが、最終的な答えはほとんどの場合ここにあると思ってください。

#まとめ

以上4つを使いこなせば、多くの問題は乗り越えられると思います。

これらを使いながら検索や質問のやり方を身につけていくと、息をするようにプログラミングの問題を解決でき、実現したいサービスをつくることができるでしょう！
Tensorflowでエラー「tensorflow error KeyError: “The name 'import/Mul' refers to an Operation not in the graph.”」が出た時

###Tensorflowのエラーが発生した時の解決法

こちらの記事を参考に、画像を認識して判定するものをつくってみました。
[TensorFlowで画像認識「〇〇判別機」を作る - Qiita](https://qiita.com/too-ai/items/4fad0239b8b3c465fe6d)


で、実際にコマンドを実行してみると

```
python label_image.py --image xxx.jpg --graph retrained_graph.pb --labels retrained_labels.txt
```

こんなエラーが発生しました。

```
 /Users/xxx/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
      from ._conv import register_converters as _register_converters
    2018-07-11 00:39:22.028051: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
    Traceback (most recent call last):
      File "label_image.py", line 131, in 
        input_operation = graph.get_operation_by_name(input_name)
      File "/Users/xxx/tensorFlow/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3718, in get_operation_by_name
        return self.as_graph_element(name, allow_tensor=False, allow_operation=True)
      File "/Users/xxx/tensorFlow/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3590, in as_graph_element
        return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
      File "/Users/xxx/tensorFlow/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3650, in _as_graph_element_locked
        "graph." % repr(name))
    KeyError: "The name 'import/Mul' refers to an Operation not in the graph."
```

ここがエラーになっているようです。

```
KeyError: "The name 'import/Mul' refers to an Operation not in the graph."
```


ちなみに「label_image.py」の中身は

```py
      input_height = 299
      input_width = 299
      input_mean = 0
      input_std = 255
      input_layer = "Mul"
      output_layer = "final_result"
```
こんなかんじ。


色々調べた結果、最後に「--input_layer=Placeholder」をつけると解決。
問題なく動作するようになりました。

```sh
python label_image.py --image cat3.jpg --graph retrained_graph.pb --labels retrained_labels.txt --input_layer=Placeholder 
```
[object Object]parsererrorSyntaxError: JSON Parse error: Unrecognized token '<' loading_end — update-product.js:

WordPressでjavascriptを使ってPOSTを送るリクエストを実装していた時に、コンソールに以下のエラーが出たのでその時の解決方法。


`[object Object]parsererrorSyntaxError: JSON Parse error: Unrecognized token '<'
loading_end — update-product.js:48`

WordPressはphpで構成されており、独自で作成したphpファイルの中でコメントアウトをかけていたところ、これが悪さをしていたようです。
自分のところでは、以下のようなコードを削除したら治りました。

```php
?>
<!-- コメントアウトされる文章 -->
<?php
```

phpを使わないところでコメントアウトを残しておくと、ダメみたいでした。
ヒカキン「質が低くても毎日更新したほうがいいよ」ぼく「せやな」

今日バズってて見つけたのですが、

https://note.mu/sukimeshi/n/n21078200f760

ヒカキン「消えるクリエイターは時間をかけて凝ったものを配信する。消えずに活躍する人は質が低くても毎日続ける」

的なことを言ったらしいです。

なるほどなるほど。

いいこと言うじゃん。

で、思ったわけです。

これは、プログラマにも当てはまるのでは？

ブロガーにとってのブログ、
Youtuberにとっての動画、
プログラマにとっては、 `git commit`かな？

つまり、Github緑化活動ですね。

# 毎日更新したほうがいいよ

これは、Youtuberやブロガーには強く当てはまる話だと思います。

本日投稿があったものを強くプッシュしてくれるYoutubeの通知機能とのマッチもそうだし、

ファンの人が毎日チェックするという、一種の習慣に落とし込むことができます。
（ぼくはこれを勝手にログボ効果と呼んでます）

ブログや動画とかのアクセス数のほとんどは、
投下してから２４時間以内に稼ぐ、という経験則もありますし。
彼らからするとすごく理にかなっているわけです。

Qiita や はてブ も、似た感じだと思います。

Githubとかは、毎日commitするのは
ぼくくらいの初級者レベルだと大事だと思います。


# 質は低くてもいい

ヒカキンもタクスズキさんも、（最初のうちは）
質が低くてもいい、みたいな言及をしています。

たぶん、下手くそのうちに質に拘っても、
こだわるポイントを間違えるだけだから、
まずはめっちゃ試行錯誤しろ、的な話だと思います。

まずは、「毎日」できるレベルが、
今の自分の真の実力だと認めろ、ってことなのかなって。

ちゃんと恥をかけ、ってことかって。

で、

このnoteでは言及されてないけど、

「最後には、クオリティもめちゃくちゃ上げる！」

という気概もいるのかな、と。

ヒカキンの動画は１つ６時間くらい時間をかけて
編集しているらしいので。

と、いうことで、

例の発言に感化され、
ぼくも今日から毎日githubがんばろうと思います。

スターください（）
https://github.com/kugyu10
GKEがデフォルトで提供してくれるログ まとめ (新Kubernets Monitoring版)

[Stackdriver Kubernetes Monitoring](https://cloudplatform.googleblog.com/2018/05/Announcing-Stackdriver-Kubernetes-Monitoring-Comprehensive-Kubernetes-observability-from-the-start.html) がベータ版としてリリースされて、
そっちに移行するとログまわりの構成が以前 ([GKEがデフォルトで提供してくれるログ まとめ](https://qiita.com/yokomotod/items/e2ac811fb12e71ce8a30)) とはかなり変化する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27025/1660a502-948d-c961-9a11-88dc2a9766a0.png)

`GKE ~` が以前までのログ。

クラスタ作成時に↓のチェックをつけて新しいモニタリングにすると、 `Kubernets~` になる。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/27025/e1b40b34-4df5-f8ac-1c66-3501c065ebf4.png)


なお1.10以上必須で、さらに、*クラスタ新規作成じゃないと有効にはできない* 1.9から１.10にしても、Kubernetes Monitoringは有効にできないので少しハードルが高い。
（ただ実際有効にしてみると後述のように盛大にログの出方も変わり、1.9からのマイグレーションをするのが辛そうなのは察せた・・・）

以下、Stackdriver Kubernetes Monitoring時代のGKEがデフォルトで提供してくれるログ まとめ

# Kubernets Container (`resource.type="k8s_container"`) 

おそらく旧 GKE Container (`resource.type="container"`) とおなじ。

デプロイされた各コンテナの標準出力、標準エラー出力が送られてくる。

## logNameがコンテナ名ではなく `stdout` ,`stderr` になった

Stackdriver Kubernetes Monitoring有効無効関わらずではなくGKE 1.10以上での変化なんじゃないかという気がしている。

コンテナごとのログを見るためには `resource.label.container_name` でフィルタすることになった。



# Kubernets Cluster (`resource.type="k8s_cluster"`) / Kubernets Pod (`resource.type="k8s_pod"`)

旧GKE Cluster Operations (`resource.type="gke_cluster"`) だったものが、
Pod内関連のログが`Kubernets Pod`、Pod外のログが`Kubernets Cluster`に分割された模様。

さらに、一部のログ "Node (node名) status is now: NodeHasInsufficientMemory" などは次に出てくる Kubernets Node に分割されている

例えば"pulling image", "Started container"などはKubernets Pod
"Scaled up replica set", "Created job"とかはKubernets Cluster

なお"Created pod"はKubernets Clusterに来る



# Kubernets Node (`resource.type="k8s_node"`)

以前はk8sノードであること関係なく、通常のinstanceでロガー使ったのと同じように GCE VM Instance (`resource.type="gce_instance"`) として出ていた。

インスタンス上で直接動く各種プロセスからのログが送らてくる。

* kubelet
* kube-proxy
* docker
* container-runtime

などのログが見える。

その中に混じって、前述のとおり "Node (node名) status is now: NodeHasInsufficientMemory" などの以前はGKE Cluster Operationsとして出ていたものが混ざっている。

# その他こまかな変化

`resource.label.namespace_id` が `resource.label.namespace_name` 、のように `..._id` だったのが `..._name` に変わっている。


# おわり

正式なドキュメントを見つけれていないけど、かなりログが変わる。

ログベースで監視とかしていて、フィルタ条件が完全に狂って混乱したので、
これからStackdriver Kubernetes Monitoringを使い始める人は注意しておくといいと思います。
Vue.js　コンポーネントをstateに入れて動的にコンポーネントを切り替える

個人的メモ
## 前提
大きめのSPAを開発するに中で、あるコンポーネントを呼び出す際、その中身を呼び出し元毎に変えたいってあるよね。（例えばモーダルとか）
中身のパターンが少しだけなら`type`を渡して`v-if`で切り替えてもいいけど多くなるとしんどいし、
`<slot>`を使えば簡単にできるけど、呼び出し元毎に同じコンポーネントを埋め込むのは非常にナンセンスな気が。。。
storeのstateに中身コンポーネントを格納しておいて呼び出し元でそのstateを別のコンポーネントに更新すると中身コンポーネントも切り替わるという設計で作成すればかなり柔軟なのではないかと行き着きました。

## 問題
ということでモーダルを作りました。が
いざモーダルを表示してみるとstateの中身コンポーネントがレンダリングされないなぜ！（文字列でfunction(){...}が表示される）
ってインスタンスのcomponentsに登録しないとそりゃまぁレンダリングされませんよね。。

```js:store.js
const inner = Vue.extend({...});
export default {
 state: {
  show: false,
  component: inner
 }
}
```
```vue:modal.vue
<template>
 <div v-if="show" class="modal">
  <div class="header">Modal Header</div>
  <div class="body">{{ inner }}</div>
 </div>
</template>

<script>
export default {
 computed: {
  ...mapState({
   show: state => state.show,
   inner: state => state.inner
  })
 }
}
</script>
```
`components`って動的に登録できないよな。。。とかしばらく悩んでたのですがすぐ公式DOCを見ていくうちに解決しました。

## isディレクティブを使う
isディレクティブを使えば動的にコンポーネントを切り替えられるみたいです。
公式DOCではcomponentsに登録した名前をisディレクティブに文字列でバインドしているみたいですが、コンポーネント自身も入れることができるみたいです。

```vue:modal.vue
<template>
 <div v-if="show" class="modal">
  <div class="header">Modal Header</div>
  <div class="body">
   <component is="inner"></component>
  </div>
 </div>
</template>

<script>
export default {
 computed: {
  ...mapState({
   show: state => state.show,
   inner: state => state.inner
  })
 }
}
</script>
```
こうすれば無事中身コンポーネントもレンダリングされました。