OmniAICreator/Qiita-1.07M huggingface dataset:
express-graphqlで出たエラーにはまった

# 何をしようとしたか
GraphQL + Express JS + MongoDBの環境構築をしようと思いました。
しかしサーバーの起動ではまることに。

# 本題
mongooseを使ってmongoDBと接続。
また`app.use`のハンドラー部分にgraphqlHTTPを指定します。
一見大丈夫そう。

```javascript
//app.js

const express = require('express')
const graphqlHTTP = require('express-graphql')
const mongoose = require('mongoose')
const app = express()

mongoose.connect('mongodb+srv://testuser001:password@cluster0.fpkid.mongodb.net/my_db?retryWrites=true&w=majority')
mongoose.connection.once('open', () => {
  console.log('db connected')
})

app.use('/graphql', graphqlHTTP({

}));
app.listen(4000, () => {
  console.log('listening 4000')
})
```


しかし`nodemon app`でサーバーを立ち上げると、graphqlHTTPのところでエラーがでました。

```
$ nodemon app
[nodemon] 2.0.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
graphql_dir/server/app.js:14
app.use('graphql', graphqlHTTP({
                   ^

TypeError: graphqlHTTP is not a function
    at Object.<anonymous> (/graphql_dir/server/app.js:14:20)
```



なにがダメなのかさっぱり分からず30分ほどはまる。

# 解決

[こちら](https://www.npmjs.com/package/express-graphql)に使い方がしっかりと書いてありました。

```javascript
// 正解
const { graphqlHTTP }  = require('express-graphql')
```

つまり下記と同義なんですよね。

```javascript

const graphqlHTTP = require('express-graphql').graphqlHTTP
```
graphqlHTTPが記述されているファイルの中身をまんま渡していたようです。

修正し、再び`nodemon app`でサーバーを起動。
無事mongoDBにも接続できました！

```
$ nodemon app
[nodemon] 2.0.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
(node:13225) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
(Use `node --trace-deprecation ...` to show where the warning was created)
listening 4000
(node:13225) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
db connected
```


# あとがき
とはいえ、`const graphqlHTTP = require('express-graphql')`のように記述している記事をいくつか見かけています。
間違ってるのか、それでうまく行くのかは分かりませんが、もしエラーが出たら参考にしてください。
AngularでBootstrap5を使う準備

#はじめに
先日、Bootstrap 5 alphaがリリースされました。
jQueryとの依存関係が削除されたりして、シンプルにAngularと一緒に使えると考えました。
これは、そのメモです。

#Angularプロジェクトの作成
まずは、テスト用に新しいプロジェクトを作ります。
任意のディレクトリに「angular-bootstrap-test」というプロジェクトを作成します。

```console
$ ng new angular-bootstrap-test
$ ? Would you like to add Angular routing? (y/N) y
$ Which stylesheet format would you like to use? (Use arrow keys)
  > CSS
    Sass
    Less
    Stylus
```

#Bootstrap5のインストール
作成したプロジェクトのデイレクトリに移動して、npmでインストールする。

```console
$ cd angular-bootstrap-test
$ npm install popper.js --save
$ npm install bootstrap@next
```

fseventsの依存関係のエラーがでるが、「wanted {"os":"darwin" ...」ということで、MacOS限定のモジュールらしい。
インストール自体は成功するが、気になる場合は、「--no-optional」でインストールすれば良い。
これで、Bootstrap5がインストールされ、angular-bootstrap-test/node_modulesにbootstrapディレクトリができる。

#使うための準備
Bootstrap5を使うために、angular.jsonを編集する。

```
"style":[
    "src/styles.css" ,
    "node_modules/bootstrap/dist/css/bootstrap.css"  //追加
],
"scripts":[
    "node_modules/bootstrap/dist/js/bootstrap.js"  //追加
],
```
これで使用できるようになりました。

#使ってみる
app.component.htmlに適当に適当に追記してみる。

```
<p class="bg-dark text-light">Bootstrap test</p>
```

#参考
https://v5.getbootstrap.com/docs/5.0/getting-started/download/
JavaScriptで現在のURLを取得 条件分岐


### URL全体の取得

```javascript
var url = location.href ;
console.log(url);
// http://hogehoge.com/fuga.html
```

```javascript
var URL = document.URL;
console.log(URL);
// http://hogehoge.com/fuga.html
```


### プロトコルのみの取得

```javascript
var protocol = location.protocol ;
console.log(protocol);
// http:
```

### ドメインのみの取得

```javascript
var host = location.hostname ;
console.log(host);
// hogehoge.com
```

### パスのみの取得
```javascript
var path = location.pathname ;
console.log(path);
// /fuga.html
```

### URLにhogeが含まれていたら処理を実行する
```javascript
if(document.URL.match("/hoge/")) {
  $('body').addClass('hoge');
}
```
2人でRailsアプリケーション開発をしてみて

#プログラミングの勉強日記
2020年8月6日　Progate Lv.226
フロントエンドエンジニアを目指して独学で勉強を始め、アウトプットのためにポートフォリオなど個人開発をしていた。
チーム開発の経験を積むべきというアドバイスを聞き、2人でRailsでアプリケーションを作成した。アプリケーションを完成することができたので、簡単にまとめてみる。

#開発環境

Rails 5.1.7

VScode
バージョン: 1.46.1 (system setup)
コミット: cd9ea6488829f560dc949a8b2fb789f3cdc05f5d
日付: 2020-06-17T21:13:20.174Z
Electron: 7.3.1
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Windows_NT x64 10.0.18362

#開発の進め方

　VscodeのRemote Development 拡張機能を使って、VSCode からインターネット経由で同じサーバーを使ってログインする。
　対面で会うことはできないので、LINE電話を使って画面共有しながら開発を進める。

#課題とその解決方法
1.完成したアプリケーションのイメージを明確にできなかった。
→言葉だけで伝えるのが難しかったので、イラストや参考にするアプリケーションを見ながら話し合いを行った。

2.役割分担を決められなかった
→自分の得意なことやできそうなことを相手に伝えて、お互いのやりたいことを進めるようにした。
アプリを1から作ったので、最初の作成やトップページなど大まかなところは一緒に作成した。

3.同じファイルを編集してしまうなど、衝突してしまうことがあった。
→自分がどのファイルを操作しているのか相手に伝えるようにした。

4.お互いのコードの理解が不十分だった
→わからないことがあれば、相手に聞くようにした。
　私自身も「動いたからいいや」という考えではなく、コードを理解しながら書くように心がけた。

5.プログラムにエラーが生じてしまい動かなくなったときにお互いブラウザで確認することができなく、作業が止まってしまった。
→2人で協力してエラーの原因を調べて、解決するようにした。
（それぞれが詰まってしまったら、一緒に問題を解決するようにした）

#感想
　対面であって話すことができないので、コミュニケーションの取り方が難しかった。チーム開発にするにあたって、コミュニケーションをとることがいかに重要かを学ぶことができた。
　エラーを解決できたり、できなかったことができるようになったりすることで喜びを共有することができ、チーム開発の楽しさを実感した。徐々に完成に近づき、形になっていくアプリ開発は楽しく、チーム開発をすることでよりアプリ開発を楽しんで行うことができた。

　個人開発の場合でも、チーム開発を想定してGitHubにあげていたが、実際にチーム開発をすることで個人開発では得られなかった経験をすることができた。サマーインターンでチーム開発をすることがあるので、この経験を活かしていきたいと思う。
telnetでのhttp接続

# 前提
・macOS Catalinaのターミナル利用
・telnetはhomebrewで入れた
・今回は http://www.example.com へ接続する。

# 手順
## 1. ポート80で接続する

```
telnet www.example.com 80
```

接続が成功すると、以下のようなメッセージが出てくる

```
Trying 2606:2800:220:1:248:1893:25c8:1946...
Connected to www.example.com.
Escape character is '^]'.
```

## 2. HTTPのリクエストを行う

```
GET / HTTP/1.1
Host: www.example.com

```

※注意点
HTTPリクエストの終わりの行に改行を入れないと、レスポンスが返ってこないので注意。
HTTPリクエストの終わりが\n\nで判断される仕様であるため。
→仕様を知るならHTTPのRFCを読むといい。ぐぐると出てくる。あとはWikipediaとか
https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol

## 3. HTTPのレスポンスが返ってくる
ターミナルにわーっとレスポンスが返ってくる。
レスポンス返却と同時にtelnet接続も終わる。

```
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 527341
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Wed, 05 Aug 2020 16:05:33 GMT
Etag: "3147526947"
Expires: Wed, 12 Aug 2020 16:05:33 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sjc/4E74)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
Connection closed by foreign host.
```
## 4.おまけ
1.のコマンドを実行するとフォアグラウンド実行っぽくなる。
telnetコマンドを実行するモードに戻りたいなら、control+]を押すと戻れる。

以下が例となる。
流れ：telnetで接続→control+]押下→telnet接続終了(close)コマンド

```
telnet www.example.com 80
Trying 2606:2800:220:1:248:1893:25c8:1946...
Connected to www.example.com.
Escape character is '^]'.
^]
telnet> close
Connection closed.
```
PythonでC言語風な構造体

## はじめに

PythonでC言語風な構造体を使いたくて悶々したときに使える手法。
例えば↓のよう構造体を作りたい場合。

```C:c_struct.h
typedef struct{
    float pos[4];
    unsigned char class;
    float score;
} HOGE;

HOGE fuga[10];

```

## Pythonでの表現方法

