OmniAICreator/Qiita-1.07M huggingface dataset:
【APIGateway・Lambda】AxiosでAPIを叩いた時にCORS設定でハマった

ReactからAxiosでLambdaで作ったAPIへリクエストした時に、CORSの設定でハマったのでメモしておきます。

## 症状
`curl`ではレスポンスがAPIから帰ってくるが、`Axios`でReact側からリクエストをすると、下記のエラーメッセージが返ってくる。

`Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.`


## 原因
API GatewayでCORSが有効化されていない。
Lambda関数が必要なヘッダー情報を返していない。

## CORS（Cross-origin resource sharing) とは？

- ブラウザのセキュリティ機能。
- ブラウザからのHTTPリクエストを制限する。

ざっくりいうとこのセキュリティ機能のせいで、ReactからLambdaのAPIを叩けない。
具体的に言うと、プレフライトリクエストがアクセスコントロールチェックをパスしていない。

**プレフライトリクエストについて**
簡単言うと、OPTIONSメソッドでAPIへの疎通確認するリクエスト。
詳しくは、https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#preflighted_requests

## 解決法

### 1. APIGatewayでCORSを有効化
#### ⑴ AWSにログイン。APIGatewayのコンソール画面からAPIを選ぶ。
#### ⑵ 「アクション」 > 「CORSの有効化」を選択。
![スクリーンショット 2021-01-23 13.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142797/1d0b1f5f-1212-48bc-8861-58c5347b8860.png)

#### ⑶ ヘッダーの設定
- メソッド：OPTIONSにチェックが入ってることを確認。（preflightアクセスで使う。OPTIONSメソッドでAPIへの疎通確認。）
- `Access-Control-Allow-Headers`が、デフォルトは`'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'`だけど、オープンな場合認証情報は必要ないので`'Content-Type,X-Amz-Date'`に設定。

![スクリーンショット 2021-01-23 13.29.33 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142797/59a04c8b-8d1f-cb61-6f4e-b34eb0f39f7c.png)

設定が終わったら「CORS を有効にして既存の CORS ヘッダーを置換」ボタンをクリック。

#### ⑷ APIのデプロイをクリック
「APIのデプロイ」をクリック。デプロイしないと設定が反映されない。

![スクリーンショット 2021-01-23 13.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142797/e5a057de-e767-f5e7-55ce-9328124ae6c5.png)


###2. Lambdaで必要なヘッダー情報を返す。

下ようにヘッダー情報を返すように関数を修正。**デプロイする。**

```
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',　// アクセス元を限定するときは 'https://www.example.com'と指定。
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        },
        'body': json.dumps('Hello from Lambda!')
    }
```

### 3. Reactからリクエストを投げる
```
import axios from 'axios';

axios({
  method: 'post',
  url:'https://xxx.execute-api.ap-northeast-1.amazonaws.com/default/your-api',
  data: {
    line_count: lineCount,
    text: finalText,
  },
})
.then(results => {
  console.log(results);
)
.catch(results => {
  console.log(results);
});
```

### 最後に
これでレスポンスが返ってくるようになりました。
もし、これでもまだ返ってこない場合は、LambdaのCloudWatchのログを見てみるか、[Testing CORS - Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-test-cors.html) を参考にCORSテストをしてみてください。


### 参考
APIGatewayでCORSを有効化
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html
LambdaでCORSを有効化
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
GinでBodyを取得する際の最大サイズについて

#概要
ginで不確定なjosnをinterfaceに変換する際、一定サイズを超えると変換できない状態になった。


###コード
```
func SAmple(c *gin.Context) {
	～～～
	//bodyを取得
	buf := make([]byte, 1028)
	n, _ := c.Request.Body.Read(buf)
	body := string(buf[0:n])
	//bodyをmapに変換
	var json_parse map[string]interface{}
	err := json.Unmarshal([]byte(b), &json_parse)
	～～～
}
```

c.Request.Body.Readでバイトスライスにボディを格納してstring形に変換していますが、
jsonのサイズが一定値を超えるとパースできなくなりました。

私の環境ではnが2575で上限になりそれ以降のリクエストボディがbodyに格納されずjson.Unmarssamlでエラーになっていました。



##修正前に
Webサーバがbodyを制限なく受け入れるとbodyサイズだけサーバのメモリが消費されるため、
大きなbodyを送信しサーバをダウンさせるセキュリティホールになります。
そのため、API側で受け取れるbodyに上限を設けることは、Webに公開するAPIの場合必須になります。

その点は注意したうえで実装してください。

##修正後
```
func SAmple(c *gin.Context) {
	～～～
	//bodyを取得
	var bodyBytes []byte
	if c.Request.Body != nil {
	  bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
	}
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
	bodyString := string(bodyBytes)
	//変換
	var json_parse map[string]interface{}
	err := json.Unmarshal([]byte(b), &json_parse)
	～～～
}
```

ioutil.ReadAllですべてのbodyを読み込めるので問題なくjsonをinterfaceへ変換できます。

#まとめ
c.Request.Body.Read(buf)にはサイズに上限がある。
全部読み込みたい場合は、ioutil.ReadAll(c.Request.Body)で読み込みましょう

ありがとうございました。
sameersbn/redmineでpluginがうまくインストールできない時のtips

dockerでサクッとredmineを用意したい時、公式のイメージ以外で有名な``sameersbn/redmine`` というイメージがあります。
このイメージ、plugins配下にpluginのディレクトリを作成して起動すると、Installも済ましてよきにはからってくれるのですが、一部パッケージがうまくいきません。
sammersbn/redmineのレポジトリに解決策があったので、記録のため、こちらに記載します。


## 参照元
以下のIssueを参考にしました。
https://github.com/sameersbn/docker-redmine/issues/267

## どうするか
plugins\post-install.sh を用意して起動しましょう。

```post-install.sh
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
```

こちらを記載すると、コンテナの実行時に記載しているコマンドが実行され、うまいことやってくれます。
Issueではeasy guntのインストールでやり取りされていましたが、今回の対応で、国内で有名な``view customize plugin`` や、かんばんを使えるようにする ``Agile`` なんかが簡単に使えるようになります。
IPアドレスの範囲からCIDRを計算する

## 動機
プライベートアドレス(RFC1918)の範囲ではないCIDRを知りたかった。
AWS のセキュリティグループで指定できるのがCIDRなので計算しなくてはならなかった。

## 要件
IPv4 のアドレス範囲（0.0.0.0 - 255.255.255.255）のうち、
プライベートアドレス（クラスA：10.0.0.0/8、クラスB：172.16.0.0/12、クラスC：192.168.0.0/16）を除いたもの。
つまり、
- 0.0.0.0 - 9.255.255.255
- 11.0.0.0 - 172.15.255.255
- 172.32.0.0 - 192.167.255.255
- 192.169.0.0 - 255.255.255.255（クラスE[240.0.0.0 - 255.255.255.255]も含めてます）

## やり方
`ipcalc` コマンドを利用する。

```
ipcalc -r ${FROM_IP} ${TO_IP}
# または
ipcalc ${FROM_IP} - ${TO_IP}
```

## 結果
```
$ ipcalc -r 0.0.0.0 9.255.255.255
deaggregate 0.0.0.0 - 9.255.255.255
0.0.0.0/5
8.0.0.0/7

$ ipcalc -r 11.0.0.0 172.15.255.255
deaggregate 11.0.0.0 - 172.15.255.255
11.0.0.0/8
12.0.0.0/6
16.0.0.0/4
32.0.0.0/3
64.0.0.0/2
128.0.0.0/3
160.0.0.0/5
168.0.0.0/6
172.0.0.0/12

$ ipcalc -r 172.32.0.0 192.167.255.255
deaggregate 172.32.0.0 - 192.167.255.255
172.32.0.0/11
172.64.0.0/10
172.128.0.0/9
173.0.0.0/8
174.0.0.0/7
176.0.0.0/4
192.0.0.0/9
192.128.0.0/11
192.160.0.0/13

$ ipcalc -r 192.169.0.0 255.255.255.255
deaggregate 192.169.0.0 - 255.255.255.255
192.169.0.0/16
192.170.0.0/15
192.172.0.0/14
192.176.0.0/12
192.192.0.0/10
193.0.0.0/8
194.0.0.0/7
196.0.0.0/6
200.0.0.0/5
208.0.0.0/4
224.0.0.0/3
```

