OmniAICreator/Qiita-1.07M huggingface dataset:
Formオブジェクトで作成したデータを削除する

#はじめに#
掲示板を作成中Formオブジェクトを用いて投稿にタグ付け機能を実装する所まで行いました。
その後投稿詳細機能と問題の投稿削除機能を実装しましたが実際に投稿を削除してみたところ

```
Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`アプリ名_development`.`poat_tag_relations`, CONSTRAINT `fk_rails_ca2d4f0737` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`))
```
というエラーが出てしまい削除ができませんでした。

#調べたこと#
エラー内容をよく読んでみると、投稿idは中間テーブルの外部キー(foreign key)に含まれて
デリートやアップデートができないよ！と書かれているのがわかります

#外部キーの設定変更#
今回はdestoryで外部キーとして設定している項目を削除させるように、dependent: :destroyを設定しようと思います
この簡単な設定により不具合なく投稿の削除ができるようになります

```/app/models/post.rb
class Post < ApplicationRecord
  has_many   :post_tag_relations,foreign_key: :post_id, dependent: :destroy
  has_many   :tags, through: :post_tag_relations
  has_many   :comment
  belongs_to :user
end
```
goenvを卒業しよう

# はじめに
Go言語のversionを使い分ける際に`goenv`を利用している方は多いと思います。
このエントリでは`goenv`を使わずに複数versionを切り替える方法をまとめます。

# 簡単3ステップ

[Goのプロジェクト構成の基本](https://zenn.dev/nobonobo/articles/4fb018a24f9ee9) の方法で実施します。

最初にOSのパッケージマネージャーでGoをインストールします。
この時は version を気にしなくて良いです。
後述の手順で利用する version を導入するためにだけインストールします。

+ on Ubuntu: (WSL2でも同様)

```shell:install.sh
sudo apt install golang-go
```

続いて`GOPATH`, `PATH` を設定します

```shell:env.sh
export GOPATH=$HOME/.go
export PATH=$GOPATH/bin
```

続いて使いたいGo versionをインストールします。

```shell:go-install.sh
go get golang.org/dl/go1.15.8
go1.15.8 download
```

これで`go1.15.8`コマンドで実行できるようになります。

```shell:go-run.sh
go1.15.8 run
```
年月を指定して、その月の最終日あるいは翌月の初日を求める

```
ykishi@dezembro issues-86 % YEAR=2021 MONTH=6                                 
ykishi@dezembro issues-86 % gdate -d${MONTH}/01/${YEAR}-1days+1month '+%Y/%m/%d'
2021/06/30
ykishi@dezembro issues-86 % gdate -d${MONTH}/01/${YEAR}+1month '+%Y/%m/%d' 
2021/07/01
ykishi@dezembro issues-86 % 
```

ちなみに指定した期間だけ移動する場合は以下：

```
ykishi@dezembro ~ % gdate -d '1 month ago' '+%Y-%m-%d'
2021-09-08
ykishi@dezembro ~ % gdate -d '3 month ago' '+%Y-%m-%d'
2021-07-08
ykishi@dezembro ~ % gdate -d '6 month ago' '+%Y-%m-%d'
2021-04-08
ykishi@dezembro ~ % gdate -d '2 week ago' '+%Y-%m-%d'
2021-09-24
ykishi@dezembro ~ % gdate -d '28 day ago' '+%Y-%m-%d'
2021-09-10
ykishi@dezembro ~ % gdate -d '1 year ago' '+%Y-%m-%d' 
2020-10-08
ykishi@dezembro ~ %
```

```
ykishi@dezembro ~ % gdate -d '+1year+2month+10day' '+%Y-%m-%d'
2022-12-18
ykishi@dezembro ~ %
```
pythonでのbit全探索

## 概要
atcoderなどでbit全探索の問題が出た際に、さらっと参照するための備忘録です。
細かなbit全探索の説明は、[けんちょんさんの記事](https://drken1215.hatenablog.com/entry/2019/12/14/171657)や[アルゴリズムの解説サイト](https://algo-logic.info/rec-bit-search/)を見た方が良いと思います。

## bit全探索について
bit全探索とは、ある集合{1,2,3,...,N}に対して1を含めるor含めない、2を含めるor含めない…で全通り探索する方法です。
要素１つにつき、含めるor含めないで2通り、集合全体で**2^N**通りになるため、Nが小さいときに活用できます。
この時、含めるを1で含めないを0で表すことで2進数を用いて簡単に全列挙できる点がポイントです。

## 使い方
基本的に自分は、集合の部分集合を全列挙する形で活用しています。
非常に基本的な問題として、以下の問題などが分かりやすいかと思います。

[引用元：AIZU ONLINE JUDGE](https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_A&lang=ja)


> 長さ n の数列 A と整数 m に対して、A の要素の中のいくつかの要素を足しあわせて m が作れるかどうかを判定するプログラムを作成してください。A の各要素は１度だけ使うことができます。
数列 A が与えられたうえで、質問として q 個の mi が与えれるので、それぞれについて "yes" または "no" と出力してください。

#### 入力
> n
A1 A2 A3 ... An
q
m1 m2 m3 ... mq

```python:sample.py 
# 入力の受け取り
n = int(input())
A = list(map(int, input().split()))

q = int(input())
M = list(map(int, input().split()))

# 列挙したものを格納する配列
sum_list = []

# 1を n bit左にシフトし、上限値を1_0*(n-1) にする。
for i in range(1 << n):
  l = []
# iをjbit右にシフトし、1の時だけ配列に格納するようにする
  for j in range(n):
    if i >> j & 1:
      l.append(A[j])
# iのときの配列をもともと設定しておいた配列に格納する
# 今回は和を求めたいため、sumで格納。
  sum_list.append(sum(l))

# 全通り列挙された配列をもとに、回答を表示していく。
for i in range(q):
  if M[i] in sum_list:
    print("yes")
  else:
    print("no")
```

## まとめ
Nが小さいときは、bit全探索を用いて全部列挙しましょう。

なんとなく理解できた方には、@e869120さんが書かれた[分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)で練習すると良いと思います。
C# Seleniumでスクリーンショット --メモ--

googleで"Selenium C#"を検索。　結果をスクリーンショット。
画像はexeと同じ場所に保存。

※　例外処理はしていません。

```c#
using System;
using System.IO;
using System.Reflection;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            IWebDriver driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));

            driver.Navigate().GoToUrl(@"https://www.google.co.jp/");

            IWebElement qbox = driver.FindElement(By.Name("q"));
     
            qbox.SendKeys("Selenium　C#");

            qbox.Submit();

            driver.Manage().Window.FullScreen();

            Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
            screenshot.SaveAsFile("SeleniumとC#の検索結果.png", ScreenshotImageFormat.Png);

            Console.ReadKey();
            driver.Quit();
        }
    }
}


```
Rubyのattr_accessorとは

# attr_accessor

`attr_accessor`の理解に少し時間がかかったため備忘録として書きます。



```ruby:user.rb
class User
  attr_accessor :name
end
```
上記は省略された書き方で、

```ruby:user.rb
class User
# セッター
  attr_writer :name

#　　ゲッター
  attr_reader :name
end
```
と書くことができます。
ここで`atter_writer`と`atter_reader`はそれぞれ「ゲッター」と「セッター」と呼ばれています。

さらに、下のように書くこともできます。

```ruby:user.rb
class User

# ゲッター
  def name=(name)
    @name = name
  end

# セッター
  def name
    @name
  end

end
```

まずゲッターは

```ruby:user.rb
def name=(name)
  @name = name
end
```
となっています。
`@`から始まる変数は[インスタンス変数](https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html)と呼ばれ、オブジェクト内でメソッドをまたいで使用できる変数です。

クラスを定義した後に

```ruby:user.rb
# Userクラスをオブジェクト化
user1 = User.new

#セッターを呼び出して値を代入
user1.name = "Taro"
```
とすれば、インスタンス変数である`@name`に`Taro`が代入されます。

次にセッターについて考えます。

```ruby:user.rb
def name
  @name 
end
```
`name`というメソッドを定義しており、その中でセッターで定義した`@name`を戻り値としています。

なので、クラス定義後に

```ruby:user.rb
# Userクラスをオブジェクト化
user1 = User.new

#セッターを呼び出して値を代入
user1.name = "Taro"

# ゲッターで返される値を出力
puts user1.name
```

とすれば、`Taro`が出力されます。


つまり、`attr_accessor`はゲッターとセッターを1行で使うことができる便利なやつということです。
Displaying progress bar and ETA for Airflow backfills

During my work I often have to run long Airflow backfills. They take very long time and my boss often asks me "How long do you still need?"
It is not very easy to answer this question, since while Airflow displays INFO messages as

```
[2021-07-06 14:24:11,117] {backfill_job.py:364} INFO — [backfill progress] | finished run 65 of 67 | tasks waiting: 0 | succeeded: 266 | running: 2 | failed: @ | skipped: 67 | deadlocked: @ | not ready: ®
```
it does not show the estimated remaining time (ETA). 

In order to solve this problem, I found myself using the simple script below (see [https://github.com/nailbiter/for/blob/master/forpython/fordatawise/non-reusable/backfill-progress.py](https://github.com/nailbiter/for/blob/345a2f291f4744e0cb99fa3a9554d2c62b5533fe/forpython/fordatawise/non-reusable/backfill-progress.py) for latest version):
```py
import click
import sys
import re
from tqdm import tqdm


