OmniAICreator/Qiita-1.07M huggingface dataset:
ADFSサーバーでのHSTSヘッタの設定

#初めに
ADFSサーバーのセキュリティ監査などでHSTSヘッタの不備を指摘されることがあります。ADFSサーバーの場合、Webの認証トラフィックは、HTTPS経由で開かれるため、HSTSヘッタの設定がないこと自体は問題ないと考えられますが、セキュリティ監査では、ヘッタが返されることが監査のクリア条件などになることがあります。
本ドキュメントでは、HSTSヘッタ（HTTP Strict-Transport-Security）の設定手順に関して記載します。

#HSTSヘッターとは
HSTSヘッタは、HTTPとHTTPSの両方のエンドポイントを持つサービスにアクセスする際に必ずHTTPSアクセスを行い、HTTPでのアクセスを使用してはいけないこと宣言するヘッタです。

#事前確認
設定を行う前に、現在のADFSサービスのアクセスでHSTSヘッタ情報が含まれていないことを確認します。chromeなどを開きF12キークリックし、「ネットワーク」タブを開いてADFSサーバーの下記のURLにアクセスを行います。

https:// ADFSサーバーのURL/adfs/ls/IdpInitiatedSignon.aspx

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526427/9a104e22-66d1-4da7-0ad3-967abf4c9303.png)
「Name」の一番最初の通信をクリックし「Response Headers」のセクションの中に、「Strict-Transport-Security」ヘッタが無いことを確認します。

#設定
ADFSサーバー（複数台ADFSサーバーがある場合、プライマリのADFSサーバー）にログインします。　管理者権限で、PowerShellを起動します。
PowerShellで下記のコマンドを入力します。

```
Set-AdfsResponseHeaders -SetHeaderName "Strict-Transport-Security" -SetHeaderValue "max-age=31536000"
```
最後の「max-age」は、有効期限で１年です。この期間を短くすることは推奨されていません。下記のコマンドで設定を確認できます。「Strict-Transport-Security, max-age=31536000」の項目が表示されれば、設定ができています。

```
Get-AdfsResponseHeaders
ResponseHeaders : {[X-Frame-Options, DENY], [Content-Security-Policy, default-src 'self' 'unsafe-inline' 'unsafe
-eval'; img-src 'self';], [Strict-Transport-Security, max-age=31536000]}
ResponseHeadersEnabled : True
```

#確認
chromeなどを開きF12キークリックし、「ネットワーク」タブを開いてADFSサーバーの下記のURLにアクセスを行います。

https:// ADFSサーバーのURL/adfs/ls/IdpInitiatedSignon.aspx

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526427/e16e48e1-d3bd-094c-dcdf-877aca0de35b.png)

ヘッタに「Strict-Transport-Security」があることを確認します。

#参考資料
[AD FS 2019 で HTTP セキュリティ応答ヘッダーをカスタマイズする][Link1]
[Link1]:https://docs.microsoft.com/ja-jp/windows-server/identity/ad-fs/operations/customize-http-security-headers-ad-fs
1週間RealmSwiftを勉強してわかった事 Part4

# 今回の内容

* CRUDのD(Delete)➡️Realmに保存しているデータ<font color="Red">削除</font>をする

# Realmのデータを削除する(Delete)
1.`import RealmSwift`をimportしてなければ、記述しましょう。(エラーが<font color="Red">Could not build Objective-C module 'RealmSwift'</font>と表示されたらXcodeの左上の▶️(Ranボタン)でBuildして下さい)

```Swift:Modelファイル
import RealmSwift 
```
2.`do{}catch{}`を用意する。(これで`try`の後の関数で<font color="Red">Error</font>が出ても、アプリが落ちないので`catch{}`内の処理が呼ばれます)

3.`do{}`の`{}`内で、`Realm()`をインスタンス化します。➡️`let realm = try Realm()`のことです。

注：`class RealmDatas:Object{}`を作成した事を仮定して説明を進めます。

4.`do{}`の`{}`内で、`realm.objects(RealmDatas.self)`を使用してRealmに保存してあるRealmDatasのデータを全件取得します。取得時は<font color="Red">配列</font>の状態で取得されます。

5.`try realm.write({})`で<font color="Red">writeトランザクション</font>を作成します。

6.`try realm.write({})`内で、`realm.delete(readRealm)`で削除出来ます。　

```Swift:Modelファイル
do{
            let realm = try Realm()
            let readRealm = realm.objects(RealmDatas.self)
            
            try realm.write({
                
                realm.delete(readRealm)
                
            })
            
        }catch{
            
            //エラー処理など
            
        }
```

# 今回はここまで

読んでみて間違っている部分などがありましたら、コメントで指摘して頂けると嬉しいです。
Grafana と InfluxDB 2.0 を接続する

http://localhost:3000/
にアクセスして、Grafana にログインします。

Data Source として、InfluxDB を選びます。
![grafana_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/5fd8a3bf-2914-9c99-8243-8bc60e64a493.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/037cacda-a3d5-9c41-048b-2d772758c63c.png)


Query Language として Flux を選びます。
URL として http://localhst:8086 を入れます。
　（薄く表示されている状態では、まだ URL が入力されていません。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/3ed60465-cd1f-f3f9-fae7-1782c8bd912f.png)


Organization
Token
Default Bucket
を入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/5f8ddf66-80a5-7032-f9e5-c795884aaa2d.png)


Save & Test をクリックします。
問題がなければ、Bucket の数が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a7287535-c591-a700-18e0-1cf28d0254bf.png)


バケットの状況を InfluxDB CLI で表示した場合

```text
$ influx bucket list
ID			Name		Retention	Shard group duration	Organization ID
f7cfd0289da80e9c	_monitoring	168h0m0s	24h0m0s			3f7974659a9fae16
ff7c957a49d147ab	_tasks		72h0m0s		24h0m0s			3f7974659a9fae16
2f0f2da2371e61ac	gunma		infinite	168h0m0s		3f7974659a9fae16
1a33e44c591bcdff	ibaraki		infinite	168h0m0s		3f7974659a9fae16
db0439b7cecead06	tochigi		72h0m0s		24h0m0s			3f7974659a9fae16
```

## Query の設定

次の Query を設定します。
 dbtest というバケットからデータを読み込みます。

```text
from(bucket:"dbtest") |> range(start: -2h)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c063dca2-6cbf-c493-d576-785dd9e6025a.png)

InfluxDB 2.0 へのデータの入れ方はこちら
>[InfluxDB v2: Python Client の使い方 （時系列データ)](https://qiita.com/ekzemplaro/items/9891d974c05a8579879f)

## 参考情報
[InfluxDB の cli の使い方 (2.0)](https://qiita.com/ekzemplaro/items/f3c8a58e337e8d974b24)
転職できるまで何にも知らない人間がTypeScript+Reactの勉強をする(その1)

>知らない状態は、知ってしまうと二度とは訪れない

# 筆者初期状態

- React聞いたことあるけど全く知らない
- TypeScript勉強中

# Reactとは
A. ユーザーインターフェース作成時に使用すると便利なもの。ウェブ以外のユーザーインターフェース作成時にも使用できる。

# 今回の目的

TypeScript+Reactの環境構築

# 導入

## 実行環境
- OS:Windows 10
- 端末:Visual Studio Code(WSL:Ubuntu)

## 手順

TypeScript使用可能なReact用のプロジェクトフォルダを以下のコマンドで作る。

```
npx create-react-app react01 --template typescript
```
※npxコマンドが実行できない場合はnpmをインストールする。

セットアップ完了後、プロジェクトフォルダに移動してプロジェクト実行。

```
cd react01
npm start
```

こんな画面がブラウザで表示されたら成功。
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792099/74cab9e5-daee-7979-59d3-6f4391ae2eea.png)

成功していれば端末でCtrl+Cを押しプロジェクトの実行を終了させる。

# 次
[Hello world](https://qiita.com/botanic7arc/items/d71b292eb5a3c40d23de)


# 参考文献

- [Reactをはじめる - ウェブ開発を学ぶ | MDN](https://developer.mozilla.org/ja/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started)
- [React - TypeScript Deep Dive 日本語版](https://typescript-jp.gitbook.io/deep-dive/tsx/react)

## 余談

[TypeScript React]でGoogle検索すると、1ページ目から完全初心者には理解不能なページがいっぱい出てきて怖い(2021/7時点)
Railsで架空のCafeのHPを作ってみよう!【3日目】

#概要
基本Railsの記法に則り書いていきます！
１から全ての説明ではなく
その中であれ？どうやるの？と
疑問に思った点や実装に困った箇所を
ピックアップして紹介していきます♩

#設定と準備
・Rails
・HTML
・CSS
・Javascript(jQuery)

↑上記の言語とフレームワークを使い
架空(自分で考えたテキトーなもの)のCafeの
HPを作っていこうと思います！

#3日目の作業内容:round_pushpin:
・トップページのレイアウトとCSS

#3日目の躓いた箇所:zap:
背景画像の上にグラデーションを
かけたいが上手くできない！

```index.html.erb

<body>

  <div class="a"　/>

</body>

```

```index.css

body {
  background-image: url(sample);
  background: linear-gradient(0% red, 50% blue)
  opacity: 0.5;
}

```

この書き方では全体にbody以下の階層全部(今回の場合要素aを含む)にopacityがかかってしまう。



#結論
背景画像だけにグラデーションをかけたい場合
rgbaを使い、色の指定をしなければならなかった。


```index.css

