OmniAICreator/Qiita-1.07M huggingface dataset:
Rust: MariaDB のデータを読む (Read)

こちらのページと同様のことを行いました。
[Rustで直接SQLを書いてMySQLからデータを抽出する方法](https://qiita.com/tonio0720/items/d6d81ecebb4559a83dd7)

Ubuntu 20.4 で必要となるライブラリーのインストール

```bash
sudo apt install libmariadb-client-lgpl-dev-compat
```

フォルダー構造

```text
$ tree -L 2
.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── main.rs
│   └── utils.rs
└── target
    └── debug
```

```text:Cargo.toml
[package]
name = "read"
version = "0.1.0"
edition = "2018"

#

[dependencies]
diesel = { version = "*", features = ["mysql"] }
```

```rs:src/main.rs
// --------------------------------------------------------------------
/*
	read/src/main.rs

					Jul/20/2020
*/
// --------------------------------------------------------------------

use crate::utils::establish_connection;
// use chrono::NaiveDateTime;
// use chrono::DateTime;

use diesel::deserialize::QueryableByName;
use diesel::mysql::MysqlConnection;
use diesel::prelude::*;
use diesel::sql_query;

mod utils;

type DB = diesel::mysql::Mysql;

#[derive(Debug)]
pub struct Cities {
    id: String,
    name: String,
    population: i32,
	date_mod: String,
//	date_mod: DateTime,
}

// --------------------------------------------------------------------
impl QueryableByName<DB> for Cities {
    fn build<R: diesel::row::NamedRow<diesel::mysql::Mysql>>(
        row: &R,
    ) -> diesel::deserialize::Result<Self> {
        Ok(Cities {
            id: row.get("id")?,
            name: row.get("name")?,
            population: row.get("population")?,
	date_mod: row.get("date_mod")?,
        })
    }
}

// --------------------------------------------------------------------
fn simple_sql() {
    let connection: MysqlConnection = establish_connection();
    let cities: Vec<Cities> = sql_query(
        "SELECT id, name, population, date_mod FROM cities",
    )
    .load(&connection)
    .unwrap();

//    println!("{:?}", cities);

	for uu in cities.iter(){
//		println!("{:?}",uu);
		println!("{}\t{}\t{}\t{}",uu.id,uu.name,uu.population,uu.date_mod);
		}
}

// --------------------------------------------------------------------
fn main (){
	eprintln! ("*** 開始 ***");
	simple_sql();
	eprintln! ("*** 終了 ***");
}

// --------------------------------------------------------------------
```

```rs:src/utils.rs
// --------------------------------------------------------------------
/*
	src/utils.rs

					Jul/12/2020
*/
// --------------------------------------------------------------------
use diesel::mysql::MysqlConnection;
use diesel::prelude::*;

pub fn establish_connection() -> MysqlConnection {
    let database_url = "mysql://scott:tigermask@localhost:3306/city";
    MysqlConnection::establish(&database_url)
        .expect(&format!("Error connecting to {}", database_url))
}

// --------------------------------------------------------------------
```

コンパイル

```bash
carogo build
```

実行

```text
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/read`
*** 開始 ***
t3321	岡山	43781	2000-3-15
t3322	倉敷	79124	2000-8-9
t3323	津山	31586	2000-6-21
t3324	玉野	52647	2000-10-12
t3325	笠岡	82631	2000-9-25
*** 終了 ***
```
Vue.js 3.0(beta 20) helloworld

# Vue.js 2.x で書いた hello world を Vue.js 3.0 beta を使って書き換え

CDNを使ってHTMLファイルとして作っています。
Composition APIは使ってません。

## Vue.js 2.x

```html
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>hello world</title>
<div id="app">
  <p>{{ display }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.6/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: { display: 'Hello World!' }
  });
</script>
```

## Vue.js 3.0.0-beta.20

```html
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>hello world</title>
<div id="app">
  <p>{{ display }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0-beta.20/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data: () => ({
      display: 'Hello World!'
    })
  });
  app.mount('#app');
</script>
```

### ポイント
* Vueコンストラクタの代わりに、`createApp`を使います。
* `data` オプションはコンポーネントと同様に、関数にする必要があります。
* `el`オプションの代わりに、`mount`を使います。
GASを用いたSlack Bot（対話型）の作り方


![alt](https://a.slack-edge.com/80588/img/slack_api_logo_vogue.png)

# Slackアプリの作成
1. https://api.slack.com/apps にアクセスし、アプリを作成。
2. `Incoming Webhooks/`
  - `Activate Incoming Webhooks`をONにする。
  - `Add New Webhook to Workspace`。
  - `Webhook URL`を控えておく。
3. `Basic Information/`
  - `Verification Token`を控えておく。

# GASプロジェクト（+スプレッドシート）の作成
1. https://drive.google.com/drive/my-drive にアクセスし、スプレッドシートを作成。
2. スプレッドシートの名前を決めて、`ツール`から`<> スクリプト エディタ`を開く。
3. ソースコードを書く。（参考： [イベントオブジェクトの形式](https://api.slack.com/events/message.channels)）
4. `公開/ウェブアプリケーションとして導入/`
  - `Project version`: New
  - `Execute the app as`: Me
  - `Who has access to the app`: Anyone, even anonymous
5. Deployして`Current web app URL`を控えておく。

# SlackアプリのWebhook設定
1. https://api.slack.com/apps に戻り、本アプリのページへ。
2. `Event Subscriptions/`
  - `Enable Events`をONにする。
  - `Request URL`にGASプロジェクトの`Current web app URL`を設定。
  - `Subscribe to events on behalf of users`に`message.channels`を設定。
  - `Save Changes`して、スナックバーからreinstall。
【C#】ディレクトリを再帰的に探索する【技術メモ】

指定したディレクトリ及びそのサブディレクトリ内のファイルに対して処理を実行したいときに使う。

```c#
/// <summary>
/// ディレクトリを再帰的に探索します。
/// </summary>
/// <param name="directoryName">探索するディレクトリのルート。</param>
private static void RecursivelySearchingDirectories(string directoryName)
{
    Directory
        .GetFiles(directoryName)
        .Where(/* 処理対象のファイルを抽出 */)
        .ToList()
        .ForEach(/* 実行したい処理 */);
    Directory
        .GetDirectories(directoryName)
        .ToList()
        .ForEach(RecursivelySearchingDirectories);
}
```
[SwiftUI macOS アプリ] NavigationView List の Detail 画面で TextField を使うサンプル（Optional Binding）

<img width="741" alt="スクリーンショット 2020-07-12 20.30.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45822/c273d960-9a4c-cc07-7a3b-6db6fd4adaba.png">

ポイントはオプショナルをバインディングするところです。extension を追加しています。


```swift:ContentView.swift
import SwiftUI

struct Person: Identifiable, Hashable {
    var name: String
    var id = UUID()
    var order: Int
}

struct ContentView: View {
    
    @State var persons = [
        Person(name: "taro", order: 2),
        Person(name: "yuki", order: 1),
        Person(name: "hoge", order: 0)
    ]
    
    @State private var selectedPerson: Person?
    
