OmniAICreator/Qiita-1.07M huggingface dataset:
【Sequelize】configファイルで環境変数を使いたい

# sequelize-cli
```terminal
npm install --save-dev sequelize-cli
```
```terminal
npx sequelize-cli init
```

こうするとRubyのActiveRecord風にSequelize経由でdbを操作することができるようになる。また、`init`で生成された`config/config.json`からdbへの接続情報を指定することになる。

```json:config.json
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "postgres"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "postgres"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "postgres"
  }
}
```

でも、jsonにパスワードなどを直接記入するのは避け、`.env`を使いたいところ。


# .sequelizerc

そこで`.sequelizerc`の登場。
プロジェクトのルートで

```terminal
touch .sequelizerc
```

```js:.sequelizerc
const path = require('path');

module.exports = {
    'config': path.resolve('./config', 'config.js'),
};
```

そして、先程の`config.json`を`config.js`にリネームし、内容を下記に書き換える。

```js:config.js
module.exports = {
  development: {
    username: process.env.POSTGRES_USER,
    password: process.env.POSTGRES_PASSWORD,
    database: 'development',
    host: '127.0.0.1',
    dialect: 'postgres',
  },
}
```

このようにすることで、sequelizeのconfigに環境変数が利用できるようになった。


## 参考
Sequlize公式ドキュメント

https://sequelize.org/master/manual/migrations.html#the--code--sequelizerc--code--file
JavaScriptでHTML要素取得をした際の返り値の違い（HTMLCollection, NodeList）

## :popcorn:はじめに
JavaScriptでHTMLの要素を取得する方法はいくつかあります。
jQueryでは`$('セレクタ')`と書いて何も考えずに取得していたのに、生のJavaScriptでは少し気を使わないといけません！
今回は取得方法による違いを見ていき、取得方法の使い分けを簡単にまとめてみたいと思います。

## :popcorn:そもそもなんでHTML要素を取得したいの？
JavaScriptを使用する目的を簡潔にいうと**HTML(DOM)操作**をしたいからではないでしょうか?
そのためどの要素に対して(または基準として)操作をするか指定するために要素取得を行います。

```javascript:JavaScript
// classを追加したり
document.getElementById('hoge').classList.add('moge');

// 子要素を追加したり
const p = document.createElement("p");
p.textContent = 'こんにちは！';
document.querySelectorAll('.moge')[0].appendChild(p);
```

簡単な例ですが、
このようにJavaScriptの大通りにはHTML要素取得が必要となってきます。

## :popcorn:要素取得してみる
HTML要素取得の必要性がなんとなくわかったところで、HTML要素を取得する方法を何個か見ていきましょう!

こういうHTMLがあったとして

```html:HTML
<ul id="list">
  <li class="item">アイテム</li>
  <li class="item">アイテム</li>
  <li class="item">アイテム</li>
  <li class="item">アイテム</li>
</ul>
```

JavaScriptでよく見るHTML取得方法を試してみる

```javascript:JavaScript
document.getElementsByClassName('item');
// => HTMLCollection(4)

document.querySelectorAll('.item');
// => NodeList(4)

document.getElementById('list');
// => <ul id="list">...</ul>
```

取得は出来ているようですが、それぞれ返り値が違うようです（混乱）

## :popcorn:返り値の違い（HTMLCollection, NodeList）
さて本題です。それぞれの返り値を見ていきましょう！

### HTMLCollection

- Element(後述)が格納されている配列風オブジェクト（Array-Like Object）
    - 取得した要素数を格納しているlengthプロパティを持っている 
- オブジェクトに[index]または.item(index)メソッドを使用してElementを取り出せる
    - 取得する要素が一個しかない場合でも配列風オブジェクトで返ってくるので[0]で取り出す
    - 要素がなければlengthが0の空の配列風オブジェクトが返ってくる
- あくまで配列風なのでforEachは使えない
    - es6対応ブラウザならArray.from(配列風オブジェクト)で変換
    - es6未対応なら[].slice.call(配列風オブジェクト)で変換
    - 単純なforなら可能
- 取得したElementたちを動的に保持している
    - DOMの要素数の影響を受ける
    - 要素が4つの状態で取得後、同じ要素がDOM上で5つに増えたら取得したオブジェクトの中身も5つになっている
- 全体的にNodeListと似ている（詳しく調べられていませんが歴史的背景がありそう）

### NodeList

- Element(後述)が格納されている配列風オブジェクト（Array-Like Object）
    - 取得した要素数を格納しているlengthプロパティを持っている 
- オブジェクトに[index]または.item(indesx)メソッドを使用してElementを取り出せる
    - 取得する要素が一個しかない場合でも配列風オブジェクトで返ってくるので[0]で取り出す
    - 要素がなければlengthが0の空の配列風オブジェクトが返ってくる
    - 単純なforなら可能
- 配列風オブジェクトだがforEachは使用できる
    - IE11はバグでNodeListにforEachは使えないので、[].slice.call(配列風オブジェクト)で変換
- 取得したElementたちを静的に保持している
    - DOMの要素数の影響を受けない
    - 要素が4つの状態で取得後、同じ要素がDOM上で5つに増えても取得したオブジェクトの中身は4つのまま
- 全体的にHTMLCollectionと似ている（詳しく調べられていませんが歴史的背景がありそう）

### Element

- 要素のこと（呼び方が若干違うかもれないですがこの記事では`Element`と呼ぶ）
- 上の例で言うとgetElementById（'list'）で取得した`<ul id="list">...</ul>`
    - HTMLで書かれたものが返ってくるので馴染みやすい
- 要素がなければnull
- 配列風オブジェクトでforEachなど使わずにHTML要素を操作したい場合は最終的にElementを指定する
    - 例） 配列風オブジェクト[0]、配列風オブジェクト.item(4) 

## :popcorn:結局どれの取得方法を使えばいい？

### 全体像
- NodeList
    - querySelectorAll
- HTMLCollection
    - getElements* (getElementsByClassNameとかgetElementsByTagNameとか複数とることが前提のやつ)
- Element
    - getElementById
    - querySelector (一番はじめにヒットするものが取得できる)
    - 配列風オブジェクトをインデックス指定した時 (配列風オブジェクト[0]など)

### 使い分け
#### ◇HTML上に一つしかない要素を取得したい
Elementで取れればいいので`querySelector`
→CSSやjQueryみたいに**セレクタ**で指定できるからいいよね

#### ◇複数要素を取得したい
扱いやすい配列で取れればいいので`querySelectorAll`
→CSSやjQueryみたいに**セレクタ**で指定できるからいいよね
→NodeListなのでIE11でforEach使う場合は注意
→取得した値はDOMの変化に同期されないので注意。

#### ◇要素が増減するので動的に取得したい
HTMLCollectionで取れる`getElements*`
gitのあるコードがいつ追加/削除されたのか調べる


`git grep`だといつ追加されたかは分からないので困って調べてみました。
指定した文字列をコードに追加・削除したコミットのみを表示するオプションがありました。

```.shell
> git log -S 検索したい文字列
```

[Git の基本 - コミット履歴の閲覧](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E5%B1%A5%E6%AD%B4%E3%81%AE%E9%96%B2%E8%A6%A7)
Railsで架空のCafeのHPを作ってみよう!【14日目】『文字数が多い時のテストコード』編

#概要
基本Railsの記法に則り書いていきます！
１から全ての説明ではなく
その中であれ？どうやるの？と
疑問に思った点や実装に困った箇所を
ピックアップして紹介していきます♩

#設定と準備
・Rails
・HTML
・CSS
・Javascript(jQuery)

↑上記の言語とフレームワークを使い
架空(自分で考えたテキトーなもの)のCafeの
HPを作っていこうと思います！

#14日目の作業内容:round_pushpin:
・単体テストコードの実行

#14日目の気になった箇所:zap:
何百、何千字のある場合のテストコードはどのように
実行したらいいだろうか。

仮説:pushpin:
今まで自分が習ったテストコードの記述では

```spec/models/sample_spec.rb
it 'textが10字以上だと追加できない' do
  @sample.text = "1234567890"
  @menu.valid?
  expect(@sample.errors.full_messages).to include('textは9文字以内で入力してください') 
end
```
一部抜粋して書いています。

このようにダブルクォーテーションで囲い文字列にして指定の文字数を入力していたが
ここに何百時も何千時もい打ち込むのはめんどくさいし綺麗なコードとは言えない。
この文字列の部分を違う記述にすれば可能なはず。

#結論:star:
答えはとてもシンプルかつ簡単で