body {
    background: linear-gradient(rgba(235, 114, 219, 0.8), rgba(153, 134, 241, 0.8)) fixed, url(sample) fixed;
}

```

このようにrgba(4つ目の数値がopacityの役割)を使い
背景画像をurl()で追記する形にすることで解決。
エクステンション(Swift)に関して

エクステンション機能とは
--
既存のクラスや構造体、列挙型、プロトコルの機能を拡張できる



```swift:拡大.swift
extension 型 {
  // 追加したい要素の記述
}
```


エクステンションはストアドプロパティは使用できない。
クラス間のデータ構造で継承が有名。
それに対して、extensionは動的に機能を拡張でき,可読性が高まる。

Object-Cのカテゴリー機能が強化されてSwiftで使われるようになったらしい。

インスタンスメソッドやイニシャライザ、コンピューテッドプロパティ、サブスクリプトを拡張する（ドキュメント参考）
--

インスタンスメソッドVer

```swift:
extension 型　{
　　　func kakutyo()　{return "あいうえお"} 
}
```

コンピューテッドプロパティVer

```swift
var kaku :String = "a"
var tyo  :String = "i"
extension 型　{
var kakutyo: String {
    return kaku + " " + tyo
  }
}
```

イニシャライザVer

```swift
extension 型 {
  // イニシャライザを追加する
  init(_ x: Int, _ y: Int) {
    self.x = x
    self.y = y
  }
}