    var body: some View {
        VStack {
            HStack {
                AddButton(persons: $persons, selected: $selectedPerson)
                Button("remove", action: {
                    print(self.selectedPerson)
                    if self.selectedPerson == nil {
                        return
                    }
                    self.persons.removeAll(where: {$0.id == self.selectedPerson!.id})
                    self.selectedPerson = nil
                })
            }
            NavigationView {
                List(persons.sorted{$0.order > $1.order}, id: \.self, selection: $selectedPerson) { person in
                    Text(person.name)
                }.frame(width: 150)

                if selectedPerson != nil {
                    Detail(person: $selectedPerson.bound)
                } else {
                    Text("nothing").frame(maxWidth: .infinity, maxHeight: .infinity)
                }
            }.frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

struct AddButton: View {
    @Binding var persons: [Person]
    @Binding var selected: Person?
    var body: some View {
        Button("add", action: {
            let names = ["foo", "bar", "baz", "tao", "tee"]
            let newPerson = Person(name: names.randomElement()!, order: self.persons.count)
            self.persons.append(newPerson)
            self.selected = newPerson
        })
    }
}

extension Optional where Wrapped == Person {
    var _bound: Person? {
        get { return self }
        set { self = newValue }
    }
    
    var bound: Person {
        get { return _bound ?? Person(name: "", order: 9999) }
        set { _bound = newValue }
    }
}

struct Detail: View {
    @Binding var person: Person
    var body: some View {
        VStack {
            TextField("", text: $person.name)
            Text(person.name)
        }.frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
```

# 参考
https://www.youtube.com/watch?v=lXTEmh5XYHs
GASを用いたLINE Bot（対話型）の作り方


![alt](https://developers.line.biz/media/common/logo-black.png)

# LINEチャネルの作成
1. https://developers.line.biz/ja/ にアクセスし`ログイン`。
2. `コンソール（ホーム）`からプロバイダーを`作成`。（既存のプロバイダーを用いても良い）
3. `Messaging API`タイプのチャネルを作成。（各項目は適当に選ぶ）

# LINEチャネルの設定
1. チャネルの詳細ページに行く。
2. `Messaging API設定/`
  - `チャネルアクセストークン（長期）`を発行し保存。
  - `LINE公式アカウント機能`へ行き、編集から【別窓】に飛ぶ。
3. 【別窓】（LINE公式アカウントマネージャー）
  - 左ペインの`応答設定`から`応答モード：Bot` `あいさつメッセージ：オン` `応答メッセージ：オフ` `Webhook：オン`と設定。
  - 左ペインの`Messaging API`から`Channel secret`を控えておく。（使わないこともある。）

# 友達になる
デバッグのためにも友達になっておく。QRコードが簡単。

1. チャネルの詳細ページに行く。
2. `Messaging API設定`からQRコードを読み込む。

# GASプロジェクト（+スプレッドシート）の作成
1. https://drive.google.com/drive/my-drive にアクセスし、スプレッドシートを作成。
2. スプレッドシートの名前を決めて、`ツール`から`<> スクリプト エディタ`を開く。
3. ソースコードを書く。（参考: [イベントオブジェクトの形式](https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects)）
4. `公開/ウェブアプリケーションとして導入/`
  - `Project version`: New
  - `Execute the app as`: Me
  - `Who has access to the app`: Anyone, even anonymous
5. Deployして`Current web app URL`を控えておく。

# LINEチャネルのWebhook設定
1. https://developers.line.biz/ja/ に戻り、本チャネルのページへ。
2. `Messaging API設定/Webhook設定/`
  - `Webhook URL`にGASプロジェクトの`Current web app URL`を設定。
  - `Webhookの利用`をONにする。

# 実際に作ったアプリで公開しているもの
https://github.com/2754github/GAS_LINE_Bot
OKE用 oci cli, kubectl install commands memo

# はじめに

次のインストール手順 Quick Start メモ

- OCI CLI
- kubectl



# OCI CLI

https://qiita.com/sugimount/items/63a8cfe1163030ae8804



# kubectl

```
mkdir ~/kubectl
cd ~/kubectl
wget https://storage.googleapis.com/kubernetes-release/release/v1.16.8/bin/linux/amd64/kubectl
chmod +x ~/kubectl/kubectl
echo 'PATH=$HOME/kubectl:$PATH' >> $HOME/.bashrc

source $HOME/.bashrc
```

# kubectx, kubens

```
git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
COMPDIR=$(pkg-config --variable=completionsdir bash-completion)
ln -sf ~/.kubectx/completion/kubens.bash $COMPDIR/kubens
ln -sf ~/.kubectx/completion/kubectx.bash $COMPDIR/kubectx
cat << FOE >> ~/.bashrc


#kubectx and kubens
export PATH=~/.kubectx:\$PATH
FOE

source .bashrc
```
enumの互換性エラーの対処法

# Optunaインストール時に起きたエラーの原因と対処法

環境は以下の通り

- Windows 10 Home 
- python 3.6.5 
- pip 19.3.1 

### Optunaをインストールしようと以下コードを実行したらエラーが出た

```:実行文
pip install optuna
```


```:実行結果
Collecting optuna
  Downloading https://files.pythonhosted.org/packages/33/32/266d4afd269e3ecd7fcc595937c1733f65eae6c09c3caea74c0de0b88d78/optuna-1.5.0.tar.gz (200kB)
     |████████████████████████████████| 204kB 1.7MB/s
Collecting alembic
  Downloading https://files.pythonhosted.org/packages/60/1e/cabc75a189de0fbb2841d0975243e59bde8b7822bacbb95008ac6fe9ad47/alembic-1.4.2.tar.gz (1.1MB)
     |████████████████████████████████| 1.1MB 6.4MB/s
  Installing build dependencies ... error
  ERROR: Command errored out with exit status 1:
   command: 'D:\Users\(user_name)\Anaconda3\python.exe' 'D:\Users\(user_name)\Anaconda3\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\(user_name)\AppData\Local\Temp\pip-build-env-5wsdb490\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=40.8.0' wheel
       cwd: None
  Complete output (14 lines):
  Traceback (most recent call last):
    File "D:\Users\(user_name)\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main
      "__main__", mod_spec)
    File "D:\Users\(user_name)\Anaconda3\lib\runpy.py", line 85, in _run_code
      exec(code, run_globals)
    File "D:\Users\(user_name)\Anaconda3\lib\site-packages\pip\__main__.py", line 16, in <module>
      from pip._internal.main import main as _main  # isort:skip # noqa
    File "D:\Users\(user_name)\Anaconda3\lib\site-packages\pip\_internal\main.py", line 8, in <module>
      import locale
    File "D:\Users\(user_name)\Anaconda3\lib\locale.py", line 16, in <module>
      import re
    File "D:\Users\(user_name)\Anaconda3\lib\re.py", line 142, in <module>
      class RegexFlag(enum.IntFlag):
  AttributeError: module 'enum' has no attribute 'IntFlag'
  ----------------------------------------
ERROR: Command errored out with exit status 1: 'D:\Users\(user_name)\Anaconda3\python.exe' 'D:\Users\(user_name)\Anaconda3\lib\site-packages\pip'
 install --ignore-installed --no-user --prefix 'C:\Users\(user_name)\AppData\Local\Temp\pip-build-env-5wsdb490\overlay' --no-warn-script-location 
--no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=40.8.0' wheel Check the logs for full command output.
```
# エラー内容
```:エラー文
ERROR: Command errored out with exit status 1: 'D:\Users\(user_name)\Anaconda3\python.exe' 'D:\Users\(user_name)\Anaconda3\lib\site-packages\pip'
 install --ignore-installed --no-user --prefix 'C:\Users\(user_name)\AppData\Local\Temp\pip-build-env-5wsdb490\overlay' --no-warn-script-location 
--no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=40.8.0' wheel Check the logs for full command output.
```

# 原因
標準ライブラリenumモジュールではなく、enum34パッケージのものが使われており、Python 3.6以降、enum34ライブラリは標準ライブラリenumと互換性がなくなったため。

# 解決策
Python3.6以降を使う場合、enum34ライブラリも不要なので、アンインストールし標準ライブラリのenumモジュールを使う。

```:enum34をアンインストール
pip uninstall enum34
```


enum34をアンインストール後、再度`pip install optuna`を実行すると、無事Optunaをインストールすることができました！
Windows10 HomeにDockerをインストールしようと思ったがうまくいかなかった

## Windows10 HomeにDockerをインストール

Pythonの勉強を始めようと思ってるんですが、どうせならDockerで
環境を作ろうかなと思ったわけです。

ただ、Docker Desktop for Windows は Hyper-V の利用を前提としているので
Windows10 Proが必要みたいなんですよね。
Windows10 HomeでDockerを使うにはDocker Toolboxをインストールすればいいらしい。

Docker Toolboxのインストール手順を調べてたんですが、
Docker Desktop for WindowsがWindows10 HomeDのWSL2に対応するという記事を見まして
Windows10 HomeにDockr Desktop for windowsのインストールを試してみました。

##まずはDockerインストールやってみる

Dockerをインストール。

https://docs.docker.com/docker-for-windows/install/

![docker1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/5a3b04b5-c497-1b80-3b42-074600ba8925.jpeg)

DockerhubからGet stableボタンをクリック。

![docker2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/5ab8615e-a4d4-d6fd-876a-9d50b7957c19.jpeg)

インストールをスタート。

![docker3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/4766ccee-437d-a70e-1800-7d9f442c0bd5.jpeg)

ダメみたいですね。
OSビルドが古い感じ？

##Windowsアップデートをやってみる


Docker Desktop for windowsに対応しているのは、
Windows10 Home(19018以降）ってことみたいなので、アップデートをしてみる。

調べてみるとWindows Insider Programでスローにしてアップデートするってことらしいけど。
![insider.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/26690284-41d8-7d83-4f3c-5da187452727.jpeg)

スロー設定ってないやん。

https://news.mynavi.jp/article/20200616-1057186/
配信方法が、リンク制からチャネル制にされてるのか。
Fastリング→Devチャネル、Slowリング→Betaチャネル、Release Previewリング→Release Previewチャネルってことね。

よし、Windows10 updateっと。


![update.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/892ef4eb-0af6-2b46-b519-0e5908e1647e.jpeg)

あれ、止まっちゃった。
何が引っかかってんだろ。

![update2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659477/5fab7bb6-2b4f-c182-22ad-c1d8c6138f70.jpeg)

アップデート先に進まないし。

これが解決するまで保留だな。
SwiftUI NavigationLinkの遷移時に別処理をかませる

備忘録。
この用途にあったメソッドがあった。

.simultaneousGestureをNavigationLinkにつけてあげれば良い↓

```swift

NavigationLink(destination: TradeView(trade: trade)) {
     Text("Trade View Link")
}.simultaneousGesture(TapGesture().onEnded{
     print("Hello world!")
})
```
[JavaScriptデバッグテクニック]メソッド実行中の変数の中とか見たくない？

それ debugger文 でできるよ
開発者ツールを開いていれば `debugger` とコードに書かれたところが実行された瞬間で止まってくれます。
コードに直接記載できるブレークポイントみたいなものですね。
（開発者ツールを閉じていると特に何も起きません）

```サンプル.js
function hoge(){
  const test = 1
  debugger
}
hoge() // debugger文で止まってソースパネルが開く
```



[debugger \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/debugger)

> **debugger ステートメント**は、ブレークポイントの設定のような任意の利用可能なデバッグ機能を呼び出します。デバッグ機能が利用可能ではない場合、このステートメントは効果がありません。

## debugger文のいいところ
昨今はトランスパイルが流行りなので、コンパイル済みコードにブレークポイントを仕掛けるのは面倒ですが、
この方法ならイベントで起動するメソッドなど、どんなところでも簡単にブレークポイントを貼れます。

## 変数の中とか見たいしメソッドも実行したい
![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/905e2e88-31fc-8a11-b008-5920641cd32d.gif)


止まっている時にconsoleタブに戻ることができます。
この時、スコープは止まっているメソッドの中になります。

なので、現在のスコープにある変数に直接操作したりできるので
「コードを書いて保存して動かして動作を確認して、駄目ならまたコードを書き換えて…」みたいな煩わしさから開放されます！

是非活用してみてください。

# その他のデバッグ術
- [\[サーバーサイドAPIデバッグ術\]ブラウザのリクエストを簡単にリトライしてサーバーの挙動を見る方法 \- Qiita](https://qiita.com/fruitriin/items/72d66cf88b8319512620)
- [\[HTML/CSS高速コーディング\]ギリギリまでコードを書かないChrome DevToolsのリアルタイムレイアウト確認テクニック \- Qiita](https://qiita.com/fruitriin/items/1e01f57ecb750f3612d0)
CSSだけでスタイリッシュな下線付き矢印

# 色々と探したがありそうでなかったデザイン
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">CSSだけでスタイリッシュな下線付き矢印 <a href="https://t.co/UHLdy2RGGm">pic.twitter.com/UHLdy2RGGm</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1282266012172185600?ref_src=twsrc%5Etfw">July 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回紹介するのはこんなデザイン！
<img width="406" alt="スクリーンショット 2020-07-12 19.41.52.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/9b46f4b1-863d-33b8-6990-99b44d133557.jpeg">

なかなかありそうで無かった。。。

# 下線付き矢印を作る

```html
  <div class="row">
          <div class="moreLink">
            <div class=" moreLinkText">実現したいことについて、もっと知る
              <div class="lineArrow"></div>
            </div>
          </div>
        </div>
```

```css
.moreLinkText {
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
  transition: all  0.3s ease;
}
/*ホバーしたときに下線矢印も同時に色を変える*/
.moreLinkText:hover .lineArrow  {
    border-bottom: 1px solid #41A849;
    border-right: 1px solid #41A849;
}
.moreLinkText:hover {
    color: #41A849;
}
.lineArrow {
  width: 120%;
  height: 15px;
  border-bottom: 1px solid #000;
  border-right: 1px solid #000;
   /*傾きを調節*/
  transform: skew(45deg);
  /*下線矢印をテキストに合わせてうまい具合にはめる*/
  margin: -10px 0 0 -25px;
}
```





# 参考
https://hirashimatakumi.com/blog/217.html

https://beginners-high.com/css-hover-change/
SAS/R データの横結合方法の比較

# SASとRでの、データの結合の比較
SASのデータセットの結合と、Rのデータフレームの結合について
いろいろな方法があると思うが、以下の方法を紹介(縦結合は略)

SASはdataステップのmergeステートメント
Rはdplyrのleft_join,inner_joinなど

また、SASもRもSQLの構文を使える
https://qiita.com/saspy/items/43b4c368d22f45f023a2


# SASのデータ結合 mergeステートメント
ソートされている前提

```sas
data work.DATA_MERGE_RESULT;
  merge
    DATA1( in = ds1 )
    DATA2( in = ds2 )
  ;
  by キー変数1 キー変数2 ... ;

%* 以下のどれかを使用 *;
%* DATA1にある行を残す場合( SQLでいうleft join ) *;
  if ds1 = 1;

%* DATA2にある行を残す場合( SQLでいうright join ) *;
  if ds2 = 1;

%* DATA1,DATA2のどちらにもある行を残す場合( SQLでいうinner join ) *;
%* 数学でいう積集合 *;
  if ds1 * ds2 = 1;

%* DATA1,DATA2のどれかにある行を残す場合( SQLでいうfull join ),別になくてもいい *;
%* 数学でいう和集合 *;
  if ds1 + ds2 >= 1;

%* DATA1だけにある行を残す場合( 数学でいう差集合 ) *;
  if ds1 - ds2 = 1;

%* DATA1かDATA2だけにある行を残す場合( 数学でいう対称差 ) *;
  if abs( ds1 - ds2 ) = 1;
run;
```

in=オプションで、指定したデータセットの行なのか判断(値は1か0が入る)
setステートメントでも使えるため、縦結合で元のデータセットを判断するときにも使ったりする

また、SASの場合はソートしてからmergeって流れに注意
(SQL使ったりすればいらなかったりする)

ds2プロシジャやHashなど、いろいろな方法でできるよう
自分の場合ds2は結局SQLでやってるが


# Rのデータ結合 dplyrパッケージのleft_joinやinner_joinなど

```r
library(tidyverse)

DATA_MERGE_RESULT <- dplyr::left_join( DATA1 , DATA2 , by = c( "キー変数1" , "キー変数2" ) )

# SQLのように、キー変数の名前が異なる場合でも結合可能
DATA_MERGE_RESULT <- dplyr::left_join( DATA1 , DATA2 , by = c( "DATA1のキー変数1" = "DATA2のキー変数1" , "キー変数2" ) )

```

left_joinをinner_join,full_join,anti_joinなどに変えれば、あとはSQLと同様の結合が可能
ソート不要

https://www.rdocumentation.org/packages/dplyr/versions/0.7.8/topics/join
「【学生向け】二次関数　その１」を参考にしました（WolframAlphaとonline sympyで実行しました）

（オリジナルポスト）【学生向け】二次関数　その１
https://qiita.com/ParisMichael/items/3a2b7d40d4e6873d512e

##Wolfram|Alpha 日本語版で実行しました。
https://ja.wolframalpha.com/input/?i=y%3Dx%5E2%2C+y%3D2x%5E2%2C+y%3D0.5x%5E2

##online sympyで実行しました。
https://live.sympy.org
plot(x**2, (x, -10, 10), adaptive=False, line_color=lambda a: x**2(a))

（参考）読書ノート » SymPy 利用ノート »プロットを利用する
https://showa-yojyo.github.io/notebook/python-sympy/plotting.html

（参考）Plotting — SymPy 1.6.1 documentation
https://docs.sympy.org/latest/modules/plotting.html

関数を複数個plotする方法を教えて下さい。
よろしくお願いします。

#おまけ:日本語は難しいですね。
「参考にさせていただきます」は失礼なのか
https://www.google.com/search?q=参考にさせていただきます&oq=さんこうに&aqs=chrome.2.69i57j0l3.9027j0j7&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8
個人的にFlutterで何回も調べがちなことまとめ

個人的な備忘としてまとめておきます
最近弊社で開発してるAndroidアプリがFlutter製ということもあり、
開発する中で何度も調べることがもっと増えてくると思うので逐次更新していきます。

## 環境
 
- Flutter 1.17.4 
- Dart 2.8.4

## Container の装飾周り

#### 角丸にする

```dart

Container(
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(4.0),
  ),
);
```

### 枠線を描く

```dart
Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.blueAccent)
  ),
);
    
