OmniAICreator/Qiita-1.07M huggingface dataset:
無料で説明図を作るならドローツール「draw.io」が一番簡単？

#はじめに
最近、当方の記事では作図ツールなど、プロジェクトの標準化に役立ちそうな
ツールや知識をまとめています。
今回もその一環で、フローチャート、概念図などを作成する際に役立つツール「draw.io」を取り上げてみたいと思います。



#特徴
・無料
・登録不要
・日本語対応

Gliffyの場合はオンライン利用の場合名前、メールアドレスの登録が必要かつ英語のみですのでこの点は比較して楽な点と言えます。

#他のツールより優れている点

①パーツやテンプレートが豊富
これだけのことが簡単にできるのは、最初から用意されている図のパーツが豊富だからというのもあります。
最初の画面で上を選ぶとテンプレートを利用できます。

![chosen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/0d3df175-b800-f119-6173-3be4b4891f32.png)

とりあえず、ざっと数えただけでも800以上ものパーツがデフォルトで用意されています。
カスタムして追加すると、更にパーツを増やすことができ、総数2000以上はあるという説もあるようです。
正直、有料ツールでも、ここまで多いものはそうないような気がします。
![templelist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/26f13e91-ea2c-25ad-cc74-7eb0c67be15a.png)

プロジェクトや資料の用途ごとにパーツを選べるのでで、テイストの違う図を作成しやすいのはGoodですね。
テンプレートを選ぶことで白紙からでなく大枠からはじめられるのも便利。

②保存場所を選べる
保存場所はGoogleドライブ、OneDrive、Dropboxのサービスの中から選ぶこともできます。もちろんローカルディスクにも保存することができます。

![saveAspng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/730f03dd-145b-b0fe-266f-ea42f5db7c92.png)


好きなクラウドドライブに保存できるのは、どこからでも編集できて便利です。
情報をクラウドにあげたくない場合は、ローカルに保存できるというのもいいですね。

③フォントも自由に設定
フォントの設定画面から、「カスタム」を選ぶことでパソコンに入っているフォントなら、自由に使うことができます。

![FontCustom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/36cc3e59-462c-353a-d692-1616e6158dbe.png)


一度登録すれば、同じブラウザなら手軽に利用できるようになります。
フォントが登録される

draw.ioは、このようにフォントも自由に設定できます。同じ手軽に使える無料のGliffyは、日本語のフォントは選択できず、全てOSデフォルトのフォントになっていました。
draw.ioは、フォント以外にも随所でこういった細かな設定ができるようになっています。
資料のテイストに合わせフォントを使いたい場合などはこの方法を使って好きなものに変えてしまいましょう。



#使い方
draw.ioの使い方は、基本的に以下の2つを押さえておけば、ある程度利用できると思います。

配置する
図同士を繋ぐ
配置する
まずは、左側のステンシルから、図をドラッグ＆ドロップで作業領域に配置します。

ステンシルを配置する

![drag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/26945fc4-e3f6-9ceb-b434-e2afd9a08f8b.png)



あとは、関連するステンシル同士を繋ぐだけです。

![stencle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/db3116cc-8876-c28c-dcf2-9ae278b1a7e7.png)


他にも設定はいろいろありますが、基本的な動作で、この2つを押さえておけば図の半分以上はできたも同然です。

あとは、ステンシル（図のパーツ）にテキストを挿入したり、大きさを調整したり、色をつけたりして、属性を変更するだけです。

保存
保存もメニューの「ファイル」から「Export as」を選択することで、いろいろな形式で保存することができます。
![saveAspng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482202/730f03dd-145b-b0fe-266f-ea42f5db7c92.png)





#まとめ
draw.ioを利用すれば、大抵の説明図ならパパパっと短時間で作ってしまえるかと思います。
いろいろ使ってみたのですが、すぐ思いつくだけでも以下の点が素晴らしいです。

・登録不要で簡単に開始できる
・操作が簡単
・操作が軽い （操作性が良い・感覚的）
・日本語対応
・ステンシル（図のパーツ）が豊富
・機能が豊富（豊かな表現ができる）
・保存方法を選べる
・出力方法も豊富（一般画像、PDF、SVG、HTML、iframeで埋め込むなど）
・PCに入っているフォントなら自由に使える（要フォント名入力）
・完全無料



有料ツールでも、ここまで機能豊富なものは、そうなさそうな気がします。
とりあえず、「図説用のドローツールはどれを使ったらよいかわからない、すぐ使いたいという場合は、draw.ioを選んでおけばまず間違いないと思います。。。！



参考：https://ferret-plus.com/8408
JSでbase64のエンコード/デコードする方法

### 実行環境
Chrome ver. 79.0
Dev toolのコンソールで動作確認

base64へのエンコードはbtoaコマンド

```
btoa("This is a test.")
> "VGhpcyBpcyBhIHRlc3Qu"
```

base64でエンコードされた文字列のデコードはatobコマンド

```
atob("VGhpcyBpcyBhIHRlc3Qu")
> "This is a test."
```
VSCodeでファイルを開くたびに前のタブが消える

