OmniAICreator/Qiita-1.07M huggingface dataset:
Cypress で特定のページにナビゲートされたか確かめるには

## Abstract

`window.open` をスタブすれば良い。

## Body

Cypress は Chromium を使って e2e テストを実施できるツール・ライブラリです。

まず前提として、Web ページを開くには a タグをクリックする方法と JS で `window.open` を使う方法の2通りあります。

前者の場合は、次のように Element に対する操作としてチェックを掛けてあげれば良いです。

```js:1-href
// click <a href='/users/1/edit' date-test="edit-link">EDIT</a>

cy.get('[date-test=edit-link]')
  .should('have.attr', 'href')
  .and('include', '/users/1/edit');
```

---

後者の場合は、 `window.open` が同じタブで新しいページを開く場合には `cy.url()` でチェックできます。

```js:2-window.open
// window.open('/users/1/edit')

cy.url()
  .should('include', '/users/1/edit');
```

---

後者の中でも `window.open` が `_blank` を指定して新しいタブを開いてしまっている場合は、`window.open` をモックしてから `open` を `calledWithMatch` 等でチェックしてあげると良いです。

```js:3-window.open-with-_blank
// window.open('/users/1/edit', '_blank')

cy.visit(`http:localhost:8000/yeyeyeyey`, {
  onBeforeLoad: win => cy.stub(win, 'open')
});

...

cy.window()
  .its('open')
  .should('be.calledWithMatch', '/users/1/edit');
```

クエリパラメタ等のほとんどの状況では本質的でない情報で URL は変化しうるので `calledWithMatch` で判定を行うのが良いと思います。

## Motivation

`href` に対するチェックは言わずもがな、`window.open` をモックするというやり方も、結果を見れば割と正攻法という感じがしますが、**Cypress ではタブに関する操作ができず新しく開いたタブの URL はどうやっても取得できない**ので、`cy.url` で頑張ろうとしても無駄です。

`window` オブジェクトの取得にクセがあったりするのも地味にハマリポイントだと思うのでまとめてみました。

なお、同じサイトのページに移動する場合は移動先の要素に対してテストを行えば十分です。今回は特定の外部サイトのページを開くというシナリオだったため、遷移先の情報を仮定しないために URL に対してのみチェックを行うようなコードを書きました。

## References

* https://www.cypress.io/
* https://stackoverflow.com/questions/48348354/cypress-get-href-attribute
AndroidStudio　データバインディングの勉強まとめ

まず、XMLレイアウトは

```xml
:qiita.rb
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>
```
着目したいのが、この定義付と

```xml
<variable name="user" type="com.example.User" />
```
と、

```xml
<TextView android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{user.firstName}" />
```
このViewModelからの呼び出し部分。

そして、次がエンティティのようだ。


```java
public class User {
  private final String firstName;
  private final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
  public String getFirstName() {
      return this.firstName;
  }
  public String getLastName() {
      return this.lastName;
  }
}
```

text属性に使用される式@ {user.firstName}は、firstNameフィールドと後者のクラスのgetFirstName（）メソッドにアクセス。

さて、次はxmlとエンティティを結びつけているActivityのようだ。
```
```

```java

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
   User user = new User("Test", "User");
   binding.setUser(user);
}
```
上記はActivityのようで、bindingをインスタンス化して、xmlとUserエンティティを紐づけているようだ。

また、次のように、バインディング式はビューのクリックリスナーをonClickFriend()メソッドに割り当てることができるようだ。。

```xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="handlers" type="com.example.MyHandlers"/>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
           android:onClick="@{handlers::onClickFriend}"/>
   </LinearLayout>
</layout>
```


そして、それは次のコードが反応する

```java

public class MyHandlers {
    public void onClickFriend(View view) { ... }
}
```

このonSaveClickの場合は、

```java

public class Presenter {
    public void onSaveClick(Task task){}
}
```
次のようになる。

```xml

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:onClick="@{() -> presenter.onSaveClick(task)}" />
    </LinearLayout>
```
TFTPコマンドでYAMAHAルータの設定ファイル取得・書き換え、ファームUP

#はじめに
YAMAHAルータ(RTシリーズ)の設定ファイル取得・書き換え、ファームのUPについて、配布されているRT-Tftp Clientを使う方法もありますが、シンプルにコンソールからTFTPコマンドでやる場合のメモを。
※RTX1200で動作確認しています。

#事前の準備
ルータに対して、TFTPアクセスの許可設定をしておく。ルータに入って設定。

特定のIPからのみ接続可能にする場合は以下。
```tftp host 接続するマシンのIPアドレス```

接続元を特に縛らない場合は以下。
```tftp host any```

ちなみに、TFTP接続不可にするときは以下。
```tftp host none```

#設定ファイルの取得
###使用中のコンフィグ番号の確認
ルータに入った上で、以下実行。

```
#show environment
(中略)
Default firmware: exec0  Default config. file: config0　　←ここを確認しておく
```

この場合は「config0」

###ファイル取得
自マシンのコンソールから、以下実行。

```
$tftp {YAMAHAルータのIP}
tftp>get {設定ファイル名}/{管理者パスワード} {保存時のファイル名}
tftp> quit
```

例）
```tftp>get config0/password config.txt```

#設定ファイルの書き換え

###事前の準備
設定内容をガッサリ入れ替える場合は、ルータに送り込む設定ファイルの先頭に
```clear configuration(+改行)```を入れ、一番最後に```save(+改行)```を入れておく。

###ファイルのアップロード
自マシンのコンソールから、以下実行。

```
$tftp {YAMAHAルータのIP}
tftp>put {設定ファイル名} config/{管理者パスワード}
tftp> quit
```

※書き換えするのでちょっと待つ

#ファームウェアの書き換え
以下から*****.binをダウンロード。
http://www.rtpro.yamaha.co.jp/RT/firmware/index.php

###現在のリビジョンを最初に確認
ルータに入った上で、以下実行。

```
#show environment
(中略)
RTX1200 Rev.10.01.75 (Fri Feb 16 13:38:37 2018)　　←この辺を確認しておく
```
この場合は「Rev.10.01.75」

###書き換え
自マシンのコンソールから、以下実行。

```
$tftp {YAMAHAルータのIP}
tftp>put {ファームファイル名} exec
tftp> quit
```

※パスワードはいらない
※書き換えと自動再起動するのでちょっと待つ

###書き換え後のリビジョンを確認
ルータに入った上で、以下実行。

```
#show environment
```
書き換えたファームのリビジョンに変わっていることを確認。

#余談
緊急時とかにconfig.txtを入れたSDカードをルータ本体に挿して、設定ファイルの書き換え(書き戻し)をしてたのですけど、サーバラック内の配置を変えたことで、SDカードスロットに手が届かなくなってしまったので、TFTPコマンドでやる方法を調べました…！
Laravelで AWS の LB を通した環境でエンドユーザのIPを取得したい

とある機能のアプリケーションログをLaravelで出力して、社内からのアクセスを判別して抜くために、エンドユーザのIPを取得したい、という目的で調べた結果をまとめたものです。

LaravelでエンドユーザのIPを取得したい時には `Request::setTrustedProxy` で信頼できる Proxy を設定して X-Forwarded-For からエンドユーザのIPを取得するという情報をキャッチしたのでやってみましたが、ちょっとハマりました。
参考: https://qiita.com/sh-watanabe/items/c3695bcecccd00fd91dd


### 環境
* laravel 5.8 （古いバージョンからあげているっているのでアプリケーションレイヤのコードは一部古い可能性があります）
* PHP 7.2


### 結論
結論でいうと、以下の公式ドキュメントにある「信用するプロキシの設定」を使えばOKでした。
https://readouble.com/laravel/5.8/ja/requests.html

すなわち、TrustProxies Middleware（`app/Http/Middleware/TrustProxies.php`）を Laravel Kernel で呼び出し、 proxies と headers を設定すればOK。
特に、proxies についてはAWS環境であれば`*`を設定してあげる。

### ハマりどころ（symfony の設定メソッドを直接呼び出そうとする）
setTrustedProxy は Laravel を構成している symfony の機能として提供されていると聞いたので、それを直接呼び出そうとしたらハマりどころがありました。

* このメソッドを直接使っても動く条件は Controller 内部で $request を受け取っており、そこで設定する。これは後述の上書きがすでに終わっており、問題が起こらないレイヤです。
* 動かない条件はLaravel middleware を独自で作成し設定しようとすること（特に上述のLaravelにより提供されている TrustProxies Middleware の前で設定しようとすると）

