OmniAICreator/Qiita-1.07M huggingface dataset:
情報セキュリティマネジメントに(多分)受かった話

2021年7月に情報セキュリティマネジメントを受けて、多分合格したので勉強方法などを書いていきたいと思います。
多分。と言ったのはまだ合格証が届いてないからです！IPAの合格発表に受験番号があったので合格はしてるとは思うんですけどね…してなかったら笑ってやってください。

それでは、以下に詳しく書いていきます。

#試験を受けた理由
~~簡単に資格手当が貰えそうだったから。~~

2021年3月に基本情報技術者試験受験直後、次に何を受けようかと思った時に何となく情報セキュリティマネジメントの午前試験の過去問を解いてみたら「あれ？今から頑張れば合格できるんじゃないか？」と思ったのがきっかけでした。
まだ基本情報技術者試験の手ごたえからして、その時は多分落ちていたと思っており、再チャレンジするよりはっここで情報セキュリティを勉強して確実な得点源にしたかったのもあります。
幸いにも基本情報技術者試験は合格したのでその考えは杞憂に終わりました。
なので、下記に示す勉強方法や、自分が感じた難易度は基本情報技術者試験に少なくとも午前試験は確実に合格する人から見た基準になると思います。

#合格した時の点数
- 午前70(ストラテジ88%/マネジメント62%/テクノロジ66%)
- 午後88(問1,79%/問2,91%/問3,88%)

午前試験が予想よりも難しくてめちゃくちゃ焦りました。正直、午前試験を落としたかと思って帰ろうと思いましたが、試験終了後にプロメトリックからのメールで受かってることがわかって凄く安心しました。
午後は午後で「全然わからん…」と思いつつ解いてました。88点も取れていて正直びっくりです。65点くらいしか取れてないと思ってました。

次に詳しい勉強方法を書いていきます。

#使用したテキストなど
午前試験の対策で使ったのはこの教科書&過去問集と

https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E5%87%BA%E3%82%8B%E3%81%A8%E3%81%93%E3%81%A0%E3%81%91-%E6%83%85%E5%A0%B1%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%9E%E3%83%8D%E3%82%B8%E3%83%A1%E3%83%B3%E3%83%88-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-2021%E5%B9%B4%E7%89%88/dp/4798168696/ref=sr_1_14?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%81%86%E3%81%8B%E3%82%8B+%E6%83%85%E5%A0%B1%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3&qid=1629989583&sr=8-14

https://www.sg-siken.com/

多くの人が利用しているであろうこのサイトです。
実はかつてcomptia security+に挑戦したこともあり(結果として落ちました…再挑戦しようと思ったら基本情報の試験が近くなって諦めましたのでいつかリベンジしたい)割と内容は1/3くらいは見たことがある物が多かったです。
自分は教科書をパラパラ見た後にひたすら問題を解きまくって、知識を補完する辞書みたいな使い方をしてました

これに加え、TACの講座を受講して入手したテキストを利用してました。

https://www.tac-school.co.jp/kouza_joho/joho_ip.html

基本情報では大原を利用しましたが今回はTACです。理由は受験を決めた時に大原は締め切っており、ギリギリ間に合うのがTACだったからです。
結論から言うと、自分には不要だったしれません。
しかし、テキスト自体は非常に質が良く、市販の過去問よりも多くの問題パターンを解くことが出来るので確実に合格できるラインに持って行けたのはこの講座のおかげだと思っています。
情報セキュリティマネジメントに限らず、個人的にはこういった資格の講座は積極的に利用すべきだと思っています。独学は厳しいと感じたり、周囲に教えてくれる頭の良い人が居ないという状況なら利用するべきと思います。
テキストを手に入れるという理由でも十分かと思います。

#勉強方法

###午前試験

過去問を解きまくれ。これで終わってしまいます。
ITパスポートや基本情報を持っているなら多分楽に解ける人も多いかと思いますが、そうでない人はテキストを1周眺めてから過去問に挑戦しましょう。
隙間時間は過去問道場を利用して、ソシャゲの周回のような感覚で解いていきましょう。
じっくり時間が取れるなら、過去問集かIPAのHPからダウンロードしてきたものを解いていきましょう。
時間が取れるときは問題の正解不正解に関わらず選ばなかった選択肢の用語や意味などもテキストで調べて理解しておくと本番でも対応できる力が付くと思います。
ただ、2016年に始まった試験という事もあり過去問もまだ少ないです。もし不安なら基本情報技術者試験のセキュリティ分野なども解いてみると良いかもしれません。

###午後試験
これもひたすらに過去問。
市販の過去問集を解いていくしかないです。
ここで通信講座を受講するアドバンテージがあると思います。
通信講座のテキストは過去3年よりも前の問題はもちろん、他の情報技術者試験の過去問から抜粋された問題も解くことが出来ます。
沢山の問題に触れることが出来て、かつ解説もついている。経験できる問題のパターンが増えるので本番での対応力が養えると思ってます。実際に自分はそう感じました。

また、午前と午後どちらにも言える事ですが、この試験はITを利用する人に向けた試験なので学生よりも就職して働いている社会人。非IT系なら総務などの事務方で働いている人の方が内容をすんなりと理解できるのではないかと感じます。働いていると常識的に考えてこうだよね。という感覚で解ける問題も存在するからです。とはいえ、気持ち程度なのでどんな人間でもしっかり勉強は必要と思います。

#終わりに
駄文ではありますが、勉強した時の内容を思い出して書いてみました。
通信講座のテキスト推し。みたいになってしまいましたが、それだけ自分としてはメリットが大きいと思っているからです。他の人がどう思っているかは知りません。
ITパスポートからのステップアップにもちょうどいい試験と思っていますので、受ける人にとって参考になれば幸いです。
Docker

# Dockerのイメージとコンテナ　

#1.イメージの取得、表示、削除
### レジストリからイメージを取得
```
docker pull イメージ名
例）docker pulll イメージ名:バージョン指定可能
``` 
### 取得したイメージを表示、確認
```
docker images
```
### 取得したイメージを削除する
```
docker image rm イメージ
省略)docker rmi イメージ
```
#2.イメージからコンテナを作成,起動,停止,削除
### コンテナの作成
``` 
docker create --name ○○○ イメージ名
詳細） --nameで名前を付けてから作成する
```
### コンテナの確認
```
起動中のコンテナ表示
docker ps 

すべてのコンテナ表示
docker ps -a
```
### コンテナの起動
```
docker start イメージ名
```
### コンテナの停止
```
docker stop イメージ名
```
### コンテナの削除
```
docker rm イメージ名
```
### コンテナを全て削除
```
docker ps -a -q | xargs docker rm
```
#Nginxで作成されたページを確認する方法
```

docker create --name 指定名　-p 8080:80 nginx
詳細）８０８０：８０　　← ホストのポート：コンテナのポート
　　　　　　　　-p ← コンテナのポートをホストい結びつけ参照できる
```
#コンテナの作成と起動を一緒に行う
```
例）Nginxの場合
docker run --name 指定名　-p 8080:80 -d --rm nginx
詳細）　　-d ← バッググラウンドで行う
　　　　　　　　　　-rm ← 停止されたら削除も行う
```
不偏分散とその意味

#不偏分散
不偏分散$U^2$,分散$S^2$は、標本平均$\bar{x}$,母平均$\mu$を用いて

```math
U^2 = \frac{(x_1- \bar{x})^2 + \cdots +(x_n - \bar{x} )^2}{n-1}\\
S^2 = \frac{(x_1-\mu)^2 + \cdots +(x_n- \mu)^2}{n}
```
で計算できる。

不偏分散が出てきた時、なぜ$n-1$なのかと思ったと思う。
一般的な本には「母集団の平均が不明な場合、分散を計算する際にサンプル平均を使うため、自由度が1減る」という説明がある。

これでは、なかなか理解できない。

母集団の分散$\sigma^2$を推定する場合

```math
 \sigma^2 = E[U^2]
```
ということがわかっているため、母集団の分散の推定値には不偏分散を用いた方が正確である。

というのが不偏分散の登場理由である。

実際に数値実験的に確認してみよう


```python
import numpy as np

n = 3
sample = 1000000

a = np.random.normal(
    loc   = 0,      # 平均
    scale = 1,      # 標準偏差
    size  = (sample ,n),# 出力配列のサイズ
)
"""
分散　　母平均を 0 と考える
"""
b = a - 0
b = np.power(b,2)     #要素二乗
variance = np.average(b,axis =1) #平均

"""
不偏分散
"""
b = a - np.mean(a,axis=1,keepdims=True)
b = np.power(b,2)     #要素二乗
unbiased_variance = np.sum(b,axis =1) / (n - 1)  #不偏分散なので n-1　で割る

"""
nで計算した分散
"""
b = a - np.mean(a,axis=1,keepdims=True)
b = np.power(b,2)     #要素二乗
unbiased_variance_n = np.sum(b,axis =1) / (n) 

"""
"分散"の平均、"不偏分散"の平均
"""
print("母平均がわかっているときの分散",np.average(variance))
print("不偏分散",np.average(unbiased_variance))
print("サンプル平均を使った分散",np.average(unbiased_variance_n))
```

