OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelでCarbonではなくChronosを使ってみる

# Carbonではなく、Chronosを使う個人的な理由
・イミュータブルなChronosがいい(建前)
・CakePHP3.5でChronosに慣れてしまったから

## インストール

インストールはcomposerでできる
https://book.cakephp.org/3.0/ja/chronos.html

```shell
# chronosの安定板をインストールする
composer require cakephp/chronos "@stable"
```

## Chronos使用方法

useすれば普通に使える

```php
use Cake\Chronos\Chronos;

$now = Chronos::now();
```

## なんか普通にCake\I18n\Timeも使えそうじゃない？

https://book.cakephp.org/3.0/ja/core-libraries/time.html
>内部的には、この Time ユーティリティを動かすために、CakePHP は Chronos を利用しています。 Chronos と DateTime でできることはなんでも、 Time と Date ですることができます。

`Cake\I18n\Time`を使えるならそっちの方がいいし、試してみる

```shell
composer install cakephp/i18n
```

怒られたけど、composer.jsonのrequireに追加しろって言われてる

```
Invalid argument cakephp/i18n. Use "composer require cakephp/i18n" instead to add packages to your composer.json.
```

追加してみる

```json:composer.json抜粋
    "require": {
        "php": "^7.1.3",
        "cakephp/i18n": "@stable",

```

composer installしてみる
どうやら入ったぽい

```shell
$composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Package operations: 4 installs, 0 updates, 0 removals
  - Installing cakephp/core (3.6.4): Loading from cache
  - Installing cakephp/utility (3.6.4): Loading from cache
  - Installing cakephp/chronos (1.1.4): Loading from cache
  - Installing cakephp/i18n (3.6.4): Loading from cache
```

下記で普通に使えました。

```php
use Cake\I18n\Time;

$now = Time::now();
```

ImmutableなFrozenTimeも使える

```shell
$php artisan tinker
Psy Shell v0.9.4 (PHP 7.2.4 — cli) by Justin Hileman
>>> use Cake\I18n\FrozenTime;
>>> $time = FrozenTime::now();
=> Cake\I18n\FrozenTime @1528811961 {#2340
     date: 2018-06-12 13:59:21.186572 UTC (+00:00),
   }
>>> $pastTime = $time->modify('-2 days');
=> Cake\I18n\FrozenTime @1528639161 {#2342
     date: 2018-06-10 13:59:21.186572 UTC (+00:00),
   }
>>> $time
=> Cake\I18n\FrozenTime @1528811961 {#2340
     date: 2018-06-12 13:59:21.186572 UTC (+00:00),
   }
>>> 
```

## find後のオブジェクトをCarbonからTimeオブジェクトに変換する

useしたら使えるのはいいけど、findしたあとにcreated_atとかupdated_atがCarbonオブジェクトのままなんですが？
と後から気がついた。
変換する場合はModelにミューテターを追加する

```php:model.php
/**
* CarbonをTimeオブジェクトに変換
* @param Illuminate\Support\Carbon
* @return Cake\I18n\Time
*/
public function getCreatedAtAttribute($createdAt)
{
    return Time::parse($createdAt);
}

/**
* CarbonをTimeオブジェクトに変換
* @param Illuminate\Support\Carbon
* @return Cake\I18n\Time
*/
public function getUpdatedAtAttribute($updatedAt)
{
    return Time::parse($updatedAt);
}
```

いちいちModelを追加する度に上記を追加するのくそ面倒なので、
MyModelとかカスタマイズ用のModelクラスを作成して、それを継承するようにすると楽。

