OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsでport 3000のプロセスを探してkillするDOS バッチファイル(Windows10)

環境: Windows10 (7でもokと思われ)
Node.jsの開発などで時折localhost:3000とタイプすると

```DOS:error
Port 3000 is already in use
```
と出て進まないとき、手動でプロセス番号を探してkillするのが手間なので、DOSバッチファイルにしました。

```DOS:processkill.bat
FOR /F "delims=" %%i in ('netstat -aon ^| findstr 0.0:3000') do set NODEPORT=%%i
echo off
@REM 出力の最後がPORTを表しているので、末尾まで読んでいる
for %%a in (%NODEPORT%) do (
set TEMPB=%%a
)
echo %TEMPB%
taskkill /pid %TEMPB% /F
```

実行法はコマンドプロンプトから

```DOS:cmd
>processkill.bat
```
だけです。

元は
netstat -aon ^| findstr 0.0:3000
で出てきたプロセス番号を読んで
taskkill /pid <プロセス番号>
とするコマンドで、このプロセス番号が一意に決まっていないので、ちょっと面倒でした。

以上です。
【SQL】表示条件・計算など:定義された関数での計算や表示順(各種関数, CASE, HAVING, GROUP, ORDER)

# はじめに
SQLはデータベースを操作するためのプログラムです。
プログラムをどのように分解するかは賛否あると思いますが、
ここでは以下の４つに分類して基本の構文をまとめます。

