OmniAICreator/Qiita-1.07M huggingface dataset:
GameServerServicesで魔法石を実装するv2

https://github.com/gs2io/gs2-sample/tree/master/unity/money

のほぼ丸パクリです。

リファレンス読んでも全然実装の仕方わからんやんけ！って萎えてしばらくなやんでいたらサンプル落ちてるやん！みたいになってしまったので置いておきます。課金を実装する手段を検討するときにでも参照してください。

1. ダウンロードしてUnityプロジェクトを開く
2. とりあえずデータベース変えるかと言われたのでYesを選択した後、手元で最新のUnityでよみこんだらいっぱいエラーが出ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/540243d4-9f0a-b926-12c8-90e81843340c.png)
3. プロジェクトを開きなおしたりIn-app Purchasingを有効にしたりとかいろいろしてエラーを取ります（importが裏で走るみたいな罠にご注意）
4. GS2Consoleを立ち上げてDeployに移動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/8f2e99c4-c879-2311-eebd-e73c8e102c52.png)
5. テンプレートを読み込ませてリソースを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/909cc158-b585-ec82-73af-83f42d78424f.png)

そうするとこのようなアウトプットが出力されます。
![スクリーンショット (129).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/9f9a58cb-dd20-1eb3-0f88-3876bd5c5619.png)

6. サンプルプロジェクトのRunシーンを開きアウトプットの出力を入れます(普通にコピペすると最後に空白が入ってバグるので注意)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/bdb667c9-782a-bc99-3af8-09db0986f30e.png)

7. Scene起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/91033155-a790-378b-f479-745e3848ded8.png)

8. アカウント作成(ボタン押すだけ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/a70f2e89-6c09-df2d-8542-ddc413202a64.png)

9. ログイン(Loginをクリック)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/66c32cf7-bc76-782e-1e4e-beae9c5ff85d.png)

10. なんか出てくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/dfb45b4e-1064-9e93-6ef3-37ff3c3b9e36.png)

11. ここで＋をおしたら商品一覧が～



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/a143a022-5610-cdd4-f78e-eb026c2b4cd6.png)

＿人人人人人＿
＞　出ない　＜
￣Y^Y^Y^Y^Y^￣



ごちゃごちゃやると……(長いので割愛)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/d846883e-d3d0-c7db-3d7e-916c07ffcb9f.png)

でてきた！（スクショの順番待ちがえてGemsがふえてます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/79111bba-a8d8-0c4b-642f-4177fcc93ed6.png)

無事Gemsも増えています。

~~このバグはサンプルでのバグであり、sdkやサービスの問題ではありません。Prefabがスクリプトで子オブジェクトに参照を持つときに、その子オブジェクトがPrefab化されていないと動かないという問題で動きません。手っ取り早く試したい方はこちらを試してください~~
~~https://github.com/piffett/gs2-sample~~

マージされたのでいまはちゃんと動くと思います
今!!流行りのSTUDIOでポートフォリオサイトをNoCodeで作り直してみた


# STUDIOとは

**「コードを書かずに、Webサイト制作を完結」** できるという国産デザインツール。

![FireShot Capture 017 - STUDIO - コードを書かずに、Webサイト制作を完結。 - studio.design.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/59f42be6-e530-07e8-7c14-741b4bb5469e.png)