## CIDR -> Ip range したい場合
```
ipcalc ${CIDR}
```
で出来ます。

```
$ ipcalc 192.168.0.0/24
Address:   192.168.0.0          11000000.10101000.00000000. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.0.0/24       11000000.10101000.00000000. 00000000
HostMin:   192.168.0.1          11000000.10101000.00000000. 00000001
HostMax:   192.168.0.254        11000000.10101000.00000000. 11111110
Broadcast: 192.168.0.255        11000000.10101000.00000000. 11111111
Hosts/Net: 254                   Class C, Private Internet
```

## 感想
ipcalc コマンドは今回のように*IP range -> CIDR* だけではなく、*CIDR -> IP range* もできるので便利に使えそうです。

調べた後にこれと同じことができるページ[^1]があることを知りました...

[^1]: IPADDRESSGUIDE: https://www.ipaddressguide.com/cidr
firebaseのCloud Firestoreの指定のドキュメント内の既に登録済みのフィールドを、上書きせずに新たに値を追加する場合(※ionic-vueで開発中)

例えば
既に登録済みの、ドキュメントのidが
`addedPetId`で、既に登録済みのフィールド

```js

petProfile: { 
  petName: "ペットの名前"
}
```
に

```js

petProfile: { 
  petName: "ペットの名前",
  petAvatar: photoUrl 
}
```

このような形で
`petAvatar: photoUrl`を新たに追加したい場合

.setを使って、下記のようにすれば追加できる。

```js

async addPetProfileAvatar(addedPetId, photoUrl) {
    const user = this.getUser();
    return await this.db
      .collection(`users/${user.uid}/pets`)
      .doc(`${addedPetId}`)
      .set(
        {
          petProfile: { petAvatar: photoUrl },
        },
        { merge: true } // ←これが大事
      )
      .then()
      .catch(function(error) {
        console.error("Error adding document: ", error);
      });
  }
```

ポイントは
`{ merge: true }`を追加してるところ。
これは
>新しいデータを既存のドキュメントに統合するオプション

だそうです。
これがないと他の値は消されて、新たに追加された値だけ入った状態で上書きされます。

参考：
https://firebase.google.com/docs/firestore/manage-data/add-data
【Android / Kotlin】プロジェクトでアノテーション（@）を使えるようにする

# はじめに
Kotlin でデータバインディングを使うために、**kapt** の導入が必要であることを知った。
具体的に言うと自分の場合は
``@get:Bindable ~``と言う記述をしても``BRクラス``に監視変数が生成されずにつまずきました。調べた結果 **kapt** の導入に行き着きました。

# なぜ必要なのか
**kapt** とは kotlin-annotation-processing-tools の略であり、Kotlin プロジェクトでもアノテーション（@）を使い自動コード生成ができるようにするもの。
つまり、Dagger や DataBinding などを利用する際に導入が必要となるようである。

# 環境
- Android Studio: 4.1.1
- Build #AI-201.8743.12.41.6953283, built on November 5, 2020
- Runtime version: 1.8.0_242-release-1644-b3-6915495 x86_64
- VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
- macOS: 10.15.7

# 導入
私の場合はこの1行追加するだけで使用できました。

```app/build.gradle
// 一部抜粋
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt' // ←ここに追加
}
```

上記ではなく、こちらの1行の追加でも大丈夫なはず

```app/build.gradle

apply plugin: 'kotlin-kapt'
```

これで無事``BRクラス``に監視変数が作成されました！！

# 最後に
Java ではこのような記述が必要ではないため、Kotlin の場合でも DataBinding の導入では以下の記述だけ追加すれば良いと考えておりました。

```app/build.gradle
dataBinding {
    enabled = true
}

// もしくは
buildFeatures {
    dataBinding = true
}
```

解決までに数時間費やしてしまい、今回また勉強になりました。


#参考リンク
ありがとうございます！
参考にさせていただきました！

- https://kotlinlang.org/docs/reference/kapt.html
- https://qiita.com/uhooi/items/836902cdd322f9accded
DialogFragmentの背景色を透明 or 指定する 


## やりたい事

マテリアルデザイン化したDialogFragmentの背景のグレー（スクリム）を透明 or 色を指定したい

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52227/7fbc3bda-4bc3-018d-f19b-1092d5d830cc.png  width=40%>


スクリムとは何か？はMaterial Designガイドラインで説明されている
https://material.io/components/dialogs#anatomy

## 完成形
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52227/fae4b5f1-f785-b7e3-58d9-3d2fcf3dcf14.png  width=40%>

## 実装コード

やり方は style.xml or コードの２通りがある。

### style パターン

```xml:style.xml

    <!-- https://material.io/components/dialogs/android#dialogs -->
    <style name="TransportDialog" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">

        <!-- 透明にする -->
        <item name="android:backgroundDimEnabled">false</item>

        <!-- 色を調整する -->
        <item name="backgroundDimAmount">10f</item>
    </style>
```

このstyleをDialogFragmentにセットする

```kotlin
class TransportDialogFragment : DialogFragment(R.layout.transparent_dialog_fragment) {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // スタイルをセット
        setStyle(STYLE_NORMAL, R.style.TransportDialog)
        return super.onCreateDialog(savedInstanceState)
    }
```

これで色が変更できた。

### コード パターン


```kotlin

class TransportDialogFragment : DialogFragment(R.layout.transparent_dialog_fragment) {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return super.onCreateDialog(savedInstanceState).apply {
            // Dialog背景色を指定
            window?.setDimAmount(0f) // 0だと透明になるので適宜調整する
        }
    }
}
```

これでも色が変更できる。

## 全体コード
GitHubにUPしておいた

https://github.com/ikemura23/Android-Kotlin-Lab/blob/master/app/src/main/java/com/ikemura/android_kotlin_lab/dialog/dialogfragment/TransportDialogFragment2.kt

## 参考リンク
material-components-android/getting-started.md at master
https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md

Dialogs - Material Design 
https://material.io/components/dialogs
本当にあったやらかしDB設計⑨【文字列日付】

どうも、最近スキー板を買った人です
緊急事態宣言出てるんですけどね…ｗ

今日は久しぶりにネタを発見したのでそれについて書いていこうと思います

#文字列日付
日付を文字列型(varcharやtext)で扱ってしまっている、ということです
これ結構見かけるので、一部界隈で流行っているのかもしれません

###何が悪いの？
日付型であれば問題にならなかったことが文字列型だと発生する可能性があります

###問題

- **日付の計算ができない**

文字列型だとそのままで計算することができません
int型に変換して無理にやろうとすると…
「2020/12/31に1を足したら、2020/12/32になった」
のようなことが発生します
そもそも30日の月と31日の月を定義するのもめんどくさい上に、うるう年のような計算も入れなければなりません

そのため、文字列型で日付の計算をしようとした場合、結局日付型に直してから計算をするはめになります
で、計算が終わったら日付型を文字列型に直してinsertする…というようなことが発生します
(うるう秒に関しては対応していないDBMSも多いようですが)

- **時差の変換ができない**

日付型には、どこの国の時間を使うかが指定できます
が、文字列型だとこんな芸当はできません
これも結局日付型に直して計算する必要があります

- **日付型より柔軟性が無い**

例えば、文字列型だと「202013」のような文字列がinsertされてしまいます
これを避けるために下2桁を抽出し、1～12に一致する場合のみinsertを許す、というcheck制約を追加したとします
しかし、もし全ての月を28日にし余った日付を13月にする、という仕組みが世界的に導入されてしまった場合、そのcheck制約は意図に反したものになってしまいます
世界的にこの仕組みが導入されるのであれば、各DBMSはそれ相応の対応をするはずです(互換性のある型を作ったりする等)
文字列型で扱っていると、その恩恵を全く受けることができなくなってしまいます

###原因
なぜこんなことが起こってしまうのか、考えてみました

- **フォーマットがめんどくさそうだから使わない**

確かに、日付型はフォーマット周りがちょっとめんどくさいです
が、逆に言えば自分の好きなフォーマットでデータを格納できる、ということなのでこれは良いことだと思います
特に指定がなければデフォルトのフォーマットを使ってしまいましょう

- **日付型にするメリットがわからない**

あまり日付を扱ったことが無いのであればわかりますが、これまで説明した内容で日付型のメリットをわかって頂けたと思います

