OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】EC2のSSHログイン時に環境を知るためのアスキーアートを表示する

# やったこと
EC2にログインした時に、ステージング環境、本番環境のどちらにログインしたかを表示させたかったので、アスキーアートを表示させるようにしました。

以下のような表示になります。
![20181013130552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/fb400b10-3682-9f09-c263-7a52579e1364.png)


# やり方
以下のコマンドで、EC2へログインした時の表示メッセージが管理されているディレクトリへ行きます。

```
$ cd /etc/update-motd.d/
```
ここがEC2へSSHした時に表示させるメッセージを追加する場所になります。

このディレクトリ内にはいくつかファイルがあり、SSHした時にはファイル名先頭の数字の昇順に表示されていくことになります。

```
$ ls
30-banner  70-available-updates  75-system-update
```

30-bannerの中身を覗くと、よく見るあの表示が出てきますね。

```
$ cat 30-banner
#!/bin/sh
version=$(rpm -q --qf '%{version}' system-release)
cat << EOF

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/$version-release-notes/
EOF
```

## メッセージを追加する
それでは、メッセージを追加しましょう。
アスキーアートをフリーで作成できるサイトはググって見つけます。


今回は30-bannerの次に表示させたいため、40-environmentというファイルを作ります。

```
$ sudo vi 40-environment
```

以下を記述。

```
#!/bin/sh
cat << 'EOF'
                                  ■■
         ■■                       ■■
         ■■
         ■■
 ■■■■■ ■■■■■■■  ■■■■■■   ■■■■■■■  ■■  ■■ ■■■■  ■■■■■■■
■■       ■■          ■■ ■■■  ■■■  ■■  ■■■  ■■■■■■  ■■■
■■       ■■          ■■ ■■    ■■  ■■  ■■    ■■■■    ■■
■■■■■    ■■      ■■■■■■ ■■■  ■■■  ■■  ■■    ■■■■■  ■■■
  ■■■■   ■■     ■■■  ■■  ■■■■■■   ■■  ■■    ■■ ■■■■■■
    ■■   ■■     ■■   ■■  ■        ■■  ■■    ■■ ■
    ■■   ■■     ■■  ■■■  ■■■■■■   ■■  ■■    ■■ ■■■■■■
■■■■■     ■■■■   ■■■■■■      ■■■  ■■  ■■    ■■     ■■■
                              ■■                    ■■
                        ■    ■■■              ■    ■■■
                        ■■■■■■                ■■■■■■
EOF
```

以下コマンドで権限を変更し、メッセージを更新します。

```
$ sudo chmod 755 40-environment
$ sudo update-motd
```

## 再度SSH
![20181013130552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/fb400b10-3682-9f09-c263-7a52579e1364.png)
無事に表示されました！
これで意図していない環境で作業してしまうのも防ぎやすくなりますね。

## 参考サイト
https://dev.classmethod.jp/cloud/aws/motd-ec2-name
周波数伝達関数G(jω)のs=jωとする理由

#私が疑問だったこと
社会人になって初めて制御工学を知り、研修中に制御の基礎を教えてもらったのですが
「ラプラス変換して、$s = j\omega$とおいて・・・」
「ボード線図がこうで・・・」
「帯域が・・・」
「安定にするには・・・」
みたいなよくある話があったわけですが、正直、$s = j\omega$の意味が謎すぎて、その場で思考停止してしまいました。

大学でやってた人に聞いて、「フーリエ変換になってるやろ？」とか言われても、「今は制御の話をしているんだぞ？」となって疑問が増えるだけでした。入力と出力の話をしているのにフーリエ変換を急に持ち出されてもね・・・きっとフーリエ変換をちゃんと理解している人には疑問ではないのでしょうが。

ここでは、制御屋さんらしく、入力と出力を見て$s=j\omega$として$G(j\omega)$を使う理由を求めたいと思います。

#本記事の目標
$s = j\omega$で何を求めているのか理解することを目標にします。
結論から言うと、$s = j\omega$とすることで、正弦波を入力したときの定常応答を求めることができています。実際に確かめていきましょう。

#導出

入力

$$u(t)=A\sin\omega t$$


正弦波のラプラス変換を思い出して

```math
\begin{align}
U(s)&=L[u(t)]   \\
&=L[A\sin(\omega t)]   \\
&=\frac{A\omega}{s^2+\omega^2}
\end{align}
```



伝達関数$G(s)$として出力のラプラス変換を求めてみよう

```math
\begin{eqnarray}
Y(s)&=&G(s)U(s)\\
&=& G(s) \frac{A\omega}{s^2+\omega^2}
\end{eqnarray}
```

$G(s)$が安定なシステムだと、安定極$p_i$を持っているはずなので

```math
\begin{eqnarray}
Y(s)&=&\frac{c_1}{s-p_1}
+\frac{c_2}{s-p_2}+\cdots+\frac{c_n}{s-p_n}
+\frac{d_1}{s+j\omega}+\frac{d_2}{s-j\omega}
\end{eqnarray}
```

出力信号の時間応答は

```math
\begin{eqnarray}
y(t)&=&L^{-1}[Y(s)] \\
&=&c_1e^{p_1t}+c_2e^{p_2t}+\cdots+d_1e^{j\omega t}+d_2e^{-j\omega t}
\end{eqnarray}
```

十分時間がたった時の定常応答は

```math
\begin{eqnarray}
y(t)&=&d_1e^{j\omega t}+d_2e^{-j\omega t}
\end{eqnarray}
```

$d_1$と$d_2$はヘビサイドの展開定理で

```math
\begin{align}
d_1 &=\left. \frac{G(s)A\omega}{s+j\omega} \right|_{s = j\omega}    \\
d_2 &=\left. \frac{G(s)A\omega}{s-j\omega} \right|_{s = -j\omega}
\end{align}
```

となるので

```math
\begin{eqnarray}
y(t)&=&A
\left\{
\frac{G(j\omega)}{2j}e^{j\omega t} 
- \frac{G(-j\omega)}{2j}e^{-j\omega t} 
\right\}
\end{eqnarray}
```

極座標で書くと

```math
\begin{align}
G(j\omega ) &=|G(j\omega )|e^{j\theta}    \\
G(j\omega ) &=|G(-j\omega)|e^{-j\theta}
\end{align}
```

$\theta = \angle G(j\omega)$



```math
\begin{align}
y(t) = |G(j\omega)|A
\left\{
\frac{e^{j(\omega t+\theta)}}{2j}
-\frac{e^{j(-\omega t+\theta)}}{2j}
\right\}
\end{align}
```

オイラーの公式を思い足して

```math
\begin{align}
y(t) = |G(j\omega)|A \sin(\omega t+\theta)
\end{align}
```

となります。どんな入力をしていたか$$u(t)=A\sin\omega t$$と比べると出力$y(t)$の振幅が
$$|G(j\omega)|$$
だけ大きくなっていて、位相が
$$\theta = \angle G(j\omega)$$

だけずれた出力が出てきている。よって、$G(s)$がわかっているときには正弦波を入力したときの定常応答が$s=j\omega$とした周波数伝達関数$G(j\omega)$でわかる。

#最後に
これで今度からはこの計算をしなくても、$s=j\omega$とした周波数伝達関数$G(j\omega)$で正弦波を入力したときの定常応答を求めることができるわけだ。ボード線図に書いてあるのはこれだったんだなー
韻を扱いたいpart7（BOW）

##__内容__
これまでとはちょっと違ったことをしてみる。テキストの分割方法に頭を悩ましていたが、母音「aiueo」の一致を見るのであれば、母音を様々に並べ、その母音が文章中に出てきたかどうかを示すことで、文章同士を比べられるのでは？という考えのもとやってみる。つまり、「出現頻度を気にせず、各単語が出現したかどうかのみに着目する」バイナリ表現という方法の各単語を母音の様々な並びにする。
##__様々な母音の並びを単語に見立てたword_listの作成__

```python
from pykakasi import kakasi
import re
import numpy as np
import pandas as pd

with open("./gennama.txt","r", encoding="utf-8") as f:
    data = f.read()

vowel_list = ["a","i","u","e","o"]
#単語リスト。母音のみ使ってできる2文字から4文字の単語。775種類
word_list = []
for i in vowel_list:
    for j in vowel_list:
        for k in vowel_list:
            for l in vowel_list:
                    word_list.append(i+j)
                    word_list.append(i+j+k)
                    word_list.append(i+j+k+l)                    

text_data = re.split("\u3000|\n", data)
kakasi = kakasi()
kakasi.setMode('J', 'a')
kakasi.setMode('H', 'a')
kakasi.setMode('K', 'a')
conv = kakasi.getConverter()
vowel_text_list = [conv.do(d) for d in text_data]
vowel_text_list = [re.sub(r"[^aeiou]+","",text) for text in vowel_text_list]
```

以外にあっさりしたものである。単語の種類も755とそこまで多くない。これまでの経験則で、5文字以上の母音の一致はごく稀であるため、4文字までとした。今までは様々な辞書を作成していたが、DataFrameにまとめてみる。
##__DataFrame作成__

