OmniAICreator/Qiita-1.07M huggingface dataset:
既存のAndroidアプリは意外と簡単にHMS対応に改修できます

#はじめに
この前の記事では、HMS（Huawei Mobile Service）とは何なのかについて説明しました。今回は、どうやって既存のAndroidアプリを改修すればHMS端末（GMSが使用できないHuawei端末）で使えるようになるのかについて紹介したいと思います。タイトル通り、実は既存のAndroidアプリは意外と簡単にHMS対応に改修することができます。

#SDKの使用状況によるアプリの分類

前回の記事で紹介したように、HMS端末ではGMSとfirebaseのSDKが使用できません。
しかし、HMS端末のOSはAOSP（Android Open Source Project）ベースですので、Androidのネティーブコンポーネントは継続的に使用できます。
AOSPとGMSの関係についてはこちらの記事でかなり分かりやすく紹介されていますので気になる方は確認してください。
https://qiita.com/hirossyi73/items/700e1be8e2b8f472b098

また、GMS以外のサードパーティーSDKの場合、GMSに依存していなければ継続的にHMS端末で使用できます。

まとめるとこんな感じになります。
**1. GMSとfirebaseのSDK：GMSのSDKは使用できませんが、FirebaseのSDKは一部使えるSDKもあります。
2. Androidのネティーブコンポーネント：継続的に使用可能
3. 3rd partyのSDK：GMSに依存していなければ使用可能**

以上のSDKの使用状況に応じて、既存のAndroidアプリを以下の2種類に分けることができます。
**1. GMSとfirebaseのSDKを使用していないアプリ：改修不要→そのままHMS端末で使用できます
2. それ以外のアプリ：若干の改修が必要**

次に、2の改修が必要なアプリについて詳細を説明します。

2020/11追記：
**Firebaseに関しては、一部使えるSDKがありますので詳しくは以下の記事にて説明しました。**
[Google Play servicesが使えないAndroid端末におけるFirebase SDKの使用可否状況のまとめ](https://qiita.com/Kirin9000/items/bbb9f61fbef505e34423)

#どんな改修が必要なのか

**必要な改修は、GMSとfirebase関連のSDKをHMSのSDKに差し替えるか、あるいは既存のアプリにHMSのSDKを追加するかだけです。**

イメージ的にはこんな感じになります。
![ghsolution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674503/734c8094-1bca-b388-4955-cec44803fc60.png)

AOSPの部分は、HMS端末で継続的に使用できますので改修が不要で、HMSのSDKさえあればアプリはHMS端末で問題なく動きますのでHMS SDKが必須となります。

以上のように、HMS版アプリを開発するときにはおもに以下の2つのソリューションがあります。

**1. GMS SDKをHMS SDKに差し替える（G2H）
2. 既存アプリにHMS SDKを追加する（G+H）**

個人的には2のG+Hソリューションが非常に魅力的に感じていますので、G+Hソリューションについて紹介したいと思います。

##G+Hソリューションの特徴と実現方法
G+Hソリューションの特徴としては：
**Pros: 1つのパッケージで複数のプラットフォームに登録できます
Cons: パッケージのサイズが若干増えます**
が挙げられます。

実現方法の例として、GoogleとHuaweiが提供しているAPIで端末のGMS/HMSの状況を判別し、それぞれの場合に該当するAPIを使用すればGMS端末とHMS端末両方で問題かく動作できるようになります。

GMSが使えるかどうかの判定方法：

```java
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == com.google.android.gms.common.ConnectionResult.SUCCESS
```
HMSた使えるかどうかの判定方法：

```java
HuaweiApiAvailability.getInstance().isHuaweiMobileNoticeAvailable(this) == com.huawei.hms.api.ConnectionResult.SUCCESS
```
以上の判定方法を使用したG+Hソリューションのイメージ（GMSを優先的に使用する場合）：

```java
if(GMS avaliable){
    //元コード
}else if(HMS available){
    //HMSの場合のコード
}
```
この方法を採用することで、既存のAndroidアプリを若干修正することでGMS、HMS端末両方で問題なく使用できるアプリに改修できます。

#終わりに
この記事では、既存のAndroidアプリのHMS対応方法の概要を説明しました。詳細な改修方法について、今後簡単なデモアプリを用いて説明していきたいと思います。
ROSをcolconでビルドしたときにCLionでコード補完をする

# はじめに

ROSの開発では、C++を主に使いますが、みなさんはIDEを使用されているのでしょうか？わたしは、C++以外にもAWS lambdaではpython、AWS CDKではnode、業務アプリケーションでは、ScalaやSQLを書く必要があり、それらを1箇所で管理するために [JetBrains CLion](https://www.jetbrains.com/ja-jp/clion/) が非常に都合が良いため、購入して使用しています。

ROSのビルドをcatkinで行っていたときは、トップレベルにメタパッケージとなるCMakeファイルを配置すればコードの補完では問題ありませんでしたが、AWS Robomakerを使用するにあたってcolconでビルドする必要があり、これまでは `colcon build` して `install` 配下に生成されたパッケージ全てに対してCLionのCMakeオプションで `CMAKE_PREFIX_PATH` に全てのパスを追加して補完をしていましたが、カスタムメッセージが認識できなかったり、1つのCMakeをロードすると異なるパッケージの参照ができなくなり、複数同時に開発する時に効率を上げるのが難しい状態でした。

そのため今回は、`compile_commands.json`を生成し、こちらをCLionで読み込む方法をまとめました。

## colcon-cmakeの対応を調べる

ワークスペースレベルでの`compile_commands.json`の生成は、こちらのPRですでにマージされています。ただしこれは、`colcon-cmake >= 0.2.20` です。

https://github.com/colcon/colcon-cmake/pull/69

そのため、まずはすでにインストールしているcolcon-makeのバージョンを確認します。

```
$ pip3 list | grep colcon
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559128/16f65457-e902-ff49-3c47-f42e48275625.png)

バージョンが `0.2.19` のため、まずはこちらをアップグレードします。

```
$ sudo apt update
$ pip3 install --upgrade colcon-common-extensions colcon-ros-bundle
$ pip3 list | grep colcon
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559128/3af99e74-31b4-77c4-0586-2df04e1cfab7.png)

`0.2.25` になり使用することができるようになりました。

## CLionの設定

### clangdの設定

つぎにCLionのclangdの設定を確認します。2020.2より前のバージョンだと、ビルドインclangdバージョンの表記はありませんでした。

https://www.jetbrains.com/help/clion/settings-languages-cpp-clangd.html

ここでは、最新にアップグレードしました。

### CLionの最適化設定

最新にアップグレードすると、これまでの最適化設定が効かなくなっていましたので、下記を参考に設定します。

https://www.jetbrains.com/help/clion/performance-tuning-tips.html#speedup-indexing


## colconでビルドする

colconでビルド時に必要な設定は、CMakeのオプションをつけるだけです。

```
$ colcon build --cmake-args=-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON
$ ls -la build/compile_commands.json 
-rw-r--r-- 1 wnwn wnwn 31714  8月 24 13:14 build/compile_commands.json
```

これで`compile_commands.json`が生成されていることが確認できました。

## CLionのプロジェクト設定

次に生成した`compile_commands.json`をCLionのcompilation databaseに読み込みを行います。

https://www.jetbrains.com/help/clion/compilation-database.html#compdb_load

すでにプロジェクトを開いている場合は、一度閉じて生成した`compile_commands.json`を選択します。

このときプロジェクトルートが、build配下となってしまいますので、`src/my_project`に設定をします。

また、terminalのデフォルトパスもbuildになってしまいましたので、ワークスペース直下に設定しなおしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559128/ac99a421-9be3-0b6f-6fa0-85c56fc1be24.png)

この時にgitリポジトリも認識されなくなってしまったので、手動で再度認識させなおしました。

これでセットアップは終了です。

## コード補完の確認をする

すでに補完ができる状態になっているため、ファイルを開きます。これまでは複数パッケージをまたいで補完はできていませんでしたが、前述の設定でできていることを確認することができます。

また`compilation database`で`compile_commands.json`の自動読み込み設定が有効になっているため、colconで`--packages-select`を用いてビルドした場合は、ビルドしたパッケージだけの補完になっていることが確認できます。

