OmniAICreator/Qiita-1.07M huggingface dataset:
備忘録 Javascript reduceの使い方

for文を多く書くとコードの見通しが悪いという事もありreduceを使ってみました。
処理速度については下記に諸先輩方が投稿されている記事があったので、下記をご参照ください。

# for文での処理

```
var array = [0, 1, 2, 3, 4];
var sum = 0;

for(var i = 0; i < array.length; i++){
  sum += array[i];
}

console.log(sum); // 10
```

# reduceでの処理①

```
var array = [0, 1, 2, 3, 4];

var result = array.reduce(function(accumlator, currentValue, currentIndex, array){
  return accumlator + currentValue;
})

console.log(result); // 10
```
![reduce1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308474/259cf70d-3986-76ad-d9db-554c5e26eb91.png)

# reduceでの処理②

```
var array = [0, 1, 2, 3, 4];

var result = array.reduce(function(accumlator, currentValue){
  return accumlator + currentValue;
},10);

console.log(result); //20

```

![reduce2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308474/cbede9fe-99dc-31d1-5fca-6a9fcb46d200.png)

※第二引数に初期値を設定する事ができる。（今回の場合は、10を設定）

# reduceでの処理③
APIのレスポンスとかで良くありそうな、配列の中にjsonオブジェクトが入った形を処理してみる。
ポイントは第二引数に0を渡すことで初期値を設定している事！

```
var items = [
  {
    name: 'pen',
    price: 100,
    quantity: 2
  },
  {
    name: 'note',
    price: 200,
    quantity: 3
  },
  {
    name: 'eraser',
    price: 50,
    quantity: 1,
  }
]

var result = items.reduce(function(accumlator, currentValue){
  console.log(accumlator);
  console.log(currentValue);
  return accumlator + (currentValue.price * currentValue.quantity);
},0);

console.log(result); //850
```

### ↑のconsole.log(accumlator)とconsole.log(currentValue)とconsole.log(result)の結果

```
0
{ name: 'pen', price: 100, quantity: 2 }
200
{ name: 'note', price: 200, quantity: 3 }
800
{ name: 'eraser', price: 50, quantity: 1 }
850
```

参考
https://qiita.com/Hibikine_Kage/items/660392270c466b3f9805
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
d-bus調査その1

#調査
D-Busの具体的な使い方の調査

#資料

https://bootlin.com/pub/conferences/2016/meetup/dbus/josserand-dbus-meetup.pdf

#概要
デスクトップアプリケーションに組み込む場合は、 session bus を用いるのが一般的である。
典型的な例：メディアプレーヤーの操作をd-busで行いたい。
恐らくだがgnomeなどのデスクトップ環境で、再生停止ボリューム調整などのメディアプレーヤー操作をメニューバーから行う際にはこれを使っている。

##具体的なアプリケーションの例
以下は audacious の場合

|クラス|指定子|備考|
|---|---|---|
|Service|org.atheme|
|Object|audacious|
|Interface|*org.atheme.audacious*|セッションユーザはこのインタフェースの備えるメソッドを実行できる 
|Interface|org.freedesktop.DBus.Introspectable||
|Interface|org.freedesktop.DBus.Peer||
|Interface|org.freedesktop.DBus.Properties|すべてのd-busオブジェクトはorg.freedesktop.DBusにも同時に属しているので、このインタフェースを介して上記 *org.atheme.audacious* にアクセスする事もできる|



org.atheme.audacious の実装するインタフェースのメソッドの一部

|Name|メソッドの機能|内容|
|---|---|---|
|Play|再生|オブジェクトに引数無しで method_call アクセスすれば機能する。GUI操作のボタン押下に対応する命令である|
|Stop|停止|同上|
|Info|再生中ファイルの情報取得|ファイルの音楽ファイルのサンプルレート・チャネル数などの情報取得。情報を得る事が目的なので、返り値を取得できる形でコールしなければならない|


#オブジェクトを操作してみる

##再生メソッドの実行

* audaciousを立ち上げた状態で以下を実行すると、ファイルの再生が開始する。

```
$ dbus-send --session --dest=org.atheme.audacious /org/atheme/audacious --type=method_call org.atheme.audacious.Play
```

##ファイル情報取得メソッドの実行

* ファイルの再生中に以下を実行すると、以下のようなリテラルが返される。(返された値を標準出力でチェックするためには、 `--print-reply` オプションが必要である。


```
$ dbus-send --session --print-reply --dest=org.atheme.audacious /org/atheme/audacious --type=method_call org.atheme.audacious.Info

method return time=1601817421.526078 sender=:1.197 -> destination=:1.259 serial=112 reply_serial=2
   int32 196000
   int32 44100
   int32 2
```

44100はサンプリングレート(44.1kHz)、2はステレオを表しているはずだが、196000が何を表しているのかは不明である。

#Todo
gioでネイティブアプリケーションにdbusアクセスコードを組み込む。
厚生労働省の各都道府県の検査陽性者の状況のPDFをスクレイピング

```shell
apt install python3-tk ghostscript
pip install camelot-py[cv]
pip install requests
pip install beautifulsoup4
```

```python
import re
from urllib.parse import urljoin

import camelot
import pandas as pd

import requests
from bs4 import BeautifulSoup

def get_link(url, text):

    r = requests.get(url)
    r.raise_for_status()

    soup = BeautifulSoup(r.content, "html.parser")

    tag = soup.find("a", text=re.compile(text))

    link = urljoin(url, tag.get("href"))

    return link

def set_col(df, n = 1):

    if n > 1:
        columns = ["".join(i) for i in zip(*(df.head(n).values))]

    else:
        columns = df.iloc[0]

    return df.iloc[n:].set_axis(columns, axis=1).reset_index(drop=True)

url = get_link(
    "https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000121431_00086.html",
    "^新型コロナウイルス感染症の現在の状況と厚生労働省の対応について",
)

link = get_link(url, "別紙１")

tables = camelot.read_pdf(link, pages="all", split_text=True, strip_text=" 　,\n")

df1 = set_col(tables[0].df, 2)
df2 = set_col(tables[1].df)

df = pd.concat([df1, df2], axis=1)

df.columns = df.columns.str.replace("※\d", "")

df["都道府県名"] = df["都道府県名"].str.replace("※\d", "")

df.mask(df == "-", inplace=True)

df.to_csv("corona.csv", encoding="utf_8_sig")
```
FFmpeg 画面を分割して複数動画を合成する

# 実行環境

Node.jsでの実行を想定しているためJavaScriptコードになります。
コマンドラインで同様のコマンドを打てばNode.js以外でも実行可能です。

# 画面の分割と複数動画の合成

画面を4分割して、左上、右上、左下に動画を合成した場合の例です。

```javascript
const { execSync } = require('child_process');

function overlay(input1, input2, input3, output)
{
    const stdout = execSync(`ffprobe -i ${input1} -show_streams -print_format json`);
    let streamInfo = JSON.parse(stdout);
    // 幅、高さを取得
    let width = streamInfo.streams[0].coded_width;
    let height = streamInfo.streams[0].coded_height;
    // 4分割後の幅、高さを計算
    let cutWidth = width/2;
    let cutHeight = height/2;
    // コマンド生成
    command = `ffmpeg -i ${input1} -i ${input2} -i ${input3} -filter_complex "\
        amix=inputs=3:duration=longest;\
        [0:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperleft];\
        [1:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperright];\
        [2:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [lowerleft];\
        [upperleft]pad=2*iw:2*ih[a];\
        [a][upperright]overlay=w:0[b];\
        [b][lowerleft]overlay=0:h\
        " \
        ${output}`;
    // コマンド実行
    execSync(command);
}
```

# コマンド内容

関数前半は、input1のストリーム情報から幅、高さを取得し、4分割後の各動画の幅、高さを計算しています。

### Audio
`amix=inputs=3:duration=longest;`はaudioの合成になります。
`amix=inputs=3:duration=longest;`を省いた場合は、左上の動画音声のみになります。

### Video

`[0:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperleft];`部分は、
`[0:v]`：input1のVideoを表しています。
`scale=${cutWidth}x${cutHeight}`：スケール変更しています。
`[upperleft]`：upperleftという名前で定義しています。名前なので任意に変更可能。

`[1:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperright];`、
`[2:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [lowerleft];`
はinput2、input3に同様の処理を行っています。

`[upperleft]pad=2*iw:2*ih[a];`
は[upperleft]映像に余白を追加しています。
`iw`はinput Widthを、`ih`はinput heightを意味しており、幅、高さ2倍の余白を追加しています。
またそれを`[a]`という名前で定義しています。

`[a][upperright]overlay=w:0[b];`
は`[a]`に`[upperright]`を横方向座標w（[upperright]の幅）、縦方向座標0の位置に合成しています。
またそれを`[b]`という名前で定義しています。

`[b][lowerleft]overlay=0:h`
は`[b]`に`[lowerleft]`を横方向座標0、縦方向座標h（[lowerleft]の高さ）の位置に合成しています。

### 注意事項

最後のオプション`[b][lowerleft]overlay=0:h`には`;`を付けるとエラー（`No such filter: ''`）になります。

# 実行結果

※動画のスクリーンショットです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/1b77f066-e2a1-7526-544c-a99b4e218fd4.png)
Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Webアプリ編)

