OmniAICreator/Qiita-1.07M huggingface dataset:
アラートダイアログのOKが押されたタイミングで処理を実行する

## 2023年9月7日追記

以下長々書いていますが、alertダイアログが表示されている間は、その後のJavaScriptの実行はブロックされるため、

```javascript
console.log("Before alert");
alert("OKを押してください。");
console.log("After alert");
```

のようにalertのあとに、実行したい処理を書けばいいだけでした。。。

## やりたいこと

![アラートダイアログの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577446/1c6f2bcf-4a20-fee4-6148-81b531e1a796.png)

上の画像のようなアラートダイアログのOKを押されたタイミングで処理を実行したいとします。

![確認ダイアログの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577446/00447bd9-883b-0abd-bfed-86edbb1ee506.png)

一般的には、上の画像のような確認ダイアログを使って、OKボタンが押された場合とキャンセルボタンが押された場合の処理を書くことが多いかと思います。

```JavaScript
if (confirm('確認ダイアログの例')) {
    console.log('OKボタンが押されました。')
} else {
    console.log('キャンセルボタンが押されました。')
}
```
### キャンセルボタンの押せない、OKボタンのみの確認ダイアログを作りたい

ただ、時には諸々の事情でキャンセルボタンを押してもらいたくない場合もあります。

ということで、キャンセルボタンの押せない、OKボタンのみの確認ダイアログを作っていきます。

## `alert()`の仕様

確認ダイアログでのOKボタンとキャンセルボタンを押された場合の処理の書き分けでは、JavaScriptの`confirm()`が

- OKボタンをクリックした場合の戻り値：true
- キャンセルボタンをクリックした場合の戻り値：false

であることを使って、if文の条件式の中で`confirm()`を使うことで実現していました。

一方、`alert()`では、アラートダイアログのOKボタンを押された際の戻り値はundefinedです。

この特性を使って、

```JavaScript
if (!alert('OKを押してください。')) {
    // OKが押された際に実行する処理
}

```

上記のような条件式を書くことによって、OKが押された際にundefinedの否定、つまりtrueとなり、処理が実行されます。

以下、サンプルです。

