OmniAICreator/Qiita-1.07M huggingface dataset:
PHP：クラスのプロパティを簡単にImmutable（不変化）

# Traitでgetterとsetter兼用の処理を定義

- 第1引数でプロパティの**参照**を受け取る。（setterの機能を実装するため）
- 第2引数で設定値を受け取る。
- 第2引数の設定値がnullの場合、getterとして振る舞う。
- 設定値があり、プロパティが設定済み（nullではない）場合、例外発生。<- 不変のため。


```php:immutableTrait.php

trait Immutable
{
    //クラスのプロパティは参照を受け取る。
    protected static function access(&$property, $value)
    {
        //設定値がnullの場合、未設定としてプロパティ値を返却（getterとして振る舞う）
        if (is_null($value)) {
            return $property;
        }
        //プロパティ値が設定済みの場合、変更をさせないため、例外発生。
        if (!is_null($property)) {
            //ImmutableExceptionとか作ってあてるのがいいかも。
            throw new \Exception('already value exists. this object is immutable');
        }
        //プロパティに値を設定
        $property = $value;
        return $value;

    }
}

```

# モデルクラスにTraitを実装
- traitのメソッド、accessを呼び出す。
- 第1引数は、プロパティ値
- 第2引数は、設定値。デフォルトをnullとする。

```php:Model.php

class Model {
   // トレイト実装
   use Immutable;

   private $_name = null;
   
   //引数には、デフォルト値を必ず設定する（getterとして使うため）
   public function name($value = null) 
   {
      //プロパティを第１引数（参照渡し）
      return self::access($this->_name, $value);
   }
   
}

```

# 使用方法

```php:using.php

$m = new Model();

//setter
$m->name('value1');

//getter
echo $m->name();

//例外発生
$m->name('value2');


```

# 問題点

- プロパティがオブジェクトや配列の場合、取得後に変更ができる。文法的にfreezeができればいいのだが。
ActiveStorageで保存するJPEG画像のEXIFをmetaデータにしたい時

# やりたい事

```rb
YourModel.first.image.metadata # => {latitude: ..., longitude: ...}

```

デフォルトで入っているImageAnalyzerは画像のwidth、heightしかmetadataとして取ってくれない。
https://api.rubyonrails.org/classes/ActiveStorage/Analyzer/ImageAnalyzer.html

# 解決策

- exifr/jpeg
- timezone_finder

を使う。

まず、`exifr/jpeg`でJPEG画像のEXIFを取り出し、GPS情報を取得。

- latitude
- longitude
- gps_date_stamp
- gps_time_stamp

gps_date_stamp、gps_time_stampはUTC。 https://www.exif.org/Exif2-2.PDF
![95e82e537d78fc41bae5e6ea2ccde143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/9750900a-97bc-7bc2-15b5-50bd60f18fc2.png)
![ed13c3b3394c498daee58c7122e16590.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/72197bbf-fc08-e8a4-1cc1-85ea33934a09.png)

UTCの時間をなるべく正確な現地時間にするために`timezone_finder`を使う。

```rb:exif_jpeg_analyzer.rbなどとしてconfig/initializersに入れる
# 元ネタはここ
# https://www.georg-ledermann.de/blog/2018/05/15/exif-analyzer-for-active-storage/

require "timezone_finder"
require "exifr/jpeg"
class ExifJpegAnalyzer < ActiveStorage::Analyzer::ImageAnalyzer
  def metadata
    read_image do |image|
      if rotated_image?(image)
        { width: image.height, height: image.width }
      else
        { width: image.width, height: image.height }
      end.merge(gps_from_exif(image))
    end
  rescue LoadError
    logger.info "Skipping image analysis because the mini_magick gem isn't installed"
    {}
  end

  private

  def ref(gps_ref)
    %w[N E].include?(gps_ref) ? 1 : -1
  end

  def gps_from_exif(image)
    {}.tap do |hash|
      next unless image.type == "JPEG"
      next if image.is_a? ActiveStorage::Variant

      image_data = EXIFR::JPEG.new(image.path)
      if image_data.exif&.fields[:gps]
        latitude = image_data.gps_latitude.to_f * ref(image_data.gps_latitude_ref)
        longitude = image_data.gps_longitude.to_f * ref(image_data.gps_longitude_ref)
        time_zone = TimezoneFinder.create.timezone_at(lat: latitude, lng: longitude)
        date_time =
          "#{image_data.gps_date_stamp.split(":").join("-")} #{
            image_data.gps_time_stamp.collect(&:to_i).join(":")
          } UTC"
        hash[:latitude] = latitude
        hash[:longitude] = longitude
        hash[:altitude] = image_data.gps_altitude.to_f
        hash[:time_zone] = time_zone
        hash[:date_time] = date_time
      end
    end

  rescue EXIFR::MalformedImage, EXIFR::MalformedJPEG

  end
end

# https://api.rubyonrails.org/classes/ActiveStorage/Blob/Analyzable.html
Rails.application.config.active_storage
  .analyzers.delete ActiveStorage::Analyzer::ImageAnalyzer
Rails.application.config.active_storage.analyzers.append ExifJpegAnalyzer

```

これによりmetadataにGPS関連が入る。

```rb
YourModel.first.image.metadata 
# => {latitude: ..., longitude: ..., altitude: ..., time_zone: ..., date_time: ...}

# これで撮影時の現地時間が取れる
metadata = YourModel.first.image.metadata
Time.parse(metadata[:date_time]).in_time_zone(metadata[:time_zone])
```
Node.js+EJSとEXPRESSで簡単WEB開発

Node.jsにEJSとEXPRESSを入れればWEBサービス開発環境を簡単に準備できる。

#手順
- npm init
    - package.jsonが生成される。
- npm install ejs --save
    - EJS は "Effective JavaScript templating" の略語
- npm install express --save

あとは初期でこのあたりは入れておくと便利。

- npm body-parser --save
- npm cookie-parser --save
- npm install express-session --save

#Express-generatorを使えば瞬殺
Express-generatorを使えばこれらの手順を瞬殺で終えることができ、フォルダ構成もきちんと生成してくれる。

```
npm install express-generator -g
```

（-gオプションはグローバルインストールをするためのオプション。ライブラリをNode.jsのグローバル領域へインストールする）

###ひな形の作成

```
express --view=ejs
```
テンプレートエンジンにejsを使う指定しています。

###必要なライブラリ一括インストール

```
npm install
```
このようにライブラリ名を指定せずに実行すると、pakage.jsonのdependenciesに指定されているライブラリを一括インストールしてくれます。

これで実行。

```
npm start
```
app.jsが実行されhttp://localhost:3000  にて確認できる。
木構造のDFS（AtCoder Beginner Contest 138より）

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/08/25/110013)からの転載）

1週間遅れですが、ABCで木構造の問題が解けなかったので、2度同じ間違いを繰り返さぬようメモります。

#### 問題内容・解法

