OmniAICreator/Qiita-1.07M huggingface dataset:
slackのbotを作成する

インターンの業務で、既存のAPIを叩いて情報をひっぱってくる予定だったが、どうもそのAPIを今後使わない方向でいるということで、今slackで勤怠管理とか色々やってるからそこで一緒に個人情報も入力できたら楽だよねってことで、slackのbotを作ることになった。
まずは、pythonでやるかjavaScriptでやるか比較してみる。

##flask
以下のurlを参考に実装した。
https://qiita.com/sh-tatsuno/items/55cd5f9e78b212fb57c2

なんかslackclientのバージョンでimportするモジュールの名前が違うみたいだから注意。

```python
import slack

slack_client = slack.WebClient(SLACK_BOT_TOKEN)
```
普通のflaskの処理でslackのbotを簡単に実現できた。
結晶格子の並進ベクトルの座標計算（Calculate xyz coordinates of translation vectors from cif format）

本稿は計算化学等で周期境界条件を用いた計算を行っている方向けのメモです。
並進ベクトル（Translation Vectors: TV）の長さと角度が既知であるユニットセルについて、格子点の3次元座標（TVの成分）を求める計算について述べます。結晶構造データベースから取得したCIFファイルに記載された結晶構造をxyzに変換するなどの際にご参照頂ければ幸いです。

# 結晶単位格子
AO系の結晶格子の一例を示します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697094/07922c04-837a-6bec-acfd-0190d4aedc0b.png" width=70%>
このような単位結晶格子は通常、$a$軸、$b$軸、$c$軸という3次元のベクトルによって記述されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697094/c4fc7e52-8e71-c655-3aa2-d2ead95838c8.png" width=70%>
$b$軸と$c$軸の成す角が$\alpha$、$c$軸と$a$軸の成す角が$\beta$、$a$軸と$b$軸の成す角が$\gamma$です。
軸の長さとそれらの角度が分かっていれば3次元のカーテシアン座標系（直交座標系）に変換することが可能です。

# カーテシアンへの変換

結晶格子を変換後の座標は一意に定まりません。
ここでは$a$軸を$x$軸に合わせて、$b$軸を$xy$平面に乗せるように変換します。

結果だけ載せると、

```math
\vec{a}=\left[\begin{array}{c}
|\vec{a}| \\
0 \\
0
\end{array}\right]
```

```math
\vec{b}=\left[\begin{array}{c}
|\vec{b}| \cos \gamma \\
|\vec{b}| \sin \gamma \\
0
\end{array}\right]
```

```math
\vec{c}=\left[\begin{array}{c} 
|\vec{c}| \cos \beta \\
\dfrac{|\vec{c}|(\cos \alpha -\cos \beta \cos \gamma )}{\sin\gamma } \\
|\vec{c}|\sqrt{1-\cos^2 \beta-\left(\dfrac{\cos \alpha -\cos \beta \cos \gamma}{\sin\gamma }\right)^2}
\end{array}\right]
```

となります。軸はすべて原点を始点としています。

因みにセルの体積$V$は$$V=|\vec{a}||\vec{b}||\vec{c}|\sqrt{\sin^2 \beta\sin^2 \gamma-\left(\cos \alpha -\cos \beta \cos \gamma\right)^2}$$で求められます。$V=\left|\vec{a} \cdot \vec{b} \times \vec{c}\right|$ としても求められますが、いまTVは

```math
\small \left[\begin{array}{ccc} 
|\vec{a}| & 0 & 0 \\
|\vec{b}| \cos \gamma & |\vec{b}| \sin \gamma & 0 \\
|\vec{c}| \cos \beta & \dfrac{|\vec{c}|(\cos \alpha -\cos \beta \cos \gamma )}{\sin\gamma } & |\vec{c}|\sqrt{1-\cos^2 \beta-\left(\dfrac{\cos \alpha -\cos \beta \cos \gamma}{\sin\gamma }\right)^2}
\end{array}\right]
```

という下三角行列になるように整理されているので、セルの体積は対角成分の積で表せます。

# 変換用コード

変換用のpythonのスクリプトを載せておきます。リスト内の数値は適当に書き換えて下さい。
なお、pythonでは三角関数の中身をラジアン単位にする必要があるので、$\pi/180$ を乗じて換算する必要があります。

```python:cartesian.py
import math

length = [6.18704,  2.91581,  7.28313] # a, b, c
degree_angle = [81.6066,  99.4557,  76.4221] # alpha, beta, gamma
angle = [i * math.pi/180.0 for i in degree_angle] # degree --> rad

a_axis = [0.0] * 3
b_axis = [0.0] * 3
c_axis = [0.0] * 3

a_axis[0] = length[0]
a_axis[1] = 0.00000
a_axis[2] = 0.00000

b_axis[0] = length[1]*math.cos(angle[2])
b_axis[1] = length[1]*math.sin(angle[2])
b_axis[2] = 0.00000

c_axis[0] = length[2]*math.cos(angle[1])
c_axis[1] = length[2]*(math.cos(angle[0])-math.cos(angle[1]) * math.cos(angle[2]))/math.sin(angle[2])
c_axis[2] = length[2]*math.sqrt(1-math.cos(angle[1])**2-((math.cos(angle[0])-math.cos(angle[1])*math.cos(angle[2]))/math.sin(angle[2]))**2)

print("TV",'{:>14.10f}'.format(a_axis[0]),'{:>14.10f}'.format(a_axis[1]),'{:>14.10f}'.format(a_axis[2]))
print("TV",'{:>14.10f}'.format(b_axis[0]),'{:>14.10f}'.format(b_axis[1]),'{:>14.10f}'.format(b_axis[2]))
print("TV",'{:>14.10f}'.format(c_axis[0]),'{:>14.10f}'.format(c_axis[1]),'{:>14.10f}'.format(c_axis[2]))
```
CSSの綺麗な書き方

#プログラミングの勉強日記
2020年8月24日
現在しているインターンでCSSの綺麗な書き方（見やすい）書き方を学んだのでまとめる。
更新があればその都度追記していきたいと思う。

#改行を作らない
　ソースコードは短く簡潔に書くことが大切なので、ソースコードには改行をしないようにする。

```css:例
.top {
  margin: 0;
  font-size: 16px;
}
.second {
  background-color: red;
}
```

