OmniAICreator/Qiita-1.07M huggingface dataset:
SQLだけでランダム抽出

SQLだけでrandomに値を抽出する方法です。
SQLServerを題材に実際に抽出するクエリのサンプルを用いて説明します。

# やりたいこと

ユーザごとにお気に入り登録している商品があり、商品は複数存在するカテゴリーのどれかに属しているとします。全てのユーザーに対しカテゴリ毎にランダムで1件抽出して、カテゴリーの種類数分の商品をユーザに紐づけることを目指します。

# データ

    CREATE TABLE Member (
    	id int,
    	name text
    );
    
    CREATE TABLE MemberFavoriteItem (
    	member_id int,
    	item_id int
    );
    
    CREATE TABLE Item (
    	id int,
    	category_id int,
    	name text
    );
    
    -- 最終的に作りたいデータ
    CREATE TABLE UserRandomCategoryItem (
    	member_name text,
    	category_id int,
    	item_name text
    )

# 抽出方法

### STEP 1

全ての対象データを結合し、ウィンドウ関数で分割したデータの中にランダムな連続する値を持たせます。ポイントはウィンドウ関数でランダム化したい単位に分割して、カテゴリーの中に含まれるitem_idの中でランダムな値を割り振っているところです。
<b>注意点</b>
* SQLServerではテーブル名の先頭に#をつけるとtempテーブル
* NEWID()によってレコード毎にユニークな文字列を付与し、それを基準にORDER BYした結果にROW_NUMBERを付与することでランダムな順序を実現している。NEWID()ではなくRAND()を使いたかったが、シードをユニークにしないと値が同じになってしまうので使っていない

### STEP2
ランダムに割り振った数値を見て必要な個数分where句で絞ります。
※ウィンドウ関数の結果は直接whereで指定できないので、一度tempテーブルを経由するか、サブクエリとして用いる必要があります。

### 実際のクエリ
    -- STEP1
    SELECT
        Member.name AS member_name,
        Item.category_id AS category_id,
        Item.name as item_name,
        ROW_NUMBER() OVER(PARTITION BY member_id, category_id ORDER BY NEWID()) AS random_num
    INTO #AggregateResult
    FROM
        Member
        INNER JOIN MemberFavoriteItem ON Member.id = MemberFavoriteItem.member_id
        INNER JOIN Item ON MemberFavoriteItem.item_id = Item.id
    ;
    
    -- STEP2
    INSERT INTO MemberRandomCategoryItem
    SELECT
        member_name,
        category_id,
        item_name
    FROM
         #AggregateResult
    WHERE
        -- カテゴリ毎に複数種類欲しいなら数を変える
        random_num <= 1

# SQLServerでやってみる

検証用データを用意する

    INSERT INTO Member
    VALUES
    	(1, 'hoge'),
    	(2, 'hero'),
    	(3, 'fuga')
    ;
    
    INSERT INTO MemberFavoriteItem
    VALUES
        (1, 1),
        (1, 2),
        (1, 3),
        (1, 4),
        (1, 5),
        (1, 6),
        (1, 7),
        (1, 8),
        (1, 9),
        (2, 1),
        (2, 2),
        (2, 3),
        (2, 4),
        (2, 5),
        (2, 6),
        (2, 7),
        (2, 8),
        (2, 9),
        (3, 1),
        (3, 2),
        (3, 3),
        (3, 4),
        (3, 5),
        (3, 6),
        (3, 7),
        (3, 8),
        (3, 9)
    ;
    
    INSERT INTO Item
    VALUES
        (1, 1, 'apple'),
        (2, 1, 'orange'),
        (3, 1, 'lemon'),
        (4, 2, 'chocolate'),
        (5, 2, 'cookie'),
        (6, 2, 'candy'),
        (7, 3, 'tea'),
        (8, 3, 'milk'),
        (9, 3, 'coffee')

結果