- [処理内容:検索/更新/挿入/削除のいずれの処理をおこなうか](https://qiita.com/yatto5/items/4a2105318f6b2a8520bf)
- [対象テーブル:処理対象のテーブルと、テーブル間の関係](https://qiita.com/yatto5/items/0f64db56928c84deaca0)
- [絞り込み条件:対象レコードをどのように絞り込むか](https://qiita.com/yatto5/items/df7742990e2d28057d45)
- **表示条件・計算など:定義された関数での計算や表示順など**

このページでは表示条件の基本構文をまとめます。
表示条件とは書いたもののかなり雑多な内容になっています。各種集約関数とGROUP/HAVING句、条件式のCASE、表示順を決めるORDER句をまとめています。

例として、[こちら](https://qiita.com/yatto5/items/4a2105318f6b2a8520bf)に掲載しているテーブルを使って、各条件の動きを解説します。

# 集約関数(GROUP BY, HAVING)
集約関数はDBMSによっていくつかありますが、主だったものは5つです。

|集約関数|概要|
|---|---|
|SUM|条件に一致するデータを集約して列の合計値を取得|
|AVG(AVERAGE)|条件に一致するデータを集約して列の平均値を取得|
|COUNT|条件に一致するデータの件数を取得|
|MAX|条件に一致するデータのうち最大値を取得する|
|MIN|条件に一致するデータのうち最小値を取得する|
参考資料：[逆引きSQL構文集 - 集計関数を使用する(基本)](http://www.sql-reference.com/summary/summary.html)

**GROUP BY**は集約の単位を指定することができ、これはSELECT句で指定する項目(集約関数は除く)と一致します。
*SELECT句の指定が集約関数のみの場合は、GROUP BY句を省略することができます。

## 数値を計算する関数(SUM, AVG, MAX, MIN)
個人的にはこの4つは使用方法が同じです。
集約単位を指定して、主に数値項目のカラムを関数内に指定する使い方です。(MAXとMINは日付型や文字列型でも利用できます)

例えば、数学テストの成績リスト(MATH_TEST)の平均点を抽出したい時は以下の形になります。

**MATH_TEST**

|ID|SCORE|
|---|---|
|0001|70|
|0002|80|
|0003|50|
|0004|100|
|0005|80|

```SQL:AVG
SELECT AVG(SCORE) AS 'AVERAGE' FROM MATH_TEST
```
実行結果は1レコードです。

|AVERAGE|
|---|
|76|

男女別で表示したい時は、GROUP BY句を利用します。

```SQL:AVGbyGender
SELECT T02.GENDER, AVG(T01.SCORE) AS 'AVERAGE' FROM MATH_TEST T01
   INNER JOIN MEMBER_LIST_2ND T02
   ON T01.ID = T02.ID
   GROUP BY T02.GENDER
```
実行結果は2レコードになります。

|GENDER|AVERAGE|
|---|---|
|M|66.66|
|F|90|

## データの件数を取得する(COUNT)
COUNT関数を分けたのは、上記の計算する関数とは異なる動きがあるためです。
COUNT関数でカウントされるのはNULL以外のデータが保持されている場合です。
そのため、あるテーブルのレコード数を取得したい場合は"*"を指定する、またはNULLが許容されていないカラムを指定することで実現できます。
"*"を指定すると対象テーブルのレコード数を取得します。
```SQL:COUNT_ALL
SELECT COUNT(*) AS 'MEMBER_COUNT' FROM MEMBER_LIST_2ND
```

|MEMBER_COUNT|
|---|
|5|

特定のカラムを指定した場合には、NULL以外のデータ件数を取得します。

```SQL:COUNT_NOTE
SELECT COUNT(ID) AS 'ID_COUNT',  COUNT(NOTE) AS 'NOTE_COUNT' FROM MEMBER_LISET_2ND
```

|ID_COUNT|NOTE_COUNT|
|---|---|
|5|0|


# 条件式(CASE WHEN)
CASE式は条件分岐をおこなって条件に対応する結果を抽出します。
*2つ目の条件分岐(GENDER = '2')やELSE条件は省略することもできます。条件に合致しないデータはNULLになります。

```SQL:CASE_1
SELECT ID,
   CASE 
      WHEN GENDER = '1' THEN '男性'
      WHEN GENDER = '2' THEN '女性'
      ELSE '不明'
   END AS '性別'
   FROM MEMBER_LIST_2ND
```

|ID|性別|
|---|---|
|0001|男性|
|0002|男性|
|0003|男性|
|0004|女性|
|0005|女性|


# 表示順(ORDER BY)
並び順決定の優先カラムとその昇順、降順を指定することができます。
書き方は2通りあり、カラム名を指定する方法と左から何番目のカラムかを指定する方法です。
降順を指定する場合はカラム名(カラム番号)の後ろに"DESC"をつけます、昇順はカラム名だけでOKです。

以下の参考SQLは同じ結果が抽出されます。

```SQL:SORT_1
SELECT ID, BIRTH_DAY, GENDER FROM MEMBER_LIST_2ND 
   ORDER BY GENDER , BIRTH_DAY DESC
```

```SQL:SORT_2
SELECT ID, BIRTH_DAY, GENDER FROM MEMBER_LIET_2ND
   ORDER BY 3 , 2 DESC
```

|ID|BIRTH_DAY|GENDER|
|---|---|---|
|0005|1980/12/14|F|
|0004|1980/8/2|F|
|0002|1981/3/1|M|
|0001|1980/10/25|M|
|0003|1980/4/2|M|
ヘルパーメソッド

様々なform系ヘルパーメソッドをそれぞれ紹介します。
**ヘルパーメソッド**:よくあるHTMLの作業を簡単にするため、動的テンプレートの中で使用できるメソッド。
##form_tagメソッド
検索フォームのような入力されたワードをデータベースに保存する必要のないフォームに使用。
##form_withメソッド
保存する必要がない場合でも、form_forと同じようなコードで書くことができます。
こちらも、form_forと同様、投稿フォームに投稿された内容をデータベースに保存することができます。(rails5.1からはこのメソッドを使用することが推奨されている。)
##form_forメソッド
railsで情報を送信する時のメソッド。簡単に入力（投稿）フォームに必要なHTMLを作成できる。テーブルにレコード（行）を新規作成、更新するときに使用する。
*セキュリティの面から、直接inputタグは使いません。（データを書き換えられてしまうリスクあり。）

**使い方**

```ruby:view
<%= form_for('モデルクラスのインスタンス') do |f| %>
  フォーム内容
<% end %>
```
*モデルクラスのインスタンス:保存したいテーブルのクラスのインスタンスのこと。
（例）propertiesテーブルに新たにレコードを作成したいので、コントローラーで下記のように記述します。以下の、@propertyをform_forの引数に指定します。

```ruby:controller
def new
  @property = Property.new
end
```
form_forではどのように送信先を決定しているのかについては、コントローラーで作成したインスタンスが、newメソッドで新たに作成されて何も情報を持っていない場合、自動的にcreateアクションへ、findメソッドなどで作成され、すでに情報を持っている場合は、updateアクションへ自動的に振り分けてくれます。

```ruby:controller
#新たに作成したレコードなため、createアクションが動く
def new
  @property = Property.new
end
#既に情報を持っているレコードを取得しているため、updateアクションが動く
def edit
  @property = Property.find(params[:id])
end
```
**ネストしている場合の使用方法**
ルーティングでネストを定義している場合は記述が変わります。

*ネスト:入れ子構造とも呼ばれる。ある記述の中に入れ子構造で別の記述をする方法。ルーティングでいうと、あるコントローラーのルーティングの記述の中に、別のコントローラーへのルーティングを記述することを指す。

賃貸物件の最寄り駅を登録するフォームを例に挙げます。以下のように記述します。

```ruby:routes.rb
resources :properties do
  resources :nearest_stations
```

```ruby:controller
def new
  @property = Property.find(params[:property_id])
  @nearest_station = NearestStation.new
end
```

@property = Property.find(params[:property_id])で、最寄り駅の物件を取得しています。

```ruby:view
<%= form_for[@property, @nearest_station] do |f| %>
  <%= f.text_field :route %>
  <%= f.submit %>
<% end %>
```
【python】「"」や「'」を使ったタイム表示(str型)をdatetimeとtimedeltaで秒(float型)に変換する

# 概要
とあるものをスクレイピングしてて，経過タイム的なのの処理に困ったのでメモ．
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407322/27c05b0c-4278-f450-d622-d71c45bc0fea.jpeg' width=10%>
こういうストップウォッチの表記知ってますか？
「x'yy"z」 は「x分yy.z秒」ということになります．この文字列（str型)からpythonを使って秒(float型)に変換したいというのが今回やりたいことです．
例えば
「1'45"5」 -> 105.5秒という変換です．

# 1. Datetimeのstrptimeを使って文字列をdatetime型に変換

プログラム中では，pythonの文字列型は`'hoge'`または`"hoge"` で記述されますが，今回のタイム表記「x'yy"z」は文字列中に「'」,「"」が含まれてしまいます．こういった場合は，pythonの文字列では`\`を使って対応し，`'x\'yy"z'`という表記になります．
これをstrptimeを使ってdatetime型にすると次のようになります．

```python
from datetime import datetime
# %Mは分，%Sは秒，%fはマイクロ秒
strtime = '1\'45"5' # 文字列
t = datetime.strptime(strtime, '%M\'%S"%f')
print('t:', t)
print('type:', type(t)) 

# Output
# t: 1900-01-01 00:01:45.500000
# type: <class 'datetime.datetime'>
```

これだけだと，datetimeは日付型なので，1900年1月1日0時1分45秒500000マイクロ秒ということになってしまいます．
今回は日付ではなく，「タイム」として扱いたいので，これだけでは不十分です．
そこで，timedelta型へ変換します．

# 2. timedelta型へ変換，更に秒への変換
timedeltaは日付や時間の足し引きに使われたりするように，「日付」ではなく「時間」を表します．しかし文字列から直接の変換ができないためdatetime型を返しました．
datetime型からtimedelta型への変換は次のとおりです．

```python
from datetime import timedelta
t_delta = timedelta(
    seconds=t.second,  # datetime型tの秒が格納されている
    microseconds=t.microsecond,  # datetime型tのマイクロ秒が格納されている
    minutes=t.minute,  # datetime型tの分が格納されている
)
print('t_delta:', t_delta)
print('type:', type(t_delta))
# Output
# t_delta: 0:01:45.500000
# type: <class 'datetime.timedelta'>
```

timedelta型では日付ではなくなり，時間としての1分45秒5として扱われていることがわかります．
最後に1分45秒5を秒のみに変換します．
もちろん，手動でプログラミング書いてもいいですが，timedeltaでは`total_seconds()`というメソッドがあり，一発で秒への変換が可能です！

```python
tdl2sec = t_delta.total_seconds()
print(tdl2sec)
print(type(tdl2sec))

#Output
# 105.5
# <class 'float'>
```

めでたく目標達成！！
STS起動時の「failed to create the java virtual machine」

# はじめに
久しぶりに macにインストールしていたSTSを起動すると、
「failed to create the java virtual machine」とダイアログが表示されました。

java コマンドは正常に動作している。

iniファイルに -vm を設定することまでは簡単に見つけるも、別のエラーに変わるだけで解消せず。
解消方法の記事を見つけるまでに時間がかかったので、残しておく。

# 対処方法

### iniファイルを開く

```bash
$ vim /Applications/SpringToolSuite4.app/Contents/Eclipse
```

### 追記内容

```bash
-vm 
/Library/Java/Home/bin
```

# References
- [macでeclipseを起動時にFailed to create the・・・](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1379352578)
【GAS】Google Calendarの予定の取得・追加・削除

# はじめに
GASの始め方は[前回](https://qiita.com/koichi_baseball/items/e4754bd1bd72666ab07b)紹介しました。
次はGoogle Calendarの予定を取得したりしてみましょう。

# Google Calendarのクラス・メソッド一覧
基本的には、Calendar(カレンダー)に紐づく⇒Event(予定)に紐づく⇒CreatorやGuestなど(作成者や招待者)クラスが用意されていて、それぞれにメソッドがあります。
[このサイト](https://google-apps-script.net/instructions/?p=249)に非常によくまとまっています。

今回は使っていきながら紹介します。

# Google Calendarの予定を取得する
予定の取得はGoogle Calendarのメールアドレスから取得することができます。
`CalendarApp.getCalendarById()`でカレンダーの取得。
取得したカレンダーに対して`getEventsForDay(date)`で`date`の1日の予定を取得でき、期間を指定する際は`getEvents(startDate, endDate)`を使って開始日と終了日を指定できます。

`date=new Date()`の引数を空欄にしておけば実行した時間が返ってきます。当日の予定の取得はそのまま空欄でいいですね。

```Javascript
function getCalendarEvent(){
  // カレンダーの予定を取得する
  var id = 'メールアドレス';
  var cal = CalendarApp.getCalendarById(id);
  var date = new Date('日時');
  var events = cal.getEventsForDay(date);
  Logger.log(events);
  if(events.length==0) Browser.msgBox("予定はありません");
}
```

# Google Calendarの予定を追加する
追加の際には基本的に自分がログインできているメールアドレスでないと許可が出ません。注意してください。
メールアドレスからカレンダーを取得する部分までは予定の取得の部分と一緒で、予定を追加する際の`createEvent()`メソッドの引数は、**title, startTime, endTime, option**となっています。
さらに、`option`内には**description,guests,location,sendInvites**となっています。

基本的に英語の通りですが以下のソースコードに説明を書いておきます。

```Javascript
function createEvent() {
  var id = 'メールアドレス';
  var cal = CalendarApp.getCalendarById(id);

  var title     = '予定のタイトル';
  var startTime = '開始時刻';
  var endTime   = '終了時刻';
    
  var option = {
    description : '説明',
    guests      : '招待する人のメールアドレス、複数人の場合は","区切り',
    location    : '場所',
    sendInvites : 'true/false(招待メールを送るか否か)'
  }
  cal.createEvent(title, startTime, endTime, option);
}
```

# Google Calendarの予定を削除する
メールアドレスからカレンダーを取得する部分までは予定の取得の部分と一緒で、予定の削除にはEventクラスの`deleteEvent`メソッドを使います。引数はありません。
以下コードは指定した日付のすべての予定を削除します。

```javascript
function deleteEvent() {
  var id = 'メールアドレス';
  var cal = CalendarApp.getCalendarById(id);
  var date = new Date('日付'); 
  var events = cal.getEventsForDay(date);
  for (var i in events) {
    var event = events[i];
    event.deleteEvent();
  }
}
```

# おわりに
今回は超基本的な内容でしたが、
これらとスプレッドシートを組み合わせることで、予定の作成、確認、削除が簡単にできます！
後日紹介します。

書きました！

https://qiita.com/koichi_baseball/items/4a60d2f79d0f9ca3854e
@ConditionalOnProperty

# はじめに
Springで複数のデータベースを接続していた時、一方のデーターベース接続するアプリで読み込ませたいクラスを変えるために使用しました。個人的には、ややこしいので一度しか使ったことがありません。
下書きに残りぱなしにするのは勿体ないので投稿させて頂きました。

# 本文

``` java
@ConditionalOnProperty
```

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.html
VScode+Docker環境でDockerエクステンションをインストールしてコンテナ管理をGUI化

Dockerを触りはじめて以来、ずっと思っていたことがあります。
<img width="568" alt="スクリーンショット 2020-05-02 20.18.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595139/69b53ab1-7e13-e9a9-eb33-e58773e73141.png">

↑これ。
ターミナルで```$docker ps```してコンテナを確認するとき、見にくくてモヤモヤする...。

なんとかならないかなあと考えて、Docker Desktopからダッシュボード開いて確認したりと試行錯誤したのですが、手間が多くてめんどくさい！となってました。

で、最近VScodeの拡張機能でDockerとの連携機能があったのでインストールしたところ、かなり便利だったので備忘録も込めて文章化します。

#Dockerのコンテナ管理

こんな感じでVScodeの拡張機能からインストールします。
<img width="1440" alt="スクリーンショット 2020-05-02 20.33.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595139/59950416-aa73-d300-283f-f5421a11c717.png">

インストールするとVScodeのサイドバーのアイコンに、Git等に並んでDockerのアイコンが追加されます。
それをクリックすると以下のように、Dockerのコンテナ、イメージ、レジストリ等、Dockerの情報を一元管理することが可能になります。
これは便利。

<img width="1440" alt="スクリーンショット 2020-05-02 20.37.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595139/b4995b3f-3db2-a98f-a262-4fb457bec772.png">

また、コンテナを右クリックすると以下のようなショートカットキーをGUIで操作できます。


<img width="423" alt="スクリーンショット 2020-05-02 20.37.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595139/ddf8bd1e-b5d2-70d0-744d-f8eb4413b82c.png">

これを使ってコンテナ起動から削除までいろいろすることができます。
特にDockerのコンテナを起動する際の
1.ターミナルを開く
2.```docker ps```でコンテナを確認
3.docker -it [コンテナ名/コンテナID]
を全て省略できるのが非常にありがたい。

以上、VScodeのDocker拡張機能でした。

Docker初心者なのでもっと便利な機能があれば追記したいと思います。
jsonリクエスト時の403エラー対策


```java
mport org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/webjars/**", "/css/**");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// @formatter:off
		http.authorizeRequests()
					.antMatchers("/loginForm").permitAll()
					.antMatchers("/customers/create").hasAnyRole("SYSTEM", "ADMIN")
					.anyRequest().authenticated()
				.and()
				.formLogin()
					.loginProcessingUrl("/login")
					.loginPage("/loginForm")
					.failureUrl("/loginForm?error")
					.defaultSuccessUrl("/customers", true)
					.usernameParameter("username")
					.passwordParameter("password")
				.and()
				.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
				.and()
				.logout()
					.logoutSuccessUrl("/loginForm");
		// @formatter:on
	}

	@Bean
	PasswordEncoder passwordEncoderEncoder() {
		return new Pbkdf2PasswordEncoder();
	}
}
```


# 参考サイト
- [Spring Securityを使ったAjax通信について](http://tech.furyu.jp/blog/?p=5706)
- [Spring not sending CSRF token on response] (https://stackoverflow.com/questions/36580295/spring-not-sending-csrf-token-on-response)
- [Spring Security 使い方メモ　CSRF
](https://qiita.com/opengl-8080/items/3720ed415c2df26251a7)
【初心者向け】10行以内のスクリプト(4.pythonからsqlite3への接続)

### 【初心者向け】10行以内のスクリプト(4.pythonからsqlite3への接続)
pythonで色々なライブラリを使えば、「少ないコードでもちょっとした事が出来て、少なければ5行程でもちょっとしたスクリプトが作れ、便利だな。」
と思ったので、pythonやその他、コマンドを羅列しただけのものも出てくるかも知れませんが、10行程のスクリプトを不定期で投稿してみようと思います。

**第4回**として、<font color=blue>pythonからのsqlite3への接続を投稿したいと思います。</font>

pytho3からsqlite3のデータをカーソルで取得・表示するスクリプト
sqlit3はサーバを動かさくてもsql文で検索が出来、ファイルをコピーすれば他の環境でも使え、また最近は機能も増えてきて、分析関数等も使える様です。
pythonでも特別なライブラリ等を用意しなくても、pythonからsqlite3に接続出来ます。
ただ、sqlite3の標準のインターフェースはシンプルで良いのですが、少し長い文や途中で間違えた等となると、正直なところ、入力が面倒だと感じる事があります。
shellスクリプトでも良いのですが、「何かスクリプトにすれば、検索が少し楽になるかな？」と思ったので、pythonからsqlite3への接続を投稿したいと思います。

***
#### pytho3からsqlite3のデータをカーソルで取得・表示するスクリプト

【環境】
Linux: DISTRIB_DESCRIPTION="Netrunner Core 20.01"
python: 3.7
conda: 4.8.3
sqlite3: 3.31.1

因みにこのスクリプトを実行したディストリビューションは、聞き慣れないかも知れませんが、debian系です。また仮想環境も以前使っていたcondaが入っていたのですが、最近、pip3でvenvに移行したので、基本的なオペレーションを思い出すのに、一瞬戸惑ってしまいました。

データは、fredからpandase-datareaderでダウンロード、csvへ書き込んだファイルを使用したいと思います。

### 

データは、事前にsqlite3にインポートした状態です。

コードはターミナルから実行しました。

```python:python3.7

# pythonからsqlite3に接続
# 全データを取得、表示
# データベース名= './dexjpus_20200501.sqlite3'
# テーブル名= 't_dexjpus'
# 
import sqlite3

# データベース接続の定義
dbname = './dexjpus_20200501.sqlite3'
conn = sqlite3.connect(dbname)
cur = conn.cursor()

#df = pd.read_sql( 'select * from t_dexjpus;' ,conn)
# 全データ取得
all_data = 'select  * from t_dexjpus'

# 取得したデータを一行ずつ表示
for row in cur.execute(all_data):
        print(row)

cur.close()
conn.close()

```

**1.データベース接続の定義**
sqlite3の場合、データをインポートしたファイル名を記述
このデータベースは、カレントディレクトリに「dexjpus_20200501.sqlite3」として作りましたので、このスクリプトでは、
しましたので、データベース名は 「dexjpus_20200501.sqlite3」としました。

```python:python3.7

dbname = './dexjpus_20200501.sqlite3'
conn = sqlite3.connect(dbname)
cur = conn.cursor()

```

**2.データの取得**
「'select * from テーブル名'」を変数に格納しました。
テーブル名は、「t_dexjpus」としましたので、全データを取得するとして
all_data = 'select * from テーブル名'

```python:python3.7
# 全データ取得
all_data = 'select  * from t_dexjpus'

```

**3.取得したデータを表示して、接続を終了。**
cur.execute(sql文の内容を格納した先程の変数)
このスクリプトでは、「cur.execute(all_data)」
for文で繰り返す


```python:python3.7

# 取得したデータを一行ずつ表示
for row in cur.execute(all_data):
        print(row)

cur.close()
conn.close()

```

**以上、pythonからsqlite3への接続でした。**
KotlinのGradle


```gradle
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.11'
}

version '1.0-SNAPSHOT'

apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'todolist.MainKt'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    compile "com.sparkjava:spark-core:2.6.0"
    compile "com.fasterxml.jackson.core:jackson-databind:2.8.8.1"
    compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.8"
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

jar {
    manifest {
        attributes 'Main-Class': "$mainClassName"
    }
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
```
MySQLでの暗号化関数

```sql

SELECT TO_BASE64(AES_ENCRYPT('hoge','EA703E7AA1EFDA0064EAA507D9E8AB7E'));
-- SELECT AES_DECRYPT(FROM_BASE64('JrLQBmDIe9pmb4yS0oj4rA=='), 'hoge');
-- SELECT AES_DECRYPT(FROM_BASE64('bNjrqPL0BJ3IrFsueauMbA=='), 'hoge');

SELECT AES_DECRYPT(FROM_BASE64('TTAn0kLBcyPjAisxxO3xSw=='), 'EA703E7AA1EFDA0064EAA507D9E8AB7E', 128);

-- SELECT AES_ENCRYPT(TO_BASE64('alice@kacky.com'), 'hoge');
-- SELECT HEX(AES_ENCRYPT('alice@kacky.com','hoge'));
-- SELECT AES_DECRYPT('U2FsdGVkX1+9zoTboh/6ehJI/89hFnpoHK/nutXVVVfPD8Xdf+EbM59IhwtpUBa+','hoge');

-- SHOW VARIABLES
```
【RPA例題】1行で完成! Automation AnywhereでWebページのBroken Linkチェック

Webサイトのリンク切れチェックは、Webサイト運営の基本的なテスト項目で、既にいろいろなテストツールやスクリプトを書いて対応しているのではないかと思います。Webサイトのテストの目的だけにRPAを導入するのはコストが割にあわない場合が多いですが、Automation Anywhere (AA) であれば無料のCommunity Editionが使えるスモール ビジネスや開発者、学生等[^1]、もしくは既に別目的でRPAを導入している中でついでにWebテストにも導入するのであれば現実味を帯びてきますね(^^)/

AAを使うとWebサイトのリンク切れチェックはとっても簡単で、「**壊れたリンクを検出 (Find Broken Links)**」コマンド1行の記載で終わってしまいます。どうやるのかバージョン別にみてみましょう(^_-)-☆

[^1]: 「スモール ビジネス」に該当するのは、1) (物理および仮想を含む) マシン台数が250 未満、2) ユーザー数が 250 未満、3) 年間収益が 500 万ドル未満の要件に該当する企業のみです。これら 3 つのうち 1 つでも超過している場合、その企業はスモール ビジネスとは見なされません。スモール ビジネス (その関連会社を含む) がCommunity Edition を使用できるのは、組織内のマシン 5 台までとなります。また、IQ Bot を使用して処理/アップロードできるのは、月に 100 ページまでとなります。スモール ビジネス、開発者、学生に限り無料となります。詳細は[AA Community Edition](https://www.automationanywhere.com/jp/products/community-edition)のページを見てください。

# v11.3の場合
**「Web Recorder」-「Find Broken Links」**コマンドを使います。テストするページのURLを指定、指定したページのみにするかサイト全体をテストするかを選択します。後は結果を保存するCSVを指定するだけ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/d4727911-79ee-0f7b-8ffa-597c1c93b369.png)
後は実行するだけです。

実行すると、いつものBot実行ウィンドウの左側に専用の進捗表示ウィンドウが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/0603168b-b3fd-b7ab-016a-cf3033d65671.png)

結果のCSVはこのような内容です。テストしたURLに対してStatusが成功なのか、エラーならエラーコードが格納されていますので、あとはこれをチェックするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/81f059fa-366c-990c-a9a0-5fa644b57598.png)

かかる時間ですが、RPAを実行するマシンスペックやネットワークの帯域幅にもよると思いますが、手元のマシンで試したら、リンクが110個のページで24秒、450個で62秒かかりました。(つまり**1リンク当たり0.15～0.2秒くらい**)

[サンプルBot (BrokenLink.atmx)のGitHubからのダウンロード](https://github.com/o-kura/AutomationAnywhere/blob/master/v11/BrokenLink.atmx)

# A2019の場合
同じコマンドが**「ブラウザ」-「壊れたリンクを検出」**にあります。これを見てみると、v11.3とほぼ同様ですね！さらに「並列スレッドの数」や「タイムアウト (秒)」など、高速化やエラー処理を行う仕組みが追加で実装されています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/443639aa-b0c1-0134-63d3-0f3967cdc138.png)
【RaspberryPi4】OpenCV4やtensorflow-kerasセットアップ

#環境
デバイス:RaspberryPi 4 4GB

##opencvを入れる

```
sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-103
sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5

pip3 install opencv-contrib-python==4.1.0.25
pip3 install opencv-python==4.1.0.25
```

##mysql(mariaDB)をいれる

```
sudo apt install mariadb-server -y
pip3 install flask flask-sqlalchemy mysqlclient
```

##tensorflow kerasの環境を作る

```
pip3 install tensorflow==1.14.0
pip3 install keras==2.2.4
pip3 install sklearn
```

##その他よく使うライブラリ

```
pip3 install boto3
pip3 install pandas
pip3 install matplotlib
pip3 install pykakasi
```
RustでAES-256-CBC暗号化

# 目的
RustでAES-256-CBCの暗号化と復号化をしてみます。試しにRubyで復号化してみます。
暗号化文字列の先頭には16byteのIVを格納しています。

# Rustで暗号化復号化
```rust:Cargo.toml
aes = "0.7.5"
base64 = "0.13.0"
block-modes = "0.8.1"
bytebuffer = "0.2.1"
rand = "0.8.4"
```

```rust:main.rs
use aes::Aes256;
use block_modes::{BlockMode, Cbc};
use block_modes::block_padding::Pkcs7;
use rand::seq::SliceRandom;

type AesCbc = Cbc<Aes256, Pkcs7>;

// ランダム文字列の元
const BASE_STR: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

// IV用にランダム文字列生成
fn gen_ascii_chars(size: usize) -> String {
    let mut rng = &mut rand::thread_rng();
    String::from_utf8(
        BASE_STR.as_bytes()
            .choose_multiple(&mut rng, size)
            .cloned()
            .collect()
    ).unwrap()
}

// 暗号化
fn encrypt(key: &str, data: &str) -> String {
    let iv_str = gen_ascii_chars(16);
    let iv = iv_str.as_bytes();
    let cipher = AesCbc::new_from_slices(key.as_bytes(), iv).unwrap();
    let ciphertext = cipher.encrypt_vec(data.as_bytes());
    let mut buffer = bytebuffer::ByteBuffer::from_bytes(iv);
    buffer.write_bytes(&ciphertext);
    base64::encode(buffer.to_bytes())
}

// 復号化
fn decrypt(key: &str, data: &str) -> String {
    let bytes = base64::decode(data).unwrap();
    let cipher = AesCbc::new_from_slices(key.as_bytes(), &bytes[0..16]).unwrap();
    String::from_utf8(cipher.decrypt_vec(&bytes[16..]).unwrap()).unwrap()
}

fn main() {
    let plaintext = "予定表～①💖ﾊﾝｶｸだ";
    let key = "01234567012345670123456701234567";
    let enc = encrypt(key, plaintext);
    println!("{}", enc);
    let dec = decrypt(key, &enc);
    assert_eq!(plaintext, dec);
    println!("{}", dec);
}
```


# Rubyで復号化
```ruby:main.rb
require 'openssl'
require 'base64'

key = "01234567012345670123456701234567"
encrypted_text = ARGV[0]
encrypted_data = Base64.decode64(encrypted_text)

dec = OpenSSL::Cipher.new('AES-256-CBC')
dec.decrypt
dec.key = key
dec.iv = encrypted_data[0..15]
decrypted_data = dec.update(encrypted_data[16..]) + dec.final
decrypted_data.force_encoding("UTF-8")
puts decrypted_data
puts decrypted_data == "予定表～①💖ﾊﾝｶｸだ"
```
クローラーについて【僕の備忘録】

##前書き
クローラーについて学んだことを自分用にまとめます（2020/05/02現在）
Googlebotを例にとって書きます
あくまで自分用ですので間違っていてもよしなによろしくお願いします～

##クローラーとは
・Webサイトの情報を収集して回るプログラム(例：Googlebot、Bingbot)
・ブラウザの検索エンジンの**検索結果の優先順位付け**に用いられる、結果は各検索エンジンのDBに保存れる
・HTTP/HTTPSプロトコルで得られる情報すべてが対象（HTML、js、cssなど）
・一回では全情報読み込めないらしく、短いスパンで何回もクローラーにアクセスしてもらえる（クローラビリティを向上する）と上位になるらしい。

→Webサイトの制作・運用をして検索結果の上位に表示させるにはクローラーを惚れさせてメンヘラ化させればいい

##クローリングされるサイト
・DBに保存されているサイトのリンクから辿っていく
・サイトマップ（サイトのすべてのURLを記載したxmlファイル）をグーグルに提供することで新規のサイトもクローリングの対象とすることができる。
・Fetch as GoogleからURLを入力してグーグルに送信する。すると対象のURLのサイトのみクローリングの対象に追加される。（サイトマップのほうがまとめてできるのでお得）

→**新規にサイト作ったらサイトマップをグーグルに連携**しましょう。サイトを更新したらサイトマップも更新しましょう。ってことかな

##クローラーの動きの確認
・Google search consoleから過去90日分の統計情報を確認することが可能
※クローリングされるページ数の減少、ページのダウンロード時間が長すぎるときなどはそのページに問題があることも、、そうなるとクローリングされなくなってしまうかもなので割と確認しておいたほうが良さそう

##クローラビリティを上げたい!!!
こっちにまとめたから読んで見ちゃってよ:relaxed:
[SEOについて](https://qiita.com/99knights0/items/a197186510acfe700158)


##まとめ
クローラーはWebサイトの検索結果の順位を決定するのに重要な存在でした！！


###参考にさせて頂いたサイト
https://innova-jp.com/3711/
文字列操作[Visual Studio C#]

```C#
//カッコで囲まれた文字を抽出する
string target = "4984988946484986486 (452E3D09047C8276)";
string pattern = @"(\()(?<body>.+?)(\))";
string body = Regex.Match(target, pattern).Groups["body"].Value;
//結果：body="452E3D09047C8276"

//IPアドレスが該当しているか（122.10.*.*）[正規表現]
string target2 = "122.10.1.1";
string pattern2 = @"122\.10\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])";
bool result = false;
//結果：result=true;

//カンマ区切り文字列を配列にする
string stCsvData = "csv1,csv2,csv3";
string[] stArrayCsvData = stCsvData.Split(',');

//タブ区切り文字列を配列にする
string stTsvData = "tsv1	tsv2	tsv3";
string[] stArrayTsvData = stTsvData.Split('\t');

//期間の開始日と終了日を分けて表示する
string kikan = "2018/08/08 - 2020/07/09";
string[] kikanArrayData = kikan.Split('-');
Array.ForEach<string>(kikanArrayData, x => kikanArrayData[Array.IndexOf<string>(kikanArrayData, x)] = x.Trim());

```
(ISC)² の無料Webinarを観て、CISSPのCPEを獲得するまで

# どうしてこれを書いたのか
自分にとってメインのCPE獲得方法になるので備忘録的に書いた。

# 複数の(ISC)² 資格を持っているのだけど、どうすればいいの？
わからん。

#手順

##1. (ISC)²の会員ページにログインする
[会員ページログインフォーム](https://www.isc2.org/Sign-In?fromURI=https%3A%2F%2Fisc2org.okta.com%2Fapp%2Fisc2orgprod_wwwisc2org_1%2Fexkeq1qd40KCe6cPq0x7%2Fsso%2Fsaml%3FRelayState%3Dhttps%253a%252f%252fwww.isc2.org%253fcheckmem%253dtrue)

##2. OPE Opportunitiesのページにアクセスする
[ここからアクセス](https://www.isc2.org/Member-Resources/CPE-Opportunities)するか、「MEMBERS」→「OPE Opportunities」で移動する。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/1111a67d-1d09-3b65-c6ec-abfd051d80f2.png)
|:-:|

##3. (ISC)² Webinarsから(ISC)² ThinkTankを選ぶ
UIがぼちぼち変わるっぽいのでこの画像は参考。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/9ef50281-a8f0-aceb-c789-000f535794c9.png)
|:-:|


##4. ThinkTank Webinarの視聴を開始しようと思う…
この画像は参考。「Play」をクリックする。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/82b0597c-19ff-782a-ec88-017c0554cf9e.png)
|:-:|


この段階で「どれを観た、どれを観てない」とか視聴管理すると後々捗りそう。


##4-a. （初回のみ）BrightTalkアカウントを登録する
BlightTalkアカウントを持っていないならここで作成するんだけど、(ISC)²アカウントとの紐付けってどうやってやったんだっけかな…

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/72e0fbbc-c21c-a7da-ba9f-6a0b74b4c484.png)
|:-:|

**これをやっておかないと、観たWebinarを手動で登録・管理しないといけなくなって地獄を見る。**

##5. BrightTalkアカウントへのログイン
BlightTalkアカウントを持っているなら、右上の「Log in」からログインする。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/dd9889b4-34e0-9234-84da-c206c4fe6cc2.png)
|:-:|

**これをやっておかないと、観たWebinarを手動で登録・管理しないといけなくなって地獄を見る。**


##6. Webinarをのんびり観る
…の前に、なんかチェックボックス入れるやつがあるけど
「スポンサーから製品の情報は必要？」って内容なのでチェックしないでProceedして大丈夫。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267016/83677bb3-1ca2-dde6-eb84-ddbf95b3d7c7.png)

で、のんびり観る。
**規定時間観ないとCPEカウントされないので注意。**
**CPEは5営業日後ぐらいにグループAへ自動登録される。**

##7. CPE登録　やったね
6がしっかりできてると、CPEが自動登録されるはず。
5営業日経っても自動登録されないなら、視聴時間カウントで何かしら問題があるはずなのでもう一度~~流し見~~視聴するといいかも。
[Notepad++] C言語/Java コンパイル＆実行環境の構築

## 事前準備
#### コンパイラを用意し、使い方を調べる
- この記事はborlandを使用する

```
bcc32 -n出力パス inputFile.c
```
`-n`のうしろに`スペース`を入れないように

#### 文字コード
- プログラムのソースファイルと、これから作成するバッチファイルの文字コードは、こちらではShift-JISに統一している
- もし文字化けが出た場合、文字コードを変えてみてください

## 手順
#### 1. Notepad++プラグインのNppExecをインストール
- 複数行のコマンドを一気に実行できるプラグイン。
- それらのコマンドをスクリプトのように管理できる。
- スクリプトをメニューアイテム/ホットキー候補に作り、Notepad++に提供。
- インストールには、プラグインメニュー＞プラグイン管理＞チェック＞インストール

#### 2. バッチファイルを用意する
- 外部コマンドプロンプトで、コンパイル済みEXEファイルを実行
- 実行終了時に自動的にpauseをかけて、ウィンドウを保持
- 作成フォルダはどこでも良い

```shell:runC.bat
@%1
@echo ーーーーーーーーーーーーーーーーーーーーーーーーーー
@echo ーーーーーーーーーーーーーーーーーーーーーーーーーー
pause
```

1. パラメータで渡されたEXE(フルパス)を実行
2. 終了の目印
3. 終了の目印
4. ウィンドウを保持

#### 3. NppExecスクリプトを作る
- プラグイン＞NppExec＞Execute
- 下記のコードを入れて、【内容】は自分の環境に合わせて書き換える
- OKをクリックし、動作を確認する
- 確認できたら、もう一度プラグイン＞NppExec＞Executeを開き、スクリプトに名前を付けてSaveする（例`runC`）

```:runC
NPP_SAVE
set obj = $(CURRENT_DIRECTORY)\$(NAME_PART)
cd 【C:\C\borland\Bin】
【bcc32 -n$(CURRENT_DIRECTORY) $(obj).c】
cd $(CURRENT_DIRECTORY)
NPP_RUN 【B:\USER_FLODER\document\runc.bat】 "$(obj).exe"
unset obj
```
1. 開いているソースファイルを保存
2. 拡張子なしのフルパスを変数に代入 ※`$(XXX)`はNotepad++の[環境変数](https://so-zou.jp/software/tech/tool/editor/notepad-plus/plug-in/nppexec/)
3. コンパイラディレクターに移動
4. コンパイル
5. 実行フォルダに移動
6. EXEフルパスを渡して、バッチファイルを外部実行
7. 変数objの消去


#### 4. スクリプトをメニューアイテム/ホットキー候補に登録
- プラグイン＞NppExec＞Advanced Options＞左下のMenuItem欄に注目
- メニューアイテム表示名を入力し（例`runC`）、スクリプトを選び、Add/Modifyで登録
- 右下のOKをクリックし、「Notepad++再起動まで変更が反映されないよ」のメッセージボックスが出る。
- Notepad++再起動

#### 5. ショートカットキー設定
- 設定＞ショートカット管理＞プラグインタブ
- `runC`にショートカットキーを設定
- もし競合が出たら、競合するメニューアイテムのショートカットが使わないものなら、解除しても構わない

#### 6. Java編
```:runj.bat
@java %1
@echo ーーーーーーーーーーーーーーーーーーーーーーーーーー
@echo ーーーーーーーーーーーーーーーーーーーーーーーーーー
pause
```

```:runJ(NppExec用スクリプト)
NPP_SAVE
set obj = $(CURRENT_DIRECTORY)\$(NAME_PART)
cd $(CURRENT_DIRECTORY)
"C:\Program Files\Java\jdk1.8.0_181\bin\javac.exe" $(obj).java
NPP_RUN B:\USER_FLODER\document\Java\runJ.bat $(NAME_PART)
unset obj
```
AtCoderのテストケース実行みたいにやりたかった。

#やりたかったこと
皆さんはAtCoderのコードテストやyukicoderのオンライン実行のような機能を利用しようとしたことはありますか？わたしはそれをPythonで実行できたらいいなぁ～と思ってました。

まあ要するに.txtのファイルをPythonのinput()で読み込めたらいいなぁ～ってことです。

なおこの実行環境はWindows10です。
###コマンドプロンプトにおいて
まずはじめに適当なフォルダーを作ってそこに適当なinput用のinput.txtファイルとinput()関数が入ったmain.pyファイルをぶち込んでみましょう。

コマンドプロンプトでさっき作ったフォルダーに移動してpython main.py < input.txtと入力するとあら不思議、textファイルから読み込めているではありませんか！！

ちなみにこれをopen(0).read()とかでやっても動きます。

###Pythonにおいて
わたしはsubprocessでやろうとして試行錯誤しまくって3日つぶしました。あほです。以下のソースコードでprint関数で出てくるoutputが出て来ます。timeoutオプションは実行時間制限、shell=Trueで本物のコマンドプロンプトで動いてくれます。ちなみにoutputはbyte型で出てくるので文字列型にしたい方はencode()で煮るなり焼くなりしてくださいな...

しかし公式のドキュメントにはセキュリティの脆弱性になりうるので使わないことが推奨されます。Winodws滅びの呪文を指定してしまったらPythonだけでなくWindowsごと消え去ってしまいますからね...

```python
import subprocess
print(subprocess.check_output('python main.py < input.txt',timeout=5,shell=True))
```

###実はほかにも...
Popen()関数でもっと詳しくできるらしいです。全くわかりません。理解に5日ぐらいかかりそうです。

#最後に
クソ記事になりました。詳しくなったらもっと書きます。。。
日記を書くためのシェルスクリプト作成

#はじめに
これは、「新しいLinuxの教科書」というLinux入門書の、シェルスクリプトの項の演習問題です。

##内容
シェルを実行したら、本日の日記を作成するファイルが作られる。

```diary.sh
#!/bin/bash

directory="${HOME}/diary"

# データ保存ディレクトリがなければ作成する
if [ ! -d "$directory" ]; then
        mkdir "$directory"
fi

#日記ファイルパスの組み立て
diaryfile="${directory}/$(date '+%Y-%m-%d').txt"

#日記ファイルがなければ（今日初めて書くならば）、先頭に日付を挿入
if [ ! -e "$diaryfile" ]; then
        date '+%Y-%m-%d' > "$diaryfile"
fi

vim "$diaryfile"
```



|  |意味  |
|---|---|
|-d file  |ファイルが存在し、ディレクトリである  |
|-e file  |ファイルが存在する  |
##参考
新しいLinuxの教科書
ヒソカ・モロウ　死神クイズ

<!DOCTYPE html>
<html lang ="ja>

<head>
<meta charset ="UTF-8">
<title>ヒソカ・モロウの紹介ページ</title>
</head>

<boby>
                      <a href ="http://www.yahoo.co.jp">Yahoo Japan</a>
   <a href ="./index2.html">./index2.html</a>
                         <a href ="index2.html">index2.html</a>

   <a href ="./company/index.html">./company/index.html</a>"
   <a href ="./company/about/index.html">./company/about/index.html</a>"
   <a href ="../access///index.html">../access/index.html</a>"
   リンクの作成(wwwフォルダ)
   <img src="./image/device.jpg">
   <img src="./image/device2.jpg">
   <img src="./image/device3.jpg">

   <p>簡易フォーム</p>

   <form method="XXX" action="XXX">
     <p>名前<input type ="text" name="XXX" size ="100" value=死人には名乗っても意味がない🍀></p>
     <p>ニックネーム<input type ="text" name="XXX" size ="100" placeholder ="ネタバレが過ぎるな 後悔するなよエセマジシャン"></p>
     <p>メールアドレス<input type ="text" name="XXX"size="100" placeholder="能力はバラしても構わない"></p>
     <p>URL<input type ="text" name="XXX" value="http://"></p>
     <p>パスワード<input type ="text" name="XXX" size="100" value="パスワードはお死枚 死神クイズに回答者はいらない・・・☠"></p>
     <p>写真<input type ="file" name="XXX" size="100" value="パスワードはお死枚 死神クイズに回答者はいらない・・・☠"></p>
     <p>これから君に渡すのは何枚でしょう？
        <lavel><input type ="radio" name="XXX" size="100" value="パスワードはお死枚 死神クイズに回答者はいらない・・・☠"></p>沈黙 それが 正しい答えなんだ</label>
        <lavel><input type ="radio" name="XXX" size="100" value="パスワードはお死枚 死神クイズに回答者はいらない・・・☠"></p>お死枚 チャンチャン♥</label>

     </p>
     <p>答えは・・・
       <lavel><input type="checkbox" name="XXX" value="XXX">トランプなので実質1枚</label>
       <lavel><input type="checkbox" name="XXX" value="XXX">マジレスすると1枚なんだよな</label>
       <lavel><input type="checkbox" name="XXX" value="XXX">お死枚 死神クイズに回答者はいらない</label>
       <lavel><input type="checkbox" name="XXX" value="XXX">好きな方で逝けや</label>
       <lavel><input type="checkbox" name="XXX" value="XXX">答えが 22枚より多かろうが全部‼撃ち落としてやる!!!</label>
       </p>

       <p>お前らなぁ
         <textarea name="XXX" rows="10" cols ="40" placeholder="お前らはキルア様を追え‼"></textarea>
       </p>
       <p>余計な体力は任務に取っておけ
         <select name="XXX">
           <option value="XXX">お前は俺が遊んでやる</option>
           <option value="XXX">お前は俺が遊んでやる</option>
           <option value="XXX">お前は俺が遊んでやる</option>
           <option value="XXX">お前は俺が遊んでやる</option>

         </select></p>
           <p><input type="submit" value ="お前ら真面目に対応してんじゃねぇよ よけろよけろ"></p>

   </form>

</boby>

</html>
【Unity】ちょ、おま。天才か？と思ったアセットたち

<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/5dde90c4-57b5-926a-5163-a6b3cbb98822.png">

---

##はじめに
Unityで開発していると、「xxみたいなことをしたいんだけど、自分で機能作るのはダルいな～」
と思うことがリアルに2時間に一回くらいあると思います。

そこで、勝手に使ってもよい(かつ基本無料がいいな♡)アセットがないか調べた結果。
「私が求めていたのはまさにこれや！！お前を天才と認めたい！！」と叫んだアセットをまとめていきます。

主観です。

#### 1. デカいterrainを分割してくれるアセット
リンク：[Unity split terrain script](http://kostiantyn-dvornik.blogspot.com/2013/12/unity-split-terrain-script.html)


感想：なんか怪しげな個人サイトなのですが、利用の仕方は非常に明瞭で(サイト内に英語の説明ありますが読まなくてもわかるレベル)速攻分割してくれました。データの破損もなさそう。


#### 1.1 やばい。上(↑)のもっと楽なやつありました(20200711追記)
リンク：Unityのパッケージ

使いかた：
- window>package managerから「terrain toolbox」を検索(2020年7月11日現在preview版なので、「advanced」から検索設定をpreview版も見えるようにしないと出てきませんので注意)、installする
- window>terrain>terrain toolboxからこの画面を開く
<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/aa766bf6-7de0-c0a8-4841-b61c9b109591.png">
- Splitのところで詳細設定をして、「split」を押す。素晴らしすぎ。

#### 2. meshからいい感じにコライダを自動生成してくれるアセット
リンク：[SAColliderBuilder](https://assetstore.unity.com/packages/tools/sacolliderbuilder-15058)


感想：これやばいですよ。まじでやばいです。<b>「meshコライダは重いから使いたくないがboxコライダをチマチマ作るのも面倒」</b>という方にお勧めです。
使いかたも明瞭で、コライダつけたいオブジェクト(もしくはその親)にSA Mesh Collider Builderを張り付けて、右下のProcessを押すだけです。楽ちん杉ですね。
<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/0149b2cf-0de0-3664-5c98-6bb02fe48c7b.png">


備考：
- DLするときに、「Unity4の時に作られたから不具合起こるかもよ」と警告が出ますが私は今のところ大丈夫です。
- 自動なので、いらない場所にもコライダをつけてしまっていることもあります。チェックは必要ですね。
- デフォルトだとすべてのコライダにRigid Bodyがついてしまうので(多分だけど死ぬほど重くなる)、外したい場合はProcessする前に、SA Mesh Collider BuilderのRigidBody項目のIs Create外しましょう。


#### 3. OculusQuestの入力に応じて、自作アバターの握り手を変更してくれるスクリプト(2020/6/2追記)
リンク：[Oculus TouchでUnityちゃんの指を動かして遊ぼう](http://eyln.hatenablog.com/entry/2016/12/19/003435)


感想：Humanoidなアバターであれば、とっても簡単に握りての実装ができちゃいます。自分でやろうかなーとあきらめかけていたところ、たまたまこの記事を見つけ、
大幅に時間が節約できました。やはり、エンジニアに必要なのはググり力ですね。世界一のググジニアを目指して、日々ググり力を極めていきたいと改めて思いました。

備考：記事が書かれたのが2016年とのことですが、今のところ目立ったエラーなどはないです。ただ、即効性(すぐ動かせる)という観点を特化したものなので、凝った動き、オーケーマークとか、キツネの指とかにしたかったら、このスクリプトをもとに自分で実装するしかないです(それは、そう)


追記します。(本当にします)



##参考
上でリンク張って紹介したサイトたち
【Flutter】Flatbutton内にwidget配置したらサイドスペースができてしまう

## はじめに
Flatbuttonを配置して、その中にTextとかImage.asset等のwidgetを配置すると、
配置したwidgetのサイドに謎のスペースが出来て少し困ったので、対処方法を載せます。
(他のボタンwidgetは試していませんので、自分で試してみてください！)

## 開発環境
|言語/フレームワーク|Version|
|:----------------:|:-----------------:|
|Flutter|1.12.13+hotfix.9|
|Dart|2.3.1|

## サクッとデモ

### 失敗コード
例として、こんなコードを書いたとします。
300x100のFlatbuttonを作り、その中に300x100のTextを配置したものです。

```main.dart
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Container(
            width: 300,
            height: 100,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.red),
            ),
            child: FlatButton(
              onPressed: () {},
              child: Container(
                width: 300,
                height: 100,
                color: Colors.blue,
                child: Center(
                  child: Text(
                    "ボタン",
                    style: TextStyle(
                      fontSize: 20,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
```

↓実際に実機にbuildしたものがこちら↓ (写真の赤枠はFlatbutton、青の長方形がText部分です。)
<img width="375" alt="IMG_0564.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185888/41c4f3fd-fc27-b8d3-75b3-d605a12f09b0.png">

### 成功コード
サイドスペースが出来てしまう理由としては、Flatbuttonウィジェットがデフォルトでpaddingかけてしまうらしいので、

```dart
padding: EdgeInsets.all(0.0),
```
を指定してあげればおkです。

↓実機で見てみても、ちゃんとピッタリ重なりましたね。↓
<img width="375" alt="IMG_0566.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185888/dbebf4ed-2092-0a88-5923-40f166bd0bf3.png">

## 全体コード
これが完成コードです。

```main.dart
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Container(
            width: 300,
            height: 100,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.red),
            ),
            child: FlatButton(
              padding: EdgeInsets.all(0.0), //追加したところ
              onPressed: () {},
              child: Container(
                width: 300,
                height: 100,
                color: Colors.blue,
                child: Center(
                  child: Text(
                    "ボタン",
                    style: TextStyle(
                      fontSize: 20,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
```

## 結果
解決したらなんだこんなことかよ！って思うよね(全部とは言わない)
ゼロから始めるLeetCode Day9「701. Insert into a Binary Search Tree」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

前回
[ゼロから始めるLeetCode Day8 「1302. Deepest Leaves Sum」](https://qiita.com/KueharX/items/130795e0efc26d71897c)

# 問題
[701. Insert into a Binary Search Tree](https://leetcode.com/problems/insert-into-a-binary-search-tree/)

またしても木の問題とタイトルでわかるような問題ですね。

見ての通り二分探索木が与えられるのでその木に正しく数字を挿入し、挿入後の木を返すという問題です。


```Python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if root is None:
            return TreeNode(val)
        if root.val > val:
            root.left = self.insertIntoBST(root.left, val)
        elif root.val < val:
            root.right =  self.insertIntoBST(root.right, val)
        return root
# Runtime: 124 ms, faster than 99.95% of Python3 online submissions for Insert into a Binary Search Tree.
# Memory Usage: 15.9 MB, less than 8.00% of Python3 online submissions for Insert into a Binary Search Tree.
```

二分探索木の性質を利用して、rootのvalの値とvalで比較し、rootの方が大きければ左に、そうでなければ右に再帰的な処理を行い、処理が終わったときにrootを返すという単純なのを書きました。
書く前に思っていたよりシンプルな答えになりました。
sbatch・srunオプション頑張って網羅

#イントロ
ジョブスケジューラーslurmは使ったことはございますか?

GPUのジョブ管理に非常に便利なのですが、問題点が非常に多いツールです。

- 公式ドキュメントがうんち (見にくい)
- ユーザグループの質問のページがうんち (見にくい)
- 英語でもうんち (リソース不足)

まあ、大半の方はインストール等を自分ですることはないので、ユーザに関係あるsbatchやsrunをちょっと見ていきたいと思います。

基本だけ述べておくと

`sbatch test.sh`
`srun python test.py`

みたいな感じで流すとslurmのジョブのスケジューラーに乗ることになります。
ただ、公式ページにいけばわかりますが([https://slurm.schedmd.com/sbatch.html](https://slurm.schedmd.com/sbatch.html))、何をそんなに書くことがあるんだってぐらい非常に長いページになっています。

このページの大半はオプションになっていて、非常に多くのオプションがあることがわかります。

これらの中には気づかない宝があるかもしれない。
なので、ちょっとずつですが試して例もつけられたら、つけていこうと思います。

#注意点

- USER名など一部人手で変更しております。

# 本編

## -a --array=\<indexes\>

ジョブIDに任意のサブの名前をつけることができます。

`sbatch --array=10 test.sh`

```
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
827_10      pc1  test.sh     user  R       0:05      1 pc1
```

"-"をつけるとこれらを繰り返すことになります。

`sbatch --array=1-10 test.sh`

```
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
828_[3-10]      pc1  test.sh     user PD       0:00      1 (Resources)
828_1      pc1  test.sh     user  R       0:00      1 pc1
828_2      pc1  test.sh     user  R       0:01      1 pc1
```
## -A --acount=\<account\>

アカウント名をつけることができますが、何に使うんでしょうか...?

通常使用の場合
`sbatch test.sh`

```
$ scontrol show job 886
JobId=886 JobName=test.sh
   UserId=user(****) GroupId=group1(****) MCS_label=N/A
   Priority=********** Nice=0 Account=(null) QOS=(null)
   JobState=RUNNING Reason=None Dependency=(null)
   (以下略)
```

使用した場合
`$ sbatch --account=super test.sh`

```
$ scontrol show job 885
JobId=885 JobName=test.sh
   UserId=user(****) GroupId=group1(****) MCS_label=N/A
   Priority=********** Nice=0 Account=super QOS=(null)
   JobState=RUNNING Reason=None Dependency=(null)
   (以下略)
```
(※ 「*」は数字が書いてありました。伏せています。)

Accountの項目につけた名前が出てきました。

## --acctg-freq

投げるjobをどの頻度で監視するかを事前に決めることができます。
これはslurm.conf(ユーザは基本見れない設定ファイル)の`JobAcctGatherFrequency`の値よりも優先されます。

`--acctg-freq=<datatype>=<interval>`となっているように\<datatype\>は`task`、`energy`、 `network`、`filesystem`の四種類で、\<interval\>は秒で指定します。

`sbatch --acctg-freq=task=20 test.sh`
`sbatch --acctg-freq=filesystem=20 test.sh`

あんまり小さい値を指定するとパフォーマンスに影響します。
デフォルトの30秒は10,000タスク以内ならそんなに気にならないとも。


随時更新予定
[Dart] あれpubコマンドが使えない。pubはここにあるぞ！

```:dartがインストールしてあるか確認
> which dart
/usr/bin/dart
```

インストールしてあったら、dartのインストールディレクトリのbinにあるpubのリンクを/usr/bin/につくる

```pubのリンクを/usr/bin/につくる
sudo ln -s /usr/lib/dart/bin/pub /usr/bin/pub
```
【Python】ブール演算子(or/and)はブール値を返さない

Pythonには`or`や`and`や`not`という演算子が存在していますが、これらはブール演算子と呼ばれます。

## Pythonにおける真理値

Pythonはどのようなオブジェクトも真理値（真偽値）として表すことができ、組み込み関数の中では以下のようなものが偽と判定されます。

- 偽であると定義されている定数: None と False
- 数値型におけるゼロ: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
- 空のシーケンスまたはコレクション: '', (), [], {}, set(), range(0)

また、オブジェクトのクラスが`__bool__()`メソッドを定義しており、それが`False`を返す場合か、`__len__()`メソッドを定義していて0を返す場合には偽と判定されます。

判定の際には組み込み関数`bool()`を利用します。

```python
>>> bool(None)
False
>>> bool(False)
False
>>> bool(0)
False
>>> bool("")
False
>>> bool([])
False
# 偽ではないものは全て真となる
>>> bool("0")
True
>>> bool([False])
True
```

## orの使い方

`AまたはBのどちらか一方が真`かどうか判定したいときなどに利用されます。
if文などの制御構文の外でももちろん利用できます。

```python
>>> x = True
>>> y = False
>>> x or y
True
>>> bool(x or y)
True
```

ちなみに`or`と後述する`and`はブール値を返さず、比較したオブジェクトを左から値を評価していき、戻り値が確定したタイミングでそのまま返します。

上記の例(x or y)では

- xが真であるならyを評価せずxを返す（yが真でもxを返す）
- そうではないならyを返す

という動作をします

```python
>>> a = 0 # 真理値がTrueとなる値を定義
>>> b = 1 # 真理値がFalseとなる値を定義
>>> a or b # bがTrueなのでbが返る
1
>>> b or a # 逆にしてもbがTrueなのでbが返る
1

>>> b = "" # 真理値がFalseとなるaとは別の値を再代入
a or b # aがFalseなのでbが返る
""
```

ちなみに`or`は2つ以上連結しても同様の動作をして、左から評価されていきます。

```python
>>> a = 0
>>> b = 1
>>> c = 2
>>> a or b or c
1
```

真理値を返す演算子だと勘違いされがちですが、忘れないようにしましょう。

## andの使い方

`and`は`AとBのどちらも真`かどうかを判定したいときなどに利用できます。

`and`についても戻り値は評価対象のオブジェクトのため、ブール値が返るわけではありません。

```python
>>> x = 0
>>> y = 1
>>> x and y
0
```

`or`と同様に結果が確定した段階でオブジェクトを返します。

- xが偽ならxを返す
- それ以外ならyを返す

という動作をします。

偽となるオブジェクトが発見次第結果を返却してしまうため、厳密には比較対象全てが真であることをチェックしていないことに注意してください。

`and`についても2つ以上の連結が可能です。

```python
>>> a = 0
>>> b = 1
>>> c = 2
>>> a and b and c # aが偽なのでaを返す
0
>>> d = 10
>>> d and b and c # dが真、bが真でcを確認した際に結果が確定するのでcが返る
2
```

## notの使い方

`not`は否定を表す演算子であり、`not False`などのように後ろに一つだけ値を取り、その値を否定します。

上記説明の二つの演算子と違い、返却するのはブール値になります。

```python
>>> x = 0
>>> y = 1
>>> not x # xはFalseとなる値であるが、notをつけるとTrueになる
True
>>> not y # yはTrueとなる値であるが、notをつけるとFalseになる
False
```

`not`は`or`や`and`よりも優先度が高く、先に評価されます。

```python
>>> a = 0
>>> b = 1
>>> c = 2
>>> not a and b and c # 偽であるaが否定され真になり、全て真であるため最後に評価されたオブジェクトcが返る
c
>>> d = 10
>>> d and not b and c # 全て真であったが、bが否定されFalseとなるためbが返る
False
```

基本ではありますが、戻り値について忘れがちなため、意識して利用するようにしていきたいです。
pip install xgboostの時にerrorが出てお困りの方々へ

なんか流行ってるし、Kaggleでもやりますかとなり結局はxgboostでしょ的なノリで
- os Mojave 10.14.6
- jupyter lab
- python 3.6.5
でやる気満々だった訳です。

# pip install xgboostエラー出まくるやないかい！

公式には

```
brew install libomp
```
して、

```
pip3 install xgboost
```
簡単にインストールできるよ！もしパーミッションエラーが出たら--userを使ってね。
homebrewとpip最高だよね！・・・やかましいわ！めちゃくちゃエラー出るやん！！

と結構苦労したので、同じような境遇の方の助けになればと思い記事を書きます。
内容の説明はすっ飛ばして、とにかくxgboostを使いたいという心意気の方向けです。

# Successfully installed xgboost-1.0.2までの過程

```
pip install xgboost
```
から始まってエラーを解消しながら最終的にインストールできるまでの過程をただ共有します。
たまにコメントでエラー文を貼り付けておきます。

gccは必要。

```
brew install gcc
```

この段階で
./xgboost/build-python.sh: line 21: cmake: command not found
っていうエラーがあったので

```
brew install cmake
```

次が時間かかりました。
使用コンパイラを設定するため

```
export CC=gcc-5
export CXX=g++-5
```

私の場合は、上記をやったのですが、
Could not find compiler set in environment variable CC:
CC=gcc-５
となってオチはただのタイポだったのですが、素晴らしく時間がかかりました。
JSのDOM

DOM操作とはJSでHTMLの要素を操作することです。

##1 そもそもDOMって？

DOMとは**「Document Object Model」**のことであり、上で話したようにJS
でHTML要素を操作することを指します。

##2 windowオブジェクト

DOMを理解する上で重要なのがこの**windowオブジェクト**です。
windowオブジェクトはブラウザが持っている情報を丸ごと保持しています。

```js
console.log(window);
```

とすることで、windowが持つプロパティやメソッドを表示できます。

ブラウザの高さを持つプロパティや幅を持つプロパティなど様々なプロパティやメソッドが存在します。

##3 Documetオブジェクト
 DocumentオブジェクトはHTML表現されているコンテンツを全て保持しているオブジェクトです。

windowオブジェクトはブラウザの情報を保持しているの対し、DocumentオブジェクトはWebサイトそのものの情報を保持していると言えます。

##4 まとめ

DOMはDocumentオブジェクトを通して個々の要素を取得したり操作したりできます。

次回は具体的なDOMの操作方法をまとめてみたいと思います。
100日後にエンジニアになるキミ - 43日目 - クラウド - よく使われるクラウドサービスの話

本日はクラウドサービスの中でも特に使われるサービスのお話です。

昨日のはこちら
[100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて](https://qiita.com/otupy/items/d1765f1541a104ed6133)

## クラウドサービスについて

詳しい話は昨日の回を見ていただくとして
クラウドサービスの中でもよく使われているものを紹介したいと思います。

プラットフォームは`AWS`,`GCP`です。

クラウドサービスの中はいくつかのカテゴリに別れてサービス展開されています。

主なカテゴリとしては
`コンピューティング`
`ストレージ`
`データベース`
`モバイル`
`ネットワーク`
`機械学習`
`分析`
などがあります。

だいたいこんな感じのサービスがあります。

| カテゴリ | AWS | GCP |
|:--:|:--:|:--:|
| コンピューティング | EC2,lambda | ComputeEngine,CloudFunctions  |
| ストレージ | S3 | CloudStorage |
| データベース | RDS,Aurora,DynamoDB | CloudSQL |
| モバイル | Amplify | Firebase |
| ネットワーク | Route53,ELB |  |
| 機械学習 | SageMaker,Forecast | AI Platform |
| 分析 | Athena,CloudSearch | BigQuery |


早速見ていきましょう。

## コンピューティング

クラウドの基本となるのはやはりサーバーそのものを借りる
コンピューティングのサービスかと思います。

`AWS:EC2`
サイズ変更可能なコンピューティング性能をクラウド内で提供するウェブサービスです

`オンデマンド`と`スポット`インスタンスが存在し
`オンデマンド`は時間当たりの従量課金ですが安定する分料金はお高めです。
`スポット`は他のサーバーの空きを見つけて使うことのできるもので
低額ですが止まったりするスポット対応用の課金体系です。

また`リザーブド`という仕組みがあり
あらかじめ数年分の年間契約をしておくと
その分料金が安くなったり(最大75%)します。

安定稼働してきたら、その分は`リザーブド`に切り替えるなどすれば
運用コストがやすくなります。

コンピューターの性能は
`CPU`,`メモリ`,`ストレージサイズ`によって変わり
性能が良ければ料金も高くなる仕組みです。

最低スペックのものだとvCPU1,メモリ500MBと少なく
高スペックだとvCPU128,メモリ3904GBというような
ハイスペックマシンも存在するようです。
(ただし利用代金は1時間38ドルで月換算で27855ドルです。)

システム要件などでここら辺のスペックを決めて
開発をしていくことになります。

基本的なOSは`LINUX OS`です。
インスタンス作成時にOSやスペックを決めて作成し、起動させると課金が始まり
サーバー停止するまでずっと課金され続けます。

開発時は自分のPCからネットワークを通じてインスタンスにアクセスし
サーバー上でコマンド操作などで作業をすることになります。

`GCP:ComputeEngine`
基本的な概念は`EC2`と一緒です。
課金体系などが少し違うだけで、使い方などもかなり似ています。

どちらか使えれば、特に支障が出ることはないでしょう。

## ストレージ

クラウドサービスを用いる利点のもう一つとして
`ストレージ`サービスがあります。

`ストレージ`サービスは、大量データの保管などをネットワークを通じて行うことができるため
現在の開発では必須になっています。

`AWS:S3`
`GCP:CloudStorage`

両方とも基本的な捜査などは一緒です。
ブラウザーなどからもデータの保管状況が見えます。

開発ではファイル数などが多くなるため、クラウドサービス側が用意している
コマンドを用いてファイルの操作をすることが多いです。

数テラバイト級のファイルのやり取りをするのに
HDDがいくらあっても足りませんが、クラウド上であれば
特にデータ容量を気にすることなくスムーズにやり取りできます。

課金体系はデータ量課金になるので
長大なデータ量になる場合はそれなりに注意が必要です。

主な使い方としてはアプリ内のデータの保管庫として用い
分析などは別途分析サービスやデータベースサービスにデータを移して
行うことが多いかと思います。

## データベース

もう一つの紹介としては
データベースサービスが挙げられます。

`AWS:RDS`
`GCP:CloudSQL`

コンピューティングとは別で、データベース専用のサーバーを
借りるイメージです。

様々なデータベースソフトウェアを用いることができ
用途に応じて性能も可変です。
基本的には時間利用の従量課金です。

`MySQL`,`PostgreSQL`などのデータベースを使うことができるので
WEBサービスを構築するのには欠かせないサービスです。

また
`GCP:BigQuery`は分析用のデータベースサービスです。
更新をかけるような用途ではなく、集計をするだけの用途であれば
分析用のサービスを用いることもできます。

`GCP:BigQuery`では、超大量のデータ集計が行えるので
大規模サービスには欠かせないツールになっており
`SQL`を用いたデータ集計はサービスの根幹を司る部分でもあるのでとても重要です。

## その他

その他にも多種多様なサービスがあり紹介するには紙面が足りません。
`機械学習`に特化したサービスや
`モバイル`専用のサービス
`ブロックチェーン`用のサービスなど
用途に応じて様々なサービスがあり
日々アップデートされています。

ここら辺は、日々の情報収拾を怠らないように
勤めることが大事です。


## まとめ

よく使われるサービスは開発の主流でもあるので
情報の手に入りやすさなども変わってくる

あまり使われていないサービスは誰も情報を出さないので開発もしにくい。
そこらへんを見極めながら何を学ぶか取捨選択しよう。


君がエンジニアになるまであと57日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython