OmniAICreator/Qiita-1.07M huggingface dataset:
Yolo V5で簡単7セグLED読み取りAI

# はじめに
センシンロボティクスでは、ロボティクス＋AIの力により社会課題を解決する業務のデジタル化を推進しています。耐用年数が長い設備ではアナログメーターが依然として多く使われており、設備点検業務のデジタル化にはまずはアナログメーターの自動読み取りが必要となります。

撮影条件を工夫したり閾値を調整したりと、従来の画像処理では苦労が耐えませんが、ディープラーニングを使って簡単にこれを実現したい！ということで、物体検出アルゴリズムのYolo V5を使って7セグLEDの自動読み取りを実現してみました。

# 環境
- Intel Core i7-8700K
- 48GBメモリ
- GTX 1080Ti
- PyTorch 1.7.0
- Yolo V5

# 学習データセット

まずは学習データセットを準備します。Raspberry Piに7セグLEDディスプレイを接続し、乱数を表示して撮影するプログラムを作成します。
参考: [Raspberry Pi＋MAX7219で7セグLEDディスプレイ](https://qiita.com/tutu/items/027bafbe43b3dfcccf0c)

2,000枚ほど撮影した後、アノテーションツール([LabelImg](https://github.com/tzutalin/labelImg)など)を使用して、0〜9、表示なしの合計11クラスをアノテーションします。アノテーションした画像は次のようなものになります(暗いのは誤って撮影中に部屋の照明を落としたため笑)。

![test_batch0_gt.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109483/3289bb52-22c3-8b98-08fc-a34f60f73226.jpeg)

# Yolo V5
## 準備
Yolo V5をダウンロードします。

```
$ git clone https://github.com/ultralytics/yolov5.git
```

datasets以下に適当にフォルダを作りtrain/validに画像を分けて、以下のようなdataset.yamlを作成します。

```dataset.yaml
train: datasets/7seg/train/images
val: datasets/7seg/valid/images

nc: 11
names: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "_"]
```

## 学習
あとは、適当に環境に合わせてバッチサイズを変えたり、エポック数を指定します。今回は４つあるモデルのうち、Largeモデルで試してみました。

```
$ python3 train.py --img 320 --batch 32 --epochs 300 --data ./datasets/7seg/dataset.yaml --cfg ./models/yolov5l.yaml --weights '' --device 0
```

## テスト
テストは、学習データセットとは別に撮影した動画を使って認識させてみます。

```
$ python3 detect.py --weights runs/exp0/weights/best.pt --img 320 --conf 0.4 --source datasets/7seg/7seg.avi
```


### 結果
多少のカメラ移動でも問題なく検出できています。多少オーバフィッティングしていると思いますが、対象の計器ごとモデルを作っても良いので十分使えそうです。

![7seg.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109483/eacdfbde-14d0-5640-8878-5013395f99f7.gif)

# まとめ
7セグLEDの認識は簡単な部類かと思いますが、Yoloの性能の高さにあらためて感心しました。引き続き新しい技術を駆使してレガシーシステムをデジタル世界につないでいきたいと思います。
シャローコピーとディープコピー違い

### シャローコピーとディープコピー違い

### シャローコピー

コピー元のオブジェクトとコピー先のオブジェクトがメモリ上の同じデータ(インスタンス変数)を参照

### ディープコピー

オブジェクトのみのコピーではなく、オブジェクトとメモリ上のデータ(インスタンス変数)の両方をコピーする

### シャローコピーの挙動

シャローコピーの挙動を少し試す

```js
// シャローコピー
nameList = [{"name": "name"}];
copyNameList = nameList.slice(0); // シャローコピー

nameList[0]["name"] = "change_name"; // オブジェクトの更新
console.log(nameList);
console.log(copyNameList); // 元々の配列は更新したら、copyNameListも更新される
```

### ディープコピーの挙動

ディープコピーの挙動を少し試す

```js
// ディープコピー
let nameList2 = [{"name": "name"}]
let copyNameList2 = nameList2.map( list => ({...list})) // ディープコピー
nameList2[0].name = "change_name" // オブジェクトの更新
console.log(nameList2)
console.log(copyNameList2) // 元々の配列は変更しても、copyした配列は変更されない
```


### 参考

https://qiita.com/yamayamasan/items/8f4fdc47f538c7027373
https://teratail.com/questions/294137
<https://itsakura.com/it-program-shallow>
<https://kurochan-note.hatenablog.jp/entry/20110316/1300267023>
https://qiita.com/k_2929/items/0ae5085d61fa5598c76e
[無料] AWS EC2 + RDS + Flask でWebアプリを作り HTTPS 化する [その11: HTTPS化完了]

[その10](https://qiita.com/nozomiyamada/items/5b01b3ca38bf79d70eb0)からの続きです、最終回です。

## ロードバランサーへのルーティング

[その8](https://qiita.com/nozomiyamada/items/007935e616f7d39577aa) の後半で HTTP でのルーティングをしたのと同様の手順でドメイン名とロードバランサーの紐付けを行います。**Route 53** のホストゾーンに入ります。以下のような感じになっています。

もしその8 で作った Type: A のレコード（www.hogehoge.ga で実験したやつ）がまだ残っていれば、一旦 **Delete record** で削除して3つだけ残して下さい。

**Create record** します。
![Screen Shot 2563-12-14 at 16.32.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/50b133a4-9828-abe6-e81b-a03211c90756.png)
**Record name** は その8 の時同様に好きなホスト名を入れて下さい。ここからは設定方法が異なります。まず **Alias** にチェックを付けて下さい。

**Route traffic to** の部分から、**Alias to Application and Classic Load Balancer** > **自分のリージョン** と選択すると、3列目に先ほど作成したロードバランサーが候補として出てくるはずです。これを選択し、**Create records** します。
![Screen Shot 2563-12-14 at 16.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/d606d3d6-8e33-e62d-f880-9a968dbf48c9.png)
レコードが4つに増えました。
![Screen Shot 2563-12-14 at 16.44.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/b4ac431c-09cf-ae1e-fa5a-9777308268f6.png)

## HTTPS化完了

実はこれで設定は全て終わりです。この状態でURLバーに `https://www.hogehoge.ga` と入力してみます。ちゃんと🔒マークが出ているのがわかります。この記事をアップする前にレコードを削除したので、申し訳ありませんが既にアクセスできません。
![Screen Shot 2563-12-14 at 16.46.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/45f77cb6-3931-66ac-af53-e37ac4f8412a.png)

AWS側での設定ですることはもうありません、後はひたすらアプリを開発してデプロイするのみです。ただ、[その6](https://qiita.com/nozomiyamada/items/4a0686485835bb0ff7ed) でも軽く触れましたが、Flask をそのままアップロードしているだけです。次回はおまけとしてアプリケーションサーバーである gunicorn の導入を行います。
[Swift] 選択されたcollectionViewCell内のLabel値を遷移先のTextFieldに渡す方法

#はじめに
今回はタップによって選択されたcollectionViewCell内のLabel値をsegueを使った遷移での遷移先のTextFieldに渡す方法を記録しておきたいと思います。ちなみにNavigationControllerとsegueを用いて画面遷移をしています。
#開発環境
```
macOS 11.0.1
Xcode version 12.2
Swift version 5.3.1
```
#実装したいこと
###前提として
まず、値を渡すコードを書く前の段階で下のような状態で、5個のcellのそれぞれラベルに[あ][い][あ][え][お]が順番通りに代入されています。
これに[あ]のcellを押したら[あ]が、[い]のcellを押したら[い]というふうに選択したcellの内容を遷移先に渡すコードを書きたいと思います。

```swift:FirstViewContoroller
import UIKit

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource{

    @IBOutlet weak var collectionView: UICollectionView!
    
    var array = ["あ","い","う","え","お"] //今回の配列の数は5個

    override func viewDidLoad() {
        super.viewDidLoad() 
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

         return array.count //cell数を配列の数に設定

    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for:indexPath)
        //タグ付けされたCell内のLabelにarrayのString値を入れる
        var arrayLabel = cell.contentView.viewWithTag(1) as! UILabel
        arrayLabel.text = array[indexPath.row] 
        
        return cell
    }
}
```
###遷移元のControllerには下のコードを書き加える

```swift:FirstViewController
    //選択されたラベル値を受け取る
    var selectedArray:String?
   
    //didSelectItemAtでcellを選択した時の挙動を書く
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        //選択したCell内のラベルがselectedArrayに代入される
        selectedArray = array[indexPath.row]
        //画面遷移
        performSegue(withIdentifier: "toNext", sender: nil)

    }

    //segueの準備
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        let nextVC = segue.destination as? NextViewController
        //遷移元のselectedArrayを遷移先のselectedLabelに渡す
        nextVC?.selectedLabel = selectedArray
     
    }
```
###遷移先のNextViewControllerに書くこと

```swift:NextViewController
import UIKit


class NextViewController: UIViewController {

    @IBOutlet weak var textFiled: UITextField! 
    //遷移元で選択された値が入ってくる 
    var selectedLabel:String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //渡ってきた値をTextFiledに渡す
        textFiled.text = selectedLabel
        
    }
```
このように書くことで、選択したcell内のラベル値を遷移先に渡す事ができます。
#よくある間違い
　NextViewControllerでは、インスタンス変数として**var selectedLabel:String?**を設定し、そこに遷移元の値を渡してします。しかし、そんなことせず直接textFiledに値を渡せばいいと思う方もいるかもしれません。僕もそうでした。
　このやり方は間違いとなっています。実際に書いてビルドしてセルを選択してみると**Unexpectedly found nil while implicitly unwrapping an Optional value**というエラーでてきます。簡単に言うと予期せぬnilがあるよ！という意味です。nilとは簡単に言うと空っぽという意味です。
　この原因はおそらく遷移元の取得した値を遷移先のtextFiledに渡そうとする時に、遷移先のUITextFiled部品のインスタンスが存在しないためだと考えられます。
#参考したサイト
https://capibara1969.com/1060/
#まとめ
今回は画面遷移時の値の渡し方についてでしたが、自分が勉強した内容を随時更新していきます！
少しでも参考になった方はLGTMをお願いします！！
【初心者】PHPで絶対値を出力したい

# PHPで絶対値を出力したい
PHPで計算した結果を絶対値として出力したい時…

```php
echo abs($式);
```
この$式の部分の結果が絶対値として出力される。

### そもそも絶対値って…？
そもそも絶対値ってなんだろう？とはならないが一応メモしておく。

絶対値とは：実数の符号を無視して得られる非負の値

簡単に言えば、-1の場合はマイナスの符号を無視して1と表記しますよということ。

いずれにしても絶対値の出力方法は使いどころ満載な気がするから覚えておきたい。
[php] returnの使い方

#この記事について
今回は初心者の私が躓いたreturnについて初心者でもわかりやすく説明していきます。
#returnとは？
簡潔にいうと**結果を変数に返すということです。**いや、どういうこと？となると思います。詳しく説明するためにはまず関数が何か理解する必要があります。
#関数とは？
関数とは、**頻繁に行う処理をまとめてもののことです。**関数でまとめたものはそれぞれに名前をつけることができて、名前を使い呼び出すことで処理結果や値を得ることが可能となります。

*  使い方

関数でまとめる際はfunction();を使います。例えば、

``echo ‘私の名前は山田太郎です。‘``を表示したかったとする。どうするかというと

```
<?php
function Name() {  //Nameは関数名
 echo ‘私の名前は山田太郎です。’ //{}ブロックという中の処理
}
Name(); //関数の呼び出し
?>
```
とすると{}で括った中の処理が名前で呼び出すことが可能になる。また、表示される名前だけ変えたい時もあるかもしれません。その場合、引数というものを使います。

* 引数の使い方

```
<?php
function Name($fullname) { //②()内に書かれたものが引数
 echo ‘私の名前は’ . $fullname . ’です。’ //③
}
Name(‘山田太郎’); 
//①下のものとそれぞれ()内で書いたものが表示結果として反映される。
Name(‘山田花子’);
?>
```
引数とは関数を引き出す時に使う値のことを指します。①から順番に引数は処理されていきます。よって、関数を呼び出す際に書いた()内のものがそれぞれ処理されていくことになります。
#再び、returnとは？
関数内の結果を再び値として呼び出し使うことができます。その時使うのがreturnです。

* 使い方

例えば、1、2を関数内で足した処理結果を変数に代入して使いたいとします。

```
<?php
function plus($int1, $int2) {
 $sum = $int1 + $int2;
 return $sum; // 処理結果の3が格納されている。
}
$sum = plus(1, 2);
echo ‘加算結果は’ . $sum . ‘です。’
?>
```
ブロック内の処理がreturnしたことにより$sumに返り、変数として別の処理で扱うことを可能としている。ここで注意点として、return文を使うと処理は呼び出し元に戻るので以降の処理は実行されないという点に気をつけてください。
#終わりに
長くなりましたが、以上がreturn文の使い方と処理のされ方です。至らない部分があったと思いますが、自分なりに学んだ点をまとめてみました。
Googleの「AppSheet」で簡単なアプリを作ってみた

## ■ はじめに
仕事で、ローコード／ノーコード開発ツールの選定を任されたこともあり、せっかくなので、記事にして残しておくことにした。
いろいろなローコード／ノーコード開発ツールで同じものを作って比較してみようと思う。

## ■ Y:やったこと

いろいろデモやら、動画を見てみてノーコード／ローコード開発ツールは、ワークフローのアプリ構築に向いていそうなので、自社の休暇申請のワークフローを参考にアプリを作ってみようと思う。

### [仕様]
- 役割：申請者、承認者
- ワークフロー：申請者が休暇申請し、承認者が承認する
- 画面

|画面名|表示項目|入力項目|ボタン|備考|
|:--|:--|:--|:--|:--|
|申請画面|入力項目参照|申請者|なし||
|||休暇種類||リスト表示|
|||休暇期間(開始、終了)||カレンダー表示|
|||届出理由|||
|||備考|||
|承認画面|申請画面と同様|コメント|承認||

一時保存や、差戻し機能も必要かもしれないけど、ひとまず上記機能を作成する

---

#### ○ ログイン
![01_ログイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/51539747-e836-a699-45f5-2041af180679.png)


#### ○ 作成アプリ選択
![02_アプリ選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/d5881190-6849-b8ef-e3cb-678609c5265f.png)

![02_アプリ選択2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/b312df0b-91f3-24b3-de7b-39c43561f746.png)

![02_アプリ選択3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/33bc9f0b-98d2-59d5-d8cd-53e7c66f5db5.png)

#### ○ スプレッドシート作成
![03_スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/ab2599e9-b5fd-cd67-c891-fa4048299f6d.png)

![03_スプレッドシート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/ea53918c-11e4-3b4d-45f8-e99545caa998.png)

#### ○ テーブル定義
![04_teble.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/3b921eca-8ce3-9ed2-23c9-dc3c1f5a7861.png)

![04_teble2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/6c60b969-f013-cd10-b371-bc2869659385.png)

#### ○ 完成品
![05_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/8a4f4902-e598-61e6-58a7-5ed3a5004aef.png)

![05_app2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154223/f8be7bde-3e37-882c-bb27-2a4ad6c44116.png)

## ■ W：わかったこと

__[良かった点]__

- スプレッドシートから自動的に作成されるレイアウトはかなり優秀
-  スプレッドシート 1シートのデータ追加・更新・削除のアプリは簡単に作れた

__[いまいちな点]__

- スプレッドシートが先に必要だと気が付くのに時間がかかった
- ヘルプも含めて英語が多く、時間がかかる
- 慣れが必要

## ■ T：次にすること

今回は以下の機能が出来なかった。もっと調査が必要。

- Listボックスの表示
- 申請→承認のワークフロー

## ■ まとめ

初めてノーコード開発ツールを触ったが、最近は組込系の開発に関わっていて、Web系のことをほとんど知らないエンジニアがいろいろ詰まりながらも短期間でWebアプリを作成出来たのはすごい。
ノーコードなので当たり前だが、そもそも言語の文法を覚えなくても作れるのがいい。

お客様との打合せでの認識合わせや、デモ、紙芝居で使ったりも出来るかも。
打合せでお客様が言ったことを打合せ中に実現したりすると、お客様を感動させられるかもと思ったりした。
やっぱりお前らのクソアプリは間違えている in 2020

（今年もこのタイトルでいいのだろうかと悩んでいたが、やっぱり、謙遜でクソアプリ言っている人を見かけたので、このタイトルのままで行こうと思った。）

これはクソアプリ2アドベントカレンダー12日目の代理投稿記事です。

##  最初に

今年もやってまいりましたクソアプリアドベントカレンダー！！
自称、クソアプリソムリエから言わせて欲しい。

**みんな！！自信もって！！**

簡単に作ったからクソアプリですとか、普通に便利そうだな、使ってみたいなと思ったもん。
ちゃんと作ってないから簡単だからって、自分のアプリを貶めてもだれも幸せにならないよ
本当のクソアプリというのは、ほんと、クソなんだ。
未来すら感じないクソなんだほんと。
本当のクソアプリは、ぶっちゃけ、こんなお祭りじゃないとイイネもストックも、もらえないものはずなんだ。
だって、寿司が回るだけのアプリに何の価値があるんだい？？どこに利便性を感じるんだい？
参考→https://qiita.com/endo_hizumi/items/2de99fafa424e04b4375

## 本題

うっかりアドベンドカレンダーの登録をわすれて埋まってしまったけど、ヒズミは諦めなかった・・・！
きっと・・・きっと！書くの忘れて開けてしまう人が出てしまうはず・・・！
だから、誰かが開けた穴を僕が塞ぐよ！！

そして、ついにきた・・・12日目！！
["待"　っ　て　い　た　ぜ　ェ　！　！・　・　・　こ　の　"　瞬　間　（　と　き　）　"　を　よ　ぉ　！　！　](https://www.google.com/search?q=%E5%BE%85%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E3%81%9C%E3%83%BB%E3%83%BB%E3%83%BB%E3%81%93%E3%81%AE%E7%9E%AC%E9%96%93%EF%BC%88%E3%81%A8%E3%81%8D%EF%BC%89%E3%82%92&client=firefox-b-d&sxsrf=ALeKk03zQz3i0C588D9mhj_nITMv3_2PPg:1607390495371&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjfrPebnL3tAhUaBogKHYuyB_0Q_AUoAXoECBEQAw&biw=1693&bih=947)


やはり、人類には、絶望するくらいなにも目的を持たないクソアプリが必要なんだ。そうに違いない！（ぐるぐる目）

それと同時に、人類には寿司が必要なんだ！！
そう確信しているッー！！
だから、今年もせっせと作ったぜェ！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/2427e4a7-9a5e-2d8f-2591-37409b84aa7a.png)

**　茶　碗　蒸　し　が　回　る　W　e　b　ア　プ　リ　を　よ　ぉ　！　！　**
https://sushi-planet.netlify.app/

寿司衛星付きです！！（増減します！！）

自転する茶碗蒸しの周りを寿司衛星が公転するところにこだわりました。


### 遊び方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/6ae1e087-b37c-4a9c-7def-1f9d7b8bfaf0.png)

＋とーで、寿司衛星の増減ができます。

stateは現在の惑星の状態を表してます。(初期値：自転中）
これはボタンになっていまして、押すことができます。


押すとどうなるのか？


知らんのか？


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/1ebc8041-bfd9-3d69-7650-91a2e176974f.png)

**一つの惑星の命を消す覚悟・・・あなたにありますか？**

### 技術的TIPS

#### 衛星軌道を綺麗に回る寿司の作り方

実は簡単です。
茶碗蒸しの要素に寿司衛星の要素を重ねて、CSSで回してるだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/ea9f9ccb-996c-38cc-8a18-87034a6c4912.png)

以下、該当部分の抜粋

```css

#root {
  display: flex;
  justify-content: center;
  margin: 50px;
}
#planet {
  background-color: transparent;
  height: 100%;
  text-align: center;
}
#satellite {
  position: absolute;
  width: 250px;
  height: 250px;
  text-align: center;
}

```

```html
  <div id="root">
    <div id="planet">
      <img v-bind:class="state" v-bind:src="url" />
    </div>
    <Satelitte
      v-for="data of satellite_data"
      v-bind:key="data.index"
      v-bind:ref="'satelitte'"
      v-bind:speed="data.spinSpeed"
    ></Satelitte>
  </div>
```

#### 寿司を四隅に寄せる
寿司の絵文字を`display:absolute`に設定して、設置するだけです。

```css
.left_up {
  position: absolute;
  left: 0;
}

.right_up {
  position: absolute;
  right: 0;
}

.left_bottom {
  position: absolute;
  left: 0;
  bottom: 0;
}

.right_bottom {
  position: absolute;
  right: 0;
  bottom: 0;
}
```



技術の無駄遣いは気持ちイイZOY! 

　　終
制作・著作
━━━━━
 　Ⓗ Ⓩ Ⓜ
Railsでherokuにデプロイした時にエラーが起こった[備忘録]

### Herokuにデプロイした際エラーが起きました。
 git push heroku masterとコマンド入力したら
```
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/アプリ名.git'
```
となった、
heroku logsでエラー確認
赤文字でherokuに飛ぶURLが記載しておりエラーを確認すると
```
！アセットのプリコンパイルに失敗しました。
！プッシュが拒否され、Rubyアプリのコンパイルに失敗しました。
！プッシュに失敗しました
```
とありました。
```
アセット <<< railsアプリでブラウザに送信するHTML以外のファイル,画像やCSS、JavaScriptのこと
コンパイル <<< ソースコードは人間に読み書きしやすい形式の言語によって記述されているものでそれをウェブ上に反映する事ができないのでコンピュータの理解できる機械語のプログラムに変換する事。
```

コンパイルの失敗部分をエラー文で探し
JavaScriptの記述がおかしい事がわかった。それを修正しgit push heroku masterしたがエラー文が変わらない。。。なぜだ。。。

次にGit Hub desktopに注目してみた
いつもGitHub リポジトリにpushしていたはずがherokuにpushとなっていたからだ

まだGitHub上にリポジトリができていないためGitHub右上にある＋ボタンで作成し
GitHub DesktopのRepository > Repository Settings... > Remote でリモートリポジトリの URLを設定しプッシュできるようになった。

そして再度
```git push heroku master```
出力されたのは```Everything up-to-date```いつもと違うエラーが出たのでうれしかったがまだうまくは行っていない。heroku自体には反映がされていると思ったので
```heroku apps:info```で確認
```
▸ No app specified.
▸ USAGE: heroku info my-app
```
リモートリポジトリがおかしくなっているという事なので```git remote -v```
で確認すると
```
heroku	https://github.com/自身のname/アプリ名 (fetch)
heroku	https://github.com/自身のname/アプリ名 (push)
```
origin(デフォルトのリポジトリの場所(URL)の別名)が作成されていなかった
```git remote rename heroku origin```
これでherokuからoriginに変わり
```heroku git:remote -a アプリ名```
これでherokuを表すリモートリポジトリを追加できる

これでプッシュし```git push heroku master```を行った次こそは！！！
また最初の記述であった同じエラー、、、なんで？
もう一回JavaScriptのコードを見ると消したはずのコードが復活している(謎でした)
そしてまた```git push heroku master```
これでデプロイする事ができました。

###結論
RubyonRails初学者に取ってはハードなエラーでした。笑
ですがエラーをしっかり読む、仮説を立てる。諦めない！！が大事だと思いました。
あまりないエラーかもしれませんので備忘録に投稿しました。
grpc での ssl通信を実装する

## 概要

手持ちのgrpcサービスにssl通信を実装しようとして、
よく理解ができていないことがわかったので備忘録としてまとめておきます。


## 手順

### サーバ側の準備

- CAの秘密鍵を作成　(server.key)
- CAの秘密鍵で署名したCA署名を作る (server.crt)

この場合、サーバーは自身の署名を持って自分を信頼できるサーバーだと宣言するので、
この作業を自己署名と呼びます。

- Server (CA) の秘密鍵、CA (Server) の署名をgrpc サーバに渡してポートを開く


以上でサーバ側は準備完了です。



### クライアント側の準備

- CA側から署名をもらいます
- CAからもらった署名を使ってサーバーへとリクエストを送ります。

以上です。
サーバー側は、クライアント側が署名を持っている、つまりCAから信頼されているため、
そのままリクエストを許可し、レスポンスを返します。




## 参考になったウェブサイト

上の手順ですが、 githubにとてもシンプルなpythonのコードが上がっており、すぐに試すことができました。
`server.py`, `client.py`　に上記の手順に沿ったコードが書いてあるので理解が深まるかと思います。


## 出くわしたエラー

https://github.com/sandtable/ssl_grpc_example
上のgitのコードを使い、`python server.py` , `python client.py`とすると、

```
python server.py
E1214 18:44:06.473170000 123145576345600 ssl_transport_security.cc:1723] No match found for server name: localhost.
E1214 18:44:06.476632000 123145576345600 ssl_transport_security.cc:1723] No match found for server name: localhost.
```

とサーバー側から怒られる。


https://stackoverflow.com/questions/44815573/in-python-grpc-i-got-a-exception-no-match-found-for-server-name

ここにあるように、　`Common Name` に　`localhost`とすることで解決した。

```
$> make gen_key
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
Generating a RSA private key
..............+++++
....................+++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
```
HomebrewのPythonのバージョンを変える

# HomebrewのPythonがいつの間にかPython 3.9になっている

brewのアップデートが入るとPythonが勝手に3.9になる．Python 3.9は新しくて対応してないパッケージがいくつかあって不便なので，Python 3.8に戻す．

HomebrewではPython 3.8 と 3.9 は別物として扱われているのでリンクを変えれば元に戻せる．

``` zsh
$ brew unlink python@3.9
$ brew link python@3.8
```
Ruby　配列内のハッシュのソート

配列の中に入ったハッシュのソートについて書いておきます。
こんな感じで、配列の中にハッシュがあったとします。


```
array = [
  {
    :nickname  =>  "Aさん",
    :image  =>  "default_user_image.jpeg",
    :sum_size  =>  211.0,
    :max_size  =>  64.0
  },
  {
    :nickname  =>  "Bさん",
    :image  =>  "/uploads/user/image/10/C2513F3.jpeg",
    :sum_size  =>  215.0,
    :max_size  =>  50.0
  },
  {
    :nickname  =>  "Cさん",
    :image  =>  "/uploads/user/image/6/FB6D582.jpeg",
    :sum_size  =>  65.0,
    :max_size  =>  65.0
  }
]
```

`:max_size`の値が大きい順にソートしたい時。

```
sort_maxsize = array.sort_by! { |x| x[:max_size] }
sort_maxsize.reverse!
```

実行結果

```

  {
    :nickname  =>  "Cさん",
    :image  =>  "/uploads/user/image/6/FB6D582.jpeg",
    :sum_size  =>  65.0,
    :max_size  =>  65.0
  },
  {
    :nickname  =>  "Aさん",
    :image  =>  "default_user_image.jpeg",
    :sum_size  =>  211.0,
    :max_size  =>  64.0
  },
  {
    :nickname  =>  "Bさん",
    :image  =>  "/uploads/user/image/10/C2513F3.jpeg",
    :sum_size  =>  215.0,
    :max_size  =>  50.0
  }
]
```

`:max_size`に対してうまくソートできました！

## 追記

コメントで教えて頂きましたので、追記させて頂きます！！

今回の様な場合は、昇順に並べてから反転させなくても`符号反転`がスマートなようです！

```
sort_maxsize = array.sort_by! { |x| -x[:max_size] }
```

コメント頂きありがとうございました！



## 参考
[Ruby リファレンス　Array#sort](https://docs.ruby-lang.org/ja/latest/method/Array/i/sort.html)

[Ruby リファレンス　Array#reverse](https://docs.ruby-lang.org/ja/latest/method/Array/i/reverse.html)
【JavaScript】location.pathnameプロパティでURLのパス名を扱う方法

#プログラミング勉強日記
2020年12月14日
location.pathnameプロパティでURLのパス名を取得したり変更したりする方法をまとめる。

#location.pathnameプロパティとは
　現在のページのURLのパス名を参照することができる。`location.pathname`で現在のパス名を取得して、`location.pathname="pathname"`でパス名を指定してページを遷移させられる。

　URLのパス名は、URLの中でファイルの場所を示す部分である。`https://qiita.com/mzmz__02`の場合パス名は`mzmz__02`の部分である。

#URLのパス名を取得・変更する方法

```js
// URLのパス名を取得
var pathName = location.pathname;

// URLのパス名を変更
location.pathname = "/newPath/test.html"
```


#参考文献
[location.pathname …… 現在ページURLのパス名を参照する](http://www.htmq.com/js/location_pathname.shtml)
[JavaScriptでlocation.pathnameプロパティを使ってURLのパス名を取得・変更する方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/32876)
PythonでRedshiftにpsycopg2を使ってsqlクエリをdry-run実行

#はじめに
Pythonで[psycopg2](https://github.com/psycopg/psycopg2)を使ってRedshiftにSQLクエリを実行する処理を実装していたのですが、dry-runで実行させる為にラッパークラスで実装したので、どのように実装したのか紹介したいと思います。

#ラッパークラスの実装
psycopg2をラッパーしてdry-run機能を実装します。
クエリを実行する時にcommitはせず、rollbackさせることでdry-runを行います。

```python:wrapper.py
import os
import psycopg2
import re

class DBWrapperClass:

    __is_dryrun = False # デフォルトはdry-run実行しません

    def __init__(self):
        self.__connection()

    def __connection(self):
        # DBの接続情報です適宜変更してください
        dsn = {
            "host" : os.environ.get('DB_HOST'),
            "port" : os.environ.get('DB_PORT'),
            "database" : os.environ.get('DB_NAME'),
            "user" : os.environ.get('DB_USER'),
            "password" : os.environ.get('DB_PASS'),
        }

        self.__conn = psycopg2.connect(**dsn)

    # with構文で引数を指定できるようにします
    def __call__(self, **kwargs):
        self.__is_dryrun = bool(kwargs['dryrun']) if 'dryrun' in kwargs else False
        return self

    # with構文でcursorを取得します
    def __enter__(self):
        self.__cursor = self.__conn.cursor()
        return self

    # with構文の終了時にcommitやrollbackを行い、cursorを閉じます
    def __exit__(self, exc_type, exc_value, traceback):
        # 例外が発生した場合はrollbackさせます
        needs_rollback = True if exc_value else False

        self.__commit(needs_rollback)
        self.__close_cursor()

        # with構文で関数のように呼び出さない場合、前回の値が引き継がれるので初期化します
        self.__is_dryrun = False

    def __commit(self, needs_rollback=False):
        if self.__conn:
            # dry-runかrollbackが必要な時
            if self.__is_dryrun or needs_rollback:
                self.__conn.rollback()
            else:
                self.__conn.commit()

    # cursorを閉じます
    def __close_cursor(self):
        if self.__conn:
            self.__cursor.close()


    # 接続を閉じます
    def close(self):
        if self.__conn:
            self.__conn.close()

    # クエリを実行します
    def execute(self, sql):
        # dry-runの場合、truncateは実行しません
        # truncateはrollbackできない為、この制御を入れています
        if not (self.__is_dryrun and re.match(r'^\s*truncate\s+', sql, flags=re.IGNORECASE)):
            self.__cursor.execute(sql)
```
psycopg2と同じようにwith構文でcursorの管理をできるようにする為、`__enter__`と`__exit__`の各メソッドにcursorに関する処理を実装しています。
また、with構文でdry-runの指定を設定できるように`__call__`メソッドを追加しています。


#ラッパークラスでdry-runを実行

```python
import wrapper

try:
    dbwrapper = wrapper.DBWrapperClass()
    with dbwrapper(dryrun=True) as db:
        # sqlをdry-runで実行
        db.execute('dry-runで実行したいsql')

finally:
    if 'dbwrapper' in locals():
        dbwrapper.close()

```
実行側ではこれだけで行えます。
今回はできるだけシンプルにする為にdry-run用の引数しか設定していませんが、autocommit等の他の設定値も引数で設定できるようにするとより便利になります。

#まとめ
psycopg2のラッパークラスを実装してdry-runの機能を追加してみました。
普段はphpでプログラムを組むことが多いのでpythonのwith構文がかなり便利だと思いました。
また、今回実装してみて思ったのがpythonにはマジックメソッドがかなり多く違う用途のクラスを実装する際はぜひ使ってみたいです。
Ubuntuのnvidia-smiが動かないときに確認すること

nvidia-driverをインストールしたのにnvidia-smiが動かなくて非常に苦しんだので、自分用のメモも兼ねてここに書き残す。

# Secure bootを無効にする
理由はわからないがSecure bootが有効になっているとnvidia-smiがエラーを吐くことがある。BIOSから無効にしよう。

# driverのインストール方法
```bash
ubuntu-drivers devices
```
で出てきた候補の中からちょうど良さそうなものを選んで

```bash
sudo apt install nvidia-driver-440
```
のようにしてインストールする。

なぜかnvidiaの公式サイトの.runファイルではうまく行かなかった。
PowerShellの日付操作

# はじめに

たまに使うと毎回調べているので、PowerShellの日時関連の処理をまとめます。
アドベントカレンダー遅刻してすみません。計画的に進めないとダメですね。

# 現在日時の取得
#### 日付

```powershell
Get-Date -DisplayHint Date
# -> 2020年12月2日
```

#### 時刻

```powershell
Get-Date -DisplayHint Time
# -> 18:03:58
```

#### 日時

```powershell
Get-Date -DisplayHint DateTime
# -> 2020年12月2日 18:04:33
```



# 文字列から日付を作成

## ParseExact

#### 基本構文

```powershell
[DateTime]::ParseExact("変換する文字列","形式", $null);
```

#### サンプル

```powershell
[DateTime]::ParseExact("20171231133355","yyyyMMddHHmmss", $null);
# -> 2017年12月31日 13:33:55

[DateTime]::ParseExact("171231133355","yyMMddHHmmss", $null);
# -> 2017年12月31日 13:33:55
```



# 指定した形式で表示

## -Format

#### 基本構文

```powershell
Get-Date -Format "変換する形式"
```

#### サンプル

```powershell
Get-Date -Format "yyyyMMddHHmmss"
# -> 20201214174433

$date = [DateTime]::ParseExact("20171231133355","yyyyMMddHHmmss", $null);
$date.ToString("yyyyMMdd")
# -> 20171231
$date.ToString("yyyy年MM月dd日 HH時mm分ss秒")
# -> 2017年12月31日 13時33分55秒
```



# 日付の加算・減算

#### サンプル

```powershell
$date = [DateTime]::ParseExact("20170615133030","yyyyMMddHHmmss", $null);

$date.AddYears(2)
# -> 2019年6月15日 13:30:30

$date.AddYears(-2)
# -> 2015年6月15日 13:30:30

$date.AddMonths(2)
# -> 2017年8月15日 13:30:30

$date.AddMonths(-2)
# -> 2017年4月15日 13:30:30

$date.AddDays(5)
# -> 2017年6月20日 13:30:30

$date.AddDays(-4)
# -> 2017年6月11日 13:30:30

$date.AddHours(5)
# -> 2017年6月15日 18:30:30

$date.AddHours(-5)
# -> 2017年6月15日 8:30:30

$date.AddMinutes(5)
# -> 2017年6月15日 13:35:30

$date.AddMinutes(-5)
# -> 2017年6月15日 13:25:30

$date.Addseconds(5)
# -> 2017年6月15日 13:30:35

$date.Addseconds(-5)
# -> 2017年6月15日 13:30:25
```

#### 

# 2つの日付の差

日付同士を引くといろいろな形式で確認できる。

```powershell
$date1 = [DateTime]::ParseExact("20170615133030","yyyyMMddHHmmss", $null);
$date2 = [DateTime]::ParseExact("20201102095548","yyyyMMddHHmmss", $null);
$date2 - $date1

Days              : 1235
Hours             : 20
Minutes           : 25
Seconds           : 18
Milliseconds      : 0
Ticks             : 1067775180000000
TotalDays         : 1235.85090277778
TotalHours        : 29660.4216666667
TotalMinutes      : 1779625.3
TotalSeconds      : 106777518
TotalMilliseconds : 106777518000
```



# 形式

| 項目         | .NET | UFormat |
| ------------ | ---- | ------- |
| 年(4桁)      | yyyy | %Y      |
| 年(2桁)      | yy   | %y      |
| 月           | MM   | %m      |
| 日           | dd   | %d      |
| 時(24時間)   | HH   | %H      |
| 時(12時間)   | hh   | %h      |
| 分           | mm   | %M      |
| 秒           | ss   | %S      |
| 曜日         | dddd | %B      |
| タイムゾーン | K    |         |



# 参考

[PowerShell Core入門 - 基本コマンドの使い方　日付を表示 Get-Date](https://news.mynavi.jp/itsearch/article/hardware/3820)
[Get-Date](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-7.1)
【秘密計算】Replicated Additive Secret Sharing とは？高速乗算可能な秘密分散法

## はじめに

この記事では、秘密分散法の一つであるReplicated Additive Secret Sharing について解説します。

秘密分散法には、大きく2つのプロトコルがあります。

1. Shamir’s Secret Sharing Scheme(シャミア秘密分散法)
2. Additive Secret Sharing Scheme(加法的秘密分散法)

今回解説する方法は後者のAdditive Secret Sharing Scheme に属する方法となります。

この記事では基本的な秘密分散法についての詳しい解説は省きます。

秘密分散法の基本的な技術は[【技術】秘密分散法とは。数式を用いて解説](https://acompany.tech/blog/technology-secrets-decentralization/)の記事を参考にしてください。

今回のReplicated Additive Secret Sharing を用いることのメリットは、3パーティである場合に非常に簡単な方法でシェア同士の乗算と加算が実現可能であることです。

それでは詳しく見ていきましょう。

## Replicated Additive Secret Sharing の方法

Replicated Additive Secret Sharing は3パーティ以上に適用できる方法ですが、3パーティの場合が最も効率が良いため、ここでは3パーティの場合について解説します。この場合(2, 3) 閾値秘密分散となり、2つのパーティが持つシェアを集めることで秘密情報を復元することができます。

あるパーティ$P_i$ が持つ秘密情報$s$ をシェア化する方法は以下です。

パーティ集合 : {$P_1, P_2, P_3$}

$s$ のシェア : {$s_1, s_2, s_3$} (ただし、$s = s_1 + s_2 + s_3$)

1. $P_i$ は乱数$s_1, s_2$ を生成し、$s_3 = s - s_1 - s_2$ を計算する。
2. $P_i$ は$P_{j\neq i}$ に$s_j, s_{j + 1}$ を送信する。ただし、便宜上$s_4$ は$s_1$ とみなす。
3. $P_{j \neq i}$ は受け取った2つのシェアを自分のシェアとする。

結果的にシェアは以下の状態で保持されます。

$P_1 : (s_1, s_2)$

$P_2 : (s_2, s_3)$

$P_3 : (s_3, s_1)$

この場合、明らかに2つのパーティが持つシェアを足し合わせることで、秘密情報$s$ が復元できることが分かります。

このように、各パーティがシェアのレプリカを保持する仕組みであることから、"Replicated" という名称になっていることが理解できます。

## 加算と乗算の方法

加算と乗算の方法を見ていきます。

まず、シェア同士の加算については明らかに準同型性を持っているため、各パーティがローカルで加算を行うことで実現できます。

また、定数による加算と乗算も同様です。

次に、シェア同士の乗算については、直接的にシェア同士を乗算することはできません。したがって、以下に説明するような方法を用いて実現します。

秘密情報$a$, $b$ を用いて$c = ab$ となる$c$ のシェアを計算することを目指します。

$a$ のシェア : {$a_1, a_2, a_3$}

$b$ のシェア : {$b_1, b_2, b_3$}

1. $P_i$ は$u_i = a_ib_i + a_ib_{i+1} +a_{i+1}b_i$ をローカルで計算する。
2. $P_i$ は$u_i$ を$P_{i - 1}$に送信する。ただし、便宜上$P_0$ は$P_3$とする。
3. $P_i$ は$c$ のシェアとしてそれぞれ$c_i = u_i, c_{i+1} = u_{i + 1}$とする。

この時$c$ は以下のように整理できる。

$$\begin{array}{ll} c&= (a_1 + a_2 + a_3)(b_1 + b_2 + b_3)\\ &= a_1b_1 + a_1b_2 + ... + a_3b_2 + a_3b_3 \\ &= u_1 + u_2 + u_3 \\ &= c_1 + c_2 + c_3 \end{array}$$

結果的に計算結果のシェアは以下のように保持されます。

$P_1 : (c_1, c_2)$

$P_2 : (c_2, c_3)$

$P_3 : (c_3, c_1)$

この場合、明らかに2つのパーティが持つシェアの値を足し合わせることで$c$ が復元できることが分かります。

したがって、$c=ab$ となる$c$ のシェアを計算し、各パーティがシェアを保持することができました。

以上の方法を用いることで、Replicated Aditive Secret Sharing では乗算と加算を実現しています。ただし、パーティ数$N$に応じてシェアのデータ数、通信回数が$O(N^2)$で増加するため、今回紹介した3パーティでの適用が最も推奨されます。

## まとめ

この記事では、Replicated Additive Secret Sharing について解説しました。

まとめは以下になります。

- Replicated Additive Secret Sharing はAdditive Secret Sharing Scheme の一種。
- Replicated Additive Secret Sharing を用いてシェア同士の乗算と加算が簡単に実現できる。
- 3パーティ以上の場合に適用できる。
- ただし、3パーティの場合に最も効率が良い。

## 参考

[https://eprint.iacr.org/2017/908.pdf](https://eprint.iacr.org/2017/908.pdf)

[https://link.springer.com/content/pdf/10.1007/978-3-540-30576-7_19.pdf](https://link.springer.com/content/pdf/10.1007/978-3-540-30576-7_19.pdf)

[https://homes.esat.kuleuven.be/~nsmart/FHE-MPC/LSSS-MPC.pdf](https://homes.esat.kuleuven.be/~nsmart/FHE-MPC/LSSS-MPC.pdf)

[https://books.google.co.jp/books?id=pKJoDwAAQBAJ](https://books.google.co.jp/books?id=pKJoDwAAQBAJ)
AzureAutomationでスマホからazureVMを起動／停止⇒Discordに起動／停止の通知してみた1

#はじめに
Azure上に作ったゲームサーバをスマホからワンタッチで起動出来たら便利だなーと思ったのがきっかけです。
備忘録としてつらつら書いていきます。

※AzureVM作成方法は割愛します

#準備するもの
- AzureVM（今回はLinuxOS）
- IFTTT
- Discord

#VM起動/停止⇒起動/停止の通知までの流れ
起動/停止の動きは基本的に同じですが、起動用と停止用で別々のRunbookを用意する必要があります。

- VM起動
![起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/1eddb253-920b-ea68-3d41-2835d504cefe.png)
①　IFTTTでVM起動用Runbookに作ったwebhookのURLにPOSTリクエストを送る
②　webhookからRunbookを実行
③　Runbookから対象のAzureVMに起動命令
④　VM起動
⑤　VMのステータスをRunbookに返す
⑥　Discordに作成したwebhookのURLにVMのステータス、メッセージをPOST


- VM停止
![停止.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/b6cec601-e326-f67c-25f3-b38be42a4304.png)
①　IFTTTでVM停止用Runbookに作ったwebhookのURLにPOSTリクエストを送る
②　webhookからRunbookを実行
③　Runbookから対象のAzureVMに停止命令
④　VM停止
⑤　VMのステータスをRunbookに返す
⑥　Discordに作成したwebhookのURLにVMのステータス、メッセージをPOST


#今日はここまで
AzureVM起動/停止用Runbookを作成する部分は長くなりそうなので一旦ここまでにします。

続きは[こちら](https://qiita.com/aki_4649/items/347fb7e21d5e58f2e83e)
２次元リストで、各行のトップ３の値のインデックスを取得

重複がない前提のコードです。

仕事で使おうと思ったけど、重複があるとダメなので

```python
list_2d = [
    [1, 3, 5, 2, 4],
    [2, 4, 5, 3, 1],
    [6, 7, 8, 9, 2],
    [4, 8, 2, 6, 1],
    [7, 2, 9, 4, 5],
    [7, 9, 8, 5, 3],
    [4, 7, 2, 1, 3],
    [9, 3, 6, 5, 8],
    [0, 3, 7, 8, 2],
    [3, 7, 2, 5, 6]
    ]
    
# 並べ替える(大きい順)
ordered_list = [sorted(l, reverse=True) for l in list_2d]
print('ordered_list = \n', ordered_list, '\n')

# 左から３番目までを抜き出す（ベスト３が残る）
ordered3 = [l[:3] for l in ordered_list]
print('ordered3 = \n', ordered3, '\n')

# 各行における１位、２位、３位のインデックスを取得
# （先ほどのベスト３のリストの値をキーに、元のリスト内のインデックスを取得）
first_indexes = []
second_indexes = []
third_indexes = []
for i in range(len(list_2d)):
    first_indexes.append(list_2d[i].index(ordered3[i][0]))
    second_indexes.append(list_2d[i].index(ordered3[i][1]))
    third_indexes.append(list_2d[i].index(ordered3[i][2]))

print('１位のインデックス: ', first_indexes)
# １位のインデックス:  [2, 2, 3, 1, 2, 1, 1, 0, 3, 1]
print('２位のインデックス: ', second_indexes)
# ２位のインデックス:  [4, 1, 2, 3, 0, 2, 0, 4, 2, 4]
print('３位のインデックス: ', third_indexes)
# ３位のインデックス:  [1, 3, 1, 0, 4, 0, 4, 2, 1, 3]
```
[Ruby] 配列から要素を取り出しての計算

## 一言
今日からまた朝活復活
朝活続けるためにルールで自分縛り、Twitterで何かしら朝の活動をつぶやく

続けば良いが・・・。
それでは本題

## 配列から要素を取り出して計算

今日の投稿も以前に解いた問題の2回目に挑戦・・・。
今回のお達しは「配列内の数字を加算せよ。但し、配列内にある同じ数字は除外して計算。同じ数字は除外するので全部同じ数字の場合は0となる」

※出力例
number([3,3,3]) => 0
number([3,2,3]) => 2
number([3,4,3,6,7,9,3,2,5]) => 33 

こんな感じに出せと。

で、重複した要素を取り出して足せばいいやと考え、「uniqメソッドとsumでいけるかな？」と思い、使ってみたが、結果できず・・・。

簡単にuniqメソッドについて解説
>uniqメソッド
>以下のような配列があるとする
>a = [1,1,1,2,3,4,5,5,5]
>uniqを使うことで、重複した数字を除き、新しい配列を返す
>p a.uniq => [1,2,3,4,5]

参考　[uniqメソッド　公式レファレンス](https://docs.ruby-lang.org/ja/latest/method/Array/i/uniq.html)

確かに重複は取り除けたけれども・・・重複していた数字はすっきりはしたものの１つは残っちゃってて、一緒に加算してしまうから結果思い通りの出力ができない。

回答拝見

```ruby
def number(nums)
 new_array=[] #取り除いた配列を新しい配列に入れる用

 nums.each do |num|
  i = 0
  nums.each do |n| 
   if num == n 
    i += 1
   end
  end
#①[4,5,4]だとまず最初は「num=4,5,4」となる
#最初のnumは「num=4」となり、nが「n=4,5,4」となる
#次にnumは「num=５」となり、nが「n=4,5,4」
#最後にnumは「num=4」となり、nが「n=4,5,4」
#numとnが同じ数字の時にカウントされる（重複した時）

  if i < 2
   new_array << num
  end
#iのカウントが１の場合は条件に合うので、[new_array]という配列に追加される。
#iのカウントが2の場合は条件に合わない(4は[i=2]となる)

 end
  sum = 0
  new_array.each do |i|
    sum += i
  end
#new_array配列内の合計

  puts sum #出力
end

① number([4,5,4]) => 5
② number([3,4,3,6,7,9,3,2,5]) => 33 

```

もっとシンプルにできないか、ない頭で考えたが頑張って最後の計算をsumメソッドを使うくらいしか思いつかず・・・。

>puts new_array.sum

こんな感じ

もっと簡単に出せたり、簡単じゃなくても他の方法があればコメントいただけると嬉しいです。
Gatsby内でアイコンを扱う

#アイコンを扱うためにreact-fontawesomeをインストールする

```
yarn add @fortawesome/fontawesome-svg-core
```

```
yarn add @fortawesome/react-fontawesome
```

```
yarn add @fortawesome/free-solid-svg-icons
```

```
yarn add @fortawesome/free-regular-svg-icons
```

```
yarn add @fortawesome/free-brands-svg-icons
```

#ファイル内でアイコンを使えるようにする

 ```
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
Import {使いたいアイコンをimportする} from "@fortawesome/free-solid-svg-icons"
///
<FontAwesomeIcon icon={使いたいアイコン名} />
```

#アイコンの拡大表示を防ぐ
アイコンが拡大表示されるのを塞ぐために、CSSファイルよりも先にFontAwesomeのCSSを読み込む

```
import "@fortawesome/fontawesome-svg-core/style.css" *1
import {config} from "@fortawesome/fontawesome-svg-core" *2
config.autoAddCss = false *2

*1:FontAwesomeのCSSを先読みする設定
*2:FontAwesomeのコンポーネント内でCSSを適用しないようにするための設定 
```




####参考文献:
Webサイト高速化のための静的サイトジェネレーター活用入門　GatsbyJSで実現する高速＆実用的なサイト構築
FortAwesome/react-fontawesome  https://github.com/FortAwesome/react-fontawesome
HTML/CSSだけで、非平行のオシャレなヘッダーを作る方法


ポートフォリオの作品としてLP（ランディングページ）を制作する際、ヘッダーを普通の平行型ではなく、非平行にすることでオシャレなヘッダーになるのではないかと思い・・・

　
**◆イメージ**
![082.com.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952495/94139d32-bd1f-eff9-653e-36ee8f1552a8.jpeg)
こんな感じで ヘッダーの背景画像を斜めにしてみたので、その結果を自分用にまとめます。

　
## コード

```HTML:HTML
<div class="header__bg"></div>
```

```CSS:CSS
  .header__bg {
    background-image: url("画像名");
    transform: skewY(-6deg);
    transform-origin: top left;
    box-sizing: border-box;
  }
```

CSSのtransformプロパティで、画像部分を傾斜したり、回転できたりすることを学んだ。
今回は`skewY`で`-6deg`（degは度数）傾斜させました。
画像を傾斜させることで上部に空白ができてしまうので、
それを`transform-origin: top left;`で調整しています。

　

## まとめ
非平行ヘッダーは最近色んなサイトで流行している手法なようです。
一気におしゃれになった感じがします！
SVGを使った方が色々対応できそうですが、今回は学習不足ということで、HTML/CSSのみで作ってみました。
SVGを使用すれば色んな非平行ヘッダーが出来そうなので、挑戦してみたいです！
　

## 参考サイト様
[斬新なのに効果的！最近流行している「非平行ヘッダー」の作り方](https://ferret-plus.com/6472)
[Oracle Cloud] Region の追加方法

# はじめに

Oracle Cloud Infrastructure(以下 OCI) では、デフォルトではホームリージョンだけ使える状態に制限されています。Tokyo と Osaka を使って DR 対策を行う、といったユースケースで複数の Region を使うことがあります。今回は、複数 Region を使うための手順を紹介します。



# Service Limit の確認

Service Limit 上限で、Region の数を1に制限されていると、複数のリージョンが使えません。Service Limit の上限を確認しましょう。

![1607934814682.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/e22df181-0c7a-0749-3781-04fd232ded52.png)



Regions の Service Limit が 1 になっている場合は、画面上部の request~~~ のところから、Service Limit の上限緩和申請が出来ます。

![1607935016205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/04d3cdf4-79f9-9114-0fa6-32174fc26e42.png)



# Region の追加

Service Limit の上限緩和後、Region の追加をしていきます。画面右上の Manage Regions を選択します。なお、Region の追加そのものはお金はかかりませんが、追加した Region で Compute Instance などを構築すると、もちろんお金が掛かるのでご注意ください。

![1607935069033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/0f49db71-5e2e-fcb4-71b9-3b4a3882bc89.png)



追加したい Region を Subscribe します。

![1607935108054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/206fbf2a-c3a0-3553-a6d4-b53d66fde321.png)



Subscribe を押すと、数分後に該当の Region が使えるようになります。

![1607935132541.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/3ea48606-3752-9981-3c7c-80007579e0db.png)
Raspberry Pi4 VNC接続できない　Raspberry Pi「cannot currently show the dekstop」2020/12

##HDMI接続を外すとVNC接続できない
本番環境でテストしようとしたら、VNC接続ができなくなったので備忘録的記事。

VNC接続したら、「cannot currently show the dekstop」という文字が以下のように出現。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530814/1d178c8e-f58d-f901-09be-13c3154e5be8.png)

以前からHDMI接続を外すとVNC接続できなくなる様子。
※参考記事
[Raspberry Pi「cannot currently show the dekstop」](#https://qiita.com/atsuyuuki/items/0f8d0a9d9018c31e1b15)

Resolutionで解像度の設定をすればVNC接続可能らしいが、
参考記事は若干Versionが古いためかSSH接続でconfigを実行しても
```$ sudo raspi-config```
↓
```7 Advanced Options > A5 Resolution```は存在しない。

##Resolutionの場所と対処方法

```2 Display Options > D1 Resolution > DMT Mode 85 1280×720```

このように設定したあとに再起動。

無事HDMI接続なしでVNC接続完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530814/d31038f1-0fdd-9ee7-0117-19e0d0730a32.png)

##最後に
最初は故障と思い初期化してしまいました。
エラーが生じた場合はググることを神に誓った瞬間でした。
今後は必ずGoogleに相談するようにします。
AssumeRoleを使ったAWS ProfileをAmplifyプロジェクトに設定する

# 概要
Amplify CLIのバージョンによってはAWSアカウントを跨いだAssumeRoleを行ってinitすると、AmplifyプロジェクトがAssume元のアカウントに作成されてしまうことがあります。
そんな時にAssumeRole先のアカウントをAmplifyCLIを使って管理する方法をまとめます。

# 前提
`~/.aws/credential`と`~/.aws/profile`が設定されている

# AssumeRoleを使わない時
一応AssumeRoleを使わない、通常時のプロジェクト作成方法もまとめます。

プロジェクト作成時コマンドを実行

```
amplify init
```

質問に答えていく

```
? Enter a name for the project SampleAmplifyGraphql
? Enter a name for the environment dev
? Choose your default editor: None
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
```

答えていくと、以下のようにAWS profileを使うか聞かれるのでYを答える

```
? Do you want to use an AWS profile? Yes
```

どのプロファイルを使うのか、`~/.aws/profile`のリストが表示されるので、使用したいものを選ぶ

```
? Please choose the profile you want to use admin
```

これでデプロイに使用するAWS Profileが設定できた

# AssumeRoleを使う場合
プロジェクトの作成だけCLIではなくAWSコンソールから作成します。
作成したプロジェクトに後からProfileの設定を行います。

## クラウドににプロジェクトを作成する
- `New App` -> `Create app backend` から適当なプロジェクト名を入力して作成

## ローカルにプロジェクトを作成する
- 作成したプロジェクトの `Open admin UI` からバックエンド管理画面に移動
- 右上にある `Local setup instructions` をクリックした時に表示されるコマンドをコピー
- ターミナルから先ほどコピーしたコマンドを実行
- 質問に答えていく
    - ここではAWS Profileの設定について質問されない

```
? Choose your default editor: None
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
? Do you plan on modifying this backend? Yes
```

## プロジェクトに使用するAWS Profileを設定する
コマンドを実行

```
amplify configure project
```

質問に答えていく

```
? Enter a name for the project SampleAmplifyGraphql
? Choose your default editor: None
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
? Do you want to enable container-based deployments? No
```

プロジェクトレベルの設定をするか聞かれるのでYと答える

```
? Do you want to set the project level configuration Yes
```

AWS Profileを使うか聞かれるのでYと答える

```
? Do you want to use an AWS profile? Yes
```

どのプロファイルを使うのか、`~/.aws/profile`のリストが表示されるので、使用したいものを選ぶ

```
? Please choose the profile you want to use admin
```

これでデプロイに使用するAWS Profileが設定できた
平面上の点の位置の判定の安定性について調べてみた


幾何的な計算を代数で行う（つまりコンピュータで扱えるような計算で行う）際に、ある点$p$が別の2点$q,r$のなす直線のどちら側にあるか？というのは基本的な問題である。基本的な問題であるが、有限精度での計算しか行えないコンピュータ（というか人類）には、なかなか難しい問題である。

Kettner L., Mehlhorn K., Pion S., Schirra S., Yap C. (2004) Classroom Examples of Robustness Problems in Geometric Computations. In: Albers S., Radzik T. (eds) Algorithms – ESA 2004. ESA 2004. Lecture Notes in Computer Science, vol 3221. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-30140-0_62

上の論文に出てくる具体例を使って、実際に自分でも難しさを味わってみたのでメモする。
## 問題
平面上の3点$p,q,r$が与えられたときに、点$p$が直線$q,r$のどちら側にあるか（あるいは直線上に乗っているか）を判定するプログラムを書きたい。じっくり考えると、

$$
1, p_x, p_y \\\
1, q_x, q_y \\\
1, r_x, r_y
$$

上のような行列を考えて、この行列式の符号で判定できることが分かる。具体的には、行列式が正（負）ならば、$p$は直線$qr$の左（右）側にある。ただし、**$p$が$qr$の左側にある**とは、$q$の上に立って$r$の方を観たときに、$p$が左側にあることとする。


```python
import matplotlib.pyplot as plt
import numpy as np
import itertools
import matplotlib.pyplot as plt
```


![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7973/50ca4903-6358-d311-a0b5-cb672c910581.png)


上の図のような配置のとき、$p$は$qr$の左側。このとき、上の行列式は正。
上の行列式によって、点の位置を判定する関数を実装する。


```python
def orientation(p, q, r):
    return np.sign((q[0]-p[0])*(r[1]-p[1])-(q[1]-p[1])*(r[0]-p[0]))
```

計算機の誤差の限界を以下の通りに探す。


```python
eps = 1.0
cnt = 0
while 1 + eps != 1:
    eps /= 2
    cnt += 1
print(eps, cnt)    
```

1.1102230246251565e-16 53

適当な平面上の3点$p,q,r$を固定し、$(p_x + m \epsilon, p_y + n \epsilon)$が$qr$の右側か左側かを$m,n\in\{0, \ldots, 255\}$の範囲で判定してみる。


```python
p = np.array([0.5, 0.5])
q = np.array([12, 12])
r = np.array([24, 24])
```



```python
ms, ns = range(256), range(256)
```



```python
ret = np.array([orientation(p + np.array([m*eps, n*eps]), q, r) for m, n in itertools.product(ms, ns)])\
    .reshape((-1, 256))
```



```python
fig, ax = plt.subplots()
ax.imshow(ret)
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7973/b626cf4e-47e3-da39-5fc0-a738e40b893a.png)


図のように、境界値付近で、たくさんの判定ミスをしている。この図は、右方向がx軸の正の向き、下方向がy軸の正の向きとなっていることに注意。
ちなみに、`np.linalg.det`で行列式を計算すると、結果が安定したのでついでにメモ。


```python
def orientation2(p, q, r):
    mat = np.ones((3,3))
    mat[:,:2] = [p,q,r]
    return np.sign(np.linalg.det(mat))
```



```python
ret2 = np.array([orientation2(p + np.array([m*eps, n*eps]), q, r) for m, n in itertools.product(ms, ns)])\
    .reshape((-1, 256))
```



```python
fig, ax = plt.subplots()
ax.imshow(ret2)
```

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7973/641f9ba8-d95d-a92c-9cf6-105c8dddc7a6.png)


きれい過ぎて分からないので左上を拡大


```python
fig, ax = plt.subplots()
ax.imshow(ret2[:30, :30])
```

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7973/76519b25-19be-0cd9-204b-3eb8882b9769.png)


すごい
（UE4）リスタート時に出現する謎の球体

##◇問題

![スクリーンショット 2020-12-14 17.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/97a58240-b1a6-2b50-cac0-7a612f98bbf0.png)
ゲームをリスタートさせるノードを組み、実行するとマップ内に謎の球体が出現してしまう。

##◇原因

![スクリーンショット 2020-12-14 17.52.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/81193386-44cd-a837-7af0-cb0b2694a3c9.png)
正体は、GameModeの初期設定にあるDefault Pawnというもの。
ゲームモードベースを継承したゲームモードを設定している場合、再生時にどうしても出現してしまう。

##◇解決法

![スクリーンショット 2020-12-14 17.54.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/7ff0b6e5-7424-e5f8-808c-40074f862b48.png)
ゲームモードベースでなく、ゲームモード継承のものを新しく作成、ワールド設定からGameMode overrideに割り当て、DefaultPawn Classをnoneに設定（デフォルトのゲームモードを選択していると変更不可）することで解消。

##＜補足＞
#####・ゲーム再生時には出現しない理由

![スクリーンショット 2020-12-14 18.12.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/44c0af9e-1cc3-19cc-cc41-995afb99f405.png)
↑がリスタートのノード設定。
キー入力で初めてゲームモードが呼び出される為、リスタートするまではDefault Pawnは生成されない。
vue.js / nuxt.js でsmooth scrollを実装

# 目次
・[smooth-scrollについて](#smooth-scroll)
・[vue-scrolltoを使います](#vue-scrolltoを使います)
・[pluginsに記載](#pluginsに記載)
・[ページ内リンクを作成](#ページ内リンクを作成)
・[最後に](#最後に)

## smooth-scrollについて
ページ内リンクを実装したときに「パッと」切り替わるのではなく、スクロールしながら特定の場所まで移動する機能です。
cssでは

```css
html{
  scroll-behavior: smooth;
}
```
とやれば、ページ内リンクがsmooth scrollになりますが、対応してないブラウザやosがまだまだあるのでこれを使用するのはあまり現実的ではないですねー。
その場合、実装する場合はjsを記述したりなどの対応が必要になりますが、vueでは不要ですー。

## vue-scrolltoを使います
smooth-scrollを実装するにあたって、vue-scrolltoを使用しますー。
まずはインストールしましょう。

```
yarn add vue-scrollto
```

インストールができたら、あとはpluginsにjs/tsファイルを追加しましょう

```plugins/vue-scrollto.ts
import Vue from 'vue'
import VueScrollTo from 'vue-scrollto'

Vue.use(VueScrollTo, {
  duration: 700,
  easing: [0, 0, 0.1, 1],
})
```
optionはいろいろあるので公式ドキュメント参考に。
https://vue-scrollto.netlify.app/docs/#options

今回は
・duration
・easing
を使用してます

durationはスクロールアニメーションの継続時間
easingは速度の緩急

今回はしようしなかったですが、offsetも便利そうですね。
offsetは遷移後の位置調整なので、要素の少し上にしたりしたらちょうど良かったりするかもですね。


## pluginsに記載
インストールが完了しvue-scrollto.tsファイルも作成したらあとは読み込みましょう。

```nuxt.config.ts
  plugins: [
    { src: '~/plugins/vue-scrollto.ts' },
  ],
```
読み込み場所はnuxt.configのpluginsに読み込めばokです！

## ページ内リンクを作成
読み込みまで完了したらあとはvueファイルでページ内リンクを作成すればokです。

公式ドキュメントにもありますが、

```vuejs
<a href="#" v-scroll-to="'#element'">Scroll to #element</a>

<div id="element">
    Hi. I'm #element.
</div>
```

とすれば、smooth scrollが完了しますー。
もしアンカーリンクなどをdataで持たせてる場合などは

```vuejs
<a href="#" v-scroll-to="element1">Scroll to #element</a>
<a href="#" v-scroll-to="element2">Scroll to #element</a>

<p id="element1">Hi. I'm #element.</p>
<p id="element2">Hi. I'm #element.</p>
```
```js
export default {
  data() {
    return {
      element1: '#element1',
      element2: '#element2',
    }
  }
}
```
とすればokです

## 最後に
vue-scrolltoを使用したsmooth scrollの実装になります。
思ったりよも簡単ですし、個別でjsを記述したりする必要もないので楽ですね！

それではみなさん、良いvue lifeを〜〜〜
freebsd-versionコマンドはどこからバージョン番号を持ってくるのか？

freebsd-versionコマンドはどこからバージョン番号を持ってくるのか？
ソースコードを見て調べてみることにします。

```
# file `which freebsd-version`
/bin/freebsd-version: POSIX shell script, UTF-8 Unicode text executable
```

freebsd-versionコマンドはシェルスクリプトのようなので簡単に調べることができました

freebsd-versionコマンドには```-k```、```-r```、```-u```の3つのオプションがあります。

```-k``` はインストールされているカーネルのバージョン
```-r``` は現在実行中のカーネルのバージョン（OS更新中などに-kと違う結果になる？）
```-u``` ユーザランドのバージョン

ちなみに何もオプションを指定しないと```-u```と同じになります

オプションごとに取得方法が異なるのでオプションごとに調べた結果

```-k``` はデフォルトで```what -qs /boot/kernel/kernel```の結果
```-r``` は```sysctl -n kern.osrelease```の結果
```-u``` はfreebsd-versionに埋め込まれた変数USERLAND_VERSION

でした。おしまい。
社内向けクイズアプリを作ってみる Vol.2 [テーブル編]  #PowerApps #decode夏まつり

# この記事は

社内向けクイズアプリを作ってみるシリーズの第二弾です！
decode夏まつりで作ったアプリを、社内向けクイズアプリとして改造していく内容となっています。

[社内向けクイズアプリを作ってみる Vol.1 #PowerApps #decode夏まつり](https://qiita.com/rnakamuramartiny/items/ac025815a7f3879c8c0b)

今回は使用するテーブルを作成していきます。

# Dataverse テーブルの作成

作成するテーブルは以下の通りです。

|テーブル名|用途|
|:--|:--|
|QuizData|クイズのデータを格納|
|QuizAnswer|ユーザーの回答データを格納|
|QuizUserManagement|ユーザーの点数情報を格納|
|QuizSession|現在のクイズ状態を格納|

## QuizData テーブル

|列名|データ型|用途|プライマリ|
|:--|:--|:--|:--|
|ID|オートナンバー|自動採番ID|*|
|QNo|整数|クイズ順番定義用||
|Level|整数|クイズの難易度（0-5）||
|Score|整数|クイズの配点||
|Category|テキスト|カテゴリ表示用||
|Question|テキスト|問題||
|A|テキスト|Aの回答||
|A_Image|イメージ|Aの回答の画像||
|B|テキスト|Bの回答||
|B_Image|イメージ|Bの回答の画像||
|C|テキスト|Cの回答||
|C_Image|イメージ|Cの回答の画像||
|D|テキスト|Dの回答||
|D_Image|イメージ|Dの回答の画像||
|Answer|テキスト|問題の解答（A-D）||
|Overview|テキスト|解答の説明文||
|Enable|yes/no|問題の有効化||

## QuizAnswer テーブル

|列名|データ型|用途|プライマリ|
|:--|:--|:--|:--|
|User|テキスト|ユーザーID（UPN）|*|
|Session|参照|QuizSessionテーブルからのリレーション||
|Quiz|参照|QuizDataテーブルからのリレーション||
|AnswerID|テキスト|解答ID||

## QuizUserManagementテーブル

|列名|データ型|用途|プライマリ|
|:--|:--|:--|:--|
|User|テキスト|ユーザーID（UPN）|*|
|Session|参照|QuizSessionテーブルからのリレーション||
|Score|整数|総得点||

## QuizSessionテーブル

|列名|データ型|用途|プライマリ|
|:--|:--|:--|:--|
|SessionID|テキスト|クイズセッションID|*|
|Quiz|参照|QuizDataテーブルからのリレーション||
|State|yes/no|セッション状態||
|Tail|整数|全問題数||
XcodeのBuild PhasesでSPMを使ってcommand line toolを実行する

XcodeのBuild PhasesでSwift Package Managerを使って以下のように実行すると

```bash
swift run -c release swiftlint
```

このようなエラーになってしまいます。

```bash
unable to load standard library for target 'x86_64-apple-macosx10.15'
```

## 解決方法

`xcrun --sdk macosx` を先頭につけてやると解決します。

```bash
xcrun --sdk macosx swift run -c release swiftlint
```

### 参考

https://github.com/SwiftGen/SwiftGen/issues/689#issuecomment-622341803