[](https://www.notion.so/5fd47cc19a884b30abcd976a09cfd392#6111c63084364cb8b5c11aa09db04cb0)

全てのメンバーに対してカテゴリ毎に1件ランダムで結果が返ってきました。
<img width="363" alt="スクリーンショット 2019-02-11 22.42.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/13766/7e35afe9-bcf4-b8c6-5b3f-95e85dff3eca.png">

実行するたびに結果は変わります。
pythonで伝説の東大入試問題に挑んでみた

詳細! Python3 入門ノート
Chapter4~5の理解度確認用に取り組んでみました。

解法はこちらの動画を参考にさせて頂きました。

https://www.youtube.com/watch?v=uO6dPVWp8CY


直径2の円に内接する正n角形の辺の長さを求める。
頂点を増やして辺の長さを円周に近似させ、入力値より大きくなることを確認する。

```todai_math.py
import math
# [π > 3.05 を証明せよ]
while True:
    target_input = input("円周率がいくつより大きいことを証明しますか？")
    try: #入力値チェック
        target = float(target_input)
    except ValueError:
        print("数値を入力してください。")
    else:
        # 入力値が円周率より大きいと無限ループするため入力値をチェック
        if target <= math.pi:
            break
        else:
            print("円周率より小さい値を入力してください。")
print("円周率が{}より大きいことを証明する".format(target))
print("")
#正ｎ角形の頂点の初期値を3にセット
n = 3
# breakするまでループさせる
while True:
    # 等辺の長さ1、頂角360/nの二等辺三角形の底辺の長さを求める
    kakudo = 360 / n
    # math関数の三角関数計算ではラジアンを用いるので度→ラジアンの変換が必要
    radian_kakudo = math.radians( kakudo )
    # 余弦定理から、底辺 x の長さは[x ^ 2 = 1 ^ 2 + 1 ^ 2 + 2 * 1 * 1 * cos(360 / n)]
    x = ( 1*1 + 1*1 - 2*1*1*math.cos( radian_kakudo ) ) ** 0.5
    # 底辺の長さ * ｎを円周の近似値 y とする
    y = x * n
    print("正{0}角形のとき、辺の長さの合計は{1}".format(n , y))
    if y / 2 > target: #目標値より大きくなったらブレイクして終了処理へ
        break
    # 頂点を1つ増やす
    n = n + 1

print("")
print("円周率 = 円周 / 直径")
print("")
print("{0} / 2 = {1} > {2}".format(y , y / 2 , target))
print("")
print("よって円周率は{}より大きい".format(target))
if __name__ == '__main__'　とはなにか

コードの例などでよく見る ```if __name__ == '__main__'```について、ずっとモヤらせていたものを調べたので記録。

#if __name__ == '__main__' とはなにか
簡単に言えば、「外部からimportして読み込んだときに実行されないようにするため」のもの。

pythonは同じディレクトリであれば```import ファイル名```でモジュールとして読み込みができる。この読み込みのときにはコード全体が実行されるため、平文で書いていたらimportしたときに値が返ってきてしまう。

たとえば、
```python:hello.py
print('hello world')
```
上のコードを別のファイルから ```import hello```とすると読み込めるが、読み込みと同時に`hello world`と返ってきてしまう。これはいけてない。し、場合によっては不具合がでうる。

それを防ぐためには、
```python:hello.py
if __name__ == '__main__':
    print('hello world')
```
とするだけでOK。

#なぜか
どうやらimportする際には内部で`__name__`という変数にモジュール名が与えられているらしい。

hello.pyをモジュールとして実行すると`__name__`は`hello`になる。
なのでif文は実行されなかったという仕組みっぽい。
Angularのe2eテスト(Protractor)でng serveとは別のURLにアクセスさせる方法 

# やりたかったこと
ある日私はこう思いました。
`ng serve`をすると`localhost:4200`でAngularアプリケーションが起動するけど、間に別の機構を挟んでいるのでテストは`localhost:4202`(=別のurl)で実行して欲しい！と。

というのも、デフォルトでは`ng e2e`を走らせると`ng serve`が自動で実行され、その後serveで立ち上がったアドレスでテストが始まるのです。今回はこの問題を解決するために行った
**1. e2eを実行するbaseUrlを変更する**
**2. ng e2eでserveを実行しない設定をする**
の２ステップに必要な手順をまとめていきます。

# baseUrlを設定する
まずはじめに、e2eの設定が記載してある`protractor.conf.js`を開きます。その中の

```js:proctractor.conf.js
baseUrl: 'http://localhost:4202/',
```
をお好みのurlに変更します。

# ng e2eでserveを実行しない設定をする
[こちらの2018年のangular-cliのissue](https://github.com/angular/angular-cli/issues/10741)を参考に`angular.json`に以下の内容を追加し、

```javascript:angular.json
...
    "<my-project>-e2e": {
      ...
      "architect": {
        "e2e": {
          ...
          "configurations": { // ココ
            "noserve": {
              "devServerTarget": ""
            }
          }
        },
      ...
      }
    }
...
```
`ng e2e --configuration=noserve`でテストを起動します。
この時、テストコマンドを走らせる前に自分で`ng serve`するのを忘れないようにしてください。これで、無事テストがlocalhost:4202で立ち上がるようになります:snowman:

ちなみに、[2017年のangular-cliのissue](https://github.com/angular/angular-cli/issues/5705)によれば`ng e2e`の代わりに`ng e2e --no-serve`とするだけで良いとのことでしたが、現在はただオプションをつけるだけではうまくいきません。(少なくとも私の手元ではできませんでした)

---
こうして初めて画面テストを書いてみていますが、
個人的には単体テストよりもするする書けるので楽しめています。
書いたことのない人もぜひ挑戦してみてください！
最後まで目を通していただきありがとうございました:dog2:
macOS からの IntelliJ CEのアンインストール方法

1. ApplicationsフォルダからIntelliJのアイコンをゴミ箱へ
2. 設定やキャッシュファイルの削除。場所は以下の通り

```bash
# 設定
ls ~/Library/Preferences/ |grep IdeaIC
rm -fr ~/Library/Preferences/IdeaIC2018.2
rm -fr ~/Library/Preferences/IdeaIC2018.3

# キャッシュ
ls ~/Library/Caches/ |grep IdeaIC
rm -fr ~/Library/Caches/IdeaIC2018.2
rm -fr ~/Library/Caches/IdeaIC2018.3

#プラグイン
ls ~/Library/Application\ Support/ |grep IdeaIC
rm -fr ~/Library/Application\ Support/IdeaIC2018.2
rm -fr ~/Library/Application\ Support/IdeaIC2018.3

# ログ
ls ~/Library/Logs/ |grep IdeaIC
rm -fr ~/Library/Logs/IdeaIC2018.2
rm -fr ~/Library/Logs/IdeaIC2018.3

```

### 環境
- macOS mojave
- IntelliJ CE 2018.03 (アップデート前のものも残っていた模様）
Macで使うmatplotlibのbackendエラー

# はじめに
pythonを使ったデータ解析環境として、まず用意したいライブラリの一つが、matplotlibだと思います。少なくとも僕はそう思っています。
なので、macのpython環境でもまずmatplotlibを入れることを考えました。

# matplotlibのインストールと実行
とりあえずpipenv環境をactivateして、いつも通り下記を実行すると問題なくするっと入ります。

```bash
$ pip install matplotlib
```
じゃあいけるだろうと思い、下記を実行。

```python:main.py
import matplotlib.pyplot as plt
a = [1, 2, 5, 4, 3]
plt.plot(a)
```
```bash
ImportError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are using (Ana)Conda please install python.app and replace the use of 'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more information.
```
なんかエラー出た。。

# macでのmatplotlibインストール エラー対策
どうやらmacあるあるらしく、たくさん解決法が書いてありました。
matplotlibのmatplotlibrcファイルのbackendをmacosxから、TkAggに変えろ、というもの。
早速、matplotlibrcの場所を下記コマンドで調べて書き換える。

```python
import matplotlib
matplotlib.matplotlib_fname()

.venv/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc'
```
```:matplotlibrc
# backend: macosx
backend: TkAgg
```
そして、また実行してみると、
<img width="752" alt="white.png" src="https://qiita-image-store.s3.amazonaws.com/0/204712/1952c838-3889-2c1e-b81d-918a83e7e6dc.png">
いやいや、グラフ出ないじゃん。

ということで、別情報を得て、backendをQtAggに変更するとできると知る。GUIとしてPyQtを使う手のようです。下記の方法でうまくいきました。

```
$ pip install PyQt5
```
```:matplotlibrc
# backend: macosx
# backend: TkAgg
backend: Qt5Agg
```
これで、matplotlibのコードを動かすと・・
<img width="752" alt="graph.png" src="https://qiita-image-store.s3.amazonaws.com/0/204712/8a970cc5-daba-012e-b612-d771793b7d58.png">
動きました。

# まとめ
とりあえず2019/2の段階では、PyQt5をインストールして、backendをQt5Aggにすれば動きそうです。Qt4Aggにすれば動くという話も出回っていますが、私の環境ではうまくいきませんでした。
皆さんのご参考になれば。
jsdoでget

#概要

jsdoで、getリクエストを受けてみた。
postは、無理。

#参考にしたぺージ

https://qiita.com/Evolutor_web/items/c9b940f752883676b35d

#サンプルコード


```
var getUrlVars = function() {
    var vars = {}; 
    var param = location.search.substring(1).split('&');
    for (var i = 0; i < param.length; i++)
    {
        var keySearch = param[i].search(/=/);
        var key = '';
        if (keySearch != -1) key = param[i].slice(0, keySearch);
        var val = param[i].slice(param[i].indexOf('=', 0) + 1);
        if (key != '') vars[key] = decodeURI(val);
    } 
    return vars; 
}
var q = getUrlVars();
alert(q['a']);
alert(q['b']);
```

#成果物

http://jsdo.it/ohisama1/qJlnU

以上。
[AWS SDK for Go] 異なる AWS アカウントの IAM ロールを使用する方法

# はじめに
本格的に AWS の運用を行いたい場合、開発用 / 本番用 AWS アカウントなど、異なる用途の複数 AWS アカウントを使い分ける事が多いかと思います。

開発者が操作したい AWS アカウントを切り替えるとき、マネジメントコンソールでは一般的に [IAM ロールの切り替え](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-console.html)を行います。AWS CLI や AWS SDK を利用したプログラムでは、AWS STS で[一時的なセキュリティ認証情報のリクエスト](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_request.html)を行う必要があります。

今回は AWS SDK for Go を使用して、一時的な認証情報を取得する方法を紹介します。

# 環境
- macOS Mojave 10.14.3
- go version go1.9.4 darwin/amd64
- aws-sdk-go: Release v1.16.29

## 事前準備
- 開発用/本番用などの AWS アカウントを 2 つ以上用意する。
- 開発用アカウントの IAM ユーザーのクレデンシャルを `aws configure` コマンドから設定する。（`~/.aws/credentials` が存在すること。）
    - 開発用アカウントの IAM ユーザーには `sts:AssumeRole` のポリシーが許可されている状態にする。
- 本番用アカウントの IAM ロールを任意の権限で作成し、`Principal` 句で開発用アカウントおよび IAM ユーザーからアクセスできる状態にする。

# サンプルコード
以下は AWS STS の [AssumeRole](https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/stscreds/) を使用して、異なる AWS アカウントの EC2 インスタンス情報を取得するサンプルコードです。

コード中の `profile`, `region`, `roleArn` 変数はご利用の環境に合わせて変更してください。

```main.go
package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ec2"
)

var (
	profile = "default"
	region  = "ap-northeast-1"
	// FIXME: Rewrite your AWS Account ID and IAM Role Name.
	roleArn = "arn:aws:iam::<123456789012>:role/<Your-Role-Name>"
)

// AssumeRoleWithSession returns switched role session from argument session and IAM role's arn in same region.
func AssumeRoleWithSession(sess *session.Session, rolearn string) *session.Session {
	sCreds := stscreds.NewCredentials(sess, rolearn)
	sConfig := aws.Config{Region: sess.Config.Region, Credentials: sCreds}
	sSess := session.New(&sConfig)

	return sSess
}

func main() {
	// Get credentials from default(~/.aws/credentials) path.
	// 開発環境などで使用している認証情報を取得する。
	creds := credentials.NewSharedCredentials("", profile)
	config := aws.Config{Region: aws.String(region), Credentials: creds}
	dSess := session.New(&config)

	// Get the Switched Role Session.
	// 本番環境など、開発環境で使用している認証情報を取得する。
	sSess := AssumeRoleWithSession(dSess, roleArn)

	// Example: Get EC2 info using the switched session.
	// 開発環境の認証情報から、本番環境の EC2 情報などが（IAM ロールの権限で許可された範囲内で）取得できる。
	result, _ := ec2.New(sSess).DescribeInstances(nil)
	fmt.Println(result)
}

