OmniAICreator/Qiita-1.07M huggingface dataset:
Google I/O 2021 フロントエンドまとめ（1/6）〜 Webプラットフォームの話（1/3）: プライバシー関連〜

# Google I/O 2021 フロントエンドまとめ（1/6）〜 Webプラットフォーム最新情報（1/3）: プライバシー関連〜

この記事は、[Google I/O 2021](https://www.google.com/io)で発表されたフロントエンド関連情報の中で個人的に気になったものをまとめたもので、
全6記事中1本目。

## Webプラットフォームの話
[ウェブ プラットフォームの最新情報 @Google I/O 2021](https://events.google.com/io/session/97ea9417-2bba-4383-8eb4-22aee86af034?lng=ja)

### `Attribution Reporting API`っていう新しいAPIを提案したよ。というお話
Google Chromeはリリース以来、サイトごとにプロセスを分離する「サンドボックス」という機能を特徴としてきたが、近年のプライバシー意識の高まりにより、サードパティーCookieを初めとしてユーザを追跡することが忌避されるようになってきた。
そこでユーザを追跡することなく広告の成果（コンバージョン）やそれに至るユーザの行動の貢献度（アトリビューション）を測定する方法として、サイト間でユーザ識別データ（いわゆるトラッキングID）を共有することなく、ブラウザがAPIへ暗号化・匿名化されたレポートを送信する仕組みを作ったよ、Chromeで使えるようになったよ、とのこと。
ちなみに、レポート作成で遅延とノイズが発生することでよりユーザを特定する試みが抑制されるとのことで、これを「差分プライバシー」と呼んでいるらしい。

#### 「サードパーティCookieを廃止する準備を段階的に進めている」←なんだって？！
上述の「`Attribution Reporting API`がChromeで使えるようになった」という話の中でしれっと「サードパーティCookieを廃止する準備を段階的に進めている」という衝撃発言があった。
要は
Google「（Google自身の収益事業でもある）広告において『サードパーティCookie使わないとコンバージョンやアトリビューションが計測できないよね』問題があったけど、それを解決する`Attribution Reporting API`ってのを使えるようにしたんだから、サードパーティCookieとかいう危なっかしいものはもう必ず使わなくても良くなってきてるよね？ね？こっち使お？サードパーティCookieつかうのやめよ？てことでじゃあ、段階的に廃止してくね。」
てことでしょうか？
~~Google「（よ〜し、これでうちらだけはこの先生きのこれる。もしみんながついてこなくても、それはそれでうちらだけが一人勝ちｨ(๑•̀ㅂ•́)و✧）」的な？~~

とりあえずGoogle Chromeで`Attribution Reporting API`が使えるようになったという発表で、 Web標準なったわけでもないまだ「新しい提案」レベルであるため、これによって本当にサードパーティCookieが廃止廃止されると判断するのはまだ早計と考えられる。
しかし、現在Webブラウザの世界シェアにおいて"強い寡占状態"を既に獲得しているChromeであるからこそこれほど強気の発信ができているのも事実であり、今後の成り行きを注視する必要があるかもしれない。

#### 私見
<details>
<summary>（長文＆私見のため、折りたたみ。「そういうのダルい」人は読み飛ばしてください）</summary>
サイト間および特定ベンダによるユーザの追跡はプライバシー保護の観点において健全ではないのは事実で、それを実現しているサードパーティCookieも（広告というWeb業界における重要な収益化手段に関らざるを得ない要素ということから一旦目を背ければ）プライバシー保護の観点において好ましくない技術であることは否定できないと思う。
もちろん、Web収益上の問題を孕まない手段でサードパーティCookieを廃止できるならそれに越したことはなく、そして確かに`Attribution Reporting API`は~~その一つの出口足り得る設計には見受けられる気がした。~~（→[EFF](https://www.eff.org/)テクノロジストである[Bennett Cyphers氏による評価](https://www.eff.org/deeplinks/2019/08/dont-play-googles-privacy-sandbox-1)では「**bad**」とのこと[^1]）
しかし一方で、その提案・推進のしかたにおけるGoogleのやり方には眉をひそめざるを得ず、強い寡占状態を人質にした強引にも見える提案()は、市場経済における「寡占企業によるプライスリーダシップ（価格誘導）」にも似た「技術標準誘導」にも見えなくもない。
もし仮にGoogle Chromeが現在の圧倒的なブラウザシェアを持っていなかったとしても、同様にこのような提案・推進をおこなっていただろうか？
このような進め方は、Web界隈にとって健全だろうか？
「[GoogleによるWeb標準の私物化](https://www.google.com/search?q=%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3+%E5%AF%A1%E5%8D%A0%E5%8C%96+chrome)」の危惧が現実味を帯び始めていはいないか？
~~そういえば、かの有名な「Don't Be Evil」って、もうGoogleの行動規範から外されているそうですね。いまは「Do the Right Thing」ですか、"正しさ"とは誰にとっての正しさですか？その"正しさ"には"「ゴールの」正しさ"だけでなく"「手段の」正しさ"も含まれているのでしょうか？~~  
Webがこれからも健全で素敵な技術・市場でありますように。

[^1]: Bennett Cyphers氏が[`Attribution Reporting API`を「**bad**」と評価](https://www.eff.org/deeplinks/2019/08/dont-play-googles-privacy-sandbox-1)した主な理由は、そのunique IDのフィールド長が64bit（18×10<sup>18</sup>=1800京くらいまでの値を取れる）という、**その気になったらネット上のユーザの行動を追跡できる**であろう十分な大きさとなってしまっているから、とのこと。（比較対象とされたAppleのものの場合、6bit（64までの値しか取れない）である）
</details>

[つづく](https://qiita.com/toshi00ysm/items/30e86f7d9be1443cbde2)
DockerでMySQLコンテナがRestartingになる現象

#発生した事象
```
    Remove MYSQL_USER="root" and use one of the following to control the root user password:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD
```
ログにこんなのが出てステータスはRestartingのまま。

#解決方法
バージョンを固定する。

```
Dockerfile

FROM mysql:5.6
↓
FROM mysql:5.6.XX
```
Couchbase コマンド解説 cbbackup

### cbbackup


#### 概要


実行中のクラスター全体、バケット、または単一ノードをバックアップします。
データは`cbrestore`を使用して復元できます。
ドキュメントをバックアップするだけでなく、インデックス等のメタデータをバックアップすることができます（復元後にインデックスを再構築する必要があります）。

#### インストール先

- Linux: /opt/couchbase/bin/cbbackup
- Windows: C:\Program Files\Couchbase\Server\bin\cbbackup
- Mac OS X: /Applications/Couchbase Server.app/Contents/Resources/couchbase-core/bin/cbbackup


#### コマンド基本構文

```
cbbackup --username <ユーザー名> --password <パスワード> [オプション] <ソースURL> <バックアップ先ディレクトリ>
```


#### バックアップモード

バックアップモードとして、利用可能なオプションは以下の通りです。
バックアップモードは、`-m`　、または`-mode`　オプションにて指定します。

- `full`: フルバックアップを実行します。
- `diff`: 最後の完全バックアップまたは増分バックアップ以降の変更のみをバックアップする差分増分バックアップが実行されます。
- `accu`: 累積増分バックアップが実行されます。これにより、最後の完全バックアップ以降のすべての変更がバックアップされます。

オプションが指定されていない場合、デフォルトで`diff`になります。ただし、特定のバックアップ先ディレクトリに対して、最初に作成されるバックアップは、指定されたモードに関係なく、常にフルバックアップになります。

#### 操作例

最も基本的な操作は、クラスター全体をバックアップすることです。これは、次のコマンドを使用して実行できます。
最初に作成されるバックアップは、指定されたモードに関係なく、常に完全バックアップです。

```
$ cbbackup http://10.112.193.101:8091 ~/backups -u Administrator -p password
```


継続的にバックアップを行うため、新しいバックアップを作成する場合、すべてのデータを再度バックアップする代わりに、最後のバックアップ以降に変更されたデータのみを含む増分バックアップを作成できます。

以下のコマンドは、明示的に増分バックアップを指定しています。

```
$ cbbackup http://10.112.193.101:8091 ~/backups -u Administrator -p password \
  -m diff
```

`beer-sample`バケットのみをバックアップするには、次のコマンドを使用します。

```
$ cbbackup http://10.112.193.101:8091 ~/backups -u Administrator -p password \
  -b　beer-sample
```


バックアップされるデータは、`-k`フラグを使用してドキュメントキーでフィルタリングすることもできます。キーが`KEY：`で始まるドキュメントのみをバックアップするには、次のコマンドを使用できます。`-k`オプションは任意の正規表現を取ります。

```
$ cbbackup http://10.112.193.101:8091 ~/backups -u Administrator -p password \
  -k '^ KEY：.*'
```



ユーザーは、特定のサービスのみをバックアップすることも選択できます。たとえば、データサービスのドキュメントのみをバックアップする場合は、次のように追加オプションを渡すことができます。

```
$ cbbackup http://10.112.193.101:8091〜/ backups -u Administrator -p password \
  -x data_only=1
```
JavaScriptのでifを使った判定処理

#はじめに

JavaScriptのifを学習をしていてRubyとは違った記述などがあったのでアウトプットしていきます。

まずは簡単に記述します。

```.js
//()の中に条件式
if(true) {
  console.log('this is true');
} else {
  console.log('this is false');
}

// this is true
```

tureだった場合は*console.log*で'this is true'か返ってきます。

ここまでは記述の仕方は違えどtrueの時はこれ！falseの時はこれ！rubyの時のニュアンスは一緒だと思いました。

#'==='と'=='の意味

```.js
if(1 == '1') {
  console.log('this is true');
} else {
  console.log('this is false');
}

// this is true
```

数字の**1**文字列の**'1'**があります。
こちらが等しい時はもちろんtrueが返ってきます。

しかし数字と文字列は別の値だからfalseです！と思ったのですが。。。


`this is true`

ええええええ！

人間から見たら1は1だけど文字式だから違うって前に学習しましたよ〜〜！

[MDN](https://developer.mozilla.org/ja/docs/conflicting/Web/JavaScript/Reference/Operators#identity)にちゃんと記載されてました。

>JavaScript には、厳密な比較と型変換の比較の両方があります。厳密な比較 (例: ===) は、オペランドが同じ型で、内容も一致している場合にのみ真になります。もっとよく使用される抽象的な比較 (例: ==) は、比較する前にオペランドを同じ型に変換します。抽象的な関係比較 (例: <=) では、比較前にまずオペランドがプリミティブ型に変換され、それから同じ型に変換されます。


**`==`**は**等価演算子**と言います。

>等価演算子は、2 つのオペランドが同じ型でないならばオペランドを変換して、それから厳密な比較を行います。両方のオペランドがオブジェクトならば、 JavaScript は内部参照を比較するので、オペランドがメモリ内の同じオブジェクトを参照するときに等しくなります。

データの型までは比較されないので1と'1'は等しいとされtrueとなりました。


```.js
if(1 === '1') {
  console.log('this is true');
} else {
  console.log('this is false');
}

// this is false
```

イコールを3つした場合はfalseになりました。

`===`の場合は**厳密等価演算子**と言います。

>厳密等価演算子は、型変換なしでオペランド同士が (上に示した通り) 厳密に等しければ真を返します。

データの型も一緒でなければなりません。
今回は数字と1と文字式の`1`なのでfalseという結果になりました。

#1とtrueの場合

```.js
if(1 == true) {
  console.log('this is true');
} else {
  console.log('this is false');
}

// this is true
```

boolean型のtrueなのになぜtrueとなるのか。

**実はtrueは数字に変換した場合は1になります。** 

実際に数字に変換してみます。

```.js
const num = Number(true);
console.log(num);

// 1

//falseの場合は０です

```

出力結果の通り1になります。

3つの場合は厳密等価演算子となり、型も一緒でなければならないのでfalseになります。
JavaScriptでJavaのorElseと同じ挙動を実装する

# はじめに

JavaScriptでメソッドチェーンを書いた際にundefinedを参照しエラーになることがあるので、JavaのOptionalのorElseの挙動を実装。

```
const hoge = undefined;
//     "errorType": "TypeError",
//     "errorMessage": "Cannot read property 'fuga' of undefined"
//     エラーになる
const fuga = hoge.fuga.fuga;
```

# コード

```
const hoge = undefined;
// undefinedだった場合、空文字が入る。　
const fuga = hoge?.fuga?.fuga || '';
```
|| は前の式がfalse(undefined)だった場合、後ろの値が代入されます。
?.という書き方はオプショナルチェイニングというものです。
>
オプショナルチェイニングoptional chaining演算子 ?. は、接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。 ?. 演算子の機能は . チェーン演算子と似ていますが、参照が nullish (null または undefined) の場合にエラーとなるのではなく、式が短絡され undefined が返されるところが異なります。 関数呼び出しで使用すると、与えられた関数が存在しない場合、 undefined を返します。

# おわりに
JavaScriptでメソッドチェーンで書いた際にundefined参照で落ちるということがなくなり、デフォルト値を返却できるようになります。


# 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining
CakePHP4でトランザクションを使う

# CakePHP4でトランザクションを使う！

```php
use Cake\Datasource\ConnectionManager;
use Cake\Core\Exception\Exception;

$connection = ConnectionManager::get('default');
$connection->begin();

$users = TableRegistry::getTableLocator()->get('users');
$articles = TableRegistry::getTableLocator()->get('articles');

$users->setConnection($connection);
$articles->setConnection($connection);

try {
    $user = $users->newEmptyEntity();
    $user->email = 'hogehoge@hogehoge.com';
    $user->password = 'passpass';
    $users->save($user, ['atomic' => false]);

    $article = $articles->newEmptyEntity();
    $article->user_id = $user->id;
    $article->title = 'タイトル';
    $article->body = '本文';
    $articles->save($article, ['atomic' => false]);

    $connection->commit();
} catch (Exception $e) {
    $connection->rollback();
    throw $e;
}
```
遠隔でJetsonの管理を実現する方法(2)

#はじめに
[前回の記事](https://qiita.com/Koharu1993/items/f20b4f9db0b8c8a7daa8)では、[Allxon DMS](https://dms.allxon.com/next/signup)を利用して、
遠隔でNVIDIA Jetsonの管理方法を簡単なセットアップ手順をご紹介しましたが、
今回はその管理機能を更に詳しくご説明していきたいと思います。
ぜひ最後まで見て頂けたら嬉しいです！

#Allxon DMSについて
Allxon Device Management Solutions (Allxon DMS) は、
多数のデバイスを容易に一元管理できるサービスです。
SIer企業及びサービスプロバイダ企業に対して、
シンプルにナビゲートしやすいデバイス管理サービスを提供します。
事業部をまたぐ多用なデバイス管理すらもひとつのAllxonアカウントから実行できるため、
デバイス上の問題解決のみならず、人件費と運用コストの大幅削減にも実現可能です。

#管理機能のご紹介
[1.OSの再起動](#1osの再起動)
[2.デバイスログの収集](#2デバイスログの収集)
[3.コマンドの送信](#3コマンドの送信)
[4.アラートの通知](#4アラートの通知)
[5.スクリーンショットの取得](#5スクリーンショットの取得)

#1.OSの再起動
デバイス画面の「操作」メニューから該当デバイスに対するリモート操作を実行することができます。
デバイスに対して主導によりOS再起動を行います。
(定期的に自動で再起動させるスケジュール設定も可能です。)
![未命名.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509678/af33c57a-4b85-565c-1fbb-8aaad0443b43.png)

#2.デバイスログの収集
デバイスのイベントログを取得できる機能です。
「デバイスプロフィール」画面からダウンロードすることができます。
![擷取.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509678/cea8ea52-ec57-bce1-f37e-022d0a1cd66c.png)


#3.コマンドの送信
コマンドのコードを入力しますとコマンドが送信される機能です、
「コマンド詳細」のウィンドウにアクションの実行状況が表示されます。
結果をダウンロードするには、「詳細を見る」をクリックします。
![擷取.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509678/b0635da2-1948-66a5-1f7e-643a16ebc655.png)


#4.アラートの通知
管理中のデバイスに異常が生じたり、不正な接続や操作を検知、
または事前に設定した監視項目がしきい値を超過した場合に
担当者に対してプッシュアラートを送信する機能です。
メールやラインなどを設定可能です。
![擷取.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509678/0347b44f-b3bb-d2ba-8258-1835cf1f8ab3.png)

#5.スクリーンショットの取得
Allxon DMSエージェントをダウンロードした該当デバイスの画面に、
遠隔でスクリーンショットを取得することができます。
![擷取.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509678/f11c6bdd-141e-7c8a-8396-520374cc9a74.png)

#終わりに
さて、皆様はAllxon DMSの基本機能について更にご理解頂けますでしょうか。
本当にとても簡単で便利ですよね！
では次回にデバイスのログ収集について詳しくご紹介していきたいと思います。
毎週火曜日に記事を更新致しますので、
ご意見または感想がございましたら、ぜひコメント欄に書いて頂けると嬉しいです！
【React-Native】プロジェクトを作成

> 私は日本就職を目指して、勉強している韓国人大学生です。
> もし、内容の中で間違った表現や言葉などがあれば、書き込みをしてください。

## 【React-Native】の目次
1. [RNのインストール](https://qiita.com/JeongJaeSoon/items/dcc15830015a22cb1e1e)
2. [プロジェクトを作成](https://qiita.com/JeongJaeSoon/items/9c470cb6068126844a3c)
3. [アプリ内メッセージを表示する](https://qiita.com/JeongJaeSoon/items/64d94d4ed8f7c5183125)
4. [タッチイベント、ボタン、スクロール](https://qiita.com/JeongJaeSoon/items/032ef2afe5e3ce6cda0b)

## 新しいプロジェクト作成
- `react-native init`コマンドでプロジェクトを作成

  ```bash
  $ react-native init my_first_app
  ```
## Simulator 実行

###iOS Simulator
  
- 実行方法

  ```bash
  // 別のターミナルで実行
  $ npm start
  $ react-native run-ios
  ```

- `command-R`を押して、リロード
- `command-D`を押して、デバッグ実行
- `--simulator`オプションを書いて、仮想デバイスを設定

    ```
    $ react-native run-ios --simulator="iPhone 8 Plus"
    ```

###Android Emulator
  
- 実行方法

  ```bash
  $ npm start
  // Android Studion - AVD Managar - 仮想デバイスを実行
  $ react-native run-android
  ```

- `R`を2回早く押して、リロード
- `command-M`を押して、デバッグ実行
- `--simulator`オプションを書いて、仮想デバイスを設定
【React】React クイズ!!

## はじめに

いきなりですがクイズです！！
React.js初心者向けのクイズを3問考えました。
クイズは、Reactの関数コンポーネントを用いたstateとライフサイクルに関する問題です。

クイズの答えは、記事の最後に記載しています。

## 第1問: 以下の様なコードを実行した場合、どのような順番に実行されるでしょうか？
A〜Cの回答で答えよ。

```javascript
import React, {useState, useEffect} from 'react'

const Button = () => {

  const [count, setCount] = useState(0)

  useEffect(()=> {
    // ①
    console.log("①")

    return ()=> {
    // ②
      console.log("②")
    }
  }, [])

  return (
    // ③
    <div>
      {count}
    </div>
  )
}

export default Button
```

回答:
A. ① → ② → ③
B. ③ → ① → ②
C. ② → ③ → ①


## 第2問: 以下の様なコードがあった場合、countの値はいくつになるでしょうか？

```javascript
import React, {useState, useEffect} from 'react'

const Button = () => {

  const [count, setCount] = useState(0)

  useEffect(()=> {

    setCount(count + 100)
    setCount(count + 1000)
    setCount(count + 10000)
    setCount(count + 10000)
    setCount(count + 100000)
    setCount(count + 1000000)

    return ()=> {
      console.log("clean up")
    }
  }, [])

  return(
    <></>
  )
}

export default Button
```

回答:
A. 1111100
B. 100
C. 1000000
D. 1121100

## 第3問: 以下の様なコードがあった場合、初回マウント時の正しい実行順序を答えなさい。

```javascript
import React, {useState, useEffect} from 'react'

const Button = () => {

  const [count1, setCount1] = useState(0)
  const [count2, setCount2] = useState(0)
  const [count3, setCount3] = useState(0)


  useEffect(()=> {
    // ①
    console.log("update count1")
  }, [count1])

  useEffect(()=> {
    // ②
    console.log("update count3")
  }, [count3])

  useEffect(()=> {
    // ③
    console.log("update")
    return ()=> {
      console.log("clear")
    }
  }, [])

  useEffect(()=> {
    // ④
    console.log("update count2")
  }, [count2])

  return(
    <></>
  )
}

export default Button
```

回答:
A. ③ → ① → ④ → ②
B. ① → ② → ③ → ④
C. ③ → ① → ② → ④
D. ④ → ③ → ② → ①


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





## 問題の答え

- 第1問の答え: B. ( ③がclassにおけるrender()、①がcomponent Did Mount()、②がcomponent will unmount()に該当する。)

- 第2問の答え: C. 

- 第3問の答え: B. コードは上から順番に実行されます。component Did Mount()後のアップデートでは、①→②→④の順に実行されます。
Socket.IOとは

Socket.IOは、Node.js サーバーとクライアントの間のリアルタイム通信を提供するライブラリです。

Node.jsサーバー用とブラウザ用のJavascriptクライアントライブラリがあります。サーバーとクライアントどちらにもインストールされていると双方向通信が可能になります。データはさまざまな形式で送信できますが、JSONが最もシンプルです。

基本的には、利用可能な場合はWebSocketを使用しますが、Flash Socket、AJAX Long Polling、AJAX MultipartStreamなどの他のテクノロジーにフォールバックする準備ができています。これにより、WebSocketがサポートされていないコンテキストでSocket.IOを使用できるようになります。

##WebSocketとの違い
- WebSocketとは異なり、Socket.IOを使用すると、接続されているすべてのクライアントにメッセージをブロードキャストできます。

- WebSocketは接続が切れると自動的に再接続されることはないが、Socket.IOは自動的に再接続する。

- Socket.IOは使用するのが簡単。

- ブラウザへの要求は、WebSocketの場合は、①HTMLページのリクエストと②WebSocketへの接続のみであるが、Socket.IOの場合は、①HTMLページのリクエストと②WebSocketへの接続、③Socket.IOクライアントライブラリ、④Ajax等のリクエストとなっている（最近の全てのブラウザはWebSocketをサポートしているため、ネットワークトラフィックの無駄）。


##どのようなサービスに向いているのか？
- チャットアプリ
- ビデオ会議アプリ
- 通信ゲーム

>マルチプレイヤーで、2人以上のユーザーが同時にプレイできるゲームを開発していると仮定します。その場合、さまざまな理由でHTTPまたはHTTPS呼び出しを行うことはありません。その理由のひとつは、パケットサイズが大きいことと、これらの呼び出しが非常に遅いことです。このようなシナリオでは、ソケットなどのライブラリを使用して、サーバーとの間でデータを送受信します。ソケットは非常に高速で、必要なデータパケットのみを送信できます。HTTPプログラミングを使用すると、サーバーとリアルタイムでやり取りするマルチプレイヤーゲームやアプリを作成することはできません。

https://stackoverflow.com/questions/18587104/what-is-the-major-scenario-to-use-socket-io

##結局Socket.IOを使うべきか？
Socket.IOは、クライアントとサーバーの間に双方向のソケット接続をセットアップしたい開発者にとって優れたツールであり、使用するのは比較的簡単です。

しかし、限られた数のユーザー向けにリアルタイムアプリを使い始めたい場合は、Socket.IOが適しています。ただ、スケールが大きくなると、Socket.IOは非同期ネットワークライブラリ上に構築されているため、サーバーに負荷をかけます。

また、最初の接続がWebSocketに比べて長いです。これは、最初にロングポーリングとxhrポーリングを使用して接続を確立し、次に可能な場合はWebSocketにアップグレードするためです。

以上を踏まえると、単純なリアルタイムアプリケーションの構築を開始するには、socket.ioが適していると思いますが、スケーラブルなサービスを開発する際には他の手段を考慮したほうが良いのかもしれません。

ちなみに代替手段として、[WS](https://www.npmjs.com/package/ws)や[SockJS](https://www.npmjs.com/package/sockjs)などのパッケージを選択した人も増えているみたいです。

##参照
https://itnext.io/differences-between-websockets-and-socket-io-a9e5fa29d3dc

https://ably.com/topic/socketio
WinActor のマイルール その1

備忘録として記述

## フローイメージ図

![{131DE933-013A-4115-A596-454E5FB9175F}.png.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195544/e9c7c058-6d3e-ef2f-72d7-d27eb0a0d9c3.jpeg)

各ロボットで変数名を一定にしておく

### 1.システムからダウンロードしたファイルを保存する段階

- ZIP：DL_ZIPファイルフルパス
- CSV：DL_CSVファイルフルパス
- Excel：DL_Excelファイルフルパス

### 2.ZIPファイルを解凍する段階

- 解凍先フォルダパス
- 解凍先内ファイルフルパス

### 3.通常運用に供するために名前を変更する段階

- CSV：CSVファイルフルパス
- Excel：Excelファイルフルパス
Settings Sync　の設定方法

https://qiita.com/tomokei5634/items/22128efe306ce9bc5682#%E5%AF%84%E3%82%8A%E9%81%93%E3%81%AA%E8%A3%9C%E8%B6%B3cloudsttings%E3%81%8C%E3%81%AA%E3%81%84%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

この記事の手順だと、いろいろ混乱するので正しいやり方を書きます。


# やり方

1. setttings syncをインストール
2. shift+ctrl+p > sync: アップロードアップデートの設定
3. login with github をクリックしてブラウザが立ち上がるのでgithubへログイン
この時点で、githubのgistにcloudSettingsが作成されているので、あとは、アクセストークンをgithubで作成する

4. githubのsettings>Developer settings>generate new token > gistをチェック  > アクセストークンをコピー
5. shift+ctrl+p > sync: 高度なオプション > 設定を開く
6. global settings アクセストークンへさっきのコピーを貼り付け
6. shift+ctrl+u 設定をアップロードできるか確認
Jupyter Notebookで思いもよらない罠にハマった話

Pythonで否定が`!`じゃないことを忘れていて書いた俺も悪いんだけどさ。さすがに、こんなんなると思わないじゃないですか。

# 問題: Jupyter Notebookでの実行結果を予想せよ

```py
a = !True
if a:
    print(a)
```

# 答え:

`['/bin/bash: 行 1: True: コマンドが見つかりません']`

**(ノ｀´）ノミ┻┻**
Dockerコンテナ内でIPアドレスを解決したい場合の代替コマンド

みなさん、Dockerは使ってますか？Dockerをドカドカ使っていると、

> 「社内のHTTP APIを呼びたいのに、なぜかホスト名をIPアドレスに解決できない」

> 「本番環境のではなく開発環境のHTTP APIを呼んでしまっている（っぽい）」

なんて、ことが稀によく発生します。

一方で、定石に従ってDockerイメージを作っていると、

> 「Dockerイメージには最小限のバイナリしか入れていないので `host`も`nslookup` も使えない。だからホスト名がどう解決されているかも分からない。」

なんてことも起きがち。

そこで、最小限のコンテナに `docker exec` した時にホスト名解決を（雑に）確認できるコマンドを紹介します。


# getent

glibc に含まれるコマンドです。

```shell
$ getent hosts qiita.com
2406:da14:add:902:68c3:7e8d:a9c:949e qiita.com
2406:da14:add:900:8bc:d6f3:591c:eb91 qiita.com
2406:da14:add:901:3a2b:2b27:a25f:7360 qiita.com
```

# Ruby 

```shell
$ ruby -rresolv -e 'puts Resolv.getaddress ARGV[0]' qiita.com
54.92.41.140
```

# Python

```shell
$ python3 -c 'import sys, socket; print(socket.gethostbyname(sys.argv[1]))' qiita.com
54.250.97.111h
```
Linux　コマンド　備忘録

# よく使うコマンド
今後追加予定。
## clear
表示している内容を削除
` $ clear`

## &
バックグランドで実行
`  コマンド　&`

## Ctrl+C
実行中のプログラムを強制終了

## Ctrl+Z
実行中のプログラムを中断

## ls
ファイルやディレクトリ名の表示

`　$ ls [オプション] [ファイル（ディレクトリ）]`

|オプション|説明|
|--|--|
|-a|隠しファイルを含めた全てを表示|
|-l|最終更新日時、オーナ、パーミッションなどを表示|
|-t|最終更新時間に従い最終更新された順に表示|
|-r|逆順にソートして表示|
|-F|分類記号を付与して表示|

## cp
ファイルのコピー

` $ cp [オプション]　コピー元ファイル　コピー先ファイル`

|オプション|説明|
|--|--|
|-i|同名のファイルが存在する場合は上書きをするかユーザに確認をする|
|-f|ユーザに確認せず全ての上書きを行う|
|-r|ディレクトリごとコピー|
|-p|日付、フラグなどのファイル情報を出来る限りそのままコピー|
|-u|同名のファイルが存在する場合、コピー元ファイルがコピー先よりも新しい時だけコピーする|
|-a|コピー元ファイルの構成と属性を可能な限り保持してコピー|

## mv
ファイルの移動

` $　mv 移動元ファイル　移動先ファイル`

|オプション|説明|
|--|--|
|-i|同名のファイルが存在する場合は上書きするかユーザに確認する|
|-f|ユーザに確認せずに全ての上書きを行う|
|-u|同名のファイルが存在する場合、移動元ファイツが移動先ファイルよりも新しい時だけ移動|
|-v|移動元ファイルと移動先や変更後ファイルの名前を表示|
|-b|ファイルを上書きする場合、ファイル名の末尾に”~”がついたファイル名でバックアップを作成|

## rm
ファイルの削除

` $ rm [オプション]　ファイル`

|オプション|説明|
|--|--|
|-i|削除をするかユーザに確認する|
|-f|ユーザに確認せずに全て削除|
|-r|ディレクトリごと削除|

## pwd
現在のディレクトリを表示

` $ pwd`

## cd
ディレクトリを変更

` $　cd 移動先のディレクトリ名`

## mkdir
ファイルの作成

` $ mkdir ディレクトリ名`

|オプション|説明|
|--|--|
|-p|指定したディレクトリのパスが存在しない場合、その中間ディレクトリも含め新たにディレクトリを作成|

## rmdir
ディレクトリの削除

` $ rmdir ディレクトリ名`

## cat
ファイルの内容を表示

` $ cat [オプション][ファイル名]`

|オプション|説明|
|--|--|
|-n|表示する内容に行番号をつける|
|-b|表示する内容に行番号をつける（空行をカウントしない）|

## find
ファイル検索
指定したパスの配下にあるファイル名を検索

` $ find パス　-name ファイル名`

## diff
ファイル比較

` $ diff [オプション]ファイル1 ファイル2`

|オプション|説明|
|--|--|
|-c|context diff形式（更新時刻などの差分も表示）|
|-u|unified diff形式（削除された行に-,追加された行に+をつけて表示）|

# パイプ
コマンド1|コマンド2...と書くことで複数コマンドを組み合わせて使える。
コマンド1によってターミナルに表示される文字に対して、コマンド2を実行する。

```
$ grep 文字列　ファイル名　|　文字列　ファイル名
```
grep は文字列を指定したファイルから見つけて該当する行を表示するコマンド
FacebookがBigBox VRを買収


Facebookがまたもゲームスタジオを買収したみたいですね。
最近Facebookの買収が続いているけど、やはりゲーム業界・VRは伸びるのかな？

買収の価格は公表されていないものの、クランチベースによるとBigBoxは６５０万ドル（日本円では7億円強）の資金調達をしていたので、おそらく数十億から数百億の買収になっているかもしれませんね。

個人的にFacebookはオキュラスをどんどん強化していきたいという考えはあると思いますし、VRの世界でも飛び抜けるのではないかと思っています。

オキュラスを私は持っていないですし、VR自体触れたことがないのですが、次のFacebookオキュラスの新しい物が出たら触れてみたいですね。

ちなみにクランチベースとは、世界最大のベンチャー企業のデータベースみたいな感じです。


これからのゲーム業界の発展が楽しみですね〜
[SQL]すっきりわかるSQL入門のまとめ①

#はじめに
昨日から「[スッキリわかるSQL入門](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB222%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1%E6%B8%85%E5%96%AC/dp/4295005096)」を参考に学び始めたのでこちらにまとめていきます。

以前書いた記事と似ている部分がありますが、復習と捉えていただければと思います。

**※こちらは教材ではないので、ストーリー性のないまとまり方をしてます。
※参考図書を丸写しするなどはしておりません。**
#基本の4大命令

SQLにおける基本的な4大命令文

- SELECT

```SQL
SELECT カラム名 FROM テーブル名 WHERE 条件~~
```
- INSERT

```SQL
INSERT INTO テーブル名(カラム1,カラム2....) VALUES(値1,値2....)
```

- UPDATE

```SQL
UPDATE テーブル名 SET カラム＝値 WHERE 条件〜〜〜
```

- DELETE

```SQL
DELETE FROM テーブル名
```

#検索結果の加工

WHEREのような修飾の中で、SELECTにしかつけられないものを紹介します。

####DISTINCT

結果表内で内容が重複しているものを除く

```SQL
SELECT DISTINCT カラム　FROM テーブル名
```

####ORDER BY

並び替えを行う。デフォルトでは昇順になっていて指定は省略できるが、降順にする際は指定が必要。また、複数の列を基準に並び替えを行うことも可能。
なお、列番号による指定も可能。


```SQL
SELECT カラム名　FROM テーブル
WHERE ~~
ORDER BY カラム名 DESC（ASC）
```

####OFFSET -FETCH

先頭から○行目を起点に、△行だけ表示する。LIMITとよく似ている。


```SQL
SELECT * FROM テーブル名
WHERE ~
ORDER BY ~
OFFSET 先頭から除外する行数 ROWS
FETCH NEXT 表示する行数 ROWS ONLY
```

###集合演算子

検索結果の加工では集合演算子なるものがある。

####UNION

和集合を求める。

```SQL
SELECT ~~
UNION (ALL)
SELECT ~~
ORDER BY ~~
```

####EXCEPT

差集合を求める。


```SQL
SELECT ~~~
EXCEPT
SELECT ~~~
```

####INTERSECT

積集合を求める。


```SQL
SELECT ~~
INTERRSECT
SELECT ~~
```

#演算子と関数

##CASE演算子

これはもうRubyでもC言語でもさんざんぱらやってきたので説明は割愛。
記述例は以下。


```SQL
SELECT 費目, 出金額,
   CASE 費目 WHEN '家賃' THEN '固定費'
   　　　　　 WHEN '光熱費' THEN '固定費'
　　　　　　　 ELSE '変動費'
　　END AS 出費の分類
FROM 家計簿
```

```SQL
SELECT 費目,入金額,
   CASE WHEN 入金額 < 10000 THEN '仕送り'
        WHEN 入金額 < 20000 THEN 'バイト代'
　　　　　ELSE `一時的な収入`
　　END AS 収入ジャンル
FROM 家計簿
```

##関数

####LENGTH関数

文字列の長さを返す。

```SQL
LENGTH(引数)
```

####TRIM

対象文字列の左右の空白を削除

```SQL
TRIM(文字列)
```

####REPLACE

置換する

```SQL
REPLACE(置換対象文字列(カラムとか),置換前の文字列,置換後の文字列)
```

####SUBSTRING

文字の抽出。

```SQL
SUBSTRING(対象文字列,抽出開始位置,抽出終了位置)
```

####CONCAT

文字列を連結する関数

```SQL
CONCAT(文字列,文字列)
```

####ROUND

指定桁で四捨五入

```SQL
ROUND(数値、有効桁数)
--有効桁数は正の場合は少数部分の桁数、負の場合は整数桁数
```

####TRUNC

指定桁で切り捨てる

```SQL
TRUNC(数値、有効桁数)
```

####POWER

べき乗する

```SQL
POWER(数値、何乗するかを指定する数値)
```

####CURRENT_DATE
現在の日付を得る関数で、現在の時刻を得たい場合は、CURRENT_TIME関数を使用する。

####COALESCE関数

最初に登場するNULLでない値を返す。これについては、以下が分かりやすい。
書体コードがもともと割り振られており、一部のレコードではそれが欠損してNULLとなっている。
二行目のコアレス関数では、欠損がなければそのままの値を返し、欠損（NULL）していれば1を返す仕組みとなっている。

```SQL
SELECT 受注日, 受注ID, 文字数,
       CASE COALESCE(書体コード, '1')
           WHEN '1' THEN 'ブロック体'
           WHEN '2' THEN '筆記体'
           WHEN '3' THEN '草書体'
  END AS 書体名,
  FROM 受注
 ORDER BY 受注日, 受注ID
```

#おわり

かなりざっくりまとめました。
引き続き学習を進めていきます。
ActiveHashを使用する上での命名規則

## 注意点

ActiveHashを使用する上で個人的に沼ったところを書き起こします。

### マイグレーションファイルは○○_idで記述する

```db/migrate/2021********_create_items.rb
class CreateItems < ActiveRecord::Migration[6.0]
  def change
    create_table :items do |t|
      t.string :name, null: false
      t.text :info, null: false
      t.integer :category_id, null: false
      t.integer :status_id, null: false
      t.integer :fee_status_id, null: false
      t.integer :prefecture_id, null: false
      t.integer :schedule_delivery_id, null: false
      t.integer :price, null: false
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
  end
end
```

こんな感じで、idと記述します。

### モデル名はマイグレーションファイルで記述した○○にする

これが個人的にめっちゃ沼ってしまった。
特に考えずに、例えばfee_status_idであればモデル名をfee.rbとかにしてました。

ちゃんとfee_status.rbでモデルを作成しましょう。

###　紐付け先のモデルには○○で記述する

今回はitemモデルにfee_statusモデルが紐づいているので、

```app/models/item.rb
belongs_to :fee_status
```

と記述します。

あまり考えずに適当に名前つけてたら、変なところでハマってしまった....
Can't resolve image into URL: to_model delegated to attachment, but attachment is nilの解決

indexメソッドを使って一覧表示しようとしたときのエラーでした。

[![Image from Gyazo](https://i.gyazo.com/71b3a61bffe4375f1e6691b58ecc40f1.png)](https://gyazo.com/71b3a61bffe4375f1e6691b58ecc40f1)

文章を訳すと画像をURLに変換できなかった、モデルと紐づけられているが、nilだよって感じですかね。

要するにitem.imageがnilなんです。

### 1モデルの紐付けを見直す

```app/models/item.rb
class Item < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :user
  has_one_attached :image
```

という感じで確かに紐付けしてる。

### 2画像がない投稿がある

今回はこっちでした。

Sequel Proで見てみると、itemの投稿は8個あったのに対して、画像は6個しかなかったんですね。

ということは2個は画像が紐づけられてないってことで、該当のレコードを削除して解決。
【kotlin】高階関数

#■高階関数とは
引数として関数を使う
戻り値として関数を返す
こういった関数を高階関数と呼ぶ。

高階関数の一例
▼forEachメソッド：配列の要素を一つづつ取り出す。
引数に関数を渡すには 「：：関数名」と言うようにする。

``` kotlin
fun a(num: Int) {
 println(num)
}

val arr = arraOf(1,2,3,4)
//引数に関数を渡している。
arr.forEach(::a)
//結果: 1,2,3,4
```

####■高階関数の引数に渡される関数(上記ではaメソッド)

▼問題
引数に渡されるためだけに使われるケースが多い
無駄になる。

▼解決法
匿名関数を使う
匿名関数の書き方ラムダ式

■ラムダ式

``` kotlin
{引数　-> 関数の本体(処理)}
```

■ラムダ式　：具体的に
引数として作ってたaメソッドがなくなっている。
引数にラムダ式で直接関数を作っている。

``` kotlin
//匿名関数を使った場合
val arr = arraOf(1,2,3,4)
//直接引数に関数を書いているこれが匿名関数　無駄がなくなる。
arr.forEach({num: Int -> printin(num)})
```

####■ラムダ式：省略した色々な書き方
▼型推論　引数のnumにIntの型を指定していたが入る型がわかっている場合は省ける。

``` kotlin
val arr = arraOf(1,2,3,4)
//:Intを省いている。
arr.forEach({num -> printin(num)})
```

▼高階関数の最後の引数がラムダ式ならラムダ式を高階関数のカッコの外に出せる。

``` kotlin
val arr = arraOf(1,2,3,4)
//()の外に書いている。
arr.forEach(){num -> printin(num)}
```

▼高階関数の引数がラムダしきならもはや()を省ける

``` kotlin
val arr = arraOf(1,2,3,4)
//()を省いている。
arr.forEach {num -> printin(num)}
```

▼ラムダ式の引数の部分が一つなら省いて関数の処理で渡していた引数をitとして受け取る。

``` kotlin
val arr = arraOf(1,2,3,4)
//引数を省き 関数の処理で渡していた引数numをitとして定義できる。
arr.forEach {printin(it)}
```
Vimを使いこなしてみたい

<h2>Vimを使うまでの流れ</h2>
VScodeの拡張機能でVimを入れてみたが、めちゃめちゃ慣れずに恐怖を覚えるほどである。
トラックボールのマウスを使うイメージに似ている。。

<ol>
　<li>チートシートをプリントする</li>
  <li>YouTubeで初心者向け動画を見る</li>
  <li>チュートリアルサイトを見ながら手を動かす</li>
  <li>実務でも使ってみる</li>
　<li>さらに修行する</li>
　<li>Vimを自分なりにカスタマイズしてみる</li>

</ol>

<h2>チートシート</h2>

https://namaraii.com/files/vim-cheatsheet.pdf

<h2>YouTubeで初心者向け動画を見る</h2>
https://www.youtube.com/watch?v=2iVxqaK7lsk

<h2>チュートリアルサイトを見ながら手を動かす</h2>
http://mattn.kaoriya.net/software/vim/20110902125512.htm
Google Analytics 360とGoogle BigQueryの連携 ~Qiita3分クッキング~

## はじめに
日○テレビのあの番組は本当に3分で料理が作れてるのでしょうか。
本記事ではそれに対抗して3分以内に**Google Analytics 360とGoogle BigQueryの連携**を行う手順をご紹介します。

## 前提条件
- Google Analytics 360でエクスポートするプロパティの変更権限をアカウントが持っていること
- BigQueryの権限がアカウントに付与されていること
- 上記２つの権限を持つアカウントで操作すること

## まず、データセットを作りましょう

![bq_ga_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/cc15c192-1268-afd5-9c6b-eba151e0e838.png)

一番はじめに行うのは、BigQuery側のデータセットを作ることです。
実はGAのデータエクスポート時にデータセットは自動で作成されるのですが、
困ったことに**リージョンがUSで作成されしまいます**。

他のテーブルとJOINを行う際にはJOIN先が同一リージョン内である必要がある為、asia-northeast1に作っておくほうが取り回しがよいと言えるでしょう。

データセットの名称をGAのビューIDと同じにすることで、
GAとBigQueryの連携時に自動的に作成したデータセットへデータが挿入されます。
なので、リージョンを「asia-northeast1」にしてビューIDを名称にデータセットを作ることで、USリージョンのデータセット作成を避けられます。

## GA側の設定

① まず、左のメニューバーにある「管理」を押下します。

![bq_ga_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/9ebc1e6c-bf1f-8dd9-ecf4-b05a8fd4f370.png)

② プロパティメニュー内の「すべての商品」を押下します。

![bq_ga_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/b20d48ad-4846-a922-3aae-92d1c0ddf10c.png)

③ 連携先の中から「BigQuery」を探し、「BigQueryをリンク」を押下します。

![bq_ga_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/a2aa8c87-7b2d-95ea-edf8-c2013aee004c.png)

④
入力欄にGCPのプロジェクトIDを入力します。
この際、プロジェクトIDが存在していたとしても使用しているGoogleアカウントにBigQueryのパーミッションが無いと画像のようにエラーが表示されます。

![bq_ga_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/19586863-d615-ca15-422b-3008221610a1.png)

⑤
エクスポートするビューを選択します。
BigQueryへエクスポートする**ビューは1つしか選べません**ので、ご注意ください。

![bq_ga_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/cf898041-f17d-7742-8c65-7bb25956478b.png)

⑥
リクエストの確認で「送信」を押下し、完了です。
データ量によりますが、1日くらい待っていると連絡先で設定したメアドにエクスポート完了メールが届きます。


## 最後に
連携設定するだけなら3分ですが、BigQueryにデータが貯まるまでは結構時間かかります(^_^;)

3分で連携設定出来た方居ましたら、出来たよコメントのほうお待ちしておりま〜す！
OpenCV4(python)の動画取り込みと関数，引数の備忘録

#はじめに
pythonでopencvを扱う際に動画ファイルの取り扱いと引数の役割を忘れそうになるのでメモ
今回は非常にシンプルな動画出力を記述。
#実行環境
OS: Windous10
python 3.7.2
opencv-python 4.2
#動画の抽出サンプルコード
~~~python
import cv2

capture = cv2.VideoCapture("動画ファイルパス")

while True:
    retval, image = capture.read()
    cv2.imshow("表示ウインド名称", image)

    if waitKey(10) == 27:
        break

cv2.destroyAllWindows()

capture.released()
~~~

`retval`は真偽値を返す(imageのデータが存在しなくなったときにFalseを返します)
`image`は画像データのndarray配列を返します。１ループ目では1フレーム目の配列というようにループ番号に対応したフレームの配列を返します。

#各種引数について
`cv2.VideoCapture()`
動画を指定して取り込みます。第1引数はファイルパスで第2引数はビデオ処理メカニズムの指定でデフォルトはcv2.CAP_ANYです。
`cv2.VideoCapture.read()`
引数なし。動画データの1フレームを読み込みます。戻り値はタプルで画像配列と画像配列の有無を表す真偽値を返します。
`cv2.imshow()`
与えられた画像配列を指定したウィンドで表示する。第１引数には表示するウィンドの名前，第２引数には表示する画像の配列を指定。
`waitKey()`
ここで特筆する内容ではないが引数で待ち時間を設定できる。（単位は(msec)である。）
==27の記述はASCIIコードで指定されており27はEscキーに当たる。つまりEscキーを押下すると分岐に入りループを抜ける。
`cv2.destroyAllWindows()`
引数なし。すべてのウィンドを閉じます。
#参照
OpenCV公式
https://docs.opencv.org/4.5.2/d8/dfe/classcv_1_1VideoCapture.html
nasmの作法 その6

#概要

nasmの作法、調べてみた。
printfで%d使ってみた。

#makefileを書く。

```
test6.exe: test6.obj
    link.exe /OUT:test6.exe test6.obj msvcrt.lib
test6.obj: test6.asm
    nasm.exe -fwin32 test6.asm


```

#サンプルコード

```

global _main
extern _printf
section .text

_main:
	PUSH 	EBP
	MOV 	EBP, ESP
	MOV 	EAX, 55
	PUSH	EAX
	PUSH 	fmt
	CALL 	_printf
	MOV 	EAX, 2
	MOV 	ESP, EBP
	POP 	EBP
	RET

section .data

fmt:
	db "(no %d)", 0


```

以上。
STM32F103C8でWS2812Bを光らせる。 (Mbed)


x Mbed NUCLEO-F103RB Mbed2 リビジョン172

目的
GPIOのテスト

BluePill F103C8

説明
WS2812Bの接続ピンは、A7です。

参考


https://www.aitendo.com/product/13348



```c++


#include "mbed.h"

//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767 303
//RawSerial pc(PA_2, PA_3); //010
//Serial pc(PA_9, PA_10); // tx, rx 103

DigitalOut myled(PA_7);
                  //     65432109876543210
int on1  = GPIOA->ODR | 0b0000000010000000;
int off1 = GPIOA->ODR & 0b1111111101111111;

int l[90]; //max30 led

void bit_on1();
void bit_off1();

//             12345678   12345678   12345678   12345678
int b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
             0b00001000,0b00000100,0b00000010,0b00000001, };

int ws_led(int num1)
{
    int on_off;

    //__disable_irq(); // disable interrupt
    //__enable_irq(); // enable interrupt

    //GPIO bkup
    //int g_bk  = GPIOA->ODR;


    for(int ii=0;ii<num1;ii++){
        //pc.printf("  -%d\t%d\r\n",ii,l[ii]); //303
        
        //8ビット分送る
        for(int jj=0;jj<8;jj++){
            //pc.printf("  -%d\r\n",jj); //103
            
            on_off = l[ii] & b8[jj];
        
            if( on_off == 0 ){
                //ビットが0
                //pc.printf("0"); //103
                bit_off1();
            } else {
                //ビットが1 
                //pc.printf("1"); //103
                bit_on1();
            }//endif
        
        }//for 8bit
        
        
    }//for max30byt

    //__disable_irq(); // disable interrupt
    //__enable_irq(); // enable interrupt

    //GPIO bkup
    //GPIOA->ODR = g_bk;

    return(0);
}

//メイン
int main() {
    
    //pc.printf("\r\n103\r\n"); //103
    GPIOA->ODR = off1;
    wait_ms(1);

    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

    l[0] = 31;
    l[1] = 32;
    l[2] = 33;

    ws_led(3);

    while(1){}

} //main

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){
   //0.3us 800khz
        
        DWT->CYCCNT = 0;

        GPIOA->ODR = on1;
        
        while (DWT->CYCCNT < 17L){ 
         //a++;
        } ;
        
        GPIOA->ODR = off1;

        while (DWT->CYCCNT < 70L){ 
         //a++;
        } ;
                
}//bit_off1


// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz
        
        DWT->CYCCNT = 0;

        GPIOA->ODR = on1;
        
        while (DWT->CYCCNT < 47L){ 
         //a++;
        } ;
        
        GPIOA->ODR = off1;

        while (DWT->CYCCNT < 70L){ 
         //a++;
        } ;
                
}//bit_on1





```

![dwtsssss2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fe5fb6ad-a08a-c4a8-93cf-9542ae2d15bd.jpeg)
nasmの作法 その5

#概要

nasmの作法、調べてみた。
printfで%s使ってみた。

#makefileを書く。

```
test5.exe: test5.obj
    link.exe /OUT:test5.exe test5.obj msvcrt.lib
test5.obj: test5.asm
    nasm.exe -fwin32 test5.asm


```

#サンプルコード

```
global _main
extern _printf
section .text

_main:
	PUSH 	EBP
	MOV 	EBP, ESP
	PUSH	name
	PUSH 	fmt
	CALL 	_printf
	MOV 	EAX, 2
	MOV 	ESP, EBP
	POP 	EBP
	RET

section .data

name:
	db "Ohisama", 0
fmt:
	db "My name is %s", 0


```

以上。
[Rails] テストコードでFakerを使う

## はじめに
前回はテストコードでFactoryBotの導入と使い方をアウトプットさせていただきました。
今回は似たような感じで、テストコードでよく使用されるであろう、値をランダムに生成してくれる**Faker**の導入と使い方を説明できればと思います。よろしくお願いします。

説明に使用しているソースコードやファイルは前回の続きです。

## Fakerとは
メールアドレスや人名、パスワードなど、様々な意図に応じた値を生成してくれます。なぜ、このランダムな値が必要になるかは、複数のテストを行う際に、一意性の値などは、意図せず弾かれてしまう可能性があるからです。
Fakerは毎回ランダムに値を生成してくれるのでその心配がなくなります。


## Fakerを導入
FactoryBot同様、FakerもGemfileのgroup :development, :test doに記述します。気をつける点ですね。

```Ruby:Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'
end
```

からのbundle install

```terminal:ターミナル
% bundle install
```

これで導入完了です。

コンソールから試してみましょう。rails cでコンソールを起動させます。

```terminal:ターミナル
[1] pry(main)> Faker::Name.initials(number: 2)
=> "TJ"
[2] pry(main)> Faker::Internet.free_email
=> "ruthanne_thompson@gmail.com"
[3] pry(main)> Faker::Internet.password(min_length: 6)
=> "O5y0Ru"
```

このように毎回ランダムに生成してくれます。
早速Fakerの記述をしていきます。

前回使用したspec/factories/users.rbの記述を変更します。

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {Faker::Name.initials(number: 2)}
    email                 {Faker::Internet.free_email}
    password              {Faker::Internet.password(min_length: 6)}
    password_confirmation {password}
  end
end
```

これで完了です。前回と同じようにテストを実行しても変わらず成功するはずです。

## おまけ
Fakerの公式GitHubを見ていたら、本当に様々なランダムな値を作れるみたいで面白かったので少し遊んでました。例えば下記をみてください

```terminal:ターミナル
[1] pry(main)> Faker::JapaneseMedia::DragonBall.character
=> "Super Saiyan Goten"
[2] pry(main)> Faker::JapaneseMedia::DragonBall.character
=> "Raditz"
[3] pry(main)> Faker::JapaneseMedia::DragonBall.character
=> "Goten"
[4] pry(main)> Faker::JapaneseMedia::DragonBall.character
=> "Demon King Piccolo"
```

ドラゴンボールのキャラクターの名前をランダムで生成してくれます笑

こんなのはどうでしょうか

```terminal:ターミナル
[1] pry(main)> Faker::JapaneseMedia::StudioGhibli.movie
=> "Porco Rosso"
[2] pry(main)> Faker::JapaneseMedia::StudioGhibli.movie
=> "The Cat Returns"
[3] pry(main)> Faker::JapaneseMedia::StudioGhibli.movie
=> "Porco Rosso"
[4] pry(main)> Faker::JapaneseMedia::StudioGhibli.movie
=> "Castle in the Sky"
```

さすがジブリ！Fakerでランダムに生成できます
でも、英語表記だとなんだか馴染みがなくてわからない。。。
Porco Rossoは紅の豚ですね
The Cat Rerurnsは猫の恩返しでしょうか、なんか違う気が、、、
Castle in the Skyはラピュタですかね笑

最後にポケモン

```terminal:ターミナル
[1] pry(main)> Faker::Games::Pokemon.name
=> "ホウオウ"
[2] pry(main)> Faker::Games::Pokemon.name
=> "シェルダー"
[3] pry(main)> Faker::Games::Pokemon.name
=> "ケンタロス"
[4] pry(main)> Faker::Games::Pokemon.name
=> "マリル"
[5] pry(main)> Faker::Games::Pokemon.name
=> "ハネッコ"
```

まさかの日本語で返ってきました笑
一発目、ホウオウが出たのなんか嬉しかったです。ガチャみたい

こちらのFakerの公式GitHubのREADMEに色々あるのでみて見てください。結構面白いですよ。
https://github.com/faker-ruby/faker
zshでプロセス完了しました と出てしまうの解決する

#結論
.zshrc　このファイルに変な記述があります。
それを消しましょう。

.zshrcはログイン時に読み込まれるファイルで、これに変なんかいてると、進まないです。

rc と書いているファイルは基本Run Commandの略なのでそういう感じの役割だそうです。
Androidのログレベル

##Androidのログレベル

Androidのログレベルを上から重要順に表にしました。

| ログレベル | 内容 | 対応メソッド |
|:-:|:-:|:-:|
|Assert   |開発者にとって絶対に発生してはいけない問題に関するメッセージ   | wtf()  |
|Error   |エラーを引き起こした問題に関するメッセージ   |e()   |
|Warn   |エラーとはいえない潜在的問題に関するメッセージ   |w()   |
|Info   |通常の使用で発生するメッセージ   |i()   |
|Debug   |詳細なメッセージ。製品版アプリでも出力される   |d()   |
|Verbose   |詳細なメッセージ。製品版アプリでも出力されない   |v()   |

Logクラスのメソッドについては、公式を参考にしてみてください。[公式リンク](https://developer.android.com/reference/android/util/Log)
STM32F103C8とクロックカウンターでGPIOで800khz(1.25us)を作る


x Mbed NUCLEO-F103RB Mbed2 リビジョン172

目的
ある意味タイマーのテスト

64Mhz(64,000khz)/800khz=80カウント

70カウントで実測789kHzだった。


資料


https://www.aitendo.com/product/13348



```c++

#include "mbed.h"

//Serial pc(SERIAL_TX, SERIAL_RX); //767
//RawSerial pc(PA_2, PA_3); //010
Serial pc(PA_9, PA_10); // tx, rx 103

DigitalOut myled(PA_7);
                  //     65432109876543210
int on1  = GPIOA->ODR | 0b0000000010000000;
int off1 = GPIOA->ODR & 0b1111111101111111;

int main()
{
    pc.printf("\r\n103\r\n"); //767

    GPIOA->ODR = off1;
    wait_ms(1);

    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

    pc.printf("1.25us\r\n"); //767
    while(1){
        
        DWT->CYCCNT = 0;
//        uint32_t startTime = DWT->CYCCNT;

        GPIOA->ODR = on1;
        
        while (DWT->CYCCNT < 35L){ 
         //a++;
        } ;
        
        GPIOA->ODR = off1;

        while (DWT->CYCCNT < 70L){ 
         //a++;
        } ;
                
//        uint32_t time = DWT->CYCCNT;

//        pc.printf("%d\r\n",time-startTime); //767

//        //1秒待つ
//        wait_ms(1000);
    }//while

}//main

//容量削減
//void error(const char* format, ...){}



```
AWS認定アカウントを統合する（メールアドレスを変更する）

会社のAWS認定アカウントにある資格情報を、退社したため自分のAWS認定アカウントに移行したい場合、AWS認定アカウントの統合を申請する必要があります。

その場合、以下の手順で統合できます。

1. 移行先のAmazon.co.jpアカウントを作成
1. https://support.aws.amazon.com/#/contacts/aws-training ←ここから申請
1. 個人情報を埋めて、以下のように問い合わせ内容を選択![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283351/34ca9f48-edc2-fae0-306f-aec65ca9ab90.png)
1. すると勝手に本文が生成されるので、以下のように内容を埋めて送信  
   - Use Case: I am no longer an employee of the old company and would like to merge my accounts.（会社辞めたのでアカウントをマージしてねって意味）
   - All email addresses you may have used in our system: 作成したすべてのAWS認定アカウントのメールアドレスを列挙する
   - The email address you would like to keep on file: 移行先のメールアドレスを記載
1. しばらく待つと「このアカウントに統合するけど確認してくれ。OKなら統合しちゃよ」とメールが来るので、移行先のアカウントが正しいメールアドレスか確認する
1. 確認したら「Confirmed. Please proceed with account merge.」的な内容でサポートに返信する、これにて完了
1. サポートから「マージしたよ！」とメールが来る。
1. あとは移行先のAWS認定アカウントに資格情報が移行されているかを確認する

ちなみにAPNのアカウントIDとかいらない。それと「いついつ退職するんだけど」的なことを話すと、「退職してからもう一回申請して！」と言われるので、タイミングや文言はしっかりしましょう。

誰かの役に立てれば幸いです。

**Thanks.**
【kotlin】データクラス

#■データクラス
処理を持たないデータだけを保持するクラス

classの前にdataをつける
{}はいらない処理を持たないので(書く事もできる。)
コンストラクタで変数を持たせる。
定数だけを持たせるクラスになる。

``` kotlin
 data class Hoge(val name: String, val age: Int)
```

####■データクラスを定義する条件
●コンストラクタが1つ以上の引数を持つ
●コンストラクタの引数は全てvar/valを付与してプロパティの宣言とする。
●abstrct/open/sealed/innerにすることはできない。

####■equalsメソッド
同値性のチェック
違うインスタンス同士でコンストラクタの値が同じ
中身のnum の変数は違う
この条件でもコンストラクタの値が同じならequalsメソッドでtrueになる。


``` kotlin
data class Hoge(var name:String = "") {
 var num:Int = 0
}

val a = Hoge("マイケル")
a.num = 40
val b = Hoge("マイケル")
b.num = 50

println(a == b) //結果：true
```

####■toStringメソッド
▼文字列表現
println関数を使ったら暗黙的に呼び出される。

▼データクラスのオブジェクトを文字列化すると
「データクラス名(プロパティ＝値)」
というように出力される。

つまりprintinでデータクラスを定義すると文字列化され
「データクラス名(プロパティ＝値)」
というように出力される。


``` kotlin
data class Hoge(var name:String = "") {
 var num:Int = 0
}

val a = Hoge("マイケル")
a.num = 40
//コンストラクタがIntでも同じ
println(a) //結果 : Hoge(name=マイケル)
```
equalsメソッドとtoStringメソッドもコンストラクタで定義された値のみを
対象としている。

■データクラスに定義されたメソッドは
　コンストラクタで定義されたプロパティのみ対象にしている。

####■componentN(分割代入)

プロパティの値を個々の変数に分解する。

```　kotlin
val a = Hoge("マイケル","所長","28")
val (name,job,age) = a

//結果
name=マイケル
job=所長
age=28
```

内部的には以下のようになっている
componennt1等の数字の部分は引数の順番になっている。

``` kotlin
val a = Hoge("マイケル","所長","28")
val name = a.component1()
val job = a.component2()
val age = a.component3()
```
データクラスにはcomponentNが実装されている。
分割代入が可能

``` kotlin
data class(val name:String, val job:String, val age:Int)
val a = Hoge("マイケル","所長","28")
val (name,job,age) = a
printin(age) //28
```

####■copy（オブジェクトの複製）
特定のプロパティの値だけを変更してコピーしている。

``` kotlin
data class(val name:String, val job:String, val age:Int)
val a = Hoge("マイケル","所長","28")
//特定のプロパティの値だけを変更している。
val b = a.copy(age=40)
println(b)
//結果: Hoge(name=マイケル,job=所長,age=40)
```
VirtualBoxを使用して，Ubuntu20.04の仮想マシンを作る

#環境
- VirtualBox 6.1
- Ubuntu 20.04


#VirtualBoxのインストール

https://www.virtualbox.org/

上記サイトよりダウンロード
今回は，Windows10上にインストールするため，Windows用のファイルをダウンロードする
実行し，手順に沿ってインストール




#VirtualBox上で仮想マシンの作成

https://jp.ubuntu.com/download

上記サイトより，Ubuntu20.04のisoファイルをダウンロード
(私は，Desktopを使わないので，Ubuntu Serverをダウンロード)

VirtualBoxを起動し，新規ボタンをクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/26b13749-b1f0-373b-8ee0-b75018ea0ce0.png" width=60%>

次に仮想マシンの名前とタイプ，バージョンを選択する．
今回は
- 名前 : 任意
- タイプ : Linux
- バージョン : Ubuntu(64-bit)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/7615bc81-02bc-77dd-91fc-bea54650c46a.png" width=60%>

次にメモリの割り当て，余裕があれば16GBくらいあると良い

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/a85684e6-d7a0-f93a-b550-d3cc750d6690.png" width=60%>

次に仮想ハードディスクの作成
1. 仮想ハードディスクを作成するを選択
2. VDIを選択
3. 可変サイズを選択
4. ハードディスクサイズを選択 (学習用のデータに合わせて余裕をもって)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/313c4ef7-9cdb-e59e-4578-23f5249dbb29.png" width=60%>

最後に設定からネットワークを選択し，割り当てをブリッジアダプターに変更

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/51c567cc-6c93-fe83-6620-0ffeeb415376.png" width=60%>


#仮想マシンへのUbuntuのインストール

先ほど作成した仮想マシンを起動し，起動ハードディスクに
ダウンロードしておいたisoファイルを選択し，起動ボタンを押す．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/8bc25485-9096-0236-054a-02ee5e26c013.png" width=60%>

起動後，
1. 言語はEnglishを選択
2. KeyboardレイアウトはJapaneseを選択
3. ネットワークはデフォルト
4. Proxy Adressは空白
5. Mirror Adressはデフォルト
6. Strage Layoutはデフォルト
7. FILE SYSTEMはデフォルト
8. Profile Setupには，自分の情報とスーパーユーザーの権限を持たせるアカウントとパスワードを入力
9. SSH Setupは，Install OpenSSH severに☑を付ける(spaceで付く)
10. Feature Server Snapsでは，何も☑しない

インストール後，再起動を行う．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/1d349b8f-0ec5-0663-c400-1531109bf551.png" width=60%>

先ほど作成したアカウントで，ログインできることを確認し，OpenSSH Serverを起動
IPアドレスを確認し，puttyなどのターミナルでログインできることを確認

```
$ sudo /etc/init.d/ssh start
$ ip a
```
TypeScriptでCheckBoxの値を取得

# 使い方

Typescriptで、チェックボックスの値を取得して分岐処理したいときに使います。
そのまんまタイトルですね。

# 問題

もともと、ドロワーナビゲーションをゼロイチ実装しているとき、
クリックされたら隠す処理を入れるのが目的でした。

そこで、書いたのが下記のコードです。
チェックが入っていたら、チェックを外します。

```ts
const navinput = document.getElementById("input[type='checkbox']#nav-input");

if (navinput && navinput.checked) {
  navinput.checked = false;
}
```

`npm start`するとエラーが出ました。

```posh:terminal
Property 'checked' does not exist on type 'HTMLElement'.  TS2339
```

# チェックボックス全部

チェックボックスがチェックされている数だけ、「やー」って言いたい場合の書き方です。

```ts:typescript
const allCheckBoxes = document.querySelectorAll("input[type='checkbox']") as NodeListOf<HTMLInputElement>;
allCheckBoxes.forEach(checkBox => {
  if(checkBox && checkBox.checked) {
    console.log('yeah!')
  }
});
```

# チェックボックス１個

あらかじめ、チェックボックスが１個しかないことが分かっているとします。
そのチェックボックスがチェック済みの時、「やー」って言いたい場合の書き方です。

```ts:typescript
const CheckBox = document.querySelector("input[type='checkbox']") as HTMLInputElement;
if(checkBox && checkBox.checked) {
  console.log('yeah!')
}
```

# チェックボックス ハイグレード

たまには高ランクのチェックボックスが生息しているかもしれません。
そんなときの呼び方も見ておきましょう。
名前は「`className=steelbox`」とします。
それらがチェックされている数だけ、「やー」って言いたい場合の書き方です。

```ts:typescript
const allCheckBoxes = document.querySelectorAll("input[type='checkbox'].steelbox") as NodeListOf<HTMLInputElement>;
allCheckBoxes.forEach(checkBox => {
  if(checkBox && checkBox.checked) {
    console.log('yeah!')
  }
});
```

# チェックボックス ネームド

なんか強そうですね。名前を持つチェックボックスを鑑定するときの呼び出し方です。
名前は「`id=pandora`」とします。
そのチェックボックスがチェック済みの時、「やー」って言いたい場合の書き方です。

```ts:typescript
const CheckBox = document.querySelector("input[type='checkbox']#pandora") as HTMLInputElement;

if(checkBox && checkBox.checked) {
  console.log('yeah!')
}
```

# まとめ

みなさん、やり方はチェックできましたか？

「やー」

**Excelsior!**
Thinreportsのアップグレードに際して注意する点

対象バージョン：Thinreports 0.11

元々メモ書きで残していたものに若干の追記修正を行っただけなので一部表現がおかしくなっているかもしれません

# アップグレード
Thinreports自体のアップグレードはGemを更新するだけで可能
ただ、テンプレートファイルについても同様にアップグレードを行う必要がある

テンプレートファイルのアップグレード方法はバージョンを上げたエディタで開き直す
**この時、一気に最新バージョンのエディタで開こうとするとそもそもファイル自体開くことができない
一つ一つバージョンを上げて確認しないと上手くいかないので要注意**

```
Thinreportsのバージョンが0.7 <= 0.8のThinreports Editorで開いてバージョンアップ
↓
Thinreportsのバージョンが0.8 <= 0.9のThinreports Editorで開いてバージョンアップ
↓
Thinreportsのバージョンが0.9 <= 0.11のThinreports Editorで開いてバージョンアップ
```

# バージョンアップに伴う修正部分

## 帳票の作成
0.7系での書き方は0.11系では以下のように変換できる

```
reports_path = File.join(Rails.root, 'app', 'reports')

# 帳票の作成
reports = Thinreports::Report.generate do |report|
  ~
end
# あるいは
report = Thinreports::Report.new layout: File.join(reports_path, 'test.tlf')

# generate時のレイアウト指定
report.use_layout File.join(reports_path, 'test.tlf'), default: true

# 新しいページの作成
report.start_new_page do |page|
  ~
end

# ページを作成するたびに実行されるcallback
report.on_page_create do |page|
  ~
end
```
`Report.new`で帳票の作成を行う場合、処理完了後に`report.generate`をしないと`send_file`などでファイル送信しても正しくファイルが読み込まれないため注意

## callback

eventsが廃止されているため、該当部分を置き換える作業も必要となる

```
events.on :page_create do |e|
  if e.page.layout.id == :test_id
    e.page.list(:details).add_row do
      (1..10).each do |cnt|
        item("test_#{cnt}").hide
      end

↓

report.on_page_create do |page|
  if page.layout.id == :test_id
      page.list(:details).add_row do |row|
        (1..10).each do |cnt|
          row.item("test_{cnt}").hide
        end
```
`events`部分はすべて必要なくなり、代わりに`item`で選択する際に`row.`指定が必要となった

## ページ番号について

* item(:hogehoge).value(hoge)
  * itemはテンプレートファイルに記載した変数指定
  * valueは変数に挿入する値のことで、"hoge"などで直接文字列を挿入することも可能

```
report.on_page_create do |page|
 page.item(:page).value(page.no)
end
```

## ヘッダ・フッタについて

* list(:hogehoge) do |list|
  * リスト表⽰された変数に順番に値を⼊れる
  * リスト表⽰は⾏で区切られた表形式のようなもの
* on_footer_insert
  * リストの最後に挿⼊される合計等に値を挿⼊する際に使⽤するもの

```
page.list(:details) do |list|
 list.on_footer_insert do |footer|
 footer.values total_count: user.size,
 price: price, total_price: total_price
 end
end
```

また、以下のようにlambda式を用いることで一括でデータを入れることも可能

```
report_header_value = lambda do |page|
  page.values date_start date_st,
              date_end: data_ed,
              section: section,
              name: user.name,
              title: "HOGE"
end
```
lambda式で入れられたデータは`report_header_value.call(page)`のように記述することで呼び出すことができる

# 参考
[Thinreport - Github](https://github.com/thinreports/thinreports-generator)
jestで同じファイル内でfunctionがfunctionを呼ぶ時にどうやってstubするか？

# 問題

```ts:utils.ts
function a() {
  return "a"
}

function b() {
  return a()
}

export { a, b }
```

例えばこういう風に`b()`が`a()`を呼ぶような場合、

```ts:utils.test.ts
import {a, b} from "./utils"

jest.mock("./utils", () => {
  const original = jest.requireActual("./utils");
  return {
    ...original,
    a: jest.fn().mockReturnValue("modified a")
  };
});

describe("utils", () => {
  it("sholuld use mocked a()", () => {
    expect(b()).toEqual("modified a")
    expect(a).toHaveBeenCalledTimes(1)
  });
});
```

こうやっても`expect(b()).toEqual("modified a")`でpassしない。


```ts
import * as utils from "./utils"
jest.spyOn(utils, 'a').mockImplementation(jest.fn().mockReturnValue("modified a"));

...
```

こうしても駄目。

どちらも`b()`はmockされていない`utils.ts`内の`a()`を呼ぶことになる。

# 解決

https://stackoverflow.com/a/47976589/1227960

```ts:utils.ts
import * as utils from "./utils"  // 自分自身をimport 
            // import名は.test側と一致する必要はない

function a() {
  return "a"
}

function b() {
  return utils.a() // importしたものから呼び出す
}

export { a, b }
```



```ts:utils.test.ts
import * as utils from "./utils"

jest
  .spyOn(utils, "a")
  .mockImplementation(jest.fn().mockReturnValue("modified a"))

describe("utils", () => {
  it("sholuld use mocked a()", () => {
    expect(b()).toEqual("modified a")
    expect(a).toHaveBeenCalledTimes(1)
  });
});
```
Windows10 Home で Docker Desktop の Error response from daemon のエラー対応

####Windows10 Home で Docker Desktop の Error response from daemon のエラー対応####
***
####症状####
しばらくWSL と VS Code& Remote WSLでサーバソフトの開発をしていましたが、諸事情でDocker Desktopに開発環境を移行することになりました。
ところが以前は、動作確認までしていたDocker Desktop で下記のエラーが発生して動かなくなっていました。

Error response from daemon: open \\\\\.\\pipe\\docker\_engine\_linux: The system cannot find the file specified\.

文面を粗く解釈すると、メッセージパイプが出来ないのでは？と考え試行錯誤。
いろいろと、ググっても解決策には、ほど遠い感じでした。

下記のリンクでも同様の症状が発生している方がいらっしゃるようです。
（再起動しなさいとか再インストールをしなさいとか）
<https://github.com/docker/for-win/issues/4495>

####調査方法####
たまたま、**WSL**のコンソールで、**wsl \-l \-v** しつつ **docker images** していたら、エラーログを吐いてくれました。
（エビデンスは、消失しましたが）開発チームに**issues**は、投げてあります。
コンソールの状況を見ると、リリース後、**docker-desktop** と **docker-desktop-data** を更新しようとした後、問題が起こるようです。
（確かにコンソールに**Installing**の文字が表示されていました。）
（送付したログには、c:\\workspace\\なんちゃらのメッセージがあり、存在しないWorkspsceをアクセスしようとし、例外を起こしているようでした。

####解決方法####
以下に従って、工場出荷状態に戻すことで、回避。
https://docs.docker.jp/docker-for-windows/troubleshoot.html
抜本的には、開発チームにお願いするしかないですが。。。
gitは、使っているものの開発者間のソースコードの依存関係が崩れているとかかなあ。（自信は、ないですけど）

####蛇足####
初投稿なので、不手際がありましたら、お手柔らかに。