```

サブスクリプト

```swift
extension Int {
  subscript(index: Int) -> Int {
    return self * index
  }
}
//上記の記述はgetのみなのでgetと｛｝を省略した場合。通常であれば下記の記述となる。
　　　　subscript(index: Int) -> Int {
    // インデックスを指定して pets の中から値を取り出す
    get {
      return self * index
    }

//またget,setを使用する場合

subscript(index: Int) -> Int {
    // インデックスを指定して pets の中から値を取り出す
    get {
      return self * index
    }
    // 新しい値を追加する
    set {
      self * index = newValue
    }
  }

//newValueがデフォルトで新しい値が入ってくる。
```


*サブスクリプトとは
配列のようにクラスから作られたインスタンスにもインデックスをつけることができる機能のこと。
クラスだけでなく、構造体や列挙型にも使用可能。
iOS アプリを公開するまでに必要だったこと/忘れがちなこと、まとめ

## 概要
iOS アプリを開発して、いざリリースする時に、「実はコレも必要でした」ってことがあったので、その情報を事前に知っておくための備忘録。

アプリ開発戦略の参考情報にでもなれば幸いです。

## iOS 開発〜リリースまでの流れ
そもそも、環境ゼロの状態から、開発〜アプリリリースまでの全行程をざっくりとまとめてみた。

- Apple IDを用意
- Apple Developer Program へ登録
  - App Store Connect へのログインできるようになる
  - Certificate（証明書）や Profile（プロファイル）の設定
- 開発環境の用意
  - Xcode 導入、Xcode 以外のコードエディタなどを使う場合は、それも導入
  - サーバ（Web/Ap等）、や DB を使用する場合は、その環境も用意
  - クラウドサービスを使用する場合、それも用意（例： Google アカウントを作成し、Firebase プロジェクト作成等）
- 開発。コーディング・テストしてアプリ完成させる
- Xcode でビルド＆アーカイブして、Xcode から App Store Connect にアップロードする
- App Store Connect の新規アプリの審査情報を入力
- 審査提出
  - 無事通過すれば、アプリリリース完了
  - リジェクト（審査通らず）の場合は、リジェクト理由を対応して、再審査

## 意外と抜けがちな、実は必要なこと一覧
ざっくりと流れを把握した上で、その中で「意外と抜けがちなこと」もしくは、作業が止まるので「事前に準備しておいた方が良いこと」をまとめてみた。

|内容|留意点|
|:--|:--|
|Apple Developer Program 登録|有料($100/ドル程)、申請してもアカウントが有効になるまでに時間がかかる（３営業日くらいかかった）|
|Xcode の導入・最新化|初めての人はそもそも入れてないこともある。かなりファイルが重いし、ネット環境が悪いと時間もかかる|
|Certificate（証明書）の発行・管理|そもそも、何故・何に必要なのかを知らずに行うと、無くしちゃいけない機密ファイルを紛失したりなどのリスクがある。事前に流れと内容を把握しておくのがオススメ|
|Bundle ID を決める|そもそも、App Store に申請する以前に、Firebase 等のクラウドサービスを利用する場合は、Bundle ID を求められる。<br>この時、テキトーに決めてしまうと、正式にリリースしたくなった時に、これらサードパーティサービスの設定ファイルを修正・再作成する必要が出て、修正ミスって通信できなくなるなど、つまらないヒューマンエラーを発生させる要因となる。<br>公式Webサイトとのドメインの整合性が取れないことで対応するための追加作業が発生したりもする。<br>なので、事前に決めておいた方が良い。できれば命名規則など作った方がより良い。<br>公式Webサイト内の説明や、社内でのプレゼン・説明にも流用できるのであった方が良い|
|アプリ名/IDが使えるかどうか|アプリ名やアプリのIDにしようと思っていた単語をWeb検索し、同じ単語のWebサイトや既存商品は多くないか？、商標として利用可能か？、既存の商品名とかとカブってたとしても問題がないか？、などを軽く検索しておくのが良いと思う<br>企業文化や個人によっては、サービス内容とアプリ名が深く影響し合うこともあると思うので、事前に下調べは必要。|
|アプリの特徴や説明文|App Store に公開される説明文や特徴内容を、適度な文字数やわかりやすい内容になるように、事前にまとめておくのが良い|
|iOS App IDs 登録|アプリ毎に作成する個別情報。一度作った App ID は削除できない。登録する内容は、「アプリ名」「Bundle ID」「App Service 設定（例えば、Push Notification等）」|
|アプリアイコンの作成|サイズ別に、結構な数のアプリアイコンを用意する必要がある。「.png」ファイルを必ず「アルファ（透明化）無効」でなければならない。これが不正だと、Xcode アーカイブ＆アップロードの時点でエラーとなる。<br>事前にアプリデザインを終わらせておき、1024×1024px の PNG 画像を用意し、『[App Icon Generator](https://appicon.co/)』などで生成しておくのがオススメ|
|Provisioning Profile の作成|Provisioning Profile（プロファイル）はアプリ毎に作成する。Production Certificate（証明書）に紐づけられているので、プロファイルを作るには、更に先に証明書を作っておく必要があります|
|サポート URL|【アプリ申請時、提出必須の項目】内容は事前にテンプレートのようなものを作っておいた方が良い。<br>つまりは、**結局「アプリの公式なWebサイト」を１つ事前に用意する必要がある。**<br>これが意外と後手の対応で一番、面倒臭かった|
|プライバシーポリシー URL|上に同じ|
|アプリのスクリーンショット|【アプリ申請時、提出必須の項目】アプリの説明ページに公開されるため、含まれる画像の著作権なども気をつけないといけない。スクリーンショットに含まれても問題のない素材を事前に用意しておくべき。また、6.5インチ/5.5インチの各画面サイズで最低１枚の画像提出が必要なので、シミュレータのデバイス設定なども、リリース申請前までには事前に終わらせておく|


## まとめ
意外とやることがたくさんあるので、テンプレートファイルや現場運営上のフレームワークを用意しておいて効率的に進めるのが良さそう。
ValueError: Classification metrics can't handle a mix of multilabel-indicator and binary targetsの解決法が分からないから書いた。

#経緯#
2値分類をするディープラーニングの結果(確率結果)に対して混同行列を作りたくて、sklearnのcofusion_matrixを使ったけど、

```python:error
ValueError: Classification metrics can't handle a mix of multilabel-indicator and binary targets
```

errorが出た、、
原因はテストデータの正解ラベルと推論結果の形式が違うからだと思う。

```python:
#テストデータ：one-hot
[[0.1.]
 [0.1.]
   :  
 [1.0.]
 [1.0.]]

#推論結果：確率
[[0.011592121794819832,0.9884079098701477]
                   :
 [0.9900621175765991,0.009937929920852184]]
```
いろいろ調べて試してみたけどよく分からんし、練習がてら自分で作ってみようと思いました！！

#作ったやつ#
テストデータは0と1の画像各100枚で、0の画像は正解ラベルが0、1の画像は正解ラベルが1と想定してます。また、分類時の閾値は0.5にしてます。評価しているのは0の画像です。

```python:コード
y_pred = model.predict(X_test)  #テスト

label = Y_test.reshape(-1,1)  #one-hotにする前の正解ラベルをn行1列に変換
result = np.concatenate([label,y_pred], 1)   #正解ラベルと結果を結合->n行3列
np.savetxt("result.txt", result, fmt = "%s", delimiter = " " )  #保存

map = np.array([[0,0],[0,0]])
result = pd.read_csv("result.txt", sep = " ", header = None, dtype = "float32") #ファイルを開く
result = np.array(result)
for col in result:  #ファイルを1行ずつ読み込み
    if col[1] > 0.5:      #predict_0>0.5    
       if col[0] == 0:    #label_0=predict_0
          map[0,0] += 1   
       else:              #label_1=predict_0
          map[0,1] += 1
    if col[2] > 0.5:      #predict_1>0.5
       if col[0] == 1:    #label_1=predict_1
          map[1,1] += 1    
       else:              #label_0=predict_1   
          map[1,0] += 1

print(map)
print("test accuracy:",(map[0,0]+map[1,1])/(map[0,0]+map[1,1]+map[1,0]+map[0,1]))
print("test precision:", (map[0,0])/(map[0,0]+map[0,1]))
print("test recall:", (map[0,0])/(map[0,0]+map[1,0]))
```

```python:出力
[[99 5]
 [1 95]]
test accuracy:0.97
test precision:0.95192308
test recall:0.99
```

本当はもっと簡単なやり方あるんだろうけど。。。
よかったら教えてください！！！
pypi に自作ライブラリを登録する手順(2021版)

# pypi に自作ライブラリを登録する手順(2021版)
## pypiとは？

Python Package Indexの略とのこと。
pip install ライブラリ名で簡単にライブラリがインストールされます。


# ざっくりと説明。
####①pypiでユーザー登録。

####②Gitにリモートリポジトリにpush。

####③パッケージをビルドする。

####④パッケージをアップロードする。
### これだけです。
```
pip install twine

python setup.py sdist
python setup.py bdist_wheel

git add .
git commint -m ''
git push origin main

twine upload -u pipyのユーザーID -p pipyのユーザーPW --repository-url https://upload.pypi.org/legacy/ dist/*
```

ソース元
======

> [Pythonで自分だけのクソライブラリを作る方法](https://zenn.dev/karaage0703/articles/db8c663640c68b)

>[Python: Twine を使って PyPI にパッケージをアップロードする - CUBE SUGAR CONTAINER](https://blog.amedama.jp/entry/2017/12/31/175036)

>[Pythonで作成したライブラリを、PyPIに公開/アップロードする - Qiita](https://qiita.com/icoxfog417/items/edba14600323df6bf5e0)

>[【Python】PyPIエラー対応 Invalid or non-existent authentication informationの対処法 - Qiita](https://qiita.com/shonansurvivors/items/f4649b620f404eddb4e9)

>[Scraping-Perlverity-Python](https://pypi.org/project/Scraping-Perlverity-Python/)

>[gitにpushする際に失敗してしまいます。｜teratail](https://teratail.com/questions/187949)

>[gitignoreの書き方チートシート2021年版](https://leading-tech.jp/wiseloan/gitignore/)
javascriptからAWS S3へのアップロード

Every Qiita #7
のんびり独学初学者の毎日投稿チャレンジ 7日目
今回は・・・
自作コミュニティアプリ開発にてjavascriptからサーバー側へのデータ受け渡し、コントローラでS3への保存を実装した時の備忘録になります。

###Ajaxでデータを送信
```javascript:index.js
 function json(url){
    // リクエストインスタンスの生成
   var xhr = new XMLHttpRequest();
  // csrfトークンの生成
   let csrf_token = document.getElementById('csrf_token').getAttribute('content');
   // 送信先の設定
   xhr.open('post',url);
   // ヘッダーの設定
   xhr.setRequestHeader('X-CSRF-Token', csrf_token);
   return xhr;
}

var xhr = json(routeで設定したパス);
// データ送信
xhr.send(送信するプロパティ);

```
####解説
1. json形式でファイルを送信するのでnew XMLHttpRequest()でインスタンスを生成します
1. リクエストにはヘッダーとメソッド・送信先のパス、プロパティが必要になります
 1. laravelにはcsrfトークンがデフォルトで記載されているので`views/layouts/app.blade.php`から持ってきます。
 1. メソッドはデータを送信するのでpostにします。urlはrouteで設定したパスを記述します
1. 関数にしておくことで、パスを引数に設定すれば非同期でデータを送信することができます。
1. 関数を呼び出し、sendメソッドでデータを送信します。

###controllerで受け取りS３へアップロード
```php
public function img_upload(Request $request){
  // s3へのアップロード 第一引数は任意のフォルダ名をつける
  $path = Storage::disk('s3')->putFile('/question', $request->image, 'public');
  // フルパスの取得
  return Storage::disk('s3')->url($path);
}
```
####解説
1. 今回はimg_uploadメソッドで画像をアップロード処理をしていきます。
1. $requestにjsonで送られたデータが格納されています。
 1. データはFormDataオブジェクトでname="image"に画像パスが入っています。
1. Storage::disk('s3')とすることでAWSのS3ストレージへ接続できます
 1. **AWS設定については[こちら](https://qiita.com/nobu0717/items/4425c02157bc5e88d7b6)の記事を参考にさせて頂きました。[@nobu0717](https://qiita.com/nobu0717)さんありがとうございました！**
1. putFileメソッドで任意のディレクトリに保存することができます。
 1. 第一引数はパスになります。（/以下は自動的にディレクトリが生成されるので何でもいいです）
 1. 第二引数には値が入ります。今回は$requestのimageキーに値が設置してますので、上記のようになります。
1. return では保存した画像パスをレスポンスとして返すことでjavascriptで操作できます。

![スクリーンショット 2021-07-09 15.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/813099/7091a70f-9f40-c020-70c4-b5cc881a6225.png)

questionディレクトリが作成されました。画像はこのディレクトリ配下に保存されます。
Safari 14.1.1（macOS 及び iOS 14.6）で初回 indexedDB.openが正常に動作しない問題


## 問題
WKWebView上にWebアプリケーションの一部画面を表示する機能を作成しており、indexedDB上のデータ取得が、特定条件で正常に動作しないことに気が付きました。
## 原因
最新のSafari（MacOSおよびiOS 14.6の14.1.1）で初めてロードしたときに indexedDBのopen(データベースを開くリクエスト)が永遠にpanding状態でリクエストが消失する不具合が、WebKitにあるようです。
[indexedDB.open() sometimes hangs forever in pending state on first page load in iOS 14.6 / WebKit Bugzilla](https://bugs.webkit.org/show_bug.cgi?id=226547)

## 対策
有志によって[npm/safari-14-idb-fix](https://www.npmjs.com/package/safari-14-idb-fix)が用意されているようですが、自環境では解消出来ず、`WKUserScript`を利用して消失しても問題ないリクエストを事前に実行することで解消しました。

```swift
let configuration = WKWebViewConfiguration()
let userContentController = WKUserContentController()
let userScript = WKUserScript(source: "window.indexedDB.open(\"dummy\", 1);", injectionTime: .atDocumentStart, forMainFrameOnly: false)
userContentController.addUserScript(userScript)
configuration.userContentController = userContentController
webView = WKWebView(frame: .zero, configuration: configuration)
```


## 参考
https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API/Using_IndexedDB
https://bugs.webkit.org/show_bug.cgi?id=226547
https://www.npmjs.com/package/safari-14-idb-fix
https://bugs.webkit.org/show_bug.cgi?id=225344
https://gist.github.com/pesterhazy/4de96193af89a6dd5ce682ce2adff49a#bugs-bugs-bugs-safari
Slack で bot を除くメンバー一覧の取得方法

プログラム組むのも手間だなーと思い、シェルだけでやってみた。
この3stepで取得可能。

# token取得

slack app 作ってtoken取得しておく
![slack_token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1533/c8b37052-e4de-b8a9-f283-7853c0221784.png)

token取得の細かい手順はこちら参考
https://qiita.com/sukebeeeeei/items/7b059f0d8f90183ecb67

# ユーザ一覧取得

curlでAPI叩く

```sh
curl -X POST -H 'Authorization: Bearer <token>' \
-H 'Content-type: application/json' \
https://slack.com/api/users.list > users_0.json
```

上記の結果、next_cursor が空じゃない場合は、続けて以下

```sh
curl -X POST -H 'Authorization: Bearer <token>' \
-H 'Content-type: application/json' \
https://slack.com/api/users.list\&cursor=<next_cursor> > users_1.json
```

`&` の前に `\` がいることに注意。
これらで取得した一覧にはbot（slack app）も含まれる。

# botを除く

取得できたusersxx.jsonを一つのusers.jsonとしてmergeして `jq` でfilterする

```sh
cat users.json | jq '.members | map(select(.is_bot == false)) | map({id: .id, name: .name})'
```

結果例

```json
[
  {
    "id": "UXXXXXXXXX01",
    "name": "xxxxx.yyyyy"
  },
  {
    "id": "UXXXXXXXXX02",
    "name": "zzzzz.yyyyy"
  },
・・・
]
```
セルフサービスBIの定着化はデータの下処理で決まる！　日付マスタ/カレンダーマスタに必要な項目


#はじめに

先日BI製品MotionBoardのユーザコミュニティに参加してみました。

そこで参加メンバーのみなさんが口をそろえて「データの下処理をしっかりしないとなかなか活用できないよね」と言っていたのが印象的で、ストアドを組んだり、何かしらのDWH、Dr.Sum等を使って対応されている方が何名かいたかなという感じでした。

ただそのあたりに手を付けられていない方もかなり多く、チャートを作る際に非効率だったり、苦労されているようでした。

今回はその下処理の一助になればとの思いで、どの会社でも活用でき、利用頻度も高い日付マスタ/カレンダーマスタの仕様についてまとめてみたいと思います。

#日付の課題

年、月、週、等、時系列って集計項目には欠かせない要素ですよね。
でも社内のレポートをよくよく見るとイロイロな粒度/要素/形式があることに気が付きます。
だからこそイロイロな課題も発生します。

![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46156/6ffcb735-7bdb-c6fd-ea2c-54acbc8605e2.png)


日付項目が１つあってもそれを色々な形に加工する必要があり、利用する敷居が高いのが現状ではないかと思います。

・加工が必要な項目が多くある（期、年度、四半期、半期、曜日、年次週、他）
・都度加工計算処理するのでパフォーマンスに影響が出る（遅くなる）
・システム毎に日付の形式が異なり結合しずらい
・海外製のBIツールは和暦なんて考慮していないので準備が手間


#日付マスタ/カレンダーマスタに必要な要素、ポイント

日付マスタ/カレンダーマスタに必要な要素やポイントは以下のようになるのではないかと思います。

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46156/97641263-283f-5bbd-1827-1c7ccc5ce3a9.png)


・日本国内の企業で一般的に利用されるであろう項目（関数等で加工し生成）を一通り用意する
・様々なシステムから結合できるように結合用に複数の日付項目を用意する


#日付マスタ/カレンダーマスタの必要項目

記載した要素ポイントを考慮すると私が準備した日付マスタ/カレンダーマスタはこんな項目を用意することにしました。



|項目名|形式内容|例|
|:-----------|:------------|:------------|
|日付|yyyy/MM/dd|2021/07/09|
|日付2|yyyy-MM-dd|2021-07-09|
|年月日|yyyyMMdd|20210709|
|年|yyyy|2021|
|年月|yyyyMM|202107|
|月|MM|07|
|Month|月 英語|Jul|
|日|dd|09|
|年度|期初時点の年|2021年度|
|曜日番号|1-7 日曜日が1|6|
|曜日|日本語|金|
|Week|曜日 英語|Fri|
|和暦|年号|令和|
|和暦|年|令和03年|
|和暦年度|期初時点の和暦年+"年度"|令和03年度|
|期|創業日からの年数　初年度は1と数える|1|
|四半期|1-4|2|
|半期|1 or 2|1|
|半期上下|上期 or 下期|上期|
|月次週|月のN週目|2|
|年次週|年のN週目(53週目まで)|28|
|年次週_年度|年度のN週目(53週目まで)|15|


#最後に

このような要素を盛り込んだ日付マスタ/カレンダーマスタを用意しておけば、多くのトランザクションデータと結合して簡単に利用できるようになるのではないかと思います。

実際にこの日付マスタを作成するプログラムをCUIのJavaプログラムで作成したので、次回はその作り方をご紹介しようと思います。
javascriptにおける論理積、論理和を用いて書いた疑似if文を許すべきか否か

#はじめに
最近Reactの勉強をしている最中にjavascriptの論理積、論理和を用いて端的にif文みたいなのを書く方法を知った。なぜそうなるのか分からなかったので原理を調べてみたのと、それを理解した上でこれを使って良いのかについて考えていきたい。

#javascriptにおける論理積と論理和
javascriptでは論理積と論理和は真偽値だけを返すものではなく、オペランドの左右のオペランドのどちらかを返すものです。他の静的型付言語では真偽値に対して使うことが多いですが、javascriptではいろいろ扱えるので結果的に真偽値以外のものが返せるということになっているのだと思います。要するにオペランドそのものまたは返り値がboolean型だった場合boolean型を返しますが、違う型だった場合はそれを返す可能性があるということです。

論理積では左辺がtrueでない場合は右辺に関係なくfalseなので右辺は実行せずに左辺を返します。逆に左辺がtrueの場合右辺の結果がそのまま論理積の結果になるので右辺を返します。反対に論理和では左辺がtrueの場合は右辺をみる必要がないのでそのまま返してtrue。左辺がfalseの場合は右辺を返します。これを利用してコードの省略を行うべきなのかという点が今回の疑問点です。

#実例
codesandboxでいろいろ試してみた。

```js
let flag = true;
if(flag === true)
  document.getElementById("app").innerHTML = `<h1>Hello</h1>`;
else
  document.getElementById("app").innerHTML = `false`;
```
flagがtrueだった場合にはHelloを出力し、falseだった場合falseを出力します。flag==trueはflag&&trueでもいいですが、人間的にわかりやすいのはこちらの書き方でしょう。この書き方の問題点は、似たような文が２回出てきている点です。できれば省略したい。

```js
let flag = true;
document.getElementById("app").innerHTML = flag &&`<h1>Hello</h1>`;
```
このプログラムは論理積演算子&&の性質を利用してHelloを出力するかどうかを短くまとめています。flagがtrueの場合Helloを出力、falseの場合はfalseを出力します。先程の文が１つにまとめられ文量的には見やすくなっています。

#積極的に使っていくべきか
分かっていて使っているなら個人で利用する分には問題ない。ただチームで使う上ではわからない人がいたら怖いが、この程度は常識なのかもしれない。論理演算のもとの意味から外れてはいるが、これを用いることでコードが減り、見やすくなるなら使ってもいいとは思う。ただすべてこれで書くのはどうかと思う。意味が分かっており、それを使うことで十分なメリットを得られるなら使ってもよい。むやみやたらに使うものではない。しかし、そもそも3項演算子使えばよくないか？

2021/07/12追記：

```js
let flag = true;
document.getElementById("app").innerHTML = flag? `<h1>true</h1>`: `<h1>false</h1>`;
```
3項演算子だとこんな風に書けます。

#結論
僕は3項演算子使います。

#参考文献
[1]:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND
[[1]]:論理積 (&&)
続PC-8001のディスプレイ

PC-8001のDIN 8ピンからVGAへの変換ケーブルを作ってみました。

![IMG_20210711_110208.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/63427767-8e4b-9e70-62e7-414985946a3b.jpeg)

|DIN||VGA|Signal|
|:--|:--|:--|:--|
|1||||
|2|-|10,6,7,8||
|3|||Clock(14.318 MHz)|
|4|-|13|HSYNC|
|5|-|14|VSYNC|
|6|150|1|R|
|7|150|2|G|
|8|150|3|B|

VGAの6,7,8はRGBのシールドになっていました。

150オームが無かったので、75x2で作りました。

SONY CPD-L150で表示

![IMG_20210709_124929.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5e76e3fb-260e-1f6b-d58e-011e7dc63c8c.jpeg)

15.625/15.75kHz対応なのですが。

たまにしたの三菱のテレビのような表示になる事もあります。

その後普通のVGAもピンクぽい表示になってしまい、ばらしてみたのですが、問題のありそうな部品はありませんでした。なぜかVGA信号はピンクぽくなるのですが、メニューはちゃんと白く表示されます。もしバックライトが切れたとかの致命的なダメージであれば、メニューも影響を受けるはずです。だめもとでコネクタ基板に一つだけのっていた電解コンデンサーのElite 25V 220uFを、手持ちのrubyconに代えたところなんと直りました。電解コンデンサーの劣化で電源が若干不安定になり、VGAをドライブしているチップだけに影響がでたというところでしょうか。特に見た目で液漏れとかはありませんでしたが、20年前の製品ですからね。

三菱の古い液晶テレビ

![IMG_20210709_132203.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d48fd197-dbcc-d535-030e-ac282df15b8d.jpeg)

CPD-L150と同じで、おそらくインターレスの15KはOKなんだけど、ノンインターレスには対応していないんだと思います。

15.75KHzで一秒に60フレームだと262.5本となるので、62.5本分のゴミデータが表示されているのだと思う。

PC-9801FA2の24.8Kは表示できるIO Data LCD-A173KBでもダメでした。

残念ながら対応しているディスプレーがありません。

上の三菱のTVではおそらくラインダブラーのような事をして、HSYNCを倍にすれば表示できるような気がします。PC-8001の場合COLOR SYNCからHSYNC作られていると思われCOLOR SYNCを数えてHSYNCを半分にすることができると考えられます。

~~水平の解像度は320でRGBで3Bitですが切が良い4Bitで計算すると160Byteのメモリが必要になります。1行をスキャンしてメモリに入れて同じ内容で2行で出力するような流れになるのだと思います。~~
水平の解像度は416のようです。
Proxy環境下のWSL2上でSeleniumを動かす

何か記事を作成してみようと思ったのと、色々つまづいたので備忘録も兼ねて書いておく。

# やりたいこと
社内のProxy環境で、Winows10のWSL2を使いUbuntu上でSeleniumを動かす。SeleniumはPythonで動かす想定。

## 0. 環境
OS: Windows10 Enterprise (Windows機) / Ubuntu-20.04 LTS (WSL)
言語: Python 3.8.10

## 1. WSL2を使えるようにする
WSLの設定方法は別の記事に: https://qiita.com/tennis_lover/items/66ebdaebee645b6b2c01

### Pythonのインストール
WSLのインストールが完了したら、PythonのインストールをUbuntu上で行う。以下の記事にまとめているのでどうぞ。

https://qiita.com/tennis_lover/items/db89163a061b59d862fa

他には[この記事](https://qiita.com/tfukumori/items/c2997988acacd0da17d0)が参考になる。

## 2. Seleniumのインストール
Ubuntu上で行う。
Seleniumはローカルマシン上で動かすか、Docker上で動かすかに大きく分かれるが、
最終的にCIでの自動テストで使いたいので、Docker上で動かす方法をとる。
私が慣れているのがPythonなので、以下はPythonでSeleniumを動作させるための方法。

以下コマンドでSeleniumをインストールする。
`pip install selenium`
環境設定が完了したら、PythonでSeleniumのコードを書いていくことになる。

### Dockerの設定
Windows上で行う(Ubuntu上にDockerを直接インストールしても良いと思うが未確認)。
Docker Desktop for Windowsを使う。Dockerのインストール方法はたくさん出てくるので割愛。
WindowsにDocker Desktopをインストール後したらProxy設定を行う。

## 3. Proxy設定
以下、Ubuntu上での作業。
コンテナ起動時にオプションで設定しても良いが面倒なので、設定ファイル内に記述する。
`/home/{USER}/.docker/config.json`に以下内容を適当なエディタで追記する。

``` config.json
"proxies": {
  "default": {
    "httpProxy": "http://{PROXY_HOST}",
    "httpsProxy": "https://{PROXY_HOST}",
    "noProxy": "{HOST_NAME}"
  }
}
```

## 4. 動作確認
以下、WSL上での作業。
https://github.com/SeleniumHQ/docker-selenium に書いてある通り以下コマンドでコンテナを起動する（ブラウザはChrome）。

```
docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:4.0.0-rc-1-prerelease-20210823
```

以下は今回作成したサンプルプログラム。Google検索の画面にアクセスして、「Selenium」と検索する。
[http://localhost:7900/](http://localhost:7900/)にアクセスするとDocker上で実行される様子を確認できる。パスワードは上記のGithub内に書いてある。
 
``` sample.py
from selenium import webdriver
from selenium.webdriver.common.by import By

# Capability の設定
capabilities = webdriver.DesiredCapabilities.CHROME.copy()

# Options の設定(ブラウザ設定)
options = webdriver.ChromeOptions()

# Selenium Server に接続する
driver = webdriver.Remote(command_executor='http://localhost:4444/wd/hub',
                          desired_capabilities=capabilities,
                          options=options)

# ウィンドウを最大化する
driver.maximize_window()

# Google 検索のページへアクセス
driver.get('https://www.google.co.jp')

# 検索テキストボックスの要素を検索する
element = driver.find_element(By.CLASS_NAME, 'gLFyf.gsfi')

# テキストボックスに「Selenium」と入力する
element.send_keys('Selenium')

# 「Google 検索」ボタンをクリックする
# 直接クリックを実行することもできる
driver.find_element(By.CLASS_NAME, 'gNO89b').click()

# ブラウザを閉じる
driver.close()
```

テキストボックスなどの要素のClassNameやIDなどはブラウザの開発者ツールで確認できる。

# ちなみに
Windows上の、`\\wsl$`がUbuntuのファイルシステムにマウントされているので、エクスプローラのアドレスバーに入力すればWindowsからでもアクセスできる。

以上です。
外れやすいキートップを外れにくくする応急処置

# キートップが外れやすくなる

LenovoのThnkPadE560、E580を使っているのですが、特定のキーボードのキートップが外れやすくなりました。
修理に出そうにも、サポートプランに入っていないと電話対応だけでも4,000円ぐらいかかり、どうしようかなと悩んでました。

たった一つのキートップが外れやすくなるだけで、数万円とか払うのもバカバカしいなと。

なんとか応急処置できないかと外れやすいキートップを観察していました。
私の場合、上か下のみが毎回外れる症状でした。


![PXL_20210709_060243629.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/d3877192-97aa-2c6f-40d9-0f4fd0274741.jpeg)


https://www.lenovo.com/us/en/laptops/thinkpad/e-series/e560/

https://www.lenovo.com/jp/ja/notebooks/thinkpad/e-series/ThinkPad-E580/p/22TP2TEE580


# 薄型の両面テープで外れやすい箇所を接着


症状はわかったので、その外れやすい場所を固定してやればいいのではと思い、両面テープか接着剤で接着してやろうと考えました。
接着剤だといろいろ問題がありそうなので、薄型の強力両面テープを補修材としました。


https://www.amazon.co.jp/%E3%83%8B%E3%83%88%E3%83%A0%E3%82%BA-%E9%80%8F%E6%98%8E%E4%B8%A1%E9%9D%A2%E3%83%86%E3%83%BC%E3%83%97/dp/B01M8JCMQO

下の写真は、下側が外れやすかったキートップで、下側に両面テープの片側を貼りつけました（ちょっと切り方が汚いですが）。

あまり幅が広いと下側の基盤にくっついてキーがあがって来ないので、パンタグラフ（キートップの基盤の間にあるバネのような部品）の接地面の幅ぐらいに切断するのがいいです。

![PXL_20210709_060511062.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/5225df28-26b8-682a-8c35-391f41105004.jpeg)


# 応急処置完了

あとはキートップをはめて何度か強く押せば接着します。
とりあえず今の所、これで外れなくなったし、通常通りキーボードが使えてます。

同じ症状の人がいれば参考にしてみてください。
数万ではなく数百円で補修ができました。
Ruby 標準入力【Paiza】

#【Ruby 標準入力】

PG試験に向けて、超基本のところをまずは解いてみました。
何か誤りやこんな表現が適当など、ご指摘いただけますと幸いです。

##標準入力、標準出力

```Ruby:Ruby
# gets：標準入力を受け取る
# chomp：末尾の改行文字を削除する。
# to_i：データを整数に変換
# times do：繰り返す
# split：データをスペース区切りにして分割
# each do |a|：配列のデータをループ、パイプのなかの変数で参照できる。
```

###1つのデータの入力

```Ruby:Ruby
s = gets.chomp
puts s
```
※Rubyは半角スペースが入っても同じで良い。

###3行のデータの入力

```Ruby:Ruby
s = gets.chomp
puts s
s = gets.chomp
puts s
s = gets.chomp
puts s
```

###N行のデータの入力（N：1行目の数）

```Ruby:Ruby
n = gets.chomp.to_i

n.times do
    s = gets.chomp
    puts s
end
```

###3行のデータが1行にスペース区切りで与えられ、分割表示
```Ruby:Ruby
s = gets.chomp
t = s.split
puts t[0]
puts t[1]
puts t[2]
```

###N行のデータが1行にスペース区切りで与えられ、分割表示
```Ruby:Ruby
n = gets.chomp.to_i
s = gets.chomp
t = s.split
t.each do |a|
    puts a
end
```

##参考

[ITエンジニア向け国内最大の転職・就職・学習プラットフォーム【paiza】](https://paiza.jp/)
【AWS】EC2に「Windowsはライセンス認証されていません」を解決しました

#はじめに
AWSのWindows AMIを違うVPC内に立てたら、急遽「Windowsはライセンス認証されていません」という表示が出てしまいました。
その解決策を備忘録として残したいと思います。

#事象
下記のように、EC2を別のVPC内に立てたら、「Windowsはライセンス認証されていません」が表示されました。
![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/f26274fa-2583-4323-e5e9-444d9edd27c9.png)

#解決策
「Windows」→「Windows Powershell」の「管理者として実行」を押下します。
![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/7bc8ab6a-638a-4a66-4aa9-670e6d187c76.png)

下記のコマンドを入力します。

```
PS C:\> Import-Module "C:\ProgramData\Amazon\EC2-Windows\Launch\Module\Ec2Launch.psd1"
PS C:\> Add-Routes
PS C:\> Set-Activationsettings
PS C:\> cscript "${env:SYSTEMROOT}\system32\slmgr.vbs" /ato
```

![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/074b7922-3ec0-da7c-502e-a489a8025084.png)

すると、「Windowsがライセンス認証されています」と変更され、無事に解決できました。

![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/5597670b-81bb-c531-a6d5-c90469dba0c3.png)

#バッチで対応
AutoScaling時に、Windowsライセンス認証失敗事象がもし発生してしまったら、非常に困るので、そのためにバッチを作成いたしました。

まずはps1を作成しました。

```Windows_lisence_Activation.ps1
Import-Module "C:\ProgramData\Amazon\EC2-Windows\Launch\Module\Ec2Launch.psd1"
Add-Routes
Set-Activationsettings
cscript "${env:SYSTEMROOT}\system32\slmgr.vbs" /ato 
echo "Success" | Out-File Windows_lisence.log
```
続いてbatを作成します。

```Windows_lisence_Activation.bat
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "C:\XXXXXXXX\Windows_lisence_Activation.ps1 -Verb runas"

```

#参考資料

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/common-messages.html#activate-windows

https://aws.amazon.com/jp/premiumsupport/knowledge-center/windows-activation-fails/
初心者がUdemyで学ぶAWS 

#概要#

####使用するUdemy講座####
今回は、**AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得**という講座で学んでいきたいと思います。
https://www.udemy.com/course/aws-and-infra/
初回登録の特典でかなり安く購入することができました。


########

#そもそもAWSとは#
Amazon.comにより提供されている**クラウドサービス**であり、正式名称を**Amazon Web Services**という。100以上のサービスが存在しており、クラウドサービスとしては最大規模を誇っている。ウェブサービスに限らない多種多様なインフラストラクチャーサービスを提供しているもの。

今回は**AWSのネットワークの用語**について記述していきたいと思います。

#AWSネットワーク用語#
####リージョン####
AWSの各サービスが提供されている地域のこと。
リージョンごとにネットワークを設定してサーバーを作っていくことになります。
リージョンによって使えるサービスも違うので事前にチェックすることが重要。

####アベイラビリティゾーン####
AWSは世界各国にデータセンターを持っており、複数のデータセンターを束ねたものがアベイラビリティゾーン。
どのリージョンにもアベイラビリティゾーンが**二つ以上**存在しており、それぞれ物理的に離れて存在しています。
複数ある理由は、例え災害が起きて一つのアベイラビリティゾーンが利用不可能になったとしてもそれ以外のアベイラビリティゾーンでシステムを利用できるようにするため。

####VPC####
VPC(Virtual Private Cloud)とは、AWS上に仮想ネットワークを作成できるサービス。
VPCを使うことで他とは分離されたネットワーク環境を自由に作ることができるもの。
AWSでは、**はじめにこのVPCを作成します**。

####サブネット####
VPCを細かく区切ったネットワーク。
例えば、ブログシステムを作る際に
　　　　 Webサーバー⇒インターネットから**閲覧可能**
データベースサーバー⇒インターンネットから**閲覧不可**
というようにしたい場合
VPCの中にサブネットを**二つ**作り、
一つをインターネットから閲覧できるように
もう一つを、インターネットから閲覧できないようにします。
このようにネットワークを区切りたい場合に利用するのがサブネットというものです。

#まとめ#
今回はAWSを使用するうえで出てくるネットワークの用語について解説していきました。
Udemyでの講座では、初心者にも分かりやすく図などを用いて説明されており深く理解できたと感じました。
EclipseでTomcat が起動できない【解決方法】

前提：サーバータブで新規からサバ―を追加している状態であること。

# 【問題内容】 
Eclipseのサーバータブ上でTomcat が起動できない事象

# 【解決方法】
サーバータブで対象サーバーを右クリック＞開く＞キャプチャのようにサーバーロケーション内の「Tomcatインストールを使用（Tomcatインストールの制御）」にチェックし、保存（Ctrl＋ｓ）すること。

![スクリーンショット 2024-01-02 171222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162001/486f4f57-802b-5819-6e43-18c6a5ec8c43.png)
Swift初学者のつくる電子レンジロジック

こんにちは！
Swiftの学習を始め早6ヶ月のennuです。

今回はおもしろそうなお題を見つけたので私も電子レンジ(温め機能なし)を作ってみることにしました！


https://qiita.com/shunta01/items/fd1c771c47b135b0010b


リファクタリングのため、コメントでアドバイスいただけると嬉しいです:grinning:



# 要件

>
・電子レンジのワット数は900,600,200とする
・今回は、安全のために11分以上は加熱できないものとする
・タイマーの実装
　　・分と秒の概念を実装
　　・残り時間の出力
　　・残り時間が0秒になったら、「温め終了です」と出力し、タイマーを停止
　　・温める時間が11分以上だと「温めを開始できません！」、
　　 「タイマーを10分59秒以内に設定してください」と出力
・タイマーが10分59秒以内にセットされたら、温め可能フラグを返し、「温め開始!!」を出力
・選択されたワット数を出力

要件は参照記事と同じです。
環境はplaygroundです。


#いざ実装！

```swift
import UIKit

class MicroWave {

    enum WattTipe: String {
        case watt900 = "900w"
        case watt600 = "600w"
        case watt200 = "200w"
    }
    
    let minute: Int
    let second: Int
    let wattTipe: WattTipe
    
    init(minute: Int, second: Int, wattTipe: WattTipe) {
        self.minute = minute
        self.second = second
        self.wattTipe = wattTipe
    }
    
    func printDescription() {
        print("ワット数: \(wattTipe.rawValue), 温め時間: \(minute)分\(second)秒")
    }
    
    func setTimer() {
        printDescription()
        
        //温め時間の指定
        guard minute <= 10 else {
            print("温めを開始できません！タイマーを10分59秒以内に設定してください")
            return
        }
        
        guard second <= 59 else {
            print("秒数は0〜59の範囲で指定してください")
            return
        }
        
        print("温め開始!!")
        
        //温め時間を秒に変換
        let timer = minute * 60 + second
            
            //Timerのセット
            for i in 1...timer {
                sleep(1)//1秒止める
                
                //残り時間の出力
                if i < timer {
                    let remainingMinute = (timer - i) / 60
                    let remainingSecond = (timer - i) - remainingMinute * 60
                    print("残り時間: \(remainingMinute)分\(remainingSecond)秒")
                } else {
                    print("温め終了です")
                }
            }
    }
}

```
##使ってみる
```swift
let timer1 = MicroWave(minute: 30, second: 85, wattTipe: .watt900)
timer1.setTimer()
//ワット数: 900w, 温め時間: 30分85秒
//温めを開始できません！タイマーを10分59秒以内に設定してください

let timer2 = MicroWave(minute: 10, second: 85, wattTipe: .watt600)
timer2.setTimer()
//ワット数: 600w, 温め時間: 10分85秒
//秒数は0〜59の範囲で指定してください

let timer3 = MicroWave(minute: 0, second: 3, wattTipe: .watt200)
timer3.setTimer()
//ワット数: 200w, 温め時間: 0分3秒
//温め開始!!
//残り時間: 0分2秒
//残り時間: 0分1秒
//温め終了です
```
- 出力は要件通りに動いています。（温め時間の表示は追加しました）
- `timer3`では１秒おきに残り時間を出力することができました！

#所感
- フラグの使いどころがわからず、実装しない形になってしまったので今後使い方を勉強していきたい。
- classやenumの使い方をよく理解していなかったので再学習するきっかけになってよかった。
- タイマーが案外簡単に作れることがわかった。
- とても勉強になったので他のお題にも挑戦してみたい。

#まとめ
書籍などで一通りSwiftの勉強したけど使い方がいまいちわからないな〜と感じる初学者の方には良いアウトプットになると思います。ぜひ挑戦してみてください！
【RPA】RPA系ブログのネタと書き方

# はじめに

この投稿は、RPA系ブログのネタと書き方について の記事です。

※ 前回の「ブログ投稿傾向」の記事の続きです。

https://qiita.com/miya_gis/items/900030508fd07225fd8a


今回の投稿は、RPAツールUiPathのコミュニティ「UiPath Friends」が企画する「**UiPathブログ発信チャレンジ2021サマー**」の 9日目の投稿になります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427?s=20


# データ傾向）投稿内容（コンテンツ）


記事の内容は、何のために書くかによって分類されそうな気がします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/58f176de-6720-d74c-5813-42142e3f304b.png)


# 何のために投稿するか

自分のため、他人のため、コミュニティや会社のため、などありますが、
まずは「自分のため」で良いと思います。自分用のメモからはじめて、それが誰かの役に立ったらラッキー！ぐらいの気持ちで十分です。

実際に書くと、後で「あの書き方なんだっけ？」と見返せることもあり、将来の自分を助けることにもなります。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/c4fbe849-b21c-cc98-5cda-54ac14463825.png)

# 記事のネタ、データソース

記事の内容は何でもいいと思います。感想や、やってみた系の話でも、人の話を聞くと意外と面白かったりします。RPAは関わる人の裾野が広いので、きっと「その情報」が役立つ人が、どこかにいるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/92057598-23e5-bf39-e6d5-ad6beb3fd05a.png)

# 書き方

ネタがないと書きにくいですが、日々ネタを集めておくと良いと思います。ネタ集めが意外と学習に繋がります。

人の書いた記事のマネでも良いと思います。100％オリジナルなコンテンツなんて少ないし、すでに同じことを書いている人がいるのは普通です。

そもそもRPAは市民開発で、技術的な競争の要素は少ないと思います。開発に携わる人も多いので「同じことをやってみた」という記事でも、共感や親近感から喜ぶ人は多いと思います。

ただ「丸パクリ」はバレるので、どこかに自分なりの独自性・オリジナリティー・アクセントを付ける努力は必要です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/8912c415-f774-3c2e-02cd-d55b25327f8a.png)


# おすすめの書き方

私が「この方法は、意外と書けるな」と思ったものを紹介します。

| No | 分類 | 内容 | 簡単レベル |
|:-:|:-|:-|:-:|
| 1| 各種情報のリンク集 | よく使う or 良質な報源のリンクを列挙 | ★★★★★（5） |
| 2| 英語の記事を訳す | 英語分からなくてもGoogle翻訳・ディープエル翻訳でOK。感想を少しと足せばオリジナル記事に | ★★★★☆（4） |
| 3| 自分はこうしてる紹介 | 簡単なTipとして、自分のやり方の紹介。短くてOK| ★★★★☆（4） |
| 4| 関連付随情報を纏めて記事化 | 製品歴史、デザインや概念紹介など | ★★★☆☆（3） |
| 5| Forumの質問回答を記事化 | 誰かの質問を発展させて、回答を整理する | ★★★☆☆（3） |

英語翻訳は、自分の学習にもなります。翻訳記事でも感想などを少しでも足せば、オリジナリティがでます。多言語圏の情報は意外と新鮮ですし。

例えば「チリのRPAスタートアップ企業の紹介」なんて面白そうですよね。

https://www.entrepreneur.com/article/373290


## おまけ）Qiitaの記事で「ブロック囲い」表現する方法

記事が長くて単調になる場合、ブロックで囲むと分かりやすくなります。

Qiita公式の書き方説明は以下にあります。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

ちなみに、記事のURLに「.md」を付けると「どう書いてるか？」がテキスト形式で見えます。

1）コードブロック（黒）

```
コードブロックです。「黒板」みたいで、見やすいです
コードブロックです（2行目）
```

2）引用ブロック

> 引用ブロックです。文字がグレーなので、あまり強調されません
> 引用ブロックです（2行目）


3）インラインブロック

`インラインブロックです` 1行しか書けません。**太字**よりは見やすいです。


4）ノートブロック

:::note info
　noteブロックの「info」です。
　「意見のまとめ」みたいに書けます
:::

:::note warn
　noteブロックの「warn」です
　「これは気をつけよう」みたいに書けます
:::

:::note alert
　noteブロックの「alert」です
　「これはダメだよ」みたいに書けます
:::

## おまけ）Noteの記事で「ブロック囲い」表現する方法

記事が長くて単調になる場合、ブロックで囲むと分かりやすくなります。

Note公式の書き方説明は以下にあります。

https://help.note.com/hc/ja/articles/360012426133-%E6%8A%95%E7%A8%BF%E7%94%BB%E9%9D%A2%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%93%E3%81%A8


以下のいずれかの方法で、ブロック囲みが出来ます。

1）コードブロック（黒）
2）引用ブロック（灰色）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/b4242480-2ae7-9a09-b0bb-db6eeaca07b6.png)


# 終わりに

いかがでしたでしょうか。ブログ投稿の際に、なにかの役に立てば幸いです。

この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。
Gmailで検索した内容をスプレッドシートにまとめる！(GAS)

## 本日の内容
- Gmail検索をして件名(シート名に設定)ごとにスプレッドシートにまとめる処理をGASで作成。
- 前回の記事でGoogleドライブから全てのtxtを検索し、スプレッドシートに出力するスクリプトを作成したので、内容は類似。

## 作成したソース
```javascript
// Gmail内にある検索条件に一致するメールの本文をスプレッドシートのシートごとに書き込むメソッド
function searchGmailMakeSpreadSheet() {

  // 取得したメールの件数のインデックス
  var num = 0;

  // シート名
  var sheetName = "";

  // sampleフォルダー配下にスプレッドシート"gmail"を作成
  var newSheet = createSpreadsheet("1_fD_XDbrDIFDrdgn_dRbFRChEdQ1tFqF", "gmail");

  // 作成したスプレッドシートのIDを取得
  var sheetId = newSheet.getId();

  // ID指定をしてスプレッドシートを開く
  var newSpreadSheet = SpreadsheetApp.openById(sheetId);

  // 検索条件に該当するスレッド一覧を取得(キーワード：出前館、件数：3件に設定)
  var threads = GmailApp.search("出前館", 0, 3);

  // 条件に該当するメッセージスレッドを取得
  var messagesForThreads = GmailApp.getMessagesForThreads(threads);

  // スレッドを一つずつ取り出す
  threads.forEach(function(thread) {
    
    // メールの件名を取得
    var subject = messagesForThreads[num][0].getSubject();

    // 取得したメールの1件目から1つずつ増やしていく
    num++;

    // 件名をシート名に設定
    newSpreadSheet.insertSheet(subject);
    
    // デフォルトで作成されている「シート1」を取得
    var delSheet = newSpreadSheet.getSheetByName("シート1");
    
    // デフォルトシートを削除
    if (delSheet != null) {
      newSpreadSheet.deleteSheet(delSheet);
      }
      
    // スレッド内のメール一覧を取得
    var messages = thread.getMessages();
    
    // メールを一つずつ取り出す
    messages.forEach(function(message) {

      // メール本文を取得
      var plainBody = message.getPlainBody();

      // メール本文が取得できているかログに出力して確認
      Logger.log(plainBody);

      // 改行単位でカンマ区切りにする(配列のイメージ)
      var txtLines = plainBody.split(/[\s]+/);

      // 配列の全ての要素に対してスプレッドシートに書き込み処理を行う
      Array.from(txtLines, x => outputLog(x, newSpreadSheet));
    });
  });
}

// スプレッドシートに出力するメソッド
function outputLog(txt, newSpreadSheet) {

  // txtが存在するとき書き込む
  if (txt != null) {
    newSpreadSheet.appendRow([txt]);
  }
}

// フォルダに新規にスプレッドシートを作成(第1引数：フォルダID, 第2引数：ファイル名)するメソッド
function createSpreadsheet(folderID, fileName) {

  // フォルダIDから該当フォルダを取得
  var folder = DriveApp.getFolderById(folderID);

  // スプレッドシートを指定されたファイル名で作成
  var newSpreadSheet = SpreadsheetApp.create(fileName);

  // IDを指定してファイルを取得
  var file = DriveApp.getFileById(newSpreadSheet.getId());

  // オリジナルのファイルで書き込みを行うと、想定通りにいかないのでコピーを作成
  var copiedFile = file.makeCopy(fileName, folder);

  // コピー元のファイルを削除
  file.setTrashed(true);

  // コピーしたファイルを返す
  return copiedFile;
}
```

- Googleドライブ内に「samplefolderフォルダ」を作成。
- samplefolder配下に「gmail」という名前でスプレッドシートを新規作成。
- Gmailから検索条件に合致する内容のメールの一覧を抜き出し、スプレッドシートに内容を入力完了させる。
- シート名は件名にしている。
- 確認用に本文内容はログに出力する。

## 実行イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1715093/d437ca15-f5b4-bef2-4544-32c2f857c592.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1715093/312279be-a246-da02-08b9-e171086ed9fd.png)

- 出力にかかった時間は検索ワード「出前館」、出力件数3で35秒程度。

## 出力したスプレッドシート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1715093/1a175a82-fffe-47db-2bde-9d522837f25a.png)

## 課題点
- GASではスクリプトの実行時間が6分という縛りがあるらしいので、全件検索や検索件数を一定数増やしたい場合には対応できないと考えられる。
2.4(標準) 期待値の定義

## 方針

いずれもtについての一変数関数なので，前半は平方完成，後半は微分して0と置くことで最小値を計算する．定積分の微分について，以下であることを用いる．

```math
\frac{d}{dx}\int_a^xf(t)dt=f(x)
```

また，「分布f_Xに従う確率変数Xについての期待値」を，次のように書くことにする．

```math
\mathbb{E}_{X\sim f_X}
```

## 答案

```math
\begin{align}
\mathbb{E}_{X\sim f_X}[(X-t)^2]&= \mathbb{E}_{X\sim f_X}[X^2]-2t\mathbb{E}_{X\sim f_X}[X]+t^2\\
&= (t-\mathbb{E}_{X\sim f_X}[X])^2+\mathbb{E}_{X\sim f_X}[X^2]-(\mathbb{E}_{X\sim f_X}[X])^2
\end{align}
```

より，

```math
\arg\min_t\mathbb{E}_{X\sim f_X}[(X-t)^2]=\mathbb{E}_{X\sim f_X}[X]
```

となる．次に，

```math
\begin{align}
\mathbb{E}_{X\sim f_X}[|X-t|]&= \int_{–\infty}^\infty|x-t|f_X(x)dx\\
&= \int_t^\infty(x-t)f_X(x)dx-\int_{-\infty}^t(x-t)f_X(x)dx\\
&= \int_t^\infty xf_X(x)dx-t\int_t^\infty f_X(x)dx-\int_{-\infty}^txf_X(x)dx+t\int_{-\infty}^tf_X(x)dx\\
&= (\int_t^\infty xf_X(x)dx-\int_{-\infty}^txf_X(x)dx)-t(\int_t^\infty f_X(x)dx-\int_{-\infty}^tf_X(x)dx)\\
&= (\mathbb{E}_{X\sim f_X}[X]-2\int_{-\infty}^txf_X(x)dx)-t(1-2\int_{-\infty}^tf_X(x)dx)
\end{align}
```

と変形できる．これをtについて微分して0と置く．

```math
\begin{align}
\frac{\partial\mathbb{E}_{X\sim f_X}[|X-t|]}{\partial t}&= -2tf_X(t)-(1-2\int_{-\infty}^tf_X(x)dx)+2tf_X(t)=0\\
\Rightarrow \int_{-\infty}^t f_X(x)dx&= \frac{1}{2}
\end{align}
```

ゆえ，E[|X-t|]を最小化するtは，P[X<1/2]=tとなるような点，すなわちXの分布の中央値である．

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
個人的にVSCodeで最近アツイコマンド1選！

# はじめに
こんにちは。毎日Qiitaの記事投稿していると、たまには遊びを挟まないとつらい時期が来ます。そんな今日はその日です:pray:
でもシンプルだけど激熱な情報をお届けします、筆者です:v:

さて、今回は個人的に**VSCode**で最近アツイ**コマンド**を1個紹介しようと思います！

# 個人的にVSCodeで最近アツイコマンド1選！
それは、`最大化されるパネルの切り替え` です！

```
workbench.action.toggleMaximizedPanel
```

# 事の発端
VSCodeでターミナル使いますでしょうか。
以下のように、下に表示される**ターミナル**縦幅が短くて、コマンドのhelp出したときとか、ほとんど隠れて見えないとか、ありませんか？
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/4c51191b-b8d8-6ea6-2567-4b0a2e278e9e.png)

# そういうときはこのボタン
右側に最大化するボタンがついています。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/cff7ef7a-a763-cc59-3cd9-a98b0bfa3e0e.png)

# 最大化するボタン押さなくても、コマンドであるんです！
それがこれ↓

`最大化されるパネルの切り替え` です！

```
workbench.action.toggleMaximizedPanel
```

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/ae547786-dd09-8c51-8961-494283777e68.png)

# 余談：個人的にVSCodeでターミナルを利用するメリット
個人的にVSCodeでターミナルを利用するメリットがあります。

それは、`スクリーンキャストモード(workbench.action.toggleScreencastMode)`を使用することで、**ターミナルでどのキーを打ったかを伝えやすい点**です。

これは、リモートが多い中、**画面共有**で新卒さんや初学者に対してメンターをする際に、とってもありがたいのです:smile:

以下で言うと、 `Ctrl + l` でターミナル上がきれいになるとか、打ち込んでないキーボード操作について、伝えやすくなるので、VSCodeのターミナルを最近よく使っている理由です。

![Local-screen-videos.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/603104fb-51cd-eac2-aebe-ee8725dbda7a.gif)

# おわりに
この機にぜひ使ってくださいませ:bow:
多用する場合はキーバインドしてもいいと思います:+1:

それでは！
mlr3で「Rによる機械学習」：第3章「遅延学習 -- 最近傍法を使った分類」

# はじめに

Lantz (2017)[^1] ではRによる機械学習のパッケージとして[RWeka](http://www.cs.waikato.ac.nz/ml/weka/)というパッケージを使っていますが，最近`mlr3`パッケージの勉強を始めたので，こちらでコードを書いてみようと思いました．

[^1]: Lantz, Brett (2017) 『Rによる機械学習』，翔泳社，長尾高弘訳

# 準備

```r
install.packages("mlr3verse", "tidyverse", "gmodels")
library(mlr3verse)
library(tidyverse)
library(gmodels)
```

# 3-2 実例 -- k近傍法を使った乳がん検診

データの準備をします．
StrawBerryMoonさんの指摘で`outer`の使い方を修正しました．

```r
url <- "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data"
col_types <- paste("if", paste(rep("d", 30), collapse = ""), sep = "")
wbcd <- read_csv(url, 
                 col_names = FALSE,
                 col_types = col_types)
specs <- c("radius", "texture",
           "perimeter", "area",
           "smoothness", "compactness",
           "concavity", "cancave_points",
           "symmetry", "fractal_dimension")
postfix <- c("mean", "SE", "worst")
colnames(wbcd) <-  c("id", "diagnosis", c(outer(specs, postfix, paste, sep="_")))
colnames(wbcd)        
```

`id`を削除します．

```r
wbcd <- wbcd[-1]
```

`diagnosis`を確認し，ラベルを書き換えます．

```r
table(wbcd$diagnosis)
wbcd <- wbcd %>%
  mutate(
    diagnosis = factor(wbcd$diagnosis,
                       levels = c("B", "M"),
                       labels = c("Benign", "Malignant")
                       )
    )
round(prop.table(table(wbcd$diagnosis)) * 100, digits = 1)
```

特徴量の一部を確認します．

```r
summary(wbcd[c("radius_mean", "area_mean", "smoothness_mean")])
```

数値データの正規化をします．

```r
normalize <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}

