OmniAICreator/Qiita-1.07M huggingface dataset:
プルリクエストの作成を自動化したい

# 背景
チーム開発で有用なPR機能だが、定型作業なのに手動で進めるのは地味に時間の浪費となっている。
開発がひと段落ついたらチャチャっとPR作成してしまいたい

# 利用する便利ツール
githubのコマンドラインインターフェース:[gh](https://cli.github.com/)


# 準備
* ghコマンドの有効化→[参考(Qiita)](https://qiita.com/KEINOS/items/d5da8c154cfb97336e3c#tl-dr-%E4%BB%8A%E5%8C%97%E7%94%A3%E6%A5%AD)

# 自動でPull Requestを立てる
<b>前提</b>
* ghコマンドを使用できる状態
* 開発はマージ先と別のブランチで行われている
* 開発が終わってコミットまで済んでいる

パラメータを対話型で入力する場合

```bash
#!/bin/bash

# ログイン状態のチェック
gh auth status 2> temp_github_auth
check_auth=`wc -l temp_github_auth |awk '{print $1}'`
rm temp_github_auth

if [ $check_auth = "1" ];then
    trap "stty echo; exit 1" 2
    stty -echo
    echo "Insert your github Token. (Now you are not logged in to github.)"
    read -p "Github Token: " pass
    echo $pass > tmp_token_github
    gh auth login -h GitHub.com --with-token < tmp_token_github
    rm tmp_token_github
    stty echo
fi

# create Pull Request
echo "Set reviewer?"
read reviewers
echo "which branch do you merge into?"
read target_branch
echo "input description if you have"
read body
echo "input the title of your PR"
read pr_title
gh pr create -r $reviewers -B $target_branch -b $body -t "${pr_title}"
```

このスクリプトを実行すると、ghコマンドの機能として対象のリポジトリに直接操作あるいはforkして操作などの選択肢が出る場合があります。
実際にPRを作成するときは、「続いて何をしますか？」という質問に"submit"(提出)を回答すると実際にPRが作成されます。

このスクリプトですが後半部分をハードコーディングした形にすると対話の手間を減らすこともできます。

```bash
# create Pull Request
reviewers="hoge,fuga,hogehoge"
target_branch="xxxxxxx"
body="This PR aims ......"
pr_title="fix bug"
gh pr create -r $reviewers -B $target_branch -b $body -t "${pr_title}"
```

パラメタを別ファイルから読み出すのもいいかもしれません。

# 最後に
地味な自動化ですが、チリも積もればなんとやら。みんなで何回も使うものを自動化する価値は高いです。
他にもghコマンドを使ってマージやラベル付与も自動化できるのでエンジニアが開発とレビューに専念出来る環境作りに有用です
この記事は[こちらの記事](https://qiita.com/ryokat3/items/d054b95f68810f70b136)を参考に作成しました。自動化ツール、すばらしい。
「ホワイトボード面接を行わない企業リスト」Hiring Without Whiteboards

## Hiring without Whiteboards 

- 「ホワイトボード面接を行わない企業リスト」。
- ホワイトボード面接 = いわゆるコーディングテスト的面接
- 作ったのは Lauren Tan という現在 Facebook (Meta) でソフトウェアエンジニアをやっている方


https://github.com/poteto/hiring-without-whiteboards

> "ホワイトボード"面接を行わない企業（またはチーム）のリストです。"ホワイトボード "は比喩で、悪い面接方法に関連するCS的トリビアの質問の種類を象徴しています。ホワイトボードは悪いものではなく、CS的トリビアを問うその質問が悪いのです。HackerRankやLeetCodeのようなサイトを使うことも、おそらく同様のカテゴリーに入るでしょう。

> ここに挙げた企業やチームは、日々の仕事に似た面接テクニックや質問を採用しています。例えば、現実世界の問題でペアを組んだり、有償/無償の持ち帰り練習をしたりします。より良い面接を行うための推奨事項を読んで（そして貢献して）ください。

(以上DeepL翻訳利用の引用)

https://twitter.com/sugarpirate_/status/841858828908015618?s=20


### Hiring Without Whiteboards に関する記事

- [Hiring without whiteboards | Hacker News](https://news.ycombinator.com/item?id=13874026)
- [Hiring Without Whiteboards | Hacker News](https://news.ycombinator.com/item?id=23981795)

https://theoutline.com/post/1256/finding-a-better-alternative-to-the-whiteboard-interview

http://they.whiteboarded.me/

https://yamdas.hatenablog.com/entry/20200803/hiring-without-whiteboards

> こういう記事が出るということは、逆に言うとホワイトボード面接がそれだけ広く行われていることの裏返しだろう。そういう面接で解かされた問題を集めた LeetCode という有名サイトもあるくらいである。
>
> これを作ったのは Lauren Tan という現在 Facebook でソフトウェアエンジニアをやっている方で、これを彼女が立ち上げようと思ったのも、ホワイトボード面接は女性の候補者に心理的ストレスを与えているという上で取り上げた話を実地で感じていたからだろうか。

## 逆質問

https://github.com/viraptor/reverse-interview/blob/master/translations/JAPANESE.md

[「就職するまでにしておくといいことはありますか」という質問に全力で答えてみる](https://zenn.dev/taikiuejo/articles/8e9d4fbc3c8863)

## What happens when..

https://github.com/tetz-akaneya/what-happens-when-JA

https://zenn.dev/ak/articles/61d25099295372


## コーディングテスト

ちょうど下のような記事を読んだので、なるほどなとおもった

https://mayah.jp/posts/2021/10/coding-test/

https://zenn.dev/katoaki/articles/f5b95e4673c709

https://zenn.dev/hidebon0630/articles/75022374e28cdf

[yangshun/tech-interview-handbook: 💯 Curated interview preparation materials for busy engineers](https://github.com/yangshun/tech-interview-handbook)

[Tech Interview Blog – IGotAnOffer](https://igotanoffer.com/blogs/tech/)
[プログラマーの力量を見極める--面接官になったら尋ねるべき質問実例集 - ZDNet Japan](https://japan.zdnet.com/article/20409456/)
[本質的なエンジニアの技術面接とは。テスト問題からリアリティのある課題へ | Findyブログ](https://findy-code.io/engineer-lab/engineer-saiyo-with-no-whiteboard)
[開発の採用活動に必要な前提知識と人事・開発それぞれからみた習得難度 - Tbpgr Blog](https://tbpgr.hatenablog.com/entry/2022/01/16/033222)
[今回の転職活動の雑感 - seri::diary](https://serihiro.hatenablog.com/entry/2022/04/29/000000)

> ビジネスを進めるためには、ビジネス上の問題を解決することが本質

という意見と

> ホワイトボードを使って人前でコーディングすると緊張して実力が出せない」

という意見ということ。

[Why I Stopped Interviewing with Companies That Require a Coding Test - DEV Community 👩‍💻👨‍💻](https://dev.to/bradstondev/why-i-stopped-interviewing-with-companies-that-require-a-coding-test-2j6n)
> 人はみな天才なのに、魚を木登りで評価したら、魚は自分がバカだと思い込んで一生を過ごすことになる

記事サマリのみですが以上です～
NFT自動生成 その1

# NFTとは
昨今NFTが盛り上がっています。NFTとはNon-Fungible Tokenの略で、代替不可能トークンとも呼ばれます。
Fungibleとは代替可能であること、分かりやすく言うと足し算引き算ができることを意味します。
Bitcoinを例に取ると、1 Bitcoinは他のどの1 Bitcoinとも同じ=代替可能(同じ意味を持ち、他との区別はない)ため、足し算して2 Bitcoinとすることができます。
一方、NFT(Not Fungible)は代替不可能なものであり、足したり引いたりすることができません。例えば家や絵画の所有権は合算したり分割したりすることはできません。NFTは、ブロックチェーン上で管理される所有権と言い換えても差し支えないと思います。ほとんどの場合、デジタルアートの所有権を意味しています。
そしてNFTの標準規格であるERC721に従って定義しておくことで、特定の第三者に依存することなく、トークンの所有権を証明したり、所有権を売買したりできます。
最近は猿のデジタルアートが数十億円で売れたり、DisneyがNFTを売出したりとNFT市場が加熱しています。

# NFT自動生成
猿のデジタルアートであるBored Apeを例に取ると、全ての作品を手書きで作成している訳ではなく、背景、服、目、口といった構成要素をランダムに組み合わせてデジタルアートを自動生成しています。
それぞれのパーツのレアリティ(出現確率)を予め設定していくことで、各個体の価値を差別化しています。
各個体がどのパーツで構成されているかは、ERC721 TokenにおけるMetadata(属性情報)の仕様に準拠しています。
ERC721に準拠することで、異なるSmartContract間でNFTをやり取りしたり、[Open Sea] (https://opensea.io/)等の二次流通市場で統一的なUIの提供を実現しています。

本投稿では、デジタルアートの構成要素を組み合わせてNFTの画像を生成し、ERC721に準拠したMetadataを生成するツールについて紹介します(不定期連載)。

# 今回作成したNFT自動生成ツール
今回作成したツールを用いると、下記のような流れでNFTを自動生成することができます。

1. 素材となる画像を配置
2. レアリティ設定ファイルの生成
3. NFT(デジタルアートとMetadata)を生成
4. レアリティ統計情報(各構成要素の出現確率)の集計

# デモ
ツールの実行結果を示すデモ動画を作成しました(上記流れの3〜4の部分のみ)。
デジタルアートの素材として緑色と青色の背景、四角形と星型の図形を用意しています。背景と図形を組み合わせることで、4パターンのデジタルアートとMetadata(Jsonファイル)を生成しています。また、動画の最後には各構成要素の出現確率を集計したJsonファイルを表示しています。

- 素材１：背景

|<img width="128" alt="green.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466824/98c82acc-89b2-f961-b680-07f6e338db41.png">|<img width="128" alt="blue.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466824/9ea3bceb-1186-2270-cba6-197032d62a88.png">|
|---|---|

- 素材２：図形

|<img width="128" alt="rectangle.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466824/aaa83852-0b1f-2fc8-672d-3ec6a0bfc292.png">|<img width="128" alt="star.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466824/b17af785-a3a0-08d1-c2a5-4c4c703d4efb.png">|
|---|---|

- 実行結果デモ
![nft-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466824/937cee51-5fc9-8d81-14a8-0a58d9b3901d.gif)

実際には背景、服、目、口等の素材を数種類用意することで、1万パターン以上のNFTを生成することができます。各素材の出現確率も設定することができ、設定した値通りの配分で生成することでレアリティを操作できるようにしています。

# さいごに
多くの反響があればツールの使い方について詳しく解説していきたいと思います。また、ツール公開に向けて作業を進めていきます。
【React】useContextの使い方

## はじめに
　本記事は、プログラミングの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## useContextの使い方
###useContextとは
`Provider`でラップしたコンポーネントのツリーのどこからでも、同一の`ContextObject`を参照できるようにするHookです。
`props`のバケツリレーを避けることができます。
`Context`を更新したときに再レンダーされるべきでないコンポーネントにも再レンダーが走る場合は、注意するべきでしょう。

###useContextを使うタイミング
コンポーネントの階層が深い場合や複数コンポーネントで同一stateを使用する場合に使用します。

###useContextの使用例

```App.jsx
import React, {createContext, useState} from 'react'
import Header from './component/Header'
import Footer from './component/Footer'
import Content from './component/Content'
 
export const ChangeContext = React.createContext();
 
function App() {
  const [chageContext, setChangeContext] = useState(true);
  const value = {
    chageContext, setChangeContext
  };
  return (
    <div className="App">
      <ChangeContext.Provider value = {value}>
        <Header />
        <Content />
        <Footer />
      </ChangeContext.Provider>
    </div>
  );
}
 
export default App;
```

```Content.jsx
import React, {useContext} from 'react';
import {ChangeContext} from '../App';
import style from '../style/content.module.scss';
 
const Content = () => {
  const {chageContext, setChangeContext} = useContext(ChangeContext);
 
  return(
    <div className={style.content}>
      <h1>
        {chageContext ? 'content': 'コンテンツ'}
      </h1>
    </div>
  )
}
 
export default Content;
```
【Laravel】配列文字列をreplaceして検索するスコープ機能

# はじめに

`VARCHAR`型に以下の形式で登録していくシステムに検索機能を追加した際の対処方法をまとめます

```php
["40","41","42","43","44","45","46","47"]
```

# やり方

# `Model`内で共通利用したいので`Scope`化する

https://readouble.com/laravel/8.x/ja/eloquent.html#:~:text=SecondScope%3A%3Aclass%0A%5D)%2D%3Eget()%3B-,%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97,-%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92


`FIND_IN_SET`:第１引数の値が第２引数に含まれている場合に範囲を返す
`?`:ユーザーの入力値を使用するので`プリペアドステートメント`でバインドする
`replace`:`カラム名,置換元文字列`,`置換先文字列`を指定する

https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set

https://www.tailtension.com/mysql/1467/

```php
"FIND_IN_SET(?,replace(replace(replace({$target_column},'[',''),']',''),'\"',''))", $item);
```




```php:User.php
public function scopeWhereInByArray($query, $target_column, $ids)
{
    $query->where(function ($subQuery) use ($ids, $target_column) {
        foreach ($ids as $item) {
            $subQuery->orWhereRaw("FIND_IN_SET(?,replace(replace(replace({$target_column},'[',''),']',''),'\"',''))", $item);
        }
    });
}
```

## `Scope`をロジックで利用する

```php:UserController.php
// クエリを生成
$query = User::query();

// 都道府県検索
if ($param->getPrefIds()) {
    $query->whereInByArray('pref', $param->getPrefIds());
}
```

# さいごに
読んでいただきありがとうございます。
いいねしていただけると記事執筆の励みになりますので、参考になったと思った方は是非よろしくお願いします！
Node.js on Dockerでエラー発生(Error: EACCES: permission denied, errno: -13)

# はじめに
DockerでNext.jsを使ってウェブページを作ろうとしたけど、`npx create-next-app {name}`の段階で`glob error`っていうワケワカランのが発生した。テンションが下がった。

# 環境
- Linux (KDE neon based on Ubuntu)
- Docker version 20.10.12
- image node:17.3-alpine

# 問題

```
# コマンドをうちこむ
docker-compose run --rm node npx create-next-app nextjs-tutorial
Creating nextjs-tutorial_node_run ... done
Creating a new Next.js app in /usr/src/app/nextjs-tutorial.

Using npm.

Installing dependencies:
- react
- react-dom
- next
#エラー❗❗❗なにこれ。
glob error [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] {
  errno: -13,
  code: 'EACCES',
  syscall: 'scandir',
  path: '/root/.npm/_logs'
}
```

とりあえず権限が無いということはわかった。`permission denied`とか出たときは大方ファイル権限かユーザー管理あたりが原因。

# 原因
DockerFileに`USER node`の指定がないことが原因だった。これが何を意味するんだろうか？
コマンドをrootで実行しなくなるということだから、とりあえずセキュリティリスクが低下することはなんとなくわかる。

とりあえず、参考したページで`USER node`の指定をしろと書いてあったのでそうする。

# 解決策
DockerFileにUSERの指定を追記したら解決するらしい。

```:DockerFile
FROM node:17.3-alpine
WORKDIR /usr/src/app

USER node
```

こうすると、このイメージで作成されたコンテナは実行ユーザーがnodeになる。
あるいは、`WORKDIR`を`/home/`にしたらいいっぽい。

```:DockerFile
FROM node:17.3-alpine
WORKDIR /home/node/app
```

やっぱりrootが絡むとよくないんだろうか。
理屈はわからんけどとりあえずヨシ！

# おわりに
理屈はまだ理解してないけれど、とりあえずこれを書いてるのが深夜3時過ぎで、このあと午前10時から予定があるので、理解は後回しにしようと思います。
誰かわかるよって人いたら教えてほしいです。よろしくおねがいします。

# 参考
https://github.com/nodejs/docker-node/issues/740

https://www.creationline.com/lab/29422
byte vs int (C#)


####経緯
for文のindex変数、どうせ0～255しか使わないし、byte型にした方が効率的ではと思い調べてみました。

####注意
C#上での話です。他の言語では多少異なる点があるかもしれません。

###結論
int型で良いです。byteはかえって非効率になりそうです。

###まとめ
int型の方が良い理由は下記の通りです。
・配列のindexはint型で管理しているので毎回Castする事になります。
・C#は整数の計算系をint型に揃えているので、そこでもCastが入る可能性があります。
・そもそもまとめて宣言しない限り0埋めが発生するので、for文のindex程度では意味がないです。
・byteかintかとか、メモリ管理はコンパイラがいい感じにしてくれるので、逆にコンパイラの邪魔になるとかいう話もあるそうです。
・そもそも最近のCPUの処理速度はとても速いので、その程度の最適化では大した差は生まれないです。もし動作が重い事を理由に最適化するのなら、intかbyteかよりも重大な問題が他にあるはずで、そこを修正した方が何倍も効率的です。

###補足
「じゃあC#のByte型いらないじゃん！」とならないように、一応補足しておくと、byte型は通信の時に文字数を節約する為に使えるので現在でも不要ではないです。
つまり処理速度を犠牲に通信量を減らすという事ですね。

杞憂でしたが、私にとっては興味深い調査でしたので満足しています。
以上です。精進します。
Docker(WSL2)でPleasanter(SQLServer)環境を作成

:::note alert
2024/02/24追記
この記事のDockerfileは古いので、[新しく投稿した記事](https://qiita.com/M_S/items/661de466de737f14e8a1)を参考にしてください
※新しく投稿した記事はホストOSがUbuntuなので、もしかしたらWSL上のUbuntuだと不具合があるかもしれません
:::

# 環境
・OS    : Windows11 pro
・WSL2  : Ubuntu 20.04.3 LTS
・Docker: version 20.10.12, build e91ed57

# 動機
Pleasnterを自分の備忘録として使えないかと思い、Dockerで環境を作りました

# 作り方
以下のDockerfileを使って

```Dockerfile.pleasanter-dotnet-sqlserver
#
# pleasanter -dotnet - sqlserver
#

FROM mcr.microsoft.com/mssql/server 

ENV ACCEPT_EULA=Y
ENV MSSQL_PID=Express
ENV SA_PASSWORD=Password1!

USER root

RUN apt-get update && apt-get install -y curl
RUN curl https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list | tee /etc/apt/sources.list.d/mssql-server.list
RUN apt-get update && \
    apt-get install -y  \
    unzip \
    dotnet-sdk-5.0 \
    mssql-server-fts

RUN wget https://github.com/Implem/Implem.Pleasanter.NetCore/releases/download/Pleasanter_1.2.24.1/Pleasanter_1.2.24.1.zip
RUN unzip Pleasanter_1.2.24.1.zip

WORKDIR /pleasanter/Implem.Pleasanter
RUN  sed -i -e 's/PostgreSQL/SQLServer/g' App_Data/Parameters/Rds.json
RUN  sed -i -e 's/Database=postgres/Database=master/g' App_Data/Parameters/Rds.json
RUN  sed -i -e 's/UID=postgres/UID=sa/g' App_Data/Parameters/Rds.json
RUN  sed -i -e 's/SetSaPWD/'${SA_PASSWORD}'/g' App_Data/Parameters/Rds.json

WORKDIR /pleasanter
CMD ["/opt/mssql/bin/sqlservr"]
```
この下のコマンドを、上から順に実行します

```
docker build -t pleasanter-dotnet-sqlserver -f Dockerfile.pleasanter-dotnet-sqlserver　.
docker run --name pleasanter-dotnet-sqlserver -p 5000:5000 -d pleasanter-dotnet-sqlserver
docker restart pleasanter-dotnet-sqlserver
docker exec pleasanter-dotnet-sqlserver dotnet /pleasanter/Implem.CodeDefiner/Implem.CodeDefiner.NetCore.dll _rds
docker exec -w /pleasanter/Implem.Pleasanter pleasanter-dotnet-sqlserver dotnet /pleasanter/Implem.Pleasanter/Implem.Pleasanter.NetCore.dll --urls=http://0.0.0.0:5000
```
これでhttp://localhost:5000/ にアクセスすればPleasanterのログイン画面が表示されます

# はまったところ
最初Githubのソースコードからbuildをしようとしましたが、ソースコードからbuildしてhttp://localhost:5000/ にアクセスすると真っ白な画面が表示されその先に進めませんでした
ブラウザの開発者ツールで原因を探ったところ、htmlでvisibility:hiddenとなっている箇所があり、それが原因ではないかと思いましたがそれ以上はわかりませんでした...(これを開発者ツールで修正しても結局その先に進めませんでした)
そのためDockerfileに書いてあるように、https://github.com/Implem/Implem.Pleasanter.NetCore/releases のzipファイルをダウンロードして実行したところうまくいきました(なぜzipから実行するとうまくいくのかはわかりません)

# 参考
https://github.com/Implem/Implem.Pleasanter
goroutineで並行処理のメモ

goroutineを使ったときのメモです。

### channelで待ち合わせせずgoroutineを使う場合の注意

mainのgoroutineが終了すると、他のgoroutineが走っていてもプログラムは終了してしまうので注意しよう。待ち合わせをしたい場合はchannelを使う。


```main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	go func() {
		fmt.Println("start goroutine")
		time.Sleep(3 * time.Second)
	}()

	// time.Sleep(4 * time.Second)
	fmt.Println("finished")
}

```

上記のコードを走らせた場合は以下のようになり、goroutineがそもそも開始されていないことがわかる。

```
$ go run main.go
finished
```


### channelを使って待ち合わせした場合

```main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	done := make(chan bool)
	go func() {
		fmt.Println("start goroutine")
		time.Sleep(3 * time.Second)
		fmt.Println("finish goroutine")
		done <- true
	}()

	<-done
	fmt.Println("finished")
}

```

こちらの場合は以下のように出力される。

```
$ go run main.go
start goroutine
finish goroutine
finished
```
クイズ大会「Megalomania Tokyo 2」の結果に基づくレーティングの算出

#興味
私は、レーティングに**過度な期待**を寄せている。レーティングがあれば、マッチングができるはずで、そうすれば適度な強さの相手と白熱した対戦ができるはずだから。

しかし、クイズという競技においてレーティングを作ることはとても難しい。
1対1対戦でなく、大会によって、ラウンドによっても1試合の人数がまちまち。しかも大会によってルールも問題傾向も違うから、有利な人が変わってくる。しかも試合数が少ないのでレーティングが安定するまでに膨大な時間がかかってしまう。

そんな中2022年1月9日に開催された「Megalomania Tokyo 2」はレーティングのテストに最適な大会だった。なぜならば、最大32試合同時進行という画期的なシステムを採用し[^1]、1日で同一ルール、同一問題傾向の試合が254試合も実施されたからである[^2]。

[^1]: 通常のクイズ大会はステージの上で試合を一つずつこなしていく。
[^2]: システムトラブルが無ければ、さらに余興の63試合が行われ、317試合となる予定だった。

この記事では、そんな「Megalomania Tokyo 2」の結果に基づいて算出されたレーティングの概略を記載する。そしてこの記事から始まる連続記事では、計算方法を導き出した経緯や、今後どう更新していくべきかについて記載する予定である。

#計算方法
レーティングはチェスのために開発されたレーティング計算方法「[Eloレーティング](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%AD%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)」をもとにして計算を行った[^3]。

[^3]: 数式が上手く入らないので、数式は省く。Wikipedia等を参照してほしい。

各プレイヤーの初期レーティングを1500、K値を20として計算を行う。計算は、Grand FinalからW1に向かって、逆順におこなった後、その値を用いて再度W1からGrand Finalまで順方向の計算を行った（これを今後往復計算と表現する）。

##逆順計算の理由
試合数が少なく、レーティング算出が困難となるのは、序盤で敗退した勝数の少ないプレイヤーである。逆順で計算を進めることにより、序盤の計算に差し掛かる時点で、勝数の多いプレイヤーが実力を反映したレーティングを既に有している状態となり、試合を適切に評価することができる。

##往復計算の理由
4人参加・2人敗北の試合であるため、プレイヤーが2敗してトーナメントを完全に去る時、同時にトーナメントを去るプレイヤーがいることになる。逆順計算の時点では二人とも初期レーティング（1500）なので、この時の結果を適切に表現できていないと考えた。逆順計算で算出したレーティングをもとに再度順方向に計算を進めることで、実力を十分に反映したレーティングを作成し、各プレイヤーの最終試合を再度評価することができる。

#レーティングとそれに基づくランキング
ということで、組み合わせ運がなくて早くに敗退してしまったプレイヤーを報いる目的で、1位から120位までのランキングとレーティングを掲載します。
手元にあるデータには実名を使っているプレイヤーが大半であり、またレーティング・ランキングの数字が独り歩きするのを妨げるため、プレイヤー名の代わりに最終試合とその順位を掲載する形とします。
**注意点１：本レーティングは、いち参加者が勝手に計算したものです。本件に関して大会主催者への問い合わせはしないでください。**
**注意点２：レーティングは、計算の仮定の置き方や計算パラメーターを変更することで容易に数値が変わります。あくまでも一つの計算の結果だということを念頭に置き、数値の使用には最大限の注意を払ってください。また、過度なショックを受けないようにしてください。**
なお、今後もより妥当なランキング・レーティングを求めるため検討を継続します。そうした意味でも今回の結果が完全無欠でなく、変更が生じうることをご理解いただきますよう、お願いいたします。

![R1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218039/9e686e3a-0f67-a062-dc62-9aebb3724335.png)
![R2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218039/8b8f8574-6c5b-44b6-9e05-b171a11c6f6d.png)
Dynamics 365 Finance and Operations ~ Transportation Management（輸送管理）~

#輸送管理（Transportation Management System）とは
・配車・配送計画、進捗管理、積荷、運賃計算、請求書発行などの管理業務の効率化を実現するシステム
・「どのルートを通ると一番効率的か」「どのように積み込めば積載効率が向上するか」
・受発注、倉庫管理、在庫管理、いずれの要素も絡む。

https://www.aspicjapan.org/asu/article/4688

#輸送管理の基本
①入庫シナリオ
PO作成 → Load（積荷）作成 → 配送業者の決定（配送レート・ルート） →　ドライバーの到着・積み下ろし → 配送費の被請求・承認

～デモ割愛～

②出庫シナリオ
SO作成 → Load（積荷）作成 → 配送業者の決定（配送レート・ルート） →　Picking/Packing → ドライバーの到着・積み上げ → 配送費の請求・承認

・SO作成（メニュー：All Sales Orders）
ヘッダー（配送に関する設定値）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/91ee4d83-98b4-06be-e22b-75f2269e15da.png)
明細（Release to warehouseをすると、Waveが作成される）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/55091755-8355-fb10-6f9f-31a7688d65d2.png)
倉庫（倉庫管理を有効化）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/b6bb6bc5-2bcd-f311-8ed9-64ecda2a304b.png)

・Load（積荷）作成（メニュー：Load planning workbench）
Sales lines → Loads ※入庫シナリオならPurchase order linesから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/0ba37a2c-86a3-7650-ffdb-05b579908df9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/d0847584-fecc-f5c8-e55d-b18182a8b73d.png)

・配送業者の決定（配送レート・ルート）
Rate shopを押すと、設定されている配送レートから選択可能なShipping CarrierやCarrier Serviceが決まる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/660c6089-fae1-05cc-61ea-283fab5d618f.png)

・Picking/Packing（Work）
（ここからはWarehouseアプリを使って、倉庫担当がLicense PlateからPickingしたりPackingしたりする作業を登録します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/d1e394c3-00ea-64b8-c1d9-847178e8be24.png)

・ドライバーの到着・積み上げ
（ここからはWarehouseアプリを使って、ドライバー担当が登録時間に到着時間にチェックインしたり、積み上げ作業を登録します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/6bc8c573-ea21-2596-6168-6e68d6a6517c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/5b8c67ed-7e57-9b59-10d6-d66a4bb02af9.png)

・配送費の請求・承認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/72d330fe-ab9f-a0fa-a8a8-ce71e9ad4965.png)
React チュートリアル　パート7　（コンポーネント＆props）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/02e44eb3-513d-c93c-a43f-4991803847c9.png)

#目標:military_medal:
ReactJSの**超重要知識**:bangbang:
コンポーネントとpropsを見ていきましょう:muscle::muscle:

#ディレクトリ構造
新しくcomponentsフォルダを作成し、そこにList.jsを作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/39f27e9f-ae33-3cd3-ebc9-b1e160d69ef5.png)


#List.jsを作成
作業は２つだけです:point_up:
まずはじめに、List.jsを作成します！下記の様に記述してください！後ほど説明します:blush:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/7097179b-e48c-ac63-21ca-fe9a304e778c.png)
:blush:
次に、App.jsを下記の様に変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/c553bd72-902d-d9c6-c5f0-aa8af762eb71.png)

>【4行目】import 文を追加

>【26行目】**\<List/>**コンポーネントに変更

>➪①**\<List/>**コンポーネントに、keyとdocumentを渡しています
➪②document={document}を解説すると、document（右）という値に、document（左）という名前を付けて**\<List/>**コンポーネントに渡しています
➪③App.jsから渡された、documentをList.jsが受け取りそれをdocumentとして受けています（List.js　【3行目】）。これが**props**になります！

#ブラウザで確認:fire::fire:
プラウザの表示には特に変わりありません！
コンポーネントを作ることによって、役割を分担することができより読みやすいコードになったかと思います:heart_eyes:


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/fef5cf5e-f2a5-6de7-c482-affd5ae365d0.png)

#次回:bell:
ReactJSで簡単な、**CRUDシステム**を構築してみます！
そこで登場するのが**filter()**メソッドです:bangbang:
**map()**メソッドと同様とても大事なメソッドになるのでしっかり学んでいきましょう:blush:
UnityでAR開発を手軽に体験してみる

今回はUnityでAR開発を手軽に体験してみる方法を記事にいたします。

AR Foundationが公式でGitHubにあげているsampleを動かします。

# AR Foundation とは
ARFoundation とは、Unity が開発している、AR 開発用のフレームワークです。ARFoundationを使えば、ARCore(Android向け)、ARKit(iOS向け)など、様々なプラットフォーム上で動くARアプリを簡単に開発することができます。

https://unity.com/ja/unity/features/arfoundation

# 動作イメージ
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/vUJna3xpGr">pic.twitter.com/vUJna3xpGr</a></p>&mdash; たく (@5HdM6WlLVaazBV7) <a href="https://twitter.com/5HdM6WlLVaazBV7/status/1482387787961692162?ref_src=twsrc%5Etfw">January 15, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 環境
- Windows10
- Unity Hub 2.4.5
- Unity 2020.3.25f1
- Android Studio 2020.3.1
- ARFoundation 4.2.0

Android向けの環境構築方法については以下の記事をご参照下さい。

https://qiita.com/Nossa/items/4b2c5026698ed4ab7d2b

https://qiita.com/tak001/items/e7a5f21742d463a37a39

https://qiita.com/tak001/items/045e6a0bd86628d59cfe

# 使用Package
今回のsampleで使用されているPackageは以下の通りです。

- ARSubsystems
- ARCore XR Plug-in
- ARKit XR Plug-in
- ARKit Face Tracking
- ARFoundation

これらは通常 Unity側の Window > Package Manager から install するのですが、今回はダウンロードしたプロジェクト内に既にあるので不要です。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/3b2cac51-a57c-941e-0258-f4bec2aab135.png)

# GitHubからsampleコードをダウンロード
https://github.com/Unity-Technologies/arfoundation-samples

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/290be3a7-c597-a6a5-8fda-dd543dc6b312.png)

任意の場所に解凍いたします。

# Unityで開く
Unity Hub のプロジェクトから「リストに追加」で先程ダウンロード解答したフォルダを追加します。

続いて、Unityのバージョンを指定します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/175b8778-335b-25dc-bacd-1409d4087e15.png)

