OmniAICreator/Qiita-1.07M huggingface dataset:
gcloud_cliで、認証済みのアカウントにログインしてるのに、認証されない時

firebase emulators を動かそうとした時に詰まった話です。

firebase emulators で、Firebase のプロジェクトの Firestore にデータを挿入しようとしたのに`default credential`がないみたいなエラーが出ました。

```bash
2021/08/05 11:38:04 google: could not find default credentials. 
See https://developers.google.com/accounts/docs/application-default-credentials 
for more information.
```

以下の二つは既にやっていました。

- ローカルの`gcloud_cli`と`firebase_cli`で、`gcloud auth login`と`firebase login`とか使って、コンソール上で認証されているアカウントに、ログイン済み。
- admin sdk キーの json もちゃんと指定してある。

試したこと

- `gcloud auth activate-service-account --key-file`でadmin sdkファイルを指定してみる。

## 解決策

調べたところ、以下のコマンドで「デフォルトアカウント」を設定する必要があったらしいです。

```bash
gcloud auth application-default login
```

[Google: could not find default credentials · Issue #5 · circleci/docker-hello-google](https://github.com/circleci/docker-hello-google/issues/5)

## 解説

ユーザーのプロジェクトへの権限とかの credential の情報は、Application Default Credentials (ADC) で取得する必要があって、それを取得するには、`gcloud auth login`ではなく、`gcloud auth application-default login`らしいです。

[gcloud auth application-default | Cloud SDK Documentation](https://cloud.google.com/sdk/gcloud/reference/auth/application-default)
[02] C言語でコンソールから関数を呼び出す機構の振り返り ...ファイル構成とMakefile


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/fc185b5da0509b9a631f|


# はじめに

本記事の趣旨は「[01 概要](https://qiita.com/robozushi10/items/40b3fc1791a1bab51e4a)」に記しているが、
13年前(=2008年) に職場のプログラムの挙動をマネて実装した
「コンソールから関数を呼び出す機構」の振り返りである.

本項では「ファイルの構成」と「Makefile」について記す.

# ファイル構成

make 実行後(コンパイル & リンク後)の状態である

```bash
.
|-- Makefile
|-- test_driver.c ..... 今回デバッグしたい関数が実装されたコード
|-- priv_cfn_invoke.h . stdin からの入力待受け、および、test_driver.c の公開関数呼び出し処理の宣言部
|-- cfn_invoke.c ...... 上記の priv_cfn_invoke.h の実装部
|-- mk_sym_tbl.rb ..... 生成された *.o から readelf -s を使って公開関数名を抽出する
|-- cfn.extern.h ...... 上記 mk_sym_tbl.rb から生成された関数の extern宣言. 
|                       コンパイル&リンクエラー回避のために用いる.
`-- cfn.tbl.h ......... 上記 mk_sym_tbl.rb から生成された関数名と関数アドレスを定義したヘッダ

```

# Makefile

```makefile
SRCS = test_driver.c
OBJS = $(SRCS:.c=.o)
MUSTSRC = cfn_invoke.c priv_cfn_invoke.h 

all: $(SRCS)
	gcc -c $(SRCS)
	./mk_sym_tbl.rb $(OBJS)
	gcc -g $(MUSTSRC) $(OBJS)
clean:
	rm -f *.o *~ a.out
```
クロップした画像をCloud Storageにアップできなかった 〜HTMLCanvasElement.toBlob()でうまいことBlobを渡せなかった話〜


input した画像を Firebase Storage に保存する実装をする方法を調べたら、大体 `type = "file"`の input タグから持ってくるみたいな見本が出てきますが、自分が触った実装は、少しイレギュラーなやつで、そこで詰まったことを書いときます。
フロントはVue.jsで、バックエンドはNode.jsの実装です。

**結論としては、**`HTMLCanvasElement.toBlob()`**をうまいこと使えてなかっただけでした。**


## 実現したいこと
自分がやった実装では、input から File を直接持ってくるんじゃなくて、[vue-advanced-cropper](https://www.npmjs.com/package/vue-advanced-cropper) っていうパッケージで、画像をクロップする必要がありました。

なので、`getResult().canvas`で返ってくる形式が File じゃなくて、 HTMLCanvasElement[*1](#HTMLCanvasElement) って形式の Object だったので、それを頑張って Cloud Storage に保存できる形式にする必要がありました。

Firebase の Cloud Storage に保存できる Object の形式は、Blob、File、Uint8Array ってやつ、あとは、`putString()`ってメソッド使えばなんか文字列もいけるらしいです。詳しくは知りません[*2](#Firebase Cloud Storage)。

つまり、クロッパーで返ってきた HTMLCanvasElement を、上のどれかの形式にすればいいって話です。HTMLCanvasElement に、`toBlob()`ってメソッドがあったので、それで Blob にちゃちゃっと変換すればいいと思ったのですが、そこで詰まったのと解決法を書きます。

## 解決法
[完成形見たい人はここ](*完成形)
### 失敗１
これはまあまあ論外のやつです。`toString()`的なやつと思いました。

```typescript
async UploadFile(): void {
  const storageRef = firebase.storage().ref()

  // canvasElement(HTMLCanvasElement)の取得
  const canvasElement = this.$refs.cropper.getResult().canvas

  const blob = canvasElement.toBlob()

  await storageRef.child('path').put(blob)
}
```
Cloud Storage には、儚く「undifined」と書かれた9バイトの`application/octet-stream`ファイルが上がっていました（Cloud Storage のデフォルトらしいです）。

## 失敗2
この辺からガチでわかんなくなりました。Blob自体は、`toBlob()`の引数のコールバック関数で生成されているのは分かったのですが、空の変数用意してってやったせいで、こんがらがりました。

```typescript
async UploadFile(): void {
  const storageRef = firebase.storage().ref()

  // canvasElement(HTMLCanvasElement)の取得
  const canvasElement = this.$refs.cropper.getResult().canvas
  let blob

  canvasElement.toBlob((blobFromCanvasElement: Blob) => {
    blob = blobFromCanvasElement
  })
  await storageRef.child('path').put(blob) 
}
```

こっから、`blob = {} as Blob`とかでリテラル代入したり、どこで undifined になってるか typeof したり、なんか色々しましたが、完成形はめちゃくちゃ簡単でした。

### 完成形
コールバック関数内で済ませればいい話でした。

```typescript
async UploadFile(): void {
  const storageRef = firebase.storage().ref()

  // canvasElement(HTMLCanvasElement)の取得
  const canvasElement = this.$refs.cropper.getResult().canvas

  await canvasElement.toBlob((blob: Blob) => {
     storageRef.child('path').put(blob) 
 )}
}
```

無事サトちゃんが Cloud Storage に保存されました！
<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1805603/c9ffc7fc-3f08-f95e-7786-8740920ddecc.png">

なんか`Array.prototype.forEach()`のコールバック関数とかで、空のリストに追加していく実装をよく見てたので、頭がそれに縛られたミスっぽかったです。
`Array.prototype.forEach()`は undifined を返すけど、`toBlob()`の特徴として、「返り値がない[*3](#HTMLCanvasElement.toBlob())」ってのがあって、それが原因なのかな…？

この記事が誰かの救いになれば :angel: 

## 参考
### HTMLCanvasElement
[HTMLCanvasElement - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement)
### HTMLCanvasElement.toBlob()
[HTMLCanvasElement.toBlob() - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement/toBlob)
### Firebase Cloud Storage
[ウェブでファイルをアップロードする | Firebase](https://firebase.google.com/docs/storage/web/upload-files?hl=ja#upload_files)
ド初心者による、OSS-DB Silverの勉強のための環境構築の記録

# 概要
OSS-DB Silver の勉強のため、Windows10のPCにVirtualBoxを使ってCentOS8の仮想環境を構築し、CentOS8にPostgreSQLをインストールしたので、その過程をまとめました。

データベースの環境構築もVirtualBoxもLinuxも初めて使うド初心者のため、OSS教科書や他のサイトを横断してやっとインストールができたので、自分がもう一度環境構築をやり直すときに見直す用の記録として、また同じくOSS-DBの勉強を始められる方の参考になればと思います！
# VirtualBox、Vagrantのインストール
↓の記事を参考に、VirtualBoxとVagrantをインストールしました。
（こちらの記事を見て「初心者の方の記事って初心者に優しいなあ」と思い、今回の記事を書くきっかけになりました！ありがとうございます！）

https://qiita.com/ume-san/items/6187346b40de39ad7450

# CentOSのインストール
先ほどの記事でVirtualBoxとVagrantをインストールしたら、早速VirtualBoxを使って仮想環境を作り、そこにCentOSをインストールしていきます。
その際とってもお世話になったのがこちら↓の記事。

画面のキャプチャ画像を載せて説明してくださっているので、初心者にもわかりやすい！
こちらの記事でもVirtualBoxのインストールから説明されていますが、こちらではVagrantを使っていないようなので、もしかしたらVagrantは入れなくてもよかったのかも。

https://glodia.jp/blog/9854/

ちなみに、上の記事に沿ってインストールする過程で注意すべきは、

>仮想HDDのサイズを設定します。
>画像のデフォルト値は8GBとなっていますが、今回は10GBに設定しました。

この部分を記事の通りに進めること。
私は最初、ケチってデフォルトの8GBのままに設定して進めたのですが、それだとCentOSをインストールする際に「容量が足りないぞ(意訳)」とエラーが出てしましました。

もしかしたらあとで変更する方法があるのかもしれませんが、ド初心者にはわからず。私は仮想環境を一旦破棄して1からやり直しをしました。
仮想環境の破棄についてはこちら↓の記事を参照しました。

https://pc-karuma.net/virtualbox-machine-del/

# PostgreSQLのインストール前準備
OSS教科書や色々ネットのサイトを漁っていると、どうやらPostgreSQLをインストールするために必要なライブラリやらツールやらが色々あるようなので、そちらを片っ端からインストールしていきました。

こちら↓の記事を参考にしました。

https://qiita.com/ume-san/items/31f661b30e76e5d226d6

いずれのライブラリも、インストールが終わると「インストールが完了しました！」（あるいは英語で“Complete!”など）といった表示が出ます。

（途中で “[y/N]?” みたいなメッセージが表示されることがありますが、「y=yes か N=No かを選べ」というメッセージなので、基本的にはyを入力してEnterを押せばインストールが進みます。）

ここで初めてyumコマンドというものを知ったのですが、Linux(あるいはCentOSだけ？)のyumコマンドって要するにPythonでいうpipコマンドみたいなものなのでしょうか？

yumコマンドについても色々調べると記事が出てきます。

# PostgreSQLのインストール
いよいよPostgreSQLをインストールします。
今回インストールしたのはPostgreSQL13.3というバージョンです。
この部分に関してはたくさん記事が出ていたのですが、私は主にこちら↓の記事に沿って進めました。

https://qiita.com/shadowhat/items/0225dfc4347aa6d260f3

他のサイトも参考にしながら進めたため、既存PostgreSQLのアンインストール、Listenアドレスの設定や、起動スクリプトについて以降の部分は、今回はすっ飛ばしました。

ちなみに、途中でviエディタを使用する部分があり、ここでターミナルでないエディタ画面が開くのですが、最初はこのエディタが入力モードになっていませんでした。

なので、こちら↓の記事に沿って、「i」を入力してEnterを押して入力モードにしました。
保存もこちらの記事を参考に、「:wq!」を入力してEnterで終了しました。
（「:wq」だけだと「!を付けなさい(意訳)」とエラーメッセージが出たため）

http://www14.plala.or.jp/campus-note/vine_linux/operation/vi.html

# 完了！
ここまで作業が完了したところで、OSS教科書に従って、ターミナル上でサーバーの起動、動作確認、サーバーの停止をするところまで確認ができました。めでたしめでたし。

以上、環境構築についてのまとめ、というよりむしろ参考になった記事のリンク集に近いものになってしまいました。
参考にさせていただいた記事を書かれたみなさま、ありがとうございます！
これから勉強を始められる方の何かの参考になれば幸いです！
# リンクを貼ったサイト以外の参考文献はこちら
・福岡博、笠原辰仁、宇山公隆 著、満川一彦 監修『OSS教科書 OSS-DB Silver Ver.2.0対応』翔泳社
Django+VSCode+Selenium環境で起こったトラブルシューティング


#なぜ書いたか
1. 何度か同じミスでハマってしまったので、再発防止に。
1. ミスを整理して言語化する事で、自分の理解を深めるため

# 環境
- Python ：3.7.4
-  VSCode：1.58.2


##venvで作った仮想環境で実行できない
### 原因｜VScodeコンソールのwslからpythonファイルを実行していなかった
VScodeコンソールのwslのコマンドからの実行と、VSデバッグ機能からの実行では参照するpython環境が違っていた。
wsl：仮想環境上のpython環境
デバッグ機能:vscode設定上でインタープリタとして設定されているpython環境

###対策案
1. wsl上からコマンドで実行（vscodeが勝手に仮想環境を使ってくれる？）
1. vscodeのインタープリタを仮想環境上のものに設定。（インタープリタ選択画面から仮想環境上のpython.exeを指定すればできるはずだが仮想環境にexe見当たらず）


##インストールしたはずのライブラリが認識されずデバッグが失敗
#### 原因｜PC内に複数のpython環境があり、インストールした環境とデバッグ実行に参照していた環境が異なっていた。
計3つの環境があった
1. 公式python
2. anaconda
3. 今回作成の仮想環境

wsl→③
vscodeデバッグ機能→②
を参照していたために、wslから③環境にライブラリをインストールしてもデバッグ機能で実行すると参照できなかった。

####対策｜
②環境を削除し、デバッグ機能→①参照するように変更


##環境変数を通してもVSCodeのPowerShellからPythonが実行できない。
####原因｜不明。VSCode経由でない方法だと実行できたので、環境変数の問題ではないところまでは確認。
####対策｜コマンドを「Python」ではなく「Py」にすると実行できた。インタラクティブモードでの実行になるらしい。
####参考URL｜https://gammasoft.jp/blog/resolve-not-to-run-python/

##自作モジュールのimportに失敗(mod1.pyからmod2.pyのimportに失敗)
mod1.pyを直接実行していた場合にはimportに成功していたが、DjangoProjectに含めるとし失敗した。

DjangoProject/
　├ DjangoApp/
　　├ urls.py/
　　└ 自作パッケージ/
　　　　　├ mod1.py/
　　　　　└ mod2.py/
####原因｜実行されるファイルがmod1.pyから変わってしまったため、import時に参照されるディレクトリが変わってしまったこと
####対策｜相対インポートであることを明示的に記述する　　
import mod2 →　from . import mod2
####参考URL｜https://note.nkmk.me/python-relative-import/

##VSCodeターミナルから実行した場合とVSCodeのdebugモードにおける基準パスの違い
開発中にDjangoの実行方法を「VSCodeターミナルからrunserver」->「VSCodedebugモード」に変更。変更前では問題なく動いていたSeleniumが、変更後に↓のようなエラーが発生。
> selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

#### 原因｜各実行方法で基準となるディレクトリが異なっていた
- 変更前：Djangoプロジェクトのmanage.pyのあるディレクトリ
- 変更後：VSCodeで開いているフォルダのディレクトリ

#### 対策｜（暫定）VSCodeで開くフォルダをDjangoプロジェクトのディレクトリと一致させる。

## ***.htmlファイルがvscodeにhtmlファイルとして認識されない
Djangoプロジェクト内に作成したhtmlファイルとして認識されず、シンタックスハイライトや拡張機能によるスニペットも利用できない。「コマンドパレット」→「言語モードの変更」をしようとしても言語モードの候補にHTMLがない。
#### 原因｜***.htmlファイルがDjangoのテンプレートとして認識されていたため。
#### 対策｜
1. VScodeにDjangoの拡張機能を追加。
1. 言語モードの変更で「Django HTML」を選択
#### 参考｜VSCodeのsetting.jsonの変更でも対応可能らしい。
https://www.it-swarm-ja.com/ja/html/django%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%A8%E3%81%97%E3%81%A6%E8%AA%8D%E8%AD%98%E3%81%95%E3%82%8C%E3%82%8Bhtml%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB/834360627/
【Nuxt】ページ遷移したいときに

```vue
<template>
  <section class="container">
    <p>{{ message }}</p>
    <hr>
    <router-link to="price">priceページに遷移</router-link>
  </section>
</template>

<script>
export default {
  data: function() {
    return{
      message: 'がんばれたけし!'
    }
  }
}
</script>
```

``<router-link to="price">priceページに遷移</router-link>``
このrouter-linkコンポーネントを使えばページ遷移をすることができる。

``to=""``ここには、移動したいページのpathを記述すればいい。
3.15(標準) 正規分布3 (方針で偶関数，奇関数を解説)

## 方針

偶関数，奇関数について解説する．

### 偶関数，奇関数

---

実数直線上に定義する関数f(x)が

```math
f(-x)=f(x)
```

を満たす時，fは偶関数であると言い，fのグラフはy軸で対称となる．またf(x)が

```math
f(-x)=-f(x)
```

を満たす時，fは奇関数であると言い，fのグラフは原点で対称となる．

---

奇関数の積分は0であることを用いる．

## 答案

```math
g(x)=\frac{x^k}{\sqrt2\pi}\exp(-\frac{x^2}{2})
```

と置くと，kが奇数の時

```math
\begin{align}
g(-x)&= \frac{(-x)^k}{\sqrt{\sqrt{2\pi}}}\exp(-\frac{(-x)^2}{2})\\
&= \frac{-x^k}{\sqrt{2\pi}}\exp(-\frac{x^2}{2})\\
&= -g(x)
\end{align}
```

より，gは奇関数なので

```math
\mathbb{E}_{X\sim\mathcal{N}(0,1)}[X^k]=\int_{-\infty}^\infty g(x)dx=0
```

kが偶数の時，Y=X^2と置くと

```math
\begin{align}
\mathbb{E}_{X\sim\mathcal{N}(0,1)}[X^k]&= \mathbb{E}_{Y\sim\chi_1^2}[Y^{k/2}]\\
&= \int_0^\infty\frac{(\frac{1}{2}^{1/2}}{\Gamma(\frac{1}{2})}y^{\frac{k+1}{2}-1}\exp(-\frac{1}{2}y)\\
&= \frac{(\frac{1}{2})^{1/2}}{\Gamma(\frac{1}{2})}\frac{\Gamma(\frac{k+1}{2})}{(\frac{1}{2})^{\frac{k+1}{2}}}\int_0^\infty\frac{(\frac{1}{2})^{\frac{k+1}{2}}}{\Gamma(\frac{k+1}{2}}y^{\frac{k+1}{2}-1}\exp(-\frac{1}{2}y)dy\\
&= 2^{k/2}\frac{\Gamma(\frac{k+1}{2})}{\Gamma(\frac{1}{2})}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
[シリーズ 全6回] C言語でコンソールから関数を呼び出す機構の振り返り

# はじめに

本記事の趣旨は「[01 概要]((https://qiita.com/robozushi10/items/40b3fc1791a1bab51e4a))」に記しているが、
13年前(=2008年) に職場のプログラムの挙動をマネて実装した
「コンソールから関数を呼び出す機構」の振り返りである.

|コンテンツ|実装時期|
|:--|:--|
|[[06] C言語でコンソールから関数を呼び出す機構の振り返り ...ソースコード全文](https://qiita.com/robozushi10/items/39baa6ea933f75f76634)|2008/11|
|[[05] C言語でコンソールから関数を呼び出す機構の振り返り ... コンソールからの関数呼び出し実行](https://qiita.com/robozushi10/items/80a898e3da187255e1e3)|2008/11|
|[[04] C言語でコンソールから関数を呼び出す機構の振り返り ... readelf -s の実行](https://qiita.com/robozushi10/items/e3d7bba126d438e5cbfd)|2008/11|
|[[03] C言語でコンソールから関数を呼び出す機構の振り返り ...ファイル構成とMakefile](https://qiita.com/robozushi10/items/df6314d73803502f9435)|2008/11|
|[[02] C言語でコンソールから関数を呼び出す機構の振り返り ...ファイル構成とMakefile](https://qiita.com/robozushi10/items/fadddc25d0e238c39513)|2008/11|
|[[01] C言語でコンソールから関数を呼び出す機構を作ったときのメモ ... 概要](https://qiita.com/robozushi10/items/40b3fc1791a1bab51e4a)|2008/11|
NCMBのSwift SDKを使っていて、SwiftUI上で文字の取得ができないのを解決する

NCMB（ニフクラ mobile backend）のSwift SDKを使えば、SwiftUIアプリなどでの開発がとても楽に行えるようになります。

しかし、データストア（データベース）のオブジェクトを使っている時に、直接データを指定すると表示できないという問題に遭遇しました。

## 現象

たとえば次のようにしてテキストを表示しようとしました。データストアでは文字列以外の情報も扱えたり、キー内のデータが nil であることもあるので `??` を使って代替の文字列を用意しています。

```swift
Text(thread["title"] ?? "")
```

これを実行すると、テキストが表示されません。

![ScreenShot_ 2021-08-07 11.31.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/338c4be6-4c66-3eff-8d77-85740a8bd2a1.png)


## 解決策

解決策としては `as String` を付けることでした。

```swift
Text((thread["title"] ?? "") as String)
```

このようにすると、テキストが表示されるようになります。

![ScreenShot_ 2021-08-07 11.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/0ce69929-9387-c2ea-efde-3f22ddf0a216.png)


## 注意点

ObservableObjectとして定義した際にはこのような状況になった覚えがないので、ViewのStateとしてデータストアを定義した時に起こる可能性があります。Xcodeは12.5.1、Swift 5.4.2で発生しています。なお、Viewの中でfunを定義して、そこから返す場合には問題ありませんでした。

## まとめ

テキスト（に限らないと思いますが）がうまく出ないときには、この方法を使ってみてください。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
リモートデスクトップ接続の履歴を削除する

リモートデスクトップの履歴の消し方です。

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/f11780f8-6fce-1309-8bf6-8752323e40ef.jpeg)

※レジストリを触るので、間違えて編集してしまうとPCが動かなくなる可能性があります。注意してください！

# 手順
1. 「スタート」→「ファイル名を指定して実行」をクリックする。
    ※ショートカットなら「Win + R」
    ![002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/b86fd144-e9e5-789f-983f-cc5a6043a3c7.jpeg)

1. 「regedit」と入力し、「OK」をクリックして、レジストリエディタを立ち上げる。
    ![003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/6ce015c3-9826-dee0-ff37-f434dc658de3.jpeg)

1. レジストリエディタから、以下のキーを選択する
    HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default
    ![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/0a1d14d5-7232-e2ee-29fc-cacb7d21b0fc.jpeg)

1. 「データ」項目から、削除したいサーバを選択し、削除する。
    ![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/9294cd5c-6bad-5320-f9c2-dc473a14903d.jpeg)

1. 履歴が削除されました。
    ![007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/abbf6401-516b-9f6f-066e-e42614edc861.jpeg)

もっと簡単に削除できるようにしてほし～い。
SQLインジェクションについて

# 目的
SQLインジェクションについて理解を深める。

# 目次

1. [SQLインジェクションとは](#sqlインジェクションとは)
1. [SQLインジェクションの対策](#sqlインジェクションの対策)
1. [特殊文字の変換](#特殊文字の変換)
1. [より厳格なSQL文の生成](#より厳格なsql文の生成)
1. [プレースホルダー](#プレースホルダー)

# SQLインジェクションとは

`SQLインジェクション`とは、「Webページのテキスト入力欄」や「URL」などにSQL文の断片を埋め込むことで、データベースを改ざんしたり不正に情報を入手する手法のことです。

# SQLインジェクションの対策

`SQLインジェクション`の対策としては以下の2つが挙げられます。

- 特殊文字の変換
- より厳格なSQL文の生成

# 特殊文字の変換

基本的な対策としてあげられるものが、SQLにおいて意味を持つ特殊文字のエスケープです。
SQL文中では`「'」`が文字列の終端を意味していることがポイントです。

たとえば、データベース内に格納された「user_id」と「password」が一致すると、ログインなどの認証を認めるアプリがあった場合、認証に用いられるSQL文は以下になります。

```sql:
SELECT * FROM users WHERE user_id='$uid' AND password='$pwd'
```

ここに以下のように入力します。

```sql:
$uid  tarou
$pwd  ' OR 'A'='A
```

すると前述のSQL文は以下のようになります。

```sql:
SELECT * FROM users WHERE user_id='tarou' AND password='' OR 'A'='A'
```

もし、特殊文字である「'」をエスケープしていなかった場合、WHERE句の中では「user_id='tarou'」に加え、「password=''と'A'='A'」の2つの条件をORで判定することになります。

この「password=''」と「'A'='A'」は「OR」でつながっているため、どちらかがtrueの場合は認証が認められてしまいます。「'A'='A'」は確実にtrueのため、「user_id」と「password」が一致していなくても、user_idだけ正しければ認証が通ってしまいます。

しかし、特殊文字をきちんとエスケープした場合はユーザーからの入力の`「'」`は単なる文字列として扱われるため、「password」に対する入力が「' OR 'A'='A'」という一連の文字列となります。このようなパスワードを設定していない限り、「password」不一致となるため認証は認められません。

実際にエスケープを行う場合は、フォームから`「'」`を含む文字列が送信された場合に、別の記号で置き換えるような実装をすることで実現できます。

# より厳格なSQL文の生成

ユーザーからの値をSQLへ反映する前に、SQL文の構造を確定する仕組みをとることで、より厳格に対策できます。SQL文確定後にユーザーからの値を入れて実行するため、ユーザーの入力値によってSQL文が変更されることはありません。

先ほどの例を用いると、データベースに対する処理を行う前に、以下のSQLを用意しておきます。

```sql:
SELECT * FROM users WHERE user_id=? AND password=?
```

ここで、「user_id」と「password」の値として`「?」`が使われており、これをプレースホルダーといいます。

# プレースホルダー

プレースホルダーはユーザーの値が入力されるまでの一時的な仮引数のようなものです。あらかじめ確定したSQLにおいて、可変の値が入力される箇所に配置します。

このようにプレースホルダーを用いて設定すれば、「usersテーブルにおいてuser_idとpasswordの組み合わせが一致するかどうかを判定できる」という構文を事前に確定することができます。この後ユーザーからどのような値が入力されようとも、上記の構文の中でSQLが実行されることになり、SQLインジェクションを防ぐことが可能です。

すなわち、「password」として「' OR 'A'='A'」と入力をしても、これらは単純な文字列として認識されます。
NCMBのSwift SDKをSwift Packagesでインストールする

NCMB（ニフクラ mobile backend）のSwift SDKをインストールする方法は2つ用意されています。

- CocoaPodsを使った方法
- Swift Packagesを使った方法

インストールの手軽さからいうとSwift Packagesを使った方法かなと思います。この方法を解説します。

## 今回のプロジェクト

今回は言語がSwift、インタフェースがSwiftUI、ライフサイクルはSwiftUI Appとしています。

## SDKのインストール

FileメニューからSwift Packages > Add Package Dependencyと選択します。

![ScreenShot_ 2021-08-02 9.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/dea9dcdc-3368-7992-67d4-8375355bf2ff.png)

出てきたダイアログでSwift SDKのGitリポジトリURLを入力します。GitHubのリポジトリでHTTPSとして取得できるもの、または下記URLになります。

![ScreenShot_ 2021-08-02 9.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8d5d62cd-cf3f-f535-8f71-f1e61569674a.png)

```
https://github.com/NIFCLOUD-mbaas/ncmb_swift.git
```

バージョンは最新のものでかまいません。

![ScreenShot_ 2021-08-02 9.36.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/9e873825-38be-97e2-edd3-44776cc72d22.png)

後はFinishボタンを押せば完了です。

![ScreenShot_ 2021-08-02 9.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/7f74527e-8de8-d5cf-b433-c16b538c24f1.png)

## 初期化

今回はSwiftUIを利用しています。ライフサイクルもSwiftUIです。

まずSDKをインポートします。

```swift
import SwiftUI
import NCMB
```

次に `scenePhase` を追加します。

```swift
@main
struct forumApp: App {
    // 追加
    @Environment(\.scenePhase) private var scenePhase
```

後は body 内で `onChange` を使って初期化します。

```swift
var body: some Scene {
    WindowGroup {
        ContentView()
    }.onChange(of: scenePhase) { scene in
        switch scene {
        case .active:
            // キーの設定
            let applicationKey = "YOUR_APPLICATION_KEY"
            let clientKey = "YOUR_CLIENT_KEY"
            // 初期化
            NCMB.initialize(applicationKey: applicationKey, clientKey: clientKey)
        case .background: break
        case .inactive: break
        default: break
        }
    }
}
```

## まとめ

CocoaPodsを使うとXcode workspaceファイルが生成されたりするので、若干プロジェクトが大規模になってしまうかと思います。Swift PackagesならばXcode Projectのまま進められるので手軽そうです。もちろん対応ライブラリの状態によって使い分ける必要があるかと思いますので、皆さんのプロジェクトに合わせてお使いください。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
Java 概要

#学習の目標
プログラミング言語のJavaの学習をします。学習の備忘録としてQiitaを使ってアウトプットしていきます。
まず、Javaの概要を学習します。

#目次
* Javaとは
* Javaの特長
* Javaの種類

#Javaとは
Javaとは、1995年に米国のサンマイクロシステムズ社（現オラクル社）がC++をベースとして開発したプラットフォーム非依存のオブジェクト指向のプログラミング言語です。
Javaは、プログラミン言語ランキングで常に上位になっているプログラミング言語で、多くの有名企業がJavaを利用したWebアプリケーションを構築しています。

#Javaの特長
プログラミング言語としてのJavaの特長を3つ説明します。

###コンパイル言語
プログラミング言語は大きく__「コンパイル言語」「スクリプト言語」__の2つに分類されます。
コンパイル言語は、予めコンパイラによってコンパイル（人間が描いたソースコードを機会が読み取ることができるように変換する作業）を行ってからプログラムを実行するものです。
それに対し、スクリプト言語は、事前にコンパイルしておくのではなく、実行時に逐次逐次変換を行っていくプログラミング言語です。
![Qiita](https://image.docbase.io/uploads/906cbb19-487b-4509-b1a0-324f18798c78.png)
代表的なコンパイル言語には__「Java」「C」「C++」__など、スクリプト言語には__「JavaScript」「Python」「Ruby」「PHP」__などがあります。
スクリプト言語は実行するたびに解釈を行うため、プログラムが途中までできた状態でも実行することができ、実行とプログラミングのサイクルを素早く回しやすい利点があります。コンパイルに時間をかける必要もありません。一方で、コンパイル言語は、事前のコンパイルにより実行する度にコードを変換する必要がないので、高速に動作します。また、文法がおかしかったり、エラーになる可能性があったりするコードをコンパイルという工程で検出することができます。もちろん全てがわかるわけではありませんが、スクリプト言語においては実行してみないとわからないエラーも、コンパイル言語では早い段階で段階で気付ける可能性が上がります。このコンパイルでわかるエラーのことを__「コンパイルエラー」__と言います。
なお、これらは一般的な比較論にすぎず、書いたプログラムや実行環境などにより状況は異なります。大事なのはそれぞれの特長（得手・不得手）があり、使いたいシーンに応じて使い分ける必要があるということです。どちらか一方が優れているということではありません。

###プラットフォーム非依存
Javaは「一度書けば、どこでも動く」という思想があり、どんな環境でも動くプログラムを作れるプログラミング言語です。
今となっては当たり前になりつつありますが、Javaが登場する以前は、Windowsように作られたプログラムは、Windows上でしか動作しない、Macように作られたプログラムは、Mac上でしか動作しなというのが当たり前だったため、当時は画期的で、Javaが普及した1つの要因となりました。

###オブジェクト指向
オブジェクト指向とは、拡張性や保守性の高いプログラムを書くための考え方です。
プログラムが大規模になると複雑になり過ぎて、プログラムの追加や修正が難しくなります。オブジェクト指向プログラミングであれば、そのような問題に悩まず、大規模なプログラミングを作成できます。これもJavaが普及した1つの要因です。

#Javaの種類
###Javaのエディション
Javaには、目的別に3つのエディションがあります。

####Java SE (Java Platform, Standard Edition)
「Java SE」は、多くのJavaプラットフォームプログラムで利用される「Java API」の集合体で、標準機能をまとめたものです。

####Java EE (Java Platform, Enterprise Edition)
「Java EE」は、「Java SE」にWebアプリケーション用の拡張ライブラリなどを追加したものです。
Webアプリケーションを構築する場合は、このエディションを使用します。

####Java ME (Java Platform, Micro Edition)
「Java ME」は、リソースが制限されたデバイスなどで実行するアプリケーションの作成に必要な機能をまとめたエディションです。

###Javaの環境
####JRE (Java Runtime Environment)
Javaで作られたアプリケーションを動かすために必要なソフトウェアです。

####JDK (Java SE Development Kit)
JavaSEを利用してJava言語でプログラム開発を行う際に必要な開発用ソフトウェアをまとめたパッケージです。Javaプログラム開発を始めるための最低限のソフトウェアのセットで、Java SE、JREなどが含まれています。
[01] C言語でコンソールから関数を呼び出す機構の振り返り ... 概要


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/fc185b5da0509b9a631f|


# はじめに

13年前(=2008年) に、次のような「コンソールからの関数呼び出し」を作成していたようである.
良い機会なので、C言語のポートフォリオ(作品)を兼ねて、該当コードを振り返ることにした.

> 当時の仕事で開発していたプログラムは、
stdin(標準入力)からの次の関数呼び出しの機構をサポートしていた.
　
この機能が存在した理由は以下であった.
プログラム実行環境には ファイルシステムが存在しない.
そのために次の制約があり、少しでもデバッグを捗るようにするためであった.
・gdb は使えない
・ログファイルの書き出しもできない


## 詳細

次のような仕組みで実装していた

### 挙動

```
(1) デバッグ対象のプログラムコード `*.c` が存在する.
　⬇️ 
(2) `*.c` をコンパイルして `*.o` を作成する
　⬇️ 
(3) `*.o` に対して `readelf -s` を実行して公開関数名を抽出する
　⬇️ 
(4) (3) で抽出した公開関数名をヘッダファイルに書き出す
　⬇️ 
(5) (4) のヘッダファイルを include して、コンソールから関数呼び出し機能も持つコードも含めてリンクする
　⬇️ 
(6) 作成された実行ファイル a.out を実行する
　⬇️ 
(7) a.out の stdin から、公開関数 (static 関数以外) とその引数を入力する
　⬇️ 
(8) 上記 (7) で入力した関数が実行される
```

### 実行例

次のような公開関数 piyo が存在した場合の実行例である.

#### コード

```c
void
piyo(char * mesg, char * mesg2)
{
    printf("(%s , %s) at piyo()\n", mesg, mesg2);
}
```

#### 実行例

下図 2行目で関数 piyo を呼び出して、6行目に関数piyo のログが表示されている.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/8c04a494-dbb1-2d27-021a-ce6f41f0cd9f.png)
NCMBのSwift SDKを使ってポインターデータを扱う

NCMB（ニフクラ mobile backend）では各種プラットフォーム向けにSDKを出していますが、今回はSwift SDKに関する記事です。まだ開発途中ということもあって、実装されていない機能もあります（執筆時点でのバージョンは1.2.0です）。今回はデータストア（クラウドデータベース）におけるポインター（データを1対1の関係で連携させるもの）の使い方を紹介します。

## ポインターとは

ポインターはあるデータと別なデータを1対1の関係で連携させるものです。個人データにおける住所の都道府県マスタと連携させるようなイメージです。

データ形式は次のようになっており、他の一般的なデータ形式（文字列や数字など）と比べると特殊です。

```json
{
    "__type": "Pointer",
    "className": "連携先のデータストアクラス名",
    "objectId": "連携先のデータのユニークID"
}
```

このフォーマットに従ってデータを保存すれば、ポインターが扱えるようになります。

## 今回のプロジェクト

今回は言語がSwift、インタフェースがSwiftUI、ライフサイクルはSwiftUI Appとしています。

## SDKのインストール

FileメニューからSwift Packages > Add Package Dependencyと選択します。

![ScreenShot_ 2021-08-02 9.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/dea9dcdc-3368-7992-67d4-8375355bf2ff.png)

出てきたダイアログでSwift SDKのGitリポジトリURLを入力します。GitHubのリポジトリでHTTPSとして取得できるもの、または下記URLになります。

![ScreenShot_ 2021-08-02 9.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8d5d62cd-cf3f-f535-8f71-f1e61569674a.png)

```
https://github.com/NIFCLOUD-mbaas/ncmb_swift.git
```

バージョンは最新のものでかまいません。

![ScreenShot_ 2021-08-02 9.36.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/9e873825-38be-97e2-edd3-44776cc72d22.png)

後はFinishボタンを押せば完了です。

![ScreenShot_ 2021-08-02 9.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/7f74527e-8de8-d5cf-b433-c16b538c24f1.png)

## 初期化

今回はSwiftUIを利用しています。ライフサイクルもSwiftUIです。

まずSDKをインポートします。

```swift
import SwiftUI
import NCMB
```

次に `scenePhase` を追加します。

```swift
@main
struct forumApp: App {
    // 追加
    @Environment(\.scenePhase) private var scenePhase
```

後は body 内で `onChange` を使って初期化します。

```swift
var body: some Scene {
    WindowGroup {
        ContentView()
    }.onChange(of: scenePhase) { scene in
        switch scene {
        case .active:
            // キーの設定
            let applicationKey = "YOUR_APPLICATION_KEY"
            let clientKey = "YOUR_CLIENT_KEY"
            // 初期化
            NCMB.initialize(applicationKey: applicationKey, clientKey: clientKey)
        case .background: break
        case .inactive: break
        default: break
        }
    }
}
```

## ポインターのデータ保存

今回は掲示板のようなスレッドクラス（Thread）に幾つかのコメントクラス（Comment）が紐付く形とします。コメントクラスを保存する際に、スレッドクラスのデータをDictionary型で定義します。

```swift
comment["thread"] = [
            "objectId": (thread["objectId"] ?? "") as String,
            "__type": "Pointer",
            "className": "Thread"
        ]
comment.save()
```

## ポインターのデータを使って検索

あるスレッドに紐付くコメントを一覧で取得したい場合、検索条件にスレッドクラスを用います。この時も、ポインターのデータ型にして指定すると、希望した結果が取得できます。

```swift
var query = NCMBQuery.getQuery(className: "Comment")
query
    .where(field: "thread", equalTo: [
        "objectId": (thread["objectId"] ?? "") as String,
        "__type": "Pointer",
        "className": "Thread"
    ])
let results = query.find()
```

## まとめ

ポインター型を使えば、データ同士の結びつきが表現できます。本当は include というメソッドを用意してコメントクラスからスレッドクラスを含めて取得することもできるのですが、まだ用意されていません。これは、今後のバージョンアップで実装されるはずです。また、ポインターの扱いについても、もっと手軽になると思います。

現状のSwift SDKでポインターデータを扱う際には、こちらを参考にしてください。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
実務未経験でエンジニア転職して感じること。〜4ヶ月目〜

##はじめに
遅くなりましたが4ヶ月目の振り返りです！もう8月、、早いですね、、、
**[1ヶ月目](https://qiita.com/makky/items/7fff5aeb1005ce6caf44)**、**[2ヶ月目](https://qiita.com/makky/items/ba83d51911e1cb39b0ed)**、**[3ヶ月目](https://qiita.com/makky/items/de20b90b74c1ba6acfd1)**と書いてきているので、
もしよければあわせて読んでいただければと思います！
では7月、入社して4ヶ月の振り返りしていきます！よろしくお願いします！



##この１か月（入社後3ヶ月〜4ヶ月）で感じたこと
正直、この1ヶ月はこの後の[「１番印象に残ったトピック」](#１番印象に残ったトピック)でお伝えする部分が全てといってもいいぐらいでした。

それ以外の部分で考えるなら、**ユーザー理解のきっかけが多かった**と思います。
クライアントの方と（オンラインですが）直接お話する機会があったり、
今関わっているプロジェクトでの業務が普段実際にクライアントの皆様がされている業務だったり。
実際に使う立場になって感じるでの理解は、全然違うなと改めて思ったので、
自分で意識してこういった機会作っていきたいです。



毎月恒例の1ヶ月でおもしろかった、勉強になった記事です。
・**[2021年のエンジニア新人研修の講義資料を公開しました](https://blog.cybozu.io/entry/2021/07/20/100000#2021%E5%B9%B4%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E7%A0%94%E4%BF%AE%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)**
サイボウズさんが新入社員向けの研修資料を公開されていました。
個人としては資料も分かりやすく、勉強になりましたし、自社の組織に興味を持ってもらう
きっかけとして、これはアリだなと。SNSでも反響大きかったですね。




##１番印象に残ったトピック
###自分が最初から携わった開発がリリースされたこと
先月も
>①自分が少しでも関わった部分が使われるようになったり、リリースされたこと

とトピックであげておりましたが、こちらはコードの一部修正、あるいは検証のみで、
今回は**設計、開発、検証、リリースまで**一貫して関わることができました。

![character_program_happy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883905/e8f9a385-f36f-0ed6-283c-03b7e8381922.png)

（画像はイメージです）


リリースの瞬間は心拍数が上がっていることが自分でも分かるぐらい緊張してました。
なぜ緊張したのか、、振り返ってみると、初めてという部分も大きいとは思いますが、
今回のリリースにともなって不具合が起きたら、、、使いづらくなったりしてたら、、という
不安の部分も大きかったのかなと思います。
でも今考えてみると、リリースする時にはプロダクトが良くなる、良くしたいと思っていることには
変わりないですし、不具合が起こってしまったとしても、使いづらくなったという声が上がって来ても、
最終的にはまた改善していくしかないと思うので緊張しすぎだったのではと思います。

ドキドキしながらリリースを終え、本番環境で動いているところを見た時の
達成感、嬉しさすごかったです。


![pose_kandou_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883905/d3c0eead-3b0c-2d3d-55c2-f40765965bb0.png)

（画像はイメージです２）


とはいえ、リリースして終わりではなく、またお客様からのFBを元に改善はしていきたいです。

実は今回、予定していた日から**１週間延期**してのリリースでした。悔しい。。
延期の理由としては今回２つの環境にリリースが必要でしたが、それぞれへのリリースに
タイムラグが発生することを考えられておらず、不具合が発生してしまうためでした。
今までの個人開発では考える必要がなかったものだったので、検討点として漏れてしまってました。
ここは反省＆改善です。次の開発時にはリリーススケジュールも考慮していきます。



###雑談
何を思ったのか、懸垂マシンなるものを買いました。
家で懸垂やら、ぶら下がりやら、ディップスやらできる器具ですね。
普段から運動や筋トレもする方ではありますが、特に目指しているものがあるわけでもなく、
器具なしで満足してました。
そんな中、なぜか懸垂マシンを購入。届いた時ももはや**何で買ったんやっけ**となる始末。
ただ実際に組み立てて使うと、**楽しい楽しい。**買ってよかったです。
リモートワークが多いので、お手洗いに行ったついでや、小休憩のタイミングで使ってますが
数十秒ぶら下がるだけで身体がすごくスッキリするので、リフレッシュになってます。

せっかくなら懸垂も回数決めてできるようになろうかな（どこを目指しているんでしょうか）
![undou_kensui_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883905/813ac587-90a6-5b19-1738-1c298db10d1c.png)



##最後に
今回は開発リリースしてから、書きたかったので何とか間に合って？よかった。。
毎月この振り返りを書くことで自分への落とし込みにもなってます。理解深まりますね。
未経験から転職したエンジニアがどうなっていくのか、、、~~乞うご期待！~~
3.14(標準) 正規分布2

## 方針

標準正規分布に従う確率変数Xの確率密度関数は，

```math
f_X(x)=\frac{1}{\sqrt{2\pi}}\exp(-\frac{x^2}{2})
```

である．

## 1.答案

```math
\begin{align}
\mathbb{E}_{X\sim\mathcal{N}(0,1)}[X^2]&= \int_{-\infty}^\infty\frac{x^2}{\sqrt{2\pi}}\exp(-\frac{x^2}{2}0dx\\
&= \int_{-\infty}^\infty\frac{x}{\sqrt{2\pi}}\{-\exp(\frac{x^2}{2})\}'dx\\
&= \left[-\frac{x}{\sqrt{2\pi}}\exp(-\frac{x^2}{2})\right]_{-\infty}^\infty+\int_{-\infty}^\infty\frac{1}{\sqrt{2\pi}}\exp(-\frac{x^2}{2})dx\\
&= 1
\end{align}
```

## 2.答案

Y=X^2の分布関数は，

```math
\begin{align}
F_Y(y)&= P[Y\leq y]\\
&= P[X^2\leq y]\\
&= P[-\sqrt{y}\leq X\leq\sqrt{y}]\\
&= \int_{-\infty}^{\sqrt{y}}f_X(x)dx-\int_{-\infty}^{-\sqrt{y}}f_X(x)dx
\end{align}
```

より，

```math
\begin{align}
f_Y(y)&= f_X(\sqrt{y})\frac{1}{2\sqrt{y}}-f_X(-\sqrt{y})(-\frac{1}{2\sqrt{y}})\\
&= \frac{1}{\sqrt{y}}f_X(\sqrt{y})\\
&= \frac{1}{\sqrt{2\pi y}}\exp(-\frac{y}{2})
\end{align}
```

である．従って，

```math
\begin{align}
\mathbb{E}_{Y\sim f_Y}[Y]&= \int_0^\infty\frac{1}{\sqrt{2\pi}}y^{1/2}\exp(-\frac{1}{2}y)dy\\
&= \frac{1}{\sqrt{2\pi}}\frac{\Gamma(\frac{3}{2})}{(\frac{1}{2})^{3/2}}\int_0^\infty\frac{(\frac{1}{2})^{3/2}}{\Gamma(\frac{3}{2})}y^{\frac{3}{2}-1}\exp(-\frac{1}{2}y)dy\\
&= 1
\end{align}
```

## 3.答案

Y=|X|の分布関数は，

```math
\begin{align}
F_Y(y)&= P[Y\leq y]\\
&= P[|X|\leq y]\\
&= P[-y\leq X\leq y]\\
&= \int_{-\infty}^yf_X(x)dx-\int_{-\infty}^{-y}f_X(x)dx
\end{align}
```

確率密度関数は，

```math
\begin{align}
f_Y(y)&= f_X(y)-f_X(-y)(-1)\\
&= 2f_X(y)\\
&= \frac{2}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})
\end{align}
```

より，

```math
\begin{align}
\mathbb{E}_{Y\sim f_Y}[Y]&= \int_0^\infty\frac{2y}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})dy\\
&= \left[-\frac{2}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})\right]_0^\infty\\
&= \sqrt{\frac{2}{\pi}}\\
\mathbb{E}_{Y\sim f_Y}[Y^2]&= \int_0^\infty\frac{2y^2}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})dy\\
&= \int_0^\infty\frac{2y}{\sqrt{2\pi}}\{-\exp(-\frac{y^2}{2})\}'dy\\
&= \left[-\frac{2y}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})\right]_0^\infty+\int_0^\infty\frac{2}{\sqrt{2\pi}}\exp(-\frac{y^2}{2})dy\\
&= \int_0^\infty\frac{1}{\sqrt{2\pi}}t^{-\frac{1}{2}}\exp(-\frac{1}{2}t)dt,\ \ \ \ (t=y^2)\\
&= \frac{1}{\sqrt{2\pi}}\frac{\Gamma(\frac{1}{2})}{(\frac{1}{2})^{1/2}}\int_0^\infty\frac{(\frac{1}{2})^{1/2}}{\Gamma(\frac{1}{2})}t^{\frac{1}{2}-1}\exp(-\frac{1}{2}t)dt\\
&= 1\\
Var(Y)&= 1-\frac{2}{\sqrt{\pi}}
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
PowerShell | バイト換算する（小ネタ）

# PowerShellでバイト換算ができる

バイトに換算したい容量を打ち込むだけ。めっちゃ簡単！笑

```powershell
PS > 10MB
10485760
```

`MB`は`mb`でもいけます。

![IMG_3027 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641252/13871bef-e8f1-64b0-2ae1-8cfa2003981e.jpeg)

## おわりに

使用頻度は少なそうですが、わりと便利では？

Macのターミナルでも同じことができるのかな？と
思ってやってみたけど、ダメでした笑
【Flutter】apkビルド時に「Warning: Mapping new ns xx/common/02 to old ns xx/common/01」が表示される

# はじめに
Flutterでapkビルド時に以下のWarningが出てうざい

```
Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://schemas.android.com/repository/android/common/01
Warning: Mapping new ns http://schemas.android.com/repository/android/generic/02 to old ns http://schemas.android.com/repository/android/generic/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/02 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/02 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
```

# 更新履歴
2021.8.7 初回投稿
2022.2.10 環境変更、手順一部修正

# 環境
- Flutter (Channel stable, 2.10.0, on macOS 11.6 20G165 darwin-x64, locale
    ja-JP)
- Android toolchain - develop for Android devices (Android SDK version 31.0.0)
- Xcode - develop for iOS and macOS (Xcode 13.2.1)
- Chrome - develop for the web
- Android Studio (version 2021.1)
- VS Code (version 1.64.0)


# 参考にしたサイト

https://blog.csdn.net/Calvin_zhou/article/details/117333108

https://se.yuttar-ixm.com/androidstudio-error-01/

# 手順

https://se.yuttar-ixm.com/androidstudio-error-01/

上記のブログの手順で通りやって解消した
0.AndroidStudioでFlutterプロジェクト内のandroidフォルダを開く
1.Project Structure 起動
　　AndroidStudio Bumblebee | 2021.1.1(Mac版)では歯車アイコンをクリックすると表示される。
![スクリーンショット 2022-02-10 10.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/c4ae130e-473c-8eda-6f6f-4781f51be8fd.png)　 
2.Module タブ選択
3.Build Tools Version 31.0.0 → 30.0.* に変更
4.Default Config タブに移動
5.Target SDK Version 31 → 30 に変更
6.OK をクリックして設定変更完了

以上
python：seleniumとBeautifulSoupでwebスクレイピング

# ・Google検索を行い、欲しいデータを取得する。
①検索ワードを入力して、GoogleChromeでGoogle検索
②表示されたWebページの下端の「他のキーワード」を取得
③「他のキーワード」をcsvデータにまとめて、保存

######「テスト」という単語で検索した際に下端に表示された「他のキーワード」
![screen 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698556/9bb71b63-10e7-ed44-0f27-7e9148c9e81c.png)
# ・目次
######1.webdriver_managerのインストール
######2.import
######3.コード
###1.webdriver_managerのインストール
seleniumで使用しているGoogleChromeのバージョンと同じChromeのドライバーを読み込ませる必要がある。
ドライバーの読み込みで苦戦したくないため、webdriver_managerを使用。

```python:webdriver_manager
pip install webdriver_manager
```
参考①：https://pypi.org/project/webdriver-manager/
参考②：https://blog.n-hassy.info/2021/05/selenium-chrome-scraping/#3
###2.import
必要なライブラリをimportする。

```python:import
#1 Chromeのドライバー取得用
from webdriver_manager.chrome import ChromeDriverManager

#2 selenium
from selenium import webdriver

#3 BeautifulSoupと必要なライブラリ
from bs4 import BeautifulSoup
import requests
import time

#4 pandas
import pandas as pd

```
###3.コード
下記の順に記述していく
①seleniumでGoogleChromeを操作して、検索を行う
②BeautifulSoupで「他のキーワード」を取得する
③pandasで結果をcsvデータに保存する

```python:「他のキーワード」の格納先
indexs = []
result = []
```
```python:webdriver
#webdriverの設定、GoogleのURLの指定
url = "https://www.google.com/"
driver = webdriver.Chrome(ChromeDriverManager().install())

#検索するワードをinput
s_word = input()
```
```python:web操作（selenium,BeautifulSoup)
#検索ワードが空欄であれば終了
#検索ワードで検索を行い、ページ下端に表示される「他のキーワード」を取得
while s_word != "":
    
    #GoogleChromeを立ち上げ、Googleページを表示
    #検索入力箇所に検索ワードを入力して、検索（submit）ボタンを押す
    #3秒後、表示されたページのURLを取得
    driver.get(url)
    search = driver.find_element_by_name("q")
    search.send_keys(s_word)
    search.submit()
    time.sleep(3)
    url_cur = driver.current_url

    #BeautifulSoupで「他のキーワード」に表示されている単語を取得
    response = requests.get(url_cur)
    soup = BeautifulSoup(response.content,"html.parser")
    others = soup.find_all(class_="BNeawe s3v9rd AP7Wnd lRVwie")
    words = [i.text for i in others]

    #「他のキーワード」をresultに格納
    #検索ワードをindexsに格納
    result.append(words)
    indexs.append(s_word)

    #検索ワードを再入力、空白なら終了
    s_word = input()

#GoogleChromeを閉じる
driver.quit()
```
```python:pandas
#検索結果をpandas のDataFrameにまとめ、csvで保存
if result != []:
    df = pd.DataFrame(result)
    df.index = indexs
    df.to_csv("other_keyword.csv")
```
##所感
色々な単語のサジェストがわかると面白いかも！と思い、作成。
今更ですが、毎回inputで１個１個入力するのではなく、あらかじめ検索する単語を決めてfor文で進めていく方がスマートかも。

以上。
レンタルポケットwifiで

レンタルした501HWをPCからusb接続しようとしたら繋がらなかった　pcが接続を認識してなかった


借りてきたものについていたケーブルが通信に使えなかった

電源供給だけ?
べつのタイプBにかえたら普通に認識されてドライバをダウンロードできた
webスクレイピングでpythonのseleniumを使用するときにchrome webdriver のPATHを通す方法

#前提
## 環境：
- mac OS
- anaconda python
- IPython

## インストールしたもの：
- selenium
- chrome webdriver -> [download](https://chromedriver.chromium.org/downloads)

## 実行内容：

```python:
from selenium import webdriver
driver = webdriver.Chrome()
```
## エラー内容:

```
WebDriverException: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home
```


# エラー解決までの手順

## PATHの確認
### IPythonでPATHを確認する方法
コンソール上で次を入力

```
%env PATH
```
出力

```
/opt/anaconda3/bin:/opt/anaconda3/condabin:/usr/bin:/bin:/usr/sbin:/sbin
```
__出力されたディレクトリのどれかに chrome webdriver の実行ファイルを保存__

## chrome webdriver 実行を許可
ファイルを実行すると次のメッセージが出ます。
![スクリーンショット 2021-08-06 15.04.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552712/9e7fc74e-db2b-6462-7ccd-ee275663bdaa.png)

macの”セキュリティとプライバシー” で実行を許可してください。

以上です。
【Flutter】apkビルド時にエラー(com.android.ide.common.signing.KeytoolException: Failed to read key )

# はじめに
Flutterでapkをビルドしようとしたら以下のようなエラーが表示された

```
Failed to read key AndroidDebugKey from store ...
```
# 更新履歴
2021.8.7 初回投稿

# 環境
- Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale ja-JP)
- Android toolchain - develop for Android devices (Android SDK version 31.0.0)
- Xcode - develop for iOS and macOS
- Chrome - develop for the web
- Android Studio (version 2020.3)
- VS Code (version 1.59.0)

# 参考にしたサイト
https://stackoverflow.com/questions/67631927/error-building-aab-flutter-android-integrity-check-failed-java-security-n

# エラー内容

```
* What went wrong:
Execution failed for task ':app:packageDebug'.
> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
   > com.android.ide.common.signing.KeytoolException: Failed to read key AndroidDebugKey from store "/Users/kazukoba/.android/debug.keystore": Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available
```

# 修正方法
~/.android/配下の「debug.keystore」を削除して再度ビルドしなおせばOK

```
% cd ~/.android
% rm debug.keystore
```

以上
geopandas インストールはチェンネルに注意

**実行環境** Windows10, conda 4.8.3, python 3.9.5, geopandas 0.9.0

## はじめに
普段シェープファイルの処理は [PyShp](https://pypi.org/project/pyshp/) で間に合わせているのですが、Pandas-like な処理をしたいとか、大量のレコードを扱いたいとか多々あるので、[GeoPandas](https://geopandas.org/) に手を出すことにしました。

さっそく conda の仮想環境から GeoPandas をインストールして使おうとしたのですが、**例によってつまづいた** のでここに記します。

Qiita でも既に同様の内容の記事はいくつかありますが、記録という意味も込めて投稿しています。

要約すると以下の通り。

エラー内容: **GeoPandas をインストールできない、またはインポートできない**
原因: **パッケージをインストールするチャンネルの混在**
対応: **仮想環境でパッケージ経由チャンネルを conda-forge にそろえる**

分かっている人には当たり前のことなのでしょうけれど。

以降詳細です。

## Try 1
以下の条件で GeoPandas をインストールしてみる

Python: **default** チャンネルからインストール
GeoPandas: **conda-forge** チャンネルからインストール


```:インストールはできる
$ conda install -c conda-forge geopandas
```

```:インポートができない（エラーレコードを一部省略）
>>> import geopandas
    ...
    OSError: could not find or load spatialindex_c-64.dll
```

spatialindex_c-64.dll が見つからない、またはロードできませんと言われました。

失敗。


## Try 2
以下の条件で GeoPandas をインストールしてみる

Python: **default** チャンネルからインストール
GeoPandas: **default** チャンネルからインストール

```:インストールできない（エラーレコードを一部省略）
$ conda install geopandas
  ...
  Found conflicts! Looking for incompatible packages.
  ...
  UnsatisfiableError: The following specifications were found to be incompatible with each other:
```

競合が見つかりました、仕様は互換性がありませんでした、みたいなことを言われます。

失敗。


## Try 3
以下の条件で GeoPandas をインストールしてみる

Python: **conda-forge** チャンネルからインストール
GeoPandas: **conda-forge** チャンネルからインストール

```:まず、conda-forgeからPython本体をインストール
$ conda install -c conda-forge python
```

```:つぎに、GeoPandasをインストール
$ conda install -c conda-forge geopandas
```

```py:GeoPandasをインポート
import geopandas
```

これでうまくいきました。


## チャンネルとは

そもそも conda-forge とは何か、という今更な疑問に直面したので調べました。

> conda-forge is a GitHub organization containing repositories of conda recipes.

（[conda-forge のトップページ](https://conda-forge.org/)からの抜粋）

つまり conda 公式リポジトリではなく、別の GitHub のリポジトリで管理されているPython パッケージ集の１つということですよね。

言ってしまえばその通り。

なお、conda info コマンドでデフォルトチャンネルの URL が出てきます。

```:一部のみ抜粋
$ conda info
  ...
  channel URLs : https://repo.anaconda.com/pkgs/main/win-64
                 https://repo.anaconda.com/pkgs/main/noarch
                 https://repo.anaconda.com/pkgs/r/win-64
                 https://repo.anaconda.com/pkgs/r/noarch
                 https://repo.anaconda.com/pkgs/msys2/win-64
                 https://repo.anaconda.com/pkgs/msys2/noarch
  ...
```

ちなみに、[pip](https://packaging.python.org/key_projects/#pip) は [PyPI](https://pypi.org/) がチャンネルになります。

さらにそもそもな話ですが、

[GeoPandas 公式ホームページ](https://geopandas.org/index.html) -> [Getting started](https://geopandas.org/getting_started.html) -> [Installation](https://geopandas.org/getting_started/install.html) 

の Using the conda-forge channel の Note に、

`両方のチェンネルのパッケージの混在はインポートの問題を引き起こすので、デフォルトか conda-forge のどちらかから、すべてをインストールすることを強く勧めます`

みたいなことがしっかり書いてありました。
反省。


## 最後に
Python 本体と GeoPandas をインストールするときのチャンネルを conda-forge に統一することで、GeoPandas を問題なく使えるようになりました。

conda を使う以上 pip は使わない、という基本的な心掛けはもっていましたが、conda の仮想環境のチャンネルの混在は気にしていませんでした。

これを機に仮想環境を再構築した次第です。

ということで GeoPandas 使っていきたいと思います。
アルミニウムXingfa

Xingfaアルミニウムとは何ですか？
-おそらくこれは多くの人が興味を持って学んでいる質問です、

-では、xingfaアルミニウムとは、実際には、企業または製造部門がブランドを作成し、他の部門と区別するために名前を付けた単なるアルミニウムのブランド名であり、それによって誰もがその独特のブランドを知っていると思います。使用する電話には、iphoneやsamsungなどのさまざまなブランドがあります...その名前を通じて、すべての人に認識されたときに独自のブランドを作成します。信頼して使用してください。

Xingfaアルミニウムの特徴は何ですか？
--Xingfaアルミニウムは、中国の広東省で製造された高品質のアルミニウムシステムであるか、一般に本物の輸入広東省の赤いスタンプXingfaアルミニウムとして知られています。
Xingfaアルミニウムは、すべての最も耐久性のある要素、最も多様な色とデザイン、最も便利で超美的な機能、そして最もリーズナブルな価格を完全に統合しています。

--Xingfaアルミニウムの厚さは1.4mm-2.0mmで、空のキャビティ内にベアリングリブを備えた特徴的なデザインが施されているため、剛性と剛性が向上しています。

--Xingfaアルミニウムには、磁器の白、茶色、黒、コーヒー、灰色などの基本的な色があります。

-さらに、Xingfaアルミニウムは、ハイエンドで有名なKinlongアクセサリシステムともリンクされているため、非常にスマートで確実なドア開放ソリューションと見なされています。

Xingfaアルミニウムには次のシステムがあります。

+システム55（回転ドア、ドア用に2.0mm、窓用に1.4mmの厚さのドアを開く）、

 

+システム65（ファサードガラス壁システムの厚さは2.0mm）、

 

+システム93（ドアと窓の両方を備えた厚さ2.0mmの引き戸）


<a href="https://xingfagroup.vn/bao-gia-cua-nhom-xingfa_p374.aspx">Cua nhom Xingfa tai Thu Do Group</a>
【React】useEffect の動きを見てみる

# useEffectとは
コンポーネントがレンダリングされる際に実行したい処理を制御するための機能。

ちなみにコンポーネントが再レンダリングされる条件は以下である
1. stateが更新されたとき
2. propsが更新されたとき
3. 親コンポーネントが再レンダリングされるとき


### 基本構文
```jsx
useEffect(() => {
  // ① 実行させたい処理
  return () => {
    // ② ①の処理と対の関係になるクリーンアップ関数（省略可能）
  };
}, [依存配列]); // ③ 第１引数の実行タイミングを制御する値
```

# 依存配列を空配列にした場合
初回レンダリング時の一度だけ①が実行される。
再レンダリングされても実行されない。

- マウント時：①が実行
- アンマウント時：②が実行

```jsx
useEffect(() => {
  // ① 実行させたい処理
  console.log("①");
  return () => {
    // ② ①の処理と対の関係になるクリーンアップ関数
    console.log("②");
  };
}, []); // ③ 依存配列を空配列にする
```

# 依存配列に値を指定する場合
依存配列に変数``count``を指定し、``count``に関心を持たせる。
初回レンダリング時に①が実行されることは変わらないが、その後``count``が更新されると②、①の順番で実行される。

```
②が実行 → ①が実行
```

```jsx
useEffect(() => {
  // ① 実行させたい処理
  console.log(`① count：${count}`);
  return () => {
    // ② ①の処理と対の関係になるクリーンアップ関数
    console.log(`② count：${count}`);
  };
}, [count]); // ③ 依存配列に変数 count を指定
```

## 依存配列を更新して動きを確認してみる
変数``count``を更新するボタンがあり、ボタンを押すと``count``が１ずつ増えていきボタンの上の数字も増えていくというもの。

※文字の大きさが違うのは気にしないでください。スクショが下手なだけです。笑


### マウント時（初回レンダリング時）

|View|Console|
|-|-|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/3af3891f-14c3-aee4-c32e-1c0a88006e82.png" width="300" />|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/93f1fd26-3c6e-34c3-6272-d3105fbf168d.png" width="300" />|

### ２にカウントアップ（``count``を更新）

|View|Console|
|-|-|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/ab07bef8-7131-f399-0f89-e43038d9fd66.png" width="300" />|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/70c5d32c-6529-c2d5-0d31-a7e25fcf9b0c.png" width="300" />|

### ３にカウントアップ（``count``を更新）

|View|Console|
|-|-|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/ac90efcd-6108-b837-0902-b0c5e9d9b8d8.png" width="300" />|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/db0b8b77-b597-5fdb-e76d-b313db3e23fe.png" width="300" />|

ここで注目したい部分としては、

```
②が実行 → ①が実行
```

の順番で実行されるのだが、②が実行されるときの``count``はカウントアップされる前（値が更新される前）の状態で実行されているということである。
①が実行されたときの状態で②が実行されるようである。

使い所としては、
①でリスナーや監視処理をセットして、②で①でセットした処理を解除する
というものが考えられる。
（Reactの公式では、``Subscription``の設定などに触れられていた）

# 最後に
大変わかりやすく参考にさせていただきました！
ありがとうございました！

- [React 副作用フックの利用法](https://ja.reactjs.org/docs/hooks-effect.html)
- [React hooksを基礎から理解する (useEffect編)](https://qiita.com/seira/items/e62890f11e91f6b9653f)
- [React17におけるuseEffectの破壊的変更を理解する](https://zenn.dev/uhyo/articles/react17-useeffect)
- [React(v16.4) コンポーネントライフサイクルメソッドまとめ](https://qiita.com/yuria-n/items/3c3fc8d29fd2e56ed7a9)
【Ruby on Rails】NO FILEと表示されているマイグレーションファイルを削除する方法


#対象者

* NO FILEと表示されたマイグレーションファイルを削除したい方
* modelを削除したけど、マイグレーションファイルだけ残ってしまた方


#目的

* up状態のマイグレーションファイルをdownに戻して削除すること

#実際の手順と実例
###1.状況確認

```
$ rails db:migration:status
```

上記を実行すると下記の表示が出ます

`````

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210915023701  Create articles
   up     20210915065320  ********** NO FILE **********
  down    20210915080932  Devise create users
`````

###2.ダミーファイル作成

真ん中のup状態のダミーファイルを作成します。
Migration IDをコピペして作成します。
下記コマンドで作成してもNewfileで作成しても大丈夫です。

````
$ touch db/migrate/20210915065320_hoge.rb
```

これで再度**rails db:migrate:status**を実行すると下記のように表示されます。

```
Status   Migration ID    Migration Name
--------------------------------------------------
     up     20210915023701  Create articles
     up     20210915065320  hoge
    down    20210915080932  Devise create users

```

後は下記コマンドを実行すればdownになるので、その後削除して、完了です。

```
$ rails db:migrate:down VERSION=20210915065320
````

こちらも参考にしてみてください。

https://qiita.com/nao0725/items/dd64bdab746fe6b2b0a0

###3.ちなみに、、、、、

データベースにあまりデータが入っていなければ、db:migrate:resetかけるのもありらしいです。




####投稿者コメント
チーム開発のときのみならず、PF作成でもやってしまったので、戒めをこめて記事にしました。
model削除する時は気をつけないと、、、、、、

####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
ずっとFPGA初心者（その11：秒カウンタ）

# 秒カウンタ
LEDを用いて経過時間（秒）を表現する。

## 環境
[その１](https://qiita.com/infinite1oop/items/4b0f03b97ed859fbd954)からずっとOdyssey MAX10 FPGA Eval KitおよびQuartus利用。

## 具体的には
本Kit（ボード）には7個のLEDがある。それぞれを2進数のビットとして扱い、0-63秒を表現、LED0をLSB、LED7をMSBとする。例えば、スタートから6秒後に、LED1及びLED2を点灯させる（00000110）。スタートはボタン押下で行い、再押下でストップ（リセット）する。

## ソースコード
```vhdl:sectest.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all; -- necessary for conv_std_logic_vector

entity SecTest is
  port (
	CLK, BTN : in  std_logic;
    LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7 : out std_logic);
end;

architecture RTL of SecTest is
constant CYCLE : integer := 50000000;  -- ①
signal CNT : integer range 0 to CYCLE-1 := 0;  -- ②
signal SEC : integer := 0;  -- ③
signal BtnFlag : std_logic := '0';  -- ④
signal LED: std_logic_vector(7 downto 0) := "11111111"; -- Off　⑤

begin
  LED0 <= LED(0); LED1 <= LED(1); LED2 <= LED(2); LED3 <= LED(3);  -- ⑥
  LED4 <= LED(4); LED5 <= LED(5); LED6 <= LED(6); LED7 <= LED(7);  -- ⑦
  
  process (SEC)  -- ⑧
  begin
    LED <= not conv_std_logic_vector(SEC,8);  -- ⑨
  end process;
  
  process (BTN)  -- ⑩
  begin
    if (BTN'event and BTN='0') then
	   --SEC <= 0;  -- NG  ⑪
	   BtnFlag <= not BtnFlag; -- ⑫
    end if;
  end process;
  
  process (CLK)  -- ⑬
  begin
	-- if (BTN'event and BTN='0') then  -- NG  ⑭
    if (BtnFlag = '1') then  -- ⑮
      if (rising_edge(CLK)) then  -- ⑯
        if (CNT = CYCLE-1) then  -- ⑰
          CNT <= 0;
		  SEC <= SEC+1;
        else
          CNT <= CNT+1;
        end if;
      end if;
    else  -- ⑱
	   CNT <= 0;
	   SEC <= 0;
	 end if; 
  end process;
end RTL;
```

- ①：1秒の定義（50MHzクロック）
- ②：クロック用カウンタ
- ③：秒カウンタ
- ④：ボタンフラグ
- ⑤：LEDフラグ配列および初期化（負論理）
- ⑥、⑦、⑧、⑩、⑬：これらは同時に処理される
- ⑥、⑦：LEDフラグをLEDピンに代入
- ⑧、⑨：秒カウンタ（数値）を論理ビット化し、LEDフラグに代入
- ⑩、⑫：ボタン押下状況をボタンフラグに反映（'1':押下、'0':未押下）
- ⑮、⑯、⑰：ボタンフラグが'1'のときは、クロックの立ち上がり時に、クロック用カウンタインクリメント、または、1秒経過時に秒カウントインクリメント
- ⑱：ボタンフラグが'0'のときは、カウンタリセット
- ⑪、⑭：（参考：これがあるとVHDL文法エラー）

## ピンアサイン
![ピンアサイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/8cc9f129-a44f-73e6-834f-dd743ddae443.png)
ボタン(BTN)、クロック(CLK)、LEDのピンアサインについては、[Odyssey MAX10の回路図](https://www.macnica.co.jp/business/semiconductor/macnica_products/max10_board_revb1p04__1.pdf)を参照。

## テスト
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/1048be7b-e15d-08c5-f2b4-6ac74f40ad9c.png", width=80%>