OmniAICreator/Qiita-1.07M huggingface dataset:
BeautifulSoupを用いて競馬データをスクレイピングする方法

# 目的
機械学習で競馬予想して回収率100%を目指す。

# 今回やること
[前回の記事](https://qiita.com/dijzpeb/items/434b259e473cc8646e91)で、netkeiba.comから2019年の全レース結果のデータをスクレイピングした。
![スクリーンショット 2020-07-04 22.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667890/7e2be0fd-3428-d49b-ffc8-21d96fd25fb5.png)
今回はこれに加えて、レースの日付の情報や馬場の状態などのデータをスクレイピングしたい。
![スクリーンショット 2020-07-05 14.11.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667890/3eef7ba5-fa1c-5787-6c85-457bb1d4a714.png)

# ソースコード
前回同様、race_idのリストを入れたらそれぞれのレースについてスクレイピング結果を辞書型で返してくれる関数を作る。

```python
import requests
from bs4 import BeautifulSoup
import time
from tqdm.notebook import tqdm
import re

def scrape_race_info(race_id_list):
    race_infos = {}
    for race_id in tqdm(race_id_list):
        try:
            url = "https://db.netkeiba.com/race/" + race_id
            html = requests.get(url)
            html.encoding = "EUC-JP"
            soup = BeautifulSoup(html.text, "html.parser")

            texts = (
                soup.find("div", attrs={"class": "data_intro"}).find_all("p")[0].text
                + soup.find("div", attrs={"class": "data_intro"}).find_all("p")[1].text
            )
            info = re.findall(r'＼w+', texts) #Qiitaでバックスラッシュを打つとバグるので大文字にしてあります。
            info_dict = {}
            for text in info:
                if text in ["芝", "ダート"]:
                    info_dict["race_type"] = text
                if "障" in text:
                    info_dict["race_type"] = "障害"
                if "m" in text:
                    info_dict["course_len"] = int(re.findall(r"＼d+", text)[0]) #ここも同様に大文字にしてます。
                if text in ["良", "稍重", "重", "不良"]:
                    info_dict["ground_state"] = text
                if text in ["曇", "晴", "雨", "小雨", "小雪", "雪"]:
                    info_dict["weather"] = text
                if "年" in text:
                    info_dict["date"] = text
            race_infos[race_id] = pd.DataFrame(info_dict)
            time.sleep(1)
        except IndexError:
            continue
        except Exception as e:
            print(e)
            break
    return race_infos
```
[前回スクレイピングしたデータ](https://qiita.com/dijzpeb/items/434b259e473cc8646e91)からrace_id_listを作り、前回同様にDataFrame型にして元々のデータにmergeする。

```python
race_id_list = results.index.unique()
race_infos = scrape_race_info(race_id_list)
for key in race_infos:
    race_infos[key].index = [key] * len(race_infos[key])
race_infos = pd.concat([pd.DataFrame(race_infos[key], index=[key]) for key in race_infos])
results = results.merge(race_infos, left_index=True, right_index=True, how='left')
```
完成したデータはこんな感じ。
![スクリーンショット 2020-07-05 14.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667890/af795f08-e122-d832-875f-4abc6e5215cc.png)

動画で詳しい解説をしています！
[競馬予想で始めるデータ分析・機械学習](https://www.youtube.com/channel/UCDzwXAWu1zIfJuPTTZyWthw)
Node.js: Starttls でメールの送信

こちらと同じことを Node.js で行いました。
[Python3: Starttls でメールの送信](https://qiita.com/ekzemplaro/items/c248b52a6f36947af080)
hi-ho.ne.jp で試しました。

## 必要なライブラリーのインストール

```bash
sudo npm install -g dotenv
sudo npm install -g nodemailer
```

## プログラム

```js:hi-ho.js
#! /usr/bin/node
//
//	hi-ho.js
//
//					Mar/31/2025
// ---------------------------------------------------------------
'use strict'

const dotenv = require('dotenv')
const nodemailer = require('nodemailer')

console.error ("*** 開始 ***")

dotenv.config()

const env = {
    server: `${process.env.SERVER}`,
    port: `${process.env.PORT}`,
    usr: `${process.env.USR}`,
    password: `${process.env.PASSWORD}`,
    from: `${process.env.FROM}`,
    to: `${process.env.TO}`,
}

console.log(env.from)
console.log(env.to)

// create reusable transporter object using the default SMTP transport
const url = 'smtps://' + env.usr + ':' + env.password + '@' + env.server 
var transporter = nodemailer.createTransport(url)

// setup e-mail data with unicode symbols
var mailOptions = {
    from: env.from, // sender address
    to: env.to, // list of receivers
    subject: 'Hello Mar/31/2025 AM 08:36', // Subject line
    text: 'Hello world AM 08:36 plaintext', // plaintext body
    html: '<b>Hello world AM 08:36 html</b>' // html body
}

// send mail with defined transport object

transporter.sendMail(mailOptions, function(error, info){
    if(error){
        return console.log(error)
    }
	console.log('Message sent: ' + info.response)

	console.error ("*** 終了 ***")
})


// ---------------------------------------------------------------
```

```text:.env
SERVER = 'hi-ho.mose-mail.jp'
PORT = 587
USR = '****@hi-ho.ne.jp'
PASSWORD = '****'
FROM = '****@hi-ho.ne.jp'
TO = 'sample@example.com'
```

## 実行結果

```text
$ ./hi-ho.js
*** 開始 ***
****@hi-ho.ne.jp
sample@example.com
Message sent: 250 2.0.0 0622YNNb088216 Message accepted for delivery
*** 終了 ***
```

## 確認したバージョン

```text
$ node --version
v23.9.0
```

## エラーが出た時の暫定対策

エラーメッセージ

```text
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames:
```

証明書を無効にします。

```js
const transporter = nodemailer.createTransport({
  host: 'eye.jp', // 使用する SMTP サーバー
  port: 465, // 例: SSL/TLS のポート
  secure: true, // true にすると SSL/TLS を使用
  auth: {
    user: env.usr,
    pass: env.password,
  },
  tls: {
    rejectUnauthorized: false, // 証明書検証を無効にする
  },
})
```
Flask実行時にModuleNotFoundError: No module named '***'の対策

###問題###
Pycharmで既存のプロジェクトにウェブサーバーを入れることにしました。ただ、既存のプロジェクトにサブパッケージとして、flaskプロジェクトを置きました。

そして、サブパッケージにcdして、falskサーバーを立ち上げて、ルーティングをアクセスする時に、以下のエラーが発生しました。

```sh
flask.cli.NoAppException
lask.cli.NoAppException: While importing "Machine_Learning_Project.resnet.server.flaskr", an ImportError was raised:

Traceback (most recent call last):
  File "/home/user/anaconda3/lib/python3.7/site-packages/flask/cli.py", line 240, in locate_app
    __import__(module_name)
  File "/home/user/Source/Machine_Learning_Project/resnet/server/flaskr/__init__.py", line 4, in <module>
    from resnet.server.flaskr.index import run_process_result, index_router
ModuleNotFoundError: No module named 'resnet'
```

エディターpycharmでは、import文にエラーがないですが、flaskサーバーにアクセスするときに、依存のパーケージを見つけれないえらーがウェブ側に表示されます。


###原因###
flaskサーバーを立ち上げるときに、いかのコマンドを実行しました。

```sh
cd /home/user/Source/Machine_Learning_Project/resnet/server
flask run
```

このコマンドを実行するディレクトリのパスはflaskサーバーのルートパースになっています。
ルートパス:/home/user/Source/Machine_Learning_Project/resnet/server
flaskサーバーはこのパスしかわからないため、importされるパッケージをたどり着けるときに、このパスからたどり着けるしかできないです。
importされたパッケージは他のディレクトリにあるため、パッケージが見つからないエラーが発生しています

<img width="441" alt="スクリーンショット 2020-07-05 14.13.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/142d213a-ae54-605a-f778-3c64f01aa70d.png">
図のように、オレンジの部分はflaskサーバーのルートパースです。オレンジ部分以外なパッケージ(赤い部分)をimportする時に、当然見つからないエラーが発生します。

<img width="1139" alt="スクリーンショット 2020-07-05 14.18.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/269c723d-17c1-9293-31d7-244381697f8c.png">
ずのように、エディターは赤い部分をルートパスとして指定するため、import分にエラーが表示されなかったです。

###解決法###
falskサーバーにimportしたいパッケージの所在地を教えてあげれば、解決されます。
教える方法は以下のコードになります。

```python
import sys
sys.path.append("/home/user/Source/Machine_Learning_Project")
```

注意点としては、importしたいパッケージのimport文の前に置くべきです。
[Swift]Gameplaykit Programming Guide超要約

### GameplayKit Programming Guide

[GameplayKit Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/GameplayKit_Guide/index.html#//apple_ref/doc/uid/TP40015172-CH1-SW1)

### GameplayKitとはどんなものか

- ゲームを作る際のアーキテクチャ 設計・構築
- ゲームを作る上で必要な複雑なアルゴリズムの構築をサポート
- 他の上位層のゲーム用ライブラリとは独立しており、ゲームを作る際自由に組み合わせて使うことができる。
   - 例えば、Gamekitと、2Dゲームの場合はSpriteKit, 3Dゲームの場合はSceneKit, サードパーティ製のエンジンを使いたい場合はMetal や　OpenGLESを組み合わせて使える。グラフィックがさほど要らないゲームならUIKitと組み合わせてもいい。
- GameplayKitのカバーする領域
  - ランダム化
     - 乱数を提供する。
  - エンティティ-コンポーネントアーキテクチャ 
     - ある動作を定義したコンポーネントをオブジェクトに複数つけることで、ゲーム上に多様なオブジェクトを定義するためのアーキテクチャ 。
  - ステートマシン
     - ゲーム内のオブジェクトがどの状態においてどの動きをするか、またどの状態からどの状態へ移行できるかを簡単に記述するための機能。
  - ミニマックス法
     - オセロ・将棋などの[完全情報ゲーム](https://ja.wikipedia.org/wiki/ミニマックス法)において、コンピュータ（人工知能）の動きを実装するために用いる。
  - 経路検索
     - ゲーム盤、フィールド上などでオブジェクトを動かす際の経路の検索に関わるライブラリ。
  - `Agent`,`Goal`,`Behavior`アーキテクチャ
     - 自律的にゲーム上のオブジェクトを動かすために、オブジェクトに行動の目的（Goal）を設定するためのアーキテクチャ 。
  - ルールシステム
     - ゲーム上に設定するルールを規定する。
Node-REDでのSQLインジェクション対策

#概要
Node-REDを簡易REST APIサーバーとして使う案件があって、
DBサーバー（MySQL）にログを保存する仕掛けになっているんだけど、
SQLインジェクション対策ってどうやるんだっけと思って、調べてみた話。

#結果
node-red-contrib-sqlstringというノードがあって、これが使えそう。
ただ、Exampleが不足していて、ちょっと使い方がわかり辛かった・・・。

#使い方
1. node-red-contrib-sqlstringを追加。
ハンバーガーメニューから、パレットの管理を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/e3f15268-8073-1c4f-e10d-e4307a653d66.png)
ノードを追加タブを選び、検索文字に「sqlstring」を入れると、node-red-contrib-sqlstringが表示されるので、「ノードを追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/9ee4b3a6-31de-22c1-2a8c-ad969025f2bc.png)
追加が完了すると、パレットにnode-red-contrib-sqlstringのノードが追加されています（なぜかストレージの項目・・・）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/1781f9c9-1906-8c4b-dcb3-9d6b97809848.png)

2. フローを作成
フローはざっくりこんな感じにしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/f271766f-28f8-d42c-bbcb-4e1e88ca04b8.png)

3. node-red-contrib-sqlstringの設定
ノードをダブルクリックして、設定を行います。
SQL構文をそのまま書けるのが嬉しい！（このノードを知るまで、Functionノードでごにょごにょ書いてた・・・）
変数は構文の中に「？」を書いておき、Variables欄に該当する変数をカンマ区切りで記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/f4038d5c-172b-1a4b-ac5c-3f3b8454aced.png)

ここでハマったのが、変数の指定の仕方。
http inノードで受けたデータは、msg.payloadの中に入ってくるんですが、
例えばブラウザで「localhost:1880/test/api/hoge?id=1」と指定すると
msg.payload.idに1が設定されて次のノードにわたってきます。

ここで、Variables欄に「msg.payload.id」と指定しても、上手く値が入ってこない・・・。
試しに「id」としても、上手く値が入ってこない・・・。
node-red-contrib-sqlstringのソース見たら、
どうやらこの場合は「payload.id」と指定する必要があるようです。
⇒ Node-REDではこの指定の方法が普通なのかな？

ちなみに、このノード、SQLインジェクション対策は
[https://github.com/mysqljs/sqlstring](https://github.com/mysqljs/sqlstring)を利用しているとのこと。
Nuxt.jsでポートフォリオサイトを作ろう #1: Nuxtプロジェクトの作成

![nuxt.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/dbc0565f-3928-8907-7bfc-5d182f514e41.jpeg)

これから何回かに分けて、Nuxt.jsのチュートリアルを兼ねたポートフォリオ制作をしていきます。

####Node.jsのインストール

Nuxt.jsをインストールするためには、npxもしくはyarnを使います。

今回はnpxを使った方法を紹介します。

npxを使うにはNode.jsをインストールする必要があります。[ここ](https://nodejs.org/ja/)で推奨版をダウンロード後、.msiファイルを開き、指示に従ってインストールを進めてください。

ターミナルを開き、以下のコマンドを実行します。

```
$ npx -v
```

バージョンが表示されればインストールは完了です。

####Nuxtプロジェクトの作成

好きなディレクトリに移動してもらい、そこでコマンドを実行します。

```
$ npx create-nuxt-app プロジェクト名
```

プロジェクト名は好きに決めてください。ここでは、nuxt-portfolioとしておきます。

```
$ npx create-nuxt-app nuxt-portfolio
```

コマンド実行後、ターミナル上で設定項目を質問されますので、以下の設定にしてください。

```
? Project Name: (nuxt-portfolio) // そのままエンター
? Programming language: (Use arrow keys)
> JavaScript // 選択
  TypeScript
? Package manager: (Use arrow keys)
> Yarn
  Npm // 選択
UI Flamework: (Use arrow keys)
> None
  Ant Design Vue
  Bootstrap Vue
  Buefy
  Bulma
  Element
  Framevuerk
  iView
  Tachyons
  Tailwind CSS
  Vuesax
  Vuefify.js // 選択
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) Axios // 選択
 ( ) Progressive Web App (PWA)
 ( ) Content
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) ESLint // 選択
 ( ) Prettier
 ( ) Lint staged files
 ( ) StyleLint
? Testing framework: (Use arrow keys)
> None // 選択
  Jest
  AVA
  WebdriverIO
? Rendering mode: (Use arrow keys)
> Universal (SSR / SSG) // 選択
  Single Page App
Deployment target: (Use arrow keys)
> Server (Node.js hosting) // 選択
  Static (Static/JAMStack hosting)
Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) jsconfig.json (Recommended for VS Code) // 選択
 ( ) Semantic Pull Requests
```

すべて選択し終えるとプロジェクトの作成が始まりますので、しばらく待ちます。

####プロジェクトの起動

プロジェクトの作成が終了したら、nuxt-portfolioディレクトリに移動します。そこで以下のコマンドを実行します。

```
$ npm run dev
```

ターミナル上にローカルホストのアドレスが表示されるので、アクセスしてみましょう。

![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/7e7ce5ed-6b76-6f76-b95a-9a963d9efe0b.png)

上の画面が表示されます。

これでポートフォリオのひな型が出来上がりました。

次回から実際にサイトを構築していきます。

[Nuxt.jsでポートフォリオサイトを作ろう #2: 固定ヘッダーとフッターの作成](https://qiita.com/takahashitakuya031126/items/458be83bcdb1cac01e43)
Node.jsのAPIをまとめてみた

#はじめに
先週ぐらいからNode.jsの参考書を読み始め、途中から
「**■■ = require('〇〇')**」
というのが連発してきて、いろんな種類のAPIが使えるのだと知りました。

参考書の最初は「require('events')」や「require('http')」を使っていて、
他にどんなAPIが使えるのか気になり、一覧としてまとめてみました。


※初学者のため誤りがあると思います。
　間違いはコメントしていただけると幸いです。:bow_tone1:

#本題の前に
本題の前に、「**require**」について少しだけ触れておきます。

requireとは、**モジュール化されたJavaScriptのファイルをNodeから読み込んで利用できるようにしてくれるもの**です。

npmを使ってインストールしてきたパッケージを利用する際にもこの「require」を使用します。

著者は普段、C言語を使用していますので、この「require」はC言語のインクルードみたいなものだと理解しています。(あくまでもイメージです。)

本記事は、Nodeをインストールしたらデフォルトで使用できるモジュールについて一覧にしてみました。

#Nodeモジュール一覧

下表は[Node.js v12.18.2 ドキュメント](https://nodejs.org/dist/latest-v12.x/docs/api/documentation.html#documentation_stability_index)を参考にまとめました。
公式ドキュメントにはそのAPIの安定性が記載されています。
簡単にまとめると、

安定性：0 - 非推奨
安定性：1 - 実験的
安定性：2 - 安定
(詳しくは ⇒ [公式ドキュメント](https://nodejs.org/dist/latest-v12.x/docs/api/documentation.html#documentation_stability_index))

使いたいAPIは、「require('下表のAPI名')」を書けば使えます。

|API            |API名  |安定性    |説明                   |
|---------------------|-------------|-------------|----------------|
|Assertion Testing|assert|2|アサーションモードの使用|
|Async Hooks|async_hooks|1|非同期リソースの追跡|
|Buffer|buffer ※1|2|バイナリデータを一連のバイト形式に変換|
|C++ Addons|./build/Release/addon ※2|2|C++で記載されたアドオンをロード|
|Child Processes|child_process|2|子プロセスを生成|
|Cluster|cluster|2|サーバポートを共有する子プロセスを生成|
|Console|console ※1|2|単純なデバッグコンソール|
|Crypto|crypto|2|暗号化機能|
|DNS|dns|2|名前解決|
|Domain|domain|0|複数の異なるIO操作の処理|
|Events|events|2|イベント処理|
|File System|fs|2|ファイルシステム操作|
|HTTP|http|2|HTTPインタフェース|
|HTTP/2|http2|2|HTTP/2プロトコルの実装|
|HTTPS|https|2|httpsインタフェース|
|Inspector|inspector|1|V8インスペクターとの対話|
|Net|net|2|TCPまたはIPCサーバ・クライアントの作成|
|OS|os|2|OS関連のユースティリティ|
|Path|path|2|ファイルおよびディレクトリパス操作|
|Process|process ※1|記載なし|プロセス制御|
|Punycode|punycode|0|Punycodeモジュールのバンドル|
|Query Strings|querystring|2|食える文字列の解析及びフォーマット|
|Readline|readline|2|ストリームから１行ずつデータ読み取り|
|REPL|repl|2|REPLの実装|
|Stream|stream|2|ストリーミングデータの操作|
|String Decoder|string_decoder|2|文字列にデコード|
|Timers|timers ※1|2|スケジュール操作|
|TLS/SSL|tls|2|TLSおよびSSLプロトコルの実装|
|Trace Events|trace_events|1|トレースイベント操作|
|TTY|tty ※3|2|tty操作|
|UDP/Datagram|dgram|2|UDPデータグラムソケットの実装|
|URL|url|2|URL解決および解析|
|Utilities|util|2|APIのユースティリティ|
|V8|v8|記載なし|V8固有のAPI|
|VM|vm|2|V8仮想マシン|
|Worker Threads|worker_threads|2|スレッド作成|
|Zlib|zlib|2|圧縮機能|
※1. グローバルスコープ内にあるため、requireを使用する必要はほとんどない
※2. `build/Release/addon.node`という名前でアドオンが作成
※3. ほとんどの場合、直接操作する必要はない

#さいごに
調べてみると、使っていないAPIがたくさんあることに気づきました。
フレームワークもたくさんあるのでそこら辺も一回整理したいですね。

##参考
* [サーバサイドJavaScript Node.js入門](https://www.amazon.co.jp/dp/B00IOGV3XU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
* [Node.js v12.18.2 ドキュメント](https://nodejs.org/dist/latest-v12.x/docs/api/documentation.html#documentation_stability_index)
今更VBAで複数ファイルを選択するダイアログを作成

### 事務作業の効率化する際に毎回検索してるので忘備のため

    Sub 複数ファイルをひらく()
    Dim sfile As Variant
    Dim cfile As Variant
    Dim path_name As String
    path_name = ThisWorkbook.Path

    Dim wb As Workbook
    'ダイアログを開くと選択したいファイルがあるディレクトリが展開されるように記述
    ChDir "C:\Users\USER\Desktop\Excel_VBA\並べ替え\バックアップフォルダ"
    'ファイルダイアログを作成。複数選択可能にするためにMultiSelect:=Trueとする
    sfile = Application.GetOpenFilename(filefilter:="Excelファイル,*.xlsx", MultiSelect:=True)
    'IsArray関数で配列チェック。
    If IsArray(sfile) = True Then

    '選択したファイル毎の読込開始。今回はサンプルとして、ファイル名は必ず表示し、
    '開いたファイルに[メイン]シートがあれば表示。なければファイルを閉じる処理をする

    For Each cfile In sfile
    Set wb = Workbooks.Open(cfile)
        MsgBox wb.Name
        Dim i As Long
        For i = 1 To wb.Sheets.Count
        If wb.Sheets(i).Name = "メイン" Then
        MsgBox wb.Sheets(i).Name
        Else
         wb.Close False
        Exit For
        End If
        Next
    Next
    Else
    End If
    End Sub
nuxt.js + docker-composeでlocalhostにアクセスするとERR_EMPTY_RESPONSEに...

どうやらテレメトリにの収集についてconfigファイルに明記する必要があるようだ。

```nuxt.config.js
export default {
  telemetry: false
}
```

これでアクセスできるように！

# 参考文献

- 公式:
https://nuxtjs.org/api/configuration-telemetry
- stackoverflow:
https://ja.stackoverflow.com/questions/63529/docker-compose-nuxt-%E3%81%A7-localhost3000%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%84
ラズパイ3：「No volume control on this device」が表示されて音声が出力されない。

# 前提

- 対象機器：Raspberry Pi 3 Model B+
- 「**/boot/config.txt**」に「**dtparam=audio=on**」は設定済み。（これがないと音声出力はされない。）
- Windows10で関連ファイルを編集。

# 現象

- デスクトップの音声アイコンを選択すると**「No volume control on this device」**のメッセージが表示される。
- 「aplay -l」コマンドを実行すると、**「aplay: device_list:270: サウンドカードが見つかりません...」**が表示される。

# 原因と対応

- 「/boot/config.txt」に「**^M**」が含まれていた。
- 「^M」を削除すると問題は解消した。


# 参考

- [VI エディタでファイルを開くと行末に ^M が表示される
](https://server.etutsplus.com/vi-remove-m-character/)
VSCodeのデザインをアニメや映画のモデルに変更できる拡張機能まとめ

#はじめに

タイトルにもある通り、VScodeのデザインをアニメや映画をモデルとしたデザインに変更できる拡張機能を紹介させていただければと思います！

エンジニアの方にとっては長時間見続ける事になるVScode,どうせならデザインを自分の好みのデザインにして楽しく作業ができたらいいなと思い調べたものをみなさんに共有できればと思います！

今回の拡張機能は[VSCodeThemes — Preview Visual Studio Code Themes.](https://vscodethemes.com/light?page=28)というVSCodeのThemeを変更できる拡張機能がまとめられているサイトを参考にさせていただきました！
今回紹介するもの以外にも、たくさんカッコイイデザインや可愛いデザインのThemeが掲載されていますので、気になる方はぜひそちらからチェックしてみてください！

リンク：　https://vscodethemes.com/
![VSCodeThemes — Preview Visual Studio Code Themes.](https://vscodethemes.com/static/screenshot.png)

では早速紹介していきましょう！

#海外作品

|拡張機能名|モデルになっている作品orキャラ名|
|:---|:---|
|[Iron Man](https://marketplace.visualstudio.com/items?itemName=lintangwisesa.iron-man)|アイアンマン|
|[Captain America](https://marketplace.visualstudio.com/items?itemName=lintangwisesa.captain-america)|キャプテンアメリカ|
|[Theme Spider Man](https://marketplace.visualstudio.com/items?itemName=jundat95.spiderman)|スパイダーマン|
|[Joker Theme](https://marketplace.visualstudio.com/items?itemName=joker-theme.joker)|ジョーカー|
|[The Dark Knight](https://marketplace.visualstudio.com/items?itemName=VikasSharma.the-dark-knight)|バットマン(ダークナイト)|
|[Star Wars Theme](https://marketplace.visualstudio.com/items?itemName=NiravAgarwal.star-wars-theme)|スターウォーズ|
|[Hogwarts colors for VSCode](https://marketplace.visualstudio.com/items?itemName=CarloCardella.hogwarts-colors-dark)|ハリーポッターシリーズ|


誰もが一度は耳にしたことがあるようなビッグタイトルばかり揃っていますね！
マーベルやDCコミックスのファンにはかなり嬉しいラインナップになっているかと思いますし、そうでない方の中にもハリーポッターやスターウォーズのファンという方は多いと思います！是非試してみてください！


#国内作品

|拡張機能名|モデルになっている作品orキャラ名|
|:---|:---|
|[Dragon Ball Theme](https://marketplace.visualstudio.com/items?itemName=AdithyaKris.dragon-ball)|ドラゴンボール超|
|[Naruto Shippuden Themes](https://marketplace.visualstudio.com/items?itemName=PangzLab.naruto-shippuden-themes)|NARUTO -ナルト- 疾風伝|
|[Pikachu Theme](https://marketplace.visualstudio.com/items?itemName=milab.pikachu-theme-vscode)|ピカチュウ(ポケモン)|
|[Lucario](https://marketplace.visualstudio.com/items?itemName=Ikuyadeu.lucario&ssr=false#overview)|ルカリオ(ポケモン)|
|[Miku](https://marketplace.visualstudio.com/items?itemName=xenolithe.miku)|初音ミク|
|[kurama](https://marketplace.visualstudio.com/items?itemName=fomtarro.kurama)|蔵馬(幽☆遊☆白書)|
|[Hisoka Theme](https://marketplace.visualstudio.com/items?itemName=abidrah.hisoka-theme)|ヒソカ(HUNTER×HUNTER)|


正直、幽☆遊☆白書の蔵馬モデルまで拡張機能があったことに驚きました！
日本のアニメ作品は海外での人気もかなり高いですし、今後もっといろんな国内作品のThemeが増えるかもしれませんね！

#その他

ここからは、アニメや映画ではないですが需要がありそうな拡張機能をいくつか紹介できればと思います！

|拡張機能名|モデル名|
|:---|:---|
|[Nintendo Switch](https://marketplace.visualstudio.com/items?itemName=ArgyleInk.nintendo-switch)|任天堂スイッチ|
|[Xbox Theme](https://marketplace.visualstudio.com/items?itemName=hector-jimenez.xbox-theme)|Xbox|
|[Netflix Red theme](https://marketplace.visualstudio.com/items?itemName=MKY.netflix-red)|Netflix(動画配信サービス)|

ゲーム機をモデルとしたThemeまであることにびっくりしました！
ゲームを普段よくやられる方は是非試してみてはいかがでしょうか！


今回紹介したものは私個人が見つけることのできたものだけになっておりますので、他にも面白いThemeがまだまだあるかもしれません！
興味のある方は是非探してみてください！
Docker上のcomposer install時にメモリ不足をお手軽に解消する Tips

# 結論

```console
$ COMPOSER_MEMORY_LIMIT=-1 composer install
```
- COMPOSER_MEMORY_LIMIT=-1をオプションにつけて実行する

## 参照記事とか

[docker上のphpコンテナでcomposer installしたら、メモリ不足で落ちた話](https://qiita.com/K-taiga/items/6319077e414ac8e4d4b3)
を参照に、php.iniを編集しても問題はありませんでしたが、もっとお手軽な方法が。

```php.ini
  memory_limit = -1
```

## composerにはCOMPOSER_MEMORY_LIMITの環境変数が使える

```console
$ COMPOSER_MEMORY_LIMIT=-1 composer install
```

[composer updateでmemoryが足りない場合の対応方法 その2](https://polidog.jp/2018/12/14/composer/)
用語：「時刻」と「時間」の区別を調べた

こんにちは。
「時刻」と「時間」の用語の意味の区別を調べてみました[^1]。

- 時刻：時点のこと。時の流れのある一点（瞬間）のこと。
- 時間：時の経過の長さのこと。２つの時点の間の長さのこと。２つの時点の間（区間）のこと。

[^1]: 「時刻」と「時間」との区別は小学校での学習事項とのことです。
Python3: Starttls でメールの送信

hi-ho.ne.jp で試した方法です。

## プログラム

```py:hi-ho.py
#! /usr/bin/python
#
#	hi-ho.py
#
#						Jun/26/2023	
# --------------------------------------------------------------------
import	os
import	sys
import	socket
from dotenv import load_dotenv
import	email
from email.mime.text import MIMEText
from email.utils import formatdate
# --------------------------------------------------------------------
from send_starttls import send_starttls_proc
# --------------------------------------------------------------------
sys.stderr.write ("*** 開始 ***\n")
dotenv_path = '.env'
load_dotenv(dotenv_path)
mail = {}
mail['server'] = os.environ.get("SERVER")
mail['port'] = os.environ.get("PORT")
mail['usr'] = os.environ.get("USR")
mail['password'] = os.environ.get("PASSWORD")
mail['from'] = os.environ.get("FROM")
mail['to'] = os.environ.get("TO")


contents = 'Hello, Good Afternoon! on Jun/26/2023 from Hi-ho\n'
contents += 'Jun/26/2023 PM 13:34\n'
contents += 'こんにちは。\n'
contents += ' ' + socket.gethostname ()

message = MIMEText (
	contents,
	'plain',
)

message['Subject'] = 'Hello Jun/26/2023 from Hi-ho'
message['From'] = mail['from']
message['To'] = mail['to']
message['Date'] = formatdate ()

send_starttls_proc (mail,message)
#
sys.stderr.write ("*** 終了 ***\n")
# --------------------------------------------------------------------
```

```py:send_starttls.py
# -*- coding: utf-8 -*-
#
#	send_starttls.py
#
#						Jul/05/2020
# --------------------------------------------------------------------
import	sys
import	smtplib
# --------------------------------------------------------------------
# [6-4]:
def send_starttls_proc (mail,message):
	sys.stderr.write("*** send_starttls *** start ***\n")
	ss = smtplib.SMTP (mail['server'],mail['port'])
	ss.ehlo ()
	ss.starttls ()
	ss.ehlo ()
	ss.login (mail['usr'],mail['password'])
	ss.sendmail (
		mail['from'],
		[mail['to']],
		message.as_string (),
		)
	ss.close ()
#
	sys.stderr.write("*** send_starttls *** end ***\n")
# --------------------------------------------------------------------
```

```text:.env
SERVER = 'hi-ho.mose-mail.jp'
PORT = 587
USR = '****@hi-ho.ne.jp'
PASSWORD = '****'
FROM = '****@hi-ho.ne.jp'
TO = 'sample@example.com'
```

## 実行結果

```text
$ ./hi-ho.py 
*** 開始 ***
*** send_starttls *** start ***
*** send_starttls *** end ***
*** 終了 ***
```

## 確認したバージョン

```text
$ python --version
Python 3.13.2
```
Ubuntuに開発用のKubernetes環境を構築する

## Kubernetesの解説動画

弊社のYouTubeチャンネルで、CTOの @bunchan_k によるKubernetesの解説動画を公開を公開しています。

[REDIMPULZ Lab【レッドインパルス・ラボ】](
https://www.youtube.com/channel/UCdsCNxALP2nAJ_mLLlg3rFQ)

<a href="https://www.youtube.com/channel/UCdsCNxALP2nAJ_mLLlg3rFQ" target="_blank">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71453/00f140eb-7a5f-2051-83df-d486a0e0013a.png" width="300" />
</a>


僕もこの動画で勉強中ですが、UbuntuのKubernetes環境の構築手順が記載されていなかったので、
公式ドキュメント等を参考にして実践し、まとめてみました。


## kubectlのインストール

バイナリを設置する方法と、パッケージマネージャーからインストールする方法がある。
バージョン更新がしやすいように、パッケージマネージャー（apt）を使うことにする。


```bash
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
```


試していないが、snapでもインストール可能。

https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/

## minikubeのインストール

kubectlのインストールが事前に必要。

### ハイパーバイザーのインストールについて

通常、KVMやVirtualBoxなど、Kubernetesを実行するハイパーバイザー環境が必要になる。

> Minikubeは、VMではなくホストでKubernetesコンポーネントを実行する--vm-driver=noneオプションもサポートしています。 このドライバーを使用するには、DockerとLinux環境が必要ですが、ハイパーバイザーは不要です。

上記の通りなので、手元のUbuntuにはDockerもインストールされているため、ハイパーバイザーは使用しないことにする。


### Linux Homebrewからのminikubeのインストール

バイナリからのインストールや、パッケージを利用したインストールなど、いくつか方法がある。
特に、Linux Homebrewからのインストールが簡単そうだったので、こちらで行う。

#### Linux Homebrewのインストール
 
macの場合と同じ手順です。


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

パスを通しておきます。

```bash
echo 'eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)' >> /home/takaken/.bash_profile
```

#### minikubeのインストール

```bash
brew install minikube
```

これで完了です！

## あとがき

Ubuntuに開発用のKubernetes環境を構築できました。
他のLinuxディストリビューションを使っている方も、パッケージ管理を読み替えれば、同様の手順で構築できるかと思います。

これからは、動画を参考にLaravelやNodeアプリをK8sで実行する方法を勉強していく予定です。


## 参考サイト

* https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/
* https://kubernetes.io/ja/docs/setup/learning-environment/minikube/
Vue 3から素のemitが警告されるようになったので対処する

## 再現方法
親子関係のcomponentsにおいて、子から親に`emit`すること

## 警告の内容
`[Vue warn]: Extraneous non-emits event listeners (rewrite) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. 
If the listener is intended to be a component custom event listener only, declare it using the "emits" option.  at ...`

> コンポーネントがフラグメントまたはテキストのルートノードをレンダリングするため、外部の非エミッツイベントリスナー（書き換え）がコンポーネントに渡されましたが、自動的に継承することができませんでした。
リスナーがコンポーネントのカスタムイベントリスナーのみを意図している場合は、"emits "オプションを使用して宣言してください。
[翻訳] DeepL

## 結論
子（emitする側）のコンポーネントで`emits`オプションを定義した上で、emit名を配列で宣言する。
以下のESLintルールに詳しい。
https://eslint.vuejs.org/rules/require-explicit-emits.html
このルールが追加された背景としてはコンポーネントからどんなイベントがemitされるのかを構造的に宣言できるようにすることでコードの自己文書化をしよう！みたいな意図だと理解した。

## 詳細なコード
親で定義した`msg`変数を子のinputタグで書き換える単純なprops down, emits upの構成
### 親コンポーネント
```vuejs
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld :msg="msg" @rewrite="changeMsg" />
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'

export default defineComponent({
  name: 'App',
  components: {
    HelloWorld,
  },
  setup() {
    let msg = ref('Hello Vue 3.0 + Vite')
    const changeMsg = (e) => {
      msg.value = e.target.value
    }
    return {
      msg,
      changeMsg,
    }
  },
})
</script>
```

### 子コンポーネント
```vue
<template>
  <h1>{{ msg }}</h1>
  <button @click="count++">count is: {{ count }}</button>
  <p>
    Edit <code>components/HelloWorld.vue</code> to test hot module replacement.
  </p>
  <input type="text" :value="msg" @input="changeMsg" />
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
type Props = {
  msg: string
}
export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      default: 'default Value',
    },
  },
  emits: ['rewrite'], // このオプションが必要
  setup(props: Props, { emit }) {
    const count = ref(0)
    const changeMsg = (e) => {
      emit('rewrite', e)
    }
    return {
      count,
      changeMsg,
    }
  },
})
</script>

```

## 何が詰まったか
1. emitsオプションを定義すべきことは分かるが、どういった形式で宣言すべきか、また何を宣言すべきかのヒントが無い
2. 警告内容でググっても現時点ではこのルールそのもののPRしかヒットせず、どうすれば解決するかが掴めない（https://github.com/vuejs/vue-next/issues/1001）
3. 純粋にググラビリティが低く、`vue 3 emits option`等検索しても2.x時代のドキュメントが大量にヒットしてしまう

## というわけで
謎に詰まってしまった。。。
おもむろに親子間でemitするだけで警告されるので、2.x時代からVueを書いている方はお気をつけください。
縦持ちデータ(ロング型)を横持ちデータ(ワイド型)に変換したい

医療関連の企業に勤める友人から、大量のロング型データをワイド型データに変換したいって相談されました。
そちらの業界では、患者などのデータをワイド型で表すことが多いという。
そこで、変換ツールをpython作ったので記事にしました。

---
以下、変換イメージ

変換前

```sample
ID,data,item,
0,100,BPS,
0,200,LDL,
1,20,YBY,
2,XXX,YYY,
2,AAA,BBB,
```

変換後

```sample
ID　  YBY  BBB  BPS     LDL  YYY                              
0     N/A  N/A  100  　 200  N/A
1      20  N/A  N/A     N/A  N/A
2     N/A  AAA  N/A     N/A  XXX
```

---
そこで、pandasを利用してツールを作成しました。
作成したツールは以下になります。

```python
import pandas as pd
import csv

csv_file = open("sample.csv", "r",
                encoding="ms932", errors="", newline="")
f = csv.reader(csv_file, delimiter=",", doublequote=True,
               lineterminator="\r\n", quotechar='"', skipinitialspace=True)
columns = next(f)
data = []

for row in f:
    data.append(row)

df = pd.DataFrame(data, columns=columns)
df_t = df.pivot_table(values=[columns[1]], index=[columns[0]], columns=[
                      columns[2]], aggfunc='sum', fill_value='N/A')
df_t.to_excel('out.xlsx', index=True)
```

sample.csvを読み取って、ワイド型データに変換し、Excelに出力します。
前提として、csvの列は３つになっています。
IDごとに行を作成し、itemの項目が多いほど列が追加されます。そして、各値にdataが設定されます。もし、dataがなければN/Aが設定されます。

出力結果
<img width="458" alt="スクリーンショット 2020-07-05 13.26.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535251/4dd84826-7960-b7c9-a5f1-0734bbb0e29b.png">

CSVをロング型からワイド型に変換するしたい方がいましたら、こちらの実装を参考にしてください。
以下のGithubにもソースは載せています。
https://github.com/kurihiro0119/transform_wide_long
JavaのHashMapの中身を覗いてみた

[](https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/master/jdk/src/share/classes/java/util/HashMap.java)







JavaのHashMapの[ソースコード](https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/master/jdk/src/share/classes/java/util/HashMap.java)を読んで、hashのキーの比較が`equals()`で行われる`ことを確認した。

```java
    /**
     * Implements Map.get and related methods.
     *
     * @param hash hash for key
     * @param key the key
     * @return the node, or null if none
     */
    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;                            // 内部配列
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {                                // 内部配列の(hashCode/配列の長さの剰余)番目に収納されている要素(LinkedListの最初のNode)
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {                                                                 // LinkedListを順々に探索していく
                    if (e.hash == hash &&                                            // hashCodeが異なったら次のNodeへ(optimization目的)      
                        ((k = e.key) == key || (key != null && key.equals(k))))      // ここでequals()で比較!!!!!!
                        return e;
                } while ((e = e.next) != null);     
            }
        }
        return null;
    } 
```

探索中のオブジェクトと探索中のLinkedListの各Nodeの持つkeyのオブジェクトを、それぞれのequals()を用いて同意性比較していることが確認できた。



# 参考

- [Why HashMap insert new Node on index (n - 1) & hash?](https://stackoverflow.com/questions/27230938/why-hashmap-insert-new-node-on-index-n-1-hash)
    - `tab[(n - 1) & hash]`が(hashCode/配列の長さの剰余)になっていることの説明
- [Why does HashMap.put both compare hashes and test equality?](https://stackoverflow.com/questions/36100482/why-does-hashmap-put-both-compare-hashes-and-test-equality)
    - equals()で比較する前にhashCode()の値を比較しているのが最適化のためだということの説明
Pythonのディレクトリ操作まとめ

- 前提条件
    - 今自分がいるディレクトリは以下とする
        - /aaa/bbb/imakokoniiruyo/
    - ファイルの実行場所は以下とする
        - /ccc/ddd/jikkoufairudayo.py

- インポート

```
import os

```


- 現在の作業ディレクトリを取得
    - これはファイルの場所ではなく、現在自分がいるディレクトリを出力する

```
os.getcwd()

print(os.getcwd())
# /aaa/bbb/imakokoniiruyo/
```


- 実行中のファイルの場所を取得

```
print(__file__)
# /ccc/ddd/jikkoufairudayo.py
```

- 実行中のファイルのディレクトリを取得
    - os.path.dirname()を使う
        - 最後のスラッシュはつかない

```
print(os.path.dirname(__file__))
# /ccc/ddd
```

- 実行中のファイルのファイル名（最後のスラッシュ以下）を取得
    - os.path.basename()を使う
        - 頭にスラッシュはつかない

```
print(os.path.basename(__file__))
# jikkoufairudayo.py
```

- 上記メソッドはカレントディレクトリからの相対パスを表示している
- 絶対パスで表示したいなら
    - os.path.abspath()を使う
    - これは本番環境でも有効

```
print(os.path.abspath(__file__))
# /ccc/ddd
```


- 現在実行中のファイルがいるディレクトリに移動したいなら
    - os.chdir()を使う

```
print(os.getcwd())
# /aaa/bbb/imakokoniiruyo/
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print(os.getcwd())
# /ccc/ddd
```
早見表　手順書フォルダ

#前書き
早見表を集めることにする。
#コンテンツ
便利な早見表
##バックエンド
Java
https://www.edureka.co/blog/wp-content/uploads/2018/10/Java-CheatSheet_Edureka.pdf?utm_source=blog&utm_medium=cheat-sheet&utm_campaign=Core-Java-Cheat-Sheet-SC
SQL
https://cdn.sqltutorial.org/wp-content/uploads/2016/04/SQL-cheat-sheet.pdf
Linux
https://files.fosswire.com/2007/08/fwunixref.pdf
GIT
https://about.gitlab.com/images/press/git-cheat-sheet.pdf
##フロントエンド
Html
https://htmlcheatsheet.com/
CSS
https://htmlcheatsheet.com/css/
http://www.simplehtmlguide.com/csscheatsheet.php
JavaScript
https://htmlcheatsheet.com/js/
jQuery
https://htmlcheatsheet.com/jquery/
【AWS】EC2(AmazonLinux)にSSHできない場合に疑うポイント

# はじめに
EC2(AmazonLinux)にSSH接続できない場合に確認する点をざっくりまとめてみました。
※僕のわかる範囲になります。不足していたらすいません。

# 概要

- インターネットゲートウェイ確認
- ルートテーブルのサブネット関連付け確認
- 自動割り当てIPアドレス設定
- セキュリティグループ設定確認
- ネットワークACLの設定確認

※全てVPCダッシュボードでの確認になります。

## インターネットゲートウェイ確認

### インターネットゲートウェイ作成確認

インターネットゲートウェイが作成されているか？

<img width="1007" alt="スクリーンショット 2020-07-05 12.00.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/500d260a-5365-a9e5-0f69-0b3e446ac8ba.png">

### VPCと紐づいているか確認 

EC2インスタンスがあるVPCに紐づいているか？

<img width="785" alt="スクリーンショット 2020-07-05 12.01.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/1e6409ab-b74e-1d38-d9f4-50ce9999f179.png">


## ルートテーブルの設定確認

### ルート設定

ルートテーブルにインターネットゲートウェイが紐づいているか？

<img width="1082" alt="スクリーンショット 2020-07-05 12.26.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/7e884c6b-cec4-c66a-a6c0-f6fc4dfe868d.png">


### サブネット関連付け設定

EC2インスタンスがあるサブネットがルートテーブルに関連付けされているか確認。

<img width="1163" alt="スクリーンショット 2020-07-05 12.28.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/d6dd0118-6a27-dc23-bd1a-51b89596699d.png">



## 自動割り当てIPアドレス設定確認

①該当のサブネットを右クリックし、**自動割り当てIP設定の変更**をクリック。

<img width="431" alt="スクリーンショット 2020-07-05 12.17.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/f75cea7c-25e6-ec07-9dda-21510f5f1475.png">

②「IPv4の自動割り当て」に**☑️**を入れ、保存する。

<img width="782" alt="スクリーンショット 2020-07-05 12.17.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/5bb097aa-4b33-9a77-f388-c8da8060fb59.png">


## セキュリティグループ設定確認

SSHのルールを設定しているか？自分のPCからアクセスできるようになっているか？
※下記例の場合は、0.0.0.0/0とフルオープン状態にしております。

<img width="1267" alt="スクリーンショット 2020-07-05 12.33.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/38e21341-96a7-0468-1a9d-c96eba849536.png">

## ネットワークACL設定確認

サブネットに紐づいているネットワークACLの設定が、SSH接続を拒否する設定になっていないこと

<img width="1084" alt="スクリーンショット 2020-07-05 12.41.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/c6061956-bdce-3538-efd8-487e7ca20fb0.png">

# 所感

実際にEC2インスタンスに接続するためにVPC設定を実施しましたが、見るべき箇所が多いと感じています。
慣れないうちは、わかりづらいのかなと思いました。
githubの内容をローカルに持ってくる

# 1、ターミナルで該当のディレクトリに移動
```
$cd 【移動したいディレクトリ】
```

▼例えばデスクトップ配下の「sample」というフォルダの中に入れたい場合

```
$cd desktop/sample
```

# 2、クローンコマンドを打つ
```
$git clone 【持ってくるプロジェクトのURL】
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274063/ff3b6497-ae15-894b-44f2-965a6cfc9c18.png)

Githubパスワードを聞かれます、入れてください
Pythonで"整数の指定桁数以下を"切り下げる方法

#Pythonで整数の指定桁数以下を切り下げる方法

小数だと切り下げはmath.foor()がありますが、整数はどうするんだ？となったので投稿。


##実現したいこと

```
165886

#上記を100の位まで切り捨て(以下にしたい)て出力したい
165000
```


##コード

```
#元の数字を「切り捨てたい桁数のひとつ上を1に、それ以下を0にした数字」で除算した、商を出す
#商に「切り捨てたい桁数のひとつ上を1に、それ以下を0にした数字」を乗算する

#100のくらいの切り捨て(「〜数字」は1000となる)、また下のコードの()でくくったのが商
result = (165886 // 1000) * 1000
print(result)

#出力結果:165000
```


##最後に

考えたらすごく単純でした。
数学的要素があるからといって、すぐにライブラリやモジュールに頼りすぎずてはだめだなと。
少しは自分の頭使わないといけないなと実感しました。
「標準ライブラリにあるだろ」と思い込みずっと探して、最終的に自分で思いついたので反省しきりです。
Jenkinsで詰まったところメモ

<環境>
・MacBookPro13(2013)
・OS:Catalina(10.15.5)
・Jenkins 2.235.1
・Java 1.8.0_252(AdoptOpenJDK)

前提条件
・HomeBrewをインストールしていること
・Jenkins.warをDLしていること

# 問題発生
エラー、なんでやw

```
% java -jar jenkins.war 
7月 05, 2020 2:30:46 午前 Main verifyJavaVersion
重大: Running with Java class version 57 which is not in the list of supported versions: [52, 55]. Run with the --enable-future-java flag to enable such behavior. See https://jenkins.io/redirect/java-support/
java.lang.UnsupportedClassVersionError: 57.0
	at Main.verifyJavaVersion(Main.java:174)
	at Main.main(Main.java:142)

Jenkins requires Java versions [8, 11] but you are running with Java 13 from /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home
java.lang.UnsupportedClassVersionError: 57.0
	at Main.verifyJavaVersion(Main.java:174)
	at Main.main(Main.java:142)
```

# 解決策検索
こちらを参考にした
[JenkinsとOpenJDK 8とJava 11についての考察]
(https://qiita.com/ma2muratomonori/items/1774016dbcd4048ff7b8)


どうやらJenkinsは1.8で動作しないと動かない？
↓
JDK1.8をを探す→見つからないw
↓
HomeBrewにあった、入れる→Jenkins起動→いけた

# 解決策実行
```
// java入れるのに必要なコマンド
% brew tap homebrew/cask-versions
// javaを入れる
% brew cask install adoptopenjdk8
% /usr/libexec/java_home -V
/// 追加されとる
    1.8.0_252, x86_64:	"AdoptOpenJDK 8"	/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
```

```
// 使用するJavaを1.8へ、パス追加
***** Jenkins専用端末なので他のアプリケーションではこのバージョンは動作させない *****
***** 別のアプリーケーションでJavaを使用する場合はこの辺りの設定は変わってくると思います。 *****
% export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
```

```
// バージョン確認
% java -version                  
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.252-b09, mixed mode)
```

# 動作確認
```
Jenkins実行
% java -jar jenkins.war 
```

Jenkinsログイン

```
http://localhost:8080/
```

＜関連＞
[【Mac】Jenkins Pluginを使わずにipa自動ビルド環境を構築する]
(https://qiita.com/moca_uni/items/2215efea878f4fab60a5)
Gormのエンティティのiotaの扱い

## gormでiotaな型をモデルのフィールド値にしたい時

iotaのままモデルに突っ込めると定数で分岐できたり、変化球が突っ込まれることがなくなるのでiotaされている型をフィールドに定義したかった。

## 結論

iotaな型はゼロ値がnilとして扱われるので、gormのタグオプションの`not null`を指定してあげて、ゼロ値をnilでなく、0とさせる。またはiotaのスタートを1などにしてあげる。

↓1はじめ

```go
type Gender int

const (
    // Male is man
    Male Gender = 1 + iota // 1
    // Female is woman
    Female // 2
)
```

gormエンティティ

```go:user_info.go
// Gender is sex of human
type Gender int

const (
	// Male is man
	Male Gender = iota
	// Female is woman
	Female
)

type (
	// Info is detailed user information.
	UserInfo struct {
		common.BaseEntity // 独自定義。各エンティティの共通項を抜き出したもの
       // gormのタグオプション、not nullを指定すればok.
		Gender    Gender     `gorm:"type:tinyint(1);not null"` 
		Birthday  *time.Time `gorm:"type:datetime;default:null;"`
		LeaveDate *time.Time `gorm:"type:datetime;default:null;index:idx_leaveDate"`
	}
)
```

テーブル定義

```sql:user_infos.sql
-- mysql
CREATE TABLE `user_infos` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `deleted_at` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `gender` tinyint(1) NOT NULL,
  `birthday` datetime DEFAULT NULL,
  `leave_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_user_infos_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4;
```
AWSアカウント間でRDS Auroraを移行する方法　~ダウンタイム・データ欠損無し~

RDSの移管って結構難しいですよね。

しかもそれがダウンタイム、データ欠損なし、AWSアカウント超える場合なんかは特に...。

それに対するアプローチを公式ドキュメントを参考に実践しました。

同じ状況に直面した方はぜひ参考にしてください。

■ヘヴィメタルエンジニアリング(はてなブログ)
・AWSアカウント間でRDS Auroraを移行する方法
https://xkenshirou.hatenablog.com/entry/2020/07/12/110500
Ardour6のビルド

# Ubuntu StudioでArdour6.2.0をビルド

ビルド環境

- Ubuntu 20.04 LTS(Ubuntu Studio)
- Linux enoki 5.4.0-40-lowlatency #44-Ubuntu SMP PREEMPT Tue Jun 23 01:32:24 - UTC 2020 x86_64 x86_64 x86_64 GNU/Linux


(Ardour6.7.0もビルドできる事を確認した)
#aptで事前インストールを要するパッケージ

|パッケージ名|メモ|
|---|---|
|libasound2-dev|~~ALSA出力を有効にしてビルドする際に必要~~|
|libglib2.0-dev||
|libboost-all-dev||
|libglibmm-2.4-dev||
|libsndfile1-dev||
|libarchive-dev||
|liblo-dev||
|libtag1-dev||
|librubberband-dev||
|libfftw3-dev||
|libaubio-dev||
|libxml2-dev||
|liblrdf0-dev||
|libsamplerate0-dev||
|liblilv-dev||
|libgtkmm-2.4-dev||
|libjack-jackd2-dev|jack出力の際に必要|
|libsuil-dev|[LV2プラグインのGUI表示に必要(後述)](#1-Processor BoxでのLV2プラグインのGUI表示)|
|libdbus-1-dev|optional?|
|libeadline-dev|optional?|
|libusb-1.0-0-dev|optional?|
|libwebsockets-dev|optional?|
|libudev-dev|optional?|
|libcppunit-dev|optional?|
|libpulse-dev|optional?|
|build-essential|当たり前過ぎて書き漏らしていた模様|
|libcurl-dev|書き漏らしていた|
|vamp-plugin-sdk|書き漏らしていた|

ビルドの際にjackのみを使用するように明示的に指定しても、`libasound2-dev` は必要である。

#ビルド手順

```
$ cd ~/Ardour-6.2.0
$ ./waf configure --prefix=$HOME
$ ./waf build
$ ./waf install
```

##出力先ドライバ


必要な出力先のドライバを明示的に指定したいのであれば、以下のようにオプションを与える。
(jackのみを有効にしてビルドする例)

```
$ ./waf configure --with-backends=jack
```

##Processor BoxでのLV2プラグインのGUI表示
Mixer画面での各チャネルストリップのProcessor Box内でプラグインをダブルクリックした際、LV2プラグインが独自のGUIを実装していた場合にはそれが別ウィンドウで表示されるというのが正しい動作である(Ubuntu Studio 20.04のArdour5ではそのような動作になっている)
この機能は`LV2 UI embedding`と呼ばれているようであり、Ardourのビルド時に組み込まれているかどうかは、メニューを追えば確認できる。
`Help > About > Config` で表示されるテキストボックスに`LV2 UI embedding:`の列がある。
この値がTrueになっていればプラグインのGUIが使用可能であり、そのためには`libsuil-dev`の導入が必要である。

#使用感
~~動作が不安定な部分が見られる。~~

- ~~Ubuntu Studio 20.04標準でインストールされているArdour5ではスムースに再生できているプロジェクトを、今回ビルドしたArdour6で再生するとXRUNが発生する。~~
- Buffer sizeを大きめに取ればXRUNが改善するかと思ったが、サイズを変更した瞬間にsegmentation faultで終了してしまう。
- ~~ミキサー画面からLV2プラグインのパラメータを変更しようとしても、プラグインのGUIではなく汎用GUIが表示されてしまう。汎用GUIでは設定できない項目もあるので困る。~~

当初6.0.0をビルド・使用していたが、6.2.0が最新である事に気付き、ビルドし直した。
6.0.0でCPU負荷が高いと感じられる(アイドル時においてさえ！)という記事がArdourのフォーラムにも投稿されていたが、改善されている模様である。
バッファサイズ変更時にsegmentation faultが起こる問題は改善されていない模様。
Ruby on Rails コントローラ作成・削除コマンド

# コントローラ作成
コントローラを作成するコマンドは
**rails g controller コントローラ名（複数形、小文字）**

例：
```rails g controller posts```

コントローラ名のあとにアクション名を追加すると
ルーティング、アクション、ビューも同時に作成される。
**rails g controller コントローラ名 アクション1 アクション2 …**

例：
```rails g controller posts index new```
# コントローラ削除
コントローラを削除するコマンドは
**rails destroy controller コントローラ名**

例：
```rails destroy controller posts```

**※ destroyを省略してdと書くことは不可**
Nest.jsのアプリケーションをCloud Functionsにデプロイする

Nest.jsをCloud Functionsで動かすメモ。

まずはよく見かけるサンプルコード

```typescript
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as express from 'express';
import * as functions from 'firebase-functions';
import { AppModule } from './app.module';

const server = express();

(async () => {
  const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
  app.enableCors();
  return app.init();
})();

export const api = functions.https.onRequest(server);
```

Cloud Functionsはデプロイ時にエントリポイントとなるファイルを一度実行します。このとき、関数がexportされていなければCloud Functionsに認識されないので、このような形になったのでしょう。

しかしながら見てのとおりですが`NestFactory.create`や`app.init`は非同期関数（DIとかDB接続とかで時間かかるのかな？）なのでコールドスタート復帰後は最初のリクエストがNestの初期化前にExpressに渡されてしまうため、リクエストが処理できずに終わってしまいます。

これを回避するには、リクエストが来るたびに初期化が終わっているかを判断させる必要があります。結果、以下のような形になります。

```typescript
const applicationReady = (async () => {
  const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
  app.enableCors();
  return app.init();
})();

export const api = functions
  .region('asia-northeast1')
  .https.onRequest(async (...args) => {
    await applicationReady;
    server(...args);
  });
```

みんなPromiseが入った変数の命名規則どうしてるんだろう...。説明し辛い...。

Nest.jsみたいな大きいフレームワークをFaaSで動かすのどうかな？と思いましたがFaaSのメリットは大きいのでまあありかなと。Nestはそんなに重くないですしね。

Nest.js人気出てきてますがフレームワークが分厚くなりすぎるとRailsのような末路をたどってしまうので、少々怖いところではあります。
Unity オブジェクトをボタンから拡大縮小するときはOnClickでthis.transform.localScale = new Vector3(1, 1, 1);をしよう！

#やること
２分でオブジェクトを拡大するボタンを作る
#完成イメージ
ボタンを押す前
![スクリーンショット 2020-07-05 11.47.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/93382825-43b8-d805-c457-292a5c0cddb7.png)
ボタンを押した後
![スクリーンショット 2020-07-05 11.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/81eb480e-f3b8-558d-efd6-a39ec4efafb9.png)


#使用したバージョン
Unity 2019 3.14

#さっそくやってみる！
##スクリプトをつくろう！
名前はなんでもいいです。
私はScaleChengeというスクリプト名にしました。
##コードをかこう！
```c#:ScaleChange.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScaleChenge : MonoBehaviour
{
    void Start()
    {
        
    }

    public void OnClick()
    {
        this.transform.localScale = new Vector3(1, 1, 1);
    }
}
```
##スクリプトを拡大したいオブジェクトにアタッチしよう！
私の場合は、carparentにアタッチしました。
![スクリーンショット 2020-07-05 11.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/106c0c7c-0610-e352-317f-5d3791855413.png)

##ボタンをつくろう！
（ボタンの作り方は割愛します）
つくったボタンのインスペクター > Buttonに下の画像のようなOnClickという場所があるのでそこの左下のところに先ほどスクリプトをアタッチしたオブジェクトをつけましょう！

![スクリーンショット 2020-07-05 11.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/5e2f354e-15a6-9160-fac0-1612ba5c15f2.png)

すると、右側のところから選択できるので
ScaleChange(スクリプト名) > OnClickを選択しましょう！

これであとは再生ボタンをおして、ボタンをクリックすれば完成です！

#縮小したいとき
もう1つボタンをつくってあげて
スクリプト内の
Vector3(0.3,0.3,0.3)とかにしてあげれば縮小できると思います！
Apache2でcgiを機能させるまで

#環境
- WEBサーバー: Apache2
- OS       : Ubuntu

# cgiモジュールのインストール

cgidインストール

```shell
$ sudo apt install cgid
```
cgi設定の確認

```shell
$ cd /etc/apache2/conf-available
$ ls 
#serve-cgi-bin.confに設定が書いてある
harset.conf  localized-error-pages.conf  other-vhosts-access-log.conf  security.conf  serve-cgi-bin.conf
```

```shell:serve-cgi-bin.conf
<IfModule mod_alias.c>
        <IfModule mod_cgi.c>
                Define ENABLE_USR_LIB_CGI_BIN
        </IfModule>

        <IfModule mod_cgid.c>
                Define ENABLE_USR_LIB_CGI_BIN
        </IfModule>

        <IfDefine ENABLE_USR_LIB_CGI_BIN>
                #URLで/cgi-bin/以下のファイルが/usr/lib/cgi-bin配下のファイルと結びつく
                ScriptAlias /cgi-bin/ "/usr/lib/cgi-bin/"
                <Directory "/usr/lib/cgi-bin">
                        AllowOverride None
                        #+ExecCGIがオプションとして書かれているのでCGIが動く
                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                        Require all granted
　　　　　　　　　　　　　　 #.cgiの拡張子がつくファイルがcgiスクリプトが書かれているファイルであることを設定
                        AddHandler cgi-script .cgi
                </Directory>
        </IfDefine>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

```

#cgiファイルを設置

```shell
$ cd /usr/lib/cgi-bin
$ vi hello.cgi
```

```:hello.cgi
#!/bin/bash

echo "Content-Type: text/html;charset=utf-8\n"
echo ""
echo '<html><body>Hello cgi.</body></html>'
```

ファイルのパーミッションにて実行権限をつける

```
$ sudo chmod 755 hello.cgi
```
#確認
http://example.com/cgi-bin/hello.cgi

<img width="1400" alt="スクリーンショット 2020-07-05 11.47.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557018/4f44b2de-8e1b-c7b6-0075-1ac2e6d7758c.png">
【pandas】欠損補完しながら重複削除

# はじめに

pandasのデータフレームをあるkeyで重複削除する際、同一レコードだと判定されたレコード同士で欠損補完してから重複削除したい場合があります。

```python
import pandas as pd

df = pd.DataFrame({
    'building_name': ['Aビル', 'Aビ ル', None, 'Cビル', 'Bビル', None, 'Dビ ル'],
    'property_scale': ['large', 'large', , 'small', 'small', 'small', 'large'],
    'city_code': [1, 1, 1, 2, 1, 1, 1]
})
df
```


| building_name | property_scale | city_code |
|:--|:--|:--|
| Aビル | large | 1 |
| Aビル | large | 1 |
| None | small | 1 |
| Cビル | small | 2 |
| Bビル | small | 1 |
| None | small | 1 |
| Dビル | large | 1 |

## 補完+重複削除関数

```python
from pandas.core.frame import DataFrame

def drop_duplicates(df: DataFrame, subset: list, fillna: bool = False) -> DataFrame:
    """subsetをkeyに欠損補完してから重複削除.

    Args:
        df (DataFrame): 任意のデータフレーム
        subset (list): 重複削除するkey
        fillna (bool): 重複レコード同士で欠損補完するかどうか. default False.
    
    Returns:
        DataFrame

    """
    group_info = df.groupby(by=subset)
    new_df = pd.concat([
        group_info.get_group(group_name).fillna(method='bfill').fillna(method='ffill')
        for group_name
        in group_info.groups.keys()])
    new_df = new_df.drop_duplicates(subset=subset)
    return new_df
```

## 実行

```python
drop_duplicates(df, ['property_scale', 'city_code'], True)
```

| building_name | property_scale | city_code |
|:--|:--|:--|
| Aビル | large | 1 |
| Bビル | small | 1 |
| Cビル | small | 2 |