## まとめ

* ROSをcolconでビルドした時にCLionでコード補完ができた
* ロボット開発をするときにいくつもの異なる言語やシステムをまたぐ必要があるため、CLionのようなIDEをうまく使うと開発効率を上げることができる
【Flutter/ Dart】外部アプリを起動して画像をシェアする方法

## 概要

共有（シェア）機能を実装するために試行錯誤した結果、採用した方法を記します。

## 結論
`esys_flutter_share `を使って簡単に実装できました。

ちなみに他に試したのは下記です。
- Platform Channelsを使ってネイティブのコードに処理を委譲（外部アプリを起動）する。
- shareプラグイン（画像のシェアができず断念）

## 設定

```.yml:pubspec.yaml
dependencies:
  esys_flutter_share: [version]
```

※`flutter pub get`を忘れずに

## コード

impportして

```.dart
import 'package:esys_flutter_share/esys_flutter_share.dart';
```

この2行だけで終わり！

```.dart
final ByteData bytes = await rootBundle.load('assets/image.png');
      await Share.file('タイトル', 'ファイル名', bytes.buffer.asUint8List(), 'image/png', text: '本文');
```

複数ファイルのシェアやHTTP経由で取得した画像のシェアも簡単にできるようです。

## 参考
[pub.dev](https://pub.dev/packages/esys_flutter_share)
PlayCanvasでの透視投影と平行投影のRayCastingについて

# PlayCanvasのRaycastingについて
PlayCanvasでレイキャストをどうやるのかとかは過去に書いているのでご参照を

[PlayCanvasのレイキャストについて知ってみる](https://qiita.com/sutobu000/items/3b105ca85f4152d59cb2)
[PlayCanvasのレイキャストをもっと見てみる](https://qiita.com/sutobu000/items/e9146a7d136ef5255ca2)


## PlayCanvasの透視投影と正射影法の切り替えについて
CameraのEntityを選択して、インスペクターからProjectionで選択可能
![スクリーンショット 2020-08-24 14.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/e40da24c-4de6-2439-4193-f4c1f69b7682.png)
画像の `Perspective` が透視投影のこと、 `Orthographic` が平行投影のこと



# 透視投影

PlaｙCanvasでRayCastingを行う場合、公式でもコードは提示されている。
https://developer.playcanvas.com/en/user-manual/physics/ray-casting/

しかし、これの通りにやれば通常できるが、これは透視投影のカメラの時だけっぽい。
上記のURLからコードを引用します。

```javascript
Raycast.prototype.doRaycast = function (screenX, screenY) {
    // The pc.Vec3 to raycast from (the position of the camera)
    var from = this.entity.getPosition();

    // The pc.Vec3 to raycast to (the click position projected onto the camera's far clip plane)
    var to = this.entity.camera.screenToWorld(screenX, screenY, this.entity.camera.farClip);

    // Raycast between the two points and return the closest hit result
    var result = this.app.systems.rigidbody.raycastFirst(from, to);

    // If there was a hit, store the entity
    if (result) {
        var hitEntity = result.entity;
        console.log('You selected ' + hitEntity.name);
    }    
};
```
(引用: https://developer.playcanvas.com/en/user-manual/physics/ray-casting/ )


# 平行投影

平行投影(Orthographic)で行いたい場合、上記のコードではできないので少し書き換える

```javascript
ClickJump.prototype.initialize = function() {
    ~~省略~~
    this.rayStart = new pc.Vec3();
    this.rayEnd = new pc.Vec3();
    ~~省略~~
};

ClickJump.prototype.doRaycast = function (screenX, screenY) {
    var farClip = this.entity.camera.farClip;
    var nearClip = this.entity.camera.nearClip;
    this.entity.camera.screenToWorld(screenX, screenY, nearClip, this.rayStart);
    this.entity.camera.screenToWorld(screenX, screenY, farClip, this.rayEnd);

    var result = this.app.systems.rigidbody.raycastFirst(this.rayStart, this.rayEnd);

    if (result) {
        var hitEntity = result.entity;
        console.log('You selected ' + hitEntity.name);
    }    
};
```

## ちょっとした備忘録でした
個人的に透視投影は3D感が強いけど、平行投影だと少し2D感が出て好きなのでよく使います。
その度にレイキャスト上手くいかなくて「どうやったっけ？」って毎度なっていたので備忘録にしました。

ちなみに平行投影のコードの書き方は、透視投影でも動くので普段からこっちの書き方にした方がいいかな
学習用データの水増し【ImageDateGenerator】

<h1>学習用データの水増し【ImageDateGenerator】</h1>
    from keras.preprocessing.image import load_img,img_to_array,ImageDataGenerator, array_to_img
    # import matplotlib.pyplot as plt
    from keras_preprocessing.image import list_pictures
    import os
    from PIL import Image

    # ---- 分類するクラス --- #
    classes = ["犬","猫","鳥"]

    # ---- 画像の大きさを設定 ---- #
    img_width, img_height = 1600, 1200

    # ---- ディレクトリ定義 ---- #
    DATA_DIR = [""] * len(classes)
    SAVE_DIR = [""] * len(classes)
    for i in range(len(classes)):
        DATA_DIR[i] = 'input/' + classes[i]
        SAVE_DIR[i] = os.path.join('output/', classes[i])  # 生成画像の保存先ディレクトリ
        if not os.path.exists(SAVE_DIR[i]):
            os.makedirs(SAVE_DIR[i])

    # 画像をロード（PIL形式画像）
    # img = load_img(IMAGE_FILE)

    # 貼り付け
    # plt.imshow(img)

    # 表示
    # plt.show()

    # 回転：-15~15
    # 上下平行移動:-0.8~1.2割の移動
    # 左右平行移動:-0.8~1.2割の移動
    # せん断:-5度~5度でせん断
    # 拡大縮小:0.8~1.2割で拡大縮小
    # 明度変更:-5.0~5.0の範囲で画素値に値を足す
    # 各画素値に値を足す:0.3~1.0の範囲で値を変更する

    datagen = ImageDataGenerator(
        rotation_range=15,
        height_shift_range=0.2,
        width_shift_range=0.2,
        shear_range=5,
        zoom_range=0.2,
       channel_shift_range=5,
       brightness_range=[0.3, 1.0]
    )

    for i in range(len(classes)):
        for picture in list_pictures(DATA_DIR[i]):
            img = img_to_array(load_img(picture, target_size=(img_height, img_width)))

            # numpyの配列に変換
            x = img_to_array(img)
  
            # 4次元配列に変換
            # x = np.expand_dims(x, axis=0)
            x = x.reshape((1,) + x.shape)

            # print(x.shape)

            g = datagen.flow(x, batch_size=1, save_to_dir=SAVE_DIR[i], save_prefix='out', save_format='jpg')
            for j in range(3):
                batches = g.next()

                # （1,縦サイズ, 横サイズ, チャンネル数)
                # print(batches.shape)
                # 画像として表示するため、４次元から3次元データにし、配列から画像にする。
                gen_img = array_to_img(batches[0])

                # plt.subplot(8, 8, i + 1)
                # plt.imshow(gen_img)
                # plt.axis('off')
dockerで「An HTTP request took too long to complete.」のエラー

## 問題

```
❯ docker-compose run --rm ほげ
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
```

## 解決方法

dockerを再起動する事で解決しました
ubuntu18.04でprocessingのvideoライブラリーが使えない

ubuntu18.04のprocessing3で、videoライブラリーが使えませんでした。

いろいろ調べると、ライブラリを↓に変えればＯＫとあったので入れ替えてみると、、

https://github.com/processing/processing-video/releases/tag/r6-v2.0-beta4


今度は、NullPointerExeptionが出てうまくいきませんでした。

もう少し調べてみると、下記のようにcameraデバイスの名前を入れてあげれば解決しました

```java:video.pde

  import processing.video.*;
  Capture video;

  setup(){
　  video=new Capture(this,width,height,"camera_device_name")
  }

```

cameraデバイスの名前は↓で取得できます

```java:camera_list.pde

  import processing.video.*;
  Capture video;

  setup(){
　  println(Capture.list());
  }

```
AWS Redshift Spectrumとviewの組み合わせのアクセス権限を調べる

公式ドキュメントにわかりやすい説明が見つからなかったので、実際にRedshiftを動かして試した結果をまとめました。試した結果なので、違ってたらごめんなさい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490207/2c021f22-4275-4529-12b6-fc54b09467e0.png)

図の中の3つのライン

1. 通常のRedshift内のtableにviewを通してアクセス（PostgreSQLでも同様）
2. Redshift Spectrumの外部スキーマのtableに直接アクセス
3. Redshift Spectrumの外部スキーマのtableにviewを通してアクセス


# 1. 通常のRedshift内のtableにviewを通してアクセス（PostgreSQLでも同様）

まず、DB userはviewへのSELECT権限が必要です。viewを作成したオーナーであればSELECT権限があります。viewを作成したのが別のDB userの場合は、オーナーを変更するかGRANTする必要があります。

次に、viewのオーナーはtableへのSELECT権限が必要です。tableを作成したオーナーであればSELECT権限があります。tableを作成したのが別のDB userの場合は、オーナーを変更するかGRANTする必要があります。

これらの条件を満たせば、DB userはtableへのSELECT権限を持っていなくても、viewを通すことでtableにあるデータにアクセスできます。

これはPostgreSQLでも同じです。


# 2. Redshift Spectrumの外部スキーマのtableに直接アクセス

DB userはSpectrumの外部スキーマのUSAGE権限が必要です。外部スキーマを作成したオーナーであればUSAGE権限があります。外部スキーマを作成したのが別のDB userの場合は、オーナーを変更するかGRANTする必要があります。


# 3. Redshift Spectrumの外部スキーマのtableにviewを通してアクセス

まず、DB userはviewへのSELECT権限が必要です。viewを作成したオーナーであればSELECT権限があります。viewを作成したのが別のDB userの場合は、オーナーを変更するかGRANTする必要があります。

次に、viewを参照するDB userは外部スキーマのUSAGE権限が必要です。外部スキーマを作成したオーナーであればUSAGE権限があります。外部スキーマを作成したのが別のDB userの場合は、オーナーを変更するかGRANTする必要があります。

1と2の事実からすると、3のケースでは、外部スキーマのUSAGE権限が必要なのはviewのオーナーだと思ったのですが、viewのオーナーは関係なくて、viewを参照するDB userが直接外部スキーマへの権限を必要とするようなんです。

そうなのか。。。
【Postgres】timestamp型のデータを登録されている日から1年後の日付で更新する

自分用のメモ用です。
timestamp型のデータを登録されている日から1年後の日付で更新する。

#■やり方

```sql
update hogetable set created_at = created_at + '1 year';
```
1年前の場合は`-1 year`としてあげれば良い。
Nヵ月前、後も同様で`year`を`month`にしてあげればよい。
もうちょいめんどいかなと思ったけど、PHPのstrtotimeみたいな融通の利くpostgresちゃん。
npm install --save firebase で発生したエラーの回避法

記事執筆時点で安定版のfirebase 6.2.4をインストールを試みたところ以下のエラーが出ました。

```
$ npm install --save firebase@6.2.6
:
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! grpc@1.20.3 install: `node-pre-gyp install --fallback-to-build --library=static_library`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the grpc@1.20.3 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/yokoyamaryouta/.npm/_logs/2020-05-10T05_49_16_325Z-debug.log
```



###結論
安定版で実行したらインストールできました。以下から確認＆試してみて下さい。

```
$ node -v
v14.8.0 //筆者の場合
```

[こちら](https://nodejs.org/ja/ "node") から確認＆インストールできます。
安定版インストール後に再度実行したらいけました。

```
$ node -v
v12.18.3 //執筆時
$ npm install --save firebase@6.2.6
```
LaravelのEloquentModelクラスを自動生成する

始まったばかりのLaravelのプロジェクトでは、移行元のある案件なので既存のデータベースをそのまま使います。
というときに、既存のテーブルから Laravel の Eloquent Model クラスを自動生成したときの作業記録です

こちらのライブラリを追加いました（読み方・呼び方不明です）
https://github.com/reliese/laravel

## composer でライブラリを追加

```sh
composer require --dev reliese/laravel
```

このとき、 `killed` と表示されたらメモリ不足を疑ってみてください。
Dockerで開発環境を作っているならばこちらに書いた方法で対処できました。

Docker内でcomposer require したらkilledになったときの対応
https://qiita.com/makies/items/3e1064f17a18df750cad


## パッケージを追加

AppServiceProvider に追記します

```php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Reliese\Coders\CodersServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // 追記ここから
        if ($this->app->environment() === 'local') {
            $this->app->register(CodersServiceProvider::class);
        }
        // ここまで
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

```

## 設定ファイルを作成

設定ファイルが `config/models.php` に生成されます。
configは一旦削除しておいたほうが良さそうです

```sh
php artisan vendor:publish --tag=reliese-models
php artisan config:clear
```

## モデルファイル生成

```sh
php artisan code:models
```

DBにあるテーブルに対するModelファイルが生成されます。
デフォルトで `app/Models` 以下に生成されます。

`config/models.php` で、出力先や親クラスなどを指定することができます。

### 生成されない場合

生成されない場合 DBのテーブルが存在しているかを確認しましょう
DBデータの永続化していない場合、DBコンテナを再起動するとデータベースが消えてしまいます。
**migrationを流してから** 再実行してください。


## 生成されるコード

- クラスプロパティ（=テーブルのカラム）
  - `@property` でクラスのdocコメントに記述
- $table テーブル名
- $primaryKey プライマリキー
- $incrementing プライマリキーをインクリメントするかどうか
- timestamps タイムスタンプを自動更新するカラム
- $casts 型を自動キャストするカラム
- $dates Carbonに自動変換するカラム
- $fillable 書き込み可能なカラム
【Rails6】resourcesメソッドを使ってdestroy

###はじめに
resourcesメソッドってRESTfulな開発には必須だと思うんですよね〜（言いたいだけ）

resourcesって実際の中身を普段目にしなくて実際どんなパスが通っているかわかりにくいなと思ったので学習しました！

今回はたまたま僕が実装しようとしているdestroyを中心に書きます！削除ボタンの実装にどうぞ！

###resoucesメソッドのルーティングの確認

```ruby:routes.rb
Rails.application.routes.draw do
  resources :tweets :only => [:destroy]
end
```
普通destroyだけ設定なんてなかなかないとおもいますが、

ターミナルにて、`rake routes`を実行するとルーティングが確認できます！

```
tweets 　DELETE /tweets/:id(.:format) 　tweets#destroy  
``` 
これで設定できているパスは以下のとおりです

| URL                       | アクション | HTTPメソッド | 名前付きパス(_path)   | 名前付きパス(_url) | 対応するパス      |
|:--------------------------|:--------|:----------|:------------------ |:-------------------|:------------------|
| /tweets/:id(.:format)      | destroy | DELETE    | tweet_path(id) | tweet_url(id) | /tweets/:id |  

### 削除ボタン実装の例
```
  <%= link_to "削除", tweet_path(○○変数名.id), method: :delete , data: { confirm: "削除しますか？"} %>
```
変数名のところは時と場合によると思います！（要は削除したいレコードのidが取得できたらOK）

以上です〜
「時系列分析と状態空間モデルの基礎」(隼本)をpystanで実装してみた

## やったこと

- **「時系列分析と状態空間モデルの基礎 RとStanで学ぶ理論と実装」のstanの章のコードをpystanを用いて実装した**

## この記事の対象者
- **時系列分析を知りたくて隼本を読んだけどpythonしかわからない！pythonで書いてくれ！という人**

## はじめに
時系列分析の入門書で調べると必ず出てくるのが「時系列分析と状態空間モデルの基礎 RとStanで学ぶ理論と実装」，いわゆる隼本です。
この本では，「ARモデル，MAモデルといった時系列分析」，「ガウス線形状態空間モデル」「ベイズ推定による状態空間モデル」について非常に噛み砕いて説明されています。
**本の中で使用されているのはR言語とstan言語であり，pythonしか使えない筆者のような人間にとってはそれが少し痛手です。**

しかし，pythonでもstanを使用することも可能なので，本で紹介されていることと同じことが実装可能です。
**そこで実際にpythonを用いて，隼本のstanによるベイズ推定を実装したので紹介します。**

実装はgoogle colabを用いて行っています。google colabではpystanがimportするのみで使用可能です。つまり初期設定がいりません，非常に便利です。
**コードはこちらから。**
**https://github.com/nakanakana12/hayabusa-bon**

## 実装結果
コードはgithubを参照していただくとして，ここでは簡単に結果のみを紹介します。

### Stanによるローカルレベルモデルの推定

ローカルレベルモデル(ランダムウォークにノイズが加わったもの)の状態空間を推定した結果が下記になります。
![ダウンロード (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/f4b60d61-84fe-acd7-8863-76cc38c70ee7.png)

青が状態，オレンジが観測値です。stanを用いて推定した状態の95%区間が青網になります。本のグラフと比べると正しく実装できていそうです。

### 応用:複雑な観察方程式を持つモデル

次の章では，もう少し複雑な方程式をモデリングしています。
青線が観測値，オレンジ線が過程誤差がない場合の値になります。こちらも正しく実装できています。
![ダウンロード (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/fed440f1-76f7-5b4d-1d0d-25ad519a887a.png)

## まとめ

- 隼本のstan部分をpythonを用いて実装した。
- 本の結果と比較して正しく実装できていそうなことを確認した。

少しでも皆さんの役に立てれば幸いです。

## 参考サイト
- 隼本サポートページ:https://logics-of-blue.com/tsa-ssm-book-support/
- Rとstanのコードとデータ:https://github.com/logics-of-blue/book-tsa-ssm-foundation
rails実行時のエラー”warning: already initialized constant FileUtils::VERSION”

初めてみた内容だったので、備忘録として記録します

##概要

`rails s`を実行すると以下の様な文が出る様になった↓

```
rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils/version.rb:4: warning: already initialized constant FileUtils::VERSION
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:105: warning: previous definition of VERSION was here
/Users.rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils.rb:1267: warning: already initialized constant FileUtils::Entry_::S_IF_DOOR
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:1284: warning: previous definition of S_IF_DOOR was here
rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils.rb:1540: warning: already initialized constant FileUtils::Entry_::DIRECTORY_TERM
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:1568: warning: previous definition of DIRECTORY_TERM was here
rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils.rb:1595: warning: already initialized constant FileUtils::OPT_TABLE
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:1626: warning: previous definition of OPT_TABLE was here
rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils.rb:1649: warning: already initialized constant FileUtils::LOW_METHODS
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:1685: warning: previous definition of LOW_METHODS was here
rbenv/versions/2.6.0/lib/ruby/2.6.0/fileutils.rb:1656: warning: already initialized constant FileUtils::METHODS
rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/fileutils-1.4.1/lib/fileutils.rb:1692: warning: previous definition of METHODS was here
```



##原因
調べてみると、fileutilsgを複数回読み込むエラーのよう


##解決策
```
gem uninstall fileutils
```

```
gem update --default
```

これでエラーが消えました！
[Rails]Faradayのミドルウェアを使ってみる

Faradayのミドルウェアを使ってみたので簡単にまとめます。

##Faradayとは？
rubyで書かれたHTTPクライアントライブラリであり、
これを利用してRailsプロジェクトから外部APIにアクセスすることができます。


##Faradayのミドルウェアとは？
Faradayにはリクエストやレスポンス処理についてカスタマイズできるミドルウェアがあります。
RequestミドルウェアとResponseミドルウェアの２つがあり、これを利用することによってリクエスト時の認証情報を付与したり、通信についてログに書き出すことができます。

シンボルを使って以下のように使うことができます。

```api_client.rb
Faraday.new(url: 'https://test.com') do |builder|
  # ミドルウェアを使用する
  builder.request :url_encoded
  builder.response :logger, Config.logger if Config.enable_logger
end
```

#Requestミドルウェアについて
Requestミドルウェアはリクエスト送信前にリクエストの詳細を設定することができます。
ここでは２つのミドルウェアを紹介します。
認証ミドルウェアはAuthorizationヘッダーの設定ができ、
UrlEncodedミドルウェアはキーと値のペアのハッシュをURLエンコードされたリクエスト本文に変換することができます。

使用例

```api_client.rb
# 認証ミドルウェア
builder.request :basic_auth, "username", "password"
builder.request : authorization :Basic, "aut_key"

# UrlEncodedミドルウェア
builder.request :url_encoded
```


#Responseミドルウェアについて
responseミドルウェアはレスポンスを受け取る際にレスポンスの詳細を設定することができます。
ここではLoggerミドルウェアを紹介します。
Loggerミドルウェアを使うと、リクエストとレスポンスの本文およびヘッダーをログに出力することができます。
またフィルター機能もあり、正規表現を利用して機密情報をフィルタリングすることができます。

使用例

```api_client.rb
# Loggerミドルウェア
builder.response :logger
# フィルター
builder.response :logger do | logger |
  logger.filter(/(password=)(\w+)/, '\1[REMOVED]')
end
```

#faraday_middlewareを使うとさらに便利！
faraday_middlewareというgemをいれると使えるミドルウェアがさらに増えます。

例えば、ParseJsonクラスを使って、parser_optionsとcontent_typeを指定すればハッシュキーをシンボルにしてJSONパースすることもできます。

使用例

```api_client.rb
builder.response :json, parser_options: { symbolize_names: true }, content_type: 'application/json'
```


##参考ドキュメント
https://lostisland.github.io/faraday/
https://lostisland.github.io/faraday/middleware/list
コンポーネント内部での画面遷移 Vue.js備忘録 vol.02

##はじめに
前回に引き続き、vue.jsを触ってみて詰まった所などを備忘録としてまとめてみます。

##Vue.js（SPA）におけるブラウザバック問題

SPAでの実装に慣れている方からすると初歩的なミスかもしれないが…
このような画面遷移を行なっていた時 `/hoge`⇨`/fuga`⇨`/fuga?page=2`
ブラウザバックを行うと `/fuga?page=2`から`/hoge`に戻ってしまっていた。

###考えられる原因
ページネーションでの遷移が`history.replaceState()`だった（現在の履歴エントリーを新しい履歴エントリーに置換する設定）
`history.pushState()`にしたらいけるのでは！？！？

###history.pushStateにしたものの…
URLは`/fuga?page=2`⇨`/fuga`へ変わるが、画面が再描画されない！！
今回作成していたページはAPIを叩いて一覧表示していたため、URLのパラメータの変更を検知して再度APIを叩く処理を書く必要がありました。

##対処
`/fuga`⇨`/fuga?page=2`や、`/fuga?page=2`⇨`/fuga`への遷移は同じコンポーネントを描画するため、同じコンポーネントインスタンスが再利用されます。古いインスタンスを破棄し、新しいものを生成するよりは効率的なのですが、同時にコンポーネント自体のライフサイクルが呼ばれないことも意味しています。
上記の問題を解消するためにvue-routerのナビゲーションガードを使用しました。
`beforeRouteUpdate`でパラメータの変更を検知できます。


```index.js
 beforeRouteUpdate (to, from, next) {
    // ルート変更に反応する
    if(to.query !== from.query){
      this.research(to.query.page);//APIを叩く処理
    }
	next();
  }
```
パラメータの変更を検知し、再度APIを叩く処理を入れることで解消することができました！

##最後に
今回は初歩的なミスではありましたが、もし同様のことでお困りでしたら参考になればと思います。
もしこれより良い方法などあればぜひ教えてください！
（vue-routerの公式にしっかり説明が書いてあったのでちゃんと読んでおけばよかったな〜）

[Vue-Router 動的ルートマッチング](https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html)
【Nuxt.js】Nuxt実践編：v-model + Vuex + firebase

🎈 この記事はWP専用です
https://wp.me/pc9NHC-yW

# 前置き
v-modelで直接storeを書き換えて
それをfirebaseへ送信してみます📤

ですが実際に使う場面はほぼありません😂笑

というのも、
firebaseを使って入力した値を送信さえできれば良いからです。
取得も簡単にできるので
わざわざVuexを使ってstoreに保存する必要がないのです…！

なので
仕組みを見て「ふーんなるほど💡」と
分かってもらえたら良いなと思います🍒👌

v-model, computed, vuex, firesbase(firestore)の
解説記事を読んだ方なら、
当たり前じゃん❗️
と思うかもしれません！
それぞれの解説記事もあるので
リンクを貼っておきます🎈🧸

⬇️解説記事はこちら
v-model: https://wp.me/pc9NHC-kI
computed: https://wp.me/pc9NHC-wY
Vuex: https://wp.me/pc9NHC-gl　https://wp.me/pc9NHC-dH
firestore: https://wp.me/pc9NHC-g4

# 完成コード
まずは完成コードからお見せしちゃいます🌟
この後に、ここに至るまでの考え方などを書いていきます。
そちらを見ながらやってみてください🔥💪

firestoreとの連携などは前置きリンクからご覧ください👀

```plugin.firebase.js
import firebase from "firebase/app"
import 'firebase/firestore'

if (!firebase.apps.length) {
 firebase.initializeApp({
  apiKey: "貼り付け",
  authDomain: "貼り付け",
  databaseURL: "貼り付け",
  projectId: "貼り付け",
  storageBucket: "貼り付け",
  messagingSenderId: "貼り付け",
  appId: "貼り付け",
  measurementId: "貼り付け"
 })
}

export default firebase
```

```index.vue
<template>
<div class="page">
  <input
    type="text"
    v-model="name"
  >
  <input
    type="text"
    v-model="email"
  >
  <p>{{ name }} {{ email }}</p>
  <button @click="submit">submit</button>
</div>
</template>

<script>
export default {
 computed: {
  name: {
    get() {
      return this.$store.getters['name']
    },
    set(value) {
      this.$store.commit('updateName', value)
    },
  },
  email: {
    get() {
      return this.$store.getters['email']
    },
    set(value) {
      this.$store.commit('updateEmail', value)
    },
  },
 },
 methods: {
  submit () {
    this.$store.dispatch('submit')
  }
 },
}
</script>
```

```store.index.js
import firebase from '@/plugins/firebase'

export const state = () => ({
 name: "名前",
 email: "email",
})

export const getters = {
 name: state => {
  return state.name
 },
 email: state => {
  return state.email
 },
}

export const actions = {
 submit ({ state }) {
  const db = firebase.firestore()
  let dbUsers = db.collection('users')
  dbUsers
    .add({
      name: state.name,
      email: state.email,
    })
    .then(ref => {
      console.log('Add ID: ', ref.id)
    })
 },
}

export const mutations = {
 updateName(state, newName) {
  state.name = newName
 },
 updateEmail(state, newEmail) {
  state.email = newEmail
 },
}
```

# 経緯
それでは解説をしていきます💡

🎈 続きはWPでご覧ください👀
https://wp.me/pc9NHC-yW
Pythonのinput関数活用の備忘録メモ

筆者がPythonを勉強する為に読んだ書籍[入門 Python3](https://amzn.to/2YJVuLt)では、なぜか標準入力関数の解説が掲載されていませんでした。:scream: ただ、使ってみると大変便利な関数なので活用方法を備忘録として残しておこうと思います。

# 最も基本的な使い方
最も基本的な利用方法は以下の通りです。実行すると標準入力(通常はキーボード)からの入力待ち状態となります。変数xに代入したい内容を入力し、最後にReturnを入力すると入力内容がxに代入されます。

```python:入力例
>>> x = input()
5
>>> print(x)
5
```

## 入力を促すメッセージを表示
入力を促すメッセージを表示させることも可能です。表示させたい内容をinput関数の引数として渡します。

```python:入力例
>>> x = input("数値を入力: ")
数値を入力: 2
>>> print(x)
2
```

# 整数として取り出す
まずはinput関数の戻り値の型を見てみます。文字列型(str)と出力されます。

```python
>>> x = input()
2
>>> print(type(x))
<class 'str'>
```

整数として取り出す場合はint関数(浮動小数点の場合float)を用いてキャストします。

```python:入力例
>>> x = int(input())
2
>>> print(type(x))
<class 'int'>
```

# 複数の値を一度に入力
## 基本は文字列
複数の値を一度に標準入力から入力したい場合は多々あります。複数の値をスペース区切りで入力した場合以下の様に変数に代入されます。

```python:入力例
>>> x = input()
2 3 4
>>> print(x)
2 3 4
```
## 文字列を分解して複数の値の取り出し

これは複数の値をスペースで連結した文字列として代入されています。故に以下の様に内包表記を用いれば複数の値が一度に取り出せます。(int関数でキャストし、整数型として取り出しています。）

```python:入力例
>>> x, y, z = (int(x) for x in input().split())
2 3 4
>>> print(x, y, z)
2 3 4
>>> print(type(x), type(y), type(z))
<class 'int'> <class 'int'> <class 'int'>
```
## リストに変換

以下の様にするとリストとして代入できます。

```python:入力例
>>> x = input().split()
2 3 4
>>> print(x)
['2', '3', '4']
```

この場合、文字列のリストになってしまいます。整数値のリストとする為に、リスト内包表記を用います。

```python:入力例
>>> x = [int(x) for x in input().split()]
2 3 4
>>> x
[2, 3, 4]
```
## if文との組み合わせ

enumerate文とif文を追加すると取り出す値の個数を制御出来ます。

```python:入力例
>>> x = [int(x) for i, x in enumerate(input().split()) if i < 3]
1 2 3
>>> print(x)
[1, 2, 3]
>>> x = [int(x) for i, x in enumerate(input().split()) if i < 3]
1 2 3 4
>>> print(x)
[1, 2, 3]
```

 # Reference
* [Pythonで複数の値を入力する方法](https://qiita.com/863/items/b970d2f376c1e16c921b)
ララベルで背景色を２色にする方法

###背景色などを２色にする方法を紹介していきたいと思います![スクリーンショット 2020-08-24 11.30.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696811/6fdec926-9c45-dfcf-f7b8-b9b60dd5fb4f.png)


それでは書き方を紹介していきます（今回はLaravelを使っています）

```navbar.blade.php
<nav class="navbar navbar-expand-sm navbar-dark" 
style="background :linear-gradient(to top, #330000 0%, #660000 100%);">
```
・background :linear-gradientを使用します（classのとこは気にしないでください）
・色の指定は()の中身でしています
この場合ではto topなので下から上にかけて色が変化します　
上の画像がこのパターンですね

```nabar.blade.php
<nav class="navbar navbar-expand-sm navbar-dark" 
style="background :linear-gradient(to top, #330000 0%, #330000 50%, #660000 50%, #660000 100%);">
```
このように0％〜50％、50％〜100％にすると２色をくっきり分けることができるので便利です！
国旗などを表現したいときにいいですね！

今回はto topを紹介しましたが
・to top 下から上へ
・to right　左から右へ
・to left　右から左へ
・to bottom　上から下へ
これらで方向の指定が可能となります

###今回のまとめ

今回は背景色の２色について紹介しました
上記はnavタグを使用していますが他のタグでも試してみてくだい！
【Unity】 iOSのLaunchScreenにStoryboardを使う方法

iOSのLaunch Screenの設定方法はいくつかありましたが、iOS13以降のApp Storeに提出されるすべてのAppは、Storyboardを使う必要があるようです。
[App StoreにiPhone Appを提出する：Apple公式](https://developer.apple.com/jp/news/?id=03042020b)

UnityではすでにStoryboardに対応していて、**Unity 2019.3以降では、Storyboardが自動生成できる**ようになりました。ただ、設定方法が少しトリッキーでハマってしまったので、設定方法をメモしておきます。

#LaunchScreenにStoryboardを使う方法
まず、Unityの「Project Settings」→「Player」の「Splash Screen」の項目を開きます。
デフォルトでは色々チェックが入っていますが、チェックをすべて外して、下の状態にします。
「Use Storyboard for Launch Screen」にチェックを入れたい衝動に駆られますが、それはワナです。気をつけて。
![スクリーンショット 2020-08-24 13.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/8a832e43-da96-efac-a6a9-9f11de59a15c.png)
「Launch screen type」の項目で、下記のどちらかを選択するとLaunch Screenに表示する画像を指定できます。

| Launch screen type | 説明 |
|:--|:--|
| Image and background(relative size) | スクリーンに合わせて画像が引き伸ばされます。 |
| Image and background(constant size) | 画像サイズを指定できます。 |

現時点では「Custom XIB」も選択できますが、将来的には非推奨になると思われます。
![スクリーンショット 2020-08-21 17.37.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/233f17a8-5b13-f765-7dc3-13b08b5c309c.png)
適当なLaunchScreen用の画像を入れました。
この設定でビルドすると、Storyboardが自動生成されます。
##Image and background(relative size)
全画面を使うスプラッシュに良さそう。
![スクリーンショット 2020-08-21 17.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/02bcaadc-44a7-5e74-e66a-57c20cd22b12.png)
##Image and background(constant size)
Appアイコンを使う場合は、こっちが良さそう。
![スクリーンショット 2020-08-21 18.08.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/11edb0a4-b132-4c7f-5c76-045ca6382aa1.png)
やり方が分かると、とても簡単ですね。

#ハマりどころ
私がハマったのは、上記にあった**「Use Storyboard for Launch Screen」**です。
UnityがStoryboardファイルを自動生成してくれるのかと思いチェックを入れたのですが、ビルドエラーが出るようになりました。
![スクリーンショット 2020-08-24 13.18.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/0f0a0cbf-acca-7712-3d34-2f08650c55ab.png)

```C#:
ArgumentException : source
Parameter name: The source path cannot be empty.
```

調べてみると、これは**「Xcodeで作ったStoryboardファイルを使う」**という項目で、Storyboardファイルの指定が必須だったようです。うーん、これは分かりづらい。

ハマる人が大量発生しそうなので、改善してほしいですね。
pythonで入力した値の約数を調べる

#はじめに
約数を求めるプログラムコードのメモとしての記述です。

##プログラムコード

```python
div = []
num = int(input())
if num >= 2:
    for j in range(num):
        if num % (j + 1) == 0:
            div.append(j + 1)
    else:
        print(div)
```
###簡単な説明
入力した値を`for`文のループ処理で割っていき、割った時のあまりが`0`の場合のみを配列に追加している。最後に配列を出力する。

##実行結果

```
入力値
28

出力値
[1, 2, 4, 7, 14, 28]
```
tensorfow を使い複数入力、複数出力を持つモデルの作成方法(mulitple input , output)

#multiple input, outputとは
##### multiple inputとは
全く違うデータ、あるいは形状の違うデータを一つのモデルに入力する、入力層自体が複数あるモデルを言います。
##### multiple outputとは
multiclassのように出力層に複数の出力を持つのではなく、出力層がそもそも複数あるモデルを言います。

# modelの定義部
modelの定義の際に気をつけなければいけないところは、複数の入力が結合するlayerの形状と、複数の出力が分岐される箇所のlayerの形です。当たり前と言えばそれまでですが、ミスしやすいところだと思います。
書き方的には単純なモデルと同じにできるのでこの部分のコードは省きます。

# from tensorflow.keras import Model の部分
次に詰まるのはmodelの宣言だと思います。multiple input output modelの宣言は以下のようにすれば可能です。

```python
model = Model(inputs=[input_1,input_2], outputs=[output_1,output_2])
```

リスト形式で宣言することができます。

今回の場合の入力層

 + input_1
 + input_2

今回の場合の出力層

 + output_1
 + output_2

# compile 部分の書き方
compileではlossと、metricsにおいて各出力層ごとに別の関数を割り当てることができます。

```python

model.compile(optimizer='adam', 
              loss={"output_1":"mse","output_2":"categorical_crossentropy"}, 
              metrics={"output_2":"acc"})
```
lossもmetricsもdict形式で与えてやることでcompile可能です出力層の指定にはnameを使うのでmodel定義の際にnameを決めてやる必要があります。


# 学習の書き方
compile同様にdict形式で各層ごとに別のものを与えてやることができます。

```python

model.fit(x = {"input_1":x_train_1,"input_2":x_train_2},
          y={"output_1":x_train_1,"output_2":y_train}, 
          epochs=10000, 
          batch_size=8, 
          shuffle=True, 
          validation_data=({"input_1":x_val_1,"input_12":x_val_2}, {"output_1":x_val_1,"output_2":y_val}), 
          callbacks=[early_stopping]
         )
```

# predictの際の注意点
predictをする際には出力は当たり前ですが定義した出力層の数だけ出てきます。そのため返り値を受け取る変数はその分用意しなければならないわけです。(例 : 出力層が2種類の場合は2つの変数が必要)
入力もdict形式で与えてやる必要があります。

```python

pred_1 ,  pred_2 = model.predict({"input_1":x_test_1,"input_2":x_test_2})
```

###### 以上でmultiple input outputなmodelの作成方法となります。
iframeのsandbox属性の動的設定

## sandbox属性とは

sandbox属性とはiframe内の要素に対し制約を設定する機能です。
iframe内でjavascriptの実行を無効などすることができます。
属性は以下のような形式で設定することができます。

```html
<iframe sandbox="allow-forms allow-scripts"></iframe>
```

※設定できる属性については[MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe)を参照。

## 動的設定方法

sandbox属性は属性を変更するだけでは反映されません。sandbox属性の変更を反映させるには、フレームを再読み込みする必要があります。

```html
<iframe src="frame"></iframe>
```

```javascript
const iframe = document.getElementById('frame');
iframe.sandbox.add("allow-top-navigation");     // この段階では反映されない。
iframe.contentWindow.location.reload();         // ここで反映される。
```

## まとめ

如何でしたでしょうか？今回はiframeのsandbox属性の動的設定方法についてまとめて見ました。
今回この記事を作成した理由ですが、sandbox属性を使用する機会があり、属性値を変更したにも関らす、反映され無くてつまったことがあったので作成しました。

記事に間違いや追加してほしい事がありましたら、コメントにご記入ください。
両端からフェードアウトしていくカーテンみたいなアニメーションをcssとjsで作成

右端からフェードアウトしていく風のものはあったのですが両端からは見つからなかったので自作。
白いボックスを両端から出して背景を覆い隠しているだけです。

```CSS
#loading {
  width: 100vw;
  height: 100vh;
  transition: all 1s;
  background-color: #274bd2;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
}
        
.fadeout {
    display: none;
}
      
#left_bk,#right_bk {
    width: 0;
    height: 100vh;
    background-color: rgba(255,255,255,0.8);
    border: none;
    position: absolute;
    top: 0;
    z-index: 2;
}       

#line {
    width: 3px;
    height: 100vh;
    background-color: #274bd2;
    border: none;
    position: absolute;
    top: 0;
    left: 47.5vw;
    z-index: 3;
}
#left_bk {  left: 0; }

#right_bk { right: 0; }

.anime5 {
    animation: animemove5 0.3s linear forwards; } /*1.5sかけて*/

.anime7 {
    animation: animemove7 1.5s linear forwards; } 

@keyframes animemove5 {
    0% {}
    100% {width: 50vw;} /*50vwまで拡大*/
}

  @keyframes animemove7 {
    0% {}
    100% {left: calc(100% - 54px);}
}

```

```js
const body = document.getElementsByTagName('body')[0];

function fadeOut() {
    left_bk.classList.add('fadeout');
    right_bk.classList.add('fadeout');
    loading.classList.add('fadeout');
}

window.onload = function() {
    setTimeout(cartain, 700);
    setTimeout(blueline, 1000);
    setTimeout(fadeOut, 2000);
};

function cartain() {
    left_bk.classList.add('anime5');
    right_bk.classList.add('anime5');            
    $("#loading").animate({ opacity: 0 }, { duration: 500, easing: 'linear'});       
}

function blueline() {
    line.classList.add('anime7');     
}
```

```html
<div id="loading">
    <div id="left_bk"></div>
    <div id="right_bk"></div>
</div>
    <div id="line"></div>

    <script src="loading.js"></script>
```
JSON.stringifyで`TypeError: Converting circular structure to JSON`というエラーが出た時の対処法

オブジェクトをJSON.stringifyしたときに、循環参照が含まれていると以下のようなエラーが出ます。

```js:コード
const a = { a1: "test" };
a.aa = a;
JSON.stringify(a);
```

```bash:実行結果
JSON.stringify(a);
     ^

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    --- property 'aa' closes the circle
    at JSON.stringify (<anonymous>)
```

# 対処法
json-cyclicを使えば解決します。

> json-cyclic - npm
> https://www.npmjs.com/package/json-cyclic

```bash

npm install json-cyclic
```

```js:コード
const { decycle, encycle } = require('json-cyclic');

const a = { a1: "test" };
a.aa = a;
console.log(JSON.stringify(decycle(a)));
```

```json:実行結果
{"a1":"test","aa":{"$ref":"$"}}
```

json-cyclicは、内部で循環参照を検出したとき、復元ができるようにタグ付けを行い、参照を削除する仕組みです。

オブジェクトを復元したい場合は以下のように`encycle`を使います。

```js:コード
const { decycle, encycle } = require('json-cyclic');

const a = {a1: "test"};
a.aa = a;
const json = JSON.stringify(decycle(a));

const obj = JSON.parse(json);
const b = encycle(obj);
console.log(b);
console.log(b.aa.aa.aa.a1);
```

```bash:実行結果
{ a1: 'test', aa: [Circular] }
test
```

ちゃんと復元できることが確認できました。
[tensorflow , keras , mnist] mnistのデータから各ラベルごとにn枚ずつ取り出し10*n枚のデータを作成する

# 前置き
なぜわざわざデータ量を少なく取りたいのか

 * データ量が少ない場合にも良い精度が出るモデルを考えたいため
 * 各ラベルごとに偏りをなくしたいため

# コード
[github](https://github.com/kzrn3318/mnist-sapling-each-label)
mnistのロードを行う

```python
(x_train, y_train), (x_test, y_test) = mnist.load_data()
```
y_trainをpandasのdataframeに一度格納し、そこからdataframeを分割、indexを取り出す。という流れでn=100で取り出します。

```python
#各label100枚ずつ足りだすためのコード、pandasを用いて行う
df = pd.DataFrame(columns=["label"])
df["label"] = y_train.reshape([-1])

list_0 = df.loc[df.label==0].sample(n=100)#n=100でsampling
list_1 = df.loc[df.label==1].sample(n=100)
list_2 = df.loc[df.label==2].sample(n=100)
list_3 = df.loc[df.label==3].sample(n=100)
list_4 = df.loc[df.label==4].sample(n=100)
list_5 = df.loc[df.label==5].sample(n=100)
list_6 = df.loc[df.label==6].sample(n=100)
list_7 = df.loc[df.label==7].sample(n=100)
list_8 = df.loc[df.label==8].sample(n=100)
list_9 = df.loc[df.label==9].sample(n=100)

label_list = pd.concat([list_0,list_1,list_2,list_3,list_4,list_5,list_6,list_7,list_8,
                       list_9])
label_list = label_list.sort_index()
label_idx = label_list.index.values

train_label = label_list.label.values

"""
x_trainからlabel用のdataframe.indexを取り出すことでlabelに対応したデータを取り出す。
"""
x_train = x_train[label_idx]
y_train= train_label
x_train = x_train / 255
x_test = x_test / 255
```
これで各ラベル100枚ごとにサンプリングできました。
Linuxコマンド備忘録

# Linxuコマンド備忘録
本記事は目的別にlinuxのコマンドを使った解決法を紹介する初心者向けの記事である。

## linkからデータをダウンロードしたい。
[pytorchの転移学習のチュートリアル](https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html)のミツバチとアリの画像データをサーバにダウンロードする。
![スクリーンショット 2020-08-24 12.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548975/60bae6eb-f78a-9d32-f2cb-20542b132413.png)
1. 上のリンクのオレンジのhereを右クリックでリンクをコピー
2.以下のコマンドを実行

```bash

$ wget https://download.pytorch.org/tutorial/hymenoptera_data.zip
```
ちなみに```wget -r``` とすると再帰的にダウンロードすることができる。
再帰的ダウンロードとはリンク先にディレクトリがあったら、そのディレクトリの中身に入り、その中身のファイルを一つ一つダウンロードするような、リンク先以下のディレクトリに存在するファイルをすべてダウンロードするようなことである。
nuxtjsでwebpackのcacheGroupsを使ってJavaScriptとcssの分割方針を変える

Webページの高速化のする手法の一つにJavaScriptやcssなどのアセットを小さくして、細かいファイルにしてCDNにアップロードするというものがあります。

HTTP/2では1つのコネクション上で複数並列に扱うことができるので、ファイルを一つにまとめて通信回数を減らすより、ファイルサイズを小さくして平行に複数ファイル取得するほうが有利です。

nuxt.jsでは`nuxt.config.js`ファイルのbuild部分がそのままwebpackの設定となるので、ここに設定を追加していくことでwebpackの設定を変更しビルドの方針を変えることが出来ます。

# 全部一つのファイルにまとめる場合

```nuxt.config.js
{

  ... (省略) ...

  build: {
    optimization: {
      cacheGroups: {
        styles: {
          name: 'styles',
          minChunks: 1, // 1箇所以上で使われていたらlibraryとしてchunkに含める
          chunks: 'all'
          enforce: true // ファイルサイズの制限を無視してchunkをまとめる
        }
      }
    }
  }
}
```

この設定では1箇所以上で使われているファイルをビルド後のファイルサイズを無視してchunkに含めるということになるので、全てのコードが1つのchunkに詰め込まれて同じファイルになります。当然ファイルは大きくなります。

# ファイルを複数に分割する場合

```nuxt.config.js
{

  ... (省略) ...

  build: {
    optimization: {
      cacheGroups: {
        styles: {
          name: 'styles',
          minChunks: 5, // 5箇所以上で使われていたらlibraryとしてchunkに含める
          chunks: 'all'
          enforce: false // ファイルサイズの制限をできるだけ守るように分割する
          minSize: 30000, // 30kbを超えるようにファイル分割する
          maxSize: 1000000, // 100kbを超えないようにファイル分割する
        }
      }
    }
  }
}
```

このように設定するとファイルのサイズが30kb〜100kbの間に収まるように出来るだけ分割してビルドしてくれます。
pythonでflickrから画像データをスクレイピングする方法

# Flickrの利用方法

## Flickr APIよりkeyを取得する
まず[Flickr](https://www.flickr.com/services/apps/create/)のページへいき**Request an API Key**をクリックする。ここでFlickrのアカウントを作成していない場合は作成しログインしておく。
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317229/0ba41958-4f5e-91a9-51d9-b700f284f9e0.png)

左側が無償(非商法）、右側が有償(商法）用なので、赤線で囲んである**APPLY FOR A NON-COMMERICIAL KEY**を選択する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317229/1238c3f7-b6eb-bbc6-3d45-b8bc15dfc5a3.png)

するとアプリケーションの登録画面が表示されるのでアプリケーションに使用する名前と使用用途を記載し、**SUBMIT**をクリックする。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317229/11fb12f1-adf5-29a7-b286-5783b9745a80.png)


登録後、key と Secret　が取得できるのでメモ帳などに控えておく。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317229/313175b1-d6d6-f2b2-19ae-eaa5fda73136.png)

## Flickr APIから画像を取得するプログラムを作成する
以下のコマンドよりFlickrのモジュールをインストールする。
```
pip install flickrapi
```

プログラム実行前に、取得した画像を保存するフォルダを作成する。

```python:download.py
from flickrapi import FlickrAPI
from urllib.request import urlretrieve
from pprint import pprint
import os,time,sys


key = "取得したkey"
secret = "取得したSecret"
wait_time = 1

# コマンドラインの引数の1番目の値を取得。以下の場合は[cat]を取得
# python download.py cat 
animalname = sys.argv[1]
savedir = "./"+animalname


# format:受け取るデータ(jsonで受け取る）
flickr = FlickrAPI(key, secret, format='parsed-json')

"""
text : 検索キーワード
per_page : 取得したいデータの件数
media : 検索するデータの種類
sort : データの並び
safe_seach :　UIコンテンツの表示有無
extras : 取得したいオプションの値(url_q 画像のアドレス情報)
"""
result  = flickr.photos.search(
    text = animalname,
    per_page = 400,
    media = 'photos',
    sort = 'relevance',
    safe_seach = 1,
    extras = 'url_q, licence'
)

# 結果
photos = result['photos']
pprint(photos)

```
上記のプログラムを実行し、成功すると以下の表示がされる。

```python:
           {'farm': 5,
            'height_q': 150,
            'id': '4375810205',
            'isfamily': 0,
            'isfriend': 0,
            'ispublic': 1,
            'owner': '47750313@N07',
            'secret': '8d0a7d24a1',
            'server': '4008',
            'title': 'cat',
            'url_q': 'https://live.staticflickr.com/4008/4375810205_8d0a7d24a1_q.jpg',
            'width_q': 150},
           {'farm': 1,
            'height_q': 150,
            'id': '27083352608',
            'isfamily': 0,
            'isfriend': 0,
            'ispublic': 1,
            'owner': '144380504@N04',
            'secret': 'd1cd159107',
            'server': '811',
            'title': 'cat',
            'url_q': 'https://live.staticflickr.com/811/27083352608_d1cd159107_q.jpg',
            'width_q': 150}],
```
'url_q'に登録されているURLを取得し、urllibを使用して画像データを取得する。

さきほどのプログラムに画像データを取得するプログラムを追加する。

```python:
for i,photo in enumerate(photos['photo']):
    url_q = photo['url_q']
    filepath = savedir + '/' + photo['id'] + '.jpg'

   # 重複したファイルが存在する場合スキップする。
    if os.path.exists(filepath):continue
   # 画像データをダウンロードする
    urlretrieve(url_q, filepath)
   # サーバーに負荷がかからないよう、1秒待機する
    time.sleep(wait_time)
```




「cat」を引数にプログラム実行後、猫の画像がFlickrから取得できた。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317229/41fda5b8-ddc7-45ef-8f65-fcf9c571b59c.png)
Nuxt.jsとMaterial Iconで、SPA時に文字化けする

事象は表題の通り

Material Iconの実装は以下の方法です。

[【IE対応】Google Material Iconsをdata 属性を使ってスマートに表示する](https://qiita.com/longbamboo/items/2d2f22cdd6649e0cd48f)

上記の手法、Nuxt.jsでSSRされたときは問題なく表示されますがSPA遷移行うとユニコードがそのまま文字列として展開されてしまいます。

**SSR**
![スクリーンショット 2020-08-24 12.25.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/9a74a1d8-a132-f8c9-b306-0ddff4930c57.png)

**SPA**
![スクリーンショット 2020-08-24 12.25.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/680cc772-7858-743f-2409-d284a5bdda40.png)

## 回避方法
これを回避する方法は２パターン考えられます。

### v-htmlを使う
どうやら仮想DOMから実際にHTMLを出力される際にユニコードを文字列としてエンコードして出しているように見えます。
`v-html`ディレクティブを利用することでこれを回避できます。

```vue
<a href="~~~" v-html="icon"></a>

...
<script>
  ...
  const icon = `<i class="material-icon" data-icon="&#57534;"</i>お問い合わせ`
  return { icon }
  ...
</script>
```

### ユニコードをそのまま貼り付ける
出力されるHTMLに注目してみましょう。

**SSR**
![スクリーンショット 2020-08-24 12.31.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/98614b9f-2245-9d4e-1644-082e45f20216.png)

**SPA**
![スクリーンショット 2020-08-24 12.32.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/a4483c32-51d3-a1b2-88f5-bb6891125ca8.png)

正常に表示できているときはHTMLに通称豆腐として展開されています。
なので、vueテンプレート側でもこの豆腐で登録することでうまく表示できるのでは？ということで試してみたところ、うまく表示されました。

![スクリーンショット 2020-08-24 12.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/9291f995-11a8-ac1e-3816-3230812c52f8.png)

使っているアイコンをオブジェクトで管理することで「この豆腐なんだっけ？」も防げますね。とはいえスマートな解決とは言えないのでもっと良い解決方法が知りたいです。
（RPA）uipathを使用し、作業を自動化にしましょう！

#背景
ITプロジェクトの中、必ず同じ作業を毎日にしなければいけない時があります。
例えば：
　・作業環境の準備（メール、IDEを開く、特定の作業フォルダ、特定の作業サイドなど）
　・運用保守する際にシステムを監視するため、データの取集を24時間やらなければならない時
　・何度も同じテスト仕様書のエビデンスを取る必要がある時
　・品質データの取得と分析
　・・・

#課題
普通自動化したい場合はVBAあるいはバッチを作りますが、でも下記の課題があります。
　・VBA、バッチの知識が必要です。
　・VBA、バッチの作成は時間がかかる。
　・UIがないので、bugがある時にメンテ（debug）が難しい。
　・VBA、バッチに対応できない時がある。
　　（例えばTFSにある特定のフォルダの最新バージョンを取得するなど）

#RPAとUiPathとは？
　RPAとは「Robotic Process Automation」の略語で、自分の理解だと、PRAソフトウェアを使用し、実際作業していく中で実行されたマウスイベント、キーボードの入力などを定義あるいは記録し、作業を自動化させることを指します。
　uipathはPRAソフトウェアで、主な機能は下記のようになります。
　　・マウスイベント、キーボードの入力などを定義あるいは記録
　　・指定したアプリ、フォルダを開く
　　・webサイト（のtableタグ）にあるデータをクロールできる
　　・excelなどのアプリを連携できる
　　・python、batchなどのプログラムを呼び出せる
　　・条件分岐（if）、ループ（for）などでロジックを実現できる

#実際UiPathで遊んでみましょう！
下記の手順で簡単な例を作成していきます。
　　①ブラウザで指定のサイトを開く
　　②検索キーワードを記入し、検索する
　　③検索結果の画面キャプチャを取る
　　④画面キャプチャをExcelに貼り付ける
※UiPathのインストールとUiPathプロジェクトの作成は省略します。

##①ブラウザで指定のサイトを開く
■アクティビティ名：「ブラウザーを開く」
　プロパティ：
　　・URL："https://www.google.com/"
　　　※””で囲むこと
　　・ブラウザーの種類：BrowserType.Chrome
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/bc73f766-509a-26c0-d1c8-4ff54c00e9ed.png)

##②検索キーワードを記入し、検索する
■アクティビティ名：「文字を入力」
　プロパティ：
　　・ターゲット：🈪をクリックし、入力するテキストボックスを選択する
　　・テキスト："UiPath"

■アクティビティ名：「クリック」
　プロパティ：
　　・ターゲット：🈪をクリックし、検索ボタンを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/232c4686-dcdd-6df6-95ec-53df14bde309.png)

##③検索結果の画面キャプチャを取る
■アクティビティ名：「スクリーンショットを作成」
　プロパティ：
　　・ターゲット：🈪をクリックし、範囲を選択する
　　・「出力」⇒スクリーンショット：image1

■変数の作成
　プロパティ：
　　・Name：image1
　　・Type:UiPath.Core.Image

■アクティビティ名：「メソッドを呼び出し」
　プロパティ：
　　・ターゲット型：System.Windows.Forms.Clipboard
　　・メソッド名：SetImage
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/a2db5065-bbef-5567-5e34-0d7e775b28dc.png)


##④画面キャプチャをExcelに貼り付ける
■アクティビティ名：「Excel アプリケーション スコープ」
　プロパティ：
　　・ブックのパス："C:\Users\zhang.yangfeng\Desktop\Temp.xlsx"

■アクティビティ名：「ホットキーを押下」
　プロパティ：
　　・ターゲット：🈪をクリックし、セルを選択する
　　・キー修飾子：KeyModifiers.Ctrl
　　・キー："v"

■アクティビティ名：「ブックを保存」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/e212465e-e336-c2a6-554e-5f410de42502.png)

#最後に
決まった手順で繰り返し行われる定常作業はどんなプロジェクトにもあると思います。
人で作業すると、単純作業で作業者のモチベーションも下がると思います。
そして、コストもかかるし、人的ミスも必ず発生します。
よって、自動化できることはなるべく自動化にしましょう！
では、UiPathに関する紹介はここまでにします。