Structured Datatypesを使用する

 * https://numpy.org/doc/stable/user/basics.rec.html#structured-datatypes
 * https://jakevdp.github.io/PythonDataScienceHandbook/02.09-structured-data-numpy.html

```Python:c_like_struct.py
import numpy as np

HOGE = np.dtype([("pos",    np.float32, (4,)),
                 ("class",  np.uint8,   (1,)),
                 ("score",  np.float32, (1,)),
                 ],
                align=True
                )
fuga = np.zeros(10, dtype=HOGE)
```

これでC言語風な構造体が表現できる。
上記でalign=Trueとすることでパディングされる。

#### 使い方確認①(とりあえず出力)

```Python:処理
print(HOGE)
print(fuga)
```

```Python:結果
{'names':['pos','class','score'], 'formats':[('<f4', (4,)),('u1', (1,)),('<f4', (1,))], 'offsets':[0,16,20], 'itemsize':24, 'aligned':True}
[([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
 ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
 ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
 ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
 ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])]
```

#### 使い方確認②(dtype, shape)

```Python:処理
print("fuga.dtype: ",fuga.dtype)
print("fuga.shape: ",fuga.shape)
print("fuga.['pos'].shape: ",fuga['pos'].shape)
print("fuga.['pos'][0].shape: ",fuga['pos'][0].shape)
print("fuga['pos'][1]: ", fuga['pos'][1])
```

```Pytohn:結果
fuga.dtype:  {'names':['pos','class','score'], 'formats':[('<f4', (4,)),('u1', (1,)),('<f4', (1,))], 'offsets':[0,16,20], 'itemsize':24, 'aligned':True}
fuga.shape:  (10,)
fuga['pos'].shape:  (10, 4)
fuga['pos'][0].shape:  (4,)
fuga['pos'][1]:  [0. 0. 0. 0.]
```

#### 使い方確認③(np.recarray)

```Python:処理
piyo = fuga.view(np.recarray)
print("piyo: ", piyo)
print("piyo.pos.shape: ", piyo.pos.shape)
print("piyo.pos[0].shape: ", piyo.pos[0].shape)
print("piyo.pos[1]: ",piyo.pos[1])
```

```Pytohn:結果
piyo:  [([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
        ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
        ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
        ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])
        ([0., 0., 0., 0.], [0], [0.]) ([0., 0., 0., 0.], [0], [0.])]
piyo.pos.shape:  (10, 4)
piyo.pos[0].shape:  (4,)
piyo.pos[1]:  [0. 0. 0. 0.]
```

#### 使い方確認④(代入処理)

```Python:処理
fuga['pos'][1] = [-1.0 , 2.3, 0.42, 0.0]
print("fuga['pos'][:3]: ",fuga['pos'][:3])
```

```Pytohn:結果
fuga['pos'][:3]:  [[ 0.    0.    0.    0.  ]
                   [-1.    2.3   0.42  0.  ]
                   [ 0.    0.    0.    0.  ]]
```
【AWSSAA(SAA-C02)】受験のために必要な最低限の知識とは？

# はじめに
AWS未経験の僕が、以前(7/23)にAWSSAA(SAA-C02)の試験を受験して合格しました。
今回は、AWSSAAの受験のために必要な最低限の知識についてまとめていきたいと思います。

※合格体験記については、私のブログに記事がありますのでご覧頂ければと思います。
[AWS未経験の僕がSAA-C02をどのように勉強したのか？](https://satton-infra.com/saa-c02-study/)

# 僕の合格点について

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/8299dc58-d102-829e-7b6b-891c85a3a7df.jpeg)


添付の結果の通り、かなりギリギリで合格しています。
**(点数:725/合格点:720)**

# AWSSAA(SAA-C02)受験の前に必要な最低限の知識とは？

こちらの知識になります。

- **基本的なネットワーク知識**
- **TCP/IPの知識**
- **ストレージプロトコルの知識**

では、掘り下げていきたいと思います。

## 基本的なネットワーク知識

AWSにてインフラを構築するためには、基本的なネットワーク知識が必要です。

なぜなら、VPC(Virtual Private Cloud)の構築に必要になる知識だからです。

例えば、こちらの知識になります。

- CIDR(Classless Inter-Domain Routing)
- サブネットマスク
- IPアドレスの割り振り方
- デフォルトゲートウェイ

**こちらの知識は、オンプレミスでのインフラ構築の際にも使用します。**

**CCNA**を勉強して頂くと、この辺の知識は自然と身に付けられるでしょう。

## TCP/IPの知識

TCP/IP（Transmission Control Protocol/Internet Protocol）とは、**「インターネットなどで一般的に使われるプロトコル」**です。

こちらのTCP/IPの知識を事前に覚えておいた方が問題が解きやすいです。

なぜなら、

- セキュリティグループ
- ACL
- Route53

等でTCP/IPの知識が必要とされるからです。

例えば、

- HTTP
- HTTPS
- SSH
- DNS
- SNMP

などは覚えておかないと、そもそもAWSにてインフラ環境の構築ができないです。

これらもまた、**CCNA**や**LPIC level1**等を勉強して頂くと身に着けることができます。

こちらのサイトに解説がありますので、ご参考下さい。

