OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails]DMユーザーリスト表示

#はじめに
個人で学習のため作成しているアプリにログインユーザーがDMを行っている相手のユーザーリストを作成しました。
その中でhelperメソッドを作成し使用したため備忘録として書きます。
今回は部屋ができた順で表示させますが、違う記事でメッセージの新しい順に表示をさせています。
[[Rails]DMリストの表示順をjoinsを使用してソートする](https://qiita.com/Masanori_N/items/d819fffda590669edbdf)

####仕様

- DMの部屋が存在する（過去に部屋を作成した）ユーザーを一覧で表示
- 表示内容は
    - ユーザー名
    - 最新メッセージの内容
    - まだメッセージがなければ[ まだメッセージはありません ]と表示

- テーブル
    - user:  ユーザーデータ
    - room:  DMを行う部屋データ
    - entry: userとroomの中間テーブル

###usersテーブル
| Column | Type | Options |
|:--|:--|:--|
| id | integer |  |
| name | string |  |
##### association

- has_many :entries, dependent: :destroy
- has_many :rooms, through: :entries

###roomsテーブル
| Column | Type | Options |
|:--|:--|:--|
| id | integer |  |
##### association

- has_many :entries, dependent: :destroy
- has_many :users, through: :entries
- has_many :messages, dependent: :destroy

###entriesテーブル
| Column | Type | Options |
|:--|:--|:--|
| id | integer |  |
| user_id | references | foreign_key: true |
| room_id | references | foreign_key: true |
##### association

- belongs_to :user
- belongs_to :room

###messagesテーブル
| Column | Type | Options |
|:--|:--|:--|
| id | integer |  |
| text | string |  |
| user_id | references | foreign_key: true |
| room_id | references | foreign_key: true |
##### association

- belongs_to :user
- belongs_to :room

##コントローラーの編集
現在ログインしているユーザーのroomデータを全て取得します。

````rooms_controller.rb
  def index
    @rooms = current_user.rooms
  end
````

##helperメソッドの作成
今回はDMの相手ユーザーの名前と最新メッセージの内容を表示させます。
そのデータの取得を今回はhelperメソッドを作成して行います。

````rooms_helper.rb
module RoomsHelper

  # 最新メッセージのデータを取得して表示するメソッド
  def most_new_message_preview(room)
    # 最新メッセージのデータを取得する
    message = room.messages.order(updated_at: :desc).limit(1)
    # 配列から取り出す
    message = message[0]
    # メッセージの有無を判定
    if message.present?
      # メッセージがあれば内容を表示
      tag.p "#{message.text}", class: "dm_list__content__link__box__message"
    else
      # メッセージがなければ[ まだメッセージはありません ]を表示
      tag.p "[ まだメッセージはありません ]", class: "dm_list__content__link__box__message"
    end
  end

  # 相手ユーザー名を取得して表示するメソッド
  def opponent_user(room)
    # 中間テーブルから相手ユーザーのデータを取得
    entry = room.entries.where.not(user_id: current_user)
    # 相手ユーザーの名前を取得
    name = entry[0].user.name
    # 名前を表示
    tag.p "#{name}", class: "dm_list__content__link__box__name"
  end

end
````

## ビューの作成
DMリストからDMルームに移動できるようにします。

````index.html.haml
.dm_list
  - @rooms.each do |room|
    .dm_list__content
      = link_to room_path(room), class: "dm_list__content__link" do
        .dm_list__content__link__box
          %h3.dm_list__content__link__box__name
            = opponent_user(room)
          %p.dm_list__content__link__box__message
            = most_new_message_preview(room)
````

# おわり
以上で、DMリストを表示できました。
今までコントローラーに書いていたロジックをhelperメソッドを作成することで、綺麗に書くことができました。
最後まで読んでいただき、ありがとうございました。
Ruby on Rails チュートリアル 6日目

##6日目
今日は、チュートリアルの3章を終わらせました。
今回は、そこまで躓くこともなく出来たかなと思います。「rails test」を使って作業していくことを今回学びました。ただ、「git push」をこまめに使えと書いてあったのはいいのですが、どのタイミングで使えばいいのかがあんまりわかりませんでした。いつでもしていいのか、それともなにか新しく作ってみたらすぐにやるべきなのかを教えてもらえると嬉しいです。
明日からは、4章をやっていきます。
netstatで通信の接続状況を定期監視

# 接続状況を定期的に記録するバッチ

C# HttpClientプログラムでポート枯渇が発生する事象があり、使用状況を監視するのに作成したバッチです。

バッチを実行するカレントディレクトリに現在日時のディレクトリを作成し、定期的に実行するnetstat実行結果をファイルに出力します。

```bat:netstat_monitor.bat
@ECHO OFF

REM 現在日時の文字列を変数OUTPUT_DIRに設定し、ディレクトリ作成
FOR /F %%i IN ('powershell Get-Date -Format "yyyyMMddTHHmmss"') DO SET OUTPUT_DIR=%%i
SET OUTPUT_DIR=netstat_%OUTPUT_DIR%
ECHO 出力先フォルダ: %OUTPUT_DIR%
MKDIR %OUTPUT_DIR%

:loop

REM 現在日時の文字列を変数NOW_STRに設定
FOR /F %%i IN ('powershell Get-Date -Format "yyyyMMddTHHmmss"') DO SET NOW_STR=%%i

REM 現在日時のファイル名でファイルを作成
ECHO %NOW_STR% > %OUTPUT_DIR%\%NOW_STR%.txt

REM 現在日時を表示
ECHO %NOW_STR%

REM netsatat採取 TCPのみ
netstat -anop TCP >> %OUTPUT_DIR%\%NOW_STR%.txt

REM ループ前にスリープ
powershell sleep 5

GOTO loop
```

```:実行例
CMD>netstat_monitor.bat
出力先フォルダ: netstat_20200418T104446
20200418T104446
20200418T104451
20200418T104457
20200418T104502
:

停止するには[CTRL]+[C]
```

# 参考文献
  - [netstat - ホストのネットワーク統計や状態を確認する](https://www.atmarkit.co.jp/fnetwork/netcom/netstat/netstat.html)
  - [TCP/IP通信の状態を調べる「netstat」コマンドを使いこなす (1/2)](https://www.atmarkit.co.jp/ait/articles/0207/20/news003.html)
  - [【Windows 10対応】Windowsの「timeout」「sleep」コマンドでバッチファイルの実行を一時停止する](https://www.atmarkit.co.jp/ait/articles/1206/08/news137.html)

# 続編
  [netstatで通信の接続状況を定期監視し可視化] (https://qiita.com/curvaceous410/items/b862bbca78e6d544b41e)を追記しました
Vuejs | Circular Dependency | Vuex + API + Axios

ばべるとかうえぶぱっくとか諸々verupしたら、以下のようなエラーを吐いてコンパイルができなくなってしまったので、その解決方法を記しておきます。

```terminal
 ✘  https://google.com/#q=import%2Fno-cycle  Dependency cycle via ../utils/httpCommon:1=>../stores:4=>./modules/root:4
  src/stores/modules/timer.js:1:1
```

## Dependency cycle via ...?
Circular Dependencyということみたいです。（初めて知った！w）
なにが起きているのかと言うと、ぐるぐるimportし続けてしまう連鎖が起きているっていうことみたいです。
ここの説明が僕的にとてもわかりやすかった。。
https://stackoverflow.com/questions/38042130/what-is-a-circular-dependency-and-how-can-i-solve-it

## こうなたっときのストラクチャー
### 1) timerモジュールがTimerApiをimportする
```js
// stores/modules/timer.js

import TimerApi from '../../api/timer';

const state = { ... }
const getters = { ... }
const actions = {
    :

  async hoge({ commit }, data) {
    const res = await TimerApi.create(data);
    if (res.status) {
      const time = res.data.hoge
      commit('HOGE', { time })
    }
  },

    :
}
const mutations = { ... }

export default {
  state,
  getters,
  actions,
  mutations,
};
```

### 2) TimerApiがhttpCommonをimportする
```js
// api/timer.js

import HTTP from '../utils/httpCommon';

export default {
  create(data) {
    const formData = {
      'hoge': { ...data },
    };
    return HTTP({
      method: 'POST',
      url: '/XXX/YYY/ZZZ',
      data: formData,
    });
  },
  
  :

};
```

### 3) httpCommonがstoreをimportする
```js
// utils/httpCommon.js

import axios from 'axios';
import router from '../router';
import store from '../stores';

const HTTP = axios.create({ baseURL: process.env.API_ENDPOINT });

HTTP.interceptors.request.use((config) => {
  config.headers = getHeader();
  return config;
});

:

```
### 4) storeがmodules/rootをimportする
```js
// stores/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import {
  modules, getters, mutations, actions
} from './modules/root';

Vue.use(Vuex);

:
const store = new Vuex.Store({
  modules,
  getters,
  mutations,
  actions,
});

export default store;
```

### 5) modules/rootがtimerモジュールをimportする　==> 1に戻る⁉️
```js
// modules/root.js

:

import TIMER from '/timer'

:

const modules = {
  :
  TIMER
  :
}

:

export { 
  modules, xxx, yyy, zzzz,
}
```

## 解決方法 => Dependency Injection
https://www.reddit.com/r/vuejs/comments/foy2nu/vuex_api_service_layer_axios_interceptors/
> We use a form of dependency injection in the API file, where instead of importing the store, it exports an init function which takes the store as an argument. Then in main.js, the init function is called and passed the store.


### 実装
**今回routerでもcircular dependecyが起こっていたので引数はstoreとrouter二つをとるようにしています**

#### 1) httpCommonjs
-  storeとrouterをimportする記述を消す
-  storeとrouterを引数とし受け取るinit functionとしてexportする記述に変更

```js
import axios from 'axios';

const HTTP = axios.create({ baseURL: process.env.API_ENDPOINT });

export default function init(store, router) {
  HTTP.interceptors.request.use((config) => {
    config.headers = getHeader();
    return config;
  });

  :

  if (store.method !== undefined) {
    return HTTP(store);
  }

  :

}
```

#### 2) main.js
```js
:

import router from './router';
import store from './stores';
import init from './utils/httpCommon';
init(store, router);

:
```


#### DONE!!!!
Visual Studio Online CLI でセルフホスティング - Windows

## Visual Studio Online とは
どこからでもアクセス可能なクラウドを利用した開発環境。あらゆる場所から開発できます。
ブラウザだけでかく、 Visual Studio Code および Visual Studio もサポートされています。

## 準備必要なもの
- Microsoft Account
- Azure Subscription

## Powershell Script Download
下記サイトから必要のスクリプトをダウンロードできます。
https://docs.microsoft.com/en-us/visualstudio/online/reference/vsonline-cli

## Visual Studio Online Download
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/617ecc04-f13d-9295-0163-510c4c503390.png)

### Powershell Script 実行し、ダウンロードする
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/aecf90e6-a11b-65a9-a8cb-78cbd7ed8460.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/2e90b93e-8ceb-8769-febb-4002caf2bc2b.png)

## 「サービスとしてログオンする」の権限付与
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/0a9bcaba-5305-9dfb-42f2-12f9fa1da407.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/07a3112c-1560-bac4-ca9a-ef1187a4914f.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/f06a356c-7c58-8147-bdd7-42bfc7b47d2b.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/3c5d08e6-5772-8c23-fd64-97cf9f671e7a.png)

## Visual Studio Online Install
コマンドプロンプトで実行する必要があります。**`vso start`** でインストール開始...
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/9dc38d42-62f3-58ee-c9b7-d2c9f632dc7f.png)

### 認証コードの入力
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/594e1758-cc2c-b90b-78e8-fc73cd821e7d.png)

