OmniAICreator/Qiita-1.07M huggingface dataset:
whereメソッドで複数条件指定してみた。（boolean真偽値とintegerの比較条件)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/3f3e1bcc-d106-20b7-ee69-f65d5504e9c0.png)

## はじめに

Whereメソッドで複数条件で事前にフィルターにかけて、
**`ransack`**に渡すことをしたく調べたけれどひとつは**boolean型の真偽値**、ひとつは**integer型の値を比較**するand検索が載っている記事がなかったので、色々試してできたので書いておきます。

## Whereメソッドの使い方
**基本的なWhereメソッドの使い方はこう**

```ruby:Whereメソッド基本形
モデル名.where(カラム名: 条件)

# nameカラムから「yamada_kun」という文字が入っているレコードを全て取得
User.where(name: "yamada_kun")
```
これで`yamada_kun`のレコードが取り出せます。
<br>
**複数条件の基本形はこう（ANDでの検索）**

```ruby:複数条件(AND)
モデル名.where(カラム名: 条件 ,  カラム名: 条件)
#または
モデル名.where(カラム名: 条件).where(カラム名: 条件)

# nameカラムから「yamada_kun」と「ageが20」が入っているレコードを全て取得
User.where(name: "yamada_kun" , age: 20)

User.where(name: "yamada_kun").where(age: 20)
```
<br>
**比較するWhereメソッドの書き方はこう**

```ruby:Whereメソッド（比較）
モデル名.where("カラム名 > ?" , 数字 )

# idが10以上のレコードを全て取得
User.where("id > ?", 10)
```

## boolean型とinteger型でAND検索
それではこの基本形と比較して条件を定義してやる方法を組み合わせてやってみましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/d061ce78-7d5d-b82b-abf3-f970f7cb1b3c.png)

<br>

