OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonのクロージャの仕組み

## はじめに　
　Pythonのクロージャを勉強していて、

```python
def outer():
    x = 0
    def inner():
        print(x)

    return inner   

func = outer()
func() # -> 0
func() # -> 0
```

というコードを見たとき、func()を呼び出した時になぜ変数xを用いることができるのか疑問に思ったので調べてみました。

## Pythonでのメモリ管理
　Pythonでは、参照カウンタという方法を用いてメモリ管理を行っています。
それぞれのオブジェクトは、いくつの変数から参照されているかという情報を持っていて、その値が0になる（＝どの変数からも参照されていない）といずれ破棄されます。
　ということは、関数outer()の実行が終了しても変数xがfunc()内で使えるということは、func()内では何らかの方法でxを参照していると考えられます。そこで、どのように参照しているかを調べていきます。

## 関数オブジェクト 
　Pythonでは関数もオブジェクトであり、複数の属性を持っています。属性の種類については以下の通りになります。

```python
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
```
　この中で、\_\_closure\_\_属性の意味を見てみます。Python公式ドキュメントからの引用を示します。

> None または関数の個々の自由変数 (引数以外の変数) に対して値を束縛しているセル (cell) 群からなるタプルになります。 
>

　よってセルを通して外側の関数中のオブジェクトは参照されるので、外側の関数の実行が終了してもオブジェクトは破棄されず、そのオブジェクトをクロージャから使うことができるといえそうです。

## プログラムを実行して確かめてみる
ここで、以下のプログラムを実行して\_\_closure\_\_属性の値を見てみます。

```python
def outer():
    x, y, z = 0, 1, 2
    print('xのメモリ番地: ', hex(id(x)))
    print('yのメモリ番地: ', hex(id(y)))

    def inner():
        print('x = ', x)
        print('y = ', y)
    
    return inner


print("outer関数のclosure属性: ", outer.__closure__)


c_inner = outer()
c_inner()

cells_obj = c_inner.__closure__

print('c_inner関数のclosure属性: ', cells_obj)


'''
実行結果

outer関数のclosure属性:  None
xのメモリ番地:  0x10c40eaa0
yのメモリ番地:  0x10c40eac0
x =  0
y =  1
c_inner関数のclosure属性:  (<cell at 0x7fdb18097fd0: int object at 0x10c40eaa0>, <cell at 0x7fdb180d6040: int object at 0x10c40eac0>)
'''
```
　c_inner関数のclosure属性をみると、セルオブジェクトが存在するメモリ番地と、整数オブジェクトのメモリ番地が表示されています。実行結果の2、3行目と比較すると、x、 yのメモリ番地と等しいことがわかります。
　よって、セルオブジェクトはクロージャが用いるオブジェクトのメモリ番地を保持していて、クロージャはセルオブジェクトを介して間接的に外側のオブジェクトを参照しているといえます。
　
## 参考文献
https://docs.python.org/ja/3/reference/datamodel.html#objects-values-and-types
PHP+MySQLでポートフォリオ作成

#記事の概要#
私が作成したポートフォリオを紹介します。



#背景#
現在、30歳、プログラミング未経験からエンジニアを目指し勉強しています。
フロントエンドエンジニアを目指していますが、バックの知識も少しは必要だということで、勉強中のPHPでポートフォリオを作成しました。



#目的#
・PHPを用いたWebアプリケーション開発経験を積む
・フルスクラッチ開発によってWebアプリの基本的な構成、動作を知る
・Web系企業さんの即戦力になれる技術を身につける(そこまでは厳しかった)



#スペック#
**言語**
PHP 7.4.6

**DBMS**
MySQL 8.0.21

**開発環境**
MacOS Catalina 10.15.6
MAMP



#主な内容#
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/hvVJEFGYzZ">pic.twitter.com/hvVJEFGYzZ</a></p>&mdash; ポートフォリオ用 (@AO88IvXNahycCKv) <a href="https://twitter.com/AO88IvXNahycCKv/status/1300107979056771072?ref_src=twsrc%5Etfw">August 30, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


架空のスニーカーのフリマサイトです。

生のPHPを書くことが目的だったので、
細かいデザインまではこだわっていません。

また本来は商品一覧ページ、出品ページ、マイページなど作成したかったのですが、
一旦、ユーザー登録までとなっております。

DB接続を行い、マイページ遷移や、簡単なバリデーションまで実装。

※セッションを使ったマイページ画面や、連絡掲示板なども作成したかったのですが、
まだ勉強中なので、簡単なPOST送信までで作成しました。



#課題#
**HTML,CSSのコーディング**
とりあえず書くことはできるというレベル。
とりあえずでdivタグで囲ったり、
とりあえずclass付けたり、
class名の一貫性、妥当性、またidは全く使っていないので、
そういった基本的なルールをまだまだ学ぶ必要あり。


**DB接続**
PDO使って、SQL実行して、といった流れはわかるが
コード一つ一つの意味（そもそもPDOとは？）など理解せずに書いてる部分多いので
きちんと理解したい。


#GitHub#
https://github.com/yusuke355/php-portfolio
放置してたGCPを復活させる（６）- nginxインストールとhttp設定 -