### Microsoft Account のログイン
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/fae34e8a-fa12-cbc7-36c8-57116739fb1f.png)

### Visual Studio Services Client のアクセス許可
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/86d73b73-ff89-ea79-e330-8aa251aa81a7.png)

### 認証完了
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/6988970d-fc1e-94d5-d4e4-568673e212d2.png)

### インストールの続き、途中でパスワードの入力がある
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/baa04bd7-8331-f656-aefb-43aac40ef494.png)
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/d1e6abac-e133-8d3b-1875-678793826b50.png)

## インストール完了
最後に表示されるURLで、Visual Studio Online にアクセスできます。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/979f1662-1aa1-b518-553b-e9b6ce79832e.png)

## 体験してみる
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/9465aa65-c538-f510-fc61-d2ba4cfae284.png)

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/7e6f1723-e176-6e84-64be-8a4789081467.png)

## 最後に、Uninstall
**`vso stop`** のコマンド実行すると、下記のように Uninstall されます。
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160072/0223535c-374e-7ded-4dcb-e97908c113d6.png)
PythonでSeleniumを使った時の例外に対する対処

#はじめに

スクレイピングでデータを収集するということでここはPythonを使いやっていこうとなりSeleniumを使用しました。その時の様々なエラーに対する処理についてまとめました。
<font color="Red">スクレイピングが禁止になっているサイトもあるのでそこは使用する時に調べて下さい。</font>

#エラーに対する処理
自分が、一番多く遭遇したエラーは<b>TimeoutException</b>です。この原因としては
####ボタンが表示される前にクリックをしてしまった
####要素を取得することができなかった
などの理由があげられます。その対策として下記の二つが挙げられます。

```python
driver = webdriver.Chrome(PATH)
# ボタンが表示されるのを10秒待機
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, 'idを記入'))) #BYの部分はXPATHなどでもOK
# ボタンをクリック
driver.find_element_by_id('idを記入').click()
```
上記の処理は、ボタンが表示されるまでの10秒の間は待機します。
(10秒たっても表示されない場合はエラーとなります)

```python
driver = webdriver.Chrome(PATH)
# 指定のドライバーの要素が表示されるまで10秒待機
driver.implicitly_wait(10)
driver.get(URL)
element = driver.find_element_by_id('idを記入')
```
上記の処理は、指定されたドライバーの要素すべてに対して表示されるまで待機します。
(10秒たっても表示されない場合はエラーとなるります)

次によく使用するのが、for文のループ処理やwhile文のループ処理です。
for文を使用した時に途中でエラーが発生して処理が止まらずに回って欲しい時にするのが例外処理で使用する`try except`です。

```python
for i in mylist:
    try:
        # 何らかの処理
    except:
        pass
```
上記の処理は、tryの中で何らかのエラーが発生した時にexceptに処理を移動しpassの処理が走り次の処理に移行してくれます。exceptに対してはすべてのエラーをキャッチするようにしているので、できることならその都度エラー処理を確認してそのエラーをキャッチするようにするのがオススメです。

最後に、できるだけsleepの処理を使用せずに処理をした方がいいです。やたらと、無駄な時間を取られる時もあるからです。forやwhileで早く回してる時に接続が切られる時があるのでその時には、sleepを入れて対処しています。

#おわりに
スクレイピングは、不安定になったりする時がたまにあるのでエラーを確認してその都度エラーにあった対処をすることがオススメです。今後、エラーを見つけたら加えていきます。

#参考文献
https://www.seleniumqref.com/api/python/time_set/Python_implicitly_wait.html
https://qiita.com/snowp/items/d5892708bc41fa7c4e39
Pythonのre.compileは必要か？