[![Image from Gyazo](https://i.gyazo.com/8b5ec35de0f2283f9cd41ded482462e6.png)](https://gyazo.com/8b5ec35de0f2283f9cd41ded482462e6)
<br>
あれ、エラーになりました・・・。

できない、できない、できないと色々と試してみてできたのがこちら。

```ruby:booleanとinteger（比較）でAND検索
モデル名.where("カラム名 条件 and  カラム名 > 数字")

# nameがyamadakunでidが10以上のレコードを全て取得
User.where("name= "yamada_kun" and id > 10)
```

ちなみに僕がransackを使ってやったコードがこちら

```ruby
@q = Item.where("onlist = true and stock >=  1").ransack(params[:q])
```
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/cb407cff-3545-19a1-49e8-991e35e83c81.png)

<br>

みなさんの探し物が見つかりますように!

> 参考サイト

- [Pikawaka　whereメソッドを使って欲しいデータの取得をしよう！](https://pikawaka.com/rails/where#where%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9)
- [SamuraiEngineerBlog　スマートに検索！Railsのwhere使い方まとめ！](https://www.sejuku.net/blog/13363)
grid-template-areasを使いこなす

# 概要

グリッドレイアウトのcssのgrid-template-areasを使っていきます！


## 今回作成するレイアウト

![_Users_abekouhei_Desktop_grid_index.html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/c9723827-9abb-46ef-83bd-1e19fe64665a.png)

こんな感じのレイアウトを作成していきます！

サイドバーがあるようなよく見るレイアウトになっています。

こちらはgridシステムを活用したgrid-template-areasを使用することで簡単に実装することができます！！


## grid-template-areasとは？

```html
 <section class="container">
    <div class="item1">1</div>
    <div class="item2">2</div>
    <div class="item3">3</div>
    <div class="item4">4</div>
    <div class="item5">5</div>
  </section>
```

```css
.grid-container {
  display: grid;
　　　　grid-template-areas: "item1 item2"
    "item3 item2"
    "item3 item4"
    "item3 ."
    "item5 .";
}
```

このように子の親要素にdisplay: gridを設定するとgridレイアウトの準備が整います。
grid-template-areasの使い方としてはエリアを追加していくイメージです。

"item1 item2"となっている部分に関しては左カラムにitem1, 右カラムにitem2が来るようなイメージになります。
"item3 item2"は左にitem3 右にitem2です。

つまりこれは横に2階層、縦に5階層のレイアウトになっているということです。
そして子要素にはgrid-areaプロパティを追加することによって指定することができます。

例

```
grid-area: item1;
```

## 今回の本番のコード

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
<body>
  <section class="container">
    <div class="item1">1</div>
    <div class="item2">2</div>
    <div class="item3">3</div>
    <div class="item4">4</div>
    <div class="item5">5</div>
  </section>
</body>
</html>
```


```css
.container {
  display: grid;
  grid-template-areas: "item1 item2"
    "item3 item2"
    "item3 item4"
    "item3 ."
    "item5 .";
    
  grid-template-rows: 200px 100px 300px 400px 500px;
  grid-template-columns: 1fr 325px;
  gap: 35px;
}

.item1 {
  grid-area: item1;
  background-color: #8ca0ff;
}

.item2 {
  grid-area: item2;
  background-color: #ffa08c;
}

.item3 {
  grid-area: item3;
  background-color: #ffff64;
}

.item4 {
  grid-area: item4;
  background-color: #8cffa0;
}

.item5 {
  grid-area: item5;
  background-color: red;
}

```

説明すると先程の通り親のcontainerにはdisplay: gridとgrid-template-areasが設定されています。


```css
  grid-template-rows: 200px 100px 300px 400px 500px;
  grid-template-columns: 1fr 325px;
  gap: 35px;
```

こちらの部分はrowsに関してはrowsの部分5階層に分けた際のpxを表しています。
![スクリーンショット 2021-06-15 1.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/50f8b651-a421-8bd7-1360-13993afe6ab6.png)

こんなイメージですね。
これは説明するためにpxで指定しましたが、実際に要素に合わせて高さを合わせタイなどがあったら

```css
grid-template-rows: repeat(5, auto);
```

みたいに設定することもできます。
こちらはrowsを5階層欲しい、pxに関してはautoで調整してー！といった指示になります。

```css
grid-template-columns: 1fr 325px;
```

こちらに関してはcolumnのレイアウトを指定しています。
ifrは残り全てを表します。
つまり左カラムを325pxに設定して、残りは1frなので画面幅に応じて変動するイメージです。

gapに関してはitemの余白をと調整することができます。

なので全ての要素の余白が35px act言うわけです。
ちなみにcolumn-gapとすればcolumnだけの余白が
row-gapプロパティを設定するとrowだけの余白を設定することができます。

レスポンシブデザインに関してもitem順番を変更していけば簡単に設定することができます！
是非試してみましょう！！


お疲れさまでした！
ubuntu 18.04でtp-link Bluetooth アダプタ UB4Aを使う

# はじめに
初投稿。自分の使っているubuntu18.04のPCにBluetoothがついていなかったので付けようと思ったが、意外と安価なUSBタイプのアダプタでのubuntuでの動作実績がなかったので、人柱として報告。結果的には何の問題もなく認識した。

今回購入したものは、現行で店頭で販売されているtp-link UB4A。

https://www.tp-link.com/jp/home-networking/computer-accessory/ub4a/

サポート情報を確認するとお約束の通り、Linuxには対応していないとのこと。
まぁそうですよね。

https://www.tp-link.com/jp/support/faq/2744/

あと、この商品パッケージに何も書いていなくてすごく不安になるのですが、ページにある通りBLEに対応しています。もっとアピールすればいいのに。


# 導入環境

- OS : ubuntu 18.04
 - testuser@FMVNFB40J:~$ uname -a
 Linux FMVNFB40J 5.4.0-74-generic #83~18.04.1-Ubuntu SMP Tue May 11 16:01:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
- PC : FMV-BIBLO NF/B40 (モバイル インテル® GL960 Express チップセット)
- 買ったBluetoothアダプタ tp-link UB4A (1000円程度)

# やること

刺すだけ。ほんとにこれだけ。
Bus 005 Device 002で認識している。この後、スマホをテストでつなげてみたが特に問題なし

    testuser@FMVNFB40J:~$ lsusb 
    Bus 002 Device 004: ID 0bda:0158 Realtek Semiconductor Corp. USB 2.0 multicard reader
    Bus 002 Device 005: ID 0411:0110 BUFFALO INC. (formerly MelCo., Inc.) 
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 006 Device 002: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
    Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 005 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
    Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

認識すると画面上の右上にBluetoothのメニューにもBluetoothの設定が出てくる
![Screenshot from 2021-06-15 00-54-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1647593/d393ebb0-451b-4085-8f89-e525ed231f0b.png)

# まとめ

家電量販店で買える、きちんと技適の通ったBluetoothアダプタの中で最安の部類に入るtp-link UB4Aが、Ubuntu18.04で使えることが分かった。これでまたPCを延命できる。

それにしても、tp-linkの製品は、なぜBLE対応をパッケージに書かないのだろうか。明らかに損をしていると思う。
mermaid.jsを使ってDoxygen用の図を描く

#概要

Doxygenとmermaidの組み合わせがみつからなかったのでメモします。



#ソースコード（.hファイルとか）にmermaidで描く
doxygenが検出するコメントに@htmlonlyと@endhtmlonlyで挟んで書く。

``` server.h
#pragma once
/**
 * @file           server.h
 * @brief          サーバー
 *
 * このモジュールの使い方
 * @htmlonly
 *	<div class="mermaid">
 *		sequenceDiagram
 *			participant cl as クライアント
 *			participant sv as サーバー
 *			participant db as データベース
 *			cl->>+ sv : データ取得要求
 *			sv ->>+ db : select発行
 *			db -->>- sv : select結果
 *			sv -->>- cl : データ取得要求結果
 *	</div>
 *	<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
 *	<script>mermaid.initialize({startOnLoad:true});</script>
 * @endhtmlonly
 *
 *
 * Copyright (c) tanabata11 Sample Inc. All Rights reserved.
 */


/**
 * \brief select発行
 */
void select();

//　いろんなコード

```

こんな風になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017728/fc7bb7aa-240c-fa66-4817-9d4857288f98.png)


#Doxygen用のマークダウン(.md)にmermaidで描く
同じく@htmlonlyと@endhtmlonlyで挟んで書く。

```　server.md
# サーバー

## このモジュールの使い方

@htmlonly
<div class="mermaid">
  sequenceDiagram
      participant cl as クライアント
      participant sv as サーバー
      participant db as データベース
      cl->>+ sv : データ取得要求
      sv ->>+ db : select発行
      db -->>- sv : select結果
      sv -->>- cl : データ取得要求結果
</div>
<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
@endhtmlonly
```

こんな風になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017728/1f5857d8-b9e3-ebae-3ce4-2d60e8f9e304.png)

他の環境で同じファイルを使うと@htmlonlyが見えちゃいます。
これに限らずマークダウンは環境で動きが変わるのがな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017728/8a5019a9-da29-9f70-3607-3f456abb080d.png)


#参考
シーケンス図のソースはこちらからお借りしました。
[mermaidを使ってMarkdownでシーケンス図を作成](https://qiita.com/poro1985/items/b23bad93bf721a195f15)
その他の書き方
[HTMLの埋め込み](https://qiita.com/harumo11/items/c51228fba7879144e12c#2-html%E5%9F%8B%E3%82%81%E8%BE%BC%E3%81%BF)
[Doxygenのマークダウン形式ファイル]
(http://www17.plala.or.jp/KodamaDeveloped/LetsProgramming/details_doxygen_markdown_file.html)
[Doxygenチートシート](https://qiita.com/yuta-yoshinaga/items/84887a89f6a21a7dcfd5)
ActiveAdminを使用してみる

個人的に作成したアプリが

PythonでYouTubeとTwitterのAPIの情報を取得する
↓
CSVでRailsのテーブルに登録

という手順。

今まではコマンドで実行していたが、視覚的にインポートをやりたいというのと、デプロイ後の管理方法が面倒なので、管理画面を実装したいなぁと思っていました。

そこで、ActiveAdminを使用することで課題がほぼ解決に。

```Gemfile
gem "activeadmin", github: "gregbell/active_admin"
gem "active_admin_importable"
```

インポートもするので、二つともGemfileに記述。

でいつもの

```
bundle install
rake db:migrate
rails s
```

を順番に実行。

```db/seeds.rb
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
```

と記述がある通り、emailとpasswordの記載があります。

http://localhost:3000/admin

にアクセス。

```
rails g active_admin:resource モデル名
```

にて管理画面専用のモデルを作成。

今回はツイートモデルを例に

```app/admin/tweets.rb
ActiveAdmin.register Tweet do
  active_admin_importable do |model, hash|
    model.create(text: hash[:text], image: hash[:image])
  end

  permit_params :text, :image
end
```

これで手動で登録することもできるようになりますし、インポートも可能。

### 課題

今回の使用用途としては困らないですが、アソシエーションしている時に登録がうまくいかなかったです。
多分paramsの設定を○○_idって感じにしなきゃいけないっぽい。
とりあえず今回の目的としてはインポートができるので、すべてOK。

### 備考

日本語表記に変更したり、タイムゾーンを変更できたりもするらしい。

個人的な最終形としては

Pythonで集計も定期実行にして、このインポートも定期実行にしてってやれば、ほぼメンテナンス要らずで管理ができるので、楽かなと。

そんな幻想を抱きながら、今日の作業は終了です、お疲れ様でした。
【Flutter】Error: The getter 'addressOf' isn't defined for the class 'xxx'.の対処法

<h2>エラー内容</h2>
しばらく使っていないプロジェクトをビルドしようとしたところ、

```terminal
Error: The getter 'addressOf' isn't defined for the class 'xxx'
```
というエラー文が表示されてしまいました。

<h2>解決策</h2>

- .ideaフォルダ、buildフォルダ、pubspec.lockファイルの削除</table>
- flutter pub get

を行う。

<h2>動作環境</h2>
```
[✓] Flutter (Channel stable, 2.2.0, on macOS 11.2.3 20D91 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] Connected device (3 available)
    ! Error: iPhone is not connected. Xcode will continue when iPhone is connected. (code -13)

• No issues found!

Dart 2.13.0
```
EC2Rescue とは？

## 勉強前イメージ

EC2 + 救援 やから、EC2になんかあった時に復旧させる的な？

## 調査

### EC2Rescue とは？

EC2インスタンスで動作する、トラブルシューティングツールになります。
Windowsのインスタンスに接続できなくなったり、起動ができなくなったなどの問題が発生した際に
分析・トラブルシューティングのためにログの収集を行うことが出来ます。

windowsインスタンスでは `EC2Rescue for Windows Server` を使用
Linuxインスタンスでは `EC2Rescue for Linux` を使用します。

### EC2Rescue for Windows Server

`EC2Rescue for Windows Server` では、以下が考えられるシナリオです。

- ファイアウォールやネットワークインターフェースなど設定が原因のインスタンスへの接続の問題
- ブートループなどOSの起動の問題
- 詳細なログ分析が必要な場合

また、以下のシステムでないと使えない可能性があります。

- Windows Server 2008 R2 以降で実行されるインスタンス
- .NET Framework 3.5 SPI 以降がインストールされているインスタンス
- RDP 接続からアクセス可能なインスタンス

### EC2Rescue for Linux

`EC2Rescue for Linux` では、以下が考えられるシナリオです。

- vmstat、iostatなどレポートの収集
- syslog、dmesgなど、ログと詳細の収集
- ルートデバイスラベルの重複など、システムの問題の検出
- OpenSSHファイルのアクセス許可の修正など自動的に修正

また、以下のシステムでないと使えない可能性があります。

- Amazon Linux 2
- Amazon Linux 2016.09+
- SLES 12+
- RHEL 7+
- Ubuntu 16.04+

## 勉強後イメージ

イメージそのままやった。
OS壊れてももしかしたら復旧する可能性あるかもってことかな？
たまにAWSの障害でEC2壊れた時にもしかしたら使えるかもね？わかんないけど。
今回は手順とかは一旦なしにして、中身だけちょっと調べてみた。

## 参考

- [Linux 用 EC2Rescue を使用してオペレーティングシステムレベルの問題をトラブルシューティングする方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-instance-boot-issues/)
- [EC2Rescue を使用して Amazon EC2 Windows インスタンスの問題をトラブルシューティングするにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2rescue-windows-troubleshoot/)
- [Amazon EC2RescueでEC2 Windows Server instanceを救出する](https://blog.serverworks.co.jp/tech/2017/03/13/amazon-ec2rescue-is-now-available/)
正規表現が苦手な人がURLからドメイン名を取得する。

TwitterのAPIを使って分析をしている過程で、どうしてもURLのドメイン名を取得したいという状況に直面したものの、正規表現が苦手。そこで、今回はＲの`stringr`パッケージを使用して、正規表現が苦手な人でもごり押しでURLからドメイン名を取得する方法を備忘録も兼ねて書きます。（そんな人いるか知りませんが。）

# 適当なデータフレームを用意する
とりあえず適当にブラウザのタブに並んでいるURLをペタペタ貼って、data.frameオブジェクトを作りました。

```{r}
df <- data.frame(id = 1:4,
                 url = c("https://developer.twitter.com/en/docs/twitter-api/data-dictionary/object-model/tweet",
                          "https://qiita.com/yuhi62320/items/d1193a03392458e99416",
                          "https://www.instagram.com/kannahashimoto.mg/?hl=ja",
                          "https://www.youtube.com/watch?v=swZVrg3H-8E"
                          )
)
                 
View(df$url)

```
このURLのリンクから、ドメイン名を取得したいのですが、正規表現が苦手すぎるので楽して実行できるものはないものか。。。
よく見ると、URLは、/（スラッシュ）で分割することによってある程度ブロックを分けられそうです。
しかも幸いなことに、ドメイン名はhttp(s)の直後に来るので、割とシンプルに獲得できそう。
というわけで、今回は、正規表現が苦手すぎる私が、stringrパッケージを使ってゴリ押しでドメイン名を獲得していきます。

#stringrを使ってゴリ押しでドメイン名を獲得する。
今回はtidyverseで。stringrも同時にロードされます。

```{r}
library(tidyverse)

df_url_split <- str_split_fixed(df$url, "/", n=4) %>% 
          data.frame()

View(df_url_split)
```


`str_split_fixed(stirng, pattern, column_number)`は、指定したパターンを基に文字列を分割し、ベクトルとして保存してくれます。
今回は、`df$url`を`pattern = "/"`で分割し、その結果を要素数4のベクトルに分割し、それを`data.frame`としてまとめています。`n = 4`としているのは、これより少ないとドメイン名以前にある"/"の数が足りず、ドメイン名を独立して分割させられないから。
こちらもよく見れば、各ドメインがX3の列にまとまっていることがわかります。ドメイン名の前に/が3個あるので、3番目の列に格納されているんですね。
あとは、いらない部分を取り除いて成形するだけ。


```{r}
df <- df %>%
  cbind(df_url_split) %>% 
  mutate(domain_name = X3) %>%
  select(-c(X1,X2,X3,X4))
View(df)
```
無事にドメイン名を取得できました。
正規表現が得意な方はよりスマートな方法を教えてください。ぜひ。
AWSのSecurityHubをただ使ってみただけの日記

2021/06/15 はれ

AWSのSecurityHubを有効化してみた。
数分経過した後、画面を更新したら、こうなった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/ba69d769-322b-b5bd-9da6-3280885cdf03.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/7bb2bec1-834a-3365-f043-244dcf6928d6.png)

大体失敗していた。AWS Configを有効化しないとほぼ使い物にならないらしい。

タイトルをクリックすると、修復手順のページに飛べるようだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/42dd0910-3aa7-f83a-87e2-753a1848b4da.png)

とりあえず、言われたとおりに設定する。ただし、SNSに関する設定はしなかった。ルールも何も選択せずに有効化した。

理由は、なんか面倒だったから。もう夜遅いし、俺は眠いのだ。

AWS Configが有効化されたことを見届け、俺は布団へ向かった････


2021/06/26 はれ

前回からだいぶ時間が空いたけど、もう結果が出ているだろうと思ってコンソールを見た。

明日は台風が来るとかで天気が荒れるらしい････

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/cc26fc1c-f3eb-6d0e-ccd9-d199326dac6d.png)

スコアが出ている。標準のタイトルをクリックすると、それぞれのベンチマークで何がダメだったのか、などを書いてくれる。

けど、今ってAWS CISはv1.4まで出ていたような････ちょっと追従は遅めなのかな･･･

コストもSecurityHubから見れるようだ。11日間で、大体200円くらいかかっていた。

PCIを有効化すれば、もうちょっとお金がかかるということだろう･･･

せっかくなので、失敗しているチェックを1つ選んで修復してみる。

今回は「MFA が「ルート」アカウントに対して有効であることを確認する」を修復。

････ってSMS認証つかえないんかーーーーい！！！！！！

仕方ないのでGoogle認証システムのアプリで認証設定を完了した。

さてさて、設定直後にSecurityHubを見ると････まだ反映されていないのか、相変わらず「MFA が「ルート」アカウントに対して有効であることを確認する」は失敗のままだった。

明日くらいにまた見てみるか････

2021/06/29 雨

直ってた。更新日時が出ているのも地味に便利。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401295/bb54eb09-704e-f8ae-e537-4847ebd35545.png)
C#でオブジェクトのシリアライズ・デシリアライズ（json）

# 概要
C#アプリで設定情報を設定ファイルに書き出し⇔読み出しするためにシリアライズするところで盛大にはまったので、結果を遺しておきます

# コード

```c#:シリアライザ

    /// <summary>
    /// シリアライズ・デシリアライズをするクラス
    /// </summary>
    /// <typeparam name="T">対象クラス</typeparam>
    class Serializer<T>
    {
        /// <summary>
        /// オブジェクトをUTF-8のjsonファイルにシリアライズする。
        /// </summary>
        /// <param name="obj">対象オブジェクト。要件1=POCOであること。要件2=シリアライズ対象メンバがpublicでgetter/setterがついていること</param>
        /// <param name="filePath">シリアライズ先のファイルパス。既存の場合は上書きされる。</param>
        public static void jsonSerializeUtf8(T obj, string filePath)
        {
            var options = new System.Text.Json.JsonSerializerOptions
            {
                // trueだと出力を整形する
                WriteIndented = true,
                // UNICODEエスケープシーケンスにしない対象を指定。やらないと、ASCII文字以外すべてが　あ → \u3042　みたいな感じでエスケープされる。
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All),
            };
            byte[] jsonOutput = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj, options);
            System.IO.File.WriteAllText(filePath, System.Text.Encoding.UTF8.GetString(jsonOutput));
        }

        /// <summary>
        /// シリアライズされたUTF-8のjsonファイルから、オブジェクトを復元する。
        /// </summary>
        /// <param name="filePath">シリアライズされたファイルのパス。</param>
        /// <returns>復元されたオブジェクト</returns>
        public static T jsonDeserializeUtf8(string filePath)
        {
            byte[] jsonInput = System.IO.File.ReadAllBytes(filePath);
            var utf8Reader = new System.Text.Json.Utf8JsonReader(jsonInput);
            return System.Text.Json.JsonSerializer.Deserialize<T>(ref utf8Reader);
        }
    }

```
usingなしで動くように書いたので若干もっさいです。


# 手段がjsonであることについて
設定ファイルの選択肢としてはapp.configあたりがあったり、他のシリアライズ手段としてはxmlシリアライズあたりがありますが、
・app.configはkey-value式なので複雑な構造はめんどくさい
・xmlシリアライズはLISTの格納時に色々めんどくさいっぽい
あたりでjsonに絞りました。
実際、コード内の `public static void jsonSerializeUtf8` のコメントに書いた通り、POCOかつgetter/setter付きにすれば問題なく動いてくれています。

# ポエムな背景
設定ファイルを読み書きしたい
→App.config ・・・xmlで定義しないとだめっぽい？しかもkey-valueだけ？
→xml・・・Listが入るとうまくいかない。サンプルコードによると保存時にコードに特別な処理が必要？やってられん
→json・・・公式の記事からするとこれが最新の手段だから楽になってくれてるかもしれない・・・頼む・・・→いけた :laughing:
【小ネタ】DeleteTrack()した際のTimelineEditorの描画崩れを防ぐ方法

UnityでスクリプトからTimelineAssetのDeleteTrack()を行った際に、TimelineEditorの描画が崩れてしまう現象を防ぐ方法を記載します。

```cs:Timelineのエディタ拡張.csの一部
timelineAsset.DeleteTrack(track);
TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);//←これが無いとエディタ表示が崩れる
```

ググったけど資料が少ないので書き留めておきます。
というかDeleteTrack()のページに書いておいてほしいなぁ。。

# 参考資料
[Timeline.TimelineAsset-DeleteTrack - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/2018.4/ScriptReference/Timeline.TimelineAsset.DeleteTrack.html)
[Unable to use DeleteTrack properly - Unity Forum](https://forum.unity.com/threads/unable-to-use-deletetrack-properly.663955/)
ridgepoleした後に、annotateを同時に実行する。

ridgepoleをした後に、annotateしてくれる流れを記載します。


以下のように annotate を実行するようにします。

`Rake::Task['annotate_models'].invoke if Rails.env.development?`

annotate_models は `rails g annotate:install` 実行後に利用可能となります。
お忘れなく。
cf: https://github.com/ctran/annotate_models#configuration-in-rails

ridgepoleをtaskにまとめて実行します。
以下のように `annotate_models` を追加したら終了です。

```
$ cat lib/tasks/ridgepole.rake
# frozen_string_literal: true