#セレクタと中括弧の間にスペースが必要
　CSSはセレクタとプロパティと値で構成されていて、どの要素かを指定する部分をセレクタという。(クラス名とかID名にもスペースを空ける）

```css
p {
  /* 処理 */
}
```

#プロパティと値の間はスペースが必要
　以下のようにコロンと値の間にはスペースが必要。

```css
.top {
  width: 100%;
}
```

#まとめられる内容はまとめて書く(paddingやmargin)
　以下のようなコードの場合は`padding: 値`で四方向すべてを、`padding: 上下 左右`で水平方向を、`padding: 上 右 下 左`のようにまとめて書くことができる。

```css
.top {
  padding-left: 10px;
  padding-right: 10px;
  margin-top: 2px;
  margin-bottom: 3px;
  margin-right: 4px;
  margin-left: 6px;
}
```
　なので上記のコードは以下にまとめられる。

```css
.top{
  padding: 0 10px;
  margin: 2px 4px 3px 6px;
}
```
MacのUSキーボードの[英字/かな]切り替えのショートカットについて

# はじめに
Macbookを新調したときの備忘録です。久しぶりにUS配列のMacBook Air（2020） を購入したのでその時の設定変更に対するメモ書きになります。

# 変更内容
USキーボードショートカットキーのデフォルト設定が、MacBook Air(2020)の場合、以下の状態でした。

```
[control] + [space]
```
個人的に、このショートカットが使いづらく感じていたので（旧MacBook（自分の場合は、Mid2011）のように、spacekキーの左のキーと組み合わせて変換したい）、以下のように設定変更しました。

```
[command] + [space]
```

この設定は、[Dock]->[システム環境設定]->[キーボード]のメニューを開いて、
[ショートカット]->[入力ソース]の項目から割り当て可能です。
下図は割り当てた後になります。
![keyboard-conf2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696120/7e94c170-2762-6171-95e0-8147e376b79f.png)


また変更前のデフォルト設定では、 [command]+[space]キーが、「Spotlight」の検索に割り当ててたので
[control]+[space]で呼び出せるように設定を入れ替えてます。
![keyboard-conf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696120/54c963e7-f92e-78c3-0e5a-7203c072e372.png)


以上です。最後までお読みいただきありがとうございました。
【競プロ初心者向け】Pythonで競技プログラミングを始める上で覚えるべき3つの入力方法

**※コメントにてアドバイスをいただき、入力方法は2つに集約できることが判明したので加筆しました。**

2020年8月22日に競技プログラミングにPythonでデビューを果たしました。
参加したのは、日本で競技プログラミングといえばまっさきに思い浮かぶ[AtCoder](https://atcoder.jp/)です。

新しく学び始めたPythonをようと、実際にはその前に会員登録して、始める準備万端でした。
過去問を解いた時に？？ってなってしまい、心の物置部屋にそっとAtCoderに登録したことをおいてきていました。

# なぜ競技プログラミングに取り組めなかったのか？
その理由はシンプルです。

**そもそもPythonでの標準入力の部分で躓いたからorz**

もちろんそれまでにPythonの入門書も読破していたので、入力方法についてもinput使えばいいことはわかっていました。
しかし、inputに関する理解が圧倒的に足りていませんでした。

# Python入門書で扱うinputといえば

inputっていえば、Python入門書で環境セットアップ後の1,2章のところで登場します。
サンプルコードは控えますが、だいたいこんなアウトプットになるサンプルコードが掲載されています。

```
$:テキストを入力してね！：○○
$:こんにちは！○○
```

その後の章に進んでも、inputの様々な使い方を学ぶよりも、他の内容についての勉強にいきがちです。
その結果、inputについてわかっても、理解にまでは至っていなかったです。
それを競技プログラミングにチャレンジして思い知らされました。
あっという間に頭がフリーズし、AtCoderのタブを閉じてしまいました・・・

# 過去問を解いて分かった覚えるべき2つのinputの使い方
**※素晴らしいアドバイスを受け3つ→2つに修正しました。**

そんな中、きちんとコードを書く機会を増やしたことで、再び競技プログラミングに挑もうという意欲が湧いてきたので、AtCoderに再度舞い戻ってきました。

**「今回は俺わからなくても、フリーズせずにググろうと思うんだ」**

という決意の元、入力の方法からしっかり調べてみたところ、A,B問題はクリアできるようになりました。
C問題は、計算量O(N^2)に苦戦し、制限時間をオーバー「TLE」の壁に苦しみます…

そんな中、**自分が躓いて投げ出してしまった導入部分の「標準入力」は主に以下の2つに集約されることが判明しました。**

## 1つの整数を入力

```
a = int(input())
```

1行で入力する整数が1個のパターンです。2020年8月22日のAtCoder Beginner Contest 176のB問題がこのパターンでした。
ただ、1つの整数だけを入力するというケースは少なく、基本的に後述する2つのパターンと組み合わせて出題されるケースが多いです。

##複数個の整数またはリストとして整数を入力

```
a,b,c = [int(e) for e in input().split()]
A = [int(e) for e in input().split()]
```

複数個の変数に入力、または入力する数が決まっていない場合に、入力した整数をリストに格納します。
1行で整数を複数入力する際には、スペースで区切るため、分割できるようにsplit()が組み込まれています。
**リスト内包表記**というPythonの記法によって、入力した個数分だけ値を格納することができます。
複数個になるパターンはAtCoder Beginner Contest 176のA問題がこのパターンでした。
また、AtCoder Beginner Contest 176のC問題が1個の整数入力と、リストによる整数入力を組み合わせた形でした。

※元々は複数個の変数とリストでの整数入力は別の方法を紹介していましたが、コメントにて２つの方法は**リスト内包表記**によって統一できるとアドバイスいただきました。


この2つの入力方法を覚えれば、競技プログラミングの最初のつまづきポイントである標準入力を回避することができます。
もちろん、他にも色々な入力形式がありますが、あまり追求すると、頭がオーバーヒートします。
**覚えられないと高らかに宣言することも大切です。**

# まとめ・終わりに

競技プログラミングで最初のつまづき「標準入力」は以下の2つコードで回避

```
# 1つの整数を入力
a = int(input())
# 複数個の整数を入力
a,b,c = [int(e) for e in input().split()]
# リストとして整数を入力
A = [int(e) for e in input().split()]
```

A問題、B問題が解けると競技プログラミングへの意欲が湧いてきます！
EC2でPlantUML Server

### graphvizのインストール
```
sudo yum install -y graphviz
```

### [EC2へのMavenインストール](https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/iam-auth-connect-prerq.html)
```
sudo wget https://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
sudo yum install -y apache-maven
sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo
sudo yum install -y apache-maven
```

### [Javaのインストール](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-8-ug/amazon-linux-install.html)
```
sudo amazon-linux-extras enable corretto8
sudo yum install java-1.8.0-amazon-corretto-devel
sudo /usr/sbin/alternatives --config java
sudo /usr/sbin/alternatives --config javac
```

### [PlantUML serverのインストール、起動](https://github.com/plantuml/plantuml-server)
```
git clone https://github.com/plantuml/plantuml-server.git
cd plantuml-server/
mvn jetty:run
```
ファジング(fuzzing)

応用情報技術者平成30年秋期 午前問43

脆弱性検査手法の一つであるファジングはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/4f154236-a64a-7f5d-d196-8d1d17d04da6.png)

１、ファジング(fuzzing)とは、
検査対象のソフトウェア製品に「ファズ（英名：fuzz）」と呼ばれる問題を引き起こしそうなデータを大量に送り込み、その応答や挙動を監視することで(未知の)脆弱性を検出する検査手法です。

ファジングは、ファズデータの生成、検査対象への送信、挙動の監視を自動で行うファジングツール(ファザー)と呼ばれるソフトウェアを使用して行います。開発ライフサイクルにファジングを導入することで「バグや脆弱性の低減」「テストの自動化・効率化によるコスト削減」が期待できるため、大手企業の一部で徐々に活用され始めています。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
補足：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a1aba238-83ee-da17-80ca-ff6f5ca41ff7.png)


１、ポートスキャンの説明
サーバにFINパケットを送信し，サーバからの応答を観測して，稼働しているサービスを見つけ出す。

２、ログ分析の説明
サーバのOSやアプリケーションソフトが生成したログやコマンド履歴などを解析して，ファイルサーバに保存されているファイルの改ざんを検知する。

３、パターンマッチングの説明
ネットワーク上を流れるパケットを収集し，そのプロトコルヘッダやデータを解析して，あらかじめ登録された攻撃パターンと一致した場合は不正アクセスと判断する。


参照：
https://www.ap-siken.com/kakomon/28_aki/q45.html
ブルートフォース攻撃（＝総当たり攻撃）

応用情報技術者平成30年秋期 午前問42

ブルートフォース攻撃に該当するものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/08359a1e-9330-97e1-09d9-d6e1062c7ddc.png)

１、ブルートフォース攻撃は、パスワードクラックに用いられる手法の１つで、特定の文字数および文字種で設定される可能性のあるすべての組合せを試すことで不正ログインを試みる攻撃手法です。
※ブルートフォース攻撃（＝総当たり攻撃）


２、キーロガーの説明
コンピュータへのキー入力を全て記録して外部に送信する。
・キーロガー（Keylogger, またはKeystroke logging）とは、コンピュータ（パーソナルコンピュータ）へのキー入力を監視し、それを記録するソフトウェアもしくはハードウェアである。

３、リプレイアタック（Replay Attack）とは、
ネットワークの盗聴者がログインシーケンス（IDやパスワードを送る手順）をそのまま記録し、後にこのシーケンスを対象サーバーに投げることです。

４、セッションハイジャック (session hijacking)とは、コンピューター通信でりようする「セッション」を窃取し、本人に成り代わって通信を行うというサイバー攻撃です。 言わば「なりすまし」で不正アクセスをする行為です。

※ハイジャック：乗っ取り


参照：
https://www.ap-siken.com/kakomon/23_aki/q42.html
【Lambda】import requests が使えるようにする【python】

# やること
↓これを実行したら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/7689356e-1f61-9b71-1fcd-0d8aca43f25c.png)

↓こうなってほしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/15a381c6-b741-152a-d16b-f11e20bf0430.png)

↓しかし、こうなってしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/7d209b66-33d7-41b4-e024-3c81cbd9f7da.png)

```json
{
  "errorMessage": "Unable to import module 'lambda_function': No module named 'requests'",
  "errorType": "Runtime.ImportModuleError"
}
```


# 手順概要
+ requests  が動くようにLayerファイル（zip)を作る
+ LambdaにLayerファイルをアップロードする
+ Layerを使って関数を作る

## Layerファイルを作ります
クライアントで作業します。
pipが動くようにして、外部モジュールを入れたものをzipしてaws管理コンソールから入れるだけ

例えば、amazon linux2で作業する場合は…

```bash
mkdir python/ 
cd python
yum -y install gcc gcc-c++ kernel-devel python-devel libxslt-devel libffi-devel openssl-devel
yum -y install python-pip
pip install -t ./ requests
cd python
cd ..
zip -r Layer.zip python/
```

## zipをLambdaに登録します
AWS管理コンソールで作業します。
![スクリーンショット 2019-09-29 21.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/f53fd022-5afb-598f-2bb1-a643a61a9296.png)
「レイヤーの作成」で、先ほど作ったLayer.zipファイルを入れれば終わりです。

## 関数の準備
Layersを選択して
![スクリーンショット 2019-09-29 21.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/0d9c5d96-74ea-a17e-5444-71e7f9708b5a.png)
「レイヤーの追加」押下で先ほど作ったレイヤーが出てきますので、選択。
![スクリーンショット 2019-09-29 21.48.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/15aff369-8503-a6fd-aad2-6a8fb8e48d0d.png)

## 関数の作成

