OmniAICreator/Qiita-1.07M huggingface dataset:
NaNって何なん？

# はじめに
いままでの人生であまり、NaNに出会わなかったので、いろいろ知らなかった。

# NaN
https://en.wikipedia.org/wiki/NaN
`IEEE 754 floating-point standard` にNaNあるよって書いてる。

こういうときに、NaNになるっぽい。

```
Indeterminate forms:
The divisions (±0) / (±0) and (±∞) / (±∞).
The multiplications (±0) × (±∞) and (±∞) × (±0).
Remainder x % y when x is an infinity or y is zero.
The additions (+∞) + (−∞), (−∞) + (+∞) and equivalent subtractions (+∞) − (+∞) and (−∞) − (−∞).
The standard has alternative functions for powers:
The standard pow function and the integer exponent pown function define 00, 1∞, and ∞0 as 1.
The powr function defines all three indeterminate forms as invalid operations and so returns NaN.
Real operations with complex results, for example:
The square root of a negative number.
The logarithm of a negative number.
The inverse sine or inverse cosine of a number that is less than −1 or greater than 1.
```

# Go
https://golang.org/ref/spec#Numeric_types
ここに、float32/float64はIEEE-754だよって書いてある

`float32     the set of all IEEE-754 32-bit floating-point numbers`

# 試してみた。

https://play.golang.org/p/Lo3TLcQCSfL

```go
package main

import (
	"fmt"
	"math"
)

func main() {
	var hoge float64 = math.NaN()
	fmt.Println(hoge)
	fmt.Println(math.IsNaN(hoge))
	var fuga float64 = math.Log(-1)
	fmt.Println(fuga)
}
```

```
NaN
true
NaN
```

なるほど。

# おわりに
NaNって値があるのにそこそこびっくり。エラーにしちゃわないところが、寛容な感じして微妙な気がするけど、結構便利そう。
バリデーションの設定で同じ記述をまとめる

バリデーションの設定で空白ではDBに登録できなくするpresence: trueはよく用いられると思います。
今まではカラム一つに対してpresence: trueを毎回記述していましたがwith_optionsを使うことで無駄な記述を省略してコードが読みやすくなりました。
例えば

```ruby
   validates :title, presence: true
   validates :name, presence: true
   validates :text, presence: true
```

このpresence: trueをwith_optionsを使うことで

```ruby
   with_options presence: true do
    validates :title
    validates :name
    validates :text
   end
```

スッキリとしたコードに編集することができました。
Appiumで要素のスクリーンショットを取る.

#Appiumで要素のスクリーンショットを取る.

