OmniAICreator/Qiita-1.07M huggingface dataset:
気象庁のAPIを使った雨の日だけ通知してくれるLINE Notifyの作成

# 概要
これまで気象庁の気象データはスクレイピングをすることでしか得られませんでしたが、1カ月ほど前に気象庁HPがAPI化した（気象庁のHPで利用されているものではあるが、公式に提供されているものではないため、アップデート等により使用不可になる可能性もあります。）ということで早速使っていこうと思います。

今回作成するものは

1. 気象庁HPからAPIで天気予報データを取得
1. 雨の日だけLINE Notifyで通知

というシンプルなもので、GoogleAppsScriptを使って実装していきます。

# 気象庁のAPI
まず、気象庁のAPIの仕様を把握する必要があります。この記事が詳しいです。

- [気象庁ホームページ防災気象情報のURL構造](https://qiita.com/e_toyoda/items/7a293313a725c4d306c0)

なお、これはF12を押すと表示されるデベロッパーツールで見ることもできて、Chromeの場合は以下のように見ることができます。

1. 取得したい情報が表示されているページを開く
1. F12
1. Network
1. リロード（ctrl+R or F5）
1. XHRを選択し、順番に見ていく
1. Preview表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/f132dfe5-fadf-57b3-3a0b-9ebcd8611ed6.png)

このときNameのところのアドレスがエンドポイントです。

# GASで処理
GASでapiを利用する際は以下のように記述します。

```js
let response = UrlFetchApp.fetch("https://www.jma.go.jp/bosai/forecast/data/forecast/120000.json");
let response_json = JSON.parse(response.getContentText());
```

responce_jsonの中身を見てほしい情報をたどってください。

```js
let weather = response_json[0]["timeSeries"][0]["areas"][0]["weathers"][0];
weather = weather.replace(/　/g, "");
let rainy_percent = response_json[0]["timeSeries"][1]["areas"][0]["pops"];
rainy_percent = rainy_percent.slice(0, 4);
```

降水確率が高いかどうかの条件分岐とLINEで送りたい文字を決めていきます

```js
if (rainy_percent.filter(element => element >= 50).length == 0){
  return
}
let text = 
`\n今日の天気：${weather}
降水確率：  6時-\t${rainy_percent[0]}%
　　　　　12時-\t${rainy_percent[1]}%
　　　　　18時-\t${rainy_percent[2]}%`

sendLINE(text)
```

# LINE Notifyに通知
まずは、LINEのトークンを取得する必要があります。以下の記事が詳しいです。

- [GAS超入門⑦ - LINEに通知してみる](https://note.com/skipla/n/nefdfa2abd350)

取得したらコードは単純です。コピペして先ほど取得したトークンの部分だけ書き換えればいいです。

```js
function sendLINE(text) {
 let messageText = text
 
 let token = "先ほど取得したトークン"
 let options = {
   "method" : "post",
   "headers" : {
     "Authorization" : "Bearer "+ token
   },
   "payload" : {
     "message" : messageText
   }
 }

 let url  = "https://notify-api.line.me/api/notify"
 UrlFetchApp.fetch(url, options)
}
```

# GASで定期実行
以下の記事が参考になると思います。

- [【Google Apps Script】その8　スクリプトを定期実行し、ビットコインの1分ごとの価格を自動取得する](https://qiita.com/rf_p/items/267a8d9daa8c9f1ef027)

こんな感じで設定すれば毎朝定期実行して、降水確率が高い日だけ通知してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/57866cce-01ac-307a-c325-69ce026e9979.png)


実際に通知が来ました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/32919b7e-3ea3-8063-181c-64490585a243.png)