「デザインの後のコーディング作業や、サーバーのセットアップは必要ありません。」
「[STUDIO](https://studio.design/ja)でデザインした画面は、瞬時にコードに変換されそのまま公開が可能です。」
という素晴らしさ！！

そして弊社[no plan inc.](https://noplan-inc.com)の案件でもよく使うようになりとても便利に使わせてもらっていました。([no plan株式会社の技術スペック](https://note.com/noplan_inc/n/n5dda25224604)）

# 今回は
[おかむー個人のポートフォリオサイト](https://www.okamu.ro)をSTUDIOに変更することにしました。

# STUDIOを使う前

そういえばSTUDIOを使う前は、HTMLを生成してホスティングしていました。

## フロント

```
gulp
sass
babelify
pug
```

## サーバー

```
Route53
Cloudfront
S3
```

という、よく見る構成ｗ
そろそろ別の技術使いたいなーとも思っていましたが、
ポートフォリオサイトに多くの時間をかけるのももったいないないなぁとも

## STUDIOを使う前で大変だったこと

- 久しぶりに触るとjsが動かないのでしんどい
- おかむー自身HTMLが苦手なので結局、うねうねするアニメーションとかかけてない
- おかむー自身HTMLが苦手なので思ったように配置できない
- レスポンシブ対応もしたくない
- 有料のbootstrap的なやつも買って編集していた

# STUDIOで書き換えた

とりあえず大枠はそのままにしつつ、見にくいところだけ変更する作戦

## 以前の構成も、たった並べるだけ

- あれだけかかってたサイトも数時間でできた
- まじで並べるだけなので超ラク
- テンプレートも充実してて、デザインがおかしくならない
- レスポンシブ対応のテンプレートも充実
- modalや遷移、配置のガイドもわかりやすい！

HTML苦手なので、まじで最高です。



# 作り直したサイト

![FireShot Capture 018 - okamu.ro - 岡室庄悟 - www.okamu.ro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62822/8628f87e-eb2a-e32d-55eb-94e42a996f04.png)

[https://www.okamu.ro](https://www.okamu.ro)

これだけの見かけのサイトを簡単に作成できてしまった!!レスポンシブも完璧(なはずw)
まじで感謝！！


## その他良いところ

- チュートリアルも丁寧でわかりやすい
- svg,gifもいける
- 簡単なモーダルもできる
- idが設定できるので、スムーススクロールも実現できる
- フォームまで用意されていて、指定したメールアドレスに通知される
- 独自ドメインもいける
- Googleアナリティクスもいける
- 将来CMSの導入が予定されている

## 気をつけたほうがいいかもしれない点

- jsのコードは入れれません
- mp4などは入れれませんのでmovieタグがありません
    - 動画はYoutubeとかVimeoのiframeで埋め込みができます
- 戻ると進むが時々バグる
- もちろんgit管理できないので、定期的にページのコピーを取りながらやったりしてました


# もしかしたら役に立つかもしれないTips!
- ヘッダー固定もできる ([no plan inc.](https://noplan-inc.com)で使用)
    - https://help.studio.design/en/articles/2618715-position-fixed-relative-absolute-z-index


- 動画を流す ([ポートフォリオ](https://www.okamu.ro)で使用)
    - iframeだとYoutubeのヘッダーが出てしまったり、Vimeoの有料会員にならないといけなそうだったので、gifに変換して設定
    - [ffmpegでとにかく綺麗なGIFを作りたい](https://qiita.com/yusuga/items/ba7b5c2cac3f2928f040)

# まとめ
- みんな、とりあえず、STUDIO、さわっとこう!!!!!
- できないこともあるので、案件によっては用件を確かめたほうがいい!!!!!
- 学習コストは極めて低いです!!!!!
- 開発速度は極めて早いです!!!!!!!

# 最後に
- もっとTwitterとかでも発信していこうと思っています!!!(宣言駆動開発)
  - Twitter: [@okamu_ro](https://twitter.com/okamu_ro)
UNVT 進捗 20200319

UNVT の Raspberry Pi 実装である Misora については、次の通り進捗しています。

OS Open Zoomstack を搭載した Misora が、電源投入だけでウェブ地図サーバになるような作り込みを完了しました。ここで見つけた工夫は、ウェブ系の技術は Docker の上に実装しなくても、直接 Raspbian の上に実装した方がやりやすいということです。これを「メザニン・アーキテクチャー・パターン」と自分では呼んでいます。

<img width="608" alt="スクリーンショット 2020-03-12 20.54.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/74ce2114-7eb6-108d-40fe-29f4639d9434.png">

いくつかタスクをいただく中で、こなしているうちに次のようなことを考えています。

1. Raspberry Pi の OS イメージそのものを Docker コンテナイメージのように使っていくアプローチをとれば、さらに「部品点数」を減らせるのでやってみる。キーワードは `rake world` であろう。
2. ベースマップ系の並行で動いているタスクがあり、それぞれが全てを共有できるわけでないので、共有できるところを共有するチャンネルをつくる。'vector tile academy' みたいな名前のチャンネルを作れるか考えてみる。
【JavaScript】var,let,const の違い

JavaScriptでは、変数や定数を宣言する際に、var/let/constを使用します。
と言っても使用は必須ではなく、var/let/constを使用せずに変数や定数を宣言できます。

こんな感じです。

```javascript
var a = 'Var';
let b = 'Let';
const c = 'Const';
d = 'Undeclared';
```

それぞれどのような違いがあるのでしょうか？
実際の動作をクイズ形式で確認してみます。

# 目的
var/let/const の違いを理解する

## Q1
エラーとならないのは(a)～(d)のどの変数でしょうか？

```javascript
console.log(a1);  // (a)
console.log(b1);  // (b)
console.log(c1);  // (c)
console.log(d1);  // (d)

var a1 = 'Var';
let b1 = 'Let';
const c1 = 'Const';
d1 = 'Undeclared';
```

正解は…
：
：
：
：
：
(a)！

## Q1解説
`var` は[巻き上げ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var)が発生します。

```javascript
console.log(a1);
var a1 = 'Var';
```

は、

```javascript
var a1;
console.log(a1);
a1 = 'Var';
```

と見なされるので、エラーとはならず(a)は `undefined` が出力されます。
(b)(c)(d)はいずれも `ReferenceError` となります。


## Q2
エラーとならないのは(a)～(d)のどの変数でしょうか？

```javascript
{
    var a2 = 'Var';
    let b2 = 'Let';
    const c2 = 'Const';
    d2 = 'Undeclared';
}

console.log(a2);  // (a)
console.log(b2);  // (b)
console.log(c2);  // (c)
console.log(d2);  // (d)
```

正解は…
：
：
：
：
：
(a)(d)！

## Q2解説
JavaScriptにブロックスコープの概念が追加されたのはECMAScript2015からです。

`let` と `const` で宣言した変数はブロックスコープが適用されます。
なので、{}の中だけで利用したい変数は `let` または `const` で宣言しましょう。

`var` で定義した変数はグローバル変数の扱いとなり{}の外からでも参照できます。
var/let/constのいずれも使用せずに宣言した変数もグローバル変数扱いになります。


## Q3
エラーとならないのは(a)～(d)のどの変数でしょうか？

```javascript
function method() {
    var a3 = 'Var';
    let b3 = 'Let';
    const c3 = 'Const';
    d3 = 'Undeclared';
}

console.log(a3);  // (a)
console.log(b3);  // (b)
console.log(c3);  // (c)
console.log(d3);  // (d)
```

正解は…
：
：
：
：
：
なし！（すべてエラーとなる！）

## Q3解説
関数（ `function` ）の中で宣言された変数は関数の外から参照できません。

{}のブロックスコープと概念が異なることに注意しましょう。


## Q4
エラーとならないのは(a)～(d)のどの変数でしょうか？

```javascript
var a4 = 'Var';
let b4 = 'Let';
const c4 = 'Const';
d4 = 'Undeclared';

a4 = 'New Var';  // (a)
b4 = 'New Let';  // (b)
c4 = 'New Const';  // (c)
d4 = 'New Undeclared';  // (d)
```

正解は…
：
：
：
：
：
(a)(b)(d)！

## Q4解説
`const` は定数を意味します。Javaでいうところの `final` と同じです。
そのため、新しい値を設定できず、(c)のみ `TypeError` となります。


## Q5
エラーとならないのは(a)～(d)のどの変数でしょうか？

```javascript
var a5 = 'Var';
let b5 = 'Let';
const c5 = 'Const';
d5 = 'Undeclared';

var a5 = 'New Var';  // (a)
let b5 = 'New Let';  // (b)
const c5 = 'New Const';  // (c)
d5 = 'New Undeclared';  // (d)
```

正解は…
：
：
：
：
：
(a)(d)！

## Q5解説
`let` と `const` で宣言した変数は再宣言が不可となります。

`let` と `const` をうまく利用すれば、間違って参照したり宣言したりしてしまうことを防げます。


# まとめ
`var`
 - 変数の巻き上げが発生する
 - グローバル変数である
 - 再代入・再宣言できる

`let`
 - 変数の巻き上げが発生しない
 - ローカル変数である
 - 再代入できる
 - 再宣言できない

`const`
 - 変数の巻き上げが発生しない
 - ローカル変数である
 - 再代入できない
 - 再宣言できない

`いずれも使用しない`
 - 変数の巻き上げが発生すしない
 - グローバル変数である
 - 再代入・再宣言できる
Alloyでパズル (15) 数独 ふたたび

[Alloyでパズル (2) 数独](https://qiita.com/jpwgad/items/612abb9b9df0e092ad97) でテーブルビューで結果が見やすく表示できるようになったのはよかった。
が、やはり結果だけでなく問題も見たい！

# 問題表示の方が難しい

「明示されていない値は不定」な Alloy で、ヒントとして与えられていないセルを空にして見せる方法が思いつかなかった。
しかしようやく意味がわかるようになった [イラストロジックをAlloyで解く](http://bonotake.hatenablog.com/entry/20120413/1334300370) を読んでいて、なるほどと思った。

# リスト

テーブルビューで見やすく表示することを最優先しているため、本体と同様に少々力技な書き方になっている（行,列とも０〜８でなく、１〜９にしたかった）。
しかしその分読みづらさは軽減されているのではないだろうか。

```alloy
// 数独 with Hint表

abstract sig Hint {C1,C2,C3,C4,C5,C6,C7,C8,C9:lone Int}
one sig R1,R2,R3,R4,R5,R6,R7,R8,R9 extends Hint {}
pred setHint[hint: set Int->Int->Int] {     // row->col->value
    let row = (1->R1 + 2->R2 + 3->R3 + 4->R4 + 5->R5 + 6->R6 + 7->R7 + 8->R8 + 9->R9),
        col = (1->C1 + 2->C2 + 3->C3 + 4->C4 + 5->C5 + 6->C6 + 7->C7 + 8->C8 + 9->C9) |
    all r,c:row.univ {
        (row[r]).(col[c]) = hint[r,c]               // Hint表へセット
        some hint[r,c] => setCell[r,c,hint[r,c]]    // Result表へセット
    }
}

// 行内各列(r1.c1, r1.c2, r1.c3, ...)の値はすべて異なる (左のdisj)
// 各行同列(r1.c1, r2.c1, r3.c1, ...)の値もすべて異なる (右のdisj)
abstract sig Result {disj c1,c2,c3,c4,c5,c6,c7,c8,c9: disj (1+2+3+4+5+6+7+8+9)}
one sig r1,r2,r3,r4,r5,r6,r7,r8,r9 extends Result {}
fact {
    // 各 3x3 領域の数字はそれぞれ９種類
    #(r1+r2+r3).(c1+c2+c3) = 9
    #(r1+r2+r3).(c4+c5+c6) = 9
    #(r1+r2+r3).(c7+c8+c9) = 9
    #(r4+r5+r6).(c1+c2+c3) = 9
    #(r4+r5+r6).(c4+c5+c6) = 9
    #(r4+r5+r6).(c7+c8+c9) = 9
    #(r7+r8+r9).(c1+c2+c3) = 9
    #(r7+r8+r9).(c4+c5+c6) = 9
    #(r7+r8+r9).(c7+c8+c9) = 9
}
pred setCell[r,c,value: Int] {
    let row = (1->r1 + 2->r2 + 3->r3 + 4->r4 + 5->r5 + 6->r6 + 7->r7 + 8->r8 + 9->r9),
        col = (1->c1 + 2->c2 + 3->c3 + 4->c4 + 5->c5 + 6->c6 + 7->c7 + 8->c8 + 9->c9) |
    (row[r]).(col[c]) = value
}

let cell[row,col,value] = row->col->value

example1: run {  // 世界一難しい
    setHint[
        cell[1,1,4] + cell[1,4,1] + cell[1,9,8] +
        cell[2,2,7] + cell[2,3,8] + cell[2,5,6] + cell[2,7,4] + cell[2,8,2] +
        cell[3,9,3] +
        cell[4,6,7] +
        cell[5,2,3] + cell[5,5,2] + cell[5,6,1] +
        cell[6,5,5] +
        cell[7,1,2] + cell[7,2,5] + cell[7,4,4] + cell[7,8,3] + cell[7,9,1] +
        cell[8,3,6] + cell[8,5,3] + cell[8,8,8] +
        cell[9,6,6] + cell[9,7,5] + cell[9,8,7]
    ]
} for 5 int

example2: run {  // 藤原博文氏作
    setHint[
        cell[2,2,4] + cell[2,3,3] + cell[2,7,6] + cell[2,8,7] +
        cell[3,1,5] + cell[3,4,4] + cell[3,6,2] + cell[3,9,8] +
        cell[4,1,8] + cell[4,5,6] + cell[4,9,1] +
        cell[5,1,2] + cell[5,9,5] +
        cell[6,2,5] + cell[6,8,4] +
        cell[7,3,6] + cell[7,7,7] +
        cell[8,4,5] + cell[8,6,1] +
        cell[9,5,8]
    ]
} for 5 int
```

# 結果

余計なものを一切見せない方針も、パズル的。
　　<img width="339" alt="sudoku2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20005/f597c10e-2ea1-c438-4cf4-5dc68968c61c.png">

# 参考

- bonotakeの日記 : [イラストロジックをAlloyで解く](http://bonotake.hatenablog.com/entry/20120413/1334300370)
- [SAT技術の進化と応用 〜パズルからプログラム検証まで〜：2．SATとパズル -問題をいかにSATソルバーで解くか-](http://id.nii.ac.jp/1001/00169409/)
Ubuntu Serverのキーボード を日本語レイアウトに変更

# ツールの起動
コンソールで以下のコマンドを入力

```
$ sudo dpkg-reconfigure keyboard-configuration
```

1. 「Generic 105-key (Intl) PC」を選択
2. 「Japanese」を選択
3. 「Japanese」を選択
4. 「The default for the keyboard layout」を選択
5. 「No compose key」を選択


```
$ sudo reboot
```
で、設定が反映されているはず。

ネットワークで接続できない時用の小型キーボードに合わせて、日本語レイアウトにしてみました。
![90146382_2902602813155479_2866231366830260224_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/2290ccab-4488-17ef-e730-67694987a5a1.jpeg)
初心者によるプログラミング学習ログ 266日目

#100日チャレンジの266日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
266日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>265日目<br>・webサイト模写　2.0h<br>・以前購入した模写教材のコンテンツ～フッター作成<br>・下層ページ1ページめのトップ作成<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1240368868423380993?ref_src=twsrc%5Etfw">March 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【Rails】 SCSS で Bootstrapライクな opacity-n(透過) を追加する

# 何をするの？👒
CSSでオブジェクトを透過したいときに、
`opacity-85`みたいな感じで `Bootstrap`ライクに指定したかったので
`SCSS`を使って追加しちゃいます

# SCSS の記述🌵
`SCSS`ファイルに以下の記述を追加するだけで、
`opacity-0` = 0% (透過) から `opacity-100` = 100% (非透過) まで全ての透過度を可変で `CSSセレクタ` としてつかうことができます

```opacity.scss
@for $i from 0 through 100 {
  .opacity-#{$i} {opacity: $i * 0.01;}
}
```

``` some.erb.html
<div class="opacity-62">
  # 62%の透過になる
</div>
```


# ファイルとして実装する方法(おまけ)

### アセットパイプラインで実装する場合 🐩
`application.scss` ▶ `opacity.scss`
の順にロードされるように配置する

```/app/assets/stylesheets/application.scss
 *= require_tree .
 // もしくは 
 *= require_tree opacity
```

```/app/assets/stylesheets/opacity.scss
@for $i from 0 through 100 {
  .opacity-#{$i} {opacity: $i * 0.01;}
}
```


### webpacker で実装する場合 🐰
`application.js` ▶ `application.scss` ▶ `opacity.scss`
の順にロードされるように配置する
追加位置はいずれも後ろの方でOK

```/app/javascript/packs/application.js

import "../stylesheets/application";
```

```/app/javascript/stylesheets/application.scss
@import "opacity";
```

```/app/javascript/stylesheets/opacity.scss
@for $i from 0 through 100 {
  .opacity-#{$i} {opacity: $i * 0.01;}
}
```


---
CSS も量が多くなったら別ファイルに分けると、見通しが良いですね🐈
自己紹介

#Qiita初投稿
閲覧頂きありがとうございます。初めまして。okayamanと申します。
あることがきっかけでプログラミングというものに出会い、プログラミングを学習していく内に「エンジニアへ転職したい！」という思いが強くなっていきました。
37歳でしかも未経験からエンジニアに転職するというのはかなり難しいと思っていますが、チャレンジするのはタダですし、**「あきらめたらそこで試合終了ですよ。」**と某バスケ漫画のA先生も仰っているので頑張ってみます！(笑)
どうぞよろしくお願いします。

##プログラミングに出会ったきっかけ
私はyoutubeを見るのが大好きで筋トレ動画(趣味である筋トレの為)やビジネス系の動画を見ていたのですが、たまたまプログラミングに関して取り上げた動画を観たのが最初の出会いです。(動画内では『簡単』だとか、『稼げる』だとか甘い言葉ばかりで今となっては釣られた感じですが、、、)『ホントかよ』と試しにProgate、ドットインストールで学習してみるとなかなか楽しいなと思ったのが最初の印象でした。。

##なぜエンジニアになりたい？
学習を進めていく内にプログラミングの奥深さに興味が湧き、もっと深く知りたい思うようになりました。また、プログラミングを習得することによって仕事でもプライベートでも色んなサービスやアプリが作れる事を知り、自分もその作り手に回りたいという思いが日に日に強くなっていきました。そして、併せてエンジニアに関する動画も観てエンジニアの働き方にも憧れを持つようになりました。


##何を学習しているの？？
現在、独学でHTML,CSS,JS,PHP,SQLを学習中。最近はプログラミングスクールがたくさん出てきてて、その道の方がエンジニアへの転職は早いと思いますが、私にエンジニアの適性があるかどうか見極めたい（『実際に会社へ入ってみないとわからないよ』と仰る方もいらっしゃるとは思いますが・・・）のもあって独学で進めてます。

これから学習予定
・github復習
・フレームワーク(Laravel)
・AWS
・Docker
そして、ポートフォリオ作成＆転職活動（やることいーっぱい＼(^o^)／）

##今後は？
学習した内容を自身の備忘録として投稿予定。
もしかしたら学習日記みたいになっちゃうかも。

##最後に・・・
妻と子供もいて学習する為の纏まった時間を作るのは大変ですが、私と同じように苦労されている方も多くいらっしゃると思うのでその方々達に負けないように頑張ります。
皆さんお互い頑張りましょう！！ご武運を！！
WebpackでCSSの読み込み順番を変えたくてつまづいた件と一時的な解決方法について

こんばんは。

今回は、React + Material-UIで、CSS Modulesを使っていた際に、自分で書いたCSSが反映されなかったときのことと、一時的な対処方法についてです。

調べても全く情報が出てこなかったため、記事にしました。

間違っている点や、よりよい方法があれば教えて下さい！

# CSSが反映されていないときの状態

Material-UIでつくったボタンに、オリジナルのスタイルを効かせようとして、

```tsx:SignupButton.tsx
import * as React from 'react'
import Button from '@material-ui/core/Button'
import styles from './SignupButton.module.css'

const SignupButton: React.FC = () => {
  return (
    <Button className={styles.signup}>新規登録</Button>
  )
}

export default SignupButton
```

```css:SignupButton.module.css
.signup {
  background-color: #aed581;
}

.signup:hover {
  background-color: #8bc34a;
}
```

あと、TypeScriptだからCSSの型情報も書いて、

```ts:SignupButton.module.css.d.ts
declare const styles: {
  readonly "signup": string;
};
export = styles;
```

さあ、ブラウザで確認！

<img width="183" alt="スクリーンショット 2020-03-19 3.17.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/dfcd0771-8231-fb0d-1c4c-acbe064c1b99.png">

ぴえん

CSSが反映されていません。

これが、起こった内容です。

# 原因の追求と解決

いろいろ探しているとスタイルの読み込み順番が問題であることが判明。

<img width="393" alt="スクリーンショット 2020-03-19 3.19.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/a61d2728-68e0-9da5-dbfa-e1fd64780665.png">

ネットで同じ問題を抱えていた人がいないか探してみるも、何も出てこず。

なんとなく、Webpackでバンドルしたときが原因であることがわかっていたので、

調べてみると、`style-loader`の[ドキュメント](https://github.com/webpack-contrib/style-loader#function)にこんなものが、

> **Function**
> Allows to override default behavior and insert styles at any position.

Google先生に翻訳をお願いすると、

> **Function**
> デフォルトの動作をオーバーライドし、任意の位置にスタイルを挿入できます。

これを書き換えれば、スタイルの読み込み順番を変更できそう！

Webpackの設定ファイルを開いて書き換えてみた、

```webpack.config.js
...
      {
        test: /.css$/,
        use: [
          {
            loader: 'style-loader',
            options: {
              insert: function insertAtBottom(element) {
                var parent = document.querySelector('body');
                parent.insertBefore(element, parent.firstChild);
              }
            }
          },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
...
```

これで、bodyの一番上にオリジナルのスタイルが挿入される！

ブラウザで確認してみると、

<img width="200" alt="スクリーンショット 2020-03-19 3.38.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/b36810a8-2bda-d3a6-eced-951d6ce90485.png">

<img width="370" alt="スクリーンショット 2020-03-19 3.41.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/98f67dce-ce83-67be-bab1-64be2a3cd990.png">

かちー

なんとかスタイルを効かせることができた...

# おわりに

本当は、オリジナルのスタイルを`head`の一番下に入れたかったが、うまくできませんでした。

今後、WebpackとMaterial-UIを詳しく調査して、オリジナルのスタイルを`head`の下に入れれるように修正したいと考えてます。
ec2をターミナルで操作するときに詰まった話(fatal: Could not read from remote repository.)

[(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/814e0979217b1a25aa3e)
を参考に、AWSにrailsアプリをあげようとしていたときの凡ミスについて。

##エラー箇所について

上記の記事で

```
[~]$ ssh mumu_key_rsa
```
でログインした後に、

```
[ユーザー名|~]$ vim .gitconfig
```

で、諸々の設定を記述するところがある。

そこで、記事通り、下記のように設定すればよかった。

```
[user]
  name = your_name (#gitに登録した自分の名前)
  email = hoge@hoge.com (#git登録時の自分のメアド)

[alias] (#これはお好きに)
  a = add
  b = branch
  ch = checkout
  st = status

[color] (#色付け)
  ui = true

# githubの場合
[url "github:"] (#pull、pushのための設定)
    InsteadOf = https://github.com/
    InsteadOf = git@github.com:
```

しかしながら、筆者は

```
[user]
  name = your_name (#gitに登録した自分の名前)
  email = hoge@hoge.com (#git登録時の自分のメアド)

[alias] (#これはお好きに)
  a = add
  b = branch
  ch = checkout
  st = status

[color] (#色付け)
  ui = true

# githubの場合
[url "github:"] (#pull、pushのための設定)
    InsteadOf = https://github.com/(ここに実際にcloneしたいアプリのレポジトリURLを書いていた)
    InsteadOf = git@github.com:(ここに実際にcloneしたいアプリのレポジトリURLを書いていた)
```

上記を見ていただければ分かる通り、無駄にレポジトリURLを記載してしまっていた。
その結果、git cloneで

```
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

と、言われてしまったのだった。

##まとめ

[(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/814e0979217b1a25aa3e)

この記事では、丁寧にコメントでここには○○を記述などと書いてくれている。

それをちゃんと読んでいなかった筆者は簡単な設定ミスで結構苦労した（３時間も使ってしまった）。

みなさんが、そして未来の自分が再びこんな凡ミスを犯さないためにも、備忘録的に書かせていただきました。
Azure Data Studio使ってみた


## Azure Data Studioとは？

Microsoftが開発するWindows,Mac,Linuxのクロスプラットフォームで動くデータベースツールです。

[Azure Data Studio](https://docs.microsoft.com/ja-jp/sql/azure-data-studio/what-is?view=sql-server-ver15)

[Azure Data Studio の提供を開始](https://azure.microsoft.com/ja-jp/updates/azure-data-studio-is-now-available/)

普段はSQLserverManagementStudio(以下、**SSMS**)を利用していますが、
いつの間にか新ツールが出ていたので使ってみました。

## ざっくり触った感想

### Visual Studio Codeと似てる!!

ていうか画面構成といい操作間といい全部一緒です。
ですのでvscodeのショートカットなどはすべて共通しています。

個人的には「矩形選択」を重宝していたので、
安心して使えます。

### 軽量!!

SSMSって高機能なおかげで動作が重たいんですよね。
小さいクエリをちょっと試したいだけの場合、
AzureDataStudioが向いています。

### 

## Azure SQL Databaseに接続

起動したら接続のウインドウが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/61e6f7be-fb04-aba0-8645-1f4f5ee0c627.png)

## クエリ実行

Studentテーブルに対してSELECT実施!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/c8a89c47-f3ea-4031-69b4-b75f36dd38bc.png)


結果がシンプルな表示で返ってきますが、意外と高機能で各種形式に出力が可能です。

結果のレコードについてはCSV、Excel、JSON、XMLに出力可能です。
結果全体も勿論出力可能です。
右側の小さなアイコンにカーソルを合わせます。

![clip.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/8e58aa61-b188-d8bb-97a7-f9882a7f7939.gif)

## Azure Data Studioにないもの

高機能エディタであるvscodeと似ていることからわかるように、
すべてがテキスト入力をベースに考えられています。

ですのでSSMSにあるようなGUIやウィザード形式で設定を行うようなものはないと思ってください。
詳細な比較は以下のページ確認してください。

[SQL Server Management Studio (SSMS) との機能の比較](https://docs.microsoft.com/ja-jp/sql/azure-data-studio/what-is?view=sql-server-ver15#feature-comparison-with-sql-server-management-studio-ssms)

逆にAzureとの連携やJupyterNotebookへの対応やGitでのバージョン管理などは
Azure Data Studioにしかないです。
ですのでData StudioはSQL server(RDB)を核としたSSMSより少し広範なデータ分析ツールと言えます。

## まとめ

SQLserverManagementStudioも必須のツールですが、
SELECT文中心に探索的データ分析を行うようなシーンではAzure Data Studioが適しているようです!!
皆さんもぜひ使ってみてください！！

今後も使い勝手を共有していきます。
hp ビジネス向けPCにハイエンドGPUを接続してみた

# hp ProDesk 600 G1 に MSI Radeon R9 390 を接続する
まず、hp ProDesk 600 G1 を、中古で買った。
これは、息子用のPCとして２００００円で購入したのだが、ノートの方が使い勝手がいいということで、早々に俺の元に帰ってきた。
しばらくは、モナコインのCPUマイナーPCとして使っていたのだが、いかんせん１日1銭くらいでは、電気代が無駄なので、GPUを取り付けたいなぁ～と、ふらりと近所のPCショップへ行くとありました。

　MSI Radeon R9 390  12,000円

# 省スペースPCに、ハイエンドグラボは入りません。
　当然のことながら、まずスペース問題が勃発。
　仕方なくマザーボードからすべて摘出。
　するとどうでしょう。

　電源ソケットが6PIN？

　なにこれ？　付属の電源では絶対に容量不足なので、500WのATX電源に付け替えようと思ったのに、メイン電源ソケットがこれじゃ、補助電源ボード経由じゃないか！

　とはいえ、電源も余りがないので、またまたハードオフでジャンクの電源搭載ケースを2000円で購入
　ケースは、Pentium D 搭載のマザーボード（メモリは抜かれてた）、500W電源付きなので、まぁこれくらいならいいやと購入。

　早速、補助電源用ボード（こういうの　https://store.shopping.yahoo.co.jp/hisui-kobo/TS150.html）で、電源を外付け。
　グラボの補助電源も接続して、いざ起動・・・・・

　難なく起動しました。

# 購入物品
|品物|新品・中古|価格|
|:---|:---|---:|
|hp ProDesk 600 G1|中古|20,000|
|MSI Radeon R9 390 8G|中古|12,000|
|補助電源ボード|新品|1,280|

ちなみにATXケースには、ねじ穴が合わず、裸で運用中・・・・
ひとまずこれで様子見します
URLを気軽に「www」なしにしてトラブった話

# 背景
Webサイトの要件決めの時に、URLを「www」なしのZone apex(ドメイン名そのもの）で気軽に了承してしまい、環境引き渡しが遅れてしまった話。

# 環境（初期構築時）
+ AWS
+ ELB＋EC2
+ お名前.com

# 問題点
ELBのDNS登録はCNAMEレコードを使う必要があるが、Zone apexのようなサブドメインなしのドメインそのものの場合、CNAMEにマッピングすることはできません。
今回の環境では使用していませんが、CDNも同様の制約があります。
この制約は何処でドメインを購入しても同様です。

その辺りの詳細な話は、以下の記事で簡潔にわかりやすくまとめてありました。
https://qiita.com/haruyosh/items/95b20bef7beb63d200ab

# 解決方法
Route53のAliasレコードならZone apexをマッピングすることは可能です。
幸いなことにネームサーバをお名前.comからRoute53に変更するのは、お名前.comのドメインNaviネームサーバー設定で、ネームサーバ情報をRoute53のものに変更で切り替えることができます。

注意しなければいけないのが、ドメインを使用していた場合はTTLの有効期限切れまで２日間程待たなければいけません。
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/migrate-dns-domain-in-use.html#migrate-dns-wait-for-ttl

# 補足
ネームサーバを変えてもレジストラは変わらないため、ドメインの更新通知は購入元のレジストラから連絡がきます。

# まとめ
URLの「www」なしはCNAMEが使えないため、特に要件が無いのであれば「www」ありにする方がオススメです。
【Unity】3D Game Kitのアセットをインポートしたらエラーが出た場合の対処法

## 現象
Unityの公式の「[3D Game Kit](https://assetstore.unity.com/packages/templates/tutorials/3d-game-kit-115747)」という3Dアクションゲームのテンプレートアセットがあるのですが、こちらをインポートしたところ以下のようなエラーが出ました。

```
Library\PackageCache\com.unity.timeline@1.2.6\Runtime\Utilities\AnimatorBindingCache.cs(91,40): error CS0117: 'AnimationMode' does not contain a definition for 'GetCurveBindings'
```

この解決法を調べたところいくつか解決策を載せてくれているのですが、私のバージョンでは上手くいかなかったので、自分のバージョンでの解決策を載せておきます。

## 環境
Unity : 2019.3.0a5
3D Game Kit : 1.9
OS : Windows10

## 解決策
このエラーはUnityのパッケージの最新バージョンにこのアセットが対応していないことによるエラーなので、パッケージのバージョンを前のバージョンに戻すことで解決できます。

1. 上のメニューから Window > Package Manager を開きます。
2. 検索欄にTimelineと入力してTimelineのパッケージを探します。
3. 左の三角アイコンをクリックして利用可能なバージョンを出します。
4. 以前のバージョンを選択して右下のUpdateを押します。

この記事を書いたときは1.2.10から1.1.0にダウングレードしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260272/64e30e32-3a80-83e0-f8b7-6f75928f0f1c.png)

すると最初のエラーは消えるはずです。

しかし今度は以下のようなエラーがでます。

```
Library\PackageCache\com.unity.ide.rider@1.1.4\Rider\Editor\RiderScriptEditor.cs(385,65): error CS0117: 'AssetDatabaseExperimental' does not contain a definition for 'IsAssetImportWorkerProcess'
```

同様の手順で、「Rider Editor」をパッケージマネージャーで検索してverifiedバージョンにupdateします。

最後に「ProBuilder」も同様の手順でupdateします。

```
Library\PackageCache\com.unity.probuilder@4.2.3\Editor\EditorCore\ShapeEditor.cs(186,37): error CS0117: 'ActiveEditorTracker' does not contain a definition for 'RebuildAllIfNecessary'
```

これでサンプルシーンから実行ができるようになりました！
マイグレーション操作

## はじめに
「Ruby on Rails 5 速習実践ガイド」の本の内容（Chapter4-1）に沿ってまとめと、他に調べて知ったことも書いてみようと思います。
（内容薄いですが、、、、）

## Ruby on Rails 5 速習実践ガイド（Chapter4-1）

### 🎈マイグレーションの適用

#### ２つのステップ
マイグレーションは基本的に２つのステップで行います。
1. Rubyのコードで、データベースのスキーマを変更するファイル、 **「マイグレーション」ファイル** を作成する
2. `rails db:migrate` コマンドで、作成した「マイグレーション」ファイルをデータベースに適用する<br><br>

#### １つのマイグレーションは１つのバージョン
１つのマイグレーション（ファイル）が、 １つのバージョンとして、扱われます。
マイグレーションファイルを作成しただけでは、データベースは変更されず（バージョンは上がらず）、マイグレーションファイルを適用するとデータベースが変更されます。
マイグレーションを取り消す（バージョンを下げる）にも、マイグレーションファイルを削除するだけでは変更されないため、取り消すコマンドを実行して、操作を適用します。



### 🎈バージョンの上げ下げ

下のマイグレーションファイルは、Userテーブル作成し、nameカラムとemailカラムを持つことを記述されています。
`changeメソッド`の中に、「Userテーブルを作成する」というコードが書かれていれば、
マイグレーションの適用を取り消す際には、「Userテーブルを削除する」というコードが書かれているかのように処理をしてくれます。

```db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```

こちらのマイグレーションファイルは、nameカラムに入る文字列の長さを制限しています。
`upメソッド` にバージョンを上げる処理、 `downメソッド` にバージョンを下げる処理を記述しています。

```db/migrate/[timestamp]_change_users_name_limit10.rb
class ChangeUsersNameLimit10 < ActiveRecord::Migration[6.0]
  def up
    change_column :Users, :name, :string, limit: 30
  end

  def down
    change_column :Users, :name, :string
  end
end
```


### 🎈schema.rbについて 

Railsは、データベースの構造（スキーマ）を `db/schema.rb` というファイルに自動で出力します。
テーブル、カラムの構造を確認できます。

 [Railsガイド](https://railsguides.jp/active_record_migrations.html#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%84%8F%E5%91%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)には、このように書かれています。
> Railsのマイグレーションは強力ではありますが、データベースのスキーマを作成するための信頼できる情報源ではありません。
信頼できる情報源は、やはりデータベースです。Railsは、デフォルトでデータベーススキーマの最新の状態のキャプチャを試みるdb/schema.rbを生成します。



### 🎈主なコマンド
#### migrationまわり
migrationに関する主なコマンドまとめです

|コマンド　　　　　　　                 　　 |意味                     |
|----------------------------------------|------------------------|
|bin/rails db:migrate                    |最新までマイグレーションを適用する 
|bin/rails db:migrate VERSION=20200319   |特定のバージョンまでマイグレーションが適用されていた状態にする
|bin/rails db:rollback                   |バージョンを１つ戻す
|bin/rails db:rollback STEP=2            |バージョンを指定したステップ数だけ戻す
|bin/rails db:migrate:redo               |バージョンを１つ戻してから１つ上げる
|bin/rails db:version             　　　  |現在の適応されているバージョンを表示する

#### dbコマンド
主なdbコマンドも少しまとめてみました

|コマンド                |意味                     |
|-----------------------|------------------------|
|bin/rails db:create    |データベースが作成される
|bin/rails db:drop      |データベースの削除される
|bin/rails db:reset     |db:dropし、db/schema.rbにもとづいてデータベースを作り直す



## おしまい

↓こちら参考にしました🎒
Ruby on Rails 5 速習実践ガイド
[Railsガイド](https://railsguides.jp/active_record_migrations.html)
[rake or rails コマンドでdbを扱うときのメモ](https://qiita.com/pugiemonn/items/e237b73025d8db8545bf)
Android + C++ で wav 音声再生するための Oboe ライブラリのメモ

# 背景

* Android で手っ取り早く C++ で wav 音声を再生したい
* Android Vulkan で compute shader で STFT 処理とか spatial audio 処理した音声データを再生したい
* Vulkan と一緒に使いたいので, Android 8 以降対応でよい.

## Native audio library

AAduio(Android 8.0 or later) と OpenSLES がありますが, どちらも低レイヤーなので,  wav をお手軽再生とかはできません.

https://developer.android.com/ndk/guides/audio

## 既存ライブラリ

手っ取り早く Android C++ で wav 再生は SoLoud があります.

https://sol.gfxile.net/soloud/

クロスプラットフォームでよいのですが, Android はあまりメンテされていないようで, CMake 用の設定がなかったり, backend は SLES だけだったり, logcat になぜか多量の debug warning が出たりといまいちです.

## Oboe

C++14 or later になりますが(Android NDK は最近 C++17 or later 対応なので問題はない), Oboe https://github.com/google/oboe が推奨っぽいので使ってみます. 実態としては AAudio, OpenSLES のラッパーです. 

クロスプラットフォームだとうれしかったですが, Android 限定です. PC を使うときは SoLoud にするなどと切り替えるとよいかもです.

Oboe 自体も, 本体は wav load とかはには対応していませんが, samples の parselib に wav などのローダがあります.

https://github.com/google/oboe/tree/master/samples/parselib/src/main/cpp


github issue を見ると, 古い Android では動かなかったりあるようですが, とりあえず AAudio(Android 8) 以降の端末では大丈夫そうでしょうか.
 
### C++14 

Android で C++14 だと, spdlog と組み合わせるときに不都合がありました.　ヘッダのインクルード順にはお気をつけください.

Android NDK + C++14 設定 cmake で no member named `make_unique` in namespace `std` エラーなどが出る
https://qiita.com/syoyo/items/5274fcde46520ff301f4

### 組み込む

CMake 設定がありますので, これを参考にするとよいでしょう.


Oboe を使っての wav のロードと再生は, drumthumber サンプルを参考にします.

https://github.com/google/oboe/tree/master/samples/drumthumper

同じく samples にある, `iolib`(play/stop とか簡単に使える API?), `parselib`(wav loader) を使っています.
これらは, ファイル数は多くないので, 自前の CMakeLists にソースコードリスト直追加が楽かと思います.
(add_subdirectory だと循環参照があって, `--whole-archive` リンカオプションを指定しないとリンクエラーになる)

`iolib` に wav をロードして再生する `SimpleMultiPlayer` があります. ただ, エラーチェックが無かったり, 初期化せずに wav ロードすると seg fault するなど, コード品質が微妙です.

#### 音声の再生

`SimpleMultiPlayer` の triggerDown で再生できます. triggerUp で再生を終了できます.
再生の停止(pause)はなさそうなので自前実装が必要そうです.

#### wav のロード


dr_libs 
https://github.com/mackron/dr_libs 

で読んでもいいかもしれません.



#### Permission は?

audio を鳴らすだけなら, AndroidManifest.xml での permission 設定(+ アプリ側での permission request)は不要です.

マイクから録音するときは permission が必要になります.
Python（boto3）でDynamoDB上のデータを更新しようとすると「ExpressionAttributeNames contains invalid key: Syntax error; key: <キー名>」となる

## 事象

AWS上に以下のようなDynamoDBテーブルがある。

- テーブル名：`client_id_master`
- パーティションキー：`client-id`（str）
- アトリビュート：
  - `device-time-stamp`（int）

今回、このテーブル上のデータの`device-time-stamp`列の値を、Python（boto3）から`update_item()`メソッドにより更新する以下のようなコードを作成した。

```py
from datetime import datetime
import boto3

dynamodb = boto3.resource('dynamodb')

now_unix_time = datetime.now().strftime('%s')
clientId = 'ef5b728f4a74aed'
option = {
    'Key': {'client-id': clientId},
    'UpdateExpression': 'set #device-time-stamp = :timeStamp',
    'ExpressionAttributeNames': {
        '#device-time-stamp': 'device-time-stamp'
    },
    'ExpressionAttributeValues': {
        ':timeStamp': now_unix_time
    }
}

table = dynamodb.Table('client_id_master')
table.update_item(**option)
```

しかし、このコードを実行したところ以下のエラーとなった。

```
An error occurred (ValidationException) when calling the UpdateItem operation: ExpressionAttributeNames contains invalid key: Syntax error; key: \"#device-time-stamp\""
```

## 原因・解決

原因としては、`update_item()`の`UpdateExpression`で指定する変数名に使える文字には制限があり、今回は`#device-time-stamp`に含まれる`-`が利用不可文字に該当したためSyntax errorとなっていた。

よって、以下のように変数名を`#device_time_stamp`とすることにより正常にコードが実行できるようになった。

```py
from datetime import datetime
import boto3

dynamodb = boto3.resource('dynamodb')

now_unix_time = datetime.now().strftime('%s')
clientId = 'ef5b728f4a74aed'
option = {
    'Key': {'client-id': clientId},
    'UpdateExpression': 'set #device_time_stamp = :timeStamp',
    'ExpressionAttributeNames': {
        '#device_time_stamp': 'device-time-stamp'
    },
    'ExpressionAttributeValues': {
        ':timeStamp': now_unix_time
    }
}

table = dynamodb.Table('client_id_master')
table.update_item(**option)
```

![image.png](https://image.docbase.io/uploads/f38fc993-ecfc-43ac-813c-e4d892e1c1fe.png)

以上
AlexaのAudio Playerで「スキルがリクエストに正しく応答できませんでした」と言われるときの対処法

Alexa (Amazon Echo) の Audio Player で「スキルがリクエストに正しく応答できませんでした」と言われるときの対処法です。

※ ブラウザ上のテストでは音声再生はエラーが発生する仕様なため実機でテストしてください。

---

* 「ビルド」タブ →「インターフェース」で「Audio Player」を有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155587/6b293dba-f7fb-3ad6-fc1e-e488bf423adc.png)

* `StopIntentHandler`, `PauseIntentHandler`, `ResumeIntentHandler` を追加する

* `index.js` 1番下の `exports.handler` に各 Handler を追加することを忘れない



```index.js
const StopIntentHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return (request.type === 'IntentRequest' && request.intent.name === 'AMAZON.StopIntent');
    },
    async handle(handlerInput) {
        return handlerInput.responseBuilder
        .addAudioPlayerStopDirective()
        .getResponse();
    }
};
const PauseIntentHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return (request.type === 'IntentRequest' && request.intent.name === 'AMAZON.PauseIntent');
    },
    async handle(handlerInput) {
        return handlerInput.responseBuilder
        .addAudioPlayerStopDirective()
        .getResponse();
    }
};
const ResumeIntentHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return (request.type === 'IntentRequest' && request.intent.name === 'AMAZON.ResumeIntent');
    },
    async handle(handlerInput) {
        const url = 'url_here';
        const AudioPlayer = handlerInput.requestEnvelope.context.AudioPlayer;
        const token = AudioPlayer.token;
        const offset = AudioPlayer.offsetInMilliseconds;
        return handlerInput.responseBuilder
            .addAudioPlayerPlayDirective('REPLACE_ALL', url, token, offset, null)
            .getResponse();
  }
};
```

# 参考
https://ask-sdk-for-nodejs.readthedocs.io/ja/latest/Building-Response.html
https://dev.classmethod.jp/cloud/alexa-sdk-v2-ninth/
PowerShellでPDFをページごとに分割 (w/iTextSharp)

PowerShellからiTextSharpを呼び出してPDFをページごとに分割します。

# 下準備

まず始めに itextsharp.dll を入手してください。

https://www.nuget.org/packages/iTextSharp/

nugetするのが本筋ですが、スクリプトを置くフォルダにlibというサブフォルダを作って、その下に itextsharp.dll を入れる方式です。
よって、下記スクリプトもこの前提です。

# スクリプト

以下を Split-Pages.ps1 として保存。

```powershell:Split-Pages.ps1
# Split PDF pages
param(
    [parameter(mandatory=$true)][string]$sourceDataPath,
    [string]$destinationPath
)

function Split-Pages($sourceDataPath, $destinationPath)
{
    # path of itextsharp.dll
    [System.Reflection.Assembly]::LoadFrom((Join-Path (Split-Path $script:MyInvocation.MyCommand.Path) "\lib\itextsharp.dll")) | Out-Null

    $pr = New-Object iTextSharp.text.pdf.PdfReader([string]$sourceDataPath)
    if($pr.IsEncrypted()){
        Write-Error("Encrypted: ", $sourceDataPath)
    }

    if($null -eq $destinationPath){
        $path = Split-Path -Parent $sourceDataPath
    }
    else{
        $path = Convert-Path $destinationPath
    }

    $fname = [System.IO.Path]::GetFileNameWithoutExtension($sourceDataPath)
    $ext = [System.IO.Path]::GetExtension($sourceDataPath)

    try {
        $pages = $pr.NumberOfPages
        $padding = [string]$pages

        for($page = 1; $page -le $pages; $page++) {

            $pn = [string]$page

            $destinationPath = Join-Path $path ($fname + "_p" + $pn.PadLeft($padding.Length, "0") + $ext)

            $fs = New-Object System.IO.FileStream([string]$destinationPath, [System.IO.FileMode]::Create)

            $doc = New-Object iTextSharp.text.Document($pr.GetPageSize($page))
            $pw = [iTextSharp.text.pdf.PdfWriter]::GetInstance($doc, $fs)

            $doc.Open()
            $doc.NewPage() | Out-Null

            $importedPage = $pw.GetImportedpage($pr, $page)
            $pcb = $pw.DirectContent
            $pcb.AddTemplate($importedPage, 0, 0)

            $doc.Close()
            $pw.Close()
            $fs.Close()

        }

        $pr.Close()
    }
    catch {
        Write-Error("Error: " + $_.Exception)
    }
}

Split-Pages (Convert-Path $sourceDataPath) $destinationPath
```

# 使用例

PowerShellを立ち上げて、

```powershell
PS> Split-Pages.ps1 元PDFファイル 出力先フォルダ
```

みたいに使います。
出力先フォルダを指定しない場合は元PDFファイルと同じフォルダに分割したPDFを保存します。

iTextSharpは使える子ですが、iTextAsian.dllを組み合わせても「半角英数含めてUniJIS-UCS2-HW-Hでエンコードされていると半角英数を取り損ねる」のはなんとかならないものか…。
package:provider を使ったFormのValidationのサンプル

## 画面構成
画面の構成的には、containerとなるページがあり、その上にログイン画面が表示されるような構成を想定しています。

main 
　└ container
　  　　　└ login

## main.dart
`ChangeNotifierProvider` をつかって状態オブジェクトを配置する。

```dart:main.dart
void main() =>
    runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (context) => ContainerStore()),
            ChangeNotifierProvider(create: (context) => LoginStore()),
          ],
          child: App(),
        )

    );

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
      home: Container(),
    );
  }
}
```

## コンテナページの作成
特に作る必要もないですが、ログインページはdismissされるというそうていで一応配備します。
ログインページを表示するだけ。

```dart:container.dart
class Container extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Login();
  }
}

class ContainerStore with ChangeNotifier {
}
```


## ログインページの作成
`TextFormField` の `onChange:` イベントで毎回メールアドレスのチェックを行い、エラーがある場合はメアド入力欄の下にエラーメッセージを表示しています。エラーの通知は `notifyListeners()` で行っています。

```dart:login.dart
class Login extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer <LoginStore>(
        builder: (context, loginStore, _) {
          return Scaffold(
              backgroundColor: Colors.blue[300],
              body: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  SizedBox(height: 50),
                  TextFormField(
                    onChanged: (text) => loginStore.changeEmail(text),
                  ),
                  Text('${loginStore.emailError}'), // エラーメッセージ
                ],
              )
          );
        });
  }
}

class LoginStore with ChangeNotifier {
  var email = "";
  var emailError = "";

  void changeEmail(String text) {
    email = text;
    emailError = validate() ? "" : "メールアドレスを正しく入力してください";
    notifyListeners();
  }
  bool validate(String email) {
    // validation処理を書く
  }
}
```
Rails6 Action Text アップロードされた画像のファイル名と画像サイズを非表示にする方法

こんにちは、「おすし」です。

最近ぶろぐを始めようと思い、 Action Txet を Rails6 で使おうと思い、導入までは順調だったのですが、いざ画像をアップロードすると、、、


<img width="1440" alt="スクリーンショット 2020-03-18 18.33.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578722/4e27b2ee-81c5-18c6-582c-6d29736c1d24.png">


なんとアップロードした画像の下にデフォルトでファイル名と画像サイズが表示されています！！！！


解決方法は....Action Textを導入した時に自動的に作成されたこのファイルから...↓ 

```erb
views/activestorage/blobs/_blob.html.erb

<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
   <% if blob.representable? %>
      <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
    <% end %>


    <figcaption class="attachment__caption"> 
      <% if caption = blob.try(:caption) %>
        <%= caption %>
      <% else %>
        <span class="attachment__name"><%= blob.filename %></span>
        <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
      <% end %>
    </figcaption>
 </figure>
```

 figcaptionタグ含め、ネストされているコードを全て消します。

```erb

views/activestorage/blobs/_blob.html.erb

<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
   <% if blob.representable? %>
      <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
   <% end %>
</figure>
```


これだけ！

見てくださりありがとうございます。
それでは、お体ご自愛ください。
SSL証明書について営業の観点（2020年3月）

**SSL証明書の不都合な真実**
というタイトルをつけていたのですが、書き終わってからそんなかっこいい記事でもないし、
かなり主観も混じった内容となってしまったので変更しました。
なるべくソースは用意していますが、普段SSL証明書を扱うものの感想レベルで認識ください。


#人はなぜ、サイトをHTTPS化するのでしょうか？

先日、Let's Encryptの証明書の強制無効化の影響で
多々対応に追われた方も多いのではないかと思います。

普段、営業の身としてSSL証明書を売る立場の人間として
ここ数年の常時HTTPS化は嬉しい流れである分、
SSL証明書の利用価値に対しては疑問を持っています。

昨今は「通信の暗号化」が大義を締め、
「サーバー証明、データの改ざん防止」における認識は狭まってきているのではと
感じています。

さくらインターネット様の「さくらのSSL」の記事が引用しました。秀逸記事です。
https://ssl.sakura.ad.jp/column/necessity-of-ssl/


#なぜそう感じるのか

この波を感じたのは2017年から2018年に発生したシマンテック（現デジサート・ジャパン）発行の
SSL証明書に対するGoogleChrome70の失効対応です。

Chrome’s Plan to Distrust Symantec Certificates
https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html

Symantec の PKI の無効化について: 要対応確認
https://webmaster-ja.googleblog.com/2018/04/distrust-of-symantec-pki-immediate.html

多くのシェアを持つchromeから締め出されるような事となってしまいシマンテックは、関連事業をデジサート社へ売却し、デジサート・ジャパン合同会社を日本で設立しました。

https://www.digicert.com/jp/news/pr_20171101/

しかし、それだけでは証明書失効対応には何もならず、「デジサートから発行された証明書」とすることが必要なため、有効期限のあるSSL証明書も再発行手続きを行い、結果ユーザへの影響が出てしまいました。

**chrome（というかGoogle）の影響力が強すぎて、chromeばかりがこの問題では浮彫になっていましたが、各ブラウザがシマンテック発行のものを失効させると表明していました。**
https://knowledge.digicert.com/ja/jp/generalinformation/INFO4983.html


**この流れにより、SSL証明書業界よりブラウザ業界のほうが優位であることが感じられました。**


#Let's Encryptの意義
先日、Let's Encryptは10億の証明書の発行という記事がありました。
ますます無料SSL証明書の存在を大きく示したのではないかと思います。

Let's Encrypt Has Issued a Billion Certificates - Let's Encrypt - Free SSL/TLS Certificates
https://letsencrypt.org/2020/02/27/one-billion-certs.html

Let's Encrypt、10億の証明書を発行 - 全体の81%がHTTPSを使用
https://news.mynavi.jp/article/20200229-984157/

無料のSSL証明書はダメなのか？
という点でよく言われるのがフィッシングサイトなどでも利用できてしまう、という点です。

無料証明書と有料証明書の違い
https://ssl.sakura.ad.jp/column/free-or-paid/

グローバルサイン様のサイトもわかりやすいです。
https://jp.globalsign.com/service/ssl/

しかし、昨今SSL証明書の利用者がどこまでここを重視しているのかが疑問です。
Let's Encryptでもドメイン認証・DNS認証は行っており、
多視点ドメイン検証というのも始まったようです。
https://www.atmarkit.co.jp/ait/articles/2002/27/news122.html

**結果、ブラウザ業界の優位に立ち、常時HTTPS化を進めることによりユーザの意識・価値観が変わってきたと思います。**

#有料SSL証明書の価値と住み分け
企業認証が出来る面というのは有料SSL証明書、とくにEVレベルは非常に価値があります。
営業的にはこの価値と住み分けをユーザにしっかり示し、要求されるセキュリティレベルやサイトの価値に対し提示できることが大切かと思います。
また、SSL会社にはクラウド対応についてもっと加勢して頂きたいと個人的に思っています。


#topic
無料SSL証明書は発行元がいつなくなるかわからない！
というのも記事で見かけますが、元々デジサートのSSL証明書を取り扱っていた会社が
突然あと2週間で取り扱い終了します、と発表し混乱が発生したり、
シマンテックに至っては一部事業がブロードコムに買収されたと思ったらそこからアクセンチュアに買収されたり、、今後もSSL証明書業界には注目していきたいと思います。
Vue.jsでブラーエフェクト付きの画像遅延ローディング

## 概要

1. [lqip-loader](https://github.com/zouhir/lqip-loader)を使って低解像度版の画像を生成する
1. [vue-lazyload](https://github.com/hilongjw/vue-lazyload)で、1で生成した低解像度の画像をローディング時の画像として用いる
2. 遷移時のアニメーションはcssのtranstionを使う

## やりたいこと

![example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316990/d2a771a7-4cca-af4e-9a3e-b71041636a67.gif)

こんな感じで画像を遅延ローディングするときのプレースホルダーにブラーがかかった画像を使いたい！

## 方法

### lqip-loaderを導入する

[lqip-loader](https://github.com/zouhir/lqip-loader)は低解像度版の画像を出力するためのwebpackのローダーです。まずはこのツールを導入します。

```
npm install --save-dev lqip-loader
```

[vue-cli](https://cli.vuejs.org/)を使ってプロジェクトを作成した場合、`vue.config.js`に次のように記述します。

```javascript:vue.config.js
module.exports = {
  chainWebpack: config => {
    const imagesRule = config.module.rule('images');

    imagesRule.uses.clear();

    imagesRule
      .use('lqip-loader')
      .options({
        path: '/media',
        base64: true,
        palette: false
      })
      .loader('lqip-loader');
  }
};
```

webpackをそのまま使っている場合は、[公式のREADME](https://github.com/hilongjw/vue-lazyload/blob/master/README.md)を参考に設定してください。

### Vue-Lazyloadを導入する

[Vue-Lazyload](https://github.com/hilongjw/vue-lazyload)はリソースの遅延ロードを行うためのVue.js用モジュールです。

[公式のREADME](https://github.com/hilongjw/vue-lazyload/blob/master/README.md)の通りに導入しましょう。

### 画像を利用する

例として、画像を遅延ロードするコンポーネント`LazyImage`を実装します。

```vue:LazyImage.vue
<template>
    <div class="lazy-image" v-lazy-container="{ selector: 'img' }">
        <img :data-src="img.src"
             :data-loading="img.preSrc"
        >
    </div>
</template>

<script>
  export default {
    name: 'LazyImage',
    props: {
      img: {
        type: Object,
        required: true,
      },
    },
  }
</script>
```

3,4行目に書いたように、lqip-loaderが出力した低解像度の画像は`preSrc`プロパティ[^1]、本来の画像のパスは`src`プロパティで取得できます。

このコンポーネントにimgを渡すときは、次のように記述します。

```vue:App.vue
<lazy-image :img="require('./img/example.png')" />
```

### スムーズに遷移する

遷移のアニメーションにはcssが使えます。

cssのfilterでblurをかけ、画像のロードが終了したときにfilterを外せば良いです。あとは好きにtransitionをかけましょう。

```scss
lazy-img > img {
  filter: blur(25px);
  transition: all .2s;

  &[lazy=loaded] {
    filter: none
  }
}
```

## 参考

- https://github.com/hilongjw/vue-lazyload/issues/211

[^1]: base64エンコードされた画像**そのもの**が入っています。
【React】Warning: Cannot update a component from inside the function body of a different component.

Reactのバージョンを16.12.0 → 16.13.0にした時に下の様なWarningが出て困った。
>Warning: Cannot update a component from inside the function body of a different component.

なんだこのWarning！？

日本語の情報が少ない中、reactのissuesやstackoverflowを一生懸命探してみたが、最終的に公式のBlogにたどり着いた。
https://reactjs.org/blog/2020/02/26/react-v16.13.0.html
>It is supported to call setState during render, but only for the same component. If you call setState during a render on a different component, you will now see a warning:

>レンダリング中にsetStateを呼び出すことはサポートされていますが、同じコンポーネントに対してのみです。別のコンポーネントでのレンダリング中にsetStateを呼び出すと、警告が表示されます。

ということらしい。

これだとWarningが出る。
Hogeのレンダリング中にFugaでsetStateを呼び出しているのが原因っぽい。

```react:App.tsx
import React, { useState } from "react";
interface Props {
  setCount: Function;
}
const Fuga: React.FC<Props> = ({ setCount }) => {
  setCount(1);
  return <p>test</p>;
};
const Hoge: React.FC = () => {
  const [count, setCount] = useState(0);
  return <Fuga setCount={setCount} />;
};
export default Hoge;
```
これを解決する方法は、もちろん公式に書いてある。
>In the rare case that you intentionally want to change the state of another component as a result of rendering, you can wrap the setState call into useEffect.

>レンダリングの結果として意図的に別のコンポーネントの状態を変更したいというまれなケースでは、setState呼び出しをuseEffectにラップできます。

要するに、setStateをuseEffectでラップすれば良いらしい。
これだと、Warningは出ない。

```react:App.tsx
import React, { useState, useEffect } from "react";
interface Props {
  setCount: Function;
}
const Fuga: React.FC<Props> = ({ setCount }) => {
  useEffect(() => {
    setCount(1);
  }, [setCount]);
  return <p>test</p>;
};
const Hoge: React.FC = () => {
  const [count, setCount] = useState(0);
  return <Fuga setCount={setCount} />;
};
export default Hoge;
```
無事解決！
ふぅ、焦ったー。。。
PowerShellでPDFを右綴じに変換 (w/iTextSharp)

PowerShellからiTextSharpを呼び出してPDFを右綴じに変換します。

# 下準備

まず始めに itextsharp.dll を入手してください。

https://www.nuget.org/packages/iTextSharp/

nugetするのが本筋ですが、スクリプトを置くフォルダにlibというサブフォルダを作って、その下に itextsharp.dll を入れる方式です。
よって、下記スクリプトもこの前提です。

# スクリプト

以下を ConvertTo-RightBinding.ps1 として保存。

```powershell:ConvertTo-RightBinding.ps1
# Convert PDF To Right-bindings
param(
    [parameter(mandatory=$true)][string]$sourceDataPath,
    [parameter(mandatory=$true)][string]$destinationPath
)

function ConvertTo-RightBinding($sourceDataPath, $destinationPath)
{
    # path of itextsharp.dll
    [System.Reflection.Assembly]::LoadFrom((Join-Path (Split-Path $script:MyInvocation.MyCommand.Path) "\lib\itextsharp.dll")) | Out-Null

    $pr = New-Object iTextSharp.text.pdf.PdfReader([string]$sourceDataPath)
    if($pr.IsEncrypted()){
        Write-Error("Encrypted: ", $sourceDataPath)
    }

    try {
        $fs = New-Object System.IO.FileStream([string]$destinationPath, [System.IO.FileMode]::Create)
        $st = New-Object iTextSharp.text.pdf.PdfStamper($pr, $fs)

        $st.AddViewerPreference([iTextSharp.text.pdf.PdfName]::DIRECTION, [iTextSharp.text.pdf.PdfName]::R2L)

        $st.Close()
        $fs.Close()
        $pr.Close()
    }
    catch {
        Write-Error("Error: " + $_.Exception)
    }
}

ConvertTo-RightBinding (Convert-Path $sourceDataPath) $destinationPath
```

# 使用例

PowerShellを立ち上げて、

```powershell
PS> ConvertTo-RightBinding.ps1 元PDFファイル (Join-Path $PWD 出力先PDFファイル)
```

みたいに使います。

C#でバイナリを作らなくていいのは便利だね。