[前回の記事](https://qiita.com/K-029/items/730223b3efd332eab068)で終わる予定だったが、困りごとが発生したので書いときます。
  テストランナーを別のテスト対象で動かそうとして、出力画面を取ろうとしたらキャプチャーが取れなかった。

- 環境
  Windows10
  Python 3.7
  Appium Python Client 1.1.0
  WindowsApplicationDriver 1.2.1

- 原因　どうやら上記環境では**get_screenshot**で[**要素**のキャプチャーはできないらしい](https://sqa.stackexchange.com/questions/46270/is-there-a-way-to-capture-screenshot-of-an-element-in-appium-for-python#)。
- 上記リンク先にコードがあったがWindowsアプリ用に書いた。

題材はまたしても[ワードパット](https://qiita.com/K-029/items/7d767086531ce862bafa)。

```python:element.py
# -*- coding: utf-8 -*-
import cv2
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

~ 前回記事を参照ください~

if __name__ == '__main__':
  #Windows Appliction Driverを起動 . 
  #ワードパッドを起動しておく. 
  appdriver = SetUp_SelectClassName('WordPadClass')
 
  filepath = r"driver.png"
  #Driverの画面をキャプチャ.   
  appdriver.save_screenshot(filepath)
  #要素のを取得.
  element= appdriver.find_element_by_name("リッチ テキスト ウィンドウ")
  #位置とサイズを取り出す.
  elwindow = {}
  elwindow["top"] = element.location["y"]
  elwindow["bottom"] = element.location["y"]+element.size["height"]
  elwindow["left"] = element.location["x"]
  elwindow["right"] = element.location["x"]+element.size["width"]
  #保存したイメージから要素の画像を切り出す.  
  img = cv2.imread(filepath)
  img1 = img[elwindow["top"] : elwindow["bottom"] ,  elwindow["left"] : elwindow["right"] ]
  #確認してみる.  
  cv2.imshow('sample', img1)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  
```

これで要素のイメージを取って画像認識できました。
トリミングについては[こちら](https://qiita.com/ikanamazu/items/d752225a0a9834ce0d41)を参考にしました。
なぜ、たかが個人サイトでユニットテストを書くのか

# TL;DR
サービスの品質ではなく、エンジニアの品質を向上させるためにユニットテストは書くべき。

# はじめに

日曜プログラマーのみなさん、個人開発してますか？

ポートフォリオサイト、ブログ、モバイルアプリなどを気の向くままに開発しているのではないでしょうか。

では、その**awsome**なサービスにおいて、ユニットテストは通してますか？

「完成品をブラウザから動くことは確認してるけど、、、」
「テスト回すよりも新規機能を追加したい」
「いや、そもそもバグなんて発生しないから」

いろんな背景から、こだわってユニットテストを書くことは後回しになってはいないでしょうか。
（私はわざわざ休日の貴重な時間を割いてまで、テストコードは書かない派でした）

しかし、今回個人のポートフォリオ作成において、テストコードを書いてユニットテストを実施しました。
その中で様々な学びがあったため、振り返りつつユニットテストを書くことのメリットを紹介します。

# 個人開発でユニットテストはサボりがち

そもそもなぜ私は今までユニットテストをはじめ、テストコードをきちんと書いてこなかったのでしょうか。

ざっくりと言えば、
 **「品質向上のためにテストコードを書くことが、個人開発においてはコスパの悪い活動だから」**
と私は考えます。

具体的な要因としては以下の3つだと考えます。

### 1. :game_die:Logicが少ない

個人開発で運用されるサイトにおいて、複雑な分岐や処理を含むことは少ない印象です。

また、あまりに複雑なことがしたい場合は、外部のライブラリに頼り楽をすることが個人的には多いです。

従って、自身が記述したロジックに対してテストコードを書くことで、新たに発見される問題は少ないといえます。

### 2. :fire:Impactが小さい

多くのユーザを抱えるサービスや公式アプリ等であれば、バグの発生はイメージダウンや信頼性の低下を招きます。また、ECサイトなどであれば、サービスが停止することで多くの機会損失が生まれます。

従って、「システムの品質」＝「死守すべきもの」といっていいでしょう。

一方で、個人サイトやブログであれば、極論何か問題が起きたとしても **誰にも迷惑はかけません**。

従って、基本動作に問題がないことを確認すればよく、それ以上の品質追及は誰得状態になります。

### 3. :family_mwgb:Memberがいない

個人開発において、試行錯誤を繰り返しながらサービスが構築され、全てのフロー制御・依存関係・例外処理は脳内デバッグされていきます。

すべての設計図は開発者の頭の中にあります。

従って、E2Eでの動作確認がクリアされている時点で、単体での品質はある程度担保されているといえるでしょう。

# ユニットテストを書いた方がいい3つの理由
上記のような要因からあまりテストコードを書いてこなかった筆者ですが、今回ユニットテストをおこなうにあたり得られたメリットが以下の3つです。

### 1. 🤔コピペコードを真に理解する

個人開発のモチベーションとして、新しい技術を触ってみたいというのが根底にあります。

従って、コードの大半はチュートリアルやQiitaから`Crtl+C,V`をすること多いです。すると、経験上あまり内容を深く理解することなく、動くものが作れてしまいます。

ここで、コピペで作り上げたキメラのようなサービスを、改めてユニットテストを書くことで理解を深めることができました。

「あれ、テストコードすらコピペしたら意味ないのでは？」

と思いますが、複雑化したコードを評価できるようなサンプルは世に落ちていないようです。

### 2. 🔧保守性が向上する

専門家ではないので細かいことは分かりませんが、巨大なモジュールやコンポーネントはテストパターンが分かりにくく、テストコードを記述することが難解になりました。

そこで、ユニットテストのカバレッジを上げていくためには、コンポーネントを適切に分割し、StubやMockを活用しながら単体ごとに評価してくことが求められました。
[マニュアルモック](https://jestjs.io/ja/docs/manual-mocks)

従って、ユニットテストを記述していく過程で、TestableでReadableなコードに近づくことでしょう。

### 3. 👨‍⚕️過去の自分を振り返る

テストコードを通すというのは、過去の自分を見つめなおすことと同義だと感じました。

「誰だよこんな意味不明な分岐作ったのは」
「なんで同じこと何回も書いてんだよ」

そんなストレスを自分に対して感じることで、反省点と改善点を自分の中で整理することができました。

このサイクルを自分だけで簡単に回すことができるのは、テストコードを書いたおかげだと思います。

# まとめ

本来ユニットテストの目的は個々の機能における品質を担保するために行われます。

一方で、個人開発程度のサービスに対して、わざわざ汗をかいて品質を担保することは、時間のない現代人にとってコスパの悪い活動といえるでしょう。

しかし、一度書いたコードを見つめなおして、あまたを使いながらリファクタリングすることで、本来の目的である技術への理解を深めることができると思います。
【Androidを使い熟す！】Android Layoutについて

#####※Android技術者認定にも役に立ちます！
#Layoutとは
<details><summary>説明</summary>アクティビティなど、アプリ内のユーザー インターフェースの構造を定義する。</details>
#よく使われるLayout
<dl>
  <dt>・LinearLayout</dt>
  <dd>Layout内にViewを【縦】また【横】に並べて配置が可能なLayout。</dd>
  <dt>・RelativeLayout</dt>
  <dd>Layout内に特定Viewを基準として自由に配置が可能なLayout。</dd>
　<dt>・ConstraintLayout</dt>
  <dd>RelativeLayoutと似てるが、Layout内、ビューに対して最低 1 つの水平方向の制約と 1 つの垂直方向の制約を設定する必要という違いがある。</dd>
　<dt>・TableLayout</dt>
  <dd>表組みを作成するレイアウト</dd>
　<dt>・FrameLayout</dt>
  <dd>Layout内にViewを1つのみで配置が可能なLayout</dd>
　<dt>・AbsoluteLayout</dt>
  <dd>Layout内に座標で指定して配置が可能なLayout</dd>
</dl>
submoduleの役割と使い方の備忘録

#Submodule知らないとハマる
らしい。
ということで調べたことをまとめた備忘録です。

基本git公式の焼きまわしの二番煎じしか書いていないので
より詳しいことはリンク飛んでください。

[こちらの記事](https://www.m3tech.blog/entry/git-submodule)が大変わかりやすかったので参考にさせていただきました。
もうぶっちゃけこっちを見とけばいいと思いますが、必要最低限のことをより端的にまとめました。

# 概要
+ 登場人物：親(主ブランチ)、子(別レポジトリのコミット)
+ 役割    ：親(主ブランチ)が子(別レポジトリのコミット)を参照する。
+ 注意点  ：
    + 参照はコミット単位。ブランチ単位ではない。
    + 子を自動で追跡はしない。明示的に参照を変える。
    + サブモジュールのあるブランチから無いブランチに切り替えると「追跡されていないディレクトリ(working treeにある状態)」として残ってしまう。
    + 親からサブモジュールへの切り離しは、親の該当ディレクトリをアンステージしてから。


### git submodule
+ git標準機能
+ 関連ファイル
    + .gitmodules
    + .git/config
    + インデックスとワーキングツリー

# 使い方
主にやれることは
##### 1. サブモジュール追加
##### 2. サブモジュール変更(リビジョンの変更)
##### 3. サブモジュール削除
##### 4. サブモジュール付きクローン
##### 5. (リモートでのみ)サブモジュール参照している場合、ローカルでも参照させる

<br>
<br>

+ サブモジュールを追加する時

```
$ git submodule add https://example.com/sub-modules # .gitmodules ファイルが更新される
$ git commit -a # 変更を保存（必須！）
```

+ サブモジュールのリビジョンを変える

```
$ cd sub-module # サブモジュールのディレクトリに移動
$ git fetch && git reset --hard origin/master # 適当なコマンドで、必要なバージョンをチェックアウトする

$ cd ../ # 親側に移動
$ git commit -a # 親側でコミット
```

+ サブモジュールを削除する

```
$ git submodule deinit -f sub-module # 登録解除
$ git rm -f sub-module # ファイルを削除
$ git config -f .gitmodules --remove-section submodule.sub-module # 設定ファイルから削除
$ git commit -a # 変更を保存（必須！）
```

+ サブモジュール付きクローン
`--recursive`を付ける。

```
$ git clone https://example.com/repo-with-sub-modules --recursive
```

+ (リモートでのみ)サブモジュール参照している場合、ローカルでも参照させる

```
$ git submodule update --init
```
 
+ どのサブモジュールを参照しているか

```
git submodule status
```





##### リビジョン？
コミットは動作、リビジョンはコミットされた状態の単位
https://qiita.com/YumaInaura/items/dc9e582d7096f54e649b

# 時々見返すメモ
* -dirty とは何か

```
$ git diff
-Subproject commit <コミット番号>
+Subproject commit <コミット番号>-dirty
```

特に触った覚えのないsubmoduleに`-dirty`付きで差分ができていた。
追跡されていない、もしくはsubmoduleに変更が加わった時に表示される。
IDEの一括変換などでウッカリ変更しちゃうなどもある。
>Submodules are now regarded as dirty if they have any modified files or untracked files, whereas previously it would only be the case if HEAD in the submodule pointed to the wrong commit. Why is this annoying? Submodules are now regarded as dirty if they have any modified files or untracked files, whereas previously it would only be the case if HEAD in the submodule pointed to the wrong commit. Why is this annoying? 


https://longair.net/blog/2010/06/02/git-submodules-explained/

https://www.it-swarm-ja.com/ja/git/git-diff%E3%81%AF%E3%82%B5%E3%83%96%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%8C%E6%B1%9A%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E8%A8%80%E3%81%86/972084848/

https://nprog256.net/post/2019/06/git-submodule-dirty/

### 参照
[submoduleとは/使い所/ﾁｰﾄｼｰﾄ](https://www.m3tech.blog/entry/git-submodule)
[7.11 Git のさまざまなツール - サブモジュール](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)
【初心者】突然、日本語入力できなくなった事象の解決手順【ショートカットキー】

<h2>症状</h2>
記事を書いている最中に突然、日本語入力ができなくなる事象に遭遇しました。

windowsのバーにあるIMEパッドは、下記のようになる状態でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/af1d58a3-f294-7d77-c7ff-8c229bac5fc9.png)

以前同事象に遭遇した際、ググってみたもののいい感じの対処法が見つからず、PCの再起動を実施して直していました。
が、今回解決したのでその方法を書いていきます。

OSは、Windows10です

<h2>解決方法</h2>
プライベートモードをOFFにすることで解決できました。
<b>CTRL+Shift+F10</b>でON/OFFできるようです。

また、画面右下のIMEのカギマークも消えていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/0bc2fc81-e9d1-2690-1db4-ec86248f0d29.png)


今まではCTRL+Shift+F10を誤って押してしまったことで、ONになってしまっていたようです。。。
あっさりですが、この記事で救われる方がいると幸いです。
ångstromCTF 2021 Writeup

## SITE 
https://2021.angstromctf.com/challenges

## My Writeup

### [crypto]
####[Relatively Simple Algorithm](https://qiita.com/_kkri_/items/50b1d76b3d1b1d8a57bd)
####[Exclusive Cipher](https://qiita.com/_kkri_/items/8d699e027b898c827c9e)
####[Keysar v2](https://qiita.com/_kkri_/items/0260d929fb39a57b2a69)
####[sosig](https://qiita.com/_kkri_/items/21f637f1186f3c4d65c6)
####[Home Rolled Crypto] (https://qiita.com/_kkri_/items/f555f6fa0507f6bc87a0)
Exclusive Cipher(Writeup)

## 問題
https://2021.angstromctf.com/challenges

>Clam decided to return to classic cryptography and revisit the XOR cipher! Here's some hex encoded ciphertext:<br>
ae27eb3a148c3cf031079921ea3315cd27eb7d02882bf724169921eb3a469920e07d0b883bf63c018869a5090e8868e331078a68ec2e468c2bf13b1d9a20ea0208882de12e398c2df60211852deb021f823dda35079b2dda25099f35ab7d218227e17d0a982bee7d098368f13503cd27f135039f68e62f1f9d3cea7c
The key is 5 bytes long and the flag is somewhere in the message.

## 解法
問題文によると5byteずつXORされているので5byteおきにsingle byte xorを試して候補を求める

## コード
```python:solution
def disas(m:bytes)->[int]:
    return list(*[iter(m)])

def single_xor(hex_str):
    d =bytes.fromhex(hex_str)
    candidates = []
    for i in range(0x100):
        b = ""
        score = 0
        for j in disas(d):
            if 0x20 <= i^j <= 0x7e:
                if 0x21<=i^j<=0x2f or 0x3a<=i^j<=0x40 or 0x3a<=i^j<=0x40 or 0x7b<=i^j<=0x7e:
                    score += 0.2   
                else:
                    score += 1
                b += chr(i^j)
        candidates.append((b,score,i))
    return sorted(candidates,reverse=True ,key=lambda x:x[1])[0]

c = "ae27eb3a148c3cf031079921ea3315cd27eb7d02882bf724169921eb3a469920e07d0b883bf63c018869a5090e8868e331078a68ec2e468c2bf13b1d9a20ea0208882de12e398c2df60211852deb021f823dda35079b2dda25099f35ab7d218227e17d0a982bee7d098368f13503cd27f135039f68e62f1f9d3cea7c"
c_pad = c + "00"* (5-(len(c)//2)%5)
print(c_pad)
l = ["".join([x+y for x,y in zip(c_pad[i::10],c_pad[i+1::10])]) for i in range(0,10,2)]

for i, s in enumerate(l):
    print(i,single_xor(s)[0],hex(single_xor(s)[2]))
```
```txt:output
0 Cat etteeegaweahovroun rp 0xed
1 otiocihs!  cheeeue}oc o t 0x48
2 nuonrnes fitodsn__.dkttco 0x85
3 gln yg aTlsf_s__hx   hhr! 0x5d
4 rasdp mgha {n_wyaoGloeeyf 0x66
```
single_xorでは、0x00~0xffまでのXORをスコアリング（英数スペース１点、その他記号0.2点）しながら実行し、一番スコアの高い文字列とそのスコア,XORした値を返します。
outputが縦読みできそうなので成功です。
うまくいかない時はsingle_xorで出力する候補数を増やしたり、状況によってスコアリング方法を変えたりもします。

```python:solusion2
key="ed48855d66"*25
ans = int(c_pad,16)^int(key,16)
print(bytes.fromhex(hex(ans)[2:]))
```

```txt:output2
b'Congratulations on decrypting the message! The flag is actf{who_needs_aes_when_you_have_xor}. Good luck on the other crypto!f'
```
【AWSを無料で使おう！】無料枠でできること

# はじめに
本記事では、無料枠でできることの中から、AWS初心者におすすめなサービス（EC2、RDS、S3）だけを抜粋して、無料でどのくらい使用できるのかを紹介しております。
※無料枠多いので全部は網羅していませんよということです。

# EC2
EC2インスタンスは以下の条件で無料で利用することが可能です。

- **期間：** 12か月間。1か月あたり750時間まで。
- **インスタンスタイプ：** t2.micro
- **OS（2021年4月時点）:**
    - Amazon Linux 2
    - Amazon Linux 2 with .Net Core, PowerShell, Mono, and MATE Desktop Environment
    - Microsoft Windows Server 2019 Base
    - Microsoft Windows Server 2019 Base with Containers
    - Microsoft Windows Server 2016 Base
    - Microsoft Windows Server 2016 Base with Containers
    - Microsoft Windows Server 2012 R2 Base
    - Microsoft Windows Server 2004 Core Base
    - Red Hat Enterprise Linux 8 (HVM), SSD Volume Type
    - SUSE Linux Enterprise Server 15 SP2 (HVM), SSD Volume Type
    - SUSE Linux Enterprise Server 12 SP5 (HVM), SSD Volume Type
    - Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
    - Ubuntu Server 18.04 LTS (HVM), SSD Volume Type
    - Ubuntu Server 16.04 LTS (HVM), SSD Volume Type
    - Debian 10 (HVM), SSD Volume Type

- **注意点：** 無料枠の条件を満たすEC2インスタンス1台ごとに、1か月につき750時間利用できるのではありません。
例えば、無料枠の条件を満たすEC2インスタンスを3台、1か月間起動しっぱなしにした場合、以下のような状態になってしまいます。（1か月が31日間=744時間の場合）
    - EC2インスタンス①：744時間常時起動→無料
    - EC2インスタンス②：744時間常時起動→6時間分のみ無料、738時間分は有料
    - EC2インスタンス③：744時間常時起動→744時間分すべて有料

つまり、**無料枠の条件を満たしたEC2インスタンス全部で750時間/月まで無料**ということです！

EC2インスタンスの起動手順確認や検証環境としての利用目的だったら、使い終わったらすぐに消せば良いので、充分活用できますね！

# RDS
RDSは以下の条件で無料で利用することが可能です。

- **期間：** 12か月間。1か月あたり750時間まで。
- **DBインスタンスタイプ：** db.t2.micro（Single-AZ）
- **DBエンジンの種類：**
    - MySQL
    - PostgreSQL
    - MariaDB

※Oracle BYOL、SQL Serverも選択できると記載がありますが、実際のマネジメントコンソール上では無料枠との記載が確認できなかったので除外してあります。

- **ストレージ容量：** 20 GB の汎用 (SSD) データベースストレージ
- **バックアップ：** 20 GB のデータベースバックアップおよび DB スナップショット用ストレージ
    - 20GBまでのバックアップ取得と、20GBまでのスナップショットの保持が可能ということです 
- **注意点：** EC2インスタンス同様、無料枠の条件を満たすDBインスタンス全部で750時間/月まで無料です。

ストレージ容量が20GBまでなので、簡単な検証（例：EC2インスタンス上にZabbixを構築→DBとしてRDSを使用する等）やRDS起動の手順とバックアップの挙動を確認するくらいなら活用できそうですね。



# S3
S3は以下の条件で無料で利用することが可能です。

- **期間：** 12か月間
- **容量：** 5GB（標準ストレージ）
- **Getリクエスト：** 20,000件
- **Putリクエスト：** 2,000件
- **データ転送：** 15GB

S3は、バケット作って適当なファイルアップロードしてみる動作確認くらいしかできなさそうですが、とにかく1回触ってみて操作を覚えたいって人には良いと思います！
（CloudTrailのログ出力先とするっていうのを思いつきましたが、意外と結構なリクエスト数になるんじゃないかと思いますので、まだAWSの料金体系に不慣れな場合はあまりおすすめしません…！）



# 無料枠の使用量を確認するには？
無料枠をどれだけ使用したかは以下の方法で確認することが可能です。

1.マネジメントコンソールにルートユーザでサインイン

2.「マイ請求ダッシュボード」をクリック
![スクリーンショット (52)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494752/b2e1e91c-5bc4-254a-9392-7195f016e3f8.jpeg)


3.下部へスクロールし、「使用状況別の上位無料利用枠サービス」の「すべて表示」をクリック
![スクリーンショット (52).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494752/c161937a-3c24-b374-097b-5436bd972234.png)

4.以下の通り詳細が表示される
![スクリーンショット (53).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494752/f875bb75-08f2-dfe5-63dd-4610a02a9298.png)
使用量が多い順に表示されるので、「このサービスそろそろ危ないな」というのが一目で確認できます！

以上。

# まとめ
無料枠は調べれば他にもたくさんあるので、自分が使ってみたいAWSサービスがあればまず検索してみて、もし無料枠があれば思い切ってやってみちゃうと良いと思います！
無料枠どんどん活用して、AWSマスターを目指しましょう～

- 参考URL
    - [AWS クラウド無料利用枠](https://aws.amazon.com/jp/free/free-tier/)
Ruby on Railsの環境構築　sudo gem install rails でのエラー【Mac】

Railsの環境構築で、`sudo gem install rails`を実行した時に、次のようなエラーが発生しました。
 
```rb

% sudo gem install rails -v "6.1.3"  
Building native extensions. This could take a while...
ERROR:  Error installing rails:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/nio4r-2.5.5/ext/nio4r
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210227-1015-xk5n2d.rb extconf.rb
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/include/ruby.h

You might have to install separate package for the ruby development
environment, ruby-dev or ruby-devel for example.

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/nio4r-2.5.5 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/nio4r-2.5.5/gem_make.out
```

この場合、`xcode-select --install`を実行することで解決しました。

試してみて下さい。
gem foreman について簡単に知る

## この記事の目的
業務で日々出てくる新しい学習をまとめています。
いつも名前だけ見ていた、`foreman`というgemが業務で登場したので、メモを残します。

## foremanとは？
アプリの外部にある`Procfile`というファイルに設定を書き込むと、WEBアプリの立ち上げに必要なさまざまなプロセスを一気に立ち上げることができます。

▶︎[Getting Started(公式)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)

例えば今回のプロジェクトでは、アプリケーションルート直下にある`Procfile`というファイルに、以下のように設定が書き込まれていました。

```Procfile
web: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
webpacker: ./bin/webpack-dev-server
```

これは`web`という名前でRailsのプロセスを、`webpacker`という名前でWebpackerのプロセスを実行するコードになります。

`foreman`が実行できる状態で、ターミナル上で、

```sh
$ foreman start
```
をすると....。

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

`webpacker`と`web`それぞれの名前でプロセスが実行されているのがわかります。（左端に注目！）

これからは、`rails s`と`bin/webpack-dev-server`を別々のターミナルでそれぞれ立ち上げなくてよくなりますね。

### 留意点？導入について

ただ、今回はgemで`foreman`を入れてしまったのですが...。

```ruby:Gemfile
group :development do
  gem ‘foreman’
end
```
[公式サイト](https://github.com/ddollar/foreman)を見ると、思い切りこんなことが書いてあります。

> Ruby users should take care not to install foreman in their project's Gemfile. See this [wiki article](https://github.com/ddollar/foreman/wiki/Don't-Bundle-Foreman) for more details.

引用文中で言及されている[wiki article](https://github.com/ddollar/foreman/wiki/Don't-Bundle-Foreman)によると、bundleするとアプリにバグが発生する可能性があるから、コマンドで入れてね、ということでした。

```sh
$ gem install foreman
```
次回から気をつけます。。。

### おしまい・参考文献
とにかくにも、以前から気になっていた`foreman`について知ることができてよかったです。

実装時にはこちら↓の記事を参考にしました。わかりやすかったです。

- [【Rails】foremanでrails serverとwebpack-dev-serverを一度に起動する](https://blog.yuhiisk.com/archive/2018/04/25/rails-and-webpacker-server.html)

次回はaxiosなど詳しく知りたいなー。と思ったり。
[OutSystems]BPTの新しいコース「Building Your First Business Process」を試してみる

OutSystemsで、ワークフローや、一定期間停止したり特定のイベントが発生するまで処理を中断するようなバッチを作る事ができる機能がBPTです。ずっと古い教育コース（動画）しかなかったのですが、最近新しいコースがOutSystems11に対応して、出ているのに気づいたので一通りやってみました。

[Building Your First Business Process](https://www.outsystems.com/training/courses/183/building-your-first-business-process/) レベル表記がAdvancedとなっており、OutSystemsの開発自体には慣れている人向けで、基本的な操作等についての説明はふくまれていません。

# コースの概要
BPTの代表的な機能を紹介しながら、経費精算ワークフローを作っていきます。
最初に作成するワークフローの仕様を紹介し、BPMNを使って表した図が紹介されます。
この図で表されたワークフローを、以下の順でBPTの機能紹介→その機能を利用した実装を追加、の順番で組み上げていく内容でした。
1. Human Activity：ユーザーにOutSystemsで作った画面を作って実行するタスクを割り当てる機能
2. Automatic Activity：小さなバッチ。ワークフロー内でそのステップに達したときに自動で動作するロジックを作る機能
3. Conditional Start：特定のEntityへのレコード追加／更新が発生するまで待ち、その時点で処理を起動させる機能（発生しなかったらこの部分は動かない）
4. Sub-Process：ワークフローから別のワークフローを起動する機能
5. Decision：ワークフロー内で処理を分岐させる機能
6. Wait：特定の時期、または特定のEntityへのレコード追加／更新が発生するまで処理をそこで止める機能
7. Callback：ワークフローまたは、ワークフローの特定の機能のイベント（開始／終了など）のコールバックを作成する機能

注意としては、2021/4/8時点では英語字幕しかつけられませんでした。

# デモアプリケーション
コースの最初の方の動画のLesson Materialsボタンから素材のアプリケーションをダウンロードできます。
ここにワークフロー以外の必要な機能は作成済みなので、ワークフローの作成に集中できます。

以前の（古い）BPTコースと違い、デモアプリケーションはReactive Web Appsです。
Traditional Webと、BPTの面では大きくは違いません（Taskboxを除き）。

# テストユーザーとロール
デモアプリケーションを作っていく動画中で、当然のように特定のロールを持ったユーザーでログインして……のような案内があります。
コースのLesson Materialsからダウンロードできるデモアプリケーションの素材の中に、When Published（モジュールをPublishしたときに起動するバッチ）でテストユーザーを作り、必要なロールを割り当てるようになっているので心配いりません。

デモアプリケーションを実行するとログイン画面に遷移しますが、画面下部のドロップダウンリストからログインしたいユーザーを選ぶと、自動的にログインさせてくれる作りになっています。

# Taskboxについて
Taskboxというのは、OutSystemsが標準提供する仕組みで、ログインユーザーに割り当てられているタスクを一覧し、タスクの処理を開始させる事もできるUI。
Traditional Webではデフォルトで有効になっていましたが、Reactive Web Appsでは自分で画面に配置する必要がある点に注意。デモアプリケーションにはこのTaskboxを組み込み済みなので心配はいりませんが。

以前QiitaでこのTaskboxをReactive Web Appsに配置する方法について書きました：[Reactive Webのカスタムタスクボックスを試してみる](https://qiita.com/jyunji_watanabe/items/04ff33b5f0946af40465)

# このコースで得られるもの
OutSystemsのBPTが何となく分かる、構成要素がなにであるかわかる、位のレベルです。
実際のプロジェクトで実装するなら、まずこのコースで概要を掴み、実際に実装するときはドキュメントを読み込む必要がありますね。
また、このコースはワークフロー側に注力していて、ワークフローと画面を連動させる部分には触れられていません。

ちなみに、私も以前BPTのチュートリアルを書いてみたことがあります：[シンプルなBPTの実装例](https://blog.house-soft.info/archives/1142)
こちらは、Traditionalで実装していて、Human Activity1つだけで構成される非常にシンプルなものになっています。
VS Code　Emmetについて

VSCodeを使い始めて、今まで補完機能の存在を知らなかったため備忘録兼ねて投稿します。。。

#機能
 Emmet
 独自の省略記法でHTML・CSSのコーディングの効率化をサポートしてくれるプラグイン。
 以下、「補完内容」で記述をすれば、コードを全て入力せずとも記述が完了する便利機能です。 

#設定方法
 VSCodeを開いた後、左下の歯車をクリック→「設定」をクリック
 検索入力で「emmet」と入力→中段「Emmet Trigger Expansion On Tab」にチェックをつける

#補完内容
|  記号  | 役割               | 記述例　　　　|
|:------:|:------------------|:-----------|
| #     | ID名の指定          | div#idName   |
| .     | class名の指定       | div.className|
| >     | 要素を入れ子にする    | div>p         |
| +     | 要素を同階層に展開する | div+p         |
| ^     | 一階層上に展開       | div>p^ul      |
| *     | 要素を複数展開       | li*3      　　|
| {}    | テキストの挿入       | p{テキスト}      |
| $     | 連番をつける        | li.item-$*3    |
| !     | HTMLの雛形        | !　　　　　      |

#おわりに
早速試しましたが、今まで一言一句打っていたのが泣けてくる位、コード打つのが早くなりました。
今回の他にも、ショートカットや知らない効率機能がたくさんありそうなので、どんどん調べて
実装力を鍛えていきます！
Rubyの日付を扱うクラス

※初学者によるアウトプットのため正確性にかけるかもしれません。
　ご注意ください。

日付を扱うためには、Dateクラスを使用します。requireを使って読み込むことで、自分でクラスを定義しなくても使うことが可能です。	
		
Dateクラスは、Date.newでインスタンスを作れます。インスタンスを出力すると、日付を表示できます。下の例以外でも色々な日付インスタンスメソッドがあります。

例えばこんな感じですね。
require "date"	
　〇〇 = Date.today

puts 〇〇

上のものは今日の日付のインスタンスを出力しています。
【Git】git megerでfatal: No remote for the current branch.と言われた時の対処法

<h2>症状</h2>
「git add -A」や「git commit」などを行い、「git merge」を実施したところ、下記のエラーが表示されました。

```
git merge
fatal: No remote for the current branch.
```

翻訳すると、「fatal: 'origin/master' does not appear to be a git repository。致命的：現在のブランチのリモートはありません。」となりました。
リモートリポジトリがないため、表示されてしまったようです。

<h2>解決方法</h2>
リモートリポジトリを設定したら問題なくできました。

```
#リモートリポジトリを設定
git remote add origin https://github.com/ユーザー名/リポジトリ名.git
　
```
<h2>参考</h2>
Railsチュートリアル
https://railstutorial.jp/chapters/beginning?version=6.0#sec-git_setup
sftp でハマったので色々やってみた

# やったこと
- 無駄にssh-keygen のbash を作成
- sftp コマンドの接続
- bashrc の設定変更

# なぜやったのか
- sftp で接続を試したが、パスフレーズを忘失 or sftp接続エラーかがわからなかった
- ポート番号・ファイル指定 のsftp を漁るのに時間がかかった
- ↑ をやった上で、エラーが発生した

# 無駄にssh-keygen のbashを作成
作る意味は、全くないと思います。
また作成するのかーコマンド探して考えるのが面倒だな！！って思ったので、無駄に作成。

```code:muda-sshKeygen.sh
#!/bin/bash

set -eu

cd ~
ssh-keygen -t rsa -b 4096
mv ~/.ssh/id_rsa.pub /home/snowdog/.ssh/authorized_keys
```

権限の設定変更

```
# chmod 700 muda-sshKeygen.sh
```

# sftp コマンド接続
ポート番号・ファイル指定の場合

ローカルPCからの接続
★ちなみに、以下の22番は指定する意味ないけどね

```
# sftp -P 22 -i .ssh/id_rsa ユーザ名@接続IPアドレス
[エラー発生]
Received message too long 11111111
Ensure the remote shell produces no output for non-interactive sessions.
```

# bashrc の設定変更
こちらで解決出来ました
- https://qiita.com/7of9/items/b08a2846023796975c16
- https://lealog.hateblo.jp/entry/2012/12/30/160812

```code:~/.bashrc
1 && return
2 
3 .......
```

必ず、先頭に入れましょう！！
やってる内容は、
> 「対話型ではない接続」の場合は、以降を読み込まないようにしてるだけ。
普段のTerminalでの接続では、いつも通り読み込まれます。

との事でした。

# まとめ
無駄な時間を過ごした事に変わりなし。
無事sftp 出来たー！！
ssh 接続で、ftp で使うポートを使ってるけど開放はしなくていいって楽だね。

前座が終わったので、次のタスクに行きましょうか・・・
git push --set-upstream origin/master masterをしたとき、fatal: 'origin/master' does not appear to be a git repositoryの対処法

<h2>症状</h2>
「git push」をした際に、下記エラーメッセージが表示されてしまいました。
翻訳すると、
「致命的：「origin / master」はgitリポジトリではないようです。致命的：リモートリポジトリから読み取ることができませんでした。正しいアクセス権があることを確認してください」でした。
リモートリポジトリが何らかの原因で読み取れないようです。

```terminal:ターミナル
#git pushをして表示されたエラー
git push origin/master
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin/master master

#エラー通りコマンドを実行

git merge
git push --set-upstream origin/master master
fatal: 'origin/master' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```


<h2>解決方法</h2>
リモートリポジトリを設定することで解決しました。
リモートリポジトリを登録し忘れていたため読み取れなかったようです。。

```terminal:ターミナル
#リモートリポジトリを登録
git remote add origin https://github.com/ユーザー名/リポジトリ名.git

#再度pushコマンドを発行すると、pushできました
git push --set-upstream origin master
```

補足ですが、リモートリポジトリを誤ったものを登録していた場合、以下コマンドで取り消して再度登録することができます。

```terminal:ターミナル
git remote rm origin
```

<h2>参考</h2>
Railsチュートリアル
https://railstutorial.jp/chapters/beginning?version=6.0#sec-git_setup

【Git】誤って登録したリポジトリを取り消して、再登録する方法
https://qiita.com/GalaxyNeko/items/0739083fd6d3797779ec
Githubとかにアップする前にAPIキーを差し替える

# はじめに

https://qiita.com/xkogij/items/2554c37929caf6f6fc3c

この記事でGoogle Maps JavaScript APIを使って地図書いたんですが、記事を書いたり、githubにアップする際、自分のAPIキーを晒すのってなんか嫌なので、アップするときに隠して使うときに設定できるスクリプトをpythonで書きました。

https://github.com/xiaomuc/gmap_ksgg

ソースはここです。./py/replacekey.pyがそう。

# 設定ファイル
githubには上げてませんが、設定ファイルが必要。replacekey.pyと同じフォルダにおいておいてください。

* keys.json

```
{
    "mine":"YOUR_API_KEY",
    "other":"OTHER_API_KEY"
}
```

mineは必須です。複数持っている場合は複数登録しておきます。

# 使い方

* YOUR_API_KEY -> 自分のキー

```
python ./py/replacekey.py
```

実行したフォルダにある*.htmlを対象に、YOUR_API_KEYって文字列をkeys.jsonのmineで登録したキー文字列に置換します。

* 自分のキー -> YOUR_API_KEY

```
python ./py/replacekey.py --mode hide
```

上の逆ですね。keys.jsonに登録した文字列をすべてYOUR_API_KEYに置換します。なお、--modeは-mでも可。

* キーを指定する場合

```
python ./py/replacekey.py --key other
```

これはYOUR_API_KEYをotherで登録した方に置換します。
--keyは-kでも可。省略時は-k mine。

* 置換するパスを指定する場合

```
python ./py/replacekey.py --path ./subfolder/*.html
```

ワイルドカード使ってもよし、ファイル決め打ちでも良しです。
--pathは-pでも可。

* 設定ファイルを指定する場合

```
python ./py/replacekey.py -json ./another.json
```

設定ファイルを別に持ちたい場合。そんなこと必要ないかもと思いつつつけてみました。--jsonは-jでも可。

* ヘルプ表示

```
python ./py/replacekey.py --help
```
為替レートAPIのexchangeratesapiの代わり(2021/4)

#アプリが動かない！

アプリが動かなくなりましたというご報告をいただき、調査したところ、為替レート取得でエラーになっていました。

# 原因
下のサイトを利用していたのですが、2021/4から？認証が必要になっていました。
https://exchangeratesapi.io/

無料枠では、250/月では少し足りないかなと思い、探し回りました。

# 代わりを探そう

あちこち探し回りましたが、見つからない。。。

でも、ようやく見つかる。

いつも使っている海外の仮想通貨取引所のBitifinexの公開APIにあったので、差し替えたら無事に動きました
https://docs.bitfinex.com/reference#rest-public-calc-foreign-exchange-rate

# 実装を直す

```old.dart
http.Response resp1 =
        await http.get("https://api.exchangeratesapi.io/latest?base=USD");
    return json.decode(resp1.body)['rates']['JPY'];
```

```new.dart
Map<String, String> headers = {"content-type": 'application/json'};
String body = json.encode({'ccy1': 'USD', 'ccy2': 'JPY'});
http.Response resp1 = await http.post("https://api.bitfinex.com/v2/calc/fx", headers: headers, body: body);
return json.decode(resp1.body)[0];
```

外部APIを使う定めなのか、変更リスクはありますね。
使えなくなってからでしか、気が付かない。。。


めでたしめでたし
【Git】誤って登録したリポジトリを取り消して、再登録する方法

<h2>症状</h2>
git remote addで誤ったリポジトリを設定してしまい、再度正しいリポジトリを記したコマンドをじっこうするもエラーが表示されてしまいました。

```terminal:ターミナル
#誤ったリポジトリを設定
git remote add origin https://github.com/ユーザー名/hogeh

#正しいものを再度入力するエラー
git remote add origin https://github.com/ユーザー名/hogehoge
fatal: remote origin already exists.
```

誤って登録してしまったリポジトリの確認を下記でしました。エラーが出ていたように2度目のコマンドではエラーが出ていたように　設定で上書きはされていないようです。


git -v
origin  https://github.com/ユーザー名/hogeh (fetch)
origin  https://github.com/ユーザー名/hogeh (push)
```

<h2>解決方法</h2>
「git remote rm origin」コマンドで登録したリポジトリを削除できました。

```terminal:ターミナル
git remote rm origin

#登録されているりぽじとりを確認するも何も表示されませんでした(登録が正常に取り消された)
git remote -v

#再度登録しなおしてして確認
git remote add origin https://github.com/ユーザー名/hogehoge

git remote -v
origin  https://github.com/ユーザー名/hogehoge (fetch)
origin  https://github.com/ユーザー名/hogehoge (push)
```
<h2>参考</h2>
git remote add を取り消す方法
https://qiita.com/ngtkk/items/05097d127db6a415a7d8
【エラー】loadイベントが読み込まれない問題【javascript】

## 原因
loadイベントを発火させる条件が、"/◯◯/new"と一致している場合としていた為（下記参照）、
renderメソッドでnewアクションを呼び出したことにより、URLが一致しなくなりイベント発火が起きなくなってしまった。

```javascript:menu.js
if (document.URL.match( "/menus/new" )) {
  window.addEventListener("load", 関数名);
}
```

## 解決方法
renderメソッドは使用せず、redirect_toを使用した。
但し、renderメソッドを使用できないとインスタンス変数に格納されているエラーメッセージを取り出すことができない。エラーメッセージを表示させる別の方法として、flashを用いた。

```ruby:menus_controller.rb
flash[:notice] = "料理が選択されていません" 
redirect_to new_menu_path
```
ビューファイルに、格納したエラーメッセージを表示させるように記述。

```ruby:new.html.erb
<%= flash[:notice] %>
```
UIActivityViewController を使うと画面が余計目に閉じてしまう問題を解決する

# はじめに

UIActivityViewControllerに関わるいろんなバグに悪戦苦闘しています。
今回は、その一つであるバグの回避方法を備忘録として書いていきます。

## UIActivityViewController を使うと画面が余計目に閉じてしまう問題

iOS13以降、UIActivityViewControllerを使用して画像を保存すると余計目に画面が勝手に閉じるバグが発生しました。

回避方法を調べる中で、UIActivityViewControllerが色々悪さをしていて(詳細は、以下の記事の通りです。)OSがバージョンアップする都度確認すべきかと感じます。早く色々改善してほしいですね。

 * UIActivityViewControllerには罠がある
 
 https://blog.sorausagi.org/2017/10/uiactivityviewcontroller.html?m=1
 

## 回避方法
閉じられる画面を予め用意して、閉じるタイミングでその画面を表示するhandlerを用意してあげると、どうにか回避されます。

```swift:ViewController.swift

// 現在、表示されている画面
private let activityWindow: UIWindow = {
    let window = UIWindow(frame: UIScreen.main.bounds)
    window.rootViewController = UIViewController()
    return window
}()

func shareAction() {

    // 保存する画像
    let image:[UIImage] = [UIImage(named:"sample")!]

    let vc = UIActivityViewController(activityItems: image, applicationActivities: nil)

    // 今ある画像を表示させるhandler
    vc.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
        UIApplication.shared.delegate?.window??.makeKeyAndVisible()
    }

    if #available(iOS 13.0, *) { // iOS13.0以上で発生するバグ
        activityWindow.makeKeyAndVisible()
        activityWindow.rootViewController?.present(vc, animated: true)
    } else {
        present(vc, animated: true)
    }
}
```

## 参考記事

参考にさせていただきました。ありがとうございます。

 * iOS 13 UIActivityViewController automatically present previous VC after image saving   
https://stackoverflow.com/questions/56903030/ios-13-uiactivityviewcontroller-automatically-present-previous-vc-after-image-sa/61032571#61032571
[Swift] 即時関数について

即時関数

現在ハンズオン形式でアプリ開発をしているのだが
理解不能なコードと遭遇した。
調べてみると即時関数を使用したコード。

原稿のコードがこれ

```swift
private var chatInputAccesoryView: ChatInputAccessaroyView = {
    let view = ChatInputAccessaroyView()
    view.frame = .init(x: 0, y: 0, width: view.frame.width, height: 100)
    return view
}

```

あるクラスをコンポーネントをクラスとして定義。
別のビューコントローラーでインスタンスを生成する。

わかりやすく書くとこうなる。

```swift
　　　　　　　 　　　　　　　）
private var chatInputAccesoryVie<--ただの変数-->　: ChatInputAccessaroyView<--クラス（型の宣言--> = {
    let view = ChatInputAccessaroyView() //インスタンスを生成　

    <--生成したオブジェクトのプロパティを変更->
    view.frame = .init(x: 0, y: 0, width: view.frame.width, height: 100)
    return view//戻り値
}

```
訳のわからないコードで騙されたが
private var chatInputAccesoryView: ChatInputAccessaroyViewは
private var hensuu:String
と意味合い的には変わらないただの変数の宣言である。

戻り値としてviewが変数chatInputAccesoryViewに格納される。
chatInputAccesoryViewの実態はプロパティが変更されたChatInputAccessaroyViewクラスの実体ということになる。

わかりやすくテストコードを書いてみた。

```swift
import UIKit

private var test: testclass{
    let x = testclass()
    x.a = 3
    return x
};()

class testclass{
    var a = 1
    func print(){
        Swift.print(a)
    }
}
print(test.a)

```
結果は3が出力される。

ここでの即時関数のメリットは
コードを簡潔にかけること。
オブジェクトのプロパティを自由に定義できる

これで合ってるのかは自分も初学者なのでわからないが...
動きさえ分かっていれば使う時に使えるようになればいいか！
phpでtry catch

phpで例外処理というものがあることを知った。

書き方：

```
try {
    // ロジック（処理）を記載

    //例外が発生したら例外を投げる
    throw new Exception();

} catch(Exception ex) {
    // 例外が渡ってくるところ
}

```

```
try{
   echo 111;
   throw new Exception();
}catch(Exception e){
   echo '捕捉した例外: ' . $e->getMessage()
}
```


こんな感じ。

いつ使うかというと、例外処理が行われるとき!!!!
わかりやすくいうと、
予期しないエラーや予期しない動作をした際に処理を中断して
catch()に処理が流れる。
かな。

try()の中での処理は普通は正常に動いてほしい。
しかし、途中でpcが落ちたりいろんな例外なことが起きた際に
try()の中の処理を無かったことに巻き戻しcatch()へ処理を流すもの。

例外がcatchされたら、try()を宣言する前まで処理が巻き戻される。

銀行のATMの例がわかりやすかったかな。
口座から100円引出したと思ったら、途中でATMが故障。
口座からは100円引かれているのに、手元には100円はない。

こういったことが起こらないように、try()の中は塊の1処理として扱い
エラーが起きたらcatch()へ処理が流れる。

その際に、getMessage()を使用するとほとんどの場合エラー内容が吐かれる。

```
try(){

  //100円を口座からマイナスする処理
  //     <-----ここでエラーが発生
  //100円をATMから出す処理

}catch(Exception e){
  echo $e->getMessage();
  //ここに飛んできたら、100円を口座からマイナスする処理は行われ無かったことになる
そして、エラーの原因が表示される。
}

```


参考：https://hara-chan.com/it/programming/php-try-catch/
Relatively_Simple_Algorithm(Writeup)

## 問題
https://2021.angstromctf.com/challenges

```python:src
from Crypto.Util.number import getStrongPrime
f = [REDACTED]
m = int.from_bytes(f,'big')
p = getStrongPrime(512)
q = getStrongPrime(512)
n = p*q
e = 65537
d = pow(e,-1,(p-1)*(q-1))
c = pow(m,e,n)
print("n =",n)
print("p =",p)
print("q =",q)
print("e =",e)
print("c =",c)
```
```txt:file
n = 113138904645172037883970365829067951997230612719077573521906183509830180342554841790268134999423971247602095979484887092205889453631416247856139838680189062511282674134361726455828113825651055263796576482555849771303361415911103661873954509376979834006775895197929252775133737380642752081153063469135950168223
p = 11556895667671057477200219387242513875610589005594481832449286005570409920461121505578566298354611080750154513073654150580136639937876904687126793459819369
q = 9789731420840260962289569924638041579833494812169162102854947552459243338614590024836083625245719375467053459789947717068410632082598060778090631475194567
e = 65537
c = 108644851584756918977851425216398363307810002101894230112870917234519516101802838576315116490794790271121303531868519534061050530562981420826020638383979983010271660175506402389504477695184339442431370630019572693659580322499801215041535132565595864123113626239232420183378765229045037108065155299178074809432

```

## 解法
RSAに関する問題。
p,qが漏れているので秘密鍵dを計算し、
cを復号する。

## コード
```python:solution
def int2bytes(x:int)->bytes:
    x_s = hex(x)[2:]
    if len(x_s) % 2 :
        x_s = "0" + x_s
    return bytes.fromhex(x_s)

d = pow(e, -1, (p-1)*(q-1))
m = pow(c, d, n)
print(int2bytes(m))

#output
#b'actf{old_but_still_good_well_at_least_until_quantum_computing}'
```
phpでPDOを用いた、データ取得など


PDOオブジェクトの作成後prepareメソッドでsqlをセットする。

```
$pdo = new PDO("mysql:dbname=test;host=localhost",USERNAME,PASSWORD);

$stmt = $pdo->prepare('select name from test where id= ? and num = ?');
```
 
その後、BindVlalueメソッドでパラメータをバインド（セット）する。
これを行うと、sqlで書いた[?]などに変数の値に置き換える処理です。
別説明：
予め記載しておいた疑問符やコロン付のラベルを、任意の値に置き換える処理です

```
$stmt->bindValue(1,2);
$stmt->bindValue(2,10);
```

これで、id には1が num には2が入る
idに2が入り、numには10が入る

bindを行いsqlの？に所定の値が入ったのであれば、実行する必要がある。
executeでクエリを実行します。

```
$stmt->execute();
```
ここで初めて、sqlが実行される。

```
$result = $stmt->fetch();
```
fetch()を使うと1件情報を取得する。
そのほかにも、
fetchAll() を使うと、複数件の情報が取得できる。

```
$stmt = $pdo->query("select name from test where id = 1");
```
queryメソッドを使うと、手軽にsqlを書くことができます。
しかし、エスケープ処理を行わないので、
queryメソッドのクエリにパラメータを渡す時は自分で書く必要があります。
エスケープ処理とは、
キーボードでは入力されない、¥や\nのような改行などを示す 文字列を出力させる処理のこと。



参考： https://bituse.info/php/37
クラウドプラクティショナー合格したのでその感想とメモ

#概要

AWSのクラウドプラクティショナーに合格したので、記憶の鮮度が高いうちに感想を書いていこうと思います。


#自分のレベル
・実務未経験
・個人開発で少しAWS触った程度

少し触ったことあるからイケるやろ！と未経験のくせに強気なマインドだったので
試験日の二日前までほとんど勉強しなかった結果、`719点`とかなりギリギリの結果でした(合格点は700点)。

設問は全65問なんですが、うち30問くらいは自信がなかったので（12000円無駄にしたかな。。）と思いながら受けていました。

#使った教材

###書籍
[徹底攻略 AWS認定 ソリューションアーキテクト](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E2%80%93-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8/dp/4295005495/ref=pd_ybh_a_1?_encoding=UTF8&psc=1&refRID=MF4WTVYWJRT0S37SND2Y)

いわゆる黒本です。
元々クラウドプラクティショナーではなくソリューションアーキテクトアソシエイトを受けるつもりだったので
この教材を使用していましたが、`辞書`のように使っていました。

単語の意味を忘れてしまった時に索引から用語を調べる際に使っていました。


###動画教材
####Black Belt Online Seminor
https://www.youtube.com/playlist?list=PLzWGOASvSx6FIwIC2X1nObr1KcMCBBlqY

AWS JPの公式YouTubeチャンネルです。

自信のないサービスを1.75倍速にしてメモしながら見ていました。
網羅的に教えてくれるので効率的に学ぶことができました。

↓下の記事でどの動画を見れば良いのかまとめてくれてました。
[2回受験して得たAWS認定ソリューションアーキテクト(SAA)の教訓](https://dev.classmethod.jp/articles/lesson-of-aws-certification-saa-taking-2-times/)


####Udemy
https://www.udemy.com/course/aws-4260/

模擬試験です。

*解く→間違えたところを黒本、Black Beltで調べる→ノートに箇条書きする*

を繰り返しやっていました。
基礎レベルを80%、応用レベル55%くらいの実力で試験当日を迎えました。
ですので確実に受かりたい方は応用レベルも70％取れるようになっておいた方がよさそうです。

#まとめ
簡単だと聞いて舐めてかかったら割とギリギリだったので次からはもっと対策していきたいと思います。
z88dkの始め方(PC-80版)

#セットアップ
先ずは
[z88dkの始め方](https://qiita.com/Stosstruppe/items/02f8f2bf650b20c22c16)
[z88dkの始め方(PC-88版)](https://qiita.com/Stosstruppe/items/8785b7a2795316150bdb)
を参考にz88dkをセットアップする。

* z88dkディレクトリ例）C:\etc\z88dk
* 開発用ディレクトリ例）C:\Projects\z88dk

#定義ファイルの用意
PC-80用の定義ファイルは無いのでPC-88用を流用。
printfなどのCライブラリ関数は使用できないので、全て自前で用意する必要がある。

`C:\etc\z88dk\lib\config\pc88.cfg`をコピーして編集。
`-Cz+pc88`はappmakeで`.t88`ファイルを作る指定。

```pc80.cfg
#
# Target configuration file for z88dk
#

# Asm file which contains the startup code (without suffix)
CRT0		 DESTDIR\lib\target\pc80\classic\pc80_crt0

# Any default options you want - these are options to zcc which are fed
# through to compiler, assembler etc as necessary
#OPTIONS		 -O2 -SO2 -iquote. -DZ80 -DPC88 -D__PC88__ -M  -Cc-standard-escape-chars -clib=default -subtype=default
OPTIONS		-O2 -SO2 -iquote. -DZ80 -M -Cc-standard-escape-chars -clib=default -subtype=default

#CLIB		default -lpc88_clib -lndos
CLIB		default -lndos

#SUBTYPE		default -Cz+pc88 -startup=1
SUBTYPE		default -Cz+pc88
```

`C:\etc\z88dk\lib\target\pc88`をディレクトリごとコピーして`pc80`に改名し、以下のように編集。

```classic\pc80_crt0.asm
        EXTERN  _main
        INCLUDE	"target/pc80/classic/monitor.asm"
```

```classic\monitor.asm
        IFNDEF CRT_ORG_CODE
            defc CRT_ORG_CODE  = $8A00
        ENDIF

        org CRT_ORG_CODE

start:
        call    _main
        jp      $5c66
```

#Cプログラムのビルド
開発用ディレクトリに以下のファイルを用意する。

* 開発用バッチファイル

```dev.bat
@echo off
path %path%;C:\etc\z88dk\bin
set ZCCCFG=C:\etc\z88dk\lib\config
cmd
```

* サンプルプログラム

```sample.c
//zcc +pc80 -compiler=sdcc sample.c -create-app

void putc(char x) __z88dk_fastcall __naked
{
__asm
	ld	a,l
	rst	18h
	ret
__endasm;
}

void main()
{
	int i;

	for (i = 0; i < 10; i++) {
		putc(0x30 + i);
	}
}
```

開発用バッチファイルを起動し、以下のコマンドを実行すると`a.t88`ファイルが作られる。

```
zcc +pc80 -compiler=sdcc sample.c -create-app
```

#X88000での実行例
N-BASICモードで起動。
メニューから「イメージ」→「テープイメージ」を選択し、`a.t88`ファイルを開く。
機械語モニタの`L`コマンドで読み込み`G8A00`で実行。
エントリポイントはデフォルトで`8A00`。
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257554/48f9e71e-9bd6-da86-9ac6-4c2b69453566.png)

#PasocomMini PC-8001での実行例

操作方法は
[PasocomMini PC-8001 │ パソコンミニ公式ウェブサイト](https://www.pcmini.jp/manual/pc-8001-manual/)
を参照。

microSDカードの`CONVERT`ディレクトリに`a.t88`ファイルをコピーする。
PasocomMini PC-8001を起動しF9キーでメニューを表示、CONVERTタブで`a.t88`ファイルを変換する。
MEDIAタブで`a.t88.cmt`を選択、セットする。
後はエミュレータと同様。
F10キー長押しでShutdownメニュー。
IBM Cloud上のGitLabのレポジトリを作成する

IBM Cloud上のContinous DeliveryのサービスにはGitLabが含まれています。本来はpipelineなどと組み合わせたツールチェーンとして利用することを想定したものですが、GitLab単体でも利用できます。
ライトプランでも、容量制限はありますが利用できます。


#Continuous Deliveryのサービス作成
カタログからContinuous Deliveryを選んで、お好きなロケーションで（ここではシドニー）作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6a40f102-8987-9108-06b7-05ce04b4d1ce.png)

作成されたらDevOpsのメニューを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b6e6efcd-49cb-245b-b629-e74e366aadb1.png)

#ツールチェーンの作成
今回はGitLabが欲しいだけなのでツールチェーンといってもGitLab一つのツールしか使わないのですが、サービスをつくったロケーションでツールチェーンを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9843001e-089d-b3ea-b555-3e4d7c742284.png)

Build your own ツールチェーンを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6aa01ba5-b728-ff6f-874b-8c18de84dfcd.png)

任意の名前を付けて作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/530575ca-9472-cfa7-4f9c-f39272a519be.png)

#GitLabの追加
ツールとしてGitLabを追加します。

ツールを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6ae4e9e6-11b4-a787-e6e9-f70326780afb.png)

GitリポジトリーおよびIssueトラッキングを選びます。これはIBM Cloud上のGitLabのサーバーになります。このタイルの下にあるGitLabはGitLab社のサービスに接続するものなので別物です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/86d440f9-d6fd-70be-8808-e8bdc55796ed.png)

任意のレポジトリ名を入れて「統合の作成」ボタンで作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0ac3b24b-b9d2-fdee-6644-e4543899dc05.png)

作成されたGitLaｂのアイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2387bc79-000d-36ba-1ff3-7c5bc31f39ae.png)

以下のようにGitLabにプロジェクトが作成されています。
後は通常のGitLabとして使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4f1dc91b-05f3-2523-0ffa-2c0e7b6d24a7.png)



なお、他にもツールチェーンと紐づけない別のプロジェクトが作りたい場合はYour Projectから作れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7dde5b90-d64f-5fda-d664-1cba694de421.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f1ec85e7-b09b-3aa1-f2b4-00923d88df81.png)

#作成したGitLabへのアクセス
GitLabのプロジェクトのページはIBM Cloudのメニュー外になるので、次からのアクセスを簡単にできるようにブラウザにプロジェクトページや、以下のGitLabのダッシュボードページ（以下の例はシドニー用）をブックマークをしておくことをお勧めします。
https://au-syd.git.cloud.ibm.com/dashboard/projects

IBM Cloudのホームからたどる場合には、メニューからDevOpsを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b233a21f-acf8-dabf-4a6f-376ac1cc4fb0.png)

サービスをつくったロケーションのツールチェーンでGitLabのアイコンをクリックするとプロジェクトに飛ぶことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cf522c31-798b-23c7-2677-4cec071e05b0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/34a8b4c6-b628-603d-c172-913ff127ab3b.png)

#参考
Git Repos and Issue Tracking
https://cloud.ibm.com/docs/ContinuousDelivery?topic=ContinuousDelivery-git_working&locale=ja

https://qiita.com/makaishi2/items/03700915f335ea6ac137
【AWS】AWSアカウントを作ったら最初にやるべき4つのこと

#プログラミング勉強日記
2021年4月8日

#AWSアカウントを作ったら最初にやるべきこと
　AWSアカウントを作ったらまず最初に、認証上のセキュリティを高める必要がある。そのためにこれから紹介する4つのことを行う必要がある。

##1. 多要素認証(MFA)を有効化する
　MFAは、メールアドレス(ログインID)とパスワードの認証に加えてもう1つの認証を組み合わせてログインすることをいう。もう1つの認証方法は、ユーザのスマートフォンからのコードや秘密の質問の答え、指紋・顔認証などである。
　MFAはセキュリティ強化を実現する有効な方法であり、MFAを有効化するべきである。

　私の場合はiPhoneにGoogle Authenticatorをインストールして認証を行った。
　[こちらの記事](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)に詳しく書いてあるので、やり方を知りたい人はぜひ見てください。

##2. 管理者用のIAMユーザーを作成する
　最初にクレジットカード情報が登録されているメールアドレスでログインするユーザーはルートユーザー(ルートアカウント)である。そのルートユーザーとは別に操作用のIAMユーザー(読み方：「アイアムユーザー」)を追加することができる。AWSの基本操作はIAMユーザーで利用することが求められる。組織的にAWSを使うのであれば、IAMユーザーを使うのが基本。

　ルートユーザであってもAdminstratorAccess権限を付与することはできる。また、AdminstratorAccess権限のないユーザーであっても、権限のあるグループに所属すればそのIAMユーザーにも権限がつく。

##3. AWS CloudTrailを有効化する
　CloudTrailによってユーザーのアクセスログを取得・監視すること、APIコールやユーザーのサインアクティビティを記録することができる。
　ルートアカウントとIAMユーザーのサインアクティビティとAPIコールをトラッキングしてログを取得することができる。また、CloudTrailログファイルは暗号化されていてS3に保存される。KMSによる暗号化もサポートされていて、デフォルトでは90日間ログが保存される。これらのサービスが基本的には無料で使用できる。

##4. AWSの請求アラートを有効化する
　請求アラートを設定することで、利用額が一定額を超過した場合に通知が来るようにできる。

#参考文献
[多要素認証(MFA)とは何でしょう？](https://www.onelogin.com/jp/learn/what-is-mfa)
Rails 親id1番の孫データを全件取得する方法

#はじめに
以下のように企業⇒従業員⇒予定の親子孫関係がある際に、
企業IDが1番の従業員が作成した予定を、全件取得する方法について記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1106668/3fa02bab-6b6b-f9fb-c6c8-738b41efaa8c.png)

#条件
モデルの関連付けは以下のようになっています。

```ruby
class Company < ApplicationRecord
  has_many :employees

class Employee < ApplicationRecord
  belongs_to :company
  has_many :schedules

class Schedule < ApplicationRecord
  belongs_to :employee
```

#結論
以下記述で取得可能となります。

```ruby:SchedulesController
@schedules = Schedule.where(employee_id: Company.find(1).employees.ids)
```

#内容
まず、companyのid1番のデータをfindメソッドを使用し取得します

```ruby
Company.find(1)
```
取得したものに対し、.employees.idsを行うことで、
企業IDが1番の従業員IDの番号を、配列の形式で得ることが可能になります。

```ruby
Company.find(1).employees.ids 
# 例）[2, 3, 4, 5, 6, 7]
```
その配列を用いてScheduleモデルにwhereメソッドを使用すると、
企業IDが1番の従業員が作成した予定を、全件取得する事ができます。

```ruby
Schedule.where(employee_id: Company.find(1).employees.ids)
```
[JS] Pace JS


##Pace JS

ページローダーのJavaScriptライブラリ

####Font Stack
font-family: 'Helvetica Neue', 'Yu Gothic', 'Meiryo', sans-serif;

最初に記述されているfontから順に、PCにインストールされているfontを探しに行って、
見つかった段階でそのfontを使用するという仕組み
AWS ElasticBeanstalk デプロイオプション

#【AWS ElasticBeanstalk デプロイオプション】

##デプロイオプション

###All at once

新しいバージョンをすべてのインスタンスに同時に展開
環境内のすべてのインスタンスは、展開が行われている間、短時間サービスが停止する。
　→　展開に必要な合計時間を最短にする。

###Rolling

ローリングデプロイ中は、アプリケーションの古いバージョンでリクエストを処理するインスタンスと新しいバージョンでリクエストを処理するインスタンスが存在する。

###Rolling with additional batch

新しいバージョンをバッチで展開する。
しかし、最初にインスタンスの新しいバッチを起動し、展開プロセス中に完全な容量を確保する。

###Immutable

変更不可能な更新を実行して、古いバージョンを起動しているインスタンスと並行して、別のAuto Scalingグループの新しいバージョンのアプリケーションを起動している新しいインスタンスのフルセットを起動する。
　→　部分的に完了したローリングデプロイにより発生する問題を防止する。
【Python】WEBサイトへ自動ログイン

####Pixivへ自動ログインするプログラムの制作
WEBスクレイピングをやりたくてPythonの勉強をはじめました。
初心者なのでお手柔らかにお願いします。



#動作環境
- macOS Catalina-ver10.15.7
- Python 3.8.5
- JupyterLab
- ChromeDriver 89.0.4389.23

JupyterLabのNotebookで動作を確認しながらコードをかきます。

##使用ライブラリ：selenium、pandas
ターミナルよりpipでseleniumをインストール。
pandasはcondaで既にインストール済みのものを使用。

```python:code0

#!/usr/bin/env python
# coding: utf-8

from selenium import webdriver
import time
import pandas as pd
```
##1、Chromeを起動してログインページへ移動
homebrewというパッケージマネージャを使用して、ChromeDriverをインストール。
これでGoogle Chromeで自動操作ができるようになる。

```py:code1

USER = "AAA"
PASS = "AAA"

# GoogleChromeを起動
browser = webdriver.Chrome()
browser.implicitly_wait(3)

# ログインページするサイトへアクセス
url_login = "https://accounts.pixiv.net/login"
browser.get(url_login)
time.sleep(2)
print("ログインページにアクセスしました")

```
##2、ログイン情報の入力
IDやPASS情報を入力するボックスにユニークなHTMLタグがついていないため、
デベロッパーツールからXPathを取得。
テキストボックスを空にする為に一応 `element.clear()` を入れておく。
情報が入ったので、ログインボタンまで押してもらう。
######これで自動ログインが完了:grinning:

```py:code2

# ログイン情報を入力
element = browser.find_element_by_xpath('//*[@id="LoginComponent"]/form/div[1]/div[1]/input');
element.clear()
element.send_keys(USER)
element = browser.find_element_by_xpath('//*[@id="LoginComponent"]/form/div[1]/div[2]/input');
element.clear()
element.send_keys(PASS)
print("フォームを送信")

#　ログインボタンを押下
browser_from = browser.find_element_by_xpath('//*[@id="LoginComponent"]/form/button')
time.sleep(3)
browser_from.click()
print("ログインボタンを押しました")
```

#参考
キノコードさんのWEBスクレイピング講座を元に作成しました。

https://youtu.be/LgZ8Li97yoM
AWS X-Ray

#【AWS X-Ray】

## AWS X-Ray

AWS Lambdaアプリケーションにおけるパフォーマンスの問題で検出、分析、最適化を実行できる。

Lambdaサービスおよびアプリケーションを構成する全てのアップストリームやダウンストリームサービスからメタデータを収集する。
　→　Lambdaアプリケーションのパフォーマンスに影響を及ぼす問題を示す詳細なグラフを示す。

##X-Rayを使用する時に考慮すること。

・**サブセグメントを作成して、AWSサービスとAWS SDK で作成するリソースへの呼び出しを記録**

内部、外部のHTTPウェブAPIへの呼び出しやデータベースクエリの呼び出しの記録もできる。
アプリケーション上のコードをデバッグしたり、注釈を付与したりすることも可能

・**メタデータオブジェクト、セグメントに保存する追加のカスタムデータを設定**

メタデータのインデックスを作成せずに、セグメントドキュメントが最大サイズ(64KB)を超えない限り、値は任意のサイズが可能
BatchGetTracesAPIによって返された完全なセグメントドキュメントであり、メタデータを表示できる。
Nuxt.jsで開発したWebAPPにXMLサイトマップを設定する

#XMLサイトマップがいかに重要か


そもそも、XMLサイトマップとは何か？

サイトマップは、WEBサイトにどんな情報があるのかを伝える「目次」のような役割をしていると理解していただければ良いでしょう。
XMLサイトマップは、検索エンジンに対してページの情報を伝える役割があります。

XMLサイトマップを設定するメリットを解説します。

**1. URLの存在をクローラーに早く検知させる**
**2. クローラーが検知できないページを知らせる**

この2つが主なメリットで、要はSEOに関して欠かせないものです。


##1. パッケージのインストール

プロジェクトのルートディレクトリにて下記コマンドを実行し、パッケージをインストールする。

```
# サイトマップ用パッケージ
$ npm install @nuxtjs/sitemap
```

##2. nuxt.config.js設定を追加する

インストールができたらnuxt.config.jsの設定をしていきます。
まずはmodulesに追加

```ruby:nuxt.config.js
export default {
    ,,,
    modules: [
        '@nuxtjs/sitemap'
    ]
    ,,,
}
```

次にsitemapの設定をしていきます。
例として、下記のように設定にしました。

```ruby:nuxt.config.js
export default {
    ,,,
    sitemap: {
        hostname: 'https://www.example.com',
        path: '/sitemap.xml',
        cacheTime: 1000 * 60 * 15,
        gzip: true,
        exclude: [
          '/admin',
          '/admin/**',
          '/works/**'
        ]
    }
    ,,,
}
```

##3. 各パラメータの説明

####hostname
サイトマップを置くサイトのルートドメインを設置する
generateオプションでdirを変更していなければ、distフォルダの中に生成される。

####path
サイトマップを生成する場所とファイル名を設定する

####cacheTime
サイトマップの更新頻度を設定する。

####gzip
gzip形式のsitemapを生成するかどうか

####exclude
サイトマップから除外するディレクトリの設定
/**を付けると、そのディレクトリ下を除外することが可能
管理者ページなどがある場合に使用する。

####routes
サイトマップに含めるURLの設定
動的ルーティングにて生成されるページ等。（これはまた今度！）

##5. 最後に
[link-1]:https://search.google.com/search-console/about?hl=ja

サイトマップを作ってもロボットにクロールさせないと意味がありません。
**いくら素晴らしいページでも、クローラーに見てもらい、インデックスをされなければ、検索エンジンの結果に出てこず、そのページが存在しないのと同じです。**
本番でのsitemap.xmlが生成完了していれば、**[Googleサーチコンソール][link-1]**からサイトマップを送信しましょう！