OmniAICreator/Qiita-1.07M huggingface dataset:
linux コマンド　参考サイト

#LINUX コマンド　　参考サイト

###最初に確認してみるサイト（基本）

https://qiita.com/arene-calix/items/41d8d4ba572f1d652727

###移動

https://eng-entrance.com/linux-command-cd

###削除

https://uxmilk.jp/8318

###rm -rf / (OS毎全部削除)等を避けるための set -eu

https://qiita.com/youcune/items/fcfb4ad3d7c1edf9dc96

###リモート・ローカル間でファイル転送

https://uxmilk.jp/50946

###ファイルの内容を表示する

https://atmarkit.itmedia.co.jp/ait/articles/1602/25/news034.html

###構成確認

https://atmarkit.itmedia.co.jp/ait/articles/1802/01/news025.html

Mac ターミナル標準のzsh環境はtreeコマンドが標準ではないのでインストールする

https://dot-blog.jp/news/mac-zsh-tree/
【Laravel】tinkerコマンド1行で目的のモデル情報を出力する小技

## ある日、こんなツイートを見つけた…

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Laravel productivity tip! Add this little function to your bash profile to quickly execute anything with the Tinker command and get the results instantly. <a href="https://t.co/qIB9pQCTWt">pic.twitter.com/qIB9pQCTWt</a></p>&mdash; Philo Hermans (@Philo01) <a href="https://twitter.com/Philo01/status/1449386062959284224?ref_src=twsrc%5Etfw">October 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 1行のコマンドでtinkerが使えるだと…！？

**`tinker 関数を bash プロファイルに追加し、コマンド実行すれば、結果を即座に取得できる！`** という旨の内容でした。ツイートの添付画像を見ると、とても分かりやすい内容で便利そうだったので自分でもやってみました。

- PC環境
 - Windows 10 pro
 - VSCode
 - Git Bash

### 1, ホームディレクトリに `.bash_profile` ファイルを作成

Git Bash 環境なので、ホームディレクトリに `.bash_profile` ファイルがあれば自動的にそのファイルを読み込んでくれます。ファイル内に関数などを定義していればそのまま使えちゃいます。ちなみに、 **Windows 10 のホームディレクトリは `C:\Users\ユーザー名` となっています。（「プロジェクトルート」と混合しないように注意）**

### 2, 作成した `.bash_profile` ファイルに関数を定義

コマンド `tinker` を利用できるように、関数を定義して保存します。これで、VSCode を立ち上げて Git Bash ターミナルを使用すると `tinker` コマンドが使えるようになります。

```bash
function tinker()
{
  if [ -z "$1" ]
    then
      php artisan tinker
    else
      php artisan tinker --execute="dd($1);"
  fi
}
```

### 3, Git Bash ターミナルからコマンドを打つ

VSCode を立ち上げて、ターミナルを Git Bash に設定しましょう。そして、Laravel のプロジェクトルートに移動して、以下のコマンドを入力します。

```
$ tinker 'User::first()'
```

予め、Userモデル情報が保存してある場合は、Userモデルの情報がターミナル上に出力されると思います。このように、1行だけで目的のモデル情報を簡単に取得することができました。

`insertした内容を手軽に確認したい`と思ったら、この方法を試してみるのも良いかもしれません。
Seurat チートシート

シングルセルシーケンスでよく使われるSeuratというツールのチートシートです。随時追加していきます。
Counts = 疎行列
object = seurat object

| やりたいこと | Command | 
|:-:|:-:|
|オブジェクトの中身を見る|str(object)|
|Cellrangerのhdf5(.h5)ファイルから疎行列（dgCMatrix）を作る|counts <- Read10x_h5(file)|   
|疎行列（dgCMatrix）からseurat objectに変換|object <- CreateSeuratObject(counts, project = "SeuratProject", assay = "RNA")|   
|cellbarcodeを取得|colnames(counts)|   
|遺伝子を取得|rownames(counts)| 
|metadataを取得|object[[]], もしくは object@meta.data|
|UMAPプロットを表示|DimPlot(object, group.by="色分けをする種類", split.by="別々に散布図を表示するとき", label=TRUE)+ ggtitle("自動でのCelltyping")|
|遺伝子名（feature名)を表示|object@assays$RNA@counts@Dimnames[[1]]|
|特定のクラスターのみ取ってくる|data2 <- subset(data, subset= seurat_clusters == 6 &#124; seurat_clusters ==12)|
|特定のクラスターを除外|data2 <- subset(data, subset= seurat_clusters != 6 & seurat_clusters !=12)|
|特定のサンプルごとにわける|object_list <- plitObject(ifnb, split.by = "stim")|
|特定の遺伝子リスト（genelist）が遺伝子に含まれていないものを抽出（意味わからん？）|setdiff(genelist, object@assays$RNA@counts@Dimnames[[1]])|
|発現量が変動している遺伝子を計算|まずはどれを基準にグルーピングするかを決める。Idents(object) <- "celltype.stim"<br>FindAllMarkers(object) -> markers|


for (i in data_list){
    i_ <- PercentageFeatureSet(i, pattern = "^MT-", col.name = "percent.mt")
data_list2 <- append(data_list2, i_)
    }
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
FindAllMarkers(new) -> markers
IBM Watson Language Translator を使用して翻訳させてみた

## 初めに

この記事では、IBM Watson 「Language Translator」サービスを使用して、実際に翻訳させてみた記事になります。プログラミング言語はPythonを使用しました。
Goole翻訳やDeepL翻訳等の無料で使用できる翻訳サービスもありますが、5,000文字に制限されます。
Watson Language Translatorなら、ライトプラン（無料プラン）を使用すると、月間1,000,000文字の制限がありますが、1回あたり5,000文字の制限は無く使用できます。


## 手順

### 手順1. Watson Speech to Text インスタンスの作成

#### 1. IBM Cloud アカウントの作成
IBM Cloudのアカウントが無い場合は、アカウントを作成します。

1-1.[https://cloud.ibm.com](https://cloud.ibm.com) にブラウザでアクセスします。

1-2.「アカウントの作成」のリンクをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/5712f555-315a-7846-24b1-40aac5c3d970.png)

1-3. アカウント作成画面になるので、画面の指示に従い、アカウントを作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/2b49f8b6-1add-2df8-a64c-b2191d12353d.png)

#### 2. Watson Speech to Text インスタンスの作成

2-1. IBM Cloud の Webコンソールから、「カタログ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/5a204e9b-7d33-eda6-0588-885e659af6c7.png)

2-2. 検索欄に、「language translator」と入力すると、候補がでてくるので、「Language Translator」を選択します。
![2022-01-25_14h28_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/8bb43386-44cd-9043-81cd-ce9533dac08b.png)


2-3. 料金プランは「ライト」を選択。使用条件の同意にチェックをつけ、「作成」ボタンをクリックします。
![2022-01-25_14h30_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/4d9fac94-572d-8d0c-9897-3ede721e7fd5.png)


2-4. インスタンスが作成されたら、「サービス資格情報」をクリックし、「apiKey」と「url」の情報を控えてください。コードを記載するときに必要になります。
![2022-01-25_14h32_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/6143f1cf-e775-b1eb-464c-7002eec6880b.png)

### 手順3. Watson SDK の導入

3-1. 以下のpipコマンドで「ibm-watson」インストールします。

```
pip install ibm-watson
```

### 手順4．コーディングと実行

4-1. 以下のようなコードを記載します。
※{APIKey}、{url}は、手順2-4で控えた値に置き換えてください。

``` translate.py
import json
import sys
from ibm_watson import LanguageTranslatorV3
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

with open(sys.argv[1]) as f:
    text = f.read()

authenticator = IAMAuthenticator(
    '{APIKey}')
language_translator = LanguageTranslatorV3(
    version='2018-05-01',
    authenticator=authenticator
)

language_translator.set_service_url(
    '{url}')

result = language_translator.translate(
    text=text,
    model_id='ja-en').get_result()    # model_idを'en-ja'にすれば、日本語から英語の翻訳になります。
print(result['translations'][0]['translation'])
```

4-2. 翻訳したいテキストファイルのパスを引数にして、記載したプログラムを実行します。翻訳結果が表示されます。

```
python translate.py {fille_path}
```

[実行例]
・サンプルテキスト

``` sample.txt
IBM Watson を使用して、日本語を英語に翻訳してみた。
ライトプランを使えば、無料でお試しできるのがうれしい。
6000文字の文書でもＯＫでした。
```

・実行結果

```
python translate.py sample.txt

I tried to translate the Japanese into English using IBM Watson.
I'm glad to use a light plan to try it free of charge.
It was OK in the 6000 character document.
```
pythonでディレクトリが存在しているかどうかをチェックする

pythonでディレクトリが存在しているかどうかをチェックするには`os.path.exists()`を使う、
ディレクトリを作成するには`os.makedirs()`を使う