結果は
母平均がわかっているときの分散 0.9996464706972592
不偏分散 0.999581178605888
サンプル平均を使った分散 0.6663874524039257

サンプル平均を使った分散が大きくずれていることがわかる！
不偏分散が真値の1にかなり近づいていることもわかる

#標本集合の要素数を3から変更して検証
###2
母平均がわかっているときの分散 1.0021416786906032
不偏分散 1.0014327352482277
サンプル平均を使った分散 0.5007163676241139

###3
母平均がわかっているときの分散 1.000000014187304
不偏分散 1.0004516102869003
サンプル平均を使った分散 0.6669677401912671

###4
母平均がわかっているときの分散 1.0010940305736264
不偏分散 1.0007410172074758
サンプル平均を使った分散 0.7505557629056064

###5
母平均がわかっているときの分散 1.0006225254226295
不偏分散 1.000463727944869
サンプル平均を使った分散 0.8003709823558951

###6
母平均がわかっているときの分散 1.0002051778361192
不偏分散 1.0002880714769913
サンプル平均を使った分散 0.8335733928974929

###7
母平均がわかっているときの分散 0.9996752826709271
不偏分散 0.9997116560516751
サンプル平均を使った分散 0.8568957051871497

###8
母平均がわかっているときの分散 0.9998854629176267
不偏分散 0.9997083843519304
サンプル平均を使った分散 0.8747448363079388

###9
母平均がわかっているときの分散 1.0002379562128902
不偏分散 1.0004974505139073
サンプル平均を使った分散 0.8893310671234737


**不偏分散は常に真値に近く**、
サンプル平均を使った分散も少しずつ真値に近づいていることがわかります。


#まとめ
以上より、標本が得られたときに、母集団の分散を推定する場合、不偏分散を使った方が、サンプル平均を使った分散より正確に推定できると考えられる。


#追記：数式的証明

```math
\begin{align}
E[(n-1)U^2]\\
&=&E[(x_1 - \bar{x})^2 + \cdots + (x_n - \bar{x})^2\\
&=&E[(x_1^2+\cdots + x_n^2) + n \bar{x}^2 -2 (x_1 + \cdots + x_n) \bar{x}] \\
&=&E[(x_1^2+\cdots + x_n^2) - n \bar{x}^2 ] \\
\end{align}
```
第一項は

```math
\begin{align}
E[x_i^2] 
&=&\sigma^2 + \mu^2 \\(x_i = N(\mu,\sigma^2))\\
\end{align}
```
といえる。（二乗平均は　平均の二乗　＋　分散　より）

第2項は

```math
\begin{align}
E[\bar{x}^2 ] 
&=&V[\bar{x}] +E[\bar{x}]^2\\
&=&\frac{\sigma^2}{n} + (\frac{n \mu}{n} )^2\\
&=&\frac{\sigma^2}{n} + \mu^2
\end{align}
```
よって


```math
\begin{align}
E[(n-1)U^2]\\
&=&E[(x_1^2+\cdots + x_n^2) - n \bar{x}^2 ] \\
&=& n(\sigma^2 + \mu^2 ) - (\sigma^2 + n\mu^2) \\
&=& (n-1)\sigma^2
\end{align}
```

よって

```math
E[U^2]　=\sigma^2
```

が示された
営業出身文系SEのDockerややこし情報整理

## Dockerややこしポイント

### RUN? START? BUILD? 何で何してるかわからん

最初Dockerというものを知ったときに持っていた印象は
「なんか好き勝手遊ぶ環境が手に入るんだろうなぁ」でした

実際そうはそうなのですがその遊ぶ環境(コンテナ)を手に入れるために取る手順がよくわからず困ったので
それについて簡単に覚書を書いておきます。

### とりあえず用語をまとめておく

* Image

コンテナを立ち上げるための情報が詰まったもの
こいつ自体はDockerHub　とかからでも引っ張って来れるしDockerfileから作ることも可能

* Docker file

Imageを作るための定義書
DockerHubにあるイメージもみんなが自分の環境でBuildしたDockerfileのImageをあげてる
人のやつ使ったことないからわかんないけど多分すごいんでしょう

* Build

Docker FileからImageを作るためのコマンド
こいつを最初見た時からこのコマンドでコンテナを立ち上げると思ってしまってずっとDokcer FileとImageの関係性がわからなかった
こいつはコンテナの元になるImageを作るだけ！

* RUN

コンテナを立ち上げてスタートさせるコマンド
こいつもこいつでややこしい名前
このコマンドでやっとImageからコンテナを立ち上げて起動することができる


### いきなりDocker File作ろうとするな

小生基本的にアプリケーションばかり作ってきた人間ですのであまりLinuxについて詳しくありませんでした。
最近になってコマンド打ちながら頭の中でPCの状態を思い描けるくらいの感じ
なのでいきなりDokcer FIle作って環境のImage作るぜ！ってなってもいまいちイメージが掴めずあたふたしちゃいました

なので初めてDocker FIle作るよ〜って人は一回基本のImageだけパクってきて
それでRUNしてコンテナの中入ってその中でわちゃわちゃインストールするのを試してみるのがいいと思います。

実際初めて作った時のコードまとめておきます。

```

# ポート開けたpython3のImageからpython_1stっていうコンテナを立てた
docker run -d -it -p 8080:80 --name python_1st python:3

# コンテナの中に入った
docker exec -it python_1st /bin/bash

# UbuntuだったのでaptをUpdate
apt update -y

# Djangoをインストール
pip3 install Django

# Nginxをインストール
apt install -y nginx

# HTML直接書くためにHTMLをインストール
apt install -y vim

# HTMLをvimで作ってHello Worldだけ書く
vim /var/www/html/test.html

# Nginxを起動させる
service nginx start

# HTMLがChromeで確認できたら閉じる
service nginx stop

```

こんな感じ

でも毎回こんなんするんだるいからこれらのupdateしたりinstallしたりした結果をImageとして
Docke Fileから作ってそのImageでコンテナを立ち上げることでこれらの処理をなくして毎回同じ環境を作れるようにするというのがDockerの魅力の一つっぽい




頭の中スッキリしたのでいったんここでまたオリジナルDockerFile作り終わったら続き書くかも
[02] docker-compose を使って即座に dnsmasq を立てる (解説)

|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/e2ed733e09c9e39407f2|

# 概要

docker-compose を使って即座に dnsmasq を構築する手順を記す.