namespace :ridgepole do
  desc 'Apply database schema'
  task apply: :environment do
    ridgepole('--apply', "-E #{Rails.env}", "--file #{schema_file}")
    Rake::Task['db:schema:dump'].invoke if Rails.env.development?
    Rake::Task['annotate_models'].invoke if Rails.env.development? # これを追加する。
  end

  desc 'Export database schema'
  task export: :environment do
    ridgepole('--export', "-E #{Rails.env}", '--split', "--output #{schema_file}")
  end

  private def schema_file
    Rails.root.join('db/schemas/Schemafile')
  end

  private def config_file
    Rails.root.join('config/database.yml')
  end

  private def ridgepole(*options)
    command = ['bundle exec ridgepole', "--config #{config_file}"]
    system [command + options].join(' ')
  end
end
```

スキーマを適応する。

```
$ bundle exec rake ridgepole:apply 
```

---

【新卒】→ SIer入社、ドキュメントの日々
【転職】→ IT上場企業、主にインフラ担当
【転職】→ ベンチャーIT企業、主にインフラ担当
【現在】→ 起業

IT業界限定で全ての方に向けて、
今だけ限定で無料キャリア相談実施中。
オンライン面談予約は http://nekakoshi.youcanbook.me
残プロ　第-13回　~pythonで定期的に画面キャプチャ~

# 大リモート時代

リモート会議，リモート授業，リモート面接...

コロナウイルスの影響で良くも悪くも，様々なことがインターネットを介して行われるようになりました．私のような怠惰な人間は授業や会議中につい寝てしまうことがあるわけです．大抵の場合，資料はメール等で配布されるのですが，愛のある(意地悪な)先生となると話は変わってきます．レジュメ配布無し・録音録画禁止といった方針の授業において，居眠りは落単そのものでしょう．Zoomなんかで録画しようものなら即バレからのご指導間違いなしですね．ほとんどの生徒はスクリーンショットをスライドごとに行うのですが，それすら面倒くさい...

こんな状況を解決する，定期画面キャプチャをpythonで書いてみました．怠惰な方はお試しあれ．


# Capturing.py

外部ライブラリはPILだけですね．

~~~ python:
from PIL import ImageGrab
import time
import os
from os.path import expanduser
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.filedialog

def capture(event):
    span = int(entry_span.get())
    split = int(entry_split.get())
    lap_imagine = span/split
    global captures
    captures = []

    for i in range(split):
        start = time.time()
        captures.append(ImageGrab.grab())
        lap_real = time.time() - start
        if lap_imagine > lap_real:
            time.sleep(lap_imagine - lap_real)
        else:
            print("split:{} is too many\n1cycle:{}sec".format(split, lap_real))


def save(event):
    iDir = os.path.abspath(os.path.dirname(__file__))
    iDirPath = tkinter.filedialog.askdirectory(initialdir=iDir)
    dir = iDirPath + "/{}".format(entry_dir.get())
    try:
        os.chdir(dir)
    except FileNotFoundError:
        os.mkdir(dir)
        os.chdir(dir)
    for i, c in enumerate(captures):
        c.save("scene{}.png".format(i))


if __name__ == '__main__':
    caputures = []

    root = tk.Tk()
    root.title("Caputo")
    root.geometry("200x322")

    button_cap = tk.Button(root, text="Capture Scene")
    button_cap.pack(fill=tk.BOTH, expand=1)
    button_cap.bind('<1>', capture)

    entry_span = tk.Entry(root)
    entry_span.pack(fill=tk.BOTH, expand=1)
    entry_span.insert(0, "Capturing Second")

    entry_split = tk.Entry(root)
    entry_split.pack(fill=tk.BOTH, expand=1)
    entry_split.insert(0, "Capturing Leaves")

    button_save = tk.Button(root, text="Save Captures")
    button_save.pack(fill=tk.BOTH, expand=1)
    button_save.bind('<1>', save)

    entry_dir = tk.Entry(root)
    entry_dir.pack(fill=tk.BOTH, expand=1)
    entry_dir.insert(0, "Saving Folder Name")

    root.mainloop()
~~~


# 実行画面

- Capture Scene：画面キャプチャ開始
    - Capturing Second：キャプチャ時間(特に制限なし)
    - Capturing Leaves：キャプチャ枚数
- Save Captures：キャプチャ保存
    - Saving Folder Name：保存フォルダ名

![caputure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/28f5e82c-86a0-6ab8-8880-fbed29d09cdf.png)


# 実行結果

キャプチャ内容は伏せてますが下図のようになります．

![sample_capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/d2acc03e-8157-0083-1818-eaedae43dd27.png)


**キャプチャした内容の取扱いは慎重に！自己責任で！**
MacのChromeでmeta keyとしてoption keyを使ってEmacs key-bind

# はじめに
もともとvimiumをゆるく使ってたんですが、emacsユーザーなので、emacsライクにブラウジングしたいなぁと思い始めました。

調べてみるとvimiumのemacs版作ってくれてる人いました。ありがたや～。
ただ、meta keyをoption keyにしたいので、設定変更しました。

[Emacsユーザ向けChrome拡張機能を公開してみた - Qiita](https://qiita.com/maebaru/items/f7163b70625865b32e68)
[Chromemacs - Chrome ウェブストア](https://chrome.google.com/webstore/detail/chromemacs/kfdibhbheajeacnkkakomaliggbgndcf)
[GitHub - maeda-kazuya/chromemacs: Chrome extension for Emacs keybind navigation, forked from Vimium.](https://github.com/maeda-kazuya/chromemacs)

# 設定変更
## Options
拡張をインストールして、下記２箇所をOptionsで設定変更します。

## ignore keyboard layout
よくわかってないけど、これにチェックを入れます。
`Ignore keyboard layout`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184221/a041b6f4-c169-961d-bdeb-eb7041b91c64.png)

## keymap
コマンドキーで登録されているものをoptionキーに切り替えます。

```
# Insert your preferred key mappings here.
map <a-v> scrollPageUp
unmap <m-v>