## サンプル

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="MtDeity" data-slug-hash="rNLLVwM" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Event After Alert">
  <span>See the Pen <a href="https://codepen.io/MtDeity/pen/rNLLVwM">
  Event After Alert</a> by Kamiyama (<a href="https://codepen.io/MtDeity">@MtDeity</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
GitHub ActionsでHello World


# 準備

まず作業用プロジェクトを作る
`github-actions-sample`というフォルダ名で作った

中身はREADME.mdだけ作っておく

![スクリーンショット 2020-10-18 21.13.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/79d1f8ce-db0b-8b26-371e-63bd76a45a8a.png)

そしてGitHubにプッシュして準備完了

# Hello Worldする。
`.github/workflows/helloworld.yml`を作成する

![スクリーンショット 2020-10-18 21.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/65357363-f8ee-3853-0fa1-e23265a08401.png)

```helloworld.yml
name: Hello World

on: 
  workflow_dispatch:

jobs:
  say_hello:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Hello World!"
```

これを`master`にプッシュ

このあとはGitHubでの作業

workflowを選択
![スクリーンショット 2020-10-18 21.44.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/9ff1705a-ca91-0005-75e1-b35647bf9ada.jpeg)

workflowの実行
![スクリーンショット 2020-10-18 21.44.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/1833caea-fcd9-276e-cba6-8110b9ddb273.jpeg)

![スクリーンショット 2020-10-18 21.44.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/dea88f28-a878-d92f-55e2-2686923385fd.jpeg)

実行したあと**ブラウザを更新すると**以下のような画面になる

![スクリーンショット 2020-10-18 21.44.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/a262a397-320f-45d3-7b82-a319d3b3bfda.png)

現れたHello Worldを選択すると以下の画面に移動する

![スクリーンショット 2020-10-18 21.44.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/ec9c9cc7-1fd6-a9e3-c77d-189c3fc0e57f.png)

しばらく待てば完了する。
完了すると、右の画面でHello World!のログが出ていることがわかる。

![スクリーンショット 2020-10-18 21.45.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/70b45a3d-e4c9-8ec0-51c0-e3cc341d6ba4.png)

# ポイント

```.yml
name: Hello World  # このworkflowの名前

on: # onで実行タイミングを設定
  workflow_dispatch: # 手動で実行するAction

jobs: # jobsで実行する内容を書く
  say_hello: # 実行する内容(job)の名前
    runs-on: ubuntu-latest # 実行するOS
    steps:
      - run: echo "Hello World!" # 実行するコマンド
```

# Next Step
GitHub Actionsで実行するジョブでcheckoutはほぼ必須だと思うのでその方法を学ぶと良いと思う。
[actions/checkout](https://github.com/actions/checkout)

こんな感じで書く

```.yml
jobs:
  job名:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ github.ref }}
```



# 参考
[Events that trigger workflows](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#manual-events)
こちらのサンプルに手動で実行するときにパラメータを付けたりする方法が乗っている
Raspberry Pi ZeroでADS1115を使う

個人的なメモ。

# 概要

Raspberry Pi ZeroでA/DコンバータのADS1115を使う方法を記す。
使用したのはA/Dコンバータは以下。


https://a.aliexpress.com/_mKHhzyT

# 配線

以下のように配線する。

V -> 3.3V(1番ピン)
G -> GND(6番ピン)
SDA -> GPIO2/SDA1(3番ピン)
SDL -> GPIO3/SDL1(5番ピン)

# 設定

/boot/config.txtに以下を追記する。

```/boot/config.txt
dtparam=i2c_arm_baudrate=400000
dtoverlay=ads1115
dtparam=cha_enable
dtparam=chb_enable
dtparam=chc_enable
dtparam=chd_enable
```

以下のパスの各ファイルで電圧を取得できる。

```bash
$ls /sys/bus/iio/devices/iio:device0
```

```
buffer                                   in_voltage2_raw
current_timestamp_clock                  in_voltage2_sampling_frequency
dev                                      in_voltage2_scale
events                                   in_voltage2-voltage3_raw
in_voltage0_raw                          in_voltage2-voltage3_sampling_frequency
in_voltage0_sampling_frequency           in_voltage2-voltage3_scale
in_voltage0_scale                        in_voltage3_raw
in_voltage0-voltage1_raw                 in_voltage3_sampling_frequency
in_voltage0-voltage1_sampling_frequency  in_voltage3_scale
in_voltage0-voltage1_scale               name
in_voltage0-voltage3_raw                 of_node
in_voltage0-voltage3_sampling_frequency  power
in_voltage0-voltage3_scale               sampling_frequency_available
in_voltage1_raw                          scale_available
in_voltage1_sampling_frequency           scan_elements
in_voltage1_scale                        subsystem
in_voltage1-voltage3_raw                 trigger
in_voltage1-voltage3_sampling_frequency  uevent
in_voltage1-voltage3_scale
```

このin_voltage<数字>_・・・がA0～A3の入力に対応している模様。

rawの値×scaleの値=電圧値(mV)となる。

# 参考文献

https://wiki.seeedstudio.com/4-Channel_16-Bit_ADC_for_Raspberry_Pi-ADS1115/
Ruby on Rails save時にrollbackする原因がわからないとき。

# はじめに
今回はrailsでsave時にrollbackする原因がわからないときの対処について学習してきます。

現在ユーザーがメモを登録できるサイトを作成中。

今回やりたい事
fromから登録（note)を送ってDBに保存（ユーザーに紐づいた）してviewに表示させる

苦戦したところ
登録した際にrollbackしてしまう。

@note.save！と記述すると下記のエラーが出たので検索

ActiveRecord::RecordInvalid: Validation failed: User must exist

要約するとuserモデルに値が入ってなくてバリデーションで弾かれていたみたい

## 解決策
optional: trueを記載

```note.rb
class Note < ApplicationRecord
  belongs_to :user,optional: true
  validates :title, presence: true
  validates :explanation, presence: true
end
```
optional: trueとはなにか？

[Railsのbelongs_toに指定できるoptional: trueとは？](https://blog.ryskit.com/entry/2018/01/27/195442)
belongs_toの外部キーのnilを許可するというもの

参考


#### しかし、

rollbackは解消されたが投稿したタイトルが全部０で表示されてしまいす。

![スクリーンショット 2020-10-18 22.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752006/840e0332-e7cd-b4a2-8da2-d2f9c2b040cb.png)

原因
マイグレーションファイルのtitleのデータ型がintegerになっていたからでした。
text型に直して`rails db:migration:reset`をして解決！
【Swift】FirebaseのdocumentIDを取得する方法

```swift
var documentId : String?

self.firestore.collection("users").document("samplesample")
            .getDocuments() { (querySnapshot, err) in
                if let err = err {
                    print("Error getting documents: \(err)")
                } else {
                     for document in querySnapshot!.documents {

                         self.documentId = document.documentID
                     }
                  }
              }

```

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
[Linux]基本コマンドまとめ

###カーソルの移動など

```
Ctrl + f     // 一文字forward
Ctrl + b     // 一文字back
Ctrl + a     // 行の先頭へ移動
Ctrl + e     // 行の最後へ移動
esc + f      // 一単語forward　※ escを押した後
esc + b      // 一単語back　　  ※ escを押した後
Ctrl + h     // 左の文字削除
Ctrl + d     // 右の文字削除
Ctrl + u     // カーソル位置から先頭行まで削除
Ctrl + k     // カーソル位置から行末まで削除
Ctrl + y     // 最後に削除した内容を挿入
Ctrl + c     // 強制終了
Ctrl + s     // 画面表示のロック（キーボードから文字の入力を受付ない）
Ctrl + q     // 画面表示のロック解除
Tab          // コマンドやパスを補完してくれる
```

###基本コマンド
```
ls [option][ディレクトリ・ファイル名]      // 一覧表示
$ ls *.php                             // 拡張子が　phpの一覧を表示
$ ls /z???                             // zから始まり 
$ ls -l                                // 詳細を表示する
$ ls -F                                // ファイル種別を表示する　@:シンボリックリンク,　*:実行可能ファイル, 記号なし:通常ファイル

mkdir [option] <作成するディレクトリ名>    // ディレクトリ作成
$ mkdir -p test/2020/10/10             // -pをつけると同時にディレクトリ作成してくれる
$ rmdir <ディレクトリ名>                 // 空のディレクトリ

cat [fileのパス]                        // ファイルの中身を表示

less [fileのパス]                       // ファイルの中身をスクロール表示  
スペースキー, f　　　　　　　　　　　　　　　 // １画面下へスクロール
b                                      // １画面上へスクロール
j                                      // １行下へスクロール
k                                      // １行上へスクロール
q                                      // qコマンドを終了
/<文字列>                               // 下に向かって検索
?<文字列>                               // 上に向かって検索

touch [file名]                         //空のファイルを作成　
rm    [option] [file名]                //ファイルやディレクトリを削除する 
$ rm -r dirr                           //ディレクトリの中身もまとめて削除

mv [file名1][file名2]              //ファイル名を変更
mv [file名][移動先のディレクトリ名]   //ファイルを移動
※　移動先がディレクトリかファイルで挙動が変わる

cp [コピー元][コピー先]
* 上書きしてしまう。安全にやるなら -i オプションをつける。

find <検索開始ディレクトリ><検索条件><アクション>
$ find . -name README.md -print 
```

###ハードリンクとシンボリックリンク
####ハードリンク
・一つのファイルに複数の名前をつける
・元のファイルを削除しても消えない
・全てのハードリンクがなくなったときに消える
####シンボリックリンク
・リンク先のパスが書かれた特殊なファイル　　　// ショートカットなど
・シンボリックリンクを残したまま、ファイルの実態を消したり移動したりすると参照できなくなる

```
ln [option][リンク元ファイル][ファイル名]
$ ln file1 file2              // オプションなしだとハードリンクをはる
$ ln -s file1 file2
```
ActiveSupport の underscore は camelize の逆変換じゃない

複数の単語からなる言葉を識別子に使うとき，スペースを含めることができないので，何らかの方法で単語の区切りを表さなければなりません。
たとえば以下のようなさまざまな表記方法が使われています。

* UpperCamelCase
* lowerCamelCase
* snake_case

ActiveSupport にはこれらの間の変換をする便利なメソッド群が用意されています。

CamelCase を snake_case に変換するには `String#underscore` が使えます。
snake_case を UpperCamelCase に変換するには `String#camelize` が使えます[^lcc]。

[^lcc]: lowerCamelCase に変換するには `camelize(:lower)` のようにします。

以下のように：

```rb
require "active_support/inflector"

p "BookTitle".underscore # => "book_title"
p "book_title".camelize  # => "BookTitle"
```

これを見ると，`underscore` と `camelize` は互いの逆変換になっており，

```rb
require "active_support/inflector"

p "BookTitle".underscore.camelize  # => "BookTitle"
p "book_title".camelize.underscore # => "book_title"
```

のように両者を重ねると（常に）元に戻るように思えます。

しかし，そうならない場合もあります。それは

```rb
require "active_support/inflector"

p "OfficialURL".underscore # => "official_url"
p "CSVFile".underscore     # => "csv_file"
```

の `URL` や `CSV` のように大文字だけで構成される単語を含むケースです。
`underscore` メソッドは，人間が期待するとおり，`CSVFile` を `CSV` と `File` に分割して snake_case 化してくれました。
しかし，これにより，変換後の `url` や `csv` がもともと大文字だけで綴られていたという情報が失われてしまうので，これらを `camelize` しても元には戻らないのです。

```rb
require "active_support/inflector"

p "OfficialURL".underscore.camelize # => "OfficialUrl"
p "CSVFile".underscore.camelize     # => "CsvFile"
```

便利なメソッドも仕様をよく理解して使わないと落とし穴に落ちる可能性がある，という例でした。
（つか，ハマったんだよ[^ot]，実際に！）

[^ot]: 当初 `gsub(/.(?=[A-Z])/){ $& + "_" }.downcase` みたいなコードで snake_case 化してて，あとで ActiveSupport を使った処理を混ぜたときに不具合が生じたという。
SwiftでFirebaseのデータを上書きする方法

```swift
import Firebase


Firestore.firestore()
                .collection("コレクション名")
                .document(ドキュメントID)
                .setData([
                    "Value": 1,
                    "UserId" : Auth.auth().currentUser!.uid
                ], merge: true)
```

ポイントはmerge: trueです。
import Firebaseも忘れずに

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
SwiftでFirebaseで認証したユーザーのIDを取得する方法

```swift
import Firebase

let userID = Auth.auth().currentUser!.uid
```
import Firebaseも忘れずに。

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
【StereoDepth】Bi3D: 前景と後景

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/f8f26c6b-e9a5-f836-5ea6-1a5461267f5e.png)

物体がとあるレンジの手前にいるか後ろにいるかSegmentationを行う事で、高速である程度の位置が分かる

<h1>Implementation</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/e0522ce3-09e9-33de-2166-77c318f9f773.png)


画像を入力してFeatureNetによってFeature Mapを得る
FRをdisparityでwarpさせたものとFLを入力し、SegNetにより手前か奥にあるか推定する。
Upsampleして入力画像と同じ解像度にする。
SegRefineでRefinementする。
sigmoidで0~1に正規化する事でConfidence Mapを得る。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/08b21689-33e9-2ef7-03d5-2fdcf37ceb5c.png)
RegNetにより近隣のDisparity情報を加味して修正する。
DispRefineによりDisparityをRefinementし最終Disparity Map M を出力する



<h1>参考文献</h1>
Bi3D: Stereo Depth Estimation via Binary Classifications
https://arxiv.org/pdf/2005.07274.pdf
SwiftでコードだけでUICollectionViewを実装する方法