wbcd_n <- wbcd %>% 
  select(-diagnosis) %>%
  summarise(across(everything(), normalize))
summary(wbcd_n$area_mean)
```

k近傍法で分類します．

```r
wbcd_backend_n <- bind_cols(wbcd_n, diagnosis = wbcd$diagnosis)
task <- TaskClassif$new("wbcd_task_n",
                        backend = wbcd_backend_n,
                        target = "diagnosis")
learner <- lrn("classif.kknn")
learner$param_set$values <- list(k = 21)
learner$train(task, row_ids = 1:469)
wbcd_pred_n <- learner$predict(task, row_ids = 470:569)
```

予測結果のクロス集計表を作成します．本の結果と異なりますが気にしないことにします．

```r
CrossTable(x = wbcd_backend_n$diagnosis[470:569],
           y = wbcd_pred_n$response, 
           prop.chisq = FALSE)
```

次にzスコアで標準化します．

```r
wbcd_z <- as_tibble(scale(wbcd[-1]))
summary(wbcd_z$area_mean)
```

先ほどと同様にk近傍法で分類します．

```r
wbcd_backend_z <- bind_cols(wbcd_z, diagnosis = wbcd$diagnosis)
task <- TaskClassif$new("wbcd_task_z",
                        backend = wbcd_backend_z,
                        target = "diagnosis")
