OmniAICreator/Qiita-1.07M huggingface dataset:
Atcoder ABC227-D Project Planningの図による考え方

解説を読んでこの天才解法は思いつかないのでは..と思っていたんですが、結局自分の考え方と全く一緒だったのでメモ。

https://atcoder.jp/contests/abc227/tasks/abc227_d

# こう考える
まず、この問題を以下のように言い換えましょう。(と、簡単に書いていますが、コンテスト中はこの言い換えはできませんでした)

- 1x1のn色のブロックをAi個ずつ持っています。 (各部署の人がAi人ずついます)
- なるべく大きなP行k列の長方形を作りたいです  (k人のP個のプロジェクトを作りたいです)
- ただし、ある行に(離れていても)同じ色があってはいけません。(同じプロジェクトに同じ部署の人がいてはいけません)
- 問：作れる最大のPを求めてください

これを図にします。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/7e8fcd64-2ff3-1276-c043-b759975c8cc5.png width=50%>

$k=4$ときに、$P=6$が作れるかを判定したいとします。この際に、部署の人数をソートする必要はありません。上と下では、部署の人数が少しだけ違います。
さて、条件は行 = 横に同じ色があってはいけませんでした。こう考えると、各色のブロックは、P個以上絶対に使えないのが見えます。逆に言うと、P以下であれば適当に積んでもいいです。(図では各色を縦に並べていますが、横に同じ色がいないなら適当な場所で良いです。

これは解説の通り、

```C++
for(long long x : v) sum += min(x, md);
if(sum >= k * md)
```

を判定しているだけです。(各ブロックをPまでしか使えないとして、K*Pが埋められるか判定しています)

# 実装
本番の自分の考え方は結果として上記と一緒で明らかに遠回りなコードを書いてしまいました。

```Python
def do():
    n, k = map(int, input().split())
    dat = list(map(int, input().split()))
    total = sum(dat)
    def func(mid): # midグループ作れるかの判定
        compk = 0 # 全グループに埋めたk(これを満たせばOK)
        curkneed = mid # そのkを作るにはあとこの人数必要です
        for i in range(n): #部署を順番に見ていく
            if compk == k: return True 
            curdept = dat[i] # 今の部署の人数をcurdeptとする
            if curkneed <= curdept: # もし、今作りたいkに人が足りているなら全員突っ込む
                compk += 1 # この場合、そのkは完成
                curdept -= curkneed # そのkに必要な人数使ったので部署に残っている人数
                used = curkneed
                curkneed = mid # 本来、次のkにはmid人必要なんだけど
                # もし、「今の部署に当てたグループ」以外に充てられるならその分は充てる。
                curkneed -= min(curdept, curkneed - used) # ただし、"curkneed-used"使ってしまうと、絶対に同じグループにその部署の人が入ってしまうのでminをとる
                if compk == k: return True
                continue
            # 今作りたいグループにこの部署を全員充てる
            curkneed -= curdept
        return False
    ng = 10 ** 20 + 10
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2;
        if (func(mid)):
            ok = mid;
        else:
            ng = mid;
    print(ok)
do()
```

https://atcoder.jp/contests/abc227/submissions/27249294
大塚弘樹著 GitHub実践入門で学んだgitコマンド備忘録

#本について
https://www.amazon.co.jp/dp/477416366X

本屋さんでGit関係の本を読みましたが、GitHubやGit Flowなどについてとても分かりやすく詳しく書かれているのでこちらを選びました。
いきなりgitに公開鍵を登録するのが序盤にあるので、GitHubを使うぞ！！という気持ちがとても伝わってきました。
著作権などに触れるとあれなので、大事なコマンドだけ抜き出してメモしておきます。
#GitHub連携系
###GitHubからクローン
```shell-session
 $ git clone git@github.com:ユーザー名/リポジトリ名.git
```
###プッシュ
```shell-session
 $ git push -u origin リモートリポジトリのブランチ名
```
###リモートリポジトリを登録
```shell-session
 $ git remote add origin git@github.com:ユーザー名/リポジトリ名
```
#情報確認系
###状況確認
```shell-session
 $ git status
```
#バージョン管理系
###リポジトリの初期化
```shell-session
 $ git init
```
###ステージ（コミットできる状態にする）
```shell-session
 $ git add ファイル名
```
###コミットする
```shell-session
コミットメッセージが１行のみ：
 $ git commit -m "メッセージ"

コミットメッセージが複数行：
 $ git commit
```
###ステージとコミットを同時に行う
```shell-session
 $ git commit -am "コミットメッセージ"
```
###直前のコミットメッセージを修正
```
 $ git commit --amend
```
###コミットログの確認
```shell-sessioin
通常
 $ git log

１行目だけ
 $ git log --pretty=short

指定したファイル・ディレクトリのみ
 $ git log ファイル・ディレクトリ名

ファイルの差分も確認
 $ git log -p

ブランチを視覚的に確認する
 $ git log --graph
```
###作業ログの確認
```shell-session
 $ git reflog
```
###戻る
```shell-session
とある場所に戻る（コミットや作業中のファイルなど、全てをその時点に戻す）
 $ git reset --hard ハッシュ
```
###差分確認
```shell-session
最後にadd/コミットした場所 と 現在のファイル の差分
 $ git diff

最後のコミット と addされたファイル の差分
 $ git diff HEAD
```
###履歴の改ざん
```shell-session
 $ git rebase -i HEAD~戻したい数
pick を fixup にすることで、その歴史を無かったことにする。
```
#ブランチ関係
###ブランチ一覧
```shell-session
 $ git branch
```
###ブランチ切替
```shell-session
通常
 $ git checkout ブランチ名

ブランチを作成＆切替
 $ git checkout -b ブランチ名

1つ前のブランチに戻る
 $ git checkout -
```
###ブランチをマージ
引数についてわかりやすいサイトはこちら。

https://sinsoku.hatenadiary.org/entry/20111025/1319497900

```shell-session
マージしたことを残しておく
 $ git merge --no-ff マージするブランチ名
```
WSLでDocker をはじめる方法

# Dockerとは？

ホストOS（使っているWindowsやMacなど）上に、気軽に仮想環境（別のマシンのようなもの）を構築できます。
DockerHubなどプラットフォームを経由し、仮想環境（イメージ）を誰かと共有・公開・利用することができます。
「ホストOS（使用しているPCなど）」の上に「Linux仮想環境」ができ、その上にコンテナ（実態）ができるイメージです。

* コンテナとは、別ユーザーのワークスペースができるようなイメージです。
* コンテナ内部のOSはLinuxが共通ですが、そこの諸々の設定（使用するコマンドやソースコードなど）はDockerfileというファイルで設定できます。
* ホストOSのボリューム（ソースコードや設定ファイル等のディレクトリやファイル）を指定して、コンテナ内部と紐付ける（マウント）ことができます。
* コンテナはポートを指定して外部と通信させることができます。
* コンテナ間で双方向に通信し連携できます。アプリ１つにつき１つデータベースが必要な場合、アプリ用コンテナとデータベース用コンテナを作成するなどの用途があります。

## メリット

* OSレベルで仮想化されるため、ローカルとは別の環境ができあがる。
* 誰かの既存のイメージ（仮想環境の設計図）を引っ張ってきて、ローカルでコンテナ（仮想環境の実態）を複数起動することができる。
* 違う環境のアプリを複数起動・管理したり、チームで環境（OS・OSにインストールしているパッケージ・アプリのバージョンなど）を統一できる。
* ローカルで既存プロジェクトの開発環境を構築する際、すぐに構築できるようになる。
* Github ActionなどのCI/CD等で、コードのPush後に自動テスト・自動デプロイのサイクルができ、作業を自動化できる。

# インストール方法
※▼からインストールできます(WSL環境前提)。まだWindowsにWSL環境がない方は、事前に【[こちらを参考に準備してください。](https://qiita.com/AppJapan/items/7d961b6a6387ea895306)】

https://docs.docker.com/desktop/windows/install/


↑からインストールできます。

1. インストールが完了したら、スタートメニューから 「Docker Desktop」 を起動します。
2. アプリ上部の「⚙」歯車アイコンから、設定を開きます。
3. 設定　>　全般　>　「wsl 2 ベースのエンジンを使用する」にチェックします。
4. 設定 > Resources > WSL INTEGRATION より、「Enable integration with my default WSL distro」にチェックするか、「Ubuntu」等のDocker 統合を有効にするインストール済みの wsl 2 ディストリビューションを選択します。
5. これでWSLにてDockerが有効になります。

* デスクトップアプリ「Docker Desktop」は、ウィンドウを閉じてもバックグラウンドで動作します。
* タスクバーの非表示領域のアイコンリストに、Dockerが表示されていれば動作しています。
* Dockerが動いていれば、WSLでdockerコマンドを使用できます。
* Dockerを使用するには、PC起動時にDocker Desktop起動が必要です。これも⚙設定から、ログイン時に起動するよう設定できます。

# 使い方

| 用語 | 説明 |
| ---- | ---- |
| Docker Engine | Dockerの核。イメージのコンテナ化やコンテナを動作させる役割を担う。 |
| Docker Image | コンテナを作成するための土台。<br>コンテナはイメージを指定してそれをベースに動作する。 |
| コンテナ | Docker Imageを元に生成された作業空間・アプリケーション。<br>イメージがあれば生成できる。 |
| Dockerfile | Docker Imageをビルド（作る）するための手順書。 |


```
# Dockerバージョンを確認します。
$ docker --version

# サンプルのイメージを実行して、インストールが正しく機能することをテストします。
$ docker run hello-world

# 作成されたイメージのリストを確認します。
$ docker images

# 動作しているコンテナの確認
$ docker ps

# 停止中のコンテナも含め確認
$ docker ps -a
```
▲の例の $ docker run hello-world では、下記のような処理をしています。
1. Docker Imageがローカルにあるか検索
1. なければDocker Hubを検索(docker search)
1. 見つかればそのイメージを取得（docker pull）
1. コンテナを作成（docker create）
1. コンテナを起動する（docker start）
※hello-worldコンテナは起動後、処理が終わると停止（docker stop）します。

# 補足
docker execでは、起動中コンテナの中にログインできます。
ホストOSではインストールしていないがコンテナには入れてあるコマンドなどは、コンテナ内部で使えます。
コンテナ内部からは、マウントしていないホストOSのディレクトリ等はアクセスできません。

docker composeを使うと、1回のコマンドで、コンテナを複数起動したり相互連携して１つのWebサービスを構築するなどができるようになります。

Docker Hubには、無料で使えるイメージがたくさん上がっているので、利用してみるといいでしょう。
自分独自のイメージをDockerfileでビルドして、公開することもできますし、Dockerfileを共有して誰かに全く同じ環境を構築してもらうことも実現できます。
Pythonでのアンパックの実践例（pillow）

# はじめに

Pythonはアンパックによって辞書型を関数にねじ込むことができる。

https://note.nkmk.me/python-argument-expand/

具体的な文法自体は上記のとおりだが、これだけでは有り難みがわかりにくかった。

仕事してたら実践例が頭の中に降ってきたので、忘れないうちに残しておく。

# 実践例

画像に対して複数の図形を書きたいとき、C#ではPenを使って同じ幅、色の図形を連続して描くことができた。
ではPython(pillow)で同じように設定を使いまわしたいときは？

→アンパックをC#のPenの代わりにできることに気がついた

## サンプルコード

```py
from PIL import Image, ImageDraw

DEFAULT_BRUSH = {"outline": (0, 255, 0), "width": 5}


def create_canvas():
    return Image.new("RGB", (500, 500), (0, 0, 0))


def paint_brush(target: Image):
    draw = ImageDraw.Draw(target)
    draw.ellipse([(100, 100), (200, 200)], fill=(255, 255, 255), **DEFAULT_BRUSH)
    draw.rectangle([(200, 100), (300, 200)], **DEFAULT_BRUSH)
    return target


if __name__ == '__main__':
    paint_brush(create_canvas()).save("sample.png")
```

### 出力結果

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/07f72fb4-2166-dba5-f7dd-90f3babbdac6.png)

## ポイント

違う関数でも名前や型が同じ引数をとるのであれば、同じ辞書型の変数を使い回せる。

共通の引数を様々な関数で使いまわしたい場合、引数をクラス化してラップ関数をるといった手が思い浮かぶが、
こんな感じにシンプルに実装できることも覚えておこう。
herokuにデプロイ時、ローカルでは動くのにオンラインではh10エラーになる件の対処について

<b>結論</b>
ポートに具体的な数字を入れるとダメらしい
ポートの数字部分を
process.env.PORT || 5000
に置き換えたら動く

<b>経緯</b>
それまでにルートディレクトリに
・Package.json
・procfile
　が無い、というところでも詰まりました

その後、
・Dynoの再起動
・package.json内のnodeやnpmのバージョンの指定
・package.json内のscriptオブジェクトにstartプロパティを追加（qiita内ではこれで直る人が多いらしい）
・npm installを再び実行
などをしましたが、解決しませんでした。

最終的にポートを触ったら動きました

<b>今週のまとめ</b>
・きちんと公式の手順を読みましょう
https://devcenter.heroku.com/ja/articles/deploying-nodejs
・きちんと公式のトラブルシューティングを読みましょう
https://devcenter.heroku.com/ja/articles/troubleshooting-node-deploys

参考文献
・https://qiita.com/peace1129/items/801a1410236e4d10da1b
・https://qiita.com/mzmz__02/items/5ac0be6f8685cb8f8e1a
Clusterはじめーる（2022/11/16）

# はじめに
UnityでClusterのワールドを作成する方法のメモです

https://creator.cluster.mu/2020/03/31/%e3%80%8cunity%e3%80%8d%e3%81%a8%e3%80%8ccluster-creator-kit%e3%80%8d%e3%82%92-%e5%b0%8e%e5%85%a5%e3%81%99%e3%82%8b/

# 開発環境
- Windows 10 PC
- Unity 2021.3.4f1
- Cluster Creator Kit 2.0.0

# 導入

1．Unityを開きます

2．Project Settings -> Package Managerで以下を入力し、Applyします

|項目|値|
|:--|:--|
|Name|Cluster|
|URL|https://registry.npmjs.com|
|Scope(s)|mu.cluster|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/49feb6d0-5664-6f18-d275-c2239b1f8713.png)

