OmniAICreator/Qiita-1.07M huggingface dataset:
FlaskでdictConfigのconfigを他のファイルから呼び出すだけのサンプル


dictConfigのconfigを他のファイルから呼び出すだけのサンプル。
utilsフォルダーに外出しした。


フォルダー構成。


```
main.py
utils/logger_config.py
```


```py:main.py
from flask import Flask, jsonify
from logging.config import dictConfig
from utils import logger_config

# log用のconfigの読み込み
dictConfig(logger_config.dict_config())

app = Flask(__name__)

```




```py:utils/logger_config.py

def dict_config():

    return {
        'version': 1,
        'formatters': {
            'file': {
                'format': '[%(asctime)s] [%(levelname)s] : %(message)s',
            }
        },
        'handlers': {
            'file': {
                'class': 'logging.handlers.TimedRotatingFileHandler',
                'formatter': 'file',
                'filename': './logs/application.log'
            }
        },
        'root': {
            'level': 'WARN',
            'handlers': ['file']
        },
    }

```




下記のようにmain.pyが冗長になるのが嫌だった。


```py:main.py

from flask import Flask
from logging.config import dictConfig

dictConfig({
        'version': 1,
        'formatters': {
            'file': {
                'format': '[%(asctime)s] [%(levelname)s] : %(message)s',
            }
        },
        'handlers': {
            'file': {
                'class': 'logging.handlers.TimedRotatingFileHandler',
                'formatter': 'file',
                'filename': './logs/application.log'
            }
        },
        'root': {
            'level': 'WARN',
            'handlers': ['file']
        },
    })

app = Flask(__name__)

```




この記事の書き方も参考になる。


https://qiita.com/ichi_zamurai/items/ebf9c0d2c4ea3fafe63e

https://hellowac.github.io/2022/01/12/Flask%E9%85%8D%E7%BD%AE%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95%E5%99%A8.html
poetry で自動生成された pyproject.toml を使って Sphinx でドキュメント自動生成

# 動機

