OmniAICreator/Qiita-1.07M huggingface dataset:
【サルが書く】cakephp2でログローテーションを簡単に行う方法

わきゃ！

## cakephp2でログローテーションを簡単にする方法

アプリケーションにおいて、時系列でなにが起きているかを把握するのがログです。
しかし、ログファイルを一つにまとめて管理をしてしまうと、あとで分析する時に「ファイルがおもすぎてひらけない！」なんてことになりかねません。
そのために、ログローテーションを行うことで、ログファイルの整理整頓を行いましょう。

```php:app/Config/bootstrap.php
// デフォルト設定
/**
 * Configures default file logging options
 */
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
    'engine' => 'File',
    'types'  => array('notice', 'info', 'debug'),
    'file'   => 'debug',
));
CakeLog::config('error', array(
    'engine' => 'File',
    'types'  => array('warning', 'error', 'critical', 'alert', 'emergency'),
    'file'   => 'error',
));

```

## 日にちごとにログローテーションを行う

ログローテーションの定石としては日付ごとにログを分割する方法があります。

```php:app/Config/bootstrap.php

/**
 * Configures default file logging options
 */
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
	'engine' => 'FileLog',
	'types' => array('notice', 'info', 'debug'),
	'file' => date('Ymd') . '_' . 'debug',
));
CakeLog::config('error', array(
	'engine' => 'FileLog',
	'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
	'file' => date('Ymd') . '_' . 'error',
));
```

date()を使用することで、ファイル名にログを書き出した日付を付与してくれます。

## cakephp2.4以降ではオプションが追加されました

>・size 
基本的なログファイルのローテーション実装に使われます。 指定したサイズにログファイルのサイズが達した場合、現在のファイルが、 タイムスタンプをつけたファイル名に変更され、新しいログファイルが作成されます。 整数バイト値か、 『10MB』、『100KB』 など人が読みやすい文字列が使えます。 デフォルトは 10MB です。　size に false をセットすると、 下記の rotate オプションが無効になります。
>・rotate 
ログファイルは、削除される前に指定した回数ローテーションします。 もし、値が 0 の場合、古いファイルはローテーションする前に削除されます。デフォルトは 10。
>・mask 
新規作成されるファイルのパーミッションをセットします。もし、空のままの場合、 デフォルトのパーミッションが使用されます。
>>https://book.cakephp.org/2.0/ja/core-libraries/logging.html


```php:app/Config/bootstrap.php

/**
 * Configures default file logging options
 */
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
    'engine' => 'FileLog',
    'types' => array('notice', 'info', 'debug'),
    'file' => 'debug',
    'size' => '7MB', // 指定したファイルサイズでログファイルを分割してくれる
    'rotate' => 7, // 指定した数分だけログファイルを保持してくれる。それ以前のものは自動で削除。
));
CakeLog::config('error', array(
    'engine' => 'FileLog',
    'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
    'file' => 'error',
    'size' => '7MB', // 指定したファイルサイズでログファイルを分割してくれる
    'rotate' => 7, // 指定した数分だけログファイルを保持してくれる。それ以前のものは自動で削除。
));
```
onlineTool > EggTimer > 目的をURLで指定できる

```txt:動作環境
Windows 10 Pro (64bit) バージョン 1709
Google Chrome バージョン: 66.0.3359.117（Official Build） （64 ビット）
```

### 関連

