OmniAICreator/Qiita-1.07M huggingface dataset:
[PowerShell]不要なプリンタの削除

# [PowerShell]不要なプリンタの削除

## 経緯
社内の機種がFuji XeroxからRicohへ変更となったたため、不要なプリンタを削除したいのだが、設置場所によってプリンタ名が異なるため、プリンタドライバ名を元にプリンタを削除したかったので作成。

## Powershellコマンド

### Windows 10
```csharp

# プリンタドライバ名
$DriverName = "FX ApeosPort-IV C7780"

# プリンタの取得
$List = Get-Printer | Where-Object DriverName -match $DriverName

# 削除するプリンタのドライバ機種のみ削除
foreach($item in $List)
{
    Remove-Printer -Name $item.Name
}

# プリンタドライバ削除
Remove-PrinterDriver -Name $DriverName

# Windowsで通常使うプリンタを管理するのチェックを外す
$RegPath = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"
$RegKey = "LegacyDefaultPrinterMode"
$RegKeyValue  = 1
Set-ItemProperty $RegPath -name $RegKey -Value $RegKeyValue
```

今回は、目的がドライバ名なので `DriverName` を使用していますが、状況によっては、`Where-Object` の指定を変えてあげれば、良いです。

「Windowsで通常使うプリンタを管理するのチェックを外す」理由としては、チェックオン状態では、最後に使用したプリンタが通常使うプリンタになってしまうためです。