```python:lambda_function.py
import requests

def lambda_handler(event, context):
    # テストサイトにGETを投げてみる
    response = requests.get('https://httpbin.org/get', params={'foo': 'bar'})
    return response.json()
```

```json:実行結果
{
  "args": {
    "foo": "bar"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.24.0",
    "X-Amzn-Trace-Id": "Root=1-5f43a5ad-a04c8100f8c999999e8e2e"
  },
  "origin": "913.931.998.950",
  "url": "https://httpbin.org/get?foo=bar"
}
```
suとsudo

- 半年以上前の編集中の記事が残っていたのであげる

# suコマンド(最強コマンド)

- 一般的なsuの使い方の場合ユーザはroot権限を一時的に使えるようになる。プロンプトは「#」になりexitするまで持続する。

- su使用時にきかれるパスワードは「rootのパスワード」である。

- もしシステム管理者があなたしかいないのならばsuで問題ないかもしれないが、他人と共有する場合、他人にrootパスワードを知らせることになる。


# sudoコマンド
- sudoはコマンド単位で一時的にroot権限を使う方法だ。「スーパーユーザでDoするからsudo」という意味合いで覚えておこう。

- 必要なパスワードは「あなたのパスワード」である。

- コマンド単位で「誰にどのコマンドをrootで実行させることを許可するか」を指定できる。こうすることでrootパスワードを知られることなく、必要なコマンドをroot権限で実行できるようになる。

- もちろん無差別に権限を割り振ってしまうと意味がなくなるので注意していただきたい。sudoを使うには、一度スーパーユーザになってから「visudo」コマンドで設定ファイルを編集しなければならない。


# 参考

- この記事、まんま[【完全初心者向け】Linuxのrootユーザとは？
](https://eng-entrance.com/linux-root)です
クロスサイトスクリプティング対策


応用情報技術者平成30年秋期 午前問41

クロスサイトスクリプティング対策に該当するものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/ddd9a749-424f-d030-ade0-5d586afc6ccf.png)


１、クロスサイトスクリプティング(XSS)は、
動的にWebページを生成するアプリケーションのセキュリティ上の不備を意図的に利用して、悪意のあるスクリプトを混入させることで、攻撃者が仕込んだ操作を実行させたり、別のサイトを横断してユーザのクッキーや個人情報を盗んだりする攻撃手法です。

２、クロスサイトスクリプティングの攻撃手法と対策は、
攻撃者が送り込んでくる文字列がHTMLドキュメントの一部となるように合成されて、その部分がブラウザによってスクリプトとして解釈される構文となることによって成立します。よって、プログラム中のデータをHTMLとして出力する際に、HTMLで特別な意味をもつ文字(<,>,",',&など)を実体参照に置き換えて無害化したり、HTMLタグを削除したりすることによりスクリプトとして解釈されないようにすることが重要です。



・SNMPエージェント（英：SNMP agent）とは
機器をネットワーク経由で管理する仕組みにおいて、実際に機器の動きを監視するもの。

下記はSNMPさん達の関係：
・SNMP：監視員さんと管理者さんの間で意志疎通するためのルール
・SNMPエージェント：監視員さん（実際に機器を監視するやつ）
・SNMPマネージャ：管理者さん（監視員さんからの報告を受けてあーだこーだするやつ）


参照：

https://www.ap-siken.com/kakomon/30_aki/q41.html

SNMPエージェント
https://wa3.i-3-i.info/word12602.html
Study Notes#2

# はじめに
Postman インストール

# 環境
 - **OS** : Ubuntu Desktop 20.04 LTS
 - **Postman Version** : v7.29.1

# Postman ダウンロード
 - Postmanのアカウント作成
ダウンロード時は不要だが、使用時は必要
・リンク：https://www.postman.com/

 - ダウンロードリンク：
Linux用Postmanをダウンロード（Linux 64-bit ダウンロード）
・リンク：https://www.postman.com/downloads/

 - Postman 起動

~~~
$ tar xvf Postman-linux-x64-7.29.1.tar.gz
$ sudo ln -s <ダウンロードしたディレクトリ>/Postman/app/Postman /usr/local/bin/postman
$ postman
~~~
起動完了
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/66b2111a-54dd-78e6-5ad4-2b1bfb89c7e4.png)

# 動作確認
 - ログイン  
まだアカウントがない場合は初期画面でアカウントを作成～  
アカウントがあれば[**Sign in**]をクリックしてログイン

![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/4b1c3238-e1ed-e757-c210-cd90697a7e1c.png)

![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/487df877-a2d2-299a-9e23-b1e603ac53f2.png)

 - 動作確認  
[**+**]クリック  
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/0bfa91c5-5598-509e-98ec-964cbe342aab.png)

googleアドレスを入力、[**Send**]クリックして結果確認
![8-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/af16c5cc-0c7c-c045-275d-b3a367908e7c.png)

REST APIなどテスト環境がある場合はそれで確認
![7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/9dd90fea-c5fe-fbd0-f2fc-c915fdfb8cfc.png)
Study Notes#1

# はじめに
Jupyter notebook インストール

# 環境
 - **OS** : Ubuntu Desktop 20.04 LTS

# インストール
- Official Manual<br>
https://jupyter.org/install

`pip3`でインストールする。

~~~
$ pip3 install notebook
~~~

カレント ディレクトリが作業スペースになるため、作業ディレクトリに移動してjupyter実行

~~~
$ mkdir python-data
$ cd python-data
$ jupyter notebook
~~~

以下画面が表示されたら起動無事完了
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/7088293d-9065-8f3f-5640-3ced4c80485c.png)

# 動作確認

- python notebook作成<br>
[New] > [Python 3]クリック
![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/b6fa23cb-b36a-80be-7f05-30408064a4ec.png)

- 動作確認
空欄に「print('Test OK')」と書いて[Run]クリック > 結果を確認
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/8a9ae410-1d33-fa50-695f-786a0f96f2f9.png)
![4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/074d03cc-cbaa-68c1-88c9-bc90f76096ed.png)

※notebook画面を閉じてもnotebookは自動停止しないため、手動停止が必要
![7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/132c510c-bda8-1c8c-2b6e-1b1f511a03f5.png)
![8-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561025/c8796736-4d6e-2dc7-59fb-a950c4607caf.png)
逆ガンマ関数をpythonで実装してみた


#導入
Pythonで逆ガンマ関数からサンプリングを行いたいのに、scipyに実装されている[invgamma](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.invgamma.html)[^1]はなぜか片方のパラメータがいじれない仕様になっていたので(次の節で出てくる関数のパラメータβがβ=1で固定：理由を知っている人がいたら教えてください)、練習（pythonとQiitaへの投稿の両方）がてら作ってみました（備忘録込み）。

#逆ガンマ関数とは
逆ガンマ関数とは、以下の形で表される連続な確率分布です。

```math
f(x,α,β)　=　\frac{β^α}{Γ(α)}x^{-α-1}e^{\frac{-β}{x}} 　　(x>0)\\
（ただし　Γ(α)　= \int_{0}^{∞}x^{α-1}e^{-x}dx　　で表されるガンマ関数)
```