本項の内容は、[前項](https://qiita.com/robozushi10/items/372785e962d282c6110f) の解説である.


# 参考にした記事

・https://qiita.com/tac0x2a/items/c6306b95dd27703bc975
・https://sites.google.com/site/hollyroyaltea/home/dns/dnsmasq


# 事前準備するファイル

次の構成でファイルを用意しておく. ファイルの中身については後述する.

```bash
.
|-- PV
|   `-- etc
|       `-- dnsmasq.d
|           |-- my.conf ...... dnsmasq コンテナ内の /etc/dnsmasq.conf から読み込まれる
|           `-- add_hosts .... 上記 my.conf から読み込まれる
`-- docker-compose.yml
```


# ファイルの中身

## docker-compose.yml

重要な点についてはファイル内にコメントを記した.

```yaml
version: '3'
services:
  dnsmasq:
    restart: always
    image: 4km3/dnsmasq
    container_name: mydnsmasq
    environment:
      TZ: "Asia/Tokyo"
    ports:
      - "53:53/udp"
      - "53:53/tcp"
    # PC を DNS に登録したい場合は ./PV/etc/dnsmasq.d/add_hosts を編集する
    volumes:
      - './PV/etc/dnsmasq.d:/etc/dnsmasq.d'
    dns:
      # 本ファイルの「dns」に対して、上位の DNSサーバを定義してしまえば、
      # PV/etc/dnsmasq.d/my.conf に上位 DNSサーバを定義する手間が省ける.
      - 8.8.8.8
      - 127.0.0.1
    cap_add:
      - NET_ADMIN
```

## PV/etc/dnsmasq.d/my.conf

`/etc/dnsmasq.d/.` に対して、`*.conf` というファイル名で配置しておけば、
設定ファイルとして読み込まれるので、ファイル名は自由である.

設定値については、「/etc/dnsmasq.conf」から必要な設定のみを取り出して再定義しただけである.

```bash
# プライベートIPの逆引きは上位DNSに転送しない
bogus-priv

# 名前と IP の管理を、/etc/hosts ではなく /etc/dnsmasq.d/add_hosts に変更する.
# (∵ コンテナ内の /etc/hosts は、ホスト側から容易にマウントできないため)
addn-hosts=/etc/dnsmasq.d/add_hosts  🛑

# 後述の「domain=」で指定されたドメインで補完する.
expand-hosts

# 補完するドメイン. ここでは「mylocal.domain」としているので適宜読み替えること.
domain=mylocal.domain
```

## PV/etc/dnsmasq.d/add_hosts

本ファイルに、PC の IP と マシン名を定義していくことになる.
なお、本ファイルは上記 🛑 によって読み込まれる.

ここでは、IP「10.208.200.123」とマシン名「piyo」を関連付けしている.

```
10.208.200.123  piyo
```


# 運用方法

## 起動

`docker-compose up -d` を実行するのみである

```bash
$ docker-compose up -d
```

起動したら、(コンテナを稼働させた PC で) 次のようにして確認すれば良い.

```bash
## dig 解決させたいマシン名 @<dnsmasq コンテナを稼働させているホストのIP>
$ dig piyo @127.0.0.1
$ dig piyo.mylocal.domain @127.0.0.1
```

## IPとマシン名の追加・変更・削除

`PV/etc/dnsmasq.d/add_hosts` を編集してから次を実行すれば良い

```
$ vim PV/etc/dnsmasq.d/add_hosts
(編集する)

$ docker-compose restart
```

以上.
[01] docker-compose を使って即座に dnsmasq を構築する (構築手順のみ)

|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/e2ed733e09c9e39407f2|

# 概要

docker-compose を使って即座に dnsmasq を構築する手順を記す.

**ここでは、私にとって最短手番での dnsmasq の起動手順を記す.**
説明については、[[02]](https://qiita.com/robozushi10/items/bc455bff0899d2d73f58) に記した.

なお、本手順は物理ホストの 53番ポートを解放済みであることを前提にしている.


# 手順

## 初回起動

```bash
## docker-compose.yml など一式を clone する
$ git clone https://github.com/robozushi10/qiita-dnsmasq.git
$ cd qiita-dnsmasq

$ vim PV/etc/dnsmasq.d/add_hosts
## /etc/hosts と同じ要領で記述する
10.208.200.123  piyo

$ docker-compose up -d
```

これで、物理ホストの IP と 53 ポートを DNSサーバとして使用すれば
名前解決ができるはずである.

## IPとマシンの定義を変更したい場合

```bash
$ vim PV/etc/dnsmasq.d/add_hosts
(IPとマシン名を定義する)

$ docker-compose restart
```

以上.
Tableau Publicで値フィールドを1つにまとめる「メジャーバリュー」の使い方を確認。「小売物価」推移データを利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/37289ea8-2829-6bd2-eba2-27347801d47a.png)

##小売物価統計調査のデータを使う

Tableau Publicを使っていると、**「メジャーバリュー」**という名称のフィールドが自動生成されることがあります。
調べてみると、

>[メジャー バリュー] フィールドには、データのすべてのメジャーが連続する値を使用して 1 つのフィールドに集められています。

https://help.tableau.com/current/pro/desktop/ja-jp/datafields_understanddatawindow_meavalues.htm

とのことです。

実際に操作して確認してみたいと思いました。
小売物価統計調査のデータを使ってみます。

https://www.stat.go.jp/data/kouri/doukou/index.html

政府統計の総合窓口[「e-Stat」](https://www.e-stat.go.jp/)からデータを取得します。
今回は「銘柄」として「さんま」「鶏（もも）」「バター」「バナナ」「ガソリン」を選択しました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/122fac89-94f0-4113-7dcb-3ec0d1dd61ad.png)


CSVファイルをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/870ce982-ed5b-a503-8043-4430ab60aba5.png)

Tableau Publicでは、Power BI Desktopが持つPower Query エディターのようにデータをクレンジングする機能を豊富に持っていないので、（使える機能があったかもしれませんが）Excel上で取り込みやすい形にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/ee798630-4ef6-5e9a-a4a7-3f062960d90e.png)

##まずTableauでコンパクトな形で取り込む

Tableau Publicにインポートします。
時系列データが横に並んでいるので、BIツールでよく使うスタイルの「時間軸」と「値」列の形に収納します。
収納する範囲を選択して、「ピボット」を実行すると、以下のようなスタイルに変わります。
（これはメジャーバリューを使わない例です。この後に使うケースを扱います）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/da9f1ca7-7f12-5778-1ac6-b99e90867d4d.png)

ワークシートに移って可視化します。
各フィールドをドラッグして右側に下記画面のように配置し、折れ線グラフを作りました。
グラフ左側の「マーク」に「銘柄」フィールドを配置し「色」属性とすると、線の色が銘柄ごとに変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/ba226256-c2c5-70f3-5683-a2945d1e4807.png)

ここでは「メジャーバリュー」はできていません。

##メジャーバリューを作り出す

「メジャーバリュー」を生成するために、「さんま」「鶏（もも）」「バター」「バナナ」「ガソリン」の各値列をExcelで作り、Tableauにインポートしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/a94c4cbe-3820-5f61-f5de-58fa89476aa1.png)

ワークシートで、各フィールドを下記画面のように配置します。
左側に「メジャーバリュー」が生成されました。
「さんま」「鶏（もも）」「バター」「バナナ」「ガソリン」の各値が「メジャーバリュー」という1つのフィールドに収納されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/15386ec3-a0b0-830c-35a0-7031d7324b13.png)

「さんま」「鶏（もも）」「バター」「バナナ」「ガソリン」を配置している場所にこれら5つのフィールドの代わりに「メジャーバリュー」を置きます。
スタイルは変わりますが、5本のグラフが生成されます。
対をなすように「メジャーネーム」も生成されます。
こちらはフィールド名称を1つにまとめます。
グラフ右の「マーク」にドラッグし、「色」属性にすると、銘柄ごとに色が変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/37289ea8-2829-6bd2-eba2-27347801d47a.png)

想定通り、上記方法で「メジャーバリュー」を意識できる手順を確認できました。

なお、「さんま」「鶏（もも）」「バター」「バナナ」「ガソリン」の各フィールドを配置して作成したグラフ（2つ上）は、5本のグラフごとにY軸を持っています。
メジャーバリューを使ったグラフのように1つのY軸で5本のグラフを描く場合、各フィールドをY軸にドラッグします。
下の画面では、「ガソリン」フィールドをドラッグしている様子です。
緑の長方形が2つ並んでいる個所に、ちょうどドラッグしたフィールドを持っていっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/dab9782a-0747-1cf3-fec2-4ecc00cc4456.png)

前の画面からもわかりますが、この方法で進めると、自動的に「メジャーバリュー」に収納されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/ad5bb6fe-58bd-7fde-9df5-f8ffbad5912c.png)


**了**
AtCoderで入水してみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/a37ee377-07ba-6e59-4871-0b542ff3851c.png)

唐突だけど2年ちょい頑張ってようやくここまでたどり着いたよ。

#自己紹介
どこにでもいる普通のプログラマ27歳。
中学3年の時の「高校の体験入学」で教えてくれたプログラミングに感動し、プログラマになることを目指した。その時の情熱みたいなものは今も心の中で燃えてるよ。

#始めたきっかけ
仕事中、「私のプログラミング能力は一般的にはどんなもんなんだろうか？」と思ったことがスタート。
最初はPaizaでプログラミングのテストがあることを知って転職への影響や市場価値を計るためにスキルチェックしまくった。早い段階でAランクに到達し、スカウトもバンバン来たが転職すること自体興味なし。（最終的にはSに到達）
他に無いかなとその辺うろついてたらAtCoderに出会ったよ。

#AtCoder上での頑張り度合い
https://kenkoooo.com/atcoder/#/user/watarimaycry2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/b7885511-55f4-29a2-8b9d-5479b5d0c190.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/fa413e66-f1c8-45ac-8397-a12a603cacb5.png)

コンテスト時間中の頑張りは、Twitterで「#競プロクソ考察」で検索

ユニーク性の高い頑張りは多分コレ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/1625f830-c747-c418-8075-8543552a1ff7.png)

以下の流れで今に至る。
・メインはJavascript、処理コストやデータ構造の都合でNGならサブでJavaでやろう。
・もっと問題解きたいな。過去問埋めていこう。
・Javascriptユーザ少ないみたいだしJavascriptのACランキング上位目指すか。
・Javaも本気出すか。

https://twitter.com/watarimaycry2/status/1304474991296045058?s=20

（↑は↓の問題をノーヒントで解けた直後のやつ）
https://atcoder.jp/contests/abc059/submissions/16637447

精進自体仕事中でもできるんだが、Javaで埋めてる時は本当に疲れた。

#JavaとJavascriptを使ってる理由
仕事で使ってるから。技術向上のついで。
なんか別言語で仕事せざるを得なくなったら、その別言語でAC埋めしまくるかも。

#仕事で役立つ？
web開発系なので競プロで学んだ典型アルゴリズムの構築とかは活かせてないが、以下の副産物は得られた気がするよ。
・基礎体力
・即効性の高いプログラミング力
・考察力
・言語特有の知識力

直近例
偉い人にサーバのCPU使用率のログ解析、抽出を急ぎで頼まれた。
競プロやってなかったら半日かかってたかも。1時間ちょいで終わらせた。

https://twitter.com/watarimaycry2/status/1421060100282671105?s=20