---
# :book: Flutterの記事を整理し本にしました :book:
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* <font color="red"><b>本稿の記事を含む様々な記事を体系的に整理し本にまとめました</b></font>
* 今後はこちらを最新化するため、<font color="red"><b>最新情報はこちらをご確認くださ</b>い</font>
* 10万文字を超える超大作になっています(笑)

---
# 注意
<font color="red"><b>本記事の内容は古くなりましたので、下記の新しい内容をご参照下さい</b></font>

* [Flutterで GooglePlay(Android) / AppStore(iOS) / FirebaseHosting(Web) にリリースする方法まとめ](https://qiita.com/kazutxt/items/f463441840292f0bbe5b)

---
# はじめに
* 最近やたらとFlutterにハマっていていよいよリリースできる状態になってきたので、具体的なリリース方法を整理したいと思います。
* 何かと注目のFlutterですが、同じソースで、Androidアプリ、iOSアプリ、Webアプリと3刀流で同じものをベースにというのも地味に感動
    * ↓がFlutterで始めるアプリ開発というサイトからの引用なのですがよくできていると思います。
    * firebaseもホスティングやその他の機能を持っていて、良い感じに連携してくれます。
        * さすがGoogle!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/666841f3-4fea-6ffc-2b36-2e7b12abbf6b.png)

# 記事の概要/前提
* Webアプリ編では、作ったアプリをFirebaseでデプロイに登録するまでを行います。
* アプリの作り方そのものではありません。
* 何らかのアプリが出来上がり、それをリリースするまでを紹介しています。
* 写真が少なくてすみません。。。