VSCode初心者のアクマちゃん([@akumachanit](https://twitter.com/akumachanit))です！

#（悪魔に逆らう反逆者のごとき）許せない挙動
VSCodeでファイルを開くとタブに*イタリック*で名前が表示されて、次のファイルを開くと*イタリック*で表示された前のタブが消えてしまう！

↓こんな感じ
![vscode-enable-preview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542817/f5e92282-a27e-bc46-70a3-a2439544aad7.gif)

**許せん！**

この挙動はファイルをダブルクリックで開いたときには起こらない。
だけど俺は`Ctrl+p`からの`→`でファイルを開いている！よくも俺の快適なコーディングを！！駆逐してやる！！

この挙動は`workbench.editor.enablePreview`がデフォルトで`true`になっているから起こる。
`false`にしてやる〜〜〜〜〜！

#駆逐してやる！

####手順

 - `Command(WinではCtrl)`+`Shift`+`p`でコマンドパレットを開く
 - `Preferences: Open Setting(UI)`を検索して開く
 - `Search settings`で`enablePreview`と入力
 - `Workbench > Editor: Enable Preview`のチェックをはずす

![vscode-disable-preview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542817/e062c911-47fd-468c-1ddd-2e6c4749db80.gif)
*オラオラオラオラァァァァ！！！！*

####んで、こうなる

![vscode-dsable-preview-done.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542817/504c76fc-4b1c-aa6b-7b97-da9331537e2d.gif)
*オラオラオラオラオラオラオラオラオラオラァァァァ！！！！*

#まとめ
**開きすぎ注意。**



仲良くしてください！[@akumachanit](https://twitter.com/akumachanit)
Flutter 正方形にカメラの映像を表示させるサンプル


## 実現したいこと
正方形にカメラの映像を表示させる

## 動作の様子
![IMG_5485 2.2020-01-30 15_06_52.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6327/58219644-8928-e2b1-7de3-026c36bab81a.gif)

## 動作コード
こちらに一式用意しています。
https://github.com/quqjp/flutter-test

コード箇所はこちら。
https://github.com/quqjp/flutter-test/tree/master/lib/sample4

## 利用プラグイン
Camera Plugin
https://pub.dev/packages/camera

installing に従い導入する
https://pub.dev/packages/camera#-installing-tab-

## コード
FittedBoxで囲ってセンタリングすることで、映像の中心を保ちつつ正方形にマスク処理できた。
FittedBox内に、AspectRatioを用いてCameraPreviewを配置しようとしたが、うまく行かず。
幅は親要素で決まるので、わざわざMediaQueryでsizeを取得したくなかったが
FittedBox内は、親要素幅を引き継いだWidget配置ができなかったためこのようにした。

映像のセンターが正しく中心に表示されているか確認のため、
右上の★ボタンを押すことで、表示の比率を変えるようにしている。

```dart
//dart package
import 'package:flutter/material.dart';

//third party package
import 'package:camera/camera.dart';

//my package

//same package

//
// カメラの映像を正方形で表示させるサンプル
//
class Sample4Page extends StatefulWidget {
  Sample4Page({Key key, this.title}) : super(key: key);

  // タイトル
  final String title;

  @override
  _State createState() => _State();
}

class _State extends State<Sample4Page> {
  //カメラリスト
  List<CameraDescription> _cameras;

  //カメラコントローラ
  CameraController _controller;

  //
  double _aspectRatio = 1.0;

  @override
  void initState() {
    super.initState();

    initCamera();
  }

  //
  // カメラを準備
  //
  initCamera() async {
    _cameras = await availableCameras();

    if (_cameras.length != 0) {
      _controller = CameraController(_cameras[0], ResolutionPreset.high);
      _controller.initialize().then((_) {
        if (!mounted) {
          return;
        }

        //カメラ接続時にbuildするようsetStateを呼び出し
        setState(() {});
      });
    }
  }

  //
  // カメラの表示比率を変更する
  //
  _toggle() {
    setState(() {
      _aspectRatio = _aspectRatio == 1.0 ? 0.7 : 1.0;
    });
  }

  ///
  ///
  ///
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.star),
            onPressed: () {
              _toggle();
            },
          ),
        ],
      ),
      //
      body: Container(
        alignment: Alignment.center,
        child: AspectRatio(
          aspectRatio: _aspectRatio,
          child: FittedBox(
            alignment: Alignment.center,
            fit: BoxFit.fitWidth,
            child: _controller != null && _controller.value.isInitialized
                ? Container(
                    width: size,
                    height: size / _controller.value.aspectRatio,
                    child: CameraPreview(_controller))
                : Container(),
          ),
        ),
      ),
    );
  }
}
```
BERT日本語モデルについてまとめ

BERTを使うことがあったので、現在公開されている日本語モデルについてまとめてみました。
フレームワークやトークナイザーのあたりはざっと資料を読んで書いてるので、本当はこうだよ！というご指摘お待ちしております。

| 制作者 | フレームワーク | 形態素解析器, トークナイザー | ソース | ライセンス | URL |
|---------------------------|-------------------------------------|------------------------------------|-----------------------------------|------------|--------------------------|
| Google | TensorFlow 2 | WordPiece? | 日本語Wikipedia? | Apache2.0 | https://li.dott.dev/FrR9 |
| 京都大学 黒橋・河原研究所 | TensorFlow 1x, PyTorch, Transformers | Juman++ | 日本語Wikipedia | Apache2.0 | https://li.dott.dev/VuH4 |
| 東北大学 乾・鈴木研究室 | TensorFlow ?, PyTorch, Transformers | MeCab(IPADic, NEologd) + WordPiece | 日本語Wikipedia | Apache2.0 | https://li.dott.dev/SGnp |
| 菊田遥平 | TensorFlow < 2.0 | SentencePiece | 日本語Wikipedia | Apache2.0 | https://li.dott.dev/fM6F |
| 株式会社ホットリンク | TensorFlow 1.11 | SentencePiece | Twitter日本語評判分析データセット | 独自規約 | https://li.dott.dev/yhRr |
| NICT | TensorFlow 2, PyTorch, Transformers | MeCab-Juman | 日本語Wikipedia | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja) | https://li.dott.dev/Y1q5 |
Webサイトのアクセス解析の第一歩【Googleアナリティクスの開設】

# はじめに
お仕事で、GoogleAnalyticsを導入する場面があったので、毎度調べなくて済むように導入方法についてここに書き記そうと思う。

# Google Analytics（グーグルアナリティクス）とは？
>Google Analytics（グーグルアナリティクス）は、Googleが無料で提供するWebページのアクセス解析サービス。 元々はGoogleが2005年に買収した、米国のWeb解析ソリューションプロバイダー・Urchin社の技術を利用している。（Wikipediaより引用）

とのことです。
サイトにどれくらい人が来ているかや、どのページがよく見られているかなど、サイトの現状を把握することができるツールです。
解析ツール自体は、他にもあるのですが、無償で高性能なGA（Googl Analytics）を使用します。

# 事前準備
・Googleのアカウント（Gmailとかのアカウント）
・アクセス解析したいサイト（URL）

# アカウントの開設
### 【ステップ1】 https://analytics.google.com/analytics/web/ にアクセスします
下記のページが開きます。
![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19460/dd9517c6-41f5-02d4-5c52-0e5fd440681f.png)
※GAを開始したいアカウントになっているか確認（右上のアイコンで確認可能）
### 【ステップ2】 「測定を開始」をクリック
設定は3つで終了です。（5分程度で完了します）
アカウントの設定→計測対象の設定→プロパティの設定

### 【ステップ3】 アカウントの設定
アカウント名：自分が管理しやすい命名にする
（例：自社サイト、制作サイト、サービス名などなど）

アカウントのデータ共有設定
データ共有オプションで、アナリティクスで収集したデータを共有するか設定できます。
（基本的にそのままの推奨設定のままでOK）
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19460/3fb1242b-268e-6e07-93d4-719cde392d10.png)

### 【ステップ4】 アカウントの設定の入力が終わったら「次へ」をクリックします。

### 【ステップ5】 計測対象を指定します。
自身が計測したいサイトがWebかAppか両方か、選択が可能です。
今回はWebで進めます。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19460/8e8f240e-6374-cb01-3e92-7e49be9add55.png)

### 【ステップ6】 対象の媒体を選択して「次へ」をクリック

### 【ステップ7】 プロパティの設定（計測するWebサイトの情報を入力します。）
ウェブサイトの名前：サイトのタイトルタグなど認識しやすい名前を付けます
ウェブサイトのURL：管理するサイトのURLを入力します。
（基本的にはサイトのドメインでしています）

業種：任意で入力してください
レポートのタイムゾーン：日本に設定します。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19460/cf9c8ce0-8f77-1f31-41fa-a5ccbf7d6b83.png)

### 【ステップ8】 「作成」をクリック

### 【ステップ9】 利用規約が出るので確認の上、問題なければ同意します。
お住いの地域を選択。
2箇所の規約を読み、問題なければ各同意のチェックボックスにチェックを入れます。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19460/41467f27-0139-32ca-cf82-c752e338a692.png)

### 【ステップ10】 ステップ9まで進んで問題なければ「同意」をクリック