[TCP/IPをはじめから - ネットワークエンジニアとして](https://www.infraexpert.com/study/tcpip.html)
[TCP/IPとは](https://wa3.i-3-i.info/word1540.html)

## ストレージプロトコルの知識

ストレージプロトコルについての知識も試験問題を解くためには必要だと感じました。

なぜなら、下記のようなサービスでストレージプロトコルの知識が必要だからです。

- Amazon EFS
- Amazon FSx
- AWS Storage Gateway

上記のサービスを使うためには、こちらのストレージプロトコルの知識を抑えておく必要があります。

- iSCSI
- NFS
- SMB(CIFS)

オンプレミスにてストレージの構築やストレージマウント作業に携わったことのある人であれば、わかりやすいと思います。

ストレージ作業未経験者は、AWSにて実際に手を動かして学んで頂くのが早いです。


# まとめ

**○AWSSAAに挑戦するためには、これらの知識は最低限レベルで必要**

- 基本的なネットワーク知識
- TCP/IPの知識
- ストレージプロトコルの知識

**○最低限知識を習得するためには、こちらの資格を勉強すると良い**

- LPIC level1
- CCNA
ネットワーク上の別マシンへの接続(telnet,ssh)

# この記事の前提
・macOS Catalinaでのターミナル経由での接続。

## telnet（ウェルノウンポート:22番）
いま使ってるOSだとtelnetコマンドがインストールされていなかったから、
もし使うならhomebrewなどを利用してローカルマシンへ入れる。

以下で接続可能。

```
telnet [接続先サーバのホスト名 or IP]
```
ただ、この方法だと通信内容が暗号化されていないので、通信の中身が丸見えになる。
（サーバによってはtelnetでの接続を禁止しているかも）

だから、sshを利用するといい。

ちなみに、ポート80で接続するとhttp通信もできる。（ウェルノウンポートそのままなら）
https://qiita.com/honeycom/items/d44590dd27d5dccb4b5a

ちゃっちゃとhttp通信のレスポンス見たいならcurlを使うか
ウェブブラウザにURL入れるほうが早いけど、telnetでも一応できる模様。

## ssh（ウェルノウンポート:23番）
以下で接続可能。

```
ssh [接続サーバのホスト名 or IP]
```

別のマシンへ接続するためのID・パスワードが指定されている場合は、
コマンド内で指定してあげると接続できる。
（パスワードは後で聞かれるので、入力したり鍵ファイルで対応したりする）

```
ssh [ユーザ名]@[接続サーバのホスト名 or IP]
```

詳しくはインターネットでsshとぐぐれば出てくるので、そちらを参照する。

# 参考にしたサイト
https://www.infraexpert.com/study/tcpip19.html
https://www.atmarkit.co.jp/ait/articles/1701/26/news015.html
VirtualBoxが不安定！WSL2と同時使用してませんか

# WSL2とVirtual Boxは同時使用できません

エラーもなにも表示されず、仮想サーバも動作します。しかし、ubuntuのインストールが正常に完了しません。CentOSもうまくインストールできません。

動いてるんだけど、正常じゃないという非常にやな状況になります。

VirtualBox 6.1.12　の場合です

# 解決策

Virtualboxを使う時は、WSLを停止させる

```powershell
Disable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```
以上

半日溶かしました。あ～もっと早くWSLを疑えばよかった。

同時に使えるようになってくれ。

気づかずハマるひといると思う（拡散希望！）

# 追加情報

VirtualBox 6.1.16　で改善されている事を確認しました。WSL2有効の状態で、ubuntu 20のVM起動できました。
Windows10のVMを起動してみたら、起動途中で止てるのではないかと思うくらい起動時間が長く、起動後も動作が非常に遅いです。軽い処理の時は、WSLと同時実行できそうですが、重い処理の時は、WSL停止する必要がありそう。

参考
http://kzlog.picoaccel.com/virtualbox-coexist-with-wsl2-hyper-v/
日付に関する正規表現

## 日付を絞る正規表現が意外と思いつかなかったんだよね

日付は１日から３１日まであるわけですが、それを表現する正規表現が今ひとつ思いつかず。
二桁の連番の表現ってなかなか難しい

## 結論を先に言おう

### 1から31を表現

```repex
([1-9]|[12][0-9]|3[01])
```

### 一桁を左0詰め表現

```repex
(0[1-9]|[12][0-9]|3[01])
```

### 8月の表現

日付を*YYYYMMDD*で表現することとして

```repex
202008(0[1-9]|[12][0-9]|3[01])
```

### フォルダの特定など

```repex
/home/hoge/202008/202008(0[1-9]|[12][0-9]|3[01])/abc.log
```

### OR表現に悩んでいて無駄なログまで拾っていたのです

カッコとOR表現を使えば、正規表現で連番を表現できるってことに気づくのにだいぶかかったんだよね。

これで、ログ検索とかもだいぶ楽になるかなあ、と思う次第です。

これまでは、15日から24日までのログを取りたいと思っても、OR表現に思い当たらずとりあえず10日代と20日代を全部拾ってたからすごく無駄な時間がかかってたんだよね。

```regex
202008[12][0-9].log
```

これもこういうふうにすると解決しますね。

```regex
202008(1[5-9]|2[0-4]).log
```

正規表現を知識と分かっていても、その組合せに気づくには知恵が必要という好例でした。
Apollo ClientからApollo Serverへファイルのアップロード

## はじめに
`Apollo Client`から`Apollo Server`にGraphQLでファイルをアップロードするにあたり、必要だった知識をメモしておきます。なお、ファイルのダウンロードに関しては、base64形式等の文字列をフロントに返すといったやり方もあるようですが、素直にRESTのエンドポイントで返す形にしました。

## Apollo Client 側
[apollo-upload-client](https://github.com/jaydenseric/apollo-upload-client)というミドルウェアをApolloLinkに追加（この記事を書いた時点ではApollo Clientとの型の整合性が取れておらず、 `//@ts-ignore` する必要がありました）

```typescript
const client = new ApolloClient({
  cache: new InMemoryCache(),
  //@ts-ignore
  link: createUploadLink({
    uri: "http://localhost:4000",
  }),
});
```

onChangeイベントで

```jsx
<input type="file" onChange={onChange}>
```

mutationリクエスト

```typescript
const UPLOAD_FILE = gql`
  mutation($file: Upload!) {
    uploadFile(file: $file) {
        success
    }
  }
`;
```

## Apollo Server 側
第2引数の `file` に、アップロードされたファイルに関するオブジェクトが渡ってくるので、その中の`createReadStream`でファイルのStreamオブジェクトを取得します。その後、[aws-sdk](https://www.npmjs.com/package/aws-sdk)を使ってS3にそのまま流し込んだり、CSVのファイルをjson形式に展開するのであれば[csvtojson](https://www.npmjs.com/package/csvtojson)を使うなど、必要な処理に進みます。

```typescript
async uploadFileResolver (
  parent, 
  { file } : { file: Promise<FileUpload> }
) : Promise<UploadFileResponse> {
  const { createReadStream, filename, mimetype, encoding } = await file;
  // createReadStream()でファイルのStreamが取得できる
}
```

内部で使われている[graphql-upload](https://github.com/jaydenseric/graphql-upload)の`FileUpload`の型がこちら

```typescript

export interface FileUpload {
  filename: string;
  mimetype: string;
  encoding: string;
  createReadStream(): ReadStream;
}
```

ファイルのmaxサイズを指定したい場合は

```typescript
const server = new ApolloServer({
  typeDefs,
  resolvers,
  uploads: {
    maxFileSize: 10000,
  },
});
```

## Codegen

Apollo Serverが自動的に追加してくれるので、スキーマファイルに `scalar Upload` を記述する必要はないのですが、[graphql-code-generator](https://github.com/dotansimha/graphql-code-generator)を使っている場合は設定ファイルに `scalar Upload` を追加する必要があります。

https://github.com/dotansimha/graphql-code-generator/issues/1073#issuecomment-448685684

## まとめ
今回はApollo ClientからApollo Serverへファイルのアップロードをする際に必要だった知識をまとめました。
PHP 条件演算子(三項演算子)の省略構文「??」〜null合体演算子〜

# 目的

- 先輩方が記載したコードを読んでいて初めて知ったものだったのでまとめる

# 三項演算子`??`

- この演算子は別名null合体演算子とも呼ばれる。
- 下記に例を記載する。

    ```php
    式1 ?? 式2;
    ```
- 式1がnullではない場合には式1が実行される。
- 式1がnullの時は式2が実行される。

# 具体例

- 変数`$str`に文字列を格納する処理を記載する。
- 変数`$base_str`に文字列が格納されている時は変数`$base_str`の文字列を変数`$str`に格納する。
- 変数`$base_str`がnullの時は文字列「base_str is null」を変数`$str`に格納する。

    ```php
    $str = $base_str ?? 'base_str is null';
    ```
# 参考文献
TCP/IP全体像__図解イメージ【初心者】


TCP/IPに関して勉強した事を
諸先輩方の記事が大量にある中ではありますが、　
忘備録として、図でアウトプットしていきたいと思います！:smile:
(個人のイメージであり、間違っている部分が多々あると思います。
 その点誠に申し訳ございませんm(_ _)m)

####1. 全体像(イメージ)
TCP/IP = "インターネット・プロトコル・スイート" (TCPとIPという意味では使わない)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/fc0e22f7-4b40-453a-e0ff-df05812f95fd.png)


####2. 無線ルーターについて 
無線ルーターは、wifiを飛ばす装置だと思ってましたが、全然違いました。
それはアクセスポイントでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/a9944d14-301f-623b-2992-db0b7cdecbda.png)

####3. アドレス変換について
グローバルアドレス一つでも、ポート番号で区別すれば、たくさんの人が使える！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/c1c1f0fb-c083-e2fc-21dc-6c7d4dfb9bdb.png)

####4. DNSについて
リゾルバはOSの機能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/90ea643f-63d3-0d20-7926-25cb86bc5569.png)

####5. メールサーバーについて
相手のPCと直接TCP通信をするとずっと電源を入れておかないといけないので、
常時ONのメールサーバーを立てる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/ab82a8a1-d880-84f8-de63-5d0295aa4480.png)


####6. 勉強中に感じた、TCP/IPを難しく感じる理由考察
今どこの話？というのがよくわからなくなりました。
それをまとめたいと思ったのが、本記事執筆の理由です。
難しい理由１.TCP/IP=インターネットプロトコルスイーツの略だが、トランスポート層のTCPとIP層など同じ名前を使っていてどこを指しているのかわかりにくい
難しい理由2.目に見えない上、現実での処理が早すぎるので、多くの処理をしている実感がなく、イメージしづらい
難しい理由３.構成要素多すぎ
逆にこれを作り上げたエンジニアとそのコミュニティの力凄すぎ、と思いました。
####７. 参考書籍
ネットワークはなぜつながるのか 第二版(戸根勤著、日経NETWORK)
マスタリングTCP/IP 入門編　第６版（井上直也、村山公保、竹下隆史、荒井透、苅田幸雄著、オーム社）
(いずれも素晴らしい書籍でした！)
ネットワークの仮想化で使われる3つの技術「VLAN」と「VPN」と「NFV」とは

サーバーのクラウド化を実現する為には、ネットワークにも物理的な構成に縛られない柔軟性が求められる。その為に重要になるのが**VLAN**、**VPN**、**NFV**という３つの技術である。

以下にてそれらを解説していく。

#VLANとは？

- **V**irtual **LAN**の略で、**１つの物理的なネットワークを複数の論理的なネットワークに分割する技術**のこと。

- 論理的に分割したネットワーク同士はルーターを介さなくてはやり取りができなくなるので、**組織単位でネットワークを分割すれば、組織内に限定したデータのやり取りを行うことができる**。


#VPNとは？

- **V**irtual **P**rivate **N**etworkの略で、インターネットのような不特定多数が利用するネットワーク上で、**仮想的に専用線のようなプライベートネットワーク接続を行う技術**のこと。

- IPsecというプロトコルを用いることで、通信する拠点の認証、通信データの暗号化が行われ、拠点間の安全な通信が実現する。

#NFVとは？

- **N**etwork **F**unctions **V**irtualizationの略で、**ネットワーク機器をソフトウェアで実現し、仮想サーバー上で構築する技術**のこと。

- NFVでは専用のハードウェアを使わずにネットワーク機器を実現することで、ハードウェア機器を代替することができ、**ネットワーク機器の需要や構成変更などにも柔軟に対応できる。**
redis-cliでHashデータをcsv出力する

# 概要
RedisのHashを一覧表示したい。
何も考えないと、keysしてから一つずつhgetallとか、hmgetする必要がある。

# 出来上がったシェル
```bash
#!/bin/sh
export REDIS_CLI_PATH=src/redis-cli
export HASH_NAME=$1
export FIELD_NAMES=${@:2:($#-1)}

if [ -z "${HASH_NAME}" ]; then
  echo "Usage: redisHashToCsv.sh [HASH_NAME] ([FIELD_NAMES])"
  echo "ex1) redisHashToCsv.sh people"
  echo "ex2) redisHashToCsv.sh people name address"
  exit 1
fi

if [ -z "${FIELD_NAMES}" ]; then
  # Print all keys
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | head -1 | awk '{system("${REDIS_CLI_PATH} --csv hkeys " $0)}'
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | awk '{system("${REDIS_CLI_PATH} --csv hvals " $0)}'
else
  # Print keys specified by args
  echo ${FIELD_NAMES} | tr " " ","
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | awk '{system("${REDIS_CLI_PATH} --csv hmget " $0 " ${FIELD_NAMES}")}'
fi
```

xargsがうまく改行を処理できず、awkでゴリっとやりました。

# 実行例1　ハッシュキーのみ指定（非推奨）
```
[ec2-user@ip-172-30-2-184 redis-5.0.8]$ ./redisHashToCsv.sh people
"_class","name","age","address"
"redisreposample.Person","hoge","20",""
"redisreposample.Person","moge","35","2-2-2"
"redisreposample.Person","toge","3-3-3"
[ec2-user@ip-172-30-2-184 redis-5.0.8]$
```

3行目はageフィールドがnilなので、詰まって表示されてしまってます。
あと、hkeysとhvalsのキー順は常に同じであることを祈ります。

# 実行例2　ハッシュキー+フィールドリストを指定（推奨）
```
[ec2-user@ip-172-30-2-184 redis-5.0.8]$ ./redisHashToCsv.sh people name age address
name,age,address
"hoge","20",""
"moge","35","2-2-2"
"toge",NIL,"3-3-3"
[ec2-user@ip-172-30-2-184 redis-5.0.8]$
```

こっちのパターンだとnilが"NIL"と表示されてズレなくてよい感じです。

# 動作確認環境
```
[ec2-user@ip-172-30-2-184 redis-5.0.8]$ uname -a
Linux ip-172-30-2-184.ap-northeast-1.compute.internal 4.14.177-139.254.amzn2.x86_64 #1 SMP Thu May 7 18:48:23 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-172-30-2-184 redis-5.0.8]$ src/redis-cli -v
redis-cli 5.0.8
[ec2-user@ip-172-30-2-184 redis-5.0.8]$
```

# 参考
- [redis-cliの使い方 - Qiita](https://qiita.com/sawada_masahiko/items/1f60936c421ecab8dfbf)
    - この記事で--csvオプションを知りました。この記事で得たアイデアのおかげで、本記事が出来ました。感謝いたします。
- [シェルスクリプトで、ある順番以降の引数を取得する - Qiita](https://qiita.com/kentaro/items/db9944429ef160987b3a)
    - 第2引数以降をまとめて処理するやり方。
- [シェルスクリプトで変数が空文字であるか調べる | ex1-lab](https://ex1.m-yabe.com/archives/4548)
   - 覚える気がないので、毎回ググってます。
ICFデータベースをbrute force的スクレイピングを用いて作成する

#はじめに
ICFとは，WHOが作成した国際機能分類のことで，人の健康状態をコードを用いて表現することができるツールです．例えば，「b280 痛みの感覚」は身体部位の損傷やその可能性を示す不愉快な感覚のことで，「b280 4」のようにコードの後ろにレベルをつけることで，そのICF項目がどれほど問題のある状態なのかを表せます．ちなみにレベル4は重症なので痛みの感覚がないことを表すコードになってると思います．（筆者は医療関係者ではないため細かな間違いは多々あると思います．）

このICFコードですが，研究で使いたいと思ったら，調べた限りデータが公開されていなかったので自分でデータベース化しようと思いました．そこで，ICFをweb上で検索できる[「ICFコード検索データベース」](http://www.icfcy-jpn.org/e-angel/icfdb/icfdb_all.htm)というサイトをスクレイピングする方法を試してみたという記事になります．

#準備
BeautifulSoupをインストールします！

```php
$ pip install beautifulsoup4
```

#方針
ICFは「b280」のように「"アルファベット" ＋ 〇〇〇〇〇」といった構成になっていて，〇には0~9の数字が入ります．つまり「アルファベット一文字と最大5桁の10進数の組み合わせ」です．今回はbrute force（総当たり）的なアプローチでコードの全パターンを生成し，生成した各コードを「ICFコード検索データベース」上でクエリに指定し，その検索結果からデータを取得しようと思います．

#コーディング
全体では，「brute forceでクエリに指定するICFコードを生成」→「ICFコードをスクレイピングのURLに挿入して，リクエストを送り，結果を受け取る」→「beautifulsoupで受け取ったレスポンスを解析して必要なデータを抜き取る」→「取ってきたデータをcsvで出力する」という流れでコードを書いていきます．

##brute forceでクエリに指定するICFコードを生成
「アルファベット一文字と最大5桁の10進数の組み合わせ」を全パターン生成していきます！書いそびれていましたが，アルファベットは例に挙げた'b'だけでなく，'b','s','d','e'の4つです．

```python

BSDE = ['b', 's', 'd', 'e']

def icf(n):
  if (int(n/10)):
    return icf(int(n/9)) + str(n%9)
  return str(n%9)

for head in BSDE:
  for N in [1, 2, 3, 4, 5]:
    for i in range(9**N):
      num = icf(i).zfill(N)
      code = head + num
```

zfillを使うのが，少しテクニカルだと思っています．
計算量は多いですが，今回はクエリに使用するため，1~5桁の全パターンを作らないといけません．例えば，「b00280」をクエリにしても「b280　痛みの感覚」という検索結果は出てこないです．従って，このように組みました．

##ICFコードをスクレイピングのURLに挿入して，リクエストを送り，結果を受け取る
実際に「ICFコード検索データベース」の"ICFコードで検索"に「b280」とクエリを指定して検索すると，遷移先のURLは以下になります．

```
http://www.icfcy-jpn.org/e-angel/icfdb/icfdb_all.cgi?IDv001=&IDn001=AND&keys1=b280&keys2=&keys3=&keys4=&keys5=&keys6=&print=10）
```
ちょうど真ん中あたりに「keys1=b280」のようにクエリが確認できます．そのため，ここにbrute forceで生成したICFコードに毎回置き換えて指定することで，生成したICFコードをクエリとした検索結果を受け取ることができます．

```python
import requests
from urllib.request import urlopen

pre_url = 'http://www.icfcy-jpn.org/e-angel/icfdb/icfdb_all.cgi?IDv001=&IDn001=AND&keys1='
post_url = '&keys2=&keys3=&keys4=&keys5=&keys6=&print=1'

url = pre_url + code + post_url #codeは先に生成したICFコード
html = urlopen(url)
```

##beautifulsoupで受け取ったレスポンスを解析して必要なデータを抜き取る
```python
from bs4 import BeautifulSoup
write_list=[]

soup = BeautifulSoup(html, "html.parser") #htmlは先の検索結果を格納したもの
try:
  table = soup.findAll("table")[0]
  rows = table.findAll("td", {"width":"85%"})
  write_list.append([rows[0].get_text(), rows[1].get_text(), rows[3].get_text(), rows[4].get_text()])
except:
        pass
```

「ICFコード検索データベース」の検索結果はHTMLでいうとtableとして返ってくるのでbeautifulsoupを使ってtable要素だけを抽出します．また，さらにtable要素の中でも必要なデータ（今回は，"ICFコード", "タイトル", "カテゴリー", "解説"のみ）を抽出する．
ここで，「b00280」と検索しても0をスルーして「b280」がヒットすることはないので，0件ヒットになってしまいます．その場合を想定してtry&exceptでエラー処理を記述します．


##取ってきたデータをcsvで出力する
```python
import csv

with open('icf_database.csv', 'w') as f:
    writer = csv.writer(f)
    writer.writerows(write_list) #write_listには抽出した必要なデータが二次元配列で格納されている
```

![CSVをEXCELにインポート](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672570/70b76b73-75ae-0077-6010-d40a5d54482e.png)
画像のようにcsvをexcelにインポートするとICFデータベースを取得できたことが確認できます．文字化けする場合は，文字コードが[UTF-8]になっているかを確認してみてください．
APIで取得したJSONデータの日本語文字化けを解消する。

##発生した問題
youtube Data APIでデータを取得する練習をしていたら、取得したデータを出力すると日本語が文字化けしてた。

```search.py
if __name__ == "__main__":
    try:
        response = youtube_search(
            q='公式', part='snippet', type='video', max_count=1, order='date')

        CURRENT_DIR = os.getcwd()
        with codecs.open(CURRENT_DIR + '/' + 'data.json', 'w', encoding='utf-8') as f:
            f.write(json.dumps(response, indent=2))

        print(json.dumps(response, indent=2))

    except HttpError as e:
        print("An HTTP error %d occurred: \n%s" % (e.resp.status, e.content))
```
```結果.
########################
## 関係ないところは省略
########################
        "title": "\u4eee\u9762\u30e9\u30a4\u30c0\u30fc\uff08\u65b0\uff09\uff08\u30b9\u30ab\u30a4\u30e9\u30a4\u30c0\u30fc\uff09\u3000\u7b2c14\u8a71[\u516c\u5f0f]",
        "description": "\u4eee\u9762\u30e9\u30a4\u30c0\u30fc\uff08\u65b0\uff09 \u7b2c14\u8a71\u300c\u30cf\u30a8\u30b8\u30b4\u30af\u30b8\u30f3 \u4eee\u9762\u30e9\u30a4\u30c0\u30fc\u5371\u6a5f\u4e00\u9aea\u300d \u6d0b\u306f\u5bcc\u58eb\u6025\u30cf\u30a4\u30e9\u30f3\u30c9\u3067\u3001\u5148\u8f29\u30fb\u8c37\u6e90\u6b21\u90ce\u3068\u518d\u4f1a\u3002\u3060\u304c\u3001\u3053\u306e\u5730\u4e0b\u306b\u306f\u3001\u30cd\u30aa\u30b7\u30e7\u30c3\u30ab\u30fc\u306e\u602a\u4eba\u30cf\u30a8\u30b8\u30b4\u30af ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/yTFJ-6NnUNY/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url"

```

##解消方法
json.dumps()のオプション「ensure_ascii」がデフォルトでTrue、つまりASCII文字を含む場合は自動的にエスケープする処理を実行する設定がデフォルトになっている。
これをFalseに設定してエスケープされないようにする。

```search.py
if __name__ == "__main__":
    try:
        response = youtube_search(
            q='公式', part='snippet', type='video', max_count=1, order='date')

        CURRENT_DIR = os.getcwd()
        with codecs.open(CURRENT_DIR + '/' + 'data.json', 'w', encoding='utf-8') as f:
            f.write(json.dumps(response, indent=2, ensure_ascii=False))

        print(json.dumps(response, indent=2, ensure_ascii=False))

    except HttpError as e:
        print("An HTTP error %d occurred: \n%s" % (e.resp.status, e.content))
```
```結果.
########################
## 関係ないところは省略
########################
        "title": "仮面ライダー（新）（スカイライダー）　第14話[公式]",
        "description": "仮面ライダー（新） 第14話「ハエジゴクジン 仮面ライダー危機一髪」 洋は富士急ハイランドで、先輩・谷源次郎と再会。だが、この地下には、ネオショッカーの怪人ハエジゴク ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/yTFJ-6NnUNY/default.jpg",
```
アセンブリ言語(CASL2)を学習＃３

#はじめに
　引き続きCASL2をやっていきます。今回は分岐条件と比較演算をやります。
#casl2について
　casl2は文字コードJIS　0201です。16進数で表しています


| \ | #30 | #40 | #50 | #60 | #70 |
|:--:|:--:|:--:|:--:|:--:|:--:|
| #0 | 0 | / | P | / | p |
| #1 | 1 | A | Q | a | q |
| #2 | 2 | B | R | b | r |
| #3 | 3 | C | S | c | s |
| #4 | 4 | D | T | d | t |
| #5 | 5 | E | U | e | u |
| #6 | 6 | F | V | f | v |
| #7 | 7 | G | W | g | w |
| #8 | 8 | H | X | h | x |
| #9 | 9 | I | Y | i | y |
| #A | / | J | Z | j | z |
| #B | / | K | / | k | / |
| #C | / | L | / | l | / |
| #D | / | M | / | m | / |
| #E | / | N | / | n | / |
| #F | / | O | / | o | / |



#コード1(JUMP命令、JPL命令,JZE命令、JMI命令)
```
RANCH    START
          LD      GR0, DATA ; OF=0,SF=0,ZF=1
          JZE     LOOP1 ; LOOP1に飛ぶ
JP1       LD      GR0, DATA2 ; OF=0,SF=0,ZF=0
          JPL     LOOP2 ; LOOP2に飛ぶ
JP2       LD      GR0, DATA3 ; OF=0,SF=1,ZF=0
          JMI     LOOP3 ; LOOP3に飛ぶ
LOOP1     JUMP    JP1 ; 無条件でJP1に飛ぶ
LOOP2     JUMP    JP2 ; 無条件でJP2に飛ぶ
LOOP3     JUMP    EXIT ; 無条件でEXITに飛ぶ
DATA      DC      0
DATA2     DC      1
DATA3     DC      #8000 ; 最上位ビットが１
EXIT      RET
          END
```
##JUMP命令、JPL命令,JZE命令、JMI命令
　JUMP命令は無条件でオペランドで指定したラベルの行に飛びます。
　JPL命令はSF=0のとき、オペランドで指定したラベルの行に飛びます。(JPL = Jump on PLus)
　JZE命令JはZF=1のとき、オペランドで指定したラベルの行に飛びます。(JZE = Jump on ZEro)
　JMI命令JはSF=1のとき、オペランドで指定したラベルの行に飛びます。(JMI = Jump on MInus)

#JOV命令,JNZ命令
JOV命令はOF=1のとき、オペランドで指定したラベルの行に飛びます。(Jump on OVerflow)
JNZ命令はZF=0のとき、オペランドで指定したラベルの行に飛びます。(Jump on Not Zero)
##比較命令（CPA命令,CPL命令）
　CPA命令はオペランドで指定した値の比較をします。比較といっても実際には
(レジスタの中身)-(指定したアドレスの中身)を行い、符号の結果をフラグレジスタに格納しています。
　CPL命令もCPA命令と同じような動作をしますが、減算は論理演算であることに注意しましょう
#分岐・比較を用いたコード
```
RA2SA     START
          IN      IBUF, LEN ; Input String
          LD      GR0, IBUF ; GR0 <- IBUF
          CPA     GR0, BOUND ; 小文字か大文字かを判定
          JPL     S2L   ; 小文字ならS2L(Small to Large)
          JMI     L2S   ; 大文字ならL2S(Large to Small)
; 変換後の値を出力する
RSTART    ST      GR0, OBUF ; GR0 -> OBUF
          OUT     OBUF, LEN ; Output String
          RET
; 小文字から大文字に変換 * only character
S2L       SUBA    GR0, CHANGE
          JUMP    RSTART
; 大文字から小文字に変換 * only character
L2S       ADDA    GR0, CHANGE
          JUMP    RSTART
; define Constants and keeping memory
IBUF      DS      1
OBUF      DS      1
LEN       DC      1
CHANGE    DC      32
BOUND     DC      95
NOTCHAR   DC      65
ECODE     DC      97
          END

; 大文字を小文字に変換し、小文字を大文字に変換するプログラム（*文字コードJIS 0208でのみ出力可）
```
上のコードでは小文字であれば大文字に、大文字であれば小文字に変換します。
大文字と小文字の差は32であるのでそれを利用しています。
#終わりに
分岐条件では見にくくなりやすいので、コメントや条件をうまくやることが大切です。
【HTML】テトリス作成に向けて

テトリス作成に向けて調べた内容をまとめていきます。

#divを横に並べる

##floatプロパティを使用する
|設定値|説明|
|---|---|
|fight|右寄せ|
|float|左寄せ|

##displayプロパティの設定
inline-blockに設定することで高さが違う要素を上揃えにすることができる。

#角を丸める
border-radius
Azureの検証環境コストを削減したい#2 Azure Cost Managementで予算を設定する

[Azureの検証環境コストを削減したい#1(Load Balancer/Application Gateway)](https://qiita.com/motomiya_hikaru/items/6db04a20a088063b0398)
からの続きの記事です。

## はじめに

何か買い物をするとき、どんなこと考えますか？そうですね、__まず予算を決めますよね！__
__予算__を決めておかないと、__ついついお金を使いすぎてしまったり、そもそもお金を使いすぎたことに気が付かない__かもしれません。


はい、そういうことで__「 Azureの検証環境コストを削減したい」#2では、Azure Cost Managementで予算を作成します!__(雑な導入)

## 一言でいうと

- 月額費用を決めて設定する！
- 割合でアラートを付加する！
- アラートが出る！

## Azure Cost Management

###**1.コストと管理を開く**
まず**「コストの管理と請求」**を開きましょう。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/1dacae03-2a8a-0502-92bd-b4cb0307b532.png)|
|:--|

上の検索ボックスに、「コスト」と入れて検索します。
**「コストの管理と請求」**が出てきますので、これを選択します。

###__2.コスト管理を選択する__
__「コスト管理」__を選択します。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/5db1eae2-1610-8d3f-c53d-b40239b504f9.png)|
|:--|

###__3.予算を選択する__
**「予算」**を選択します。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/aaf02f50-4b1d-2e4e-8bb8-f4f3d15c1cdd.png)|
|:--|

###__4.予算を追加する__
**｢追加｣**を選択します。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/7afdb729-8f40-9960-b649-ca58761c3352.png)|
|:--|

###__5.予算を作成する__
予算の作成画面が表示されるので、各種設定値を入れます。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/64e76fc1-3425-6b7a-25c2-97572515dd5c.png)|
|:--|

- 名前:任意のわかりやすい名前を入れます。ここでは｢Monthly-cost｣としました。予算名には、英数字、アンダースコア、ハイフンのみを含めることができます。

- リセット期間:予算をリセットしたい期間を選択します。請求書:「課金月」｢課金四半期｣「課金月」,暦付き:｢月単位｣「四半期ごと」「毎年」から選択することができます。ここでは暦月:「月単位」としました。

- 作成日:予算を評価したい期間を選択します。ここでは「月単位」なので、「8月1日」(日は変更不可)としました。この日にち以後、定められたリセット期間ごとに予算がリセットされます。

- 有効期限:｢2022/08/31｣を指定しておきます。

- 予算額:予算の閾値としたい金額を入れます。ここでは「5000」(円)としました。
__｢次へ｣__を選択します。

###__6.通知の設定をする__
閾値の割合に達した場合、アラートを出すように設定することができます。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/f7461b7c-fe47-31c9-4e1e-110449486250.png)|
|:--|
- 警告条件
    - 予算の割合:予算の何%でアラートを出すか設定します。ここでは｢80｣,｢50｣を設定しました。
    - 金額:予算の割合から、自動的に金額を表示します。
    - アクショングループ:「なし」を選択します。アクショングループを設定すると、これをトリガーにアクションを起こすことができます。稼働中のリソースをすべて削除する、とか。
    - アラートの受信者: メールアドレスが設定できます。自分のメールアドレスを入れます。
    - ｢作成｣を選択すると・・・