#解決方法

- **日付を扱うときは日付型を使う**

これだけで文字列型で発生していた問題を解決することができます

#ちょっとおまけ
今回は日付を文字列型として扱ってしまう、という例を見てきましたが、日付をint型で扱うこともあるようです
データ型の選択肢を誤る、異常な制約を掛けてしまう、ということがかなり起こっているようです

例えば、number型(numeric型)のようなものの場合、小数点より右側を何桁までにするかは重要ですが、小数点より左側を何桁までにするかはあまり重要ではありません
にもかかわらず、整数部にまで桁数の制限を掛けたりしてしまっているようです

varchar型やtext型でも、「とりあえず1000くらいで制限をかけとこ」って人が多いようです
確かに、1レコードが格納できる容量というのは決まっているためある程度制限を掛けたほうが良いという意見もわかりますが、これをやってしまうと別の問題が発生します

画面で1000文字までの入力しか受け付けず、DBでも1000文字までしか受け付けないようにしているとします
このとき、画面側で3000文字まで入力を受け付けたい、となったときはDBのカラム定義変更を行う必要が出てきてしまいます
これは、DBで異常な制約を掛けてしまったせいで画面とDBが密結合になってしまっている例です
画面で受け付けるデータの種類を増やしたい、という例であればDBのカラム追加は正当なものになり得ますが、文字数に関しては本来不要だった作業が増えてしまっています

そのため、文字列型や実数型で異常な制約を掛けるのはやめましょう
基本的には、制限を掛けないか、デフォルトの値を使いましょう

データの生成をデバックするのはアプリケーションの仕事です
倉庫に失敗作が入っているからといって、それを倉庫のせいにしないでください
(勿論、データの不整合を防ぐための外部キーは必要です)

#まとめ
- **黙って日付型を使え**
- **意味もなく制限を掛けるな**

どうだったでしょうか
無意味なことはやめて、意味のあることをやりましょう

