OmniAICreator/Qiita-1.07M huggingface dataset:
（調査メモ）気象庁XMLバリデーションエラー

個人VPSで、気象庁XMLのPULL型フィードを購読して、これまた自分で作ったRelax NGスキーマでバリデーションしています。これ、地味にトータル品質に役に立っていて、エンドツーエンドの評価になるので

* 取得処理のエラー（もうほとんどなくなった）
* 保存のエラー（今はこれが多い）
* スキーマの間違い（荒天時に増えるので忘れずにしないといけないのですが）

など全部混ざって取れます。

で、直近もなくならないので、メモ

# 2019-09-26 tarwriter 緊急修正

0x380000 バイト以上のファイルは直接書き出ししてエラー回避

https://github.com/etoyoda/tarwriter/commit/04fc78d0ea9cb438781e828058681e01fa394928

# 2019-09-26 4760df5d-dc7b-33a5-b0fc-231f86c2bf40

* エラー種類： 404エラー時にリトライせずにレスポンスボディを保存してしまったもの

# 2019-09-27 feedfollow を修正して対応

電文本体取得で 404 になったらスキップします（次回実行でリトライされるはず）
https://github.com/etoyoda/feedfollow/commit/4d33c6ccf2bbb268f48ea70fd1c899d39cf0a2e0

2019-10-04T11 まで再発していない。

# 2019-10-01 e1fc1336-0530-37c4-adc1-7ba410845920

* DateTime: 2019-10-01T04:50:19Z
* Head/Title: 滋賀県気象警報・注意報 （やばい）
* エラー種類： 途中からNULに化ける（TarWriterの書き込み不具合）
* ファイル長： 19217 バイト
* 化けはじめ位置： 9728 バイト目

# 2019-10-05 tarwriter 緊急修正

おそらく、化けが起こっているときは電文全体を bcontent に入れたときに bcontent[でかい数字, 512] が nil を返しているのではないかという疑い。その場合を救済するパッチを打ち込んでみた

https://github.com/etoyoda/tarwriter/issues/1

# 2019-10-03 a45e388d-5bca-36c2-a90d-d991f43b6be2 障害調査（遅れていた）

ログ https://toyoda-eizi.blogspot.com/2019/10/jmx-nightly-validation-2019-10-03-12124.html

XMLタグが閉じていないというバリデーションメッセージは基本NUL化けファイルちょん切れである。

* ファイル長 33894バイト
* 化け位置 25600バイト

# 2019-10-06 tarwriter 2.0.4

めんどくさくなってきたので 10240 バイト以上のファイルは全部安全コードで書き出すことにする。自前バッファリングは役に立っているのかどうかも定かではないが、まあもったいないのでブロッキングファクタ以下のサイズでは使ってみる。そのうえで、nil 問題が生じるなら syslog に出すことにする（ライブラリで STDERR というわけにもいかんだろう）。

https://github.com/etoyoda/tarwriter/commit/0ee7f2d9f756139c011217f3bd9b82cf81d8ee1e

# 2019-10-06 feedstore rc=1 の理由が判明する

ログファイルを読みさえすればわかったのだが、 feedstore が exit code 1 で死んでいたのは EAGAIN であった。つまり前回実行が1分以上かかり、DBがアンロックされていないのをつかみに行ったのである。単に排他制御がうまくいっているだけなので、gracefully に死んでほしいし syslog にももうちょっと意味が解ることを出してほしいよね。

https://github.com/etoyoda/feedfollow/commit/71d1392b513735c06d229ef861604eb6691c8869

# 2019-10-06 ようやくスキーマ間違い

https://toyoda-eizi.blogspot.com/2019/10/jmx-nightly-validation-2019-10-06-11383.html
https://github.com/etoyoda/jmx-rng/issues/1

# 2019-10-08 Polygonの緯度が一桁になる場合がある

https://github.com/etoyoda/jmx-rng/issues/2

# 2019-10-10 PublishingOffice 改修適用漏れ

https://github.com/etoyoda/jmx-rng/commit/bcf790b343b881631af7e284ddaa2d097cdca320

# 2019-10-12 PublishingOffice のパターン想定不足

* 土砂警は都道府県と気象庁の共同発表なので東京都については「東京都 気象庁予報部」となるが、指定河川洪水予報では都道府県ではなく国交省の地整や河川系事務所と気象台の共同発表となることがある
* 指定河川洪水予報は複数都道府県にまたがることがある

もうちょっとパターンを書ききれないので .* で逃げますね。
https://github.com/etoyoda/jmx-rng/commit/8355bf096575fd6e1269c8834ae10831f908a853

# 2022-09-05 追記：運用休止
https://toyoda-eizi-ja.blogspot.com/2022/09/jmx-nightly-validation.html
何か動きがあったらgithubに出ます
【Unity】Animation単体の時に、アニメーションを最初から再生する方法

#はじめに
Animatorを使わずに、Animationのみで実装する系の記事って意外と(?)無い気がするんですよね…。
というか、Unityのアニメーション関連は検索するのが難しい…。
で、「Animation　最初から」とかで検索かけてもあまりヒットしなくて毎回苦労しているのでメモ。

###開発環境
Unity2019.1.8f1

##巻き戻せば良いんや
再生する前に、最初の状態に戻しましょう。
「Animation　最初から」でググるからいけなかった。「巻き戻す」でググれば良かったんですね。

```C#:PlayAnime.cs
Animation anime;
anime = GameObject.Find("Animationがアタッチされているオブジェクト").GetComponent<Animation>();

anime.Rewind("アニメーション名");	//0フレーム目に巻き戻す
anime.Play("アニメーション名");
```

[Animation-Rewind - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/current/ScriptReference/Animation.Rewind.html)

#最後に
他にもこんな方法あるよーというのがございましたらぜひご教示ください！
【AWS IAM】グループ、ユーザー、ロール、ポリシーの関係性の理解

# 【AWS IAM】グループ、ユーザー、ロール、ポリシーの関係性の理解

## はじめに
初めてAWSを触るのですが、自分に与えられたユーザーがどういう権限を持っていて何ができて、みたいなことがわからずあたふたしているので、とりあえず概念を勉強して行こうかなと思い、調べた結果を自分の言葉でまとめてみました。  

## そもそもAWS IAMとは
AWS Identity and Access Management, 通称IAM。

そもそもAWSには、二つのアカウントが存在する。

・AWSアカウント
   - ルートアカウントで、最強のアカウント。
   - 全てのサービスを操作(起動/削除/変更etc...)出来る。
   - 取扱に注意が必要。
   - **普段からの利用は極力避ける。** 

・IAMアカウント
   - マネジメントコンソール上で操作する時、APIで操作する時に使うアカウント。
   - IMAアカウントは、それ毎に細かくどのサービスをどの程度設定出来るかを定義することが出来る.
   
IAMは、AWS上のサービスを使う際における、AWSアカウントを直接使う代わりの、**ユーザー認証・許可の制御サービス**。

## AWS IAMの機能　　
機能に関しては、とりあえずこの二つ理解してればいいかなぁって。

・**AWSアカウントへの共有アクセス**
パスワードやアクセスキーを共有しなくても、AWSアカウントリソースの管理・利用のためのアクセス許可を他者に付与できる。

・**詳細なアクセス権限**
リソースごとに、ユーザーごとに、さまざまなアクセス権限を付与できる。例えば、このIAMユーザーはこのサービスの管理画面は入れるけどこっちはだめ、見るだけならオッケー、みたいな。

**要は開発側のユーザー権限の管理が簡単にできちゃうよ**ってことだと思う。

## 使っていてよくわからなかった概念
使っていて混乱したことをまとめます。
結論を先に言うと、
**ポリシーは実行権限を表すもので、ユーザーや関数につける。関数には一つしか紐づけられないから、ロールに複数のポリシーをまとめて、ロールを関数に紐付ける。**
って理解をしとけばいいのかなぁと。

とりあえず、関係性を図にすると、こんな感じ。
<img width="998" alt="スクリーンショット 2019-10-04 19.39.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/cdab9e7b-78f7-e4b9-b1a7-0b3c9f2340a9.png">

### ユーザー  
AWSを利用するユーザー。
ユーザーには、（複数の）ポリシーが適用される。
ユーザーは0個以上のグループに所属することができる。
所属するグループのポリシーは、ユーザーに引き継がれる。

### グループ  
似た性質をもつユーザをまとめたグループ。
グループには、（複数の）ポリシーを適用される。
グループに適用されたポリシーは、グループに所属するユーザーにも引き継がれる。

### ポリシー  
サービスへのアクセス権を管理するもの。
AWSの多様なサービスとそれに対する動作（アクション）に対して、3つのルールに基づいて許可するかどうかをポリシーとしてまとめる。

　　Action - どのサービス
　　Resource - どういう機能の範囲を(起動/削除/変更etc...)
　　Effect - 許可 or 拒否

このポリシーには2種類ある。
　　・AWS Managed Policies　：　AWSが最初から設定しているポリシー
　　・Customer Managed Policies　：　ユーザが独自に作成したポリシー
　
### ロール  
AWSのリソースの、他のリソースへのアクセス権を管理するもの。
ロールには、(複数の)IAMポリシーが適用される。
一つのリソースには、一つのロールが付与される。