##### D - Ki
[D \- Ki](https://atcoder.jp/contests/abc138/tasks/abc138_d)
<img width="1104" alt="スクリーンショット 2019-08-25 10.38.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/2d568175-b292-1f32-8481-7072a27038a5.png">
問題文その通りの考え方をすると、以下のように計算されていくことになります（ピンクの丸が頂点id、白い丸が値）。
![図1_190825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/eddfc90c-e8c8-5efd-fc6d-7f978a100821.png)
しかし、このロジックのまま実装すると何度も下層に降りて和を計算する必要があるため、非効率です。
このようなケースの常套手段として、累積和をとる方法があります。図にすると以下のような考え方です。
![図2_190825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/d69c12fd-b429-8c0c-c614-b2c79728398c.png)
各頂点直下の頂点にのみ値を足し、足された値をまた直下の頂点に足すことで、結果的に問題文の指示通りの和が計算されることになります。

さて、このようにどんどん下層に降りていって和をとる問題なので、DFSを適用することになります。

コードは[@dn6049949さん](https://atcoder.jp/contests/abc138/submissions/6989207)のものを多少改変して転載しています。

```python
import sys
def LI(): return [int(x) for x in sys.stdin.readline().split()]

n,q = LI()

v = [[] for i in range(n)]
for i in range(n-1):
  a,b = LI()
  a -= 1 # listのindex参照をそのまま使いたいので頂点id(1から始まっている)を-1しておく
  b -= 1 # aと同様
  v[a].append(b)
  v[b].append(a)

f = [0]*n
for i in range(q):
  p,x = LI()
  p -= 1 # aと同様
  f[p] += x

def dfs(x,d,s): # x:計算する頂点（上側）, d:計算済み(0)か否か(1), s:頂点xの値
  for y in v[x]: # 頂点xとつながる各頂点yの計算を行う
    if d[y]: # 頂点yが計算未了の場合
      s += f[y] # 頂点xの値sに頂点yの値を足す
      ans[y] = s # 頂点yの値はsに確定
      d[y] = 0 # 頂点yの計算は終わったのでd[y]=0とする
      dfs(y,d,s) # 頂点yの下層についても再帰的に計算
      s -= f[y] # 頂点yの下層の計算が終わったので、sを頂点xの値に戻す

ans = [0]*n
d = [1]*n
d[0] = 0
ans[0] = f[0]
s = f[0]
dfs(0,d,s)
print(*ans)
```
wemosでモーターシールド

#概要

wemosでモーターシールドやってみた。

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8704cdc7-67b6-f12a-9994-471c272c591a.png)

#回路図



![moter.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a64fe4db-c4fd-6b11-e377-5f337270c185.jpeg)


#サンプルコード

```
#define LATCH 			12
#define CLK 			4
#define ENABLE 			13
#define DATA 			0
#define M1 				13
#define M2 				5
#define M3 				15
#define M4 				2
void setup()
{
	byte d = 0xff;
	Serial.begin(9600);
	while (!Serial)
	{
		;
	}
	Serial.println("\nstart");
	pinMode(LATCH, OUTPUT);
	digitalWrite(LATCH, HIGH);
	pinMode(ENABLE, OUTPUT);
	digitalWrite(ENABLE, LOW);
	pinMode(M3, OUTPUT);
	digitalWrite(M3, HIGH);
	pinMode(M4, OUTPUT);
	digitalWrite(M4, HIGH);
	pinMode(DATA, OUTPUT);
	digitalWrite(DATA, LOW);
	pinMode(14, OUTPUT);
	digitalWrite(14, LOW);
	pinMode(CLK, OUTPUT);
	digitalWrite(CLK, LOW);
	pinMode(M2, OUTPUT);
	digitalWrite(M2, HIGH);
	digitalWrite(LATCH, LOW);
	shiftOut(DATA, CLK, LSBFIRST, d);
	digitalWrite(LATCH, HIGH);
	Serial.println("ok");
}
void loop()
{
	if (Serial.available() > 0)
	{
		char ch = Serial.read();
		digitalWrite(LATCH, LOW);
		shiftOut(DATA, CLK, LSBFIRST, ch);
		digitalWrite(LATCH, HIGH);
		Serial.println(ch);		
	}
  delay(100);
}



```

以上。
連結リストについてまとめてみた

こんにちは、~~[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている者です~~（2020年1月退社）。
今回は、連結リスト（Linked list）について勉強したので、連結リストについてまとめてみました。

## 連結リストとは？配列（リスト）との違いは？

連結リストとは、各要素が一つ後ろや前の要素へのリンクを持っているリストのことです。
ある一つの要素にアクセスする際、配列（リスト）の場合、その要素に直接アクセスできます。
しかし、連結リストの場合は、最初の要素から順にリンクを辿ってアクセスせねばなりません。
また、配列のデータは、各要素の値だけです。
それに対し、連結リストのデータは、各要素の値に加えて、後（前）の要素へのリンクもあります。
そのため、連結リストは、同じ要素数の配列に比べてメモリを多く消費します。
しかし、要素を挿入したり削除する際、配列では後ろの要素を全てずらす必要があるのに対し、連結リストでは、その箇所のリンクを繋ぎかえるだけで済むので、時間を短縮できます。

まとめると以下の表のようになります。
||メリット|デメリット|
|----|----|----|
|連結リスト|要素の追加や削除にかかる時間が短い|要素へのアクセスの際に順にリンクをたどる必要あり|
|配列|要素を指定するだけですぐにアクセスできる|要素の追加や削除に時間がかかる|

## 連結リストの種類

連結リストには、単方向リスト（Singly-linked-list）、双方向リスト（Doubly-linked-list）、循環リスト（Circularly-linked list）の3種類があります。
それぞれのイメージは、以下の通りです。

- 単方向リスト：各要素が一つ後の要素へのリンクを持っているリストです。
head→3→7→4→
コードで書くと、
```python:
class Node():
    __init__(self, data, next=None):
        self.data = data
        self.next = next

    def set_next(self, next):
        self.next = next

class SinglyLinkedList():
    __init__(self, head=None):
        self.head = head

    def append(self, data):           #最後の要素の追加
        new_node = Node(data)
        if self.head is None:         #最初の要素の追加
            self.head = new_node
            return

        last_node = get_last_node()
        last_node.next = new_node

    def pop(self):                    #最後の要素の削除
        last_node = get_last_node()
        last_node = None

    def get_last_node(self):
        last_node = self.head
        while not last_node.next is None: #最後の要素のnextはNone
            last_node = last_node.next
        return last_node
```
といった感じでしょうか。

- 双方向リスト：各要素が一つ後と前の要素へのリンクを持っているリストです。
head⇄3⇄7⇄4→

- 循環リスト：各要素が一つ後の要素へのリンクを持っており、最後の要素は最初の要素へのリンクを持っているリストです。
3→7→4
↑←←↓

## 連結リストの用語

- node：要素の値（data part）と次の要素（や前の要素）へのリンク（address part）とをセットにしたものです。
- head：連結リストの一番最初のnodeへのリンクを表します。
- tail：連結リストの一番最後のnodeで、単方向リストと双方向リストでは、次のnodeへのリンクはnullになります。

## まとめ

今回は、連結リストについてまとめました。
私はまだまだプログラミング初心者ですので、間違いがあるかもしれません。
もし間違いがありましたら、修正しますので、ご指摘の方よろしくお願いいたします。
『現代数理統計学の基礎』の読書ノート、演習問題解説等参考となる記事のまとめ

『[現代数理統計学の基礎](https://amzn.to/2zlI4bj)』
<a href="https://www.amazon.co.jp/%E7%8F%BE%E4%BB%A3%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6%E3%81%AE%E5%9F%BA%E7%A4%8E-%E5%85%B1%E7%AB%8B%E8%AC%9B%E5%BA%A7-%E6%95%B0%E5%AD%A6%E3%81%AE%E9%AD%85%E5%8A%9B-%E4%B9%85%E4%BF%9D%E5%B7%9D-%E9%81%94%E4%B9%9F/dp/4320111664/ref=as_li_ss_il?ie=UTF8&linkCode=li2&tag=aokikenichi-22&linkId=6047f79d5e35003d388a428f8b63a620&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4320111664&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aokikenichi-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aokikenichi-22&language=ja_JP&l=li2&o=9&a=4320111664" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
が統計検定1級の準備にちょうどいいらしいが、演習問題が略解のみなどなかなか難しいらしい。読書ノート、演習問題の解説をしている記事を集めた。

# 著者のサポートサイト
[現代数理統計学の基礎](https://sites.google.com/site/ktatsuya77/xian-dai)

+ 章末問題略解
+ ベイズ統計に関する補足
+ 正誤表

# 読書ノート
## 読書ノート：現代数理統計学の基礎
+ [読書ノート：現代数理統計学の基礎](https://qiita.com/fred55/items/dc77a73ee3d11eaa0d11)
    + 1-4章
+ [読書ノート：現代数理統計学の基礎(その２)](https://qiita.com/fred55/items/e5e8410f25b85a0462de)
    + 5章 「標本分布とその近似」の確率収束の定義
+ [読書ノート：現代数理統計学の基礎(その３)](https://qiita.com/fred55/items/899163074b9ab3519795)
    + 6章 「統計的推定」演習問題の問16
+ [読書ノート：現代数理統計学の基礎(その４)](https://qiita.com/fred55/items/06401efc37540ed3500e)
    + 5章 「標本分布とその近似」
    + 6章 「統計的推定」
+ [読書ノート：現代数理統計学の基礎(その５)](https://qiita.com/fred55/items/08769bd1d9328a104ec1)
    + 7-8章

## [これからどうしようか？ 現代数理統計学の基礎](https://raytechnology.hatenablog.com/search?q=%E7%8F%BE%E4%BB%A3%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6%E3%81%AE%E5%9F%BA%E7%A4%8E)
+ [「現代数理統計学の基礎」第1章　確率](https://raytechnology.hatenablog.com/entry/2018/08/14/210823)
+ [離散一様分布](https://raytechnology.hatenablog.com/entry/2019/02/14/104844)
    + 現代数理統計学の基礎p29 離散一様分布(Discrete Uniform Distribution)について
+ [二項分布](https://raytechnology.hatenablog.com/entry/2019/02/15/100408)
    + 現代数理統計学の基礎p30 二項分布(binary distribution)の確率密度関数、平均、分散、確率母関数、積率母関数を求めていく。

# 演習問題の解説
## 現代数理統計学の基礎 演習問題解説
+ [現代数理統計学の基礎 演習問題1章 解説](https://qiita.com/strawhare_eng/items/55890052a6946f2c54f2)
+ [現代数理統計学の基礎 演習問題2章 解説](https://qiita.com/strawhare_eng/items/5546c77af41e2ea40cf7)

## [easy writing 現代数理統計学の基礎](https://thunderbirds555.hatenadiary.jp/archive/category/%E7%8F%BE%E4%BB%A3%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6%E3%81%AE%E5%9F%BA%E7%A4%8E)
+ 2019-08-24現在 第3章問12まである

# 『現代数理統計学の基礎』を用いた統計検定1級の勉強法

+ [文系で統計検定１級に合格した](https://hawkingh.hateblo.jp/?page=1514698727)
+ [1級合格者の声 機械学習に寄った分野、統計モデリングやベイズ統計学について勉強をしていきたい](http://www.toukei-kentei.jp/koe/koe-4623/)
+ [統計検定1級に合格しました](https://mt19.hatenablog.com/entry/2018/12/17/210900)
+ [【準備期間3か月】統計検定1級受験 数弱文系大学生編](https://zawalog.com/2018/08/04/%E3%80%90%E6%BA%96%E5%82%99%E6%9C%9F%E9%96%933%E3%81%8B%E6%9C%88%E3%80%91%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A1%E7%B4%9A%E5%8F%97%E9%A8%93-%E6%95%B0%E5%BC%B1%E6%96%87%E7%B3%BB%E5%A4%A7%E5%AD%A6/)
日銀レビュー検証Ⅰ 同時相関している？？ (最近の株価と為替の同時相関関係の強まりについて)

(日銀レビュー)最近の株価と為替の同時相関関係の強まりを参考にして、
自分でもpandasを活用して計算してみました。
まず、第1弾として「図表２ 株価と為替の同時相関」の様なグラフが自分でも描けるが、
公開されているデータから確認してみます。

グラフの傾向としては、大体合っているのかなとは思います。
が、、そもそもレビューの主旨である、「為替先行の相関係数より同時相関の相関係数が徐々に高く
なっていくんだ！」みたいなのは確認できませんでした。。。

もし、何かお気づきの点ございまいたら教えてください。

元記事（日銀）
https://www.boj.or.jp/research/wps_rev/rev_2013/rev13j08.htm/

全ソース
https://github.com/kaijiii/stock_price_analysis/blob/master/TopixDiffCorr.ipynb

【用意するもの】
　・TOPIXデータ（2000～2018）
　　　https://quotes.wsj.com/index/JP/TOPIX/historical-prices
　　　Wall Street Journalから取得。
　　　Investing.comでもTOPIXデータはあるが、古いデータは扱っていない。

  ・為替データ（2000～2018）
　　https://jp.investing.com/currencies/usd-jpy-historical-data

【処理内容】
　1)前処理
　
　日銀レビューでは恐らく、為替相場とTOPIXのデータは日本時間の終値を使用している。
　しかし、世の中でフリーで出回っている為替データはニューヨーク取引所のもので、
　TOPIXのデータはもちろん、日本の時間帯にものなので、
　それを合わせる処理を行う。
　
　具体的には、
　　・取得したcsvにタイムゾーンを設定し、両者を日本時間に合わせる
　　・日付でマージを行う
　　・TOPIXの始値と為替データの終値を使って2)の計算を行う
　
　2)Pandasの機能を用いて、500日間ローリング相関を行う
    　df.rolling(500).corr()

【結果】
　
　・日銀レビューでは～2012年頃まで、為替先行が同時相関より相関係数が高くなっており、
　　徐々に逆転していくという結果（ペーパーの主旨）になっているが、
　　私の計算だと常に同時相関の方が相関係数が高い

　・2000～2013年の間では、どちらの結果も為替先行、
　　同時相関の値は2008年がピークとなっており、その点は一致している
　
　・株価先行の値も00～10年はマイナスの相関だったのが、
　　近年はプラスの相関に若干触れているという傾向も日銀レビューと一致

![TOPIX-exchange.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486814/4d5c44bd-9480-8b67-e0dd-b23d714d8ca7.png)

※自分の計算結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486814/f7c9241e-2b59-4cbd-3c08-54ce4c6650ae.png)
　※日銀レビュー「図表２ 株価と為替の同時相関」から引用
Associate Cloud Engineer 取得時のメモ

先週GCPのAssociate Cloud Engineer(以下ACE)を取得したので、その時の勉強の仕方を記載しておきます。

#ACEの範囲
公式サイトに記載の通り[こちら](https://cloud.google.com/certification/cloud-engineer?hl=ja)から出題されます。
試験会場は東京都内にいくつかありました。
AWSと同じくPCに向かって答えをクリックして行う形式です。
試験の合否は試験終了後に出るので、とてもわかりやすいですね。

#勉強方法
AWSほど教本や資料が無いので、他の方の合格記を参考にしました。
主に教本と、公式リファレンス、Qwiklabsをやりました。

##教本
有名ですが、こちらの本を参考に全体のサービスを押さえました。
[GCPの教科書](https://www.amazon.co.jp/dp/B07S1LG1Y1/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

AWSのSAAだと教本だけでも学べるのですが、GCPだとコマンドも出てくるので、実際手を動かしてみた方が覚えられます。

##公式リファレンス

概要、やれること、選ぶ時の判断基準を勉強しました。特にNoSQLあたりは何種類もサービスがあるので、把握はマストですね。

##Qwiklabs
実践で弄ると覚えます。どういうシチュエーションでこのコマンドを使って対応するのか、という視点で学ぶと試験で役立ちます。
こちらに関してはGoogle Cloud Next'19で1ヶ月無料体験のチケットを頂いたので、存分に使わせて頂きました。

#勉強期間
20日間ほどです。
GCP自体は趣味で何となく1年ほどいじっていたので、画面がどんな感じなのか、とかは理解しているレベルからのスタートでした。

#試験を受けてみて
個人的には少し難しい印象を受けました。私自身業務でGCPを使い始めたところなのですが、Interconnectで専用線引いたり、VPC設計したりなど、まだGCE,GAE,GKEを使っている段階ではなかったためです。

これから取得しようとしてる人は、このシチュエーションならどのサービスを選定して、どういう順序で対応するのか、を意識して学ぶといいと思います。
またgcloudコマンドは使うので、コンソールでできること、コマンドでできることはざっくり押さえとくといいと思います。
ProgateのHTML&CSS中級編

未来電子テクノロジーでインターンをしています。Qiita投稿2回目です。
ProgateのHTML&CSS中級編で学んだことをまとめていきます。

##headerとfooter

```
<div class ="header"></div>
<div class=""top-wrapper"></div>
<div class="footer"></div>
```

↓HTML5では省略できる

```
<header></header>
<div class="top-wrapper"></div>
<footer></footer>
```

##背景画像を指定する
```
HTML
<div>
     <h1>title</h1>
</div>

CSS
div{ 
    height:200px;
    background-image:url;
   }
```

##背景画像の大きさ指定
```
div{
    background-size:cover;
    }
```

##要素を中央を配置する
```
.box{
     width:300px;
     margin:0 auto;
     }
```

##透明度、文字の間隔を調整しよう
```
opacity:0.5;
```

##文字の間隔を指定する
```
letter-spacing:2px;
```
webarenaでubuntu その30

#概要

webarenaでubuntu18.04やってみた。
apache2.4,php7.2やってみた。
ファイルアップロードやってみた。

#サンプルコード

```
<?php
	if (isset($_FILES["pngfile"]))
	{
		if (is_uploaded_file($_FILES["pngfile"]["tmp_name"]))
		{
			move_uploaded_file($_FILES["pngfile"]["tmp_name"], "./png/test.png");
			chmod("./png/test.png", 0644);
		}
?>
<html>
<head>
	<meta charset="utf-8">
	<title>upload</title>
</head>
<body>
	upload ok<br>
	<img src="./png/test.png">
</body>
</html>
<?php
	}
	else
	{
?>
<html>
<head>
	<meta charset="utf-8">
	<title>upload</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
	png file: <br />
	<input type="file" name="pngfile" size="30" /><br />
	<input type="submit" value="send" />
</form>
</body>
</html>
<?php
	}
?>
```


以上。
Unity備忘録 ～Unityちゃんになる～

## はじめに
この記事は8日前にUnityを触り始めた人の勉強メモです。過度な期待はしないでください。
誤った内容が含まれる可能性が多々あります。誤りに気付いた方は、コメントにて脇腹をつついてください。

### 雑手順
■床作成
「Hierarchy」で「Create-3D Object-Plane」を選択

■OVRPlayerController配置
「Project」の「Oculus-VR-Prefabs-OVRPlayerController」を「Hierarchy」にドラッグ＆ドロップ
「Hierarchy」の「MainCamera」削除

■Oculusトラッキング用オブジェクト作成
「Hierarchy」の「OVRPlayerController-OVRCameraRig-TrackingSpace」に頭、右手、左手用のオブジェクト作成

「OVRPlayerController-OVRCameraRig-TrackingSpace-CenterEyeAnchor」を右クリックし、「Create Empty」を選択
「GameObject」の名称を「HeadTarget」に変更し、選択
「Transform-Rotation」を「X：0、Y：‐110、Z：-60」に修正

「OVRPlayerController-OVRCameraRig-TrackingSpace-LeftHandAnchor-LeftControllerAnchor」を右クリックし、「Create Empty」を選択
「GameObject」の名称を「LeftHandTarget」に変更
「Inspector」の「Transform-Rotation」を「X：0、Y：90、Z：0」に修正

「OVRPlayerController-OVRCameraRig-TrackingSpace-RightHandAnchor-RightControllerAnchor」を右クリックし、「Create Empty」を選択
「GameObject」の名称を「RightHandTarget」に変更
「Inspector」の「Transform-Rotation」を「X：0、Y：90、Z：0」に修正

■Unityちゃん配置
「Project」の「unity-chan!-Unity-chan! Model-Prefabs-unitychan_dynamic」を「Hierarchy」の「OVRPlayerController」にドラッグ＆ドロップ

■UnityちゃんにVRIKアタッチ
「Project」の「Plugins-RootMotion-FinalIK-IK Components-VRIK」を「Hierarchy」の「unitychan_dynamic」にドラッグ＆ドロップ

「Hierarchy」の「unitychan_dynamic」を選択
「Inspector」の「VRIK(Script)-Solver-Spine-Head Target」に上で作成した「HeadTarget」をドラッグ＆ドロップ
「VRIK(Script)-Solver-Left Arm-Target」に上で作成した「LeftHandTarget」をドラッグ＆ドロップ
「VRIK(Script)-Solver-Right Arm-Target」に上で作成した「RightHandTarget」をドラッグ＆ドロップ
「VRIK(Script)-Solver-Left Leg-Swift Offset」を -70 に設定
「VRIK(Script)-Solver-Right Leg-Swift Offset」を 90 に設定
「VRIK(Script)-Solver-Locomotion-Foot Distance」を 0.1 に設定

■Unityちゃんのモーション関連調整
「Hierarchy」の「unitychan_dynamic」を選択
「Inspector」の「Animator-Controller」に設定されている「UnityChanARPose」を削除
「Inspector」の以下項目のチェックボックスを解除
　・Idle Changer（Script）
　・Face Update（Script）
　・Spring Manager（Script）
　・Randam Wind（Script）
　・Auto Blink（Script）

■OVRPlayerControllerのCharacter Controller調整
「Hierarchy」の「OVRPlayerController」を選択
「Inspector」の「Character Controller」の値を以下のように修正
　・Center　Y：0.775
　・Radius　0.2
　・Height　1.55

■OVRCameraRigの高さ調整
「Hierarchy」の「OVRPlayerController-OVRCameraRig」を選択
「Inspector」の「Transform」の値を以下のように修正
　・Posision　Y：1.36
　・Rotation　X；15

■固定カメラの設定
「Hierarchy」で「Create-Camera」を選択
「Inspector」の以下項目を変更
　・Transform-Posision　Y：0.85、Z：2.55
　・Transform-Rotation　Y：-180
　・Camera-Target Eye　None（MainDisplay）

疲れたので、一旦ここまで
同じポートにしても動かない（2019.08.30 訂正版）【Vagrant, PHPStorm, Xdebug】

## TL;DR

大いなる勘違いをしていたので訂正します。

~~Xdebugのポートは**9001**にするけど、PHPStomeのXdebug用ポート設定は**9000**のままにするんだ！~~
Xdebugのポートを**9001**にして、PHPStomeのXdebug用ポート設定も**9001**にするんだ！
9000番はphp-fpmが使っている可能性があるぞ！

## 環境

Vagrant: 2.2.0
ゲストOS: CentOS 7.6.1810 (Core)
Apache: 2.4.6
PHP: 5.6.38
Xdebug:2.5.5

ホストOS: Windows 10 Pro 64bit ver. 1903
PHPStorm：2019.2.1 RC
Pleiades: 2019.08.21
Chrome: 76.0.3809.100 (Official Build) 64ビット
Xdebug helper: 1.6.1

## 前提

- Vagrantの仮想環境にOS、Apache、PHP、Xdebugがインストール済み
- WindowsにPHPStorm、Chrome、Xdebuger helperがインストール済み
- ソースコードはゲストOSにホストOSと同じものをアップロード済み

## PHP の Xdebug 設定

Xdebugインストール時にphpのXdebug用設定ファイルが作成されたので、値を追記します。
php.iniへの追記でも大丈夫かもです（未検証）。

```ini:/etc/php.d/15-xdebug.ini
zend_extension = /usr/lib64/php/modules/xdebug.so ; Xdebugモジュールのパス
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = 192.168.33.1 ; デバッグ接続するPCのIPアドレス
xdebug.remote_port = 9001         ; デフォルトは 9000
xdebug.idekey = "PHPSTORM"`       ; PHPStormとのセッションクッキー名
```

## PHPStrom側の設定

1. メニューより[ファイル]→[設定]を開きます。
2. [言語 & フレームワーク]→[デバッグ]を選択します。
3. [Xdebug]→[デバッグ・ポート]の値をデフォルト値「9000」から~~**変更してはいけません**~~**「9001」に変更します**。iniファイルの`xdebug.remote_port`と合わせると~~うまく動作しなくなります~~うまく動作します！。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76242/c180ad72-94e0-f947-768d-6bfea1b26440.png)

4. [言語 & フレームワーク]→[サーバー]を選択します。[+]でサーバーを追加します。
    1. [名前]に本設定の名前を付けます。「vagrant_server」としました。  
    2. [ホスト]にドメイン or IPアドレスを入力します。「192.168.33.10」としました。Vagrantfileで設定しているものと同じIPアドレスです。
    3. [サーバ上の絶対パス]にVagrant仮想環境へアップロードした絶対パスを入力します。
5. メニューより[実行]→[構成の編集]を選択します。
6. 左上の[+]から、「PHP Remote Debug」を選択し、設定を追加します。
    1. [名前]に本設定の名前を付けます。「test_project」としました。
    2. [構成]→[サーバ]コンボボックスより先ほど作成したサーバー「vagrant_server」を選択します。
    3. [構成]→[Ide キー（セッション id）]にiniファイルで指定した「PHPSTORM」を入力します。ダブルクォーテーション（"）は不要です。

## Xdebug helperの設定

1. Chomeのメニューより[設定]→[機能拡張]を選択します。
2. Xdebug helperの[詳細]→[機能拡張のオプション]を選択します。設定画面が開きます。
3. [IDE Key]の「Eclipse」を「PhpStorm」に変更し、IDEキーを「PHPSTORM」に変更します。
4. [Save]ボタンをクリックして保存します。

------

以上の設定でブレークポイントが機能します。
~~Xdebugのポート番号とPHPStomeのポート番号を一致させると動かないとか意地悪ですねぇ…~~

私がどうかしてました。ガセ情報を流してスミマセン。😓

## 謝辞

本記事は @atchy@github 様の記事「[Vagrantに構築した環境へPHPStorm + Xdebug でデバッグする](https://qiita.com/atchy@github/items/2a3ece955a50d4dace8e)」を参考に作成されました。
ありがとうございます！
Attended/Unattended Robotという考え方、ライセンスについて

初投稿です。RPAにかかわり始めてからRPAで効率性を高めROIを追求する方法を調べているが、その中でもライセンスについて不思議な概念があったのでメモしておく。RPAベンダーによってAttended/Unattended Robotという考え方をしており、UIPath社とAutomation Anywhere社が2つの概念を両方提供している。


* Attended(アテンディット/デスクトップ型/人間主導型) - 従業員のデスクトップ内にインストールし、従業員の操作により動作するロボット
* Unattended(アンアテンディット/サーバ型/ロボット主導型) - サーバー内の仮想マシンでも動作し、従業員による操作が不要なロボット。独立して常時稼働が可能なロボット。


UIPath社

* [さまざまな自動化シナリオに対応するUiPath Robots](https://www.uipath.com/ja/blog/corporate/uipth-robots) - 「Attended RobotsをサーバーOSに導入することも、Unattended RobotsをクライアントOSに導入することも可能です」とのこと。
* [ライセンシングについて](https://docs.uipath.com/robot/lang-ja/docs/about-licensing)
* [RPA 2019: Hidden UIPath RPA Pricing](https://ui.vision/blog/uipath-pricing/)

Automation Anywhere社

* [AttendedとUnattendedの違い](https://www.automationanywhere.com/jp/solutions/attended-vs-unattended-rpa)
* [ライセンス概要](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/control-room/administration/licenses/license-overview.html) - Attendedでも「ローカル スケジュールやトリガーを使用して、時間やイベントに基づくオートメーションを実行することもできます」とのこと。

BluePrism社　--> Unattended Robotのみ

# ライセンス費用
ライセンス費用は両社ともAttendedの方が安く、UnattendedはAttendedの3～6.5倍程度高いようである。費用を考えるうえでこの差は大きい。権限的には、サーバからタスクが起動できるか、スケジュールできるか、負荷分散する仕組みがあるか、管理できるか、などが違うのだろうが、従業員がリモートログインしておきAttendedライセンスをOSのタスクスケジューラ等別の仕組みで起動してはだめなのだろうか。従業員がリモートデスクトップを業務で主に使用している場合はどうなるのか。ドキュメントには両社とも明確な記載はなく、明確な禁止事項も記載がないので、問い合わせるしかないのだろうか。

**補足**: Attended, Unattendedは、つまるところ「**ユーザーライセンス**」「**デバイスライセンス**」と同等の概念のようである。Attendedは人間ユーザーがログインして一緒に使うことが前提、人間ユーザーと一緒に利用する利用形態、Unattendedはデバイスと紐づいていて人間ユーザーがログインしていなくても24時間に近い稼働を実現できる利用形態である。故にUnattendedのほうが高額な値付け設定がされているようである。

# Named User, Concurrent User
また、別の概念としてユーザーを特定する場合、同時接続数でみる場合などもバリエーションがある。業務形態によって使い分けが必要なようだ。
gitで空コミットを行う方法

### WIPフローを用いて開発する際の覚書
WIPのプルリクを発行する最初のコミットや、親のコミットとの差分が無い状態で始めたいときに使ってます。
差分をステージングせず`git commit`に`--allow-empty`を付与するだけでおk。
以下コマンド例

```shell
git commit -m "init" --allow-empty
```
First

初めての投稿
처음 만든 글

はじめまして。ka373と申します。
実は韓国人です。うああ最近日韓関係悪いですね！
しかし、人対人としては仲良くしたらと思います。

なんか、日本のITのプロさんたちは、これ使っている方が多いらしいですね :)
私もコミュニケーションしたいと思ってアカウント作ってみましたが、まだ仕組みなど知らないことばかりです。
一旦、初めての投稿として書いてみましたが・・・

プロフィル写真は韓国の献血のキャラクターです。
献血という活動に共感して結構してきたし、キャラクターも可愛いと思います。
そして、赤と白から日本を連想することも？

それでは、どうぞよろしくお願いいたします。

【Blog】
■日本語：
https://ka373.blogspot.com

■韓国語：
https://ka373.tistory.com

【GitHub】
https://github.com/ka373
webarenaでubuntu その29

#概要

webarenaでubuntu18.04やってみた。
mysql5.7やってみた。
to_charがない。

#to_charでエラー

```
to_char(atime, 'YYMMDDHH24MI')
```

#date_formatで代替

```
DATE_FORMAT(atime, '%y%m%d%H%i')
```

以上。
ssh -T git@github.comしたらタイムアウトする

## 問題
`ssh -T git@github.com`でsshキーの確認をしようとしたら、

```
❯ ssh -T git@github.com
ssh: connect to host github.com port 120: Connection timed out
```

とかわけのわからないことを言われる。

### 環境
Raspbian GNU/Linux 9 (stretch)

## 原因
`/etc/ssh/ssh_config`をのぞいてみると、`Host *`の下のところになぜか`Port 120`があったので、それをコメントアウト。

ちなみに、`ssh -v <args>`でデバグできます。
【PowerApps】カメラで撮った画像をSharePointリストに保存し、他のアプリで見る。

# 今回やろうとしている事
アプリで写真を撮ってそれを他のアプリで見えるようにする事はいろんな業務改善で応用が出来ます。

ちょっと前に同じ事をして最後はうまく行ったのに、今回またやろうとしたらまた大ハマりしたので、ここに記録しておきます。

実現する事は単純でアプリにカメラコントロールをつけてそれで撮った画像をSharePointリストに保存して、他のアプリからその画像を出力します。

PowerAppsのアプリ以外で出力する必要がないのでMS Flowとかは使わずにPowerAppsとSharePointリストだけで完結します。

PowerApps界でお馴染みの@h-nagaoさんの記事も参考にさせて頂きました。ありがとうございました。

「#PowerApps SharePointリストへのカメラ画像アップロード (Flowなし & 添付ファイルなし)」
https://qiita.com/h-nagao/items/15b4bb3ac66abb04d944

@h-nagao さんも仰っていますが、これが一番シンプルなやり方でしょう。

# ポイントはSharePointリストの保存先の設定の仕方
自分がハマった原因はSharePointリストの設定が不十分だった事です。
画像を保存する列の種類を「複数行テキスト」にはちゃんとしてたけど、**その下の「書式なしテキスト」にする必要がありました。それを見つけるのに数時間を費やしました。**:frowning2:

![SP List Setting for Image URL.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403091/0c4eefa5-d919-1b5c-4fcd-87e751c7d339.jpeg)

# SharePointリストに画像を保存する。
提出ボタンのOnSelect属性に下の式を入れました。

```ruby:OnSelect属性
   Patch(
        Tbl_Statement_Submission,
        {Title: Blank()},
        {
            Title: (Last(Tbl_Statement_Submission).Title + 1) & "",
            Submitted_Date: Now(),
            Submitted_Date2: Value(Text(Today(),"[$-en-US]yyyymmdd")),　　　//この列は「委譲」用に使用します。
            Submitter: User().FullName,
            Image_URL: Camera1.Photo,
            Status: "提出済み"
        }
    )
```

Patch関数でSharePointにあるTbl_Statement_Submissionというリスト内に新しいレコードを追加しています。
Image_URLの列が「複数行テキスト」の種類で「書式なしテキスト」にしておく必要があります。

SharePoint上で見ると画像ではなくとても長い文字列が保存されているだけですが、他のスクリーンや他のアプリからこの列を画像コントロールのImage属性で参照するとちゃんと画像が出てきます。

参考までに下記の式で単純に画像コントロールを挿入したギャラリー内でSharePointリストに保存した画像を一覧表示しています。

```ruby:ギャラリーのItems属性
     Tbl_Statement_Submission
```

```ruby:画像コントロールのImage属性
     ThisItem.Image_URL
```
競プロでつまづいた、桁が多い同士の掛け算のオーバーフロー問題(備忘録)(かなり初歩的です)

# 掛け算のオーバーフロー問題
競プロの復習をしている際に、9桁×9桁の計算でそれを1e9+7の余りを出すという問題があった。
9桁では1e9+7であらかじめ余りを出すことはできず、for文で一つずつ足すことも考えたが9桁分(10億回)ループを回すのはあほらしい。
## 何が原因だったか
わかれば滅茶苦茶簡単な理由だった。
今までプログラムを書いてきて、ほとんどintで済ませてきていたため、今回の問題もintで進めていた。
intの最大値は約2.1e9なので、もちろん9桁同士の掛け算はオーバーフローを起こす。

## 解決方法
解決方法は単純明快、intを使わなければいいだけの話。
intからlong long intに型を変更した。
long long int型は最大値が約9.2e18なので9桁同士の掛け算は余裕ですることができる。
型を変更したことで、簡単に答えを出すことができた。

# 結果
普段使わない型もしっかりと把握しておけば問題ない。

こんな簡単なことに数時間気付かなく恥ずかしい...
PhpStormで"Plugin 'gherkin'  failed to initialize  and will be disable."みたいなエラーが表示されたら

# エラーの内容
PhpStormをアップデートしたら、Codeceptionプラグインが停止していたので、有効化して再起動。

すると以下のようなエラーが発生。

```
Plugin 'gherkin' failed to initialize and will be disable. Please restart Intellij IDEA
```

思い返すと、アップデート直後にもエラーが出てたけど、再起動したらエラーが出なかったのでスルーしていました。

Codeceptionを使おうと思ったら、上述の通りエラー再発。

# ネットの情報 & TRIAL
ネット上には、ほとんど情報がなく、唯一みつけたのが、以下のツイート。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/phpstorm?ref_src=twsrc%5Etfw">@phpstorm</a> after the latest upgrade:<br><br>Plugin &#39;gherkin&#39; failed to initialize and will be disabled. Please restart IntelliJ IDEA. <br><br>PicoPluginExtensionInitializationException: Duplicate registration for EP: original plugin cucumber, new plugin gherkin <a href="https://t.co/h6BgwrQxCh">pic.twitter.com/h6BgwrQxCh</a></p>&mdash; Dalibor Karlović (@dkarlovi) <a href="https://twitter.com/dkarlovi/status/1129271441923428353?ref_src=twsrc%5Etfw">May 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

公式の回答ツイートもあり。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="en" dir="ltr">By saying latest update you mean 2019.1.1 &gt; 2019.1.2? Please try to download a package from <a href="https://t.co/PpZh9od0Bo">https://t.co/PpZh9od0Bo</a> &amp; install it manually.</p>&mdash; JetBrains PhpStorm (@phpstorm) <a href="https://twitter.com/phpstorm/status/1131563757702995968?ref_src=twsrc%5Etfw">May 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

これに従って、PhpStormを再インストールしてみるも、うまく行かず。

エラーによればGherkinプラグインに問題ありという事なので、Gherkinを無効化したり有効化してみたり、いろいろ試すも、うまく行かず

# そして、SUCCESS
最終的に、PhpStormでGherkinプラグインを検索してみたところ、Jetbrains版とbundled版の２つがあったので、Jetbrains版を停止してbundled版に切り替えたところ、エラーも消えて、Codeceptionプラグインも無事有効化することができました。

公式回答の再インストール策でも、プラグインの設定も含めて再インストールしていれば、解決していたかもしれませんが、再インストールすると結構時間取られるので、最小限で解決してよかったです。


# まとめ
原因はPhpStormのアップデートだったのか、ダウンロード版PhpStormを削除してToolbox版のPhpStormに切り替えなんかもしてたので、その辺が原因だったのかもしれません。

どこかのタイミングでbundled版からJetbrains版のGherkinプラグインに切り替わってしまっていたようです。

Codeceptionプラグインはbundled版のGherkinプラグインに依存しているようです。

同様のエラーが出ている場合は、対象プラグインを検索して、複数ある場合は切り替えるとうまく行くかもしれません。
Lookerで２軸グラフを作成する方法

Lookerで可視化するときに、2軸グラフを作成する方法の紹介です。

覚えると、単純ではあるんですが、初めて作成してしばらくたってから、もう1回やろうとしたら、あれ？これどうやって作ったんだっけ？的な感じになったので、メモとして残します。


##やりたい事
Lookerで2軸グラフを作成する

##作業手順
 **DIMENSION**を１つ以上、**MEASURE**を２つ以上選択してから **Run** でグラフを表示する
![looker2軸グラフ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/b327f745-9c0d-8750-5de4-eadfb1784ca4.png)

**VISUALIZATION** の **EDIT** をクリックし、**Seriesタブ**を選択
**CUSTOMIZATIONS**に**MEASURE**項目名があるため、そこから２軸にしたいものを選択し、**Type**を
Column→LINEなどに変更する
![looker2軸グラフ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/3960abb9-8c1f-ff13-7cfc-f99e8ed0aec9.png)
![下矢印.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/eb38374d-e49a-6d5a-7b35-52bca2a46d18.png)
![looker2軸グラフ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/3b59c5b8-922e-476a-3d4c-cd25123d1261.png)

**Yタブ** の **LEFT AXES** にある項目を **RIGHT AXES** へ **ドラッグ＆ドロップ**する
![looker2軸グラフ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/379575a9-3d93-5d7d-d69d-ae8e1f59ca70.png)
![下矢印.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/eb38374d-e49a-6d5a-7b35-52bca2a46d18.png)
![looker2軸グラフ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/b25f14c8-0f5a-e80e-4e3b-dbc3a0eb1ffd.png)

##まとめ
今回は、Lookerでの2軸グラフの作成手順を紹介させていただきました。
**EDIT**の部分からは他にも軸の高低を変更したり、色を変えたり、表記をローマ字→日本語に変えたり等も可能ですので、いろいろ試してみてください。良い発見があるかもしれません。

そして、作った後にいうのもなんですが、**2軸グラフは左右で軸の高さが異なる場合、データを誤認させてしまう可能性もある**といわれている為、2軸にする意味がある情報以外には、あまり利用しない方がよいです。

その場合、**1軸で複数のLookerを用意する**事で、同じようにデータを比較する感じになります。
RealsenseでSLAM, visual odometry

ロボットの自己位置推定を行う際に必要なSLAMをrealsenseで実現する。
Odometryはロボットの移動量を様々な方法で計算する手法。
SLAMは周囲の環境の地図作成とロボットの自己位置を推定するアルゴリズム。

# 環境
* Ubuntu 18.04
* ROS melodic
* Intel realsense D415

# 準備
ROSやRealsenseのインストールの方法は以前に書いたとおり。
https://qiita.com/kei_mo/items/c0387b7d277948451881

Visual odometry, SLAMに必要なrtabmap(http://wiki.ros.org/rtabmap_ros) 等のパッケージをインストールする。
RealsenseのSLAM with D435i(https://github.com/IntelRealSense/realsense-ros/wiki/SLAM-with-D435i) を参考にインストール。
使っているのがROS melodcicであるためその部分を変更した。

```bash
sudo apt-get install ros-melodic-imu-filter-madgwick
sudo apt-get install ros-melodic-rtabmap-ros
sudo apt-get install ros-melodic-robot-localization
```
# SLAMの実行
SLAMを実行する。

```bash
roslaunch realsense2_camera　opensource_tracking.launch
```

rtabmapから実行する方法もある
https://qiita.com/k65c1/items/0d9039c021ecbb26b04e

# Visual odometryのみ行う。
計算資源が少ない等、SLAMは重すぎる場合は、visual odometryのみ行うことができる。
このためにはlaunch fileを自分で作っていく。
*Launch fileはROSのノードをまとめて立ち上げるためのファイル。

### パッケージの作成
まずはパッケージをつくる。
パッケージは以下のコマンドで作成できる。
`catkin_create_pkg [package名] [依存package名1]　[依存package名2] …`

```bash
cd ~/catkin_ws/src
catkin_create_pkt visual_odometry std_msgs rospy roscpp rtabmap
```
*依存パッケージは上記で十分だが必要条件ではないかも

###Launch fileの作成
Launch fileは慣例的にlaunchディレクトリの作成に作る。

```bash
cd ~/catkin_ws/src/visual_odomety
mkdir launch
cd launch
touch run_visual_odometry.launch
```

run_visual_odometry.launchの中身は次のとおりにする。

```xml
<launch>
   <node pkg="rtabmap_ros" type="rgbd_odometry" name="visual_odometry" output="screen">
   <remap from="rgb/image"       to="/camera/color/image_raw"/>
   <remap from="depth/image"     to="/camera/depth/image_rect_raw"/>
   <remap from="rgb/camera_info" to="/camera/color/camera_info"/>
   <param name="frame_id"    type="string" value="camera_link"/>
   <param name="publish_tf"  type="bool"   value="false"/>
   </node>
</launch>
```
ポイントはpublish_tfをfalseにするところ。

###ビルド

```bash
cd ~/catkin_ws
catkin_make 

source devel/setup.bash
```

###実行
Terminal 1 realsenseを立ち上げる。

```bash
roslaunch realsense2_camera rs_camera.launch
```

Terminal 2 visual odometryを立ち上げる。

```bash
roslaunch visual_odometry run_visual_odometry.launch
```

###Topicの確認
Terminal 3

```bash
rostopic list
```
`/rtabmap/odom`がpublishされていることがわかる。!

ノードの確認

```bash
rosgraph
```
![visual_odometry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190972/63846341-11cb-e387-f7d4-024560fb88a3.png)

# その他
* 計算資源が少なく処理を軽くしたい場合はパラメータを調整して処理を少し軽くすることもできる
http://wiki.ros.org/rtabmap_ros/Tutorials/Advanced%20Parameter%20Tuning#Increase_Speed
ZEIT NOWにNuxtをデプロイする

# 概要
色んな経緯があって友人のお店のWebサイトを改修することになった。
Nuxtで作成されたWebサイトを[Zeit Now](https://zeit.co/)にデプロイする方法をメモ代わりに残しておく

# 前提
Nuxt 2.8.0

# 参考サイト
[now-builder](https://github.com/nuxt/now-builder)
[Nowの日本語手順](https://jpn.now.sh/)

# デプロイ手順

### 1. rootディレクトリに`now.json`を作成し、下記のように記載する

```now.json
{
  "version": 2,
  "builds": [
    {
      "src": "nuxt.config.js",
      "use": "@nuxtjs/now-builder",
      "config": {}
    }
  ]
}
```

### 2. Now CLIをインストール

```
npm install -g now
```

### 3. Zeitアカウント作成

[ここで作成する](https://zeit.co/signup)

### 4. NowCLIでログインする

```
$ now login
> We sent an email to XXXXXX@gmail.com. Please follow the steps provided
  inside it and make sure the security code matches Valuable Tasmanian Devil.
✔ Email confirmed
> Ready! Authentication token and personal details saved in "~/.now"

```

### 5. Nowにデプロイする

```
$ now
> Deploying ~/dev/maynewyork under mh52124
> Using project maynewyork
> Synced 6 files (437.46KB) [2s]
> https://XXXXX-XXXXXXX.now.sh [v2] [991ms]
> Ready! Deployed to https://XXXXX.XXXXXXX.now.sh [in clipboard] [2m]

```

これだけでWebサイトを公開できたので非常にかんたん

# 補足

## Github連携

[Zeit Nowのアカウントページ](https://zeit.co/account)のSettingで連携の設定を行う

指定のリポジトリを設定してあげれば、masterブランチにpushされた時点で自動でデプロイしてくれる！！
かなりかんたんで便利

## 独自ドメイン

独自のドメイン設定するには下記のコマンドでできるらしい

```
now domains add □□□.com
```

実行したら下記のメッセージが出てきたのでその通りにやったら独自ドメインの反映も完了

```
> Success! Domain meynewyork.com added correctly. [3s]

> WARN! The domain was added but it is not verified. To verify it, you should either:
  a) Change your domain nameservers to the following intended set: [recommended]

     Intended Nameservers    Current Nameservers
     a.zeit-world.co.uk      b.zeit-world.co.uk     ✘
     d.zeit-world.org        d.zeit-world.org       ✔
     e.zeit-world.net        e.zeit-world.com       ✘
     f.zeit-world.com        f.zeit-world.net       ✘

  b) Add a DNS TXT record with the name and value shown below.

     name        type        value
     _now        TXT         QmUXnkuCvQecaRGLn3wHHaSpDBLw282LaUArVw5r334QEx

  We will run a verification for you and you will receive an email upon completion.
  If you want to force running a verification, you can run `now domains verify <domain>`
  Read more: https://err.sh/now-cli/domain-verification

```
AWS EC2でLaravel6.0を入れる手順　AWS/Laravel6.0連載(2)

# EC2インスタンスを立てる

前回の記事に引き続き、こちらを参考にEC2インスタンスを立てます。

参考：AWS EC2でWebサーバーを構築してみる
https://qiita.com/Arashi/items/629aaed33401b8f2265c

# PHP7.2、PHP拡張を入れる

yumでPHPをそのまま入れると5.4と古すぎるバージョンが入ります。
LaravelはPHP7系（Laravel5.8ではPHP7.1.3以上）です。

```shell-session
$ sudo amazon-linux-extras install php7.2
$ sudo yum -y install php php-devel php-bcmath php-ctype php-json php-mbstring php-openssl php-pdo php-tokenizer php-xml php-zip
$  php -v
```

```shell-session
$ PHP 7.2.19 (cli) (built: Jun 12 2019 20:39:39) ( NTS )
$ Copyright (c) 1997-2018 The PHP Group
$  Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

参考：Amazon Linux 2でPHP7.2をインストールする
https://qiita.com/owlbeck/items/20f3e5402cb782f6291e

# Composerを入れる

ComposerはPHPのパッケージ管理システムです。

```shell-session
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
$ composer --version
```

うまくインストールできているとこんな感じの表示です。

```shell-session
$ Composer version 1.9.0 2019-08-02 20:55:32
```

# Laravel6.0を入れる

以下公式ドキュメントに従ってインストールします。

Laravel
https://readouble.com/laravel/6.0/ja/installation.html

```shell-session
$ composer global require laravel/installer
```

laravelインストーラが入ったのでパスを通します。

```shell-session
$ vi ~/.bashrc
```

以下追加し保存

```vim
export PATH="~/.config/composer/vendor/bin:$PATH"
```

.bashrcはターミナル次回起動時に反映されるので、即時反映させる。

```shell-session
$ source ~/.bashrc
$ laravel -V
```

コマンドが見つからない場合はパスが間違っているはずです。
成功すると以下のようなメッセージが出ます。

```shell-session
$ Laravel Installer 2.1.0
```

では、公式ドキュメントに沿ってblogというアプリケーションを作ります。
ホームディレクトリに置くのは気持ち悪いので、/var/www/に配置します。

```
$ cd /var/www
$ sudo chown -R ec2-user:apache /var/www/
$ sudo chmod -R 770 /var/www/
$ laravel new blog
$ chmod -R 777 /var/www/blog/storage
$ chmod -R 777 /var/www/blog/bootstrap/cache
```

※本来パーミッションやオーナーはec2-userや777じゃなく適切なものを指定すべきですが、ここでは動作を最優先にしているので割愛します。

Laravelインストーラのバージョンは確認しましたが、Laravel自体のバージョンも確認してみましょう。

```powershell
$ php artisan -V
Laravel Framework 6.0.3
```

Laravel6.0系が入っていることが確認できました。

# Apacheの設定変更

```shell-session
# vi /etc/httpd/conf/httpd.conf 
```

DocumentRootで調べて書き換え。
また、そのディレクトリのAllowOverride Allを追記し保存します。

```
...

DocumentRoot "/var/www/blog/public"

...

<Directory "/var/www/blog/public">
    AllowOverride All
</Directory>
```

Apacheの設定変更後は再起動。

```shell-session
# service httpd configtest
# service httpd graceful
```

これでアクセスした際にLaravelが表示されます。
サクッとDockerでPySparkを試してみる

# 本記事の背景・目的・対象者
昨今、機械学習やAIを始め様々な事業においてデータ活用の重要度が増しています。データ活用するにあたって必要になってくるのが、以下の4点です

1. データを集めること
2. 集めたデータを解析しやすいように変換・保存すること
3. 解析しやすくなったデータを解析すること
4. 解析したデータをわかりやすく表示すること

2の**集めたデータを解析しやすいように変換・保存すること**をETL(Extract Transform Load)と呼び、いわゆるデータ基盤エンジニアのメインとなる仕事がこの部分です。

このETLに非常に適したフレームワークがPySparkです。本記事においてはこのPySparkをとにかく楽に簡単に手元で動かしてみることを目的とします。詳しい仕組みについての説明はここではしません。

従って本記事の対象者はこれからデータ基盤エンジニアを目指す人や目指すかどうかはおいといてデータ基盤エンジニアの仕事に興味がある人やとにかくPySparkをいじってみたい！という人を対象としています。

# PySparkとは
PySparkとはApach SparkのPython版です。
Apach Sparkとはすごくザックリいうといい感じにメモリを使う分散処理システムです。AWSがこのSparkと色々な独自の便利機能を組み合わせてすごく便利にETLを行えるGlueというリソースを提供しています。


もっと具体的にSparkのことについて知りたい方は[こちら](https://qiita.com/Hiroki11x/items/4f5129094da4c91955bc)をご覧下さい。

# 準備
big-data-europeという団体が提供しているDockerイメージを用いてPySparkを試してみるのが非常に楽で簡単です。[こちら](https://github.com/yuma300/docker-pyspark-try)にbig-data-europeが提供するDockerイメージとPySparkのインストールやサンプルコードまでセットになったリポジトリを用意しておきました。

```
$ git clone git@github.com:yuma300/docker-pyspark-try.git
$ cd docker-pyspark-try
$ docker-compose up -d
$ docker exec -it spark-master bash
```

これで準備完了です。あとは試してみるだけです

# 実行

準備の段階でコンテナイメージの中に入っているので、そのまま以下を実行します

```
# cd home
# python setup.py install
# python sample.py
```

するとサンプルコードのsample.pyが実行され PySparkにより以下が画面に出力されます

```
+---+-------+                                                                   
| id|   name|
+---+-------+
|  1|  spade|
|  2|   hurt|
|  3|   club|
|  4|diamond|
+---+-------+
```

以上で終了です。これでとにかくPySparkを実行する環境は整ったのであとはプログラムさえ書ければPySparkを用いたETLスクリプトの開発が出来るようになりました。

# 採用目的

現在私が所属するbitbankではデータ基盤エンジニアの採用を行っております。興味を持たれた方は是非下からご応募よろしくお願いします。

https://career.bitbank.cc/engineer-data
JavaScript の関数宣言、関数式、アロー関数式、Function コンストラクタの違い

JavaScript では関数もオブジェクト。関数オブジェクトの作成方法には、Function コンストラクタ、関数宣言（function declaration）、関数式（function expression）があり、関数式には従来の関数式とアロー関数式（arrow function expression）がある。

関数宣言は、昔はよく使われたけれど、今では使わないほうがいいと思う。アロー関数式は関数式の糖衣構文ではないので注意。Function コンストラクタの使用は推奨されない。

## 関数宣言
文（statement）が `function` で始まると関数宣言となる。関数宣言は `}` で終わる文なので、末尾にセミコロンを**つけない**。

関数宣言は、`var` と同様に巻き上げ（hoist）られるので、宣言の前に使うことができる。

```js
sum = plus(3, 2);
console.log(sum); // 5
var sum;
function plus(x, y) {
  return x + y;
}
```

## 関数式
関数式は関数オブジェクトを返す式。これも `}` で終わるけれど、これ自体は式なので、文の末尾にセミコロンを**つける**。

普通は無名の関数オブジェクトを作成する。変数に格納すると、変数名を使って関数を呼び出せる。

```js
let sum;
const plus = function(x, y) {
  return x + y;
};
sum = plus(3, 2);
console.log(sum); // 5
```

ほかの関数に引数として渡すこともよくある。

```js
let sum;
sum = [3, 2].reduce(function(x, y) {
  return x + y;
});
console.log(sum); // 5
```

即時実行関数式（Immediately Invoked Function Expression: IIFE）も作れる。関数宣言にならないように、`function` の前に何かつける

```js
(function(x, y) {
  console.log(x + y);
})(3, 2); // 5

!function(x, y) {
  console.log(x + y);
}(3, 2); // 5
```

関数式でも関数に名前をつけることができる。自分自身を再帰的に呼び出す場合などに使う。関数名のスコープは関数自体であることに注意。

```js
const f = function(n) {
  return 0;
};
const factorial = function f(n) {
  return n > 1 ? n * f(n - 1) : 1;
};
console.log(f(5)); // 0
console.log(factorial(5)); // 120
```

## アロー関数式
アロー関数式を使うと、関数式を短く書ける。

```js
let sum;
const plus = (x, y) => {
  return x + y;
};
sum = plus(3, 2);
console.log(sum); // 5
```

この例のように関数の本体が 1 つの `return` 文だけなら、さらに短く書ける。

```js
let sum;
const plus = (x, y) => x + y;
sum = plus(3, 2);
console.log(sum); // 5
```

引数が 1 つの場合、引数を囲む括弧を省略できる。

```js
const isEven = x => x % 2 === 0;
console.log(isEven(2)); // true
```

アロー関数式は関数式の短縮形**ではない**。もっとも重要な違いは `this` が束縛（bind）されないこと。

```js
this.x = 0; // this はグローバルオブジェクト
const object1 = {
  x: 1,
  log: function() {console.log(this.x);}
};
const object2 = {
  x: 2,
  log: () => {console.log(this.x);}
};
object1.log(); // 1（this は object1）
object2.log(); // 0（this はグローバルオブジェクト）
```

jQuery でアロー関数式を使うときは注意。

```js
$('input').on('click', function() {
  const width = $(this).width(); // this は input 要素
  console.log(width); // クリックされた要素の幅
});
$('button').on('click', () => {
  const width = $(this).width(); // this はグローバルオブジェクト
  console.log(width); // ブラウザウィンドウの幅
});
```

## Function コンストラクタ
`Function` コンストラクタで関数オブジェクトを作成するには、引数の名前と関数の本体を文字列として渡す。

```js
let sum;
const plus = new Function('x', 'y', 'return x + y;');
sum = plus(3, 2);
console.log(sum); // 5
```

なお、`new` は省略できる。作成される関数オブジェクトのスコープは常にグローバル。

```js
const x = 0;
(() => {
  const x = 1;
  const logger1 = function() {console.log(x);};
  const logger2 = Function('console.log(x);');
  logger1(); // 1
  logger2(); // 0
})();
```

関数を動的に生成できるという利点はあるが、パフォーマンスは関数宣言や関数式に比べて劣る。
JavaScript の個人的なメモ

# 前置き

こんにちは、2記事目ですね。
最近になって JavaScript を勉強し始めた、プログラミング初心者の @mt_tai です。

今回は、JavaScript を勉強し始めて個人的に新鮮に思ったことを書いていきます。
と言いましても、まだ勉強を始めて1週間と経っておらず、知らないことの方が圧倒的に多いため、
周知の事実をさも新発見のごとく書いてしまうかもしれませんが、そこは初心者を免罪符に許してもらえたらと。

# JavaScriptの '型' について

今回 JavaScript を学習するにあたって、変数宣言の時点でいきなり言語間の壁にぶち当たりました。
というのも、例えば javaScript で変数宣言の一例を挙げると

```javascript:sample1.js
var num = 256;
var string = "Hello World!";
```

のように宣言できるわけです。え？ 何もおかしくない？ そうですね。
でも私はこれを見て思ってしまったんです。

「型の宣言はどこ？」

これには私の学習経歴が関係してまして、今までで学習したことのあった言語が**C言語**だったんですね。
ちなみにC言語で同じように宣言する一例を挙げさせてもらうと

```c:sample1.c
int num = 256;
char string[] = "Hello World!";
```

のように書けると思います。
変数名以降は同じですが、手前についているのが JavaScript では一貫して`var`であるのに対し、C言語では`int`や`char`であるといった点が異なってますね。
（とりあえず今回は \`型` にだけ注目しているので、C言語の配列のことは無視します…）

どうやら JavaScript では宣言は`var`で行えるみたいですね。型宣言はいらないのか。
他にも変数宣言に用いるキーワードとして、`var`だけでなく`let`や`const`などもあるらしいです。
JavaScript は`var`で統一して宣言できる分、データ型に関するところが甘いらしく、明示的な型変換を行わなくとも以下のようなことができるみたいです。

```javascript:sample2.js
var num = 1024;
var string = "2の10乗は"

var sum = string + num;

console.log(sum); // コンソールには "2の10乗は1024" と表示される.
```

とても新鮮です。これで通ってしまうことが。

ここまでで JavaScript の洗礼を (勝手に) 受けた私ですが、もうひとつ新鮮なことがありました。

# 等価演算子(==)と厳密等価演算子(===)

私がもう一つ新鮮に感じたことが、この等価演算子と厳密等価演算子の存在です。
コード内では`==`と`===`で表されますね。
等価演算子は見たこともありました。しかし、厳密等価演算子に関しては初見でした。
初心者丸出しの第一印象は「間違って一個多めに打ちこんじゃったのかな」です。
なぜわざわざ等価演算子と厳密等価演算子の二つが用意されているのだろうと疑問に思い、二つの違いについて調べたところ、またもや新鮮な事実に行き当たりました。
ここで等価演算子と厳密等価演算子の使用例を一つ挙げさせてもらいます。

```javascript:sample3.js
var num = 1;

console.log(num == 1); // true
console.log(num === 1); // true

console.log(num == true); // true
console.log(num === true); // false
```

`num == 1`が`true`なのはわかります。`num == true`も`true`？
自分が等価演算子と思っているものと、JavaScript の等価演算子は違うみたいですね。
どっちかというと、厳密等価演算子がそれに当たるのかな？
JavaScript における等価演算子は比較する際に、同じ型になるように暗黙的な型変換が行われるようです。
そのため上の例では、`num == true`は`true`が暗黙的に数値型へ変換されたために`num == 1`と同じ形になってしまったのですね。
今までと同じ感覚で等価演算子を使ってしまうと、意図しない結果を出力してしまう可能性もありますね…。気を付けないと。

<br>

**追記：**コメントの方でご指摘を頂いたのですが、どうやらC言語にもstdbool.hというbool型を同じ振る舞いで使用できるライブラリが存在するみたいです。勉強不足ですね…。
ここでの例が結果的にあまりよろしくないものとなってしまったのですが、
「ぱっと見の型は違うのに等価判定でtrueと出ることが少し不思議に感じた」
というニュアンスが伝わってくだされば幸いです。
（また、非常に丁寧な解説をコメントの方で頂いているので、参考例としてはそちらのほうが良いと思われます！)

# 終わりに

JavaScript に慣れるのはもう少し先になりそうです。
慣れないといけないこと、知らないといけないこともまだまだ多いみたいなので、
少しずつでも着実に知識を増やしていって、できることのレパートリーを増やしていきたいですね。

追記: 2の10乗をどういうわけか256と書いてしまっていたので修正しました。
SP3777をArduinoで制御　DSP　FMラジオモジュール

#はじめに
* 電子工作の初心者としてDSPラジオに挑戦。
* AITENDOさんで入手可能なモジュールを順番にTRY。今回はSP3777に挑戦。作例も少なく、データシートも中国語で苦戦。裏技的な資料を入手して何とか成功。

#使用したもの
* Aitendoさんのモジュール。SP3777-M(http://www.aitendo.com/product/4769)
* IC（SP3777AHN)のデータシート。上記参照。
* IC（DX5767)のデータシート。検索してください。
* Arduino Uno互換機(ELEGOO)

#モジュールについて
* DIP化。この変換基板(http://www.aitendo.com/product/17501) を利用。本来の用途とは違う気もしますが、店頭でみかけたので使っています。念のため、絶縁のため中央部分にはテープを貼って使っています。
![20190822_233347.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/a2999322-1e0c-dd39-e44b-93b42350cdb0.jpeg)


#データシートについて
* DSP3777AHNのデータシートは中国語でわかりにくい。いろいろ調べていくうちに、「DX5767」とレジスタが同じようだ、ということが判明。
* 技術的な話も少し載っていて、主としてこのデータシートを使って、コードを書きました。

#配線
* これもモジュールの説明通りにつなぐだけ。イヤフォンに直接出力可能です。出力コンデンサも不要。 
* よく見ると、本モジュールはAR1019とピン配置が同一。代替品としての利用も想定されていたのかもしれません。
![SP3777.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/74b89705-270d-448d-ca10-af5a39c94188.jpeg)


#Slaveアドレス
* 本モジュールは2つのアドレスあり。RDA5807に似ています。
    * 0x10　A mode 今回はこちらを使います。
    * 0X60　P mode TEA5767互換モード（ここでは取り扱わず）

#I2C通信
* 本モジュールの　0x10　はレジスタ連続書込/読込用に設定されていて、個別レジスタへの書き込みはサポートされていない（RDA5807と同様）。
* このアドレスを用いると、自動的に以下のレジスタから連続して書込/読込が行われる。個別のレジスタを指定することはできない。書込：03Hから　　読込：00Hから。
* 書込コード例。このコードで03Hと04Hに書き込まれる。
 
```
Wire.beginTransmission(0X10); //slave address
Wire.write(0x44); // 03h
Wire.write(0x81); // 03l
Wire.write(0x7C); // 04h
Wire.write(0xFA); // 04l 82.5
Wire.endTransmission();
```
* 読込コード例。このコードで00Hから6バイト読み込まれる。つまり、00H、01H、02Hの3つのレジスタを読み込むことになる。

```
Wire.beginTransmission(0X10); // slave address
Wire.requestFrom(0x10,6); //n byte read
```

#コード作成のポイント
* DISABLE=0　ICを起動するにはDISABLEビット(03h.15)にゼロを書き込めばよい。
* TUNEビット0→1　他のDSPモジュールと同様に、特定周波数をレジスタに書き込む場合、以下の手順を踏む必要がある。
    * まず、TUNEビット（03h.9)をゼロにする。
    * 次に、特定周波数、VOLUME、BNADなどをセット
    * 最後にTUNEビットを1にする。
* CHANの計算　とにかく50Khzを使って計算する。80Mhzを選ぶなら、CHANは200になる。

#動作コード
* 上記のポイントを考慮して作成した、特定の周波数を書き込むシンプルなコード。3つのレジスタだけ操作すればよく、後はDefaultのままでOK。
* 03h　→　04h　→　05h　→　03h　と書き込めばよいので、連続書込みでも特に難しくはなかった。
* 今回は、0bxxxxyyyyの形で表記してみた。この方がわかりやすいかも。

```
#include <Wire.h>

void setup()
{
delay(1000);
  
Wire.begin();

Wire.beginTransmission(0X10); //slave address
                        //  write starts from 03H
Wire.write(0b01000100); // 03h TUNE 0
Wire.write(0b10000001); // 03l
Wire.write(0b01111100); // 04h
Wire.write(0b11001000); // 04l 80Mhz
//Wire.write(0b11111010); // 04l 82.5
Wire.write(0b10011001); // 05h
Wire.write(0b11000000); // 05l
Wire.endTransmission();

Wire.beginTransmission(0X10); //slave address
Wire.write(0b01000110); // 03h TUNE 1
Wire.write(0b10000001); // 03l
Wire.endTransmission();
}

void loop() {
  // put your main code here, to run repeatedly:
}
```

#おまけ
* 本ICは台湾製と説明があるが、データシートにはメーカーの表記が見当たらず。中国語のデータシートは何となく意味はわかった。
* TEA5767との互換モードもあるらしいので、互換品としてのニーズを狙った製品なのかも。