OmniAICreator/Qiita-1.07M huggingface dataset:
Db2:インデックスの差異を見つけたい

# 背景と状況
本番用データベースとテスト用データベースとでテーブルのインデックスが異なっていることはありませんか。インデックスが定義されていない、列の並びが違う、列が不足している等です。テーブルが300くらいあると調べるのが大変です。
# やりたいこと
異なるデータベースのインデックスを比較して違いを見つけたい。
IBM Db2 V11.5 Windwosで確認しています。
# やり方
Db2のシステムテーブルからインデックス情報を取得してテキストファイルに出力、テキスト比較ツールで比較します。

1. SQLを作るSQL
2. インデックス情報をファイルに出力
3. テキスト比較ツールで比較

# SQLを作るSQL
まずはテーブルの一覧を取得してテーブルごとにインデックス情報をファイルに出力するSQLを作成します。比較対象から外すテーブルをwhere条件で指定しています。

```sql:Index_SYSCAT.sql
SELECT 'EXPORT TO ' 
       || Rtrim(indname) 
       || '.txt of del ' 
       || 
' select INDNAME, COLNAME, COLORDER from  SYSCAT.INDEXCOLUSE where INDNAME = ''' 
|| Rtrim(indname) 
|| ''' order by COLSEQ ;' 
FROM   syscat.indexes 
WHERE  indschema = 'DB2ADMIN' 
       AND tabname not LIKE 'ADVISE_%' 
       AND tabname not LIKE 'EXPLAIN_%' 
       AND tabname not in  ('OBJECT_METRICS')
ORDER  BY tabname, 
          indname ;
```

以下のコマンドでSQLを作成します。Index_out.sqlというファイルが作成されます。
`db2 -txf Index_SYSCAT.sql -z Index_out.sql`

```sql:Index_out.sql
EXPORT TO MST_KEY.txt of del  select INDNAME, COLNAME, COLORDER from  SYSCAT.INDEXCOLUSE where INDNAME = 'MST_KEY' order by COLSEQ ;                                                                                                                                                                                                                                                  
EXPORT TO SND_KEY.txt of del  select INDNAME, COLNAME, COLORDER from  SYSCAT.INDEXCOLUSE where INDNAME = 'SND_KEY' order by COLSEQ ;

```
テーブルごとにインデックス情報をファイルにエクスポートするSQLです。

# インデックス情報をファイルに出力
以下のコマンドでファイルにインデックス情報をエクスポートします。
`db2 -tvf Index_out.sql`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/98945316-b85c-9086-6f3a-9bc8a3bae253.png)

# テキスト比較ツールで比較
フォルダーごとテキスト比較ツールで比較します。例では、[WinMerge](https://winmergejp.bitbucket.io/ "WinMergeのウェブサイトへ")を使って比較しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/bb1a60b5-188c-d2c8-d701-8c994718cf20.png)
ファイルをクリックして中身を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/68b5d472-ee22-8867-b747-1a797540d562.png)
インデックスごとに列名、昇順降順を比較することになります。
railsコンソール：実行環境の切替え

# はじめに

テストコードを書く際に、データベースに値を入れて検証したいと思ったが
コンソールがデフォルトだとdevelopment（開発環境）だと気づく。

テスト環境や本番環境など、別環境への切替方法を調べたので
記録として残しておく。

**■使用データベース： MySQL**

# 実行環境の種類

実行環境は３つ存在するので、状況に応じて切り替えする。

1. 開発環境 (development)
2. テスト環境 (test)
3. 本番環境 (production)



# コンソール

記述したコードが正しく動作しているかを確認するもの。

`rails c`コマンドで起動できる。

ただし、デフォルトは開発環境。

```
%　rails c

Running via Spring preloader in process 25986
Loading development environment (Rails 6.1.4)
irb(main):001:0> 
```




# 現況確認

コンソール画面で、`Rails.env`コマンドで実行すると
現在の実行環境が返答される。

```
irb(main):001:0> Rails.env

=> "development"
```



# 環境を切替え

コンソールから抜け出した後、linuxコマンドを打つ。

返答はないが、`export RAILS_ENV=test`コマンドで
実行環境がテスト環境に変わっている。

```
% export RAILS_ENV=test
```

もし本番環境に変更したい場合は
`export RAILS_ENV=production`とする。



# コンソールを起動

再び`rails c`コマンドを実行する。

```
%　rails c

Running via Spring preloader in process 26085
Loading test environment (Rails 6.1.4)
irb(main):001:0> 
```

すると、表示されている環境が
`development` → `test`に変更されているのが分かる。



# データベースへ値の入力

Userモデルに、新規ユーザーを作成してみる。

ちゃんと、データが作成されている様子。

```
irb(main):001:0>　User.create(name: "Test", email: "test@mail.com", password: "1122334455")

  TRANSACTION (0.3ms)  BEGIN
  User Exists? (0.4ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'test@mail.com' LIMIT 1
  User Create (0.4ms)  INSERT INTO `users` (`name`, `email`, `created_at`, `updated_at`, `password_digest`, `activation_digest`) VALUES ('Test', 'test@mail.com', '2021-07-20 04:33:44.655390', '2021-07-20 04:33:44.655390', '$2a$04$ScRQSjFBEzENKlmFvdh7jug0nhwLmMtjFwH2GLdapCbiEab5pk24O', '$2a$04$PYLIqUcQuXZKmv2vcq71s.FzWgPmjTBk35.Rcf4HonQYYFm1qoBCC')
  TRANSACTION (0.6ms)  COMMIT
```





# MySQLで確認

showコマンドで存在するテーブルを確認後、
select文で表示カラムをnameとemailに設定して表示させる。

```
mysql> show tables;

+--------------------------------+
| Tables_in_＜アプリ名＞_test       |
+--------------------------------+
| articles                       |
| relationships                  |
| users                          |
+--------------------------------+


mysql> select name, email from users;

+------+-------------------+
| name | email             |
+------+-------------------+
| Test | test@mail.com     |
+------+-------------------+
```

ちゃんと、ユーザーが作成されているので上手くいっているはず。



# 番外：DBに保存せずに検証したい

下記コマンドなら、コンソール終了後にロールバックされるので
DB上にデータが残らない。

検証はしたいが、データは残したくない場合に便利。

```
%　rails c --sandbox

Running via Spring preloader in process 26196
Loading development environment in sandbox (Rails 6.1.4)
Any modifications you make will be rolled back on exit
```

# Docker環境でコンソールを立ち上げる

先に、docker-composeコマンドで複数コンテナを立ち上げて
同じ様にコンソールを起動させる。

```zsh:ターミナル 
# 複数コンテナをバックグラウンドで立ち上げる
% docker-compose up -d

# 起動中コンテナの名称を確認する
% docker-compose ps

# 確認したwebサーバーのコンテナにログインする
% docker container exec -it webサーバーのコンテナ名 bash

# コンテナ内でsandboxを起動する
root@1234567890:/# rails c --sandbox
↑　プロンプトが変わる

Running via Spring preloader in process 91
Loading development environment in sandbox (Rails 6.1.4)
Any modifications you make will be rolled back on exit
irb: warn: can't alias context from irb_context.

```



# 終わりに

簡単な内容ではあるが、まとめてみた。

今後も学習記録を残す。

以上。
2.17(難) 期待値の演算

## 1.方針

「連続関数が増加関数」とは，「微分して0以上」である．また指数が連なっていて嫌なので対数を取る．式変形が難しい．

## 1.答案

A(t)の対数を取って

```math
h(t)=\log A(t)=\frac{1}{t}\log\mathbb{E}_{X\sim f_X}[X^t]
```

と置く．h(t)がtの増加関数であるためには，h'(t)=>0であれば良い．