#目的
Pythonの正規表現等で使う**reモジュールにおけるcompileは、必要か？**を調べる。

以下のようなもの。

```
pattern2 = re.compile('.ou.')
```

#結果
多くの方が書かれているように、**特別、意味はない**と思われます。これによって**速くなるなどのメリットはない。**

ワタシも、速くなるようなことを期待しました。

しかし、

```
pattern2 = re.compile('.ou.')
```

のようなわずかなインプットに対して、時間をかけて何をする必要がある？
時間をかけてすることがないのであれば、毎回実施しても良いハズ。

（キャッシュ等の話もありますが、まあ、無理やり感があります。）

結論としては、
**特に意味はない。ただし、コードの書き方が変わりますので、その観点では、意味がある可能性あり。(下記、参照）**

これは、
**compileという言葉は、ちょっと、印象が強すぎるだけかも。。。
例えば、set_pat(pattern)みたいなのだと、誰も、気に留めなかった気がします。**

#参照

stackoverflowに、参考になりそうな、質疑の結果がありました。
https://stackoverflow.com/questions/452104/is-it-worth-using-pythons-re-compile

タイトル：**Is it worth using Python's re.compile?**

* 1番の回答としては、経験として、**速さは変わらない。**
* 2番の回答が、**コードの書き方が変わるので。。。いいかも**

でした。

#まとめ
特に、ありません。
(最初は、別のことも含め、処理時間を計ろうとしましたが、ここに落ちました。）
ローカル開発環境でCSSが反映されない原因（キャッシュが残っていた）

まだまだPCについての知識が乏しいので、当たり前な人からしたら当たり前なのかもしれませんが、**自戒の念**も込めて記しておこうかと...

<h1>chrome内でキャッシュが残っていた</h1>
ローカル開発環境で開発中、CSSを何度設定しても、反映されず。。。
viewファイルの読み込みが間違っているのか、classの名前に齟齬があるのかとコードを見返すもなかなか判明せず。反映されないCSSを設定したままそのまま1日が経過し、何となく開発中のページを開いてみると、いつの間にやらCSSが反映されていました。かと思いきや、再度CSSを解除しても反映されず。
調べてみると、chrome内でキャッシュが残っているので、設定が反映されないとのこと。

<h2>対処方法</h2>
①問題があるページでデベロッパーツールを開く。

②リロードボタンで右クリックして、『キャッシュの削除とハード再読み込み』をクリック。

これで無事反映されるようになりました。何とも簡単な。。。
Spring-Batchをストレスなく使う

# Spring-Batchをストレスなく使う

- TLDR；
  - spring-batchにはジョブ状態を管理する機能があるが、邪魔なので`application.yml`で無効にできる
  - その他の関連する設定についても書く


## application.ymlの設定

- banner-mode: off
  - spring-bootの起動時のバナー表示をしない(off,console,logの設定ができる）
- initilization-schema: never
  - spring-batch起動時にバッチジョブ用テーブルを初期化するかどうか


```yaml
spring:
  main:
    banner-mode: off
  batch:
    initilization-schema: never
```

## アノテーション設定
- spring-batchはジョブの状態を保存しようとするが、特にそういった機能はいらない
- ここを参考にしてデータソース自体を作らせないようにする
  - [Spring BatchでIn-MemoryのJobリポジトリを利用する方法](https://qiita.com/KevinFQ/items/d24de607795f75866864)

```java
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
```




## 参考

- [Spring BatchでIn-MemoryのJobリポジトリを利用する方法](https://qiita.com/KevinFQ/items/d24de607795f75866864)
[Unity初級]this.gameObject.SetActive

#概要
自オブジェクトを消そうとした時、thisの記述をミスしました。備忘録として記事にします。
#本文
オブジェクトが何かにぶつかったとき自分自身を画面から消すようなスクリプトを書こうとしましたがエラーになります。

```cs
    void OnCollisionEnter2D(Collision2D collision) {
        if (collision.gameObject.name == targetObjectName){
            this.SetActive(false);
        }

    }
```

gameObjectが無いと構文的におかしいものでした。

```cs
    void OnCollisionEnter2D(Collision2D collision) {
        if (collision.gameObject.name == targetObjectName){
            this.gameObject.SetActive(false);
        }

    }
```
rubyのforでハッシュを扱った時の挙動

普段for文なんて使わないので意外とその挙動を忘れていた。

```
-> % ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
```
#### hashをforでループさせる場合、要素としてkeyとvalueから成る配列が代入される

```rb:
#keyとvalueのペアを配列として扱う

for val in {a: 1, b: 2}
  p val
  p val[0]
  p val[1]
end

#=>
[:a, 1]
:a
1
[:b, 2]
:b
2
```

#### 要素を配列として扱いたくない場合には次のようにする

```rb:
for key, value in {a: 1, b: 2}
  p key
  p value
end
#=>
:a
1
:b
2
```
MVCモデルについて

## MVCモデルとは
MVCモデルとはModel、View、Controllerにプログラムを分けて実装する

## JavaScript側でMVCが進んだ背景について
AJAXの普及により、コンテンツ表示の主となり、それに伴ってコード量も増加した。
また、一気にWEBコンテンツは複雑、かつ高度化が進んでいった。

## サーバー側のMVC
Controllerがクライアント(画面側)からのリクエストを受けて、そのリクエストからModelの処理に進む。
Modelは場合によっては、DB上のデータを操作する。
Modelの処理結果により、Controllerに返して、ControllerからViewに引き渡す。
ViewはControllerからう蹴ったデータ、情報を基に、HTMLを生成し、クライアント(画面）に返す。
サーバー側のMVCと全く同じではないが、JavaScript側でもMVCを意識して実装していけないほど、
JavaScriptの仕事が複雑になってきた。

## JavaScript側のMVC
JavaScript側のMVCは、サーバー側のMVCとは少し異なる。
厳密に言うと、Cotrollerに相当するものがなかったり、ViewがCotrollerの役割を兼用していたりする。
「MV」や「M-V-whatever(MVW)」と呼ばれたりする。
JavaScriptでMVCモデル実現するためには、JavaScriptのフレームワークを使用するのがスタンダード。
JavaScriptでのMVCは、多くのケースでは、Viewnに相当する部分は、ユーザーアクション＊１を受け取る。
何かの処理のトリガーをHTMLのイベントとして拾うことが多いので、Cotrollerの一部をView側で担うことが多い。
Viewは処理のキャッチ後に、Modelに引き渡す。
Model側では、Webサーバーに対し、データ操作をリクエストする。
ここで、APIのXMLHttpRequestを使う。
View側では、レンダリング処理を行う。

## JavaScriptの用語まとめ
レンダリング処理は、DOM(Document Object Model)操作やCSS操作を指す。
DOM操作は、特定のコンテンツを追加、変更したり削除したりする処理を実行する操作。
CSS操作は、CSS操作はスタイリングの変更やアニメーション(移動や回転など)の処理を実行する。

*1 マウスを入力したり、文字を入力したりする行為
Babel6 --> 7 やったこと memo

Babel6から7へのverupでやったことをまとめておきます

## babel-upgradeで
https://github.com/babel/babel-upgrade
コマンドをうつと自動で全てbabel7に合うようにファイルを書き換えてくれます。（ここに全て書いてありますが、）
僕はinstallする前にどんな差分が出るのかみたかったのでwriteだけにして、確認してからinstallしました。


```
$ npx babel-upgrade --write
$ yarn install
```

## .babelrc --> babel.config.js
1) .babelrcをbabel.config.jsという名前に変えます。
2) jsファイルになるので書き方を以下のように変えます。

```js
// .bablerc
{
  "presets": [...],
  "plugins": [...],
  "env" : {...}
}
```

```js
// babel.config.js

module.exports = function (api) {
  api.cache(true);

  const presets = [ ... ];
  const plugins = [ ... ];
  const env = { ... };

  return {
    presets,
    plugins,
    env
  };
}
```

### [余談].babelrcのままでも動くけど。。。
なぜかjestが以下のように"Jest encountered an unexpected token"というエラーを吐いてこけてしまう。
vueファイルを持っているnode_moudle（この時はvue-stepper）をうまくtransformできていないのが原因のよう。しかしながらtransformIgnorePatternsにはきちんとそれを処理するように記述している。。。（https://github.com/vire/jest-vue-preprocessor/issues/10#issuecomment-318286914）


```terminal
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/yohei_goto/Workspace/XXXXXXXXXXX/node_modules/vue-stepper/src/Translations.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export default {
                                                                                             ^^^^^^

    SyntaxError: Unexpected token 'export'

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1086:14)
      at node_modules/vue-stepper/src/HorizontalStepper.vue:53:1
      at Object.<anonymous> (node_modules/vue-stepper/src/HorizontalStepper.vue:255:3)
```
#### ==> 原因: .babelrcのままだとうまくコンパイルできないことがあるみたい
https://github.com/facebook/jest/issues/6229#issuecomment-403539460

## corejs２ --> corejs3へ
以下のようなwarningがでていたので

```
warning @babel/runtime-corejs2 > core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
```

やったこと

```
$ yarn remove @babel/runtime-corejs2
$ yarn add core-js@3 @babel/runtime-corejs3
```

```js
// babel.config.js
// corejs3を使うよう書き換え

...

 const plugins = [
    "transform-vue-jsx",
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
      }
    ],

...
```


もし何か足りないことや、間違っていることなどございましたら教えてくださいませ🙇‍♂️
Numpyのarrayとasarrayについて

Python1年生を学習中にnumpy.asarrayという表記が出てきたので調べてみた。
調べるとnumpy.arrayというのも出てきたので違いを解説する

※Numpyには配列を高速に扱うためにndarrayクラスがあり、
 ndarray配列を生成するためにnp.array()を用いる。

## np.array(リスト)
```
import numpy as np
print(np.array([1, 2, 3]))

>>>出力結果
>>>[1 2 3]
```
続いて
## np.asarray(リスト)
```
import numpy as np
print(np.asarray([1, 2, 3]))

>>>出力結果
>>>[1 2 3]
```
では何が違うのか？

#ここが違う
##np.array
```
copy_array[0] = 100
print(x)
print(copy_array)

>>>[1 2 3]
>>>[100 2 3]
```
##np.asarray
```
copy_asarray[0] = 100
print(x)
print(copy_asarray)

>>>[100 2 3]
>>>[100 2 3]
```
結論としてはasarrayはコピー前の物も引き継いでいる。
[Python]ベクトル演算

## ノルム
$ \left\Vert \mathbf{a} \right\Vert_2 = \sqrt{\sum_{i=1}^n a_i^2} = \sqrt{a_1^2 + a_2^2 + a_3^3 + \cdots + a_n^2} $ 

```
import numpy as np
a = np.array([1, 2, 3])
n = np.linalg.norm(a)
print('norm=',n)

norm= 3.7416573867739413
```

## 内積
$ \mathbf{a} \cdot \mathbf{b}= \sum_{i=1}^{n} a_i b_i = a_1 b_1 + a_2 b_2 + a_3 b_3 + \cdots + a_n b_n $

$ \mathbf{a} \cdot \mathbf{b}= \left\Vert\mathbf{a}\right\Vert\left\Vert\mathbf{b}\right\Vert\cos (\theta) $

$\theta$はベクトル$\mathbf{a}$とベクトル$\mathbf{b}$の間の角度

```
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
p = np.dot(a,b)
print('dot product=',p)

dot product= 32
```

## 外積
$ \mathbf{a} \times \mathbf{b} =\left\Vert\mathbf{a}\right\Vert\left\Vert\mathbf{b}\right\Vert\sin (\theta) $

$\theta$はベクトル$\mathbf{a}$とベクトル$\mathbf{b}$の間の角度


$ \begin{pmatrix}a_1\\ a_2\\ a_3 \end{pmatrix} \times \begin{pmatrix}b_1\\ b_2\\ b_3\end{pmatrix} = \begin{pmatrix}a_2b_3-a_3b_2\\ a_3b_1-a_1b_3\\ a_1b_2 - a_2b_1 \end{pmatrix} $

```
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
p = np.cross(a,b)
print('cross product=',p)

cross product= [-3  6 -3]
```
pipenvのinstall時に、No module named '_ctypes'が発生する

## 環境

OS:
  Amazon Linux 2
Python:
  3.8.1

## 事象

pyenvでpython3.8.1をinstall後、`pip install pipenv`を実行すると以下のエラーが発生し、installできない。

```
    ERROR: Command errored out with exit status 1:
     command: /root/.pyenv/versions/3.8.1/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-shwfwhga/distlib/setup.py'"'"'; __file__='"'"'/tmp/pip-install-shwfwhga/distlib/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base pip-egg-info
         cwd: /tmp/pip-install-shwfwhga/distlib/
    Complete output (11 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/root/.pyenv/versions/3.8.1/lib/python3.8/site-packages/setuptools/__init__.py", line 20, in <module>
        from setuptools.dist import Distribution, Feature
      File "/root/.pyenv/versions/3.8.1/lib/python3.8/site-packages/setuptools/dist.py", line 35, in <module>
        from setuptools import windows_support
      File "/root/.pyenv/versions/3.8.1/lib/python3.8/site-packages/setuptools/windows_support.py", line 2, in <module>
        import ctypes
      File "/root/.pyenv/versions/3.8.1/lib/python3.8/ctypes/__init__.py", line 7, in <module>
        from _ctypes import Union, Structure, Array
    ModuleNotFoundError: No module named '_ctypes'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
```


## 対処方法

以下で解決

```sh
pyenv uninstall 3.8.1
sudo yum install libffi-devel
pyenv install 3.8.1
```


この状態で

```sh
pip install pipenv
```

すればinstallできます！
【herokuへのデプロイ時】bash: rails: command not found　のエラー解決方法

herokuへのデプロイでタイトルのエラーが発生した為、解決方法を記載させていただきます

###環境
MacOS
Rails 5.2.4.1
heroku/7.39.2 darwin-x64 node-v12.13.0

###状況
開発環境で、作成したRuby on Railsのアプリケーションを、
herokuにデプロイするために、
**①heroku create**
**②git add .**
**③git commit -m "コミットメッセージ "**
**④push heroku ブランチ名**
行った。

⑤**heroku run rails db:migrate**
これで「heroku上でアプリが表示できる！」と期待するも、

```
$ heroku run rails db:migrate
Running rails db:migrate on ⬢ アプリ名... up, run.1884 (Free)
bash: rails: command not found
```
**bash: rails: command not found**という
エラーが出てしまった。

###原因

原因は非常にシンプルで、私がdevelopブランチをherokuにpushしていたことが関係していました。

###解決策

master以外のブランチを、herokuにpushする際には、

```
$ git push heroku 【ブランチ名】 :master
```
と、最後にmasterをつけてpushする必要がありました。

私の場合は、**git push heroku develop:master**
で、無事デプロイすることができました。
ネット非接続のwindows terminal インストール

#はじめに
　windows terminal はmicrosoft-storeでインストールするのが一般的だが、ネットにつながっていないPCにインストールする手順

# 詳細
- sourceforge.netからダウンロード
:(https://sourceforge.net/projects/windows-terminal.mirror/)
- **.msixってのを*.zipに改名
- *.zipを解凍
- 解凍した中のwindows.terminal.exeを実行

#注意
　**.msixをクリックすると、エラーがでてインストールできないので、苦肉の策として上の方法で動いたということであります。
#Rspec での double と spy の違い ( Rspec double and spy : behaviour difference ) 

# double

unable to use undefined method
定義していないメソッドは使えない

```rb
user = double(name: :alice).name
# => :alice

user = double(name: :alice).address
# => [#<RSpec::Mocks::MockExpectationError: #<Double (anonymous)> received unexpected message :address with (no args)>]

```

# spy

定義していないメソッドも使える、メソッドチェーンができる
able to undefined method and it returns double

```rb
user = spy(name: :alice).name
# => :alice

user = spy(name: :alice).adress
# => #<Double (anonymous)>

spy.a.b.c
# => #<Double (anonymous)>

spy.to_s.b.c
# NoMethodError: undefined method `c' for "#[Double (anonymous)]":String

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ViewModelの文字列キーからリソースを取得するコンバーター

#はじめに

ViewModelにリソースを持つのはよくないよねー
ってことでViewModelにはキーだけで、そこからリソース本体を持ってくるコンバーターを作りました。

#コンバーター本体

```cs
class StaticResourceConverter : MarkupExtension, IValueConverter
{
    private FrameworkElement _target = null;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var resourceKey = (string)value;

        return _target?.TryFindResource(resourceKey) ?? Application.Current.TryFindResource(resourceKey);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var rootObjectProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        if (rootObjectProvider == null)
            return this;

        _target = rootObjectProvider.RootObject as FrameworkElement;
        return this;
    }
}
```
ProvideValueのおかげで、コンバーターが置いてあるXAMLのFrameworkElementが取れます。
あとはそこからTryFindResourceでリソースが持ってこれます。

#使用例
わかりやすくするために、不要であろう部分を削除しています。

```xml:sample.xaml
<UserControl x:Class="FreeCellPlug.Views.Card"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:vm="clr-namespace:FreeCellPlug.ViewModels"
             xmlns:conv="clr-namespace:FreeCellPlug.Views.Converter"
             xmlns:local="clr-namespace:FreeCellPlug.Views"
             mc:Ignorable="d"              
             d:DesignHeight="350" d:DesignWidth="250" 
             d:DataContext="{d:DesignInstance {x:Type vm:CardViewModel}}">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Views/Cards/Trump.xaml"/> <!-- ここにリソースディクショナリがある -->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

    <ContentControl>
        <Viewbox>
            <Rectangle Fill="{Binding ResourceKey, Converter={conv:StaticResourceConverter}}" />
        </Viewbox>
    </ContentControl>
</UserControl>
```

MarkupExtensionを継承しているおかげで、Converter={conv:StaticResourceConverter} を追加するだけで使用できます。
TryFindResourceは、コンバーターを置いたのがRectangleでも、リソースがあるUserControlまでさかのぼってくれます。


参考：
https://stackoverflow.com/questions/695624/binding-a-datacontext-string-property-to-a-staticresource-key/695657#695657
IPアドレス範囲を別のサブネットに1:1で変換する

# やりたいこと
2つのネットワークを接続したが，IPアドレスの重複があるので直接ルーティングを設定することができない．そこで接続先のIPを使われていないIP範囲に変換したい．

# 想定するネットワーク
Host H1(192.168.30.10)とH2(192.168.1.10)を通信させるために， 2台のLinuxサーバGW1とGW2を接続した．しかし，H2の属する 192.168.0.1/24 サブネットは Network 2で使われているため， GW1に直接ルーティングを設定して通信させることができない．

```
(Network 1)
    .10 192.168.30.0/24  .1     .1 192.168.1.0/24
[H1]======================[ GW1 ]================
               192.168.99.1 ||
                            ||
               192.168.99.2 ||
                       eth1 ||  .1 192.168.1.0/24  .10   
                          [ GW2 ]====================[H2] 
(Network 2)
```

# 解決策

iptables の NETMAP を使うことでNetwork 1から見たH2のIPアドレスを，Network 1で使われていない別のサブネットに変換する．

元ネタ
https://serverfault.com/questions/109569/iptables-massive-11-nat

ここでは，H2の属するサブネットのホストに， 192.0.2.x/24 でアクセスできるようにアドレス変換を行う．

## アドレス変換 (192.168.1.0/24 <-> 192.0.2.0/24)
GW2に以下の設定を追加する.

```
iptables -t nat -A PREROUTING -d 192.0.2.0/24 -i eth1 -j NETMAP --to 192.168.1.0/24
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j NETMAP --to 192.0.2.0/24
```
アドレス変換を行う宛先の範囲をNetwork 1宛に限定するため， 接続しているインタフェースで対象を限定している．これがないと，Network2内の別サブネットに対してもアドレスが変換されてしまう．

## ルーティング
static routingを追加する．
GW1には，192.0.2.0/24 宛のルーティングを設定する

```
ip route add 192.0.2.0/24 via 192.168.99.2
```
H1にも192.0.2.0/24 宛のルーティングを設定する．（GW1がデフォルトゲートウェイなら不要)

GW2には，192.168.30.0/24 宛のルーティングを設定する．

```
ip route add 192.168.30.0/24 via 192.168.99.1
```
H2にも192.168.30.0/24 宛のルーティングを設定する．（GW2がデフォルトゲートウェイなら不要)

ここまでの設定を行うことで， H1とH2が通信可能になる．

H1からH2へ通信: 変換後のアドレスを指定する

```
h1$ ping 192.0.2.10 
h1$ ssh 192.0.2.10
```

H2からH1へ通信: H1のアドレスをそのまま指定

```
h2$ ping 192.168.30.10 
h2$ ssh 1192.168.30.10
```

H１では， H2からの通信は変換後の192.0.2.10から接続された通信として見えます．

### 補足: 通信が H1→H2の片方向の場合

H1からH2方向にしか通信を開始しないのであれば， GW2にSNATを設定することでH2側のルーティング設定は不要となる．この場合はH2ではH1からの通信はGW2からの接続に見える．

GW2に以下を追加

```
iptables -t nat -A POSTROUTING -d 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
```
192.168.1.1はGW2のIPアドレス

# 最後に

単一ホスト宛のIPを書き換える SNAT/DNATの記事は各所で見つかりますが，サブネットの範囲全体のIPアドレスを置き換える方法についての記事がなかなか見つからなかったので，こちらにまとめました．
Udemyで英語 onlyの教材で日本語字幕をリアルタイムで表示する方法

## Overview
取りたい資格がある！Udemyで人気の教材がある！
**けど英語だった！私日本人！**

**そんな時に字幕を見やすくする方法を伝えたい。**

**でも過度の期待はダメ。自動字幕出力と自動翻訳の組み合わせだから。**

## Require

■ 動画に「caption」の設定があること。

以下の画像でいうと「English [Auto-generated]」がそれに値する。
<img width="552" alt="スクリーンショット 2020-04-18 8.24.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/745d4bd9-959b-b283-ddea-b2c19d2ec6a0.png">

■ Udemyの言語をEnglishに変更する
サイトの右下にある言語設定を「English」に変える
<img width="533" alt="スクリーンショット 2020-04-18 8.28.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/65a9705b-c7ad-ccb3-0332-c94e4c7d756a.png">

## Procedure

■ TransScriptを表示する
右サイドメニューに動画内の「Transcript(字幕)」が表示される。
<img width="276" alt="スクリーンショット 2020-04-18 8.34.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/5dcde5e0-830e-0147-bb91-95bda0962ef9.png">

■ Transcriptを日本語化
Transcriptの画面で右クリック「日本語翻訳」を選択

<img width="441" alt="スクリーンショット 2020-04-18 8.36.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/ec40cf8c-9951-ad9f-91f4-6511a97f4ef2.png">

■日本語化できた！
<img width="246" alt="スクリーンショット 2020-04-18 8.37.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/ee93bfc6-52d6-eb18-ad48-7bdcaf0346b3.png">

■動画を流す
動画でのメッセージに対してサイドメニューのTranscriptの背景色が変わると思う。
今「そこ」を話している。
<img width="244" alt="スクリーンショット 2020-04-18 8.45.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408070/00260946-47ec-2c5f-78b7-e3376fe4d61f.png">


## 完走した感想

■２行に渡るメッセージは翻訳がおかしくなる。
途中で切られるため、変なメッセージは日本語化解除してTranscriptからそのメッセージを繋げてGoogle翻訳に投げよう

■Transcript自体がおかしい場合がある
自動出力(auto-generated)なので、おかしい部分もある。
そこは勇気とガッツで補え！

■大事なのは雰囲気。情報０から情報Xに変わること。
全く判らないところから取っ掛かりを取得できる点。
字幕で判らなかったら最悪そこを自分で調べれば良いのです。
Promiseオブジェクトの関数に引数を使用する【編集中】

ポイント
(1) Promiseオブジェクトをreturnする関数にする
(2) 実行処理で引数指定

```元のコード.js
var getRoomData = new Promise(function(resolve,reject){
    roomInfo.on('value', (snapshot)=> {
        resolve(snapshot.val())
    });

    ・・・省略・・・

getRoomData.then(function(dbData){
    ・・・省略・・・
})
```

```正しいコード.js
var getRoomData = function(roomInfo){ //(1) Promiseオブジェクトをreturnする関数にする
    return new Promise(function(resolve,reject){
            roomInfo.on('value', (snapshot)=> {
                resolve(snapshot.val())
            });
        })

    ・・・省略・・・
 
}
getRoomData(roomInfo).then(function(dbData){ //(2) 実行処理で引数指定
    ・・・省略・・・
})
ASP.NET [C#] Core 3.X MVC ページコンテンツがリフレッシュされない

ASP.NET [C#] Core 3.X MVC ページコンテンツがリフレッシュされない (デフォされない）時の対処方法。

# `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation`をインストール

```
PM > Install-Package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
```

# Startup.csを編集

下記のライン

```
services.AddControllersWithViews();
```

こちらに変更

```
services.AddControllersWithViews().AddRazorRuntimeCompilation();
```
matplotlibで軸とラベルが重なってしまうとき


# はじめに

<img width="197" alt="スクリーンショット 2020-04-18 8.15.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/ae2fe2fe-b6fa-e0d4-bbcd-16baf0b2d328.png">

軸とラベルが重なってしまう
matplotlibをするためだけに生まれてきた男

# 解決策

```python
ax.set_ylabel("cost", rotation=270, labelpad=15)
```

上記のrotationは関係ないです（通常右向きのラベル"cost"を反対向きにさせたいので使っています．）

labelpadを指定することで，図からの距離を指定することができます．

これで以下のように，幅を開けることができました．　


<img width="142" alt="スクリーンショット 2020-04-18 8.17.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/04e9bbf4-8422-4db2-9bf7-a0ddc39f09c2.png">


# サイト

- https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.set_ylabel.html
VisualStudioCode基本操作

#まとめて移動
![block7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/c0277ec1-bc7b-b68e-80b6-78def82cafa6.gif)
①移動させたい範囲をShiftキーを使って選択

②Altキー＋上下ボタンでまとめて移動
（動画を見てわかるように順番の入れ替えもしっかりやってくれます）

③範囲選択されたままTABキーを押すと複数行同時にインデント
（Shift＋TABキーでまとめてインデント下げもできます）



#複数個所同時操作
![block8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/f5bffe4d-aa91-19af-ccc2-64167ce30332.gif)

Altキー＋マウス左クリックで複数個所にカーソルを配置できます。
同時に文字を入力したり文字を消したりできます。
（ESCキーで解除）
Bash でタイムスタンプを扱う

Bash でタイムスタンプや、その比較を行いたかったが、やり方を知らないことに気づいたので、焦らずしっかり調べて理解する。

# 現在の時間の取得

`date` コマンドは現在時間を取得する。
 
```bash
$ date
Fri Apr 17 14:54:18 PDT 2020
```

上記のは現在のタイムゾーンの値であるので、大小比較が可能な、`1970-01-01 00:00:00 UTC` からの経過秒数に変換します。`%s` がそれを表す記号ですので、`date "+フォーマット" の形式で形式をしていして表示できます。

```bash
$ date "+%s"
1587160470
```

# Date のフォーマット

```bash
$ date "+%m/%d/%Y %H:%M"
04/17/2020 15:01
```

現在時のフォーマットはこれでよいですが、特定の文字列のフォーマットから違うフォーマットに変換する場合は、`--date` もしくは `-d` の引数で文字列を渡すとよいです。

```bash
$ date -d "04/17/2020 15:10"    
Fri Apr 17 15:10:00 PDT 2020
$ date -d "04/17/2020 15:10" "+%m/%d/%Y %H:%M"
04/17/2020 15:10
```

# %s からのフォーマット
ただし、文字列ではなく、`1970-01-01 00:00:00 UTC` からの経過秒数 から変換をかけたい時は`@`を添付します。

```bash
date --date @1269553200 "+%m/%d/%Y %H:%M"
03/25/2010 14:40
```
# 大小の比較

タイムスタンプの大小比較は、`1970-01-01 00:00:00 UTC` からの経過秒数で比較するのがよさそうです。単純に比較するとよいです。結果も予想通り。ちなみに、Bashで数値の計算をしたいときは、`$((計算))` になります。

_test.sh_

```bash
#!/bin/bash

last=$(date "+%s")

sleep 1

current=$(date "+%s")

if [ $current -gt $last ]; then 
        s=$((current - last))
   echo "current is bigger than Last: difference: ${s} sec."
else
   s=$((last - current))
   echo "Last is bigger than Current: difference: ${s} sec."
fi
```

結果は想定の通りです。

```bash
$./test.sh 
current is bigger than Last: difference: 1 sec.
```
サイトの引っ越しでやったことメモ（Google Search Console周り）

基本的にはこのドキュメントに従ったのですが、備忘録を兼ねて作業をメモしていきます

https://support.google.com/webmasters/answer/6033049?hl=ja

# Start地点

## 1. redirectの設定

### サイトURLのマッピング

今回は https://ichoose.jp という求人サイトを　https://jobrainbow.jp という、リリースから1年たった新サイトに吸収統合するというもの。
サイトの構成が異なるし、ichoose掲載の企業情報ページ・求人情報ページのURLとjobrainbow側のURLは全く一致しないのでマッピングが必要になりました。

こちらは、.htaccessファイルを作成することで対応しました
スプレッドシート上で、ichoose URLと JobRainbow URLとの対応表を作り、
そこから、リダイレクトの文字列を生成しました。

```
RewriteRule ^s/&company_id=57$ https://jobrainbow.jp/companies/80 [R=301,L]
```
こんな感じの文

## 2. .htaccessの書き替え

リダイレクトが301になっていることを確認

## 2. Search Consoleの設定

### 2-1: 新しいサイトを準備する
これは上の1でなんとかおわったところ

### 2-2. URLマッピングを準備する

上で記述したように、ワイルドカードを使用したリダイレクトが使えないため、
1. https://ichoose.jp のURLの特定
2. ichoose.jp と jobrainbow.jp のURLマッピングを作成

を準備した上で
1. 新しいURLを含むサイトマップファイル
2. 前のURLを含むサイトマップファイル
を作成しました (一番簡単なTextタイプ）

```(sitemap.txt)
https://ichoose.jp/search.html
https://ichoose.jp/s/&syokusyu=593
https://ichoose.jp/s/&syokusyu=576

```

今回はこれらのサイトマップを古いサイトに配置して、https://ichoose.jp側のサーチコンソールから送信しました
（もちろん、そのサイトマップはリダイレクトから除外）

https://ichoose.jp/ichoose-final-sitemap.txt
https://ichoose.jp/redirected-sitemap.txt

### 2-3. robot.txt の更新

1. ichoose側に robot.txtが存在しないことを確認
2. jobrainbow側のrobot.txtの方で、全てのクロールが許可されていることを確認

→今回はrobot.txtの更新・削除は必要なし

### 2-4. アドレス変更ツール

条件の確認
#### 1.  サーチコンソールにて、それぞれのドメインのドメインプロパティが存在し、その所有者である事を確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/758975ca-000e-ffa4-aaae-b33d84c6fea9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/b239c84b-ac8c-2d25-9826-4732c43751f5.png)

#### 2. ステップ1：準備作業が完了していることを確認 (https://support.google.com/webmasters/answer/9370220#prerequisites)
) 

#### 3. アドレス変更ツールを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/e874133b-5d5d-94b5-5504-f8d128ff33e8.png)

「検証して更新」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/f4d8a30f-50f1-9d64-4830-792b32773237.png)

すると「クイック検証」が実施される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/fb427e1d-afe3-c70f-dc08-7a2927f723d1.png)

検証に合格とでる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/9fe73cdc-3384-f3b1-9fe8-9f53888d5bec.png)