```

## おわりに
筆者が検証した際に、AWS SDK for Go での AssumeRole の日本語記事がさっと見つからなかったので記事にしました。

どなたかのお役に立てば幸いです。

## 参考 AWS 公式ドキュメント
- [Getting Started with the AWS SDK for Go - AWS SDK for Go](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html)
- [stscreds - Amazon Web Services - Go SDK](https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/stscreds/)
rbenv で Rails 環境をローカルに作る

今どき Docker じゃなくて、Mac に Rails 環境を作る方法。

グローバルで使う Ruby の設定

```sh
$ rbenv global 2.6.1
$ rbenv rehash
$ ruby -v
```

Rails に依存する gem はすべて bundler 経由でインストールして、ローカルに保存する。グローバルの Ruby 環境は極力汚さない。

Ruby 2.6.1 のデフォルトの gem はこんなかんじ。

```sh
$ rbenv exec gem list
```

```
bigdecimal (default: 1.4.1)
bundler (default: 1.17.2)
cmath (default: 1.0.0)
csv (default: 3.0.4)
date (default: 2.0.0)
dbm (default: 1.0.0)
did_you_mean (1.3.0)
e2mmap (default: 0.1.0)
etc (default: 1.0.1)
fcntl (default: 1.0.0)
fiddle (default: 1.0.0)
fileutils (default: 1.1.0)
forwardable (default: 1.2.0)
io-console (default: 0.4.7)
ipaddr (default: 1.2.2)
irb (default: 1.0.0)
json (default: 2.1.0)
logger (default: 1.3.0)
matrix (default: 0.1.0)
minitest (5.11.3)
mutex_m (default: 0.1.0)
net-telnet (0.2.0)
openssl (default: 2.1.2)
ostruct (default: 0.1.0)
power_assert (1.1.3)
prime (default: 0.1.0)
psych (default: 3.1.0)
rake (12.3.2)
rdoc (default: 6.1.0)
rexml (default: 3.1.9)
rss (default: 0.2.7)
scanf (default: 1.0.0)
sdbm (default: 1.0.0)
shell (default: 0.7)
stringio (default: 0.0.2)
strscan (default: 1.0.0)
sync (default: 0.5.0)
test-unit (3.2.9)
thwait (default: 0.1.0)
tracer (default: 0.1.0)
webrick (default: 1.4.2)
xmlrpc (0.3.0)
zlib (default: 1.0.0)
```

パッケージマネージャの bundler はグローバルにインストールする

```sh
$ rbenv exec gem install bundler
$ rbenv rehash
```

Rails をローカルインストール

```sh
$ mkdir create-rails-project
$ cd create-rails-project
```

Gemfile を作る

```sh
$ cat << EOS > Gemfile
source "http://rubygems.org"
gem "rails", "5.2.2"
EOS
```

Rails を `vender/bundle` にインストールする

```sh
$ bundle install --path vendor/bundle
```

これで『ガワ』を作ったことになるので、このディレクトリ内で Rails プロジェクトを作る。

```sh
$ bundle exec rails new my-app --skip-bundle
```

`--skip-bundle` を必ず忘れないように。これを忘れると、グローバルの Ruby 環境に依存 gem がインストールされてしまう。

また、`bundle exec rails new my-app -BCMT --skip-coffee -d sqlite3` とすると、 `skip-bundle`, `skip-action-cable`, `skip-action-mailer`, `skip-test` と CoffeeScriptのインストールがキャンセルされるので便利。-dは使用するデータベース種別を指定する。

こういう構成になった。

```
.
├── Gemfile
├── Gemfile.lock
├── my-app
└── vendor
```

`my-app` が実際に開発する Rails 環境になる。

```sh
$ mv my-app ../
$ cd ..
$ cd my-app
```

gem をローカルにインストールする。

```sh
$ bundle install --path vendor/bundle
```

`vendor/bundle` を git の管理外にする。

```sh
$ echo '/vendor/bundle' >> .gitignore
```

bundle lockコマンドの実行

```sh
$ bundle lock --add-platform x64-mingw32 x86-mingw32
```

このコマンドを実行しておくと、bundle install時の `The dependency tzinfo-data (>= 0) will...`のワーニングが表示されなくなる。

起動してみる。

```
$ bundle exec rails s
```

成功。
『エンジニアが死滅シタ世界』解答例その1

今回は『[エンジニアが死滅シタ世界 アンドロイドとふたりぼっちで生きろ](https://paiza.jp/botchi/)』の解答例および簡単な解説を書いてみたい。なお、今回はDランクの問題について簡単に解答例のコードを書いてみたい。

# 前提条件

今回はPython 3で書いた。多くの場合は他の言語でも応用は効くが、Python特有の仕様が絡む場合は特記事項として注意書きを行いたい。

# 解答例コード

## 荒れ果てた警察署

### 解答例

```police.py
# coding: utf-8
num = 0
arr = input().split(' ')
for item in arr:
  num += int(item)

print(num % 10)
```

### 解説

今回の場合は数字Aと数字Bが半角空白を挟んで入力されるので、それを `split(' ')` で分割すればよい。

なお、今回の場合は以下のようにストレートに加算しても問題ないが、可変長だった場合は対応できないため、 `for` ループで回すのが無難である。

```police_fair.py
arr = input().split(' ')
num1 = int(arr[0])
num2 = int(arr[1])
print((num1 + num2) % 10)
```

## 荒れ果てたオフィス

### 解答例

```office.py
# coding: utf-8
times = int(input())

for i in range(times):
    pair = input().split(' ')
    if int(pair[1]) == 3:
        print(pair[0])
```

### 解説

これは、出力すべき文字列と優先度が空白を挟んで入力されるので、それを分割して、優先度が3であれば出力するというように、基本的にストレートに書けば問題ない。

## アンドロドの生産工場

### 解答例

```fab.py
# coding: utf-8
text = input()
raw = ""
for i, ch in enumerate(text):
    if i % 2 == 0:
        raw += ch
print(raw)
```

### 解説

これは、入力された文字列から(1から始めた場合)奇数の番目の文字を抽出して結果を出力するものである。Pythonにおいては、 `enumerate(str)` 関数でインデックスと文字がペアになって取得できるので、それを使う。

なお、Pythonに限らず、多くのプログラミング言語では、一般的な人間の感覚とは違って、配列のインデックスは0スタートであるため、人間でいう1番目は、プログラム上では0番目として扱われる。したがって、設問で書かれている「奇数文字目」は一般的な人間の感覚でのものであることから、プログラムでは「偶数文字目」を抽出するようにする必要がある。

もし以下のように人間の感覚のように奇数文字目を抽出してしまうと結果間違いになる。

```fab_bad.py
# coding: utf-8
text = input()
raw = ""
for i, ch in enumerate(text):
    if i % 2 == 1:  # これだと人間の感覚でいう偶数文字目になってしまい、不正解になる
        raw += ch
print(raw)
```

もし、人間の感覚のように1スタートとしたい場合は、以下のようにする必要がある。

```fab_alt.py
# coding: utf-8
text = input()
raw = ""
for i, ch in enumerate(text, 1):  # ここで明示的に1スタートにすることで問題が解消される
    if i % 2 == 1:
        raw += ch
print(raw)
```

## お金が引き出せない銀行

### 解答例

```bank.py
# coding: utf-8
balance = int(input())
withdraw = int(input())
rslt = balance - withdraw
if rslt < 0:
    print("error")
else:
    print(rslt)
```

### 解説

1行目は残高、2行目は引出額で、引出額が残高を超えていればエラーを表示、そうでなければ引出し後の額を表示するプログラムである。

なお、 `if rslt < 0:` およびそれ以降の部分は、 `print(rslt if rslt >= 0 else "error")` とすることで、よりシンプルに記載することができるが、Python 3の三項演算子は多くのプログラミング言語で使われている `条件式 ? 真の場合 : 偽の場合` とは違い、 `真の場合 if 条件式 else 偽の場合`となるため、要注意である。

## 錆びついた電波塔

### 解答例

```radio_tower.py
# coding: utf-8
input()

success = 0
arr = input().split(' ')
for str in arr:
    if int(str) > 5:
        success += 1

print(success)
```

### 解説

Pythonでは文字列を分割できるため、最初の1行目は捨てている。

2行目を半角空白で分割し、それぞれを `for` ループで回して5以上なら成功として成功回数に+1すれば良い。

もし1行目の入力を使う場合は、配列の要素数チェックとして用いるのが良いだろう。

# 最後に

今回はDランクの問題のサンプルコードおよび解説ということで、基本的なプログラミングの考え方を知っていればすぐに理解できるだろう。今回はPython 3で書いてみたが、他のプログラミング言語でも基本的な考え方で大きく変わることはほとんどないので、Pythonに限らず他の言語だとどうなるのかを比較しながらやってみると良いだろう。
Reactアプリの本番用ビルド(production)でお手軽にconsole.log()の出力を止める

# 概要

本番環境ではコンソールに不要なログは出力したくないものです。
create-react-appではその手段を提供していないため、自身でやる必要があります。
webpackの設定を使用する方法はあるようですが、create-react-appでは設定ファイルへアクセスするにはイジェクトが必要になります。
そこでイジェクトすることなくお手軽にconsole.log()の出力だけ止めてしまおうという話です。


# 読者対象

- Reactアプリの本番環境で不要なログ出力で困っている。
- だけどcreate-react-appは絶対にイジェクトしなくない。
- consoleのラッパー作ってそれですべて置き換え、中で切り替えるのは面倒。
- ログの内容は仮に見られたとしても問題なく、パフォーマンス低下を防ぐために止めたいだけ。


# Road to disable console.log()

## console.log()を冒頭ですり替えちゃおう(;´∀｀)

create-react-appでプロジェクト作るとsrc/index.jsがあると思います。
このソースはMatarial-UIのサンプルなのでちょっと違うかもしれませんが、要はrender()の前に実行すればOK。
render()の後だとちょっと出力が見られました。

```javascript:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Index from './pages/index';
import * as serviceWorker from './serviceWorker';

