OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】エラー Fatal Error Unable to create lock file: Bad file descriptor (9)

php artisan serve で、サーバーが起動できなくなった。

#### 原因
- 全ユーザーが書き込み可能なハズのtmpディレクトリに、書き込み権限がなくなってた。。パーミッションエラー！

#### 解決方法

```php:権限を与えて解決
% ls -ld /private/tmp             // 確認
  drwxr-xr-x  22 root  wheel  704 11 15 16:59 /private/tmp
         // ↑ tがない
% sudo chmod 1777 /private/tmp   // 権限を付与
% ls -ld /private/tmp            // 確認   
  drwxrwxrwt  22 root  wheel  704 11 15 16:59 /private/tmp
         // ↑ tがついた
% php artisan serve             // 起動できた
```

- パーミッションのマーク ： 「 t 」って？
  - スティッキービット（Sticky Bit、全ユーザーが書き込みを行える権限）のこと。
  - 削除は、所有者とrootだけ可能。

```php:スティッキービットを設定方法
% chmod 1777 ディレクトリ名      // パーミッション値 +1000
```
RHELで環境構築(開発者サブスクリプション取得からコマンドで開発者サブスクリプション登録)

#はじめに

Qiita初投稿になります。CentOSではなく開発者用サブスクリプションを利用してRed Hat Enterpriseで色々な検証の備忘録として残してます。将来的にはコンテナに集約していく予定です。


#参考サイト

赤帽エンジニアブログ　「Red Hat Developer Programに参加して最新技術を学習しよう」(参照　2019-06-18)

https://rheb.hatenablog.com/entry/developer-program

#環境構築の手順

##Red Hat DeveloperサイトでRed Hatアカウント作成、Red Hat Developer Programに参加して開発者用サブスクリプションを取得 

https://developers.redhat.com/

##RHEL8.2のISOファイルダウンロード

今回は「Red Hat Enterprise Linux 8.2 Binary DVD」を選択する。
https://access.redhat.com/downloads/content/479/ver=/rhel---8/8.2/x86_64/product-software

##仮想環境構築

利用する仮想環境ソフトウェアは以下を使用

VirtualBox(2020年11月15日現在、バージョンは6.1.16)
https://www.virtualbox.org/

VMware Workstation Player(2020年11月15日現在、バージョンは16)
https://my.vmware.com/jp/web/vmware/downloads/info/slug/desktop_end_user_computing/vmware_workstation_player/16_0

##RHELインストール
　　
今回は、いちから環境構築していくので「ソフトウェアの選択」は「最小限のインストール」を選択し、必要に応じてパッケージを追加します。

##dnf(yum)が使用できるようにCLIでサブスクリプション登録

subscription-managerコマンドを使用して仮想マシンをRed Hat社に登録します。

```
subscription-manager register --username RHアカウント --password RHアカウントパスワード
```


##利用可能なサブスクリプションをコマンドで確認

確認する項目としては、"プール ID"と"終了"で登録するのIDと利用可能なサブスクリプションを確認します。
また開発者用サブスクリプションは1年間しか利用できないため場合によっては、サブスクリプションの有効期限を更新する必要があります。

```
subscription-manager list --available
```

##サブスクリプションをシステムにアタッチ

利用可能なサブスクリプションが一つの場合は以下のコマンドを実施します。

```
subscription-manager subscribe --auto
```

##利用可能なサブスクリプションが複数ある場合は以下のコマンドで指定して登録

```
subscription-manager subscribe　--pool=確認した"プール ID"を指定
```

##サブスクリプションがアタッチされているか確認
正常にアタッチされていれば"状態"の項目が"サブスクライブ済み"と表示されます。

```
subscription-manager list
```

##仮想マシンのRH登録解除

仮想マシンを再構築したり、不要になったら以下のコマンドで登録を解除します。

```
subscription-manager unregister
```
node.jsとリアクトAPIの練習

node.jsとリアクトAPIの練習

node.js側にこちらを追加
    // 次の 1 行を追加
    res.set('Access-Control-Allow-Origin', '*');
【サーバー側】Access-Control-Allow-Origin を返す場合

node.jsをウェブサーバーにする、参考記事

ReactでAPIの情報をJsonで受け取り、mapで配列を表示する方法
https://note.com/aokha/n/n43444782566d

解りやすいページ　node.jsとエキスプレスフレームワーク
https://sbfl.net/blog/2018/08/25/nodejs-express-webapi/

node.jsでMYSQL
https://qiita.com/ryu1_f/items/9ff4c88ac335eee368c1

起動の方法nmp index.js
練習フォルダnode.js

リアクトとJAVAのAPI実装
https://fintan.jp/?p=5583&amp


子コンポーネントから親コンポーネントの変更方法
関数コンポーネント編

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
 
//ボタンをコンポーネントとして抽出
function MyButton({OnBtnClick, isDark}) {
  //イベントハンドラには props 経由で受け取る MyComponent の関数 を設定
  return (
    <button onClick={OnBtnClick}>
      Change to {isDark ? "white" : "black"}
    </button>
  );
}
 
function MyComponent() {
  const [isDark, setDark] = useState(false);
  const bgColor = isDark ? "black" : "white";
  
  // MyButton に渡して state を更新する関数
  const handleOnClick = () => {
    setDark(!isDark);
  }
  
  //props.OnBtnClick で MyButton へイベントハンドラを渡す
  return (
    <div className={`content bg-${bgColor}`}>
      <p>The background color is {bgColor}</p>
      <MyButton OnBtnClick={handleOnClick} isDark={isDark}/>
    </div>
  );
}
 
ReactDOM.render(<MyComponent />, document.getElementById("root"));
Djangoのtemplateで演算処理を行う方法

##はじめに
django-mathfiltersというモジュールを利用することでテンプレート上での演算処理ができるようになります。この記事では、その実装方法について紹介します。