![WS000000504.JPG](https://qiita-image-store.s3.amazonaws.com/0/90597/08d94f10-61d6-9c77-902b-4736466e1b33.jpeg)

### Windows 8.1以下
```csharp
# プリンタドライバ名
$DriverName = "FX ApeosPort-IV C7780"

# WMIプリンタオブジェクトのの取得
$List = Get-WmiObject Win32_Printer

# 削除するプリンタのドライバ機種のみを取得
$DeletePrinterList = $List | Where-Object DriverName -match $DriverName

# 削除する対象プリンタの削除
$DeletePrinterList.Delete();
```

Widows10出なければ、「Windowsで通常使うプリンタを管理する」がないので、レジストリ設定を省きました。
また、 WMIを使用して不要プリンタを削除しています。
ツクールMVでセーブデータの表示を改造する＋セーブ日時を表示する


セーブ画面のレイアウトを改造するプラグインを作ろうとしたのですが、既にいいプラグインがあったんですよね。

[【プラグイン】セーブウインドウ改造プラグイン](http://bb-entertainment-blog.blogspot.jp/2016/11/blog-post_27.html)
最終的にはゲームの仕様などが複雑に絡むため、プラグイン一つで何でも解決！とは行かないことがわかり、作成中のプラグインは没になりました。
しかし、何も発表しないのは悔しいので、どうやったらメニュー画面を改造できるかだけまとめます。

#表示の仕組みは？
セーブデータを参照する画面は**Window_SaveFile**で管理されます。
**Scene_Load**と**Scene_Save**は、**Window_SaveFile**への*setHandler()*で渡す関数が違うだけです。
共通の**Scene_File**をベースとして持ち、どちらも機能はほぼ同じです。

#saveinfoって何よ？
saveinfoとは*DataManager.makeSavefileInfo()*で作られる、サムネイル用の情報をまとめた構造体です。
セーブデータを書き込む直前に作成されて、よくわからないタイミングで埋め込まれます。
（ソースコード内を検索すればすぐに見つかるのですが、OOP的に細かい原理は意識しないようにする）

```js:rpg_manager.js

DataManager.makeSavefileInfo = function() {
    var info = {};
    info.globalId   = this._globalId;
    info.title      = $dataSystem.gameTitle;
    info.characters = $gameParty.charactersForSavefile();
    info.faces      = $gameParty.facesForSavefile();
    info.playtime   = $gameSystem.playtimeText();
    info.timestamp  = Date.now();
    return info;
};
```

デフォルトでは上記の要素のみです。
よく話題に上がるのが「セーブした場所の名前を記録してほしい」ですね。
案外簡単に実装できます。

```js:rpg_manager.js
function addMapName(info){
    info.mapname = $gameMap.displayName();
}

const DataManager_makeSavefileInfo= DataManager.makeSavefileInfo;
DataManager.makeSavefileInfo =function(){
    const info = DataManager_makeSavefileInfo.call(this);
    addMapName(info);
    return info;
};
```

表示するときは*Window_SavefileList.prototype.drawContents()*を改造すればOKです。

```js:rpg_manager.js
Window_SavefileList.prototype.drawContents = function(info, rect, valid) {
    var bottom = rect.y + rect.height;
    if (rect.width >= 420) {
        this.drawGameTitle(info, rect.x + 192, rect.y, rect.width - 192);
        if (valid) {
            this.drawPartyCharacters(info, rect.x + 220, bottom - 4);
        }
    }
    var lineHeight = this.lineHeight();
    var y2 = bottom - lineHeight;
    if (y2 >= lineHeight) {
        this.drawPlaytime(info, rect.x, y2, rect.width);
    }
};
```


第一引数にinfoというデータがありますが、これが前述のsaveinfoです。
ブレークポイントで中身を確認しながら表示を機能を作りましょう。


##セーブ日時を表示する
セーブした日付はセーブデータに最初から格納されています。
saveInfoにtimestampというメンバがあって、これをnew Date(saveInfo.timestamp)で変換すれば必要なデータがすぐに手に入ります。
毎回変換するのが遅いと気になるのであれば、データ作成時に文字列へ変換するのがいいだろうと思います。
文字列に変換するのは以下のような関数で行えます。
すごく楽。

```js:
//日付表示設定を細かく改造したい場合、このパラメータを改造する。
//詳細はJavaScript Dateで検索すること
//また、このパラメータをオプションに設定すること
const dateOptions =  {
//        weekday: "long", // 曜日
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit"
};

/**
 * @return {String}
 * @param {Date} date 
 */
function dateFormat(date){
    //For languages ​​other than Japanese, change "ja-JP"
    return date.toLocaleDateString("ja-JP",dateOptions);
}
```

あとは*drawContents()*で適当に*drawText()*すればOKです。

以上。
ずいぶん雑な解説でしたが、saveinfoを*drawContents()*で表示するのだけわかれば後は何でもできます。
2017年の弊社技術領域の振り返り

この記事は、 [BRIGHT VIE Advent Calendar 2017 - Qiita](https://qiita.com/advent-calendar/2017/brightvie)の 25日目の記事になります。

メリークリスマス！クリスマスはいかがお過ごしですか？もう今年も残り1週間。
そして、アドベントカレンダーも本日が最終日です。（今年はなんとか走りきったー）

# はじめに

アドベントカレンダーの最後は、2017年弊社で取り組んできた技術領域や個人的な技術の取り組みの振り返りなどを行おうと思います。

## フロントエンド領域

- Backbone.js
- Knockout.js
- Angular
- Ionic

技術領域としては個人的に今年は（いや、「今年も」か）Webのフロントエンドがメインだった1年と感じています。それぞれ、Backbone 7割、Knockout 1割、Angular/Ionicで2割程度の内訳で案件に取り組んでいました。
ちょうど夏場は3種類のフレームワークの案件を並行して開発を進めなければいけなかったので、頭の切り替えがなかなか出来ずに苦労した記憶があります...

一番慣れているのは「Backbone.js」ですが（内部ソースを一度読んだことも安心感につながっているのかもしれません）、今弊社でもメインで扱っているは「Angular/Ionic」であるため、来年は個人的にもマスター出来るように、そして得られた知見とかどこかで発表できたら良いなぁと思います。

## サーバサイド領域

- Node.js（6系, 7系）
   - Express（4系）
- PHP（5.6系）
   - CakePHP（2.9）
   - FuelPHP（1.7）
- DB
   - Mongo DB
   - MySQL
   - Elasticsearch
   - Redis
   - DynamoDB

サーバサイドのプログラムも記載していましたが、主にNodejsにどっぷり浸かっていた1年だったなぁと!（数年前にNode.jsで記載されたプログラムの保守などはなかなか大変だった思い出が...）

動くものを作るフェーズだったので特に新しい領域にはチャレンジできない分野でもあったので、特にこれといって語る部分もなく...来年は色々と取り組んでみたい！

## インフラ領域

- AWS
   - EC2, Route53, VPC, RDS, CloudFront, S3くらいかな...
- さくらVPS
- 社内VPN環境の構築
- Jenkinsによるデプロイ環境の構築
- サーバの死活監視/URLチェック/SSLチェック機構の構築

今年もAWSをほぼほぼ利用していた1年だったなぁ...インフラ領域も監視の仕組みや負荷分散など世間一般的なことくらいしか着手できておらず、最低限は大丈夫というようなところで止まっている印象です。

来年はGCPの活用やプロビジョニングツールやDockerの導入など、インフラ面としてもしっかり整備していきたい！


## その他

- Bluetoothを利用したデータ連携
- FCMによるWebPush通知基盤の構築
- Google Assistantを活用したスマートスピーカー対応アプリの開発
- iOS/Android WebViewを活用したキャッシュ基盤の構築
- 在宅ワークメインだったのがオフィスを借りての開発
- データを活用するための機械学習への取り組み


メインの開発以外にも色々と取り組むことが出来たが、今年は特に英語のドキュメントに向き合うことが多かった...（苦手意識が強いぶん、読まなきゃいけない状況に追い込まれたためいい勉強にはなりましたが）
ある程度、来年はこれらの取り組みがサービスに乗っかって動き始めることもあり、今度は運用に伴う苦労などとも向き合うことになるんだろうな！


日々の業務の中で「研究開発」という名目で色々な技術にチャレンジしていけるような風土は、今後人が増えてきたときもしっかり残していきたい。。。


# まとめ

とても内輪的で個人的な振り返りになってしまいましたが、会社としても技術領域としては基盤としてしっかり土台を固める1年だったなと感じています。
来年は、人も増えてくるだろうし、よりいっそう環境を整備しながら開発を加速化させて行く必要があるので、組織体制、エンジニアの育成含めた視点で動いていく必要もあり、今からワクワクが止まりません。


来年の弊社「[株式会社ブライト・ヴィー](https://brightvie.me/)」を宜しくお願い致します。
今年も1年間お疲れ様でした！！
yamllint

CloudFormationのYAML対応により、AWS CLIでYAMLを扱う場合はそのバリデーションが必要になってきます。

ここではyamllintの導入方法を説明します。

リポジトリ: https://github.com/adrienverge/yamllint
ドキュメント: https://yamllint.readthedocs.io/en/latest/



# 1. インストール

```bash:コマンド:
sudo pip install yamllint
```


```bash:コマンド:
yamllint -v
```

```text:結果(例):
yamllint 1.10.0
```

```bash:コマンド:
which yamllint
```

```text:結果(例):
/usr/local/bin/yamllint
```


# 2. 設定

CloudFormationのテンプレートをチェックするとdocument-startについてエラーが出るので、設定で抑制します。

```bash:コマンド:
mkdir -p ~/.config/yamllint
```

```bash:コマンド:
cat << EOF > ~/.config/yamllint/config
  rules:
    document-start:
      present: false
EOF

cat ~/.config/yamllint/config
```

# 3. 実行テスト


# 完了
Windowsであれこれメモ

直ぐに忘れるので個人的なめっも

# Windowsでtail -f
PowerShellで

```
Get-Content -Path ファイル名 -Wait -Tail 出力行数 -Encoding 文字コード
```

なんか入力めんどくさい・・・

# Windowsでalias

```
doskey alias名=実際のコマンド`
```

#Windowsで空ファイルを作る
Linux系だとtouchで作れるけども・・・

DOS窓だと

```
type nul > 作成するファイル名
```

Powershellだと

```
New-Item -ItemType file 作成するファイル名`
```
準新卒エンジニアがレガシーコード改善のためにテストの書き方を学ぶ方法

__今自分に求められている仕事はなんだ？__

__今私が学ぶべきことはなんだ？__

__今私が会社に貢献していることはなんだ？__

## テストだ

__注： この記事は、レガシーコードを見ると燃えてくる系若手エンジニア向けの記事です__

8月にアイリッジに転職してから日夜テストと格闘している@aimofです。今日はコード資産のない純新卒エンジニアがプライベートにおいてテストを書く練習を始める方法を話します。

### 「レガシーコード改善ガイド」を読んで

「レガシーコード改善ガイド」を読んで感化されました。テスト書きてー。そう思った時、数千行に渡る汚いコードなんてプライベートではそうそう手元にはありません。今まで作ったものはあってもせいぜい数百行。今更メンテナンスする気も起きない殴り書き……。自分自身の昔のコードがすでにレガシーコードですが、どうせなら、他人の書いた大規模プロジェクトにテストを書きたい！

### テストの重要性〜テストのないコードはレガシーコード〜

「レガシーコード改善ガイド」なる本によると「テストのないコードはレガシーコード」です（初出かは知りません）。理由は、テストがなければあらゆるコード改修が綱渡りみたいになるからです。それじゃあ良くない、というわけで、テストを書きます。

## プライベートでテストを学ぶにはどうしたら良いか？

現在業務で必要とされているテストは、「自分より実力のある人が書いて」「当初は問題なく動いていて」「改修の必要がある」コードです。コード資産も実力もないエンジニアが用意したコードでは（無駄ではないが）効率が悪いです。

## テストがないけど利用されていて自分より実力のある人が書いたコードといえばあれしかない！

お馴染みgithubを漁りましょう。上の条件を満たすコードがゴロゴロ転がっています。

### 方法！

検索クエリはこんな感じ。

```
created:>2016-01-01 stars:>200 language:Go license:mit
```

この結果に対して、Least Recently Updatedでソートをかけます。

#### 検索結果

テストコードなし、メンテなし、スターはある、しかもコード改変可能みたいなプロジェクトが大量に出て来ます。垂涎ものですね。

## 私のリポジトリ紹介

そんなわけで、クローンさせていただいたのが[thymeというリポジトリ（オリジナル）](https://github.com/sourcegraph/thyme)になります。これをクローンして、[github.com/aimof/thyme](https://github.com/aimof/thyme)というリポジトリを作成しました。

* スターが多い
* Issueが多い
* テストがない
* 1年以上ほったらかし
* 個人的に興味を持てる
* ライセンス
* バグだけでなく改修後の要望もたくさん

と今回求めている要件を全部満たした夢のようなリポジトリになります。（ちょっと失礼な言い方ですが）

### 書いたテストの例

```linux.go
// isVisible checks if the window is visible in the current viewport.
// x and y are assumed to be relative to the current viewport (i.e.,
// (0, 0) is the coordinate of the top-left corner of the current
// viewport.
func isVisible(x, y, w, h, viewHeight, viewWidth int) bool {
	return (0 <= x && x < viewWidth && 0 <= y && y < viewHeight) ||
		(0 <= x+w && x+w < viewWidth && 0 <= y && y < viewHeight) ||
		(0 <= x && x < viewWidth && 0 <= y+h && y+h < viewHeight) ||
		(0 <= x+w && x+w < viewWidth && 0 <= y+h && y+h < viewHeight)
}
```

```linux_test.go
func TestIsVisible(t *testing.T) {
	if isVisible(0, 0, 0, 0, 0, 0) {
		t.Error("case0")
	}
	if !isVisible(0, 0, 0, 0, 1, 1) {
		t.Error("case1")
	}
	if !isVisible(1, 1, 1, 1, 2, 2) {
		t.Error("case2")
	}
	if !isVisible(1, 1, -1, -1, 1, 1) {
		t.Error("case3")
	}
}
```

なんかカバーしきれていない……

この部分、wとhはゼロ以上のはずだたったり、何か書き方が雑だったり色々ツッコミどころが多いのですが、テストの書き方を改めて勉強せねば……。

頑張ろう

## まとめ

* githubを探せばテストの必要なリポジトリはいっぱいあるよ
* PRもいいけど、まずはクローンして自分なりにやるのも良いかも
* 勉強しよう
* [github.com/aimof/thyme](https://github.com/aimof/thyme)をよろしく
Rails 5.1.4におけるjQueryの導入について

#Rails5でjQueryが正常に機能しない
題名の通りです。

jsは動いていることが確認できたのですが、jQueryがまったく動かない。

いろいろ調べまわったすえ、一日かかって解決しました。
俺のクリスマスイブを返してくれ。。

#application.jsに"//= require jquery"を書き足すだけ

application.jsに"//= require jquery"を書き足すだけ。

ほんとこれだけです。

```app/assets/javascripts/application.js
//= require rails-ujs 
//= require turbolinks 
//=require_tree .
```
もともとはこんな感じになってると思います。
それを

```app/assets/javascripts/application.js
//= require jquery
//= require rails-ujs 
//= require turbolinks 
//=require_tree .
```
こうするだけ。これで、途端にjQueryが動きます。

**追記**

コメント欄で、@rubyist_yasunao さんより以下のようなご指摘をいただきました。検証はしていませんが、併せてご確認ください。

> //= require jquery
> //= require jquery_ujs
> 
> 今は、このようにしないとダメみたいですので、蛇足です。
> Rails 5.2.2

#それでも動かない場合は
自分もこの回答に到達するまでにいろいろ試したので、もしかしたら複合的な要因で解決したのかもしれません。一応、自分がやったことを書いておきます。

といっても、Gemfileに

```
gem 'jquery-rails' 
gem 'jquery-ui-rails'
```
と書き足す。そしてconsoleでbundle install。
以上。

どこかの誰かも、これで救われますように。
Visual Studio | WPF > fileIO > アプリケーションのパスを得る > GetExecutingAssembly().Location | MainModule.FileName など

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

WPFでアプリケーション(実行ファイル)のパスを取得したい。

### 参考

- https://stackoverflow.com/questions/3123870/find-the-location-of-my-applications-executable-in-wpf-c-or-vb-net
- [Windows GUIプログラミング入門11 設定保存(2)](https://qiita.com/Kosen-amai/items/7835aac8df7cc925eddd)

### code

以下の3種類は使えることはわかった。

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _171225_t0955_appFilepath
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void B_apppath_Click(object sender, RoutedEventArgs e)
        {
            string appPath1 = System.Reflection.Assembly.GetExecutingAssembly().Location;

            string appPath2 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;

            string appPath3 = System.Reflection.Assembly.GetEntryAssembly().Location;

            //MessageBox.Show(appPath1);
        }
    }
}
```

どれも今日の晩には忘れていそうな記述ばかり。

`MainModule.FileName`だけ覚えておくと見つかりやすいだろうか。

### appPath1のはまり

appPath1 については上記のStackoverflowのコメントに下記がある。

> This may not work properly all the times. It will get the executing assembly, not the application's executable. ...

### appPath2のはまり

appPath2については以下の「はまり」事項があるようだ。
[64bit環境で、Process.GetProcesses()を使用しウィンドウをもつプロセスのMainModule.FileNameを取得したい。](http://king-of-nowhere.hatenablog.com/entry/2013/08/27/124440) by Icoさん
> しかし、これを64bit環境で実行すると、
p.MainModuleにアクセスした時点で
>> 32 ビット プロセスは、64 ビット プロセスのモジュールにアクセスできません。

> とエラーが出る。

それに関する解決案は以下にある。
https://stackoverflow.com/questions/9501771/how-to-avoid-a-win32-exception-when-accessing-process-mainmodule-filename-in-c

プロセスの権限が関係しそう。自分自身のプロセスのMainModuleプロパティを取得する分には問題はないのかもしれない。
mos wifi コマンドで Error: no config value at path "wifi.sta.enable" が出るとき

`mos wifi` を設定しようとすると、

```shell-session
$ mos wifi $MOS_SSID $MOS_PASS
Getting configuration...
Error: no config value at path "wifi.sta.enable"
```

と怒らることがあります。

## 原因
wifi ライブラリが入っていません。

## 解決
mos.yml の libs に追加します。

```diff
 libs:
   - origin: https://github.com/mongoose-os-libs/spi
+  - origin: https://github.com/mongoose-os-libs/wifi
   - origin: https://github.com/mongoose-os-libs/vfs-dev-spi-flash
```

```shell-session
$ mos build
$ mos wifi $MOS_SSID $MOS_PASS
Getting configuration...

Setting new configuration...
Saving and rebooting...
$ mos flash
```

これで無事設定できました。
RStudioのGlobal設定(前編)

これは[RStudio Advent Calendar 2017](https://qiita.com/advent-calendar/2017/rstudio)の...17日が空いたままだったので埋めることにした即席の記事です。

## RStudioのGlobal Options

RStudioで全体的な設定をする場合，メニューの[Tools] - [Global Option...]から行うこととなります。ここで設定した内容は(当たり前ですが)RStudioを扱う際の全体設定となります。

なお，RStudioにはさらにProject設定があり，Project設定とGlobal設定があった場合にはProject設定が優先されます。また，現在作業している環境やファイル個別で設定がある場合には，そちらが優先されます。

自分が使いやすい環境はGlobal Optionsで設定しておき，個別で必要に応じてProject設定や個別の設定を切り替えるのが上手な使い方だと思います。というわけで，今回はGlobal Opitonsをさらっと紹介してみます。ただ長いので記事を分割し，今回は前編とします。今回はRStudio v1.1.383での内容となります。

## General

![11114739583.png](https://qiita-image-store.s3.amazonaws.com/0/35118/c589f979-0cd0-fe89-b0e8-467f5275aece.png)

全体的な設定となります。

どちらかというとRの挙動に関する設定が中心です。デフォルトの作業ディレクトリや，履歴(.Rhistory)を常に保存するかどうか，環境に入れているオブジェクトをリストアしたり保存したりするかどうか，エラーが出たら常にデバックするかどうかなどを設定します。

この辺りは自分なりのRスタイルがあるでしょうから，お好みで設定してみてください。なお私は.RDataは保存しないようにし，履歴は(一応)残すように設定しています。Projectによっては履歴も残したくない場合があるので，この時はProject設定で切るようにしています。

## Code

コード編集に関する設定です。

ここはさらに5つのタブに分かれていて，Global Optionsで一番設定項目が多い場所となっています。Rはコードを入力してなんぼですから，ここは重要ですよね。

### Code - Editing

![11134897.png](https://qiita-image-store.s3.amazonaws.com/0/35118/dfa015d4-ee28-a7df-1fcd-3977b27e99ef.png)

**Editing**ではコード入力/編集における設定となります。最重要は**Insert spaces for tab**で，ここは必ずチェックしてください。個人的にはTabを2スペースにしていますが，おそらく多くの方もこの設定が望ましいと思います。  
他にも**Keybinding**でemacsやvimのようにすることも出来ますし，キーボード・ショートカットを変更することも可能です。あとSnippetsも確認/編集できます。

### Code - Display

![111435903.png](https://qiita-image-store.s3.amazonaws.com/0/35118/b5b98a5e-8cf7-babc-9930-6f8bc36b9b16.png)

コード編集における表示に関する設定です。この辺りは完全に好みでしょう。ただこれまでデフォルトでやってきた方はちょっと確認してみるといいかもしれません。

### Code - Saving

![111453092.png](https://qiita-image-store.s3.amazonaws.com/0/35118/6f6a81f9-6648-9048-6f30-8d89ece0056d.png)

コードの保存に関する設定です。項目数は少ないですが，**Default text encoding**だけは気をつけてください。特にWindowsユーザーおよびコードを共有する場合には...。

### Code - Completion

![111459045.png](https://qiita-image-store.s3.amazonaws.com/0/35118/9a73da8b-595e-901b-4497-1cd3eb43cfa6.png)

コード補完に関する設定です。例えば「コード補完を自動的に出すか，あるいはOFFにするか」とか，「ツールチップを表示するかどうか」とか，あるいは「多言語でコード補完を出すかどうか」とかも設定できます。それ以外にも「何文字入力したらコード補完を呼び出すか」なども設定できたりします。このあたりで不満があった方は見直しましょう。

### Code - Diagnostices

![111349053890.png](https://qiita-image-store.s3.amazonaws.com/0/35118/fd0d4b51-c378-c7ef-6715-529cb449371c.png)

コードの診断に関する設定です。Rスクリプトを書いていて，文法上おかしい場合には編集中でもRStudioから怒られていたと思います。その辺りの設定です。私もそうなのですが，初歩的なところでミスすることが多いので，これらの項目を多めにチェックをいれるのもいいかも。あとJSやHTML, CSSもよく書くので私はこれらの言語もチェックを入れています。

## 続きは後編で

ざっくりと紹介しましたが，やはりCode部分はRStudioユーザーであれば自分のコーディングスタイルを意識して設定項目を確認すべきでしょう。全ては作業の効率化のためです。

**Enjoy!**
2017年を振り返って

これはLIG Advent Calendar 2017の最終日の記事です。
最終日という大役をいただいたので、今年を振り返ってまとめたいと思います。

なにも考えずに書き出して、何も考えずに公開することになるきがするので、
この記事を読んでも得られる知見はなにもないと思います。
時間を無駄にする前に、ブラウザバックするなり、お気に入りから別サイトにいくなりしてもらえれば幸いです。

##はじめに
普段はでバックエンンドだったらい、フロントエンドまがいの事をしています。
他にもこまごまやってますが、主にこれがメインです。
会社自体もいろいろやってますが、メインはWEB制作の受託の会社で11期目らしいです。
ちなみに1月で35になるおっさんなので、定年説と頑張って戦っていこうかと思います。
老害にはなりたくねぇなぁ。

##全体的な話し
例年の事ではありますが、去っていった仲間がいました。
とても悲しい(寂しい？)事ですし、未だになかなか慣れません。
WEB業界は人材が流動的だしね、とかある程度はありえることだとは思ってるんです。
でもなかなか割り切れねぇですなぁ。
あー戻ってこないかな、あいつとかあいつとか。
来年も再来年も存続して、戻って来たくなるような会社にしないとなぁくそう。

今年去っていた人たちは、割とその後会社で異様に会うので、寂しさはだいぶ少なかった気がしますw
また何人も会社にきてくれた仲間もいました。
みんな優秀だしいい子達で、期待しています。
大切にしていかなければなるまい。と思っています。

## 個人としてのエンジニアとしての話
あんまりこれが伸びたぜと、自分では言えない年だったなと感じでいます。
なんか新しい事やれたかなと振り返ってみましたが、あんまりなかった。
AWSの新しいサービス使ったり、Rubyをちょっとさわったりしたくらいでした。
フロントはまったく進化できなかった気がします。
来年はGLSLをちゃんと学んでもっと発信していきたい。。。
コード書く時間がどんどん減ってるきがしなくもないですが、やはりコード書いてたいので頑張らないと。
老害にはなりたくねぇぇぇぇ

## 会社としてのエンジニアの話
案件の規模や質はだいぶ変わってきました。
バックエンドとしてはPHPがあいかわずメインではありますが、幸い規模も大きい案件をいただける事も多く、AWSでインフラをという話も増えてきました。
GCPもやってこうという動きが社内でもあります。
PHPは紆余曲折ありましたが、LaravelがメインのFWに落ち着きそうです。
WordPressの案件もかなり多かったのですが、セブのオフショア拠点で解消できるような動きが活発です。
いいことだなー

フロントエンド側はサービス寄りのメンテナンス性にすぐれたコードを書こうぜ！勢とアニメーションとかすごい表現やっていこうぜ！勢がいて、お互いいいところを伸ばしていってくれています。
アニメーション勢が今人が少なめなので、この辺りに力を入れていきたいと思ってます。
あとはあれですね、数年前の環境がすぐ動かなくなってるのが昨今のフロントの恐ろしいところな気がしています。
うちで作ったnode0.10.2とかの環境がまったく動かねぇ、ちょっとCSS変更したいだけなのに環境つくるのに何日かかるんだようわぁぁぁ、という事例を少なくしたい。。。
これは解決策がよくわからんのですが、教えて偉い人という感じです。

## 閑話休題
うちは例にもれず3月で年度末なので実は絶賛年末進行中なので、そんなに振り返る感もあんまないのですが。
振り返ってあの頃楽しかった、この頃楽しかったとか思い出がすごいでてきました、ノスタルジーだ。
別に今も楽しいんだけどね、楽しさの質が年々変わっていってはいるきがする。
閑話休題って言いたかっただけなんだけど、あってるのかな。使い方。

## 来年に関して
なんも考えずに書き始めるとどうまとめていいかわからない。
ダメな記事を書くにはどうしたらいいかの、バッドノウハウがこの記事1本でかなり蓄積されました。
誰に向けて、どういう風に思って欲しいか考えて記事を書こうとか、自分でも言ってるけど、それ正しい。
改めて身を持って知った。

やらなきゃいけないことはいっぱいあるし、やりたいこともそこそこある。
割と自分の能力がポンコツなのはさすがに自覚している年だし、できることを確実にやっていきたい。
俺が曹操並にすごかったいいんだけど、背伸びして王平くらいにしかなれないきがしている。。。

LIGにきてくれた仲間が、仕事できてよかったと思ってくれるような環境にできるように
できることを地道にやっていきたい。

## まとめ
毎年思うが、忙しかったしハードな年でした。
ただ今年も振り返るとなんだかんだ楽しかった。

来年もそう思えるように凡人なりにやっていこうと思います。

見返すと公開できなくなるきがるので勢いで公開します。

おわり
[django]ManyToManyField(中間モデル)の要素にテンプレートからアクセスする方法

# 経緯

汎用詳細ビューでテンプレートから中間モデルのフィールドにアクセスする方法がわからなかったため、
調べたところ、良い方法が見つからなかったため。
django初心者につき、もっと良い方法があればご教示いただきたいです。

# 暫定解決方法

```python:models.py
class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)
```

カスタムフィルターを準備

```python:extras.py
from django import template

register = template.Library()

@register.filter()
def get_relation_id(qs, group_id):
    return qs.filter(group=group_id).get().id

@register.filter()
def get_relation_invite_reason(qs, group_id):
    return qs.filter(group=group_id).get().invite_reason
```

フィルターを使用し、要素にアクセス

```jinja:group_detail.html
{% for member in object.mermbers %}
<tr>
<td>{{ member.membership_set|get_relation_id:object.id }}</td>
<td>{{ member.membership_set|get_relation_invite_reason:object.id }}</td>
</tr>
{% endfor %}
```
AWS Cognitoについて調べてみた

## Cognitoとは
認証・認可周りを担当するサービス。
大別して三つの機能があり、それぞれ名前のついたサービスに分かれている

| 機能 | サービス |
| --- | --- |
| ユーザの管理と認証 | User Pools |
| AWSの各リソースへの認可 | Federated Identities |
| 同一ユーザのデバイス間同期 | Sync |

[![AWS Black Belt](https://image.slidesharecdn.com/20170517aws-blackbeltamazoncognito-170517101907/95/aws-black-belt-online-seminar-2017-aws-cognito-12-638.jpg)](https://www.slideshare.net/AmazonWebServicesJapan/20170517awsblackbeltamazoncognito/12)

### Cognito User Pools
- ユーザの管理
    - メールアドレスなどを利用したユーザ登録
    - メールアドレスや電話番号の検証
    - パスワード再発行
    - CSVなどを利用したインポート・エクスポート
- ユーザの認証
    - ID/Passwordでの認証
    - OpenID Connectに準拠したTokenの発行

### Cognito Federated Identities
- Identityの発行
    - 認証サービスを利用しているユーザを名寄せし、統合したIDを発行
- AWSリソースへの認可
    - Cognito User Poolのユーザの認可
    - 未認証ユーザの認可
    - 以下の外部認証サービスのユーザの認可
        - Amazon
        - Facebook
        - Google
        - Twitter
        - OpenID Connectプロバイダー
        - SAMLプロバイダー
        - 独自に実装したプロバイダー

### Cognito Sync
- データの保存
    - key-valueの形式でデータを保存
    - オフライン状態でも動作
- 同一ユーザ間の同期
    - 同じユーザの複数デバイス間でデータを同期

## 動作

[![AWS Black Belt](https://image.slidesharecdn.com/20170517aws-blackbeltamazoncognito-170517101907/95/aws-black-belt-online-seminar-2017-aws-cognito-15-638.jpg)](https://www.slideshare.net/AmazonWebServicesJapan/20170517awsblackbeltamazoncognito/12)

1. UserPoolにログインしてTokenを取得
1. 取得したTokenをFederated Identitiesに渡す
1. Federated IdentitiesがTokenを検証
1. 検証が完了したらSTSから一時クレデンシャルを取得
1. ユーザに一時クレデンシャルと統合IDを返す
1. 統合IDと一時クレデンシャルを利用してAWSリソースにアクセス


## 参考
- [よくわかる認証と認可](https://dev.classmethod.jp/security/authentication-and-authorization/)
- [AWS Black Belt Online Seminar 2017 AWS Cognito](https://www.slideshare.net/AmazonWebServicesJapan/20170517awsblackbeltamazoncognito)
- [Amazon Cognitoによる認証はSTSのweb identity federationとどう違うのか！？](https://dev.classmethod.jp/cloud/aws/cognito-identity-and-sts-web-identity-federation/)
【覚書】Mac版 SourceTreeでリモートリポジトリの認証に失敗後、再度認証して欲しいとき

**環境**
・SourceTree Mac版　バージョン2.3.2 (75)
・macOS 10.13.1

## リモートへプッシュ！あ、認証ミスった！
 SourceTreeではリモートリポジトリへの初めてのプッシュで認証確認がはしるものの、
一度入力ミスると、次回以降のプッシュでは認証の再確認はされない。
なので、一度パスワードをリセットする必要がある。
リセットによりプッシュ時に再確認が行われる。

##対処方法
リモートリポジトリへの認証情報は「キーチェーン」へ保存されているので、一度削除する。
そうすると再度リモートへプッシュすると認証確認が実施される。

意外とハマってしまったので覚書でした。

![keyScreen.png](https://qiita-image-store.s3.amazonaws.com/0/142161/26c13e0b-5765-9f91-abe6-13dc39b7a37b.png)
もくもく会運営

PORT株式会社では毎月, 「[PORTもくもく会](https://freestyle-mokumoku.connpass.com/)」という勉強会を開催しています。
2017年の12月で35回なので, 始めてからもうすぐ3年。参加者40名以上の規模になりました。最近では「どうすれば集客できるのか」を聞かれます。

実は特別工夫していることはないのですが, 振り返って集客に役立っているなと思ったことを以下に記します。

# 開催時期とタイミング
## 毎月必ず開催
- 35回続けているのでリピーターが多い。常連参加者が知人を誘ってくれたりもする。
- 毎月恒例なので習慣化しやすい。既婚者の方は奥様も許可しやすい？

## 開場時間が長い
- 開場10:00, 終了19:00くらい。ほぼ１日中利用できる。移動時間が長い方も利用しやすい。
- 途中参加途中退出OK。なので午前だけ参加, 午後だけ参加も可能

# 会場
## 立地が良い
- 西新宿なので、アクセス悪くない

## 会場が良い
- 会場が広いので集客しやすい。いろんな人が集まって楽しい。10人くらいの会場だと、キャンセルと遅刻の影響大きすぎて運営多分つらい。
- そこそこ綺麗でそこそこオシャレ。トイレも綺麗なので女性も安心？まあ女性は来ないけど

# メンバー
## 参加者が素敵
- 参加者同士の交流が活発。分からないことを教えあったり、就職転職の助言をしあったり。もくもく会のおかげで就職できた、転職の紹介もらった等の声も！
- 参加者が打ち上げの設定や会場の後片付け、お菓子の買い出し等を手伝ってくれる。なので, 運営の負担が少ない。感謝!
- お菓子食べながらおしゃべりが楽しい！ブルボンのルマンドとルーベラが人気！

## 主催者も頑張ってる
- 私以外の主催者が、社交的でキャラが濃い。見た目もトークも面白い。ずるい。
- 私は参加者の名前や得意分野を覚えるようにしています。凡人なりの努力と工夫。

ということで, 毎月欠かさず広い会場で開催できれば集客はできるかと思います。
とはいえ天の時, 地の利は人の和に如かず。主催者と参加者が仲良く楽しめると良いコミュニティになるかと思います。
それでは良い勉強会ライフを！
ReactでWindowのリサイズイベントを取得する方法

##windowリサイズイベント取得
react-event-listenerをインストール

```
yarn add react-event-listener
```

react-event-listenerをインポート

```jsx
import EventListener from 'react-event-listener';
```

windowがリサイズされたらコンソールにwindow.innerHeightとwindow.innerWidthを出すサンプル

```jsx:Home.js
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import EventListener from 'react-event-listener';
import s from './Home.css';

class Home extends React.Component {

  handleResize = () => {
    console.info(
      `window height:width=${window.innerHeight}:${window.innerWidth}`,
    );
  };

  render() {
    return (
      <div className={s.root}>
        <EventListener target="window" onResize={this.handleResize} />
      </div>
    );
  }
}

export default withStyles(s)(Home);
```
cAdvisorの起動時エラー：inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: no such file or directory

デバッグメモ

コンテナ単位のリソース状況を確認したくて、kubernetes/dockerのリソースモニタリングツール　cAdvisor を実行したところ、以下のエラーとなり起動できなかった。

```
Failed to start container manager: inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: no such file or directory
```

ちなみにdocker runコマンドは以下

```
sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --privileged=true \
  --volume=/cgroup:/cgroup:ro \
  google/cadvisor:latest
```

参考）
https://github.com/google/cadvisor

そこで、stackoverflowの以下トピックを参照し解決
https://github.com/google/cadvisor/issues/1444
https://github.com/kubernetes/kubernetes/issues/32728#issuecomment-252469277


Short synopsis from the linked issue - the cgroup is mounted under cpuacct,cpu inside a container, but the host mounts it as cpu,cpuacct. libcontainer returns the first viable candidate it finds - mrunal and vish were discussing changing libcontainer to return all of them and letting cadvisor have more info to pick the right one to look at for the host.

どうやらマウントの仕方の問題らしい。

ホストで以下のコマンドを実行することで、正常にcAdvisorを起動できるようになった

```
  sudo mount -o remount,rw '/sys/fs/cgroup'
  sudo ln -s /sys/fs/cgroup/cpu,cpuacct /sys/fs/cgroup/cpuacct,cpu
```
RoBoHoNめも_04：Android Studio 3.0に対応したよ！

# RoBoHon開発めも
RoBoHoN開発のことをめもしていきます！

# Android Studio 3.0に対応したよ！
なにげに、AndroidSttudio3.0に対応していなかったSDKが、12/13にリリースされたRoBoHoN_SDK_1_3_0で対応しました！

# そのほかの更新状況はこんな感じ！
Message送信用のAPIの追加
電話機能有無判別用のシナリオ変数の追加
各種ドキュメントの追加、修正等

# 電話機能有無判別用のシナリオ変数の追加
これを使うと、Wifiモデルかどうかわかります。シナリオ変数なので、あんま使わない気もする・・・。

# Message送信用のAPIの追加
謎の機能。ロボホンのメッセージなのか、メールなのか、それとも違う何かなのか・・・。
ドキュメントみると前半メッセージで後半メールって書いってある。
こんどためしてみようかな。

# 各種ドキュメントの追加、修正等
雑なアナウンスだなこれ・・・。

ダンス後のコメントをキャンセルすることが出来るようになっています。
複数台でダンスするときにつかえます。
やっと対応してくれて嬉しい。

# まとめ
ひさびさのロボホンめもでした！ わーわー。
WEBアプリケーション開発で見積もりを安くしたいお客さんに提案すること

# WEBアプリケーション開発で見積もりを安くしたいお客さんに提案すること

## 要求定義の工数を軽減する（折半）

超概算見積もりならまだしも、正式見積もりで、「○○を作りたい」だけでは要件分析が入りその分だけ工数が振られている。

人生の謎としては、要件定義が見積もりのあとにあるので、要件定義する前に見積もりしなければならず「何を欲しがっているのか全然わからない」という状態で見積もりをすることがしばしばある。

ちなみに、これで再見積もり依頼されるとその分工数が乗っかるのでお値段もあがる。

昨今見積もり無料と書かれているものは大体他の工数に含まれていると言っても過言ではない。

### 要求定義の作成

何を作りたいのかを詳細に決定してもらう。

家造りと同じものと説明すればわかりやすい。

* 予算
* 納期
* 最終的にほしいもの（イメージ）

上記は必須であるが、それだけでは満足のいくものができない。

もっと思考をアウトプットしてもらう。家で例えるならば「リビングは2階がいい」「システムキッチンは255cmで」といった基本的な仕様から、「スキップフロア付き」「ロフト付き」などのオプションまで、全て出してもらって、見積もりを出してから削るほうが良い。→第二フェーズなどの提案ができる。

この時、長期的に見たシステムの使い方を考えてもらう必要がある。5年～7年後のシステムを見据える。
業務フローを考えてもらう。

「1階部分の一部はお稽古の教室として使いたい」「友達をたくさん呼ぶのでパーティが開けるスペースのリビングがほしい」など、個人個人の都合による機能は存在する。

この部分をお客様がしっかり作っているならば、要求分析が減り、コスト削減に繋がる。

### 要求定義を具体的に作ってもらうには

1. 最終的な目的を出す
1. そのために必要な動作を洗い出す
1. どういう導線ならば使いやすいかを洗い出す
1. 「○○ならば××」「しかし△△ならば□□」といった分岐は曖昧にせずしっかり定義する（長い付き合いだから10％オフなどといった人間の心情での分岐はシステムに組み込めない）

基本的には上記の繰り返し＋業務フローと照らし合わせることで可能である。

その上で、別途

1. コード定義が存在するか確認する
1. 外部システム連携はあるか確認する

といった細かい部分を確認してもらう。

これをやることで、先方担当者の方の意識もシステムに向くので、齟齬が生まれにくい。

## お客さんにゆだねてはいけないもの(お値段があがります)

* ミドルウェアの選定

お客さんで、いつか内製にしたいからミドルや言語を指定してくることがあるが、その言語やミドルが依頼した会社にマッチしていればいいけれどマッチしていなかったら品質の担保は自社で持つようにお願いしたほうが良い。

javaの開発会社にGo言語で開発依頼することはないだろうが、javaの開発会社にPHPでの開発依頼は多々ある。Tomcatメインの会社にJBossを使ってほしいと言ってくることもある。

できなくはないがやりたくもない。
この場合、見積もりする人が抱えている人員のスキル次第だけれども、実装・テストが2割増くらいになっていると思っていい。

人員確保の工数が増えるからだ。

* WEBデザイン会社とのデザインFIX

極稀に「ここはAjaxで連携することを前提に作っています。Ajax部分のJS処理は開発会社にお願いしてください」という丸投げWEBデザイン会社がある。

あるいは「特殊なカレンダー表示をしたいので、ペーパーモックは作ったので実装は開発会社の人にお願いしてください」といった無茶振りもある。

そんなの見積もりに入っているわけがない。後請求です。

あとでものすごく揉める元になるので、開発会社も入ってFIXしたほうがいい。

## お客さんの協力がなければ安くはできないということ

コンサルも含めているんだから、と言われても、何をやりたいかを明確にしていないシステム開発は確実に失敗する。

もし、全てをコンサルだとして委ねるのならば、定義に半年は付き合ってもらったほうがいい。
掲示板だって半年ROMれって言われるけれど、それと同じ。空気の理解は重要だということ。
CanvasのshadowOffsetはscaleに影響されない

CanvasのshadowOffsetX/Yがscaleに影響されない件でハマりました。同じようにハマる人がでないよう願って記事にしておきます。

```js
ctx.scale(5, 5);

ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.shadowOffsetY = 100;

ctx.fillStyle = "#222";
ctx.fillRect(50, 50, 100, 100);
```

これを1000x1000のCanvasで実行すると以下のようになります。ChromeとFirefoxで確認しました。

![canvas-shadow1.png](https://qiita-image-store.s3.amazonaws.com/0/166423/0de68e22-8bbd-d8d3-c920-0af6f0f214eb.png)

scaleで5倍していますが影のズレは100pxです。なぜ影響されないのでしょうか。これはshadowOffsetの値にscaleの値をかけることで回避できます。

```js
ctx.shadowOffsetY = 100 * 5;
```
Google Calendar APIでイベントのIDを取得した話

#はじめに
@satoshiks です
Apps Scriptでカレンダーの予定を取得する時に、Calendar ServiceではイベントのIDが取得できなかったのでCalendar APIを利用して取得した時のメモです

イベントの編集画面への直リンクを作りたくてイベントIDを取得したかった

###ここでいうイベントIDとは
![スクリーンショット 2017-12-25 7.33.34.png](https://qiita-image-store.s3.amazonaws.com/0/45849/09a4ad50-3f7a-039e-54a5-c27634647e38.png)





#これで取得できた
Google Calender APIを有効にして以下のコードを実行すると取得できました

```js:Code.gs
function get_event_id() {
  var events = Calendar.Events.list("primary", {
    timeMin: new Date().toISOString(),
    singleEvents: true,
    orderBy: "startTime",
    maxResults: 1
  });
  var link = events.items[0].htmlLink;
  var event_id = link.split("eid=")[1];
  Logger.log([link, event_id]);
}
```

##イベントの編集画面への直リンク作成
htmlLinkは編集画面へのリンクではないため、編集画面への直リンクを作るには　https://calendar.google.com/calendar/r/eventedit/イベントID のようにイベントIDをくっつけると作成できました

###htmlLinkで開く画面
https://www.google.com/calendar/event?eid=イベントID で開く画面
![スクリーンショット 2017-12-25 8.38.16.png](https://qiita-image-store.s3.amazonaws.com/0/45849/c1b00dc3-262d-9856-1117-f80f58386f1e.png)

###イベントの編集画面
https://calendar.google.com/calendar/r/eventedit/イベントID で開く画面
![スクリーンショット 2017-12-25 8.39.30.png](https://qiita-image-store.s3.amazonaws.com/0/45849/aef0f399-4bb6-5def-cfeb-01a18beb3ad6.png)


##htmlLink以外に取得できる項目
[Events/Resource representations](https://developers.google.com/google-apps/calendar/v3/reference/events#resource) 

##Calendar APIを有効にする手順
1. スクリプトエディタを開く
2. 上部のメニューからリソースを開く
3. Google の拡張サービス...を開く
4. Calendar APIを「ON」にする（そしてOKをクリックする）
5. Google API コンソールのリンクをクリックする
6. Calendarで検索してGoogle Calendar APIを選択する
7. 「有効にする」ボタンをクリックする

[詳しくはこちら](https://developers.google.com/google-apps/calendar/quickstart/apps-script)

手順4でOKをクリックするとモーダルが閉じるので、7までやってからOKをクリックするとよいかも

#取得できなかったコード

最初はこれで取得できると思っていましたが、hoge@google.comというidが返ってきました
欲しいidはこれじゃなかったのでいろいろ調べてCalendar APIにたどり着いたのでした

```js:Code.gs
function get_event_id(){
  var calendar = CalendarApp.getCalendarById("primary");
  var events = calendar.getEventsForDay(new Date());
  var events0_id = events[0].getId();
  Logger.log(events0_id);
}
```

#おわりに
Calendar Serviceで実現できそうな気もしながら色々調べて試してみた結果できなかったため、APIを利用して取得してみました
本当はできるんじゃないかとまだちょっと思っていますが、APIで実現できたので今回はその方法を書いてみました


#参考

- [Google Calendar API (calendar/quickstart/apps-script)](https://developers.google.com/google-apps/calendar/quickstart/apps-script)

- [Calendar Service](https://developers.google.com/apps-script/reference/calendar/)
- [Events/Resource representations](https://developers.google.com/google-apps/calendar/v3/reference/events#resource) 
- [calendar/quickstart/apps-script](https://developers.google.com/google-apps/calendar/quickstart/apps-script)
CentOS7にPython3をyumでインストール

# 目的
- CentOS7にPython3(Python3.6)をyumでインストールしたい

# 環境
- OS: CentOS Linux release 7.0.1406 (Core)
- Kernel Version: 3.10.0-123.el7.x86_64

# 手順
IUS Community Project のリポジトリを追加

```
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
```
Python3.6をインストール

```
# yum install -y python36u python36u-libs python36u-devel python36u-pip
```
RDS Consoleの新旧UI比較

<a href="https://qiita.com/advent-calendar/2017/relux" target="_blank">Relux Advent Calendar</a>25日目です。

RDSのWebコンソールは現在、新旧2種類のUIを選択して使用できます。
UIの切り替えは、Dashboardの上部に表示される切り替え用のリンクをクリックすることで可能です。
![Screen Shot 0029-12-25 at 7.06.05.png](https://qiita-image-store.s3.amazonaws.com/0/13038/6af929e7-fd5a-d246-8f4f-16fd668adcaa.png)
![Screen Shot 0029-12-25 at 7.06.28.png](https://qiita-image-store.s3.amazonaws.com/0/13038/d67fb6e5-07da-4bf7-1baf-465a5777cfbe.png)


このリニューアルで追加されて嬉しかったもの、ちょっと不便になったと感じるものとその代替手段をご紹介します。

## 【便利】一覧にPriority tierを表示できるようになった

旧UIでは一覧やdetailでは表示されず、tierの値を確認するには編集画面へ入る必要がありました。
![Screen Shot 0029-12-25 at 7.46.03.png](https://qiita-image-store.s3.amazonaws.com/0/13038/1bbaebc3-4d63-a11d-ce4e-2248870f83ea.png)

新UIではtier値を一覧に表示することが可能で、同一クラスタのインスタンス同士での比較が容易になりました。
![Screen Shot 0029-12-25 at 7.18.01.png](https://qiita-image-store.s3.amazonaws.com/0/13038/a32fa264-6a82-d592-599b-3b4579c53a2c.png)

## 【便利】Aurora Replica作成時にParameter Groupを選択できるようになった

旧UIでは、Aurora Replica作成時にParameter Groupの選択ができませんでした。
インスタンスを立ち上げるとParameter Groupはdefaultになっており、自分で作成したParameter Groupを使用するには 作成 → 変更 → 再起動 という手順を踏む必要がありました。

新UIでは作成時に指定できるため、作成後に設定変更・再起動をすることなくすぐに使用することができます。
![Screen Shot 0029-12-25 at 7.28.42.png](https://qiita-image-store.s3.amazonaws.com/0/13038/ded302e3-48e7-e8b2-54fe-753c8365b011.png)


## 【不便】複数インスタンスでのモニタリング比較ができなくなった

旧UIでは、一覧で複数インスタンスを選択した状態でモニタリング画面を開くと、グラフが重ねて表示されてパフォーマンスの比較をすることができました。
![Screen Shot 0029-12-25 at 7.31.06.png](https://qiita-image-store.s3.amazonaws.com/0/13038/50beca62-33b6-5ede-d6f2-038b8560027b.png)

新UIではインスタンスを1つずつしか選択できず、RDSコンソールでの比較はできません。
#### モニタリングはCloudWatchですれば良い
CloudWatchであれば複数インスタンスのグラフを重ねて見ることができます。
カスタムダッシュボードに設定しておいたり、必要な時に作成すれば事足ります。
![Screen Shot 0029-12-25 at 7.40.21.png](https://qiita-image-store.s3.amazonaws.com/0/13038/3f4f411e-5097-7094-b263-1369551ba6e6.png)
新UI移行後はCloudWatchで見れば良いでしょう。

## まとめ
Aurora Clusterを使用していて欲しかった機能が追加され、とても便利になりました。
新UIをまだ使った事がないという方は、とりあえず切り替えてみると良いと思います。使いづらければ戻すこともできるので。

新UIはユーザの意見を元に改善したものらしいです。このように改善してもらえるのはとてもありがたいことです。
RDSだけでなく、他サービスのUIも同じように改良されることを強く期待しています。
Chromeの便利なプラグイン


# vim風にChromeを使えるようにする

## vimium

http://vimium.github.io/

Chromeの操作を、vimキーバインドで使えるようにできるプラグインです。

詳しくはこちらの記事が参考になります。
[Chromeをvimライクに使えるようにする](https://qiita.com/satoshi03/items/9fdfcd0e46e095ec68c1)

# プロキシの設定を切り替える

## Falcon Proxy

[Falcon Proxy](https://chrome.google.com/webstore/detail/falcon-proxy/gchhimlnjdafdlkojbffdkogjhhkdepf?hl=ja)

プロキシ設定を環境ごとに切り替えるプラグインです。

![image](https://qiita-image-store.s3.amazonaws.com/0/132118/245d1c88-93a7-a41e-717b-48065a022440.png)

インストールすると、ツールバーにアイコンが追加されますので、
それをクリックすると、設定の切り替えができます。
私は、通常使う用と、休日のテスト用の設定を切り替えたりしています。
ノートパソコンとかで複数の場所でプロキシを切り替えるような場合にも利用できるかと思います。

## Proxy SwitchyOmega

PCの入れ替えをしていたら、↑のFalcon Proxyがなくなったことに気づきました。

[本家](https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif)

いろいろ探してみて、このSwitchyOmegaが秀逸だったので記事を更新しました。
自動でProxyを切り替える機能があってURLに応じて、利用するProxyを変えることができます。
ぜひ使ってみてください。
Google Homeを使って、Discordに音声で文字入力してみた

#概要
GoogleHomeに「Discord XXX」というと、Webhookが発行されたDiscordのテキストチャンネルに送信する。

#Discordでwebhookの発行
サーバー設定＞Webhooks＞Webhookを作成
・名前は適当な名前を設定
・チャンネルは送信したいチャンネルを選択
・WEBHOOK URLを控えておく


#IFTTTで設定
https://ifttt.com/
ログイン＞右上のアカウント＞NEW Applet
・+thisをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/3c22c9cd-accd-a71d-0c39-3a67d60d2d8c.png)

・検索窓に「go」入力し、「Google Assistant」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/d63fbefa-8a2e-879e-f58a-aae9e6cab59b.png)

・connectする（画面に従って承認）
　＊connectするアカウントはGoogle Homeにリンクしているアカウントにすること
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/f4f5e474-b9a7-09cc-1761-37697224898d.png)


・画像の通りにクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/082712fc-ec93-0a5f-2616-46e963bb7ee8.png)

・「What do you want to say?」に「Discord $」と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/315c82e8-ec5b-5cf8-80f6-da1f7eb972cc.png)

・「What do you want the Assistant to say in response?」に「Discordで $ を送信しました」と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/99404b2c-3db8-9a5e-b4f9-f4fa8b039f62.png)

・「Language」を「Japanese」に変更

・Create triggerをクリック

・+thatをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/a17d77b8-183d-f670-4c93-0b66fa8d5d7b.png)

・検索窓に「web」入力し、「Webhooks」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/f63135ec-1eae-e67c-30ca-bb2f09c7584e.png)

・「Make a web request」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/0f41821a-286d-9cf1-3fd1-a95c1f5806be.png)

・「URL」に WEBHOOK URL と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/6533052d-a537-3f2a-af10-0602d7f1cb7f.png)

・「Method」を「POST」に変更
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/93c81894-8d23-0c6f-eaec-bf4ef4cc2ea9.png)

・「Content Type」を「application/json」に変更
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/16387e56-537d-3497-170b-3c5b1fe24578.png)

・「Body」に { "content":"{{TextField}}"} と入力
　＊応用 { "content":"{{TextField}}" , "username":"syado" , "avatar_url":"http://....."}
　　content：メッセージ内容
　　username：送信者のアカウント名を設定変更可能
　　avatar_url：アイコンをURLの画像に変更
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/160ad404-6842-cac1-5ca4-ea4e00f3bee0.png)


・Create actionをクリック

・自分がわかりやすい説明を書く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192511/3ef07ae1-e477-7d84-397c-f9bd5efa7170.png)

・Finishをクリック
Firebirdで配列

こんにちは。
これは Delphi Advent Calendar 2017 最終日の投稿です。

最終日だというのに、おいらなんかがノコノコ出て来て良いのか？って話もありますが。
よろしくお願いします。

Firebirdで配列を使いたい。と思って挑戦した時の顛末です。
データロガーを作っているのですが、DoubleとBooleanの配列をテーブルに格納したかったというところから始まっています。

##環境
Delphi 10.2.2 
Firebird 2.5
Windows10
の環境での話です。


##取り敢えず、データベースを作成して、テーブルを作成します。
isqlやFrameRobin等を使用して、次のテーブルを作成しました。

```sql
CREATE TABLE LOG_DATA(
　LOG_NO    INTEGER   NOT NULL,
　LOG_COUNT INTEGER   NOT NULL,
　GET_TIME  TIMESTAMP NOT NULL,
　SET_ANLG  DOUBLE PRECISION[32],
　SET_DGTL  SMALLINT[32],
　GET_ANLG  DOUBLE PRECISION[512],
　GET_DGTL  SMALLINT[1024],
　CONSTRAINT PK_LOG_DATA_ID PRIMARY KEY( LOG_NO, LOG_COUNT )
);
```

PRIMARY KEYはLOG_NO, LOG_COUNTとしておきます。

SET_ANLG, SET_DGTL, GET_ANLG, GET_DGTLの4項目。
型定義の後に`[]`で添字が付けられているのが配列項目になります。



##Delphiから、 FireDACを用いてこのテーブルにアクセス
FDConnectionを置いて、Server, Database, UserName, Password等のパラメータをセット。

そしてFDQueryを置いて、FDConnectionを関連付けて、
FDQueryのSQLに

```sql
　SELECT * 
　FROM LOG_DATA
　WHERE LOG_NO = :LogNo AND LOG_COUNT = :LogCount
```
と設定。
実際の読み込みは、

```delphi
　FDQuery.ParamByName( 'LogNo' ).AsInteger    := _LogNo;
　FDQuery.ParamByName( 'LogCount' ).AsInteger := _LogCount;
　FDQuery.Open;
```

とすれば、_LogNo, _LogCountで指定した行が返されます。


##さてさて、配列部分はどうアクセスすれば良いのでしょうか？

```delphi
　v := FDQuery.FieldByName( 'GET_ANLG' )[0].AsFloat;
```

みたいに書けるのかと思ってみたのですが、違うようです。

色々試してみました。

```delphi
　v := FDQuery.FieldByName( 'GET_ANLG[0]' ).AsFloat;
```

と書くと動きました。

でも、これだと、for文で回して配列内の全ての項目にアクセスする場合、

```delphi
　for i := 0 to 512 - 1
　　v := FDQuery.FieldByName( 'GET_ANLG[' + i.ToString + ']' ).AsFloat;
```

と、かなり冗長というか、何のための配列なの？となってしまいます。

##もっと違う方法があるはず
もっとスマートな方法が必ずあると思い、Helpを舐め回しました。
ありました！もう少しスマートなやり方が！

TArrayFieldのFieldValuesを使う方法です。
早速書き換えてみます。

```delphi
for i := 0 to 512 - 1 do
  v := TArrayField( FDQuery.FieldByName( 'GET_ANLG' ) ).FieldValues[i];
```

TArrayFieldにキャストして、FieldValuesにアクセスするというのが基本みたいです。
FieldValuesはVariantの為、AsFloatとか無くてもそのままDoubleが帰って来ます。(vがDoubleで宣言されている場合)
個人的にはVariantはあまり使わないのですが、背に腹は代えられません。。。


このFieldValuesはTArrayFieldのデフォルトプロパティなので

```delphi
for i := 0 to 512 - 1 do
  v := TArrayField( FDQuery.FieldByName( 'GET_ANLG' ) )[i];
```

でアクセスできました。
うん、少しはスマートになりました。


##もう一声って感じで。

for文で回す中で、毎回毎回FieldByNameが走るとなると、いくらDictionaryを使っているとはいえ、
パフォーマンスに難がありそうです。

そこで、

```delphi
var
　fld: TArrayField;
```

と宣言してfor文の前にfldに該当のTArrayFieldを取り出します。

すると、

```delphi
　fld := TArrayField( FDQuery.FieldByName( 'GET_ANLG' ) );
　for i := 0 to 512 - 1 do
　　v := fld[i];
```

と、かなりスッキリしました。

##あとがき
みなさん、あまりDBで配列使わないみたいで、情報がネットにも殆どありませんでした。
そもそも、DBで配列がサポートされて、それをFireDAC等のミドルウェア(?)がサポートしたのも
最近っぽいのでいたしかたないのかと思いますが。

実際、上記テーブルに、1秒間隔でログデータを落としていますが、今の所、問題なさそうです。
これから、長期稼働テストとかしないといけませんけど。。。



#それでは、みなさま、よいお年をお迎えください。
今年もお世話になりました。
来年もよろしくお願いいたします。
エンジニア出身のコミュ障がプロダクトマネージャー的お仕事をするようになった話

少し前までDOOR賃貸で、最近はマッハバイトでプロダクトマネージャーみたいな仕事をしていますtsuchiyamaです。

これは、[Livesense - 学 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/livesense-gaku)の25日目の記事で
エンジニアが企画もしたいと。ディレクターに、プロダクトマネージャーになりたいと思って5年たったらこうなったを書いてみたいと思います。
もし似たような思いを持った人がいて、背中を押す力になれたら幸いです。

# 難ありエンジニアが企画に興味を持ち始めるまで
8年前、サーバサイドエンジニア職で入社してWEBアプリ開発を4年くらいやっていました。既存、新規を跨いで商用サイトの基本は一通り経験したかな。くらいです。

突然ですが、当初の私は相当「いけ好かないエンジニア」でした。
仕様を決めて下さい、詳細が決まってないと見積もりできません。決めるのは自分の仕事ではありません。みたいな感じでしょうか。当時の上司に「tsuchiyamaとは仕事がしづらいと同僚がいっている」と伝えられて、枕を濡らしました。

そんな経験からディレクターの意図を汲み取ったり、提案したり、相手の言葉で話したり、謙虚(自分が正しいという勘違いをしない)であろうと努めたりといった取り組みを始めました。そうするうちに「こうするともっと良くなるかも」とか「こうしないと企画が失敗しても原因を絞れない」とか考え始めたんですね。「自分で企画を主導したい」と考えるまで時間はかからなかったように思います。謙虚どこいった。

**伝えたいことは**コミュニケーションスキルの習得や性格の矯正は

* 社会人になってからでも十分できる(と信じて地道にとりくむこと)
* 現実を受け止めて、治しやすいものから取り組みましょう。状況がよくなるだけでなく、自分に新しい感覚を与えてくれるかもしれません。
* 私は惨憺たる状態でした。その分時間はかかったかもしれませんが、なんとかなるよ！

# エンジニアからディレクターになって挫折して、エンジニアになった話
4年ほど前、エンジニア兼企画をやりたいと上司に相談。結果、一度エンジニアを辞めてディレクターになることに。当時はエンジニア兼ディレクターなキャリアパスがなかったんですね。

新しい事業部でディレクター見習いに。これが全くうまく行きませんでした。色んな背景があるのですが、ディレクター上司からは教えてもらえず、メンバーのエンジニアからは信頼されず、自分自身と他人からの否定がつらくてを辞めたいと思ったこともありました。

当時を振り返って、自分で状況俯瞰して克服のための行動できたことは、ほとんどなかったように思います。なぜそれでも今につながっているかというと、当時の私を肯定して、助けてくれる人がいたからです。

大きくは二人。一人は当時のエンジニア部長で「もう一度エンジニアに戻ってこい」と手を差し伸べてもらい、その後も多くのアドバイスを頂きました。もう一人は当時の恋人、今の妻です。二人に心理的な安全をもらってあの時期を乗り越えることができたと思っています。

**ここで伝えたいこと**

* 場所はどこでも構いません。ありのままの自分と付き合ってくれる人は非常に心強い存在です。周囲のあらゆる人との関係でそうなるための挑戦をしましょう。当時の状況もそういった関係構築を心がけていれば全く違ったかもしれません。

# エンジニアをしながら企画をできるようになった話
それから(先の一件からしばらくしてから)はエンジニアとして貢献することで、私の中でのチームにおける存在価値に不安がなくなり、人間が縮こまっていた状態がなくなったように思います。

その上で、エンジニアからディレクターへ企画領域で協力することで信頼を積み上げながら、ディレクター以外でも企画を提案できるようなチーム文化を作っていくようにしました。
その過程の後半では、嬉しいことに、私の得意分野ならディレクターに相談をもらえることもありました。

**ここでの経験から出来るアドバイス**

* 異業種から企画職に広げるなら、ベース職種を必ず強みとして動ける状態を維持してください。私の様な転向はリスクが高いと考えます。
* 企画方面での信頼や実績を作るときは、ベース職種・スキルと掛け算できそうな企画を小さいものから行うことをオススメします。成功率、吸収率ともに高いです。
* 企画失敗から学ぶこと自体がスキルを要します。というのも失敗時の原因が複数ある状態では学べないことがあるからです。原因が1つ、または結果内容毎に特定できる企画設計を心がけましょう。また、実施ディティールも要因と成り得ることを念頭に置きましょう。

# エンジニアがプロダクトマネージャー的お仕事をするようになった話
1年前、企画兼エンジニアになりたいと思ってから4年くらいたって、プロダクトマネージャー的お仕事をする立場になりました。
的と言うのは、まだ社内にプロダクトマネージャーという名前もなく、私も役職についていなかったので「役割」みたいな状態でした。
やっていたことは

* サービスの規定
* 年間戦略の策定
* 各種率改善・流入獲得企画の立案・実施・マネジメント
* チームビルディング
* UX設計
* SEO設計
* 外部折衝
* 事業計画策定(期中修正)

どれもが誰かの助けを借りてやっとの状態ですが、ようやく成りたかった"モノ"になれてきた感覚がありました。
この頃になるとプロダクトマネージャーという役割を意識していて、でも明確に定義できなくて、今に続いています。

**それでも大事に思っていたことは以下のようなものです**

* 確実に改善し続ける
* 改善は可視化する
* 最大のフォーカスはユーザーに
* 事業を蔑ろにしない
* 今の解決のために後の問題点を作らない
* ゴールから逆算する
* チームメンバーの力を頼る
* チームメンバーの力になる
* チームとして足りないものを探して埋める
* 全部はできないことを認識して行動に反映する(理想的よりも現実的な行動を行う)

# さいごに

さて、色々と書きましたが、発想の飛躍や説明不足の感が否めず、混乱させていたら申し訳ありません。
この記事を読んでくださったみなさんの中で、開発職から企画に領域を広げるような方の参考になれば幸いです。

以上、長々とお読みいただきありがとうございました！
初心者に役立つgitコマンド

P&Dアドベントカレンダー25日目担当seaaaaaaaaaです。

##はじめに
初心者の私がよく使っているGitHubのコマンドを紹介したいと思います！！
(注)私は2年前まで実家にネット環境がなく、PCを全く使ってこなかった人間です。
 

## 1. commitの取り消し

今回は`reset`のやり方について紹介します。
(`revert`に関しては参考記事の方を参考にしてください)

```git:zsh
% git log


commit xxxxxxxxxxxxxxxxxxxxx //以下ハッシュ値 // 注目
Author: アカウント名 <登録メールアドレス>
Date: Mon Dec 24 17:05:08 2017 +0900

　　　yyyy //commitした時のメッセージ
```

```git:zsh
% git reset --hard ハッシュ値
```
`HEAD`：戻したい`commit`のハッシュ値

操作が終え、以下のようになっていると完了です。

```git:zsh
% git log


commit ハッシュ値　(HEAD -> branch名) // 左の()が追加されている
Author: アカウント名 <登録メールアドレス>
Date: Mon Dec 24 17:05:08 2017 +0900

　　　yyyy //commitした時のメッセージ
```

### `reset`と`revert`の違いって？
`reset`は「`commit`を取り消す」という作業になるため、`log`から確認ができなくなります。
`revert`は特定の`commit`を元に戻すもので、`commit`が削除されることはありません。
個人的には`log`を開いたときにわかりにくくなったりするのであまり使うことはないですが、
共同開発で他の人が後から見ても確認ができるので、一般的に推奨されているのは`revert`のようです。


## 2. resetで見れなくなったlogも見る

今回は`reflog`について紹介します。

```git:zsh
% git reflog

ハッシュ値 HEAD@{num}: コマンド: 動作内容

(例)
de688a4 HEAD@{0}: reset: moving to de688a4fbac0526f8671c
```

`num`:Gitを操作した記録が番号順になっている。０が最新。

`reflog`はHEADが辿ってきた履歴を確認することができます。
つまり、これまでにそのプロジェクトで行なった`git`コマンドとその内容を最新のものから順に確認することができます。
なので、上記で述べた`reset`による確認できなくなる`log`も見ることができます!!!!
ただ、どのcommitにハッシュ値が対応してるかなどはわかりにくくなるので注意です。

### (注) reflogは最強ではない！？
`add`しただけで`commit`してないものがある時に、`reset --hard`をしてしまうと`add`した内容は復元できません。
`add`すらしてないものももちろん消えます。

## 最後に
今回は2つのことについてまとめてみました。
開発していく中で役立ったものがあったら、また書いていきます(^0^)
その他、不適切な部分等あればご指摘ください。

## 参考資料
・[[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法](https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe)
・[【gitコマンド】いまさらのrevert](https://qiita.com/chihiro/items/2fa827d0eac98109e7ee)
２０１７年のSRE勉強会・イベント

# ２０１７年のSRE勉強会・イベント

- 2016-07-25 [SRE Tech Talks Site Reliability Engineeringにまつわるエトセトラ](https://connpass.com/event/34825/)
    - [(レポート)SRE Tech Talks 第1回 #sretalks](https://dev.classmethod.jp/event/etc-on-site-reliability-engineering/)

- 2017-01-30 [Google、書籍「Site Reliability Engineering」の無料公開を開始。インフラや運用をソフトウェアで改善していく新しいアプローチ](http://www.publickey1.jp/blog/17/googlesite_reliability_engineering.html)

- 2017-01-30 [SRE Tech Talks #2](https://techplay.jp/event/609456)
    - [Arukasの運用事例と、末永くインフラ運用していくためのTips（SRE Tech Talks #2）](https://www.slideshare.net/sakura_pr/arukastipssre-tech-talks-2)
    - [SREグループができてこの半年間やってきたこと](https://speakerdeck.com/isaoshimizu/sregurupugadekitekofalseban-nian-jian-yatutekitakoto)
    - [SRE Tech Talks #2 に行ってきた。](https://www.wantedly.com/companies/mixi/post_articles/50556)
    - [SRE Tech Talks #2 に参加してサービス運用の事例を聞いてきた](http://kakakakakku.hatenablog.com/entry/2017/02/05/002016)
    - [SRE Tech Talks #2 に参加してきた](http://blog.ginbear.com/entry/2017/01/31/202200)

- 2017-07-25 [hbstudy#74 第74回： SRE大全: 序章](https://hbstudy.connpass.com/event/61687/)
    - [hbstudy#74 SRE大全：序章 活動報告](https://heartbeats.jp/hbblog/2017/07/hbstudy74-sre.html)
    - [『第74回： SRE大全: 序章』hbstudy#74 に参加してきた](http://blog.ginbear.com/entry/2017/07/25/234243)

- 2017-08-22 SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム 日本語版発売

- 2017-08-17 [hbstudy#75 第75回： SRE大全: メルカリ編](https://hbstudy.connpass.com/event/62296/)
    - [「hbstudy#75 SRE大全：メルカリ編」で登壇しました](http://tech.mercari.com/entry/2017/08/21/120000)

    >行きました。
    >100名以上きました。
    >SREへの注目なのか、ユニコーン企業であるメルカリへの注目なのかは判断つかず。
    >Q「（メルカリキャッシュ障害の）担当者への賞罰のようなものは？」A「ここに立ってます」(笑)

- 2017-08-24 [hbstudy#76 第76回： SRE大全: XFLAG スタジオ編](https://hbstudy.connpass.com/event/62338/)
    - [「hbstudy＃76 SRE大全: XFLAG スタジオ編」で発表しました](https://xflag.com/blog/hbstudy76_sre_xflag.html)
    - [hbstudy #76 「SRE大全: XFLAG スタジオ編」 - YouTube](https://www.google.co.jp/search?q=SRE大全:+XFLAG+スタジオ編&gws_rd=cr&dcr=0&ei=vR5AWrHSAcqD8wXDxKPQCQ)

    >行きました。
    >「SREとは、古いシステムを確実に捨てることである」が強く印象に残りました。

- 2017-09-25 [SRE Meetup Tokyo @ Google JP オフィス](https://connpass.com/event/66219/)

    >行きました。
    >200名以上きて、部屋に入らないので食堂開放。
    >SREの熱気を感じました。

- 2017-10-02 記事 [Site Reliability Engineering （SRE）ー 社内勉強会を開催しました。（前編）](https://dev.classmethod.jp/study_meeting/site-reliability-engineering-in-house-study-sessions-part-1/)

- 2017-10-02 記事 [Site Reliability Engineering （SRE）ー 社内勉強会を開催しました。（後編）](https://dev.classmethod.jp/study_meeting/site-reliability-engineering-in-house-study-sessions-part-2/)

- 2017-10-18 記事 [http://www.ap-com.co.jp/blog/archives/5352](SRE(Site Reliability Engineering)勉強会を実施しました)

- 2017-11-20 [hbstudy#79 SRE大全：クックパッド編](https://hbstudy.connpass.com/event/70180/)
    - [イベント資料一覧](https://hbstudy.connpass.com/event/70180/presentation/)
    - [hbstudy#79 「SRE大全: クックパッド編」 - YouTube](https://www.youtube.com/watch?v=G7_gkpwzNiY)

    >行きました。
    >Prometheusの話が印象に残りました。
describeを利用してテストする範囲を絞る方法

# はじめに
テストプログラムを作成しているときに、あるグループだけ実行したいという時があるかもしれません。
そのときにはdescribeを使って、テストをグループ化するとテストがしやすくなります。

# テストのグループ化と実行

下記は例で記載しているコードのため動きません。

```elixir:test/sample_test.exs
defmodule SampleTest do
  use ExUnit.Case
  doctest Samplelog

  describe "Get.Test" do
    test "Get info" do
      %{status_code: status_code} = ExBacklog.get(@test_url, @api_key)
      assert status_code == 200
    end
    # その他テスト関数がいっぱい
  end

  describe "Put.Test" do
    test "Put info" do
      %{status_code: status_code} = Sample.put(@test_url, @api_key)
      assert status_code == 200
    end
    # その他テスト関数がいっぱい
  end
```
例のようなテストコードがあって、Get系のテストだけ動かしたい場合は下記のコマンドを実行すれば良いです。

```bash
$ mix test --only describe:"Get.Test"
```
CentOS7 コマンドラインの編集

コマンドラインのカーソルは、カーソルキー(矢印キー)を使うことで移動できます。
しかし、カーソルキーはキーボードの隅の方にあることが多いため、キー入力の歳にはどうしてもホームポジションから大きくずらすことになってしまいます。
カーソルキーはなるべく使わず、コントロールキーなどを利用したキー入力をします。
Linuxを使っている間は、カーソルキーは存在しないものと思って操作します。

#行頭・行末へのカーソル移動
|コマンド|内容|
|:---:|:---:|
|Ctrl + b|後方に1文字ぶん移動する|
|Ctrl + f|前方に1文字ぶん移動する|
|Ctrl + a|行頭に移動する|
|Ctrl + b|行末に移動する|

#単語単位でのカーソル移動
|コマンド|内容|
|:---:|:---:|
|Meta + b|後方に単語1つぶん移動する|
|Meta + f|前方に単語1つぶん移動する|

#文字の削除
|コマンド|内容|
|:---:|:---:|
|BackSpaceキー、またはCtrl + h|カーソル位置の後方に1文字削除する|
|Deleteキー、またはCtrl + d|カーソル位置の1文字を削除する|
|Ctrl + w|後方にスペース区切りで1単語ぶんを削除する|

#カットとヤンク
|コマンド|内容|
|:---:|:---:|
|Ctrl + k|カーソル位置から行末までを削除する|
|Ctrl + u|カーソル位置から行頭までを削除する|
|Ctrl + y|最後に削除した内容を挿入する|

#コマンド履歴
|コマンド|内容|
|:---:|:---:|
|Ctrl + p、または矢印上キー|1つ前のコマンド履歴に移動する|
|Ctrl + n、または矢印下キー|次のコマンド履歴へ移動する|
|Ctrl + r|履歴を遡ってインクリメンタル検索する|