```
・問題
クエリがいくつか与えられる。
与えられるクエリには日付情報Di、時刻情報Ti、CPU使用率Ciが記載されており、予め用意した配列上にCPU使用率を加算していく。
できた配列の結果をCSVに出力すること

・配列の形
|hh:mm| 0:00 | 0:05 | 0:10 | … | 23:50 | 23:55 |
| day |  -   |  -   |  -   | - |   -   |   -   |
| 0   |      |      |      |   |       | 10000 |
| 1   |      |  50  |      |   |       |       |
| 2   |      |      |  10  |   |   80  |       |
| 3   |      |      |      |   |       |       |

・クエリ(本当はもっと複雑な形)
7/20 17:25 50.53%
7/20 17:40 72.27%
・・・

・条件
クエリの総数は不明
Di Tiは昇順ソート済み
TiとTi+1の差は5以上（差自体は5の倍数だが、必ずしも差が5ぴったりとは限らない）

・解法
時刻は12進数の考えで左から「時刻 * 12 + (分 / 12)」番目に加算しよう。
```

共同とはいえ、解法を思いつけた時は楽しかったな～

#AtCoder以外でもやってるけど・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/0d00187b-7845-1e4e-92c5-fea563217ed9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/760dc107-051d-ee53-6eea-8db64c1733cb.png)

社会人なので夜中までやるのはしんどい。参加できる時はやってるよ。
CodeForces問題埋めも再開しないとだな。

#続けられる理由
理論的な理由は不明。
「プログラミングを使って何かやること」が苦で諦めがあったり挫折とかは何度もしたけど、「プログラミングをすること」自体が苦になったことは無い。
初めて触れた時の感覚が残ってる間は、少なくともモチベーションは下がらないと思う。

個人的に「相互にライバル意識を持つ存在」がいたらいいなとか思ってるけど特にいない。

#次の目標
30歳までに青色に行く。行けるかどうか知らんけど。
PHPのスコープ

PHPでグローバルスコープ、ローカルスコープを学習したので忘れないように備忘録として残していきます。



##グローバルスコープ
開発環境の全てに影響を及ぼす変数（スコープ外の変数）

```php
$globalScope = 'グローバルな変数です';

function localScope()
{
  $localScope = 'ローカルな変数です';
  echo $localScope;
}

echo $globalScope;
```


`echo $globalScope;`で「グローバルな変数です」と表示されます。


グローバル変数を関数内で直接は使用することはできません。
関数内で直接使用するには関数内で

```php
function localScope()
{
  global $globalScope;
  $localScope = 'ローカルな変数です';
  echo $localScope;
}
localScope();
```

関数内の$globalScopeの前に`global`をつけることで関数の中で記述した変数を呼ぶことができます。


##ローカルスコープ
スコープの関数内での中だけで使える変数



```php
function localScope()
{
  $localScope = 'ローカルな変数です';
  echo $localScope;
}

localScope();
```

関数を呼ぶ時はスコープ外で`localScope()`と記述すると呼ぶことができます。


###関数内でグローバル変数を使いたい時は引数に書くようにします

```php
$globalScope = 'グローバルな変数です';

function localScope($val)
{
  echo $val;
}

localScope($globalScope);
```
dnfコマンドでRPMファイルをダウンロードする

# What's？

タイトル通り。

パッケージのRPMファイルを簡単にダウンロードする方法が知りたいな、と。

# 環境

CentOS 8で確認します。

```shell
$ cat /etc/redhat-release
CentOS Linux release 8.4.2105


$ uname -srvmpio
Linux 4.18.0-305.12.1.el8_4.x86_64 #1 SMP Wed Aug 11 01:59:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```

# RPMファイルをダウンロードする

これは、`dnf download`で簡単に実現できます。

Apacheを例に。

```shell
$ dnf download httpd
Last metadata expiration check: 0:38:55 ago on 2021年08月26日 22時50分47秒.
httpd-2.4.37-39.module_el8.4.0+778+c970deab.x86_64.rpm                                                                                      7.2 MB/s | 1.4 MB     00:00    
```

取得したRPMファイル。

```shell
$ ll httpd-2.4.37-39.module_el8.4.0+778+c970deab.x86_64.rpm
-rw-rw-r--. 1 xxxxx xxxxx 1466539  8月 26 23:29 httpd-2.4.37-39.module_el8.4.0+778+c970deab.x86_64.rpm
```

ダウンロードするファイルについては、もうちょっと指定することもできます。

ヘルプを見てみましょう。

```shell
$ dnf download --help
```

`download`に関するオプションは、こちら。

```shell
Download command-specific options:
  --source              download the src.rpm instead
  --debuginfo           download the -debuginfo package instead
  --debugsource         download the -debugsource package instead
  --arch [arch], --archlist [arch]
                        limit the query to packages of given architectures.
  --resolve             resolve and download needed dependencies
  --alldeps             when running with --resolve, download all dependencies
                        (do not exclude already installed ones)
  --url, --urls         print list of urls where the rpms can be downloaded
                        instead of downloading
  --urlprotocols {http,https,rsync,ftp}
                        when running with --url, limit to specific protocols
```

たとえば`--source`オプションを付与すると

```shell
$ dnf download --source httpd
```

src.rpmがダウンロードされます。

```shell
enabling appstream-source repository
enabling baseos-source repository
enabling extras-source repository
enabling epel-modular-source repository
enabling epel-source repository
CentOS Linux 8 - BaseOS - Source                                                                                                            121 kB/s | 350 kB     00:02    
CentOS Linux 8 - AppStream - Source                                                                                                         358 kB/s | 841 kB     00:02    
CentOS Linux 8 - Extras - Source                                                                                                            4.6 kB/s | 7.6 kB     00:01    
Extra Packages for Enterprise Linux Modular 8 - x86_64 - Source                                                                              16 kB/s |  14 kB     00:00    
Extra Packages for Enterprise Linux 8 - x86_64 - Source                                                                                     4.4 MB/s | 2.1 MB     00:00    
httpd-2.4.37-39.module_el8.4.0+778+c970deab.src.rpm
```
【GitHub Actions】トリガーにファイルパスとブランチの両方を指定したときの動作

GitHub Actions を使っていると、ファイルパスとブランチのANDが取れたときだけワークフローを動かしたくなることがある。

例えば、各ファイルに紐づくワークフローがあり、あるブランチにマージしたときだけ動かしたいとき。ここでは、未更新ファイルに紐づくワークフローは動いてほしくない。

期待はこう。

```
ファイル A を更新 → ワークフロー A だけが動く
ファイル B を更新 → ワークフロー B だけが動く
```

## こうすればOK

```workflow_A.yml
on:
  push:
    branches:
      - main
    paths:
      - 'file_A' #このワークフローに紐づくファイル名を指定
```

ただ、[公式Doc](https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions) に明示的に仕様が書かれていなかったので、いくつかのパターンで検証してみました。

## 検証

| ケース                                   | 期待動作                   | 
| ---------------------------------------- | -------------------------- | 
| ファイル A を編集し main ブランチに push | ワークフロー A が動く      | 
| ファイル B を編集し main ブランチに push | ワークフロー B が動く      | 
| ファイル C を編集し main ブランチに push | どのワークフローも動かない | 
| ファイル A を編集し test ブランチに push | どのワークフローも動かない | 


ファイル構成はこんな感じ。ワークフローの中身は[こちら](https://github.com/sasamuku/github_actions_test/tree/public_sample_trigger)。

```
.
├── .github
│   └── workflows
│       ├── workflow_A.yml
│       └── workflow_B.yml
├── file_A
└── file_B
└── file_C
```

## 検証結果

| ケース                                   | 期待動作                   | 結果 | 
| ---------------------------------------- | -------------------------- | ---- | 
| ファイル A を編集し main ブランチに push | ワークフロー A が動く      |  OK | 
| ファイル B を編集し main ブランチに push | ワークフロー B が動く      |  OK | 
| ファイル C を編集し main ブランチに push | どのワークフローも動かない |  OK  | 
| ファイル A を編集し test ブランチに push | どのワークフローも動かない |  OK  | 

以上の結果から、`on.push.branches` と `on.push.paths` を併用した場合は、ANDが取れた場合にのみ更新されることが確かめられました。
Chrombookからのsmb接続がうまくいかない

# Chrombookからのsmb接続がうまくいかない

## 現象
Chromebookにのファイルアプリケーションには標準で"SMBファイル共有"の機能がある。
これを使って自宅のubuntuサーバにsmb接続しようとしたが認証でエラーになってしまう。
原因がわからないので"File system for Windows"という拡張機能を入れて試してみたところこちらだと問題なく繋がった。

## 解析
サーバ側でlog levelを3にしてlogをとってみたところどうも"SMBファイル共有"だとユーザ情報など認証情報がうまくわたっていない模様。
"File system for Windows"だと認証情報が渡っているので相性なのか、"SMBファイル共有"側の不具合なのかが判断できない…。


"SMBファイル共有"の怪しいログ

~~~
[2021/08/26 22:34:37.419392,  3] ../../auth/ntlmssp/ntlmssp_server.c:550(ntlmssp_server_preauth)
  Got user=[] domain=[] workstation=[] len1=0 len2=0
~~~

"File system for Windows"のログ

~~~
2021/08/26 22:17:26.495028,  3] ../../auth/ntlmssp/ntlmssp_server.c:550(ntlmssp_server_preauth)
  Got user=[hogehoge] domain=[?] workstation=[FSP_CIFS] len1=24 len2=130