なぜこういうことが起こるかというと、 

1. `app/Http/Kernel.php` の内部で呼び出す middleware を順番に定義している

```php
    protected $middleware = [
　　　　 // この前に独自定義しようとすると動かない（TrustProxiesを今まで使ったことないので、そういうものがあるのを知らず、最初は独自定義しようとした）
        \App\Http\Middleware\TrustProxies::class,
        // 略
    ];
```

2. `app/Http/Middleware/TrustProxies.php` の親である `vendor/fideloper/proxy/src/TrustProxies.php` の handle() は下記のように一度リセットしてから、改めて先ほど見た `$proxies`変数に設定されているものを見ています。

```php
    public function handle(Request $request, Closure $next)
    {
        // ここでリセット
        $request::setTrustedProxies([], $this->getTrustedHeaderNames()); // Reset trusted proxies between requests
        $this->setTrustedProxyIpAddresses($request);

        return $next($request);
    }
```

```php
    protected function setTrustedProxyIpAddresses(Request $request)
    {
        // ここで改めて設定取得している
        $trustedIps = $this->proxies ?: $this->config->get('trustedproxy.proxies');

        // Only trust specific IP addresses
        if (is_array($trustedIps)) {
            return $this->setTrustedProxyIpAddressesToSpecificIps($request, $trustedIps);
        }

        // Trust any IP address that calls us
        // `**` for backwards compatibility, but is depreciated
        if ($trustedIps === '*' || $trustedIps === '**') {
            return $this->setTrustedProxyIpAddressesToTheCallingIp($request);
        }
    }

```


### 終わりに（反省会会場）
Middleware あたりにこういう設定のところがあるよ、となんとなく知っていればすんなり解決したかもしれないが、適当にググって symfony の setTrustedProxies メソッドがあるよ、から入ってしまったので Middleware に設定があると気がつくまでに時間がかかってしまった。
普段からLaravelのフレームワークのコードリーディングを意識的にやっていれば、このレイヤにこういった設定があるのは（後から思い返せば）実に自然なので、困った時だけじゃなくて普段使いにおいても徐々に読み進めておくのが良さそう。
Rails tutorialで省略していたherokuを導入する(windows)