3．Window -> Package Manager -> Packages: My RegistriesにCluster Creator Kit 2.0.0が表示されるのでInstallします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/c928b60f-83fd-4a38-6152-e38b9e8c2fb8.png)

4．ワールドを作成します
・SpawnPointの設置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/d4af9497-a5a4-8728-8123-40cd3f7bf42c.png)

・DespawnHeightの設置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/bc2d3fe5-8bef-4035-5580-f49c236982f0.png)

・Planeの設置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/da2f050b-1693-5118-0d57-05f6693b67f9.png)

5．再生ボタンをクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/cb789c32-e704-0d53-908a-571e2a82e613.png)

6．Cluster -> ワールドアップロードからワールドをアップロードします

※アップロードする前にMain Cameraを消しておきましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/3abfab82-1b09-c12c-3328-442dc0bf4b56.png)

7．Clusterを起動してワールドに入ってみましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/90543940-80f2-6ec0-2a48-4b0bb6766ca9.png)

お疲れ様でした
ネットワーク送受信とCPU使用率に応じてラズパイ4のLEDを点滅させる

www.kernel.org からダウンロードした素のLinuxカーネルの話です（Raspberry Pi OSで使えるか不明）。Linuxでは [`/sys/class/leds` にあるファイルに書き込む](https://qiita.com/masap/items/5734fe8e325ced76194e)とLEDを操作できます。ラズパイ４の場合赤いLEDは `/sys/class/leds/PWR`, 緑のLEDは `/sys/class/leds/ACT` に対応します。それらディレクトリの下にある `trigger` ファイルに何か書くとLEDを点灯する条件を制御できます。条件の一覧は必要なモジュール（`ledtrig_netdev.ko`などを`modprobe`した後に） `cat /sys/class/leds/PWR/trigger` で出てきますが、それぞれの意味は [Kconfig](https://github.com/torvalds/linux/blob/master/drivers/leds/trigger/Kconfig) である程度わかります。ここでは

* `netdev` [指定したネットワークインターフェイスの活動を示す](https://gist.github.com/FrankWu100/25779214ea0981f7d3095014a815a10f)
* `activity` [CPUの使用率が高いと点灯する](https://lore.kernel.org/lkml/1486856514-9634-1-git-send-email-w@1wt.eu/)

以下のsystemdスクリプトで赤LEDでネットワーク`ip6tnl1`の送受信を表示し、緑LEDでCPU使用を表示するようにできます。

```config:/etc/systemd/systemd/leds.service
[Unit]
After=modprobe@ledtrig_activity.service
After=modprobe@ledtrig_netdev.service
After=network-online.target
Wants=modprobe@ledtrig_activity.service
Wants=modprobe@ledtrig_netdev.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo activity > /sys/class/leds/ACT/trigger"
ExecStart=/bin/sh -c "echo netdev > /sys/class/leds/PWR/trigger"
ExecStart=/bin/sh -c "echo ip6tnl1 > /sys/class/leds/PWR/device_name"
ExecStart=/bin/sh -c "echo 1 > /sys/class/leds/PWR/tx"
ExecStart=/bin/sh -c "echo 1 > /sys/class/leds/PWR/rx"

[Install]
WantedBy=multi-user.target
```
【AWSセキュリティ基礎】AWS Artifact

# AWS Artifactとは
AWSのコンプライアンスドキュメントとAWS契約へのオンデマンドのアクセスを提供するサービス。
以下の2つの機能から成っている。

- AWS Artifact Reports
- AWS Artifact Agreements

## AWS Artifact Reports
サードパーティーの監査人によるAWSの監査レポートのダウンロードサービスで、様々な認証についてのレポートが提供されている。
レポートを利用するためにはAWSとの事業提携契約(BAA)や秘密保持契約(NDA)を受諾する必要があるため、顧客や監査人に提供する際は適切な範囲の文書にアクセス権限を設定して利用することが望ましい。
公開されているレポートの大まかな分類としては、以下のようなものがある。

- ISO認定
- Payment Card Industry(PCI)レポート
- System and Organization Control(SOC)レポート



### 何ができるのか
- Artifact Reportの内容を共有することで、顧客にAWS自体の安全性を説明できる
- 監査を受ける際、セキュリティおよびコンプライアンスを証明する資料として用いることができる

## AWS Artifact Agreements
AWSアカウントとAWS間での契約を確認・受諾・管理したり、過去に受諾した契約が不要となった場合、その契約を終了したりするためのサービス。
AWSの個々のアカウントだけでなく、AWS Organizationsにおいて組織に含まれる全アカウントの契約についても一括して代理で確認・受諾・管理ができる。

### 何ができるのか
- 様々な種類の契約を用意することで、特定の規制の対象となる顧客に対応できる
    - 例えば、Health Insurance Portability and Accountability Act(HIPAA)を順守する必要のある顧客向けに事業提携契約(BAA)が用意されている
    - こういった契約が必要な場合、AWS Artifact Agreementsを使用することで、AWSとの契約を必要に応じて結ぶことができる

- AWS Organizationsに対応しているため、組織の管理するすべてのアカウントにおいて同様の契約を一括で確認・受諾・管理できる。
    - それぞれのアカウントでログインし直す必要がなく、簡単に契約を結ぶことが可能

# 参考

https://aws.amazon.com/jp/artifact/

https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947#
pythonって、な〜に

pythonっていうのは「インタープリタ型の高水準汎用プログラミング言語」(Wikiより)です。
組み込みとかにも使えますが、うp主の知識不足がバレるので、今回はprint(“Hello World”);だけ紹介します。
print(”hello world“);って、なーにって人もいるかもしれませんが、c++で言うcout << “hello world” << endl;と同じような感じ。って言っても結構な確率で初心者には伝わらないので、簡単に言い直します。
え〜「画面にhello worldって打ち込め」。
略するとこんな感じです。
こんな感じでゆっくりと僕の記事は進めさせていただきます。
Runtu(Openbox)における、リモートデスクトップサーバーの設定の方法



# 結論
下記コマンド

```
sudo apt install xorgxrdp xrdp ​xinit 
sudo sed -e 's/^new_cursors=true/new_cursors=false/g' -i /etc/xrdp/xrdp.ini 
sudo sed -e "34i export GTK_IM_MODULE=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "35i export QT_IM_MODULE=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "36i export XMODIFIERS=\"@im=fcitx\"" -i /etc/xrdp/startwm.sh
sudo sed -e "37i export DefaultIMModule=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "38i fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "39i unset DBUS_SESSION_BUS_ADDRESS" -i /etc/xrdp/startwm.sh
sudo sed -e "40i exec openbox-session" -i  /etc/xrdp/startwm.sh
sudo systemctl restart xrdp
```
#解説
## 必要なライブラリのインストール
[こちら](https://qiita.com/faz479704/items/5b992ec81b46a8d911e4)を参考に

## 設定
### カーソルの設定
```
sudo sed -e 's/^new_cursors=true/new_cursors=false/g' -i /etc/xrdp/xrdp.ini
```
これまた、[こちら](https://qiita.com/faz479704/items/5b992ec81b46a8d911e4)を参考に


## リモートセッション開始の設定
```
sudo sed -e "39i unset DBUS_SESSION_BUS_ADDRESS" -i /etc/xrdp/startwm.sh
sudo sed -e "40i exec openbox-session" -i  /etc/xrdp/startwm.sh
sudo systemctl restart xrdp
```
これまた、[こちら](https://qiita.com/faz479704/items/5b992ec81b46a8d911e4)を参考に。
と言いたいところだが、今回はopenboxであり、 cinnamon-sessionではない。

ならば、ということで、cinnamonをopenboxに読み替えて行う

## だが、画面が真っ黒
```
sudo apt install -y xserver-xorg-core xorgxrdp xrdp
```
ここで、[他のサイト](https://orenda.co.jp/blog/1874/)を見てみると
とあるので、xrdp以外で実行

※xserver-xorg-coreは既にインストール済み
##だが、引き続き、画面が真っ黒
```
sudo apt install -y xinit
```
ここで、悶々として、本家ubuntuとapt listでパッケージを比較して、気づいたことが。
#### xinitがない
考えてみれば、描画がうまく行ってないので、X系になにかあるわけで。
Xの起動を担うこやつがあれば、と思い。


##日本語入力
```
sudo sed -e "34i export GTK_IM_MODULE=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "35i export QT_IM_MODULE=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "36i export XMODIFIERS=\"@im=fcitx\"" -i /etc/xrdp/startwm.sh
sudo sed -e "37i export DefaultIMModule=fcitx" -i /etc/xrdp/startwm.sh
sudo sed -e "38i fcitx" -i /etc/xrdp/startwm.sh
```
日本人としての仕上げ。
[こちら](https://jade.alt-area.jp/archives/45)を参考に

# 総括
ディストリはウリに特化する反面、削ぎ落としている面が。
こういったことがあるから、[自分でUbuntuを改造しました](https://docs.google.com/document/d/1poKaJAAzqccWVkKZRAcX3TS14oHL5UqyVYRpYEIFvfs/edit)、という人が続出するのだろう(筆者)。
PowerAutomateのISO8601とシリアル値の相互運用の条件

PowerAutomateのワークフローからOneDriveやSharePointで管理されたExcelのデータにアクセスする場合、日付データについての制約があります。

# Background

PowerAutomateの日付データはISO8601形式の文字列型データ、対してExcelの日付データは1900年1月1日を起点とするシリアル値です。

以前はPowerAutomateからExcelのデータを参照したり更新したりする場合、2つのデータ型の間をフロー開発者が自分自身で取り持ってやる（相互変換してやる）必要がありました。
これをしないと、PowerAutomateの日付データは文字列そののままの内容でExcelに書き出され、Excelの日付データはシリアル値そのままの内容でPowerAutomateに読み込まれてしまうという問題があったのです。

2021年現在「DateTime形式」というオプションが追加され、この問題が改善しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/e220dd8a-4764-4b77-33a8-8027b242d94f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/85552ce3-f86b-3ef5-8bdc-5597b4679979.png)


# Problem

しかしこの「DateTime形式」で `ISO 8601` を選択していても日付データが相互変換されないことがあります。
つまり従来どおり、PowerAutomateの日付データは文字列そののままの内容でExcelに書き出され、Excelの日付データはシリアル値そのままの内容でPowerAutomateに読み込まれてしまうということです。
このような違いはどうして起きるのでしょうか？

# Solution

「DateTime形式」で `ISO 8601` を選択して日付データの相互変換をするには以下の条件をいずれも満たす必要があるようです：

- 列の表示形式が「日付」ないし「時刻」になっていること
- 列の最初の行のデータが日付ないし時刻として妥当な値（ようするにシリアル値）であること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/13ed19c0-36a1-1e7b-1e3b-3630b088180c.png)

例えば、次のテーブルでは `DATE2` ～ `DATE5` はいずれも「表示形式」が「日付」となっています。 `2021/11/14` や `2021/11/15` と表示されている部分はシリアル値が入力されている状態、対して ISO8601形式の日付が表示されている部分は文字列が入力されている状態です：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/2283fe73-c50a-97ae-9b4d-91b56ed19623.png)

「DateTime形式」で `ISO 8601` を選択した状態のアクションを使い、このテーブルからレコードを読み取ったり書き込んだりすると、 `DATE3` や `DATE4` の列は相互変換が行われますが、 `DATE2` や `DATE5` の列は行われません（個別のセルごとに変換の有無が変わるのではなく、条件に該当する列のセルはすべて変換、該当しない列のセルはすべて変換なしになります）。

このように、「DateTime形式」の機能を使う場合は列の「表示形式」だけでなくその列に実際に入力されている値についても考慮する必要があります。
GitHub Actionハッカソンに参加して20万円ゲットしよう！

※2021/11/27 タイトルを『200万円』から『20万円』に修正

[dev.to](https://dev.to/)で2021/11/09から[Join Us for the 2021 GitHub Actions Hackathon on DEV!](https://dev.to/devteam/join-us-for-the-2021-github-actions-hackathon-on-dev-4hn4)というイベントが開催されているので、その紹介です。


# Join Us for the 2021 GitHub Actions Hackathon on DEV!

GitHubの協力により、ここDevで2回目の`GitHub Actionsハッカソン`を開催します。

いまから2021/12/08までの間、GitHubはGitHub Actionsを使ってオープンソースに貢献する絶好の機会を提供します。
GitHub Actionsを使ってどのように素晴らしいワークフローを作り上げたかを、Devに投稿してください。
皆さんの投稿を楽しみにしています。

GitHub Actionsについて、またハッカソンへの参加方法については下記をご覧ください。

## What Are GitHub Actions?

[GitHub Actions](https://github.com/features/actions)は、ソフトウェア開発のワークフローを自動化したりカスタマイズしたりします。
コードを保存したり、仲間と共同開発したり、issueを解決したり、OSSをリリースしたりするのと同じように使うことができます。

今年のハッカソンでは、既存のGitHub Actionsを利用してリアル世界に影響をおよぼすワークフローを推奨しています。
新たにActionsを作ってもかまいませんが、今回のコンテストでは、既存のGitHub Actionsを使ったOSSで利用できる実用的なソリューションに焦点を当てています。

皆さんがこの課題にどのように取り組むか、楽しみにしています。

## Categories

今回のGitHub Actionsハッカソンのカテゴリです。

### Maintainer Must-Haves

OSSのメンテナの生活を楽にする。

### DIY Deployments

OSSプロジェクトのデプロイを楽にする。

### Interesting IoT

IoTのなんかクールなプロジェクト。

### Phone Friendly

iOS/Androidなど、モバイル向けのワークフロー。

### Wacky Wildcards

その他。
奇抜な投稿も歓迎。

## Why Participate?

先月開催したハクトーバーフェストが盛況だったことを受けたものであり、GitHub ActionsがOSSへの素晴らしい入口であることを示したいのです。
GitHub Actionsは、あなたの生活に役立つ論理的なワークフローを作ることもできます。

また、賞品も充実しているので、とっても魅力的だと思いますよ😉


## Prizes

### Grand Prize Winners

カテゴリごとに1名。
・1500ドルのギフトカード
・300ドルのDevショップクレジット
・GitHubグッズ詰め合わせ
・Devのステッカーパック
・Devの"Actions Hackathon 2021"最優秀賞バッジ

### Runner-Up Prizes

合計10名。
・250ドルのギフトカード
・150ドルのDevショップクレジット
・GitHubグッズ詰め合わせ
・Devのステッカーパック
・Devの"Actions Hackathon 2021"優秀賞バッジ

### Participants 

参加賞。
・Devのステッカーパック
・Devの"Actions Hackathon 2021"参加賞バッジ



## How to Participate

参加方法。

[GitHub Actions](https://github.com/actions)には、既に強力なライブラリが転がっています。
そこで今回のハッカソンでは、[既存のActions](https://github.com/marketplace?type=actions)を活用したワークフローを推奨します。
もちろん必要に応じて新しいActionsを作ってもかまいません。

[#ActionsHackathon21](https://dev.to/t/actionshackathon21)タグをつけます。
Devに投稿する際は[テンプレート](https://dev.to/new/actionshackathon21)に従います。

何らかを購入したりする必要はありません。
参加資格は18歳以上です。
公式ルールについては[告知ページ](https://dev.to/page/actions-hackathon-2021-rules)を参照してください。


ぜひ、このチャレンジを楽しんでいってください！

# コメント欄

「Exciting!」
「ありがとうGitHub。」
「真夜中だけどさっそく投稿した！」
「Wacky Wildcardsの応募作を見るのが楽しみ。」
「ここから生まれる素晴らしいプロジェクトに期待。」
「18歳未満なので参加できない😭」
「私にいいアイデアがある。」

# 感想

優秀賞1800ドルって[賞品の桁がちがいすぎる](https://qiita.com/official-events/12fc7bacec894d33a981)。
そもそも日本では技術記事に賞品なんてほとんど出ないからな…

ちなみにQiita Azureの賞品は[何気にけっこう豪華](https://qiita.com/official-events/2578ba1c949d056847df)なんだけど、これ絶対MSから提供されてるよね。
わりと参加者少ないし、意外と狙い目だと思います。

そんなわけで腕と英語力に自信のある方は、GitHub Actionsハッカソンに参加してみてはどうでしょうか。
Anaconda iCloud Driveにアクセス

# ターミナル
## jupyter notebook
cd ~/Library/Mobile*Documents/com~apple~CloudDocs/参照したいフォルダ名

```
// 自分の場合 anacondaフォルダを参照
cd ~/Library/Mobile*Documents/com~apple~CloudDocs/anaconda
```
```
// jupyter notebook開く
jupyter notebook
```
sudoersの#include #includedirはversion1.9.1から@include @includedirとも書ける

`sudoers`で先頭に`#`がついているのにコメントを意味しない設定として。

- #include
- #includedir

という指定したファイル、ディレクトリを`sudoers`ファイルとして読み込む設定があります。

こちらに設定について初見だとなかなか勘違いしやすいパラメータかと思います。
コメントだと思って消したりすると悲惨。

## version 1.9.1以降では`@include` , `@includedir`と書ける

タイトルに書いてあるとおり、こちらの設定については`version 1.9.1`以降ならば、`#`の代わりに`@`で記述できます。
（`sudoers 1.9.1`以降のドキュメントを読んでいて気が付きました。）

[suders - Including other files from within sudoers](https://www.sudo.ws/man/1.9.1/sudoers.man.html#Including_other_files_from_within_sudoers)

例としては下記のように記載できます。

- `@include`
- `@includedir`

# 総評

`#`はコメント行と見間違える可能性があったりするのでなるべく、`@`で書いたほうがいいのか？　とは少し考えますが。
`@`は`@`でそれともそもそもこれなに？　といった疑問が発生してしまいそうに思います。

それでも？　`#`のコメントと見間違えるのよりかはマシなのかも？　と言った所。

ともかく`@include`、`@includedir`の設定を見かけても、`version 1.9.1`から利用できるやつですね。　と知ってれば焦らないで済むので`sudoers`をさわる際には抑えておきたいポイントかと思います。
PHPでアップロードできるファイルの上限値を変更する

# 背景
PHP×nginxの案件でファイルをうまくアップロードできないことがあり、アップロードする際に許容上限に引っかかっていることが判明。
PHPとnginxの設定をそれぞれ変更してあげる必要があったので、その手順を記載。

# PHPの設定を変更

## PHPの設定を確認
まずはphpinfo()でPHPの設定を確認。
以下内容のファイルをブラウザで表示できる任意のディレクトリ下に設置して、PHPの設定を確認。

```phpinfo.php
<?php
phpinfo();
```

phpinfoが開かれたら、下記５項目の設定値を確認。

①file_uploads
　ファイルのアップロードの有効/無効（※Onで有効）
②max_file_uploads
　一度にアップロードできるファイル総数
③memory_limit
　メモリ上限
④post_max_size
　一度にアップロードできるファイル合計サイズ
⑤upload_max_filesize
　１ファイルの容量上限

※それぞれの詳細な説明は[PHPマニュアル](https://www.php.net/manual/ja/ini.core.php#ini.sect.file-uploads)で確認をお願いします。

## PHPの設定を変更
今回は`upload_max_filesize`（１ファイルの容量上限）の設定が原因だったのでここの値を変更。（※デバック方法は最後の[補足](#補足)に記載してます。）
今回はphp.iniを直接編集して設定を変更。

```php.ini
upload_max_filesize = 8M
```

ここで注意なのが、公式マニュアルに下記のようなメッセージがあるので要チェック。
> ・一般的に memory_limit は、 post_max_sizeよりも大きくする必要があります。 
> ・post_max_size には、 upload_max_filesizeより大きな値を指定しなければいけません。

つまり、

:::note warn
memory_limit　>　post_max_size　>　upload_max_filesize
:::
の関係になるように値設定が必要。


## PHPの設定を反映
php.iniを変更した後は、設定を反映させるためにphp-fpmを再起動。

```
sudo systemctl restart php-fpm
```

php-fpmを再起動後、phpinfoで変更した値が反映されていればOK。


# nginxの設定を変更
PHPの設定を変更して、いざアップロード！
しかし未だにアップロードがうまくできず、、、

調べた結果、nginxの設定も変更が必要みたい。

## nginxで許容するアップロードサイズ
[nginx公式](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size)によると、 nginx ではデフォルトで1MBまでのファイルしか受け付けない設定になっているよう。

nginx で1MBより大きなファイルをアップロードできるようにするには、 confファイルに client_max_body_size ディレクティブを設定。

```hoge.conf
server {
    listen       80;
    server_name  localhost;

    client_max_body_size 8M;

    location / {
    ・・・

```

## nginxの設定を反映
confファイルを変更した後は、設定を反映させるためにnginxを再起動。

再起動する前に記述に誤りがないか確認。
設定ファイルに問題がなければ、以下のように表示されます。

```
nginx -t
> nginx: the configuration file /etc/nginx/hoge.conf syntax is ok
> nginx: configuration file /etc/nginx/hoge.conf test is successful
```

設定ファイルに問題がなければnginxを再起動。

```
sudo systemctl restart nginx
```

これで無事にアップロードできるようになった…！

# 補足
今回の記事の内容とは逸れるので、最後にファイルアップロード時のデバックについて記載。

ファイルのアップロードに失敗した際、PHP側でエラーコードが返されるので、それを参考にすると原因が分かりやすい。

今回、`$_FILE`の値をみるとこうなってた。

```
Array
(
    [0] => Array
        (
            [name] =>
            [type] =>
            [tmp_name] =>
            [error] => 2
            [size] =>
        )
)
```


[公式マニュアル](https://www.php.net/manual/ja/features.file-upload.errors.php)より、エラー番号2(アップロードしたファイルがMAX_FILE_SIZE を超えている)が返ってきているので、
アップロードしようとしたファイルサイズが設定値を超えていることが判明しました。
PHPで配列を関数の返り値として使ってみましょう！

#関数の返り値に配列を渡す
<br>
返り値を配列にして仮引数に渡します。

以下の sum 関数があったとします。
<br>

```php:index.php
<?php
function sum(...$numbers) {
  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return $total;  //返り値
}
print_r(sum(1, 2, 3));
```

<br>
ターミナルに以下を入力します。
<br>

```
~$ php index.php
```

<br>
合計が出力されました。
<br>

```
~ $ php index.php
6~ $ 
```

<br>
３つの合計の平均値も一緒に出力されるように、

返り値を配列にします。

３つの合計値と、　合計値を個数で割るようにします。
<br>

```php:index.php
<?php
function sum(...$numbers) {
  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return [$total, $total / count($numbers)];   //返り値を配列にする
}
print_r(sum(1, 2, 3));
```

<br>
ターミナルに以下を実行します。
<br>

```
~$ php index.php
```

<br>
３つの合計値と平均値が出力されました。
<br>

```
~ $ php index.php
Array
(
    [0] => 6
    [1] => 2
)
~ $ 
```
【Rails 】Dockerで使用したコマンド集


## 用語
| 名称 | 説明 |
|:-:|:-:|
|Dockerエンジン|Dockerにおいてコンテナ型仮想化を実現するためのコア|
|  Dockerコンテナ | Dockerイメージをもとに作成されるコンテナ型仮想環境  |
|  Dockerイメージ |  Dockerコンテナ作成時に必要な雛形となるもの。できたアプリケーションをイメージとして保存して、別のサーバーでも同じ環境を再現できる。|
|  Dockerfile |  Docker イメージをビルドする為の手順を記載するファイル|

#コマンド

## Dockerコンテナの起動、構成、Dockerイメージの作成まで一気に実行＋（Gemfile変更時）

```
docker-compose build
```

## コンテナ起動

```
docker-compose up

#バックグラウンドでコンテナ起動
docker-compose up -d
```

## コンテナ停止

```
docker-compose stop
```
## コンテナ削除

```
docker-compose down
```
## コンテナ再起動

```
docker-compose restart
```
##全てのログ表示

```
docker-compose logs
```

##コンテナ一覧を表示
```
docker ps
docker ps -a  #停止中も含めたコンテナ一覧表示
```
##イメージ一覧を表示
```
docker images
```
## イメージの取得
```
docker pull イメージ名[:タグ名]
```
##イメージ削除
```
docker rmi イメージ_id 
docker rmi -f イメージ_id　　 #強制削除
```

##コンテナ削除
```
docker rm コンテナ_id
```

#Rails コマンド
####モデル作成
```
docker-compose run web bundle exec rails g model モデル名　カラム名
```
####マイグレーション実行
```
docker-compose exec web bundle exec rake db:migrate
```
####コントローラー作成
```
docker-compose exec web rails g controller コントローラー名
```
####データベース削除
```
docker-compose run web bundle exec rake db:drop
```
####ロールバック（１つ前に戻る)~STEPで指定可
```
docker-compose run web bundle exec rake db:rollback
docker-compose run web bundle exec rake db:rollback STEP=○
```

####データベースリセット
```
docker-compose run web bundle exec rake db:migrate:reset
```
###シード
```
docker-compose run web bundle exec rake db:seed
```
####ルーティング確認

```
docker-compose run web bundle exec rake routes
```

# binding pry

```
docker attach　コンテナ名_web_1  #アタッチ

#アタッチしたコンテナから抜ける
Ctrl+P, Ctrl+Q　
```

# Rspec(Gemfile記述後)

```
docker-compose run web bundle exec rails g rspec:install

docker-compose exec web bundle exec rails g rspec:model　モデル名

docker-compose exec web bundle exec rspec -f d spec/models/モデル名_spec.rb　　　#ドキュメント形式で表示
```

## Docker Hubにログイン
```
docker login 
```
###イメージタグ設定
```
docker tag イメージ名　ユーザー名/イメージ名:タグ名
docker tag sample_web taro/sample_web:ver1
```
###dockerコミット
```
docker commit コンテナ名　またはコンテナID イメージ名：タグ名
```
### dockerプッシュ
```
docker push ユーザー名/イメージ名:タグ名
docker push taro/sample_web:ver1 
```
#MySQL
```
docker-compose ps  #起動中のコンテナ名確認

docker exec -it DBコンテナNAME  bash  #DBコンテナに入る

mysql -u root -p  #mysqlへ接続(パスワードはdocker-compose.ymlに記載したもの)
Enter password: 

show databases;　　#データベース確認

use　データベ-ス名;　　#使用したいデータベースに切り替え

show tables;　　#テーブル確認

describe テーブル名複数系;　　#テーブルの構造確認

select * from テーブル名複数系;　　#テーブルの中身確認 
```


##起動時にエラーが出た場合、サーバーpidが残っている場合(exit１が発生）
=> Booting Puma
web_1  | => Rails 5.0.0.1 application starting in development on http://0.0.0.0:3000
web_1  | => Run rails server -h for more startup options
web_1  | A server is already running. Check /app/tmp/pids/server.pid.
web_1  | Exiting


```
rm -f tmp/pids/server.pid
```
Jenkins slave nodeの追加

#事前準備
masterノード: 1台のAWS EC2インスタンスを作成しておく。
slaveノード: 1台のAWS EC2インスタンスを作成しておく。

# slaveノードの配置

```
sudo yum update
sudo amazon-linux-extras install java-openjdk11
java
sudo useradd -d /var/lib/jenkins jenkins
sudo grep jenkins /etc/passwd
sudo su - jenkins
cd /var/lib/jenkins
mkdir .ssh
mkdir work
cp /home/ec2-user/.ssh/authorized_keys /var/lib/jenkins/.ssh/
chmod 600 /var/lib/jenkins/.ssh/authorized_keys
chmod 700 /var/lib/jenkins/.ssh
```

# Jenkins web uiでslaveノードの追加と接続
<1>masterノードから、slaveノードにsshで接続する用credentialの作成
username: jenkins
ssh private key: kp1.pemの中身をコピーし、入力し、保存する

![Screen Shot 2021-11-15 at 19.09.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/7de0e45d-044b-eb30-87dc-57ee9aa88853.png)

<2>slaveノードを追加する
![Screen Shot 2021-11-15 at 19.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/7b9bf7af-a905-8de7-6d8d-a01904864629.png)

![Screen Shot 2021-11-15 at 19.10.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/d487d860-07fb-01be-70de-4c60be40725a.png)

![Screen Shot 2021-11-15 at 19.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/c372bb6b-6a53-f1dc-12cf-e13e03de39bd.png)

<3>slaveノードを確認する。

```
[ec2-user@ip-172-31-40-72 ~]$ sudo ls -la /var/lib/jenkins
total 20
drwx------  5 jenkins jenkins  121 Nov 15 03:16 .
drwxr-xr-x 31 root    root    4096 Nov 15 02:47 ..
-rw-------  1 jenkins jenkins  194 Nov 15 03:10 .bash_history
-rw-r--r--  1 jenkins jenkins   18 Jul 15  2020 .bash_logout
-rw-r--r--  1 jenkins jenkins  193 Jul 15  2020 .bash_profile
-rw-r--r--  1 jenkins jenkins  231 Jul 15  2020 .bashrc
drwxrwxr-x  3 jenkins jenkins   17 Nov 15 03:16 .cache
drwx------  2 jenkins jenkins   29 Nov 15 02:51 .ssh
drwxrwxr-x  3 jenkins jenkins   42 Nov 15 03:16 work
[ec2-user@ip-172-31-40-72 ~]$ sudo ls -la /var/lib/jenkins/.ssh
total 4
drwx------ 2 jenkins jenkins  29 Nov 15 02:51 .
drwx------ 5 jenkins jenkins 121 Nov 15 03:16 ..
-rw------- 1 jenkins jenkins 385 Nov 15 02:51 authorized_keys
[ec2-user@ip-172-31-40-72 ~]$ sudo ls -la /var/lib/jenkins/work
total 1476
drwxrwxr-x 3 jenkins jenkins      42 Nov 15 03:16 .
drwx------ 5 jenkins jenkins     121 Nov 15 03:16 ..
drwxrwxr-x 4 jenkins jenkins      34 Nov 15 03:16 remoting
-rw-rw-r-- 1 jenkins jenkins 1507813 Nov 15 03:16 remoting.jar
[ec2-user@ip-172-31-40-72 ~]$ 
```
PHPで可変長引数を使ってみましょう！

#可変長引数
<br>
渡された引数が何個になっても処理してくれる可変長引数を、

foreachと一緒に使います。

以下の sum 関数があったとします。

引数に可変長引数の 「 ... $ numbers 」を入れておきます。

foreach で $numbers の中身を一つづつ取り出して、

$total にプラスしていきます。

$total　　を ...$numbersの仮引数に返します。

<br>

```php:index.php
<?php
function sum(...$numbers) {
  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return $total;
}
echo sum(1, 2, 3) . PHP_EOL;
echo sum(4, 5, 6, 7) . PHP_EOL;
```

<br>
echo sum (1,  2,  3)  .  PHP_EOL ;  で実引数を渡します。

echo sum (4,  5,  6,  7)  .  PHP_EOL ; で個数を変えて実引数を渡してみます。

ターミナルで以下を実行します。
<br>

```
~$ php index.php
```

<br>
計算結果が出力されました！
<br>

```
~ $ php index.php
6
22
~ $ 
```
NuxtJS における vue.config.errorHandler と Sentry(nuxt/sentry module) について

```nuxt.config.json
export default {
  ...(いろいろ),
  vue: {
    config: {
      errorHandler: (err, vm, info) => {
        console.log("Logged in Vue global error handler___________________________", err, vm, info);
      },
    },
  }
}
```


`errorHandler` を自前で定義すると、sentry の設定(`errorHandler`)を上書きしてしまい、Sentry へ情報が送られない、という記事を見ました。
しかし、
NuxtJS + nuxt/sentry (nuxt-module) を使う限りにおいて、上記の記述では問題なく Sentry へエラー情報が送られるようでした。


Sentry は `render:errorMiddleware` を使っている様です [source](https://github.com/nuxt-community/sentry-module/blob/v4.0.3/lib/module.js#L151)
AzureユーザーマネージドIDを使ったVM→Blobへのアップロード

以前、[AzureシステムマネージドIDを使ったVM→Blobへのアップロード](https://qiita.com/shingo_kawahara/items/38bfb2d0351288a9c484) を書きましたが、それだと複数ストレージアカウントに対応できませんでした。
ユーザーマネージドIDを使って、1つの仮想マシンで複数のBLOBストレージにアップロードしてみます。

# ユーザー割り当てマネージドID作成
* Azure Portalより[マネージドID]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/0bd48753-3e52-d771-fa0b-1c9d3728a1c0.png)

* [作成]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/868d1809-bced-0e45-becf-11f12dc400e6.png)

* [リージョン]、[名称]を入力し作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/af647b3b-2347-7796-4730-8ba4ffb2049d.png)

* 作成できたらマネージドIDの概要ページにいき、[クライアントID]をメモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/50ff2e8a-26b8-6c24-7694-85807f564d33.png)

# VMにユーザー割り当てマネージドIDを追加する
* アクセス元となるAzure VMで、[ID]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/b6f80a78-9146-04c3-0c0a-8071060437ec.png)

* [ユーザー割り当て済み]→[追加]の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/81e829d9-7e0d-05fa-f75a-9392cb4cffb7.png)

* 先ほど作成したユーザー割り当てマネージドIDが出てくるはずなので、選択して追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/db1d3752-2d44-e958-8d3e-d414329e0b8a.png)

# StorageAccountへのロール割り当て
* アップロード先のStorageAccountのIAMを選択、[追加]→[ロールの割り当ての追加]の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/b552f284-1132-ee20-703b-00c7f4b1fed9.png)

* [ストレージBLOBデータ共同作成者]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/394173ab-e142-3edf-12ee-fdb926480275.png)

* アクセスの割り当て先を[マネージドID]に変更し、[メンバーを選択する]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/7a4cc000-2f91-402b-b8bc-1b861b30e5f3.png)

* [ユーザー割り当てマネージドID]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/02772a55-eaa7-549b-e63f-5c41e4658ac9.png)

* 先ほど作成したユーザーマネージドIDを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/fd9b39da-1e4c-2031-b799-c97c832b3156.png)

* [条件]は特に設定不要なので、この状態で権限追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/4e7f735d-7926-c953-84ba-d64ee470c607.png)

* ロールの割り当て欄がこのような形になればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/2b1fea5b-f914-9ed5-8b64-06894660fa32.png)

* アップロード先StorageAccountが複数ある場合はそちらも同じようにロール割り当てします。

# Azure PowerShell インストール
ここからはWindows Serverでの操作になります。

* Azure PowerShellがインストールされていない場合は、 [Azure PowerShell をインストールする](https://docs.microsoft.com/ja-jp/powershell/azure/install-az-ps?view=azps-2.8.0) を参考にインストールします。

## Blobアップロード
* ユーザーマネージドIDを使ってログインします。

```powershell
Connect-AzAccount -Identity -AccountId [事前にコピーしたクライアントID]
```

* ストレージコンテキストを取得します。

```powershell
$ctx = New-AzStorageContext -StorageAccountName "ストレージアカウント名" -UseConnectedAccount
```

* ファイルアップロードします。

```powershell
Set-AzStorageBlobContent -File "ソースファイル" -Container "ストレージBLOBのコンテナー名" -Context $ctx
```

* ストレージコンテキスト取得部分でストレージアカウント名を切り替えることで複数ストレージアカウントにアップロード可能です。

以上
PHPで配列の中の配列にアクセスしましょう！

#配列の中の配列
<br>
配列を、他の配列の中で使ってみます。

以下の配列があったとします。

 $scores の配列の中に、 $numbers配列を入れています。

<br>

```php:index.php
<?php
$numbers = [4, 5];

$scores = [
  1,
  2,
  3,
  $numbers,
  6,
];

print_r($scores);
```

<br>
ターミナルに以下を入力します。
<br>

```
~$ php index.php
```

<br>
配列の中に配列が入った状態で表示されます。
<br>

```
~ $ php index.php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => Array
        (
            [0] => 4
            [1] => 5
        )

    [4] => 6
)
~ $ 
```

<br>
そのまま連続で入れ込みたい場合は、

配列の前に 「 ... 」 をつけます。
<br>

```php:index.php
<?php
$numbers = [4, 5];

$scores = [
  1,
  2,
  3,
  ...$numbers,
  6,
];

print_r($scores);
```

<br>
ターミナルで以下を実行すると...
<br>

```
~$ php index.php
```

<br>
連続で表示されました！
<br>

```
~ $ php index.php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
)
~ $ 
```

<br>
配列の要素にアクセスしてみます。

以下の配列があったとします。

$numbers 配列の中にさらに配列を入れています。

echo  $scores [ 5 ] [ 1 ]　で配列を呼び出します。

<br>

```php:index.php
<?php
$numbers = [
  4,
  5,
  [10, 20],
  ];

$scores = [
  1,
  2,
  3,
  ...$numbers,
  6,
];

echo $scores[5][1] . PHP_EOL;
```

<br>
ターミナルで以下を実行します。
<br>

```
~$ php index.php
```

<br>
$scores の5番目の配列の中の1番目が取り出されました！
<br>

```
~ $ php index.php
20
~ $ 
```
C#のWindowsフォームアプリでTextBoxを継承して作ったオリジナルのTextBoxが使えない

#概要
C＃のWindowsフォームアプリで既存のTextBoxを継承して、オリジナルのTextBox作ってFormに配置しようとしたのにツールボックスに表示されない、表示されて配置しようとしても`「ツールボックス アイテム‘TextBoxEx’ の読み込みに失敗しました。アイテムはツールボックスから削除されます。」`となってしまって困りました。

#解決策
オリジナルのTextBoxを作成したら、次に`開始`をクリックしてアプリを終了させることで、ツールボックスに表示されてFormに配置できるようになります。

#作成～配置までの手順
##オリジナルTextBoxの作成
`TextBoxEx`という名前でクラスを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/b96b69d5-1307-56d0-3769-0e9be1ab00bb.png)

##TextBoxExのコーディング
TextBoxからカーソルが離れたらTextBoxの背景を赤にする

```C#:TextBoxEx.cs
using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp6
{
    public sealed class TextBoxEx : TextBox
    {
        protected override void OnLeave(EventArgs e)
        {
            this.BackColor = Color.Red;
            base.OnLeave(e);
        }
    }
}
```

##アプリを開始して終了する
するとツールボックスにTextBoxExが表示されて、Formへ配置できるようになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/56e856e8-cda0-d383-07a1-918920ce0943.png)

#おわり
少しハマった
Amazon linux上のJenkinsインストール


# 事前準備
1台のEC2インスタンスを用意しておく。
![Screen Shot 2021-11-15 at 18.35.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/0034f50a-feb1-b16a-2940-ca21f641cd2a.png)

security groupを設定しておく。
![Screen Shot 2021-11-15 at 18.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/a9a8dc4a-8cb7-b688-1a5e-634503cf98f0.png)

#1. jenkinsをインストールする

```
sudo yum update
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum upgrade
sudo amazon-linux-extras install epel-release
sudo amazon-linux-extras install java-openjdk11
java
sudo yum install java-11-openjdk-devel
javac
sudo yum install jenkins
sudo systemctl daemon-reload
sudo systemctl start jenkins
sudo systemctl status jenkins
```

参照：
https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos

#2. jenkins web uiにログインする
Administratorの初期パスワードを取得しておく。

```
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
```

#http://xx.xx.xx.xx:8080にアクセスする
![Screen Shot 2021-11-15 at 9.30.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/d32eb43d-bdca-201d-49a5-9c5947139d46.png)

![Screen Shot 2021-11-15 at 9.31.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/8f431b06-fd02-6bb8-4fbd-e7af658de120.png)

![Screen Shot 2021-11-15 at 9.32.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/e03f7ae1-2808-84d2-4ed0-83c774488a21.png)

![Screen Shot 2021-11-15 at 9.34.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/1955d125-8255-882a-fbd8-6625fc66ec11.png)

![Screen Shot 2021-11-15 at 9.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/d66856cb-95fc-b45b-3917-80f47c1213fc.png)

![Screen Shot 2021-11-15 at 9.37.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/d8272db6-2f80-e4b7-cda5-4b83ad31db54.png)

![Screen Shot 2021-11-15 at 9.38.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/eed7d9ec-e030-bf89-ae5a-09fdfc402266.png)

![Screen Shot 2021-11-15 at 9.38.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/b16b7e52-315d-ed3e-b2cb-9ef4a358e393.png)

![Screen Shot 2021-11-15 at 9.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289758/ca290152-e741-5cf6-f247-2227f857f9b6.png)
Ubuntu20.04にて、homebrewをインストールする

#はじめに
homebrewをインストールするまでの道のり。
![Image from iOS-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/4acf3535-4fdc-5555-ad7b-4edf76dc8905.jpeg)


# 最終更新日
2021年11月15日

# 環境の情報
OS
Ubuntu20.04


# 注意
最新の状態を確認して下さい。

# 公式はこちら
https://brew.sh/

# 実際に作業をしていく
![Screenshot from 2021-11-15 12-04-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/9df64938-cd56-da8c-4289-2d0a7d8023b6.png)
こちらが公式さまのサイト。（色々、変わっているかもしれない）

一杯やりたくなる（うるさいな）このサイトのちょっと下

![Screenshot from 2021-11-15 11-59-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/fec8a09c-56e0-6aa5-4ef0-fe415d3545fe.png)


```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

こちらにコピーする個所があります。
ここをコピって、端末にて、実行します。


![ぶりゅーこぴー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/0fda1cff-2818-e583-f8d0-4addbd4d1ac5.png)
こんな感じになります。

```
[sudo] user のパスワード:
```
PCにログインする時のパスワードを入れます。

```
Press RETURN to continue or any other key to abort:
```
Enterを押します。


#で、実行すると、なんかいろいろでる

```
==> Tapping homebrew/core
remote: Enumerating objects: 1094128, done.
remote: Counting objects: 100% (82/82), done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 1094128 (delta 45), reused 65 (delta 29), pack-reused 1094046
Receiving objects: 100% (1094128/1094128), 420.74 MiB | 5.71 MiB/s, done.
Resolving deltas: 100% (754292/754292), done.
From https://github.com/Homebrew/homebrew-core
```

このへんで時間かかるのでお待ち下さい。


```
######################################################################## 100.0%
==> Installation successful!
```
こんな感じになっていれば、インストール出来ているかと思います。

# しかし、パス通っていない（かなしみ）
```
==> Pouring portable-ruby-2.6.8.x86_64_linux.bottle.tar.gz
Warning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
==>ポータブルを注ぐ-ruby-2.6.8.x86_64_linux.bottle.tar.gz
警告：/home/linuxbrew/.linuxbrew/binがPATHにありません。
```

```
brew
コマンド 'brew' が見つかりません。もしかして:
  command 'brec' from deb bplay (0.991-10build1)
  command 'qbrew' from deb qbrew (0.4.1-8build1)
次を試してみてください: sudo apt install <deb name>
```
brewさんは、いらっしゃらないので、実行できない。


```
==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
```
こちらへ出ている、これをしなくちゃ動かない。


```
echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```
パスちゃんを通します。


```
brew
Example usage:
  brew search TEXT|/REGEX/
  brew info [FORMULA|CASK...]
  brew install FORMULA|CASK...
  brew update
  brew upgrade [FORMULA|CASK...]
  brew uninstall FORMULA|CASK...
  brew list [FORMULA|CASK...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA|CASK

Contributing:
  brew create URL [--no-fetch]
  brew edit [FORMULA|CASK...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh
```
OKです。動くようになりました。

# 参考さま
https://qiita.com/jun3030/items/afcd3287285a57b32ccb
GithubにSSHキー登録する手引き

# まえがき
GithubのSSHの設定を教える機会が何度かあったので記事として残しておこうと思い筆を取りました．
メモ書き程度ですが利用していだだけたら幸いです．

# ①公開鍵・秘密鍵を作る
1. .sshディレクトリに移動  

``` bash
$ cd $HOME/.ssh/
```  
1. キー生成  

```bash
$ ssh-keygen -t ed25519
```  
1. キーの名前を入力  
デフォルトは`id_ed25519`  
鳩屋敷は`id_<サービス名>_ed25519`で統一(あくまで一例)  

```
Enter file in which to save the key (/home/hato_yashiki/.ssh/id_ed25519): (ここで入力)
```
ちなみにpathを含めた命名になるためフルパスで指定すれば始めの`cd`はいらなかったりする．
入力し終えたらプロンプトが返ってくるまで全部エンターで良し．(公開鍵を使うためのパスワードが設定できる．気になる人は設定してもいいかも)

# ②公開鍵をGithubに登録
1. 公開鍵のコピー  
`cat`でさっき作ったキーの公開鍵(拡張子が`.pub`のファイル)の中身を見て，コピーしておく．
1. Githubを開く  
Githubで自分のページの`Settings`を開き，`SSH and GPG keys`を開く．
1. 公開鍵の登録  
`New SSH key`ボタンを押し，`Key`に先ほどコピーした公開鍵を貼り付ける．  
`Title`はなくてもいいが，どのPCのどのターミナルのものか，わかるよう命名しておく方が身のため．
`Add SSH Key`を押して登録．

# ③`config`ファイルの設定
```conf
Host github.com
    Identityfile ~/.ssh/<さっき作成した秘密鍵(拡張子はいらない)>
    User git
```
上記の内容を`~/.ssh/config`に記述してください。vimでもvscodeでもechoでもメモ帳でも何で記述してもOKです。

# ④SSH疎通の確認

```bash
$ ssh -T git@github.com
```
ちゃんと`config`ファイルができていれば

```
Hi <ユーザー名>! You've successfully authenticated, but GitHub does not provide shell access.
```
と返ってくるはず．
これでユーザーネームとかパスワードとかトークンとか気にせずに

```bash
$ git clone git@github.com:UserName/Repository.git
```
とかのコマンドが叩けるわけですね．

# おまけ
```bash
$ git remote get-url origin
```
を叩くとoriginのURLが取得できる．これがHTTPSのURLだとSSH通信でpushやpullができない．
GithubからSSH用のURLをコピーしてoriginのURLを更新する必要がある．

```bash
$ git remote set-url origin <ssh用のURL>
```
これでpushやpullも問題なく行えるはず．

また別途SSH通信ができない場合はおまけに追記していくかも．
npmでパッケージをインストールしようとしてもnode_modulesフォルダーが作成されずインストールされない件の対処法



<p>テキスト通りにやっても無反応でしたが、node_modulesフォルダーをエクスプローラー上で予め作成してから
npm install ejs することでなぜか解決しました</p>

対処法というより対処療法

参考文献　node.js超入門　第3版　85p
【Rails】定数の呼び出し方

##環境
Ruby 3.0.2
Rails 6.1.4.1

##定義と呼び出し方

```ruby
class Hogehoge
  TARGET_ARTICLES_COUNT = 100.freeze
end
```

```ruby
Hogehoge::TARGET_ARTICLES_COUNT
# => 100
```


他のクラスやモジュールで定義された定数を参照するには```::演算子```を使って定数のパスを指定。
トップレベルの定数を確実に参照するにはパスを```::```から始めると外部の定数を絶対パスで指定できる。



##参考

https://railsguides.jp/constant_autoloading_and_reloading.html
pdfのdecrypt

pdfminerを使用する際、Encyptされているpdfをそのまま入力するとエラーが出るので、事前にdecryptしておく必要がある。
パスワードが存在する場合は　```--password=パスワード```　とする。

```python:decrypt_pdfs.py
import glob 
import os
from subprocess import call

encrypted_files = glob.glob(pdf_directory)
for file in encrypted_files:
    pdf_filename = os.path.basename(file)
    out = "./decrypted_PDFs/" +pdf_filename 
    call('qpdf --password=%s --decrypt %s %s' %('', file, out), shell=True)
```
Airtestでほぼ円状にスワイプしてみる

#先にコードを掲載
<details><summary>ほぼ円状にスワイプ</summary><div>

```Swipe_in_an_almost_circle.py
# -*- encoding=utf8 -*-
from airtest.core.api import *
import math

'''
x , y はスマホ内の座標
radiusは描く円の半径距離
'''

x , y = 540 , 1110
radius = 300

list = []
for i in range(39):
    tuple = (x + math.sin(i/6) * radius),(y + math.cos(i/6) * radius)
    list.append(tuple)
    

device().maxtouch.swipe_along(list,duration=0.02, steps=3)
```
</div></details>


#Airtestってなんだ？
画像認識やUIの階層化により、ゲームテストをサポートする自動化フレームワークです。
簡単に言ってしまえば、画像認識を主とする自動化ツールという認識で問題ないです。

スマホの操作を主とする画像認識ベースのテスト自動化ツールを使うのであれば、
執筆時21/11/16時点では、Airtestの選択がベターな選択になると思います。

詳細についてはこのQiitaの記事がまとまっていてとても良いです。
https://qiita.com/Nitudon/items/0c5c527841388fec22ed

ドキュメント
https://airtest.doc.io.netease.com/en/

リファレンス
https://airtest.readthedocs.io/en/latest/index.html


#実際に実行するとこうなる
![ダウンロード (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2287682/7c897e42-eca2-407f-36c9-d578fd7722b1.gif)

#何故この記事を？
~~お蔵入りしているコードの共有でええええす！！~~
AirtestのスワイプはAssistantやリファレンス上の機能を確認するだけだと
直線でのみのスワイプしか想定されないので、
簡単な計算を元に曲線も描けるということを伝えたかった。

ADBで動いているというのもあり、記述次第で意外と器用な挙動もできるので
Airtest、色々と試してみてはいかがでしょうか。

テスト中、特定のオブジェクトをスワイプで囲みたいという時に使用すると良いと思います。
ゲームで使用する場合はクイックスのような囲んで陣地を取るゲームや、
特定のキャラクターを囲むと挙動が発生するテストがあれば使用する場合があると想定されます。

#注意点
・スマホ1台接続での実行を想定したコードになります。
nav varのテンプレート

```php
    <nav class="navbar navbar-expand-sm navbar-dark bg-dark">
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav4"
                aria-controls="navbarNav4" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <a class="navbar-brand font-weight-bold" href="#">あ</a>
        <div class="collapse navbar-collapse">
            <ul class="navbar-nav">
                <li class="nav-item active">
                    <a class="nav-link" href="#">い</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">う</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">え</a>
                </li>
            </ul>
//右寄せしたい部分だけulを分けて、ml-autoを追加する
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <button type="button" class="btn btn-outline-light">ログアウト</button>
                </li>
            </ul>
        </div>
    </nav>
```

#改訂版

レスポンシブルに対応

```php
    <nav class="navbar navbar-expand-md navbar-dark bg-dark">
        <a class="navbar-brand text-white">グローバルメニュー</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav4"
                aria-controls="navbarNav4" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav4">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active">
                    <a class="nav-link">a</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link">b</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link">c</a>
                </li>
            </ul>
        </div>
    </nav>
```