OmniAICreator/Qiita-1.07M huggingface dataset:
RPAの利用状況は？RPAの活用事例を部門ごとにまとめて紹介！

みなさん、こんにちは
Peaceful morning株式会社でインターンをしている高橋です！

RPAに関する投稿はこれが2回目となります。
1回目の投稿は予想以上に反響があり、非常にうれしいです。
今後もみなさんにRPAに関する有益な情報をお届けできるように努めて参ります。

**1回目では、基本的なRPAの特徴、AIとの違い**について解説しました。
「RPAとは？」という部分は理解していただけたのではないでしょうか。
今回は実際その**RPAが実務にどう活かされているのか**会社における部門ごとに紹介していきたいと思います！

まだ1回目の投稿を読んでいない方、RPAって何？という方はこちらをご覧ください↓
https://qiita.com/RPAHACK/items/36e6fcc4ff73372db17a


**RPAのことがよくわからない！という方はこちらのRPA HACKの記事もおすすめです！↓**
**・RPAを家事に例えるなら？**
https://rpahack.com/rpa

**・RPAがなぜ注目されるのか？４つのポイントをおさらい！**
https://rpahack.com/rpa-attention


##RPAの導入状況 

DX、業務効率化と言われる世の中でRPAの導入をしている企業が増えているのは事実です。では、現時点でのRPAがどのくらい導入されているのか数字で確認してみましょう。