// ↓ この一行でnpm run buildの際にconsole.log()を何もしないメソッドにすり替え
process.env.NODE_ENV !== "development" && (console.log = () => {});

ReactDOM.render(<Index />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
```

しっかりif文でやるとこう。

```javascript:index.js
if (process.env.NODE_ENV !== "development") {
    console.log = () => {};
}
```

```npm run build```実行時にはprocess.env.NODE_ENVにはproductionという文字列が入ってきますが、それがもし変更された際への考慮として逆のdevelopmentじゃない場合を条件にしています。
これなら変更あった際、開発段階でログ出力されなくなることから、変更にすぐ気が付くので(;^ω^)
一時的に出力されることに抵抗がないなら、```if (process.env.NODE_ENV === "production")```が直感的でいいかもしれません。


## お手軽といったのには訳がある・・・

もう終了と思ったかもしれませんが注意点があります。
なぜなら、クライアント環境でこれを簡単に戻せる方法があるからです。
ブラウザのデベロッパーツールのコンソール開いて以下を打ち込みます。

```terminal:console
console.log = console.info
```

そしてログ出力されるようなアクションを実行してみてください。
ログ出力が復帰します(　ﾟдﾟ)ポカーン
じゃあinfoもつぶせばOKかというとNoです。
consoleにはlog,debug,info,warn,error等ありますので、気になるならその辺もつぶしましょう(;^_^A
試しにとある人気サイトをのぞいてみると、これらのメソッドがすべて置き換わっていました。


## すり替えのその先の可能性

まだ試してはいないですが、errorの場合にはエラー内容を開発元にフィードバックできそうだなと思いました。
メトリックツール導入していると、機能の一つとしてエラーの際の内容を送ってくれる製品がありますが、あれを自前でやるイメージです。
どのブラウザでどういうエラーが起こったのか把握できるため、開発環境ではわからなかったバグFixに非常に重宝しました。
もしやる機会があってうまくいったら記事にしてみようかと思います。
ツール導入してやることはないかもしれないですが(;^_^A


## おまけ

後でググったところ、1年以上前ですが本家のissueに質問した方がいたようでした。
回答の一つして、同様に空のFunctionですり替え提案されてました(;^_^A
https://github.com/facebook/create-react-app/issues/1491
macOS Mojave で rails s が起動しない

エラーログ

> Puma caught this error: Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? can't activate sqlite3 (~> 1.3.6), already activated sqlite3-1.4.0. Make sure all dependencies are added to Gemfile. (LoadError)

Gemfile の sqlite 箇所を以下のようにしたら治った

```
gem 'sqlite3', '~> 1.3.6'
```
大学の先生でYoutubeに投稿している人まとめ

###個人

照井章　先生
https://www.youtube.com/channel/UCwNU0NVn5vW13C7sOx3jlfg

坂内健一　先生
https://www.youtube.com/channel/UC_regUkO_aie2RXZ3CMbB_w

Andrew Ng　先生
https://www.youtube.com/user/andrewyantakng


### 組織
統計数理研究所
https://www.youtube.com/channel/UCi0d34-fr49EQC9gfIIh9_Q

理研AIP
https://www.youtube.com/channel/UCipPccqvcfychKNOaYUokyQ

慶應義塾大学
https://www.youtube.com/user/keiouniversity

東大TV
https://www.youtube.com/channel/UCGkctuF55veBi7xDGCgcYkw
canvasを画像としてダウンロードさせたかった話

Qiita初投稿につき不作法等あるかと思うので、ご指摘いただけると幸いです。
プログラミングぢからも底辺なため、そちらも合わせてご指導願います。

## やりたかったこと
1. ユーザがWebページ上のボタンをクリックする
2. `<canvas>`の描画内容がpng画像に変換される
3. png画像が自動でダウンロードされる

たった3行の要件に結構な時間かかった。つらい。

## どのように困ったのか
### ①「.click()」がFirefoxで動作しない
#### 【問題】
最初に書いたJavaScriptはこんな感じ。仮想の`<a>`要素を作ってからURLを仕込んでクリックさせればええんちゃう？といった感じ。

```javascript

  let canvas = document.getElementById('targetCanvas')
  let link = document.createElement('a')
  link.href = canvas.toDataURL()
  link.download = 'cancas.png'
  link.click()
```

とりあえず自分のメインブラウザたるChromeで検証したら、あっさり意図したとおりに動いた。いいね！
しかし次にFirefoxで検証したところ、ピクリとも動かず。よくないね！

#### 【原因】
Firefoxでは実在しない要素に対して`.click()`できない模様。まあ気持ちは分かる。

#### 【対策】
A案：`appendChild()`で要素を追加してから`.click()`する。
B案：予めHTML内に`<a id="hoge">`を書いておき、JS側で`href`属性を書き換える。

今回は実装が簡単そうなB案を採用。`<a id="hoge">`がユーザに見えないようCSSで`display: none;`したら、見た目も動作も当初案と同じになって無事解決した。

### ②それでも「.click()」がIE/Edgeで動作しない
#### 【問題】
なんとなく「IE/Edgeはすんなり動いてくれないだろうなあ」と思ってたけど、案の定ノーリアクション。もしやと思って`display: none;`外して手動クリックしてみたら、ページ遷移のエラーが発生した。

#### 【原因】
今回の`link.href = canvas.toDataURL()`の部分は、いわゆる「https://～」の形式ではなくて、「data:image/png;base64,とても長い文字列～」となる。「データURIスキーム」って言うんだって、知らんかった。
なおこれについてWikipediaで調べてみると……

>2018年現在、データURIは主要なほとんどのブラウザで完全にサポートされている。ただし、Internet ExplorerとMicrosoft Edgeでは、一部の機能が実装されていない。

あっはいそうなんすね。マイクロソフトさんさすがっす。

#### 【対策】
当初要件の「png画像を自動でダウンロードさせる」は、IE/Edgeでは実装困難と判断して諦めることに。画像をサーバ側に一回保存して、改めて`<a href="https://hoge.com/image.png">`とかやれば不可能ではないんだろうけど、~~そこまでの技術力は無い~~流石にめんどい。
代用として、ダウンロードさせたかった画像をページ上に小さく表示させ、手動で「右クリック→名前を付けて保存」してもらうことにした。我ながらダサい……もっとスマートなアイディアあったら誰か教えてください。

ちなみにIE/Edgeのときだけ当該部分が表示されるようにCSS弄ってみたりもしたけど、有象無象のスマホブラウザ共が自動ダウンロードできるのかとか、IE/Edge専用CSSがちゃんと反映されるのかとか、色々考えたら（正常動作するChromeとFirefoxも含めて）常に表示しとく方が良いなと思い直した。


## というわけで最終形
```hoge.html
<body>
  <canvas id="targetCanvas"></canvas>
  <button onclick="downloadCanvas()">図としてダウンロード</button>

  <a id="hiddenLink" download="canvas.png">link</a>
  <!-- CSSで「display: none;」して非表示 -->

  <p>自動でダウンロードされない場合、下図を右クリックして保存してください。</p>
  <img id="canvasImage" src="dummy.png">
  <!-- CSSで小さめサイズに調整 -->
</body>
```

```hoge.js
function downloadCanvas() {
  let canvas = document.getElementById('targetCanvas')
  let link = document.getElementById('hiddenLink')
  link.href = canvas.toDataURL()

  document.getElementById('canvasImage').src = canvas.toDataURL()

  link.click()
}
```

これでChromeとFirefoxでは要件通りに動作、IE/Edgeでも手動スクショ強要はせずに済んだ。めでたしめでたし。
いやホントはSafariとかスマホ版Chromeとかでも検証しないといけないんだけどね。おいおいやります。

## 番外編　～.toDataURL()がエラー吐く話～
ローカルでテストしてたとき、画像ファイルを`<canvas>`要素に取り込んでから`.toDataURL()`すると、Chromeが下記のエラーを吐いた。
> DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

汚染されたキャンバスはエクスポートできません？なるほどわからん。

ググったら[こんな](https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image)記事が見つかりました。要約すると「外部コンテンツを取り込んだcanvasはセキュリティの都合でExportできないよ」ってことかな。ええ、いや、自サイト内の画像を取り込んでるだけなんですけど。

結局このエラーが出るのはローカル上で動かしてるときだけで、Web上にデプロイしてからテストすれば何の問題もなく動いた。結構時間食って悲しかったので一応書き添えておきます。根本的な解決方法は知らぬ……。
【目的無しの泥臭調査④】主なデータフォーマットについて、把握する。

- ふと気になったことを、淡々と赴くままに調査していく、この上ない自己満足記事第四弾。
- 四回目にして、「この快楽行為は際限なく続いてしまう」と、全てを悟ってしまった、生粋のさとり世代は、「とことんこの山道を登りきる」という、更に悟りを重ねる始末。
- 今回は、前から知りたかった各データフォーマット調査をしてみよう。

## 調査対象
- JSON
- XML
- YAML
- TOML


## JSON
- JavaScriptベース表記の軽量データ記述言語。

### 書き方

```json
{
  "name": "hanako",
  "age": 3,
  "job" : "baby"
}
```

### 特徴
- PythonやPHP等、多数の言語との親和性が高く、汎用的。
- 構造をシンプルに記述できる。
- テキストベース
- 文字コードはUTF8が必須。
- コメント書けない

### 事例
- 各種API
- JS関連ライブラリ

## XML
- データ構造化マークアップ言語。

### 書き方

```xml
<users>
  <user>
      <name>hanako</name>
      <age>3</age>
  </user>
  <user>
      <name>taro</name>
      <age>2</age>
  </user>
</users>>
```

### 特徴
- 新しくタグや属性を定義・使用可能
- システム間のデータ交換が容易
- データの再利用性が高い

### 事例
- RSS
- Office Open XML

## YAML
- データ構造やオブジェクト表現のための設定言語。

### 書き方

```yaml
user:
 - name: hanako
   age: 3
   job:
    - baby
    - heroine

 - name: taro
   age: 2
   job:
    - baby
    - hero
```

### 特徴
- 記法がシンプルで、可読性も高い
- コメントが書ける
- テキストベース
- 終了タグが必要ない

### 事例
- Ruby on Rails
- Ruby関連ファイル

## TOML
- 最小限の明瞭設定言語。

### 書き方

```toml
title = "hello"

[owner]
name = "hanako"
age = 3

[database]
server = "80.80"
ports = [ 80, 81, 82 ]
```

### 特徴
- 読みやすい
- 明確に設計されている。
- 多様な言語に対応
- コメントが書ける

### 事例
- GitLab
- pip
- vim

## まとめ
- 今回は主なデータフォーマット調査ということで、各々の「取り柄・長所・特技・欠点」等を、資格すらももらえない「親の気分」で把握していく、まごころ作業。
- この変遷は、「人間にもコンピュータにも分かりやすく、読みやすく」という「開発者達の愛情と熱意の歴史でもある」という、未来永劫似合わない感情に浸る。
- 今後の、「愛溢れる新たなデータ形式」への開発にいそしんでいる開発者達に敬意を示しながら、またひそひそ調査生活を過ごすことにしよう。

## 参考
- https://gist.github.com/miyakogi/e8631ce5f7c956db2313  
→こちらの記事を参考にしました。大変お世話になりました。
C言語に配列の要素数を計算するメソッドがなくてビビった

初めて触ったプログラミング言語が Ruby とか JavaScript だったので、最近はじめた C 言語は新鮮なことばかりで面白いですね。 `length` メソッドみたいのも無いんですもんｗ

## TL;DR

```c:main.c
#include <stdio.h>

int main()
{
    const size_t NUM = 100;
    int numbers[NUM];
    for (size_t i = 0; i < NUM; ++i)
        numbers[i] = i;

    int length = sizeof(numbers) / sizeof(numbers[0]);
    printf("length of 'numbers' is: %d\n", length);
}
```

C言語には残念ながら配列の要素数を計算するメソッドはないため、 `配列の総バイト数 / 配列一個あたりのバイト数` を計算して求めるしかないらしいです。ポインタの値がどうのこうのでも求められるらしいんですが、そのあたりはまだ勉強してないので次の機会に。
git submodule, fork周りのメモ

## Git Submoudle で忘れがちなこと

- Cloneするときに、Suboduleも同時にCloneするには...
    - http://karoten512.hatenablog.com/entry/2017/11/09/013845

```
git clone --recursive {Repo}
```

- 最新版のCommitに、Submoduleの参照を追従させるには...
    - https://qiita.com/kshimo69/items/ac22d414d756ea08943f

```
git submodule foreach git pull origin master
```

## Forkして困ったこと

- GithubでFork元に追従するときあるある
    - 本家で治ったからローカルの編集をなかったことにしたい
        - https://qiita.com/YuukiWatanabe/items/d326aad1224f2a559843
    - その上で、本家の更新を取り込む 
        - https://qiita.com/xtetsuji/items/555a1ef19ed21ee42873
DatePeriodクラスを使ってカレンダーに必要な値を取得

## DatePeriodクラスを使って日付のレンジを指定
DatePeriodクラスを使うことによって、日付のデータをまとめて取得することができる。　

```php:calendar.php
$period = new DatePeriod(
   new DateTime('first day of this month'),
   new DateInterval('P1D'),
   new DateTime('first day of next month')
);
//今月の月初から月末までの日付データを取得することができる
```
第１引数ではDateTimeクラスを使っていつの日付からデータを取得するか指定、第２引数ではDateIntervalクラスを使って何日間隔で日付データを取るかを指定、そして第３引数では同じくDateTimeクラスを使って、いつまでの日付を取得するかを指定しています。　

第３引数がnext　monthになっている理由は、’last day of this month’にしてしまうと、月末日を取得できない為です。　なので月内の日付を全て取得したい場合は、上記のように書きます。　

## DateTimeオブジェクト操作する　
繰り替えし処理を使い日付データを取り出していきます。

```php:calendar.php
foreach($period as $day){
   echo $day->format('d');
}
//0102030405060708091011121314151617....
```
formatはDateTimeクラスに用意されているメソッドになっており、決められた書式でデータを返してくれる。　

公式サイトにまとまっているので、以下を参考に引数を設定してあげればいい。

[formatに関する公式サイト](http://php.net/manual/ja/function.date.php)
Raspberry Pi（Raspbian）でモーションセンサー式の防犯カメラ的なものを作ってみる

#はじめに
Raspberry Pi（Raspbian）でモーションセンサー式の防犯カメラ的なものを作る方法です。

#必要なもの
- RaspbianがインストールされているRaspberry Pi
- Raspberry Pi用のカメラモジュール
- 赤外線モーションセンサー（HC-SR501）
- ジャンパー線（メス/メス）x3

#配線
GPIO, 5V, GNDならどこでも可ですが、今後の拡張性などを考えるとGPIOのみのピン（3, 5, 8, 10, 19, 21, 23, 24, 25以外）を使う方が無難だと思います。
この投稿では4（5V）, 6（GND）, 7（GPIO4）ピンを使用しています。
![DSC_0216.JPG](https://qiita-image-store.s3.amazonaws.com/0/263360/4104b177-7a3a-824f-f8f6-9357f667f874.jpeg)
![HC-SR501_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/263360/5c8dc0c3-a866-19a1-b7ee-2a41f42335d7.png)
↓HC-SR501の配線は左から順にGND, OUT, VCC。
![DSC_0217.JPG](https://qiita-image-store.s3.amazonaws.com/0/263360/d201e053-2662-8b9e-d733-94991cc02aa2.jpeg)
↓右側のダイヤルで距離、左側のダイヤルで時間を調整することができるので、使用用途と環境に合わせて調整する。（調整するのが面倒なら↓と同じにしておけばOK）
![DSC_0220.JPG](https://qiita-image-store.s3.amazonaws.com/0/263360/0b2d1043-8253-6aa1-7d74-87cd78fbe77d.jpeg)

#プログラム
```security_camera.py
#Import Files
import RPi.GPIO as GPIO
import picamera
import time

#GPIO Settings
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#Camera Settings
CAM_DIR  = "/home/pi/python/_video/"

camera = picamera.PiCamera()

#Main
try:
    while True:
        if GPIO.input(4) == 1:
            filename = time.strftime("%Y%m%d%H%M%S") + ".h264"
            save_dir_filename = CAM_DIR + filename
            camera.start_recording(save_dir_filename)
            camera.wait_recording(300)
            camera.stop_recording()
        else:
            pass

except KeyboardInterrupt:
    GPIO.cleanup()
```

#解説
1. スイッチの制御に使用する`RPi.GPIO`ライブラリをインポートする
2. Raspberry Piのカメラモジュールの制御に使用する`picamera`ライブラリをインポートする
3. 時間を取得するために使用する`time`ライブラリをインポートする
4. GPIOのモードをBCMに設定する（物理的なピン番号ではなく、GPIO**を使用する）
5. GPIO4を入力端子に設定し、状態をプルダウン（Low）にする（Hi=ON, Low=OFF）
6. `CAM_DIR`に保存先のディレクトリを設定する
7. PiCameraクラスのインスタンスを生成する
8. `while True:`で解説9〜16の処理を無限ループさせる
9. センサーが動きを検知したら（GPIO4がHiになったら）動画を撮る処理を行う
10. `time.strftime`でセンサーが動きを検知した時の日時を取得する
11. `time.strftime`で取得した日時＋拡張子（.h264）をファイル名にする
12. `CAM_DIR`で指定したディレクトリとファイル名を連結させる
13. `camera.start_recording`で動画を撮る
14. `camera.wait_recording`で指定した時間が経過したら動画を撮る処理を終了する（括弧には秒数を入れる）
15. `CAM_DIR`で指定したディレクトリに動画を保存する
16. 解説9に遷移 or プログラムが終了するのを待つ
17. Control+Cが押されたらGPIOを解放してプログラムを終了する

#プログラムを実行してみる
1. プログラムを実行する
2. センサーが動きを検知すると動画ファイルに記録される![2019-02-05-175400_947x685_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/263360/872726ed-2f5a-497a-cad5-bf77ce6065ea.png)
3. 人や動物など、動くものが映っていれば完成（Raspberry Piだと正常に再生できないので手持ちのPCにコピーして再生する）<img width="878" alt="スクリーンショット 2019-02-11 20.49.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/263360/14d295db-8e22-5f0c-13c8-ac5c0781a1a7.png">

#参考
- 「[Raspberry Pi（Raspbian）で写真を撮るプログラムを作る](https://qiita.com/Yuta_Chief/items/97192cd1f1b719538629)」と組み合わせることで`センサーが動きを検知したら写真を撮るプログラム`を作ることができる
- センサーの状態（Hi/Low）は目視で確認できないので、GPIOの入力値を`print`で出力しておくと調整しやすい
- 動画の保存先には使い捨ての外部ストレージ（USBメモリ）などを指定した方が安全に運用できる
- 屋外に設置すると雨などの影響で壊れる可能性が高いので、屋内での運用が望ましい
pythonでデータ分析するための環境構築

私の会社ではPythonを使っている人はいませんが、業務ではPythonが必要だなと思う機会が増えてきました（AWSのLambdaとか）
データ分析でpythonを使用することになりそうなので環境構築を備忘録がてらにつらつらと書きます．．．
想定環境：Ubuntu18.04 Python3
#●pip
パッケージ管理で、ライブラリのインストール

インストール
$sudo apt-get inatall python3-pip
$sudo pip3 install パッケージ名

#●Numpy
多次元配列などの数値計算を高速に処理できます。書籍でnpと略されることが多いです

インストール
$sudo pip3 install numpy

#●Scipy
最適化、保管、積分、空間解析、信号処理、画像処理などができるそうです
私の業務では統計・クラスタリングで使用します
spと略されます

インストール
$sudo apt-get install libblas-dev gfortran liblapack-dev g++

#●Matplotlib
データを可視化のためにグラフを描画します、データ分析ではグラフは欠かせませんね！
pltと略されます

インストール
$sudo apt-get install libgtk2.0-dev
$sudo apt-get install libfreetype6-dev libpng-dev graphviz
$sudo pip3 install matplotlib

#●pandas
データ構造やデータ解析に使用し、行列型データを扱います
CSV、Excelに対応しており、データ分割、インデックス、2次元・3次元・時系列データを操作できます
pdと略されます

インストール
$sudo pip3 install pandas

csvデータの読み込み
import pandas as pd
iris = pd.read_csv("iris.csv")
iris.info()

データ分析に使えそうなライブラリ（IPythonとか）はまだあると思うのですが今の想定はこんなとこです


相関係数を求めたり検定を行う場合以外はBIツールで可視化はできそうですが、BIツールでできない部分をPythonで補えたらいいなと思います
JenkinsとSlack連携

JenkinsとSlackを連携して、Jenkinsのビルド結果をSlackに通知させます。

## Slack側の設定
ワークスペースにJenkins CIアプリをインストールします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/6b7e72c1-c4da-31a4-458b-370c9e9a59d8.jpeg" width=70%>
完了すると、Jenkins側のセットアップの手順が表示されます。
BaseURLとTokenが発行され、Jenkins側の設定で使うのでひかえておきましょう。

Slack側の設定は以上です。

## Jenkins側の設定
プラグインで[Slack Notification Plugin]をインストールします。
Jenkinsの管理 > プラグインの管理 > Slack Notification Plugin をインストール。

インストールが完了したら、通知設定をします。
Jenkinsの管理 > システムの設定 > Global Slack Notifier Settings 
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/ebc4bba1-d28f-652e-4f2d-3fe4b9b863b1.jpeg" width=100%>（バージョンの違いかわかりませんが、Slack公式ドキュメント記載のIntegration Tokenの欄はありませんでした。）

|項目|入力値|
|---|---|---|
|Slack compatible app URL|https://{ワークスペース名}.slack.com/services/hooks/jenkins-ci/|
|Team Subdomain|ワークスペース名|
|Integration Token Credential ID|認証情報の追加 → 種類:SecretText > Secret:Slackで発行されたトークン ID:任意の名前|
[Test Connecting]でSuccessになればOK

Slack設定が完了したら、あとは通知対象のジョブの設定をします。
ジョブ > 設定 > ビルド後の処理：Slack Notifications を選択。
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/2c5ab8f8-6101-3393-fbbf-43188e8035a1.jpeg" width=70%>

以上で設定完了です。
ジョブのビルドが走ると、Slackにメッセージがとんできます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/0bf7bb0b-b63a-3ed0-ab4f-650ac71b65e9.png" width=60%>
WSLのUbuntuを設定する

#犯行動機
- ThinkPad A485を買ったから、まずは環境構築したい。
- Qiitaに投稿したかった。
- たまにしかやらないから忘備録を書きたい。

#WSLの設定
インストールとユーザー設定自体は難しくないので一旦省略します。基本はStoreで検索してポチーするだけ。
なので、これはやったほうが良いのでは?というものだけ記載する方針です。

- リポジトリの変更
 デフォルトのリポジトリが海外サーバのため、日本のサーバに変更します。
`sudo sed -i 's/archive\.ubuntu\.com\/ubuntu/ftp\.yz\.yamagata-u\.ac\.jp\/pub\/linux\/ubuntu
\/archives/' /etc/apt/sources.list`
このコマンドで`archive.ubuntu.com/ubuntu`を`ftp.yz.yamagata-u.ac.jp/pub/linux/ubuntu/archives`に置換しています。
終わったら`sudo apt update`、`sudo apt upgrade`の順でコマンドを実行してアップデートしましょう。
 
- タイムゾーンの変更
`sudo dpkg-reconfigure tzdata`を実行します。
するとConfiguring tzdataと書かれたウィンドウが表示されるので、Asiaを選択し、次にTokyoを選択します。

- 日本語化
`sudo apt install language-pack-ja`をで言語パックをインストールします。
次に、`sudo update-locale LANG=ja_JP.UTF8`を実行してロケールを変更します。
exit等でWSLの再起動をしましょう。
manページも日本語化してしまいましょう。
`sudo apt install manpages-ja manpages-ja-dev`を実行します。

以上です。
次はElixirをインストールしたいと思います。
python で関数の引数の名前を取得する方法

# 結論
```py
関数名.__code__.co_varnames[:関数名.__code__.co_argcount]
```
とすると取得できます

# 実例
以下のようなテストコードを用意しました

```py:test
def fnc3(a, b, c):
    d = 0
    return a + b + c

arg_names = fnc3.__code__.co_varnames[:fnc3.__code__.co_argcount]
print(arg_names)
```

```
$ python test.py
('a', 'b', 'c')
```
きちんと取得できていますね

# ちなみに
``__code__.co_varnames``は単にその関数内で使用されている変数を列挙するだけなので

```py
arg_names = fnc3.__code__.co_varnames
```
とすると、関数内で使用されている``d``くんも取得してしまいます

```
$ python test.py
('a', 'b', 'c', 'd')
```

# 余談
``python2``では[inspect.getargspec](https://qiita.com/some-nyan/items/3490f5e56ffa38d5771a)
``python3``では[inspect.signature](https://blog.amedama.jp/entry/2016/10/31/225219)
というものを本来使って情報を取得するらしい

しかし、こちらのほうが単純なので、今後はこちらを使用する
IPアドレス基礎メモ

#はじめに
いまいちちゃんと理解できなかったので自分が理解するために記事にしています。:nerd:
今更です。十分に理解しています(o*｡_｡)o

#進数

####2進数(コンピューターさんはこれ基本)
01で表すもの

```
0 1 10 11 100 101 110 111 1000 …
```


####10進数
0~9(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)で表すもの

```
0 1 2 3 4 5 6 7 8 9 10 11 12 13 …
```

:flushed:あ！進数って使う文字がどれくらいあるかなのか!!
:confused:じゃ？16進数は？
:flushed:16進数は、[0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F]だよ！
:flushed:進数が多ければ表現できるものも多くなる！ヽ(´▽｀)/


#10進数からみて(上記参考)

```
2　は　10

7 は 111
```

#ビット
```
2進数の 0 or 1 => 1bit　　　//1桁
2進数の 00 or 01 or 11 or 10 = 2bit   //2桁
2進数の 000 or 001 or 010 or 011 or 100 …　3bit //3桁
```
**bit数が大きければパターンも多くなる**

#バイト
```
8bitが1バイト


8bitになると 2の8乗で256通り表せれる。(｡･ω･｡)すごい(｡･ω･｡)
bitが大きければそれだけ色々な通りを表せれる。 (｡･ω･｡)すごい(｡･ω･｡)
```


#IPアドレスは32bit
```

2の32乗で4,294,967,296通り。 (｡･ω･｡)すごい(｡･ω･｡)	
```


#IPアドレス実は中身はこんな感じか

```
00000000000000000000000000000001 (｡･ω･｡)すごい(｡･ω･｡)
```

#とても上記だと見にくい
```

ちょっと分割してみる

00000000 00000000 00000000 00000001

8bitずつ分割

これを8bitを10進数に変換しているとか…
00000000 は 0
00000000 は 0
00000000 は 0
00000001 は 1

ので
0.0.0.1　となる。

( ･ὢ･ ) こんなIPアドレス見たことないよ〜( ･ὢ･ ) ま、どこかに存在はしているはず！

でもこれであっているはず。これが元の原理。
8bitでは256通り表せれるから

0~255 0~255 0~255 0~255 のどれかになる。　(｡･ω･｡)お！

113.1.233.222とかありそう。

ってことは
255以上はないと言うこと( ･ὢ･ )！！！！！！！！！


256.1.344.3 なんてものは存在しないのだ(｡･ω･｡) 256も344もオーバーなのだ！！

なるほど！！

```

#結果

```
IPアドレスは
0.0.0.0 ~ 255.255.255.255 
```

#参考
https://wa3.i-3-i.info/word1605.html
http://www.asahi-net.or.jp/~ax2s-kmtn/ref/bdh.html
https://www.pc-master.jp/words/2sinsu.html
Electron + React(v16.8) で動画・静止画ビューワーを作った

※本記事には少しだけR18要素がありますので、拒絶反応がある方はページを閉じることをおすすめします。

---

以前、[shokushuという動画プレイヤーをElectronで作った](https://qiita.com/takeyuichi/items/82c155168b2dc7ae18a7) のですが、静止画も扱える shokushu2 というアプリケーションをElectronで作りました。

https://github.com/y-takey/shokushu2

趣味アプリなので、実行ファイルの配布はしていません。
ご興味あれば `git clone` してから `yarn install && yarn package` すると、 `<PROJECT_ROOT>/release` ディレクトリに ビルド環境に適応した実行ファイルが作成されます。
ただし Mac でしか動作確認をしていないため Windows 等で動くかは不明です。特にアプリケーションの性質上、ファイルシステムにアクセスするのでその部分が微妙です。
詳細は README を参照してください。

# モチベーション

* 前出の動画プレイヤーを数年使っていて、改善したい部分が溜まっていた。
* 原点回帰とでもいうか、近年は静止画を購入することも多くなっていたが、気にいるビューワーがなかった。K○miflo(R18のサービスなので、伏せ字および無リンクにしておきます)と同じように閲覧したかった。
* 動画も静止画も同じようにプライベートなプラットフォーム上で一元管理したかった。
* React Hooks が実戦投入可能か評価したかった。（2019/2月上旬に React 16.8 の安定版がリリースされたが、実装開始時はまだ alpha 版だった）

# 使用した主な技術・ライブラリ

## [Electron](https://electronjs.org/)

HTML, JS, CSS 等のWeb技術でクロスプラットフォームなデスクトップアプリケーションが作れるやつ。 
現在では[NW.js](https://nwjs.io/)や [neutrino](https://neutrinojs.org/)等の選択肢もあるが、こだわりも不満も特になかったので今回もElectronを採用。
ちなみに、[このボイラープレート](https://github.com/electron-react-boilerplate/electron-react-boilerplate)を使って、初期セットアップを済ませた。

## [React v16.8](https://reactjs.org/)

今回の主目的の一つであるHooks の評価のために、16.8 のalpha バージョンから使用。
ちなみに Redux 等は使用しておらず、React 標準機能の Context 等を使用。（とりまRedux、という風潮(？)が嫌い）
 
## [Ant Design](https://ant.design/)

中国のアリババのグループ企業であるAlipayのエンジニアが主に開発しているUIライブラリ。
今までUIライブラリは色々試してきたけど、デザイン・コンポーネント数・扱いやすさ等の総合評価では1番いい。
ちなみに名前の由来は、アリ(ババ|ペイ)→蟻(日本語)→Ant(英語)？

## [NeDB](https://github.com/louischatriot/nedb)

組込のドキュメント型データベース(NoSQL)。API は MongoDB のサブセットなので、MongoDB を使ったことがあればほとんど同じ感じで使える。 MongoDB を使ったことがなくても 何かしら O/Rマッパー を使ったことがあれば雰囲気で使えるはず。
データファイルはプレーンテキストなので、直接ファイルの中身を参照・編集できて嬉しい。

## [React Hotkeys](https://github.com/greena13/react-hotkeys)

ホットキー(ショートカットキー)用のライブラリ。同種のライブラリを色々試した中で一番フィットした。
ちなみに`react-hot-keys` 等、似た名前のライブラリが多いので注意。
2019/02/11 時点での安定版は v1 だが、v2 が開発中で、使用したい機能がv2からだったのでv2を使用。開発中とは言え、特にバグに遭遇することもなく安定していた。


# 機能

## リスト

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25588/915c01ba-931d-6507-74a2-694745326e7c.png)

* 一般的な検索・ソート・ページングができる
* サムネイルは静止画の場合は最初のページを使用。動画の場合は再生時間の中央のイメージを使用。ただしブックマーク(後述)が登録されている場合はその最初の位置を使用。

## ビューワ

### 静止画ビューワ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25588/58610349-ef89-1cc0-461b-ff445b6e1188.png)

* 画像からは分かりにくいけど、紙の本と同じように２ページ分を左右に並べて表示。（設定で1ページにもできる）
* 普通の動画プレイヤーと同じ操作感で<kbd>←</kbd> , <kbd>→</kbd> でページ送りができる。通常は2ページ単位で移動するが、 <kbd>shift</kbd>+<kbd>←</kbd> , <kbd>shift</kbd>+<kbd>→</kbd> で1ページ単位になる。（見開きページ用の調整）
* <kbd>b</kbd> でブックマークを設定できる。(スライダー上の白丸がブックマーク位置)同じ位置でまた <kbd>b</kbd>を押すとブックマークを解除。
* <kbd>↑</kbd>, <kbd>↓</kbd>で現在ページを起点に前後のブックマークへ移動。

### 動画ビューワ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25588/f0a4dfa6-c423-c2f1-7f85-3f8afd2ef6cd.png)

* 機能的には静止画ビューワとほぼ同じ。
* <kbd>←</kbd>, <kbd>→</kbd> での移動秒数は設定可能。（初期値は10秒）

## メタデータの編集

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25588/6e0260da-727b-2828-599c-48bcbe21cb34.png)

* リストまたはビューワからタイトルや作者・タグ等のメタデータを編集できる
* タイトルを変更すると、実際のファイル名・ディレクトリ名も変更される。
* ちなみに動画・静止画の最後まで閲覧すると視聴回数を自動インクリメントするため、編集項目に視聴回数(Viewed Count)は不要なはずだけど、開発時にインクリメントしすぎるバグがあり、回数を補正するために編集可能にした。今は当該バグはないけど、その名残。
オブジェクトをジグザグに動かしてみる

#はじめに
スーパーマリオ・ソニック等アクションゲームに代表されるものに、物体・地形が動くものがほぼまちがいなくある。
その中でも基本となる上下に動くものを今回作成すると同時に、2種類の方法を用いて挙動の違いを調べてみる。

##方法1　Mathf.Sinメソッド

3座標のうち
・2座標を動かす：円運動
・1座標を動かす：ジグザグ

~~~C#
public class CubeLR : MonoBehaviour {
    float x;                       //三角関数の数値設定
    float speed = 3f;              //スピードの数値設
    float radius = 0.1f;           //半径の設定
	
	// Update is called once per frame
	void Update () {


       x = radius *Mathf.Sin(Time.time * speed);  //三角関数による動きの設定。

       //X座標のみ三角関数による動きの設定を反映
       transform.position = new Vector3(x+transform.position.x,transform.position.y,transform.position.z);  
		
	}
}
~~~

##方法2　PingPongメソッド。
PingPong(Time.time(移動スピード）,3(移動距離));

~~~C#
public class test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = new Vector3(Mathf.PingPong(Time.time,3),transform.position.y,transform.position.z);
    }
}

~~~

###結果
青Cube : PingPong
緑Cube : Mathf.Sin

![movie.gif](https://qiita-image-store.s3.amazonaws.com/0/307841/cb14fa76-8ac5-eba8-b316-14a974e0e804.gif)

###感想

両方ともほぼ同じ動きになるが、PingPongは速度、距離の設定がとても簡単である。
わざわざMathf.Sin関数を使うメリットは今のところ感じられません。
reportlab の Table の表示位置をコントロールする

次のような PDF を作成するサンプルです。
![table_feb11.png](https://qiita-image-store.s3.amazonaws.com/0/179446/a36639f9-d081-941a-e950-ab86dd4c70eb.png)

```py:table_position.py
#! /usr/bin/python
# ------------------------------------------------------------------
#	table_position.py
#
#						Feb/11/2018
# ------------------------------------------------------------------
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.lib import colors
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfgen import canvas
from reportlab.platypus import Image, Paragraph, Table
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# ------------------------------------------------------------------
fontname_g = "HeiseiKakuGo-W5"
pdfmetrics.registerFont(UnicodeCIDFont(fontname_g))

cc = canvas.Canvas('example.pdf', pagesize=A4)
width, height = A4

cc.setFont("HeiseiKakuGo-W5", 16)
str_out = "こんにちは"
cc.drawString(100, 730, str_out)

data = [["テスト", 2, 3], ["日本語", 1, 3], [3, 2, 10]]

table = Table(data, colWidths=20*mm)
table.setStyle([("VALIGN", (0,0), (-1,-1), "MIDDLE"),
                ("ALIGN", (0,0), (-1,-1), "CENTER"),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
		('BOX', (0, 0), (-1, -1), 0.25, colors.black),
		('FONT', (0, 0), (-1, -1), "HeiseiKakuGo-W5", 16),
		])
#
table.wrapOn(cc, width, height)
#
table.drawOn(cc, 140*mm, 250*mm)
table.drawOn(cc, 75*mm, 225*mm)
table.drawOn(cc, 10*mm, 200*mm)
#
styles = getSampleStyleSheet()
my_style = styles["Normal"]
my_style.name = "bonlife"
my_style.fontName = "HeiseiKakuGo-W5"
my_style.fontSize=16

ptext = "これはサンプルです。"
pp = Paragraph(ptext, style=my_style)
pp.wrapOn(cc, 70*mm, 50*mm)  # size of 'textbox' for linebreaks etc.
pp.drawOn(cc, 50*mm, 190*mm)    # position of text / where to draw

cc.showPage()
cc.save()
# ------------------------------------------------------------------
```
Active Storageをルートから削除する方法

# なぜ、、、
`rake routes`をしてみたら`/rails/active_storage/**`というルートが勝手に追加されていた。

<img width="1121" alt="スクリーンショット 2019-02-11 20.39.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/331247/459df591-d0ae-1727-7855-c6bf3c88f631.png">


# Active Storageとは
Active Storageが何かわからなかったため、軽く調べてみました。

Active Storageは、Rails5.2で追加された、ファイルアップロードを行うための機能です。これを使えば、フォームで画像の投稿機能などが簡単に作れます。また、Amazon S3, Google Cloud Storage, Microsoft Azure Storageなどのクラウドストレージサービスに対するファイルのアップロードを簡単に行うことができます。クラウドストレージの他に、ローカルディスクにファイルを保存することもできます。
Paperclip, Carrierwave, Dragonflyなどのgemの代わりになるとされていますが、現時点ではバリデーションとキャッシュ関連の機能は残念ながら備えていません。使うにはRails 5.2以上にアップグレードする必要があります。

必要ないので削除したいと思います。

# 削除する方法

#### ※Rails6.0以上の方は一番下へ

## 手順１
application.rbの記述を修正する。
require "active_storage/engine"が不要なのでコメントアウトする。
修正するべき部分だけ記述しています！

修正前

```config/application.rb
require 'rails/all'
```

修正後

```config/application.rb
require "rails"

# Include each railties manually, excluding `active_storage/engine`
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
# require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
require "rails/test_unit/railtie"
```

## 手順２
下記のコードを全てコメントアウトする。

```config/environments/development.rb
config.active_storage.service = :local
```

```config/environments/production.rb
config.active_storage.service = :local
```

```config/environments/test.rb
config.active_storage.service = :test
```

## 手順３

下記のコードをコメントアウトする

```app/assets/javascripts/application.js
//= require activestorage
```

# 参考記事

https://mikerogers.io/2018/04/13/remove-activestorage-from-rails-5-2.html

Active Storageについてもっと詳しく知りたい方は
https://qiita.com/hmmrjn/items/7cc5e5348755c517458a

# Rails6.0以上
[こちらを参考にしてください](https://qiita.com/k_teluki/items/c9674499e51dd83f97f5#comment-1bab8d43669ccde652c6)
RailsでControllerだけでアソシエーションがあるModelの結果をjsonの応答で返す方法

意外とバチっとハマる記事がなかったので、投稿。

JavascriptでAjax的な処理を書こうとするとviewを書くほどでもないActiveRecordの結果をjsonで返す処理はよく書くと思う。

特に自分の場合、複雑なGUIをJavascriptでやろうとすると必ずd3.jsを使って解決しようとしてしまうので、様々な処理をしながらもレスポンスは常にすべてのデータを返す、みたいな実装をしがちだ。

普通に検索すると以下のようなコードが見つかる。

```ruby
@items = Model.all
render :json => @items
```

これはこれでいいのだが、belongs_toとか関連付けのあるModelの関連のModelまで取得しようと思うとなかなかピンポイントの記事がない。

結果としては、as_jsonを使うと思った通りの結果になった。
to_jsonはよくデータ出てくるのだが、いったん文字列になってしまうため、またjsonに戻さないといけない。
ということで相手のModelのidとtitleだけほしいみたいな場合は、以下のように書けばよかった。

```ruby
ars = Model1.eager_load(:model2)
@items = ars.as_json(:include => {:model2 => {:only => [:id, :title]}})
render :json => @items
```
なかなか思うように動かない今日なのでした。#100DaysOfCode #Day3

昨日はCSSを覚えたので、さっそくはてなブログのCSSをカスタマイズしてみたのですが、なぜかウンともスンともいいません。良く分からないので後回しにして。

今日はProgateで Javascript と jQuery の初級編をクリアしました。

JavaScript は ホームページで なんかいろいろ動かしたりするプログラムが作れるみたいです。それから笑い袋を作りました。

昨日コピペで試作してみたのを、JavaScriptでrandom()に笑いが発生するようにしました。くだらねーですね！
http://appdays.herokuapp.com/Day1

jQuery は 文字とか写真とかを なんかいろいろ動かしたりとかできるみたいです。こちらはテトリスをコピペしました。7行で テトリスが動くってすごくないですか？

お手本
https://qiita.com/ryuichi1208/items/f9e6ac2b99bbe4fc82d3

練習
https://appdays.herokuapp.com/Day3

 それからRubyとRuby on Railsも。こちらはTwitter みたいなやつが作れるそうです。これも練習アプリにチャレンジしたのですが、なぜかHerokuにアップするとうんともすんとも動きません。原因がわからないので一旦アプリを全部削除して作り直す。ついでにじゃかじゃかアップしたファイルやアプリを整理して。うーん動かず。何でだろう。

ハッシュタグ #100DaysOfCode の存在を知る。３日目だし参加してみようかな。

なかなか思うように動かない今日なのでした。ではまた明日！

(所要時間3時間半）
PHPで入力フォームのデータをSELECT文のINSERTを使って、MySQLに書き込む

以下の2つソースコードを作ります。
①入力フォーム
②入力フォームで入力されたデータをPOSTで受け取って、DBに接続して書き込む

↓入力フォーム画面
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/262601/7735d3c9-ccd4-880e-f7fe-cc40be704f4a.png)


```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="description" content="このページの説明">
  <title>このページのタイトル</title>
  <link rel="stylesheet" href="/main.css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<body>
<div id="post_page">
  <form method="post" action="process_post.php">
    <div>name <input type="text" name="name" size="30"></div>
    <div>category <input type="text" name="category" size="30"></div>
    <div>description <textarea name="description" cols="30" rows="10"></textarea></div>
    <div><input type="submit" name="submit" value="投稿" class="button"></div>
  </form>
</div>
</body>
</html>
```



↓登録・登録結果表示画面

```php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="description" content="このページの説明文">
  <title>このページのタイトル</title>
  <link rel="stylesheet" href="/main.css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<body>

<?php
  try {
    //DB名、ユーザー名、パスワード
    $dsn = 'mysql:dbname=データベース名;host=サーバー名';
    $user = 'ユーザー名';
    $password = 'パスワード';

    $PDO = new PDO($dsn, $user, $password); //MySQLのデータベースに接続
    $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //PDOのエラーレポートを表示

    //input_post.phpの値を取得
    $name = $_POST['name'];
    $category = $_POST['category'];
    $description = $_POST['description'];


    $sql = "INSERT INTO contents (name, category, description) VALUES (:name, :category, :description)"; // INSERT文を変数に格納。:nameや:categoryはプレースホルダという、値を入れるための単なる空箱
    $stmt = $dbh->prepare($sql); //挿入する値は空のまま、SQL実行の準備をする
    $params = array(':name' => $name, ':category' => $category, ':description' => $description); // 挿入する値を配列に格納する
    $stmt->execute($params); //挿入する値が入った変数をexecuteにセットしてSQLを実行

    echo "<p>name: ".$name."</p>";
    echo "<p>category: ".$category."</p>";
    echo "<p>description: ".$description."</p>";
    echo '<p>で登録しました。</p>'; // 登録完了のメッセージ
  } catch (PDOException $e) {
  exit('データベースに接続できませんでした。' . $e->getMessage());
  }

?>
</body>
</html>
```