なんか「推奨」がでた・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/8c993b1f-941f-2747-9b4a-625d98da52ee.png)

で、「移動を確認」とすると「このサイトは現在移行中です」となったです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/036e14fd-fc53-7f0c-1958-1aa5418376da.png)
【Flutter】nestedパッケージと理解するMutliProvider

[Provider](https://pub.dev/packages/provider)の内部では、[nested](https://pub.dev/packages/nested)というパッケージが使われています。
nestedパッケージを理解して、MultiProviderが実際にはproviderのネストを簡単に記述できるようにしているだけであることを確認します。
MultiProviderでは実質的には表記順にもとづいて親子関係が作られているので、順番が問題になることがあります。

# nestedパッケージ

https://pub.dev/packages/nested の通り、

```dart
 MyWidget(
   child: AnotherWidget(
     child: Again(
       child: AndAgain(
         child: Leaf(),
       )
     )
   )
 )
```
を、MyWidget~AndAgainをすべて`SingleChildStatelessWidget`もしくは`SingleChildStatefulWidget`を継承させて書き換えることで以下のように書き換えられる。

```dart
 Nested(
   children: [
     MyWidget(),
     AnotherWidget(),
     Again(),
     AndAgain(),
   ],
   child: Leaf(),
 )
```
MyWidgetの書き換え例は以下。
`SingleChildStatelessWidget`は、`build`のかわりに`buildWithChild`をoverrideさせる。(buildをoverrideしてはいけない)

```dart
 class MyWidget extends StatelessWidget {
   MyWidget({Key key, this.child}): super(key: key);
 
   final Widget child;
 
   @override
   Widget build(BuildContext context) {
     return SomethingWidget(child: child);
   }
 }
```

```dart
 class MyWidget extends SingleChildStatelessWidget {
   MyWidget({Key key, Widget child}): super(key: key, child: child);
 
   @override
   Widget buildWithChild(BuildContext context, Widget child) {
     return SomethingWidget(child: child);
   }
 }
```

# MultiProvider
Providerの内部では、すべてのProviderの祖先である`InheritedWidget`が`SingleChildStatelessWidget`を継承し、`MultiProvider`が`Nested`を継承している。
そうすることで、

```dart
 Provider<Something>(
   create: (_) => Something(),
   child: Provider<SomethingElse>(
     create: (_) => SomethingElse(),
     child: Provider<AnotherThing>(
       create: (_) => AnotherThing(),
       child: someWidget,
     ),
   ),
 )
```
を、

```dart
 MultiProvider(
   providers: [
     Provider<Something>(create: (_) => Something()),
     Provider<SomethingElse>(create: (_) => SomethingElse()),
     Provider<AnotherThing>(create: (_) => AnotherThing()),
   ],
   child: someWidget,
 )
```
のように書けるようにしている。(最初の例と同じように)
PythonGUIによる簡易営業ツール作成:デスクトップアプリ公開

今まで作成したGUIアプリを他の人にも使ってもらえる公開メモ。

1.Spyderで作成したコードを新規作成したフォルダに保存(ファイル名.py)

2.Anaconda Promptで下記コマンド入力

```
pip install　pyinstaller
```

3.Anaconda Promptで下記コマンド入力

```
cd C:\新規作成したフォルダ名　#.pyファイル保存のフォルダ先へ移動
pyinstaller ファイル名.py --onefile
```
4.少し待って、distフォルダに.exeが作成される
Dartのコンストラクタのあとのコロン

[initializer list](https://dart.dev/guides/language/language-tour#initializer-list )と呼ばれるもので、
1. assert
2. fieldの初期化
3. 他のコンストラクタ(super含む)
がサポートされており、`,`でつなげて表現できる。

```dart
 import 'dart:math';
 class Point extends SomeParent {
  final num x;
  final num y;
  final num distanceFromOrigin;
  Point(x, y)
      : assert(x != null),
        assert(y != null),
        x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y),
        super(x, y);
  }
```
Unity Timeline簡単拡張

## ScriptのMonobiを使ってアニメーショントラックからゲームオブジェクトにない値を操作する
シャドウディスタンスなどゲームオブジェクトにない値をスクリプトを経由してアニメーションできるようにするタイムラインでは一番簡単な拡張方法。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/11a33275-5393-b465-583e-e598d50b1335.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/b2073747-cd81-b928-c979-9808f2074626.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/2d07d4bd-0ac9-b5c5-2be2-0d801f2c3ae0.png)

## コントロールトラックを使った拡張
こちらはものびにITimelineContorolを継承させて使う。
以下の３つを継承して使う
void OnControlTimeStart(){}

void OnControlTimeStop(){}

void SetTime(double time){}

double time1以外渡せないので複雑なことができない。

スタートや終わりの時にしたい処理だったりtimeを使った簡単な操作ならplayable拡張するよりこっち使ったほうが良き。


#　がちTimeline拡張　カスタムトラック
参考　URL
https://blogs.unity3d.com/jp/2018/09/05/extending-timeline-a-practical-guide/
https://docs.unity3d.com/ja/current/ScriptReference/Playables.PlayableBehaviour.html?_ga=2.160512317.1239615847.1586800196-1964762908.1584240122
https://docs.unity3d.com/ScriptReference/ExposedReference_1.html
https://docs.unity3d.com/ScriptReference/Playables.PlayableDirector.html
https://light11.hatenadiary.com/entry/2019/05/16/214328

まず知っておくべきはTimelineはPlayable APIをベースに作られている。
playableGraphを視覚的にしたい場合はplayable ビジュアライザーを使うと視覚化できる。

using UnityEngin.Playables;
using UnityEngin.Timeline;　　を使う

### 必要なもの

#### トラックの拡張　　　TrackAseetを継承する

#### クリップアセットの作成　　 TrackAssetを継承する [System.Serializable]  シリアライズが必要。保存するため

#### 構造を作成　PlayableBehaviorを継承する。

#### ミキサーでブレンド　PlayableBehaviorを継承する


## 構造を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/1c84e923-f246-046f-fd1c-1af6aee9990e.png)

##アセットの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/bd431bc4-ba87-f52a-ccfa-7f41025fe879.png)


### Playableトラックでいじるだけなら上二つで十分　同じ処理を何回も使う場合はいちいち参照を入れなければいけないので向いていない

## トラックの拡張
トラックのバインドするタイプとクリップのタイプ、カラーを指定する
クリップは複数定義することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/2c188048-b660-2da3-30e7-3a6653b86406.png)

