OmniAICreator/Qiita-1.07M huggingface dataset:
[Python]自然言語処理で遊んでみた ~transformers~

自然言語処理の様々なツールがpythonで試せると聞いたので色々と遊んでみました。
アルゴリズムは全く見えませんが、ほんの数行で面白いことができるのは驚きです。

###実行環境
Google ColabNotebook

#やってみたこと

まずはtransformersをインストールし、必要なものを定義しておきます。
＊transformersのソースは[こちら](https://github.com/huggingface/transformers#model-architectures)


```
pip install transformers
```

```lang.py
import torch
from transformers import pipeline
sentiment_analysis = pipeline('sentiment-analysis')
question_answering = pipeline('question-answering')
fill_mask = pipeline("fill-mask")
feature_extraction = pipeline("feature-extraction")
```
今回は上の４つで遊んでみました。以下でそれぞれ見てみます。

###sentiment-analysis
入力された文のポジティブ・ネガティブ度合いを出力してくれます。

```lang.py
sentiment_analysis("Because of the pandemic, I decided to refrain from going out.")
# => [{'label': 'NEGATIVE', 'score': 0.9692758917808533}]
```
すごい確率でネガティブ予想されています。

###question-answering
質問文、状況説明文（この中に答えとなる単語がある）を与えると、答えを返してくれます。


```lang.py
question_answering({
    'question': 'What is the cause of the pandemic?',
    'context' : 'The coronavirus triggered an outbreak, and society was thrown into chaos.'
})
# => {'answer': 'coronavirus', 'end': 15, 'score': 0.6689822122523879, 'start': 4}
```
正しい答えが出ていますね。
（ただ、他にも色々試したところ誤りを返すこともままあったので、アルゴリズムにとって分かりやすい？文でないと上手くいかなさそうです。）

###fill-mask
文の中に一箇所<mask>を入れたものを与えると、その空欄に当てはまりそうな単語を入れて返してくれます。

```lang.py
fill_mask("I have to be in bed all day today because I get <mask>.")
'''
 => [{'score': 0.2714517414569855,
  'sequence': '
 I have to be in bed all day today because I get tired.
',
  'token': 7428},
 {'score': 0.19346608221530914,
  'sequence': '
 I have to be in bed all day today because I get sick.
',
  'token': 4736},
 {'score': 0.07417058944702148,
  'sequence': '
 I have to be in bed all day today because I get headaches.
',
  'token': 20816},
 {'score': 0.05399525910615921,
  'sequence': '
 I have to be in bed all day today because I get insomnia.
',
  'token': 37197},
 {'score': 0.05070624500513077,
  'sequence': '
 I have to be in bed all day today because I get sleepy.
',
  'token': 33782}]
'''
```

どれも良さそうですね。
（時節柄、気が滅入りそうな例文ばかりですみません。。）


###feature-extraction
入力した文の特徴を表すベクトルを返してくれます。
上の三つとは違って数値のみの戻り値ですが、これを使えば自作のモデルで文章を扱うのも簡単にできそうだな〜と思ったり。（いつか何かやってみたい）

```lang.py
array = feature_extraction("I catch a cold.")

import numpy as np
np.array(array).shape
# => (1, 7, 768)

array[0][0][:10]
'''
 => [0.3683673143386841,
 0.008590285666286945,
 0.04184938594698906,
 -0.08078824728727341,
 -0.20844608545303345,
 -0.03908906877040863,
 0.19680079817771912,
 -0.12569604814052582,
 0.010193285532295704,
 -1.1207540035247803]
'''
```

上のような次元、値を持つリスト型を返してくれました。
それにしても、「風邪を引いた」という文一つを理解するのにこんなにデータを使うとは。。

以下ついでにもう一つ。

```lang.py
array = feature_extraction("I catch a cold　and I am sleepy.")

import numpy as np
np.array(array).shape
# => (1, 11, 768)

array[0][0][:10]
'''
 => [0.3068505525588989,
 0.026863660663366318,
 0.17733855545520782,
 0.03574731573462486,
 -0.12478257715702057,
 -0.22214828431606293,
 0.2502932548522949,
 -0.17025449872016907,
 -0.09574677795171738,
 -0.9091089963912964]
'''
```

二番目の次元が変わりました。最後の次元の768というのは変わらないみたいです。
Webスクレイピングでボートレース試合情報を取得する

# はじめに
この記事は、自身で製作しWeb公開にまで至ったボートレース３連単予測サイト「[きょう、ていの良い予想は当たるだろうか](https://youhaveniceboat.pythonanywhere.com)」の内部コード解説となります。今回はウェブスクレイピングに関してまとめていきます。

※コードの書き方は我流なので、アドバイスいただけると有り難いです。


# どんな情報が欲しいか、それをどこから頂くか
私が作りたいのは機械学習によるボートレースの3連単予想サイトなので、学習データとして、過去のレース結果をなんとか入手したいです。
最低限欲しい情報としては、、

- 競艇場
- 選手名
- Lane情報
- レース結果
- レースが行われた日付

ですかね。その他に欲しい情報は

- 第何レースか
- その日の天気
- モーター情報

などでした。最近のボートレース公式HPはデータもきちんと整備されており、過去のレース結果も参照することができます。

今回は、ここから学習データの大元となるレース結果を取得していきたいと思います！

# URL構造を把握する
ボートレースの事前知識として、基本的に365日、24競艇場の中の幾つかの競艇場でレースが行われています。
そこで、URL構造を把握した後はレース情報を希望日数×24競艇場分取得することにしました。（レースが行われなかった場合は処理をスキップする）

URL構造を把握し、以下のようにしてURLが入った箱を用意しました。
コード内では2020/6/22のみのデータを取得していますが、year, month, dayのリストを増やしていけば、その他の日付のURLも取得できるようなイメージです。

```python
import pandas as pd
import numpy as np

list = []
year = ['2020']
month = ['06']
day = ['22']
site = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24']

for i in year:
    for j in month:
        for k in day:
            for l in site: 
              list.append("url name is described here")
```

# ボートレース結果を取得する！
こちらがそのコードとなります。
スクレイピングをする際には相手側のWebサーバーに負荷をかけないよう、一定時間を**必ず**設けるようにしましょう。

```python
import requests
from time import sleep
from bs4 import BeautifulSoup

path_w = 'bs_2020_0622.txt'
list_errorlog = [] #その日試合がなかった競艇場をメモる、一応。

for m in range(len(list)):
    try:
        res = requests.get(list[m])
        res.encoding = res.apparent_encoding
        res.raise_for_status()
        with open(path_w, mode='a', encoding='utf-8') as f:
            txt = res.text
            soup = BeautifulSoup(txt)
            f.writelines(soup.get_text())
        sleep(5) #消さない！
        
    except:
        sleep(5) #消さない！
        list_errorlog.append(list[m]+"is not existing")

print(list_errorlog)
```

このコードでは

* ページにアクセス→テキストデータを取得し.txtに記入→5秒あけて繰り返す
* try catchによりWebページが存在しない（＝レースがない）場合はスキップするように処理

を行なっています。参照先がかなりシンプルな構成なのでこれでいけますが、もっと凝ったページだとHTMLタグを上手く絞ってスクレイピングする必要があると思います。

# 取得結果がこちら
いい感じですね。次回はこのtextデータを機械学習が行えるようなDataFrame形式に変換していきたいと思います。
う〜ん、スクレイピングってすごい。（流行乗り遅れ感はありますが..）
<img width="642" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/9cfad415-b976-9b42-01b9-ebc50036c280.png">

## 最後に
* Webスクレイピングを行うにあたり、公式ホームページサイトポリシーを一読しました。
* また、スクレイピング せずとも上記のようなテキストデータは**公式サイトからダウンロード可能**です（爆）

<div align="right">お後がよろしいようで..</div>
まぁダウンロードを都度都度せずに自動的に処理できたし、勉強できたし、良かったかな！
【Javascriptライブラリ】sticky-sidebar (追従サイドバー)

# はじめに

サイドバーの追従のJavascriptライブラリを紹介しようと思います。
Qiitaでは初ものの記事となります。

サイドバーの追従といえば、CSS```position: sticky;```で実装するのが通常かと思います。


sticky-sidebarを使うことのメリットとしては、

* ```position: sticky;```はブラウザによって対応していないものもあるが、sticky-sidebarはJavascriptライブラリなので基本的にはどのブラウザでも動く
* Javascriptを使ってサイドバーの追従を実現しているため、Bootstrapなど複雑なCSSをいじるのは面倒という方にはとても便利

まずは下記リンク先のデモを使用してみて、便利だと思ったら使用してみてください。

* デモ
    * https://abouolia.github.io/sticky-sidebar/examples/basic.html
* sticky-sidebar (GitHub)
    * https://github.com/abouolia/sticky-sidebar

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/33be12f3-2840-132a-4dd8-e49638a5b8fe.png)

# 使い方

## GitHubからダウンロード

赤枠部分をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/696dec02-aa25-2c22-ae28-731035601b55.png)