これで予算が作成できました！

## まとめ
これで、__月額で2500円使った場合と、4000円使った場合にアラートを受信でき、コストオーバーしないように対策を実施することができます。__
月末に｢●●●万円請求がッッッッッッッッッッッッッッッッッッッッッッッッッッッ！｣となることもありません。
また、今回はサブスクリプションに対して予算を付加しましたが、これを__リソースグループ単位でも付加することができます。__
これでリソースグループ別に使いすぎを抑制することができます。

## 終わりに
予算を設定するのは、__多額の請求を回避するために重要なことです。__
__是非一番最初に設定しておきましょう！__

次:
[Azureの検証環境コストを削減したい #3 Azureポリシーを利用してリソースを制限する](https://qiita.com/hikaru_motomiya/items/ab21e39e99dab494c881)

## 参考
Azure Cost Management および Billing のドキュメント
https://docs.microsoft.com/ja-jp/azure/cost-management-billing/
Azure Portal でのアクション グループの作成および管理
https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/action-groups

Azureの検証環境コストを削減したい#1(Load Balancer/Application Gateway)
https://qiita.com/motomiya_hikaru/items/6db04a20a088063b0398
CentOS8にAnsibleをインストールしてみた

##概要
CentOS8にAnsibleをインストールしようとしたところ、
すんなりいかなかったので、備忘録として残しておきます。

##参考サイト
以下を参考にさせていただきました。
[CentOS8 にAnsible をインストールする](https://qrunch.net/@santak/entries/aW0BnXf2IDDn6F4Z)

##Ansibleのインストール

 - dnfコマンドでインストールを試みる

```bash:ターミナル

dnf install -y ansible

→一致した引数がありません: ansible
```

インストールができない。。。

ということで、ググることにした。
その結果、参考サイトに出会ったため、私の環境で実行した結果を備忘録として残しておきます。

##Re:Ansibleインストール

```bash:ターミナル

#パッケージのUPDATE
dnf update -y
→更新なし

#Python package manager のアップグレード
pip3 install --upgrade pip

#rpm追加
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

#Ansibleインストール
dnf install  --enablerepo epel-playground  ansible

#Ansibleバージョン確認
ansible --version
→バージョン情報が出力されること
```

##Ansible動作確認

動作確認用のPlayBookを作成する

```bash:ターミナル

#作業ディレクトリ作成
cd <任意のディレクトリ>
mkdir ansible
ls -ltr
→ansibleディレクトリが作成されていること

#hosts設定
cd /etc/ansible
cp -p hosts hosts_org
ls -ltr
→バックアップが作成されていることを確認

#hostsファイルに接続先設定追加
vim hosts

#以下を追加
[server]
CentOS8のローカルIP

#playbook作成
cd <任意のディレクトリ>/ansible
pwd
→ディレクトリ移動できていること

vim ansible-test.yml

#以下を追記
 - name: Ansibleテスト
   hosts: server
   gather_facts: no
   tasks:
   - name: チェックディレクトリ
     shell: ls -l /home
     register: result

   - name: チェックした内容を確認
     debug: var=result.stdout_lines

#動作確認
#事前に「ssh <CentOS8ローカルIP>を実行して、finger printを認証しておくこと
cd <任意のディレクトリ>/ansible
ansible-playbook ansible-test.yml -k
→「SSH password:」とパスワード入力を求められるため、コマンド実行しているユーザパスワードを入力。
→shellで設定したコマンドが正常に実行されていれば、成功。
```

##まとめ
Ansibleインストールができたので、
Jenkinsと連動して、色々と自動化できることを考えていきたいと思います。
Rails herokuにデプロイ後にAPIキーが見当たらなかった時の解決方法

#実装した機能
`gem geocoder` を使って入力した住所から緯度、経度を取得。
Google API Keyを取得してアプリ上に地図表示。



#発生した問題
開発環境では問題なく動作していたがデプロイ後に本番環境で
動作チェックすると入力した住所に対して地図が表示されず何も返してくれなかった。


#推測してみた

コンソールをチェックすると`No Apikeys`、`Invalidkey`と出ていたので、APIキーが原因であると推測。

APIの知識が不足していたので開発環境で書いているコードの問題かGoogle APIの設定の方に問題があるのか？
と考えて深掘りしていくが解決出来そうな記事は見当たらず。


ちなみにAPIキーは`gem "dotenv-rails"`を使い、`.env`の中の環境変数に入れて`.gitignore`の中に隠してました。

Chromeの拡張機能であるGoogle Maps Platform API Checkerを入れてみると、
エラーの文字と、APIキーを入れたコードの一文が表示されているのを確認できたがAPIキー自体が見当たらない。

つまり環境変数が呼び出されていないということ。


#問題解決

ここでむやみやたらとググりまくると沼にハマる姿が目に浮かんだので（笑）
いったん落ち着いて考えてみることにしました。


**・・・もしかしてherokuにデプロイしてるのが原因かな？？**


ということでググってみるとこれがビンゴ！

**herokuでは.gitignoreに入っているファイルはデプロイされない**らしく
`heroku config:set`で環境変数をセットする必要があるとのことでした。

[[heroku] 環境変数の操作](https://qiita.com/colorrabbit/items/18db3c97734f32ebdfde)

こちらの記事を参考にさせていただきherokuに環境変数をセット。

無事解決できました！！！
MAMP, phpで多言語のcsvを読み込む際に、カンマごとにうまく取得できない時の確認箇所と解決方法

# MAMP, phpで多言語のcsvを読み込む際に、カンマごとにうまく取得できない時
グローバル時代を迎え、多言語対応のサイトやアプリを開発する機会が多い最近。mamp, phpで多言語のcsvを読み込む際に、カンマごとにうまく取得できない時があって悩んでいる方、
その方々に、試行錯誤を経て分かった方法を共有します。

## 環境の整理
- プログラミング言語：php
- サーバー起動：MAMP
- 対象言語：韓国語

##目的
assets/csv/にあるprofile.csv からデータを取得し、
１列ごとにphpの配列に格納したい。

例：
"성명"
"stage_name"
...

まず挙動を確認するため、var_dump()メソッドで表示を確認。

##CSV状況
![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/84d6faf3-0979-9b0f-60ff-b806a9972dae.png)

##phpファイル状況

```profile.php

if (($handle = fopen("assets/csv/profile.csv", "r")) !== FALSE) {
  while (($data = fgetcsv($handle))) {
    var_dump($data[0]);
  }

```

##ブラウザ表示状況
![bbb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/638df463-0144-02a1-bd6d-3d89cc722c2e.png)

＊目的と違って、１行目の３列分が取得される場合がある。"성명,본명,영어"

##原因
php.ini の文字コード設定にあった。

##解決方法
1. MAMP/conf/phpx.x.x(=>自分が使用しているphpバージョン) にあるphp.iniを開く
2. default_charset を"UTF-8"に変更する。（今回のように新しく追加してもいい）
3. mbstring.internal_encodingをUTF-8に変更する。（今回のように新しく追加してもいい）

    ```php.ini
    ;default_charset = "iso-8859-1"
    default_charset = "UTF-8"

    ;mbstring.internal_encoding = EUC-JP
    mbstring.internal_encoding = UTF-8

    ```

##php.ini変更後のブラウザ表示状況
![ddd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/f3bccb57-9737-e6c7-97a1-d4090d359db0.png)


＊今回は韓国語が対象になったが、他の言語を対応する際にも
　事前にMAMPの言語設定はUTF-8に設定してから進めた方が嵌らなくよいと思います。
Puma - Nignx って環境で rails s -e production -d でうまくいかない時の逃げ道

# 前提
EC2 に Rails6 + Puma + Nginxでデプロイしてて
かつ EC2にSSH接続したターミナルで

```
rails s -e production 
```
では問題なくサービスが表示されているのに

```
rails s -e production -d
```
ではエラー画面が表示されるだと？

#### ええ〜これじゃサービス起動させ続けるのにSSH接続しっぱなしじゃーん
という悩みを抱えたキミ向けだよ！

# 解決
Railsのルートフォルダにあるconfig/puma.rbに

``` config/puma.rb
daemonize
```
って追記するんだ！
これで

```
rails s -e production -d
```
では起動できないままだけど

```
rails s -e production 
```
これでデーモン化されるので解決だよ！

これじゃローカルでもデーモン化されて不便だろって人は

``` config/puma.rb
if Rails.env == 'production'
  daemonize
end
```
って書こうね！誰でも思いつく回避策だね！知ったげに書いてごめんね！

# 原因
完全に調べきったわけじゃないですが、私がネットサーファーになってgoogleの海を潜った結果、どうやら pumaで"rails s -d" でデーモン化すると puma.rbが読み込まれないみたいです。
rails s -e production -d で起動した際にNginxのエラーログにpuma.rbで設定しているsocketで接続できなかったよ！って記載されていますので、多分あってるんでないかなと思います。

### コイツはマズイぜ！という点があればご指摘ください！
Udemy 【MOS試験Excel対策オンライン講座【2013スペシャリスト】エクセル兄さんのスピードMOS対策・合格コース】レビュー

今回は私が2020年6月に三週間程かけて学習した
Udemy【MOS試験Excel対策オンライン講座【2013スペシャリスト】エクセル兄さんのスピードMOS対策・合格コース】定価：￥12600
について講評いたします。
講座URL↓
https://www.udemy.com/course/excelmos2013lite/


評価：〇
『セール中に買えば費用対効果あり』


まず、Udemyに関して説明します。
Udemyはオンライン学習サービスです。
短いチュートリアル動画を視聴していくタイプの学習法です。
前回レビューしたTechAcademyのように課題や添削、面談などはありませんが、
その分費用は安く、また指導者に質問をチャット的なツールで投げかけることもできます。
コースは13万種もあるらしく、IT系から教養まで多種多様です。
利用者はコースを選択し、購入します。
一度購入するとずっと視聴可能、いつ始めてもいい買い切り型で自由度は高いです。
その分、ただコースを学んだだけでは履歴書に書けるほどではない、箔はつかない学習法です。
あくまでもそのコースを通じて何か資格を取れたか。仕事に活かせたか。またはポートフォリオを充実させる事ができたかというのが肝になると思います。

本題ですが、
本講座は『Excel 2013』のマイクロソフト公認資格『MOS Excel2013　スペシャリスト』に合格することに焦点を置いた教材です。
このコースは短い動画が229、計17時間分の内容で、私は約三週間ほどで視聴し終えました。
実際手を動かした時間含めて一日二時間ペースで取り組んでいたと思います。
そのまた三週間後ぐらいにMOSを受験し、943/1000点で合格しました。
合格のボーダーラインはおよそ700点です。

・この講座は有用か？
　本コースの最も有益な点は『速習』です。
　このことはコース内でも述べられています。
　一発で覚えなくてもいいから、とりあえずどんなことやるのか、どんなことができるのか、どこまでが範囲なのか確認する、ザッと目を通す作業です。
　その後、試験問題集などを別に買い、それに付属している『模擬試験ソフト』にてくり返しテストに挑み、高得点を確実に取れるようにしていく。それが合格への流れです。
　実際、私も本コースを視聴しただけでは模擬テスト、不合格の600点台からギリギリの700点台をウロチョロするレベルでした。
　確実に合格するためには常に900点台を出せるようになりたいものです。
　後に購入した『模擬テストソフト』でくり返しテストに挑戦し、高得点をだせるようになりました。
　本コースでもこのやり方を推奨しています。
　
　つまり、合格のために本当に必要なものは『模擬試験ソフト』であって、本コースではありません。
　蛇足とまではいいませんが、本コースを一度目を通しただけでは合格できるかどうかは微妙です。
　模擬試験ソフトの付いている問題集は、大体2000円ほどします。
　MOSスペシャリストの受験費用は約1万円と高額です。
　本コースを購入した際の費用は、1万5000円～3万円と、人によってはかなり痛い出費です。
　人によっては本コースの購入を見合わせたくなるでしょう。

　しかしながらもしあなたがExcelの実務経験がなく、またどこかの教室などでしっかり教えてもらったわけでもなく、
　模擬試験ソフトのついている問題集のテキストを読み進めていくのと、本コースも合わせて取るのと、どちらが効率的でしょうか？
　私が思うに、
　テキストをなぞるのが苦手な方は、本コースをザッと視聴した方が内容が頭に入るし、効率的だと思います。
　人は、読んで覚える事が得意な方と、見て覚えるのが得意な方に分かれていると思います。
　動画では実際のやり方を何度でもくり返して見て確認することができるので、テキストよりも感覚的です。
　百ページ超に及ぶテキストに嫌気がさして途中でやる気が萎えてしまう方もおられるかと思います。
　私にとってはテキスト全部読むよりかは、本コースの動画をザッと見る方が、まだマシだと思えました。
　どちらの方が向いているかは皆さん自身がよく存じられていることかと思います。

・疑問、問題点
　本コースには以下の問題点があると思います。
　１・内容がかったるい
　２・バージョンが古い
　３・定価では内容に見合わない
　４・必ずしも必要ではない

　４の『必ずしも必要ではない』に関しては前述したので省きます。

・『内容がかったるい』について
　本コースは、本当にパソコン自体を触ったことのないような入門者でも分かるような解説をされています。
　文字入力に関しては、指で一本ずつ入力している始末です。
　MOS試験にのぞまれる多くの方は、ブラインドタッチ、もしくはそれなりに文字入力を普段からされている方だと思います。
　少なくとも私は、
　『もうわかってるって、そんなこと……』
　『その説明、半分の時間でまとめる事できたやろ！』
　と何度も心の中で毒づいていました。
　しかしたまに便利な小技の紹介も挟んでくるので、安易にスキップもできず……
　本コースを受けるにあたって必要なのは、忍耐や辛抱だと実感させられました。

・『バージョンが古い』
　Excel2013といえば、もう4、5年前に買ったパソコンについてきたようなバージョンで、古く感じます。
　現在の主流は2016年版、もしくはoffice2019、Microsoft365といった最新版でしょう。
　受験するのであれば新しいバージョンの試験に臨みたいと思うのが当然だと思います。
　私もMOS2013自体が、バージョンが古いという理由で敬遠されるかどうか心配です。
　ちなみにExcel2013の模擬試験のソフトを、それよりも新しいバージョンのExcelで起動させると、一部ファイルが開かなかったり、模擬試験中にエラーが出て中断する場合があります。
　皆さんがMOS試験を受けられる際は、ご自身の持つバージョンの試験に挑まれる方が無難かと思います。
　ちなみに、本コースでは2016年版を使用している方向けの補足も織り込まれています。

・『定価では内容に見合わない』
　パソコン教室に通うよりは安いですが、直接指導無しで12600円はかなり割高に感じます。
　ですがUdemyでは頻繁にセールをやっており、特に本コースはよくセール価格で販売されているような気がします。
　私もセール価格で購入しました。
　その時のお値段は『￥1380』　約90%OFFです。
　その値段ならば、転ばぬ先の杖として購入する価値は充分ありだと思います。


　まとめ
　◎　パソコン教室よりは安く、テキストよりも学習しやすい
　◎　直感的な教材で、よく頭に入る
　〇　便利な小技も教えてくれる
　〇　全範囲網羅できる
　〇　例題ファイルなども完備
　△　バージョンが古い（2016版へのフォローはある）
　△　合格に必要ではない
　✕　動画時間を半分にしてほしいほどかったるい
　✕　定価では絶対買わない

　結論
　テキスト読むよりも動画の方が頭に入るし、それだけのお金を出してもいい
　という方に向いているのではないでしょうか。

　以上、長文を最後までご覧いただき、ありがとうございました。
Lighthouseのreportが真っ白になった

### 症状
ある時から、Lighthouseのレポート画面が真っ白で内容が確認できなくなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/f1ef1223-e1c9-0ea8-8598-1a901fc58cd7.png)

### 原因
私の場合は[HTTP/2 and SPDY indicator](https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=ja)が原因でした。

### 対策
原因がわかっている場合は、[拡張機能](chrome://extensions/)から対象の機能を無効化すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/22c9b62e-66a4-cfe7-7b68-7a40ba3d1aa8.png)


不明の場合、シークレットモードで試すと、基本的に全ての拡張機能が無効化されているので切り分けやすいです。
【Swift】UIButtonをタップ（isHighlighted）した時にBackgroundColorを変更する

UIButtonのタップアクションに合わせて文字の色を変更するのは簡単ですが、背景の色を変えるのは少し面倒です。

```main.swift
// CustomButtonを作成する
@IBOutlet weak var button: CustomButton!
```
カスタムボタンのクラス

```swift
class CustomButton: UIButton {
    override open var isHighlighted: Bool {
        // ここでisHighlightedを元にbackgroundColorを設定する
        didSet {
            backgroundColor = isHighlighted ? .gray : .white
        }
    }
}
```

これでボタンのタップアクションに合わせて背景の色を変えることができます👌

##### 余談
もちろん同じ要領で`isSelected`の時も色の変更が可能。
プロジェクトでレイアウトを統一する時は共通コンポーネントとして用意しておくと便利ですね。
ブラウザの戻るボタンを押せなくする（ブラウザバック禁止）

既出だとおもいますが、勉強になったのでメモがてら。

表題通り、ブラウザバックさせないようにするためには、履歴を残さないようにすればOK。
`Location.replace()` を使えば、ページを移動した履歴が残らないとのこと。


html 内に書くなら、onclickを使って下記通り。

```html

<a href="javascript:void(0)" onclick="location.replace('https://xxxx')">ページをすすむ</a>

```


jsで書くなら下記通り。

```js
$('.class').on('click', function () {
  window.location.replace(指定のURL);
});

```




##■参照
http://www.htmq.com/js/location_replace.shtml
https://syncer.jp/javascript-reference/location/replace
IBM Cloud , Cloud Foundry でエラーが出たのですが

IBM Cloud のワークショップでエラーが出たとのことでいくつかご質問をいただきました。エラーの内容は
```
No space targeted. Use 'ibmcloud target -s SPACE' to target a space.
```
どうすればいいでしょうか？
エラーに書かれている様にSPACEを設定すればいいのです。どんなSPACEがあるかは次のコマンドでリストアップしてください。
```
$ ibmcloud cf spaces
```
SPACEが出てくるので
```
$ ibmcloud target -s SPACE名
```
でSPACEを指定してあげましょう。
もしSPACEがなかったら、次のコマンドでSPACEを作りましょう。
```
$ ibmcloud cf create-spece SPACE名前（任意）
```

ところでIBM Cloud のCloud Foundryが使えるのは現在（2020年8月）５カ所です。米国南部（us-east), 米国南部(us-south), 英国(eu-gb), ドイツ(eu-de), オーストラリア(au-syd)です。この場所を指定する時は
```
$ ibmcloud target -r 場所(例：us-south)
```
でできます。
なお無料のライトアカウントの場合は米国南部しか使えないのでご注意ください。
カレンダーのコンポーネントを作成する

## やったこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/f46d1291-35ff-d50c-e384-a8105064b579.png)
- カレンダーにて日付を選択できるコンポーネントを作成した

## ソース
https://github.com/simpliciter11/Power-Platform/tree/master/Power-Apps/CalendarComponent_1_0_0_1

## がんばったこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/068d043c-fe27-ab7d-5de7-c46325e52c34.png)
- 月を変更して、日付と曜日が調整されるようにした

## できなかったこと
- 月の初期値設定
- 日の初期値設定
    - OnStartやOnVisibleなどのプロパティが存在せず、変数に初期値が設定できなかった
    - やりようはあるかも
Qiitaに「user_creating_public_draft_items_countは10以下の値にしてください」で怒られる。

# エラー内容
Qiitaに記事を投稿しようとしたところ，「user_creating_public_draft_items_countは10以下の値にしてください」というダイアログが表示されて記事が投稿できなかった。
自動保存も正しく動いていない。

#解決策
一度下書きに保存してある記事をすべて削除して新規投稿として作り直した。
内容はローカルに保存しておきましょう。

自分で保存した内容の他に，自動保存された記事が下書きに大量に保存されていた。
VSCodeでマークダウンを書いてからコピペしていたので，それが原因かもしれない。
Kubuntuのインストールから初期設定

この記事は，基本的なKubuntu環境セットアップの個人的なメモを兼ねたチュートリアルです。
なるべく自分で設定することが少なくなるような環境を選択しています。

日本語入力とターミナルの設定を主に行います。
個人的な好みで設定しているので適宜読み替えてください。

ハード環境はThinkPad X1 Carbon 6th のUSキーボード仕様です。

# ディストリビューション(デスクトップ環境)
ディストリビューションはKubuntuを選択します。
デスクトップ環境はKDEで，ウィンドウマネージャはX Windowです。
Windowsライクで使いやすいと思います。

# インストール

isoファイルを[ここ](https://kubuntu.org/)からダウンロードします。
何かしらのツールでUSBに焼いてください。

起動順序を変えてUSBを指した状態で起動すると，Kubuntuが起動するのでインストールアイコンをクリックしてインストールに進みます。
デュアルブート時以外は，特に設定することもありません，案内に従ってインストールしてください。

USBを抜いて再起動，aptのアップデートをかけます。
その後，各ソフトを選択してインストールしてください。

```
$ sudo apt update
$ sudo apt upgrade
```

# HiDPI設定

サイズに対して解像度の大きいモニタを使っている場合，表示が小さすぎて読みにくくなります。

KDE設定の「ディスプレイとモニタ→ディスプレイの設定」からGlobal scaleを調整するとすべての要素が拡大されます。
解像度が2560x1440のノートパソコンの場合，倍率150%に設定するのがいいと思います。

# キーコンフィグ

個人的な好みで`Ctrl`は`A`の横に来てほしいので設定から`left Ctrl`と入れ替えます。
KDE設定から「入力デバイス→キーボード→詳細→Ctrl position→Swap Ctrl and Caps Lock」を有効化して，入れ替えることができます。

# フォント
和文フォントとして，Notoを選択します。
(Kubuntuではインストール済み)

プログラミング，コンソール向けの等幅フォントはHackGenNardを使用します。
[リリースページ](https://github.com/yuru7/HackGen/releases)から最新バージョンダウンロードし，`~/.fonts`に展開したttfファイルを配置して`$ fc-cache -fv`でインストールされます。

## 設定

KDE設定の「外観→フォント→すべてのフォントを調整」から`Noto Sans CJK JP`を選択してサイズを調整します。
これでシステムフォントがNotoになったはずです。

等幅フォントも`HackGenNard`ファミリーのうちどれかに変えておきます。

# ターミナル環境

ターミナル環境はyakuakeにFishを起動させています。

yakuakeはドロップダウン式の端末エミュレータです。
ホットキーを押すことで画面上部からターミナルが出てきます。

fishは，zshなど他の高機能シェルと異なり，無設定でプラグインを使わなくてもシンタックスハイライトなどの機能が最初から使えるユーザーフレンドリなシェルです。

`.bashrc`などにFishを起動させる設定を行うこともできますが，ログインシェルは残したいというのと，シェルスクリプトの書式が異なるのでデフォルトのシェル等は意図的に無設定で残しています。

## fish on yakuakeの設定

`sudo apt install yakuake fish`でインストールされます。

まずは，起動時にyakuakeが自動起動するように設定します。
1度yakuakeを起動して，トリガーキーを設定しておきます(デフォルトだとF12)。

KDE設定の「ワークスペース→起動と終了→自動起動→プログラムを追加」からyakuakeを検索して登録します。
再起動し，登録したキーを押して起動していることを確認してください。

次に，起動したyakuakeの右下の「閉じる」の横のボタンをクリックして幅と高さを好きなように調整してください。
同じところから「プロファイルの管理」に入ってfishの起動設定をします。

「New...」で新しいプロファイルを作り，「Edit...」で編集画面に入ります

「全般→コマンド」で`/usr/bin/fish`を設定してください。
これで最初からfishが起動されます。

「外観」でテーマをお好みに変えておくとよいです。
テーマを編集することで透明にすることもできます。

また，「Choose...」をクリックしてフォントを変えることができます。
ここでもHackGenを指定しますが，デフォルトでは出ないので`Show all fonts`を有効にして，`HackGen35Nard Console`を選択してRegularの12ptに設定します。

最後に，編集を抜けたプロファイル管理画面で「デフォルトにする」を押してyakuakeの設定は完了です。

今回，`Ctrl+Alt+T`ショートカットは残しているので，bashを使いたい場合はKonsoleを使用できます。

# 日本語入力環境

Fcitx-Mozcを使用します。
入力切り替えは`Ctrl + Space`の他に`Left Alt`を設定します。

Mozcでは日本語環境でのふるまいを調整します。

## Fcitx設定

Fcitx設定を起動して現在の入力メソッドに英語とMozcが登録されていることを確認します。

「全般の設定→Trigger Input Method」の「全半キー」になっているところをクリックして`Left Alt`を登録します。

## Mozc設定

Mozc設定を起動して，「一般」から句読点を「，。」に，スペースを半角に設定します。

「入力補助」から全角半角の設定をします。
文字グループのうち，アルファベット，数字，「(){}[]」，「#\$&2@$^_|`\」の変換前文字列を半角に設定します。

# まとめ

この他に，メモリが足りない場合にはスワップ領域の拡張を行ってください。

おすすめの設定や環境があれば，教えてください。
PythonとGDALを使ってウェッブマップを作ろう

オープンソースのPythonとGDALを使って無償でGISデータを処理する方法を紹介します。今回使用するデータは国土地理院が提供している<a href="https://fgd.gsi.go.jp/download/menu.php">基盤地図情報</a>の数値標高モデル。

[![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677829/523a02a2-b6b5-6a22-c7b2-76773c887a27.png)](https://danielhoshizaki.github.io/hillshade/)

PythonとGDALの組み合わせで上記のウェッブマップが作成されます。

#### インストール
まずは<a href="https://docs.conda.io/en/latest/miniconda.html">Miniconda</a>を使ってPythonと必要なライブラリをインストールしましょう。ダウンロードが完了したと後はMinicondaのコマンドラインを開きPythonの仮想環境を立ち上げます（デフォルトのPython3バージョンを使用）：

```
conda create --name myenv
conda activate myenv
```

次にPythonのスクリプトに使用するライブラリをインストールします：

```
conda install -c conda-forge gdal numpy beautifulsoup4
```

最後にウェッブマップ作製に使用するPythonのスクリプトをダウンロードします：

```
git clone https://github.com/danielhoshizaki/hillshade
```

#### 使い方
まずは```./data/raw```ディレクトリに数値標高モデルファイルがあることを確認しましょう。他のファイルをダウンロードしている場合はこの段階で```./data/raw```の中に置きます。

Pythonスクリプトを回す前にコードの一部を変える必要があります。```conda```でインストールしたライブラリGDALのパスを指定する必要があります。GDALは協力なソフトですがインストールが非常に複雑である為今回は絶対パスを使いましょう。GDALのバイナリーを探すにはLinuxの```find```を使うかWindosの検索ボックスを使います。上記で作成したmyenv仮想環境のディレクトリを探せばすぐに出てきます。探すのはgdaldem.exeとgdalbuildvrt.exeが入っているはディレクトリとgdal2tiles.pyが入っているディレクトリ。見つけたらPythonスクリプトのgdal_bin_pathとgdal_tiles_pathを設定します。

準備が整ったらスクリプトを起動してウェッブマップが出来るのを待ちます。

#### 仕組み
Pythonスクリプトは大きく分けて二つの役割を果たしています。一つは```convert```と言うファンクションを使って生の数値標高モデルファイル（ZIPされたXMLファイル）をGeoTiffに変換すること。二つめの役割はコマンドラインを通してGDALに直接データを処理してもらうこと。GDALに直接流すコマンドは三つあります以下のデータ処理が行われます：

1. 各DEMのGeoTiffを陰影起伏GeoTiffに変換
2. 全ての陰影起伏GeoTiffをバーチャルデータセットvrtにまとめる
3. バーチャルデータセットをウェッブマップに変換

最後に回すgdal2tilesコマンドは新規に```./data/WTMS```ディレクトリを作ります。ディレクトリの中にはLeaflet.htmlと言うファイルがあるのでダブルクリックをしましょう。独自のウェッブマップが完成です！ただしこのウェッブマップは自分のPCで見ることしかできません.. 他の人にも見てもらい場合はGithub PagesやAWS S3に乗せるかもうちょっと頑張ってウェッブサバーに乗せてみましょう！