```math
h'(t)=-\frac{1}{t^2}\log\mathbb{E}_{X\sim f_X}[X^t]+\frac{1}{t}\frac{1}{\mathbb{E}_{X\sim f_X}[X^t]}\mathbb{E}_{X\sim f_X}[X^t\log X]
```

であるから，

```math
\begin{align}
h'(t)\geq0&\Leftrightarrow \frac{1}{t}\frac{\mathbb{E}_{X\sim f_X}[X^t\log X]}{\mathbb{E}_{X\sim f_X}[X^t]}\geq \frac{1}{t^2}\log\mathbb{E}_{X\sim f_X}[X^t]\\
&\Leftrightarrow t\mathbb{E}_{X\sim f_X}[X^t\log X]\geq \mathbb{E}_{X\sim f_X}[X^t]\log\mathbb{E}_{X\sim f_X}[X^t]\\
&\Leftrightarrow \mathbb{E}_{X\sim f_X}[X^t\log X^t]\geq\mathbb{E}_{X\sim f_X}[X^t]\log\mathbb{E}_{X\sim f_X}[X^t]\tag{1}
\end{align}
```

ここで，Y=X^tと置くと，(1)式は

```math
\mathbb{E}_{X\sim f_X}[Y\log Y]\geq \mathbb{E}_{X\sim f_Y}[Y]\log\mathbb{E}_{X\sim f_X}[Y]\tag{2}
```

と書ける．さて，

```math
g(y)=y\log y
```

なる関数を考えると，

```math
g''(y)=\frac{1}{y}>0,\ \ \forall y>0
```

よりgは凸関数であるから，Jensenの不等式により(2)式は成立する．

## 2.方針

1.を利用する．H,Mはそれぞれt=-1,1をA(t)に代入したものなので，Aは増加関数よりH<=Mである．あとはGがt=0を代入したものであることを示す．

## 2.答案

```math
\begin{align}
\lim_{t\rightarrow 0}h(t)&= \lim_{t\rightarrow0}\frac{\log\mathbb{E}_{X\sim f_X}[X^t]}{t}\\
&= \lim_{t\rightarrow0}\frac{\mathbb{E}[X^t\log X]}{\mathbb{E}[X^t]}\\
&= \mathbb{E}[\log X]
\end{align}
```

なので，

```math
\begin{align}
\lim_{t\rightarrow0}(\mathbb{E}_{X\sim f_X}[X^t])^{1/t}&= \lim_{t\rightarrow0}\exp(h(t))\\
&= \exp(\mathbb{E}_{X\sim f_X}[\log X])\\
&= G
\end{align}
```

であるから，A(t)は増加関数より，H<=G<=Mが成り立つ．

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
【Kubernetes】podのレプリカを作る(手動でスケーリングする方法)　no.4

![名称未設定のデザイン (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/f9737dec-ff20-602c-ee7b-502dfdbb2cac.png)


こんにちは。まゆみです。

Kubernetes についての記事をシリーズで書いています

前回と前々回の記事で、

>①Podsを作り
②そのPodsに外部からアクセスする方法

を書いてきました。

次にやりたい事と言えば、あなたが作ったPod(Container)に<font color="Red">外部からのアクセスが増えた時、Podを増やしたい</font>ですよね。

![172.17.0.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/975c415a-39db-2713-8b13-2335ce582133.png)


そのような時、どのようにKubernetesを使ったらいいのかを今回の記事にまとめていこうと思います


#kubectl scaleでアップスケーリングする

```
kubectl scale <オブジェクトの種類>/<オブジェクトの名前> --replicas=<増やしたい数>
```
結果は下のようになります

![2021-07-20_13-27-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7bbc9640-a722-3c28-ea84-fc23c2a9fff3.png)


#kubectl scale でダウンスケーリングする

逆に、トラフィックが減ったのでオブジェクトの数を減らしたい時もkubectl scale を使います

減らしたい時は--replicas=に書く数字を今より小さいものに書き換えます。

![2021-07-20_13-35-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/2aa6d976-f7b3-580e-0a8d-4f44b3e58f53.png)

#まとめ
今回の記事では、『手動』でスケーリングする方法を書かせていただきました。

また記事を改めて、『自動で』スケーリングする方法も書いていこうと思います。
Sidekiqが死んだままサービス運用をしてしまった際の復旧手順について

### 1. 現状蓄えられているQueueを確認
```ruby
> stats = Sidekiq::Stats.new
> stats.queues
→ { "default" => 100, "mailers" => 400 }
```
keyはQueueの名前、valueはQueue内のJob数です。

### 2. すべてのJobを削除
```ruby
stats.queues.keys.each do |queue_name|
  queue = Sidekiq::Queue.new(queue_name)
  queue.each do |job|
    # 特定のjobだけを消したい場合はなんかしらのガード文を書く
    # next unless job.klass == "SampleWorker"
    job.delete
  end
end
```
### 3. Queueが消えているかを確認
```ruby
> stats.queues
→ { "default" => 0, "mailers" => 0 }
```

### 4. 再起動

### 5. チームメンバーへ謝罪

---
参考
https://qiita.com/dany1468/items/20cf0dfc40d589993bda
https://www.it-swarm-ja.com/ja/ruby-on-rails/%E3%82%AD%E3%83%A5%E3%83%BC%E5%86%85%E3%81%AE%E5%86%85%E5%AE%B9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%97%E3%80%81sidekiq%E3%81%A7%E3%82%AD%E3%83%A5%E3%83%BC%E3%82%92%E3%82%AF%E3%83%AA%E3%82%A2%E3%81%99%E3%82%8B%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/1069431510/
Content Builder の基本 ⇒ コンテンツ戦略に合わせたアセットの整理

１．Content Builder のフォルダーを整理する最適な方法はどれですか?
２．フィルターオプションには何がありますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/38615782-6e3b-f1c1-5b60-425bfc505c98.png)
独学プログラマーのまとめ　その5

#初めに
学んだことがどんどん活用されているので復習になっている。


###6章　文字列操作

- 理論的には、理論と実践に違いはない。しかし、実践的には、ある。
    - 現在、絶賛感じているところである。

- 3重クォート文字列
    - 文字列を複数行書きたい場合、クォートを3つ使う三重クォートで書ける。

```python
  
print("""
line one
line two
line three

""")
```
> line one
line two
line three

- インデックス
    - 文字列はイテラブルであり、インデックスを指定して取り出せる。
    - 文字列の最初のインデックスは0
    - マイナスインデックスも使える。

- 文字列はイミュータブル
    - 文字列は足し算やかけ算の演算子を使って新しい文字列を作れる
    - コンテナで勉強した大文字小文字の操作が可能
    - 文字列の最初の文字を大文字で書くことをキャピタライズという。
 
```python
 "four score and...".capitalize()
```
> 'Four score and...'

- 書式化
    - formatメソッドで文字列の一部をあとで穴埋めできる。
    - プログラムの利用者が入力した文字を使って文字列を組み立てる時に便利

```python
what = input("何が:")
when = input("いつ:")
where = input("どこで:")
do = input("どうした:")

r = """ {} は{} に {} で{}。
    """.format(what,
               when,
               where,
               do)

print(r)
```
> '何が:'
'いつ:'
'どこで:'
'どうした:'

 
- 分割、結合、空白除去
    - それぞれsplit、join、stripメソッドで文字列を編集できる。
- 置換、文字探し、包含
    - それぞれreplace、index、inメソッド
- エスケープ文字
    - 構文エラーなどを起こさないための文字の別の解釈の記号pythonではバックスラッシュ。\nだと改行ができる。
- スライス
    - 繰り返し可能なオブジェクトの一部を取り出して新しく生成したイテラブルなオブジェクトを返す。
 