[onlineTool > カウントダウン タイマー オンライン > ブラウザタブにカウントダウン残り時分秒が表示される | notification:終了時の明示](https://qiita.com/7of9/items/8895a93e1020bf86d046)

### 複数のタイマー動作

上記のリンク先のツールにて複数のカウントダウンタイマーを実行した時、「このカウントダウンは何のためだっただろうか？」となる (少なくとも7of9は)。

「目的」を残すことで、そのカウントダウンの詳細は忘れて、別の作業に邁進できる。

### e.ggtimer.com

http://e.ggtimer.com/

リンク先に以下のような記載例がある。

```
http://e.ggtimer.com/5minutes
http://e.ggtimer.com/1hour
http://e.ggtimer.com/30 (defaults to seconds)
```

### 裏技

URL指定には`#`付のコメントが残せる。
例として

http://e.ggtimer.com/3hour45minutes#WRF
とすると、「将来参照時」に「WRFの処理だ」というのが分かる。

適宜適切なコメントをURLに含めることで、3つ以上のキッチンタイマーの運用での失敗確率が低減するだろう。

### 備考

もともと使っていた下記のツールでも同様のことができる。

[onlineTool > カウントダウン タイマー オンライン > ブラウザタブにカウントダウン残り時分秒が表示される | notification:終了時の明示](https://qiita.com/7of9/items/8895a93e1020bf86d046)

軽い方法を使うといいだろう。
プルリクのコメントにタグ付けして意図を伝える

元ネタはこちらです。
[レビューコメントにラベルをつけるだけで開発効率があがって幸せになれそうな話](https://qiita.com/godgarden/items/3ea57a7ee6dbff1df6e6)

こちらの記事にshy_azusaさんが[shields.io](http://shields.io/)のラベルをつけると見易いですよ、とありましたが、私のチームでは下記のchrome extension　を導入して実現しました。

[Text Blaze](https://chrome.google.com/webstore/detail/text-blaze/idgadaccgipmpannjkmfddolnnhmeklj)

| shortcut|snippet |sample|
|:-----------------|------------------|------------------|
| /must| `![badge](https://img.shields.io/badge/review-must-red.svg)`| ![badge](https://img.shields.io/badge/review-must-red.svg)|
|/imo|`![badge](https://img.shields.io/badge/review-imo-ff69b4.svg)`|![badge](https://img.shields.io/badge/review-imo-ff69b4.svg)|
|/nits|`![badge](https://img.shields.io/badge/review-nits-green.svg)`|![badge](https://img.shields.io/badge/review-nits-green.svg)|
|/ask|`![badge](https://img.shields.io/badge/review-ask-blue.svg)`|![badge](https://img.shields.io/badge/review-ask-blue.svg)|

特に若手に指摘する場合、萎縮しないように気を遣っているみなさんの心が少しでも楽になるといいな、と思います。
Sensuで最初にやるべきことについて。

Sensuで登録する際に、まずどこからやればいいかについて公式ページのどこにもGetting Started的なページがなかったので苦戦した記録。一応中の人ですがこれﾜｶﾘｽﾞﾚｴﾔってなったので。   
# 0. Sensuってなんぞや
サービス監視ソフトの方じゃなくて、「多通貨」「多プラットフォーム」対応の投げ銭システム。公式サイトは[こちら](https://sensu.tips/)。
公式で対応しているのはTwitter/Discord/Telegram/LINE。ただ、作りたい人が自由にプラットフォームを作って対応可能なので、個人IDがとれるものなら作りさえすれば何でもできそう。実際、Sensu対応を謳いながら特定通貨のみ対応させることも難しくない（というか早く見たい）。
# 1. アカウント登録
いわゆる「どこでも簡単に投げ銭ができる！」とは言っていますが、多プラットフォームで使う前提で考えると登録を最初にしたほうがスムーズになります。
1. Sensu公式サイトの[登録ページ](https://sensu.tips/account/new?hl=ja)を開く。
2. ざくざくとID/Passを入力し、利用規約を確認、CAPCTHAを通過。
   (パスワードは確か8文字以上で通る。CAPTCHA楽になったもんだ。)
   ![image.png](https://qiita-image-store.s3.amazonaws.com/0/147334/91744332-4d6e-fb98-2a4c-46fd8bf38d7d.png)
3. アカウント作成が終わるのでログインをクリックし、先ほど入力したID/Passを入力、CAPTCHA通過後ログイン。
ここまでできりゃアカウント作成はおしまい。

# 2. 連携
「agreeコマンドを入力すりゃ使える」っていう風に言われているけども、連携すればそもそもそれすら打つ必要ない感じ。そもそもアカウント作成時に利用規約に同意しているからね。
今のところ公式プラットフォームの数が少ないので全部書く。公式以外もプラットフォームを作れるようになっているからその説明はこの後で。

## Telegramでの連携
1. 公式ページの[公式サービス](https://sensu.tips/official_service?hl=ja)よりリンクを確認。[Tipsensubot](https://telegram.me/tipSensuBot)。
2. Telegramにて追加。1to1のページに移されるのでそこで待機。
3. 公式サイトのログインページで
   ログイン→連携タブ→連携から連携コードを発行。
4. ここで発行した連携コードを使って、TelegramのtipSensuBotに対してlinkコマンドを送信。   
   Example: `/link <連携コード>`
5. 連携完了した旨の表示が出ればOK。

連携コードに関して、「使われるとまずい」って書いてあるから要は失敗してもOKなところで使えばいいやー、って発想でほかのプラットフォームでも連携していく。

## Discordでの連携
1. 公式ページの[公式サービス](https://sensu.tips/official_service?hl=ja)より[公式サーバーに参加](https://discord.gg/sVh2GWq)。   
右側に書かれているものを見ればOK。左側は自サーバーに追加するときのやつ。
2. 下の画像のように右側にアイコンが見えるので、Sensu[BOT]を右クリックして[メッセージ]をクリックし、DMに呼ぶ。   
![SensuBOT,Discord](https://qiita-image-store.s3.amazonaws.com/0/147334/e167d0f6-cffc-8f22-264f-b8d982078b95.png)
3. DMにてTelegramと同様に連携コードを発行し、linkコマンドを送信。   
   Example: `./link <連携コード>`
4. 連携完了した旨の表示が出ればOK。

## Twitterでの連携
1. 公式ページの[公式サービス](https://sensu.tips/official_service?hl=ja)よりTwitterBotの[リンク](https://twitter.com/tipsensu)を確認。
2. ダイレクト…からDMにSensuを呼ぶ。   
   ![image.png](https://qiita-image-store.s3.amazonaws.com/0/147334/989206b0-3ddd-0d86-222e-1db2cb39772f.png)
3. DMにてTelegram/Discordと同様に連携コードを発行し、linkコマンドを送信。   
   Example: `link <連携コード>`
4. 連携完了した旨の表示が出ればOK。

## LINEやそのほか独自プラットフォームでの連携
今までのと同じように、「少なくともほかの不特定多数の方に見えないような場所で」連携させればOK。あくまでも連携コードは一回こっきりのものなので、基本正常に連携できていれば取られないが、怪しいのでは事前に確認を行う。

# 3. 実際にdeposit,withdraw,tip,rainを行う
ここに関してはここでまとめなくてもなんとなく想像できるが、ざくざくと書いておく。

- depositで入金アドレスを表示して入金
- tipでその人に贈る予約をする（相手が三日以内にbalanceなどで確認しなかったばあい、戻ってくる）
- rainで直近三日にそのプラットフォームで何かの動作をしている人にぶん投げ
- withdrawで引き出し
  （送れる料金は微妙に減るので、送金料が事前に決まっているもの相手に直接送らないこと！！！）

ベータ２からは公式以外でもサービスを作成することができるようになったので、自鯖用のBotとか自鯖のところで三日以内に操作している人にrainってこともできるようになってたりするので、できる人はやってみると幸せになれそう。
はぶふぁん。
Homebrewでnodebrew入れたらハマった

nodebrewのセットアップにハマった案件。

## nodebrewでnodeのインストールができない

```sh
$ nodebrew install-binary v6.10.0
Fetching: https://nodejs.org/dist/v6.10.0/node-v6.10.0-darwin-x64.tar.gz
Warning: Failed to create the file 
Warning: /Users/hikaru/.nodebrew/src/v6.10.0/node-v6.10.0-darwin-x64.tar.gz: 
Warning: No such file or directory
                                                                           0.0%
curl: (23) Failed writing body (0 != 847)
download failed: https://nodejs.org/dist/v6.10.0/node-v6.10.0-darwin-x64.tar.gz
```

はて・・・`~/.nodebrew`ディレクトリが無いだと・・。

## 解決

Homebrewでインストールした時に

```sh
$ brew install nodebrew

:(省略)
==> Caveats
You need to manually run setup_dirs to create directories required by nodebrew:
  /usr/local/opt/nodebrew/bin/nodebrew setup_dirs

Add path:
  export PATH=$HOME/.nodebrew/current/bin:$PATH

To use Homebrew's directories rather than ~/.nodebrew add to your profile:
  export NODEBREW_ROOT=/usr/local/var/nodebrew

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions

:(省略)
```

セットアップの方法がちゃんと書いてあるではないか！！

```sh
$ /usr/local/opt/nodebrew/bin/nodebrew setup_dirs
```

```sh
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```

これで無事にnodeを入れることができた。

```sh
$ nodebrew install-binary v6.10.0
Fetching: https://nodejs.org/dist/v6.10.0/node-v6.10.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully

$ nodebrew use v6.10.0
use v6.10.0

$ node -v
v6.10.0
```
airflowのweb authentificationのuser.passwordでAttributeError発生した時の対応

# 背景
- airflow_version1.8.2
- airflowに簡単なログイン認証を追加したかった
- aiflowのドキュメントにある[web authentification](https://airflow.apache.org/security.html#web-authentication)を採用した
- [パスワード設定](https://airflow.apache.org/security.html#password)用のpythonコード `user.password = 'set_the_password'` の箇所で`AttributeError: can't set attribute` エラーが発生した

# 対応
- [パスワード設定](https://airflow.apache.org/security.html#password)用コードのuser.password を user._set_pasword に書き換える

```
# navigate to the airflow installation directory
$ cd ~/airflow
$ python
Python 2.7.9 (default, Feb 10 2015, 03:28:08)
Type "help", "copyright", "credits" or "license" for more information.
>>> import airflow
>>> from airflow import models, settings
>>> from airflow.contrib.auth.backends.password_auth import PasswordUser
>>> user = PasswordUser(models.User())
>>> user.username = 'new_user_name'
>>> user.email = 'new_user_email@example.com'
>>> user._set_password = 'set_the_password' # ←ここ
>>> session = settings.Session()
>>> session.add(user)
>>> session.commit()
>>> session.close()
>>> exit()
```

# 参照
- https://stackoverflow.com/questions/48917131/airflow-basic-auth-cannot-create-user?noredirect=1&lq=1
UiPathでpdfテキスト化

前提：pdfはテキストが埋め込まれている。

１．PDFActivitiesをインストール
![u1.GIF](https://qiita-image-store.s3.amazonaws.com/0/96158/75215f3d-821c-4921-6482-4677e9651b51.gif)


２．Read PDF Textアクティビティを追加
![u2.GIF](https://qiita-image-store.s3.amazonaws.com/0/96158/88c17cdd-0ce4-6d32-e4d0-047aeba8cb8e.gif)


３．Outputに変数名を記入
![u3.GIF](https://qiita-image-store.s3.amazonaws.com/0/96158/2c03da9e-f849-ee3e-b6d9-bb51c8c3fad8.gif)


４．Write text fileアクティビティを追加し、３の変数をInput、出力ファイル名をFileNameに記入する。出力ファイル名はダブルクォーテーションで囲むこと。
![u5.GIF](https://qiita-image-store.s3.amazonaws.com/0/96158/5f0bd166-f2fe-839e-ec95-cdfc9ae9f667.gif)


５．実行すると、プロジェクトフォルダにテキストファイルができる。
![u4.GIF](https://qiita-image-store.s3.amazonaws.com/0/96158/85a4fcda-596c-bb51-2a69-e60c2d7d46a2.gif)


参考：https://www.uipath.com/ja/tutorials/pdf-data-extraction-and-automation-jp
SPSS Modelerでクラスタ分析で変数の重要度でソートする

SPSS Modelerではクラスターモデルのクラスタービューアーで変数の重要度でソートすることができます。
ソートはクラスター全体で行う方法とクラスター毎に行う方法があります。

１．全体の重要度でソートする方法
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223763/d2637877-fd3a-6527-25f5-7b272d5ecc16.png)

２．クラスター内の重要度でソートする方法
下の例ではクラスター4ではIncomeが2番目に重要だったことがわかります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/223763/6e560383-2f2a-9086-320b-546fcb65f2a6.png)


IBM Knowledge Center - 「クラスター予測値の重要度」ビュー
https://www.ibm.com/support/knowledgecenter/ja/SS3RA7_18.1.1/modeler_mainhelp_client_ddita/clementine/entities/clusterviewer_variable_importance_panel.html#clusterviewer_variable_importance_panel

重要度の決め方は以下のアルゴリズムガイドのp.90にあります。
ftp://public.dhe.ibm.com/software/analytics/spss/documentation/modeler/15.0/ja/AlgorithmsGuide.pdf
loggingで直近n件のログを取得

# 動機
エラーが起こった地点からn件をメールで送信したかった

# コード・使い方
使い方は普通のloggingと同じです。
`handler = StackHandler(max=10)`でハンドラをつくり、
設定したハンドラのstackを見に行けばテキストのリストが入っています。
maxにはスタックする数の最大を入れます。(任意)

```python:stacklog.py
import logging
from collections import deque

class StackHandler(logging.StreamHandler):
	def __init__(self, max=10):
		super(StackHandler,self).__init__()
		self.stack = deque(maxlen=max)

	def emit(self, record):
		self.stack.append(self.format(record))

logger = logging.getLogger()
handler = StackHandler(max=10)
handler.setFormatter(logging.Formatter("%(levelname)-8s %(asctime)s %(message)s"))
logger.addHandler(handler)

for i in range(20):
	logger.error(i)

for i in handler.stack:
	print (i)
```

```:出力
ERROR    2018-04-23 13:23:38,966 10
ERROR    2018-04-23 13:23:38,966 11
ERROR    2018-04-23 13:23:38,966 12
ERROR    2018-04-23 13:23:38,966 13
ERROR    2018-04-23 13:23:38,966 14
ERROR    2018-04-23 13:23:38,966 15
ERROR    2018-04-23 13:23:38,966 16
ERROR    2018-04-23 13:23:38,966 17
ERROR    2018-04-23 13:23:38,966 18
ERROR    2018-04-23 13:23:38,966 19
browserifyのrequireに指定できるのは文字列リテラルだけ

以下のいずれも実行時に「Uncaught Error: Cannot find module」が発生する

```javascript
var validPath = './util';
var util = require(validPath);
```

```javascript
var util = require('./' + 'util');
```

上記のように書くとbrowserify結果ファイルの例の

```javascript
},{"./aaa":9,"./bbb":15,"./util":49}],4:[function(require,module,exports){
```

みたいなやつが

```javascript
},{"./aaa":9,"./bbb":15}],4:[function(require,module,exports){
```

となってしまう

以下によればそういうもんみたいなのであきらめるしかない
https://github.com/browserify/browserify/issues/664#issuecomment-35615649

> browserify doesn't work with conditional requires and can't be made to work with arbitrary dynamic requires without solving the halting problem first. Do something different instead. This is a dead end.

あきらめられなかったので続き → [browserify前にrequireのパスを正規表現で置換](https://qiita.com/pilot/items/774fce0910b7853883e1)
Talend Open Studio for Data Integration(TOS DI)の活用(概要＋初期設定編)

# Talendとは？(簡単に)

オープンソースの統合ソフトウェア
今回利用するのはその中の「Data Integration」というETLツール

有償版と無償版(Talend Open Studio)があるが、
無償版でやりたいことはほとんど出来るのでそっちを利用する。
※チーム開発をしたいなどあれば有償版がいいそうな(詳細は知らない)

他にも様々なツールがあるので興味あれば「TalendHP > ダウンロード」を見てください。


## なにができるの？

とりあえず色々出来る。今回私が使用した機能を例に挙げると

・FTPにあるファイルのDownload/Upload
・Amazon S3にあるファイルのDownLoad/Upload
・マスタ用ExcelとDownLoadしたCSVなどのマッピング
・CSVやExcel出力
・エラー時にメール送信

などなど。
当然DBにつないだり、AWS以外のクラウドサービスにつないだりも可能。

日本語マニュアルもあるので、興味あればそちらを確認(1500ページ位あるので心が折れないよう注意)

※PDFなので「Talend Integration Suite コンポーネント リファレンスガイド」とかで検索


## 初期設定

### 用意するもの

・JDK8

以下OracleのJDKDLページより
「Java SE Development Kit 8u171」の「◯Accept License Agreement 」にチェック
自分の環境に合わせたやつをダウンロード
<a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html" target="_blank">http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html</a>

ダウンロードされた実行ファイル(渡しの場合はjdk-8u171-windows-x64.exe)を実行し、好きな場所にインストール。

・Talend Open Studio for Data Integration(v7)

以下Talend公式HPの「ダウンロード」をクリックし、保存
<a href="https://jp.talend.com/products/data-integration/data-integration-open-studio/" target="_blank">https://jp.talend.com/products/data-integration/data-integration-open-studio/</a>

ダウンロードされたZIPファイルを、好きな場所に解凍
フォルダ内の「TOS_DI-win-x86_64.exe」を実行するとTalendが立ち上がる。


## プロジェクトの作成

新規プロジェクトを作成 > 完了

で画面が起動する。
※Talendのインストールディレクトリの「workspace」フォルダにプロジェクトが作成される


初期設定は以上です。
次回は簡単な使い方を説明できればと思います。
【Rust】WebフレームワークRocketを動かしたときのエラー

# 概要
RustのWebフレームワークを使ったときにエラーが出たのでメモ。[Rockerのドキュメント](https://rocket.rs/guide/quickstart/#running-examples)のクイックスタートをやってみました。問題の解決方法としては`cargo rust`を実行するときにrustのnightly版を使って実行すれば解決できますが、nightlyの使い方を知るまでに時間がかかりました。エラー内容は長いので記事の最後に記載します。

(2018/05/10追記)
@ykonomi さんがコメントに載せてくださったやり方でnightlyを動かすのでも良さそうです！

環境：windows10

# やったこと
nightlyをinstall

```
rustc install nightly
```

nightlyをつかう。この'+nightly'を知るまでに時間がかかった。

```
cargo +nightly run
```

これで実行できた。

#エラー内容

```
error: failed to run custom build command for `rocket_codegen v0.3.8 (file:///xxx/rust/Rocket/codegen)`
process didn't exit successfully: `xxx\rust\Rocket\target\debug\build\rocket_codegen-d2d1541e746ad235\build-script-build` (exit code: 101)
--- stderr
?[1;31mError:?[0m ?[37mRocket requires a nightly or dev version of Rust.?[0m
?[37mInstalled version is:?[0m ?[33m1.25.0 (2018-03-25)?[0m. ?[37mMinimum required:?[0m ?[33m1.27.0-nightly (2018-04-06)?[0m.
?[34mSee the getting started guide (?[0m?[37mhttps://rocket.rs/guide/getting-started/?[0m?[34m) for more information.?[0m
thread 'main' panicked at 'Aborting compilation due to incompatible compiler.', codegen\build.rs:38:17
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: failed to run custom build command for `pear_codegen v0.0.16`
process didn't exit successfully: `xxx\rust\Rocket\target\debug\build\pear_codegen-a28c5dcc6703d3d8\build-script-build` (exit code: 101)
--- stderr
?[1;31mError:?[0m ?[37mPear requires a nightly or dev version of Rust.?[0m
?[37mInstalled version is:?[0m ?[33m1.25.0 (2018-03-25)?[0m. ?[37mMinimum required:?[0m ?[33m1.27.0-nightly (2018-04-14)?[0m.
thread 'main' panicked at 'Aborting compilation due to incompatible compiler.', xxx\.cargo\registry\src\github.com-1ecc6299db9ec823\pear_codegen-0.0.16\build.rs:31:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: failed to run custom build command for `rocket v0.3.8 (file:///xxx/rust/Rocket/lib)`
process didn't exit successfully: `xxx\rust\Rocket\target\debug\build\rocket-c96e4e05a2a699a0\build-script-build` (exit code: 101)
--- stderr
?[1;31mError:?[0m ?[37mRocket requires a nightly or dev version of Rust.?[0m
?[37mInstalled version is:?[0m ?[33m1.25.0 (2018-03-25)?[0m. ?[37mMinimum required:?[0m ?[33m1.27.0-nightly (2018-04-03)?[0m.
?[34mSee the getting started guide (?[0m?[37mhttps://rocket.rs/guide/getting-started/?[0m?[34m) for more information.?[0m
thread 'main' panicked at 'Aborting compilation due to incompatible compiler.', lib\build.rs:38:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: build failed
```

# 20180501追記
nightlyをデフォルトにすることができるみたい。やってはいないが、これで`+nightly`の指定がいらなくなるのかな。

```
rustup default nightly
```

# 参考
https://github.com/rust-lang-nursery/rustup.rs/issues/762
https://rocket.rs/guide/quickstart/#running-examples
https://qiita.com/yyu/items/18df35988f3ea3b12af0
CLBからNLBへの変更時に引っかかったこと

ALBの影に隠れて今一つ目立たないNLBですが、触る機会があり、引っかかったところと対応方法を共有します

## インスタンスタイプに制限がある
ターゲットグループにお目当てとなるEC2がどうしても出てきませんでした
VPC、subnet、SGは問題ありません

よくよくマニュアルを読めば、
> インスタンス ID がC1、CC1、CC2、CG1、CG2、CR1、G1、G2、HI1、HS1、M1、M2、M3、および T1 のインスタンス ID でインスタンスを登録することはできません。IP アドレスで、これらの種類のインスタンスを登録することができます。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/load-balancer-target-groups.html

対象のEC2のインスタンスタイプはm3系
お客さまに説明し、価格もスループットも向上するということでインスタンスタイプの変更を了承頂きました

## インスタンスタイプとEBSの最適化での問題
NLBとは直接関係ありませんが、もう1点
今回の対象システム、アクセス数の少ない夜間はt2系に下げる運用をしています
夜間になり、t2系に変更して起動しようとしたらエラーで起動できず

m4系に変更したことで、EBSの最適化が自動的に適用されるものの、t2系だとEBSを最適化されていると起動できないというトラップが！

APIを調べたところ、インスタンスタイプ変更時のAPIパラメータに

```
EbsOptimized={
        'Value': True|False
    },
```

http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Instance.modify_attribute
というのを発見、こいつをFalseにして起動しようとしたところ、そのパラメータの組み合わせは同時にセットできませんのメッセージが

同時にセットするのがダメなら別々なら大丈夫???

```
instance.modify_attribute(InstanceType={'Value': instance_type})

if instance_type in NOT_EBS_OPTIMIZE_TYPE:
    instance.modify_attribute(EbsOptimized={'Value': False})
```

これで事なきを得ました

結構特殊な運用をされているので、同じような問題に引っかかる方は少ないと思いますが、何かの参考になりましたら
herokuにデプロイできるが動かない〜PostgreSQL 1.0.0編〜

# Steps to reproduce

1. Gemfileのproductionに`gem "pg", "1.0.0"`を追記
2. bundle install
3. git add .
4. git commit
5. git push heroku master
6. Webアプリのトップページを開く

# Expected behavior
ちゃんとWebアプリが動く

# Actual behavior
アプリが動かず、

```
2018-04-23T02:16:05.027483+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/"
```

のような、なぜかクラッシュしていることだけがわかるログが現れる。

# How to do to resolve
まず、何が起こっているか確認したい。
なので以下の手順でログを確認する。

1. heroku run rails c
2. Webアプリにアクセス

（参考：http://www.workabroad.jp/posts/2166）

すると

```
`rescue in spec': Specified 'postgresql' for database adapter, but the gem is not loaded. Add `gem 'pg'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
```

というように、postgresqlがうまく動いていないというエラーが見て取れる。
このエラーメッセージで検索すると、以下のページが見つかった。
https://github.com/rails/rails/issues/31673
回答にあったリンク先に向かうと、
https://github.com/rails/rails/issues/31669
とあり、現在のrailsではpostgresql 1.0.0はサポートされていないことがわかる。
なので、以下の手順で解決する。

1. Gemfileのproductionのpgを`gem "pg", "~> 0.21.0"`に変更
2. bundle install
3. git add .
4. git commit
5. git push heroku master
6. Webアプリのトップページを開く

無事に動きました。
radikoの「ライブ」風船がわざわざ跳ねてイラつかせてくるのでChrome拡張作って黙らせた

そもそも、なぜ不要なアニメーション処理を追加してリスナーの集中力を妨げるのでしょうね？
![screenshot1.png](https://qiita-image-store.s3.amazonaws.com/0/7638/ce8e84cf-c4d6-7100-e433-96fd1e8bf461.png)

不思議でしょうがないのですけど、radiko.jpに問い合わせても直す気がまったくない様子でして。
幸い、Chrome拡張作ればなんとかなる＝自分の手の届く範囲だったので、手を動かしてみました。
おかげで、今は平和です。

拡張のページ: [radiko.jp Hide Popping Balloon](https://chrome.google.com/webstore/detail/radikojp-hide-popping-bal/agjfhidljoomfmnakphkeaioljjdnmch)

## はじめてのChrome拡張作り

についてのエントリにしようと当初は思っていたものの、`Chrome 拡張 作る`でググればQiitaの良記事がいくつもヒットするので要らないかなと。

大事なことは
・自分専用の拡張作るならタダでなんぼでも作れる
・[Chrome Web Store](https://chrome.google.com/webstore/category/extensions)で公開するなら、公開用アカウント登録料で$5かかる
です。

## やってること

動的に表示される風船要素を監視・抑え込むために[MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)を使っています。自前でpollingするよりも簡潔・軽量です。

```javascript
(function () {
  const playerDetailObserver = function (mutationsList) {
    const tooltip = document.querySelector('#player-detail .tooltip');
    if (tooltip) tooltip.remove();
  };
  const observer = new MutationObserver(playerDetailObserver);
  observer.observe(document.querySelector('#player-detail'), { childList: true });
})();
```

ソースリポジトリ: [https://github.com/reedom/radiko-hide-popping-balloon](https://github.com/reedom/radiko-hide-popping-balloon)

## おわりに

だめなUX/UIサイトも自分の手でなんとかできる、というのが判ると夢は広がります。
サーバーにBasic認証パスワード設定する方法

■サーバーがApacheであること前提
■最終的に出来上がるもの
・.htaccessファイル…パスワードの照合に必要な.htpasswdの在処などを記載するファイル
・.htpasswdファイル…IDとパスワードを暗号化して記述しておくファイル

# 1.まずはアップロード場所のフルパスを調べる
大体のサーバーはコントロールパネルなどにパスの記載があるけれど、調べるのが面倒な時・調べ方が分からない時などは下記の方法で

## 1-1.パスワードかけたいフォルダに下記をアップロード
ファイル名が既存ファイルと被るときはもちろん改名して使う

```ruby:test.php
<?php
echo __FILE__;
?>
```

## 1-2.アップロードしたtest.php(仮名)にアクセス

アクセスすると、test.php(仮名)自身のアップロード場所のフルパスが表示される

> /home/○○○/xxx.com/public_html/○○○○/test.php


# 2. .htaccessを準備

新しく作成したファイルに以下を記述し「htaccess.txt」と名前を付けて保存。
※既に.htaccessがある場合は、既存ファイルをダウンロードして上の方に追記。ファイル名の改名不要。

```ruby:.htaccess
AuthUserFile /home/○○○/xxx.com/public_html/○○○○/.htpasswd
AuthGroupFile /dev/null
AuthName "Please Enter your ID & Password"
AuthType Basic
require valid-user

<Files ~ "^.(htpasswd|htaccess)$">
    deny from all
</Files>
```

1行目は.htpasswdファイルの場所を記述。
1.で調べたフルパスを使って書く。

# 3. .htpasswdを準備
http://www.luft.co.jp/cgi/htpasswd.php
上記ツールを使って設定したいIDとパスワードを暗号化。
新しく作成したファイルにテキストをコピー＆ペーストして「htpasswd.txt」と名前を付けて保存。

# 4. htaccess.txtとhtpasswd.txtをパスワード設定したいフォルダにアップロード
それぞれサーバー上で「.htaccess」と「.htpasswd」に改名。
これで完了
vhをpxに変換

#はじめに

いわゆるハイブリッドアプリ開発時に、ネイティブ実装した画面と組み合わせる際にレイアウトの値を指定するのに苦労したのでまとめました。
設定による違いは検証していないので検証次第追記しようと思います。

---

#vhとは

Viewportの高さの1/100を1vhとする単位です。
Viewportを基準とする単位は他に「vw」「vmax」「vmin」があります。

---

#変換します

画面全体にWebviewを表示している場合のvhは以下のように取得できます。

```kotlin
val displayMetrics = context.resources.displayMetrics //DisplayMetricsを取得
val statusBarHeight = 24 * displayMetrics.density //ステータスバーの高さ
val height = displayMetrics.heightPixels - statusBarHeight //Androidの画面の高さ
val deviceViewPortHeight = height / displayMetrics.density //デバイスのViewportの高さ
val px = deviceViewPortHeight / 100 //1vhあたりののピクセル値
```
---

DisplayMetrics.heightPixelsはステータスバーの高さも含まれるためステータスバーの高さ分引いてあげるのを忘れないように注意してください。
※[ステータスバーの高さについて](https://material.io/guidelines/patterns/navigation-drawer.html#navigation-drawer-specs)
また、Viewportの高さはdensityに依存しているようです。
はじめ、ディスプレイの高さに対して計算させると想定していたよりだいぶ大きくて焦りました。

---

もしかしたら、確認した環境との違いでうまくいかないかもしれません。
その場合は以下について考慮に入れて試してみてください。

- Webページ側のmetaタグでViewportのheightを設定していない
- Webviewの設定で「useWideViewPort」「loadWithOverviewMode」をtureにしている

---

#まとめ

CSSの単位は色々あるので他のもpxに変換できるようにしておくと便利かもしれません。
【iOS11】iPhone/iPadでOffにしたWifiが自動的にOnになってしまうときの対処【設定】

# はじめに
iPhoneのWifiをOffにしたのにしばらくするとOnになっている。
気になりつつも放置していたけど、思い立って調べてみたのでメモ。

# 現象
- 仕事場でiPhone（iPad）のWifiをコントロールセンターでOffにする。
- 自宅に戻るとOnになってWifiにつながっている。

# Appleの公式情報
[Apple support Link](https://support.apple.com/ja-jp/HT208086)
コントロールセンターで操作した場合、以下の条件でWifiが有効になるそうだ、なんてこった。
移動するとOnになっているのはなんとなく感じていたけど。

- コントロールセンターで Wi-Fi をオンにする。
- 「設定」>「Wi-Fi」で Wi-Fi ネットワークに接続する。
- 新しい場所に徒歩や車で移動する。 
- 現地時刻の午前 5 時になる。
- デバイスを再起動する。

上記リンクにもあるが、Bluetoothも同様らしい。こちらは位置は関係ないのね。

- コントロールセンターで Bluetooth をオンにする。
- 「設定」>「Bluetooth」で Bluetooth アクセサリに接続する。
- 現地時刻の午前 5 時になる。
- デバイスを再起動する。

# 対処法
つまり、コントロールセンターで操作しなければいい、設定→Wifi→Offに。
Bluetoothも同様。

# 感想
公式ページにあるように
> iOS デバイスを快適に使えるように、Wi-Fi と Bluetooth はなるべくオンにしておくようにしてください。

ということなんだと思うんだけど、十分な説明なしに勝手に動作するのはいかがなものかと。
設定画面まで遷移しなきゃいけないとなると、コントロールセンターの良さが死ぬ。
4GでYoutube繋いでしまって通信料がオーバーしてしまった！とかいう状況の回避にはなるかもしれないけど、いまどきはアプリ側で4G繋いでるよっていう表示が出たりするのでそんなに困らない。
ubuntu 16.04上のanaconda3でkerasでGPUを使う環境作り

ざっと検索した通りに入れるとtensorflow-cpuがインストールされてしまって，kerasがgpu使うのか心配だったので．
anacondaの場合導入は簡単．

なおanaconda3-4.4.0を使っている．
pyenv派で，pythonはpython3.6，pipはpip3を指す環境下で実行しているため注意．
pipは9.0.1から上げてない．

# CUDAを入れる

まずtensorflowのバージョンを決めて，対応するCUDAとcuDNNのバージョンを決める．
とりあえず普通に最新のものを入れればよかろうということで

```shell
conda search tensorflow-gpu
```

一番下に出てくる数字のデカいのが入る．今なら1.7.0．

ここでリリースノートを見る．
https://github.com/tensorflow/tensorflow/releases/tag/v1.7.0

    Deprecations

    - TensorFlow 1.7 may be the last time we support Cuda versions below 8.0.
      Starting with TensorFlow 1.8 release, 8.0 will be the minimum supported
      version.
    - TensorFlow 1.7 may be the last time we support cuDNN versions below 6.0.
      Starting with TensorFlow 1.8 release, 6.0 will be the minimum supported
      version.

CUDA 8.0以降ならよさそう．
ubuntuでcudaを入れる．

```conf:/etc/apt/sources.list.d/cuda.list
deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /
```

よくapt-keyを入れろとかあるけど，毎回警告が出ることが煩わしくなければ入れなくて良い．

インストール

```shell
sudo apt-get update
sudo apt-get upgrade # 必要なら
sudo apt-cache search cuda # 記事の時点ではcuda-9-1が最新
sudo apt-get install cuda-9-1
```

# cuDNNインストール

実は，先にhttps://developer.nvidia.com/rdp/cudnn-downloadから

- cuDNN v7.1.3 Runtime Library for Ubuntu16.04 (Deb)
- cuDNN v7.1.3 Developer Library for Ubuntu16.04 (Deb)
- cuDNN v7.1.3 Code Samples and User Guide for Ubuntu16.04 (Deb)

を入れちゃったからよく分からんが，conda install tensorflow-gpuでもcuDNNが入る．(記事の時点では7.1.2)

debファイルは sudo dpkg -i で上から順に入れればOK．
誰かこれから入れる人がいたらcuDNNを入れずに次の手順をやって，動くかどうか確かめてくれると嬉しい．

(ここでsudo ld-configしてたら，わざわざ入らなかったのかな…今更わからん)

# tensorflowのインストール

tensorflowはcpu版とgpu版があって，選択して入れないといけない．
両方入れることもできるかも知れないけど，どっちが使われているか分からなくなりそうなので試してない．

```shell
conda install tensorflow-gpu
# ここでcuDNNがまた入った．こっちは7.1.2
```

# kerasのインストール

kerasも，gpu版が別にある．
ざっと検索するとpip install kerasとか書かれているけど，keras-gpuとしないとtensorflow (無印)を入れようとしてくるので，keras-gpuを指定した．

```python
conda install keras-gpu
```

ちなみにimport文には``-gpu``はいらない．
ベクトル解析

# ベクトル解析

[トップページ](c6dc94cdd8997164e730)

## ベクトル表記

```math
\begin{align}
　&\boldsymbol{A} = A_x e_x + A_y e_y + A_z e_z　　　　　\\
　&\boldsymbol{A} = (A_x, A_y, A_z)\\
  &（A_x, A_y, A_zは係数でスカラー）\\
\end{align}
```

## [ベクトルの掛算](1872c8dae554c998aeb4)

1. 整数倍 => ベクトルになる（平行なベクトル）$(k\boldsymbol{A})$
2. 内積 => スカラーになる $(\boldsymbol{A} \cdot \boldsymbol{B})$
3. 外積 => ベクトルになる（法線ベクトル） $(\boldsymbol{A} \times \boldsymbol{B})$
4. テンソル積 => ２階テンソルになる $(\boldsymbol{A} \otimes \boldsymbol{B})$

## [２階テンソルとベクトルの積](6fe08467490fcede1313)

[２階テンソルとベクトルの積](6fe08467490fcede1313)

## ナブラ

ベクトルと考える

```math
\nabla = e_x \frac{\partial}{\partial x} + e_y \frac{\partial}{\partial y} + e_z \frac{\partial}{\partial z} \\
```

## ナブラの掛算

[ナブラの掛算](fc774fb7107ad97528f1)

1. スカラー場をかける => スカラー場の勾配(grad)（整数倍=>ベクトル場）
2. ベクトル場と内積 => ベクトル場の発散(div)（内積=>スカラー場）
3. ベクトル場と外積 => ベクトル場の回転(rot)（外積=>ベクトル場）
4. ２乗する          => ラプラシアン($\nabla^2$)（２乗=>ラプラシアン）
5. ベクトル場とテンソル積 => ベクトル場の勾配(grad)（テンソル積=>２階テンソル場）
6. テンソル場と内積 => テンソル場の発散(div)（内積=>ベクトル場）


## [ベクトル関係の記述](30b140a91fd140ebfe52)

[ベクトル関係の記述](30b140a91fd140ebfe52)
Rails x Cloudinaryでパーミッションエラーが出た時の対処

Cloudinaryに画像をアップロードするアプリケーションを作っていた時に起きた問題

## エラー内容

以下のようなエラーが出た。

```
Netrc::Error: Permission bits for '/Users/username/.netrc' should be 0600, but are 644
from /Users/username/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/netrc-0.11.0/lib/netrc.rb:45:in `check_permissions'
```

## 対処法

エラーメッセージの通り、644権限でエラーになってるので、600にファイルのパーミッションレベルを変更する

```
$ chmod 600 /Users/username/.netrc
```
Vue.jsのUIコンポーネント「Vuetify」をIE11/Safari9に対応させる

## Vuetifyとは
VuetifyはVue.jsで利用できるUIコンポーネント。マテリアルデザインにもとづいて実装されています。
https://vuetifyjs.com/ja/


## ブラウザサポート
IE10以下は非対応となります。
今回の対象となる、IE11/Safari9はPolyfillを使うことで対応が可能です。

## 手順
### babel-polyfillのインストール
```
// my-project/
$ npm install babel-polyfill --save
// or
$ yarn add babel-polyfill
```

### webpackのエンドポイントのソースでimport
```javascript
// my-project/src/main.js
import 'babel-polyfill'
...
new Vue()
```

### webpackのビルド設定ファイルの修正
```javascript
module.exports = {
  // 略
  entry: {
    app: ['babel-polyfill', './src/main.js']
  },
  // 略
```
`entry`のプロパティに`babel-polyfill`を追記します。

## 参考URL
https://vuetifyjs.com/en/getting-started/quick-start#ie11-support
https://github.com/vuetifyjs/vuetify/issues/794
モンティホール問題 JavaScript 17行

初版は間違えてた。はづかしい


# モンティホール問題
[モンティホール問題 - Wikipedia](https://ja.m.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C)

> 「プレーヤーの前に閉まった3つのドアがあって、1つのドアの後ろには景品の新車が、2つのドアの後ろには、はずれを意味するヤギがいる。プレーヤーは新車のドアを当てると新車がもらえる。プレーヤーが1つのドアを選択した後、司会のモンティが残りのドアのうちヤギがいるドアを開けてヤギを見せる。ここでプレーヤーは、最初に選んだドアを、残っている開けられていないドアに変更してもよいと言われる。プレーヤーはドアを変更すべきだろうか？」

変更しない場合の正解の確率は 1/3, 変更した場合の正解の確率は 2/3。よって変更した方がよい。

# コード

30000 回の試行をして、変更しない場合は 10000回程度の成功、 変更する場合は20000 回程度の成功となることを確かめる。

```js
const BOX = [0, 1, 2];
const randInt = num => Math.floor(Math.random() * num);
const chooseRandomFrom = arr => arr[randInt(arr.length)];
const playWithoutRechoice = (answer, choice) => choice === answer;
const playWithRechoice = (answer, choice) => {
  const opened = chooseRandomFrom(BOX.filter(x => x !== answer && x !== choice));
  const rechoice = chooseRandomFrom(BOX.filter(x => x !== choice && x !== opened));
  return rechoice === answer;
};
// main
const count = { without: 0, rechoice: 0 };
for (let i = 0; i < 30000; i += 1) {
  const [answer, choice] = [chooseRandomFrom(BOX), chooseRandomFrom(BOX)];
  if (playWithoutRechoice(answer, choice)) count.without += 1;
  if (playWithRechoice(answer, choice)) count.rechoice += 1;
}
console.log(count);
```

結果。いい感じ。

```
{ without: 10054, rechoice: 19946 }
```
Wikipedia のリンクの短縮法

　プレゼン資料や勉強用のメモ書きに Wikipedia へのリンクを貼りたいけど、リンクをコピーしてペーストしてみたらめちゃくちゃ長いやつがペーストされた、って時の対処法です。私はいつも以下のサイトでリンクを短縮しています。
　
https://sleepygamersmemo.blogspot.jp/2017/06/wikipedia-url-shortener.html

　理屈はまだよく分かっていませんが、とりあえずしっかりとリンクは繋がるので急ぎの方は活用してみるといいかもしれません。
homebrew-caskって何？？？

Xamarin StudioをMacに入れようと思いまして、

「たぶん`brew install xamrin-studio`みたいな感じやんな。」
と思いながらググったら、

`brew cask install xamarin-studio`

って[ここに](http://macappstore.org/xamarin-studio/)書いてありました。

あれ？そういや使ったことあるけど**cask**って何？？？

# Caskの公式から
> Homebrew-CaskはHomebrewを拡張し、その優雅さ、シンプルさ、スピードをmacOSアプリケーションや大きなバイナリにもたらします。
あなたのシェルで1行だけで、5476人のコントリビューターによって管理されている3960個のCasksに到達します。


つまりCaskは**Homebrewの拡張**であると。

# Diff
## homebrew
Mac用のパッケージマネージャー。**ターミナル**で使うものをインストールできる。

### 例1. git
```
brew install git
```

### 例2. python
```
brew install python3
```

## homebrew-cask
homebrewの拡張で、Macの**GUIアプリケーションも**コマンド一発で管理してしまおうというもの。

※ 拡張であるってとこは重要ポイントだと思います。

# 例1. google-chorme
```
brew cask install google-chrome
```

# 例2. xamarin-studio
```
brew cask install xamarin-studio
```

# めっちゃ便利やん！
新人プログラマーや勉強会の参加者などに、GUIアプリケーションをインストールして開発環境を整えてもらう...。というのはよくあるユースケースだと思いますが、全員に同じことをやらせるのは重複ですよね。

コマンド叩いてもらったら全員同じになるようにしよう！というのは**DRY**で良いですね。


# 参考
https://www.evoworx.co.jp/blog/homebrew-cask/
ZipArchiveで圧縮


メモ

```php
$zip_file_path = [zipファイルパス];

$zip = new ZipArchive();
$zip_res = $zip->open($zip_file_path, ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE);

if ($zip_res === true) {
    $zip->addFile([zipファイルに入れたいファイルパス], [ファイル名])
    $zip->close();
 }
```
頻繁に使う Linux のコマンド集（自分用）

　これから Linux を使う機会がバンバン増えていきそうなので、先輩に「よく使うよ！」と教えられたり、覚えていなかったら気まずい雰囲気になったり場合によっては怒りを買うことになるほど常識的なコマンドをここにまとめておきます。あくまで自分用です。

# タブキーを押す

　いきなりコマンドじゃなくてショートカットキーです。タイトル詐欺です。ですが本当に頻繁に使うので覚えておくべきしょう。使いたいコマンドや、ディレクトリのパスを途中まで入力した状態でこれをすると補完してくれます。　
　
※カーソルキーの下を入力するとこれまで入力してきたコマンドが出るという機能がありますが、うちではあまり使うことを推奨されませんでした。個人差はあると思いますが、最終的にこっちを使った方が早いらしいです。

# ip a

　ネットワークデバイスのIPアドレスを表示します。Windows では ipconfig、Linux では ip a という風に私は使いわけています。

#shutdown -h now

　システムをシャットダウンします。×ボタンを押したりして強制的に消すとかしないように！

# clear

　ターミナルが自分の入力したコマンドでゴチャゴチャになってきたと感じたら入力しましょう。画面がクリアされます。Enter連打で強引に体裁を整えている人は、それをやめてこちらを使ったほうがいいかもしれません。


# history

　今まで自分の入力してきたコマンドが一覧で表示されます。

# history | grep xxx

　今まで自分の入力してきたコマンドの中で、xxxにある文字のみを表示します。

# !x

　履歴の x番目のコマンドを実行します。

# find xxx

　検索コマンド。xxxには検索するファイル名を指定する。検索したファイルがなければ、エラーが表示される。

# yum

　まだ一言で説明できるほど理解はできていないので参考になりそうなサイトへのリンクを貼っておきます。
　https://eng-entrance.com/linux-package-yum

　頻繁には使わないかもしれませんが、勉強用に Virtual Box で CentOS をインストールしネットワーク環境を構築したいと思ったときに使うことになるかもしれません。



　以上になります。これからも更新します。たぶん
Windows7でSeleniumを使う

#Windows7

#PHP7.2.4
公式サイトから64bitスレッドセーフ版をダウンロード(php-7.2.4-Win32-VC15-x64.zip)。C:\PHPに配置。

#Visual C++2017
PHPを動かすために必要らしい。マイクロソフトからダウンロード。

#Composer
公式サイトからダウンロード。インストーラ実行。コマンドプロンプトでcomposerと打ってロゴが出ればok。

#ChromeDriver
公式サイトからダウンロード。

#PHP.ini
extension=curlの先頭のセミコロンを外して上書き。

#Selenium(facebook/webdriver)
何かディレクトリを作ってそこに移動。
コマンドプロンプトでcomposer require facebook/webdriberと打ってインストール。

実行するスクリプトは下記を参照
https://qiita.com/tsuuuuu_san/items/61379b797878d0e0f4d7

環境構築に躊躇していましたが、意外とすんなり入りました。

#さてFirefoxも試そうとしたところ、ハマりました。

#Seleniumのバージョンを3.4
http://selenium-release.storage.googleapis.com/index.html?path=3.4/

#Firefoxのバージョンを60.0

あらかじめStandaloneを起動してからPHPを実行
java -jar selenium-server-standalone-3.4.0.jar -port 4445

#失敗
Firefox起動のたびにSSLが自己証明書になっているとの警告

以下のコードで解決

```PHP
$profile = new FirefoxProfile();
$caps = DesiredCapabilities::firefox();
$caps->setCapability(FirefoxDriver::PROFILE, $profile);
$caps->setCapability('marionette', true);
$caps->setCapability('testCap', true);
$caps->setCapability('acceptInsecureCerts', true);

// selenium
$host = 'http://localhost:4445/wd/hub';
// chrome ドライバーの起動
$this->driver = RemoteWebDriver::create($host,$caps);
```

#could not be scrolled into view
情報がない。困った。

依然として原因が不明だが、以下のコードを入れたところ、とりあえずうまくいく。

```PHP
$dimension = new WebDriverDimension(800, 600);
$this->driver->manage()->window()->setSize($dimension);
```
[oVirt] CentOS 7で動くoVirtを4.1.6から4.2へアップグレード

CentOS 7で動いているoVirt 4.1.6を4.2へアップグレードしました。

https://www.ovirt.org/release/4.2.0/#centos--rhel にある手順に従えばいいはずですが、パッケージの依存性でつまずきました。

# つまずいたこと

```shell-session
# yum install http://resources.ovirt.org/pub/yum-repo/ovirt-release42.rpm
# yum update "ovirt-*-setup*"
  .
  .
  .
--> Running transaction check                
---> Package python-linecache2.noarch 0:1.0.0-1.el7 will be installed                     
--> Processing Conflict: ovirt-engine-setup-plugin-ovirt-engine-4.2.0.2-1.el7.centos.noarch conflicts ovirt-engine < 4.1.7                                                          
--> Finished Dependency Resolution           
Error: ovirt-engine-setup-plugin-ovirt-engine conflicts with ovirt-engine-4.1.6.2-1.el7.centos.noarch                                                                               
 You could try using --skip-broken to work around the problem                             
 You could try running: rpm -Va --nofiles --nodigest  
```

ovirt-engine-setup-plugin-ovirt-engine conflicts with ovirt-engine-4.1.6.2-1.el7.centos.noarch と言われてしまいました。

## 解決策

先にoVirt 4.1.6を4.1.8へアップグレードする必要がありました。

```shell-session
# rm /etc/yum.repos.d/ovirt-4.2*
# yum update "ovirt-*-setup*"
# engine-setup
```

oVirt 4.2のレポジトリを消してから、4.1.8へアップグレードしました。


# リトライ

```shell-session
# yum install http://resources.ovirt.org/pub/yum-repo/ovirt-release42.rpm
# yum update "ovirt-*-setup*"
# engine-setup
```

これでできました。
具体的な条件で使用するStream

StreamAPI 関連のブログ記事とかを見ても
示し合わせたようにみんな超シンプルに String しか使ってなくて面白味がない。

〜.class単位でソートしたいときだってあるし、
特定の値でグループ化したうえで処理したいことだってある。

「そんな具体的な条件でStreamを使おう」という内容です。

```java:Person.class

public class Person {
	private String name;
	private String gender;
	private double height;

	public Person(String name, String gender, double height) {
		this.name = name;
		this.gender = gender;
		this.height = height;
	}

	public String getName() {
		return name;
	}

	public String getGender() {
		return gender;
	}

	public double getHeight() {
		return height;
	}
}

```

```java

// Streamで処理するList
List<Person> people = Arrays.asList(
		new Person("alex", "male", 161.7),
		new Person("boss", "male", 171.4),
		new Person("chaos", "male", 154.3),
		new Person("akari", "female", 135.4),
		new Person("big mam", "female", 151.2),
		new Person("cinnamon", "female", 148.7),
		new Person("jhon", "them", 187.5),
		new Person("wall", "them", 157.9),
		new Person("owner", "them", 187.8));
// とりあえずシャッフルしておく。
Collections.shuffle(people);

```

## 型を変換する
更新予定

## グループ化

グループ化は `Collectors.groupingBy(classifier)` を使います。
並列ストリームの場合は `Collectors.groupingByConcurrent(classifier)`です。

```java:性別でグループ化して名前のListを取得する

// 性別ごとに名前のListを作る
Map<String, List<String>> genMapped = people.stream()
        .collect(Collectors.groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toList())));

System.out.println(genMapped);
// {them=[jhon, owner, wall], female=[akari, big mam, cinnamon], male=[alex, boss, chaos]}

```
macOSのソフトウェアアップデートはコマンドラインで


- App Storeアイコンのバッジでアップデートに気づいて動かすとなんかアップデートに時間がかかって微妙...ってことありませんか？
- ソフトウェアアップデートにはコマンドもあるんですね、アップデートはコマンドラインからしちゃいましょう！
- なんとなく精神衛生的にいい感じですw

## softwareupdate


- ヘルプを見るとこんな感じ

```sh
sh-3.2$ softwareupdate -h
usage: softwareupdate <cmd> [<args> ...]

** Catalog Management:
	--set-catalog <URL>	Set the new catalog URL (requires privileges)
	--clear-catalog		Clear the catalog URL back to defaults (requires privileges)

** Manage Updates:
	-l | --list		List all appropriate update labels (options:  --no-scan, --product-types)
	-d | --download		Download Only
	-e | --cancel-download		Cancel a download
	-i | --install		Install
		<label> ...	specific updates
		-a | --all		All appropriate updates
		-R | --restart		Automatically restart (or shut down) if required to complete installation.
		-r | --recommended	Only recommended updates
	--background		Trigger a background scan and update operation
	--ignore <label> ...	Ignore specific updates
	--reset-ignored		Clear all ignored updates

** Other Tools:
	--suspend-background 	Suspend background operations from occurring temporarily (use --duration to specify duration to suspend in seconds)
		--duration <duration>)		Optional duration in seconds to suspend background operations (defaults to 5*60 seconds)
	--dump-state		Log the internal state of the SU daemon to /var/log/install.log
	--evaluate-products	Evaluate a list of product keys specified by the --products option
	--history		Show the install history.  By default, only displays updates installed by softwareupdate.
	--all 			Include all processes in history (including App installs)

** Options:
	--no-scan		Do not scan when listing or installing updates (use available updates previously scanned)
	--product-types <type>		Limit a scan to a particular product type only - ignoring all others
		Ex:  --product-types macOS  || --product-types macOS,Safari
	--products		A comma-separated (no spaces) list of product keys to operate on.
	--force			Force an operation to complete.  Use with --background to trigger a background scan regardless of "Automatically check" pref

	--verbose		Enable verbose output
	--help			Print this help
```

## 基本的には、```softwareupdate -i -a```でOK

- 全てインストール（リスタートは無し）で実行します。

```sh
sh-3.2$ softwareupdate -i -a
Software Update Tool

Finding available software
```
USB フラッシュドライブから起動した Raspberry Pi Desktop [Stretch] を (多分) 安全にアップデートする方法

# はじめに

["Raspberry Pi Desktop (Stretch) を USB フラッシュドライブから起動して使う"](https://qiita.com/ht_deko/items/cba4e77ce776839dc004) って記事を書いたのですが、USB フラッシュドライブから起動した場合に `apt-get upgrade` を行うとカーネルが更新されずにカーネルモジュールとのバージョン不一致が起きるようです。

判りやすい所だと `mount -t cifs` ([CIFS](https://ja.wikipedia.org/wiki/Server_Message_Block) によるファイル共有) ができなくなると思います。現象的には以下のレポートと同様です。

 - [Debian Bug report logs - #884094 register_key_type symbol missing, ABI counter not incremented](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=884094)

USB フラッシュドライブから起動した Raspberry Pi Desktop のカーネル更新方法がよくわからないので、とりあえずの回避方法を書いておきます。なお、`apt-get dist-upgrade` や `rpi-update` でもカーネルが更新されなかった事をお断りしておきます。


# (安全な？) アップデート

以下の手順で [パッケージアップデーター] を起動します。 

```bash
$ pi-gpk-update-viewer
```
**linux_headers- と linux-image- で始まるパッケージのチェックをすべて外します。**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/1bf338c4-4c6a-791b-94f1-e068b9bf94e7.png)

二か所くらいにまとまって存在すると思います。片方はメタパッケージ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/0ef42fc0-68ec-4b34-6218-fd7934d7e14b.png)

[更新をインストール] ボタンを押すとパスワードを尋ねられます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/e05ef45e-acf6-caba-bf93-9e09bb81e318.png)

パスワードを変更していないのなら、パスワードは **raspberry** です。

パッケージのアップデートにはかなり時間が掛かります。永続ストレージは 2.7GB 程消費します。アップデートが終わったら再起動を行ってください。

# おわりに

[パッケージアップデーター] を使う方法でもそんなに手間ではないかと。なお、[パッケージアップデーター] をアプリケーションメニューに表示するには以下の手順で行います。

　1. アプリケーションメニュー (ラズベリーアイコン) から [設定 | Main Menu Editor] 。
　2. メニューエディタ (Main Menu Editor) が開く。
　3. 左ツリーで "システムツール" を選択。
　4. 右ペインで "パッケージアップデーター" にチェックを入れる。
　5. [OK] ボタンを押す。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/b5f19463-1a0c-d651-acee-126427453d36.png)
PowerShellでSQL Server Agentを自動起動するようにする


## スクリプト

SQL Server AgentのWMIオブジェクトを取得し、ChangeStartModeで開始モードを自動起動に設定する。

``` powershell
$wmi=Get-WMIObject win32_service | Where-Object { $_.Name -like "*SQLAgent*" }
$wmi.ChangeStartMode("Automatic")
```

## ChangeStartModeのパラメータ

|開始モード|パラメータ|
|---|---|
|自動|Automatic|
| 手動 | Manual|
| 無効 | Disabled |

## 捕捉

### WMIって？

https://technet.microsoft.com/ja-jp/library/2007.05.powershell.aspx

Windows Management Instrumentationの略。
WMIオブジェクトを操作することでWindowsの管理をPowerShellから行うことが出来るらしい。
vagrant -v や vagrant up 実行時に executable file not foundが発生する事象の解決法

﻿# vagrant -v や vagrant up 実行時に executable file not foundが発生する事象の解決法

この問題を確認しているのは、
- Windows 10
- Vagrant 2.0.4
- avast 18.3
の環境で確認しております。

以下のコマンド実行例のように、`vagrant -v`や`vagrant up`実行時に、ruby.exeが環境変数`%PATH%`に見つからないよ。というエラーが発生することがあります。

```shell
C:\vbox\redmine>vagrant -v
Exec error: exec: "ruby": executable file not found in %PATH%

C:\vbox\redmine>vagrant up
Exec error: exec: "ruby": executable file not found in %PATH%
```

この原因として、avastのウィルスソフトによって、ruby.exeが除去されてしまうために発生している可能性があります。
ruby.exeは、デフォルトインストール状態の場合、通常は以下にインストールされています。
`C:\HashiCorp\Vagrant\embedded\mingw64\bin`

このフォルダを確認すると`ruby.exe`が確かに見当たらず、`rubiw.exe`などがあるのみとなっています。

## 対処方法

### avastのウィルスソフト設定による除外設定

avastのウィルスチェックにより、除去されないよう、当該フォルダを、以下avastの参考サイトに従って特定フォルダの除外設定をすることで対応する。
https://support.avast.com/ja-jp/article/168/

### Vagrantの再インストール

除外設定が完了したら、Vagrantを一度アンインストールし、OSを再起動したあとにVagrantを再インストールする。
再インストール後、`vagrant up`コマンドなどの挙動を確認し、当該エラーが発生しないことが確認できればOKです。
RustリポジトリのREADME.mdメンテナンスを自動化する

# はじめに
GitHubの`README.md`はついついアップデートを忘れてしまって、ソースコードとの不一致を起こしてしまいます。
今回は以下の2点について自動化してみました。

- `[dependencies]`のバージョン表記
- サンプルソースのテスト

実際に適用したリポジトリはこちらです。

https://github.com/dalance/fts-rs

## `[dependencies]`のバージョン表記
ここで言うバージョン表記とはRustライブラリのUsageによくある

```
[dependencies]
fts = "0.1.7"
```

というやつです。
まあ[crates.io](https://crates.io)を見に行けば書いてあるのですが、ないと寂しいのでついつい書いてしまいます。

この更新を自動化するには[`cargo release`](https://github.com/sunng87/cargo-release)を使います。
これは`cargo publish`に関連する作業を自動化するツールで、`Cargo.toml`の`version`書き換えやgitのタグ付け、`cargo publish`までを自動でやってくれます。
このツールは`README.md`の書き換えを想定した機能も入っており、`Cargo.toml`に以下のように設定します。

```toml
[package.metadata.release]
pre-release-replacements = [
    { file = "README.md", search = "fts = \"[a-z0-9\\.-]+\"", replace = "fts = \"{{version}}\"" },
]
```

これにより`file`から正規表現`search`にマッチする部分を`replace`に置き換えてくれます。
`{{version}}`はリリースしようとしているバージョンに置き換わります。

## サンプルソースのテスト
Rustではソースコード中のコメントはテストできますが、`README.md`のサンプルソースは対象外です。
`cargo`の[PR](https://github.com/rust-lang/cargo/issues/383)にはずいぶん前から上がっていますが特に入る予定もなさそうです。
というわけで[rust-skeptic](https://github.com/budziq/rust-skeptic)を使います。
カスタムビルドスクリプトを使っているので結構手順が多いですが以下のように使います。
（コードブロック内で```` ``` ````を書く方法が分からなかったので一部``` `` ` ```としています）

- `Cargo.toml`に追記

```toml
[package]
build = "build.rs"

[build-dependencies]
skeptic = "0.13"

[dev-dependencies]
skeptic = "0.13"
```

- `build.rs`を追加

```rust
extern crate skeptic;

fn main() {
    skeptic::generate_doc_tests(&["README.md"]);
}
```

- `tests/skeptic.rs`を追加

```rust
include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));
```

- （必要に応じて）`README.md.skt.md`を追加

```
```rust,skt-default
extern crate fts;

fn main() {{
    {}
}}
`` `
```

- `README.md`のソースコード

```rust

```rust,skt-default
use std::path::Path;
use fts::walkdir::{WalkDir, WalkDirConf};

let path = Path::new( "." );
for p in WalkDir::new( WalkDirConf::new( path ) ) {
    println!( "{:?}", p.unwrap() );
}
`` `

```

`README.md.skt.md`は`README.md`のソースコードが`fn main()`を含まない場合など、そのままではコンパイルできないときに使います。
`README.md`のコードブロックで````` ```rust, テンプレート名````` と指定すれば、`README.md.skt.md`の同じ名前のコードブロックの`{}`に埋め込んだ形でコンパイルしてくれます。

実行時の流れは以下のようになっています。

- `build.rs`が`README.md`からRustのコードブロックを抜き出して`skeptic-tests.rs`を生成
- `tests/skeptic.rs`が生成された`skeptic-tests.rs`をincludeしているので、これを普通にテスト

何かうまくいかない時は以下で実行しようとしているソースコードを確認するといいでしょう。

```console
$ cat ./target/debug/build/*/out/skeptic-tests.rs
```
xubuntu18.04(beta版)の画面が正常に表示されない時

macのvirtualbox 5.2.10 (2018/4/23時点で最新)にて確認。
Lubuntu18.04でも発生した。

## 現象

xubuntu 18.04 の LiveCD で起動すると以下表示となった。

![スクリーンショット 2018-04-23 8.49.59 1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/fc7c7deb-8b98-747a-cbb1-e11d8a79cabe.png)

## 対処

LiveCD起動時に F6 -> Esc キーを押して、
以下のように`nomodeset`オプションを追記し
Enterキー押下

![スクリーンショット 2018-04-23 8.59.20.png](https://qiita-image-store.s3.amazonaws.com/0/25728/82893672-27f0-d1ce-30a2-1ef42a780c2b.png)

正常に表示されるようになった。

![スクリーンショット 2018-04-23 8.58.53.png](https://qiita-image-store.s3.amazonaws.com/0/25728/eedbfd53-f975-03ac-bb6f-b39af5a4fb76.png)


## インストール完了

今度はタスクバーを垂直表示すると文字が90度回転しておらず読めない問題発生・・・。
こちらは修正待ち[昔のですが関連](https://bugs.launchpad.net/ubuntu/+source/gnome-panel/+bug/43066)

![スクリーンショット 2018-04-23 9.14.06.png](https://qiita-image-store.s3.amazonaws.com/0/25728/8248dfba-26e3-9880-e73e-ba2d059c0cdf.png)

## LibreOffice7でリボンUIを使う方法

![1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/74c38e14-3fb0-b3b5-5eb4-dc2d73078b95.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/025e911b-f9f5-0ce4-b5d2-631541770d22.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/b846d235-7da0-f149-dff6-6971da8f794f.png)

一応表示できるが、まだ機能は少なく使いやすいかは不明。