企業の状況を確認すると、全体では**2019年11月時点でのRPA導入率は38％、これは2018年の6月の導入状況が22％**だったのに比べると上昇傾向にあることがわかります。さらに**大手企業にだけに絞ると、導入率は51％**となっております。一方中小企業は25%とまだまだこれからというような状況が伺えます。
(参考：https://www.m2ri.jp/release/detail.html?id=391)

では自治体はどうでしょうか？
令和元年、**都道府県のうち85％、指定都市のうち70%**がRPAを導入しています。
しかし、一方**その他の市区町村ではまだ導入済みが18％**と導入が進んでいるとは言えません。
(参考：https://www5.cao.go.jp/keizai-shimon/kaigi/special/reform/wg6/20200324/pdf/shiryou3-2.pd)

このことからもわかるように、**組織が大きい、資金力がある**、ところでは現在RPAの導入がしっかりと進んでいるのが伺えます。
しかし、**中小企業、地方の市町村**ではまだまだRPAの導入が進んでおらず、**大きな組織との格差**という問題も浮き彫りになってきています。


##RPAの導入事例
ここからはさっそく、企業、組織における部門ごとのRPAの利用方法についてみていきたいと思います！
今回は**経理、人事、営業**、の3部門についてみていきます！

##経理
###経理部門の問題
経理部門では、入力されたデータと実際の証憑（しょうひょう）に記載されている金額が、**入力・確認ミスにより金額が一致していないという問題**が起こります。また結果が一致してない場合に、その確認作業に膨大な時間がかかります。その他にも、経理部門には請求書や領主書の内容をエクセルに入力したり、煩雑な作業が多くあるということが現状です。

###事例1 データ突合
RPAを使用することで買掛金や売掛金の消込などの突合などの作業が自動的に照合されるため**不一致なものは自動的に取り除かれます。**

###事例2 伝票データの取り込み作業
請求書、領収書等のデータを入力するという煩雑な作業を、それらの伝票データを撮影するだけで**「会計システム」や「エクセル」へ自動入力**されます。

##人事
###人事部門の問題

人事部門においては、入社・退職が発生した都度、業務システムや社内システムに該当する社員の情報を更新する必要があります。**各種手続きなどに伴う様々な情報のデータ入力や勤怠状況のデータ管理など定型的な事務作業が非常に多い**ことが問題点として挙げられます。勤怠データが福利厚生や給与管理システムと連携し、反映されているケースはまだ少ないです。

###事例1社員の働き方の可視化と給与への反映
勤務データをそれぞれのアプリケーションに入力する業務などをRPAで自動化になります。

###事例2 入社・退職の手続き
Excelで社員情報を管理している場合、Excelの情報を取得し、システムの情報と照合を行い更新をする作業をRPAが一任して行ってくれます。

##営業
###営業部門の問題
営業部門では、商談など顧客とのコミュニケーションに多くの時間を費やさなくてはならない一方、**顧客データの管理、情報収集、資料作成など社内での定型的な事務作業が多くなってしまう**ことが問題点として挙げられます。

###事例1 顧客データの管理
顧客から預かった受注伝票をOCRを活用し取り込むことでRPAでデータを自動更新し、管理することが可能です。

###事例2 資料作成
営業担当者のスケジュールを確認し、顧客情報を収集し提示資料をRPAが自動生成します。



この記事を読んで、さらに気になった方は、こちらRPA HACKの記事をご覧ください！
この記事では、**この3部門におけるその他の自動化、マーケティング部門の使用事例**も掲載しています！
(記事リンク:https://rpahack.com/rpa-casestudy)


##RPA HACKについて
RPA HACKではRPA・AI・Power Automateに関する記事が100本以上掲載されています！
すべて無料でご覧いただけます！

RPAのツールを触ってみたい！という方におすすめ↓
**・UiPath StudioXの基本をマスター！～画面構成/カード/アクション**
https://rpahack.com/uipath_studiox_1

RPAエンジニアとして働いてみたいという方におすすめ↓
**・事務職から転職したRPAエンジニアが語る仕事の2つの魅力**
https://rpahack.com/attraction-of-rpa


RPA HACKのtwitterのフォローもよろしくお願いします！
(URL：https://twitter.com/home）
centosでMSファイルをpdfに変換

以前に実装した手順の備忘録。
結果的には最新版にしても昔の問題点はあまり改善されてないぽい。

問題１：プログラムがマルチスレッド非対応
問題２：エクセルの改ページとかが反映されない？

## LibreOfficeをインストール

yum はないっぽいので公式サイトからrpmをダウンロードしてインストール

2020/07/14時点のLibreoffceの安定化バージョン
LibreOffice_6.3.6_Linux_x86-64_rpm.tar.gz
日本語化パッケージ
LibreOffice_6.3.6_Linux_x86-64_rpm_langpack_ja.tar.gz
コマンドライン変換の場合はいらないかも

```bash
$ tar zxvf LibreOffice_6.3.6_Linux_x86-64_rpm.tar.gz
$ cd LibreOffice_6.3.6_Linux_x86-64_rpm/RPMS/
$ sudo yum install ./*.rpm
$ cd ../../
$ tar zxvf LibreOffice_6.3.6_Linux_x86-64_rpm_langpack_ja.tar.gz
$ cd LibreOffice_6.3.6_Linux_x86-64_rpm_langpack_ja/RPMS/
$ sudo yum install ./*.rpm
```

## 変換コマンド

```bash
$ /usr/bin/libreoffice6.3 \
--headless \
--nologo \
--nofirststartwizard \
--convert-to pdf:writer_pdf_Export \
--outdir /home/user/tmp/ \
test.xls
```
依存関連でエラーが出た

```bash
javaldx: Could not find a Java Runtime Environment!
Warning: failed to read path from javaldx
/opt/libreoffice6.3/program/soffice.bin: error while loading shared libraries: libcups.so.2: cannot open shared object file: No such file or directory
```

lib_cupsがないので関連パッケージを探して入れる

```bash
yum whatprovides libcups.so.2
...
1:cups-libs-1.6.3-43.el7.i686 : CUPS printing system - libraries
Repo        : base
Matched from:
Provides    : libcups.so.2
$ sudo yum install cups-libs
```
同様に`cairo`と`libSM`も入れた。
Windows Formで沢山あるラジオボタンの任意の一つを選択状態にするド素人的解決

最近C#の勉強をしなければならなくなって,以前にhtaで書いたソフトウェアをC#+Windows Formで作り直すってやってんだけど,「コードで複数のラジオボタンの一つをチェック状態にする」ってのがもう全然判らなくて2日ほど嵌ってしまった。
いやまあラジオボタンにチェック付けるだけなら

```C#
ラジオボタン名.Checked = true
```

でええんやけど,そうではなく.
例えば10個あるラジオボタンのn番目にチェックを付けたいって時のやり方がGoogleっても全然出てこないのよ.
最初は

```C#
グループ名.Controls[n].Checked = true
```

でいけるやろ？ と思ったんだけど,Controls[n]のプロパティに「Checked」が無いでやんの（´・ω・｀）.
まあControlsに含まれるのはラジオボタンとは限らんもんな……
じゃあOfTypeでラジオボタンだけフィルタすればよくない？と思いついて

```C#
グループ名.Controls.OfType<RadioButton>()[n].Checked = true
```

ってやってみるも「角かっこ[]付きのインデックスを'IEnumerable<RadioButton>'型の式に適用することはできません」ってエラー.なんでや！
そして,2日間いろいろ試行錯誤してようやくたどり着いたのがこれ↓

```C#
グループ名.Controls.OfType<RadioButton>().ToArray()[n].Checked = true
```

OfTypeでラジオボタンだけフィルタしてToArrayで配列に変換した後に[n]で当該ラジオボタンを選択.これだとCheckedが使えるぞ!!!
もうちょっと簡単な方法ありそうだけどまあ動くのでこれで.

※ちないろいろGoogleってた時にラジオボタン名を連番にして名前で指定,みたいのんは見かけたんだけど,実際には上記グループはタブになってて「１番目のタブの２番目のラジオボタン」みたいな指定しなきゃならんのでラジオボタン名を生成するのが面倒くさくてスルーやで.
PG::ConnectionBad: FATAL:  the database system is starting up

MacでRailsアプリ開発中に、rails db:migrateをしたらPG::ConnectionBad: FATAL:  the database system is starting upが出た

### 現象

`ターミナル`

```
$ bundle exec rails db:migrate
rails aborted!
PG::ConnectionBad: FATAL:  the database system is starting up
/Users/jun/dic/Task-twitterclone/Rblog/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg.rb:58:in `initialize'
...

```

### 解決策

```
$ rm /usr/local/var/postgres/postmaster.pid         // postmaster.pidを削除
$ brew services restart postgresql         // postgresql再起動
```

### 接続確認

```
$ psql -l
                                    List of databases
              Name               | Owner | Encoding | Collate | Ctype | Access privileges 
---------------------------------+-------+----------+---------+-------+-------------------
 FACEBOOK_EXAM_development       | jun   | UTF8     | C       | C     | 
 FACEBOOK_EXAM_test              | jun   | UTF8     | C       | C     | 
 GraphQL-app_development         | jun   | UTF8     | C       | C     | 

```

OK！

参考
https://qiita.com/hirocueki2/items/327dc6e87005edf622ad
https://blog.n-z.jp/blog/2020-01-08-homebrew-postgresql.html
https://qiita.com/opiyo_taku/items/2fc4bef8a6bfd468de6a
[Laravel]Jobの遅延ディスパッチはSQSの遅延キューの遅延設定を上書きする

# はじめに

`Amazon SQS`には`遅延キュー`というキュー全体に対して遅延時間を設定する機能がありますが、
LaravelにもJobを遅延させて実行する仕組みとして、`遅延ディスパッチ`という機能があります。
両方遅延時間を設定した場合に、
「どちらの遅延時間が優先されるのか」  あるいは「両方合わせた時間遅延するのか」を調べました。

## Amazon SQS 遅延キュー
> 遅延キューを使用すると、キューへの新しいメッセージの配信を数秒間遅延させることができます。たとえば、コンシューマーアプリケーションがメッセージの処理に追加の時間を必要とする場合に遅延キューを使用できます。遅延キューを作成した場合、キューに送信したメッセージはいずれも、遅延期間の間コンシューマーに表示されなくなります。キューのデフォルトの (最小) 遅延は 0 秒です。最大は 15 分です。

> キュー全体に対してではなく、各メッセージに遅延の秒数を設定するには、メッセージタイマーを使用して、遅延キューの DelaySeconds 値ではなく、メッセージタイマーの DelaySeconds 値を Amazon SQS で使用できるようにします。

配信キューはキュー全体に対して遅延設定を設定する仕組みのようです。

https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html


## Amazon SQS メッセージタイマー
> メッセージタイマーを使用すると、キューに追加するメッセージの初期非表示期間を指定できます。たとえば、タイマーを 45 秒に設定してメッセージを送信すると、そのメッセージはキューに入ってから 45 秒間はコンシューマーに表示されません。
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-timers.html

配信キューと違い、メッセージタイマーはキューごとに遅延時間を設定できる仕組みのようです。

## Laravel 遅延ディスパッチ

> キュー投入されたジョブの実行を遅らせたい場合は、ジョブのディスパッチ時にdelayメソッドを使います。

https://readouble.com/laravel/6.x/ja/queues.html

Laravelから個別にキューの遅延時間を指定するにはこの機能を使います。


## 調査結果
- 遅延ディスパッチを行うための`delay`メソッドは`Queueable`traitのメソッド
- `delay`メソッドを呼ぶと引数の遅延時間をメンバー変数`delay`に保持する
- `SQSQueue`クラスの`letar()`メソッドで遅延ディスパッチを行っている
- `letar`メソッドでは`SQSClient`を使って、SQS APIの`sendMesssage`を呼んでいる
- sendMessageのオプションとして`delaySeconds`に`delay`で指定した秒数が設定される
- delaySecondsはメッセージタイマー機能の設定 
    - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
- メッセージタイマーは遅延キューの設定を上書きする 
    - > 個々のメッセージのメッセージタイマー設定は、Amazon SQS 遅延キューの DelaySeconds 値よりも優先されます。
    - https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-timers.html


# まとめ

- Larvelから遅延ディスパッチしたときは、遅延時間がメッセージタイマーとして設定される
- メッセージタイマーは、キュー全体の遅延設定である遅延キューの遅延時間より優先される


以上、参考になりましたら幸いです。
【vue】 親コンポーネントのstyleタグから、子コンポーネントのidやclassの情報を変更できるようにするための方法メモ

# はじめに

vueで、親コンポーネントのstyleタグから、子コンポーネントのidやclassの情報を変更できるようにするための方法。
自分用メモ。

# 内容

下記の方法

```
::v-deepを子コンポーネント内部の変更させたいidやclassの前に記述する
```

を行うことで子コンポーネント内部の要素も変更されるようになる。

具体的な記述は以下。

```vue:親コンポーネント
<template>
    <div class="parent">
        <p class="text">親コンポーネントpタグ</p>
        <Child />
    </div>
</template>

<script>
import Childfrom '../components/Child.vue'
export default {
    name: 'Parent',
    components: {
       Child
    }
}
</script>

<style lang="scss" scoped>
::v-deep .text {
  color: red;
}
</style>
```


```vue:子コンポーネント
<template>
 <div class="children">
  <p class="text">子コンポーネントpタグ</p>
 </div>
</template>

<script>
 export default {
  name: 'Child'
 }
</script>
```

以下の記事を参考させていただきました。ありがとうございます。

https://designsupply-web.com/knowledgeside/4833/
Wikipediaダンプからリダイレクトを抽出する

個人的な備忘録として残します。
手早くファイルを得られるよう、なるべく簡潔に書きたいと思います。

# 完成予想図

Wikipediaのリダイレクトを収集して以下のようなファイルを作ります。

~~~bash:redirects.json
{"src": "COVID-19", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "COVID-2019", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "Covid-19", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "Covid-2019", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "新型コロナウイルス感染症", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "コビッド19", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "COVID19", "dst": "新型コロナウイルス感染症_(2019年)"}
{"src": "2019新型コロナウイルス感染症", "dst": "新型コロナウイルス感染症_(2019年)"}
~~~

## リダイレクトとは

以下参照
[Wikipedia:リダイレクト](https://ja.wikipedia.org/wiki/Wikipedia:リダイレクト)

### リダイレクト例

https://ja.wikipedia.org/wiki/COVID-19 にアクセスしようとすると、
自動的にhttps://ja.wikipedia.org/wiki/新型コロナウイルス感染症_(2019年) に飛ばされます。

# 実装等

## 0. 必要な色々

- MySQL
- Python3
 - mysqlclient  
`pip install mysqlclient`

## 1. Wikidumpのリストア

### 必要データのダウンロード

以下から必要なデータをダウンロードしてください。  

https://dumps.wikimedia.org/jawiki/

- `jawiki-[dump取得日]-redirect.sql.gz`
- `jawiki-[dump取得日]-page.sql.gz`

### 解凍

~~~
$ gunzip jawiki-[dump取得日]-redirect.sql.gz
$ gunzip jawiki-[dump取得日]-page.sql.gz
~~~

### MySQLデータベースへリストア

~~~
$ mysql -u [ユーザー名] -p [DB名] < jawiki-[dump取得日]-page.sql
$ mysql -u [ユーザー名] -p [DB名] < jawiki-[dump取得日]-redirect.sql
~~~

## 2. リダイレクト抽出

### Pythonコード

データベースを叩いてリダイレクトを抽出しJSONで保存するコードです。

~~~python:extract_redirects.py
import json
import MySQLdb

USERNAME = "[MySQLユーザー名]"
PASSWORD = "[パスワード]"
DB_NAME = "[DB名]"
OUTPUT = "./redirects.json"

def save_jsonl(file_path, data):
    json_dumps = lambda d:json.dumps(d, ensure_ascii=False)
    dumps = map(json_dumps, data)
    with open(file_path, "w") as f:
        f.write("\n".join(dumps))

if __name__ == '__main__':
    # データベースに接続
    conn = MySQLdb.connect(
        user=USERNAME,
        passwd=PASSWORD,
        host='localhost',
        db=DB_NAME
    )

    # Cursorを作成しクエリを実行
    cur = conn.cursor(MySQLdb.cursors.DictCursor)
    sql = "select page.page_title, redirect.rd_title from page, redirect where redirect.rd_from=page.page_id"
    cur.execute(sql)
    rows = cur.fetchall()

    # 実行結果を整理
    redirects = []
    for row in rows:
        row = {key:cell.decode() if type(cell) is bytes else cell for key, cell in row.items()}
        redirects.append({
            "src":row["page_title"],
            "dst":row["rd_title"]
        })

    # 保存
    save_jsonl(OUTPUT, redirects)

    cur.close()
    conn.close()
~~~

### 実行

`python extract_redirects.py`

以上です!

# α. 軽い解説等

※事前知識:Wikipediaのページには`title`の他に`page_id`が個別に割り振られています。

`jawiki-[dump取得日]-redirect.sql.gz`では、リダイレクト元の`page_id`とリダイレクト先の`title`がレコードで紐づけられています。
`jawiki-[dump取得日]-page.sql.gz`では、`page_id`と`title`がレコードで紐づけられています。

この2つのダンプを組み合わせることで、リダイレクト元`title`とリダイレクト先`title`を紐づけています。
mackerel でホストを管理対象外（退役）とする

# はじめに
mackerel でホストを管理対象外（退役）とする方法
よく忘れるのでメモしておく

まぁ、ここに書いているんだけどね
https://mackerel.io/ja/docs/entry/howto/host-retirement



# 手順

## ホストの選択
左のメニューで「Hosts」を選択するとホスト一覧が出てくるので、管理対象外にしたいホストを選択する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/010680ab-c851-f456-a9dc-e75324842899.png" width=50%>

##ホストの設定画面表示

歯車マークの「設定」をクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/0b0cc8c7-f7ac-c5c8-8ff2-f4ec1d5c04b1.png" width=50%>

## ホストの退役

画面の一番下の右側にある「このホストを退役させる」をクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/67dafb11-99f7-5433-1e91-df1cf45d201d.png" width=50%>

その後、確認のポップアップが出てくるので「OK」を押せば管理対象外（退役）となる。

以上
[Rails]ransackで関連するモデル(親や子)のカラムをまたいで検索する方法

# 実現したいこと
1つのモデルに関連(ネスト)するモデルのカラムまで、検索対象にしたい

具体的には、古着屋の店舗名だけでなく、エリア名(1対多）や取り扱いブランド名(多対多)まで含めて一括検索したい。

<img width="1438" alt="スクリーンショット 2020-07-11 17.45.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602794/952102e7-fe9b-1de9-5036-f665a4a806c5.png">

# 結論
**フォームタグの要素名に、`関連するモデル名_関連するモデルのカラム名`を指定する**

## 関連するモデルが、`対1`（belongs_to: hoge、やhas_one: fuga）

例えば、shopモデルに紐づくareaモデルのエリア名(name)を検索条件にしたい時
`= f.フォームヘルパー :要素名`の`要素名`を`area_name_cont`とする。

>分解すると
area →　関連するモデル名
name →　関連するモデルのカラム名
cont →　部分一致を指定する述語

となります。

```ruby
= search_form_for(@q, url: shop_search_path) do |f|
  = f.text_field :area_name_cont
  # shopモデルに紐づくareaモデルの、エリア名(name)
```

## 関連するモデルが、`対多`（has_many: hogesなど）

例えば、shopモデルに紐づくbrandsモデルのブランド名(name)を検索条件にしたい時
`= f.フォームヘルパー :要素名`の`要素名`を`brands_name_cont`とする。

>分解すると
brands →　関連するモデル名 ※shop has_many: brandsなので複数形
name →　関連するモデルのカラム名
cont →　部分一致を指定する述語

となります。

```ruby
= search_form_for(@q, url: shop_search_path) do |f|
  = f.text_field :brands_name_or_genres_name_cont
  # shopモデルに紐づくbrandモデルの、ブランド名(name)
  # shopモデルに紐づくgenreモデルの、ジャンル名(name)
  # ※紐づくモデルが複数の時は、モデル名が複数形になることに注意
```
ちなみに、`_or_`などでカラム名を繋ぐと、複数カラムを検索対象にできます。

実際のransackの使い方などについては、[[Rails]ransackを利用した色々な検索フォーム作成方法まとめ](https://qiita.com/nishina555/items/2c1f8bae980e426519bc)などの記事を参考にしてください。

# モデル間のアソシエーション
※関連する箇所のみ記載

<img width="802" alt="スクリーンショット 2020-07-11 18.17.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602794/dd797cde-8b56-fb4f-5967-446e008eed7f.png">


```ruby:shop.rb
# shopモデル
  belongs_to :area, optional: true
  has_many :shop_genres
  has_many :shop_brands
  has_many :genres, through: :shop_genres
  has_many :brands, through: :shop_brands
```

```ruby:area.rb
# areaモデル
  has_many :shops
```

```ruby:brand.rb
# brandモデル
  has_many :shop_brands
  has_many :shops, through: :shop_brands
```

```ruby:shop_brand.rb
# shop_brandモデル
  belongs_to :shop
  belongs_to :brand
```

```ruby:shop_genre.rb
# shop_genreモデル
  belongs_to :shop
  belongs_to :genre
```

# 関連を調べる方法

`ransackable_associations`というメソッドを使うと便利です。

**1. アプリケーションディレクトリでrails c**

```terminal:terminal
# 該当のアプリケーションディレクトリで実行

$ rails c
Running via Spring preloader in process 61541
Loading development environment (Rails 5.0.7.2)
[1] pry(main)> 
```
**2. `モデル名.ransackable_associations`を実行**

```terminal:terminal
# 今回はShopモデルとの関連を調べたいので、Shop.ransackable_associationsとすると
  Shopモデルに紐づくモデルが表示される
[1] pry(main)> Shop.ransackable_associations
=> ["user", "area", "shop_genres", "shop_brands", "genres", "brands"]
[2] pry(main)> 
```

# 参考
[Ransackで簡単に検索フォームを作る73のレシピ -026 関連](http://nekorails.hatenablog.com/entry/2017/05/31/173925#026-%E9%96%A2%E9%80%A3)
[Ransackで親テーブルや子テーブルのカラムで複数検索する方法](https://hi-algorithm.com/ransack-multiple-search/)
Access VBAでシートとセルを指定してエクスポート

##やりたいこと
AccessでExcelの同一のシートへ追記したい。（通常のエクスポートでシート単位でデータが作成されるので）
こんなテーブルがあったとします。↓　ここから年齢別にクエリをかけて同じシートへ追記していくようにします。
![1png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205747/cf959fcf-5d4c-4303-7575-d594bd6ed947.png)

###Excelのシート、セルを指定して追記するコード
呼出側で指定されたクエリを読み込んで、データを追記していきます。ポイントはエクセルの最終行の取得の部分です。
    introw = .cells(.rows.Count, 1).End(-4162).row + 1
[終端セルを参照する(Endプロパティ)]などで検索するとでてきます。エクセルVBAならxlupで良いのですが、Accessはそんなことはわからないので明示してあげます。また、追記するのは最終行の次の行になるので＋１とします。

    Sub Excelのセルを指定して貼りつけ(qname As String)
    Dim db As Database
    Dim rs As Recordset

    Dim xpath As String
    xpath = CurrentProject.Path

    Dim introw,col as Integer
    Dim xls As Object

    Set db = CurrentDb
    '呼出側のクエリ名を取得
    Set rs = db.OpenRecordset(qname)
    'Excelの生成
    Set xls = CreateObject("Excel.Application")

    xls.workbooks.Open (xpath & "\test.xls")
    With xls.sheets("年齢別")
    '見出し行をコピー
    introw = 1
    For col = 1 To rs.Fields.Count
    'MsgBox rs.Fields(col - 1).Name
    .cells(introw, col).Value = rs.Fields(col - 1).Name
    'MsgBox .cells(row, col).Value
    Next col

    '見出し行以降をexcelの最終行に追記
    introw = .cells(.rows.Count, 1).End(-4162).row + 1
    Do Until rs.EOF
        For col = 1 To rs.Fields.Count
        .cells(introw, col).Value = rs.Fields(col - 1)
        Next col
        introw = introw + 1
        rs.MoveNext
    Loop
    rs.close
    End With

    xls.workbooks("test.xls").Save
    xls.workbooks("test.xls").Close
    Set xls = Nothing
    End Sub

次にこのサブルーチンを呼び出すコードを記述します。
クエリの条件を変更しながらデータを抽出して、先述のサブルーチンを実行していきます。

    Sub クエリ実行()
    Dim sql As String
    Dim db As Database
    Set db = CurrentDb
    Dim myq As QueryDef

    Dim age(2) As String
    age(0) = 25
    age(1) = 30
    age(2) = 45

    Dim i As Long

    For i = 0 To 2
    sql = "select * from T_顧客管理 where T_顧客管理.年齢=" & age(i) & ";"
    Set myq = db.CreateQueryDef("Q_顧客管理", sql)
    Call Excelのセルを指定して貼りつけ("Q_顧客管理")
    Application.CurrentDb.QueryDefs.Delete "Q_顧客管理"
    Next

    db.Close
    Set db = Nothing
    End Sub

クエリの実行結果が年齢順に追記されています。参考になれば幸いです。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205747/62115c45-4802-d04a-4312-a40f81cbc56e.png)
mackerel-container-agentのメトリック数を調整する

# 概要
mackerel-container-agentでFargate上のnginxとphp-fpmの監視を[実装した](https://qiita.com/batch9703/items/e30e8ccfa68da9097c6e)ら、1マイクロホストのメトリック数30を微妙にオーバーして料金が2マイクロホスト分になってしまった。
<img width="344" alt="ecs_metric_count.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152189/85342fdd-6f99-ed9a-18c3-1785cab49837.png">
6メトリックで料金が倍になるのも癪なのでいらないもを調整する。
# 監視から外してもいいメトリックを検討する
ホストの画面からグラフを確認する。
<img width="330" alt="ecs_metric_many.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152189/4a9001c7-600c-78b0-a27e-787d89d29683.png">
サービス以外の以下のコンテナはいらなそう。

* mackerel-container-agent
* \_internal_ecs_pause

# 設定方法(失敗)
目星をつけたコンテナをignoreContainerの設定でコンテナを監視対象外とする。
ignoreContainerは正規表現指定なのでOR条件で二つのコンテナ名を指定。
`\A(mackerel-container-agent|_internal_ecs_pause)\z`

```yaml:mackerel_config.yaml
apikey: "********" # mackerelのAPIキー
plugin:
  metrics:
    nginx:
      command: mackerel-plugin-nginx -host=localhost -path=/nginx_status -port=80
    php-fpm:
      command: mackerel-plugin-php-fpm -url http://localhost/phpfpm_status?json
ignoreContainer: '\A(mackerel-container-agent|_internal_ecs_pause)\z'
```

設定してデプロイ
が、、、
`_internal_ecs_pause`が監視対象外にならない、、、
そもそも、コレが何なのかちゃんと調べてなかった、、、
[公式](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-networking.html)に出てました。
> awsvpc ネットワークモードを使用してタスクが開始されると、タスク定義内のコンテナが開始される前に、各タスクに Amazon ECS コンテナエージェントによって追加の pause コンテナが作成されます。次に、amazon-ecs-cni-plugins CNI プラグインを実行して pause コンテナのネットワーク名前空間が設定されます。その後、エージェントによってタスク内の残りのコンテナが開始されます。こうすることで pause コンテナのネットワークスタックが共有されます。つまり、タスク内のすべてのコンテナは ENI の IP アドレスによってアドレス可能であり、localhost インターフェイス経由で相互に通信できます。 

ではコンテナ名は何なんだろ？
`なんとかpauseコンテナ`かなと目星をつけて正規表現で指定してみることに。

# 設定方法(成功)
`なんとかpauseコンテナ`で指定する。
`.*pause`

```yaml:mackerel_config.yaml
apikey: "********" # mackerelのAPIキー
plugin:
  metrics:
    nginx:
      command: mackerel-plugin-nginx -host=localhost -path=/nginx_status -port=80
    php-fpm:
      command: mackerel-plugin-php-fpm -url http://localhost/phpfpm_status?json
ignoreContainer: '\A(mackerel-container-agent|.*pause)\z'
```
コレでデプロイした結果、成功した。
`mackerel-container-agent`と`_internal_ecs_pause`の二つのコンテナが監視対象外にとなったので、結果として監視対象メトリック数が 36->28 となり、１マイクロホスト内に収まった、、、
![ecs_metric_count_after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152189/7077e074-6b7b-b0ba-4d54-40b7a9a0129d.png)

---
Mackerelのメトリック数のカウントってわかりにくいと思うのは自分だけだろうか、、、？
グラフ数えてもなんか微妙に違う気がするし、カウントされてるメトリック一覧みたいの出して欲しい。
styled-componentsを使ってCSS Animationを実装する方法

#はじめに
`styled-components`はReactコンポーネント内で使えるCSS in JSの一種です。
スコープをコンポーネントのローカルに保てる点や、Sass記法で記述できる点などが特徴です。

通常のCSSであれば`@keyframes`を使ってアニメーションを記述できますが、styled-componentsではどうでしょうか。

##styled-componentsでのkeyframes
結論から言うと、ほぼpure CSSと同様の記述でkeyframesを実装できます。
（keyframesのimport文が必要になります）

```javascript:animation.js
import styled, { keyframes } from 'styled-components';

const fadeIn = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;
const FadeIn = styled.div`
  animation: ${fadeIn} .5s ease-in-out;
`;

// JSXで<FadeIn>コンポーネントを使うとkeyframes: fadeInが適用される
```

##参考
[Basics - styled-components](https://styled-components.com/docs/basics#animations)
【随時更新】Ruby on Rails 便利なメソッド

### alias化されたattributeを知りたい。
```terminal
pry(main)> Member.attribute_aliases
=> { "user_name"=>"UserName", "mail_address"=>"MailAddress",}
```


### methodsメソッドで取得したメソッド一覧からgrepで検索したい。
```terminal
pry(main)> Member.methods.grep /attribute_aliases/i
=> [:attribute_aliases, :attribute_aliases?, :attribute_aliases=]
```
Herokuコマンド　アップデート

Ubuntu18.04でherokuコマンドを使うと下記のようなワーニングが、、

```warning_heroku
arning: heroku upate avaiable from 7.42.3 to 7.42.4
```

アップデートせよとのことなので、下記コマンド実行。。。

```update_heroku
heroku update
```

すると、、

```update_heroku
Warning: update with: snap refresh heroku
heroku: Updating CLI... not updatable
heroku: Updating plugins... done 
```
と出てアップデート出来ない。。

warningにsnapをrefreshと書いてあるので実行


```snap_refresh
sudo snap refresh 
```
アップデート出来ました
PHP - 偶数or奇数を判定する方法

対象の数字が偶数なのか、奇数なのか、if文で判定します。

・パターン1
対象の数字($A)を2で割った時、余りがないかを確認しています。
余りがない場合は「偶数」です。
<pre>
<?php
if ($A % 2 == 0) {
    //偶数の場合の処理
} else {
    //奇数の場合の処理
}
?>
</pre>

ビット演算子を使用します。
ビットは2進数なので、2で繰り上がっていきます。
なので、2で割り切れない数字(奇数)は2進数化した10進数の末尾が1となります。
<pre>
<?php
if($A & 1) {
    //奇数の場合>
} else {
    //偶数の場合
}
?>
</pre>

◼︎用語の詳細
・A % B
代数演算子。剰余。AをBで割った時の余り。

・A & B
ビット演算子。ビット積。
Vue.jsの環境構築まとめ

Vue.jsというJavaScriptフレームワークを勉強しようと環境構築にちょっと時間がかかってしまったのでフロートしてのこしておきます[Windows]

## Vue.jsにちょっと触れてみる
簡単なVue.jsを作成して雰囲気をつかんでみる  
CDNで読み込むだけなので簡単に確認できる  

```CDN
<script src="https://unpkg.com/vue"></script>
```
&lt;/head&gt;タグのすぐ上に挿入する

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue.jsサンプル</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <h1>Vue.js</h1>
  <div id="app">
    {{ message }}
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue'
      }
    });
  </script>
</body>
</html>
```

Hello表示を確認するのに一般的なコードですね  
{{ message }}の部分が Hello Vue になって表示されます  
  
なるほどつかいやすそうな気がする  
## ということで導入していきます

プログラミングの世界には便利なものはまとめて管理しようとする流れがあります  
【Vue.js】も【npm】とうパッケージ管理ツールで利用できます  
【npm】は【Node.js】というプログラグに組み込まれています  

- 【Node.js】の中の【npm】をつかって【Vue.js】を管理する流れです

## まずはNode.jsをダウンロード、インストールしましょう  

[Node.jsのダウンロード](https://nodejs.org/ja/)

インストールしたらコマンドプロンプトから【Vue CLI】とインストールしましょう

ディレクトリを移動して下記を入力
```
npm install -g @vue/cli
```
ちょっと時間かかります

次に【cli-service-global】ファイルも必要になるのでインストール
```
npm install -g @vue/cli-service-global
```

これでVue CLIを使用できます
Vue.jsのコマンドツールなので後々役立つので入れていきましょう  

## まとめ  
構築は比較的簡単な方だったとおもいますがディレクトリの移動や、コマンドを忘れてしまったりと細かいところでつまづきやすいです  
メモとして残っていると安心です
連想配列をsortする

## sort関数について

- 単純なsort

文字コード順に並び替えられる。

```
const suji = [50, 10, 100];
console.log(suji.sort()); // [ 10, 100, 50 ]
```
- 数値順に並び替えsort

数値順に並び変えるのなら、以下のように比較関数にします。これで、数値の大きさ順に配列が並び替える

```
const suji = [50, 10, 100];
console.log(suji.sort(function(x, y) {
	return x - y;
})); //  [ 10, 50, 100 ]

```
ここでしていることは、最初は50 - 10をして正数が返るから50は10より後で、50 - 100では負数が返るから50は100より前に来るというようにしているだけです。それを配列内の値で、順々に関数のxとyの引数に渡して位置を並び替えています。
以下のURLが非常に分かりやすい。
参考：https://furukawahiroaki.com/javascript-sort.html

## 連想配列のsort
ポイントは連想配列のkeyから配列のindexを取得できる `findIndex`メソッドを使用すること。
以下はarrのnameの順番に基づいて、objの配列を変更している。

```javascript
let arr = [
{name:'hoge',num:9},
{name:'huga',num:11},
{name:'test',num:13},
]

let obj = [
{name:'huga',num:10},
{name:'hoge',num:5},
{name:'test',num:11}
]


obj.sort(function(x,y){
   return arr.findIndex(x.name) - arr.findIndex(y.name)
})

console.log(obj)

//出力
// obj = [
// {name:'hoge',num:5},
// {name:'huga',num:10},
// {name:'test',num:11}
// ]

```

参考：https://qiita.com/Test_test/items/7d532f445f2980e896d0
Digdag公式ドキュメントからDigdagを学ぶ-Language API-Ruby

# 目標
Digdagの公式サイトのドキュメントのOperatorsの翻訳＋α
DigdagのRubyを使ってRailsにバッチを作るまでが最後の目標
http://docs.digdag.io/operators/scripting.htmlhttp://docs.digdag.io/operators/scripting.html

# 目次
[Getting started](https://qiita.com/amagasu/items/92ad70c33f73ab613d08)
[Architecture](https://qiita.com/amagasu/items/572075dcc8b3c8640072)
[Concepts](https://qiita.com/amagasu/items/c850db3b564a7d6dc99c)
[Workflow definition](https://qiita.com/amagasu/items/2a8b84ac8fb4da2d9968)
[Scheduling workflow](https://qiita.com/amagasu/items/9f47a34884ba06d93264)
[Operators](https://qiita.com/amagasu/items/1f9b26a71c86fc9d4607)
Command reference
[Language API -Ruby](https://qiita.com/amagasu/items/b11527d92d259bd3ab48)
[Digdagで環境毎に設定値を変える（RubyOnRails）](https://qiita.com/HavenSpring/items/bb1c7fbae9175c1f9479)
[Digdagを用いてRubyOnRails環境でバッチ実装](https://qiita.com/HavenSpring/items/b3c3e26ef868f8d5eaf4)

# Language API-Ruby
## **Programmable workflow in Ruby**

```rb:workflow1.dig
_export:
  rb:
    require: 'tasks/my_workflow'

+step1:
  rb>: MyWorkflow.step1

+step2:
  rb>: MyWorkflow.step2
```

```rb:my_workflow.rb
class MyWorkflow
  def step1
    puts "ruby step1"
  end

  def step2
    puts "ruby step2"
  end
end
```

```rb:結果
$ digdag run workflow1.dig --rerun
2020-07-12 17:37:09 +0900 [INFO] (0017@[0:default]+workflow1+step1): rb>: MyWorkflow.step1
ruby step1
2020-07-12 17:37:10 +0900 [INFO] (0017@[0:default]+workflow1+step2): rb>: MyWorkflow.step2
ruby step2
```

## **Defining variables**
step1でmy_valueに1を保存してstep2では保存した変数を出力する

```rb:
class MyWorkflow
  def step1
    Digdag.env.store(my_value: 1)
  end

  def step2
    puts "step2: %s" % Digdag.env.params['my_value']
  end
end
```

## **Method argument mapping**
step1で設定した変数はstep2で関数のパラメーターとして受け取れる

```rb:my_workflow.rb
class MyWorkflow
  def step1
    Digdag.env.store(my_value1: 1)
    Digdag.env.store(my_value2: 2)
  end

  def step2(my_value1: 0, my_value2: 0)
    puts "my_value1: #{my_value1} my_value2: #{my_value2} "
  end
end
```

```rb:結果
$ digdag run workflow1.dig --rerun
2020-07-12 17:47:41 +0900 [INFO] (0017@[0:default]+workflow1+step1): rb>: MyWorkflow.step1
2020-07-12 17:47:42 +0900 [INFO] (0017@[0:default]+workflow1+step2): rb>: MyWorkflow.step2
my_value1: 1 my_value2: 2 
```

## **Generating child tasks**
Digdag.env.add_subtaskを使ってRubyでサーブタスクを生成可能です。

```rb:my_workflow.rb
class MyWorkflow
  def step1
    puts "step1 start"
    Digdag.env.add_subtask(MyWorkflow, :step3, arg1: 3)
    Digdag.env.store(my_value: 2)
  end

  def step2(my_value: "default")
    puts "step2: %s" % my_value
  end

  def step3(arg1:)
    puts "step3: %s" % arg1
  end
end

```

結果を見るとわかると思いますがstep1が実行される時、step1で追加したサブタスクstep3が実行される。

```rb:結果
$ digdag run workflow1.dig --rerun
2020-07-12 17:56:27 +0900 [INFO] (0017@[0:default]+workflow1+step1): rb>: MyWorkflow.step1
step1 start
2020-07-12 17:56:27 +0900 [INFO] (0017@[0:default]+workflow1+step1^sub+subtask0): rb>: ::MyWorkflow.step3
step3: 3
2020-07-12 17:56:28 +0900 [INFO] (0017@[0:default]+workflow1+step2): rb>: MyWorkflow.step2
step2: 2
```

これでDigdagとRubyとの連携についての説明は完了です。
次回からRubyでバッチを作ってDigdag上で実行してみたいと思います。
マウスのみで今Qiitaの最新記事を猫に喋らせたいなら

[![Image from Gyazo](https://i.gyazo.com/2246157be6e368b9bdd4dec086e4bf2a.png)](https://gyazo.com/2246157be6e368b9bdd4dec086e4bf2a)

猫といっても見た目憎たらし…（おっと誰か来たようだ…）

# はじめに
Scratch3.0で拡張ブロックを作ってみたくてWebAPIを利用するブロックを作ってみました！

また、この記事は`Qiita夏祭り2020_パソナテック`のエントリー記事です。
テーマページは[こちら](https://qiita.com/official-events/5d181aadf5db26b73d33)

言語としてはJavaScriptで拡張ブロックを追加していきます！

# Scratchで拡張ブロックを作る

参考記事
* https://qiita.com/Hiroyuki_OSAKI/items/a46e1c881d3aed4661f7
* http://www.moonmile.net/blog/archives/10331

たいへん参考になりました。
やはりたくさん情報がありますね。
しかし、vmとguiのフォルダ行き来するのは確かに大変…

## ソースコード

今回は`axios`を使ってQiitaのAPIを利用します。
なのでまず`axios`のインストールです。

```sh
npm i axios
```

この後、ブラウザリロードだけだとだめで、一度ローカルで立ち上げているScratchを落とし


```sh
yarn start
```

でもう一度立ち上げが必要でした。

以下、`scratch-vm/src/extensions/scratch3_newblocks/index.js`内の一部です。

```js
const axios = require("axios");
(略)
　　　　　　　　　{
                    opcode: "tagBody",
                    blockType: BlockType.REPORTER,
                    text: "tag: [TEXT] の最新記事の内容",
                    arguments: {
                        TEXT: {
                            type: ArgumentType.STRING,
                            defaultValue: "Qiita",
                        },
                    },
                },
(略)
    tagBody(args) {
        const tag = Cast.toString(args.TEXT);
        return axios
            .get("https://qiita.com/api/v2/items?per_page=1&query=tag:" + tag)
            .then((response) => {
                console.log(response.data);
                return response.data[0].body;
            })
            .catch((err) => {
                console.log("err:", err);
                return err;
            });
(略)
```

略が多いですね。触るファイルも多ければ飛び飛びで書かなきゃですし…

# 使ってみる

試しにスクラッチキャットに喋らせてみました。

[![Image from Gyazo](https://i.gyazo.com/9df152b707d7a9aea7e2487e624ac823.png)](https://gyazo.com/9df152b707d7a9aea7e2487e624ac823)

インテリな猫になりましたね…
**かわいィィぃぃeeee！！**

# おわりに
拡張ブロックを作るのは一回わかれば簡単にできそうですが、やはり色々なファイルや箇所も飛び飛びな場所を触らなきゃだったりなので怖いですね。

でもブロック作るのは楽しい！
【ER図】ER図の基本知識とIEとIDEF1X の違い

# ER図とは

データベース設計（データモデリング）で使う設計手法のこと。
ER 図を熱用してデータ構造を俯瞰的に設計できる！

主な ER 図は 2 つ

- IE 記法（鳥の足記法）
- IDEF1X 記法

## IE記法とは

リレーションが鳥の足のような形をしていることから、別名「鳥の足記法」とも呼ばれる

リレーションが直感的に理解しやすい

## IDEF1X記法とは

世界中で使われるポピュラーな ER 図記法

リレーションを「●」で表現する

IE 記法より細かい表現ができる

## ER図の基本ルール

IE記法とIDEF1X記法に共通した基本ルール（カーディナリティ以外）

### エンティティ

データのまとまりのこと。
エンティティの中に、アトリビュートという属性情報がある

e.g.

顧客 IDのなかに顧客名、電話番号がある

### アトリビュート（属性）

エンティティの中の属性情報のこと

アトリビュートの中で「主キー」や「外部キー」も表現する

主キーの項目は、エンティティ上部で資格に囲い明示する

外部キーの項目は、最初の項目名の後ろに「（FK）」と書いて明示する（それ以降の項目は、項目名のみ記述する）

### リレーション

エンティティ同士の関係を表現する線のこと。
リレーションの詳細は「カーディナリティ」という記号を使って表現する

### カーディナリティ（多重度）

1対1や1対多、多対多など、リレーションの詳細を表現する記号のこと

0以上や0または1といった表現も消える

### エンティティの依存関係、非依存関係とは

#### 依存関係

依存関係とは、必ず紐づくデータが存在しなければならない関係のこと

エンティティ間で親子関係になる

子となるエンティティの枠線を角丸で表現する

e.g. 注文テーブル（親エンティティ）と注文詳細テーブル（子エンティティ）

#### 非依存関係

エンティティ間で「親子関係がない」リレーションのこと

どちらも四角の枠線で表現する

e.g. 社員マスタと社内サークルマスタ
社員番号を元にリレーション関係が成り立っているが、紐づくデータがなくてもシステム的に成り立つ

## カーディナリティの書き方

IE記法とIDEF1X記法では、カーディナリティの書き方が異なる

### IE記法

IE記法は「○」「|」「鳥の足（３つ又の線）」という3つの記号を組み合わせて表現

| 記号 | 意味 |
| --- | --- |
| ○ | 0（ゼロ） |
| \| | 1 |
| 鳥の足 | 多 |

### IDEDF1X記法

IE記法に比べて細かい表現ができる

| 記号 | 意味 |
| --- | --- |
| なし（エンティティと直線を結ぶ） | 1 |
| ● | 0以上 |
| ●P | 1以上 |
| ●Z | 0または1 |
| ●N | 指定した数。仕様に応じてNに実数を代入(e.g. ●10) |
| ●N-M | 実数の範囲指定。仕様に応じてNとMに実数を代入(e.g. ●1-10) |
| ◇ | 0または1 ※非依存リレーションでのみ使用 |
列挙型に値が存在するか確認する方法

特定の事柄に対して値を持たせる場合に、定数って使いたいじゃないですか。
Pythonで定数を扱う場合って個人的には`Enum`（列挙型）を使うのがいいと思うんです。

## そもそもPythonって定数なくない？
そうなんです。
どんな値でもやりようによっては上書きできてしまうので、厳密な意味での定数は存在しません。
でも[公式ドキュメント](https://docs.python.org/ja/3/library/enum.html) にそう書いてあるんだもん。

## 列挙型の記法
```python
from enum import Enum
class Hoge(Enum):
    ONE = 1
    TWO = 2
    THREE = 3
```

## 列挙型とループ処理
列挙型は識別子の集合なので、識別子に持たせた値そのものに意味があるケースが少ないのではないかなと。
リスト型であればfor文で簡単に出力できるのですが、列挙型では書き方に工夫が要ります。

```python:リスト型
>>> lst = [1, 2, 3]
>>> [l for l in lst]
[1, 2, 3]
```
```python:列挙型
>>> from enum import Enum
>>> class Hoge(Enum):
...     ONE = 1
...     TWO = 2
...     THREE = 3
...
>>> [v.value for n, v in Hoge.__members__.items()]
[1, 2, 3]
```

## ここまで来れば書けそう
```python
>>> from enum import Enum
>>> class Hoge(Enum):
...     ONE = 1
...     TWO = 2
...     THREE = 3
...
>>> [v.value for n, v in Hoge.__members__.items()]
[1, 2, 3]
>>> 1 in [v.value for n, v in Hoge.__members__.items()]
True
```
できました。使い所は知りません。

### おまけ
列挙型の`__members__`の中身ってどうなっているんだろう？

```python
>>> Hoge.__members__
mappingproxy({
    'ONE': <Hoge.ONE: 1>,
    'TWO': <Hoge.TWO: 2>,
    'THREE': <Hoge.THREE: 3>
})
```
`MappingProxyType`ってなんだろう？
[公式ドキュメント](https://docs.python.org/ja/3/library/types.html?highlight=mappingproxytype#types.MappingProxyType)によると
> 読み出し専用のマッピングのプロキシです。マッピングのエントリーに関する動的なビューを提供します。
> つまり、マッピングが変わった場合にビューがこれらの変更を反映するということです。

なるほど（？）
このプロキシの中に`items()`があるわけですね。
さらっと見た感じだと辞書型にも似てますね。

# 追記
@shiracamus様よりもっと簡素的な書き方があると教えていただきました。

```python
>>> 1 in [e.value for e in Hoge]
True
```
あるいは

```python
>>> any(e.value == 1 for e in Hoge)
True
```
と書けるようです。ありがとうございます！！
一つ目の方はなぜ気付かなかったのだろうかというレベルです・・・

記事を書くことでアドバイスをいただけるので、やはりアウトプットって大切だなぁと思いました。
JSFのバージョンを確認する方法

簡単に確認できる方法を知っている方は教えてください

# 方法1. `FacesContext`クラスで確認する
1. `FacesContext`クラスをimportしているクラスを探す
    1. `$ grep -iIr import | grep FacesContext`
2. デバックしやすいクラスを選んでブレークポイントを張る
3. デバックする
4. ブレークポイントにきたらEclipseの[Expression]タブなどで以下の結果でバージョンを確認する
    1. `FacesContext.class.getPackage().getImplementationVersion();`
    1. `FacesContext.class.getPackage().getImplementationTitle();`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/1849e369-26b7-56ae-2403-c368ffab61c5.png)

# 方法2. MANIFEST.MFを見る
`/META-INF/MANIFEST.MF`を開いてみる

# 方法3. pom.xmlをみる
Mavenのプロジェクトの場合

```xml
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.faces</artifactId>
      <version>2.3.9</version>
      <scope>provided</scope>
    </dependency>
```

# 参考
- [How to detect current JSF-Version? - Stack Overflow](https://stackoverflow.com/questions/13125782/how-to-detect-current-jsf-version)
googletransでプロキシ設定

###こんなエラーに悩んでいませんか？

```
httpcore._exceptions.ConnectError: [Errno 0] Error
```
たぶんこのページで解決できます．知らんけど．
結論から申し上げますと，翻訳APIのインスタンス化の際に以下のようにプロキシオプションを付与するだけで解決できます．

```
translator = Translator(proxies={"ホスト名":ポート番号})
```

###社内ネットワークってめんどくさいですよね
というわけでこんにちは．
業務の関係上，英文メールをよく作成するのですが，英語よわよわ星の出身なので苦労することがよくあります．
楽にサクッと作成したいときは自動翻訳使えると便利だなーということで，自動化ツールを作成したのですが，その際社内ネットワークのプロキシ設定が回避できず，ドツボにハマったのでその覚書です．
サーバーまわりやネットワークまわりはド素人なので，有識者のコメントをお待ちしております．
作った自動化ツールについてはまた気が向いたときにでも．



###環境とか必要パッケージ
-Windows10
-python3.8
-VScode1.47
-**何らかの社内ネットワーク**

たぶんパッケージはgoogletransのみで大丈夫なはず．
`pip install googletrans`でインストール．
下のサンプルコードを回す場合は`pip install pyperclip`しておきましょう．
クリップボードをpythonから扱えるようになります．

###社内ネットワークの情報を調べる
プロキシ設定が有効の時に**[こちら](http://taruo.net/e/?)**にアクセスすると，自動で解析してくれます．
`REMOTE_ADDR`の部分のipアドレスを控えておいてください．
ここでは気の利いた例が思いつかないので 123.456.789.012だったとしましょうか．

もしここで上のリンクを踏んでも社内サービスなどでブロックされてしまった方は，おとなしくシステムを管理している部署に問い合わせてください．僕には他の方法がわかりません．

###サンプルコード
これで必要な準備は完了です．以下のコードはクリップボードをの文字列を取得して翻訳するスクリプトなので，①コピペして，②123.456.789.012という頭の悪そうな部分だけ書き換えて，③適当な日本語をクリップボードにコピーして実行してみてください．

なお，その直後の80はプロキシのポート番号です．環境によって異なりますが，よく使われるのは80,8080,1080,3128あたりらしいです．よく知りません．
windowsの方で，すでに有効化している場合は本体設定の「プロキシの設定を変更する」から既存値を確認できます．

```translate.py
import pyperclip
from googletrans import Translator

text = str(pyperclip.paste())  #クリップボードから文字を取得
print('原文',text)

translator = Translator(proxies={"123.456.789.012":80})  #ここを書き換えてね．

text = translator.translate(text, dest = 'ja').text   # 翻訳
print('翻訳',text)
```

ちなみに，googletransを利用したコードをいくつか見ましたが，大抵が
`translator = Translator() `と書いてますよね．インスタンス化とゆーやつ．
そこに`proxies={"123.456.789.012":80}`を入れるだけで，それ以降に変更を入れる必要は特にありません．[公式リファレンスはこちら](https://py-googletrans.readthedocs.io/en/latest/)

コメントお待ちしております！よき翻訳ライフを．
ブラウザの戻るボタンを無効化する

#javascriptでブラウザの履歴を操作する

#####やりたかったことは、
一日一度押せるボタンがあって押したらページ遷移して、遷移先のページから戻るボタンでは前のページに戻らせない（ブラウザバックで戻るとサイドボタンを押せてしまうため）

```javascript
window.addEventListener('DOMContentLoaded', function () {
  // 戻るボタンを制御
  history.pushState(null, null, location.href);
  window.addEventListener('popstate', (e) => {
    history.go(1);
  });
});
```
###history.pushState(null, null, location.href);
まずこの記述で、偽の履歴を追加しています。

###window.addEventListener('popstate', function(e){...}
ブラウザバックのイベントを取得して

###history.go(1);
で偽装したページに遷移させます。

以上です。

参考にさせてい頂いたサイト
https://pisuke-code.com/javascript-prohibit-browser-back/
ありがとうございました。
Ubuntu Desktop 20.04 にて起動時にスプラッシュ画面からログイン画面へ遷移できなくなった問題についてのメモ

## 事象

ThinkPad T480s に入れていた Ubuntu 20.04 にて、PC起動時に以下のスプラッシュ画面からログイン画面へ遷移しなくなった。

![splash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10443/633c8acb-fa38-dfd0-8c31-f3ae00a316c0.jpeg)

強制的に再起動して、リカバリーモードで起動。
root権限で CUI から `less /var/log/boot.log` を実行したところ、以下のように `A start job is running for Hold until boot process finishes up` が多数出力されていることを確認。

![boot_log.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10443/b002408d-865e-2b38-cc92-de129ddd161f.jpeg)

## 原因

上記のメッセージ `A start job is running for Hold until boot process finishes up` を Web で検索をかけたところ、以下のページをみつけた。

Cannot boot system due to start job running for hold
https://askubuntu.com/questions/760825/cannot-boot-system-due-to-start-job-running-for-hold

このページに書かれている以下のとおり、リカバリーモードから resume で起動したところ、ログイン画面に到達できた。

> I was able to start in recovery mode until I see the recovery mode menu and, from there, when choosing "resume" I would get to the normal graphical environment. 

このことから、起動時のスプラッシュ画面でなにか悪さをされていると判断。

## 解決

前述のページで書かれているとおり、リカバリーモードで `sudo apt remove plymouth` を実行して、以後は通常起動時にログイン画面に到達できるようになった。
Travis CI のバッジが変わらない時の対処法（ステータス・アイコンが Failing のまま）

> Travis CI の**テストをパスしたのに README.md のステータス・バッジが `Failing` のまま**です。
> Travis CI のサイトにあるバッジ表示では `Passing` のグリーンになっています。

**Chorme のみでの現象**で、Firefox やスマホでは表示は変わっているため、キャッシュ関連に問題がありそうです。

しかし、[「travis ci badge not updating」でググる](https://www.google.com/search?q=travis+ci+badge+not+updating)と出てくる、シークレット・ウィンドウで開いても NG、`Crtl`+`F5` でも NG、`Shift + リロード` の強制読み込みも NG です。

最終手段として「Cookie、キャッシュなどを全てクリアする」と直るのですが、他のサイトもすべて再ログインが必要になるので、簡単に・確実にキャッシュをクリアできないものでしょうか。


## TL; DR

> **Chrome のデベロッパー・モードで「キャッシュの消去とハード再読み込み」**します。ログイン Cookie なども無事です。

## TS; DR

この現象は GitHub などの [CDN](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%83%87%E3%83%AA%E3%83%90%E3%83%AA%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF) を通しているサイトで発生する可能性が高いです。そのため、オリジナルの画像（ステータス・バッジ）が更新されていても、参照している他のサイトで更新されないケースが発生します。

1. 表示のおかしいサイトを開きます。
2. Chrome の `⋮` メニューの「その他のツール」から「デベロッパー ツール」を開きます。<br><sup>（デベロッパー・モードに入り、右側にデベロッパー・ツールのペインが表示されます）</sup>
2. ツールを開いたまま、ブラウザの更新アイコンを右クリックします。
3. 「キャッシュの消去とハード再読み込み」を選択します。


### 参考文献

- [Travis-CI badge not updating](https://stackoverflow.com/a/61676400/12102603) @ StackOverflow
BigQueryにASSERT文が来たのでDebuggingのおさらい

# BigQueryにASSERT文が来た
2020-07-13 UTC以降、ASSERT文がサポートされました。
検証結果がTRUEであることを検証できます。

ERROR関数に次いで、2番目のDebugging系の機能です。
2020-07-14 10:36 JST現在、US以外のロケーションではサポートされていないようです。

# Debuggingのおさらい
BigQueryには、従来ERROR関数があり、**ないべき値はERROR関数**で記述することができました。
新たにリリースされたASSERT文は、文であり、**あるべき値をASSERT文**で記述できるようになりました。

## ASSERTの使い方
ASSERT文は、あるべき状態を検証します。プログラミングの`ASSERT`のように、`TRUE`でない式が評価された場合にエラーを発生させます。ただし、デバッグレベルを調整して無視するような機能は今のところBigQueryにはないです。

文ですので、SELECT文と同じレベルで記述します。

### エラーメッセージ付きASSERT
ASSERTの後に、BOOLを返す式を入れます。ASでエラー時のメッセージを記述します。
メッセージは文字列リテラルである必要があり、Scriptingから変数を入れることはできません（EXECUTE_IMMEDIATEを除く）。

```sql
ASSERT
  (
  SELECT
    LOGICAL_AND(x > 0)
  FROM
    UNNEST([1,-1]) AS x) AS 'x > 0'
```

エラーはこのように出ます。

```
x > 0
```

式が`FALSE`か`NULL`を返す場合エラーになります。

### メッセージ省略ASSERT
メッセージは省略可能ですが、見返すことを考えると意味の分かるメッセージを入れておくことが推奨されます。

```sql
ASSERT 0 = 1
```

エラーはこのように出ます。

```
An internal error occurred and the request could not be completed. Error: 3144498
```

### ASSERTの注意点
ASSERT文はキャッシュされません。同一の文を複数回実行したり、Scriptingで繰り返したりしても、毎回参照料金がかかります。

## ERRORの使い方
ERROR関数は、あってはならない状態を検証します。
ERROR関数が評価されたタイミングでエラーを発生させます。


関数ですので、SELECT文の中で記述します。
IF関数やCASE式とセットで使ったり、存在しないことを`SELECT ERROR`で確認に使うことが多いです。

### エラーメッセージ付きERROR


```sql
SELECT
  *
FROM
  UNNEST([-1])x
WHERE
IF
  (x > 0,
    TRUE,
    ERROR(FORMAT('Error: x must be positive but is %t', x)));
```

エラーはこのように出ます。

```
Error: x must be positive but is -1
```

### エラーメッセージ省略ERROR
引数は省略できませんが、空文字列を入れることができます。

```sql
SELECT
  ERROR('')
```

```
An internal error occurred and the request could not be completed. Error: 3144498
```

NULLを入れると別なエラーになります。

```sql
SELECT
  ERROR(NULL)
```

```
Input to ERROR function must not be NULL
```

## ASSERTとERRORの違いまとめ
- ASSERTはあるべき状態を、ERRORはないべき状態を記述する
- ASSERTは文、ERRORは関数
- ASSERTは引数がFALSEかNULLだとエラー、ERRORは評価されると、エラー
- ASSERTは文字列リテラル（実行前評価）、ERRORは文字列（実行時評価）をエラーメッセージにする
- ASSERTはキャッシュされない、ERRORはキャッシュされる


# 使い所
## ASSERT
データの全体感のチェックに使うと良さそうです。Scriptingでプロシージャにして、データの定期健康診断にしても良いですね。

- UNIQUE制約を満たしているか
- 外部キー制約を満たす割合は妥当か
- 中央値平均値、パーセンタイルは妥当か
- TrainingデータとServingデータに乖離がないか
- データがテストデータと完全一致しているか（ユニットテスト）

## ERROR
データの個別行のチェックに使うと良さそうです。EL(Extract/Load)やT(Transform)に混ぜ込んで、ワークフローの健康診断に使っても良いですね。

- データに値域異常がないか
- 外部キー制約を満たしているか
- データの行内依存関係を壊す異常がないか（最大値列と最小値列が逆になっていないか）
- 関数が想定の動作をしているか（ユニットテスト）

# まとめ
BigQueryのDebugging機能にASSERT文が仲間入りして、データのあるべき状態を検証しやすくなりました。ワークフロー系ツールと相性が良さそうですので、通知系まで組み入れてデータの健康診断をちょくちょく出来ると良いですね。
３次元座標データ群に関し、”ほぼ一致する”点が存在するかをひたすら確認する

#はじめに
もっといい方法はないだろうか..と模索しつつも、ひとまずこの方法でまとめておく。**~~（もっといい方法ご存知の方、教えてください！！）~~→教えて頂いた皆様、本当にありがとうございました！改良版をページ下部に追記しました。**

#やりたいこと
①基本
下図のように３次元の座標点が格納されているエクセルがあり、同じ座標を持つ番号をリンクさせたい。下図の例ではS/N-2の座標とS/N-3の座標（水色でハイライトした箇所）は完全一致しているので、これらは「同じ座標です！」と判定させる。

②応用
私が今回取り組んでいる対象の仕様として、完全に座標が一致することはなかなか起こらない。そのため、ある程度のMarginをもって一致していると判定したい。例えば、S/N-8の座標とS/N-9の座標（黄色でハイライトした箇所）は**概ね**一致しているので、これらも「同じ座標です」と判定して欲しい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/21505b38-9c3d-1dcb-315a-8562c0249745.png)

今回、この”応用”のグッドアイデアが今一つ思い浮かばなかった。。
完全一致のみを抽出する場合はX座標、Y座標、Ｚ座標を文字列として結合して、一致するか判断していけばいいのかなと思いました。

#できたコードがこのような感じ
まずはmarginを含んで判定できるような関数を作成。以下の場合誤差±100は無視され、３つの座標がmargin込みで一致した場合、Trueが返ります。

```python

def coordinates_check(ax,ay,az,bx,by,bz):
    margin=100
    flag = 0
    result=False
    
    if ax-margin < bx < ax+margin:
        flag = flag +1
    if ay-margin < by < ay+margin:
        flag = flag +1
    if az-margin < bz < az+margin:
        flag = flag +1
        
    if flag >2:
        result = True

    return result
```

この関数を使用して、エクセルファイルの行を上から読み取っていきます。
読み取りが重複しないように、２つ目のfor文の開始番号を工夫しています。

```python
df_test = pd.read_excel('sample.xlsx')

for i in range(len(df_test)):
    ax= df_test.loc[i,"X座標"]
    ay= df_test.loc[i,"Y座標"]
    az= df_test.loc[i,"Z座標"]
    k = i+1
    for j in range(k,len(df_test)):
        bx = df_test.loc[j,"X座標"]
        by = df_test.loc[j,"Y座標"]
        bz = df_test.loc[j,"Z座標"]
        if coordinates_check(ax,ay,az,bx,by,bz):
            print("一致しました：",df_test.loc[i,"S/N"],"-->",df_test.loc[j,"S/N"])
```

結果、うまくできている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/b724a72b-26c4-7365-d08b-f8e78a2808ff.png)

# 少ないデータならいいのだけど..
私が今回使いたいデータは1万行超えで、上記のコードを実行すると**３時間くらい**かかってしまったんですよね..。もっといい方法があるはずだよなぁと思った今日この頃でした。いい方法をご存知の方、助けてください！

# (2020/7/16追記)助言をもとにアップデート
コメント欄にて協力頂いた皆様、誠にありがとうございました！！
numpyに変換し、ismatchを使って処理したところ**およそ2秒**で完了しました。
恐るべし..numpy..

（↓参考に頂いたコードのほぼコピペです。本当にありがとうございました。）

```python
import time
import numpy as np

margin = 100

data = df_all.loc[:, ["X座標", "Y座標", "Z座標"]].values

margin = 100

match_dict = {}

start = time.time()
for i in range(data.shape[0]):
    # Broadcast用にshapeを拡大する
    compared = np.expand_dims(data[i], 0) # shape = (1, 3)

    # np.abs(data[i+1:] - compared) < margin　で各要素がmargin内に入っているか判定
    # np.all(axis=1)でx,y,z軸の論理積を取っている
    # 最終的なismatchはi+1番目からのshape=(10000 - i - 1)のBoolean型になる
    ismatch = np.all(np.abs(data[i+1:] - compared) < margin, axis=1) # shape = (10000 - i - 1,)

    # True=1，False=0と捉えられるので，nonzeroでTrueのIndexを取得
    # ismatchのIndexはi+1番目からなので + (i + 1)する
    match_dict[i] = np.nonzero(ismatch)[0] + i + 1
    #print(np.nonzero(ismatch)[0])


print(time.time() - start) # 2s
```

良い感じ！(Index=2はIndex3,4とマッチしている）
numpy.nonzeroがこのような振舞いをするとは、知らなかったですね..。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/cdea94b0-7cd4-4772-8183-9e50eb2571de.png)
[Chakra UI]TypeError: Cannot use 'in' operator to search for 'green' in undefined

##問題
npm installでchakra-uiをインストールしてすぐ、ボタンを描画しようとしたがこのようなエラーが出た。

##直し方
ThemeProviderってゆうのを使う必要があるみたい。
これを加えたらうまくいけました。

```sample.js
// import the provider
import { ThemeProvider, CSSReset } from '@chakra-ui/core'

// in your index.tsx, add this

<ThemeProvider>
   <CSSReset />
   <App/>
</ThemeProvider>
```
Rubyで配列の中のハッシュの値を取り出す方法

久しぶりにRubyに触れたらびっくりするぐらいわからなかったので調べました。

こんな気持ち悪い配列とハッシュの組み合わせの場合。

```ruby:test.rb
user_data = [
  { user: { profile: { name: 'George', sex: 'man' } } },
  { user: { profile: { name: 'Alice', sex: 'woman' } } },
  { user: { profile: { name: 'Taro', sex: 'man' } } }
]
```
配列の中に、userというハッシュがあり、更にネストしてprofileというハッシュがあり、nameというキーに値が入ってる・・・もはやわけがわからんですね。

ではこれを取り出してみます。

## 'George'を取り出す。
こんな感じ

```ruby:test.rb
puts user_data[0][:user][:profile][:name]
```

'Alice'を取り出すなら当然こんな感じ

```ruby:test.rb
puts user_data[1][:user][:profile][:name]
```

配列の位置を変えただけ。

'Alice'のハッシュ内にある性別を取り出す場合は

```ruby:test.rb
puts user_data[1][:user][:profile][:sex]
```

:nameを:sexに変えただけ。

## 配列内にある:nameをすべて取り出す
配列なのでeachを使って１つずつ取り出す。

```ruby:test.rb
user_data.each do |values|
  puts values[:user][:profile][:name]
end
```

結果はこうなる

```ruby:test.rb
George
Alice
Taro
```

## digメソッドを使う場合
Ruby 2.3以降からはハッシュクラスで新しく使えるメソッドとしてdigというものが用意されています。

### digメソッドで'Gorge'を取り出してみる

```ruby:test.rb
puts user_data.dig(0, :user, :profile, :name)
```
配列に含まれたハッシュなら、何番のデータがほしいか引数に入れるだけ。

### digメソッドで　':name'全て取り出してみる

```ruby:test.rb
user_data.each do |values|
  puts values.dig(:user, :profile, :name)
end
```

### digメソッドを使うメリット
キーが見つからない場合にエラーで返すかnilで返すかの違いのようです。digを使えばnilで返してくれるのでエラーへの対策が不要になるとか。（それまではfetchメソッドを使うなどしていたそうです）

```ruby:test.rb
user_data = [
  {user: {}},
  {user: {}},
  {user: {}}
]

# digを使った場合
user_data.each do |values|
  puts values.dig(:user, :profile, :age)
end

# digを使わなかった場合
user_data.each do |values|
  puts values[:user][:profile][:age]
end
```

こんな感じの結果となる

```ruby:test.rb
% ruby tmp/test.rb
#=> nil

#=> undefined method `[]' for nil:NilClass (NoMethodError)

```
circleci　環境変数の設定

#circleciで環境変数を知らなかったので、備忘録メモ


## circleciで環境変数を設定
1.　pipelinesの右上にある**Project Setting**をクリック
<img width="1184" alt="スクリーンショット 2020-07-14 11.12.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/3d079298-6415-961b-182b-24de861cf338.png">




2.ページ左の**Environment Variables**をクリック
<img width="364" alt="スクリーンショット 2020-07-14 11.14.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/409fd418-d41b-545e-7aa4-851c1742125c.png">
　
3.**Add Variable**をクリックして設定していく
<img width="1144" alt="スクリーンショット 2020-07-14 11.16.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/c14fffc9-4b29-9af8-f844-9e3867e55664.png">




## config.yml

```ruby:.circleci/config.yml
      - run:
          name: Environment Variables
          command: |
            touch .env
            echo GOOGLEMAP=$GOOGLEMAP > .env
            echo S3_ACCESS_KEY_ID=$S3_ACCESS_KEY_ID > .env
            echo S3_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY > .env
```



circleciで設定した環境変数を.envに入れていく
pandas_profilingを使ってデータの状態を確認する

# 概要
データエンジニアやデータ整備をやっている方はデータの不整合見るときにいろいろなツールを使って調べたり、SQLで叩いて調べたりすると思います。
最近自分もそのようなことをすることが多いです。特に新しいデータの連携とかが始まった時などはデータの内容を見ることが多いです。そんな時に[pandas_profiling](https://github.com/pandas-profiling/pandas-profiling)は役に立ちます。


# インストール方法
```
pip install pandas-profiling[notebook]
```

# 使い方
```python
import pandas_profiling as pdp
from sklearn.datasets import load_boston

data = load_boston()
df = pd.DataFrame(data.data, columns=data.feature_names)

profile = pdp.ProfileReport(df, {'correlations': None})
profile.to_file("profile.html")

```

私は単純にデータの分布が知りたいことが多いので相関の計算などはしないようにオプションを追加しています。
また他の方への共有などをするためにhtmlに出力しています。

# 結果
Jupyter notebook上で実行すると下図のようにプロセスバーが表示され、処理されている状態がわかります。
各項目のデータの状態がわかります。特に私が気にかけているのは欠損値で、欠損値の数や割合が表示されるのでとても便利です。

![スクリーンショット 2020-07-14 11.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199445/8c37139b-27c9-9d29-57d8-684e1771dcb6.png)
![スクリーンショット 2020-07-14 11.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199445/6f86e296-fa1e-1739-99ae-4d116bc3b4f8.png)