```

### 影をつける

```dart
Container(
  decoration: BoxDecoration(
    color: Colors.white,
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.5),
        spreadRadius: 0,
        blurRadius: 4,
        offset: Offset(0, 2),
      ),
    ],
  ),
);
```

## Navigator での画面遷移周り


### 画面遷移

`Flutter 画面遷移` でいつも調べてます
Navigator は iOS と同じならスタック（後のせ先取り）なので **push** はお皿を積むイメージ

```dart
Navigator.push(
  context,
  MaterialPageRoute<Null>(
    settings: RouteSettings(name: "/detail"),
    builder: (BuildContext context) => Container();
  )
);
```

### 前の画面に戻る

**pop** はお皿を取るイメージ
一枚だけ上からとります

```dart
Navigator.pop(context);
```

### rootまでpopする

積んだお皿全部退けます

```dart
Navigator.popUntil(context, ModalRoute.withName('/'));
```

## TextField の装飾周り

### 枠線を描く

iOS ちっくなTextFieldにしたいときよく使う

```dart

TextField(
  decoration: InputDecoration(
    border: OutlineInputBorder(),
  ),
);
```

### ラベルとヒントをつける

プレースホルダー的なやつを設定したいときあるけどよく忘れる

```dart
TextField(
  decoration: InputDecoration(
    labelText: 'ラベル',
    hintText: 'ヒント',
  ),
);
```
A2019 Bot Agent インストール中に "Automation Anywhere Bot Agent service install configuration fail to register and return error (5)" が出る場合の対処法

# 現象
Automation Anywhere A2019のBot Agentのインストール中に **"Automation Anywhere Bot Agent service install configuration fail to register and return error (5)"** というエラーが出て停止し、その後インストーラがロールバックしてしまいBot Agentがインストールされない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/aace6c6f-a968-5f36-ab62-5a6432fd9069.png)

### 対象

* 商用版 Enterprise A2019
* Community Edition A2019
* Free Trial Enterprise A2019

### 追加情報
Bot Agentがインストールされていた環境に、Bot Agentのアップグレードなどで何回かアンインストールをして再インストールをしたタイミングである時点から本現象が発生。昔は正常にインストールできていたという点で、システム要件を見たいしていないという問題とは異なります。

# 考えられる原因
前回のアンインストール時にBot Agentサービスの残骸が残っていて、再インストールの際の障害となっていることが考えられます。

# 対処法
残っている残骸を手動で削除します。

### 1. Bot Agentフォルダーの削除、プロセスの削除
以下の場所にフォルダーがあるかを確認します。ある場合は、以下のフォルダーの中身とフォルダー自信を削除します。
`C:\Program Files\Automation Anywhere\Bot Agent`

削除ができない場合、生きているプロセス等がある場合はタスクマネージャーで探して終了してください。
例: `C:\Program Files\Automation Anywhere\Bot Agent\nssm\nssm.exe`

### 2. "Automation Anywhere Bot Agent" サービスの削除
実体ファイルを削除するだけでは、サービスは削除されない場合があります。その場合は「サービス管理ツール」を開いてみましょう。サービス管理ツールはコントロールパネルからも開けますが、タスクマネージャーの「サービス」タブの下側からも開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/2db6b3ce-e65a-d283-18ae-15d829c7c521.png)

サービス管理ツールが開いたら、一覧で「Automation Anywhere Bot Agent」というサービス名がないかを探してみましょう。実体ファイルが削除された後も、サービスのエントリは残っている可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/a3c0df18-a123-84c6-ea66-068cdc793d3d.png)

詳細を見てみると、サービスは停止してはいるものの、まだ登録があることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/f8547d36-dbdf-ef9c-b3ff-5219da9f2f7e.png)

サービスを手動で削除するには、コマンドプロンプトから行う必要があります。**コマンドプロンプトを管理者として実行**して起動してください。コマンドプロンプトのコンテキストメニューに「管理者として実行」があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/c8176fff-6087-a9bd-b7a5-d3bb69569e4a.png)

管理者として実行で起動したコマンドプロンプトは、タイトルが**「管理者: コマンドプロンプト」**となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/1c45a1eb-8e7c-dd6b-a383-774a1d67ea65.png)

この状態で、以下のコマンドを実行します。サービス名は、先ほどのサービス管理ツールの詳細ダイアログボックスから持ってきます。

```
sc DELETE "Automation Anywhere Bot Agent"
```
正常に完了すると、以下のメッセージが表示されます。

```
[SC] DeleteService SUCCESS
```

サービス管理ツールの表示を再表示させると、エントリーはなくならないものの、「無効」になっていることがわかります。一度、サービス管理ツールを終了し、再び起動して一覧を見ると、「Automation Anywhere Bot Agent」サービスが消えていれば成功です。

ここまで実行できれば、再びBot Agentインストーラを起動すると、エラーが出ずに完了できるのではないかと思われます。

### 3. %TEMP%フォルダーの下のインストーラの削除
Bot Agentインストーラが途中で終了した場合、一時フォルダーの中にはインストーラのごみが実行時毎に残ります。%TEMP%フォルダーの中で「AutomationAnywhereBotAgent.exe」という名前のファイルを検索してみてください。出てくるようなら削除してください。もしくは、一時フォルダーの中のファイルをストレージセンサーでまとめて整理してください。
金融機関のシステム障害に関する分析Power BIレポート

## はじめに
2020/6/30に金融庁から発出されたIT・サイバーセキュリティの取組みに関する3つのレポート（[IT・サイバーセキュリティの取組みに関するレポートの公表について](https://www.fsa.go.jp/news/r1/20200630.html?fbclid=IwAR1_uXW04vaG0YgwwsupgHIgd8fsR5vpVJmI31N56TeOYDfeybrnZkU2ias)）のうち、[3.「金融機関のシステム障害に関する分析レポート」（41ページ）のPDF](https://www.fsa.go.jp/news/r1/20200630-2/system_01.pdf)にある事例をPower BIレポートにしました。

→ [レポートはこちら https://bit.ly/fsa-sys202006](https://bit.ly/fsa-sys202006)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/02aa683e-18e3-63d2-3eba-6b621d6d8c49.png)

### 対象期間
- 2019 年4月～2020年3月

### 本レポートの「はじめに」等より

- 前年より2割増加
- 中でもデジタライゼーションの進展等に伴うサードパーティの障害が増加傾向
- 自己責任原則の下、**創意・工夫**を活かし、**それぞれの規模・特性等**に応じたシステムリスク管理を行う際の、**あくまで参考**とすることを想定
- チェックリストとして用いたりすることは望ましくない

### 新規として上がったのは以下の5カテゴリー

1. **新型コロナウイルス感染症の影響に関する障害** (システム性能・容量面において許容範囲を超え)
2. **サービス継続等に関する障害** (障害に備えた冗長構成が意図どおりに機能しない)
3. **過去の大規模イベントに基づくシステム改修に関する障害** (改元・10 連休対応や消費税率変更といった特殊イベント対応)
4. **自然災害の影響に関する障害** (台風の影響による停電)
5. **データセンター・回線に関する障害** (電源工事の作業誤りや設備の老朽化等)

### 事例集より

- 「ソフトウェア障害」と「管理面・人的要因」による障害が約6割
- 図表1によると以下のような障害事象別割合（全業態）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/f7d9eea5-bd86-b6d8-18c0-8429e9e89013.png)
- 事例に上がっているものは58ケース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/f781734d-7712-dd56-c165-3a5abb80c614.png)

- カテゴリー毎のケース数と、原因と対処の内容を見て、独自に障害事象に分けたものは以下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/e65b1ea4-8708-6856-0a01-02de0ab5ed61.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/48175150-545c-a2d6-7e78-277adad4817c.png)

- 業態別

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/ef9aafe5-aa29-cd8b-05b4-e501de5751f1.png)




### Power BIレポート化の手順概要
1. Acrobat ProでPDFからExcel形式でエキスポート
2. Power BIのPower QueryまたはExcelで必要なデータを抽出、クレンジング
3. Power BI Desktopでビジュアルを作成
3. Word Cloud用に品詞分解したものを取り出し（Robotic Cloud Agent等）
4. Power BI化したビジュアルを見ながら、障害事象を割り当て
5. Power BI Desktopでビジュアルを整える

## おわりに
今回、障害事象は私が独自に仕分けして割り当ててみたものです。見方によっては、これは一義的に「ソフトウェア障害」とするのがよい、というのもあるでしょう。一つに決めかねるものもあるでしょう。多面的な見方がありうることを良ししてい、実質的な再発防止や今後の前向きな取り組みに結びつけたいものですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/7962d8d9-67d7-c8f0-05ae-9422d0c74150.png)
Pythonチュートリアルを参考にxmlファイル読み込み


```data3.xml
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
```

##findall　同じ子ノードすべてを参照する

findやfindallでほしいタグを指定する
以下ではすべてのcountryタグを取得する

```python
from xml.etree import ElementTree