# 参考文献
- [気象庁ホームページ防災気象情報のURL構造](https://qiita.com/e_toyoda/items/7a293313a725c4d306c0)
- [GAS超入門⑦ - LINEに通知してみる](https://note.com/skipla/n/nefdfa2abd350)
- [【Google Apps Script】その8　スクリプトを定期実行し、ビットコインの1分ごとの価格を自動取得する](https://qiita.com/rf_p/items/267a8d9daa8c9f1ef027)
ColdFusionタグ　自分メモ＜随時更新＞

#CFLOOP(forのこと)

### 1. インデックスグループ
 - index 名前を付けたこれを
 - From　ここから
 - To　ここまで
 - Step　こんだけずつ増やす

```
<cfloop index="index" from="1" to="100" Step="2">
    <cfoutput>
        #index#
    </cfoutput>
</cfloop>
```
### 2. 条件付きループ
 - condition これになるまで
  
```cfm
<cfloop condition = "expression"> 
　ここで条件が変わるものを入れる必要がある
</cfloop>
```
### 3. クエリループ
 - query SQLで抽出したDB内容を
 - startrow　この行から
 - endrow　この行まで処理する

```
<cfloop query = "myQuery"
        startRow = "#Start#"
        endRow = "#End#"> 
<cfoutput>#name# #amount#</cfoutput>
```

### 4. リストループ
 - index 配列中身を順番に処理
 - list　リストの中身を順番に処理
 
```
<cfset myArray = ["John", "Paul", "George", "Ringo"] >
<cfloop array="#myArray#" index="idx">
   <cfoutput>#idx#  </cfoutput>
</cfloop>
```
```
<cfset myList="John,Paul|George|Ringo"/>
<cfloop list="#myList#" delimiters=",|">
    <cfoutput>
        #name#
    </cfoutput>
</cfloop>
```

#try-catch
```
<cftry>
 通常の処理をするコード

<cfcatch type="例外タイプ">
 例外が発生したときのコード
</cfcatch>

</cftry>
```

#デバッグ
- formの中身

```
<cfdump var="#form#">
```

- cflog
- cftrace

# 固定ヘッダーセッターを作りたい
```
<cfinclude template="aa.cfm">
```
これでもできそう

```
<cfmodule template="../profile/profile.cfm" keyword="ColdFusion 8">
```

# コンポーネント
```
<cfcomponent></cfcomponent>
```
コンポーネントであることを宣言する。
.cfcでファイルの最も外側で記述する必要がある。

```
<cffunction
name=""
returnType=""
roles=""
access=""
output="">
<!---メソッドの中身--->
</cffunction>
```
コンポーネントが持つメソッドを宣言する。
タグのボディにメソッドが呼ばれたときに実行することを記述する。
記述できるのはCFMLタグのみ。

```
<cfargument
name=""
type=""
required=""
default=""
>
```
functionの中に記述する。このメソッドが取りうる引数を記述する。
function内をスコープとしてargumentsという頭につけてアクセスできる。（省略可能）

```
<cfretrun hogehoge>
```
コンポーネントが実行された戻り値を返す。
cffunctionのReturnTypeの属性と同じでなければならない。

```
<!---これで呼び出す--->
<cfinvoke  
component="helloworld"
method="sayhello"
returnVariable="aString"
>
<!---メソッドの引数を受け取る場合--->
<cfinvokeargument  name="yourname"  value="岩井">
</cfinvoke>
```
JavaDocスタイルのドキュメントを見る
http://localhost:8500/CFIDE/componentutils/componentdoc.cfm

# 文字化け回避
```
<cfprocessingdirective pageencoding="UTF-8">
```

# cfscript
```
<cfprocessingdirective pageencoding="UTF-8">

    <cfscript>
       
        function myname(lname,fname) {
            retval = lname & fname;
            return retval;
        }
    </cfscript>

    <cfoutput>#myname("岩井","菫")#</cfoutput>
```
【コピペ】Dockerでrustの開発環境を作りたい時のやつ

``` docker
RUN dnf install -y curl gcc
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH=/root/.cargo/bin:$PATH
RUN . ~/.bashrc
```

# 用途
- Rust開発したい
- でも、Doker-Hubのコンテナはやだ

みたいな時のDockerfileに記載するやつ
liberty-maven-pluginでLiberty上で稼働するアプリケーション開発を効率化する

## 概要

Mavenのliberty-maven-pluginを使うと、OpenLiberty(WebSphere Liberty)を使うWebアプリケーションの開発を効率化できます。

## このプラグインでできること

- Libertyの導入を自動化できる。pom.xmlに導入したいサーバーの種類(OpenLiberty or WebSphere Liberty)、バージョンなどの情報を書いておけば良い
- LibertyをDev modeで起動することで、pom.xml含むソースコードやLiberty構成ファイル(server.xml)などをエディタで変更した結果をすぐにサーバーへ反映できる
- Eclipseを使わなくてよくVSCodeなどの好きなエディタを利用できる

## 利用方法

### ファイルの準備

pom.xmlにプラグインを追加して、`<runtimeArtifact>`にサーバーの種類(OpenLiberty or WebSphere Liberty)、バージョンを記載します。以下はOpenLibertyの例です。

```xml
<build>
  <plugins>
  <plugin>
    <groupId>io.openliberty.tools</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>3.3.4</version>
    <configuration>
      <runtimeArtifact>
        <groupId>io.openliberty</groupId>
        <artifactId>openliberty-kernel</artifactId>
        <version>21.0.0.3</version>
      </runtimeArtifact>
    </configuration>
  </plugin>
  </plugins>
</build>
```

WebSphere Liberty JavaEE8を利用したい場合はこうなります。

```xml
<build>
  <plugins>
  <plugin>
    <groupId>io.openliberty.tools</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>3.3.4</version>
    <configuration>
      <runtimeArtifact>
        <groupId>com.ibm.websphere.appserver.runtime</groupId>
        <artifactId>wlp-javaee8</artifactId>
        <version>21.0.0.3</version>
      </runtimeArtifact>
    </configuration>
  </plugin>
  </plugins>
</build>
```

server.xmlはMavenのプロジェクト構成の場合、`src/main/liberty/config`に配置しておきます。特別な記載は必要ありません。以下の例では、`<feature>`としてCDIとJAX-RSのフィーチャーを指定しています。

```xml
<server description="my server">

	<featureManager>
		<feature>cdi-2.0</feature>
		<feature>jaxrs-2.1</feature>
	</featureManager>

	<httpEndpoint httpPort="9080" id="defaultHttpEndpoint" host="*"/>
</server>
```

### サーバーの作成と起動

コマンドラインで`mvn liberty:dev`というコマンドを実行すると、以下が一気に実行されます。
- アプリケーションのコンパイル
- サーバーの作成、不足したフィーチャーの導入
- Dev modeでLibertyの起動


```bash
mvn liberty:dev
```

### 利用上のポイント

- サーバーの標準出力(message.log)が`tail -f`で出力される状態になるので、アプリケーションログも標準出力に出力されるようにしておくと良いです。Ctrl+Cで終了できます
- Javaソースコードだけでなくpom.xml、logback.xmlなどのリソース、テストコードがエディタで変更されていないか監視され、変更されたタイミングでコンパイル＆サーバーへ反映されるので開発をサクサク進められます
- `mvn liberty:dev`で起動中のターミナルでエンターキーを入力するとテストコードを実行できます。単純な単体テストだけでなくLiberty上で稼働するアプリケーションを叩く結合テストを実行することもできます
- サーバーは`target/liberty`配下のディレクトリに作成されるので`mvn clean`で再作成できます
- `src/main/liberty/config`に配置下ファイルは`target/liberty/wlp/usr/servers/defaultServer`へコピーされます。JDBCドライバーなどを置いておくとserver.xmlからは以下のような指定で参照できます。

```xml
<library id="db2Lib">
  <fileset dir="${server.config.dir}" includes="db2jcc4.jar"/>
</library>
```

- VSCode拡張機能のOpen Liberty Toolsも提供されていますが私の環境では動きが変な時がありました
- Maven以外にGradle用のプラグインもあります

## 参考

- [liberty-maven-pluginのREADME](https://github.com/OpenLiberty/ci.maven)
- [インストール時に設定可能な項目](https://github.com/OpenLiberty/ci.maven/blob/master/docs/installation-configuration.md)
- [Dev modeの説明](https://openliberty.io/docs/21.0.0.3/development-mode.html)
アセンブリ入門

#汎用レジスタ
x86 CPUには8つの汎用レジスタがありデータの格納に用いられる。EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI。
これらのレジスタは４バイトであり、プログラムは４バイト、２バイト、１バイトの値としてレジスタにアクセス可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/9dacc6c2-f926-e388-37a4-59dcbb19fe7c.png)
下位２バイトにはAX,BX,CX,DX,SP,BP,SI,DIとしてアクセス可能。
下位１バイトにはAL,BL,CL,DL,２バイト目にはAH,BH,CH,DHでアクセス可能。

visual stusioのレジスタ情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/8986e938-78e6-dbb5-a4ed-c5c5153f9047.png)

#命令レジスタ
EIPは命令ポインタが格納されており、メモリ内の次の命令のアドレスを指す。

#セグメントレジスタ
CS,SS,DS,ESがある。
CS:コードセグメント。次に実行するコード（機械語）へのポインタ。
SS:スタックセグメント。スタックへのポインタ。
DS:データセグメント。データへのポインタ。レジスタとメモリのデータ転送時に参照される。
ES：エクストラセグメント。追加のデータへのポインタ。
FS,GS:さらなるデータへのポインタ。

#データの移動
基本文法
　mov dst, src
レジスタへの格納
　mov eax, 1 //eaxに1の格納
レジスタ間の移動
　mov ebx, eax //ebx=eax
メモリからレジスタ
　mov eax, [0x123456] //0x123456のアドレスの値をeaxに格納
　格納先のレジスタの大きさに応じて移動させる値のサイズも変わる。


#算術演算
add 加算
sub 減算
mul 乗算
div 除算
typeof についてTypeScript独自の用法とJavaScriptと共通の用法を整理。

`typeof`演算子は、型コンテキストでは型定義、その他の場所ではデータ型の種類の文字列を返す。
前者はTypeScript独自の用法、後者はJavaScriptと共通の用法。

## 型コンテキストでは

型コンテキスト(TypeScriptで型定義を書く箇所)では、`typeof`は対象の型定義を返す。

```ts
const hito = {
  name: 'Taro',
  age: 18
}

const syuto = 'Tokyo';

let kuni = 'nihon';

const jinkou = 1000;

let jinkou2 = 1000;

const hito3: typeof hito = {
  name: 'hide',
  age: 20
}
// const hito3: {
//   name: string;
//   age: number;
// }

const syuto2: typeof syuto = 'Tokyo';
// const syuto2: "Tokyo"

type s = typeof syuto;
// type s = "Tokyo"

const syuto3: s = 'Tokyo'
// const syuto3: "Tokyo"

const kuni2: typeof kuni = 'amarica'
// const kuni2: string

type k = typeof kuni;
// type k = string

const kuni3: k = 'amarica'
// const kuni3: string

const jinkou3: typeof jinkou = 1000;
// const jinkou3: 1000

const jinkou4: typeof jinkou2 = 1001;
// const jinkou4: number
```

## その他の場所では

型コンテキスト以外の場所では、`typeof`は対象のデータ型の種類を文字列で返す。
返しうる文字列は`"string", "number", "bigint", "boolean", "symbol", "undefined", "object", "function"`

```ts
const hito = {
  name: 'Taro',
  age: 18
}

const syuto = 'Tokyo';

const hito2 = typeof hito;

console.log(typeof hito); // object
console.log(typeof syuto); // string
console.log(hito2); // object
console.log(typeof hito2); // string (文字列'object'の型の種類string)

if (typeof hito2 === 'string') {
  console.log("hito2 is 'string'")
}
// hito2 is 'string'
```
非IT民がwslにUbuntuを入れてROSを動かすまで

####「○○上で△△を動かすようにしといてね」
と簡単そうに言われても途中でハマりまくるのは非IT民に良くあること。

今回は
#####　wslにUbuntuを入れてROSを動かす#####
というゴールに辿りつくまでやったことをメモします。



##結論
####ネットに上がってる実績ある手法を遵守しよう
これに尽きます。

以前に別件でUbuntu18を入れたことはありましたが、ROSを動かすのに良く使われているのはUbuntu16でした。記事を参考にしながらやればUbuntu18でもできるだろう、という安直な考えで取り掛かりましたが、これが大誤算。原点に立ち返ってようやく目的を達成できました。

動作確認できた組み合わせは以下の通りです。

- wsl1
- Ubuntu16
- Xming(Xサーバー)

##はじめに試したこと

条件①(初期条件)
- 初期wsl:1
- Ubuntu18

下記サイトではUbuntu16で行っていましたが、もともと環境のあるUbuntu18でまずは取り掛かってみました。
https://qiita.com/takapen_jp/items/57e083a25ec11778b4cb

調べると、Ubuntu18に対応しているROSはROS melodicであるため、記事のUbuntu16-ROS kineticと異なる点に注意しました。
https://www.cman.jp/network/term/subnet/p3/

上記の場合、robosenseでcatkin_makeしたときにエラーが出てハマりました。
robosenseのディレクトリ構成が悪かったのが要因という可能性もありましたが、心が折れたのでUbuntu16でやり直す方向で進めました。

##wsl1からUbuntu18をアンインストールしてUbuntu16を入れて再トライ

*実はwsl2にUbuntu16を入れたことも試しましたが、そもそも参考記事が少なく途中でハマり挫折したのでwsl1にUbuntu16を入れ直しました

####やったこと

wsl1からUbuntu18をアンインストールし、
下記リンクを参考にwsl2のUbuntu16の登録を解除。
https://qiita.com/rubytomato@github/items/a290ecef2ea86ea8350f

PoweShell上で
`wsl --set-default-version `
でwsl1をデフォルトに設定する。

この時、`wsl -l --version` でアクティブなバージョンを確認したところ何も表示されないという謎現象がありましたが、
wsl1でPCに入っているUbunt16を立ち上げ初期化して正常そうだったのでスルーしました。

その後は記事を参照しながら進めました。

####Xming～ROSのインストール
https://naonaorange.hatenablog.com/entry/2018/11/05/200715

####ROSとRobosense
http://www1.meijo-u.ac.jp/~kohara/cms/technicalreport/ubuntu16-04_ros_install

####shell.startupでXmingをPC起動時に起動するようにしておく
https://torisky.com/wslwindows-subsystem-for-linux%e4%b8%8a%e3%81%a7gui%e3%82%a2%e3%83%97%e3%83%aa%e3%82%92%e5%8b%95%e3%81%8b%e3%81%99%e3%81%be%e3%81%a7%e3%81%ae%e6%89%8b%e9%a0%86/
これをやらないとXサーバーを立ち上げるのを忘れた際に、`Error: Can't open display: :0.0`と出てxeyesを表示できません。(忘れるなよって話ですが、操作するのは人間だもの)

####機器との接続用にIPアドレスを固定しておく
https://www.cman.jp/network/term/subnet/p3/

今回は何も機器に繋いでないので動作確認は`$ rviz`が動くかで行いました。

##振り返り

その分野に精通してないと変な挙動があった時に対処できないので、環境構築に関しては、まずは自分で判断してアレンジする部分をできるだけ排除した方が良いと痛感しました。先人の知恵を使い倒しましょう。
【超基礎】データベース設計について①

実務でデータベース設計に関わる機会があったため、個人的な忘備録としてのまとめです。

データベース設計の基礎について何回かでまとめていけたらと思ってます。
わかりにくい部分などあるかと思いますが、何卒大目に見て頂ければ幸いです。

学習した教材
- [はじめてのテーブル設計・データベース設計【わかりやすい解説 + 身近なテーマでレッスン】](https://www.udemy.com/course/hajimete-ronrisekkei/)

### データベースとは

__データを入れておく箱__みたいなものです。

もう少し詳細に説明すると、データベースには大きく２つの役割があります。

__1. データの保存__
__2. データの使用__


です。データベースは、


大量の情報を保存することができる →__（データの保存）__
保存された情報に効率よくアクセスできる仕組みがある → __(データの使用）__


といった役割があります。

ECサイトやSNSなど、
データを扱うWebサービスの裏側には、ほとんどの場合データベースが存在しています。


### データベースの種類

データベースは下記のような種類があります。

- __リレーショナルデータベース（RDB)__
- グラフ型データベース
- キー・バリュー型データストア
- ドキュメント指向データベース

一般的にデータベースと言われているものは、
大抵の場合__リレーショナルデータベース（RDB）__を指していることが多いです。



#### なぜデータベースに効率よくアクセスできるのか？

> 保存された情報に効率よくアクセスできる仕組みがある

と記載しましたが、
「なぜ効率よくアクセスできるのか？」というと、

__データベースマネジメントシステム（DBMS）__があるからです。

リレーショナルデータベース（RDB）の場合は、

__リレーショナルデータベースマネジメントシステム（RDBMS）__

と呼ばれるものになり、図で表すと下記のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393934/147f7801-d979-a166-682f-1a9e974b64af.png)

私たちがデータベースへアクセスする際は、

1. RDBMSへSQLを発行する
1. RDBMSがRDBへアクセスし、データの操作や取得を行う
1. 操作の結果や取得したデータを、ビューとして表示する

といった仕組みになっています。

代表的なRDBMSとして、

- Oracle
- MySQL
- PostgreSQL
- SQL Server 
- SQL Lite

などがあります。


### データベース設計とは

では、データベース設計とはなにか？

WEBサービスやシステム開発のひとつのプロセスで、

__データベースに保持するデータに関する設計__

を行うことです。そのまんまですね。

データベース設計は、

__システムの拡張性やパフォーマンスに影響が大きいため、開発において極めて重要なプロセス__です。

WEBサービスやシステム開発のプロセスは以下のような流れになっており、


1. 要件定義（何を作るか）
2. __設計（どう作るか）__
3. 開発（実装）
4. テスト（期待通りに動くか）

データベース設計は「2. __設計（どう作るか）__」に該当します。
参考までに設計のプロセスの中にも以下のようなものがあります。

- __データベース設計（データを保持について考える）__
- アプリケーション設計（提供機能を決める）
- インターフェース設計（使用画面などを決める）
<br>など

またDBの種類ごとに、DB設計のやり方は異なりますが、
この記事では、主に__リレーショナルデータベース（RDB）__の設計について記載しています。

- __リレーショナルデータベース（RDB)__
- グラフ型データベース
- キー・バリュー型データストア
- ドキュメント指向データベース

### ３層スキーマ

データベース設計を行う上で、__３層スキーマ__についても理解しておく必要があります。

スキーマとは、「構造」や「枠組み」といった意味です。わかりづらいですね。

データベースは、

1. __外部スキーマ（ユーザーから見たデータベース、ビュー）__
1. __概念スキーマ（開発者から見たデータベース、テーブル）__
1. __内部スキーマ(DBMSから見たデータベース、データの物理的配置）__

の３層のスキーマから構成されています。
３層のスキーマのイメージは下記のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393934/7b1aea30-bd3b-8813-09ec-ae16c1d87a9e.png)

ここで押させておきたいのは、
__外部スキーマと内部スキーマが直接関連していない__ということです。

#### 外部スキーマと概念スキーマ

より理解を深めるために、外部スキーマと概念スキーマを関連性について考えてみます。
SQL（SELECT文）によってテーブルからビューを取り出すことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393934/367e3404-f3f9-c112-2c7a-184931f7ee8f.png)


#### 概念スキーマと内部スキーマ

次に概念スキーマと内部スキーマの関連性について考えてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393934/462f1026-f764-d0bf-7fbe-1c10f046e6c0.png)
データファイルを__テーブル__という人間が扱いやすい形に変換しています。

データベースにアクセスする際は内部スキーマのデータから情報を取得する必要があります。
その際内部では、

__概念スキーマと内部スキーマ__の関連性においては、
→　データファイルに入っているデータを人間が扱いやすい形__（テーブル）__に変換

__外部スキーマと概念スキーマ__関連性においては、
→　変換されたテーブルからSQLによってデータを取得

といったことが内部で行われているということですね。
なんとなく理解できたようで、理解できてない感じがしてますが笑

今回の記事では一旦ここまでです。

また別の記事で、

- 論理設計と物理設計
- ３層スキーマとデータ独立性

などについてまとめていきたいなーと思います。
相関サブクエリや共通表式を使って、他のテーブルをもとにUPDATEする

# 前提

商品在庫を管理するシステム構築にあたり、まず在庫数を商品ごとに格納しているinventoryテーブルがあるとします。

|goods|pieces|
|:---|---:|
|夏タイヤ|10|
|冬タイヤ|20|
|ホイール|30|

次に商品がいつどれだけ入荷されるかの履歴や予定を格納しているarrivalテーブルがあります。

|goods|created_at|pieces|
|:---|---:|---:|
|夏タイヤ|2021/03/31|1|
|冬タイヤ|2021/03/31|2|
|ホイール|2021/03/31|3|
|夏タイヤ|2021/04/01|4|
|夏タイヤ|2021/04/01|5|
|冬タイヤ|2021/04/01|6|

ここで2021/04/01になったので、2021/04/01に到着する商品数を在庫数に足してやる必要があります。つまり、arrivalテーブルから2021/04/01に到着する商品を取り出して、inventoryテーブルのpicesに足しこむようなUPDATE文を作る必要があります。

なお実行後のinventoryテーブルは以下のようになるはずです。

|goods|pieces|
|:---|---:|
|夏タイヤ|19|
|冬タイヤ|26|
|ホイール|30|

# 解法1

もっともべたに書くと次のようなUPDATE文になるはずです。

```SQL
UPDATE inventory
SET pieces = inventory.pieces + (
  SELECT SUM(pieces) 
  FROM arrival
  WHERE inventory.goods = arrival.goods
  AND arrival.created_at = '2021-04-01')
WHERE EXISTS (
  SELECT *
  FROM arrival
  WHERE inventory.goods = arrival.goods
  AND arrival.created_at = '2021-04-01'
);
```

# 解法2

共通表式を利用すると、もう少しすっきりした見た目にはなります。

```sql
WITH t AS (
  SELECT goods, SUM(pieces) AS total
   FROM arrival
  WHERE created_at = '2021-04-01'
  GROUP BY goods
)
UPDATE inventory
SET pieces = pieces + (SELECT total FROM t WHERE t.goods = inventory.goods)
WHERE EXISTS (SELECT * FROM t WHERE t.goods = inventory.goods);
```

# 解法3

解法3はこの問題特有の解法になります。到着する荷物がない場合「UPDATE対象にしない」と考えるのではなく、「0を足す」という風に考えると、WHERE節を省くことができます。解法1と解法2はWHERE節とSET節両方でサブクエリを書く必要があって、このせいで冗長な書きぶりになっていましたが、以下のクエリであればそれを避けることができます。

```SQL
UPDATE inventory
SET pieces = inventory.pieces + (
  SELECT COALESCE(SUM(pieces), 0)
  FROM arrival
  WHERE inventory.goods = arrival.goods
  AND arrival.created_at = '2021-04-01'
);
```

# 検証環境

```
Microsoft SQL Server 2019 (RTM-CU9) (KB5000642) - 15.0.4102.2 (X64) 
	Jan 25 2021 20:16:12 
	Copyright (C) 2019 Microsoft Corporation
	Developer Edition (64-bit) on Linux (Ubuntu 18.04.5 LTS) <X64>
```
【iOS】ipaファイル作成手順 & ipaファイル公開手順

<!--
・参考
https://docs.monaca.io/ja/products_guide/monaca_ide/deploy/non_market_deploy/
-->

##前書き
ipaファイルを作成して、アプリをブラウザから端末にインストールする方法のメモ書き🖋


## ipaファイル作成手順
1. Generic iOS Device にする
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/252c160f-248f-58da-2c9b-e2c1c804f384.png)