```spec/models/sample_spec.rb
it 'textが100字以上だと追加できない' do
  @sample.text = "a" * 100
  @menu.valid?
  expect(@sample.errors.full_messages).to include('textは99文字以内で入力してください') 
end
```
このように1文字を100回反映させるように
演算子を使えば可能！
1000字でも10000字でも同じ記述で簡単にできる！
SpringBootにおけるレイアウト

## 本日の内容
- レイアウト機能を用いて画面を構成するため必要な知識の備忘録
- Thymeleafのレイアウト機能を用いて完成させる
- 共通レイアウトとしてヘッダー、フッター、サイドバーを用意し、個別画面の内容を出力する
- レイアウト機能を利用した画面は保守性、拡張性に優れている

## 画面イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1715093/88ff2bc4-d581-8ec5-841d-9b0ec254697f.png)

# レイアウト画面について
- レイアウトのhtmlにレイアウトとして使用するという宣言をする
- ヘッダー、フッター、サイドバー、コンテンツのスペースを確保するイメージ

```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:fragment="layout(body)">
<head>
<meta charset="UTF-8">
<link th:href="@{/css/layout.css}" rel="stylesheet">
<title>Insert title here</title>
</head>
<body>
	<div th:replace="~{header::layout-header}"></div>
	<div>
		<div th:replace="~{sidebar::layout-sidebar}"></div>
		<div id="main" th:replace="${body}"></div>
	</div>
	<div th:replace="~{footer::layout-footer}"></div>
</body>
</html>
```

## テンプレートを実装するにあたって
- th:fragment属性を記述→このHTMLをテンプレートとして使用するという宣言
- fragment(フラグメント)→そのデータを識別する名前
- th:fragment="layout(body)"→layoutという名前を付けて、そのテンプレートに個別画面のbodyの内容を埋め込む
- th:replace属性→共通部品の埋め込み先となるタグを記述する
- <タグ名 th:replace=~{ファイルのパス名 :: フラグメント名}">で記述
- ファイルのパス名→templatesフォルダを起点としたファイル名(拡張子は除く)
- フラグメント名にはth:fragmentで設定した名前を記述
- コンテンツ画面を埋め込む場所にはth:replace="${取得する情報の範囲}"
- <div th:replace="${body}></duv>→コンテンツ画面のbodyの内容をうめこむ

## 共通部品(ヘッダー、フッター、サイドバー)にそれぞれ名前をつける
## ヘッダー
```html
<div id="header" th:fragment="layout-header">ヘッダー</div>
```

## フッター
```html
<div id="footer" th:fragment="layout-footer">フッター</div>
```

## サイドバー
```html
<div id="sidebar" th:fragment="layout-sidebar">サイドバー</div>
```
## コンテンツ画面(テンプレートのメインに埋め込む画面)
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	th:replace="~{layout::layout(~{::body/content()})}">
<head>
<meta charset="UTF-8">
<link th:href="@{/css/layout.css}" rel="stylesheet">
<title>Insert title here</title>
</head>
<body id="main">
	<div>コンテンツ内容</div>
</body>
</html>
```

- コンテンツ画面にはth:replace="~{テンプレートのパス::フラグメント名(~{::コンテンツ画面から取得される情報の範囲})}"のように記載をする
- th:replace="~{layout::layout(~{::body/content()})}"→layout.htmlに対して、コンテンツ画面(index.html)のbodyタグの内容を埋め込んでいる
- bodyの後の/content()はbodyタグ内のコンテンツを取得するという意味

# 装飾
```css
div#header {
	background-color: red;
	height: 100px;
}

div#sidebar {
	background-color: yellow;
	float: left;
	height: 300px;
	width: 200px;
}

div#main {
	float: left;
	height: 300px;
}

div#footer {
	background-color: green;
	clear: left;
	height: 100px;
}
```

## ふりかえり
- thymeleafの機能を利用すれば比較的観点にレイアウト機能を実装できる
- 一度レイアウトの枠組みを作ってしまえば、あとは個別のコンテンツ画面を作るだけでいいので、ページ作成の効率化になる
C言語　動かして理解するシグナル、プロセス間通信。sigactionの使い方

# はじめに

プロセス間通信を簡単な例で紹介します。
実行中のプロセスに対して、外部からシグナルを送信することで、セグフォを発生させて落とすプログラムを作成します。

**環境**

```
sw_vers
ProductName:    macOS
ProductVersion: 11.4
BuildVersion:   20F71
```

## Server (受信する側)

```c
int main()
{
	while (1);
	return 0;
}
```

### コンパイルしてバッググラウンドで起動

```
$ gcc server.c -o server
$ ./server &
[1] 14380 <- こんな感じで番号が出ます。
```

## Client (送信する側)

```c
#include <libc.h>

int main(int ac, char **av)
{
	(void)ac;
	kill((pid_t)atoi(av[1]), SIGSEGV);
	return 0;
}
```

killコマンドはシグナルを送る関数です。

### コンパイルしてシグナルを送る

serverをバッググラウンドで起動した際に出たプロセスIDを引数にして、実行

```
gcc client -o clinet
./clinet [PID_ID]
```

## 結果

serverプログラムがセグフォします。

```
[1]  + 14380 segmentation fault  ./server
```

これは、プロセスがSIGSEGVを渡されると、落ちるようにデフォルトで設計されているからです。

# 応用編

## sigactionを使ってシグナルから関数を起動

もっと複雑なことをやろうとするなら、sigaction関数を使って、シグナルが渡された際の挙動を自分で定義することも可能です。
プロセス間通信を使って思い通りの通信(動作)を実現しましょう。

データはbitなので、2つのシグナル、`0と1`になるものがあれば、あらゆるデータの送受信ができます。

## sigcation

sigactionを使用すれば、シグナルをトリガーにして、関数を起動できます。
sigactionは一度動かすとプロセス終了までずっと設定したシグナルをキャッチしてくれます。

詳しくは`man sigaction`を見てください。シグナル関係は環境によって設定がけっこう変わるので、環境に合わせて実装したほうが良いです。

私の場合は汎用性を持たせるために関数ポインタを渡して、設定できるようにしています。

```c
void	receiver(void handler(int, siginfo_t *, void *))
{
	struct sigaction	act;

	bzero(&act, sizeof(struct sigaction));
	act.sa_sigaction = handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;
	sigaction(SIGUSR1, &act, NULL);
	sigaction(SIGUSR2, &act, NULL);
}
```

お作法的な部分なのでさっくり説明します。

- bzeroで構造体の初期化
- sigemptysetでシグナルの初期化
- `act.sa_flags = SA_SIGINFO;`でhandler関数を使用する設定にする。
- sigactionは第一引数にどのシグナルをトリガーにするか設定します。複数のシグナルで同じ関数を動かすときには、上記のように複数回呼び出します。


## 連続してシグナルを送る場合のインターバルの設定

今回私の目的は、文字列をbitに変換し、プロセスに送ることなので、連続して何度もシグナルを送ります。

```c
void	send_char(pid_t pid, char c)
{
	int				bit;
	int				i;
	unsigned char	uc;

	uc = (unsigned char)c;
	i = 0;
	while (i < 8)
	{
		usleep(50);
		bit = (uc >> i) & 0x01;
		if (kill(pid, SIGUSR1 + bit) == -1)
			fatal("kill error");
		i++;
	}
}
```

どれくらいのインターバルを設定するべきか、という根拠は現状ありません。

usleep(50)くらいに設定しておくと、シグナル通信で送っているbitの情報に抜けが起こらなかったので、それを根拠に実装しています。

## まとめ

送信するシグナルの量を増やさない限り、bit抜けを検知できないのが難点です。
原始的なデータの送信方法を学べたので、今度はより高度な通信手段を見てみたいと思いました。
[Laravel8.x]APIResourceCollectionのResourceをカスタマイズする方法

# 公式ドキュメント

[Laravel 8.x Eloquent：APIリソース](https://readouble.com/laravel/8.x/ja/eloquent-resources.html)


# やりたいこと

API ResourceのCollectionで特定Resourceでパスワードなど不要な情報やEnumを文字列変換したデータを取得したい。
公式にはやり方が記載されていなかったので、実装例を残しておきます。


```json:Collectionの取得したいデータイメージ
{
    "data": [
        {
            "id": 1,
            "name": "佐々木",
            "status": "本登録",
        },
        {
            "id": 2,
            "name": "嘉納",
            "status": "退会",
        },
        {
            "id": 3,
            "name": "亜門",
            "status": "仮登録",
        },
    ],
    "count": 3,
    "statuses": {"1": "仮登録", "2": "本登録", "3": "退会"}
}
```

# サンプルコード

## Collectionクラス

**実装する時のポイント**
デフォルトだと`$this->collection`となっている。
指定したいResourceクラスのcollectionを使って呼び出す。
`UserResource::collection($this->collection)`

```php:UserCollection
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => UserResource::collection($this->collection),
            'count' => $this->collection->count(),
            'statuses' => UserStatusEnum::values(),
        ];
    }
}
```

## Resourceクラス

**実装する時のポイント**

`$this->`パラメータ名を指定して値が取得できます。
コード値の文字列変換や、必要なパラメータのみを定義することが出来ます。

```php:UserResource
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'status' => UserStatusEnum::description($this->status),
        ];
    }
}
```
Solidityのvirtualとoverrideキーワードの意味

virtualとoverrideはどちらもSolidity 0.6.0で追加されたキーワードで、
virtualは「この関数は後でオーバーライドしていいよ」
overrideは「この関数は前に定義した関数をオーバライドしてるよ」
という意味を表します。この二つはセットで使います。

例：

```solidity
contract Parent {
    uint u;
    function Test() public virtual{
        u = 1; 
    }
}