## パスを確認

ダウンロードしてきたファイルのパスを確認してください。

こちら、```**your_path_to**/sticky-sidebar/dist/jquery.sticky-sidebar.min.js```

## HTML

1. jQueryライブラリを読み込み
2. sticky-sidebarのライブラリを読み込み
3. classを付与（ main-content / sidebar / sidebar__inner / content ）
4. jQuery にてstickySidebarを適用
5. 分かりやすくするためにCSSを追加
6. 

```html:sticky-sidebar.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Sticky-Sidebar</title>

    <!-- 5. 分かりやすくするためにCSSを追加 -->
    <style type="text/css">
      .container {
        height: 2000px;
        width: 1500px;
      }
      .top-content {
        height: 150px;
        width: 1500px;
        background-color: green;
      }
      .main-content {
        height: 2000px;
      }
      .inner_content {
        height: 200px;
        width: 500px;
        float: left;
        background-color: red;
      }
      .content {
        height: 1200px;
        width: 1000px;
        float: right;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="top-content"></div>

      <!-- 3. classを付与（ main-content / sidebar / sidebar__inner / content ） -->
      <div class="main-content">
        <div class="sidebar">
          <div class="sidebar__inner">
            <div class="inner_content">

            </div>
          </div>
        </div>

        <div class="content">
          <!-- Content goes here -->
        </div>
      </div>
    </div>

    <!-- 1. jQueryライブラリを読み込み -->
    <script type="text/javascript" src="jquery-3.5.1.min.js"></script>
    <!-- 2. sticky-sidebarライブラリを読み込み -->
    <script type="text/javascript" src="jquery.sticky-sidebar.min.js"></script>

    <!-- 4. jQuery にて、stickySidebarを適用 -->
    <script type="text/javascript">
      $('.sidebar').stickySidebar({
        topSpacing: 150,
        bottomSpacing: 0,
        containerSelector: '.main-content',
        innerWrapperSelector: '.sidebar__inner'
      });
    </script>
  </body>
</html>

```


# まとめ

めちゃ使いやすいライブラリですので、是非使ってみてください。

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
【UiPath】バージョンアップ時のhoge.IsNullOrEmptyエラー

RPA開発ベンダーが開発していたUiPathロボットのバージョンアップ作業(v18.1⇒v19.10)をしていたところ、**hoge.IsNullOrEmpty**が認識できないというエラーが多発。。
![エラーイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101698/762b3f48-4e0e-16aa-9d82-2952d8bb85bf.png)


### 何故このようなエラーが発生したか
そもそも、.netの記述として[**String.IsNullOrEmpty(hoge)**](https://docs.microsoft.com/ja-jp/dotnet/api/system.string.isnullorempty?view=netcore-3.1)が正しいはずなのに、何でこんな記述が出来たのか…？また、バージョンアップ後では出来なくなったのか？

結論から言うと、UiPath(v18.1)時点ではStudioへStringの拡張メソッドとしてIsNullOrEmptyメソッドを提供しているようだった。また、v18.2⇒v18.3でUiPathのCore部分に大規模な改修が入っており、恐らくそのタイミングでinternalメソッドへと変更されているようでした。（不具合だった？）

以下はUiPath Studioを逆コンパイルしたソースの中身。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101698/19fe54b9-1952-da53-3d53-2daad3f3f2eb.png)



### 対応方法
.net公式として**String.IsNullOrEmpty(hoge)**が正しい為、v18.2以前でhoge.IsNullOrEmptyを利用している箇所は一律修正が必要です。また、同様に**hoge.IsNullOrWhiteSpace**でエラーが発生する可能性もあるが、こちらも**String.IsNullOrWhiteSpace(hoge)**へ修正掛ければOK！
【プログラミング初心者】Swift基礎~デリゲート~

