OmniAICreator/Qiita-1.07M huggingface dataset:
【JMH】JMH Gradle PluginでExecution failed for task ':jmhRunBytecodeGenerator'. java.lang.NullPointerException...となって実行が失敗する場合の対処【Gradle】

`JMH Gradle Plugin`（`me.champeau.gradle.jmh`）で、以下のようなスタックトレースが出て実行が失敗する場合への対処法です。

```bash
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':jmhRunBytecodeGenerator'.
> A failure occurred while executing me.champeau.gradle.JmhBytecodeGeneratorRunnable
   > Generation of JMH bytecode failed with 1 errors:
       - Annotation generator had thrown the exception.
     java.lang.NullPointerException
        ...
```

自分は以下の`build.gradle.kts`でプロジェクトをやっていましたが、`group = "com.wrongwrong"`としているのに、ベンチマークが`com.wrongwrong`パッケージ配下に無かったことが原因でした。

```kotlin:build.gradle.kts
plugins {
    kotlin("jvm") version "1.4.10"
    id("me.champeau.gradle.jmh") version "0.5.2"
}

group = "com.wrongwrong"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))

    implementation(group = "org.openjdk.jmh", name = "jmh-core", version = "1.25.2")
}
```

上手くいっていなかった時の配置は以下の通りでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/3a3675e7-a8dd-b7af-5aa1-8fe23966def9.png)
以下のように配置することで上手くいきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/957b1994-3e94-eaaf-5465-8d2a3acd2af9.png)
以下のように、子パッケージに配置した場合も上手くいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/5897f209-d7c1-7626-f99f-bf2377e80447.png)
【Vue.js】動的に数が変わる複数フォームの入力バインディング

# 概要

フォームが複数ある場合に、入力バインディングする方法をまとめました。
基本的な内容ですが、備忘録も兼ねて初心者の方向けに書きたいと思います。

# 課題
例えば、フォームの数が固定されている場合は、各フォームに対応する分だけdataオブジェクトにプロパティを用意することで実装できます。
しかし、フォーム数が動的に変わる場合は、フォーム数に応じてdataオブジェクトにプロパティを追加する必要があるので面倒です。

また、プロパティ数が多いのは見栄えが悪いです。

```vuejs:フォーム数が固定されている場合
<template>
  <div>
    <!-- ループ数固定でv-forを使った場合 -->
    <div v-for="n in 3" :key="n">
      <input type="checkbox" :value="n" v-model="$data[`hoge${n}`]" />
      チェックボックス{{ n }}
    </div>

　　<!-- べた書きした場合 -->
    <div>
      <input type="checkbox" value="4" v-model="hoge4" />
      チェックボックス4
    </div>
    <div>
      <input type="checkbox" value="5" v-model="hoge5" />
      チェックボックス5
    </div>
    <div>
      <input type="checkbox" value="6" v-model="hoge6" />
      チェックボックス6
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge1: undefined,
      hoge2: undefined,
      hoge3: undefined,
      hoge4: undefined,
      hoge5: undefined,
      hoge6: undefined
    }
  }
}
</script>
```

# 解決方法

解決法としては、dataオブジェクトに一つのプロパティを用意し、配列の要素として入力バインディングしていきます。

## チェックボックスの場合

dataオブジェクトのプロパティとしてhogeを用意し、初期値を配列にしておきます。
v-modelにはhogeを指定します。

```vuejs
<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      <input type="checkbox" v-model="hoge" />
      チェックボックス{{ n }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], // チェックを付けるごとに順に要素が追加される。（例）[1,3]
      loop: 3
    }
  }
}
</script>
```

## ラジオボタンの場合

dataオブジェクトのプロパティとして`hoge`を用意し、`v-model`には`hoge[n - 1]`を指定します。
配列の要素ごとにフォームを対応付けます。

```vuejs
<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      ラジオボタン{{ n }}
      <input type="radio" :name="'name' + n" value="A" v-model="hoge[n - 1]" />A
      <input type="radio" :name="'name' + n" value="B" v-model="hoge[n - 1]" />B
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], //（例）上から順にフォームに「A」「B」「A」を選択すると、["A","B","A"]
      loop: 3
    }
  }
}
</script>
```

## テキストフィールドの場合

dataオブジェクトのプロパティとして`hoge`を用意し、`v-model`には`hoge[n - 1]`を指定します。
配列の要素ごとにフォームを対応付けます。

```vuejs
<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      <input type="checkbox" v-model="hoge[n - 1]" />
      チェックボックス{{ n }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], // （例）上から順にフォームに「A」「B」「C」と入力すると、["A","B","C"]
      loop: 3
    }
  }
}
</script>
```

## セレクトボックスの場合

dataオブジェクトのプロパティとして`hoge`を用意し、`v-model`には`hoge[n - 1]`を指定します。
配列の要素ごとにフォームを対応付けます。


```vuejs
<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      セレクトボックス{{ n }}
      <select v-model="hoge[n - 1]">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
      </select>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], //（例）上から順に「A」「B」「C」を選択すると、["A","B","C"]
      loop: 3
    }
  }
}
</script>
```

# まとめ

プロパティを一つ一つ用意するのか、まとめられるところは配列としてまとめるのか、使い分けが大事だと思います。
今回は配列にまとめる方法を書きました。
誰かの参考になれば幸いです。
DockerでRails5、postgresqlの環境を作り、pgadminも使えるようにする

mysqlしかdockerで使ったことがなくて、時間がかかってしまったので、後で見れるように書きました。
pgadminも便利なので入れました。
```docoker-compose up```したあと```rails s```しなくてもいいようにdocker-compose.ymlにcommandで自動でやってくれるように書きました。

普段はコンテナ再作成しなくてもよいと思うので```docker-compose start / stop```でやる想定です。

```dockerfile:Dockerfile
FROM ruby:2.6

RUN apt-get update -y && \
    apt-get install  -y nodejs

COPY Gemfile /Gemfile
COPY Gemfile.lock /Gemfile.lock
RUN gem install bundler
RUN bundle install
```

```docker:docker-compose.yml
version: "3"
services:
  db:
    image: postgres
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
    volumes:
      - "./postgres-data:/var/lib/postgresql/data"
  pgadmin4:
    image: dpage/pgadmin4:4.2
    ports:
      - 80:80
    volumes:
      - ./docker/pgadmin4:/var/lib/pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: root
      PGADMIN_DEFAULT_PASSWORD: root
    depends_on:
      - db
  web:
    build: .
    volumes:
      - ".:/app"
    ports:
      - "3000:3000"
    tty: true
    depends_on:
      - db
    working_dir: "/app"
    command: "rails s -b 0.0.0.0"
```

mysqlとdatabase.ymlが違っていて、ここらへんを書くところをdevelopとかに書いてしまっていてハマりました。ちゃんとdefaultに書かなくてはいけませんでした。

```yaml:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # ここらへん
  username: root
  password: root
  host: db
```

