OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでFXチャートを表示してみる バックテスト編

PythonでFXチャートを表示するのをGoogle Colabでやってみます。
https://colab.research.google.com

【Python】Backtesting.pyで株売買のバックテスト・最適化してみる
https://qiita.com/Fujinoinvestor/items/f2bdaabb766db443ddc0

アキシオリーのヒストリカルデータをダウンロードしてきます。
https://www.axiory.com/jp/how-to-install/historical-data

```
!pip install backtesting
```

もしも所持金5万円でドル円を取り引きした場合、2022年1月に114円下回ったら買い、116円上回ったら売りとしたらどうなったのか。

```
import pandas as pd
from google.colab import drive

# Googleドライブからアキシオリーの2022/01のCSVファイルを読み込む
drive.mount('/content/drive')
df = pd.read_csv(filepath_or_buffer='drive/My Drive/USDJPY_2022_01.csv', names = ['date','time','Open','High','Low','Close','volume'])
df['timestamp'] = pd.to_datetime(df['date'] +" "+ df['time'], format='%Y.%m.%d %H:%M')
df.drop({'date','time'},axis = 1,inplace = True)
df.set_index("timestamp", inplace=True)

# バックテスト実行、ストラテジー作成
from backtesting import Backtest, Strategy
from backtesting.lib import crossover

class myStrategy(Strategy):    
    def init(self): # ポジションを閉じる
            self.position.close()
        
    def next(self):
# 114円より下回ったら買い
        if crossover(114, self.data.Close):
            self.buy() 
# 116円より上回ったら売り
        elif crossover(self.data.Close, 116):
            self.sell()

# バックテストを設定
bt = Backtest( 
    df,
    myStrategy,
    cash=500, # 所持金50,000円
    commission=0.0001, # 取引手数料（為替価格に対する倍率で指定、為替価格100円でcommission=0.0001なら0.01円）
    margin=0.04, # レバレッジ25倍
    trade_on_close=True # 現在の終値で取引する
)

output = bt.run() # バックテスト実行
display(output._trades) # 取り引き結果
print(output) # バックテスト実行結果
bt.plot() # 実行結果のグラフ表示
```

![名称未設定１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124454/4d3bef41-8d86-93bb-027e-7c57ecadb601.jpeg)

![名称未設定２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124454/e3dfaa91-37e6-e782-1a00-866933c8c076.jpeg)
【Rails】チェックボックスで複数選択した値を中間テーブルに保存する

# はじめに
中間テーブルの保存でハマった人へメモを残します。

## 環境
- Ruby 2.5.9
- Rails 5.2.6

## 構成
- Furnituresテーブル { name }
- Furniture_scenes中間テーブル { furniture_id, scene_id }
- Scenesテーブル { name }

##手順
- Model（アソシエーションの設定）
- View（formの追加）
- Controller（createアクション）
- 完了

## Model（アソシエーションの設定）

```rb:model/furniture.rb
class Furniture < ApplicationRecord
    has_many :furniture_scenes
    has_many :scenes, through: :furniture_scenes
end
```

```rb:model/furniture_scene.rb
class FurnitureScene < ApplicationRecord
    belongs_to :furniture
    belongs_to :scene
end
```

```rb:model/scene.rb
class Scene < ApplicationRecord
    has_many :furniture_scenes
    has_many :furnitures, through: :furniture_scenes
end
```

`through: :furniture_scenes`で関連するモデルを使用できるようにしています。


## View（formの追加）

```erb:views/furnitures/new.html.erb
<%= form_for @furniture do |f| %>

    <%= f.label :scene_id, class: "control-label" %>
    <%= f.collection_check_boxes(:scene_ids, Scene.all, :id, :name) do |b| %>
        <label class="checkbox-inline">
        <%= b.check_box class:"form-control2" do %>
            <%= b.check_box + b.text %>
        <% end %>
            <%= b.label {b.text} %>
        </label>
    <% end %>
    <%= f.submit %>

<% end %>
```

`collection_check_boxes`の引数で指定している`Scene.all`でScenesテーブルから全ての項目を取得しています。
`collection_check_boxes`でクラスを指定できなかったので
下記の記事を参考にしました。