# Unityのアップグレード
プロジェクトを開こうとすると、以下のように「新しいバージョンのUnityにアップグレードしますか？」と聞かれますので、「確認」をクリックして下さい。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/be36fc01-ce98-be01-55f2-7a09f7602578.png)


# Unity側でbuild
あとは、Unity側の 「File」 > 「Build Settings」から、
Androidの「Switch Platform」をクリックしてAndroid向けのbuildにしておきます。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/bb260a9e-f35c-37ae-7214-90d88847654c.png)

そして、「Build And Run」をクリックします。

ちゃんとAndroid向けの環境構築が正しくできていれば、実機側でsampleのアプリが起動されます。

# サンプルで体験できること
ARFoundationの機能として顔検出や平面検出などをMenu画面から体験できます。
ただし、Android/iOSのバージョンや機種によっては選択できない(遊べない)ものもあります。
【CloudFront】キャッシュ期間をフロー図っぽくしただけ

## キャッシュ期間がわかりにくい

なので、ただ図にしただけの味のしない記事です。
（間違えがあればご指摘いただけると嬉しいです!）

## CloudFront キャッシュ期間

![スクリーンショット 2022-01-16 0.44.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632997/ca03c510-3f90-f59a-2093-a7e07626186e.png)


## 参考

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

https://qiita.com/t-kigi/items/6d7cfccdb629690b8d29
特定のフォルダ内に指定のファイルが存在することを確認するWindowsバッチ