以上でアナリティクスのアカウントの開設が完了です。
設置に関する情報は下記紹介します。
[Webサイトのアクセス解析の第一歩【Googleアナリティクスの設置】](https://qiita.com/Sakurai1111/items/2f6e7ebafd1b05fcfe73)

以上
Pythonのクラス変数をインスタンス変数だと思ってて死んだ

インスタンスを何度作り直しても `__init__()` で作ってるつもりの変数が変わらず、何ヶ月もハマってた

## 結論

python書き始めてからずーーっと勘違いしてました

```py
class H:
  val = 1        <-------これは
  
  def __init__(self):
    self.val = 1        <-------これと同じものだと思ってました
```

本当はこうだった


```py
class H:
  val = 1        <-------クラス変数
  
  def __init__(self):
    self.val = 1        <-------インスタンス変数
```



## test code

```python
import datetime, time

# クラス変数
class A:
    t = datetime.datetime.today()          #<-----------------# クラス変数： 何度インスタンスを作っても変わらない！！

class B:
    def __new__(cls):                      # <----------------# __new__ インスタンス変数
        self = object.__new__(cls)
        # print('__new__ :', str(id(self)))
        self.t = datetime.datetime.today()
        return self

class C:
    def __init__(self):                 # <----------------# __init__ インスタンス変数
        self.t = datetime.datetime.today()

class D:
    def __call__(self):                 # <----------------# __call__ インスタンス変数は class名() で呼ばれる。instance.__call__() を省力する感じ。
        return datetime.datetime.today()

def start():
    print("-start")
    print(datetime.datetime.today())

    print("-A")
    instance = A()
    print(A.t)           # class変数のみインスタンスではなく、クラス直で呼び出せる
    print(instance.t)    # インスタンスから取得        <----------- 違うインスタンスでも共通の値（一番最初にclassが呼ばれたときの数字で固定

    print("-B")
    instance = B()
    print(instance.t)

    print("-C")
    instance = C()
    print(instance.t)

    print("-D")
    instance = D()
    print(instance())    # <---------------- __call__ はclass名() で呼ばれる。instance.__call__() を省力する感じ。

##############################################################
if __name__ == "__main__":

    start()
    print("=========================================")
    time.sleep(1)
    start()
```

## result

インスタンスを作り直しているのに、

```ruby
-start
2020-01-30 14:29:24.227419
-A
2020-01-30 14:29:24.227217             <-----------ここと
2020-01-30 14:29:24.227217
-B
2020-01-30 14:29:24.227470
-C
2020-01-30 14:29:24.227494
-D
2020-01-30 14:29:24.227516
=========================================
-start
2020-01-30 14:29:25.230648
-A
2020-01-30 14:29:24.227217           <-----------ここが同じ orz
2020-01-30 14:29:24.227217
-B
2020-01-30 14:29:25.230766
-C
2020-01-30 14:29:25.230833
-D
2020-01-30 14:29:25.230877
```

他のは違う。class変数ってそういうやつやったんや・・・



## 全力で踏み抜くスタイル
> **クラス変数の使用上の注意**
クラス変数にアクセスする場合は、特別な理由がない限り「インスタンス.クラス変数」や「self.クラス変数」のようにアクセスすることは避けるべきです。Python ではインスタンス変数をインスタンスオブジェクトから生成することができ、意図せずクラス変数をインスタンス変数で隠蔽してしまうことがあります。
https://uxmilk.jp/41600

色んな所で思いっきりやっております。ほえ〜。まいったまいった・・・。

# まとめ

雰囲気でpythonするのはやめよう
で、結局UTC、GMT、Unixtimeって何が違ってどう書けばいいの？？？

## 事の発端
お仕事で時刻の変換の処理を書いたのですが、今までなんとなく「new Date()」の関数でやり過ごしてきてしまっていました。今回は「サマータイムの処理も頑張って書いてね。」と言われて色々調べたのでその結果を備忘として残したいと思います。
（かなり基礎的な情報なので、初心者向けです。）

#時間表現の違い
（UT、）UTC、GMT、Unixtimeとは何かについて書いていきます。

##UT(Universal time)
天文観測に基づきイギリスのグリニッジを通る本初子午線に対する平均太陽時角に12時を加えたもので表される世界共通の時間。
あまり実務で意識することはないかもしれません。

##GMT(Greenwich mean time)
英国のグリニッジ（経度0度）の地方平均時（平均太陽が南中する時を正午とする）のことで、一般的な意味合いではUTと同義語。
こちらはnew Date()をするタイミングで見たことがあるかもしれませんね。

##UTC(Coordinated universal time)
まず、UTCを理解する前段階として、原子時計と国際原子時の説明をします。
##### 原子時計
  セシウム原子の振動数を基準にした時系で、1年に百万分の1秒ほども狂わない高精度な時計です。
##### 国際原子時
  基準時計として最も安定した原子時計が採用され、1958年1月1日0時0分0秒の世界時を原点としてスタートしたのがです。
ところが、地球の自転速度にふらつきがあるので、この原子時計を基準にすると秒の単位が常に変動してしまい、様々な問題が発生することがわかりました。
##### 協定世界時：Coordinated universal time
ここで登場するのがUTC（協定世界時：Coordinated universal time）です。
世界協定時とは、国際原子時と世界時の誤差が0.9秒以上ならないようにうるう秒で調整をした時間で、原子時の精度を保ちながら、太陽の運行と時間の表示がさほど狂わないように調整したものらしいです。

##Unixtime
各々のPC端末内に持っている時間で、協定世界時 (UTC) での1970年1月1日午前0時0分0秒から形式的な経過秒数（すなわち、実質的な経過秒数から、その間に挿入された閏秒を引き、削除された閏秒を加えたもの）
PCは時々サーバに時刻（UTC時刻）を取得しに行ってこのUnixtimeを調整することで、時間がずれないようにしているらしいです。
Unixtimeは経過時刻なので、現在は10桁の数字で表されています。
例えば、日本時間での13:58:06秒は　1580360290 のような形で表されます。

>参考
>[CITIZEN公式サイト](https://citizen.jp/support/useful/gmt_utc.html)
>[Wiki](https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93)

#実装の話
では具体的にJSではどう書けばどんな時間が取れるの？というところを書いていきます。
#####実行環境
- Chromeのコンソール
- タイムゾーン：Tokyo

### new Date()
```
new Date()
Thu Jan 30 2020 14:01:47 GMT+0900 (日本標準時)
```
new Date()をした時は使っている端末のタイムゾーンでの現在時刻が取得できます。

### new Date().toISOString()
```
new Date().toISOString()
2020-01-30T05:28:18.076Z
```
使っている端末のタイムゾーンでの時刻(東京の時刻)を世界標準時に直した時刻が取得できます。

### new Date().getTimezoneOffset()
```
new Date().getTimezoneOffset()
-540
```
取得したDateと世界標準時の誤差を取得できます。
東京は9時間進んでいるので、-(9 * 60)分の誤差が返って来ていますね。

### Date.now()
```
Date.now()
1580360742505
```
Date.now()をした時は使っている端末のタイムゾーンでの1970年1月1日午前0時0分0秒からの経過秒数を取得できます。

だいたいこんなところでしょうか？

#サマータイムはどうする？
私の仕事上の課題は、自システムにサマータイムを導入するためにどうするか、ではなく、欧米圏はサマータイムやっているけどその時Dateモジュールの動きが変わるのでは？？？という懸念から生まれたものでした。
結論として、UTCもUnixtimeも基準となる地点からの経過時刻なので、それがサマータイムという制度によって変わるわけではないから、特別なロジックは必要ないね。と落ち着きました。

自サービスがサマータイムの制度上で動く場合は時間がズレる月にズラすロジックが必要になるのだと思います。

#まとめ

- UTC
   原子時の精度を保ちつつ、地球の自転とのズレを吸収して運用されている世界共通時刻
- GMT
   英国のグリニッジ（経度0度）の地方平均時（平均太陽が南中する時を正午とする）
- Unixtime
　　各々のPCに持っている時間で、UTCを基準としてタイムゾーンを反映した時間


読んでくださってありがとうございました。
認識違いなどありましたら教えてくださると嬉しいです！
TypeScriptで配列の要素を再特定する（`xs is Array<Foo>` by `.every()`）

- 今週の標語: optional property 以外への`as`は unsafe

## 解決策: 関数でラップしてあげる

解決策

```typescript
function hasTypedElements<PropType>(
  xs: Array<unknown>,
  isTypedElement: (x: unknown) => x is PropType
): xs is Array<PropType> {
  return xs.every(isTypedElement)
}
```

確認

```typescript
/**
 * Checking for primitives
 */

// TypeScriptが `(x: unknown) => typeof x === 'string'` を `x is string` だと理解してくれないので、関数化する
function isString(x: unknown): x is string {
  return typeof x === 'string'
}

const xs: Array<unknown> = ['string']
if (!hasTypedElements(xs, isString)) {
  throw new Error('good bye')
}
const recovered0: Array<string> = xs
console.log(recovered0) // [ 'string' ]

try {
  const ys: Array<unknown> = [10]
  if (!hasTypedElements(ys, isString)) {
    throw new Error('good bye')
  }
  const recovered1: Array<string> = ys
  console.log(recovered1)
} catch (e) {
  console.log(e) // Error: good bye
}

/**
 * Checking for objects
 */

interface Foo {
  x: string
}

function isFoo(x: unknown): x is Foo {
  return typeof (x as { x?: string }).x === 'string'
}

const zs: Array<unknown> = [{ x: 'string' }]
if (!hasTypedElements(zs, isFoo)) {
  throw new Error('good bye')
}
const recovered2: Array<Foo> = zs
console.log(recovered2) //  { x: 'string' } ]
```

## そもそも期待していたこと

コード

```typescript
interface Foo {
  x: string
}

function isFoo(x: unknown): x is Foo {
  return typeof (x as { x?: string }).x === 'string'
}

const xs: Array<unknown> = [{ x: 'string' }]
if (!xs.every(isFoo)) {
  throw new Error('good bye')
}
const ys: Array<Foo> = xs
```

- 期待していたこと: コンパイルが通る
- 実際: `2322: Type 'unknown[]' is not assignable to type 'Foo[]'. Type 'unknown' is not assignable to type 'Foo'.`

`.every`！　お前型ガードしてくれよ！！

## 解決策

関数化により、`.every`をラップしてあげることにします。

```typescript
function hasTypedElements<PropType>(
  xs: Array<unknown>,
  isTypedElement: (x: unknown) => x is PropType
): xs is Array<PropType> {
  return xs.every(isTypedElement)
}
```

---

TypeScript が型をつけてくれる？
否。
私達が "TypeScript に" 型をつけて回るのだ。

許せん。
FizzBuzzプログラムを作成してみよう。

#FizzBuzz問題
- 3で割り切れる数値を引数に渡すと、Fizzと返す。
- 5で割り切れる数値を引数に渡すと、Buzzと返す。
- １５で割り切れる数値を引数に渡すと、FizzBuzzと返す。
- それ以外の数値は文字列に変えて返す。

###FizzBuzzのプログラムを段階的に考えていく。
- まず整数を文字で出力する。
- to_sメソッドを使い数字を文字にする。


```ruby:qiita.rb
def fizzbuzz(i)
    i.to_s
end
puts fizzbuzz(1)
#数値が出力される
```
- 次に３で割れる数値の時にfizzと出力するようにする。
- 割り算は%を使う。
- 値が等しい時は==を使う。(=は値を入れることなので注意)
- 条件分岐if文を使う。
- [変数や条件分岐について書いた記事も参考までに](https://qiita.com/Chihiro_0701/items/0b4c58767feff8093c62)


```ruby:qiita.rb
def fizzbuzz(i)
    if i % 3 == 0
        "fizz"
    else
        i.to_s
    end
end
puts fizzbuzz(1)
puts fizzbuzz(3)
#1とfizzが出力される
```

- 次に５で割れる数値の時にbuzzと出力されるようにする。


```ruby:qiita.rb
def fizzbuzz(i)
    if i % 3 == 0
        "fizz"
    elsif i % 5 == 0
        "buzz"    
    else
        i.to_s
    end
end
puts fizzbuzz(1)
puts fizzbuzz(3)
puts fizzbuzz(5)
#1とfizzとbuzzが出力される
```
- 最後に１５で割れる時はfizzbuzzと出力されるようにする。
- 書くときに注意としては、今の流れでif文の下に１５の条件を書くと、最初の３の条件で出力される（15も３で割り切れる）ため、15の条件を３より前に書く。

```ruby:qiita.rb
def fizzbuzz(i)
    if i % 15 == 0
        "fizzbuzz"
    elsif i % 3 == 0
        "fizz"
    elsif i % 5 == 0
        "buzz"    
    else
        i.to_s
    end
end
puts fizzbuzz(1)
puts fizzbuzz(3)
puts fizzbuzz(5)
puts fizzbuzz(15)
#1とfizzとbuzzとfizzbuzzが出力される
```

以上になります。
「プロを目指す人のためのRuby入門」にて最初に学んだ事を書かせていただきました。
プロパティグループのインデックスの構造がよくわからん。[AfterEffects][Expression]

#プロパティ構造がAEで一番わかりにくい！！

プロパティのオブジェクトを取得するには

```jsx
thisProperty.propertyGroup(3).propertyIndex
```
ってな具合でpropertyGroup(インデックス指定)してオブジェクトを取得するんだけど、このインデックスに隠れてるものがあったりしてよくわからん！！！
とりあえずデバック用でわかるようにしてみた。

```jsx
t = thisComp.layer("ball").content("Character").content("Obj").content("楕円形パス 1").position;
var txt = "";
count = 1;
try{
	while(count <= 10){
		txt += count+":"+t.propertyGroup(count).name+"\r"
		count++
		txt
	}
}catch(e){
	txt
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/ebc3ee2d-0c88-71d9-9c2b-c8f66de7cb8a.png)

見てもらったら分かる通りコンテンツってものが増えてるせいでインデックスが分けわからなくなる。
多分グループを作成すると、コンテンツという目に見えない物が発生していると思われる。
確かリファレンスにもこんな説明なかったよな～。。。。。
指定した深さまで再帰的にディレクトリやファイルを検索するgrepコマンドの使い方

# 前置き
 
日頃からUnix系OSに親しんでいる人ならば既知だと思うがご存知でない人もいると思われるので投稿する。
Linux、WSL、macのCLI初心者でファイル検索に困っている人の役に立てば幸いである。

# 本題

ディレクトリ5階層分までの範囲でファイル名`hogehoge`を検索したい場合は以下の通り。

```bash
$ find . -maxdepth 5 | grep hogehoge
```

`-maxdepth`の後に検索したい範囲のディレクトリの深さを指定すればよい。
`-maxdepth`の説明をman日本語版より抜粋。

>-maxdepth levels
コマンドライン引き数として指定したパスから最大 levels 段階下の ディレクトリまで探索する (levels は非負の整数)。 -maxdepth 0 は、判別式やアクションの対象にするのは、 コマンドライン引き数だけであることを意味する。

さらにファイル名が大文字か小文字があいまいな場合は`grep`コマンドに`-i`オプションを付ければよい。
例を示すと以下の通りになる。

```bash
$ find . -maxdepth 5 | grep -i hogehoge
```
PackerでCompute Engineのイメージを焼くときはOSログインを無効化する

# これはなんですか

- PackerでCompute Engineのイメージを焼いてる時にOSログインで詰まったので備忘としてメモしておきます。
- コンテナ全盛の時代にイメージ焼いてます。

# Packer と OSログイン

PackerとGCEのOSログイン設定について軽く説明する。

## Packer

各種イメージを焼いてくれるすごいやつ。GCP向けには、Compute Engine向けのイメージを作成するためのBuilderが用意されている。

https://www.packer.io/docs/builders/googlecompute.html

具体的な動作は次の通り:

1. イメージ作成用のインスタンスを所定のネットワーク上に作成する
2. インスタンスに接続し、イメージを焼くための各種操作を行う
3. イメージを作成する
4. インスタンスを削除する

JSONファイルで設定を記述し、`packer build` コマンドを実行すると、上記の順でイメージが作成される。設定は主に「何のイメージを作るか」を定義する Builder と「どのようにイメージ用インスタンスを構成するか」を定義する複数の Provisioner からなる。


## OSログイン

VMインスタンスへのSSH接続、特権昇格をCloud IAMで制御するための機能。GCP的にはGCEを使う際の推奨設定らしい。設定方法はメタデータに `enable-oslogin: TRUE` を設定するだけ。

https://cloud.google.com/compute/docs/oslogin?hl=ja


## PackerはOSログインに対応していない

以下のIssue参照。
https://github.com/hashicorp/packer/issues/7663


# 回避方法

イメージ作成用のインスタンスのメタデータに `enable-oslogin: FALSE` を設定する。GCEのメタデータはプロジェクト単位、インスタンス単位で設定でき、同じキーについてはインスタンスの設定が優先される。そのため、Packer の Compute Engine Builder にメタデータを設定することで、プロジェクト単位でOSログインが設定されている状況でもイメージが作成できるようになる。

```image.json
{
    "builders": [
        {
            "type": "googlecompute",
            "account_file": "{{user `account_file_path`}}",
            "project_id": "{{user `project_id`}}",
            "source_image_family": "{{user `source_image_family`}}",
            "ssh_username": "packer",
            "zone": "asia-northeast1-a",
            "image_family": "{{user `image_family`}}",
            "image_name": "{{user `image_family`}}-{{timestamp}}",
            "metadata": {
                "enable-oslogin": "FALSE"
            }
        }
    ],
    "provisioners": [
        ...
    ]
}
```

重要なのは以下の `metadata` 設定。

```
            "metadata": {
                "enable-oslogin": "FALSE"
            }
```

このブロックの中に、インスタンスのカスタムメタデータを記述する。

# まとめ

- OSログインが有効な環境ではPackerが使えない。
- インスタンス単位でOSログインを無効化することで回避した。
- しばらくはおまじない感覚で入れておくのが良さそう
    - そもそもPacker使う人がどれくらいいるか問題はあるが。。。
Numpy > Masked array > マスクされた箇所に別のarrayの要素を入れる

## 概要

- マスクされた要素(`--`)を持つarrayがある
- マスクされた要素に別のarrayの要素を上書きする

## 実装

### 実装 

一次元にしてから処理をしている。
直接的な処理にはなっていないが、希望の動作にはなった、という程度の実装。


https://ideone.com/oxDinW

```py 
import numpy as np
import numpy.ma as ma

# checked with PEP8

MASKED_VALUE = -32768
SIZE_X = 3
SIZE_Y = 3

# 1. data preparation
ncep = np.array([[3, 1, 4], [1, 5, 9], [2, 6, 5]])
oisst_unmask = np.array([[2, 7, 1], [8, 2, 8], [1, 8, 2]])
masks = np.array([[1, 0, 1], [1, 0, 1], [1, 0, 1]])
oisst_masked = ma.masked_where(masks, oisst_unmask)
ma.set_fill_value(oisst_masked, MASKED_VALUE)
print(ncep)
print(oisst_unmask)
print(oisst_masked)

# masked.mask = ma.nomask  # unmask > values before masking
print(oisst_masked.mask)

# 2. unmasking by overwriting with ncep data
# flatten_mask = ma.MaskedArray.flatten(oisst_masked)
flatten_mask = oisst_masked.mask.flatten()
flatten_oisst = oisst_masked.flatten()
flatten_ncep = ncep.flatten()
print(flatten_mask)
for idx, elem in enumerate(flatten_oisst):
    if flatten_mask[idx]:
        flatten_oisst[idx] = flatten_ncep[idx]

print(flatten_oisst)
array_oisst = flatten_oisst.reshape([SIZE_X, SIZE_Y])
print(array_oisst)

```

### 結果

```
[[3 1 4]
 [1 5 9]
 [2 6 5]]
[[2 7 1]
 [8 2 8]
 [1 8 2]]
[[-- 7 --]
 [-- 2 --]
 [-- 8 --]]
[[ True False  True]
 [ True False  True]
 [ True False  True]]
[ True False  True  True False  True  True False  True]
[3 7 4 1 2 9 2 8 5]
[[3 7 4]
 [1 2 9]
 [2 8 5]]
```

### 関連

- [SciPy.org > Masked array operations](https://docs.scipy.org/doc/numpy/reference/routines.ma.html)
- [numpy.ma.MaskedArray.flatten](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.MaskedArray.flatten.html#numpy.ma.MaskedArray.flatten)
- [Unmasking of masked Numpy array changes masked values to 0's](https://stackoverflow.com/questions/18845254/unmasking-of-masked-numpy-array-changes-masked-values-to-0s)
- [Scipy.org > The numpy.ma module](https://docs.scipy.org/doc/numpy/reference/maskedarray.generic.html)
Netlify CMS で Deploy Preview にBasic認証が掛けられない

# 要約
- [Netlify](https://www.netlify.com/) + [GatsbyJS](https://www.gatsbyjs.org/) + [Netlify CMS](https://www.netlifycms.org/)の環境で [Deploy Preview](https://www.netlify.com/blog/2016/07/20/introducing-deploy-previews-in-netlify/) に [Selective Password Protection](https://www.netlify.com/blog/2017/04/07/selective-password-protection/) の機能を使ってBasic認証を掛けたら、Netlify CMSの管理画面にアクセス出来なくなってしまった
- Netlify CMSに関わるディレクトリを除いてBasic認証を試したが、GatsbyJSを使っている関係上SPAのため、どこか1ページでもアクセスできると全てのページが見られる脆弱性があった
- Netlify のサポートに問い合わせた結果、Basic認証は永続的な認証を意図したものではなく、サイト全体に認証を掛けたいのであれば[Site-wide protection](https://docs.netlify.com/visitor-access/password-protection/#site-wide-protection)を掛けた方がいいという回答だった
- Site-wide protectionを掛けると公開されているページを含むサイト全部にパスワードが掛かってしまうため、**GatsbyJS + Netlify CMSとBasic認証の併用は不可能**という結論になった

# 問題
- GatsbyJS でサイトを構築
- ホスティングに Netlify を使用
- Netlify CMS で更新を簡便化している

という環境での話です。

Netlify には GitHub でPRを作成した時、自動でプレビュー環境を作ってそのリンクを生成してくれる[Deploy Preview](https://www.netlify.com/blog/2016/07/20/introducing-deploy-previews-in-netlify/)という機能があります。

しかし、プレビュー環境はURLさえ分かれば誰でもリンクできてしまうので機密性に乏しく、そのため同じく Netlify の機能にある [Selective Password Protection](https://www.netlify.com/blog/2017/04/07/selective-password-protection/) を使ってプレビュー環境にBasic認証を掛けようとしました (Basic認証はProプラン以上で使用可能)。

プレビュー環境に認証を掛けること自体は上手くいきましたが、認証が掛かっている状態で Netlify CMS の管理画面にアクセスしようとすると**Basic認証ダイアログが出て管理画面に永遠に入れないバグ**に遭遇しました。

# 試したこと
Netlify CMS に関するディレクトリ以外にBasic認証を掛けようとしましたが、GatsbyJS を使っている関係上SPAなので、**どれか1ページでもアクセスできると全てのページにアクセスできてしまう脆弱性**がありました (存在しているページにはBasic認証が掛かるが、404のページには掛からず、結果として存在しないページにアクセスすると全て見れてしまう)。

サポートに問い合わせたところ、
> Hello,
The basic-auth header isn't really meant to be permanent authentication solution. You could try setting a > > password for your site here: https://app.netlify.com/sites/[サイトURL]/settings/access#password-jwt-secret and see if that works for you. You'll also want to remove the basic-auth header.

という回答。

つまり、`Basic認証は永続的な認証を意図されたものではなく、サイト全体に認証を掛けたいのであればSite-wide protectionを掛けた方がいい`とのことでした。

[Site-wide protection](https://docs.netlify.com/visitor-access/password-protection/#site-wide-protection) を掛けると公開されているページ全てにパスワードが掛かってしまうため、**GatsbyJS + Netlify CMS とBasic認証の併用は不可能**という結論になりました。

Netlify CMS を使っていてBasic認証を試そうと思っている方はお気をつけください。
Cloud RunかわいいよCloud Run

Google Cloud PlatformのサービスであるCloud Run。
超ざっくり一言でいうと「簡単にコンテナアプリを動かせる環境」です。
コンテナアプリは作って、さあ次Kubernetesとか、Knativeとか、
気になってるけど環境を用意するのが大変そう、、、という方の足がかりにオススメです。
そんなCloud Runのかわいいポイントを紹介します。
※本投稿ではフルマネージドのCloud Runについてのみ言及します。

## Cloud Runとは

もうちょい正確に言うと、
「GCPが管理しているどこかのKubernetesクラスタ上で動いているKnative環境」です。
Knativeとは、とかをお話すると長くなるので、
「なんかKnativeっていうコンテナを扱うプラットフォームがあって、それをGCPが用意してくれてる」
っていう感じです。

## かわいいポイント1: 簡単

用意するのはコンテナのイメージだけ。
デフォルトではTCP 8080で待ち受けるWebアプリを想定しているので
そんな感じのアプリをコンテナ化(&イメージ作成)しておけば
あとはそれを指定するだけで動いちゃいます。
<img width="556" alt="スクリーンショット 2020-01-30 13.41.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89002/c2ea089e-7111-4ad2-394e-bebb77e69bda.png">

↑設定項目は、コンテナイメージ、プラットフォーム(フルマネージドか否か)、サービス名、認証(外部公開するか否か)だけ

## かわいいポイント2: 便利

Cloud Run(というかKnative)の便利な機能として、
カスタムドメインのSSL化があります。
独自ドメインが使えるのは当たり前、なんと自動でLet's Encryptの
SSL証明書をあててくれます。
更新も不要！らくちん！

## かわいいポイント3: まだちょっと不器用

Knativeの機能として細かいルーティング制御がありますが
こちらはまだCloud Runでは使えません。
使えるようになれば、Canaryリリースができるようになるなど
ルーティングの幅が広がります。
こちらは今後の動きに注目です。

## まとめ

Cloud RunをきっかけにKnativeやIstio、
Kubernetesの世界に踏み込むこともできると思いますので
コンテナアプリに興味がある方はぜひ触ってみてください。
Cloud RunかわいいよCloud Run。
質問力をつけてエンジニアとしての格を上げろ！！！

# はじめに

エラーや問題に直面し自力で解決ない場合、メールや掲示板サイトで人に聞く際の良質な質問のポイント

# 対象

質問から解決までに以下のような問題を抱えている人

- 漠然と質問の仕方がわからない
- 質問してもなかなか返信がない
- 解答が的外れ
- 解答を得られるまでに何回もやりとりが発生する

# 得られること

#### ・　できるエンジニアと思われる ← <font color="Red">以外にこれ重要！　コーディング能力がある人 < 質問力がある人</font>
#### ・　論理的思考能力が身に付く
#### ・　言語化能力が身に付く
#### ・　問題解決能力が身に付く

# 良質な質問とは

ここでは<font color="Red">少ないやり取り（できれば一発）で目的の解答を得られる質問</font>と定義

# 質問したときやりがちなNGなこと

#### 「××というエラーが発生しました、どうしたらいいですか？」

(･＿･).｡oO（何をしたら発生したの？）
(･＿･).｡oO（どういう実装をしたの？）

#### 「〇〇ができません。全ソースコードペタ〜」

(･＿･).｡oO（範囲が広い。。。どこを見たらいいの？）

#### 解答をすると「それはもうやりました」

(･＿･).｡oO（はじめに言っておいて。。。）

#### 「自己解決しました」

(･＿･).｡oO（結局何が原因だったの？）

#### わからなかったら直ぐ質問して、と言われたのでとりあえず質問する

(･＿･).｡oO（直ぐ質問して=自分で考えずに直ぐ、という意味じゃないよ）

# 本題：質問の仕方

質問する前に内容を整理しましょう。
これを繰り返すことで次の能力が向上します。
- 論理的思考能力
- 言語化能力
- 問題解決能力向上

さらに、整理することで問題点や解決方法が見つかる可能性もあります。

次章から具体的なポイントを説明します。

## 前提

- <font color="Red">出来るだけ多くの情報を</font>
- <font color="Red">わかりやすく</font>
- <font color="Red">詳細に</font>


## 1. 実現したいこと、解決したいエラーは何か

簡潔に。

例

- 〇〇という機能を実装したい。
- ××したい。

## 2. 問題の詳細

エラー画面のキャプチャやログを記載すること
<font color="Red">**出し惜しみしないこと**</font>

ダメな例

- エラーの文字列だけを記載

良い例

- コマンド実行からのログ
- 操作を開始してからのログ
- Web系であれば、ブラウザ内だけでなくURLも含めたキャプチャ等

## 3. 発生手順

エラーが発生した直前の手順だけというように<font color="Red">**手を抜かないこと**</font>
一連の操作の流れを記載すること

例

1. Aの画面でBのボタンをクリック
　=> B'の画面が表示sれる

2. 〇〇の情報を記入
3. Cのボタンをクリック
　=> ××のエラーが発生

## 4. 対象のソースコードの提示

- 正常動作していた時からエラーが発生した時点までに編集したソースコード
- キャプチャであれば行番号を含める
- ソースコードを貼り付ける際はMarkdown記法[^1]を使用

\[^1]: [Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)


## 5. 問題に対して自分が試したこと

- 実施した内容とその結果（どうダメだったか）
- 参考サイトのURL

## 6. 環境

- システム構成
- OS
- ソフトウェアのバージョン

## ※ 自己解決した場合

情報を共有しましょう。
今後類似した問題に直面したときや、別の人が同じ問題に直面したときに役立ちます。

# 最後に

質問の仕方が上手な人は周りの評価が上がります。
逆に、プログラミング能力に長けていても、質問の仕方が下手だと「できないやつ」と思われてしまいます。
Gulpの基本的な文法



#はじめに 
前回はGulpの環境を整えたので、今回は基本的な文法を学んでいきます。
開発環境：Mac(ターミナルを使用)

##基本的な文法

###1.gulpfile.jsのファイルを作成
  

###2.ファイルをコピーするための記述 
```javascript:gulpfile.js
const{src, dest} = require('gulp');

function copyFiles(){
      return src('./src/index.html')
      .pipe(dest('./dest'));
}

exports.copyFiles = copyFiles;

```

####作業
1.Gulpは何らかのファイルに対して何らかの処理を行うという流れなので、操作対象となるファイルの指定と、操作した後の出力先を決定する。

src→操作対象を指定、dest→作業が完了した時のフォルダ

```javascript:gulpfile.js
const{src, dest} = require('gulp');
```




2.srcフォルダを作りその中にindex.htmlファイルを作る

3.処理をした後のファイルを格納するためdistフォルダを作る

4.相対パスで場所を指定し、格納される状態にする
　pipeでどんどん処理を繋げていく。


```javascript:gulpfile.js
return src('./src/index.html')
.pipe(dest('./dest'));
}
```

5.ターミナルで実行する関数copyFilesを追加

```javascript:gulpfile.js
exports.copyFiles = copyFiles;
```
6.プロジェクトフォルダに移動
　＊gulpfile.jsのデレクトリ内でターミナルを実行する必要がある。

7.ターミナルで実行しdistフォルダの中にindex.htmlを格納させる

```terminal:Terminal
gulp copyFiles
```



＊複数ファイルの場合
配列で指定

```javascript:gulpfile.js
return src(['./src/index.html','./src/sub.html'],)
```

たくさんある場合は、ワイルドカードで指定するとsrcフォルダで格納された全てのファイルがコピーされる

```javascript:gulpfile.js
return src('./src/*')

```
＊HTMLだけ指定したい場合

```javascript:gulpfile.js
return src('./src/*.html')
```

＊フォルダと中身もコピーしたい場合

```javascript:gulpfile.js
return src('./src/**')
```
同様に、HTMLのみコピーした場合は＊＊.htmlを指定


##Gulpにタスクを追加

1.ファイルの名前を変えるためのプラグインをインストール

```terminal:Terminal
yarn add gulp-rename --dev
```
すると、package.jsonに追加されているのがわかります。
<img width="439" alt="スクリーンショット 2020-01-30 21.31.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451241/417e95a7-33c1-4a5f-b580-687166b84a12.png">
2.requireでインストールして指定したファイルに入れる
オプションを付けたい場合はprefixに付与したい文字列をいれるとファイル名の先頭に文字列が付きます。

```javascript:gulpfile.js
const{src, dest} = require('gulp');
const rename = require('gulp-rename');

function copyFiles(){
      return src('./src/index.html')
      .pipe(rename('./dest'){
        prefix: 'hello-'
　　　}))
 　　　.pipe(dest('./dest'));
}

exports.copyFiles = copyFiles;
```
以上が、Gulp開発の流れになります。

 
##最後に
基本的な文法とGulp開発の流れを学べました。
次は、いろいろなプラグインを使って処理を行なってみたいと思います。
herokuでRailsAdminが原因でデプロイできないとき

##どのようなエラーか?
```
#省略
NameError: uninitialized constant RailsAdmin
#省略
```

##1.gemfileを開く

```
#省略
group :development, :test do

 gem 'rails_admin'

#省略


```
対策:開発、テストグループに入っているためその枠外から外してあげる。
その後、bundle installしてあげる。

これで、herokuに再度デプロイすればエラーはでなくなります。
TD workflowのHIVEをversion2で動かすとき

# はじめに
Treasuredataでhive2が使えるようになりました。がWorkflowで指定するのはどうすればいいのかと思ったのでやってみたら通ったからメモ。

```sample.dig
+owned:
  td>: queries/03_owned_visit.sql
  database: ${td.database}
  engine: hive
  engine_version: experimental
  insert_into: four_segments_webidhas
```
enjine_version: experimental で指定するようです。
## 参考
1. APIでのやり方  
https://support.treasuredata.com/hc/en-us/articles/360027259074-How-to-use-Hive-2
herokuにデプロイできない時の対処法

#herokuにデプロイできなくなったら??
 ##1. 以下のコマンドを入力

```
$ heroku run rails db:migrate

$ heroku restart
```
Ps. デプロイできなくなるほとんどの原因は、heroku上でのマイグレーション忘れだと思うのでぜひ試してみてください。
SphereColliderのGizmoを自力で描画する

SphereColliderのCenter、Radusは、アタッチしたTransformや親Transformの影響を受け、RadiusはScaleのx、y、zの中の最大値がｚを受けるようです。

これをGizmoで描画する場合、以下のようなコードになります。

```C#

[SerializeField] private SphereCollider _sphereCollider;

private void OnDrawGizmos()
{
    Gizmos.color = Color.yellow;

    var scale = Mathf.Max(transform.lossyScale.x, transform.lossyScale.y, transform.lossyScale.z);

    var center = transform.TransformPoint(_sphereCollider.center);
    var radius = _sphereCollider.radius * scale;

    Gizmos.DrawWireSphere(center, radius);
}
```

![collider_gizmo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/1306e554-8e76-bb6f-61fb-d9d63c814b5a.gif)

緑の線が、UnityEditorが描画したコライダーで、黄色の線が、自分で描画したコライダーです。一致していますね！
[Maya]複数立ち上げたUIを識別しやすく色付け

Mayaを複数立ち上げた時、非アクティブな方のウインドウを触って切り替わってあーもうってなりませんか私はなります。

こちらを参考にランダムでメニューバーに色を付けるスクリプトを書きました。
http://myara.blog.fc2.com/blog-entry-218.html
Pyside2なので2017以降向けです。
Maya立ち上げてる間だけ有効です。

![mWindow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428123/b75915b2-36a0-2f61-1a3d-0febb3545496.png)


```python
# -*- coding: utf-8 -*-
from PySide2.QtWidgets import *
import random

def changeUIColor():
    collist = [(165, 0, 33),(11, 120, 0),(38, 104, 255),(255, 135, 75),(225, 120, 200)]
    app = QApplication.instance()
    num = random.randint(0, 4)
    col = str(collist[num])
    app.setStyleSheet("QMenuBar {background: rgb" + col + "; color: white;}")
changeUIColor()
```

色を変えたり追加したい時はcollistの中をいじってください。
追加したらnum = random.randint(0, 4)の引数を変更してください。

メニューバーない自作ウインドウがある場合はここを参考にセレクタを追加してください。
https://doc.qt.io/qtforpython/overviews/stylesheet-examples.html?highlight=stylesheet
自分はQTabBar追加しました。
Python学習ノート_問題の解決_001

#pipが実行時にエラーについて

- pipで直接使えない場合があります。（外部サイトへのアクセス制限あり）  
下記のようにパッケージをインストール時にはエラーになる解決方法はproxyサーバー経由でアクセスする

```エラー内容_01.txt
 'Connection to pypi.org timed out. (connect timeout=15)'
```

```pipコマンド_01.txt
修正前：
pip install <PACKAGE_NAME>
修正後：
pip install <PACKAGE_NAME> --proxy http://<PROXY_URL>:<PORT_NO>
```

- 上記の方法でも解決できない時もあります。  
下記のようなｓｓｈ認証のエラーが発生したら、pipのパラメーターに「--trusted-host pypi.org --trusted-host files.pythonhosted.org」を追加することで解決できます。

```エラー内容_02.txt
Could not fetch URL https://pypi.org/simple/ibm-db/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url:
/simple/ibm-db/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1108)'))
) - skipping
```

```
修正前：
pip install <PACKAGE_NAME> --proxy http://<PROXY_URL>:<PORT_NO>
修正後：
pip install <PACKAGE_NAME> --trusted-host pypi.org --trusted-host files.pythonhosted.org --proxy http://<PROXY_URL>:<PORT_NO>
```
PHP DateTime の差を小数点以下も含めて合計秒数を表示する

# 環境

- PHP 7.3

# コード

```php
$d1 = new DateTime('2020-01-01 12:00:00.123456');
$d2 = new DateTime('2021-02-03 14:50:06.654321');