[PEP 621](https://peps.python.org/pep-0621/) や [PEP 631](https://peps.python.org/pep-0631/) にあるように、Python を使うプロジェクトの設定は pyproject.toml に記載することが求められている。

[poetry](https://python-poetry.org/) は pyproject.toml を自動生成し、インストールしたパッケージ情報を（requirements.txt を使うこと無く）pyproject.toml に記載してくれる。

また [sphinx-pyproject](https://github.com/sphinx-toolbox/sphinx-pyproject) は pyproject.toml を自動的に読み取るので、
[Sphinx](https://www.sphinx-doc.org/ja/master/) の conf.py から sphinx-pyproject の SphinxConfig を呼び出す事で、pyproject.toml を変更するだけでドキュメントを変更できるようになる。

このことによって、バージョン番号を上げる時など、pyproject.toml の一箇所を変更するだけで、パッケージのバージョン番号・ドキュメントのバージョン番号の両方を一度に変更でき・・・るように思ってしまう。

しかしそう上手く問屋は卸さない。

poetry は[基本的な必須情報](https://cocoatomo.github.io/poetry-ja/pyproject/)（name, version, description, authors）を pyproject.toml の `[tool.poetry]` セクションに設定してしまう。これがないと poetry が動かない。

これに対し sphinx-pyproject は、PEP に定義されているように、基本的な必須情報は `[project]` セクションに設定されているものとして読み込む。
（もちろん sphinx-pyproject に poetry の事情を汲み取る義理は無い）

この問題は poetry 側の問題であり、これを解決するよう　[issue](https://github.com/python-poetry/poetry/issues/3332) も作られている。
しかしこの issue の議論を見る限り、この問題が解決される気配は無い。
（とても残念）

pyproject.toml に `[project]` と `[tool.poetry]` の両方を設定することが最も早い解決法だが、同じファイルであっても２箇所に同じ設定があるのは、やはりとても気持ちが悪い。

そこで sphinx-pyproject 側を修正し、無理やり `[project]` ではなく `[tool.poetry]` を読み込むようにしたい。

また sphinx-pyproject では、authors および maintainers の項目は table として設定することを前提としている。

```
[[project.authors]]
name = "1st Author"

[[project.authors]]
name = "2nd Author"
```

しかし poetry では `1st author <1st.author@domain>` の形の配列で指定する。

```
[tool.poetry]
authors = ["1st Author <1st.author@domain>", "2nd Author <2nd.author@domain>"]
```

この問題についても sphinx-pyproject-poetry では poetry の形式を前提として、
authors および maintainers の項目を読み取るようにしたい。

# 作ったよ

https://github.com/tetutaro/sphinx_pyproject_poetry

# 使い方

使い方は sphinx-pyproject と全く同じ。

```
# conf.py

import os
import sys

from sphinx_pyproject_poetry import SphinxConfig

sys.path.insert(0, os.path.abspath(".."))
config = SphinxConfig("../pyproject.toml", globalns=globals())
project = config.name
release = config.version
```
これだけ。

Sphinx の conf.py を上記のように修正し、pyproject.toml の `[tool.pyproject]` に項目を書くだけで、conf.py を変更しなくても良くなる。

name, version, description, authors, maintainers の５つの項目は　`[tool.poetry]` から読み込む。そして authors と maintainers の２つの項目は併せて author という名前で保持される。

conf.py で設定できる項目は、[www.sphinx-doc.org](https://www.sphinx-doc.org/ja/master/usage/configuration.html)　に全部載っている。そして項目を追加する場合でも修正する場合でも、pyproject.toml に設定を追加したり変更するだけである。

便利！！（自画自賛）
前任者から引き継いだ業務量を1週間で半分以下にした話

# サマリ

プロジェクトを移動した際に前任者から引き継いだ仕事を半分にしました。
前任者が早出と残業で最大10時間かかっていた定型業務を4時間くらいに短縮しました。
自動化したり、ツールの使い方を工夫するだけですが、非エンジニアからすると意外と知らないものが多いようので備忘録がわりに記載しておきます。

# 一覧

| No | ASIS | TOBE |
|:-:|:-|:-|
| 1  | Excelの記載内容からJiraチケット等を作成。  | [Jira API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-events-get)を使用する。APIを使用できないタスクの場合は[Power Automate](https://powerautomate.microsoft.com/ja-jp/templates/)を使用する。  |
| 2  | メールが煩雑  | [outlook](https://support.microsoft.com/ja-jp/office/outlook-%E3%81%A7%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B-75ab719a-2ce8-49a7-a214-6d62b67cbd41)や[gmail](https://support.google.com/mail/answer/6579?hl=ja)の仕分けルールを使用する。その際CCで送られてくるFYI系は全て通知をOFFにしておく。  |
| 3  | 会議の設定が大変  | [outlook](https://support.microsoft.com/ja-jp/office/%E4%BA%88%E5%AE%9A%E8%A1%A8%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%82%92%E4%BD%9C%E6%88%90-%E8%A1%A8%E7%A4%BA-%E3%81%BE%E3%81%9F%E3%81%AF%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B-04fc64f2-b658-450b-8dce-dd27ed660570)や[gmail](https://support.google.com/a/answer/1626902?hl=ja)のグループスケジュールを使用する。  |
| 4  | Jiraチケットの確認が大変  | Jiraチケットにタグをつけるか、サマリのルールをつけておき、[JQL](atlassian.com/ja/software/jira/guides/expand-jira/jql) でフィルタリングしておく。 |
| 5  | 権限の関係で、毎日一方のフォルダから一方のフォルダへ手動でコピーしないといけない  | 大抵のクラウドストレージには自動コピー機能があるためそれを使用する。sharepointなどサポートされていないものは[Power Automate](https://powerautomate.microsoft.com/ja-JP/templates/details/c246fffdb0aa4578b8838f96950944f6/sharepoint-online-%E3%81%AE%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%BE%E3%81%9F%E3%81%AF%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC%E9%96%93%E3%81%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%B3%E3%83%94%E3%83%BC%E3%81%99%E3%82%8B/)などのRPAツールの利用を検討する。  |
| 6 |シーケンス図やフロー図を作成するのが大変 | VSCodeを使用しているのであれば、[mermaid](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)や[plantUML](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)を使用する。 |
| 7 | エクセルの集計作業やレポート業務に時間が取られている | [VBA](https://learn.microsoft.com/ja-jp/office/vba/library-reference/concepts/getting-started-with-vba-in-office)で処理する。 |
| 8 | 朝一に色々アプリの立ち上げをしないといけなくて大変。| Windowsであれば[スタートアップ](https://support.microsoft.com/ja-jp/windows/windows-10-%E3%81%AE%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AB%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B-150da165-dcd9-7230-517b-cf3c295d89dd)に設定しておく |

# 終わり

エンジニアやそのツールを普段から使用している人からするとこれだけ？という印象をされる人も多いと思いますが、今回非エンジニア部門に参画した際に、「これだけ」をしていない人に多く出会いました。
聞いてみると、現在使用しているツールで上記のことができるとは思わなかったという人が多いようでした。
非エンジニア部門の方と仕事をする機会があれば聞いてみても良いかもしれません。

# 備考

1. 基本的にそれぞれのツールの便利な使い方は、そのツールのチュートリアルを見れば書いてあることがほとんどです。一度目を通しておくことをお勧めします。
1. Power Automateなどの広範囲をカバーするRPAツールを使用する際はなんでもそれで解決しようとしないようにしてください。例えばExcelの内部で閉じた処理はVBAで行う方がやれることは多いですし処理も早いです。Power Automateを使用する場合はツール間の連携など、それぞれに特化した処理を横断的に処理する方が良いです。
1. なんでもかんでも自動化・ツール化すると、その仕組みを作った人がいなくなった後に誰もメンテナンスせず、その人の退職に合わせて廃れることがほとんどです。KTやメンテナンス用のドキュメントは細かく残しておくことをお勧めします。
[emacs]init.elにcustom.elが読み込まれないときの対応

# emacsをアップデートするといつもハマるcustom.elの読み込み方法

そして、いつも参考にさせてた抱いているサイト
[vinelinux[設定ファイル]](https://vinelinux.org/docs/vine6/emacs-guide/emacs-customize-saving-customizations.html "設定ファイル")

``` init.el
(setq custom-file "~/.emacs.d/custom.el")
(if (file-exists-p (expand-file-name custom-file))
    (load-file (expand-file-name custom-file)))
       
```
input().rstrip().split()でスペースで区切られた入力文字列をリストにして返す


input().rstrip().split()についてメモ。
バージョンはPython3.10.6で、引用は公式ドキュメントから。

コード
```python
input = input().rstrip().split()
print(input)
```

入力
```
hoge1 hoge2 hoge3
```
出力
```
['hoge1', 'hoge2', 'hoge3']
```

# str.rstrip()
rstripは入力文字列の末尾を削除する。ここでは、末尾に意図しない空文字や改行文字が入ってしまった場合にそれを削除するために使用している。
>文字列の末尾部分を除去したコピーを返します。引数 chars は除去される文字集合を指定する文字列です。 chars が省略されるか None の場合、空白文字が除去されます。 

# str.split()
split()は引数をデリミタ文字列として区切った文字列のリストを返す。引数を指定しない場合は空文字で区切られる。デリミタとは、カンマや空白など要素の区切りを表す文字のことを指す。ここでは引数を指定していないので、入力文字列をスペースで区切ったリストが返される。
>文字列を sep をデリミタ文字列として区切った単語のリストを返します。

# 自分がした勘違い
最初このコードを見たとき、inputというクラスがあるのだと勘違いしてそのメソッドとしてrstrip()を探す、みたいな勘違いをしていた。そうではなくて、組込関数input()の戻り値としてstrが返され、そのstrのメソッドとしてrstrip()やsplit()があるようだ。そろそろなんとなく使っていたクラスやメソッドについてもしっかり勉強しなければ。
2022年に読んだ本まとめ

こんにちは。masangoです。

今年ももう終わりですね。
年末にふさわしく、今年1年で読んだ本を短い感想と共にまとめていきます。

※購入順で技術書・ビジネス書をメインに、それ以外 & 積み本は番外編として後半に綴ります。

# 技術書・ビジネス書

## [アドテクノロジーの教科書 デジタルマーケティング実践指南](https://amzn.asia/d/6UiRdvF)

今年の4月に広告系の会社に転職するにあたって、業界知識などを得るために転職先の先輩におすすめされて購入しました。
出版自体はかなり前ですが、アドテクの基本が詰まっていて、私のようにアドテクにこれから入る方には良いと思います。

## [SCRUM BOOT CAMP THE BOOK](https://amzn.asia/d/1TgJ2UD)

こちらは[ITエンジニア本大賞2021](https://www.shoeisha.co.jp/campaign/award/2021/result/)で紹介されており、スクラムの基本を振り返るために購入しました。
物語ベースなので堅っ苦しくなく、実際の開発現場でも起こりうる問題を物語の起承転結にあてており読みやすいです。
これからスクラム開発の現場に飛び込む方などにおすすめです。

## [アイデアのつくり方](https://amzn.asia/d/i2pyW0M)

朝会で会社の同僚におすすめされて購入しました。
アイデアがどういった時に生み出されるかをロジカルに分析した内容などが書いてあります。
文量は少ないため、サクッと読めます。

## [マスタリングTCP/IP　入門編（第6版）](https://amzn.asia/d/7nuha6k)

こちらも[ITエンジニア本大賞2021](https://www.shoeisha.co.jp/campaign/award/2021/result/)で紹介されており、ネットワーク系としてはかなり有名どころですね。
網羅本チックなこともあり、ネットワークエンジニアでもないと中々業務に役立つ知識は得られないかもしれませんが、振り返ると個人的には後に学んだAWSのVPCやネットワークインターフェース周りが理解しやすくなったような気がしています。

## [サイコロジー・オブ・マネー――一生お金に困らない「富」のマインドセット](https://amzn.asia/d/3bCM2H6)

今、日本でも徐々に投資をしている人が増えていますが、過去投資で成功・失敗した人の事例からお金に関する考え方を紹介しています。
他にも似たような内容を書いた本はたくさんあると思うので、まだ投資に関する本を読んだことがない方はぜひ。
（余談ですが、今年の米国株は辛かったですね・・・働いても浮いたお金が全て持っていかれるレベルだったので本当に辛かった・・・）

## [改訂版　日本統計学会公式認定　統計検定２級対応　統計学基礎](https://amzn.asia/d/eZAVJzh)

広告の効果測定でデータと睨めっこすることもあり、統計の知識必要かなぁと思ってたところ、統計検定の存在を知ったため購入。
~~(筆者は情報系大卒ではありますが授業なんてろくに聞いてなかったので)~~ この本だけだと難易度が少し高かったため、[統計WEB](https://bellcurve.jp/statistics/course/)様も一緒に使わせて頂きました。
基礎的なところは業務にも活きそうでしたが、検定・回帰分析あたりは機械学習周りでないと実際には使わないかもなーなんて思いながら一通りは学習しました。
~~（試験も受けましたが59点(1点足らず)で落ちたのはここだけの話）~~

## [OpenCVではじめよう ディープラーニングによる画像認識](https://amzn.asia/d/i6JSDYW)

某麻雀ゲームのゲーム画面から牌検出をしたいがために購入。
画像処理周りは全くの初心者だったのでハンズオン形式で触ってるだけでも結構面白かったです。
結局キャプチャの処理ぐらいでしか使わず、牌の検出と判定の処理は[Roboflow](https://roboflow.com/)を活用することにはなりましたが、今後何かに活きると良いなぁという気持ち。

## 

# 番外編

## [Scalaスケーラブルプログラミング 第4版 impress top gearシリーズ](https://amzn.asia/d/hefubFC)

こちらはScalaでの開発が必要になったタイミングで購入しました。
結局、辞書的に時折見る使い方になってしまったため全てに目を通せてはいないので、そのうち読破しておきたいですね。。

## [やはり俺の青春ラブコメはまちがっている。](https://amzn.asia/d/eHRFAco)

今年は久々にラノベを読んだのでせっかくなので。
アニメは全て見ていましたが、原作を読んでみようと思い購入。年末までに最終巻まで読み切れました。
セリフに出さずに読者に心情を読ませるタイプの作品は良いですねーマジで面白かった。
（おすすめのラノベあればコメント欄でぜひ教えてください！）

## セール等で買うだけ買って全く手をつけていない本

- [freeeの事例に学ぶ、新規プロダクト開発の進め方](https://amzn.asia/d/2WCEmMh)
- [Clean Architecture](https://amzn.asia/d/8pa1ggh)
- [Engineers in VOYAGE ― 事業をエンジニアリングする技術者たち](https://amzn.asia/d/3Y6XYVJ)
- [Fluentd実践入門](https://amzn.asia/d/8moG5PN)
    - 2割ぐらいは読みましたが、ライブラリのDocs的なフェーズに入ったところで、今読んでも覚えてられないなと思って中断...
- [問題解決力を鍛える！アルゴリズムとデータ構造](https://amzn.asia/d/4MRV6eC)


# 最後に

個人的に、今年は読書量が少なめだった気がします。
最近はわざわざ本を買わなくても、ネットの情報だけで解決できたりもするので便利ですが、瞬間的には不要でも周辺情報まで目に入れられるという点で、本はやはり優秀だなと思うので、量にはこだわらないですが定期的に本は読んでいきたいですね。

それでは皆さん良いお年を。
OIDC ubuntsu

ubuntu

```
sudo apt install libapache2-mod-auth-openidc

OIDC無

composer create-project --prefer-dist laravel/laravel Laravelauth
cd Laravelauth
composer require laravel/jetstream
php artisan jetstream:install livewire
composer require "laravelcollective/html"
npm install && npm run dev
php artisan migrate

```

OIDC有

```bash
composer create-project --prefer-dist laravel/laravel Laraveloidc
cd Laraveloidc
composer require laravel/jetstream
php artisan jetstream:install livewire
composer require authlete/authlete-laravel
php artisan authlete:authorization-server
composer require "laravelcollective/html"
npm install && npm run dev

```

django編
OIDC無
```
django-admin startproject myboard
cd myboard
python3 manage.py migrate

```

OIDC有

```
django-admin startproject myoidc
cd myoidc
vi authlete.ini

--------------------
[authlete]
base_url           = https://api.authlete.com
service.api_key    = YOUR_SERVICE_API_KEY
service.api_secret = YOUR_SERVICE_API_SECRET
--------------------
python3 manage.py migrate
python3 manage.py runserver 

```
未経験から転職して半年が経とうとしてますが、以下が通読してる書籍一覧になります。

JavaSE11 Silver
JavaSE11 Gold
Java入門実践編
サーブレット＆JSP入門
Eclipseパーフェクトガイド
新しいLinuxの教科書
Spring徹底入門
JUnit実践入門
良いコード/悪いコードで学ぶ設計入門
Silver DBA
シェル芸（Bash）でAtCoderの問題を解こう！

# はじめに

シェル芸（Bash）を用いて競技プログラミングサイト「AtCoder」の問題を解きましょう。

# AtCoderのアカウント作成

まずはAtCoderのアカウントを作成します。

下記のリンクから、AtCoderのウェブサイトにアクセスしてください。

https://atcoder.jp/

右上の「新規登録」をクリックしてアカウントを作成してください。

![スクリーンショット (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/70ac98ab-104a-48b8-d08e-aa7b1897caa7.png)

# AtCoderの問題の解き方

アカウントを作成したら、さっそく問題を解いてみましょう。

## 問題文

下記のリンクから、AtCoder Beginner Contest 002 のB問題「罠」を開いてください。

https://atcoder.jp/contests/abc002/tasks/abc002_2

以下の画像のような問題ページが表示されます。

![スクリーンショット (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/2ac12d9a-408d-2102-2c68-467e56dbfefe.png)

問題文を読み、問題を理解してください。

すると、文字列```W```が入力として与えられるので、そこから母音を削除したものを出力すればよいのだと分かります。

## 入出力の形式

問題文の下に入力と出力についての記述があります。

入力は標準入力から与えられ、回答は標準出力から行います。

![スクリーンショット (25).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/f189dee8-8c49-6e52-96f5-35db5e18cdc0.png)

## 入出力の例

入出力の記述の下には、以下の画像のような入出力の例の記述があります。回答する際の参考にしてください。

![スクリーンショット (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/02f730b9-3f6d-3e86-e4a9-9259f7316051.png)

## コードテスト

それでは実際にシェル芸を書いていきましょう。

問題ページの上部のタブに「コードテスト」があるので、そちらをクリックしてください。

すると、以下の画像のようなコードテストページが表示されます。

![スクリーンショット (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/327c953c-8e9c-f11f-814a-c6e47234f181.png)

言語は```Bash```を選択してください。

そして、ソースコードに問題を解くためのシェル芸を記述します。

シェル芸例

```bash
tr -d aiueo
```

さらに、標準入力に、問題ページにあった入力例をコピペします。

そして最後に、「実行」ボタンを押すと、結果が出力されます。

出力が正しいことを確認してください。

## シェル芸の提出

自分が書いたシェル芸を提出してみましょう。

コードテストで記述したシェル芸をクリップボードにコピーしてください。

その後に、ページ上部のタブにある「提出」をクリックします。

![スクリーンショット (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/6a16dd4b-6575-6ae1-eece-36668394c310.png)

提出ページで、問題は```B - 罠```を指定してください。

また、言語は```Bash```を指定してください。

そして、先ほどコピーしたシェル芸をソースコードに貼り付けてください。

最後に「提出」ボタンを押してください。

## 結果発表

「提出」ボタンを押すと、ページが自動的に遷移します。

自分の提出において、結果が```AC```となっていれば正解です。

```WA```や```TLE```など、```AC```以外が表示されていると不正解です。

![スクリーンショット (29).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/1065c9b4-40f7-34ef-e0e8-19ffa8dd8062.png)

# 問題の探し方

以上でAtCoderの問題の解き方は終わりです。

最後に、AtCoderの問題の探し方をお伝えしておきます。

以下のリンクから「AtCoder Problems」というウェブサイトにアクセスできます。

https://kenkoooo.com/atcoder/#/table/

こちらのウェブサイトからAtCoderの問題に簡単にアクセスできます。

また、他にも様々な情報を知ることもできます。

ぜひいろいろ試してみてくださいませ。

![スクリーンショット (30).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/cdddf95f-d89f-1631-8fc2-f5bb0f17fe21.png)

# おわりに

シェル芸とAtCoderとAtCoder Problemsに感謝を。

ありがとうございます。

楽しいです。

# ブログの移転

新しくブログを始めました。AtCoder関連の記事もあります。

https://yusukekato.jp/20230420.html
[WordPress]CSSカスタマイズの罠　管理メニューが崩れる

# WordPressのカスタマイズをしていて、管理メニューが崩れる問題でハマった。
原因を特定するのに時間がかかったが、最終的にCSSの最適化設定を行っていたことを思い出して無効化したら解決した。

![customize_css.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084136/dd44b978-1287-07f3-b4e2-c35e5ad54dce.jpeg)
今日のwget エラー

macOSでwget

```macOS:bash
$ wget https://www.autosar.org/fileadmin/standards/classic/22-11/
--2022-12-30 13:21:10--  https://www.autosar.org/fileadmin/standards/classic/22-11/
www.autosar.org (www.autosar.org) をDNSに問いあわせています... 195.234.139.22
www.autosar.org (www.autosar.org)|195.234.139.22|:443 に接続しています... 接続しました。
エラー: www.autosar.org の証明書(発行者: `CN=Starfield Secure Certificate Authority - G2,OU=http://certs.starfieldtech.com/repository/,O=Starfield Technologies\\, Inc.,L=Scottsdale,ST=Arizona,C=US')の検証に失敗しました:
  発行者の権限を検証できませんでした。
www.autosar.org に安全の確認をしないで接続するには、`--no-check-certificate' を使ってください。
$ wget https://www.autosar.org/fileadmin/standards/classic/22-11/ --no-check-certificate
--2022-12-30 13:21:42--  https://www.autosar.org/fileadmin/standards/classic/22-11/
www.autosar.org (www.autosar.org) をDNSに問いあわせています... 195.234.139.22
www.autosar.org (www.autosar.org)|195.234.139.22|:443 に接続しています... 接続しました。
警告: www.autosar.org の証明書(発行者: `CN=Starfield Secure Certificate Authority - G2,OU=http://certs.starfieldtech.com/repository/,O=Starfield Technologies\\, Inc.,L=Scottsdale,ST=Arizona,C=US')の検証に失敗しました:
  発行者の権限を検証できませんでした。
HTTP による接続要求を送信しました、応答を待っています... 500 Internal Server Error
2022-12-30 13:21:44 エラー 500: Internal Server Error。

$ 
```
ABテストについて

## はじめに
業務では使用しなかったため内容は理解していないが、頻繁に目にする単語なので基礎知識を調査。
調べたので備忘録として公開。

## 具体的な内容
### ABテストとは
A/Bテストとは、バナーや広告文、Webサイトなどを最適化するために実施するテストの一つ。
特定の要素を変更したAパターン、Bパターンを作成し、ランダムにユーザーに表示し、それぞれの成果を比較することで、より高い成果を得られるパターンを見つけること。

### メリット
両パターンが同時並行で試せるので、どちらが良いかが正しく評価できる点。
条件が統一されていて変更点の評価しやすい。

### ポイント
1. 何を改善するためのテストか目的を明確にする。
2. 仮設を立てる
3. 影響範囲の予測
4. テスト後に要因の分析と次の施策を考える

### 使用場面
Webページ、広告バナー、広告文など

### 有名な事例
オバマのWebサイトでの成功事例
下記記事が参考になりそう。多変量テストの事例紹介。
https://juicer.cc/articles/archives/1273/


### ABテストのパターン
- 同一URLのABテスト
  - 見た目を変更する。
  - javascriptを利用してソースコードを書き換える

- 別ページへリダイレクトさせるABテスト
  - 一般的にはスプリットurlテストと呼ぶ
  - Googleオプティマイズの機能になっているらしい

- 多変量テスト
  - 同ページ内、又はページを跨いで様々な箇所のテストを同時に行う
  - 同時に行うテスト内容の組み合わせの中で、どれが最適であるか見つけることができる点がメリット

### ABテストの必要性
- サイト改善の成果を分析してさらなる改善に繋げられるため重要。Webサイトの課題に対してPDCAをしっかり回すことができる。
- また、広告に比べお金をかけずにCV数を継続して増やしやすい手法であるため。
- リニューアルのリスクを回避することができる

## 参考元
https://www.innovation.co.jp/urumo/split_testing/
https://www.assion.co.jp/blog/guide-of-abtesting/
データベーススペシャリスト試験 合格体験記

今秋のデータスペシャリスト試験に合格したので、勉強方法を共有しようと思います。

# 筆者について
データベーススペシャリスト試験は初受験
2年前に応用情報技術者試験に合格
半年ほどデータエンジニアとして従事

# 受検動機
応用情報技術者試験の合格で午前1試験が免除となるのですが、その免除期間が切れてしまうため。(2年で失効)
最近データ系の業務に従事することとなったので、軽い気持ちでとっておいてもいいかなと思ったため。

# 学習期間
3ヶ月(ずっとゆるくやっていた)

# 試験対策
[こちら](https://www.amazon.co.jp/dp/4798174904/ref=as_sl_pc_as_ss_li_til?tag=asuyuh-22&linkCode=w00&linkId=a0be267421ef30416d067af7227f88c7&creativeASIN=4798174904)の参考書を購入して、まず1周通して読みました。
ところどころ読みづらい箇所や退屈な箇所がありますが、そういった部分は読み飛ばしていました。(業務説明の章など結局最後まで読まなかった箇所もあるくらいです)
一方で、試験対策ページ(序章)やSQL・正規化(1,3章)の章を継続的・重点的に読み込みました。

## 午前2
[過去問道場](https://www.db-siken.com/dbkakomon.php)に記載の過去問をひたすら演習しました。短期集中で取り組むというよりは、少しずつでも良いから継続的にこなしていくことを心がけました。最終的に過去問題の9割以上に着手し、9割以上の正答率を目指しました。

## 午後1
[こちら](https://www.amazon.co.jp/dp/4798174904/ref=as_sl_pc_as_ss_li_til?tag=asuyuh-22&linkCode=w00&linkId=a0be267421ef30416d067af7227f88c7&creativeASIN=4798174904)の参考書の序章には優先して解くべき問題が記載されていますので、これを優先的に演習していきました。(結局他の問題は手を付けませんでしたが...)
実際に試験を受けてみて、ここに記載している問題はマストで取り組むべきと感じました。時間が足りない場合は解答を読み込むだけでも効果的だと思います。

午後1の試験は「関係スキーマ」や「正規化」などのいくつかのトピックの知識をベースとして、ある種のパターンに則った解放に沿って解答していくことが重要だと感じました。覚えるべきものは覚え、理解すべきものは理解することが重要と考えます。


## 午後2
こちらも参考書の序章に優先度別に重要問題が記載されていますので、それに従って演習を進めていきました。
午後2には例年2つのトピック「概念データモデル・関係スキーマの完成」と「物理設計」が出題され、どちらか一方を選択して解答する必要があります。
私は前者を選択することを決めていたので、物理設計の問題には着手しませんでした。(とはいえ午後1には物理設計も出題されるので解いておいて損はないと思います)

午後2の試験の特性上、知識というよりは解法を身体に染み込ませることが重要と考えます。特に、「概念データモデル・関係スキーマの完成」の分野では、だいぶ例年の傾向が確立されています。最初は解答を見ながら正しい解法を丁寧に追体験し、慣れさせることが肝心です。

## 試験対策のTips
試験対策や実際の試験を受検して感じたことをTipsとしてまとめていました。

【試験区分別の優先度】
問題量の多い午後試験に慣れるために、午後試験に割く時間を多めにとりました。
午後2 > 午後1 > 午前2

【午後試験への向き合い方】
午後1の演習を少しやっていく中で、「なるほどデータベーススペシャリスト試験とはこういうものか」と少しわかってきたら午後2の演習に進むと良いのかなと感じました。

午後試験は過去問演習を徹底して行うのが合格の肝ですが、試験問題はなかなかヘビーなので最初はなかなか気が乗りません。とはいえ過去問演習は合格のためには避けては通れないので、うまいことこなす必要があります。
最初は大問ごとに30~60分単位で細切れにして演習していくでもOKです。もっといえば右も左も分からない段階であれば、解答を見ながら演習しても構わないと思っています。慣れてきたら午後1であれば90分、午後2であれば120分を戦い抜く持久力を付ける練習をしていけばよいです。

【試験本番にて】
試験本番では解答用紙が配布されてからその後に問題が配布されると思います。
特に概念スキーマの問題を解くにあたっては、解答用紙に記載された図で事前に問題のイメージを膨らませておくことができます。

# 結果
無事合格しました。
午前1: 免除
午前2: 96%
午後1: 89%
午後2: 63%

終始ダラダラ学習していたため、午後2では危ない橋を渡りました。みなさまは午後2試験の対策に余念なく臨まれることを強くオススメいたします。
以上となります。
Linux VMで開発の際のaliasやブランチ設定の追加を自動化してみた

最近VMで開発することが多くなっているのだが、その際のエイリアスなど毎回同じものを追加しているので自動化してみた。

以下のことをしたい

- gitコマンドのエイリアス追加
- ブランチ表示

そして上記のコマンドがすでにファイルに記載されていたら再度追加するのを防いでおきたい。
それは `grep -qxF "${stmt}" filename` でできるらしい（以下参照）。

https://stackoverflow.com/questions/3557037/appending-a-line-to-a-file-only-if-it-does-not-already-exist

シェルスクリプトは以下

```alias.sh
#! /bin/sh

# useful aliases when development in VM

HOMEDIR="/home/vagrant"

touch $HOMEDIR/.bash_aliases

stmt='alias gst="git status"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gp="git push"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gcmsg="git commit -S -m"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gup="git pull"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias ga="git add"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gco="git checkout"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gcb="git checkout -b"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gm="git merge"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases
stmt='alias gcm="git checkout main"'
grep -qxF "${stmt}" $HOMEDIR/.bash_aliases || echo "${stmt}" >> $HOMEDIR/.bash_aliases

stmt="
if [ -f $HOMEDIR/.bash_aliases ]; then
    $HOMEDIR/.bash_aliases
fi"

grep -qxF "${stmt}" $HOMEDIR/.bashrc || echo "${stmt}" >> $HOMEDIR/.bashrc

stmt="
git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}"

grep -qxF "${stmt}" $HOMEDIR/.bashrc || echo "${stmt}" >> $HOMEDIR/.bashrc

stmt='export PS1="\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \$(git_branch)\$ "'
grep -qxF "${stmt}" $HOMEDIR/.bashrc || echo "${stmt}" >> $HOMEDIR/.bashrc



```

VagrantでVMを立ち上げているので、このシェルスクリプトを走らせるように追加しておく。

```Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
    config.vm.define "vm-build" do |v|
    end
  
    config.vm.box = "bento/ubuntu-18.04"
  
    config.vm.synced_folder "./", "/home/vagrant/myfolder"
  
    config.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get install -y nasm make xorriso binutils gcc automake g++
      sudo ./alias.sh
    SHELL
  end
```

これで`vagrant up`でgit周辺のコマンドも追加できる！
相対パスが使えなかったので`/home/vagrant`を指定しないといけないのはめんどうだが

あとはssh, gpg鍵の自動化もできたらいいのだが、、、
[python] dicのgetメソッドで値取得のエラーを防ぐ

# 環境
Python 3.9.13
# Code
```python
a = {"aa": True}

a["aa"]
# True

a["cc"]
# Error

a.get('cc')
# None

a.get('cc', "no exist")
# no exist

print(a)
# {'aa': True}
# 元のdicは変更されない
```

# 実用例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/9cfe272f-d701-bc47-2be9-31cd316b0b3b.png)

検索した直後のurl
`https://qiita.com/search?q=aa`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/8a754cf5-8d9e-3f04-ed6d-557f6f20f43c.png)

関連順をもう一回クリックしたら次のようになった。
`https://qiita.com/search?q=aa&sort=rel` 

Qiitaの検索ページを見たとき、デフォルト設定が`関連順`になっている。
しかし`url`には`sort=rel`がない。 
→ `sort=` の値がない時にデフォルトで`sort=rel`と読み取る

# Djangoでurlからパラメータを読み取ってsortする場合を想定
## getメソッドを使わない方法
```python
try:
    sort = request.GET["sort"]
except Exception as e:
    sort = 'rel'
```

## getメソッドを使った方法
```python
sort = request.GET.get('sort', 'rel')
```

このように１行で変数を作ることができるので、エラー対策として必須で使用している

# 関連
https://www.w3schools.com/python/ref_dictionary_get.asp
AWS Pricing CalculatorのCSV出力文字化け問題を回避する

AWS Pricing Calculator
https://calculator.aws/

を使ってるとCSV出力で文字が化けることがある。説明文をたくさん入れるなどしているとどこかでおかしくなる。単にUTF8のBOMの問題ではなく、バックスペースなどの制御コードまで入ってるから日本語以前にファイルが壊れる。発生条件はいまいち分かってないけど、フロントエンドでCSVを作成しているところでおかしくなってると推測。

じゃぁってことで画面上をJSでスクレイピングして、そのままタブ区切りテキストトとして出力する。

### 回避策のJS

以下がソース。このソースをdeveloper.toolsのconsoleに貼り付けて実行すると、タブ区切りテキストがconsoleに出力されるので、これをまたエクセルにコピペする。

```sample.js
let lines = [];
$$('[role=table] tr').forEach((row)=>{ 
    let cols = [];
    row.querySelectorAll('th,td').forEach((td)=>{
        cols.push(td.innerText);
    })
    lines.push(cols.join("\t"));
})
console.log(lines.join("\n"));
```

上記のソースをconsoleにコピペして実行すると、タブ区切りで出力される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/1830d459-c122-7b67-4f04-4a7e790f931d.png)

それをエクセルにコピペ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/d4a43cb0-fc91-abd0-12f9-a2703e00aebe.png)

### ソースの解説

やってることは、テーブルタグのtrを行、thもしくはtdをカラムとしてタブ区切り文字列を作ってるだけ。

一番左に空白セルがるはチェックボックスの欄がそのまま引っ張ってきてる。
チェックBOXのセルを取り除くことをしてもいいけど、ソースが分かりにくくなるのでこの例では超シンプルな「テーブルをタブ区切りにするサンプル」として認識してほしい。

理想を言えば、JSのBlobを使ってファイルとして保存できればいいんだろうけど、どうもそのロジックでPricing Calculatorがバグっているっぽいので、あえてそこでは追いかけない。
【Python】各ディレクトリからファイル名に特定の文字列をもつファイルパスを全件取得する

# ■はじめに
・特定の拡張子をもつファイルパスを全て取得したい
・ファイル名に指定した文字列を含むファイルパスを全て取得したい
・ディレクトリの階層にかかわらず、指定した特徴を持つファイルパスを全取得したい

以上、3つの要望を満たす処理を
普段の業務効率化ツールの実装でよく使うので、
同様の処理にお困りの方へ、ご参考いただければと思います。


# ■お急ぎの方へ、一先ず全文公開
```python
import os
import glob
from tkinter.filedialog import askdirectory

def GetFilePath():
    dirBase = askdirectory(title='CSVファイルをまとめた親フォルダを選択してください。')
    dirpath = dirBase + '\\*'
    pathList = glob.glob(dirpath)
    
    #取得したCSVファイルを格納するためのリスト
    fpathList = []

    #選択したディレクトリ以下のディレクトリでCSVファイルを全て取得する。
    for p in pathList:
        if os.path.isdir(p):
            plist = glob.glob(p+'\\*')
            pathList.extend(plist)
        elif p[-3:] == 'csv':
            fpathList.append(p)
        else:
            pass
    return fpathList

```

# ■処理の流れ
ポイントだけピックアップして説明します。

1.tkinterのaskdirectoryを用いて、
任意のフォルダを選択できるフォルダ選択ダイアログを開きます。
```python
from tkinter.filedialog import askdirectory
dirBase = askdirectory(title='CSVファイルをまとめた親フォルダを選択してください。')
```
2.1で選択したディレクトリパスの1階層下にあるファイルやディレクトリのパスをglobで取得。pathListは、ファイルやディレクトリの絶対パスを含むlist型の変数です。
```python
import glob
dirpath = dirBase + '\\*'
pathList = glob.glob(dirpath)
```
3.後の処理で"狙った"ファイルパスを追加するためのリストを用意。
```python
#指定した条件にマッチしたファイルを格納するためのリスト
fpathList = []
```

4.2で取得したpathListのパスをfor文で1つ1つ見ていきます。
ここの処理では、ディレクトリパスを避けつつ、どんなファイルを取得したいかを指定します。

```python
import os
for p in pathList:
        if os.path.isdir(p):
            plist = glob.glob(p+'\\*')
            pathList.extend(plist)
        elif p[-3:] == 'csv':
            fpathList.append(p)
        else:
            pass
```
【if~】
①最初に、取得したパス(p)が、ディレクトリかどうか判断。
②ディレクトリパスの場合、更に1階層下に存在するパスをリスト(plist)にして、pathListに結合。
▶②により、ディレクトリパスが出てきても、最初のfor文でその配下の全パスを読み込むことができます。

【elif~】
ここの処理に入ってくるパスは全てファイルパス。
条件式では、取得したいファイルが持つ文字列の特徴を指定してください*。
*例文では、拡張子が「csv」であるパスを指定しています。

【else~】
ここに入ってくるは、ディレクトリパスでもなく、
上記の条件に当てはまらないファイルパス。
使わないパスは、passしましょう。

```python
return fpathList
```
以上の処理を通して、
指定した特徴を持つファイルパスのみが、fpathListに入ってくるので、最後にreturn。


# ■まとめ
Pythonで「**各ディレクトリからファイル名に特定の文字列をもつファイルパスを全て取得する**」ための処理の紹介でした。
もし、もっとスマートなロジックがございましたら、是非ともフィードバックお願い申し上げます。
以上です！
symfony5.4のコマンドまとめ

### 前提
Symfony 5.4

```console
# ローカルサーバスタート
symfony server:start

# db作成
php bin/console doctrine:database:create;

# Entityクラス作成
symfony console make:entity XxxxXxxxx

# マイグレーションファイル作成
symfony console make:migration

# マイグレーションファイルからdb定義変更
symfony console doctrine:migrations:migrate

# マイグレーションファイルのどこまでやっているかを見れる
php bin/console doctrine:migrations:status

# コントローラ作成
symfony console make:controller XxxXxxxController
```
今日のdocker エラー

docker update, upgradeがエラーでできなかった。　

ハードディスクの空きを40Gbにした。


```macOS:bash
$ docker run -it ubuntu /bin/bash
```

でもやっぱりだめだった。


```docker:bash
# apt update
Unable to locate an executable at "/Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/bin/apt" (-1)
```
JS使いがGather APIを利用して更に楽しむために行ったこと3選

- リモートコミュニケーションツールとして[Gather](https://gather.town/)を利用しています。
- Gatherは基本機能以外の仕掛けが沢山あり、その中の1つが[ブラウザコンソール等で扱えるAPI](http://gather-game-client-docs.s3-website-us-west-2.amazonaws.com/classes/Game.html)の存在です。
- 「現在位置の取得」や「参加者情報の取得」など豊富に存在しており、それらを適切に組み合わせることで色々な操作を行うことが可能です。
- 今回はその中から**大人数で盛り上がりそうな組み合わせ3選**をご紹介いたします。

## 前提
- 以下の機能の利用は[一定の権限(Admin or Builder)](https://support.gather.town/help/user-roles)が必要です。
- 必要な方は管理者に権限を設定していただいてください。

## 1. 一括ダンス
- **全員で全身で喜びを表現したい時に利用できます。**
- 以下の内容をChromeコンソール画面に入力して実行するだけで、**参加者全員に一括でダンスしてもらうことができます**。

```js
game.playerUidsSeenOnConnect.forEach(p => game.move(4,true,p))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/f619afb9-b17c-9479-3b72-83fa545d645f.png)

## 2. 一括リアクション
- **報告や発表の際に全員で同じリアクションをしたい時に利用できます。**
- 以下の内容をChromeコンソール画面に入力して実行するだけで、**参加者全員にリアクションしてもらうことができます。**

```js
game.playerUidsSeenOnConnect.forEach(async p => {
    game.setEmote("🎉",p);
    await new Promise(r => setTimeout(r,3000));
    game.setEmote("",p)
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/c864f69f-3744-dfde-cd21-e7057433e073.png)

- また上記の絵文字の部分を[手を振る絵文字](https://emojipedia.org/waving-hand/)に変えると**集まりの終了時**などに利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/835ed8f1-9485-17e4-2932-6244f083397a.png)

## 3. 一括着せ替え
- **イベント時などに全員に同じ格好をしてもらいたい時に利用できます。**
- まず自身が着せ替えたいキャラになり、以下の内容をChromeコンソール画面に入力して実行するだけで、参加者全員を一括で着せ替えることができます。
    - **※戻す実装をしていないので各々に戻していただいてください。**

```js
const character = game.players[gameSpace.id].outfitString
game.playerUidsSeenOnConnect.forEach(p => {
    game.setOutfitString(character,p)
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/32ac2b8b-e87c-1e45-d01f-b51d0f924723.png)

## まとめ
- Gatherは基本機能でも満足できますが、こうしたAPIを利用することでプログラムでリモートコミュニケーションを促進することが可能です。
- 他にも組み合わせ次第でさまざまに遊べると思いますので活用していければと感じました。

## 参考
- [Gather Websocket API](https://gathertown.notion.site/Gather-Websocket-API-bf2d5d4526db412590c3579c36141063)
- [ドキュメント](http://gather-game-client-docs.s3-website-us-west-2.amazonaws.com/classes/Game.html)
WSLでarduino-cliを使う

WSLでArduino IDEを使う記事をいくつか読みましたが，書き込みをするためにデバイスをWSLに接続して，とかいろいろ難しそうです...

WSLでは exe を直接実行できますので，デバイス接続せずに，WSLから書き込み「操作」を行うことで，うまくいきました。

`arduino-cli.exe` を入手し，以下ではデスクトップ上にzipを展開して，WSLでそこに移動して実行しています。

- https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.zip

```bash
$ cd /mnt/c/Users/aaaaa/Desktop/arduino-cli_0.29.0_Windows_64bit
$ ./arduino-cli.exe upload -p COM8 --fqbn arduino:avr:leonardo blink_monitor
```

arduino-cli 好きです！ ボード定義やライブラリーの追加がコマンドラインでできますので，環境の構築や復元がしやすいですね。
こんな感じの`Makefile`を作って利用しています。WSL用に少し手直ししました。

```Makefile
# usage:
#
# make                 # build only
# make upload          # build and upload
# make upload monitor  # build, upload and then monitor
# make setup

BIN=./arduino-cli.exe

# TARGET = blink
TARGET = blink_monitor

CORE = arduino:avr:leonardo
PORT = COM8

compile:
	${BIN} compile --fqbn ${CORE} ${TARGET}

upload: compile
	${BIN} upload -p ${PORT} --fqbn ${CORE} ${TARGET}

monitor:
	sleep 1;
	${BIN} monitor -p ${PORT}

CORE_URL = https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json

setup:
	${BIN} core update-index
	# ${BIN} core search M5 --additional-urls ${CORE_URL}
	# ${BIN} core install m5stack:esp32 --additional-urls ${CORE_URL}
	# ${BIN} board listall # show available board
	# ${BIN} board list # show connected board
	# ${BIN} lib search M5
	# ${BIN} lib install M5StickCPlus
	# ${BIN} lib install LovyanGFX
	${BIN} core install arduino:avr
```

実行例

```bash
$ make upload monitor
./arduino-cli.exe compile --fqbn arduino:avr:leonardo blink_monitor
最大28672バイトのフラッシュメモリのうち、スケッチが4210バイト（14%）を使っています。
最大2560バイトのRAMのうち、グローバル変数が161バイト（6%）を使っていて、ローカル変数で2399バイト使うことができます。


Used platform Version Path
arduino:avr   1.8.6   C:\Users\aaaaa\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6

./arduino-cli.exe upload -p COM8 --fqbn arduino:avr:leonardo blink_monitor
Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

sleep 1;
./arduino-cli.exe monitor -p COM8
Connected to COM8! Press CTRL-C to exit.
Count 1
Count 2
Count 3
Count 4
make: *** [Makefile:24: monitor] Error 58
$
```
Databricks on AWSで数百Gのファイルからテーブルを作成しようとすると発生することのあるエラーとその対策

ローカルファイルシステムからDBFSへの大容量ファイルのアップロードや大容量ファイルからテーブルを作成する際に、以下のようなエラーが発生することがあります。

> Part number must be an integer between 1 and 10000, inclusive

パートの数は1から10000でなくてはなりません。と、これだけですと切り分けが難しいですよね。

以下のナレッジベースに詳細な説明と対策方法の記載があります。

https://kb.databricks.com/cloud/s3-part-number-limit.html

**原因**
これはS3におけるセグメント数の制限です。分割されたファイルは1から10000の個数でなくてはなりません。

**対策**
この例外の発生を防ぐには、それぞれのパートファイルのサイズを増やしてください。

1. クラスターの[Spark設定](https://docs.databricks.com/clusters/configure.html#spark-configuration)の以下のプロパティを設定してください。

    ```
    spark.hadoop.fs.s3a.multipart.size 104857600
    ```

1. クラスターを再起動します。

つまり、S3への[マルチパートアップロード](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/mpuoverview.html)のパートの数の上限に引っかかっていたと言うことでした。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html

**Maximum number of parts per upload**は**10,000**であり、上の設定でパートあたりのファイルサイズを大きくしてパート数を1万に収まるようにしないといけません。デフォルト値は`10MB`です。

例えば、500GBのファイルからテーブルを作成しようとすると、5万弱のパートになるので、上述の制限の1万を超えてしまいます。`spark.hadoop.fs.s3a.multipart.size`を50MBに設定すれば、パート数は1万になりますのでエラーを回避することができます。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
GCP Professional Cloud Architect 合格体験記

このたびGCPの認定資格Professional Cloud Architectを取得いたしました。
合格までの勉強方法などを共有いたします。

# 筆者について
GCPの経験は業務で半年ほど経験(Workflows, CloudFunctions, BigQueryなどを中心に)
AWSはSAA資格(アーキテクト試験)を去年取得

# 資格概要
[こちら](https://cloud.google.com/certification/cloud-architect?hl=ja)に公式の案内がございます。
重要そうな事項をかいつまんでみます。

【受検方式】
テストセンターか自宅かが選択可能です。
この手の試験では、私はいつもテストセンターから受検しています。自宅からの受検だと不正行為防止のためのチェックが面倒だなと思ってしまうので...

【問題数と試験時間】
2時間で50問です。
※余談ですが受検時は筆記用具の使用が認められませんでした。この点はAWSの認定資格とは異なりますね。

【試験当日の持ち物】
担当者に身分証2点と承認コードを提出します。
私は身分証として運転免許証とマイナンバーカードを持参しました。承認コードは受検予約時のメールに記載があります。

# 勉強方法
主に下記の流れで進めました。
1\. Couseraのコース受講
2\. Udemyの日本語版問題集
3\. 海外サイトの英語版問題集
4\. 公式模擬問題集

ひとつずつみていきます。

## Couseraのコース受講
下記のコースを受講しました。GCPのサービスの全体をざっと把握する目的で受講しました。
- Google Cloud Fundamentals: Core Infrastructure 日本語版
- Essential Cloud Infrastructure: Foundation 日本語版
- Essential Cloud Infrastructure: Core Services 日本語版
- Elastic Cloud Infrastructure: Scaling and Automation 日本語版
- Reliable Cloud Infrastructure: Design and Process 日本語版
- Getting Started with Google Kubernetes Engine 日本語版
- Preparing for the Google Cloud Professional Cloud Architect Exam 日本語版

## Udemyの日本語版問題集
[こちら](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/)の問題集を購入し、3周ほど反復して演習しました。
実際の試験でも類題が多く出題されましたので、正答率が100%になるまで解くとよいでしょう。この問題を解く中で翻訳調の字面にも慣れておくとよいでしょう。

## 海外サイトの英語版問題集
Udemyの問題集を解き終えたら、[こちら](https://www.examtopics.com/exams/google/professional-cloud-architect/view/)の問題集に着手しました。
Udemyの問題集と重複する内容が多いですが、私が実際に試験を受けた感じからすると解いておく価値は十分にあると思います。

## 公式模擬問題集
最後の仕上げに、公式の[模擬問題集](https://docs.google.com/forms/d/e/1FAIpQLScpVCxsKSrqMBmqJ4fiYrJfCSlMhJVIFaW_v3MD4xEd6NW0Bw/viewform?hl=ja)に着手しました。
解説が非常に充実しているので、知識の最終確認に役立ちます。

# 所感
せっかく受けるなら合格したかったので、かなり徹底して問題演習を行いました。(なるべく費用は抑えながら...)
私が受検した感じだとここまでやっておけば合格は堅いかなと思います。
試験対策の中でGCPのサービスを広く知ることができてよかったです。
Incorrect use of ParentDataWidget（ParentDataWidget の不適切な使用エラー）　

最近Flutterの開発で初心者の自分はこのエラーと出会って、解決策をこの記事にまとめました。

# エラーメッセージ
<pre><code>
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a
RenderObject, which has been set up to accept ParentData of incompatible type BoxParentData.
Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically,
Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Padding widget.
The ownership chain for the RenderObject that received the incompatible parent data was:
  RichText ← Text ← Expanded ← Padding ← Container ← _BodyBuilder ← MediaQuery ←
LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ← AnimatedBuilder ← ⋯
</code></pre>

# 原因
このエラーは、Flexible(), Expanded(), Positioned(), TableCell() ウィジェットなどの子ウィジェットに、該当する親ウィジェットがない場合に発生します。 例えば
<pre><code>
Container(
  Expanded(
    child: Text("Hello FlutterCampus")
  )        
) //Error: Incorrect use of ParentDataWidget
</code></pre>

# 解決策
| Widget | Parent Widget |
|:-----------|------------:|
| Expanded()    | Row(), Column(), Flex()| 
| Flexible()    | Row(), Column(), Flex()| 
| Positioned()  | Stack()| 
| TableCell()   | Table()| 

# Example Code
<pre><code>
Row( 
  children:[
    Expanded(
      child: Text("Hello FlutterCampus")
    )
  ]
)
</code></pre>
OR:
<pre><code>
Stack( 
  children:[
    Positioned(
      child: Text("Hello FlutterCampus")
    )
  ]
)
</code></pre>
# 参考記事
+ https://stackoverflow.com/questions/54905388/incorrect-use-of-parent-data-widget-expanded-widgets-must-be-placed-inside-flex
+ https://www.youtube.com/watch?v=OM-sxyITP4o
[備忘録]逆アセンブルするときのobjdumpの使い方

# 実行
```
$ objdump -M intel -D a.out | grep -A30 main.:
```

`-M` オプション：


オブジェクトファイルを逆アセンブルするとき、アーキテクチャを指定する。 これは S-record のような、アーキテクチャの情報を持たないオブジェクトファ イルを逆アセンブルするときに有用である。指定可能なアーキテクチャンのリ ストは -i オプションによって得られる。


| オプション | 意味 |
| - | - |
| -M | 逆アセンブルする際のアーキテクチャを指定 |
| -D | 命令を含むと思われるセクションだけでなく、全てのセクションを逆アセンブルする。|
|-A30| (grepのオプション)検索文字列が見つかった行から後ろの30行を表示する、という意味。数字は変更可能。|

```
grep -A30 main.:
```
↑これはアセンブリの `main:`の中身30行だけを表示させるという意味。
`main:`が長かったら数字をもっと大きくして表示させる必要あり。
基本情報技術者試験に受かったけど、反省していること[これから受ける人必見]

<a href='https://qiita.com/curro/items/e6aa870943f2d7e39e21'>騙されるな！基本情報技術者試験の合格が別に凄くない理由 [高校生でも受かる]</a>
こちらの記事にもあるように、私は令和4年度10月の基本情報技術者試験を独学で受験し、合格しています。

自分としては合格することは勉強を始めた時から確信していたのですが、点数だけを見ると午前67.5点、午後67点と、超余裕というわけではありませんでした。(想定の範囲内といえば範囲内)

今振り返ってみると、こういう勉強法で臨めばもう少し高い点数を取ることが出来ただろうというのが見えてきましたので、来年4月に応用情報技術者試験を受ける自分用にも、またこれから基本情報技術者試験を受験する方向けにも、反省点を書いていきたいと思います。


<h3>反省点１:「プログラミング」の勉強ではなく「擬似言語」の勉強をしてしまった</h3>

基本情報技術者試験・応用情報技術者試験には、「擬似言語」というアルゴリズム力を問われる分野があります。特に基本情報技術者試験は午後の方が難しいとされていますが、その一因でもあるのがこの分野です。
私も初めて解いた時はプログラミングというものをほとんど理解していなかったので、納得に相当な時間がかかりました。
今思えば、「擬似言語」から入るのではなく、「プログラミング」の基礎を学ぶことから始めればよかったと振り返ります。

結局本番の時には擬似言語分野をやや得意というレベルまで持って行けたので、73%の正答率を得ることが出来ましたが、どう考えてもプログラミングを知ってから擬似言語に入る方が効率がいいという結論に至りました。


<h3>反省点2:午前の4択問題を正解の選択肢だけ見直していた</h3>

基本情報技術者試験・応用情報技術者試験の午前問題は、主に知識を問われる問題で、4択問題が何十問と出題されます。
私は復習がめんどくさかったので、「正解の選択肢が正解の理由」だけを理解して、「不正解の選択肢が不正解の理由」を復習しませんでした。
正直なところこのようなやり方でも合格できてしまうのがこの試験ですが、高得点は望めないでしょう。時間にある程度余裕がある方は不正解の選択肢にも着眼点を向けるべきです。そうすることで、別角度からの問題が出されたとしても、対応することが出来ます。

<h3>反省点3:学習を長期的にやりすぎた</h3>
私が基本情報技術者試験を受けようと思ったのは2022年2月で、参考書もその時期に買いました。しかしその時期は部活動もあったので、少しずつ学習を進めていました。６月からは部活もなくなり学習時間は取れましたが、３ヶ月あれば合格できると思っていたのであまり学習せず、8月末あたりから本気の学習を始めました。
しかしその時期には2月から５月あたりにやっていた範囲をほとんど覚えていなかったため、また復習し直す必要がありました。結果として合格は出来ましたが、2月から5月あたりにやっていた勉強はほとんど意味がなかったと考えています。
よく、基本情報技術試験の合格に必要なのは200〜300時間という記事を見かけるかと思いますが、1日3時間×100日の300時間と、1日1時間×300日の300時間では、全く意味が違います。前者の方が遥かに効率がいいです。
長期的だったというよりも、期間を空けすぎたというのが問題ですが、今後受ける方は、試験本番の3ヶ月前あたりから対策を始めることをお勧めします。その代わり、ほぼ毎日欠かさず学習する必要がありますが。


<h3>反省点4:午後の選択分野を決めるのが遅かった</h3>
現在、基本情報技術者試験では午前も午後も全問必須となっているので、基本情報技術者試験を受ける方はこの文章を読む必要はありませんが、応用情報を受ける自分用にも反省点として記しておきます。
現在の応用情報技術者試験や過去の基本情報技術者試験では、午後の分野を選択する必要がありました。この選択分野を決めるのが早ければ早いほど、その分野に特化した学習ができるのでその文点数を上げることが出来ますが、私が選択分野を絞り込んだのは午後試験の1ヶ月前くらいだったと記憶しております。
来春受ける応用情報では、午後問題の対策を始める時点で選択分野を決定したいと考えております。

<h2>まとめ </h2>
ここまで、私が基本情報技術者試験を受けて反省した点を書いていきました。<a href='https://qiita.com/curro/items/7c9f03455e85a6885076'>こちらの記事</a>では、基本情報技術者試験の合格法を記していますので、ぜひこちらもご覧ください。

こちらの記事についてご不明な点あればコメントください。


また、Twitterもやっているのでフォローしていただけると幸いです。
JavaScriptでのモジュール化 import, export

```javascript:/modules/area.js
export function triange(base, height){
    return (base * height)/2;
}

export function circle(r){
    return r * r * Math.PI;
}
```

```javascript:main.js
import { triange, circle } from './modules/area';

console.log(triange(3,8));
console.log(circle(10));
```

関数のほかに変数やクラスをexportすることもできる。

```javascript:/modules/constants.js
const THRESHOLD = 100;
const MAIN_COLOR = 'purple';
const MODAL_WIDTH = 800;
const LIST_LENGTH = 100;
const DEFAULT_SORT = 'created_at';

export {THREHOLD, MAIN_COLOR, MODAL_WIDTH, LIST_LENGTH, DEFAULT_SORT };
```

１ファイル内で1つしかexportするものがない場合、上記のようにdefaultを使って明示できる。
```javascript
export default class Triangle {
    constructor(base, height){
        this.base = base;
        this.height = height;
    }
    getArea(){
        return (this.base * this.height) / 2;
    }
    doubleBase(){
        this.base = this.base * 2;
    }
}

```
インシデントって結局なに？〜ITIL4から学ぶインシデント管理・問題管理〜1/2


## はじめに

障害対応や不具合調査をしていく中で、
**「これ前にもあった気がする、、」「これって〇〇さんじゃないとわからないかも、、」** といったことありません、、？ありますよねあります。
それはインシデント管理が適切にできていないのではということで、まずインシデント管理とはなんぞやということで今回ITIL4を学び始めることにしました。
ITILとはなんぞや？は今回は大きく取り扱わないため、
気になる方は「ITILファンデーション」など調べてみていただければと思います。



## ITIL4におけるサービスマネジメントプラクティス

ITIL4では管理プラクティスとして「一般的マネジメントプラクティス」「サービスマネジメントプラクティス」「技術的マネジメントプラクティス」の3つに大きく分けられます。
詳細は省略しますが、それぞれ**ベストプラクティスがぎゅっとまとめられている** ようなものです。

そのうちの「サービスマネジメントプラクティス」はインシデント、問題管理、サービスデスクなど、システム運用に大きく関わる部分が記載されています。

サービスマネジメントプラクティスとは下記の7つで構成されています。
```
①モニタリングおよびイベント管理
②インシデント管理
③問題管理
④サービス要求管理
⑤変更実現
⑥リリース管理
⑦サービス構成管理
⑧IT資産管理
⑨サービスデスク
⑩サービスレベル管理
```


今回はこの中でも
```
①モニタリングおよびイベント管理
②インシデント管理
③問題管理
```
について取り上げたいと思います。


## ①モニタリングおよびイベント管理
ITILにおけるモニタリングおよびイベント管理は下記のように記載されています。
>サービスの提供に必要なサーバ、アプリケーションなどから通知されるすべてのイベントを監視し、異常状態を通知するイベントが発生した場合にはイベント管理プラクティスにエスカレーションするなど、適切な対応を行います。

この中で
>　すべてのイベントを監視し

個人的にはここがミソだと思いました。
インシデントに繋がるから監視、記録するのではないとうことですね。

上記を踏まえた上で①モニタリングおよびイベント管理では下記の3つのイベントに分類されます。

#### ①情報
**どのような対処も必要とされないイベント** が該当します。
例えば
```
・バッチ処理が正常に終了した
・ユーザーAがアプリケーションに正常にログインした
```
など、その場で何か対処が必要ではないですが、記録しておくことで分析すると何か改善が見えるかもしれません。

#### ②警告
あるしきい値に達したときに生成されるイベントです。
例えば
```
・メモリの使用量が80%を超えるとレスポンスが遅くなる場合に、メモリ使用量が70%を超えていて
今も上昇し続けている
・正常状態と比較して、バッチ処理完了までの時間が15%も長くなっている
```
など、このまま**放っておくと危ないよ〜というイベント**が該当します。
警告イベントはインシデント管理プラクティスや変更実現プラクティスにエスカレーションしたりする場合があります。放っておいたらまずいから今のうちに改善しようといったイメージです。

#### ③例外
いわゆる障害やインシデントというときにはこちらを指すケースが多い印象です。
```
・サーバーがダウンした
・ネットワークの応答に20秒以上かかっており、許容できる範囲を超えている
```
正常に運用できていない場合に生成されるイベントです。
ここの「正常」というのはサービス提供者と顧客で合意している基準（SLAといったりします）を満たしているかどうかということになります。


## ②インシデント管理
やっとタイトル回収。ここまでも長かったですね、、

ここでいうインシデントとは
**「サービスを中断させる、または中断させる可能性があるすべての事象」** が対象です。

そしてインシデント管理では
**可能な限り迅速に運用を回復させること**を第一に考えます。
逆に言うとこのインシデント管理では**問題の根本原因の調査や解決などは実施しない**です。
それは後ほど説明させていただく③問題管理の役割です。


インシデントは下記3つを経由して記録されます。

### ①サービスデスク経由でユーザーから直接伝達された現象
システムを使われているユーザーから「アクセスできない」「レスポンスが遅くなった」など
いわゆる問い合わせをいただくことで記録されます。

ここは個人的には１番避けたいですね、、ユーザーから問い合わせをもらう前に検知したいものです。


### ②モニタリングおよびイベント管理プラクティスからのエスカレーション
先程説明させていただいた①モニタリングおよびイベント管理で、警告イベントや例外イベントなど
エスカレーションされたものがこちらに該当します。


### ③技術スタッフによる記録
技術スタッフがハードウェアやネットワークの不具合に気づいたケースなどが該当します。
例えば深夜帯に技術スタッフが気づき、ユーザーが気づいていない場合もインシデントとして扱います。



>そしてインシデント管理では
**可能な限り迅速に運用を回復させること**を第一に考えます。

と記載させていただいた通り、
①②③を経由して登録されたインシデントをできるだけ早く正常に運用できるよう回復させるのが
インシデント管理の役割です。


様々インシデントが記録されていく中でどのように優先順位をつけるのでしょうか。
一旦正常に運用できるよう回復したとして、根本解決はどうするのでしょうか。

、、、思ったより長くなってしまったため、こちらは次回に持ち越したいと思います！


### 終わりに
そもそもインシデントとはなんぞや、という部分は
今回を通して少しは理解が深まったような気がします。
実際にこの通りに運用とはなかなかいかないかもしれないですが、そもそもや
ベストプラクティスを知っておくのは大事だなと。
次回はインシデント管理→問題管理まで書きたいと思います！


### 参考
今回はこちらの本をもとに書かせていただきました、ありがとうございました！

https://amzn.asia/d/d71yeuG
HTMLをショートカットを使って書く

今回はHTMLを書くときのショートカットについての備忘録です。

ショートカットを使うことのメリットは以下の点です。

<ul>
    <li>コードの間違いが減る。</li>
    <li>作業速度が格段に上がる。</li>
</ul>

というわけで、これから自分の作業速度を早くしていきたいので、学んだショートカットについて書き残しておきます。

<h1>ショートカット一覧</h1>
<h2>クラスやIDを持ったタグを生成する。</h2>

```HTML
.class
→<div class="class"></div>

#container
→<div id="container"></div>

span.cls
→<span class="cls"></span>
```

<h2>クラスやIDをつけた入れ子をを生成する</h2>

```HTML
#container>.cls
<div id="container">
    <div class="cls"></div>
</div>

.cls>.on
<div class="cls">
    <div class="on"></div>
</div>
```

<h2>入れ子の中身を複製する</h2>

```HTML
#container>.cls*6
→<div id="container">
        <div class="cls"></div>
        <div class="cls"></div>
        <div class="cls"></div>
        <div class="cls"></div>
        <div class="cls"></div>
        <div class="cls"></div>
</div>

#container>.cls-$*6
<div id="container">
        <div class="cls-1"></div>
        <div class="cls-2"></div>
        <div class="cls-3"></div>
        <div class="cls-4"></div>
        <div class="cls-5"></div>
        <div class="cls-6"></div>
</div>

#container>.cls-$$*6
<div id="container">
        <div class="cls-01"></div>
        <div class="cls-02"></div>
        <div class="cls-03"></div>
        <div class="cls-04"></div>
        <div class="cls-05"></div>
        <div class="cls-06"></div>
</div>
```
これらのショートカットはほんの一部だと思うので、これからどんどんショートカットを覚えていって作業速度を上げていこうと思います。
【データ結合/Python】左外部結合でmergeすると、右側のテーブルの値がNaNで結合されてしまう

# 今回の課題
train.csv(train_df)を左、tranaction.csv(transaction_df)を右側で左外部結合したところ、
transaction_dfの`transactions`カラムがNaNになってしまった。

原因としては、
**結合するためのキーとして設定していた`date`カラムが、
train_dfとtransaction_dfの間で一つも一致するものが無く、うまく結合ができていなかっただけ**だった...。

初歩的な原因ではあったが、
pythonでデータの結合を試行錯誤した記録としてメモに残すことにした。

**※補足**
[Store Sales - Time Series Forecasting](https://www.kaggle.com/competitions/store-sales-time-series-forecasting)で配布されているCSVデータを少し加工して、結合しようとしました。

## 試行錯誤した内容
#### 1)dateとstore_nbrをキーにして、左外部結合してみた
```python
transaction_date_family_train_df = pd.merge(train_df, transaction_df, on=['date', 'store_nbr'], how='left')
transaction_date_family_train_df.head()
```
これだと、`transaction_df`側の、`transactions`カラムがNaNってしまった。

#### 2)dateとstore_nbrをキーにして、右側外部結合してみた
```python
transaction_date_family_train_df = pd.merge(train_df, transaction_df, on=['date', 'store_nbr'], how='right')
transaction_date_family_train_df.head()
```
これだと、`train_df`側の`sales`カラムと`onpromotion`カラムがNULLとなってしまった。

#### 3)dateとstore_nbrをキーにして、内部結合してみた
```python
transaction_date_family_train_df = pd.merge(train_df, transaction_df, on=['date', 'store_nbr'], how='inner')
transaction_date_family_train_df.head()
```
生成したデータフレームにはデータが何も格納されなかった。

上記のように試行錯誤した結果、
**結合のキーに設定しているカラムに問題があるのではないか？** と考えた。

そして、下記の2つを試してみた。


#### 最後に試したこと
* `date`だけをキーにして内部結合
* `store_nbr`だけをキーに内部結合

この2つを試してみると、
`store_nbr`だけをキーにして結合する場合は、データが抽出されるのに対して、
`date`だけをキーにして結合すると、何もデータが抽出されなかった。

以上の結果から、
**結合するためのキーとして設定していた`date`カラムが、
train_dfとtransaction_dfの間で一つも一致するものが無く、うまく結合ができていなかっただけ**だったと言うことがわかった。
AWS CodeStarのDjangoプロジェクトでgunicorn再起動設定

AWS CodeStarで作成したDjangoプロジェクトが初期設定のままだとEC2インスタンスを再起動した時に自動でgunicornが起動しないので起動するように設定変更

### supervisod.confを修正
パスを変更
```
[program:djangoproject]
command = /home/ec2-user/environment/bin/gunicorn -b 0.0.0.0:80 ec2django.wsgi
```

### サービス化するファイルを作成
djangoはお好きな名前に変更
```
sudo vi /etc/init.d/django
```
```
#!/bin/sh
# chkconfig: 2345 99 10
# description: start django
# processname: django

start() {
       echo "start"
       source /home/ec2-user/environment/bin/activate
       export LD_LIBRARY_PATH="/usr/local/lib"
       /home/ec2-user/environment/bin/supervisord -c /home/ec2-user/supervisord.conf
}

stop() {
       echo "stop"
       pkill supervisord
}
case "$1" in
 start)
       start
       ;;
 stop)
       stop
       ;;
 restart)
       stop
       start
       ;;
esac

exit 0
```
### サービスの登録
```
sudo chkconfig --add django
sudo chkconfig django on
sudo chmod u+x /etc/init.d/django 
sudo service django restart
```

再起動して画面が見えればOK