@click.command()
def backfill_progress():
    idx = 0
    max_cnt, tqdm_object = [None]*2
    pat = re.compile(r".*finished run (\d+) of (\d+).*")
    while True:
        try:
            line = input()
        except EOFError:
            break
        m = pat.match(line)
        if m is not None:
            i, cnt = [int(m.group(i+1)) for i in range(2)]
            if max_cnt is None:
                max_cnt = cnt
                tqdm_object = tqdm(total=max_cnt)
            if i > idx:
                tqdm_object.update(i-idx)
                idx = i

        click.echo(line)


if __name__ == "__main__":
    backfill_progress()
```

The usage is as follows (if you have the script above saved under the name `backfill-progress.py` in your current folder):
```sh
airflow backfill DAG_ID -s YYYY-MM-DD -e YYYY-MM-DD | python3 backfill-progress.py
```

The generated output will be similar to below:

![Screen Shot 2021-07-07 at 15.48.54 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/bb6733bd-0819-e6ad-b634-123870451361.png)


As can be seen from source code, the idea is simple: upon reception of a line from `backfill` command's output (here we make use of Unix's mighty [piping mechanism](https://en.wikipedia.org/wiki/Pipeline_(Unix)))) script searches the line for 
text matching the regex `finished run (\d+) of (\d+)` and if this regex is present, updates the progress bar and ETA estimate. Also, the line is unconditionally forwarded to stdout (so we can view the `backfills`'s output as well).

Before wrapping out, I have to mention that displaying progress bar and ETA estimate is done via the great [tqdm](https://github.com/tqdm/tqdm) package. Also, `click` library is used for convenience, but this dependency can be easily removed.
GoogleDriveにアップロードしたQRコードをjsで読み取る

#利用シーン
GformでLINEの友達追加QRコードを送信してもらってスプレッドシートで管理していた。
画像だといちいち読み取るのがめんどくさいので、解析したいなと思いました。（※架空の話です）

その他にもgoogleDriveのQRコードをさくっと解析したい時ぐらいあるはず。
知見を見つけるのに時間がかかったので書きました。


#画像IDを取得する
①GoogleDriveにアップロードされた画像の共有リンクを発行します。

```
https://drive.google.com/file/d/1e9TFzKj25YS12nlr1ItHGpPRHTvSvpj/view?usp=sharing
```

②共有リンクから、画像IDを取得します。
リンクの中の`d/`と`/view`に挟まれた部分です。

③jsのコードに画像IDを書き換えます

```index.js
const axios = require("axios");
const QRReader = require("qrcode-reader");
const jimp = require("jimp");

async function main() {
    const imageID = "画像ID" 
  await jimp.read(
    `https://drive.google.com/uc?export=view&id=${imageID}`, 

    async function (err, image) {
      const qr = new QRReader();
      const value = await new Promise((resolve, reject) => {
        qr.callback = (err, v) => (err != null ? reject(err) : resolve(v));
        qr.decode(image.bitmap);
      });
      message = { type: "text", text: `解析結果：${value.result}` };
      console.log(message)
    }
  );
}
main();
```

④モジュールのインストールをこないます

```
npmi init -y
npm install 
```

⑤起動します

```
node index.js
```
⑥解析が完了します!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/3c390b37-7618-c1e0-acfd-425db2687b5b.png)

## サンプルコード
https://github.com/inoue2002/googledrive-qrcode-reader


##利用例

https://qiita.com/inoue2002/items/0099c17d9f2a69e21920
【Docker】Reactがすぐにexitしてしまう時の対処方法　no.32

![パンプキン カフェ (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/1d38c588-fce6-0215-a1c3-132666e0e61d.png)


こんにちは。まゆみです。

DockerでReact環境を作ろうと、

```
docker run <ImageID>
```

したら、すぐにContainerがExitになってしまう。

今回の記事では、ContainerのSTATUSがExitになってしまう時の対処方法を書いていこうと思います

#Exitしてしまう時の対処方法

Create React Appのアップデートにより、今までは普通に『docker run』できていたのが、できなくなってしまったようです。


解決方法は『-it』を付けてContainerをrun すればいいようです。



##Dockerfileの場合

```
docker run -it <ImageID>
```

##docker-composeの場合

```
stdin_open: true
```

docker-composeファイルに変更を加えた時は必ず

```
docker-compose down && docker-compose up --build
```

と、down でContainerを停止・削除してから--build オプションを付けて、Image をrebuildしましょう
Freenomでエラーを回避して無料ドメインを取得する（2021/07/08版）

# なんどやってもエラーで取得できない

Freenomにて無料ドメインを取得する方法はググると大量に出てくるが、これらの回避方法を色々と試しても **Some of your domains could not be registered because of a technical error** となってしまい、取得ができない。

# 試したこと

- プロキシを通してアメリカのIPで登録する
- ドメインのTLD（.tk）まで指定してドメインを検索する
- ログアウトした状態（新規ユーザー）で登録する
- 正しい住所等を入力する

これらを色々と試したが、うまくいかない。
過去に下３つの要件で登録できた実績はあるが、久々にやろうと思ったらできなかった。
恐らく時期で要件が変わっているのではないかと思われる。

# うまくいった・・・が・・・？

本日（2021/07/08時点）での必須要項は

## 1. ドメインのTLD（.tk）まで指定してドメインを検索する

検索は `hogehoge.tk` 形式で検索すること。

## 2. アカウント情報をすべて入力するが**住所はアメリカのものでなければならない**

というものだった。
国の選択肢があるのに・・・

なお、企業名や電話番号も必須。
企業名はなにがしかが入っていればいいようなので「Personal」でもよい。

### ただし住所はダミーでも良い

いいのかよっ！


つまり、ここでの解決法は**アメリカのダミー住所（と電話番号）を取得して登録**するというもの。

ちなみに、**登録済みユーザーでもアカウント情報を要件を満たすように変更すれば大丈夫** なので、複数ドメイン持ちにもなれる。



## アメリカの（嘘）住所を取得しよう

US Fake Address Generator
https://www.fakeaddressgenerator.com/usa_address_generator

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104999/b31120e2-590f-4a5c-f3ea-269af71bb06b.png)

上記にアクセスした時点ですでに添付のような感じで作成されている。
気に入らない場合は「reflesh」ボタンで変更可能。

住所はもちろん、電話番号も作成されているため、+1電話番号部分に入力する

ちなみに、氏名も作成されるが、これは自分の名前でもいいかと思う（わかりづらいし）

# まとめると

- IPは関係ない
- 新規ユーザーかどうかも関係ない
- `hoge.tk` や `fuga.ml` のようにTLDでドメイン検索を行う必要がある
- アカウント情報はすべて埋める必要がある
- 住所や電話番号はアメリカのものが必要（US Fake Address Generatorで作成）
- 住所や電話番号、企業名はダミーでも通る

それでは、よい Freenomライフを！




# 注意

あくまでこの方法で登録できたというものなので、
ダミー住所を扱うことの是非やそれにより生じたトラブルについては自己責任でお願いします。
1.8(易) 和事象と確率の和


## 方針

事象A_k, k=1,2,...を考える．命題1.2(4)より，

```math
P[A_1\cup A_2]=P[A_1]+P[A_2]-P[A_1\cap A_2]
```

であるから，

```math
P[A_1\cup A_2]\leq P[A_1]+P[A_2]
```

である．さらにこれを拡張して

```math
P[\cup_{k=1}^\infty A_k]\leq \sum_{k=1}^\infty P[A_k]
```

が成り立つ．

## 答案

```math
\begin{align}
P[\cap_{k=1}^\infty A_k]&= 1-P[\cup_{k=1}^\infty A_k^c]\\
&\geq 1-\sum_{k=1}^\infty P[A_k^c]
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
【自戒】JavaScriptは関数型言語であってオブジェクト指向言語ではない は間違いだよ

# 概要

TwitterでJavaScriptについて誤った解釈のツイートをしました。

https://mobile.twitter.com/bkmntn1592/status/1412936378439016449

するとそれは違う旨の指摘を頂き、調べてみるとどうやら全く理解出来ていなかったみたいでした。
自戒の意を込めて調べた内容をまとめてみました。


# JavaScriptにおけるオブジェクトとは

JavaScriptの広義のオブジェクトは
**nullとundefined以外の全て**

JavaScriptのオブジェクトは全てがその元となるプロトタイプオブジェクトと呼ばれる、オブジェクトの元となるオブジェクトが存在する。

Rubyなどの、クラスのインスタンスとしてオブジェクトが存在するようなのはクラスベースと呼ばれる。

https://qiita.com/awakia/items/8ff451ca5f8ae0122be7

# では、関数型言語ってなに？

Wikipedia曰く

> 数学的な意味での関数を主に使うプログラミング言語のこと。