参考サイト
[pgadmin4/dockerの接続サーバー設定の永続化 \- Qiita](https://qiita.com/tonouchi510/items/a18ef8f934ba41479716)

[rails5のDockerfileとdocker\-compose\.ymlを書く \- Qiita](https://qiita.com/yoshinyan/items/e1f801d6df422d5b7f88)
リダイレクトの仕組み？ ETag？ IPアドレスを取得する方法！

# はじめに
今回はHTTPに関する用語について紹介します！
具体的には以下の内容を扱います。

- リダイレクトの仕組み
- ETagヘッッダ
- IPアドレス関連のヘッダ (remote_addr, x-forwarded-for, x-real-ip)

youtubeでも解説しているので、確認してみてください！

[【YouTube動画】 リダイレクトの仕組み、ETag, IPアドレス](https://youtu.be/k3SgY3K1CqY)
[![リダイレクトの仕組み、ETag, IPアドレス関連のヘッダ](https://img.youtube.com/vi/k3SgY3K1CqY/0.jpg)](https://www.youtube.com/watch?v=k3SgY3K1CqY)

# リダイレクトの仕組み
[動画]((https://www.youtube.com/watch?v=k3SgY3K1CqY&t=40s))では図解で説明しているので、ぜひ確認してみてください。
リダイレクトとは、あるウェブサイトから別のウェブサイトへページ遷移させることです。

リダイレクトでは以下のような通信が行われています。

```
クライアント -> サーバー1 -> クライアント -> サーバー2
```

上記の通信では、サーバー1からクライアントに返るとき、リダイレクト用のステータスとLocationヘッダを返します。
リダイレクト用のステータスには、301と302があります (下記の表参照)。Locationヘッダには、遷移先のURLが返ってきます。


| ステータス |  | 意味 | 特徴 |
|:------------:|:------------:|:------------:|:------------:|
| 301 | Moved Permanently | 恒久的なウェブサイトの移動 | サーバー1を経由せず、サーバー2へ進むことがある |
| 302 | Found | 別のサイトを見つけた | 毎回サーバー1を経由して、サーバー2へ進む |


# ETag
ETagはHTTPレスポンスヘッダに付与されるランダムな値です。
クライアント側でキャッシュするときに利用します。

ここらあたりの説明は動画の方で詳しく説明しているので、ぜひ確認してみてください。

[ETagヘッダについて](https://www.youtube.com/watch?v=k3SgY3K1CqY&t=271s)

# IPアドレス関連のヘッダ
IPアドレスに関するヘッダをいくつか紹介します。
動画だと[この部分](https://www.youtube.com/watch?v=k3SgY3K1CqY&t=510s)になります。


## remote_addr

これを付けると、サーバーが認識する1つ前のIPアドレスを返します

例えば、以下の順序で通信が行われているとします。
この場合、サーバーのremote_addrはリバースプロキシのIPアドレスになります。

```
クライアント -> ロードバランサー -> リバースプロキシ -> サーバー
```


## x-forwarded-for

これは、クライアントからサーバーまでのIPアドレスを全て返します。

## x-real-ip

これを付けると、クライアントのIPアドレスだけを返すようにできます。

# まとめ


今回、HTTPに関連する用語の説明をしました。
もっと、こういうところを説明して欲しい！などの意見や感想がありましたら、コメントお願いします！

[twitter](https://twitter.com/yassun_youtuber)や[youtube](https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/featured?view_as=public)もやっているので、コメントをいただけると励みになります！
Amazon Lightsailでサーバー構築

## Amazon Lightsailとは？
AWSのサービスの一つであり、レンタルサーバーのようなものです。
類似サービスにEC2がありますが、相違点としては使用料が月額3.5＄からの固定であることや、アプリケーションやフレームワークのインストールが非常に容易であることが挙げられます。

## 使ってみよう
AWSのサービス検索フォームでlightsailを検索しましょう。
![スクリーンショット 2020-10-09 18.04.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/cb990b36-eaf2-c103-719b-60a6c5802e4e.png)

遷移先の画面でインスタンスを作成します。
![スクリーンショット 2020-10-09 18.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/37198a60-1ae7-f687-28fb-65256938e41b.png)

すごく魅力的な画面になります。以下の画像に表示しているものが全てインストール可能です。
今回はwordpressを使いたいだけなのでLinuxとwordpressを選択しました。
![スクリーンショット 2020-10-09 18.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/756586f9-422e-4c36-629c-f9aebde1fc13.png)

続いて契約プランの選択です。
作成するインスタンスのスペックが高いほど料金は高額となります。
![スクリーンショット 2020-10-09 18.35.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/97743124-1c05-9ff7-d05a-fd466a51852f.png)

画面下部の「インスタンスの作成」を押下すれば前準備は完了です。
![スクリーンショット 2020-10-09 18.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/3bae257e-ee49-dbad-96d4-999c88eb962f.png)

## インスタンスにアクセスする
前述の作業でインスタンスが既に出来ていると思います。
続いて、インスタンス名をクリックして詳細画面を確認しましょう。
![EU3dHGSAlLqpUEm1602236934_1602237067.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/777b09a7-425f-d706-889d-d34181ce8505.png)

赤枠で囲ってあるパブリックIPにアクセスしてみましょう。
![HTjLTT4siFvkl9c1602237948_1602238011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/61f867ae-9a13-9278-24d0-f2bdfd07d55a.png)
既にwordpressが起動している状態なので、デフォルトの画面が表示されます。
![スクリーンショット 2020-10-09 19.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/bccf2051-ec93-8829-c61e-56d8a2be1036.png)

ログイン画面には パブリックIP/wp-admin でアクセスすることができます。
![スクリーンショット 2020-10-09 19.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/5e96572e-4cac-b391-28ca-61aa462785ad.png)

ログインパスワードは「SSHを使用して接続」から確認することが可能です。
![HTjLTT4siFvkl9c1602237948_1602238011 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/16566cf4-afab-e57b-706d-a1c5002ace19.png)

ターミナルでlsコマンドを実行すると「bitnami_application_password」というファイルがあることを確認できます。
このファイルにパスワードが記載されています。
![スクリーンショット 2020-10-09 20.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/b3ff47d7-00ee-d697-8f6e-94a1fe77b18f.png)

というわけで、ログインIDとパスワードは以下になります。
ログインID: user (これがデフォルト)
パスワード: 「bitnami_application_password」に記載

これでログインできました！
![スクリーンショット 2020-10-09 20.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/a33d885c-b6ff-61a3-7316-e80b79b18922.png)

今回の記事は以上です！
半分くらいwordpress記事になってしまいましたが、Lightsailは様々な用途に利用可能です。
ぜひ一度使ってみてください！
My CheatSheet

# CheatSheet
未経験エンジニアの中途入社社員がいち早く業務でコミット出来るように、私が参考にした資料をまとめておく。

## Pull Request
- [完璧なプルリクエストの書き方("How to write the perfect pull request" by Keavy McMinn@GitHub)](https://qiita.com/imagire/items/7495bdf30c74985debd3)
- [より良いプルリクエストのための10のヒント](https://yakst.com/ja/posts/1625)
- [WIP Pull Request でチェックボックスを表示する](https://qiita.com/kleerd/items/0855fce57b0d9754e0d1)

## Google Analytics
- [Google Analytics](https://marketingplatform.google.com/intl/ja/about/analytics/)
- [【今さら聞けない】Googleアナリティクスとは？導入手順から使い方まで5分で理解！](https://wacul-ai.com/blog/access-analysis/google-analytics-method/what-is-google-analytics/#/s01)
- [【Googleアナリティクスの使い方】最初に絶対マスターしておきたい6ポイント！](https://wacul-ai.com/blog/access-analysis/google-analytics-method/viewpoint-of-ga/)

## Google Search Console
- [Search Console の概要](https://support.google.com/webmasters/answer/9128668?hl=ja)

## Shortcut
- [[厳選]開発効率を上げるMacのショートカットまとめ](https://qiita.com/eve1224/items/b8939f90715e2622a1de)
- [[厳選]開発効率を上げるChromeのショートカットまとめ](https://qiita.com/eve1224/items/2da0c7d06cce01688306)
- [Vimの簡易チートシート](https://qiita.com/eve1224/items/6a6606f2a536eff12565)
ディレクトリ内のファイル数を調べる

```python

DIR = './dataset'

print(sum(os.path.isfile(os.path.join(DIR, name)) for name in os.listdir(DIR)))
```

最初、下のように書いていたのですが、@shiracamusさんに
>リストを作るとメモリを大量消費するので、sum関数でbool値を合計するといいですよ。

とコメントいただきました。ありがとうございます！


↓メモリ大量消費するやつ。

```python
DIR = './dataset'
print(len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))]))
```

>2933

🐣
****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
ヨドバシドットコム購入明細メールの商品一覧から商品名と価格を抜き出す

※ 2020/10/19追加：さすがに隙間が0秒だとクリップボードスタックに履歴がたまらないことがあるためスリープ処理を追加

表題の通り、ヨドバシドットコムの購入明細メールから、商品名と価格の組み合わせを取得するプログラムを、Pythonで書いてみました。クリップボード履歴ツールの活用方法と、Pythonのモジュール、PyPerclipとzip関数の利用例にと思ってくれたら幸いです。

説明が要らない という方はこちらをどうぞ

* [ヨドバシドットコム購入明細メールの商品一覧から商品名と価格を抜き出す](https://gist.github.com/TakamiChie/ac0c84727288487198562e87eeb9bec2)

# 動機など
わたしはZaimを使って家計簿を作成しています。レシートを撮影して明細を登録できるほか、Amazonなど一部のサイトでの購入情報を自動的に登録できるため便利です。

しかしこのZaim、残念ながらヨドバシドットコムとの連携には対応していません。このため、ヨドバシドットコムを多用するわたしは買い物履歴を登録するのに毎回苦戦していました。

そこで、ヨドバシドットコムでの商品購入時に届く「ヨドバシ・ドット・コム：ご注文ありがとうございます」のメールに書かれている商品明細を読み込んで、Pythonで商品名と価格を抽出することにしました。

```
【ご注文商品】
---------------------------------------------------------------
・「[商品名(改行あり)]」

　　配達希望日：[日時]

　　合計 [個数] 点　 [価格] 円

・「[商品名(改行あり)]」

　　配達希望日：[日時]

　　合計 [個数] 点　 [価格] 円
・・・

・配達料金：　　0 円

```
## とりあえず実装方針
クリップボード履歴ツールのスタッククリップボード機能を使うと便利です。

スタッククリップボード機能とは、Clipboard-Historyなど多くのクリップボード履歴ツールについている機能で、コピー操作によりスタックに格納したテキストを順番に貼り付ける機能です。

これは単体で使ってももちろん便利ですが、スクリプトと併用すると結構便利です。このため、これを使って、クリップボードスタックに商品と値段を格納します。

#実装例
とりあえずこんな感じで。正規表現で商品名と価格名のリストを作成し、`zip`関数でまとめて、クリップボードに転送します。
スクリプトを実行する前に、以下の準備が必要です。

* クリップボード履歴ツールのスタッククリップボード機能を有効にしておく
* ヨドバシドットコムから届く注文明細の、「ご注文商品」～「配達料金」のひとつ上の行までをクリップボードにコピーしておく

```py
import re
import pyperclip
import sys
from time import sleep
n = []
p = []
text = pyperclip.paste()
for m in re.finditer(r"「([^」]*)」", text, re.MULTILINE):
  n.append(re.sub("\\n\\s*", "", m[1]))
for m in re.finditer("([\\d,]+)\\s*円", text, re.MULTILINE):
  p.append(re.sub("\\n\\s*", "", m[1]))
ret = ""
for a, r in zip(n, p):
  pyperclip.copy(a)
  sleep(0.1)
  pyperclip.copy(r)
  sleep(0.1)
```

Pythonスクリプトからクリップボードへのアクセスには、`pyperclip`モジュールを用います。`pip install pyperclip`で事前にインストールしておきます。

実行すると、クリップボードスタックに買った商品の名前と値段が交互にコピーされるので、Zaimの支出フォームに順次貼り付けていきます。

# プログラミングって、本職じゃない人が使っても便利
プログラミングは、このように仕事と関係ない分野でも結構使えます。日頃の定例作業を簡素化したり、自動化したり。IFTTTなどの自動処理サービスを使う場合も、プログラミングの知識感覚があった方ができることの幅は広がります。

なので、本職でない人・そのようなことを仕事でする予定がない人も、できて損をしないものではないでしょうか と、もっともらしいことを言ってみる。


まあ、願わくばこういうそれっぽいスクリプト群を気軽に作成できて、気軽に実行できるランチャーみたいな環境があるといいっちゃいいのですが・・・。
画像を一括リサイズ

何百枚でも何千枚でもリサイズできます。

#縦横比を保たずリサイズ
![anjyu3P2A6684_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b88fffb7-8a33-7181-0134-10a54133665b.jpeg)　　　![anjyu3P2A6684_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/686143e0-19cd-c9d5-8442-14c435da5931.jpeg)

```python

import os
import glob
from PIL import Image

src = glob.glob('./dataset/*.jpg') # オリジナル画像のパスと拡張子を設定
dst = './dataset_resized/' # リサイズ画像の保存フォルダ

width = 513 # リサイズ後の横幅
height = 513 # リサイズ後の縦幅

for f in src:
    img = Image.open(f)
    img = img.resize((width,height))
    img.save(dst + os.path.basename(f))
```

#縦横比を保ってリサイズ
![anjyu3P2A6684_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b88fffb7-8a33-7181-0134-10a54133665b.jpeg)　![anjyu3P2A6684_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/9035908b-0e64-4ba5-17f7-1455d21cd9d1.jpeg)

横幅を指定する場合

```python

import os
import glob
from PIL import Image

src = glob.glob('./dataset/*.jpg') # オリジナル画像のパスと拡張子を設定
dst = './dataset_resized/' # リサイズ画像の保存フォルダ

width = 513 # リサイズ後の横幅

for f in src:
    img = Image.open(f)
    original_width, original_height = img.size
    scale = width / original_width
    height = int(original_height * scale)
    img = img.resize((width,height))
    img.save(dst + os.path.basename(f))
```
縦幅を指定する場合

```python

import os
import glob
from PIL import Image

src = glob.glob('./dataset/*.jpg') # オリジナル画像のパスと拡張子を設定
dst = './dataset_resized/' # リサイズ画像の保存フォルダ

height = 513 # リサイズ後の縦幅

for f in src:
    img = Image.open(f)
    original_width, original_height = img.size
    scale = height / original_height
    width = int(original_width * scale)
    img = img.resize((width,height))
    img.save(dst + os.path.basename(f))
```
🐣
****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
【Java Silver】配列の生成方法

#配列の特徴

- 配列は**nullを許容**する
- 配列の要素数は、初期化された時に決まり、後から変更できない(要素の**追加・削除不可**。上書きは可能) 
- 配列はオブジェクトクラスのサブクラスなので、**オブジェクト型**とみなすことができる

例）

```java
example(Object[] val);  //引数にオブジェクト型の配列を受けとる

example(Object val)  //引数に配列を受け取ることができる
```

#配列の生成方法
**【注意するポイント】**

- 変数宣言時に大かっこ[]があるか →　[]無し、または[]以外のカッコを使っていたら**コンパイルエラー**
- 変数宣言時に要素数を指定していないか → **変数宣言時**に**要素数を指定**していたら**コンパイルエラー**
- **インスタンスの生成時**に**要素数を指定**しているか
- **インスタンスの生成**で**newを記述**しているか
 
**※） new省略し、初期化子( {} )だけで配列を作ることは可能！！**
- 初期化子で指定した要素の数だけ、自動的にメモリ領域を確保する。
- 初期化子が使えるのは、変数宣言と同時の時のみ
- 変数宣言と初期化を別にすると**コンパイルエラー**
- 配列の初期化子は、左辺のデータ型から**配列のデータ型を推論**する

**【配列の初期化例】**

```java
int a [][] = {{1,2},{3,4}}; //newを使わず初期化子だけで配列を生成
int b [] = {};   //newを使わず初期化子だけで配列を生成。配列の中身は空だがエラーではない

int[][]c = new int [][]{}; //newと初期化子、両方使うなら[][]の中は空である必要がある

int[] d;
d = new int[]{2,3};  //配列を格納する変数を作成後、インスタンスを生成して変数に代入

int [] e = new int[3]; //要素数３のインスタンス領域を確保
```

**【コンパイルエラーが発生する初期化例】**

```java
int[] a;
a = int[2];   //インスタンス生成時にnewを記述しておらず、インスタンスを生成できていない

int array = new int[2]; //配列型を示す[]が無い

int array[2]; //変数宣言時に要素数を指定している。

int array1 = new int[2];
array1 = {1,2};  //初期化子が使えるのは変数宣言と同時の時だけ

int[] array2= new int[3]{}; //無名配列を作るときは[]の中に要素数を記述しない

```

**【ポイント】**

- 配列はインスタンスなので、生成しない限り使えない

- 配列を表す変数は、配列インスタンスへの**参照**を保持するための器であり、変数内に配列が作られるわけでは無い。配列インスタンスの方に、扱う要素数を記述する必要がある。
exitコマンドの終了コードを0にしたいときは、明示的に0を指定する

「[exitコマンドの終了コード](https://qiita.com/jkr_2255/items/6d14045cfa0494c21a20) - @jkr_2255」という記事が面白かったので、自分の環境で実際に挙動を確認してみました。

## 環境

```
$ bash --version
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
```

## 出力結果

まず、`exit` コマンドは引数として指定した数字を終了コードとして返します。

```
$ bash -c 'exit 0'; echo $?
0
$ bash -c 'exit 1'; echo $?
1
$ bash -c 'exit 255'; echo $?
255
```

引数を指定せず、`exit`した場合は、終了コードが0となります。

```
$ bash -c 'exit'; echo $?
0
```

言及元の記事の通り、引数指定なしの `exit`コマンドの終了コードは、前回のコマンドの終了コードとなりました。

```
$ bash -c 'bash -c "exit 10"; exit'; echo $?
10
```

途中で `ps`コマンドを発行してプロセスを確認してみます。`exit 10`を発行するプロセスが、`exit` を発行するプロセスの子プロセスになっていることがわかります。

```
$ bash -c 'bash -c "ps f;exit 10"; exit'; echo $?
10
22911 pts/0    Ss     0:00 bash
28813 pts/0    S+     0:00  \_ bash -c bash -c "ps f;exit 10"; exit
28814 pts/0    S+     0:00      \_ bash -c ps f;exit 10
28815 pts/0    R+     0:00          \_ ps f
```

## 余談

255以上の数値を指定すると、0を返すようです。

```
$ bash -c 'exit 256'; echo $?
0
```

コマンドのタイポをした場合は、127が返ります。

```
$ bash -c 'eecho;'; echo $?
bash: eecho: command not found
127
```

## おわりに

特殊なケースでない限り、`exit 0` と終了コードを明示的に指定しようと思います。トラブルが少なくて済みそうです。
スイッチ間の接続経路の冗長化（ネットワーク）－午後

応用情報技術者平成28年春期 午後4

ファイル：2016h28h_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/28_haru/pm04.html

メモを簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。

１、〔STPの導入検討〕について，(1)，(2)に答えよ。
（１）、本文中の下線②において，PC1が部署1サーバのMACアドレスを取得するためにARPフレームを送信したとき，ARPフレームが到達するサーバ名を，図2中の名称で答えよ。また，PC1から部署1サーバが利用できなくなった理由を30字以内で述べよ。

再構成後は部署1からL2SW1への通信は全てp3を経由するため、L2SW1は部署1からの通信をVLAN20からのデータであると認識します。要するに部署1のセグメントはVLAN20に属するようになります。

このような仕組みにより部署1から発信したARPリクエスト部署2サーバには到達しますが、VLAN名が異なる部署サーバ1には届きません。

VLAN20から部署１サーバへアクセスできない（私の答え）
→
理由＝PC1と部署1サーバが所属するVLANが異なるから（参考の答え）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5a3cbf45-851f-ea6f-d037-80ddd47f8fff.png)


＜＜STPの導入検討＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5b757c9f-f0b6-ea70-ef6e-9540cc4225a9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5823a318-adb7-2da5-6e9b-5061d55ee01f.png)



・VLAN(Virtual LAN)とは、
レイヤ2スイッチ(スイッチングハブ)に接続された端末を物理的な構成に関係なくグループ化する機能、またはその機能で形成されたネットワークのことです。

・ポートベースVLAN
グループ分けに使用される情報により以下の方式がありますが、図1で採用されている「ポートベースVLAN」は、その名の通りスイッチの接続ポート単位でグルーピングする方式です。
ポートベースVLANでは同じVLANIDが割り当てられたポート同士しか通信できないようにすることでネットワークを分割します。したがって図1の本社LANには、VLAN10とVLAN20という2つのネットワークセグメントが存在することになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/16965746-30ac-8cfc-d3ad-4f6268e8ec84.png)
【Rails】ActiveStorageを用いた画像複数枚投稿のエラー

##エラー【undefined method `to_model'】
フリマアプリの開発中、以下のようなエラーが出ました。
`Can't resolve image into URL: undefined method ``to_model' for #<ActiveStorage::Attached::Many:0x00007fb7ffa59fb0>
Did you mean?  to_yaml`

![スクリーンショット 2020-10-10 11.25.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696812/b7facd00-67e0-6c98-da05-6831b7ca5ff0.png)


###現状
- ActiveStorageというGemをを用いて画像保存を可能にしている。
- 1つの商品につき複数の画像の投稿を可能にした。←今ここ

###エラーの内容
`to_model`というメソッドは定義されていないよーって言われてます。


**以下のように、保存した画像を表示させたい時にエラーがでました。**
![スクリーンショット 2020-10-10 12.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696812/a333bbbe-2738-a87e-492c-7bc4e7c68af2.png)




####問題があったコード

```Ruby
<%= image_tag @item.images, class: 'buy-item-img' %>
```

####解決したコード

```Ruby
<%= image_tag @item.images[0], class: 'buy-item-img' %>
```

一つの商品に複数枚画像があるため、どの画像を表示させるかを記述する必要があります。
そうじゃなかったらどの画像を表示するのか判断できないですもんね😓

他の方の記事などを見てみると、
`@item.images.url`と記述すれば解決することもあったそうです。
参考になれば、と思います！
テクニカルライティング資料置き場

# テクニカルライティング資料置き場

## Google
[Technical Writing](https://developers.google.com/tech-writing)
[Technical Writing One](https://developers.google.com/tech-writing/one)
[Technical Writing Two](https://developers.google.com/tech-writing/two)
## qiita
[Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したい](https://qiita.com/yasuoyasuo/items/c43783316a4d141a140f)
[ドキュメント作成スキル向上を目指す人向けおすすめ記事まとめ](https://qiita.com/yasuoyasuo/items/1eb7298f91a44dce7abc)
[Google社のテクニカルライティングの基礎教育資料を和訳・要約した](https://qiita.com/y_k_individual/items/7c5ea35441c02cba4471)


## 
### 書籍
[成果を生み出すテクニカルライティング　ートップエンジニア・研究者が実践する思考整理](https://www.amazon.co.jp/dp/B07NP49KBT/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[gihyo](https://gihyo.jp/book/2019/978-4-297-10406-1/content/preface)
### スライド
[トップエンジニアが実践する思考整理法～テクニカルライティングを用いた課題解決の基本](https://www.slideshare.net/hajime-f/ss-142326446)
SwiftでUUIDをbase64にして短縮する。

UUIDは分散的に生成できて、かなり使いやすいのですがエンコードする時にいかんせん長いです。

`E2731BE6-470D-4782-B853-E5B13E8A1ECF`
`D879A224-9A58-4D71-8E43-B7F3D001B7E4`
`FFF4DCE4-3C49-459B-BDB9-EB4B5A030FEB`

これをそのまま保存するのは流石に避けたい。

UUIDは通常16進法で書かれるので、文字列で保存するならもっと短縮できるはずです。

# 実装

こんな `extension`を実装します。


```swift

extension UUID {
    public var base64String: String {
        var base64WithPadding = self.data.base64EncodedString()
        // base64の末尾の==を取り除く
        base64WithPadding.removeLast(2)
        return base64WithPadding
    }
    
    public var data: Data {
        var result = Data()
        let uuidTuple = self.uuid
        result.append(uuidTuple.0)
        result.append(uuidTuple.1)
        result.append(uuidTuple.2)
        result.append(uuidTuple.3)
        result.append(uuidTuple.4)
        result.append(uuidTuple.5)
        result.append(uuidTuple.6)
        result.append(uuidTuple.7)
        result.append(uuidTuple.8)
        result.append(uuidTuple.9)
        result.append(uuidTuple.10)
        result.append(uuidTuple.11)
        result.append(uuidTuple.12)
        result.append(uuidTuple.13)
        result.append(uuidTuple.14)
        result.append(uuidTuple.15)
        return result
    }
}

```

これで36文字が22文字まで短縮できます。

```
40CC21EA-7D27-49CC-8A18-280373933BE2 -> QMwh6n0nScyKGCgDc5M74g
2AF87112-E64C-441F-85E1-FD4FCCD097CA -> KvhxEuZMRB+F4f1PzNCXyg
D9C051E6-D7E2-4198-9CB1-A399E347D860 -> 2cBR5tfiQZicsaOZ40fYYA
```

# テスト

以下のコードでテスト

```swift
for _ in 0..<10 {
    let id = UUID()
    let data = Data(base64Encoded: id.base64String + "==")!

    let uuid = UUID(uuid: (
        data[0], data[1], data[2], data[3], data[4], data[5],
        data[6], data[7], data[8], data[9], data[10], data[11],
        data[12], data[13], data[14], data[15]
    ))

    print(id, "->", id.base64String, "->", uuid)
}
```

```
40CC21EA-7D27-49CC-8A18-280373933BE2 -> QMwh6n0nScyKGCgDc5M74g ->
40CC21EA-7D27-49CC-8A18-280373933BE2

2AF87112-E64C-441F-85E1-FD4FCCD097CA -> KvhxEuZMRB+F4f1PzNCXyg -> 
2AF87112-E64C-441F-85E1-FD4FCCD097CA

D9C051E6-D7E2-4198-9CB1-A399E347D860 -> 2cBR5tfiQZicsaOZ40fYYA -> 
D9C051E6-D7E2-4198-9CB1-A399E347D860
```

可逆圧縮できている。
【JS学習その⑩】JavaScriptにおけるgetter/setterとstatic

#JS学習シリーズの目的
このシリーズは、私ジャックが学んだJavaScriptのメカニズムについてアウトプットも兼ねて、
皆さんと知識や理解を共有するためのものです。
(理解に間違いがあればご指摘いただけると幸いです)

#getter/setterとは
* getter => 「**プロパティが参照された際に行う処理**」
* setter => 「**プロパティに変更があった際に行う処理**」

※**プロパティにはディスクリプターというものがあり、その中にgetとsetがある**

```main.js
function Person1(name, age) {
    this._name = name;
    this._age = age;
}

Object.defineProperty(Person1.prototype, 'name', {
    get: function() {
        return this._name;
    },
    set: function(val) {
        this._name = val;
    }
)};

const p1 = new Person1('Bob', 23);

console.log(p1.name); /*Bob*/

p1.name = 'Tom';
console.log(p1.name); /*Tom*/
```
上記のコードでは、
`Object.defineProperty`メソッドで`Person1.prototype`内の`name`プロパティのディスクリプターを直接定義しています。
上記の`get`がgetter,`set`がsetterです。

また、ES6からは上記をクラス構文で次のように簡略化して記述できます。

```main.js
class Person2 {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }

    get name() {
        return this._name;
    }

    set name(val) {
        this._name = val;
    }
}

const p2 = new Person2('Bob', 23);
console.log(p2.name); /*Bob*/

p2.name = 'Tom';
console.log(p2.name); /*Tom*/
```

#静的メソッドとは
「**インスタンス化せずに直接実行できるメソッド**」
静的メソッドはクラス内で`static`というキーワードを使用して定義します。

```main.js
class Person2 {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }

    get name() {
        return this._name;
    }

    set name(val) {
        this._name = val;
    }

    static hello() {
        console.log('hello');
    }
}

Person2.hello() /*hello*/
```
上記の`hello`メソッドが静的メソッドになります。
前述したように、静的メソッドはインスタンス化せずに直接実行できます。ただ、注意点があります。
それは、**静的メソッド内(`static`内)では`this`は使えない**ということです。

また、静的メソッドは他のメソッドと違い、**`__prototype__`内に定義されるのではなく`constructor`内に生成されます**。
だからインスタンス化しなくても直接実行できるという訳です。

```main.js
function Person1(name, age) {
    this._name = name;
    this._age = age;
}

Person1.hello = function() {
    console.log('hello');
}

Person1.hello(); /*hello*/
```
よってクラス内で`static`を使って定義した静的メソッドは上記のようにして書いたものと同じということです。

#まとめ
いかがでしたでしょうか。
getter,setterとstatic(静的メソッド)はJavaScriptにおいて重要なのでしっかり理解しておきましょう！
dbpediaの研究 その37

#概要　

dbpediaが難解なので、手出してみる。
鉄道駅LODやってみた。
奥羽本線、表示してみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/789677c4-cb16-6539-45cd-8643a4c84e4e.jpeg)


#投げたsparqlクエリー

```
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX schema: <http://schema.org/>
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX propja: <http://ja.dbpedia.org/property/>
PREFIX class: <https://uedayou.net/jrslod/Class/>

SELECT DISTINCT ?title ?lat ?lon
WHERE {
    ?link a class:駅;
        rdfs:label ?title;
        propja:所属路線 ?rosen;
        geo:lat ?lat;
        geo:long ?lon.
    FILTER regex(?rosen, "奥羽")
}


```

#成果物

https://embed.plnkr.co/plunk/0A1RXRH96OdDwPPb

以上。
【Android / Java】表示Fragmentによりイベントを切り替える

# はじめに
Android Studio(java)でアプリを開発していて、「表示しているフラグメントに応じて端末の戻るボタンを押した時の処理を切り替える」という実装をしたい場面があった。
そのときに学んだ内容を投稿します。

# 学んだ内容
コードの一部を記載

## ActivityからFragmentを表示

このアクティビティxmlファイルにフラグメントを表示させる

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fl_activity_main"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
```

フラグメントの表示処理はこのように行う

```MainActivity.java
// 指定したフラグメントを表示するメソッド。引数のfragmentに表示したいフラグメントのインスタンスを渡す。
public void showFragment(Fragment fragment, FragmentManager fragmentManager) {

    fragmentManager
            .beginTransaction()
            .replace(R.id.fl_activity_main, fragment)
            .addToBackStack(null)
            .commit();
}
```



## 表示しているFragmentを取得してイベント（処理）を行う

今回は例として、端末の戻るボタンを押したときに表示されているフラグメントが``FooFragment``または``BarFragment``であれば、アクティビティを終了させる、という実装にしている。


```MainActivity.java
// onBackPressed()は端末の戻るボタンを押した時に呼ばれるメソッド
@Override
public void onBackPressed() {
  // ここで現在表示しているフラグメントを取得
  // findFragmentById()の引数にはフラグメント表示のreplace()で表示先のレイアウト部品のid（コンテナ)を入れる。
  Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fl_activity_main);
        
   // FooFragmentまたはBarFragmentを表示しているときにはアクティビティを終了(finish)
   if (fragment instanceof FooFragment || fragment instanceof BarFragment) {
     finish();
   }
   super.onBackPressed();
}
```

# 最後に
どのように表示しているフラグメントを判断させるか、意外と簡単に実装ができた。
今後も学習した内容を積極的にアウトプットしていきます。

# 参考資料
ありがとうございました！！

[Android 初めてのFragment イベント編](https://qiita.com/Reyurnible/items/d6397f5fbb03ee4fb93b)
あなたのC++理解度は10段階評価でいくつ？(On a scale from 1 to 10, how do you rate your understanding of C++?)

![slide255.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6657/b76c13e1-9f93-2ee2-775f-7f743778ed39.jpeg)
(from [Deep C (and C++)](https://www.slideshare.net/olvemaudal/deep-c/255), Olve Maudal.)

[Bjarne Stroustrup](https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%A3%E3%83%BC%E3%83%8D%E3%83%BB%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B4%E3%82%B9%E3%83%88%E3%83%AB%E3%83%83%E3%83%97): 「7」
Google Play Consoleで APK拡張ファイル（.obbファイル）をアップロードする方法

Google Play Consoleで
APK拡張ファイル（.obbファイル）をアップロードしようとしたところ
ハマったので、書き残しておく

### 注意

- APKファイルを**一番初めにアップロードする時しか、OBBファイルは追加できない**
    - もしOBBファイルを追加忘れても、あとから追加はできない
    - 同じバージョンのAPKファイルは再アップできない
    - アップロードしたAPKファイルを削除もできない
    - **よって、VersionCodeの値を変更後、再アップロードするしか方法がない** (←つらい）
- 新しいUI（2020/11/2〜デフォルトになるらしい）では既存のUIと指定場所が違う
    - 今回は新しいUIの画面です



### 手順

1. Google Play Consoleにログイン 
2. アプリの画面に移動
3. リリース > ご希望のテスト > 新しいリリース作成 （通常のリリース作成手順）
4. APKファイルをアップロードする 
5. アップロードが環境すると、APKファイルが表示されるので、その一覧の右の点をクリック ![スクリーンショット 2020-10-10 11.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6568/af25ce5a-710c-10b4-54c1-0e119edd972c.png)
6. APK拡張ファイル（.obbファイル）追加メニューが表示されるので、選択
7. OBBファイルを指定してアップロード


##### 雑感
UIわかりやすくしてほしい…。
AWS Certified Security Specialty(SCS)合格体験談

### 前書き

- 試験の概要については、AWS 公式サイトや他の記事に委ねますので、ここでは割愛します。
- 自分の試験対策方法をここで簡単にご紹介します。とは言え、あくまで自分のやり方なので、すべての人に適応できるとは限りません。ご自身に一番合う手法やペースで頑張りましょう。

### 受験結果

- 2020/10/08 に一発で合格、スコアは 774
- 五つのセクションのうち、「ログと監視」と「インフラストラクチャのセキュリティ」については再学習の必要ありだとレポートに叩かれました（ややショックだった、インフラの部分一番自信あるのにな。。。:persevere:）

### 受験者スペック

- 新卒で IT 業界に入りエンジニアとしてのキャリアは今年で 5 年目、AWS 歴は 2 年
- 受験時に以下の資格を保有：
  - AWS Certified Cloud Practitioner
  - AWS Certified Solutions Architect - Associate
  - AWS Certified Developer - Associate
- 最初は EC2 や DMS などを用いて弊社製品 COMPANY のデータ移行ツールの開発に携わっており、使ってるサービスはそれほど多種多様なわけではないが、今年に入ってからCOMPANYとは違う自社開発のWebアプリケーションの環境設計・構築大臣になり、そこで AWS のベストプラクティスに沿う王道的な設計パターンを学び続けてきました。同時にセキュリティ周りの需要も段々出てきて、それで今回受験の決意に至りました。

### 試験対策

- 対策本として利用したのは**『AWS認定 セキュリティ-専門知識』** 
https://www.amazon.co.jp/gp/product/4839970947/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1  
比較的新しく出版された本であって、内容も体系的に書かれており、とても分かりやすかったです。試験ガイドラインで示された 5 つの分野に沿い、それぞれに対してどのようなサービスを利用すれば「安全」だと言えるのか、ユースケースも含めて説明してくれました。  
さらに、40 問ほどの練習問題も用意してくれて、試験前のリハーサルとしてかなり有用です。本番ほどの長文や難易度ではないが、大事なポイントをそこそこカバーしており、回答も丁寧に書かれております。  
試験までにはこの本を 2 周しまして、だいたいの勉強時間は前後で 50 時間くらい。

- 模擬試験
AWS 公式で提供されている模擬試験です。以前の認定試験合格の特典でもらったクーポンを使って無料で 2 回受けました（ちなみに 2 回とも全く同じ問題文でした）。難易度的には上記対策本の練習問題とほぼ同レベルで、本番よりは低い。受験後即時に簡単な結果レポートをメールで送ってくれるんで、それを参照して自分の弱いところを補うのは良いでしょう。

- 実際に手を動かす
これ対策と言えるかどうかちょっと微妙ですが、正直今回一番ためになったのは実際の仕事経験です。前述の通り、受験前にすでに仕事で社内サービスのアーキテクチャを設計・構築したことがあって、各種 AWS サービスのコンセプトや利用方法をそこそこ身に付けておりました。本番の試験問題を見たら、「これうちが作った Web アプリと一緒じゃねえ？！」みたいなデジャブが多々ありました:laughing:。なので実践こそ、試験合格の一番の近道かもしれません。

### 試験の難易度比較

★★★★★ 　本番試験
★★★★ 　　 AWS 公式模擬試験、対策本の模擬試験

さらに、あくまで個人感覚ですが、他の Associate 認定試験と比べると、
**SAA** < **DVA** ≒ **SCS**

コンセプト的には、
**【SAA】**開発や運用の要件を達成し、かつ AWS Well-Architected を満たすためにどのサービス（あるいはサービスの組み合わせ）がベストなのか
**【DVA】**上記よりさらに一歩進んで、そのサービス（あるいはサービスの組み合わせ）をどのように実装・設定・運用すれば良いか
**【SCS】**上記よりさらに一歩進んで、そのサービス（あるいはサービスの組み合わせ）をどのように実装・設定・運用すれば**「安全」**と言えるか

### 試験について

- 全 65 問の中、問題文がユースケース中心で長文の割合が高く、1 行や 2 行で完結する問題はほんのわずか、なので意外と疲れます。集中力保持のために前日はきちんと寝ましょう。時間配分をそこそこ意識できれば、再検査の時間は十分に確保できるはず。
- 今回の試験でテストセンターがメモ用紙も用意してくれました（前の DVA を受けたときはなかったけど、なぜでしょうかね:thinking:）。思考が混乱するとき、メモ用紙でちゃんと構造図とかを描いてみたら意外とスッキリするかも。

### 対策本であんまり言及されていないが確認したほうが良いポイント

- CLB から ALB に移行するとき発生する認証エラーのトラブルシューティング
- SES の SMTP インターフェース、TLS 暗号化
- GuardDuty の信頼できる IP リスト
- Secrets Manager の自動更新

### 最後に

本当は DVA の体験談も書きたかったけど、結局ずっと後回しにしていて、試験の内容をほとんど忘れてしまい書けなくなった。。。一つだけ覚えているのは、サーバーレスに関する問題の割合が物凄く高いこと。多分それがこれからのトレンドですかね。  
次は Professional 認定にチャレンジします。
【laravel】migrationでindexをつけたときのメモ

毎回調べるのが面倒になったのでまとめました
全てmigrationファイル上での記述です。
参考 : https://laravel.com/docs/5.8/migrations

####1. 基本的なキー作成

```php
Schema::create('members', function (Blueprint $table) {
    $table->integer('id')->primary(); //プライマリキー
    $table->string('email')->unique(); //ユニークキー
    $table->string('name')->index();  //indexキー
});
```

laravelではキーを作成するときに「テーブル名+カラム名+キー」の命名規則で自動で名前をつけてくれる。
(上記の例だとmembers_name_index, members_email_uniqueという名前になる)


######名前を自分で付けたいとき
引数に任意のキー名を入れる

```php
Schema::create('members', function (Blueprint $table) {
    $table->string('email')->unique('email_unique'); 
    $table->string('name')->index('name_index');
});
```



####2. 複合キー
カラムの配列を渡す
(名前を自分でつけたいときは同じく第二引数で指定する)

```php
Schema::create('members', function (Blueprint $table) {
    $table->integer('id'); 
    $table->string('email'); 
    $table->string('name');
    $table->unique(['email', 'name']); //複合ユニークキー
    $table->index(['id', 'email'], 'members_index'); //複合index(任意の名前をつける)
});
```

##キーの削除
第一引数に削除するキーの名前を渡す
(laravelの命名規則に則っている場合は、カラム名の配列を渡して指定することもできる)

```php
Schema::table('members', function (Blueprint $table) {
    $table->dropUnique('members_email_unique'); //キー名を指定して削除
    $table->dropIndex(['name']); //members_name_indexを削除
});

```
KiCadでFusionPCBに発注するときの設定

# ガーバーファイルの出力
公式の説明を参考に出力していく
https://www.fusionpcb.jp/blog/?p=1178

ファイル->プロット

1. 出力ディレクトリをプロジェクト直下に作成し設定する
2. 以下のレイヤーを設定する
3. Protelの拡張子を使用にチェック
4. 拡張X2フォーマットを使用のチェックをはずす
5. 製造ファイル出力を選択して、ファイルを出力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/2a1bafaa-7063-bbf6-69a8-659c5c8bec32.png)

ドリル ファイルを生成を選択

1. Excellonを選択し、PTHとNPTHを一つのファイルにマージを選択
2. ドリル単位のmmを選択
3. ドリル ファイルを生成を選択して、ファイルを出力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/1572c07d-a450-8a1c-0fa9-911287c8807a.png)


# ガーバーファイルの詳細

ファイル名|説明
------------------------------|------
<プロジェクト名>-F_Cu.gtl      |表面パターン
<プロジェクト名>-F_Mask.gts    |表面レジストマスク
<プロジェクト名>-F_Paste.gtp   |表面メタルマスク
<プロジェクト名>-F_SilkS.gto   |表面シルク
<プロジェクト名>-B_Cu.gbl      |裏面パターン
<プロジェクト名>-B_Mask.gbs    |裏面レジストマスク
<プロジェクト名>-B_Paste.gbp   |裏面メタルマスク
<プロジェクト名>-B_SilkS.gbo   |裏面シルク
<プロジェクト名>-NPTH.drl      |ノンスルーホールのドリル
<プロジェクト名>-PTH.gbr       |スルーホールのドリル
<プロジェクト名>.gbr           |NPTHとPTHをまとめたのドリルデータ
<プロジェクト名>-Edge_Cuts.gm1 |基板外形


※内層データが有るときは以下が追加される

ファイル名|説明
------------------------------|------
<プロジェクト名>-In1_Cu.g2     |内層1パターン
<プロジェクト名>-In2_Cu.g3     |内層2パターン

### elecrowで発注する際
ガーバーデータの名称を置き換える必要がある

ファイル名|Elecrow用
------------------------------|------
F_Cu.gtl      | xxx.GTL
F_Mask.gts    | xxx.GTS
F_SilkS.gto   | xxx.GTO
B_Cu.gbl      | xxx.GBL
B_Mask.gbs    | xxx.GBS
B_SilkS.gbo   | xxx.GBO
.grl          | xxx.txt
Edge_Cuts.gm1 | xxx.GML
nodemonの使い方

#プログラミング勉強日記
2020年10月10日
nodemonというツールを初めて見かけたので、まとめておく。

#nodemonとは
　コードの変更を監視して自動でサーバーを再起動してくれるツール。
　Node.jsで動いてるアプリのコードを修正した後は、サーバーの再起動が必要になるが、コードを修正した後に毎回手動で再起動するのは面倒だし、再起動をし忘れてしまうことがある。そういった作業を自動化できるnodemonは便利である。


#nodemonのインストール
　使用したいプロジェクトの下で以下のコマンドを実行する。

```
npm install nodemon --save-dev
```
　開発環境のみで使用するので`--save-dev`を付ける。コマンドを実行するとpackage.jsonに以下のように追記される。

```json:package.json
"devDependencies": {
    "nodemon": "^2.0.3"
  }
```
　本番環境においては以下のコマンドを実行すると除外される。

```
npm install --production
```

#アプリの実行
　`npm start`で起動できるようにpackage.jsonにscritを設定する。

```json:package.json
"scripts": {
    "start": "nodemon src/app.js"
  },
```

　package.jsonを変更したら以下のようにコマンドを実行してアプリを起動させる。

```
$ npm start

> express-api@1.0.0 start /sample/express-api
> nodemon src/app.js
```

　これでnodemon経由でsrc/app.jsが起動された。


#参考文献
[nodemonを使用して、コード変更後に自動でNode.jsのアプリを再起動する方法。](https://blog.officekoma.co.jp/2020/05/nodemonnodejs.html)
[nodemonで自動再起動【開発時の手間削減】](https://www.wakuwakubank.com/posts/680-nodejs-nodemon/)
【Java Silver】初期化について

#インスタンスの初期化
- **コンストラクタ**で初期化処理を行う
- **インスタンス変数**は、**インスタンス作成時**に初期化される

※**定数（final）**も**コンストラクタで初期化**できる
クラスに定義された、初期化されていない定数は、コンストラクタで初期化できる

例）

```java
public class Main{
   public static void main(String[] args){
       Sample a = new Sample(5);
       System.out.println(a.num);   //５と表示される

   }
}

class Sample{
     final int num;  //この時点で定数フィールドは初期化されていない
     Sample(int num){  //int num はインスタンス変数と同名のローカル変数
         this.num = num;  //コンストラクタで定数を初期化
     }
}
```


#コンストラクタの共通処理を初期化する

- { }　という初期化子（インスタンスイニシャライザ）を利用する
- コンストラクタがオーバーロードされて複数ある場合、共通処理をインスタンスイニシャライザで先に在以降できる
- インスタンスイニシャライザは、**インスタンス化される直前**に実行される

例）

```java
public class Main{
   public static void main(String[] args){
       Sample a = new Sample(5);    //「インスタンスイニシャライザを実行」
       System.out.println(a.num);   //5
       
       Sample b = new Sample();    //「インスタンスイニシャライザを実行」
       System.out.println(b.num);  //10

   }
}

class Sample{
     final int num;  //この時点で定数フィールドは初期化されていない
     {
        System.out.println("インスタンスイニシャライザを実行"); 
     }
     Sample(){
         this.num = 10;
     }
     Sample(int num){  
         this.num = num;  //コンストラクタで定数を初期化
     }
}

```

#staticフィールドを初期化する
staticフィールドはインスタンスを生成しなくても利用できる。
そのため、**コンストラクタで初期化できない**

→static初期化子(イニシャライザ)で初期化する必要がある

例）

```java
public class Main{
   public static void main(String[] args){       
       System.out.println(Sample.num);  //100と出力
   }
}

class Sample{
     static final int num;  //この時点でstaticな定数は初期化されていない
     static {
        num = 100;  //staticな定数の初期化
     }     
}
```

#初期化子が動作する順番

**イニシャライザ→インスタンスイニシャライザ→コンストラクタ**

例）

```java
public class Main{
   public static void main(String[] args){
       User a = new User();   //「イニシャライザの実行　インスタンスイニシャライザの実行　コンストラクタの実行」と出力
  }

}

class User{
  private static int count;
  static{
      User.count = 0;  //static変数を初期化
　　　 System.out.println("イニシャライザの実行");
  }
 
  {
     System.out.println("インスタンスイニシャライザの実行");
  }

  User(){
     System.out.println("コンストラクタの実行");
  }
}
```
DockerのゲストOSをCentOS 7.4として古いVivadoを動かす

# Linux版Vivadoの動作環境について
　 みなさんこんにちは。よくFPGA開発をする際問題になるのは，Vivadoのバージョンだったりします。
何年も前から続いてるプロジェクトだったりするとどうしても最新のVivadoが使えないケースも出てきます。
このとき困るのは，VivadoをLinux上で動かす必要があるときです。

Xilinxのページによると，Vivado 2018.2が動作可能なLinuxとしては

 - Red Hat Enterprise Workstation/Server 7.2、 7.3、 および 7.4 (64 ビッ ト )
 - Red Hat Enterprise Workstation 6.6、 6.7、 6.8、 および 6.9 (64 ビッ ト )
 - SUSE Linux Enterprise 11.4 および 12.3 (64 ビッ ト )
 - CentOS 7.2、 7.3、 および 7.4 (64 ビッ ト )
 - CentOS 6.7、 6.8、 および 6.9 (64 ビッ ト )
 - Ubuntu Linux 16.04.3 LTS (64 ビッ ト )
 
が挙げられています。どれもこれも少なくとも3年くらい前の古いOSです。
急遽Vivado 2018.2が必要になったからといって，新しい環境のPCを仕立ててくるのも，大変です。
そこでDockerの出番です。

# 試した環境

## ホスト側OS
- Ubuntu 20.04 LTS
- Dockerはaptからインストールできるものを使用

## ゲスト側OS
- Cent OS 7.4

# 手順

## Dockerfileを用意する
まず次のようなDockerfileを用意しました。

```Dockerfile
FROM centos:7.4.1708

RUN yum update -y
RUN yum groupinstall -y "Development Tools"
RUN yum install -y kernel-devel kernel-headers
RUN yum install -y gtk2-devel
RUN yum install -y libcanberra libcanberra-devel
RUN yum install xauth libXtst libXrender -y
RUN yum install -y xeyes
RUN yum install -y sudo
RUN yum clean all

ARG uid=1000
ARG gid=1000
RUN groupadd -g ${uid} kohei && \
    useradd -u ${gid} -g kohei -G wheel,root kohei && \
    chown ${uid}:${gid} -R /home/kohei

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'kohei ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER kohei
WORKDIR /home/kohei
```
Dockerfileでは開発ツール一式，X11クライアントとして動かすために必要なもの一式，sudoをインストールするようにしています。
また当初試したときいくつかのライブラリが不足したため，それを補うようにしてあります。

パスワード無しでsudoできるようにもしてあります。

## Dockerイメージのビルド
このDockerfileからビルドするイメージをcentos_xilとして次のコマンドでビルドを行います。

```bash
docker build -t centos_xil .
```

## ビルドしたイメージの起動
```bash
docker run -ti --rm --name centos_xil \
           -e DISPLAY=$DISPLAY \
           -v /tmp/.X11-unix/:/tmp/.X11-unix \ 
           -v /home/kohei:/home/kohei \
           centos_xil /bin/bash
```
ここで注意しておきたいのは，まずゲストOS側でアプリケーションを実行して，ホスト側のXサーバにGUIが表示されるようにするため，
環境変数`DISPLAY`をコンテナに渡し，X11の環境をマウントによってコンテナとホスト側で共有するようにしていることです。
次にホームディレクトリを共有していることにも注目する必要があります。Vivadoのインストールによってイメージが肥大することを防いだり，開発環境をコンテナとホスト側でやりとりしたりする手間を省く効果を狙っています。

## Vivadoのインストール
コンテナ上でVivadoのインストーラを実行します。インストーラはホームディレクトリに一時ファイル置き場を作ってそこにダウンロードしておくのが良いでしょう。日本語の名前になっている「ダウンロード」ディレクトリには入れない可能性があります。インストール先は権限の問題などもあり，`~/Xilinx`としました。

## VivadoとSDKの動作確認
上記の手順を踏むことで，問題なくVivadoとSDKが起動することは確認できました。

Vivadoについてはデザインのコンパイルも問題なく行えました。

# 参照したページ(順不同)
- [X11とDockerを少し(でも)理解した(い)](https://gilito.net/20200522/258/)

- [Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105)

- [Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（2)](https://qiita.com/yamada-hakase/items/80cef4ed58fefbba266b)

- [Docker でGUIを立ち上げる＋sudoを使う方法](https://marsee101.blog.fc2.com/blog-entry-4438.html)

- [Xilinx用docker環境の構築
](https://aster-ism.hatenablog.com/entry/2019/02/17/164042)
SwiftUIとりあえず試すまで

# Swift UIの体験の仕方
SwiftUIを体験したり、試すのに必要な手順です。

## とりあえずアプリで使えるまで
1. 新しいプロジェクトを作る
2. Applicationを選択(Single View Appで良い)
3. プロジェクトのオプションで`Language: Swift`、`UserInterface: SwiftUI`で選択する
![スクリーンショット 2020-09-12 16.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/b48716e6-6bf2-3653-1082-425b8651f473.png)


4. コードは既に生成されているので実行する。

ちなみにObjectiveCとSwiftUIの組み合わせは選択できません。


できた！
<img width=240 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/23fd56d8-079a-8b4c-ab75-6d8ee4fd0240.png />


## とりあえずPlaygroundで試せるようにするまで。

1. Playgroundを開いて、以下を記入、実行する。

```swift
import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

// playgroundでの実行に必要
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())
```

できた！
![スクリーンショット 2020-09-12 16.43.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/10712b6e-b6e4-9741-96a7-c751049b584f.png)

# ツールの使い方。
Playgroundは基本的に実行ボタンを押すだけです。こちらでは主にXcodeでProjectを開発している時の使い方について書きます。

## プレビュー機能
簡単にSwiftUIのコードを試せる機能があります。

右上にある**Resume**ボタンを押しましょう。
![スクリーンショット 2020-09-12 16.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/e92db9e7-cb06-19b2-d883-5579cba6ddc1.png)

この状態でコードを変更すると、UIのプレビューも同時に変わります。

### GUIを利用してUIを修正する
Commandを押しながら、UI部品をクリックすると、メニューが出ます。
Show SwiftUI Inspectorを選択すると、その部品の操作が直感的に行えます。

#### Command + Clickでメニュー
![スクリーンショット 2020-09-12 17.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/0fb26a2e-94cd-fbb1-69f0-70c652153400.png)


#### Inspector
![スクリーンショット 2020-09-12 17.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/84b1d35b-e179-474d-c55a-8f705535a1bc.png)

Inspector上で変更した項目は、SwiftUIのコード側にも自動で反映されます。

* InspectorはUI部品を選択して、`Command + Option + 4`でも呼び出せます！ 
* SwiftUIのコードのUI部品を`Command + Click`でもメニューは出せます。

# まとめ
Swift UI是非試してみてください。
冗長構成をもつネットワーク（システムアーキテクチャ）－午後

応用情報技術者平成28年春期 午後4

ファイル：2016h28h_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/28_haru/pm04.html

メモを簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。

１、本文中の下線①について，(1)，(2)に答えよ。ここで，L3SW及びL2SWの稼働率はともにα(0＜α＜1)とし，L3SWとL2SW以外の機器の稼働率は1とする。
（１）、L3SW，L2SWが1台ずつで冗長性がない構成の稼働率を答えよ。
L2SW1とL3SW1は直列ですね。a^2です。

（２）、図1のように，L3SW，L2SWが2系統に構成された業務ネットワークの稼働率を答えよ。
冗長構成あり場合、L2SW1とL3SW1を直列して、並列になります。
1-(1-a^2)^2ですね。

※稼働率
　・直列
　　Ra　×　Rb

　・並列
　　１－（１－Ra)　×　（１－Rb)

＜＜図１＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/bde5eff6-20a6-ecbd-f840-d89f43a42523.png)


２、〔業務サーバの更新検討〕について，(1)，(2)に答えよ。
（１）、本文中のaに入れる適切な数値を答えよ。答えは，小数第2位を四捨五入して小数第1位まで求めよ。
サーバは下記を更新している：
　・CPUが更新　新は旧の２倍/コア
　・コア数更新
　・メモリ更新　新は旧の２倍/メモリ　ただ、メモリサイズと関係ない

なので、新は旧の　２＊２＊２＝８倍速くなる。
処理時間が新は８時間/８＝１時間になる。
注意するところ：小数一位までが必要ので、１．０時間ですね。


（２）、新サーバの諸元は本文中の下線②の目標を満たしているか。満たしていない場合は1CPU当たりのコア数を最少幾つにすればよいか，2のべき乗数(4，8，16，32，…)で答えよ。満たしている場合は表1と同じ"2"と答えよ。
業務の改善により、バッチ処理時間が１０倍（＝８０時間）になる。
８０時間／８＝１０時間。つまり、新サーバは１０時間が必要ですね。＞目標（＝現行の８時間）ので、だめですね。
４コアはどうなりますか？
新は旧の２＊４＊２＝１６倍速くなる。
８０時間／１６＝５時間。それで目標を達しますね。


＜＜業務サーバの更新検討＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/328e18f0-7d3a-86a7-8b84-324260098bf1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/b784bfda-2291-f828-45ae-f10aa4c0384e.png)


＜＜業務の改善＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c6ad1d1a-61c3-ebfe-2f1b-8dd766b8b809.png)


３、本文中のU氏のコメントⅰについて，(1)，(2)に答えよ。
（１）、どのリンクが帯域不足となるか。ア～クの記号で全て答えよ。
現状のピークは０．３Gb/sですね。５年後は、１０倍になる想定ので、３Gb/sになりますね。
なので、ア、イは２本LAで２Gb/sになるが、足りないですね。

（２）、LAを利用する場合，1Gビット／秒のリンクを最少何本束ねればよいか。数字で答えよ。
３本でたります。

＜＜業務サーバの更新に伴うネットワークの見直し＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/50ea3eab-e09f-2911-0cfa-ffaef5ec7be9.png)


４、本文中のU氏のコメントⅱについて，確認しておくべき性能要件を20字以内で答えよ。
「各スイッチのスループットは，現行の各処理が必要とする通信量に見合っている。」という記載がありますが、処理データ量や通信量が増加した後にスイッチのスループットが十分であるかを検証していません。

バッチ処理は3台の業務サーバの間でL2SWを経由して通信し実行するので、たとえ通信回線の帯域が充足していても、スイッチの処理能力が不足しているとボトルネックになり、バッチ処理が既定時間内に終了しなくなってしまうことが考えられます。

したがって、L2SWについて確認しておくべき性能要件は「スループットが通信量に見合うこと」となります。

スイッチのスループット最大値（私の答え）
→
スループットが通信量に見合うこと（参照の答え）
Ruby と Python で解く AtCoder ABC178 D 動的計画法

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[AtCoder Beginner Contest D - Redistribution](https://atcoder.jp/contests/abc178/tasks/abc178_d)*
<font color="green">Difficulty: 830</font>

今回のテーマ、動的計画法

いわゆる典型的な動的計画法の問題です。
*[前の記事 - Qiita](https://qiita.com/superrino130/items/a00e035222911da60d1e)* で取り上げました、*[AtCoder Beginner Contest E - Crested Ibis vs Monster](https://atcoder.jp/contests/abc153/tasks/abc153_e)* では、目標値を超えてた場合もケアしないといけませんが、今回はジャストでよいので、その分少し簡単です。
# Ruby
```ruby.rb
s = gets.to_i
dp = Array.new(s.next, 0)
dp[0] = 1
s.times do |i|
  next if dp[i].zero?
  3.upto(s) do |x|
    if i + x <= s
      dp[i + x] += dp[i]
      dp[i + x] %= 1000000007
    else
      break
    end
  end
end
puts dp[s]
```
```ruby.rb
    if i + x <= s
      dp[i + x] += dp[i]
      dp[i + x] %= 1000000007
    else
      break
    end
```
今回はジャストでよいので、`i + x <= s`についてのみdpを加算します。
# Python
```python.py
from sys import stdin

def main():
    input = stdin.readline

    s = int(input())
    dp = [0] * (s + 1)
    dp[0] = 1
    for i in range(s):
        if dp[i] == 0:
            continue
        for x in range(3, s + 1):
            if i + x <= s:
                dp[i + x] += dp[i]
                dp[i + x] %= 1000000007
            else:
                break
    print(dp[s])
main()
```
***PyPy*** は凄く速いですね。

||Ruby|Python|PyPy|
|:--:|:--:|:--:|:--:|
|コード長 (Byte)|244|405|405|
|実行時間 (ms)|284|509|70|
|メモリ (KB)|14400|9060|64596|
# まとめ
+ ABC 178 D を解いた
+ Ruby に詳しくなった
+ Python に詳しくなった

参照したサイト
*[Ruby と Python で解く AtCoder ABC153 E 動的計画法 - Qiita](https://qiita.com/superrino130/items/a00e035222911da60d1e)*