#はじめに
今回は**デリゲート**と呼ばれるプログラミングの手法について紹介します。
プロトコルを使った実装になるのでプロトコルがわからない方は[こちら](https://qiita.com/euJcIKfcqwnzDui/items/b7ad792b3b0a70bae124)をまず参照してください。

デリゲートはiOSアプリでよく出てきます。
例えば`UITableView`や`UICollectionView`などです。
よく出るがゆえに避けては通れないので内部ではどんな実装になっているのか想像できるようにはしておきたいですね。

#デリゲート(Delegate)
##デリゲートとは
**デリゲート**はSwiftの文法ではなく、プログラミングの手法の１つです。
つまり、こんな感じでクラスを作ると便利ですよというようなクラス作成のパターンです。
このようなパターンのことを**デザインパターン**などと言ったりします。

デリゲート(Delegate)には「委譲する」、「任せる」というがあります。
あるオブジェクトの処理を他のオブジェクトに任せる目的で使います。

デリゲートには「処理を任せる」オブジェクトと「処理を任される」オブジェクトが出てきます。

「処理を任せる」オブジェクトにボタンがあったとします。
そのボタンをタップしたとき何らかの処理を行ないますが、その具体的な処理は「処理を任される」オブジェクトに任せるます。
「処理を任される」オブジェクトから見るとボタンが押されたとき「処理を任せる」オブジェクトからボタンが押されたという通知が来るようなイメージです。

言葉で説明するとこんな感じの手法ですが、実際の実装方法を見たほうがわかるかもしれません。
とはいっても以前説明した[プロトコルを使った実装例](https://qiita.com/euJcIKfcqwnzDui/items/b7ad792b3b0a70bae124#%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E5%AE%9A%E7%BE%A9)とあまり実装の違いはありません。

##デリゲートの実装
あるボタンクラスがあり、そのボタンが押されたら何かしらの処理をするというように実装していきます。

###デリゲートを定義する
デリゲートはプロトコルで定義します。

```swift:ButtonDelegate.swift
protocol ButtonDelegate {
    func didTapBotton()
}
```
ボタンオブジェクトがタップされたら`didTapBotton()`が呼び出されるという想定です。
デリゲートには委譲する処理を定義していきます。

###「処理を任せる」オブジェクトを作成する
今回の場合ボタンクラスが「処理を任せる」オブジェクトになります。
以下のような実装となります。

```Button.swift
class Button {
    var delegate: ButtonDelegate? = nil
    
    func onTapButton() {
        print("ボタンがタップされました")
        print("処理を委譲します")
        
        delegate?.didTapBotton()
    }
}
```
ボタンが押されると`onTapButton()`が実行されるとします。
`onTapButton()`で何らかの処理を行った後`ButtonDelegate`の`didTapBotton()`を呼び出します。
これで委譲する準備は完了です。

`ButtonDelegate`はプロトコルなので具体的なクラスは気にしません。
とりあえずボタンが押されたら`didTapBotton()`を呼び出してあげるから、あとは好きな処理をしといてー
というようなイメージです。

###「処理を任される」オブジェクトを実装する
「処理を任される」オブジェクトは画面クラスやその他テキトーなクラスなど何でも構いません。
`ButtonDelegate`を継承しているだけでいいのです。

```swift:Hoge.swift
class Hoge: ButtonDelegate {
    func didTapBotton() {
        print("Hogeに処理が委譲されました")
    }
}
```
委譲されるクラスの実装はこれだけです。
ボタンがタップされたら`didTapBotton()`が呼び出されるのでここに好きな処理を書きます。

###実行する
これでデリゲートの実装ができました。
それでは実際に使ってみましょう。

```swift
let button = Button()
let hoge = Hoge()

button.delegate = hoge // delegateに委譲先のオブジェクトをセットする

button.onTapButton() // ボタンがタップされたと想定
```
```:実行結果
ボタンがタップされました
処理を委譲します
Hogeに処理が委譲されました
```
`button.delegate = hoge`で委譲元オブジェクトのデリゲートに委譲先オブジェクトを設定し紐付けしています。

このようにしてデリゲートで処理を委譲します。

#最後に
今回はデリゲートの実装方法を紹介しました。
基本的にプロトコルの実装とあまり変わらないのではないでしょうか？

冒頭で言ったようにiOSでは`UICollectionView`などでよくデリゲートが使われています。
(DataSourceもありますがこれもデリゲートと似たようなものです)

`UICollectionView`のデリゲートはよく画面クラスで継承しますが、内部ではこのようにして処理を通知するような実装がされています。

自分で実装するのはまだ難しいかも知れませんが内部の処理を想像できる程度に理解できていればいいかなと思います。

今回の内容は以上です。
本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載は以下にまとめていますのでそちらも是非もご覧ください。
http://naoyalog.com/
Rails6で lib ディレクトリの自作クラスを使用する


自作クラスを作成し利用する方法、
今回はroot/lib配下に作る方法をご紹介します。


###環境
rails 6.0.3

###application.rbの設定

```application.rb
module Myapp
  class Application < Rails::Application
    config.load_defaults 6.0
    config.paths.add 'lib', eager_load: true #これを追加
  end
end
```
lib配下をautoload_pathsに追加します。
autoload_pathsについては[こちら](https://qiita.com/hirokisoccer/items/4ba62a56b18eb834a8ee)

### lib配下の構成
```
lib
 ├── assets
 ├── asks
 └── utils
     └── hoge.rb
```

utils/hoge.rbを作成しまいした。
分かりやすい命名にしましょう。

### hoge.rbの中身

```hoge.rb
class Utils::Hoge
end
```
もしくは

```hoge.rb
module Utils
  class Hoge
     def greeting
         'hello'
     end
  end
end
```

親ディレクトリの名称をネームスペースとして、クラスを定義しましょう。
こうすることでautoload_pathsの規則に乗っ取って以下のように呼び出せます。

```application_controller.rb

class ApplicationController < ActionController::Base
   hoge = Utils::Hoge.new
   hoge.greeting
   #=> hello  
end

```

###最後に
この記事を書いてる際以下のような投稿を発見しました。
（リサーチ不足が露呈した、、、）

[autoload_pathsを修正して謎エラーをなくした話](https://qiita.com/fursich/items/8a4c67d7e73830d7d5f7)

Rails Guaidによると
「Rails5より前ではlib/以下をautoload_pathsに含めることがよく行われていたが、現在はappフォルダ以外の場所にコードを置いてautoload対象にするのは勧めない」となっています。
本番環境特有のエラーが発生するかもしれないとのこと。

app配下はautoload_pathsにデフォルトで入っているので、
そちらを使うのが良さそう。

じゃあなんでlibディレクトリは存在してるんだ？
開発上手な人はうまく使い分けているのかな。

新たな疑問が生まれたところで、今回は以上です。
日々精進
ゼロから始めるLeetCode Day67 「1486. XOR Operation in an Array」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day66「438. Find All Anagrams in a String」](https://qiita.com/KueharX/items/dfa635edc45a4e7dc978)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！

# 問題
[1486. XOR Operation in an Array](https://leetcode.com/problems/xor-operation-in-an-array/)

問題としては、整数 n と整数 start が与えられます。

`nums[i] = start + 2*i (0-indexed)` で `n == nums.length`の配列 `nums` を定義します。

`nums`の全要素のビット単位の`XOR`を返します。


# 解法


```python
class Solution:
    def xorOperation(self, n: int, start: int) -> int:
        ans = 0
        for i in range(n):
            ans ^= start + 2 * i
        return ans
# Runtime: 24 ms, faster than 95.07% of Python3 online submissions for XOR Operation in an Array.
# Memory Usage: 13.9 MB, less than 100.00% of Python3 online submissions for XOR Operation in an Array.
```


```python
class Solution:
    def xorOperation(self, n: int, start: int) -> int:
        i = ans = 0
        while i<n:
            val = start + 2*i
            ans ^= val
            i+=1
        return ans
# Runtime: 24 ms, faster than 95.07% of Python3 online submissions for XOR Operation in an Array.
# Memory Usage: 13.9 MB, less than 100.00% of Python3 online submissions for XOR Operation in an Array.
```


どっちでもやっていることは変わりませんし、正直にいうと簡単な内容でしたが速い解答が出たので記事を書いてみました。

正直最初にみた時に解説にほとんど書いてあるので変に勘ぐって色々回り道をしましたが、最終的には解けました。

解いたことにない初心者にイメージを掴んでもらうにはおすすめの問題です！

では今回はここまで。お疲れ様でした。
【R8/ProGuard】マージ後のProGuardルールファイルを確認する方法

[ライブラリ モジュールの開発に関する考慮事項](https://developer.android.com/studio/projects/android-library?hl=ja#Considerations) の **ライブラリ モジュールには独自の ProGuard 構成ファイルを含めることができる** に記載がある通り、ライブラリ側がProGuardルールファイルを内包している場合があります。（ `consumerProguardFiles` ）

そういうライブラリを使っている場合、最終的に生成されるProGuardルールファイルは、それぞれのProGuardルールファイルがマージされたものになります。

今回は、そのマージされたProGuardルールファイルを確認する方法を記載します。

# `printconfiguration` を使う:bulb:

方法は簡単で、アプリ側で使っている `proguard-rules.pro` に

```
-printconfiguration proguard-rules-full.pro
```

と記述し、 `minifyEnabled true` な状態でビルドすると `proguard-rules-full.pro` というファイル名で出力することができます。

参考：https://developer.android.com/studio/build/shrink-code?hl=ja#configuration-files

# （おまけ）メンテナンスがしやすい:wrench:
出力されたProGuardルールファイルは、単純に各ProGuardルールファイルを結合しただけのようでした。

そのため、例えばあるライブラリを使っていて、そのライブラリのルールをアプリ側に記述していたが、実はライブラリが内包しているProGuardルールファイルにそもそも記述されているので不要、といったこともわかるため、ProGuardルールファイルのメンテナンスがしやすいです。
（ProGuardルールファイルは一度書くと、なかなか変更などしないですよね。:innocent:）

## 例えば「Glide」の場合

画像ライブラリで有名なGlideですが、GitHubのREADMEに [ProGuard](https://github.com/bumptech/glide/blob/85868bdb31b393e85c8c97c1465f13d47872d7ab/README.md#proguard) の記述があるため、特に調べることなく、アプリ側のProGuardルールファイルにルールをコピペしがちです。

しかしながら、 build.gradleを見てみると[consumerProguardFiles](https://github.com/bumptech/glide/blob/85868bdb31b393e85c8c97c1465f13d47872d7ab/library/build.gradle#L42) の記述があり、 [proguard-rules.txt](https://github.com/bumptech/glide/blob/85868bdb31b393e85c8c97c1465f13d47872d7ab/library/proguard-rules.txt) を覗いていると、READMEに書かれているルールとほぼ同じもの [^1] が書かれているため、アプリ側のProGuardルールファイルにルールを書く必要がないことがわかったりしました。

[^1]: 正確には `for DexGuard only` のところがコメントアウトされていました。
Firebase Storage から getDownloadURL を使わずに(少し早く)ダウンロードする

Firebase Storage でパーマネントリンクを発行する方法を紹介します。

# Firebase Storage とセキュリティルール

Firebase Storage は大容量のデータを保存することのできるストレージです。画像ファイルや、比較的大きな (例えば数 MB もあるような) JSOM などを保存したい場合は、Firestore ではなく Firebase Storage を使うと思います。

Firebase Storage のサンプルコードを読むと、 `getDownloadURL` というメソッドが登場します。

```javascript
const ref = firebase.storage().ref('images/stars.jpg'); // 1. 準備
const url = await ref.getDownloadURL(); // 2. ダウンロード URL を取得する
const response = await fetch(url);      // 3. URL からダウンロードして、レスポンスを得る
const image = await response.blob();    // 4. レスポンスからバイナリを得る
```
上記は公式サンプルコードではなく、オリジナルです。

`2. ダウンロード URL を取得する` の箇所で `getDownloadURL` が使われています。ここで注目して欲しいのは、この関数の戻り値が非同期であることです。ただ URL を得るだけの関数がなぜ非同期なのかというと、この操作が実際には "秘密の URL を取得するために Google のサーバで認証を行っている" からです。

ここでいう認証とは、 `storage.rules` ファイルによって定義されたセキュリティルールに合致するかどうかの判定です。このファイルは Firebase プロジェクトを作ったときに作られているかも知れませんが、なければウェブ上のダッシュボードからも読み書きできます。

さて、この認証は場合によっては "お節介" かも知れません。僕の手元では 500ms-700ms ほどの時間がかかっていますが、ネットワークが遅い場合はもっとかかることもあるでしょう。とにかくダウンロード時間を短縮したい場合 (ユーザーを待たせたくない場合)、この操作をスキップすることができます。

ただし、 **この操作はバケット全体に影響を与えます。** 認証をスキップするということは、誰もがストレージオブジェクトをダウンロード可能になってしまうということです。それでも問題ない場合は、以下の手順を試す価値があります。あるいは、新しいバケットを作って、ダウンロードされて大丈夫なものだけをまとめることもできます。いずれにせよ、ダウンロードされて困るものがひとつでもバケットに入っている場合は、この方法を使うべきではありません。

ファイルごとにパーマネントリンクを発行したい場合は firebase-admin の Storage オブジェクトから利用可能な [getSignedUrl](https://googleapis.dev/nodejs/storage/latest/Bucket.html#getSignedUrl) に目一杯長い期間を設定します。詳細は割愛します。


# Firebase Storage バケットを公開する

デフォルトでは、 Firebase Storage のダウンロード URL はすべて "秘密の URL" です。これがどこで決められているかというと、 IAM で決められています。

IAM を変更するには、ブラウザで [ストレージブラウザ](https://console.cloud.google.com/storage/browser) を開いて、 Firebase プロジェクトと同じ名前のプロジェクトを選択したら、一覧から `(Firebase のプロジェクト名).appspot.com` という名前のバケットを開いてください。(おそらく出てくると思いますが、Firebase 側で設定が必要かも知れません)

ストレージブラウザでは "Google Cloud Storage" と呼ばれていますが、これは "Firebase Storage" のことだと読み替えてください。

権限タブに移動すると、IAM を表示したり変更したりできます。メンバー追加をクリックして、 `allUsers` に対して `Storage レガシーバケット閲覧者` ロールを設定してください。このロールは標準で存在する中では唯一 `storage.objects.get` 権限だけを含んでいます。権限については[公式のドキュメント](https://cloud.google.com/storage/docs/access-control/iam-roles)に詳しい説明があります。

> ↑こちらの説明は間違っており、正しくは `Storage レガシー オブジェクト読み取り` でした。


[![Image from Gyazo](https://i.gyazo.com/2d483b4335688bd1bb3ab1fc0f11850e.png)](https://gyazo.com/2d483b4335688bd1bb3ab1fc0f11850e)

保存ボタンを押すと、バケットが誰からもダウンロード可能になります。試しに、適当なオブジェクトをダウンロードしてみましょう。 `インターネットに公開 🔗` というボタンをクリックすると、パーマネントリンクを開いてくれます。(オブジェクトのヘッダによっては直接ダウンロードされることもあります)

[![Image from Gyazo](https://i.gyazo.com/24cacaf30b11ba80bffa371a62ea5ede.png)](https://gyazo.com/24cacaf30b11ba80bffa371a62ea5ede)

パーマネントリンクは `https://storage.googleapis.com/(Firebase プロジェクトの名前)/(オブジェクトのパス)` という URL になっています。この URL を `fetch()` なりすれば、 `getDownloadURL` を使わずにダウンロードすることができます。
OperationalError: (psycopg2.OperationalError)でエラーが出た

# はじめに

flaskのアプリをpsycopg2で動かしていたら下のようなエラーが出た。

```
OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
```

# 解決方法

```python
from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy

class SQLAlchemy(_BaseSQLAlchemy):
    def apply_pool_defaults(self, app, options):
        super(SQLAlchemy, self).apply_pool_defaults(self, app, options)
        options["pool_pre_ping"] = True

db = SQLAlchemy(app)
```
上のプログラムを入れると解決しました。下の参考URLには他の解決方法も載っていたりするので英語が得意だったら見てみてください。


参考URL

https://stackoverflow.com/questions/55457069/how-to-fix-operationalerror-psycopg2-operationalerror-server-closed-the-conn

https://github.com/pallets/flask-sqlalchemy/issues/589#issuecomment-361075700
Typechoインストール（Docker）

# Typechoインストール（Docker）

![image-20200625004519989](https://i.loli.net/2020/06/24/Qr7ELmGHD8ycS1f.png)

> インストール環境

* Linux（CentOS 7.7）

* Docker

  ※docker-composerがインストール済み
　　docker-networkが作成済み


> インストール手順

1、ディレクトリを作成

```bash
mkdir -p /home/typecho/data  
mkdir -p /home/typecho/mysql
```

2、typechoディレクトリに入って，Docker-compose.ymlファイルを作成し、下記の内容を記入する。

```bash
version: "3"

services:
  typecho:
    container_name: typecho
    restart: always
    image: 80x86/typecho:latest
    ports:
      - 8002:80  #ポート8002は適当に変更する。
    volumes:
      - /home/typecho/data:/data
      - /home/typecho/mysql:/var/lib/mysql
networks:
  default:
    external:
      name: docker-network #网络名根据实际情况填写

```

3、コンテナーの生成して起動する。

```bash
docker-compose up -d
```

4、Mysqlのインストール

```bash
docker exec -it typecho sh #コンテナーに入る
apk add mysql mysql-client #Mysql(MariaDB)をインストール
mysql_install_db --user=mysql --datadir=/var/lib/mysql #Mysqlを初期化
mysqld_safe &
mysql_secure_installation #パスワード設定後、全部「y」を選択して設定する。
mysql -u root -p #DBログイン
create database typecho; #データベース作成
```


5、Nginxにプロキシ設定が必要であれば、下記の内容をNginxの設定ファイルに設定する。

```bash
location / {
        proxy_pass http://typecho;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host      $http_host;
}

```

6、下記のURLをウェブブラウザに入力してTypechoの設定画面に遷移する。

http://ip
[Heroku] Enable Review Apps で Item could not be created エラーの解決方法

# 概要
Heroku で　Enable Review Apps で Item could not be created というエラーが発生したときの解決方法をご紹介します。

```
Item could not be created: Invalid request. #: failed schema #/definitions/review-app-config/links/0/schema: "repo" wasn't supplied.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4798/81c22e0a-2173-15f0-ec64-05c6dd19e870.png)

# Item could not be created の解決方法

Item could not be created エラーの原因は、Heroku App と GitHub の連携はしていたのですが、Heroku Pipeline と GitHub の連携設定が未だだったためでした。

以上、Heroku で Enable Review Apps ができなくて戸惑った、現場からお送りしました。
初心者によるプログラミング学習ログ 354日目

#100日チャレンジの354日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
354日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日の作業・やったこと⇩<br>●ブログ1記事作成<br>●プログラミング学習354日目　2.0h<br>・架空LP タブレット版作成(<a href="https://twitter.com/ririru_123?ref_src=twsrc%5Etfw">@ririru_123</a> ) 1.0h<br>・udemyでフロントエンド講座 1.0h<br><br>今度は夜に報告するね<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@社畜✕投資✕ブロガー (@ppmp65) <a href="https://twitter.com/ppmp65/status/1276156857242062853?ref_src=twsrc%5Etfw">June 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
チェックボックス・ラジオボタンCSSライブラリ pretty checkbox

# はじめに

チェックボックス・ラジオボタンのCSSライブラリ __pretty checkbox__ について紹介したいと思います。
Qiita内を検索してみましたが、pretty checkbox の記事がなかったので、どなたかの参考になればなーと思います。

classを設定するだけで適用できるので、Javascriptのライブラリよりもお手軽で、個人的には超お気に入りです。

【サンプル】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/42f93fe6-55e9-aec8-0fcf-3967f43c3067.png)

詳細については公式ドキュメントにて触ってみてください。

* pretty checkbox 公式
    * https://lokesh-coder.github.io/pretty-checkbox/


# 使い方

CSSを以下からダウンロードし、HTMLにて読み込みをしてください。
https://cdn.jsdelivr.net/npm/pretty-checkbox@3.0/dist/pretty-checkbox.min.css

```html:pretty-checkbox.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pretty-checkbox@3.0/dist/pretty-checkbox.min.css">
    <title>Pretty Checkbox</title>
  </head>
  <body>
    <!-- ここにサンプルを載せていきます！ -->
  </body>
</html>

```



# まとめ

いかがでしょうか。
classを付与するだけでAnimationを適用できるなど、手軽にキレイなUIを実装できますので是非使ってみてください！

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
DeepRunning　～Level3.3～

#Level３．応用数学③
##3-3.情報理論

##・学習の目標
　　(1)自己情報量・シャノンエントロピーの定義を確認する。
　　(2)ＫＬダイバージェンス・交差エントロピーの概要を知る。

###3-3-1.自己情報量
　・対数の底が2のとき、単位はビット（bit）
　・対数の底がネイピアの $e$ のとき、単位はナット（nat）
　　※natsとbitsでかじるものとかじられるもの。
　・自己情報量：工学的、モールス信号では「どのくらい少ない情報で送れるか」と考えられた。
　・情報の分かり易さを“比率”で把握している。
　　⇒10gの重さの違いが分かる人でも、10kgの物の上に10gを乗せても気が付かない。

```math
I(x)= -log(P(x)) = log(W(x))
```
　・$x$は、いろいろなイベント
　・$W=\frac{1}{P}$と表せる。
　　logは逆数にすると符号が逆転する。（－をつける）
　・$log(W(x))$で、底は$e$が省略されている。（底の変換）

　（例）
　　情報の量によって用意するスイッチの数は、$log$を取ればわかる。
　　　1～2個の情報：　スイッチ1個（=$log_{2}2$）
　　　1～4個の情報：　スイッチ2個（=$log_{2}4$）
　　　1～8個の情報：　スイッチ3個（=$log_{2}8$）

###3-3-2.シャノンエントロピー
　・微分エントロピーともいうが、微分しているわけじゃない。
　・自己情報量の期待値

```math
\begin{align}
H(x)&= E(I(x))\\
&= -E(log\:(P(x)))\\
&= -\sum(P(x)\:log(P(x)))
\end{align}
```
　　　　　　　　　　　　　　　　⇒　（確率　×　確率変数）の合計（＝期待値）

###3-3-3.カルバック・ライブラー　ダイバージェンス
　・同じ事象・確率変数における異なる確率分布$P,Q$の違いを表す。
　　⇒コインを投げる。確率分布は$\frac{1}{2}$だが、イカサマのコインで確率が違うことが後で分かった等。
　　　どれだけ違う分布だったのかを調べる。
　・相対エントロピー
　

```math
\begin{align}
D_{KL}(P||Q)&= E_{X～P}\begin{bmatrix}log \frac{P(x)}{Q(x)}\end{bmatrix}\\
&=E_{X～P}\begin{bmatrix}log P(x) - log Q(x)\end{bmatrix}
\end{align}
```
　・D:ダイバージェンス、KL：カルバック・ライブラー
　・$(P||Q)$は、この2つの差を見たいという意味。

```math
\begin{align}
I(Q(x))-I(P(x))&= (-log(Q(x))) - (-log(P(x)))\\
&=log\frac{P(x)}{Q(x)}\\
\end{align}
```
    
```math
E(f(x))= \sum_{x}P(x)f(x)
```
    
```math
\begin{align}
D_{KL}(P||Q)&= \sum_{x}P(x)(-log(Q(x))) - (log(P(x)))\\
&=\sum_{x}P(x)log\frac{P(x)}{Q(x)}
\end{align}
```
　　　⇒シャノンエントロピーと似ているのでは？？
　　　　$D_{KL}(P||Q)とD_{KL}(Q||P)$は異なる値となる。
　　　　そのため、2つの差を距離としては扱えない。

###3-3-4.交差エントロピー
　・KLダイバージェンスの一部分を取り出したもの。
　・$Q$についての自己情報量を$P$の分布で平均している。
　・事前に暗号化した表を用意しておくなどのデータ圧縮もある。
　・機械学習及び最適化における損失関数の定義に使う。
　　（ロジスティック回帰モデルなど）

```math
\begin{align}
H(P,Q)&= H(P) + D_{KL}(P||Q)\\
H(P,Q)&= -E_{X～P}\;\;log\;Q(x)\\
&= -\sum_{x}P(x)\:log\:Q(x)
\end{align}
```
　・同じ事象・確率変数における異なる確率分布$P,Q$の違いを表す。
Postgresでシーケンス作成

##はじめに
テーブル作成の際にシーケンスを使用・テスト時にエラーが発生し解消したので
今後のために書き留めておく。

##シーケンスとは
>シークエンス（sequence）、シークエンシング（sequencing）は、一般には「連続」「順序」という意味を持つ。シークェンス、シーケンスとも。

[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%AF%E3%82%A8%E3%83%B3%E3%82%B9)

テーブルでデータを一意に特定するために使用します。

##作成方法

以下のコマンドで作成出来ます。

```sql

CREATE SEQUENCE seq_no
 START WITH     1
 INCREMENT BY   1
 MAXVALUE 100
 NOCYCLE;
```
seq_noという名前のシーケンスを作成します。

`START WITH`：順序番号の初期値です。

`INCREMENT BY`：インクリメントする値を設定します。
　　　　　　　　　例えば2にすると「1, 3, 5, 7 ...」という感じにインクリメントされます。

`MAXVALUE`：順序の最大値を指定します。

`NOCYCLE`：順序が最大値または最小値に達した場合は、それ以上値を生成しないように指定できます。

他にもMINVALUEなど様々な指定が出来ます。

以下のページを参考にしました。
[Oracle® Database SQL言語リファレンス](https://docs.oracle.com/cd/E16338_01/server.112/b56299/statements_6015.htm)

##シーケンスがずれてしまった

無事にシーケンスも作成し、テスト環境で動作も確認し安心していたところ
次の日に以下のエラーが発生。

```
duplicate key value violates unique constraint
```

コードも確認して、シーケンスも問題ない、なぜ、、、

テーブルのレコードを確認してみると追加した覚えのないレコードがたくさん。
原因は他のメンバーが該当テーブルにてデータをコピーしていたため
シーケンスがずれてしまったようです。

以下の手順で修正

次の採番値を確認

```sql

SELECT nextval('テーブル名_シーケンス名_seq');
```

次の採番値をテーブルのデータに合わせる

```sql

SELECT setval('テーブル名_シーケンス名_seq', (SELECT MAX(シーケンス名) FROM テーブル名));
```

以上。
Amazon Honeycodeとは何か

つい先日リリースされたHoneycodeについて勉強中のフクリンゴ([@fukulingo](https://twitter.com/fukulingo))です。

HoneycodeはAmazonがリリースした、いわゆるNoCodeなサービスです。
エクセル的なUIで、コードを書かないことにこだわっているサービスですね。
触ってみた感じ、けっこう初見殺しなところはあります。

以下は、Honeycodeコミュニティに投稿されたWhat is Honeycodeの記事の翻訳です。

## Welcome to Honeycode!
Honeycodeは、チームが仕事を思い通りに進めるために、モバイルアプリやウェブアプリの構築を支援します。
Honeycodeでアプリを構築するのに**プログラミングのスキルは必要ありません**。

- ビジュアルビルダーを使ってアプリを作る
- テーブルでデータを管理する
- 自動化を利用して手動のステップを置き換える

プロジェクト管理、オペレーション、顧客パイプライン、リソース追跡、承認ワークフローなどのユースケースにHoneycodeが使えます。

作成したアプリは、10人規模のチームでも、組織全体で数百人規模でも使用することができます。

## Honeycodeのメリット
ブラウザ、iOS、Androidで動作するWeb・モバイルアプリを構築します。
プログラミングは不要なので、誰でもアプリを作成することができます。

Honeycodeのアプリは、チームが状況を把握するのに役立ちます。
なぜなら、すべてのチームメンバーがアプリのデータにアクセスでき、リアルタイムで更新されるからです。

Honeycodeアプリは、各チームメンバーに関連するデータをパーソナライズして表示することができます。

Honeycodeを使えば、手動で行うステップを自動化することができます。
更新情報をメンバーに通知したり、リマインダーをかけることができます。

## なぜHoneycodeを使うのか？
多くの人がスプレッドシートを使ってプロジェクトを管理しています。
スプレッドシートはチームでの共同作業のために設計されてないので、面倒な部分がありエラーが発生しやすいです。

チームのプロジェクトに特化したアプリがあったらどうでしょう？
残念ながら、アプリの作成にはプログラミングスキルやリソースが必要です。

Honeycodeを使えば、その必要なく自分だけのアプリを作ることができます。
Honeycodeは、フロントエンドのコンポーネントやアプリのクライアントからバックエンドのデータストレージまで、必要なものをすべて提供します。

これらすべてが、使いやすいビジュアルベースのインターフェースによって操作することができます。


## 本文で出てきた用語の解説

### Honeycode Tables(テーブル)
スプレッドシートのように見えるが、データベースのように動作する。
Honeycodeのテーブルは、リレーショナルデータベースのように振舞う。

### Honeycode Builder(ビルダー)
Builderでは、アプリのレイアウトや外観をカスタマイズが可能。
表示したいデータをリンクして、アプリをすぐに動かすことができる。

### Honeycode Automations(自動化)
ワークフローとビジネスプロセスを自動化できる。
自動化したいアクションを選択し、そのトリガーとなる条件を設定する。

## 翻訳してみての感想
Amazon Honeycodeは非開発者をかなり意識している感じがします。
スプレッドシートを普段使っているような人に向けて、テーブルUIを中心にしているのが特徴的ですね。
まだまだ情報は少なく英語のみの提供なので学習コストも高めですが、これからHoneycodeの情報をどんどん発信していきたいと思います。
docker : Data Volumeの作成から削除まで

# Data Volumeとは
Dockerにおいてデータの永続化は気にしなかればならない問題です。
そこで使われるのが、Data Volumeです。Data VolumeはDockerコンテナ-ホスト間で直接ディレクトリを共有することで、データ永続化を実現する仕組みです。Data Volumeはコンテナを破棄してもホスト側に保持されることになります。

コンテナのデータ永続化手法としては、Data Volumeコンテナの手法が推奨されています。
こちらでは、コンテナ間でディレクトリを共有することになります。Data Volumeコンテナは、データのみを保持するためのコンテナで、ホスト側に保持された永続化データの一部をVolumeとして別のコンテナに共有できるようにしたものです。

Data VolumeコンテナのVolumeは、ホスト側の`/var/lib/docker/volumes/`（管理領域）以下に配置されます。

## ボリューム作成

```bash
$ docker volume create --name <VOLUME NAME>
```

## 一覧表示

```bash
$ docker volume ls
DRIVER              VOLUME NAME
local               0a990e22051c0815c18cb10ae5eea84ce37db2e91e83c3e976d54646c466c249
...<omitted>...
local               mysql-data
```

## マウント

```bash
$ docker run [options] -v {Host directory}:{Container directory} <Repository>[:tag] [Command] [Arguments]

# 例）
$ docker run -d --name mysql -p 3306:3306 -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql
```


## 削除

```bash
$ docker volume rm <VOLUME NAME>
```

## 全て削除

```bash
$ docker volume rm $(docker volume ls -qf dangling=true)
```

## リンク切れのみ削除

```bash
$ docker volume ls -qf dangling=true | xargs -r docker volume rm
```

- `[Command A] | xargs [Command B]` : コマンドAの実行結果を引数にしてコマンドBを実行
- `-r` option : 標準入力(引き数）が空の場合はコマンドBを実行しない

## データのエクスポート

Data Volumeコンテナで利用しているデータを他のコンテナで利用したい場合、一度データをエクスポートしたいとなるはずです。
Volumeデータをホスト側にエクスポートする方法を記載します。

```bash
$ docker container run -v $PWD:/tmp \
  --volumes-from mysql-data \
  busybox \
  tar cvzf /tmp/mysql-backup.tar.gz /var/lib/mysql
```

上記例では、以下のようなイメージです。

- mysql-data(Data volumeコンテナ)の`/var/lib/mysql`の中身をtar圧縮
- 圧縮したファイルをbusyboxコンテナの`/tmp`以下に`mysql-backup.tar.gz`として保存
- busyboxコンテナの`/tmp`をHost側のカレントディレクトリにマウント

![data_volume_export.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650551/25c256a3-7e62-b81d-6c60-0284751bebb8.png)
expoを使う最初の環境構築

####実施環境
- Mac Mojave使用
- vscode使用
- node.jsインストール済み

##はじめに
https://expo.io にアクセス
[Get Start]ボタンで始める

##00 Sign in
ページ右上の[Sign in]ボタンよりユーザ名、メールアドレス、パスワードを入力

##01 Fall in Love
[Try Snack]ボタンを押下するとチュートリアル画面が表示される
右側がシュミレーターになっているので実装内容が確認できる
試しに15行目の「Change code〜」の文を変更してみると、右のシュミレーター画面も変わっていることが確認できる

##02 Download NodeJS
NodeJSをインストールします
今回は導入済みの想定なのでスキップします

##03 Get the command line tool
`$npm install expo-cli --global`
：expo-cliをインストール
 React Nativeのプロジェクト作成・ビルド・デプロイが簡単にできるようになります

`$expo --version`
:expoのバージョンを確認
下記のようにバージョンが表示されていればインストール完了です

```
$ expo --version
3.21.10
```
ログインが完了したら
`$expo login`
:expoにログインする
ナビ通りにUsernameかEmail AddressとPasswordを入力する
下記のように表示されればOK

```
Success. You are now logged in as ユーザー名.
```

##04 Create your first project
`$expo init myNewProject`
:React Nativeプロジェクトを作成
("myNewProject"の部分は自分のつけたいプロジェクト名に変更してください)

```
? Choose a template: (Use arrow keys)
  ----- Managed workflow -----
❯ blank                 a minimal app as clean as an empty canvas 
  blank (TypeScript)    same as blank but with TypeScript configuration 
  tabs                  several example screens and tabs using react-navigation 
  ----- Bare workflow -----
  minimal               bare and minimal, just the essentials to get you started 
  minimal (TypeScript)  same as minimal but with TypeScript configuration 
```
とテンプレートに関する質問がされます

簡単にexpoのサポートを受けながら開発したい場合は`Managed workflow`を選択
*`blank`画面がまっさら(blank)な状態からスタート
*`tabs`いくつか画面にタブがある状態からスタート
今回は`Managed workflow`の`blank`を使用とEnterキーを押すと必要なもののインストールが始まります

インストールが完了したら
`$cd myNewProject`

`$expo start`
:実行

左下にQRコードの表示されたブラウザが起動すればOK
<img width="906" alt="スクリーンショット 2020-06-25 22.37.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594379/2c22c89e-2283-a557-9077-602a8ba4af07.png">
FreeBSD12.1+apacheでgitサーバ(smart http)

gitレポジトリのサーバを立てるにあたり、プロトコルはsshでいいや、と思っていたのだけど、意外とhttpプロトコルでの設定も簡単にできるとのこと。

* [Gitサーバー - Smart HTTP](https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-Smart-HTTP)

とりあえず、試してみました。

## 環境

* VirtualBox on ubuntu20.04
* FreeBSD 12.1

上記の環境で、インストールしてネットワークが接続できるところまで設定し終わっている事を前提とします。

## 設定

apacheとgitのインストール。

```
pkg install apache24 git
```

apacheの設定。
「`/usr/local/etc/apache24/Include/000-default.conf`」というファイルを作成して、設定します。

```/usr/local/etc/apache24/Include/000-default.conf
<VirtualHost *:80>
    ServerName hoge.example.com

    SetEnv GIT_PROJECT_ROOT /var/html/git
    SetEnv GIT_HTTP_EXPORT_ALL
    ScriptAlias /git /usr/local/libexec/git-core/git-http-backend
    <Location /git>
        AuthName "Git Repository"
        AuthType Basic
        AuthUserFile /usr/local/etc/apache24/git.passwd
        Require valid-user
    </Location>
</VirtualHost>
```

「`/etc/rc.conf`」で、apacheサービスを有効設定にします。

```/etc/rc.conf
apache24_enable="YES"
```

パスワードファイルを作成します。
以下のコマンドを実行すると、パスワードを尋ねられるので、入力します。

```
htpasswd -c /usr/local/etc/apache24/git.passwd katsuko
```

レポジトリを作成します。

```
mkdir -p /var/html/git
git init --bare --shared /var/html/git/project.git
cd /var/html/git/project.git
git update-server-info
chown -R www:www .
```

サービスを起動します。

```
service apache24 start
```

これで、他のクライアントから「`git clone http://katsuko@hoge.example.com/git/project.git`」でクローンができる…と思いきや、

```
fatal: repository 'http://hoge.example.com/git/project.git/' not found
```

とのエラーが。
ふと「`/usr/local/etc/apache24/httpd.conf`」を見てみると、

```/usr/local/etc/apache24/httpd.conf
<IfModule !mpm_prefork_module>
        #LoadModule cgid_module libexec/apache24/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
        #LoadModule cgi_module libexec/apache24/mod_cgi.so
</IfModule>
```

というように、`mod_cgi`がコメントアウトされているので、このコメントを外してやりましょう。
いやー、CGI動かすの久々なんで、ちょっと悩みましたよ。

ちなみに、「`Options ExecCGI`」は要らないのかな、と思ったのだけど、[apacheのマニュアル](https://httpd.apache.org/docs/2.4/ja/howto/cgi.html)によると、必要なのは「`ScriptAlias`」の指定以外でCGIを動かす場合のようです。

---
続き。

* [ubuntu20.04/debian10+apacheでgitサーバ(smart http)](https://qiita.com/katsuko0303/items/289b5da985a149380037)
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～CSS第4の2回～

# アジェンダ
* リストのマーカー
    * ulで指定できるもの
    * olで指定できるもの
* マーカーの位置
* 実践

# リストのマーカー
リストのマーカーを指定する場合、以下のように書く。

```
list-style-type: 値;
```
指定できる値(マーカーの種類)は、ulとolで異なる。

## ulで指定できる単語
<dl>
  <dt>disc</dt>
  <dd>黒い丸</dd>
  <dt>circle</dt>
  <dd>白い丸</dd>
  <dt>square</dt>
  <dd>黒い四角</dd>
</dl>
など。ほかにもさまざまな種類がある。

## olで指定できる単語
<dl>
  <dt>decimal</dt>
  <dd>数字</dd>
  <dt>decimal-leading-zero</dt>
  <dd>0埋めした数字</dd>
  <dt>lower-roman</dt>
  <dd>小文字のローマ数字</dd>
  <dt>lower-alpha</dt>
  <dd>小文字のアルファベット</dd>
</dl>
など。ほかにもさまざまな種類がある。

# マーカーの位置を指定する場合、以下のように書く。

```
list-style-position: 値;
```
値は以下の単語で指定する。
<dl>
  <dt>inside</dt>
  <dd>マーカーをブロックの内側に表示させる。</dd>
  <dt>outside</dt>
  <dd>マーカーをブロックの外側に表示させる。</dd>
</dl>

# 実践
上記の内容を用いて、以下のindex.htmlとstyle.cssを作成した。

```html:index.html
<!DOCTYPE html>

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <link type="text/css" rel="stylesheet" href="./style.css">
    <title>言語</title>
  </head>
  <body>
    <h1>好きな言語</h1>
    <p>
      <ul class="circle">
        <li>Python</li>
        <li>C++</li>
        <li>Java</li>
      </ul>
    </p>
    <h1>学んでみたい言語ランキング</h1>
    <p>
      <ol class="lower-roman outside">
        <li>JavaScript</li>
        <li>Go</li>
        <li>PHP</li>
      </ol>
      <ol class="lower-roman inside">
        <li>JavaScript</li>
        <li>Go</li>
        <li>PHP</li>
      </ol>
    </p>
  </body>
</html>
```

```css:style.css
.outside {
  list-style-position: outside;
}

.inside {
  list-style-position: inside;
}

.circle {
  list-style-type: circle;
}

.lower-roman {
  list-style-type: lower-roman;
}
```
これをWebブラウザに表示させるとこんな感じ。
![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/005f7f17-31b5-9255-3e8c-883974baad2a.png)

注目すべきは下のolの差。
list-style-positionを指定した時、

* outside : リストに書き込む内容の頭位置を揃えている
* inside : リストのマーカーの先頭を揃えている

という違いがある。

# おわりに
今回は、リスト表示の変更方法の内容だった。
マーカーは結構趣味が出そうだと思った。

ちなみに好きな言語と学んでみたい言語は真実です。C++いいね。

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/3f482b0758bded329da7)
## 参考
[4-6 リストの表示方法（CSSの文字とリスト）](https://www.youtube.com/watch?v=-b4hkuSlb78&list=PLjw-30bsJNVVa4PuUseJ5YPN1K2dJr041&index=21)
Docker TypeScript で　React  環境を構築

自分用のmemoのつもりで
Dockerで環境構築
Dockerはinstall済み

■Dockerfile作成
空のPJディレクトリ内にDokerfile作成し以下を記載

```
FROM node:13.5.0-alpine3.11
WORKDIR /usr/src/app
```

FROMは新しいイメージの元となるイメージの読み込み
alpineというのでめちゃくちゃファイルサイズを小さくできるらしい

■docker-compose.yml作成
※ymlは「yaml ain't markup language」の略で構造化データの表現方法
※簡単に言えば設定ファイル

```
version: '3'
services:
  sample:
    build:
      context: .
    tty: true
    environment:
      - NODE_ENV=production
    volumes:
      - ./:/usr/src/app
    command: sh -c "cd tips && yarn start"
    ports:
      - "3000:3000"
```

■イメージをビルド

```
docker-compose build
```

■React と create-react-app をインストール + アプリ作成

```
docker-compose run --rm sample sh -c 'npx create-react-app sample_app --template typescript'
```

出来上がるディレクトリ 構成

```
- Dockerfile
- docker-compose.yml
- アプリ名
    |- node_module
    |- public
    |- src
```

■起動

```
docker-compose up -d
```

※ローカルでyarn startする時よりも時間がかかる感覚はある

Localhost:3000でApp.jsの中身が表示される

■停止

```
docker-compose stop
```
【初学者手順書２】Ruby on Rails ：Railsの雛形作成


[初学者手順書１](https://qiita.com/katlao/items/5e530571703b6cb6ab21)の続きです。
今回は、Railsの雛形を作成していきます。

# Rails雛形作成

Railsアプリケーションを作成
ターミナル上、指定のディレクトリで実行

```
% rails _Ver.指定_ new アプリ名 -d RDBMS名(mysqlなど)
```

ファイルの文字コードの設定(必要な場合)

```yml:config/database.yml
# m4を削除
encoding: utf8
```

データベース作成

```
% rails db:create
```

不要なファイルが作成されないように追記(必要な場合)
rails gでコントローラを作成する場合テストファイルなどを自動で作るため

```rb:config/application.rb
# 省略
module アプリ名
  class Application < Rails::Application
    config.load_defaults 6.0
    config.generators do |g|
      g.stylesheets false
      g.javascripts false
      g.helper false
      g.test_framework false
    end
  end
end
```

GitHubコミットされたくないファイルを記載

```.gitignore:.gitignore
public/uploads/*
```
READMEに、データベース設計やアプリの情報を記載していく。
pip install mysqlclientでハマった際の備忘録

##詳細
`clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'clang' failed with exit status 1`
と怒られてた。

##やったこと
###xcodeのアップデート
->改善せず

##追加のcomponentsのinstall
xcodeを起動した時にpop upが出て、追加のcomponentsをinstallしますか?
と出たもの
->改善せず

##環境変数の追加
`
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
`
->installできました。
パスが通ってなかったことが原因みたい。
参照:[https://teratail.com/questions/214631](https://teratail.com/questions/214631)
Azure App Service static Web Appsがプレビューです。

# Azure App Service Static Web Apps がプレビューされました。
クライアントサイトプログラマーにとっては、よりAzureのサービスが利用しやすい環境となると思います。また、サーバーサイドのプログラマーも、別で環境を準備しなくてもよくなるので、環境としてはよりシンプルになる事が期待できます。

## Full stackのJavaScripterに最適
最近はクライアント側をSPAとして開発し、サーバー側はSPAが必要とする情報を提供するAPIとして構成するというイメージが強くなってきましたが、今回プレビューとして公開されたStatic Web Appsでは、１つの環境でその両方が実現できるものになっているようです。
そして、Azure App Serviceでは、Node.jsを使用したサーバー側の実装も提供できるようになっています。
この場合、エンジニアはJavaScriptがあれば、クライアント/サーバー両方のプログラムを開発する事が出来るので、非常に有利ですね。

## 1つのリポジトリ整合性のとれたCI/CD環境が実現
１つのWebApps で、静的コンテンツからAPIを利用して実現するSPA用のクライアントと、APIを提供するサーバーの両方が提供される環境なので、1つのリポジトリで管理する事ができ、かつCI/CDのpipelineを組むことで、1回で整合性のとれた統合/デプロイが可能となります。
今まで、別々のリポジトリで管理しなければならなかったクライアントコードとサーバーサイドのコードが1リポジトリで管理できるというメリットは大きいです。なぜならそれぞれ別々で管理している場合、整合性が取れなくなる可能性がありましたが、そのリスクが大きく削減できるからです。

詳細は以下のリンクからどうぞ。

https://docs.microsoft.com/ja-jp/azure/static-web-apps/?WT.mc_id=build2020_swa-docs-cxa
SpacemacsでTerraformの自動補完やフォーマット機能を使う

Ubuntu18.04LTS on WSL2 on Windows10でやった。
最近[Terraform Layer](https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/terraform)にLSPサポートが入ったので満を持して。。。





# 保存時に自動フォーマットする
`terraform-auto-format-on-save`を有効にする。

```emacs-lisp:.spacemacs
(defun dotspacemacs/layers ()
   '(
     (terraform :variables
                terraform-auto-format-on-save t)
    )
)
```





# LSPを使う
LSPを経由して自動補完やlinterの機能を使う。

前置き：
Spacemacsが利用する `lsp-mode`にはクライアントとして `lsp-terraform`が含まれている。内部ではterraform-lspを使っている。

cf. https://github.com/emacs-lsp/lsp-mode/blob/666de5f50942efa461130846be740729b25081fd/lsp-mode.el#L377-L385

手順はこう。

- Goをインストール
- terraform-lspをインストール
- SpacemacsでLSPを使うように設定


## Goをインストール
[terraform-lsp](https://github.com/juliosueiras/terraform-lsp)をビルドするためにはGo (golang)が必要とのこと。

> it will need Go 1.14+

今回はUbuntuに手動インストール。
[Go公式サイト](https://golang.org/dl/)から `go1.14.4.linux-amd64.tar.gz`をダウンロードした (terraform-lspが要求するバージョン以降を)

```shell
cd ~
wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz
```

次は[installation instructions](https://golang.org/doc/install)に従ってGoをインストールし、環境変数のパス設定と反映まで行う。

```shell
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bash_profile
source ~/.bash_profile
```

`go version`や `go --help`が使えれば完。


## terraform-lspをインストール
[リリース](https://github.com/juliosueiras/terraform-lsp/releases)をダウンロードする or リポジトリをcloneする の方法がある。
cloneするほうでやった。

```shell
git clone https://github.com/juliosueiras/terraform-lsp.git
```

もし `~/.bin/`ディレクトリがなければ作っておく。
ビルド先のようなので、環境変数のパス設定と反映まで行う。

```shell
mkdir ~/.bin
echo 'export PATH=$PATH:$HOME/.bin' >> ~/.bash_profile
source ~/.bash_profile
```

公式に従ってビルド。cloneしたディレクトリ下 ( `terraform-lsp/`)で行う。

```shell
GO111MODULE=on go mod download
make
make copy
```

successすれば `terraform-lsp`コマンドが使えるようになる。完


## SpacemacsでLSPを使うように設定する
`terraform-backend`の値を `'lsp`にする。

```emacs-lisp:.spacemacs
(defun dotspacemacs/layers ()
   '(
     (terraform :variables
                terraform-backend 'lsp)
    )
)
```
ポートフォリオ作成

# プログラミングの勉強日記
2020年6月25日　Progate Lv.148

##ポートフォリオとは
　ポートフォリオは自分の能力を確認できる作品集のようなものである。

##ポートフォリオ作成の経緯
　私は今までフロントエンドエンジニアになるためにProgateを用いて勉強していた。現在までにNode.js/React/JavaScript/Sass/SQL/Git/Command Line/jQuery/HTML&CSSの全コースを修了した。HTML&CSS/jQuery/JavaScriptを学んだ段階で1度Webページの作成をしたが、それ以降は実際に自分で考えてコードを書いていなかった。そこで、自分のスキルをより身に付けるためにポートフォリオを作成することにした。これからも時間を見つけてProgateは利用していきたいと思う。

##記載する内容
　自己紹介、技術スキル、制作物、連絡先（Twitterなど）
　この制作物には以前作ったサイトも入れようと思う

##

##公開方法
　前回のホームページ同様にGitHubのホスティングを利用しようと思う。


##参考文献
　https://wa3.i-3-i.info/word15625.html
実践コミュニティとベクトルタイル

国連ベクトルタイルツールキット (UNVT) と実践コミュニティ (Comunity of Practice) との関係について考えています。

# きっかけ
[Integrated Geospatial Information Framework Part 2: Implementation Guide](https://ggim.un.org/IGIF/part2.cshtml) の [Strategic Pathway 8](https://ggim.un.org/IGIF/documents/SP8-Capacity_and_Education_19May2020_GLOBAL_CONSULTATION.pdf).6.10 に実践コミュニティの概念が記述されていたことです。

# 実践コミュニティとは
あるテーマに関する関心や問題、熱意等を共有し、その分野の知識や技能を、持続的な相互交流を通じて深めていく集団なのだそうです。

知識は、静的な情報の集まりというよりは、むしろ生きているプロセスに近く、専門的技術を向上させるためには、同じような状況に直面する人々と交流する機会が必要なのだそうです。

# 実践コミュニティを形成する戦略的意図
## 助け合いのコミュニティ
専門分野での一般的な仕事上の問題を協力して解決します。専門家を対等な関係で相互に結びつけるものです。

## ベストプラクティスのコミュニティ
ベストプラクティスを開発して普及させます。実践の有効性と便益を検証するプロセスを持っていて、文書化された実践を共有することをします。

## 知識の世話人のコミュニティ
任務で必要なツールや洞察や手法を開発し、世話をします。メンバーが日常的に用いる知識を体系化し、更新し、浸透させます。

## イノベーションのコミュニティ
極めて斬新な解決方法やアイディアを生み出します。多様なものの見方を持ったメンバーを結びつけるために、意図的に境界を跨いでいます。

# これから
ただの抜き書きのようになってしまいましたが、UNVT に実践コミュニティに関する考えを適用することについて考えてみたいと思っています。

例えば、戦略的意図の認識がずれているとコミュニケーションが難しくなるので、戦略的意図を明示的に共有することが必要な気がしたりしています。

# 参考文献
Wenger et al.: コミュニティ・オブ・プラクティス
Flutterで多言語化リソースの定義を効率化するLiveTemplate定義

AndroidStudioでは以下のようなLiveTemplateを登録しておくと、かんたんにボイラープレートの入力ができます。

# 定義

```
String get $NAME$ {
  return Intl.message(
    "$VALUE$",
    name: $NAME$,
    desc: "$DESC$",
    locale: localeName,
  );
}
```
私は `ls` という略語を割り当てていて、 こんな感じで入力の効率化をしています。

![画面収録-2020-06-25-22.12.44.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/880a7507-4e96-7035-c4c1-8208a8e6f3e3.gif)

# 利用
定義したリソースへのアクセスのために、以下のLiveTemplateも定義しています。
`L10n` はご自身の環境へ置き換えてください。

```
L10n.of(context).$NAME$
```
AWSコスト情報をZabbixでモニタリングする

## やりたいこと

最近、ようやくAWSを触り始めました。いやー楽しいですね。全然わかんないけどw。
趣味のため、無料枠でAWSのいろいろなサービスを使って遊んでします。
が、何が無料枠か否か理解しておらずコストが突然跳ね上がったときに気付きたいと思い、
Zabbixで、一日に一回、AWSのコストをモニタリング(以下)するようにしました。

![Screenshot from 2020-06-25 21-04-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82244/223f542e-9f5b-eb5a-b819-aecf4b161f2b.png)

## もうちょっと具体的に

* AWSのトータルコストと各サービスのコストをモニタリング(1日1回)
* トータルコストに対して、閾値(WARN/HIGH)のトリガーを設定できます。
* zabbix-agentとaws-cli(aws ce)を使用します。
* aws-cliの実行方法(awsコマンド+jq)は、以下URLを参考(ありがとうございます!)
    * https://qiita.com/shinsaka/items/c368c403935549b4401b

## 注意事項

 * AWSのCostExplorerを利用するためコストが発生します。
 * CostExplorerを実行するたびに、0.01USD発生します(2020/06/24現在)
 * 当機能を使用すると、1日に2回CostExplorerを呼び出すため、0.02USDの費用が発生します。

## 内容

作成物は以下の2ファイル (githubに登録,下図でいうオレンジ部分)
 https://github.com/mishikawan/aws-getcost-zabbix-template

 * zabbix-agentの設定ファイル
    * zabbix_agentd.d/userparameter_awscli.conf
 * zabbixのテンプレート
    * zabbix_template/zbx_AWSCost_templates.xml

![Screenshot from 2020-06-25 21-35-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82244/ac7b7640-8d9a-96ee-b77f-be11af8a68ed.png)

## 稼働条件

* Linuxサーバ(検証環境はオンプレのCentOS8)が稼働しており、以下が動いていること
    * zabbixサーバ(検証環境は4.0)
    * AWSCLI
    * jqコマンド
   
## 導入手順

### 1.JQのインストール
```
yum install jq
```

### 2.AWSCLI導入(既に導入されていれば不要)

```
# pip3 install awscli
```

### 3.zabbixユーザでのAWSコンフィグ設定(既に設定されていれば不要)

#### 3-1.zabbixユーザのホームディレクトリのパスを調べる

```
# egrep zabbix /etc/passwd
zabbix:x:2000:2000:Zabbix:/var/lib/zabbix:/sbin/nologin
```

#### 3-2.zabbixユーザのホームディレクトリ(上記例で/var/lib/zabbix)が無い場合は作成します

```
# mkdir /var/lib/zabbix
```

#### 3-3.AWSコンフィグ用のファイルを設置します

```
# mkdir /var/lib/zabbix/.aws
# cat > /var/lib/zabbix/.aws/config 
[default]
output=json
^D
# cat > /var/lib/zabbix/.aws/credentials 
[default]
aws_access_key_id=XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key=XXXXXXXXXXXXXXXXXXXX
^D
# chown -R zabbix:zabbix /var/lib/zabbix/.aws
```

### 4.zabbix_angentファイルを/etc/zabbix/zabbix_agentd.d/配下に設置

```
# cp zabbix_template/zbx_AWSCost_templates.xml /etc/zabbix/zabbix_agentd.d/.
# systemctl restart zabbix-agent.service 
```

### 5.設置したzabbix_agentが機能していることを確認します
#### 5-1.zabbix_agentその1: aws.getcost
```
# zabbix_get -s 127.0.0.1 -k "aws.getcost"
{"AWS Config":"0"
,"AWS Cost Explorer":"0"
,"AWS Elemental MediaStore":"0"
,"AWS Key Management Service":"0"
,"AWS Lambda":"0"
,"AWS Systems Manager":"0"
,"Amazon API Gateway":"0"
,"Amazon CloudFront":"0"
,"EC2 - Other":"0"
,"Amazon Elastic Compute Cloud - Compute":"0"
,"Amazon Elastic Load Balancing":"0"
,"Amazon Simple Notification Service":"0"
,"Amazon Simple Queue Service":"0"
,"Amazon Simple Storage Service":"0"
,"Amazon Virtual Private Cloud":"0"
,"AmazonCloudWatch":"0"
,"Tax":"0"
}
```
#### 5-2.zabbix_agentその2: aws.getcosttotal
```
# zabbix_get -s 127.0.0.1 -k "aws.getcosttotal"
{"Total":"0"}
```

### 6.zabbix_templateファイルをZABBIXにインポート

必要に応じて、template内のMacrosの内容(以下)を変更します。

| Macro	| Value	| 備考 |
| ----- | ----- | ----- |
| {$BUDGET_HIGH} | 100 | コストの閾値 100USD超えればアラート（深刻度=HIGH) |
| {$BUDGET_WARNING} | 10 | コストの閾値 10USD超えればアラート（深刻度=WARNING) |
| {$COSTCHECK_DATETIME} | h11m00 | Cost  Explorerを呼び出す時間 (h11m00 = 11:00) |