関数型プログラミングというのはそういうスタイル(副作用が少ない、参照透過性の高い記述ができる[^2])で書くことを指す。
よって、**関数型の色があってもオブジェクト指向言語ではないということにはならない**

現に、JavaScriptは第1級関数[^1]をサポートしているので関数型プログラミングができるが、だからといって関数型言語なだけとはならない。

# まとめ。なぜ間違えた？

プログラミングパラダイムの中で分類されていたのを見て、「JavaScriptは関数型が使えるんだから関数型言語に分類されるんだ！ならオブジェクト指向じゃないのじゃなくて関数型言語なのか！(´☆ω☆｀)ﾅﾙﾎﾄﾞﾈ！」と思ってしまいました。

https://ja.m.wikipedia.org/wiki/手続き型プログラミング

なんかこの辺の思考回路だけ小学生のまま止まってる気がする。。
とはいえこの機会に(ちょっとは)分かった(つもり)になれたので、良かったです！

指摘してくださった方、ありがとうございました！

[^1]: 関数を、他の基本的なオブジェクト同様に生成、代入、演算といった用途で使用することができる性質のこと。[参考](https://ja.m.wikipedia.org/wiki/第一級関数)

[^2]: この辺は混みいりそうな感じなので、再度調べて書き直そうと思います。[参照](https://qiita.com/Yametaro/items/1de3c2b76b8a4dc2d30d)
【初心者向け】Python入門に超おすすめの本ランキング〜機械学習・作業自動化〜

この投稿ではこれから Python に入門する人に向けて **まず読んでほしい**おすすめの書籍をランキング形式で紹介しています。

## Pythonで出来ること

Pythonは本当に色々なことができるプログラミング言語です。

- 機械学習
- 統計処理
- Webアプリのサーバーサイド
- エクセル操作等の単純作業の自動化
- Webスクレイピング
- 一部のデスクトップアプリ作成

できることを挙げ出せばキリがありません。
しかもサードパーティライブラリが異常に充実しているので、少ないことで高い生産性を発揮することが出来ます。
おまけに文法も単純なのでプログラミング入門にも超オススメな言語です。

この投稿ではランキング形式でおすすめPython本を紹介しています。
が、実際に読む本を選ぶときにはPythonを活用して達成したい目的に合わせて自由に選択してください。


## 【やりたいこと別】Python入門にオススメの本ランキング



### 1位：ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

・[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://amzn.to/3wlXkA6)

一位は**「ゼロから作る Deep Learning」**にしました。
その名の通り、前提知識なしでディープラーニングの実装をスタートできる良著です。
機械学習や統計の知識がまだなくてもOKですですし、Python の基本文法の解説から入るのでプログラミング経験がなくても問題ありません。
高校レベルの数学さえ踏まえておけば OK です。

それでいてディープラーニングの基礎となる順伝播・逆伝播などの仕組みが一から理解できるのがポイントですね。
特定のフレームワークに依存した本でもないので、この本で学んだ内容は後々応用が利きます。


ちなみに同じシリーズの[自然言語処理編](https://amzn.to/3jUWnfl)もおすすめです。

### 2位：退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

・[退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング](https://amzn.to/3xmZEb3)

これも有名な本です。
これはエクセル処理やネットからのデータ取得、メールの一斉送信などの<font color="Red">「仕事上やらなくてはいけないけど全く面白くない」</font>作業をPythonで全て自動化するための本です。
「ノンプログラマーにもできる」と書いてある通り非エンジニアでもそれほど抵抗無く習得できる難易度です。
出てくるコードをコピペしたり少しいじって使うだけでも、雑務をこなすスピードが1000倍くらいになること請け合いです。

類似書籍としとして、[シゴトがはかどる Python自動処理の教科書](https://amzn.to/2TzV1w1)もオススメです。

### 3位：Python 1年生 体験してわかる！会話でまなべる！プログラミングのしくみ 
・[Python 1年生 体験してわかる！会話でまなべる！プログラミングのしくみ](https://amzn.to/2Uq95bi)

3位には、純粋なPython入門書を持ってきました。
登場人物として出てくるのは**「ヤギ博士」**と**「ふたばちゃん」**といういかにもユルそうなキャラクターです。
全体的な雰囲気からもわかる通り、かなり難易度が低めです。
その分、プログラミング経験者やガチ勢には少し物足りないかもしれませんが、「絶対に途中で挫折したくない」という初心者には超オススメできる一冊です。


### 4位：Pythonによるデータ分析入門 第2版
・[Pythonによるデータ分析入門 第2版](https://amzn.to/2SSvNIN)

こちらはPythonというより、Pythonの定番データ分析ライブラリである**Pandas**の入門本です。
（作者はPandasを作った人です。）
Pandasは、もともと株価などの金融データの定量分析のために作られたそうですが、今ではあらゆるデータ分析の場面で使用しますね。
僕も何度お世話になったかわかりません。

今後研究や仕事でデータ分析を行いたい人は、読んでおいて損はないはずです。
というか、定番すぎて職場や研究室の本棚をあさるとすぐに見つかる可能性もあるので、是非一度探してみてください。

なお、Pandasは勝手にデータの型が変換されていたりと、思わぬところに落とし穴があります。なので、中級者以上も読んでみると何かしら収穫があると思います。

## 関連記事

・[Python初心者必見にオススメのAI・機械学習のUdemy動画まとめ](https://qiita.com/ykimura517/items/1664fb0b66b488280800)

・[【超厳選7冊】おすすめの初心者向け株式投資本【最強のバフェット本】](https://in-base.com/3-investment-books)

・[【プログラミング初心者】費用対効果が高いUdemyのおすすめ動画講座まとめ](https://qiita.com/ykimura517/items/65df87dd77823fb2904d)
(たぶん) 4年越しにVirtualBoxをアップデートした話。

VirtualBoxをアップデートしました。
確認できた一番新しいバージョンが5.1.22なので、たぶん4年越しのアップデートになります。
かなりバージョンの開きがあり仮想OSが動作するか不安でしたが、ちゃんと起動したので書きます。

# 経緯
去年のWindows Updateにより、以前のバージョンのまま使用していたVirtualBoxが互換性エラーで使用不可に...
当時は諦めてそのまま放置していましたが、今更ながら確認したいファイルが出てきたので、恐る恐るアップデートを試すことに。

# 環境
* Windows 10 Home : 2004
* Oracle VM VirtualBox : 5.1.22(おそらく) → 6.1.22
* (仮想OS)Ubuntu 14.04

#更新してみた
## 5.1.22 → 5.2.44
いきなり最新版をインストールするのは怖かったので、5.2系から順々にアップデートすることに。
Windows hostsからインストーラをダウンロード後、そのままインストール。
↓
[Download VirtualBox (Old Builds): VirtualBox 5.2](https://www.virtualbox.org/wiki/Download_Old_Builds_5_2)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539214/c13bde39-e059-dd2a-675d-f14bd4be1d23.png)
5.2系すらサポート外と書かれている始末...(アプデさぼりすぎた)
とはいえ無事アップデートが完了し、Ubuntuを起動することが出来ました。

* [x]  5.1.22 → 5.2.44
* [ ]  5.2.44 → 6.1.22

## 5.2.44 → 6.1.22
バージョンを5.2.44にしたことで、VMの起動時に最新版のインストールを促すメッセージが出現。
なんだかこのメッセージにも安心感を覚えます。
そのままメッセージのリンクをたどってインストールします。
↓
[VirtualBox 6.1.22 platform packages](https://www.virtualbox.org/wiki/Downloads)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539214/7d17d04a-efe5-a27e-3be6-1a7c0e712ff7.png)

アップデートが完了し、Ubuntuもちゃんと起動しました。
(モニターの互換性が～みたいなメッセージは出てましたがとりあえずヨシとします。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539214/ced0ff42-d202-19fa-4f20-fc2a2af28b51.png) 

* [x]  5.1.22 → 5.2.44
* [x]  5.2.44 → 6.1.22


# おわりに
使用していたアプリが急に使えなくなると結構心臓に悪いことが分かりました。
このような事態にならぬよう、こまめなアップデートを心掛けたいと思います。

~~そもそもUbuntu14.04も更新したほうがいい。~~
テストコードを書く意味を考えてみた

#はじめに

webアプリを製作する上で動作に不具合があってはいけません。それを確かめるために動作確認をしますが、1つ1つ確認していくのには時間がかかります。

しかし動作を確認するためのコードを書き、そのコードを実行して自動で確認するという方法があるのでテストコードを理解するためにもアウトプットとして投稿したいと思います。

#テストコードとは

アプリの実装が終わったら自らを動かして確かめることができます。

例えば・・・

ユーザー管理機能の実装が終わり、ニックネームが空の場合登録できないので確かめてみる。。。
よし登録できない！

次はメールアドレスだ！空にして送信。登録できてない！成功！

と確かめなけらばなりません。

![スクリーンショット 2021-07-08 11.58.30（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/18b12f30-e10a-64a8-72b8-ee756a7d7be2.png)

#テストコードを書く意義

###ブラウザ上で手動で確認するのはデメリットが多い

アプリの挙動を確かめるには様々な挙動を確かめなければなりません。

- ユーザーがログインしているときは投稿ができる

- 投稿したユーザーがその投稿の編集ができる

など細かい作業があるのでもしかしたら人為的的なミスが起きるかもしれません。

もう一つはどのように確かめたかが残りません。
テストコードを書けば1つづつ何を検証したのか記述が残ります。

###テストコードを書けばアプリの仕様が理解できる

テストコードは仕様を理解してないと書くことはできません。
テストする項目を洗い出すことができ、仕様を見極めることができます。

#テストコードのパターンについて

大きく分けて2つあります。

**「うまくいくとき」「うまくいかないとき」** のパターンです。

ユーザー登録の項目を全て正しく入力した時登録される←**正常系**

ニックネームが空のとき登録できない←**異常系**

テストコードの種類も2つあります。

###単体テスト
モデルやコントローラーなどの機能ごとに問題がないか確かめます。たとえば、ユーザー登録におけるUserモデルのテストコードでは「ニックネームがないと登録できない」というバリデーションの挙動を確認します。

###結合テスト
ユーザーがブラウザで操作する一連の流れを再現して、問題がないか確かめます。たとえば、ユーザー登録における新規登録のテストコードでは「全てに入力して新規登録ボタンを押すと、新規登録完了ページに移動し、TOPページに戻るとさきほどマイページが表示されている」という流れを一気に確かめます。
playwrightをdockerでwatchモードとして動かしたい

# 今の所まだwatchモードはない（@playwright/test v1.12.3）

https://github.com/microsoft/folio/pull/154

# dockerで動かす

https://playwright.dev/docs/docker

公式が用意している`mcr.microsoft.com/playwright:focal`を使う。

```dockerfile:Dockerfile
FROM mcr.microsoft.com/playwright:focal

# 細かな設定があれば...
ENV LANG C.UTF-8

WORKDIR /app
```

```yml:docker-compose.yml
version: "3.7"
services:
  frontend:
    build:
      context: ./frontend # 適当な場所で
    ipc: host # chrome動かすなら入れたほうが良いらしい
    volumes:
      - ./frontend:/app # 適当な場所で
    user: 1000:1000 # これでデフォルトのpwuserで操作できる
    tty: true
```


https://playwright.dev/docs/docker

> NOTE
Using --ipc=host is recommended when using Chrome (Docker docs). Chrome can run out of memory without this flag.

コンテナ内に入って

```terminal
$ npm i chokidar-cli
```

scriptsを用意

```json:package.json
{
  "scripts": {
    "test:e2e": "playwright test",
    "test:e2e:watch": "SHELL=$(which bash) chokidar 'tests/**/*.spec.ts' -c 'npm run test:e2e -- --retries=0 {path}'"
  },

  ...
  ...
```

`SHELL=$(which bash)`を入れておかないと`throw new Error('$SHELL environment variable is not set.');`が起きるっぽい


```terminal
$ npm run test:e2e:watch
```

デフォルト設定としてこうしておけば実行中の動画が取れたりする。

```ts:playwright.config.ts
import { PlaywrightTestConfig } from "@playwright/test"
const config: PlaywrightTestConfig = {
  use: {
    slowMo: 50,

    // Context options
    viewport: { width: 1280, height: 720 },
    ignoreHTTPSErrors: true,

    // Artifacts
    screenshot: "only-on-failure",
    video: "on",
  },
}
export default config
```

# 参考

https://playwright.dev/docs/test-configuration#global-configuration

https://github.com/microsoft/playwright/issues/7035
Node.jsで文字列を圧縮 


Node.jsのビルドインモジュールを使って文字列を圧縮 （gzip）

https://nodejs.org/dist/latest-v14.x/docs/api/zlib.html

```javascript
const Buffer = require('buffer').Buffer;
const zlib = require('zlib');

/**
 * 圧縮
 */
function gzip(str){
    const content = encodeURIComponent(str) // エンコード
    const result = zlib.gzipSync(content)   // 圧縮
    const value = result.toString('base64') // Buffer => base64変換
    return value;
}
/**
 * 解凍
 */
function unzip(value){
    const buffer = Buffer.from(value, 'base64')              // base64 => Bufferに変換
    const result = zlib.unzipSync(buffer)                    // 復号化
    const str = decodeURIComponent(result).toString('utf-8') // デコード
    return str;
}

const str = `あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお`
const str1 = gzip(str);
const str2 = unzip(str1);

console.log(str)
console.log(str1)
console.log(str2)
```

圧縮前

> あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお

圧縮後
> H4sIAAAAAAAAA1N1NVa1MFS1MFKFMkxgDDMYwwLGcFQdVTyqmBqKATEK0v52AgAA

解凍

> あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお
gitの複数のブランチを一括で削除する

複数ブランチを一括削除する Tips はあったが、
grep の引数に複数の値を渡すのどうやるんだっけとなり調べたのでメモ。
`-e` オプションで書いてやるといいらしい

```bash
git branch | grep \
-e hoge_branch \
-e fuga_branch \
| xargs git branch -d ;
```

以下、grep のドキュメントから抜粋

```text
   Matching Control
       -e PATTERNS, --regexp=PATTERNS
              Use PATTERNS as the patterns.  If this option is used
              multiple times or is combined with the -f (--file) option,
              search for all patterns given.  This option can be used to
              protect a pattern beginning with “-”.
```

https://man7.org/linux/man-pages/man1/grep.1.html

参考にした記事：

https://qiita.com/satoshi03/items/c53aab17f3270477e33a
1.7(易) 因果関係と相関関係，独立性 

## 方針

確率変数XとYが無相関であるとは，

```math
E[XY]=E[X]E[Y]
```

が成り立つことを言い，一方確率変数XとYが独立であるとは

```math
P[XY]=P[X]P[Y]
```

が成り立つことをいう．本問では，確率変数が

- A: 確率cでA_1を．1-cでA_2を取る
- B: 確率bでB_1を，1-bでB_2を取る．

とされているため，独立性を用いるなどして連立方程式を解く．

## 答案
### 1.
薬の服用に関する確率変数をA,病気の治癒に関する確率変数をBとおく．今，AとBは独立であるから，

```math
P[A=A_1,B=B_1]=P[A=A_1]P[B=B_1]
```

などが成り立つので，

```math
\begin{align}
\begin{cases}
a&= bc\\
\frac{1}{9}&= (1-b)\\
\frac{4}{9}&= b(1-c)
\end{cases}
\end{align}
```

を連立して解くと，

```math
a=\frac{2}{9},\ b=\frac{2}{3},\ c=\frac{1}{3}
```

となる．

### 2.

```math
P[A=A_1] = P[A=A_1,B=B_1]+P[A=A_1,B=B_1]
```

などを用いて，

```math
\begin{align}
\begin{cases}
a+\frac{4}{9}=b\\
a+\frac{1}{9}=c\\
\frac{1}{9}+d=1-b\\
\frac{4}{9}+d=1-c
\end{cases}
\end{align}
```

これらを連立して解くと，

```math
a=\frac{4}{9}-d,\ b=\frac{8}{9}-d,\ c=\frac{5}{9}-d
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
Numpyインストール

Numpyをインストールしたときの備忘録です

#インストール方法
pipを使うかcondaを使うかで変わるので、その時の環境に応じて変える

##pipの場合
インストールのコマンド
```pip install numpy```
バージョンの確認
```pip list```

##condaの場合
インストールのコマンド
```conda install -c anaconda numpy```
バージョンの確認
```conda list```


#参考URL
[https://pypi.org/project/numpy/](https://pypi.org/project/numpy/)
[https://anaconda.org/anaconda/numpy](https://anaconda.org/anaconda/numpy)
[Rails]ランキング機能の順位を同率表示する

ここまでランキング機能に関する記事を2記事書いてきました

[[Rails]いろんなランキング表示(いいね、コメント、投稿数)](https://qiita.com/nakachan1994/items/ace3508d5192c58efdf1)
[[Rails]月間、週間、日別でランキング機能を実装(Time.current)](https://qiita.com/nakachan1994/items/682ae620bf3fa6687d5c)

上記の記事でも順位を表示する方法を紹介しているのですが、同率の場合でも順位が１位、２位となっていました。
たとえば、いいね数のランキングでいいね数が5のAさん、Bさん、いいね数が３のCさんがいたとします。
そのときの順位は1位Aさん、２位Bさん、３位Cさんとなってしまいます。

それを今回、１位Aさん、１位Bさん、３位Cさんと同率の場合は順位を同じにしていきます。

#開発環境

> ruby 2.6.3
> Rails 5.2.6

#前提

- 投稿サイトを想定
- ランキングの順位に応じて１位、２位などの順位を表示（同率の場合は同率で順位を表示）
- ranksコントローラーのrankアクションに処理を記述
- rank.html.erbでビューを表示

モデル名、変数名等は適宜、ご自身の開発環境に変換してお考えください。

user  ユーザー
post  投稿
like  いいね
comment  コメント

#まず結論から

まず、結論のコードを見せてそのあとに解説していきます。

```erb:views/ranks/rank.html.erb
        <!--同率順位表示-->
        <% last_like = 0 %>
        <% j = 1 %>
        <% @post_like_ranks.each.with_index(1) do |rank, i| %>
          <!--最初の値をlast_likeに保存-->
          <% if i == 1 %>
            <% last_like = rank.likes.count %>
          <% end %>
          <!--last_likeといいね数比べて同じなら同じ順位、違うなら次の順位表示-->
          <% if rank.likes.count != last_like %>
            <% j = i %>
            第<%= j %>位
            <p><%= rank.likes.count %>いいね</p>
            <% last_like = rank.likes.count %>
          <% else %>
            <% last_like = rank.likes.count %>
            第<%= j %>位
            <p><%= rank.likes.count %>いいね</p>
          <% end %>
        <% end %>
```

長々とコード書いてるので解説していきます。

#解説

基本的な考え方としては、last_likeという変数にいいねのカウント数を入れていき、last_likeといいねのカウント数を比べて、同じなら同じ順位を表示、違うなら次の順位を表示していく流れです。

なので処理としてはそんなに難しいことはせずに、if文で条件分岐しているだけなので安心してください。

では、コードを細かくみていきましょう！

```erb:解説
<!--last_likeを定義して0を代入-->
<% last_like = 0 %>
<!--jを定義して1を代入-->
<% j = 1 %>

<!--いいねの多い順に並べたものを配列でまわす-->
<% @post_like_ranks.each.with_index(1) do |rank, i| %>
:
<% end %>

<!--順位が1位のときlast_likeに値は入っていないため、１位のいいねのカウント数を代入-->
<% if i == 1 %>
  <% last_like = rank.likes.count %>
<% end %>

<!--rank.likes.countとlast_likeを比べて条件分岐-->
<!--値が一致しないとき-->
<% if rank.likes.count != last_like %>
  <!--値が一致しないということは次の順位を表示したいので-->
  <!--j　に i　を代入して表示-->
  <% j = i %>
  第<%= j %>位
  <p><%= rank.likes.count %>いいね</p>
  <!--値が一致していなのでlast_likeの値を更新-->
  <% last_like = rank.likes.count %>
<% else %>
  <!--last_likeといいねのカウント数が同じとき-->
  <!--値は同じですが今後も使うので、代入しておく-->
  <% last_like = rank.likes.count %>
  <!--jには前の順位と同じ値が入っているので、更新せずそのまま表示-->
  第<%= j %>位
  <p><%= rank.likes.count %>いいね</p>
<% end %>
```

#最後に

ひとつずつ見ていくとそこまで難しい記述ではなかったとは思うので、理解できていると思います。

今後も使う機会が多そうな処理なので、しっかりと理解してまた色んな場面で再現できるようにしておきましょう。
1.6(易) 条件付き確率の典型問題2

## 方針

「陽性反応が出る」という事象をA，「陰性反応が出る」という事象をA^cとし，「疾患がある」という事象をB，「疾患がない」という事象をB^cと置き，条件付き確率を計算する．

## 答案

「陽性反応が出る」という事象をA，「陰性反応が出る」という事象をA^cとし，「疾患がある」という事象をB，「疾患がない」という事象をB^cと置き，条件付き確率を計算する．今，問題文より

```math
P[A|B^c]=\frac{2}{10},\ P[A^c|B]=\frac{1}{10},\ P[B]=\frac{1}{10}
```

であるから，

```math
\begin{align}
P[B|A]&=\frac{P[A\cap B]}{P[A]}\\
&= \frac{P[A\cap B]}{P[A\cap B]+P[A\cap B^c]}\\
&= \frac{P[B]P[A|B]}{P[B]P[A|B]+P[B^c]P[A|B^c]}\\
&= \frac{P[B](1-P[A^c|B])}{P[B](1-P[A^c|B])+P[B^c]P[A|B^c]}\\
&= \frac{\frac{1}{10}(1-\frac{1}{10})}{\frac{1}{10}(1-\frac{1}{10})+\frac{2}{10}\frac{9}{10}}\\
&= \frac{1}{3}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
イイカンジの背景画像を見つけたので...

![スクリーンショット 2021-07-08 10.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263633/896bef35-9b94-dd04-2cc9-53aadb81dfbd.png)
![スクリーンショット 2021-07-08 11.32.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263633/79d3d04d-68a7-3a3b-6f1b-d579a2811fac.png)

こなさん、みんばんわ！
しばらくぶりにまたジジイが「ざっくり時計」ネタで投稿に来ましたよw
https://qiita.com/sigmoc/items/097292d800b6ca6a10ce
https://github.com/sigmoc/zackly_clock.git
背景が単色塗りつぶしじゃ、やっぱ殺風景でさびしーなーと思っていた今日この頃、イイカンジにジジイのノスタルジーを刺激する背景（壁紙）画像が、無料で配信されてるのを見かけたので、これを時刻表示の背景にしたらオシャレかも〜と、改造してみました。  
画像の引用元は、象印さんの[GARARY（ガラリー）](https://www.zojirushi.co.jp/life/garary/download/)
ここの花柄ポットの模様、イイよね〜。ライトモードには「花の舞」、ダークモードには「カトレア」を使わせていただいてます。  
JPEGの圧縮率をガッツリ上げて画質をだいぶ落としたモノを「あくまでひとつのサンプル」としてgithubのリポジトリに入れといたけど、もしご利用になる方がいらしたら、各自copyright的に大丈夫なモノをご用意くださいw　`zackly.html`ファイルと同じ階層に、`zackly_light_bg.jpg`(ライトモード用)、および`zackly_dark_bg.jpg`（ダークモード用）を置けば、それを背景に使用できます。
無断再配布だって怒られたら取り下げます。
Enjoy!
GitとGitHubを基本からまとめてみた【超入門】

## Gitで出来ること

①ファイルのバージョン管理
- 任意のタイミングでファイルの状態を記録

②以前の状態に戻せる
- 前のバージョンに直ぐに戻せる

③チームでスムーズに開発
- 複数人の共同編集は事故りやすく、思わぬ上書きを防止できる

## GitHubで出来ること(チーム開発で必須のスキル)

①コードの共有
- Gitで管理しているソースコードをチームや複数人で簡単に共有する

②コードビュー
- 複数人でコードの共有ができ、プルリクエストでチーム開発ができる。
- コードレビューができる。

③OSSに参加
※ OSS（オープンソースソフトウェア（Open Source Software））とは、ソースコードが公開されており、無償で誰でも自由に改変、再配布が可能なソフトウェアのこと。

## Gitの基本コマンドのまとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/dc52a1e9-89df-7728-dace-e06473c6d309.png)

## ローカルの基本操作①：初期化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/051dd806-630f-41f1-c20d-f4f8ca487bb7.png)
```
$ git init
```

Gitで変更内容を記録するために「git init」でリポジトリを作成する。
※ リポジトリとは変更を記録するためのデータベースのこと。

## ローカルの基本操作②：記録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/704d3612-095c-3af2-9033-c02825ed3711.png)

```
$ git add .
『.』はファイル名を指定。"."は全変更ファイル

$ git commit -m "コミットメッセージ"
コミットメッセージは、変更内容を記載
```
ワークツリーの内容をリポジトリにコミットする前にステージを挟む。
ステージは、Aの変更・Bの変更というように複数ファイルを変更したけど一部だけをコミットしたいときに使用する。

## ローカルの基本操作③：状況確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/53b1429c-5999-2a80-5510-3b8f05db15b1.png)

```
// リポジトリとワークツリーの差分をチェック
$ git diff 
// リポジトリとステージの差分をチェック
$ git commit diff -staged
// 変更ファイルを確認
$ git status
```
変更内容を確認するときは「diff」「status」の2つのコマンドを使用する。
基本的に変更内容を確認してから「add」「commit」で変更内容を記録する。

## ローカルの基本操作④：履歴の確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/716ae848-6614-d716-328f-c1a9965a393d.png)

```
$ git log
```
どんな変更を記録したのかを確認したいときには「git log」を使用する。

## ローカルの基本操作⑤：変更の取り消し

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/86be28af-8570-0ccc-2389-79da5d0c5462.png)

```
// ワークツリーの変更を取り消す
$ git restore <ファイル名>
// ステージに挙げた変更をワークツリーに戻す
$ git restore -staged <ファイル名>
```
変更を記録した後、元の状態に戻したいときには「restore」を使用する。


## 参考サイト
[【Git入門講座 合併版】この動画1本でGitとGitHubの基礎をゼロからマスター！【初心者向け】](https://www.youtube.com/watch?v=WHwuNP4kalU&t=1970s)
[3章 Git の仕組みと操作](https://terakoya.sejuku.net/programs/3/chapters/16)
[【Git入門】Gitの基本的な仕組み・コマンドを図解で徹底解説](https://terupro.net/git-basic-command/)
OVR grabbableでモノが動かせない場合

Unityで、OVR Grabbableを設定したのにモノが動かず、1時間ぐらい試行錯誤してしまったが、めちゃくちゃ単純な要因だったのでメモ。

# 要因
オブジェクトがStaticになっていた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34650/5426ccba-d875-d271-7960-d53249dca7e2.png)

# 対応
Staticを外すだけ^^；
Unity asset storeの素材をそのまま使う場合などは、デフォルトがStaticになってる場合があるようなのでご注意を。
1.5(易) 条件付き確率の典型問題

## 方針

「0を送信する」という事象をA，「1を送信する」という事象をA^cと置き，「0を受信する」という事象をB，「1を受信する」という事象をB^cと置き，条件付き確率を計算する．1.の結果を2.で利用する．

## 答案

「0を送信する」という事象をA，「1を送信する」という事象をA^cと置き，「0を受信する」という事象をB，「1を受信する」という事象をB^cと置く．今，問題文より

```math
P[A]=\frac{1}{3},\ P[A^c]=\frac{2}{3},\ P[B^c|A]=P[B|A^c]=\frac{1}{10}
```

であることが分かっている．

### 1.

```math
\begin{align}
P[B]&= P[A\cap B]+P[A^c\cap B]\\
&= P[A]P[B|A]+P[A^c]P[B|A^c]\\
&= \frac{1}{3}\frac{9}{10}+\frac{2}{3}\frac{1}{10}\\
&= \frac{11}{30}
\end{align}
```

### 2.

```math
\begin{align}
P[A^c|B]&= \frac{P[A\cap B^c]}{P[B]}\\
&= \frac{P[A^c]P[B|A^c]}{P[B]}\\
&= \frac{\frac{2}{3}\frac{1}{10}}{\frac{11}{30}}\\
&= \frac{2}{11}\\
P[A|B^c]&= \frac{P[A\cap B^c]}{P[B^c]}\\
&= \frac{P[A]P[B^c|A]]}{P[B^c]}\\
&= \frac{\frac{1}{3}\frac{1}{10}}{\frac{19}{30}}\\
&= \frac{1}{19}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
【Azure】 リソース "e-pass-pln" を更新できませんでした。を解決した！

学習中に以下のエラー(MissingSubscriptionRegistration)で躓いたので、解決した方法を残しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544790/6f245b47-27f2-ba61-c6e7-bbcf7194e4b6.png)


##原因

エラー文の中にある「microsoft.insights」というリソースプロバイダーが
登録されていないと記載されている。多分、これが原因みたいだ。


##解決方法

Azureポータルのホーム画面 → サブスクリプション 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544790/3948e397-5bf8-3cee-7432-18d2705ed822.png)


リソースプロバイダーを開いて「microsoft.insights」でフィルタして表示されるプロバイダー名の状態を確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544790/da262b19-e349-6e3c-a7ab-6a7211b72124.png)

「Registerd」になっていない場合、「登録」ボタンから登録をする。
2～3分で登録完了となり「Registerd」に変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544790/c56a28c9-e3f8-19a3-8a69-1737b6eedc2c.png)



##補足

リソースプロバイダーとは、Azureのリソースを操作したり管理するために必要なものみたいです。
初めから登録されているものもあれば、必要に応じて自動的に登録されるので、
ほとんど意識する場面はないとのことですが初めての人はわからないですね；；

##参考

https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/error-register-resource-provider

Azure難しい( ﾟДﾟ)
1on1をより満足度の高いものにするためには、カウンセリングではなくコーチングをしたら良いのではないか？

突然ですが、カウンセリングとコーチングの違いがわかりますか？

わたしは過去に受けてきた1on1で、満足度の高いものとそうでないものとの違いがここにあると感じました。

> <b>カウンセラー</b>
ある心理状態を引き起こしている理由をクライアントから引き出す

> <b>コーチ</b>
最後の最後まで「で、あなたはどうするの？」ときき続ける、まったく何の落としどころもなくクライアントに立ち向かっていく

> 引用：[新 コーチングが人を活かす](https://www.amazon.co.jp/dp/B089GMQX97/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

どちらも問題解消のために力になってはくれますが、 <b>終わった後に解消のための第一歩が確実に決まっている</b> かいないかが重要なのではないかと思います。

## 私の思う、満足度の低い1on1
「こういうことで悩んでいて…」と相談した時に「難しいよね…わかる」で終わってしまうものです。悩みに対して共感してもらえることで心理的には多少楽になるのですが、<b>本質的な問題解消にはなっておらず、1on1が終わった後にも同じ問題に悩み続けることになります。</b>問題をたくさん抱えているとその分<b>コンテキストスイッチが入り生産性が落ちる</b>ということを身を持って感じてきました。

## それを踏まえて、何を意識してメンターを行っているか
わたしは今年の３月からPMOという立場で <b>PMの生産性を向上する</b> というミッションを掲げて働いています。

とは言え社内でもこのようなポジションの人は他におらず、具体的に何をすればPMの生産性が向上するのか・何に困っているのかがわからなかったので、まずは1on1を通じて状況確認をすることから始めました。

メンターとして1on1をすること自体初めてでしたが、やるからには満足度の高いものにしたいという気持ちがあったので、終わった後に必ず <b>次やるべきことが明確になっている状態</b> を目指して行いました。

## やり取りの例
メンティー（受ける側）「他部署との認識齟齬が発生しているから、もっとコミュニケーションを取ったほうがいいと思っている」

メンター「コミュニケーションを取るために具体的に何をしたら良いだろう？」
メンティー「主要メンバーを集めて定期的に会議をするとか」

メンター「主要メンバーって誰だろう？」
メンティー「AさんBさん、それとCさんかな」

メンター「そのメンバーが都合の良い時間はどこだろう？」
メンティー「毎週水曜の15時」

メンター「定例のゴールはなんだろう？」
メンティー「〇〇が問題だからまずはそれを解消したい」

メンター「そのためにどういうアジェンダでやっていくのが良さそう？」
メンティー「まずはゴールから共有して、次に◯◯についてを話そうかな」

メンター「じゃあもうカレンダーに予定入れちゃおう、メモ欄にアジェンダも記載しておこう！」

このようになるべく具体的にアクションを決めることで、認識齟齬の問題に関しては <b>一旦頭から切り離すことができる</b> ことが重要だと思います 。アクションが決まらず、「後でコミュニケーション施策をどうやるか考えないと…」で止まっていると、1on1が終わった後もモヤモヤと悩み続けてしまい <b>他の業務に支障をきたしたり、そのまま忘れてしまい何も改善されないこと</b> が続いてしまいます。

## まとめ
結果、メンティーからの評判が良く、最初は２人だけだったものの「自分も受けたい」と言ってくれる人が現れ、今となってはPMだけに留まらずたくさんのマネージャー陣やエンジニアと1on1をするようになりました。

カウンセリングをすることでメンティーに考えを整理してもらうことでも効果はあると思いますが、<b>第一歩をどう踏み出すのか</b> まで一緒に考えられると、より満足度の高い1on1になるのではないかと思います。
unityでbuttonを複数instantiateし配置する場合の注意点

UnityでVRソフトを作る際、Buttonをスクリプトから生成していい感じに配置しようとした際にちょっとしたハマりがあったのでメモ。

# やりたいこと
* button prefabをスクリプトで複数生成
* 等間隔にいい感じに配置

# はまったこと
変な位置に設定される（参考記事のように、SetParentにworldPositionStays=falseを設定したが、謎の位置に配置される）

# 要因
位置設定は「SetParentの前」に行う必要があった

# NGコード
setparentした後にpositionを設定すると、謎の位置に配置される（理由は不明）
```
        for(int i = 0; i < mission_list.Count; i++)
        {
            GameObject MissionButton = Instantiate(m_menu_mission_button_prefab) as GameObject;]
            MissionButton.transform.SetParent(m_canvas_menu.transform, false); 

            //ミッションボタンの位置を設定。iの値により、横・縦位置を調整
            Vector3 button_width = new Vector3(m_menu_width, 0, 0) * (i % m_menu_number_of_line);
            Vector3 button_height = new Vector3(0, m_menu_height, 0) * Mathf.Floor(i / m_menu_number_of_line);
            MissionButton.transform.position = m_menu_first_position + button_width + button_height;
        }```


# OKコード
setparent前に位置を設定すると、その位置情報がそのままローカル座標になってうまく配置できた
```
        for(int i = 0; i < mission_list.Count; i++)
        {
            GameObject MissionButton = Instantiate(m_menu_mission_button_prefab) as GameObject;]
            
            //ミッションボタンの位置を設定。iの値により、横・縦位置を調整
            Vector3 button_width = new Vector3(m_menu_width, 0, 0) * (i % m_menu_number_of_line);
            Vector3 button_height = new Vector3(0, m_menu_height, 0) * Mathf.Floor(i / m_menu_number_of_line);
            MissionButton.transform.position = m_menu_first_position + button_width + button_height;

            MissionButton.transform.SetParent(m_canvas_menu.transform, false); 
        }```


# 参考記事
https://kido0617.github.io/unity/2014-12-07-ugui-dynamically-create-button/
ターミナル用のインターアクティブなミュージックラジオplayerをBash Scriptsで作ってみた話

# Terminal Radio (TERA)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30943/18689272-87b0-f482-e2d9-0a6157ece5ad.png)

# Introduction

アマゾンミュージックはもう聞き飽きた。Youtubeはブラウザーを開けるのが面倒臭い。Spottifyは持ってない。ということでterminal用のmusic radio playerをBash Scriptで作りましたので皆さんに使って欲しいという話です。

[こちらがrepoです。](https://github.com/shinokada/tera)

# Features

-  [Radio Browser API](https://de1.api.radio-browser.info/)を使って27780+のradio stationsが検索できます.
- [MPV](https://mpv.io/)をmedia playerとして使ってます。
- 自分のリストがCRUDできます。
- tag, name, language, country code, stateによってサーチができます。
- radio station の追加/削除ができます。
- I feel lucky menuがあります。
- Gistにuploadできます.

# Requirements

- mpv はオープンソースのメディアプレーヤーです。
- jq は JSON 用のプロセッサーです。
- gh は GitHub CLIです。

# Installation

[Awesome Package Manager](https://qiita.com/shinichi_okada/items/835625959a00a64d638d)でインストール。

```
awesome install shinokada/tera
```

HomeBrew/LinuxBrewを使っている人は。

```
brew tap shinokada/tera
brew install tera
```

# Usage

`tera`と叩けばメニューが出るのでそれに従って操作してください。

```
tera
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30943/f3933c57-dde8-f653-5795-a9391c52edab.png)

# Play from my list

Sampleリストがついています。

# Search Menu

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30943/8ee6cf33-5136-7d3f-b0e2-9d7cc6b581ab.png)

サーチはtag, name, language, country code, state, advanced searchでできます。

サーチをして聴き終わって気に入ったらリストにも追加できます。

[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)はISO 3100-1 alpha-2に準拠してます。

Advanced search以外は全て単体でsearchします。
Advanced searchは次のように複数でsearchしてください。

```
-d tag=rock -d language=english -d countrycode=uk
```

# List CRUD

自分用のリストを作って、読んで、Updateして、削除できます。

# Delete a radio station

Radio stationをリストから選んで削除できます。

# I feel lucky

Key wordを入れたらランダムにRadio stationを探しPlayします。

# Gist

自分のリストを全部GistにUploadします。

使ってみて何かありましたら[GitHub isssue](https://github.com/shinokada/tera/issues)にご連絡を。
Unityのonclick.addlistenerではまった場合の対処法

スクリプトで以下のような処理を実装しようとしたところ、onclick.addlistenerではまった。

# やりたいこと（実施したい処理）
* ボタンprefabをinstantiate
* onclick.addlistenerを設定

# 発生した課題
「ArgumentException: method arguments are incompatible」が常時発生

# 原因
 ボタンprefabのonclickに最初から不要なaddlistenerが設定されていた（以下のような状況で、一見未設定にみえたが、実は未設定のlistenerが存在している状態だった）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34650/4d63d65a-cfd9-55fc-dfa3-dec4133001d7.png)


# 対応
Removeして以下のような状態にしたら解決
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34650/20794c78-548c-f8dc-ac57-aa33cfc1e6a3.png)
GitHub Actions での C++ Code Scanning

---
皆さんごきげんよう。本記事は、2021 年 7 月 7 日（米国時間）ポストされた **[Code Scanning C++ with GitHub Actions](https://devblogs.microsoft.com/cppblog/code-scanning-with-github-actions/)** の速報的なアレというか意訳のようななにかとなります。内容については下記が原文で、正となります。

https://devblogs.microsoft.com/cppblog/code-scanning-with-github-actions/

------------------

昨年、GitHub は [Code Scanning](https://github.blog/jp/2020-10-06-code-scanning-is-now-available/) をリリースしました。これにより、開発者はセキュリティ チェックの仕組みを CI/CD 環境や開発ワークフローに組み込むことができます。この記事では、GitHub Actions で Code Scanning のバックエンドの解析エンジンを利用するやり方について紹介します。


https://docs.github.com/ja/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning

https://github.blog/jp/2020-10-06-code-scanning-is-now-available/

#CodeQL とは

https://codeql.github.com/docs/codeql-overview/

[CodeQL](https://codeql.github.com/docs/codeql-overview/) は、コードベースから生成されたデータベースに対してクエリを実行することで、セキュリティ チェックを自動化する解析エンジンです。CodeQL データベースは、ビルド プロセス中に作成され、ソースコードを表形式で表現します。既定では、Code Scanning は GitHub の研究者やコミュニティが作成した標準的な CodeQL クエリを実行しますが、独自のカスタムクエリを作成して利用することもできます。

既定のセットに含まれるクエリは以下の通りです。

* Pointer Overflow Check 
* Potentially overflowing call to snprintf
* Uncontrolled format string

など。

> uikou 注 : CodeQL は、ソースコードにおいて、セキュリティ脆弱性を分析し、発見してくれます。もともとは、アメリカの Semmle 社が開発していたものです。なお、Semmle 社は 2019 年 9 月に GitHub が買収しました。Code Scanning は、いわゆる静的アプリケーションセキュリティテスト (SAST) 手法を実現するために、GitHub のワークフローの一部として実装できる仕組みです。

![sec](https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2021/06/Capture.jpg)

#GitHub Actions での CodeQL 設定
Code Scanning (with CodeQL) は、Public リポジトリであれば無料で利用可能です。GitHub Enterprise では、GitHub Advanced Security の一部として提供されています。
ここでは、4 クリックであらびっくり、簡単にセットアップする手順を紹介します。以下に GIF ファイルもありますので、手順を見てみてくださいね。

![sec2](https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2021/06/codeqlsetup.gif)

これで対応 done です。
既定の CodeQL 解析ワークフローは、Default の branch に対して、Push したり、Pull Request を上げたりするたびに、コード解析をしてくれるように構成されています。つまり、新しいファイルを直接 main branch に commit したあと、コード解析が自動的に走ってくれるという事です。

コード解析のログは、`Actions` タブで確認できます。また、アラートは `Security` タブで表示、管理することができます。

#アラートのベースラインを管理する
時に、とりわけ大規模なレガシー コードベースでは、圧倒的な数のアラートが出力されることがあります。そのため、CodeQL では Pull Request に含まれる新規、または修正されたアラートのみを表示するようになっています。既存のアラートを管理したい場合は、`Security` タブの　`Code scanning aleats` セクションから対応します。

![Sec3](https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2021/06/Capture2-scaled.jpg)

##*Dismiss* と *Delete* の違いは重要です
**この二つの違いを理解することは、とっても重要です。**
特に重要なポイントを例にあげると、アラートを解除する (Dismissing) と、（次にスキャンされても）同じコードがアラートを再生成することはないが、アラートを削除する (Deleting) と、同じコードが次にスキャンされたとき、また同じアラートが生成されるという動作の違いがあるという事です。

アラートを一括して解除したい（bulk-dismiss) 場合は、アラートのサマリから行うことができます。（解除したいアラートのセットにリストをフィルタリングした後に行いましょう）

#フィードバックおまちしてます
今回の記事は、CI/CD 環境における Code Scanning のほんのさわりです。基本を理解した後は、ご自身でオリジナルの CodeQL クエリを作成してみたり、解析頻度を調整したりしてみてください。

GitHub Actions での Code Scanning、是非おためしくださいね！

----------------

以上、[**Nick**](https://devblogs.microsoft.com/cppblog/author/uhlenhuthn/) さんからでした。

![Nick](https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2019/01/Nick-Uhlenhuth-Headshot-e15107735971951-150x150.jpg)

それではみなさんごきげんよう。
Gitのコマンドで日本語名ファイル名を化けないようにする

当記事は、Gitのコマンド操作で日本語ファイル名表示を行う設定のメモです。
下記のコマンドを実行するだけで、以降日本語ファイル名が化けずにGitコマンドを操作できます。

<pre>git config --global core.quotepath false
</pre>
Numpy array のスライスで気づいたこと

Numpy array のスライスで気づいたことをメモ

例えば、
shapeが(X,4) （X行４列）のarr_1があったとして、

arr_1[:,0:5]

と

arr_1

は同じ配列であるということです。

これが正しいことは引き算してみると分かります。
arr_2 = arr_1[:,0:5]-arr_1
print(arr_2)
print(arr_2.max(axis = 0))
CentOS カーネルパッチ適用の仕方(2/2)

前回の続き
[「CentOS カーネルパッチ適用の仕方(1/2)」](https://qiita.com/start-action/items/17ccf5c29f6bfafc2f0b)

今回適用するパッチの修正は既にLinuxツリーのgitにマージされており、
commit ID：ddea368c78ff9acf45261a7c82635b98e9c1fcd6
修正ソース：drivers/net/bonding/bond_main.c 　
と分かっている時の例です。

###1. パッチを作成する

Linuxカーネルのgitレポジトリをローカルマシンにcloneにします。

```
# git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
```


clone後、commit IDから今回のパッチ内容が正しいか確認します。
git show [commit ID]で、修正前後の内容が見れます。

```
# cd linux
# git show ddea368c78ff9acf45261a7c82635b98e9c1fcd6
```

問題なければ、パッチを作成します。
パッチファイル名は自動生成されますので、必要に応じてリネームしてください。

```
# git format-patch -1 ddea368c78ff9acf45261a7c82635b98e9c1fcd6
```

###2. パッチを適用する

作成したパッチを使って、パッチ適用とビルドを一緒に実施します。
作成したパッチは `/root/rpmbuild/SOURCES` 配下に置きます。

今回のバッチをRPMのSPECファイルに追加します。

```
# cd /root/rpmbuild/SPECS
vi kernel.spec

（略）

Patch needed for building this packages
Patch999998: 0001.patch   ★追加
empty final patch to facilitate testing of kernerl patches
Patch999999: linux-kernel-test.patch

（略）

ApplyOptionalPatch debrand-rh-i686-cpu.patch
ApplyOptionalPatch 0001.path    ★追加

```

もう一度ビルドをしてみる。

```
cd /root/rpmbuild/SPECS
rpmbuild -bb kernel.spec 2>&1 │ tee build.log
```
2>&1 │ tee build.log を付けることでビルドログが出るため、
パッチが適用されているか、ログで確認をする。

ビルド完了後、`/root/rpmbuild/RPMS/RPMS/に作られたrpmをインストールして、reboot。
これでカーネルパッチの適用は完了。

```
cd /root/rpmbuild/RPMS/x86̠ 64
rpm -ivh xxx.rpm
```
[UE4] Widgetとリソースを切り離す方法

#1. 課題
　本記事では「Widgetとリソースを切り離す方法」を説明しており、この記事を読むと"Widgetを使用してUIを構築する際の問題とその解消方法"が理解できるようになります。
　Widgetを使用してUIを構築する際のありがちな問題点として以下のようなものがあります。

**① UIを表示する瞬間にヒッチ(スパイク)が発生する**
**② UIを表示する際に長いロードがある**
**③ UIを使用しているシーンのメモリ使用量が多い、リソースが開放されない**

これらの問題がある場合は本対策が有用なことがあります。

#2. 解説
　対策を記載する前にこれらの原因を把握するためにここで解説します。わかりやすくするために以下に例で示します。

まず①、②に関しては同じ事が原因のケースが多いです。例えば、以下のように1つのWidgetに1つのImage(Texture)を配置している状況があるとします。
![2021-07-07_11h56_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/285852bd-fc01-ff71-dd37-d5a400a1652d.png)
この場合はDesigner上に配置したリソースとは**ハードリファレンス(強い参照)**を持つことになります。そのため大量の表示物を一度に表示しようとする場合は、初回はリソースのロードでヒッチ/スパイクが発生する可能性があります。表示したいリソースを自動的に引っ張ってきてロード出来るという便利な側面もありますが、逆に集中するとロード時間が長くなる事もあるので注意が必要です。
![2021-07-07_11h57_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/ab23a838-33f5-0c9b-08f6-fe533d0ec2df.png)

次に「このWidgetをある一定の時間だけ表示したい」としましょう。おそらく「このWidgetを子Widgetとして親Widgetから表示するタイミングを制御すること」を想像するかもしれません。具体例として、親Widgetから必要なタイミングで生成する例を以下に挙げてみました。
![2021-07-07_12h06_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/9fa07a9d-e30c-4bb0-c91a-cba0671e55c9.png)

このようなケースにおいて親Widgetと子Widgetとリソースの関連性は以下のようになります。
![2021-07-07_12h15_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/fd1df1ca-e2ee-c08c-bedd-308b92c64f1e.png)
図を見るとわかるようにいずれもハードリファレンスとなっています。この時点で想像つくかもしれませんが、親Widget(WB_Main)がロードされた時点で子Widget(WB_Image)も、そのリソースもロードが発生することになります。そのため、表示していないにもかかわらず長いロードが発生している、ということも起きている可能性があります。これは最初にすべてのリソースをロードしているため、子Widget(WB_Image)を表示する際にはロード時間が無いというメリットもありますが、親Widgetのロード時にロード時間が長くなることもあります。

③についてもこれに関連していますが、使い終わって削除したはずの子Widgetがまだメモリ上に残っているという事が発生します。RemoveFromParentでWidgetを削除した後にGCを実行したとしても、ハードリファレンスされたWidgetがある場合はまだ再利用される可能性があるため（オブジェクトが完全に切り離されていない状態）GCの対象とはなりません。これはWidget(Slate)の既定動作であり、親Widgetが完全に削除されたり、OpenLevelなどによるシーンの移動が発生するまではリソースは開放されません。

#3. 対策
　これらの問題に対する方法として、完全なレイアウト配置を持たない（動的生成が可能な）Widgetはソフトリファレンスを使用して動的に生成することが挙げられます。以下の例は、上記の親Widgetと子Widgetを切り離すために変更した、親Widgetの実装です。ソフトオブジェクトリファレンス、ソフトクラスリファレンスを使用して強い参照を持たないようにしています。
![2021-07-07_12h11_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/db71857c-8730-49d1-0b26-3281acfbb3cd.png)
このようにすることで、リファレンスビュワー上も以下のような表示となり、子Widgetとはソフトリファレンス（弱い参照）となっていることがわかります。
![2021-07-07_12h14_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/34ad4231-944a-4f79-c411-7d7d13b05d75.png)

このようにすることで親Widgetをロードした子Widgetのロード＋子Widgetのリソースのロードが発生しなくなるので、ロード時間が短くなりスパイクを回避しやすくなります（その代わり子Widgetを使用する際には初回のロードがあります）。これで①や②の問題には対処することができます。

またこのように子Widgetを分離することによって親Widgetとのリファレンスが無くなりGCを適用することができるようになります。上記のノード中の最後にCollect Garbageを実行していますが、この実行によって即時で子Widgetとそのリソースが削除されて③の問題も対処できるようになります。

リファレンスはUIを担当する人もこの部分を理解しておくと、Widgetを実装する際に手戻りが少なくなったり、リソースを適切にコントロールできるようになるので是非おぼえておきましょう。

#4. その他
　上記を確認する上で役に立つコンソールコマンドは以下の通りです。

・現在ロード/生成済みのWidget一覧の表示

```
obj list Class=WidgetBlueprint
```

・現在ロード/生成済みのTexture一覧の表示

```
obj list class=Texture
```

・現在生成されたWidgetの参照元表示

```
obj refs Name=[WidgetName]
例：obj refs Name=WB_Main
```
[UE4] 複数のOnlineSubsystemを併用する

#1. 概要
　複数のOnlineSubsystemを併用・切り替えて利用することができます。例えば特定のプラットフォームサービスを使用しつつDedicated Serverで接続したいようなケースなどが１つの例として挙げられます。以下の図はもう少し分かりやすくしたものですが、例えばOSSSteamの一部のサービスとOSSNullの一部のサービスを併用したいケースでは以下のような構成になります。それぞれのOSSにはインタフェースを利用してアクセスするだけです。

![2021-07-07_11h35_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/d53c9f41-bc71-3f54-e048-05d801717988.png)

#2. 準備
　必要な設定は併用したいプラットフォームのOnlineSubsystemサービスを有効にするだけです。Pluginsから併用しようとするプラグインをすべて有効にしておきます。有効にするとゲームの起動直後に各OnlineSubsystemのモジュールを起動してオブジェクトを生成するようになります。
![2021-07-07_14h26_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/f809e266-1689-2d7d-5257-c917350e8d8c.png)
　また、必要があればEngine.ini (DefaultEngine.iniまたはプラットフォームのEngine.ini)の"DefaultPlatformService"を設定したいプラットフォームサービスに変更してください。基本的にはプラットフォームで使用するサービス（AndoridであればGoogle, WindowsであればSteam）に設定されています。

```:DefaultEngine.ini
[OnlineSubsystem]
DefaultPlatformService=Null
```

#3. 利用方法​

OnlineSubSystemは

```
DefaultPlatformService
```
で登録されたものを利用するようになっており、

```
IOnlineSubsystem::Get();
```

でSubsystemへアクセスした際に利用されるものがこれに該当します。
複数のOSSを有効にしている場合は、

```
IOnlineSubsystem::Get(OSSName);
```

のようにOSSを直接指定して利用できるのでSubSystemを切り替えてアクセスすることができます。 

```
IOnlineSubsystem::Get(NULL_SUBSYSTEM);
IOnlineSubsystem::Get(EOS_SUBSYSTEM);
```

のような指定でNullSubsustemとEOSSubsystemを参照できます。DefaultPlatformは.iniで指定された**DefaultPlatformService**を参照するだけなので、起動時に設定するのみとなっています。そのため、プラットフォームを切り替えるというよりは、必要な時にプラットフォームサービスを指定するといった利用方法となります。プラットフォームの名称はOnlineSubsystemNames.hを参照してください。

​例えばセッションの作成したりマッチメイキングをするにしても、まずはサブシステムを取得する必要があるので以下のようにサブシステムを取得します。

```
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
```

この方法で取得できるのはデフォルトプラットフォームのサブシステムなので、明示的にOSSNameを指定して取得するだけです。

```
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(EOS_SUBSYSTEM);
```