```python:test.py
import os

checkdir = './testdir'
if os.path.exists(checkdir) == False:
    print("{} not exists".format(checkdir))
    print("{} create path".format(checkdir))
    os.makedirs(checkdir)
else:
    print("{} exists".format(checkdir))
```

実行する

```
$ python test.py 
./testdir not exists
./testdir create path
$ python test.py 
./testdir exists
$ ls testdir/
```

# 参考
https://docs.python.org/3/library/os.html
[Flutter] ビルド時のエラーの解決策 ( No matching client found for package name)

flutterで、androidのビルド時に下記エラーがでて、詰まったので共有です。

## エラー文
```terminal
Execution failed for task ':app:processDebugGoogleServices'.
> No matching client found for package name 'com.xx.xx'
```

## 解決策
google-services.jsonのpackage_nameとbuild.gradleのapplicationIdの２つを一致させる必要がありました。

``` android/app/google-services.json
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "xxxxxxxxxxx",
        "android_client_info": {
          "package_name": "com.xx.xx" //ここ
        }
      },
```



```android/app/build.gradle

    defaultConfig {
        applicationId "com.xx.xx" //ここ
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.2.2"
        multiDexEnabled true
    }
```

### 参考
https://stackoverflow.com/questions/34990479/no-matching-client-found-for-package-name-google-analytics-multiple-productf