learner$train(task, row_ids = 1:469)
wbcd_pred_z <- learner$predict(task, row_ids = 470:569)
```

予測結果のクロス集計表を作成します．こちらも本の結果とは異なり，変化はありませんでした．

```r
CrossTable(x = wbcd_backend_z$diagnosis[470:569],
           y = wbcd_pred_z$response,
           prop.chisq = FALSE)
```
Linux基本学習まとめ２

#　プロセス・ジョブ管理
プロセスとは、実行中のファイルのことで、Linuxでは、コマンドを実行するたびにプロセスが増えていきます。
ジョブとは、プロセスの集まりのこと。シェルの１行ごとがジョブです。

```
$ ps[オプション]　　:プロセスを表示するためのコマンド
auxオプション：全ユーザーのプロセスを詳細に表示する

$ jobs [オプション]　：ジョブを表示するためのコマンド
　　　　
```

```:ジョブとプロセス
$ ps aux | grep yes | less
#これはパイプを使って３つのプロセスを実行しており、ジョブはこのコマンド全体で１つのジョブと扱う

```

プロセスとジョブの違い

- プロセスはOS全体で統一して管理され、システムが自動で実行しているプログラムや他のユーザーが実行しているコマンドも一括して管理している
- ジョブは、シェルごとに管理されている


# バックグラウンドとフォアグラウンド

ショルの画面外でコマンドを実行することをバックグラウンドと言い、画面内で実行することをフォアグラウンドと言います。
ファオグランドから停止させる場合は、`Ctrl+z`、停止を解除する場合は`fgコマンド`を入力する。
停止状態から`bgコマンド`を実行することで、バックグラウンドからコマンドを実行できる。

```
$ sleep 10 & 
# バックグラウンドでコマンド実行する際にコマンドの後に「スペース+&」でいきなりバックグラウンドでコマンド実行ができる。
 