path = 'data3.xml'
tree = ElementTree.parse(path)
root = tree.getroot()
countries = root.findall('country')
for country in countries:
    gdppc = country.find('gdppc')
    print(country.attrib)
    print(gdppc.text)
```

```
{'name': 'Liechtenstein'}
141100
{'name': 'Singapore'}
59900
{'name': 'Panama'}
13600
```

##孫ノードまで取得

for文をネストする。

```python
cnt = 1
for child in root:
    print('---', cnt, '---')
    print(child.tag, child.attrib, child.text)
    for gild in child:
        print(gild.tag, gild.attrib, gild.text)
    cnt += 1
```

```
--- 1 ---
country {'name': 'Liechtenstein'}

rank {} 1
year {} 2008
gdppc {} 141100
neighbor {'name': 'Austria', 'direction': 'E'} None
neighbor {'name': 'Switzerland', 'direction': 'W'} None
--- 2 ---
country {'name': 'Singapore'}

rank {} 4
year {} 2011
gdppc {} 59900
neighbor {'name': 'Malaysia', 'direction': 'N'} None
--- 3 ---
country {'name': 'Panama'}

rank {} 68
year {} 2011
gdppc {} 13600
neighbor {'name': 'Costa Rica', 'direction': 'W'} None
neighbor {'name': 'Colombia', 'direction': 'E'} None
```

##参考URL
https://docs.python.org/ja/3/library/xml.etree.elementtree.html
【Python】7DaysToDieをDiscordから管理したい！ 3/3

#概要
[【Python】7DaysToDieをDiscordから管理したい！ 1/3 (環境構築)](https://qiita.com/Trusted_Dream/items/4f7c3f754651d392bdbf)
[【Python】7DaysToDieをDiscordから管理したい！ 2/3 (Discordから管理できるBOTの作成)](https://qiita.com/Trusted_Dream/items/c7d5187c5e8124cd6f36)
[【Python】7DaysToDieをDiscordから管理したい！ 3/3 (動作チェック)](https://qiita.com/Trusted_Dream/items/a242207b306850f85fe0)

GitHubに保管しました。
https://github.com/Trusted-Dream/7DaysToDie_Launcher

##プログラムの動作確認
それでは[前回](https://qiita.com/Trusted_Dream/items/c7d5187c5e8124cd6f36)に作成したsdtd_start.shを起動してDiscordからコマンドを送ってみましょう。

```terminal
$ cd $HOME/python/discord
$ ./sdtd_start.sh
2020-07-12 17:36:04 --- [29093] kill ok
2020-07-12 17:36:07 --- [29932] start
```
![7days.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672611/39ef5e64-a351-e456-273b-844c46a9eaf5.png)
※ポート変更してありますが、変更しても問題なく動きます。

##今後の予定について
今後はもう少しコマンドを増やしてmod鯖にも切り替え可能にしたりを考えています。
また他に需要がありそうなBOTも増やして自動化してイカに楽して運用するかを考えつつコーディングしていこうと思います。
キャンバスアプリでForms Proコントロールを使ってみる

## Forms Proとは
クイズやアンケートをさくっとつくれる組織向けのアプリです。
Google FormsのMS版です。個人向けはForms無印版があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/489e0227-5657-da66-a439-59a34f77cdc9.png)

分岐ルールで、入力内容に合わせて、質問の内容を変えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/01e6e175-3b81-eab5-9c65-fd56bc954f7c.png)

何も設定しなくとも、回答結果を分析してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/845defb0-948f-44b7-7f10-41570f532f4b.png)

データはCDSに格納されるので、Power BIなどで別の分析にも利用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/b63017e7-b4e8-e283-0edd-660334acca74.png)

CDSエンティティの詳細については、以下Docsを参照してください。
https://docs.microsoft.com/en-us/forms-pro/developer/forms-pro-reference

## キャンバスアプリでForms Proを埋め込む
キャンバスアプリにはForms Proコントロールがあり、アンケートが埋め込めます。(現状、クイズは選択できないっぽい)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/dc7a8c74-06a5-e8a5-911e-3e616993464e.png)

キャンバスアプリから引数を渡せます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/e7975714-42d3-a8a6-ca9d-c4f5b54dfa1f.png)

キャンバスアプリからForms Proに引数を渡す場合、Forms Proにて調査変数を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/a6bef778-b6fa-576e-a6e6-14234c2aefaf.png)

引数のデータはmsfp_surveyresponseエンティティのmsfp_embedcontextparametersフィールドに格納される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/a9640b56-480d-023f-91d0-62ee4d11cfa3.png)

## 活用方法案
- アプリに対してフィードバックが欲しい場合
- CDSのマスタを選択して、Forms Proにて回答してもらいたい場合
    - Forms Proから直接CDSのマスタを参照できないため
    - ただし、調査変数は選択肢などに使用できない

## これからの改善に期待したい点
- Forms Proはソリューションに入れられない
    - テナントが違うと、デプロイできない
    - テナントが同じならば、Forms Proのコピー・移動でデプロイできる

## サンプル
https://github.com/simpliciter11/Power-Platform/tree/master/Power-Apps/FormsProApp_1_0_0_5
**Forms Proがソリューションに入れられないので、インポートしても動かないです**
AWS MediaLive データ転送料金試算例

### 東京リージョンの1GB当たりのデータ転送量
| /月 | USD/GB |
|:--|:--|
| 1GB ~ 10 TB まで | 0.114 |
|  次の 40 TB | 0.089 |
|  次の 100 TB | 0.086 |
| 150 超 | 0.084 |

### 5Mbps、30分の配信を10人が視聴した場合のデータ転送量概算
( 5Mbps ÷ 8 ) × 1800(秒) × 10(人) =  11250MB
11250MB ÷ 1024 = 10.9GB
10.9GB × 0.114 = 1.24
<b>1.24USD
Go のロギングライブラリ "go-logging"

# ロギングについて
プログラムを書いていると、内部の処理で値がどのように変化しているかログを出して確かめたい時があると思います。しかし、 **全ての情報をログに出力しようとするのはあまりにも煩雑になってしまい、本来得たい情報が読み取りづらくなる恐れがあります。**

上記の問題を解決したいため、ログに出力する情報を制御できる仕組みが欲しいです。

Go 言語には [go-logging](https://github.com/op/go-logging) というロギングライブラリがあり、レベル毎のログ出力の制御や出力情報のカスタマイズなどができます。今回はこれについてご紹介したいと思います。

# 使い方紹介

### サンプルコード

```go:main.go
package main