特定のフォルダ内に指定のファイルが存在することを確認するWindowsバッチを書いてみます。

たとえばこんなフォルダ（INFILE）と
batファイル（FileExistsCheck.bat）を用意して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/74ab7a37-fb12-3268-4901-be1eb34d3991.png)

INFILE内にこんなファイルを用意して……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/748ac795-f56d-5e58-887c-84f858ea9746.png)

これらの存在を確認してみます。


FileExistsCheck.batへ次のように書きます。

```bat:FileExistsCheck.bat
@echo off
rem >> 標準出力を停止
rem ◎指定フォルダ・指定ファイルの存在を確認する
rem ------------------------------------------------------------------------
setlocal enabledelayedexpansion
rem >> 遅延変数を使う場合の指定
cd %~dp0
rem >> このbatファイルが置かれているディレクトリをカレントディレクトリとする
rem ------------------------------------------------------------------------

rem >> 日付取得
echo 日付 %date%
echo 時刻 %time%
echo !date! !time! --- begin ---

rem >> ディレクトリ名、ファイル名、変数の定義
set targetdirin=INFILE
set targetinfile01=%targetdirin%\11111hogehoge.csv
set targetinfile02=%targetdirin%\22222hogehoge.csv
set targetinfile03=%targetdirin%\33333hogehoge.csv
set targetinfile04=%targetdirin%\44444hogehoge.csv
set targetinfile05=%targetdirin%\55555hogehoge.csv
set dirinerr=0
set csvinerr=0

rem >> 動作指定
rem 01.指定ディレクトリ配下のファイルの存在確認
if not exist "%targetdirin%"  (
    echo ディレクトリ %targetdirin% は存在しません。 
        set dirinerr=1
) else (
    if not exist %targetinfile01% (
        echo ディレクトリ %targetdirin% 配下に %targetinfile01% が存在しません。
        set csvinerr=1
    )
    if not exist %targetinfile02% (
        echo ディレクトリ %targetdirin% 配下に %targetinfile02% が存在しません。
        set csvinerr=1
    )
    if not exist %targetinfile03% (
        echo ディレクトリ %targetdirin% 配下に %targetinfile03% が存在しません。
        set csvinerr=1
    )
    if not exist %targetinfile04% (
        echo ディレクトリ %targetdirin% 配下に %targetinfile04% が存在しません。
        set csvinerr=1
    )
    if not exist %targetinfile05% (
        echo ディレクトリ %targetdirin% 配下に %targetinfile05% が存在しません。
        set csvinerr=1
    )
)

if %dirinerr% == 1 (
    echo ＩＮファイルの格納先フォルダに問題があるため処理を中止します。
)
if %csvinerr% == 1 (
    echo ＩＮファイルの格納状況に問題があるため処理を中止します。
)
if %dirinerr% == 0 (
    if %csvinerr% == 0 (
        echo ＩＮファイルの格納状況に問題はありません。
    )
)

echo !date! !time! --- end ---
timeout /t 5 /nobreak
```