~~~

## というわけで
何か分かったらまた投稿します。
【Rails】掲示板コメント機能実装（メモ）

#　目標
###　コメント機能の実装

[![Image from Gyazo](https://i.gyazo.com/8b971d580120bd020f316bde87e15df4.gif)](https://gyazo.com/8b971d580120bd020f316bde87e15df4)
#　環境
* Rails: 6.1.3
* ruby: 3.0.0
* mac: os

#　前提
* 掲示板投稿機能実装済み
* 投稿テーブル名post

#　実装
##　１．モデルを作成
```ruby:ターミナル
$ rails g model Comment comment:string post:references
```
生成されたマイグレーションファイル。
今思えばモデル名もコメント名もcommentで紛らわしくしちゃった気がします。。

```ruby:
class CreateComments < ActiveRecord::Migration[6.1]
  def change
    create_table :comments do |t|
      t.string :comment
      t.references :post, null: false, foreign_key: true

      t.timestamps
    end
  end
end
```

マイグレーション実行。

```ruby:ターミナル
$ rails db:migrate
```
##　２．モデルの関連付け

```ruby:app/models/post.rb
class Post < ApplicationRecord
  has_many :comments, dependent: :destroy
```
postは複数のコメントを持てるので`has_many :comments`
post投稿を削除した際追従して、コメントも消えてほしいので`dependent: :destroy`を追記。

```ruby:app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :post
```
１件のコメントは１件の投稿に属していますね。
このアソシエーション部分かなり重要です。
##　３．ルーティング追加

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :posts do
    resources :comments
  end
end
```
ネストしたルーティングを記述。
`rails routes`で確認したら`post_commnts POST`が`/posts/:post_id/commnts(.:format)`になっています。

## 4.コントローラー作成

```ruby:ターミナル
$ rails g controller Comments
```
生成された`app/controller/comments.rb`に`create`アクションを記述。

```ruby:app/controller/comments.rb
class CommentsController < ApplicationController

  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(comment_params)
    if @comment.save
      flash[:success] = 'コメントを投稿しました'
      redirect_to post_path(@post)
    else
      flash[:danger] = 'コメント投稿に失敗しました'
      redirect_back(fallback_location: posts_path)
    end
  end
end

private

def comment_params
  params.require(:comment).permit(:comment)
end
```
# 5.ビューに記述
投稿詳細ページにコメント投稿フォームとコメント一覧を作成する。

```erb:app/views/posts/show.html.erb
<%= form_with(model:[ @post, @post.comments.build ], local:true) do |form| %>

    <div class="form-group">
        <p>
            <%= form.label 'コメント(255文字未満)' %>
            <%= form.text_area :comment,class: 'form-control' %>
        </p>
    </div>
    <div class="form_action row">
        <%= form.submit 'コメント投稿',class: 'btn btn-primary' %>
    </div>
<% end %>
```

コメントしたユーザーの名前と作成時間、コメント内容の記述。

```erb:app/views/posts/show.html.erb

<% @post.comments.each do |comment| %>
   <P><%= comment.user.name %> : <%= comment.created.at %></p>
   
   <p><%= commet.comment %></p>
<% end %>
```
ざっくりとはしていますが、これで投稿に対してのコメント機能が使えるはずです、この辺りはしっかりおさえておきたいので備忘録として残しておきます。
#　参考
参考にさせていただいた記事です。
https://qiita.com/nojinoji/items/2034764897c6e91ef982
https://qiita.com/__kotaro_/items/8a6bda99dab61d2a72a5
クソデカログを生成するコマンド

### はじめに
先日、クソデカログを生成したくなったので方法を共有します。


### 各行の文字列が同じでも良い場合

head のオプション `-n 10` が行数を表してます。10をクソデカ数に書き換えてください

```shell
$ yes | head -n 10
y
y
y
y
y
y
y
y
y
y
```

ファイルに保存したい場合は次のようにしましょう。

```
$ yes | head -n 10 > kusodeka.log
```


### 各行の文字列がランダムであってほしい場合

fold のオプション `-w 20` が 1行の文字数、head のオプション `-n 10` が行数を表してます。

1行をクソ長にしたい場合は20をクソデカ数に、行数をクソデカにしたい場合は10をクソデカ数に書き換えてください

```
$ cat /dev/urandom | LC_ALL=C tr -dc "[:alnum:]" | fold -w 20 | head -n 10
zQrYUcA346KBl2EoJdaw
N7JSAh63K2woc0N3gguM
uQoYadLuyfkIX5V1rpSW
Eg16Q8WjSFU4Ye3llGg5
7yuxuhURaAQDDONMusMX
4r4ILD2FkQxyFotFA49k
NXOZZ6Jx8odFZUYWMbvN
1cdR2f7qZyoaqJhY2LKf
8gpQpbEaCIoncgyXObAV
dx4DcR0sBIOrIMOf9bs1
```


ファイルに保存したい場合は次のようにしましょう。

```
$ cat /dev/urandom | LC_ALL=C tr -dc "[:alnum:]" | fold -w 20 | head -n 10 > kusodeka.log
```

### 各行の文字列がランダムであってほしい場合 Part2（2021/08/27追記）
trのところはbase64を使ってもできるみたいですね。

```
$ cat /dev/urandom | base64 | fold -w 20 | head -n 10 
KfV9Hp9HBS2VAjTEcyNS
ZdgHQlTHtJo+SQVb3rBm
nhFUvy4T/WLCT27MRgMT
k+VC78GKFvmM/51WlxLR
D/X+OBas/B8lVjC+mI4e
r8pQbYinxcSZGo52eVCL
eJN7g7j0ebYOetZ8N21L
6rAkZbOCn65gIghtkxcp
yg0F+y7IGJkc8YvWgTUm
sWRs2RzXRNG4RHVi5Otk
```


### 参考
* https://l-w-i.net/t/ubuntu/passwd_001.txt
* https://unix.stackexchange.com/questions/45404/why-cant-tr-read-from-dev-urandom-on-osx
【エラー備忘録】config関数を使って値を取得する / $ php artisan config cache

##状況
Laravelのコントローラー内で、config関数を使い以下のコードを書いた。

```HelloController.php
public function index()
    {
        $sample_msg = config('sample.message');
        $sample_data = config('sample.data');
        $data = [
            'msg' => $sample_msg,
            'data'=> $sample_data
        ];
        return view('hello.index', $data);
    }
```

このデータをビューで呼び出す。

```index.blade.php
<p>{!!$msg!!}</p>
<ul>
@foreach($data as $item)
<li>{!!$item!!}</li>
@endforeach
</ul>
```

ここでブラウザにエラーが出た。

##エラー文

```
Invalid argument supplied for foreach() 
(View: /Users/hinako/laravel_app/resources/views/hello/index.blade.php)
```

意味は、foreach文に渡された引数が間違っているもしくはNULLになっているという意味らしい。

##原因

使用している変数をddやLog::debugでデバッグしてみた。
Log::debugでは値が変数に入っていると確認できたが、ddでブラウザに表示するとNULLになっていた。

##解決策

変数に入っている値は問題なかったので、以下のコマンドを実行してみる。

```
$ php artisan config:cache
```

これでエラーは解消された。

しかし調べていると、このコマンドは安易に使用すると危ないらしい…。

理由は、`config:cacheしてしまうと、env()はnullを返すようになる` から。
つまり、設定ファイル(configディレクトリ以下のファイル)以外でenv()を直接使っている箇所がある場合、 .envが読み込まれないようになっているので、nullが返ってくるようになる。

この場合は、
・configに.envの加えたい値を追加する
・env()ではなく、config()を利用して値を取得する
のように対処する必要がある。


####
参考サイト
https://readouble.com/laravel/6.x/ja/configuration.html#configuration-caching
Node.js で標準入力から同期的に一行読み取る

# 前座：既存の手法（非同期 or 入力全行）

主に競技プログラミングなどのシーンで標準入力からデータが受け渡されることは多いです。競技でなくとも、同様の形式でコーディングテストが行われることもあります。

こういったときに Node.js だと少し煩雑な手順を取る必要があります。

## `readline`

https://nodejs.org/api/readline.html#readline_readline_createinterface_options

```js
const rl = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];

rl.on("line", (line) => {
  lines.push(line);
  // ... 多分入力処理
});

rl.on("close", () => {
  // 入力が閉じたのでデータは受け取った
  // データを全て受け取った前提の処理がここ
});
```

何も知らない人から見ると呪文です。
上から順に実行されるのはそうなのですが、`rl.on` では「イベントに対するコールバックを設定」という処理が行われるだけなので `rl.on("line", ...);` の直後に処理を書いたとしてもデータが入っているとは限らないのが罠です。
インタラクティブな場面では気持ちがいいかもしれません。

## `fs.readFileSync`

https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options

```js
const fs = require("fs");
const wholeInput = fs.readFileSync("/dev/stdin", "utf8");
const inputLines = wholeInput.split("\n");

const n = Number(inputLines[0]);
// ...
```

こちらは比較的まともです。標準入力からの入力を全て文字列として受け取るものです。

強いて欠点を挙げるとすれば以下のようになるでしょう。

* インタラクティブな場面には向かない
* 行を取るには `split` してインデックスを指定する必要がある

# 作ってみた

正直上の二つがあれば特に困らないのですが、例えば ruby や python などで簡単に利用できる `gets` や `input()` などのような関数が Node.js にもあればなあ、と思い作ってみました。

https://github.com/cwd-k2/node-gets

## 使う

~~ローカルにインストールして利用する場合は `npm` で直接 github 上のリポジトリを指定してください。~~

（10/28 追記）npm に publish しました。
https://www.npmjs.com/package/node-gets

```
$ npm install --save node-gets
```

GitHub にあるリポジトリを指定してインストールすることもできます（`<owner>/<repository>` と書けば GitHub からインストールできるらしい）。

```
$ npm install --save cwd-k2/node-gets
```

（10/28 追記終わり）


以下のような書き心地になります。

```js
const gets = require("node-gets").createGets();

const n = Number(gets().trim());
const a = gets().trim().split(" ").map(Number);
// ...
```

- 行入力末尾の改行文字などは付いたまま
- EOF 的な感じで入力がなくなると `undefined` を返すようになる

## 問題点

* テストがない
* ベンチマークがない
* 実装上の問題
    * ~~一行読むたびに内部のバッファでコピーが発生している（リングバッファにすべきなど色々あると思います）~~
    * `\n` 以外の文字での分割に対応していない

## 最後に

他に問題点があったり、直してやったぞということがあれば issue や PR をお願いします。
PEP8のMaximum Line Lengthいくつにしてます？

# 規約

コーディング規約のPEP8に１行の最大文字数を定めた項目があります。

[原文](https://www.python.org/dev/peps/pep-0008/#maximum-line-length)
[日本語](https://pep8-ja.readthedocs.io/ja/latest/#id9)

> すべての行の長さを、最大79文字までに制限しましょう

と最初に書かれています。

自分もそれに従い、Lintでもデフォになってた79文字でチェックかかるようにしていました。
ただこれを守ろうとして逆に可読性を下げているなぁと感じることが稀にあったので、規約をもういちど読み直しました。

## 調整の幅

> 1行を79文字より長くするのを好むチームもあります。この問題について合意できるチームが独占的に、もしくは重点的にメンテナンスするコードについては、1行> 99文字まで制限を緩めてもOKです。ただし、コメントや docstring については72文字で折り返すようにすることが条件です。

という記載もあります。

## 根拠

もともとの79文字の根拠については以下のような記載があります。

>エディタのウィンドウの幅を制限すると、複数のファイルを並べて開くことができ、二つのバージョンを隣り合ったカラムに表示するコードレビューツールを使うときにもうまくいきます。
ほとんどのツールのデフォルトの折り返し動作は、コードの見た目の構造を壊し、理解するのを難しくします。79文字という制限は、ウィンドウの幅を80に制限し、行を折り返すときにツールが行末にマーカーを置いたとしても、エディタに折り返す動作をさせない目的で選ばれています。

なるほど。

またPEP8全体の [一貫性にこだわりすぎるのは、狭い心の現れである](https://pep8-ja.readthedocs.io/ja/latest/#id4) の項目には

> しかし、一貫性を崩すべき場合があることも知っておいてください - つまり、このスタイルガイドが適用されない場合があります。疑問に思ったときは、あなたの判断を優先してください。

とも書いてます。ちょっと見直してみることにしました。

# 参考情報
## IDEのデフォは？

ちなみにPyCharmとVSCodeで確認しましたが、IDE内のエディタはデフォで1行120文字になってました。けっこう長い。

## 他の言語は？

[Characters per line - Wikipedia](https://en.wikipedia.org/wiki/Characters_per_line) に色々まとめて載ってました。
80文字の言語が多め。

タイプライターやパンチカードにも由来してそうなところがおもしろい。

> In the era of typewriters, most designs of the typewriter carriage were limited to 80–90 CPL. 

〜
> In computer technology, a line of an IBM punched card consisted of 80 characters. 

# で、どうしたか

ということで、自チームの標準的なエディタ環境だと90文字ぐらいであれば ツリータブ×1 + エディタタブ×2 の表示でも全然収まるので、ひとまずMaximum Line Length=90に変更しました。２ヶ月ほど経過しましたが変更してよかったと感じています。

様子見て99文字にしてもいいかな〜と考えています。
【LWC】tree-grid

#tree-gridとは

レコードを一括で表示するにはdata-tableを使用することが多いですが、lwcにはtree-gridというものも存在します。
どちらもレコードを表示できますが、tree-gridは行を折りたたんだり展開したりできます。子レコードを表示するときなどに便利かもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407598/2a25f4e8-732c-e014-13e5-885f220cfccc.png)
このように取引先と取引先責任者をグループ化して表示することができます。
以下、今回の実装内容を載せるので参考にしてください。

#レコードの取得

data-tableでは基本的に単一オブジェクトを取得しますが、tree-gridでは親-子リレーションで取得するのでデータの整形が必要になります。

```JavaScript:SampleTreeGrid.js
import { LightningElement, api, wire } from 'lwc';
import getAccountWithContact from '@salesforce/apex/AccountTableViewController.getAccountWithContact';

export default class SampleTreeGrid extends LightningElement {
  columns = [
    { label: 'Account Name', fieldName: 'Name', type: 'text'},
    { label: 'Id', fieldName: 'Id', type: 'text'},
  ]
  
  accounts;

  connectedCallback() {
    getAccountWithContact()
    .then(data => {
      console.log('data');
      // オブジェクトをJSON文字列に変換
      let accountData = JSON.parse(JSON.stringify(data));
      for(let i = 0; i < accountData.length; i ++) {
        let cons = accountData[i]['Contacts'];
        if(cons) {
          accountData[i]._children = cons;
          delete accountData[i].Contacts;
        }
      }
      this.accounts = accountData;
      
    })
    .catch(error => 
      console.log(error))
  }
}

```
columnなどはdata-tableと同じ書き方ですね。データの取得の部分だけ若干複雑ですが一度形を理解してしまえば難しくはないです。
HTMLも載せておきます。

```HTML:SampleTreeGrid.html
<template>
  <lightning-card title="取引先と取引先責任者" icon-name="custom:custom1">
    <div class="slds-p-around_medium">
      <lightning-tree-grid
        columns={columns}
        data={accounts}
        key-field="Id">
      </lightning-tree-grid>
    </div>
  </lightning-card>
</template>
```

#datatableとの違い

おおまかな違いはありませんが、tree-gridではインライン編集が出来ません。その代わりに行拡張は出来るそうです。
もう少し調べる機会があったらまた書きます。

詳しく知りたい方はリファレンスをご覧ください。
[tree-grid](https://developer.salesforce.com/docs/component-library/bundle/lightning-tree-grid/example/)
AWSの便利なプラットフォーム「Amplify」について

# はじめに
これからAWSのサービスの一つ、**Amplify（アンプリファイ）**を利用してアプリケーションを開発するため、備忘録としてここに記述します。
私は初学者ですので、誤っている箇所がありましたらご指摘いただけますと幸いです。

# Amplifyとは
クラウドサービス上におけるモバイルアプリケーションやWebアプリケーションを安全に構築するためのプラットホームになります。
**Lambda**、**DynamoDB**、**Cognito**、**AppSync**、**CloudFront**、**S3** など、AWSのサービスを使いやすくパッケージ化したものです。Amplifyに対応している言語**（ JavaScript、iOS、Android ）**、ライブラリ**（ React、Vue.js、Angular ）** でフロントエンドさえ作ってしまえば、サーバーサイド、インフラはAWSのサービスで簡単につくれてしまうという優れものです。

# 導入されているツール（一部抜粋）

### ① API（例：AppSync、REST、GraphQL）
ソフトウェアの一部を外部に向けて公開することで、第三者が開発したソフトウェアとも機能が共有できるようになります。最初からプログラムを組む必要がなくなり、ソフトウェア開発の効率化が計れます。

### ② Auth（例：Cognito）
認証を行うことです。認証の対象が人である場合は、その人で本当に正しいかどうかを確認します。IDとパスワードさえ確認できれば本人と確認ができるという仕組みです。これにより安全性が高まり、セキュリティが向上します。

### ③ Pub/Sub（例：Lambda）
非同期メッセージングサービスです。イベントを処理するサービスとイベントを生成するサービスを切り離すことができます。これにより、一貫性のあるパフォーマンスを実現させることができます。

### ④ Storage（例：S3）
データを保存して置く場所です。AWS Amplifyにはこのような補助記憶装置があり、データを長時間保存することができます。またAWS AmplifyのStorageにはアクセスレベルが3つ存在し、使い分ける必要もあります。

# メリット

### ① 短時間でサービスをリリースできる
開発者目線だとアプリケーション開発に必要な一般的な技術要素をゼロから構築するのは大変です。それこそ本来作りたいアプリケーションの開発に注力したいといったような課題があります。例えば、`amplify add api`といったコマンドをやりたいことベースで入力し、簡単な操作を行い自動でバックエンドが構築されます。

### ② 柔軟性の良さ
Amplifyの構成要素である **Amplify Console** は、SPAやホスティング、Cl/CDの運用を自動化するマネージドサービスです。拠点ごとにテスト環境を自動で構築したり、認証を付与するといった、柔軟な開発フローの設計ができます。静的なサイトであれば Amplifyを用いなくても数クリックで使用できてしまう優れものです。

### ③ ソフトウェアの拡張性を気にしなくて良い
AmplifyはAmplifyフレームワークでアプリケーションを拡張するため、スケーラブルなサーバーレスバックエンドを基盤に構築します。

### ④ サービスの成長による環境変化に強い
Amplifyには **Multi Environment** という機能が存在し、本番環境と全く同じバックエンドを構築することができます。また、Webアプリケーションであれば、**Amplify Console** を用いて、CI/CD環境を簡単に構築することもできるようになります。

### ⑤ ユーザーの反応や動きを可視化できる
AmplifyとPinpointを統合することでユーザーのエンゲージメントを簡単に可視化することができます。また、個別の属性を付与しサービスに応じたエンゲージメントの可視化も行うことができます。

### ⑥ スケールのしやすさ
AWS Amplifyが使用するバックエンドはスケールすることを前提としたコンポーネントで構築されるので、バックエンドを再構築する必要がありません。初期段階からスケーラビリティの心配をしなくてもよいという大きなメリットがあります。

# おわりに
AWSのプラットフォームであるAmplifyについて初学者なりにまとめました。これから開発に進みたいと思うのですが、公式では簡単とはいえど詰まった場合、参照できる情報がAWSは少ない印象です。最新の記事や情報を見ながら地道に積み上げていきたいと思います。

# 参考
https://aws.amazon.com/jp/amplify/

https://www.skyarch.net/column/aws-amplify/

https://www.fenet.jp/aws/column/technique/139/#AWS_Amplify%E3%81%A8%E3%81%AF%EF%BC%9F

https://atmarkit.itmedia.co.jp/ait/articles/2108/12/news012.html

https://fixel.co.jp/blog/amplify-severless-webapp/
サブプロセスで使用する変数が与える親プロセスへの影響

結論から言うと当然ながら影響しないのでした。
勿論、そのはずと思っていたのですが、念の為に変数あるいはワーキングディレクトリに関して、そのスコープについて確認しました。

```
ykishi@dezembro httpd_log % beautysh -i 2 testme.sh 
ykishi@dezembro httpd_log % cat testme.sh 
```

```bash
#!/bin/sh

BASE_DIR=/tmp
cd ${BASE_DIR}

n=0
i=0


echo `pwd`

(
  echo "Sub process A has started..."
  sleep 7
  echo "A done"
  for i in `seq 1 10`; do
    let n=${n}+1
  done
  echo "n=${n}"
cd /tmp/bar; echo `pwd`) &

(
  echo "Sub process B has started..."
  for i in `seq 1 20`; do
    let n=${n}+1
  done
  echo "n=${n}"
  sleep 5; echo "B done"
cd ${BASE_DIR}; echo `pwd`) &

(
  echo "Sub process C has started..."
  for i in `seq 1 30`; do
    let n=${n}+1
  done
  echo "n=${n}"
  sleep 3;
  echo "C done"
cd /tmp/foo; echo `pwd`) &

wait

echo "Completed!"
cat << EOF

n=${n}
i=${i}
`pwd`
EOF
```
```
ykishi@dezembro httpd_log % ./testme.sh 
/tmp
Sub process A has started...
Sub process B has started...
Sub process C has started...
n=20
n=30
C done
/tmp/foo
B done
/tmp
A done
n=10
/tmp/bar
Completed!

n=0
i=0
/tmp
ykishi@dezembro httpd_log % 
```
【TypeScript入門】呼び出しシグネチャとは

# まとめ
呼び出しシグネチャを使うことでアノテーションをたくさん書く必要がなくなります。また、再利用ができるのでコードの質も高まります。

## 呼び出しシグネチャとは
* どのような関数なのかを表現する型定義
* 省略記法はアロー関数と似た形
* 安全な記法はオブジェクトと似た形

```typescript:省略版
type LogMessage = (message: string) => void
export const logMessage: LogMessage = (message) => {
  console.log('sample:', message)
}
```

```typescript:完全版
type FullLogMessage = {
  (message: string): void
}
export const logMessage: FullLogMessage = (message) => {
  console.log('sample:', message)
}
```
【JavaScript】変数について

#はじめに

はじめまして。
エンジニア転職に向けて学習中の佐藤です。
このQiitaでは、学習中のアウトプットや、同じところでつまずいてしまう駆け出しエンジニアに向けて発信していきます！

誤った情報がありましたら、ご指摘いただけると幸いです！


##変数について(let,const,var)
letは値を再代入できる。

```js:JavaScript
let width = 1280;
whidth = 640;
console.log(width); //640が出力される
```
<br>
一方、constは値を再代入できない。定数と呼ばれる。
値を変えないものに上書き禁止のものに関しては、constを使用する。

```js:JavaScript
const height = 680;
height = 340;
console.log(height); //エラーになる
```
<br>
varはletと同じように値の再代入ができるが、ES6のアップデート以降は使用されていない。

```js:JavaScript
var width = 1280;
whidth = 640;
console.log(width); //640が出力される
```
<br>
#最後に
今回はJavaScriptの変数について記事にしてみました。
最初は覚えることが多いですが、できることが増えると楽しくなってきますね！

同じように学習中の方に向けて、定期的にQiitaにて記事を投稿していこうと思います！
k8sでNodeのリソース状況とかRequest・Limitを一覧で見る方法

## kube-capasity

https://github.com/robscott/kube-capacity

## 出力イメージ

```shell
NODE                                          CPU REQUESTS   CPU LIMITS     MEMORY REQUESTS   MEMORY LIMITS
*                                             16960m (35%)   18600m (39%)   26366Mi (14%)     3100Mi (1%)
ip-10-0-138-176.eu-north-1.compute.internal   2460m (31%)    4200m (53%)    567Mi (1%)        784Mi (2%)
ip-10-0-155-49.eu-north-1.compute.internal    2160m (27%)    2200m (27%)    4303Mi (14%)      414Mi (1%)
ip-10-0-162-84.eu-north-1.compute.internal    3860m (48%)    3900m (49%)    8399Mi (27%)      414Mi (1%)
ip-10-0-200-101.eu-north-1.compute.internal   2160m (27%)    2200m (27%)    4303Mi (14%)      414Mi (1%)
ip-10-0-231-146.eu-north-1.compute.internal   2160m (27%)    2200m (27%)    4303Mi (14%)      414Mi (1%)
ip-10-0-251-167.eu-north-1.compute.internal   4160m (52%)    3900m (49%)    4491Mi (14%)      660Mi (2%)
```

便利！
AtCoderログ：0093 - ABC 086 B

# 問題

https://atcoder.jp/contests/abc086/tasks/abc086_b

## 問題文
> シカのAtCoDeerくんは二つの正整数 $a,b$ を見つけました。$a$ と $b$ をこの順につなげて読んだものが平方数かどうか判定してください。

## 制約
> ・$1 \le a,b \le 100$
> ・$a,b$ は整数

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #008

# 回答
## 回答1 (AC)
「$a$ と $b$ をこの順につなげて読んだもの」を作るには $a$ と $b$ を文字列として読み込んで a+b を処理すれば良いでしょう。コードは以下のようになりました。

```C++:abc086b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  string a, b;
  cin >> a >> b;

  int n = stoi(a+b);
  if ( pow(int(sqrt(n)),2)==n ) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }    
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc086/tasks/abc086_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc089/editorial.pdf)
平方数かを判定するのに、全数検索 (1x1 から 1000x1000 まで比べていく) が紹介されていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0092 - ABC 215 C](https://qiita.com/RoadLynton/items/3ea5cbaa16efbf5b0344)
- 前の記事 → [AtCoderログ：0094 - ABC 074 B](https://qiita.com/RoadLynton/items/c4eb75ae4f0ac8f4a125)
SalesforceのPageBlockTableとenhacedList

###・要件
SalesforceのVisualpageでデータテーブルの表示のTagは何種類がある。違いは何



###・可能コンポーネント
TagのPageBlockTableのコラム長さ調整はできない
ListViewもソートができます。
enhancedListは長さ調整できます。
Datatable+Javascriptで上記より、自由にカスタマイズできる

###・コード
####PageBlockTable

```
<apex:page standardController="Account" recordSetVar="Accounts" >
<apex:pageBlock >
<apex:pageBlockSection title="Items" columns="1">
<apex:pageBlockTable value="{!Accounts}" var="d" columnsWidth="250px, 180px, 120px, 100px">
<apex:column value="{!d.Id}"/>
<apex:column value="{!d.Name}"/>
<apex:column value="{!d.Phone}"/>
<apex:column value="{!d.Industry}"/>
</apex:pageBlockTable> 
</apex:pageBlockSection>
</apex:pageBlock>

</apex:page>

```
####ListView
```
<apex:page showHeader="true" tabstyle="Account">
    <apex:ListViews type="Account" id="AccountList" />
</apex:page>
```
####enhancedList
```
<apex:page >
    <apex:enhancedList type="Account" height="300" rowsPerPage="10" id="AccountList" />
</apex:page>
```
####Datatable
##### VF
```
<apex:page controller="DatatableCntrl" sidebar="false">  
 <head>  
   <apex:includescript value="https://code.jquery.com/jquery-3.3.1.js"/>  
   <apex:includescript value="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"/>  
   <apex:includescript value="https://cdn.datatables.net/1.10.19/js/dataTables.material.min.js"/>  
   <apex:stylesheet value="https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.1.0/material.min.css"/>  
   <apex:stylesheet value="https://cdn.datatables.net/1.10.19/css/dataTables.material.min.css"/>  
   <script type="text/javascript"> 
   j$ = jQuery.noConflict();  
   j$(document).ready( function () {  
     var accTable = j$('[id$="accTable"]').DataTable({  //datatable 
        columnDefs: [  
     {  
       targets: [ 0, 1, 2 ],  
       className: 'mdl-data-table__cell--non-numeric'  
     }  
   ]  
     });  
   });
   </script>
     
   <style>  
     div.dataTables_wrapper div.dataTables_filter {  
     text-align: right;  
     margin-right: 2%;  
      border-radius: 2px; 
      height: 51px;   
   } 
   
   thead th{
    resize: horizontal;
    overflow: hidden;
    background-color: lightgray;
    border: 1px solid black;
　 } 

   tbody td{
    resize: horizontal;
    overflow: hidden;
    border: 1px solid lightgray;
　 } 

  


   </style>  
 </head>  
 <body>  
   <table id="accTable" class="mdl-data-table" style="width:100%">  
     <thead>  
       <tr>  
         <th>Name</th>  
         <th>Billing State</th>  
         <th>Website</th>  
       </tr>  
     </thead>  
     <tbody>  
       <apex:repeat value="{!accList}" var="acc">  
         <tr>  
           <td>{!acc.Name}</td>  
           <td>{!acc.BillingState}</td>  
           <td>{!acc.Website }</td>  
         </tr>  
       </apex:repeat>  
     </tbody>  
   </table>  
 </body>  
 </apex:page>
```

##### Apex
```
public class DatatableCntrl{  
   public List<Account> accList {get; set;}  
   public DatatableCntrl(){  
     accList = [SELECT Name, BillingState,Website FROM Account where BillingState!='' and Website !='' order by name ];  
   }  
 }  
```
camelotで大量のページのPDFをCSV変換

Colaboratoryでcamelotを利用してPDFからCSVに変換していると200ページ超えたあたりからメモリ不足で落ちます

対策として50ページぐらいに分割して変換してから結合

https://www.city.kawasaki.jp/350/page/0000116827.html

川崎市の陽性者一覧のPDFを利用

```
# ダウンロードURL
!wget https://www.city.kawasaki.jp/350/cmsfiles/contents/0000116/116827/4.pdf -O data.pdf
```

```
!apt update
!apt install python3-tk ghostscript
!pip install camelot-py[cv]
```

```python
import camelot
import pandas as pd

from tqdm.notebook import tqdm
from more_itertools import chunked

# ページリスト取得
handler = camelot.handlers.PDFHandler("data.pdf")
pages = handler._get_pages(pages="all")

# ページ範囲のリスト作成
pages_list = [str(i[0]) if i[0] == i[-1] else f"{i[0]}-{i[-1]}" for i in chunked(pages, 50)]
pages_list

dfs = []

for page in tqdm(pages_list):

    tables = camelot.read_pdf(
        "data.pdf",
        pages=page,
        split_text=True,
    )

    for table in tables:
        dfs.append(pd.DataFrame(table.data[1:], columns=table.data[0]))

df = pd.concat(dfs).reset_index(drop=True)

df.to_csv("data.csv")
```
Timerを使って4秒間隔でviewの背景色をランダムで変更

#今回の内容
* Timerを使用して、一定間隔で背景色を変更する。

#コードと簡単解説

* 4秒間隔で`changeBackGroundColor`の処理をさせます。

* `changeBackGroundColor`はviewの背景色を2秒かけて変更します。

* `.random(in:x...y)`は指定したxからyまでの値をランダムに取得できます。

```Swift:Timer
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
       
        Timer.scheduledTimer(timeInterval: 4.0, target: self, selector: #selector(changeBackGroundColor), userInfo: nil, repeats: true)    
    }

    @objc func changeBackGroundColor(){
        
        UIView.animate(withDuration: 2.0, delay: 0, options: .allowAnimatedContent, animations: {
            
                        self.view.backgroundColor = UIColor(red: CGFloat.random(in: 0...255) / 255,
                                                            green: CGFloat.random(in: 0...255) / 255,
                                                            blue: CGFloat.random(in: 0...255) / 255,
                                                            alpha: CGFloat.random(in: 0.0...1.0))
            
        }, completion: nil)
   
    }
}
```
# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
Composerのインストール方法【macOS編】

#はじめに
Composerとは、PHPを利用するためのパッケージ管理ツールです。
Laravelでアプリを作る前にインストールしておく必要があるので、今回はComposerのインストール方法について説明します。

#Composerのインストール方法
基本的には、公式ホームページに載っているマニュアルどおりなのですが

1) 以下の公式ホームページにアクセスします。
　公式ホームページ→　[Composer](https://getcomposer.org/)
2) 「Download」をクリックします。
3) 3行目くらいにある以下のコマンドをターミナルで実行することで、composer.pharというファイルが作成されます。