import (
	"os"

	"github.com/op/go-logging"
)

var log = logging.MustGetLogger("example")

// ログの出力フォーマットを定義
var logFmt = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} PID=%{pid} MOD=%{module} PKG=%{shortpkg} %{shortfile} FUNC=%{shortfunc} ▶ %{level:.4s} %{id:03x} %{color:reset} %{message}`,
)

func Backend(format logging.Formatter, level logging.Level) logging.LeveledBackend {
	// ロギングの初期設定
	// ログの出力先は os.Stderr（標準エラー）に設定する。
	backend := logging.NewLogBackend(os.Stderr, "", 0)

	// ログのフォーマットを適用する
	backendFormatter := logging.NewBackendFormatter(backend, format)

	// 出力するログの種類（レベル）を設定
	backendLeveled := logging.AddModuleLevel(backendFormatter)
	backendLeveled.SetLevel(level, "")

	return backendLeveled
}

func main() {
	backend := Backend(logFmt, logging.DEBUG)
	logging.SetBackend(backend)

	log.Debug("debug")
	log.Info("info")
	log.Notice("notice")
	log.Warning("warning")
	log.Error("err")
	log.Critical("crit")
}
```

### 実行結果

```
$ go run main.go
15:25:21.133 PID=15179 MOD=example PKG=main main.go:33 FUNC=main ▶ DEBU 001  debug
15:25:21.133 PID=15179 MOD=example PKG=main main.go:34 FUNC=main ▶ INFO 002  info
15:25:21.133 PID=15179 MOD=example PKG=main main.go:35 FUNC=main ▶ NOTI 003  notice
15:25:21.133 PID=15179 MOD=example PKG=main main.go:36 FUNC=main ▶ WARN 004  warning
15:25:21.133 PID=15179 MOD=example PKG=main main.go:37 FUNC=main ▶ ERRO 005  err
15:25:21.133 PID=15179 MOD=example PKG=main main.go:38 FUNC=main ▶ CRIT 006  crit
```