contract Child is Parent {
    function Test() public override{
        u = 2;
    }
}
```
sinatraでActiveRecordを使わずに掲示板アプリを作ってみた

# プロローグ

Rails今までやってきて、あまり基礎力というか、地力ついた感じしないんすけど、何やったらいいすかねーーー。。。ってruby-jpに相談したら、
https://github.com/ttanimichi/0ch#sinatra%E3%81%A7%E6%8E%B2%E7%A4%BA%E6%9D%BF%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86
この課題に取り組んでみてください。
とアドバイスをいって頂いた。
この課題を見てみると、ActiveRecordを使わずに、生SQLを書いて掲示板アプリを作るという指定があった。
そんなことやったことがないので、早速詰んだ。

```ruby
  def save
    validate
    DB.query("INSERT INTO posts (name, email, body, topic_id, created_at) VALUES ('#{@name}', '#{@email}', '#{@body}', '#{@topic_id}', NOW())")
  end

```
多分だけど、この生SQLを書けば、ActiveRecord使わずとも、データベースとやり取りができそう。
ActiveRecordのsaveメソッドがそこら辺をよしなにやってくれてたと思うと、そりゃ実力付かんわ。
と改めて反省。


# 

何はともあれ、ActiveRecordを使わずにデータベースを操作する練習をしなきゃならんので、

https://qiita.com/toshiro3/items/b65b2ad744d8f3ecc734
この記事をやってみることに。

この記事通りだとうまく行かないことあるので、
補足させていただくと

まず、CREATE DATABASE test;
を実行しないと、
create table test.languages (id int, name varchar(32));
これでエラー出るようです。

CHAR 型は指定した文字数以下の文字を格納した場合には文字列の末尾に空白を必要なだけ付け加えて指定の長さの文字列として格納します。ただし値を取得する場合は末尾にある空白は全て削除された上で取得されます。比較される時も同じです。

VARCHAR 型は末尾に空白を付けるようなことはしません。また現行のバージョンでは末尾に空白がある文字列であっても空白が付いたまま格納されます。取得する時も空白付きで取得しますが、 WHERE 句で比較する時だけ末尾の空白を削除した上で比較されます。

引数には、最大文字列を指定してるっぽい。


https://www.dbonline.jp/mysql/type/index3.html
引用

```ruby

require 'mysql2'

client = Mysql2::Client.new(:host => 'localhost', :user => 'root', :password => 'password')
query = %q{select user, host from test.languages}
results = client.query(query)
results.each do |row|
  puts "--------------------"
  row.each do |key, value|
    puts "#{key} => #{value}"
  end
end

```

これだとエラー出るので、

```ruby

require 'mysql2'


 query = %q{select *  from test.languages}

```

に変更。


てか、require 'mysql2'
って書いた時点で、mysql使えるのはしゅごい。
Macにmysqlをインストールしたからなのは分かってるけど。。。。
そこら辺を上手いこと参照してくれるのは驚き。
将来の成長した自分が、そこら辺の疑問点を解決してくれることを願って、先に進めよう。

あと

%q{}って記法がよく分からないので、調べてみると
https://qiita.com/mogulla3/items/46bb876391be07921743
>シングルクオートやダブルクオートのエスケープが不要になる。

うん、意味が分からん。
https://blog.senseshare.jp/escape.html
を参考にして説明すると、
> エスケープ処理とは、プログラムの中で使う特殊な記号を「ただの文字」として扱いたい時に行う処理です。

とありました。なるほど、なるほど。

次回はいよいよ

https://github.com/ttanimichi/0ch#sinatra%E3%81%A7%E6%8E%B2%E7%A4%BA%E6%9D%BF%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86
この課題のコードリーディングで基礎力や地力をつけていきたいと思います。



# [#2はこちらから](https://qiita.com/divclass123/items/290cd5d47c03dc73e60e)
AWS  Cloud Practitioner 合格記録

# この記事

AWS Cloud Practitionerを取得したため
CLFの試験を受けた記録を残します。

# about me
AWS業務を4年ほど行っています。

```
2019
Solution Architect Associate （7月）
SysOps Administrator Associate (9月)
Solution Architect Professional (11月)
Developer Associate (12月)
2020
DevOps Engineer Professional (3月)
Security Specialty（5月）
Advanced Networking(10月)
2021
Database Specialty（1月）
Data Analytics Specialty(6月)
Machine Learning Specialty(7月)
Cloud Practitioner(7月)
```

# 試験について

**公式ガイド**が最も有効です。
https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

# 推奨する学習方法

## 初級者向け

- AWSクラウドを利用することでどんなメリットが有るのか？

例：サンプル問題にあるような「責任共有モデル」「AWS クラウドの利点」

- どんな種類のサービスがあって、一言で言うと何ができるのか？

参考：試験ガイド下部「AWS のサービスと機能」

- **ひたすら問題集を解く**

問題を覚えるくらいの勢いで解くことをおすすめします。
https://aws.koiwaclub.com/


## 中級者以上向け

そんな方はあまりいないと思うのですが、なめてかかると本当に落ちると思います。
私は時間の都合で対策ができなかったのですが、スコアが思ってたよりも結構低かったです。。

主に２点気をつけたほうが良いかと思います。

**①分野ごとの主要サービスをもう一度把握する**

特に、いつも一部のAWSサービスしか使用していない方は
他のサービスに関する問題が来ると軒並み落とす可能性があります。

サンプル問題を見ればわかるのですが、VPC, EC2, RDSしか触らない方は
多分セキュリティ面や管理に使用できるサービスを学習したほうが良いと思います。

**②AWSが推奨するAWS Well-Architected フレームワーク**

具体的なAWSサービスがどうこうではなく、机上の話になります。
以下に、AWSでわかりやすいガイドが公開されておりますので、**復習しましょう**。
https://aws.amazon.com/jp/builders-flash/202101/awsgeek-well-architected/

# 結果とまとめ

スコアが想定よりも低かったですが、合格しました。
カバーしていなかった or 忘れていたサービスは覚えている範囲で復習しました。

これで、すべての**AWS Certificationコンプリート**となりました。
時間をかけてしまいましたが、とても良い学習のきっかけとなりました。

私は、資格取得をAWS学習のきっかけとして受けたので、
NetworkingからMachine Learningまで、幅広いサービスに触れることが出来てとても良かったです。

ストックしてあるAWSの検証したいことが結構あるので、Qiitaにもアウトプットしていこうと思います。

また、**資格は勉強すれば取れるんだなという自信**が持てました。

AWS資格に関しては、次の更新は**最難関であった**
Solutions Architect - Professional 
になるので、引き続き精進しようと思います。

ありがとうございました！
AWS  Machine Learning - Specialty 合格記録

# この記事

AWS機械学習分野の資格を取得したので、その学習記録を記します。

# about me

AWSを主軸として、インフラエンジニアに従事しております。
また、半年ほど機械学習エンジニア(イチから)に従事した経験はあります。

```
2019
Solution Architect Associate （7月）
SysOps Administrator Associate (9月)
Solution Architect Professional (11月)
Developer Associate (12月)
2020
DevOps Engineer Professional (3月)
Security Specialty（5月）
Advanced Networking(10月)
2021
Database Specialty（1月）
Data Analytics Specialty(6月)
Machine Learning Specialty(7月)
```

# 試験の特徴

まず正とする情報は、公式案内です。
https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/

この試験に挑む方の中には、きっと全く機械学習技術に触れたことのない方も、ある程度いらっしゃるのではないでしょうか。

サンプル問題をよく見ると、問題の中に「**機械学習の基礎知識がないと答えられない問題**」があることがわかります。

つまりある程度は、**AWSに関係ない機械学習自体のお勉強が必要になります**。


# （あくまで個人的な）学習方法例

目的が、概要理解と資格取得、その後の学習へのきっかけとする方を前提として記載します。

先に、機械学習にはどんなものなのか、大まかな流れと概要を理解します。
「どんな登場人物が出てくるのか？」「例えば何ができるのか？」「どんなデータを扱うのか？」「機械学習エンジニアは何をやるのか？」という観点で調べます。
たくさん出てきますが例えば以下のサイトがわかりやすかったです。
https://ledge.ai/machine-learning/

あとは今まで通り、問題集を解きます。
というのも、全く未知の分野を資格取得に向けて学習するには、問題集でわからなかった用語などから紐付けて学ぶことが間違いないと思います。
その際は必ず、基礎知識レベルで「ふーん、こんなものなのか」って感じたら**あまり長くとどまらず**戻ってくることをおすすめします。問題集が進まないことにより疲れてしまって、**モチベーションが下がることを防ぐため**です。


例えば、サンプル問題２番に「TF-IDFマトリックスの次元」とあります。

この用語は自然言語処理で扱う用語なので、始めはわからない場合がほとんどです。
まず用語を調べると「言語処理に使う」「文書の特徴抽出に使うもの」「実体はよくわからん数式？」ということがわかってきます。
素晴らしい解説サイトに出会うと理解の深度が変わりますが、ある程度（長くて５分くらい）で一旦問題集に戻ります。（良いサイトに出会えたら、メモを添えてブックマークはしておく）

このくらいの深度で拾っていくと、単語自体に馴染んでいけるので、問題が出た際になんとなく聞かれていることがわかってくるようになります。

**ただし、一部の問題はやはりそれでも全くわからん分野が出てきます。**
全然わからない問題に時間をかけるよりは、他の問題をカバーしたほうが効率が良いことが多いため、次に行きましょう。
判断の目安は、解いた問題集の中で後回しの問題が**15%**を超えたらアウトだと思います。

# 主に復習した内容

- 機械学習における、評価指標

以下が理解しやすいです。
https://www.codexa.net/ml-evaluation-cls/

「適合率」「再現率」「特異度」「AUC」など、問題をウィルス検査などの身近な話に置き換え、具体的に理解します。機械学習トレーニングでどんな学習結果になったときに、どの評価指標をどちら(大小)に改善すれば良いのか？を理解することが、実際MLエンジニアにとっては重要です。


- 扱うデータや課題の種類と、アルゴリズムの種類（対応）

以下が理解しやすいです。
https://ainow.ai/2019/11/26/180809/

分類をしたいのか、回帰予測をしたいのか？
用意したデータに正解ラベルがあるのか？
など、それぞれ解決手法＝アルゴリズムも異なるので、頭で紐付けをします。

- DataAnalytics範囲のAWSサービス

AWS Glue
Kinesis系
Amazon EMR
などの基本機能を復習

# 問題集

いつもどおり、こちらです。

https://aws.koiwaclub.com/


# 結果

時間が思ったほど取れなかったので２回目かと思いましたが、結果は8割で合格でした。

学習時間は20時間でしたが、スキマ時間をたくさん使ったので結構疲れが蓄積しました。

今回も、試験中一部は英語表記に直してから解きました。。

最後の資格となったCLFも取得しましたので、別途記録します。

ありがとうございました。

# 戦いの記録

SAA
https://qiita.com/shinon_uk/items/5525178bf98034676b2f

SOP
https://qiita.com/shinon_uk/items/e60bcb946b49bf5cabda

SAP
・勝利編
https://qiita.com/shinon_uk/items/c6b599d1cd3000e84d59
・敗走編（資料集め）
https://qiita.com/shinon_uk/items/ba839ba048ba439cc3ff

DVA
https://qiita.com/shinon_uk/items/8015953c792ef4bc7223

DOP
https://qiita.com/shinon_uk/items/5646d536e649b60b962a

SCS
https://qiita.com/shinon_uk/items/67fab096f9b85c47de55

ANS
https://qiita.com/shinon_uk/items/05f90e2ff6e9c9e732e8

DBS
https://qiita.com/shinon_uk/items/996edfa2ceab274c38cb

DAS
https://qiita.com/shinon_uk/items/b1d3510ee5fa452d91f1
【node.js】CSVファイル読込パッケージ「CSV Parser」・出力機能「CSV stringifier」の紹介およびコード例

## 背景

掲題モジュールを使えば「CSVを取得して読み込む時はカンマでsplitして…」といった面倒な処理から解放されたため、自身のメモ代わりに共有する。
二次元配列または連想配列の配列のように取得することができるため、肝心の実装に注力することができる。

## 公式ページ

### CSV Parser for Node.js
https://csv.js.org/parse/

### CSV stringifier for Node.js
https://csv.js.org/stringify/options/cast/

## csv-parse実装例

■元データ

```
A列, B列, C列
1, 2, 3
```

といったCSVファイルがあるとする。

```
const csvParseSync = require('csv-parse/lib/sync') // requiring sync module
const fs = require('fs')