# まとめ
何に応用するか考えながら学ぶ。
input type="date"で昨日以前を選択できないようにする方法

#概要
`<input type="date>"`を用いることで、簡単にカレンダーによる選択を実装できる。
昨日以前を選択できないようにしたかったが、検索しても中々ヒットしなかった。
個人的な備忘録の意味でも、方法と流れをまとめてみた

▼使用スキル
HTML、Vue.js

#手順①
HTML

```html
<input type="date" min="2021-07-18">
```

HTMLにinput type="date"を設置。min='XXXX-XX-XX'を指定することで、'XXXX-XX-XX'がより前の日付に関しては、選択できなくなる。例えば、2021-07-18とすれば、7/17以前の日付は、選択できないようになる。
[デモコード](https://jsfiddle.net/zxyaukLh/)
[詳しくは公式のリファレンスをご確認ください。](https://www.google.co.jp/)

#手順➁
ユーザーがサービスを利用する日にちによって、'XXXX-XX-XX'の中身を変更するようにしたい。つまり、動的に管理したい。本記事では、Vue.jsにて実装していく。

HTML

```html
<div id="app">
 <input type="date" v-bind:min="today">
</div>
```

Vue.js

```javascript
var vue = new Vue ({
  el: '#app',
  data: {
    today:''
   },
  created: function(){
    this.today= new Date();
  }
 })
```
[ここまでのデモはこちら](https://jsfiddle.net/zxyaukLh/1/)
###解説
`this.today= new Date();`により、今日の日付を取得している。今日が7/18ならば、minには7/18が入る。しかし、このままでは正常に動作しない。上記のデモは確認してみて欲しい。
検証ツールを確認すると分かりやすいのだが、
この時点では、`min=Tue Jul 20 2021 12:56:01 GMT+0900 (日本標準時)`とminに入っている形式がおかしい。**minが正常に動作するためには、`min='XXXX-XX-XX'`という形式になっている必要がある。**
todayの形式を'XXXX-XX-XX'に変更する記述は以下になる。

#手順➂
Vue.js

```javascript
  created: function(){
    let todaySet = new Date();
    let YYYY = todaySet.getFullYear();
    let MM = ('00' + (todaySet.getMonth()+1)).slice(-2);
    let DD = ('00' + todaySet.getDate()).slice(-2);
    this.today = YYYY + '-' + MM + '-' + DD
  },
```

###解説
恐縮ではあるが、`getFullYear()`等の詳しい解説は割愛させていただく。別途、公式のリファレンスや、他Qiita記事をご覧願いたい。

一点解説しておくと、下記コードの`'00'`及び`slice(-2)`がポイントである。下記部分がない場合、例えば今日が7/7だとすると、todayは2021-7-7という形式になる。下記部分があることで、2todayは2021-07-07となる。minが正常に動作するのは、2021-07-07の方だ。

```javascript
 let MM = ('00' + (todaySet.getMonth()+1)).slice(-2);
 let DD = ('00' + todaySet.getDate()).slice(-2);
```
完成形はこちらでご確認いただきたい。
https://jsfiddle.net/zxyaukLh/2/

###最後に
分かりにくい点があったら大変申し訳ないが、以上とさせていただく。
【Terraform】外部ファイルで変数を使用

Lambdaをデプロイする際などスクリプト内で変数を使用したい場合などに、template_fileとlocal_fileを組み合わせる事でterraformのvariables内で変数を定義する

使用するData SourcesとResourceは以下の通り
- [template_file | Data Sources | hashicorp/template | Terraform Registry](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file)
- [local_file | Resources | hashicorp/local | Terraform Registry](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)

## ディレクトリ構造
```
.
├── template.py
├── variables.tf
└── lambda
    └── example #変数に値をセットした後のファイルの出力先
```

## ファイル内容
```template.py
...
        Instances={
            'InstanceGroups': [
                {
                    'Name': 'Master nodes',
                    'Market': 'SPOT',
                    'InstanceRole': 'MASTER',
                    'InstanceType': '${instance_type}',
                    'InstanceCount': ${instance_count_master},
...
```

```variables.tf
# template.pyを読み込み、変数に値を渡す
data "template_file" "example" {
  template = "${file("${path.module}/template.py")}"
  vars = {
    instance_size         = "c4.large"
    instance_count_master = "1"
    instance_count_core   = "2"
    
  }
}

# template_fileをファイルに出力
resource "local_file" "example" {
  content  = "${data.template_file.example.rendered}"
  filename = "${path.module}/lambda/example/lambda_function.py"
}
```
### 使用方法
通常のTerraformと同じく、terraform applyする。teffarorm destroyする事で生成されたファイルが削除される

```
> terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # local_file.example will be created
  + resource "local_file" "example" {
      + content              = <<-EOT
...省略
Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:　　# yes入力後Enter押下

...省略
local_file.example: Creating...
local_file.example: Creation complete after 0s [id=b0e33cd03e3451033468b33361454f71cb2d8c4b]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
結果

``` ./lambda/example/lambda_function.py
...
        Instances={
            'InstanceGroups': [
                {
                    'Name': 'Master nodes',
                    'Market': 'SPOT',
                    'InstanceRole': 'MASTER',
                    'InstanceType': 'c4.large',
                    'InstanceCount': 1
...
```
nuxtで作成したSPAをs3ホスティングし、cloudfront + lambda@edgeでbasic認証をかけて配信する

タイトルの通り。

# nuxt

```
% npx create-nuxt-app app
```

SPAなので以下のあたりの設定になります。
他はお好みで。僕はtypescriptを使います。typescriptしか勝たん。

```
> ? Rendering mode: Single Page App
> ? Deployment target: Static (Static/JAMStack hosting)
```

```
% cd app
% npm run build
% npm run generate
```

generateを実行すると、デフォルトだと `dist/` とその中にファイル群が生成されます。

# s3

適当にバケットを作成でOK
アクセスも全てプライベートでOK
静的ウェブサイトホスティングも無効のままでOK

`dist/` の中身を直下に全てアップします。

# cloudfront

ディストリビューションの作成

- Origin domain: 先ほど作ったs3バケット
- s3ののアクセス: OAIを新規に作成( `Create new OAI` )してそれを利用。バケットポリシーのアップデートをする。（以下の画像の状態）

![スクリーンショット 2021-07-20 12.13.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213486/2870c232-7d5f-d54b-55ac-0dbd55435808.png)

- Viewer protocol policy: `Redirect HTTP to HTTPS`
- Allowed HTTP methods: `GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE`
- その他は全てそのままでOK

# lambda@edge

nuxtのルーティング用とbasic認証用で2つ用意する

参考: [Lambda@Edge イベント構造](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-request)

- ビューアーリクエスト
    - basic認証用
    - 参考: [CloudFront Lambda@Edge with Python 3.8 で Basic 認証を実現する](https://qiita.com/t-kigi/items/582b36e76b35c278eb96)
    - 参考: [Amazon CloudFrontとAWS Lambda@EdgeでSPAのBasic認証をやってみる](https://dev.classmethod.jp/articles/cloudfront-lambdaedge-basic-spa/)
- オリジンリクエスト
    - nuxtアプリケーションでのルーティング用
    - リクエストを受けてパスを書き換えるような処理
    - 参考: [nuxt generate + S3 + CloudFront + Lambda Edge で静的サイト構築＆ハマりポイントと解決法 / Lambda Edge でオリジンパスのハンドリングを設定する](https://qiita.com/GussieTech/items/3ae77dbcb1e79222a9bc#lambda-edge-%E3%81%A7%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E3%83%91%E3%82%B9%E3%81%AE%E3%83%8F%E3%83%B3%E3%83%89%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)
    - 参考URLをもとに、python3.8に書き換えたものが以下のコードとなっている

```python
import re

def lambda_handler(event, context):
    suffix = '/index.html'
    append_to_dirs = 'index.html'

    # e.g.) "/some/page" but not "/", "/some/" or "/some.jpg"
    regex_suffixless = r'^/(?=.+)(?!.+\..+$)(?!.*/$).*$'

    # e.g. "/some/" or "/some/page/" but not root "/"
    regex_trailing_slash = r'^.+/$'

    request = event["Records"][0]["cf"]["request"]
    uri = request["uri"]

    if suffix and re.match(regex_suffixless, uri):
        request["uri"] = uri + suffix
        return request

    if append_to_dirs and re.match(regex_trailing_slash, uri):
        request["uri"] = uri + append_to_dirs
        return request

    return request
```

これでSPAにbasic認証をかけて周りに共有することができた。
（今回はIP制限かけられない縛りでこの方法をとってみた）
IBM Verifyアプリに表示されるサービス名を変更する

# はじめに
IBM Security Verifyの多要素認証要素としてIBM Verifyアプリが提供されています。

- Android：
    - https://play.google.com/store/apps/details?id=com.ibm.security.verifyapp&hl=ja&gl=US
- iOS：
    - https://apps.apple.com/jp/app/ibm-verify/id1162190392

IBM Security Verifyの画面で、IBM Verifyアプリを登録すると、サービス名として「IBM Security Verify」が表示されます。
このサービス名を変更する方法についてご紹介します。

![ibmverifyapp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/4e053014-d9e5-d6ec-45a1-c732348eba52.png)

# 登録プロファイルの変更

サービス名は、登録プロファイル内に定義されています。
管理者画面で「セキュリティ」タブ-「登録プロファイル」を選択し、プロファイルを編集します。

![ibmverifyapp (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e502bced-4bdb-3827-f307-0325932a60eb.png)

サービス名に記載の「IBM Security Verify」がIBM Verifyアプリに表示される名称となります。
![ibmverifyapp (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/f4b7d806-2bb7-d791-eb3e-3ad330a2137f.png)

サービス名を「cloud Bank」に変更して保存します。
![ibmverifyapp (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/6db6eb2c-08b9-de0f-7e8b-14838dc0d4a4.png)

変更した状態で、IBM Verifyアプリをセットアップすると、サービス名が「cloud Bank」と表示されるようになります。
![ibmverifyapp (4).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e328055e-36ec-87b5-2d98-7fd393d59b6d.png)


# 最後に
IBM Verifyアプリに表示されるサービス名の変更方法について紹介しました。
cudaをubuntuにインストールした際のメモ


# ダウンロードするCUDA Toolkitのバージョンを知るための自分の環境の確認(GPU、CPU、ubuntu、gccの確認)
``` bash
$ lspci | grep NVIDIA
01:00.0 VGA compatible controller: NVIDIA Corporation GP106 [GeForce GTX 1060 6GB] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GP106 High Definition Audio Controller (rev a1)
```


``` bash
$ uname -m && cat /etc/*release
x86_64
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

``` bash
$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

# CUDA Toolkit のダウンロード（上で得た情報を元に選択していく）
https://developer.nvidia.com/cuda-downloads


# インストール実行
``` bash
$ sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.0-470.42.01-1_amd64.deb 
$ sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pub 
$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
$ sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ sudo apt-get update
$ sudo apt-get install cuda
$ sudo apt-get install nvidia-gds 
```

全部下記ページに書いていますが、\<distro\>、\<version\>、\<architecture\>に何を入れれば良いかよくわからずつまづきました。

https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation

# サンプル実行
動作確認のためにサンプルを実行してみます。
ウィンドウが立ち上がって緑色の画面が出ると成功です。この緑色をドラッグすると動いて楽しいです。

``` bash
$ cd ~/NVIDIA_CUDA-11.4_Samples/5_Simulations/fluidsGL
$ make
$ ./fluidsGL
```
Next.js + Ant Designでページネーションできるテーブルを実装する方法

この投稿では、Next.jsとAnt Designでページネーションできるテーブルを実装する方法を説明します。使用する言語はTypeScriptです。

できあがりの様子は次の動画のようになります:

<iframe width="560" height="315" src="https://www.youtube.com/embed/nNSY8ip3eJ0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

ページネーションのUIをクリックすると、データがロードされたり、URLの`page`パラメータを直接指定してアクセスした場合に、該当ページが表示されたりするようにします。

このチュートリアルは下記の続きです。

https://qiita.com/suin/items/2a8a51994daf48f3b2e9

このチュートリアルで作ったものの完成形コードは[GitHubにあります](https://github.com/suin/nextjs-ant-design-typescript/tree/2b63d8974fc38498488f0b20c75001ffaef60f68)。

完成形のデモアプリは[Vercelにホスティングしてある](https://nextjs-ant-design-typescript-6g9ktfnnt-suin.vercel.app/users)ので、実際に操作してみたい方はそちらをご覧ください。


## Next.js + Ant Designでページネーションできるテーブルを実装する方法

Ant Designの`<Table>`コンポーネントを用います。

https://ant.design/components/table/

いきなり完成形ですが、pages/users.tsxの中身は次のようにします。

```tsx:pages/users.tsx
import { Avatar, PaginationProps, Table } from "antd";
import { TablePaginationConfig } from "antd/es/table/interface";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";

const { Column } = Table;

export default function Users() {
  const router = useRouter();
  const [data, setData] = useState<ReadonlyArray<any>>([]);
  const [loading, setLoading] = useState(true);
  const [pagination, setPagination] = useState<PaginationProps>();

  // URLのpageクエリーパラメータをもとに、APIから所定のページを取ってくるようにします。
  // pageパラメータが変化するごとに発動します。
  useEffect(
    () => fetchUsers((router.query.page as any) ?? 0),
    [router.query.page]
  );

  // これは、ページネーションのUIをクリックしたときに発動します。
  function handleChange({ current = 0 }: TablePaginationConfig) {
    router.push({ pathname: router.pathname, query: { page: current } });
  }

  // ユーザーのダミーデータを提供してくれるAPI、ReqResからデータをお借りします。
  function fetchUsers(page: number = 1) {
    setLoading(true);
    fetch(`https://reqres.in/api/users?page=${page}`)
      .then((res) => res.json())
      .then((data) => {
        setData(data.data);
        setPagination({
          total: data.total,
          pageSize: data.per_page,
          current: data.page,
        });
        setLoading(false);
      });
  }

  return (
    <Table
      rowKey="id"
      dataSource={data}
      loading={loading}
      pagination={pagination}
      onChange={handleChange}
    >
      <Column title="ID" dataIndex="id" />
      <Column
        title="Photo"
        dataIndex="avatar"
        render={(x) => <Avatar src={x} />}
      />
      <Column title="First Name" dataIndex="first_name" />
      <Column title="Last Name" dataIndex="last_name" />
      <Column title="Email" dataIndex="email" />
    </Table>
  );
}
```

これを実装すると冒頭の動画のように、ページネーションのUIを操作したときにデータがロードされたり、URLに`page`パラメータを指定して直接アクセスしたときに該当のページが表示されるようになります。
DigiSpark macでの書き込み方法(備忘録)


macbook pro 13inch(2020 late)
MacOS Catalina 10.15.7
Arduino IDE Ver 2.0.0-beta-4にて

Driverは入れた気はするが、それでも書き込みができずにもんもんとしてたが・・
いまのところ、以下方法でなんとかなった

Preference-Additional boards manager URLs

```
http://digistump.com/package_digistump_index.json
```

BOARD MANAGERで、
digistump avr boardsで検索
Disistump AVR　Boards by Digistamp
をInstall

Tools-Board 
 Digistump AVR Boards-Digispark(Default - 16.5mhz)

Programmer-Micronucleus


```
// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(0, OUTPUT); //LED on Model B
  pinMode(1, OUTPUT); //LED on Model A   
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(0, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(1, HIGH);
  delay(200);               // wait for a second
  digitalWrite(0, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(1, LOW); 
  delay(200);               // wait for a second
  digitalWrite(0, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(1, HIGH);
  delay(500);               // wait for a second
  digitalWrite(0, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(1, LOW); 
  delay(1000);  

}
```

DigSparkをUSBから外して、書き込みボタンを押すと同士にUSBに差す
以下のようなコンパイル・書き込みログが表示されれて、DigSpark基板上のLEDが点滅すればOK

```
Sketch uses 774 bytes (12%) of program storage space. Maximum is 6012 bytes.
Global variables use 9 bytes of dynamic memory.

--------------------------
Compilation complete.
Running Digispark Uploader...
Plug in device now... (will timeout in 60 seconds)
> Please plug in the device ... 
> Press CTRL+C to terminate the program.
> Device is found!
connecting: 16% complete
connecting: 22% complete
connecting: 28% complete
connecting: 33% complete
> Device has firmware version 1.6
> Available space for user applications: 6012 bytes
> Suggested sleep time between sending pages: 8ms
> Whole page count: 94  page size: 64
> Erase function sleep duration: 752ms
parsing: 50% complete
> Erasing the memory ...
erasing: 55% complete
erasing: 60% complete
erasing: 65% complete
> Starting to upload ...
writing: 70% complete
writing: 75% complete
writing: 80% complete
> Starting the user app ...
running: 100% complete
>> Micronucleus done. Thank you!

--------------------------
upload complete.
```




-- 番外


```
Compilation error: Error: 2 UNKNOWN: fork/exec /bin/avr-g++: no such file or directory
```

が出たときは
BOARD MANAGERで、
digistump avr boardsで検索

Disistump AVR　Boards by Digistamp
をUninstallし、ArduinoIDEを再起動したら、再度Install
で一応解決・・
Databricks（Spark）にてPython（PySpark）・SQL・Scalaにより利用するSparkデータベースを変更する方法

## 概要
Databricks（Spark）にて、Python（PySpark）・SQL・Scalaのそれぞれの言語別に利用するSparkデータベースを変更する方法を共有します。

## 手順
### 事前準備

```python
# 現在のデータベースを`default`へ初期化
setCurrentDatabase = spark.catalog.setCurrentDatabase('default')
currentDatabase = spark.catalog.currentDatabase()
print(currentDatabase)
```

```sql
%sql
--切り替え対象のデータベースを作成
create database if not exists qiita;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/cf11f5e2-4041-3022-a960-cbd0c9e07364.png)

### Python（Pyspark）で実施する方法

```python
%python

database = 'qiita'
setCurrentDatabase = spark.catalog.setCurrentDatabase(database)


currentDatabase = spark.catalog.currentDatabase()
print(currentDatabase)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ab953d3e-0ba6-d51c-64bc-c51aa11a66ee.png)


### SQLで実施する方法

```SQL
%sql

use qiita;

select current_database() 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/92bbd9ef-bd67-afb8-4643-5a214a84bfc7.png)


### Scalaで実施する方法

```Scala
%scala
val database = "qiita"
val setCurrentDatabase = spark.catalog.setCurrentDatabase(database)


val currentDatabase = spark.catalog.currentDatabase
println(currentDatabase)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d59791a9-ef3b-2453-31be-10e8520d0931.png)

## 関連記事

- [External metastore にインポートする table DDLs を作成する方法-Azure Databricks - Workspace | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/databricks/kb/metastore/create-table-ddl-for-metastore)
俺のSQL

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E4%BF%BA%E3%81%AESQL/)をご覧ください😀

よく書くけど毎回ググってる気がするMySQLのクエリーメモ


## 前日から直近30日のデータを抽出

カラムがdatetime(時分秒持ってる)のとき

```sql
WHERE
DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) <= updated_at
AND updated_at < CURRENT_DATE
```

- CURRENT_DATE は当日のdate（YYYY-MM-DD）　を取得する関数
- dateとdatetimeの比較メモ
    -  `2021-07-20 23:59:59 < 2021-07-21`
    -  `2021-07-20 <= 2021-07-20 00:00:00`

## 先月1ヶ月分のデータを抽出

`前々月の1日 <= データ < 前月の1日` で取得してあげる

```sql
WHERE
updated_at >= DATE_FORMAT(ADDDATE(CURDATE(), INTERVAL -1 MONTH), '%Y-%m-01'))
AND updated_at < DATE_FORMAT(CURDATE(), '%Y-%m-01')
```

## 列名に変数を使いたい（列名に現在日を表示したい）

こんなことしたい。

| name | 2021-09-13_count |
|:-----------|------------:|
| hoge       | 1        |
| fuga       | 100        |


PREPARE構文使わないとできない？もっと簡単にできる方法あれば知りたい。。。

```sql
SET @DATE=curdate();
set @query = concat('select 1 as `', @DATE, '_count`;');
prepare stmt from @query;
execute stmt;
```

## 重複が多いデータを調べる

```sql
SELECT count(*),column_name
FROM table_name
where column_name is not null
GROUP BY column_name
HAVING count(*)>1
ORDER BY count(*) DESC
```

## 文字数が長いデータを調べる

```sql
SELECT *,CHAR_LENGTH(column_name) as STR_LEN FROM table_name ORDER BY STR_LEN DESC;
```
LINQPadでODataのサービスに対して検索して、ODataクエリを確認する

# はじめに
Office 365のAPIの動作確認をするために、ODataクエリの動作確認を簡単にできるものが無いかな？と思いLINQPadのOData ドライバーについて調査しました。

残念ながらOIDCやAOuthなどのクレームベースの認証には対応していないので、Outlookなどの認証が必要なODataエンドポイントに対して利用する場合は、前段で認証を処理してくれるCDATAのアダプターなどを導入する必要がありそうです。

ただ、認証が必要ないか、後述するいくつかの認証方式で良い場合はそのまま利用できそうなので導入方法を書いておきます。

# 導入

コネクション作成時に表示される`View more drivers`から新しいドライバーの追加を行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/f37c8519-8b02-c340-0fbf-3a9162119180.png)
ドライバーの検索画面で`odata`などのキーワードで検索し、`OData v4 Driver`を選択して`install`ボタンからインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/79b5c4de-0a25-951a-2e4f-156e639c31b7.png)
正常にインストールされると、コネクションの一覧に先ほどインストールした`Odata v4 Connection`が表示されるので、このドライバーを使って接続を作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/c5b03821-9822-9244-d4dc-1caabfc58c60.png)

# コネクションの作成

odata.orgで提供されているサンプルサービスを参照してみます。LinqPadはこのURLをベースにmetadataを探しに行くようですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/f3e52bf3-e477-c10d-7633-e7e6cef75d2a.png)
現在は`Accept invalid certificates`にチェックをしないと下記のようにエラーになってしまうようなので注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/79790b21-12ad-8047-4c84-7c71812733c3.png)

接続作成時にはLog ondetailsにある次の認証方式のクエリだけがサポートされています。
- No authentication
- Windows authentication
- Basic authentication
- Client certificate authentication
OAuthでの認証ができないか？といった内容がLINQPadのフォーラムに挙がっていましたが、現在のところサポートされていないようです。
https://forum.linqpad.net/discussion/113/odata-service-and-oauth

コネクションが登録できると、コネクションツリーにプロパティーが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/0534afa2-c2a9-a7d1-879b-462ff613b1cb.png)

# クエリの実行

クエリを実行するとResultsタブに結果が表示され、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/16734fe2-3728-7dcc-8d38-b02cfd804cbb.png)
SQLタブにODataのクエリが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/82324fcb-d8dc-c4c5-d9ca-2832657f2583.png)

C#のコードでフィルタしたりソートすると、ODataクエリが変更され
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/2aaf6bcb-308f-5d66-1c8a-efd2408d98ea.png)
結果がその通りに表示されることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/b4bd05a1-bd1d-ec6f-0a82-43949f084844.png)

ただし、ODataのクエリに変換できないような式はエラーになってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36535/a6eb32a2-6661-117d-5541-f16c7244114f.png)
BigQuery Reservationsの Flex Slotsでリスク軽減とコストのバランスについて考えてみた

## 概要 - BigQueryの料金体系について
BigQueryのクエリは、初期状態では「オンデマンド」状態での実行となっている。大まかな特徴は以下の通り。

- 実際に実行したクエリに応じて課金が発生する
- 原則的な上限スロット数(2000)を条件付きでバーストすることができる
    - 実行リージョン全体でのスロット数にゆとりがある場合に適用される
    - 逆にリージョンのスロットの状況によっては2000未満しか使えないことがある

低コストでBigQueryの恩恵を受けられる料金体系だが、スロットの確保も都度行われるという点に注意が必要。複雑度が著しく高い集計が集中している場合、クエリ実行時にあまりスロットが確保できなくなるためだ。平時こういった事象が頻発することはないが、人気のあるリージョンや、Googleで元々確保しているリソースが少ないリージョン(例えば、USやEUと比べてAsia-Northeastは後者にあたるらしい)で需要の高まる時期にはスロットの枯渇が起こるということも考えられる。

## 今回検討したこと - Flex Slotsの活用

上記のスロット枯渇は、BigQuery Reservations([https://cloud.google.com/bigquery/docs/reservations-intro?hl=ja](https://cloud.google.com/bigquery/docs/reservations-intro?hl=ja))の適用で解決できる。あらかじめスロットを確保することで、リージョン全体のスロット枯渇の影響を受けなくなる。

しかし、現在想定している環境は以下のとおりである。

- 定期処理をオンデマンドのまま実行している環境
- 安定させたいのは1日の中で特定時間帯(朝方)のクエリのみ

この条件でいきなり年間コミットメント・月間コミットメントといった定額課金に移行するのは若干金銭面のハードルが高い。スロットの枯渇は毎月・毎四半期確定で起こるというものではない。スロット枯渇に対応するコストを定額課金によるコストが著しく上回るのは避けたい。

そこで今回は、基本はオンデマンドのまま、リスクの高い時期のみFlex Slotsを必要数購入してそちらで実行する方法をとることにした。需要が上がるタイミングに合わせてFlex Slotsを活用することについては以下で言及されている。今回は、基底部分に定額制のコミットメントを置かず、Flex Slotsのみを単独で使用する。

[https://cloud.google.com/blog/ja/products/data-analytics/introducing-bigquery-flex-slots](https://cloud.google.com/blog/ja/products/data-analytics/introducing-bigquery-flex-slots)

## やり方

以下を参考に、重要な日次処理の実行前にスロット購入～割り当ての処理を、終了後に割り当て削除～スロット購入取りやめの処理を入れる。

[https://cloud.google.com/bigquery/docs/reservations-tasks?hl=ja#bq](https://cloud.google.com/bigquery/docs/reservations-tasks?hl=ja#bq)

## 注意点

### いきなり使用頻度の高いプロジェクトに適用しない

理由として、以下の2点がある。

- 割り当てはプロジェクト単位のため、同じプロジェクトで定期実行の処理以外にユーザがクエリを叩けば、そこにも購入したスロットが割かれる
→BigQuery Reservations適用状態では購入スロット数以上のバーストは発生しないため、逆に枯渇リスクが高くなってしまう
- 購入スロットの割り当て/割り当て解除を行った際、反映されるまでに5分前後のラグが発生する
→特に、割り当て解除～スロット購入取りやめを行った場合、この5分間はクエリ実行に失敗するようになる
    - オンデマンドに切り替わる前かつ使えるスロットがない状態によるエラーのため、年間コミットメント+Flex Slotsの構成でFlex Slotsだけを取りやめた場合は問題ないと考えられる(要検証)

2点目については今後改善される可能性があるが、基本的にはこの仕組みを適用したい処理のみ別プロジェクトに切り出すのが安全である。

## 疑問点

スロットの割り当て/解除の遅延について調べてみたものの、同じような事例を見かけなかった。これについては見落としや更新が無いかまた時間をおいて確認したい。
[AWK] 特定の文字のあとにテキストを挿入する


特定の文字のあとにファイルにある任意のテキストを挿入します. 

```shell
# テストファイルを作製します
## infileのINSERT部分にinsertファイルにある文字を挿入します
cat << EOF>infile
A
B
INSERT
C
D
EOF

cat << EOF >insert
aaaaa
bbbbb
EOF
```


```sh
cat infile |
  awk '1;/INSERT/{
    while((getline line < "insert")>0){
      print line
   }}' |
  grep -v "INSERT"

# 出力
A
B
aaaaa
bbbbb
C
D
```
【openFrameworks】ofxReflectionRefractionを動かす

# はじめに
openFrameworksにはいろんなアドオンがあり、「少し動かせるようになったけどどんなことできるんだろう？」と思った方は[ofxAddons](https://ofxaddons.com/categories)を徘徊してみると楽しいと思います。

# ofxReflectionRefraction

そんな中、光の屈折とか反射みたいなものをoFで表現できないかなあと思っていたら、[ofxReflectionRefraction](https://github.com/kashimAstro/ofxReflectionRefraction)というまさにそれ！って感じのアドオンを見つけたので紹介します。

まずこんなことができるみたいです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/eku8l7SfzmY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# exampleを動かす

example-vboディレクトリにサンプルコードが載っているので、これを動かしてみましょう。

そうすると、`ofxReflectionRefraction.h`に次のようなエラーが出てくると思います。

```
Invalid operands to binary expression ('glm::mat4' (aka 'mat<4, 4, float, defaultp>') and 'ofMatrix4x4')
```

これはoFのversion0.10.0以降に`ofCamera::getModelViewMatrix()`がglm型で返却されるようになったことが原因みたいです(参考: [openFrameworks で glm を利用する](https://qiita.com/ayumu_nagamatsu/items/f05e330fc7a3a2f6ed66))

`cam.getModelViewMatrix()*tra`の掛け算の順番を変えることにより解決しました。

```diff
void drawMeshGlass(ofCamera cam,ofVec3f translate) {
    ofMatrix4x4 tra;
    tra.preMultTranslate(translate);
    glass.begin();
    glass.setUniformMatrix4f("u_viewProjectionMatrix",cam.getProjectionMatrix());
-    glass.setUniformMatrix4f("u_modelMatrix",cam.getModelViewMatrix()*tra);
+    glass.setUniformMatrix4f("u_modelMatrix",tra*cam.getModelViewMatrix());
    glass.setUniformMatrix3f("u_normalMatrix",mat4ToMat3(ofGetCurrentNormalMatrix()));
    glass.setUniform4f("u_camera",cam.getGlobalPosition().x,
                                  cam.getGlobalPosition().y,
                                  cam.getGlobalPosition().z,0);
    glass.setUniform1i("u_cubemap", 0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, Ctexture);
        vbo.drawElements(GL_TRIANGLES, sizeVboMesh);
    glass.end();
}
```

いちおうプルリクも出しておきました。(2022/4/19追記 マージされたみたいです)

https://github.com/kashimAstro/ofxReflectionRefraction/pull/1
cognito user-poolからtextメールを送信する

Cognitoからの各種メールはhtmlメールとなる。
textメールを送る場合は以下の手順。

1 CognitoへCustomEmailSender　lambdaメソッドを登録する
2 lambdaメソッドから、SES等を使用してメールを送信する

# 1 CognitoへCustomEmailSender　lambdaメソッドを登録する
こちらの記事を参考に、ほぼ完了
https://qiita.com/kiwi26/items/0ed9e51c9089cf6e7ca9

## 補足、plaintextのテキスト文字列の取得方法
plaintextはプレーンなテキストではない

```.ts
import { decode } from "html-entities";

const { plaintext, messageHeader } = await decrypt(keyring, b64.toByteArray(code));
const plainTextCode = decode(plaintext.toString());
```

@aws-crypto/client-node => decryptで取得したplaintextのtoStringによりテキストを取得する。
この文字列は & が &amp; とゆー感じで、パスコードの記号部分が変換されている。
html-entitiesを使って、デコードする。

https://www.npmjs.com/package/html-entities

## lambdaへは、KMSへのアクセス権限が必要

# 2 lambdaメソッドから、SES等を使用してメールを送信する
ここは、普通にSESで送れば良い。



最後に。
これくらい、設定で出来るようにして欲しいと思う。
Python対話モード風にDjangoのモジュールを扱う

---
###Djangoのsettingsが効いてる状態で対話式にAPIとかの動作確認をしたい

```python
python manage.py shell
```

対話モードになります

```python
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
```

Djangoのモデルや、ライブラリー等が、ソースに書く感覚で対話式に扱えます


```python
>>> from links.models import Link
>>> from django.db.models import Q

>>> filter = (
... Q(url__icontains="code") | Q(description__icontains="code"))
>>> article = Link.objects.filter(filter)
>>> for e in article.all():
...     print(e.description)
code writing keep me sane
```
【iOS】アプリ内課金のテストユーザ管理

## Sandboxユーザの登録方法
AppStoreConnectの**Users and Access**を選択して、サイドメニューからSandbox>Testersを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5ec21faa-7cec-2ff5-e653-d94cd8da4b5c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/c4520cd7-12ad-f894-53db-27ac52b6585c.png)

| 項目 | 入力内容 |
|:-:|:-:|
| First Name | 制限なし |
| Last Name |  制限なし |
| Email | 実際に使用できるメールアドレス出なくもOK、過去にApple IDとして紐づけられていないもの |
| Password | 最低8文字以上（32文字以内）。数字、大文字の英字、小文字の英字をすべて1文字ずつ含む。Apple ID と同一の文字列は使用不可。同じ文字の連続3文字使用不可 |
| Secret Question | 制限なし |
| Secret Answer | 制限なし |
| Date of Birth | 制限なし |
| Aoo Store Country or Region | - |

## Sandboxユーザの切替方法
iPhoneで設定アプリを開き、App Store>Sandbox Accountでログアウトやサインインが可能
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/d866bde2-22c5-8943-6e90-0837f9351fcc.jpeg"><img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/1db76a00-ccde-1ce0-8016-a76558363435.jpeg">

## 参考記事

https://support.apple.com/ja-jp/HT201303

https://qiita.com/Masataka-n/items/6f98a5a9fee7b28ccd1f
[Rails]バリデーションのエラーメッセージを３ステップで日本語化

過去の記事
[[Rails]よく使うバリデーションまとめ](https://qiita.com/nakachan1994/items/4279523f7e10e5a9b5b0)
[[Rails]フラッシュメッセージとエラーメッセージ違いと実装方法](https://qiita.com/nakachan1994/items/a4c15e960ae7d941abce)
で、
バリデーションによるエラーメッセージの表示を解説して、実装しましたが、デフォルトではエラーメッセージが英語のままなので、日本語化していきます。

![スクリーンショット 2021-07-19 21.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1554142/58786156-9043-6175-7966-69facd552877.png)

#開発環境

> ruby 2.6.3
> Rails 5.2.6

#3ステップ

エラーメッセージを日本語化するには`３ステップ`です！

①rails-i18nをインストール
②デフォルトの言語を日本語にする
③カラム名も日本語化する

#①rails-i18nをインストール

エラーメッセージを日本語化するには、rails-i18nというgemを使います。
Gemfileに追加します。

```Gemfile
gem 'rails-i18n'
```

追加したら、インストールします。

```
$bundle install
```

これで、rails-i18nをインストールできました。

#②デフォルトの言語を日本語にする

次に、デフォルトの言語を日本語に設定します。
`config/application.rb`に設定を追加していきます。

```config/application.rb
:
module SampleApp
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # 以下一文を追加
    config.i18n.default_locale = :ja
  end
end
```

これで、デフォルトの言語を日本語に設定できました。
サーバーを再起動して試してみてください。

これだけでカラム名以外は、日本語で表示ができています。
![スクリーンショット 2021-07-19 22.08.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1554142/53ddafd3-8717-67c8-dcd7-e659942812f8.png)

#③カラム名も日本語化する

カラム名は各Webサービスによって、表示したい名前も変わってくると思うので、開発者側で設定する必要があります。

`config/locales配下にja.ymlファイルを作成`してその中に、モデル、カラム名の設定を記述していきます。

```yml:基本形
ja:
  activerecord:
    models:
      モデル名: 表記したい名称
    attributes:
      モデル名:
        カラム名: 表記したい名称
        カラム名: 表記したい名称
```

基本はこのような形で記述していきます。
表記したい名称には、imageカラムなら「画像」が入ります。

これだけだとわかりにくいと思うので、実際に記述したコードを載せておきます。

モデルは、以下です。

- User
- Post
- Comment
- Like
- Contact

```config/locales/ja.yml
# エラーメッセージのカラム名日本語化
ja:
  activerecord:
    # 全てのモデル記載
    models:
      user: ユーザー
      post: 投稿
      comment: コメント
      like: いいね
      contact: お問い合わせ
    attributes:
      # 各モデルのカラム名を記載
      user:
        name: 名前
        email: メールアドレス
        password: パスワード
      post:
        content: 説明
        image: 画像
      comment:
        comment: コメント内容
      contact:
        name: 名前
        email: メールアドレス
        content: お問い合わせ内容
```

これで、カラム名も任意の名前に変更できました。
確認してみてください。
![スクリーンショット 2021-07-19 22.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1554142/7680a6b4-d93c-2c47-0618-ef47d7b9bd70.png)

#まとめ

エラーメッセージを日本語化するには`３ステップ`です！

>①rails-i18nをインストール
>②デフォルトの言語を日本語にする
>③カラム名も日本語化する

エラーメッセージをかんたんに実装することができました。

あらためてgemの偉大さを痛感しました！（かんたんすぎ）

最後まで見ていただきありがとうございました。
【SQL Server】【SQL文】行ロック状態取得サンプル

```行ロック状態取得.sql
SELECT count(st.text) AS sts FROM sys.sysprocesses s
OUTER APPLY sys.dm_exec_sql_text(s.sql_handle) st
WHERE s.spid in
(
SELECT  request_session_id
  FROM
      sys.dm_tran_locks
  WHERE resource_type = 'OBJECT'
    AND request_mode='IX'
    AND ( CASE WHEN resource_type = 'OBJECT' THEN
          OBJECT_NAME( resource_associated_entity_id )
      ELSE
          ( SELECT
              OBJECT_NAME( OBJECT_ID )
           FROM
             sys.partitions
           WHERE
               hobt_id=resource_associated_entity_id )
      END)='PRAMETE_TBL-ID'
)
  AND CHARINDEX('目標行の某列のTarget値',st.text) > 0

```
###結果判定：
>IF STS = 0 THEN '通常待機状態READY' ELSE 'ビジー状態' END
Laravel でのファイルダウンロードを実装してみた

##LaravelでPDFファイルのダウンロードを実装してみて、こんなに簡単に実装できるんだ、、、と驚いたので書いてみた

####仕様、もしくは前提
・OS : Windows
・PHP 7.4.16 (cli) (built: Mar  2 2021 14:06:15) ( ZTS Visual C++ 2017 x64 )
・Laravel Framework 6.20.24
・ある画面に表示される「PDF出力」ボタンをクリックすると、DBに登録されているPDFファイルのパスを取得し、ブラウザ経由でローカルにPDFファイルがダウンロードされる。

####1.PDFファイルのパス取得
```php
$res = \DB->table('files')
       ->where('id', '=', $id)
       ->get();
$pdfFilePath = $res->pdf_pile_path;
//C:\LaravelDir\storage\app\public\pdfFiles\202107191038162092931173.pdf
$pdfFileName = pathinfo($pdfFilePath)['basename'];
//202107191038162092931173.pdf
```

####2.ヘッダー情報指定
```php
$headers = [
   'Content-Type' => 'application/pdf'
];
```

####3.ファイルが存在したらダウンロード
```php
if(file_exists($pdfFilePath)){
    return response()->download($pdfFilePath, $pdfFileName, $headers);
}else{
    //ファイルが存在しなかった場合のエラー処理
}
```

###まとめ
こんな感じです。
他にも`Storage::download()`や`Storage::response()`を使う方法があるみたいですが、今回は使いませんでした。
[Vuetify]プロフ画像と削除アイコン

こうするとどうなるでしょう？

# 環境
Vue2
Vuetify

# ソースコード

```vuejs
<v-badge offset-x="20" offset-y="20" overlap color="rgba(0,0,0,0)">
  <v-btn
    slot="badge"
    color="grey white--text"
    class="delete-button"
    fab
    height="20"
    width="20"
    @click="onClickDelete"
  >
    <v-icon small>fas fa-times</v-icon>
  </v-btn>
  <v-avatar size="80" class="mb-3 avatar" @click="onClickImage">
    <img
      src="@/assets/logo.png"
      alt="avatarImage"
      class="avatar-image"
    />
  </v-avatar>
</v-badge>
```


# 実装した結果
![スクリーンショット 2021-07-20 9.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360072/38a6b203-e45d-73d1-eda6-6824dde0c50f.png)


# 解説
今回実装したかったのは、クリックで画像アップロードできるようなプロフィール画像表示と、それを削除するボタンです。

## avatar
プロフィール画像には `v-avatar` を使用します。
これはユーザープロフィール画像用のVuetifyコンポーネントです。

```vuejs
<v-avatar size="80" class="mb-3 avatar" @click="onClickImage">
  <img
    src="@/assets/logo.png"
    alt="avatarImage"
    class="avatar-image"
  />
</v-avatar>
```
## badge
削除ボタンには `v-badge` `v-btn` を使用します。
`v-badge` はアバターのようなコンテンツに付属する部品として
用意されているコンポーネントです。

ただし、削除ボタンはクリックイベントが必要です。
`v-badge`に直接クリックイベントを設けると、
画像をクリックした時のイベントと被ってしまいます。
それを回避するために `v-btn` を `v-badge` にスロットさせています。

```vuejs
<v-badge offset-x="20" offset-y="20" overlap color="rgba(0,0,0,0)">
  <!-- 削除クリックイベントを発生させるためのボタン -->
  <v-btn
    slot="badge"
    color="grey white--text"
    class="delete-button"
    fab
    height="20"
    width="20"
    @click="onClickDelete"
  >
    <!-- ×アイコン -->
    <v-icon small>fas fa-times</v-icon>
  </v-btn>
  <!-- 画像描画領域 -->
  <v-avatar>略</v-avatar>
</v-badge>
```

## まとめると
```vuejs
<v-badge>
  <v-btn>
    <v-icon></v-icon>
  </v-btn>
  <v-avatar></v-avatar>
</v-badge>
```

このように、一見するとヘンテコなDOM構成で
プロフィール画像と削除アイコンを実装することができます。

# リポジトリ
https://github.com/RinyuDrvo/profile-photo-with-vuetify
WioLTE: シリアルモニタを使う

WioLTE でシリアルモニタを使う方法です。5秒毎に時間を出力します。

## 実行結果
![time_arduino.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9ce51ad0-ee7b-0928-8e48-0b2641b23a4c.png)

## プログラム

```text:gettime_test/gettime_test.ino
#include <WioLTEforArduino.h>

#define INTERVAL  (5000)

WioLTE Wio;

void setup() {
  delay(200);

  SerialUSB.println("");
  SerialUSB.println("--- START ---------------------------------------------------");
  
  SerialUSB.println("### I/O Initialize.");
  Wio.Init();
  
  SerialUSB.println("### Power supply ON.");
  Wio.PowerSupplyLTE(true);
  delay(500);

  SerialUSB.println("### Turn on or reset.");
  if (!Wio.TurnOnOrReset()) {
    SerialUSB.println("### ERROR! ###");
    return;
  }
  delay(3000);
  


  SerialUSB.println("### Setup completed.");
}

void loop() {
  SerialUSB.println("*** loop start ***");
  SerialUSB.println("### Get time. ***");
  struct tm now;
  
  if (!Wio.GetTime(&now)) {
    SerialUSB.println("### ERROR! ###");
    goto err;
  }
  SerialUSB.print("UTC:");
  SerialUSB.println(asctime(&now));
    SerialUSB.println("*** check BBB ***");
err:
  delay(INTERVAL);
    SerialUSB.println("*** check CCC ***");
}
```

ポートが次のようになる場合の対応方法

```text
$ ls -al /dev/ttyACM0 
crw-rw---- 1 root dialout 166, 0  7月 20 10:03 /dev/ttyACM0
```

次のコマンドを実行する必要があります。

```bash
usermod -a -G dialout uchida
```

変更を有効にする為に一度ログアウトする必要があります。

参考ページ
[Serial port permissions](https://playground.arduino.cc/Linux/All/#Permission)

## Arduino IDE
2.3.2 を使いました。
ボードは、 Seeed Wio LTE Cat.1 です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6fa01038-4c77-eae0-ef3d-415b4197c5de.png)
ワードミュートがないマストドンインスタンスで擬似的にワードミュートを実現する

Qiitadon で使ってる Mastodon のバージョンは少々古いので, ワードミュート機能が実装されていません。

ということで, ブラウザで見ているときに限りそれっぽいことを実現するユーザースクリプトを書いてみました。

TamperMonkey などのユーザースクリプトを実行する拡張機能を導入し, 以下のスクリプトを書きます。

```js
// ==UserScript==
// @name         Mastodon Pseudo Word Mute
// @namespace    http://junjo-ponpo.com/
// @version      0.1
// @description  擬似的にワードミュートする
// @author       ブルーレヰ
// @include      *://qiitadon.com/*
// @require      https://code.jquery.com/jquery-3.3.1.js
// @grant        none
// ==/UserScript==

/* globals $ */

$(function() {
    "use strict";

    /* ミュートしたい単語のリスト */
    const wordmute_list = [
        'うんこ',
        'ちんちん',
        '残業',
    ];

    const observer = new MutationObserver(records => {
        wordmute_list.forEach(element => {
            $('div.status__wrapper').find(`p:contains("${element}")`).closest('article').css('display', 'none');
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
});
```

細かいカスタマイズは各自でお願いします。