OmniAICreator/Qiita-1.07M huggingface dataset:
AWS CLIでRequestTimeTooSkewedエラーが発生した時の対処法

VirtualBoxで構築したUbuntu環境にAWS CLIをインストールし、実行してみたところ以下のエラーが発生しました。

```
$ aws s3 ls
An error occurred (RequestTimeTooSkewed) when calling the ListObjectsV2 operation: The difference between the request time and the current time is too large.
```

調べてみたところ、実行環境のシステム時間と現在時間が大きくズレていると発生するようです。

## システム時間確認

dateコマンドで時間確認

```
$ date
Tue Feb 19 06:05:09 UTC 2019
```

2019年2月19日15:20頃が実行したタイミングの日本時間だったので、9時間15分と確かに大きくズレていました。

## タイムゾーン設定
まずは時差による9時間のズレを直すため、timedatectlコマンドでタイムゾーンを東京に設定します。

```
$ timedatectl set-timezone Asia/Tokyo
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-timezone ===
Authentication is required to set the system timezone.
Authenticating as: vagrant,,, (vagrant)
Password:
==== AUTHENTICATION COMPLETE ===
$ date
Tue Feb 19 15:06:40 JST 2019
```

## 時刻微調整
続いて分単位の時刻設定を行おうとしましたが...

```
$ timedatectl set-time "2019-02-19 15:25:00"
Failed to set time: Automatic time synchronization is enabled
```

同期設定が有効になっているため失敗しました。
一旦同期設定をOFFにし、再度時刻設定を行います。

```
$ timedatectl set-ntp no
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-ntp ===
                network time synchronization shall be enabled.
Authenticating as: vagrant,,, (vagrant)
Password:
==== AUTHENTICATION COMPLETE ===
$ timedatectl set-time "2019-02-19 15:27:00"
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-time ===
Authentication is required to set the system time.
Authenticating as: vagrant,,, (vagrant)
Password:
==== AUTHENTICATION COMPLETE ===
```
今度は時刻設定に成功しました。
同期設定を有効に戻します。

```
$ timedatectl set-ntp yes
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-ntp ===
                network time synchronization shall be enabled.
Authenticating as: vagrant,,, (vagrant)
Password:
==== AUTHENTICATION COMPLETE ===
```

念のため時刻とタイムゾーンが正しいか確認します。

```
$ timedatectl status
                      Local time: Tue 2019-02-19 15:27:52 JST
                  Universal time: Tue 2019-02-19 06:27:52 UTC
                        RTC time: Tue 2019-02-19 06:27:53
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
```

## AWS CLI動作確認
改善したか確認します。

```
$ aws s3 ls
2019-02-19 14:18:00 ***************
2018-10-09 16:35:28 ***************
2019-01-12 21:45:34 ***************
(伏字はS3バケット名)
```

無事結果が返ってくるようになりました。
G Suite Admin SDK / Google API Client Library for Pythonの使い方

Google APIはドキュメントは多いけどよくわからんかったので使ったときのメモ。

### 前提
* Pythonが使える
* G Suiteのアカウントがユーザー管理の役割とかの強い権限を持っている