```swift
class SampleCollectionView: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    lazy var collectionView : UICollectionView = {
        let collectionView = UICollectionView(

            frame: CGRect(x: 0, y: statusBarHeight, width: self.view.frame.width, height: self.view.frame.size.height - statusBarHeight),
            collectionViewLayout: UICollectionViewFlowLayout())
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cellId")

        return collectionView
    }()

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //セルのアイテムの数
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        //アイテムの大きさ
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        //アイテム表示領域全体の上下左右の余白
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        //アイテムの上下の余白の最小値
    }
    // アイテムの表示内容（UICollectionViewDataSource が必要）
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CollectionViewCell
        //セルの表示内容
        return cell
    }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        //セルをクリックされた時のアクション
    }
}
```

## おすすめ情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
Flaskで初めて動的なサイトを作成した時のメモ

##本記事の趣旨
　静的サイトは作ったことがあったが動的サイトは初めて作った時期に、少しだけ戸惑ったポイントをメモとして記載。
なお、フレームワークはpythonのflaskです。

#### 1 css,javascriptが反映されない
色々な例が考えられますが、例えば以下の様な構成だとapp.py実行時にcss,javascript,画像ファイルが読み込まれません。

```:ディレクトリ構成【失敗例】
-app/
 -app.py
 -index.html
 -index.css
 -index.js
 -img.png
```

```python:app.py【失敗例】
from flask import Flask

app = Flask(__name__)

@app.route('\')
def showTopPage():
    return render_template('index.html')

if __name__ =='__main__':
    app.run()
```
```html:index.html【失敗例】
<head>
    <link rel='stylesheet' href="index.css">
    <script src="index.js')}}" defer></script>
</head>
<body>
    This is my flask application!
    <h3>
        <img class='img' src="static/images/img.png">
    </h3>
</body>
</html>
```

※index.cssとindex.jsのコードの中身はどのような内容でも、本記事の趣旨とは関係ないので、例の記載を省きます。

その代わり、ディレクトリ構成とindex.htmlの<head></head>部分を下記の通り修正すると、index.cssとindex.jsが反映されます。

```:ディレクトリ構成【成功例】
-app/
 -app.py
 -templates/
   -index.html
 -static/
  -css/
    -index.css
  -js/
    -index.js
　-images/
    -img.png
```

```python:app.py【成功例】
from flask import Flask

app = Flask(__name__)

@app.route('\')
def showTopPage():
    return render_template('index.html')

if __name__ =='__main__':
    app.run()
```
```html:index.html【成功例】
<head>
    <link rel='stylesheet' href="{{url_for('static',filename='css/index.css')}}"> #←ここを修正
    <script src="{{url_for('static',filename='js/index.js')}}" defer></script>　  #←ここを修正
</head>
<body>
    This is my flask application!
    <h3>
        <img class='img' src="static/images/img.png">
    </h3>
</body>
</html>
```