map <c-a-b> goBack
map <c-a-f> goForward
unmap <c-m-b>
unmap <c-m-f>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184221/73d0687a-03ad-b82e-9f66-201f2e79d897.png)

# おわりに
これで、快適Emacsライフを送れます。
ドキュメントレジュメ

##はじめに
システム開発で利用する、ドキュメントのレジュメメモ。

##キックオフ
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. 前提条件
 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. 機能詳細
1. 画面仕様
 1. 画面一覧
 1. 画面詳細
1. 帳票仕様
 1. 帳票一覧
 1. 帳票詳細
1. バッチ処理仕様
 1. バッチ処理一覧
 1. バッチ処理詳細
1. ファイル仕様
 1. ファイル一覧
 1. ファイル詳細
1. I/F仕様
 1. I/F一覧
 1. I/F詳細
1. コード体系仕様
 1. コード一覧
 1. コード詳細
1. 非機能要件
1. 可用性
1. 性能・拡張性
1. 運用・保守性
1. 移行性
1. セキュリティ
1. システム環境

##テスト・移行計画/ リリース判定報告
1. 概要
1-1. 背景と課題	
1-2. 対応内容と効果	
1-3. 対応概要	
1-4. 動作環境および利用者運用者
		
2. 対応内容		
3. マスタスケジュール	
4. 体制図		

5. テスト方針
5-1. テスト目的/方針	
5-2. テスト対象/範囲	
5-3. テストカバレッジの考え方
		
5-4. テスト日程	
5-5. テスト環境/手法	
5-6. テスト管理方法	