- [本当にあったやらかしDB設計シリーズ一覧](https://qiita.com/bouitengineer12/items/e63e5f7d6f628da11362)
Mqtt Explorer の使い方

Ubuntu へのインストール方法

```bash
sudo snap install mqtt-explorer
```

起動

```bash
mqtt-explorer
```

![mqtt_a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d8f5a128-e96f-c987-34a9-99705082af1b.png)

publish
>Topic を入れます。

![mqtt_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/54328bfa-0ae2-60a6-5ff8-ae3ad4ce5c25.png)

subscribe

![mqtt_cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/5d6526de-6aee-302e-f7fd-a43afd56709a.png)

テストに使ったブローカーはこちらで作成したものです。
ポートは 8883 になります。
[Mosquitto で Let's Encrypt の証明書を使う](https://qiita.com/ekzemplaro/items/d2afb5d421c7d4d457c2)
A server is already running. すでにサーバーが動いています。

#はじめに
Railsチュートリアル第2章を学習中に`Rails server`したあと、誤ってターミナルを閉じてしまい、再度`Rails server`をするとエラーがでたのでその解決方法を書いていきます。

#エラー内容
```
=> Booting Puma
=> Rails 6.0.3 application starting in development 
=> Run `rails server --help` for more startup options
A server is already running. Check /home/ubuntu/environment/toy_app/tmp/pids/server.pid.
Exiting
```

【翻訳】
=> プーマを起動する
=> 開発中のRails6.0.3アプリの開発開始 
=> `rails server --help` を実行すると、起動時のオプションが増えます。
すでにサーバーが動いています。/home/ubuntu/environment/toy_app/tmp/pids/server.pidを確認してください。
終了する

翻訳サイト: [DeepL](https://www.deepl.com/home)

#エラー解決までの道のり
`/home/ubuntu/environment/toy_app/tmp/pids/server.pid`を確認してください。
とあるので、確認してみるとポート番号が書いてあったので、強制終了します。

```
kill -9 [ポート番号]
```

`rails server`で再起動をして、無事解決できました！
#参考にした記事
* [【Rails】終了できない！A server is already runningの対処！
](https://qiita.com/pippi0920/items/4baadd537a3213c4b30d)
* [Rails sのプロセスが切れない時](https://qiita.com/motty93/items/d22c1eb8f5128f8cd7f8)
量子コンピュータって何？

・量子
原子とか電子とか　目に見えないくらいの小さい粒

・量子力学
量子には慣性の法則などの物理法則が通用しない
どんな性質や法則が存在するか調べる学問

「おもな性質・補足」
-観測されると動きが変わる（2重スリット実験）
-量子を引きちぎって双子にすると、どれだけ離れていてもお互いに見られていることに気づく（量子テレポーテーション）

・量子コンピュータ
いろんな状態が重なり合って存在しているという量子の性質を利用して、計算を一気に同時に実施するコンピュータ
matlabのData Acquisition Toolboxを使う② NI cRIO-9201

　アナログ入力を手軽に得る方法に、NIの測定ツールを使う方法があります。低速なものから高速なツールがあります。前回使ったUSB-6009（14ビット、差動4チャネル）は、低速です。少しサンプリング速度の高い9201を利用します。
　このユニットcRIO-9201のおもなスペックは、
　　±10 V, 500 kS/s, 12-Bit, 8-Channel C Series Voltage Input Module
ですが、単独では使えません。収納するケースが何種類かあり、ここでは、一番安価な、
　　NI cDAQ-9171　NI CompactDAQ 1 スロットバス電源駆動 USB シャーシ
に取り付けて使いました。

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/7bcda5b0-c751-f801-2ddf-2e0e216a3e7b.png">
　USBケーブルでPCとつなぐだけで準備は終わります。ここでは、入力信号にファンクション・ジェネレータFGX-2005の出力を、0番と9番（GND）につなぎました。8番はNCです。

###アプリAnalog Input Recorderを起動
　Data Acquisition Toolboxをインストールすると、Analog Input Recorder、Analog Output Generatorがアプリに登録されています。Analog Input Recorderを起動します。cRIO-9201を探し出してきて、入力波形を表示します。
　Rateがデフォルトの1000だと波形が出なかったので、10000に変更しました。

![スクリーンショット 2021-01-23 12.23.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f6355c3a-c09f-0f39-7c01-2319f94ea4cd.png)


　画面上部の右端にあるGenerate Script codeをクリックします。そのまま実行をクリックします。1秒間ロギングしたデータがグラフに描かれます。

![スクリーンショット 2021-01-23 12.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/055333d7-4ef1-c414-9d49-ea2183f77d49.png)

　ファンクション・ジェネレータは1kHz、1Vp-pの正弦波です。

　細かくてわからないので、

```matlab
data = cDAQ1Mod1_1(1:50, :)
```

　先頭の50個を表示しました。
![ni101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f0268589-14e8-8e50-eb30-5415d7265ce0.png)


　サンプリング・レートが低いですね。デフォルトは10000になっていました。最大値800000に変更します。表示は1000に変更しました。

```matlab
d.Rate = 800000;
```
![ni102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f010db11-6350-c7f6-0e26-170d4fc920ca.png)

　差動入力でないのが理由かもしれませんが、ノイジーです。

###発振器の周波数を10kHzに更新

![ni103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/19360d31-b7eb-582f-feb5-ef9abba28eaf.png)

　発振器の周波数を50kHzに更新します。

![ni105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/15587a8f-d2b3-fd4e-cd2f-5645e73ecc3f.png)

　限界を超えたようです。

###プログラム

```matlab
%Create a DataAcquisition object for the specified vendor.
d = daq("ni");

%Add Channels
addinput(d,"cDAQ1Mod1","ai0","Voltage");

%Set DataAcquisition Rate
d.Rate = 800000;

%Read the data in timetable format.
cDAQ1Mod1_1 = read(d,seconds(1))
summary(cDAQ1Mod1_1)
data = cDAQ1Mod1_1(1:200,:);

%Plot the read data on labeled axes.
plot(data.Time, data.cDAQ1Mod1_ai0)
xlabel("Time")
ylabel("Amplitude (V)")
legend(cDAQ1Mod1_1.Properties.VariableNames)

%Clear all DataAcquisition and channel objects.
clear d
```

###スムーズにしてみた

　意味があるかどうかはわかりませんが、入力10kHzに移動平均（データは10個）をかけました。
![ni106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/888ba63f-162e-3ea8-25c4-556ad1aa59f2.png)



（※）matlabはR2020bアップデート3です。
シンボリックリンクで別ドライブにPDF-XChangeEditorのキャッシュを保存する

PDF-XChange EditorのキャッシュがCドライブの容量を圧迫するのでその対処方法をメモとして残します
本ソフトに限ったことではありませんが似たような状況の人は参考にしてみてください

##PDF-XChangeEditor使用するのになにが問題なのか？
問題点
PDF-XChange EditorのキャッシュがCドライブの容量を圧迫し保存ができなくなる
原因
キャッシュフォルダ内「PDFXedit」が原因　※数GBのキャッシュを作る場合もある



##対処はキャッシュフォルダをシンボリックリンクで別ドライブへ逃がす

なぜ別ドライブに逃がす必要があるのかというと
弊社PCのCドライブの空きが2GB程度、個人の保存領域としてXドライブが20GBほど割り当てられている環境で
キャッシュでCドライブの空き容量を食い尽くされると編集中のPDFファイルの上書き保存ができなくなるんですよね
そもそもCドライブの容量を大きくしてくれればいいんですが・・・

対処手順ですが下記となります

####1：キャッシュを逃したいフォルダに「PDFXEdit」フォルダを作成する　※今回はXドライブ直下
>キャッシュの逃し先です、もとのフォルダ名以外でも大丈夫だとは思いますがわかりやすくするために同じ名前にしています

####2：CドライブTemp内にある「PDFXEdit」を削除
>削除しておかないとmklink時に"既に存在するファイルを作成することはできません。"といったエラーを吐きます

####3：コマンドプロンプトを管理者権限で実行
>mklinkコマンドが管理者権限でないと実行できません

####4：下記コマンドの実施
mklink /D C:\Users\\<ユーザー名>\AppData\Local\Temp\PDFXEdit X:\PDFXEdit

イメージ的には
mklink [オプション] リンク作成場所 実際にファイルを格納する場所
と言う感じでしょうか　/Dはディレクトリを作成するというオプションとなります

これでPDFXeditの中身が別のドライブに保存されるようになります
テスト26

```vb

Private Sub Workbook_Open()

'祝休日からの営業日判定
'--------------------
'事前に参照設定を行う
'Microsoft XML, v3.0
'---------------------
'https://www.apibank.jp/ApiBank/api/detail?api_no=599&api_type=Iを参照
'祝日判定WebAPI
'内閣府のwebを元に祝日チェック(日本特有の官公庁や東証の休日にも対応)を行うwebAPI
'-----------------------

Dim D As Variant         '日付用
Dim apiUrL As String    'apiのURL
Dim apiUrL2 As String   'apiのURL
Dim day As Variant
Dim HttpReq As Object   'Httpリクエストオブジェクト用
Dim i As Long           'カウンタ
Dim j As Long           '営業日
Dim k As Long           '通常日数

Application.ScreenUpdating = False

On Error GoTo ErExit

apiUrL = "http://s-proj.com/utils/checkHoliday.php?kind=h&date="

D = Replace(Date, "/", "")

i = 1
    
Set HttpReq = CreateObject("MSXML2.XMLHTTP")
    
apiUrL2 = apiUrL

D = Date

k = 0
'-----------------------------------------
For i = 1 To 21

    D = Replace(D, "/", "")
    
    apiUrL2 = apiUrL & D

    HttpReq.Open "GET", apiUrL2, False

    HttpReq.Send (Null)
    
    '戻り値（祝休日の場合holiday、それ以外はelseを返す)
    If HttpReq.responseText = "else" Then

        '営業日計算で指定の日数に達した条件ごとに入力
        If j = 1 Then
        
            ThisWorkbook.Sheets("Sheet7").Cells(4, 2).Value = Format(D, "0000/00/00")
        
        ElseIf j = 5 Then
        
            ThisWorkbook.Sheets("Sheet7").Cells(5, 2).Value = Format(D, "0000/00/00")
        
        ElseIf j = 10 Then
        
            ThisWorkbook.Sheets("Sheet7").Cells(6, 2).Value = Format(D, "0000/00/00")
        
        End If

        j = j + 1   '営業日日数加算
        k = k + 1   '通常日数加算
        
    Else
    
        '通常日数加算
        k = k + 1
  
    End If
    
    D = Date + k
        
    If k = 21 Then
    
        ThisWorkbook.Sheets("Sheet7").Cells(7, 2).Value = D
    
    End If
    
Next i
'-----------------------------------------

Set HttpReq = Nothing

Application.ScreenUpdating = True

Exit Sub

'----------------------
ErExit:

MsgBox "サーバーに接続できなかったので、手入力でお願いします。", vbCritical

Set HttpReq = Nothing

Application.ScreenUpdating = True

End Sub
```
シェルスクリプトで配列の格納ができなかった話

とあるデータをシェルスクリプトで読み取ろうとして失敗したお話

```test.txt
aaaaaa
iiiiii
```

```read.sh
TEXTFILE=./test.txt

echo "start"

cat ${TEXTFILE} | while read line
do
 echo ${line}
done

echo "done"
```

```
$ sh read.sh
start
aaaaaa
iiiiii
done
```

これで問題なく動作する

# これを配列に格納するようにする場合

```read.sh
TEXTFILE=./test.txt
declare -a list

echo "start"

cat ${TEXTFILE} | while read line
do
 list+=(${line})
done

echo ${list}
echo "done"
```

```
$ sh read.sh
start

done
```

実行結果としては配列に入っていて欲しいデータがない状態となる

この原因としては下記のようにパイプ用いる場合、パイプ以降の処理が別のプロセスとして処理される
`cat ${TEXTFILE} | while read line`

今回で言うと`while`は別の処理として扱われてしまうため`list`にデータが格納されない

# 改善方法

早い話がパイプを使わなければいい

```read.sh
TEXTFILE=./test.txt
declare -a list

echo "start"
DATA=`cat ${TEXTFILE}`

while read line
do
  list+=(${line})
done << FILE
${DATA}
FILE

echo ${list[*]}
echo "done"
```

```
$ sh read.sh
start
aaaaaa iiiiii
done
```

改行は配列の出力の仕方を変えればいいので今回は省略
自宅wifi速度を改善してみる


## 自宅wifiの速度が出ない


親機 : WHR-1166DHP4（https://www.buffalo.jp/product/detail/whr-1166dhp4.html）
速度計測ツール : https://fast.com/ja/

自宅3Fに無線親機を置き、2Fに中継機を置いている
2F : 1回目 1.2Mbps 2回目 4.3Mbps 3回目 1.7Mbps
3F : 1回目 4.0Mbps 2回目 2.5Mbps 3回目 2.0Mbps

無線接続端末は 5台
優先接続端末は 1台

> 快適なインターネットの通信速度の大まかな目安は20Mbps
> 快適なインターネットの速度は、非常におおまかにいって20Mbps（メガビーピーエス※）が目安となります。現在使用しているインターネット回線の速度を計って20Mbps出ていれば、大抵のことは快適にこなせる状態といえるでしょう。
FYI : https://selectra.jp/telecom/guides/knowledge/best-speed

## 公式アナウンス
https://www.buffalo.jp/support/faq/detail/8342.html

## 試行錯誤
・[高速アドレス変換（有線）]の[使用する]のチェックを外し、[設定]をクリックする
　・インターネットと有線LANを利用する場合に必要な設定。
　-> 有線LAN使っていないので、無効にして再起動。

・ファームウェアのアップデート
　・自動更新になっているが、最新版ではなかったので、2.93 -> 2.94 に手動アップデート。

ここまでして、3F で再計測すると、7.4Mbps 7.3Mbps。

・「電波の干渉を受け、不安定になっている」可能性があるので、「Buffalo-A-DCxxx」の帯域を変更
　800Mbps -> 400Mbps に変更

## 再計測

3F 120Mbps 37Mbps 23Mbps 11Mbps 31MBps 32MBps
2F 4.3Mbps 11Mbps 3.3Mbps 3.8Mbps 28Mbps 22MBps


## 結論

追記 2020/01/25

オンライン会議の音声が途切れたり、ラグがあり気になったので、ルーターを下記に買い換えた。
WSR-1166DHPL2 : https://www.amazon.co.jp/dp/B086WDY9XS/

後、モデムとルーターをつなぐ有線LANを下記に変えた。

UGREEN LANケーブル カテゴリー7 : https://www.amazon.co.jp/dp/B00QV1F0RU/

160Mbpsまで出るようになった。

追記 2021/03/30

オンライン対戦ゲームしていると回線落ちがちょくちょく発生するようになり、
何が問題か調べたところ、IPv6対応がルーター側の設定でできていなかったことがわかった。

FYI : http://elsur.xyz/buffalo-router-setting-ipv6

200Mbps到達した！

![スクリーンショット 2021-03-30 3.13.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247837/11d9f1f5-f721-fdf9-e41f-d5379311adac.png)
STSで行うカバレッジ測定

1. Eclipseマーケットプレイスで「EclEmma Java Code Coverage」をインストールし、再起動する


![スクリーンショット 2021-01-23 12.39.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/909c5d0f-ff41-6a3e-de67-f99477048c51.png)

![スクリーンショット 2021-01-23 12.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/564ba713-87b3-f092-1d92-d9ef0cd254cb.png)

2.　「src/test.java」を右クリックで画像のようにJUnitを選択して実行
![スクリーンショット 2021-01-23 12.40.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/be4273aa-fd3a-a5dd-2ecd-33b8ce190920.png)


３. 以下の画面のように、ソースコードに背景色がつく。
　　緑:OK 黄色:分岐の片方しか通っていない 赤:通っていない。これを全て緑にすると、「カバレッジ100%」
![スクリーンショット 2021-01-23 12.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/782a463c-1617-424f-9e07-277a1b0604c2.png)
全体のカバレッジのパーセントは「カバレッジ」のビューで確認できる
![スクリーンショット 2021-01-23 12.45.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/dd9d2aee-be45-5825-8bf8-0403aaa7eaf7.png)
[HTML5] datetime-localで，placeholderが表示されない問題を解決する

# datetime-localとは

日付と時刻を1つのウィンドウで入力できる，input要素の型です。

詳しくは，MDN Web Docsで説明されておりますので，下記URLからご確認ください。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/datetime-local

## ブラウザーの対応状況

2021年1月23日時点の，"Can I Use..."の情報 ( https://caniuse.com/?search=datetime-local ) によると，


- モバイルブラウザー: ほとんどが対応しています。（Opera MiniとKaiOS Browserを除く）
- デスクトップブラウザー: IE，Firefox，Safariが非対応となっています。
（ただし，SafariのTechnology Preview版では対応とのこと→次期バージョンのSafariは，対応するかも？）

モバイルではほぼ導入が完了している一方で，デスクトップでは導入に消極的です。

結論: アクセスをモバイル端末に限定させるか，Cordovaを利用してアプリにするならば，問題はなさそうです。

# 本題: Placeholderが表示されない！

なぜかiOS Safari等で，placeholderが表示されません。
そこで，:beforeとカスタム属性を使って，強引に解決させます。

##コード

HTML

```HTML
<input type="datetime-local" id="target">
```

CSS

```CSS
#target {
  position: relative;
  width: 50%;
  height: 10vh;
  font-size: 14px;
 -webkit-appearance: none;
 -moz-appearance: none;
 appearance: none;
 border: 1px solid #333;
 border-radius: 0;
 outline: none;
}
#target::before {
  position: absolute;
  width: 100%;
  height: 100%;
  padding-left: 10px;
  font-size: 14px;
  line-height: 10vh;
  top: 0;bottom: 0;left: 0; right: 0;
  content: attr(placeholder2);
}
#target:focus{
  background: #333;
  color: #fff;
}
```






JS

```JS
const placeholder="日時を選択",target=document.getElementById('target');
target.setAttribute('placeholder2',placeholder);

const focusplaceholder=()=>{
    event.target.setAttribute('placeholder2', ' ');
}

const inputplaceholder=()=>{
  if(event.target.value){
    event.target.setAttribute('placeholder2', '  ');
  }else{event.target.setAttribute('placeholder2',placeholder);}
}

target.addEventListener("focus",focusplaceholder);
target.addEventListener("input",inputplaceholder);

```

## 注意事項

- 上記コードは，モバイルブラウザーでの利用（or Cordovaでの開発）が前提です。
デスクトップブラウザーの場合，ブラウザーデフォルトの"yyyy/mm/dd --:--"と，上記で設定したplaceholderは重なります。それゆえ，使い物にはならないでしょう。

- コードは，各自で改良していただければと思います。もっと綺麗に書ける方法があれば，ご教示いただければ幸いです。
Gradleプラグインを適用するスマートな書き方

`app/build.gradle`

```groovy:before
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
```

```groovy:after
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
}
```

## 参考リンク

- [Using Gradle Plugins](https://docs.gradle.org/current/userguide/plugins.html)
【Rails】ルーティングヘルパー

#はじめに
ポートフォリオの作成をし、メンターさんにフィードバックをいただいた点があったので今後の為に書き留めておきます。
改善目標として
・Railsっぽいコード（レールに乗ったコード）を目指す。つまり、Railsが用意している便利な機能を活用する。

・ルーティングは以下のように設定しています。

```ruby:config/routes.rb
resources :blogs
```

#Before
```erb:app/views/blogs/edit.html.erb
<h1>ブログ編集</h1>
    <%= form_with model:@blog, url:"/blogs/#{@blog.id}", local: true do |f| %>
      <h4>タイトル</h4>
      <%= f.text_field :blog_title %>
      <h4>画像</h4>
      <%= f.attachment_field :image %>
      <h4>本文</h4>
      <%= f.text_area :blog_text, size: "40x10" %>
      <%= f.submit "編集を保存", class: "btn btn-primary" %>
    <% end %>
```

改善すべきは２行目の「url:"/blogs/#{@blog.id}"」
このようにurlをベタがきしていると、urlを変更したくなった時に修正箇所がとても多くなってしまう。
そこで、ルーティングヘルパーという機能でこのコードを改善します。
#やったこと

```:Terminal
$ rails routes
                    blogs GET    /blogs(.:format)                                                               blogs#index
                          POST   /blogs(.:format)                                                               blogs#create
                 new_blog GET    /blogs/new(.:format)                                                           blogs#new
                edit_blog GET    /blogs/:id/edit(.:format)                                                      blogs#edit
                     blog GET    /blogs/:id(.:format)                                                           blogs#show
                          PATCH  /blogs/:id(.:format)                                                           blogs#update
                          PUT    /blogs/:id(.:format)                                                           blogs#update
                          DELETE /blogs/:id(.:format)                                                           blogs#destroy

```

パスとヘルパーメソッドの関係はターミナルから「rails routes」と打って確認できます。
左がヘルパーメソッドに渡すコードで右がそれによって返されるパスという認識です。

#After

```erb:app/views/blogs/edit.html.erb
<h1>ブログ編集</h1>
    <%= form_with model:@blog, url: edit_blog_path(@blog.id), local: true do |f| %>
      <h4>タイトル</h4>
      <%= f.text_field :blog_title %>
      <h4>画像</h4>
      <%= f.attachment_field :image %>
      <h4>本文</h4>
      <%= f.text_area :blog_text, size: "40x10" %>
      <%= f.submit "編集を保存", class: "btn btn-primary" %>
    <% end %>
```

#最後に
Railsが提供している機能を知り、レールに乗ったコードが書けるように精進します:fist::fire:
AtCoder C++ メモ

基本入力方法をメモします。
AtCoder初心者ですが、これははまる。。。

```c++:include

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
```


```c++:input
int N, C;
cin >> N >> C;
```


```c++:vector
//1-dim
vector<int> vec(N);
//2-dim
vector<vector<int>> vec(Col, vector<int>(Row));  
//3-dim N × (3 × 3)要素の配列
vector<vector<vector<char>>> data(N, vector<vector<char>>(3, vector<char>(3)));
```

```c++:vector_input
vector<vector<int>> vec(N, vector<int>(3));
for(int i = 0; i < Row;i++){
    for(int j = 0; j < Col; j++){
        cin >> vec[i][j];                    
    }
}
```

```c++:sort
// 昇順に並べ替える
sort(v.begin(), v.end());
```


```c++:cout
cout << "No money" << endl; 
cout << "sum = " << sum << endl; 
cout << "day = "<< day << ", sum = " << sum << endl; 
cout << "day = "<< day << ", sum = " << sum << ", total = " << total <<endl; 
```

```C++:cout_vector
cout <<"string_split " ;
for(auto ss : opt){
    cout <<  ss << " " ;
}
cout <<endl;
```

```C++:int_to_char
string str;
int num = str.at(k) - '0';
```

参考サイト　
[多次元配列] (https://atcoder.jp/contests/APG4b/tasks/APG4b_t)

int_to_char '0' が必要な理由↓
[char型をint型に変換する方法と注意【数値化 キャスト 文字列変換】]
(https://marycore.jp/prog/c-lang/convert-or-cast-char-to-int/)
Reactアプリ内でのReduxの複数のReducerを一つにまとめる方法

## 1. `combineReducers()`を`redux`からimportする。

```js:src/reducers/index.js
import { combineReducers } from 'redux';
```

## 2. まとめたい他のreducerもimportする。
```js:src/reducers/index.js
import { combineReducers } from 'redux';
import counterReducer from './counter'; // 追加
import loggedReducer from './isLogging'; // 追加
```

## 3. importした`combineReducers()`を使用してreducerをまとめる。そしてexport。

```js:src/reducers/index.js
import { combineReducers } from 'redux';
import counterReducer from './counter';
import loggedReducer from './isLogging';

// coombine()を使ってreducerをまとめる。
const rootReducers = combineReducers({
  // key名はなんでも。任意のものでいい。
  counter: counterReducer,
  isLoggedIn: loggedReducer
  // ちなみに、ES6のプロパティ名のショートハンドを使用して以下のようにも書ける
  // counterReducer,
  // loggedReducer
});

export default rootReducers;
```

## 4. exportしたrootReducerを`src/index.js`でimportする。

```js:src/index.js
import roorReducers from './reducers' // ファイル名の指定がない場合、webpackがindex.jsを自動的に指定してくれる

// ReduxのcreateStore()の引数にrootReducersを渡す。
const store = createStore(
  rootReducers
);
```
## 完了！

# 参考
▷[Redux For Beginners \| React Redux Tutorial - YouTube](https://youtu.be/CVpUuw9XSjY)
▷[ちょっと高度なJavaScriptの話 - Qiita](https://qiita.com/renesisu727/items/0447fce8a9e00817f1f5#%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E5%90%8D%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%83%8F%E3%83%B3%E3%83%89)
Couldn`t find Item(Model) without an IDの解決

### はじめに
個人でアプリを開発していてわかったことを今回記事にしました。
状況によっては異なる場合がございます。

###### 開発環境
pc: macOS Catalina
shell: zsh
rails: 6.0.0
ruby: 2.7.2

### エラー内容
![スクリーンショット 2021-01-23 11.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953148/d9e128ba-084f-cc47-59a7-679c6a04eee5.png)

controller処理でfindメソッドがIDがないと警告を出しています。
itemテーブルの情報を取得する記述をしています。

### 仮説
①ルーティングの影響により記述が間違えていることによりパラメーターのIDを取得することができない
②ビューのURLに引数として指定されたIDが引き渡しができていないことでIDがないと言っている。

### 結論
今回のエラーの解決方法にはルーティングのネストの影響が関係していました。
ルーティングをネストすることで、IDが変わってしまうと言うことです。

```Ruby:routes.rb
Rails.application.routes.draw do
  devise_for :users

  root to: "items#index"
  
  resources :items do
    resources :orders , only: [:index, :create]
  end
end

```


```
% rail routes

        root GET    /                                            items#index
 item_orders GET    /items/:item_id/orders(.:format)             orders#index
             POST   /items/:item_id/orders(.:format)             orders#create
       items GET    /items(.:format)                             items#index
             POST   /items(.:format)                             items#create
    new_item GET    /items/new(.:format)                         items#new
   edit_item GET    /items/:id/edit(.:format)                    items#edit
        item GET    /items/:id(.:format)                         items#show
             PATCH  /items/:id(.:format)                         items#update
             PUT    /items/:id(.:format)                         items#update
             DELETE /items/:id(.:format)                         items#destroy
```

### 解説
items controllerでURIは/items/:id(.:format)となっています。
そのため、@item = Item.find(params[:id])とすることでIDが取得することができます。
しかし、Prefixのitem_ordersをみてみるとURIには/items/:item_id/orders(.:format)となっており
IDが変化してしまっています。ですので上記のように記述をしてしまうと、エラーを引き起こしてしまうのです。
@item = Item.find(params[:item_id])とすることでルーティングのURIのIDが一致し取得することができます。

ここから、ネストすることの意味も把握する必要があるのだなと実感しました。


### 参考文献
・ Ruby on Rails 　　　　    　著：小餅 良介
・ 達人に学ぶDB設計徹底指南書   　著：ミック
CARTAって何だ?

[CARTA](https://www.gartner.com/en/webinars/3891406/the-7-imperatives-of-continuous-adaptive-risk-and-trust-assessme)とはContinuous Adaptive Risk and Trust Assessmentの頭文字を取った略語でGartner社が2018年頃から使い始めたようですが、いったい何のことでしょうか? この記事は私なりのCARTAに対する理解をまとめものです。

# 一回こっきりから継続へ
ある一時点で認証や認可を行いリスクを検証するのではなく、サービス開発〜運用までのライフサイクル全般に渡り継続的にリスクを検証することが根底にある考え方だと理解しています。数年前によく耳にした[DevSecOps](https://www.redhat.com/en/topics/devops/what-is-devsecops)のように、SDLCライフサイクルに各種セキュリティプラクティスを組み込むことと同じ考え方だと思います。

# 物理から論理へ
デバイスのIDやIP Addressのような物理情報をチェックしてリスクを検証するのではなく、ユーザのIDや振る舞い、利用しているApplicationのような論理情報をチェックしてリスクの大小を判断することが重要と思っています。例えば、既に安全なアクセスと認識されているデバイスIDとID Addressの組み合わせでユーザがあるサービスにアクセスしてきた場合でも、リスク無しと判断せずに認証を要求して、認証に成功したタイミングで初めてリスク無しと判断します。

# 下位層だけでなく上位層も
"物理から論理へ"と同じをことを違う粒度で述べていることになりますが、HardwareやNetwork, OSのような下位層の情報だけではなく、Applicationやユーザがやろうとしている活動、時間帯やアクセスしようとしてきている場所、クレデンシャルの評判等、上位層の情報も包括的に加味してリスクの大小を判断すべきと考えています。ニューノーマルな時代に下位層の情報だけをリスクを検証することは無意味ですね。

# 具体例
私が今思いつく具体例です。

1. あるユーザがシアトルからMacBook ProにインストールされたChromeを利用してあるWeb ApplicationにID=hoge/Password=hogeでログインに成功しました
2. 悪意のある犯罪者が東京からWindows10にインストールされたChromeを利用してあるWeb ApplicationにID=hoge/Password=hogeで認証を試みました
3. IDプラットフォームは、犯罪者のデバイスIDとIP Addressをチェックして、アクセスしようとしている場所は東京と判断しました。更に入力されたID=hoge/Password=hogeをチェックして、数分前にシアトルからWeb Applicationにログインしていることが判明しました
4. IDプラットフォームはこのログイン試行をリスク大と判断して、犯罪者にID/Passwordとは別にSMSに送ったコードを入力するよう促しました
5. 犯罪者はコードを確認できないためWeb Applicationにログインできません

<br>
おわりです。まだ理解が浅いので随時アップデートします。
[Python pandas]複数のcolumnを参照して、rollingでapplyしたい。

# はじめに

Pythonライブラリpandasで、移動平均などを計算するときには、窓関数を計算するrollingメソッドを利用することが多いです。rollingメソッドを使って、meanなどのデフォルトで用意されている計算以外を行う場合は、applyメソッドで、独自定義した関数を指定します。その時に複数のcolumnが関連した計算をしたいことがあるのですが、rollingメソッドは、columnごとで計算をするので、単純には複数のcolumnを参照した計算を行うことができません。

この記事は、rollingメソッドを使って、複数のcolumnが関連する計算方法についてのメモです。

# 環境
- Windows 10 Home
- Python(3.7.6)
- Pandas(1.2.1)

# 複数のcolumnを参照する方法

[pandasの説明](https://pandas.pydata.org/docs/reference/api/pandas.core.window.rolling.Rolling.apply.html)では、独自関数の引数では、ndarray(if raw=True)かSeries(if raw=False)を受けることになっているので、複数のcolumnを指定することができません。そこで、argsを使って、独自関数の引数にもとのDataFrameを指定して、複数のcolumnを参照します。

```Python
import pandas as pd
import numpy as np
df = pd.DataFrame({'date':pd.date_range('2021/01/20', '2021/01/23'),
                   'A':np.arange(0, 4),
                   'B':np.arange(11, 15),
                   'C':np.arange(34, 38)})
df = df.set_index('date')
#print("Original DataFrame")
#print(df)

#applyしたい関数
def user_define(x, df_u):
    """
    Args:
    	x: applyで与えられるSeries(indexを利用するため）
    	df_u: argsで与える元のDataFrame
    """
    df_A = df_u.loc[x.index, 'A']
    df_C = df_u.loc[x.index, 'C']
    return np.sum(df_A + df_C)

#print("Applied Series ")
df['A'].rolling(2).apply(user_define, args=(df,), raw=False)#argsはタプル指定

```

もとのDataFrame
![rolling_original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/e4c5c4e3-6842-e3f4-7062-95f393a6e692.png)
　　

rolling.applyを適用したSeries
![rolling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/0b7a076c-d16f-3220-b59e-b9c981e6f0f4.png)

# 追記
上記の例だと、`method='table'`でもできます。
```Python
import pandas as pd
import numpy as np
import numba
df = pd.DataFrame({'date':pd.date_range('2021/01/20', '2021/01/23'),
                   'A':np.arange(0, 4),
                   'B':np.arange(11, 15),
                   'C':np.arange(34, 38)})
df = df.set_index('date')

@numba.jit
def user_define(w):
    return np.sum(w[:,0] + w[:,2])

df.rolling(2, method='table').apply(user_define, raw=True, engine='numba').loc[:,'A']
```

# 参考

https://stackoverflow.com/questions/21040766/python-pandas-rolling-apply-two-column-input-into-function

https://pandas.pydata.org/docs/reference/api/pandas.core.window.rolling.Rolling.apply.html
PHPで突如現れた「? : 」に、なんそれ！となった頃の話

めちゃめちゃ初心者だった頃、PHP Laravelでの業務中に、先輩が書いたコードで突如現れた「? : 」に、なんそれ！となりました。

開発言語がPHPなので、「PHP ? : 」とかでググってみても、いまいちHITしなくて困った記憶があり、同じ様な人がいるかもしれないので、記事にしてみました。

早速「? : 」の正体ですが、条件演算子の中の『三項演算子』です。

```
AAA ? BBB : CCC
```

この形、

>AAA が「true」なら BBB 、「false」なら CCC

ということになります。

初心者だった頃の私は、この条件分岐なら全部if文で書いてました。

```ruby:example.php
if ( AAA ) {
    BBB
} else {
    CCC
}
```
どっちが見やすいか、一目で分かりやすいか、と言われると、定義する値によるため、場合によって書き分ける必要があります。

条件や分岐後に定義したい内容が変数だけとかの短いものは、「AAA ? BBB : CCC」の形がスマートだなと思います。

条件演算子『三項演算子』については、PHPマニュアルにて確認しました。
https://www.php.net/manual/ja/language.operators.comparison.php

## 最後に
この記事が「PHP ? : 」とかでググった時に出ると良いなぁと思いながら書きました。
どうなんでしょうね…届けこの想い…！
WSL2向けUbuntu20.04/22.04の初期設定

WSL2でUbuntu(20.04/22.04)を使用する際に、普段実施している共通作業です。
この記事の後、各種用途に合わせて環境を作り込んでいくことを想定しています。

※2023/02/26に22.04環境を作った際、20.04と同じコマンドで問題なく設定できたので記事を更新しました。

# やること
WSL2(Ubuntu)のインストール直後から開始して、

・ホスト名の変更（プロンプトをシンプルにするため）
・パスワード無しsudoを可能に
・Manコマンドなど含め、普通の日本語環境（LC_ALL=日本語）
・デフォルトエディタの変更

# 環境
エディション：Windows 10 Home
バージョン：2004

```
> ver
Microsoft Windows [Version 10.0.19041.746]

> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2
```

# 初期設定

## ホスト名変更

WSLの場合Linuxコマンドの「sudo hostnamectl set-hostname <HOSTNAME>」は次のエラーが出て使えません。

>System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to create bus connection: Host is down

Windowsの設定画面でコンピュータ名を変更するか、管理者権限で起動したPowershellで次のコマンドを入力すると[変更できます](https://4thsight.xyz/10362)。

```powershell
Rename-Computer -NewName "<HOSTNAME>"
```

以降のコマンドはWSL（Ubuntu）上で投入します。

## パスワード無しでsudo可能にする

visudoを使っても良いですが、ファイル編集が面倒なので、/etc/sudoers.d/へ設定ファイルを配置します。

```sh
sudo bash -c 'echo "<USERNAME> ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/<USERNAME>'
```

## パッケージ更新処理

```sh
sudo apt-get update
sudo apt-get upgrade
```

## ロケール設定

manコマンドなど、対応しているコマンドの出力が日本語になります。

```sh
sudo apt install language-pack-ja
sudo update-locale LC_ALL=ja_JP.utf8
```

## Timezone設定

WSLはホストOSのTimezoneが設定されているので作業不要です

## デフォルトエディタを変更

```sh
sudo update-alternatives --config editor
```

対話形式に（vimの場合は[/usr/bin/vim.basic]の）選択肢Noを入力
（vim.basicとvim.tinyの違いは機能が多いか少ないか。通常のvimはvim.bashcのエイリアスです）

# (参考1)普段入れているソフトウェア

## build-essential

c/c++コンパイラおよびMakeと付随するソフトウェアがインストールされます。

```sh
sudo apt install build-essential
```

## gh

githubを便利に
[Installing gh on Linux and BSD](https://github.com/cli/cli/blob/trunk/docs/install_linux.md)

## python-venv

Pythonの仮想環境作成モジュール。Python3は入っているのでvenvも入っているつもりで作業開始すると毎回「not found」と怒られるのでインストールしておく。

```sh
sudo apt install python3-venv
```

# (参考2)やった方が良い場合もあるかもしれない設定

## WSL2環境にWindowsからlocalhostを指定してアクセスできるようにする

例えばFishシェルの設定画面のように、WSL上のWebサーバーなどにWindowsからlocalhostを指定してアクセスしたい場合があります。そんなときの為の設定。

Windowsで次のファイルを作成

```sh:cドライブ/Users/<ユーザー名>/.wslconfig
localhostForwarding=True
```

## Proxy設定

WSLのネットワーク設定は基本的にホスト側の設定を利用するけれど、うまく通信できない場合は次のサイトなどを参考にすると解消するかもしれない。

[UbuntuのProxy設定備忘録](https://qiita.com/daichi-ishida/items/b77c151067427806ede5)

## DNS設定

上記と矛盾するけれど、DNS設定の連携がなぜか中途半端なのでトラブル時は次のページなどを参照する。会社の環境へVPN接続している場合は特に。

[windows標準のubuntuのDNS設定はWindowsとは別に管理されている](https://qiita.com/hashitomu/items/794c9de4989f456db74e)
【UiPath】アクティビティ表示名に番号を振って重複を防ぐ

# はじめに

この投稿は「UiPathでアクティビティ表示名に番号をつけて、強制的にユニークにしよう」という投稿です。
以下の投稿に少し似ています。
　[UiPathワークフローのアクティビティ表示名を一括してユニークにする方法](https://qiita.com/Jun96427231/items/a2b4619e12ed5e48eff9)

この記事は、`UiPath Friends もくもく会 2021年1月開催 2021-01-23（土）08:45 - 12:00` で書きました。

https://uipath-friends.doorkeeper.jp/events/116284


# アクティビティ表示名をユニークにする理由

**エラー発生時に止まった箇所を特定するため**です。
実行ログには「エラーになったアクティビティ表示名」が記録されますが、同じ名前のアクティビティ名があると、どっち（どこ）でエラーになったか判別できません。

同じ名前のアクティビティ名があると、ワークフローアナライザでは「表示名の重複」の警告が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/42632c3a-962b-d449-1e80-f5de9f8cefcc.png)


# 既にツールが公開されている

UiPathマーケットプレイスを検索すると、既にありました。

 - [**パーソルのRPA - アクティビティ採番** (公開日: 2020年5月20日)](https://marketplace.uipath.com/ja/listings/hakttuns7bpz5ewcj4olfo) : xamlファイルに使用されているアクティビティを採番します。
 - [**DisplayNameにユニークなIDを付加** (公開日: 2020年7月3日)]
(https://marketplace.uipath.com/ja/listings/hxhp7a639mmrrbufwdh8go) : アクティビティのDisplayNameにユニークなIDを付加し、DisplayNameの重複を回避します。

良くできていて「どちらも素晴らしい」のですが、自分がやりたいことには 以下の点でマッチしませんでした。

- 実行前に自動でバックアップ取りたい（怖いから）
- カスタムアクティビティだと困ることもある（カスタマイズしたい時がある）
- 時によっては採番方法を変えたい時がある（ファイル単位 or プロジェクト単位）
- 変更する必要がないファイルは編集したくない（更新日変えたくない）
- 表示名の変更前後の内容を知りたい（どう変わったのか、ユニークなのか確認）

# 作る

学習も兼ねて、作りました。

:link: [UiPath Marketplace > Number the Activity DisplayName](https://marketplace.uipath.com/ja/listings/2553)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/0f877797-272e-fe7a-eba2-aa9392e1881d.png)


処理は以下の流れになっています。

```
- 1. Set target project
- 2. Backup project folder
- 3. Get projects xaml
- 4. Edit xaml
  - For Each - line
    - For Each - xaml file path
      - If - contains DisplayName ?
        - Sequence - edit DisplayName
- 5. Output result
```

実行すると、編集前の内容で、フォルダごとバックアップを作成します。
（フォルダ名の後ろに「_年月日-時刻」を付与して作成）
変更結果として、以下のようなHTMLを出力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/184f5526-1185-2c97-d90c-fa3f9dbeb323.png)

# 終わりに

作ってみて思ったのですが、採番に頼らず、自分の手でユニークにするほうが良い話ですね。このツールを使うのは最終手段な気がしました。（例：工数足りず、仕方なくツールで採番）

最後まで読んでいただき、ありがとうございました。
AWS EBで「Unhandled exception during build: invalid literal for int() with base 8: '493'」エラーの対処

## 概要
AWSのElastic Beanstalkで.ebextensionsを利用時にデプロイでエラー発生
（ちなみにPHPでLaravel）

```/var/log/cfn-init.log
2021-01-23 02:10:56,395 [ERROR] -----------------------BUILD FAILED!------------------------
2021-01-23 02:10:56,395 [ERROR] Unhandled exception during build: invalid literal for int() with base 8: '493'
Traceback (most recent call last):
  File "/opt/aws/bin/cfn-init", line 171, in <module>
    worklog.build(metadata, configSets)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 129, in build
    Contractor(metadata).build(configSets, self)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 530, in build
    self.run_config(config, worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 542, in run_config
    CloudFormationCarpenter(config, self._auth_config).build(worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 251, in build
    changes['files'] = FileTool().apply(self._config.files, self._auth_config)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/file_tool.py", line 103, in apply
    file_is_link = "mode" in attribs and stat.S_ISLNK(int(attribs["mode"], 8))
ValueError: invalid literal for int() with base 8: '493'
```

## 今回解消した方法
.ebextensions/hogehoge.configファイルの内容を修正（modeのパラメータを"で囲む）

```
files:
  "/hoge/fuga.txt":
    mode: 000755
```

```
files:
  "/hoge/fuga.txt":
    mode: "000755"
```
【UiPath】xamlファイルのデバッグを意識した実装

# はじめに

この投稿は「**UiPathでファイル単位でデバッグしながら開発する**」実装の紹介です。
内容的には、以下の投稿に少し似ています。
　[デバッグモードを用意してinvokeされるxaml内にダミーデータを用意する](
https://qiita.com/heppokofrontend/items/9cff3f11973517a56e73)

この記事は、`UiPath Friends もくもく会 2021年1月開催 2021-01-23（土）08:45 - 12:00` で書きました。

https://uipath-friends.doorkeeper.jp/events/116284

# 処理が大きくなる → xamlに切り出す

UiPathでは処理が大きくなってくると、UiPathStudioの `ワークフローとして抽出を使用する` 機能を使い、1つの処理ブロックをxamlファイルとして切り出します。
切り出すメリットは

- 1つのxamlファイルが小さくなり、可読性が良くなる。縦（スクロール）横（ネスト）も短くなり快適。変数も減る
- 処理を小さい単位で実装でき、テストが楽

等がありますが、デメリットとして

- ファイルが増える
- 引数があるとファイル単体のテストが面倒

があります。
今回の投稿の趣旨は、この「**引数があるとファイル単体のテストが面倒**」という課題を解決することです。

:camera_with_flash: 参考画像）右クリック「ワークフローとして抽出を使用する」で簡単に切り出せる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/a0dac2df-8281-dcb3-e891-f8c0e3ce8cfd.png)
 

# xamlに切り出すと、デバッグ実行が面倒

切り出した後で「ファイル単位でテスト」する場合は、Studio上部メニューの `ファイルをデバッグ`でテストすると、ファイルの処理だけ実行してくれます。
ただ、上述の通り、「**デバッグ実行時の引数は空になってしまう**」ため、「引数ありき」の処理はエラーになってしまいます。
そして、多くのワークフローは「引数を渡して、出力を受け取る」という形なので、`ファイルをデバッグ`でテストができません。

:camera_with_flash: 参考画像）上部メニュー「ファイルをデバッグ」をするとファイル内の処理だけ実行できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/def6b6d8-3b59-38dc-ea56-f436c8e5e06a.png)


# 実装しながらテストしたい

UiPathはローコード開発なので「短納期」です。なので素早く実装する必要があり、そのために
　・作る -> テストする -> 動かない -> 修正する -> テストする
という流れで、部品化して開発をしたい。その際に「ファイルをデバッグ」は使いたい。

この「ファイルデバッグ実行で、引数無しエラー」を回避する案として、

| No | 対応策 | 懸念 |
|:-----------:|:------------|:------------|
| 1| xamlを呼び出すTest.xamlを「別で」作成して引数を渡す| 別ファイルを作るのは面倒|
| 2| 実装中だけ 引数を「そっと」セットする処理を仕込む | 後で消すのが面倒|
| 3| xamlファイル内のデバッグフラグを「手で書き換えて」 引数を自動セットする| 修正するのが面倒|
| 4| Unitテストのフレームワークを「しっかり」使用する| そもそも実装中にパッとテストしたい|

があると思います。
私も 1 → 2 → 3 と流れてきて、他にお手軽な良い方法はないかな？と思っていました。


# 引数の設定ファイルの有無でデバッグ実行か判定

上記の対応策をミックスする案を考えました。

-  ファイルデバッグ実行したいフローは、ある程度の処理ブロックになっている
-  多くの場合、引数で設定ファイルを渡している
-  フロー内で設定ファイルを使わなくても、引数追加しても さほど害はない

と思い、**設定ファイル引数の値が空かどうか ＝ ファイルでバッグ実行か否か？**
と判断できると考えました。
そして、以下のようなフローを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/2d3d7dba-7f6a-7af3-59f8-09a537e35a50.png)


# 説明

処理の最初で「ファイルのデバッグ実行か？」を **「引数のin_config（設定ファイル）が空（Nothing）か？」**で判定し、デバッグ実行なら「テスト用の値を引数にセット」します。

ただし、この方法だと

　1）設定ファイルのパスを各xamlに書かないとダメ（パスが変わると修正が必要）
　2）意図せず、設定ファイルを空で渡してしまう処理があっても、正常に動いてしまう

という「デメリット」があります。

1に関しては「実装途中で設定ファイルのパスは変わる」ことは少ないので、大きな問題では無いとしました。（パス変更が面倒なら、パスを解決する共通フローを作っても良いかもしれません。）

2は、ちょっと嫌なので上記サンプルでは「デバッグ実行中です・・・」というアラートログを出力しています。

# 終わりに

以上、デバッグ実行を意識した実装の一例でした。もっといい方法もあるかもしれませんし、今後、UiPathがなにか機能を提供してくれるかもしれません。

今回の話以外でも「早く開発するポイント・手法」みたいなものはあると思いますので、折を見て別途、投稿したいと思います。