let path = '/any/'
let filename = 'test.csv'
// ファイル読込。パスやファイルネームはここでは仮。
let buffer = fs.readFileSync(path + filename )
// CSV変換
let csvResult = csvParseSync(text)
// 結果出力
console.log(csvResult )
```

■出てくるであろう結果

```
[
  ['A列', 'B列', 'C列'],
  ['1', '2', '3']
]
```

上記のように二次元配列として取得できる。


## csv-stringify実装例

■元データ

```
[
  ['A列', 'B列', 'C列'],
  ['1', '2', '3']
]
```

上記のような二次元配列をCSV化したいとする。

```
const fs = require('fs')
const stringify = require('csv-stringify/lib/sync')

let outputArray = 
[
  ['A列', 'B列', 'C列'],
  ['1', '2', '3']
]

// 二次元配列をCSV向けテキスト化
let resultCSV = stringify(inputArray)

let path = '/any/'
let filename = 'test.csv'
// ファイル書込。パスやファイルネームはここでは仮。
fs.writeFileSync(path + filename , resultCSV )
```

■期待されるであろう結果

```
A列, B列, C列
1, 2, 3
```

上記のようなCSVを出力することができる。

## その他留意すべきこと

### sync（同期的）モジュールとasync（非同期的）モジュールがあることを理解する

本記事にて紹介している2機能とも同期的・非同期的モジュールがそれぞれ用意されている。
上記例にて用いている例がsync（同期）であるように、単純で使いやすいのはsync（同期）である。

公式（＋Google自動翻訳）では同期APIについて、以下のように書かれている。

> レコードの完全なデータセットを受け入れ、完全な結果セットを返します。
>
>これは、関数への通常の直接同期呼び出しを表します。レコードを渡すと、CSVテキストが返されます。単純であるため、スケーラビリティが不要で、データセットがメモリに収まる場合は、これが推奨されるアプローチです。

### optionを活用

要件や実装によっては、初期設定にてマッチしないケースが考えられるだろう。
その時はoptionを見て解決できないかを判断しても良い。
以下は便利だなと思ったオプションを一部紹介する。

* csv-parseのオプション：endoding

https://csv.js.org/parse/options/encoding/
bufferとなっているデータについて、encodingにもとづいて出力してくれる。
bom付きなども判定できる。

* csv-parseのオプション：relax_column_count

https://csv.js.org/parse/options/relax_column_count/
レコード間でフィールド数が一貫していない場合、許容するかどうかを設定できる。デフォルトはfalse。

* csv-stringifyのオプション：quoted_empty

https://csv.js.org/stringify/options/quoted_empty/
nullやundefinedを空文字に変換してくれる。

* 双方のモジュールにあるオプション：columns

https://csv.js.org/parse/options/columns/
二次元配列ではなく、連想配列の配列のように変換してくれる。列変更が楽になりそう。
ただし1行目が日本語ヘッダーの場合、連想配列のキーとしてはよろしくない可能性がある。

キー名が何かを明示的に設定した後、オプションfrom_lineと併用することが望ましいと考えられる。
https://csv.js.org/parse/options/from_line/
Elmerによる練習１：書籍『例題で極める非線形有限要素法』より--補足--

# はじめに
前回の投稿、[Elmerによる練習１：書籍『例題で極める非線形有限要素法』より](https://qiita.com/superrino130/items/ce61a8b24811d29139a9) で、６面体要素メッシュの結果が上手くいかなかったことの補足です。
# 振り返り
予想していた結果と異なったわけですが、むしろ良すぎた結果です。
きっと、せん断ロッキングがなかったのではないかと~~当てずっぽう~~
# Salome
![20210730b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/77a6c55b-28ce-864e-2aa0-3645c3b59ccf.png)
前回は、linear から quadratic に 変換していますので、今回は変換なしで解析します。
# 解析結果
![20210730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/87117974-f751-03a0-17cd-4f6ea6591818.png)
![20210730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/81f00161-6a18-0ebd-6b74-8af70d95df28.png)
![20210730a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/6f5f2a78-d195-3572-19ed-6a65ebef4a96.png)
![20210730a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/12c2de0c-cabe-d6d3-da75-fc728459bc79.png)
![20210730a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/5228042c-2d0e-9c56-f77a-7d5c01757766.png)
書籍の通り10要素が、1.34e-05 に近い値になりました。
Qiita諸先輩の記事 [Salome-Meca2019による練習１：書籍『例題で極める非線形有限要素法』より](https://qiita.com/Sagittarius_Chiron/items/75915bb2c4f58d11fe48) のグラフとも近い感じで、ヨシ！
# convert
convertの詳しい中身は、ここを見るとわかるかもしれません。

https://docs.salome-platform.org/8/gui/SMESH/tui_modifying_meshes.html#tui-quadratic
# まとめ
+ Elmer さんありがとう
+ Salome さんありがとう
+ 例題で極める非線形有限要素法 さんありがとう
+ S さんありがとう
The Cancer Genome Atlas(TCGA)からRNA-seqデータを一括ダウンロード

[PictBio HP「解析メモ」](https://www.pictbio.com/tips/3541.html) と同一内容です。
元記事：2021/7/30 公開 The Cancer Genome Atlas(TCGA)からRNA-seqデータを一括ダウンロードする

The Cancer Genome Atlas(TCGA)では膨大ながん関連遺伝子発現データや腫瘍画像データが公開されており、日々がん研究に役立てられています。

今回は、The Cancer Genome AtlasからRNA-seqの発現量データをLinuxコマンドで一括ダウンロードする方法を説明します。
まずは[The Cancer Genome Atlasのサイト](https://www.cancer.gov/about-nci/organization/ccg/research/structural-genomics/tcga)にアクセスして、下段にある「Access TCGA Data」から [検索ページ](https://portal.gdc.cancer.gov/)に飛びます。
![TCGA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/2957a448-f7ee-4558-ac50-bbc84a32a022.png)
図１、The Cancer Genome Atlasのトップページ

検索窓に「LUAD」(=Lung Adenocarcinoma、肺腺癌)と入力すると、登録されているLUAD関連サンプルの候補が表示されます。今回はTCGA-LUADを選択して検索します。
![TCGA検索画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/4be93af0-0844-019d-c5eb-73bb1300a9eb.png)
図２、TCGAの検索ページとLUADの入力した結果

検索するとTCGA-LUAD関連データ一覧が表示されるので、このうち右側の「Files」をクリックします。
![TCGA-LUAD検索結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/0b71e869-a083-1b51-b412-a064959dcccc.png)
図３、TCGA-LUAD関連データ一覧と、Filesボタン

左側のメニューにおいて「Experimental Strategy」で「RNA-seq」、「Workflow Type」で「FPKM」にチェックを入れると、RNA-seqの補正済み発現量カウントデータ(FPKM)のみに表示が自動で切り替わります。
![TCGA-LUADのFiles一覧.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/8f8f3d0d-c61e-5b25-9bce-3a6891eb580b.png)
図４、項目選択前
![TCGA-LUADのRNA-SeqとFPKMを選択後画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/4e90abeb-9ecc-8afa-9512-a740fd701966.png)
図５、「RNA-Seq」と「FPKM」を選択後の画面

選択されているファイルをダウンロードするためには「Add all files to Cart」ボタンを押し、画面右上のCartに追加されることを確認します。
![Add_all_files_to_the_Cart選択画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/226b4ea6-8b28-b591-41e7-28c3db3a4552.png)
図６、カートに追加する画面

右上のカートボタンを押して、カートの中身を確認します。
![カートからダウンロード.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1711036/0ab3ffaa-e2e8-d4da-f482-872322da948d.png)
図７、カートの中身とダウンロードボタン

カートにある「Download」→「Cart」ボタンから直接ダウンロードすることも可能です。今回はファイル数が多いので、手元のPCではなく直接Linuxサーバー(CentOSなど)に一括ダウンロードすることを考えます。

まずは図７にある「Download」→「Manifest」ボタンからManifestファイルをダウンロードしておきます。今回はダウンロードしたManifestファイル名を「gdc_sample_sheet_LUAD_htseq_fpkm.tsv」とします。このファイルの情報に基づいて後のダウンロードが行われるので、このファイルをLinuxサーバー側にscpコマンドなどで転送しておきます。

次にLinuxサーバーにgdc-clientツールをダウンロードします。

https://gdc.cancer.gov/access-data/gdc-data-transfer-tool

にアクセスし、下段にある [Linux用Binary](https://gdc.cancer.gov/files/public/file/gdc-client_v1.6.1_Ubuntu_x64.zip)をダウンロードします。

```
$ wget https://gdc.cancer.gov/files/public/file/gdc-client_v1.6.1_Ubuntu_x64.zip
```
ダウンロードしたzipフォルダーを解凍するとgdc-clientができるので、実行権限が無ければchmodで実行権限を与えます。

```
$ unzip gdc-client_v1.6.1_Ubuntu_x64.zip
$ chmod +x gdc-client
```

gdb-clientに先ほど転送しておいたManifestファイル-mで指定すればダウンロードが開始されます。-dで指定されるダウンロード先フォルダーはmkdirコマンドで事前に作成しておく必要があります。

```
$ ./gdb-client download -m gdc_sample_sheet_LUAD_htseq_fpkm.tsv  -d download_dir/
```

データが大きくダウンロードには時間がかかるので、nohup [コマンド] & を付けて実行することが推奨されます。

```
$ nohup ./gdc-client download -m gdc_sample_sheet_LUAD_htseq_fpkm.tsv  -d download_dir/ &
```
Stripeのsubscriptionsで `This customer has no attached payment source or default payment method.` エラーが出て決済処理ができない

## 背景
- StripeConnectを用いてプラットフォームを構築したかった

```js
     const result = await stripe.subscriptions.create({
          customer: customerId,
          items: [
            {
              price: priceId,
            },
          ],

          application_fee_percent: 10,
          transfer_data: {
            destination: connectAccountId,
          },
      }, {
          idempotencyKey: idempotencyKey,
      });