## クイックスタート
[Python Quickstart  |  Directory API       |  Google Developers](https://developers.google.com/admin-sdk/directory/v1/quickstart/python)
最初のサンプルコードもこれのステップを踏むだけでいい。とくに準備はいらない。ちゃんとやるのならDevelopers Consoleでプロジェクト作ってクレデンシャル作成とかしてもいい。

サービスというのはAPI Explorerで一覧になってるやつ。
[Google APIs Explorer](https://developers.google.com/apis-explorer/#p/admin/directory_v1/)

URLの`/admin/directory_v1/` に該当する部分を指定すればいい。


```python
service = build('admin', 'directory_v1', credentials=creds)

  # Call the Admin SDK Directory API
  print('Getting the first 10 users in the domain')
  results = service.users().list(customer='my_customer', maxResults=10,
                orderBy='email').execute()
  users = results.get('users', [])
```

使い方の雰囲気はみればわかると思うけど、

1. googleapiclient.discovery.buildからサービスを作成
2. サービスから実行するリソースを取得
3. リソースに対して実行するメソッドを指定してリクエストを作成
4. リクエストに対して`execute()`を実行してレスポンスを取得
5. レスポンスはただのディクショナリになっているのであとは自由に

という感じ。

### SCOPEの探し方
指定するスコープの一覧はここにある。
[Directory API: Authorize Requests  |  Directory API       |  Google Developers](https://developers.google.com/admin-sdk/directory/v1/guides/authorizing)

やりたい内容に合わせて複数指定していけばいい。

## Web APIのリファレンス
リクエストとレスポンスの詳細をみたいときはこれをみるといい。
[API Reference  |  Directory API       |  Google Developers](https://developers.google.com/admin-sdk/directory/v1/reference/)

その場で試すのもできる。

## Python APIのリファレンス
ここから辿れる。わりとしっかり書いてるので読めばだいたい解決する。
https://google-api-client-libraries.appspot.com/documentation/admin/directory_v1/python/latest/index.html

## こまごまTips
### ページング
ページング用にlist_nextが用意されている。使うとラク。自前でwhileとか再帰とか書かないでいい。
[Pagination  |  API Client Library for Python       |  Google Developers](https://developers.google.com/api-client-library/python/guide/pagination)

```python
activities = service.activities()
request = activities.list(userId=‘someUserId’, collection=‘public’)

while request is not None:
 activities_doc = request.execute(http=http)

 # Do something with the activities

 request = activities.list_next(request, activities_doc)
```

### バッチ処理
HTTPリクエストがいっかいで済む。エコ。
https://developers.google.com/api-client-library/python/guide/batch

更新系だけじゃなくて参照でも使える。

```python
def insert_animal(request_id, response, exception):
 if exception is not None:
  # Do something with the exception
  pass
 else:
  # Do something with the response
  pass

service = build('farm', 'v2')

batch = service.new_batch_http_request(callback=insert_animal)

batch.add(service.animals().insert(name="sheep"))
batch.add(service.animals().insert(name="pig"))
batch.add(service.animals().insert(name="llama"))
batch.execute(http=http)
```
ひとりRedmineのススメ



# 序文

せっかくGCPでサーバーを借りているのに使い道がなく困っていたラチェです。
今回は、暇つぶしがてらRedmineをGCP上で公開したお話をしたいと思います。
Redmineを公開するにあたっての注意点などなど。


## 経緯

実は1月頭まで技術ブログを運営してたのですが、アクセス数が無いこと、[^1]
また、更新のモチベーションがないことなどから
このまま放置してセキュリティホールになる前に潔く決着をつけようと思い、ブログの削除を行いました。
(イメージ丸ごと消しました！)

ブログを削除したついでに、USリージョンで新しくサーバを建て直し[^2]、
現在のblog.deathers.jpは、静的コンテンツをひっそり置いただけのものとなっています。

ただ、せっかくサーバを立てているのにコンテンツが静的コンテンツだけではもったいないなぁと思い、
*とりあえず*サブドメイン切って、Redmine立てとこうという流れになりました。

# 管理項目はどうしよう

ひとりRedmineなので、管理対象としては

* GCPのサーバー、セキュリティ管理
* プライベートのこと
* ブログサイトを今後どうしていくか

にしました。
また、今後のことも考え、権限設定だけはきっちり行いました。

# ひとりRedmineの利点

* 自分のタスクが目に見えてわかるようになる。
　これが決め手！と言うか、これしかない。
　期限管理、Tipsの登録などもRedmine上でできて非常に快適。

* 毎日見ることを習慣づけすることで抜けのない計画を立てられる。
　習慣づけすると非常に楽ですね。友達と約束してたセミナーへの参加等もこちらで管理できるので
　使いやすいです。

* 振り返りができる。
　今後、同じことを行おうとした時、エビデンスがあるので、対応コストが非常に減少します。
　去年何やってたっけなぁ。って思いだす手間がなくなるので非常にいい。

# Redmineを外部サーバに公開するにあたっての抵抗

やはり、多少はありました。
ぶっちゃけ、ローカルでサーバ立てて管理しても良くね？と思ったこともあります。
ですが、やはりスマフォで確認ができる。この一点ではないでしょうか。
いつでもどこでもタスクが確認できるメリットは非常に高いです。

## セキュリティ面でどうしたか

外部から確認できないようにするためのセキュリティとして、
以下3点を特に注意しています。

* コアなことは書き込まない(侵入された時の対策)
　結局外部サーバに公開している以上、コアな個人情報に関連する事柄はかけないです。
　また、アカウント情報なども同様。
　極端にぼかして書くもしくは書かないことに意識を向けています。

* ログを定期的に見る
　自分のサーバではfluentdを利用して、ログをCloudSQLに送っています。
　念のため、月1くらいで自分以外のIPから侵入が無いかを確認しています。
　ログはCloudSQLに入れているため、SQL一本書くだけで抽出は容易です。
　また、今後は監視設定をちょっと変えて、侵入検知などもできたらいいなと…

* ポートスキャン対策
　基本はHTTPとHTTPSとSSHしか開けてないので大丈夫だとは思います。[^3]
　必要最低限の構成にすることで、侵入のリスクを最低限にする考えです。
　ぶっちゃけWebサーバーのみなので、そんなにポート開けなくてもいい…

他、VPNでしかアクセスできないようにするとかそういうのも考えています。
WAFとかIDSとかを低価格で入れれたらもうちょいセキュアにはなるかと思いますが、
お金がない…

# ひとりRedmineのススメ(導入)

簡単な構成なら以下でインストールできます！(宣伝)
<a href="https://qiita.com/rache/items/4cf5477ef0e095832353">bitnami+GoogleCloudPlatformでお手軽サーバ構築</a>

ただ、セキュリティ的にはどうなのかは分からないので、自己責任で…
自分は直接GCEのインスタンスにRedmineを導入しました。(費用節約のため)

# まとめ

・ひとりRedmineすっごい便利
・web公開するならセキュリティがっちりと。
・簡単なインストール手順があるので、初心者でもWeb公開までは漕ぎ着けることができる！

**ということで、みなさん、一人Redmineいかがでしょうか！！**


[^1]: 正直言うと、1月あたり、100PVも無いので実質廃墟…
[^2]: GCEのインスタンス無料化にあやかり、リージョン変えました。<a href="https://qiita.com/rache/items/796a65a446cc2788144a">詳しくはこれ</a>
[^3]: デフォルトポート弾いたりなどの基本的な設定はちゃんとやってるはず…？
【連載】ジャンプ＆ランゲームを作ろう(3)  床の生成・カメラ移動に伴うスクロール・非可視床の削除

# はじめに

こちらのQiitaは勝手連載「ジャンプ＆ランゲームを作ろう」になります。
初回の記事はこちらです。
[【連載】ジャンプ＆ランゲームを作ろう(1) プロジェクト作成](https://qiita.com/motoyasu-yamada/items/3fcc164cae23537b5f1a)
※お断り※ 毎日お昼休みに15分程度で執筆していおり細切れになりましてすみません


# まずは
プラットフォーム（床）のブロックを自動で作成し続けます。
ブロックは移動しないがカメラが移動します。
カメラ外に外れたブロックは削除します。

# 先に結論

今回のソースコードは`Main.ts`のみいじっています。Main.tsの完成像はこちらです。
https://github.com/liberapp-inc/h5g-qiita-jump-and-run/blob/1b50e73244528bb126427ca24efb7789075acfea/src/Main.ts

# ゲームの初期化
カメラの対象となるゲーム内オブジェクトを格納するコンテナオブジェクト`world`を作成します。
まずはカメラの位置を `0`に初期化します。

```ts:Main.ts
    protected createGameScene(): void {
        this.world = new egret.DisplayObjectContainer();
        this.addChild(this.world);

        this.lastDrawnX  = - this.width / 2;  
        this.cameraX = 0; 
        this.updateCamera();
    }
```

# ゲームループのスタート

`ENTER_FRAME`イベントを処理する`enterFrame`メソッドがゲームのループ処理になります。

```ts:Main.ts
    private async runGame() {
:
        this.addEventListener(egret.Event.ENTER_FRAME, this.enterFrame, this);
    }
```

各フレームでは
1. カメラの位置を右に移動させます。
2. 次にカメラの視界の先のブロックを生成します。
4. カメラの位置にあわせてすべてのオブジェクトの表示位置を更新します。
5. カメラの視界から外れたブロックを削除します。

```ts:Main.ts
    private enterFrame(t:number):boolean {
        this.cameraX += 1; // 1
        this.generateNewBlocks(); // 2
        this.updateCamera(); // 3
        this.eraseBlocksOutOfCamera(); // 4
        return true;
    }
```

# カメラの視界の先のブロックを生成

`generationBorder`はカメラの位置からちょうど画面幅分右先の位置です。最後に作成したブロックの右端を`this.lastDrawnX`で管理しています。最後に生成したブロックの右端が`generationBorder`より左まで来た場合にブロックを生成します。

`this.colors`で生成するブロックの色のパターンを管理しています。`this.generationIndex`で次のブロックがどのパターンになるかを管理しています。

ブロックのサイズは`PLATFORM_BLOCK_WIDTH`で、ブロックの世界座標から右方向に幅`PLATFORM_BLOCK_WIDTH`、下方向に幅`PLATFORM_BLOCK_WIDTH`のブロックを生成します。

```ts:Main.ts
    private generateNewBlocks() {
        const generationBorder = this.cameraX + this.width;
        while(this.lastDrawnX  < generationBorder) {
            const p = new egret.Shape();
            p.x = this.lastDrawnX;
            p.y = 0;
            this.lastDrawnX += PLATFORM_BLOCK_WIDTH;
            
            const c = this.colors[this.generationIndex];
            p.graphics.beginFill(c);
            p.graphics.drawRect(0, 0, PLATFORM_BLOCK_WIDTH,PLATFORM_BLOCK_WIDTH);
            p.graphics.endFill();
            this.world.addChild(p);
            this.platforms.push(p);
            this.generationIndex = (this.generationIndex + 1) % 2;
        }
    }
```

# カメラ位置に応じて表示の更新

カメラ位置に連動するオブジェクトはすべて`this.world`オブジェクトの子として生成しています。そのために`this.world`の画面座標を調整するだけですべてのオブジェクトの位置が更新されます。

```ts:Main.ts
    private updateCamera(): void {
        this.world.x = this.width / 2 - this.cameraX;
        this.world.y = this.height / 2;
    }
```

# 最後に

画面の左端（カメラの位置から画面幅の半分だけ左）より左側にある非可視のオブジェクトをすべて削除します。

```ts:Main.ts
    private eraseBlocksOutOfCamera() {
        const visibilityLeft = this.cameraX - this.width / 2;
        this.platforms = this.platforms.filter((p) => {
            const r = p.x + p.width;
            const inCamera = visibilityLeft <= r;
            if (!inCamera) {
                this.world.removeChild(p);
            }
            return inCamera;
        });
    }
```
Google Apps Scriptを用いたスプレッドシート入力規則の設定を行う

## はじめに
大勢が共有して利用するシートにおいて、人的ミスは避けられない。（※繰り返し）

以前に投稿した[『Google Apps Scriptを用いたスプレッドシート保護の設定を行う』](https://qiita.com/himiyo3in/items/317a86c0c80a62d2a847)では、編集可能な人を制限することでシートの不用意な改変の防止を試みた。

本稿では、**指定範囲部分にドロップダウンリストを設定**し、**入力可能な値の制限**を行う設定をGoogle Apps Script(GAS)で記載することで、入力データの定型化を図る。


## 概要
・ プログラミングに不慣れな人でも簡単にできるよう、
　 **入力規則設定用シート（*"[入力規則]Config"*）**を作成し、このシートをベースに入力規則の設定を行う
・ <font color="DodgerBlue">**青色部分**</font> のシート範囲において、<font color="Red">**赤色部分**</font> に記載された値のみを入力可能な状態へと設定をする
　 （= ドロップダウンリストの作成）
![n入力規則.png](https://qiita-image-store.s3.amazonaws.com/0/157315/d65c937c-5045-1a7b-9095-d69e21537a4a.png)

## スクリプト
### 実行方法
```javascript:dataValidation.gs
function dataValidation(){
  addValidate('B2:B'); // "[入力規則]Config"シートから読み込む範囲を指定
  addValidate('C2:C');
}
```
### メインメソッド
```javascript:dataValidation.gs

// Configシートを読み込む
var protectconfig_sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('[入力規則]Config');


function addValidate(param_range){
  
  // Underscoreライブラリ(M3i7wmUA_5n0NSEaa6NnNqOBao7QLBR4j)の導入が必要
  var _ = Underscore.load();
  
  
  
  /* 1. configシートから、入力規則を設けるシート名・範囲情報とドロップダウンリストを読み取る */
  
  var validate_param     = protectconfig_sheet.getRange(param_range).getValues();
  
  var validate_sheetName = String(validate_param[0][0]);
  var validate_range     = String(validate_param[1][0]);
  
  var validate_sheet     = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(validate_sheetName).getRange(validate_range);
  
  
  
  /* 2. ドロップダウンリストの配列を作成 (データ範囲を転置 → データ範囲の1列目２行目以降に値が入っているものを抽出して配列化) */
  
  var valuelist = [];
  var validate_paramTrans       = _.zip.apply(_, validate_param).filter(String);
  var validate_paramList        = validate_paramTrans[0]
  
  for (var i = 2; i < validate_paramList.length; i++){
    if(validate_paramList[i] != null && validate_paramList[i] != "") {
      valuelist.push(validate_paramList[i]);
    }
  }
  
  
  
  /* 3. 指定範囲にドロップダウンリストを設定する */

  var rule = SpreadsheetApp.newDataValidation().requireValueInList(valuelist, true).build();
  validate_sheet.setDataValidation(rule);
  
}
```

### 結果
<img width="643" alt="ドロップダウンリスト.png" src="https://qiita-image-store.s3.amazonaws.com/0/157315/08d9703e-ccff-3cc7-eac9-9f6ddc2096d8.png">
<img width="643" alt="設定範囲.png" src="https://qiita-image-store.s3.amazonaws.com/0/157315/cfd8e44f-5c00-bec0-4d4e-16db46704dde.png">

やったね(^^)

### 補足
メインメソッド最終行手前の `.requireValueInList` の部分を変更することで、より複雑な設定が可能。
詳しくは[公式ドキュメント](https://developers.google.com/apps-script/reference/spreadsheet/data-validation-builder)を参照してね。


### 参考サイト
- [Google公式 : Class DataValidationBuilder](https://developers.google.com/apps-script/reference/spreadsheet/data-validation-builder)
- [エクセルの神髄 : 第31回．入力規則](https://excel-ubara.com/apps_script1/GAS031.html)
- [インストラクターのネタ帳 : ドロップダウンリストからデータ入力できるようにするGoogle Apps Scriptスクリプト](https://www.relief.jp/docs/google-spreadsheet-gas-set-data-validation-list.html)
【mac】brewからpyenv経由でpython 3.7.2を入れてみる

# 早速構築していく

```
$ python -V
Python 2.7.10
```
これがMacにもともと入っているpythonのversionです。
ここから簡単にpythonのversionが変更できるように設定する。

まず、Pythonのバージョンを管理できる「pyenv」をbrew経由でinstall！

```
$ brew install pyenv
```

すかさず、うまくいったか確認！

```
$ pyenv -v
pyenv 1.2.9
```
ちゃんと入っているようです。
pyenvでinstallできるPythonのリストを表示してみる。

```
$ pyenv install -l
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  2.4.1
  2.4.2
….
```

おもむろに2.7.15をinstall

```
$ sudo pyenv install 2.7.15
ERROR: The Python zlib extension was not compiled. Missing the zlib?
→なんかerrorが出た。。。
```
Xcodeのcomand line tool絡みのerrorっぽかったので再インストールしてみる。
https://stackoverflow.com/questions/34617452/how-to-update-xcode-from-command-line

```
1. removing the old tools ($ rm -rf /Library/Developer/CommandLineTools)
2. install xcode command line tools again ($ xcode-select --install).
```
→だめ。

pyenvのgithub issue見てると

```
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
でいけるでよ！という記事見つけたので試してみる。
https://github.com/pyenv/pyenv/issues/1219

```
mac:~ gaku$ sudo pyenv install 2.7.15
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-2.7.15.tar.xz...
-> https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tar.xz
Installing Python-2.7.15...
python-build: use readline from homebrew
Installed Python-2.7.15 to /Users/gaku/.pyenv/versions/2.7.15
```
→installできたっぽい！
pyenvでinstallした2.7.15を適用してみる。

```
$ sudo pyenv global 2.7.15
$ python -V
Python 2.7.10
```
→だめ。→適用はできているけど、もともと入っているpythonが使用されているような気がする。
いろいろ調べていると環境変数を通す必要があるようなので、以下コマンドで通していく

```
$ 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
pyenv: cannot rehash: /Users/gaku/.pyenv/shims isn't writable // rehash?わからんけどやってみる
$ sudo pyenv rehash
```
すると

```
$ python -V
Python 2.7.15
```
🎉キターーー(´・ω・｀)ーーーーー🎉

この調子で、Python3にしてみる。

```
$ sudo pyenv install 3.7.2
$ sudo pyenv global 3.7.2
$ python -V
Python 3.7.2
```
🎉Python3環境が完成しました(´・ω・｀)b🎉

# その後
sudo付きでpythonをinstallすると、のちのちで支障が出たので、以下記事を参考にsudoなしで導入できるように環境を構築しました。
[pyenvをちゃんと消してから入れ直す](https://qiita.com/yasudadesu/items/1177aa93229e7c4b7a45 "pyenvをちゃんと消してから入れ直す")

# 終わりに
mac mojaveでerrorが出るようになってるっぽいので、ちょいハマりましたがinstallできました。
ハマったらgithubのissue読め！ですね。(´・ω・｀)
JavaScriptのfilterとmapで配列の中から条件に合うものを抽出し、特定項目の配列を作成する

javascriptで配列の中から条件に合うものを抽出し、特定項目の配列を作成する処理の例です。
filterとmapを使用することで取得できます。

```javascript
// isValueがtrueのtype配列を作成したい
data = [
    {type:1,isValue:true},
    {type:2,isValue:false},
    {type:3,isValue:false},
    {type:4,isValue:true},
    {type:5,isValue:false},
    {type:6,isValue:true},
    {type:7,isValue:false},
];

// [1,4,6]の配列が作成される
data.filter(d=>d.isValue).map(d=>d.type);
```
Amazon WorkDocs ドライブアプリをインストール

# 概要

Amazon WorkDocsのドライブアプリ（デクストップクライアント）を Mac にインストールしてみます。

WorkDocs 導入と Admin 設定については、以下をご参照ください。  
  
* [Amazon WorkDocs その 1 -- 導入](https://stangler.hatenablog.com/entry/2019/02/12/124148)
* [Amazon WorkDocs その 2 -- Admin 設定](https://stangler.hatenablog.com/entry/2019/02/13/113050)


# 参考サイト
  


*  [Amazon WorkDocs ドキュメント](https://docs.aws.amazon.com/workdocs/index.html#lang/ja_jp)


# ダウンロード
  
まずは、WorkDocs にログインし、トップページのグローバルナビゲーションにある「サポート」をクリックします。次に、プルダウンメーニューにある「サポート」をクリックします。  
  
![20190128_WorkDocs_ドライブアプリ_01_サポート01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/d399fb9d-5da6-657a-2d91-649c430acd19.png)

  
サポートサイトが開くので、そのページにある「ドライブアプリ」のところにあるボタンをクリックしてアプリをダウンロードします。ここでは、Mac 版をダウンロードしますが、Windows をお使いの方は「 PC 」ボタンをクリックしてダウンロードしてください。  
  
![20190128_WorkDocs_ドライブアプリ_02_ダウンロード01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/27bcc8dc-f2ac-d595-301b-345382b28bd6.png)

  
# インストール
  
ダウンロードされた「 AmazonWorkDocsDrive.pkg 」をダブルクリック。指示に従ってインストールします。  
  
![20190128_WorkDocs_ドライブアプリ_03_インストール01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/95e602e1-99a9-6a30-4878-47afb6d7aaf1.png)

  
# アプリ起動
  
インストールが終わったら、アプリを起動しましょう。初回起動時に次のような表示が出てくるので、空欄に作成した WorkDocs の URL をインプットします。  
  
![20190128_WorkDocs_ドライブアプリ_04_アプリ起動01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/0b2c776f-c115-4294-ba9e-a23ecc9a4264.png)
 
  
認証情報を求められるので、ご自分のアカウントのユーザー名とパスワードを入力します。  
  
![20190128_WorkDocs_ドライブアプリ_05_認証01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/a20ac440-a4db-d03f-778d-bddc9f486013.png)

  
無事、認証を通過するとデスクトップ上に以下のようなアイコンができていると思います。  
  
![20190128_WorkDocs_ドライブアプリ_06_アイコン01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/54551e05-e98d-1ce9-2bd2-5f0848ff29ab.png)


# ファイルのアップロード
  
デスクトップにできたアイコンをダブルクリックすると以下のように Mac 内にできた AmazonWorkDocs 用のディレクトリが開きます。  
  
![20190128_WorkDocs_ドライブアプリ_07_ディレクトリ01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/92bbed79-3eb4-a465-c30b-ca96dec725f1.png)

  
MyDocuments ディレクトリを開いて、そこに何かファイルをドロップしてみましょう。  
  
![20190128_WorkDocs_ドライブアプリ_08_アップロード01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/8114466c-447f-b8e9-d3c7-ce682216dd42.png)

  
ブラウザで WorkDocs を確認してみます。今、ドロップしたファイルが以下のように表示されていれば、アップロードは完了です！  
  
![20190128_WorkDocs_ドライブアプリ_09_アップロード02.png](https://qiita-image-store.s3.amazonaws.com/0/344724/97a28f61-86e3-f267-661d-22b586e02f6e.png)

  

# ファイルのバージョン管理
  
先ほどアップロードした「テスト.txt 」に、Mac のドライブアプリ側で修正を加え、保存してみます。ブラウザの WorkDocs で「テスト.txt 」を開くと、きちんと修正されているのが確認できます。  
  
それと同時に、以下のようなバージョン管理がなされているのも確認できます。  
  
![20190128_WorkDocs_ドライブアプリ_10_バージョン管理01.png](https://qiita-image-store.s3.amazonaws.com/0/344724/21a476b3-c3f7-62b8-a8c1-2b33b1dbd467.png)

  
いつ、誰がドキュメントを修正したかがわかって便利です。また、各バージョンのリンクをクリックすると、その時のドキュメントを閲覧することができます。Git などでバージョン管理している雰囲気で、ファイルを管理できて、良い感じです。  
  
以上です。
SQLのLISTAGGについて

LISTAGGにお世話になったのですが、使えるようになるまで少し手間取ったのでおさらい。

LISTAGGとは、複数行を単一列に連結するための集計関数です。
構文は以下。

LISTAGG(【カラム名】, '【区切り文字】') WITHIN GROUP (ORDER BY 【カラム名】) AS 【別名】

SQL文の中では次のように使用します。

SELECT
　　LISTAGG(NAME, ',') WITHIN GROUP (ORDER BY CD) AS NAME
FROM
　　T_NAME

GROUP BYを使用したい場合は次のように。

SELECT
　　KBN
　　,LISTAGG(NAME, ',') WITHIN GROUP (ORDER BY CD) AS NAME
FROM
　　T_NAME
GROUP BY
　　KBN

GROUP BYとORDER BYをどう設定するかで引っかかって見事に詰みました。
冷静になって考えてみると単純なんですが……。
ちなみに以下は実際に使用したものに近いSQL。より実用的かも。

SELECT
　　KBN
　　,LISTAGG(NAME || '(' || CD || ')', '、') WITHIN GROUP (ORDER BY CD) AS NAME
FROM
　　T_NAME
GROUP BY
　　KBN

カラム名のところを文字連結しただけですが、わざわざLISTAGGを使う状況というと複数行の複数の値を連結したいケースが多いと思われるので参考までに。
SCPコマンド　大量のファイルの送信時に接続が切れてしまう対策

## こんな風に途中で切れてしまう場合

```                                                    
received disconnect from xxx.xxx.xx.x: 2: Packet corrupt
```

## 対策

```
[root@localhost ~]# ethtool -K eth0 tx off rx off
```
Vue.jsをi18nで多言語対応（言語別ファイル版）

## 準備

ライブラリをインストール

```bash
npm install vue-i18n
```

## 設定

```main.js
// 多言語対応
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
import { data } from '@/lib/lang/index.js'
const i18n = new VueI18n({
  locale: 'en', // デフォルト言語設定
  fallbackLocale: 'ja', // 選択中の言語に対応する文字列が存在しない場合はこの言語の文字列を使用する
  messages: data
})

new Vue({
  i18n: i18n,
})
```

## 多言語設定

src配下にlib/langフォルダがなければ作る

```src/lib/lang/index.js
import en from './TranslationsEN'
import jp from './TranslationsJP'

// jsonを結合する
var data = Object.assign(en, jp)

export { data }
```

日本語設定ファイル

```src/lib/lang/TranslationsJP.js
export default {
  ja: {
    Home: {
      title: '俺のページ'
    }
  }
}
```

英語用設定ファイル

```src/lib/lang/TranslationsEN.js
export default {
  en: {
    Home: {
      title: 'MyPage'
    }
  }
}
```

グローバル登録しているので各Vueファイルではインポートなど無しでいきなり使える

```hoge.vue
<template>
  <div>
   <div{{$t("Home.title")}}</div>
  </div>
</template>

<script>
export default {}
</script>

<style scoped>
</style>
```

英語に言語変更する場合はJavascriptで以下のようにする

```javascript
this.$i18n.locale = 'en';
```

## 終わりに

多言語設定あるとかっこいいですよね
今回は１言語で１ファイルにしてますが１画面で１ファイルというのもアリかもしれません
っていうか今思ったけどもはや自動でGoogle翻訳とかにかけてくれてリアルタイム翻訳してくれるライブラリとかあると便利なので誰か作ってくれ〜

最近はGoogle翻訳ばかり使って全然英語読んでない。。
Google翻訳便利すぎんよ〜

ではでは。

## 参考
http://kazupon.github.io/vue-i18n/installation.html#compatibility-note
Docker for Mac のアップグレード

# 概要
  
Macbook に Homebrew でインストールした Docker をアップグレードします。

![20190215_docker.png](https://qiita-image-store.s3.amazonaws.com/0/344724/25e82e0a-1c4e-026f-a396-ea876fc284c6.png)

# インストール
  
今回は、アップグレードですが、その前にインストールについて、一応、言及しておきます。といっても、以下のコマンドを実行するだけです。  
  
```
% brew cask install docker
```
  
# アップグレード
  
アップグレードも簡単です。まずは、Docker アプリが起動している場合は、終了させてください。次に以下のコマンドを実行します。  
  
```
% brew cask upgrade docker
```

# 確認
  
Docker アプリを起動し、以下のコマンドで確認します。  
  
```
% docker info
% docker version
```
  
以上です。
GASでTwitterに画像を投稿するだけ

Google Apps Scriptで画像を投稿したいのに、検索方法が悪いのか、なんなのかわからないが、全然サンプルコードが出てこない。公式リファレンスを読むのも（全ページ英語なので）面倒くさい。ということで、メモ用に投稿しておく。
<br>
まず、ご存知の通り、このAPIは非推奨（廃止？）になった。
`var url="https://api.twitter.com/1.1/statuses/update_with_media.json";`
参考：https://teratail.com/questions/98359
<br>
次に、[とりあえずこの辺](https://webird-programming.tech/archives/274)をコピペしてスクリプトを作る。（認証方法が変わっている件については[このへん](https://qiita.com/tdkn/items/521686c240b0c5bc6207)が詳しい）
※サポート関数は使う予定がなければコピペする必要なし

```javascript:Twitter.gs
//ツイートする
var option = { "status":"ツイート本文" };
var resp = Twitter.api("statuses/update",option);
```
これを実行して、文字だけのツイートをして楽しもう。

<br>
そして、問題の画像のみを投稿する方法。[この記事](https://qiita.com/pekko1215/items/43ef98d99ab186bd67a7)を参考にしながら、必要な部分だけ切り出した。

```javascript:Twitter.gs
var file_name = 'ファイル名(拡張子を忘れずに)'; 
var file_temp = DriveApp.getFilesByName(file_name).next();//GoogleDriveから画像を取得

var resp = file_temp.getBlob();
var resp_64 = Utilities.base64Encode(resp.getBytes());//Blobを経由してBase64に変換

var img_option = { 'method':"POST", 'payload':{'media_data':resp_64} };
var image_upload = JSON.parse(Twitter.oauth.service().fetch("https://upload.twitter.com/1.1/media/upload.json",img_option)); 
var sendmsg = "ツイート本文を入力"; 
var sendoption = { 'status':sendmsg, 'media_ids':image_upload['media_id_string']} ;//オプションに突っ込む

Twitter.api('statuses/update',sendoption);//送信 
```
画像ファイルは予めGoogleDriveにアップロードしておくこと。

GoogleDrive内でのファイル名の衝突とかはたぶん、[このあたり](https://qiita.com/tanaike/items/94c263d3906ee23ad522)でなんとか解決してください。
<br>以上。
Windows ServerがインストールされたGCEインスタンスをPuppet Discoveryで検出してみた

この記事は[こちら](https://qiita.com/hisashiyamaguchi/items/7eeb89c5895a8e4ccc2a)の続編です。Windows Serverも検出してみました。

# 前提条件
- **Puppet Discovery ServerのOS** : CentOS 7(3.10.0-957.1.3.el7.x86_64)
- **TargetのOS** : Windows Server 2012 R2
- **Puppet Discovery** : 1.8.0 Build: b2f5c3c
- **Targetのドメイン環境** : Work Group

# 検出
メニュー -> 認証情報の追加を選択します。
<img src="https://i.imgur.com/M2Fp4gx.png" width=50%>


WinRM認証情報を押します。
<img src="https://i.imgur.com/Bk5sKNK.png" width=50%>


名前、Administratorのユーザ名、パスワードを入力、チェックボックスを全て選択して認証情報の追加を押します。
<img src="https://i.imgur.com/T8SKqbP.png" width=50%>


検出を開始します。しばらくすると検出データがダッシュボードに表示されます。
<img src="https://i.imgur.com/5LVgPVN.png" width=50%>
キー名の大文字小文字を区別するか（.env）

キー名に小文字を使ってるところを見つけたので動作確認

### 準備

```ini:.env
abc=abc
ABC=ABC
```

### 実行

```php:tinker
>>> env('abc', 'hoge')
=> "abc"
>>> env('ABC', 'hoge')
=> "ABC"
>>> env('aBc', 'hoge')
=> "hoge"
```

結論：大文字小文字を区別する
AWS IoT / Azure / IBM WatsonにSigfox DATA ADVANCED Callbackが対応

Sigfoxクラウド8.0/8.1のリリースに伴いAWS IoT / Azure / IBM WatsonへのDATA ADVANCED Callbackが可能になりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/42fde757-5556-5789-fbcb-f8b13e2e0ebd.png)

#DATA ADVANCED Callbackとは
Sigfoxネットワークでは、1つのデバイスから送信されたメッセージを、複数のSigfox Base Station（ゲートウェイ）で受信することができるため、ネットワーク品質評価は、受信した各基地局における受信レベル（RSSI）で評価されます。詳しくは[こちら](https://qiita.com/ghibi/items/11acba7b61ad986a6559)。
DATA ADVANCED Callbackは、このネットワーク品質評価指標（Link Quality Indicator: LQI）を計算しCallbackしてくれます。
また、今後、Atlas WiFiと呼ばれるWiFi APベースの位置推定や[Atlas Bubble](https://www.sigfox.com/en/solutions/sigfox-bubble)と呼ばれるSigfoxビーコンベースの位置推定によるデバイス位置が、このDATA ADVANCED Callbackに追加される予定です。（2019年2月現在）

#DATA ADVANCED Callbackのはじめ方
Sigfox Callbackと各プラットフォームとの連携は、
AWS IoT : https://qiita.com/ghibi/items/a1c49a180b885e712841
Azure IoT Hub : https://qiita.com/ghibi/items/16f9f7a421bdd4fac1c1
IBM Watson IoT : https://qiita.com/ghibi/items/6ac04e23e9072dc07b21
を参考にしてください。
DATA ADVANCED Callbackは、上記設定において、*Type*項目を**SERVICE**-**DATA_ADVANCED**に設定してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/fd2e8a64-64a9-7dd3-3eff-64398079d614.png)
これにより、下図のように
lqi: Link Quality Indicator（ネットワーク品質評価指標）の他、computedLocation（Atlasシリーズにより算出されたデバイス位置情報）をCallback時の変数として利用することができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/09faf70e-67c1-68a0-6d59-345d26dab0ac.png)

例えば、下記のようなCallback Bodyを作成することにより

```in.json
{
  "device": "{device}",
  "time": "{time}",
  "seqNumber": {seqNumber},
  "lqi": "{lqi}",
  "computedLocation": {computedLocation}
}
```
下記のようなCallbackが各IoTプラットフォームに送信されます。

```out.json
{
  "device": "7B0DE2",
  "time": "1550556026",
  "seqNumber": 398,
  "lqi": "Excellent",
  "computedLocation": {
	"lat":35.642533388093675,
	"lng":139.7312282567643,
	"radius":11736,
	"source":2,
	"status":1
	}
}
```
なお、sourceは、位置推定で使用したSigfoxサービス、statusは、推定エンジンの結果ステータスを意味し、下記の定義となっています。

**source**
- 1 : Sigfox GPSフォーマットでペイロードに記載されたGPS位置情報
- 2 : Atlas Native（基地局測位）
- 6 : Atlas WiFi（WiFi APベースの位置測位）

**status**
- 00: No position
- 01: OK
- 02: Fallback of Atlas WIFI
- 20: Invalid payload
※Fallback of Atlas WIFIは、Altas WiFiにより位置推定結果が得られたが、Atlas Nativeの結果に対して、10㎞以上の誤差がある場合を意味します。
つまり、この場合は、Atlas WiFiサービスで使用するWiFi APロケーションDBにおいて、登録されているAPの位置情報に誤りがある可能性があります。

最後に
DATA ADVANCED Callbackは、LQIや位置情報の計算処理のため、約30秒遅れてCallbackされることをご留意ください。

[Sigfox Japan KCCS](https://qiita.com/organizations/sigfox)
pip install twilioしたときにハマったこと

以下リファレンスを参考にTwilio Python ヘルパーライブラリーをインストールしたところハマったことがあったので備忘録です。
https://jp.twilio.com/docs/libraries/python

## 環境
mac:Mojave 10.14.3
Python:2.7.10(macデフォルト)

## エラーの内容
`pip install twilio` コマンドを実行すると以下エラーが発生

```
pyopenssl 19.0.0 has requirement six>=1.5.2, but you'll have six 1.4.1 which is incompatible.
Cannot uninstall 'pyOpenSSL'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
```

上記エラーの内容は`pyopenssl 19.0.0はsixのバージョンが1.5.2以上が必要です、しかしあなたは互換性の無いsixの1.4.1バージョンを持っています。`と言われています。

## 解決方法
### 1.インストール済みのパッケージを無視してインストールさせる
以下オプションを追加して、インストール済みのパッケージを無視して再インストールさせます。

```
--ignore-installed six

// 最終的なコマンド
pip install twilio --ignore-installed six
```

### 2.python3を利用する
macデフォルトのpythonではなく、新しくpython3をインストールしてtwilioをインストールします。

python3をインストール

```
// brewはmacにインストール済みとします。
// brewをインストールしていない人は、「https://brew.sh/index_ja」よりbrewをインストールしてください。
brew install python3
```

twilioをインストール

```
pip3 install twilio
```

## そのほか
そのほかパーミッションエラーとかでインストールに失敗するときもあります。
詳細については、[公式ドキュメント](https://jp.twilio.com/docs/libraries/python#permission-denied)を参照してください。
rspecで404 NotFoundのテストが通らなかった理由

#404 NotFoundのテストが通らなかった理由

rspecのログを見ると、

```
レスポンスに404番を返す (FAILED - 1)
Failures:
  1) ProjectsController showアクションを検証する @projectが見つからない場合 レスポンスに404番を返す
     Failure/Error: @project = Project.find(params[:id])
     
     ActiveRecord::RecordNotFound:
       Couldn't find Project with 'id'=0 [WHERE "projects"."deleted_at" IS NULL]
     # ./app/controllers/projects_controller.rb:38:in `set_project'
     # ./spec/controllers/project_spec.rb:42:in `block (4 levels) in <top (required)>'
Finished in 0.03384 seconds (files took 1.06 seconds to load)
3 examples, 1 failure
```
となっており、

```
ActiveRecord::RecordNotFound
```
というエラーを出されている。

そのため、テストをActiveRecord::RecordNotFoundを返すように書かないといけなかった。

現在は、

```
expect(response.status).to eq 404
```

という、**HTTPステータス**を返すように書いてしまっていた。

そのため、下記のようにActiveRecord::RecordNotFoundを返すように修正すると、テストが通りました。

```
context '@projectが見つからない場合' do
  it 'レスポンスに404番を返す' do
    expect {
      get :show, params: { id: 0 }
    }.to raise_error(ActiveRecord::RecordNotFound)
  end
end
```

```
ProjectsController
  showアクションを検証する
    @projectが存在する場合
      レスポンスに200番を返す
      値をjsonで返す
    @projectが見つからない場合
      レスポンスに404番を返す

Finished in 0.04004 seconds (files took 1.23 seconds to load)
3 examples, 0 failures
```

showアクションで、存在しないidにアクセスする＝get :show, params: { id: 0 }

エラーを出す＝raise_error(ActiveRecord::RecordNotFound)

※ActiveRecordに値を渡す時は、{ }ブロックで渡すこと。
雑なシェルスクリプト一覧( 増えていくと思います。。。)

## よく使うやつ

* ファイル確認
```
$ls 
```
* ファイルに移動
```
$cd [directory名]
```
* ディレクトリ作成
```
$mkdir [directory名]
```
* 過去のコマンド確認
```
$history
```
* ssh接続
```
$ssh name@ipアドレス
```
* 現在の場所確認（Rでいう、getwd()）
```
$pwd
```
* ファイルの中身確認
```
$cat [ファイル名]
```
* ファイルの行数確認
```
$wc ファイル名
```
* ファイルをローカルにコピー
```
$ scp アップロードするファイル名 サーバのユーザID@サーバのドメイン:アップロード先のディレクトリ
```
* mysqlを使う（mysqlが起動している前提）
```
$mysql -u [mysqlのUserName] -p 
```この後にパスワード求められる。

#tmux
* ちょっと曖昧なとこもあるので、わからなかったら詳しい人に聞いてください。


* tmuxを使う```$tmux```

* 現在動いてるtmux（この表現が正しいのか。。。）を確認```$tmux ls```

* tmuxに入る```$tmux a -t 数字
```

動かしているtmuxを完全に消したいときは、control+D
そのまま残したいときは、control+BのあとにD

違ってたら、ご指摘お願いいたします。
QuantXを使ってみた

##こんにちは。
先週からSmartTradeでインターンをし始め、都の西北にある大学教養学部4年のリィァンです。Pythonはクラスまで学んで、金融に関しては基本な会計知識を知っている程度です。


##QuantXとの初対面
最初QuantXのプロジェクトテンプレートを開いて、見たことがない変数や関数を見かけた時、すごく慌ててました。だけど、この「[アルゴリズム開発入門](https://determined-feynman-fb5a05.netlify.com/ja/#overview)」を読んだら、コードの構成がすぐ分かりました。

##SMAとMACDを実装
今回は移動平均線とMACDの組み合わせを実装してみました。結果は以下の通りになります。
![Qiita_01.png](https://qiita-image-store.s3.amazonaws.com/0/363919/415c6187-a064-6d02-d4c2-3e61b99ec2fe.png)

##感想
QuantXでは全ポートフォリオの収益変化だけではなく、各株の取引状況も見えて、本当に便利だと思います。

そして、SmartTradeは週二回(水、金)勉強会を行い、アルゴリズムや株に関して簡単なプレゼン発表します。Pythonで株に関するアルゴリズムを書くことに興味を持っている方、是非参加してください。
-　水曜日18:00~ は開発者向けもくもく会
-　金曜日19:00~ は初心者向けワークショップの形式で
(勉強会ウェブサイト)
https://python-algo.connpass.com/
【iOS】目的地の距離と方向を確認できるARアプリ作ってみた

# 作ったもの

<img width="375" alt="IMG_2180.png" src="https://qiita-image-store.s3.amazonaws.com/0/263659/97b36604-8ab3-9982-b19c-9a3c5a7c6b13.png">

・[どこだっけAR](https://itunes.apple.com/us/app/%E3%81%A9%E3%81%93%E3%81%A0%E3%81%A3%E3%81%91ar/id1452169628?mt=8&ign-mpt=uo%3D4)

表題の通り、ARで目的地の距離と方向を確認できるアプリです。フローとしては

1. AR表示する目的地のアイコン画像を選択する
2. 地図上で目的地の位置情報を設定する
3. AR画面で表示する

とこんな感じです。

# 1. AR表示する目的地のアイコン画像を選択する

<img width="375" alt="IMG_2200.png" src="https://qiita-image-store.s3.amazonaws.com/0/263659/e6d40226-c16e-3d99-d02a-6015b3511fd6.png">

アイコンの選択、追加、削除ができます。アイコンはRealmで管理しています。
RealmのNotificationTokenを使うと、Viewの更新が下記のような感じにスッキリかけていいですね。

```swift:SelectARIconViewController.rb
    self.iconNotiToken = self.viewModel.icons.observe { [weak self] (changes: RealmCollectionChange) in
        guard let collectionView: UICollectionView = self?.collectionView else { return }
        switch changes {
        case .initial:
            break
        case .update(_, let deletions, let insertions, let modifications):
            collectionView.performBatchUpdates({
                collectionView.insertItems(at: insertions.map({ IndexPath(item: $0, section: 0) }))
                collectionView.deleteItems(at: deletions.map({ IndexPath(item: $0, section: 0) }))
                collectionView.reloadItems(at: modifications.map({ IndexPath(item: $0, section: 0) }))
            }, completion: { [weak self] _ in
                self?.setNoLabelHidden()
            })
            
        case .error(let error):
            fatalError("\(error)")
        }
    }
```

# 2. 地図上で目的地の位置情報を設定する

<img width="375" alt="IMG_2202.png" src="https://qiita-image-store.s3.amazonaws.com/0/263659/b07a37ee-0193-f053-e074-d717ea0e1ba2.png">

MapKitでユーザーの現在地と、設定したい目的地の位置情報を表示しています。
工夫した点ですが、ユーザーのアイコンを表示するには、MKMapViewのuserTrackingModeをfollowに設定すれば可能ですが、ユーザーの向きまでは表示してくれないです。followWithHeadingを指定すると向きが表示されますが、マップを移動したりするとすぐに向きの表示が消えてしまいます。(iOS標準のマップアプリでも同じような挙動でした。仕様?)
目的地の位置を設定する際にはユーザーの向きも表示した方がUX的にもいいと思ったので、MKAnnotationViewに向きの画像を設定して、方位角が変更されるたびにMKAnnotationViewのtransformのrotateを変更して実現しました。方位角の取得には[INTULocationManager](https://github.com/intuit/LocationManager)というライブラリを使用しています。

```swift
    self.headingRequestId = INTULocationManager.sharedInstance().subscribeToHeadingUpdates { [weak self] (heading, status) in
        guard let weakSelf = self else { return }
        if status != .success && heading == nil {
            return
        }
        let transform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(heading!.magneticHeading.radian))
        weakSelf.userLocationView.transform = transform
    }
```

# 3. AR画面で表示する
ARの表示はARKitを使用しました。目的地への距離と角度からAR空間に変換して表示しています。
座標計算に関しては記事が大変参考になりました。
https://qiita.com/k-boy/items/775633fe3fd6da9c5fb6


#使用したツール
・Xcode10.1
・GitHub
・SourceTree
・Prepo
・Screenshot Designner
などなど

# 終わりに
よかったら使ってみてください!
感想・批評なんでもどうぞ！
Goの埋め込みstructはキャストできない

```go
package main

import "fmt"

type Hoge struct {
	m string
}

type Fuga struct {
	Hoge
}

func main() {
	h := Hoge{"hogehoge"}
	f := Fuga{Hoge: h}

	fmt.Println(f)
}
```

実行結果

```
{{hogehoge}}
```

FugaはHoge->mを直下のメンバーのように呼び出せるけど実際は入れ子の状態で格納されている

```go
fmt.Println(f.m) // out: "hogehoge"
fmt.Println(f.Hoge.m) // out: "hogehoge"
```

よって構造違うのでキャストもできない

```go
f := Fuga(h) // compile error
```

最近知った。以上。
C++ Builder XE4 > TeeChart > タイトルフォントサイズを変更後もグラフ描画領域を同じにする実装

```txt:動作環境
C++ Builder XE4
```

### 概要

- グラフのタイトルフォントサイズを増やす
    - グラフ描画領域がずれる
- グラフ描画領域のずれを計算し、常に同じ位置になるように補正する

### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

static const int kTop_chartRect = 100; // この値を使って、グラフ描画領域を固定化する

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// グラフ描画用にダミーのデータを追加する
	//
	Chart1->Series[0]->XValues->DateTime = true;
	Chart1->BottomAxis->DateTimeFormat = L"nn:ss";
	//
	TDateTime dt;
	//
	dt = Now();
	//
	double yval;
	for (int idx=0; idx < 10; idx++) {
		yval = (1+ idx) % 2;
		Series1->AddXY(dt, yval, "", clRed);
		dt = IncSecond(dt, 1);
	}

	// フォントを拡大した時に上方向につまらないようにTop座標を変更
	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, kTop_chartRect, 500, 300);

	// 位置の確認用
	Shape2->Top = kTop_chartRect;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::updateGraphView(TChart *chrPtr)
{
	if (chrPtr == NULL) {
		return;
	}

	// グラフ描画の更新を促すため
	int pre = chrPtr->Title->Font->Size;
	chrPtr->Title->Font->Size = pre + 1;
	chrPtr->Title->Font->Size = pre;

	// *** 注意: これがないとChartRect.Topの読取り値がおかしくなる場合がある ***
	Application->ProcessMessages();
	Sleep(100); // msec
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int fontSize = (Chart1->Title->Font->Size + 2);
	Chart1->Title->Font->Size = fontSize;
	updateGraphView(Chart1);

	// Fontが増えたことによるTop位置のずれを補正する
	int atop = kTop_chartRect - (Chart1->Title->Height + 5); // 5: 描画を参考に決めた
	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, atop, 500, 300);
	updateGraphView(Chart1);
}
//---------------------------------------------------------------------------

```

### 実行例

ソフト起動直後
![2019-02-19_14h19_01.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5792d445-8359-68fa-9733-852388aefb2b.png)

Button1押下後
![2019-02-19_14h19_05.png](https://qiita-image-store.s3.amazonaws.com/0/32870/eab3233f-d038-2b77-34fc-e5ec1be41457.png)

さらにButton1押下後 (二回)
![2019-02-19_14h19_10.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7e512a57-4cf5-b27c-7331-d841e98c852b.png)

さらにButton1押下後 (二回)
![2019-02-19_14h19_17.png](https://qiita-image-store.s3.amazonaws.com/0/32870/24c8e93c-f275-07fb-565a-a8bd58621a1f.png)

コンストラクタでセットしたShape2(四角)の上端と、グラフ描画領域が常に同じになるようになった。

### 備考

ソフト起動直後はChart1->Title->Heightが1になってしまう(15でなく）ため、位置調整の処理はしていない。

TeeChartの機能により、もっと簡単にこの実装ができればいいが、そのような機能は見つかっていない。
jqueryのDatepickerのイベント終了時にajaxでDBを更新したい


## 実現したいこと
 - クリック時に.datePickerを表示
 - 入力欄に不要な文字は入力出来ないようにする
 - 日付を選択 or 入力欄をクリア(=deleteキー押下)したタイミングでajax処理が走る
 - ajax先でDBのカラムを更新する

## datePickerのイベント監視箇所について
 - 日付選択時
 - 入力欄でdeleteキーが押された時
 
## 実装

```javascript

$(document).ready(function(){
    $('.input-text').keypress( function() {
        // 半角入力させない
        return false
    }).datepicker({
        "dateFormat": 'yy-mm-dd',
        onSelect: function(dateText) {
            // 日付選択時/deleteキーが押されて._clearDate()が走った時 実行
            save($(this), dateText); //-> 実行したい処理
        }
    }).keyup(function(e) {
        // deleteキーが押された場合に実行
        if(e.keyCode === 8) {
            $.datepicker._clearDate(this);
        }
    });
});

//**
//  ajax処理(→対象のControllerのメソッドでカラム更新)
//**
function save(elm, value){
    let url = location.pathname + "/" + $(elm).attr("data-cid");
    let key = $(elm).attr("data-key");
    $.ajax({
        url: url,
        type: "PATCH",
        data: {
            key : key,                   // モデルの対象カラム名
            value : value,               // 設定したい値
            id: $(elm).attr("data-cid"), // 対象モデルを検索するためのid
            ajax: 'true'
        },
        dataType: "html",
        success: function(data) {
            console.log("success");
        },
        error: function(data) {
            console.log("error");
        }
    });
}

```

## 最後に
.blur()も試したが、それだと何も値変更しなくても、マウス外しただけで走るのでイベント頻度が多すぎたので不採用。

この処理の欠点は、deleteキー１回押すと入力欄全てがクリアになること。

結局のところ、クリアボタン配置するとか、[bootstrapの方](https://bootstrap-datepicker.readthedocs.io/en/latest/)使えばいいやんってなりました。
VS Code 備忘録

#はじめに
VS Codeの設定を忘れないようにメモっておくための記事。
気が向いたときに追記する。

#環境
バージョン: 1.32.0-insider (user setup)
コミット: aeaef41d51201e555735f5e8d2f38a9d0ddb9026
日付: 2019-02-20T06:17:32.389Z
Electron: 3.1.3
Chrome: 66.0.3359.181
Node.js: 10.2.0
V8: 6.6.346.32
OS: Windows_NT x64 10.0.17134

##settings.json
Windows：%APPDATA%\Code\User

##Font Family
会社でのコーディングはインデントでお尻を揃えることを推奨されるので、`'ＭＳ ゴシック'`を設定

ホントは、源ノ角ゴシックCode(Source Han Code JP)が使いたかったけど、
以下の記事によると

[コーディングに最適な日本語対応の等幅フォントSource Han Code JPとは](https://ics.media/entry/7010/2)
>半角2文字に対して全角1文字が一般的なので、Source Han Code JPの半角3文字に対して全角2文字というのは新しい取り組みと言えるでしょう。この点はコードの末尾を揃える嗜好のあるプログラマにとっては好き嫌いが分かれると思います。

ということで、MSゴシックのようにお尻が揃わないので会社では使用できない :(


##Editor: Line Height
標準の行間だと隙間が気になるので狭める
MSゴシックの時は14ぐらいが良い

##Editor: Mouse Wheel Zoom
チェックを入れるとマウスホイールでフォントサイズを変えられる

##言語ごとの設定
Ctrl+Shift+Pでコマンドパレットを開き、
`Preferences: Configure language specific settings`
を選択し、設定したい言語をを選ぶ。
言語に設定したい内容を{}の間に記載する。
settings.jsonに追加。

```c
"[c]": {
  "editor.fontFamily": "'ＭＳ ゴシック'",
  "files.encoding": "shiftjis",
  "editor.lineHeight": 15,
  "editor.tabSize": 4,
},
```

##ヘッダファイル用の設定
デフォルトではヘッダファイルは言語に紐ついていないので、紐つける。
settings.jsonに追加。

```c
"files.associations": {
  "*.h": "c"
},
```

##Grep結果からフォルダを除外
ローカルヒストリーはGrep結果に出てほしくないのでフォルダ除外を追加する。
settings.jsonに追加。

```c
"search.exclude": {
    "**/tmp/cache": true,
    "**/.history": true
},
```
XAMPP 7.3.1でローカルホストに接続できないと思ったら..

PHP7の環境を整えたく XAMPP 5.6.31 から　XAMPP 7.3.1　に変更したところ
それまで出来ていたLocalhostへの接続が出来なくなってしまいました。

なお、ブラウザ(chrome)に stackman_launcher の　General　に表示されている IP Address を打ち込めば 
/dashboard/ は表示されるが、phpmyadmin は”アクセス禁止”と表示されてしまいます。

Network で　「localhost:8080 -> 80(Over SSH)」をEnableをクリックして有効にもしているのですが...

なんで...？


まずは、ターミナルからdigコマンドでローカルホストのIPを確認してみます。

```
dig localhost +short
```
すると、127.0.0.1 と表示　General　に表示されている IP Address　とは一致しません
これは一体？ 調べても私の状態と一致する記事が出てこない...。


ふと、改めてインストールしたXAMPPのダウンロードファイルを確認すると、、。
xampp-osx-7.3.1-0-vm.dmg　となっていました。

vm !? 
あ- virtual machine（仮想マシン)版だったのですね。。 

その後すぐに[apachefriends](https://www.apachefriends.org/download.html#download-apple)から
xampp-osx-7.3.1-0-installer.dmgをダウンロードしてインストールしてすんなり解決いたしました。

XAMPPは使用していましたが、VM版を使ったことがなかったのでちょっと躓いた話でした。
LaravelでMailHogを使ってメール受信テストをかんたんにする

[MailHog](https://github.com/mailhog/MailHog)は開発者向けの電子メールテストツールです。これをいれておけば、リアルにメールサーバーを使うことなく受信テストができます。また、どの宛先に送ってもMailHogに届くので間違って送ってはいけないアドレスに送ってしまった・・・なんてことも防げます。
<img width="975" alt="スクリーンショット 2019-02-19 14.08.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/72150/9a22d955-10b1-6d2d-243a-e3099f3f87f8.png">

## Macの場合のインストール方法
ターミナルで
`brew install mailhog`
でインストール。

常に起動しておくには
`brew services start mailhog`

そして、ブラウザで
`http://localhost:8025/`
を開くとMailHogの画面がでてきます。

## Laravel側の設定方法
.envのメールの設定をこのようにするだけ。

```
MAIL_DRIVER=smtp
MAIL_HOST=0.0.0.0
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
```

以上！かんたん。

## 最後に
個人が月額制でスキルを教えたり、教えてもらったりできる[MENTA](https://menta.work/)というサービスをつくってます。プログラミングを教えられるメンターさん、教えてほしい初学者さん、ぜひご利用ください！
E212: Can't open file for writing　CentOS7

sudoを忘れて保存できない。

そんなときは、

```
:w !sudo tee % > /dev/null
```

を実行すると強制的に保存することができる。


エラーの一例としてはこんな感じで表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/87be450b-534e-2b0f-b80e-a00bec0a45fc.png)
isset,is_null,empty　どれがわかりやすい？

配列
それはPHPでは多くの箇所で使われると思います

```php:index.php
$data = [null,"",'',1,"1",'1'];

foreach ($data as $value) {
    if (isset($value)) {
        // true
    } else {
        // false     
    }
    if (is_null($value)) {
        // true
    } else {
        // false      
    }
    if (empty($value)) {
        // true
    } else {
        // false      
    }
}
```

結果

| 値       |型|       isset |is_null|    empty    |
|:-----------------|-----------------:|------------------:|------------------:|------------------:|
|null|null|false|true|true|
|“”|string|true|false|true|
|‘’|string|true|false|true|
|1|int|true|false|false|
|"1"|string|true|false|false|
|'1'|string|true|false|false|
u-bootのnetconsole

シリアルが出てないモジュールでu-bootを使う場合はnetconsoleという機能が便利です。

u-bootのビルド設定に以下を追加します。

```
#define CONFIG_NETCONSOLE       /* include NetConsole support   */
#define CONFIG_NET_MULTI        /* required for netconsole      */
#define CONFIG_PREBOOT          "setenv stdout nc;setenv stdin nc"
```

CONFIG_IPADDRとCONFIG_SERVERIPも自分が使っているネットワークの設定にしてください。

これでビルドしたバイナリーをOpenOCDなどで焼くとnetconsoleで起動します。netconsoleはUDPのポート6666で通信をおこないます。

KS8695で試してみました。tools/ncb.cというコマンドも用意されていますがncコマンドだけでも使えました。

```
% nc -l -u 6666
```

ターゲットの電源を入れて"Hit any key to stop autoboot"が表示されたら（少し時間がかかります）リターンキーを何度か入力します。

これで止める事が出来ますが、止まらない時は何度か試してみてください。

mruby on Yet Another Bare Metalでも同じポートにメッセージを送るようにスクリプトを書いてみました。

```ruby
def fib n
  return n if n < 2
  fib(n-2) + fib(n-1)
end

begin

yabm = YABM.new

addr = "10.10.10.202"
mask = "255.255.255.0"
gw = "10.10.10.3"
dns = "10.10.10.3"

yabm.netstart(addr, mask, gw, dns)

dist = "10.10.10.3"

yabm.udpinit

while 1 do
   yabm.print "."
   yabm.udpsend(dist, 6666, ".", 1)
   start = yabm.count() 
   fib(32)
   time = (yabm.count() - start) / 1000
   res = "fib(32): " + time.to_s + "sec¥n"
   yabm.udpsend(dist, 6666, res, res.length)
end

rescue => e
  yabm.udpsend(dist, 6666, e.to_s, e.to_s.length)
end
```

これをflashに焼いて実行すると以下のようにncに表示されます。

```
.fib(32): 37sec
```

ubootの起動出力を受けた場合、一度止めてもう一度ncを起動する必要があるようです。
DBViewerをEclipse2018-12以降でも使用したい！！

備忘録として投稿しておくー。

```
追記1 ：pleiades-2021-09 でも同様の方法でDBViewer使えてます。

追記2 ：BIN$～なテーブル名も出てきて「なんじゃこりゃ？」って思ってたんですが、
　　　　DROPされてゴミ箱にあるテーブルなんですね。

追記3 ：DBViewerでPostgreSQLのテーブル開いたらコネクション掴んだままロック状態
　　　　になってJUnitが動かなくなった。
　　　　どうやら、DBViewerの接続設定で「自動コミットモードをオフ」にしていると、
　　　　タブ等を閉じてもcommitもrollbackもされないまま掴みっぱなしになるらしい。
　　　　自動コミットモードをオンにしたら変わるかな？と思ったけど回避できなかった。
　　　　SQL 実行・ビューの「ロールバック」を実施したら解除されるみたい。都度は面倒だね。。。
　　　　いちいち面倒な人はPostgreSQLやMySQLの人は専用のビューワーを使った方がいいと思います。
```
※ 追記2 情報元：[Shift the Oracle / テーブル削除と削除の取り消し](https://www.shift-the-oracle.com/sql/drop-table-flashback-table.html)
※ 追記3 情報元：[DBViewerのmetadata lockの罠](https://www.bunkei-programmer.net/entry/20110602/p1)

- - -

[Pleiades](http://mergedoc.osdn.jp/)で新しいバージョン **Eclipse 2018-12** が公開されていたので、早速ダウンロードして解凍。

やっとわかりました。
いつも業務でDBViewerを使用しているのだが、Eclipseのバージョンアップするとそのままでは使えないため、こちらもマーケットプレイスからインストールし直し。。。

えっ！なんで！？
マーケットプレイスで検索しても**DBViewer**が表示されない！！
![MarketPlace.png](https://qiita-image-store.s3.amazonaws.com/0/293828/728ce406-a656-c083-2882-45a2a0cb5be3.png)

リンクで表示されたところからソリューションページを表示
・・・え、、あるじゃんょ。
![MarketPlace2.png](https://qiita-image-store.s3.amazonaws.com/0/293828/bcb9bfb4-e6d1-0a74-cb37-609be9f16a58.png)

じゃー、どうして表示されないんだろう。。。

試しにソリューションページの`Install`ボタンをクリック。
でも、ボタン押しても、eclipseのマーケットプレイスダイアログが表示されるだけで、
結果変わらなかった。

仕方なく他の方法がないか調べたら、、、あった！これだ。

参考サイト：[eclipseにERMasterを入れる際はjar経由がよさそう](http://tonaise.hatenablog.jp/entry/2017/05/17/125117)


"**jar経由**" にピンときた！
初期の頃はeclipseにプラグインを追加する際に、自分でダウンロードして
eclipse配下の`plugins`と`features`に配置していたんだった。

[[DBViewer Plugin for Eclipse 開発プロジェクト](https://ja.osdn.net/projects/dbviewer/releases/)] でjarファイルを公開しているので、
jarをダウンロードし、`plugins`に配置。

`eclipse.exe -clean.cmd`を実行し、クリーンアップしてeclipseを起動。

無事、DBViewerが使用できた♪(∩´∀｀)∩ﾜｰｲ

同じところで躓いてる人の役に立てたらいいなぁ(o^皿^o)
[tvOS] UITableViewのグラデーションマスクを削除する

備忘録

tvOSでは`UITableView`を使うと、上下のスクロール領域が下記イメージのようにマスク処理されています。

<img src="https://qiita-image-store.s3.amazonaws.com/0/16417/3fc8031b-c7d6-03be-652f-e96bdd996035.png" width="960">

これは、tvOSのUITableViewにはmaskプロパティに`CAGradientLayer`を含んだviewが設定されているためです。

・iOS

```
print(tableView.mask)

nil
```

・tvOS

```
print(tableView.mask)

<_UIScrollViewGradientMaskView: 0x7fcf41109930; frame = (-90 -40; 1920 1080); userInteractionEnabled = NO; layer = <CAGradientLayer: 0x6000032a6ee0>>
```

なので、不要の場合は

```
let tableView = UITableView()
tableView.mask = nil
```

でOK。

<img src="https://qiita-image-store.s3.amazonaws.com/0/16417/09092096-1b2a-7675-9a4e-ccf86aa1f858.png" width="960">

### 参考

[mask \- UIView \| Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiview/1622557-mask)
Sass+globパターンの環境構築とコンパイルの覚書

これやっといてーと修正投げられたあるウェブサイトのスタイルはSassで書かれていました。基本Javaとかでサーバーサイドの私ですが、せっかくなのでSassの環境構築とコンパイル方法を学びました。この記事はその覚書で、Sassの詳細な利用方法や記法などは記載していません。

## 環境
- Node.js v9.4.0
- MacBook Air (13-inch, Mid 2012)
- macOS Sierra 10.12.6

## Sassとglob
普通にコンパイルするとエラーになるので調べると、`@import 'layout/**/*.scss';`のようにglobパターンで複数のscssファイルがインポートがされていたためでした。Sassのデフォルトではサポートされていないようで、glob用のプラグインを利用する必要があるとのこと。

globについてはこちらで教えていただきました。
https://qiita.com/tonkotsuboy_com/items/67d9fd4d054a45af9f34

メインのscssはこのような内容

```scss:style.scss
@charset 'utf-8';

// Utils
//-----------------------------------------------------------
@import 'utils/var';
@import 'utils/fonts';
@import 'utils/mixin';

// Base
//-----------------------------------------------------------
@import 'base/reset';
@import 'base/default';

// Layout
//-----------------------------------------------------------
@import 'layout/**/*.scss';

// Page style
//-----------------------------------------------------------
@import 'pages/**/*.scss';
```

## 環境構築
以上を踏まえて、参考記事にもあるNode.jsの「[node-sass-globbing](https://www.npmjs.com/package/node-sass-globbing)」というプラグインでglobパターンが使えるように、そしてコンパイラは必須の「[node-sass](https://www.npmjs.com/package/node-sass)」を利用します。

npmの初期設定

```bash
npm init -y
```

node-sassとnode-sass-globbingのインストール

```bash
npm install node-sass --save
npm install node-sass-globbing --save
```

## コンパイル
作成されたpackage.jsonにコンパイルするためのscriptを追加します。（少し省略）
参考記事のコメントに書かれている通り、`--importer`オプションでnode_modules/node-sass-globbing/index.jsを指定するのがミソ。

```json:package.json
{
  "name": "scss",
  "version": "1.0.0",
  "scripts": {
    "build": "node-sass --importer node_modules/node-sass-globbing/index.js -o dist style.scss"
  },
  "dependencies": {
    "node-sass": "^4.11.0",
    "node-sass-globbing": "0.0.23"
  }
}
```

コンパイル実行

```bash
npm run build
```

コンパイルに成功すると「dist」というディレクトリにcssが作成されます。
あとは、node-sassのオプションで
圧縮したり`--output-style compressed`、
ソースマップを作成したり`--source-map true`。

## 最後に
node-sassは結構高速な印象でした。Sass素敵。