### フォーマットについて

**logging.Formatter** という interface によって定義します。
サンプルコードで利用したもの以外にも、様々な情報をログに出力することができます。

```
%{id}        一意となるログのID
%{pid}       プロセスID
%{time}      ログ出力のタイムスタンプ
%{level}     ログの種類（レベル）
%{module}    モジュール名（MustGetLogger で指定した文字列）
%{program}   os.Args[0] で取得できる文字列
%{message}   ログのメッセージ
%{longfile}  ログが出力されたファイル名と行数を返す (/a/b/c/d.go:23)
%{shortfile} ログが出力されたファイル名と行数を返す (d.go:23)
%{longpkg}   パッケージ名を出力 (github.com/go-logging)
%{shortpkg}  パッケージ名を出力 (go-logging)
%{longfunc}  関数名を出力 (littleEndian.PutUint32)
%{shortfunc} 関数名を出力 (PutUint32)
%{color}     ログの種類（レベル）毎に色を付与できる
```

### ログレベルの制御について

**SetLevel** によって出力するログのレベルを制御できます。
サンプルコードでは logging.DEBUG を渡していましたが、 logging.ERROR を渡すと **ERROR 以上のログレベルのみを出力するようになります。**

```go:main.go
(省略)
func main() {
	backend := Backend(logFmt, logging.ERROR)
	logging.SetBackend(backend)

	log.Debug("debug") //出力されない
	log.Info("info") //出力されない
	log.Notice("notice") //出力されない
	log.Warning("warning") //出力されない

	log.Error("err")
	log.Critical("crit")
}
```

### 実行結果

```
$ go run main.go
15:48:02.674 PID=15555 MOD=example PKG=main main.go:39 FUNC=main ▶ ERRO 001  err
15:48:02.674 PID=15555 MOD=example PKG=main main.go:40 FUNC=main ▶ CRIT 002  crit
```

# まとめ