```

- こんな感じでサブスク決済を実行したかったが、決済処理が `This customer has no attached payment source or default payment method.` とのエラーがでて実行できない。

## 対応
- ストライプのAPIドキュメントを確認
  - https://stripe.com/docs/api/subscriptions/create#create_subscription-default_payment_method
  - subscriptionsのPOST APIのオプショナルパラメータで、default_payment_methodを設定できるらしいので、明示的に指定した。
  - 下記のような感じで。

```js
      const result = await stripe.subscriptions.create({
          customer: customerId,
          items: [
            {
              price: priceId,
            },
          ],
          // consumerのpayment_methodを取得してきて、明示的に指定した。
          default_payment_method: paymentMethodList.data[0].id,
          application_fee_percent: 10,
          transfer_data: {
            destination: connectAccountId,
          },
      }, {
          idempotencyKey: idempotencyKey,
      });
```

- 上記の対応で、無事APIが通って、サブスク課金を実装できました。

![スクリーンショット 2021-07-30 14.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116518/20fab8bd-0b01-6c7f-13a8-e2600af4cf62.png)


## 備考
> default_payment_method
> optional
> ID of the default payment method for the subscription. It must belong to the customer associated with the subscription. This takes precedence over default_source. If neither are set, invoices will use the customer’s invoice_settings.default_payment_method or default_source.

APIドキュメントに、 `customer` の `invoice_settings` の `default_payment_method` に設定しても同様のことができるよと記載があるのでそちらを設定した方がbetterなのかもしれない。
59日後にITパスポートを受けるFラン私大文系既卒(1日目)

# 学んだこと

* 企業活動：商品やサービスを作り、それをお客さんに売ること
* 日本の会社の形態には4つある
 * 株式会社
 * 合同会社
 * 合資会社
 * 合名会社
* 株式会社：株主からお金をもらって事業を運営する会社
* 経営者
* 社員
* 株主：会社にお金を出している人
* 経営理念：会社の存在意義
* ビジョン：会社が目指す将来の姿
* 経営戦略：ビジョンを実現するための具体的な行動計画
* 株主総会：株主が集まる会議、株式会社の最高意思決定期間
* CSR(Corporate Sosial Respnsibility)：社会的責任
 * グリーンIT：地球環境に優しいIT。ITを使って社会の省エネを推進し、環境を保護していくという考え方。
 * ダイバーシティ　(多様性)：様々な人材を活用することで生産性を高めようとする考え方。
 * ソーシャルビジネス：社会的課題を、ビジネスという手段で解決していく企業活動のこと
 * SDGs(Sustainable Development Goals)：持続可能な世界を実現するための17の国際目標。
* 経営資源は4つある。
 * ヒト
 * モノ
 * カネ
 * チエ
* HRM(Human Resource Management)：人的資材管理。ヒトを経営資源の一つと考え、人的資源を有効活用すること
 * 人は訓練や教育で価値を高めることができる
* OJT(On the Job Training)：実際の実務に応じた教育訓練2
* Off-JT(Off the Job Training)：仕事を離れて行われる教育訓練
* e-ラーニング：パソコンやインターネットなどのITを使った学習方法
* アダプティブラーニング：ITを用いて客観的データに基づいて、個人の習熟度や、苦手分野に適した(adaptive)学習内容を提供する教育手法である。
* 経営組織：ヒトの集まり。
* 組織形態：経営組織の形態(5つ)
 * 職能別組織：業務を専門的な機能に分けて、各機能を単位として構成する組織
 * 事業部制組織：事業部を単位として構成する組織
 * マトリックス組織：社員が職能部門と事業部門の両方に所属する組織
 * プロジェクト組織：問題解決のために専門家が集まった組織
 * 持ち株会社：子会社の株式を有する親会社
* テストに出てくる経営陣の役職名は2つ
 * CEO(Chief Executive Officer)：最終的な責任を負う役職
 * CIO(Chief Information Officer)：情報システムの総括をする役職
* パレード図：折れ線グラフと棒グラフが組み合わさったグラフ
* ヒストグラム：横軸が連続した項目の棒グラフ
* レーダチャート：放射状に現した図
* 散布図：2種類のデータの関係性を示す図
* 回帰分析：回帰直線を引いて、過去のデータを分析し、未来を予測する手法
* 期待値：確率的に決まる平均値
* ブレーンストーミング：複数で集まってアイディアを出し合う方法。ルールは4つ
 * 批判禁止
 * 質より量
 * 自由奔放
 * 便乗OK
* 損益分岐点：売り上げの額と費用の額が等しくなる売上高
* 売り上げ：商品やサービスを売って得たお金
* 費用：サービスや商品を売るために必要な費用
* 変動費：販売数に比例して増える費用
* 固定費：販売数に関係なく発生する費用
* 利益：売り上げから費用を差し引いた金額
* 財務諸表：ステークホルダーに対して、経営成績を報告するための書類。財務諸表は4つ。
 * 貸借対照表：ある時点の会社の全財産が記載された表。表の左右が釣り合っているからバランスシートとも言う。
 * 損益計算表：会社の利益が記載された書類
 * キャッシュフロー計算表：会社の現金の出し入れが記載された書類。キャッシュ(cash = 現金)、フロー(flow = 流れ)。会社のリスクを見つけられる。
 * 株主資本変動計算書
* 貸借対照表には3つの項目が記載される
 * 資産
 * 負債
 * 総資産
* 損益計算書に記載される用語13つ
 * 売上高：商品を売って得た金額
 * 売り上げ原価：商品を作るための費用
 * 売り上げ総利益：売上高 - 売り上げ原価
 * 販売費及び一般管理費：商品を販売・管理費(≒ 固定費)
 * 営業外収益：本業以外で稼いだ収益
 * 営業外費用：本業以外でかかった費用
 * 経常利益：営業利益 + 営業外収益 - 営業外費用。本業と副業を合わせた会社全体の競争力を知ることができる
 * 特別利益：特別利益。自社のビルを売って得たお金など
 * 特別損失：臨時の損失。地震、火災、裁判などで発生する損失
 * 税引前当期純利益：税金を引く前の会社の利益
 * 法人税等：税金を払うための費用
 * 当期純利益：全ての利益から、全ての費用を差引いた金額
*黒字倒産：売掛金を回収する前に借金が返せず倒産すること
* キャッシュフロー計算書の現金出入りの分類3つ
 * 営業活動によるキャッシュフロー：本業に関わるお金の残高を計算する
 * 投資活動によるキャッシュフロー：　設備投資や、株・債券の売買後の残高を計算する。
 * 財務活動によるキャッシュフロー： 資金調達に関するお金の残高(お金の貸し借り後の残高)を計算する
* ROE(Return On Equity)：自己資本利益率。会社が株主から集めたお金で、どれほど利益をあげたのかを表す指標。

```math
ROE = \frac{当期純利益}{自己資本}\\
```
 * 当期純利益：会社の最終的な利益
 * 株主から預かっているお金の総額
pythonでcsvファイルを読み込み表示させる

シンプルですが，単に，csvファイルを読み込み表示させるpythonプログラムです．

```python
import pandas as pd
#import matplotlib.pyplot as plt #もちろん，これはなくてもいいですね．．．
#import numpy as np　#もちろん，これもなくてもいいですね．．．
import csv