トラックに合わせてアセットとBiheviを修正
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/07b64407-eaf1-50e3-23a6-5fc30118251e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/110cb3c9-6dfb-2ea3-ab06-da999b880229.png)


## ミキサーを作りブレンドできるようにする
ミキサーもPlayableBehabiourを継承する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/0f68e984-19ef-4659-f43f-93db4f6a038e.png)

ミキサーに合わせてアセットやロジックを変更する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/8960e761-e330-9f25-34c5-60bb3e2f230f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/b2d43e4b-f200-583a-aced-23f1865eaa80.png)

トラックにミキサーだということを定義する関数があるので付け足す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433236/ebe2f08e-bfa5-47b8-b868-14b91e4726de.png)
COVID-19チャレンジ（フェーズ3）その2

#概要

signateのCOVID-19チャレンジ（フェーズ3）やってみた。
投稿してみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f4a934ae-07eb-2b97-9167-233b1bc2ee61.png)


#サンプルコード


```

var myChart;
var ctx = document.getElementById("canvas").getContext("2d");
const yy =  [2, 0, 0, 0, 2, 0, 3, 0, 4, 4, 5, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 2, 0, 1, 14, 16, 7, 8, 10, 10, 11, 17, 25, 12, 11, 19, 25, 14, 13, 15, 18, 19, 38, 29, 60, 41, 41, 9, 70, 58, 0, 62, 72, 66, 0, 39, 11, 35, 39, 44, 94, 27, 65, 114, 80, 81, 225, 173, 0, 87, 225, 317, 122, 522, 0, 515, 252, 351, 410, 863, 475, 743, 622, 275, 455,]
//alert(yy.length);
var pre = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,3,3,4,6,7,9,11,14,17,21,26,31,37,45,53,62,73,85,99,114,131,149,169,190,213,237,263,290,318,346,375,404,433,461,489,515,539,562,582,600,615,627,635,640,641,639,634,624,612,596,578,557,534,509,482,455,426,397,368,340,311,284,257,232,208,185,164,145,127,111,96,83,71,60,];
//alert(pre.length);
var label = [];
var data = [];
var s = 0;
for(var i = 0; i < 120; i++)
{
	label.push(i);
	if (i < 85)
	{
		s += yy[i]; 
	}
	else
	{
		s += pre[i];
	}
	data.push(s);
}
var j = 0;
var out = document.getElementById('out');
for(i = 0; i < 110; i++)
{
	if (i > 95)
	{
		j++;
		out.value += j + "," + data[i] + "\n";
	}
}
myChart = new Chart(ctx, {
  type: 'line',
	data: {
    labels: label,
    datasets: [{
      label: "covid-19",
      fillColor: "rgba(151, 187, 205, 0.2)",
      strokeColor: "rgba(151, 187, 205, 1)",
      pointColor: "rgba(151, 187, 205, 1)",
      pointStrokeColor: "#fff",
      pointHighlightFill: "#fff",
      pointHighlightStroke: "rgba(151, 187, 205, 1)",
      data: data
    }]
  },
	options: {
		elements: {
			rectangle: {
				borderWidth: 2,
				borderColor: 'rgb(0, 255, 0)',
				borderSkipped: 'bottom'
			}
		},
		responsive: true,
		legend: {
			position: 'top',
		},
		title: {
			display: true,
			text: 'Chart.js Line Chart'
		}
	}
});


```