#Rails用にherokuをwindowsに導入
*注意
私はRails tutorial でherokuを省略していたためtutorial終了後になってやっています。
[これが本文です](https://qiita.com/take1457a/items/172ecdca3b86d67f927f)
###環境

+ windows 8.1
+ Rails 5.1.6
+ ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
+ [今回導入] → heroku/7.26.2 win32-x64 node-v11.14.0

#手順

+ 1 heroku [(https://signup.heroku.com/identity)](https://signup.heroku.com/identity) でユーザー登録 
+ 2 Heroku Toolbelt [(https://devcenter.heroku.com/articles/heroku-cli)](https://devcenter.heroku.com/articles/heroku-cli) からインストール
+ 3 コンソールでバージョンを確認

```bash
$ heroku --version
$ heroku/7.26.2 win32-x64 node-v11.14.0
```

+ 4 ログインしてSSHキーを追加

```bash
$ heroku login --interactive
#heroku: Enter your login credentials
Email: (heroku登録時のEmail)
Password: (heroku登録時のPassword)
#Logged in as (heroku登録時のEmail)
$ heroku keys:add
# Found an SSH public key at C:\*****\.ssh\id_rsa.pub
# ? Would you like to upload it to Heroku? Yes
# Uploading C:\*****\.ssh\id_rsa.pub SSH key... done

```

+ 5 Herokuサーバーにサンプルアプリケーションの実行場所を作成

```bash
$ heroku create
# Creating app... done, 以下省略
``` 

+ 6 Herokuにデプロイ

```bash
$ git push heroku master
```

+ 7 herokuでアプリの動作確認

```bash
$ heroku open
```

「hello, world!」が出たら完了

補足 : heroku create コマンドでgitのリモートリポジトリにherokuが設定されます。一度 heroku create を実行後は次からはheroku create なしで git push heroku master で更新します。

# heroku コマンド (自分用メモ書き)

```bash
# herokuにあげたappの確認
$ heroku apps

# ログアウト
$ heroku logout

# アプリ削除
$ heroku apps:destroy --app アプリ名

# gitのリモートリポジトリのheroku設定削除
$ git remote rm heroku

# herokuのdbをmigrateする
$ heroku addons:add heroku-postgresql
$ heroku run rails db:migrate
$ heroku run rails db:seed
```

#参照
[https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_setup](https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_setup)
[https://qiita.com/chihiro/items/5c3ff400f6cb99deb945](https://qiita.com/chihiro/items/5c3ff400f6cb99deb945)
実務未経験がチーム開発に挑戦してみた

#はじめに
こんにちは。かちゃあと申します。
早いもので3度目の投稿になります。

今回は、以前からメンターの方々と取り組んでいるチーム開発について
未経験ながら実務と似たような形で、作業に取り組ませて頂いているので
その主な開発の流れや、取り組んでみての発見などを書いていきたいと思います。



#チーム開発とは
文字通り、チーム(複数人)になって１つのサービスやプロジェクトの開発を進めることです。
質の高いサービスやコンテンツを作り上げるためには、主にチームで開発をすることが基本で、
細分化された分野、ジャンル、課題ごとにチームで別れて開発を進めていきます。
いかに周りのメンバーと連携しながら、綺麗で見やすいコードを書いたり、コミュニケーションを取れるかが大事になります。

#どんな流れで進んでいくのか
※あくまで僕が体験したチーム開発になります。

1.タスクの割り振り(全体)
2.開発(機能実装、テスト記載)
3.プルリクエスト
4.コードレビュー(メンター)
5.開発ミーティング（全体で最終チェック&次タスクの割り振り）
6.マージ
7.デプロイ&リリース

ざっくり言うとこのような流れで作業をしていきます。

#1.タスクの割り振り
チーム全体でどのような機能をつけるかタスクを作り、その担当を決めるための話し合いをします。
実務ではないので、技術レベルに関わらず自分でやりたいタスクを選ぶことができました。
さらに、必要であればここで大体の開発に必要な目標期間も決めます。
また、週単位で振り返りを行いタスクの進捗具合を報告していきます。
今回チームで使用したのは、Github上にあるprojects機能を使い、(1.Icebox/2.Todo/3.In progress/4.Review/5.Done)の5つに分けて作業の管理をします。

実際のタスクの例はこちら。
ex)投稿記事が削除できるようにする、記事ストック検索機能の実装、自分の投稿記事をいいねできないようにする、など

#2.開発
実際にその割り振られたタスクのコードを調べながら書いていきます。
機能実装のためには様々な知識が必要です。適宜、必要な知識をググって補完しながら、チームメンバーに見やすく、分かりやすいコードで開発を進めていきます。テストコードの記述もこの工程で行っていきます。各自、新しいブランチ上で作業を進めていきます。

#3.プルリクエスト
仮完成したコードをgithub上のプルリクエストを使って各自のブランチから各開発環境先のブランチなどに送るためのチェックをしてもらいます。
プルリク内の説明欄には何を実装したかのコメントと実装後のUIの変化を画面キャプチャを貼るなどしてわかりやすくします。
プルリクエストを送ったら、githubとは別でslackか何かでプルリクを送ったと言う報告をします(slackと連携していたら必要ないかも)。

#4.コードレビュー
メンターの方にgithub上でコードレビューをしてもらいます。
プルリク内変更差分ファイルのコード内で、行を指定したコメントでのやり取りを何度もしていただきました。
ex)このgemは必要ないのではないか?、インデントが正しくありませんね、など。

#5.開発ミーティング
コードレビューしていただいた箇所を修正し、それをチーム全体に共有し、チェックします。
自分の担当したタスクを、分かりやすく他のメンバーに説明しながら実際にローカルサーバー上で動かしてみます。
もっとこうした方がいいと言うアドバイスや、エラーの発見などをお互いに伝えあったりします。
ミーティング後は各自、修正必要箇所を直し、再びプルリクエストを送ります。
この場合は、また再びミーティング行うことはありません。
修正が特に必要ない場合は、また新しい次に取り組むタスクを決めます。

#6~7.マージ&デプロイ
そして修正箇所もなくなり、問題がなくなった場合は、いよいよ最後のマージ、デプロイの工程に移ることができます。
先程の3工程で作成したプルリクエストのマージを行います。その後、別環境の場合は本番環境へデプロイをすることで全ての工程が完了となります。

#取り組んでみての感想
・タスクをバラしても開発にかかる時間を逆算するのは難しく、思った期間内に終わらないこともある。
・cssの設計命名ルール、BEMについての理解が必要。製作者しかわからない名前のつけ方はよくない。
・他のメンバーの進捗がわかると、自らのタスクに対するモチベーションの向上に繋がる。



今後も引き続きチーム開発に取り組み続けていきたいと思っています。
[小ネタ] IntPtr型の省略可能引数には、default(IntPtr)を使う

タイトル通りです。

IntPtr型の省略可能引数を定義するときは、

```csharp
public void ExampleMethod(IntPtr param = new IntPtr()){}
```
もしくは

```csharp
public void ExampleMethod(IntPtr param = default(IntPtr)){}
```
と書く。

規定値を`IntPtr.Zero`と書きたくなるが、
`error CS1736: param' の既定のパラメーター値は、コンパイル時の定数である必要があります。`
というコンパイルエラーになります。

詳しくは [省略可能な引数](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#optional-arguments)を見てください。
axoisにFormDataを使ってArrayデータを送信する

## 画像ファイルと一緒にarrayデータを送信するときにハマった

## axiosでのファイルの送信

axiosで画像データを送信するにはFromDataを使用する

```js
    const params = {
      name: '名前'
      title: 'タイトル'
      image: '画像ファイル'
    }
    const formData = new FormData()
    Object.entries(params).forEach(([key, value]) => {
      formData.append(key, value)
    })

    await this.$axios.post(API_URL, formData, {
      headers: {
        'content-type': 'multipart/form-data'
      }
    })
```

## arrayデータを追加して送信(失敗例)

以下のやり方だとArrayデータが正しく送信できない

```js
    const params = {
      name: '名前'
      title: 'タイトル'
      image: '画像ファイル'
      tags: ['タグ1', 'タグ2'] // 追加
    }
    const formData = new FormData()
    Object.entries(params).forEach(([key, value]) => {
      formData.append(key, value)
    })

    await this.$axios.post(API_URL, formData, {
      headers: {
        'content-type': 'multipart/form-data'
      }
    })
```

## arrayデータを追加して送信(成功例)

```js
    const params = {
      name: '名前'
      title: 'タイトル'
      image: '画像ファイル'
      tags: ['タグ1', 'タグ2'] // 追加
    }
    const formData = new FormData()
    Object.entries(params).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        value.forEach((v, i) => {
          formData.append(key + '[]', v)  // arrayデータを分割して入れ直す
        })
      } else {
        formData.append(key, value)
      }
    })

    await this.$axios.post(API_URL, formData, {
      headers: {
        'content-type': 'multipart/form-data'
      }
    })
```

formDataを使うと文字列として入れるようなので、Arrayだけじゃなくて、Objectを送信したい時も分割して入れよう！
IMUからのトピックをTFに変換する

#この記事は
ROSを使っている人向けの記事です。TFの知識が少しあると良いかもです。

#使っているセンサー
Realsense D435i


#Realsenseの導入方法
少し記事が古いですが、参考にどうぞ
[RealSense D435のROSへの導入でつまづいたところ](https://qiita.com/shrimp-f/items/eba5878a3a5f05f6be2d)


#コード
GithubでROSのパッケージも公開してます。(ライセンスとかは今度編集します…。)
[shrimp-f/imu2tf](https://github.com/shrimp-f/imu2tf)

```cpp:imu2tf_converter.cpp
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <turtlesim/Pose.h>
#include <sensor_msgs/Imu.h>


void poseCallback(const sensor_msgs::Imu& msg){
    static tf::TransformBroadcaster br;
    tf::Transform transform;
    transform.setOrigin( tf::Vector3(0.0, 0.0, 0.0) );
    tf::Quaternion q;
    double g = 10.0; //重力加速度
    double r,p; //それぞれroll,pitch。下は、それぞれトピックの値から計算
    r = atan(msg.linear_acceleration.y/msg.linear_acceleration.z);
    p = atan(-msg.linear_acceleration.x/(sqrt(pow(msg.linear_acceleration.y,2)+pow(msg.linear_acceleration.z,2))));
    q.setRPY(r, p, 0);
    transform.setRotation(q);
    br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", "camera_link"));//親フレームをworld,子フレームをcamera_linkとしてTFを配信
}


int main(int argc, char** argv){
    ros::init(argc, argv, "my_tf_broadcaster");
    ros::NodeHandle node;
    ros::Subscriber sub = node.subscribe("/camera/accel/sample", 10, &poseCallback);//ここでIMUのトピックを購読

    ros::spin();
    return 0;
};
```

#最後に
トピック名とTFのフレームは適宜自分の使いたい名前に変えてください。
TFはちゃんと調べて理解するとROSの世界が広がる(気がする)ので頑張ってください！
フォーム送信時にチェックボックスにチェックがされていない場合送信できないようにする。

プライバシーポリシーを確認してもらうなど、送信前に「確認した」ことをチェックするためにチェックボックスを付けて、チェックが付いていないと送信ボタンが押せないようにするソースです。
html+javascriptのシンプルなソースで実装します。

```html:チェックボックスhtml
<input type="checkbox" autocomplete="off" id="accept">
<label for="accept">* <a href="***.html" target="_blank">プライバシポリシー</a>に同意しました</label>
<button type="submit" id="send" class="btn"><span>送信</span></button>
```
チェックボックスと送信ボタンです。
CSSで加工してください。

```Javascript
$(function(){
  $("#send").prop("disabled", true);
  $("#accept").click(function(){
    if ($(this).prop("checked") == false) {
      $("#send").prop("disabled", true);
    } else {
      $("#send").prop("disabled", false);
    }
  });
});
```
チェックボックスがクリックされたときに.propでクリックできるできないをコントロールするだけです。
Rails 画像の読み込み  public か app/assets/images

画像を使いたい時｡

Progateではpublicディレクトリで画像を読み込みますが､
別の方法もあります｡
app/assets/imagesディレクトリで読み込む方法｡


app/assets/imagesの方が､キャッシュが残らないとのこと｡

"アセットパイプライン"によってアセットを最小化､ファイルを連結して1つにするフレームワーク､
ページの読み込み時間が大幅に短縮できるそう｡
(JPGかPNGでダウンロードします｡)

結論:app/assets/imagesで画像を読み込んだほうが良いかも？




参考
https://techblog.kyamanak.com/entry/2017/10/13/003818
https://railsguides.jp/asset_pipeline.html
TravisCIでYarnの別バージョンをインストールする。

TravisでYarnの別バージョンをインストールする方法について書きました。

# .travis.ymlにこれを追加するだけ

```yaml:.travis.yml
before_install:
  - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version [version]
  - export PATH=$HOME/.yarn/bin:$PATH

cache:
  yarn: true
```

`[version]`にインストールしたいYarnのバージョンを入力する。

## Stable（安定版）をインストールしたい場合

```yaml:.travis.yml
before_install:
  - curl -o- -L https://yarnpkg.com/install.sh | bash
  - export PATH=$HOME/.yarn/bin:$PATH

cache:
  yarn: true
```

## Release Candidate（リリース候補）をインストールしたい場合

```yaml:.travis.yml
before_install:
  - curl curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --rc
  - export PATH=$HOME/.yarn/bin:$PATH

cache:
  yarn: true
```

## Nightly（ナイトリービルド）をインストールしたい場合

```yaml:.travis.yml
before_install:
  - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --nightly
  - export PATH=$HOME/.yarn/bin:$PATH

cache:
  yarn: true
```

# 参考

- [Installation | Yarn](https://yarnpkg.com/en/docs/install)
- [Continuous Integration | Yarn](https://yarnpkg.com/lang/en/docs/install-ci)

# あとがき

思ったんですけどなんでTravisにインストールされるYarnのバージョンが`1.3.2`なんでしょうかね...（なぜ安定版の最新がインストールされないのだろうと疑問に思っている。）
理由が何かあるのかな🤔
Vuexのgettersを使う時の注意点についてまとめてみた

# はじめに

Vuexの `state` をアクセスする方法には2つあります。
1. 直接 `this.$store.state.xxx` などで直接 `state` にアクセスする
2. `Vuex.getters` (以下、`getters`) を用いて `state` にアクセスする

どちらの方法でも `state` にアクセスできますが、`getters` をどう使い分けをしたらいいのか、自分の中で理解できなかったので調べてみました。

# `getters` について

Vuex 公式ドキュメントには次のように書かれています。

> Vuex を利用するとストア内に "ゲッター" を定義することができます。それらをストアの算出プロパティと考えることができます。算出プロパティと同様に、ゲッターの結果はその依存関係に基づいて計算され、依存関係の一部が変更されたときにのみ再評価されます。

> ～　中略　～

> プロパティとしてアクセスされるゲッターは Vue のリアクティブシステムの一部としてキャッシュされるという点に留意してください。

`computed` や `watch` 同様に、**`getters` はオブジェクト指向プログラミングでよく使われる getter と同義でない**ことがわかりました。

# `state` を直接参照する場合と `getters` を使い分けるには？

## TL;DR

単にstateの値を取得するだけ(オブジェクト指向などで使われる一般的なgetter)であれば、 `state` を直接参照する
何らかの計算処理を行なった結果を取得するのであれば `getter` を使用した方が望ましい

---

`getters` は公式ドキュメントの引用のよればキャッシュ機構が備わっているため、 `computed` と一緒に使うと二重にキャッシングされてしまいます。

```javascript

// store(vuex)
export default new Vuex({
  state: {
    musicList: [
      { id: 1, name: foo, category: 'pop' },
      { id: 2, name: bar, category: 'rock' }
    ]
  }

  getters: {
    musicList: state => state.musicList
  }
})


// component (vue)
export default {
  computed: {
    getMusicList() {
      return this.$store.getters.musicList // コンポーネント側とVuex側で二重にキャッシングされてしまう
    }
  }
}

```

ただし、いくつかの複数のコンポーネントで `state`を用いて何らかの計算処理を行い場合は、コンポーネント側で計算処理が重複して記述されるのを防ぐため、 `getters` を記述すべきでしょう。

```javascript

// store(vuex)
export default new Vuex({
  state: {
    musicList: [
      { id: 1, name: foo, category: 'pop' },
      { id: 2, name: bar, category: 'rock' }
    ]
  }

  getters: {
    rock: state => state.musicList.filter((music) => music.category === 'rock')
  }
})


// component (vue)
export default {
  computed: {
    getRockMusicList() {
      return this.$store.getters.rock // これはOK!
    }

    // computed側で記述すると、計算処理が重複してしまう
    // getRockMusicList() {
    //   const musicList = this.$store.getters.rock
    //   return musicList.filter((music) => music.category === 'rock')
    // }
  }
```

# まとめ

- **`getters` にはキャッシュ機構が備わっている。**
- `computed` (`watch`) と併用して利用すると二重でキャッシュしてしまうため、`state` を直接参照する。
- `state`を参照して何らかの計算処理などを行い、かつ複数コンポーネントでその計算処理が利用される場合は、`getters` を利用する。

# 参考

- [公式ドキュメント](https://vuex.vuejs.org/ja/guide/getters.html)
- [Vuex getters are great, but don’t overuse them](https://codeburst.io/vuex-getters-are-great-but-dont-overuse-them-9c946689b414)
NavMeshAgent同士の衝突でOnCollisionEnterが動作しない場合の対処法

# 問題

NavMeshAgentがアタッチされている2つ以上のオブジェクトが衝突してもOnCollisionEnterが呼ばれない。

# 原因

- NavMeshAgentを動かすためにはRigidbodyのisKinematicをオフにする必要がある
- isKinematicがオフの物体同士の衝突ではOnCollisionEnterが呼ばれない

という2つの相反する要求が同時に発生しているからです。

# 解決法

1. isKinematicをオンにする
1. NavMeshAgentのMassを0 (厳密には1e-07)にする

# 参考

- [Unity : 衝突検出のOnCollisionEnter, OnTriggerEnter が呼ばれない、反応しない（Collision Detection） - いんでぃーづ](https://indie-du.com/entry/2015/02/04/200000)

- [NavMesh Agent を他のコンポーネントと共に使う - Unity マニュアル](https://docs.unity3d.com/ja/current/Manual/nav-MixingComponents.html)
Spring boot開発～開発環境編～

この度今まで経験がない環境で開発をやることになりました。
ただ事例としてはとても一般的なのでネットで情報を調べながら開発していくことになると思います。
一旦環境作成まで終わったのでそこまでの備忘として記載

#使用技術

##環境
・Win10
・インフラ：AWS（AWSの構築はしないのでいろいろ書かない）
・開発ツール等は2019/07現在最新のものを使う予定

##言語：Java
Javaを使ったWEBシステム開発は３年位やっています。
いままではSIだったのに対し、今回はWEBの会員サイトです。

###FW：Spring boot
Springは少しあるけどbootは初めて！！

###DB：PostgreSQL
DBはOracleが３年くらい、MySQLが１年弱でSQLServerとポスグレは実務経験ナシ
といった状態なので基本は大丈夫なんだけど細かいところわからないって感じ

###バージョン管理：Git
仕事ではずっとSVN
家でちょろちょろ触っているけど、あまり使えない（用語は少しわかるレベル）

###開発環境：Eclipse

といった感じで自分はニアミスしながら結果はじめてのものが多いんだけど、WEB系の開発でよくあるタイプだと思います。

#開発環境作成
##Eclipse

サイトから落としてきてCドラ直下に解凍
自分は一旦最新版
http://mergedoc.osdn.jp/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/02d21961-f310-7b33-3165-02e9fad7fc63.png)


右上からGitとJavaEEを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/6f481150-ddd6-1c0a-caeb-e75536a5b542.png)

パッケージエクスプローラからプロジェクト作成＞Springbootスタータープロジェクト
古いバージョンだとデフォルトでSpringBootが入っていないのでEclipseマーケットプレースからSTSを手に入れないといけないかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/f67a8e1b-98f1-99bb-0847-12ed1ea33799.png)

依存関係で以下の画像にある通り選択（あとから変わるかもしれぬ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/0a5a6b93-a40e-a705-4bca-c991c5915779.png)

##PostgreSQL 
https://www.postgresql.jp/download

ここからダウンロード後インストール
ID、パスワード、DB名などを設定

DDLとか流してテーブルとか作る

あとプロジェクトの以下のファイルを編集してDB接続情報を設定

```src/main/resources/application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/DB名
spring.datasource.username=ユーザーID
spring.datasource.password=パスワード
```

##Git
Githubに自分のアカウント適当なリポジトリを作成
https://github.co.jp/

プロジェクトを右クリック
チーム＞プロジェクトの共用＞Git

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/c2b20d06-eeb2-d2fa-b497-81bd0ad846ac.png)

プロジェクトの親フォルダ内の～にチェックを入れて下のパスを選択（チェックは入れない）
リポジトリーの作成を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/0a77483e-0c92-bcfa-d781-fea6d5d71b64.png)

Github右にあるクローンダウンロードから自分が作ったGithubリポジトリのパスをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/bd833071-a1f1-24ef-6e60-4d360b589571.png)

Eclipseに戻って右上Gitタブからローカルリポジトリを右クリック
リポジトリパスまたはURIの貼り付けを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/d74c901f-6069-7be5-3084-372239f7c6a7.png)

次へ～ってやってリポジトリを登録

ココらへんで一通り環境作成はおしまい
いまま調べながら画面起動開発を進めているけど人に説明できるほど理解できるにはしばらく掛かりそう
[備忘録]axiosのPOSTでVueのobjectが空になってしまう問題

#Jsの型
typeofでチェックしても、配列、連想配列、VueオブジェクトどれもObjectとして返されるがObjectでもそれぞれ違う。

#今回ハマったこと
```vuejs:sample.vue
<script>
data() {
    return {
        object: [] //v-forで動的に生成される
    }
}
methods:{
 post() {
    axios.post('/api/hoge',{
         key1: 'fuga',
         key2: this.object
    }).then(response => {
          console.log(response.data)
 })
} 
~省略〜
</script>

```
この時、動的に生成されたobjectはどうやらそのまま、Axiosの第二引数にぶち込んで送ることはできないみたい。サーバーサイドで取得した物をそのまま返してコンソールで確認してもArray(0)になるだけ。

#送れるObjectに変換
[How to convert the object of Vue to normal object？ #292](https://github.com/vuejs/Discussion/issues/292)
>It is said that JSON.parse (JSON.stringify ()) is a good method in this discussion, but I think that using JSON.stringify is not a good method.
Because Date type etc. are converted to String.
As the most effective means, I think best answer @imbolc 's Object.assign ({}, vm.$data)

```js
Object.assign ({}, vm.$data)
```
こいつで変換するのが最良だぜ！とのことだったので、、、

```vuejs:sample.vue
<script>
data() {
    return {
        object: [] //v-forで動的に生成される
    }
}
methods:{
 post() {
    var convert = Object.assign({},this.object)
    axios.post('/api/hoge',{
         key1: 'fuga',
         key2: convert
    }).then(response => {
          console.log(response.data)
 })
} 
~省略〜
</script>

```
コンソールでそのまま全部返した物を確認すると

```js:console
{
  key1: 'fuga',
  key2: {name: value, name2: value2}
}
```
ちゃんと送れた模様
catとpbcopyを一緒に行うエイリアスを作る

cat hoge.txt | pbcopy をエイリアスにするときに詰まったのでメモ


これや

~~~~
alias cpb="cat $1|pbcopy"
~~~~
これだといけない

~~~~
function cpb () {
    cat $1
    pbcopy
                }
alias cpb=cpb
~~~~

これだといける

~~~~
function cpb () {
    cat $1 | pbcopy
                }
alias cpb=cpb
~~~~
ただ、このままでは最後の改行も入ってしまう。
なので、変数を使って色々して、最後の改行をコピーしないようにする。

~~~~
function cpb (){
    ll=`cat $1` 
    echo -n "$ll" | pbcopy #変数はダブルクォート（クォートは不可）で囲まないと、改行コードがスペースなどに置き換えられる。
               }
alias cpb=cpb
~~~~
こうすることで、catの内容から、最後の改行を抜いたものをpbcopyするエイリアスができる。
JavascriptのFetch APIを使ってJSONを取得する。

タイトルの通りだが、従来はJavascriptでJSONを取得する際は、`XMLHttpRequest`というものを使っていたらしい。`fetch()`メソッドはこの`XMLHttpRequest`の代替として、よりシンプルで強力な機能を実現してくれるようだ。

とりあえず、これを使ってJSONを取得して、画面に表示してみる。
今回は[鉄道遅延情報のjson](https://rti-giken.jp/fhc/api/train_tetsudo/)というサイトを利用させていただく。

（本当はAppleの[RSSジェネレータ](https://rss.itunes.apple.com/en-us)を使ってappstoreのランキングを取得しようと思ったのだが、CORSによるクロスドメインのエラーによってやる気を削がれてしまった。その件についても、後日書こうと思う。）

さて、遅延情報の取得に戻ろう。fetchを用いたjavascriptは以下の通り。

```javascript:javascript
window.addEventListener('load', function() {
  getTrainList();
});

function getTrainList() {
  var url = 'https://tetsudo.rti-giken.jp/free/delay.json'; //遅延情報のJSON
  fetch(url)
  .then(function (data) {
    return data.json(); // 読み込むデータをJSONに設定
  })
  .then(function (json) {
    for (var i = 0; i < json.length; i++) {
      var train = json[i].name;
      var company = json[i].company;

      //表形式で遅延路線を表示する
      var row = document.getElementById('train-list').insertRow();
      row.insertCell().textContent = i + 1;
      row.insertCell().textContent = train;
      row.insertCell().textContent = company;
    }
  });
}

```

シンプルに、これだけ。上記のinsertRow().insertCell().textContentによって、列と行を追加し、JSONの値を詰め込んでいく。

```html:index.html
    <h1>遅延路線</h1>
      <table id="train-list">
      </table>
```


シンプルに路線名と鉄道会社名のみを表示させた↓

![Screenshot 2019-07-23 20.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444965/bda216f8-676a-75b9-b3bf-6416fa5d8566.png)

ここにFetch APIの詳しい情報が載っています。
[MDN web docs 〜Fetchを使う〜](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)
プログラミング講習(仮)06

#プログラミング講習(仮)06
#目的
勉強したい人の支援

#内容

ファイル分割

クラス
　☆アクセス
　☆コンストラクタ

おまけ

#今回使用するクラス
前回に引き続き自作複素数クラスを使用する

#ファイル分割
長いファイルが読みにくいので、
クラスを目処にファイル分割をしていく
![prex06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/db38f3c6-d6b4-045e-c6a2-6b9b1d034263.png)
### こんな感じにします

```comp.hpp
class comp 
{
public:
    float re, im;

    comp add(comp);
};
```

``` comp.cpp
#include "comp.hpp"

comp comp::add(comp inp)
{
    comp res;
    res.re = re + inp.re;
    res.im = im + inp.im;

    return res;
}
```
自作ヘッダはダブルクォーテーションで囲みます

```main.cpp
#include <iostream>

#include "comp.hpp"

using namespace std;

int main()
{
	comp a, b;
	a.im = 32;
	a.re = 11;

	b.im = 10;
	b.re = 30;

	comp c = a.add(b);

	cout << c.im << ", " << c.re << endl;

	return 1;
}
```

##コンパイル方法
メンバ関数を記述したcomp.cppも同時にコンパイラに投げる

```
g++ -o exe main.cpp comp.cpp
./exe
42, 41
```

#アクセス
```comp.hpp
class comp 
{
public:
    float re, im;

    comp add(comp);
};
```
アクセスについて
それ以降同じ

public:
クラスの内外からアクセスできる。
例えば

``` main.cpp
comp c = a.add(b);
cout << c.im << ", " << c.re << endl;
```
のように。
メンバ関数、メンバ変数にクラス外からアクセスを行っている。

対義語は
private:
で、クラス内のメンバ関数以外からのアクセスができなくなる。
意味は色々あるんだろうけど、なれるまで使わなくていいと思う。

#コンストラクタ
今まで、
インスタンス生成→メンバ変数設定
という手順を取ってきたが、正直ダルい

ということで、インスタンス生成と、メンバ変数設定を行いたい
そう、コンストラクタを使って。

```comp.cpp
#include"comp.hpp"

comp comp::add(comp inp)
{
    comp res(0, 0);
    res.re = re + inp.re;
    res.im = im + inp.im;

    return res;
}

comp::comp(float ir, float ii)
{
	re = ir;
	im = ii;
}
```
下方の
comp::comp(ry
が、コンストラクタである
（上方の関数も少し変わっている点注意）
コンストラクタには戻り値がないです
中身のないコンストラクタを
フォルトコンストラクタ
とか言います

```main.cpp
#include <iostream>

#include "comp.hpp"

using namespace std;

int main()
{
	comp a(32, 11);
	comp b(10, 30);

	comp c = a.add(b);

	cout << c.im << ", " << c.re << endl;

	return 1;
}
```
こんなふうに使います。
もちろんヘッダも書き換えます。（合うように）

#おまけ課題
AWS Amplify CLIで作ったアプリに既存のAPIを取り込みたかった話

#はじめに

Amplify CLIで作ったアプリに既存のAPIを追加したくて、やってみた話です。

APIもAmplify CLIから作りたかったのですが、フックするLambdaのランタイムがPython縛りだったので、断念しました。が、近い将来サポート言語が増えると信じていますので、いったんそれまでのツナギ案です。

#要件
* Amplifyは、Multienvでステージを分離したい（prod, dev）
* 既存APIも、Amplifyのステージをスイッチするタイミングで、同じように切り替えたい
* API Gatewayは、Amplify CLIで作成したCognitoで認証したい
* ソースコードは極力シンプルにしたい

#方法
authRoleにAPI Invokeのポリシーをアタッチしておく。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*",
                "execute-api:Invoke"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

取り込みたいAPIをaws-exports.jsライクに定義する。

```js
// NOTE: Supported runtime is NodeJS only in Amplify API,

const awsmobile = {
  "dev": [
    {
        "name": "api-dev",
        "endpoint": "https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod",
        "region": "ap-northeast-1"
    }
  ],
  "prod": [
    {
        "name": "api-prod",
        "endpoint": "https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod",
        "region": "ap-northeast-1"
    }
  ]
};


export default awsmobile;

```
aws-exports.jsからenv nameを取得して、APIの定義をする。
env nameは、ホスティングバケットのサフィックスになっている。
（素直にenv_nameをaws-exports.jsに吐き出してくれればいいのに、、、）

```js
import config from './aws-exports'

const REGEX = /.*-(\w+)/
const env = config.aws_content_delivery_bucket.match(REGEX)[1]
console.log(env)
```
env nameでAPIの定義を取得して、configureする。

```js
import apiExports from './aws-apiexports'

config.aws_cloud_logic_custom = apiExports[env]
Amplify.configure(config)
```

#さいごに

これがベストかはわかりませんが、個人的にはAmplify CLIで完結しているアプリと同じ操作感になった？気がします。
CentOSにコマンドラインのみでGitをインストールする方法

#Gitをインストール

Git公式サイトの手順から、perl-ExtUtils-MakeMakerを追加してインストールする

[Git - Gitのインストール](https://git-scm.com/book/ja/v1/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) 


```
$  sudo yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker
>インストール:
  expat-devel.x86_64 0:2.1.0-10.el7_3                          libcurl-devel.x86_64 0:7.29.0-51.el7                          perl-ExtUtils-MakeMaker.noarch 0:6.68-3.el7

依存性関連をインストールしました:
  gdbm-devel.x86_64 0:1.10-8.el7                 libdb-devel.x86_64 0:5.3.21-24.el7        perl-ExtUtils-Install.noarch 0:1.58-294.el7_6      perl-ExtUtils-Manifest.noarch 0:1.61-244.el7
  perl-ExtUtils-ParseXS.noarch 1:3.18-3.el7      perl-devel.x86_64 4:5.16.3-294.el7_6      pyparsing.noarch 0:1.5.6-9.el7                     systemtap-sdt-devel.x86_64 0:3.3-3.el7
```

#wgetで最新のGitのソースをダウンロードする

最新の2.22.0をダウンロードする

```
$ wget https://www.kernel.org/pub/software/scm/git/git-2.22.0.tar.gz 

$ tar zxvf git-2.22.0.tar.gz  
```

#コンパイルしてインストール

```
$ cd git-2.22.0/

$ make prefix=/usr/local all

$ sudo make prefix=/usr/local install

$ git --version
>git version 2.22.0  #バージョンを確認する
```

##参考サイト
 [CentOSに最新版のGitをインストール・アップデートする方法 - TASK NOTES](https://www.task-notes.com/entry/20150622/1434942000)
HTMLにJavaScriptを反映させる

#HTMLへのJavaScriptの記述

HTMLに直接JavaScriptを記述する場合は下記のように記述する。

```index.html
<head>

</head>
<body>
  <script>
    //ここにメソッドを記述する
    window.alert('Hello, JavaScript!');
  </script>
</body>
```

しかし、記述が多くなると見辛くなるため、別ファイルに記述して、htmlのheadで読み込む。

```index.html
<head>
  <script src="java_script.js"></script>
</head>
<body>
  <script>
    //ここにメソッドを記述する
    window.alert('Hello, JavaScript!');
  </script>
</body>
```
JIRAのサービスが起動中か知りたいので調べた

#はじめに
$ systemctl status jiraみたいな感じで確認できるのか調べました。
ちなみにjiraの知識は使ったことあるけどオンプレとなると未知の領域って感じのパンピーです。

#作業環境
mac
オンプレのjira

#作業開始
##ググる

公式の手順が2つ見つかりましたのでそれに倣います。

https://ja.confluence.atlassian.com/jirakb/starting-jira-automatically-on-linux-828796713.html

こっちは補足っぽく読む感じで。startとstopは存在するっぽい。
https://ja.confluence.atlassian.com/jirakb/startup-check-starting-jira-872266333.html

手順通りに読み進めると少しずつ理解できました。
仮にstatus.shみたいなスクリプトが存在するなら設定できそうですね。
init.d配下にjiraサービスを配置して、その中でstartとstopを呼び出してる。
よってstatusはないです。

ドキュメント後半はchkconfigにaddして自動起動の設定したり、ですので省略。
ならどうやって起動中か否か判定するの、と問われるとpsコマンドしかなさそうです。


```
$ ps aux | grep jira
```

これでプロセスが起動してれば起動中だし、出力されなかったら停止中。。って判断で良さそうですね。
再起動もstop→startしかなさそうですし、systemctlに慣れた身としてはなんか違和感。
けどその思い込みで結構時間を消費してしまったので反省です。

psコマンドについてわかりやすかった記事はこちら。
https://qiita.com/toshihirock/items/565fe71d778d3ee36b96

記事内のコマンドを拝借させていただきました、出力結果をいい感じにしたければ下記コマンドで。


```
$ ps aux |egrep 'PID|jira'|grep -v 'grep'
```

こうすると以下のようにカラムに名前がつきます。素晴らしい！

```
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
```

#おわりに
目的はjiraの起動ステータス確認なのですが、調べて身についた知識は他の作業でも活かせるのが楽しいところですね。
本記事がどなたかのお役にたちますように〜！
[nuxt.js その7] グローバルsnackbarの実装

# snackbarとは
以下の画像の赤枠で記しているメッセージボックスのことです。Vuetifyで用意されているのですぐに使用することができます。
![snackbar.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283352/1c493e3b-7793-9bca-cc4e-7f12a2956ec7.png)

タイトルではグローバルsnackbarと銘打っていますがその名前が正しい表現なのかはわかってません。実体は、storeにsnackbar操作用のデータを用意して、そこにディスパッチすることで表示するsnackbarのことです。

# snackbar.js (ストア）の実装
表示/非表示を表す値：`isEnable`
表示するメッセージ：`message`
を用意して、以下のように作成しました。

``` javascript:~/store/snackbar.js
export const state = () => ({
  isEnable: false,
  message: false
})

export const getters = {
  status: state => {
    return state.isEnable
  },
  message: state => {
    return state.message
  }
}

export const mutations = {
  setenable (state) {
    state.isEnable = true
  },
  setdisable (state) {
    state.isEnable = false
  },
  setMessage (state, message) {
    state.message = message
  }
}

export const actions = {
  snackOn ({commit}) {
    commit('setenable')
  },
  snackOff ({commit}) {
    commit('setdisable')
  },
  setMessage ({commit}, message) {
    commit('setMessage', message)
  }
}
```

実際に表示したい場合は以下のように呼ぶことで表示することができます。

```vue.js
this.$store.dispatch('snackbar/setMessage', 'ログアウトしました')
this.$store.dispatch('snackbar/snackOn')
```

# default.vueにsnackbarをセットしておく
操作用のストアはできたので、実際に表示される部分の実装をしていきます。
全体で１つのsnackbarを使用できるようにしたいのでレイアウトにあるdefault.vueに埋め込みます。

```vuejs:~/layouts/default.vue
    <v-snackbar
      top
      v-model='snackbarVisible'
    >
      {{ this.$store.getters['snackbar/message'] }}
    </v-snackbar>
    <v-content>
      <v-container>
        <nuxt />
    　</v-container>
    </v-content>
```

snackbarVisibleをv-modelにセットして、これをcomputedにて実装しているのですが、ここで非常につまずきました。当初、`this.$store.state.snackbar.isEnable`をそのままv-modelにセットしたり、以下のようなcomputedの実装で試みましたが、ページをリロードしたタイミングでstoreの値が一時的にtrueに変わってしまい毎回snackbarが表示されてしまうといった動きになっていました。

```vue.js
  computed: {
    // snackbarが自動でfalseに設定するためセッタを用意して、明示的にdispatchからOffするようにする
    snackbarVisible () {
        return this.$store.state.snackbar.isEnable
    }
  }
```

snackbarが設定された表示時間が経過すると自動的に表示のフラグをfalseに変えてくれる仕様のようなのですが、おそらくこれがうまく動いてなかったことで、上記のような動作になっているようでした。以下のようにsnackbarVisibleにゲッタとセッタを明示的に用意してあげることで解決しました。

```vue.js
  computed: {
    // snackbarが自動でfalseに設定するためセッタを用意して、明示的にdispatchからOffするようにする
    snackbarVisible: {
      get() {
        return this.$store.state.snackbar.isEnable
      },
      set() {
        return this.$store.dispatch('snackbar/snackOff')
      }
    }
  }
```

セッタなしcomputedに戻すと以下のエラーメッセージが出てました。
 `[Vue warn]: Computed property "snackbarVisible" was assigned to but it has no setter.`
セッタを用意しろ　って書いてありますね。気づかなかった。。。

ひとまず、これでsnackbarの実装もできました。
何かユーザにメッセージを通知したい場合には簡単に表示できるようになりましたね。
CloudWatch Logs Insights を触ってみた

Amazon CloudWatch LogsにはAWSのサービスのログが大量に出力できます。
ログを分析するためにはデータをエクスポートして分析を行う必要がありました。
2018年11月にリリースされたCloudWatch Logs Insightsによりログの分析をCloudWatch Logs上で行えるようになりました。


ここでは、VPC Flowlogsを設定済みとする。
CloudWatchLogs を開き、インサイトを開く。
![スクリーンショット 2019-07-23 18.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/3efa4c0e-1e6a-5362-532e-ca613e8a128a.png)


「サンプルクエリ」ー「VPC フローログのクエリ」- 「送信元と送信先のIPアドレスの平均、最小、最大バイト転送」をクリック。
![スクリーンショット 2019-07-23 18.51.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/3429ed5d-e1bc-0a13-66be-15948b969a84.png)


「クエリの実行」をクリック。

```
stats avg(bytes), min(bytes), max(bytes) by srcAddr, dstAddr
```

![スクリーンショット 2019-07-23 19.19.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/ddd6bf64-c94d-a06c-98f4-e6e46f2d0251.png)


この様に、クエリの結果が表示されます。
![スクリーンショット 2019-07-23 19.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/ab90f383-ff73-8330-cabe-a0d6fb47fb0a.png)
GoogleDrive上でMarkdownを書いて共有したい

# GoogleDrive上でMarkdownを書いて共有したい

## TL;DR;
* stackEditをGoogleDriveと連携させると捗る
* 400エラーが出たらStackEditに行ってGoogleログインすればOK

## やりたかったこと
社内でドキュメントのやり取りを行う場合、GSuiteを入れている企業ならばGoogleSpreadSheetを使っていることが多いのではないかと思います。実際、かなり便利で私もよく使います。
が、GoogleSpreadSheetはあくまでスプレッドシートなので表形式で表すことのできる二次元データならばいい感じに表現できますが、階層のあるデータの場合面倒です。

### Markdownで書きたい
階層のあるデータの場合、エンジニアとしてはやはりMarkdownで書きたいです。(人が読む用じゃなければjsonやyamlで構いませんが)
というわけで、GSuite上でSpreadSheet並みに手軽にMarkdownを書いて共有する手段がないかなと探したところ、
[StackEdit](https://stackedit.io)が見つかりました。

## StackEdit
StackEditはブラウザ上で動作するMarkdownエディタで、即時プレビュー等の機能を備えています。
単純にエディタとしても優秀ですが、このStackEditは外部連携機能を備えており、
GoogleDrive上でファイルを作成・編集したりその他ブログサービスにデータを出力できます。
(残念ながらQiitaは対応してくれていませんが…)
この機能を使えば流石に複数人同時編集は出来ませんが、いい感じにDrive上でファイルが共有できます。

## Google Driveからの連携
### Google Driveにアプリを追加する
ドライブのメニューで右クリック=>その他=>アプリの追加　からStackEditが追加できます。
これを行うことによりDrive上のMarkdownファイルを開いた場合に自動でStackEditで開くことが出来るようになります。

#### 連携時に400エラーが出る場合
なぜか私がChromeで試した時はOAuth2連携でパラメータ不足で400エラーが出てしまいました。
ただ、後述のStackEdit側のGoogleログインを行ったところ問題なく連携できるようになったのでそちらでも行けるかと思います。

### StackEditからGoogleログインする
StackEditの右上のアイコンからGoogleログインを行い、アクセス許可を行うと
StackEdit上からGoogle Drive上にファイルが投入できるようになります。
ファイルを作成した後、右上のアイコンからpublish > publish to Google Driveを選択しましょう。
なお、GoogleDrive側から作成したMarkDownファイルの場合Publishは不要です。
社内勉強会 機械学習入門（3.機械学習って何ですか？）

# コンピューターが学習する？
人間に限らず、脳をもった動物は学習します。
うちの愛犬（トイプードル）も「トイレ」をちゃんと認識しています。
トイレの「場所」が変わろうが、トイレを買い替えて「見た目」が少しくらい変わろうが、ちゃんと認識しています。
子犬だったときに、奥さんが **ちゃんと教えてあげた** からですね。
（どのように教え込んだのか？は、私はわかりませんが、、、）
で、これと同じこと（**教えて、認識できるようにすること**）をコンピューターに対して行うのが、「機械学習」です。

# AIと機械学習
* 機械学習は、AI（人口知能）の一分野
* 機械学習は、データを学習し、学習した結果から得られた学習済みモデルをもとに未知のデータに対する予測をする
![2019-07-23_18h57_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/17c68634-35ba-b45c-2f34-5c355fd34122.png)


# ディープラーニング（深層学習）
* ディープラーニング（深層学習）は、機械学習の一手法（機械学習をさらに発展させたもの）
* 「AI ⊃ 機械学習 ⊃ ディープラーニング」という関係

# ３種類の学習方法
| 学習方法 | 説明 | 用途 | 利用例 |
|:--|:--|:--|:--|
| 教師あり学習| 学習用データには「正解」「不正解」のラベルが付いている。| データの分類、数値の予測| 画像の分類、文字認識 |
| 教師なし学習| 学習用データには「正解」「不正解」のラベルは付いていない。| データのクラスタリング（似たものを集めてグルーピングする） | ある商品を買った人が次にどのような商品を買ったか（リコメンド機能） |
| 強化学習| 学習用データには「正解」「不正解」のラベルは付いていない。| ゲームのルールなどを与えて、自ら学んで強くなる | 将棋や囲碁、自動車の自動運転 |

次回は、「4.Pythonでプログラムを書いてみよう」です。
[社内勉強会 機械学習入門（4.Pythonでプログラムを書いてみよう）](https://qiita.com/masami310/items/12473af40507791567ce)
【Flutter(Dart)】json_serializableで日付をシリアライズするとJSTがUTCに変換される

# 背景
電車の時刻表のように日時が配列形式でズラーっと並んでいるようなJSONをAPIから取得する画面を実装していました。
その際に、ブラウザ上でAPIを叩いた時とFlutter側で画面表示した際の日時にズレが生じていることに気付きました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">あ、Flutter側で受け取るタイミングでDateTimeがUTC形式に変換されてるっぽい。<br>23日5時が22日20時になってる。</p>&mdash; うめちゃん (@umechanhika) <a href="https://twitter.com/umechanhika/status/1153584883614113793?ref_src=twsrc%5Etfw">2019年7月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 原因
[json_serializable](https://pub.dev/packages/json_serializable)で日付をシリアライズすると内部では`DateTime.parse(String formattedString)`が呼ばれます。
この`parse`メソッドですが、実装を見てみるとタイムゾーンがUTC以外の場合にはUTC形式に変換するような処理が入っていました。

```dart:date_time.dart（一部抜粋）
static DateTime parse(String formattedString) {
  // 省略

  if (match[8] != null) {
    // timezone part
    isUtc = true; 
    if (match[9] != null) {
      // timezone other than 'Z' and 'z'.
      int sign = (match[9] == '-') ? -1 : 1;
      int hourDifference = int.parse(match[10]);
      int minuteDifference = parseIntOrZero(match[11]);
      minuteDifference += 60 * hourDifference;
      minute -= sign * minuteDifference;
    }
  }

  // 省略
}
```

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">DateTime.parseのコメント。<br>英語に自信がないけど、UTC以外のタイムゾーンを指定していた場合も、UTCに変換されるってことかな？ <a href="https://t.co/1ycvJy9HsV">pic.twitter.com/1ycvJy9HsV</a></p>&mdash; うめちゃん (@umechanhika) <a href="https://twitter.com/umechanhika/status/1153588923160915970?ref_src=twsrc%5Etfw">2019年7月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://t.co/uGnrQ1JuwD">https://t.co/uGnrQ1JuwD</a><br>タイムゾーンオフセットのパースには対応しているけど、データはUTCになるよってことか。</p>&mdash; うめちゃん (@umechanhika) <a href="https://twitter.com/umechanhika/status/1153598349238423552?ref_src=twsrc%5Etfw">2019年7月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 対応
json_serializableではシリアライズ処理に独自メソッドを指定することができるので、一度シリアライズされたDateTimeを端末ローカルのタイムゾーンに変換するように修正したところ、UTCからJSTに変換することができました。

```dart:sample_data.dart
@JsonSerializable()
class SampleData {
  @JsonKey(fromJson: parseDateTime)
  final DateTime dateTime;

  static parseDateTime(dynamic value) => DateTime.parse(value as String).toLocal();
}
```
CentOS7にプロキシサーバー(Squid)を組み込み

# 利用するソフトウェア
Squid
プロキシサーバーでのデファクトスタンダートと思われる。

# 手順
1.Squidをインストール
2.ファイアウォールの設定
3.Squidの起動

## Squidをインストール
```
sudo yum -y install squid
```

## ファイアウォールの設定
デフォルトではSquidのポートは3128が設定されている。このため、Port番号3128へ送られるパケットは受け取れるようにする。

```
sudo firewall-cmd --zone=public --permanent --add-port=3128/tcp #許可ポートの追加
sudo firewall-cmd --reload #設定反映
sudo firewall-cmd --zone=public --list-all #結果確認(portに3128が追加されていることを確認）
```

## Squidの起動
```
systemctl enable squid #自動起動設定
systemctl start squid #起動
```


# (オプション)Basic認証
1.Squidの設定ファイルの編集
2.パスワード設定
3.Squidの再起動

## Squidの設定ファイルの編集
```
sudo vi /etc/squid/squid.conf

squid.confファイル内の「acl CONNECT method CONNECT」の次行にBasic認証に関する設定を追記
acl CONNECT method CONNECT

# ここからBasic認証に関する追記を開始
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/.htpasswd
auth_param basic children 5
auth_param basic realm Squid Basic Authentication
auth_param basic credentialsttl 5 hours
acl password proxy_auth REQUIRED
http_access allow password
# ここまで
```

## パスワード設定
htpasswdコマンドを使用するため、もしインストールされていなければ以下のコマンドでインストールする

```
yum install httpd-tools
```

basic認証用のユーザー名とパスワードの設定を行う

```
htpasswd -c /etc/squid/.htpasswd 登録するユーザー名
#コマンド実行後、パスワードの入力を促されるのでパスワードを入力する
```

## Squidの再起動
```
systemctl restart squid 
```

これで設定完了。あとはブラウザにプロキシ設定を行って動作確認をする。

# 参考リンク
https://turningp.jp/server-client/linux/squid-install
https://www.server-memo.net/centos-settings/firewalld/firewalld.html
https://www.server-world.info/query?os=CentOS_7&p=squid&f=3
Rで周波数スペクトルの統計量を算出する

## はじめに
振動データを機械学習モデルで分類するタスクを行う上で、周波数スペクトルの統計量を特徴量として利用したいことがありました。
しかし、自分が普段利用しているPythonではそのようなライブラリがなかったため、Rの`seewave`というパッケージを利用して算出したので、その流れを紹介します。

### 結論
Rパッケージ`seewave`の中の`specprop`という関数を利用することで、[こちら](https://www.rdocumentation.org/packages/seewave/versions/2.1.0/topics/specprop)のような統計量を算出できます。

## seewaveをインストールする

```R:
install.packages("seewave", dependencies = TRUE)
```
上記のコマンドでインストールできます。

## スペクトルを求める

```R:
library(seewave)

data = read.table('data.txt')
data_spec = spec(wave=data, f=2048)
```

`data.txt`に振動データが保存されているとします。

振動データのスペクトルは`seewave`パッケージの`spec`という関数を利用することで求められます。
spec関数の詳細は[こちら](https://www.rdocumentation.org/packages/seewave/versions/2.1.3/topics/spec)をご覧ください。

必須引数は、`wave`と`f`で、`wave`にはデータを入力して、`f`には、サンプリング周波数を入力します。

ここまでで、以下のように振動データのスペクトルを得られます。

<img width="415" alt="スクリーンショット 2019-07-23 18.50.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257347/810cc23b-04cb-877e-46ea-d5481947c494.png">
       振動データ(data)

<img width="413" alt="スクリーンショット 2019-07-23 18.48.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257347/82418d71-9df0-3789-9180-f7207842e286.png">
   振動データの周波数スペクトル(data_spec)


## スペクトルの統計量を求める

```R:
specprop(data_spec)
```
最後に関数`specprop`を利用して、スペクトルの統計量を求めます。

下記のように、統計量を項目ごとに求めてくれます。

```
$mean
[1] 242.0646

$sd
[1] 130.2206

$median
[1] 211.0143

$sem
[1] 2.377493

$mode
[1] 129.067

$Q25
[1] 138.2861

$Q75
[1] 319.5945

$IQR
[1] 181.3084

$cent
[1] 242.0646

$skewness
[1] 4.525991

$kurtosis
[1] 37.61237

$sfm
[1] 0.2065057

$sh
[1] 0.8636798

$prec
        x 
0.3413333 
```
Zynq XADCの使い方

#環境
* ボード
    * Arty Z7(zynq評価ボード)
* ツール
    * Vivado2018.3(Windows10)
    * petalinux2018.3(Ubuntu 16.04)

#やりたいこと
zynqのXADCを使って、3ch分のアナログデータを取得します。
今回使用するボードには、XADCのCH1、CH6、CH9につながるピンがある為それを利用します。
（言い訳）
私はソフト屋なのですが、FPGA使える人間がいないとのことで回ってきました。
その為、回路のことは正直よく理解していません・・・

#ハードウェアの作成
##PSの配置
定番ですがPSを配置します。
![1_初期.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354707/b98bd8cb-05de-ff2c-8250-eec7927d643f.png)

##XADCコアの配置
XADC WizardがIPに登録されているので配置し、自動配線します。
![2_ウイザード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354707/c1af4bc3-71ad-ece8-7266-5757314c71fa.png)


##XADCコアの設定
デフォルトの設定だと、1ch分のデータしか取得できません。今回は3ch分のデータを取得するために、「Startup Channel Selection」を「Channel Sequencer」に変更します。
![3_channelseq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354707/06688a00-eb83-d138-4186-aba696b25aaf.png)

変更すると「Channel Sequencer」タブが表示されるので必要なチャネルを有効化します。
![4_チャネル設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354707/dc8aa799-5b6f-f8a8-d6f6-52f0aa701d8b.png)

##ポート接続
アナログ入力を接続します。
![5_ポート接続.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354707/d7fc05d3-f00f-5b7f-5510-d1c1bb2ca0db.png)

ピン設定は固定なので変更できません。接続するだけでOKです。

#ソフトの作成
##Linux
デバイスツリーにXADCが接続されていることを記述する必要がありますが、便利なことに自動で吐き出してくれました。
その為、プロジェクト作成以外は特別なことはしていません。

##値の取得
XADCに割り当てられたアドレスが、0x43C00000になります。
デフォルトの設定で動くといいなと思いながら、とりあえず現在のADCされたデータが取得できるレジスタをリードしてみます。

* リードアドレス
    * CH1:0x43C00244
    * CH6:0x43C00258
    * CH9:0x43C00264

ターミナルを起動し、
 
```
#devmem 0x43C00244 w
```
と入力するとレジスタの値を取得できます。
繰り返し読むとCH1は値が変化しているので何となく読めていそうです。
しかし、CH6、CH9は常に同じ値しか取得できないので失敗です。そんな甘くはありませんでした・・・。

##Sequence registerの設定
マニュアルをちゃんと読んでみると「Sequence register」なるものがいます。どうやら、このレジスタに対して読みたいチャンネルのビットを立てれば読めそうです。

```
#devmem 0x43C0324 w 0x00000242
```
をして

```
#devmem 0x43C00244 w
#devmem 0x43C00258 w
#devmem 0x43C00264 w
```
をやると取得することができました。
C++ Builder 10.2 Tokyo + Windows 10 v1903 > 不具合 > TDatePicker, TTimePicker > 見当違いのところに表示される

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3 
Windows 10 v1903
```

### 不具合概要

- 二台のモニタ
- サブモニタにフォーム表示
- TDatePikcer, TTimerPickerを使用するとメインモニタにドラムロールUIが表示される


図1. サブモニタのフォーム `[異常]` (TDatePicker選択時)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/ff0a747b-217f-5cb8-de30-c099309c0f5a.png)

図2. メインモニタの左上に表示される `[異常]` (TDatePicker選択時)
![{F961FC93-C286-49E4-900C-FCB0FB2445CD}.png.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/6f4a2fa9-ea30-11df-f9b0-40c63c7e3975.jpeg)


マルチモニタで動作検証していないのだろう。

本来は、図1のフォーム上のTDatePickerの近くにドラムロールが表示される(図3)。


図3. メインモニタでのフォーム動作 `[正常]`
![{A90F4251-17C0-4EE1-8468-1346FBF7BE52}.png.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/b69710b8-7433-364a-a104-91cec59b07f7.jpeg)

### 連絡
(2019-07-24)

IDERAのforumに連絡した。

Embarcadero Developer Network (EDN)は2019年7月24日現在、接続できず。