inp_file="C:\\Users\\name\Desktop\\nmea20210705\\2021-07-05_09_GNRMC.csv"
#ファイルがUTF-8なら
enc_sty="UTF-8"
#ファイルがshift_jisなら
# enc_sty="shift_jis"

with open(inp_file, "r", encoding=enc_sty, errors="", newline="" ) as f:
    lst = csv.reader(f, delimiter=",")
    # df = pd.DataFrame(lst).rename(columns={0:'ID',1:'time',2:'de',3:'lat',5:'lon',7:'knot',9:'date',12:'mode'})
    df = pd.DataFrame(lst)

# 読み込んだファイルを表示する
df

```
qiita-vim を使い始めた

[`qiita-vim`](https://github.com/mattn/qiita-vim) を使い始めました。

ためしたばかりなので、あまり感想を書けませんけれども、ちゃんと使えるようです。でも、ドキュメントが不足していて、インストールや設定の方法を探るのに苦労しました。[@_kazuyaさん](https://qiita.com/_kazuya)の[紹介記事](https://qiita.com/_kazuya/items/bf46271aeba97425d5e8)には助けられました。感謝します。

以下に紹介するのは `@_kazuya`さんの設定をさらに単純にした、Qiita への投稿機能に絞った設定です。`@_kazuya` さんの記事には Markdown の編集機能やプレビューの機能に関する設定も含まれているので参考になさるとよいかと思います。私は Markdown プロセッサとして Pandoc を使っているので、別な設定を使っています。

# 準備

Qiita にアクセスするための認証情報（個人用アクセストークン）を発行します。Qiita のサイトで「アカウント > アプリケーション」のページから発行できます。

# インストール

~~Qiita が配布している Python 用の API ([`qiita_v2`](https://pypi.org/project/qiita_v2/) と~~（7月30日21:17訂正；Python 用の API は使わずに Vim スクリプトで実装した webapi を使っているようです） NeoVim 用に [`mattn`](https://github.com/mattn) さんが提供する Vim パッケージ群 ([`mattn/qiita-vim`](https://github.com/mattn/qiita-vim), [`mattn/webapi-vim`](https://github.com/mattn/webapi-vim)) が必要です。

vim-plug の設定は以下のとおり。

~~~
Plug 'mattn/qiita-vim'
Plug 'mattn/webapi-vim'
~~~

# 記事のリストの表示

準備ができたら、NeoVim から `:Qiita -l` を実行すると自分が投稿した記事のリストが表示されます。


# 既存の記事の編集

適当に選ぶと、その記事の編集モードに入ります。編集した記事を保存 (`:w`) すると編集内容が Qiita に反映されます。


# 新しい記事の投稿とちょっぴり注意

新しい記事を投稿するときは、手元に Markdown ファイルを作成し、そこで `:Qiita` コマンドを実行すればよいようです。

以下はこの記事の書式です。（なにせ、Qiita に投稿するのも今日が始めてで）よくわかっていないので最低限の書式です。

~~~
qiita-vim を使い始めた
Vim:None 

本文はここに Markdown 書式で書く。
~~~

「既存の記事の編集」と同様に、記事を保存 (`:w`) すると、投稿されます。ただ、ここで注意があります。何ども保存すると、その都度、同じ標題の異なる記事が投稿されてしまいます。文章の編集中に指が勝手の `:w` してしまう人は注意しましょう。

たぶん、事前に Markdown 記事を完成してから `:Qiita` &amp; `:w` で投稿するのが正しいような気がします。

もしかして Qiita に草稿を保存する機能があって、qiita-vim がそれに対応していたなら、それを利用したいです。いかにもありそうだけど。

（2021-07-30 15:13 追記）Qiita には下書き保存の機能はありますが、`qiita-vim` は対応していないようです。Qiita で下書き保存しても `Qiita -l` で表示されませんでした。`qiita_v2` API では `QiitaClient.post` の `params` 引数に `private` （デフォルトは `False` なので公開）があって、`QiitaClient.list_items` も `params` 引数を取るので、下書きへのアクセス手段はあるようです。あとは `qiita-vim` の機能拡張か。


# 記事の削除

「新しい記事の投稿とちょっぴり注意」で書いたように、新規投稿すると誤って同じ内容の記事の複製を作ってしまうことがあります。無駄なものを削除するのは簡単です。記事のリストから削除したい記事を開き `:Qiita -d` するだけです。


# 設定ファイル

NeoVim で `:Qiita` を実行すると最初に認証情報の提供を求められました。この内容は `~/.qiita-vim` に保存され、次回以降は認証を求められなくなるようです。このファイルはテキスト形式で最初の行が Qiita のアカウント名、二行目が Qiita で取得したアクセストークンのようです。


# ヘルプ

NeoVim で `:help qiita-vim`

---
Qiita にはお世話になってきましたが、neovim から投稿できることがわかって、自分でもすこし恩返しをする気になってきました。
macでKHcoderを使えるようにした時に詰まったとこのメモ


仕事で使う必要が出てきたので環境構築した。その際に詰まったことのメモ

変なことしていなければ
https://qiita.com/Yomiyama1998/items/172ad392e1971e20e9ac
や
https://b.okadajp.org/2021/04/17/untitled/
を参考に進めれば大丈夫だと思う。

①cpanm Tk* がうまくいかない
https://qiita.com/Yomiyama1998/items/172ad392e1971e20e9ac
を参考に作業していたので、何も考えずにcpanm Tk*などと打っていたところエラー。
*を削除し、cpanm Tk としたら実行された

②cpanm Tkが上手くいかない
cpanm Tkを実行すると、C compiler cannot create executables~とエラー。
種々のライブラリ(gccやc++)の導入を試みたが何も変わらず。
https://qiita.com/DaikiSuyama/items/09f5aa399aad37783146
を参考に
```$ xcode-select -p
```
と打つと
```/Applications/Xcode.app/Contents/Developer```
と出てきたので、
```$ xcode-select -s /Library/Developer/CommandLineTools```
と打った後、再度cpanm Tkを試みたところ上手くいった。
kintoneの印刷画面で添付のPDFファイルを印刷する技

今回は、kintoneの印刷画面で添付のPDFファイルも印刷するカスタマイズです。
※DOM操作するので要注意！

完成イメージはこんな感じです。

<iframe width="480" height="360" src="https://www.youtube.com/embed/InAcu1ReiB4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


# アプリの準備

この記事のアプリをそのまま使います。

https://qiita.com/juri_don/private/dc9e5634fa6a4cea354a

# JavaScript

印刷画面に印刷ボタンを付けて、

```js
kintone.events.on(["app.record.print.show"], (event) => {

  const client = new KintoneRestAPIClient();
  const sp = kintone.app.record.getSpaceElement("sp");

  event.record.添付ファイル.value.forEach(async (f) => {
    if (f.name.indexOf(".pdf") !== -1) {
      const data = await client.file.downloadFile({
        fileKey: f.fileKey,
      });
      // pdfをダウンロードしてiframeにセット
      const b = new Blob([data], { type: "application/pdf" });
      const ifr = document.createElement("iframe");
      ifr.src = URL.createObjectURL(b);
      // iframeは見えないほうがいいかな？
      ifr.style.display = "none";
      sp?.appendChild(ifr);
    }
  });

  // 添付ファイルも印刷するボタンをつけよう。
  const msp = document.getElementsByClassName("print-header-gaia");
  const btn = new Kuc.Button({
    text: "レコードも添付PDFも印刷する",
    type: "submit",
  });
  msp[0].appendChild(btn);
  btn.addEventListener("click", (event) => {
    window.print();
    const ifrs = document.getElementsByTagName("iframe");
    // 一つ一つ印刷する
    ifrs.forEach((ifr) => {
      ifr.contentWindow?.print();
    });
  });
});
```
繰り返し（ループ）処理についてまとめてみた（つもり）

![E7hJexxVkAAMaZF.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293580/d5d18f00-6d3c-69b1-34b8-06f66293a93c.jpeg)
動画で全体的に解説しています
https://youtu.be/itxCzogV2QI
SwiftのProtocolとdelegateを理解する

# Protocolとdelegateの関係

`Protocol`と`delegate`の関係は密であり、`Protocalでdelegateを実装する`という関係です。

## delegateを知る

- `delegate`は使わなくてもいい
- メリット:クラス側に処理の内容を任せるのではなく、自分で処理を決めることができる。

## Protocolでdelegateを実装

```swift
protocol ButtonDelegate {
    func delegateClicked()
}
```

## delegateを変数として宣言

```swift
class Button {
    var delegate: ButtonDelegate?