# 最後に
私は現在、[株式会社ダイアログ](https://www.dialog-inc.com/)という物流×ITの会社に勤務しております。
現在、エンジニアを募集していて、カジュアル面談も実施しているのでお気軽にご連絡ください！

https://www.wantedly.com/companies/company_3244501/projects
【抄訳】GitHub Actions が簡単に使えるようになりました！ 

みなさんごきげんよう。Microsoft App Innovation チームです。今回は 12 月 17 日に投稿された The GitHub Blog より、「GitHub Actions just got easier!」の抄訳をお届けします。

https://github.blog/2021-12-17-getting-started-with-github-actions-just-got-easier/?Dev_QT=PET3035062

#GitHub Actions が簡単に使えるようになりました！

GitHub Actions の「新しいワークフロー」エクスペリエンスが改善されました。

リポジトリの Actions タブでアクション ワークフローを作成する際に、リポジトリ コンテンツの分析に基づいてワークフローが推奨されます。また、検索とフィルターも追加され、独自の要件に合った適切なワークフローを見つけやすくしています。 

#仕組み

ワークフローの推奨事項は、プログラミング言語、ビルド ツール、フレームワーク、パッケージ マネージャーなどの要素を検出するリポジトリ分析に基づいています。リポジトリにコンテナー化された Node.js アプリケーションが含まれている場合、リポジトリ分析ではコンテナーとノード関連のワークフローの両方が優先されます。

また、推奨事項を Deployment カテゴリに拡張しました。リポジトリに Dockerfile が含まれている場合、これらのコンテナーをビルドしてコンテナー互換のクラウド サービスにデプロイするワークフローを提案します。これによって、クラウド パートナーは各サービスのワークフローを提供し、リポジトリ コードで使用される言語とフレームワークに基づいて、エンド ユーザーに適切なワークフローを推奨できます。

さらに、カテゴリ別にフィルター処理する機能と、アクション ワークフローのカタログ上の検索機能を追加し、要件に合った適切なワークフローをすばやくに見つけられるようにしました。 

#はじめ方 

- これらの機能は、現在のすべての GitHub.com と GitHub エンタープライズ クラウド組織で利用できます。
- リポジトリの Actions タブで、**新しいワークフロー（New Workflow）**を選択します。
- 改善された推奨事項、検索、およびフィルター機能を使用して、関連するテンプレートを検索します。

#Actions ワークフローの使用に関する新機能 

GitHub には、リポジトリ内のコードに基づいて推奨されるワークフローのカタログがあります。GitHub アクション ワークフローの詳細については、ドキュメントを参照してください。

[Quickstart for GitHub Actions（英語）](https://docs.github.com/ja/actions/quickstart?Dev_QT=PET3035062) 

#最後に 

Microsoft ドキュメント「Azure 向けの GitHub Actions の概要」も合わせてご確認ください。 

https://docs.microsoft.com/ja-jp/azure/developer/github/github-actions?Dev_QT=PET3035062

また、Github Actions 関連の Microsoft Learn もお試しください！ 

- [GitHub Actions を使用してワークフローを自動化する](https://docs.microsoft.com/ja-jp/learn/paths/automate-workflow-github-actions/?Dev_QT=PET3035062) 
- [GitHub Actions を使用してクラウドネイティブの ASP.NET Core マイクロサービスをデプロイする](https://docs.microsoft.com/ja-jp/learn/modules/microservices-devops-aspnet-core/?Dev_QT=PET3035062) 
- [GitHub Actions または Azure Pipelines を使用して Java アプリを迅速に開発してデプロイする](https://docs.microsoft.com/ja-jp/learn/modules/deploy-java-azure-pipeline-terraform/?Dev_QT=PET3035062) 
- [カスタム GitHub アクションを作成して公開する](https://docs.microsoft.com/ja-jp/learn/modules/create-custom-github-actions/?Dev_QT=PET3035062)
なぜ2の補数で負数を表現するのか

# なぜ2の補数を使うのか
ビットで負の数を表現するときには、2の補数を用いて表現されることが多いです（これを2の補数表現といいます）。
なぜ2の補数表現が用いられるのか？
それは「**マイナスの計算が簡単にできるから**」です。

（2進数上で）2の補数で表現された負数は、以下のように**そのまま足すことでマイナスの計算ができます**。
例： 5 - 4 をするとき
10進数の 5 → 2進数 0101
10進数の-4 → 2進数 1100 (2の補数表現を用いた場合）
0101  + 1100 = 10001
一番左の桁あふれは無視されるので、答えは0001 = 1 

これから仕組みを説明していきます。

# そもそも2の補数ってなに？
計算が簡単になる仕組みを説明する前に、まずはおさらいです。

すべてのビットを反転させた数が「1の補数」で、（例：101 の 1の補数 → 010)
すべてのビットを反転させて +1　をした数が「2の補数」 (例 101 の 2の補数 → 011)
と習うかもしれません。
が、これは「補数の求め方」であって、「定義」とはちょっと違う話になります。
定義を以下に説明します。


### 2の補数とは
補数とは、足すとちょうどその桁数を超えるような数のことをいいます。（1の補数ではなく2の補数の場合）

4桁の2進数で考えてみましょう。
ここに「1001」という数があるとします。この数になんの数を足すと、ちょうど桁が超える数...つまり「10000」になるでしょうか？
**10000 - 1001 = 0111** ですね。これが「1001 に対する 2の補数」です。
これはビット反転 +1 でも求められます。
1001 をビット反転 → 0110  これに1を足すと、 0111。

4桁の10進数でも考えてみましょう。
「2進数で言う2の補数」というのは、10進数では「**10の補数**」と呼ばれます。
ここに「1234」という数があるとします。この数になんの数を足すと、ちょうど桁が超える数...つまり「10000」になるでしょうか？
**10000 - 1234 = 8766** ですね。これが「1234 に対する 10の補数」です。
2進数とは違い、10の補数は引き算なしでは求められません。
 
# 2の補数で簡単にマイナスを計算できる仕組み

では、なぜ2の補数で簡単にマイナス計算ができるのでしょうか。

### 10進数で10の補数表現で計算してみる
まずは10進数で10の補数表現を用いてマイナスの計算をしてみましょう。
234 - 568 = -334　を考えます。

568 の 10の補数は 1000 - 568 = 432 です。これを234 に足してみましょう。
234 + (-568 +1000) = 234 + 432 = 666 です。
答えの-334 とは全然違う数になりましたね。なぜなら式を見ての通り+1000 を多く足しているからです。

なので最後に-1000をしてあげましょう。
234 - 568
= 234 + (-568 + 1000) - 1000 = 234 + 432 - 1000
= -334
正しい数になりました。結局のところ、補数を用いた計算は＋1000をして再び-1000をしているだけです。
でもこれだと逆にややこしいですね。
-568+1000で結局引き算をしているからです。

### 2進数で2の補数表現を用いて計算してみる
2進数の場合は補数計算が楽なので簡単になります。

12 - 8 を2進数で考えます。
(10進数)12 → (2進数)01100
(10進数)8  → (2進数)01000
01000 の 2の補数は、10111 + 1 = 11000　です。

なので、
12 - 8
= 01100 - 01000
= 01100 + 11000 -100000 = 100100 - 100000　= 00100
01000の2の補数である11000は、100000 - 01000 をして求められた数なので、2足すと100000が多く足されます。だから最後に引く必要があります。
これが結局桁あふれになって、ビット計算では自動的に引かれることになるのです。
Jupyter RuntimeErrorの対処方法 asyncio.run() cannot be called from a running event loop

Jupyter自身のイベントループ上で新たにイベントループを開始しようとしたために起こったエラー。非同期処理を実行させたければ、await関数で直接実行させれば良い。


```python:Jupyterで非同期処理を実行させる
import asyncio
import datetime

async def display_date():
    """現在時刻を５秒間表示する"""
    loop = asyncio.get_running_loop()
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if(loop.time()+1.0)>=end_time:
            break
        await asyncio.sleep(1)

x : asyncio.run(display_date())
○ : await display_date()
```
```
2022-01-25 15:31:57.799997
2022-01-25 15:31:58.804521
2022-01-25 15:31:59.815091
2022-01-25 15:32:00.834119
2022-01-25 15:32:01.848780
```

# じゃあjupyterのイベントループはどのファイルが実行してるの？

以下コードをnotebook上で実行すると、イベントループを実行していないにもかかわらず、現在イベントループが実行中という事がわかる。

```python
import asyncio

asyncio.current_task()
```

```:notebook上で実行
<Task pending name='Task-2' coro=<Kernel.dispatch_queue()
 running at C:\Users\yourname\.pyenv\pyenv-win\versions\3.9.6\lib\site-packages\ipykernel\kernelbase.py:461>
 cb=[IOLoop.add_future.<locals>.<lambda>()
 at C:\Users\yourname\.pyenv\pyenv-win\versions\3.9.6\lib\site-packages\tornado\ioloop.py:688]>
```
notebookはtornadoというファイルによって実行されているということが分かる。

以下コードをターミナル上から実行するとasyncioによって実行されていることが分かる。

```python
import asyncio


async def whats_event():
    print(asyncio.current_task())

asyncio.run(whats_event())
```

```:ターミナル上で実行
<Task pending name='Task-1' coro=<whats_event() 
running at c:\Users\yourname\lessons\python_lessons\project\aysnc_test.py:5> 
cb=[_run_until_complete_cb() 
at C:\Users\yourname\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\base_events.py:184]>
```
【Django】IIS のサーバータイムアウト時間の変更

#はじめに
Django フレームワークを用いて IIS サーバーへデプロイしました
その際に サーバータイムアウト の設定を IISマネージャーからどこを変えてもうんともすんとも効かなかったので、変更箇所を共有したいと思います
IIS タイムアウト時間はデフォルトで 110 秒となっています

※DjangoをIISへデプロイしたり環境の用意をする記事ではありません

####下記の環境を想定しています
```
- Windows Server 2019
- IIS 10
- Python 3.9.7
- Django 3.2.10
- wfastcgi 3.0.0
- wwwroot 直下に venv にて python 仮想環境フォルダ(env)を作成
```


#もくじ
- applicationHost.config の変更


#applicationHost.config の変更
下記ディレクトリにある applicationHost.config を変更します
```C:\Windows\System32\inetsrv\Config\applicationHost.config```
※任意でバックアップはとっておきましょう

ファイル内にあるタグ \<fastCgi> を編集します
例では 180 秒に変更しております

【変更前】

```
<fastCgi>
    <application fullPath="C:\inetpub\wwwroot\env\Scripts\python.exe" arguments="C:\inetpub\wwwroot\env\lib\site-packages\wfastcgi.py" 
    signalBeforeTerminateSeconds="30" />
</fastCgi>
```

【変更後】

```
<fastCgi>
    <application fullPath="C:\inetpub\wwwroot\env\Scripts\python.exe" arguments="C:\inetpub\wwwroot\env\lib\site-packages\wfastcgi.py" 
    signalBeforeTerminateSeconds="30" activityTimeout="180" />
</fastCgi>
```
activityTimeout="180" を追記しました
あとはサーバーを再起動すればタイムアウト時間が 180 秒に変更されます


#おわりに
IIS は基本的に asp.net に合わせた設定が多いらしく、Django との相性は…
タイムアウト伸ばすだけでしたが、情報がなかったので共有しておきます
ConoHaのマーケティングってわけがわからない


- VPSを売るために、キャラクター作る。 ← わかる。

- VPSを売るために、キャラクターのTシャツ作る。 ← まあ、わかる。

- VPSを売るために、キャラクターのカレーやらその他グッツ作る。 ← わからん。

- VPSを売るために、キャラクターの漫画作る。← わからん。

- VPSを売るために、キャラクターに声優つけて歌わせて、アルバム発売。← わからん。

ConoHaはVPSを売りたいんじゃなくて、キャラクターのグッツを売りたいんか？
Tabular Playground Series - Nov 2021 の解法まとめ

こんにちは、tmrtjと申します。

私は現在株式会社音圧爆上げくんという会社に所属しており、プロKagglerとして活動しています。


これから、主にテーブルデータコンペに取り組むに当たって、そこで得た知見などを記事として投稿していく予定です。

また、コンペに直接関係する内容の記事はprivate sharing に当たらないように該当コンペのDiscussion にも同じ内容のものを投稿します。



私は現在プロKagglerとして、業務の一環で、現在Kaggleで行われているコンペの一つである[Tabular Playground Series - Jan2022](https://www.kaggle.com/c/tabular-playground-series-jan-2022) に参加しています。



このコンペに取り組むにあたり、過去行われたTabular Playground Series の公開されている解法を読んでまとめています。

まとめたものの一部を記事として公開していきます。

今回は、Tabular Playground Series の[11月](https://www.kaggle.com/c/tabular-playground-series-nov-2021)のコンペ（以下TPS11という）の解法をまとめたものを紹介します。

特に、まとめるにあたり、個々の解法から、他のテーブルコンペにも応用が効きそうな点をピックアップしました。

コンペのEDAやコードの追試などまでは行えていないので、理解が不十分な点があるかもしれません。

また、Kaggleのコンペに参加するのは今回が初なので、中級者以上の方から見ると大したことが書いてないように思われるかもしれませんが、私のような初心者の方にはとっかかりとしては役に立つかもしれません。
お手柔らかにお願いします。


また、Kaggle上にNoteBookとして同じ内容の記事を英語で投稿しています。
リンクは[こちら](https://www.kaggle.com/c/tabular-playground-series-jan-2022/discussion/303698)です。


#TPS11
#1位解法
[リンク](https://www.kaggle.com/c/tabular-playground-series-nov-2021/discussion/291883)
・シンプルなNNを訓練しoofを得る
・このoofから間違って予測したTop5％（たぶん、特にoofの精度が悪かったデータという意味）をラベルを貼り直してNNを再学習
・5%のデータでpseudo-labelingして再学習
・公開されている他のnotebookと混ぜて最終予測とした

#2位解法
[リンク](https://www.kaggle.com/c/tabular-playground-series-nov-2021/discussion/291903)
・chunkごとに含まれる正解ラベルの割合が違う問題だった
・なのでchunkごとに補正をかければ精度が上がると考えた
・補正をかけずに訓練させたNNモデルによる予測をベースラインとし、それを使ってtestデータは9のchunkに分かれることが分かった
・テストデータのどのchunkが精度向上に寄与するかを割り出し、それに応じた補正をかけて、最終提出の予測値を出した。

#3位解法
[リンク](https://www.kaggle.com/c/tabular-playground-series-nov-2021/discussion/291766)
・testデータが九つのチャンクに分かれていることがまず分かった
・leakしている学習データによってそれぞれのチャンクがさらに二つに分かれることがわかり、計18のchunkに分かれることがわかった
・1日あたり5回のsubmissionができるので、18回のLBスコアからそれぞれのchunkに含まれているtargetの確率が割り出せる
・その割合と公開されているNotebookの加重平均を最終予測にした


#TPS11所感
・与えられたデータがchunkになっているということが明らかになる前と後でかなりコンペへの取り組み方が様変わりしたことが各解法から窺える。
・1日あたり5回のsubmissionをどう使い、testデータのchunkに含まれるtargetの割合を割り出すゲーム。
・2位、3位解法で用いられているような、複数回予測値を提出し、得られる複数のPublic Scoreを用いてPublic Leader Boardのデータの中身を推定するテクニックを「Leader Board Probing」というらしい。
・3位の方の解法の、4日かけてsubmissionを消費してtestデータの各chunkにおけるtargetの割合を特定しにいくのはかなりの確信がないとできない。
・ただ、1位の方は自身ではLeader Board Probingをしておらず、Probingを用いて良いスコアを叩き出していた公開カーネルをうまく使って優勝している。



#全体としての感想
これまで解法を紹介してきたコンペとは違い、Kaggle特有のハックをどう上手くやるかという勝負のコンペでした。

TPS11のようなコンペは、現実のデータサイエンスの問題に即したコンペとは言い難く、賛否両論あると思いますが、あくまでkaggleで良い成績を収めることを目指すなら知っておいた方がいいのだと思います。

ただ、個人的には、解法を読んでいて、仕組みをハックしようとする熱意が感じられて、解法を読んでいてとても面白かったです。

また、ハックする方法に気づいているのが自分だけとは限らない以上、そこに気づいたうえで、さらにその気づきをどうハイスコアに繋げるかが好成績を取るためには重要で、現実的なデータサイエンスの問題に取り組むのとは違った頭の使い方が求められそうで、こういうコンペも一度は体験してみたい気持ちがあります。

重ねて、優勝解法を読んで、自分で発見することも大事ではありますが、コンペで勝つためには、他の人の発見や成果などをどのように使っていくかというのも重要になってきますし、うまくやれば、オリジナルの人をも超える結果を出すこともできる、というのがKaggleの奥深いところだと思いました。






#さいごに
株式会社音圧爆上げくんではプロKagglerを募集しています。
ご興味のある方はぜひ以下のリンクをご覧ください。
[Wantedlyリンク](https://www.wantedly.com/projects/748285)
[jest]localStorageをjestでテストしたい

## やりたいこと
localStorageのテストをjestでしたかったのですが、
jest初心者で忘れそうなのでメモ的に残しておこうと思います。

## コード
### js(react)
実際のコードを書いていきます。(簡単に)
雑に書いてるのでミスがあったらすみません。

```.jsx
export const sample = () => {
  const ini = {};
  const [sampleData, setSampleData] = useState(ini);
  useEffect(() => {
    const getItem = localStorage.getItem('item');

    if (!getItem) {
      const sampleText = "sampleです";
      localStorage.setItem('item', sampleText);
      setSampleData(sampleText);
    } else {
      setSampleData(getItem);
    }
  }, []);
}
```

### jest
```.js
import {renderHook } from '@testing-library/react-hooks';
import sample from "./" // 上記のファイルを呼び出し

describe("ここに任意のテスト名", () => {
  test.each([[''], ['item']])("ここにテストの内容", (item) => {
    const spySet = jest.spyOn(Storage.prototype, "setItem");
    const spyGet = item ? jest.spyOn(Storage.prototype, "getItem").mockReturnValue(item) : '';

    const { result } = renderHook(() => sample());
    if (item) {
      expect(spyGet).toHaveBeenCalledTimes(1);
      expect(spyGet).toBeCalledWith("item");
    } else {
      expect(spySet).toHaveBeenCalledTimes(1);
      expect(spySet).toBeCalledWith("item", "sample");
    }
  });
});
```

### 解説
上記のコードで何をやっているか簡単に解説させてください。
まず、localStorage.getItemで該当のkeyを持ったstorageが存在するかを確認し、
あったらstateに値を保存。(値はlcoalStorage.getItemの値)
なければ、setItemし、stateを更新というだけのことをしています。

jestの方の解説ですが、
上から順に説明します。

#### each
eachは設定した配列の分だけテストを実行してくれます。
以下は3回testを回します。

```
.each([
[1],[2],[3]
])
```
こちらの値を参照するときは、test("", Fn)の引数に設定することで参照することができます。

#### spyOn
関数のモック化をします。
spyOnの第一引数に該当のオブジェクト、第二の引数にメソッドを指定することで該当の関数を
モック化できます。

#### mockReturnValue
モック.mockReturnValue('test');
とするとモックが実行された際の戻り値がmockReturnValueに設定された引数になります。

#### renderHook
カスタムフックを呼ぶための関数で、今回の場合だとuseEffectの実行です。

#### toHaveBeenCalledTimes
toHaveBeenCalledTimesは該当の関数が何回呼ばれたかを返します。

#### toBeCalledWith
toBeCalledWithは該当の関数が実行された際の引数を返します。

## まとめ
曖昧な部分が多く、間違っている部分があるかもしれないのでもし違う場合は教えてください。
GitHubでcloneしたLaravelプロジェクトをDockerを使ってローカル環境構築するまでの手順

#はじめに
GitHubでcloneしたLaravelプロジェクトをDockerで環境構築したい人に向けて簡潔に手順を解説します

５分程度で終わります
#１．リモートリポジトリをローカルにcloneしてbuildする
```
#GitHubからcloneする
$ git clone {リポジトリURL（https://〜.git}

# イメージを作成
$ docker-compose build

#cloneしたディレクトリに移動してbuild
$ docker-compose up -d
```
#２．パッケージのインストール
・Dockerコンテナ内に入って以下のコードを実行

```
$ docker-compose exec {サービス名} bash
$ composer install
```
#3.APP_KEYの作成
```
$ chmod 777 -R storage/
$ cp .env.example .env
$ php artisan key:generate
```
#4.localhostでウェルカムページを確認
[localhost](localhost)
![スクリーンショット 2022-01-25 14.16.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2166327/7eb0e50d-463d-c7b6-7540-fe1dc59de04f.png)

上記の画像が表示されたら完了です！

#おわりに
GitHubからcloneしたLaravelプロジェクトはDockerでビルドしたらすぐに開けるものかと思ってた、、
APIドキュメントから生成したFastApiスタブをPysenに怒られないようにするまで

以前はFlaskを使ってゆるい型もないゆるゆるフワフワしたAPIを作って居たものです。
しかしながら、最近は型の概念がいかに素晴らしいかというのをTypeScriptやらGolangやらで体感したので、たとえPythonであっても、しっかりした型でいい感じのコードを書きたくなりました。

## 開発環境
- Poetry+Pysen
  - これが今どきの最新っぽい雰囲気でおすすめされてたので使います
- openapi-generator-cli
  - 別に何で生成してもいいと思いますが、以前から何度か使っていて慣れているので使う
- Stoplight
  - 初めからStoplight使って居るので、無いとやってられない、もはや手書きでは書けない

## 1 ドキュメントを作る
Stoplightでガリガリ書きます

## 2 Python-templeteを使い PysenとPoetry入ったプロジェクトを生成

https://github.com/shuntaka9576/python-project-template

で作ったあと、`git clone` してくる。
(非常に助かりましたありがとうございます)

## 3 openapi-generator-cliで ドキュメントからスタブ生成
cloneしたプロジェクトのsrcフォルダ内でスタブを作る。

```bash
npm install -g openapi-generator-cli
openapi-generator-cli generate -g python-fastapi -i server.yaml -o api_gen
```

## 4 生成したフォルダを調整
個人的にsrcフォルダ内直下に入って欲しい。なのでまずは VSCodeのファイル内検索で、`from openapi_server.models` を `from src.models`に一括置き換えする。
そして `openapi_server`フォルダの中身を全て 1階層上に移動する。

## 5 テストの返り型を指定
openapi-generator-cliで生成したテストは 返り値型が付いていないので
`(client: TestClient):` を `(client: TestClient) -> None:` に一括置き換えする

## 6 paramsの型TupleではなくDictにする
そのままでは testsのclient.requestのparamsは`typing.MutableMapping[str, str]`、つまりDict型を要求するにも関わらずparamsがTupleとして投げられるため、mypyが怒る。(実際には内部で上手いことやってくれるようだが。)
`[("localization", "en"), ("page", 1), ("keywords", "test")]` を `dict([("localization", "en"), ("page", 1), ("keywords", "test"))`として一括置き換えして、明示的にDict型にする

## 7 paramsにValueに型が無いのでStrにする
先程触れたように testsのclient.requestのparamsは`typing.MutableMapping[str, str]` であるため
paramsを `Dict[str, str]`にする。そのため、`params =` を `params: Dict[str,str]` に置き換えて`("page", 1)`を`("page", "1")`に置き換える。これでtestsフォルダのフォーマットは完了。`poetry run pysen run format`して`poetry run pysen run lint`して問題なければCommit

## 8 apisのrouterに付いている Dependsをすべて 外してインポートするようにする。
Pythonの関数のデフォルト引数は、読み込まれたタイミングで一度だけ実装される。この仕様をしらずにあとから関数を実行してトラブルになる可能性があるため、デフォルト引数に関数を与えるとPEPに怒られる。
これを回避するには、共通するDependsを全て 別ファイルに書き出してしまえば良い。
詳細は省くが、いい感じに置き換えを使う。

## 9 横に長過ぎる説明を改行
OpenAPIドキュメントで書いてあるコメントが丁寧すぎる場合、flake8で指定してある88文字を大幅に超えることがある。その場合は改行を入れる。

## 10 モデル確認
ちゃんと生成されていればここまでで動くはずだが、上手く行かない場合は、複雑なモデルの生成に失敗している可能性がある。modelsフォルダの中のモデルを眺めてみて、おかしな生成があれば修正する。

## 11 完了
`poetry run pysen run format`して
`poetry run pysen run lint`

```bash
isort .......... OK (2.01 sec)
black .......... OK (3.82 sec)
flake8 .......... OK (4.04 sec)
mypy .......... OK (17.52 sec)
```

というように、4人みんなにOKを貰えたら合格、CommitしてPush。


## 参考
実際作っているプロジェクト

https://github.com/PurplePalette/sonolus-fastapi

テンプレートの解説ページ

https://dev.classmethod.jp/articles/shuntaka-python-tools/
FastAPIでかんたんFirebaseAuthorization+かんたんにテスト

これまで他の言語で作っていたAPIを書き直しています。以前のAPIはFirebaseAuthorizationで認証していたので、FastAPIでもFirebaseAuthorizationでユーザー認証したい。さて、どうするか。

## 公式ライブラリでなんとかする
https://qiita.com/DeliciousBar/items/d6845d329e37f21a6d4f

https://kazuki-hayakawa.hatenablog.com/entry/2019/04/09/213725

セキュリティ的にこれが無難だと思う。しかし、`account_key.json` のような認証鍵をファイルとして渡す必要があり、Dockerコンテナ化する場合はボリュームのマウントがめんどくさくなってしまう。環境変数に全部乗せることができないだろうか?

## サードパーティライブラリでなんとかする
https://github.com/tokusumi/fastapi-cloudauth

実は、本当にFirebase Authorizationの認証だけがしたいならProjectIDさえあれば、署名が有効かどうかは 特定のエンドポイントにパラメータを添えてGETするだけで良い。(最悪IDトークン本体が1時間有効なJWTなので、本体をパースするだけでも確認できてしまうが、それが無効化されているかどうかを念の為Google鯖に確認しに行っているというだけ) それをすごくシンプルにできるようにしてるのがこのFastAPI-CloudAuth。本家firebase_adminと違い、深い依存関係が追加されることもないので、セキュア度が高くない用途であれば、このサードパーティでも良いと思う。今回作っているのは軽いゲームなので、今回はこっちを採用。

## 検証の実装例
非常にシンプルにできる仕様なので、実装も何もという感じだったが紹介。

```python
from fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims


router = FastAPI()
get_current_user = FirebaseCurrentUser(project_id=os.environ["PROJECT_ID"])


@router.post(
    "/users",
    responses={
        200: {"description": "OK"},
        400: {"description": "Bad Request"},
        401: {"description": "Unauthorized"},
        409: {"description": "Conflict"},
    },
    tags=["users"],
    summary="Add a user",
)
async def add_user(
    auth: FirebaseClaims = Depends(get_current_user),
) -> None:
    """Add specified new user to server"""
    # 認証できていればこの中にたどり着く
    # できていなければ401が既に返されている
    return auth.user_id # user_idが手に入ればあとは好きにどうぞ

```

## テスト用のスタブ例
Headerに入ったBearer 以降の部分をそのままユーザーIDとして扱うことで、テスト時はトークン関係なしに直接試せるようにする。もっとやりようはあるが、愚直にやったらこうなった。あとはテストをしようとしたら、毎回認証がスキップされて本体だけのテストを行うことができる。

```python:seurity_api.py
dependsHeader = Header(None)

async def get_current_user_stub(
    authorization: Optional[str] = dependsHeader,
) -> FirebaseClaims:
    if authorization is None:
        raise HTTPException(status_code=401, detail="Not authenticated")
    separated_authorization = authorization.split("Bearer ")
    if len(separated_authorization) != 2:
        raise HTTPException(status_code=401, detail="Not verified")
    DUMMY_USER["user_id"] = separated_authorization[1]
    return DUMMY_USER


get_current_user = FirebaseCurrentUser(project_id=os.environ["PROJECT_ID"])
```

```python:conftest.py
from src.security_api import get_current_user, get_current_user_stub

@pytest.fixture
def app() -> FastAPI:
    # ここにDependsの関数名をキーとして 別の関数を入れると オーバーライドができる
    application.dependency_overrides[get_current_user] = get_current_user_stub
    return application  # type: ignore
```

## やってみた感想
Firebase Authorizationは楽にできてすごく良い
APT を使ったNVIDIAドライバのインストールでハマった話

NVIDIA Driver って突然使えなくなりますよね。

今回、`nvidia-smi` コマンドを実行すると、以下のエラーが発生しました。

```
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```

以前も似たようなエラーに遭遇していて、その時は NVIDIA Driver と CUDA の再インストールで解決しました。おそらく、`sudo apt upgrade`で知らない間に関連するライブラリをアップデートしてドライバの依存関係が壊れてしまっていたのだと思います。

今回も再インストールで直るかなと思ったのですが、少しはまったので記事にしました。

### 環境
* Ubuntu 18.04
* GeForce GTX 1080 Ti

### 試したこと

毎回、NVIDIA Driver と CUDA の再インストールで直るので、今回も試してみました。
再インストールの方法は以下の記事を参考にしました。
https://qiita.com/porizou1/items/74d8264d6381ee2941bd

NVIDIA Driver のインストール方法はたくさんありますが、自分は Ubuntu を使っているので、`ubuntu-drivers` コマンドを使っています。

`ubuntu-drivers devices` でインストール候補の NVIDIA Driver を探して、apt でインストールするのですが、インストール最中に以下のメッセージがでます。

```
...
ERROR: Cannot create report: [Errno 17] File exists: '/var/crash/nvidia-kernel-source-470.0.crash'
Error! Bad return status for module build on kernel: 5.4.0-84-generic (x86_64)
Consult /var/lib/dkms/nvidia/470.63.01/build/make.log for more information.
dpkg: error processing package nvidia-dkms-470 (--configure):
...
Errors were encountered while processing:
 nvidia-dkms-470
 nvidia-driver-470
E: Sub-process /usr/bin/dpkg returned an error code (1)
```

どうやら nvidia-dkms が怪しいようです。
また、
`sudo apt purge nvidia*`
で関連するライブラリをアンインストールしようとしても、nvidia-dkms はアンインストールできなかったです。


### 原因
ググってみると、以下のスレッドを見つけました。
https://forums.developer.nvidia.com/t/nvidia-driver-470-does-not-install-on-ubuntu-20-04-lts/191593

カーネルをビルドした時のコンパイラと現在DKMSをビルドする時のコンパイラが異なっていることが原因とのことです。DKMSとは、Linux でカーネルに組み込まれていないカーネルモジュールを動的にロードする仕組みとのことです。カーネルモジュールのビルドかロードに失敗しているようですね。

実際に gcc のバージョンを見てみると、Not Found となっていました。。。
以下で、gcc をインストールします。
`sudo apt install gcc`
これで、gcc がインストールできます。

`cat /proc/version`と`gcc --version`
のバージョンが一致しているか確認します。

これで、無事に NVIDIA Driver がインストールできました。

### まとめ
CUDA 環境の構築に慣れはこない
PythonでAPIを確認する

##はじめに
データを集める時に、APIが使えるようになると便利だなと思って基礎を学ぶことにしました。
自分の備忘録用。

##利用するAPI

http://zipcloud.ibsnet.co.jp/doc/api

サイトを検索すると手法習得で用いられている郵便番号のAPI。今回はその中でも、zipcloudを使うことにしました。

##コードと追記
```python
#モジュールをインポート
import json
import requests
import pandas as pd

#リクエストURL
url = 'https://zipcloud.ibsnet.co.jp/api/search'

# 条件指定
param={'zipcode':'100-0005'}

#条件からレスポンスを取得
res = requests.get(url, params=param)

#dict型に変換
response = json.loads(res.text)

#results部分だけ抜き出す
address = response['results'][0]

#データフレームに変換(最初に郵便番号がくるように入れ替え)
df = pd.DataFrame(address.values(), index=address.keys()).T
re_df = df.reindex(columns=['zipcode','address1','address2','address3','kana1','kana2','kana3','prefcode'])
re_df
```

| 項目 | 追記 |
|:-----------:|:------------:|
| リクエストURL      | 使いたいURLの情報を設定する       |
| 条件指定    | リクエストURLに送るパラメータを決める    |
| レスポンスを取得       | パラメータから返ってきた情報が得られる        |
| dict型に変換         | 文字として認識できるようにする          |
| resultの抜き出し       | 住所部分だけにする       | 
| dfへの変換    | データセットの形にする     |

上のスクリプトで得られたデータフレームがこちら。resultをそのまま抜き出すと郵便番号が最後になるので、re_dfで順番を入れ替えています(ここは好みの問題)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/f921afdb-f627-84b4-0f84-76a517bd3729.png)

##まとめ
APIというとかなり複雑なイメージがあったのですが、郵便番号に関しては割と簡単なコードで使えることが分かりました。これからはもっと複雑なAPIもトライしていけたらと思います。

ちなみに、〒100-0005は東京駅がある住所です。豆知識。

##参考
https://www.taillook.tech/entry/python3-requests-zipcloud
https://www.sejuku.net/blog/78985
Meet Your Business Needs with AppExchange > AppExchange Solutions > Install an AppExchange Solution


# エラーメッセージ

+ We can’t find the 'VideoFileViewer' package installed in your org.

1. まだ、何もしていない状態
2. Service Agent Script for Salesforce Flowをインストールした状態
3. ハンズオンの Challengeに入る直前 

**フローのLightningランタイムを有効にする**
分かりにくい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1259e49a-de3d-1d4b-6b93-5d6f33779281.png)


**フローを作成する**

+ We can't find a flow with the label 'Welcome Video Flow'. Make sure that the flow’s API Name is 'Welcome_Video_Flow'.

Flow Video Player & File Viewer パッケージをインストールした段階

あとは、指示通りに作れば完了できました。
jsxとvueの条件によってタグを表示させる方法

## 概要
最近react,vueを触る機会が多いので、メモするほどのことでもないのですが、
初心者やreact,vueってどんな感じなの？って人用に書かせてもらいます。
(シリーズ化して、小出しに記事にしていくかも？)

### vueでの条件によって表示させる方法
vueでは表示したい要素のタグの属性にv-ifを追加することで
要素を表示するか、しないかを表現できます。

```.vue
<template>
  <div>
    <span v-if="flag">表示されます</span>
    <span v-else>表示されません</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      flag: true
    }
  }
}
</script>
```

vueでの出しわけ方法は分かりやすく、
タグにv-if="~~"というディレクティブ(※)を追加することで、簡単に出しわけができます。
もちろん、v-else-ifも使えます。

※ DOM要素に対して何かを実行することをvue側に伝えるものと覚えておくといいかもしれないです。

### jsxでの条件によって表示させる方法
jsxの場合は以下になります。

```.jsx
const flag = true;
return (
<div>
  {flag && <span>表示されます</span>}
  // or
  {flag ? <span>表示されます</span> : <span>表示されない</span>}
</div>
)
```

jsxの場合は{}を記述して、中に条件を書くことでタグの出しわけができます。
flagの管理などはstateと呼ばれるものを使用したりしますが、それはまた別の機会に。
M1 Mac/Intel Mac/Linux/WSLでhomebrewの.zshrc設定を共通化

## はじめに

Homebrewは、M1 Mac/Intel Mac/Linux(WSL)の３種類で、
インストール先のパスが違います。

`.zshrc`の設定をGitコミットして各マシンで共有してるときに、この違いが都合悪いので、自動判定できるようにしました。

## 結果

こんな感じ。

```zsh:.zshrc
if [[ -d '/home/linuxbrew/.linuxbrew' ]]; then
 # Linux/WSL
 HOMEBREW_HOME='/home/linuxbrew/.linuxbrew'
elif [[ -d '/opt/homebrew' ]]; then
 # M1 Mac
 HOMEBREW_HOME='/opt/homebrew'
else
 # Intel Mac
 HOMEBREW_HOME='/usr/local'
fi
eval "$($HOMEBREW_HOME/bin/brew shellenv)"
```

めっちゃそのまんまですが、ディレクトリの存在チェックをして、しかるべきパスの`brew`コマンドを叩きます。

Linux/M1 Macはどっちを先に判定しても良いんですけど、Intel Macは最後の`else`に持ってきたほうが良い。`/usr/local`ディレクトリは必ず存在しますからね。

## 余談: unameは使わないほうが良い

最初は`uname`コマンドでこんな風に書いてました。しかし、これだとM1 Macでうまく動かないことがあります。

```zsh:.zshrc
if [[ `uname` == 'Linux' ]]; then
 # Linux/WSL
 HOMEBREW_HOME='/home/linuxbrew/.linuxbrew'
elif [[ `uname` == 'Darwin' && `uname -m` == 'arm64' ]]; then
 # M1 Mac
 HOMEBREW_HOME='/opt/homebrew'
else
 # Intel Mac
 HOMEBREW_HOME='/usr/local'
fi
eval "$($HOMEBREW_HOME/bin/brew shellenv)"
```

Macの場合、ターミナルアプリの「情報を見る」で、「Rosettaを使用して開く」のチェックを入れると、Rosettaを使ってIntelアーキテクチャとしてターミナルを開いてくれます。

![CleanShot 2022-01-25 at 13.51.27@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24333/4d18e030-2a6d-0e4b-eda4-d961947fe59a.png)

Rosettaで開いた場合、`uname -m`の結果も`arm64`ではなく`x86_64`となり、Intel Mac判定となります。
しかしHomebrewのインストール先は同じマシンなので一緒なので、「`/usr/local/bin/brew`なんて見つからねーよ！」となるわけです。

CLIアプリもまだまだM1対応してないものは多いので、Rosettaを使うこともある場合は、素直に「インストール先ディレクトリが存在するか」でチェックしたほうが安全です。
Python3: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする

デジタル庁の [接種状況ダッシュボード](https://info.vrs.digital.go.jp/dashboard/) のデータを処理して、ワクチン接種済者をカウントします。

データの取得

```bash
wget https://data.vrs.digital.go.jp/vaccination/opendata/latest/summary_by_date.csv
```

次を計算します。
>ワクチン2回目接種済者
>ワクチン2回目接種後、6ヶ月が経過した者
>ワクチン3回目接種済者

```py:count_vaccination.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	csv_read.py
#
#						Jan/25/2022
#
import	sys
import	csv
import	datetime
#
from datetime import timedelta

# --------------------------------------------------------------------
def count_proc(array_aa,day_6months):
	second = 0
	second_6months = 0
	third = 0
	for unit in array_aa:
		dte = datetime.datetime.strptime(unit["date"], '%Y-%m-%d').date()
		if (dte < day_6months):
			second_6months += int(unit["count_second_shot_general"])
		second += int(unit["count_second_shot_general"])
		third += int(unit["count_third_shot_general"])
#
	sys.stderr.write("second = %d\n" % second)
	sys.stderr.write("second_6months = %d\n" % second_6months)
	sys.stderr.write("third = %d\n" % third)
# --------------------------------------------------------------------
def csv_read_proc(file_csv):
#
	fp = open(file_csv, 'r')
	reader = csv.DictReader(fp)
	array_aa = []
	for row in reader:
		array_aa.append(row)
#
	fp.close()
#
	return	array_aa
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
file_csv = sys.argv[1]
sys.stderr.write(file_csv + "\n")
#
#today = datetime.datetime.today()
today = datetime.date.today()
sys.stderr.write("%s\n" % today)
#
delt = timedelta(days=184)
day_6months = today - delt
sys.stderr.write("%s\n" % day_6months)
#
try:
	array_aa = csv_read_proc(file_csv)
	sys.stderr.write("len(array_aa) = %d\n" % len(array_aa))
	count_proc(array_aa,day_6months)
except Exception as ee:
	sys.stderr.write("*** error ***\n")
	sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

実行結果

```text
$ ./count_vaccination.py summary_by_date.csv
*** 開始 ***
summary_by_date.csv
2022-01-25
2021-07-25
len(array_aa) = 288
second = 93833803
second_6months = 28855283
third = 2629857
*** 終了 ***
```

<table>
<tr>
<td>ワクチン2回目接種済者</td>
<td>93,833,803</td>
</tr>
<tr>
<td>ワクチン2回目接種後、6ヶ月が経過した者</td>
<td>28,855,283</td>
</tr>
<tr>
<td>ワクチン3回目接種済者</td>
<td>2,629,857</td>
</tr>
</table>
【GoでMockを差し込めるようにリファクタリングした】

現在Goで作っているアプリケーションを先輩からアドバイスをもらって、より疎結合に実装できるようになったのでまとめる。（MVCの概念の中で行うことを前提にしています）

## 何をMock化したいのか？

今回のリファクタリングを通じて思ったのは、「どこの関数をmock化したいのか」をまず考えるべきと言うこと。

今回の例だとcontrollerの`user.setvalue()`をmock化できればCreateUserの単体テストが楽になりそうだ。

userController.go

```go
package controllers

import (	
	"app/~/models"
	"github.com/gin-gonic/gin"
)

func CreateUser(c *gin.Context) {
	user := &models.User{}
	c.BindJSON(user)

	user.SetValue(*user) /* <--------- ここをMock化できたらよさそう*/

	c.JSON(200, gin.H{
		"result": true,
	})
}
```

## どうやってやるのか？

### Model側の設定

この`user.setvalue()`はUserModelの関数であるため、**UserModelが実装となるinterface**を定義してあげる必要がある。

userModel.goとuserInterface.go

```go
package models

type User struct {
	Name                 string  `json:"name"`
	Email                string  `json:"email"`
}

func (u *User) SetValue(user User) {
	// 具体的な処理
}
```

```go
package models

type UserInterface interface {
	SetValue(user User)
}
```

これで、userModelの代わりとなるをmockを差し込むためのModel側の準備は完了。

### controller側の修正

あとは、mockを使うのか実際のmodelを使うのかをインスタンスを生成するタイミングで差し込んであげればいい（コンストラクタインジェクションともいう。）のでそのための修正をcontrollerに加える。

オブジェクト指向言語であれば、コンストラクタがあるのでそこの引数とインスタンス変数で実現できる。しかし、Goにはこういったものはないので**独自にNew関数とインスタンス変数っぽいものを作る**。New+〜とするのが推奨されているらしい。

**修正後 userController.go**

```go
package controllers

import (	
	"app/~/models"
	"github.com/gin-gonic/gin"
)

type UserRepository struct {
	User models.UserInterface　/* <-- インスタンス変数っぽく扱うもの */
}

/* コンストラクタの代わりになるもの */
func NewUserRepository(user models.UserInterface) *UserRepository {
	return &UserRepository{
		user,
	}
}

func (r *UserRepository) CreateUser(c *gin.Context) {
	user := &models.User{}
	c.BindJSON(user)

	r.user.SetValue(*user) /* <--------- UserRepositoryのUserのSetValueを使用する*/

	c.JSON(200, gin.H{
		"result": true,
	})
}
```

### 実際にNewするところ

これでようやくインスタンス生成時に、インターフェースを介して疎結合にモデルかmockを差し込める。
controllerに処理を渡す上位層でNewすればいい。
`&models.User{}`をMockにすれば、`CreateUser()`の単体テストは楽になるだろう￥

```go
userCnt := controllers.NewUserRepository(&models.User{})
userCnt.CreateUser()
```

## まとめ

Goで疎結合な設計を行うためには、構造体とinterfaceをうまく使う必要がある。
AWS Cloudformation で　ROLLBACK_COMPLETE　となってしまう場合の対応

# 経緯（AWS　ハンズオンでの失敗）
### AWS初心者向けハンズオン
　「[AWS Hands-on for Beginners](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/?trk=aws_blog)」という初心者向けのAWSが
公開している無償ハンズオンがあります。  
　今回この中で[AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cfn-2020-reg-event-LP.html?trk=aws_introduction_page)というハンズオンを受講しました。
### 失敗したこと
　なんども<b><font color="Red">ROLLBACK_COMPLETE</font></b>というエラーを食らいました。
![スクリーンショット 2022-01-25 131911.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296147/e6ea4e1f-36b0-9090-2b6c-28a399ba4563.png)

　今回この対応方法と推定原因がわかったのでここに書き記します。


# 対応
### エラーに対して
 スタックを削除するともう一度スタックを作成できます。
### エラーを防ぐ方法
　前のスタックが完全に起動してから（<b><font color="Green">CREATE_COMPLETE</font></b>の表示になってから）次のスタックを起動するとうまくいきました。


# 推定原因
　YAMLファイルを見ていると、前に作成したスタックから、VPCやEC2のIDをもらっています。スタックが起動していないために、そのIDを受け取ることが出来なかったことが原因と推定しています。
はじめてのGoogle AIY Voice Kit④【ラズパイセットアップ編】

# はじめに
前回のケーブル接続編の記事は[こちら](https://qiita.com/yuzuki6v6/items/c7790c56c5ee4b31e258)から:information_desk_person:
今回はラズパイセットアップ編です。
セットアップはラズパイの画面をモニターに映し、マウス・キーボードで操作し行いました。

## ラズパイを起動
AIY Voice Kit本体の電源を入れ、ラズパイを起動します。
![IMG_0662.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/a19c29d2-37c1-1c8e-5690-3cb569a07a80.jpeg)

## セットアップ手順
①パスワードを変更してくださいというポップアップが表示されますが、[OK]ボタン押下で次へ進みます。
![IMG_0266.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/39302b09-1870-e2c4-d90e-36b210d476e1.jpeg)

②「Welcome to Raspberry Pi （ラズベリーパイへようこそ）」画面が表示されます。
[NEXT]ボタン押下で次へ進みます。
![IMG_0267.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/fd4822d0-5423-c08f-f2c0-12e4377547a7.jpeg)

③「Set Country（地域の設定）」画面が表示されます。
Countryの中から【Japan】を選択します。Language項目は【Japanese】を選択します。Timezoneは【Tokyo】を選択します。
[NEXT]ボタン押下で次へ進みます。
![IMG_0269.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/dba23bae-7e47-4635-6796-b8aa8d6f6660.jpeg)

④「Change Password（パスワードの変更）」画面が表示されます。
パスワードが設定できますので、好きなパスワードを入力します。
[NEXT]ボタン押下で次へ進みます。
![IMG_0273.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/af25aa0b-3099-6cdd-cac2-9d0d2ec12af7.jpeg)

⑤「Set Up Screen （スクリーンのセットアップ）」画面が表示されます。
もし画面の端に黒い枠線がある場合は、チェックボックスを選択します。（基本はチェックなしでOKです）
[NEXT]ボタン押下で次へ進みます。
![IMG_0274.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/8f27f6ab-1404-f7ae-59a3-9e6050027fd8.jpeg)

⑥「Select WiFi Network（WiFiネットワークの選択）」画面が表示されます。
接続したいWiFiネットワークを選択し、パスワードを入力します。
[NEXT]ボタン押下で次へ進みます。
![WiFiネットワークの選択.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/cc689f4d-8484-ab7e-878c-c59889d1f779.jpeg)

⑦「Update Software（ソフトウェアのアップデート）」画面が表示されます。
最新のソフトウェアにアップデートします。[NEXT]ボタン押下で実行します。
![IMG_0277.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/0c50aa06-7858-a306-92d8-b4fb0d154b25.jpeg)

ダウンロードサイズが大きいため、環境によっては時間がかかることがあります。
![IMG_0278.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/ed94c727-5a78-996e-c92e-4c340d6f6e09.jpeg)

⑧「Setup Complete」画面が表示されます。これでセットアップは完了です！
[Done]ボタン押下で終了します。
![IMG_0280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921847/aa3e64aa-ea68-6e60-6008-fe41c141f196.jpeg)

# 所感
今回初めてラズパイのセットアップを行いました。
壁紙がいい感じ…！
ラズパイSSH接続編に続きます！
BigQueryでsleep関数

慣れればなんということもなさそうだけれど、一応メモ。

```sql 
DECLARE DELAY_TIME DATETIME;
DECLARE WAIT BOOL;

BEGIN 
  SET WAIT = TRUE;
  SET DELAY_TIME = DATE_ADD(CURRENT_DATETIME, INTERVAL 10 SECOND);
  WHILE WAIT DO
    IF (DELAY_TIME < CURRENT_DATETIME) THEN
      SET WAIT = FALSE; 
    END IF; 
  END WHILE;
END
```


## 参考文献
- [Is there a wait method for Google BigQuery SQL](https://stackoverflow.com/questions/66097351/is-there-a-wait-method-for-google-bigquery-sql)
記事の生地

#はじめに
テンプレートがあった方が書きやすいと思い、
個人用のテンプレートを投稿します


#テンプレート
```
#はじめに
説明文…

####下記の環境を想定しています
>```
>- 環境
>- 言語
>```


#もくじ
- サンプルA
- サンプルB
- サンプルC


#サンプルA
説明文…


#サンプルB
説明文…


#サンプルC
説明文…


#おわりに
説明文…

```


#おわりに
よければ使ってください…
環境にある">"は除去してください…
[Stripe Updates] ”Payment Links(支払いリンク)"で、複数の商品が登録可能になりました

ノーコードでオンライン決済を実現するためのサービスとして、StripeではPayment Links(支払いリンク)を提供しています。

https://stripe.com/jp/payments/payment-links

# これまでの支払いリンク

これまで、この支払いリンクは、１つの商品に対してのみ作成できました。

そのため、例えば「オプションサービスを含むメンバーシップ」など、複数の商品をまとめて購入・契約してもらうには、複数のリンクにアクセスしてもらう必要がありました。

# 複数商品の設定をサポート！

今回のアップデートから、複数の商品を登録した支払いリンクを作成できるようになりました。

![スクリーンショット 0004-01-25 9.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/1dff51b2-fd6f-316b-ec64-eceb38d2258a.png)

支払いリンク作成画面にて、[別の商品を追加]をクリックすることで、複数の料金データをリンクに登録することができます。

また、数量についても、こちらでデフォルト値を指定した上で、顧客がそれぞれ変更できるようにも設定できます。

![スクリーンショット 0004-01-25 9.23.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/790177f7-bed5-617a-5861-bb87e0d193b6.png)


## 複数登録ができないケース

Invoicing(請求書)などと同様に、以下のケースについては現在設定できません。

- 支払いサイクルが異なる料金（買い切りと月額など）
- 通貨が異なる料金（JPYとUSDなど）


## 注文商品の設定は変更可能

登録した商品の種類や登録済みの商品の個数、顧客が指定できる範囲の設定などは、作成後も変更できます。

![スクリーンショット 2022-06-13 21.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/ec6dcf90-545c-b24b-e506-0063ac90125e.png)

# 作成済みの支払いリンク確認方法

作成済みの支払いリンクは、Dashboardの[支払い > 支払いのリンク]から一覧で確認できます。

![スクリーンショット 0004-01-25 9.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/4ed525b9-1c19-419f-1d69-889b3795c997.png)
https://dashboard.stripe.com/test/payment-links

# ユースケース（例）

支払いリンクを利用したユースケースを２つほど簡単に紹介します。
幅広いユースケースで利用できるサービスですので、ぜひ「こんなユースケースで使ってみた！」などの情報を、[Twitter](https://twitter.com/search?q=%23JP_Stripes&src=typed_query)やご自身のブログなどで共有ください :)

https://stripe.events/jpdevguides

## 1: 月額・年額などのメンバーシップで、オプションプランの提案を行う

顧客が数量を変更できる設定にすることで、「不要であれば数量を０にして削除してください」というスタイルでのオプションの提案ができます。

![スクリーンショット 0004-01-25 9.37.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/48aa51b4-9a78-3b7e-1991-1c028ca4f841.png)

なお、クロスセル(ベータ)やアップセルの設定を商品に行うこともできますので、こちらも合わせてご検討ください。

https://stripe.com/docs/payments/checkout/cross-sells

https://qiita.com/hideokamoto/items/669d8b02195ac148dd3e

## 2: SNSのプロフィールやTwitter固定ツイートなどにリンクを設定する

現在も見かけることの多いユースケースの１つです。

手芸品や書籍など、数量を指定して注文したい商品についても、この支払いリンクを利用することで、顧客が個数を指定して注文できるようになります。

また、購入数の制限を0-99の間で指定できますので、１度に大量の注文がくるリスクを回避することもできます。

# 関連ドキュメント・リンク

https://stripe.com/docs/payments/payment-links

https://stripe.com/jp/payments/payment-links
[2022-01] mysql80-communityリポジトリの yum update が失敗するときの対処方法

庭いじり的に触っている趣味サーバー（CentOS7）でyum updateしたらmysqlのアップデートでコケた。

```zsh:
sudo yum update
...
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql から鍵を取得中です。


The GPG keys listed for the "MySQL 8.0 Community Server" repository are already installed but they are not correct for this package.
Check that the correct key URLs are configured for this repository.


 Failing package is: mysql-community-client-plugins-8.0.28-1.el7.x86_64
 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
```

下記を実行して解決した。

```zsh:
sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
sudo yum update
```

参考リンク：

https://support.cpanel.net/hc/en-us/articles/4419382481815-MySQL-GPG-keys-expired-preventing-installation-upgrade-of-MySQL-packages-from-the-official-repository-
実務で使えるVBA

<<データを他ブックからコピー>>
  
    'ファイル参照ダイアログの表示
    filePath = Application.GetOpenFilename(FileFilter:="Excelファイル,*.xls*")
    
    'ファイル参照先をこのブックと同じ場所に設定する場合
    '<<filePath = ThisWorkbook.Path & "\" & "test">>
    
    Dim wbMoto, wbSaki As Workbook
    
    '集計ツールをオブジェクトにセット
    Set wbMoto = ActiveWorkbook
    
    '追加リストブックを読み取り専用で開く
    Set wbSaki = Workbooks.Open(filePath, UpdateLinks:=0, ReadOnly:=True, IgnoreReadOnlyRecommended:=True)

 
    '参照先の1～5番目までのシート上のデータをコピーする。
    For i = 1 To 5
    
        'アクティブブックの最後尾を取得
        Row1 = wbMoto.Worksheets(1).Range("A100000").End(xlUp).Row
            
        '参照先データをアクティブブックに移す
        wbSaki.Worksheets(1).Range("A2:C1000").Copy
        wbMoto.Worksheets(1).Cells(Row1 + 1, 1).PasteSpecial xlPasteFormulasAndNumberFormats
        Application.CutCopyMode = False
            
    Next i
    
    '参照先ワークブックを閉じる
     wbSaki.Close


<<データを他ブックに丸ごと移す>>

    Dim newBookName As String
    Dim newBookPath As String
    Dim newBook As Workbook
    
    Dim today As Variant
    
    '日付の表示を取得
    today = Format(Date, "yyyymmdd")
    
    '新しいファイルの名前を指定
    newBookName = "test" & today

    '新しいファイルのフルパスを設定
    newBookPath = ThisWorkbook.Path & "\" & newBookName
    
    '指定したパスにファイルが作成済でないかを確認。
    If Dir(newBookPath) = "" Then
        '新しいファイルを作成
        Set newBook = Workbooks.Add
        
        '新しいファイルをVBAを実行したファイルと同じフォルダ保存
        newBook.SaveAs newBookPath
    
    Else
        '既に同名のファイルが存在する場合はメッセージを表示
        MsgBox "既に" & newBookName & "というファイルは存在します。"
    
    End If
    
    '---------------------------------------------------以下、コピー＆ペースト処理-------------------------------------------------------
    
    Dim SetFile As String
    Dim wbMoto, wbSaki As Workbook
    
    'コピー元のファイルをセット
    Set wbMoto = ThisWorkbook
 
    Application.DisplayAlerts = False
    
    'コピー先のパス
    SetFile = ThisWorkbook.Path & "\" & newBookName
    
    'コピー先のファイルをセット
    Set wbSaki = Workbooks.Open(SetFile)
    
    'コピー元の集計表をコピー
    wbMoto.Worksheets("test").Range("A1:E171").Copy
    
    'コピー先にペースト
    wbSaki.Worksheets("sheet1").Range("A1").PasteSpecial xlPasteFormats
    wbSaki.Worksheets("sheet1").Range("A1").PasteSpecial xlPasteValues
    
    'コピー先のシート名を変更
    wbSaki.Sheets("Sheet1").name = "test"
    
    'コピーの切り取り解除
    Application.CutCopyMode = False
    
    'コピー先の列幅を調整
    Worksheets("test").Columns(1).ColumnWidth = 23
    Worksheets("test").Range("B:E").Columns.AutoFit
    
    'コピー先を保存
    wbSaki.Save
    
    'コピー先のファイルを閉じる
    wbSaki.Close
    
    Application.DisplayAlerts = True
Vue.jsのtransitionにはCSSとJSフックがある

環境：Vue2・Vue3

Vue.jsでtransitionタグやtransition-groupタグを使用してアニメーションを実装する場合、
CSSのクラスを使用する方法とJavaScriptフックを使用する方法がある。

## 1.CSSクラスを使用する場合
Vueが用意してくれているcssクラスを使用する。
詳細は公式を確認お願いします。

https://v3.ja.vuejs.org/guide/transitions-overview.html


## 2.Jsフックを使用する場合
Vueが用意してくれている関数等を使用する。
詳細は公式を確認お願いします。

https://v3.ja.vuejs.org/guide/transitions-enterleave.html#javascript-%E3%83%95%E3%83%83%E3%82%AF

## どちらを使えばいいか
単純にCSSだけを使用するなら"1.CSSクラスを使用する場合"で問題ないと思われるが
もし「getBoundingClientRect()を使用して要素の高さを取得してからその数値を元に処理したい」など
jsの関数を使った処理が必要になる場合等はjsフックを使ったほうがシンプルに実装できそう。
argo workflow触ってみた

# Argo workflowとは？
Kubernetes上で動くコンテナネイティブなワークフローエンジン

https://argoproj.github.io/argo-workflows/

# 触ってみる

https://argoproj.github.io/argo-workflows/quick-start/

- ネット上にあるmanifestファイルをkubentl applyすると立ち上がりUIを触れる
- argo CLI をインストールすると、`argo submit` でワークフローをデプロイできる

# さらに触ってみる

https://argoproj.github.io/argo-workflows/training/

- とにかくこのチュートリアルが秀逸。何度かやるとなんとなく理解できた...気がする。
- Argo Workflowがapplyされているクラスタに `kind: Workflow` をapplyすることでジョブをsubmitする
- Workflowの定義方法をTemplateと呼び、TemplateはConteinerやDAGなどの種類ががある
  - DAGはAirflowのDAGのようにジョブ同士の依存関係を定義できたり、繰り返し処理を定義できたりする
- `kind: CronWorkflow` でいわいる定期実行ジョブを定義できる

# 感想(Cloud Composerとの比較)
- kubernetesを運用する環境が既にあり、運用できる人材も揃っているのであれば採用メリットは大きいと思う
- Cloud Composerのように1クラスタ毎にそこそこな金額が取られるようなことがないのが特に大きなメリット
- Airflow ではexecution_dateが手軽にDAGに組み込めたためbackfillな処理が描きやすかったが、Argo WorkflowではBackfillな処理を書くにはwithSequenceでBackfill定義を行うらしい(まだやってない)
    - [Cron Backfill](https://argoproj.github.io/argo-workflows/cron-backfill/)
【Processing-java】Usage: PApplet [options] <class name> [sketch args]と表示されたら。

# 実行コマンド
スケッチフォルダは気にしないで。。

```shell
$ processing-java --sketch=`pwd`\\$1 --force --run
```

# エラー文
そもそもErrorなのか？と思うようなUsageが表示された。原因不明。
「なにもしてないのに」と思ったときは何かしている。

```
Usage: PApplet [options] <class name> [sketch args]
See the Javadoc for PApplet for an explanation.
Finished.
Could not run the sketch (Target VM failed to initialize).
For more information, read revisions.txt and Help → Troubleshooting.
Could not run the sketch.
```

# main関数
ある`class`にて`main`と名付けたクラスメソッドを実装していた。つまり、以下のような構造。

```javascript
void setup(){
    hoge = new Hoge();
}
void draw(){
    hoge.main();
}
```

これがまずかったっぽい。mainを別の名前(display)に変えたら動いた。

# 反省
mainとかそういう名づけはしない。