scipyのinvgammaがなんでβ=1で固定なのかよく分かりませんが(自分の分野以外のことはたいして知らない...)、私はMCMC（マルコフ連鎖モンテカルロ法）で正規分布の分散の事前分布に使用する時に、β=1以外も使いたいので今回この記事を書きました。MCMCを詳しく知りたい方は@pynomiさんの[記事](https://qiita.com/pynomi/items/75ac937fc4ed0b39e3d5)[^2]を見るといいと思います。


#実際に書いてみた

```python
from scipy import stats
from scipy.special import gamma
import numpy as np

###逆ガンマ分布の確率密度関数###
class invgamma(stats.rv_continuous):

    def _pdf(self, x,alpha,beta):
        
        px = (beta**alpha)/gamma(alpha)*x**(-alpha-1)*np.exp(-beta/x)
        
        return px

###逆ガンマ関数からサンプリング###
invgamma = invgamma(name="invgamma", a=0.0)    
sample_from_invgamma = invgamma.rvs(size=1, alpha = 1, beta = 1.0) 
```

こんな感じ。
（OS:Windows10, Python3.7, 開発環境:Spyderで動作確認済み、β=1として乱数を固定したとき、scipyのinvgammaとサンプリングの値が一致したので、多分あってると思います。）

#引用
この記事とコードを書くに当たって、@physics303さんの[記事](https://qiita.com/physics303/items/93626d32dd1d17388610)[^3]も参考にしました。ありがとうございます。
[^1]: [scipy.stats.invgamma]()
[^2]: [pythonでギブス・サンプリングによるベイズ線形回帰を実装してみた](https://qiita.com/pynomi/items/75ac937fc4ed0b39e3d5)
[^3]: [Pythonで任意の確率密度関数からサンプリングを行う方法](https://qiita.com/physics303/items/93626d32dd1d17388610)
インターネットPC→DMZ（Webシステム）→DB


応用情報技術者平成30年秋期 午前問40


インターネットに接続された利用者のPCから，DMZ上の公開Webサイトにアクセスし，利用者の個人情報を入力すると，その個人情報が内部ネットワークのデータベース(DB)サーバに蓄積されるシステムがある。このシステムにおいて，利用者個人のディジタル証明書を用いたTLS通信を行うことによって期待できるセキュリティ上の効果はどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2985800a-d9bd-5071-8b0d-896ee85e4413.png)


設問の関係を図示すると次のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d68c7f97-d558-4978-f0c0-be0caf8809e9.png)

これは、インターネットからDMZ間は、TLS通信を行うので、暗号化通信していますね。
DMZからDBの間は、内部なので、TLS通信するのは必要なりません。

・DMZ(DeMilitarized Zone)
非武装地帯の意味で、イントラネットとインターネットの中間で、インターネットに公開するWebサーバやメールサーバ、DNSサーバなどを設置する場所です。

・TLS(Transport Layer Security)
TCP/IPネットワークでデータを暗号化して送受信するプロトコルで、データを送受信する一対の機器間で通信を暗号化し、中継装置などネットワーク上の他の機器による成りすましやデータの盗み見、改ざんなどを防ぐことができます。

・ディジタル証明書は利用者個人のものですので利用者認証のために使用します。
ディジタル証明書が正当なものならば、利用者(クライアント)の真正性が証明されます。
利用者PCと通信を行うWebサーバは、利用者個人のディジタル証明書に付された認証局の署名を検証することで、ディジタル証明書の正当性を確認します。


参照：
https://www.ap-siken.com/kakomon/30_aki/q40.html
https://itsiken.com/30A_L3/30A_L3_40.html
【Rails】ルーティングのcollectionとmemberについて【学習メモ】

collectionとmemberは、ルーティングにおいて生成されるURLとコントローラーを自由に設定する記述のこと。

```ruby:routes.rb
#collectionによる記述
resources :tweets do
 collection do
  get 'search'
 end
end

#/tweets/searchにアクセスした時にtweetsコントローラのsearchアクションに振り分ける。
#つまり、以下の記述と同義

get '/tweets/search' => 'tweets#search'

#memberによる記述
resources :tweets do
 member do
  get 'search'
 end
end

#挙動はほぼ同じだが、URIパターンに:idが入る違いがある。
#よって以下の記述と同義

get '/tweets/:id/search' => 'tweets#search'
```

resourcesメソッドやネストによりルーティングの記述が簡素化して非常に見易くなっているが、中でどのような振り分けが起きているのかを正しく理解する工程が必要だと感じ記載した。
Progateの学習では一つ一つ書かれており冗長だったが、同様の記載に敢えて直すことで簡単に理解出来た。
rails routes万歳。初記事で緊張する。
DNSキャッシュポイズニング攻撃


応用情報技術者平成30年秋期 午前問39


DNSキャッシュサーバに対して外部から行われるキャッシュポイズニング攻撃への対策のうち，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/644f2756-7854-5fc7-bdea-95b74f931ebf.png)

１、DNSキャッシュポイズニング攻撃は、
DNSキャッシュサーバに偽のDNS情報をキャッシュとして登録させることで、利用者を偽のWebサイトに誘導する攻撃です。


２、再帰的な問合せ
リゾルバから名前解決要求を受けたDNSサーバが他のDNSサーバに代理して問合せを行い、最終的な結果をリゾルバに返す必要のある問合せのこと

　・リゾルバ(Resolver)は、ドメインネームシステムのネームサーバへアクセスしドメイン名前空間から任意のノードの情報を取得するために用いられるクライアントの名称。

３、反復問合せ
リゾルバから再帰的問合せを受けたDNSサーバが、それを解決できるまで繰り返し他のDNSサーバに行う問合せのこと


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/bba9051a-14e5-257b-3a7e-b750d1cdbf2f.png)



★攻撃者がDNSキャッシュサーバに偽のキャッシュ情報を登録させる手順：
・攻撃者は、キャッシュサーバに対して偽の再帰的な問合せを行い反復問合せを強制的に生じさせる。
・キャッシュサーバは、コンテンツサーバに対して反復問合せを行う。
・攻撃者は、コンテンツサーバが**正規の応答を返すよりも先にキャッシュサーバへ偽の応答を送りつける**。
・キャッシュサーバは、攻撃者から送られた偽の応答を正規のものと判断しキャッシュに登録する。この時点でDNSクエリは解決済なのでコンテンツサーバから送られた正規の応答は破棄される。

つまり、再帰問い合わせを外部ネットワークからのリクエストを禁止すると、キャッシュサーバに偽キャッシュを登録させるリスクがなくなるので、対策となります。




・リゾルバと（resolver）は、名前解決のためのDNSクライアントのことである。 ドメイン名を元にIPアドレス情報を検索したり（正引き）、IPアドレスからドメイン名の情報を検索したり（逆引き）するのが目的である。 名前解決を行うことから「解決するもの」（resolver）という意味でリゾルバと呼ばれている。

・キャッシュポイズニング（DNS cache poisoning）とは、DNSのキャッシュ情報を意図的に書き換え、利用者を誤ったサイトへ誘導する攻撃である。 例えば、キャッシュポイズニングの攻撃により、オンラインバンキングのサイトの偽情報を流すことができれば、利用者の口座番号やパスワードなどの情報を抜き出すことが可能となる。

参照：
https://www.sc-siken.com/kakomon/26_aki/am2_9.html

リゾルバ(Resolver)
https://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%BE%E3%83%AB%E3%83%90
ポインタとは何か、初心者目線で解説してみた

業務でGO言語を扱うことになり、必死に勉強していたのですが、
ポインタが最初はなかなか理解できずに苦労しました。

今回はそんなポインタとはなんぞやという方に向けて解説していきたいと思います。

※自分もまだまだ未熟なため、一部不適切な部分があるかもしれませんが、ご了承ください。

<h4>ポインタを理解するために抑えておくべき用語</h4>
　　・メモリ
　　・アドレス
　　・値渡し

一応、さらっと用語について解説します。