```python
df = pd.DataFrame({"文章": text_data, "母音": vowel_text_list})
#カラム名"aa"等で、文章中に出現したら１、しなければ０
binaly_dic = {}
temp = []
for word in word_list:
    for vowel in vowel_text_list:
        if word in vowel:
            temp.append(1)
        else:
            temp.append(0)
        binaly_dic[word] = temp
    temp = []

for k, v in binaly_dic.items():
    df[k] = v
df.to_csv("df_test.csv")
```

カラムは「文章、母音、単語…」とし、「文章」には元のテキストデータを分割した文章、「母音」にはそれを母音のみに変換したもの、「単語…」にはその単語が文章中に入っていれば1、入っていなければ0をそれぞれ与えた。
##__活用例__

```python
#コサイン類似度        
def cosine_similarity(v1, v2):
    cos_sim = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
    return cos_sim

print(cosine_similarity(df.iloc[0, 2:].values, df.iloc[3, 2:].values))
```

例えばこのようにして、文章0と文章3の類似度を表示させる。他にも`sum`を使って、どの単語が一番共通して使われているか、等もすぐに分かる。
##__まとめ__
母音のみに着目しているので、2～4文字で全ての組み合わせを考えても単語数755に抑えられた。これまで文章を分割して取り扱おうとしていたが、そのままでも出来ることがあった。自分の中で大きな出来事なので、内容が薄いが記事にした。今後は文章の類似度からさらに何か処理をしたり出来ないか等、作ったDataFrameを元にやっていこうと思う。
SECCON Beginners CTF 2020 Writeup

yharimaとして参戦。序盤は上位にいたものの後半とけねーとなり21位でフィニッシュ。

## readme
読み込めるファイルに制限があるスクリプトを攻略する問題。`/home/ctf/flag`にフラグがあるもののファイルパスに`ctf`が含まれていると実行できない。

それを回避するためにうまくフラグのあるディレクトリにアクセスできないかを考え、`/proc`で動いているプロセス自身の情報を利用してファイルを読み込む。
実行プロセスのカレントディレクトリが`/home/ctf/server`らしいということが環境変数をみるとわかったのでそれを使うとフラグが取れた。

```
$ echo /proc/self/environ | nc readme.quals.beginners.seccon.jp 9712
File: ...PWD=/home/ctf/server...
$ echo /proc/self/cwd/../flag | nc readme.quals.beginners.seccon.jp 9712
File: ctf4b{m4g1c4l_p0w3r_0f_pr0cf5}
```

## mask
入力した文字列に定数をマスクして、その値がプログラム内に埋め込まれた文字列に合致するかを判定するバイナリを解析する問題。入力する文字列がフラグになるのでそれを突き止める。

aからzの文字を入力して以下のような換字表を作り、埋め込まれた文字列も持ってきて人力でフラグを取った。

```
abcdefghijklmnopqrstuvwxyz
a`adede`a`adedepqpqtutupqp
abc`abchijkhijk`abc`abchij

ctf4b{dont_reverse_face_mask}
atd4`qdedtUpetepqeUdaaeUeaqau
c`b bk`kj`KbababcaKbacaKiacki
```