$seconds = $d2->getTimestamp() - $d1->getTimestamp();
$decimal = $d1->diff($d2)->format('%f');
echo $seconds . '.' . $decimal;

// 34483806.530865
```

# 2020.01.30 追記

Carbonを使うとスマートに書けることを教えていただきました！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Carbonの使用をお薦めします。 <a href="https://t.co/ffA5iCpuSG">pic.twitter.com/ffA5iCpuSG</a></p>&mdash; Indra 印洞羅 (@neindk) <a href="https://twitter.com/neindk/status/1222751278758936576?ref_src=twsrc%5Etfw">January 30, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

```php
use Carbon\Carbon;

$d1 = new Carbon('2020-01-01 12:00:00.123456');
$d2 = new Carbon('2021-02-03 14:50:06.654321');

echo $d1->floatDiffInSeconds($d2);

// 34483806.530865
```

# 参考

- https://www.php.net/manual/ja/class.datetime.php
- https://www.php.net/manual/ja/class.dateinterval.php
- https://carbon.nesbot.com/docs
gradle buildがwindowsでjava.nio.file.InvalidPathException: Illegal char <:> at indexというエラーになる

<code>gradle build</code>をwindowsで実行したところ以下のようなエラーになった。以下エラー中のファイルパスは適当なものに書き換えている。

```
* What went wrong:
Execution failed for task ':api:compileJava'.
> java.nio.file.InvalidPathException: Illegal char <:> at index 71: /usr/local/xxx/lib/aaa.jar:/xxx/bbb.jar:/usr/local/xxx/ccc.jar

