OmniAICreator/Qiita-1.07M huggingface dataset:
Nextcloud のユーザー管理

#はじめに
Nextcloudはオンラインストレージを構築できるオープンソースソフトウェアです。利用するユーザーの登録や削除、グループの割り当てなどは、管理者がWebインターフェース上で行うことができます。今回は、ユーザー管理画面について、紹介をしたいと思います。

#ユーザー管理画面
ユーザー管理画面を開くには、Nextcloudの管理者権限（adminグループに所属するユーザー）がある事が前提となります。まず、管理者ユーザーでログインし、画面右上のメニューから「ユーザー」を選択します。
![画像156.png](https://qiita-image-store.s3.amazonaws.com/0/308127/23081e03-7da4-2415-1cbb-b91eae87bceb.png)

ユーザー管理画面が表示されました。画面左側はグループ一覧が表示されています。画面中央から右端までは、ユーザー一覧が表示されています。（ユーザー一覧はログインIDのアルファベット順に並んでいます。）LDAP連携したユーザーやグループもこの画面上に表示されます。
![画像157.png](https://qiita-image-store.s3.amazonaws.com/0/308127/788409ae-4479-43d4-0f47-1bdddf06332d.png)

#ユーザー登録
ユーザー登録をするには、画面左上にある「＋新しいユーザー」をクリックします。
![画像158.png](https://qiita-image-store.s3.amazonaws.com/0/308127/26728f99-84fc-041f-5629-70b2ced3d8fb.png)

「＋新しいユーザー」をクリックすると、右側のユーザー一覧の上部より新しいユーザーを登録する事ができます。以下の項目を入力し、右端のチェックボタンを押すと、ユーザーが登録されます。

ユーザー登録の項目は以下となります。
・ユーザーID・・・ログイン時のID
・表示名・・・ブラウザ上で表示されるニックネーム的なもので、ユーザ自身で変更する事が可能です。
・パスワード・・・ログイン時のパスワードです。
・メール・・・メールアドレスを登録しておけば、アクティビティ機能などでメール通知する事ができます。
・グループ・・・所属するグループを設定します。（複数グループ設定可能）
・グループ管理者・・・グループ管理者に設定されたユーザーは、ユーザー管理画面を開く事ができます。指定されたグループのユーザー一覧しか表示されませんが、そのグループ内のユーザーの管理（登録や削除、クォータの変更等）は可能となります。
・クォータ・・・ユーザーに割り当てる容量が設定できます。

![画像159.png](https://qiita-image-store.s3.amazonaws.com/0/308127/115e19ba-92f7-526d-0275-d87a686c2247.png)


ユーザー登録が完了すると、ユーザー一覧に反映されます。
![画像160.png](https://qiita-image-store.s3.amazonaws.com/0/308127/bbd301bb-9353-5f3d-e4a9-ab2acc205a11.png)

#グループ追加
画面左上の「＋グループを追加する」を選択します。
![画像161.png](https://qiita-image-store.s3.amazonaws.com/0/308127/2c2a4974-d630-c5af-7b64-2f53be7ad526.png)

入力欄が表示されますので、任意のグループを入力し、「→」をクリックします。
![画像162.png](https://qiita-image-store.s3.amazonaws.com/0/308127/3da35c02-259b-943d-f902-a8a409c83e53.png)

グループが登録されました。
![画像163.png](https://qiita-image-store.s3.amazonaws.com/0/308127/57ae31b7-8546-4f30-6075-b7d342bcf57f.png)

登録済みのユーザーにグループを割り当てるときは、ユーザー一覧のグループの箇所で設定できます。
![画像164.png](https://qiita-image-store.s3.amazonaws.com/0/308127/75ae37ca-209f-ae05-d4ca-d577c98d4f4c.png)

#その他の項目
画面左下の「Setting」アイコンをクリックします。
![画像165.png](https://qiita-image-store.s3.amazonaws.com/0/308127/f64f9de2-d1ef-40b6-e7eb-40a7fe4a6f3a.png)

以下の項目が表示されます。チェックを入れると、ユーザー一覧に表示されます。
・デフォルトのクォータ・・・ユーザー登録した際に設定されるクォータのサイズです。
・Show Languages・・・ユーザー毎に設定されている言語
・最終ログインを表示・・・ユーザーが最後にログインした時間です。
・ユーザーバックエンドを表示・・・そのユーザーがNextcloudのローカルユーザーか、LDAP連携されたユーザーかを表示します。
・Show storage path・・・そのユーザーのファイル保管場所を表示します。

![画像166.png](https://qiita-image-store.s3.amazonaws.com/0/308127/a94f9421-5773-82c7-46c4-52a052a4174f.png)

#ユーザーの削除や無効
ユーザー一覧の右端の「・・・」をクリックすると、以下の項目が表示されます。
・ユーザーを削除・・・ユーザーを削除します。そのユーザーのディレクトリ（保管しているファイル）ごと削除されますので、削除の際はご注意ください。
・ユーザーを無効・・・無効にすると、ユーザーはログインできなくなります。
・ウェルカムメールを再送する・・・ユーザー登録時に通知する案内を再度送信します。（メールアドレスが設定されている事が前提です。）
・偽装・・・管理者がそのユーザーとしてログインできます。[別記事](https://qiita.com/mmisu/items/6b7e705302a9249561aa)で詳細を書いております。

![画像167.png](https://qiita-image-store.s3.amazonaws.com/0/308127/84192710-e287-88b6-93c9-16a2a1bf0f18.png)

#まとめ
ユーザー管理画面はこの1画面のみとなりますが、非常に使いやすい画面となっています。ユーザー数が多く（数千人以上とか）になってくると、一覧表示は難しくなってきますので、そういった場合は、画面左側のグループを選択すれば、そのグループに所属するユーザーだけ表示する事も可能です。

この記事は、[スタイルズ社のNextcloudサイト](https://nextcloud.stylez.co.jp/nextcloudblog)にも公開しております。
定例議事録を自動で作ってSlackに通知する

# 動機
弊社では毎週金曜日に事業部のAndroidエンジニアが集まって定例を行なっています。各々のプロジェクトの進捗や困っていること、最近気になった技術記事の共有などが目的です。話す内容は、定例までに共通のGoogleDocumentに各々書いておきます。
共通のGoogleDocumentは前日にリードエンジニアが用意してSlackで通知しています。この作業自体は大した労力はいりませんが、業務に追われて忘れてしまった場合スムーズに定例を始められません。そこで自動化してしまおうというのが動機です。

# コード
[**GoogleAppScript**](https://developers.google.com/apps-script/)を使います。コードの全容は以下です。

```javascript

var postUrl = 'SlackのIncoming WebhookのURL';
var username = 'hogehoge';  // 通知時に表示されるユーザー名
var icon = ':hatching_chick:';  // 通知時に表示されるアイコン

function createAndroidMTGDocument() {
  var fileName = "hogehoge";
  var fileId = "テンプレートファイルのID";
  
  var date = new Date();
  date.setDate(date.getDate() + 1);
  var formattedDate = Utilities.formatDate(date, "JST", "yyyyMMdd");
  
  var f = DriveApp.getFileById(fileId);
  //コピーを作成。作成したコピーを参照。
  f = f.makeCopy(fileName + "_" + formattedDate);
  f.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.EDIT);
  
  // Slack通知
  var url = f.getUrl();
  var message = "Android定例の議事録です。\n" +url
  var jsonData =
  {
     "username" : username,
     "icon_emoji": icon,
     "text" : message
  };
  var payload = JSON.stringify(jsonData);

  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };

  UrlFetchApp.fetch(postUrl, options);
}
```
なんとなく意味は分かるのではないかと思いますが、以下解説です。

# 解説

```javascript

var fileName = "hogehoge";
var fileId = "テンプレートファイルのID";
```
ファイルの作成をしています。あらかじめ議事録のテンプレートファイルを用意しておき、fileIdにテンプレートファイルのIDを格納します。

```javascript

var date = new Date();
date.setDate(date.getDate() + 1);
var formattedDate = Utilities.formatDate(date, "JST", "yyyyMMdd");
```

ファイル名のsuffixに定例の開催日を入れるための処理です。定例前日に議事録を作成するために今日の日付+1をしています。

```javascript

var f = DriveApp.getFileById(fileId);
//コピーを作成。作成したコピーを参照。
f = f.makeCopy(fileName + "_" + formattedDate);
f.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.EDIT);
```
テンプレートファイルをコピーしてアクセス権限の変更をしています。権限の変更については[コチラ](https://developers.google.com/apps-script/reference/drive/access)を参照してください。

```javascript
// Slack通知
var url = f.getUrl();
var message = "Android定例の議事録です。\n" +url
var jsonData =
{
   "username" : username,
   "icon_emoji": icon,
   "text" : message
};
var payload = JSON.stringify(jsonData);

var options =
{
  "method" : "post",
  "contentType" : "application/json",
  "payload" : payload
};

UrlFetchApp.fetch(postUrl, options);
```
Slackの通知は[コチラ](https://qiita.com/chihiro/items/c7b11abc78f5d806c3a8)のページが非常に分かり易かったので参照してください。

これをGoogleAppScriptで定期実行することで、議事録を作成してSlackに通知することができます。

# おわりに
指摘大歓迎です。
メモリ 応用情報技術者試験 対策日記@8

#メモリ
メモリとは、コンピュータにおいて情報の記憶を行う装置。
プロセッサが直接アクセスできる主記憶装置と、それ以外の補助記憶装置に分かれる。

##1.RAMとROM
主記憶装置には大きく分けて**RAM**と**ROM**がある。

**RAM(Random Access Memory)** 
「メモリ」という場合多くはRAMのことを指す。読み書きが自由である点が特徴。
半導体メモリを使っており、電源の供給がなくなると内容が消えてしまう。
一定時間経つとデータが消失してしまう**DRAM(Dynamic RAM)**と、電源を切らない限り内容を保持する**SRAM(Static RAM)**の二種類がある。
DRAMは安価で大容量のため、主記憶装置としてのメモリに使用される。一方、プロセッサがメモリにアクセスする頻度が多くなると処理速度が遅くなるため、高速かつ消費電力の小さいSRAMがキャッシュメモリに使われる。

**ROM(Read Only Memory)**
基本的に読み出し専用の記憶装置。書き換えができないマスクROMや書き込みが可能なPROM、書き込みと消去が可能なEPROMなどの種類がある。EPROMでも特に電圧をかけることで何度も書き込みと消去ができるEEPROMの一つとして、**フラッシュメモリ**が挙げられる。フラッシュメモリはUSBやSSDなどの記憶媒体に利用されており、本来はROMなので何度も書き換えを行うと劣化するため書き換え回数に上限がある。

##2.キャッシュメモリ
プロセッサとメモリの間の性能差を埋めるために、高速なSRAMを利用してキャッシュを格納している。
キャッシュメモリでデータを管理するときには、ブロックと呼ばれる一定長の単位にまとめる。このとき、メモリのデータがキャッシュメモリのどの部分にあるのかを管理する方法には次の三つがある。

1.**ダイレクトマップ方式** 
メモリのアドレスごとにキャッシュメモリの格納場所が一つに決まる方式。メモリのアドレスから場所が特定できるため検索は容易だが、データの衝突が起こりやすい。

2.**フルアソシアティブ方式**
アドレスによる振り分けを行わず、キャッシュメモリの空いているブロックにデータを入れていく方式。データの衝突は起こらないが、データの使用時に毎回線形探索を行わなければならないため、応答速度に問題がある。

3.**セットアソシアティブ方式**
キャッシュメモリを複数のグループに分け、そのグループ内でフルアソシアティブ方式の様に空いているブロックを利用する方式。ダイレクトマップ方式とフルアソシアティブ方式の融合。

また、キャッシュメモリに書き込みが行われたときに、即時にメモリにも内容を転送する方式を**ライトスルー方式**、すぐには反映しない方式を**ライトバック方式**という。

##3.メモリインタリーブ
キャッシュメモリ以外に、CPUとメモリのデータ転送を高速化する技術にメモリインタリーブがある。データを複数のメモリバンクに分割して配置し、読みだすときは複数のメモリバンクに同時にアクセスすることによって、効率よくデータを取り出すことができる。

##4.管理方式
メモリのどの領域にどのデータを割り当てるのかを管理するアルゴリズムとして、代表的なものを二つ。アドレスの下位から順に検索して見つかった空き領域を割り当てる**ファーストフィット方式**、要求された大きさを満たす最小のものを割り当てる**ベストフィット方式**がある。

------
[ホームへ](https://qiita.com/k-y/items/dc2c9a3a8425712253e8)
Incoming WebhooksをOutgoing Webhooksから呼ぶことはできないという話

# 目的
あるチャンネルでポストした内容をそのまま別のチャンネルBでもポストする

# やったこと
Incoming WebhooksのAPIをOutgoing Webhooksで叩くようにした

# 期待する挙動
Outgoing Webhooksが拾ったテキストをIncoming Webhooksが吐き出す

# 実際の挙動
Incoming Webhooksがだんまり

# 原因
おそらくmimetypeの違い

* Outgoing Webhooksが送信するmimetype: `application/x-www-form-urlencoded`
* Incoming Webhooksが受信するmimetype: `applocation/json`

# 感想
両アプリのjsonのスキーマは一致していたので惜しい

```
{text: hoge}
```
GitHubでCC0のLICENSEファイルを自動生成する

GitHubにはLICENSEファイルの自動生成機能がありますが、現在CC0は選べません。
※以前は選べたようです
https://qiita.com/spiegel-im-spiegel/items/cc3d9cc46cc931b0e921

現在は著作権放棄のライセンスとして**Unlicense**を選べますが、Wikiを見る限りCC0の方が適切に思えます。
https://ja.wikipedia.org/wiki/Unlicense
<img width="970" alt="スクリーンショット 2019-01-17 13.00.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/142643/a50b7915-26ef-83ee-d3ac-c5add1595d88.png">


CC0を宣言したい場合はLICENSEファイルを自作する必要があると思っていましたが、GitHub上で自動生成する方法を知ったので共有します。

## 方法

とりあえずLICENSEファイル無しでリポジトリを作成する。

```
// 作成されたリポジトリのURL
https://github.com/<user>/<repo>
```

次に、リポジトリURLの末尾に`/community/license/new?branch=master&template=cc0-1.0`を付けてアクセス

```
// 例
https://github.com/<user>/<repo>/community/license/new?branch=master&template=cc0-1.0
```

するとCC0のテンプレートが反映されたLICENSEファイル作成ページが開くので、
<img width="1154" alt="スクリーンショット 2019-01-17 12.27.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/142643/ee122f4b-e3a0-bde3-b532-9d572133cb4b.png">
**Review and submit**ボタンを押してプルリク作成 & マージで完了です。
GitのコミットハッシュからGithubのプルリクエスト番号を取得する

## 概要

どうしてもshellscriptでGitのコミットハッシュから、Githubのプルリクエストの番号を取得する必要があった

## 前提

GithubのPersonal access tokenを事前に取得しておくこと
( https://github.com/settings/tokens/new から取得)
privateリポジトリの場合、 `Full control of private repositories` にチェックを入れないとうまくいかなかった

また、下記コマンドを使用するのであらかじめインストールしておくこと

- `curl`
- `jq`

## コード

```bash
pull_requests=(`curl -s -H "Authorization: Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}" "https://api.github.com/search/issues?q=repo%3A${GITHUB_USER_NAME}%2F${REPOSITORY_NAME}+is%3Apr+${GIT_COMMIT_HASH}" | jq ".items[].number"`)
```

で変数 `pull_requests` に配列でプルリクエストのIDが入る
あとはその配列をよしなに使う

## 解説

Githubの検索APIを使って、 `issues` をプルリク限定のみに絞り込んでコミットハッシュで検索している
( `+is%3Apr` の後に `+is%3Aopen`をつけて `open` なプルリクのみ検索とかも可能)
`curl` で叩くと

```json
{
  "total_count": 1,
  "incomplete_results": false,
  "items": [
    {
      "url": "https://api.github.com/repos/hoge/fuga/issues/1234",
      "repository_url": "https://api.github.com/repos/hoge/fuga",
      "labels_url": "https://api.github.com/repos/hoge/fuga/issues/1234/labels{/name}",
      "comments_url": "https://api.github.com/repos/hoge/fuga/issues/1234/comments",
      "events_url": "https://api.github.com/repos/hoge/fuga/issues/1234/events",
      "html_url": "https://github.com/hoge/fuga/pull/1234",
      "id": 123456789,
      "node_id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
      "number": 1234, # プルリクエスト番号
      "title": "P-Rタイトル",
      ...
      ...
      ...
    }
  ]
}
```
というような感じで、そのコミットハッシュが含まれるプルリクエストの情報が(存在すれば) `JSON` で返ってくるので、 `jq` コマンドで整形している
Rumaleで機械学習を試してみた

SVMKitはRumaleに改称されました。
[Rumale🦆チートシート](https://qiita.com/kojix2/items/069a45ebb1104ff4256c) をご覧ください


## Rumaleとは
Rubyで書かれた機械学習用のライブラリ。
https://github.com/yoshoku/Rumale

## インストール

```bash
gem install rumale
```

## データの準備

ここではirisのデータセットで分類を試す。

- label   `Numo::Int32#shape=[150]`
- samples `Numo::DFloat#shape=[150,4]`

```ruby
require 'rumale'
require 'daru'
require 'rdatasets'

# データセットの読み込み
iris = RDatasets.load(:datasets, :iris)
# Daru::DataFrame

# ラベルの準備 # Numo::Int32#shape=[150]
iris_labels = iris['Species'].to_a
encoder = Rumale::Preprocessing::LabelEncoder.new
labels = encoder.fit_transform(iris_labels) 

# 特徴量の準備 Numo::DFloat#shape=[150,4]
# (Daru -> NArray の変換はやや煩雑)
samples = Numo::DFloat[*iris[0..3].to_matrix.to_a]
```

## 分類モデル

* 公式リファレンス https://www.rubydoc.info/gems/rumale/

```ruby
# 線形SVM
model = Rumale::LinearModel::SVC.new(
  reg_param: 0.0001,
  fit_bias: true,
  max_iter: 3000,
  random_seed: 1
)
```

* いろいろ

```ruby
# 決定木
model = Rumale::Tree::DecisionTreeClassifier.new(random_seed: 1)
# ランダムフォレスト
model = Rumale::Ensemble::RandomForestClassifier.new(random_seed: 1)
# K近傍法
model = Rumale::NearestNeighbors::KNeighborsClassifier.new(n_neighbors: 5)
# ナイーブベイズ
model = Rumale::NaiveBayes::GaussianNB.new
```

# 検証する

```ruby
# KFold データセットの分割
kf = Rumale::ModelSelection::StratifiedKFold.new(
  n_splits: 5,
  random_seed: 1
)

# 交差検証
cv = Rumale::ModelSelection::CrossValidation.new(
  estimator: model,
  splitter: kf
)
report = cv.perform(samples, labels)

# 結果
scores = report[:test_score]
puts scores.sum / scores.size
# 0.9466666666666667
```

## 学習と予想

```ruby
# 学習させる
model.fit(samples, labels)

# 予想
# 引数は 2D NArray。ここでは Numo::DFloat#shape=[150,4]
p model.predict(samples).to_a
```

## モデルの保存、読み込み

```ruby
# モデルの保存
File.binwrite("model.dat", Marshal.dump(model))

# モデルの読み込み
model = Marshal.load(File.binread("model.dat"))
```

## 参考資料
* 洋食の日記 https://yoshoku.hatenablog.com/
* 公式リファレンス https://www.rubydoc.info/gems/rumale/
CMAKE_INSTALL_PREFIXの初期値を変更する

CMakeの変数`CMAKE_INSTALL_PREFIX`は実行時に引数で渡せば変更可能だが、デフォルト値を変えたい場合にどうするか、という話。

## 解決方法

`CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT`という変数を使う。
https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html

この変数はユーザによって`CMAKE_INSTALL_PREFIX`が変更されていない場合にTRUEになるため、以下のように利用するとデフォルト値を変えることができる。

```cmake
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX /path/to/default CACHE PATH "..." FORCE)
endif()
```

## ダメな例
### その1
以下のように書いた場合、`CMAKE_INSTALL_PREFIX`はそもそも定義済みなため、if文の条件を満たせない。

```cmake
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
  set(CMAKE_INSTALL_PREFIX /path/to/default CACHE PATH "..." FORCE)
endif()
```

### その2
間違ってはいないがUNIX系でしか動かない(Windows用の設定を書けばいいという話ではない)。

```cmake
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr/local")
  set(CMAKE_INSTALL_PREFIX /path/to/default CACHE PATH "..." FORCE)
endif()
```
Python Scheduleライブラリでジョブ実行

## アジェンダ

* はじめに
* ライブラリの紹介
* 利用例の紹介

## はじめに
スクレイピング等でPythonを定期実行させるために利用したライブラリがとても便利だったので紹介します。


### ライブラリの紹介
Pythonの定期実行には下記のライブラリを使いました。
[Scheduleライブラリ](https://schedule.readthedocs.io/en/stable/)
>Python job scheduling for humans.

> An in-process scheduler for periodic jobs that uses the builder pattern for configuration. Schedule lets you run Python functions (or any other callable) periodically at pre-determined intervals using a simple, human-friendly syntax.

人のためのPythonジョブスケジューリング

読みやすい構文を使い、Python関数や呼び出し可能オブジェクトを定期実行させることができます、とのこと。

### 使い方

```bash

pip install schedule
```

```python
import schedule
import time

def job():
    # 定期実行させたい処理
    print('Do Action')

def main():
    # 10分ごと
    schedule.every(10).minutes.do(job)
    
    # 2時間ごと
    schedule.every(2).hours.do(job)

    # 毎日10時
    schedule.every().day.at("10:00").do(job)

    # 毎週月曜日
    schedule.every().monday.do(job)

    while True:
        schedule.run_pending()
        time.sleep(1)
```



### 解説

```python
schedule.every(10).minutes.do(job)
```
``` schedule.every``` で定期実行するためのジョブをライブラリに登録しています。
登録したジョブは実行時間などを管理していますが、次に記載する``` shedule.run_pending ```が呼び出されるまで、ジョブは実行されません。

```python
while True:
    schedule.run_pending()
    time.sleep(1)
```
登録したジョブを実行させるための処理です。
schedule.run_pendingは登録したジョブを実行しますが、1回の呼び出しでは1回のジョブしか実行されません。
例えば、毎秒1回のジョブ```schedule.every(1).second().do(xx)```を用意したとしても``` schedule.run_pending() ```を1分に1回しか呼び出さない場合、そのジョブは1分間に1回しか動作しません。

上記のコードは無限ループでschedule.run_pending()を呼び出すようにしています。

　　
``` schedule.every().day.at("10:00").do(job) ```のような時間指定でジョブを実行させるコードは実行環境の時刻でジョブを開始します。タイムゾーン変換機能はないらしいのでご注意ください。

### まとめ
Pythonを定期的に動かすのにバッチを作ってタスクスケジューラに登録するしかないかなぁ、と思っていたのですが、Pythonで楽に書けるライブラリがあったので使ってみました。
手軽にジョブを設定できるので、かなり楽にシステムを動かすことが出来ました。
Windowsでのパケットキャプチャ（netsh使用版）

## Why?

業務で必要になったので調査して、ついでに手順をメモ。

## パケットキャプチャ

Windows上でのパケットキャプチャの方法です。
以前ならWiresharkとかいれないとダメでしたが、今は標準コマンドでもいけるみたいなので調べておきました。


## 準備

**Microsoft Message Analyzer**
キャプチャ結果を見るためのツールになります。ダウンロードしてインストールしておいてください。
https://www.microsoft.com/en-us/download/details.aspx?id=44226
MessageAnalyzer64.msi

**netsh**
キャプチャをするコマンドです。Windows標準で入っているコマンドなので何もしなくてもよいです。

## 手順

さっそくの手順です。

- コマンドプロンプトを管理者権限で起動します。
  右クリックして「管理者として実行」を選んで実行してください。
- コマンドプロンプトで下記実行します。

```
C:\Users\xxxx> netsh trace start capture=yes

トレース構成:
-------------------------------------------------------------------
ステータス:           実行中
トレース ファイル:    C:\Users\xxxxAppData\Local\Temp\NetTraces\NetTrace.etl
追加:                 オフ
循環:                 オン
最大サイズ:           250 MB
レポート:             オフ


C:\Users\xxxx> netsh trace stop
トレースを関連付けています... 完了
トレースの結合中... 完了
データ収集を生成しています ... 完了
トレース ファイルと追加のトラブルシューティング情報は、"C:\Users\xxxx\AppData\Local\Temp\NetTraces\NetTrace.cab"  としてコンパイルされました。
ファイルの場所 = C:\Users\xxxxx\AppData\Local\Temp\NetTraces\NetTrace.etl
トレース セッションは正常に停止しました。
```

- スタートメニューから`Microsoft Message Analyzer`を起動。 `File`メニューから先ほど作成された`........NetTrace.etl`を選択してください。キャプチャー結果の閲覧が可能です。

`netsh`のオプションで色々指定できますし、`Microsoft Message Analyzer`で、フィルタとかをかけることで色々見やすくなりますが、それはまた別の話。
クロスブラウザに対応したオートコンプリート付き入力フォーム

##前提条件
 - ユーザー名とパスワードのオートコンプリートではありません
 - 用語として、オートコンプリートを自動入力／自動補完／オートフィルと同じ意味で使っています
 - 2019/1/16時点の内容です
 - 検証したOSやブラウザのバージョンは一部です（IEやFirefoxは見ていない）

##オートコンプリートで頭に叩き込んでおくこと
 - **iOSのSafariはautocomplete属性に"nope"を指定しても自動入力は無効にできない**
 - **iOSのSafariはname属性で住所と推測できる項目があると連続して自動入力する**
 - **autocomplete属性を指定してもname属性の値によって挙動が変わる場合がある**
 - autocomplete属性の指定がなければname属性に含まれる文字列で判定される
 - 自動入力を無効にしたい場合はname属性をブラウザに推測されないようユニークな値にする
 - 特に都道府県と市区以降の住所は判定が複雑になっている

##成功パターン例

|項目|input type|autocomplete|autocorrect|autocapitalize|name|誤判定を避けるポイント|
|---|---|---|---|---|---|---|
|名前|text|name|||full_name|
|施設名|text||||shop|※nameに`name`を含む文字列を入れないこと
|メールアドレス|email|email||||
|電話番号|tel|tel|||tel|※nameに`number`を含む文字列を入れないこと
|郵便番号|number|postal-code||||
|町名・番地|text|address-line1|off|none|home_address1|`home_`が必要だった
|建物名・部屋番号|text||off|none|home_address2|`home_`が必要だった
|URL|url|url|||web_site_url|※nameに`address`を含む文字列を入れないこと
※都道府県と市区は試していません
※住所は並び順も影響します

##iOSのSafariで起きた不思議な出来事と仕様
・autocomplete属性に無効な値（"nope"など）を指定しても無視された
・建物名・部屋番号のautocomplete属性に"address-line2"を指定してもaddress-line1が入った
・住所のname属性をhome_address1とhome_address2から、address1とaddress2にすると建物名・部屋番号が空欄になった
・URLの項目のname属性をweb_site_addressにするとstreetaddressが自動入力された

##Chromeで起きた不思議な出来事と仕様
・電話番号の項目のnameにnumberを含めると先頭の0や国番号が消える（数値形式になるのかも）
・氏名の項目のnameにcontactを含めると先頭の文字が消える（理由は推測できなかった）
・AndroidのChromeで電話番号の保存時に国番号が自動的に補完される場合がある
・iOSのChromeは市区町村を保存できるが、AndroidのChromeは市区町村を保存できない

##まとめ
・name属性はSafariが大きな制約条件になるため、まずはSafariに合わせる
・name属性の値によってはChromeで先頭の文字列が消えるので注意する
・autocomplete属性は必須ではない

##その他
・Safariにおいてinput typeに"search"を指定しても、formのaction属性を設定していない場合は「改行」が「検索」にならない
Overleafでの日本語文書作成＆画像の挿入 備忘録

Overleafで卒論を書いてて日本語文書の作成，画像の挿入で躓いたのでメモ書き程度に残しておきます．

#最初にやったこと
[Overleaf v2 で日本語を使用する方法](http://doratex.hatenablog.jp/entry/20180503/1525338512)
を参考に`latexmkrc`ファイルを作成しコンパイラは`LaTeX`を使用していました．

しかし画像を入れようとしたらなぜか表示されない．
graphicxパッケージもちゃんと入れてる

なぜ？？？？

#解決法
結論から言えば最初に張ったリンク先に全部書いてありました．
途中経過は全部省きます．

1. コンパイラを`XeLaTeL`に変更
2. プリアンブルを`\documentclass[xelatex,ja=standard]{bxjsreport}`に変更
3. パッケージは`\usepackage[dvipdfmx]{graphicx}`

これだけです．ちなみに`XeLaTeX`の場会`latexmkrc`ファイルも不要です．

#教訓
文書は最後までしっかり読まないとダメですね．
斜め読み，ダメ，絶対（）
CentOS 7.4 の Emacs 上で ibus (xim) による入力ができない場合があることへの対処

# TL;DR

**DISCLAIMER: 不確定の情報もあるので，あくまで参考情報としてまとめています．**

- CentOS7 (Gnome Desktop) で，ibusによる日本語入力が基本的にできるようになったにもかかわらず，Emacs上では ibus (xim) による日本語入力が全くできないことが起こってしまった．
- 力技として，セッションが立ち上がるタイミングで `gdm` による `ibus-x11` プロセスを `kill` すると解決する場合がある．

```bash
# echo 'pkill -Ugdm ibus-x11' >> /etc/gdm/PreSession/Default
```

# 環境

- Windows 10 Pro (1803)
    - Vagrant 2.2.2
- CentOS 7.4 (bento/centos-7.4)
    - ibus-1.5.17-2.el7.x86_64
    - gdm-3.28.2-10.el7.x86_64
    - emacs-24.3-22.el7.x86_64

# Summary

- 現象
    - CentOS 7.4をインストールし，`GNOME Desktop`と`ibus-anthy`をインストールする
    - `gnome-terminal`等では日本語入力ができるが，`emacs`だけできない
    - 再現しないこともあるらしい
- 原因（と思われるもの）
    - ログイン画面（gdm）による `ibus-daemon` と，ログインしたユーザの `ibus-daemon` の2つが立ち上がっている
    - 参考：["ibus\-x11 \-\-kill\-daemon" dies without killing ibus\-daemon when I log out a desktop environment\. · Issue \#1907 · ibus/ibus](https://github.com/ibus/ibus/issues/1907)
    - `gdm` の `ibus-daemon` はログイン画面起動時に立ち上がり，ユーザログイン後には別のプロセスIDで立ち上がっている
    - `ibus-daemon` プロセスは，自身が行方不明の時に自動起動するようになっており，ユーザのログイン処理中に一度 gdm の `ibus-daemon` は落ちたものの，また立ち上がってしまっている？
        - `ibus-daemon` は `ibus-x11` が本当は落としてくれる？
- 場当たり的な対処
    - ユーザのログイン後に gdm による `ibus-daemon` を kill する
        - ただし，`ibus-x11`を`kill`すれば，それに合わせて落ちてくれる．
    - 場合によっては，ユーザの `ibus-daemon` を再起動する

```bash
$ sudo -ugdm pkill ibus-x11
$ ibus restart
```

# 未検証

- ibusを1.59以降にアップデートすればよいのでは？（パッチが1.59で取り込まれているっぽい）
exe/dllから .NET Frameworkのバージョンを確認する方法

ildasm.exe (IL 逆アセンブラー) を使用することで、exe/dllから.NET Frameworkのバージョンを確認することが可能です。

# ildasmで.NET Framework(CLR) のバージョンを確認する方法

以下の手順でCLRのバージョンが確認できます。

1. 「Visual Studio コマンドプロンプト」起動
1.  ildasm実行
1.  GUIが起動するので、exe/dllを読み込ませる。
1. 「MANIFEST」を表示する。
1. 先頭行のMetadataを参照 

> 例：
> // Metadata version: v4.0.30319

CLRのバージョンと.NET Frameworkのバージョンの対応は以下が参考になります。
https://blogs.msdn.microsoft.com/jpvsblog/2015/04/06/net-framework-3/

# dumpbin を使用して.NET Framework(CLR) のバージョンを確認する方法

WEB上には、dumpbinを使用して.NET Framework(CLR)のバージョンを確認するが紹介されている場合がありますが、dumpbinでは正しい.NET Frameworkのバージョンは確認できないようです。

> このツールで「ランタイムバージョン」と呼ばれているのは、実際にはランタイムバージョンではなく、それとほとんど関係がないです。それは誤称です。 dumpbinを使って実際のランタイムバージョンを表示することはできません。代わりに、ランタイムバージョンを「メタデータバージョン」として参照するildasmを使用できます。メタデータのバージョンはアセンブリのマニフェストにあります。 .NET 4.xの場合、ランタイムバージョンは4.0.30319です。

引用元:https://stackoverflow.com/questions/37011949/clr-runtime-version-from-clr-header
Angular 親コンポーネントから子コンポーネントにデータの渡し方

##親コンポーネントから子コンポーネントにデータを渡す方法

親コンポーネントから子コンポーネントにデータを渡す場合、「@Inputデコレーター」を使用し、プロパティに値を設定するします。

子コンポーネントで、「@Input」によりプロパティを作成し、親コンポーネントで、プロパティに値を設定します。

- 子コンポーネント Typescript

```
import { Input } from '@angular/core';

export class xxxComponent implements OnInit {
  @Input() プロパティ名 : string;
}
```

- 親コンポーネント テンプレート(HTML)
- 
```
<app-子コンポーネント [プロパティ名]="設定する値"></app-子コンポーネント>
```

###子コンポーネントから親コンポーネントにデータを渡す場合
「@Outputデコレーター」を使用し、親コンポーネントにイベントを通知し、イベント引数としてデータを渡すイメージとなります。

子コンポーネントで、「@Output」によりイベントを発生させ、親コンポーネントで、イベントおよびイベント引数を受け取ります。

- 子コンポーネント Typescript

```
import { Output } from '@angular/core';

export class xxxComponent implements OnInit {
  @Output() イベント名(xxEventとつけると分かりやすいです。) = new EventEmitter();

  searchClick(){
    // 単一のデータを渡す場合
    イベント名.emit(設定する値);
    // 例
　　searchEvent(searchedData);
    
    // 複数のデータを渡す場合
    イベント名.emit({
      戻り値のプロパティ名1:設定する値1,
      戻り値のプロパティ名2:設定する値2,
      戻り値のプロパティ名3:設定する値3,
    })
    // 例
　　searchEvent({
      A1: this.cmbA1.value,
      A2: this.cmbA2.value,
      A3: this.cmbA3.value
    });
  }
}
```

- 親コンポーネント テンプレート(HTML)

```

<app-子コンポーネント (イベント名)="イベント処理メソッド($event)"></app-子コンポーネント>
```

- 親コンポーネント Typescript

```
イベント処理メソッド(eventArgs){
  // 複数のデータが渡る場合
  let aaa = eventArgs;

  // 複数のデータが渡る場合
  let a1= eventArgs.a1;
  let a2 = eventArgs.a2;
  let a3 = eventArgs.a3;
}
```

どうでしょうか。これで親子コンポーネントのデータの受け渡しができるかと思います。
よろしければ、「いいね」をお願いします。励みになります。
Macのターミナルで若干時間かかるスクリプトを実行した時に終了時の通知がほしい

いろいろやり方はありそうだけど今回は`AppleScript`で。
シェルは`fish`です。
スクリプトは`Dropbox`内に置いて同期。


```alert.scpt
tell application "System Events" to display dialog "Finish terminal task" buttons { "ok" }
```

```~/.config/fish/config.fish
alias alert 'osascript ~/Dropbox/Apps/alert.scpt'
```

**なんか実行するとき**

```fish
ruby main.rb ; alert
```

![Screen Shot 2019-01-17 at 11.33.26.png](https://qiita-image-store.s3.amazonaws.com/0/34733/629e408c-ea2f-2777-53bc-532f3c4877d3.png)



**使わなかったけど便利そうなツール**
[GitHub - julienXX/terminal-notifier: Send User Notifications on macOS from the command-line.](https://github.com/julienXX/terminal-notifier)
[GitHub - vjeantet/alerter: Send User Alert Notification on Mac OS X 10.8 from the command-line.](https://github.com/vjeantet/alerter)
Googleカレンダーを集計して、今週どのぐらいジムに行ったかを教えてくれるSlack通知

# 理由
最近、ジムを始めました。会費が地味に高いので、どのぐらい通ったかを自動にカウントしたい。

# 必要な設定
- ジムのイベントがGoogleカレンダーに追加されていること
    - [Gmailに受信したFEELCYCLE予約完了メールからGoogleカレンダーにイベント追加するGASスクリプト]
(https://qiita.com/micciiii/items/3bbc8bd78f38018a292f)
- SlackでEmail受け取りの設定済み
    - [【超簡単５分】自分宛のbacklogの通知をSlackで受け取る方法] (https://qiita.com/Kathy/items/14749d2bdbf1f23f4012)

# イメージ
こんな感じで、毎週金曜に集計してくれる。
<img width="611" alt="Screen Shot 2019-01-17 at 11.08.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/343755/cda4e38e-0362-7939-b485-b2b51152c481.png">

# Script
テスト時はmain()関数を実行し、Trigger設定を含めて実装する時はinit()を実行。
`cal_name`, `gym_name`, `slack_email`を適宜変えてください

```
function init(){
  // Trigger every week
  ScriptApp.newTrigger('main').timeBased().everyWeeks(1).onWeekDay(ScriptApp.WeekDay.FRIDAY).atHour(10).create();
}

function main() {
  var cal_name = "Feelcycle";
  var gym_name = "Feelcycle";
  var slack_email = "xxxx@xxxx.slack.com";
  var end_date = new Date();
  var start_date = new Date(end_date.getTime());
  start_date.setDate(start_date.getDate() - 6);  // one week from now

  events = getEventsFromCal(cal_name, start_date, end_date);
  Logger.log("Fetched " + events.length + " events");
  
  content = createEmailBody(events, gym_name);
  Logger.log("content " + content);
  sendToMyself(slack_email, gym_name, content, start_date, end_date);
}

function getEventsFromCal(name, start, end) {
  var cal = CalendarApp.getCalendarsByName(name)[0];
  if (cal) {
    return cal.getEvents(start, end);
  } else {       
    Logger.log("カレンダーが見つかりませんでした: " + name);
  }
}

function formatDateStr(d){
  Logger.log(d);
  return d.getFullYear() + ("0" + (d.getMonth() + 1)).slice(-2) + ("0" + d.getDate()).slice(-2);
}

function sendToMyself(email_address, gym_name, content, start_date, end_date) {
  var startDateStr = formatDateStr(start_date);
  var endDateStr = formatDateStr(end_date);
  var fileName = gym_name + "_weekly_stats" + "_" + startDateStr + "_" + endDateStr
  GmailApp.createDraft(email_address, fileName, content).send();
}

function createEmailLine(i, event, gym_name){
  var title = event.getTitle();
  var startIdx = title.indexOf("]"); // parse event title
  var endIdx = title.indexOf("@");
  var realTitle = title.slice(startIdx + 1, endIdx);
  var date = event.getStartTime();
  var dateStr = date.toLocaleDateString();
  var str = (i+1) + ") " + dateStr + " - " + realTitle + "、" + gym_name + "に行ったね"
  
  return str
}

function createEmailBody(events, gym_name) {
  // loop through all events
    if (events.length > 0) {
      var body = "";
      for (var i = 0; i < events.length; i++) {
        var event = events[i];
        var str = createEmailLine(i, event, gym_name);
        if (i < events.length - 1) {
          body += str + "\r\n";
        }
        else {
          body += str;
        }
      }
      return body;
    } else {
      return gym_name + "に行ってないじゃん";
    }
}
```
[Qiita]コメント単位での通報方法

## 2019/07/13 追記
![20190714013240.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70638/d12a9459-6f03-8892-eb07-a7a26a9b0238.jpeg)

<font color="tomato">**ログイン中でも通報できるようになったようです！**</font>
@yama-t さん、情報ありがとうございました！

というわけでこの記事は御役御免となりましたが、一応記録ということで残しておきたいとおもいます。
以下はもう読まなくても大丈夫です。

---

## はじめに
普段はあまり出番のない話です。
まれにスパムっぽいコメントを見かけることはないでしょうか。記事単位の通報は簡単にできますが、コメント単位での通報はちょっと手順にクセがあったので記録を残しておきたいと思います。

## 手順
1. <font color="red">**ログアウト**</font> します。
2. コメントの横に通報ボタンが現れますので下記操作で通報できます。
![tuuhou.gif](https://qiita-image-store.s3.amazonaws.com/0/70638/9cd8ee73-9e81-f35d-ae09-44bfb051c226.gif)
3. おわり。

## 追加情報
ログアウトするのが億劫な場合は、シークレットウィンドウや別ブラウザを使うとログアウトしなくて済みます。
(@sax_ さん、コメントありがとうございました。)

## 最後に
ログインしたまま通報できれば一番いいんですけど、なんでこういう仕様なんでしょうね。Qiita の問い合わせフォームから意見を送信はしておきましたが、何らかの理由があってこうせざるをえないのかもしれないので、もしコメントの通報が必要な場合はひとまずはこの方法を参考にしてください。

(ちなみにヘルプ等探したんですがコメント単位での通報については見つかりませんでした。どこかに載ってるんでしょうかね？もしご存知の方いらっしゃいましたらコメントください。)
Google Cloud Platform 2つの料金無料枠

# 序文

今回は、自分の健忘の為にGCPの無料枠の詳細の説明をしたいと思います。
先月まで、月に700円程サーバ代が課金されていたのですが、
無料枠の情報を知ったため、共有がてら記載していきます。
(2019/1/17時点での情報です。今後利用規約が変更になる可能性があるのでそこは考慮お願いします)

参考ドキュメント：
<a href="https://cloud.google.com/free/docs/frequently-asked-questions">[Google Cloud Platform の無料枠]</a>
<a href="https://cloud.google.com/free/docs/always-free-usage-limits">[Always Free の使用制限]</a>

# 無料トライアル

クレジットカード登録(請求アカウントの作成)から、12か月間、$300相当のクレジットをもらえます。
GCPのサービスならほとんど利用が可能ですが一部例外があります。
また、Googleの無料APIでも利用が可能なようです。
無料トライアルとAlways Freeは併用できます。

## 無料トライアル対象外一覧


* プロジェクトで同時に実行できるコア（または仮想 CPU）は 8 つまでです。

→n1-standard-8、n1-highmem-8、n1-highcpu-8以下であればOKっぽい？
　マシンタイプで末尾が8以下のタイプを選べばOK。

* Compute Engine インスタンスに GPU を追加することはできません。

→NVIDIA® Tesla®とかは使えない。

* プリエンプティブ VM インスタンスは無料トライアルには含まれません。

→プリエンプティブ VM：24時間しか使えないバッチ処理とかする用の仮想マシン
　これも使えない。

* 割り当ての増加をリクエストすることはできません。

→急激にアクセスが増えたときの割り当ての増加が利用できない

* Cloud TPU は、Always Free プログラムの一部ではありません。

→TPUは利用できない。(機械学習系のCPUっぽい)

* Google Cloud Platform サービスを使用して暗号通貨を利用することはできません。

→そりゃそうだ！無料枠使って採掘してウハウハは無いよね…

## 無料トライアルで料金は発生するのか(実際登録したクレジットカードに請求が来る？)

基本的には無料トライアルの期間中ではない模様。
ただし、クレカの承認手続きによって、1ドルくらいの請求が来るが、
取り消しされるので問題なし。
そもそも、無料で使うのにクレジットカードの登録が必要なのは身元証明(Botの対策)とのこと。

## 無料期間終了後即座に課金されるとかないよね…？

有料アカウントにアップグレードしなければ、クレジットカードに料金が請求されることはありません。
→有効期限切れか、クレジットをすべて使い切った場合、インスタンスが即座にすべて止まるらしい

## 具体的に無料枠でどういうことができるの？

タダでサーバーいっぱい立てれる！
他、ビッグデータ連携とかもできるよ！

---------------------------------------------------

# Always Free

無料トライアルが終了した後でも、*条件付き*で引き続き無料でGCPを利用できる制度です。
実はここからが本題。
*運が良ければ*月あたり無料でサーバーを運営できるかも。

## Always Free の使用要件

* Google とカスタムの契約や料金体系を締結していない。

→特別な契約をGoogleとしていないことが条件

* アップグレードした請求先アカウントを持っている。

→クレジットカードへの課金を開始していることが条件
　(Always Freeの対象以外のものを利用したら即座に料金が加算されるので注意！)

* アカウントが良好な状態である。

→たぶん悪いことしていなければいい。

## Always Free の条件(GCEに限って記載)

### 利用可能なリージョン

| 地域 | リージョン名 |
|:-----------|:------------|
| 米国東部(サウスカロライナ)| us-east1|
|米国西部(オレゴン)|us-west1|
|米国中央部(アイオワ)|us-central1|

### 利用可能なインスタンス

・f1-micro(仮想CPU:1、メモリ:0.60GB)

→仮想マシンを作成するときの最低のインスタンスです。

### 利用可能なHDD＋スナップショット

・30 GB の HDD（期間合計）、5 GB のスナップショット（期間合計）

### 無料対象のネットワークトラフィック

・1 GB の北米から全リージョン宛て下りネットワーク（1 か月あたり、中国およびオーストラリアを除く）

→ここが完全無料にするにあたって一番のネックだと思います。

### 利用不可なライセンス

・プレミアム OS ライセンスや、Cloud Marketplace。

→WindowsServerとかは使っちゃダメっぽい(そりゃそうだ)

### Always Freeを利用するにあたっての豆知識

<a href="https://cloud.google.com/billing/docs/how-to/budgets">予算とアラート</a>に行き、
「予算を作成」を押して、一定額を超えるとメールで通知してもらうと吉。
(ただしリアルタイムではないのでその点注意が必要です)

# 終わりに

非常に雑多にまとめただけなので、もっと詳細に知りたい方は、
序文の参考ドキュメントを参考にしてください。

GCE以外のAlways Freeについては、以下ドキュメントを参考にしてください。
<a href="https://cloud.google.com/free/docs/always-free-usage-limits">[Always Free の使用制限]</a>
Dockerfile : COPY対象のファイルの存在が不確定の場合への対応

同一コンテナでもデプロイ環境が異なると、confファイルが異なったり、存在しなかったりする。
confファイルがあってもなくても、同一のdockerfileでbuildしたい。
COPY対象ファイルが存在しない場合でも問題なくdocker buildする方法を調べた時のメモ。

## COPY対象ファイルがない場合のdocker build
COPY対象ファイルsample.confが存在しない場合の例

![dockerCOPYdirectory.png](https://qiita-image-store.s3.amazonaws.com/0/105178/3674ecb6-8b32-a793-f9f0-800f3de58b02.png)


```test:Dockerfile
FROM amazonlinux
COPY sample.conf /etc/
CMD ["cat", "/etc/sample.conf"]
```

実行結果
![dockerCOPY001.png](https://qiita-image-store.s3.amazonaws.com/0/105178/1b4e3d46-5c8c-e3f4-f61e-e41051fc2b16.png)

## 対応
COPY対象として、必ず存在するファイルを１つ指定。サンプルではDockerfile。
存在が不確定なファイルはワイルドカードで指定。

```text:Dockerfile
FROM amazonlinux
COPY Dockerfile sample.conf* /etc/
CMD ["cat", "/etc/sample.conf"]
```

実行結果
![dockerCOPY002.png](https://qiita-image-store.s3.amazonaws.com/0/105178/a746e24d-fc7e-fd95-b3ce-cd4e69fc41c1.png)

Dockerfileはコピーされてしまうので、必要であれば削除するなどの後処理を追加する。

## 参考

ワイルドカードなしの場合もエラーになる

```text:Dockerfile
FROM amazonlinux
COPY Dockerfile sample.conf /etc/
CMD ["cat", "/etc/sample.conf"]
```

![dockerCOPY003.png](https://qiita-image-store.s3.amazonaws.com/0/105178/a5205e92-d027-5381-7e85-4baf1fb4ea27.png)

ワイルドカードのみの場合もエラーになる

```text:Dockerfile
FROM amazonlinux
COPY sample.conf* /etc/
CMD ["cat", "/etc/sample.conf"]
```

![dockerCOPY004.png](https://qiita-image-store.s3.amazonaws.com/0/105178/a803fdab-7fca-ac35-3537-bf804e2bba13.png)
JavaFlightRecorderでheapの使用状況を確認する

やりたかったことは、jcmdを利用してjfrファイルをWebアプリケーションサーバで取得し、開発用の自分のPC(Windows)のjmcでheapの使用状況を確認する、ことでした。

# 基本情報

* 執筆：2019/1/17
* OS:RHEL7.4
* Java1.8

# 結論（解決に時間がかかったところ）

jfrファイルにheapの利用状況データを記録するためにはプロファイルを修正し、jcmdのsettingsパラメータとして渡す必要がある。（探し方が悪かったのか、辿り着くのにかなり時間がかかった。）

# 手順
### １．プロファイルの修正
以下に2種類のプロファイルが格納されています。

```
$ cd [JDK_PATH]/jre/lib/jfr
$ ll
-rw-r--r-- 1 root root 20109 10月  6 22:55 default.jfc
-rw-r--r-- 1 root root 20065 10月  6 22:55 profile.jfc
```

profile.jfcをコピーし（myProfile.jfc）、heapのデータ記録に関すると思われる部分を有効化します。この辺りのリファレンスが見つけられなかったため、これは正しいかは定かではありません。（が、一応動きます。）

```
<!-- 127行目あたり、falseからtrueへ -->
<flag name="heap-statistics-enabled" label="Heap Statistics">true</flag>

<!-- 268行目あたり、falseからtrueへ -->
    <event path="vm/gc/detailed/object_count">
      <setting name="enabled" control="heap-statistics-enabled">true</setting>
      <setting name="period">everyChunk</setting>
    </event>
```

### ２．jfrファイルの取得
詳細情報は割愛しますが、ポイントはsettingsパラメータで先に作成したプロファイルを指定するところです。

```
jcmd [PID] JFR.start name=MyJfrRec settings=myProfile maxsize=100mb dumponexit=true filename=/tmp/myJfrRec.jfr
```

記録状況のチェック

```
jcmd [PID] JFR.check
```

記録情報のダンプ

```
jcmd [PID] JFR.dump name=MyJfrRec filename=/tmp/mytasrec.jfr
```

記録の終了

```
jcmd [PID] JFR.stop name=MyJfrRec
```

あとは、取得されるjfrファイルをjmcに読み込ませれば良い感じでグラフが出てくれると思います。

【参考にさせて頂いたサイト】
http://waysaku.hatenablog.com/entry/2014/07/22/005304
https://blogs.oracle.com/poonam/clarifying-some-confusion-around-java-flight-recordings

弊社ではエンジニアを募集中です。こちらも見て頂けると嬉しいです。
https://www.nittsu-infosys.com/recruit/2019/index.html
JAVA DB接続方法

#JAVAでDBに接続するコードのメモ

完全に理解していないのでここから理解を深めていく。

```java
public static void main(String[] args) {
		//DB接続
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			Class.forName("org.postgresql.Driver");
			conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/DB名",
					"ユーザー",
					"パスワード"
					);
			//SQL文を定義する
	        String sql = "INSERT INTO テーブル名(●, ●, ●) values(?,?,?)";
			ps = conn.prepareStatement(sql);
			conn.close();
			System.out.println("DBに接続しました。");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("失敗しました。");
		}
		launch();
	}
```
Cloud FunctionsにGoがサポートされたので使ってみた

GCPのCloud Functionsでgolangがサポートされました。
[Cloud Functions: Go 1.11 is now a supported language | Google Cloud Blog](https://cloud.google.com/blog/products/application-development/cloud-functions-go-1-11-is-now-a-supported-language)

さっそく使ってみたいと思います。

## 導入
gcloudが必要なので[インストール](https://cloud.google.com/sdk/docs/)しておきます。
また現在Golangのサポートはベータなので、gcloudでベータ機能を使えるようにしておきます。

```shell-session
$ gcloud components update
$ gcloud components install beta
```

今回作るサンプルのプロジェクトを作成します。

```shell-session
$ mkdir sample-cloudfunctions-go && cd sample-cloudfunctions-go
```

Cloud Functionsでgolangを使う場合、[Go Modules](https://github.com/golang/go/wiki/Modules)が必要です。
golang1.11では環境変数で宣言が必要です。

```shell-session
$ export GO111MODULE=on
$ # 以下コマンドでgo.modファイルが作成される
$ go mod init
```


サンプルの関数を作ります。

```golang:function.go
package sample

import "net/http"

func Hello(w http.ResponseWriter, r *http.Request) {
    msg := "Hello World"
    w.Write([]byte((msg)))
}
```

デプロイします。

```shell-session
$ gcloud functions deploy Hello --runtime go111 --trigger-http
# 以下一部抜粋
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
entryPoint: Hello
httpsTrigger:
  url: https://us-central1-xxxxxxxxx.cloudfunctions.net/Hello
labels:
  deployment-tool: cli-gcloud
name: projects/xxxxxxxxx/locations/us-central1/functions/Hello
runtime: go111
status: ACTIVE
timeout: 60s
updateTime: '2019-01-17T00:28:43Z'
versionId: '1'
```

トリガーするURLが出力されるので叩いてみると・・・

```shell-session
$ curl https://us-central1-xxxxxxxxx.cloudfunctions.net/Hello
Hello World
```

実行できました！

## 所感
`net/http` を使ってるのでとてもシンプルです。
どこかでmain関数を定義すればローカルでも実行できるため開発しやすいです。

```golang:cmd/main.go
package main

import (
    sample "github.com/morix1500/sample-cloudfunctions-go"
    "net/http"
)

func main() {
    http.HandleFunc("/hello", sample.Hello)
    http.ListenAndServe(":8082", nil)
}
```

```shell-session
$ echo "module github.com/morix1500/sample-cloudfunctions-go" > go.mod
$ go run cmd/main.go
$ curl localhost:8082/hello
Hello World
```

## 参考資料
[The Go Runtime](https://cloud.google.com/functions/docs/concepts/go-runtime)
Slackのアイコン変更されたメモ

今日ブラウザを見てみたら、Slackのアイコン変わってました…！
ちょうど、新旧いろんなファビコンが残ったままの状態になっているので記念に残しておきます笑


![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/200222/f9fc5743-7cb7-1ea7-8b6a-92b0719e762d.jpeg)


http://www.itmedia.co.jp/news/articles/1901/17/news051.html

これまでは確かに統一性はなかったですねぇ。
共通でドンっと同じアイコンが並ぶようにするべき、という考え方は参考になりますね。
Storybook (Vue) で Vuetify を使う際にアイコン（<v-icon>）が表示されない件




## 現象

アイコンが表示されてほしいが、文字列だけになってしまう。

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/b45f86c9-2483-16fb-b03c-85368fec32b2.png)


## 対策

### フォントへの参照が無いのが原因の場合

`.storybook/preview-head.html` に以下を追加

```html:.storybook/preview-head.html
<link
  href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
  rel="stylesheet"
/>
```

### IEの場合

 @font-face で不明のエラーが出るようです。
 
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/4196cffe-9c35-66f2-d017-c20d239e1532.png)

WebFontに対応してなさげなので、別途対応が必要です。

[IEでWebフォントを表示させる | demodemo - Webデザイン/アプリ開発/フロトエンド開発のスキルデモ](http://neromiu.net/demodemo/cording/ie-webfont-eot/)

[IE11 not showing font awesome icons · Issue #8825 · FortAwesome/Font-Awesome](https://github.com/FortAwesome/Font-Awesome/issues/8825#issuecomment-365918464)


## 結果

無事、アイコンが表示されました。

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/227858d5-8331-f7d0-6931-ae1ba276fcaa.png)



## リンク

[Icon Component — Vuetify.js](https://vuetifyjs.com/ja/components/icons)
Angularの良く使うコマンド一覧

Angularの良く使うコマンド一覧を載せてみました。

###Angularコマンド一覧

|内容|コマンド|備考|
|:----------------------|:-------------------------------------|:------------------------------|
|プロジェクト新規作成|ng new **プロジェクト名** --style=scss|プロジェクト作成時に聞かれます。とりあえずこれがいいと思います。Angular routing?：Yes、Which stylesheet：scss|
|モジュール新規作成|ng g m **モジュール名** --routing|事前に「cd」コマンドでディレクトリを移動すること|
|コンポーネント新規作成|ng g c **コンポーネント名**|事前に「cd」コマンドでディレクトリを移動すること|
|サービス新規作成|ng g s **サービス名**|事前に「cd」コマンドでディレクトリを移動すること|
|アプリ実行|ng s -o|「s」は「serve」の略　「-o」は「open」の略で実行後にブラウザを開いてくれます。|
|アプリ実行|ng s -o --port 8888|オプションの「port」はポート番号変更しての実行|
|実行の停止|Ctrl+C → y||
|アプリリリースビルド|ng build --prod||
|Gitから新規取得後のパッケージのインストール|npm install||
|ng serveをiPadで表示|ng s --host **自分のIP**|iPadから「**自分のIP**:4200」で接続可能|

皆さんの参考にしていただければ幸いです。
javaDocをwordファイルに出力

参照元
https://www.csync.net/blog/pc/docxdoclet/

cmdにコマンドでjarファイルを行って、wordファイルを出力する。


コマンド様式：
javadoc.exe -private -encoding utf-8 -doclet doclet.docx.DocxDoclet -docletpath docxdoclet-1.0.jar -classpath docxdoclet-1.0.jar -sourcepath ソースファイルのパス -file 出力ファイル.docx -font1 "Meiryo UI" -font2 "Consolas" -title 題名 -subtitle 題名の補足 -version バージョン -company 発行者 -copyright 著作権フッタ表示 パッケージ名

コマンドサンプル：
javadoc.exe -private -encoding utf-8 -doclet doclet.docx.DocxDoclet -docletpath C:\docxdoclet-1.0.jar -classpath  C:\docxdoclet-1.0.jar -sourcepath C:\workspace\sampleproject\src\ -file C:\出力ファイル.docx -font1 "Meiryo UI" -font2 "Consolas" -title サンプルシステム -subtitle サブシステム名 -version バージョン1.0 -company 発行者 -copyright "Copyright c 2019 licb All Rights Reserved." C:workspace\...log4j\*.java


※javaDocに<br/>とか改行しない場合、。は改行した場合、下記のソース修正要
DocumentBuilder.javaのprintメソッド510行目下記のソース追加すればいい
javaファイルは参照元にダウンロードして、修正後、jarファイルの拡張子をzipに変更して、差し替えていいです。

			// 行ごとに改行を挿入
			// update start
//			paragraphs[i] = paragraphs[i].replaceAll("\\.\\s+", ".\n");
//			paragraphs[i] = paragraphs[i].replaceAll("。\\s*", "。\n");
			paragraphs[i] = paragraphs[i].replaceAll("<br>", "\n");
			paragraphs[i] = paragraphs[i].replaceAll("<br/>", "\n");
			paragraphs[i] = paragraphs[i].replaceAll("<p/>", "\n\n");
			// update   end
deoplete.nvim用にVim8をインストールする

[deoplete.nvim](https://github.com/Shougo/deoplete.nvim)を使いたかったので[requirements](https://github.com/Shougo/deoplete.nvim#requirements)を満たす必要がありました。
Amazon Linuxで試したときの手順です。

## pyenvとvimのソースを取得するためにgitをインストールする

```bash
$ sudo yum install -y git
```

## pyenvをインストールしてbashの設定を変更する

```bash
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

## python2と3をpyenvでインストールする

```bash
$ sudo yum install -y readline-devel bzip2-devel openssl-devel sqlite-devel patch gcc
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.6
$ CONFIGURE_OPTS="--enable-shared" pyenv install 2.7.9
$ pyenv global 2.7.9 3.6.6
$ pyenv rehash
```

pythonのライブラリをVimと共有するために`--enable-shared`オプションが必要です。

## Pythonのneovim用クライアントとgreenletをインストールする

```bash
$ pip3 install neovim
$ pip3 uninstall -y greenlet
$ pip3 install greenlet --no-binary :all:
```

neovimの依存関係でついてくるgreenletをpip3で普通にインストールするとどうやら非互換のバイナリファイルが含まれてしまうみたいだったので`--no-binary :all:`オプションを付けて再インストールします。

## vimをソースコードからインストールする

今回はユーザーのホームディレクトリ以下にインストールしました。

```bash
$ mkdir -p ~/local/src
$ git clone --depth 1 https://github.com/vim/vim ~/local/src/vim
$ cd ~/local/src/vim/src
$ LDFLAGS="-Wl,-rpath=${HOME}/.pyenv/versions/2.7.9/lib:${HOME}/.pyenv/versions/3.6.6/lib"   ./configure --prefix=$HOME/local/vim --enable-luainterp=yes --enable-python3interp=yes --enable-pythoninterp=yes --enable-gui=no --enable-multibyte
$ make
$ make install
$ echo 'export PATH="$HOME/local/vim/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ vim --version
```

pythonのライブラリとリンクするためにvimをLDFLAGS変数付きでインストールしました。

以上です。

本記事の[英語版](https://nabewata07.com/posts/vim8-enabled-python3-for-deoplete-nvim/)
よく使うInteliJショートカット

よく見直すので最低限使うものをメモ(ボタンにカーソル合わせれば分かるけど。)

- なんでも検索
  - shift2回
- ファイル名頭出しカーソル移動
  - ディレクトリクリックし、ファイル名文字入力
- ファイル検索
  - Command + Shift + O
- 関数ジャンプ
  - Command + B
- 行ジャンプ
  - Command + L
- 階層呼び出し
  - Alt + fn + F7
- クラス内のアウトライン表示
  - Command + fn + F12
- project structure
  - Command + ;
- ファイルパスコピー
  - Command + Shift + C
- 全文検索
  - Command + Shift + F
- ジャンプ前に戻る
  - Command + option + ←
- ジャンプ後に戻る
  - Command + option + →
- 一括置換
  - shift + fn + F6 
- 行複製
  - Command + D 
- 行削除
  - Command + delete  
- 大文字小文字切り替え
  - Command + Shift + U
進捗管理入門

#進捗管理とは
進捗・・・物事が進みはかどること

なので、単に進捗が上がっている状態を管理するのではなく、良い状態＝捗っている状態を管理していくことである。

#進捗管理ができないのはなぜか
・急なタスクが割り込んだ
・スケジュールが管理されていない
・作業範囲が不明確
　→だれが何をどこまでやるのか
・メンバーから想定を下回る品質のものがでてくる。

これらだけでなく、もう少し上位でみてみる。
・計画段階で抜けもれがあった
・時間(納期)の見積もりが甘い
・ゴールのイメージすり合わせがメンバー間でできていない
　→情報の共有不足
・遅延対策が適切でない

それをふまえた進捗管理とは

仕事が進んでいるいい状態を保つように取り仕切ること


#タスク(納期)の見積もり方法
基本的には以下となる

悲観時間ー期待時間＝バッファ

見積もりに関しては社内の有識者に聞いてしまうのが早い(ナレッジ管理)


##「進捗率90%です」と言われたら
残りの10%がどのような状況なのかをヒアリング
・あと10%が一番重いタスクが残っている
・課長の承認待ちの状態
・ヒアリング内容が返ってこないと対応できない
などなど

なので、進捗率計測は以下を確認するとよい
・終わっているor終わっていない
・マイルストーンでの重みづけ
・あと何日で完了予定か

#今後のために
・進捗管理の時には、「あとどれくらい残っていて」「あと何日で終わるのか」を確認する。
・今後のPJ管理用にガントチャートとタスク管理が行える管理表のテンプレを作成する(1月末まで)
php-master-changes 2019-01-16

今日は型付プロパティ関連の実装修正と最適化があった！

# 2019-01-16
## dstogov: Fixed uninitialized result of PRE_INC/PRE_DEC in case of exception.
- https://github.com/php/php-src/commit/239305d12ee1f6d3fbfef72d2cfead9bb97141ef
- 型付プロパティの参照を前置インクリメント/デクリメントが例外になる際に uninitialized の結果になる問題の修正、かな
- 型付参照のインクリメント/デクリメントを zend_incdec_typed_ref() に関数分離

## dstogov: Separated zend_binary_assign_op_typed_ref() and zend_binary_assign_op_typed_prop() helpers
- https://github.com/php/php-src/commit/938ba93f4a76db49e2bb43d0aaa33ca4772be2d3
- zend_binary_assign_op_typed_ref() と zend_binary_assign_op_typed_prop() を関数分離

## dstogov: Reuse zend_incdec_typed_ref() and separate zend_incdec_typed_prop()
- https://github.com/php/php-src/commit/a5446cc01c1ef72f807636d0afdd415dd259adc9
- zend_incdec_typed_ref() の再利用箇所を足して zend_incdec_typed_prop() の関数分離

## weltling: Fix param list for build without global reg
- https://github.com/php/php-src/commit/cd43a4629fcb57d7ef4cecd6b4ad9390f1df3992
- zend_binary_assign_op_typed_ref() と zend_binary_assign_op_typed_prop() の引数に EXECUTE_DATA_CC を追加

## dstogov: Separated zend_assign_to_typed_prop()
- https://github.com/php/php-src/commit/0b21a4ba4513d89474e09363b8675498064bb52f
- 型付プロパティへの代入処理を zend_assign_to_typed_prop() に関数分離

## dstogov: Fixed and improved incorrect usage of value_type argument.
- https://github.com/php/php-src/commit/fd27fd4a150125e6c91842e439fe18113ec3db62
- zend_wrong_assign_to_variable_reference() の value_type の誤った利用を修正

## dstogov: Fixed tests
- https://github.com/php/php-src/commit/cbfb3f3fff4bf2602f6fe2c908d2eff0812d2edb
- 型付プロパティ関連のテストの期待出力を修正

## dstogov: Extend zend_get_property_offset() to return property_info for typed properties.
- https://github.com/php/php-src/commit/9f05f64240d21b2c2f9a28876214e909f5208c68
- 型付プロパティ用に zend_get_property_offset() が property_info を引数経由で返すよう修正

## dstogov: Micro-optimization
- https://github.com/php/php-src/commit/44f4370880680c1f6e914c3577900f70a6453e88
- zend_get_property_offset() の実装の局所最適化

## dstogov: Reduce slow code size
- https://github.com/php/php-src/commit/8661b6dd5db6135f3b5c7562ac3e25613d7981e6
- UNEXPECTED なコードのコードサイズを削減
データサイエンティストのスキルレベル ～検定／判断～

# はじめに

標題の通り、どんなスキルレベルがあるのか確認
https://www.datascientist.or.jp/common/docs/skillcheck.pdf

統計数理基礎；
https://qiita.com/iwasaki_kenichi/items/25d55bcd872121b1015c

予測；
https://qiita.com/iwasaki_kenichi/items/3c2755e0b29669c11fbe


# 検定／判断
|No|スキルカテゴリ|スキルレベル|サブカテゴリ|データサイエンス力：チェック項目|必須スキル|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1  |検定/判断| ★  | 検定/判断| 点推定・区間推定の意味を理解している| |
|2  |検定/判断| ★  | 検定/判断| 帰無仮説・対立仮説の意味を理解している| ◯|
|3  |検定/判断| ★  | 検定/判断| 第1種の過誤、第2種の過誤、p値、有意水準の意味を理解している| |
|4  |検定/判断| ★  | 検定/判断| 片側検定、両側検定の意味を理解している| |
|5  |検定/判断| ★  | 検定/判断| 対応のあるデータ、対応のないデータの意味を理解している| |
|6  |検定/判断| ★  | 検定/判断| 平均値、分散、平均値の差の検定手法を知っている| |
|7  |検定/判断| ★★| 検定/判断| t検定を理解して、パラメトリックな2群の検定を活用することができる| ◯| |
|8  |検定/判断| ★★| 検定/判断| 様々な分散分析の考え方（一元配置、多重比較、二元配置）を理解して、パラメトリックな多群の検定を活用することができる| |
|9  |検定/判断| ★★| 検定/判断| ウィルコクソン検定（マンホイットニーのU検定）を理解して、ノンパラメトリックな2群の検定を活用することができる| |
|10 |検定/判断| ★★| 検定/判断| クラスカル・ウォリス検定を理解して、ノンパラメトリックな多群の検定を活用することができる| |
|11 |検定/判断| ★★| 検定/判断| カイ二乗検定、フィッシャーの直接確率検定を理解して、分割表における群間の関連性の検定を活用することができる| |


# おわりに
検定／判断は、2番目の帰無仮説・対立仮説の理解が必須であるのと、と7番目のt検定とパラメトリック検定を活用するのが必須項目でした。
大学の教養科目で習いましたが、ほとんど覚えていないですね。

帰無仮説・対立仮説は下記サイトがわかりやすいです。
https://to-kei.net/hypothesis-testing/about-2/
既存のファイルを空にするLinuxコマンド

```bash
$ : > hoge.txt
```

`echo '' > hoge.txt`だと空文字に1B使うので気持ち悪い（というか空になっていない）。

と社内のWikiに書いたところコメントで大喜利が始まったので載せておきます。

## /dev/nullをコピーする

```bash
$ cp /dev/null hoge.txt
```

なるほど、nullをコピーするのか。

## `rm`と`touch`をつなげる

```bash
$ rm hoge.txt && touch hoge.txt
```

これはもはや。。と思いましたが

> Explicit is better than implicitな思想の人は好きそうですね
(パーミッション気にかけないと初期化されますが)

という意見も寄せられました。
確かに明示的なので見たら何やってるのかすぐわかります。

## `sed`の`d`コマンドで中身を削除する

```bash
$ sed -i '' -e 'd' hoge.txt
# macだと上書き保存のときにバックアップの拡張子指定がいるので、空っぽにするとバックアップを作らない
```

## truncateコマンド

> gnuにまさしくそのためのソフトウェアであるtruncateがあります
https://linuxjm.osdn.jp/html/GNU_coreutils/man1/truncate.1.html

上記のようなコメントもいただきました。
コマンドとしては下記です。

```bash
$ truncate hoge.txt --size 0
```

## `echo`の`-n`オプションで空行の末尾の改行を省略する

```bash
$ echo -n > hoge.txt
```

以上です。

こうやってたくさんコメントを貰えるのはとても参考になりますしありがたいです。
DynamoDB Localに登録したテーブルがほかのプログラムから見えないときに読むやつ

DynamoDB LocalをDockerで起動して、AWS CLIでテーブルを作って、いざプログラムからデータを入れようとしたらテーブルが無いといって怒られる、ということに遭遇したのでその解決策をば。

## 原因
DynamoDB LocalのテーブルはアクセスキーID/リージョンごとに管理されているから。
ローカルで動いてるからアカウントもリージョンも関係ないだろと思ってたけど、ちゃんと区別してるんですね。
具体的には、`[アクセスキーID]_[リージョン].db`という名前のデータベースファイルで管理されているそうです。

ちなみに、指定するアクセスキーIDとリージョンは適当な文字列で大丈夫です。

## 解決策
### アクセスキーIDとリージョンを揃える
素直な解決策ですが、AWS CLIでテーブルを作るときに使うアクセスキーIDとリージョンを、プログラムで使用しているものと合わせる方法です。

```
$ AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXABCD AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXABCD  AWS_DEFAULT_REGION=ap-northeast-1 aws --endpoint-url http://127.0.0.1:8000 dynamodb create-table --table-name example-table ...(略)
```

### -sharedDbオプションを指定する
デフォルトだとアクセスキーIDとリージョンごとにデータベースファイルを作りますが、-sharedDb オプションを使用すると、DynamoDB は `shared-local-instance.db` という名前の単一のデータベースファイルでデータを管理します。
つまり、アクセスキーIDやリージョン関係なく、必ず同じデータベースファイルを参照します。

具体的には、以下のコマンドでdockerコンテナを実行すればOKです。

```
$ docker run -d -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -dbPath . -sharedDb
```
`-jar DynamoDBLocal.jar -dbPath .`はデフォルトのコマンドです。
それに`-sharedDb`をくっつけています。

いろいろ設定する必要がなくなって便利ですが、複数アプリケーションからDynamoDB Localを利用する場合はデータベースの情報が混ざるので注意が必要です。
一つのアプリケーションからしか使わない場合はとても便利ですね。

## おまけ
`http://localhost:8000/shell/`にアクセスすると、DynamoDB Web Shellが使えます。
JavaScript SDKのDynamoDB関連のプログラムを試せます。各操作のテンプレートも用意されているので、JS使うなら入門にいいかも？
<img width="1287" alt="スクリーンショット 2019-01-13 10.32.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/39565/c2d630d0-9f77-4e3b-4140-20c607b9a45e.png">

## 参考
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html
【rails5】現在時刻保存時に、秒数以下を表示させない方法

##現在時刻保存時に、秒数以下を表示させない方法

Time.nowで現在時刻を保存し、ビューでstrftime("R")を使って、「24:00」という風に時間を表示させたかったが、エラーで上手くいかなかった。

```
strftime("R")は24時間表示
「24:00」
```

他の方法を探すべくアクションを見直していると、Timeクラスのオブジェクトを作るときに、Time.nowとしていたので、秒数以下まで引っ張ってきてしまっていた。

```
@current_time.update_attributes(current_time: Time.now)
```

上記(current_time: Time.now)の引数内で、**欲しい時間の情報（今回は年・月・時・分）だけを保存するように書き換える**とイメージ通りに出来ました。

**取得している時間をstrftimeで変換する**という考え方ではなく、
**欲しい時間だけを保存する**という考え方を学びました。