#成果物

https://embed.plnkr.co/plunk/UY702xxQnn1S2YZZ

以上。
[Blender]見えない裏側も選択する

![スクリーンショット (92).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/76a92178-5366-5974-e512-9a16e8cb02d4.png)
写真のようなループカットで切れ目を入れた箱がある
![スクリーンショット (93).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/89216cd7-f017-c91b-43be-6637f2024fe6.png)
側面から見て、写真のように変形するために、普通に選択するだけだと
![スクリーンショット (94).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/ae595b21-f641-1cf4-7c2e-da4b2541228e.png)
手前側しか選択されずにこんな形になってしまいます
![スクリーンショット_(96).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/d129b603-ce3e-c310-fb71-f9a4bb5c240a.png)
透過表示にしておけば、見えていない裏側の部分も選択してくれるようになるので
![スクリーンショット (97).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/e2cdb57f-7029-03c7-e43b-39365018205d.png)
裏側もしっかり変形させることができるようになります。
Rails6 のちょい足しな新機能を試す 127（memory cache編)

# はじめに

Rails 6 に追加された新機能を試す第127段。 今回は、`memory cache` 編です。
Rails 5.2.4.2 や、 Rails 6.0.0 では、 キャッシュとして、 memory cache を使っていて、 キャッシュから値を取り出したあとで、その値を破壊的メソッドなどで修正すると、 キャッシュの値も変わってしまうというバグ(?) がありました。