```

原因は依存性の中のあるjarのマニフェストファイルのClass-Pathだった。ここに以下のように":"（コロン）区切りでファイルパスが指定されていた。クラスパスは、Linuxでは区切り文字は":"（コロン）だが、windowsでは";"（セミコロン）、で指定しなければならない。よって、windowsでだけビルドエラーになる。

```
Class-Path: /usr/local/xxx/lib/aaa.jar:/xxx/bbb.jar:/usr/local/xxx/ccc.jar
```

対策としては、excludeするとか、問題のあるjarを作り直すとか、になる。
HTML メールの忘備録

自分の作業環境での話になるので、全ての環境で、とは行かない・参考にならないかもしれませんが、一応、自分の忘備録的に残しておきます。

## HTML メールの基礎知識

- テーブルレイアウト
- CSS はインライン指定  
    e.g. `<span style="font-size:14px">`
- メディアクエリーは `<style>` 要素内に記載

参考）[HTMLメールを作る前に押さえるべき基本事項](https://www.wantedly.com/companies/wantedly/post_articles/34634)



## HTML Attributes

- `<table>` ではなく `<td>` に `width` 属性を適用  
    table では可変にならないが td だと可変、レスポンシブになる。

## CSS Properties

- `box-shadow` - 適用されない物が多い
- `width`  
    - `max-width: 100%` は Gmail だと謎の px 値に変換される
    - `width: 100%` は問題なし
- Negative Margin - Gmail で適用されない

</ul>

- `<img width="100%">` and `img { max-width: 100% } ` と指定
    - 多種のメーラーで表示崩れを回避してると思われる

## 細かい挙動

### @ outlook.live.com

- インライン要素同士は勝手に繋げられる  
   ≒ 半角スペース除去  
    e.g. `<span /> <span />` → `<span /><span />`
- ブロック要素同士は勝手に離される  
   ≒ display: inline 時などに半角スペース分あく  
    e.g. `<div /><div />` → `<div /> <div />`
シェイプレイヤーパスの真ん中の座標を取る方法 [AfterEffects][Expression]

＃シェイプ事の真ん中座標
テキストをシェイプに変換してテキストキャラ毎（文字毎）に真ん中の座標を取得する方法
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/96964f65-3ed7-c6d7-5472-d0c67aab0b74.png)

```jsx
val = thisComp.layer("timetoeditアウトライン").content("t 2").content("t").path.points(0);