2. Product -> Archive を選択
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/41b665d1-fca3-24f6-82b1-28ae2111d97a.png)


3. **Distribute App** を選択
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/6e3704ab-c1c0-36ea-b577-fe5f6761255e.png)

4. **Ad Hoc** を選択して、**Next**を押下
 ![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/6a946777-6af1-db90-1f3b-883fb7b4be21.png)

5. デフォルトのまま**Next**を押下
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/0e79f853-d8e3-7316-36d2-76045e5ee92d.png)

6. デフォルトのまま**Next**を押下
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/b1c70925-d84c-4d33-a4f5-c81d6423226d.png)

7. **Export**を押下して、任意の場所にipaファイルが格納されたフォルダを保存する
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676215/363e71bc-f751-ffb7-309a-1d4e88c00068.png)



## ipaファイル公開手順
サーバーにipaインストール用のページを作成して、そこからipaをインストールできるようにします。
httpsで通信が可能なWebサーバーに下記で作成したファイルを配置します。

``` 
https://example.com
 |- ipa
     |- ipa.html
     |- ipa.plist
     |- XXXX.ipa
```
&ensp;

1. **ipa.plist**ファイル（ファイル名はなんでも良い）を作成して、下記のコードをコピペして、任意の場所にファイルを置いてください。  
※ ipaファイルのURLはipaファイルが置かれているURLに変更してください

