OmniAICreator/Qiita-1.07M huggingface dataset:
micro:bit runtime開発環境をつくる

# 環境

- Windows10


# 概要

Windows10上にC++を使ってmicro:bitの実行ライブラリ [micro:bit runtime](https://lancaster-university.github.io/microbit-docs/) を直接利用するプログラムの開発環境を構築する。


# 手順

micro:bit runtimeインストール方法は [Offline Development \- micro:bit runtime](https://lancaster-university.github.io/microbit-docs/offline-toolchains/#installation-on-windows) に従う。

[Mbed](https://www.mbed.com/en/)  のビルドシステム [yotta](https://yottabuild.org/) と、EPROM 用ファイルをつくるための [SRecord](http://srecord.sourceforge.net/) を入れることになる。

## Pythonを入れる

yottaはPython2.7.9以降を要求している。
未確認だがPython3.7でも問題は無いようだ。
インストーラーで入れてCコンパイラも入れたが、Cコンパイラの必要性は不明。

参照: [Python 2\.7のインストール \- python\.jp](https://www.python.jp/install/windows/install_py2.7.html)

## CMake を入れる

インストーラーで導入。

[Download \| CMake](https://cmake.org/download/)


## Ninja を入れる

yottaで利用しているビルドシステム。
Zipファイルを適当なディレクトリに解凍して、パスを通す。

[Ninja, a small build system with a focus on speed](https://ninja-build.org/)

## arm-none-eabi-gcc を入れる

マイコンのコードをクロスコンパイルするための道具一式。
yottaのドキュメントでは [4.9](https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q2-update/+download/gcc-arm-none-eabi-4_9-2015q2-20150609-win32.exe) を使っていると書いてある。未検証だがそれ以降でも可能かもしれない。
[GNU Arm Embedded Toolchain in Launchpad](https://launchpad.net/gcc-arm-embedded)
[GNU Toolchain \| GNU\-RM Downloads – Arm Developer](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)

## yotta を入れる

Windows10 Python2.7の環境で、2019年10月8日の最新リリース yotta v0.19.0 は `error:'Version' object has no attribute 'truncate'` が出て動かなかった。
以下の修正コミットを指定して入れたら動いた。

[\`yotta target\` fails with \`error: 'RegistryThingVersion' object has no attribute 'truncate'\` · Issue \#856 · ARMmbed/yotta](https://github.com/ARMmbed/yotta/issues/856)

```shell
pip install git+git://github.com/ARMmbed/yotta.git@047cff288c3f7fe520c391fc61805ea3c8dafebc
```


## SRecord を入れる

SRecord の Windows 版をダウンロードする。
[SRecord \- Browse /srecord\-win32 at SourceForge\.net](https://sourceforge.net/projects/srecord/files/srecord-win32/)
Zipファイルを適当なディレクトリに解凍して、パスを通す。


# 使い方

[Offline Development \- micro:bit runtime](https://lancaster-university.github.io/microbit-docs/offline-toolchains/#installation-on-windows) を参照。

## プロジェクトをダウンロードする

```shell
git clone https://github.com/lancaster-university/microbit-samples
cd microbit-samples
```

## yottaのターゲットを設定する

```shell
yt target bbc-microbit-classic-gcc
```

## プロジェクトをビルドする

```
yt build
```

## micro:bitへ書き込む

```shell
cp ./build/bbc-microbit-classic-gcc/source/microbit-samples-combined.hex /Volumes/"MICROBIT"
```

# 資料

## [micro:bit runtime](https://lancaster-university.github.io/microbit-docs/#)

micro:bit runtimeの公式ドキュメントであり、アーキテクチャやAPIの説明が書いてある。


## [BBC micro:bit C\+\+ Getting Started](https://www.forward.com.au/pfod/microbit/gettingStarted.html)

micro:bit rumtimeを使った開発の手順やスレッドやイベント、メモリなどを解説している。
ジョブカンの技術スタックを調べる

最近不調が目立つジョブカンでどんな技術が採用されているか調べてみました。

## 調査方法

もっとも頻繁にアクセスするモバイル版のログイン後ページを中心に[URL(ドメイン)から情報を調べるウェブサービス)](https://qiita.com/studio15/items/3c54937d0a3c643e84ea)などで調査

## 結果

| 対象 | 採用技術/結果 | 所感 |
|---|---|---|
| HTML | XHTML 1.0 Transitional | CSS,JSが含まれておりメンテナンス大変そう |
| Validity | 11 validation errors |  |
| CSS | Plain CSS | CSSリセットもオリジナル？ |
| JS | jQuery 1.9.0 | 2013-01-04リリース |
| フロントエンドフレームワーク | PC版では一部Bootstrap | バージョンは不明 |
| ウェブサーバー | Apache |  |
| CDN | なし |  |
| DNS | AWS Route53 |  |
| ウェブサーバー | AWS EC2 |  |
| Chrome Audit | Performance 90 |  |
AWSのRedashのAMIを使ったときのGroupの権限を細かく設定する方法

AWSのRedashのAMIを使ってRedashを使ってみたが
RedashのWeb管理画面のGroupの権限設定は、Full AccessかView Onlyしか選べない。

View OnlyなGroupに所属するユーザにもクエリーを実行してもらいたがったが
View Only権限だとクエリーの実行ができない。

コマンドではもっと細かく権限を付与できるみたいなので、実行してみた。
AWSのRedashのAMIを使うと、諸々のコンポーネントがDockerComposeで起動するので、それを利用してコマンド実行を行う。

```bash
$ cd /opt/redash

# Group IDを調べて記載する
$ GROUP_ID=3

# 権限変更
# この権限だと、クエリーの実行や閲覧のみでき、クエリーの作成はできない
$ sudo docker-compose run --rm server manage groups change_permissions --permissions view_query,view_source,execute_query,list_users,schedule_query,list_dashboards,list_alerts,list_data_sources ${GROUP_ID}
```
SeleniumWebDriverとPythonで自動化したテストのレポートをAllureで出力するところまで

## Allure Frameworkとは

公式サイトより引用

> Allure Framework is a flexible lightweight multi-language test report tool that not only shows a very concise representation of what have been tested in a neat web report form, but allows everyone participating in the development process to extract maximum of useful information from everyday execution of tests.

- 複数言語対応のテストレポートツール
- Webブラウザで見られるレポートを出力
- 何をテストしたのかが完結でわかりやすい

などの特徴があります。

単体テストフレームワークを使ってテスト自動化を行うと、レポートはだいぶ簡素なものになりがちです。開発者個人でテストをやって結果を確認する分にはそれでもいいのですが、テストチームやQAチーム内で確認をしたり、マネージャに報告するのに使ったりする分には物足りないことも。

そんなときには、Allureなどの何らかのレポートツールを使うのがよいでしょう。

今回は既存の、自動テストスクリプトの実行結果をAllureのレポートとして表示できる、というところまでの手順です。

## 環境構築

### 前提

- Python, pytest, SeleniumWebDriverで自動テストを書いて実行できる状態であること

### Allureのインストール

[2.1. Installing a commandline | Allure Framework](https://docs.qameta.io/allure/#_installing_a_commandline)

を参考に。

今回はWindowsでやろうと思うので、Scoopというコマンドラインインストーラを使います。

``` Cmd
scoop install allure
```

### allure-pytestのインストール

今回はpytestを使うので、pytest向けの手順で行きます。

Behaveの場合とNoseの場合も、公式に書いてあるので参考にしてください。

[6. Python | Allure Framework](https://docs.qameta.io/allure/#_python)

手順は簡単で、pip でインストールすればOKです。

``` Bash
$ pip install allure-pytest
```

### 動作確認

ここまでの環境構築が出来たら、Allureのレポートが出力されるかどうか見てみましょう。

動作確認用に、[6.1.3. Basic Reporting | Allure Framework](https://docs.qameta.io/allure/#_basic_reporting)のサンプルコードを`test_allure_sample.py`というファイル名で保存します。

pytestで`test_allure_sample.py`のテストを実行します。

``` cmd
pytest test_allure_sample.py --alluredir=/tmp/my_allure_results
```

その後、`allure serve`コマンドを使って、レポートを表示します。

``` cmd
allure serve /tmp/my_allure_results
```

レポートが表示されます。

![allure_sample_result.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/19f73a50-369d-98e6-e4df-8e97a4e19080.png)

公式のサンプルを数回実行しただけなのでTREND等は出ていませんが、各テストケースの結果詳細など見られます。

こちらは、失敗するテストを作って実行してみた結果の様子です。

![Allure-NG例.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46492/5b8ef8f0-6a91-f913-db14-aa265c11bbcf.png)

pytestの出力した結果が右側に出ています。

pytest用のファイルを実際に実行したいものに置き換えれば、ここまでと同じ手順でAllureのレポートを出力し、確認することができます。

テストを複数回実行すれば、過去の分のレポートも（alluredirを変えない限りは）溜まっていきます。

## この先

既存の自動テストスクリプトに全く手を入れたくない（＝pytestの実行時のパラメータ変更だけでなんとかしたい）となると、出来るのはここまでかなと思います。

ここまででも自動テストのレポートをグラフィカルに表示することはできるので、一定の意味はあります。が、より詳細な、希望通りのレポートを出力したい、となると、自動テストスクリプトにAllure関連のコードを入れていくことになります。

### Allureの機能を使う

[6.1.5. Allure Features](https://docs.qameta.io/allure/#_allure_features)にも書いてありますが、

- Steps
  - `@allure.step`デコレータを付けたメソッドをテストメソッドから呼び出すことで、テストメソッドの中での段階を定義することができる
  - Seleniumを使ったテストをする場合、例えば「ログイン」等のステップを用意することで、レポートの見やすさがUP
- Attachments
  - レポートに画像やHTMLなどを添付できる
- Descriptions
  - レポートに詳細情報を付与できる（＝HTMLなど書ける）
- Titles
  - レポートに表示されるテスト名称を任意に設定できる

などができます。

この辺の具体的な使い方は別でまとめようと思います。
Oracle HTTP ServerにLet's Encryptで取得したSSL証明書をインストールする方法

# はじめに

OHSにオレオレ証明書ではなく、ちゃんと署名されたSSL証明書をインストールしようとして激ハマりしました。

証明書はLet's Encryptで取得したものですが、ググってもうまくまとまってる記事がなくかなり苦戦。
とりあえずうまくいったので、メモ代わりに。

## 環境
RHEL7
WebLogic 12c

## SSL証明書の取得
以下の証明書類がある前提で。
これをOHSにいれたかった。

- cert.pem（サーバー証明書）
- chain.pem（ルート証明書）
- fullchain.pem（サーバー証明書とルート証明書が合体したやつ）
- privkey.pem（秘密鍵）

これらのファイルを /tmp/certs あたりにでも置いておきましょう。

## うまくいかなかった方法
OHSにはOracle Walletっていう仕組みがあるらしく、この中に証明書を入れないとダメらしい。

とりあえずやってみる。

``` shell-session
$ ./orapki wallet create -wallet /tmp/wallet -auto_login_only
操作は正常に完了しました。

$ ./orapki wallet add -wallet /tmp/wallet -user_cert -cert /tmp/certs/cert.pem -auto_login_only
PKI-04006: ウォレットに一致する秘密鍵がありません。
```

んー。秘密鍵をいれるには、import_private_keyっていうオプションがあるみたい。
やってみる。

``` shell-session
$ ./orapki wallet import_private_key -wallet /tmp/wallet -pvtkeyfile /tmp/certs/privkey.pem
PKI-07015: 秘密鍵をインポートできません。証明書が必要です。
```

証明書？サーバー証明書も一緒に指定してみる。

``` shell-session
$ ./orapki wallet import_private_key -wallet /tmp/wallet -pvtkeyfile /tmp/certs/privkey.pem -cert /tmp/certs/cert.pem -cacert /home/oracle/cert/chain1.pem
秘密鍵のパスワードを入力してください:
PKI-07014: 秘密鍵をインポートできません。 Header not present in private key
```

秘密鍵にパスワード付けてないし、"秘密鍵にヘッダーがない"とは・・・？

という感じで、秘密鍵にパスワード付けてみたりいろいろやりましたが、ダメでした。


## うまくいった方法
opensslでpem→pfxに変換し、それをインポートすれば良いみたいです。

### ペアを作る
``` shell-session
$ openssl pkcs12 -export -in /tmp/certs/cert.pem -inkey /tmp/certs/privkey.pem -out ./pkcs.p12
Enter Export Password: ［そのままEnter］
Verifying - Enter Export Password: ［そのままEnter］

$ ls -l
-rw-r--r-- 1 user group 3013 10月 30 10:56 pkcs.p12  ←ペアのファイルができる
```

### walletを作る
``` shell-session
$ ./orapki wallet create -wallet /tmp/wallet -auto_login_only
操作は正常に完了しました。
```

### ルート証明書をwalletに追加する
``` shell-session
$ ./orapki wallet add -wallet /tmp/wallet -trusted_cert -cert /tmp/certs/chain.pem -auto_login_only
操作は正常に完了しました。
```

### ペアをwalletにインポートする
``` shell-session
$ ./orapki wallet import_pkcs12 -wallet /tmp/wallet -pkcs12file ./pkcs.p12 -auto_login_only
PKCS#12ファイル・パスワードを入力してください: ［そのままEnter］
orapki command import_pkcs12 executed successfully.
```

### walletの中身を確認
``` shell-session
$ ./orapki wallet display -wallet /tmp/wallet
Requested Certificates:
User Certificates:
Subject:        ［自分の証明書のCN］
Issuer:         CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US

Trusted Certificates:
Subject:        CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US
Issuer:         CN=DST Root CA X3,O=Digital Signature Trust Co.
```

あとは、SSLWalletにこのウォレットを指定してあげればOK。

### ちなみにfullchainの場合
ペア作るときの-inをfullchain.pemにして、そのままwalletにインポートすれば良さそうです。
（ペアの中にルート証明書が入ってるので、wallet addでルート証明書追加しなくていい）
Larevel routes/web.phpとかに書けるメソッドたち

ルーティングに直接関わるもの抜粋。
`group()`とか`prefix()`などは省いてます。

# HTTPメソッドに対応したもの

```php
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
```

## 使い方
```php
Route::get('/path/to/route/{param}',function($param){
    // return view('...'); などなど...
});

Route::get('/path/to/route/{param}', 
    'path\to\Controller@methodName');
```

[ルーティング 5.7 Laravel](https://readouble.com/laravel/5.7/ja/routing.html)

# リソースルート

`php artisan make:controller ****Controller --resource`ってしたときに自動的に作られるメソッドに対応したルーティングをしてくれる。

```php
Route::resource($uri, $controller, $options = []);
```

## 使い方
例としてこんなのを作るとこうなる

```php
Route::resource('articles', 'ArticleController');
```

| HTTPメソッド | URI | 対応するコントローラのメソッド |
|:--|:--|:--|
| GET | /articles | index() |
| GET | /articles/create | create() |
| POST | /articles | store(Request $request) |
| GET | /articles/{article} | show($id) |
| GET | /articles/{article}/edit | edit($id) |
| PUT/PATCH | /articles/{article} | update(Request $request, $id) |
| DELETE | /articles/{article} | destroy($id) |

`create()`、`edit($id)`はモデルの新規作成・編集用のViewを返すためのメソッドとして用意されている。

## オプションをいじる

```php
Route::resource('articles', 'ArticleController', ['only' => ['index']]);
```

などとするとGETで`/articles`以外にリクエストを送ると404が返る。
オプションで実装していないメソッドなどを明示しないとReflectionExceptionとかが出る。

他にも`Route::resource()->only([...])`とかでも指定できるみたいだけど、`name()`付けたいときとかに困りがちなので配列で引数に与えるのがおすすめ。

[コントローラ 5.7 Laravel](https://readouble.com/laravel/5.7/ja/controllers.html)

# APIルート
さっきのから`create()`、`edit($id)`がなくなった版。
`php artisan make:controller ****Controller --api`に対応してます。

```php
Route::apiResource($uri, $controller, $options = []);
Route::apiResources($array);
```

## 使い方

```php
Route::apiResource('/articles', 'ArticleController');

Route::apiResource('/articles', 'ArticleController', ['only' => ['index', 'show']);

Route::apiResources([
    'articles' => 'ArticleController',
    'users' => 'UserController'
]);
```

`Route::apiResources()`にオプションを効かすこともできる。

```php
Route::apiResources(
    [
        'articles' => 'ArticleController',
        'users' => 'UserController'
    ],
    [
        'only' => ['index','show']
    ]
);
```

こんな実装なので、配列に書いたコントローラすべてに同じオプションを効かすようです。

```php
    /**
     * Register an array of API resource controllers.
     *
     * @param  array  $resources
     * @param  array  $options
     * @return void
     */
    public function apiResources(array $resources, array $options = [])
    {
        foreach ($resources as $name => $controller) {
            $this->apiResource($name, $controller, $options);
        }
    }
```

[コントローラ 5.7 Laravel](https://readouble.com/laravel/5.7/ja/controllers.html)
【Node.js+Express+PostgreSQL】async/await使ってPostgreSQLに接続

# はじめに
本記事では、コールバックではなく、``async/await``を使ってExpressでPostgreSQLに接続する方法をまとめる。
``async/await``部分以外は、以下の記事を参考にしていただければ。

* [【Node.js+Express+PostgreSQL】ExpressにPostgreSQLを導入](https://qiita.com/c6tower/items/c6fc18e14229dbf2f53a)

## 環境
* Windows 10
* Express 4.17.1
* PostgreSQL 11.3
* pg 7.12.1

## サンプルコード
```js:sever.js
const express = require("express");
const app = express();
const pg = require('pg');

const pool = pg.Pool({
  host: hoge,
  database: hogehoge,
  user: huga,
  port: 5432,
  password: hugahuga
});

app.get("/", (req, res) => {
  pool.connect( async (err, client) => {
    if (err) {
      console.log(err);
    } else {

      //同期っぽい処理
      try {
        var result = await client.query("SELECT * FROM users WHERE age = $1", [24]);
        console.log(result.rows);
      }  catch (err) {
        console.log(err.stack);
      }

      //非同期処理
      try {
        var result = client.query("SELECT * FROM classes WHERE id = $1", [1]);
        console.log(result.rows);
      }  catch (err)  {
        console.log(err.stack);
      }

      res.json({
        msg: "Hello, world!"
      });
    }
  });
});
```

## 参考サイト
* https://node-postgres.com/features/queries
#docker + alpine + headless #GoogleChrome = chromium で HTML to PDF 変換 / スクリーンショット撮影を実行する例 ( online で URL 指定 )


# 参考

[ヘッドレス Chrome ことはじめ  |  Web  |  Google Developers](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)

>TL;DR
>Headless Chrome が Chrome 59 に搭載されます！これは Chrome をヘッドレス環境で実行する手段です。Chrome をクローム（ブラウザーのUIのこと）なしに実行します！ヘッドレス Chrome によって、Chromium とそのエンジン Blink が提供するモダンなウェブプラットフォームの機能すべてがコマンドラインにもたらされるのです。

# docker run alpine

```
docker run -it --name chrome-headless alpine:3.10.3 ash
```

# install chromium


```
apk add --update chromium
```

# Convert HTML to PDF 

```
chromium-browser --no-sandbox --headless --disable-gpu --print-to-pdf https://yahoo.com
```

# Copy pdf file to local = docker host and open it

```
docker cp chrome-headless:/output.pdf ./
open output.pdf
```

# PDF

謎に日付が入っているが、これさえ消せたら良いのだけど。

![image](https://user-images.githubusercontent.com/13635059/67832471-1c612100-fb25-11e9-9001-adc67dc5c21b.png)

# Web

比較

![image](https://user-images.githubusercontent.com/13635059/67832976-aeb5f480-fb26-11e9-8b7e-e28afd040b1e.png)

# スクリーンショット

```
chromium-browser --no-sandbox --headless --disable-gpu  --screenshot --window-size=1280,1696 https://yahoo.com
```

```
docker cp chrome-headless:/screenshot.png ./ && open screenshot.png
```

![image](https://user-images.githubusercontent.com/13635059/67833252-7e228a80-fb27-11e9-85e6-ddfc96aeceb9.png)



# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2640








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
UiPathで椎名林檎の名曲をChatworkに送る

#今度はUiPathで
先日は本業が暇だったので、[Google Apps Scriptで椎名林檎の名曲botを作りました](https://qiita.com/k-saori-g/items/5d444575cdfa30dbfcbd)。
今度はUiPathでChatworkを動かしてみたいと思いました。

##UiPath.Web.Activitiesを入れる
リボンにある「パッケージを管理」をクリック。
「UiPath.Web.Activities」を探してインストール、保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295560/8b6a1669-96b9-5b0f-1358-d2583e58ed36.png)
準備ここまで。

##「HTTP要求」アクティビティを使う
「HTTP要求」のアクティビティをデザイナーパネルに追加すると、「HTTP要求ウィザード」が現れます。
こいつ、デザイナーパネルに追加した時にしか現れないみたいです。
うっかり閉じちゃった方は、アクティビティを追加しなおしてください！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295560/a65a9bfd-c8fa-7fec-69a7-6e7b16ff6f8e.png)

####エンドポイントを入力
Chatwork公式の[APIドキュメント](http://developer.chatwork.com/ja/endpoints.html)を参考に、エンドポイントを入力します。
とりあえず、メッセージを送るだけにしてみるので、エンドポイントは「https://api.chatwork.com/v2/rooms/{room_id}/messages」を入力。
ポイントとしては、このウィザード内に入力するときは「""」が不要です。

####要求メソッドを選択
今回はメッセージを送りたいので「POST」を選択。

####URLセグメントを追加
「URLセグメントを追加」をクリックすると、入力できる行が現れるので、エンドポイントの{room_id}を設定します。
「名前」は「room_id」、値にはメッセージを送りたいルームIDを入力します。
こちらも「""」は不要です。
ちなみに、ChatworkのルームIDは、「https://www.chatwork.com/#!rid●●●●●」の●●●●●部分の数字です。

####ヘッダーを追加
URLセグメントを追加したのと同じ要領で、ヘッダーを追加します。
「名前」は「X-ChatWorkToken」、値にはAPIトークンを入力します。

####パラメータを追加
最後に、パラメータを追加。「名前」は「body」、値には送りたいメッセージを入力します。
後からプロパティパネルで変更することもできるので、変数なんかも普通に使えます。

##実行するだけ！
手順はたったこれだけ！
Webの仕組みもよう分かってない私でも、すぐできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295560/b05aed73-24ed-f982-778f-b2e0e31c1c1b.png)
よく使うgitコマンドメモ

# はじめに
タイトル通り、私がよく使うgitコマンドをメモしておきます。
またそのうち整備したほうがよさそうな内容。

# 使用ツール
今回は略。

# よく使うgitコマンド

## 設定を追加

```
git remote add origin [url]
```

## 現在の設定

```
git remote -v
```

## 設定を削除

```
git remote rm origin
```

## 設定のURLを変更

```
git remote set-url origin [url]
```

## ブランチ名追加

```
git branch ブランチ名 remotes/origin/ブランチ名
```

## ブランチの内容をpush

```
git push origin ブランチ名
```
## ブランチ名削除

```
git branch --delete ブランチ名
```

# よく使うわけじゃないけどたまに発生するやつ

## Subversionリポジトリ登録

```
git svn init -T <trunkのURL> -b <branchesのURL> -t <tagsのURL> --username=<ユーザー名>
```
## Subversionリポジトリの変更取り込み

```
git svn fetch
```
NativeScript(Angular): Web/Android/iOS

## はじめに

この記事は、Angularを触った事がある方を対象にしています。

### NativeScriptとは

[NativeScript](https://www.nativescript.org/)はWebとMobileアプリ（AndroidとiOS）をJavaScriptとCSSで実装出来るフレームワークです。
NativeScriptで作成されたアプリはFull-Nativeなモバイルアプリになります。

### NativeScriptの何が嬉しいか

- __簡単導入__

  - Angular Schematics と `ng add` を使う事によって簡単に導入できます。

  - 同じリポジトリ内でWebとMobileを構築していくことが出来るため、コードの共有化が可能になります。

- __完全ネイティブ__

  - NativeScriptで開発されたアプリは完全にネイティブです。これは、ネイティブUIやネイティブAPIへのアクセス、およびデバイス上のネイティブレンダリングを意味しています。

- __コード共有__

  - KotlinとSwiftでの開発に比べるとロジックや通信部分を共有して、テンプレート部分のみ個別に作成していけるので無駄が無く、素早い実装が可能です。

  - １つのコードで、Web/Android/iOSを管理でき、より楽に、安心してコード管理をしていくことが可能なります。

  ![basket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137825/730c07d1-75de-8862-c6a4-5e1b0ae43a10.png)

## 開発環境構築

- XcodeとAndroid studioなどのダウンロード/インストール

  - [こちらを参考にインストール](https://docs.nativescript.org/start/ns-setup-os-x)

- NativeScript CLIのインストール

  - `npm i -g nativescript`

- Angular CLIのインストール

  - `npm i -g @angular/cli`

- NativeScript Schematicsのインストール

  - `npm i -g @nativescript/schematics`

### プロジェクト生成

- Angular Schematicsを使用してプロジェクトを生成

  - `ng new --collection=@nativescript/schematics project-name --shared --style=scss`

#### Webローカルホスト起動

- `npm run start`

  <img width="926" alt="localhost.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137825/5aa43911-c048-cb4b-ad40-7241d04cdb45.png">

#### iOSエミュレーション

- `npm run ios`

  ![emulation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137825/1965db90-00b9-1797-281d-f4b7a57f8291.png)

#### Androidエミュレーション

- `npm run android`

  ![emulator_android.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137825/2f9b5631-4d7d-ac27-87bc-1b16dc5e2c59.png)

## 感想

簡単なHelloWordアプリ（[コードはこちらから](https://github.com/andre-oshiro/webile)）を実装してみましたが、今後実務でも扱っていけたら、改めて記事を書こうかと思います。
Angularを使った事がある人なら、直ぐに開発を始められて、Web、Android、iOS間でコード共有出来るのでコード管理が楽になると思います。
コンソールで"モデル名.connection"してくれと言われた。

# "モデル名.connection"でコンソールが汚れないようにするには
カラム名を参照するとき、コンソールでモデル名を入力し確認することが多い。
`rails db:reset`した後で、いつものようにPostモデルのカラム名を参照しようとしたら、`Post.connection`してくれとのレスが返ってきた。

```
pry(main)> Post
 => Post (call 'Post.connection' to establish a connection)
```
言われた通りコンソールで`Post.connection`にすると、夥しい量のコードでコンソールが汚れる。

```
pry(main)> Post.connection
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter:0x00007fc55bedab20
 @config=  {:adapter=>"postgresql",
   :encoding=>"unicode",
   :pool=>5,   :database=>"beershelf_development"},
 @connection=#<PG::Connection:0x00007fc55beeaa98>, @connection_parameters={:dbname=>"beershelf_development"}, @idle_since=696392.120269,
 @instrumenter=
  #<ActiveSupport::Notifications::Instrumenter:0x00007fc55beb1900
   @id="40e50609520945ffce99",   @notifier=

以下省略
```
コンソールが汚れないようにするには、`.connrction`を`.count`にすればいい。

```
pry(main)> Post.count
   (1.4ms)  SELECT COUNT(*) FROM "posts"
=> 1
```
Introducing SwiftUI: Building Your First App ・Roomsのパート2

# WWCD2019のセッション204を再現しての話　その2 ?

# SwiftUI Canvasでは作動するがSimulatorでは作動しない ?

> 2019/10/30 PM18:10 修正します、画像の話ですが ? サムネイルが64X64ピクセルです、遷移先の画像はそれなりに大きめです

> Canvasでは正常に作動しますが、なんか ? simulatorではセルの部分が表示しませんよね ? 不思議だっ ?

[引用先・WWDC2019 204 Rooms by Apple](https://developer.apple.com/videos/play/wwdc2019/204/)

引用先の動画の10分24秒からのCanvasの挙動をsimulatorで作動するようにしました、能書きよりもコードを見る方がわかりやすい ?

でも少し解説です

- ファイル名はContentView1としました
- Room.swiftの内容を持ってきてRoom1とかtestData1とかに名前を変更しました
- NavigationView内も必要に応じて名前を変更しました
- 画像ですが、ご存知でしょうが ? testData1のRoom1(name: "Observation Deck", capacity: 6, hasVideo: true)ですが ? 何の画像でも良いですが64X64ピクセルで拡張子は.jpgでObservation Deck.jpgとObservation DeckThumbのように2種類の画像を遂にしてAddの分を足して10対を用意してください

はい、コードです

# ContentView1.swift

```ContentView1.swift

//
//  ContentView1.swift
//  Rooms
//
//  Created by 福田 敏一 on 2019/10/30.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI

struct ContentView1 : View {

    var body: some View {
        NavigationView {
            List(testData1) { room1 in
                NavigationLink(destination: Text(room1.name)) {
                    Image(room1.thumbnailName)
                        .cornerRadius(8)
                    
                    VStack(alignment: .leading) {
                        Text(room1.name)
                        Text("\(room1.capacity) people")
                            .font(.subheadline)
                            .foregroundColor(.secondary)
                    }
                }
            }
            .navigationBarTitle(Text("Rooms"))
        }
    }
    
    struct Room1: Identifiable {
        var id = UUID()
        var name: String
        var capacity: Int
        var hasVideo: Bool = false
        var imageName: String { return name }
        var thumbnailName: String { return name + "Thumb" }
    }
    
    @State private var testData1 = [
        Room1(name: "Observation Deck", capacity: 6, hasVideo: true),
        Room1(name: "Executive Suite", capacity: 8, hasVideo: false),
        Room1(name: "Charter Jet", capacity: 16, hasVideo: true),
        Room1(name: "Dungeon", capacity: 10, hasVideo: true),
        Room1(name: "Panorama", capacity: 12, hasVideo: false),
        Room1(name: "Oceanfront", capacity: 8, hasVideo: false),
        Room1(name: "Rainbow Room", capacity: 10, hasVideo: true),
        Room1(name: "Pastoral", capacity: 7, hasVideo: false),
        Room1(name: "Elephant Room", capacity: 1, hasVideo: false)
    ]
}

struct ContentView1_Previews: PreviewProvider {
    static var previews: some View {
        ContentView1()
    }
}

```

ここまで

# 私の感想

> 私の感想ですが ?
私はあまり理解していませんが動けばOKとして考えています、単純にどうしてAppleが動画で親切にも詳しく解説しているのに作動しないのか ? ただ、それが疑問なだけで取り組んでいます
なんでRoom.swiftとかをファイル別にするとSimulatorでCanvas同様に作動しないのでしょうか ? 研究は進みます
【Java】文字列を一文字ずつ切り出しする方法

一文字ずつ切り出す方法を簡単にまとめておきます。

##ソースコード例

```
class Main{
public static void main(String[] args) {

    //切り出しする文字列
    String text = "abcde";
    
    char[] work = new char[text.length()];

    for(int i = 0; i < text.length(); i++){
            work[i] = text.charAt(i);

            //切り出した文字列を一文字ずつ出力
            System.out.println(work[i]);
        	}
	}
}
```

##出力結果

```
a
b
c
d
e
```
この他にsubstringを使う方法などもあります。
querySelectorAll はNodeListを返すので単なるif(hoge) で存在チェックできない

JavaScript のファイル内で、対象のページにDOMが存在するか分からない時に、対象のDOMを`querySelector()`した後で`if(hoge)` で存在チェックをすることがあります。
`querySelector()` の場合には戻り値が`null`なのでこれでいいのですが、`querySelectorAll()` を使った時にほんの少しハマったので共有しておきます。


Chrome Developer Tool のコンソールで動作を確認してみます。

### `querySelector()` のケース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/dd44d181-0123-67b3-d742-8383e5de36a9.png)

マッチしないものを指定しているので`null`が返ってきて想定どおりです。

### `querySelectorAll()` のケース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/e1063e77-0882-9de0-fd1e-d5dcccbbca80.png)

`NodeList []`が返ってきてます。これだと
`if(temp)` だとNodeListが空でもtruthyなので存在チェックになっていません。

というわけで存在判定には length を使って以下のように使えばよかったのでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/fdd00345-0143-6c8d-7bd6-443a6b342d72.png)
JavaScript（クラス/インスタンス/コンストラクタ）

#クラス
オブジェクトを効率よく量産するために、元となる設計図（土台）のことを**「クラス」**と呼ぶ。

書き方：`class クラス名`
:point_up:クラス名は**大文字**から始めるようにする

```js
//例
class User {

}
```

#インスタンス
量産するオブジェクトの設計図（クラス）ができたので、その設計図を元に実際に生成する。
クラスから生成したオブジェクトのことを**「インスタンス」**と呼ぶ。

書き方：`new クラス名()`

```js
//例
class  Animal{

}
const Animal = new Animal();
```

#コンストラクタ
インスタンスを生成するときに実行したい処理や設定を追加するための機能のことを**「コンストラクタ」**と呼ぶ。
クラスの中括弧 { } 内に`constructor() { }`と記述する。

```js
//例
class Animal {
  constructor(){
	}
}
```

ここに書いた処理はインスタンスが生成された直後に実行される。
:point_up:コンストラクタはインスタンスごとに毎回実行される。

```js
class Animal {
	constructor(){
		console.log(“こんにちは！”);
	}
}
const animal1 = new Animal();
const animal2 = new Animal();

//コンソール
こんにちは！
こんにちは！
//↑↑↑インスタンスが二つ設定されているので、2回処理が実行された。
```

コンストラクタの中で、生成したインスタンスに関する情報を追加してみる。
コンストラクタの中で`this.プロパティ = 値`とすることで、生成されたインスタンスにプロパティと値を追加することができる。

```js
//例
class Animal {
	constructor(){
		this name = “バルー”;
	}
}
```

インスタンスとはオブジェクトなので、コンストラクタの中で追加した値は、`インスタンス.プロパティ`とすることでクラスの外で使用できる。

```js
//例
class Animal {
	constructor(){
		this name = “バルー”;
	}
}
const animal = new Animal();
console.log (animal.name);
//コンソール
バルー
```

##コンストラクタの引数
コンストラクタでは、引数を受け取ることが可能。
**「constructor」の後の括弧「( )」内に引数名を記述する**ことで、その引数をコンストラクタの処理内で使用できる。

```js
//例
class Animal {
	constructor(name,age){
		//処理
	}
}
```

コンストラクタに引数として値を渡すには、**「new クラス名()」の括弧「( )」内に値を追加する。**

```js
//例
class Animal {
	constructor(name,age){
		//処理
	}
}
const animal = new Animal(“バルー”,3);
```
macOS CatalinaでGo2Shellが使えなくなっても絶望しない方法 (Finderから現在いるディレクトリを1クリックでiTerm 2で開く方法)

## 前置き
自分は`macOS Mojave`でFinderで現在いるディレクトリをワンクリックでiTerm 2で開ける[Go2Shell](https://apps.apple.com/jp/app/go2shell/id445770608?mt=12)を愛用しています。
しかし`Go2Shell`は32bitアプリケーションかつ最終更新が4年前であるため`macOS Catalina`では使えず、アップデートも期待出来ない状況でした。

そんな時に@ryuta69さんが下記の素晴らしい記事を投稿してくださいました。
>[AppleScriptで「Finderでボタンポチるだけで、そのディレクトリでターミナル開く」（cloneしてドラッグ＆ドロップするだけで利用可能）](https://qiita.com/ryuta69/items/83a485c8fc8c8cb8b011)

この記事では`ターミナル.app`を主題に他のアプリケーションでも活用可能なコードを複数掲載しており大変参考になりました。
また、本投稿を行う事についても快諾していただき大変感謝しています。

## 記事内にiTerm 2を開くコードを発見
記事内に`iTerm 2`を開くコードを発見し「お、これは！」となりました。
挙動としては下記のようになっていました。

1. 現在のディレクトリパスを取得
2. iTerm 2のセッションからウィンドウを取得
3. ウィンドウに新規タブを作成
4. `cd [現在のディレクトリパス]`を入力

次に`Go2Shell`の挙動は下記。

1. 現在のディレクトリパスを取得
2. 新規ウィンドウを作成
3. `cd [現在のディレクトリパス]; clear; pwd`を入力

挙動の差としては下記。

- 前者はアクティブなウィンドウがない場合に実行が失敗してしまう
- 新規ウィンドウか既存ウィンドウへの新規タブか
- 実行されるコマンド

ここで「これは少し調整すれば`Go2Shell`になれるぞ？」と思いました。

## Go2Shellの動作を再現するコード

```applescript
tell application "Finder"
    -- set _dir to POSIX path of ((folder of (front window)) as alias)
    if exists Finder window 1 then
        set currentDir to target of Finder window 1 as Unicode text
        set posixPath to get POSIX path of currentDir
    end if
end tell

tell application "iTerm"
    activate
    create window with default profile
    set _current_session to current session of current window
    tell current window
        tell current session of current tab
            write text "cd " & posixPath
            write text "clear; pwd"
        end tell
    end tell
end tell
```

元コードとの違いとしては以下。

- 新規ウィンドウを作成している
- 新規タブの作成は行わない
- `write text "clear; pwd"`を実行している

## 作成からFinderに追加するまで

1. `Automator.app` を開く
2. `新規書類 > アプリケーション`
3. 「AppleScriptを実行」を右にドラッグドロップ
4. 上記のコードをコピペして任意の名前で保存 (ここでは`OpeniTerm2.app`)
5. `OpeniTerm2.app` をCommand押しながらFinderのツールバーにドラッグドロップ
6. セキュリティ警告が出たら `システム環境設定 > セキュリティとプライバシー > 一般 > 下部から許可`

詳細な手順は@ryuta69さんが投稿してくださった記事に丁寧にまとまっています。

## 終わりに

今現在自分は`macOS Catalina`へのアップグレードを行っていません。
しかしこれでアップグレード後の環境への懸念が1つ解消されました。
バグ修正などが更にリリースされ、安定した環境となった頃にアップグレードを試みたいと思います。
CSSで複数行3点リーダーを実現する「line-clamp」がついにIE以外に対応したよ！

#最新のFirefoxが対応した!!
これにより、IEさえ無視すれば完全にCSSのみで複数行の3点リーダーが実現可能となりました。
よく使う割に難しい処理だったので、地味に嬉しいです。
[最新の対応状況はこちら](https://developer.mozilla.org/ja/docs/Web/CSS/-webkit-line-clamp)

##line-clampとは？
行数を指定して、テキストが領域をはみ出した時に3点リーダ「…」を表示することができます。

![スクリーンショット 2019-10-30 16.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457046/1aa59e49-0980-3e52-c52f-d816a396ef17.png)

``` css
//css

 p {
   width: 170px;
   display: -webkit-box;
   -webkit-line-clamp: 4; //3点リーダを表示する行数を指定
   -webkit-box-orient: vertical;
   overflow: hidden; 
}
```

たったこれだけで実現できちゃいます。
詳しくは[こちらの記事](https://qiita.com/yoshida-hi/items/055c36e015f0bf8fe4f6)でわかりやすく書かれています。

##現状のベストプラクティス
・IE以外で簡単に実現できるようになったので、基本line-clampを使いましょう。
・IE対応が必要な場合は、引き続きIEのみ従来のJSや擬似要素で無理やり実現する方法などで対応しましょう。
git pullを自動で行う

サーバーに構築したgitレポジトリからcloneしたディレクトリをいちいち`git pull`してられませんということで試してみたら意外とすぐできたのでメモ  

```
/home/git/test
```

に`/home/git/test/test.git`がある状態で、
`/home/git/test/`以下にソースがある状態と仮定  

```
$ cd /home/git/test/test.git
$ cd hooks
$ ls
applypatch-msg.sample      post-update.sample         pre-push.sample            prepare-commit-msg.sample
commit-msg.sample          pre-applypatch.sample      pre-rebase.sample          update.sample
fsmonitor-watchman.sample  pre-commit.sample          pre-receive.sample
```

適当に上記ファイルのどれかを複製して`post-receive`を作成する
そのファイルの内容を編集する

```
cd /home/git/test/
git --git-dir=.git pull origin master
```
と記述するだけ。
1行目 = ソースがあるディレクトリ（cloneしたディレクトリ）
2行目 = 1行目で指定したディレクトリに対してpullさせる

これでローカルからpushしたら自動的にpullがされるようになりました。ちゃんちゃん
GitなしでGithubにローカルフォルダをアップロードしたいなあ

#　と思う吉宗であった
Git管理下でローカルフォルダを作成する方法はたくさん出てきたけど、
GitをインストールするのがめんどいのでなんとかGitHubだけで完結できないかなーと思って探したらありました。よかった。

[参考ページ](https://github.com/KirstieJane/STEMMRoleModels/wiki/Creating-new-folders-in-GitHub-repository-via-the-browser"Creating new folders in GitHub repository via the browser")
![動画](https://camo.githubusercontent.com/29f2fd0f075716239c61d9cd7dd58c5b02ca297a/687474703a2f2f692e737461636b2e696d6775722e636f6d2f3949666d6a2e676966)

先頭にスラッシュ入れても反映されないので
（アカウント）/HTML/gazouimg.jpg
「gazou」と「img.jpg」をあとからスラッシュで区切る感じにすればいいっぽい。
出来上がった余計なテキストファイルは後で削除しましょう。
ES6 以降は JavaScript のプロパティに順序は「ある」

## はじめに

「JavaScript のプロパティは順序が保証されていない」 とか 「実装依存だ」 というのが、時々語られることがあるけれど、**古い仕様の話**である。

ES2015 (ES6) 以降はそうでもないよと言うお話。

## 仕様

プロパティキーの順序に関する部分は [ここ](https://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys)

- 文字列キーの内、0 以上の整数に解釈可能なキーが整数昇順で並ぶ
- それ以外の文字列キーが作成順で並ぶ
- シンボルキーが作成順で並ぶ



「作成順」は、オブジェクトリテラルの場合、単に上から。

~~~js
const o = {
  a: 1,
  b: 2,
  c: 3
};
console.log(Object.keys(o)); // ES6 以降なら必ず a, b, c
~~~


## 各種メソッド

- `getOwnPropertyNames` ([仕様](https://www.ecma-international.org/ecma-262/6.0/#sec-object.getownpropertynames))
    - 文字列キーのみ
    - プロトタイプは辿らない
- `getOwnPropertySymbols` ([仕様](https://www.ecma-international.org/ecma-262/6.0/#sec-object.getownpropertysymbols))
    - シンボルキーのみ
    - プロトタイプは辿らない
- `Object.keys` ([仕様](https://www.ecma-international.org/ecma-262/6.0/#sec-object.keys))
    - 文字列キー, 列挙可能なもののみ
    - プロトタイプは辿らない
- `for in` ([仕様](https://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-enumerate))
    - 文字列キー, 列挙可能なもののみ
    - プロトタイプがあれば**辿る** (プロトタイプのキー群は後にくる)

## おわりに

というわけで、環境を ES2015(ES6) 以降に限定できるのであれば、整数キーの扱いに注意はいるものの、プロパティ順序に依存したプログラムも問題なく書ける。

Internet Explorer 11 も ES6 対応は中途半端だけれど、順序に関しては準拠しているので、最新版のみ相手にするなら、主要なブラウザなら大体使えるねと思っても差し支えない。

ES5 な環境も元気で生きているので、そこまで含めた話なら、順序に期待できないねえというのはわかるのだけれど、ES6 の解説してるところまで順序が無い的なことが書いてあったりするので、色々と注意が要る。

仕様書読もう仕様書。

## 参考

[ECMAScript® 2015 Language Specification](https://www.ecma-international.org/ecma-262/6.0/)
[ECMAScript 6 compatibility table - kangax, own property order](https://kangax.github.io/compat-table/es6/#test-own_property_order)
AWSへデプロイしてみよう（〜SSH接続〜Rubyインストール その３）

## 9.SSH接続 その１
まずは公開鍵をコピーします。
一度 exit でEC2から抜けてローカルで以下を実施します。

```
cat ~/.ssh/id_rsa.pub
```
表示された公開鍵をコピー

続いてEC2上のsshディレクトリ配下にauthorized_keysファイルを作成、そのファイルの中に公開鍵を保存します。

```
$ sudo su app
$ cd ~
#sshディレクトリを作成（既に存在している場合は省略）
$ mkdir .ssh
#自分のみに実行権を与える
$ chmod 700 .ssh
#sshディレクトリへ移動
$ cd .ssh
#authorized_keysファイルを作成
$ touch authorized_keys
#そのファイルに自分のみに編集権限を与える
$ chmod 600 authorized_keys
#authorized_keysファイルを開く
$ vi authorized_keys
```

このファイルの中に先ほどコピーした公開鍵を追記し、ファイル編集後はexitでAWS環境を離脱します。

## 10.SSH接続 その２
次にコピーして公開鍵でSSH接続します。
ローカル環境で秘密鍵の所在をpwdコマンドで確認します。

```
cd ~/.ssh 
Axxxxxx-no-MacBook-Pro:.ssh Axxxxxx$ pwd
/Users/Axxxxxx/.ssh
```
確認したら、そのパスを元に、sshコマンドを実行

```
ssh -i "pwdで確認したpath/id_rsa" app@パブリック（ElasticIP）IP
```
appユーザーとして接続できたら、SSH接続の完了です。

## 11.タイムゾーンと時刻の確認
EC2にて実施

```
[app@ip-172-31-50 ~]$ date

（下記内容が出力できればOK）
2017年  10月 25日 水曜日 18:02:29 JST
```
続いて時刻のズレの修正を以下のコマンドで行って、インスタンスを再起動します。

```
$ sudo service crond restart
$ sudo reboot
```

続いて、デフォルトのユーザであるec2-userは今後使用しないため、削除します。

```
$ sudo su -
$ userdel ec2-user 
```
## 12.EC2への各種インストール
ツールの導入は管理者権限が必要なのでsudo su -でrootユーザーになった状態でツールを導入します。
まずは　git のインストール。

```
$ sudo su -
$ yum -y install git
$ git --version
```

次に rbenv のインストール。

```
$ git clone https://github.com/rbenv/rbenv.git /usr/local/rbenv
vi /etc/profile.d/rbenv.sh
```
VIMで以下を記述します。

```
export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)" 
```
正しく読み込ませるために、sourceコマンドを実行

```
source /etc/profile.d/rbenv.sh
$ rbenv --version
```

次にruby-buildをインストール

```
$ git clone https://github.com/rbenv/ruby-build.git /usr/local/rbenv/plugins/ruby-build 
$ rbenv install -list
```
次にRubyのインストールに移る前にRubyをインストールするために必要なパッケージ群をインストール

```
$ yum -y groupinstall "Development Tools"
$ yum -y install gcc-c++ glibc-headers openssl-devel readline libyaml-devel zlib zlib-devel libffi-devel libxml2 libxslt libxml2-devel libxslt-devel mysql-devel readline-devel
$ yum -y install ImageMagick ImageMagick-devel
```
gccのダウングレードを実施

```
$ yum install gcc44
$ alternatives --set gcc /usr/bin/gcc44
```

ようやくRubyをインストール（デプロイするアプリと同じバージョン）

```
$ rbenv install 2.6.3
$ rbenv versions
$ rbenv global 2.6.3
$ rbenv rehash
$ ruby -v
```

ここで exit で、appユーザーに戻って、appユーザーのRubyバージョンも変更します。

```
$ cd /usr/local/rbenv/
$ sudo chown app version
$ sudo chown app shims
```

ls -laのコマンドで、ディレクトリ内にあるものすべての権限をチェックすると、該当のファイルだけappユーザーが所有者になっていることを確認。（shims)

これでappのRubyバージョンを変更できます。（一度exitして再接続して）

```
$ rbenv global 2.6.3
$ rbenv rehash
$ ruby -v
```
次にEC2へBundlerのインストールを行います。

```
$ sudo su -
$ rbenv exec gem install bundler
$ rbenv rehash
$ which bundler
```
これで　/usr/local/rbenv/shims/bundler　と出ればOKです。

つづく。。
Python+OpenCVで透過画像作る

# はじめに

透過画像作りたいのですが、調べたら意外となかったので自分のために備忘録

# 環境
* MacBookPro

* Python (3.7.4)

```
python --version
Python 3.7.4
```

* OpenCV （4.1.1）

```
>>> import cv2
>>> cv2.__version__
'4.1.1'
```

# プログラム

```python

#!/usr/bin/python
import numpy as np
import cv2

image_file = 'sample.png'
image = cv2.imread(image_file, -1)

width = image.shape[0]
height = image.shape[1]
out = np.zeros(image.shape[:4], np.uint8)

for i in range(width):
	for j in range(height):
		b = image[i][j][0]
		r = image[i][j][1]
		g = image[i][j][2]
		a = image[i][j][3]
		if r>0 or g>0 or b>0:
			out[i][j][0] = 255
			out[i][j][1] = 255
			out[i][j][2] = 255
			out[i][j][3] = 255
		else:
			out[i][j][0] = b
			out[i][j][1] = r
			out[i][j][2] = g
			out[i][j][3] = 0

cv2.imwrite("alpha.png", out)
```

# 簡単な解説

## 前提
そもそもalphaチャネルは、pngじゃないともっていないので、jpgとかだとダメです。なので、まずは、pngファイルを準備します。

## 画像読み込み

```python
image_file = 'sample.png'
image = cv2.imread(image_file, -1)
```

画像を読み込む時の引数で `-1` をつけるとalphaチャネルまで読み込めます。

## 出力画像の箱準備

```
out = np.zeros(image.shape[:4], np.uint8)
```

0で埋めたnparrayを準備してます。

## 透過処理

```python
for i in range(width):
	for j in range(height):
		b = image[i][j][0]
		r = image[i][j][1]
		g = image[i][j][2]
		a = image[i][j][3]
		if b>0 or r>0 or g>0:
			out[i][j][0] = 255
			out[i][j][1] = 255
			out[i][j][2] = 255
			out[i][j][3] = 255
		else:
			out[i][j][0] = b
			out[i][j][1] = r
			out[i][j][2] = g
			out[i][j][3] = 0
```

1ピクセルづつ処理してます。
この処理だと、黒（0,0,0）を透過させてます。そして、黒じゃないところを白（255,255,255）にします。
なので、黒じゃない時（b>0 or r>0 or g>0）はそのまま、それ以外の時は、alphaを0にしてます。

## 結果

処理前
![decode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55871/ad46bb1c-a89a-65c5-246a-26dcf7c59ce5.png)

↓↓↓↓↓↓↓↓↓
処理後
![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55871/d8c6cd8e-21c8-6524-1743-90849482c617.png)
※透過+白だから見えないぽいので、クリックしていただけると幸いです。

たまに、透過画像が必要になる人は参考にしていただければと思います。

ありがとうございました。
たくさんのステップを手動で実行しているものを自動化するため方法の１つ

# 概要

テスト時や、開発中のプログラムの実行が手動で８ステップとかあるときに、どうやって自動化するかの方法について


# 結論

うまくいくケースのみ考えて、スクリプトにしてしまう。

3ステップにするとこんなかんじ

# ステップ1、全体を実行するスクリプトをつくってしまう。

以下のようなbashスクリプトを用意する
今回は `./testscript.sh` とする

`set -eux` をつけておく。

- `e` エラーがおきたら止まるようにする
- `u` 未定義変数があったら止まるようにする
- `x` 実行したコマンドを出力する

```bash
#!/bin/bash
set -eu

echo "Step 1 start"
date
# 実行したいコマンド、今は手で入力しているもの
# cwltool step1.cwl
# nextflow step1.nf
echo "Step 1 end"
date

# n step分

echo "ALL STEP IS OK!!"
```

# ステップ2、定期的に実行するようにする

次に自分のcronの設定をし、
定期的に正しく実行できることを確認する。

実行されるディレクトリへ、明示的に `cd` しておく。

ログの回収するファイル名を、日付と時間にしておくと、
テストが失敗したときに、以前の結果と比べられるので、よかった。



# ステップ3、通知をするようにする。

うまくいったか、いかなかったかを、Slack へ通知する
通知は、毎日おこなったほうがよいと考えている
成功だけとか、失敗だけとかにしておくと、通知システムの故障時など、通知がこないこと自体にきづかない。

- `./testscript.sh` が、自動実行スクリプト本体
- `./notify.sh` は、Slackへ通知をするスクリプトとする。
  - この部分は、 `curl` などで直接実行しても良い。
 

```bash
#!/bin/bash
RET=./testscript.sh
if [ ${RET} -ne 0 ]; then
  # エラー時の処理
  # slackとか使ってなかったら、echo "ERROR" でもよい
  ./notify.sh ERROR
else
  # 成功時の処理
  # slackとか使ってなかったら、echo "SUCCESS" でもよい
  ./notify.sh SUCCESS
fi
```

# コツ

必要なものはそろっているとして、スクリプトを書き始めてしまって良い。
準備する部分を書き始めると大変なので、それはあとで書けば良いと思う。

とにかく、全部実行できるものがひとつできあがると、いろいろ追加しやすかったという経験があります。
「No signing certificate "iOS Development" found」がでてarchiveが正常にいかなくなったときになんとかした話

# 始めに
今回の記事では、JenkinsでUnityビルド→Xcodeビルドをした際に
「**No signing certificate "iOS Development" found**」がでてarchiveができなくなった際にしたことを書き留めていきます。

本来distributionでビルドするはずだったのになぜかDevelopmentになっている！
そんな困ったことが起こった時に対応できると思います。

宜しくお願い致します。

# 開発環境
Unity 2018.4
Xcode 10
Jenkins
pipeline
# なぜ起きたのか
こちらに関しては調査をしていたのですが、原因究明までは至りませんでした。
ただ、XcodeのBuild settingがDevelopmentになっていたのでここの設定項目(何も設定していないせい)で発生していたのではないかと思います。

さらに言えば、今回発生した原因の一つとしてビルドをする際の状況が特殊だったことも起因しているのではないかと思います。
(開発におけるアレコレ)

# 対策
まず下記の記事のようにXcode自体の設定をいじればarchive自体は通ります。
https://dev.classmethod.jp/smartphone/iphone/xcode-no-signing-certificate-ios-development-found-error/

しかし、この設定を毎回手動でやるのはJenkinsを使っている意味がなくなるのでJenkinsの方をいじってなんとかします。

下記のバッチビルドがあります。

```
xcodebuild -sdk iphoneos \
  -project hogehoge.xcodeproj -target Unity-iphone \
  -configuration Release build
```

この設定に対して

```
  CODE_SIGN_IDENTITY=\"iPhone Distribution: hogehoge\" \
```
これを加えます！
iphone Distribution以下は環境により変わります。(つかない場合もあり。)

付加することで向き先がDistributionになり、正常にビルドが通るようになります。

# 最後に
いかがでしたでしょうか？
ほかの案件の兼ね合いでXcodeを色々触っていてビルドが全部動かなくなった！とかなった人の手助けの一助になれば幸いです。
私は、ビルド周りで本当に悩まされてきました・・・
というかビルド周りは本当に難しい・・・
有難う御座いました。
Javaで2つのjsonを比較する

# はじめに

## 何がやりたかったか

* jsonを返却してくれるAPIがあって、その改修をしたい
* 共通のUtilクラス変更したり、ライブラリの更新したりする  
　→ 1つのAPI改修に対して影響範囲が広くなりそう
* テスト書きづらいつくりしてる

じゃあ返却されるjsonの差分とってまず動作担保しよう！

## 要件

* java(Kotlinも可) でやる
  * 対象のAPIがjavaで実装されているので、同じ言語・フレームワークで比較できるようにしておく。後々の運用時学習コストを下げるため。
* 差分の場所、内容がわかる。
  * 差分ありますよ！じゃなくて、どこで差分が出てるかがわかる
  * 文字列差分じゃなくてちゃんとオブジェクト差分
* さくっとやりたいので使えるライブラリあるならそれを使う

# 結論

経緯とかいろいろ書くより、何やったか(使ったか)を書いておきます。
これ見て満足した人はこのページそっと閉じて実装しに行ってください(ﾊﾞｲﾊﾞｲ)

[zjsonpatch](https://github.com/flipkart-incubator/zjsonpatch) を使いました。

```java:差分チェック
// {"a": 0,"b": [1,2]}
JsonNode jsonA = jacksonObjectMapper.readTree(jsonAString);
// {"b": [1,2,0]}
JsonNode jsonB = jacksonObjectMapper.readTree(jsonBString);

JsonNode patch = JsonDiff.asJson(jsonA, jsonB)

patch.toString() // [{"op":"move","from":"/a","path":"/b/2"}]
```

`op` の部分に種別が入ります。
削除で `remove`, 追加で `add` とか。
`path` には対応するjsonのパスが入ります。
あとは種別に応じて、例の `from` みたいにオブジェクト生成されます。

# 調べたこととか

[json-patch](https://github.com/java-json-tools/json-patch) も同じことができる模様。
ただ、[stackoverflow] (https://stackoverflow.com/questions/6526911/best-way-to-compare-2-json-files-in-java) の回答者が以下のように書いてくれてます。

```
This library is better than fge-json-patch (which was mentioned in another answer) because it can detect items being inserted/removed from arrays.
Fge-json-patch cannot handle that (if an item is inserted into the middle of an array, it will think that item and every item after that was changed since they are all shifted over by one).

【訳(ありがとうGoogle翻訳)】

このライブラリは、fge-json-patch（別の回答で言及されています）よりも優れています。
アレイから挿入/削除されるアイテムを検出できるためです。
Fge-json-patchはそれを処理できません（アイテムが配列の中央に挿入されると、すべてのアイテムが1つずつシフトされるため、アイテムとその後のすべてのアイテムが変更されたと見なされます）。
```
配列の差分比較がちゃんとできないっぽい。
ライブラリの更新日を見ても今回紹介したものの方がよさそうなのでこちらを採用しました！

# おわりに
jsonの比較したいと思って調べても英語記事とか独自実装とか多めで、さくっと見つけられる情報あるといいなと思って書いてみました。
この記事見つけてくれた方のお役に立てば幸いです。
RiotAPIのregionについてまとめてみた

タイトルだと分かりづらいですが、、、

```
from riotwatcher import RiotWatcher

API_KEY = '[APIキー]'
watcher = RiotWatcher(API_KEY)

region = 'kr' # 鯖
name = 'Hide on bush' # サモナーネーム
summoner = watcher.summoner.by_name(region, name)
summoner
```
これのregionという各地域のサーバーの文字列（上の例だとkrで韓国）についてまとめました。

この部分については公式の方でもちゃんと書かれておらず、地域によって名前が多少違っていたりする（krだったりjp1のように最後に1がついたり）ので書いてみました。

# region

| region           | name                                   |
|:-----------------|:---------------------------------------|
| RU               | Russia（ロシア）                        |
| KR               | Korean（韓国）                          |
| BR1              | Brazil（ブラジル）                      |
| OC1              | Oceania（オセアニア）                   |
| JP1              | Japan（日本）                           |
| NA1              | North America（北アメリカ）             |
| EUN1             | EU Nordic & East（北および東ヨーロッパ） |
| EUW1             | EU West（西ヨーロッパ）                 |
| TR1              | Turkey（トルコ）                        |
| LA1              | Latin America North（北ラテンアメリカ）  |
| LA2              | Latin America South（南ラテンアメリカ）  |

※regionについては大文字でも小文字でも可
【groovy】実行するポートを指定（変更）する方法

groovyスクリプトをポート8080で上手く接続できない、エラーが出る場合の対処方法です。
##ポート9000で実行する場合の例
コマンドプロンプト（ターミナル）で以下のように入力します。

```
spring run test.groovy -- --server.port=9000
```

問題なく実行できたら以下のURLで実行結果を確認しましょう。

<a href="http://localhost:9000/" target="_blank">http://localhost:9000/</a>
##参考：実行ソース例
ファイル名：test.groovy

```php:hello.php
@RestController

class App{
  @RequestMapping("/")
  def home(){
  "Hello!"
  }
}
```
##参考：JVMオプションを指定して実行する
```
JAVA_OPTS=-Xmx1024m spring run test.groovy
```
参考：<a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#cli-run" target="_blank">https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#cli-run</a>
Storybook Nuxt + Vuetifyのリンクの対応

nuxt-linkやVuetifyの[to]でのリンク（router-link）はstorybook上でリンクが動くとおかしなことになるのでエラーが出る仕様になっていて、エラーが出るの嫌だし、出力でどこにリンクするのかが欲しいというのが課題でした。

私は、Nuxt初心者だけどNuxt, Vuetify, Storybook, TSで環境構築しましたが色々本当に大変でやっと整ってきました。

いろんな記事に本当に助けられました。
色々ありますが、今回はリンク対応だけ載せておきます。

```js
import Vue from 'vue'
import { action } from '@storybook/addon-actions'
Vue.component('nuxt-link', {
  props: ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    }
  },
  template: '<a href="#" @click.prevent="log()"><slot>NuxtLink</slot></a>'
})

Vue.component('router-link', {
  props: ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    }
  },
  template: '<a href="#" @click.prevent="log()"><slot>RouterLink</slot></a>'
})
```

## ファイルの全体

```js
import { configure, addDecorator } from '@storybook/vue'
import { withKnobs } from '@storybook/addon-knobs'
import { setConsoleOptions } from '@storybook/addon-console'
import { withInfo } from 'storybook-addon-vue-info'
import { action } from '@storybook/addon-actions'

// 追加
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.css' // →これ重要

Vue.component('nuxt-link', {
  props: ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    }
  },
  template: '<a href="#" @click.prevent="log()"><slot>NuxtLink</slot></a>'
})

Vue.component('router-link', {
  props: ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    }
  },
  template: '<a href="#" @click.prevent="log()"><slot>RouterLink</slot></a>'
})

// 依存注入
Vue.use(Vuetify)

addDecorator(() => ({
  vuetify: new Vuetify(),
  template: `
<v-app>
    <story/>
</v-app>
`
}))

setConsoleOptions({
  panelExclude: []
})

addDecorator(withKnobs)

addDecorator(withInfo)

// automatically import all files ending in *.stories.js
configure(require.context('../stories', true, /\.stories\.js$/), module)
```

## nuxtにstorybook入れるとこけるcore-js
`core-js`というライブラリのバージョン3以上が入っているとエラーでこけます。
とりあえず以下のバージョンに下げることで動きます。

```js:package.json
"core-js": "2.6.2",
```

## 参考
- [`nuxt-link` タグのリンクをStorybook上で確認する方法](https://qiita.com/sawami2019/items/407b85fc78e6c04fac5c)
RHELでyumを使用とすると「invalid user credentials」と出てしまう場合の対処方法

#概要
RHELをインストールしてすぐにyumコマンドを使用しようとしても下記のエラーが出て
yumコマンドが使用できないときの対処方法

```this system is not registered with an entitlement server```

#原因
RHELではyumの初期設定が行われていない
そのため、RHELのsubscription登録、及びrepolistの更新を実施する必要がある


```
[root@localhost ~]# yum repolist
読み込んだプラグイン:langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
repolist: 0 
#　↑初期設定されているレrepolistが0        

```

#対処方法
以下の手順を実行

```
①サブスクリプション登録
[root@localhost ~]# subscription-manager register --auto-attach
登録中: subscription.rhn.redhat.com:443/subscription
ユーザー名:        ### RHEL OSをダウンロードする際に登録したユーザ名
パスワード:        ### 上記パスワード
このシステムは次の ID で登録されました: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX 

インストール済み製品の現在の状態:
製品名: Red Hat Enterprise Linux Server
状態:   サブスクライブ済み


②レポジトリ登録
[root@localhost ~]# subscription-manager repos --list
[root@localhost ~]# subscription-manager repos --enable rhel-server-rhscl-7-rpms
リポジトリー 'rhel-server-rhscl-7-rpms' はこのシステムに対して有効になっています。
[root@localhost ~]# subscription-manager repos --enable rhel-7-server-optional-rpms
リポジトリー 'rhel-7-server-optional-rpms' はこのシステムに対して有効になっています。


③yumアップデート
[root@localhost ~]# yum -y update
```


#参考にしたサイト：
https://access.redhat.com/ja/solutions/3218261
[vba excel] MessageFormat のbak

<h1>以前仕事中によく使われていた共通メソッド</h1>

```vb

'*******************************************************
'MessageFormatの使い方の例　↓
' Dim args(2) As String
' args(0) = "test1"
' args(1) = "test2"
' args(2) = "test3"
' MsgBox (MessageFormat("this sheet{0},{1},{2} has done.", args))
'*******************************************************
Function MessageFormat(targetMsg As String, args() As String) As String
    Dim index  As Integer
    For index = 0 To UBound(args)
        targetMsg = Replace(targetMsg, "{" & index & "}", args(index))
    Next index
    MessageFormat = targetMsg
End Function
```
Nuxt.js グリッドレイアウトのカラム指定のプロパティをバインド

## 動的にBootStrapVueのグリッドレイアウトの指定を変える

### やりたい事
Blogサイトを作っている時に、`Card`で見せている記事一覧を絞り込みをかけると`1`件表示になる時がある。
Bootstrap-vueでのレスポンシブレイアウトを指定するときは、`md="4"`等と指定するが、これはあくまで、画面の表示サイズに合わせてレイアウトを指定している。
1件しかないにも関わらず、グリッドの指定は`md="4"`と３件づつ並べるレイアウト指定になってしまう等が起こる。
その為、1件しかない時は`md=12`、2件の時は`md="6"`を指定できる様にしたい。

### 方法
`cols`をバインディングできれば、表示`item`数によって場合分けを`comuputed`ですれば良さそう。

### 実装

```html
<b-col
          v-for="post in items"
          :key="post.id"
          sm="6"
          :md="colParm"
          class="text-center d-flex justify-content-center my-3"
        >
```

```js
export default {
  //中略
  data() {
    return {
      items: [] // 表示する記事情報の配列
    }
  },
  computed: {
    ...mapState(['posts']),
    colParm() {
      let colnum = '4' // デフォルト値、記事数が３以上の場合はこの数が入る
      if (this.items.length === 2) {
        colnum = '6'
      } else if (this.items.length === 1) {
        colnum = '12'
      }
      return colnum
    }
  }
  // 中略
}
```

### まとめ

クラスに関わらず、プロパティ全般をバインド出来る様なので便利。
データ側でThemeなどを指定すれば、様々なレイアウトが指定できれば面白そう。