#### 2 cssを変更したのに、変更が反映されない
【原因】変更前のcssファイルと変更後のcssファイルが同じurlであるため、ブラウザが「すでに取得済みなので再び読み込みに行く必要がない」と判断し、前回のcssの内容を反映している。（キャッシュ）
【解決策１】cssのファイル名を変更する。そうすることで、変更前と変更後のcssのurlが同じでなくなるため、キャッシュしなくなる。
[解決策2】キャッシュを無効にする。chromeの場合は、「developer tool」から、「Disable cache」にチェックを入れることで、キャッシュを無効にできます。


---
##終わり
以上です。静的サイトは作ったことがあるものの、動的サイトを初めて作った時に、最初に引っかかったのは上の様な点でした。
PHP: IF文（初心者向け）

####if(式)
 
`式がtrue`なら`最初のくくり`で処理が行われます。
`式がtrueでなくて`elseがあれば`elseくくり`で処理が行われます。
 
[公式リンク](https://www.php.net/manual/ja/control-structures.if.php)

```php:ifのいろいろなパターン
//超基本形
if (式) {
    //式 が trueなら処理が行われる
}
//否定形
if (!式) {
    //式 が falseなら処理が行われる
}
//if ~ else
if (式) {
    //式 が trueなら処理が行われる
} else {
    //式 が falseなら処理が行われる
}
//if ~ elseif ~ else
if (式１) {
    //式１ が trueなら処理が行われる
} elseif (式２){
    //式２ が trueなら処理が行われる
} else {
    //式１ と 式２ が true でなかったときに処理が行われる
}
```



####おまけ・よく出る比較演算子（詳しくは公式で）
[公式リンク: 例がたくさんあります](https://www.php.net/manual/ja/language.operators.comparison.php)

```php:よく使う比較演算子
//同じか？
if ($a == $b) {
    //$a が $bに等しいとき -> true -> 処理が行われる
}
//違っているか？
if ($a != $b) {
    //$a が $bに等しくないとき -> true -> 処理が行われる
}
//小さいか？
if ($a < $b) {
    //$a が $bより小さいとき -> true -> 処理が行われる
}
//大きいか？
if ($a > $b) {
    //$a が $bより大きいとき -> true -> 処理が行われる
}
//小さい若しくは等しいか？
if ($a <= $b) {
    //$a が $bより小さいか等しいとき -> true -> 処理が行われる
}
//大きい若しくは等しいか？
if ($a >= $b) {
    //$a が $bより大きいか等しいとき -> true -> 処理が行われる
}
```
####使用例
```php:使用例
$a = 5;
$b = 10;

//等しいか？
if ($a == $b) {
    echo '$a と $b は等しい';
} else {
    echo '$a と $b は等しくない';
}
//-> $a と $b は等しくない

//大きいか？小さいか？
if ($a <= $b) {
    echo '$a と $b より小さいか等しい';
} elseif ($a > $b) {
    echo '$a は $b より大きい';
}
//-> $a は $b より小さいか等しい

//気をつけないといけないパターン
$res = '';
if ($a == $b) {
    echo '$a と $b は等しい';
}
//-> なにも出力されません。
// 式がfalseかつ elseがないので resには何も入りませんでした。
```

`if (式) {` は、`式`が`true`なら`最初のくくり`を処理します。
そうでないときに`else`があれば`elseくくり`を処理します。


####ネストの闇の話
```php:深いネストはアンチパターン
if (Aの条件) { //if:A
    //Aの条件が通ったとき
    if (Bの条件) {  //if:B
        //Bの条件が通ったとき
        if (Cの条件) {    //if:C
            //Cの条件が通ったとき
        } else {         //if:C
            //Cの条件が通らなかったとき
        }
    } else {       //if:B
        //Bの条件が通らなかったとき
    }
} else {      //if:A
    //Aの条件が通らなかったとき
}
```
`ネスト`とは上記のように`ifの中`に`ifが入った` `（入れ子）`状態をいいます。
`ネストの深い条件分岐`は`読むのに時間がかかる`ようになります。
上記のようにネストは３つぐらいに抑えたいですね。

###ネストを抑えるために: 一例

```php:ガード節
if (!Aの条件) {
    //Aの条件が通らなかったとき
    //終了
}
if (!Bの条件) {
    //Bの条件が通らなかったとき
    //終了
}
if (Cの条件) {
    //A、B、Cの条件が通ったとき
}
```
`A、Bの条件`が`通らなかったときに終了`としたのは少し乱暴ですが、`考え方`として捉えてください。
`ネスト`だと`Aの条件`、`Bの条件`を`頭のどっかに置いたまま`コードリーディングします。
対して`ガード節`だと、`AとBが通らなかったときは終了している`ので`Cの条件に集中できる`ので理解しやすくなります。

ここまで読んでいただいてありがとうございます！
初心者の方への一助になれば幸いです。

LGTMお願いします！
ストックのついでにお願いします！
モチベーションがあがります！
KEIAN KVI-70Bで卓上カレンダー

# 初期化

* いつからかサインイン後、10秒くらいたつととシャットダウンしてしまうように
* 「Windowsが正しく読み込まれませんでした」→「詳しい詳細オプションを表示する」→「トラブルシューティング」→「このPCを初期状態に戻す」→「すべて削除する」をしたら、サインイン画面前にシャットダウンしてしまうようになったため初期化することに
* 別のPCで「[【Windows 10】「メディア作成ツール」でインストールUSBメモリを作る：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/1508/06/news034.html)」の方法でWindows 10インストール用USBメモリ作成、32bitのみ
* KVI-70Bに「[Amazon | ルートアール 充電可能 4ポートスリムOTGハブ + microUSBケーブル RUH-OTGU4+C | ルートアール | USBハブ 通販](https://www.amazon.co.jp/dp/B010EFZISY/)」、USBメモリ、キーボード、マウスを接続
* KCI-70Bを電源ON、キーボードの「Delete」キーを押してBIOSでUSBメモリから起動
* 「名前：ドライブ0 パーティション3」「合計サイズ：13.8GB」「種類：プライマリ」をフォーマットしてWindowsをインストール
![IMG_20201015_214359.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240188/72984d58-c187-11f8-5bb5-401cc410881c.jpeg)

* インストール途中、ネットワークに接続せずにローカルユーザーを作成
* 「[価格.com - KEIAN KEM-70B のクチコミ掲示板](https://bbs.kakaku.com/bbs/K0000789714/)」にある「KEM-70B.zip」、「[KEIAN KVI-70B ドライバ保管庫 | Windows 高速化,EeePC,ネットブック カスタマイズ・改造・便利なオプション紹介](http://eeepc.dnki.co.jp/?eid=1106892)」にある「SileadTouch.fw」をインストールしようと思ったが、「KEM-70B.zip」をインストールするとサインイン後、10秒くらいたつとシャットダウンしてしまうようになったため、ドライバーのインストールはしないことにした

# 画面縦表示

* 設定／システム／ディスプレイ／画面の向き：横→縦

# ディスプレイ常にON

* 設定／システム／電源とスリープ
  * 次の時間が経過後、ディスプレイの電源を切る（電源に接続時）：10分→なし
  * 次の時間が経過後、PCをスリープ状態にする（電源に接続時）：10分→なし

# DAKboard

* [DAKboard - A customizable display for your photos, calendar, news, weather and more!](https://dakboard.com/site)
* 有料プランもあるがフリーでもそこそこ使える
* Layout: Mobile/Tablet
* Background: Google Photos
* Calendars
  * Calenadr URLs: GoogleカレンダーのicsのURL
  * Google Calendar 日本の祝日
* Settings & Defaults / Base Font Size: Large
![IMG_20201018_211949.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240188/4658a1ce-2417-d318-929e-e1c47e03a4c8.jpeg)

# Edge設定

* メニュー／拡大：100%→75%
* 拡大メニュー右端の矢印をクリックして全画面表示
![全画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240188/03124bc2-8016-8198-bb80-17858ecd0f33.png)

* メニュー／詳細／プライバシーとセキュリティ／クリアするデータの選択
  * 閲覧の履歴：ON
  * Cookieと保存済みのWebサイトデータ：ON→OFF、DAKBoardのログイン情報は残しておきたいため
  * キャッシュされたデータとファイル：ON
  * 保存して閉じたタブや最近閉じたタブ：ON
  * ブラウザーを閉じるときに、常にこれを消去する：OFF→ON、ディスク容量節約のため

# UltraVNC

* [Home - UltraVNC VNC OFFICIAL SITE, Remote Access, Support Software, Remote Desktop Control Free Opensource](https://www.uvnc.com/)
* ドライバーをインストールしていない→タッチパネル操作不可ということでインストール
* サービスとして起動させることで、UAC画面表示時に操作できなくなってしまう問題回避

# マウス未接続時にマウスカーソル表示

* 設定／簡単操作／操作／マウス／マウスをキーパッドで操作する／テンキーを使用するためにマウスキー機能をオンにして、マウスポインターを移動する：オフ→オン
* [VNC関係のプチ情報 - PC破壊日記的ブログ](http://pc-diary.com/blog/2007/07/vnc.html)

# その他買ったもの

* [Amazon | タブレット スタンド 卓上 Klearlook【揺れず頑丈な金属製台座・12.9インチ程対応・360度回転可能】スマホホルダー (i)Pad スタンド アーム 横/縱/仰向け 持ち運び易い For (i)Pad/Kindle/Nintendo Switch/android/(i)Phone多機種対応 (ブラック) | KlearLook | スタンド 通販](https://www.amazon.co.jp/dp/B081VBXM6K/)
* [Amazon.co.jp： 変換名人 USB A to micro下L型100cmケーブル USBA-MCDL/CA100: 産業・研究開発用品](https://www.amazon.co.jp/dp/B01MT40SE2/)
Twitterシェアボタンをカスタマイズする方法

# シェアボタンとは
ボタン1つで、SNSにWebページや記事を共有してもらえるボタンです。自分のサイトを利用者に拡散してもらい、認知度をあげることができます。

# Twitterの設置方法
アイコンを使う場合は、以下のブランドリソースを守りましょう。
https://about.twitter.com/ja/company/brand-resources.html
## 1. 公式ページにアクセス
シェアボタンなどツイッターの埋め込み形を生成できる[公式ページ](https://publish.twitter.com/#)にアクセスしましょう。
公式ページ→https://publish.twitter.com/#
![スクリーンショット 2020-10-18 20.54.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680229/63f0d3c6-f33c-b372-6940-3c04bb562abf.png)
## 2. Twitter Buttonsをクリック
下にスクロールして、**Twitter Buttons**をクリックします。
## 3. Share Buttonを選択
**Share Button**を選択することで、URLをシェアするボタンを作成することができます。
![スクリーンショット 2020-10-18 20.55.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680229/ece0012b-5605-d795-18c7-f3bfb62f4ef0.png)
## 4. set customization optionsをクリック
タイトルに書いてある
That’s all we need, unless you’d like to **set customization options.**
の青くなっている**set customization options.**をクリックすると以下の画面になります。
![スクリーンショット 2020-10-18 20.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680229/f1e801b7-c6f3-032e-9b80-672530477e61.png)
各項目は以下のことを指定できます。

| 英文 | できること |
|:-:|:-:|
|  Do you want to prefill the Tweet text? | 入力したい文字 |
|  Do you want to set a specific URL in the Tweet? | 共有するURLもしくはツイートURL |
|  Would you like this Tweet to include your screen name? | 自分のツイッターアカウント |
|  Would you like to set a hashtag for the Tweet? | 共有したいハッシュタグ |
|  Do you want to recommend accounts? | お勧めするツイッターアカウント? |
|  How would you like the button displayed?  | ボタンの大きさ（カスタマイズする場合は選択不要） |
|  What language would you like to display this in?  | 言語設定  |

最後に、**Update**をクリックしたら完成です。

## 5. Copy Code
Updateを押すと前のボタンに戻されます。Copy Codeを押すとクリップボードにコードがコピーされます。

## 6. カスタマイズする！！
1. 一度、公開するWebページに貼り付けます。
2. そして、Webページを開きます。
![スクリーンショット 2020-10-18 21.12.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680229/65f922db-78e6-d3ed-e594-43e167c1a02e.png)
するとツイートボタンが表示されています。
3. Google Chromeのディベロッパーツールを使用します。
4. ページ上で、右クリックを押してから**検証**を押します。
5. ソースコードが出されるので、その中から、aタグを見つけ、href=""の中に書いてある文字をコピーします。

>> 写真の場合、```https://twitter.com/intent/tweet?original_referer=http%3A%2F%2F127.0.0.1%3A54313%2F&ref_src=twsrc%5Etfw&text=Document&tw_p=tweetbutton&url=http%3A%2F%2F127.0.0.1%3A54313%2Findex.html```

![スクリーンショット 2020-10-18 21.14.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680229/cbde5260-78c5-ec6c-9656-e455e7153d71.png)
6. 自分の作りたいボタンをデザインして、先ほどコピーしたものを貼り付けると完成です！！
【JavaScript・React】基本知識


JavaScriptやReactの基本となる概念について📄

##モジュール

コードを再利用しやすい形に細分化して影響範囲を狭めたもの。
違うモジュール同士なら名前が被ってもOK👍なので、変数名や関数名が被ってしまう名前空間の問題を解決する。基本的にモジュールは１ファイルに1モジュール定義。

**JavaScriptのモジュール形式**

* **CommonJS** ：Node.js(サーバーサイド)で使われるJavaScriptの各種仕様。
* **ES Modules** ：JavaScript公式の言語仕様。今はこれが主流。

##パッケージ管理システム
パッケージとは、コードの一部を使い回すために切り出したもの。
パッケージ管理システムではパッケージをいい感じでインストールし管理してくれる。　
例えば30個の依存関係のあるパッケージがあると、それぞれのパッケージがさらに依存関係を持っている、、、これをいい感じに管理してくれるのがnpm、yarn等のパッケージ管理システム。

**主な機能**
    1. ローカル環境のパッケージを更新、検索
    2. パッケージインストール削除
    3. 依存関係の解決、必要な依存パッケージ自動インストール
    4. 設定を書いて1-3を自動化

* **npm (Node package manager)**
Node.jsの標準パッケージ管理システム。(最近githubに買収された。)

    * **package.json**：インストールが必要なパッケージリスト

    * **package-lock.json**：
実際にインストールしたパッケージがどの依存関係を持っているかの記録。チームで共有することで環境を統一できる。node_modules、package.jsonが変更されると自動で作成、変更される

    * **node_modules**：
ディレクトリの中に依存関係のパッケージが入っている。


* **yarn**
npmよりも高速なパッケージマネジャー。npmより厳密にモジュールのバージョンを固定でき、yarn.lockファイルで、各パッケージのインストールバージョンを固定できる。しかもnpmと同じpackage.jsonが使えるため、同一プロジェクトでnpmかyarnかなんて迷わなくてOK👍:）
https://classic.yarnpkg.com/ja/docs/install#mac-stable

##ビルド

書いたコードを異なる環境で動かすための準備のこと。npmでインストールしたいろんな形式のモジュールで書かれたパッケージを使えるようになる。JavaScriptのビルドでは(Browserifyや)webpackが使われる。webpackではモジュールに加え画像やcssなども一緒にビルドしてくれる。

* **Browserify**
CommonJS形式で書かれたものをブラウザ向けにバンドル(変換)するツール。CommonJS形式で書けばBrowseryで変換することでブラウザでもNode.js向けのパッケージが使えるようになった。ブラウザでもnpm(CommonJS形式のパッケージがメイン)が使われるようになった。

* **webpack**
Browserifyの上位互換バンドルツール。JavaScript向けのファイルのみでなく、対応するローダーを使ってバンドル(変換)すればHTML,CSS,画像などを読み込めるようになる。ES Modulesにネイティブ対応。
https://webpack.js.org/

##コンパイル
開発時はブラウザで動かないコードを、ブラウザで動くように変換しJavaScriptにする機能。バンドルはモジュール依存関係解決に焦点、コンパイルは事前に変換する機能である。
ES2015の新機能を古いブラウザでもバンドル(トランスパイル)して動くようにしてくれるのがBabel。webpackと併用しコンパイルで事前に変換することでモジュールと依存関係を解消し、かつ、ES6の新しい機能も使えるようになった。
Reactだと、そのままでは動かないjsxファイルを、事前にコンパイルして変換すると、ブラウザで動くようになる。このようにいったんバンドルやコンパイルを挟むことがjQueryと違うところ。


* **Babel** <br>
ReactのJSX(JavaScript XML React)というJavaScriptの拡張版でXMLを出力すると、Babelが自動でJavaScriptに変換してくれる。👏<br>
他にもNodeでは認識されるES6の`const foo = <div>` を標準的な` var foo = React.createElement()` に変換してくれる。👏👏<br>以下のページの左側にXMLを入力すると、右側にリアルタイムでJavaScriptが表示される
https://babeljs.io/
JSXを使うことでHTMLのような書き方でh1タグが作成できる。

```React
//JSXでのh1タグ
import React from 'react';
import ReactDOM from 'react-dom';

const element = <h1>Hello!</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
```
【Django】管理画面でのモデル名の複数形を修正する

## Django モデル名
Djangoでは一般的に(?)モデル名を単数形の形で定義する。
そのため、管理サイトでは複数形の"s"が自動で付与されて表示される。

ただ、カテゴリーモデルの**Category**を**Categories**にしてくれたり、
ニュース（お知らせ）モデルの**News**を**News**のままにしてくれる機能はない。

これらは`Categorys`と`Newss`になってしまいます。

表示上の問題だと思うので、スルーしても差し支えないと思われますが
少し気になるので修正してみました。

## 正しい表示に直してみる
モデルのMetaオプションで表示したい文字を指定すればOKです。

```
class Meta:
        verbose_name_plural = 'Categories'
```
小文字でも良いみたいです。

```
class Meta:
        verbose_name_plural = 'categories'
```

### Categories
```python:models.py
class Category(models.Model):
    name = models.CharField(max_length=50)
    
    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name
```

## 終わりに
今回も備忘録。
誰かのお役に立てれば幸いです。

自分のブログでも紹介してます。

https://dottrail.codemountains.org/py-django-model/
Tkinterで日付セッターを実装する

ソースコードは以下になります。

```python
import tkinter as tk
from tkinter import ttk
import datetime
import calendar

year_list = ['2020', '2021']
month_list = [str(date).zfill(2) for date in range(1, 13)]
date_list = [str(date).zfill(2) for date in range(1, 32)]
hours_list = [str(date).zfill(2) for date in range(24)]
minutes_list = [str(date).zfill(2) for date in range(60)]
seconds_list = [str(date).zfill(2) for date in range(60)]


def change_date():
    def inner(self):
        last_day = calendar.monthrange(int(cb_year.get()), int(cb_month.get()))[1]
        if int(cb_date.get()) > last_day:
            cb_date.set(str(last_day).zfill(2))
        cb_date.config(values=[str(date).zfill(2) for date in range(1, last_day+1)])

        # datetime形式で出力
        # date = cb_year.get()+'-'+cb_month.get()+'-'+cb_date.get()+' '+cb_hours.get()+':'+cb_minutes.get()+':'+cb_seconds.get()
        # print("Date = ", date)
    return inner


root = tk.Tk()
root.title('Date Picker')


cb_year = ttk.Combobox(root, values=year_list, width=5, state='readonly')
cb_year.set(year_list[0])
cb_year.bind('<<ComboboxSelected>>', change_date())
cb_year.pack(side='left')

label_slash = ttk.Label(root, text='/')
label_slash.pack(side='left')

cb_month = ttk.Combobox(root, values=month_list, width=5, state='readonly')
cb_month.set(month_list[0])
cb_month.bind('<<ComboboxSelected>>', change_date())
cb_month.pack(side='left')

label_slash = ttk.Label(root, text='/')
label_slash.pack(side='left')

cb_date = ttk.Combobox(root, values=date_list, width=5, state='readonly')
cb_date.set(date_list[0])
cb_date.pack(side='left')

label_space = ttk.Label(root, text=' ')
label_space.pack(side='left')

cb_hours = ttk.Combobox(root, values=hours_list, width=5, state='readonly')
cb_hours.set(hours_list[0])
cb_hours.pack(side='left')

label_colon = ttk.Label(root, text=':')
label_colon.pack(side='left')

cb_minutes = ttk.Combobox(root, values=minutes_list, width=5, state='readonly')
cb_minutes.set(minutes_list[0])
cb_minutes.pack(side='left')

label_colon = ttk.Label(root, text=':')
label_colon.pack(side='left')

cb_seconds = ttk.Combobox(root, values=seconds_list, width=5, state='readonly')
cb_seconds.set(seconds_list[0])
cb_seconds.pack(side='left')

root.mainloop()
```

年や月による最終日の違いはcalenderモジュールで対応しました。
起動後は以下のような画面が出るので日時を選択できます。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178012/5a583ae2-1cc3-569c-50c3-ae425334be80.png)

最後まで読んでいただきありがとうございました。
またお会いしましょう。
[Rails]本番環境で画像が表示されないエラーについて

#はじめに
ローカル環境ではしっかりと画像が表示されていたのに本番環境にデプロイすると画像が表示されなくなった時の対応。

#環境
・Rails 6.0.3.
・Haml

#状況

以下の表記みたいにRailsのヘルパーメソッドの`image_tag`を用いて画像をパス指定していてローカル環境ではうまく表示されていた。


```ruby

= image_tag "assets/material/icon/icon.png"
```

しかし、いざデプロイすると画像が表示されなくなりました。（この表記もあやしいですが）

もちろん`scss`ファイルに記載している`background-image`も表記されませんでした（この対応ついては下の方に記載してます）

#原因

本番環境では、画像もコンパイルされ、画像ファイル名が変わりディレクトリも変わってしまいます！

本番環境とローカル環境での違いは、
パスが変わる（app/assets/images/icon.png => /assets/icon.png）
名前が変わる（icon.png => icon-xxx… .png) ※xxx… はdigest
これが変わってしまいます！

#対策

`assets_path()`という`Rails`のオプションを使用します。
これは便利で本番環境へデプロイしファイル名やディレクトリが変わってもそれに対応しているのでローカルも本番もこれ一つで対応できてしまいます！

具体的には以下のように修正

```ruby

= image_tag asset_path("assets/material/icon/icon.png")
```

これでうまく行くと思いきや、、、、
ローカル環境でも表示されなくなりました。。。。

ダメ元でデプロイしても結果は同じ（当然です）

#asset_pathでもうまくいかない原因

`asset_path`というオプションは`app/assets/images`の直下にあるファイルに対応しているが、どうやらその先のディレクトリの中にあるファイルには対応していないみたいです。

#対応

ディレクトリで管理していた画像をすべて`app/assets/images`直下へ移動し、表記も下記のように修正しました。

```ruby

= image_tag asset_path("icon.png")
```

これでデプロイするとようやく画像が表示されました！！

まとめると`asset_path`というオプションを使うことと画像ファイルの場所を`images`直下にすることが解決策でした。


#[scss]background-imageについて

こちらも以下のようにただ画像ファイルのパスを指定してもうまくいきませんでした。

```css

background-image: url("main-image.jpg");
```

#対応

`image-url`を使うとローカルでも本番環境でも対応してくれます。

```css

background-image:image-url("main-image.jpg");
```
このように記述すると対応できます。
もちろん画像は`app/assets/images`直下のものを指定

ここで注意が必要なのは`:(コロン)`の後はスペースを開けずに記述する点です。SCSSの記述はコロンのあとは大体半角スペースを開けて記述していたのでクセになってました。
なので誤っているとは知らずになかなか原因に辿り着けずにいました。

これでデプロイすると正常に画像が表示されました！！
ARKit :  Reality Composerでオブジェクトに名前をつける、Swiftで名前を得る

#Reality Composerで名前をつける
表示するオブジェクトをダブルクリックして設定画面を表示し名前をつける。下図の場合「hako」という名前をつけている。
![スクリーンショット 2020-10-18 20.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658283/7ae2776a-4ee4-25ce-669a-8610ecce7bd4.png)

#Swiftで名前を得る
オブジェクトをタップするとデバッグ画面に「hako」と表示される。

```Swift

import UIKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Load the "Box" scene from the "Experience" Reality File
        let boxAnchor = try! Experience.loadBox()
        boxAnchor.actions.tapped.onAction=clickEvent(_:)
        // Add the box anchor to the scene
        arView.scene.anchors.append(boxAnchor)
    }
    
    func clickEvent(_ entity: Entity?) {
        guard let entity = entity else { return }
        
        print(entity.name)
    }
}
```
「tapped」はReality Composerで付けたビヘイビア。
Penronseの環境構築 [Windows]

# 目的
数式からいい感じに図をつくる描画用ソフトPenronseを使いたくなった。
下記の記事を参考に、Windows10でPenronseを使用できる環境を構築してみる。
このソフト名は、ノーベル賞を受賞したペンローズさんを指してるのでしょうか？

[記事：数式からいい感じに図表が生成できてしまう! Penroseを試す (SIGGRAPH 2020)](https://qiita.com/tomo_makes/items/5f88c32b4c2f2f33da92)

# 1. 環境構築
この節では、Windows10向けのPenroseの環境構築について説明する。

## 1.1 Docker
この節では、Dockerの環境構築について説明する。
WSLがWSL1と古かったのでWSL2に更新する[[1]](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)。Windows10で以前インストールしたUbuntu-18.04の設定をWSL1からWSL2に更新する。

```
$ wsl set-version Ubuntu-18.04 2
```
WSLの設定更新が完了後、Dockerの環境構築を行う。まず、Docker Hubをインストールする。BIOSの設定を変更しないとDocker Hubでエラーが発生してしまうので設定変更する。BIOSで「Intel VT-x」と「Intel Virtualization Technology」を有効にする[[2]](https://algorithm.joho.info/programming/docker-for-windows-hardware-assisted-virtualization-and-data-execution-protection-must-be-enabled-in-the-bios/)。
以上で、Dockerの環境構築は完了である。

## 1.2 Penrose
この節では、Penroseの環境構築について説明する。
WSL2と設定したUbuntu-18.04のターミナルでPenroseの環境を構築していく。Penroseの環境を構築しようとするとnpmのインストールで失敗してしまう。素直にapt-getでnpmをインストールすると失敗するので、apptitudeを用いてnpmをインストールする[[3]](https://kataware.hatenablog.jp/entry/2017/06/27/125618)。

```
$ sudo apt-get install aptitude
$ sudo aptitude install npm
$ which npm
```

Penroseのコンテナをダウンロードしセットアップする。npmで警告文がでるが無視する（たすけて...）。
ここまでくれば元記事と同じコマンドで実行できる環境が整った。

```
$ docker pull vanessa/penrose
$ cd penrose
$ make recreate-dev
$ make dev-build
```

# 2. 動作方法
この節では、Penroseの動作方法について説明する。
WSL2と設定したUbuntu-18.04のターミナルでPenroseのコンテナを実行する。

```
$ make start-dev
```

下のコマンドを実行することで結果を可視化できる。

```
$ make penrose set-theory-domain/tree.sub set-theory-domain/venn.sty set-theory-domain/setTheory.dsl
# ブラウザから http://localhost:3500 にアクセスする
```

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/18214859-8441-0264-b69f-03af2139d659.png)

# 3. まとめ
PenronseをWindows10で動作することができた。Penronseの使い方をサンプルコードをもとにまとめる予定である。
gitに自動pushする方法

#はじめに
私はAtCoderの過去問を解いたらそのソースコードをgithubにpushしています。
毎回同じコマンドを打つのはめんどくさいので、Macでlinux系のコマンドcrontabを使用してgit pushを自動化しました。

# crontabとは
決まった時間に自動的にコマンドを使用してくれるデーモンプロセスです。

```crontab -e```でコマンドの登録をします。

```shell:
分 時 日 月 曜日 コマンド
*  *  *  *  *  some_commands
```

*はワイルドカードを意味しています。

例えば、以下のようにすると、毎日20時0分にechoしてくれます

```shell:
分 時 日 月 曜日 コマンド
0  20  *  *  *  echo "Hello World!"
```

# Macでの注意点
私はmacOS 10.15.5 catalinaを使用しているのですがこのままだとcrontabが動かないので、
フルディスクアクセスにcronを追加しましょう。
[このサイト](https://mac-ra.com/catalina-crontab/)のやり方が参考になります。

# crontabにgit pushを登録
SSH のラッパースクリプト(git_ssh.sh)を作成します。

```shell:git_ssh.sh
#!/bin/bash

exec ssh -o IdentityFile=/path/to/id_git_rsa "$@"
```

秘密鍵とシェルスクリプトのパーミッションを変更します。
こうすることで秘密鍵を利用して git push が実行されます。

```shell:
chmod 600 /path/to/id_git_rsa
chmod 755 /path/to/git_ssh.sh
```

```crontab -e```を実行して以下のコマンドを書き込みます。

```shell:crontab
0 20 * * * cd /path/to/git_repository; export GIT_SSH=/path/to/git_ssh.sh; git add .; git commit -m "daily commit"; git push -u origin master;
```

これで毎日20時0分にgit pushが実行されます。

# 実行されない場合
crontabが実行されてないと```mail```にエラーが届きます。

ターミナルで```mail```と打つの内容が見れます。

私は以下のようなエラーが出ました。

```shell:
fatal: could not read Username for 'https://github.com': Device not configured
```

リポジトリのリモートURLがHTTPSになっていたのが問題っぽいです。
このコマンドを打ちましょう。

```shell:
git remote set-url origin git@github.com:username/repo.git
```

私はこれでエラーが解決でき、無事にgit pushできました。

# まとめ
crontabを利用してgit pushを自動化しました。皆さんも是非crontabを利用してみてください。


# 参考文献
https://qiita.com/ryusukefuda/items/878556158d8f1d3d887a
https://mac-ra.com/catalina-crontab/
http://tm.root-n.com/unix:command:git:cron_git_push
http://nyangryy.hatenablog.com/entry/2013/11/12/175408
【Go】実行・ビルド・パッケージのテストについて

##一応 前提環境
・macOS
・goenv 2.0.0beta11
・go version go1.15.2 darwin/amd64


##実行方法
今回は定番のHello Worldを実行します。

とりあえず$GOPATH直下に**hello.go**という名前でファイルを作成し、そこに下記のプログラムを書きます。

```
package main　　//パッケージの宣言

import (　　//使用するパッケージをインポート
    "fmt"
)

func main() {　　//関数main(エントリーポイント)の定義
    fmt.Println("Hello World")　　
}
```

そうしたらファイルを作成したディレクトリをターミナルで開き、```$ go run hello.go```を入力し、**Hello World**と表示されたら実行成功です。

##ビルド
次はhello.goを実行ファイル形式にコンパイルします。

下記のように**buildコマンド**を入力、-oオプションを使用することで実行ファイル名を指定できます。

```
$ go build -o hello hello.go
```

すると**hello**という実行ファイルができるので、ターミナルで下記のコマンドを入力するだけでHello Worldが実行できます。

```
$ ./hello
Hello World
```

##パッケージのテスト
仮に下記のようなパッケージ構成になっているとして、testsディレクトリの配下のファイルたちをテストするとします。

また、依存モジュール管理ツール Modulesを使用しており、
```go mod init　github.com/username/testproject```にしてあります。
※go 1.13から取り込まれていますが、go 1.11から移行期ではありますが、```export GO111MODULE=on ```にすることで使えるようになります。

```
testproject
│────── tests
│        │────testA
│        │────testB
│        │────testC
│        
│────── main.go
```

まず、testsディレクトリの配下に末尾が**_test.go**終わるようにファイルを作成します。これはパッケージをテストする際に決められたルールです。
```例)tests_test.go```

下記のようにtests_test.goファイルの内容を書きます。

```
package tests

import (
	"testing"

)

func TestJapaneseSubject(t *testing.T) {
	expect := "Japanese"
	actual := JapaneseSubject()


	if expect != actual {
		t.Errorf("%s != %s", expect, actual)
	}
}

func TestEnglishSubject(t *testing.T) {
	expect := "English"
	actual := EnglishSubject()


	if expect != actual {
		t.Errorf("%s != %s", expect, actual)
	}
}

func TestMathSubject(t *testing.T) {
	expect := "Math"
	actual := MathSubject()


	if expect != actual {
		t.Errorf("%s != %s", expect, actual)
	}
}
```

それではターミナルでコマンドを入力してテストを実行し、下記のように出力されれば成功です。

```
$ go test github.com/username/testproject/tests
ok      github.com/noa-1129/testproject/tests   0.506s
```

また、-vオプションをつけるとファイルごとに詳細が確認できます。

```
$ go test -v github.com/username/testproject/tests
=== RUN   TestJapaneseSubject
--- PASS: TestJapaneseSubject (0.00s)
=== RUN   TestEnglishSubject
--- PASS: TestEnglishSubject (0.00s)
=== RUN   TestMathSubject
--- PASS: TestMathSubject (0.00s)
PASS
ok      github.com/username/testproject/tests   0.230s
```

##最後に
今回パッケージのテストでは依存モジュール管理ツールとして**Go Modules**を使ってテストをしましたが、Go modulesについては次の記事で書こうと思います！
【M5Stack GRAY+ M5Stack用3G拡張ボード】書込み時のエラー (Could not auto-detect Flash size, defaulting to 4MB) の解決方法

##環境
Windows 10

##エラーの内容

M5Stack GRAY に、[M5Stack用3G拡張ボード](https://soracom.jp/products/kit/3g_module_m5stack/)を付けて書き込みしたとき、こんなエラーが出て結構ハマりました。
M5Stack BASICではエラーは出ずに書き込みできたのですが、なぜ？

```
Warning: Could not auto-detect Flash size (FlashID=0xffffff, SizeID=0xff), 
defaulting to 4MB

A fatal error occurred: Timed out waiting for packet content
```

エラーメッセージをそのまま読むと、M5StackGRAYのFlashサイズは16MBあるのに、4MBとみなして書き込もうとしています。

なぜ？


##解決

いろいろな方法を試した結果、
こちらのサイト
[M5Stackの困ったときの対処や注意すること](https://raspberrypi.mongonta.com/m5stacktips/)
記載の
>【M5StickC】書き込みエラーの対処
③電源ボタンを押しながら接続してみる。
<B>USBに接続する時に電源ボタンを押しながら接続してみる</B>と成功する場合があります。


の方法で、エラーが出ずに書き込み成功しました。（M5StickCの解決方法ですが・・・）

たまたまかと思いましたが、もう１個同じエラーが出る別のM5Stack GRAYで試しても、エラーが出ずに書き込みできました。




<br>
このエラーの解決に累計２日かかりました。
何度もM5Stackを諦めて、他の方法にしようとしたことか・・・・

理由はさっぱり分かりませんが、
動いたらヨシ！
ということで、とにかく良かったです。
<BR>

このサイトの方、本当にありがとうございました。

<BR>
Docker でRails6とPostgreSQLの環境構築

## Dockerで Rails6 + PostgreSQLで環境構築
自分の備忘録も兼ねてDockerでRails6 + PostgreSQLで環境構築のやり方を記事にして残しておきます。
今回はアプリ名をshopping_appとして作成していきます。

#### 作成する環境の各バージョン
- Ruby 2.7.2
- Rails 6.0.3
- PostgreSQL 13.0

#### ディレクトリ構造
````sh
 .
 ├── Dockerfile
 ├── docker-compose.yml
 └── shopping_app
     ├── Gemfile
     └── Gemfile.lock
````

## Dockerfileの作成
まずはDockerfileの作成をします。

````sh
FROM ruby:2.7.2
ENV LANG C.UTF-8


RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && \
    apt-get install -y build-essential \
            libpq-dev \
            nodejs \
            postgresql-client yarn

RUN mkdir /app
RUN mkdir /app/shopping_app

ENV APP_ROOT /app/shopping_app
WORKDIR $APP_ROOT

ADD ./shopping_app/Gemfile $APP_ROOT/Gemfile
ADD ./shopping_app/Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install

ADD . $APP_ROOT
````

## docker-compose.ymlの作成
docker-compose.ymlを作成します。今回はportを1501に設定しています。

````sh
version: '3'
services:
  postgres:
    image: postgres
    ports:
      - "3306:3306"
    volumes:
      - ./tmp/db:/var/lib/postgresql/data #MacOSの場合
    environment:
      POSTGRES_USER: 'admin'
      POSTGRES_PASSWORD: 'admin-pass'
    restart: always
  app:
    build: .
    image: rails
    container_name: 'app'
    command: bundle exec rails s -p 1501 -b '0.0.0.0'
    ports:
      - "1501:1501"
    environment:
      VIRTUAL_PORT: 80
    volumes:
      - ./shopping_app:/app/shopping_app
    depends_on:
      - postgres
    restart: always

volumes:
  app_postgre:
    external: true

````

## Gemfileの作成
````sh
source 'https://rubygems.org'
gem 'rails', '6.0.3'
````
Gemfile.lockは空のままでいいです。

## コンテナをBuildしてappを作成
````sh
$ docker-compose run app rails new . --force --database=postgresql --skip-bundle
````

## webpackerのinstall
````sh
docker-compose run app rails webpacker:install
````

## Databaseの作成と設定

作成されたappのdatabase.ymlを設定します。

````sh
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # 以下を記述
  user: admin
  password: admin-pass
  host: postgres
````

## imageをbuild
````sh
docker-compose build
````

## Databaseの作成
````sh
docker-compose run app rails db:create
````
以上で構築完了です。
以下のコマンドでアプリを起動して

````sh
docker-compose up
````
http://localhost:1501/
にアクセスすれば以下の画面に表示されます。

![スクリーンショット 2020-10-18 20.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501889/b7875e37-3972-d0c1-76f1-44fba8e312e4.png)

以上です。
axiosのinterceptorsで、requestのキャンセルを行う

# tl;dr
`interceptors.request.use()`内で`axios.Cancel()`をthrowすることでリクエストを直前でキャンセルできます。

# 🚀サンプル
認証トークンがlocalStorageに保存されており、トークンがなければAPIリクエストを投げたくないというケースを考えてみます。

認証トークンを取得する関数は以下です。

```JavaScript
function getToken(){
  return window.localStorage.getItem("token");
}
```
axiosのinterceptorsを定義します。

```JavaScript
const axios = require('axios');

  axios.interceptors.request.use(config => {
    if (!getToken()) {
      throw new axios.Cancel('トークンがないためリクエストはキャンセルされました');
    } else {
      config.headers.Authorization = "Bearer " + getToken();
      return config;
    }
  });
```

適当なドライバを作成し、コールしてみます。この時、ローカルストレージは空なので、requestがキャンセルされるはずです。

```JavaScript
  async function getZip() {
    try {
      const response = await axios.get('http://api.thni.net/jzip/X0401/JSON/064/0941.js');
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  }

  getZip();
```
実行結果

```
Cancel { message: 'トークンがないためリクエストはキャンセルされました' }
```
思惑通り、requestはキャンセルされました。

以上。
[Tips]初心者向け XCodeやSwiftで困ったときの解消法

# 環境
`macOS:Catalina 10.15.6`
`Xcode:12.0`
`Swift:5.3`

# 筆者について
趣味で`swift`を勉強中の只のエンジニアです。仕事では全く使っていません。
`swift`は2015年頃に一度勉強していて、最近再燃して勉強し直しています。

#1.Stack Viewの制約がうまくつけられない
`spacing`の値に0以外の値が入っていると制約に影響が出てしまうようなので、
`spacing`には0を入力した方が良いです(制約に影響が出ない箇所なら可)。
![スクリーンショット 2020-10-18 19.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204486/b68f94e3-224d-a5d7-5e4d-3d2809645809.png)

#2.新しいクラスを作成しプロトコルを継承すると、警告が出る。
`Cannot declare conformance to 'NSObjectProtocol' in Swift;`
と言って怒られます。
この場合、`import Foundation`した上で、`NSObject`を継承すれば解決です。
私の場合、`import Foundation`を削除した上で試行錯誤していたので、大変でした。

#3.ビルドエラー
`Multiple commands produce XXX`が発生。
詳しく見ると`Target [アプリ名] has copy command from XXX`と`Target [アプリ名] has link command with output XXX`が発生。
少し調べてみると何かが衝突しているようだった。`.swift`ファイルを`XCode`上で手動コピーしたのがまずかったのかと思う。
よく分からなかったので、プロジェクトを作り直すことで解決した。
`XXX.swift`と`Main.storyboard`を`Finder`上で、旧プロジェクトフォルダから新プロジェクトフォルダへコピーすることで解決した。
`Main.storyboard`の場所が一瞬分からなかったが、`Finder`上では`.../[アプリ名]/[アプリ名]/Base.Iproj/`の中にある。

#4.オブジェクトを比率で上手いこと調整したい(高さ40%のTableViewなど)
[こちら](https://pippi-pro.com/swift-dummyview-responsive)のサイトが参考になります。

#5.テキストが改行されない
改行コードを入れて任意の箇所で改行させたいが、改行されない。
`¥n`ではどうも効かないようで、`\n`と入力する必要があった。
`\`は`option`キーを押しながら`¥`を押下で入力できる。

#6.`.swift`ファイルへ`Outlet`接続、`Action`ができない
遷移先など新しく`ViewController`を作成し、最初からある`ViewController`と同じようにびよーんと接続をしようとしたが、`Object`項目が`Exit`しか選択できない。
![スクリーンショット 2020-10-24 21.32.08（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204486/1f9698b8-90ab-76a2-d8d1-39fb43baf601.png)

`Storyboard`上で対象の`ViewController`を選択。
`Identity Inspector`の`Custom Class`から`ViewController`に対応するクラスを選択する。
(画像は修正後)
![スクリーンショット 2020-10-24 21.37.51（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204486/6df2ae51-a82d-c83c-6a48-a485aac337cb.png)

#7.`TableView`を外出しできない
`ViewController`の肥大化を防ぐ為、`UITableViewDelegate`、`UITableViewDataSource`を継承したクラスを別途作成し、そのクラスに処理を委譲することができる。
この場合、気をつける点がある。
委譲する先のクラスのインスタンスは`viewDidLoad()`の外で生成する必要がある。
まあ、少し考えてみれば当然だが。
委譲先を`ViewController`(自分)にする場合は、`viewDidLoad()`の中でインスタンス生成しても問題なく動く。
本題とずれるが、タイミングなどの問題でインスタンス生成を`viewDidLoad()`の中でやりたい場合(何かの処理の後にしたい場合)、`viewDidLoad()`の外側で変数宣言だけしておき、`viewDidLoad()`の中で代入すれば問題ない。

#8.ビルド時に`Command CompileAssetCatalog failed with a nonzero exit code`が発生
私の場合複数の画像ファイルを使用しており、数十枚程度ならエラーは出なかったが、ある1枚のファイルを追加するとエラーが発生、という事象が発生した。
調べても原因が分からなかった(`OS`と`XCode`は最新化したら解決するという記事もあったが解決しなかった)。
ひとつ心当たりがあって、`png`ファイルを`jpg`に変換した画像を`Assets.xcassets`に追加していたのがマズいのではないかと思い、そのまま`png`で保存すると、大丈夫なようだった。
使用している画像ファイルが多く、最終的に解決しているか不明である為、参考程度にして頂きたい。
エラーバンドリングの表示

【概要】
----------------------------------------
<b>1.結論</b>

<b>2.どのようにコーディングするか</b>

<b>3.開発環境</b>

<b>補足</b>




1.結論
----------------------------------------
<b>@if (count($errors) > 0) と、@foreach</b>を使用する!
<br>

2.どのようにコーディングするか
----------------------------------------
@if や @foreach の使い方は自分のこちらの記事にて説明しているので、よかったらご覧ください！
<a href="https://qiita.com/taka_no_okapi/items/c5e4ceebafe6e0144b83">blade構文</a>

```php:resorces/views/hoge/index.blade.php
<p>{{$msg}}</p>
 @if (count($errors) > 0)
  <div>
   <ul>
    @foreach ($errors->all() as $error)
     <li>{{$error}}</li>
    @endforeach
   </ul>
  </div>
 @endif
```
エラーメッセージあれば、そのエラーの全てをそれぞれ取り出すようにしています。そしてそれを変数を用いて表示しています。


ただ、バリデーションがかかっていることが前提なので下記のようにコーディングしています。

```php:app/Http/Controllers/HogeController.php

class HogeController extends Controller
{
    public function index(Request $request)
    {
      return view('hoge.index', ['msg'=>'入力してください:']);
    }

    public function post(Request $request)
    {
      $validate_rule = [
        'name' => 'required' ,
        'mail' => 'email' ,
        'age' => 'numeric|between:0,150' ,
        ];
        $this->validate($request , $validate_rule);
        return view('hoge.index' , ['msg'=>'正しく入力してください']);
    }
}
```

<br>

3.開発環境
----------------------------------------
Mac catalina 10.15.4
Vscode
PHP 7.4.10
Laravel 8.9.0
Apache 2.4.41
<br>


補足
----------------------------------------
エラーバンドリングを表示させるということは2.のあとにform要素を付け加えると思います。その際に@csrfの記載を忘れないでください。セキュリティ対策になります。