``` ipa.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>http://example.com/XXXX.ipa</string> ← ipaファイルのurlを設定
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>com.example.test</string>
                <key>bundle-version</key>
                <string>1.0.0</string>
                <key>kind</key>
                <string>software</string>
                <key>title</key>
                <string>AppName</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>
```
&ensp;
2. ダウンロード用のHTMLファイルを作成して、下記のコードをコピペする。
※ **https://example.com/** はipa.plistが置かれている自分の環境のURLに変えてください。

```ipa.html
<a href="itms-services://?action=download-manifest&amp;url=https://example.com/ipa.plist">Download</a>
```
&ensp;
3. ipaファイルを設定したurl配下に配置してHTMLファイルを開いて、リンクを押下するとインストールできる
Haskell のインストール

[[増補改訂]関数プログラミング実践入門](https://www.amazon.co.jp/dp/4774183903/)を読んで Haskell を Mac（Big Sur）にインストールする。

# 手順
### Stack のインストール

Stack は Python の Virtualenv や Ruby の rbenv のようなもの。正常にビルドできることが保証されたパッケージ群（スナップショット）を提供する Stackage（Stable Hackage） を利用している。

[The Haskell Tool Stack](https://docs.haskellstack.org/en/stable/README/)

```bash
$ curl -sSL https://get.haskellstack.org/ | sh
```

### Stack から GHCをインストールする
GHC はコンパイラ。

```bash
$ stack setup
・・・・
stack will use a sandboxed GHC it installed
For more information on paths, see 'stack path' and 'stack exec env'
To use this GHC and packages outside of a project, consider using:
stack ghc, stack ghci, stack runghc, or stack exec
```

### GHCi が起動する
GHCi は対話的インタープリタ。

```
$ stack exec ghci
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
Prelude> 
```

# GHCi コマンド

```bash
# ヘルプ
Prelude> :?
# 終了
Prelude> :q

```
after_initialzeを使用時には、実行条件をつけてあげよう

# はじめに
現在Railsを使って開発中のアプリケーションで、`after_initialize`を使用する機会があった。
正直コールバックは苦手意識があって、避けてきたのもあるのと`after_initialize`に関しては使い所がイマイチわからなかったため、無知の状態であった。

いざ使ってみると便利だが、少し気をつけたいポイントもあるので、本記事に記述する

## `after_initialize`とは
その名のと通り、設定したクラスのオブジェクトがインスタンス化された後に実行される処理のことである。

以下にかんたんな使用例を示す。
Userクラスのオブジェクトがインスタンス化された後に、name属性に予め値をセットしている。

```ruby

class User < ApplicationRecord
  after_initialize do
    self.name = "default name"
  end
end
```




[Railsガイド](https://railsguides.jp/active_record_callbacks.html#after-initialize%E3%81%A8after-find)には以下のように説明がされている。

>after_initializeコールバックは、Active Recordオブジェクトが1つインスタンス化されるたびに呼び出されます。インスタンス化は、直接newを実行する他にデータベースからレコードが読み込まれるときにも行われます。これを利用すれば、Active Recordのinitializeメソッドを直接オーバーライドせずに済みます。

ここで重要なのが、`直接newを実行する他にデータベースからレコードが読み込まれるときにも行われます。`という部分になる。

これは本記事のタイトルの部分にもつながる重要な部分である。


### なぜ実行条件をつけるのか？

今記事の目的となる部分です。Railsガイドの説明を読み解くと、`User.new`だけではなく`User.all`や`User.where`等でも`after_initialize`は実行されることになります。
 
実は`new`だけでなく、`all`や `where`でもインスタンスは生成されている。

つまり`after_initialize`を設定していると取得件数分だけ処理が実行されることになる。
DBに10000件ユーザーのデータ入っていたとして、`User.all`を実行すると、`after_initialze`が同じ件数だけ実行される。

これは処理速やパフォーマンスに影響が出かねない。
また既存データ取得時に`self.name = "default name"`のようにデータに触る処理を書いてしまうと、既存データが予期しない値が入ってしまうことも考えられえるため、非常に危ない。

Railsには,FW側で便利なメソッドが揃っているため、その力をお借りして実行条件を付与しよう

私の場合は、新規データ作成時にのみ実行をしたかったため`new_record?`という、インスタンス化したオブジェクトが新規か既存データかを判定してくれるメソッドを使うことで、実行条件を付与した

```ruby
class User < ApplicationRecord
  after_initialize :set_default_name, if: :new_record?

  def set_default_name
    self.name = "default name"
  end
end
```

### 本当にインスタンスを生成しているのか？
余談だが、`all`や`where`の戻り値が本当にインスタンスが生成されているのかを確認したい場合の方へ。

Rubyには`instance_of?`という対象簿のオブジェクトが引数に指定したクラスのインスタンスを生成しているのか、判定するメソッドがある。

```terminal
pry(main)> users = User.all
pry(main)> users[0].instance_of? User
=> true
```

普段使わない機能を使う事で新たな気付きがあるので、今後も積極的に使っていきたい
【Rails6】WebpackerによるBootstrap導入

#　はじめに
この記事ではWebpackerによるBootstrapの導入方法を説明します。
  
# bootstrap, jQuery, popper.jsのインストール
　ターミナル上で以下のコマンドを実行する。

```
yarn add jquery bootstrap popper.js
``` 
　　
これによって、
`package.json`ファイルに次の３行追加される。

```json:package.json
"bootstrap": "^4.6.0",
"jquery": "^3.6.0",
"popper.js": "^1.16.1",
```

# Bootstrapを利用できるようにする
`app/javascript/packs/application.js`に、
以下の２行を追加する。

```js:app/javascript/packs/application.js
import 'bootstrap'
import '../stylesheets/application'
```
　　
新しいディレクトリ、ファイルを追加する。
まずは以下のコマンドで`app/javascript`にstylesheetsディレクトリの作成。

```
mkdir app/javascript/stylesheets
```
　　
`app/javascript/stylesheets`にapplication.scssファイルを作成。

```
touch app/javascript/stylesheets/application.scss
```
　　
次は`app/javascript/stylesheets/application.scss`に
以下のコードを追加する。

```scss:app/javascript/stylesheets/application.scss
@import '~bootstrap/scss/bootstrap';
```

# jQueryとPopper.jsを利用できるようにする
次に`app/config/webpack/environment.js`を修正。

```js:app/config/webpack/environment.js
const { environment } = require('@rails/webpacker')

//ここから
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    Popper: ['popper.js', 'default']
  })
)
//ここまでを追加。

module.exports = environment
```
　　
# レイアウトを修正する
`app/views/layouts/application.erb.html`の
「stylesheet_link_tag」を「stylesheet_pack_tag」に変更する。

```erb:app/views/layouts/application.html.erb
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```
　　
これでbootstrapが利用可能になります。

　　
# 注意点
bootstrapのドキュメントを参考にする場合はバージョンにあったものを使用すること。でないとjQueryが動かない場合がある。

# 参考にした記事
https://qiita.com/niconicocareer/items/03fa995e7c5d71852fcd
XMLSerializerで後方互換を考慮したかった

XMLSerializer、使っていますか？
データの保存＆読み込みが簡単にできるので重宝しています。

私も使っていたのですが、この度保存データ構造のほうに変更がありまして・・・
新しい保存データが古いアプリで読み込めないどころか、読み込まそうとするとクラッシュすることが判明してしまいました。

ちゃんと保存回りを作っておけばよかった！
ということで、過去の自分への戒めも込めてどうすればいいかまとめてみます。

# この記事の目標
XMLSerializerを使って、データの保存を行います。
保存データの変更、つまりプロパティの追加や削除などが起きても、とりあえず読み込めるようにすることが目標です。

# XMLSerializerの挙動
まず、挙動についてまとめます。

以下の2点の変更について、それぞれ影響を見ます。

* プロパティが追加 or 削除された
* 列挙子の種類が追加された

## プロパティが追加 or 削除された場合
とりあえず例として以下の従業員クラスを考えてみましょう。
名前とIDだけがあるクラスです。

~~~ C#
    public class Employee
    {
        /// <summary>
        /// 名前
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// ID
        /// </summary>
        public int Id { get; set; }
    }
~~~

これをXMLSerializerでXML化するとこうなります。

~~~ XML 
    <Employee>
      <Name>山田太郎</Name>
      <Id>1</Id>
    </Employee>
~~~

では、データの構造が変化したものとして、以下のXMLをデシリアライズしてみます。

~~~ XML 
    <Employee>
        <NewProperty>1</NewProperty>
    </Employee>
~~~

`Name`と`Id`プロパティを削除し、`NewProperty`を追加した形になります。
これを読み込ませると、`Name = null`、`Id = 0`となります。
まとめると、

* プロパティが追加された場合
    * 追加プロパティは無視される → 対策不要
* プロパティが削除された場合
    * 型ごとのデフォルトの値が使われる → `NullReferenceException`が発生しうる

nullチェックをするか、初期値をちゃんと入れておけば問題なく読み込めます。
初期値を入れる場合はデシリアライズする際、引数のないコンストラクタが呼び出されるので、そこで設定します。


## 列挙子の種類が追加された場合

またもや従業員クラスを例にしてみます。
今度は役職だけ持っているクラスになります。

~~~ C#
    public class Employee
    {
        /// <summary>
        /// 役職
        /// </summary>
        public PostType PostType { get; set; }
    }

    public enum PostType
    {
        /// <summary>
        /// 部長
        /// </summary>
        Chief,

        /// <summary>
        /// 一般
        /// </summary>
        Staff,
    }
~~~

これをXMLSerializerでXML化するとこうなります。

~~~ XML 
    <Employee>
      <PostType>Chief</PostType>
    </Employee>
~~~

列挙子の種類が追加したものとして、以下のXMLをデシリアライズしてみます。

~~~ XML 
    <Employee>
      <PostType>NewValue</PostType>
    </Employee>
~~~

デシリアライズすると、`InvalidOperationException`例外が発生します。
これは、`PostType`列挙子に`NewValue`という値が存在しないため、
文字列を`PostType`列挙子に変換できないために発生します。

直接列挙子をシリアライズするのではなく、文字列や数値に変換してからシリアライズすることで対応できそうです。

~~~ C#
        /// <summary>
        /// 役職
        /// </summary>
        [XmlIgnore]
        public PostType PostType { get; set; }

        public string PostString
        {
            get
            {
                return PostType.ToString();
            }
            set
            {
                var result = PostType.Other;
                if(Enum.TryParse<PostType>(value, out result))
                {
                    PostType = result;
                }
            }
        }
~~~

`XmlIgnore`によって`PostType`プロパティは直接シリアライズしないようにしています。
代わりに文字列型の`PostString`プロパティを介してシリアライズします。
デシリアライズするときは、文字列を`PostString`プロパティを介して`PostType`プロパティに設定します。
これで文字列を変換できなかった場合の処理をこの中でできるようになっています。

# まとめ

* プロパティの削除を見越してプロパティに初期値は設定しよう
* Enumの種類の追加を考慮して、文字列でシリアライズ、デシリアライズできるようにしよう

というわけで、この辺の設計はきちんと後々のことまで考えてするようにしましょうね！
データベースとSQL　概要

***
###■　Webシステムの構造とDBについて
Webシステムは以下の要素に分類される
・アプリケーション
・ミドルウェア
・OS
・ハードウェア

その中でミドルウェアは以下の種類がある
・Webサーバ
・APサーバ
・DBサーバ
上記3つのサーバによる典型的なミドルウェアの構成をWeb3層構造という

DBサーバはDB管理システム（DBMS：マネジメントシステム）が作動するサーバで
DBMSはDBを管理するための専用ソフトウェア

DBは様々なモデル（格納方式）があり
・階層型
・ネットワーク型
・リレーショナル型
・オブジェクトリレーショナル型

主に利用されているのはリレーショナルDB（RDB）
RDBの代表的なものは以下のようなものがある
・Oracle
・MySQL
・Postgre SQL
上記のRDBのマネジメントシステムをRDBMSという

RDBは以下で構成される
・テーブル（表）Excelでいうタブ
・レコード（行）横の列
・カラム（列）縦の列
・フィールド（レコードとカラムの交差点）Excelでいうセル

※NULL値：フィールドに値が格納されていない状態
⇒0や空白とは異なる
***
###■　主キーと外部キー
主キー：テーブル内でレコードを一意に特定するため、1つのカラムに指定するキー
　　　　役割は
　　　　1．レコードを識別する
　　　　2．他テーブルと連携させる
　　　　主キー制約があり、1テーブルに1つ、カラム内の他フィールドと重複しない
　　　　必ず値が入る（NULLにできない）
外部キー：同じ、もしくは他テーブルの主キーを参照する
　　　　　参照する主キー内の値のみ格納可
　　　　　NULL値は格納可
　　　　　⇒意味のないデータの登録を防げる
***
###■　SQL
SQLはRDBMSでRDBからデータを取得する際に用いる「構造化問い合わせ言語」
データを取り出すSELECT文など、さまざまな文（コマンド）があり
それぞれの文は以下4つに分類分けされる
・DML (Data 「Manipulation」 Language：データ「操作」言語)
・DDL (Data 「Definition」 Language：データ「定義」言語)
・DCL (Data 「Control」 Language：データ「制御」言語)
・トランザクション制御（一かたまりの処理）

■　DML
⇒表内のデータを直接操作する処理
・SELECT文（データの取り出し）
・INSERT文（新規データの挿入）
・UPDATE文（既存データの更新）
・DELETE文（既存データの削除）
・MARGE文（データのマージ<統合>）

■　DDL
⇒表などのデータベースオブジェクトを作成・変更・削除する
・CREATE文（オブジェクトの作成）
・ALTER文（オブジェクト定義の変更）
・DROP文（オブジェクトの削除）
・RENAME文（オブジェクト名の変更）
・TRUNCATE文（表の切り捨て）
・COMMENT文（コメントの定義）

■　DCL
⇒データベースに対する権限を付与・取り消しする
・GRANT文（権限の付与）
・REVOKE文（権限の取り消し）

■　トランザクション制御
※トランザクションとは：DBに対して行われる1つ以上の更新処理のこと　これを制御するのがトランザクション制御
例えば2つのUPDATE文でテーブル内の2カ所を変更（更新）する場合、通常であれば1つ目の処理を実行し完了させたのち
2つ目の処理を実行し完了となるがトランザクション制御を行うことで2つの処理が正常に完了できたなら確定
そうでないなら変更の取り消しを行う、ということができる
具体的にはSTART TRANSACTIONという開始コマンドを入力し、以下に各SQL文を記述し、最後に変更の確定 or 変更の取り消しの文を記述する
（Oracleはデータベースへ接続したら自動的にトランザクションが始まることになっているため開始コマンドは無い）

・COMMIT文（変更の確定）
・ROLLBACK文（変更の取り消し）
・SAVEPOINT文（セーブポイントの作成）
jQuery UI で要素をドラッグしよう

# はじめに
みなさん、要素をドラッグして移動したいと思ったことはありませんか？
これからjQuery UIを使って要素をドラッグしていきます。

# jQuery UI
jQuery UIを使うためには読み込む必要があります。

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
```
適当な場所からjQueryとjQuery UIを読み込みます。今回は [Google Hosted Libraries](https://developers.google.com/speed/libraries) から読み込むことにしました。
ご自身でダウンロードして読み込んでいたただいても構いません。

# 移動させたい

```html
<div class="drag">
  <div class="drag-content">content1</div>
  <div class="drag-content">content2</div>
  <div class="drag-content">content3</div>
</div>
```

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="result" data-user="risuney" data-slug-hash="OJWzexP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Qiita-drag">
  <span>See the Pen <a href="https://codepen.io/risuney/pen/OJWzexP">
  Qiita-drag</a> by Risuney (<a href="https://codepen.io/risuney">@risuney</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

こうしても当然の如く要素の移動はできません。

# jQuery UIを使う

```js
$('.drag').sortable()
```

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="result" data-user="risuney" data-slug-hash="eYgywGe" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Qiita-drag-2">
  <span>See the Pen <a href="https://codepen.io/risuney/pen/eYgywGe">
  Qiita-drag-2</a> by Risuney (<a href="https://codepen.io/risuney">@risuney</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

jQuery UIを使って要素の並べ替えができました。

# 要素をまたいでで移動
ただ並び替えただけではつまらないですね。
親要素とその他の要素間をまたいで移動させましょう。

```js
$('.drag').sortable({
  connectWith: '.drag',
  items: '.drag-content'
})
```

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="result" data-user="risuney" data-slug-hash="LYxeKbJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Qiita-drag-3">
  <span>See the Pen <a href="https://codepen.io/risuney/pen/LYxeKbJ">
  Qiita-drag-3</a> by Risuney (<a href="https://codepen.io/risuney">@risuney</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

要素をまたいで移動することができました。
`connectWith`でまたぐ要素、`items`でドラッグする要素を指定しています。

# 追記
コメントで報告してくださいました。
この機能はスマートフォンなどのタッチディスプレイでは非対応のようです。

# まとめ
sortableで簡単に要素の移動ができる
Reactの.envにシークレットトークンとかを決して含めてはいけない

## やりたいこと
Create React Appで作成したReactアプリケーションで環境変数を扱いたいという場面があり注意すべきことに出会ったのでそれについて書いていきます。

早速Create React Appのドキュメントを読んでみました。次のように書かれています。

https://create-react-app.dev/docs/adding-custom-environment-variables
> Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined for you, and any other environment variables starting with REACT_APP_.

つまり`REACT_APP_`から始まる環境変数を使用することができるようです。
`REACT_APP_NOT_SECRET_CODE`という名前で変数を宣言すると、JS側からは`process.env.REACT_APP_NOT_SECRET_CODE`として使用できるそうです。

## 環境変数の定義
シェルで一時的な環境変数を追加して使用することもできます。
Bashの場合は以下のようになります。

```
REACT_APP_NOT_SECRET_CODE=abcdef npm start
```

またはプロジェクトのルートに.envファイルを作成して、そのファイルに環境変数を定義することもできます。

```text:.env
REACT_APP_NOT_SECRET_CODE=abcdef
```

以下のようにDOMAINという定義された変数を拡張して、.envファイルで使用するすることもできます。

```text:.env
DOMAIN=www.example.com
REACT_APP_FOO=$DOMAIN/foo
REACT_APP_BAR=$DOMAIN/bar
```

環境変数を変更すると、それを反映させるために、開発サーバーが起動している場合は再起動が必要になります。

## 注意ポイント。プライベートAPIキーなどは環境変数で使わないこと。

ドキュメントには注意書きで次のように書かれています。

> WARNING: Do not store any secrets (such as private API keys) in your React app!
Environment variables are embedded into the build, meaning anyone can view them by inspecting your app's files.

訳すと以下のような意味です。
警告：Reactアプリに秘密（プライベートAPIキーなど）を保存しないでください。
環境変数はビルドに組み込まれているので、アプリのファイルを調べれば誰でも見ることができます。

ビルド時には、`process.env.REACT_APP_NOT_SECRET_CODE`が環境変数`REACT_APP_NOT_SECRET_CODE`の現在の値に置き換えられます。
つまり.envに環境変数を書いて.envファイルをgitignoreしておくと、GitHubに変数を公開することを防ぐことができますが、ビルドしたファイルの内容を見れば誰でも変数の内容を見ることができるようです。

例

```jsx:text.jsx
render() {
  return (
    <div>
      <small>You are running this application in <b>{process.env.NODE_ENV}</b> mode.</small>
      <form>
        <input type="hidden" defaultValue={process.env.REACT_APP_NOT_SECRET_CODE} />
      </form>
    </div>
  );
}
```

これをnpm startして、ブラウザで画面を見てみます。検証をして内容を見てみると以下のようになります。REACT_APP_NOT_SECRET_CODEの内容が丸見えですね。

```html
<div>
  <small>You are running this application in <b>development</b> mode.</small>
  <form>
    <input type="hidden" value="abcdef" />
  </form>
</div>

```

## どうするか

クライアント側から直接シークレットキー等を使用して外部のAPIを叩いているという状態を避けるためにどうするかという問題ですが、APIキーやシークレットはバックエンドにのみが持つべきだそうです。

**クライアントがバックエンドAPIにリクエストを送り、バックエンドAPIがAPIキーを使って実際のAPIコールを行い、データをクライアントに送り返すように実装する**のが良いのではないかと考え、そちらの方向で実装をするようにしました。またAPIキーの使用範囲の制限などをしていたり、特に公開されても問題のないキーであれば、それを使用してフロントエンド側から外部のAPIを直接叩いても問題ないと思います。

以上です。コメント、指摘等あれば宜しくお願い致します🙇‍♂️
Doma2で前方一致検索をしたい場合は@prefixを活用する。

自分がかかわっているシステム開発プロジェクトで、他のチームがこのことでえらく盛り上がっていたので、自分なりに調べた結果を残しておきたいと思います(´・ω・｀)

# 前提

商品在庫を管理するシステム(Java + Doma2)を構築するにあたって、ユーザ入力値をもとに商品名を前方一致で検索したいという要件があったとします。

この要件を実現するため、とある開発者が実施したことは、まず以下のような2-way SQL (`findLikeName.sql`)を用意することでした。

```SQL:findLikeName.sql
SELECT *
  FROM product
 WHERE name LIKE /* name */'みかん%'
```

これを以下のような形で呼び出すわけですね。

```java
String name = "りんご"; // ユーザの入力した値
name += "%";
List<Product> products = productDao.findLikeName(name);
doSomething(products);
```

この場合、以下のようなクエリが発行されるので、要件が実現できているように見えます。

```sql
SELECT *
  FROM product
 WHERE name LIKE 'りんご%'
``` 

# 問題点

たとえばユーザ入力値が`%`だったとします。

```java
String name = "%"; // ユーザの入力した値
name += "%";
List<Product> products = productDao.findLikeName(name);
doSomething(products);
```

この場合、以下のようなSQLが実行されます。

```sql
SELECT *
  FROM product
 WHERE name LIKE '%%'
``` 

このクエリはnameがnull以外の行にヒットしてしまいます。これでは`%`で商品名を前方一致検索したいという要件にこたえられていないだけでなく、セキュリティ上の問題を発生させる可能性すらあります。

# 修正方法

[この解決策としては`Expression language`の`@prefix`を利用することです。](https://doma.readthedocs.io/en/2.46.0/expression/#using-built-in-functions)

今回の場合はまず`findLikeName.sql`を以下の通りに修正します。

```sql:findLikeName.sql
SELECT *
  FROM product
 WHERE name LIKE /* @prefix(name) */'みかん%'
```

その後呼び出し方を以下のように修正します。

```java
String name = "りんご"; // ユーザの入力した値
List<Product> products = productDao.findLikeName(name);
doSomething(products);
```

`@prefix`は入力パラメタを前方一致検索用の文字列に変換してくれるだけでなく、`%`や`_`のような特別な意味を持つ文字をエスケープしてくれる関数です。そのため、パラメタとして`%`が渡されたとしても安心ということですね。

# 環境情報 (pom.xmlから抜粋)

```xml:pom.xml
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.seasar.doma.boot</groupId>
    <artifactId>doma-spring-boot-starter</artifactId>
    <version>1.5.0</version>
</dependency>
<dependency>
    <groupId>org.seasar.doma</groupId>
    <artifactId>doma-processor</artifactId>
    <version>2.30.0</version>
    <scope>provided</scope>
</dependency>
```
クラスがないGo言語(golang)でstructとメソッドを使った計算してみた。（初心者向け）

go言語(golang)でstructとメソッドを使った計算してみました。

<b>現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
https://www.udemy.com/course/go-fintech/learn/lecture/12003084#content
問題内容はこちらから↑


演習問題で『structとメソッドを使った３と４を足して7を出す』演習問題ありましたので、
コードを書いてみました。

まず自分の回答から

##回答

```
package main

import (
	"fmt"
)

type Vertex struct{
	X, Y int
}

func (v Vertex) Plus() int{
	return v.X + v.Y
}

func main(){
	v := Vertex{3, 4}
	fmt.Println(v.Plus())
}
```







##問題

```
package main

import (
	"fmt"
)

type Vertex struct{
	X, Y int
}


func main(){
	v := Vertex{3, 4}
}
```


##解説



```
func (v Vertex) Plus() int{
	return v.X + v.Y
}
```

このような感じで任意の関数名(ここではPlus)とinteger(int)と返り値の含まれたコード(return)を
書いてみました。オブジェクト指向型言語だと**クラス**みたいなやつですね。。。
これをGo言語では**メソッド**といいます。



**※因みに、Go言語にはクラスがないみたいです。。。**



ソースコードを全体ソースコードに入れると、

```
package main

import (
	"fmt"
)

type Vertex struct{
	X, Y int
}

func (v Vertex) Plus() int{
	return v.X + v.Y
}

func main(){
	v := Vertex{3, 4}
}
```

こんな感じです！！

紐付けしたコードを足したいので、
mainの箇所でfmt.Printlnで変数のvとPlus関数(任意の関数名)で


```
func main(){
    v := Vertex{3, 4}
    fmt.Println(v.Plus())
}
```

出力します！！

最終的な全体のソースコードが
**回答**になります！！！


#感想

Javaのオブジェクト指向の理解をしていたので、
分かりやすかったです。
他言語をマスターしていると簡単かもしれませんね。

逆に初心者からするとここから第一の壁かもしれない。。。汗



###~おまけ~
**クラス**とは...
**プログラムを作るための設計図**。
Javaなどのオブジェクト指向の言語でよく出てきます。

参考サイト↓
https://wa3.i-3-i.info/word1120.html
GCEのサイトをSSL化

## インストール方法を確認
無料の Let's Encrypt でSSL証明書を発行するため、インストール方法を[Certbot公式サイト](https://certbot.eff.org/)で確認。

今回使ったGCEはDebian10+Nginxだったので[この手順](https://certbot.eff.org/lets-encrypt/debianbuster-nginx)に沿って作業を行う。

## Snappyのインストール
パッケージ管理ソフト Snappy をインストールする。

```
$ sudo apt update
$ sudo apt install snapd
$ sudo snap install core; sudo snap refresh core
core 16-2.49.2 from Canonical✓ installed

```

## certbot のインストール
古いパッケージがあればアンインストール

```
$ sudo apt-get remove certbot

```
Snappyを使って最新インストール

```
$ sudo snap install --classic certbot
certbot 1.14.0 from Certbot Project (certbot-eff✓) installed

```

シンボリックリンク作成

```
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
```

## Certbot設定実行
Nginx用設定を自動実行

```
$ sudo certbot --nginx
```

メールアドレスを入力

```
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): <メールアドレス>
```
使用許諾

```
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
```

寄付のメールを送って良いか？

```
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 
```

```
Congratulations! You have successfully enabled https://hogehoge
```

以上
ざっくりMVCモデルについて解説してみた！

# はじめに
私自身、MVCモデルを説明してみて？と聞かれた時に、
詰まってしまったので、知識の整理を目的に本記事を作成しました！

# 本記事の対象者
* プログラミングを学び始めた人
* MVCモデルを理解したい、または復習したい
* これからフレームワーク（Ruby on Rails, Laraval, Express、Vue.jsなど）を使用して開発をしていきたい

上記を対象とした方の力になれれば幸いです。

それではいきます！！！

# 概要
MVCとは機能でなく、数多くある中でのデザインパターンの一つである！
以下はWikipediaに書かれている[デザインパターン](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))の解説です。

```
ソフトウェア開発におけるデザインパターン（型紙（かたがみ）
または設計パターン、英: design pattern）とは、
過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、
名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものである。
```

デザインパターンを噛み砕いて説明すると次のようなイメージとなります。

* 実装でよくあるパターンを定型化したもの

* 過去にプログラミングの達人たちが作った、
コードをキレイにかくためのテンプレートのようなもの
(将棋の定跡・囲碁の定石のようなもの)

* 実装コードが大きくなっても、パターン(テンプレート、定石)に
当てはめて実装することで、管理しやすくなる

そして、「MVCは数多くあるデザインパターンのうちの1つ」という理解が大切です！

## MVCの役割を理解する
「MVC」は「Model」「View」「Controller」の3つ頭文字をとったものです。

実装する機能によって「Model」「View」「Controller」の3つのカテゴリにわけて、実装コード(ファイル)をカテゴリ毎に管理するためのものです。

まずはこちらの画像でざっくりデータの流れを把握しましょう！

![スクリーンショット 2021-04-11 12.50.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705266/4bce2bb3-595a-ae03-05f4-b0bb43b5ec61.png)

①〜⑧のデータの流れをざっくりいくと

* サーバーはクライアントからリクエストを受け取る
* リクエストに応じて「MVC」の各モジュールが連携してレスポンス値を生成する
* サーバーは生成したレスポンス値をクライアントに返す

### Modelの役割
**Modelはデータ管理の役割を持つモジュール(=パーツ)**

* データベースとの（DB）とのやりとりを行う
* データの操作を行う（作成、取得、削除、更新）→　CRUD処理と呼ばれる
* データの加工を行う（Modelが保持しているデータを組み合わせ、求めているデータ形式に変換する）

### Viewの役割
**Viewは表示周りの責任を持つモジュール**

* テンプレートファイルと呼ばれるHTMLを生成するコードを実装
* テンプレートファイルでは外から受け取ったデータを埋め込むことが出来る

そして、次に説明する「Controller」が利用するテンプレートファイルを指定して、生成されたHTMLコードをクラインアントに返すことで、Webブラウザ上でHTMLコードを元にWebページが表示されるようになるという流れです。

### Controllerの役割
**ControllerはModel、Viewの橋渡しの役割をもつモジュールです。**

* クライアントからのリクエストに応じた処理を実行
* 必要に応じてModelからデータの受け渡しを行う
* Viewを生成する際に、必要に応じてModelから受け取ったデータをViewに渡す
* クライアントにレスポンスとしてViewや、API通信であればJSON形式のデータを返す

端的にいうならば、クライアント、Model、Viewの仲介役をになってくれていると思ってください！

# まとめ

1. MVCは機能ではなく、デザインパターンの一つであり、コードをきれいに保ち、かつ保守性の高い状態で管理するために使用される
1. MVCは「Model」「View」「Controller」の頭文字をとったもので、実装する機能に応じてファイルを「Model」「View」「Controller」にわけることで作業を分担して開発を進めることができる
1. Modelはデータ管理の責任をもつモジュール
1. Viewは表示周りの責任をもつモジュール
1. Controllerは他のモジュール(Model, View)やクライアントとの仲介役の責任を持つモジュール
yukicoder contest 290 参戦記

# yukicoder contest 290 参戦記

★1.5が3つ、★2が2つあって前回に続いて ABC っぽさを期待したが、まあいつもの星数詐欺でした.

## [A 1469 programing](https://yukicoder.me/problems/no/1469)

理由は知らないのですが、Python の文字列の加算は遅くないので、素直に加算すれば良い.

```python
S = input()

result = S[0]
for c in S[1:]:
    if c == result[-1]:
        continue
    result += c
print(result)
```

文字列の加算が遅い言語は StringBuilder を使うなり、リストに追加して最後に join するなりすればいいんじゃないですかね.

```python
S = input()

t = [S[0]]
for c in S[1:]:
    if c == t[-1]:
        continue
    t.append(c)
print(''.join(t))
```


## [B 1470 Mex Sum](https://yukicoder.me/problems/no/1470)

2つの値の mex は 1, 2, 3 のどれか. 後は場合分けして計算するだけ.

```python
N, *A = map(int, open(0).read().split())

a, b, c = 0, 0, 0

for x in A:
    if x == 1:
        a += 1
    elif x == 2:
        b += 1
    elif x >= 3:
        c += 1

result = 0
result += a * (a - 1) // 2 * 2  # mex(1, 1)
result += a * b * 3             # mex(1, 2)
result += a * c * 2             # mex(1, >=3)
result += b * (b - 1) // 2 * 1  # mex(2, 2)
result += b * c * 1             # mex(2, >=3)
result += c * (c - 1) // 2 * 1  # mex(>=3, >=3)
print(result)
```

## [C 1471 Sort Queries](https://yukicoder.me/problems/no/1471)

各インデックスまでのアルファベットの累積出現数を求めておけば *O*(26) でクエリに回答できる. *N*,*Q*≦10<sup>4</sup> なので、時間及び空間計算量は 2.6×10<sup>5</sup>となり問題ない.

```python
from sys import stdin

readline = stdin.readline

N, Q = map(int, readline().split())
S = readline()[:-1].encode('us-ascii')

a = [0] * 26
b = []
for c in S:
    i = c - 97
    a[i] += 1
    b.append(a[:])

result = []
for _ in range(Q):
    L, R, X = map(int, readline().split())
    L, R = L - 1, R - 1
    t = b[R][:]
    if L != 0:
        u = b[L - 1]
        for i in range(26):
            t[i] -= u[i]
    c = 0
    for i in range(26):
        c += t[i]
        if c < X:
            continue
        result.append(chr(i + 97))
        break
print(*result, sep='\n')
```

## [E 1473 おでぶなおばけさん](https://yukicoder.me/problems/no/1473)

到達可能な体重を最大化するように、同じ到達可能な体重であれば通る必要のある道の数を最小化するように幅優先探索するだけ.

```python
from collections import deque
from sys import stdin

readline = stdin.readline

INF = 10 ** 18

n, m = map(int, readline().split())

links = [[] for _ in range(n)]
for _ in range(m):
    s, t, d = map(int, readline().split())
    s, t = s - 1, t - 1
    links[s].append((t, d))
    links[t].append((s, d))

q = deque([(0, INF)])
dp = [(-1, -1) for _ in range(n)]
dp[0] = (INF, 0)
while q:
    cp, mw = q.popleft()
    if dp[cp][0] > mw:
        continue
    for np, lw in links[cp]:
        w, s = dp[np]
        nw = min(mw, lw)
        if w >= nw:
            continue
        if w == nw:
            dp[np] = (nw, min(s, dp[cp][1] + 1))
        else:
            dp[np] = (nw, dp[cp][1] + 1)
        q.append((np, nw))
print(dp[n - 1][0], dp[n - 1][1])
```
【Pandas】matplotlibを使ってグラフを書く方法 ② .no.38

![見出しを追加 (97).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7b2c2a59-b02f-1fae-f15f-3d8ef8b8960e.png)
こんにちは、まゆみです。

Pandasについての記事をシリーズで書いています。

今回は第38回目になります。

今回は、[前回の記事](https://qiita.com/Mayumi_Pythonista/items/48eea3dd9057d2babc58)に引き続きmatplotlibライブラリーを使ってグラフを描く方法を書いていきます。

前回は

>折れ線グラフ

を描く方法について書きました。

今回は、

>棒グラフと

>円グラフ

の描き方について書いていきます。

では早速はじめていきますね。

#棒グラフ(bar chart)の描き方

棒グラフに適しているのは、『カテゴリーに分けられたグループのそれぞれのカウント数』のデータなどなので、『[セントラルパークのリスに関するデータ](https://data.cityofnewyork.us/Environment/2018-Central-Park-Squirrel-Census-Squirrel-Data/vfnx-vebw)』を使って、グラフの描き方を説明していきます。


![スクリーンショット 2021-04-11 115408.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/9715f5bd-be86-01bd-0209-1eb54a0ec167.jpeg)
上記のような数字だけでデータを示すのではなく

![スクリーンショット 2021-04-11 115500.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/67063441-a9e9-d545-78fe-8228ddf1e1c1.jpeg)

このようなグラフにすると一目でデータの概要をつかむことができます。


matplotlibとPandasをインポートします(matplotlibのインポートについての注意点は[こちら](https://qiita.com/Mayumi_Pythonista/items/48eea3dd9057d2babc58#matplotlib%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88)を参考にどうぞ)

```
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
```

.read_csv()でデータを読み込むと下のようになります。

![スクリーンショット 2021-04-11 115639.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7a395f9d-4207-9c11-7543-0eca4d4c0ccb.jpeg)

『Primary Fur Color』はリスの毛の色についてのコラムなので、こちらのコラムをGray, Black, Cinnamon に分け、アイテム数を棒グラフにします。

#.value_counts()でそれぞれの値の数を取り出す

```
df["コラム名"].value_counts()
```
で、それぞれの値がいくつあるのかを取り出すことができるので、まず.value_counts()を使い、3つのグループのそれぞれのカウント数を調べましょう


![スクリーンショット 2021-04-11 120105.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/45e56a84-67f6-262f-136a-262c27c4085f.jpeg)

この後ろに、.plot()メソッドを使うと、折れ線グラフが示されます。


![スクリーンショット 2021-04-11 120343.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/34167a9f-7509-fb2b-74cd-8a8ea5eadc4a.jpeg)


<font color="Red">.plot()のパラメーターkindに引数『bar』</font>を渡せば、棒グラフにすることができます。


![スクリーンショット 2021-04-11 121422.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/95e1ebe2-3178-3ef8-040c-2bd3bcfdc220.jpeg)

引数をbar ではなく、『barh』にすると、bar<font color="Red">h</font> はbar <font color="Red">H</font>orizontal(horizontalは<font color="Red">水平方向の</font>という意味です。)という意味であり、下記のように横軸・縦軸が入れ替わります。


![スクリーンショット 2021-04-11 121826.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e94a6e8d-0206-5afa-2400-8f00d400b6e3.jpeg)

#円グラフ(pie chart)の描き方

![見出しを追加 (96).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/30f268b0-15d7-e32c-b52c-2082eed61a4a.png)

円グラフは全体のどれくらいの割合なのかを視覚で訴えたい時に便利です。

.plot()に渡す引数を"pie"にします


![スクリーンショット 2021-04-11 122952.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/ef2b8ec1-185c-a603-824f-e4ce179ab735.jpeg)

#まとめ

前回に引き続きmatplotlibを使ってグラフを描く方法を書かせていただきました。

色んなデータを使って是非、応用してみてくださいね。