[【Rails】Ransackのcollection_check_boxesで、checkboxタグに任意のクラスを指定する](https://qiita.com/BRSF/items/ed299a936a544755c53e)

`:scene_ids`は後述するcontrollerで使用します。

## Controller（createアクション）

```rb:controller/furnitures_controller.rb
class FurnituresController < ApplicationController

    def create
        @furniture = Furniture.new(furniture_params)
        @furniture.save
    end

    def furniture_params
        params.require(:furniture).permit(:name, scene_ids:[])
    end
end
```

今回のポイントは、
Viewで使用した`:scene_ids` を Controllerのストロングパラメーターで`scene_ids:[]`とすることでした。
`collection_check_boxes`はどうやらXXXX_idsという配列を渡すようです。

## 完了
おつかれさまでした。
２分で分かるインナークラス　JavaGold 取得への道（内部クラス編）


徹底攻略Java SE 11 Gold問題集（黒本）を読んで最初にぶち当たる壁「内部クラス」ついて、４つの記事に分けてまとめました。
僕のようなJava初心者や、JavaGoldの資格取得に向けて、勉強をしている方にこの記事がお役に立てれば幸いです。
#はじめに
ネストしたクラスには４種類あります。
今回はその中でインナークラスについて解説していきます。

 ・インナークラス👈🏻
 [・staticインナークラス](https://qiita.com/110shun/items/ee2c3383b4817751ba7b)
 [・ローカルクラス](https://qiita.com/110shun/items/da476b32117f904ea4d4)
 [・匿名クラス](https://qiita.com/110shun/items/e912bab6c55982f50494)

#インナークラスとは？　
一言で表すと、クラスの中に定義したクラスのことをインナークラスと言います。
###使い所
　・パッケージの中でも隠蔽したい時に使います。

身近な例に例えると、たとえ血の繋がっている家族でも秘密にしたいことってありまよね。
多くの人は、秘密を自分自身の中に留めておきます笑。
イメージとしてはこのような感じなのかな〜って思います。

#どのように使うの？
###定義方法
下記のコードのようにクラスの中にクラスを定義するだけです。

```Outer.java
public class Outer{
   class Inner{
    public void sample(){
      System.out.println("インナークラスです。");
    }
  }
}
```
:::note warn
インナークラスを定義する時にstaticを修飾するとstaticインナークラスになるのでご注意してください。
:::
下記の表はインナークラスとアクセス修飾子の関係を表しています。

| public | protected | private | final| static |
|:-:|:-:|:-:|:-:|:-:|
| ○ | ○  |  ○ |  ○ | ×|

##インナークラスのインスタンスの生成方法
エンクロージングクラスをインスタンス化してから、インナークラスをインスタンス化します。
上のコード例だと、エンクロージングクラスはOuterクラスのことを指します。

```main.java
public class Main{
　public static void main(String[] args){
  Outer outer = new Outer();
  Outer.Inner inner = outer.new Inner();
  inner.sample();
 }
}
```
```
結果
インナークラスです。
```
:::note warn
インナークラスのみのインスタンス生成をすることは出来ません。
:::
#まとめ
・インナークラスとは、クラスの中に定義したクラスのこと
・インスタンスを生成するときは、エンクロージングクラスをインスタンス生成してから生成する

##参考文献
・優しくない!? Javaシリーズ
<iframe width="560" height="315" src="https://www.youtube.com/embed/C8ajfSSjhR8" title="YouTube video player" frameborder="5" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

・徹底攻略Java SE 11 Gold問題集
・【Java】インナークラス(内部クラス)って何？概要から使い方まで解説
  https://style.potepan.com/articles/30021.html
python 正規表現 忌々しい日付のゼロを取り除く


月と日のあたまにあるゼロをとって、ついでに、日付を世界標準形式のハイフンに変換します。

```python
import re

text = '2022年01月01日'

pattern = r'([12]\d{3})[\.\-年](0?)([1-9]|1[0-2])[\.\-月](0?)([1-9]|[1-2][0-9]|3[0-1])日?$'
if re.match(pattern, text):
    print(re.sub(pattern, r'\1-\3-\5', text))
else:
    print('no match')
```
```
'2022-1-1'
```
DrillDown Pt.3

Continuation from [pt.2](https://qiita.com/tayama468/items/798048576ef0da79c263)

## Implementation

### 2. components/Dialog.vue

#### Create components/Dialog.vue

```shell
touch components/Dialog.vue
```

▼

```shell
vim components/Dialog.vue
```

▼

```vuejs
// components/Dialog.vue
<template>
  <div>
    <v-dialog>
      <v-card>
        <v-card-text>
          Dialog
        </v-card-text>
      </v-card>
    </v-dialog>
  </div>
</template>
```
#### Set slot

```shell
vim components/Dialog.vue
```

▼

```vuejs
// components/Dialog.vue
<template>
  <div>
    <v-dialog>
      <v-card>
        <v-card-text>
          <slot></slot>
        </v-card-text>
      </v-card>
    </v-dialog>
  </div>
</template>
```

#### Set Promise for opne/close

```shell
vim components/Dialog.vue
```

▼

```vuejs
// components/Dialog.vue
<template>
  <div>
    <v-dialog v-model="dialog" @keydown.esc="cancel">
      <v-card>
        <v-card-text>
          <slot></slot>
          <div>
            <v-row justify="center">
              <v-btn
                color="primary"
                outlined
                rounded
                @click.native="cancel"
                >キャンセル</v-btn
              >
              <v-btn color="primary" rounded @click.native="agree">
                適用する
              </v-btn>
            </v-row>
          </div>
        </v-card-text>
      </v-card>
    </v-dialog>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        dialog: false,
        resolve: () => {},
        reject: () => {},
        open: () => {
          return new Promise((resolve, reject) => {
            this.dialog = true
            this.resolve = resolve
            this.reject = reject
          })
        }
      }
    },
    methods: {
      agree() {
        this.resolve(true)
        this.dialog = false
      },
      cancel() {
        this.resolve(false)
        this.dialog = false
      }
    }
  }
</script>
```

#### Use Dialog in DrillDownSearch.vue

```shell
vim pages/DrillDownSearch.vue
```

▼

```vuejs
// pages/DrillDownSearch.vue
<template>
  <v-app>
    <div>
      <v-btn @click="open" block>
        Components Button
      </v-btn>
      <ConfirmDialog ref="confirm">
        Dialog
      </ConfirmDialog>
    </div>
  </v-app>
</template>

<script>
  // ...
  import ConfirmDialog from '../components/Dialog.vue'
  export default {
    components: { Button, ConfirmDialog },
    data() {
      return {
        isDialogOpened: false
      }
    },
    methods: {
      async open() {
        this.isDialogOpened = true
        if (await this.$refs.confirm.open()) {
          this.isDialogOpened = false
        } else {
          this.isDialogOpened = false
        }
      }
    }
  }
</script>
```

## Next [DrillDown Pt.4](https://qiita.com/tayama468/items/7dae00e9f42e0a17d9ef)
DrillDown Pt.2

Continuation from [pt.1](https://qiita.com/tayama468/items/f10e9a50d897f12de2ea)

## Implementation

### 1. pages/DrillDownSearch.vue

#### Create pages/DrillDownSearch.vue

```shell
touch pages/DrillDownSearch.vue
```

#### Put Button for dialog

```shell
vim pages/DrillDownSearch.vue
```

▼

```
// pages/DrillDownSearch.vue
<template>
  <v-app>
    <div>
      <v-btn block>
        Components Button
      </v-btn>
    </div>
  </v-app>
</template>

<script>
  import Button from '../components/Button.vue'
  export default {
    components: { Button },
  }
</script>
```

## Next [DrillDown Pt.3](https://qiita.com/tayama468/items/6a330b4c537e36ae633a)
DrillDown Pt.1

## Overview

- pages
  - it should use dialog when use drilldown
  - it can access DrillDown data when dialog have been closed
- components
  - DrillDown
    - it have multiple slot
    - it get options and initial value from parent Class
    - it is selected in order
    - it get the next item from api each time one item is selected
  - Dialog
    - it should return Promise when open itself (pending)
    - it should resolve/reject Promise when close itself (notification)

## Implementation

### Index

1. pages/DrillDownSearch.vue
  - Create pages/DrillDownSearch.vue
  - Put button for dialog
2. components/Dialog.vue
  - Create components/Dialog.vue
  - Set slot
  - Set Promise for opne/close
  - Use Dialog in DrillDownSearch.vue
3. components/DrillDown.vue
  - Create files
    - components/DrillDown.vue
    - __mock__/api/drillDown/dummy.json
    - __mock__/api/drillDown/GET.js
    - store/drillDown.js
  - Set form data to DrillDown.vue in DrillDownSearch.vue
  - Prepare dummy data
  - Prepare get function (just return dummy data)
  - Prepare action function (just fetch dummy data)
  - Use action in DrillDown.vue mounted
  - Return options according to post data
  - Store fetch data
  - Set initial option and value
  - Watch items and Update item according to new value
4. __tests__
  - Create files
    - __tests__/pages/DrillDownSearch.spec.js
    - __tests__/components/Dialog.spec.js
    - __tests__/components/DrillDown.spec.js
  - Describe DrillDownSearch page
    - It should use dialog when use drilldown
    - It can access DrillDown data when dialog have been closed
  - Describe Dialog component
    - It should return Promise when open itself (pending)
    - It should resolve/reject Promise when close itself (notification)
  - Describe DrillDown component
    - It have multiple slot
    - It get options and initial value from parent Clas
    - It is selected in order
    - It get the next item from api each time one item is selected

## Next [DrillDown Pt.2](https://qiita.com/tayama468/items/798048576ef0da79c263)
Kolla-ansible OpenStack(All-in-One) : インスタンスから直接外部ネットワークへ通信させるための設定方法

## はじめに
この記事では、OpenStack All-in-Oneマシン上で作成したインスタンスを、Routerを介さずに直接外部ネットワークへ通信させるための設定方法について記載します。

ある程度のネットワーク知識をお持ちの場合、わざわざOpenStack内に外部接続用のRouterを立てずにインスタンスから直接外部ネットワークへ通信できないものか・・と考える方もいらっしゃるかと思います。私も同じことを考えていました。
Kolla-ansibleを使ってOpenStackを作成する際、特定パラメータを設定することで実現可能でしたので、備忘として設定方法を残しておきたいと思います。  

## 前提
前提として、ここで作成したAll-in-Oneマシンは検証などのテスト用途で作成したものであります。本番環境での利用を想定していないので、あくまで参考手順として利用下さい.


  
簡単ですが、作成環境は以下の通りです。
・サーバー(VM) : 12vCPU / 16GB Mem / 900GB HDD / 2vNIC (VMware ESXi6台上で作成)
・OS : ubuntu 20.4.3 LTS
・kolla-ansible : 13.1.0
・OpenStack Release : xena 


## 手順  
Kolla-ansibleでOpenStackのAll-in-Oneマシンを作成する際に設定が必要となるパラメータだけピックアップして記載します。
基本的な作成方法は、[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/) を参考として下さい。

### 1. globals.ymlへのパラメータセット
Kolla-ansibleでOpenStackを作成する前に、globals.ymlへ下記パラメータをセットしておきます。

```
enable_neutron_provider_networks: "yes"
```

### (任意) ml2_conf.iniへのパラメータセット

vlanを使ってインスタンスが接続するネットワークセグメントを細かく指定したい場合 (=つまりOpenStackマシンのNICをtrunkポート化したい場合) Kolla-ansibleでのdeploy完了後にml2_conf.ini内へ必要パラメータをセットします。
冒頭の基本的な作成方法に従えば、対象ファイルは「/etc/kolla/neutron-server/ml2_conf.ini」に存在するはずです。
なお、OpenStackマシンのNICが接続されているスイッチのポートが「access」ポート設定となっている場合、この手順は不要です。

```
[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan,vlan

[ml2_type_vlan]
network_vlan_ranges = physnet1:[許可したいvlan番号の始まり]:[許可したいvlan番号の終わり]
※許可するVLAN番号の始まりと終わりについては、スイッチ側設定と完全一致 or スイッチ側設定に包含されるよう設定ください。
```

### 2.OpenStack上でネットワークを作成

OpenStack上でAdmin権限を持つユーザーにてネットワークを作成します。
※ここではGUIでの設定方法を記載します。

OpenStackへGUIでログイン後、左メニューの Admin -> Network -> Networks と辿り、「+Create Network」から新規ネットワークを作成します。設定内容は下図サンプルを参照ください。下図ではOpenStackマシンのNICがTrunkポートとなっていることが前提となりますが、Provider Network TypeとしてVLAN、Physical Networkとして物理NIC名(physnet1)、Segmentation IDとしてVLAN番号を指定しています。
OpenStackマシンのNICがAccessポートとなっている場合、Provider Network TypeとしてFLAT、Physical Networkとして物理NIC名(physnet1)が指定されていればよいはずです。
なお、External Networkのチェックボックスには必ずチェックを入れましょう。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817499/686abc40-f470-26bb-cb4f-01375cf9814c.jpeg)


### 最後に

公式の手順などを見ても、インスタンスを外部接続させるにはOpenStack内にRouterを作成するのがセオリーのようですが、インスタンスのネットワークパフォーマンスを高めたい場合は、今回のような方法を取るのがよいようです。ある程度ネットワークを知っている方の場合は、今回の設定の方がしっくりくるのではないかと思います。
この記事が、同じ悩みを持つ方の問題解消に役立てれば幸いです。
【Kaggle解法まとめ】～House Pricing～ ＃欠損値の扱い

## 記事の概要
[前回の記事](https://qiita.com/matsuda-blog/items/c10697f87f89f31b43d6)に続いて、今回は欠損値の扱いについてまとめてみた。


## 欠損値の扱い
欠損値をどう処理するかは、主に次のようなものが挙げられる。

- そのまま放置
- 列ごと削除
- 欠損に意味があるならカテゴリ化
- 代表値で埋める
- 他の特徴量の情報から埋める
- 欠損か否かを表す特徴量を作る

それぞれもう少し具体的に説明していく。

### そのまま放置

XGBoostやLightGBMなど欠損値のままでも動くフレームワークであれば、欠損値を補完する必要がない。欠損していること自体に情報が含まれている、と考えると、欠損値を削除したり無理に補完するよりもそのまま取り扱った方が精度が良くなる可能性がある。

欠損値のままでは動かないモデルの場合は、0や-9999など通常はとりえない値を欠損値に代入することで欠損値のまま取り扱うのに近いやり方をすることができる。

### 列ごと削除

大部分が欠損している場合は、その特徴量ごと削除することを検討する。
ただし、以下で紹介する補完方法が使える場合はそちらを優先したほうが良いかも。

### 欠損に意味があるならカテゴリ化

欠損していること自体に意味が含まれている場合、欠損を一つのカテゴリにする。

例えば、PoolQcを見てみると大部分が欠損しているが、これを「プールがない」と解釈すれば実感に一致する。プールは普通の家にはないはずで、あるのはお金持ちの家くらい。したがって、欠損値を「None」や「NoPool」などに置き換える。（なお今回のコンペの場合、dataset内のdata_descriptionにその旨が記載されていた）

ちなみに、欠損数に着目するとこの種のパターンは見つけやすくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900599/cefd7de7-cf63-cb75-5584-a02c16c31434.png)
例えば上のGarage関連の特徴量はそろって159個欠損している。さすがにこれが偶然とは考えづらいので、何かしらの関連があるとみるのが自然。

### 代表値で埋める

**数値変数**の場合は、平均値や中央値で欠損を埋めるのがメジャーな方法。ただし平均値は分布がゆがんでいると適切な代表値として機能しないので、中央値をつかうか、log変換して平均をとる。

平均値や中央値を取る範囲にもいろいろある。全体の平均・中央値で埋めるのが一番手っ取り早いが、他のカテゴリ変数でgroupbyして各groupごとの平均・中央値で埋める方法もある。

例えば、カテゴリ変数"Neighborhood"でgroupbyして、もし"Veenker"の行で欠損しているなら"Veenker"の中央値で埋める、といった具合。

**カテゴリ変数**の場合は、最頻値で埋める。

例えば"MSZooning"では全体の約8割が「RL(Residential Low Density)」なので、欠損値は「RL」で埋める。

ただし、欠損が多いときに最頻値で埋めるとあまりよろしくない場合がある。
下は「FireplaceQu」の欠損を最頻値で埋める前後の様子であるが、埋める前後で「Gd」がデータ全体に占める割合が約半分から約4分の3になってしまい、分布が大きく変わっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900599/c9035700-7cd5-c631-cbe7-79f4c50e0cc6.png)


### 他の特徴量の情報から予測する

欠損している変数が他の変数と関連性がある場合は、他の変数を特徴量、欠損している変数を目的変数とみなして、欠損値をモデルの予測値で埋めるという方法も有効かも。

### 欠損か否かを表す特徴量を作る

新たな特徴量として「欠損しているか否か」を表す二値変数をつくると良い特徴量として機能する場合もある。

一つは、欠損している列は予測に使わないでおいて、欠損しているか否かを表す特徴量だけを予測に用いる方法。もう一つは、欠損値は埋めておくけれども、欠損していたという情報を損なわないために二値変数も予測に用いるというやり方。

## 参考
https://www.kaggle.com/dansbecker/handling-missing-values
https://www.kaggle.com/serigne/stacked-regressions-top-4-on-leaderboard
https://www.kaggle.com/erikbruin/house-prices-lasso-xgboost-and-a-detailed-eda
https://www.kaggle.com/c/house-prices-advanced-regression-techniques/discussion/35968
【つくりながら学ぶ! PyTorchによる発展ディープラーニング】をUbuntu20.04(WSL2)で学ぶ

## 概要 

Kindleで読みながら勉強したかったので、WSL2上で勉強・動作確認しました
原著が**Ubuntu 16.04 &CUDA11.0未満**を想定していたものであるため、
**Ubuntu20.04 & Ampere (RTX30~) Series**対応版を作成しました。

特にNLPの章で結構ソフトを変えてます

ソフトは[こちら](https://github.com/KyanainsGate/pytorch_advanced)

## 環境
GPU: Geforce RTX3090
OS: Ubuntu 20.04 @ WSL2 (Windows 11)
CUDA: 11.1 (ただし CUDA on Windows Subsystem for Linux (WSL) )
Python: 3.9.7

## VcXsrvのセットアップ
環境によってうまくいく個体差がありそうですので、以下私の構成でうまくいった設定の共有です

- Xlaunch起動時に、`Disable access control`を**チェック**
- 以下を`.bashrc`内に記述

```
# Set on ~/.bashrc
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):
``` 

## 参考

WSL2 & CUDA導入：[待ってました CUDA on WSL 2](https://qiita.com/ksasaki/items/ee864abd74f95fea1efa)
小川先生の記事：[PyTorchでBERTなど各種DLモデルを作りながら学ぶ書籍を執筆しました](https://qiita.com/sugulu_Ogawa_ISID/items/07253d12b1fc72e16aba)
JavaScript Math「floor」「random」

数値（Number型）を変数として定義した後、
そのNumber型変数に「Math」を使うと、その数字をアレンジできます

_コード_

```
let x=1.56;
x=Math.floor(x);
console.log(x);
```
出力

```
1
```
このように「Math」の後に「floor」を入れて()内に数字変数を入れると
小数点以下切り捨てをしてくれるので出力は「1」がでます

_コード_

```
let y=1.56;
y=Math.random(y);
console.log(y);
```
次に「Math」の後に「random」を入れて()内に数字変数を入れると
小数点以下の数字が毎回の表示でランダムに出力してくれます

この２つの組み込み関数である「Mathオブジェクト」を使用して、
０〜９の値をランダムに表示させてみます。
「Math」の後の「floor」「random」を使用して０〜９の値をランダムに出力したい時は

_コード_

```
let z=1.56;
z=Math.floor(Math.random(z)*10);
console.log(z);
```
このように「random」した変数「z」を×１０して
それを「floor」に入れて小数点以下を消してあげると
「1」の位をランダムに出力できるようになりました
Google Apps Script(GAS) の new Date() で日本時間を取得する方法

GAS はデフォルトだとニューヨーク時間になっているので、東京時間に変更しておく。

プロジェクト設定から「appsscript.json」マニフェスト ファイルをエディタで表示する」にチェックを入れる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/77783721-5490-4757-9346-4df467084814.jpeg" width=500>

timeZoneを変更する。

```:appsscript.json
America/New_York
↓
Asia/Tokyo
```

![b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/2699fd40-4d03-587c-0cc5-28058e3d134a.jpeg)
Linux端末でgorin.jpのライブ動画を再生したい

## Linux端末でgorin.jpのライブ動画だけ再生できない
地上波で放送しているオリンピックをTVで、gorin.jpのLive動画をモバイルモニターで同時視聴しようとしました。
最初にモバイルモニターにGoogle Chromecastを付けてandroid端末の画面をミラーリングして観ていましたが、解像度がそこまで良くないので普通にPC(Linux端末)に接続することを考えます。
しかし、Androidで再生できるgorin.jpのライブ映像がLinux端末では再生できませんでした。。

## 環境
OS：ArchLinux (2022/02時点の最新)
デスクトップ環境：xfce4
ブラウザ：Goole Chrome / Mozilla Firefox

## 原因調査
事象としては、gorin.jpのLive動画以外は再生できます。
再生ボタンを押しても反応がない状態です。
ChromeとFirefoxのどちらでも同じでした。-> LinuxOSということが原因か。
ホームページの[よくある質問](https://www.gorin.jp/info/faq/)を確認すると推奨環境はWindows/Mac/iOS/Androidです。
不思議ではありませんがLinuxは当然対象外ですね。。

ConsoleとかNetworkタブでなにか分かるかもしれないので開発者ツールを開きます(F12)。
Consoleでエラーが出ていて、Chromeでは「Uncaught TypeError: Cannot read properties of null (reading 'split')」、Firefoxでは「Uncaught TypeError: platform.os.version is null」が確認できました。
Firefoxのメッセージを見るとやはりLinuxOSであることがダメっぽいです。(Platform.js?)

## 解決方法
ブラウザ上でOSの情報が取得できないのであれば、別のOS上で動いているように見せると大丈夫なのではないかと考えました。

開発者ツールのToggle device toolbar(Ctrl + Shift + M)を開きます。
Responsiveや他のデバイスが選択できるのでLive動画が再生できそうなものを適当に選びます。(ここではiPad Air)
![device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265526/9ceee86d-f4ab-b5e1-19df-63e75e022e77.png)
ここで__ページを再読込(リロード)__してライブ動画を再生してみるとうまくいきました。(Chrome)
※Firefoxでは再生ボタンを押すことができましたが、広告が流れた後で動画再生できませんでした。調べるとFlashPlayerとか自動再生の設定を変更する必要があるかもしれません。

## 全画面表示
以下の手順でモニターで動画を全画面表示することができました。
・動画プレイヤーを全画面表示
・ブラウザの表示を最大化(F11)
・開発者ツールを閉じる(F12)

## 補足
ArchLinuxだからOS情報が取得できないだけで、Ubuntuとかメジャーなものだと大丈夫なのでしょうか。
同じく民放テレビ局による無料の動画配信サービスのTVerのライブ動画でも同じことが起きる可能性があります。
pushでnon-fast-forwardのエラーが出たら強制的にプッシュ

### docker-compose.ymlの:delegatedとは

[https://qiita.com/ysKey2/items/346c429ac8dfa0aed892](https://qiita.com/ysKey2/items/346c429ac8dfa0aed892)

### mysqlのテーブルを見る

[https://qiita.com/crispypanda/items/0c81fe9130305501b152](https://qiita.com/crispypanda/items/0c81fe9130305501b152)

sequel aceを用いて接続した。ポートは13306

### mysqlへの接続

まずdockerのコンテナの中に入る

```bash
$ docker exec -it コンテナ名 bash
```


```bash
$ mysql -u データベース名 -p
Enter password:
```

[https://akizora.tech/docker-mysql-container-access-2704](https://akizora.tech/docker-mysql-container-access-2704)

docker ps でコンテナIDを確認して

```bash
$ docker exec -it <コンテナID> bash
```

で入ることもできる

### db:migrateをする

```bash
$ docker-compose run <サービス名> bundle exec rake db:migrate
```

```bash
$ docker-compose run web rake db:create

$ docker-compose run web bin/rails g scaffold User name:string

$ docker-compose run web bundle exec rails db:migrate
```

### buildしてからのup

release_buttonというorigin/release_buttonからpullしてきたブランチが、docker-compose upした時に何かしらエラーが起きた


試しにbuildしてからupしてみると無事接続できた

```bash
$ docker-compose build --force-rm app
$ docker-compose up
```

### pushでnon-fast-forwardのエラーが出たら強制的にプッシュ

```bash
$ git push origin release_button -f
```

### すでに消されたリモートリポジトリのブランチを、ローカルリポジトリでも根絶やしにしたい

[https://www.r-staffing.co.jp/engineer/entry/20201023_1](https://www.r-staffing.co.jp/engineer/entry/20201023_1)

```ruby
$ git remote prune origin
```

### gitでブランチを作成すると「fatal: Failed to lock ref for update: Not a directory」エラー

[https://anton0825.hatenablog.com/entry/20140610/1410154651](https://anton0825.hatenablog.com/entry/20140610/1410154651)
Google、Facebook、Microsoftアカウント連携のボタンのルール

## ガイドライン

- [Microsoft](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-add-branding-in-azure-ad-apps)
- [Facebook](https://developers.facebook.com/docs/facebook-login/userexperience?locale=ja_JP)
- [Google](https://developers.google.com/identity/branding-guidelines?hl=ja)


検索すれば出てくるのですが、備忘録的に残しておこうかと。
bashスクリプトでlnコマンド出来ない？え？なんで！？あっれ〜知らなかったの〜ウケる〜

# なにそれ〜ウケる〜
## これが動かないパターン
エラーメッセージ
```bash:適当なシェルスクリプト.sh
#!/bin/bash
# 直書きなら動く
#ln -s ~/.emacs.d/inits-stok/autoinsert.el ~/.emacs.d/inits/001-autoinsert.el
S='ln -s ~/.emacs.d/inits-stok/autoinsert.el ~/.emacs.d/inits/001-autoinsert.el'
# 実行
# bash script ln: failed to create symbolic link no such file or directory
${S}
```
```bash
$ ./適当なシェルスクリプト.sh
ln: ~/.emacs.d/inits/001-autoinsert.el: No such file or directory
```
## これが動くパターン
```bash:適当なシェルスクリプトaaa.sh
#!/bin/bash
S='ln -s ~/.emacs.d/inits-stok/autoinsert.el ~/.emacs.d/inits/001-autoinsert.el'
eval ${S}
```

## たぶんだけど

rbashってあるじゃん。あれってbashの名前が違うだけのエイリアスなんだよね。
セキュリティ的観点から動作を制限してるってヤツ。
んでもって、オペレーションミスなんかで大量にゴミを生み出すような、手のつけられない状況になるようなシェルスクリプトの使い方は抑制されてんじゃねーのかなって、思うのよ。

制限下のbash、restrictedモードのbashって事でrbashをシェルに使っている場合は、evalコマンドとか刺さりそうなコマンドは動かないような気がするのね。
なので、シェルの方も変数展開してのコマンド実行なども、刺さる人には刺さる属性持ってるので制限されちゃってるんじゃないかと。
bashを使う限りじゃ、eval($ほげー)を使えばいいじゃんって話だしね。

## ちなみに

あっれ？動かないじゃん。
あっぁっぁ、そう言えば、昔も同じことで悩んだんだった・・・ orz={( ´,_ゝ｀)ﾌﾟｯ}
じぶんへのいましめのため　Qiita　に書いてます。

ちなみに、今、作ってたスクリプトはこれ

```bash:~/.emacs.d/_inits-stok_2_makelink.sh
#!/bin/bash

# ファイル名を配列に取り込む
# コメント記号の後は必ず空白が必要
TGTFNS=$(cat << 'FNEOS'
    autoinsert
    face-font
    all-the-icon
    calendar
    scratch
    swiper
    dired
    tabbar
    tree_speed_ber
    ido
    find-grep
    company
    ctags
    ediff
    electrict-mode
    org-mode
    howm
    markdown
    flycheck
    perl
    moccur
    oddmuse
    vim
    allwantfont
    plantuml
FNEOS
)
echo $TGTFNS

# 配列要素の数だけループ処理を行う
countLineSkiper=0
countIndex=0
for x in $TGTFNS
do
  # echo "a:[$x]"

  # 次行スキップ処理
  if (($countLineSkiper > 0)) ; then
    let --countLineSkiper
    # echo "skipper ${countLineSkiper}:[${x}]"
    continue
  fi

  # 入力要素の検査：コメント行は以降の処理をスキップする
  if [[ "${x}" =~ ^#.* ]]; then
    # echo "対象はコメント行です。スキップします"
    let ++countLineSkiper
    continue
  fi

  let ++countIndex
  S=$(printf "ln -s ~/.emacs.d/inits-stok/${x}.el ~/.emacs.d/inits/%03d-${x}.el" "${countIndex}")
  #echo "![${S}]"
  echo "${S}"
  ${S}
  #eval ${S}
done

echo "aaa"

## EOF _makelink

```

Emacs　の inits ディレクトリでファイル名のプレフィックスに数桁数値が並んでいると目が滑って辛い。
よーし、リハビリを兼ねて久しぶりにシェルスクリプト書いちゃうぞ〜！
そういう現実逃避で作ってる途中です。
ほぼほぼ出来てるので、完成まで持ってかないでこのままぶん投げちゃうかもしれないです。
Git管理からあらかじめ除外しておく方法

### Git管理から除外する

```bash
git update-index --assume-unchanged .gitignore Gemfile Gemfile.lock bin/start.sh config/boot.rb db/schema.rb docker-compose.yml
```

確認する方法

```bash
git ls-files -v | grep ^h
```

除外したファイルを元に戻す方法

```ruby
$ git update-index --no-assume-unchanged Gemfile Gemfile.lock
```

### commitしたファイル一覧を確認する

```bash
$ git log -1 --name-only
```

### 過去のコミットから特定のファイルを除外する

コミットする必要のないファイルを誤ってコミットしてしまったときに、ファイルを削除することなく除外する

rebaseを用いる

[https://yami-beta.hateblo.jp/entry/2016/08/16/000247](https://yami-beta.hateblo.jp/entry/2016/08/16/000247)

```bash
$ git rm --cached [ファイル名]
```

どのファイルがコミットされたかを確認する

```bash
$ git log --graph --pretty="%h %s" --stat
```

rebaseする

```bash
$ git rebase -i 8f832af
```

コミットを修正する

```bash
$ git add .
$ git commit --amend
```

コミット内容を後から追加

```bash
$ git commit --amend --no-edit
```

コミットのメッセージを後から修正

```bash
$ git commit --amend -m "修正されたコミット"
```

### コミット、ステージング、ワークツリー

git diff では、indexとworking treeの差を出している
git diff --cached では、commitとindexの差を出している

### git reset, git reset —hard, git reset —softの違い

[https://qiita.com/forest1/items/3cd291b14b4bd8340dfe](https://qiita.com/forest1/items/3cd291b14b4bd8340dfe)

untracked fileとは、前回のcommitの時点では存在しなかった新たに作成したfileであり、かつgit addしてステージさせていないfileのこと

### コミットとインデックスを移動させたい

```bash
$ git reset --mixed HEAD^
```

### ファイルを一つずつaddして、addしたくないファイルはcheckoutする

```bash
$ git add ファイル名
$ git commit -m "メッセージ"
$ git checkout ファイル名
```

### update-indexをしてからの方が楽

```bash
$ git reset --mixed HEAD^
$ git update-index --assume-unchanged .gitignore Gemfile Gemfile.lock bin/start.sh config/boot.rb db/schema.rb docker-compose.yml
$ git add .
$ git commit -m "confirm pages with style"
$ git status
On branch pages_styles_list
nothing to commit, working tree clean
```
WSL2でSSH出来なくなった時の備忘録


久しぶりにwsl2環境で作業しようとしたところ、SSHなどあらゆるサービスが使えなくなっていた。原因はPID1で起動すべきsystemdがinitに代わっていたためだった。以下環境におけるssh接続までの手順を記載する。

### 環境情報
* wsl2
* Ubuntu18.04
* （後日Ubuntu20.04のwsl2環境で同様の手順を行い確認済）

### wsl2でsystemdを使えるようにする過去記事の情報が古かった

[こちらの記事](https://qiita.com/I_Tatsuya/items/9f85cdb9adc3adcf1abd)などでgenieというのがsystemdの起動に必要と分かった。しかし、記載されている情報が古かったせいか手順通り行ってもうまくいかなかった。

### wsl2でsystemdを使用する手順 （2022.2）

ほぼ文末記載の参考サイトを参考に設定してsshd起動までを確認した。以下はその際の手順メモ。

```
$ sudo apt install apt-transport-https
```

```
$ sudo wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
```

```
sudo nano /etc/apt/sources.list.d/wsl-transdebian.list
```

下記をwsl-transdebian.listに追記して保存する

```
deb https://arkane-systems.github.io/wsl-transdebian/apt/ focal main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ focal main
```

genieをインストール

```
$ sudo apt update ; sudo apt upgrade
$ sudo apt install systemd-genie
```

genieを起動するとタイムアウトした。

```
$ genie -s
Waiting for systemd....!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Timed out waiting for systemd to enter running state.
This may indicate a systemd configuration error.
Attempting to continue.
Failed units will now be displayed (systemctl list-units --failed):
  UNIT                         LOAD   ACTIVE SUB    DESCRIPTION
● ptp4l.service                loaded failed failed Precision Time Protocol (PTP) service
● systemd-modules-load.service loaded failed failed Load Kernel Modules
● systemd-remount-fs.service   loaded failed failed Remount Root and Kernel File Systems

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
```

私の環境の場合、ptp4lがタイムアウトしていたのでサービスを無効化した。

```
$ sudo systemctl stop ptp4l ; sudo systemctl disable ptp4l
```

再度genieを起動してみたところすでに起動（ボトル？）していた。

```
$ genie -s
genie: already inside the bottle; cannot start shell!
```

wsl2を再起動。

```
PS> wsl2.exe shutdown
```

systemdがPID1で実行されていることを確認。

```
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 225252  8592 ?        Ss   11:05   0:01 systemd
```

wsl2でsshdのサービスがアクティブになっていることを確認でき、ホストからのSSH接続を確認出来た。ここではすでにWindowsホストからのSSH接続設定済だったのでSSH周りの設定は割愛する。

### 参考
【Rails6】Webpacker::Manifest::MissingEntryErrorを解決する

## Webpacker::Manifest::MissingEntryErrorが発生


Articleモデルのindexビューを作成して、表示させようとしたら``Webpacker::Manifest::MissingEntryError``が生じました。



```:エラー
Webpacker::Manifest::MissingEntryError in Atricles#index

Showing /Users/app/views/layouts/application.html.erb where line #9 raised:
Webpacker can't find application.js in /Users/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}
```

webpakerをインストールして、compileすれば良いみたいなので、下記を実行してエラー等生じなければ、問題解決です。

```:ターミナル
rails webpacker:install
rails webpacker:compile
```

ただ私はこれらを実行した時に、諸々別のエラーが発生したので、それを以下に記載します。

## Webpackerのインストール

まずはwebpakerをインストールします。

```:ターミナル
rails webpacker:install
```

すると、下記の通りwebpackのcommandなんてないよと言われました。

```:ターミナル
error Command "webpack" not found.
```

gemのwebpackerのバージョンを上げてみます。
Gemfileに変更を加えて、``bundle install``

```:Gemfile
gem 'webpacker', '~> 4.0' # 変更前
gem 'webpacker', '~> 5.0' # 変更後
```

```:ターミナル
bundle install
```

もう一度インストールしたら、今度は成功しました。

```:ターミナル
rails webpacker:install
```

## Webpackerのコンパイル

続いてコンパイルを実行します。

```:ターミナル
rails webpacker:compile
```

すると、下記エラーが生じました。
自分のPCにインストールしたNode.jsのバージョン(v17.4.0)では対応していないみたいなので、バージョンを下げる必要があるようです。

```:ターミナル
Error: error:0308010C:digital envelope routines::unsupported

〜省略〜

Node.js v17.4.0

Completed 500 Internal Server Error in 1994ms (ActiveRecord: 0.2ms | Allocations: 9891)
```

そもそもNode.jsのバージョン管理ツールを入れていなかったので、このタイミングで入れておきます。
バージョン管理ツールは色々あるみたいですが、今回は``n``を選択。
npmで``n``をインストールして、任意のバージョンのNode.jsをインストールします。

```:ターミナル
npm install -g n

n 15.0.0 #インストール

node -v #バージョン確認
> node/15.0.0
```

Node.jsのバージョンを下げたので、もう一度コンパイルを実行。

```:ターミナル
rails webpacker:compile
```

すると、コンパイルに成功しました。
Webpacker::Manifest::MissingEntryErrorは消え、ビューが上手く表示されました。

## おまけ：　エラー文に書かれているjavascript_pack_tagの箇所を削除すると・・・

エラー文を読むと、application.html.erbの9行目でエラーが生じていることが分かるので、9行目を削除することでもエラーは生じなくなります。

ただこれをやってしまうと、後々開発に影響が出てくる可能性があります。

例えば、私の場合だと、Action Text(Rails6から追加されたリッチテキスト機能)を使おうとした際に、エディタがうまく表示されなくなるといった問題が生じました。なので、安易に削除するのは良くなさそうです。

```:app/views/layouts/application.html.erb
1: <!DOCTYPE html>
2: <html>
3:   <head>
4:    <title>StudyBlogApp</title>
5:    <%= csrf_meta_tags %>
6:    <%= csp_meta_tag %>
7:
8:    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
9:    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
10:  </head>
11:
12:  <body>
13:    <%= yield %>
14:  </body>
</html>
```

## 参考

[【Rails6】エラーの中身と対処法 Webpacker::Manifest::MissingEntryError in](https://qiita.com/shizen-shin/items/38fd774ffc87bc8838c9)

[nodeのバージョンをnで管理する](https://qiita.com/bigplants/items/2d75bf552e0da4a7e822)
outsystemsUI開発の基本

Outsystems画面とは、リッチなインターフェイスを形成する各種要素からなる、インターフェイスの構成要素のひとつです。


Outsystems画面テンプレート
画面は空のキャンバスから始めることも、テンプレートをベースにすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/ee94a999-48ea-7a5e-0174-0c046be17f5f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/ed3c15d4-2809-0299-d015-a7b5e2b61625.png)

画面のウィジェット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/4d4bfa22-28a2-4760-9959-5792398484f2.png)
画面の入力と変数

エンドユーザーに表示する内容は、データによって異なる場合がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/93f0df25-aa0d-385b-83b2-5ec233aa9470.png)
一部のデータは画面に渡すことができる
例えば入力パラメータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/a673c7c6-d3fd-0c30-d148-c5749fe3f26e.png)

画面にはローカル変数を含めることもできる
ローカル変数は画面のスコープ内で初期化される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/8d52affa-a23b-00aa-78ea-f267ebb09372.png)

クライアント側のロジック

画面アクションは、画面のスコープ内でクライアント側のロジックを実行する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/0cc346b4-7907-e20e-8eeb-54ff4b817dee.png)

LinkとButton
両方のウィジェットにOn Clickの移動先がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/e539f3ad-d85f-0a03-4df7-4f90aa7a49e5.png)
【Goのhttptestでtestを書くにあたって学んだこと】

## 大まかなテストの流れ

 * 擬似リクエストを作る
 * レスポンスを受け取るRecorderを作る
 * アサーションで結果を比較する。

以下記事よりstatusCodeとhttptestの値を確認した。

```jsx
例）http.StatusCreated === 201
```

[net/httpとfasthttpの対応表 - Qiita](https://qiita.com/satto_sann/items/576fb45981d17ae56f9f)

## 疑似リクエスト作成方法

```go
httptest.NewRequest(
 	http.MethodPost, // 形式
 	"/user",  // エンドポイント
 	bytes.NewBuffer([]byte(body)) // 引数に必要ならいれる、不要ならnil（body）
)
// 第3引数はio.Reader型である。
func NewRequest(method, url string, body io.Reader) (*Request, error) {
 	return NewRequestWithContext(context.Background(), method, url, body)
}
```

## io.Reader型とは？

バイト列を読み出すためのインターフェース

```go
// 具体的なio.Reader interface
// たったこれだけ。
type Reader interface {
    Read(p []byte) (n int, err error)
}

// bytes.Buffer型はio.Reader型とio.Writer型を満たす
// Buffer構造体はReadメソッド、Writeメソッドを持っている。
	// WriteメソッドはBuffer自らのbyteに書き込むためのメソッド
	// ReadメソッドはBuffer自らのbyteを読み取るためのメソッド
func Buffer struct {
		byte []
}
func (r *Buffer) Write(x) {
		r.byte = x
}
func (r *Buffer) Read(x)(Buffer){
		return r.byte
}
```

## jsonへのEncodeをstream処理で行う

```go
e := json.NewEncoder(w) // w = io.Writer
data := map[string]interface{}{
		"name": "example",
		"email":  "example@gmail.com",
	}
e.Encode(data)
```

## encodeしたデータで新しいリクエストを作成する
```go
// NewRequestに渡すio.Reader型を持った変数を定義する
// bytes.Bufferやbufio.Readerなどがあるので適当に作って渡せばいい
var buf bufio.Reader 
req := httptest.NewRequest(http.~, "エンドポイント", &buf)
```
Python 文字列の中に変数値を入れる

### 文字列の中に変数値を入れる

フォルダやファイル作成時に今日の日付を入れたり時にformatを使い実施


```python
import datetime as dt
import os

today = dt.date.today().strftime('%Y%M%d')
today
```

    '20220012'

これでフォルダ名などの文字列に追加したい日付文字列が作成できたので、フォーマットを使って文字列と結合します。
コーテーションの前に`f`をつけて作成します。(Python3.6以降)
もちろん`+`で結合することも可能ですが、フォーマットを使ったほうがコードが見やすいと思います。


```python
print(f'newfolder_{today}make')
print('newfolder_' + today + 'make')
```

    newfolder_20220012make
    newfolder_20220012make
    

これを使えばフォルダ名に作成日を追加することが可能


```python
os.makedirs(f'newfolder_{today}make')
```
UbuntuARMの環境をQEMUでx86 Ubuntu上に用意する。

#初めに
久々のQiita。3本目を書いていこうと思います。皆様いかがお過ごしでしょうか。
さて、今回のは無性にUbuntuARMを使いたくなったからインストールしてみた、ということで書いていこうと思います。
今回はこの記事の~~パク~~リスペクトです。こちらで見た内容を自分の中ですっきりさせるためにまとめてみました。
この記事を読むときには、参考サイト様の方も見ていってください。:D

参考サイト様

https://zenn.dev/tlls/articles/553b022a4ae4d63efc65

この記事の内容は以下のGithubリポジトリにまとめてあります。
記事の最後に使用手順をざっくりまとめますので、一度記事に目を通してからご利用ください。

https://github.com/chibibaku/UbuntuARM_QEMU

#UbuntuARMとは
名前の通りですが、UbuntuのARM版です。今回は18.04.5-aarch64でした。
なお20.04は未検証です。試した方がいらっしゃいましたらコメント欄に書き残していただけると幸いです。
#筆者の環境
```
・Ubuntu20.04-x86_64
・Core2Quad Q9550
・Mem8G
```
検証用マシンなのでcore2世代の子ですが頑張ってくれてます。
OSはUbuntu 20.04 or 18.04推奨です。
#やっと構築に入ろうと思います。
最初に、作業ディレクトリを用意し、入っておきます。
不要になったらディレクトリごと削除すればOKです。

```shell
$ cd
$ mkdir UbuntuARM
$ cd UbuntuARM
```

必要なパッケージのインストールです。

```shell
$ sudo apt install qemu-system-arm
$ sudo apt install cloud-image-utils
```

次に、UbuntuARM(cloud image版)本体のイメージとEFIをwgetでダウンロードします。
UbuntuARM本体は名前が長いのでダウンロードと同時にRenameします。

```shell
$ wget -O ubuntuARM.img http://ubuntutym2.u-toyama.ac.jp/cloud-images/releases/18.04/release/ubuntu-18.04-server-cloudimg-arm64.img
$ wget https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd
```

EFIをイメージ化します。

```shell
$ dd if=/dev/zero of=flash0.img bs=1M count=64
$ dd if=QEMU_EFI.fd of=flash0.img conv=notrunc
$ dd if=/dev/zero of=flash1.img bs=1M count=64
```

GUIの無いサーバー版の為cloudinitが使用可能です。user,password等を設定しましょう。
初回起動時に読み込んで自動的に設定してくれます。
(この二行を書くのに暫く以下のサイトとにらめっこしてました)

https://mekou.com/linux-magazine/ubuntu%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B/

```shell
$ cat >cloud.txt <<EOF
> #cloud-config
> user: [ユーザー名]
> password: [パスワード]
> chpasswd: { expire: False }
> ssh_pwauth: True
> EOF
```

```shell
$ cloud-localds --disk-format qcow2 cloud.img cloud.txt
```

さあ、これで準備が整いました。
参考サイト様ではここでimagefileをバックアップしていました。(任意)

```shell
$ cp Ubuntu_Image.img Ubuntu_Image.old
```

#起動する
早速起動と行きましょう。
以下のシェルスクリプトをstart.shとして保存してください。
メモリは任意で変更してください。

```shell:start.sh
$ qemu-system-aarch64 -m 4096 -smp 4 -cpu cortex-a57 -M virt -nographic \
  -pflash flash0.img \
  -pflash flash1.img \
  -drive if=none,file=ubuntuARM.img,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  -drive if=none,file=cloud.img,id=clouds \
  -device virtio-blk-device,drive=cloud
```

```shell
$ chmod +x ./start.sh
$ ./start.sh
```
ターミナル内でCUIでVMが起動します。まれにユーザーネーム入力画面が出た状態で起動プロセスの出力が覆いかぶさってきて画面がごちゃごちゃになることがあります。その時は一度何も入力せずenterを押すと再度ログインのプロンプトが出てきます。

:::note warn
警告: 初回起動は時間がかかることがあります。
:::

本家の記事にはsshに関することが書かれていますが、今回は不要~~(と書いて面倒と読む)~~なので省略します。
いかがでしょうか。QemuでUbuntuARMが動いています。
ちなみに、筆者の環境では初回起動直後の状態で370MB程度のディスク使用量、アプデ後に1.6GB程度でした。
#Github版について
ここまでの内容を一つのシェルスクリプトにまとめ、手順を簡略化したものを以下のgithubリポジトリにまとめてあります。

https://github.com/chibibaku/UbuntuARM_QEMU

ZIPとしてダウンロードするか、git clone後に以下の手順で導入してください。
細心の注意を払って書いていますが、万が一何かあったときの責任はとれませんので、自己責任で使ってみてください。
mkvm.shを起動すると、UbuntuARMのuser名とpasswordを入力するように求められるので、ご希望の内容を入力してください。
導入後は./start.shで実行できます。

```shell
cd ARMUbuntuGit
chmod +x mkvm.sh
./mkvm.sh
```
#最後に
QEMUでUbuntuARMだぜうぇいってなったところで自分は気づきました。
「・・・あれ、使い道あんま無くない？」

お読みいただきありがとうございました。
historyで簡単に過去のコマンドを実行する

[zenn](https://zenn.dev/mo_ri_regen/articles/linux-history)でも同じ記事を投稿しています📮
[zenn](https://zenn.dev/mo_ri_regen)ではフロントエンドのことも含め、いろいろ投稿しているのでぜひご覧ください👋

## 用法

一つ前に実行したコマンドであれば"↑"を押せば実行できますが、
少し前に実行したコマンドとなると、"↑"を押し続けることになるので遡ることが大変です。
そのようなときに history コマンドを使うと過去に入力したコマンドを一覧で表示することができます。
どのコマンドを使ったか覚えている場合は grep で絞ると見やすくなります。

```bash
history | grep <search_word>
```

実行すると、行番号と<search_word>で絞ったコマンドが表示されるので

```bash
!<行番号>
```

を入力すると実行されます。

## 実例

"php artisan migrate" コマンドを実行したいとします。

```bash
# artisanに絞って履歴を出力する
[username@foo]$ history | grep artisan

# 実行結果
989 php artisan list
991 php artisan route:list
992 php artisan route:list
998 php artisan migrate
1012 php artisan list

# 998行目を実行
[username@foo]$ !998
```
スプレッドシートにハッシュ関数を実装してみた【GAS】

セキュリティ系の勉強を進めているうちに一方向ハッシュ関数についても触れ、
実装してみたいなぁと思いGASで実装してみました。

といっても、**GASが最強に便利すぎてハッシュ関数の命令文が用意されていた**ので、ほとんど何もしなくても実装できちゃいました。
さらにさらに、先人がわかりやすいコードも残してくれていたので**脳死状態でSHA256を実現できました**。
すご。

https://qiita.com/benridane/items/2b7caa9df9445b6991bb

#実現したかったこと
**「パスワードが記載されたシートをハッシュ化してCSVファイルに出力する。」**

本当にそれだけです。なんとなくハッシュ後の値を別で保存するシートを用意していますが、**実行するとどっちも更新されるので、認証的な効果は皆無です**。
ちょっと改良すれば、認証機能を持たせることができると思いますので、いつか暇があったら実装してみます。

#コード内容

```javascript:SHA256_GAS
function myFunction() {
  var currrentSheet = SpreadsheetApp.getActiveSheet();
  var targetSheet = SpreadsheetApp.openById("*************************").getActiveSheet();
  var targetLastRow = targetSheet.getLastRow();
  var currentValues = currrentSheet.getDataRange().getValues();
  
  var hashedRow; //ハッシュ化結果を保存

  for(var i=1;i<currentValues.length;i++){
    //ハッシュ化(SHA256)
    var raw = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, currentValues[i][0], Utilities.Charset.UTF_8); 
    hashedRow = mySHA256(raw);

    currrentSheet.getRange(i+1,2).setValue(hashedRow); //元シートにハッシュ値を出力
    targetSheet.getRange(targetLastRow+1,1).setValue(hashedRow); //別シートにハッシュ値を出力

    targetLastRow = targetSheet.getLastRow(); //最終行の更新
  }
  csvOut(targetSheet.getDataRange().getValues());  
}

function mySHA256(raw){
  var strHash = ''; //ハッシュ値の文字列
  var numHash = 0;  //ハッシュ値の数値
  
  for (i = 0; i < raw.length; i++) {
    numHash = raw[i];
    if (numHash < 0) { //ゼロ未満だったら
      numHash += 256;  //マイナスの除去
    }
    if (numHash.toString(16).length == 1) { 
      strHash += '0'; //1桁なら0をくっつける
    }
    strHash += numHash.toString(16); //16進数表記の文字列に変換
  }
  return strHash;
}

function csvOut(targetValues){
  //ファイル名生成
  var date = new Date();
  var toDay = Utilities.formatDate(date,"Asia/Tokyo","yyyyMMdd"); 
  var fileName = "SHA256_" + toDay;
  
  //csv出力の準備
  var csvOutput = targetValues.join('\n');
  var blob = Utilities.newBlob(csvOutput, MimeType.CSV, fileName + '.csv');
  var id = "*************************"; //フォルダID
  var folder = DriveApp.getFolderById(id);

  //CSVファイルを作成
  folder.createFile(blob);
}
```

myFunction関数はメイン処理を行うところで、mySHA256関数は文字列を取得して16進表記の文字列に変換、csvOut関数は指定したGoogleDriveのフォルダにcsv形式のハッシュ化データを保存する関数です。
細かい説明はコメントに残しています。（放棄）

#実行結果
以下がパスワード一覧の元データです。
ちなみに、ここに書いているパスワードは日本人が設定しがちでかつ一瞬で打ち破られるパスワード一覧らしいです。
GASを実行するとB列にハッシュ値が出力されます。
![スクリーンショット 2022-02-12 10.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/c19698ef-ce6f-85d0-d12e-14e7b453783c.png)

こちらがハッシュ値を保存しておく別ファイルです。
このファイルをそのままcsvで出力します。
![スクリーンショット 2022-02-12 10.50.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/cc4462e9-ed06-87d4-7ee5-aa138b818bd6.png)

そしてこちらがCSVファイルの生成結果です。
![スクリーンショット 2022-02-12 10.51.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/e61b6643-e727-4e4d-e340-152637e7007a.png)

関数モリモリで簡単にSHA256を実現できたので、
外部の怪しいハッシュ変換ソフトを使うくらいなら自分で作ったほうが良いかもしれませんね。
**まぁ、そもそもこの結果がうまくいってるのかはわからんですが。**
python:gpt-3を使ってAIを感じてみる。

#背景
・仕事で疲れた状態などストレスが溜まっているときは「酒！やけ食い！」してしまう。
・夕食の内容はAIに決めてもらう自分ルールを作って、少しでも健康的な身体になりたいなと。
#内容
①gpt-3とは
②活用例
③実際に使ってみて
###①gtp-3とは
・OpenAIの最新の深層学習モデルにアクセスすることができるクラウドサービス
・触ったばかりで詳細は理解してませんが、「色んな文章作成サービス」と捉えています。
・OpenAIのURL
https://beta.openai.com/overview
###②活用例
・チャットボット、英訳、プログラミングコード作成、文章を要約、レシピ作成など。
・OpenAIのホームページに他に例がたくさんあり。
・海外の掲示板の質問の返答にも使われていた！？らしいです。
###③実際に使ってみて
・コードは下記記事を参照。
https://qiita.com/nyax/items/553bf5610c2d2202de22

```python:code
import openai

openai.api_key = "取得したAPIキー"
prompt = "太りたくないが、食欲は満たしたい。何を食べたらいいかな？"

response = openai.Completion.create(
    engine="davinci",
    prompt=prompt,
    max_tokens=300,
    stop="."
)

print(response["choices"][0]["text"])
```
***
返答は、下記のようになりました。
食べる献立を教えてくれなかったけど、なんか凄いぞ！！
![screen 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698556/b2a8b38e-a236-be67-8796-966a88cab6d3.png)
#所感
・色々な質問しても返答くれるので非常に面白いです。
・他にも多々使い方があるので、非常に面白い。
・面白いので活用例を見ながら無料使用枠内で色々触ってみます。

※無料使用枠
・使用開始3ヶ月間の有効期限付きの18$無料クレジットが配布される
・使った分だけ課金される従量課金制。

※登録したらすぐ使えました。

以上。
タイマの分解能とレイテンシーの測定方法

# 概要
プログラミング言語には，実行時間を測定するために複数のタイマを提供していることがある．
それぞれのタイマには性能が異なっていることがある．そのため，タイマの性能を知っていないと正確に実行時間の測定が行えない．
そこで，タイマの分解能とレイテンシーの測定をプログラムで行う方法を解説する．これによって，分解能とレイテンシーの測定方法を知ることで独自でタイマの性能を調べられる．

:::note info
**分解能**
タイマが測定可能な時間粒度を指す．
:::
:::note info
**レイテンシー**
タイマの測定遅延時間を指す．
:::

# 測定方法
タイマの分解能とレイテンシーの測定方法は参考資料[1]の3章に記載されている方法を解説する．

:::note warn
以降で紹介するプログラムは参考資料[1]とは多少異なっている箇所がある．
:::
:::note warn
インタープリタ系言語では，参考文献[1]の方法を用いて分解能とレイテンシーを測定するのは難しいかもしれない．
:::


# 分解能
タイマを連続実行してタイマのカウンタが変化したタイミングを捕捉する．その変化値を分解能として算出する.

:::note info
参考資料[1]では，タイマのカウントが変化したタイミングを複数回捕捉する．そして，その変化値の平均値を分解能としている.
:::

### プログラム例
以下に，分解能測定の実装を記載したプログラム例を示す.

```C++:[C++]分解能測定関数
/**
 * @fn
 * 分解能測定
 * @brief タイマの平均分解能を測定する.
 * @param count タイマ捕捉回数 
 * @return 平均分解能
 * @detail タイマを複数回実行して，タイマのカウントが変化したタイミングを捕捉する.
 * 　　　　　それを引数で指定したタイマ捕捉回数分行う．
 * 　　　　　そして，その変化値の平均値を分解能として算出する．
 */
double get_resolution(const size_t count) {
    long long sum = 0;
    for (auto last = time(), size_t index = 0; index < count; last = time()) {
        const auto next = time();
        if(last != next){
            ++index;
            sum += next - last;
        }
    }
    return static_cast<double>(sum) / count;
}
```
:::note info
**time()**
分解能測定対象のタイマ関数
:::

:::note warn
for文を用いて測定を行っているので多少の誤差が発生していることがある.
:::

**使用方法**
get_resolutionに分解能捕捉回数を引数に指定して分解能の平均値を取得する.

```C++:[C++]分解能測定関数使用例
# タイマの分解能を取得
const auto resolution = get_resolution(1000);
```
:::note alert
タイマがサポートしている時間単位によっては実行に時間がかかることあるので分解能捕捉回数を調整する必要がある．
例えば，秒単位タイマでは捕捉回数を1,000回に設定すると計測に約17分以上かかる. 
:::

# レイテンシー
タイマのを複数回実行したときの合計実行時間を計測する。そして，その合計実行時間を基に算出した平均値をレイテンシーとする．

### プログラム例
以下に，レイテンシー測定の実装を記載したプログラム例を示す.

```C++:[C++]レイテンシー測定関数
/**
 * @fn
 * レイテンシー測定
 * @brief タイマのレイテンシーを測定を測定する.
 * @param count タイマ関数実行回数 
 * @return 平均レイテンシー(タイマ平均実行時間)
 * @detail 引数で指定された回数分タイマを実行した合計実行時間を測定する。
 * 　　　　　そして，その合計実行時間を基に算出した平均値をレイテンシーとして算出する．
 */
double get_latency(const size_t count) {
    const auto start = time();
    for (int index = 0; index < count; ++index) {
        time();
	}
    const auto stop = time();
    return static_cast<double>(stop - start) / (count + 1);
}
```
:::note info
**time()**
レイテンシー測定対象のタイマ関数
:::

:::note info
count + 1で割っているのはタイマの測定開始(start)とタイマの測定終了(stop)の分も考慮して+1している．
:::

:::note warn
for文を用いて測定を行っているので多少の誤差が発生していることがある．
:::

**使用方法**
get_latencyにタイマ実行回数を引数に指定してレイテンシーを取得する．

```C++:[C++]レイテンシー測定関数使用例
# タイマのレイテンシーを取得
const auto latency = get_latency(1000000000);
```
:::note alert
タイマが補足できる実行時間単位になるように実行回数を調整する必要がある．
例えば，秒単位タイマでは，ナノ秒単位でのレイテンシー測定を考慮すると合計実行時間が秒になるように1,000,000,000回以上に調整すると望ましい.
:::

# 参考資料
1. Optimized C++ ―最適化、高速化のためのプログラミングテクニック, Kurt Guntheroth (著), 島 敏博 (監修), 黒川 利明 (翻訳), オライリージャパン, 2017年2月.
1. 性能評価プログラム, https://github.com/Ocean00000/TimeEvaluation
RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens メモ


* RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens の個人メモ

## Mutual TLS for OAuth Client Authentication

クライアント認証方式として、次の2つを定義する。

### PKI Mutual TLS Method(`tls_client_auth`)

* クライアント・認可サーバー間のTLS通信で用いられたクライアント証明書をクライアント認証に用いる。
* **認可サーバー** : クライアント証明書の有効性確認としてSubject Distinguished NameもしくはSubject Alternative Nameのエントリーのどちらかが事前に登録されている値と一致するかを確認する。
  * **クライアント** : クライアント証明書のSubject Distinguished NameもしくはSubject Alternative Nameを事前にサーバーに登録する。

### Self-Signed Certificate Mutual TLS Method(`self_signed_tls_client_auth`) 

* 自己署名証明書をクライアント証明書として用いる。
* クライアントは、自己署名証明書・公開鍵を事前に認可サーバーに登録する。



## Mutual-TLS Client Certificate-Bound Access Tokens

* 認可サーバー側でアクセストークンをクライアント証明書と紐づけ、API認証をより強固に行う方法
* **処理の流れ**
  * **認可サーバー/トークンエンドポイント** : アクセストークン発行時、TLS 通信で提示されたクライアント証明書のハッシュ値を計算し、そのハッシュ値をアクセストークンと紐付けて保存する。
     * アクセストークンがJWT形式の場合は、ハッシュを埋め込む。
  * **クライアント** : 取得したアクセストークンを使いリソースサーバーの API にアクセスする。その際、トークンエンドポイントリクエスト時に使用したものと同じクライアント証明書を用いる。
  * **リソースサーバー** : リクエストからアクセストークンとクライアント証明書を取得し、クライアント証明書のハッシュ値を計算して、その値がアクセストークンと紐付くハッシュ値と同じか確認する。

![mtls.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/2ba933c1-9285-14c8-f07b-dd4c9da4756c.png)




## 参考情報

* [RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens](https://www.rfc-editor.org/rfc/rfc8705.html)
【RAIL】Webアプリのパフォーマンスを上げるための指標

# RAILってなに？

RubyのフレームワークRailsのことではありません。

### RAILとは
- ユーザーが行う行動を4分割し、それぞれでアプリが必要なパフォーマンス目標を数値化したもの
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1310301/de3c9b1c-6fdf-11ae-d6cf-bd3385a67c75.png)

参考画像：[RAILモデルでパフォーマンスを評価する](https://web.dev/rail/)

### 要するに、UX改善のためのパフォーマンス指標のこと === "RAIL"

R　・・・ レスポンス
A　・・・アニメーション
I　・・・アイドル処理
L　・・・読み込み

# レスポンス : 100ミリ秒
:::note info
ユーザーがアクションを起こして、イベントが起こるまでの時間
例 ： ボタンをクリックした時にダイアログが表示されるまでの時間
:::

:::note warn
100ミリ秒~300ミリ秒が経過するとユーザーは微かに遅延していると感じる
→ インジケータの表示が求められてくる
:::


# アニメーション : 10ミリ秒(最大16ミリ秒)

:::note info
アニメーションの各フレームを10ミリ秒以内に生成
例 ： 可視的なアニメーション、ドラックやスクロールなど
:::
- フレームとは、[Scripting、Rendering、Painting](https://qiita.com/kosuke-17/items/aaf8ecb090fb664198f4)という描画の処理が始まって終わる工程

# アイドル処理 : 50ミリ秒
:::note info
アイドル状態に実行されるJacascriptの処理時間
例 ： ページを最初に読み込む際に、少ない量のデータを読み込んでアイドル時間を使って残りのデータを読み込む
:::
- 一度、レスポンス、アニメーション、読み込みが終わってユーザーのアクションを待っている状態

# 読み込み : 1000ミリ秒
:::note info
Webページのコンテンツの読み込みにかかる時間
1000ミリ秒で抑えられると、画面遷移が問題なく行えていると実感できる
例 ： スプラッシュスクリーンを活用(ローディング画面)
:::

>ページの読み込みパフォーマンスに影響を与える要因
>・ネットワークの速度と遅延
・ハードウェア（たとえば、低速のCPU）
・キャッシュの削除
・L2 / L3キャッシングの違い
・JavaScriptの解析


***

**参考**
[RAILモデルでパフォーマンスを評価する](https://web.dev/rail/)
**書籍**
[Webフロントエンド ハイパフォーマンス チューニング](https://www.amazon.co.jp/Web%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89-%E3%83%8F%E3%82%A4%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E4%B9%85%E4%BF%9D%E7%94%B0-%E5%85%89%E5%89%87/dp/4774189677/ref=pd_sim_14_2/355-8347036-3165354?_encoding=UTF8&pd_rd_i=4774189677&pd_rd_r=242f1b07-5d75-484b-831f-8e3186723bd4&pd_rd_w=SLj3f&pd_rd_wg=efHnd&pf_rd_p=51d7f721-ab31-4c99-8db8-c3f45803167a&pf_rd_r=639J7G22C2SMCZT0SF5B&psc=1&refRID=639J7G22C2SMCZT0SF5B)