[go-logging](https://github.com/op/go-logging) は非常に使いやすいロギングライブラリとなっています。趣味や業務などで Go 言語を利用されている方は是非使ってみてください。
TechAcademyが無料公開している「レスポンシブWebデザイン入門講座」を受講する～第2回～

# アジェンダ
* 文字の装飾
* 文書の装飾

# 文字の装飾
## 文字に線を引く
文字に線を引く場合、以下のように指定する。

```
text-decoration: 値;
```
値には単語を用いる。
単語には以下のようなものがある。

<dl>
  <dt>none</dt>
  <dd>無し</dd>
  <dt>underline</dt>
  <dd>下線を引く</dd>
  <dt>overline</dt>
  <dd>文字の上に線を引く</dd>
  <dt>line-through</dt>
  <dd>打ち消し線を引く</dd>
</dl>
それぞれ、以下のように表示される。
![text-decoration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/c41f597e-a830-1889-dd50-d5699f1a8a03.png)

## 文字に影を付ける
文字に影を付ける場合、以下のように指定する。

```
text-shadow: 横方向のズレ 縦方向のズレ ぼかし幅 影の色;
```
横方向のズレ、縦方向のズレ、ぼかし幅は数値で指定する。
影の色は色で指定する。

以下のように表示される。
![text-shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/faa04f05-93d3-55bb-4276-33de681c51bc.png)

# 文書の装飾
## 一行目にインデントを付ける
一行目にインデントを付ける場合、以下のように指定する。

```
text-indent: 値;
```
値は数値で指定する。

## アルファベットの大文字・小文字のコントロール
アルファベットの大文字小文字をコントロールする場合、以下のように指定する。

```
text-transform: 値;
```
値には単語を用いる。
単語には以下のようなものがある。

<dl>
  <dt>none</dt>
  <dd>通常</dd>
  <dt>capitalize</dt>
  <dd>全ての単語の先頭を大文字で表示する</dd>
  <dt>lowercase</dt>
  <dd>全てを小文字で表示する</dd>
  <dt>uppercase</dt>
  <dd>全てを大文字で表示する</dd>
</dl>
それぞれ、以下のように表示される。
![text-transform.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/4909848a-1471-b006-3c2b-7cb16b3f32d7.png)

# おわりに
今回は装飾に関する内容だった。
おしゃれなWebページを作成するためには必要な内容だ。

## 参考
[2-1 文字の装飾（CSSを使った文字の装飾）](https://www.youtube.com/watch?v=ITiflFSjXR4&list=PLjw-30bsJNVVUTdM-KUqkiVy3uj4fTfLD&index=7)
[2-3 空白などの扱い方について指定する（CSSを使った文字の装飾）](https://www.youtube.com/watch?v=4c60vV50Kbw&list=PLjw-30bsJNVVUTdM-KUqkiVy3uj4fTfLD&index=8)
[2-4 文字に影をつける（CSSを使った文字の装飾）](https://www.youtube.com/watch?v=417mkWBNIDE&list=PLjw-30bsJNVVUTdM-KUqkiVy3uj4fTfLD&index=10)
GitHubによるpushの手順


##GitHubとは 

GitHubはアプリやサービスなどを開発したときのコードをバージョン管理するためのプラットフォームです。

GitHubでソースコードを管理している企業は数多く存在しています。

**・DeNA
・クックパッド
・LINE
・Yahoo!**

などの名だたるメガベンチャーも使用しているらしいです。

####環境

**・AWS Cloud9
・Windows 10
・Ruby2.6.3**


####バージョン管理とは？

バージョン管理はソースコードを記述したファイルを保存・更新することを指します。

####GitHubの機能

簡潔には以下のような機能があります。

**1.ソースコードをリモートリポジトリへプッシュする・・・・・①
2.ソースコードをローカルリポジトリにプルする・・・・・②
3.ファイルの変更履歴を特定の場所まで戻る・・・・・③**


他にも機能がありますがこの記事では上記の①について説明させていただきます。
残りの2つについては他の記事で説明します。


####GitHubの機能①

GitHubでソースコードのバージョン管理を行うためには**まず初めに特定のフォルダをバージョン管理下に置く必要があります。**

**1.ターミナルでバージョン管理をしたいフォルダの直下に移動します。
2.ターミナルで下記のコマンドを入力する。**

```
$ git init
```

このコマンドによりバージョン管理されているフォルダには下記のような`~/フォルダ名 (master)`と表示されます。

![バージョン管理下の状態](
https://i.gyazo.com/f468874d6a5cd0826f62b45d9e1e8efe.png "バージョン管理下の画像")

以上でバージョン管理の状態になりました。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

次に**リモートリポジトリへプッシュするために必要な手順**を説明します。

**1.ターミナルで以下のコマンドを入力してワークツリー⇒インデックスに移動する。**

```
$ git add .
```

このコマンドにより変更があったファイルは全てワークツリー⇒インデックスに移動できる。

＊ワークツリー⇒インデックスに移動したいファイルを指定する場合は`$ git add ファイル名`のコマンドを使用する。


**2.次にターミナルで以下のコマンドを入力してインデックス⇒ローカルリポジトリに移動する。**

```
$ git commit -m "コミットメッセージ"
```

＊コミットメッセージは他者が見ても分かるような記述の仕方にしましょう。

例:　良い例："バリデーションメッセージを日本語表示に変更"

この場合は他者がソースコードを見た時にコードのどの部分を変更したのか分かると思います。

悪い例："コードの追加"

この場合はどの部分を修正して何を表しているのか分からないので他者が見ても一目でわかるような
コミットメッセージを記述しましょう。

**3.次にローカルリポジトリからリモートリポジトリにプッシュする。**

```
$ git remote add origin https://github.com/ユーザー名/first-git.git

$ git push origin master
```

ただし、`$ git remote add origin ~~~ `のコマンドは初めてリモートリポジトリに登録するときに使用するコマンドです。そのため、2回目以降に`push`するときは必要ありません。

**4.上記のコマンドを入力したらGitHubのユーザー名とパスワードを入力が要求されるので入力する。**


以上でリモートリポジトリへのpushは完了です。
オブジェクトが循環参照しているかを検証する方法(ガチめ)

## 循環参照ってなんですか

循環参照(`Circular reference`)は、オブジェクトが子要素として持つオブジェクトが自分自身を持つような状態を指します。(孫でもひ孫でもいいたいことは同じです)

TypeScriptであれば最も簡単な例はこのようなものです。

```typescript
const obj1: any = {};
const obj2: any = {
  obj1
};

obj1.obj2 = obj2;
```

`obj1`の子供に`obj2`というオブジェクトが、そして`obj2`の子供に`obj1`というオブジェクトがあることがわかります。

## JavaScript, TypeScriptで昔からある鉄板の方法

JavaScriptでは組み込みで存在するメソッドを使うことによって一発でそのオブジェクトが循環参照しているかどうかを検証することができます。すでにご存じのかたも多いとは思いますが、そのメソッドとは`JSON.stringify()`です。

`JSON.stringify()`は文字列という**直列化可能**なモノへ変換するために、元のオブジェクトも直列化可能である必要があります。そのため循環参照しているオブジェクトを検出すると`TypeError`を投げて処理を終了します。この例外を`catch`すればそのオブジェクトは循環参照しているといえます。

```typescript
const isCircular = (obj: object): boolean => {
  try {
    JSON.stringify(obj);

    return true;
  }
  catch (err) {
    if (err instanceof TypeError) {
      return false;
    }

    throw err;
  }
};
```

当然ながら、この手法はJavaScript, TypeScriptで可能な方法です。他の言語でも使えるような普遍的な知識として**そのオブジェクトが循環参照しているかどうか**を検証できる方法を今回は紹介します。

## どうやって循環参照を検出するんですか

循環参照を検出するためには、やや煙たがられているオブジェクトの性質を使います。その性質とは**オブジェクトが等しいかどうか**を判定することです。

一般的にオブジェクトを代表するリファレンス型は等値比較ができません。

```typescript
{} === {}
// false
```

これは、リファレンス型のときの等値比較はプリミティブ型のそれとは異なり、指しているオブジェクト(のインスタンス)自身が等しいかどうかを指しているからです。同じキー、プロパティを持っているかどうかの検査ではないというプログラムの初心者が陥りやすい罠でもあります。

### オブジェクトが同一かどうかを検出につかうとどうなるんですか

オブジェクトを再帰的に走査していくときに、コールスタックのようなモノを保持して、その中に同じオブジェクトが現れるかどうかを判定すればよいということになります。

### 成果物

以下が成果物です。

```typescript
export const isCircular = (value: unknown): boolean => {
  return isCircularInternal(value, new WeakSet<object>());
};

const isCircularInternal = (value: unknown, objs: WeakSet<object>): boolean => {
  if (!isObject(value)) {
    return false;
  }
  if (objs.has(value)) {
    return true;
  }

  objs.add(value);

  return Object.keys(value).some((key: string) => {
    return isCircularInternal(value[key], objs);
  });
};

const isObject = (value: unknown): value is {[key: string]: unknown} => {
  if (typeof value === 'object') {
    if (value === null) {
      return false;
    }

    return true;
  }

  return false;
};
```

コツは以下です。

1. `isCircular`は直接処理をせず、オブジェクトの走査をするときの訪問済みオブジェクトを溜める`WeakSet`を確保します
1. オブジェクトに対し再帰的にすでに訪問したオブジェクトがあるかを検証します
1. 訪問していない場合は`WeakSet`に溜めます

### 最後に

この手法はオブジェクトリテラルに限らず、プロトタイプベースのオブジェクト(要するにクラスなど)でも可能です。木を作ったときやグラフを走査するときに同じオブジェクトを参照していないかを検証するときにも使えます。
ShellScriptでディレクトリのみ処理したい

### やりたいこと

指定したディレクトリにある、ディレクトリのリストだけ処理したい

### やること

指定したディレクトリの配下の一覧から、ディレクトリだけ処理を行えるようにします

```bash
#/bin/bash

DIR=/home/hogehoge  # TODO:ディレクトリ名を指定
FILES=${DIR}/*

for FILEPATH in ${FILES}; do
  if [ -d $FILEPATH ] ; then
    DIRNAME=`basename $FILEPATH`
    echo ${FILEPATH}  # フルパス
    echo ${DIRNAME}   # ディレクトリ名
  fi
done
```

### 結果

```bash
/home/hogehoge/20200701
20200701
/home/hogehoge/20200702
20200702
/home/hogehoge/20200703
20200703
```
Docker環境で複数のSQLを一括実行

## 目的
EC-CUBE4のDocker環境で特定ディレクトリ内のSQLファイルすべてをコマンドラインで一括実行したい。

## 方法
1. SQLファイル置き場を作成するため、`docker-compose.yml`に下記のように行を追加する。

    ```docker-compose.yml
    services:
      mysql:
        volumes:
          - ./additional_sql:/home/additional_sql # この行を追加
    ```
1. `docker-compose up -d`する。
1. プロジェクトフォルダ直下に「additional_sql」フォルダが作成されるので、そこに実行させたいSQLファイルを保存する。
1. プロジェクトフォルダ直下に「additional_sql」フォルダ内のSQLファイルを全て実行するシェルスクリプトを作成する。

    ```additional_sql.sh
    #!/usr/bin/env bash

    # additional_sqlフォルダ内の全SQLファイルをEC-CUBEのDBにて実行する。
    for file in ./additional_sql/*.sql
    do
        docker-compose exec mysql bash -c "mysql -u dbuser -psecret eccubedb < /home/${file}"
    done
    ```
1. 下記コマンドラインをプロジェクトフォルダ直下で実行する。

    ```bash
    # WindowsのGit Bashの場合、TTYエラーを避けるためのお約束
    $ exec winpty bash

    # additional_sqlフォルダ内の全SQLファイルを実行するシェルスクリプトを実行
    $ ./additional_sql.sh
    ```

## SQLファイル作成時の注意点
冒頭に`CHARSET utf8;`を記述しないと、日本語が文字化けしてDB登録されてしまう。

## 参考
- https://qiita.com/amanoese/items/7b237e8703c3b4c7f001
- http://taustation.com/mysql-garbled-characters/
Dronecode Devマニュアル抜粋&翻訳-Motor/Servo Checks

#この記事は
Dronecode本家サイトの[Motor/Servo Checks](https://docs.px4.io/master/en/config/motors.html)ページの抜粋・翻訳です。

>※このドキュメントの通りにドローンの機体を組んで、モーターが動作するか確認しようとQGCのMotersというメニューから試してみたのですが、「Motor test command not support」と表示されてダメでした。。
Armすることや、[コマンドからの実行](/sakaeda11/items/017c9ee57ccdbe8cbaf3#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%86%E3%82%B9%E3%83%88)でモータは動くので、何かこのテストツールに問題がかもです？？？



# 参考：QGCのマニュアルにあるMotorsのページの利用手順
https://docs.qgroundcontrol.com/en/SetupView/Motors.html

1. プロペラを外しておきます。
2. もし利用していれば、safety switchを有効化します
3. モータースライダーを有効にするために「Propellers are removed - Enable motor sliders」と書かれているスイッチをスライドします。
4. それぞれのモータのスライダーを調整してスピン方向などを確認します。

# Motor/Servo Checks|モーターやサーボの確認
機体をセットアップしたら、モーターの割当や回転方向、サーボの反応などを確認します。これはQGCを使って行えます。

次のPX4固有の動作に注意してください。

- safety buttonを利用している場合、モーターテストが許可される前にそれを押す必要があります。
- キルスイッチは、モーターをすぐに停止するために引き続き使用できます。
- [COM_MOT_TEST_EN](https://docs.px4.io/master/en/advanced_config/parameter_reference.html#COM_MOT_TEST_EN)というパラメータによって、モータテストを完全に無効化することが出来ます。
- IOを備えたボードでは、MAINピンのみをテストできます。
- シェルからもモーターテストは行なえます。[motor_test](https://dev.px4.io/master/en/middleware/modules_command.html#motortest)

もし一つまたは複数のモーターが正しい方向に回らなかったら、逆回転させる必要がありますが、幾つかの方法があります。

- [DShot](https://docs.px4.io/master/en/peripherals/dshot.html)をサポートしているESCでは、DShotの[コマンド](https://docs.px4.io/master/en/peripherals/dshot.html#commands)で方向を変えられます。
- モータへのケーブルの3つのうち2つを入れ替えます。(どれを変えても良いです。)

> もしバレットコネクタを使わずにモーターと接続している場合は改めてハンダ付けが必要になります。(そんなこともあり、DShotのESCが好まれます)

以下の機体が正しくセットアップ出来ているか、以下を追加で確認しておきます。

1. プロペラを外したまま、マルチコプターの場合は[Stabilizedモード](https://docs.px4.io/master/en/flight_modes/manual_stabilized_mc.html)、固定翼機の場合は[Manualモード](https://docs.px4.io/master/en/flight_modes/manual_fw.html)にして**arm**します。
2. スロットルを少し(車両が自動的にdisarmしないぐらいに)上げ、スロットルにモータが反応するかを確認します。
3. すべてのモーターが最小のスロット値でも動くかを確認します。
4. 車両に補助翼がある場合、ロール/ピッチスティック入力コマンドを出すときに、補助翼が正しい方向に応答しているかどうかを確認します。


# コマンドからのモーターテスト
https://dev.px4.io/v1.9.0/en/middleware/modules_command.html#motortest
にあるように motor_test というコマンドからもモータ動作を確認出来ます。

コマンドは[こちらで教えていただいた](https://discuss.px4.io/t/how-to-access-flight-controller-console-via-usb/17619/4)のですが、QGCのMAVLink Consoleから実行出来ます。
Docker for macの環境でk8sにECRの認証情報を渡すのに苦戦した件

# 概要
Dockerイメージを作成しAWS ECRにイメージを上げたが、K8Sでプルできなかった。
調べたらしっかり認証情報がわたっていなかった。

# 環境
- mac Catalina
- docker for mac
- AWS Cli
    - これがしっかり使える前提です

# 解決手順
デスクトップ右上にあるDockerのマークをクリックしてPreferencesを開く。
そうすると「Include VM in Time Machine backups」というものがあるのでこれをクリックするとしたの、「Securely store Docker logins in macOS keychain」がアクティブになるのでクリックして無効化

その後、（vim -/.docker）を以下のように変更

```json:config.json
"credsStore": "desktop"　#これを削除
```

これで以下のようにコマンドを叩くとECRの認証情報が保存されてK8sでもとってこれる状態となる。

```console
aws ecr get-login-password --region リージョン | docker login --username AWS --password-stdin ECRのエンドポイントのURL
```

その後この認証情報を持ったsecretを以下のコマンドで作れば、ECRからDockerイメージを持ってくることができるようになる。

```console
kubectl create secret generic シークレットの名前 \
        --from-file=.dockerconfigjson=$HOME/.docker/config.json \
        --type=kubernetes.io/dockerconfigjson
```

# 参考資料
- [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)
- [Getting started with Amazon ECR using the AWS CLI](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
- [Cannot unset Preference "Securely store Docker logins in MacOs keychain". Upgrades from previous version fail docker login if preference unset. #3774](https://github.com/docker/for-mac/issues/3774)
- [kubernetesでprivateなdocker hubからpullできるようにする](https://qiita.com/reoring/items/9333f952fccf171cae08)
- [macOSで~/.docker/config.jsonのauthesに認証文字列がない場合の対処](https://qiita.com/reoring/items/a1c229fd895f3c1b43bb)
Windowsでbashシェルスクリプトをダブルクリックで実行する

## 方法1. Git Bashをインストールして.shファイルをダブルクリック。Git Bashの範囲内でbashが実行できる。


## 方法2. WSLのインストールして、下記のようなバッチファイルを作成しダブルクリック。wslの範囲内でbashが実行できる。

### 実行したいシェルを配置する。
```
c:/toos/script/hoge.sh
```

### バッチファイルを作成する。
```run_wsl.bat
wsl bash /mnt/c/tools/script/hoge.sh
```
Android studio でエミュレーターが反応しなくなったときの対処法

###この記事を書く理由

Androidでアプリの作り方を勉強中,あれアプリビルドしても反映されねえって思ったら,
アプリどころかエミュレーター上でボタンもなにも反応しねえ!
ってなったので調べてみた

参考サイト
https://stackoverflow.com/questions/7961856/full-queue-lose-event-in-android-emulator

###実行環境

Ubuntu 18.04
Android Gradle Plugin Version 4.0.0


###対処法

Android studio上の Toolsバー --> AVDManager を選択する

AVDManagerのエラーが発生しているエミュレーター上で右クリックし,Cold Boot Now をクリック

###結果
エミュレーターが正常に作動して,アプリが反映されるようになった