```
【Vue.js】「 v-bind:」をつける時、つけない時


# 環境

- vue.js: 2.x


# メモ

## 「 v-bind:」をつける時

### その1
` v-bind:`をつけると、そのattributeの値には変数（というのかな？）が書ける

```vue
<div v-bind:id="divId"></div>
```

この場合、`divId`というdataやcomputedの変数に入っている値がid属性に設定される

`divId = 1`の場合、↓のHTMLになる

```html
<div id="1"></div>
```


### その2

` v-bind:`をつけると、javascriptの式が書ける
javascriptとして解釈される

```vue
<div v-bind:id="isFirst?'first':'second'"></div>
```

三項演算子なんかも書ける

`isFirst = true` の場合、↓のHTMLになる

```html
<div id="first"></div>
```


## 「 v-bind:」をつけない時

文字列として解釈される

### その1

```vue
<div id="divId"></div>
```

この場合、`divId`というdataやcomputedの変数があったとしても、id属性には「divId」という文字列が設定される

↓のHTMLになる

```html
<div id="divId"></div>
```


### その2

```vue
<div id="isFirst?'first':'second'"></div>
```

三項演算子を書いたとしても、id属性には「isFirst?'first':'second'」という文字列が設定される


↓のHTMLになる

```html
<div id="isFirst?'first':'second'"></div>
```


### ありがちな間違い

- 親コンポーネント

```vue
<child is-first-child="true"></child>
```

- childコンポーネント

```vue
props: {
    // 型チェックとバリデーション
    is-first-child: {
      type: Boolean,
      required: true,
    }
}
```

この場合、親コンポーネントで「v-bind:」をつけていないので、childコンポーネントの`is-first-child`propsには**「true」という文字列**が渡される。
そうすると、childコンポーネントのバリデーションに引っかかってしまう。


- 親コンポーネントで「v-bind:」をつける

```vue
<child v-bind:is-first-child="true"></child>
```

「v-bind:」をつければ、Booleanとして渡せるのでバリデーションに引っかからない。


## 備考

「:」は、「v-bind:」の省略記法

```vue
<div v-bind:id="divId"></div>

