OmniAICreator/Qiita-1.07M huggingface dataset:
systemdのログ確認方法

## 目的
systemdのログ確認方法を調査する
([Raspberry Pi 3 のshutdown時に自動で外付けHDDを停止させる](https://qiita.com/marumen/items/78f65ad946a69603382e) で追加したServiceのログを確認したい)

## 環境
+ Raspberry Pi 3 ModelB
+ OS：Raspbian GNU/Linux 9.4 (stretch)
+ 外付けHDD：EC-PHU3W1(IO-DATA)

## 作業メモ

### systemdについて少し調査

<b>参考サイト</b>
http://enakai00.hatenablog.com/entry/20130914/1379146157
http://enakai00.hatenablog.com/entry/20141130/1417310904

+ Unit

用途に応じた処理の塊
[Raspberry Pi 3 のshutdown時に自動で外付けHDDを停止させる](https://qiita.com/marumen/items/78f65ad946a69603382e) だと"shutdown/reboot/halt時にHDDの電源をOFFする"という用途[^1]
[^1]: 他と比べるとレベルが細かすぎるので本来はUnitのレベルで定義すべきでないものに思えるが・・
現在動作しているunitは以下で確認可能

```
$ systemctl list-units --type=service
  UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
  alsa-restore.service               loaded active exited  Save/Restore Sound Card State
  avahi-daemon.service               loaded active running Avahi mDNS/DNS-SD Stack
  bluealsa.service                   loaded active running BluezALSA proxy
(略)
```

+ target

複数のUnitをグルーピングする
systemdの起点はdefault.target
今回の環境だと、`/lib/systemd/system/default.target`

+ ログ出力

journaldというServiceでログ管理しているらしい

### ログ(journald)の内容確認

<b>参考サイト</b>
http://enakai00.hatenablog.com/entry/20141130/1417310904

本題に戻ってログの内容確認を行う

+ ログ保存用のフォルダを作成

```
$ sudo mkdir /var/log/journal
```

このフォルダを作成しないと再起動ごとにログが消えてしまい、前回shutdown時のログを確認できない

+ ログを確認
 
```
$ journalctl
```

上記で確認できるが大量にログが出るので、`grep`などで必要なものだけに絞る

```
$ journalctl | grep hdd
(略)
 6月 24 23:24:15 raspberrypi hdd_off.sh[1188]: HDD is nothing
```

すると、意図したログ(HDD未接続時のログ)が出力されていることが確認できた

## まとめ
目標達成！
>systemdのログ確認方法を調査する
([Raspberry Pi 3 のshutdown時に自動で外付けHDDを停止させる](https://qiita.com/marumen/items/78f65ad946a69603382e) で追加したServiceのログを確認したい)

これでService作成からログによる動作確認までできるようになった
docomo自然対話APIをGASで利用する

# はじめに
docomoの雑談対話APIが2018年6月末でサービス終了し、自然対話APIに変更されます。
私はLINE bot([at]ffr6825b)の運営で、Google Apps ScriptからこのAPIを利用していたのですが、変更に必要な作業をまとめた記事が少ないと感じたので解説します。
ちなみに、自然対話APIも10月から有料になってしまうそうです(料金未定)。
誰か他にいい日本語会話APIをご存知でしたら教えてください！

GASを使うと、サーバー無しかつ無料で常時稼働のbotを作れるという点がとても魅力的です。
また、データベースの代わりとしてGoogle Spreadsheetを簡単に連携できるのも便利です。
参考: [GASとLINE Messaging APIで同棲生活を便利にした話 - DMM inside](https://inside.dmm.com/entry/2017/12/19-dmmlabotech-adventcalender-_GAS)

# 主な変更点
- エンドポイントが変更された
- ContextIDが廃止され、AppIDが必要になった
- オプションの設定

# 変更後のコード
LINEからクライアントのユーザIDを取得できるので、それをキーとしてAppIDを発行しGASのプロパティに保存しています。
口調の設定(t)は10や20などの番号から、kansai(関西弁)、akachan(赤ちゃん)、指定なし(デフォルト)の指定へと変わりました。
appRecvTime(アプリが最後に取得パラメータを受信した時刻)とappSendTime(送信パラメータを送信した時刻)は何に使うのかよくわかりませんが、適当に指定すれば動きます。


```js
var APIKey = DOCOMO_API_KEY;

// ユーザIDとメッセージから回答を出力する
function getDialogueMessage(userId, mes) {
  var dialogueUrl = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY=' + APIKey;
  var appId = getAppId(userId);
  var requestOption = {
    'language': "ja-JP",
    'botId': "Chatting",
    'appId': appId,
    'voiceText': mes,
    "clientData":{
      "option":{
        't': 'kansai',
      }
     },
    'appRecvTime': Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyyMMdd HH:mm:ss"), 
    'appSendTime': Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyyMMdd HH:mm:ss")
  };
  
  var option = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(requestOption),
  };

  // ドコモAPIにメッセージを投げて返答を受け取る
  var response = UrlFetchApp.fetch(dialogueUrl, option);
  var content = JSON.parse(response.getContentText());

  return content.systemText.expression;;
}

// AppIDを取得する（文脈の記憶に必要）
function getAppId(userId) {

  // GASのプロパティに保存されていればそれを利用
  var props = PropertiesService.getScriptProperties();
  var key = 'appId-'+userId;
  var userAppId = props.getProperty(key);
  if (userAppId) { return userAppId; }
  
  // なければユーザ登録
  var option = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify({
      botId: "Chatting",
      appKind: "LINE bot"
    })
  };
  var registerUrl = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY="　+ APIKey;
  var res = UrlFetchApp.fetch(registerUrl, option);
  var json = JSON.parse(res.getContentText());
  
  // GASのプロパティに値を保存
  props.setProperty(key, json.appId);
  
  return json.appId;
}

```

# わからなかったこと
clientDataでニックネームや誕生日を指定すると、ユーザのニックネーム・誕生日になってしまいました。
botに指定する方法はないのでしょうか？

# 参考文献
[1] [自然対話（雑談対話） | docomo Developer support | NTTドコモ](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4)

[2] [docomo雑談対話APIが終了するので自然対話APIに移行する - Qiita](https://qiita.com/abeyuya/items/3568b8f680ec9390c9d7)

[3] [ChatBot入門-Slack×GAS×docomo雑談対話APIで簡単開発 - Qiita](https://qiita.com/torisankanasan/items/6c1d8cd77269053c02fa)
attr_accessorについて

#使い方

[Railsから入った人へ【attr_accessor】って？](https://qiita.com/Hassan/items/0e034a1d42b2335936e6)
この記事で学ばせていただきました。

attr_accessorには２つの役割があり、

１.クラスの中にあるインスタンス変数を、クラスの外から変更できるようにするためのもの
２.インスタンス変数を戻り値として取ってきてくれるもの
です。

コードで書くと、

```ruby.rb
attr_accessor :name
```
と書いて利用します。

そうすると何が起こるかというと、

```ruby.rb

def name=(w)
 @name = w
end

def name 
 @name 
end

```

というコードが生成されたのと同じことになります。
１つ目のdef name=は@nameに好きな引数の値を入れることができる。
２つ目のdef nameは単に、@nameの中身を返してくれるものです。
大事なのはインスタンス変数に代入してくれるということです。
つまり。。。

```ruby.rb

def call_name
 p @name
end

```

というコードを同一クラス内に書いても、きちんと動くということになります。


#railsにもあるけど見えてないだけ
もちろんこれは、railsにもデフォルトで組み込まれてます。
ですが、わざわざ明示的に書くことがないので、rubyをちゃんと勉強して初めてわかる知識かと思います。

例えば、railsでbookクラスがあり、そのプロパティにnameがあるとして、、、

```ruby.rb
book = Book.new
book.name = "sample"

```

こんな感じで書くことができますよね。
これは、わざわざ書いてはいませんが、 attr_accessor :nameがデフォルトであるからできるんですよね。。。
C#で複数の対象フレームワーク(.NET Standard、.NET Framework など)に対応したライブラリを作成するメモ

# はじめに
今回は、`.NET Standard 2.0`と`.NET Framework 4.5`の両方に対応したライブラリを作成します。確認はしていませんが、その他の構成でも同じ方法でいけそうです。(要検証)
説明が分かりにくいなどあるかと思いますが、ご容赦ください。

より詳しい情報は以下を参照してください。
https://docs.microsoft.com/ja-jp/dotnet/standard/frameworks

実はこれによって、複数フレームワークに対応したNuGetのパッケージの生成もVS上から可能です。

# 1.プロジェクト作成
一旦Visual Studio上でプロジェクトを作成します。プロジェクトの種類はクラスライブラリ(.NET Standard)で作成します。

# 2.プロジェクトファイルの編集
生成された(プロジェクト名).csprojファイルをコードエディタで開き、以下のように変更します。
ちなみに、TargetFramework要素の名前をTargetFrameworksに変更しています。
### 変更前

```(プロジェクト名).csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>
```
### 変更後

```(プロジェクト名).csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

</Project>
```

# その他
## 対象フレームワークを限定して参照を追加する

プロジェクトファイルの`<ItemGroup>`や`<PropertyGroup>`要素に`Condition`属性を設定することによって、特定のビルド構成や対象フレームワークへ適用するかどうかをカスタマイズすることができます。
これがとても便利。
例えば、`<ItemGroup Condition="'$(TargetFramework)' == 'net45'">`とすれば、`.NET Framework 4.5`だけを対象にして、パッケージやDLLへの参照の追加を行えます。

# おわりに
これを機に、複数の対象フレームワークに対応したライブラリを作成してみましょう！
PlayableDirectorのイベントをObservable化する


Played, Paused, StoppedはそれぞれのタイミングをObservable化したもの．

`PlayAsStream`はタイムラインの一覧の流れをStreamとして扱えるようにしたものです．


```csharp
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UniRx;

public static class PlayableDirectorExt {

	public static IObservable<PlayableDirector> PlayedAsObservable (this PlayableDirector src) {
		return Observable.FromEvent<PlayableDirector>(h => src.played += h, h => src.played -= h);
	}

	public static IObservable<PlayableDirector> PausedAsObservable (this PlayableDirector src) {
		return Observable.FromEvent<PlayableDirector>(h => src.paused += h, h => src.paused -= h);
	}

	public static IObservable<PlayableDirector> StoppedAsObservable (this PlayableDirector src) {
		return Observable.FromEvent<PlayableDirector>(h => src.stopped += h, h => src.stopped -= h);
	}

	/// <summary>
	/// WrapModeがNoneのときのみ使える.
	/// 再生から終了までをStreamとみなす．
	/// Disposeで止まる
	/// 再生中ならリスタートする．
	/// </summary>
	public static IObservable<PlayableDirector> PlayAsStream (this PlayableDirector src) {	
		
		return Observable.Create<PlayableDirector>(observer => {
			if(src.state == PlayState.Playing)
				src.Stop();
			
			src.Play ();

			var disposable = src.StoppedAsObservable()
			.Subscribe(x=>{
				observer.OnNext(x);
				observer.OnCompleted();
			});

		 	return Disposable.Create(() => {
		 		 disposable.Dispose();
				 if(src.state == PlayState.Playing)
				 	src.Stop();
			 });
		});
	}
}
```

# Stoppedの呼ばれるタイミング
WrapModeがNoneであれば，

- 再生終了時
- GameObjectごとDestroyしたとき

に呼ばれることが確認できました．
しかし，コンポーネントのenabledがfalseになったときは呼ばれません．
これは中断扱いとなります．
電気系プログラミングガチ素人が、Xamarinでアプリ開発する話　７日目~~

# まえがき
この記事は「Skype工学勉強会」の「アプリ作成部屋　Xamarin」での活動をまとめて記録したものです。参考書が、マイクロソフトさんから布教されておりますので、そちらを和訳しつつ、まとめて記事にしていく流れになっております。
しかし、当方、タグの通り、「電気系」の学生で「ガチ素人」であるため、先輩にまさかりを投げてもらいながら、覚えていく所存でございます。また、もし他に指摘点などございましたらぜひともよろしくおねがいします。

↓Xamarinの布教用PDF、Kindle版もございますので、英語読める方、ぜひとも。
https://blogs.msdn.microsoft.com/microsoft_press/2016/03/31/free-ebook-creating-mobile-apps-with-xamarin-forms/

# 前回までの活動
[６日目](https://qiita.com/sanbongazin/items/b8848adf02b05f6e5ccb)

# 使おうと思ったら・・・「記述古いぞ！」って怒られた・・・
以下の文を実行しようと思ったら、記述が古いとのお達しが・・・

この記述は、どうやら、RuntimePlatform　の構文に纏まったようです。
[デバイス クラス](https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/platform/device)

これによると、書式を以下に変更すると、できるようです

```C#
			//InitializeComponent(); 
#if __IOS__
			//Padding = new Thickness(100, 100, 100, 100);
#endif
			//Padding = Device.OnPlatform<Thickness>(new Thickness(0, 20, 0, 0),new Thickness(0),new Thickness(0));//これでは古い！！
			double top;//これから、
            switch (Device.RuntimePlatform)
            {
                case Device.iOS:
                    top = 20;
                    break;
                case Device.Android:
                case Device.UWP:
                default:
                    top = 0;
                    break;
            }
            Padding = new Thickness(100, top, 100, 0);//これに変更！！


        }

		}
  }
```

のようです。しかし、動かない・・・・
と思った時久々なので、あいつを設定することを忘れていたのです・・・

4日目あたりの・・・あいつをさ・・・

* まずは、v4を検索し、Xamarinサポートをインストール
* csprojファイルに記述を追加

で、解決しました。

またまた長かった・・・

# あとがき
みなさんお久しぶりです！！
教育実習で実はプログラミングに触る機会が失せていた中、
土日で、禁断症状が出まして、Paizaで気を紛らわせましたw

また、駄文ではありますが継続していきますのでよろしくお願いします！
Watson Language Translator でポーランド語やロシア語が翻訳可能になった

# 6月15日付で英語ドキュメントが更新された
Watson language translator でポーランド語やロシア語が翻訳できるようになったらしい、と聞いて試してみました。
ところが、リファレンスの [翻訳モデル](https://console.bluemix.net/docs/services/language-translator/translation-models.html) ページを見ると、ポーランド語やロシア語載っていないですねぇ？
![languages_180223.png](https://qiita-image-store.s3.amazonaws.com/0/27855/b5653350-d722-35d6-3773-01226ce35501.png)

念のために、ページの一番下の言語を日本語から英語に変えたら、ドキュメントの更新日付が2018年2月23日ではなく6月15日になって、最新の対応状況が表示できました。ちなみに、API の Ver 2 を見ると、6月12日付けの更新で、その3日後にさらに Ver 3 に変わったんですね。
![languages_180615_in_en.png](https://qiita-image-store.s3.amazonaws.com/0/27855/7666753a-a4ec-7544-fcfd-e97217f1d550.png)

2月23日の日本語版ドキュメントと6月15日付けの英語ドキュメントを比較すると、翻訳可能言語では、下記のような変化があります。
    - 2種類あったアラビア語が1つになる
    - 中国語は、大陸用の簡体字(Simplified)と台湾用の繁体字(Traditional)の2種類に分かれる
    - オランダ語 (Dutch)、ポーランド語 (Polish)、ロシア語 (Russian)、トルコ語 (Turkish)が追加された。

および、識別できる言語の数は変わりませんが、クメール語が中央クメール語 (Central Kumer) に変更されていました。クメール語の中央方言のこと？

# 非公式でヒンディー語やチェコ語にも対応？
Node-RED エディターで早速 Language Translator のノードをクリックして翻訳元 (Source) と翻訳先 (Target) の選択肢を見ると、面白いことに気づきました。
![languages_to_en_180615.png](https://qiita-image-store.s3.amazonaws.com/0/27855/a563dab1-2be3-cb43-80e4-bebf37384a87.png)
英語から・または英語へ　の翻訳の場合、英語ドキュメントに掲載されているほかに下記の5種類も選択可能になっています。
    - cs (チェコ語)
    - da (デンマーク語)
    - fi (フィンランド語)
    - hi (ヒンディー語)
    - sv (スウェーデン語)

ほかの組み合わせも調べてみると、ca (カタロニア語) がスペイン語との間で翻訳可能になってます。

上記の言語の翻訳も近いうちに正式対応されるのでしょうか？楽しみです。

# 試してみた
[今年1月に書いた記事](https://qiita.com/strysd/items/592ad17f6108994affae) のフローを手直しして、ロシア語、ヒンディー語、チェコ語が英語へ翻訳できるか試してみました。

ロシア語
![180624_try_russian.png](https://qiita-image-store.s3.amazonaws.com/0/27855/ca4ce5bd-0af4-effc-7a59-c2c30e86545c.png)

ヒンディー語
![180624_try_hindi.png](https://qiita-image-store.s3.amazonaws.com/0/27855/cc8251a6-68f6-ffb6-7e6d-b32a59f22b27.png)

チェコ語
![180624_try_cz.png](https://qiita-image-store.s3.amazonaws.com/0/27855/2b1fc379-019d-04a3-5ab5-3041e1ab93da.png)

以上のように、公式対応のロシア語から英語への翻訳のほか、ヒンディー語とチェコ語からも何となく翻訳できているらしいことがわかりました。

ちなみに、テストに使った Node-Red のフローは [Github で公開](https://github.com/strysd/watsontranslator/blob/master/igtranslator.json)しています。

# 東欧言語がさらに充実 (2019/09/19 追記)
2019/08/22版の API では、下記の言語が翻訳可能になっています。（東ヨーロッパ各国の言語のみ掲載）
エストニア語、クロアチア語、チェコ語、ハンガリー語、
スロバキア語、スロベニア語、ブルガリア語、ポーランド語、
ルーマニア語、ロシア語

現時点での EU 加盟国の言語に対応させるには、あと2種類、ラトビア語とリトアニア語も追加すると完成ですね！
XCode10の早くなったビルドを試してみる


# まえがき

iOSアプリエンジニアの多くが感じる、「ビルドに時間がかかる」という苦悩が、XCode10の新しいビルドシステムでマシになるそうなので検証してみました。

# 環境

- マシン
    - MacBook Pro 2017 13inch
        - OS: High Sierra ver 10.13.5
        - CPU : Core i7-7660U
        - RAM : 16GB

- IDE
    - XCode10 beta2(10L177m)

- 比較対象のIDE
    - XCode9.4.1


# 方法
　事前にビルド時間を表示するオプションを有効にした状態で、[TrySwift](https://github.com/tryswift/trySwiftAppFinal/tree/2acf568e337003538c604c9e70b8cd4e66aebd63)をクリーンビルドして時間を測定してみます。設定などはcloneしたままの状態で変更しません。TurboBoostを考慮して、10回ビルドをし続けて最速の結果を比較してみます。

TurboBoostを切ってやっても良かったのですが、実際に利用する際の環境に近づけたかったので、切らずに検証します。


# 結果

- XCode 9.4.1

<img width="494" alt="Xcode9.png" src="https://qiita-image-store.s3.amazonaws.com/0/105287/fa15a8a0-5627-8e53-d6a8-2a570ee7f9b1.png">


- XCode 10 beta2(10L177m)

<img width="503" alt="Xcode10.png" src="https://qiita-image-store.s3.amazonaws.com/0/105287/9b00b200-7fb8-017e-ea8d-c2bcbca42021.png">

# 結論
XCode10を利用することでTrySwiftの場合、ビルド時間が3/5に短縮されることがわかりました。  


これまでビルド時間が長すぎて感じたつらさがある程度緩和されたのではないでしょうか。XCode10の正式リリースが楽しみですね！

# 宣伝
[ブログ](https://5hyn3.github.io/)やってます。こちらもよろしくおねがいします。
Node.jsでサクッとWebサーバーつくってみる

<h1>対象者</h1>
<ul>
<li>JavaScript初心者から脱したい方</li>
<li>とりあえずサーバーつくってみたい方</li>
</ul>
<h1>まずNode.jsとは</h1>
<ul>
<li>JavaScriptで動作するサーバー環境</li>
<li>JavaScriptでWebサーバーを「つくる」ことができる</li>
<li>JavaScriptのフレームワークではない(Node.jsのフレームワークがある）</li>
</ul>
<h1>Node.jsの特徴</h1>
<ul>
<li>ライブラリが多数あり、簡単に利用できる</li>
<li>サーバー、クライアントの両側で同じ言語が書ける</li>
<li>非同期I/O、ノンブロッキングI/Oを採用している(要は処理待ちの間に別の処理を行うことができる)
<li>上記の理由で大量のアクセスを処理するのに向いている(例：チャットアプリとか)</li>
</li>
</ul>
<h1>実行環境</h1>
<ul>
<li>MacOS
</ul>
<h2>作成手順</h2>
<ol>
<li>公式サイトからNode.jsをインストール↓<p><a　href="https://nodejs.org/ja/">https://nodejs.org/ja</a></p></li>
<li>インストール後、下記のコマンドを入力してバージョンが返ってくればOK</li>
<div>

```
$ node -v
```
</div>
<li>以下の２つのファイルを作成<p>※作業フォルダを作成して、その中にファイルを作成するようにしてください</p></li>
<div>

```sample.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>test</title>
</head>
<body>
  <h1>Hello World!!</h1>
</body>
</html>
```

```sample.js
const http = require('http')
const fs = require('fs')
const server = http.createServer(function(req,res){
  fs.readFile('./sample.html','utf-8',function(err,data){
    res.writeHead(200,{'Content-Type':'text/html'})
    res.write(data)
    res.end()
  })
})
server.listen(8080)
console.log('server start-up!')
```

</div>
<li>ターミナルを開き、ファイルが格納されているフォルダに移動し下記のコマンドを入力し、サーバーを起動<p>※正常に起動すれば'server start-up!'が即座に表示されます</p></li>
<div>

```
$ node sample.js
```
</div>
<li>Webブラウザで以下のURLを入力して実際に確認してみてください
<p>http://localhost:8080</p></li>
</ul>
<p>以上で終了です。ローカル環境ですが実際にサーバーをたてることができました。構文の意味とかは別記事で。

<h3>あとがき</h3>
本記事をご覧になってもらってJavaScriptでサーバーたてることができた小さな快感を味わってもらったら幸いです。(JavaScriptすごいすわ)
今回簡単にサーバーをたてましたが、私はNode.jsの知識についてはまだまだですので、この記事を修正・改善したり、他の記事を書いていきたいと考えています。
Nuxtで特定パス配下にサイトを公開する際の設定

# はじめに
最近、Nuxtを利用してサイトを作りましたが、諸事情によりドメインのルート配下ではなく、特定パス配下で公開する必要がありました。ルーティングに加えて、今回導入していたPWAにおいても設定が必要でしたので、そのメモです。

# 想定するサイト公開URL
`https://yourdomain.com/yourpath`

# サイト開発環境
* Nuxt
* @nuxtjs/pwa
* (@nuxtjs/onesignal)

# 設定内容
```js
/*
** Module configuration
*/
modules: [
  '@nuxtjs/onesignal', // OneSignalを使う場合は追加
  '@nuxtjs/pwa'
],

/*
** OneSignalを使う場合は追加
** Web Push(OneSignal) configuration
*/
oneSignal: {
  // ...省略
  path = '/yourpath';
  importScripts = ['/yourpath/sw.js']; // onesignal用のスクリプトの中でswが読み込まれるようになる
},

/*
** workbox configuration
*/
workbox: { 
  // ...省略
  swURL: '/yourpath/sw.js', // これを設定しないとswのregistrationでうまくいかない
  swScope: '/yourpath' // スコープは通常公開パスに設定されるが、一応明示的に指定
},

/*
** route configuration
*/
router: {
  base: "/yourpath/", // ここを設定しないとサイトが表示されない
},

/*
** PWA configuration
*/
manifest: {
  // ...省略
  start_url: "/yourpath/" // ←最後の'/'が非常に重要。忘れると※1のようなエラーが発生
},
```

※1:
**User will not be prompted to Install the Web App**
Service worker does not successfully serve the manifest's start_url


# おわりに
Nuxt良いですね。サイトをささっと作ってしまいたいときに、面倒な作業は既に設定済みで開発に集中できる感があります。
Obnizでプラレールを制御（サーボモータを動かすテスト）

#概要
Obnizの作品事例を見て、「これは一番簡単に始められるIoTでは？？」と思い購入してみました。

[本家のチュートリアル(Lesson: Servo Motor)](https://obniz.io/doc/lessons_servo_motor)

にあるサーボモータを制御するページを試してみたのですが、Obniz開封後30分でサーボモータがインターネットにつながってしまい、あまりの簡単さに感動しました。

本家と全く同じだとつまらなので、「サーボモータをつなげられるものはないかな・・・」と家の中を探してみて見つけたのがプラレールでした。そのため、本編はプラレールが主となっています。

#使用機材
+ [obniz](https://obniz.io/)
+ [サーボモータSG90](http://amzn.asia/bVxq1Rn)
+ ストップレール（レバーを倒すと電車を止められるレール）
+ クリップ

#手順
1. [チュートリアル(Lesson: Servo Motor)](https://obniz.io/doc/lessons_servo_motor)の通りに行い、サーボが動くことを確認（配線＋コードをコピペ＋実行で10分程）
2. ストップレールとサーボを段ボールに張り付ける（今回はスイッチサイエンスさんの段ボールを使用）
3. クリップをライターで炙り、ストップレールに連結用の穴をあける（子供はもう使わないので加工してしまいました）
4. 連結（ストップレールのレバー＋クリップ＋サーボ）
5. 動作確認
6. 遊ぶ！

#動画
![videotogif_2018.06.24_21.31.51.gif](https://qiita-image-store.s3.amazonaws.com/0/181708/005fcca4-18b4-f49a-177f-613aba30802b.gif)

よく見て頂くとObnizの液晶部分にPINの役割が表示（gnd:0, vcc:1, signal:2）されていて感動しました。

#感想
チュートリアルには他にもLEDを点滅（Lチカ）させるものもあり、
+ LED
+ サーボ
が使えようになれば、プラレールワールドも飛躍的にグレードアップしそうです。

夏休みの工作に子供と色々試してみたいと思います。
(あれ。。。IoTはどうした？？？センサー、カメラをつけて室外からプラレールを操作したらIoTになるのかな・・・・）
MacでHomebrewをインストール

# Homebrewの公式サイト
https://brew.sh/index_ja.html

# ターミナルに入力
```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

# あとは待つ
途中で
```Downloading Command Line Tools (macOS Sierra version 10.12) for Xcode```
XcodeかCommand Line Toolsインストールされる模様。
時間かかりました。

```
- Run `brew help` to get started
- Further documentation: 
    https://docs.brew.sh
```
ここまで出たら完了。

インストールしているHomebrewのバージョン確認は
```brew --version```

# どこのディレクトリにあるのか？
ここで迷ったので。
インストール先は'usr/local/Homebrew'
Homebrew経由でインストールしたものは'usr/local/Cellar'配下に。
JS基礎ーasync/await

# 初めに
非同期処理は、JavaScript (Node.js) で開発する上で避けては通れない。
自分は業務中でよくPromiseで非同期処理を行いますが、今回はasync/awaitとの仕組みを使ってみる。

# async/awaitは何
簡単に言うとasync/awaitとは**簡潔に非同期処理が書ける**やつ。
基本的な形式：

```
async function Fn(){
    var variable = await getVariable(name);
}
```

async ：関数やラムダ式の前につけ、戻り値をPromiseに加工する
await ：Promise.resolveの値を取得するまでブロッキングし、同期処理のふうに非同期処理を書ける

検証しましょう：

```javascript

async function testAsyncAwait() {
    return 'show asyncawait';
}

const result = testAsyncAwait();
console.log(result);
```
実行すると

```
PS C:\Users\ma\work\nodejs> node .\async_await.js
Promise { 'show asyncawait' }
```
戻り値がPromise形とのことが分かった。

# エラー処理
awaitの後ろについたのでpromiseオブジェクトなので、rejectedの可能性がある。
下記のようにtry...catchでエラーをcatchする。

```
async function myFunction() {
  try {
    await Promise();
  } catch (err) {
    console.log(err);
  }
}
```

# 終わり
そもそもasync/awaitもPromiseを利用しているため、Promise自体を理解しないとまずいかも。。
次回はPromiseを整理してみましょう。
Array.reduceとasync/awaitを使って関数を順番に実行する

Array.reduce()を使う


```js
const axios = require('axios');

// https://qiita.com/asa-taka/items/888bc5a1d7f30ee7eda2
const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));

const users = [
    'tj',
    'dougwilson',
    'jonathanong',
    'defunctzombie',
    'aheckmann',
    'slaskis',
    'ciaranj',
    'michaelahlers',
    'blakeembrey',
    'notrab',
    'riadhchtara'
];

async () => {
    const names = await users.reduce(async (prev, user) => {
        try {
            const p = await prev;
            const { data } = await axios.get(`https://api.github.com/users/${user}`);
            // rate limit対策
            await sleep(1000);
            return [...p, data];
        } catch (err) {
            console.log(err);
        }
    }, []);
};
```
CakePHP2のHttpScoketで複数のホストにSSLアクセスするとSSL証明書の検証に失敗する


CakePHP2.10.10で確認。

```
$httpSocket = new HttpSocket();
try {
	$httpSocket->get('https://example.com');
	$httpSocket->get('https://netcommons.ryus.co.jp');
} catch (Exception $e) {
	debug($e->getMessage());
}
```
こんなコード実行すると

```
stream_socket_client(): Peer certificate CN=`*.coreserver.jp' did not match expected CN=`example.com'
stream_socket_client(): Failed to enable crypto
stream_socket_client(): unable to connect to ssl://netcommons.ryus.co.jp:443 (Unknown error)
```
こんな例外投げられる。

というわけで別ホストにもSSL接続するときは、新たに ```HttpSocket``` の別インスタンスつくって接続した方がいいようです。

追記
別ホストに接続する前に ```reset();``` 呼べば良かっただけかも

```
$httpSocket = new HttpSocket();
try {
	$httpSocket->get('https://example.com');
	$httpSocket->reset(); // これを追加
	$httpSocket->get('https://netcommons.ryus.co.jp');
} catch (Exception $e) {
	debug($e->getMessage());
}
```

これなら大丈夫そう
rails new したときに openssl でつまずく


新しいrubyのバージョンがでてビルドでつまずいて、結局元のバージョンのまま使ってたりしたんですが、ruby 2.6.0-preview2も出た事なのでそうも言ってられないという事で腰を入れて(という程でもないですが)調査しました。

railsのインストールまではなんとかできるのですが、```rails new```でopensslが読み込めないというエラーが出てしまいます。



```
/Users/ISD/.rvm/rubies/ruby-2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- openssl (LoadError)
```

試しに ```gem install openssl``` してもうまくいきません。

いつもならググって対応策が見つからなくてよくわからんで過ごすんですが、ログを見て見るとどうやら1.0.1よりバージョンが低いと判断されている様です。
(実際は openssl 1.0.2o_2 がインストールされてます。)

```
checking for OpenSSL version is 1.0.1 or later... -------------------- no

"gcc -I/Users/ISD/.rvm/rubies/ruby-2.5.1/include/ruby-2.5.0/x86_64-darwin17 -I/Users/ISD/.rvm/rubies/ruby-2.5.1/include/ruby-2.5.0/ruby/backward -I/Users/ISD/.rvm/rubies/ruby-2.5.1/include/ruby-2.5.0 -I. -I/usr/local/Cellar/openssl098/0.9.8zh/include  -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -fno-common -pipe    -c conftest.c"
conftest.c:6:20: error: 'conftest_const' declared as an array with a negative size
int conftest_const[(OPENSSL_VERSION_NUMBER >= 0x10001000L) ? 1 : -1];
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
```


ログをもう少し良く見て見ると```openssl098```というのがあります。

どうもこのファイルがあるとバージョンが低いと判断される様です。

という事で削除すると ```gem install openssl``` が通って ```rails new``` でプロジェクトが作成できました。


だいぶ古いMacからずっとファイルを引きずってきているのでゴミの様に古いファイルが残っていたためのようでした。
VimのAirline行表示がバグる問題

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116252/72b016e8-8597-b198-9c2b-e9675ab16b84.png)

解決できたので一応投稿。
set ambiwidth=double
これをvimrcから消すと直った。
画像で1/485ってなっている部分です。
コメントアウトして検証したらこれのせいだと判明した訳で原因は調べてないしわからない。
個人的にはVimの設定にはあまり時間かけたくないです。
かかってるけど・・・。
C言語のポインタの簡素な説明

#はじめに

C言語でつまずき易い個所の一つにポインタというものがあります。
私自身ポインタを覚えるのに苦労しましたし、C言語から少し離れていると忘れがちになるので今回の記事を書くことにしました。

#ポインタとは何か
　変数を宣言する際は対象の型の後に変数名を下記のように書きます。値を入れる場合はさらに=と値を追加します。
　ポインタはこのような値ではなく、メモリのアドレスを持った変数のことです。
```
  int a;
  int b = 1;
```
　ポインタはこのような値ではなく、メモリのアドレスを持った変数のことです。
```
　int *c;
```
 これだけではただポインタ変数が宣言されただけです。これに配列を入れてみます。

```
　int *c;
  int array[3] = {1,2,3];
  c = array;
```
これでポインタ変数cにint配列arrayのアドレス先頭を指すようになりました。これでcからアドレスを辿って配列arrayの値を扱えるようになります。
変数cの前に*を付けると、アドレス内部の値を取りだしてくれます。しかし取り出せるのは先頭の値だけなので他の配列の値を取りだす場合は、アドレスに
加算して配列内部の別の値のアドレスとすることで取り出せるようになります。

```
  printf("%d\n",*c);
  //output: 1
  printf("%d\n",*(c+1));
  //output: 2

```

ではこれが何の役に立つのか。値をコピーするだけなら別の変数に同じ値を入れるだけでいいはずです。
役に立つのはメモリの節約です。
同じ値をコピーする場合はその変数と同じだけメモリを使うことになります。しかしポインタであればどのような変数であろうともアドレスだけで同じ値を参照できるようになるのです。

#おわりに
以上でポインタの説明はおわりです。
Railsアセットパイプラインのpathにvendor/assetsを設定する方法

# 実行環境

- ruby 2.5.0
- Rails 5.2.0

# 目次

1. プラグイン/ライブラリファイルの各々の保存場所について
2. vendor/assetsにpathを通す方法

## 1. ファイルの各々の保存場所について

用途によって3つに分けられます！

#### 1. <font color="Red">app/assets</font>  ・・・アプリ全体として共通管理するファイルや独自のファイルを置く（app/assets/javascripts/application.jsとか、app/assets/javascripts/posts.coffeeとか）

####2. <font color="Red">lib/assets</font>  ・・・アプリケーション外で共通のもの

####3. <font color="Red">vendor/assets</font>  ・・・ サードパーティ（外部ベンダーが提供したもの、プラグインとかライブラリ）　←今日まとめるのはココ！


## 2. vendor/assetsにpathを通す方法


```bash:ファイル構造
vendor
└── assets
    ├── javascripts
    │   └── tagsinput.js # ←今回使用するプラグイン
    └── stylesheets
        └── tagsinput.css # ←今回使用するプラグイン
```

外部のライブラリをvendor/assets配下に配置します。
配置した後は、app/assets/javascripts/application.js　や app/assets/stylesheets/application.scss のマニュフェストファイルに読み込むよう記述します。

```ruby:app/assets/javascripts/application.js
//= require rails-ujs
//= require activestorage
//= require jquery3
//= require jquery_ujs
//= require popper
//= require tagsinput # ←今回このプラグインを使用したいため、新たに記述
//= require bootstrap
//= require bootstrap/customize
//= require_tree .
```

```ruby:app/assets/stylesheets/application.scss
@import "bootstrap";
@import "font-awesome";
@import "bootstrap/custmize";
@import "tagsinput"; # ←今回このプラグインを使用したいため、新たに記述
```

以上で、設定は完了なのですが。。。<h3><font color="Red">pathが通ってないと使えません。</font></h3>当たり前ですが
そこで、次にpathが通っているのか確認します。

```bash:
rails c #コンソールを起動
> Rails.application.config.assets.paths #pathを確認
```

```bash:今回確認したらpath通っていたためpathを通す作業は不要でした。
=> ["/Users/username/app_name/app/assets/config",
 "/Users/username/app_name/app/assets/images",
 "/Users/username/app_name/app/assets/javascripts",
 "/Users/username/app_name/app/assets/stylesheets",

 "/Users/username/app_name/vendor/assets/javascripts",
　# ↑vendor/assets/javascriptsにpathが通っているのでその直下のファイル名をapplication.jsに記述して使う
 "/Users/username/app_name/vendor/assets/stylesheets",
　# ↑vendor/assets/stylesheetsにpathが通っているのでその直下のファイル名をapplication.scssに記述して使う
```

---

pathが通っていない場合も今後の自分のために書いときます（試すときがきたら以下の記述は修正します）

```bash:vendor/assets配下にpathが通ってない
=> ["/Users/username/app_name/app/assets/config",
 "/Users/username/app_name/app/assets/images",
 "/Users/username/app_name/app/assets/javascripts",
 "/Users/username/app_name/app/assets/stylesheets",

# 下記の記載がない場合、pathが通っていない
#  "/Users/username/app_name/vendor/assets/javascripts"
#  "/Users/username/app_name/vendor/assets/stylesheets"

```

```ruby:config/initializers/assets.rbに以下を記述
Rails.application.config.assets.paths << Rails.root.join("vendor", "assets", "stylesheets")
Rails.application.config.assets.paths << Rails.root.join("vendor", "assets", "javascripts")

# 記述が完了したらサーバーを再起動して読み込ませる。[ctr + c]→[rails s]
```
これでマニュフェストファイルに「vendor/assets/javascripts」と「vendor/assets/stylesheets」以下のファイル名で記述すると使えるようになります。
CGImageは画像の向きを保持していない

## CGImageは画像の向きを保持していない

画像編集アプリ([iOSCameraSample – GitHub](https://github.com/YutoMizutani/iOSCameraSample)) を作成している際にハマったため，備忘録として記事にします。
記事が古くならないよう，参照を添えてAgeておきます。*知らないと必ずハマります。ハマりました。*

## 発生した問題

コントラストを変更しようと編集した`UIImage`を`UIImageView`に反映させた際に，何故か画像が横に回転してしまった。

## 原因

`CGImage`が向きのパラメータを保持していないことが原因であった。

画像のコントラストを変更するために必要な，
`UIImage` -> `CGImage` -> `CIImage` -> `CGImage` -> `UIImage`
へとキャストしていく過程で，

`UIImage`から`CGImage`への変換時に方向パラメータを喪失した。

```swift
let uiImage = UIImage()
let cgImage = uiImage.cgImage
```

`CGImage`から`UIImage`への変換時に
`UIImage.imageOrientation`がnilとなり，表示先の`UIImageView`が方向を読み取れなくなったことが原因。

```swift
var uiImage = UIImage()
let cgImage = uiImage.cgImage
uiImage = UIImage(cgImage: cgImage, scale: 0, orientation: nil)
```

## 対策

`UIImage`の向きのパラメータを保持し，`UIImage`にキャストする際に向きのパラメータ(`UIImageOrientation`)を注入する。

```swift
func translate(from image: UIImage) -> UIImage? {
    guard let cgImage = image.cgImage else { return nil }
    let ciImage = CIImage(cgImage: cgImage)
    let ciContext = CIContext(options: nil)

    /* CIImageを使用した画像編集処理 */

    guard let cgImage: CGImage = ciContext.createCGImage(image, from: image.extent) else { return nil }
    let result = UIImage(cgImage: cgImage, scale: 0, orientation: image.imageOrientation)
    return result
}
```

## 参考

[画像に何か加工を行った際に向きが勝手に変わってしまう](http://gokujo.hatenablog.jp/entry/2013/02/28/223939)
[iPhoneカメラで撮影した画像のUIImageからCGImageを取り出すと90度傾く問題の解決法](http://blog.katty.in/105)
[Swift で UIImage の方向を強制的に変換する](https://qiita.com/kitsuyui/items/c8d76acfa0ecd6570fdb)
【Ruby】配列の中のハッシュ

#配列とハッシュ
>配列はpythonでいうところのリスト、ハッシュはpythonでいうところの辞書に近いイメージ。
しかしrubyでは配列の中にハッシュを入れられる（というかハッシュを配列できる）仕組みがあり、これはpythonのリスト、辞書の関係とは異なる部分だと思う。

#カープ選手に当てはめてみてみよう
>変数carp_playersという配列の中に、{name:"選手名", number:背番号}というハッシュを作り、それを何名か並べてみた。

```ruby:
carp_players =[{name:"uemoto", number:0},
               {name:"tanaka", number:2},
               {name:"kokubo", now_in:"yuu"}]
#最後の小窪選手だけ、背番号ではなくnow_inキーをつけて"yuu"という値を与えた。
#悪口ではない、２軍の由宇球場で頑張っていないで早く1軍で活躍してくれというエールの意味だ。


#それでは実験①
ground = carp_players[0]
puts ground[:name]      # => uemoto

#実験②
ground = carp_players[1]
puts ground[:number]    # => 2

#実験③
ground = carp_players[2]
puts ground[:number]    # =>    (何も出てこない)

#実験④
ground = carp_players[2]
puts ground[:now_in]     # => yuu
```

>結論

配列の中のハッシュ同士のキーは必ずしも合わせないといけない訳ではない。
そして入ってるキーを指定すればちゃんと値が出てくる。
Vagrant + docker-symfony でホスト OS のブラウザからアプリケーションにアクセスする

# 背景

* Symfony を Vagrant + Docker で動かしたいため、Docker イメージの [docker-symfony](https://github.com/eko/docker-symfony) を使った
* コンテナの起動まではできたものの、動作確認のためにホスト OS から PHP アプリケーションへのアクセスができない
  * nginx の "404 Not Found" が出る

# 対処方法

## 1. Vagrantfile にポートフォワード設定をする

* 基本的なところだが、改めて設定を確認する
* 以下のような記述がされていれば OK (筆者は 8000 -> 8000 に設定している)

```ruby:Vagrantfile
  config.vm.network "forwarded_port", guest: 8000, host: 8000
```

* VM をすでに起動している場合は `vagrant reload` して反映させておく

### 備考

* フォワード先のポートは `docker-compose.yml` の `ports` と辻褄をあわせておくこと

```yaml:docker-compose.yml
    nginx:
        build: ./nginx
        ports:
            - "8000:80"
    :
```

## 2. ホスト OS の hosts に `symfony.localhost` を追加する

* 個人的にはここが盲点だった
* docker-symfony を使う場合は hosts に `symfony.localhost` を追加する必要がある
  * …が、てっきり **ゲスト OS** の hosts だけに追加すればよいのだと勘違いしていた
  * 実際は **ホスト OS** (Windows なり Mac なり Linux なり) の hosts に追加が必要
* Windows XP 以降であれば `C:\Windows\System32\drivers\etc` に hosts があるので以下を追加

```text:hosts
127.0.0.1 symfony.localhost
```

## 3. ホスト OS のブラウザからアクセスする

* URL は `http://symfony.localhost:8000/`
  * ポートは適宜変えること
* Welcome!
![image.png](https://qiita-image-store.s3.amazonaws.com/0/49525/b05ce173-b261-aef8-4f03-86ff39c2b93a.png)
SeleniumでIEをNode.jsから動かしてみた

#はじめに
突如SeleniumでInternet Explorerを動かしてみたくなりました。
ざっと下調べしたところ、Selenium/Node.js/IEの組み合わせの記事はなさそうだったのでやり方をまとめます（あったらごめんなさい）。
Google ChromeやFireFoxではSelenium IDEというGUIを使えるようですが、IEには対応していないみたいですね。

#インストール手順
OS : Windows10
Selenium Webdriver（Node.js版）のバージョン : 4.0.0-alpha.1

インストールは以下のコマンドを打つだけです。

```none:Seleniumのインストール
$ npm install selenium-webdriver
```

※事前にNode.jsとnpmをインストールする必要があります。

次に、ドライバーを以下のURLからダウンロード、解凍して環境変数Pathにパスを通しておきます。
https://www.seleniumhq.org/download/
画像の赤いエリアですね。

![www.seleniumhq.org_download_.png](https://qiita-image-store.s3.amazonaws.com/0/227999/3930bcb9-3789-ed4d-e8bf-f02866c818cd.png)


#設定
IEだと事前にいくつか設定が必要です。

### IEの設定

* 文字サイズを100%にする
* 保護モードを有効にする
インターネット、ローカル イントラネット、信頼済みサイト、制限付きサイトのそれぞれで保護モードを有効にする（Internet Explorerの再起動が必要）のチェックを入れる

<img width="338" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/227999/4ee54b2c-0f80-d333-d43b-5726112b3a5b.png">



レジストリの設定が必要・・・との記事も見かけましたが必要なさそうで安心しました。

### ソースコード
以下のコードはチュートリアルのコードをほぼ同じで、Googleで検索するだけです。Googleの検索用テキストボックスには`name="q"`という属性がついているため、そこにキー入力をしています。

```javascript:ie_search.js
const {Builder, By, Key, until} = require('selenium-webdriver');

(async () => {
  let driver = await new Builder().forBrowser('internet explorer').build();
  await driver.manage().window().maximize();
  await driver.get('http://www.google.com');
  await driver.findElement(By.name('q')).sendKeys('アデリーペンギン', Key.RETURN);
})();
```



#実行
```javascript:Seleniumの起動
$ node ie_search.js
```

<img width="1128" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/227999/9928d092-1719-0e04-78dc-9733d38e5c38.png">

できました。


#おわりに
IEは無事動かせましたが、欲を言うとheadlessで動かしたいものです。
Phantom.jsは更新停止したようですし、IEをheadlessで動かすよい感じの方法はないものでしょうか・・・
セキュリティエンジニアになるための道筋が見えた？(インフラ勉強会　LT分まとめ　2018/06/23)

昨日、インフラ勉強会で「セキュリティエンジニアになりたい私の相談に乗って下さい！！」を私の登壇で行いました。


そこでセキュリティエンジニアになるためのスキルやキャリアをまとめたいと思います。
あくまでも相談して私の自身の考えです。

※インフラ勉強会:インフラエンジニア初心者から誰でも参加できるオンライン勉強会です。
　              参加方法:https://wiki.infra-workshop.tech/lets-begin 



・自己紹介(背景)
私はこれまでセキュリティエンジニアになり、サイバー空間の犯罪をなくしたいと思っていました。
しかし数あるセキュリティエンジニアとしての仕事の特定のなにかこれがしたい！というものはありませんでした。

というよりも全部に興味があるといったイメージです。




・やっとその見つけ方がわかった


講演の後も雑談で多くの方に相談していただいたのですが、それは「どのレイヤーのセキュリティを守りたいのか」です。

レイヤーとはPC同士が通信行う際の過程にいくつかの区切りをつけて、通信の流れを理解しやすくしてくれる考え方の１つです。
エンジニアの方なら必須の考え方ですよね。


これからは自分が興味のある分野がどのレイヤーに当たるのかを明確にして、そのレイヤーの知識を深く学んでいくことが重要だとわかりました。

以上!
CentOS(nginx)でDockerのcloud9をサブディレクトリに

最近デスクトップクラウド化計画の一環でクラウドエディタを試しています。でもVSCodeの快適さに慣れてしまうとなかなかエディタを移れませんね……

そんな中cloud9を試してみようとDockerHubからkdelfour/cloud9-dockerを落としてみたのですが、普通に使う分には問題なさそうでしたがリバースプロキシを通して`http://hostname:port/subdir/`とアクセスすると、`http://hostname:port/ide.html`に飛ばされちゃって、うまくいかないわけです(´・ω・｀)

じゃぁって`http://hostname:port/subdir/ide.html`でアクセスすると、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140718/2c8335a1-c505-e0a4-4183-3929b213d799.png)
みたいなチップス表示がでて先に進みません。


「cloud9 subdirectory」で検索してもissueは上がっているものの「それが、何か？」みたいな感じになってて修正が期待できない感じなのですが、英語弱者なのでいまいちよくわかりません。コードを眺めて/ide.htmlの部分を/subdir/ide.htmlのように書き換えてみても、いまいち動きが変わらず力尽きました。

そんな中「参照先をリバースプロキシで書き換える方法があるよ」的な書き込みを見かけたので試してみたらうまく言った感じがするので、共有してみようと思います。

参考になったのはこちら。
https://github.com/c9/core/issues/237

# １．nginxでsub_folderを使えるようにする

CentOSのnginxはそのまま入れるとsub_folderが使えないようで、confに記述するとエラーがでます。なのでモジュールを入れるべきなのですが、どれ入れたらいいのかわからなかったので全部パックを入れました。

```bash
sudo yum install nginx-all-modules
```

さすがに全部入りだと一発で動きました。

# ２．nginxにコンフィグを追加

`http://hostname:3080/ide/ide.html`でアクセスしてきたのをdocker(localhost:8080)に回します。

proxy_set_headerはいつものセットで、sub_filterのところを参考リンクから拾ってきました。結構書き換えが必要だったんですね。

```nginx:/etc/nginx/conf.d/ide.conf
server{
    listen 3080;

    proxy_set_header    Host    $host;
    proxy_set_header    X-Real-IP    $remote_addr;
    proxy_set_header    X-Forwarded-Host       $host;
    proxy_set_header    X-Forwarded-Server    $host;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    location /ide/ {
        proxy_pass http://localhost:8080/;

        sub_filter_types        txt/html txt/css application/javascript;
        sub_filter              "/configs" "/ide/configs";
        sub_filter              '"/static' '"/ide/static'; #note the single and
        sub_filter              '"/vfs' '"/ide/vfs';
        sub_filter              '"/_ping' '"/ide/_ping';
        sub_filter_once         off;
    }
}
```

書き換え終わったら`sudo systemctl reload nginx`して有効化しておきます。

# ３．dockerを立ち上げて動作確認

kdelfour/cloud9-dockerが☆が多かったので使ってみました。使ってみた時点では最終ビルドが４ヶ月前なのでそこまで古くなかったです。代替で使おうとしていたcodeboxが３年前とかなので(´・ω・｀)

```bash
sudo docker run -it -d -p 8080:80 -v /home/my_user/workspace:/workspace kdelfour/cloud9-docker
```

立ち上がったら、ブラウザでアクセスしてみます。

```
http://hostname:3080/ide/ide.html
```

ide.htmlまで必要です。`http://hostname:3080/ide/`で止めると`http://hostname:3080/ide.html`にリダイレクトされてうまく動きません。

次のような画像が表示されたら成功です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140718/a441d299-e002-e2db-7ef6-c265cdef91f2.png)

ユーザー/パスワードは設定できないみたいなので、nginxのconfの設定に特定IPのみ許可とか入れておくと良さそうですね。

```nginx:/etc/nginx/conf.d/ide.conf
  location /ide/ {
    # 追加
    allow xxx.xxxx.xxx.xxx;
    deny all;
  }
```

# 認証をつける
コンテナ内の`/etc/supervisor/conf.d/cloud9.conf`の中に起動コマンドがあるので、コマンドの最後に

```
--auth ユーザー名:パスワード
```

をつけてやれば認証が入ります。

認証が必要な場合はイメージをそのまま使うのでなく、Dockerfileでsedあたりで起動コマンドを書き換えて使うと良さそうです。
コンポーネントのPropsにデフォルト値を持たせる

# デフォルト値について
Reactのコンポーネントを呼び出す時、そのコンポーネントのプロパティとしてPropsを渡すことができます。

```jsx:呼び出し例
// labelとcheckedがprops
<TodoLabel label="メールを返信する" checked={false} />
```

この時、コンポーネント側にdefaultPropsというプロパティを定義しておくと、このPropsにデフォルト値をもたせることができます。
デフォルト値を持たせることによって、コンポーネントの呼び出しを柔軟にできたり、Propsが渡されなかった時の実装を楽にすることができます。

# defaultPropsとは
下記画像のTodoラベルのコンポーネントを例に解説します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116289/761da4ed-7c39-e594-96c0-eeefb3ef1870.png)

```jsx:TodoLabel.jsx
import * as React from 'react';

class TodoLabel extends React.Component {
  render() {
    return (
      <div><input type="checkbox" defaultChecked={this.props.checked} />{this.props.label}</div>
    );
  }
}

// Propsのデフォルト値
TodoLabel.defaultProps = {
  checked: false, // デフォルトはチェックボックスにチェックを入れない
};

export default TodoLabel;
```

defaultPropsに設定したいプロパティと値を書くことでデフォルト値を定義できます。

この状態で次のように呼び出すと、次の画像の通りになります。

```jsx:呼び出し例
<TodoLabel label="メールを返信する" />
<TodoLabel label="書類を作る" checked={true} />
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116289/e470d715-ec99-9094-8acc-89cc58421e3d.png)

# Functional Componentの場合
Functional Componentの場合も同様に記述できます。

```jsx
import * as React from 'react';

const TodoLabel = ({ label, checked }) => {
  return (
    <div><input type="checkbox" defaultChecked={checked} />{label}</div>
  )
}

// Propsのデフォルト値
TodoLabel.defaultProps = {
  checked: false,
};

export default TodoLabel;
```

# Staticプロパティにした書き方
transform-class-propertiesなどのBabel transformを使用している場合はStaticプロパティにした書き方も可能です。
（create-react-appから作った場合、transform-class-propertiesは最初から入っています）

```jsx
import * as React from 'react';

class TodoLabel extends React.Component {
  // Propsのデフォルト値
  static defaultProps = {
    checked: false,
  };

  render() {
    return (
      <div><input type="checkbox" defaultChecked={this.props.checked} />{this.props.label}</div>
    );
  }
}

export default TodoLabel;
```
Vagrant&Virtual Box開発環境下でメモリと容量を増やす

## 概要
VagrantとVirtual Boxを利用して、ローカル開発環境を作っていたのですが、途中で容量とメモリが足りなくなったので、Vagrantfileの設定を変更することで問題を解決しました。

## 動作環境
Vagrant Version: 2.1.1
Virtual box version 5.2.12
Box image [ubuntu/xenial64 v20180615.0.0](https://app.vagrantup.com/ubuntu/boxes/xenial32/versions/20180615.0.0)

## Vagrantfileの変更
デフォルトでは仮想環境の容量は10GBで設定されているので、これを50GBまで増やします。
また、メモリも1024MBに変更します。

```shell-session:Vagrantfile
Vagrant.configure("2") do |config|

  config.vm.box = "ubuntu/xenial64"
  config.disksize.size = '50GB'           #容量を増やす時に追加する
  config.vm.box_url = " --box-version"

  config.vm.provider "virtualbox" do |vb| #メモリを増やす時にコメントアウトする
     vb.memory = "1024"                   #メモリを増やす時にコメントアウトする
  end                                     #メモリを増やす時にコメントアウトする
end
```
変更が完了したら、vagrantを起動して以下のコマンドで、容量とメモリが増えているかどうかを確認します。
## 容量の確認
```shell-session:~/
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            490M     0  490M   0% /dev
tmpfs           100M  3.1M   97M   4% /run
/dev/sda1        49G  8.3G   41G  18% /
tmpfs           497M     0  497M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           497M     0  497M   0% /sys/fs/cgroup
vagrant         466G  110G  357G  24% /vagrant
tmpfs           100M     0  100M   0% /run/user/1000
```


## メモリの確認
```shell-session:~/
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            992          44         898           3          49         844
Swap:             0           0           0
```
以上で、きちんと容量とメモリを増設することができました。
オープンツール (Open Tooling) を使用して Ext JS アプリケーションを生成する

![ext-js-6-6-application-generated-by-open-tooling.png](https://qiita-image-store.s3.amazonaws.com/0/67627/ee9ec709-42ea-41e1-ef0e-19eff18fd894.png)

オープンツール (Open Tooling) で Ext JS アプリケーションを生成して実行する手順をメモっとく。Ext JS 6.6 がリリースされ、これまでの Sencha Cmd だけでなく npm をベースとしたオープンツールによってアプリケーションを生成したりビルドしたりできるようになったのだ。

# 前提条件

Java 8 と Node が必要なのでインストールしておこう。Java は 8 とバージョン指定がある。Node は最新で大丈夫なので、下記のように Homebrew でインストールしておく。

```shell-session
$ brew install node
```

# Sencha のレジストリにログインする

Ext JS 本体や ExtGen などのオープンツールは Sencha のレジストリから提供されるので、Sencha のレジストリにログインしておく必要がある。

商用ライセンスを持っていれば、サポートポータルにログインするときのアカウントでログインできる。ただし、Username に入力するメールアドレスの `@` は `..` に置換して入力する必要がある。

商用ライセンスを持っていなければ、[Try Sencha Ext JS 6.6 with Open Tooling](https://www.sencha.com/products/extjs/evaluate/opentooling/) から試用を申し込んで利用する。

```shell-session
$ npm login --registry=http://npm.sencha.com --scope=@sencha
Username: takuya.tsuchida..example.com
Password: 
Email: (this IS public) takuya.tsuchida@example.com
Logged in as takuya.tsuchida..example.com to scope @sencha on http://npm.sencha.com/.
```

# ExtGen をインストールする

Ext JS アプリケーションを生成する ExtGen パッケージを npm でインストールする。

```shell-session
$ npm install -g @sencha/ext-gen
```

# Ext JS アプリケーションを生成する

Ext JS 6.6 のアプリケーションを ExtGen を使用して生成する。今回はデフォルト設定でアプリケーションを生成する。様々な設定が可能なようなので、詳細な使い方は `ext-gen --help` を実行して確認してほしい。

```shell-session
$ ext-gen app -a
```

# Ext JS アプリケーションを実行する

my-app ディレクトリに MyApp プロジェクトが生成されるので、そのアプリケーションを実行してみよう。下記のコマンドを実行すると自動的にデフォルトブラウザーが立ち上がってサンプルアプリケーションが表示されるはずだ。

```shell-session
$ cd my-app
$ npm start
```

---

今回は Ext JS 6.6 で追加されたオープンツールを使用して Ext JS アプリケーションを生成して実行する手順について説明した。Sencha Cmd からオープンツールへの移行は様子を見ながらになると思うが、JavaScript 界隈でデファクトスタンダードになっているツールなのでいずれは全面移行する気がする。個人的には Sencha Architect で生成されるプロジェクトのビルドツールがオープンツールになったら移行しようかなと思っている。

# 参考文献

https://www.sencha.com/blog/announcing-sencha-ext-js-6-6-with-open-tooling-ga-ja/
http://docs.sencha.com/extjs/6.6.0/guides/getting_started/open_tooling.html
Debug.Log()って打つの面倒くさい

とにかく少しでも楽に書けるようにする方法を考えてみました
（スニペット使えとか言わないでください）

環境： Unity 2017 .NET 3.5

##普通にメソッドを作る
```定義.cs
public class d
{
	public static void l(object message)
	{
		Debug.Log(message);
	}
}
```
```使う側.cs
d.l("あああ");
d.l(123.4f);
d.l("位置は " + transform.position);
```

普通ですね

##拡張メソッドを作る

```定義.cs
public static class Aaa
{
	public static void l(this object self)
	{
		Debug.Log(self);
	}
}
```

```使う側.cs
"あああ".l();
123.4f.l();
("位置は " + transform.position).l();
```

連結しない限りは普通のメソッドよりこっちのほうが楽そうです

##コンストラクタでやる

```定義.cs
public class w
{
	public w(object message)
	{
		Debug.Log(message);
	}
}
```

```使う側.cs
new w("あああ");
new w(123.4f);
new w("位置は " + transform.position);
```
ドットを打たなくていいという利点があります


##インデクサーを使う

```定義.cs
public class s
{
	public static s o = new s();

	private string str;

	public s this[object obj]
	{
		get
		{
			str += " " + obj.ToString();
			return this;
		}

		set {}
	}

	public static s operator --(s self)
	{
		Debug.Log(self.str);
		self.str = "";
		return self;
	}
}
```

```使う側.cs
var o = s.o; //変数に入れないときつい

--o["あああ"];
o[123.4f]--;
--o["位置は " + transform.position];
--o["位置は"][transform.position];
```

うーん

## 演算子オーバーロードを使う

``` 定義.cs
public class c
{
	public static c o = new c("");

	private string str;

	public c(string str)
	{
		this.str = str;
	}

	public static implicit operator c(string str)
	{
		return new c(str);
	}

	public static implicit operator c(UnityEngine.Object obj)
	{
		return new c(obj.ToString());
	}

	public static implicit operator c(ValueType val)
	{
		return new c(val.ToString());
	}

	public static c operator -(c left, c right)
	{
		Debug.Log(right.str);
		return null;
	}
}
```

```使う側.cs
var o = c.o;

o-="あああ";
o-=123.4f;
o-="位置は " + transform.position;
```

かわいい

#感想
```cs

Action<object> l = obj => Debug.Log(obj);
```
PlayableDirectorの再生が終わると状態がリセットされる場合


![playable.gif](https://qiita-image-store.s3.amazonaws.com/0/113504/1be19154-7b83-de15-9136-6d61e83e78ca.gif "playable.gif")

WrapModeをHoldにすれば解決できますが，それだとPlayableDirectorの
stoppedイベントが呼ばれないのでHoldは使いません．

# 原因
![スクリーンショット 2018-06-24 19.28.55.png](https://qiita-image-store.s3.amazonaws.com/0/113504/bc700294-2a46-e293-03bd-51d2b8387af3.png "スクリーンショット 2018-06-24 19.28.55.png")

AnimatorのControllerが原因でした．
このAnimatorのControllerをNoneにすることでリセットされなくなりました．

TimelineからAnimatorのControllerのstateをいじる方が正解な気はします．
pyenvでPythonの最新安定版をインストールするワンライナー

## はじめに

本記事は，[rbenvでRubyの最新安定版をインストールするワンライナー](https://mawatari.jp/archives/install-latest-stable-version-of-ruby-using-rbenv) のPython版です。

[pyenvで最新の安定版Pythonをインストールする（2系3系とも）](https://qiita.com/ry0f/items/a38947ab70845326e552)ではrc版がインストールされてしまう。

## 確認用

#### Python 2.x (確認用)

```sh
$ pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s2\.?*' | tail -1
```

#### Python 3.x (確認用)

```sh
$ pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s3\.?*' | tail -1
```

## インストール

#### Python 2.x

```sh
pyenv install $(pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s2\.?*' | tail -1)
```

#### Python 3.x

```sh
pyenv install $(pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s3\.?*' | tail -1)
```

## pyenvのインストールから設定まで (macOS)

```sh
brew install pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
python2=$(pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s2\.?*' | tail -1)
python3=$(pyenv install -l | grep -v '[a-zA-Z]' | grep -e '\s3\.?*' | tail -1)
pyenv install $python2
pyenv install $python3
pyenv global $python2 $python3
pyenv rehash
```

## References

[rbenvでRubyの最新安定版をインストールするワンライナー](https://mawatari.jp/archives/install-latest-stable-version-of-ruby-using-rbenv)
[tail - ファイルの末尾部分を表示する](https://www.ibm.com/support/knowledgecenter/ja/ssw_i5_54/rzahz/tail.htm)
[grepでこういう時はどうする?](https://qiita.com/hirohiro77/items/771ffb64dddceabf69a3)
[grepコマンドの詳細まとめました【Linuxコマンド集】](https://eng-entrance.com/linux-command-grep)
[変数を使用する – UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/variable.html)
[MacでPython使う時の最低限のメモ（pyenv編）](https://qiita.com/zaburo/items/dd1a8323633035614efc)
[【へぇ】IT業界でよく見る、rc版、とかga版とはなんぞや](https://chat-rate.com/it/2200/)
FlutterでWidgetをWrapするためのショートカットが超便利

Flutterでアプリのコードを書いていて、
**既存の`Column`を`Expanded`でWrapしたい！**
みたいなとき、何にも知らない私は
**`Column`の箇所を選択してカットして、代わりに`Expanded`を書いてその`child:` に先ほどの`Column`をペーストして。。**
というやり方をしていました。

これメンドクサイのでなんとかならないとのかな〜と思っていたら、**IDEのショートカットで簡単に出来る**ことが分かりました。

その方法は、[Codelabsのこちらの回](https://codelabs.developers.google.com/codelabs/flutter/#7)のなかで紹介れています。

![9ccd4f42017afaa7.png](https://qiita-image-store.s3.amazonaws.com/0/214755/fd64925f-1526-9673-4240-f5132c8d5957.png)

WrapさせたいWidgetをクリックすると、その行の左にバルブが表示されるので、それをクリックします。
そうすると、`Wrap with new widget`という項目が出てくるので、それを選択すると`widget`でwrapしてくれます。あとはそれを目的のWidgetに置き換えるだけです。

キーボードのショートカットの場合、**`option+return (macOS)`** **`alt+enter (Linux, Windows)`** です。

上では IntelliJ IDEAの例ですが、AndroidStudioでも同様にできました。
キーボードのショートカットも同じです(Linux, Windowsは未確認)。

![WidgetWrapShortCutViaAndroidStudio.jpg](https://qiita-image-store.s3.amazonaws.com/0/214755/2d8ab9c6-cecf-1d56-da7e-1eaddb70b102.jpeg)