    func clicked() {
        if let delegate = delegate {
            // 自分で実装した処理
            delegate.delegateClicked()
        } else {
            // 通常の処理
            print("クリックされました")
        }
    }
}
```
## Mainクラスを実装

ここから実際に`Main`クラスでの`delegate`の使い方を説明していきます。

冒頭で説明したように`delegate`は必ずしも必要なわけではないので、`Button`クラスで`delegate変数`を宣言しましたが、使用しない方法を説明していきます。

### delegateなしの場合

```swift
class Main {
    let button = Button()

    func clicked() {
        button.clicked()
    }
}

let main = Main()
main.clicked()  // 「クリックされました」とprintされる  
```

### delegateありの場合

`Class`は継承ですが、`Protocol`は適合といいます。



```swift
class MainWithDelegate : ButtonDelegate { // ButtonDelegateを適合
    let button = Button()

    init() {
        button.delegate = self // delegateをインスタンス化
    }

    func clicked() {
        button.clicked()
    }

    // 自前でdelegateClicked()を実装
    // Protocolを適合したので、ButtonDelegate内で宣言された関数の処理を実装しないとコンパイルエラーになる
    // deletgateClicked()はButton.Click()時に呼ばれる
    func delegateClicked() { 
        print("クリックされたよー")
    }
}

let mainWithDelegate = MainWithDelegate ()
mainWithDelegate.clicked() // 「クリックされたよー」とprintされる
```

## delegateのポイント

`delegate`で実装した関数は自分で呼び出すわけではない
今回の例では、勝手に`clicked()`関数が呼び出している。なので実装しておしまいです。呼び出す必要はありません。

## 別の例

Figureクラスを使いたいが`getArea()`が通常の処理では、横×縦の値が返ってくるが、それを2倍にする処理にしたい


```swift
protocol FigureDelegate {
    func getAreaDelegate() -> Int
}

class Figure {
    var delegate : FigureDelegate?

    let width : Int
    let height : Int

    init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }

    func getArea() -> Int {
        if let delegate = delegate {
            return delegate.getAreaDelegate()
        }
        else {
            return self.width * self.height
        }
    }
}

class Main : FigureDelegate {
    let figure = Figure(width: 5, height: 7)

    func setDelegate() {
        figure.delegate = self
    }

    func printArea() {
        print(figure.getArea())
    }

    func getAreaDelegate() -> Int {
        return self.figure.width * self.figure.height * 2
    }
}

let main = Main()

main.printArea()

main.setDelegate()
main.printArea()
```
PyCharmでjupyterのデバッグを行う方法

## はじめに
有料版Pycharm (月額2,290円、学生は無料) には、jupyterファイルのデバッグを行う機能がありますが、デバッグを行う上で少し引っかかった場所があったためメモします。

## 機能

jupyterの機能に加えて、変数の値やインスタンスの中身を一覧で見ることができたり、ブレークポイントを設定してデバッグを行うことができます。（jupyterにも拡張機能の`Variable Inspector`で変数の値の一覧を表示したり`import pdb; pdb.set_trace()`でデバッグする機能もありますが、とても簡易的なものです。）

少し見づらいですが、実行画面はこのようになります。左にコードやマークダウンを記述して、右側に結果が出力されます。そして、下側にすべての変数が一覧表示されています。
![スクリーンショット 2021-07-30 12.13.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/4297cbc2-84bc-e722-429b-4cffbd623c1f.png)



## 詰まったところ

デバッグを行うとき、普通の`.py`ファイルと同じように`Debug Configurations`を設定して虫アイコンをクリックしていたのですが、`NameError`が出ました。エラーをコピペして調べてみても全然ヒットしません。

ドキュメントを読んで確かめると、`Debug Configurations`は必要なく、jupyterセルの三角アイコンをクリックして表示される虫アイコンをクリックするとデバッグができることが分かりました。

![スクリーンショット 2021-07-30 12.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/e4c18547-36e2-c45f-b8f0-64a9c20c40eb.png)

## おわりに
jupyterは変数の値をキャッシュして扱いやすいですが、デバッグしづらいことが欠点だと思います。PyCharmを用いると、この欠点を補うことができるので便利です。
【php】配列の中身の0と空要素を削除する ※array_filter()を使う

処理時間:1758ナノ秒

```PHP
<?php