## 参考
[Carbon と Chronos から見る OSS 運営](https://www.slideshare.net/serima1/carbon-chronos-oss)
[WIP] (Google I/O 2018)Modern Android development: Android Jetpack, Kotlin, and moreの備忘録

# はじめに
[Modern Android development: Android Jetpack, Kotlin, and more](https://events.google.com/io/schedule?section=may-8&sid=c0a88a3f-f2f9-4b3f-97bd-969bc0883d2f)
の簡単な備忘録です。
（※一部動画のキャプチャを引用しております。）
※もし間違いがありましたら、すみませんがご指摘ください。
※編集途中です、きれいにまとめ次第WIPを外します

# 概要

The last couple of years have seen a plethora of new features and patterns for Android developers. But how do developers know when to use existing APIs and features vs. new ones? This session will help developers understand how they all work together and learn what they should use to build solid, modern Android applications.

[google翻訳]
ここ数年、Android開発者のための新しい機能やパターンが数多く登場しました。しかし、開発者は既存のAPIや機能をいつ新しいものと使うべきかを、どのように知っていますか？このセッションでは、デベロッパーがどのように連携して動作するかを理解し、堅実で現代的なAndroidアプリケーションを構築するために使用する必要があるものについて学びます。

#内容
AndroidツールキットチームのHaaseさんとフレームワークチームのGuyさんが登場し、太陽がまぶしいとモダンなAndroidへようこそとあいさつしてくれます。
Androidは誕生から10年、また時代遅れな情報がおおいとのこと。
続けて、Androidの歴史に関して語りました。2008に登場し、2013にandroid studioが登場しました。RecyclerViewやConstraintLayoutなどが続けて登場してきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250967/52c61b27-ac5b-abfb-c818-c93ec5e6271c.png)

##Layout Inspector
続けて、Viewの構造を可視化できるHierarchy Viewerについて言及しました。現在では
Layout Inspectorのほうがいいらしいです。一度に複数の検査ができます。埋め込みやマージンなど

##systrce
コードをプロファイリングするツールに昔はTrace View使われましたが、今はAndroid Studioのプロファイラを使うのがいいとのことです。

##Layout Design
XMLをごりごりかかなくても、視覚的なツールでレイアウトをつくることができそう。

##ランタイム
Dalvikが昔使われたらしい
後継にARTが使われる
（ちょっとここらへん勉強して、余裕あったら別記事に書きます）
電池とメモリ使用量を意識してコーディングしましょう！

##言語
一般的な言語だからjavaが採用されていた（今でもだけど）
去年からkotlinが採用された！！

##API

###レイアウト
![image.png](https://qiita-image-store.s3.amazonaws.com/0/250967/2e2450b3-4f47-15ee-8f3f-b7ba72ef63d7.png)
こんな感じ
（ConstraintLayout の2.0に期待）

###AdapterView
ListViewよりRecyclerViewのほうがリッチ！

###Fragments
プラットフォーム版を使わない
サポートライブラリもしくはJetpackのを使用すべき

###Activities
可能なかぎり単一のActivityを使いましょう

###アーキテクチャ
2年前は別にどれでもよかった。
今ではViewModel、LiveDataが推奨される
(Android Architecture Components)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/250967/f3f6322a-04d5-3c2b-ad92-0abeb352bb2b.png)

###グラフィクス
IBOutletをスーパークラスに持たせる方法

# 状況
`ViewController_A.swift`と`ViewController_B.swift`が、*同じUIViewを異なるStoryboardから接続している*。
そこで、**スーパークラスを作ってそれを継承させてスマートにしたい**！

# こうする
普通に`@IBOutlet`を書いてOKだった。

```swift
class BaseVC: UIViewController {
    @IBOutlet weak var boardView: UIView!
}

class ViewController_A: BaseVC {
    // boardViewを扱える
}

class ViewController_B: BaseVC{
    // boardViewを扱える
}
```

異なるStoryboardと繋いでるから、継承元で接続しようがないのでは...?と思っていたが違うようです。

# どうなってるの？
左側の接続情報(○のとこ)をクリックすればわかる。
Xcodeが接続情報を自動で管理してくれる。

![スクリーンショット 2018-05-22 22.54.43.png](https://qiita-image-store.s3.amazonaws.com/0/159680/731e8d4d-9b32-2423-6d16-f2626e4e5209.png)

こんな感じの表示が出るはず。

出てないときは、**手動でStoryboardから複数個のUIを一つのプロパティやアクションに繋ぎましょう**。
JDBCでプリペアドステートメントを使った際に実行結果を見てみる

JavaのJDBCを使う際にプリペアードステートメントを用いてSQL文を実行

```java
String sql = "sql文";
stmt = conn.prepareStatement(sql);
stmt.setQueryTimeout(10);
stmt.setString(1, table);
stmt.setString(2, username);
int count = stmt.executeUpdate();//これで実行
stmt.close();
return (count > 0); // affected row(影響された列が1以上だったら、成功したよね？と解釈。)
```

affected　rowの個数から判断するとは思いつきませんでしたね。


#参考文献
https://stackoverflow.com/questions/24378270/how-do-you-determine-if-an-insert-or-update-was-successful-using-java-and-mysql
https://code.i-harness.com/ja/q/d4d07c
golang Error {write tcp 127.0.0.1:12345->127.0.0.1:12346: use of closed network connection}


Websocksを使ってる時に出るエラー並列処理で通信中のWebsocksにまた命令を書いてるからダメってこと
例はRedis



```main.go
var single chan bool

func main(){
	single = make(chan bool,1)
}
func redisGet(key string) (reply interface{}, err error) {
	single <- false
	reply,err = Conn.Do("GET", key)
	<-single
	return reply,err
}
```

こうしてからredisGetを並列処理で呼び出しても、通信が完了するまで.Doを実行しないためこのエラーを回避できる





参考
https://ja.stackoverflow.com/questions/20719/go%E3%81%AEwebsocket%E3%81%A7%E8%B5%B7%E3%81%8D%E3%81%9Fuse-of-closed-network-connection%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
EnumerateFiles(?, ?, AllDirectories) メソッドで、アクセス権エラーを回避する

#はじめに
[System.IO.Directory.EnumerateFiles](https://msdn.microsoft.com/ja-jp/library/system.io.directory.enumeratefiles.aspx) メソッドは、引数に[SearchOption.AllDirectories](https://msdn.microsoft.com/ja-jp/library/ms143448.aspx) を指定すると、指定したディレクトリの内部にあるファイルをサブディレクトリを含めて検索して返してくれて便利です。
しかし、ディレクトリ内部に[フォルダ一覧化](https://www.teppi.com/column/file_mgmt/008_filing_win_acl03/)のアクセス権がないディレクトリがあると、[System.UnauthorizedAccessExceptionSystem.](https://msdn.microsoft.com/ja-jp/library/system.unauthorizedaccessexception.aspx)例外が発生してしまいます。

#解決例
自前でEnumerateFilesメソッドを作成してみました。
自分で階層を探ります。[IEnumerable](https://msdn.microsoft.com/ja-jp/library/9eekhta0.aspx)\<[string](https://msdn.microsoft.com/ja-jp/library/system.string.aspx)> 型で返し、[GetFiles](https://msdn.microsoft.com/ja-jp/library/system.io.directory.getfiles.aspx)メソッドのように全部走査し終わるまで待たされることもありません。

##コード
```C#
using System;
using System.Collections.Generic;
using System.Linq;

namespace SampleProject
{
    public class Directory
    {
        public static IEnumerable<string> SafeEnumerateFilesInAllDirectories(string path)
        {
            return SafeEnumerateFilesInAllDirectories(path, "*");
        }

        public static IEnumerable<string> SafeEnumerateFilesInAllDirectories(string path, string searchPattern)
        {
            var files = Enumerable.Empty<string>();
            try
            {
                files = System.IO.Directory.EnumerateFiles(path, searchPattern);
            }
            catch(System.UnauthorizedAccessException)
            {
            }
            try
            {
                files = System.IO.Directory.EnumerateDirectories(path)
                    .Aggregate<string, IEnumerable<string>>(
                        files,
                        (a, v) => a.Union(SafeEnumerateFilesInAllDirectories(v, searchPattern))
                    );
            }
            catch (System.UnauthorizedAccessException)
            {
            }

            return files;
        }
    }
}

```

#参考にしたサイト 感謝！
- [Windowsアクセス許可のいろいろ](https://www.teppi.com/column/file_mgmt/008_filing_win_acl03/) - [Teppi technologies](https://www.teppi.com/)さん
MacbookPro2016を修理した（２回目）

１回目は[こちら](https://qiita.com/SYABU555/items/07b80e705c0f41973f5c)

# スペック

* Macbook Pro 2016
* 15inch
* 2.7 GHz Intel Core i7 (Quad core)
* 16GB Memory
* 512GB SSD
* Intel HD Graphics 530 1536 MB
* USキーボード

# 修理

## 症状

今回の症状は２つ、いずれも前回の修理直後から現れた症状です

- スピーカーが音割れする（特に低音）
- ログイン時に指紋認証が受付されない（タッチバーに指紋認証の文字がでない）

スピーカーに関しては他に事例もネットに転がっておらず、ほとほと困っていました。
一度オーディオドライバ的なものをリセットしてみたんですが、直りませんでした。

## 前回の修理と違うこと

- 日本で修理した（前回はカナダのバンクーバー）
- ビックカメラに設置されているApple公式修理サポートに預けた（八王子）

## 修理期間

土曜に出して翌週土曜に修理完了の連絡、１週間ちょうどでした。

## 結果

### CASE1: スピーカーが音割れする

**スピーカー周りの小さいネジの締めが甘く、外れてスピーカーの磁力に捕まってひっついていたことが原因** だそう
レアケースのため、Appleへ保証対象かの確認をとっていたために修理期間が長引いたそうです

スピーカーユニットごと交換となりました。

### CASE2: 指紋認証ログインにならない

これは超恥ずかしい事実が判明しました
なんと **前回修理後に指紋登録情報がリセットされていた** らしく、
それに気づかず毎度ログイン時に指紋認証のナビゲーションがないことに「？」となっていたようです

**みなさんも修理から帰ってきた時には気をつけましょう！！**
ちなみに前回はキーボード故障でした。

## 所感

### １週間もかかった

知人はキーボードの修理で３日ほどで帰ってきたと言っていたのと
修理受付の人も３日くらいと言っていたので安心していたのですが１週間丸々かかりました

日本でUSキーボードの修理だからかなぁと思っていたのですが、
レアケースのために１週間かかったようです。

USキーボードだからといって期間が伸びるわけではないそうです。

### めっちゃ親切

前回のカナダで修理時には対応に腹がたつことばかりだったんですが、
今回は全く問題なく、むしろ好印象しかなかったです。

さすが日本人と日本人、わかってらっしゃる。

何がわるくて、どう対応したかを事細かに説明いただけたので
こちらとしても安心して受け取ることができました。

感謝です！！

### AppleCare

今回はネジのゆるみという先方の明確な対応不備であったにしろ、
年に２回も修理に出すことになっちゃいました。

購入から１年は無料で対応してくれますが、今回の修理費が本来7万円（前回もそれくらい）かかると思うと
長く使うつもりのマシンであればAppleCareは入っておいたほうが良さそうですね

ちなみに **そこらの非公式格安修理に一度修理にだすと、公式サポート対象外になります** のでご注意を。

## 結論

カナダのApple修理サービスには気をつけろ...！！！
VirtualBoxのcentosにTomcatをインストールしてサンプルアプリを動かしてみた

Virtual Boxのcentos7にtomcatを導入したので手順をまとめた。

環境
- VirtualBox 4.2.12
- CentOS 7.4.1708
- tomcat 7.0.76

## 1.Tomcatインストール

1. Tomcatがインストールされているか確認

    ```bash
yum list installed | grep tomcat
```
結果が何も返ってこなければ、インストールされていない
　
2. Tomcat&サンプルページのインストール

    ```bash
yum -y install tomcat
```
「完了しました!」と表示されればOK

    ```bash
yum -y install tomcat-webapps
```  
サンプルページ用のファイルを追加
「完了しました!」と表示されればOK
　
3. 動作確認

    ```bash
systemctl start tomcat
```
Tomcatを起動

    ```bash
systemctl status tomcat
```
「Active: active (running)」なら起動している

    ```bash
http://ゲストOSのIPアドレス:8080/
```
ホストOSのブラウザからアクセスし、猫の画面が表示されればOK

## 2.サンプルページ確認

1. サンプルページを確認

    ```bash
http://ゲストOSのIPアドレス:8080/sample/
```
「Sample "Hello, World" Application」のページが表示される
該当のプログラムは以下にある

    ```bash
/usr/share/tomcat/webapps/sample
```
JSPは「hello.jsp」、
Servletは「WEB-INF/classes/mypackage/Hello.class」にクラスファイルがある

## 3.その他：yumのエラー

Tomcatのインストールで以下のエラーが発生した
[Errno 14] curl#6 - "Could not resolve host:

具体的なメッセージは以下に詳しく記載されている
https://qiita.com/ponsuke0531/items/e036dfa4dd1e69086e13
解決策の参考に調査
http://toriaezu-engineer.hatenablog.com/entry/2017/01/08/095517

最終的にはネットワークを再起動すれば直った。
UE4で作成したOculus GoアプリをOculus Storeにデプロイする時の設定のメモ

# はじめに
USB接続等によるOculusGo実機へのデプロイの際は問題にならないようですが、Oculus Storeにデプロイする際にAPKに細かな設定が必要なようなのでそのメモをここに記す。

アルファチャンネルなどに対するデプロイにおいても必要です。

## 前提
バージョンは、4.19。

[UE4 Oculus GoでVRアプリの開発を開始するまでの方法](http://unrealengine.hatenablog.com/entry/2018/05/04/232708)
を見て、Android開発環境を構築し、プロジェクト設定をしておく。

上記記事作業での個人的なハマりポイント：
NVPACK内のディレクトリ構成が変更になっていてパッケージング時にSDKが見つけられないようなので、古いCodeWorksを既に導入している場合はアンインストールしておく、または別のフォルダに該当バージョンCodeWorksをインストールするとよさそう。

ここまでの設定のみではOculus StoreへAPKをアップロードする際にエラーになります。
(アップロードにはCLIツールを使用すると便利です。[Oculus Platform Command Line Utility](https://dashboard.oculus.com/tools/cli/) )

```
* APK install location should be `auto` (android:installLocation in AndroidManifest.xml). See documentation at: https://developer.oculus.com/documentation/publish/latest/concepts/publish-mobile-manifest/
* APKのデバッグモードがオンになっています(AndroidManifest.xmlのandroid:debuggable)。
* Exclude from Recents(AndroidManifest.xmlのandroid:excludeFromRecents))はtrueにしてください。
* APK main activity intent filter set to `android.intent.category.LAUNCHER`, but must be `android.intent.category.INFO`. Your app must only appear in Oculus Home. It must not appear in the phone’s launcher.
```

これらのエラーに対して、次章で加筆修正をします。

# 前提に加筆修正

UE4のGearVR向けドキュメントは若干古い部分があるので、OculusのGo対応のモバイル向けドキュメントを見て加筆修正する。
[Unreal Mobile Development](https://developer.oculus.com/documentation/unreal/latest/concepts/unreal-gsg-mobile/)
[Application Manifests for Release Builds](https://developer.oculus.com/distribute/latest/concepts/publish-mobile-manifest/)

Minimum/Target API versionは、21。
Androidのテクスチャ圧縮は、ASTC(またはETC2)。

## APK install location ～に対する修正

Project Settings
-> Platforms
--> Android
---> APK Packaging
----> Install Location => auto に設定。

## Exclude from Recents ～に対する修正

Project Settings
-> Platforms
--> Android
---> Advanced APK Packaging
----> Extra Tags for UE4.GameActivity \<activity> node => android:excludeFromRecents="true" を記述。

## APKのデバッグモード～ と APK main activity intent filter ～に対する修正

Project Settings
-> Project
--> Packaging
---> Project
----> For Distribution => チェックを入れる

さらに、[How To Sign UE4 Android Package](https://wiki.unrealengine.com/How_To_Sign_UE4_Android_Package)の通りにAPKの署名設定をする。
上記記事内のkeystoreの位置(\<project>/Android/Builds)は古いようなので、\<project>/Build/Androidと読み替える。

# おわりに
これでAPKをOculus Storeにアップロードできるようになるはずです。
ただしあくまでアップロードできるようになるだけで、実機で動作するかは未確認です。もし動作しなかった場合はその修正ポイントなどはまたどなたかが記事にしてくださいよろしくおねがいします。
vue-cliのwebpackテンプレートで環境別に`npm run build`が出来るようにする

# はじめに
表題のことをやりたくて色々と試しながら一旦落ち着く形となったので、備忘録として残しておきます。

ここに書いている設定は、以下のような環境をイメージして書いています。

- ローカル環境(local)　→　自身の作業PCに構築した環境とか
- 開発サーバ(dev)　→　チームメンバーで共有して使用するサーバに構築した環境とか
- 本番サーバ(prod)

# ビルド設定
## 環境別に環境変数ファイルを用意する
```js:config/local.env.js
'use strict'
// local環境用の環境変数

const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"local"',
  API_ENDPOINT: '"http://127.0.0.1:9000/api"'
})
```
```js:config/dev.env.js
'use strict'
// 開発サーバ用の環境変数 ※webpack-dev-server用の環境変数も兼ねている

const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  API_ENDPOINT: '"https://dev.hoge.com/api"'
})
```
```js:config/prod.env.js
'use strict'
// 本番環境用の環境変数

module.exports = {
  NODE_ENV: '"production"',
  API_ENDPOINT: '"https://hoge.com/api"'
}
```

## buildスクリプトの引数に環境を指定できるようにする
```json:package.json（変更前）
{
  ...
  "scripts": {
    ...
    "build": "node build/build.js"
  },
  ...
}
```
```json:package.json（変更後）
{
  ...
  "scripts": {
    ...
    "build": "npm run build_local",
    "build_local": "node build/build.js local",
    "build_dev": "node build/build.js dev",
    "build_prod": "node build/build.js production"
  },
  ...
}
```
↑では`npm run build`でローカル環境のビルドをするようにしているけど、ここはお好みで変えてしまってOK


```js:build/build.js（変更前）
'use strict'
require('./check-versions')()

process.env.NODE_ENV = 'production'
...
```
```js:build/build.js（変更後）
'use strict'
require('./check-versions')()

const envCheck = (env) => {
    return env
      && (env === 'local' || env === 'dev' || env === 'production')
}

process.env.NODE_ENV = envCheck(process.argv[2]) ? process.argv[2] : 'production'
...
```

## build時のwebpackConfig(`webpack.prod.conf`)が使用する環境変数ファイルを制御する
```js:build/webpack.prod.conf（変更前）
...
const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : require('../config/prod.env')
...
```
```js:build/webpack.prod.conf（変更後）
...
const getEnv = {
  'local': () => {
    return require('../config/local.env')
  },
  'dev': () => {
    return require('../config/dev.env')
  },
  'production': () => {
    return require('../config/prod.env')
  }
}

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : getEnv[process.env.NODE_ENV]()

console.log(env)
...
```

# ビルド
## ローカル環境
```shell
$ npm run build
$ npm run build_local
```
## 開発サーバ
```shell
$ npm run build_dev
```
## 本番サーバ
```shell
$ npm run build_prod
```

## 参考
[vue-cli の webpack テンプレートでテスト環境向けにビルドしたい - kntmr-blog](http://kntmr.hatenablog.com/entry/2018/02/06/132815)
Pythonでのリスト内包表記について

#リスト内包表記とは
Pythonに手を染めてから、理解しがたく、しかし魅力的なのはリスト内包表記(list comprehension)です。”comprehension”とは英語で理解と丸暗記しましたが、包含、内包力というような「包み込む」といった意味があるようです。
通常、num_listの各要素の値に対し1を加えたnum_plusを作る場合には次のようにfor-loopを使います。

```python:program1
"""
forループを使い、リストの各要素に1を加えた数値のリストを作成
"""

num_list = [0,1,2,3,4]
num_plus = []
for num in num_list:
    num_plus.append(num + 1)
num_plus
```
これに対し、リスト内包表記では次のようになります。

```python:program2

"""
リスト内包表記を使って、リストの各要素に1を加えた数値のリストを作成
"""

num_list = [0,1,2,3,4]
num_plus = [num + 1 for num in num_list]
num_plus
```

#リスト内容表記はリスト以外もできる

いずれも結果は[1, 2, 3, 4, 5]となります。前のfor-loopの2～4行目が1行に収まってしまいました。3行目のfor-loopが行の後半に、4行目のappendする値が行の前半に、そして2行目のリストの初期化は、式を”[　]”で囲うことで表記できます。ちょっと戸惑いますが、並べてみると簡単です。ちなみに、リスト内包表記はリストだけではなくタプル(tuple)や集合(set)などイテラブル(iterable)なものであればインプットで使うことができます。Iterableは繰り返し(iterate)ができるという意味です。タプルの場合は次のようになります。

```python:program3
"""
内包表記を使って、タプルの各要素に1を加えた数値のリストを作成
"""

num_tuple = (0,1,2,3,4)
num_plus = [num + 1 for num in num_list]
num_plus
```


集合(set)でも同様です。

```python:program4
"""
内包表記を使って、集合の各要素に1を加えた数値のリストを作成
"""

num_set = {0,1,2,3,4}
num_plus = [num + 1 for num in num_list]
num_plus
```

いずれも結果は[1, 2, 3, 4, 5]となります。

一方アウトプットにはアウトプットのnum_plusはタプルは使えません。タプルとは複数の構成要素からなる組をいいますがイミュータブル(immutable) は作成後にその状態を変えることのできないことをいいます。ちなみにimmuteとは変化するという意味です。


```python:program5
"""
リスト内包表記を使って、リストの各要素に1を加えた数値のタプルを作成しようとしたら
ジェネレータオブジェクトが生成された例
"""
num_list = [0,1,2,3,4]
num_plus = (num + 1 for num in num_list)
num_plus
```

上記のプログラムを実行すると、ジェネレータ式というものが生成され、つぎにような結果になります。ジェネレータについは現時点で、私の理解を超えているのでまた勉強したいと思います。

```
 <generator object <genexpr> at 0x000001A1C38B7620>
```

これは、次のプログラムを実行すると8行目のタプルとして定義したnum_plusにappendメソッドを使うことができないためであると思われます。

```python:program6
"""
forループを使って、タプルにappendメソッドを使おうとしてエラーとなる例
"""

num_list = [0,1,2,3,4]
num_plus = ()
for num in num_list:
    num_plus.append(num + 1)
num_plus
```

この結果は次にようなエラーになります。

```
AttributeError                            Traceback (most recent call last)
<ipython-input-6-cdaba0cccdcf> in <module>()
      6 num_plus = ()
      7 for num in num_list:
----> 8     num_plus.append(num + 1)
      9 num_plus

AttributeError: 'tuple' object has no attribute 'append'
```

一方setはイミュータブルなので、次のようなことも可能です。

```python:program7
"""
内包表記を使って、集合の各要素に1を加えた数値の集合を作成
"""

num_list = [0,1,2,3,4]
num_plus = {num + 1 for num in num_list}
num_plus
```

結果は{1, 2, 3, 4, 5}となります。
conda, pip コマンドメモ

たまにコマンドを忘れてしまうので、備忘録的にコマンドのメモを書きます。

__Memo:__
conda と pip を共存させるケースでは, インストールされるパッケージが競合してしまうなどの不都合が起きることがあるので, 極力 conda で管理して, どうしても pip を使わないといけないパッケージのみを pip でインストールするようにするのがおすすめです。

## conda
### ■仮想環境
#### 1. 新規作成
コマンド:

```
conda create -n [仮想環境名] python=[バージョン] [パッケージ名]
```

具体例:

- python3.5 という名前で python 3.5 を指定して, anaconda のパッケージをすべて入れる.

```
conda create -n python3.5 python=3.5 anaconda
```

- myenv という名前で python 3 を指定して pandas matplotlib を入れる. この場合, 最新の Python3 が追加される.

```
conda create -n myenv python=3 pandas matplotlib
```  

#### 2. 仮想環境の activate
- Mac, Linux

```
source activate [仮想環境名]
```  

- Windows

```
activate [仮想環境名]
```  
#### 3. 仮想環境の一覧表示
- 現在の環境にアスタリスクがつく

```
conda info -e
```  
#### 4. 仮想環境のクローン（リネーム必要）
```
conda create -n [新しい仮想環境名] --clone [clone元仮想環境名]
```  

#### 5. 仮想環境の削除
```
conda remove -n [仮想環境名] --all
```  

### ■パッケージ管理
以下のコマンドは現在動作中の環境にのみ適応される

##### 1. インストール済みパッケージの確認
```
conda list
```  

##### 2. パッケージのアップグレード
```
conda upgrade [パッケージ名]
```  

##### 3. パッケージのアップデート
```
conda update [パッケージ名]
```  

##### 4. パッケージのインストール
```
conda install [パッケージ名]
```  

##### 5. パッケージの削除
```
conda uninstall [パッケージ名]
```  

##### 6. パッケージリストをファイル出力
```
conda env export > [export_filename].yaml
```  

##### 7. パッケージリストを読み込んでインストール
```
conda env create -f  [export_filename].yaml
```  


## pip
### ■パッケージ管理

#### 1. インストール済みパッケージの確認
```
pip list
```

#### 2. パッケージのインストール
```
pip install [パッケージ名]
``` 
 
#### 3. パッケージの更新
```
pip install -U [パッケージ名]
```  

#### 4. パッケージの削除
```
pip uninstall [パッケージ名]
```  

#### 5. パッケージリストをファイル出力
```
pip freeze > requirements.txt
```
#### 6. パッケージリストをファイルから読み込んでインストール
```
pip install -r requirements.txt
```
40代おっさんの手習いで始めるPython（2018/05/22編）其の参

昨日のソース、Twitter API の秘密鍵書いたままコミットしちまった。
やべぇ、このままだと俺のアカウントがレイバンのセールスマンロボットになってしまうかも知れない、と感じたおいらは以下のように対策を取った。

#[Twitter Apps](https://apps.twitter.com/)のアプリの削除
![APP削除.PNG](https://qiita-image-store.s3.amazonaws.com/0/258622/7958072b-1570-8e24-ea43-14c3f89ea78e.png)
もう、APIの削除をためらわなく行う！

#そして[Twitter Apps](https://apps.twitter.com/)の新規申請を行う！
![新規申.PNG](https://qiita-image-store.s3.amazonaws.com/0/258622/f21bb8f0-bc6f-8121-2ad9-82342227f80e.png)

#OAuth のキーをgitに登録しないために、工夫する
要するに、アプリを駆動するためのソースに、トークンや秘密鍵をべた書きしてたのが良くないのだ。
だから、まずはOAuthに必要な情報を取得するだけのモジュールを作成する

```python:OAuth_ORG.py
# -*- coding: utf-8 -*-

def OAuth_CK():
    CK = 'XXXXXXXXXX'                             # Consumer Key
    return CK

def OAuth_CS():
    CS = 'XXXXXXXXXX'         # Consumer Secret
    return CS

def OAuth_AT():
    AT = 'XXXXXXXXXX-XXXXXXXXXX' # Access Token
    return AT

def OAuth_AS():
    AS = 'XXXXXXXXXX'         # Accesss Token Secert
    return AS
```

で、このモジュールをgitに登録しないように .gitignore に追加する

```git:.gitignore
# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
Bottle Practice/PyTwitter/OAuth_ORG.py
```

<B>Bottle Practice/PyTwitter/OAuth_ORG.py</B> を追加しておくことで、このファイルをうっかり git に挙げることがなくなるようにしておくのだ。秘密鍵はローカルにだけ。複数の端末で開発したいときは少々面倒だが、ここはセキュリティを重視しておきたい。

で、実際にOAuth 認証をするときは、こうやって対応する

```python:sample.py
import OAuth_ORG
from requests_oauthlib import OAuth1Session

def get_search():
    #ツイッターAPIを取得する
    #OAuth_ORG.py を作成し、それぞれのキーを返すメソッドを用意すること。
    #git には加えてない（秘密鍵が漏れるの怖いので）
    CK = OAuth_ORG.OAuth_CK()
    CS = OAuth_ORG.OAuth_CS()
    AT = OAuth_ORG.OAuth_AT()
    AS = OAuth_ORG.OAuth_AS()
    twitter = OAuth1Session(CK, CS, AT, AS)
```

こうすることで、gitに漏らさずにTwitter のトークンとか取得できるようにした。
これはまぁ、もう一つ利点があって、別のアプリ作る時にもこの OAuth_ORG モジュールを同じフォルダにおいて import すればよいのだから便利。

…あれ？ OAuth1Session を返すメソッドもついでに OAuth_ORG に実装しておくとよいのかな？
まぁ、その辺はおいおい試してみよう。
文字列をHTML数値文字参照とCSS数値文字参照に変換する

##はじめに
CSS用(backgroundのcontent)の数値文字参照を一発で出してくれるツールがすぐ見つけられなかったので作るついでにサロゲートペアに対応した状態にしました。&#x1f4aa;とかも大丈夫です。

下記に変換ツールを公開しています！
[文字列→数値文字参照ツール](https://tamfoi.github.io/c2ncr/)

この記事は変換部分だけ紹介しています。

##実装
###文字列→HTML数値文字参照
```javascript
function stringToHtmlNumCharRef(string){
    let result = "";
    
    for(let val of string){
      result += "&#x" + val.codePointAt(0).toString(16) + ";";
    }

    return result;
}
```
###文字列→CSS数値文字参照
```javascript
function stringToCssNumCharRef(string){
  let result = "";
  
  for(let val of string){
    result += "\\" + val.codePointAt(0).toString(16);
  }

  return result;
}
```
###解説
for...of文とcodePointAtがサロゲートペアに対応してるので、1文字ずつ16進数に変換してそれに必要な文字列をくっつけるだけです。
いろんな状況を考えてローパスフィルタ使って見た

今回は、ローパスフィルタを使って見てどんな挙動になるのか調べて見ました。

まず、簡単にローパスフィルタ(LPF)について説明します。
私も専門家というわけではないので簡単に！

ローパスフィルタと聞いて真っ先に思い浮かぶのはRC回路ではないでしょうか。
例えばエンコーダとか加速度センサとかを使うことを考えます。どのようなセンサも必ずノイズというものが乗ります。どれほどの量が乗るかはそのセンサによってまちまちだと思います。
また、全く同じ型番の製品でも個体差があるため、全く同じ挙動を示すセンサというものは実質ないと言えます。
ノイズとして例をあげると、部屋の蛍光灯とか家電製品から発せられる電磁波もノイズになります。

ローパスフィルタとはこのノイズの中で、高周波成分を取り除いて低周波成分のみを通すようなフィルタと思ってください。名前からも低周波成分(Low)を通す(pass)フィルタ(filter)ということですwww

もっと詳しく知りたい人はインターネットで調べればたくさん資料が出てくると思います。

では本題に戻ります。今回は離散信号のローパスフィルタを考えるのですが、その式は次のように書くことができます。

$$y[t]=\alpha y[t-1] +(1-\alpha)x[t]$$
ここで、$x[t]$は入力信号、$y[t]$は出力信号です。いい変えれば、「センサからゲットした値が$x[t]$で、フィルタをかけた後の値が$y[t]$」ということになります。一般的には$\alpha=0.8~0.9$くらいに設定するそうです。(この辺りは今回は詳しく調べていません)
どのような値を設定するべきかは、システムをモデル化して周波数成分を考えてカットオフ周波数を基準とすればいいと思いますが、今回は割愛です。

では、Pythonでノイズを乗せた元の関数を再現できるか実験して見ます。今回の実験条件としては次のようなものを考えてみたいと思います。

- 入力:$x[t]=t$、ノイズ:$e[t]=t^2{\rm sin^2}(t)$
- 入力:$x[t]=t^2$、ノイズ:$e[t]=t^2{\rm sin^2}(t)$
- 入力:$x[t]=t^3$、ノイズ:$e[t]=t^2{\rm sin^2}(t)$

今回はノイズを一定にして、線形、二次関数、三次関数について$0\leq t \leq 10000$の範囲で計算してみました。実際に使ったコードは次のものになります。なお、ローパスフィルタの係数は一律$\alpha = 0.8$としています。

```python:LowPassFilter.py
import numpy as np
import matplotlib.pyplot as pat

x=np.array([i for i in range(10000)])
#フィルタ適用後のデータ格納用配列
_y1=np.array([i for i in range(10000)])
_y2=np.array([i for i in range(10000)])
_y3=np.array([i for i in range(10000)])
#真値
y1_true=x
y2_true=x**2
y3_true=x**3
#ノイズを乗せた後の値
y1_error=y1_true+x*x*(np.sin(x)**2)
y2_error=y2_true+x*x*(np.sin(x)**2)
y3_error=y3_true+x*x*(np.sin(x)**2)

#low pass
for i in range(10000):
    if i==0:
        _y1[i]=y1_error[0]
        _y2[i]=y2_error[0]
        _y3[i]=y3_error[0]
        continue
    
    _y1[i]=0.2*y1_error[i] + 0.8*_y1[i-1]
    _y2[i]=0.2*y2_error[I] + 0.8*_y2[i-1]
    _y3[i]=0.2*y3_error[i] + 0.8*_y3[i-1]

fig=plt.figure(figsize=(15,5))  
ax1=fig.add_subplot(1,3,1)      
ax2=fig.add_subplot(1,3,2)
ax3=fig.add_subplot(1,3,3)

ax1.plot(x,y1_error,color="g")
ax1.plot(x,_y1,color="b")
ax1.plot(x,y1_true,color="r",linewidth=2)

ax2.plot(x,y2_error,color="g")
ax2.plot(x,_y2,color="b")
ax2.plot(x,y2_true,color="r")

ax3.plot(x,y3_error,color="g")
ax3.plot(x,_y3,color="b")
ax3.plot(x,y3_true,color="r")

plt.show()
```

このコードを実行すると次のような結果となります。

![figure.png](https://qiita-image-store.s3.amazonaws.com/0/215792/8e2b79a8-4fba-bf5a-17d7-551429c360b5.png)

今回ノイズとしてのせたデータは２次の誤差だったので、3時関数に対しては小さい誤差量だったためかほぼほぼ一致していました。緑の線は誤差を乗せた信号、青い線はフィルタを施した信号、赤い線は真値です。線形データに対しては誤差量が大きいので真値に近ずくことは難しいですが、かなり振動を抑えられていると考えられます。

今回はかなり大雑把な実験でしたが、実際に手を動かして実験したことで、どのような条件の場合にローパスフィルタを使えば良いかについて再度考えさせられました。
今後はハイパスフィルタなども使ってみたいと思います。
座標上の四角形の中に、点が入っているかを調べたい

# はじめに
点(a,b,c,d)をもつ四角形の中に点eが入っているか、を出すためにベクトルの外積を使用します。
numpyって本当に便利ですね。

# 考え方
1. まず、原点から点(a,b,e)へのベクトルA,B,Eを作成。
2. 点aからbへのベクトルAB、点aからeへのベクトルAEを計算。
3. ベクトルAB、ベクトルAEの外積を計算
4. b->c,c->d,d->aに対しても2,3を実施する。
6. a->b, b->c, c->d, d->a のすべてで外積がマイナスであれば、
   点は確変の左側にあるといえる
   ->四角形の中にある

![image.png](https://qiita-image-store.s3.amazonaws.com/0/63125/1bcc336b-48a3-431d-d6bb-e1e1360c4f7f.png)

# 実装
以下が実装。

```python:rect_inside.py

def in_rect(rect,target):
    a = (rect[0][0], rect[0][1])
    b = (rect[1][0], rect[1][1])
    c = (rect[2][0], rect[2][1])
    d = (rect[3][0], rect[3][1])
    e = (target[0], target[1])

    # 原点から点へのベクトルを求める
    vector_a = numpy.array(a)
    vector_b = numpy.array(b)
    vector_c = numpy.array(c)
    vector_d = numpy.array(d)
    vector_e = numpy.array(e)

    # 点から点へのベクトルを求める
    vector_ab = vector_b - vector_a
    vector_ae = vector_e - vector_a
    vector_bc = vector_c - vector_b
    vector_be = vector_e - vector_b
    vector_cd = vector_d - vector_c
    vector_ce = vector_e - vector_c
    vector_da = vector_a - vector_d
    vector_de = vector_e - vector_d

    # 外積を求める
    vector_cross_ab_ae = numpy.cross(vector_ab, vector_ae)
    vector_cross_bc_be = numpy.cross(vector_bc, vector_be)
    vector_cross_cd_ce = numpy.cross(vector_cd, vector_ce)
    vector_cross_da_de = numpy.cross(vector_da, vector_de)

    return vector_cross_ab_ae < 0 and vector_cross_bc_be < 0 and vector_cross_cd_ce < 0 and vector_cross_da_de < 0

if __name__ == '__main__':
    rect = [[48, 43],[45, 42],[43, 38],[45, 39]]
    print(in_rect(rect, [44,45]))
    # -> False
    print(in_rect(rect, [46,41]))
    # -> True
```

# 参考
http://www.endo-yuta.com/2011/09/blog-post_06.html
【調査】WEBアプリをPWAとして起動した場合にブラウザのlocalStorageが引き継がれるか確認する

# 【追記】調査用アプリ
調査で利用したWEBアプリは今後もiOS, Androidバージョンアップ時に利用する可能性がありそうなためHerokuで公開しておきました。（無料プランのためしばらくアクセスがなかった場合はページが表示されるまで少し時間がかかります）

https://pwa-localstorage-test-app.herokuapp.com/
![heroku-pwa-localstorage-test-app.png](https://qiita-image-store.s3.amazonaws.com/0/141934/162f1223-7a6b-b05e-2400-8bd935a4be89.png)

# 調査内容
WEBアプリをPWA（プログレッシブウェブアプリ）として起動した場合にブラウザのlocalStorageが引き継がれるか確認する。

## 調査対象

- iOS 11.3
- Android 8.0

# 調査の背景

参考：[【調査】WEBアプリをPWAとして起動した場合にブラウザのCookieが引き継がれるか確認する \- Qiita](https://qiita.com/NaokiIshimura/items/19073a45f994129c40b1)

iOS(11.3)のPWAではブラウザとCookieが共有されない＆前回起動時のCookieは引き継がれないため、これまでのWEBアプリのようにCookie(Session)にログイン情報を保存しておくということができない。

PWAではオフラインストレージの利用が想定されているため、ログイン（ユーザ認証）済みであることを示す情報をlocalStorageに保存した場合、どのようにブラウザ／PWA間で引き継がれるのか確認した。

## 確認方法
**set token**リンクをクリックするとlocalStorageに`token`として`ランダムな英数字`を格納するアプリを作成。

事前にブラウザでtokenをsetしておき、PWAとして起動した場合に、
- valueの値がブラウザと同じであれば、localStorageが引き継がれている
- valueの値が空欄であれば、localStorageが引き継がれてない
と判断する。

<img width="852" alt="pwa_localstorage01.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/85b178a7-69fc-001a-12eb-58f265b3b384.png">

# 結果

## まとめ

iOS 11.3 はブラウザとPWAでlocalStorageが共有されない。
PWAを再起動してもlocalStorageのデータは保持される。
ブラウザとPWAでlocalStorageは独立している。

Android 8.0 はブラウザとPWAでlocalStorageが共有される。

## 詳細：iOS 11.3

- ブラウザのlocalStorageはPWA起動時には引き継がれない
- PWAを再起動（HomeScreenから再度開く）した場合、前回PWA起動時のlocalStorageは引き継がれる
- PWAでlocalStorageに値を設定しても、ブラウザのlocalStorageには反映されない

## 詳細：Android 8.0

- ブラウザのlocalStorageはPWA起動時に引き継がれる
- PWAを再起動（HomeScreenから再度開く）した場合、前回PWA起動時のlocalStorageは引き継がれる
- PWAでlocalStorageに値を設定したら、ブラウザのlocalStorageにも反映される

# スクリーンショット

## iOS 11.3

<img width="846" alt="pwa_localstorage_ios01.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/92532eba-11f4-2df3-0722-3c13486cbe44.png">


<img width="850" alt="pwa_localstorage_ios02.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/5b4912b5-d42f-0c68-1443-b29d220235bc.png">


<img width="865" alt="pwa_localstorage_ios03.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/54c702b7-c492-05c9-8340-6795295ee39c.png">

## Android 8.0

<img width="877" alt="pwa_localstorage_android01.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/30741f52-c343-dcb7-1c21-749be7d66ee7.png">


<img width="858" alt="pwa_localstorage_android02.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/8fd723c2-91b4-a225-ea04-66b57a047eec.png">


<img width="861" alt="pwa_localstorage_android03.png" src="https://qiita-image-store.s3.amazonaws.com/0/141934/ba12ae94-e2c7-d4fa-6bab-580722467e09.png">

# 補足

## 調査用アプリのソースコード（Ruby on Rails）

[NaokiIshimura/Qiita\-PWA\-LocalStorage](https://github.com/NaokiIshimura/Qiita-PWA-LocalStorage)

> 補足：localStorageへのset/get/removeはJavaScriptだけで操作できますが、
> 　　　Cookie調査時のソースコードを流用したためRailsアプリとなってます。。。
> 　　　HTML/JS部分のみ確認したい場合は[こちら](https://github.com/NaokiIshimura/Qiita-PWA-LocalStorage/blob/master/app/views/static_pages/home.html.erb)をご参考ください。
Pythonで世界地図-6

グラフで座標を取得する方法がわかったので、
#####座標から経度・緯度を求める
方法を探しました。

実行例
./map1.py 東京
（全ての都市で使えるわけではなさそうです。ではなくて時間が掛かって失敗しているのか？何回かやれば表示されました。ローマ字だとすぐに表示されるようです。）

地図上をクリックすると、緯度・経度が表示されます。

間違っていたので修正しました。

```python:map1.py
#!/usr/bin/python3
# coding: UTF-8

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
from pygeocoder import Geocoder
import sys

font = {'family':'IPAGothic'} #日本語Fontを指定

args = sys.argv
argc = len(args) # 引数の個数

if (argc != 2):   # 引数がない場合
    print ('./map1.py 目的地の名称')
    quit()

area_name = args[1]

try:
    result = Geocoder.geocode(area_name)
    lon1 = float(result.longitude)
    lat1 = float(result.latitude)
except:
    quit()

map = Basemap(llcrnrlon=lon1-2,llcrnrlat=lat1-2,urcrnrlon=lon1+2,urcrnrlat=lat1+2,resolution='h',projection='cyl')

map.shadedrelief() #標高図
map.drawcoastlines()

map.drawmeridians(np.arange(0, 360, 10))
map.drawparallels(np.arange(-90, 90, 10))

try:
  while True:
    a=plt.ginput(n=1)[0]  #クリックして座標を取得
    b=map(a[0], a[1], inverse=True) #座標を緯度・経度に変換
    plt.title("東経{}°　北緯{}°".format(b[0],b[1]), **font)
except:
  pass

plt.show()

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/9cff5f9f-66c8-62e0-dfa3-7c3b3a666bb5.png)
今、気が付きましたが、これを指定するとグラフの右下に表示される座標が、緯度・経度に代わっています。

#####2点間距離を求める
地図上を2箇所クリックする。

変更点

```python:
from mpl_toolkits.basemap import pyproj

try:
  while True:
    aa=plt.ginput(n=1)[0]  #クリックして座標を取得
    bb=map(aa[0], aa[1], inverse=True) #座標を緯度・経度に変換
    cc=plt.ginput(n=1)[0]  
    dd=map(cc[0], cc[1], inverse=True) 
    map.drawgreatcircle(bb[0],bb[1],dd[0],dd[1],linewidth=2,color='b')  #大圏コース
    gc = pyproj.Geod(a=map.rmajor,b=map.rminor) # ポイント間の距離計算
    az1, az2, dist12 = gc.inv(bb[0],bb[1],dd[0],dd[1])
    plt.title("2点間の距離＝ {} km".format(dist12/1000), **font)
except:
  pass
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/8a75d5cf-0502-0375-6ead-c8bc5041b900.png)

#####ウインドウの中で地球を動かすことができるか？
私が調べた範囲ではできないような気がする。

plt.show()を終了させることが、できなかった。
無限ループでウインドウの右上のXボタンで終了させて、次の表示まで１０秒程度表示なしで繰り返すことくらいしか出来なかったので、アニメgifにしました。
白黒の地球で数分程度？、なんか寂しいので標高図（山の高さにより色が違う）にすると、ファイルサイズは3〜５倍程度だが、無限ループで360枚pngファイルを作成しようと思ったら、メモリ不足？作成時間はだんだん長くなるわ、エラーで止まるわ４時間程度かかった。
最後２０枚程度は１枚１枚作成したら、それほど時間がかからなかった。メモリを開放しなければいけなかったのか？。

色の付いたアニメgifは出来ましたが、サイズオーバーでアップできませんでした。

![a.gif](https://qiita-image-store.s3.amazonaws.com/0/238800/291960bc-e282-6b5d-a800-bab0d8216e1b.gif)
AWS Connected Vehicle Solution Implementation Guideのイケてないところを指摘する

## 自己紹介
5年ほどAWSを使ってメディア系サービスの開発に携わった後、ConnectedService関連の開発を1年ほどしています。
昨年AWSがAWS Connected Vehicle Solution を発表して自動車業界への興味関心をアピールしたが、読みつつ個人的にイケてないと思った部分をここに記します。

## おことわり
 - AWS Connected Vehicle Solutionについて：https://aws.amazon.com/jp/answers/iot/connected-vehicle-solution/
 - January 2018バージョンのImplementationGuideに対してレビューしました
 - AWS大好きです

## 指摘１：可用性、拡張性より移植性がほしい
本ガイドの前半、概要部分にはざっくりと以下のようなことが書かれている。

 - このアーキテクチャを活用するとサーバレスでコネクテッドサービス基盤を作成できる
 - AWS-IoTを使って車と接続することでセキュアでローレイテンシーでオーバーヘッドが少なくなる
 - イベントドリブンなアプリケーションを構築できる（ヘルスチェックやメンテナンス、レコメンド）
 - 安全に車両接続ができ、車両内でのローカルコンピューティングができ、データを安全に保管でき、様々なイベント処理ができる
 - このソリューションはフレームワークを提供するもので、やりたいサービスによって拡張できる。例えば音声対話、ナビ、遠隔車両診断、ヘルスチェック、予測分析、メディアストリーミング、セキュリティサービス、ヘッドユニットアプリケーション、モバイルアプリケーションなどの拡張性を備える
 - コストに関しては、扱うデータサイズによって変わる

全体としてAWSの特長を活かした可用性、拡張性に優れたアーキテクチャであることを主張している。
しかし、コネクテッドサービスを実際につくる側の立場にたつと、会社には既にコネクテッドサービス基盤（やそれに近しいWebシステム）が存在しており、移植性や疎結合性について言及していないのは開発者のことを本気で考えていないように感じてしまう。

## 指摘２：車を既存のThingと同一視している
サンプルとして提供されているCloudFormationTempleteに対しては以下のように説明している。

 - デフォルトのCloudFormationTempleteに従って環境を構築すると、6つのビジネルルールに従ってデータを処理する
  - anomaly detection : Kinesis Firehose でリアルタイムにデータを処理し、Kinesis Analyticsで機械学習で異常を検知し、KinesisStreamでDynamoに異常レコードを保存すると同時にSNS通知のトリガーも行う
  - trip data : トリップデータをトリップが終わるまでDynamoに送り続ける
  - driver safety score : トリップの終了を検知して、運転後にトリップデータから安全度のスコアを算出する
  - diagnostic trouble codes : トラブルコードを検知してSNSで通知
  - location based marketing : 車両の位置を監視して、特定のポイントに近づいたら広告をSNS経由で出す
  - Just in time registration : 車両の証明書の自動登録
 - サードパーティのアプリケーションはCognito、APIGatewayを用いてDynamoにアクセスできる

車両（モノ）単位でデータを扱っているが、車の挙動やそれに伴って出現するデータは運転者に依存するところが大きいことを考慮してほしい。ある人にとっては急ブレーキでもある人にとってはそうでなく、そこに正解／不正解もないのが車だと思う。なので、本アーキテクチャでは（3rd-partyサービス以外は）データを車両単位で考えているが、私は基本的に人単位で考えるべきだと思う。
少なくともそういう拡張性があることを説明してほしい。

## 指摘３：資料の公開範囲が広すぎる
この資料の最後には以下のように記載されている

 - この文書は情報提供のみを目的として提供されています。これは、このドキュメントの発行日現在のAWSの現在の製品提供および実践を表しており、予告なしに変更されることがあります。お客様は、本書の情報およびAWSの製品またはサービスの使用に関する独自の評価を行う責任を負います。これらの製品またはサービスは、明示または黙示を問わず、いかなる保証もなく現状のまま提供されます。

技術者的に情報提供はありがたいのだが、問題は非技術者にもこれが展開されてしまい、技術者は非技術者（往々にして上司）に対する本資料の説明に追われたことである。（自分だけですかね）

もし本当に情報提供が目的だったのであれば、誰にでも伝わりやすいニュースリリースでなく、Blackbeltのような技術者向けの配信形態をとってほしかった。

## まとめ
 - 既存のコネクテッドサービスと共存ないしは移植できるのか。
 - 車は人が乗るものだから人単位で管理したい
 - 技術提供は技術者にしてほしい
SPSS Modelerを解説するYoutube動画

#SPSS Modelerを解説するYoutube動画が公開されています。

■日本独自コンテンツで一本あたりは4分程度でまとめたもの
4分でわかる! IBM SPSS Modeler概要 機能篇 - YouTube
https://www.youtube.com/watch?v=iD6Et_svUZY
IBM SPSS Modeler は、正確な予測モデルを素早く構築し、個人、グループ、システム、企業に予測インテリジェンスをもたらす国内シェアNo.1のデータ・マイニング予測分析プラットフォームです。


IBM SPSS Modelerのデータハンドリング機能 - YouTube
https://www.youtube.com/watch?v=2stYxYt8q2U
IBM SPSS Modelerなら 、分かりやすいGUIによる操作で、データの出し入れはもちろん、データ・クレンジング、データ結合など煩雑なデータ・ハンドリングもスマートに完了いただけます。データ準備とデータ分析が同一のプラットフォームでできるのも、一連の分析業務を効率化できる秘訣です。

IBM SPSS Modelerのオートメーション機能 - YouTube
https://www.youtube.com/watch?v=8fHCfPHrhTk
IBM SPSS Modelerのオートメーション機能から、よく利用される「自動変数選択」「自動モデリング・アンサンブル」「データ自動準備と欠損処理」を紹介します。複数種類の予測分析アルゴリズムを利用し、データの欠損値を判別しながら、短時間に分析精度の高い予測分析モデルを作成していきます。


IBM SPSS Modelerの機械学習・決定木分析 - YouTube
https://www.youtube.com/watch?v=vtCxArBB6qE
IBM SPSS Modelerならば、機械学習のアルゴリスムとなる決定木分析も簡単にチャレンジ可能。データ分布を確認しながら内部的に全てのクロス集計を自動実行。入力変数、分割数、閾値も自動判別し、分岐させたデータグループを表示します。更にデータ毎に予測分析を実行。ビジネス利用を考えずにはいられなくなるでしょう。

SPSS Modelerの機械学習・ニューラルネットワーク - YouTube
https://www.youtube.com/watch?v=b3DfApLWKZw
IBM SPSS Modelerは、機械学習のアルゴリスムであるニューラル・ネットワーク、サポートベクターマシンも利用可能。自動モデル作成はもちろんのこと、SPSS Modeler独自機能である、個々の分析モデルの評価を行う評価グラフもご覧いただきます。


SPSS Modelerで実践-解約・休眠防止 - YouTube
https://www.youtube.com/watch?v=kcVO6CAP7g8
IBM SPSS Modelerで顧客を休眠させないための実践例を取り上げます。購買動向をRFM分析し、次の四半期に休眠予測を決定木分析で実施します。ぜひビジネスへお役立てください。

SPSS Modelerで実践-新規顧客の獲得 - YouTube
https://www.youtube.com/watch?v=lFeyME6oJSk
IBM SPSS Modelerで、Webログを用いた顧客の予測モデルの作成しROIの最大化を目指す例を紹介します。自動車メーカーWebサイトの行動を例に、スコアリングにより顧客のライフタイム・バリューのピークに顧客を獲得する方法を考え契約率が高いと予想される見込み客リストを作成する方法です。

SPSS Modelerで実践-顧客クラスタリング - YouTube
https://www.youtube.com/watch?v=i0UncrUsQuU
IBM SPSS Modelerで、顧客の育成を目的にした顧客誘導の実践、分析例をご紹介します。顧客として定着した後に客単価を向上させて行くため、購買傾向の似たクラスタに分けて、クラスタ内で人気の製品を購入しているかどうかを調べ、未購入の製品を表示させて成長を促すパスについて検討します。


SPSS Modelerで実践-リピート率の向上 - YouTube
https://www.youtube.com/watch?v=q9-ESnJqYNU
IBM SPSS Modelerで、トライアル期の顧客行動パターンに注目し、リピート率の誘発を検討します。獲得直後の顧客を定着させるには、初動での購買パターンを踏まえた適切なオファーが有効です。単純な併売傾向ではなく、協調フィルタリングによる適切なオファリングを開発、時間軸を加味した顧客への推奨を考えます。

SPSS CADS 分析結果を利用した業務の自動化と展開 - YouTube
https://www.youtube.com/watch?v=gxktNevQ0LY
予測分析モデルから結果を得ることだけにとどまらず、予測結果をビジネスに活用する検討をする場合、何が必要となるでしょう。IBM SPSS Collaboration and Deployment Servicesならば、SPSSの分析結果を定型化し、分析結果によるジョブの業務に組み込みを行うことができます。

■翻訳もので、一本でまとめたもの
予測分析を始めましょう SPSS Modeler クイック・スタート・ガイド - YouTube
https://www.youtube.com/watch?v=cNh2Ebhrehg
SPSS Modelerトライアルのクイックスタートのために、本製品を使用するコツとヒントをムービーでご紹介します! (24分30秒)
windowsとmacのディスプレイ共有

ご覧いただきありがとうございます。
初投稿です。お世話になります！

MacBookProをメインとしてwindowsをデュアルディスプレイとしてに使用したいのですが、色々と試しましたが上手くいかず困っております。

まずスペックを記載させていただきますね。

【mac】
MacBook Pro (Retina, 15-inch, Mid 2015)
High Sierra　バージョン10.13.2
HDMI端子有り

【Windows】
VS350/T
windows7
HDMI端子無し

mac側にHDMI端子を差し込み、それを変換アダプタでUSB端子へ変換→windowsのUSB口に差し込んだのですが、macがwindowsを認識してくれません。
windows側は一応反応はしています。（通常のUSBメモリを差し込んだ時と同じで「データを取り込みますか」と言った反応をします）

いくら検索しても解決策が見当たらず・・周囲に詳しい人もいないので解決できず困っています。
スペース的にもう１台モニターを置くことはできないので、既存のwinを上手く活用できれば・・・・。
どうかご教授宜しくお願い致します！
Serverless Framworkを使ってdeployするときの必要最低限の権限

ServerlessFrameworkではAdministrator権限付与することになっていますが、ダメって言われたので調べました。
ServerlessFrameworkでデプロイ、Lambdaを実行するためだけの権限です。

Serverless Frameworkで使用するIAMのユーザーに、
下の内容をポリシーのJSONに記載して、そのポリシーをユーザーに付与すれば可能

###ポリシーのJSON
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "events:EnableRule",
                "logs:DescribeLogStreams",
                "events:PutRule",
                "iam:GenerateServiceLastAccessedDetails",
                "s3:CreateBucket",
                "cloudformation:DescribeStackResource",
                "s3:ListBucket",
                "cloudformation:CreateChangeSet",
                "s3:GetBucketPolicy",
                "s3:GetObjectAcl",
                "iam:PassRole",
                "cloudformation:DescribeStackEvents",
                "events:ListRules",
                "cloudformation:UpdateStack",
                "logs:FilterLogEvents",
                "s3:DeleteObject",
                "cloudformation:ExecuteChangeSet",
                "events:DisableRule",
                "events:PutEvents",
                "iam:ListPolicies",
                "iam:GetRole",
                "events:DescribeRule",
                "iam:ListSAMLProviders",
                "iam:ListGroupPolicies",
                "logs:CreateLogGroup",
                "events:TestEventPattern",
                "cloudformation:DescribeStacks",
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutBucketNotification",
                "s3:ListAllMyBuckets",
                "cloudformation:CreateStack",
                "lambda:*",
                "s3:GetBucketLocation",
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*"
        }
    ]
}
```

これでServerlessFrameWork　でdeploy,実行はできました。
正直やっている途中で雑に権限を付与したので、不要なものもあると思います。


>参考にした記事
[【AWS x S3 x IAM】アプリから S3 にデータをアップロードするときの IAM 権限設定]
(https://qiita.com/tanakaworld/items/196300d556feada5737b)
スマートコントラクトを理解してみた

#スマートコントラクトとは

##目次
1,スマートコントラクトとは
2,Smart Contract Japanでの説明
3,今後の方針

##1,スマートコントラクトとは
大学の研究で暗号通貨に関しての研究をすることになった際に調べて意味がわからなかったため調べて見ました。
調べた結果、スマートコントラクトとは端的にいうと<font color="crimson">***「第三者を介さない自動契約履行システム」***</font>であると自分は理解しています。(あくまで自分の見解です)

「スマートコントラクトとは?」に関して詳しく説明する前に、「第三者を介さないで契約を行う仕組みがなぜ必要なのか?」を現在の契約を執行する仕組みがどのようになっているのかというところから説明したいと思います。
現代社会では、webサイトなど相手の見えない場面で取引を行う際には必ず信頼のある第三者(クレジットカード会社など)が介入し、そこが商品が配送されなかった場合や、入金がされなかった場合などの保証を行うというような仕組みになっています。
具体的に例を挙げて説明してみると
例1)現在のwebサイトで物をクレジットカードを利用して売買をする時
![smart01.jpg](https://qiita-image-store.s3.amazonaws.com/0/182526/e7ea4f24-c625-44c5-5dad-a6a53b4b9373.jpeg)


このような形です。本来であれば、このままで問題はないかと思われるかもしれませんが、この第三者を介して取引をする場合には以下のような問題点が挙げられます。
###[問題]
1,やりとりのコスト(手数料)が高い
2,第三者機関の信頼の必要性
3,プライバシー
4,取引成立までにかかる時間
5,中央集権的


「こんな問題が発生するなら直接売り手と買い手が売買を行えばいいじゃないか!」という人もいるかもしれません。では、直接やりとりをした時のことを想定して見ましょう。自分が靴を買うために初めて見たwebサイトから購入したい靴を購入ボックスに入れて、購入手続きを行いました。購入手続きが完了した最後に、「以下の講座番号にお金をいついつまでに振り込んでください。」という文章が出てきました。この時、あなたははいわかりましたとお金を振り込むでしょうか。ある程度の人は、ここで素性のわからない、靴も確実に送ってもらえるかわからない相手に対してお金は振り込まないでしょう。むしろ先に靴を送れよ!となるかもしれません。これに対して、販売業者側は靴を送ったところでネットの向こう側のお客さんが確実にお金を振り込んでくれるかなんてわかりません。なので、「靴を送る前にまずはお金を払ってよ!」となります。お互いがこのような状況になっては一向に契約が履行されません。
例2)webサイトでクレジットカードなど第三者を介さず、物を売る側と買う側が直接売買をする時
![smart012.jpg](https://qiita-image-store.s3.amazonaws.com/0/182526/5fd8148a-6170-7969-400e-ee459c25eb35.jpeg)


このように相手が信頼できない関係同士での取引の場合は直接やりとりをするのはどちらも損はしたくないという心理が働けば自然とこのようになってしまうものです。なので、今までは仕方がないく信頼の置ける第三者機関を挟さむことで取引を行なっていたのですが、インターネット場でスマートコントラクトが実行可能になることで、信頼の置ける第三者機関がなく、かつ相手を信頼せずともネットを介して物の売買が行えるようになったのです。

ここからようやくスマートコントラクトの説明です。
スマートコントラクトとは最初の説明でもお話ししたように「第三者を介さない自動契約履行システム」のことです。ここで思い込みをしている方がたまにいるのですが、スマートコントラクトとは仕組みのことなので、ブロックチェーン上で実行されるもののみがスマートコントラクトという訳ではありません。実際にこの現実世界でブロックチェーン以外で稼働しているスマートコントラクトのシステムは存在します。それは自動販売機です。自動販売機は売りたい側の人が直接売るのではなく、間に決まったアルゴリズムにしたがって自動的に処理を行ってくれる機械を挟み、取引契約を行っています。ここでいう取引というのは飲み物を買うに値する十分なお金と購入対象の飲み物が存在することを確認して、飲み物を買い手に渡し、お金を売り手に渡すという取引のことです。最近話題になっているスマートコントラクトとはこの自動販売機のようなアルゴリズムにしたがって自動的に実行される仕組みをブロックチェーン技術を応用することでネットワーク上でも可能になったというお話です。

![smatr04.jpg](https://qiita-image-store.s3.amazonaws.com/0/182526/3d100fc4-3ebe-ef3c-bce3-f19a37524075.jpeg)
（※↑のフリーイラストの男性を反転させればよかったことに後から気づいたのですが、作成中は気づかなかったため、消費者と販売側が自動販売機のイラストに限り左右反転しています。）

![smart05.jpg](https://qiita-image-store.s3.amazonaws.com/0/182526/3aa6c9ea-fe49-41ea-bd27-f05f59ef4c0e.jpeg)




##2,Smart Contract Japanでの説明
スマートコントラクトの定義は、2015年現在未だ曖昧ですが、
基本的には「オンライン上の効率的な合意システム」として、
様々なプラットフォーム上で実装が試行され始めています。
文字を分解すると、スマートとは、効率的であるという意味、
そして、コントラクトとは、法的な「契約」という意味ではなく、「合意」という意味です。
つまりスマートコントラクトとは、効率的な合意システムです。

##3,今後の方針
実際にスマートコントラクトがBlockchain(特に分散処理アプリケーションのプラットフォームとしての幅を聞かせているイーサリアム上)でどのように実行されているのかを調べて見たいと思います。
指摘等ありましたらバシバシお願いいたします。
Xcodeをアンインストールしたらgitが使えなくなった

## 概要
swiftでの開発をしなくなったので、Xcodeを削除したらいきなりgitが使えなくなったので解決法のメモです。

エラー内容

```
error: active developer path ("/Applications/Xcode.app/Contents/Developer") does not exist
```

## 解決法
参考ブログの項目に記載している記事のコマンドをコピペしたら解決したので、コマンドのみ記載します。
専門分野外のことは解決すれば内容は気にならないタイプなので、詳しく知りたい方は参考ブログを御覧ください。

```
$ sudo xcode-select -switch /Library/Developer/CommandLineTools
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install git
```

## 参考ブログ
- [Xcodeをアンインストールしたことによってgitが使えなくなった時に、運悪くOSがYosemiteだった時の対処法](http://tiro105.hateblo.jp/entry/2015/06/23/134741)
Fusion360で作成したオブジェクトをBlenderで編集する

# はじめに
Fusion360のスカルプトモデリングってすごいですよね。あの曲線。本当に「粘土をこねるように」操作できて感動です。

そして私は思うんです。こんなにきれいに曲線ができるなら、人体の曲線美の表現が非常に楽になるのではないかと。モチモチのほっぺや流れるような髪を表現できないかと。Fusion360で作成したモデルにボーンを追加して編集できれば、素晴らしいキャラクターが作れないかと。

そこで、MMDモデラーにも広く使用されているBlenderでFusion360で作成したオブジェクト(モデル)を読み込み、編集する方法について調べたので、まとめておきたいと思います。


# Fusion360からオブジェクトをエクスポートする
Fusion360ではオブジェクトをエクスポートする方法が2種類あります。
#### ローカル
ローカルエクスポートでは以下のファイル形式で書き出すことが可能です。

- .f3d
- .igs/.iges
- .sat
- .smt
- .stp/.step

画像の場所からすぐに書き出せます。簡単！！
![local_export.png](https://qiita-image-store.s3.amazonaws.com/0/230703/05f9e81b-255d-bc6b-f849-1410775a5191.png)

また、以下のようにブラウザから`.stl`形式に書き出すことも可能です
![stl_local.png](https://qiita-image-store.s3.amazonaws.com/0/230703/6bb15328-c6e8-74c8-88a4-175e271c9562.png)


#### クラウド
クラウドエクスポートでは以下のファイル形式で書き出すことが可能です。

- Fusion360 Archive
- Inventor 2016
- .iges
- .sat
- .smt
- .step
- .dwg
- .dxf
- .stl
- .fbx
- SketchUp
- .obj

クラウドエクスポートを使うためにはオブジェクトの保存場所をwebブラウザで開く必要があります。

# Blenderで使うために
この記事では以下のテストオブジェクトを使用していきます。
取っ手の部分がスカルプトモードでモデリングを行った部分になります。

![test v1.png](https://qiita-image-store.s3.amazonaws.com/0/230703/830d6130-6d17-c5cd-5ce6-c62740ee026b.png)

Blenderで使うためには`.stl`もしくは`.obj`で書き出す必要があります。
`.stl`はローカルエクスポートでもできますが、`.obj`はクラウドエクスポートでないと書き出せない形式ですね…
ただ、`.stl`形式だと、オブジェクトの向きが3Dプリンター向けに自動修正されてしまいます…非推奨です……
![ratate.png](https://qiita-image-store.s3.amazonaws.com/0/230703/43261942-5157-1762-ba90-e2afb938c440.png)


この記事では`.obj`形式で書き出していきます。

## 書き出す
オブジェクトの保存場所をwebブラウザで開きます。
プロジェクト名をクリックすると飛べます。
![project.png](https://qiita-image-store.s3.amazonaws.com/0/230703/22125b7d-b97b-65a0-3728-a420ca31900c.png)


ダウンロードから`.obj`を選択します。
![8.png](https://qiita-image-store.s3.amazonaws.com/0/230703/f318edc2-e07c-a60d-0471-f6012c78849b.png)

書き出しが終了すると、アカウントに登録されているメールアドレスにファイルが送られるので、ダウンロードしてください。

## Blenderにインポートする
`import`からファイル形式`.obj`を選択し、
![blender.png](https://qiita-image-store.s3.amazonaws.com/0/230703/007e5aa4-c361-3a6f-0e6d-5b5d945c0ca9.png)

先ほどダウンロードしたファイルを選択してインポート！
![import.png](https://qiita-image-store.s3.amazonaws.com/0/230703/1b25caae-ffa8-49dd-5b2a-75e09d803814.png)


できた！すごい！
![complete.png](https://qiita-image-store.s3.amazonaws.com/0/230703/62da2d26-a62e-9605-e358-a5603e1710f6.png)

取っ手もいい感じですね

# おわりに
やっぱり曲線は頂点数が多くなります…
MMDで動かすなどする前に頂点を減らしたほうがよさそうではあります…
Leaflet.js を使って GeoJSON データを地図上に表示してみる その2

[Leaflet\.js を使って GeoJSON データを地図上に表示してみる その１ \- Qiita](https://qiita.com/sin164/items/1ed25130fa5a1de00ea8)
で下ごしらえしたGeoJSONファイルを使用

#JavaScript
```javascript:index.js
//. 掛川城の緯度経度（初期位置）
var lat = 34.77530283508074;
var lng = 138.01500141620636;

var map = null;
var marker = null;

$(function () {
  //. 掛川城を中心とした地図を OpenStreetMap データで表示
  map = L.map('map').setView([lat, lng], 15);
  L.tileLayer(
    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'Map data &copy; <a href="http://openstreetmap.org/">OpenStreetMap</a>',
      maxZoom: 18
    }
  ).addTo(map);

  $.getJSON('./convertcsv.geojson', function (data) {
    var geojson = L.geoJson(data, {
      onEachFeature: function (feature, layer) {
        var field = '名称: '+feature.properties.name+ '<br>'+
        '住所: '+feature.properties.address+ '<br>'+
        '電話番号: '+feature.properties.tel+ '<br>'+
        '<a href="'+feature.properties.url+ '" target="_blank">ホームページ</a>';

        layer.bindPopup(field);
      }
    });
    geojson.addTo(map);
  });
});
```
ServerlessFrameworkで『自身のSTAGEが知りたい』時

# 背景
ServerlessFrameworkでは「--stage Dev」といったようにして、ステージという概念でプロダクションと開発環境を分けたりします。

つまりAWS lambda内に
プロジェクト名-Prod-関数名
プロジェクト名-Dev-関数名
が沢山並んでいる状態です。

関数が単独で完結している場合は良いのすが、invokeで呼び出したい場合、
「ステージProdの時はProdの、あの関数を呼び出したい」「ステージDevの時はDevの関数を呼び出したい」というケースもあります。

ServerlessFrameworkはデプロイすると関数の『タグ』を自動的につけてくれます。
STAGEの値がそれです。

これが簡単に取得できると、invokeする側で「今、私のステージはDevだから、同じステージのこの関数を呼び出そう」という事ができます。

# やり方
下記のようにすると「自身のステージ」を得ることができました。
必要な権限は lambda:GetFunction でした。

```
const lambda = new AWS.Lambda({ region: 'ap-northeast-1' });

module.exports.hoge = (event, context, callback) => {
  lambda.getFunction({ FunctionName: context.functionName }, (err, data) => {
   if (err) console.log(err, err.stack);
   else     console.log(`STAGE is ${data.Tags.STAGE}`);
  });
}
```

lambda.getFunctionについては[ココ](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#getFunction-property)

context.functionNameについては[ココ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-prog-model-context.html)を参考にしました

# 反省
context.functionName で自身の関数名が取得できているので、API叩くのではなく、文字列をゴニョゴニョした方が早そう。
プロジェクト名も入ってるしね。