6. テスト内容
6-1. テスト項目一覧	
6-2. 個別テスト内容	

7. 課題対処状況		
8. 成果物一覧		
9. 品質管理基準
9-1. 品質評価基準	 
9-2. リリース判定基準	

10. 移行計画
10-1. 移行概要	
10-2. 業務移行	
10-3. データ移行	
10-4. システム切替方式	
10-5. 移行リハーサル	
10-6. 移行スケジュール	
10-7. タイムチャートとチェックポイント
		
10-8. チェックポイントと判定基準
		
10-9. 切り戻し時の業務影響と対応事項
		
10-10. 移行体制	
10-11. 移行作業出勤シフト
10-12. 本稼働後の監視と切り戻し上演

##議事録
ユーザと打ち合わせした内容は議事録を残すのが好ましい。
特に要件定義等はシステム稼働後に、エンドユーザ担当者が変わって
「なんでこんな仕様になっているの？」と言われることが多い。
5年10年経過してユーザもSEも不在になった場合に参照できるようにしておくのが好ましい。

1. 会議名称
1. 資料
1. 日時
1. 場所・参加者
1. 資料
1. 議題
1. 内容
1. 決定事項
1. アクションアイテム

##障害報告書
障害発生時にユーザ報告に必要な項目

1. 概要
1. 対象システム
1. 発生期間
1. 障害範囲・影響
1. 経緯
1. 原因
1. 暫定対応
1. 恒久対応


---
2021/6/14：作成
2021/6/27：キックオフを追記
KryptonでAWSアカウントをセキュアに！

#はじめに
AWSアカウントの多要素認証の1つとして、U2Fセキュリティーキーを登録する方法があります。
U2Fとは、USBデバイスなどのハードウェアキーを使用して多要素認証を行いますが、有償の専用のハードウェアを用意する必要があり、それなりのハードルがあります。
Kryptonというソフトウェアを使用すると、専用のハードウェアを用意する必要がなく、スマホをハードウェアキー代わりに使用することが出来、また、パスコードやワンタイムパスワードのようなコードを入力する必要もないため、お手軽に認証することができます。

本記事では、AWSアカウントにKryptonを利用してU2Fセキュリティーキーを登録する手順について記載します。

#Kryptonを使ったAWSアカウントの2要素認証
### *事前準備*
1. ChromeにKrypton拡張機能を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/a167db58-d33a-38d8-573d-8c10bca75a58.png)

1. スマホにKryptonアプリケーションをインストールします。

1. スマホとブラウザをペアリングします。
ブラウザから、先程追加した拡張機能を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/5180bea4-de7a-2bd3-899a-9493e67f28f1.png)
スマホにインストールしたアプリを起動し、QRコードを読み取ります。<br>
スマホのアプリを起動し、画面下の「PAIR」を選択するとQRコード読み取りのためにカメラが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/482d94c1-e259-623f-33bf-713839b28724.png)
QRコードを読み取ると、ペアリングを行うかどうか聞かれるので、「PAIR」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/acea3512-d348-a4e8-0c1e-e4ca0cde8d21.png)
以下のようなメッセージがでれば、ペアリング完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/005dce03-e9e2-5ce1-1c49-e539f5ec5a41.png)


### *AWSアカウントへの登録*
1. IAMユーザーでログインします。
1. IAMサービスへ移動します。
1. 認証情報に、MFAデバイスの割り当てを追加します。<br>
「ユーザー」メニューを選択し、MFAデバイスの割り当てを行う対象ユーザーを選択します。その後、認証情報タブを選択し、のMFAデバイス割り当ての「管理」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/56af1772-95ba-230a-45c0-2f8042695ac5.png)
「MFAデバイスの管理」ウィンドウが出てきたら、「U2Fセキュリティキー」を選択して続行ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/3a3e7512-3b01-9f32-441c-23928850b19f.png)
U2Fセキュリティーキーの設定画面が出たあと、スマホに通知が出てくるので、「APPROVE」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/3adb36e4-d213-2dd0-ff2f-f6515f3e3295.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/df92115a-4812-e7f6-5195-222d6b6fef24.png)<br>
登録が完了すると、以下のような画面が出てきますので、閉じるボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/d845fd85-da58-2536-6434-d931347bce28.png)
閉じるボタンを押すと、IAMサービス画面に戻りますので、MFAデバイスの割り当てにリソースが割当てられていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/3691f3a3-fcc6-0a8b-c2c8-960515e3d5e9.png)
これで登録は完了です。

### *IAMユーザー認証の実施*
1. IAMユーザーでログイン
U2Fセキュリティーキーで登録したIAMユーザーでログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/6d0a0bbe-4758-e8fd-24cb-b83da852b6f8.png)

1. U2Fによる認証実施
ID/PASSWORDでログインすると、MFAを使用してサインインの画面が出たあとに、スマホに通知が出てくるので、「APPROVE」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/9f4122fd-5e96-9064-9dcd-30baae843dc6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/e7684677-fd12-f216-7121-f99743282fd0.png)
これで認証が行われ、ログインが完了します。

#注意点
なぜかわかりませんが、Kryptonによる認証が1回目は必ず失敗します。（ブラウザ画面上では、U2F認証待ちから何も変化しません。）
再度ログインし直すと正常認証が行われますので、「MFAを使用してサインイン」画面から切り替わらない場合は、ID/PASSWORDの入力からやり直してください。
Alexa連携の共用買いものリストアプリをGlideAppで作ってみた結果をふりかえる