```PHP:PHP
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

4) composer.pharをどこからでも使えるようにするため、以下のコマンドをターミナルで実行して、/usr/local/bin/composer以下に移動させます。

```PHP:PHP
mv composer.phar /usr/local/bin/composer
```
5) これでComposerのインストールは完了したはずなので、以下のコマンドをターミナルで実行して、インストールできているか確認してみましょう。

```PHP:PHP
$composer -V
```

もしくは

```PHP:PHP
$composer --version
```

6) バージョンが表示されていれば、Composerのインストールは完了です。
pandasでcsvのデータ加工

# データ読み込み

```python
import pandas as pd
path = 'csvのパス'
df_csv = pd.read_csv(path)
df_csv = pd.read_csv(path, header=None) #カラム名無し(0からの連番がカラム名)
df_csv = pd.read_csv(path, names=('A', 'B', 'C', 'D')) #カラム名指定
```

# 不要な列、行の削除

```python
df_csv = df_csv[['必要なカラムを,区切りで記載']][必要な行指定]
```

# 任意の要素取得

```python
df_csv.iloc[4:10, 2:6] #5から10行目、2から5列目を指定
df_csv.loc[5:10, '初めの指定からカラム名':'最後の指定カラム名'] #5から10行目を指定
```

# 条件抽出

```python
df_csv[df_csv['抽出カラム名'] == '抽出条件']
df_csv[df_csv['抽出カラム名'] > 数字]
df_csv[df_csv['抽出カラム名'].isin'抽出条件']
```

# ユニークな値の抽出

```python
df_csv['カラム名'].unique()
```

# 重複除去

```python
df_csv.drop_duplicates(subset='[カラム名]')
```

# カラム名変更

```python
df_csv.columns = ['変更後のカラム名']
df_csv = df_csv.rename(columns={'変更前のカラム名': '変更後のカラム名'})
```

# 並び替え

```python
df_csv.sort_values('カラム名') #昇順
df_csv.sort_values('カラム名', ascending=False) #降順
```

# ダミー変数の処理

```python
pd.get_dummies(df_csv, columns=['カラム名'])
```

# 欠損値の確認、補完

```python
df_csv.isnull().sum() #確認 
df_csv.fillna(0) #0で補完
```

# 欠損値の削除

```python
df_csv.dropna(axis=1) axis=0なら行削除
```

# ユニークな値と出現回数

```python
df_csv['カラム名'].value_count(s)
```

# グループごとの集計

```python
df_csv.groupby('カラム名').mean() # 平均値
df_csv.groupby('カラム名').std() # 標準偏差
df_csv.groupby('カラム名').median() # 中央値
df_csv.groupby('カラム名').max() # 最大値
df_csv.groupby('カラム名').min() # 最小値
```

# csvの出力

```python
df = df_csv.fillna(0).to_csv('ファイル名', index=False, header=False) # カラム名、index無し
df = df_csv.fillna(0).to_csv('ファイル名', columns=["カラム名1","カラム名2"]) #特定のカラムのみ

df.to_csv(sys.stdout) # 標準出力
```