実行してみる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/e8d4afa1-ba83-419c-a783-18f6c7c47aa1.png)


いい感じ。
ディレクトリ名をINFILAにしてみたり
ファイル名を一部 hugahugaにすると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/67aefe5e-a4d6-be12-2503-6a53a03d5829.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/b3764d36-8d0c-16c5-a6f0-872d24ff6baa.png)

ちゃんと反応してますね。

お疲れさまでした。
React チュートリアル　パート6　（style）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/a1f6e41b-b558-3b45-f3c2-ea53aa245310.png)

#目標:military_medal:
文字に装飾を付けてみましょう:sparkles::sparkles:

#App.jsに記述
divタグと、pタグに**style属性**を記述しています:pencil2:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/fefd5662-6daf-5b38-abd0-10096794066d.png)

>【25行目】　**style属性{{ }}**にスタイルを記述していきます！

#ブラウザで確認:fire::fire:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/f19205e1-4867-6d64-e0fa-62f2ba90e49b.png)

他にも、スタイルの記述方法はあります:crayon:
一つ紹介すると、**styled-components**があります！ぜひトライしてみてください:muscle:

https://youtu.be/-FZzPHSLauc

#次回:bell:
次は、フックと同じぐらい大切な**コンポーネント**と**props**を学びます:bangbang:
【JavaScript】ES5とES6において、親クラス継承の違い