function center(arr){
	var tempx = [];
	var tempy = [];
	for (var i =0; i < arr.length ; i++){
		tempx.push(arr[i][0])
		tempy.push(arr[i][1])
	}
	var x = (Math.min.apply(null,tempx)+Math.max.apply(null,tempx))/2;
	var y = (Math.min.apply(null,tempy)+Math.max.apply(null,tempy))/2;
	return [x,y]
}

center(val)

```
配列基本

```java

public class test {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		int array[] = new int[10];
		int sum = 0;

		for(int i=0; i<=array.length; i++) {
			if(sum>100) {
				System.out.println("-----------------------------------------");
				System.out.println("入力された数値を出力");
				for(int j=0; j<array.length; j++) {
					System.out.println(array[j]);
				}
				System.out.println("-----------------------------------------");
				break;
			}
			else if(i==10) {
				System.out.println("-----------------------------------------");
				System.out.println("入力された数値を出力");
				for(int j=0; j<array.length; j++) {
					System.out.println(array[j]);
				}
				System.out.println("-----------------------------------------");
			}
			else {
				System.out.print((i+1)+"回目の数値を入力:");
				array[i] = new java.util.Scanner(System.in).nextInt();
				sum += array[i];
			}
		}
	}
}
iOS Safari / Android Chrome の 100vh フルスクリーン問題