# 関連記事
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Android編)](https://qiita.com/kazutxt/items/66d52d78ec1349f2b249)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Webアプリ編)](https://qiita.com/kazutxt/items/e86bec4d335488a8baa0)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(iOS編)](https://qiita.com/kazutxt/items/0ea523d5ccf647c144ad)


# 参考文献
* https://flutter.dev/docs/deployment/web
* https://www.flutter-study.dev/host-web-app/hosting (←すごく分かりやすい)

# Webアプリリリースへの道

## 1. Firebaseのアカウントを作る
* https://console.firebase.google.com/
    * 上記URLにアクセスしてプロジェクトを作ります
    * 数クリックでできます
* プロジェクトができたら、サイドナビの「開発 → Hosting」を選択「始める」を選択します

```
npm install -g firebase-tools　// ツールのインストール
firebase login // ログインとアカウントの紐付け
firebase init
「Hosting」を選択しEnter
「Use an existing project」を選択しEnter
使用するプロジェクトを選択しEnter
「? What do you want to use as your public directory?」に 「build/web」 を入力
「? Configure as a single-page app (rewrite all urls to /index.html)?」に 「N」 を入力
```
* npmとnodeが古すぎてエラーが出ていたようなので、最新化しました。
* <font color='red'>build/webがデプロイされる実体のフォルダになるので注意すること

</font>
## 2. flutterでWebの資材を作る

```
$ flutter channel beta
$ flutter upgrade
$ flutter config --enable-web
$ flutter create --org package_name .
$ flutter build web
```
* channelをbataにするとあったのですが、がちゃがちゃやっていたらmasterでも動いたっぽいです
* ドメインが"com.example"だとandroidアプリがNGだったので変えた影響かflutter create .ではエラーが解消できず、"--org packaage_name"にしたところ動きました

## 3.デプロイ
`firebase deploy`でデプロイできます。
* 反映まで30秒程度？かかります
* URLはコマンド実行時の `Hosting URL:XXXXX`もしくは、Webサイトのダッシュボード行けます

### イメージ
![イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/99652712-4a70-a043-25bf-74326a134276.png)

* 縦長のスマホと横長のブラウザなので、レイアウトはずれますね。。。みんなどうしているんだろう？？？

## 4.デバッグ
`flutter run -d chrome`でgoogle chromeが起動し、動作を確認できます。
エラーが起きたときも、デバッグコンソールに表示されるので、シミュレータ相当で、デバッグに役立ちます
Flaskで自作サービスや作品を自由に乗せるWEBサイトを作ってGoogleAdsenseの審査にようやく通った話

##はじめに
こんにちは、コーダー2年目のペーペーITエンジニアです。
普段、仕事はIT企業でPHPやPythonを使ったWEB開発やアプリ開発をやってます。
あとは、時々kotlinでAndroidアプリもやったりします。
以前はハード系のエンジニアやっていましたが、去年プログラムの道に変更し、今では楽しくコードを書いています。

##今回作ったポートフォリオサイトSho's Laboについて
実際のサイトは**[こちら](https://shomyapp.net/)**になります。

開いたらびっくり！**これはITエンジニアのサイトなのか？**と疑います、自分でも。
アート色強めなのでぱっと見た感じITエンジニアのサイトではないですが、
**[MyAppのタグに移動すると作成したWEBツール](https://shomyapp.net/it/)**があります。

基本的にはポートフォリオサイトなのですが、ブログ記事みたいなレイアウトにしてGoogleAdsenseに申請をだしました。※申請には5，6回程度落ちてコンテンツを試行錯誤しました・・（笑）
絵が好きで絵にまつわるサービスや作品紹介を多めにしたことで申請が通ったんでしょうか・・。謎ですがそれはあとで話します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493888/234aabcd-b79d-a750-f9df-a980c3f644f5.png)


##個人サイトを作ろうと思ったきっかけ
最初の理由は、エンジニアとしてのポートフォリオづくりでした。
いつフリーランスになってもいいように仕事を受注するため様々なことができますよ～ってアピールですね。
Githubでもいいのですが、Privateリポジトリが多いので、。それに実際にサービスとしてあったほうがWEBエンジニアとしては一通りのリリースができる証明になるのでわかりやすいかなと思いました。
それに、サービスを作るたびにサーバーを借りてってやるとコストがかかりすぎてしまいますので、一つにまとめて公開しよう！となりました。
特に、LINEBOTとかスクレイピングとかは結構需要があるので、実際に使ってこういうことができるんだ～って見てもらった方がいいなと。
※ITサービスをまとめた時点でGoogleAdsenseに申請を出し、落ちました。

作ってる最中に、『どうせなら描いた絵も乗せられるサイトにしたいなぁ～』と欲が出始めて、絵とデザインタグも追加しまして公開しました。
※その時にも、GoogleAdsenseに申請したのですが、見事に落ちました(笑)

##システム構成
サーバーはUbuntuOSを借りています。
AI(Tensorflow)を使ったサービスもあるのでPythonで作成しました。フレームワークはFlaskです。
動的な記事の作成や編集は管理者ページを作り、そこで追加できるようにしています。
CMSは独自のものとQuill.jsの併用したものを使っています。
本当はフロントにはVueを使いたかったのですが、Vueを勉強する前だったので仕方なくJQueryを使ってます・・。
![Slide1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493888/b04ba523-b830-2bb1-5bba-4071d67c6182.jpeg)

##GoogleAdsenseの審査に落ちまくる
サイト自体は2か月前くらいにできてはいたのですが、なぜかGoogleAdsenseに落ちる落ちる・・。
なぜだと思い、審査が通ったであろうブログサイトや通る方法のノウハウの記事とかを読んで参考にしました。
すると、お問い合わせやプライバシーポリシーがないとダメっぽい！ということらしくすぐさま追加！
サイトもブログ風デザインにして、タグ検索やサイト検索機能も追加！！

##しかし、またGoogleAdsenseの審査に落ちる
なぜだぁああああああ！と頭を抱えます。
そこで一番大事であろう項目に目が行きます。
『ユーザーの悩みや疑問を解決するコンテンツかどうか』
『独自性のある記事かどうか』
これを見て、あーなるほど、たしかにこのサイトはユーザーの悩みも問題も解決しないし、何も得るものがない。
そもそももともとポートフォリオサイトなんだから、**自分はこんなことできますよ！！仕事くれ！！**っていってるようなサイトにそんな用途はありませんよね。
でもペイントアプリとか画像加工アプリ、イラスト採点アプリ、メインカラー解析アプリ、、結構使えるアプリあるよ！！と思ってる自分もいました。

##そして、なぜかようやくGoogleAdsenseの審査が通る
審査が通らないのでそのまま利用していました。
新しい記事や絵の追加などコンテンツを増やして、アートを追加するときはメイキング動画をとったり、作品のDetailページは作品が生えるようなデザインにしたりといろいろしました。※AccessログをDB上でとっているのですが、絵を乗せると結構アクセス増えました。
そしてITサービスがあったので、利用規約も追加しました。
泣きの最後の審査、、、**それがなぜか通った・・！**
利用規約が重要だったのか、コンテンツ不足が原因だったのか、アートの追加がよかったのか、、いまだよくわかりません。

##最後に
ここまで読んだ方、お疲れさまでした。
今回、自分で自分のサイトを作りGoogleAdsenseの申請に悪戦苦闘した話を描きました。
無事審査が通り、今ではうざいくらい広告つけているので良かったらサイトの滑稽具合を見てやってください。
あと、**[ペイントアプリ](https://shomyapp.net/it/paint)**とか結構頑張って作ったので、適当に描いて作品を残してもらえたらうれしいです。ほぼ私のテストしかないので・・(笑)
モノづくりがすきなので、これからも作ってはなにかしらブログにアップしておきます。
ではまた。
Xavierのファンを早めに回して温度を下げる

#はじめに
ファンがついている割に大して仕事をしない為
結構高温（GPU60℃越え）になるXavierさんですが
ファン設定を見つけたので自分用メモ

Xavier NXでも有効のようですが温度と設定値がXavierと異なるようです。
[※公式情報](https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fpower_management_jetson_xavier.html%23wwpID0E01M0HA)

#確認環境
本体：Xavier
Jetpack：4.4DP

#コマンド

★早めにファンを回すモード
35℃：30%
53℃：47%
62℃：63%
73℃：100%

```
$ sudo /usr/sbin/nvpmodel -d cool
```

★デフォルトに戻す
50℃：30%
63℃：47%
72℃：63%
81℃：100%

```
$ sudo /usr/sbin/nvpmodel -d quiet
```

★モードの確認

```
$ sudo /usr/sbin/nvpmodel -q
```

一応設定を覚えているらしく、"cool"に設定後にリブートしても
"cool"を保持していました。


#【参考】PWMを固定値に変更してとにかく回す。

min:0
MAX:255

```

$ sudo sh -c 'echo 255 > /sys/devices/pwm-fan/target_pwm'
```
C#でデータベースのデータを使う - DBのNULLの判定について

# データベースのNULLの判定にいきなりハマった

## C#の記事
- [C#でMySQLを使う - 1.開発環境インストール](https://qiita.com/kazumi75kitty/items/9953bb84edd7717bc90a)
- [C#でMySQLを使う - 2.SELECT・画面表示](https://qiita.com/kazumi75kitty/items/dd391cab06762555dc5d)
- [C#でMySQLを使う - 3.追加更新と削除](https://qiita.com/kazumi75kitty/items/65f8ae261bbe61964627)
- C#でのデータベースのデータのNULLかどうかの判定【この記事】
- [C#のdelegate(デリゲート)と=>(ラムダ式)はC言語の関数へのポインタに似た扱い](https://qiita.com/kazumi75kitty/items/fdf4e1d2ea8e9c9326ba)
- [動的にコントロールを追加 - 1.ボタンクリック](https://qiita.com/kazumi75kitty/items/2e3f4c10a93d26032382)
- [動的にコントロールを追加 - 2.テキストボックスの参照](https://qiita.com/kazumi75kitty/items/093b1d679e016782d3af)
- [動的にコントロールを追加 - 3.DB(MySQL)から動的に作成](https://qiita.com/kazumi75kitty/items/3bbb8afdfbc21fb6b3f1)

C#の慣習で、取得失敗といえば「null」だろうという感覚でソースコードを組んでいた私。。。( ´ •̥  ̫ •̥ ` )実はデータベースに関してはハマったことがあります。

それは**C#のデータベースのNULLの扱いは、データベース(SQL)の世界ではNULLは不定値であり、C言語やJavaでいう「完全なゼロ」を意味するnullとは別物である**現実を知らずに、DBのNULLを「<変数> == null」で判定してしまったということです。

DBの世界ではNULLは無効な不定値を意味するので、今になって、さすがに混同なんてできないものだって反省しました…

## 環境
- OS：Windows 10 Pro
- 開発環境：Visual Studio 2019
- データベース：MySQL 5.7


# もともとのソースコードの状態
今回は、[MySQLをC#に導入したとき](https://qiita.com/kazumi75kitty/items/65f8ae261bbe61964627)
のプログラムを組んでみたのですが、実際のデータは以下のようになっています。

| id | name     | memo                   |
|:--:|:---------|:-----------------------|
|  1 | テスト用 | Only for testing.      |
|  2 | π       | 3.14159265358797323... |
|  4 | 3.14     | NULL                   |
|  6 | 超難しい | Difficult Testing      |
|  7 | 難しい   | テスト                 |
|  8 | √5      | 2.2360679...           |

実際には、memoの一部には**NULLが含まれているため、以下のコードでは、実行すると空白で表示されてしまったんです**。

```c#
listBox1.Items.Add(row[1]);
listBox2.Items.Add(row[2]);
```

## 「== null」ではNULLの判定ができなかった
そこで、取得したmemoはrow[2]に該当するので「row[2] == null」「row[2] != null」で、NULLかどうかの判定をしたのですが…

```c#
listBox1.Items.Add(row[1]);
if (row[2] != null) {
	listBox2.Items.Add(row[2]);
}
else {
	listBox2.Items.Add("(未設定)");
}
```

うまく比較されていませんでした( ´ •̥  ̫ •̥ ` )

![実行結果_悪い例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/253d3c8e-a5c6-da0f-f9ce-0377680eab03.png)

# 正しいDBのNULLの判定

## データベースのNULLは不定値である
最近はDBのNULLについて理解を深めていったけど、**データベースの世界では、NULLは不定値を意味するのであって、C言語やJavaのように、完全無効なゼロを意味するものではない**ということで、C言語でDBのNULLについていうと、初期化されていない変数みたいなもので、不安定な値を含んでいるものに近いらしい。

そうなれば、DBのNULLを「==」「!=」演算子で比較しようとしても、当然うまくいかないのかもね。。。

## 正しい比較のしかた
っということで、正しい比較としては、**DBNull.Value**というものが用意されているので、その値に等しければ、取得したデータはNULLだということが判別できる

```c#
listBox1.Items.Add(row[1]);
if (!row[2].Equals(DBNull.Value)) {
	listBox2.Items.Add(row[2]);
}
else {
	listBox2.Items.Add("(未設定)");
}
```

![実行結果_正しい例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/1d5a0d8e-abf9-9c35-cdf4-83df07ff12c7.png)

これでNULLの場合の比較ができた(♥´꒳`\*)


# 参考文献
　1. [[C#]DataRowの値がNullかチェックする方法](http://www.curict.com/item/e3/e3bbda8.html)
　2. [DBNull.Value フィールド](https://docs.microsoft.com/ja-jp/dotnet/api/system.dbnull.value?view=netcore-3.1) - Microsoft .NET 公式
FFmpeg 動画の前後に無音黒画面を挿入

# 実行環境

Node.jsでの実行を想定しているためJavaScriptコードになります。
コマンドラインで同様のコマンドを打てばNode.js以外でも実行可能です。

# 動画の先頭に無音黒画面を挿入

```javascript
const { execSync } = require('child_process');

function Insert_haed_blank(input, duration, output)
{
  execSync(`ffmpeg -i ${input} -vf tpad=start_duration=${duration}:color=black -af "adelay=${duration}s:all=1" ${output}`);
}
```

### パラメータ
- input：入力動画パス
- duration：挿入する無音黒画面時間（秒）
- output：出力動画パス

### コマンド内容

`-vf tpad=start_duration=${duration}:color=black`がvideo、
`-af "adelay=${duration}s:all=1"`がaudioの設定になります。

挿入する無音黒画面期間をフレーム数で指定する場合は、`tpad=start_duration=`を`tpad=start=`に変更します。
白画面を挿入する場合は、`color=black`を`color=white`に変更します。
`adelay=${duration}s`で音声の開始をduration秒だけ遅延させています。
`all=1`はaudioの全チャンネルを指定しています。

# 動画の末尾に無音黒画面を挿入

```javascript
const { execSync } = require('child_process');

function Insert_end_blank(input, duration, output)
{
  execSync(`ffmpeg -i ${input} -vf tpad=stop_duration=${duration}:color=black -af "apad=pad_dur=${duration}" ${output}`);
}
```

### パラメータ
先ほどと同様

### コマンド内容

`-vf tpad=stop_duration=${duration}:color=black`がvideo、
`-af "apad=pad_dur=${duration}"`がaudioの設定になります。
挿入する無音黒画面期間をフレーム数で指定する場合は、`tpad=stop_duration=`を`tpad=stop=`に変更します。
inner join とサブクエリについて

inner join とサブクエリについて調べたので、備忘録的にまとめようと思いました。
・inner join ってなに？
←内部結合とは2つのテーブルでそれぞれ結合の対象となるカラムを指定し、それぞれのカラムに同じ値が格納されているデータを結合して取得するものです。
(引用元: https://www.dbonline.jp/sqlite/join/index1.html)

・ほかのjoinには何があるの？
　1・left join on
　2・using
　3・inner join
　4・outer join　などがあるようです。
(引用元: https://rfs.jp/sb/sql/s03/03_3.html#OUTER_JOIN)

・4との違いですが、これをよく表した説明があります。
　・リレーションを作成した際、片方のテーブルに情報がない場合に、inner joinの場合は、それを除外して表示する。

　・これに対して、outer joinの場合は、片方にないところはNULLを表示する。(行自体は存在させる。)

・1との違いですが、left join onは、左側のテーブルの要素について、マッチするレコードがなかった場合であっても、レコードが表示される。その際、右側のテーブルのフィールド値はすべてNULLになる。

・usingは、結合する条件が同じ名前のフィールド名である場合に、それを使って結合条件を指定することができます。

こんなところですかね。

次に、サブクエリについてまとめます。
サブクエリは、どこに埋め込むかによって分類ができるようです。
・どんな種類のサブクエリがあるのでしょうか？　
　・select句
　・from句
　・having句
　

・select句のサブクエリ
単一のselect文ではグループ化された結果と全体の結果を同時に取得することはできませんが、サブクエリなら異なる値を同時に取得することが可能です。

・from句のサブクエリ
これが最も頻繁に利用されるようです。
from句のサブクエリは、その結果をテーブルとして渡します。
例えば、購入履歴テーブルを購入者でグループ化し、その平均値を算出したりします。

・having句でのサブクエリ
使用方法はwhere句のサブクエリと同じだそうです。

(引用元:https://rfs.jp/sb/sql/s03/select_sql.html)

参照元の素晴らしいサイト様のおかげで、理解が深まった気がしました。ありがとうございます。
これなしでは開発できない！ iOS/Android アプリ x Azure おすすめ開発術

『知らないと損？あなたのお勧めAzureテクニックを大募集！』といいテーマで、自分なりのおすすめ Azure テクニックをご紹介したいと思います。

## 構成

構成は以下の通りです。

* Local environment
    * Any Operating System
* Remote environments
    * Visual Studio App Center

## What is Visual Studio App Center?

[Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) は Microsoft が提供している アプリのビルド、アプリのテスト、テスト、テスターへの配布、クラッシュレポート、分析と診断をサポートしている CI/CD + α な SaaS です。

詳しくは[こちら](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601)をご覧ください

## メリット

[Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) をおすすめする複数のメリットがあります。

### メリット 1: 導入が容易

まず、メリットの一点目は導入が容易なことです。CircleCI、Travis CI、GitHub Actions、Azure Pipelines など多くの CI/CD のサービスを利用する場合、そのサービスにあった設定ファイルを作成しなければなりません。

初めて導入する際、この設定ファイルを正しい状態にするのが難しく、トライアル・アンド・エラーを繰り返して、正しい状態に持っていきます。

その点、[Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) は [たった数行](https://docs.microsoft.com/en-us/appcenter/sdk/getting-started/android#41-add-the-start-method?WT.mc_id=AZ-MVP-5001601) 追加するだけです。

後は [Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) のサイト上で選択肢を選択していくだけで、ビルドが成功するので、非常に導入がし易いです。

### メリット 2: 機能が豊富

二点目のメリットは機能が豊富なことです。

CI/CD + α と上記した通り、CircleCI、Travis CI、GitHub Actions、Azure Pipelines など多くの CI/CD のサービスではテスターへの配布、クラッシュレポート、分析と診断などをサポートしていません。しかし、これらの機能はiOS/Android アプリを開発する上で必須機能です。そのため、これらのサービスを使う場合は、別のサービスを追加するか、自分自身で機能を実装しなければなりません。

一方、[Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) はそれらのサービスと異なり、CI/CD、テスターへの配布、クラッシュレポート、分析と診断をサポートしています。

そのため、[Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601) を導入するだけでよく、非常に利便性が高いです。

## まとめ

『知らないと損？あなたのお勧めAzureテクニックを大募集！』といいテーマで、自分なりのおすすめ Azure テクニックをご紹介しました。
実際、私自身も業務で使っていますが、とても生産性の向上に寄与しています。
みなさんも[『知らないと損？あなたのお勧めAzureテクニック』](https://qiita.com/official-events/d513e4b8c3509ababcb5)をお持ちでしたら、ぜひ共有してください。

## 参考
- [Visual Studio App Center](https://azure.microsoft.com/ja-jp/services/app-center/?WT.mc_id=AZ-MVP-5001601)
- [Using App Center - Visual Studio App Center | Microsoft Docs](https://docs.microsoft.com/en-us/appcenter/dashboard/?WT.mc_id=AZ-MVP-5001601)
- [Get Started with Android - Visual Studio App Center | Microsoft Docs](https://docs.microsoft.com/en-us/appcenter/sdk/getting-started/android#41-add-the-start-method?WT.mc_id=AZ-MVP-5001601)
【CSSデザイン】iOS_Safariのinput要素のグラデーションを適用させたくない時の対処方法

ページ制作時のとてもピンポイントな課題です。

iOS Safariのinputボタンのデザイン
背景色を指定してもボーダーを変えても
グラデーションスタイルが残ります。
※2020年10月現在
![botan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/0d75ad43-22ff-d054-1d5d-35d3326eb59c.png)

##回避方法
これを回避するためには、
ボタン要素に下記のプロパティを指定します。

`-webkit-appearance: none;`

例：
`<input type="button" style="-webkit-appearance: none;">`

これで自身で指定したスタイルを
適用する事が出来ます。

##補足
OS/ブラウザの統一性を持たせるために
デフォルトスタイルが用意されていると思います。
個人的にはサイトのデザインを優先させたいですが
これは各々考えがあると思います。。。
覚書:TribuoでTensorFlowを試そうとしたら動かないから本家を模索する旅に出た結果惨敗した

#まえおき
2020/10/03 執筆時点での感想文です。

TribuoでTensorFlowの話はここでは出てきません。Tribuoだけではなく、いろいろなものが厳しいです。ハマった記録だけです。TribuoからTensorFlowの連携をする以前の問題です。

#結論

TensorFlow Javaは、Mavenセントラルレポジトリの最新版(1.15.0)でもJava 7でビルドする必要があります。新規でJava7採用するプロジェクトはあまりやりたくないです。一応Java11でのビルドまでは動作しましたが、Java12以降では実行時にエラーとなりました。

TensorFlowの最新版(2.3.0)でもCuda11は対応されてませんでした。無理に動かそうと思えば動かせます。

Tribuo忘れてました。気が付いたら朝になっているし、いつの間にかTensorFlowでJavaの話も忘れて、pythonの実装してました・・・。やはりスクリプト系の言語は好きになれないです。

Windos上でTensorFlowからGPUの利用は可能ですが、Windows on WSL2 on ubuntuではワタシの環境ではうまくいきませんでした。

#現状の把握
###Windows版Docker DesktopがGPGPU対応してない
Windows環境でDocerにLinuxを入れて、TensorFlowからGPUを利用しようとしましたがダメでした。そもそも、Windows版のDocker DesktopがGPGPUに対応してませんでした。

###WindowsでWSL2上に構築したUbuntuでDockerを動かしたがGPUが認識しない
WindowsでWSL2上に構築したUbuntuに、Dockerを入れてヒャッハーみたいな情報もあったため試してみましたが、ワタシの環境ではダメでした。そもそもDockerを入れるためのUbuntu上でも、/usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQueryを実行すると、35が返却されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732297/e74f93f2-cbd5-43c2-79d0-b6431650df68.png)

TensorFlowのイメージも試してみましたが、こちらもうまく動作しませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732297/65f49770-438e-3476-5e50-cb8ebb090b94.png)

###WindowsでWSL2上に構築したUbuntuでGPUが認識しない
AMD:Ryzen 3700x
GPU:RTX3090
OS:Windows Build 20226.rs_prerelease.200925-1415
NVIDIA GPU Computing Toolkit:CUDA11.1/CUDA10.1/CUDA10.0
CUDANN:CUDA11.1/CUDA10.1/CUDA10.0

WindowsでWSL2上に構築したUbuntuからGPUを利用できるようになり、実際に動いたという情報があったため、試してみましたが、CUDA10/CUDA11-0/CUDA11-1のツールキット全部、ワタシの環境ではダメでした。~~Gefoce RTX 3090だから?AMDの呪い?~~

DeviceQueryを叩くとエラーコード35が出力されます。


#ホストOSのWindows10上にダイレクトに構築

こちらは検索すると情報がでてくるのでば、あまり困らずに構築できました。必要な環境ごとに仮想環境をつくっているため、仮想環境ではないホストOSに、開発環境を構築するのは、あまりやりたくないです。Hyper-v on windowsでGPUが使えればいいのですが、ホストOSがWindows Serverではないですし、WSL2ではうまくいかないしで、時間だけが過ぎてしまいました。

TensorFlow JavaもGPUで動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732297/42b33b50-15fb-f544-cff1-9c9afe4751cd.png)

ただし、Java12以降を指定すると実行時にエラーとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732297/2d6a8b84-cf03-b960-d7cd-c4de85e99b4c.png)

#感想

バージョン関係がカオス。
MonoBehaviourが本当にnullか否かを確認するにはReferenceEqualsとis演算子を使え

[PR: CADDiではバックエンドエンジニア、フロントエンジニア、アルゴリズムエンジニア、SRE等などを募集しています](https://corp.caddi.jp/recruit/eng)。

`MonoBehaviour` と `null` の比較が特殊であることは周知の事実である。これは `MonoBehaviour` の基底クラスである `UnityEngine.Object` のメソッド `Object.operator bool`、`Object.operator ==`、そして `Object.operator !=` に起因する。

`operator bool` と `null` との比較は同じ結果が得られるため、`null` との比較においては `operator ==` や `operator !=` を使う意味はほぼ無い。

- [Object-bool - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/Object-operator_Object.html)
- [Object-operator != - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/Object-operator_ne.html)
- [Object-operator == - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/Object-operator_eq.html)

たとえば、状態を常に正しい状態に保つためにプロパティの `set` で単なる代入以外の処理を行っている場合、オブジェクトが本当に `null` かどうかを確認してから代入したい場合がある。

```csharp
SomeType someField;
SomeType SomeProperty {
    get => someField;
    set {
        someField = value;
        SomeMethod();
    }
}
```

この様な場合、`System.Object.ReferenceEquals` を用いることでオブジェクトが本当に `null` か否かを確認することができる。

```csharp
void UpdateSomeProperty() {
    if (!System.Object.ReferenceEquals(null, SomeProperty) && !SomeProperty) {
        SomeProperty = null;
    }
}
```

`System.Object.ReferenceEquals` は `is null` や `is object` で置き換えることで、更に簡便に記述することができる。

```csharp
void UpdateSomeProperty() {
    if (SomeProperty is object && !SomeProperty) {
        SomeProperty = null;
    }
}
```

`null` であることを確認する場合は `is null` を、`null` でないことを確認する場合は `is object` を用いる。

- [Object.ReferenceEquals(Object, Object) メソッド (System) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.object.referenceequals)
- [is - C# リファレンス | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/is)
- [Expressions - C# language specification | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/expressions#the-is-operator)
- [型のテスト演算子とキャスト式 - C# リファレンス | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/type-testing-and-cast#is-operator)

`null` 以外との比較には変わらず `ReferenceEquals` が使える。

```csharp
SomeType someField;
SomeType SomeProperty {
    get => someField;
    set {
        if (ReferenceEquals(lockTarget, value)) {
            return;
        }
        someField = value;
        SomeMethod();
    }
}

void UpdateSomeProperty() {
    if (!SomeProperty) {
        SomeProperty = null;
    }
}
```
Pythonでデフォルト引数を使う際に気を付けること

# はじめに
使用歴が浅いPythonなのですが、
デフォルト引数の仕様を知らずにちょっとハマってしまいました。

# デフォルト引数で指定した値はキャッシュされる
実は、デフォルト引数で指定した値は**キャッシュされる**ため、これを知らずにデフォルト引数にリストや辞書のような**ミュータブルデータ**を使うと意図しない動作になってしまう。

```python
# aがデフォルト引数
def hoge(a=[]):
  a.append('a')
  print(a)

hoge() # ['a']
hoge() # ['a', 'a'] ※['a']ではない
```

上記を実行した場合、2回目のhoge()呼び出しでa = ['a']ではなく['a', 'a']となってしまう。
これは、1回目の呼び出し後の['a']が使い回されているため。

# 解決策
デフォルト引数に、Noneや数値や文字列、タプルなどの**イミュータブル**な値を使うようにする。

どうしてもデフォルト引数にリストや辞書を使いたい場合は、以下のような方法を用いると良い。

```python
def hoge(a=None):
  if a is None:
    a = []
  a.append('a')
  print(a)

hoge() # ['a']
hoge() # ['a']
```
vuetify勉強 2020/10/04

マテリアルデザイン
　https://saruwakakun.com/html-css/material#section1

Vuetify参考サイト
　https://slash-mochi.net/?p=3335
　https://qiita.com/y-tsutsu/items/e8544ec5fe1b9a69ea35

Vuetifyインストール
　コマンドプロンプトで作成したVUEプロジェクトに移動
　コマンドプロンプトでvue add vuetifyを実行

Welcomeページ解説
　https://mebee.info/2019/11/16/post-3899/#outline__5

グリッドシステム
　http://websae.net/twitter-bootstrap-grid-system-21060224/

vuetify基本構文
　https://dev83.com/vue-vuetify-basic/

VSCode拡張機能
　https://biz-navi.site/vscode%EF%BC%8Bvetur/
　vetur：コードハイライト、スニペット
　eslint:javascript：静的解析ツール
　prettier：コード整形ツール

vue 公開
　コマンドプロンプトでプロジェクトフォルダに移動し
　npm run buildを実行する
　http://salary.katsulabo.com/%E3%80%90vue-js%E3%80%91%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E5%85%AC%E9%96%8B%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%EF%BC%88%E3%83%93%E3%83%AB%E3%83%89%E6%89%8B%E9%A0%86%EF%BC%89/
　
Windows2012　キーボード設定変更
　https://harucharuru.hatenablog.com/entry/2019/11/20/131538

Windows2012　FTPサーバー構築
　https://genchan.net/it/pc/windows/13930/

FTP接続ツール
　https://forest.watch.impress.co.jp/library/software/winscp/download_10950.html
Ubuntu-20.04 に nodenv をインストール (Homebrew より)

# 概要
Ubuntu-20.04 で Homebrew から nodenv を使えるようにします。

# 手順

[Homebrew Documentation - Homebrew on Linux](https://docs.brew.sh/Homebrew-on-Linux#debian-or-ubuntu) を参考に進めます。

## 1. build-essential をインストール

Ubuntu に下記コマンドを入力して build-essential をインストールする。

```
$ sudo apt-get install build-essential curl file git
```

参考：[Debian or Ubuntu](https://docs.brew.sh/Homebrew-on-Linux#debian-or-ubuntu)

## 2. Homebrew をインストール

```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

参考：[Homebrew](https://brew.sh/)

## 3. PATH を設定

下記コマンドを順に実行して `~/.profile` に PATH を設定する。

```
$ test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
$ test -d /home/linuxbrew/.linuxbrew && eval (/home/linuxbrew/.linuxbrew/bin/brew shellenv)
$ test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
$ echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
```

参考：[install](https://docs.brew.sh/Homebrew-on-Linux#install)
[How to install Homebrew on Ubuntu 20.04 / 18.04 / Debian 10?](https://www.osradar.com/install-homebrew-ubuntu-20-04-debian-10/)

## 4. Homebrew が入ったことを確認

下記コマンドを実行する。

```
$ brew --version
```

下記のようにバージョン情報が出れば、Homebrew は無事インストールできている。

```
Homebrew 2.5.2
```

## 5. nodenv をインストール

下記コマンドで brew で nodenv をインストールする。

```
$ brew install nodenv
```

## 6. シェルに nodenv を設定

好きなエディタで `~/.profile` を開き、下記の 1 行を最終行に追加する。

```
eval "$(nodenv init -)"
```

参考：[Groom your app’s Node environment with nodenv. - Installation](https://github.com/nodenv/nodenv#installation)


## 7. nodenv がコマンドになったことを確認

下記コマンドを実行する。

```
$ nodenv --version
```

下記のようにバージョン情報が出れば、nodenv は無事インストールできている。

```
nodenv 1.4.0
```
Terraformでazurerm_role_assignmentするために必要な準備の手順

# はじめに

Terraformのazurerm_role_assignmentを使用すれば、アプリの各種権限を付与することができる。
https://www.terraform.io/docs/providers/azurerm/r/role_assignment.html

しかし、下記の権限を付与していないと、Terraformからのリソース作成が失敗してしまう。
Microsoft.Authorization/roleAssignments/write
Terraform公式ドキュメントには記載されていないので、対処法を記載する。

## 準備：Powershell 7 &AzurePowerShellAzのインストール

まず、Powershell 7 のインストールを行う。

https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7

次に、AzurePowerShellAzコマンドを実行できるよう、インストールを行う。

```powershell:install.ps1
# AzurePowerShellAzのインストール
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
    Write-Warning -Message ('Az module not installed. Having both the AzureRM and ' +
      'Az modules installed at the same time is not supported.')
} else {
    Install-Module -Name Az -AllowClobber -Scope CurrentUser
}
```

インストールバージョンを確認する

```powershell:checkVersion.ps1
# powershell
$PSVersionTable.PSVersion
# AzurePowerShellAz
Get-InstalledModule -Name Az -AllVersions

#-------------------------
Major  Minor  Patch  PreReleaseLabel BuildLabel
-----  -----  -----  --------------- ----------
7      0      3
Version              Name                                Repository           Description
-------              ----                                ----------           -----------
4.7.0                Az                                  PSGallery            Microsoft Azure PowerShell - Cmdlets to …

```

[詳細]
https://docs.microsoft.com/ja-jp/powershell/azure/new-azureps-module-az?view=azps-4.7.0&viewFallbackFrom=azps-3.3.0

## Terraformを実行しているサービスプリンシパルへのロールの付与

[Azure PowerShell を使用して Azure ロールの割り当てを追加または削除する]
https://docs.microsoft.com/ja-jp/azure/role-based-access-control/role-assignments-powershell

```powershell:setup.ps1
# ログインする
Az login
#Azureサービスに接続する
Connect-AzAccount

# 組み込みのロール定義を確認する。内容を知っているなら、実行しなくてもよい。
Get-AzRoleDefinition
#「Terraformに使用しているサービスプリンシパルのObjectID」
$objID = "Hoge"
# AzureサブスクリプションのID
$subID = "Hoge"
New-AzRoleAssignment -ObjectId $objID -RoleDefinitionName "User Access Administrator" -Scope $subID
```
書き方 docker-compose

# docker-compose.yamlの書き方

```:サンプル
version: '3'
services:
   ubuntu:
     image: ubuntu
     container_name: ubuntu01
     tty: true
     volumes:
       - ".:/var/log"
```
```:サンプルを基に意味を解説
version: '3'
# docker-composeのバージョン。3以外はほぼ使わない
services: 
# コンテナの組合せ名を命名する
   myweb:
# 組合せ名をmywebと命名。名前は好きに決めてOK
     image: centos
# コンテナのイメージを指定。バージョン指定する場合は`centos:7`のように記載。バージョン指定なしであれば自動で最新版が指定される
     container_name: my-centos
# 作成されるコンテナ名を指定。名前は好きに決めてOK。指定した方が後々わかりやすい。
     tty: true
# Bashが入力待ち状態になるよう指定（nginxやmysqlのようにポートを開いて待受けするシステムの場合は指定不要）
     volumes:
# 同期するパスを指定。
       - ".:/var/log"
# ホストのパス:コンテナのパス の形式で同期するパスを記載。上記はホストのカレントディレクトリとコンテナの/var/logディレクトリが繋がっている
```

[参考1:　ばったんの技術系ブログ](https://blackbird-blog.com/docker-comopse-startup01)
録音したラジオ番組のCMカット～本編とCMをリネーム分離する～


##前回のあらすじ

[raspberry pi をラジオサーバにしてラジオ番組のCMカットを企む](https://qiita.com/el-coverage/items/4d2293323a4ce1fd31f8)
および[伊集院光のラジオ番組CMカット自動化のための調査結果①～朝のラジオ～](https://qiita.com/el-coverage/items/c492082d675e6d490b33)の記事の追加です。本記事では前回までの内容を前提に話を進めます。

前々記事では、ラジオサーバおよびsambaサーバの構築およびCMカットを行いました。

これによって毎日、CMカットがなされたラジオが聞けるようになりましたが、どうしてもCM扱いされてカットされてしまう箇所が発生してしまう事が前記事で分かりました。

このカットされた部分を聞き返すためには、カット前のmp3ファイルにアクセスし、該当箇所を探さなければならず、非常に不便です。またカット前のmp3ファイルを残す必要があるのも腹立たしいです。

これを解決するために、「CM部分を削除するのではなく、リネームする」ようにしようというのが今回のテーマです。これによってカット前のmp3ファイルを削除することが可能になります。


前回のソースでは「区切り無音時間」と「CMと判定される秒数」が固定化されてしまうため、番組ごとに別途のシェルファイルを用意しなければなりませんでした。これも様々な番組にcronのみで対応するために、引数から受け取るようにしました。

前回のrec_radiko.shは無駄にmkdirをしていましたが、mp3spltでは出力ファイルを指定できるため、これもmp3spltに任せる事にします。

修正内容が大きいため、rec_radiko.shは別途新しいものを用意してください。

##rec_radiko.shの改修点　

```shell:/home/pi/rec_radiko.sh
～(最終行に追加)～
sudo mp3splt -sn -p th=-50,min=$5,shot=10 -d "${outdir}/${PREFIX}_${date}" "${outdir}/${PREFIX}_${date}.mp3"
sudo chmod -R 777 "${outdir}/${PREFIX}_${date}"

for file in `find "${outdir}/${PREFIX}_${date}" -type f`
do
        fsize=`wc -c $file | awk '{print $1}'`
        if [ $fsize -lt $6 ]; then
                mv "$file" "${outdir}/${PREFIX}_${date}/_${file##*/}"
        fi
done
sudo chown -R pi "${outdir}/${PREFIX}_${date}"

rm -f "${outdir}/${PREFIX}_${date}.mp3" #元の音声ファイルが必要であればコメントアウトしてください
```


```shell:crontab
0 1 * * 2 sleep 15; /home/pi/rec_radiko.sh TBS 120 /home/pi/samba/radio "伊集院光・深夜の馬鹿力" 1.7 3000000 
30 8 * * 1-4 sleep 15; /home/pi/rec_radiko.sh TBS 150 /home/pi/samba/radio "伊集院光とらじおと" 0.7 2000000
0 18 * * * /sbin/shutdown -r now
```

変更点の中の特筆すべきは、rec_radiko.shへの修正が最後尾追加になったことと、第五引数(番組を区切る無音秒の単位)、第六引数(CMと見なすファイルのbyte数)が増えたという点です。

唯一のデメリットとして、前回は「CMと見なす秒数」でCMカットしていたのに対し、今回は「CMと見なすファイルサイズ」でリネームしているという点です。
ファイルサイズでは直感的にCM判定しづらいかなぁ……と思います。
CMと見なすファイルサイズは、それぞれの番組で試行錯誤してみてください。mbでもkbでもなく、byteですのでご注意を。

PythonでMFCC(メル周波数ケプストラム係数)を計算して、パーソナリティとアシスタントだけを判定するように出来たらもっと便利なんですけどね。

誰かやってくれないかなぁ……
参考：[声優の声を分析してみた](https://qiita.com/1234224576/items/f785eef6eed68271be64)、[機械学習でμ’sの声を識別する](https://sunpro.io/c91/hideo54.html)
R Studio Cloud 日本語文字化け対策

# この記事の目的
R Studio Cloudで日本語でplotする

# 解説
Terminalタブで以下を実行した後、メニューから `Session` → `Restart R` (Ctrl+Shift+F10) でOK

```bash
mkdir ~/tmp
cd ~/tmp

wget https://moji.or.jp/wp-content/ipafont/IPAexfont/ipaexg00401.zip
unzip ipaexg00401.zip

mkdir -p ~/.fonts/ipa
cp ipaexg00401/ipaexg.ttf ~/.fonts/ipa

```



# 参考
[RStudio CloudのPlotで日本語が文字化けする](https://ziomatrix18.blog.fc2.com/blog-entry-853.html)

[IPAexフォントおよびIPAフォントについて](https://moji.or.jp/ipafont/)
2.5: 特徴量サンプリング

#概要

この記事では、Dr. Marcos著「Financial Machine Learning」の2章5節、特徴量サンプリングについて簡単な解説を行います。実際の応用として、特徴量サンプリングの手法の一つである、CUSUMフィルタを仮想通貨に対して適用した結果をご紹介します。

#特徴量サンプリングについて

2.3ではいくつかのバー(要はサンプリングの方法)について解説されています。2.5では、さらにサンプルデータの絞りこみについて解説が行われています。こちらを特徴量サンプリングと本では読んでいます。

#なぜ特徴量サンプリング？

では、なぜそもそも特徴量のサンプリングを行うのでしょうか？ナイーブに考えると、データの数が増えれば増えるほど、サンプルの数が増え、ロバストな学習が行えそうです。こちらは本にも記載されている通り、主に理由は二つあります。

1. モデルの学習のため
2. データ量削減により、精度が高まるため

です。1についでですが、いくつかのモデルは、多すぎるデータに大してはあまり機能しません(本の中ではSVMが挙げられています)。そもそもデータ数がすくない金融時系列データなのに、そんな状況があるのかというツッコミに対しては、例えば分足データや多資産のマルチインデックステーブルに対する予測をお考えください。
　2についてですが、こちらの方がより重要だと思われるのですが、適当にサンプルを選んだ方が精度は高まります。こちらを理解するためには、例えば、分かりやすくリーマンショックのような金融危機の例を考えてみてください。このような状況は、いわゆるアノマリー(分布のテール)に相当します。普段の市場と異なった状況になるわけです。このようなデータも含めて学習すると、例えば通常のマーケットでよく機能する特徴量から作られたモデルは、パフォーマンスにネガティブな影響があることが想定されます。そのため、そういったイベントを学習データから取り除くという施策に意味がある訳です。(ただ、オルタナティブデータなどから作られた特徴量で、そういったイベント下でも機能すると考えれられる特徴量であれば、訓練データに含めてパフォーマンスを見ることは意味があります。)

#CUSUMフィルタについて

では、そういったイベントはどのように検出すれば良いのでしょうか？そのための一例として、CUSUMフィルタが本では取り上げられています。ここで、以下の統計量を計算します:

```math
\begin{align}
S_t &= max \{ 0, S_{t-1} + y_t - \mathbf{E}_{t-1}[y_t] \}
\end{align}
```

ここで、$y_t$は局所定常過程、$S_0=０$とします。局所(弱)定常過程なので、

```math
\begin{align}
\mathbf{E}_{t-1}[y_t] &= const.
\end{align}
```

です。つまり、単なる定数で閾値を変えるだけなので、0と置いてしまいます。$y_t$は特徴量でも、ラベルでも、なんでも良いです。要は、$S_t$は測定した値が(それまでの経路で取った値も含めて)どれくらい平均的に離れているかを表しています。ここで、ある閾値$h$を設定して、$S_t>h$であれば、イベントであるとします。以下、負の方向のイベントも含めて(対称CUSUMフィルタ)、イベントをサンプリングするコードです。

```
def getTEvents(gRaw: pd.Series, h: float) -> pd.DatetimeIndex:
    
    # Initialization
    tEvents, sPros, sNeg = [], 0, 0
    
    diff = gRaw.diff()
    
    for i in diff.index[1:]:
        
        sPros, sNeg = max(0, sPros + diff.loc[i]), min(0, sNeg + diff.loc[i])
        
        if sNeg < -h:
            sNeg = 0
            tEvents.append(i)
        elif sPros > h:
            sPros = 0
            tEvents.append(i)
            
    return(pd.DatetimeIndex(tEvents))
```

ここで、以下のある仮想通貨の価格時系列に対して、上記のCUSUMフィルタを適用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547335/d032571b-9a10-36e8-7911-fc1f67c44206.png)


適当にパラメーター$h$を設定すると、以下のようなイベントがサンプリングされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547335/3bbc884a-3275-8d69-3d9f-2500d0fbfa38.png)

ここから、 実際のアルファリサーチにおいては、上記のイベントになんらかの共通性がみられるか？その共通性には、どういった定性的な背景があるかなど(例えば、雇用統計などファンダメンタルなイベントが起こっているのかなど)を詳しく調べていきます(ここが個人的にはリサーチで一番面白いところですね)。ここでは、例として日付・時間ごとのイベント数のヒートマップを描いてみます(以下のグラフでは、パラメータ$h$の値を下げています)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547335/24563596-3bd7-c4d5-f58d-60faf16b95b4.png)

こちらのヒートマップを見ると、10-15時くらいでは、イベントの数が多いようです。つまり、この時間帯ではリターンが(どちらか一方に)大きく動きやすいということになります。言い換えると、トレンドが効きやすいということです。したがって、モメンタム系の特徴量をモデルに与えるとすると、上記の時間帯でモデルを学習し、上記の時間帯のみで運用する方が、全ての時間帯で学習し運用するよりも、パフォーマンスが向上するのではないか？という仮説が立つわけです。また、逆にそれ以外の時間では回帰的な動きをしやすいため、回帰性を前提とする特徴量などをモデルに入れればより良いパフォーマンスが得られるのではないかという仮説が立ちます。

#まとめ

本記事では、特徴量サンプリングの一つであるCUSUMフィルタについて解説を行いました。特徴量サンプリングは、モデルのベストパフォーマンスを追求するために必要です。あと、こちらは本に記載されていない余談ですが、他の特徴量サンプリングの手法として、直近のラベルとの相関(情報係数)が逆転している訓練期間を除くといった手法等があります。
Vue TMDb APIを使って映画検索

#はじめに
完成イメージはこんな感じ

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Vueで映画情報の検索がようやくできた。。<br>社会人ってこんなに忙しんや。。。作りたいアプリを作る時間がこんなに無いとは、先が思いやられる。😭<a href="https://twitter.com/hashtag/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#プログラミング</a> <a href="https://twitter.com/hashtag/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2?src=hash&amp;ref_src=twsrc%5Etfw">#エンジニア</a> <a href="https://t.co/GEUoDZ2iMV">pic.twitter.com/GEUoDZ2iMV</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1311622468952416261?ref_src=twsrc%5Etfw">October 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[Vue 映画情報をTMDb APIを使って取得](https://qiita.com/kokogento/items/569d85c760c4d0316fbd)
一応、上記の続きです。:point_up:

#環境
Vue v2系です。

どうやら2020/09現在、vue v3系ではvuetifyが使えないようなので、あえてv2系にしました。。
https://github.com/vuetifyjs/vuetify-loader/issues/127

使えるようになってら、コメントより教えてください:blush:

別に「vuetifyなんて使わない」と言う方は、特にバージョンを気にしなくて良いかと！

#vuetifyとaxiosを入れる
コマンドプロンプトかターミナルより、プロジェクトvueの階層へ移動

```console
vue add vuetify

npm install axios
```

#TMDbのAPI keyを取得
[【Ionic + Angular】TMDb APIで映画の一覧を取得して表示する](https://qiita.com/kokogento/items/646122b3126037840e72#映画情報を取得できるtmddb-api)
上記リンクのリンクより、取得できます。

#検索してみる

APIのドキュメントはこちら:point_down:
https://developers.themoviedb.org/3/getting-started/search-and-query-for-details


```vue
<template>
    <v-container text-center>
        <v-row>
            <v-col>
                <h1>検索</h1>
                <input
                type='text' 
                v-model='query' 
                placeholder="検索したい映画を入力"
                @keyup='getSearch(query)'
                >
            </v-col>
        </v-row>
        <v-row>
            <v-col v-for='result in results' :key='result.id'>
                 <v-card>
                    <v-img v-bind:src="'http://image.tmdb.org/t/p/w300/' + result.poster_path"></v-img>
                    <v-card-title>{{ result.title }}</v-card-title>
                    <v-card-subtitle>{{ result.release_date }}</v-card-subtitle>
                    <v-card-text>{{ result.overview }}</v-card-text>
                </v-card>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
import axios from 'axios'
export default {
    name: 'search',
    data() {
        return {
            query: '',
            results: '',
            // 自分のkeyに置き換える
            apiKey: '***',

        }
    },
    methods: {
        getSearch(query) {
           axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${this.apiKey}&query=${query}`)
           .then(response => {
               this.results = response.data.results
           });
        },
    }
}
</script>
```

`input`タグで**`@keyup`**を使うことで、どうやら非同期っぽい検索をできるようです:relaxed:

#参考
https://dev.to/mustafaturk/using-the-movie-database-tmdb-with-vue-js-and-axios-1dn8
React JSXの中でfor文やif文を使う方法(備忘録)

# JSXの中でfor文やif文を使う
## 1.即時関数を使う
Reactでは、JSXで直接for文やif文などの文を記述することができません。
以下のように、JSXの中で即時関数を使うことで、for文やif文を使うことができるようになります。


```javascript:test
render() {
    return (
      <div>
        {
          (function () {
            const list = [];
            for (let i = 0; i < 10; i++) {
              list.push(<li>{i}</li>);
            }
            return <ul>{list}</ul>;
          }())
        }
      </div>
    );
  }
```

上のコードの場合、以下のように表示されます。

+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9

## 2.mapを使う
また、Listの内容を表示したい場合などは、mapを使うことで同様にループさせることができます。以下の例では二重ループをmapを使って実装しています。

```javascript:test
render() {
  return(
    <div>
    {
       Array(10).fill(0).map((val, i) => {
         return (
           <div>
             {
                Array(10).fill(0).map((val2, j) => {
                  return(
                    <button>{i} {j}</button>
                  );
                })
              }
            </div>
          );
        })
    }  
    </div>
  );
}
```
macでpython3.8の環境構築


基本的にこれ(以降基本記事)にそって進めます
https://prog-8.com/docs/python-env

2. Homebrewのインストール

にインストールコマンドが記載してありますが
下記サイトの一番上に記載されているコマンドでインストールするようにしましょう

https://brew.sh/index_ja

その後、基本記事に記載してあるようにパスワードを入力して、
下のような表示で先に進めなくなって
再度パスワードを求められたら
xcodeがインストールされていません。

```
Downloading Command Line Tools for Xcode
```

パスワード記載待ちのままターミナルは置いておいて、
xcodeをインストールしましょう

インストール方法はこちら
https://qiita.com/nakashunshun/items/0f4bc585530ec75c62cb


Command Line Toolsのインストールまで終わったら
戻ってきましょう

再度パスワードを入力すればインストールできるはずです


「実行結果が /bin/bash の場合、以下４つのコマンドを実行してください。」
まで進めましょう
この４つのコマンドではなく下の記事を参考にしましょう。
https://qiita.com/crankcube/items/15f06b32ec56736fc43a


4. Pythonのインストール　まで進めましょう


```
pyenv install 3.6.5
```

ここで3.8.0を指定しましょう

あとは記事の通りに進めればOKです！
【CSS】iOS_Safariなどでコンテンツの幅がオーバーしてしまう時の対処方法

ページ制作時にブラウザの違いで
デザインが微妙に変わってくるのは良くあります。

その中でもiOS Safariなどで
コンテンツの幅がオーバーした時に対処した方法です。
幅100指定で横スクロールが出ると結構カッコ悪いです。
※iOSに限らない課題でもあります。
![haba.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/dffd9bc1-420c-b377-8225-0d83334d8de1.png)

##paddingやborderの幅の解釈の違い
レスポンシブを意識してコーディングしているのに
はみ出てしまう。その要因の1つとして考えられるのが
幅指定とpaddingの解釈です。
※ボックスモデルという各領域の解釈

例：

```
<div style="width:100%;padding:10px;">
TEXT
</div>
```

このような書き方ですと幅100%に加えて10pxの
内部余白を付けるという意味合いになります。

##回避1： 幅指定とpadding指定のボックスは分ける
この場合は幅100%のボックスの中に、
余白10px付きのものがあるという意味合いに
なりますのではみ出ません。

```
<div style="width:100%;">
	<div style="padding:10px;">
	TEXT
	</div>
</div>
```


##回避2： box-sizingプロパティを使う
これはborderとpaddingの幅も含めてその要素の
サイズですと指示するためのものです。
paddingの10pxはあくまで100%の中の幅として
認識されます。

```
<div style="width:100%;padding:10px;box-sizing:border-box;">
TEXT
</div>
```

##まとめ
個人的に、この幅とposition(配置）辺りは
CSSの中でも特にわかり辛いなと思っています。
だからこそ実際に複数のパターンを書いてみて、
表示してみて覚える事をオススメします。
コマンド docker-compose 

# 超基本的コマンド

```:起動しているコンテナを表示
docker-compose ps
docker-compose ps -a #停止コンテナも含めて全表示
```
```:コンテナを起動
docker-compose start (up -dでも大丈夫)
```
```:コンテナを作成・起動
docker-compose up
docker-compose up -d #バックグラウンドで実行 
```
```:起動しているコンテナを停止
docker-compose stop
```
```:イメージのビルド
docker-compose build
```
```:コンテナの作成
docker-compose create
```
```:コンテナを破棄
docker-compose down
```
```:コンテナへ接続
docker-compose exec コンテナ名 bash
```
```:ログを表示
docker-compose logs コンテナ名
```

# ちょっと応用

```:サービス内でどの環境変数が利用可能か調べる
docker-compose run サービス名 env
```
```:コンテナを破棄してイメージも破棄
docker-compose down --rmi all
```
キーワードで勉強しよう！ - ORM

##ORM(Object-relational mapping)
ORMはオブジェクトと関係型データベースを相互連結してくれるツールやフレームワークのこと。
関係型データベースから取得したレコードが自動的にオブジェクトに入るため開発者がレコードのデータを一つづつオブジェクトに格納する処理を構築しなくてもよいし、逆に関係型データベースを更新するために毎回SQLに更新するデータをマッピングしなくてもよい。

ORMを使うには取り扱うデータをオブジェクトにする必要がある。オブジェクトにセットやゲットメソッドがあれば使用部で自動的にデータを取扱いしてくれる。

```java:java
public class Item{
    private String name;
    private String code;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getCode() {
        return this.code
    } 
}
```
上記のようなソースコードでメンバーnameとcodeはテーブルのカラムに該当する。

##ORMの種類

| ORMの種類 | 代表的なORM |
|:-:|:-:|
|JDBCラッパー型|Spring JDBC、Apache Common DbUtils、sql2o|
|SQLマッパー型|MyBatis、Doma、Mirage SQL、jdbi|
|クエリビルダー型|JOOQ、DBFlute、Reladomo、Querydsl、Ebean、Speedment、 Jinq、requery、Cayenne、Torque|
|ORマッパー型(JPA仕様の実装)|Hibernate、EclipseLink|

##参考
[参考１]
(https://qiita.com/niisan-tokyo/items/156eb35c6eeaf07b9b65)
[参考２]
(https://qiita.com/niisan-tokyo/items/156eb35c6eeaf07b9b65)
既定のディストリビューションを Ubuntu-20.04, WSL 2 に更新する

# はじめに

## WSL 2 の概要
2020年、Microsoft から WSL 2 が発表されました。
これまでの WSL 1 に比べ、高いパフォーマンスを期待できます。
また、GUI の扱いが簡単になります。:computer:

詳細：[WSL 1 と WSL 2 の比較](https://docs.microsoft.com/ja-jp/windows/wsl/compare-versions)

## 目的
既定のディストリビューションを Ubuntu-18.04 (WSL 1) から Ubuntu-20.04 (WSL 2) に切り替えたい。

# 手順

## 1. Linux 用 Windows サブシステムを有効にする

管理者として PowerShell を開く。（スタートメニューボタン右側の「ここに入力して検索」に `PowerShell` と入力。PowerShell が表示されたら、右クリックで「管理者から開く」を選択する）

PowerShell に以下コマンドを入力。

```
    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

## 2. 既定のディストリビューションを WSL 2 に更新するための必要条件を満たしているかを確認

スタートメニューボタン右側の「ここに入力して検索」に `winver` と入力し、 winver を開くと、使用している Windows のバージョン情報が確認できる。
以下必要条件を満たしているか確認する。

- 
    x64 システムの場合:バージョン `1903` 以降、ビルド `18362` 以上。
- 
    ARM64 システムの場合:バージョン `2004` 以降、ビルド `19041` 以上。

満たしていなかった場合、Windows 更新アシスタントで Windows を更新する。

（ちなみに、自分のPCのバージョンは以下の通りで、必要条件を満たしていました。

> Microsoft Windows
> バージョン `1909` (OS ビルド `18363`, 1082)

）

## 3. 再起動
Windows を再起動する。

## 4. WSL2 Linux カーネル更新プログラム パッケージをインストール
[ここ](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)から WSL2 Linux カーネル更新プログラム パッケージのインストーラをダウンロードし、実行する。

## 5. Ubuntu-20.04 を入手
Microsoft Store から [Ubuntu-20.04](https://www.microsoft.com/ja-jp/p/ubuntu-2004-lts/9n6svws3rx71?rtc=1&activetab=pivot:overviewtab) を入手する。

## 6. 既定のバージョンを WSL 2 に更新

再び PowerShell を管理者から開き、以下コマンドを入力して既定のバージョンを Ubuntu-20.04 の WSL 2 に更新する。

```
wsl --set-version Ubuntu-20.04 2
```

## 7. 既定のバージョンが更新されたかを確認

PowerShell に以下コマンドを入力して既定のバージョンを確認する。

```
wsl --list --verbose
```

以下のような出力になればOK。

```
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2
  Ubuntu-18.04    Stopped         1
```

`*` がついている方が既定のディストリビューションです。

また、スタートで `Ubuntu` と入力したとき、一番上に Ubuntu-20.04 が出てくることを確認してください。


# 参考
[Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
HTMLでの略語や名前、住所の記述方法

#プログラミング勉強日記
2020年10月4日
`<abbr>`は略語要素を表すことは知っていたが、それ以外の住所や名前の表現を知らなかったので今回まとめる。

#略語を記述する場合
　略語は`<abbr>`属性(abbreviation)を使って表す。主にtitleタグと一緒に使われて、abbrタグで囲まれた部分が略語であることを示す。abbrタグで囲まれたところにカーソルを合わせるとtitleタグで入力したものが表示される。(titleタグはタイトルを付けて、検索エンジンの検索結果に反映されるタグ)

```html:例
<abbr title="Hypertext Markup Language">HTML</abbr>について
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/e16a55ee-e834-0a39-3eca-9c7c1edcfc55.png)

#名前を特記する場合
　名前を特記する場合には、`<cite>`属性を使って表す。citeは引用するといった意味があり、映画や本、新聞といったタイトル名を記述するときに使われる。HTML5では作品のタイトルに使うことが推奨されている。

```html:例
<cite>ハリーポッターと賢者の石</cite>はシリーズの最初の作品です。
```

#住所を記述する場合
　住所や連絡先を記述する場合には`<address>`属性を用いる。

```html:例
<address>東京都渋谷区道元坂一丁目</address>
```

#まとめ
　それぞれの属性は意味を持っているので、見た目は変わらなくてもHTMLではそれぞれ意味が異なるので、属性を正しく使い分けることが大切。適切な属性を使うことでページの価値が高くなる。

#参考文献
[HTMLで略語を表現する方法 – abbr【初心者向け】](https://techacademy.jp/magazine/5629)
[abbr 属性](https://reference.hyper-text.org/html5/attribute/abbr/)