OmniAICreator/Qiita-1.07M huggingface dataset:
CWLのInitialWorkDirRequirementについて

# 概要

CWL の InitialWorkDirRequirement は、いろいろなことができる。
またそれにより、本来の用途と違ったことに、「使えそうにみえる」ことがあるので、
それらについて、今までに得られた知見をまとめておく

いろいろなことが、わかってくるので、随時書き足していく予定です。

# 結論

あくまで `ステージング用途で使うものである。`
ホスト側のディレクトリを、ワークフロー実行時にマウントするという用途のためにあるわけではない。

## そもそもステージング用途である。

そもそもステージング用途である。
既存のディレクトリを指定したとしても、
実行用の環境(たいてい/tmp/以下のディレクトリ)に、
既存のディレクトリをコピーすることになる。

## 書き込み可能なディレクトリを作りたいときに使う。しかし書き込みをしてもホスト側に反映されない？

InitialWorkDirRequirement で指定されたディレクトリは、実行環境にコピーされる。
コピーされたディレクトリは、デフォルトでは、リードオンリーである。

おそらくここが気になっている人の多くは、このディレクトリになにか作成し、それを取り出したいと考えているのではないかとおもう。
デフォルトでリードオンリーなので、書き込みができないというエラーがでる。
仕様を読むと、 `writable` が指定すると、新しいディレクトリに書き込みが可能となる。

実際にツールを実行しても、書き込みができないというエラーはでなくなる。

ただし、書き込みができても、それはあくまで、ステージングされたディレクトリ内であり、
ホスト側にそのデータが永続化されるわけではない。

特に構造化されていなくても良い状態で、ファイルや、ファイル群を、永続化したいのであれば、 `outputs` で、とりだせばよいが、
構造化されたディレクトリをつくってそれを取り出したいのであれば、ディレクトリを作ってそれを `outputs` で回収するということになる。

このとき、ホスト側に存在するディレクトリに追記する形でとりだしたいとう場合については、今後何かを書く予定。

## できることが多い

- 新しいディレクトリを作る
  - writable でも作れる
- 新しいディレクトリを作った上で、そこに、指定したファイルを置くということもできる
- ホスト側にあるファイルを置くこと（ステージング）もできる
- ファイルシステム上の既存ディレクトリを渡す（ステージング）こともできる
  - 相対パスがおすすめ
  - フルパスは、ただしく動くか不明、今後書く予定


## 使用例としては、compformance test にでている。

今後それらを紹介して行く予定

## 実際にあったケース

実際にあったケースを消化雨する予定

### ケース1 --tmpdirみたいなのを.cwlのなかで指定できませんか？

>  https://github.com/ykohki/DAT2-cwl/blob/master/tool/sleuth/sleuth.cwl
>  でkallistoのoutput dirをinputにしているのですが、tmpdirがみんなバラバラになってしまうのでsleuth.Rから読み込めなくなってしまいます。安直にやるなら、sleuth.Rにkallistoのoutput dir
> 引数として全て渡してもいいのですが、sleuth.Rでkallisto_outのtmpdirを一箇所にまとめてそのpathをsleuth.Rの引数にとった方が少し汎用性が高いのかなと考えています。

#### 解決方法

この方法でまとめることができた

```
  - class: InitialWorkDirRequirement
   listing:
     - entry: $(inputs.kallisto_out)
       writable: true
```
管理工数(請負)

　　(1)進捗管理
　　　・開発スケジュールの作成・修正
　　　・進捗報告書の作成
　　　・進捗定例会議への参加
　　(2)品質管理
　　　・設計書レビューの実施
　　　・ソースコードレビューの実施
　　(3)変更管理
　　　・仕様変更に対する会議への参加
　　　・変更箇所に対する設計・影響調査
　　　・スケジュール調整
　　(4)障害管理
　　　・テストに対する障害の集計と改修計画
　　　・改修結果に対する確認
　　(5)リスク管理
　　　・他プロジェクトとの連携部は遅延が影響する
　　　・QCDに対してのリスク→洗い出し→対処法→工数計算　

全体工数の1割程度
ただし案件によっては2割など顧客によって要調整

参考ブログ
https://qiita.com/tshiono9/items/7b19c17a5c66bbc57fd5


突っ込まれる事項
リスク工数
- 納期遅れなどを進捗定例会議に突っ込まれるので前もって用意しておく必要がある
- 納期遅れの期間は作業代もらえるんですか？等


リスク管理フォーマットを作成する
オプショナルのお勉強

Swift超初心者がひとまず１0分勉強した。
オプショナルの入り口の備忘録。
ちょっとずつ付け足すつもり。

``` *.swift
// nilを取り扱えない通常の変数を宣言
var suji_A: Int8 = 10
var moji_A: String = "moji_A"

// nilを取り扱えるオプショナル変数を宣言
var suji_B: Int8? = nil
var moji_B: String? = nil

// 型名をデバッグ表示
print(type(of: suji_A))   // => Int8
print(type(of: moji_A))   // => String
print(type(of: suji_B))   // => Optional<Int8>
print(type(of: moji_B))   // => Optional<String>

//print( suji_A + suji_B )
// => Error : Value of optional type 'Int8?' must be unwrapped to a value of type 'Int8'
//print( moji_A + moji_B )
// => Error : Value of optional type 'String?' must be unwrapped to a value of type 'String'

// アンラップ
// nilなので実行時エラー

//print( suji_A + suji_B! )
/* 実行時エラー
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
*/
// => Fatal error: Unexpectedly found nil while unwrapping an Optional value

// nilを解消
suji_B = 20
moji_B = "moji_B"

//print( suji_A + suji_B )
// => Error : Value of optional type 'Int8?' must be unwrapped to a value of type 'Int8'
//print( moji_A + moji_B )
// => Error : Value of optional type 'String?' must be unwrapped to a value of type 'String'

// アンラップ
print( suji_A + suji_B! )   // => 30
print( moji_A + moji_B! )   // => moji_Amoji_B

/////////////////////////////////////////////////////////////////////////////////
// おまけ（マークアップコメント）
// マークダウン形式でコメントをつけることができる。
// 表示の切り替えは、
// [Editor] - [Show Raw Markup]
/*:
 - - -
 # 設計文書（クラス設計）
 ## マークアップコメント
 1. Step1
 1. Step2
 1. Step3
 
 * 箇条書き1
 * 箇条書き2
 * 箇条書き2
 
 ## 参考記事
 [XcodeでSwiftの型を把握する](https://qiita.com/bannzai/items/bc6e286dc590e30d3714)
 
 [どこよりも分かりやすいSwiftの"?"と"!"](https://qiita.com/maiki055/items/b24378a3707bd35a31a8)
*/
/////////////////////////////////////////////////////////////////////////////////
```
R言語の基礎

## 文法基礎メモ

#### 配列

```
> matrix(1:12, 3, 4)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
```

#### グラフ

```
x <- rnorm(100, mean=0, sd=1) #平均100、標準偏差1の乱数を100個生成

plot(x) #描画
hist(x)
```

#### ファイルの読み込み・書き込み

```
read.csv("test.csv")
write.csn(x, "test.csv")
```
JavaScriptでstring->numberへのcastは2種類あるので使い分ける

- Number()
- parseInt

の2種類ある

挙動に違いは以下

```js:Number()とparseInt()の違い
console.log(Number("1234"));  // 1234
console.log(parseInt("1234"));  // 1234

console.log(Number("asdf"));  // Nan
console.log(parseInt("asdf"));  // Nan  ここまでは同じ結果

console.log(Number(""));  // 0  空の文字列のとき0
console.log(parseInt(""));  // Nan  からの文字列のときNan
```

例えば `JSON.stringify` でこれらを変換する場面で結構な違いになる

```js
const obj = {foo: parseInt("")};
console.log(JSON.stringify(obj));  // {"foo": null}
obj.foo = Number("");
console.log(JSON.stringify(obj));  // {"foo": 0}
```

自分のイメージ的には `""` をnumberにcastしたときは `null` 値になって欲しい気がするので、基本的には `parseInt()` を使ったほうが意図しない変換結果になることを防げる気がする

また、 `parseInt` は以外と名前の通りいろいろやってくれる

```js
console.log(parseInt("20px"));  // 20 いい感じにparseしてくれる
console.log(parseInt("Jackson5"));  // NaN でも後方にある場合はだめ
console.log(Number("20px"));  // Nan

// 基数指定できるのもparseInt
console.log(parseInt("0x100", 16));  // 256
```

## 参考