$arr =  [1,2,3,'あああ','00456','123abc',-3,0,0,0,''];

$start = hrtime(true); // 計測開始時間

$arr = array_filter($arr);

$end = hrtime(true); 
echo '処理時間:'.($end - $start).'ナノ秒';

var_dump($arr);

?>
```

もしくは

処理時間:6726ナノ秒

```PHP
<?php
$arrs =  [1,2,3,'あああ','00456','123abc',-3,0,0,0,''];

$start = hrtime(true); // 計測開始時間

foreach($arrs as $arr ){

    if(!empty($arr)){

        $result[] = $arr;
    };
};

$end = hrtime(true); 
echo '処理時間:'.($end - $start).'ナノ秒';

var_dump($result);
?>
```






出力結果

```
array(7) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  string(9) "あああ"
  [4]=>
  string(5) "00456"
  [5]=>
  string(6) "123abc"
  [6]=>
  int(-3)
}
```
STM32F446RE NUCLEO (PlatformIO+VSCode)でSeeed SDカードシールドを使う

STM32F446RE NUCLEOボードを使ってArduino開発環境でグラフ作成プログラムを開発中ですが、グラフデータなどを保存するためにSDカードを接続しました。
使えるSDカードはいろいろありますがSeeedのSDカードシールドを使いました。
　※ これを使うとマイコンボードにシールドを挿入するだけでSDカードに読み書きできます。(ただし、マイコンボードのリセットボタンが押しにくくなります)
![Seeed SD Card on stm32f446re.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1824458/e85788d0-c4d0-26b8-13f6-406e31895b32.jpeg)


その際に注意することが２つありました。

【注意点１】　SDカードシールドの裏面にあるランドで３つ(CLK,DI,DO)の信号の配線を変更します。

　<説明>　STM32F446RE NUCLEOボードはICSPソケットが搭載されていないためシールドの配線を変更する必要があります。SDカードシールド裏面にあるランドのディフォルトの配線をナイフなどで３個所切断してからハンダでブリッジして配線し直します。(切断するときにランド間にある配線も切断しないように注意してください)
![Seeed SD Card rear.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1824458/9c6d0e99-8c09-403c-3fad-95790ae3e908.jpeg)

【注意点２】　付加されていたSDライブラリを削除したのち、新たに正しいSDライブラリを付け足します。

　<説明>　このプログラムはAdafruit_GFX.hとAdafruit_HX8357.hライブラリを使用しており、それらのライブラリをプログラムに付加したときにSDライブラリも一緒に付加されていたようです。しかしこの一緒に付加されていたSDライブラリはArduino開発環境用のものではなかったようでコンパイル時にエラーとなりました。(Mbed用?)

　対処方法は下のとおりです。

　<方法>　PlatformIOのこのプログラムのフォルダーにある".pio>libdeps\nucleo f446re>SD"ディレクトリにある"src>utility"ディレクトリ内のSd2Card.cppファイルがエラーになりました。
　そこでSDディレクトリ以下を削除した後で新たにPlatformIOのホームからLibrariesボタンを押してArduino標準の(Arduinoから提供されている)SDライブラリを付加します。
![Seeed SD Card sd library.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1824458/4bfe3424-b04a-ffad-c702-1bd838d81cd2.jpeg)
正しいSDライブラリをプロジェクトに付加します。
![Seeed SD Card new sd library.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1824458/80f5df0f-2e09-673c-c5c7-a33c26b09b1e.jpeg)

　上記の対処により、正常にコンパイルが終了してSDカードの読み書きができることを確認しました。
【PHP】配列の中身をintに置き換える



```PHP
<?php

$arr =  [1,2,3,'あああ','00456','123abc',-3,' '];

$arr = array_map('intval', $arr);

var_dump($arr);



function convertArrayValues($array) {
    foreach ($array as $key => $value) {
        if (is_numeric($value)) {
            $array[$key] = (int)$value;
        } else if (is_string($value)) {
            $array[$key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
        }
    }
    return $array;
}

// 使用例
$array = ['1', '2', 'hello', '3', '<script>alert("xss");</script>','1a',0 ];
$result = convertArrayValues($array);

print_r($result);


function convertArrayValues($array) {
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $array[$key] = convertArrayValues($value);
        } else if (is_numeric($value) && $value !== '0') {
            $array[$key] = (int)$value;
        } else if (is_string($value)) {
            $array[$key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
        }
    }
    return $array;
}

// 使用例
$array = ['1', '2', 'hello', '3', '<script>alert("xss");</script>', '0', ['4', '5', '<img src="x">']];
$result = convertArrayValues($array);

print_r($result);


?>
```

#出力結果

```
array(8) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(0)←あああ
  [4]=>
  int(456)←00456
  [5]=>
  int(123)←123abc
  [6]=>
  int(-3)
}
```
セッションマネージャーを経由したリモートRDSへのアクセス方法

# 概要
プライベートサブネット内の Amazon RDS や Amazon Aurora のアクセス方法で困ったことないですか？
ローカルのクライアントツールからリモートの DB へ EC2 の踏み台サーバ経由でアクセスする方法です。

今回、実現する方法にはセッションマネージャーが必要ですので、予め設定しておきましょう。

# 動作環境
踏み台サーバ: AmazonLinux2
リモートDB: RDS or Aurora
ローカル: Mac

# 前提
- ローカル環境にセッションマネージャーのインストール  
[Session Manager プラグインを macOS にインストールおよびアンインストールする](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#install-plugin-macos)
- EC2 にセッションマネージャーからのアクセスを許可するロールを付与  
[Systems Manager セッションマネージャを使ったら SSH 管理不要になった](https://qiita.com/syoimin/items/6f5f0aca002161d40233#%E5%B0%8E%E5%85%A5%E6%96%B9%E6%B3%95)
- EC2 にローカル環境からアクセスできるように ec2-user の公開鍵を登録
- 予め接続したい AWS アカウントへの AWS CLI とプロファイルの設定をしておく


# SSH Config の設定内容
上記の前提の設定が完了したら、ポートフォワードするための SSH の Config を設定します。

```config:~/.ssh/config
host <ホスト名>
    HostName <インスタンスID>
    Port 22
    User ec2-user
    ServerAliveInterval 300
    IdentityFile ~/.ssh/id_rsa.pem
    LocalForward 33306 <リモートホスト RDS or Aurora>:3306
    ProxyCommand sh -c "env PATH=/usr/local/bin:$PATH aws ssm start-session --profile <プロファイル名> --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

注目するところは下記です。

```config
 LocalForward 33306 <リモートホスト RDS or Aurora>:3306
```
ここでは、ローカルポートに `33306` 番ポートを開けて、そこへのアクセスを SSH 経由で最終的に、リモートホストの DB: `3306` 番ポートへアクセスを流しています。

また、下記の設定で、セッションマネージャー経由で EC2 へアクセスを行ってます。
セッションマネージャー経由なので EC2 には 22 番ポートのセキュリティグループを開ける必要はありません。

```config 
    ProxyCommand sh -c "env PATH=/usr/local/bin:$PATH aws ssm start-session --profile <プロファイル名> --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

# SSH 接続
事前にポートフォワーディング用に SSH を接続しておきます。 `~/.ssh/config` で設定したホスト先（踏み台サーバ）にコネクションを貼りましょう。

```sh
ssh <ホスト名>
```

踏み台サーバへ SSH アクセスができていれば成功です。SSH のセッションが生きてる間は、ポートフォワーディングできる状態になっています。DB クライアントツールの作業中は常に SSH 接続を維持しておきましょう。

# DB クライアントツールの接続情報
上記設定が完了したら、後は DB クライアントツールから接続します。

Connection Method は `TCP/IP` で接続
Hostname: は `localhost`
Port: はポートフォワーディング元の `33306` を指定

あとは、DBのユーザ、パスワード、DBスキーマを設定すると接続が成功します。

![スクリーンショット 2021-07-30 12.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175476/5aabf8a7-a65c-5535-f30f-3b84818081f2.png)

# まとめ
AWS では、リモート環境でかつプライベートなDBへのアクセスには現状踏み台サーバを経由してアクセスするしか方法がありません。
その際に、毎度接続方法を忘れてしまうのでまとめました。

誰かにためになれたら幸いですm(_ _)m

# あとがき
以前投稿した下記記事の改良版になっております。
ポートフォワーディング部分のネットワーク図などを見たい方は参考にしてください。
[セッションマネージャー over SSH 経由でプライベートサブネット内のRDSへ接続する方法](https://qiita.com/syoimin/items/eb6d4d9e01f460623531)