## yakisoba
入力した文字列をいろいろ処理して条件にあっているかどうかを判定するプログラムが渡される。めんどくさかったので[angr](http://angr.io/)で自動処理。

まずは正解のメッセージが出力される処理の実行アドレスを突き止める。そして[angrのGithubのトップ](https://github.com/angr/angr)にあったコード持ってきてアドレスをちゃちゃっと書き換え実行するとフラグが出てくる。

```python
import angr

project = angr.Project("./yakisoba", auto_load_libs=False)

@project.hook(0x4006d9)
def print_flag(state):
  print(state.posix.dumps(0))
  project.terminate_execution()

project.execute()
```

## ghost
GhostScriptのソースコードが渡される。実行すると標準入力から文字列が読み込まれ、文字列が数値に加工される。問題ファイルには加工後の文字列が記された`output.txt`が渡されるので、その値になるように入力する文字列を特定する問題。

GhostScriptを調べて他の言語に置き換えるのもいいが、あまりドキュメントもなくめんどくさくなったのでブルートフォースで解析。


```python
from pwn import *

def check(flag):
  p = process('gs chall.gs', shell=True)
  p.sendline(flag)
  p.recvline()
  p.recvline()
  p.recvline()
  r = p.recvline().decode('utf-8').strip()
  p.close()
  return r

worddic = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_}!?.,-/'
flag = 'ctf4b{'

found = True
with open('output.txt') as f:
  l = f.read().strip()
  for i, s in enumerate(l.split(' ')):
    if i < len(flag):
      continue
    if not found:
      print('Ooooops...')
      break
    found = False
    for c in worddic:
      r = check(flag + c).split(' ')[-1]
      if r == s:
        flag += c
        found = True
        break

print(flag)
```

## sneaky
スネークゲームをするプログラムが渡される。問題文を読むと高得点取るとフラグらしい。

真面目にやっても仕方ないのでバイナリ解析して得点を管理する部分を突き止め初期得点を書き換える。

![sneaky](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5804/7b30695c-35e2-0e3e-66f3-ed34b3e166ca.png)
画像のように0x04007d0が初期得点を入れる命令なので、そこを高得点に書き換えて実行するとフラグが出力される。
機械学習における正則化の意味を分かりやすく説明する

# はじめに
機械学習（ディープラーニング含む）に触れたことがある人であれば、正則化という言葉を一度は耳にしたことがあるでしょう。英語ではregularizationと言います。

一般的には、機械学習において過学習を防ぐための手法であると説明されています。さらに、損失関数を含んだ数式とともに、L1正則化やL2正則化などの正則化の具体的手法についても紹介されていることが多いです。ただ、そもそも過学習についてや、正則化を使うとなぜ過学習を防ぐことができるのかについて、イメージとともに分かりやすく説明されているものをあまり見たことがありません。

この記事では、機械学習における正則化の意味をイメージとともに分かりやすく説明します。あくまでも正則化の意味のイメージを掴むための記事なので、数式はあえて書きません。

# 過学習とは？
正則化の説明の前に、過学習について説明します。

例として、部屋の広さからマンション価格を推定する問題を考えます。マンション価格には部屋の広さ以外にも場所、駅までの距離、築年数なども影響しますが、考えやすいように説明変数を部屋の広さ一つにしています。

そして、学習データが6件あり、グラフにプロットすると次のようになったとします。横軸が部屋の広さ、縦軸がマンション価格です。

<img width="300" alt="スクリーンショット 2020-05-31 18.08.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127582/5a1b79f1-952c-c699-1ffb-025dcb303d4c.png">

ここで、正則化を使わずに線形回帰分析などでマンション価格を推定すると、回帰式は次のような形になり得ます。

<img width="300" alt="スクリーンショット 2020-05-31 18.14.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127582/dda0e9fc-a956-90de-6841-d97c9d038e54.png">

ただ、この回帰式の形状は明らかにおかしいです。例えば、部屋の広さが狭い場合にマンション価格が極端に安くなっており、また、部屋の広さが広い方が値段が安くなっている箇所があります。

なぜ、回帰式がこのような形になったかと言うと、学習データに引きずられすぎているからです。言い換えると、学習データを過学習しているということです。つまり、過学習とは学習データを過剰に学習した結果、汎化能力に欠ける状態になっていることを意味します。

# 正則化を使うとどうなる？
正則化をうまく使うと、前記の回帰式の形状は次のようになります。「うまく」と書いたのは、正則化の中で使うパラメータを適切に設定する必要があるからです。

<img width="300" alt="スクリーンショット 2020-05-31 18.54.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127582/916e9a53-560e-2263-90c1-4821be6841aa.png">

この回帰式の形は直感と一致する結果になっています。これより、正則化を使うことで過学習を防ぐことができたと言えるでしょう。

正則化について詳しくは説明しませんが、回帰式が複雑な形状になった場合にペナルティを設けることで、回帰式をなるべくシンプルな形状に保つというテクニックの一つだと考えて下さい。

# 最後に
本記事では、機械学習における正則化の意味をイメージとともに分かりやすく説明しました。正則化の具体的手法や数式を確認したい場合は、応用数理学会に掲載された[過学習と正則化](https://www.jstage.jst.go.jp/article/bjsiam/28/2/28_28/_pdf/-char/ja)というチュートリアル論文をご覧下さい。正則化の具体的手法や数式が分かりやすく説明されています。
rails6でデータベースを変更した話



これまではMySQLを使用していましたが、本番環境を考えてPostgreSQLに変更しました。

ググって、**SQLite→MySQL or PostgreSQL**の変更方法は出てくるのですが、
**MySQL→PostgreSQL**の変更方法は、ネットになかなか落ちていませんでした。

そんなとき、webpack周りで躓いた際に参考にした記事を思い出しました。
[Ruby on Rails 6の主要な新機能・機能追加・変更点](https://qiita.com/ryohashimoto/items/622c3bcfb3336cb9317e)

##どうやらrails6では簡単に変更出来るらしい

```terminal:ターミナル
bin/rails db:system:change
```

上記で行けるみたい。
rails6からは**RDBMSを変更するdb:system:changeタスクが追加された**とのこと。

ちなみにMySQLとSQLiteへの変更の仕方は以下の通り
[Rails6「SQLite ⇆ MySQL ⇆ PostgreSQL」データベースを移行(変更)する方法](https://o9sec.com/2019/09/14/3615/)

```terminal:ターミナル

#MySQLに変更
rails db:system:change --to=mysql

```

```terminal:ターミナル

#SQLiteに変更
rails db:system:change --to=sqlite3

```


##実際にやってみる
```terminal:ターミナル
#--to=*********で変更したいDBを指定する
bin/rails db:system:change --to=postgresql

```

```terminal:ターミナル

Overwrite /Users/environment/アプリ名/config/database.yml? (enter "h" for help) [Ynaqdhm]

```
上記で、「上書きしますか？」と出るので、**y**を記入

```terminal:ターミナル
Overwrite /Users/environment/アプリ名/config/database.yml? 
 (enter "h" for help) [Ynaqdhm] y
       force  config/database.yml
        gsub  Gemfile
        gsub  Gemfile

```

**これで変更完了。**
SQLite→MySQLに変更した際は、**bin/rails db:system:change**を知らなかったので
database.ymlを自身で書き換えたりと少々めんどくさかった。

基本DBは変更しないほうがいいと思いますが、
rails6になってDBは簡単に変更出来るようになったよって、
話でした。

ではでは。
VSCode は素晴らしいが CPU使用率100% 以上使ってしまう問題

VSCode 便利ですよね。
自分は最初IntelliJ使っていたのですが、VSCodeが盛り上がってきたので乗り換えました。

フリーで使えて言語によってIDEをかえる必要もなくなり、ものすごく満足しています。

### VSCode はフリーで使えるIDEとしては歴代最高水準（個人的に）

（別に自分が今更絶賛することではないのですが）

- 高速に動作
- 多くの言語をサポート
- 豊富なプラグイン
- 活発なコミュニティ

### そんな最高な IDE ですが、時にはPCのリソースを食い潰します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/08d2d585-40d0-2b30-f52b-e869d5a29801.png)

VSCode は メモリ、CPUを出来る限り使って高速な動作を実現しています。
それはそれでよいのですが、性能が限界に達するとPCごと重くなります。

例えば、Idea の IDE は、実行環境であるJVMに上限が設定されているため、
重くなると 自分で上限を設定する必要があります。


### 問題がおきる背景

VSCode は、整形、補完、バリデーションを行うためにファイルを監視しています。
その仕組みが、CodeHelper というプロセスです。

Code Helper はファイルを監視しています。

そのため、ファイル数が増えると、それに応じてCPU,Memory の消費量がどんどん増えていきます。
CPUリソースが枯渇しはじめるとエディタのレスポンスが悪くなっていきます。

### 対策

Node のプロジェクトは、nodemodules のなかに大量のファイルがあります。
そういったファイルは標準の設定で監視対象から外されています。

ただ他のも Amplify, Create React App や Nuxt.js などを使うとビルドファイルが生成され、
そういったファイルも監視対象から外す必要があります。

Code->設定-> 基本設定

を開き、

files.watcherExclude で検索しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/5dbdd38a-8ea5-3676-6b02-9b15ff46d418.png)


ユーザのパターンを追加で

```
"**/build/**"
```

などを追加することができます。


### チームに共有しよう
チーム開発をしている場合は上記の対応を開発車全員に共有する必要があります。files.watcherExclude はフォルダ単位でも設定することでき、
その内容を共有することができます。

フォルダ単位で設定した内容は下記に保存されます。

```
project/.vscode/setting.json
```

このファイルを commit & push すると、そのブランチを pull したユーザの環境にもその対応を追加することができます。

### VSCode はやっぱりすごい。

設定しないと重くなってしまうとはいえ、自分で設定し、さらにそれをチームに共有できる、設定ファイルもわかりやすい、という意味ではやっぱりすごいIDEだなと思います。

この情報も[issue](https://github.com/microsoft/vscode/issues/51776)で議論されたものを参考にしたものです。
対応策がみんなで議論されていました。

今後のバージョンアップで標準設定ファイルも改善されていくと思います。
C++ STLコンテナの非const dataメンバ関数

最近のC++では`vector`や`string`に非constの`data`メンバ関数があります。後方互換性に捕らわれない限り、メモリのアドレスを取得するために`&v[0]`のような表現は不要になりました。

# スコープと動作確認環境
- C++17、Standard Template Library（STL）。
- Windows 10、Visual Studio Community 2019 Preview（Version 16.7.0 Preview 1.0）、C++言語標準はstd:c++17。

# 非const dataメンバ関数
C++17ではSTLコンテナや文字列クラスの`data`メンバ関数に非const版が実装されています。以前は`&v[0]`のようなコードを書いていましたが、今後は`data`メンバ関数を使用できます。

```cpp
#include <vector>
#include <string>

using namespace std;

int main()
{
	std::vector<int> {0, 1, 2, 3, 4};
	std::wstring s = L"abcde";

	auto pv = v.data();
	auto ps = s.data();
	// 以前はこの書き方だけでした。
	// auto pv = &v[0];
	// auto ps = &s[0];

	pv[2] = -1;  // v = {0, 1, -1, 3, 4}
	ps[2] = 'X'; // s = L"abXde"

	return 0;
}
```

# `std::data`の利用
固定長配列等にも共通のインターフェイスを与えるため、`data`関数テンプレートが利用できます。STLコンテナを使う関数テンプレートの作成時はこちらが適切かもしれません。

```cpp
#include <vector>
#include <string>

using namespace std;

int main()
{
	vector<int> v {0, 1, 2, 3, 4};
	wstring s = L"abcde";

	auto pv = data(v);
	auto ps = data(s);

	pv[2] = -1;  // v = {0, 1, -1, 3, 4}
	ps[2] = 'X'; // s = L"abXde"

	return 0;
}
```
Pythonでローグライクゲーム作ってみた

# 概要
pythonの言語勉強としてローグライクのサンプルゲームを作成しました。
[GitHubにプロジェクトを公開](https://github.com/becky3/python_dungeon_game_sample)していますので、その紹介記事となります。

こちらは、廣瀬 豪さん著「[Pythonでつくるゲーム開発 入門講座](https://amzn.to/2ZNCgps)」の題材となっている、本格RPGのサンプルゲームをベースとして、ゲーム内容の調整やオブジェクト指向の取り入れ等を行った物となります。

なのでコードを確認する前に一旦こちらの入門書を終わらせておくと、内容が理解しやすいかも知れません。

プロジェクトの詳細な説明については、GitHubの `readme` をご参照ください。

## プレイ動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/MsCe81pIWYY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 環境
- OS：Windows 10
- Python：3.7.4
 
## 利用ライブラリ
### pygame 1.9.6
pythonで2Dゲーム制作を行う際に便利なライブラリ
https://github.com/pygame/pygame/

### numpy 1.18.4
配列の利用にちょっと参照した程度。 単に使ってみたかったので入れました。

https://numpy.org/

# オリジナルからの主な変更点
オリジナルのRPGは戦闘シーンがドラクエ風対面式バトルとなってましたが、マップ上でシームレスにバトルができる仕組みへと変更してます。
また、GitHubへ公開するに当たり、リソース類をすべて自作のものに差し替えています。

以下、主な変更点です。

- オブジェクト指向で制作
- クラス単位でファイル分割
- バトル方式を対面式からシームレスタイプに
- ゲームの進行にシーンとタスクの手続き導入
- 移動のアニメーションをスムーズに
- 画像描画手続きをカメラを用いた構造に変更
- リソース類の置き換え

# 利用したツール
## MusicStudio (作曲)
https://apps.apple.com/jp/app/music-studio/id328608539

iPadで作曲ができるDAWアプリです。 Winで気軽に使えるDAWになかなか巡り会えず、5年前くらいに買ってほぼ放置していたアプリを引っ張り出してきました。
Serverモードという、ブラウザからアクセスしてファイルを直でダウンロードできる機能がなかなか良い。

## KanaWave (効果音)
https://www.vector.co.jp/soft/win95/art/se232653.html

ひらがなで効果音が作成できるフリーウェアのツールです。　ちょっとした効果音をサクッと作りたいときにすごく重宝してます。
## Audacity (効果音調整)
https://forest.watch.impress.co.jp/library/software/audacity/

音声波形編集ツールで、こちらもフリーウェア。　音声ファイルの音量調整や、wav → ogg 変換等に利用しました。

## Aseprite (ドット絵)
https://store.steampowered.com/app/431730/Aseprite/?l=japanese

ドット作成ツールです。　STEAMのストアで購入しました。　アニメーションの確認ツールなども含まれており、かなり本格的なツールですが、ちょっとしたドットを書きたい時でも、ストレスなく簡単に使えて良いです。


# 参考書籍
今回の題材としたこちらの書籍ですが、
とにかく実践的な内容で、細かい言語仕様の解説よりまずは手を動かしてものを作っていくスタイルとなっていました。
最終的には今回参照した本格RPGに、落ちものパズル等、結構ガッツリしたゲームの作成解説があり、プログラミング楽しみながら覚える入門書として、すごく優れている本だと思います。
逆に、Pythonの言語仕様については解説が少なめなので、この本でコードを書くという事になれたら、別の入門書で保管する流れが良さそうです。

**■ Pythonでつくるゲーム開発 入門講座**
https://amzn.to/2ZNCgps
[![image](https://images-na.ssl-images-amazon.com/images/I/515CbwaQfAL._SX394_BO1,204,203,200_.jpg "Pythonでつくるゲーム開発 入門講座")](https://amzn.to/2ZNCgps)

# GitHub
https://github.com/becky3/python_dungeon_game_sample

# 感想

Pythonの勉強のために、軽くリファクタリングをしながら、2～3日で終わらせるつもりが、ゲームエンジン部の作り込みにハマってしまい、いつの間にか2週間規模の作業となってしまいました。

IDEはVSCodeを使ったのですが、デバッグ実行等もでき、軽くならリネームも効いて、かなり開発が行いやすかったです。
また、lintライブラリとして、pylintとflake8を使ったのですが、これらのおかげでpythonの一般的なコーディングルールが学べました。
新しい言語を勉強する際はとりあえずlintを入れるというのはかなり有効ですね。

ある程度汎用的に利用できる直前くらいまでは作り込めたと思うので、今回の学習を活かして、今後スマホで同様のアプリを作ってみるなり何らかの展開が見せていければ良いなと思っています。
C++ STL イテレーターのRange access（std::begin等）の概要と一覧

Q.`std::begin`とか`std::data`って何のためにあるの？
A.テンプレート機能を利用してSTLコンテナ、固定長配列、初期化子リスト等に共通の機能を提供するため。

# スコープと動作確認環境
- この記事ではC++20のStandard Template Library（STL）について扱います。
- サンプルコードの動作確認環境はWindows 10、Visual Studio Community 2019 Preview（Version 16.7.0 Preview 1.0）でC++言語標準をstd:c++latestとした状態です。
- 未確認ですがC++17も対応していると思います。

# まえがき
STLはC++の標準ライブラリの一部であり、よく使う機能をクラスや関数テンプレートで提供する軽量なライブラリです。このノートでは`std::begin`、`std::data`等の目的と使い方を紹介します。個人的な目的は規格案やSTLの学習なので、不適切な部分があれば指摘いただけると嬉しいです。

# イテレーターのRange access
## 概要
STLには`std::begin`や`std::data`といった`std::vector`のクラス関数と同名の関数テンプレートが定義されています。これらは`std::vector`のようなSTLコンテナクラスだけ使用する場合は不要ですが、固定長配列（`T x[N]`）や初期化子リスト（`std::initializer_list`）に対して同様の機能を提供したい場合に役立ちます。

C++20規格案では[23.7 Range access](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf#page=957)に定義されています。

## 一覧
[23.7 Range access](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf#page=957)で定義されたイテレーターのRange accessの一覧です。以下の関数は関数テンプレートおよび特殊化によりSTLコンテナクラス、固定長配列、初期化子リストに対して使用できます。

|関数|概要|
|:--|:--|
|std::begin|最初の要素|
|std::end|最後の要素|
|std::cbegin|最初の要素（const）|
|std::cend|最後の要素（const）|
|std::rbegin|末尾から最初の要素|
|std::rend|末尾から最後の要素|
|std::crbegin|末尾から最初の要素（const）|
|std::crend|末尾から最後の要素（const）|
|std::size|符号なしバイトサイズ|
|std::ssize|符号付きバイトサイズ|
|std::empty|空判定|container.empty()|
|std::data|内部メモリのポインタ|

## サンプルコード
次のコードで`std::cbegin`、`std::data`、`std::size`がSTLコンテナ、初期化子リスト、固定長配列に対して同様の機能を提供すること、`std::list`のようなデータが不連続なSTLコンテナに対しては`std::data`が提供されないことを確認できます。

```cpp
#include <iostream>
#include <string>
#include <list>
#include <vector>
// STLコンテナクラスを使用する場合はインクルードされるので不要です。
// #include <iterator>

int main()
{
	std::wstring s = L"abcde";
	std::vector<int> v = {0, 1, 2, 3, 4};
	std::list<int> l = {0, 1, 2, 3, 4};
	int a[5] = {0, 1, 2, 3, 4};
	std::initializer_list<int> il = { 0, 1, 2, 3, 4 };

	std::wcout << *std::cbegin(s) << std::endl; // 'a'
	std::wcout << *std::cbegin(v) << std::endl; // 0
	std::wcout << *std::cbegin(l) << std::endl; // 0
	std::wcout << *std::cbegin(il) << std::endl;// 0
	std::wcout << *std::cbegin(a) << std::endl; // 0

	std::wcout << std::data(s) << std::endl; // "abcde" (<address>)
	std::wcout << std::data(v) << std::endl; // <address>
	// コメントを解除するとコンパイルエラー
	// std::listはデータが連続しないのでstd::dataが適用できない。
	// std::wcout << std::data(l) << std::endl;
	std::wcout << std::data(a) << std::endl; // <address>
	std::wcout << std::data(il) << std::endl;// <address>

	std::wcout << std::size(s) << std::endl; // 5
	std::wcout << std::size(v) << std::endl; // 5
	std::wcout << std::size(l) << std::endl; // 5
	std::wcout << std::size(a) << std::endl; // 5
	std::wcout << std::size(il) << std::endl;// 5

	return 0;
}
```

それぞれの定義を表示することでSTLコンテナ、固定長配列、初期化子リストに対して適切な関数テンプレートが呼び出されていることが分かります。

# 参考
- [C++20 規格案（ISO/IEC N4659、Working Draft, Standard for ProgrammingLanguage C++）](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf)
windowsでiverilog その7

#概要

windowsでiverilogやってみた。
割り算、書いてみた。

#サンプルコード


```
module div(input clk, input [7:0] A, input [3:0] B, output reg [3:0] Q, output reg [3:0] R);
	reg [3:0] Q_pre;
	reg [3:0] R_pre;
	always @*
	begin
		Q_pre = A / B;
		R_pre = A - Q_pre * B;
	end
	always @(posedge clk)
	begin
		Q <= Q_pre;
		R <= R_pre;
	end
endmodule 

```

#結果


```
  A  B  Q  R
  x  x  x  x
  9  3  x  x
  9  3  3  0
155 15  3  0
155 15 10  5
100 15 10  5
100 15  6 10
  1  3  6 10
  1  3  0  1


```

以上。
AWS Certified Database - Specialty合格記

AWS Certified Database - Specialtyを受けてきました。
取得を考えている方の参考になれば幸いです。

# 試験概要
https://aws.amazon.com/jp/certification/certified-database-specialty/

- 時間：180分
- 問題数：65問[^1]

[^1]: 試験ガイドに記載が無いので、問題数は変わるかもしれません

# 事前準備

1. 関連しそうなAWSのドキュメントを読む
    - RDS
        - https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Welcome.html
    - Aurora
        - https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html
    - Neptune
        - https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/intro.html
    - DynamoDB
        - https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html
    - DocumentDB
        - https://docs.aws.amazon.com/ja_jp/documentdb/latest/developerguide/what-is.html
    - 他
2. 模擬試験を受ける


# 結果

合格
受験者スコア: 808

# 受験者のスペック
参考になるかわかりませんが。。。

- クラウド歴：6年
- クラウド関連の保有資格
    - AWS: アソシエイト×３＋プロフェッショナル×２＋スペシャルティ×５＋プラクティショナー
    - GCP: クラウドアーキテクト＋データエンジニア＋デベロッパー＋ネットワーク＋セキュリティ
    - Azure: ソリューションアーキテクトエキスパート
- 外観：メガネぼーず

# 難易度等
時間は1周目で半分余りました。慌てなくても十分時間はあると思います。
難易度はAWSソリューションアーキテクトプロフェッショナルと同じか、ちょっと難しい位だと思います。
ゴリゴリRDSさわっている方でも、結構歯応えを感じるのではないでしょうか。
今更データベースぅ？とか言わず、是非チャレンジしてみてください。

# 感想
これでとりあえずAWSの認定はコンプしたけどIoTやメディアあたりとか、また認定増えたりするのかなぁ。
何か認定の更新と新規取得で１年が終わる感じがする。
リポジトリを追加する方法 & git pull時のエラーについて

リポジトリ追加の際のcommandの操作について
いつも忘れてしまうのでメモです。

#環境
- 作成済みのリポジトリを用意
- ローカルに新しくディレクトリを作成して`git init`後の操作

#リポジトリ追加コマンド
```
$git remote add origin 追加したいリポジトリ
```

#リポジトリ消去コマンド
```
$ git remote rm origin
```

#`git pull`を実行するとエラーが出る
```bash

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> master
```

どのブランチにマージしていいかわからないという意味なので以下のコマンドを実行します。

```bash
$ git pull リポジトリurl master
```

これでマージできました。
Windows10とubuntuのデュアルブート

#はじめに
一つのHDDにWindows10とUbuntu18.04を入れる機会があり、実施してみたところ思ったより躓いたので備忘録として残します。
躓いた部分は、Boot Listの設定やWindows10のセーフモード起動です。
DELL PCにWindows10がインストールされた環境から行いました。

#構築環境
今回使用したPC、OS、インストールメディアになります。
## PC
XPS 15 9570
デバイス名：DESKTOP-FBGEGJ0（DELL）
プロセッサ：Intel(R) Core(TM) i7-8750H CPU @2.20GHz 2.21GHz
実装RAM：16GB
ディスプレイ：Intel(R) UHD Graphics630

## OS
Windows10, Ubuntu18.04

## インストールメディア
RUF3-K64GA-BK（BUFFALO）

# 全体手順
1. Ubuntuインストールメディアの作成
* Ubuntuをインストールするためのパーティションの確保
* BIOS設定画面に入り、Boot List Optionを”Legacy External Devices”に変更
* Ubuntuをインストールする
* BIOS設定画面に入り、SATA Oprationを”AHCI”に変更して、Ubuntuが起動できるか確認
* Windows側でAHCIでも、起動するように設定

## 1.Ubuntuインストールメディアの作成


1. [Ubuntuのisoイメージのインストール]
(https://jp.ubuntu.com/download)
2. BootableUSBの作成
[Rufus 3.10](https://rufus.ie/)


## 2.Ubuntuをインストールするためのパーティションの確保
Windows10で、Ubuntuをインストールするためのパーティションの確保
winキー → 「コンピュータの管理」と入力 → 記憶域 → ディスクの管理
未割り当て領域がなければ、縮小していいボリュームを選択
右クリック → ボリュームの縮小 → サイズ選択（公式では25GB必要と記載されている。今回は64GB確保）


## 3.BIOS設定画面に入り、Boot List Optionを”Legacy External Devices”に変更
BIOS設定画面に入り、General → Boot Sequence → Boot Listが”UEFI”の場合、”Legacy External Devices”に変更

## 4.Ubuntuをインストールする
再起動して、BIOS設定画面のBoot SequenceでUSBの優先度を上げる
インストール方法は[参考URL-1](https://qiita.com/yo_kanyukari/items/2a944a300db22482c696)の通り

## 5.BIOS設定画面に入り、SATA Oprationを”AHCI”に変更して、Ubuntuが起動できるか確認
BIOS設定画面に入り、System Configuration → SATA Operationで”AHCI”に変更
再起動でデュアルブート画面になり、Ubuntuを選択。Ubuntuが起動するか確認

## 6.Windows側でAHCIでも、起動するように設定
SATA Operationが”AHCI”のまま、Windowsを起動するとエラーになる。

***改善方法***
BIOS設定画面でSystem Configuration → SATA Operationで”RADI ON”に変更
Windows10を起動 → スタートボタンを右クリック → ファイル名を指定して実行
“regedit”を入力 → レジストリエディターが起動

Windows 10レジストリキーを以下の通りに変更

- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\storahci\StartOverride　サブキー[0]の値を3→0 
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\storahci　サブキー[ErrorControl]の値を3→0

管理者権限でCMD（コマンドプロンプト）起動
`bcdedit /set safeboot minimal`でセーフモードに設定。
再起動し、BIOS設定でSATA OperationをAHCIへ変更、保存、再起動

Windows10がセーフモードで再起動
Windows 10レジストリキーで変更サブキーを確認
管理者権限でCMD起動
`bcdedit /deletevalue safeboot`でセーフモード解除に設定
再起動でWindows10が起動したらOK！！


# 参考URL
[Windows10とUbuntu18.04をデュアルブートする。](https://qiita.com/yo_kanyukari/items/2a944a300db22482c696)
[いつの間にか切り替わってしまったRAIDモードをAHCIモードに…](https://blog.goo.ne.jp/mowyano2/e/868e6b52030fbeb60a2c34eaee4ed0b1)
[PCの設定（IDEからAHCI変更）](https://ameblo.jp/wookr/entry-12210214379.html)

# おわりに
在宅勤務って素晴らしい
NASAの10のコーディングルールの力

>こちらの記事は、[Riccardo Giorato](https://medium.com/@riccardogiorato) 氏により2019年10月に公開された『 [The Power of 10 — NASA’s Rules for Coding](https://medium.com/better-programming/the-power-of-10-nasas-rules-for-coding-43ae1764f73d) 』の和訳です。
本記事は原著者から許可を得た上で記事を公開しています。
※Riccardo Giorato氏の個人ページは[こちら](https://riccardogiorato.com)

NASAの10のルールは、コードのレビューや静的解析を困難にするC言語のコーディング手法をなくすことを目的としています。

![1_GgydMj60aCOb7HWoVSk82g.png](https://miro.medium.com/max/2000/1*GgydMj60aCOb7HWoVSk82g.png)

NASAはこちらの10のルールについて、以下の通り述べています。

このルールは、車のシートベルトのように機能します。最初は少し違和感があるかもしれませんが、しばらくするとその使い方が第二の習慣のようになり、使わないことは想像できなくなります。

![0_1fY5NND25YrIraRi.jpeg](https://miro.medium.com/max/388/0*1fY5NND25YrIraRi)
Gerard J. Holzmann

10のルールの力は、2006年にNASA/JPL研究所のGerard J. Holzmannによって信頼性の高いソフトウェアのために作成されました。それらのルールは、レビューや静的解析が難しいC言語のコーディング手法をなくしていくことを目的としています。これらの規則は、MISRA Cガイドラインを補完するものであり、より多くのJPLコーディング標準に組み込まれています。

# NASAの10のコーディングルール

1. goto文や再帰呼び出しのような複雑なフロー構造を避ける
2. すべてのループは必ず固定のリミットを設ける(コードの暴走を防ぐことができます。)
3. ヒープメモリの割り当てを避ける
4. 一画面に収まるように関数を短縮する
5. 関数ごとに最低2つの実行時アサーションを使用する
6. データの範囲を可能な限り小さく制限する
7. すべての非void関数の戻り値をチェックする、またはvoidに型変換して戻り値が不要であることを示す
8. プリプロセッサを控えめに使う
9. ポインタの使用を単一の間接参照に制限し、関数ポインタは使用しない
10. 起こり得るすべての警告を有効にしてコンパイルする。ソフトウェアのリリース前に必ずすべての警告に対処する

上記のルールはC言語のために定義されたものではありますが、中にはモダンなWebやモバイルアプリのプロジェクトでも使えるかもしれません。いくつかピックアップしてみました。

# 1. GotoやRecursionのような複雑なフロー構成を避ける

forで処理できるようなシンプルな重複するタスクを作成する必要がない場合は、再帰呼び出しを使用しません。火星や月、海の底など、マシンに直接アクセスできない場所での再帰は非常に危険です！

# 2.すべてのループは必ず固定のリミットを設ける
1つ目のルールと似ていますが、ループ処理も無限ループやコードの暴走を防ぐために、固定のリミットを作ります。

# 4. 一画面に収まるように関数を短縮する
関数の長さを1ページに短縮すると、プログラムの特定のルーチンのすべての機能を把握しやすくなります。

この長さを超えると、コードに追加するアクションが多すぎることを示します。
コードの重複を防ぐために関数を小さな関数に分割していないという別の問題も起こるかもしれません。

# 6. データの範囲を可能な限り小さく制限する
もしJavaScriptを使っているとしたら決してvarを使ってはいけません。常にletを使用して、変数のリークや上書き、ゴースト化を防ぎます。C#のような言語にも同じことが言えます。

privateやprotectedのように最も堅牢で小さい範囲で値を使ってください。

# 10.起こりえるすべての警告を有効にしてコンパイルする。ソフトウェアのリリース前にすべての警告に対して対処する必要があります。

JavaScriptではコードをコンパイルしませんが、コードから警告を得るために、簡単にESLintや同様なツールを利用できます。

役に立たないと思っても、すべてを削除して修正すべきです。

これで火星にコードをローンチする準備は万端です！

![0_B392ytMVoonA5BDj.jpg](https://miro.medium.com/max/1400/0*B392ytMVoonA5BDj.jpg)
Mars Curiosity rover


# 翻訳協力
Original Author:  **[Riccardo Giorato](https://medium.com/@riccardogiorato)** 
Thank you for letting us share your knowledge! 

この記事は以下の方々のご協力により公開する事が出来ました。
改めて感謝致します。
選定担当: @r_pg10
翻訳担当: @r_pg10
監査担当: tsurumaki
公開担当: @r_pg10

# ご意見・ご感想をお待ちしております
今回の記事は、いかがだったでしょうか？
・こうしたら良かった、もっとこうして欲しい、こうした方が良いのではないか
・こういったところが良かった
などなど、率直なご意見を募集しております。
いただいたお声は、今後の記事の質向上に役立たせていただきますので、お気軽にコメント欄にてご投稿ください。
みなさまのメッセージをお待ちしております。
[Flutter] 00_開発環境セットアップ

<img width="700" alt="maxresdefault.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69002/392dc7cf-ebe1-af05-4396-136ba96c5b22.jpeg">
Flutter作業メモシリーズ。。

# 概要
Flutter開発環境セットアップ手順のまとめ

# 開発環境前提

- マシンOS: Mac (Catalina 10.15.5)
- メインエディタ: VS Code

# 諸々ダウンロード・インストール
|No.|項目|説明|備考|
|---|-----|---|---|
|1|Visual Studio Code|今回使うメインエディタ。|AndroidStudioでも、Atomでも代用可。|
|2|Android Studio|Android統合開発環境。エミュレータを使うために必要。||
|3|Xcode|iOS統合開発環境。シミュレータ(=エミュレータ)を使うために必要。|アプリ配信でも使う。|
|4|Flutter SDK|Dartパッケージを含むFlutter基本ライブラリ。バージョンアップを簡単にできるようGitパッケージとして取り込む。||

### Visual Studio Code
<img width="500" alt="Visual Studio Code Extension.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69002/3f53720f-2d96-bd63-bc7d-48770f79e3a4.png">

1. https://code.visualstudio.com/download より、ダウンロード。
2. Extension(=プラグイン)をインストール。最低下記2つ。
  - Dart
  - Flutter

### Android Studio
<img width="500" alt="Android Studio Plugins.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69002/bd38a273-27b6-5488-ea9f-fc30c337699c.png">

1. https://developer.android.com/studio より、ダウンロード。
2. Plugin(=プラグイン)をインストール。最低下記2つ。
  - Dart
  - Flutter

### Xcode

1. https://apps.apple.com/app/xcode/id497799835 より、インストール。
2. 起動して、RequiredComponentsをインストール。 

### FlutterSDK
<img width="500" alt="SourceTree flutter.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69002/5d8f7928-d042-68f9-deee-b6ca6c170b55.png">

1. https://github.com/flutter/flutter.git より、PCの任意の場所にクローンする。
2. stableブランチに切り替え。（最新機能を使いたい場合は、betaブランチ）
3. PATHを通す
  1. ターミナルで`vi ~/.bash_profile`
  2. `export PATH=$PATH:{ディレクトリ置き場}/flutter/bin`を追加し、保存。
4. セットアップ
  - ターミナルで`flutter doctor`すると、最終設定＋環境チェックが行われる。
  - 環境チェックの結果必要な作業が指示された場合は、それに従う。
  - うまくいかない場合は、{ディレクトリ置き場}/flutter/binにあるcacheディレクトリを削除して再実行。

# 参考
## 公式Docs
|No.|項目|説明|備考|
|---|---|---|---|
|1|[GetStarted/Install](https://flutter.dev/docs/get-started/install)|インストール方法||
|2|[GetStarted/Set up an editor](https://flutter.dev/docs/get-started/editor)|エディタ設定方法||

# 備考
(特になし)
よく使うgitコマンド

# gitでよく使うコマンド
リポジトリ初期化
```console
$ git init
```
プル
```console
$ git pull
```

ブランチを作成し移動
```console
$ git checkout -b ブランチ名
```

ブランチ削除
```console
$ git branch -D ブランチ名
```

状態確認

```console
$ git status
``` 
差分確認　※qまたはShiht+Z 2回で終了
```console
$ git diff
``` 

選択したファイルをステージング

```console
$ git add ファイル名
```

コミット
```console
$ git commit -m "コメント"
```

変更履歴確認
```console
$ git log
```

コミットメッセージを変更したい
```console
$ git commit --amend -m "変更したいメッセージ"
```

プッシュ
```console
$ git push origin プッシュ先
```
チェリーピック
```console
$ git cherry-pick コミットID
```

過去のコミットに戻る
```console
$ git reset --hard 戻りたいコミットID
```
過去のコミットに戻るの打消し
```console
$ git reset --hard ORIG_HEAD
```
最新developを作業用ブランチにマージしたい
1.developブランチでgit pull
2.作業中のローカルブランチに移動
3.マージ
```console
$ git pull
$ git checkout -b ブランチ名
$ git merge develop 
```
p5.js [タイルで埋める] 基本編

#作例
タイルはクリエイティブコーディングの基本となる手法です。応用の幅が広いため、シンプルながら人によってかなり個性が出ます。
![Frame 4 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637821/047471ca-33b7-d895-6461-96d9f1e82003.png)
[数学から創るジェネラティブアート](https://gihyo.jp/book/2019/978-4-297-10463-4)
[Generative Design with p5.js](http://www.bnn.co.jp/support/generativedesign_p5js)
#まず考えるべきは３つだけ
>**1. タイルの枚数（横,縦）**
>**2. タイルの幅（横,縦）**
>**3. タイルの座標（X,Y）**

##１.タイルの枚数
使いたいキャンバスの縦横比をイメージし、そこにタテ×ヨコ何枚のタイルを敷き詰めたいか想像してみましょう。想像できたら、さっそく変数に代入です。
###コード

```javascript:qiita.js
tileCountX = 20; //横20枚
tileCountY = 10; //縦10枚
```

###イメージ
![Frame 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637821/f7de236b-d41d-23df-3653-0a890836ce0d.png)

##２.タイルの幅
画面いっぱいに敷き詰めるので
(タイル一枚の幅) = (画面サイズ) ÷ (タイルの枚数)
です。横幅と縦幅をそれぞれ決定し、変数に代入しておきましょう。

###コード

```javascript:qiita.js
tileWidth = width / tileCountX; //横幅30px
tileHeight = height / tileCountY; //縦幅50px
```

###イメージ
![Frame 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637821/31954f38-ffe7-c47c-69b0-142a752b4d81.png)
##３.タイルの座標
X,Y座標に対応するグリッド番号を、縦,横の枚数分だけfor文の入れ子で回します。

###コード

```javascript:qiita.js
 for(let gridY = 0; gridY < tileCountY; gridY++){ //gridYを0~10まで加算
    for(let gridX = 0; gridX < tileCountX; gridX++){ //gridXを0~20まで加算
      let posX = gridX*tileWidth; //X座標の設定
      let posY = gridY*tileHeight; //Y座標の設定

      rect(posX, posY, tileWidth, tileHeight); //タイルの描画
    }
  }
```
< 解説 >
例では縦10枚,横20枚ですので

>gridYが0でgridXを0→20,
 gridYが1でgridXを0→20,
...
gridYが10でgridXを0→20

のように左上タイルから1行ずつグリッド番号を指定していきます。
for文内で行う処理は

- 指定されたグリッド番号にタイルの幅をかけることで、タイルのX,Y座標を取得(→ posX,posYに代入)
- 座標と幅の情報を元に,rectタイルを一枚描画

の2つです。

###イメージ
![Frame 3 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637821/bf4cf524-c947-86e4-e4e0-ab8928c17f0a.png)

##完成！
###全コード

```javascript:qiita.js
//設定

let tileCountX,tileCountY;
let tileWidth,tileHeight;

function setup(){
  //キャンバス設定
  createCanvas(600, 500);//600px * 500px

  //色塗り設定
  colorMode(HSB);
  fill(200,70,100);//塗りは水色
  stroke(100);//枠線は白

  //1.タイルの枚数
  tileCountX = 20;
  tileCountY = 10;

  //2.タイルの幅
  tileWidth = width/tileCountX;
  tileHeight = height/tileCountY;
}

//描画
function draw(){
  //3.タイルの座標
  for(let gridY = 0; gridY < tileCountY; gridY++){
    for(let gridX = 0; gridX < tileCountX; gridX++){
      let posX = gridX*tileWidth;
      let posY = gridY*tileHeight;
      rect(posX, posY, tileWidth, tileHeight);
    }
  }
}
```
↓↓↓
![スクリーンショット 2020-05-31 17.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637821/62bcffff-b9ed-655c-c542-5d4113a733b5.png)
##お風呂場の壁ができました
これだけだと味気ないですよね。
[色塗り編](https://qiita.com/Majogari/items/f97b6a8fc5d6bac3c483)、サイズ編、画像読み込み編など随時更新予定。
【enchant.js】画像を拡大したらピンぼけしてたから直した

趣味でプログラミングをしているいちいち@ichiichi_1115 です。
enchant.jsで画像の拡大をしてたらぼやけてしまったので備忘録＆その先に躓く人がいないようにまとめてみました。

# imageSmoothingEnabled をFalseに

[imageSmoothingEnabled](https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled) をFalseにすると、補完処理をしなくなるという話を聞いたのでやってみました。

enchant.js(整形版)4460行目あたりに、`_dctx`といういかにもコンテキストそうな変数があったのでそれに対してやってみたが効果なし...

というか、すでにimageSmoothingEnabledがFalseにされていました(以下コード)。

```javascript:enchant.js
    _setImageSmoothingEnable: function() {
        this._dctx.imageSmoothingEnabled =
        this._dctx.msImageSmoothingEnabled =
        this._dctx.mozImageSmoothingEnabled =
        this._dctx.webkitImageSmoothingEnabled = false;
    }
```

JavaScriptの書き方で、`a = b = false`と書くと、aもbもFalseになりますが、その記法です。

とりあえず、これでは治りませんでした。

# リファレンスを読む

[imageSmoothingEnabledのリファレンス](https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled) を読んでたら、こんなものを発見しました。

>このプロパティは、たとえばキャンバスをスケーリングするような、ピクセルアートをテーマにしたゲームに役立ちます。 既定のリサイズアルゴリズムは、ぼやかし効果をかけることで、美しいピクセルを崩してしまいます。このような場合、このプロパティを false に設定します。image-rendering プロパティも確認してください。

**image-rendering プロパティも確認してください**らしいです。

これは、画像を拡大縮小するときのアルゴリズムを指定するものらしいです。

## image-rendering

詳しくはリファレンスに書いてありますが、これを pixelated という値にすると、ピクセル画で表示されます。

読解力と知識の無さでその他の値については読み解けませんでしたスマヌ...

#まとめ

以下をコピーして、styleタグやcssファイルに貼り付けてください。

```css:style.css

    canvas{
        image-rendering: pixelated;
    }
```

これで、画像を拡大してもぼやけさせずに表示することができました！！！

以上。
【Material-UI】FormControlLabelを使ったラジオフォーム作成

# はじめに
今回は、React UI コンポーネントフレームワークの「Material-UI」を使って、以下のようなラジオフォームを作成します。

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

## ポイント
- 基本的にはMaterial-UIデフォルトスタイルで作成
- 複数のコンポーネントを組み合わせて作る　
- ラベルのフォントサイズの変更について


# マークアップ構成
`<FormControl>`コンポーネントで、Formの領域を確保して、
`<RadioGroup>`コンポーネントでラップした項目一覧（`<Radio>`コンポーネント）を配置します。
今回は、ラベルを`<FormControlLabel>`コンポーネントを使います。

以下の構成です。

```jsx
return (
  <FormControl>
    {/* グループにラベル */}
    <FormLabel />
    {/* ラジオグループ */}
    <RadioGroup>
　　  {/* リスト */}
      <FormControlLabel>
        <Radio />
      </FormControlLabel>
      ...
    </RadioGroup>
  </FormControl>
)
```

# ソースコード
それぞれが選択された場合の処理を追加して完成です。

```jsx
import React from "react";
import Radio from "@material-ui/core/Radio";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormControl from "@material-ui/core/FormControl";
import FormLabel from "@material-ui/core/FormLabel";
import { makeStyles } from "@material-ui/core/styles";
import "./styles.css";

export default function App() {
  const [value, setValue] = React.useState("React");
  const classes = styles();

  const handleChange = event => {
    // クリックされたら、valueの値をsetします。
    setValue(event.target.value);
  };

  return (
    <div className="App">
      <FormControl component="label">
        <FormLabel component="label">JavaScript framework</FormLabel>
        <RadioGroup
          name="JavaScript framework"
          value={value}
          onChange={handleChange}
        >
          <FormControlLabel
            value="React"
            control={<Radio />}
            label="React"
          />
          <FormControlLabel
            value="Vue.js"
            control={<Radio />}
            label="Vue.js"
          />
          <FormControlLabel
            value="AngularJS"
            control={<Radio />}
            label="AngularJS"
          />
          <FormControlLabel
            value="jQuery"
            disabled
            control={<Radio />}
            label="jQuery"
          />
        </RadioGroup>
      </FormControl>
    </div>
  );
}

```

# ラベルのフォントサイズを変更したい
Material-UIのデフォルトデザインで利用できれば上記で良いですが、
なかなかデザインいじらずに使えると機会は少ないかと思います。

今回は、ラベルのフォントサイズを変更してみます。

## `FormControlLabel`の構造について
`<FromControlLabel>`コンポーネントは、大きく、controlプロパティで指定したエレメント（`Radio`・`Switch`・`Checkbox`）と「ラベル」の二つで構成されています。

公式リファレンスによると、ラベルのデフォルトスタイルは、Typographyスタイルが当たっているようです。
>Styles applied to the label's Typography component.

## `label`プロパティにエレメントを当てて上書きする
テキストでそのまま送らずに、`<span>`タグ等で囲ってあげて、スタイルを当ててあげることで上書きしてみました。

```jsx
<FormControlLabel
  value="React"
  control={<Radio />}
  label={<span className={classes.labelRoot}>React</span>}
/>
```

# 紹介した内容のSnadbox
[![Edit Material-UI_FormControl](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/material-uiformcontrol-e33hn?fontsize=14&hidenavigation=1&theme=dark)
【Swift】ノベルゲームっぽく文字を表示するライブラリ

#ノベルゲームを作りたかった
Swiftでノベルゲームを作りたかったのですが、文字をそれっぽく表示するライブラリだけは発見できました。

他にも何かいい情報あれば教えてください！

cocoapodsでこれをインストール

```
pod 'SRGNovelGameTexts'
```

あとはこのコードの表示位置やテキストを変えれば完成です。

```swift
// テキスト出力用のViewを初期化
let novelGameText = SRGNovelGameTexts()
novelGameText.frame = CGRect(x: 100,y: 100,width: 100,height: 100)
novelGameText.textColor = UIColor.black
self.view.addSubview(novelGameText)

// 出力したいテキストをセット
novelGameText.setText("こーら！まだ起きないの？")

// 演出を再生開始
novelGameText.startDisplayingText()
```
AWS の EC2 上で動作する Moodle の SELinux を有効にする

Moodle サーバの SELinux を有効にしてみました。

ちなみに、moodledata を AWS の EFS に置いています。パスは、/mnt/nfs/html/moodledata です。

Moodle の web 画面が以下となります。

```
Fatal error: $CFG->dataroot is not writable, admin has to fix directory permissions! Exiting. 
```

次のコマンドを実行した。

現在の boolean を確認した。

```
# getsebool -a | grep nfs | grep httpd
httpd_use_nfs --> off
```

httpd が nfs をつかえるようにした。

```
# setsebool -P httpd_use_nfs on
```

（参考）
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-managing_confined_services-the_apache_http_server-configuration_examples

再起動すると、moodledata へのアクセスは解消されたようだが、データベースへのアクセスができないというエラーになっていた。

以下のコマンドを実行した。

```
# setsebool -P httpd_can_network_connect_db 1
```

（参考）
https://serverfault.com/questions/240015/how-do-i-allow-mysql-connections-through-selinux

webアクセスで確認したら、まだエラーが取れていない。audit.log を確認すると、以下のようになっていた。

```
# less /var/log/audit/audit.log | grep denied

type=AVC msg=audit(1590352121.329:94): avc:  denied  { name_connect } for  pid=2318 comm="php-fpm" dest=3306 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket permissive=0
```

（参考）
https://dev.classmethod.jp/articles/redhat-selinx-might-block-network-connection-to-servers-from-apache-php/

再起動して web アクセスすると、以下の表示になっていた。

```
Invalid permissions detected when trying to create a directory. Turn debugging on for further details.
```

audit.log を確認すると、以下のエラーになっていた。

```
type=AVC msg=audit(1590352587.167:90): avc: denied { write } for pid=2347 comm="php-fpm" name="localcachedir" dev="nvme0n1p1" ino=239410 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir permissive=0
```

次のコマンドを実行した。

```
# setsebool -P httpd_can_network_connect 1
```

エラーが出なくなった。

httpd_can_network_connect_db はいらなかったかな。


（参考情報）
nfs に dataroot が無い場合、要すれば、よくある構築の一例の場合の参考例です。

semanage コマンドが入っていない場合、file context は手動で設定できる。


（一例）

```
# vim /etc/selinux/targeted/contexts/files/file_contexts.local

/var/www/html/moodle(/.*)?   system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html/moodledata(/.*)?   system_u:object_r:httpd_sys_rw_content_t:s0

# restorecon -R -v /var/www/html/moodledata
```

再起動して確認した。

```
# ls -laZ /var/www/html/moodledata
```

以下のラベルがついて、エラーもなくなったようだ。

```
httpd_sys_rw_content_t
```

上記は、参考情報で、いつもの場合です。

今回は、moodledata のバスが /mnt/nfs/html/moodledata なので、boolean だけで設定できた。
結局、以下を実行した。

```
# setsebool -P httpd_can_network_connect 1
# setsebool -P httpd_use_nfs on
```

ちなみに、semanage は以下の方法でインストールできます。

```
# yum -y install policycoreutils-python
```

つづき
[AWS の EC2 上で動作する Moodle の SELinux を有効にする(その2)](https://qiita.com/intrajp/items/7985f7bcbaa82f6f1219)
AWS 上の ALB の HealthChecker に 200 を返す方法

AWS 上の ALB のターゲットの Moodle で HealthChecker に認識させることはできないのは、config.php が読み込んでいる lib/setuplib.php でリダイレクトしているからで、ターゲットでは 303 になりうまくいきません。
config.php の最上部で、以下のように記述すれば、200 を返す事ができます。 
コツは、lib/setuplib.php を読み込む前に処理を入れることです。


```PHP
$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
if (strstr($http_user_agent, "ELB-HealthChecker")) {
    echo "ok";
    die;
}
```
posts_controller.rb

class PostsController < ApplicationController
  def index
    # Post.allにorderメソッドを用いて、新しい投稿が上から順に表示されるようにしてください
    @posts = Post.all.order(created_at: :desc)
  end
  
  def show
    @post = Post.find_by(id: params[:id])
  end
  
  def new
  end
  
  def create
    @post = Post.new(content: params[:content])
    @post.save
    redirect_to("/posts/index")
  end
end

//降順にデータベースに投稿された内容を表示する
Spring BootでHashiCorp Vaultからデータを読み込むためにハマったこと

それぞの公式ページを参照しながら作業したのですが、自分のやりたい条件で実現することに時間がかかってしまいました。

備忘録と参考までに投稿します。

# 環境

- OS: CentOS7
- Spring Boot: org.springframework.boot spring-boot-starter-parent 2.1.13.RELEASE、spring-cloud.version Greenwich.SR2
- Vault: v1.4.2

# やりたかったこと

- ローカルでサービスとして動いているVaultからデータを読み込む。
- Vaultのバックエンド ストレージは[ファイルシステム（Filesystem Storage Backend）](https://www.vaultproject.io/docs/configuration/storage/filesystem)。
- [シークレット エンジン（Secrets Engines）](https://learn.hashicorp.com/vault/getting-started/secrets-engines)は`kv`（バージョン1）

# ポイント

## HashiCorp Vault側

### /etc/vault.d/vault.hcl

- ストレージを`file`にする。

#### 例

````
storage "file" {
  path    = "/var/vault/data"
}
````

`path`は任意のディレクトリ

### アプリケーション用ポリシーの設定

以下のように設定する。

```hcl
path "secret/application" {
  capabilities = ["read"]
}
path "secret/<パス名>" {
  capabilities = ["read"]
}
path "secret/data/application" {
  capabilities = ["read"]
}
path "secret/data/<パス名>" {
  capabilities = ["read"]
}
```

Springはデフォルトで`secret/application`のパスも読み込もうとしているようで、`secret/<パス名>`のみを読み取り可能にするとエラーになりました。また、[Spring Cloud Vaultの公式ページ](https://cloud.spring.io/spring-cloud-vault/reference/html/#vault.config.backends.kv.versioned)によると、Spring Cloud Vaultが自動で`secret/data/application`と`secret/data/<パス名>`も読み込み元に追加するため、 `secret/data/application`と`secret/data/<パス名>`にもアクセス許可を与える必要がありました。

### データの書き込み

- `vault kv put secret/<パス名>`で書き込む。

`secret/data/<パス名>`にデータを書き込んでも読み込まれませんでした。
 
## Spring Boot側

### <プロジェクト ルートディレクトリ>/src/main/resources/bootstrap.yml

- `spring.application.name`か`spring.cloud.vault.application-name`の設定が必要。

当方環境では、`spring.cloud.vault.kv.application-name`のみを設定しても、エラーになり値を読み込むことができませんでした。

#### 当方環境で機能した設定

```yaml
spring.cloud.vault:
  application-name: <アプリケーション名>
  scheme: http
  token: ${VAULT_TOKEN}
  kv:
    enabled: true
```

`<アプリケーション名>`は、Vault側で`vault kv put secret/<パス名>`によりデータを書き込む際の`<パス名>`と一致している必要があります。

`spring.cloud.vault.token`は、Vault側で`vault token create 〜`でアプリケーション用に読み取り専用のトークンを作成する関係で環境ごとに変わるため、環境変数`VAULT_TOKEN`に設定します。

### Javaのソース

`@Value("${<Vaultに書き込んだキー>}")`により、値を取得できます。


`vault kv put secret/testapp aaa.bbb.ccc=hogehoge`でデータを書き込んでいた場合、


```java
// （前略）
    @Value("${aaa.bbb.ccc}")
    private String testVar;

// （中略）

    @PostConstruct
    private void testMethod() {
        System.out.println(testVar);
    }
// （後略）
```

で、`testVar`の値が「hogehoge」として出力されます。

# その他

Vaultの設定についてはAnsibleのPlaybookを作成したので、よろしければ自由に改変してお使いください。

https://github.com/ecormaksin/ansible_playbook_hashicorp_vault_local_filesystem

誤りのご指摘、ご質問など、何でもフィードバックをいただけると嬉しいです。

# 参照サイト

https://spring.io/guides/gs/vault-config/
https://docs.spring.io/spring-vault/docs/2.2.2.RELEASE/reference/html/
https://cloud.spring.io/spring-cloud-vault/reference/html/
https://www.baeldung.com/spring-cloud-vault
https://learn.hashicorp.com/vault
https://www.vaultproject.io/docs
[Python]04章-06 いろいろなデータ構造（ディクショナリの作成）

#[Python]04章-06 ディクショナリの作成
この節では、ディクショナリについて説明していきます。リストやタプルといったように、1つの変数にいくつかの要素を持たせていることは同じです。
ディクショナリを用いることで、特定の項目に対して、値を関連付けることもできるようになります。

ここでは、**「ディクショナリ」**という表現をしますが、Pythonの書籍によっては単に**「辞書」**ということもありますので、把握しておいてください。

##ディクショナリの作成
ディクショナリとは、それぞれの要素に**キー（key）**と**値（value）**をペアとして存在しているデータ構造です。

早速ディクショナリを作成していきましょう。
**Python Console**より、以下のコードを入力してください。今回の例では、情報処理技術者試験の略称名を用いて説明していきたいと思います。

```.py
>>> D = {'ip' : 'ITパスポート試験', 'fe' : '基本情報技術者試験', 'sg' : '情報セキュリティマネジメント試験', 'ap' : '応用情報技術者試験'}
>>> D
{'ip': 'ITパスポート試験', 'fe': '基本情報技術者試験', 'sg': '情報セキュリティマネジメント試験', 'ap': '応用情報技術者試験'}
```

こう見てみると、実際の辞書のように、**ip**が何なのか、といったことが記載されています。

ディクショナリにおいては、**{キー1 : 値1, キー2 : 値2, …}**といったように、キーと値を:（コロン）で区切り、各要素を,（カンマ）で区切ります。さらにそれらを**{  }**で囲みます。

また、キーだけを抽出する、値だけを抽出するといったことも可能です。いったん**D**の要素を確認してから変更します。

```.py
>>> D = {'ip' : 'ITパスポート試験', 'fe' : '基本情報技術者試験', 'sg' : '情報セキュリティマネジメント試験', 'ap' : '応用情報技術者試験'}
>>> D.keys()
dict_keys(['ip', 'fe', 'sg', 'ap'])
>>> D.values()
dict_values(['ITパスポート試験', '基本情報技術者試験', '情報セキュリティマネジメント試験', '応用情報技術者試験'])
```

キーを知りたい場合は**keys()メソッド**を、値を知りたい場合は**valuesメソッド**を使用します。

##ディクショナリの要素の参照
ディクショナリにおける要素の参照は少し特殊です。リストやタプルでは、各要素の番号を**[  ]**に指定して表示していましたが、ディクショナリでそれを行うとエラーとなります。ディクショナリでも要素を参照する際には**[ ]**を使用しますが、その指定方法が異なります。

**Python Console**より、以下のコードを入力してください。ディクショナリでは以下のように**キーを指定**して要素を表示します。

```.py
>>> D['fe']
'基本情報技術者試験'
```

もちろん、存在しないキーを指定するとエラーとなります。

```.py
>>> D['db']
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'db'
```

要素の値のほうを変えるには、キーを指定して、書き換えることができます。いったん**D**の要素を確認してから変更します。

```.py
>>> D
{'ip': 'ITパスポート試験', 'fe': '基本情報技術者試験', 'sg': '情報セキュリティマネジメント試験', 'ap': '応用情報技術者試験'}
>>> D['ap'] = 'ソフトウェア開発技術者試験'
>>> D
{'ip': 'ITパスポート試験', 'fe': '基本情報技術者試験', 'sg': '情報セキュリティマネジメント試験', 'ap': 'ソフトウェア開発技術者試験'}
```

この変数**D**はまた使うので**'ap'**を元に戻しておきます。

```.py
>>> D['ap'] = '応用情報技術者試験'
>>> D
{'ip': 'ITパスポート試験', 'fe': '基本情報技術者試験', 'sg': '情報セキュリティマネジメント試験', 'ap': '応用情報技術者試験'}
```

なお、値は変えられることはわかりましたが、キーは変えることはできません。
先ほどのタプルの時にも触れましたが、キーはイミュータブルのため、変更はできません。

##最後に
今回はディクショナリについて触れました。キーと値の組み合わせについては、コンピュータ関連の書籍をあさっていけば、どこにも掲載されていると思います。
キーと値の操作に慣れておきましょう。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)
サービスメッシュに関する図(PlantUML) 

サービスメッシュに関する図をPlantUMLで作成しました。
この図を含んだブログ記事も記載しているので、興味あるかたは以下からどうぞ。
[すごいよ、サービスメッシュ！ 〜 マイクロサービスアーキテクチャの設計パターン 〜 - ふじやまエッグの日々](https://fujiyamaegg.hatenablog.com/entry/2020/05/31/165055)

# データプレーンとコントロールプレーン
サービスメッシュは、データプレーン(data plane)とコントロールプレーン(control plane)と呼ばれるコンポーネントから構成されています。
それを表したのが以下の図です。

![データプレーンとコントロールプレーン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/de275310-df37-03ac-2ac5-e7cdd5d6f0c5.png)


# カナリアリリース
サービスメッシュの特徴として、トラフィックコントロールがあげられます。それを利用することでカナリアリリースも実現することができるのです。

第１段階
![canary1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/edec438a-23b7-3f64-93ab-5caa585c7afa.png)

第２段階
![canary2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/04716ee1-6d8f-d304-d001-ad775ea55471.png)

第３段階
![canary3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73241/2f2037f6-d596-250e-044c-405686e2a071.png)

# 最後に
サービスメッシュは、マイクロサービスアーキテクチャにとっては、必須といっていいのではないかと思います。そんなサービスメッシュのありがたさを以下の記事にまとめているので、興味あるかたはぜひどうぞ。

[すごいよ、サービスメッシュ！ 〜 マイクロサービスアーキテクチャの設計パターン 〜 - ふじやまエッグの日々](https://fujiyamaegg.hatenablog.com/entry/2020/05/31/165055)