##参考
[django-mathfilters · PyPI](https://pypi.org/project/django-mathfilters/)

##環境
Python(3.6.2)
Django(2.1.7)


##インストール方法

### django-mathfiltersをインストール

```python
pip install django-mathfilters
```

### mathfiltersをINSTALLED_APPSに追加

```python:settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sass_processor',
    'storages',
    'mathfilters', # ← 追加
]
```

###テンプレートから読み込む

```python
- load mathfilters
```

これでテンプレート上で演算処理が可能になります。

##演算方法

- sub – 減算
- addition – 加算
- mul – 乗算
- div – 除算
- intdiv – 整数除算
- abs – 絶対値
- mod – 剰余



```python:template_file.html.haml
- load mathfilters

%ul
  %li
    10 - 2 = {{ 10 | sub:2 }}  # 8
  %li
    10 + 5 = {{ 10 | addition:5 }} # 15
  %li
    10 × 3 = {{ 10 | mul:3 }} # 30
  %li
    10 ÷ 2 = {{ 10 | div:2 }} # 5
  %li
    | -10 | = {{ -10 | abs }} # 10
  %li
    20 ÷ 3 = {{ 20 | mod:3 }} # 2
```
さくらVPS Ubuntu 公開鍵暗号設定

#はじめに
VPS(さくらのVPS（仮想専用サーバ)上にUbuntuサーバーに公開鍵暗号設定をいれる。
Ubuntuバージョン：18.04.5
#ログイン・ユーザー作成・権限付与
Mac PCのターミナル、またはTera Term等のツールから作業
$ ssh ubuntu@[IPアドレス]
$ sudo adduser [User名]
$ sudo gpasswd -a [User名] sudo

#公開鍵暗号方式の設定
###公開鍵作成、配置
鍵のペアを作って、秘密鍵をローカルPC上に、公開鍵をサーバー上に格納する。
$ mkdir ~/.ssh #サーバー上でフォルダ作成
$ ssh-keygen -t rsa #ローカルで鍵を作成(パスフレーズなし)
$ ssh-copy-id -i ~/.ssh/id_rsa.pub [User名]@[IPアドレス] #ローカルからサーバーに公開鍵を配置
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/xxxxxxxxxxx/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

 
Number of key(s) added:        1
 
Now try logging into the machine, with:   "ssh ’[User名]@[IPアドレス]'"
and check to make sure that only the key(s) you wanted were added.
 #公開鍵作成、配置完了

サーバー上で公開鍵を確認する。
$ cat ~/.ssh/authorized_keys #サーバー上で実行
ssh-rsa ******公開鍵の情報******
 
ローカルPC上で秘密鍵を確認する。
$ cat ~/.ssh/id_rsa #ローカルPC上で実行
-----BEGIN OPENSSH PRIVATE KEY-----
******秘密鍵の情報******

###鍵の権限設定
$ chmod 700 .ssh
$ chmod 600 .ssh/authorized_keys
 
###sshd_configの事前バックアップ
sshでログインする際、パスワードログインを禁止し、[User名]での公開鍵でのログインのみ許可する。コンフィグファイルをいじるので、念の為ファイルをバックアップする。
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.old
 
###sshd_config編集(viモード)
$ sudo vi /etc/ssh/sshd_config

viモードでは、以下有効化したい項目先頭のコメントアウト'#'を削除し、末尾の設定値(yes,no等)を書き換えてSaveする。
  PermitRootLogin no
  PubkeyAuthentication yes
  PasswordAuthentication no
  PermitEmptyPasswords no
  AllowUsers [User名]
 
$ sudo systemctl restart sshd #反映コマンド。念の為、接続済のセッションは残しておく 

#秘密鍵を使用し、ユーザー[User名]でログイン
パスワード入力なしで、秘密鍵を使ってサーバーにログインできることを確認する。
$ ssh [User名]@[IPアドレス] -i ~/.ssh/id_rsa

Ubuntuではログインできなくなっていることを確認する。
$ ssh Ubuntu@[IPアドレス]
 
###自分以外のメンバーの公開鍵を登録
自分以外のメンバーがサーバーにログインできるよう、メンバーが持つ公開鍵を登録する。
$ sudo vi ~/.ssh/authorized_keys
ssh-rsa AAAABBB……XXX==
ssh-rsa AAAACCC……XXX==
ssh-rsa AAAADDD……XXX== #… こんな感じに複数の鍵を登録。

終わり。
【初心者向け】ボタンホバー時に透過しても背景が見えないようにする方法

# どうも7noteです。透過時に背景が見えてしまう対策方法

背景色が入っている箇所の上にボタンを配置した時、ボタンがhoverで透過した際に背景色がうっすら見えてしまう対策方法について。

画像を使わずに、背景色で作成したボタンであれば次の方法で対策をすることができます。

（※ボタンが画像の場合は[こちら](https://qiita.com/7note/items/eba35487ccd7d2e099a8)）

![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/ce88ec54-323b-94d4-c0ab-a86fcdfee05a.gif)


## ソース


```index.html
<div class="box">
  <div class="btnA">透けちゃう。</div>
  <div class="btnB">透けないよ！</div>
</div>
```

```style.css
.box {
  padding: 50px;         /* 適当な余白を確保 */
  background: #f36 25%,  /* 分かりやすいよう赤のストライプを指定 */
    #fff 25%,
    #fff 50%,
    #f36 50%,
    #f36 75%,
    #fff 75%,
    #fff
  );
  background-size: 40px 40px;  /* 適度な大きさに指定 */
}

.btnA,
.btnB {
  width: 150px;         /* 横幅を適当なサイズに指定 */
  text-align: center;   /* 文字を中央揃え */
  background: #eee;     /* 背景色をグレーに */
  padding: 10px 30px;   /* 内側の余白を指定 */
  margin: 10px;         /* ボタン同士が見やすいよう適度な余白 */
}

.btnA:hover {
  opacity: .9;          /* これだと透けてしまう */
}

.btnB:hover {
  background: #fafafa;  /* これなら透けない */
}
```

## 解説

手法は、**hover時に透過するのをやめ、背景色を変更する**ことです。
こうすることにより、当たり前ですが透過はしないので後ろが透けることはありません。
背景色が単色やグラデーションでも対応できますが、**画像の時ではこの方法は使えないので注意**。

## まとめ

細かいところなのでチェック時に見落としがちですが、対応方法をしっていればなんてことないのでしっかり直しておきたいポイントです。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】HTML・CSSのちょいテク詰め合わせ](https://qiita.com/7note)
oh-my-zshをインストールしたあとgit:(master)×と表示され進めない時

# はじめに
職場のカリキュラムを進めていく中でoh-my-zshをインストールしている時に、ターミナルに妙な表示が出て表示を直したいなと思ったことが今回の記事を作成しようと思ったことのきっかけです。
ちなみに、ターミナルにでた表示とは下記です。(この表示消えない！こっから進めない！！なんなんだ！！)

```:ターミナル
➜  ~ git:(master) ✗
```

順を追ってこの表示を変更する方法を説明したいと思います！

## oh-my-zshのインストール
oh-my-zshのインストールは以下記事を参考にしました。
[Macにzshをインストール(oh-my-zshを入れるまで)](https://qiita.com/SuguruOoki/items/af738e2b6e1425425761)
この記事を参考に、4.oh-my-zshをインストールまで進め「oh-my-zsh」をインストールした際、ターミナル画面に上記表示が出るようになりました。
本来なら下記表示になる予定でした...

```:ターミナル
-> %
```

まず、「→git.(master)×」。この表示の意味するところは、**シェルのプロンプトにgitのブランチ名と状態が出るようになってしまっているということ**です。
設定としてgitの状態を表示するよう設定されちゃってるので、それを変えれば良い！というお話です( ◜௰◝ )ﾅﾙﾎﾄﾞ

## プロンプト(zshrc)を編集・カスタマイズ
#### プロンプトの変更
下記コマンドでプロンプトの設定を確認します。

```:ターミナル
$vim ~/.zshrc
```

※ **vim** →　Vimは、vi から派生し、発展した高機能なテキストエディタです。これを使ってファイルの中身をいじっていきます！
※ **.zshrc** → zshの設定ファイルです。

上記コマンドを実行すると以下のような内容が表示されるかと思います。


```:ターミナル
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="/Users/mochidzuki-wataru/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"　←今回はここを書き換えます。ohmyzshで使えるテーマの指定場所。

# Set list of themes to pick from when loading at random
...(以下略)
```

ここの１０行目**ZSH_THEME**を編集。rubbyrussellからcandyへ書き換えて、INSERT(入力モード)からエスケープボタンを押して離脱、:wq(上書き保存&終了)をして設定の変更は完了です。

続いて以下コードを実行して変更を反映させましょう！

```:ターミナル
$ source ~/.zshrc
```

「**source**」コマンドは、ファイルに書かれたコマンドを現在のシェルで実行する、というコマンドです。 主に今回のようなシェルの設定ファイルを反映させる際に使用します。

これでgitの表示はなくなったかと思います(੭ ᐕ)੭ｵｼﾏｲ ﾁｬﾝﾁｬﾝ

## おまけ

ZSH_THEMEで記述してあったrobbyrussellと変更したcandy、それぞれのテーマ内容を確認したい方はGithubからご覧いただけます。
[→　robbyrussell.zsh-theme](https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme)
[→　candy.zsh-theme](https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/candy.zsh-theme)
Oracle Instant Client 19.9にはlibclntsh.dylibがないんだよ、というお話

## 環境

macOS Big Sur(11.0.1)
serverless
Python3

## 問題発生

serverlessのプログラム実行中に以下が発生(長いので改行しています)。

```
cx_Oracle.clientversion()

cx_Oracle.DatabaseError: DPI-1047: 
 Cannot locate a 64-bit Oracle Client library: 
 "dlopen(libclntsh.dylib, 1): image not found". See 
https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html
 for help
```

64bitライブラリを入れてね、ということなので、[上記URL](https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html)に飛んで[64bitのリソースがあるところ](https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html)に飛んでダウンロード。

2020/11/15時点では19系は19.9。
ダウンロードして、解凍して、指示通りにリンク……ファイルがない！

サイトの説明に書いてあるバージョン(19.3)にはあるので、それを使うのが良い。
19.9しか見当たらないけど、リンクを細工するとダウンロードできます。

- Oracle Instant Client 19.9へのリンク  
https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-basic-linux.x64-19.9.0.0.0dbru.zip
- Oracle Instant Client 19.3へのリンク(小細工)
https://download.oracle.com/otn_software/linux/instantclient/193000/instantclient-basic-linux.x64-19.3.0.0.0dbru.zip

- リンクする

`ln -s /opt/oracle/instantclient_19_3/libclntsh.dylib ~/lib/`
Shopify CSSでLiquidを使う

#css上でliquidを使う方法
cssファイル内でurlを読み込むとき、src:url()とかの部分をliquid表記にする。cssのままではliquidがかけないので、liquidファイルにしていく。
 例：`main.css`→`main.scss.liquid`
（scssはShopifyが勝手にcssにしてくれる）
`theme.liquid`とかで読み込む

```liquid

    {{ 'main.scss.css' | asset_url | stylesheet_tag }}
```
これでOK！（のはず）
MITライセンスです

# はじめに

私は自作したソフトウェアには、MITライセンスを適用しています。
MITライセンスとは、そのソフトウェアを使用者の自己責任で

  - 使用する→OK
  - 配布する→OK
  - 改造する→OK
  - 改造したのを配布する→OK
  - 商用利用する→OK

という自由度の高いライセンスです。

そしてMITライセンスを適用するには、比較的簡単な以下の条件  
　①著作権表示を記述する。
　②MITライセンスの許諾表示を記述する。
　③両者の記載個所は、ソフトウェアのすべての複製または重要な部分とする。

を守る必要があります。


# それぞれの条件

### ①著作権表示を記述する。

よく見かける著作権表示で長いものだと、以下のように記述されています。

```
Copyright © [初回バージョンの公開年]-[最新バージョンの公開年] [著作権者の氏名] All Rights Reserved.
```

ただし法律的にはこれらすべてが必須なわけではありません。以下要素別に

  - Copyright：著作権表示であることを示します。ただしそれを示す法律上の記述は©であり、こちらは不要です。
  - ©（必須）：著作権表示であることを示します。(C)や(c)ではなく、法律上は©が正式なマークとなります。
  - 初回バージョンの公開年（必須）：このソフトウェアの初回バージョンを最初に公開した年です。
  - 最新バージョンの公開年：このソフトウェアの最新バージョンを公開した年です。法律上は不要です。
  - 著作権者の氏名（必須）：このソフトウェアの著作権者です。本名でなくとも、世間に認知される名称であれば、例えばSNSのアカウントでもOKです。
  - All Rights Reserved.：「著作権者が権利を持ってますよ」という宣言です。法律上は不要です。

従って、著作権表示は以下で成立します。

```
© [初回バージョンの公開年] [著作権者の氏名]
```

### ②MITライセンスの許諾表示を記述する。

MITライセンスはこういうものですよ、という説明の「定型文」を記述します。
記述すべき定型文は[こちら](https://opensource.org/licenses/mit-license.php)に記載されていますが、全文の替わりに全文を記載してるWEBページのURLを記述してもOKです。
従って

  - MITライセンスの全文
  - URL「https://opensource.org/licenses/mit-license.php 」
  - MITライセンスの全文が記載されている他のサイト（自サイトに用意してもOK）のURL

のいずれかを記述します。

### ③両者の記載個所は、ソフトウェアのすべての複製または重要な部分とする。
一般的には

  - ソースコード内の先頭にコメントで
  - ソフトウェアのトップ階層に配置した、ライセンス記載用テキストファイル

のいずれかまたは両方に記述するケースが多いようです。



# 私の場合

### ファイルの作成
ソフトウェアのトップ階層に以下のファイルを作成します。これが絶対ではありませんが、GitHubのデフォルトであるためこうしています。

  - README.md  
    最初に一読してほしい内容を記載したテキストファイル。
  - LICENSE.txt  
    ライセンス記載用のテキストファイル。デフォルトから拡張子を付与しています。

### README.mdの記述
ファイルの最後に以下を記述します。著作権と、このソフトウェアがMITライセンスを適用していること、LICENSE.txtを見てほしいことを記述します。
nnnmu24は私のGitHubのアカウントです。

```
# Lisence

This project is licensed under the MIT License, see the LICENSE.txt file for details
```

### LICENSE.txtの記述
著作権表示の下にをMITライセンスの全文を記述します。
GitHubにアップする場合は自動で作成してくれるので、それに任せていますが、「(C)」と生成されるので「©」に変更してます（そのままでも問題になることはほぼありませんが、気持ちの問題で）
ファイル毎に複数のライセンスを使い分ける場合や、ファイル単位で流用されることを意識する場合はソースにも記載した方がよいでしょう。

```
MIT License

Copyright © 2020 nnnmu24

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
PoCを作ろう～nrf52840搭載の電子ペーパー名札を作る～Eink BLE Name Plate

nrf52840を搭載したRAYTACのMDBT50Qモジュールを使用した電子ペーパー搭載の名札を作りました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/418c8bdd-ee38-c2ac-156f-a5a35fce888b.jpeg" alt="" width="700" height="" border="0" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/640a7968-6b1f-b794-4561-a522c6c317f9.jpeg" alt="" width="700" height="" border="0" />
##使用イメージ
受付に行ってもどの人が自分のお客様かわからない事はありませんか？
来訪者が入ってはいけない場所に行ってしまう事はありませんか？
イベント会場で、どんな人が自分のブースに来訪して、どの位居たか知りたくありませんか？
これらを解決するBLE名札を製作することとしました。
今回のモデルは、さらに電子ペーパーも搭載したモデルになります。
LEDにより、来訪者の属性分類や、侵入禁止エリアに入った際の警告が可能です。
電子ペーパーには、来訪者の氏名や訪問先を記載することも可能です。
###LineThingsでの使用イメージ
https://www.youtube.com/watch?v=yBLfJ507tHg
##仕様
マイコン：nrf52840(RAYTAC MDBT50Q)
センサー：温湿度センサ、気圧センサ、加速度センサ
付加機能：フルカラーLED、NFC、スピーカー、電子ペーパー
##回路図
![20201115_15_44_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/92a1bd0b-106f-35f5-7f65-dbb86765400e.png)
![20201115_15_50_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/09eac18c-cc3b-93a5-8edc-bdd9ced7c779.png)
LEDは、回路図の用につなげており、Matrix LEDに近い構成です。
マイコンは20mA程度の電流しか使用できない為、LEDコントローラーでコントロールします。
今回はI2C接続のPCA9622DRを使用しています。
##開発環境
SeggerEmbeddedStudioとArduinoで開発できます。
Amazon S3に画像を保存する（Local／Heroku）

# はじめに
自分用の備忘録

# 手順（Local）
## Gemインストール

```:Gemfile
gem "aws-sdk-s3", require: false
```
## 保存先を変更

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

#下記に変更
config.active_storage.service = :amazon
```

## storage.ymlに追記

```yml:config/storage.yml
amazon:
 service: S3
 access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
 secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
 region: ap-northeast-1
 bucket: バケット名
```

## 環境変数を設定

```:ターミナル
# Catalina以降
% vim ~/.zshrc

[insert mode]
export AWS_ACCESS_KEY_ID="Access key ID"
export AWS_SECRET_ACCESS_KEY="Secret access key"
[:wqで保存]

# 反映させるコマンド
% source ~/.zshrc
```

# 手順（Heroku）
※Gemインストール済

## 保存先を変更

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

#下記に変更
config.active_storage.service = :amazon
```

## 環境変数を設定

```:ターミナル
heroku config:set AWS_ACCESS_KEY_ID="Access key ID"
heroku config:set AWS_SECRET_ACCESS_KEY="Secret access key"
```

### 確認コマンド

```:ターミナル
% heroku config
```
pushして反映

# おわりに

バケットは使いまわせるのでいちいち作らなくてよろしい。

✔︎
POSTパラメータで安易に@Query使ったら泥沼にハマった

## はじめに
読んだ書籍をリスト管理するアプリを作成するべく、書籍追加のAPI実装をしておりましたが
どんな画像を選択しても画像取得エラーとなり追加できませんでした。
ようやく泥沼から抜け出せたので備忘録として記録しておきます。
<img width="200" alt="追加" src="https://user-images.githubusercontent.com/72906152/98779632-89490f80-2437-11eb-9142-92dceffb400b.gif">

## 原因
```xml:Log
Response{protocol=http/1.1, code=414, message=Request-URI Too Large
```
どうやらURIが長すぎるよう。でも何でそんな長くなるの？
原因はリクエストでデータを送信する方法に問題があった。

```java:ApiInterface.java
public interface ApiInterface {
    @Headers(HEADERS)
    @POST("/books")
    Call<BookInfoResponse> addBook(
            @Header("Authorization") String token,
            //　↓原因 
            @Query("name") String bookTitle,
            @Query("image") String stringImage,
            @Query("price") int bookPrice,
            @Query("purchase_date") String purchaseDate
    );
```
### @Queryとは
>データベースに送るクエリ文の指定法。URLに情報が記載される。

つまり書籍名やら画像パスやら追加するブックの情報全てがURLに含める設定にしてたわけです。
そりゃ長くなるわ。
原則として
・Postリクエストは@Body
・GETリクエストは@Query (※GETリクエストで@Bodyは使えない）
とのこと。

ということで@Bodyに変更したらうまくいきました！　

```java:ApiInterface.java
public interface ApiInterface {
    @Headers(HEADERS)
    @POST("/books")
    Call<BookInfoResponse> addBook(
            @Header("Authorization") String token,
            //　@Bodyに変更
            @Body BookRequest bookRequest
    );
```
```java:BookRequest.java
public class BookRequest {
    @SerializedName("name")
    private String title;

    @SerializedName("price")
    private int price;

    @SerializedName("purchase_date")
    private String purchaseDate;

    @SerializedName("image")
    private String image;

    public BookRequest(String title, int price, String purchaseDate, String image) {
        this.title = title;
        this.price = price;
        this.purchaseDate = purchaseDate;
        this.image = image;
    }
}
```

## 勉強させてもらったサイト
https://qiita.com/sakuraya/items/6f1030279a747bcce648#1-%E3%82%AF%E3%82%A8%E3%83%AA%E3%82%B9%E3%83%88%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E5%90%AB%E3%82%81%E3%82%8B

## 最後に
皆さんからしたら、そもそもなんで@Queryにしてたの？って感じなんでしょうね。笑　
完全な知識不足です。勉強になりました〜。
SwiftPMがプロキシを越えられず、プロジェクトへパッケージが追加できない問題を解決する

SwiftPMがプロキシを越えられず、プロジェクトへパッケージが追加できないという現象が発生したのですが、解決することができたのでまとめます。

## 注意
この解決策は私のプロキシ環境において有効性を確認したものであり、プロキシ環境は会社や組織によって異なるため、この解決策がどの環境にも当てはまるとは限りません。

## 環境

- MacBook Pro (Retina, 15-inch, Mid 2015)
- macOS Catalina 10.15.7
- Xcode 12.0

## 発生した現象
- 「[SwiftPMでプロジェクトへパッケージを追加する](https://qiita.com/kabosu3d/items/f6fae72ba111f980c0c0) - Qiita」に従って実施したが、リポジトリのパスを入れて[Next]を押した後、しばらくしてからエラー終了する。
- macのプロキシ設定や、インストールされている`git`、`curl`のプロキシ設定を見直しても改善しない。

## 解決策

調査の結果、なぜか「追加済みのSwift Packageの依存関係として入っているSwift PackageについてはProxyを超えることができ、インストールできる」ということがわかりました。

つまり、**「入れたいSwift PackageをDependencyとして追加したSwift Packageをローカルに作り、それをプロジェクトへ追加する」**ことで解決できます。

ローカルのSwift Packageを追加する方法については、SwiftPMの主要開発者によると、[ディレクトリをプロジェクトへドラッグアンドドロップすれば追加できる](https://forums.swift.org/t/how-to-add-local-swift-package-as-dependency/26457/2)とのことです。それでうまくいけばOKです。
私の環境ではそれだとうまくいかなかったので、[このワークアラウンド](https://qiita.com/kabosu3d/items/3132bd5cb333cf3e427e)を使って追加しました。

以上です。
変数のスコープを間違えてたメモ

#やりたかったこと
LINEで飲みに行きたいと言ったらメッセージが返ってくる予定

#あかんかった
単純なミスだからインデントをちゃんとつけよう。（どこのカッコの中に入ってるかわかりにくかった）
飲みに行きたい1人目って返信してもらうはずが、なにも来なかった。
定義されたスコープが違うからと認識しているが、別の理由か？（use strictをグローバルレベルのところには書いてた。）
もう少し調べよう。

<img width="300px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/607cd8da-36f5-3e3d-a62b-7d775477e630.png">



```javascript
        // ユーザーメッセージが飲みに行きたいものかどうか
        if (check_go(event.message.text)) {
            let pushText = '';
            console.log("飲みに行きたいってさ");
                        
            pushText = "飲みに行きたい人1人目";
        }
　　　　// 中略
        // 「プッシュ」で後からユーザーに通知します
        return client.pushMessage(event.source.userId, {
            type: 'text',
            text: pushText,
        });
【Azure🔰】Windows仮想マシンを作成するの備忘録

#はじめに
AWSを元々勉強していたが、諸事情でAzureの勉強をする必要が出てきた。
AWSと比べてAzureに関する初心者向けの記事が少ないので、私の記事などを通して少しでも初心者でもAzureに対する抵抗感を払拭できたらと思う。
今回はAzure Learnの 「Azure で Windows 仮想マシンを作成する」をやったので、スクショ付けて備忘録として残したい。

#手順
リソースの作成をクリックする。
![スクリーンショット 2020-11-15 10.18.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/8dba2aeb-0166-60a7-5e10-2400fce75fdb.png)
検索ボックスでWindows Serverを入力し、エンターキーを押す。
![スクリーンショット 2020-11-15 10.20.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/0be8edf9-d86b-ca24-0ef1-fcb9541c5119.png)
Windows Serverを選択。
![スクリーンショット 2020-11-15 13.43.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/01303ee8-3b42-5a02-a875-bb5635cf6913.png)
Windows Server 2019 Datacenterのプランを選択し、作成を押下する。
![スクリーンショット 2020-11-15 10.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/4a1796a5-fc80-2897-9379-13f1cbde41b1.png)
仮想マシンの作成が表示されるので、プロジェクトの詳細でリソースグループを新規作成する。
![スクリーンショット 2020-11-11 10.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/393b0675-e760-c6d1-2184-1924ad0c885b.png)
インスタンスの詳細セクションで設定を行う。
サイズはデフォルトだと料金が高いので、なるべく安めのStandard_B1sを今回は設定した。
![スクリーンショット 2020-11-15 9.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/4a7c51f2-fa24-0adb-3e3d-f238dc781ebc.png)
管理者アカウントを設定する。
![スクリーンショット 2020-11-15 9.19.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/6476b8e8-98db-c4c1-3ff5-ab007e42d617.png)
受信ポートをRDPに設定。
![スクリーンショット 2020-11-15 9.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/24a3cd55-851d-0fe2-a3d3-c8bbd63d3e61.png)
ライセンスはデフォルトのままで「次：ディスク」を選択する。
![スクリーンショット 2020-11-15 15.42.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/7539a9c1-a07a-76f3-2fb1-e3dcbd9997ce.png)
ディスクのオプションはでデフォルトのままにする。
![スクリーンショット 2020-11-15 9.35.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/89a0fba7-62c6-d694-a957-c157680f9034.png)
データディスクで新しいディスクを作成し接続するを選択する。
![スクリーンショット 2020-11-15 9.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/159714a7-f73c-b5a3-0b3e-4053f22ba7eb.png)
デフォルトのままでOKを押した。
![スクリーンショット 2020-11-15 9.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/c86d4c15-8e51-3276-bd1b-c4e4cc0dcdb2.png)
ネットワークのセクションで、仮想ネットワークの新規作成を押下する。
![スクリーンショット 2020-11-15 9.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/2257ce9d-49b7-2d6a-7554-3edba40ed49b.png)
アドレス空間のアドレス範囲を`172.16.0.0/16`にする。
サブネットのアドレス範囲を`172.16.1.0/24`にする。
確認したらOKを押下する。
![スクリーンショット 2020-11-15 9.43.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/085a6da1-68b7-90b1-a31b-6033f3f79e3c.png)
ネットワークのセクションに戻り、残りのオプションは既定値で問題ないので、確認および作成を押下する。
![スクリーンショット 2020-11-15 9.44.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/77b12bac-d1a9-0503-8ad5-fa516b029884.png)
問題なければデプロイが行われる。
![スクリーンショット 2020-11-15 9.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/1ef93868-9812-0f08-f4e9-bb413761df3b.png)
東京リージョンのCloud SQLとUSリージョンのBigQueryをFederationする

BigQueryからCloud SQLに対してクエリを実行できる、Cloud SQL federated query機能はとても便利です。
この機能を活用すれば、Cloud SQLからBigQueryに対するETLを作成しなくても、簡単にBigQueryにデータを転送できます。
しかし、この機能はCloud SQLとBigQueryの2つが同一リージョンにある場合のみ使用することができます。
https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries

では、東京リージョンのCloud SQLからUSマルチリージョンのBigQueryに対してクエリを実行したい場合はどうすればよいのでしょうか？

# 解決策
Cloud SQLのリージョン間レプリケーション機能を使い、USリージョンにリードレプリカを作成する。

例えば以下のようなDBインスタンスが東京リージョンにあったとします。

```terraform
resource "google_sql_database_instance" "hoge-instance" {
  name             = "hoge"
  database_version = "MYSQL_5_7"
  region           = "asia-northeast1"

  settings {
    tier = "db-n1-standard-1"
    backup_configuration {
      binary_log_enabled = true
      enabled            = true
      start_time         = "17:00" # JST:02:00
    }
  }
}
```

この場合は、このようにアイオワリージョン(us-central1)にリードレプリカを作ることで、USリージョンのBigQueryとの連携が可能になります。

```terraform
resource "google_sql_database_instance" "hoge-replication" {
  name                 = "hoge-replication"
  database_version     = "MYSQL_5_7"
  master_instance_name = google_sql_database_instance.hoge-instance.name
  region               = "us-central1"

  # プライマリーインスタンスが死んでも、このインスタンスにはフェイルオーバーさせない
  replica_configuration {
    failover_target = false
  }

  settings {
    tier = "db-n1-standard-1"
    backup_configuration {
      enabled = false
    }
  }
}
```
【Java】暗黙的型キャスト（AOJ10 - 数字の和）

#型キャスト
* **char型は暗黙的にint型やdouble型にキャストできる**
* char型のラッパークラスCharacter型はUnicode文字表現
* ”1”の場合U+0031（16進法）49（10進法）
    * char型の”1”が暗黙的にint型にキャストされた場合”49”が出力される
* 参考にさせていただきました
    * [Why we use -'0' beside charAt(i)?](https://stackoverflow.com/questions/12438336/why-we-use-0-beside-charati)
    * [【Java】char型はint型にキャストできる](https://qiita.com/nkojima/items/d358f99efa71655911ea) @nkojimaさま記事

```java
public class Main {
	public static void main(String[] args)  {

        char c = '1';
        //暗黙的にint型、double型にキャスト
        int i = c;
        double d = c;
        System.out.println(c + "をint型へキャスト→ " + i);
        System.out.println(c + "をdouble型へキャスト→ " + d);

        //引数がdouble型のメソッドに、char型を引数として渡す
        doubleMethod(c);
    }

    static void doubleMethod(double d) {
        System.out.println("double型→ " + d);
    }
}
```
```java
1をint型へキャスト→ 49
1をdouble型へキャスト→ 49.0
double型→ 49.0
```

#数字の和（ITP1-8）
>与えられた数の各桁の和を計算するプログラムを作成して下さい。
Input
複数のデータセットが入力として与えられます。各データセットは１つの整数 x を含む１行で与えられます。
x は 1000 桁以下の整数です。
x が 0 のとき入力の終わりとします。このデータセットに対する出力を行ってはいけません。
Output
各データセットに対して、x の各桁の和を１行に出力して下さい。

* この例での`ans += line.charAt(i)-‘0’;`で暗黙的にキャストをしている
    * `line.charAt(i)`はcharを返す
    * `ans`はintegerなので、integerに変換する


```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int ans;

        while(true){
    	String line = br.readLine();
    	    if(line.length() == 1 && line.equals("0")){
    	        break;
    	    }else{
        	    ans= 0;
        	    for(int i = 0; i < line.length(); i++){
        		    ans += line.charAt(i)-'0';
        	    
        	   /*型キャストの確認
        	   System.out.println("line.charAt(i) "+line.charAt(i));
    	       System.out.println("line[i] "+(int)line.charAt(i));
               System.out.println("(int)'0' "+(int)'0');
               */
    	       }
    	       System.out.println(ans);

    	    }
        }
    }
}  
```
【Java】文字列を大文字/小文字へ変換（AOJ⑨ - 大文字と小文字の入れ替え）

#大文字/小文字の変換
* 文字列を大文字/小文字へ変換
    * **toUpperCase,  toLowerCaseメソッド**
* 大文字/小文字かどうかを判別
    * **isUpperCase. isLowerCaseメソッド**

```java
public class Main {
    public static void main(String[] args){
    String str1 = new String("MoHuNeKo");
    String upper_str1 = str1.toUpperCase();
    String lower_str1 = str1.toLowerCase();

    System.out.println("入力文字列 : " + str1);
    System.out.println("1文字目は大文字? : " + Character.isUpperCase(str1.charAt(0)));
    System.out.println("大文字変換 : " + upper_str1);
    System.out.println("小文字変換 : " + lower_str1);
    System.out.println("=======^･ω･^=======");

    String str2 = new String("The current world population is about 7,594,690,000!");
    String upper_str2 = str2.toUpperCase();
    String lower_str2 = str2.toLowerCase();

    System.out.println("入力文字列 : " + str2);
    System.out.println("2文字目は小文字? : " + Character.isLowerCase(str2.charAt(1)));
    System.out.println("大文字変換 : " + upper_str2);
    System.out.println("小文字変換 : " + lower_str2);
    System.out.println("==============");
    System.out.println("大文字? : " + Character.isUpperCase('\n'));
    System.out.println("小文字? : " +Character.isLowerCase('\t'));
   }
}
```

```java
入力文字列 : MoHuNeKo
1文字目は大文字? : true
大文字変換 : MOHUNEKO
小文字変換 : mohuneko
=======^･ω･^=======
入力文字列 : The current world population is about 7,594,690,000!
2文字目は小文字? : true
大文字変換 : THE CURRENT WORLD POPULATION IS ABOUT 7,594,690,000!
小文字変換 : the current world population is about 7,594,690,000!
==============
大文字? : false
小文字? : false
```

#大文字と小文字の入れ替え（ITP1-8）
>与えられた文字列の小文字と大文字を入れ替えるプログラムを作成してください。
Input
文字列が1行に与えられます。
Output
与えられた文字列の小文字と大文字を入れ替えた文字列を出力して下さい。アルファベット以外の文字はそのまま出力して下さい。
Constraints
* 入力される文字列の長さ < 1200
Sample Input
fAIR, LATER, OCCASIONALLY CLOUDY.
Sample Output
Fair, later, occasionally cloudy.

```java
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < line.length() ; i++){
            char now = line.charAt(i);
            if(Character.isUpperCase(now))      sb.append(Character.toLowerCase(now));
            else if(Character.isLowerCase(now)) sb.append(Character.toUpperCase(now));
            else                                sb.append(now);
        }
        System.out.println(sb);
    }
}
```
2Dプロジェクトで画像を表示する

# 前書き
初めてUnityを触る方向け記事になります。
（筆者も初めてUnityに触っているため一部誤りがあるかもしれませんがご了承ください）

Unityのインストールがまだの方はこちらを参照し、インストールしてください。
[Unityインストール手順](https://qiita.com/atsushi-iida/items/2511585a82c59387b7e3)

# 2Dプロジェクトで画像を表示する
画像を表示する方法を下記手順に沿って解説します。

## 2Dプロジェクトを作成
[Unityの新しいプロジェクトの作り方](https://qiita.com/drafts/e26195dbbf4fcf227a97)を参考に2Dプロジェクトを作成する

## Canvasを追加
ヒエラルキー内のMain Cameraを右クリックし、UI→Canvasを選択します。
Canvasはオブジェクトを表示するために必要な要素になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644902/be782359-0c70-55ef-3161-09944ac313f4.png)

## 画像を追加
追加したCanvasを右クリックし、UI→画像を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644902/d9f25d66-b4c0-0199-cbbd-5c8a2eb02367.png)

次に適当な画像ファイルをUnityに読み込ませます。
プロジェクト内のAssetsを選択し、エクスプローラーから画像を引っ張って入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644902/ea3f1ad5-3707-dfcc-4912-b9ce4f9559ab.png)


画像ファイル投入後、Imageに画像を設定するため、ヒエラルキー内の画像を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644902/9394e947-9b34-6667-349c-0dff4fdbec17.png)

右側のインスペクター内に[ソース画像]に"なし（スプライト）"となっているので、ここに先ほどAssetsに投入した画像を引っ張ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644902/befe07a7-6914-da6b-5953-2d690b8deb53.png)

以上で画像を表示させることができます。
SwiftPMでローカルにあるSwift Packageをプロジェクトへ追加する

SwiftPMで、ローカルにあるSwift Packageをプロジェクトへ追加したい場合があります。例えば、プロジェクトと依存パッケージを単一のリポジトリで扱いたい場合などです（モノレポ）。

[SwiftPMの主要開発者の回答](https://forums.swift.org/t/how-to-add-local-swift-package-as-dependency/26457/2)によると、プロジェクトへパッケージをドラッグアンドドロップすればOKとのことですが、少なくとも私の環境ではうまくいかない状況でした（この回答が「あるべき動き」だろうから、今後のアップデートで解消されていくとは思われますが）

この記事では、私の環境における現状(2020/11/15)のワークアラウンドをまとめます。

## 環境
- MacBook Pro (Retina, 15-inch, Mid 2015)
- macOS Catalina 10.15.7
- Xcode 12.0

## 手順
1. 追加したいSwift Packageを、ローカルのgitリポジトリにする。このgitリポジトリはあとで消すので、やり方は適当で構いません（`git init; 
 git add . ;git commit -m "init"`する）
2. 追加したいSwift Packageのディレクトリを、プロジェクトフォルダ内のどこかに置きます。
3. 追加したいSwift Packageのディレクトリを、Xcodeプロジェクトにドラッグ＆ドロップします。
4. Xcodeのメニューから、[File] - [Swift Package] - [Add Package Dependency] と進み、当該のSwift Packageのパスを指定します。「file:// + フルパス」の形です。例えば`file:///Users/n/d/expProject/expdat/swiftPackage`などとなります。
5. パスを修正します。テキストファイルとして.pbxprojを開き、`file://`で検索
して4.で指定したパスを見つけ、相対パスに置き換えます。例えば`./expdat/swiftPackage`などとします。
6. Swift Packageのディレクトリから`.git`ディレクトリを削除します。

`4.`の時点で、すでにプロジェクトへの追加は完了していますが、ローカルでしか扱えず、Gitとかにpushができない状態になります。それを解消するために`5.`、`6.`の手順を行っています。

以上です。
[個人開発]Webアプリを公開してからやった8つのこと

##追記
コメントでのご指摘を受け一時的にサービスを中止し、考え直すことにしました。サーバーはメンテナンスモードにしてあります。再開することになってもURLは変えません。ユーザー登録をしてくださったかた、コメントをくれた方、ありがとうございました。

##初めに
僕はちょうど一か月前にWebアプリを公開しました。そこで公開してから１か月間やったこと、立ちはだかった問題などを振り返ってみようと思います。

##作ったWebアプリ
![code-sell3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480294/87176d28-5478-ef4d-759e-bf0e03d63bf1.png)

URL
https://www.code-sell.net/

プログラムコードを販売できるサービスです。公開した直後にqiitaでも宣伝させていただきました。
[コードを販売できるサービス「Code-sell」をリリースした！(個人開発)](https://qiita.com/UTOG/items/40baefaf9a4a668d39cc)

##やったこと
ここからが本題です。どのようなことを、いつ、どうして、やったかを振り返っていきます

###1 動作確認
いつ...公開した直後
どうして...開発環境ではうごいても本番環境では動かないということがあるから

まあこれは皆さん普通にやると思います。ただ筆者の場合これが甘すぎました。
アカウント登録と有効化
コード販売
購入機能

このくらいしかしませんでした。おかげで細かいところでエラーの目撃が相次ぎました。
送金機能、検索機能、アカウント編集機能、ページが開けないなど...
こういうのはサービスの信頼にかかわるのでしっかりやることをお勧めします。焦らずに、すべてのページを開いてすべての機能を試したほうがいいです。しかもこれをしっかりしなかったせいで、後で紹介する致命的バグに3,4週間くらい気づけないことになります。

###2 初期データ投稿
いつ...動作確認が終わってから
どうして...初期データがないと使ってもらえないから

これはいろんなサイトで言われていますが、だれも投稿していないあやしいサイトを使おうと思いますか？使わないでしょう。
だから初期データを作るか、トップページでは投稿されてるかどうかわからなくしたほうがいいです。

###3 めっちゃ宣伝


[qiita](https://qiita.com/)
[dev.to](https://dev.to/)
[service safari](https://www.service-safari.com/)
[つくろぐ](http://creators.eightbit.jp/)
[startapp](http://startapp.jp/)
[eggineer](https://www.eggineer.com/)
[ロケットリリース](http://rrws.info/)
[note](https://note.com/)
[zenn](https://zenn.dev/)
[crieit](https://crieit.net/)

くらいですかね。宣伝できる場所があれば徹底的にやりました。特にqiitaとservice safariとnoteが効果が大きかったと思います。

###4 バグ・エラー修正
いつ...qiitaなどで宣伝した直後（本当は動作確認で気づくべき）

がばがば動作確認によって発生したバグ・エラーたちを修正します。

###5 機能追加
いつ...バグ・エラー修正が一通り終わったころ

公開してから追加した機能は
技術メモ...廃止済み
運営からのおしらせ...最初から実装しとくべきでした。
フォロー...なくてもいいかも
pv機能...なくてもいいかも

くらいですかね。技術メモは「このままだとオワコンになるかも！」とか言って深夜テンションで作ってしまった黒歴史です。qiitaには投稿できないようなしょっぼいメモを残すというものです。全く使われませんでした。しかもサービスの機能の統一性がなくなるのでSEOも弱くなるかもしれません。
皆さんがwebアプリを作るときは一つのサービスだけをやりましょう。

###6　公式ツイッターをつくる
いつ...機能追加してる合間

これは、もっとユーザーが増えてからでもいいかもしれません。宣伝効果もないし、アップデートはお知らせでできるし。

###7　致命的バグに気づく
いつ...公開してから3,4週間たってから

どうのようなバグかというと**送金先がみんな同じになる**というものです。
幸い、お金の取引はまだされていなかったので大丈夫でしたが本当に取り返しのつかなくなるところでした。
####なぜここまで発見が遅れたか
- 基本的な機能過ぎて逆に見直してなかった 

- 管理画面を見てもアカウント数がある程度がないとわかならい

- testコードを書いていなかった

- 一つや二つのアカウントだけで動作させているとわかならい（お問い合わせが来なかった理由）

みなさんも動作確認するとき１つや２つのユーザーではなくseedで5~10くらいのテストユーザーを作ってやりましょう。

###8 SEO対策や速度改善（現在）
今は機能を追加するというよりSEO対策や速度改善などを中心にしています。トップページのデザインを細かく変えたり、サイトマップを作りGoogle Search Consoleに送ったり、余計なcssを消したりしています。

[参考サイト](https://www.gyro-n.com/seo/hack/seo-point/)


##まとめ
今回学んだこと

- 動作確認は慎重に、seedを利用しテストユーザーを作ってからやる

- 宣伝、完璧な状態になってからやる

- 変なノリでいらない機能は作らない。

ここ一か月いろいろありました。急にアカウント数が増えたり、バグに気づき冷や汗をかいたりすごい良い体験をして一か月だったなと思います。よかったら開発したアプリ使ってみてください。

https://www.code-sell.net/
Cloud Pub/Subのリージョン間通信費用にご用心

Cloud Pub/Subはリージョンに依存しないサービスですが、使い方によってはリージョンを考慮する必要があります。
その1つの例がリージョン間通信費用です。

以下のような構成で東京リージョンのApp EngineからUSリージョンのCloud Dataflowにデータを転送していました。

![Untitled Diagram (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/b982d345-8221-c16a-c876-8622d6f96ca8.png)

そのプロジェクトのBilling Dashboardを見ると、少し違和感のある項目が見つかりました。
Cloud Pub/Subのリージョン間転送費用が加算されていたのです。
Cloud Pub/Subはリージョンに依存しないサービスであるため、この項目には違和感がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/a95e87da-797b-10cc-2e31-f8243245a724.png)

Pub/Subの利用料金のページをよく見ると、これに該当する項目が見つかりました。

> The fees for internet egress and message delivery between Google Cloud regions are consistent with the Compute Engine network rates

https://cloud.google.com/pubsub/pricing#egress

Cloud Pub/SubにPublishしたリージョンとSubscribeしたリージョンが異なる場合は、GCEと同等のレートで課金が発生します。
今回の例は東京→USなので、以下のページの「Egress to a Google Cloud region on another continent (excludes Oceania)」に該当します。
1GBを転送する毎に0.08 USBの課金が発生します。
転送するデータ量が少ないうちは無視できる金額ですが、TB級のデータをCloud Pub/Subで転送するときには気にする必要がありそうです。

https://cloud.google.com/vpc/network-pricing#egress-within-gcp

# 場合によっては2回課金されるケースもある
トピックにストレージポリシーを設定している場合は、さらなる注意が必要です。
https://cloud.google.com/pubsub/docs/resource-location-restriction

この場合は以下の3つのリージョンが登場することになり、場合によって1→2と2→3の2回でリージョン間転送費用が課金されます。

1. PublisherからのPublishリクエストを受けとるリージョン
2. ストレージポリシーで許可されているリージョン
3. SubscriberからSubscribeリクエストを受け取るリージョン
DjangoでRailsのhelperのような機能を実装する方法

##はじめに
この記事はDjangoで初めてアプリを作る際に、Railsのhelperのような機能がないか調べた際の個人的メモです。



##環境
Python(3.6.2)
Django(2.1.7)


##カスタムテンプレートフィルタ
Railsのhelperはhelper内で定義したメソッドをview側で呼び出すことができます。Djangoでも同じように別ファイルで定義したメソッドをtemplate側で呼び出せないか調べたところ、カスタムテンプレートフィルタを作成することで実現できるようです。


##実装方法
以下の手順で、カスタムテンプレートフィルタを作成できます。

###1. templatetags というディレクトリを作成
カスタムフィルタを導入したいテンプレートのアプリディレクトリ内にtemplatetagsというディレクトリ を作成します。

###2. templatetagsに \_\_init__.py を設置
templatetagsディレクトリ内で作成するファイルをモジュール化するために\_\_init__.pyを設置します。

###3. templatetagsにカスタムテンプレートフィルタを定義するファイルを作成

まずテンプレートライブラリを呼び出します。

```python
from django import template
register = template.Library()
```

このライブラリにオリジナルで作成するカスタムテンプレートフィルタを登録します。これで、template側で作成したメソッドを呼び出すことが可能になります。

```python
@register.filter
def transrate_media_number(var):
  if var == 0:
    media_name = 'ぐるなび'
  elif var == 1:
    media_name = '食べログ'
  elif var == 2:
    media_name = 'ホットペッパー'
  else:
    media_name = 'その他'
  return media_name

```

```python:custom_filter.py
from django import template
register = template.Library()

@register.filter
def transrate_media_number(var):
  if var == 0:
    media_name = 'ぐるなび'
  elif var == 1:
    media_name = '食べログ'
  elif var == 2:
    media_name = 'ホットペッパー'
  else:
    media_name = 'その他'
  return media_name

```

最終的には、以下のようなディレクトリ 構造になります。


app/
　├ models.py
　├ templatetags/
　│　├ \_\_init__.py
　│　└ custom_filter.py
　└ views.py



###4. テンプレート側で呼び出す

まずはテンプレートから 作成した カスタムテンプレートフィルタ を読み込みます。

```python
  - load custom_filter
```
読み込まれたカスタムテンプレートフィルタは下記のような形で利用することができます。

```python
  {{ 引数 | カスタムテンプレートフィルタ名 }}
```



```python:template_file.html.haml
- load custom_filter

%table
  {% for data in datum %}
    %tr
      %td
        {{ data.take_at }}
      %td
        # {{　引数 | カスタムテンプレートフィルタ名 }}
        {{ data.media_number | transrate_media_number }}
```


これで完了です。
エンジニアリングマネージャーとしての数ヶ月を振り返る

こんにちは、CAMPFIREでエンジニアリングマネージャーをやっている[岩崎](https://twitter.com/yuzoiwasaki)です。元々はSREだったり、SREのプレイングマネージャーをしていたりするのですが、前任者の退職と組織変更に伴い、現在は全体のエンジニアリングマネージャーをやっています。今のCAMPFIREにはCTOもVPoEもいないので、ある意味で私がそれらのロールも引き受けていることになります。

今の立場になって数ヶ月、初めての職種で不慣れなことだらけでしたが、周りのサポートもあり、私なりに考えて様々な取り組みを行ってきました。このアドベントカレンダーもそのうちの一つです。アドベントカレンダーはCAMPFIREでは初めての試みなのですが、言い出しっぺの所信表明ということで一日目に書かせていただきました。

## エンジニアリングマネージャーとは
そもそもエンジニアリングマネージャーとはどういった職種なのでしょうか。もちろんその名の通りエンジニアに対するマネージメントを行う役割ではあるのですが、組織によって担当する範囲は様々だと思います。

共通する役割としては、エンジニアメンバーに対する 1 on 1 などを通した日々のケアや評価、採用などでしょうか。ここはどの会社でもエンジニアリングマネージャーが担当しているように思います。

一方で技術的な意思決定については必ずしもエンジニアリングマネージャーが行うわけではなく、むしろテックリードが行うケースが多いようです。会社によってはエンジニアリングマネージャーがテックリードを兼任しているケースも多いため、この辺りは一概には言えないところでしょう。

また、メンバーのタスク調整については、エンジニアリングマネージャーが行うケースもあればプロジェクトマネージャーが行うケースもあるようです。

## 初めにやったこと
私がエンジニアリングマネージャーになった時、あまり組織は良い状態ではありませんでした。優秀なエンジニアがどんどん辞めている状態だったからです。一人一人の辞めた理由は様々ですが、改善できるところは改善し、まずは内部を建て直す必要がありました。

### 1 on 1
まず、今の状態をヒアリングするためにメンバーと 1 on 1 を行いました。そうして、コミュニケーションの取りづらさ、環境の不満など出てきた声を一つ一つ丁寧に解消していきました。

1 on 1 では、「最近どうですか？」から入ってゆるい雑談ベースで話し、もし不安なことや困っていることがあれば一緒に取り除くようにしました。また、ここでは進捗確認や評価は行わないようにしました。

1 on 1 のアンチパターンとして部下が相談しても上司が否定して終わってしまう、上司の確認のための時間になってしまうというのがあるため、そうならないように意識しました。

### 会議体の見直し
元々のチームがPM、エンジニア、デザイナーが一緒になっており、しかも正社員、業務委託問わずミーティングに出席していたため、毎日のミーティングの人数が非常に多いという問題がありました。最大で20人くらいの人数になっていたため、細かい話ができず、発言のハードルも高い状況でした。

そこで一旦正社員エンジニアだけでミーティングを行い、その他の連携は別途取る形式に変えました。同様にデザイナーもデザイナーだけで集まってミーティングをするようになりました。

## コロナ下でのコミュニケーションを考える

今年はコロナもあって、リモートの状況下でメンバー間のコミュニケーションが取りづらいという声が多く聞かれました。そこでCAMPFIREでは以下のような取り組みを行いました。

### 個人チャンネルの活用
Slackの個人チャンネル（分報チャンネル）を積極的に活用しました。実際に運用してみると個人チャンネルへの投稿は心理的障壁が低く、積極的に投稿してくれることがわかりました。個人チャンネルでコミュニケーションが生まれることで、出社していた時にあったちょっとした雑談ができるようになりました。

### 質問チャンネルの活用
質問専用のSlackチャンネルを作りました。専用のチャンネルを作って質問を推奨することで、詰まっているところを積極的に質問することができるようになり、また以前質問した人が別の人に回答するなど、良い循環が生まれました。

### 社内ミートアップの開催
上記のように、ミーティングの形式が変わったことで横のつながりが薄くなってしまったため、定期的にコミュニケーションを目的とした社内ミートアップを開催しました。今は月一ペースで昼に10人〜20人くらいで集まって、最近のことや相談したいことについてゆるく話しています。

### もくもく会の開催
これは私ではなく現場のメンバーからやりたいと声が上がって始まったものなのですが、毎週火曜日の夕方にもくもく会をやることにしました。参加したい人はGoogle Meetで繋いで作業するイメージです。やってみると、出社していた時のような雰囲気がありわりと良いと好評のようです。

## 最近は何をやっているか
最近は内部の改善が一通り落ち着いてきたので、少しずつ役割の委譲や採用に着手しています。

### 役割の委譲
私一人で全てのチームを見続けるのは限界があるため、徐々に他のメンバーに役割を委譲しています。具体的には、SREチームとCAMPFIRE本体の開発チームでそれぞれリードエンジニアを立て、ミーティングの進行やメンバーのフォロー、相談などは彼らにお願いすることにしました。

このようにうまく回るようになったタイミングで役割を徐々に委譲していくことで、スケールする組織になりますし、私が他のところに入って別の改善に取り組めるようになります。また、委譲されたメンバーのモチベーション向上にも繋がります。

CAMPFIREには元々リードエンジニアという職種はなかったのですが、今回のように適切なポジションを提供し続けることで、今後のメンバーのキャリアプランについても考えていきたいと思っています。

### 採用
エンジニアリングマネージャーの重要な仕事の一つにエンジニアの採用がありますが、私は採用するならまず中を見るべきだと思っています。外ばかり見て中の優秀なエンジニアに辞められては本末転倒ですし、中の環境が良くなればリファラルなどで自然と良いエンジニアは集まってくるからです。中の環境の整備と外の採用は一枚のコインの表と裏なのです。

CAMPFIREの開発チームはSREチームと比べて発信力が弱いという課題があり、これまで採用に苦戦していたのですが、テックブログを始めたり社内勉強会を開いたりと、徐々にブランディングできるような取り組みを始めました。冒頭に書いた通り、今回のアドベントカレンダーもその一つです。
https://note.com/campfire_dev/n/ne023ff03ab4a

こうした取り組みは上からの押しつけになってしまっては意味がありませんが、今のところわりと楽しんでもらっているように思います。引き続き、良い組織作りができるように頑張っていきます。

明日はSREの[naoto](https://qiita.com/fnaoto)さんです！
include?メソッドを使った名前入力確認

以下備忘録

```ruby
def check_name(str) 
  if str.include?(".")
    puts "!エラー!記号は登録できません"
  elsif str.include?(" ")
    puts "!エラー!空白は登録できません"
  else
    puts "登録が完了しました"
  end
end

puts "登録したい名前を入力してください(例)YamadaTaro"
str = gets
check_name(str) 
```

check_nameメソッドでは、「ピリオドや空白がない場合は登録を行い、ピリオドや空白がある場合はエラーを出す」という条件分岐を行うためにif文を使用しています。
引数strで受け取った文字列に対してinclude?メソッドを使用し、”.”(ピリオド)と
” ”(空白)がないか判断を行います。
SwiftPMでプロジェクトへパッケージを追加する

SwiftPMでプロジェクトへパッケージを追加する方法についてまとめます。

## 環境

- MacBook Pro (Retina, 15-inch, Mid 2015)
- macOS Catalina 10.15.7
- Xcode 12.0

## 手順
### 1. Xcodeで、[File] - [Swift Package] - [Add Package Dependency] と進み、

![スクリーンショット 2020-11-15 15.12.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/8a46c0e4-c90f-d38a-b55d-eb67a2d4706d.png)

### 2. Swift Packageのリポジトリ名を入れて(ここではPromiseKit)、[Next]を押す

![スクリーンショット 2020-11-15 15.13.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/89bb6c39-a89b-8407-2ac0-783470c7dd49.png)

あとは指示に従って進めば追加できます。

以上です。
確率表記一覧

今更ながら確率系の勉強をしていて、諸々の表記法がごちゃごちゃして分からなくなってきたので整理してみます。
独学なので厳密な定義や表記には誤りがあるかもしれません。気がついたら適宜ご指摘いただけると幸いです。



## 条件付き確率
$P\left(A|B\right)$

事象$A$と事象$B$
事象$B$が起こったときに事象$A$が起きる確率

$P\left(A|B\right) = \dfrac{P(A\cap B)}{P\left(B\right)}$
と定義される

## 同時確率
$P(A,B)$
事象Aと事象Bが同時に起こる確率

$P(x=a,y=b)$
の様にx=aかつy=bになる確率、といった表記で利用することもある


## 期待値
$E_{p\left( x\right)}\left[ x\right] $
や
$\langle x\rangle _{p\left( x\right) }$
確率$p\left( x\right)$での$x$の期待値


## ドロー
$x\sim p$
$x\sim p(x)$

確率$p(x)$のもとで$x$を取り出すこと


## 独立
$A\perp B$
>私が書籍でみたものは縦棒が2つなのですが、LaTexでの表現方法が分からず。。

事象Aと事象Bの発生がお互いに影響しないこと。

## 確率密度関数
$p(x)$
大文字の$P$だと一般的に確率を示すが、
小文字の$p$は一般的に確率密度関数を示す。


## ガウス分布
$\mathcal{N}(x| \mu,\sigma^2)$
または$x|$を省略して
$\mathcal{N}(\mu,\sigma^2)$

ガウス分布または正規分布と呼ぶ

$\sigma^2$は分散
$\mu$は平均値
CentOSのバージョン確認コマンド

#コマンドはこちら

```shell:
cat /etc/redhat-release
```
例えばの結果はこんな感じ。
CentOS Linux release 8.2.2004 (Core) 


#蛇足
CentOSはファイルサーバー兼ネットの動画見る用（Chromeブラウザで）として使っているん。

ファイルサーバーのバックアップをクラウドに移行したり、redmine入れたり、などなど用途が増えていく予定。
ゼロから始めるORACLE MASTER Bronze Oracle Database 12c対策生活【前編】（Bronze DBA12c 編）

#はじめに
　先月（2020年10月）、ORACLE MASTER Bronze Oracle Database 12cという資格に合格（認定）しました。が、合格するまでの道のりが中々に鬼畜極まりなかったので、今回その内容を書き起こそうと思い記事を作成しました。ORACLE Databaseに限らず、「これからDatabaseを勉強しよう！！」という方向けに作成しておりますのでご覧ください。

#ORACLE MASTER Bronze Oracle Database 12cとは
　ORACLE MASTER Bronze Oracle Database 12cとは、Oracle Enterprise Managerなどを活用し、データベース管理者として必須となる管理者業務を行うための知識があることを証明する認定資格です。要は<b>「ORACLE Databaseが分かるよ！！」</b>と客観的に証明する認定資格の事です。
　ORACLE MASTER Bronze Oracle Database 12cを認定するには、以下の2つの試験を両方とも合格する必要があります。
<ul>
<li>Bronze DBA12c  (1Z0-065-JPN) 試験
https://education.oracle.com/ja/bronze-dba-12c-available-only-in-japan/pexam_1Z0-065</li>
<li>12c SQL基礎(1Z0-061-JPN) 
https://education.oracle.com/ja/oracle-database-12c-sql-fundamentals-retiring-april-30-2018/pexam_1Z0-061</li>
</ul>
 前者はORACLE Databaseの「製品・機能・役割」といった性質を理解する試験で、後者はORACLE Databaseの「SQL文（正確にはORACLE Database独自のSQL文）」の性質を理解する試験です。今回は前者のBronze DBA12c  (1Z0-065-JPN) 試験に関してお話をしていきたいと思います。
<br>
後編はこちらから：
https://qiita.com/syuki-read/items/bd4a5075844eda6296a8

#Bronze DBA12c  (1Z0-065-JPN) 試験

###試験内容
 ORACLE Database Bronze DBA12c  (1Z0-065-JPN) 試験は前述した通り、ORACLE Databaseの「製品・機能・役割」といった性質を理解する試験です。具体的には

<ul>
<li>ORACLE Database管理の概要</li>
<li>ORACLE Databaseのインストール</li>
<li>ORACLE Database作成</li>
<li>ORACLE Network環境構築</li>
<li>ORACLEインスタンスの管理</li>
<li>Database記憶域構造の管理</li>
<li>ユーザ・セキュリティ管理</li>
<li>スキーマ・オブジェクト管理</li>
<li>バックアップ・リカバリ</li>
<li>ユーザ・セキュリティ管理</li>
</ul>

などがあります。

###試験概要
また、試験概要も記載すると下記のような構成となっております。

<ul>
<li>試験時間120分</li>
<li>問題数73問</li>
<li>合格ライン70％以上</li>
<li>問題形式：選択式</li>
</ul>


#対策方法
ここからはBronze DBA12cの対策方法に関して記載いたします。

###1.Ping-t
まずは、全体像を掴むためIT学習用のサイトである「Ping-t」を活用し対策の方を行っていきました。まずBronze DBA12cの各分野ごとの項目を9割以上正解できるようにし、全体を網羅し、その後模擬試験で総合演習を行いこちらも9割以上の正解率を出すようにし、何度も何度も繰り返し対策を行いました。しかし、Ping-tの問題集は本番試験の問題より簡単な傾向があるため、これでは不十分と感じPing-tに加え、別の対策を行っていきました。（試験生活が終わった今でも、Ping-tの問題集のみの対策は実試験をかなり乖離があると個人的に感じています）

Ping-tのサイトのURL
https://ping-t.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/6bdc6d5e-cc20-8a75-de4a-934ce9fe49a1.png)

###2.黒本
Ping-tの一通りの対策が完了後、私は問題集の対策にシフトしていきました。取り扱った問題集で、私は通称『黒本』と呼ばれる「徹底攻略ORACLE MASTER Bronze DBA 12c 問題集［1Z0-065］」を活用しました。こちらの「問題集で安定のインプレス」が出している問題集なだけあって、Bronze DBA12cのかなり細かい内容まで網羅しておりました。現に、Ping-tではカバーしきれなかった問題は勿論の事、Oracle Database特有の「重箱の隅をつつくような問題」まで幅広く対応がなされておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/e57da529-c9fa-8dbd-abb4-436ffdd547f6.png)

#試験当日
試験対策は平均毎日1～2時間の対策、約2ヶ月ぐらいかけて対策の方を行ってきました。（Ping-tに1ヶ月半、黒本に半月）そんな万全を期した準備した試験当日、かなりの意地の悪い問題に圧倒されかけました。というのも、このOracle Database全般を通して言える事なんですが、ここが出題している問題は「幅広い基礎知識を問う問題」ではなく、「幅広い知識を前提に細かいシチュエーションを問う問題」がほとんどで、重箱の隅をつつくようないやらしい問題が本当に多いです。そんな訳で、試験当日は目をかなり殺気立てて行っていたと意識しております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681742/5d8e0d52-9858-bef0-de00-39c8b43df22a.png)


#結果は
試験結果は71％とギリギリの合格でした（合格ライン70％以上）
マジで、ギリギリでした😣


#終わりに
試験を通して感じた事は、このBronze DBA12cがORACLE Databaseの「製品・機能・役割」といった性質を理解する試験で、サブ的な試験だと考えているととても痛い目に合う試験だと改めて感じました。特に、試験では重箱の隅をつつくような問題が多いので、『黒本』か『白本』（模擬試験がメチャクチャ難しいで話題の問題集）でしっかりと対策していった方がいいと強く思います。
【Docker】ローカルのDockerイメージからHerokuへデプロイする方法

デプロイする流れ

```
１　Heroku上にHerokuアプリを作成する。（URLが付与される） 

２　Herokuのコンテナレジストリ（Heroku上のDockerイメージ置き場）にDockerイメージをプッシュする。

3  Dockerイメージをアプリへリリース

４　デプロイしたアプリへブラウザでアクセス
```


事前にアカウントを作成し、クレジットカードを登録しておく。（クレジットカードを登録しないと公開できない。)

heroku cli のインストール(mac)

```
brew install heroku/brew/heroku
```
herokuへログイン

```
heroku login
```
自動起動するブラウザからログインする。


コンテナレジストリにログイン

```
heroku container:login
```

アプリに移動

※herokuはアプリのルートディレクトリ直下のdockerfileを参照する仕様。そのため、dockerfileが違う場所にある場合は、複製してルート直下にheroku用のdockerfileを配置する必要がある。

herokuでapacheを動かそうとするとエラーとなるので一部対処が必要。

エラー対処設定ファイルを作成

```run-apache2.sh
sed -i "s/Listen 80/Listen ${PORT:-80}/g" /etc/apache2/ports.conf
rm /etc/apache2/mods-enabled/mpm_event.conf
rm /etc/apache2/mods-enabled/mpm_event.load
apache2-foreground "$@"
```
dockerfileでコンテナへコピーする記述と実行コマンドを追記

```heroku用　dockerfile.
COPY ./docker/app/run-apache2.sh /usr/local/bin/
CMD [ "run-apache2.sh" ]
```

エラー対処設定ファイルに実行権限を付与する

```
chmod +x run-apache2.sh
```

herokuアプリを作成

```
heroku create
```

データーベースと連携させるためアドオンをインストールする。(ignite => 無料)

```
heroku addons:create cleardb:ignite
```

cleardbの接続設定を確認する。

```
heroku config | grep CLEARDB_DATABASE_URL

mysql:// ユーザー名 : パスワード @ ホスト名　/データーベース名 ?
```
環境変数の設定

```
heroku config:add DB_USERNAME=ユーザー名

heroku config:add DB_PASSWORD=パスワード

heroku config:add DB_DB_HOST='ホスト名' (.が入っているので'で括る)

heroku config:add DB_DATABASE=ユーザー名　
```

確認

```
heroku config
```

テーブルの作成

```
heroku run "テーブルの作成関数が記載されたファイル"
```


レジストリコンテナへプッシュ

```
heroku container:push web
```
レジストリコンテナへリリース

```
heroku container:release web
```

ブラウザ上からアクセス

```
heroku open
```

※複数のアプリを登録していた場合

```
heroku apps:info
```

アプリケーション名を調べてコマンドの末尾に

```
--app アプリ名　
```
を付与する。

herokuアプリを削除する方法

```
heroku apps:destroy --app アプリ名 -confirm アプリ名
```

heroku ログの確認(--tail で監視)

```
heroku logs --tail
```

修正を反映させる。
ローカルファイルを修正。


レジストリコンテナへプッシュ

```
heroku container:push web
```

レジストリコンテナへリリース

```
heroku container:release web
```