#メモリとアドレス
<strong>メモリ</strong>はデータを一時的に保存する場所ですね。
メモリに変数が格納され、変数に値が格納されています。
つまり、 メモリ＜変数＜値(文字列とか数値）という構造になります。

メモリは広大な野原だと思ってください。
その野原に変数という名の箱がたくさん置かれています。
多すぎて、どれが何の箱なのかわかりません。
なので、箱ごとに住所をつけて管理をします。

その住所が<strong>アドレス</strong>です。

```main.go
	a := "asfd"
	fmt.Println(&a) // 0xc00008e1e0
```
実際のアドレスはこのように文字と数字の羅列(16進数）で表されています。

#値渡し
値渡しは関数の呼び出し方の方法の一つです。
重要なのは、引数に指定した値の<strong>コピーが関数内部で使用される</strong>ということです。

```main.go
func printValue(a string) {
    a := "fuga"
    fmt.Println(a)
}

value := "hoge"

printValue(value)
// 出力結果 "fuga"

fmt.Println(value)
// 出力結果 "hoge"
```
値渡しは値をコピーして渡しているだけなので、
関数内で引数の値を書き換えても、呼び出し元で指定した引数(value）の値は変わりません。

いよいよポインタの説明に入ります。

#ポインタとは何か
ポインタとは実際のアドレスを指定したデータ型。及び、変数のことです

ポインタ型は「*変数名」とすることで生成することができます

実際にコードを見ながら解説していきます。

```main.go
func printValue(a *string) {
   //valueの値を直接書き換えている
	*a = "fuga" 
	fmt.Println(*a)
}

func main() {

	value := "hoge"

	fmt.Println(value)
	//出力結果 hoge

	printValue(&value)
	//出力結果 fuga
	
	fmt.Println(value)
	//出力結果 fuga
}
```

「&変数名」でアドレスを参照することができて、「*変数名」は値を参照することができます。

値渡しは値のコピーで元の変数の中身を書き換えることはできない。
ポインタ渡しは実際の値を書き換える。

これが値渡しとポインタ渡しの違いになります。
esbuildがwebpackより187倍早いらしいので環境構築しよう

# はじめに
久しぶりの投稿になります。
今回は以下の記事で、<a href="https://github.com/evanw/esbuild">esbuid</a>がすごい！！という話を聞きつけこの記事を書くことにしました。
参考: <a href="https://www.kabuku.co.jp/developers/ultrafast-tsx-build-tool-esbuild">[Web フロントエンド] esbuild が爆速すぎて webpack / Rollup にはもう戻れない</a>

どのくらいすごいのでしょうか？
参考に挙げている記事によると
> esbuild は Go 言語で書かれた JavaScript および TypeScript のビルドツールです。 esbuild 単体でトランスパイル + バンドル + ミニファイできます。 JSX / TSX もサポートされています。そしてめっちゃくちゃ速いという触れ込みです。最初から速度を意識して無駄がないように書かれており、構文解析・出力・ソースマップ生成は並列化され、ネイティブコードで動作します。公式の README では three.js のビルドが Rollup + terser より 100 倍速い と謳っています。 
https://www.kabuku.co.jp/developers/ultrafast-tsx-build-tool-esbuild

とのことです。
なるほどなるほどと。最近わたしも`Webpack`のBuild遅いなあと思っていたのでこの情報を鵜呑みにして、`esbuild`の環境構築をしたくなりました。

また、<a href="https://github.com/evanw/esbuild#javascript-benchmark">ドキュメント</a>によると<b>esbuildはwebpackの187倍もBuildが早い</b>みたいです。

# esbuildの環境構築
環境構築についてですが、だいたいのモジュールバンドラにはコンフィグファイルがつきものです。esbuildのgithubを参考にしましたが、ワンライナーのCL上での実行例のみでコンフィグファイルらしいものの書き方見当たりません。
少し詳細に調べたところ、
https://github.com/evanw/esbuild/issues/39
以下に書いてありました。
ふむふむ、一応、対応はしているみたいです。
## 前準備
今回は、`React+TypeScript`で記述されたプロジェクトを対象にBuildを行う環境構築をします。Vueについては、`vite`というモジュールバンドラが`esbuild`を利用して、Buildを行っているため、そちらを利用してくださいとのことです。

まずは以下の通りにnpmモジュールをインストールします。
`npm install -D esbuild @types/node`

Reactのプロジェクトは後ほど説明する注意点に気をつければなんでも大丈夫です。
わたしのgithubのプロジェクトを例に説明します。
https://github.com/tsukuha/esbuild-tmp

## Buildスクリプトの作成
まず最低限、以下の条件を実現したいです。

- developmentとproductionの環境でBuildを分ける
- エントリーポイントの指定
- Build後に出力されるESの規格の指定
- プラットフォームの指定（node, browser）
- production時にはminifyをかける
- 出力先ディレクトリの指定
- tsconfig.jsonの読み込み

以上の条件を元に作成した、esbuildのBuildファイルは以下の通りです。

```build.ts
const { argv } = require('process')
const { build } = require('esbuild')
const path = require('path')
// optionsの定義
const options = {
  // 以下のdefineプロパティを設定しない場合Reactのプロジェクトの実行時にエラーが出ます
  define: { 'process.env.NODE_ENV': process.env.NODE_ENV },
  entryPoints: [path.resolve(__dirname, 'src/Index.tsx')],
  minify: argv[2] === 'production',
  bundle: true,
  target: 'es2016',
  platform: 'browser',
  outdir: path.resolve(__dirname, 'dist'),
  tsconfig: path.resolve(__dirname, 'tsconfig.json')
}
// Buildの実行
build(options).catch(err => {
  process.stderr.write(err.stderr)
  process.exit(1)
})
```
上記のファイルを以下のnodeコマンドで実行することでBuild可能です。
`node build.ts production/development`

npmスクリプトにして実行しやすくするのもいいかもしれませんね。

# 実装時の注意点（2020/08/24）
現時点でesbuildを利用する際には、以下のような注意点があります。

- `TypeScript`のトランスパイル時の型チェックに対応していません
- `css-modules`に対応していません
- `plugins`に対応していないので、各種loaderの読み込みや詳細な設定をすることはできません


# おわりに
`webpack`を`esbuild`に置き換えることによって、Reactを導入しているプロジェクトが`CSSフレームワーク`や、`CSS in JS`を利用している場合、<b>かなりの効果を発揮する</b>かもしれませんね！！

もし何か質問やご指摘などありましたらお願いします！
.NET Core で RIPEMD160 を使おう！ with Bouncy Castle

ハッシュアルゴリズムの RIPEMD160 を Bouncy Castle を使って C# で実装した時のメモです。
このアルゴリズムは Bitcoin 等に使われてますね！

### 環境
* .NET Core 3.1

## RIPEMD160 が消えた
[公式ドキュメント](https://docs.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.ripemd160?view=netframework-4.8) を見るとわかる通り、 .NET Framework では RIPEMD160 アルゴリズムが公式にサポートされていましたが、.NET Core では削除されていました。
[リポジトリの Issue ](https://github.com/dotnet/runtime/issues/2094) を見るに、(私の拙い英語力で解釈すると) 
「OS 側で提供されないアルゴリズムは .NET Core では実装しないよ！」ということでしょうか？
困りました。

## Bouncy Castle を使おう
Bouncy Castle は暗号化ライブラリの一つです。言語は Java と C# がサポートされています。
.NET Core でも使えます。
[Nuget](https://www.nuget.org/packages/BouncyCastle/) からサクっといれちゃいましょう。
執筆時点(2020/08/24)ではバージョンが最新ではないみたいなので、気になるようであればリポジトリの [Release](https://github.com/bcgit/bc-csharp/releases) からどうぞ。

### 使い方
Org.BouncyCastle.Crypto.Digests 名前空間の RipeMD160Digest クラスを使います。
コード自体は簡単なものになります。

```csharp
class Program
{
    static void Main(string[] args)
    {
        var data = Encoding.UTF8.GetBytes("abcdefg");

        var digest = new RipeMD160Digest();
        var result = new byte[digest.GetDigestSize()];
        digest.BlockUpdate(data, 0, data.Length);
        digest.DoFinal(result, 0);

        WriteBytes(result);
        //874f9960c5d2b7a9b5fad383e1ba44719ebb743a
    }

    private static void WriteBytes(IEnumerable<byte> bytes)
    {
        Console.WriteLine(string.Join("", bytes.Select(x => $"{x:x2}")));
    }
}
```

1. RIPEMD160 のインスタンスを生成して、
1. BlockUpdate を呼び出して、
1. DoFinal で結果を得る。  

という単純な使い方です。
(RipeMD160 の仕様は長さが20バイトなので、`digest.GetDigestSize()` の値も 20 で固定です。)

### 参考にしたもの
[RipeMD160Digest.cs](https://github.com/bcgit/bc-csharp/blob/f18a2dbbc2c1b4277e24a2e51f09cac02eedf1f5/crypto/src/crypto/digests/RipeMD160Digest.cs)
[GeneralDigest.cs](https://github.com/bcgit/bc-csharp/blob/f18a2dbbc2c1b4277e24a2e51f09cac02eedf1f5/crypto/src/crypto/digests/GeneralDigest.cs)

Bouncy Castle は C# に対するドキュメントが無いため、学ぶにはソースコードを読む必要があるなど一苦労かかりますね！
私の記事がなにかお役に立てれば幸いです。
【Salesforce】豆知識

#豆知識
##■バッチ関連
###・バッチは**1時間単位**でスケジュールが可能
###.一定時刻おきにバッチを起動したい場合
バッチのFinishメソッドでSystem.scheduleを利用して設定する。
/**
 * Finish
 */
public void finish(Database.BatchableContext BC) {
    // 次回スケジュールバッチ登録判定
    if (this.isNextBatch) {
        // 次回スケジュールバッチ実行時間取得
        Datetime nextBatchTime = Datetime.now().addMinutes(5);
        // 次回スケジュールバッチ実行時間登録
        OpportunityChatterPostBatchSchedule cls = new OpportunityChatterPostBatchSchedule();
        String jobName = 'OpportunityChatterPostBatchScheduleJob_' + nextBatchTime.format('yyyyMMddHHmm');
        String sch = nextBatchTime.format('0 m H d M ? yyyy');
        System.schedule(jobName, sch, cls);
    }
}


###・任意時刻でバッチを起動したい場合
任意のClassでバッチをスケジュール、Excute AnonymousでそのClassを実行すれば、設定されます。
その後はFinish実行。
或いは、バッチをスケジュールするためのバッチを作る、例毎日0時のバッチで、次の24時間分のバッチを纏めてスケジュールする。

global class ExcuteScheduler {
	public static void execute() {
		String jobId_1 = System.schedule('【午前】9:00に開始','0 0 9 * * ?', new TestScheduler());
		String jobId_2 = System.schedule('【午後】18:00に開始','0 0 18 * * ?', new TestScheduler());
	}
}

##■開発ツール
#####・開発コンソールで、メターデータ内にに含まれる文字列を検索
開発者→コンソール→Edit→Search in files
Qiitaはじめました。まずはポートフォリオ作成と就職を目標に。

#自己紹介
未経験からITエンジニアを目指しています。 
前職の経験から業務効率化の必要性を痛感し、プログラミングに興味を持ちました。 
独学やスクールを通し、一層仕事にしたいと思いながらも、転職活動に苦戦中です。

2018年10月〜　　progateや書籍にて独学を開始（Python, HTML&CSS 等）
2020年1月〜5月　プログラミングスクールにて学習（Java, MySQL 等）

#Qiitaをはじめた理由
このたび、ようやくQiitaを開設(?)しました。
最大の理由は、転職活動が長期戦になってきて、次の戦いを起こす必要性を感じたからです。

過去に制作した「Webアプリケーション」を放置したままで、勿体無く感じたので、
・そのポートフォリオを作成し、少しでもアピールできる形にする！
・プログラミングの面白さを今一度思い出し、転職活動のモチベーションを維持する！

まずは、上記目標を達成すべく、ブログ感覚で使おうと思っています。
（使い方、これでいいのかな・・・）

#ポートフォリオ作成にあたって
ただ、全てが初めての経験でどう進めればいいのか分かっておりません。

そんな中、[tan3sugarless](https://note.com/tan3_sugarless)さんの記事から、
[見かけたQiita記事がポートフォリオとしてもプログラミングの教科書としても良かったので紹介します](https://note.com/tan3_sugarless/n/n1e19f77e807e)

@RINYU_DRVO さんの記事に辿り着き、
[PHP+MySQLでポートフォリオ作成](https://qiita.com/RINYU_DRVO/items/6607a0aa7ca3294f8e47)
これを参考にしたらできるかも！と思い、今に至ります。
（見出しや項目など、概ね同じになるかもしれませんがどうかお許しください。）
<br>

また、全部まとめてから投稿。だと完成までモチベーションの維持が難しいと思ったので、
随時、書き加えて更新することに決めました。

「初心者が模索しながら、何かをしようとしている。」
と温かく見守っていただけると幸いです。
Amazon S3, Route53, CloudFront を利用して SSL化した LP をホスティングする方法

# まえがき
本記事では、Amazon S3, Route53, CloudFront を利用して SSL化した LP をホスティングする方法についてご紹介します。
実際に、最近この方法で [LP](https://gaobowl.com/) を公開したので、備忘録も兼ねて以下に大まかな流れを記載します。

# ⓪ AWS の 利用
・まず、[AWS](https://portal.aws.amazon.com/billing/signup?redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation&language=ja_jp#/start) にて、アカウントを作成します。
・アカウント情報, 連絡先情報, お支払い情報 を登録して、SMS等でのアカウント認証を行います。
・その後、サポートプランの選択を済ませれば、アカウント作成完了。AWSコンソールにログインできる様になります。

# ① S3 に LP をデプロイする
・まず、サービス の ストレージ から S3 を選択します。
・S3 にて、 バケットを作成する を選択し、バケット名(プロジェクト名, ドメイン名等)、
リージョン(アジアパシフィック(東京)) を入力します。
・作成した バケット に LP の ディレクトリ をデプロイします。
・アクセス権限 から ブロックパブリックアクセス をオフにします。
・プロパティ から Static website hosting の ウェブサイトをホストする を選択し、
インデックスドキュメント を設定します。
・エンドポイント (http://[バケット名].s3-website-[region].amazonaws.com/~) からアクセスできればデプロイ完了です。

# ② Route53 にて ネームサーバー の設定を行う
・まず、サービス の ネットワーキングとコンテンツ配信 から Route53 を選択します。
・ホストゾーン から、ホストゾーンの作成を選択し、ドメイン名 を入力します。
・作成した ホストゾーン の NSレコード に割り当てられた、 4つの ネームサーバー をコピーします。
・ドメインを取得したサイトの管理画面から、対象ドメインのネームサーバー設定を、上記のネームサーバ情報に変更すれば完了です。

# ③ Certificate Manager にて SSL の設定を行う
・まず、サービス の セキュリティ、ID、およびコンプライアンス から Certificate Manager を選択します。
・証明書のプロビジョニング を選択し、パブリック証明書のリクエスト を選択します。
・CloudFront との兼ね合いにより、画面右上のリージョンを「米国東部 (バージニア北部)」に変更します。
・ドメイン名を追加し、DNSの検証 を選択後、任意でタグを入力し、確定とリクエスト を選択します。
・検証保留中の証明書のリクエストが作成されるので、詳細から Route53でのレコードの作成 を選択します。
・検証が進行するので、状況欄が 発行済み になれば完了です。

# ④ CloudFront にて SSL の設定を行う
・まず、サービス の ネットワーキングとコンテンツ配信 から CloudFront を選択します。
・Create Distribution を選択し、Web の Get Started を選択します。
・Origin Domain Name に S3 の バケット名 を入力します。
・Viewew Protocol Policy にて Redirect HTTP to HTTPS を選択します。
・SSL Certificate にて Certificate Manager にて作成した証明書を選択します。
・Alternate Domain Name にて ドメイン名 を入力します。
・Default Root Object にて S3 の インデックスドキュメント を入力します。
・設定内容を保存するとデプロイが始まるので、Status欄 が Deployed になれば完了です。

# ⑤ Route53 にて Aレコード の追加設定を行う
・まず、対象ホストゾーン から レコードを作成 を選択し、タイプ(Aレコード)、エイリアス(はい)、エイリアス先（CloudFrontディストリビューションから選択)という内容で作成します。
・指定ドメインでアクセスできればデプロイ完了です。

# ⑥ CloudFront にて ポリシー の設定を行う
・まず、対象Distribution の Origins and Origin Groups から、表示されている S3 Origin の編集を選択し、Restrict Bucket Access(Yes)、 Origin Access Identity(Create a New Identity)、 Grant Read Permissions on Bucket(Yes, Update Bucket Policy) という内容で更新します。
・S3 の 対象バケット の バケットポリシー にて、ステートメントが追加されていれば完了です。

# ⑦ CloudFront にて キャッシュ の管理を行う
・まず、対象Distribution から Create Invalidation を選択し、 Object Paths にて 削除したいオブジェクトのキャッシュ を入力します。(全選択の場合は、 `/*` と入力)
・Invalidate を選択すると、キャッシュ削除が始まるので、Status欄 が Completed になれば完了です。


# まとめ
今回、社内のプロジェクトで急遽 LP を制作する流れになったため、ホスティングの方法等いろいろ悩んだのですが、初の S3 でのデプロイにもかかわらず、思っていたよりスムーズ(約１~2時間)だったので、軽く感動しました。
もし、LP をアップロードすることがあれば、参考にしていただければ幸いです。

-次回 (8/31)
「[GAOGAO 社内 OOUI WorkShop 体験記](https://note.com/masanaosuzuki/n/nd808d38e8592)」

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [S3+CloudFront+Route53で静的サイトを公開した作業メモ](https://note.com/cfbif/n/n9d8789034a3b)
- [[AWS] Amazon CloudFrontのキャッシュ削除(Invalidation)](https://dev.classmethod.jp/articles/aws-amazon-cloudfront-deleting-cache-by-invalidation/)
IPアドレスを環境変数に設定する

`ifconfig`の結果から該当部分を抽出していく

`ifconfig`するとズラズラ出力されるので、少しづついらないところを削っていく

```
ifconfig wlp4s0 | grep inet | grep -v inet6
>         inet 192.168.x.x  netmask 255.255.255.0  broadcast 192.168.2.255
```

`inet 192.168.x.x`が欲しいので、更に削る

```
ifconfig wlp4s0 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}) .*/\1/" | sed "s/ //g"
> 192.168.x.x
```

最後に設定ファイル(.config/fish/config.fishとか)に追加する

```
set -x HOST_IP (ifconfig wlp4s0 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}) .*/\1/" | sed "s/ //g")
```
iOSアプリで音楽や動画のバックグラウンド再生の実装方法(他アプリ音声を停止しないやり方も)

AVPlayerやAVAudioPlayerなどで音声再生や動画再生の実装をする場合デフォルトのままだとアプリをバックグラウンドへ移行したりスリープをした時に再生が自動で停止します。
以下の実装を行うことで再生を継続させることができます。

簡単な手順でOKです。

#手順1
1. プロジェクトファイルを開く
2. メニュー -> Editor -> Add Capability -> Background Modesを選択
3. Audio, AirPlay, and Picture in PictureのチェックマークをONにする

![スクリーンショット 2020-08-24 19.18.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678249/8a56ec6a-0f4a-1b0f-4530-bad6f8c8cadd.png)


#手順2
プロジェクト内の任意の場所に以下のコードを書きます

```swift
// アプリ初期化時等
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
} catch _ {
    NSLog("audio session set category failure")
}

// 音声、動画再生時
do {
    try AVAudioSession.sharedInstance().setActive(true)
} catch _ {
    NSLog("audio session active failure")
}

```

注意点として、上記の実装をしているともし別のアプリで音声を再生している場合
上記のsetActiveが呼び出された時点で別アプリの音声再生が停止します。
なのでsetActiveは自分のアプリでの音声再生を開始する時点で呼ぶのが望ましいです。

#他アプリの音声再生を停止せずに再生する方法

AVAudioSessionのsetCategory時にoptionを設定します  

```swift
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback,
                                                            options: [AVAudioSession.CategoryOptions.mixWithOthers])
} catch _ {
    NSLog("audio session set category failure")
}

```

上記はmixWithOthersを指定しましたが、duckOthersというのも存在します
違いは
- mixWithOthers → 他アプリの音声の音量を下げ**ない**
- duckOthers     → 他アプリの音声の音量を**下げる**
場面に応じて使い分けましょう！

他のoption
- allowBluetooth →　音声再生時にはこのoption指定は無視される(bluetoothイヤホンを利用できるようになるとかそういうものではない）
- defaultToSpeaker　→ イヤホンやヘッドセットを利用しない場合にいわゆる電話の耳を当てる部分から音が出るのがデフォルトになっているが、それをスピーカーから音が出る状態にするoption


公式ドキュメント:
 [AVAudioSession](https://developer.apple.com/documentation/avfoundation/avaudiosession)

#終わりです

Brewus,Inc.
株式会社ブリューアス
https://brewus.co.jp
[MVVM-DataBinding] 数字入力のEditTextに単位とセパレーターを自動で追加する


## 背景

数字入力に限定した`EditText`(`android:inputType="number"`)に対して、3桁ごとのセパレーターと`suffix`として単位をつけたい

理由
・ユーザーに極力数字以外のものを受け付けたくない
・桁数と単位でより入力内容をわかりやすくしたい

## 環境
MVVM-DataBinding
※導入方法は省略

## 実装

今回は長さ(m)を例に実装します

やりたい事は、もしユーザーが`1222`と入力したとすると、`1,222m`と`EditText`に表示させたいです

### XML

```snippet.xml
<data>

    <import type="your.package.name.Converter" />

    <variable
        name="viewModel"
        type="your.package.name.SnippetViewModel" />
    </data>

(略)

<EditText
    android:id="@+id/length_m"
    android:layout_width="match_parent"
    android:gravity="end|center_vertical"
    android:hint="0m"
    android:inputType="number"
    android:maxLines="1"
    android:paddingStart="0dp"
    android:paddingEnd="8dp"
    android:text="@={Converter.addNumberSeparatorAndUnitMeter(viewModel.length)}"
    android:textSize="18sp" />
```

・`ViewModel`を`binding`の`variable`として登録
・`EditText`の内容を後述する`MutableLiveData`と対応させたいので双方向データバインディングしています
・`Converter`の`import`と使用、こちらも後述

### ViewModel


```SnippetViewModel.kt
class SnippetViewModel() : ViewModel() {

    val length = MutableLiveData<Int>()

(略)
```

ここでは対象の`MutableLiveData`を定義しています

### Converter

ここでは`EditText`上でユーザーが数字が入力するものの、`EditText`には`数字+セパレーター+単位`を表示したいわけです
ただし、今回は双方向データバインディングのため、またユーザーが数字を入力する際に、`EditText`に表示されている`数字+セパレーター+単位`をそのまま`getText`等で使い数字のまま使えるわけではないので不整合が生じやすいです

そのため、
<b>・EditTextへの入力内容(Int) -> EditTextの表示内容(String)</b>
<b>・EditTextの表示内容(String) -> EditTextの入力内容(Int)</b>

これらをうまく変換するためのメソッドが必要になります
ここで役立つのが、[@InverseMethod](https://developer.android.com/topic/libraries/data-binding/two-way?hl=ja#converters)です

`@InverseMethod`では上記の変換、逆変換をスマートにこなしてくれます
今回の例でいうとこのようになります

```Converter.kt
object Converter {
    @InverseMethod("inverseToInt")
    @JvmStatic
    fun addNumberSeparatorAndUnitMeter(value: Int): String {
        val intValueWithFormat = String.format("%,d", value)
        return "${intValueWithFormat}m"
    }

    @JvmStatic
    fun inverseToInt(value: String?): Int {
        return kotlin.runCatching { value?.replace("m", "")?.replace(",", "")?.toInt() }
            .getOrNull() ?: 0
    }
}
```

ひとつめの`addNumberSeparatorAndUnitMeter`では`ユーザーが入力した内容=LiveDataの値`に対してセパレーターとmの単位を付与しています

```
@InverseMethod("inverseToInt")
```

の`inverseToInt`は逆変換するのに必要なメソッド名になります
これにより再度ユーザーが数字を入力した際、逆変換のメソッドが呼ばれIntとなり、そのIntの値を使ってまた`addNumberSeparatorAndUnitMeter`が呼ばれるということになります

`inverseToInt`メソッドでは数字＋セパレーター＋単位をIntに戻しています

これでユーザーが数字を入力するだけで`EditText`にセパレーターと単位を補助入力できるようになりました🎉

## InverseMethodを使うと何が嬉しいの？

個人的な意見です
・パターンに応じた複雑なロジックを自前で定義する手間が減る
・変換、逆変換の処理を無限ループしにくい状態で定義できる
・もとの`LiveData`の値を変換していないままの型(今回は`Int`)として使うことができるので、その値を使ったバリデーションや値変換(`Transformations.map`)がしやすい


## おわり
以上です　参考になれば幸いです
よりよい方法がありましたら是非ご教授ください🙏
iTerm2でAlfredのスニペットが展開せず、iTerm2 seems to be preventing text expansion ~　と言われたとき

いろいろ探すのに意外と時間がかかったのでメモしておきます。
Alfredのスニペット機能、少しずつ使いこなしはじめた矢先の出来事。

## エラーでググって調べたページ

[Alfredのヘルプページ](https://www.alfredapp.com/help/troubleshooting/snippets/)を見たけど、いまひとつピンとこなかった。

そもそも昨日まで使えていた（はず）だったのに、あるタイミングから展開されなくなったので、この辺の設定ではなさそう。
あらためて確認したけどシステムのフルディスクアクセスはもちろん設定済みだった。
では、なぜ？

## iTerm2の設定だった
まあAlfred側じゃないなら、そうなりますよね、という話。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273745/8abc9028-9dde-842a-8ffb-38496d48fa13.png)


なにかのタイミングでこのショートカットキーで設定を変更してしまったのでしょう。
Macのシステム設定をやりなおしたり、PCごと再起動したりしながら、iTerm2のPreferencesの項目を眺めていろいろと原因を探していたのですが、設定のありかはPrefencesの中ではありませんでした。
このチェックを外すと元通り展開されるようになりました。

### ちなみにTerminalでは
普段使ってなかったので意識してなかったのですが、iTermで展開されなかったのでTerminalの方でも試してみたところ、こちらもダメでした。
設定はiTerm同様、メニューバーにあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273745/542a90e1-8b55-80c7-45f1-92dfa0c34aec.png)

[Appleの公式サイト](https://support.apple.com/ja-jp/guide/terminal/trml109/mac)にも設定が書いてあったのですが、iTermの設定を変更した後だったのでここを読まずともすぐ察しがつきましたｗ
Go 再入門 - VSCode で環境構築

## 概要

半年ほど前から Go 言語の勉強を始めたのだが、何かと忙しく放置気味になってしまった。余裕ができたので久しぶりに VSCode を開いたものの、PC 交換時に環境移行を怠ってしまい、再び環境構築から Hello, world までやり直したのでその備忘録。今回は Mac での作業だが、Windows でもパスなどを随時読み替えれば OK。

## 前提条件

- macOS High Sierra 10.13.6
- bash 3.2.57(1)-release
- Homebrew 2.4.13
- VSCode 1.48.1

## インストール

Homebrew 経由でインストール。

```bash
brew install go
```

バージョンは記事の執筆時点で `1.15`。

```bash
go version
go version go1.15 darwin/amd64
```

一応 Windows でもパッケージマネージャの Scoop 経由でインストールが可能。

## PATH 関連

### GOPATH

ソースコードや実行ファイル、コンパイル済みのパッケージファイルなどを保存するためのディレクトリを指定する。デフォルトでは `$HOME/go` となってるので、特にこだわりがなければそのままホーム直下を指定。

```bash
echo 'export GOPATH=$HOME/go' >> ~/.bash_profile
```

### GOROOT

SDK のディレクトリを指定する。Homebrew でインストールした場合は `brew upgrade` でのバージョン更新が反映されないため、**エイリアスへのパスを指定**する。

```bash
echo 'export GOROOT=/usr/local/opt/go/libexec' >> ~/.bash_profile
```

## VSCode

### 拡張機能

Marketplace から拡張機能をインストールする。以前は Microsoft のリポジトリで管理されていたが、Go のプロジェクトへ移行されたらしい。『Go』で検索すれば恐らく 1 番上に表示されるはず。

![img_1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/57fe932e-1afd-f8bf-866e-32e7f171c723.png)

### ツール群

拡張機能のインストール後 `⌘+⇧+P` でコマンドパレットを呼び出し、開発に必要なツール群をインストールする。

```bash
Go: Install/Update Tools
```

ツールは個別に選択が可能だが、取り敢えず全てにチェックして OK を押し、インストールを完了させる。

![img_2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/642d485b-f884-417a-8a7a-2a64fd865b50.png)

## Hello, world

動作確認のためにお決まりのアレをやる。

```bash
mkdir -p $GOPATH/src/golang/hello
cd $GOPATH/src/golang/hello
touch hello.go
```

**GOPATH 配下**で新規にプロジェクトを作成。パスは適当。GitHub 上でパッケージを公開することから `github.com/username/repository` にすることが多い。`hello.go` という名前の空ファイルを生成したら、VSCode でコーディングしていく。

```go
package main

import "fmt"

func main() {
    fmt.Println("Hello, world")
}
```

`⌃+⇧+^` でターミナルを呼び出して実行。

```bash
go run hello.go
Hello, world // 実行結果
```

問題なく Hello, world 出来れば一先ず環境構築は終了。

## gopls

### 機能

> gopls (pronounced: "go please") is the official language server for the Go language.

ざっくり言えば IDE で必要なコード補完や定義へのジャンプ、フォーマットなどをまるっと提供する機能のこと。Microsoft が定義した Language Server Protocol (LSP) に沿って実装されている。gopls は Go 公式の Language Server。現段階でサポートされるのは以下の通り。

- Autocompletion (コードの自動補完)
- Jump to definition (定義へのジャンプ)
- Signature help (ヒントの表示)
- Hover (カーソル位置の情報の表示)
- Document symbols (シンボル一覧の表示)
- References (参照へのジャンプ)
- Rename (命名変更)

### 導入

[ここ](https://github.com/golang/tools/blob/master/gopls/doc/vscode.md)に書いてある内容を `settings.json` に追加する。

```json
"go.useLanguageServer": true,
"[go]": {
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true,
    },
    "editor.snippetSuggestions": "none",
},
"[go.mod]": {
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true,
    },
},
"gopls": {
    "usePlaceholders": true,
    "staticcheck": false,
}
```

保存するとインストールを促す通知が表示されるので、『Install』をクリックすれば OK。

![img_3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/69b080ee-0692-3b91-bd59-85b55159f165.png)

## 参考

- [golang/vscode-go](https://github.com/golang/vscode-go)
- [golang/tools](https://github.com/golang/tools)
[Swift] textFieldのclearButtonMode

`textField`は中身を全部消すことができる`clearButton`が実装できます。
画像の右端にあるバツマークです
![スクリーンショット 2020-08-24 18.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468821/1f892bd5-a824-5f92-7932-251a4dd66b3c.png)

これの表示パターンは`clearButtonMode`の設定で変更することができます。

## .always

`.always`はtextFieldに文字列があれば常に出現します。

```swift
textField.clearButtonMode = .always
```

## .never

`.never`はボタンを表示しません

```swift
textField.clearButtonMode = .never
```

## .unlessEditing

`.unlessEditing`はtextFieldに文字列があり、textFieldが選択されていない時に出現します

```swift
textField.clearButtonMode = .unlessEditing
```
## .whileEditing

`.whileEditing`はtextFieldに文字列があり、textFieldが選択されている時に出現します

```swift
textField.clearButtonMode = .whileEditing
```

## storyboard上での実装
textFieldのClearButtonの部分を変更すれば実装できます
 
![スクリーンショット 2020-08-24 19.01.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468821/53e3b02d-28d9-400a-c38a-e5350fab33b9.png)
Boost.Qiとlexmeを調べてみた


Boost.Qiにlexmeという記法(ディレクティブ）が使える。

<pre>
qi::lexeme[ascii::digit >> ascii::digit], ascii::space);
</pre>

ドキュメントを見てみる。

https://www.boost.org/doc/libs/1_65_1/libs/spirit/doc/html/spirit/qi/reference/directive/lexeme.html

The lexeme directive makes its subject a primitive. In a logical point of view, lexemes (and primitives) are minimal atomic units (e.g. words, numbers, identifiers, etc). These are the things that you'd normally put in the lexer (hinting at the term "lexeme"), but in a lexer-less world, you put these in a lexeme. Seeing its subject as a primitive, the lexeme directive does an initial pre-skip (as all primitives do) and turns off white space skipping.

よくわからない。。

コードを見てみる。

     1#include <boost/spirit/include/qi.hpp>
     2#include <string>
     3#include <iostream>
     4
     5using namespace boost::spirit;
     6
     7int main()
     8{
     9  std::string str;
    10  std::getline(std::cin, str);
    11  auto it = str.begin();
    12  bool match = qi::phrase_parse(it, str.end(),
    13    qi::lexeme[ascii::digit >> ascii::digit], ascii::space);
    14  std::cout << std::boolalpha << match << '\n';
    15  if (it != str.end())
    16    std::cout << std::string{it, str.end()} << '\n';
    17}

どうやら、lexme[]で囲われたパターン(ascii::digit >> ascii::digit)に関しては、スペースをスキップしないということらしい。

> the lexeme directive does an initial pre-skip (as all primitives do) and turns off white space skipping.


実行してみる。

<pre>
# ./a.out 
111 11
true
1 11

始めの2文字が数字なため成功

# ./a.out 
11 11 11 
true
11 11 

始めの2文字が数字なので成功

# ./a.out 
1 1111 1
false
1 1111 1

2文字目にスペースがある(数字でない）ためfalseになる。

</pre>

また、lexmeのパターンの前まではスペースをスキップする、ということになる。

<pre>
# ./a.out 
 11 111
true
111
</pre>
macOS のコンテクストメニューで HEIF 画像を JPEG に変換

# はじめに

HEIF 画像 => JPEG 変換をコンテクストメニューで行うのが便利なので、そのやり方を紹介します。なお、2019年5月当時のスクショ画像を元に記憶だけで書いてるので、再現できるかどうか微妙です。足りない手順に気づいた方、教えて頂けると幸いです。

以下のように、HEIF 画像(拡張子はheic)アイコンを右クリックしてクイックアクションから「JPEGで保存」を選ぶだけで JPEG に変換出来るようになります。

|![quickaction1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/d083a659-7ef4-193b-b7b9-2d7aa171fda1.png)|
|---|
|![quickaction2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/4b38374f-e934-a813-3e79-3339fd58db9e.png)|

iPhone7 の世代からカメラで撮影した画像を HEIF 形式で保存する事が出来ます。JPEG に比べて画質をあまり落とさずにサイズを大幅に削減できるので、利用している人は多いでしょう。

ただ、残念ながら古い機種や Apple 以外の製品だと HEIF を扱えない事が多いですし、そもそも Webブラウザが HEIF に対応する気がなさそうで、結局のところ JPEG に変換する手間から逃れられないです。

# 事前知識

実はデフォルトで macOS のクイックアクションに「PDFを作成」が存在します。これの JPEG 版です。
あと、クイックアクションは Animator で作れます。

# Animator

アプリケーションフォルダにある Animator を起動して、「クイックアクション」を作成します。

![animator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/82efdbcf-a978-67eb-9a67-d9a10db0fb23.png)
![quickaction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/5331361c-031a-6bd4-c929-b71bf3bc5645.png)

「イメージのタイプを変更」を右の真ん中にドラッグ＆ドロップして、以下のように設定します。

![imagetypechange.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/6b17d383-9813-f943-b429-9747dc2133e5.jpeg)

「メニュー」＞「書き出し」で workflow ファイルを生成します。

![export.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/ff33ba6f-a9e3-66ed-4c28-bd81ed74ef41.png)

生成された workflow ファイルをクリックして、メニューにインストールします。

![D70_jUSVUAAUdpvのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/6c916523-21ff-7271-3d14-2a0e5a5e6fce.png)

これで冒頭で紹介したような、HEIF 画像を選択してクイックメニューから JPEG で保存が実行できるはずです。

# 後始末

いらなくなったらシステム環境設定で、クイックアクションから外す事ができます。

![systemenvsetting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/096198b2-9823-3540-5705-7cc94a3b9c58.png)

# 課題

- JPEG quality が 95 になるので、Twitter に投稿する時に再エンコードが走ります。85 で変換出来ると良いのですが。
SaaS、PaaS、IaaS

応用情報技術者平成30年秋期 午前問38

JIS X 9401:2016(情報技術－クラウドコンピューティング－概要及び用語)の定義によるクラウドサービス区分において，パブリッククラウドのクラウドサービスカスタマのシステム管理者が，仮想サーバのゲストOSに対するセキュリティパッチの管理と適用を実施可か実施不可かの組合せのうち，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/042664f8-53f2-3e2b-4cc1-e815a9a38358.png)

JIS X 9401:2016では、クラウドコンピューティングのサービスモデル「SaaS」「PaaS」「IaaS」について次のように区分しています。
１、SaaS（Software as a Service）
サービス利用者が、クラウドサービス提供者の**アプリケーションを利用**することができる形態
※アプリケーション利用するだけ

２、PaaS（Platform as a Service）
サービス利用者が、クラウドサービス提供者によってサポートされる一つ以上のプログラミング言語と一つ以上の実行環境とを使って**利用者が作った又は利用者が入手したアプリケーションを配置し、管理し、及び実行する**ことができる形態
※アプリケーション自作など可
※MWインストールは不可


３、IaaS（Infrastructure as a Service）
サービス利用者が、クラウドサービス提供者の演算リソース、ストレージリソース又はネットワーキングリソースを供給及び利用することができる形態
※アプリケーション自作など可
※MWインストールは可


つまり、上記に三つは、
・SaaSはSoftware提供される。　
→Softwareを利用するだけ。　
例：Salesforce

・PaaSはPlatform提供される。　
→Softwareを自作する要。　
例：Google App Engine やMicrosoft Azure

・IaaSはInfra提供される。　　 
→MW（IIS、Apacheとか）インストール要。その上でSoftware構築する。
例：Google Compute Engine や Amazon Elastic Compute Cloud (EC2) 

となりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e9459326-9dbc-18ad-7882-e00921b25413.png)


参照：
https://www.ap-siken.com/kakomon/30_aki/q38.html

SaaS、PaaS、IaaSとは
https://www.cloud-ace.jp/column/detail01/