スマホ向けのアプリケーション フルスクリーンを作る時の問題のお話です。

iPhone Safari height:100vh が正常動作しない問題があります。

## height: 100vh とは

- 「vh」は「viewport height」の略で、viewport の高さ（ブラウザの高さ）に対する割合を指定することが可能です
- viewport のサイズのため、下部にアドレスバーやナビゲーションが表示された場合は、100vh はそれに応じて小さくなリます。 

## height: 100% との違い
- height: 100% は親要素に対する割合です。100 vh は親要素関係なく viewport の高さを設定することができます。

## iPhone Safari で起きている問題
- 100vh はアドレスバーなどを覗く画面のサイズを返すはずなのですが、この値が正しくないケースがあります。そのため、アドレスバーの考慮が入ってないサイズになったりしてしまいます。
- Safari だけの問題かと思ったら、Android Chrome でも発生を確認しました。

## 対応策

- [viewport-units-buggyfill](https://github.com/rodneyrehm/viewport-units-buggyfill) を適用する。

発生すると言われる Mobile Safari on iOS and IE9+ に対して修正コードを当ててくれます。

### 導入

```
npm i viewport-units-buggyfill -d
```

### 使い方

実行場所はどこでも良いです。

```javascript
import viewportUnit from 'viewport-units-buggyfill';

// 対象端末に絞って対応するならこちら
viewportUnitsBuggyfill.init();

// 全ての端末を対象とする場合はこちら。Android Chrome でも現象を確認できたので force がおすすめです。
viewportUnitsBuggyfill.init({force: true});
```

webpack, es6 を使わない環境であればこちら。

```
<script src="viewport-units-buggyfill.js"></script>
<script>window.viewportUnitsBuggyfill.init();</script>
```

iframe の フルスクリーンなども問題なく実現できました。
ruby 配列の中身の差

Rubyの配列の中身の差を求める。

```ruby:array.rb
array = [1, 6, 8, 15, 18, 25]
array.each_cons(2) do |l, r|
   puts (r - l).abs
end
```

```ruby:実行結果
5
2
7
8
3
7
```

参考資料
https://ref.xaio.jp/ruby/classes/enumerable/each_cons
https://teratail.com/questions/115298
https://www.javadrive.jp/ruby/numeric_class/index7.html
rake db:createまでにハマった

#きっかけ
久しぶりに作りかけのアプリの続きでもやろうかと、開いたら、rake db:createができなかったところからハマった話

```
rake aborted!
LoadError: cannot load such file -- bundler/setup
```

この後にも色々ファイル名とか書いてあるが、とりあえず、bundler見つからないのいやそんなはずはないとここでなぜか思ってしまい、ググったコードをなんとなく試してみる。


```
$ sudo gem install bundler
```

なにやら権限を変えてbundlerをインストールするらしい。bundlerのインストールがうまくいっていないと思い上記のコードをターミナルにぶち込んでみる。
結果↓

```
Successfully installed bundler-2.1.4
Parsing documentation for bundler-2.1.4
Done installing documentation for bundler after 5 seconds
1 gem installed

```

はいできた！！で、`rake db:create`↓


```
LoadError: cannot load such file -- bundler/setup
```

ハマる予感。。

改めて

```
$ gem install bundler
```

結果

```
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_sysopen - /Users/ユーザー名/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/CHANGELOG.md
```

だいたいこーなったら当てずっぽうで色々やってみるパターンになる。文字読むの嫌いだから。

とりあえずbundler入っているのかいないのかわからんので。`bundler -v`

```
Traceback (most recent call last):
	2: from /Users/ユーザー名/.rbenv/versions/2.5.1/bin/bundler:23:in `<main>'
	1: from /Users/ユーザー名/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/Users/ユーザー名/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundException)

```

読む前にググる。なにやらGemfile.lockに記載されているBUNDLE_WITHのバージョンがインストールされているbundlerのバージョンが違うとか書いてある。のでバージョン指定でインストールしてみる

```
$ gem install bundler -v 2.0.2
```

```
$ bundler -v
Bundler version 2.0.2

```
キタコレ！

が！

```
rake db:create
Could not find rake-13.0.1 in any of the sources
Run `bundle install` to install missing gems.

