OmniAICreator/Qiita-1.07M huggingface dataset:
Minecraftで学ぶ！シェーダー作成の基本！【glsl】


次回:[影をつける方法](https://qiita.com/MCH_YamaRin/items/771e0d49ef90c39d3fbc)
#はじめに

みなさんはMinecraftの影Modをご存じでしょうか...？
![2017-11-30_20.45.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087947/795c8663-d311-a0a8-2270-d698e75e693b.jpeg)
(画像:SEUS Renewed)

そうです！Minecraftの世界をとてもリアルにしてくれるアレです！
代表的なSEUS Renewedをはじめ、有志によって製作された様々な影Modがありますが、そのすべてに共通すること...

**glslという、シェーダー言語で作られていることです！**

#glsl(シェーダー言語)とは...
**グラフィックに特化したC言語だと思ってくれてかまいません。**

ベクトルやマトリックスなど...
色や座標の計算がしやすいような要素が豊富に用意されています！

**この記事では、Minecraftを使用しながらglslの基本を解説していきます！**

#準備

**まず、Minecraftのシェーダーのテンプレート用意したので、そちらをダウンロードしてください。**

**[テンプレートはこちら](https://cdn.discordapp.com/attachments/772427867605696542/807610322991054848/Template.zip)**

テンプレートをMinecraftに適用させる方法は、基本的に他の影Modと変わらないです。
(ここでの導入方法の解説は割愛させていただきます)

![2021-02-06_23.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087947/638fad9e-d4f7-2be4-459a-0db7bfb8b1b9.png)


適用すると、何も導入していない状態のMinecraftの世界と、見た目があまり変わっていないはずです。

違いがあるとすれば、霧の有無でしょうか。

#実際に編集してみましょう！

テンプレートのフォルダを開くと、「shaders」というフォルダが中にあります。

その中に、glslのシェーダーファイルである、拡張子が「.fsh」、「.vsh」のファイルがたくさん入っています。

**今回は、Minecraftの基本的なブロックの色を担当している、「gbuffers_terrain.fsh」を編集してみましょう。**

```glsl
#version 120

uniform sampler2D lightmap;
uniform sampler2D texture;

varying vec2 lmcoord;
varying vec2 texcoord;
varying vec4 glcolor;

void main() {
	vec4 diffuse = texture2D(texture, texcoord) * glcolor;
	diffuse *= texture2D(lightmap, lmcoord);

	gl_FragData[0] = diffuse;
}
```

**仕組みを簡単に説明すると、「diffuse」という変数にMinecraftのテクスチャの情報や明るさの情報を入れ、それを最終的に色の情報を決める、「gl_FragData[0]」に入れています。**

「diffuse」には、「赤、緑、青、透明度」の情報が入っているので、今回は透明度をのぞいた色の情報を編集してみます。

```glsl
diffuse.rgb *= vec3(3.0 , 1.0 , 1.0);
```
こちらのコードを、「gl_FragData[0] = diffuse;」と「diffuse *= texture2D(lightmap, lmcoord);」の間に書いて保存し、シェーダーを読みこんでみましょう。

![2021-02-06_23.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087947/e40c0634-1bc1-4e2c-8776-9ed590499613.png)

ブロックが真っ赤になりましたね。

「A \*= B;」は、
**Aに、AとBを掛け算したものを入れる**
という意味になるので、さきほど書いたコードに置き換えると、
**diffuse.rgbに、diffuse.rgbと「赤3.0、緑1.0、青1.0」を掛け算したものを入れる**
という意味になります。

diffuseに「.rgb」をつけることで、透明度をのぞく、3色の情報を編集することができます。

「vec3()」は、
**かっこの中にある、コンマで区切られた3つの数値を一つにまとめたもの、といった意味で覚えてもらってかまいません。**

ご存じのとおり、何かに1.0を掛け算しても結果は変わらないので、さきほど書いたコードでは赤の要素を3倍にしたものになります。

**vec3()のかっこの中の数値を変更することで好きな色にすることができるので、あなたのお好みの色に変更してみましょう！**

#さいごに

今回が私の初めての記事となります。
なぜMinecraftを使用してglslの基礎を紹介したかというと、

**・大人気のゲームなので知名度が高い**
**・環境を構築する必要がないため、手軽に始められる**
**・Qiitaで同じような記事が無かった**
**・単純に私が大好きなゲーム**

などの理由があるからです。

Minecraftは有料のゲームですが、シェーダー以外にもMod、コマンド、データパック、リソースパックなど、ひとつのゲームだけで、プログラミング経験者やそうでない人でも多種多様な創作をすることができる点が素晴らしと思います！

**次回があれば影をつける方法を解説するつもりなので、今後ともよろしくお願いします！**
特定のアプリをきちんと停止させて削除する方法

MAMPが必要ないなと思ったのとMAMPのmysqlとbrewでインストールしたmysqlで接続の関係でぶつかったりしないのか、そもそも二つあるのがややこしいと思ったので、MAMPを削除することにした。

その際にちゃんと機能停止させて削除したのでそのことをまとめておく。

##ps aux で現状把握

実行されてるプロセス、ここではmysqlに関して実行されてるプロセスを把握するために`ps aux`を利用した。

```
ps aux | grep mysql
```

PID(プロセス番号）とともにどのプロセスが実行されているかがよくわかる。


##brew services stopでアプリの停止

`brew services stop mysql`でbrewにあるmysqlを停止させることができる。

```
brew services stop mysql@5.7
==> Tapping homebrew/services
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-services'...
remote: Enumerating objects: 76, done.
remote: Counting objects: 100% (76/76), done.
remote: Compressing objects: 100% (72/72), done.
remote: Total 1121 (delta 36), reused 14 (delta 3), pack-reused 1045
Receiving objects: 100% (1121/1121), 328.76 KiB | 622.00 KiB/s, done.
Resolving deltas: 100% (471/471), done.
Tapped 1 command (41 files, 419KB).
Error: Service `mysql@5.7` is not started.
```

このときもう一度`ps aux | grep mysql`でプロセスの把握をする。
このbrewのmysqlの停止でどのmysqlが動いているかの確認をした。

##killしてプロセスを停止していく！

```
kill PID(数字)
``` 
`kill`コマンドでmysqlに関するコマンドを停止していく。
`ps aux | grep mysql`でmysqlの実行されているプロセスがPIDとともにわかるのでそのPIDを`kill`に入れることでmysqlに関するプロセスを一つずつ停止させることができる。

全てのmysqlに関するプロセスを停止させたらあとは削除するのみ。

ここでは`rm -rf`でフォルダごと削除してもよいが、AppCleanerというアプリを使ってみたかったので使用した。
おそらく、AppCleanerは完全にアプリを停止させないと該当のアプリを削除できない可能性があるのでしっかり`kill`しておく必要がある。

##brewのmysqlの復活
最後にbrewのmysqlをまた使えるようにする必要がある。
ちなみに@5.7はバージョンだから気にしなくて良い

```
brew services start mysql@5.7
==> Successfully started `mysql@5.7` (label: homebrew.mxcl.mysql@5.7)
```
Salesforce Classic での Pardot を使用した対ビジネスマーケティングの自動化 ⇒ Salesforce Engage の基本 ⇒ Salesforce Engage の使用開始

１．Salesforce Engage はどのようにしてビジネスの役に立ちますか?
２．Salesforce Engage を構成する 4 つのコンポーネントは何ですか?
３．Salesforce Engage を使用するマーケティング担当者は、次のうちどれでメールテンプレートを作成できますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/ca1440de-fc41-a844-2a87-ca88334b1a7a.png)
【Python】ダイグストラ法(自分自身への最短経路もOK)【AtCoder】

ABC191
[E - Come Back Quickly](https://atcoder.jp/contests/abc191/tasks/abc191_e)
でダイグストラが出てきたので今後のためにも自作ライブラリ作った！

※ABC191EでAC確認済ですが、万が一バグがあれば教えてください！

***
###ちなみに
Pythonの標準ライブラリ
`scipy.sparse.csgraph`の関数`shortest_path()`
は、以下の2点の場合、競プロでは使えない。

- N>=10**4 の場合
    - 計算量が`O[N(N*k + N*log(N))]>=O[N**2]`なため。隣接行列を作る過程で、`O[N**2]`になる。
- 自分自身への最短経路を算出できない
    - 自分自身の最短経路が`0`でかえってくる。今回のABC191Eのパターン。


※標準ライブラリのわかりやすい記事はこちら
[SciPyでグラフの最短経路を算出（ダイクストラ、ベルマンフォードなど）]
(https://note.nkmk.me/python-scipy-shortest-path/)

#ダイグストラ法
`list_Adj`は隣接リストです。
隣接リストの作り方は、#使い方の箇所をみてください。

```python:test.py
import heapq,math
def dijkstra(N,list_Adj,start,goal):
    dist = [math.inf]*N
    dist[start] = 0
    # retval = math.inf
    hq = []
    heapq.heappush(hq,(0,start))
    while hq:
        cost,no = heapq.heappop(hq)
        if dist[no]<cost:
            continue
        for g_no,g_cost in list_Adj[no]:
            # if g_no==goal:
            #     retval = min(retval,dist[no]+g_cost)
            if dist[g_no]<=dist[no]+g_cost:
                continue
            dist[g_no] = dist[no]+g_cost
            heapq.heappush(hq,(dist[g_no],g_no))
    return dist[goal]
    # return retval #自分自身への最短経路を算出したい場合はこっちをreturn

#使い方(ABC191Eのコードをそのままはっつけただけ)
N,M = map(int,input().split())

l = [[]*N for _ in range(N)]
for _ in range(M):
    a,b,c = map(int,input().split())
    a,b = a-1,b-1
    l[a].append((b,c))
for i in range(N):
    ans = dijkstra(N,l,i,i)
    print(ans if ans!=math.inf else -1)
```

おわり！
GoogleAppsScriptでGmailのメールをSlackに転送する

GoogleAppsScriptでGmailのの内容をSlackに転送するシステムを作りました。

## Gmailのメールを取得する
Gmailの受信リストを取得するのに[GmailApp](https://developers.google.com/apps-script/reference/gmail/gmail-app)を使います。

### Gmailのフィルタで取得するメールを絞る
特定の条件のメールを探すのに、`search()`メソッドを使います。条件フィルタは、専用の演算子を使って作ります。
例えば、以下のときは**未読になっているメール**に絞ります。

```javascript
GmailApp.search("is:unread")
```
フィルタのための演算子は、[演算子を使ったフィルタ条件の記述方法](https://www.howtonote.jp/gmail/filter/index4.html)を参照してください。

### その他メソッド
GmailAppの各メソッドを使って取得できる項目は以下の通りです。
- `getDate()`：受信日
- `getFrom()`：送信者
- `getSubject()`：件名
- `getPlainBody()`：本文

## 転送するメールを選別する
TwitterやGoogleなどのログイン通知、広告など、Slackに送信する必要のないメールを選別する関数を作成します。
まず、Slackに送信しないメールアドレス (`@`より後ろ) をまとめた配列を用意します。

```javascript
var ls = ["accounts.google.com", "twitter.com", "google.com", "github.com", "youtube.com", "docs.google.com"];
```

任意のアドレスと配列内のアドレスが`match`というメソッドで一致したとき`True`を返します。
つまり、メインの関数ではこの関数を呼び出し、`False`になったメールをSlackに転送すれば良いのです。

`match`メソッドは文字列ではなく、正規表現フォーマットにする必要があります。
正規表現にフォーマットする際は、`RegExp`を使います。
参考：[Google Apps Scriptで正規表現を使って必要な情報を抽出する最も簡単なスクリプト](https://tonari-it.com/gas-regular-expression/)

```javascript
function isBotAddress(mail) {
  var ls = ["accounts.google.com", "twitter.com", "google.com", "github.com", "youtube.com", "docs.google.com"];
  for (var i=0; i < ls.length; i++) {
    // 正規表現のフォーマット化
    var botAddress = new RegExp(".*@"+ls[i]);
    // 一致したときTrueを返す
    if(mail.match(botAddress)) {
      return true
    } else {
      continue
    }
  }
}
```

Slackに転送しないメールが増えたときはは、そのアドレスを配列に足すだけで解決します。

## 全体
`getFrom()`は、送信者のメールアドレス以外のものも含まれているので、事前にメールアドレスを抽出します。
参考：[Google App Script(GAS)でメールを抽出してSpreadSheetに書き出す](https://qiita.com/ran/items/28e2a4fb06af8ae230a2)

```javascript
var fromAddress = msg.getFrom().replace(/^.*<(.*?)>.*$/, "$1");
```

スクリプトを紹介すると、
- 返信がスレッドとして繋がっているので2次元配列になっているのでFor文を2回使っています。
- `markRead()`でSkackに送信したメールを既読にします。
- **Webhook**を使ってSlackに転送する関数は、[Googleformからのslack通知設定方法](https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9)を参考に作成しています。
- 本文部分を<code>```</code>で括ると、Slackではコードブロックで表示されます。(**表示画面**参照)

```javascript
function tenso(){
  var threads = GmailApp.search("is:unread");
  var msgs = GmailApp.getMessagesForThreads(threads);
  for(var i = 0; i < msgs.length; i++) {
    var msgsInthread = msgs[i];
    for (var j=0; j < msgsInthread.length; j++) {
      var msg = msgsInthread[j];
      // アドレス部分を取り出す
      var fromAddress = msg.getFrom().replace(/^.*<(.*?)>.*$/, "$1");
      Logger.log(fromAddress);
      if (isBotAddress(fromAddress)) {
        Logger.log("This is mail from BotAddress.");
      } else {
        var date = msg.getDate();
        var from = msg.getFrom();
        var subject = msg.getSubject();
        var body = msg.getPlainBody();
        var mailBody = "メールを転送します。\n"+ from +"さん\n日付："+ date + "\n*件名："+ subject + "*\n\n```"+ body+"```";

        // Go To Slack        
        sendToSlack(mailBody, "チャンネル名");
      }
      // 既読にする
      msg.markRead();
    }
  }
}
```
以下のようにSlackに表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/d1eaad68-4a02-19db-ebae-93d9dfa64c46.png" width=480px>
ThinkPad T480S(Windows10 Pro)で謎のフリーズが頻発したときの解決策

# 環境と症状

- 環境
 - ThinkPad T480S
 - Windows10 Pro (Homeでも確認済み)

- 症状
 - 昼夜問わずフリーズが発生
 - フリーズするタイミングがわからない
 - フリーズすると強制終了するしかない
 - キーボード・マウスともに反応しない

# 結論

Google Chromeの**「ハードウェア アクセラレーションが使用可能な場合は使用する」をオンにしていたから**だった．

Chromeの設定画面から詳細設定を開き，「ハードウェア アクセラレーションが使用可能な場合は使用する」をオフにして再起動．

これでレポートを書いてるときにCtrl+Sをしまくる必要がなくなった．安心．

ちなみに追加したSSDに入れたLinuxでは同機能をオンにしても今の所フリーズは発生していない．Windows特有の問題？

それにしてもめちゃくちゃ個人的な覚書（メモ）でしかない記事だなあ．
コピペで簡単！CSSでinput要素をおしゃれなフローティングラベルにする

https://myscreate.com/floating-label/
![lightsail01_header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593842/3687a837-07e5-5d46-e16f-68fa9784d391.png)
TPKeyboardAvoiding　textfieldやtextviewがキーボードに隠れる問題

# 実行環境
Xcode 12.2
Swift 5.3.1

# はじめに

ビルドしてtextfieldやtextviewに入力しようとするとキーボードにそれらが隠れてしまい入力できない問題を解決してくれる便利ライブラリがあります。コードは特に書かなくて大丈夫です。

# TPKeyboardAvoiding

`TPKeyboardAvoiding`というライブラリが先述したような問題を解決してくれます。

入力しようとすると勝手にスクロールしてキーボードがtextfieldやtextviewにかぶらないようにしてくれます。

では早速使い方を見ていきましょう。

```swift:podfile
pod 'TPKeyboardAvoiding'
```
podfileにライブラリ名を記述してpod installします。

そうしたら
`ScrollView`を追加して画面いっぱいに広げて上下左右0（currentviewに対して）にして`add constraints`してください。その上に`UIView`を敷いてこれまた上下左右0にして`add constraints`（scrollviewに対して）してください。それからその`UIView`の高さを1500くらいにしてください。これで今まであったエラーが解消されてると思います。

![スクリーンショット 2021-01-20 0.58.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943089/523baa1b-9c41-e7c8-5465-26efee03fced.png)

そうしたらscrollviewのクラスを上のように設定します。

それからUIViewの上にtextviewなりtextfieldなり置いて（レイアウトの設定忘れずに）ビルドして入力しようとしてみてください！自然にスクロールしてキーボードがtextfieldなどにかぶらないようになると思います！

スクロールの程度はUIViewの高さを調節して調整してください。

## 参考URL
[TPkeyboardAvoiding](https://github.com/michaeltyson/TPKeyboardAvoiding)
Flutter Doctor の cocoapods でハマった

ここだけ`flutter doctor`で出てくる指示通りではうまくいかなかったので、解決した方法をメモしておく。

# 環境
```
macOS Catalina v10.15.4
Flutter 1.26.0-17.3.pre
Dart 2.12.0
```

# homebrewをバージョンアップする

```
brew update
```
コマンドを実行すると

```
homebrew-core is a shallow clone.
homebrew-cask is a shallow clone.
```
という警告が出たので、指示に従って処理を実施した。

```
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
```
その後再びアップデートを実行した。

# Rubyをバージョンアップする
```
brew install ruby
```
その後は指示に従って諸々のパスを通す

```
You may want to add this to your PATH.

ruby is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have ruby first in your PATH, run:
  echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> /Users/[username]/.bash_profile

For compilers to find ruby you may need to set:
  export LDFLAGS="-L/usr/local/opt/ruby/lib"
  export CPPFLAGS="-I/usr/local/opt/ruby/include"

For pkg-config to find ruby you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/ruby/lib/pkgconfig"
```

パスを通した後は、`.bash_profile`を読み込み直すことを忘れずに

```
source ~/.bash_profile
```

バージョンが最新になっているか確認する

```
ruby -v
```
# cocoapods をインストール
```
sudo gem install -n /usr/local/bin cocoapods
```

これでiOSエミュレーターでもFlutterアプリを動かせるようになった。
【Ruby】sort を使わずにマージソートをする

# Rubyでマージソートのアルゴリズムを作る

あえてRubyのsortを使用せずにRubyでマージソートのアルゴリズムを書いてみる。

## マージソート

```ruby
def merge_sort(array)
  return array if array.length <= 1
  mid = array.length / 2
  first_array = array.slice(0..mid - 1)
  second_array = array.slice(mid..-1)

  first_array = merge_sort(first_array)
  second_array = merge_sort(second_array)

  result = []
  until first_array.empty? and second_array.empty?
    if first_array.empty?
      result.concat(second_array)
      second_array.clear
    elsif second_array.empty?
      result.concat(first_array)
      first_array.clear
    else
      if first_array.first < second_array.first
        result << first_array.shift
      else
        result << second_array.shift
      end
    end
  end
  result
end

puts "スペースで区切って数値を入力してください"
list = gets
print merge_sort list.split(" ").map(&:to_i)

```

# 参考文献

Rubyのsort組み込みライブラリ
https://docs.ruby-lang.org/ja/latest/method/Array/i/sort.html

Wikipedia マージソート
https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88#:~:text=%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88%E3%81%AF%E3%80%81%E3%82%BD%E3%83%BC%E3%83%88%E3%81%AE,%E4%BD%9C%E6%A5%AD%E3%81%AF%E4%B8%A6%E5%88%97%E5%8C%96%E3%81%A7%E3%81%8D%E3%82%8B%E3%80%82
Goでリスト内の合計値を返す

# はじめに
リスト内の合計値を求めることが幾度かあったので、備忘録のためメモ

## リストの合計値を返す関数
### リストがintの場合
```
package main

// リストの合計値を返す
func total(data []int) int {
    total := 0
    for i := 0; i<len(data); i++ {
        total += data[i]
    }
    return total
}
```

### リストがstringの場合
```
package main
import "strconv"

// リストの合計値を返す
func total(data []string) int {
    total := 0
    for i := 0; i<len(data); i++ {
        value, _ := strconv.Atoi(data[i])
        total += value
    }
    return total
}
```

## 利用例
### リストがintの場合
```
package main
import "fmt"

func main() {
    test := []int{7, 8 ,1, 4, 3, 21}

    fmt.Println("合計値:", total(test))}

// リストの合計値を返す
func total(data []int) int {
    total := 0
    for i := 0; i<len(data); i++ {
        total += data[i]
    }
    return total
}
```

### リストがstringの場合
```
package main
import "fmt"
import "strconv"

func main() {
    test := []string {"7", "8" ,"1", "4", "3", "21"}

    fmt.Println("合計値:", total(test))}

// リストの合計値を返す
func total(data []string) int {
    total := 0
    for i := 0; i<len(data); i++ {
        value, _ := strconv.Atoi(data[i])
        total += value
    }
    return total
}
```
GPT とは (パーティション形式について調査)

## 勉強前イメージ

UEFIで使われる何か....
UEFI → GPT ってざっくりなイメージ

## 調査

GPT とはパーティション形式 で、他にも種類があり全部で2つある

- MBR形式
- GPT形式

### MBR形式

`Master Boot Record` の略で、古いタイプのパーティション形式になります。
基本構造としては以下になります。

- MBRセクター
- パーティション
	- プライマリーパーティション1
	- プライマリーパーティション2
	- プライマリーパーティション3
	- プライマリーパーティション4 または 拡張パーティション

パーティションは2種類あり、詳細は [こちら](https://qiita.com/miyuki_samitani/items/99b3325e7bf7b399fb88) に記載していますが
プライマリー(基本)パーティション と 拡張パーティション があります。
プライマリーパーティションは4つまでしか作ることができず、
4つ以上作成したい場合は、1つのプライマリーパーティションを拡張パーティションにしてその中に論理パーティションを作成する必要があります。

### GPT形式

`Globally Unique IDentifier Partition Table` の略で、新しいタイプのパーティションテーブルで
windowsではGPTに対応したのはVista以降でXP以前は使用することができません。
また、32bitは対応してないです。
基本構造としては以下になります。

- 保護MBR
- プライマリーGPTヘッダー
- パーティションエントリー
- パーティション
- バックアップパーティションエントリー/プライマリーGPTヘッダー

GPTはMBRとは違い、無制限にプライマリーパーティションを作成することができます(OSによって制限されることはあります)。
MBRではプライマリーパーティションのかわりに拡張パーティションを使っていましたが、
プライマリーパーティションをたくさん作れるので拡張パーティション・論理パーティションは存在しません

### MBR形式 と GPT形式 の違い

- ブートモードの違い
	- MBR形式 : BIOSモードをサポート
	- GPT形式 : UEFIモードをサポート
- ディスク容量の違い
	- MBR形式 : 最大2TBをサポート
	- GPT形式 : 2TB以上をサポート
- パーティションの数の違い
	- MBR形式 : プライマリーパーティションが4つまで
	- GPT形式 : 無制限(OS側で制限がある可能性がある)

## 勉強後イメージ

前に、パーティションの種類について調べたときに拡張パーティションの役割がよくわからなくて、
GPTだったらプライマリーパーティション無制限に作れるのに拡張パーティションの必要ある？って思ったけど、
拡張パーティションはMBRのためのパーティションだったのか

## 参考

- [完全解説｜MBR と GPTの違い、それぞれの特徴、確認方法、相互変換方法など](https://jp.easeus.com/partition-manager/mbr-gpt-features-differences-convert-methods.html)
- [MBR形式とGPT形式の違い(パーティション)](https://pc-kaizen.com/difference-between-mbr-and-gpt)
Webサーバー・データベースの設定を行う

##Webサーバーの設定

###設定ファイルの編集

まずは設置したサイトの設定を行います。

```bash
sudo vi /etc/httpd/conf/httpd.conf
```

ここでDocumentRootの設定を、設置したLaravelアプリケーションの公開フォルダに変更します。

```conf
DocumentRoot "/var/www/app/public"
```

またアプリケーションのフォルダでLaravelの.htaccessが有効になるよにしておきます。
＜Directory /var/www/html＞の設定がありますのでその後に設定を追記します。

```conf
<Directory /var/www/app/>
    Options FollowSymLinks
    AllowOverride All
</Directory>
```

###バーチャルホストの設定

　Apacheにバーチャルホストという設定があり、アクセスされたホスト名によってサーバー内のどこにアクセスさせるか設定することで複数アプリケーションを設置できる機能があります。
　/etc/httpd/conf.dに設定ファイルを入れると自動的に読み込まれますので、そちらにapp.confという設定ファイルを新規作成する。

```bash
sudo vi /etc/httpd/conf.d/app.conf
```

下記を入力します。yourhost.example.comは今回利用されるホスト名を入力してください。サンプルを試す場合はAWSの『IPv パブリックIP』を入力します。

```conf
<VirtualHost *:80>
    DocumentRoot /var/www/app/public
    ServerName yourhost.example.com
</VirtualHost>
```

設定ファイルの変更をWebサーバーに反映させるため、Apacheの再起動を行います。

```bash
sudo service httpd restart
```

これでApacheの設定は完了です。

###動作確認

Webサーバーの設定が正常に行えているか、アクセスしてみる。
公開フォルダにあるfavocon.icoやrobots.txtにアクセスする。
『http://外部IP/robots.txt』で中身が表示されていれば問題なし。

##データベースの設定

###RDSコンソールへ

- サービスメニューから『rds』と入力する
- 『データベース作成』を押下する
- MySQLを選択する
![](https://gyazo.com/e83f70d2240926e072f535ffe062ae06.png)
- 無料利用枠を設定する
![](https://gyazo.com/c63881614d8a4f10a59d66a86f1d6b12.png)
- DBインスタンス識別子
    - 自由に指定して大丈夫。デフォルトのままでもOK。
- マスターユーザー名設定
- マスターパスワード名設定
- 1つ目のデータベース指定
![](https://gyazo.com/6c7b9b662c8b0ed915c544a337b39c2d.png)
- 『データベース作成』ボタンを押下する

###セキュリティグループ

DBを作成した際には、defaultのセキュリティグループに割り当てられています。
こちらにEC2と同じセキュリティグループを割り当てる。
（『アクション』⇨『ネットワーキング』⇨『セキュリティグループの変更』へと進む）
3byteの符号あり表現について

2021/2/11 コメントの内容でソースコード例を修正しました

##はじめに
通信プロトコルで３byteの符号ありをどう表現するか悩んだのでここにまとめる．
1byte, 2byte, 4byteのデータならそれぞれchar, short, intでキャストすれば終了
じゃあ，3byteならどうする？？？
ちゃんと符号付数値表現について把握する必要がある．
結構，ネットを見ると色々な解釈をしていて，怪しい記事もいっぱいだった．

##符号付数値表現とは
コンピュータで負の数を表す方法は、実は複数存在。二進記数法を拡張して負の数を表す方法（符号-仮数部、1の補数、2の補数、エクセスN）のうち，大体は2の補数表現を使う．

###そもそも2の補数(two's complement)って？

```
2の補数とは2進数表示したものに、数字の0と1を入れ替え、1を足したもの
```

補数とはある基数法において、ある自然数 a に足したとき桁が1つ上がる（桁が1つ増える）数のうち最も小さい数という意味．すごい分かりづらいが，次の例だと補数の意味がわかりやすい．

+ ７に対しての３　足したら10になる
+ 11に対しての89　足したら100になる
+ 256に対しての744　足したら1000になる

つまり桁が上がる数値を補数というわけ．
2の補数って表現自体がわかりづらさを生んでいる気がするが，
要するに対象Aに対して足したら桁が上がる数値BのBのことを補数と呼び
それは，**2進数表示したものに、数字の0と1を入れ替え、1を足したもの**で求まるということ


###なぜ2の補数が優れているか
詳細は割愛するが，1の補数表現が昔のコンピュータでは使われていた．1の補数表現では加算したときに桁上り(キャリー）が発生した場合に，キャリー分も加算してあげる必要がある．２の補数ではそれが必要なく普通にビット演算するだけで良い．

##3byteの符号付き数値表現
まずコンピュータでは3byteの型は存在しないので，int(32bit)でキャストする必要がある．
ここではデータ転送側が，ビッグエンディアンかつ，24-32bit目には別データを格納して転送すると想定する．エンディアンや符号付き表現はIF仕様に合わせて注意する必要がある．

int型では，3byteの補数表現を認識しないため，3->4byteの補数表現に変換してあげる必要がある．これは3byte目の先頭bitが0か1かに応じて残りの4byte領域を埋めれば良い

[データ受信側]
これを実現するための一例

``` c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int32_t hoge(const uint8_t srcv[3])
{
    int32_t val = (int32_t)srcv[0] << 16 | (int32_t)srcv[1] << 8 | srcv[2];
    if (srcv[0] & 0x80) {
        val |= (int32_t)0xff000000ULL;
    }
    return val;
}

int main(void)
{
    //転送側はビッグエンディアンで転送
    printf("%08"PRIx32"\n", hoge((uint8_t[3]){0xff, 0xff, 0xf1}));
    printf("%08"PRIx32"\n", hoge((uint8_t[3]){0x12, 0x34, 0x56}));
}
```


[参考]
https://qiita.com/YamadaTakahito/items/79693ce08cad8baf130b

https://ja.wikipedia.org/wiki/符号付数値表現
AtCoder 生活107日目

[前回](https://qiita.com/flandrescarlet237/items/2e52daecdb3edb3bf1d9)

#107日目
今日は、灰色を1問解いた後にABC191に参加しました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC065|A|◯|9分11秒|

![Screen Shot 0003-02-06 at 23.33.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606053/ef958cb5-e173-3927-6aa9-ae41054a34e5.png)

##[ABC191](https://atcoder.jp/contests/abc191)

###A

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int v,t,s,d;
    cin >> v >> t >> s >> d;
    if(s*v >= d && t*v <= d)cout << "No" << endl;
    else cout << "Yes" << endl;
}

```

###B

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n,x;
    cin >> n >> x;
    rep(i,n){
        int a;
        cin >> a;
        if(a == x)continue;
        cout << a << " ";
    }
}

```

##[ABC065_A](https://atcoder.jp/contests/abc065/tasks/abc065_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll x,a,b;
    cin >> x >> a >> b;
    ll r = b - a;
    if(r <= 0){
        cout << "delicious" << endl;
        return 0;
    }
    if(r <= x) cout << "safe" << endl;
    else cout << "dangerous" << endl;
}

```

解くのにかかった時間：9分11秒


###最後に
今回のABCのC問題はかなり難しく感じた。またA問題も今までより少し難しくなってきている気がする。
ただ、今回はパフォーマンスを600まで戻せたのでこっからは伸びるだけだと思う。
MCMCをフルスクラッチで実装するトレーニング方法

# はじめに
東京大学・株式会社Nospareの菅澤です．

今回はベイズ統計を用いたデータ分析を実施する上で欠かせないマルコフ連鎖モンテカルロ法(いわゆるMCMC)をフルスクラッチで実装するためのトレーニング方法と，そのための参考書について紹介いたします．
最近ではstanのように，モデルと事前分布を記述するだけで汎用的にMCMCが実行できてしまう環境が整っていますが，


- **そもそもMCMCがどういう流れで動いているのか理解する**
- **stanなどの汎用ツールがうまく使えない(orうまく動かない)場面に遭遇したときに自分の手で実装できるようにする**

ためには，標準的なモデルでMCMCをフルスクラッチで実際に組んだ経験が重要になってくると思います．

# 参考書について
トレーニングのために私がオススメするのは以下の本です．

**[J. Chan, G. Koop, D. J. Poirier, J. L. Tobias 『Bayesian Econometric Methods』 ](https://www.amazon.co.jp/Bayesian-Econometric-Methods-Exercises/dp/1108437494/ref=pd_lpo_14_t_0/356-9149762-0335915?_encoding=UTF8&pd_rd_i=1108437494&pd_rd_r=73af9043-218f-46fb-a56d-257ef365fbd5&pd_rd_w=opknD&pd_rd_wg=7Wdq0&pf_rd_p=cb2cef9d-b0a3-4b58-a575-45abfc5e07e8&pf_rd_r=3NNHAGW6C25TKHEM460M&psc=1&refRID=3NNHAGW6C25TKHEM460M)**

学部レベルの統計学を理解していれば十分に読める内容になっていると思います．(英語の書籍というのが若干ハードルを上げておりますが...)
タイトルに「Econometric」とありますが，必ずしも計量経済的な内容だけ触れられているわけではなく，ベイズ統計学における標準的な内容は全般的にカバーされています．「Econometric」っぽさはパネルモデルやプロビットモデル，トービットモデルといった計量経済学で頻繁に用いられるモデルについて他書と比べて丁寧にカバーされている点でしょうか．

私は院生時代にこの本を輪読する講義を受講し，その資料準備の一環でRによるフルスクラッチの実装をやってみたことでMCMCを実装するノウハウをそれなりに習得することができました．また，実装に限らない理論的な内容(事後分布の解析計算など)も充実しておりますので，実装に主眼を置かない一般的なベイズ統計学の勉強にも適した参考書だと思います．

本書では主に以下の内容について扱われています．

- 基礎的なベイズ推測
- 事後推定と事後予測
- サンプリング手法 (乱数生成法)
- MCMC (一般論)
- 線形回帰モデル
- 階層モデル
- 潜在変数モデル
- 混合モデル
- 時系列モデル (単変量&多変量)
- 状態空間モデル


また，**本書の最大の特徴としては本文の説明が「問題→解説」形式で進められていく**ことです．
例えば「正規分布モデルの平均・分散パラメータに対する事前分布として正規分布・逆ガンマ分布を用いたベイズ推定」について扱う場合，本書では

**「正規分布モデルの平均・分散パラメータに対する事前分布として正規分布・逆ガンマ分布を用いた場合の事後分布を導出せよ」**

といった演習問題が出題され，直後にその解説(事後分布の導出)が記述されています．このように，「問題→解答」の形で様々な話題が小分けにされて登場するため「何を目的に何を考えればいいのか」が明確でわかりやすいという印象を受けました．

このような形式が様々な統計モデルにおいても同様に展開されます．例えば後半では「プロビットモデルにおけるギブスサンプリング(MCMCの一種)を導出せよ」といったような問題が登場します．文中では潜在変数を用いた条件付き事後分布が導出されますが，まずはこの導出を自分で考えてみることで，**事後分布の形からMCMCアルゴリズムを自力で設計する**トレーニングを行うことができます．

本題である「MCMCをフルスクラッチで実装するトレーニングの話」に戻ります．
前述のように，様々なモデルに対してMCMCアルゴリズムを「設計」する問題が本書では多数扱われますので，その際に**導出したアルゴリズムをRなどで実装し，シミュレーションデータや本に収録されているデータなどを使って実際に動かしてみる**ことで，座学としての内容だけでなくMCMCを自力で実装する経験も積むことができると思います．このような作業を様々なモデルで繰り返し行うことで，MCMCを実装するノウハウが自然と身につき，新しい統計モデルにおけるMCMCを実装する場面においても何らかの形で対処することができるようになるのではないかと思います．

ちなみにmatlabコードが[本のポータルサイト](https://web.ics.purdue.edu/~jltobias/bayesmethods.html)で公開されていますので，matlabユーザーまたはmatlabが読める人は答え合わせをすることができます．



# おわりに
今回はMCMCをフルスクラッチで実装するトレーニング方法について紹介しました．

今回紹介した本では，全体的に潜在変数を導入してMCMCを効率化するテクニック(data augmentationとも言いますが)について丁寧に触れられておりまして，個人的にはその部分がとても勉強になった記憶があります．

一方で，本書では医学統計などで頻繁に用いられるロジスティック回帰モデルに関してはほとんど扱われておりません．（計量経済学では二値データに対する回帰モデルとしてはプロビットモデルの方が標準的であることと，ロジスティック回帰はプロビット回帰と異なり潜在変数を用いた簡単なMCMCアルゴリズムが導出できない点が主な理由かもしれません．）

しかし，近年**Polya-gamma data augmentation**と呼ばれるロジスティック回帰に対する効果的な潜在変数表現が提案され，ベイズ統計学におけるロジスティック回帰への印象が変化しました．このような比較的最近の話題については今回紹介した本ではカバーできていないですが，[こちらの記事](https://qiita.com/gen_nospare/items/d560fdfd2f8b7257cc2a)で紹介しています．


株式会社Nospareでは統計学の様々な分野を専門とする研究者が所属しております．統計アドバイザリーやビジネスデータの分析につきましては[株式会社Nospare](https://bit.ly/38WtGZH)までお問い合わせください．
<a href="https://bit.ly/38WtGZH">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1023506/d5c625c0-d6f4-680b-d702-3c40f11d6c39.jpeg" alt="株式会社Nospare" width=400>
</a>
【G検定対策】シンギュラリティに対する著名人の主張まとめ

#シンギュラリティに対する著名人の主張をまとめてみた
試験に出るようだが、著名人と言っても「え？誰それ」みたいな人もいるので覚えやすいように
端的かつ明快に各自の主張をまとめてみることにした。
(wikiや書籍の情報を参考にしています）

##イーロン・マスク
ご存知、宇宙開発企業スペースXの創設者およびCEO。
先進技術大好きなイメージがあるが意外なことにシンギュラリティに危機感を持っている。
不安なことは調べようと言わんばかりに2015年、人工知能（AI）研究の非営利団体OpenAIを設立。

##レイ・カーツワイル
アメリカ合衆国の発明家、実業家、未来学者、思想家。
「2029年にはAIが人間並の知能をもつ。そして2045年にはシンギュラリティがやってくる」
という主張。シンギュラリティそのものの脅威に関してはあまり言及していない。
不老長寿の研究のために、1日に200錠ものサプリメントを摂取したりする面白い人。
万一死亡した場合はアルコー延命財団で人体冷凍保存を行う予定らしい

##ヒューゴ・デ・ガリス
オーストラリアの人工知能の研究者。
「シンギュラリティが21世紀の後半に来る。そのとき、人工知能は人間の知能の1兆の1兆倍（10の24乗）になる」

##ヴァーナー・ヴィンジ
アメリカ合衆国の数学者、計算機科学者、SF作家。
作家としても有名で、多くの一般人にシンギュラリティという言葉広めたとも言われているらしい。
シンギュラリティの定義を「機械が人間の役に立つふりをしなくなること」と定義した。
他の人とは違った視点でシンギュラリティを定義している。
人間に対して従順なものではなくなるという意味では若干脅威とみているのかも。


##スティーヴン・ホーキング
イギリスの理論物理学者。
「車椅子の物理学者」としても知られる。（1960年代、筋萎縮性側索硬化症（ALS）を発症したとされている）
「AIの完成は人類の終焉」と主張している。
関係ないが、宇宙からの信号らしきものを受信したと伝えられた際は「応答するな！応答するな！応答するな！」と厳しい警告を発していたらしい。結構慎重派な人なのかも。

##オレン・エツィオーニ
アレン人工知能研究所のCEO。
シンギュラリティが起こり人類が終末を迎えるという説に対しては、「馬鹿げている」と主張。
シンギュラリティそのものではなく、人類終末論に対しての批判であることに注意。

##ビル・ゲイツ
AIが高い知性を持つことに警鐘を鳴らしている。
どちらかというと脅威に思っている派の一人。
【AWS】AWS認定資格試験をピアソンVUEで申し込む時にクーポンを使う方法

先月クラウドプラクティショナーを取得した際に貰った特典を使って、
ソリューションアーキテクトの試験申し込みをしようとした際にクーポン使用方法が分かり辛かったので、自分のようなボケをかます人はいないと思うけど、記事として残しておく。

## 前提
AWS資格を既に取得しており、特典を保有している事。
https://aws.amazon.com/jp/certification/benefits/
特典にはいくつかありますが、ここで便宜上クーポンと言っているのが「再認定試験を含むすべての試験に適用可能な50%の割引」コードの事。他にも模擬試験が無料になるコードなどもある。

## 手順
まずはAWS認定専用サイト上で特典のクーポンコードを発行する。
（資格を取得した事がある前提なので、AWS認定アカウントの件は割愛します。）

メニューの特典をクリック。

![スクリーンショット 2021-02-06 23.07.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/b7796a6e-164c-5d54-9897-49f7191d2dba.png)

` 50% Discount on your next Exam ` が試験の割引コードなので、ここで`特典を申請する`をクリックし、コードを発行する。コードはメモっておくか、コピーしておきましょ。

![スクリーンショット 2021-02-06 23.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/dbae8214-bca7-d99e-ce55-13c502f4f926.png)

ピアソンVUEから申し込みます。

![スクリーンショット 2021-02-06 23.20.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/0c83d6a1-1a46-a815-dcfc-56f50462daab.png)

ローカルのテストセンターでの受験かオンライン受験かで支払い方法入力画面までのプロセスは微妙に違うと思うけど、クーポンを使用するのはクレジットカード情報を入力するタイミングなので忘れないように。

![スクリーンショット 2021-02-06 23.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/da6b6870-0bd0-d7c9-9157-074181ee4e06.png)

ここで`バウチャーまたはプロモーションコードを追加`をクリックすると、、、
![スクリーンショット 2021-02-06 23.32.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/213ceb1f-904b-da6d-033b-899c2fc745e6.png)
コードの入力フォームが出てくる。さっき発行したコードをコピペすればOK

めでたしめでたし。。。
【Woocommerce】チェックアウトページにカスタムフィールドを追加する

#はじめに
wordpressのECプラグインであるWoocommerceの記事です。
チェックアウトページ（商品を決済する画面）にお客様情報（名前や住所）を入力するフィールドがあります。そこに固有のフィールドを追加したいなぁと思い、いろいろと調べたのですが日本語の記事がないようだったので、備忘録として残しておきます。Woocommerceを使用したことがある方向けです。

#やること
　- チェックアウトページの備考欄の下にテキストフィールドを追加する
　- 追加したフィールドに記載した内容が、woocommerce管理画面の注文詳細で確認できる

#完成イメージ
###チェックアウトページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187747/cfe6bbdc-46f6-c2ec-00e4-cd3b9ff4618f.png)

###注文詳細
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187747/a4003f9d-ac66-e106-0a1c-52416e28b9c1.png)

#コード
下記コードをfunctions.phpに記載します。ただし、テーマが更新されてしまうと追加したコードは消えてしまうので、安全に実装するのであれば、専用のプラグインを自身で作成してその中に記載するのが良いです。

```
//備考欄の下にテキストフィールドを追加する
//ここではアクションフックを使って追加しています。もし別のところに追加したい場合は下記のサイトを見て適切なフックを探してください。
// https://www.tychesoftwares.com/woocommerce-checkout-page-hooks-visual-guide-with-code-snippets/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
    
	echo '<div id="my_custom_checkout_field"><h2 style="margin:30px 0 10px;">タイトル</h2>';
	?>
	<?php 
	woocommerce_form_field( 'custom_field', array(
		'type'          => 'text',
		'class'         => array('form-row-wide'),
		'label'         => __('ラベル'),
		'placeholder'   => __('お名前をご入力ください'),
		), $checkout->get_value( 'order_gift_name' ));

	echo '</div>';
	?>
	<?php 
}

//追加したカスタムフィールドに記載された内容を保存する
//上記のwoocommerce_form_fieldの第一引数に渡されている'custom_field'がinputのname属性として渡るので'custom_field'でPOSTデータを受け取りことができます。
//update_post_metaの第二引数には保存したカスタムフィールドを一意に表す文字列を指定します。
function my_custom_field_update_meta( $order_id ) {    
	if ( ! empty( $_POST['custom_field'] ) ) {
		update_post_meta( $order_id, 'my_custom_field', sanitize_text_field( $_POST['custom_field'] ) );	}
        
    
}
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_field_update_meta' );

//保存したフィールドの内容を注文詳細画面に出力します
//'my_custom_field'で保存しておいたので、それをget_post_metaでとってきます。
//第三引数には必ずtrueを設定してください。trueにすることで保存した内容が返されます。
function my_custom_gift_field_display_admin_order_meta($order){    
    echo '<p><strong>'.__('追加フィールド').':</strong> ' . get_post_meta( $order->id, 'my_custom_field', true ) . '</p>';
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_gift_field_display_admin_order_meta', 10, 1 );
```
raidの定期チェック

自分のサーバではraid5で12TBのストレージを運用しています。
これに何かあったらすぐに対処したいので障害が起きたらメールで通知が来るように設定しておきます。

~~~shell:chkraid.sh
cat /proc/mdstat | grep _ > /dev/null
if [ $? = 0 ]; then
        # raidでエラー発生
        cat /proc/mdstat | mail -s "raid error!" user@hoge.com
else
        echo "raid check success."
fi
~~~

こんな感じのスクリプトを用意します。
エラーチェックの方法は正規の方法が分からなかったので、/proc/mdstat の中に`_`があったらエラーとみなし、/proc/mdstatの内容をメールで送るようにしました。

追記：
`/sbin/mdadm --monitor --scan -1 --test`
でエラー発生時ではなく実行時にメールが飛ぶのでこれでもいいかな。

正常に動くことを確認したら

~~~shell:/etc/cron.d/raid_chk
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
#17 *   * * *   root    cd / && run-parts --report /etc/cron.hourly
10 0 * * *      user1  /home/user/scripts/chkraid.sh >> /home/user1/scripts/cron.log
~~~
このようなファイルを作成してcronで定期的に実行させます。
とりあえず一日一回実行し、出力をログに残します。

メールが飛んでこないことを祈りましょう。
ランチにPicoはいかがでしょうか～第3話　Micro Python版Blink an LED～

ごきげんよう、ちゃまおです。

[第2話](https://qiita.com/Chamaotaku/items/bf7c8c36541987c95790)からの続きです。今回の記事ではMicro Python版のLチカについて解説していきます。とは言え、私はPythonについて詳しい訳では無いので非常にざっくりした解説になってしまう事を、ご了承下さい。

#ソースコードとThonnyでの実行方法
今回取り上げるコードは[Raspberry Pi PicoのPython SDK(以下、公式SDKドキュメント)](https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-python-sdk.pdf)p.13-14に載っているコードを参考にしながら、[第1話で取り上げたソースコード](https://qiita.com/Chamaotaku/items/4b21b4f86506f7ead13d)と同じ動作をするように修正したものになります。

```python
from machine import Pin
import utime

led = Pin(25, Pin.OUT)

while True:
    led.value(1)
    utime.sleep_ms(250)
    led.value(0)
    utime.sleep_ms(250)
```

ThonnyとRaspberry Pi Picoは、[第2話](https://qiita.com/Chamaotaku/items/bf7c8c36541987c95790)の最後に記載した所で止まっている(つまり、開発環境が整っている)と想定しています。

まずは、Thonnyにソースコードをコピペしましょう。終わったら保存しますが、その時に「This computer」と「Raspberry Pi Pico」のどちらに保存するか聞かれるので、「Raspberry Pi Pico」を選びます。

好きな名前で保存し終わったら、Thonnyの上部アイコン左から4つめの"Run current script"ボタンを押します。LEDがチカチカ光ったら成功です。

#ソースコード解説
ここからは、1行ずつコードの中身を解説してきます。

最初の2行に出てくる```from machine import Pin```と```import utime```でモジュールの読み込みを行っています。「コーディングするのに便利な機能を呼び出すよー」と言う意味です。モジュールの詳細は、[Pythonの公式ドキュメント](https://docs.python.org/ja/3/tutorial/modules.html)を読んで頂くのが良いと思います。
Micro Pythonで用意されているモジュールのうち、今回は["machine"](http://docs.micropython.org/en/latest/library/machine.html)と["utime"](https://docs.micropython.org/en/latest/library/utime.html)と言う名前のモジュールを使います。"machine"モジュールの中には、いくつかのクラスがあり、今回の場合は、"machine"モジュールの中の["Pin"](http://docs.micropython.org/en/latest/library/machine.Pin.html)クラスを呼び出しています。モジュールとかクラスって何だろう？と疑問に思われる方もいらっしゃるかと思いますが、ここでは説明を省略させて頂きます。

```led = Pin(25, Pin.OUT)```は、「Raspberry Pi Picoに搭載されているGPIOピン25番を、ledと言う名前で、出力(OUTPUT)として定義するよ」と言う意味です。()内の1番目でGPIOピン番号、2番目でピンの入出力状態を指定する為、例えばGPIOピン10番を入力(INPUT)として使用したい場合は```Pin(10, Pin.IN)```となります。

```while True:```以下では、繰り返しの内容が書いてあります。```led.value(1)```はピンの状態を表しています。```value()```の数字が"1"の時はTrue、つまりスイッチONの状態です。逆に数字が"0"の時はFalse、つまりスイッチOFFの状態です。

```utime.sleep_ms(250)``` は、「250ms待つよ」と言う意味です。250の数字を1000に変更すると、Lチカの間隔が1000ms(1秒)になります。

解説は以上となります。お疲れ様でした。

#次回予告
[第2話](https://qiita.com/Chamaotaku/items/bf7c8c36541987c95790)の冒頭に書いた問題が一応解決したので、次回はC/C++開発環境の導入について解説する予定です。
そうだ、SQLを勉強しよう②

#はじめに
無理に暗記しようとせず、文や句の意味を理解しておくと、覚えやすいとこに気づきました。

##4つも命令文の基礎
###共通している部分

- 最初に命令文がくる(SELECT,UPDATEなど)
- 必ず、テーブル名を書く

###違い

- テーブル名を書く直前の句が違う。
- 条件を指定しない操作もある。 

表にまとめると…

|操作|検索|更新|削除|追加|
|---|---|---|---|---|
|命令|SELECT|UPDATE|DELETE|INSERT|
|テーブル指定|<font color=lightgreen>FROM</font>|<font color=red>なし</font>|<font color=lightgreen>FROM</font>|INTO|
|条件の指定|<font color=blue>WHERE</font>|<font color=blue>WHERE</font>|<font color=blue>WHERE</font>|<font color=red>なし</font>|

- UPDATE文は、テーブル名を記述したあとで、何を更新するのかSET句で記述する。
- INSERT文は、既存のテーブルに何か行うのではなく、新規で追加する操作なので、条件の指定はしない。
- SELECT文だけ、表を返してくる。
- DELETE文でWHERE句で行を指定しないと、全件削除！！

##感想
学習を始めたばかりだけど、
SQLはパズルみたいで、理解できると楽しいし、Rubyなどのプログラミング言語と違ってある程度ゴールが見えているから、モチベーションも維持しやすいと感じています。
【基本情報技術者】2進数の足し算と10進数へ変換

2進数11.1111と1.1101を加算し、10進数に変換する

【解説】
2進数11.1111+1.1101の結果を10進数に変換する方法を説明してみたいと思います。

筆算で書いてみると
 11.1111
+ 1.1101　となります

この結果
111.1100となり、
これを10進数に変換していきます。

2進数100を10進数に直すと4
2進数10を10進数に直すと2
2進数1を10進数に直すと1
2進数.1を10進数に直すと0.5
2進数.01を10進数に直すと0.25

これらを全て足して
4 + 2 + 1 + 0.5 + 0.25 = 7.75
この値が2進数111.11を10進数に変換した値になります。


計算式は
1桁目はそのまま = 1
2桁目は1 * 2 = 2
3桁目は1 * 2 * 2 = 4
0.1桁目は1 / 2 = 0.5
0.01桁目は1 / 2 / 2 = 0.25

これらを全て足して
1 + 2 + 4 + 0.5 + 0.25 = 7.75
となり、上記の式とも一致しました。
いまさら聞けないFisher情報量とCramer-Raoの不等式

# Fisher情報量の定義

そもそもFisher情報量とはなんだろう。
大抵の教科書にはこんな定義が書いてあります。

```math
I = \rm E_{\theta}
    \left[
        \left(
            \frac{\partial}{\partial\theta}
            log \it f(X; \theta)
        \right)^2
    \right]
```

これを説明するのに、Cramer-Raoの不等式という不等式から考えると、スムーズです。このCramer-Raoの不等式というのは不偏推定量の分散の下限を与えるものです。
この不等式を証明するためには、微分と積分が交換可能だよ、とかまぁ色々難しい仮定が必要ですが、その結論だけを観てみましょう。

詳しく知りたい人はこちら。証明は[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%83%A1%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%A9%E3%82%AA%E3%81%AE%E9%99%90%E7%95%8C#%E6%AF%8D%E6%95%B0%E3%81%8C1%E3%81%A4%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AE%E8%A8%BC%E6%98%8E)に書いてあります。

# Cramer-Raoの不等式

## 概要（というか結論)

いま、ある$X_1, X_2, ..., X_n$は、確率関数$f(x; \theta)$によって発生する確率分布に従うとします。$T(X_1,X_2,...,X_n)$を$g(\theta)$の不偏推定量とすると、下記のような不等式が成り立つ。これがCramer-Raoの不等式です。

```math
V_\theta{T(X_1, X_2, ..., X_n)}\geqq\frac{g'(\theta)^2}{nI_X(\theta)} \\
I_X = \rm E_{\theta}
    \left[
        \left(
            \frac{\partial}{\partial\theta}
            log \it f(X; \theta)
        \right)^2
    \right]
```

なんだか難しいですが、$T(X)$が$g(\theta)$の不偏推定量であるということは、$E[T(X)]=g(\theta)$ということです。

## 正規分布の場合

具体例で考えてみましょう。みんな大好き正規分布です。
正規分布の場合のパラメータは、$\theta=(\mu, \sigma^2)$と考え、不偏推定量は下記と計算できます。

$$
T(X_1, X_2, ..., X_n) = (T_1, T_2) = (\overline{X}, \frac{1}{n-1}\Sigma(X_i - \overline{X})^2)
$$

さて、ここでサンプリングしたデータで与えられる$T_1$, $T_2$は、どの程度信頼のおけるデータとなるのでしょうか。もう少し良い言い方をすると、どの程度良い統計量なのでしょうか。  
当然、サンプリングするデータによって統計量はばらつきを持ちます。ばらつきは小さい方が良いですよね。ですので、統計量の分散を考える必要があるわけです。

細かい計算は割愛しますが、$I_X$を頑張って計算していくと、こんな式になります。

```math
I_X(\mu)=E_\theta[\frac{\partial}{\partial\mu}log\Pi f(x_i; \theta)]^2=\frac{n}{\sigma^2} \\
I_X(\sigma^2)=E_\theta[\frac{\partial}{\partial\sigma^2}log\Pi f(x_i; \theta)]^2=\frac{n}{2\sigma^4}
```

最初のCramer-Raoの不等式に代入してやれば、下記が得られます。

$$
V_\theta(T_1)\geqq\frac{\sigma^2}{n},V_\theta(T_2)\geqq\frac{2\sigma^4}{n}
$$

ここで$I_X$にはデータ数$n$が含まれていますので、直感に合います。つまり、データが沢山とれてないと、最低でもそれなりに分散が大きくなってしまい、ろくな推定量になりません、ということです。ただし、これは下限を述べるものであり、上限を述べるものではありませんので、注意が必要です。

## 有効推定量

1式目($T_1$に関する式)の左辺はどうなるでしょうか。下記はとても簡単に算出ができます。

$$
V_\theta(T_1)=V_\theta(\overline{X})=\frac{\sigma^2}{n}
$$

ここで、左辺と右辺が一致しているのがわかります。つまり$T_1$に関しては、Cramer Raoの不等式の下限を表しています。これは一様最小分散不偏推定量(UMVUE)と呼ばれ、良い推定量です。  
$T_2$についてはどうなるでしょうか。実はこちらは計算していくとCramer Raoの下限にはなりません。しかしそれでも$T_2$の推定量はUMVUEになります。その解説はまた気が向いたら。Cramer Raoの不等式は下限を与えるだけで、その下限設定は少し甘いこともあるということになります。

# 実験

本当に正気分布の平均値や分散の不偏推定量は、上記のFisher情報量の逆数で表される程度の分散を持つのか実験してみましょう。

下記は実験結果です。正規分布$N(0, 5^2)$でデータを沢山作成し、その中から2~30個までサンプリングの数を変えたときの、"平均"の"分散"を描きました。

薄いオレンジの色が、Fisher情報量の逆数です。
青いX印が、データを複数回サンプリングし平均の分散を計算したものです。

![mean.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204712/43124a0a-c156-f1d3-b230-797e720032a2.png)

今回はCramer Raoの不等式の下限と、データから求める平均の分散が等しくなるので、だいたい同じラインに乗ってきます。データを増やせば、平均の分散は小さくなっていきます。

# おわりに

僕らが観測している不偏推定量も、平均的に良いというだけで、分散を持つことを少しだけ考えることができました。自分たちが観測しているデータがいったい何者なのか、よく考えながらモデリングなどを進めていけると良いなぁと思います。
HerokuでデプロイしたときにSkyWayビデオチャット画面が表示されない原因

#プログラミング勉強日記
2021年2月6日


#環境説明

環境：Windows

SkyWayを用いてビデオチャットアプリを作成し、Herokuを使ってデプロイした。ローカルでは普通に動くが、本番環境ではchromeにビデオチャット画面にアクセスした際、カメラと音声のアクセスができなくなっていた。(画面自体は表示され、chromeのデベロッパーツールではエラーがない状態)

#対処法
　localhost以外の通信からの場合は、<b>`https`</b>にする。
　`http://アプリ名.herokuapp.com/`→`https://アプリ名.herokuapp.com/`にすることで解決した。

#httpとhttpsの違い
　HTTP：Hyper Text Transfer Protocolの略で、ページのデータをサーバーとクライアントの間で通信するときの通信規約のこと。通信内容は暗号化されていない。
　HTTPS：Hyper Text Transfer Protocol Secureの略で、HTTP同様ページのデータをサーバーとクライアントの間で通信するときの通信規約のこと。通信内容が暗号化されている。

　つまり、通信が暗号化されているかどうかが違う。httpから始まるサイトは暗号化されていなく、httpsから始めるサイトは暗号化されて通信されている。
WSL Docker のデータ保存場所を変更する

# WSL の Docker のデータ配置場所を変更する

## ご注意

* 実践する際は自己責任でお願いします。
* 運が悪いと Docker Desktop が死にます

## はじめに

Docker Desktop for Windows を WSL で使用する場合、次のパスにデータが保存されます。

*  `C:\Users\<USER>\AppData\Local\Docker\wsl\data` 

C ドライブから変更したい人などのために手順を記載します。

## 手順

1. Docker Desktop をインストールしなおす
   * しなおすほうが成功率が高いです
1. Docker Desktop を終了する
1. すべての WSL ディストリビューションを終了する

   ```sh
   wsl --shutdown
   
   # すべてのディストリビューションが Stopped になっていれば OK
   wsl -l -v
     NAME                   STATE           VERSION
   * Ubuntu-20.04           Stopped         2
     docker-desktop-data    Stopped         2
     docker-desktop         Stopped         2
   ```

1. Docker のデータディストリビューションをファイルに出力

   ```sh
   wsl --export docker-desktop-data docker-desktop-data.tar
   ```

   * Docker のデータは `docker-desktop-data` で管理されています。
   * `docker-desktop-data.tar` は任意の出力先パスに変更しても OK です。

1. `docker-desktop-data` ディストリビューションを削除

   ```sh
   wsl --unregister docker-desktop-data
   ```

1. `docker-desktop-data` をインポート

   ```sh
   mkdir E:\wsl\distro\docker-desktop\data
   wsl --import docker-desktop-data E:\wsl\distro\docker-desktop\data docker-desktop-data.tar --version 2
   ```

   * `E:\wsl\docker-desktop-data` 以下に出力する場合は上記です。

1. 動作確認する
   * うまくいかない場合、 `docker-desktop-data` だけでなく `docker-desktop` も移動すると解決するかも
      * @bridgenail24 さん、コメントありがとうございます！
1. 出力した TAR ファイルは不要なら削除する

   ```sh
   rm docker-desktop-data.tar
   ```

## wsl --import で失敗する場合

### 解決策1: WSL 1 としてインポートして WSL 2 に変更する

```sh
wsl --import docker-desktop-data E:\wsl\distro\docker-desktop\data docker-desktop-data.tar --version 1
wsl --set-version docker-desktop-data 2
```

### 解決策2: WSL 2 の設定を変更する

```conf:~/.wslconfig
[wsl2]
memory=8GB
swap=64GB
```
ubuntu 20.04 LTS server でpostfixをインストールしgmailをサーバに設定する

システムに異常が発生した時にメールで通知したいのでpostfixをインストールしgmailサーバでメールを送るように設定しました。
メールサーバの設定は昔のsendmail設定の複雑怪奇さの印象しかないのでgmailサーバを使わせてもらいます。

[Gmail 経由でメールを送信するように Postfix を設定する](https://blog.ymyzk.com/2017/06/postfix-smarthost-gmail/)

設定ではこちらを参考にさせていただきました。というかそのままです。

## postfixのインストール
`$ sudo apt install postfix bsd-mailx libsasl2-modules`
を実行して関連パッケージをインストールします。
設定画面が表示されるので、

- インストール種別の選択肢で`Internet with smarthost`
- SMTP relay hostに`[smtp.gmail.com]:587`

を指定します。

`/etc/postfix/sasl_passwd`
というファイルを作成してgmailの認証情報を記述します。
`[smtp.gmail.com]:587 <username>@gmail.com:<password>`
<>内は自分の環境に合わせてください。
パスワードは2段階認証を設定しているとエラーになるのでアプリパスワードを発行して使用してください。
[アプリパスワードの発行方法はこちら]

(https://support.google.com/accounts/answer/185833?hl=ja)

`sasl_passwd`ファイル補作成したら

~~~
$ sudo chmod 600 /etc/postfix/sasl_passwd
$ sudo postmap /etc/postfix/sasl_passwd
~~~
を実行し、

`/etc/postfix/main.cf`に

~~~
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
~~~
と追記します。

設定が終わったら
`$ sudo systemctl restart postfix.service`
でpostfixを再起動します。

## 動作確認

`$ echo "test" | mail -s "subject" user@hoge.com`
みたいなコマンドを実行してみます。
メールアドレスは送りたいメールアドレスを指定してください。

メールが届けば成功です。
`var/log/mail.log`にログが残っているはずなので気になる方は確認してください。
考えをまとめるには from エンジニアの知的生産術(マイピックアップ)

「[エンジニアの知的生産術](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93-%E2%80%95%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B3%E3%80%81%E6%95%B4%E7%90%86%E3%81%97%E3%80%81%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88%E3%81%99%E3%82%8B-WEB-PRESS-plus-ebook/dp/B07JFRF6MW/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2GRDGUXMBTF82&dchild=1&keywords=%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93&qid=1608975046&sprefix=%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%2Cstripbooks%2C272&sr=8-1)」を読み、今の自分にとって大切な考え方をピックアップ!


# 第5章. 考えをまとめるには

たくさんの情報を収集しインプットした後の状態を想定して、それを自分の中で整理していくプロセス

## 情報を書き出し、情報量を確認する

まずは、自分の中の情報を全て書き出す。この際に**重複を気にしてはいけない**
→　時間的に離れた自分が、それぞれの時に独立して「これは書くべきだ」と考えたということ = <font color="orange">重要度がとても高い情報であることの証<font>

## 繰り返しによる研磨

SNSの履歴にある数年前の投稿内容なども、過去に自分が書いた文章が、今の自分にとっての刺激となる。
例えば、3年前に自分が書いた文章を見て今でも重要だと思ったら、よりよく修正した上で再投稿するのは考えをまとめることに繋がる。
→　**自分の中の考えを長期にわたって磨いていくことが出来る & 記憶に定着する**
railsのpathヘルパーを変更

## はじめに
railsのpathヘルパーの変更方法を備忘録的に書きました。

## 変更方法
例えば下記のルート定義の場合

```ruby
get '/login', to: 'users#login'
```

pathヘルパーは`login_path`となります。
![スクリーンショット 2021-02-06 21.52.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057421/a1d82167-aa77-277c-ae7f-ce86c4c550c2.png)


例えば`users_login_path`に変更したい時は`as`を使って下記のように変更できます。

```ruby
get '/login', to: 'users#login', as: :users_login
```

pathヘルパーが`users_login_path`になりました。
![スクリーンショット 2021-02-06 22.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057421/5eb2b9a3-498e-3e47-b633-4bdd750476b7.png)

## 参考
[Railsドキュメント](https://railsdoc.com/routes)
AWS CloudShell で sl を動かしてみた

AWS CloudShell でslを動かしました。


```
sudo amazon-linux-extras install epel -y
sudo yum install sl
sl
```

参考:
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-enable-epel/

![AWS_CloudShell_sl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102457/e0c33f72-48d6-2d4c-81bd-fc5eecfbdbaa.png)
AWS ClientVPN 接続手順

## 概要

AWS ClientVPNを急遽使用することになったので、構築手順をメモとしてまとめます。

## 構成図

構成図は以下の通りです。


![名称未設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497547/23d9f26b-890e-a2c2-c3ad-12bd34ace612.jpeg)



## 手順

* ACMに自己証明書をインポートする。

公式手順通りに証明書の発行を行います。

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/client-authentication.html#mutual

```bash
$ git clone https://github.com/OpenVPN/easy-rsa.git
$ cd easy-rsa/easyrsa3
$ ./easyrsa init-pki
$ ./easyrsa build-ca nopass
$ ./easyrsa build-server-full server nopass
$ ./easyrsa build-client-full client1.domain.tld nopass
```

作成した以下証明書・秘密鍵を任意のディレクトリに保存し、ACMにインポートを行います。
公式手順はCLIですが、今回はGUI画面からインポートを行っています。

```bash
ca.crt     server.crt server.key  client1.domain.tld.crt        client1.domain.tld.key
```

![スクリーンショット 2021-02-06 17.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497547/0634626c-fa99-becf-29b1-e0a382cc762e.png)


* ClientVPN Gatewayの作成

クライアント側のIPv4 CIDR領域はVPC内のネットワークと重複しないよう設定します。

* クライアントからの受信を承認

認証タブの`受信の承認`を押下し、クライアントが接続できるネットワークの範囲を設定します。
宛先ネットワークについてはVPC領域全てを設定し、個別設定などは特に行っておりません。


![スクリーンショット 2021-02-06 18.01.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497547/1ce69458-9f6d-3f7d-876d-a24d944bf73d.png)


* 設定ファイルの修正

`クライアント設定のダウンロード`を押下し、ダウンロードした設定ファイルを修正します。
接続先ホスト名に任意の文字列を加え、証明書・秘密鍵の内容を追記します。

```
remote test.xxxxxxxxxx.amazonaws.com 443
.
.
.
<ca>
xxxxxxxxxxx
</ca>

<cert>
xxxxxxxxxxx
</cert>

<key>
xxxxxxxxxxx
</key>

reneg-sec 0
```

* 任意のClientVPNソフトを使用し接続確認

今回は`Tunnelblick`を使用し、VPN接続後インスタンスにSSH接続を行います。
インスタンスのセキュリティグループは、VPNに割り当てられるクライアントIPアドレスのCIDR領域を予め許可しておく必要があります。

```bash
$ ssh ec2-user@10.0.1.217 -i ~/.ssh/xxxxx.pem
Last login: Sat Feb  6 08:34:34 2021 from ip-10-0-1-39.ap-northeast-1.compute.internal

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

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-0-1-217 ~]$
```

プライベートIPアドレスで接続できることが確認できました。

## 終わりに

エンドユーザに影響するサービスではないので、本番環境も自己証明書で運用しても良いと思っています。
今回は簡単な手順なので、セキュリティグループなどは適宜見直す必要があります。
UbuntuへDockerをインストール

#概要
備忘録として書いております。
タイトル通りubuntuにdockerをインストールします。

#環境
Conoha VPS (ubuntu RAM 512MB)

##1. 事前準備
```:Ubuntu/terminal
$ sudo apt update
```


##2. パッケージのインストール
https経由でレポジトリを使用できるよう、下記でパッケージをインストールします。

```:Ubuntu/terminal
$ sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
```


##3. パッケージのインストール
Dockerの公式GPGキーを追加
正しく登録できると"OK"と表示されます。

```:Ubuntu/terminal
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

Dockerの公式GPGキーが追加されていることを確認するには、下記コマンドを実行します。

```:Ubuntu/terminal
$ sudo apt-key fingerprint 0EBFCD88
```


##4. Dockerのリポジトリを追加

```:Ubuntu/terminal
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```


##5. Dockerのインストール

```:Ubuntu/terminal
$ sudo apt install -y docker-ce
```


##6. Docker-Composeのインストール
一斉にコンテナを立ち上げられて便利なのでこちらも使えるようにします。

```:Ubuntu/terminal
$ sudo curl -L https://github.com/docker/compose/releases/download/1.28.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
```
上記のバージョン"1.28.2"は下記で最新のものを確認して、必要に応じて変更します。
https://github.com/docker/compose/releases

##7. 実行できるように
バイナリに対して実行権限を与える

```:Ubuntu/terminal
$ sudo chmod +x /usr/local/bin/docker-compose
```
完了後、適宜 docker-compose -vで確認します。


###参考
https://docs.docker.jp/compose/install.html
envコマンド

説明	| printenv	| env	| set	| export
--------|---------------|-------|-------|---------------
概要	| ・環境変数の一覧を出力。|・環境変数の一覧を出力。・特定コマンドのみ有効な環境変数を設定。（下欄で紹介しているコマンドを参照）|・シェル変数と環境変数の一覧を表示・シェル変数を表示するには echo $＜変数名＞とする|・環境変数の一覧を表示・環境変数を設定環境変数を表示するにはecho $＜変数名＞とする
環境変数対応|〇（環境変数が表示される）|〇（環境変数が表示される）|〇（環境変数が表示される）
シェル変数対応|×（シェル変数は表示されない）|×（シェル変数は表示されない）|〇（シェル変数は表示される）
【Swift】画像の色を変更するには？

# はじめに
iOSアプリケーションを開発していく中で、画像の色を条件によって変更させたいシーンに遭遇しました。
自分は、各色の画像を用意するものだと思っていましたが調べてみたところコードで変更できることを知ったので今回まとめます。

# 開発環境

- macOS Catalina version10.15.7
- Xcode version12.2
- Swift5

# 画像の反映方法
画像を反映させる際は、通常以下のように記載するかと思います。

```swift
imageView.image = UIImage(named: "画像ファイル名")
```

---

では画像の色を変更するにはどうすればいいのかと言うと、`withRenderingMode()`を用いてtintColorを指定することでできます。


```swift
imageView.image = UIImage(named: "画像ファイル名")?.withRenderingMode(.alwaysTemplete)
imageView.tintColor = .white //画像の色を白にする
```

ちなみにレンダリングモードの指定値は以下の通りです。解釈が間違っている可能性もあるため公式ドキュメントをご確認お願いします。

| レンダリングモード | 詳細 | 
|:-----------|:------------|
| withRenderingMode(.automatic)   |コンテキストのレンダリング（？）    | 
| withRenderingMode(.alwaysOriginal)   |  常に元の画像を描画    |
| withRenderingMode(.alwaysTemplete)   | 色情報を無視して、テンプレート画像を描画        |


参考
[公式ドキュメント：UIImage Changing the Image Attributes](https://developer.apple.com/documentation/uikit/uiimage)

[公式ドキュメント：withRenderingMode(_:)]
(https://developer.apple.com/documentation/uikit/uiimage/1624153-withrenderingmode)

[公式ドキュメント：UIImage .Rendering Mode](https://developer.apple.com/documentation/uikit/uiimage/renderingmode)

# まとめ
今回は画像の色を変更する方法についてまとめました。

以上