Rails 6.0.1 以降では修正されています。

Rails 6.0.2.2, Rails 6.0.1, Rails 6.0.0, Rails 5.2.4.2 で確認しました。

```shell
$ rails --version
Rails 6.0.2.2
```

今回は、 User モデルを作って cache を使って値を取り出すメソッドを作成して確認していきます。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# User モデルを作成する

User モデルを作成します。

```shell
$ bin/rails g model User name
```

# User モデルに cached_name メソッドを追加する

かなりわざとらしいですが、 `User` モデルに `cached_name` というメソッドを追加します。

`cached_name` では、 cache から name を取り出したあと、 `upcase!` で変換して、再度 cache から name を取り出します。

```ruby:app/models/user.rb
class User < ApplicationRecord
  def cached_name
    name = Rails.cache.fetch("#{cache_key_with_version}/name") do
      User.find(id).name
    end
    name.upcase!
    Rails.cache.fetch("#{cache_key_with_version}/name") do
      User.find(id).name
    end
  end
end
```

# スクリプトを作成する

User#cached_name を呼び出すスクリプトを作ります。

```ruby:scripts/user_name.rb
User.delete_all
User.create(name: 'John')
u = User.last
p u.cached_name
p u.cached_name
p u.name
```

# development 環境でキャッシュを有効にする

development 環境でキャッシュを有効にします。

```shell
$ bin/rails dev:cache
Development mode is now being cached.
```

# Rails 6.0.1 以降では

スクリプトを実行すると名前は、常に `John` のままです。

```shell
$ bin/rails runner scripts/user_name.rb
Running via Spring preloader in process 675
"John"
"John"
"John"
```

# Rails 6.0.0, Rails 5.2.4.2 では

キャッシュに保存されている値が変わってしまうため、2回目の `cached_name` の呼び出しのときに `JOHN` に変わってしまいます。

```shell
bash-5.0# bin/rails runner scripts/user_name.rb
Running via Spring preloader in process 747
"John"
"JOHN" # => キャッシュの値が変わっている
"John"
```

# 試したソース

https://github.com/suketa/rails_sandbox/tree/try127_cache_memory_store

# 参考情報

* [Fixes #36956 by dup'ing the value and entry object returned from MemoryStore.](https://github.com/rails/rails/pull/37210)
* [Don't return references from cache #24415](https://github.com/rails/rails/pull/24415)
* [Caching with Rails: An Overview](https://guides.rubyonrails.org/caching_with_rails.html)