- [parseInt\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
- [Number \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number)
【Laravel】リレーション先のデータ取得方法を調べた

LaravelのEloquent ORMは、テーブル間のリレーションを管理・操作する際の独自の表現があります。
[Laravel5.8 Eloquent：リレーション](https://readouble.com/laravel/5.8/ja/eloquent-relationships.html)

"１対多"や"多対多"のリレーションなどはよく使うのではないでしょうか。
今回は、これらのリレーションを定義したのち、<b>実際にリレーション先のテーブルのデータをどうやって取得するのか</b>、いくつか手法を調べました。

※ここから先は、予めモデルクラスに以下のリレーションを定義したという前提で進めます。
ブログサイトなどで、1人のユーザーが複数の投稿を登録しているという想定です。

```User.php
    public function posts()
    {
        return $this->hasMany('App\Posts');
    }
```

<br>

### 1.メソッドで呼び出す

マニュアルに記載されている、基本のやり方です。

```User.php
// ユーザーに紐づく投稿を全て取得し、Collectionで返す
    public function getPosts()
    {
        return $this
            ->find(1)
            ->posts()
            ->get();
    }

// 条件を付け加えることももちろん可能
// ユーザーに紐づく投稿について、題名で部分一致検索するものをCollectionで返す
    public function getPostByTitle()
    {
        return $this
            ->find(1)
            ->posts()
            ->where('title', 'LIKE', '%hoge%')
            ->get();
    }
```

`posts` メソッドが呼び出されると、システムは `Posts` モデルクラスを参照します。
ですから、通常のモデルクラスの操作と同じように、メソッドチェーンであらゆる条件などを追加できます。

公式マニュアル曰く
> Eloquentは「動的プロパティ」を提供しているので、モデルのプロパティとして定義したリレーションメソッドへアクセスできる

ということで、以下の書き方も可能です

```User.php
    public function getPosts()
    {
        return $this
            ->find(1)
            ->posts; //プロパティで呼び出す
    }
```

さて、筆者も初めはこの方法で全てなんとかなると思っていましたが…ちょっとした落とし穴がありました。
というのも、上記のメソッドで取得できるのは<b>特定のユーザーに紐づく、投稿のデータのみ</b>であるため、例えば<b>ユーザーのデータと投稿のデータを同時に返したい</b>という場合や、<b>ある条件を満たすユーザーに紐づく投稿を取得する</b>といった場合に不都合が生じたのです。

```User.php
    public function findPostByUserIsOver25yo()
    {
        return $this
            ->where('age', '>', '25')
            ->get()
            ->posts;
            //get()した時点でcollectionオブジェクトになっており、collectionからpostsプロパティを呼び出そうとしているため、エラーになる
    }
```
そのような時はどうすればよいのでしょうか？

### 2.withメソッドを用いる
このような場合は、 `with()` メソッドを使うとうまくいくようです。
[参考にさせていただきました](https://www.yoheim.net/blog.php?q=20181104)

（公式マニュアルよく読んだらひっそりと使われていた…調べて存在を知るまで気がつかなかった）

```User.php
    public function findPostByUserIsOver25yo()
    {
        return $this
            ->with('posts')
            ->where('age', '>', '25')
            ->get();
    }
```

このように取得すると、 各 `User` モデルクラスの `relations` プロパティに `Post` モデルクラスが紐づいた状態になり、条件に合うユーザーのユーザー情報と投稿データを一度に取得できます。



### まとめ
両者を比較した上で、筆者の意見としては<b>全部withでよくね？</b>というのが正直なところです。
特に親テーブルのデータが不要で小テーブルの情報だけ取得したいという場合は、メソッドで呼び出すのがいいのだと思いますが、結局 `relations` プロパティで呼び出せるしなぁ…
もう少し色々な挙動を試してみたいです。

ご意見・ご指摘などありましたらコメントお寄せください。
コマンドヒストリーの検索を手軽にしたい

自分の環境構築用メモ。

```
$ histry
```

してからの
ctrl+r
でもいいんだけど
ctrl+r
だけで検索したいなっていうあれ。

# pecoをinstall

macでbrewはいってる前提です。

```
$ brew install peco
```

# .zshrcに追記

```
function peco-select-history() {
    local tac
    if which tac > /dev/null; then
        tac="tac"
    else
        tac="tail -r"
    fi
    BUFFER=$(\history -n 1 | \
        eval $tac | \
        peco --query "$LBUFFER")
    CURSOR=$#BUFFER
    zle clear-screen
}
zle -N peco-select-history
bindkey '^r' peco-select-history
```

追記したら

```
source ~/.zshrc
```
して反映。

ctrl+r

でコマンドヒストリー検索だ！
【Rails on Rails】.envの環境変数をjsファイル内で利用する方法

#はじめに

Rails内で環境変数を.envファイル内に書いておくと、ENV["環境変数名"]で利用することが出来ます。

しかし、erbファイル内では利用することが出来ますが、jsファイルで利用することが出来ません。

そこで、jsファイル内で環境変数を利用する方法を解説します。


#gemのインストール

以下の２つのgemをインストールします。

Gemfileに以下の２つのgemを記入し、

```ruby:Gemfile
gem 'gon'
gem 'dotenv-rails'
```
bundle installします。

```
bundle install
```

#.envファイルの作成作成

jsファイル内で利用したい、環境変数を.envファイルに記入します。

```ruby:.env
KEY = "xxx"
```

#.gitignoreファイルを編集

念の為、GithubなどにAPI KEYなどの環境変数が公開されていように設定します。
.envに以下の１行を追加します。

```ruby:.gitignore
/.env
```

#application.html.erbの編集

application.html.erbのhead内に以下の１行を追加します。

```ruby:application.html.erb
<%= include_gon %>
```

:triangular_flag_on_post:**【注意】javascriptより上に書くこと**


#コントローラーの編集

環境変数を利用したいコントローラーのメソッドに追記。

```ruby:xxx_controller.erb
def xxx
 gon.xxx_key = ENV['KEY']
end
```

:triangular_flag_on_post:**KEYは.envに記述したもの**

#jsファイルの編集

```ruby:xxx.js
const KEY = gon.xxx_key;// 環境変数
```


これでjsファイル内で環境変数を利用することが出来ます。

#参考リンク
https://qiita.com/uma0317/items/e142661c004f68d858a5
NETWORKDAYS関数


#NETWORKDAYS関数
あるインシデントの受付～完了までの時間をカウントしたいというニーズがあり、
単純に`完了日時-受付日時`してしまうと、土日祝日まで時間に含まれるので、対応時間が実態に合わなくなる
ということで稼働日をカウントする関数を調べてみました
[EXCEL:NETWORKDAYS関数](https://support.office.com/ja-jp/article/networkdays-%e9%96%a2%e6%95%b0-48e717bf-a7a3-495f-969e-5005e3eb18e7?NS=EXCEL&Version=16&SysLcid=1041&UiLcid=1041&AppVer=ZXL160&HelpId=xlmain11.chm60520&ui=ja-JP&rs=ja-JP&ad=JP)

```Excel:NETWORKDAYS
　=NETWORKDAYS(開始日,終了日[,祝日])
```
日数がこれでカウントできるので、24時間を掛ければ経過時間が出せるようになります
祝日を設定するには、直接日付を入れてもいいが、祝日リストを作っておいて範囲指定するのが扱いやすい

|A|B|C|
|:-:|:-:|:-:|
|2019/7/1|2019/7/31|2019/7/15|
|||2019/7/16|

```EXCEL:NETWORKDAYS
=NETWORKDAYS(A1,B1,C1:C2)
```
とすると
`20`という結果が得られる

ちなみに、日付をカウントする`DAYS`関数だと`=DAYS(完了日,開始日)`と逆順になる

##時間までカウントするには？
開始日の開始時間から終了日の終了時間までの営業時間をカウントするにはどうしたらいいか？
初日と最終日のところだけ数値を変換する

|A|B|C(祝日)|
|:-:|:-:|:-:|
|2019/7/1|2019/7/31|2019/7/15|
|時間(始|時間(終|2019/7/16|
|10:00|18:00||
```Excel:NETWORKDAYS
=(初日の時間)+中間の日数*24時間+(最終日の時間)
=("24:00:00"-A3)+(NETWORKDAYS(A1,B1,C1:C2)-2)*"24:00:00"+(B3)
```
Excelの場合は[書式設定]>[ユーザー定義]で、`[h]:mm:ss`とすると、経過時間表記になります

###GoogleSpreadSheetなら以下のようにも書けます
Sheetの場合は[表示形式]>[数字]>[経過時間]に書式を変更する

```GoogleSheet:NETWORKDAYS
=time(24,0,0)-A3+(NETWORKDAYS(A1,B1,C1:C2)-2)*time(24,0,0)+(B3)
```
※この書式、Excelだとエラーになります。TIME関数の仕様で、Excelではtime(0,0,0)~time(23,59,59)までとなっているためのようです

###営業時間でカウントしたい
ある案件が7/1 13:00 ~ 7/10 12:00 まで継続し、営業時間は10:00~19:00なので、営業時間で経過時間をカウントしたい場合

|A|B|C|D|E|F|
|:-:|:-:|:-:|:-:|:-:|:-:|
|開始日|開始時間|完了日|完了時間|営業時間(始|終)|
|7/1|13:00|7/10|12:00|10:00|19:00|

```Excel:稼働時間(営業時間計)
=(初日の稼働時間)+(中間の稼働時間)+(完了日の稼働時間)
=(F2-B2)+(NETWORKDAYS(A1,B1,C1:C2)-2*9)+(D2-E2)
```

##休日が土日とは限らない
`NETWORKDAYS`関数は土日を非稼働日として除きますが、必ずしも土日が休みとは限らないはずです
そんな場合には`NETWORKDAYS.INTL`を使うことができます
[NETWORKDAYS.INTL](https://support.office.com/ja-jp/article/networkdays-intl-%E9%96%A2%E6%95%B0-a9b26239-4f20-46a1-9ab8-4e925bfd5e28)

```EXCEL:NETWORKDAYS.INTL
=NETWORKDAYS.INTL(開始日, 終了日, [週末], [休日])
```
`NETWORKDAYS`に加えて、週末を引数で設定できます

|週末番号|週末の曜日|
|:-:|:-:|
|1 または省略|土曜日と日曜日|
|2|日曜日と月曜日|
|3|月曜日と火曜日|
|4|火曜日と水曜日|
|5|水曜日と木曜日|
|6|木曜日と金曜日|
|7|金曜日と土曜日|
|11|日曜日のみ|
|12|月曜日のみ|
|13|火曜日のみ|
|14|水曜日のみ|
|15|木曜日のみ|
|16|金曜日のみ|
|17|土曜日のみ|
うちは月・水が休みなんだけど、という場合は、7桁の数値で設定できます
0=稼働日
1=非稼働日です
月水休みなら、

```EXCEL:NETWORKDAYS.INTL
=NETWORKDAYS.INTL(開始日,終了日,"1010000"[,祝日])
```
のように書きます。最近流行の週4勤務などにも対応できそうですね


## 資料：2019年の祝日
2019/1/1
2019/1/14
2019/2/11
2019/3/21
2019/4/29
2019/4/30
2019/5/1
2019/5/2
2019/5/3
2019/5/4
2019/5/5
2019/5/6
2019/7/15
2019/8/11
2019/8/12
2019/9/16
2019/9/23
2019/10/14
2019/10/22
2019/11/3
2019/11/4
2019/11/23
Xcode11 Beta4 で Carthage の Build Failed を回避する

### Xcode11 Beta4 で Carthage の Build Failed を回避する
------------
Xcode11 Beta4 で Carthage で framework をビルドすると失敗しました。
回避策が本家Carthage の issues にありました。感謝です。
「Xcode 11.0 Beta 4がSwiftを含むフレームワーク（ビットコード付き）のアーカイブに失敗する」
そうです。

------------
##回避策
#xcconfigファイルを用意する
この例でのファイル名は
```
workaround.xcconfig
```
ファイルの内容は
```
LD_VERIFY_BITCODE=NO
```
だそうです。
ビルド時にフルパス指定するので任意の場所に作成します。
お好きな方法で作成してください。
以下はターミナルで作成する例です。

```
$ echo LD_VERIFY_BITCODE=NO > workaround.xcconfig
```

------------
##ターミナルでこのファイルを指定しつつ、いつものbuild、またはupdateコマンドを実行

ビルド失敗したということは既にcheckout済みですのでbuildの例を以下に示してみます。
通常はupdateコマンドでよろしいかと思います。
workaround.xcconfigはフルパス指定しないとうまくいきませんでした。
パスはみなさんそれぞれですので読み替えてください。

```
$ XCODE_XCCONFIG_FILE=/Users/SomeUser/SomeDirectory/Project/workaround.xcconfig carthage build --platform iOS
```

------------
### リンク
#### Carthage の issues
[Carthage/issues : Xcode 11.0 Beta 4 fails to archive Swift-containing frameworks w/ Bitcode · Workaround Available #2825](https://github.com/Carthage/Carthage/issues/2825)

#### 参考記事
xcconfigで快適なBuild Settingsライフを
https://qiita.com/hirothings/items/7f6943db609ff88c10be

超効率化外伝: xcconfigの便利なところ＆設定例
https://qiita.com/rotors123/items/1affd9a286505536e809
plunkerでvue その4

#概要

plunkerでvueやってみた。
babylonやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cdf36d6f-780d-702f-8cf2-159e4c40af84.png)


#成果物

https://embed.plnkr.co/N5qs1ACkQaMOsgFlv7Qn/

以上。
plunkerでvue その3

#概要

plunkerでvueやってみた。
threeやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8c1c1f78-3185-55c6-83a6-236e7e5ba28d.png)


#成果物

https://embed.plnkr.co/KVp4k2mRqwjgfmvcyTtO/

以上。
AzureDevOps でDocker をAzure Container Registry にデプロイ!

Azure DevOps 触ってみた

### Pipelineを作る

(1)まずは[AzureDevOps](https://azure.microsoft.com/ja-jp/services/devops/)にログインし「Create Project」をクリック
![AzureDevOps01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/a8446eaa-014d-a4cc-9aa5-7c6f1d309d9d.png)

(2)適当に名前を付けて、「Create」をクリック
　今回はとりあえず「Private」で作ります
![AzureDevOps02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/cffc47d6-2fff-7f25-4d0b-6b2b2b754e1e.png)

(3)出来上がったらロケットのマーク(Pipelines)をクリック
![AzureDevOps03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/c6812ce0-9542-aa66-d3da-b6effcb04f13.png)

(4)「New Pipeline」をクリック
![AzureDevOps04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/6c86ef8e-18c9-5791-8ac4-dfea120e689e.png)

(5)ソースコードの置き場所として今回は「GitHub」を選択
![AzureDevOps05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/35ca23ea-1a53-5205-2a3c-b3b557a04926.png)

※Preiew future の 「Multi-Stage Pilelines」をOnにする
(Pipeline内のジョブを段階にまとめることができる)
![AzureDevOps05.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/eace274a-d81a-0339-a158-200bb903b2ce.png)

(6)GitHubの連携のため認証を行う
　 すでに連携してるGitHubアカウントがあれば「Grant」をクリック(要パスワード入力)
![AzureDevOps06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/289f44a6-f902-9e0f-d304-bf5c86a7d1c1.png)

(7)連携できるとリポジトリが出てくるので、必要な方を選択する
![AzureDevOps07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/a1731c4d-c284-96cf-49b7-ec70ba8bf89a.png)

(8)このプロジェクトでリポジトリを限定するかを選択し「Approve & Insall」をクリック
![AzureDevOps08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/b24b46f4-23ec-c6bb-0137-009fd69d33ea.png)

(9)「Docker」をクリック
![AzureDevOps09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/0dd787a1-8e71-7d45-bf3e-8fd06854f84a.png)

(10)今回Azure Container Registry を使うのでSubscription を選択
![AzureDevOps10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/699a64d1-134f-0545-7d85-ca6e27e2a0cd.png)

(11)保存するContainer Registry名を確認して「Validate and configure」をクリック
![AzureDevOps11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/f3f4c370-e90b-f62c-f849-a38a5d168ed1.png)

(12)yamlファイルが出来上がるので、問題なければ「Save & run」をクリック
![AzureDevOps12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/b5628fc6-8e78-8f9b-6d5e-f9bb50226512.png)

(13)コミット時のメッセージとMasterとプルリクエストか選択して「Save & run」をクリック

(14)実行されるとこんな画面になる。下にある「build」をクリック
![AzureDevOps14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/aa38c3b3-2823-c3c1-113d-d865ee606f85.png)

(15)なんとログも見ることができる！！
![AzureDevOps15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/8139be2e-4162-eaa7-a8bc-3b6f4268cc36.png)

(16)Azure ポータル側からもデプロイされたことが確認できる！
![AzureDevOps16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/097a1b95-15b6-a58b-605f-3b29fccc37bc.png)
React Native Error: System limit for number of file watchers reached

#React Native Error: System limit for number of file watchers reached


いつものようにyarn startでReactNativeアプリケーションを立ち上げるとこんなエラーが出た。あ〜も〜ReactNativeアプリをイチから再構築か？と諦めながら検索したらどちらかというとubuntuの問題であった。簡単な解決方法。しかしマイubuntuでいろいろ開発してるけどなぜにReactNativeで？の疑問は残る・・・


###原因
システムによってモニタリングされているファイルが上限を超えた。

###解決方法
```bash
$ sudo gedit /etc/sysctl.conf
```
でsysctl.confを開いて、ファイルの最終行に以下の一文を追加


`fs.inotify.max_user_watches=524288`

そしたら保存。
<br>

そしたら次のコマンドで確認。
`sudo sysctl -p`


以下のように出力されるはず。

```bash
$ sudo sysctl -p
fs.inotify.max_user_watches = 524288
```
これで無事にyarn startできた。


<br>
参考：[React Native Error: ENOSPC: System limit for number of file watchers reached](https://stackoverflow.com/questions/55763428/react-native-error-enospc-system-limit-for-number-of-file-watchers-reached)

<br>
CentOS 或いはEC2(Amazon Linux 2) にapache2.4 ,php5.4 を追加する

#あらすじ
先輩に教えてもらったキーワードを元にサーバーを構築する備忘録。
今回はapache,phpを追加する。AWSのEC2にも同様の記述が使えるそうなので、そちらでも構いません。
EC2で動作確認しながら書いてます。
※2019年7月22日追記
本当はDBも入れようして失敗したので理由探してたのですが、Amazon Linuxを選択していて、それ自体がmariaDBをサポートしていないことが原因でした。EC2はAmazon Linux 2を選択してください。


##とりあえず2ついっぺんにインストール

```
$ sudo yum install httpd php 
# Is this ok [y/d/N]: が出て止まったら y,Enter でok
```
##apache
[apacheについてはこちら](https://www.kagoya.jp/howto/rentalserver/apache/)

```
# httpdを起動
$ sudo systemctl start httpd

# 確認（active:runningになればOK）
$ sudo systemctl status httpd

# システム起動時に毎回起動するように設定
$ sudo systemctl enable httpd

# 確認
$ sudo systemctl is-enabled httpd

# 起動
$ sudo systemctl start httpd.service
```

うまくいけばapacheのテストページが表示されます。
AWSでElastic IPに書かれてるIPをブラウザに打ち込んで入ってみましょう。もし失敗したらAWSのセキュリティグループのページを確認して、HTTPのポート８０番が空いているか確認しましょう。

<img width="787" alt="86153f00ca952916533bd061c9e783df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281672/7551054c-f6b3-2499-71e0-d3ecb8311a1f.png">
これでapacheはOK。


##hello world！！
お約束ですね、動作確認のためやりましょう！
本来ならconfigファイルを確認したほうがいいかもしれませんが別の機会に回します。

初期設定としてapacheは/var/www/html内のファイルを最初に読むようになっています。そこにphpファイルを作成しついでphpの動作確認をするとしましょう。


```
$ sudo vim /var/www/html/index.php
```

```index.php
<?php echo'hello world!!';
echo phpinfo() ?>

```
下のようになっていればOK!ようこそ,PHPの世界へ・・

<img width="791" alt="b6dbc1b4d545b8d6591521809102ccba.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281672/246af0fb-fab4-be35-3647-c646faf88d6c.png">


はい！ということで必要最小限の設定はできたかと思います。本当はDBも入れようと思ったんですがec2の方はどうも勝手が違うようで(RDSあるから？)それ確認してからにします。
次回もどんどん機能を足していきましょう！

##参考文献
[ PHP + Apacheのインストール - Linux環境 - CentOS](https://webkaru.net/php/apache-php-centos/)
タブローで地図情報を扱う時

# 目的
BigQueryにある緯度経度情報をTableauで可視化したい

# 問題
緯度経度情報（GEO系）をBigqueryでPOINTとかに変換してもTableauで文字列としてしか認識してくれない
# 解決方法
・python でshapeファイルに変換（geojsonとかでもなんでもいいと思う）

# サンプルコード
```python3
import csv
import shapefile

w = shapefile.Writer("../data/point", shapeType=shapefile.POINT)

w.field("id", "C", "40")
w.field("date", "C", "40")
w.field("price", "C", "40")
w.field("flg", "C", "40")

with open("../data/___.csv") as text:
    reader = csv.DictReader(text)
    for row in reader:
        w.record(str(row['id']), str(row['date']), str(row['price']), str(row['flg']))
        w.point(float(row['longitude']), float(row['latitude']))

w.close()
```
RxのFlatMapをサクッと理解する

**RxのFlatMap**について、理解するまでちょっと戸惑ったので忘備録。

### FlatMapとは

[公式](http://reactivex.io/documentation/operators/flatmap.html)に書いてあることをまとめると以下のようになります。

1. observableに送られてきた値の一つ一つに対し、その値を元に新たなobservableを作成する関数を当てる
2. 上で作成された複数のobservableを一つのobservableにマージする

#### 1. observableに送られてきた値の一つ一つに対し、その値を元に新たなobservableを作成する関数を当てる

例えば以下のobservableがある時、

```javascript
const originalObservable =  Rx.Observable.of(1, 2, 3);
```
`originalObservable`に送られた3つの**それぞれの値から更にobservaleを作る**ような以下の関数を用意します。

```javascript
const getNewObservable = (value) => {
    return Rx.Observable.of(value+ "A", value+ "B", value+ "C"); 
}
```
これにより、以下のような三つのobservableが作られます。

1. Rx.Observable.of("1A", "1B", "1C") <= 1が送られてきた時
2. Rx.Observable.of("2A", "2B", "2C") <= 2が送られてきた時
3. Rx.Observable.of("3A", "3B", "3C") <= 3が送られてきた時

#### 2. 作成された複数のobservableを一つのobservableにマージする

上記で作成された複数のobservableを一つのobservableにマージした時に送られてきた値は以下のようになります

```console
"1A"
"1B"
"2A"
"1C"
"2B"
"3A"
"2C"
"3B"
"3C"
```

全体の検証コードは以下のようになります

```javascript
const originalObservable =  Rx.Observable.of(1, 2, 3);

const getNewObservable = (value) => {
    return Rx.Observable.of(value+ "A", value+ "B", value+ "C"); 
}

const flatMapped = originalObservable
  .flatMap(getNewObservable);

function test() {
  flatMapped.subscribe(val => {
    console.log(val);
  });
}
```

[CodePenはここから](https://codepen.io/nichiyoshi/pen/WVboOd)
plunkerでvue その2

#概要

plunkerでvueやってみた。
bootstrapvueやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e212cae8-8dc0-9495-71f7-60ff5270d1ae.png)


#成果物

https://embed.plnkr.co/DfMZyuLV33akLIUYapig/

以上。
plunkerでvue

#概要

plunkerでvueやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/72413427-6ab4-9d93-381e-3f8703100c70.png)

#成果物

https://embed.plnkr.co/BTCGOOTcMPL8w1q4o46C/

以上。
PostgreSQLのデータベース操作

postgreSQLを起動させて基本的なデータベース操作をささっと。

※行頭が**psql外では`$`**、**psql内では`#`**でコマンドを記述してある


##データベースの新規作成/削除

###DB作成
psql外で行う場合

```
$ createdb <DB name>
```

psql内で行う場合

```
# create database <DB name>;
```


###DB削除

psql外で行う場合

```
$ dropdb <DB name>
```


psql内で行う場合

```
# drop database <DB name>;
```



##DB一覧を表示

psql外で行う場合

```
$ psql -l
```

psql内で行う場合

```
$ \l
```




##データベースに入る/出る/切り替え

###DB入

様々な指定をして入ることが可能だが、少なくともこの2つだけは忘れないようにする。

```
#DB名のみを指定して入る
$ psql <DB name>

#DB名とユーザー名を指定して入る
$ psql -U <User name> <DB name>
```

###DB出

MySQLには`exit;`しかないがpostgreSQLには2つある。どちらでも動く。`;`は不要

```
# \q

# exit
```



###DB切り替え

切り替えはpsql内で行う。以下のどちらでも動作する。`;`は不要

```
# \c <DB name>

# \connect <DB name>
```



##挙動
DB操作の一通りの挙動を示す



```text:terminal
sf213471118:postgres sf213471118$ psql -l                  /* 最初の状態　 */
                             List of databases
   Name    |    Owner    | Encoding | Collate | Ctype |   Access privileges   
-----------+-------------+----------+---------+-------+-----------------------
 postgres  | sf213471118 | UTF8     | C       | C     | 
 template0 | sf213471118 | UTF8     | C       | C     | =c/ sf213471118     +
           |             |          |         |       | sf213471118=CTc/ sf213471118
 template1 | sf213471118 | UTF8     | C       | C     | =c/ sf213471118     +
           |             |          |         |       | sf213471118=CTc/sf213471118
(3 rows)
sf213471118:postgres sf213471118$ createdb hogeDB           /* hogeDB作成  */
sf213471118:postgres sf213471118$ psql -U aa291336 hogeDB   /* hogeDB入  */
psql (11.4)
Type "help" for help.
hogeDB=# \connect postgres                                  /* postgresに切替 */
You are now connected to database "postgres" as user "sf213471118".
postgres=# drop database "hogeDB";                          /* hogeDB削除 */
DROP DATABASE
postgres=# \q                                               /* postgres出 */
```
以上のように動く。


##DB内の文字の扱いについて

上記の挙動におけるhogeDB削除の部分に関しては、`""`で括らないと

```
postgres=# drop database hogeDB;
2019-07-19 15:32:41.280 JST [57231] ERROR:  database "hogedb" does not exist
2019-07-19 15:32:41.280 JST [57231] STATEMENT:  drop database hogeDB;
ERROR:  database "hogedb" does not exist
```
のようにエラーを吐く。このエラーは `hogeDB `が大文字を含むことから発生している。

データベースは二重引用符を使用して作成されているため、大文字/小文字は区別される。

そのため参照するときは二重引用符`""`を使用する必要がある。

このことから纏めると

+ psql外（DB外）
    - `dropdb hogeDB`  --> 通る
    - `dropdb "hogeDB"` --> 通る
+ psql内（DB内）
    - `drop database hogeDB` --> 通らない
    - `drop database "hogeDB"` --> 通る



`createdb`/`create database`に関しては両方とも参照は必要ないため`""`で括る必要はない。
SharePointに、メールを受信できないゲストユーザーを招待する

SharePointやTeamsのファイル共有は便利。外部のユーザーを招待すればさらに便利。(組織によっては制限があるけど)

前回は、[G Suiteユーザーを招待する](https://qiita.com/hisssa0102/items/a74fd4114fd17a408d03)手順をまとめた。
今回は相手側の組織の都合でメールが受信できないユーザー(たとえば、組織がからのメールを受信できないポリシーを適用されている、など)を招待する手順をまとめてみた。

おもな流れはこんな感じ。

・招待する側が、招待する。
・招待された側が、あるURLを開く
・サイトにアクセスする。


#招待する側が、招待する。

通常の手順で、共有操作を行う。いつも通り、招待する側のアカウントにメールが届く。

招待される側にはメールが送られるのだけど、受信できないので、当然メールボックスには届かない。招待する側のメールボックスには先方に届かなかったというエラー通知もこない。

でも、招待したという処理はされてる。

#招待された側が、あるURLを開く

招待する側テナントのドメインが、contoso.comの場合だと

https://portal.azure.com/contoso.com


招待を受けた側に365にログインした状態で、このアドレスを開いてもらう。

Azureポータルの画面が表示されて驚くけど、これでOK。




通知メールを送った場合は、メールのリンクを開いて、承諾する必要がある。この手順だと承諾された状態にもうなってる。


#SharePointサイトのURLを開いてもらう

もう承諾済み=AzureADのゲストユーザーとして登録された状態、かつサイトへのアクセス権も付与済み。

そのまま使ってもらいましょう。


#まとめ

開いてほしいアドレスをどう伝えるか、という問題はありつつだけど、相手がたとえメールを受け取れなくても共有きるのは、レアケースだけど使いどころはあるんじゃないかな。
tensorflow.jsでchart.js

#概要

tensorflow.jsでchart.jsやってみた。

#参考にしたページ

https://qiita.com/oyenakaw/items/b05b4045b2ef6540b2ce

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/48855b3e-c022-3957-6d53-bbe080061a3d.png)



#成果物

https://embed.plnkr.co/QlqNjpb8EiAIEvPvK2Wj/

以上。
Macの画面を一瞬でロック/スクリーンセーバにする方法

セキュリティ的な面から『パソコンの画面をそのままにして離席をする』ということはなるべく避けたほうがよいです。

とはいえ、離席をするたびに画面のロック操作をするのは面倒です。そこで今回は一瞬で画面をロック/スクリーンセーバにする方法を共有します。

なお、対象はMacとなっております。

## ショートカットキーで画面ロックを行う
Macの画面ロックのショートカットキーは『command + ctrl + q』となっています。
![c3ddf02c-9555-de91-c45c-b803e68a2831.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/21250418-d100-40b1-402c-bf96562ea5e5.png)



ショートカットキーは初めこそ覚えるのが大変ですが、覚えてしまえば本当に楽です。


## ホットコーナーを活用する
Macには、画面端にカーソルを移動させることで特定のアクションを呼び出すという、ホットコーナーと呼ばれる機能があります。

ホットコーナーを活用することで画面ロック/スクリーンセーバが一瞬で呼び出せます。

ホットコーナーは『システム環境設定』→『デスクトップとスクリーンセーバ』→『ホットコーナー』から設定可能です。
![d821d1b2-a20f-5335-9f40-1614a43af07b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/58e39c62-df8e-e109-8499-68751d896b04.png)



![3267d308-4e89-bfa7-3a05-6350bc158a67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/0eb4004e-2bd3-0bd5-ed5a-af29c60eb9b5.png)



自分の場合は左下にカーソルを移動させるとスクリーンセーバが起動するようにしています。
![36080242-7c50-b291-ec82-7d13dbabadaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/384dc939-ea26-7e63-005d-392b65926b62.png)



ちなみに、Macのスクリーンセーバは『[Aerial](https://github.com/JohnCoates/Aerial)』というApple TVの空撮をスクリーンセーバとして利用できるツールがキレイでオススメです。
![c0e1cc4c-7c95-11e5-9d3b-842d3acc2fd5-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/b86324c6-e2bf-cf12-5719-68217b6bf78c.gif)
ArduinoでOSを作る

### 概要
Arduino Unoを使ってOSを作ろうという話です．以下の手順で進めていきます．

### 手順
1. [GDBで動作確認](https://qiita.com/hiro4669/items/01f9f0f3d480b471ce0b)
1. [LED点灯](https://qiita.com/hiro4669/items/56099dd9adfd9e7b5a39)
1. [シリアルの設定](https://qiita.com/hiro4669/items/aa82f379abffc7f09e6b)
1. [タイマー割り込み](https://qiita.com/hiro4669/items/00b9d60cf8e1f6320acc)
1. [putsの実装](https://qiita.com/hiro4669/items/c871f389e09749fd8f1e)
1. [タイマー割り込み(再)](https://qiita.com/hiro4669/items/f48835d8178176953660)
1. [スレッドの実装](https://qiita.com/hiro4669/items/cceb2090efa9b15043fe)
1. [LED点滅](https://qiita.com/hiro4669/items/a469b649cb7b3284815e)

### 参考
・[ArduinoUnoのブートシーケンス](https://qiita.com/hiro4669/items/933bb0881c82f0dc2bdd)
・[AVRの開発環境を整える](https://qiita.com/hiro4669/items/d46503d9b2a3b050c864)
Edge TPUパフォーマンスベンチマーク

個々のEdge TPUは、各TOPSに0.5ワット（ワットあたり2 TOPS）を使用して、1秒間に4兆回の操作（テラ操作）を実行できます。 それがアプリケーションのパフォーマンスにどのように変換されるかは、さまざまな要因によって異なります。 すべてのニューラルネットワークモデルにはそれぞれ異なる要求があり、USB Acceleratorデバイスを使用している場合、全体のパフォーマンスもホストCPU、USB速度、およびその他のシステムリソースによって異なります。
<img width="NaN" alt="google-coral-ai-iot-products.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/c8933f2e-d681-0e1d-1fb5-5bc8a3ec4a7b.jpeg">

購入代理店：https://store.gravitylink.com


そうは言っても、以下の表1は、Edge TPUでいくつかの一般的なモデルと単一の推論を実行するのに費やされた時間を比較したものです。

これは、Edge TPUと互換性のある少数のモデルアーキテクチャを表しています（これらはすべて、1,000クラスのImageNetデータセットを使用してトレーニングされています）。 自分のモデルをテストしたい場合は、モデルアーキテクチャーの要件を読んでください。

>注：これらの数値は、モデルの実行に必要な時間のみを測定しています。 入力データを処理する時間（入力テンソルに合わせて画像を縮小するなど）は含まれません。これはシステムとアプリケーションによって異なります。 これらのテストもC ++ベンチマークテストを使用して実行されますが、私たちのパブリックPythonベンチマークスクリプトはPythonからのオーバーヘッドのために遅くなるかもしれません。

##### 1.推論あたりの時間、ミリ秒（ms）

![微信截图_20190719144541.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/58c8b540-85b2-681f-1bfc-d5daa54e8131.png)
![微信截图_20190719144556.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/2ba009c4-1a21-0845-e4d3-c40e63a01ee4.png)

1. デスクトップCPU：64ビットIntel（R）Xeon（R）E5-1650 v4 @ 3.60GHz
2. 組込みCPU：クアッドコアCortex-A53 @ 1.5GHz
3. Dev Board：クアッドコアCortex-A53 @ 1.5GHz + Edge TPU
4. 一部の操作はCPU上で実行する必要があるため、パフォーマンスが低下します
5. 
`Edge TPUランタイムのバージョン10ではサポートされていません。 アップデートは近日中に公開される予定です。`
Laravel 5.8 メール

認証機能のうちユーザー登録にメール確認を行うことができるようなので
予めメール送信の設定を行う。
#メール設定
.envファイルかconfig/mail.phpで行う。

```bash
MAIL_DRIVER=smtp
MAIL_HOST=smtp.hoge.com
MAIL_PORT=587
MAIL_USERNAME=hoge.admin@example.com
MAIL_PASSWORD=(パスワード)
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=hoge.admin@example.com
MAIL_FROM_NAME="hoge admin"
```
以下のコマンドでテスト送信。nullが変えればOK。

```powershell
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.20 ? cli) by Justin Hileman
>>> Mail::raw('Test Mail', function($message) { $message->to('hoge@example.com')->subject('TEST Title'); });
=> null
>>> 
```

gmail等の場合、`MAIL_ENCRYPTION=null`を`tls`にする必要があるが環境によっては
PHP Warningとなる。

```powershell
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.20 ? cli) by Justin Hileman
>>> Mail::raw('Test Mail', function($message) { $message->to('hoge@example.com')->subject('TEST Title'); });
PHP Warning:  stream_socket_enable_crypto(): Peer certificate CN=....
>>> 
```

sslの厳密な検証を行うと証明書がドメインに含まれてないからエラーとなっている模様。
以下の設定を追加するとWarningを無視する。

```php:config/mail.php
'stream' => [
   'ssl' => [
       'allow_self_signed' => true,
       'verify_peer' => false,
       'verify_peer_name' => false,
   ],
],
```

参考URL
[How to deal with self-signed TLS certificates in Laravel's SMTP driver?](https://stackoverflow.com/questions/30714229/how-to-deal-with-self-signed-tls-certificates-in-laravels-smtp-driver)
ArduinoUnoのブートシーケンス

### 概要
ArduinoでOSを作るために，ブートローダやメモリ配置，割り込みベクタについて調べたことをまとめておく．ここでは，特に断らない限りArduino Unoについて書いていく

#### ブートローダの振る舞い
Arduinoのブートローダは，ユーザが実装するアプリケーションとは別に存在し，工場出荷時に予めチップ(e.g., atmega328p)に組み込まれている．電源が入る，またはリセットボタンが押されるとこのブートローダが起動し，ブートローダはシリアルを監視する．PCからシリアル経由でプログラムを受け取ると，プログラムの配置情報(リンカスクリプト)に従ってフラッシュに書き込む．その後，0x00番地にジャンプし，アプリケーションを起動する．
一方，ブートローダは一定時間待ってもプログラムが送られてこないと，0x00番地にジャンプして書き込み済みのアプリケーションを起動する．

#### ブートローダの書き込み位置
Arduino Unoのatmeta328pは，16KBのフラッシュメモリと2KBのSRAMを備えている．読み込むだけのプログラムはフラッシュメモリに格納され，読み書きが必要なデータがSRAMに置かれる．フラッシュメモリには，プログラム(ユーザが作成)と，プログラムをロードするブートローダが書き込まれ，どの位置にブートローダを書き込むか(Boot Flash Section)は，ヒューズビットによって変更することができる．
さらに，ヒューズビットは3種類(EFUSE, HFUSE, LFUSE)に分類され，Boot Flash Sectionの位置を決めるのはHFUSEの下位3ビット目，下位2ビット目に当たる，BOOTSZ1, BOOTSZ0であり，それぞれでデフォルト値は(0, 0)である(データシートp349)．これらビットの組み合わせとBoot Flash Sectionのアドレスの対応を下にまとめる

| (BOOTSZ1, BOOTSZ0) | Boot Flash Sectionアドレス |
|-----------:|------------:|
| (1, 1) | 0x3f00 |
| (1, 0) | 0x3e00 |
| (0, 1) | 0x3c00 |
| (0, 0) | 0c3800 |

ここで，デフォルト値が(0, 0)であることから，Boot Flash Sectionのアドレスは0x3800であることがわかる．
ただし，atmega328pは，データシートによるとすべての命令は2倍とで構成される，とあるため実際のアドレスを考えるときには2倍して考えないといけない．よって，書き直すと以下のようになる．

| (BOOTSZ1, BOOTSZ0) | Boot Flash Sectionアドレス |
|-----------:|------------:|
| (1, 1) | 0x7e00 |
| (1, 0) | 0x7c00 |
| (0, 1) | 0x7800 |
| (0, 0) | 0c7000 |

よって，開始位置は0x7000である．


#### リセットベクタ/割り込みベクタ
リセットベクタとは，電源が入ったとき，もしくはリセットボタンが押された時にMCUが実行を開始するアドレスのことを指す．また，割り込みベクタとは，各種割り込みが入ったときの割り込みベクタを配置するべき開始アドレスを指す．リセットベクタと割り込みベクタはあるビットを操作することによって変更可能になっている．リセットベクタの位置を決めるのはBOOTRSTで，これは前述のHFUSEの最下位ビットに相当する．また，割り込みベクタの位置を決めるのはIVSELで，これはMCUCRレジスタの下位2ビット目のことを指す．
BOOTRSTが1の場合，リセットベクタは0x00に配置され，0の場合Boot Flash Addressの先頭番地に配置される．電源が入ったとき，もしくはリセットボタンが押されたときには常にブートローダから起動してほしいので，BOOTRSTは0で有ることが望ましい(ただし，BOOTRSTのデフォルト値は1)．一方，IVSELが0のとき，リセットベクタは0x002に配置され，1のときにはリセットアドレス+0x0002に配置される．つまり，0のときは固定で0x002番地，1のときにはリセットのアドレスに続くアドレスに配置される(1命令が2バイトで構成されるため，続くアドレスとは2バイトずれる)．
よって，ブートローダが起動しているときには，割り込みベクタはブートローダが用意した割り込みベクタを使えたほうが都合が良いので，IVSELの値は1のほうが良い(そして恐らく，リセットされるとハードウェアでIVSELは強制的に1になる)．
一方，アプリケーション(e.g., OS)は0番地から配置され，起動したあとは独自の割り込みハンドラを設定したい．そのため，アプリケーション実行直後の初期化処理などで，IVSELを0にし，割り込みベクタの位置を0x002にする．

![Screen Shot 2021-03-02 at 8.38.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57629/1c0e9ba2-a9f9-8558-1cee-58e341cbdff8.png)


#### Arduino Unoのブートローダ設定
Arduinoのブートローダは，0x7800に書き込まれている．これは，Arduino IDEをインストールした時に一緒に入る，"/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/bootloaders/atmega/Makefile"を見ると，以下の行によって確認できる．

```
atmega328: LDSECTION  = --section-start=.text=0x7800
```
しかし，一方でブートローダの書き込み位置を決めるBOOTSZ1, BOOTSZ0のでデフォルト値は0, 0であった．この場合，Boot Flash Secitonのアドレスは0x7000で，仮にBOOTRSTの値が0でも辻褄が合わなくなる．
そこで，このMakefileを見ると，以下の設定が見つかる．

```
atmega328_isp: HFUSE = DA
atmega328_isp: LFUSE = FF
atmega328_isp: EFUSE = 05
```
このように，HFUSE = DAとなっているDA = 1101 1010なので，下位3ビットを見ると(0, 1, 0)となる，つまり，(BOOTSZ1, BOOTSZ0) = (0, 1)となるので，Boot Flash Secitonのアドレスは0x7800で，BOOTRSTも0である．つまり，ブートローダを書き込む時にヒューズビットも変更することで，この動作を実現している．
コマンドプロンプト上で「'DOSKEY' は、内部コマンドまたは...」なるエラーの対処法

# はじめに

コマンドプロンプトを開いたときにエラーが出ましたが、ググっても日本語の情報が出てこなかったので残しておきます。

# コマンドプロンプトを開いたときのエラー

`'DOSKEY' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。`
と表示されます。

# 対処法

Pathに追加をします。
`コントロールパネル->システムとセキュリティ->システムの詳細設定->環境変数`
ウインドウの上の方にあるユーザー環境変数の`Path`をダブルクリック。
`環境変数名の編集`ウィンドウが表示されたら、右にある`新規`を選択し、
`C:\Windows\System32\`を記載して保存。(\\(バックスラッシュ)は&yen;(円マーク)に置き換えてください)
コマンドプロンプトを開き直せば消えていると思います。

# 原因

新しい開発環境を整えているときに誤ってインストーラを落としたことが原因でしょうか...
エラーは精神衛生上よろしくないので、とりあえず対処です。
JFreeChart-DateAxis


目次 ⇒ [JFreeChartサンプル](https://qiita.com/artery/items/3e9c63e5c14a9e965c97)

```java
package jp.avaj.lib.chart;

import java.util.Random;

import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.DateTickUnitType;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;

import jp.avaj.lib.algo.ArDate;

/**
■ JFreeChart-DateAxis
・X値は日時のデータで、その基底クラスはRegularTimePeriod.
・DatasetはTimeSeriesCollectionなどを使用する.注、名称がDatasetではないが、Datasetを実装.

 */
public class Chart18_11 {
  // 目次-時系列データの表示.
  A_Chart15 a_Chart15;
  // 目次-Artery-JFreeChart用のライブラリ
  A_Chart00 a_LibChartSampeContents;

  public static void main(String[] args) {
    // 表示データを作成する
    TimeSeriesCollection ds = createData();
    // レンダラ
    // 最初の引数はラインを引くかどうか⇒今回はラインは引く
    // 次の引数はデータの場所に形を表示するか否か⇒今回は形を表示する.
    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true,true);
    // X軸はDateAxis
    DateAxis xAxis = new DateAxis();
    // 軸の表示単位を設定する,1は一日単位の意味,2にすれば二日ごとに表示する.
    xAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY,1));
    NumberAxis yAxis = new NumberAxis();
    // Plotを作成してチャートを表示する
    XYPlot xyPlot = new XYPlot(ds,xAxis,yAxis,(XYItemRenderer)renderer);
    JFreeChart jfreeChart = new JFreeChart("売上推移",(Plot)xyPlot);
    ChartFrame cFrame = new ChartFrame("売上推移",(JFreeChart)jfreeChart);  // (1)
    cFrame.pack();
    cFrame.setVisible(true);
  }
  // 表示データを作成する
  private static TimeSeriesCollection createData() {
    // 商品名の定義
    final String[] items = new String[]{"A","B","C"};
    // 最初の日
    final ArDate startDate = new ArDate(2030,7,1);
    Random ran = new Random();
    TimeSeriesCollection ds = new TimeSeriesCollection();
    for (int item=0; item<items.length; item++) {
      ArDate arDate = (ArDate)startDate.clone();
      // 商品名でTimeSeriesを作成する
      TimeSeries series = new TimeSeries(items[item]);
      for (int day=0; day<5; day++) {
        // 日付をRegularTimePeriodに変換する,RegularTimePeriodの派生クラスはいろいろある.
        Day date = ArcDay.fromArDate(arDate); // DateやCalendarやlongでも可能
        // 売上 ⇒ サンプルなので適当.
        int sales = item*10+ran.nextInt(10);
        // 売上データを作成してSeriesに追加する
        TimeSeriesDataItem dataItem = new TimeSeriesDataItem(date,sales);
        series.add(dataItem);
        // 次の日
        arDate.forward(1);
      }
      // TimeSeriesをTimeSeriesCollectionに追加.
      ds.addSeries(series);
    }
    return ds;
  }
}

```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/7c50d93e-6e38-aca9-505e-1c0ef98a0085.png)
redashのCounter設定がわかりにくいのでメモ

redashの `Visualization Editor` ではグラフの他にCounterという数値や
その数値の比較数値のみを表示させる形式があるが、このCounter用途のクエリ作成時の注意点と
Counter作成時の設定方法は忘れやすいためメモしておく。

やりたいこと
・レコードの行数を指定し、表示する小数点第何位かまでを指定する

ますは結果table用のクエリを作成する。

```
select
    整数,小数点一位,小数点二位
from (
    select
        2 as 整数
        ,0.2 as 小数点一位
        ,0.02 as 小数点二位
    
    union

    select
        3 as 整数
        ,0.3 as 小数点一位
        ,0.03 as 小数点二位
) as row
;
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386370/a0500c0f-95af-cc18-d15e-7296565566a4.png)

Counterクエリ作成時の注意点は
グラフ用クエリとは違い、列はあくまでも表示する指標としての意味合いしか持たないということ。
グラフ用のクエリは何ごとに何を集計するか細かく設計してからではないとうまいことグラフにできないが
Counterは「このカラムだったら何行目のデータを表示したい」という考え方でクエリを作成すること。
そのため、行数が多いほどCounter作成はめんどくさくなり、編集する際の可読性は悪いため
なるべくほしいデータは横並びにして作成することをお勧めする。


では、次に `0.30` のデータのあるセルのみをCounterにする。

Visualization編集画面での設定は以下となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386370/36991363-01cd-a66a-f850-61c8504f438a.png)

 `Counter Value Row Number` で何行目のデータがにするかを指定。
今回は結果の2行目である `0.3` を表示。

今回は `0.3` ではなく `0.30` の小数点第二位まで表示したい場合は
Formatで `Formatting Decimal Place` の数字を2にすればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386370/9921ac68-210e-4788-0a1f-e53be1a8e11f.png)
C言語のunsigned short intとunsigned long intの足し算

gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0を利用していたときに起きた出来事です。
型変換を明示してやらないと変な結果になりました。

# 失敗するコード
```C
#include <stdio.h> //printf(), perror()

int main(int argc, char** argv){
  unsigned long int x=0;
  printf("%lu\n",x);
  for(int i=0;i<1000000;i++){
    unsigned short int y=50000;
    if(i<10){
      printf("%d %lu\n",i,x);
    }
    x+=y*y;
  }
  printf("%lu\n",x);
}

```

結果は

```
0
0 0
1 18446744071914584320
2 18446744070119617024
3 18446744068324649728
4 18446744066529682432
5 18446744064734715136
6 18446744062939747840
7 18446744061144780544
8 18446744059349813248
9 18446744057554845952
18444949106413551616
```

# 成功するコード
```C
#include <stdio.h> //printf(), perror()

int main(int argc, char** argv){
  unsigned long int x=0;
  printf("%lu\n",x);
  for(int i=0;i<1000000;i++){
    unsigned short int y=50000;
    if(i<10){
      printf("%d %lu\n",i,x);
    }
    x+=(unsigned long int)y*y;
  }
  printf("%lu\n",x);
}
```

結果は

```
0
0 0
1 2500000000
2 5000000000
3 7500000000
4 10000000000
5 12500000000
6 15000000000
7 17500000000
8 20000000000
9 22500000000
2500000000000000
```

自動型変換に頼ってばかりいて落とし穴にハマりました。
PostgreSQLのクエリを静的チェックする



PostgreSQLをつかってたり、あるいはAWS Redshiftを利用している場合、クエリのチェックをしたい時がある。

[pgsanity](https://github.com/markdrago/pgsanity) を利用すると、クエリが有効であるかを確認できる。

## インストール

```
$ pip install pgsanity
```

[Getting PgSanity](https://github.com/markdrago/pgsanity#getting-pgsanity)

## 動作確認

installすると、`pgsanity`コマンドが利用可能になる。引数として対象のsqlファイルを指定すればいい。

SQLクエリのサンプルを用意していて実行してみる。

```sql:target.sql
select * from hogehoge;
```

上記ファイルを対象として静的チェックするには以下のコマンドで可能だ。

```sh:command1
$ pgsanity target.sql
```

出力がない場合、静的チェックにおいては問題がない。

### 失敗時
ためしに、ファイルを以下のように変更してみる

```sql:target.sql
select * from;
```

すると、`command1`を実行してみると、以下のように結果がでる。

```
line 1: ERROR: syntax error at or near ";"
```

このように、構文のおかしいクエリを検出できる。

## Pythonのテストコードとして利用

`pgsanity` をpythonのアプリのテストコードとして利用することも可能だ。

以下のようにクラスを発行するclassがあるとする。

```py:sample.py
from textwrap import dedent

class Sample():
    def query(self):
        return dedent("""\
            select * from hoge;
        """)

# hoge = Sample()
# print(hoge.query()) -> select * from hoge;
```

これのテストコードは以下のようになる。

```py:test_sample.py
import unittest
from sample import Sample
from pgsanity import pgsanity

class TestSample(unittest.TestCase):
    def test_query(self):
        hoge = Sample()
        result, message = pgsanity.check_string(hoge.query())
        self.assertTrue(result, 'failed:' + message)
```

実行してみる

```sh
$ python -m unittest discover -v
```

結果

```
test_query (test_sample.TestSample) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.010s

OK
```
office365のグループの配信メンバー一覧をサクッと取得したい

「Aさんが受け取ってるメールリスト、全部俺も受け取れるようにしといて」
すごい簡単に言うじゃん…やるけど…

## とりあえずグループがわかれば良い人向け
1. Exchange管理センター
2. 受信者
3. グループ
4. 「…」
5. データをCSVファイルにエクスポート


## 配信メンバー一覧をPowerShellで取得する

### Powershellからoffice365へ接続できるようにする下準備
#### Microsoft Online Services サインイン アシスタントの導入
[DLして叩いてインストールする](https://www.microsoft.com/ja-jp/download/details.aspx?id=41950)

#### Windows Azure Active Directory モジュールを導入する
powershellを管理者権限で起動して以下を実行。

```
Install-Module -Name AzureADPreview
```
信頼されていないリポジトリからモジュールをインストールするようにメッセージが表示されたら、「Y」と入力し、Enter を押す。


+ 「Install-Module」が使えないエラーが出る
    + [「Windows Management Framework」](https://www.microsoft.com/en-us/download/details.aspx?id=54616)が入ってなさそうなのでインストールしてくること
        + この導入は以下条件を満たしていないと失敗します
            + インストール可能なOSであること
            + .NET Framework 4.5以上がインストールされていること
            + WMF 3.0がインストールされていないこと

### powershellからoffice365に接続する

#### powershellでのスクリプト実行を許可する
```
Set-ExecutionPolicy RemoteSigned
```

#### office365へ接続する情報を指定する
以下を実行すると権限情報入力ダイアログが出現します。
管理者権限を持つユーザーIDとパスワードを入力してください。

```
$UserCredential = Get-Credential
```

※Enterを押すとすぐに確定扱いされて、「あぁパスワードの入力がまだなのに…」ということになります。
※最後に入力した情報が保持されるので、何回失敗しても平気

#### Sessionの確立
権限情報が間違っているとこの実行でエラーがでます。
間違っていないと何も出力されずに実行が完了します。

```
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
```

何も起きなければ以下を更に実行

```
Import-PSSession $Session -DisableNameChecking
```

### グループメンバ情報を取得する
ここまでの接続が完了しているならば以下手順へ。

#### 出力する項目情報を定義する

お好きにカスタムしてください。

```
$Temp = foreach ($i in Get-DistributionGroup -ResultSize Unlimited){Get-DistributionGroupMember -Identity $i.PrimarySmtpAddress -ResultSize Unlimited | select @{n="Name";e={$i.Name}},@{n="DistributionGroupName";e={$i.DisplayName}},@{n="Alias";e={$i.Alias}},@{n="DistributionGroupMailAddress";e={$i.PrimarySmtpAddress}},@{n="GroupType";e={$i.GroupType}},@{n="ManagedBy";e={$i.ManagedBy}},@{n="HiddenFromAddressListsEnabled";e={$i.HiddenFromAddressListsEnabled}},DisplayName,PrimarySmtpAddress}
```

#### 定義した情報を出力する

出力先csvのパスは適宜変更すること。

```
$Temp | Export-Csv -Encoding UTF8 -NoTypeInformation -Path "C:\hogehoge\output.csv"
```

一覧が出る！！！嬉しい！！！！


### 忘れずにoffice365接続セッションを切る

```
Remove-PSSession $Session
```

## 共有メールボックスは？？？
うまいこと一覧でとれなかったけど、個別指定ならいける…
共有メールボックスに紐づくユーザ情報は`Get-MailboxPermission`で取れるらしい。

これをtempに指定して先述の出力でOK

### メンバー軸
hogehoge:メンバーのID

```
$Temp = Get-mailboxPermission -ResultSize Unlimited -identity * -User hogehoge
```

### メールボックス軸
hogehogeあっとmailaddres.sample.com：メールボックスのアドレス

```
$Temp = Get-mailboxPermission -ResultSize Unlimited -identity hogehoge@mailaddres.sample.com
```

## 参考にさせて頂いたところ

https://bizlog.tech/exo-gpmem-export/
https://bizlog.tech/powershell-connect-office365/
https://qiita.com/opengl-8080/items/bb0f5e4f1c7ce045cc57
https://docs.microsoft.com/ja-jp/office365/enterprise/powershell/connect-to-office-365-powershell
https://docs.microsoft.com/en-us/powershell/module/exchange/mailboxes/Get-MailboxPermission?view=exchange-ps
【Win】Adobe Illustratorに合成フォント読み込み

調べてもパッとでてこなかったので備忘録。というかGUから読み込めるようにしてほしい。

`C:\Users\ユーザー名\AppData\Roaming\Adobe\Adobe Illustrator 23 Settings\ja_JP\x64\合成フォント\Temp`
配下に入れる。

Adobe Illustrator [バージョン] Settings
【JavaScript】要素の取得方法(getElement、querySelector)

#はじめに
JavaScriptにおいて、HTMLの要素を取得するには様々な方法があります！
今回はその要素の取得方法に関してまとめました！

#ID名を指定して要素を取得するメソッド
##document.getElementById()
`document.getElementById()`は引数にID名を入れることで、そのIDの要素を取得することができます。
同じID名が複数存在する場合には最初の要素のみを取得します。
以下が簡単な例です。
htmlの`id='sample'`のdiv要素を、jsファイルにて取得して、定数sampleに代入しています。

```test.html
<div id='sample'></div>
```

```test.js
const sample = document.getElementById('sample')
```
#class名を指定して要素を取得するメソッド
##document.getElementsByClassName()
先ほどの`document.getElementById()`ではID名から要素を取得しましたが、
`document.getElementsByClassName()`ではクラス名を指定して要素を取得できます。
こちらの場合は、該当する複数の要素を取得することが出来ます！
以下が例です。

```test.html
<div class='sample'></div>
```

```test.js
const sample = document.getElementsByClassName('sample')
```
#ID名とclass名どちらを入れても要素を取得出来るメソッド
## document.querySelector()
こちらも引数にID名やクラス名を入れることで、要素を取得することができます！
先ほどの`getElementById()`や`getElementsByClassName()`では、それぞれID名かクラス名どちらかしか指定できませんでした。
しかし`document.querySelector()`ではID名もクラス名も両方指定できます！
しかし例えばID名sampleを指定したい場合、先ほどの`document.getElementById()`とは違って、引数には`#sample`と書かなければなりません。
クラス名の場合も同様で`.sample`と書きます！
CSSでセレクタを記述する際と同じ書き方です。
`document.getElementById()`と同じように引数内を`'sample'`と書いてしまうと、ID名を指しているのかクラス名を指しているのかわかりません。
以下が例です。

```test.js
const sample = document.querySelector('#sample')
```

##document.querySelectorAll()
`document.querySelector()`の場合は、取得出来る要素はひとつのみでしたが、`document.querySelectorAll()`を使用すると、引数で指定したID名、もしくはクラス名と一致する全ての要素を取得することができます。
以下が例です。

```test.html
<div class="hoge"></div>
<div class="foo"></div>
<div class="hoge"></div>
```

```test.js
const hoge = document.querySelectorAll('.hoge')
```

３つ並んでいるdiv要素のうち、１番目と３番目の要素が取得できます。

#余談①
今回は全て、documentから要素を探しました。
(document.querySelectorやdocument.getElementsByClassName等)
しかし、documentではなくelementを指定して要素を取得することもできます。
以下が例です。

```test.html
<ul class="hoge">
  <li class="foo"></li>
  <li></li>
  <li></li>
</ul>

```

```test.js
const sample = hoge.getElementsByClassName('foo')
```

上記の例では、hogeクラスの中にある、fooクラスの要素を取得しています。

#余談②
特定のIDもしくはクラス名を指定して、一つの要素を取得したい場合。
`getElementBy`と`querySelector`どちらを使用するべきなのでしょうか。
基本どちらでも良いのですが、
`getElementBy`の方が`querySelector`よりも速度が早いらしいです。
でも人がわからないレベルらしい。。
少しでも早くしたいって方は`getElementBy`を使った方が良いかも？？

#さいごに
今回はID名やクラス名を指定しての取得の仕方のみ解説しましたが、他にもタグ名を指定して取得する方法などがあります。
以下の記事がとても詳しいので、深掘りしたい方にはおすすめです！
https://qiita.com/amamamaou/items/25e8b4e1b41c8d3211f4
GCP KMSで文字暗号化／複合化

公式のドキュメントはファイルを暗号化／複合化する方法しかありませんので、短い文字列（パスワードなど）の暗号化／複合化方法を記載します。

Linux環境が必要ですが、Cloud Shellで実行しても問題ありません。

## 暗号化
五つ変数値を適切な値に変更し、コピペで実行する

```sh
export TARGET_VALUE=1234567890
export PROJECT_ID=project-xxxx
export KEYRING_LOCATION=global
export KEYRING_NAME=keyring-name
export KEY_NAME=api-key

echo -n ${TARGET_VALUE} \
| gcloud kms encrypt \
  --project ${PROJECT_ID} \
  --plaintext-file=- \
  --ciphertext-file=- \
  --location=${KEYRING_LOCATION} \
  --keyring=${KEYRING_NAME} \
  --key=${KEY_NAME} \
| base64 -w 0
```
```sh
実行結果：
CiQA+lBo1CitnyMsruff02M8vtkYj8hNeqvlrWUb6+tv6RIaFXYSMwAWnQXqyTD+IF10De7/w8vUcvHQKnAxF8yTeoJr/OB25ps4DIi2Ou9BF6nh4a7kL9cw+A==
```

## 複合化
五つ変数値を適切な値に変更し、コピペで実行する

```
export TARGET_VALUE=XXXXXXXXXXXXXXXXXXXXX
export PROJECT_ID=virtual-assistant-xxxxxxx
export KEYRING_LOCATION=asia-northeast1
export KEYRING_NAME=keyring-envs
export KEY_NAME=api-key

echo -n ${TARGET_VALUE} \
| base64 -d \
| gcloud kms decrypt \
--project ${PROJECT_ID} \
--plaintext-file=- \
--ciphertext-file=- \
--location=${KEYRING_LOCATION} \
--keyring=${KEYRING_NAME} \
--key=${KEY_NAME}
```

```
実行結果：
1234567890
```
Amazonで買った時のGmailを自動で既読にする

#Why to make
先日のAmazonプライムデーで買い過ぎました。数十件のGmailの通知が...
1件1件ポチポチと既読つけ、アーカイブ...もうめんどくさい！
※誰かに購入された時に気付かない可能性もあるので、やるなら自己責任でお願いします。

#How to make
[GoogleAppsScriptページ](https://script.google.com/home/)開いて、以下ソースコードをコピペ。認証して、トリガーを1分ごとに。必ず入ってる、にっくき"ご注文の確認"を含む未読メールをアーカイブして、既読をつけてます。

```.js
function getMail(){

  var FindSubject =  '(is:unread + "ご注文の確認")';
  var myThreads = GmailApp.search(FindSubject, 0, 5);
  var myMessages = GmailApp.getMessagesForThreads(myThreads);
  GmailApp.moveThreadsToArchive(myThreads);

  for(var i in myMessages){
      myMessages[i][0].markRead();
  }
}
```