# 背景
- 以前書いた[この記事](https://qiita.com/meowmeowcats/items/1a08aa4578eb32640009)のアプリを、半年間運用してみて思ったことをメモしておくことにする

# 具体的な運用
- 買い物は毎週末
- 買い物リストへの登録はAlexaからどちらが行っても良い
- 買い物は私がする（運用変更）

# 追加要望（新規に追加した機能）
- 毎週木曜日に定期的に買うものを転載する機能（GAS）

```js:
function copyRoutine2List(){

  //二次元配列に
  var routine_data = routine_spreadsheet.getRange(1,1,routine_spreadsheet.getLastRow(),3).getValues();

  routine_start_cell = 2 //Routineはいつも２行目からコピー
  shoppinglist_start_cell = settings_spreadsheet.getRange(2,2).getValue()
  

  var i = -1
  Logger.log(routine_start_cell)
  for (var j = routine_start_cell; j<=routine_spreadsheet.getLastRow() ; j++){
    Logger.log(routine_start_cell)
    to_buy = "[routine]"+routine_data[routine_start_cell + i][0] + routine_data[routine_start_cell + i][1]
    bikou = routine_data[routine_start_cell + i][2]
    Logger.log(to_buy)
    shopppinglist_spreadsheet.getRange(shoppinglist_start_cell + i + 1,1).setValue(to_buy)
    shopppinglist_spreadsheet.getRange(shoppinglist_start_cell + i + 1,3).setValue(bikou)
    i++;
  }
  settings_spreadsheet.getRange(2,2).setValue(shoppinglist_start_cell + i + 1)
}
```
- 定期的に転載するアイテムを登録する機能（GlideApp）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/99fdc09f-d048-33c2-f193-812293eb7f63.png">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/5776fc51-2f41-da0b-8e7b-f7a3a2033721.png">


# 良くなったところ

- 定期的なアイテムを忘れにくくなった
    - 冷蔵庫チェックするときにあるかないか確認するアイテムが、転載により一覧化されているため
- 複数人で買い物を管理できる
    - 夫「〇〇買っておいて」→私がメモ、の流れがなくなり、「Alexaに入れておいて」で済む。これぞDX！
    - 食料品と日用品で売り場が異なる時も手分けして二人で同時にチェック可能

# 悪くなったところ
- Alexaの買い物リストに大量にゴミが溜まっている（予想どおり）
- 子供達がいたずらでいろんなものを入れる
- 時々謎の何かが入っていて（子供のいたずら、登録ミス）、解読作業が必要になる
- GlideAppの無料の1000回編集が3ヶ月くらいで尽きるため、新しいアプリに移行が必要となる
    - コピーすればいいのでちょっと手間があるだけ。再度開発とまではならない。

# 総じて、運用の手間は大したことなく、下記がめちゃめちゃ便利だったと思う。今後も使い続ける。
- 買い物リストを複数人で管理できる
- 定期的なアイテムを忘れにくい
[Oracle Cloud] Standard Objectsの拡張方法

Oracle Cloud Applicationsは、Standard Objectsを拡張する機能を提供しています。
Objectsを構成するパーツ（Objects, Fields, Pages）の紹介と、拡張方法を記載していきます。

## Objects

関連するビジネス・エンティティを表します。

* Leads, Sales Campaigns, Opportunitiesなど
* Springboardにある全てのアイコンがオブジェクトであるわけではない。例えば、Workspaceは検索とレコード管理の画面です。

## Fields

Objectに関する一つの情報を保存する項目です。データ型を指定できます。String, Number, Dateなどの基本型以外に、Static picklists, dynamic picklists, formularsなどの拡張データ型も使用可能です。

### 1. Standard Fields

定義済みフィールドのことです。中にはSystem Fieldsが含まれています。

System Fields:

* 全てのObjectには6つのSystem Fieldsが含まれています。
  * CreatedBy(Text) : 作成者のユーザID
  * CreationDate(Date) : 作成日
  * Id(Number) : ユニークなID
  * LastUpdateDate(Date) : 最終更新日
  * LastUpdatedBy(Text) : 最終更新者のユーザID
  * RecordName() : 所属オブジェクトのプライマリ項目。例えばOppotunitiesだとOppotunity名、連絡先だと苗字が格納される。
* ほとんどのObjectにPUID(Public Unique Identifier) Fieldが含まれています。
  * System-defined text field
  * 外部システムとのインテグレーションに使用される。OIC(Oracle Integration Cloud)も含まれます。

### 2. Custom Fields

ユーザが追加したフィールドのことです。

## Pages

Object情報の表示方法を表します。

## Standard Objectの拡張手順

### 1. Sandboxを作成しアクティブ化します。

サインアウトと再サインインし、正しいSandboxを選んでいることを確認します。

### 2. 拡張対象のObjectを選択します。

Application Composerの画面を開き、拡張対象のObjectを選択します。

### 3. Fieldを追加します。

### 4. Pageレイアウトを修正します。

### 5. Pageで画面を確認します。

### 6. Sandboxを公開します。
Nodebrew 　を使って　Node.js　をインストールしてみた

#はじめに

+ 2021年6月開講の医療者向けプログラミングスクール「ものづくり医療センター」に0期生として参加させていただくことになった。　

+ 受講にあたって以下の事前準備を行ったので、備忘録として記す。

#環境

+ MacOS BigSur
+ VSCode
+ (iTerm2) ：事務局から推奨されたわけではないが、個人的にインストールしてあった。

#1.Homebrew のインストール
今回は、NodebrewをHomebrewからインストールする　
省略
→　参考　https://qiita.com/zaburo/items/29fe23c1ceb6056109fd


###動作確認
```
MB:~ tomoko$ brew -v
Homebrew 3.1.9-129-g9f4874d
Homebrew/homebrew-core (git revision ********; last commit 2019-04-22)
```

#2.Nodebrew の　インストール

```
$  brew install nodebrew 
```

###動作確認

```
MB:~ tomoko$ nodebrew -v
nodebrew 1.0.1
```
無事Nodebrewがインストールされいた

#3.Nodebrew を使って Node.js をインストール

###インストール可能なバージョンを確認（省略可能）
```
MB:~ tomoko$ nodebrew ls-remote
```

###最新版のNode.jsをインストール
```
MB:~ tomoko$ nodebrew install-binary latest
Fetching: https://nodejs.org/dist/v16.3.0/node-v16.3.0-darwin-x64.tar.gz
######################################################################### 100.0%
Installed successfully
```

###インストールされているバージョンを確認

```
tomoko@MB ~ % nodebrew ls
v11.14.0
v16.3.0

current: v11.14.0
```

###最新版のバージョンを有効化

```
tomoko@MB ~ % nodebrew use  v16.3.0
use v16.3.0
```

###バージョンの再確認
```
tomoko@MB ~ % nodebrew ls          
v11.14.0
v16.3.0

current: v16.3.0
```
無事、最新版になっていることを確認できた。

#4.npmのバージョン確認
Node.js をインストールするとパッケージ管理ツールの npm（Node Package Manager）も一緒にインストールされる。

```
tomoko@MB ~ % npm -v
7.15.1
```

#参考にしたサイト
+ https://www.webdesignleaves.com/pr/jquery/node_installation_mac.html
MacでNode.jsのバージョン変更をする&パスを通す

#タスク
+ 既にインストールしたNode.jsを、スクール指定のバージョンへ変更
+ スクールから頂いた参考Qiitaは↓
https://qiita.com/7110/items/efe0be1be11bed1db143

#レベル
+ 初心者
+ 「パスを通す」の意味を他人に説明できない

#インストールしたはずのNode.jsのバージョン確認でつまずく
前日にインストールまで成功したはずのNode.js
確か、最新バージョンをインストールしたはずだった。

```
tomoko@MB ~ % node -v
zsh: command not found: node
```
あれ？　なんで　バージョンが出てこないのか？
これがいわゆる　「パスが通っていない」　状態らしい。

困ったな。。。。
ここは一旦放置して、　再度スクールからの参考Qiita通りに Nodebrew　の有効化から始める。

#1.Nodebrew　の有効化

```
tomoko@MB ~ % nodebrew
nodebrew 1.0.1
```
ズラズラ出てくるのが終わったので、

```
tomoko@MB ~ %　　nodebrew setup
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```

`
export PATH=$HOME/.nodebrew/current/bin:$PATH
`
↑のようにパスの指定が表示された。

#2.パスを通す

```
tomoko@MB ~ % vim ~/.zshrc
```

すると、突然目の前の様子が変わり、
![スクリーンショット 2021-06-14 22.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1565008/b41c8b20-d2ab-f9a6-6d3e-24a0e264f7c6.png)
スクリーンショット 2021-06-14 22.32.20

ドキドキする画面が出てきた。
勇気をもって 
①　` i `　のキーを押す
②　すると、下端に　`INSET MODE`　と表示されたので、　そのまま
`export PATH=$HOME/.nodebrew/current/bin:$PATH` 　を　コピペ入力
③ `esc` を押してから `:wq` と入力
④　エンターを押し保存。

もとの見慣れたターミナル画面になったので、

```
tomoko@MB ~ % source ~/.zshrc
```
で　完了。

#3.Node.js　のインストール
### インストール可能なNode.jsのバージョン確認

```
tomoko@MB ~ % nodebrew ls-remote
v0.0.1    v0.0.2    v0.0.3    v0.0.4    v0.0.5    v0.0.6

（中略）
v14.0.0   v14.1.0   v14.2.0   v14.3.0   v14.4.0   v14.5.0   v14.6.0   v14.7.0
v14.8.0   v14.9.0   v14.10.0  v14.10.1  v14.11.0  v14.12.0  v14.13.0  v14.13.1
v14.14.0  v14.15.0  v14.15.1  v14.15.2  v14.15.3  v14.15.4  v14.15.5  v14.16.0
v14.16.1  v14.17.0

v15.0.0   v15.0.1   v15.1.0   v15.2.0   v15.2.1   v15.3.0   v15.4.0   
（後略）
```

指定の ` v14.17.0' を見つけた。

###指定されたバージョンのインストール

```
tomoko@MB ~ % nodebrew install v14.17.0
Fetching: https://nodejs.org/dist/v14.17.0/node-v14.17.0-darwin-x64.tar.gz
######################################################################### 100.0%
Installed successfully
```
無事インストールされた。

###インストールしたバージョンを有効化

```
tomoko@MB ~ % nodebrew use v14.17.0
use v14.17.0
```
無事有効化された

###有効となったNode.jsの確認　１回目

```
tomoko@MB ~ % node-v
zsh: command not found: node-v
```
あれ？　あれ？　これは先程パスを通したはずなのに、、、また通っていない状況。

よくわからないが、とりあえず、もう一度　１.Nodebrewの有効化 　２.パスを通す作業を繰り返した。。。。

###有効となったNode.jsの確認　2回目

```
tomoko@MB ~ % node -v
v14.17.0
```
できていた！！　

おまけに

```
tomoko@MB ~ % npm

Usage: npm <command>
```

#まとめ
系統だった説明はできないが、なんとか見様見真似で一応できただけ。
BC5 圧縮テクスチャ

# はじめに

プログラムから, テクスチャ圧縮がしたいです. BC1, BC3, BC6h BC7についてはispc texture compressionを使おうと思っていましたが, BC5がないのです.

https://software.intel.com/content/www/us/en/develop/articles/fast-ispc-texture-compressor-update.html

ガイドに仕様がちゃんと書いてあります. 簡単そうなので作ってしまいます.

https://docs.microsoft.com/en-gb/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc5

# ファイルフォーマット

4x4のブロックごとに圧縮するブロック圧縮です. BC4はRだけの1チャネル, BC5はRGの2チャネルを扱います. `4x4x2 = 32 bytes`を次の `tablex2 = 16 bytes`に圧縮します. BC5_UNORMとBC5_SNORMの2バリエーションです. 2つはシェーダでサンプルした場合, [0 1]の浮動小数点数になるか, [-1 1]の浮動小数点になるかが違います.

テーブルは, 4x4の最小値と最大値が先頭に2バイト, 次に3bits x 16のテーブルへのインデックスが並びます.

```cpp
/*
MSB                   LSB
| red_0               | 1 byte minimum color
| red_1               | 1 byte maximum color
| red_h | red_g | red_f | red_e | red_d | red_c | red_b | red_a | 3 bits x 8
| red_p | red_o | red_n | red_m | red_l | red_k | red_j | red_i | 3 bits x 8
*/
```

テーブルは明示的に持たず最大値, 最小値から計算します. UNORMとSNORMで１箇所異なりますが, 圧縮するだけならばどちらでも同じなので統一します.

```cpp
static constexpr u32 Shift = 20;
void createTable(s32 colors[8], s32 block[16])
{
    colors[0] = block[0];
    colors[1] = block[0];
    for(u32 i = 1; i < 16; ++i) {
        colors[0] = minimum(colors[0], block[i]);
        colors[1] = maximum(colors[1], block[i]);
    }
    colors[0] <<= Shift;
    colors[1] <<= Shift;

    if(colors[1] < colors[0]) {
        // 6 interpolated color values
        colors[2] = (6 * colors[0] + 1 * colors[1]) / 7; // bit code 010
        colors[3] = (5 * colors[0] + 2 * colors[1]) / 7; // bit code 011
        colors[4] = (4 * colors[0] + 3 * colors[1]) / 7; // bit code 100
        colors[5] = (3 * colors[0] + 4 * colors[1]) / 7; // bit code 101
        colors[6] = (2 * colors[0] + 5 * colors[1]) / 7; // bit code 110
        colors[7] = (1 * colors[0] + 6 * colors[1]) / 7; // bit code 111
    } else {
        // 4 interpolated color values
        colors[2] = (4 * colors[0] + 1 * colors[1]) / 5; // bit code 010
        colors[3] = (3 * colors[0] + 2 * colors[1]) / 5; // bit code 011
        colors[4] = (2 * colors[0] + 3 * colors[1]) / 5; // bit code 100
        colors[5] = (1 * colors[0] + 4 * colors[1]) / 5; // bit code 101
        colors[6] = 0;                                   // bit code 110
        colors[7] = 255<<Shift;                          // bit code 111
    }
}
```

ピクセル値に最も近いテーブルインデックスを検索して, 符号化します.

```cpp
u64 findNearest(s32 colors[8], s32 x)
{
    u32 index = 0;
    s32 mind = absolute(colors[0] - x);
    for(u32 i = 1; i < 8; ++i) {
        s32 d = absolute(colors[i] - x);
        if(d < mind) {
            mind = d;
            index = i;
        }
    }
    return index;
}
```

# まとめ

[GPUOpen Compressonator](https://gpuopen.com/compressonator/)と結果がことなるため, もっといい方法がありそうです.
ボタンを押したときにくるくるローディングさせるやつ

何かのときに使えそうな、ボタンを押すとくるくるローディングするやつ。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="result" data-user="takiguchi-yu" data-slug-hash="NWpEoPR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ボタンを押したときにくるくるさせるだけ">
  <span>See the Pen <a href="https://codepen.io/takiguchi-yu/pen/NWpEoPR">
  ボタンを押したときにくるくるさせるだけ</a> by takiguchi-yu (<a href="https://codepen.io/takiguchi-yu">@takiguchi-yu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
【CPUの高速化技術】基本情報技術者試験のためのコンピュータの構成

※この記事は
「栢木先生の基本情報技術者教室」を参考に学んだことをまとめた記事です。

##CPUの高速化について

###CPUの命令のおさらい
①命令の取り出し
②命令の解読
③実効アドレス計算
④オペランドの取り出し
⑤命令の実行
⑥演算結果の格納

* **逐次制御方式**とは6つ流れを1命令ずつ繰り返し実行すること

時間がかかり、効率が悪いです・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965248/93ef9d51-9f7a-c5cb-0ff5-b63933c900d2.png)

* **パイプライン方式**　とは複数の命令を1つずつずらしながら並行処理する方式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965248/b1bae6ae-2ca7-ee3e-dbdb-d521875b35c3.png)

メリット
効率が上がる

デメリット
分岐命令が来ると、先読みしていた命令を破棄し、新たに分岐先の命令を実行する必要がある

デメリットの解決策
処理の順序が乱れること = パイプラインハザード

パイプラインハザードを起こさないために、**分岐予測**や**投機実行**などが使われる

分岐予測 = 実行される確率の高い方を予測する
投機実行 = 分岐先が正しければその結果を利用する 

* CPUの高速化を図るために**スーパーパイプライン方式**や**スーパースカラ方式**も活用されている

**スーパーパイプライン方式**
パイプラインをさらに細分化した方式

**スーパースカラ方式**
複数のパイプラインを利用して同時に複数の命令を実行することで、高速化を図る方式

* CPUの命令セットアーキテクチャとして**CISC（シスク）**と**RISC（リスク）**がある

**CISC（シスク）** 
１回の命令で複雑な処理ができる
使用用途: PCのCPU

**RISC(リスク)**
命令の実行時間が均等になり、パイプラインで効率よく処理ができる
使用用途: スマホ・タブレット

* **マルチコアプロセッサ**とは1つのCPU内に複数のコアを備えたもの
メリット
消費電力を抑えながら、処理速度の高速化を図ることができる

* **GPU**とは3Dの画像処理を高速に実行する画像処理装置のこと
OpenWeatherMap のCityID検索用サービスを作ってみた


## 無料で多機能な天気系APIの一つOpenWeatherMap 

https://openweathermap.org/

使い方として、以下のjsonから対応した都市の名前を探して、一致した名前をリクエストするもの

http://bulk.openweathermap.org/sample/

例：
`http://api.openweathermap.org/data/2.5/forecast?q=Fuchu,jp&APPID=API_KEY`

注意：API_KEY取得しなければいけません(無料)

## 自宅付近の府中見つけた！けど確か広島にも府中ってあったよな…

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

先程のjsonデータをダウンロードしてきて、府中に住んでいるので「fuchu」と検索したらありました。

ただ、広島にも府中という都市があることを知っていて、「あれ？これはもしかして違うかも？」と思ってしまいました。

他の情報はjpという日本という情報しかなく、ほんのちょっとだけ不安になり、lonとlat（緯度経度）から割り出そうとしました。

### でもこの数値でググるってなんかなぁ

じゃぁ勝手にツール作ろうってことで作りました。

## 使用技術

* Vue
* Vuetify
* Axios
* GitHub pages

特に難しいことはしてないです

GoogleMap使おうとも考えたけど、まぁいいかなっと

### サービスは[こちら](https://tkyko13.github.io/OWM-city-searcher/)

https://tkyko13.github.io/OWM-city-searcher/

[![Image from Gyazo](https://i.gyazo.com/ef33e485d8cb4d5fdad9c6246ffb5445.png)](https://tkyko13.github.io/OWM-city-searcher/)

緯度経度入力とブラウザで現在地を許可してあげると現在地から近い都市のリストを10件出力します。

これで間違いなく自宅近くの天気情報が取得できるようになりました！

### ちなみに緯度経度0,0は

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

Earth?地球？
Power Automate: 書式編集出来ない（テーブル化無しで） Excel から情報を取得する

# 概要
部署間の業務フローを見直したいのに見直せず、Excel書式で社員の回答を提出しないといけない。
そんな時に、そのExcel書式からデータを取得する方法の備忘録

###### AutomateでExcelを処理する際、Table化も検討したほうが良いです。Office Scriptsでも可能ですし。

0. Excelからデータを JSON で取得する Office Scripts
0. Automateで office scripts を動かして、Resultを利用。Parse JSONで。

## Excelからデータを JSON で取得する Office Scripts

- 取得元のExcelの例
![2021-06-14_23h05_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c71d66b2-5594-62e4-dcb2-031d9cd11f3e.png)

- 取得したいセルのデータを利用して、JSONを生成。ここが今回の肝:point_up_tone2:。

[MS: 自動で実行される Power Automate フローにスクリプトからデータを返す](https://docs.microsoft.com/ja-jp/office/dev/scripts/tutorials/excel-power-automate-returns)

```typescript
function main(workbook: ExcelScript.Workbook
) {
	let selectedSheet = workbook.getActiveWorksheet();
	// Set range A5 on selectedSheet

	const retreiveData: JSON = <JSON><unknown>{
		"username": selectedSheet.getRange("E3").getValue(),
		"department": selectedSheet.getRange("E2").getValue(),
		"answers": Array(
			selectedSheet.getRange("A5").getValue(),
			selectedSheet.getRange("B5").getValue(),
			selectedSheet.getRange("C5").getValue(),
			selectedSheet.getRange("D5").getValue(),
			selectedSheet.getRange("E5").getValue(),
			
			selectedSheet.getRange("A7").getValue(),
			selectedSheet.getRange("B7").getValue(),
			selectedSheet.getRange("C7").getValue(),
			selectedSheet.getRange("D7").getValue(),
			selectedSheet.getRange("E7").getValue()
		),
	};
	return JSON.stringify(rememberUser)
}
```

## Automateで office scripts を動かして、Resultを利用。

- 利用例
    - Run Scriptで必要な情報を取得
    - Parse JSON で利用する
    
![2021-06-14_23h08_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/2cae064e-4d09-4c90-898e-0209ea4fb87f.png)


# まとめ

- 前回と同じですが・・部門間のフローを最適化出来るのが良いですね。現場改善を支援してみんなの笑顔を作る仕事がしたいものですな:laughing:
AWS実務ほぼなしでAWS資格のネットワーク専門知識に合格した勉強法

#取得のきっかけ
人事考課で宣言していたAWS資格のプロフェッショナルが難しすぎて断念。
AWSの実務経験はほぼないですが、ネットワーク経験は長いので
AWSのネットワーク専門知識(以降、ANS)はいけるのでは？と考え合格を目指しました。

#勉強した期間
1カ月前に試験日を決め、結果として4カ月間の勉強となりました。
自分としてはこれが一番大事だったのですが、まず__スマホを手に取らないようにしました。__
スマホを手に取りそうになったら勉強を始めるようにして、意識的に勉強に努めてることに重きを置きました。
勉強ばかりだと息が詰まるので途中息抜きもしつつ、試験日を決めた際に受かったらご褒美として
ラーメンとビール、おいしいスイーツを食べることを糧にモチベーションを維持した感じです。

#環境
会社がAWSを押していてAWS専門部署もあり、ANSを目指すメンバーで情報交換もできました。
社内で週一でSAA勉強会を開いていて、言い出しっぺがそろそろ受からないと示しがつかない状況で
そもそも追い詰められないとモチベーションが上がらず勉強しないタイプだったので、この__外的要因を作れた__のは大きかったです。

#AWSの知識
AWS実務はAMIの作成・EC2リストアを6日くらい実施。
SAAは3年前に取得していて個人的にEC2作成～PCからSSH接続までを何十回か実施した程度。
SAPはどこかのサイトの問題集を300問くらい2周して受けた結果、玉砕。

#インフラの知識
サーバ/VMwareとネットワークはL2～L3、FWの設計/構築/試験などインフラ周りを9年ほど業務で経験。
WAN、VPNなど外部接続はほぼ実務なし、研修などで数回実施。
資格はCCNPまで取得していて、ネットワーク用語や経路の優先順位などの知識はあり。

#実施した勉強
・最初の1カ月目はQiitaやGoogle先生でANSに関連する情報を調べてなんとなく出題範囲などを理解。
・BlackBeltをKoiwaClub実施前と試験日前日で計2周確認。
　ELB、DX(冗長構成含む)、Route53、VPC、Transit Gateway、CloudFront
　https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/
・3カ月前からKoiwaClubに登録して問題を実施し始める。
　https://aws.koiwaclub.com/exam/ans/
　試験の進め方は#1～5まで実施したら、また#1からやり直し、それを繰り返す形で実質5周した。
　補足も確認すると頭に入りやすく、__答えが違うものもなぜ違うのか覚えておくと良い。__
・DX、Route53、VPC、Transit Gateway、CloudFront
　上記サービスを実際に触り、イメージを頭に入れる。
　作成直前までならお金は掛からない。
　特にRoute53のポリシーの推移は触っておくとイメージしやすい。
・公式の攻略動画を見て学習。
　「AWS 認定- 専門知識を攻略しよう 高度なネットワーキング(ANS-C00)」
　https://pages.awscloud.com/AWS_Certification_NW_jp_confirmation.html
　※簡単な登録が必要
・公式のサンプル問題を2周。
　https://d1.awsstatic.com/ja_JP/training-and-certification/docs-advnetworking-spec/AWS-Certified-Advanced-Networking-Specialty_Sample-Questions.pdf
・Googleで「AWS Certified Advanced Networking – Specialty」で検索したものを読み漁る。

#本番
試験前日はできるだけBlackBeltで知識を詰め込みました。
記憶が定着するそうで6時間以上は寝て、試験当日朝にKoiwaClubの5周目を実施してほぼ間違えず復習できました。
試験開始時間はできるだけ午前中がいいみたいですが、勉強がいつもギリギリになるので14時開始に。
結果的に復習が行え、余裕を持って試験に臨むことができました。
以下は注意したほうがいいと思ったポイントです。

・気持ちに余裕ができるため、テストセンターは早めに着いておいたほうがいい
・受付のあと開始まで時間があったが、センター内で復習はできず、すぐに試験となる
・序盤で10分くらい迷う問題があったので、解答に迷う問題は仮回答してフラグを立て見直したほうがいい
・__見直しは最後までやり尽くす！__

問題を受けての所感は、
・実施した勉強から4割くらい
・見たことないが実施した勉強の知識から回答できたのが3割くらい
・見たことなく、回答もなんとなくしか分からない問題が2～3割
という具合で、30問くらいはフラグが付きました。(多い。。)
1時間前には全問入力が終わり、フラグの見直しをゆっくり1回実施してギリギリ合格でした。。

|![AWS ANS.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596030/88d3a41a-9689-13a0-4a35-af8ebfbbd316.png)|
|:--|

（__見直ししてなかったら落ちてました。。__）

#終わりに
思ったよりもネットワークの用語や基本的な知識が役に立ちました。
プロフェッショナルよりはまだ簡単に感じましたが、考え方やネットワーク構成も出てくるので逆にネットワークに触れてきてない人は用語も都度調べないといけなくきつそうに思えました。
次はプロフェッショナルをリベンジできれば・・・！
今見ているサイトのGoogleAnalyticsトラッキングIDを表示するブックマークレット

閲覧しているサイトの
GoogleAnalytics（ユニバーサルアナリティクス）
のトラッキングID[UA-〇〇〇〇]をスピーディに表示します。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/fdc7bd74-e8ec-9355-3e81-dff490b4b229.png)


このサイト、GA入ってる？という時、デバッグにどうぞ。
もちろんGAが入っているサイトじゃないと反応しません。

##使い方：
・適当なブックマークを作る
・ブックマークのURLに下記のコードを入れる
・調べたいサイトでこのブックマークをクリックする

```
javascript:var trackers2 = ga.getAll();var gacall="";for(i=0;i<trackers2.length;i++){if (gacall.indexOf(trackers2[i].get('trackingId') ) != -1) {console.log('test');}else{gacall+=trackers2[i].get('trackingId') + "\n";}}alert(gacall);
```

##簡易解説

ポイント：ga.getAll();　/ get('trackingId')

javascriptで
ga オブジェクト メソッドというものを活用しています。
GAに関する様々な情報を取得できます。
それをアラートで表示しているだけです。

他にも活用できると思いますので是非ご参考に！

Google公式
https://developers.google.com/analytics/devguides/collection/analyticsjs/ga-object-methods-reference?hl=ja