GCP復活の作業履歴
[放置してたGCPを復活させる（１）- プロジェクト作成 -](https://qiita.com/3S_Laboo/items/62322280d1844d461bab)
[放置してたGCPを復活させる（２）- VMインスタンス作成 -](https://qiita.com/3S_Laboo/items/03b54621479e193101f7)
[放置してたGCPを復活させる（３）- gcloud CLIインストール -](https://qiita.com/3S_Laboo/items/75682b3d008d0fdce355)
[放置してたGCPを復活させる（４）- PC(Windows10)からVMにssh接続 -](https://qiita.com/3S_Laboo/items/63a17738071a171decb1)
[放置してたGCPを復活させる（５）- VMのIPを固定する -](https://qiita.com/3S_Laboo/items/c897628aec6d04f4fe5f)
[今回：放置してたGCPを復活させる（６）- nginxインストールとhttp設定 -](https://qiita.com/3S_Laboo/items/9a8446f84baa80252cb9)
[放置してたGCPを復活させる（終わり）- 独自ドメインの設定 -](https://qiita.com/3S_Laboo/items/cce944d49cbd1d4aa745)

そろそろ我がGCP VMが復活しだしたのでnginxでも入れてみよう。

# 情報収集
[WEBサーバ「nginx」をインストール[GCE]](https://sbc-web.hatenablog.jp/entry/2017/04/23/WEB%E3%82%B5%E3%83%BC%E3%83%90%E3%80%8CNginx%E3%80%8D%E3%82%92GCM%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

# yumを使ってnginxをインストール
以下コマンドを実施
```sudo yum install nginx```
完了
バージョン確認
```nginx -v```
自動起動を有効化
```sudo chkconfig --level 3 nginx on```
サービス開始
```sudo service nginx start```
![2020-08-31_01h21_16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/7da4f52a-ea6a-57e8-5840-6dcfc439f815.jpeg)
これでアクセスできるかと思ったらできない。。。
# ファイアウォール
![2020-08-31_01h24_19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/375e1adf-aeb8-20f8-222c-e9f5156ec0e9.jpeg)
# 接続
![2020-08-31_01h29_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/a8b5f73b-45f7-77e0-39bb-1cd507fa62f8.jpeg)
イエイ！
今回はここまで。
ありがとうございました。
次回
[放置してたGCPを復活させる（終わり）- 独自ドメインの設定 -](https://qiita.com/3S_Laboo/items/cce944d49cbd1d4aa745)
React NativeのFlatListのdataに型エラーが出ているとき

## はじめに
dataにデータを渡してアプリでも問題なく動いていることを確認してふとみるとdataに赤線が。
どうやら型エラーが出ているようなので、とりあえずググるもみんなrenderItemについての
ことばっかりだったので、解決法を残しておく。

## 結論
型データに配列宣言が足りない

## 今回の事例
dataという大本に、characterというデータがある
characterの中にはstatusというデータがある
そして、FlatListで、characterの数だけ表示したい

~~~typescript
const characters = useSelector((state: State) => state.data.characters);
<FlatList
  data={characters}
  renderItem={({ item }) => (
    <ListContents
      なんかいろいろ
    />
  )}
  keyExtractor={(item, index) => index.toString()}
/>
~~~

そして、このdataに型エラーがでていた。
どうやら配列でいれろとのこと。
しかし、console.logでデータを見てもちゃんと配列が入っている。
はて？

## 型宣言の間違い
Character型の宣言(Status型が別ファイルに設定されています）

~~~typescript
import { Status } from './status';

export type Characters = {
  status: Status;
};
~~~

Data型の宣言

~~~typescript
import { Characters } from './characters';

export type Data = {
  characters: Characters;
};
~~~

おそらく、このあたりに間違いがあるとみていろいろ試した結果、これが正しかった

~~~typescript
import { Characters } from './characters';

export type Data = {
  characters: Characters[];   // ←ここでcharacterの配列宣言をする
};
~~~

要は、「Data型は複数のCharacterを持つから、配列宣言をしておく」ということらしい。
これが、変更前は「Data型はひとつのCharacterを持つ」という宣言のはずが、FlatListの
dataに入れていたため、そもそも複数ならば配列を入れよ、ということみたい。
これがJSだったら気付かずそのままだったけど、TSのおかげで本当の正しい形が分かったのは
よかったけどたどり着くのに地味に時間がかかった。。
swiftUIのpickerを動的に書き換える技

環境 xcode11.6
swiftUI

あまり日本語でこの問題に関して言及する記事がなかったので書いてみました。

Pickerに表示したい要素をarrayで定義しておいてForEachで動的に表示したいことってありますよね？うん？
ただ、動的にarrayの要素を削除したりしてpcikerを動かそうとすると
`Fatal error: Index out of range`
となります。
なぜなら、pickerはそのなかのarrayが変化したことを検知できないのです！！
なので、検知させましょう。
ということで、方法は下記のようにPickerに`.id()`を追加します。

```swift
Picker(selection: selectd, label: Text("文字色")) {
                ForEach(0..<array.count, id: \.self){ id in
                    self.array[id]
                        .tag(self.array[id])
                }
            }
            .id(self.uuid)
```

こうすると、idの引数に渡したself.uuidが更新されたときに、pickerがreloadされて動的に削除したり追加した要素を正しく反映できます。
ちなみに、Pickerのselectionにわたすselectedは、下記のようにカスタムBindingを用意して、setされたらuuidを更新するようにしたりすればいいでしょう。

```swift
let selectd = Binding(
            get: {  },
            set: {
                self.uuid = UUID()
            }
        )
```

こうしてまた迷えるswiftUIエンジニアを救ってしまった。

あ、参考情報はこちらです。

まさにこれで解決できました。
https://stackoverflow.com/questions/60082411/swiftui-hierarchical-picker-with-dynamic-data-crashes

カスタムバインディングについて。
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-custom-bindings
CDN 版の Vue.js でコンポーネントを別ファイルに分けたい。できるだけ簡単に。

# はじめに
Vue.js の学習をするにあたって、最小構成の環境で進めていくにはどうすればいいかを考えたときのメモ書きです。

# コンポーネントファイルを切り出したい
.vue ファイルのようにコンポーネントのファイルを別で定義していくと、学習した内容を分かりやすく管理できる、と思ったのですが、**.vue ファイルを使うには webpacker が必須**ということが分かりました。webpacker は使わず、できるだけシンプルな状態で Vue.js を触りたい…。そこで **script タグで読み込むことで簡易的にファイルを切り出す**ことにしました。

```
vue-sample/
　├ index.html
　├ main.js
　└ sample-comonent.js
```

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue Sample</title>
</head>
<body>
  <div id="app">
    <sample-component/>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- コンポーネントから読み込まないと上手くいかない -->
  <script src="sample-component.js"></script>
  <script src="main.js"></script>
</body>
</html>
```

```main.js
new Vue({
  el: '#app'
})
```

```sample-component.js
Vue.component('sample-component', {
  template: '<p>this is sample component</p>'
})
```

学習やサンプル程度のコードならこれで十分進めていけると思います。
JSSEC AndroidセキュアコーディングガイドにおけるAndroidManifest.xmlの書き方

# JSSEC AndroidセキュアコーディングガイドにおけるAndroidManifest.xmlの書き方

## 概要
一般社団法人日本スマートフォンセキュリティ協会（JSSEC）発行の[「Androidアプリのセキュア設計・セキュアコーディングガイド」](https://www.jssec.org/dl/android_securecoding/index.html)を基準に、
セキュリティ調査する機会があったため、記事にしてみました。

今回はまず見るであろう、
AndroidManifest.xmlに焦点を絞っていきたいと思います。

お題目としては、以下の様になります。
1. 各コンポーネントの公開設定
1. 使用権限の定義

## 想定している対象者
* Androidの基本コンポーネント・権限については理解したので、これからセキュリティ観点についても理解を深めていきたい方

## 本題

### 各コンポーネントの公開設定

新しくコンポーネントを増やす場合は、以下に注意。
* 追加したコンポーネントごとにexported属性が明示的に指定する
* 非公開となっているコンポーネントに、intent-filterを定義しない

AndroidManifest.xmlによっては、
「非公開のつもりだったけど、公開で別アプリから起動出来る状態になっていた」ということがありえるので、
書き方には、十分気をつける必要があります。

セキュアコーディングガイドでいうと、[こちら](https://www.jssec.org/dl/android_securecoding/4_using_technology_in_a_safe_way.html#exported-%E8%A8%AD%E5%AE%9A%E3%81%A8intent-filter%E8%A8%AD%E5%AE%9A%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B_x28activity%E3%81%AE%E5%A0%B4%E5%90%88_x29)の内容となります。

### 使用権限の定義
新しく権限を追加する場合、
これから新しく使用する製品には、以下の様な対策をすると良いと思いました。
* xml上でのなぜ追加したか、コメントを記載
* git blameで管理出来る様に、コメントで利用用途を追える様にしておく。

歴史の長い製品なんかだと、かなり昔に宣言されたものの実際は使用していないなんてことはよくあると思います・・
(自分も今回チケット、コミットログを掘り続けることになりました・・)

個人的には、git logが伸びてくると追うのが辛いので、コメントで管理しておくのがベストかなと思います。

権限については、実装上でも注意点多いので、セキュアコーディングガイドでいうと、[こちら](https://www.jssec.org/dl/android_securecoding/5_how_to_use_security_functions.html#permission%E3%81%A8protection-level)や公式資料をよく見ておく必要があると思います。

## まとめ
慣れない内は、定期的に上記コーディングガイドを定期的に見直す習慣をつけると良さそうと思いました。

今回は本当に触りについてしか触れていないので、他の内容については、また触れたいと思います。
10ホールハーモニカの楽譜もどきを作成するPGM

<h3> 10ホールハーモニカの楽譜もどきを作成するPGM </h3>
<hr>
10ホールハーモニカの楽譜もどきを作成するプログラムを作成しました。
作成した楽譜ファイルはスクリプト内からインポートして読み出すことが可能です。

各記号の意味は以下のように設定してあります。
ただの数値：吐いて音を出す場所
丸文字の数値：吸って音を出す場所
↓と数値：ベンドとどれだけ下げるか
+：その分だけ音を長く出す
zkf, 2kf, 4kf, 8kf, 16kf:それぞれの休符
tempo:音の速さ

楽譜は一段ずつ登録していき、一番下のファイル出力ボタンで
一連の登録した行が出力されます。

<hr>
githubURL: https://github.com/NanjoMiyako/10hpGakufu
サンプルページURL: https://nanjomiyako.github.io/10hpGakufu/

<hr>
スクリーンショット
![image1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/f2669d4b-23a6-e5bb-77a0-71414ac0a25e.jpeg)

<hr>
参考にしたサイト
<a href="https://qiita.com/DecoratedKnight/items/103ab57431b6c448e535">特定の文字列を全て置換する[Javascript] - Qiita</a>
<a href="https://murashun.jp/blog/20191110-18.html">JavaScript - 配列の要素を削除する | murashun.jp</a>
<a href="https://techacademy.jp/magazine/28206">JavaScriptで文字列をファイル出力する方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン</a>
<a href="https://developer.mozilla.org/ja/docs/Web/API/Blob/Blob">Blob() - Web API | MDN</a>
これから学ぶ言語について

HTML <Hypertext Markup Language>
・ウェブページを作成するために開発されたマークアップ言語　<プログラミング言語とは違う>
＊他のマークアップ言語　SGML　XML
・基本的に、「タイトル」「見出し」「段落」などの要素から構造化
・HTMLには「HTML」「XHTML」「HTML5」など、いくつか種類があり、使えるタグに違いがある

<身近なHTMLの使用例>
　⑴ウェブサイト
　⑵電子メール（HTML形式）
　⑶スマホアプリ

CSS<Cascading Style Sheets>
・構造化された文章のデザインを変更する言語＝スタイルシート言語
・文字の太さ、色の変更、背景色の変更、余白の調整などを行う
・CSSはHTML＜＝マーク言語＞と組み合わせて使う
・HTMLとCSSで分けることでソースコードを読みやすくする仕組みになっている

Java Script
・ヴレンダン＝アイク氏によって開発された言語
・ユーザー側のWebブラウザと、Webサイトまたはウェブサービスの相互間のやりとりを、円滑にするためのプログラミング言語
・コンテンツを更新したり、マルチメディアを管理したり、その他多くのことができるスクリプト言語
・ページを更新せずに画像が切り替わる、入力中に検索候補が出てくるなど
動きのあるページを作れる＝非同期処理
・Javaとは違う
・クライアントサイド、サーバーサイドでも動かすことが可能
＊クライアントサイド：PC、スマホ
＊サーバーサイド：インターネット接続先サーバー

Ruby
・マツモトユキヒロ氏により開発された言語
・コンパイル不要のスクリプト言語
＊コンパイル：ソースコードを機械命令に変更すること
・日本語のリファレンスが豊富
・全てのデーターがオブジェクトとしって表現されている、オブジェクト指向プログラミング
・WEBサイト、WEBベースの業務システムを効率よく使用できる

Rails(Ruby on Rails)
・Rubyでよく使われるフレームワーク
・WEBアプリケーション開発に利用
・開発工程の短縮、コードの書き方が統一されることで、効率化
・スマホアプリ、機械学習が不得意

<Ruby on Rails使用例>
・WEBサイト
・ECサイト
・WEBサービス、WEBアプリケーション
JavaScript: async function内で await を使ってもその関数自身が同期的に実行されるわけではない

# はじめに

async/awaitで勘違いしていたことがありました。
それは、async function 内で 非同期処理を await で待機した場合、そのasync function 自身が同期的に振舞うようになるものだと思っていたことです。
基本的な事とは思いますが、最近同じような問題に直面したので記事にまとめる事にしました。

# async/awaitの基礎

まずは、以下のような非同期処理を含む関数があるとします。

```javascript:JavaScript
function funcA(){
  console.log("a1");
  new Promise((resolve)=>{
    setTimeout(
      ()=>{
        console.log("a2");
        resolve();
      }, 1000
    );
  });
  console.log("a3");
}
```

この関数を実行すると、出力結果は以下のようになります。

```
a1
a3
a2
```

これを

```
a1
a2
a3
```

のように順番通りに出力したいとします。
awaitを使って実現すると以下のようになります。

```javascript:JavaScript
async function funcA_await(){
  console.log("a1");
  await new Promise((resolve)=>{
    setTimeout(
      ()=>{
        console.log("a2");
        resolve();
      }, 1000
    );
  });
  console.log("a3");
}
```

これでfuncA_await()が同期的に振舞うようになりました。
正確に表現するならば、非同期関数であるfuncA_await()内の非同期処理をawaitによって待機し同期的に処理していると言えばよいでしょうか。
これが基本的な async/await の使い方です。
このぐらい単純な場合には、難し事ではありません。

# 非同期関数と同期関数を順番に呼び出す。

さて問題はここからです。
先ほどのfuncA_await()の終了後に新たな処理を行い、出力データとして以下が欲しいとします。

```
a1
a2
a3
b1
b2
b3
```

単純に以下のように実装して実行してみます。

```javascript:JavaScript
function funcB(){
  console.log("b1");
  console.log("b2");
  console.log("b3");
}

function funcC(){
  funcA_await();
  funcB();
}
```

この実装では、出力は残念ながら以下のようになります。

```
a1
b1
b2
b3
a2
a3
```

非同期関数であるfuncA_await()の終了を待たずにfuncB()の処理が始まっています。
これをasync/awaitを使って当初の目論見通りに動かすようにするには以下のようにします。

```javascript:JavaScript
async function funcC_await(){
  await funcA_await();
  funcB();
}
```

しっかりとasync/await、Promiseを勉強していれば当たり前の話だとは思いますが、非同期関数であるfuncC_await()の実行を待つには、await()やPromise.then()を使う必要があります。

蛇足ですがこのfuncC_await()の後に処理を続ける場合は、同じようにasync/awaitを使う必要があります。

```javascript:JavaScript
function funcE(){
  console.log("e1");
  console.log("e2");
  console.log("e3");
}

async function funcD(){
  await funcC_await();
  funcE();
}
```

このような実装を続けると非同期処理が1つしかないにもかかわらず、いつの間にかにasync/await地獄に陥っていたりします。

# まとめ

async/awaitは、

- 非同期処理を同期的に扱う仕組み
- それらを用いたasync functionはあくまでも非同期処理

という事です。

このことから非同期処理は、しっかりと設計をして扱わなければいけない事が分かるかと思います。

この記事の場合は、

- 初めの非同期処理を同期処理に置き換える
- その後の一連の処理を順番に依存しないように作り替える

など根本的な対策が必要なのだと思います。
もっとも、根本の原因を取り除ける場面は多くなく小手先の対応を余儀なくされる場面の方が多いかと思いますが。
他にもっと良い方法があったら教えてもらいたいものです。


# 最後に

async/awaitも万能ではありません。
適切に使えるようになりたいものです。
放置してたGCPを復活させる（５）- VMのIPを固定する -

GCP復活の作業履歴
[放置してたGCPを復活させる（１）- プロジェクト作成 -](https://qiita.com/3S_Laboo/items/62322280d1844d461bab)
[放置してたGCPを復活させる（２）- VMインスタンス作成 -](https://qiita.com/3S_Laboo/items/03b54621479e193101f7)
[放置してたGCPを復活させる（３）- gcloud CLIインストール -](https://qiita.com/3S_Laboo/items/75682b3d008d0fdce355)
[放置してたGCPを復活させる（４）- PC(Windows10)からVMにssh接続 -](https://qiita.com/3S_Laboo/items/63a17738071a171decb1)
[今回：放置してたGCPを復活させる（５）- VMのIPを固定する -](https://qiita.com/3S_Laboo/items/c897628aec6d04f4fe5f)
[放置してたGCPを復活させる（６）- nginxインストールとhttp設定 -](https://qiita.com/3S_Laboo/items/9a8446f84baa80252cb9)
[放置してたGCPを復活させる（終わり）- 独自ドメインの設定 -](https://qiita.com/3S_Laboo/items/cce944d49cbd1d4aa745)

今回はVMのIPを固定しまーす。
# 情報収集
[静的外部 IP アドレスの予約](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address?hl=ja)
[GCP/GCEの固定グローバルIPアドレス、2020年より有料化](https://www.zaikei.co.jp/article/20190823/527366.html)
え、有料化？
ま、まぁとりあえずトライアルだから良しとしよう
#静的アドレスを予約
ハンバーガー⇒VPCネットワーク⇒外部IPアドレス
![2020-08-30_23h53_13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/5a80392b-d100-4f4d-a001-87281af34218.jpeg)
静的アドレスを予約
![2020-08-30_23h55_00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/4719a043-eba2-7c07-8e91-3556059f7972.jpeg)
名前とか接続先入れて予約
![2020-08-31_00h06_22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/2d9b4202-e449-0b95-9570-7fb5e7472abb.jpeg)
![2020-08-31_00h08_24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/53ab387e-906b-0af4-9a1e-3a3ebf16b95e.jpeg)
出来たのかしら？
![2020-08-31_00h13_27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/8b3858b0-5524-d4cd-bfe0-af8544ff9983.jpeg)
あ、なんかアドレス設定されている。
# 再起動してみよう
キャプチャは取ってないけどipが変わらないことを確認。

今回はここまで。

ありがとうございました。
次回
[放置してたGCPを復活させる（６）- nginxインストールとhttp設定 -](https://qiita.com/3S_Laboo/items/9a8446f84baa80252cb9)
一部処理の他ジェネレーターへの委譲

複雑なジェネレーターを記述する際には、yield from命令を利用することで処理を分離でき、コードがより見通しやすくなる。

```gen_from.py
def read_files(*files):
    for file in files:
        yield from read_lines(file)

def read_lines(path):
    with open(path,'r',encoding='UTF-8') as file:
        for line in file:
            yield line.rstrip('\n')
            
for line in read_files("./path/1","./path/2","./path/3"):
    print(line)
```

独習Pthon 9.2.4 より引用
スプレッドシートで管理しているタスクのステータスをSlack通知する

# 目的
マイルストーンをGoogleスプレッドシートを使って管理していると、各タスクのステータスの変化はスプレッドシートを見にいかないと確認できない。タスクの添削をお願いしたいときにこの状態だと作業が滞ってしまう可能性がある。
この問題を解決するために、添削をお願いしたいタスクをSlackに通知するスクリプトを**Google Apps Script**(以下、GAS)で作成した。

# マイルストーン
今回はマイルストーンの作成の仕方については、以下のサイトを参考に作成した。
[【テンプレDL可能】ガントチャートをGoogleスプレッドシートで作ろう](https://web-guided.com/1021/)

作成したマイルストーンでは、以下のようにステータスを設定している。
このうち、「添削お願い」を選択したときに通知がいくようなシステムを構築する。
![プルダウン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/321e740b-bfea-18da-cf03-2f6b88ab927c.png)



# 仕組み
GASは、`getActiveCell()`を使って変更されたセルを取得することができる。
そして、取得したセルと以下のメソッドを合わせることで様々な値を取得することができる。
- `getValue()`：取得したセルに入力されている値
- `getRow()`：取得したセルの行番号
- `getColumn()`：取得したセルの列番号

タスク名や担当者などは、`getRange(row, column)`を使って指定することで取得できる。

```
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
if(cell.getColumn()==7){
  var row = cell.getRow();
  if(cell.getValue() === "添削お願い"){
    var body = "「" + sheet.getRange(row,3).getValue() + "」の添削をお願いします。\n担当者：" + sheet.getRange(row,6).getValue() + "さん";
    sendToSlack(body, "チャンネル名");
  }
}
```
- `getActiveSheet()`：アクティブなシートを取得する。
- `if(cell.getColumn()==7)：`変更されたセルが上記のプルダウンであるか、if分で確認する。
- `if(cell.getValue() === "添削お願い")`：タスクのステータスを確認し、"添削お願い"のときにSlackに通知する。
-  `sendToSlack`：Slackに通知するために作成した関数。`body`は通知する内容を指す。[Googleformからのslack通知設定方法](https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9)を参考に作成した。

# トリガー
内容を変更したときにスクリプトが動くようにトリガーを、「編集」->「現在のプロジェクトのトリガー」から設定する。
「イベントの種類」を"変更時"にすることで内容が変更されたかどうか探知できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/d1f11d12-2c39-7d87-a0c3-1ad003e820ba.png" width="480px">

# 参考にしたサイト
- [Google Apps Scriptで値の変更をトリガーにしつつ変更されたセルの行番号と列番号を知る](https://tonari-it.com/gas-trigger-changed/)
XOR世界で行列のrankを求める(F2上での行列のrank)

#最初に
ご指導まっています

##XORとは
詳しくは別サイトで調べてください.
かいつまんで話すと
1+1=0
1+0=1
0+1=1
0+0=0
と演算が定義されている世界だと思っていただければ(代数的に言うと$\mathbb{F_2}$上の和です.)

##簡約化とは
行列のrankを保ちつつ都合がいい形に変形していく作業です.
rankが分かると嬉しいことが多いです(雑)
また簡約化する過程で存在すると逆行列を得ることができるので簡約化は結構大事なものです.

##プログラム
まずは演算を定めます

```
def cal(a,b):
    if a==1 and b==1:
        return 0
    elif a==1 and b==0:
        return 1
    elif a==0 and b==1:
        return 1
    else:
        return 0
```

次に行列の行の足し算を定義しておきます(よく使うので)

```
def matcal(line1,line2):
    ans=[0]*(len(line1))
    for i in range(len(line1)):
        ans[i]+=cal(line1[i],line2[i])
    return ans
```

あとは簡約化(上三角までしかしないけど)をしてくれるやつを書くだけです

```
def simple(mat):
    ans=copy.copy(mat)
    rank=0
    for i in range(len(mat[0])):
        for j in range(rank,len(mat)):
            if ans[j][i]==1:
                for k in range(rank,len(mat)):
                    if ans[k][i]==1 and k!=j:
                        ans[k]=matcal(ans[k],ans[j])
                if j==rank:
                    pass
                else:
                    ans[j],ans[rank]=ans[rank],ans[j]
                rank+=1
                if rank==len(mat)-1:
                    return ans
                break
            else:
                pass
    return ans
```
流れを雑に説明すると
rank番目の列に1があるかを検索してあったら行を交換.そして自分より下の行の1を消す(足してあげる)
を繰り返す感じです.
きれいに簡約化しなくてもrankを求めるならこれで十分です.

##動作

```
print(simple([[1,1,1],[1,1,0],[0,1,0]]))
>>>[[1, 1, 1], [0, 1, 0], [0, 0, 1]]

print(simple([[1,1,0],[1,1,0],[0,1,0]]))
>>>[[1, 1, 0], [0, 1, 0], [0, 0, 0]]

print(simple([[0,0,1],[0,1,0],[1,0,0]]))
>>>[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
```
いい感じですね.

##rankを返す

上のやつで簡約化もどきまで行えばrankを教えてくれる君です.

```
def rank(mat):
    l=len(mat[0])
    che=[0]*l
    cnt=0
    for i in range(len(mat)):
        if mat[i]!=che:
            cnt+=1
    return cnt
```

##最後に
$\mathbb{F_2}$じゃなくても$Z/nZ$でやれるようにしたいですね.
ただ今回は１の逆元が1なので自分自身を足せばよかったですけど,$Z/nZ$だと逆元を探してくれるプログラムを準備しないといけないのでちょっと大変かも.
GitHubとZenHubでIssueのタイトルとSP一覧を取得する

ZenHub便利なのですが、現在のリストからSP合計を知りたい、というときにエクスポートする機能がありません。
GitHubのAPIとZenHubのAPIを使って取得できないか試してみました。

# 下準備
GitHubとZenHubのトークンを取得しておきます。


# 動作確認　

まずGitHubのAPIでIssueのリストを取得します。

```bash
GITHUB_TOKEN=xxxxxxxxxxxxxxxx

$ curl -H -s "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/yousan/damp/issues\?per_page\=100\&page=1

10
"Bump lodash from 4.17.15 to 4.17.19 in /php7.2/apache/pma.test"
9
"Bump jquery from 3.4.0 to 3.5.0 in /php7.2/apache/pma.test"
```

ZenHubのAPIも確認しておきます。ZenHubでSPを取得するにはIssueごとにAPIを発行する必要があります。

```bash
ZENHUB_TOKEN=xxxxxxxxxxxxxxxx
REPO=xxxxxxxxxxxxxx

$ curl -s -H 'X-Authentication-Token: ${ZENHUB_TOKEN}' https://api.zenhub.io/p1/repositories/${REPO}/issues/1/ | jq .estimate.value

```

# GitHubでCSVを作成
GitHubでは1ページ当たり100件までという制約があるため100件ずつ取得します。

また`jq`でIssue番号とタイトルだけを抜き出すようにしています。その際に`perl`コマンドで改行をカンマ区切りへと変換しています。

```bash
GITHUB_TOKEN=xxxxxxxxxxxxxxxx
USER=yousan
REPO=damp

PAGED=1
curl -H -s "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/${USER}/${REPO}/issues\?per_page\=100\&page=${PAGED} | jq ".[] | .number,.title" | perl -pe 's/([0-9]+)\n/$1,/g' > gh_${PAGED}.txt &
PAGED=2
curl -H -s "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/xxxxxxx/xxxxxxxxxxxxxxx/issues\?per_page\=100\&page=${PAGED} | jq ".[] | .number,.title" | perl -pe 's/([0-9]+)\n/$1,/g' > gh_${PAGED}.txt &
.....

wait;

cat gh_1.txt gh_2.txt gh_3.txt gh_4.txt gh_5.txt gh_6.txt gh_7.txt gh_8.txt > gh.csv
```

最後に`cat`コマンドでCSVとして結合させています。

# ZenHub
ZenHubもループで回して`zenhub.csv`に書き出します。

```bash
ZENHUB_TOKEN=xxxxxxxxxxxxxxxx
REPO=xxxxxxxxxxxxxx

for i in {1..600}; do
  curl -s -H 'X-Authentication-Token: ' https://api.zenhub.io/p1/repositories/${REPO}/issues/${i}/ | jq .estimate.value >> zenhub.csv
done
```

２つのcsvファイルをエクセルなどで結合すれば完成です。
SchemaSpyをピュアなWindows環境で動かしてみた

ドキュメント成果物に **ER図** を含めて納品することになった。
形だけで良いようなので、外部キー制約を主キーから推測しER図を生成する **SchemaSpy** に頼ることにした。

Docker を使わずに、ピュアな Windows10 環境だけで動かしてみたが、そのような実行手順は Qiita で誰も書いていなかったので情報共有しておく。

# 前提ライブラリの準備
## Chocolatey のインストール
**Chocolatey** とは Windows の（非公式の）パッケージマネージャである。
Linuxの`yum`や`apt`に相当するものと言えばお分かりいただけるだろう。
PowerShellを管理者モードで起動し、次のコマンドを実行するとインストールできる。

```powershell:PowerShell
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```

インストールされたことを確認する。

```powershell
$ choco -v
0.10.15
```

## Graphviz のインストール
[DOT言語](https://ja.wikipedia.org/wiki/DOT%E8%A8%80%E8%AA%9E)で記述したファイルから画像ファイルを出力するツール **Graphviz** をインストールする。

```sh
choco install graphviz -y
```

bin に Path を通す。

```
SETX /M PATH "%PATH%;C:\Program Files (x86)\Graphviz2.38\bin"
```

なお、`winget`というマイクロソフト公式のパッケージマネージャが使える環境なら、

```
winget install graphviz
```

としてインストールしてもOKだ。

## JREとJDBCドライバのインストール
本記事を読んでいるということは、すでに導入済みと思うので、手順は割愛する。

# SchemaSpy 本体のインストール
https://github.com/schemaspy/schemaspy/releases/download/v6.1.0/schemaspy-6.1.0.jar
を任意のフォルダにダウンロードする。（バージョン番号は記事執筆時点のもの）

# 起動方法
実行コマンドとパラメータは次の通り。

```sh
java -jar schemaspy-6.1.0.jar -t "DBタイプ" -dp "JDBCドライバ" -db "DB名" -host "サーバ名" -port "ポート番号" -u "ユーザ名" [-p "パスワード"] -o "出力先ディレクトリ"
```

例えば MySQL の場合、次のように指定する。

```sh
java -jar schemaspy-6.1.0.jar -t mysql -dp mysql-connector-java-8.0.20.jar -db example_db -host example.com -port 3306 -u root -o schema -connprops serverTimezone\=Asia/Tokyo
```

パラメータは類はプロパティファイルに記述しておき、それを読み込ませる方法でも良い。

# 実行
実行すると、出力先ディレクトリにHTMLファイルと画像ファイルが出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/02e9666d-a26a-f9b3-bdd7-f61270818b58.png)
`index.html`を開くと、最初にダッシュボードの画面になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/0eb4a2ed-752c-0631-9a56-02b9caa2cd32.png)
テーブル名をクリックし、Relationships から ER図 を表示できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/3019a90b-9225-7347-93ad-7c46fbc00477.png)
データベースの設計について

データベースの設計は、**`論理設計`**と**`物理設計`**の２つの段階に大きく分けられる。

#論理設計とは

- データベースに格納すべきデータの洗い出しとそのデータ同士の関連性を定義すること

- 洗い出したデータをさらに重複のないように整理したものを、格納するべきデータとし、物理設計に進む。


#物理設計とは

- 論理設計で定義されたデータを実際のデータベース内にどのように格納するかを決めること

- 具体的には、「そのデータは文字列か数値か」、文字列であれば「何文字の文字列か」、数値であれば「整数か小数か」といった、データをどのような種類のものとして格納するかといったことを検討する。
MySQL8.0でのユーザー作成について  ERROR 1819 (HY000):　が出たとき

MySQL8.0にユーザーを追加しようとしたところエラーが出ました



```
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
```

このエラーはもっと文字列を複雑にしてくださいという内容です。







これではユーザー作成できないので、どんな制限がかかっているかみてみました。

```
SHOW VARIABLES LIKE 'validate_password%';
```



```
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password.check_user_name    | ON     |
| validate_password.dictionary_file    |        |
| validate_password.length             | 8      |
| validate_password.mixed_case_count   | 1      |
| validate_password.number_count       | 1      |
| validate_password.policy             | MEDIUM |
| validate_password.special_char_count | 1      |
+--------------------------------------+--------+
```

パスワードの長さは８文字以上、ポリシーは MEDIUM になっていてこれだと簡単な物だとエラーが出てしまいます。
なので以下のように設定しました。

```
mysql> set global validate_password_length=6; # 文字列の長さを変更
mysql> set global validate_password_policy=LOW;　# ポリシーを変更
mysql> set global validate_password.check_user_name = OFF;　
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| validate_password.check_user_name    | OFF   |
| validate_password.dictionary_file    |       |
| validate_password.length             | 6     |
| validate_password.mixed_case_count   | 1     |
| validate_password.number_count       | 1     |
| validate_password.policy             | LOW   |
| validate_password.special_char_count | 1     |
+--------------------------------------+-------+
7 rows in set (0.00 sec)
```

行った内容は、パスワードの長さを６文字、ポリシーをLOWに変更



ここでやっと準備が終わったのでユーザー作成へ！

```
CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';　＃ユーザー作成する
SELECT  host, user FROM mysql.user;　　#ユーザ作成できているか確認
```
```

+-----------+------------------+
| host      | user             |
+-----------+------------------+
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
| localhost | test             |
+-----------+------------------+
5 rows in set (0.00 sec)
```


ユーザー追加できました。
[Rust] &str と String を両方取れる関数を作成する

もう語り尽くされたネタですが。
Rustで`&str`と`String`の双方を取れる関数は色々あると思いますし、実際下の`func1`のようなものはよく見かけるのですが、他にもいろいろなパターンが考えられるのではないかと思って書きました。

```rs
use std::borrow::{Borrow, Cow};
use std::convert::AsRef;
use std::ops::Deref;

fn func1<'a, S: Into<Cow<'a, str>>>(s: S) {
    let s: Cow<'a, str> = s.into();
    let _: &str = &s;
    let _: String = s.into_owned();
}

fn func2<'a, S: Deref<Target = str>>(s: S) {
    let _: &str = &*s;
}

fn func3<'a, S: AsRef<str>>(s: S) {
    let _: &str = s.as_ref();
}

fn func4<'a, S: Borrow<str>>(s: S) {
    let _: &str = s.borrow();
}

fn main() {
    let s: &str = "abc";
    func1(s);
    func1(s.to_string());
    func2(s);
    func2(s.to_string());
    func3(s);
    func3(s.to_string());
    func4(s);
    func4(s.to_string());
}

```

# まとめ
`func`の中で`String`型でほしいときは`func1`がいいですね。(もちろん`&str`から`String`に変換はできますが、もともと`func`に`String`が渡された場合に2度変換されるという無駄が発生する)

あと、上記の関数では型テンプレートを使用していますが、その中では`Into<Cow<'a, str>>`を実装している型がいちばん少なそうなので、コンパイラへの負担も`func1`が一番小さいのではないでしょうか。

# 追記: バイナリサイズを比較したら`func3`, `func4`が最小でした

`rustc --crate-type lib` でコンパイルしました

- func1: 4920Byte
- func2: 4918Byte
- func3: 4904Byte
- func4: 4904Byte

本来はバイナリをデコンパイルする等しっかり調べるべきですが、大して差がないため、関数名のマングル時などに差が生じたのでしょう。
SQLのHAVINGについて①

前回、SQLについての記事を書いたので、今回も引き続きSQLについて書こうと思います。
今回はHAVINGについて説明します。
個人的にはあんまり使う機会がないのですが、けっこう頻繁に使い方を忘れてしまうので……。
使用するテーブルは以下の通りです。

|name|class |
|:-----|:-----|
|鈴木   |Aクラス   |
|田中   |Aクラス   |
|山田   |Bクラス   |
|佐藤   |Bクラス   |
|渡辺   |Bクラス   |
|中村   |Cクラス   |

まずはHAVINGのみを単体で使用します。

```ruby:SQL
SELECT name, class from TABLE1 HAVING class = 'Aクラス';
```

すると、以下のような結果が抽出されます。

|name|class |
|:-----|:-----|
|鈴木   |Aクラス   |
|田中   |Aクラス   |

お察しの通り、WHEREとまったく同じ動きをします。
少しややこしいのですが、HAVINGとWHEREは呼び出されるタイミングが違って、そこによって使い分けます。
WHEREはGROUP BYされる前の段階の抽出条件を指定する句であり、HAVINGはGROUP BYが適用された後の抽出条件を指定する句になっています。
逆に言えば、GROUP BYが使用されていないSQLの中ではWHEREとHAVINGは全く同じ動きをするわけです。
そんな事情で、HAVINGはほとんどの場合、GROUP BYと一緒に使用されることになります。
次回は実際にどのような動きをするのかを説明したいと思います。
機械学習についてのメモ(随時更新)

#学習の流れ

1. 実施内容の決定

2. データ入手

3. データ前処理

4. 手法選択

5. ハイパーパラメータ選択

6. モデルの学習

7. モデルの評価　→ 3、4、5へ


#訓練データとテストデータを分ける理由

・システムリリース時
持っている全データを訓練データとしても良い

・精度評価を行いたい場合
訓練データとテストデータを分け、訓練データのみから学習したモデルでテストデータを評価する

教師あり学習の目的が、未知のデータに対する予測であるため


#適合不足と過学習

##適合不足
・訓練データに対しても予測精度が低い状態

##過学習
・訓練データによくフィットしているが、テストデータ(未知のデータ)に対する予測精度が低い状態

適合不足と過学習のバランスをいかにうまく取るかが機械学習の一番難しいところ
NIC(eth0)のアドレス部分だけを取得する

#　ネットワークのアドレス

ifconfigでipを表示すると複数のNICのipが取得できます。
例えば下記のような感じです。
この中からifconfigでeth0のNICアドレスを取得するにはどうするのかを考えます。

```
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.28.99.150  netmask 255.255.240.0  broadcast 172.28.111.255
        inet6 fe80::215:5dff:xxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:90:90:41  txqueuelen 1000  (Ethernet)
        RX packets 742  bytes 149376 (149.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16  bytes 1216 (1.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

# eth0のアドレスをgrepする
ifconfigでgerpしてipアドレスだけを取得するには下記のようにします。

```
ifconfig eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
```

ifcongit eth0 で取得したいNICの情報を表示させます。
もし別のNICのIPアドレスが取得したければethXXといった感じでナンバーを指定します。
(これで通じるのだろうか。。。。)
その後パイプで結果を渡して正規表現でgrepしてます。
oはマッチしたとこだけ取るオプションでPはPerl形式の正規表現で、
この組み合わせで行の抽出と切り出しがマッチした部分のができますね。
【Gatsby】(ほぼ)ノーコード、１分でGatsby×NetlifyCMSブログサイトをつくる

>✳︎*最近盛り上がっているNoCodeツールは関係ありません*
>✳︎*非エンジニアが書く初心者向けの内容です*

基本的には[NetlifyCMS公式サイト](https://www.netlifycms.org/)のGetStartedから順に進んでいくと１分くらいでデプロイ出来ます。

かなりできることに限りはありますがコードを書いたりコマンド操作なしで

* Gatsbyサイトの公開
* ブログ投稿
* 見た目を少しイジる

をやってみました。。本格的にカスタマイズするにはGatsby.js/HTML/CSS/React/Node.js/yarn/GitHubなどの知識が必要になります。



## 1.Netlifyにデプロイ
GitHubにログインした状態で
[NetlifyCMS](https://www.netlifycms.org/)
から「GET STARTED」→「Gatsby Site StarterのDeploy to Netlify」に進みます。

![netlifyqiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/4c3abf49-5196-a729-8a4b-4646f1550501.gif)

***Get your Gatsby site in 1 min.***と出てきたら「Connect to GitHub」をクリック
![スクリーンショット 2020-08-30 21.43.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/78be5a4d-a0e9-56a6-a42b-ec0a837aa004.png)

あとは***Repository name***を入力して「Save & Deploy」でデプロイ完了です。ここまでおよそ１分。。今回は「gatsby-test」というリポジトリで作成しました。
![スクリーンショット 2020-08-30 21.44.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/9464fd6c-b745-322c-f0b9-ae32e7355540.png)

## ２.見た目をカスタマイズ
「Save & Deploy」後少し待つとURLが発行されます。
![netlifyDeploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/707dd24e-e968-1714-0d13-c55820dfa849.png)
最初はこんな感じのカルディがテーマのサイトが出来上がります。
![スクリーンショット 2020-08-30 22.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/9db9466b-d7d9-7f89-cea3-481814061d61.png)

デプロイの時点でGitHubにもリポジトリが作成されています。
![github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/34bcb58e-f14d-66ee-cd6d-0a5cf4669dd3.png)

編集画面にはトップページの下部（フッター内)のAdminもしくはURLに```/admin```をつけても移動出来ます。ログインを求められますが、なぜかGitHubアカウントではエラーが出ます。
![スクリーンショット 2020-08-30 22.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/4f7ae060-e3b1-5a8c-de2b-37b42b70d50d.png)

Forgot password?からパスワードを再設定するとログイン出来ます。
![スクリーンショット 2020-08-30 22.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/e15544bc-a9cf-563b-2570-c12b3f71863a.png)

見た目の変更はCollectionsのPagesタブから
* Landing Page
* About
* Products Page
をページごとに編集出来ます。ここではLanding Page（トップページ）のヒーローImageとタイトルを変更してみます。画面右側でプレビューを見ながら変更していきます。変更後は右上のPublishで編集完了。ビルドに少しかかるので数分してページを更新すると変更が反映されます。
![スクリーンショット 2020-08-30 23.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/1d9bd28d-6d6e-a2f8-7bad-6c86436663ac.png)
## 3.ブログ記事投稿
ブログ記事は編集画面右上のQuick addから編集して投稿出来ます。本文エディタはブロックエディタかマークダウンどちらも使えるようです。
![スクリーンショット 2020-08-30 23.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/d6bd7fb4-419f-fe5f-316d-7afa8e24c2b9.png)

#### Lighthouse
![スクリーンショット 2020-08-30 23.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/95d53f68-406a-0d73-42b0-e9deb4ddd659.png)
#### PageSpeed Insights
![スクリーンショット 2020-08-30 23.23.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/234a837a-98f5-758a-704b-d1ffd0082578.png)

パフォーマンス、スピードもまずまず。次は同じくNetlifyCMSを使ったGatsbyテーマ『yellowcake』のデプロイ、設定方法について書いていこうと思います。。
Using another database for phpunit test on Laravel 6 with docker-compose.

Every engineer would hope to divide database when running test.
I'll show using another database for phpunit test on Laravel 6 with docker-compose in this article.

## STEP

1. Adding test database on docker-compose
2. Adding setting for test database in config/database.php
3. Adding environment at phpunit.xml
4. Create .env.testing as new env file
5. Running migration command for test database
6. Running phpunit


## CODES

```php:docer-compose.yml
version: '3' 
services:    
  db:            
    build:   
      context: ./app/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hoge
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hoge
    container_name: mydb
    ports: 
      - "3306:3306"
    tty: true
    volumes:
      - ./app/mysql/db_data:/var/lib/mysql
  testdb:            
    build:   
      context: ./app/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hoge
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hoge
    container_name: testdb
    ports: 
      - "3307:3306"
    tty: true
    volumes: 
      - ./app/mysql/testdb_data:/var/lib/mysql
  web:
    ...
```

```php:config/database.php
    ...

    'connections' => [

       ... 

       'mysql' => [
            ...
        ],  
                                                                                                                                                                                                              
        'mysql_testing' => [
            ...
            'host' => 'testdb',
            ...
        ],  
 

```

```php:phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>                                    
    ...
    <php>                                                                 
        <env name="APP_ENV" value="testing" force="true"/> 
        <env name="DB_CONNECTION" value="mysql_testing" force="true"/> 
        ... 
    </php>                                                                
</phpunit>    
```

```php:.env.testing
APP_ENV=test
APP_KEY=[YOURKEY]
APP_DEBUG=true 
```

```
$ php artisan:migrate database=mysql_testing
$ ./vendor/bin/phpunit
```
【CSS】マウスカーソルが乗るとアンダーラインがニュッと出てくる

# はじめに
・自分自身の備忘録として書きます。
・間違いなどあればご指摘いただけますと幸いです。

# こんな感じ
https://gyazo.com/a02da2706b969203c369281f69f251d6

# コードはこんな感じ
```css

a {
  color: #707070;
  position: relative;
  text-decoration: none;
}
a:before{
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1px;
  background: #555;
  transform: scale(0, 1);
  transform-origin: left;
  transition: 0.5s;
}
a:hover {
  color: #101010;
}
a:hover:before {
  transform: scale(1);
}
```

`transform-origin: left;`を指定しない場合、中心から左右に向かってアンダーラインが出ます
`height: 1px;`はアンダーラインの太さです
※hoverした時に文字色が変わるようにしていますが、これはアンダーラインと関係ない部分です
Bizサイドの人にも（正しく）知ってほしいDev用語

## 社内LT用

----

## （正しく）知ってほしいDev用語

- **Biz-Dev間で齟齬のない**コミュニケーションを取れるように
- **Biz側**の人にも**正しく**知って欲しい**Dev用語**をまとめて見ました
- 3つだけ！笑

---

## 何が正しいかは主観

- 齟齬をなくせればいい
- 共通の認識

---

# 実装

---

## 実装

ソシャゲとかで、、、

- 「コラボイベント 実装！(●月●日)」
- 「新キャラ 実装(来春)予定！」

**「リリース」に近い意味？**で使われる

----

## 実装

エンジニアが、、、

- 「新機能の実装できました！」
    - 開発（コードを書く作業）が終わったという意味

---

## 実装

### "implement"
「仕様・要件をコードに落とし込む」
「あるいはコードそのものを指す」

---

## 実装

- **リリース済**と言う意味合いは**全くない**
- レビューや動作確認などリリースまでには**残作業がある**

----

# コミット

----

## コミット

- コミットメント
  - 目標を立てて、責任を持ってそれに挑むと言う宣言？

----

## コミット

### "Commitment"
「約束」「目標」「責任」

---

## コミット

### Commit (version control)

> In version control systems, a commit adds the latest changes to [part of] the source code to the repository, ...[（略）](https://en.wikipedia.org/wiki/Commit_(version_control)#:~:text=In%20version%20control%20systems%2C%20a,kept%20in%20the%20repository%20indefinitely.)

バージョン管理システムにおいて、コミットはソースコードに対する変更をリポジトリに追加すること・・・

----

## コミット

- 目標も責任も全く関係ない（笑）
- 「コミットをプッシュ」
    - 「修正したコードをgithubにあげた」くらいの意味（雑）
    - 「めちゃめちゃ頑張る」ではない（笑）

----

## バグ

- 説明不要？？？

----

## バグ

- コンピュータのプログラムにひそむ**誤り**
- **仕様・要件の通り**にプログラムが**実装されていない**

-----

## バグ

- 問題の原因が**仕様・要件の不備**にあればそれは**バグではない**

----

## バグ

- バグはエンジニアだけの力で直せるもの
- バグか否かを適切に振り分けて、バグは早急に直す！
- 割れ窓問題

----

# that's it! thanks! :relaxed:

* 実装
* コミット
* バグ
Swift で日本語を含む URL を扱う

日本語を含む文字列を URL に変換する時に値が nil になることがあると思います。これは、URI において使用できない文字列を URL として変換しようとしている時に発生します。Google などの検索バーでは、このような使用できない文字列を自動で[パーセントエンコーディング](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)しているので正常に検索を行うことができます。自分もたまに、エンコーディングを忘れてしまうのでこれを機に気をつけて行こうかと思います。

### 文字列をエンコード

今回は楽天市場の商品 URL を取得するという設定でエンコーディングを行っていきます。

```swift
let itemString = "スコーピオン"
let itemEncodeString = itemString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
let urlString = "https://search.rakuten.co.jp/search/mall/\(itemEncodeString!)"

print("itemEncodeString: \(itemEncodeString!)") // itemEncodeString: %E3%82%B9%E3%82%B3%E3%83%BC%E3%83%94%E3%82%AA%E3%83%B3
print("Result URL: \(URL(string: urlString)!.absoluteString)") // Result URL: https://search.rakuten.co.jp/search/mall/%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%94%E3%82%AA%E3%83%B3
```

上記のようにエンコードすることができました🎉  

`.addingPercentEncoding(withAllowedCharacters: CharacterSet)` にセットするCharacterSetですが、今回の場合は URL の Path にセットされる文字列に日本語が含まれている可能性があったので `.urlPathAllowed` という CharacterSet を使用しています。URL String 全体に対してエンコーディングをかける場合は、`.urlFragmentAllowed` もしくは `.urlQueryAllowed` を使用すればそれなりに正しくは動きますが、個人的にはお勧めしません。理由としては、それぞれの CharacterSet で守備範囲としている URL コンポーネントが違うからです。例で言うと下記のように、パスの文字列で `?` を含む URL String 全体を `.urlQueryAllowed` を使ってエンコードした場合、`?`は文字列とみなされずエンコードされません。つまり、結果として取得した URL が正確でない可能性があります。そのため、使う用途に分けて URL コンポーネントそれぞれをエンコードするのがベストでしょう。

```swift
let urlString = "https://search.rakuten.co.jp/search/mall/スコーピオ?ン"
let encodeUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)

print("Result URL: \(URL(string: encodeUrlString!)!.absoluteString)") // Result URL: https://search.rakuten.co.jp/search/mall/%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%94%E3%82%AA?%E3%83%B3
```

URL コンポーネント別の CharacterSet 一覧は下記になります。

- [urlFragmentAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1412537-urlfragmentallowed)
- [urlPasswordAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1417313-urlpasswordallowed)
- [urlPathAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1416804-urlpathallowed)
- [urlQueryAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1416698-urlqueryallowed)
- [urlUserAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1411851-urluserallowed)
- [urlHostAllowed](https://developer.apple.com/documentation/foundation/nscharacterset/1416426-urlhostallowed)


### 参考


- https://developer.apple.com/documentation/foundation/nscharacterset

- https://qiita.com/shtnkgm/items/83e88f230366adfad8e8

- https://qiita.com/nagisawks/items/25433a5f1d45756dbfde
Automation Anywhere A2019 日時ユーティリティパッケージ (Bot Store) を使う

Automation Anywhere A2019で標準では対応していない日時の演算処理 (2つの日時の差分計算、日時型変数から要素を取り出す、うるう年判定など)を行ってくれる便利なパッケージがリリースされています。

# A2019 日時ユーティリティ
以下の場所から無料でダウンロードできます(^_-)-☆。
[A2019 日時ユーティリティ](https://botstore.automationanywhere.com/jp/bot/a2019-datetime-utilities/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/afa0c416-906b-658e-eba5-77179811c8c6.png)

Control Roomにインストールすると以下のアクションが使えるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/b2e3bd7d-da7c-f73c-1d98-06acbb69dce6.png)

### Difference Between Dates
指定された2つの日時の差分を指定された単位 (日/時/分/秒) の数字で返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/55ff85a8-88b6-b095-e517-2ccd06f49840.png)

### Get Day Of Month/Week/Year
指定された日付が指定した月の何日目(数字)か、何曜日(英語で曜日の文字列)か、指定した年の何日目(数字)かを返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/86393b77-6e63-3e83-b77c-a2158d05fe76.png)

### Get Days In Month
指定月 (yyyy年MM月) の日数を数字で返します。Get Length Of Monthと同じ？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/4ee36b88-4586-dfcf-d210-5e3e894012a2.png)

### Get Year/Month/Hour/Minute/Second
指定された日時の年/月/時/分/秒の要素を数字で返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f239fc09-3542-0514-95bb-a3d6ea4017a9.png)

### Get Length Of Month/Year
指定月 (yyyy年MM月)または指定年の日数を数字で返します。Get Length Of MonthはGet Days In Monthと同じ？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/3f58f3fd-39be-d24e-af7d-c5fbe720744f.png)

### Is Leap Year
数字で指定された年のうるう年判定をします。(boolean型で返す)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f584858c-616c-7641-b38b-f3c168363b68.png)

### Now
現在の日時をフォーマットされた文字列型で返します。しかし、標準でも`$System:Date$`に現在日時が入っており、様々に加工することによって同様のことができるので、このアクションの存在意義は疑問？です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/fb5f6050-dffc-392c-cd6a-63cfeeeeea80.png)



# A2019 日時 (日本)
上記のパッケージでは対応していない書式処理 (和暦、令和対応)や日本の祝休日/稼働日判定ができるパッケージもあります(^_-)-☆
以下の場所から無料でダウンロードできます。
[A2019 日時 (日本)](https://botstore.automationanywhere.com/jp/bot/a2019-datetime-japan/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/9a89cb50-6313-40d6-b1d0-a2991fd52be4.png)

日本市場における日付関係のユーティリティパッケージとサンプルボットがついています。パッケージは6つのアクションを提供します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/5438d96e-f604-6cfa-72e0-c340cf5e3da5.png)

詳しくは、「[【Automation Anywhere A2019】日本向けに役に立ちそうなBot Storeアイテム4選](https://qiita.com/Okura_/items/66e85f176d94c7369c3f)」の「4. A2019-日時（日本）」の章を参照してください(^^)/
[左右分離式キーボード]R-GO SPLIT ERGONOMIC KEYBOARDを買ってみた

弊社も例に漏れずで、コロナの影響にて強制的にリモートワークを余儀なくされています。
100%リモートでなくてもいいんだけど、どちらかというと歓迎。通勤の時間って無駄ですよね。

まあ、それは置いときまして。
職場環境（＝自宅）が気になり、少しずつ改善してたりします。
仕事PCはmacbook proです。外部モニタは不使用。
目線の高さが重要で、なるべく高くってお話もあったりしますが、MTGの度に部屋を移動したりもするので、固定のモニターは面倒だなと思って導入してません。
そこでどうしようかなって思った結果、とりあえず外部キーボードを導入してみようかなと。
そしてPCは少し高めの台に置く。移動の時はPCだけ持ってく。

・・と前置きが長くなりましたが、外部キーボードとしてR-GOってブランド・・なのかな？、のキーボードを導入してみた話です。

## 選定の経緯

- 分離キーボードを使ってみたい
- でも高い
- 普段使ってるし、ファンクションキーとかもほしい。

とか思いつつ、メルカリだとかをしばらく眺めていました。
当初の候補としては、

1. Barocco MD770
2. 自作キーボードキット

1.はレビューとか見てもよさげだったし、無難かなと。ヤフオクで入札したりもしました。
新品はちょっとお高くてもうちょっとなんとかならんかなー、って感じ。
2.も考えましたが・・フルサイズ（テンキーレス）のキーボードとなると選択肢がけっこう少なくて、キーキャップだとかいろいろ揃えると結局お高い。そしてリスキー。
そんなわけでふらふらしてましたが・・なんとなく気まぐれでのぞいたamazon.com

https://www.amazon.com/R-Go-Tools-Keyboard-RGOSP-USWIBL-Integrated/dp/B071GCDWN7/

なんだこのキーボード。一目ぼれ。薄くて良くない？持ち運びも便利そう。打鍵感とかはbaroccoとかの方が良いのだろうけど、あんまりそのへんは気にした事ないし。
そして価格もまあお手頃。日本に配送してくれる所だと `RAREWAVES-IMPORTS` ってところがあって少し割高にはなったけど送料込みで$132ぐらい。購入から10日くらいで届いたかな。
なんか今みたらamazon.co.jpにもあって、そっちの方が安いかも。

https://www.amazon.co.jp/dp/B072MRN82W

なお、上記のレビュー内で
> When you press the shift key you have to press it with the same side that you're pressing a key for, so if you want to do a capital 'A' then you must press shift on the left keyboard, not the right.

> i'm using this with a mac.

みたいな低評価のレビューがあったりしましたが、ここはKarabiner-elementsで解決しましたよ。
低評価レビューはどちらかというとそういう上手くいかなかったというのが多いすね。まあ、そこは自己責任で。

## 今の構成

![IMG_20200830_222632.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/0a5c3c3c-fa1a-bf1e-8c1b-fa77a338317d.jpeg)

mackbookのモニターを頭の高さに持ってきつつ、手元にはR-GO SPLITキーボード。
マウスは使わずマジックトラックパッドを使用しています。

## Karabiner-Elements設定

![スクリーンショット 2020-08-30 22.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/7fb343ec-9f67-242b-64b0-595b011cab19.png)

US配列のを購入し、しばらくはUS配列設定で使ってたのですが、macbook自体が日本語配列だったりして本体のキーボードを使う時に頭の切り替えが大変だったりしたのと、個人で使用しているPC達も日本語配列だったりして、結局はそっちに寄せました。
前述の画像を見てもらえるとわかると思いますが、実は一部のキーにラベル貼ってあります。例えば数字の`2`のキーはUS配列だとshift併用で`@`になるはずが、日本語設定にしたので`"`となっています。
あとは左シフトの横のキー(non_us_backslash)がよくわかんないキーになってたので`¥`(internatinal3)に変えました。
それ以外は今の所はシフトだけかな。

デフォルトで使った場合の最大の問題点として、左と右で別のキーボードみたいに認識されてしまってる事があります。
まずは当たり前の事として、左のShiftキーを押しながら`a`のキーを打つと`A`が入力される。当然、右のShiftキーを押しながら`a`のキーを打った場合も`A`が入力されてほしい。
・・が、その当然の動作にはならず、右のShiftキーは左のどのキーとも連動しないし、逆もまた同様。これはめっちゃ辛い。
ただ、Karabiner-Elementsを使い、`left_*`を`right_*`に全て紐づけ、`right_*`も`left_*`にってやると解決しちゃいました。もちろん、本来の役割(左シフト+左側のキーとか)も動作している。

なお、独自のショートカット設定したりとかはあまりしない主義です。そういうのを覚えたりするのにメモリ使ったりしたくないし、道具を選びたくない。
なのでシンプルな設定だけしかしてないです。

## 感想

まだちょっと慣れてない部分はありますが、けっこう気に入ってます。
意外にも左右に分かれているという点の使いずらさは最初からまったく感じませんでした。

サイズ感：☆☆☆☆☆
打鍵感：☆☆☆☆★
薄さ・軽さ：☆☆☆☆☆
角度のアジャスト：★★★★★
マット感：☆☆☆☆★
ロゴが光る：☆☆☆☆☆

サイズ感としてはmacbook proより少し大きいくらいですかね。キーを打ってる感じはmacbook proと比べるとかなりある。タッチは軽めで音も小さめですね。
薄くて軽いのはかなりポイント。ノートPCと一緒に持ち運んでもぜんぜん苦にならない。マグネットで引っ付くので一枚の板として持ち運べます。
ネックなのはキーボードに角度をつけられない事かな。あとはパームレストとか使いたい人には高さがなさすぎるかなとも。（逆にパームレストいらない高さともいえる）
キーボードのマット感とロゴがグリーンに光るのは個人的にはポイント高し。
AtCoder Beginner Contest 177

##[A - Don't be late](https://atcoder.jp/contests/abc177/tasks/abc177_a)

```python:python
D, T, S = list(map(int, input().split()))
 
if T >= D / S:
    print('Yes')
else:
    print('No')
```

##[B - Substring](https://atcoder.jp/contests/abc177/tasks/abc177_b)

- 1000*1000なら全探索で間に合う

```python:python
S = str(input())
T = str(input())
 
Ans=1000
for i in range(0, len(S)):
    Tmp=0
    if i + len(T) <= len(S):
      for j in range(0, len(T)):
          if S[i+j] != T[j]:
              Tmp += 1
      Ans = min(Ans, Tmp)
print(Ans)
```

##[C - Sum of product of pairs](https://atcoder.jp/contests/abc177/tasks/abc177_c)

- 2^100000 * 2^100000だと全探索では間に合わない
- O(N)にする
- グラフを作ると答えが見ます
 
```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
#define MOD 1000000007;
 
int main(int argc, const char * argv[]) {
    
    int N;
    ll A[200000];
    ll AA[200000];
    
    cin >> N;
    for(int i=0; i<N; i++){
        cin >> A[i];
        if(i==0) AA[i] = A[i];
        else AA[i] = (A[i] + AA[i-1]) % MOD;
    }
    
    ll Ans=0;
    for(int i=0; i<N; i++){
        Ans += (AA[i] * A[i]) % MOD;
        Ans = (Ans - A[i] * A[i]) % MOD;
        if(Ans < 0) Ans += MOD;
    }
    
    cout << Ans << endl;
    
    return 0;
}
```
簡易相関図ツールを作成した

## 概要
ログイン不要、無料で簡易の相関図を作れるツールを作成しました。
作成した図はimgタグ情報コピー機能があるので、htmlにそのまま貼り付けられます。
wordpressや記事投稿サイトに使用するときは画像のダウンロード、アップロードが不要です。
(文字数はすごいことになりますが・・・)
qiitaはそのまま貼り付けできないみたいです。

png形式でダウンロードも可能です。
https://skz-app.tontonton.work/

## どんなことができる
こんな感じの図をWeb上で作成できます

![イメージ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361500/bc05fe04-3a10-7661-7cb0-73befaa117ab.png)
![イメージ２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361500/bb309544-dce5-600c-bd4e-a39226c7f3f0.png)


## 技術
* フロントエンド
  * html
  * javascript

* バックエンド
  * Firebase

* その他
  * google マテリアルアイコン (https://material.io/resources/icons/?style=baseline)

## なぜ作ったか
記事を書いているときに、

「説明するための図が欲しいな」

「そんなに詳細な図じゃなくていいんだけど、図を作成するのがだるい」

「作成するためのアプリを立ち上げるのが煩わしい」

「作成した図を保存→サイトにアップロードというプロセスが面倒」

という、なるべく怠けたい熱い思いから作成に至りました。

## まとめ
Firebaseは初めて使用しましたが、簡単にデプロイできて胸熱ですね。
試しに使ってみてください。