例えば、あるEC2には一つだけIAMロールが付与出来るが、そのロールに様々なポリシーを付与する事で、そのEC2は様々なAWSリソースにアクセスする事が出来るようになる。
(AWSCliコマンドから、S3バケットにアクセスしたり、Lambdaを実行したり出来る。)

ロールは、ユーザーにも付与することがあるらしいが、よくわからなかったので割愛。


## 参考サイト
これ読んで全部理解できればいいんだろうなぁ
[AWSドキュメント：IAMとは](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/introduction.html)  

まとまっていてわかりやすかった
 [qiita : Amazon AWSのIAMのPolicy、Roleの理解](https://qiita.com/Mount/items/b8c9db4dbe6500f41e27)

概念の話というよりは手順の話だったけど、いざ使うってなったら参考になりそうな
[qiita : GWも明けたし、AWSのIAMについてちゃんと理解しとく](https://qiita.com/ritukiii/items/566f19deff34c29581ba)

もうちょっと勉強してから読み直したい
[qiita : 【AWS】IAMまとめ](https://qiita.com/iron-breaker/items/49669aea2d20cc26484d)
Typescriptのタイプガードが上手く効かない場合の逃げ

今一つ明確な条件が分かっていないんですが、
ネストの深いプロパティを無名関数の中で使おうとするとたまにタイプガードが効かなくなることがあります。

``` typescript
type Fuga = {
    val:string
}

type Hoge = {
    fuga?:Fuga
}

type Piyo = {
    hoge:Hoge
}

(piyo:Piyo) => {
    if(!piyo.hoge.fuga){
        return;
    }
    piyo.hoge.fuga.val;//OK
    () => {
        piyo.hoge.fuga.val///エラーになる
    }
}

```
こんな時は、

``` typescript

(piyo:Piyo) => {
    if(!piyo.hoge.fuga){
        return;
    }
    const fuga = piyo.hoge.fuga;

    () => {
        fuga.val///エラーにならない
    }
}

```
と一度適当な変数に受けてやってから使うと、
fugaの時点で型が`Fuga|undefined` ではなく `FUGA`に固定されるのでfuga.valは問題なく通ります。
SkeletonView

よく商用アプリでも使われているのを見るローディングライブラリである「[SkeletonView](https://github.com/Juanpe/SkeletonView)」を使用したので、使い方の備忘録として書き残しておきます。

```swift
import SkeletonView
```

```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        // TableViewの行の高さを可変にする
        tableView.rowHeight = UITableView.automaticDimension
        // UITableView.automaticDimensionを設定している場合に、SkeletonViewを使うなら
        // estimatedRowHeightの設定が必要
        tableView.estimatedRowHeight = 140
        // スケルトン表示開始
        view.showAnimatedGradientSkeleton()
    }
```



```swift
            defer {
                // スケルトン表示終了
                self.view.hideSkeleton()
            }
```



```swift
// MARK: - SkeletonTableViewDataSource
extension ViewController: SkeletonTableViewDataSource {
    /// スケルトン表示時のセクション数
    func numSections(in collectionSkeletonView: UITableView) -> Int {
        return 2
    }
    /// スケルトン表示時の行数
    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    /// スケルトン表示する再利用セルのIdentifier
    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
        switch indexPath.row {
        case 0:
            return "summaryCell"
            
        case 1...:
            return "detailCell"
            
        default:
            DispatchQueue.main.async {
                self.showAlert(title: "予期せぬエラー", message: "予期しないセルがあります")
            }
            return ""
        }
    }
}
```

## 参考

https://github.com/Juanpe/SkeletonView

https://dev.classmethod.jp/smartphone/iphone/oss-skeleton-view-introduction/
ボタン連打、連続クリックを止める

更新ボタンを連打されAjaxの処理を重複させない為に、処理中にボタンを無効にしたい。
無効時はボタンの色を薄くして、わかるようにする。

##処理概要
①クリック時にボタンを無効にし色を変更。

②クリック時に行いたい処理を書く(書き換え、送信処理など)。

③処理完了後、指定時間後にボタンを有効にし色を戻す。
ここでは、仮に処理が1秒程かかるとして、1秒間だけ無効にする。

※しかし、処理完了後にすぐボタンを有効にしたい場合、
setTimeoutを削除する。
詳しくはページ下部の[補足](#補足)へ


#####備考
●disabled
クリックできるか　true:無効化、false:有効化。

disabledが有効の場合自動で半透明になるので、特にオリジナルのカラーを使用しなければ以下2つは必要ない。
●addClass( )
既存の CSS クラスを追加する場合に使用

●removeClass( )
既存の CSS クラスを削除する場合に使用

##ソース
```a.html
<script>
$(function(){

  //更新ボタンクリック
  $("#refresh").click(function (event) {
    //ボタンクリック無効化
    if (cancelFlag == false) {
      $("#refresh").prop("disabled", true).addClass("btn-pink");

      //処理内容
        $.ajax({
          url: "https://?????",
          type: "GET",
          success: function () {
            console.log("OK");
          },
        });

      //ボタンクリック有効化
      setTimeout(function () {
        $("#refresh").prop("disabled", false).removeClass("btn-pink");
      }, 1000);
    }
  });

});
</script>

<button id="refresh" class="btn-red">更新</button>
```
```b.css
/*ボタンは赤色*/
.btn-red {
	background-color: #red;
}

/*ボタン無効時はピンク*/
.btn-pink {
	background-color: #pink;

```

#####補足
処理終了と同時に有効化したい場合、有効化の部分のsetTimeout()を削除し、処理内容の最後に有効化処理を入れる。
更新終了と同時にボタンを有効化にできる。

```a.html
<script>
・・・
        //処理内容
        $.ajax({
          url: "https://?????",
          type: "GET",
          success: function () {
            console.log("OK");
            //ボタンクリック有効化
            $('#refresh').prop('disabled', false).removeClass('sending');
          },
        });
・・・
</script>
```

#####(※追記)
chromeでは問題なかったが、
IE(バージョン不明)ではボタン有効化時の`.prop('disabled', false)`が効いていない
ことが判明。
removeAttr()でボタン無効処理ごと消す。

```a.html
<script>
・・・
//ボタンクリック有効化
$('#refresh').removeAttr('disabled').removeClass('sending');
・・・
</script>
```
Laravel-admin [インストール編]

しばらくlaravel-adminという管理画面作成用ライブラリを使ってみたので少しずつ記事にしていこうということで、まずインストールの手順からまとめていこうと思います。

# プロジェクトの作成
Laravelのライブラリということでまず必要なものとなるのがLaravel。
Laravel-adminの公式ページによるとPHP７以降、Laravel５.５以降のものが必要とあるのでバージョンを指定してLaravelでプロジェクトを作成する。

```console
$ composer create-project --prefer-dist "laravel/laravel=5.5.*" プロジェクト名
```

DBも必要になるので.envファイルも用意する。

```:.env
DB_DATABASE=DB名
DB_USERNAME=ユーザ名
DB_PASSWORD=パスワード
```

# Laravel-admin導入
次のコマンドを実行する。

```console
$ composer require encore/laravel-admin
```
vendor/encoreの中を見るとLaravel-adminが入っていることが確認できる。
次に下記のコマンドを実行する

```console
$ php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
```

Laravel-adminが展開され、configやマイグレーションなどが追加される。
最後に下記のコマンドを実行することで必要な情報がDBに入る。

```console
$ php artisan admin:install
```

あとは``php artisan serve``などをして、http://localhost:8000/admin にアクセスする。
username、password共に``admin``と入れ、Dashboardが表示されれば成功。

# まとめ
最初からそれなりの画面が表示されているのであとは公式ページにあるクイックスタートの通りに進めていくと簡単に管理画面ができます。
これから少しずつ、スローペースではありますが、laravel-adminで試したことをまとめていきたいと思います。

## おまけ
ユーザの追加などをしようとするとConfig errorと出る。
追加はできるのですがやはりエラーが出たままなのはいい気分にはなれないので、config/filesystems.phpの一番下、local、public、s３と続いている下に以下を追加する。

```php:filesystems.php
'admin' => [	
'driver' => 'local',	
'root' => public_path('uploads'),	
'visibility' => 'public',	
'url' => env('APP_URL').'/uploads',	
],
```

するとエラーが表示されなくなる。

参考
<a href="https://qiita.com/n-sawada-12345/items/ac1229f3470ec71bced9">laravel-adminインストール手順</a>
<a href="https://laravel-admin.org/docs/#/">Laravel-admin 公式</a>
読んだ本の紹介03「まんがでわかる　伝え方が9割」

[まんがでわかる　伝え方が９割](https://www.amazon.co.jp/%E3%81%BE%E3%82%93%E3%81%8C%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-%E4%BC%9D%E3%81%88%E6%96%B9%E3%81%8C9%E5%89%B2-%E4%BD%90%E3%80%85%E6%9C%A8-%E5%9C%AD%E4%B8%80/dp/447806864X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1563240487&sr=1-2)
おすすめ度★★★★★

## なぜこの本を読んだのか
伝え方がイマイチなことがよくあるのでそれを克服したかった
まんがなので読みやすいと思ったから

## まとめ
- 「イエス」に変える3つのステップ
 1. 自分の頭の中をそのままコトバにしない
     - 何でもかんでもストレートに言うのはばくちと一緒
 2. 相手の頭の中を想像する
     - 何が好きか？何が嫌いか？どんな性格か？わかりうる相手の基本的な情報を思い出す
 3. 相手のメリットと一致するお願いをつくる
     - 相手の文脈でコトバをつくること 

例：例えばデートに誘いたとき
1. 直接「デートに行こう」とは言わない✖
2. 相手を考える「忙しい」「新しいもの好き」「ラーメンが好物」
3. 「驚くほどおいしいラーメン見つけたけど行かない？」〇

- 「イエス」に変える切り口
    1. 「相手の好きなこと」
         -  自分のメリットだけではなく相手のメリットも考える
    1. 「選択の自由」
         -  人は「決断」が得意ではないので選択肢を使って選ばせる
    1. 「認められたい欲」
         -  それを満たすためにちょっとくらい面倒なことでもやろうと思ってしまう
    1. 「あなた限定」
         -  特別感を出すと人は承諾してしまう（あなただけにはこの壺を50万のところ30万で売ります）
    1. 「チームワーク化」
         -  「一緒にやりましょう！」などといい相手が面倒くさいと思わないようにする
    1. 「嫌いなこと回避」
         -  相手の嫌いなことからコトバを作る
    1. 「感謝」
         -  人は感謝から入ると「ノー」と言いにくい



自分のメリットだけでコトバを発すると相手は賛同しにくい
`相手のことを考え、相手にメリットがあるようにコトバを変える`
そうすると相手は「イエス」と言ってくれることが多くなる


## 感想
まんがで読みやすく、短時間で人への伝え方が学べた
1冊の本として他の本より量が少なかったが必要なものがギュッと詰まっていた
こういった本を通して、どの本にも「自分の頭の中の言葉をそのまま発しない」が書かれていて重要性を改めて感じた
例がたくさんあってわかりやすかった
今まで読んだ中で一番わかりやすく頭に入ってきた
moduleとmixin

## モジュール


```ruby:
module SampleModule
  CONST_NUM =100

  def const_num
    CONST_NUM
  end
end

puts SampleModule::CONST_NUM

# moduleをincludeしたあとならモジュール名を省略して定数に直接アクセスできるようになる
include SampleModule
puts CONST_NUM
puts const_num
```

`module_function`を使うことで`module`名に.をつけてメソッドを呼び出せるようになる

```ruby:
module SampleModule
  def module_function_sum(a, b)
    a + b
  end

  module_function :module_function_sum
end

SampleModule.module_function_sum(1, 100)
=> 101
```

## ミックスイン
モジュールの機能をクラスに取り込むには
　　`include モジュール名`
とする

```ruby:
module SampleModule
  def sum(a, b)
    a + b
  end
end

class Sample
  include SampleModule

  def class_sum(a, b)
    sum(a, b)
  end
end
```

実行してみる

```ruby:
sample = Sample.new
puts sample.sum(1, 100)
=> 101

puts sample.class_sum(1, 100)
=> 101

```

## 使い道
- 複数のクラスで使う共通のメソッドを`module`として定義し、適宜`include`して使う
- 特定のメソッドを`module`としてまとめておきユーティリティーとして使用する
Vue.jsの"なければならない"

<h1>コンポーネント</h1>

<h2>dataは関数でなければならない</h2>

```
Vue.component('my-component', {

...

   data: function () {
      return {
         message: 'Hello Vue.js'
      }
   }
})
```

<h2>テンプレートの要素は一つでなければならない</h2>

```
templatel: '<span>a</span><span>b</span>'
```
↑はNG

```
template: '<div><span>a</span><span>b</span></div>'
```
のように大きく一つにまとめればOK

<h2>.nativeで発火</h2>

コンポーネント内でv-onを使いたいときは、.nativeをつけなければならない.
例

```
<my-component v-on:click="eventClick"></my-component>
```
↑ではクリックしても、eventClickは実行されない。
この場合実行するには、子コンポーネントで$emitを使って発火しなければならない。

これを回避するには、

```
<my-component v-on:click.native="eventClick"></my-component>
```
とすればよい。
Macbook ProのSSDを換装する

# 動機
　普段使っているMacの容量が不足し、普段遣いに影響が出るのはもちろん、授業で使うソフトウェアもインストールできずかなり辛さを感じ始めた。
　もともとの容量が128GBであったことに加え、Bootcampを使ってWindows用のパーティションを64GBも作っていた。つまり半分である。
　Xcodeなどの重いソフトのせいで、頻繁にディスクを整理しなれけば「容量減ってますよ」とMacくんに怒られ続けるだけのMac人生になっていた。無知であった自分に首を絞められていたわけである。
　そのため、そろそろディスクごと交換しなければどうにもならないな、とようやく重い腰をあげた次第である。

# やること
+ 元のSSDに入っているデータのバックアップ
+ SSDの交換
+ バックアップからの復元
+ 重いソフトを落としてハッピーになる

# 使ったアイテムとか
+ MacBook Pro (Retina, 13-inch, Early 2015)
+ 外付けディスク
+ [Crucial P1 NVMe PCIe 2280 M.2 SSD 1000GB](URL https://www.amazon.co.jp/gp/product/B07JWKKBVV/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)
+ [M.2 NGFF SSD (AHCI) → APPLE 2013 Macbook AIR A1465 A1466 A1398 A1502 128G 256G 512G SSD 変換アダプター](URL https://www.amazon.co.jp/gp/product/B07CS775JD/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)
+ [星形ドライバー](URL https://www.amazon.co.jp/dp/B00KM4HFB6/ref=cm_sw_em_r_mt_dp_U_jeVLDbMCRDS5H)
+ [精密ドライバー(T5)](URL https://www.amazon.co.jp/dp/B002SQLDS2/ref=cm_sw_r_tw_dp_U_x_uqVLDb3PYV3QT)


　外付けディスクはバックアップに使用するが、その際フォーマット(データの消去)をしなければいけないため、必要であれば新しく用意する。
　ドライバーたちは友人が所有していたものを拝借した。精密ドライバーについては同一の製品が見つからず、同じ型の製品のリンクを貼ってある。

　なお、使用するSSDは接続形式がM.2のものである必要がある。古いものでは使用できていたが、Macbook Pro 2015では2.5インチのものは使用できないため、注意する必要がある。

# SSDを交換する
ここからは実際にSSDを交換するための段階に入っていく。

## バックアップを取る
外付けディスクをMacに接続し、TimeMachineを使ってバックアップを取る。
システム環境設定 > Time Machine でディスクを選択し、バックアップを実行する。
フォーマットを要求された場合、後から自分がわかるように適当な名前をつける。
定期的にバックアップしていない場合はかなり時間がかかるが、気長に待つ。

## 開けて、交換して、閉める
### 開ける
残念ながら写真は用意していない(撮るのを忘れていた)ため、割愛する。
以下のサイトを参考にしながら行ったため、参照されたい。

https://akiba-pc.watch.impress.co.jp/docs/sp/1201336-2.html
https://jp.ifixit.com/Guide/MacBook+Pro+13-Inch+Retina+Display+Early+2015+%E3%81%AESSD%E3%81%AE%E4%BA%A4%E6%8F%9B/38520

#### 裏蓋を外す
裏面にある10個のネジを星形ドライバーを使って外す。
この際、ネジをなくさらない・見失わないようにしておく必要があるが、今回は机に敷いたティッシュの上にまとめて置いておく手段を取った。
なお、奥側の中心側のネジ×2はそれ以外と形が違うため、混ざらないようにすると良い。

#### バッテリーのコネクタを外す
凸型のシールのようなものをめくり、コネクタを外す。シールは後々貼り直すためとっておく。
コネクタはかなり強く接続されているため、大きめのマイナスドライバーとテコの原理を利用して外した。
交換作業中にコネクタが端子に触れないよう、持ち上げておく。

### SSDを交換する
ネジをT5ドライバーで外し、SSD本体を軽く持ち上げてから引き抜く。
端子が折れてしまわないよう、掴んで引き抜くための最低限だけ持ち上げる。そこそこ強く差し込まれており多少怖さがあるが、勇気を出して取り外す。

新しいSSDに購入したアダプターを接続し、元のSSDがあった位置に差し込む。外す時と同じかそれ以上に力が必要になるが、臆さず差し込み、元のようにネジをつける。

### 閉める
開けたのと逆の手順を辿っていけば閉められる。


##バックアップから復元する
裏蓋を閉められたら、元のデータを復元する作業に移る。

### 起動する
Time MachineバックアップはMacOSの起動ディスクとしても使うことができるため、バックアップを取ったディスクをMacに接続し、Macの電源をつける。起動したら、バックアップ用ディスクを選択し、読み込むのを待つ。
起動したら、Macで使用する言語を選択する。

### SSDをフォーマットする
無事に起動したら「ディスクユーティリティ」を選択し、新しく装着したSSDを選択、上のメニューから「消去」を実行する。
いくつか設定項目があるが、デフォルトで選択されている項目のままにしておけば良い。ディスク名を入力する欄があるが、バックアップから復元されたときになかったことにされるため、どんなものでも問題ないだろう。

### 復元する
Cammand+Q、または画面上部のメニューからディスクユーティリティを終了し、「Time Machineバックアップから復元」を選択する。バックアップ用ディスク、復元先のSSDを順番に選択し、復元させる。
毎度のことながら時間がかかるが、首などを長くしながら待つ。

### ログインする
復元が終わると自動で再起動してくれるため、もともと使っていたユーザ名とパスワードを入力し、ログインする。
無事にログインできれば、手順は完了している。自分にお疲れ様を言って、終了。


# まとめ
　無事にストレージを拡張できた。容量不足で長い間行えていなかったXCodeのアップデートを実行し、ハッピーになった。
コマンドプロンプトでpythonファイル(.py)を開く方法

当たり前過ぎてどこにも書いてなかったので。

当該.pyファイルのディレクトリに移動し、

```
open pythonfile.py
```

で開けます。

当たり前ですけれど。
----------------------------------------------------------
SQL小技集
https://qiita.com/ool/items/75da830e7373138c8125
UTCとJST
https://qiita.com/ool/items/6be9cc290c8ad9e0f5bc
今流行りの量子コンピューター
[量子コンピューター]Qisikitでアダマールゲートを実装する
https://qiita.com/ool/items/1a5041edddc11b14efc0
[Qiskitのアカウント認証の仕方]Qiskit IBMQ プロバイダー
https://qiita.com/ool/items/e80c1266cda68984a103
Qiskitの使い方
https://qiita.com/ool/items/2227d2d515caa5087752
[量子コンピューター]Qiskit Tutorials
https://qiita.com/ool/items/2a5038df1471635d442c
InfluxDB-Pythonでナノ秒単位のデータを登録する

# はじめに

InfluxDBのpythonクライアント（[InfluxDB-Python](https://influxdb-python.readthedocs.io)）でナノ秒単位のデータを登録する際に、タイムスタンプが崩れるため工夫が必要だったという話です。

# 環境

* OS: Windows 10
* InfluxDB: v1.7.8
* Python: v3.7.4
* InfluxDB-Python: v5.2.3

# 再現コード

InfluxDB-Pythonの[README](https://influxdb-python.readthedocs.io/en/latest/include-readme.html)を参考にして、ナノ秒単位のデータ登録を行ってみます。

```python
from influxdb import InfluxDBClient

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ts = '2019-01-01T00:00:00.123456789Z'
    body = [{
        'measurement': 'cpu',
        'time': ts,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')
```

サーバ設定はデフォルトのままです。期待ではそのままのタイムスタンプで登録されていて欲しかったのですが、サーバには丸められたタイムスタンプで登録されていました。

```
> select * from cpu
name: cpu
time                sys  usr
----                ---  ---
1546300800123456000 12.3 45.6
```

他にも例えば「2019-01-01T00:00:00.123Z」のようにミリ秒単位のタイムスタンプを指定すると、「1546300800122999808」とズレたタイムスタンプで入ってしまうのが困りました。

# 対応コード

どうもクライアント側で丸められているようでした。タイムスタンプをUnix時刻（ナノ秒）で指定すると問題なさそう。

```python
from influxdb import InfluxDBClient

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ut = 1546300800123456789
    body = [{
        'measurement': 'cpu',
        'time': ut,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')
```

これだとうまく入ります。

```
> select * from cpu
name: cpu
time                sys  usr
----                ---  ---
1546300800123456789 12.3 45.6
```

InfluxDB-Pythonのナノ秒単位のタイムスタンプの文字列の扱いにはどうも制約があるようです。ナノ秒単位のデータを扱い得るときには、基本的に整数型で指定する方がよいように思います。

ちなみにタイムスタンプの文字列（RFC3339）をナノ秒単位のUnix時刻に変換するには、標準ライブラリでさくっと、というわけにはいかなさそうです。いちばん手軽にできるのはnumpyのdatetime64ですかね。

```python
from influxdb import InfluxDBClient
import numpy

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ts = '2019-01-01T00:00:00.123456789Z'
    dt = numpy.datetime64(ts, 'ns')
    ut = dt.astype('uint64')
    body = [{
        'measurement': 'cpu',
        'time': ut,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')
```

# おわりに

InfluxDB-Pythonでナノ秒単位のデータを登録する際に、タイムスタンプの文字列の扱いに制約があるため工夫が必要だったという話でした。

# 参考

* [Incorrect nanosecond timestamps being written to influxdb #649](https://github.com/influxdata/influxdb-python/issues/649)
javascriptで日時のタイムスタンプ文字列を生成する

JavaScriptだけでDateをフォーマットするのは面倒です（０埋めが必要だったり、getMonthが0-11を返すとか・・・）

[moment.js](https://momentjs.com/)を使うがお勧めですが、手元でちょいとフォーマットしたい的な際のサンプルです。

```javascript
    // 現在日時からタイムスタンプのファイル名を生成
    const d = new Date(); // Today
    const DateTimeFormat = 'YYYYMMDD_hhmiss'; // "2019/10/04 12:34:56" -> "20191004_123456"
    let toFileName = DateTimeFormat
      .replace(/YYYY/g, String(d.getFullYear()))
      .replace(/MM/g, ('0' + (d.getMonth() + 1)).slice(-2))
      .replace(/DD/g, ('0' + d.getDate()).slice(-2))
      .replace(/hh/g, ('0' + d.getHours()).slice(-2))
      .replace(/mi/g, ('0' + d.getMinutes()).slice(-2))
      .replace(/ss/g, ('0' + d.getSeconds()).slice(-2));
```

DateTimeFormat文字列を変更すれば、お好きな形式に整形できます。

```javascript
    const DateTimeFormat = 'YYYY/MM/DD hh:mi:ss'; // "2019/10/04 12:34:56" -> "2019/10/04 12:34:56"
```
Cognos Analytics スライサーのレポートをURL呼び出し

#スライサーのレポートをURL呼び出し
どうも調べても、ちゃんとした情報が見つからなかったので、投稿しておきます。

ディメンショナルモデル(DMR)で、以下のようなクロス集計を配置し、クロス集計に登場しない「Year」でスライサーをかけています。
<img width="565" alt="001.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/1db57037-0e5a-3c75-f9ae-37e6bc1d93d8.png">

スライサーの内容は以下で、promptmanyマクロで複数選択可能なpYearパラメーターを指定しています。
<img width="480" alt="002.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8ecc7a22-abff-dc77-5f2c-86db5a5d01fe.png">

この「URLReport03」という名称のレポートを、「pYear」パラメーターに、「年」を設定して、URLで直接呼び出す書き方です。

ディメンショナルモデルの場合、リレーショナルモデルのレポートと書き方が随分違います。

#「年」=2012年と2013年指定で、通常の方式で呼び出すURL
こんな感じです。
p_pYear=の様に、パラメーターの前に「p_」を付ける書き方はリレーショナルレポートの書き方と同じですが、その後は「2012」というような値ではなく、メンバーを指定する書き方となります。
左辺は「レベル」を指定し、右辺はメンバーを指定しますが、「:[PC].[@MEMBER].」はメンバー指定の時のお決まりの書き方のようです。

```html
http://CognosHost:9300/bi/?pathRef=.public_folders%2FFolder1%2FURLReport03&format=HTML&Download=false&prompt=true&p_pYear=[Sales].[Time].[Time].[Year]->:[PC].[@MEMBER].[2012]&p_pYear=[Sales].[Time].[Time].[Year]->:[PC].[@MEMBER].[2013]
```

このURLで呼び出したレポート結果です。
どうもプロンプトは選択された色付き状態にならないのですが、クロス集計はしっかり「2012年と2013年」でフィルターされています。
<img width="556" alt="003.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/69300fbf-2175-946d-1788-58561a0ff81b.png">


#「年」=2012年指定で、JSON方式で呼び出すURL
JSONの場合、こんな感じです。
valueの中に「レベル -> メンバー」の指定をします。

```html
http://CognosHost:9300/bi/?pathRef=.public_folders%2FFolder1%2FURLReport03&format=HTML&Download=false&prompt=true&promptParameters={"name":"pYear","value":[{"use":"[Sales].[Time].[Time].[Year]->:[PC].[@MEMBER].[2012]"}]}
```

実行結果。2012年でクロス集計は絞り込まれています。
<img width="550" alt="004.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/582583f9-6c61-b0e7-0ab5-ee6293d61a9e.png">

どこかでお役に立てば幸いです。
PostgreSQLでDBを複製する方法とシーケンスだけ作られない時の対処法

##はじめに
デモサイト用に作ったローカルに保存してあるDBをDBサーバーに複製する際に、シーケンスが作られず思ったより苦戦してしまったので備忘録として記録
※超初心者(完全未経験文系のエンジニア歴３ヶ月)が書いてる記事であることにご注意
※記事の内容や理解に間違いがあったらご指摘いただけると嬉しいです。

##実行環境
【DB】
PostgreSQL 11.3
（バージョン違いの際の注意点についても記載）

【OS（ローカル）】
Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G95

【OS（サーバー）】
CentOS Linux release 7.6.1810 (Core)

##基本的な流れ
（0.サーバー側に空のDBを用意する）
1.dumpファイルを作成する
2.作成したdumpファイルをリストアする

基本的には、1・2だけで終わる。
今回はリストア先のサーバーに複数のDBが存在していたので、干渉がないように空のDBを用意してそこにリストアする手順で行なっている。

##コマンド
####(0.dumpファイルを作成する)
空っぽのDBを用意

```sql:SQL
    CREATE DATABASE hogeDB
```
####1.dumpファイルを作成する
Macのターミナルから直接実行。
バージョン違いの対処もできるようにするためにスクリプト形式でdumpファイルを出力する。
<FONT COLOR=gray>※普通にやる場合は、オプションで"-Fc"をつけてアーカイブ形式にした方が、容量も小さくなりBetterな気がする</FONT>

```:スクリプト形式
    pg_dump -h localhost -U ユーザ名 DB名 > DB名.dump
```
```:アーカイブ形式
    pg_dump -h localhost -U ユーザ名 -Fc DB名 > DB名.dump
```


####2.作成したdumpファイルをリストアする
Macのターミナルから直接実行する
    
```:スクリプト形式
    psql -h localhost -U ユーザ名 -f DB名.dump hogeDB
```
```:アーカイブ形式
    pg_restore -h サーバーのIPアドレス -U ユーザ名 DB名.dump -d hogeDB
```


##シーケンスだけが作られない時の原因と対処法
####原因
**dump元とrestore先のPostgresqlのバージョン違いが主な原因。**
異なるバージョンのPostgresqlで作成したdumpファイルは、一部中身を書き換えないとシーケンスが作成されない場合がある。

実際、バージョン8.1がインストールされているサーバーに、11.3で作成したdumpファイルをリストアしようとした際、オプションや形式を変えてもシーケンスがサーバー側で作成されず、その原因にすぐ気付けずに時間を無駄にしてしまった。
####対処法
バージョン違いの対処方法としては、作成したdumpファイルを直接テキストエディタで開いて、AS integerの部分を削除すれば異なるバージョンでもシーケンス込みでリストアできる。

```sql:dumpファイル（スクリプト形式）　一部抜粋
    CREATE SEQUENCE public.シーケンス名
    AS integer --この行を消す
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;
```
PostgreSQLのバージョンが8.1等の古いものだと「AS integer」という風に指定ができず、エラーとなってしまってシーケンス自体が作られないこととなる。

以下、「[PostgreSQL 8.3.7文書](https://www.postgresql.jp/document/8.3/html/sql-createsequence.html)」より引用
>互換性
以下の例外を除き、CREATE SEQUENCEは標準SQLに従います。

>標準におけるAS <data type>式はサポートされていません。

>次の値を取り出すには、標準のNEXT VALUE FOR式ではなくnextval()関数を使用します。

>OWNED BY句はPostgreSQLの拡張です。

　
以下、「[PostgreSQL 11.4文書](https://www.postgresql.jp/document/11/html/sql-createsequence.html)」より引用

>互換性
以下の例外を除き、CREATE SEQUENCEは標準SQLに従います。

>次の値を取り出すには、標準のNEXT VALUE FOR式ではなくnextval()関数を使用します。

>OWNED BY句はPostgreSQLの拡張です。

公式文書を見ても、例外でなくなっていることがわかる。
また、11.4の CREATE SEQUENCE 文を見るとオプションにしっかりと[ AS data_type ]が書けるようになっている。

##参考にしたサイト
[PostgreSQL 8.3.7文書](https://www.postgresql.jp/document/8.3/html/sql-createsequence.html)
[PostgreSQL 11.4文書](https://www.postgresql.jp/document/11/html/sql-createsequence.html)
[メモ：PostgreSQLのDBを丸ごと移行する方法](https://torazuka.hatenablog.com/entry/20100415/pg)
React Map<K,V>型でループしてコンポーネントを返したい。

表記のとおり、Map<K,V>型でループしてコンポーネントを返したい場合、

```TypeScript
function Qiita(props: { chikyuwaMawaruMap: Map<Date, Unit> }) { 
    return (

//NG   Map<>型でループできる方探してたらforEach があったのでreturn returnで返るのかなと憶測で考えていたけどだめでした。Object.entries() する必要があるみたいです。
 return (
    {props.chikyuwaMawaruMap.forEach((value, index) => {
      return(<JikkoWaSarerukedoReturnSarenai />)
    }}
)
//OK
 {Array.from(props.chikyuwaMawaruMap.entries()).map((entry, index) => {
   Return (<SampleComponent />);
 }}


//FYI
 interface Map<K, V> {
     clear(): void;
     delete(key: K): boolean;
     forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
     get(key: K): V | undefined;
     has(key: K): boolean;
     set(key: K, value: V): this;
     readonly size: number;
 }
```
HerokuでCorretto 11を使う

## buildpackの設定

```shell-session
$ heroku buildpacks:set jdk/corretto -a [App名]
$ heroku buildpacks:add heroku/java -a [App名]
```

## 環境変数の追加

- [jkutner/corretto-buildpack](https://github.com/jkutner/corretto-buildpack)用に[Corretto 11のダウンロード先とチェックサム](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html)を環境変数で指定する
  - 環境変数を指定しない場合のデフォルトはCorretto 8

```shell-session
$ heroku config:set \
  CORRETTO_URL=https://d3pxv6yz143wms.cloudfront.net/11.0.4.11.1/amazon-corretto-11.0.4.11.1-linux-x64.tar.gz \
  CORRETTO_CHECKSUM=4bbcd5e6d721fef56e46b3bfa8631c1c \
  -a [App name]
```

## 参考

- [Using AdoptOpenJDK, Corretto, Zulu, and Graal on Heroku](https://jkutner.github.io/2019/03/27/using-corretto-adopt-graal-zulu-on-heroku.html)
【2019年10月版】Cloud Storageの直リンクは見れない

# Cloud Storageに上げたファイルの直リンクをChrome以外のブラウザで見ると・・・

画像素材などのアップロード先として何かと便利な Cloud Storage ですが、Google Cloud Platform の管理画面で提示される `リンクURL` は問題があります。

Cloud Storage の管理画面でファイルの詳細を開くと以下のような形式で `リンクURL`が表示されていると思います。

```
https://storage.cloud.google.com/バケット名/ファイル名
```

ファイルの公開設定をちゃんとした後、このアドレスを Safari や Edge など Google の *アカウント情報が提供されていないブラウザ* で直接開くとどうなるでしょうか・・・？

**Googleアカウントのログインか選択画面が表示されると思います。**

設定画面の `相互運用性`タブに記載があるのですが・・・

> リクエスト エンドポイント
> その他のクラウド ストレージ システム（Amazon S3 など）で使用するツールまたはライブラリにあるリクエスト エンドポイントで、以下の Cloud Storage URI を使用していることを確認してください:
> 
> `https://storage.googleapis.com`

直リンクは `https://storage.googleapis.com` のエンドポイント使ってね、ということです。。。~~(先に言えよ)~~

WEBサイトなどからファイルの直リンクを設置する場合、管理画面に提示されたリンクURLではなく、

```
https://storage.googleapis.com/バケット名/ファイル名
```

の形式のURLにしてね、ということです。

## Firebase はOK

また Cloud Storage は Firebase からも利用することができます。
この場合は firebase の管理画面で生成されるURLで問題ありません。

ファイルの詳細画面でファイルのリンクが表示されていると思います。
クリックすると別タブでファイルが開きますが、この時のURLを SafariやEdgeなどで開いてもそのまま問題なく表示できます。

ちなみに以下のような形式になってます。

```
https://firebasestorage.googleapis.com/v0/b/プロジェクト名.appspot.com/o/バケット名/ファイル名?alt=xxxx&token=xxxxx
```

firebaseの場合は最初からちゃんと `googleapis.com` ドメインを使ったURLを生成してくれています。

## というわけで

Cloud Storage のリンクURLはそのまま使っちゃダメ！
Rails エラーメッセージの出し方　バリデーションエラー

#はじめに
DBに値を保存する際(ユーザー登録やツイートの登録等)のバリデーションエラー文を表示するやり方について備忘録のために記載しておきます。
参考程度にどうぞ。

#バリデーションとは？
バリデーションとはDBに値を保存する際に何か値が抜けていると保存できなくするものです。
簡単に言えばフィルターみたいなものですね。

例えばユーザー登録時にpasswordを入力してもらうとします。passwordが「111」とかだったらセキュリティーが甘くなりますね。
そこでバリデーションを記載してpasswordを8文字以上にしないと登録できないようにすれば、「111」と入力しても弾かれて保存できないようになります。
バリデーションの組み方は無数にあり、やり方を変えれば自分の思い通りに値を保存することができます。

例１）
モデルに下記のように記載すれば空では保存できません。

```ruby:product.rb
class User < ApplicationRecord
  validates :title, presence: true
end
```
例２）
モデルに下記のように記載すれば漢字のみ保存できるようになります。

```ruby:product.rb
class User < ApplicationRecord
  kanji = /\A[一-龥]+\z/
  validates :name, format: { with: kanji }
end
```
例3)
モデルに下記のように記載すれば"2019-10-04"のような形でのみ保存できるようになります。

```ruby:product.rb
class User < ApplicationRecord
  year_month_day = /\A\d{4}-\d{2}-\d{2}\z/
  validates :birthday, presence: true, format: { with: year_month_day }
end
```

#バリデーションエラーメッセージの出し方

**①商品の保存を行うアクション（ここではcreate）に保存の成功/失敗の条件分岐を記載。**
ここで気をつけて欲しいのは失敗時のviewの読み込みはrenderを使用しましょう。
理由は後で解説します。

```ruby:products_controller.rb
  def create
    @product = Product.new(product_params)
    if @product.save
      redirect_to controller: :products, action: :index
    else
      render "new"
    end
  end
```
**②エラーメッセージのview作成**
htmlのif文をmodel.errors.any? にしておくことでどのモデルのバリデーションにも対応させることができます。

```ruby:layouts/_error_messages.html.haml
-if model.errors.any? 
  .alert
    %ul
      -model.errors.full_messages.each do |message| 
        %li= message
```

```ruby:layouts/error_messages.scss
  .alert {
    color:#262626; 
    background:#FFEBE8;
    text-align: center;
    border:2px solid #990000;
    padding:12px; font-weight:850;
  }
```

**③エラーメッセージの表示**
あとはエラーメッセージを表示させたいところに以下のコードを記載するだけです。

```ruby:products/new.html.haml
 = render 'layouts/error_messages', model: f.object
```

完成です。
こんな感じになります。めちゃめちゃ簡単です。

![スクリーンショット 2019-10-04 17.31.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501638/200a0009-eff1-79bd-3346-9707973211ca.png)


#redirect_toとrenderの違い

先ほど、失敗時のviewの読み込みはrenderを使用すると記載しましたが、そこについて軽く触れます。
redirect_toとrenderはルーティングを通るか通らないかという違いがあります。
**redirect_to…ルーティングを通り、新たにviewページを呼び出す。
render…ルーティングを通らず、viewページに飛ぶ。**
正式にはもっと違いがありますが、とりあえずこの認識でOKです。

なので失敗時のviewの読み込み（以下の部分）をredirect_toにすると、
新しいビューページが呼ばれてしまうため、ページに書いたif文が反応しません。

```ruby:products_controller.rb
  def create
       ~省略~
    else
      render "new"
    end
  end
```

#おわりに
特定のgem（例えばdeviseとか）には初めから実装されていることがあります。
ぜひ調べてみてください:santa::santa:
プログラミング未経験者の奮闘記

# 自己紹介

初めましてこんにちは。kazuyoshi（かずよし）と申します。

ツイッターでも１日ごとの経過を投稿しておりますが、学んだことをアウトプットしたいなと考えていたのでQiitaを用いて１週間ごとの報告&アウトプットをしていきたいと思います。

今回初めての記事投稿なのでまずは自己紹介をさせて頂きます。

私の経歴は地方国立大学の化学科を卒業して旧帝大院に進学、その後就職活動で第一志望であった高倍率の化学メーカー研究開発職に就職しました。（売り上げ3000億円規模の中堅企業）

モノづくりが好きで工学部に進学して専攻してきた有機化学の知識が活かせる満足な就職先でした。

なら、どうしてその専門性を捨ててエンジニアへ転職しようとしているのか疑問に思われると思います。

エンジニアになりたいと思うに当たって影響があった事柄として

1.修士2年就活終了後にyoutubeで[Somewhat Japanese By Sashi](https://www.youtube.com/channel/UClxDs-wxR4dOZjbrI5V-1uA/featured)さんの動画を見てエンジニアの考え方やストイックさに憧れた事（筋トレもこの時期からsashiさんの影響で始めました）

2.企業に就職して新聞や情報サイト等で製造業をはじめとして、化学の分野でもDX（デジタルトランスフォーメーション）の流れがきていると知り成長産業に関わりたいと思った事

3.既存産業とITの掛け算で変化を起こす側になるために、非情報系院卒２６歳がITを学ぶのも年齢的に遅すぎるかなと悩んでいた時に＠fuku_techさんの記事[（化学系研究者が完全未経験からWeb系自社開発企業に転職するまで）](https://qiita.com/fuku_tech/items/b8db09720c6d38eb27b9)を見て「先を越されてる！！」という気持ちと「似たような人もいるもんだなー」という気分になった事（笑）

これらのことから
・IT×既存産業で新たな価値やものの創造が出来る時代になってきた事
・それに伴いこれからますますITスキルの需要が伸びるであろうこと
・年齢的にも未経験でIT業界への就職は可能である事
がわかりエンジニアへの転職を考え始めました。

しかしプログラミングに適性があるかコードを描いてみないとわからないので取りあえずprogateをやってみて見極めようと思いました。

HTML、CSS、JS、Ruby、rails、python、MySQL（一部）の課金コンテンツをやってみたところ意外にできそうだと感じて、「一度きりの人生、２０代でチャレンジしなきゃ絶対後悔するだろうな」と思い、エンジニアになろうと決意して2019年９月に前職を退職し１０月より３ヶ月間渋谷の某教室型プログラミングスクールに通うことにしました。

まだまだ右も左も分からない状態ですがこれまで人生で発揮してきた継続性を武器に技術や経験の積み上げを行いたいと考えているのでよろしくお願いします。

# まとめ
IT×既存産業に興味があり、そうしたプロジェクトにエンジニアとして参画したい

年齢的にもエンジニアになることは可能であるのでエンジニア転職を決意した

ツイッターに１日の報告とQiitaで週１のアウトプットを行う（取りあえず１００日間を目標！！）


初学者なので始めは大したアウトプットはできないと思いますが継続することで質を上げていきたいと思います。
NomadのClient起動時に`client unexpected keys host_volume`

遭遇時のバージョン
--------------------

- Nomad: `0.9.5`

状況
--------------------

### 導入

Nomad Clientに`host_volume`を付けて、永続ストレージを使いたかった。
そのため、以下のような設定ファイルを作った。

```hcl
client {
  ...
  host_volume "volume" {
    path = "/tmp/volume"
  }
  ...
}
```

Nomad Clientの実行は、特に難しくなく設定ファイルのみを指定した。

```sh
sudo nomad agent -config ./client.hcl
```

### 現象

上記Nomad Clientの実行時に、以下のエラーが出る。

```
===> Error loading configuration from ./client.hcl: Error loading client.hcl: client unexpected keys host_volume
```

[Nomadの公式サイトの仕様](https://www.nomadproject.io/docs/configuration/client.html#host_volume-stanza)や、[GitHubのソースコード](https://github.com/hashicorp/nomad)、テストコードでも`client { host_volume [] }`があるのに、なぜか解析エラー扱いになる。
また、ACLの`host_volume`節も同じように、期待されていないキー扱いになる。

### 解決

最新版は`0.10.0-beta1`だったので、[このバイナリ](https://releases.hashicorp.com/nomad/0.10.0-beta1/)をインストールしてみたら、解析エラーは出なくなった。
→ソースコードを見るときに、きちんとgitでcloneしとけば、コミットログから違いをもう少し追えたはず。。反省。
imagemagickを使って画像をアップロードするとSSLが外れてしまう時の対処法

minimagickのgemを使って画像をアップロードすると、その画像が表示されるページのSSLマークが外れるという問題が発生したので、その時の解決方法を残します。

##このサイトで目にする画像は、悪意のあるユーザーによって差し替えられたものである可能性があります

###事象
・minimagickのgemを使って画像をアップロードすると、その画像が表示されるページでSSLマーク（鍵マーク）が外れ、びっくりマークに変わる
・びっくりマークをクリックすると「このサイトで目にする画像は、悪意のあるユーザーによって差し替えられたものである可能性があります」のメッセージがでる。

###解決方法
nginxのconfファイルにproxy_set_header X-Forwarded-Proto https;を追記

```/etc/nginx/conf.d/hoge.conf
location @app {
 proxy_set_header Host $http_host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Host $http_host;
 proxy_set_header X-Forwarded-Server $hostname;
 proxy_set_header X-Forwarded-Proto https; #この一行を追加
 proxy_set_header X-Real-IP $remote_addr;
 proxy_redirect off;
 proxy_pass http://app_server;
 }
```

Nginx再起動

```
systemctl restart nginx
```
##解決までの流れ

###①画像ファイルへのリンクの確認
この事象はサイト内で使用している画像に、httpアクセスで記述している箇所があると発生するらしいので、デベロッパーツールで画像リンクのプロトコルを確認。
参考：https://stackdesign.jp/how-to-create-ssl-wordpress-site/

→きちんとhttpsになってた。

###②Railsの環境設定を変更
production.rbのconfig.force_ssl = trueを有効にすると、本番環境でSSL通信を強制できるので、コメントアウトを外し設定を有効にして再デプロイ。
参考：https://railsguides.jp/configuring.html

```/config/environments/production.rb
config.force_ssl = true
```

→ページにアクセスできなくなる
メッセージ
・このページは動作していません
・リダイレクトが繰り返し行われました。

→再びコメントアウト

###③nginxのconfファイル修正
HTTPSアクセスであることをX-Forwarded-ProtoでRailsへ通知することでリダイレクトのループを回避する。
参考：https://keruuweb.com/rails-nginx-https%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%92%E3%81%99%E3%82%8B/

```/etc/nginx/conf.d/hoge.conf
location @app {

 proxy_set_header X-Forwarded-Proto https; #この一行を追加

 }
```

→無事に全ページでSSL化が有効になりました

##まとめ

「proxy_set_header X-Forwarded-Proto https;」はリダイレクトのループを回避するための設定で、本来はSSL化をする際に設定しておく必要があったらしい。

SSL化の際にきちんと設定ができていたら、そもそも今回のエラーは生じなかったってことですね、、、
勉強会のサテライトリージョンを作るためのTips

# ちょっと今回は毛色が変わる記事を

先日、こちらの勉強会に・・・
[PowerAppsでローコーディングなハッカソン＆ハンズオン！同時開催！](https://powerapps.connpass.com/event/147590/)

福岡の会議室からWeb会議システム（Microsoft Teams）を使用して接続し、サテライト会場としたのです。
[JPAUG 合同企画 PowerApps ハッカソン in Fukuoka](https://o365jpfuk.connpass.com/event/147258/)

これが意外と好評でして
勉強会が都会に集中してて、地方の方が参加できない！！という悲しい現実を
打破できるのではないかという~~妄想~~野望が芽生えたので
皆さんにぜひ活用していただきたく、Tipsとしてまとめました。

# Web会議システムの選定
前提として、基本的に無料もしくは勉強会の内容的に既に使用しているものを使いたいものです。
以下にいくつかピックアップしています。
機能比較はさすがに勘弁させて頂きたいところですが

- 複数人会話ができるかどうか
- 会議時間の制限
- 資料の共有方法
- 会議への参加方法
- 時間当たりの帯域使用量（後述）

といった観点で決めるとよいかと思います。

## Microsoft Teams無料版
https://products.office.com/ja-jp/microsoft-teams/free

## zoom 無料版
https://zoom.us/jp-jp/meetings.html

## Skype
https://www.skype.com/ja/

# 機材の選定
Web会議を実施する上で必要となるのが配信する機材ですね。
しかも双方向会話だとそれぞれの拠点にて必要となるものが出てきます。

## カメラ
これは当然必須ですね。
相手の会場の様子が見える見えないで、臨場感がかなり変わってきます。
登壇者の映像も確かに必要ではありますが、会場の様子も見せると更に良いでしょう。

### 会場撮影用カメラ

会場は広く撮影したいため、広角レンズを搭載したカメラが必要です。
ですが、一般的に販売されているWebカメラは一人用がほとんどで、それらは広角には対応していません。

基本的に一眼レフカメラのHDMIポートをソフトウェアエンコーダーにつないでWebカメラ化するというやり方が一般的ではありますが、ソフトウェアエンコーダーを使用するには、それなりにハイスペックなマシンが必要となってくるためお勧めしません。
何より、Webカメラとして認識してくれるかも正直怪しかったりもします。
そして結構めんどくさいです。
ここは、USB接続でWebカメラと認識してくれつつ広角レンズもつけられるものがいいですよね。

#### 私がおすすめするカメラ

https://www.amazon.co.jp/gp/product/B07RT535VG/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/8450af1d-3a4e-13cd-0b3d-49223f869f47.png)

中国製だから怪しいのでは？と思われるかと思います。
ビデオカメラとしての性能は正直あてにしない方がいいです。
手振れもついてませんしね。
ですが、こいつをなぜお勧めするかというと、実はUSB接続でそのままWebカメラとして認識してくれます。
拡大・縮小もカメラ側で制御できますので、今までのWebカメラではなかなかできなかった表現ができますし、標準で広角レンズもついています。
また、同梱されているガンマイクも装着することで、会場の音声も拾ってくれますからかなりおすすめですよ。

### マイク

会場の様子を伝えるには、マイクも当然会場の音を拾ってあげる必要があります。
パソコン標準搭載のマイクや、一般的なマイクは、指向性マイクという種類になり
一方向の音のみを収集する為、周りの音を拾うことができません。
会議室用に用意されている、複数のマイクが搭載されたものが望ましいです。

#### 私がおすすめするマイク
https://www.amazon.co.jp/gp/product/B07Q3FQ8K6/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e0fb3bd7-45f9-18bc-59ed-b09e0d5fabe7.png)

会議室用のマイクで複数のマイクが搭載されているものですと
大体1万5000円以上します。
ですが、これはその半分の値段ながら、かなり広範囲の音も拾ってくれます。
100名近く入る会議室の場合は、カメラ搭載のガンマイクの方が良いですが
20名程度の会議室であれば、むしろこちらの方が良いかと思います。
スピーカーもついてますからね！一石二鳥です。

### パソコン
ミドルクラスのPCは必要と思ってもらったほうがいいです。
最低でもCore i3以上はほしいところ。
かといって大きいパソコンだとかさばりますし、何より重いですよね。
できればUMPCぐらいが望ましいです。

#### お勧めするパソコン
https://www.amazon.co.jp/dp/B07RXTTNT8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/b1d89b3a-54f1-60b7-f3e7-149c1a49ff33.png)

8インチ程度と超小型ながら、中身は非常にパワフル。
これぐらいのスペックであれば、よほどのことがない限り大丈夫でしょう。


### それ以外に必要なもの

- 三脚
- 5m~20mの延長USBケーブル
- 高速で安定的な独立したインターネット回線　※

※ほかの方と同じ回線だと、帯域を奪い合って配信にかなりの支障を及ぼします。
　可能であれば、配信とゲスト用は分離すべきです。

機材としてはこれぐらいでよいかと


# 注意するべきこと

## 遅延は気にしたら負け

回線にもよりますが、たいてい遅延します。
こちらが話しかけた相手に音声や映像が届くのは５～１０秒はかかると思ってください。
いちいち気にしていては話が一向に進みません。
また、聞く側は、相手が話し終わったタイミングで都度うんうんなど、きちんと聞こえて理解したアピールをするとスムーズに進むと思います。

## 回線は分離

ゲストの通信は参加者や時期にもよりますが、かなり大量に発生します。
特にWindows Updateが走るであろう日程は、ほとんど回線を食いつぶすため、安定的な会議となりません。

## コミュニケーションは大事
配信中もスタッフはお互い連絡を密に行い、段取りを都度確認しつつ進行してください。
しゃべってる側はその辺気にする暇正直ないですしね。
GradleプロジェクトでSource not found

## 事象
#### Jarファイルの中身が見えない
Jarファイルが見えないからソース添付したいけど「Edit Source Lookup Path...」ボタンがないのでできない。
エラーメッセージにできないっぽいことが記載されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/504a9b21-fac9-aedd-19b9-3b99b634c571.png)
<font color="red">`The JAR of this class file belongs to container ‘Project and External Dependencies’ which does not allow modifications to source attachments on its entries`</font>
Google翻訳：
このクラスファイルのJARは、コンテナ「プロジェクトと外部の依存関係」に属します。このコンテナでは、エントリのソース添付ファイルを変更できません

## 原因
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/7cda2fda-435c-1aba-fcf4-3010b1744b11.png)
大元のプロパティ見てみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/3d9252bb-dd54-1267-2044-8933eeba270b.png)
gradleを通してみているのでソースファイルの添付はできないらしい

## 解決
できないので、プラグインのdecompilerつかう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/90d5ec63-9377-a389-dc8f-68a11fc5e59c.png)

プラグインいれたら再起動して、「Class Decompiler Viewer」をDefaultにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/247bc4f1-9300-a6b6-c49a-6a23909f180b.png)

classファイルを開くとみれるようになっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/456aa677-e411-cb75-fe38-3cdc252560f0.png)
This object represents a Chatter Group Announcement.

https://blog.enree.co/tag/group


select FeedItem.Body, ExpirationDate, Parent.Name from Announcement

To create the object programmatically follow these rules:

//query the Collaboration Grouop
CollaborationGroup group = [Select Id From CollaborationGroup Where Name = 'Awesome Group'];
 
//creates a feed item; type "AdvancedTextPost" is mandatory
FeedItem item = new FeedItem(Type='AdvancedTextPost', ParentId=group.Id, Body='This is an awesome announcement');
insert item;
 
//create the announcement
Announcement anc = new announcement(FeedItemId=item.Id, ExpirationDate=System.today().addDays(10));
insert anc;
 
//upate the group
group.AnnouncementId=anc.Id
update group;
ダブルコーテーションとブランクの両方を含む文字列を条件に使うときは遅延変数で使う

# ダブルコーテーションとブランクの両方を含む文字列を条件に使うときは遅延変数で使う

結論はこのとおりです。

一応環境載せておきます。

```
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
```

変数を用意しておきます。
挙動を確認するため echo on にします。
遅延変数の宣言もします。

```batch
@echo on
setlocal enabledelayedexpansion

REM ダブルコーテーションとブランクを含む文字列
set str1="C:\Program Files\hoge\foo.exe" "%%1"
REM 同じもの(別になんでもいいです)
set str2="C:\Program Files\hoge\foo.exe" "%%1"

echo 1: %str1%
echo 2: %str2%
```

```:出力
>setlocal enabledelayedexpansion

>REM ダブルコーテーションとブランクを含む文字列

>set str1="C:\Program Files\hoge\foo.exe" "%1"

>REM 同じもの(別になんでもいいです)

>set str2="C:\Program Files\hoge\foo.exe" "%1"

>echo 1: "C:\Program Files\hoge\foo.exe" "%1"
1: "C:\Program Files\hoge\foo.exe" "%1"

>echo 2: "C:\Program Files\hoge\foo.exe" "%1"
2: "C:\Program Files\hoge\foo.exe" "%1"
```

これに追記していきます。

## 駄目なパターン１: %変数のまま使う

```
if %str1% == %str2% (
    echo OK
) else (
    echo NG
)
```
```:出力
"%1" の使い方が誤っています。
>if "C:\Program Files\hoge\foo.exe" "%1" == "C:\Program Files\hoge\foo.exe" "%1" (
```

誤っているそうです。
これはよく「ブランクを含む文字列を使うときの注意」とかで解説されているやつですね。


## 駄目なパターン2: %変数を `"` でくくって使う

```
if "%str1%" == "%str2%" (
    echo OK
) else (
    echo NG
)
```
```:出力
Files\hoge\foo.exe" "%1"" の使い方が誤っています。
>if ""C:\Program Files\hoge\foo.exe" "%1"" == ""C:\Program Files\hoge\foo.exe" "%1"" (
```
%変数 を `"` でくくるというのはよくある解決策として挙げられていますが、これではダメです。

`""C:\Program` と `Files` 以降で分かれちゃったようです。
`Files` 以降 は `Files\hoge\foo.exe" "%1""` でひとかたまりなのかな？その間にブランクがあるけれども。
よくわかりません。

## うまくいくパターン: 遅延変数を使う
```
if !str1! == !str2! (
    echo OK
) else (
    echo NG
)
```
```:出力
>if !str1! == !str2! (echo OK )  else (echo NG )
OK
```
構文エラーは出ませんでした。

遅延変数は、`"` でくくってもくくらなくてもちゃんと動きます。

`"` でくくった場合は、 「くくった`"`も含む文字列」の比較になります。

## どんなときに使うねん

`ftype` コマンドでファイルとアプリケーションの関連付けを見ると、`"` と ` `(ブランク) が使われた文字列が出てきます。

e.g. .docファイル

```
>assoc .doc
.doc=Word.Document.8

>ftype Word.Document.8
Word.Document.8="C:\Program Files (x86)\Microsoft Office\Root\Office16\WINWORD.EXE" /n "%1" /o "%u"
```

この辺いじってたら気づきました。

~~`"C:\Program Files\~~"` みたいなファイルパスにしおってからに・・・~~
GCP アップデート (9/27-10/3 2019)

### CloudSQL: [Sep 27, 2019](https://cloud.google.com/sql/docs/release-notes#september_27_2019)
- Postgres11がGAになったよ。
  - デフォルトで作成されるのも11に。

### Compute: [Sep 27, 2019](https://cloud.google.com/compute/docs/release-notes#september272019)
- Cascade LakeベースのN2マシンタイプがGAになったよ。

### BigTable: [Sep 25, 2019 日付不正?](https://cloud.google.com/bigtable/docs/release-notes#September_06_2019)
- java用のクライアントライブラリがGAになったよ。

### NAT: [Sep 30, 2019](https://cloud.google.com/nat/docs/release-notes#September_30_2019)
- NAT IPをdrainしてくれる機能がGAになったよ。
  - drainされたIPがを新規接続で利用しなくなるので影響なくIPを捨てる。

### Compute: [Oct 1, 2019](https://cloud.google.com/compute/docs/release-notes#october012019)
- OVAインポートがGAになったよ。

### GKE: [Sep 26, 2019 日付不正？](https://cloud.google.com/kubernetes-engine/docs/release-notes#september_26_2019)
- バージョンアップデートのお知らせ。
  - デフォルトがv1.13.7-gke.24になったよ。
  - 1.11は1.12に10/7週にアップグレードされるよ。

### Dataprep: [Sep 16, 2019 日付不正?](https://cloud.google.com/dataprep/docs/release-notes#September_16_2019)
- 前のAPIの話。dataflow template実行ではなく、dataprepのAPIで直接管理する。

### Compute: [Oct 2, 2019](https://cloud.google.com/compute/docs/release-notes#october022019)
- OSやカーネル、パッケージの情報を収集して確認できるOS Inventory ManagementがGAになったよ。

### GKE: [Oct 2, 2019](https://cloud.google.com/kubernetes-engine/docs/release-notes#october_2_2019)
- メンテナンスの開始時間や期間、繰り返しの時間を指定できるようになったよ。

### 

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
DPO(Data Protection Officer)の役割と選任

GDPR 第37条に当てはまる場合はDPO(Data Protection Officer)と呼ばれるデータ保護オフィサーを選任する義務があります。

そもそもGDPRって何？という方はこちら → [EU一般データ保護規則（GDPR）の概要](http://www.intellilink.co.jp/article/column/security-gdpr01.html)

#TL;DR
DPOには

* 個人情報保護に対する専門知識を有する人を任命
* 社外の人を雇って任命してもいい

そしてDPOは以下を実行しなければならない

* 組織内のデータ管理者、処理者に対してGDPRの周知徹底、教育、遵守の監査、アドバイスをする
* 監督機関との連絡窓口として行動
* データ取り扱い業務の潜在的問題やリスクに対し先見的な対応

# データ保護オフィサーを選任しなければいけない場合はどのような場合か
GDPRの第37条に定義があります。[^1]
[^1]: GDPR日本語訳(個人情報保護委員会) - https://www.ppc.go.jp/files/pdf/gdpr-provisions-ja.pdf
> (a) 公的機関又は公的組織によって行われる場合。ただし、裁判所がその司法上の権限を行使する
> (b) 管理者又は処理者の中心的業務が、 その取扱いの性質、範囲及び又は目的のゆえに、データ主体の定
期的かつ系統的な監視を大規模に要する取扱業務によって構成される場合
> (c) 管理者又は処理者の中心的業務が、第9 条による特別な種類のデータ及び第10 条で定める有罪判決及
び犯罪行為と関連する個人データの大規模な取扱いによって構成される場合。

日本の企業でもEUに支店等の拠点をおく場合で上記のいずれかに当てはまる場合
EUに拠点が無くとも、日本国内のサービス等でEU市民の個人情報を取り扱う場合で上記のいずれかに当てはまる場合

**EUに拠点がなくても日本国内でEU市民の個人情報を取り扱う場合** というのがミソです。

# DPOって誰がやればいいの？
GDPR第37条では以下のように規定されています。
> データ保護オフィサーは、専門家としての資質、及び、特に、データ保護の法令及び実務に関する専門知識
並びに第39 条で定める職務を充足するための能力に基づいて指定される。

簡単に言えば **個人情報の保護に対する専門知識を有していて、それを実践できる人** ですね。

また、第37条第6項にあるように、DPOの選任にはデータの管理者や処理者の中からでもいいですし、外部から業務委託などで雇ってもいいそうです。
> 6 . データ保護オフィサーは、管理者又は処理者の職員とすることができ、又は、業務契約に基づいてその職務
を果たすことができる。

# DPOの責務と役割
具体的にDPOがすべきことは以下のようなことです。
第39条に記述がありますが簡単にまとめると次のようになります。

- 他のデータ管理者、処理者に対してデータの取り扱いについて教育
- GDPRに遵守して個人データが取り扱われているか監査
- 監督機関との連絡先として行動し、監督機関に協力する
- 取り扱いのデータについて範囲や性質を理解した上でリスクに注意を払う
- データ取り扱い者に対する責任の適正な割り当て


## 組織内での立場
DPOはデータの管理者もしくは処理者である場合、
通常と同じように業務として行うものの、独立性が守られています。

これは第38条で以下のように規定されています。
> 管理者及び処理者は、個人データの保護に関連する全ての問題に、適正かつ適時に、データ保護オフィサー
が関与することを確保しなければならない。

> 管理者及び処理者は、データ保護オフィサーが、その職務の遂行に関し、いかなる指示も受けないことを確
保しなければならない。当該データ保護オフィサーは、当該データ保護オフィサーの職務の遂行に関して、管
理者又は処理者から解任され、又は罰則を受けることがない。データ保護オフィサーは、管理者又は処理者の
最高経営者レベルに対して直接報告しなければならない。

DPOはデータの管理者、処理者からの指示や罰則は受けず、独立した立場から個人情報の取り扱いについて監査、助言します。
また、最高経営者レベルに対して直接報告する立場にあります。

# まとめ
GDPRが適応されなくとも個人情報の取り扱いというのはリスクが大きいため、適切に対策する必要があります。
GDPRに対応しなければいけなくなった今、これをきっかけにして組織内での取り扱いや、個人個人への教育が行われるととても良いかと思います。
俺は "楽して" Reactを "試して" みたいんだよ！

Reactを触ってみたいけど、

- ちょっと敷居高そうだな～
- 環境作るのめんどくさそうだな～

と思っているあなたへ。

ちょっと試してみたいだけなら、とても簡単に環境を用意できます。
以下のコードをHTMLファイルとして保存し、ブラウザで表示してみてください。

```html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>easy react</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script type="text/babel">
        class HelloWorld extends React.Component {
            render() {
                return (
                    <h1>
                        {this.props.text}
                    </h1>
                )
            }
        }
        ReactDOM.render(
            <HelloWorld text="HelloWorld!!" />,
            document.getElementById("root")
        );
    </script>
</body>

</html>
```

**`HelloWorld!!`**と表示されたと思います。
簡単ですね。
ちょっと試してみたいだけなら、これでも十分です。

しかし、このままではVSCodeでオートフォーマットが効きません。
`<script type="text/babel">`を`<script type="text/javascript">`に書き換えることで、オートフォーマットが効くようになります。
コードを書いているときは`text/javascript`、実行するときは`text/babel`といった具合に使い分けましょう。

興味が湧いたら、ぜひ公式へ！
[**React 公式ページ**](https://ja.reactjs.org/)