##ES5においての継承

```javascript

<script>

//親
function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
}


Phone.prototype.call = function () {
    console.log(" give XXX a call")

}

//子
function smartPhone(brand, price, color, size) {
    Phone.call(this, brand, price);
    this.color = color;
    this.size = size;
}

smartPhone.prototype = new Phone;  //親を呼び出す
smartPhone.prototype.constructor = smartPhone;


//子　メソッドの追加
smartPhone.prototype.photo = function () {
    console.log("take photo")
}

smartPhone.prototype.mail = function () {
    console.log("receive email")
}


let iphone = new smartPhone('iphone', 100, 'white', '6.7inch');
console.log(iphone);

//smartPhone{brand: 'iphone', price: 100, color: 'black',size: '6.7inch'}

</script>
```

##ES6での継承
```javascript

<script>

//親
class Phone {
    constructor(brand, price) {
        this.brand = brand;
        this.price = price;
    }

    call() {
        console.log(" give XXX a call")
    }
}


//子　*** extendsを使えば継承できる ***
class smartPhone extends Phone {
    constructor(brand, price, color, size) {
        supre(brand, price); //イコール  Phone.call(this,brand,price)
        this.color = color;
        this.size = size;
    }

    photo() {
        console.log("take photo")
    }

    mail() {
        console.log("receive email")
    }
}

let iphone = new smartPhone('iphone13', 200, 'pink', '6.1inch')

console.log(iphone)
  //smartPhone{brand: 'iphone13', price: 200, color: 'pink',size: '6.1inch'}


iphone.call()//" give XXX a call"
iphone.photo() //"take photo"
iphone.mail() //"receive email"

</script>
```

##違い
ES６とES5と比べて、親クラスを継承するときのコードが明らかに簡潔ですね。
classとextendsを使えば、親クラスを継承できるので、
PHP、Javaなどの構造と似ているように思います。
phpenv update でPHPの最新のバージョンが反映されない

```
$ phpenv install --list

```
PHP8系が一覧にない


```
$ phpenv update

error: Your local changes to the following files would be overwritten by merge:
	share/php-build/default_configure_options
Please commit your changes or stash them before you merge.
Aborting

```
エラーがでた。
以下のファイルをgitでcommitかスタッシュすればいいらしい。
面倒なので、default_configure_optionsのファイル名を変更（バックアップ）

```
/Users/[ユーザ名]/.anyenv/envs/phpenv/plugins/php-build/share/php-build/default_configure_options
```


```
$ phpenv update

$ phpenv install --list
```
PHP8系がインストールリストに表示された！
Wordで中クリックを押すと不幸になる

## 事象説明

:::note warn
Windowsのバージョンによって再現するかしないか違いがあります。
知りうる組み合わせでの解決手段をメモしていますが、確実性はありません。
下記の再現方法は、未保存の情報がある状態では決して試さないでください。
:::

Wordにはマウスの中クリック(第二ボタンのクリック)を押すとカーソルが変わり、カーソルの位置により自動でスクロールが行われる機能があります。
この状態で、何某かのキーを押すと(矢印キーとかEscキーでも)状態を解除できなくなります。
また、[バージョンによっては発生しないこともあるそうです。](https://answers.microsoft.com/ja-jp/msoffice/forum/all/word%E3%81%A7%E4%B8%AD%E3%82%AF%E3%83%AA%E3%83%83/851c04b9-f642-4f4b-ad18-17576133ae15)
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172587/9b8ee51d-bfd5-e71f-ff3e-b88debf2076d.png)

# 再現・確認環境

|OS        |MS Office|
|----------|------------|
|Win10 21H2| Office 2019|
|Win10 21H1| Office 2016|

# 解決手段

:::note warn
もし、事前にAlt+F4などを入力してしまった場合は、決して試さないでください。この手順は、固まってからの操作がすべて実行されてしまいます。

下記、手順1は絶対に省くべきではありません。何もしていない状態で手順2を実行するとWordが「応答なし」状態となり、強制終了以外の手段がなくなる場合があります。
:::

以下、2つの手順を行ってください。

* 手順1: Wordのページ内で、左クリックしてください。何も書かれていない箇所が良いです。
![b - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172587/0f5d9e1d-d6c4-d19a-2b94-221307aa66a6.png)
  
* 手順2: デスクトップのプレビュー上で右クリックすると解除できます。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172587/f2235362-89d2-4a6e-6356-4ece067f15cc.png)
FireStoreにデータを保存と応用

# はじめに
スクレイピングで集めた情報を、Firestoreに保存します。データを保存することで、アプリなどに応用することができます。

今回は、前回の続きで、ニュース記事のデータを例に用います。