```

慌てすぎた。

```
$ bundle install
```

ここで`bundle install`している途中にこんなエラー文が出て完了できなかった。

```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```

これも即ググり、コードコピペ。

```
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
```

なにやら空であったbuild.mysql2のローカル値を入れているらしい。

そして、やっと`bundle install`完了からの`rake db:create`

```
rake aborted!
LoadError: dlopen(/Users/ユーザー名/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib

```

これは

```
$ brew update && brew upgrade
```

Homebrewとパッケージのアップデート

そして、やっと

```
$ rake db:create

```

成功。

#まとめ
ターミナルを遡って書いてはみたが、記録として。これ以外にも色々やってはいるが、長すぎて、変化のあったところだけ抜粋。いつか見返して全ての意味がわかればいいかなと。
FormからPUT、PATCH、DELETEリクエストを送る方法（Laravel）

### はじめに
今回は、LaravelでFormからPUT、PATCH、DELETEリクエストを送る方法をアウトプットします。前提として、HTMLのformタグがこれらの形式をサポートしていないため、実際のところPOST送信となっています。それを回避するための対策です。

#### POST,PUT,PATCHの使い分けの参考資料
[POSTとPUTとPATCHの使い分けについて](https://teratail.com/questions/193410)

#### ルート定義メソッドの機能名等についての参考資料

[Laravelのルーティング表](https://qiita.com/daijinload/items/3024bea467fdc3464826)



### 結論
(例)このようなフォームがあったとします。

```hoge.blade.php
<form action="{{ url('/posts',$post->id) }}" method="post">
  @method('PATCH')
  @csrf
</form>
```

上記のように、Baldeのディレクティブを使って、@method('PATCH')と記述してあげれば、Laravelで送信形式をPATCHと判断することができます。
<font color="Red">PUTとDELETEに関しても、ここのPATCHの箇所を置き換えていただければ大丈夫です。</font>

##### では、実際に試して確認してみましょう。

まず、HTTP動詞に対応したルートを定義してあげます。


```web.php
Route::patch('/posts/{post?}','PostsController@update');
```



```PostsController.php
public function update(Request $request)
{
    dd($request->method());
}
```
dd関数を使用して、リクエストされたメソッドを確認してみると


![patch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/03d70ff9-fe79-85ae-f598-145500902229.png)

はい、ちゃんとメソッドが確認できていますね！


### おわりに
アウトプットというよりもメモになってしまいましたね（笑）もし内容に誤りがありましたら、お手数ですがご指摘をよろしくお願い致します。読んでいただき、ありがとうございます。

---
### 参考記事
[LaravelのFormからPUT / PATCH / DELETEリクエストをおくる](https://blog.e2info.co.jp/2018/04/21/laravel_form_put_patch_delete/)
【Git】コミット日時を最新化する

# コミット日時を現在日時に更新したい
以下のコマンドを実行することで、 AuthorDate と CommitDate に最新日時を設定してコミットしなおすことができます。

```
$ git commit --amend --date=now
```

rebase でコミット順を変更したり、 cherry-pick でコミットを引っこ抜いてきたあとコミット日時を更新したいときに使ってます。
deviseを使う

##### ※rails 開発環境設定（既に設定済みの場合はスルーしてください）
https://qiita.com/tksh8/items/d9190451d1f01d5a5e19


## deviseとは
Ruby/railsのgemの1つで、ログイン機能の実装を簡単にしてくれるgemである

### 1.アプリの新規作成

```
rails _5.2.3_ new devise_app
```


### 2. deviseをインストール


```Gemfile:Gemfile
gem 'devise'
```

```
$ bundle install
```

依存するファイルも一緒に作成

```
$ rails g devise:install
```

### 3.Usersモデルを作成

```
$ rails g devise user


マイグレーション
$ rails db:migrate
```

```
起動
$ rails s
```
これだけで

http://localhost:3000/users/sign_in
にアクセスすると、

<img width="226" alt="スクリーンショット 2020-01-29 20.51.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355517/b67c78ad-60de-5267-bd9a-a2eba891da1d.png">


ログインページができます！！！
便利すぎる！！

### 次回：punditを使う



--------
これでほとんどdeviseでの簡単な紹介は終わったのですが、

初学者の方は参考程度に
↓

### 4.ルーティングの設定

```ruby:config/routes.rb
root to: "home#index"
```


views/home/index.html.erbを作成

```ruby:views/home/index.html.erb
TOP画面です！
```

controllers/home_controller.rbを作成

```ruby:controllers/home_controller.rb
class HomeController < ApplicationController
  def index

  end
end
```

### 6. Flashメッセージの設定


```ruby:layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>DeviseFunction</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>
```



### 7. deviseに対応したコントローラ,ビューの作成

```
コントローラ
$ rails g devise:views users

ビュー
$ rails g devise:controllers users
```

日本語化
https://qiita.com/tmyn470/items/ce61aba0a0b45407cb2a¥
Laradockで複数プロジェクトのローカル環境構築！

Windows10のアップデートでvirtureBoxの環境がぶっ壊れてしまい、Laradockに触れてみた。
やっと起動したぜ！

#**1．下準備（Docker desktopインストール）** 

ローカルドメインイメージ

```
https://dog.local/
https://cat.local/
https://pig.local/
```

* 以前、vitureBoxを使用していた場合はdockerで始まる環境変数を全て削除する
*  **hyper-vを有効化** する（https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v）
* タスクマネージャで仮想化が有効になっているか確認（念のため）
* TMBDserviceを無効にして置く（ウイルスバスターファイアウォール環境の場合）
* Docker for Windowsをインストールして、 **管理者権限** で実行（https://docs.docker.com/docker-for-windows/install/）
* Docker desktopアイコンを右クリックSwitch Linux･･･項目がある場合 **Linuxコンテーナに変更** する。
* Docker desktop右クリック→Setting→ **File sharingにチェック** を入れる

*既存プロジェクトを各フォルダにクローンして置く
作成イメージ

```
c://work/laradock　//laradockは勝手に生成されるので作らない
c://work/dog
c://work/cat
c://work/pig
```


# **2．Laradockをクローン** 

コマンドプロンプトを **管理者権限** で開く

```
cd  work <-任意の作業フォルダ
git clone https://github.com/Laradock/laradock.git laradock
```


#**3. Laradockの.env設定** 

laradockフォルダ内のenv-exampleをコピーして
.envを作成
.envをエディターで開いてphpのバージョンを7.2にする

```
-PHP_VERSION=7.3
+-PHP_VERSION=7.2
```
他の設定は不要



# **4. Laradockでnginxの複数サイト設定** 

c://work/laradock/nginx/sitesへ移動
laravel.conf.exampleをコピーして
dog.conf
cat.conf
pig.conf
を作成
dog.conf、cat.conf、pig.confの中身を編集

```
//下記コメントアウト
#listen 80;　
#listen [::]:80;　

//下記追加
listen 443 ssl; 
listen [::]:443;
ssl_certificate /etc/nginx/ssl/dog.local.crt;　//SSL設定用のオレオレ証明書
ssl_certificate_key /etc/nginx/ssl/dog.local.key;
//（cat、pig同様）

//server_name とrootを変更
server_name dog.local;
root /var/www/dog/public;
```

C:\work\laradock\nginx\startup.shを開く

下記内容を追記
★同じ内容のcat,pigバージョンをそれぞれ作成

```
if [ ! -f /etc/nginx/ssl/dog.local.crt ]; then
    openssl genrsa -out "/etc/nginx/ssl/dog.local.key" 2048
    openssl req -new -key "/etc/nginx/ssl/dog.local.key" -out "/etc/nginx/ssl/dog.local.csr" -subj "/CN=dog.local/O=dog.local/C=UK"
    # ↓ Chrome用に設定を追加。ホスト名を指定する。
    echo subjectAltName=DNS:dog.local > "/etc/nginx/ssl/dog.ext"
    openssl x509 -req -days 365 -in "/etc/nginx/ssl/dog.local.csr" -signkey "/etc/nginx/ssl/dog.local.key" -out "/etc/nginx/ssl/dog.local.crt" -extfile "/etc/nginx/ssl/dog.ext"
fi
```

 

#**5.hostsの設定を行う** 

メモ帳を管理者権限で下記のhostファイルを開く
C:\Windows\System32\drivers\etc\hosts

```
127.0.0.1 dog.local
127.0.0.1 cat.local
127.0.0.1 pig.local
```
を追記

 

#**6.コンテーナ起動** 

初回は数分かかる

```
docker-compose build nginx
docker-compose up -d workspace nginx
```
エラーなくコンテーナが起動したら
下記URLで確認して完了

```
https://dog.local/
https://cat.local/
https://pig.local/
```

#**7.そのた** 

・コンテーナ起動
docker-compose up -d workspace nginx
・コンテーナoff
docker-compose down
・コンテーナ確認
docker-compose ps
・nginxコンテーナ中身
docker exec -it laradock_nginx_1 bash

健闘を祈る、、