↓ 省略記法（同じこと）

<div :id="divId"></div>
```
PHP 型演算子 instanceofを使って変数を評価する

# 目的

- PHPの方演算子であるinstanceofを使って評価対象の変数が指定のクラスのオブジェクト変数かどうかをチェックする。

# 方法

- 下記のように記載することで指定クラスのオブジェクト変数かどうかをチェックする。

    ```php
    評価対象の変数 instanceof クラス名；
    ```

- 評価の結果は真偽値（bool）で返ってくる。（評価対象の変数が指定したクラスのオブジェクト変数だった場合trueが返される。）
- 参考文献先に下記のようなソースが記載されていた。

    ```php
    <?php
    class MyClass
    {
    }
    
    class NotMyClass
    {
    }
    
    $a = new MyClass;
    
    var_dump($a instanceof MyClass); //trueを返す
    var_dump($a instanceof NotMyClass); //falseを返す
    ```

- `$a`はMyClassクラスのがインスタンス化されたオブジェクト変数であり、無関係なNotMyClassクラスのオブジェクト変数ではない。
- よって`$a instanceof MyClass`はtrueとなる。



# 参考文献

- [https://www.php.net/manual/ja/language.operators.type.php](https://www.php.net/manual/ja/language.operators.type.php)
codeコマンドインストールに失敗する時は先にコマンドアンインストールを試す

## 筆者の環境
・M1 MacBook Air (2020)
・Mac OS Big Sur 11.4

## 発生した問題
Visual Studio Codeで「シェルコマンド：PATH内に'code'コマンドをインストール」を選択しても
**EACCES: permission denied, unlink '/usr/local/bin/code'**
というエラーが発生しcodeコマンドが使用できない。

#解決方法
①VSCodeを再インストール

②VSCodeがアプリケーションフォルダにあるか確認

③ **「シェルコマンド：PATH内に'code'コマンドをアンインストール」** を実行
実行すると
「管理者特権でシェル コマンドをインストールできるように、Code が 'osascript' のプロンプトを出します。」
といったポップアップが出るので「OK」を押した後認証し、

④再度「シェルコマンド：PATH内に'code'コマンドをインストール」を実行
するとcodeコマンドが正常にインストールできました。