前回の記事：[ニュース記事をスクレイピング](https://qiita.com/babmuclr/items/64a8833bfe7a7e32f09e)
前回の記事：[SeleniumでDeepL翻訳](https://qiita.com/babmuclr/items/41bed1261be4e1c73a06)

# 目次
<!-- タイトルとアンカー名を編集 -->
1. 全体概要
1. 実行コード
1. アプリケーションへの応用
1. 参照文献

<!-- 各チャプター -->
# 全体概要
イメージですが、Firebaseは、サービス全体を指しています。Firestoreは、Firebaseの中の一つのサービスです。

使い方ですが、前提として、Firebaseの使い方は、ドキュメントを参照することが、一番良いです。保存するコードは、少しずつ変化するからです。しかし、公式ドキュメントは、わかりづらいように、自分は感じました。ここでは、私がどのように使っているかの例について示します。

[Firebaseの公式ドキュメント](https://firebase.google.com/docs?hl=ja)
[Firestoreの公式ドキュメント](https://firebase.google.com/docs/firestore?hl=ja)

実行する内容とはしては、下記の内容を、Firebaseに保存します。データは、辞書型で持ちます。

```python:保存内容
article = {
    "title": "Biden says hes not sure about voting bills future after Sinema reiterates opposition to rule change - CBS News",
    "pubDate": "Thu, 13 Jan 2022 23:58:00 GMT",
    "source": "CBS News",
    "link": "https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LmNic25ld3MuY29tL25ld3Mva3lyc3Rlbi1zaW5lbWEtdm90aW5nLXJpZ2h0cy1zZW5hdGUtcnVsZXMtc3BlZWNoL9IBAA?oc=5",
    "title_ja": "バイデン氏、シネマ氏がルール変更に改めて反対した後、投票法案の将来について「確信が持てない」と発言 - CBS News"
}
```

保存後の状態は、次のようになります。
<img width="500px" alt="保存のページ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416886/1f0b02af-3695-8879-8aa3-4ad50189f5e8.png">


# 実行コード

```python:regist_firebase.py
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

# firestoreを初期化する
cred = credentials.Certificate("./serviceAccountKey.json")
firebase_admin.initialize_app(cred)
db = firestore.client()

# firestoreに保存する
doc_ref = db.collection("importants").document()
doc_ref.set({
    u"title": article["title"],
    u"pubDate": article["pubDate"],
    u"link": article["link"],
    u"source": article["source"],
    u"title_ja": article["title_ja"],  
})
```

serviceAccountKey.jsonには、APIキーが一覧として保存しているファイルです。

保存する内容を変化させたいのであれば、u"保存したいデータの名前": 保存したいデータの内容　とすれば、良いです。db.collection()の中の部分を変化させると、保存するデータベースのコレクション名を変更できます。

# アプリケーションへの応用
これまでの内容を、応用することで、下のようなアプリを制作することができます。このWebアプリは、（ https://www.babmuclr.com/ ）で閲覧できます。このWebアプリの概要は、次のnoteで説明しています。（ https://note.com/babmculr/n/n72baebdb9a70　）

<img width="500px" alt="アプリのページ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416886/21f1d5a4-f3b8-c443-887f-cab73121290e.png">


# 参考文献
- [Webアプリ](https://www.babmuclr.com/)
- [Webアプリの説明概要](https://note.com/babmculr/n/n72baebdb9a70)
主キー設定ありテーブルで重複レコードができてしまった。→そのうち一方の値だけ変更したい時にやったこと。【データベース】

システム検証の仕事をしていた頃のお話。

主キーありのテーブルの中に、どういうわけか全く同じデータ（レコード）が2件作成されていたんです。
（主キーの値も含めて全て重複したレコード）
んで、検証のためにそのうち1件だけ値を編集したいということがありまして。
（一方の主キーの値を変更したい）

ただ、当時使っていたデータベースツールの仕組み（？）として…
一方のデータを変更するともう一方のデータも変わっちゃうということがありまして。
（おそらく、主キー含め全くの重複データなので指示が両法にに伝わっちゃうから）

その時に行った対処法としては…

そのレコードの値をメモし、削除
（一方を選択して削除すると、もう一方も削除される。＝2件ともレコードが削除される）
↓
レコードをそれぞれ新規で作り直す。
1件は元のデータ。
もう1件は編集したかった内容を反映させてデータ作成。

とりあえずはこの手順で検証に必要なデータが用意できました。
シンプルではありますが、カラム数が少ない時はこのほうが早かったです。

以上、備忘録。
テスト（単体テスト・結合テスト）

###テストについて


項目として案件定義、外部設計、内部設計、コーディング、単体テスト、結合テスト、運用テストがあります。
![My First Board (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188773/c62e6cba-ecff-d64d-4382-e6d1e0e8b69e.jpeg)
現場によっては定義されている内容や名称も異なる事があります。内部設計ではなく、詳細設計と書かれていたり、運用テストが結合テストと呼ばれていたりします。
今回は、一般的な単体テストと結合テストについて触れていきます！



###テストの流れ
![My First Board (6).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188773/a945d62e-f281-d78e-f12b-54b3d05da663.jpeg)

上記の図が一連の流れとなります。
システムを作る際、クライアントと調整し設計を行いコーディング、テストを行います。
この流れ、手順の事をウォーターフォールと呼びます。
全部で７つのフェーズに分かれており、V字型モデルとも呼ばれています。

###単体テスト
機能単位のテスト。
■関数単位
・function内で定義した処理が実行されるのか
・～book/1をURLに入力した際、idが『1』の情報を取得されているのか
■パーツ単位
・ユーザー登録を実行した際、データベースのテーブル内に1行データが増えているのか


###結合テスト
機能同士を組み合わせたテスト。
例）SNSの場合
・ログインをした後の最初のページにログインユーザーの名前やフォロー中のユーザーのつぶやきが表示されているのか
（フォロー中のユーザーのツイートを表示させる、ログインユーザーの名前を表示させる。①ログイン機能+②フォロー機能+③つぶやき機能）
・新規登録時にバリデーション機能が動くか
（登録時は文字列なのか、数字限定なのかという条件が機能しているか、空欄や入力文字数が多いとエラー文言が表示される。①登録機能+②バリデーション機能）
・退会した後はつぶやきが表示されないかどうか
（ログインが出来なくなり、フォローしている相手情報がないのでつぶやきも見れなくなる。①退会機能+②非ログイン時の動き）

###まとめ
・単体テストは内部設計（機能単位）のテスト
・結合テストは外部設計（機能同士を組み合わせた）テスト
※現場によって細かい定義の内容は変わってくるので、現場に確認を行ってください。
【Lighthouse】Background and foreground colors do not have a sufficient contrast ratio.が出た時の解決策

# 事象
Lighthouse AccessibilityでBackground and foreground colors do not have a sufficient contrast ratio.が出た時の対処法

![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651106/b2fee814-a5fa-56c8-effc-4763c1b3c72b.png)


# 解決策
背景色と前景色のコントラスト比が十分でない（直訳）と怒られてますので、適切なcolorに変えます。

**手順**

1.chormeのdeveloperツールを開き、該当タグのcolorの四角（赤枠）をクリックします。
![スクリーンショット 2022-01-15 23.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651106/ed05edaf-6c2d-dfc5-c55b-5b796be06b30.png)

2.赤枠の右矢印をクリックします。
![スクリーンショット 2022-01-15 22.56.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651106/27762d4e-6a6e-2f89-8809-560c64985de6.png)

3.適切なcolor（コントラスト比4.5以上）を選択します。
![スクリーンショット 2022-01-15 23.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651106/981d9d41-604a-50ac-d3c7-d7b6ff6edadc.png)

以上で修正終了です。

## コントラスト比に注意しよう
コントラスト比を意識してデザインしてもらってます。
ですが、予想以上に注意しないといけない点でした。今後もより良いプロダクトを目指してチームで話し合っていきます。


# 参考記事
https://www.w3.org/TR/WCAG21/#contrast-minimum
JavaScript関数

## 関数を定義する
JavaScriptでは、関数は次のように定義される。

```
function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}
```
上記の`abs()`関数の定義は次のとおりです。

- functionは関数を定義することを示す。
- absは関数の名前です。
- (x)のxは関数のパラメーターであり、複数のパラメーターは[,]で区切られている。
- {...}の間のコードは関数本体であり、複数のコードを含める。

要注意：関数本体内のステートメントが実行される時、`return`が実行されると、関数が実行完了、結果が返される。 したがって、条件付きの判断とループにより、関数内に非常に複雑なロジックが実装できる。

`return`ステートメントがない場合、関数は実行後に結果も返しますが、結果は`undefined`です。

JavaScript関数もオブジェクトであるため、上記で定義した`abs()`関数は関数オブジェクトであり、関数名`abs`は関数を指す変数と見られる。

したがって、関数を定義する2番目の方法は次のとおりです。

```
var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};
```

このように、`function(x){...}`は無名関数であり、関数名はありません。 ただし、この無名関数は変数`abs`に割り当てられているため、変数`abs`を介して関数を呼び出すことができる。
上記の2つの定義は完全に同じです。

## 関数を呼び出す
関数を呼び出す時に、パラメーターを順序で渡す。

```
abs(10); // 10を返す
abs(-8); // 8を返す
```
定義されているよりも少ないパラメータを渡しても問題はありません。

```
abs(); // NaNを返す
```
この時点、`abs(x)`関数のパラメーター`x`は`undefined`受信され、結果は`NaN`です。

## 変数のスコープ
JavaScriptでは、`var`宣言された変数はスコープされる。
変数が関数本体の内部で宣言されている場合、変数のスコープは関数本体全体であり、変数を関数の外部で参照することはできません。

```
function foo() {
    var x = 1;
    x = x + 1;
}
x = x + 2; // ReferenceError! 関数の外部で変数xを参照できません。
```

2つの異なる関数が同じ変数を宣言する場合、その変数はそれぞれの関数の本体内でのみ機能する。つまり、異なる関数内の同じ名前の変数は互いに独立しており、互いに影響を与えません。

```
function foo() {
    var x = 1;
    x = x + 1;
}

function bar() {
    var x = 'A';
    x = x + 'B';
}
```
JavaScript関数はネスト(関数内関数)できるため、この時点で、内部関数は外部関数に定義された変数にアクセスできますが、その逆はできません。

```
function foo() {
    var x = 1;
    function bar() {
        var y = x + 1; // barはfooの変数xにアクセスできる
    }
    var z = y + 1; // ReferenceError! fooはbarの変数yにアクセスできません
}
```
内部関数と外部関数の変数名が同じ名前の場合はどうなりますか？それをテストしてみましょう：

```
function foo() {
    var x = 1;
    function bar() {
        var x = 'A';
        console.log('x in bar() = ' + x); // 'A'
    }
    console.log('x in foo() = ' + x); // 1
    bar();
}
foo();
// 結果：
// x in foo() = 1
// x in bar() = A
```
これは、JavaScript関数が変数を探すときに独自の関数の定義から始まり、「内部」から「外部」まで検索することを示している。内部関数が外部関数と同じ名前の変数を定義している場合、内部関数の変数は外部関数の変数をシールドする。
numpyチュートリアル on Jupyter Notebook

numpyチュートリアル（ビギナーズ向け）及びnumpyクイックスタートのWebサイトの内容を翻訳し<font color=blue>Jupyter Notebookで実際に動かしながら学習できる</font>ように編集しました。

元にしたWebサイトはこちら

https://numpy.org/doc/stable/user/absolute_beginners.html

https://numpy.org/doc/stable/user/quickstart.html

オリジナルのサイトに加え、<font color=blue>わかりにくいと思われる箇所の補足説明</font>や、<font color=blue>全てのコードが実行できるようにテストデータを作成するコードの追加等</font>を実施しています。

<font color=blue>numpy の学習ツールとして活用ください。</font>

:arrow_down: <b>下記のGithubのサイトからファイル(.ipynb)をダウンロードして、Jupyter notebook環境、またはGoogleコラボ上で実行してください。</b>  
  
https://github.com/DeepAelurus/numpy_Learning

+ NumPy the absolute basics for beginners.ipynb : numpyチュートリアル（ビキナーズ向け）
+ Numpy quickStart.ipynb : numpyクイックスタート

---
なお、numpyチュートリアル（ビギナーズ向け）の翻訳のWeb版を下記で公開しています。
実行まで必要としない場合はこちらを参照ください。

https://qiita.com/DeepTama/items/0aa2c4840571ba789e85

また、「Pythonチュートリアル」も同様に動かしながら学習できるように下記で公開していますので合わせてご活用ください。

https://github.com/DeepAelurus/Python_Leraning


# サンプルイメージ

上記コンテンツのサンプルイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/de6f8915-3fdc-b4bc-203f-02a46e08e25f.png)

・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/db0eb6fa-6a4c-0ad1-7ac9-aaf17973d52d.png)


・・・

## 補足説明の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/6ab6cfde-b438-6ec0-a2eb-32ca0bd82d53.png)


## テストデータ生成の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/7bc6b3a9-5bfc-e8fb-42dc-f73e728005da.png)


# 参考

## Googleコラボをまだ使ったことがない方は下記を参考にしてください。

https://www.youtube.com/watch?v=inN8seMm7UI


## Googleコラボのインストールは、以下の手順で簡単に行えます。

- Googleアカウトを作成（まだ持っていない場合）
- Googleドライブ上で左上のメニューから「アプリで開く」->「アプリを追加」で、Googleコラボ　　を選んでインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/5da58c21-830f-4628-08ca-c01eaff6c0fa.png)

- Githubからアップロードしたファイルを実行するとGoogleコラボで起動します

誤りや不足、加筆修正すべきところがありましたらぜひご指摘ください。継続してブラッシュアップしていきます。
© 2022 [NPO法人AI開発推進協会](https://sites.google.com/deepaelurus.com/aboutus/home)
AtCoder Beginner Contest 235 の思考メモ（5完）

##はじめに
[AtCoder Beginner Contest 235](https://atcoder.jp/contests/abc235)に参加して75分5完、955位でした。
あまりにも不甲斐ない内容だったために再発防止のためにコンテストでした思考を時系列順にまとめたいと思います


##[A - Rotate](https://atcoder.jp/contests/abc235/tasks/abc235_a)
21:00:00 開始
問題文中に
>3 つの数字 x,y,z をこの順に並べてできる 3 桁の整数を xyz と表すことにします。

という文を確認

* 文字列として受け取って一桁ずつ処理
* 3桁なので力技で行く

の2択から、汚くても速く書ける後者を採用

```C++:C++
    ll n;
    cin>>n;
    ll a,b,c;
    a=n%10;
    n/=10;
    b=n%10;
    n/=10;
    c=n;
```

21:01:53 [提出　AC](https://atcoder.jp/contests/abc235/submissions/28527059)
汚いコードだが、とにかくAC
##[B - Climbing Takahashi](https://atcoder.jp/contests/abc235/tasks/abc235_b)

実際にシュミレートするだけ

21:03:36 [提出 AC](https://atcoder.jp/contests/abc235/submissions/28529716)

##[C - The Kth Time Query](https://atcoder.jp/contests/abc235/tasks/abc235_c)
問題を流し読みし、制約をろくに読まずvectorで実装し始める
2×10^5なら充分がと思いこむがそれだと実際に必要な配列の個数はaiの最大値の10^9個

21:08:00 Google検索 c++ map
実装し終わったものの、テストケース2でランタイムエラーを起こす
ここでようやくmapを使わなければいけないことに気がつく
[C++日本語リファレンス](https://cpprefjp.github.io/reference/map/map.html)を見ながら実装するも、
mapにその要素があるかどうかをempty()でやろうとしてバグらせる
.count(x) == 0　に修正してAC

21:22:07 [提出 AC](https://atcoder.jp/contests/abc235/submissions/28544991)
もうここで14分無駄遣いしている。この14分がなければ青パフォであった

##[D - Multiply and Rotate](https://atcoder.jp/contests/abc235/tasks/abc235_d)
出てくる数字がせいぜい10^6の10倍程度なのでとにかく出てくる数字を全部出してsetで管理すれば良いなと判断

21:40:00 Google検索 set同士の足し算 c++
insertでsetを足そうとして手間取る
setの結合はmerge かあ。足し算 という単語も適切ではないっぽいので、しっかりと使うものは頭に入れておくこと

21:42:20 [提出 TLE](https://atcoder.jp/contests/abc235/submissions/28551916)
現在のループで新しく発見した数字が空ならループを抜ける処理を書いていたが、
いくつかのケースでTLEが発生。無限ループが出たと思われる

21:45:11 [提出 AC](https://atcoder.jp/contests/abc235/submissions/28552706)
この問題ではすぐに答えが出るだろうと判断。1000回の試行で解がでなければ不可能と判断して打ち切る処理を足してAC
5分以上の思考をするならペナルティ覚悟ですぐ出す、という競技プログラミングの解き方をした

##[E - MST + 1](https://atcoder.jp/contests/abc235/tasks/abc235_e)
Eの問題に面食らったが、最小全域木の求め方のアルゴリズムがしっかり頭に入っていたため、
それをやっていけば良いと判断

21:52:00 Google検索 c++ 配列 上限 個数
しかし、クエリをO(1)で処理するためにはクラスカル法の全状態を保存しなければ行けないのでは？と迷走
200000*200000で40000000000個の配列を作ろうとして流石に無理だと考察を続ける

22:00:00 [Luzhiled's Library](https://ei1333.github.io/library/)内 でunionfindを捜索
クエリの先読みだと気付き実装を開始
AtCoder Libraryを使えば良さそうなものだが、未だにpaiza.ioで実装しているため人のライブラリを使わせてもらっている

22:10:34 [提出 AC](https://atcoder.jp/contests/abc235/submissions/28558738)
グラフの持ち方が

```C++:C++
vector<pair<ll,pair<ll,pair<ll,ll>>>> g(m+q);
cin>>a>>b>>c;
g.at(i)={c,{-1,{a,b}}};
```

という実装でいいのか疑問だったが、他の人の提出を見てみると
pair< pair < int,int>, pair< int,int> > とかタプルで作成しているのでまあいいのだろう。

##[F - Variety of Digits](https://atcoder.jp/contests/abc235/tasks/abc235_f)
桁DPだということは制約を見てすぐ分かったが、
ちゃんと桁DPを実装したことがなかったためえっちらおっちら実装しているうちに時間切れ。精進しなさい


# 今後の課題
* set,mapの使い方を再確認 コンテスト中に見るチートシートを作成しておく
* D問題で無限ループする原因の特定と対処法の確認
* 桁DPの過去問を解く
UnityでAndroid向けにbuildして実機で動作確認する方法

基本的な内容ですが個人のメモとして残します。

# 環境
- Windows10
- Unity Hub 2.4.5
- Unity 2020.3.25f1
- Android Studio 2020.3.1

# Unity側のbuild準備(SDK等の設定)
Android向けの環境構築方法については以下の記事を参照。

https://qiita.com/Nossa/items/4b2c5026698ed4ab7d2b

https://qiita.com/tak001/items/e7a5f21742d463a37a39

# Android側の設定を開発者モードにする
Unity側の設定が終わったら次は Android 側の設定を行います。

機種によって異なりますが、
「設定」 > 「システム」 > 「端末情報」 に行くと「**ビルド番号**」という項目がありますので、**7回ほどタップ**します。

すると「開発者モードになりました」というようなメッセージがでます。

# Android側でUSBデバッグモードにする
続いては、Android側でシステムの画面まで戻ると、
「**開発者向けオプション**」というような項目が追加されていますので、
項目をタップして画面遷移します。

少し下の方へスクロールすると、「**USBデバッグ**」という項目がありますので、
ONにします。

# PCとAndroidをつなぐ
PCとAndroidをUSBでつなぎます。

※USB使用モードは「ファイルを転送」にする必要があります。
(上から下にスワイプして出る通知バーに項目があります)

# Unity側でBuild And Run
あとは、Unity側でしっかり設定をしていれば「Build And Run」をして実機側で開発中のアプリが起動されます。
(少し時間がかかります)
今使ってるLinuxをDockerイメージ化する

# はじめに
`Dockerfile`で宣言する`FROM centos:7`などのベースイメージは公式で配布するもの使用するのが一般的ですが、こういったベースイメージは実は自前の物を使う事もできます[^1]。今回は自分が使用しているシステムをそのままDockerイメージ化する方法をまとめて置きます。

# Dockerイメージの作り方
Linuxでベースイメージを作るにはそのままで稼働できるファイルの群れ、すなわちルートファイルシステム[^2]が必要です。今回は使用中のLinuxシステムをそのままイメージ化することが目的なのでシステム自体を圧縮してファイル化します。

## 1. 全体のシステムをコピーする
`rsync`を使ってシステムのスナップショットを作ります。その時、`/dev`, `/proc/`, `/sys/`, `/run`, `/mnt`は現在のマシーンに依存するディレクトリーなので除外します。
下記の例では`/mnt/copy`にシステムをコピーします。

```bash
rsync -avz /* /mnt/copy/ --exclude '/dev' --exclude '/proc' --exclude '/sys' --exclude '/run' --exclude '/mnt'
```

## 2. 除外したディレクトリーを生成する
除外したディレクトリーもまたシステムに必要なものなので空のディレクトリーを生成します。

```bash
mkdir /mnt/copy/sys /mnt/copy/dev /mnt/copy/proc /mnt/copy/run /mnt/copy/mnt
```

## 3. `tar.gz`に圧縮する
軽量化のために`tar.gz`を使います。また、この時、ルートが`/`になるようにすることが重要です。今回は `/mnt`の中で`-C`オプションを使いました。

```bash
cd /mnt
tar -czvf my-linux.tar.gz -C copy  .
```

## 4. Tarballを使ってイメージを作る
`Tarball`をそのまま`import`する方法[^3]とDockerfile[^1]を使う方法があります。

### Tarballをそのまま取り入れる

```bash
docker import my-linux.tar.gz
```

### Dockerfileでイメージをビルドする

```Dockerfile:Dockerfile
FROM scratch
ADD my-linux.tar.gz /
CMD ["/bin/bash"]
```

```bash
docker build --tag my-linux:lastet .
```

[^1]: Create a base image, https://docs.docker.com/develop/develop-images/baseimages/
[^2]: root ファイルシステム, https://www.ibm.com/docs/ja/aix/7.2?topic=tree-root-file-system
[^3]: docker import, https://docs.docker.com/engine/reference/commandline/import/
jupyter notebookでcondaで作った仮想環境を使う

# やりたいこと
anacondaで仮想環境を作った。
これをjupyter notebook上で使いたい。

# 環境
- windows 10
- anacondaをインストール済み

# やり方
### 前提
次のコマンドとかで仮想環境HOGEが既に作ってあるとする。

```terminal
conda create -n HOGE
```

### 手順
1. 環境HOGEに入る

    ```terminal
    C:\Users\username> conda activate HOGE
    ```

1. notebook, ipykernelをインストールする

    ```terminal
    (HOGE) C:\Users\username> conda install notebook ipykernel
    ```

1.  jupyter notebookを実行


    ```terminal
    (HOGE) C:\Users\username> jupyter notebook
    ```

1.  jupyter notebookのNewボタンからファイルを開き、必要なライブラリを使えるかimportとかしてみて確認する。できたら終わり。

    下の図では```!conda list```で入っているライブラリを表示して、確認している。
    また、```import cv2```を実行して正常にimportできるか確認している。
    
    ![スクリーンショット 2022-01-15 232817.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2510180/8854d25b-347a-d056-585a-75ff39bca8ba.png)


### 2回目以降の入り方
terminalから環境HOGEに入って、```jupyter notebook``` を実行するだけ


# なぜ書いたか
普段はterminal上で環境を立てて使用しているが、他人にプログラムを教えることになり、jupyterを初めて触る必要が出たため。

# 余談
初めてqiita上で記事を書いた。久しぶりにマークダウンを書いて、書くのに結構時間がかかった。
別のFirebaseプロジェクトにアクセスしたい場合

# この記事を書いた理由

大体のアプリではクラッシュログとかを拾うためにFirebaseを組み込んでいるアプリが多いと思います。その場合は通常アプリ＝Firebaseプロジェクトとなっていますが、例えば他のアプリとデータを共有したいとか別のFirebaseのプロジェクトにアクセスしたい場合が発生したので、共有のために貼っておきます。

ニーズが少ないのかあまり情報がなかったので、ちょっと苦労しました。と言っても数時間ではありますが。

# やり方

今回は事情があってObjective-Cのコードですが、Swiftの人は置き換えてみてください。

流れとしては、別のプロジェクトを指定するためには、GoogleService-Info.plistをまるっと使います。「OtherApp.plist」とでもリネームしてプロジェクトに取り込んでください。

そして、「OtherApp.plist」へのファイルパスを指定して、FIRAppのインスタンスを作成します。
こんな感じです。

```objectivec
@property (nonatomic, retain) FIRAuth *auth;

-(void)setup {

    // plistのパスを取得
    NSString *filePath =[[NSBundle mainBundle] pathForResource:@"OtherApp-Info" ofType:@"plist"];

    // plistを指定してFIROptionsを作成します
    FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];

    // 読み込んだ設定に名前をつけます。
    [FIRApp configureWithName:@"OtherApp" options:options];

    // 指定した「OtherApp」を指定してFIRAppオブジェクトを作成します
    FIRApp *app = [FIRApp appNamed:@"OtherApp" ];

    // FIRAppオブジェクトを使ってFIRAuthオブジェクトを作成します
    self.auth = [FIRAuth authWithApp:app];
}
```

例えば、こんな感じ。

```objectivec
-(void)doHogehoge {

    [ self.auth signInAnonymouslyWithCompletion:^(FIRAuthDataResult * _Nullable authResult,
                                                      NSError * _Nullable error) {

        // 認証後に必要な処理（Firestoreへのアクセスとか）をここで書く

    }];
}
```

今回はデータを共有したかったのですが、Analyticsを一つにまとめたいとかにもいいかもしれません。
dpkg ってなに？

## 勉強前イメージ

ubuntu触ってたときにコマンドであったけど
debian系のyumみたいなやつ？？

## 調査

### dpkg とは

dpkg とは Debian Package の略で、 Debianのパッケージを管理するコマンドになります。
`debファイル` を使ってパッケージのインストールを行います。
Redhat系では `rpm` に相当するようなものになります。

Redhat系のyum同様、Debian系にもaptというものがあります。
aptはパッケージのを操作したり管理したりするものになります。

yumのがわかりやすいーな方は [こちら](https://qiita.com/miyuki_samitani/items/9ac04ca2b783575d8371) も見ていただけますと
理解がしやすいかもしれません。

### debファイルってなに？

Debian系で使用されるパッケージの拡張子がついたファイルで、
インストールする際は、debファイルを先にダウンロードしてからインストールを行います。

### dpkg と apt の役割の違い

dpkg,apt、どちらもインストールは行いますが
aptは統合的にパッケージを管理し、依存性を解決しながら順番に必要なパッケージをインストールするものになります。

イメージとしてはカレーを作る際は
dpkgでは、玉ねぎ・カレールー・人参・お肉 を単体で買ってきて、それぞれ切ってからお鍋に入れないといけないですが
aptでは、玉ねぎ・カレールー・人参・お肉が入ったカレーセットを買ってきて、まるごとお鍋に入れてしまうイメージです。
aptのときはカレールーは後から入れたいな・・・って思っても自動的に野菜が炒まってから自動的に入れてくれます。

### ちょっとしたコマンド比較

- インストール
	- dpkg -i [debファイル]
	- apt install [パッケージ名]
- すべてのパッケージを表示
	- dpkg -l
	- apt list

## 勉強後イメージ

前触ってたときはほぼapt-getしか使ってなかったからわからんかった・・・
dpkg初めて知った。
てか、apt-getじゃなくてaptなの？
それは今度確認しよ。

## 参考

- [debファイルを扱うdpkgコマンドの使い方を簡単解説](https://eng-entrance.com/linux-package-dpkg)
- [Linuxのパッケージシステムを知ろう第2回(宮崎悟氏)](https://kusanagi.dht-jpn.co.jp/2020/02/linux%E3%81%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E7%9F%A5%E3%82%8D%E3%81%86%E7%AC%AC2%E5%9B%9E%E5%AE%AE%E5%B4%8E%E6%82%9F%E6%B0%8F/)