OmniAICreator/Qiita-1.07M huggingface dataset:
[Kotlin] 繰り返し関数 Int.times を作成

# 概要

kotlin には既に `repeat(n)` などの便利な繰り返し関数があるが，個人的に Ruby の `n.times` が好きなので，拡張関数や高階関数の勉強を兼ねて実装．初心者向け．

# 実装

結論を先に述べると実装は次のようになる．

```kotlin:Times.kt
fun <T> Int.times(lambda: (Int) -> T) {
  for (i in 0 until this) {
    lambda(i)
  }
}
```

使い方の例．

```kotlin:Main.kt
fun main() {
  5.times { println(it) }
}
```


```:Output
0
1
2
3
4
```

# 解説

Kotlin の[拡張関数 (extensions) ](https://kotlinlang.org/docs/extensions.html)機能により，既存のクラスに新たな関数を定義できる．例えば，次に示す拡張関数はレシーバとなる Int 型の値と引数 `a` との積を返す関数である．

```kotlin
fun Int.multi(a: Int): Int = this * a
```

```kotlin
println(5.multi(4)) // -> 20
```

そして，Kotlin の[高階関数 (High-order function) ](https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas)機能を併用して，引数に渡されたラムダ式 `lambda()` をレシーバの値の回数だけ実行する高階関数を定義する．

```kotlin
fun <T> Int.times(lambda: () -> T) {
  for (i in 0 until this) {
    lambda()
  }
}
```

パラメーターのラムダ式 `lambda()` に，何回目の処理であるかを示すパラメーター `it: Int` を定義することで，`times` 関数を呼び出すときにラムダ式の中で利用できる．この場合，ラムダ式のパラメーターが 1 つなので宣言を省略して `it` として使用できる

```kotlin
fun <T> Int.times(lambda: (Int) -> T) {
  for (i in 0 until this) {
    lambda(i)
  }
}

fun main() {
  5.times { println(it) }
}
```

定義に従うと次のような呼び出し方ができるが，

```kotlin
5.times( { println(it) } )
```

> According to Kotlin convention, if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses

https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas

とのことなので，次のように変形できる．

```kotlin
5.times{ println(it) }
```
VirtualBoxのNATアダプターに外部PCからSSHする

いやNATじゃなくてブリッジアダプターを使えよ！というツッコミが聞こえてきそうだが、少なくとも自分には需要があったのでメモ

## やりたいこと
Windows10にインストールしたVirtualBox上の仮想マシンに、MacからSSHしたい

## アクセス先IP
* Windows10：192.168.116.72
* 仮想マシン
    * ホストオンリーアダプターIP: 192.168.56.101/24
    * NATアダプターIP: 10.0.3.15/24

## やったこと

1. 仮想マシンにNATアダプターをつけて以下のようにポートフォワーディング設定をする
    - ホストIP：192.168.116.72（WindowsのIP）
    - ホストポート：10022（ウェルノウンポート以外ならなんでも良い）
    - ゲストIP：10.0.3.15（NATアダプターのIP）
    - ゲストポート：22
    ![スクリーンショット (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2343213/136baf62-c367-975a-187a-d189f1c2e435.png)

1. MacからSSH

```
$ ssh -p 10022 kali@192.168.116.72
```

**以上！**
Vue.jsでVimeo動画のフレームを自作することができるのか？

# はじめに
はじめまして！株式会社オークンの向坂英希と申します！
前回のプロジェクトでVimeoのAPIを触ったので、情報を共有していきたいと思います。
# 結論

Vue.jsでVimeo動画のフレームを自作することは**可能です**。
さらに、Vimeoが多くのAPIを提供しているので、動画の細かい設定や制御にも対応できます。

# モジュールのインストール
```
npm install @vimeo/player
```

# 動画の表示
表示する動画のプレイヤーインスタンスを作成し、動画を表示する。
## 手順１　動画を表示する要素の指定
```
<template>
 <div id='vimeo'/>
</template>
```
## 手順２　プレーヤーインスタンスの作成
インスタンスを作成する関数のパラメータに下記を指定する。
第１パラメータ: 動画を表示する要素のid
第２パラメータ: 動画の埋め込みオプション
*埋め込みオプションに関しては、下記を参考にする。
https://developer.vimeo.com/player/sdk/embed

ちなみに、キーボードでの動作を制御する埋め込みオプションが最近追加されました。
キーボードの制御可否をVimeonに問い合わせた直後に追加されたので、結構ユーザの要望を反映してくれるかも？

```
import Player from '@vimeo/player'
export default {
  data () {
    return {
      player: undefined, // 作成したインスタンスを格納する
      // 動画の埋め込みオプション
      options: {
        id: undefined, // vimeoのURLまたはvimeoのID
      },
    }
  },
  mounted () {
    this.player = new Player('vimeo', this.options)
  }
}
```
以上で動画を表示することができる。

# 動画の制御
上記の方法で追加したプレイヤーインスタンスに対して、VimeoのSDKを用いて動画の制御ができます。

ざっとできることは下記になります。
- プレイバックコントロール
- プレイバック時のイベント取得
- プレイバック情報の取得
- プレイヤーインスタンスの制御

詳しくは下記を参考する
https://developer.vimeo.com/player/sdk/reference
## 主なプレイバックコントロール
### 再生

```
this.player.play()
```
### 停止

```
this.player.pause()
```
###再生速度

```
this.player.setPlaybackRate(rate) // rateは0.5から2で指定が可能
```

### 指定秒数からの再生

```
this.player.setCurrentTime(seconds) // 秒数の指定が可能
```

## 主なプレイバック時のイベント
### 再生
```
this.player.on('play', () => {
 // 再生時に発火する処理の記述
})
```
### 停止
```
this.player.on('pause', () => {
 // 停止時に発火する処理の記述
})
```
### シーク（動画の再生時間を変更する時）
```
this.player.on('seeked', () => {
 // シーク時に発火する処理の記述
})
```
### 再生中
```
this.player.on('timeupdate', () => {
 // 再生中に発火する処理の記述
})
```

## プレイバック情報
### 現在の再生秒数

```
this.player.getCurrentTime()
```

## プレイヤーインスタンス
### 動画の切り替え

```
this.player.loadVideo(id | url) // vimeoのURLまたはvimeoのID
```

### プレイヤーインスタンスの削除

```
this.player.destroy()
```

this.loadVideo()で動画は切り替えられるが、埋め込みオプションを選択することが出来ない。
埋め込みオプションも変更する際、一度プレイヤーインスタンスを削除して、再度作成する必要がある。
開発者の用途に応じて、使い分けることが可能である。

# 感想
今回初めてVimeoを使用して、サービスを作成しましたが、Vimeoの便利さに驚きました。
多様なAPIを提供していることもですが、下記の特徴もVimeoの大きな魅了でした。
- 商用利用ができる
- セキュリティ強化や転載防止が可能
- 用途に合わせたプラン設定
Youtubeは商業目的とした使用は禁止されているので、これからもVimeoを使う機会がありそうです。
Next.jsのSSGを勉強してつまづいたことをただメモしていく

Next.jsでSSGサイトが構築できる様に勉強中。
つまづいたことをメモしていく。

## SSGとは
Next.jsで作成したサイトをHTMLの静的ページに書き出すこと


### SSGにする方法

`package.json` に `&& next export` を追記

```
"scripts": {
  "build": "next build && next export"
}
```

参考ドキュメント： https://nextjs.org/docs/advanced-features/static-html-export


### next/image を使って画像を表示させてるとエラーになる

対処法 img タグにして linter の調整をする

紹介記事： https://qiita.com/toshikisugiyama/items/9d9ada2de0cedb03a21e


### getStaticPaths の fallbackでtrueは使えないので、falseにする

参考ドキュメント： https://nextjs.org/docs/messages/ssg-fallback-true-export
紹介記事： https://qiita.com/thesugar/items/47ec3d243d00ddd0b4ed#fallback-true
Nervesにユーザ名／パスワードでSSHログインする

この記事は[#NervesJP Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nervesjp)の11日目です。

10日目は @the_haigo さんの「[Nerves で GPS Loggerを作ってみた](https://qiita.com/the_haigo/items/a941f769ed1e60e382eb)」でした。

----

# 背景
これまで、NervesにSSHする場合はSSHの鍵ペアを作成後 `config/target.exs` に公開鍵を登録していると思います。

これはこれで安全でいいとは思うんですが、Nervesのデモやハンズオン、複数人で利用しようとしている時に、SSH鍵の管理したくないなぁとか簡単にログイン情報共有したいなぁと思う場面が出てきます（よね）。

そこでいつの頃からか、 `nerves_ssh` に `Username/password authentication` という機能が追加されていたのでやってみました。

https://github.com/nerves-project/nerves_ssh#usernamepassword-authentication


# 前提
- Nervesをコンパイル、SSHログインできる環境を構築できている


# 設定
`config/target.exs` に設定を追記します。

`authorized_keys` はSSH公開鍵を登録する箇所（こちらはおまけ）、
`user_password` はユーザ名／パスワードでSSHログインの設定を記入する箇所になります。

以下のような設定をすると、SSH公開鍵にマッチする秘密鍵がPCに保存されてない場合、ユーザ名／パスワードでSSHログインできるようになります。

| ユーザ名 | パスワード |
|:------:|:-------:|
| kazuma | nishiuchikazuma |
| aiueo | kakikukeko |

```elixir:config/target.exs
config :nerves_ssh,
  authorized_keys: [
    "SSH公開鍵A",
    "SSH公開鍵B",
    "SSH公開鍵C"
  ]

config :nerves_ssh,
  user_passwords: [
    # {"username", "password"},
    {"kazuma", "nishiuchikazuma"},
    {"aiueo", "kakikukeko"}
  ]
```

# 確認

今回は `aiueo` ユーザでログインしてパスワードでログインできることを確認します。

```shell:fish
❯ ssh aiueo@192.168.5.156
SSH server
Enter password for "aiueo"
(aiueo@192.168.5.156) password: ※ここで「kakikukeko」と入力
Interactive Elixir (1.12.3) - press Ctrl+C to exit (type h() ENTER for help)
████▄▄    ▐███
█▌  ▀▀██▄▄  ▐█
█▌  ▄▄  ▀▀  ▐█   N  E  R  V  E  S
█▌  ▀▀██▄▄  ▐█
███▌    ▀▀████
yokogawa 0.1.0 (2418023f-ac9f-5cb1-7ac8-19ee000769e3) arm f3rp7x
  Uptime       : 1 minutes and 3 seconds
  Clock        : 2021-12-04 04:58:31 UTC

  Firmware     : Valid (B)               Applications : 32 started (mdns_lite not started)
  Memory usage : 44 MB (4%)              Part usage   : 36 MB (0%)
  Hostname     : nerves-00000000000000000Load average : 1.69 0.56 0.20

  eth0         : 192.168.5.156/24, fe80::200:64ff:fe9c:a2f0/64

Nerves CLI help: https://hexdocs.pm/nerves/using-the-cli.html

Toolshed imported. Run h(Toolshed) for more info.
iex(1)> 
```

# まとめ
`config/target.exs` に `user_passwords` を設定すると、ユーザ名／パスワードでSSHログインできるようになりました。


# 注意事項
設定にあたっての注意事項は以下になります。

- 認証の順序は `authorized_keys` → `user_password` となり、SSH鍵認証が優先される
- SSHのデフォルトユーザは一番はじめに記載されたユーザ
- パスワードが平文で保存される


明日は @torifukukaiou さんの「[Third-party JS packages on Phoenix 1.6 (2021/12/12)](https://qiita.com/torifukukaiou/#)」です。
【React, typescript】react-router-domでLinkタグを使わずにページ遷移させる

#概要
こんにちは
今日はreact-router-domでルーティングを実装するときにURLの遷移をLinkタグを用いずに行う方法を紹介します。
自分はボタンを押したときにapiとデータをやり取りする必要があり、その後にページの遷移を行なって欲しかったため、この方法が役立ちました。

#具体的な方法

（例）

```typescript
import { useHistory } from 'react-router-dom'
...（略）
const history = useHistory()
history.push("/Loading");
```

まずuseHitoryをreact-router-domからimportします。
その後history変数を宣言します。
最後に```history.push("指定するURL")```とすれば完成です。

#個人的な感想

これを用いることで好きなタイミングでURL遷移を行うことができるのが嬉しいです。
自分は外部APIと通信し、そのデータを用いて次の画面を表示させたかったのでとても役立ちました。
またそこではaxiosを用いて非同期通信を行いました。いずれその記事も書こうと思います。
【TypeScript】オプショナルプロパティ(Optional Property)

# 概要
TypeScriptのオプショナルプロパティ(Optional Property)について、学んだことや理解したことなどを記載する。

# この記事で理解できること
* オプショナルプロパティとはなにか
* いつ、どのように使用するのか

# オプショナルプロパティ(Optional Property)とは
* オブジェクトのプロパティを`任意プロパティ`として定義したい場合に使用する。
* プロパティの末尾に「`?`」を付加することで、<br>そのプロパティは`オプショナル(任意)なプロパティ`であることを定義できる。 

```ts
// 以降のオブジェクトで使用する型エイリアス(名前の付いた型)を定義
type Human = {
  name: string;    // 名前
  age: number;     // 年齢
  hobby?: string;  // 趣味(「?」を付加したことで、オプショナル(任意)なプロパティになる)
}

// 以降のオブジェクトにHuman型を指定する
const member1: Human = {
  name: 'Taro',     // 必須
  age: 24,          // 必須
  hobby: 'running'  // 任意
}
// => OK

const member2: Human = {
  name: 'Jiro',     // 必須
  age: 24,          // 必須
}
// => OK hobbyプロパティは任意のプロパティなので、存在していない場合でもエラーにならない

const member3: Human = {
  name: 'Hanako',   // 必須
  hobby: 'cooking'  // 任意
}
// => NG Human型では必須のageプロパティが足りないとエラーになる

const member4: Human = {
  hobby: 'running' // 任意
}
// => NG Human型では必須のname、ageプロパティが足りないとエラーになる
```
Python 辞書

#はじめに
基礎から定着させていこうということで辞書についてまとめました。
Python 3.8.2

#辞書の作成
```python:dict.py
d = {"x":1,"y":2}
print("d is",type(d))
print(d)

d2 = dict(x=10,y=20)
print("d2 is",type(d2))
print(d2)

d3 = {"x":"hello","y":"world"}
print("d3 is",type(d3))
print(d3)
```

```:出力結果
d is <class 'dict'>
{'x': 1, 'y': 2}
d2 is <class 'dict'>
{'x': 10, 'y': 20}
d3 is <class 'dict'>
{'x': 'hello', 'y': 'world'}
```

#辞書の書き換え、追加
```python:dict.py
d = {"x":1,"y":2}

d["x"] = 11
print(d)

d["y"] = "yyy"
print(d)

d["z"] = 3
print(d)
```

```:出力結果
{'x': 11, 'y': 2}
{'x': 11, 'y': 'yyy'}
{'x': 11, 'y': 'yyy', 'z': 3}
```

#辞書のkeyとvalueの確認

```python:dict.py
d = {"x":1,"y":2}

print(d.keys())
print(d.values())
```

```:出力結果
dict_keys(['x', 'y'])
dict_values([1, 2])
```

#要素の確認
```python:dict.py
d = {"x":1,"y":2,"z":3}

print(d["x"])
print(d.get("y"))
```
```:出力結果
1
2
```

#辞書に存在しない要素の確認
"nothing"という辞書には無いkeyを指定して要素を確認する
keyは存在しないので、デフォルトでNoneという値を返す
デフォルト以外の値を返したい場合は、keyの後に返したい値を指定する

```python:dict.py
d = {"x":1,"y":2,"z":3}

print(d.get("nothing"))
print(d.get("nothing", 0))
```
```:出力結果
None
0
```
d[key]の方法で存在しないkeyを指定するとエラーが発生する

```python:dict.py
d = {"x":1,"y":2,"z":3}

print(d["nothing"])
```

```:出力結果
Traceback (most recent call last):
  File "dict.py", line 52, in <module>
    print(d["nothing"])
KeyError: 'nothing'
```

#keyが辞書に存在するか確認
```python:dict.py
d = {"x":1,"y":2,"z":3}

r = "x" in d
print(r)

r = "a" in d
print(r)
```

```:出力結果
True
False
```

#辞書のオーバーライド
```python:dict.py
d = {"x":1,"y":2}
d2 = {"x":10,"z":30}

d.update(d2)
print(d)
```

```:出力結果
{'x': 10, 'y': 2, 'z': 30}
```

#辞書の削除
```python:dict.py
d = {"x":1,"y":2,"z":3}

del d
print(d)
```
「del d」を行った後に「print(d)]で呼び出しているため、エラーが発生している
辞書自体が削除されていることが確認できる

```:出力結果
Traceback (most recent call last):
  File "dict.py", line 74, in <module>
    print(d)
NameError: name 'd' is not defined
```

#辞書のコピー

```python:dict.py
d = {"x":1,"y":2,"z":3}

d2 =  d.copy()
d2["x"] = 10

print(d)
print(d2)
print("d is",id(d))
print("d2 is",id(d2))
```
idを確認してみると別のオブジェクトであることが確認できる

```:出力結果
{'x': 1, 'y': 2, 'z': 3}
{'x': 10, 'y': 2, 'z': 3}
d is 4442169536
d2 is 4441815872
```
#要素の抜きだし、削除
```python:dict.py
d = {"x":1,"y":2,"z":3}

d.pop("x")
print(d)

del d["y"]
print(d)
```

```:出力結果
{'y': 2, 'z': 3}
{'z': 3}
```

#辞書のクリア
```python:dict.py
d = {"x":1,"y":2,"z":3}

d.clear()
print(d)
```
辞書の中身がクリアになっていることが確認できる

```:出力結果
{}
```

以上
openpyxlで円グラフを作成する

　openpyxlで円グラフを作る方法は本に書いてあったり、ネットで検索しても情報がたくさん出てきますが、凡例の指定の仕方まで書かれているものはなかなか見つからなかったのでここに書いておきます。

##データ準備
　以下のようなデータ表を用意します。
![input_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617752/b30e473c-f79d-a6c1-81b5-56e78cc1ed57.png)
　参考までに乱数を振って表にまとめるコードを載せておきます。（数字が書いてあればなんでもOKです）

```Python
import numpy as np
import pandas as pd

#make DataFtame
test_matrix = np.random.rand(3,3)
row_label = ['row_0','row_1','row_2']
col_label = ['col_0','col_1','col_2']
df = pd.DataFrame(test_matrix,index = row_label,columns=col_label)
df.to_excel('PieChart.xlsx', sheet_name='raw_data')
```

##円グラフ作成
　以下、円グラフ作成のコードと実行結果です。
 　(グラフの大きさが違うのが気になる。揃えるオプションがあるのか、Libreの癖なのか。。。)

```Python
import openpyxl
from openpyxl.chart import PieChart, Reference
from openpyxl.chart.label import DataLabelList

#read Excel file
wb = openpyxl.load_workbook('PieChart.xlsx')
ws = wb.copy_worksheet(wb['raw_data'])

for i in range (0,3):
    #set PieChart
    chart = PieChart()
    chart.height = 5
    chart.width  = 10
    data = Reference(ws,min_row=1, min_col=i+2,max_row=4)
    labels = Reference(ws,min_row=2, min_col=1,max_row=4)
    chart.add_data(data, titles_from_data=True)
    chart.set_categories(labels)

    #set DataLabel
    chart.dataLabels = DataLabelList()
    chart.dataLabels.showVal = False
    chart.dataLabels.showPercent = True
    chart.dataLabels.dLblPos = 'outEnd'

    #put graph
    ws.add_chart(chart, ws.cell(row=10*i+6,column=1).coordinate)

#save Excel file
wb.save('PieChart.xlsx')
```
![result2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617752/ab3e8a7e-8227-0d6c-fc4d-fa931c44b1c7.png)
 個人的に共有したかったのは凡例を設定する部分。

```Python
#set DataLabel
chart.dataLabels = DataLabelList()
chart.dataLabels.showVal = False
chart.dataLabels.showPercent = True
chart.dataLabels.dLblPos = 'outEnd'
```
　グラフ一個だけなら手で設定しても問題ないが、今回の例のように複数グラフを同じ凡例の設定で並べて見たい時にはコード上で設定できた方がいい。
　因みに今回の設定は「数値の表示」OFF,「割合の%表示」ON,[凡例の表示位置]外側、に設定している。
　
　他の設定や詳細の引数などの情報は以下サイトに書かれています。

https://openpyxl.readthedocs.io/en/stable/api/openpyxl.chart.label.html
ESP32とjoyconのBluetooth通信がうまくいかんだ話

# 概要
ESP32でおもしろいことしたいなーと思い立ち、結果よくわからないまま失敗したあほの記事

## やりたかったこと
ご存じESP32にはBluetooth通信の機能がついている。そしてjoyconにもBluetooth通信の機能がある。
じゃあいけるじゃん！と思い、やってみた

## やったこと
まず[bluetooth-command-line-tools](https://bluetoothinstaller.com/bluetooth-command-line-tools)というのを用いてjoyconのMACアドレスを取得する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/c75d73a6-286a-35ff-12cb-63e6bf49b93e.png)



次に以下のようなコードをESP32に書き込んだ

```joyconL.ino
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

String MACadd = "D4:F0:57:D9:81:80";
uint8_t address[6]  = {0xD4, 0xF0, 0x57, 0xD9, 0x81, 0x80};
String name = "Joy-Con (L)";
char *pin = "1234"; //<- standard pin would be provided by default
bool connected;

void setup() {
  Serial.begin(115200);
  //SerialBT.setPin(pin);
  SerialBT.begin("ESP32_test", true); 
  //SerialBT.setPin(pin);
  Serial.println("The device started in master mode, make sure remote BT device is on!");
  
  // connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs
  // to resolve name to address first, but it allows to connect to different devices with the same name.
  // Set CoreDebugLevel to Info to view devices bluetooth address and device names
  //connected = SerialBT.connect(name);
  connected = SerialBT.connect(address);
  
  if(connected) {
    Serial.println("Connected Succesfully!");
  } else {
    while(!SerialBT.connected(10000)) {
      Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app."); 
    }
  }
  // disconnect() may take upto 10 secs max
  if (SerialBT.disconnect()) {
    Serial.println("Disconnected Succesfully!");
  }
  // this would reconnect to the name(will use address, if resolved) or address used with connect(name/address).
  SerialBT.connect();
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }
  delay(20);
}
```
まあつながりませんでしたが。

## 反省
私は失敗したがやってる人はいたからできることではある
ESP32がbluetooth3.0に対応していない可能性を考えたが、ネットにbluetooth3.0のコントローラーと通信してそうな記事があったので違いそう
また再挑戦はします……
iOSエンジニアとして入社したその後を振り返る

この記事は ビビッドガーデン Advent Calendar 2021 の5日目です。
こんにちは、食べチョクの開発をお手伝いさせていただいている@y_hakutakuです。

さてなにを書くかと思いましたが、入社後のiOS開発のプラットフォーム部分での取り組みを振り返りと今後の展望です。

# まずはなにから手をつけていこう！？ :thinking: 
私が入社するまでは1名体制で入社しても2名。やりたいことプロダクトとしても、プラットフォーム（技術的な要素）的にも沢山ある。
リソースをより本質的なことに避けるように自動化に取り組みました。
目的は**プロダクト開発に使える時間を増やす**でスコープは**開発サイクルで頻出、重要な作業の軽量化**としました。

## Cocoa PodsやCarthageで導入しているライブラリの定期自動更新🌀
こちらの[記事](https://qiita.com/y_hakutaku/items/1722ebb70346eb603559)で概要を記載していますが、ライブラリ周りの更新はサボりやすく、溜まると非常に厄介です。
そのため、食べチョクアプリでは週１回定期的に自動更新、テスト実行、PRの作成まで自動で行っています。
マージについては手動で行っています。これは目視で確認を行いたいケースもあるためです。
![PR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/48a67785-cab5-7075-e401-162d13176eb8.png)

## リリース作業の自動化✨
こちらの[記事](https://qiita.com/y_hakutaku/items/4a8fc318d9903a8f6b03)で後半については紹介していますが、結果としてリリースタグを作成すると
審査に自動で提出しFirebaseCrashlyticsへのdSYMのuploadや審査通過通知など全てタグ生成のみで完了できるようになりました。
記事化したことでBitrise賞がもらえたりしました。
![Slackの通知.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/99d2af96-ba62-6349-9bf7-8e5fadd2b0e9.png)

# 次にやったこと機能実装のリファクタリング🧑‍🏭
ログイン/ユーザー登録リファクタリングを行いました。シーケンスのうち要/不要が不明瞭になっている箇所があったため、整理の意味を兼ねます。
ログインについては、UITestがあり、登録については新たに実装を行っていただいた上で実施しました。

今後もリファクタリングについては必要に応じて実施していければと考えています。
リファクタリング候補としては、アプリとしての重要導線に関わる箇所についてはシンプルにする方向で積極的に行いたい気持ちです。

# 思いついて始めたこと💡
App Storeのリリースノートが少し味気なかったのでこちらにエンジニアやマーケターの方のメッセージを載せることにしました。
Slackでぼそっと呟いたことから始まりましたが、生産者さんからも見てるよーという話もあり、これも継続していければと思っております。
![iOS の画像 (40).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/86be9591-0fce-f65f-a551-bb5acb2facfb.png)

# これからのこと👀
プラットフォームについても改善していきたいことは、山ほどあります。
現在、iOSアプリ開発において理想をiOSメンバーでブレストで出す作業を進めており、その後全体を俯瞰し優先順位をつけて進めていく計画です。

# 最後に
ビビットガーデンで働いてきた振り返りとしては直接農家さんと交流するイベントやTwitterでの不具合報告を拾ったりとユーザーに近いところで仕事ができたことも大きかったなと感じています。

この年末の食材の購入、ぜひ食べチョクのご利用を検討いただけると幸いです。
https://www.tabechoku.com/

また、ソーシャルカンパニーのエンジニアとして働くことに興味がお持ちでしたら、ついでに、プロダクトチームも覗いて見てはいかがでしょうか？
https://www.wantedly.com/companies/vivid-garden/post_articles/362779
https://herp.careers/v1/vividgarden/KpLywERTT_Wh
UnityのWebGLでwasmのMIMEに関して表示される警告を回避する

![img20211204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112430/3801fc0a-042c-9fe2-1eb2-83089ac6473e.png)
Unityで練習として構築中のプロジェクトをWebGLでサーバにアップロードしたら変なメッセージが出た。
多分、MIMEが登録されていないという警告だと思う。

MIMEについては世界中に良い説明がたくさんあると思うので割愛けど、今回は自社で使っているレンタルサーバ『さくらインターネット』のスタンダードタイプで、UnityのWebGLによって書き出されたプロジェクトをアップロードした際に遭遇したトラブルとその対処を備忘録として記述しておく。

使用レンタルサーバサービス：
さくらインターネット　スタンダードプラン

Unityのバージョン：
2020.3.23.f1

何をしようとしたか：
Unityで構築したプロジェクトをレンタルサーバへアップロードしてプレイしてみようと思った。

どうやったか：
UnityのBuildでWebGLを選択しパブリッシュ。
FTPソフト（Adobe DreamWeaverを使用）からレンタルサーバへフォルダごとアップロード。
ウェブブラウザからアップロードしたフォルダへアクセスしたところ、WebGLアプリ起動時に以下のようなメッセージが表示された。

![img20211204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112430/19419db0-ab3c-8dec-cc65-61b9e6ddd7b1.png)

>HTTP Response Header "Content-Type" configured incorrectly on the server for file Build/Demo.wasm , should be "application/wasm". Startup time performance will suffer.

>(DeepLでの翻訳）Build/Demo.wasmファイルに対するHTTP応答ヘッダーのContent-Typeがサーバー上で正しく設定されていませんでした。スタートアップ時のパフォーマンスが低下します。

DeepL（すごい便利な世の中になったもんだ）の翻訳によるとContent-Typeがちゃんと設定されていないことが原因だってことなので、レンタルサーバの.htaccessファイルに以下の一文を追加した。

```tarminal
AddType application/wasm wasm
```

つまり、wasmファイルはアプリだよ
ってことをサーバにちゃんと明言したってことだと思う（違ったらすいません）。

ちなみにwasmファイルはUnityでWebGLを書き出すとBuildというフォルダの中に作られるファイルの拡張子（何をしているファイルかはよくわからんw）。

とにかくこれでWebGLアプリの起動時に、あの変な黄色い色で囲われたメッセージは出なくなった。

めでたし、めでたし
マスク下の表情を当てるアプリを作った

この記事は、[クソアプリ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kuso-app) カレンダー3 の6日目の記事です。

# 作ったもの
今回作成したものは、こちら ↓

https://www.under-mask.xyz/

![スクリーンショット 2021-12-04 13.41.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/bc527fcc-579e-1b33-ae43-d24aaf9ea6a6.png)


# どんなサービスか
名前の通り、マスク下の表情を当てるゲーム！
最初にマスクをしていない画像が表示されるので、その画像と同じ表情をしていると思われる画像を選択します。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/3a729ef3-5200-f619-93d4-434c32bc573a.gif)
全部で3問あります！

# なぜ作ったか
偶然、クソアプリ Advent Calendar を見つけたのがきっかけです。「何か作るなら身近なものが良いなー」「そういえば、去年からずっとマスクをつけているなー」と思い、このサービスを思いつきました。

# 技術的な話

## 使ったフレームワーク・ツールなど
- Nuxt.js
- Tailwind CSS
    - 最近、個人で開発をするときによく使っているCSSフレームワークです
    - クラスの命名について考える必要がないのが楽です
- Vercel
- [Canva](https://www.canva.com/ja_jp/)
    - 表示している画像はCanvaを使って作成しました
    - 表示する画像をどんな画像にしようかという所に一番時間がかかった気がします
- [ソコスト](https://soco-st.com/)
    - OGP画像やfaviconのマスク画像は、ソコストを使って作成しました
    - 統一感があってシンプルなイラストが好きです

## 工夫した点
画像選択時のアニメーションをどうしよーかなーと悩んでいたんですが、クリックすると元の画像が表示されてスーっと消えていくように実装しました。

Tailwind CSSだと `class="opacity-0 transition-opacity duration-3000"` とするだけで、3秒かけて、opacityが徐々に0になるように設定することができます。

```vue
<div class="mt-2 w-72">
  <ul class="flex flex-wrap justify-center">
    <li v-for="n in numArr" :key="n" class="py-2 w-32">
      <a v-if="isClicked" class="opacity-0 transition-opacity duration-3000"><img :src="'/img/mouth'+n+'.png'" alt=""></a>
      <a v-else class="cursor-pointer transform hover:-translate-y-1 hover:scale-110" @click="isCorrectAnswer(n)"><img src="/img/mask.png" alt=""></a>
    </li>
  </ul>
</div>
```

# おわりに
以上、マスク下の表情を当てるクソアプリをご紹介しました！

特に誰の役にも立たない、クソアプリとして絶妙な仕上がりになったのではないかと思います。
ぜひ、「マスク下の表情当てゲーム」で遊んでみてください〜

https://www.under-mask.xyz/

良いと思う部分があれば、是非LGTMをお願いします！
【Swift】前の○曜日の日付を出力する関数

# 概要

直近の水曜日の日付（午前0時ちょうどの時刻）を出力したい場面があったので、関数を作ってみました。

## コード

modulo演算を作っておきます。
参考：https://qiita.com/Ryuichirou/items/5ffed727c031290fed61

```swift:Utils.swift
import Foundation

infix operator %%
func %%(lhs: Int, rhs: Int) -> Int{
    return ((lhs % rhs) + rhs) % rhs
}

```

今日の曜日から、目的の曜日まで何日戻せば良いか計算して、Dateを出力します。
引数がStringだとヒューマンエラーが起こりそうなので、引数をenum（Weekday型）にしてコンパイル時にエラーがわかるようにしています。
（イニシャライザは要検討かも）

```swift:DateUtils.swift
import Foundation

class DateUtils {    
    class func dateOfLastWeekday (_ weekday:Weekday) -> Date {
        let dateFormatter = DateFormatter()
        let calendar = Calendar(identifier: .gregorian)
        let today = Date()
        dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "E", options: 0, locale: Locale(identifier: "en_US_POSIX"))
        let weekdayOfToday = dateFormatter.string(from: today)
        let interval = (Weekday(weekdayOfToday).order - weekday.order) %% 7
        let date = calendar.startOfDay(for: Calendar.current.date(byAdding: .day, value: interval * (-1), to: today)!)
        return date
    }
    
    enum Weekday {
        case Sunday
        case Monday
        case Tuesday
        case Wednesday
        case Thursday
        case Friday
        case Saturday
        
        init(_ E :String){
            switch E {
            case "Sun": self = .Sunday
            case "Mon": self = .Monday
            case "Tue": self = .Tuesday
            case "Wed": self = .Wednesday
            case "Thu": self = .Thursday
            case "Fri": self = .Friday
            case "Sat": self = .Saturday
            default: fatalError("Illegal weekday string \"\(E)\"")
            }
        }
        
        var order: Int {
            switch self {
            case .Sunday:    return 0
            case .Monday:    return 1
            case .Tuesday:   return 2
            case .Wednesday: return 3
            case .Thursday:  return 4
            case .Friday:    return 5
            case .Saturday:  return 6
            }
        }
    }
}
```

## 使い方

```swift
let lastWednesday = DateUtils.dateOfLastWeekday(.Wednesday)
print(lastWednesday)
// 2021-11-30 15:00:00 +0000　
// -> 日本標準時では2021-12-01 00:00:00 となり、水曜日の午前0時が出力されている
```
AVX/AVX2による256ビットストア命令

# はじめに
 256ビットのストア命令について書きます．

## _mm256_store|storeu_ps|pd|si256 (AVX)
```cpp
void _mm256_store_ps (float * mem_addr, __m256 a)
asm: vmovaps m256, ymm
void _mm256_storeu_ps (float * mem_addr, __m256 a)
asm: vmovups m256, ymm
void _mm256_store_pd (double * mem_addr, __m256d a)
asm: vmovapd m256, ymm
void _mm256_storeu_pd (double * mem_addr, __m256d a)
asm: vmovupd m256, ymm
void _mm256_store_si256 (__m256i * mem_addr, __m256i a)
asm: vmovdqa m256, ymm
void _mm256_storeu_si256 (__m256i * mem_addr, __m256i a)
asm: vmovdqu m256, ymm
```

| Architecture | Latency | Throughput |Uops|
|--------------|:-------:|:----------:|:--:|
| Alderlake    |mem. dep.|    1.0     |  - |
| Icelake      |   4/11  |    0.5(1)  | 1/2|
| Skylake      |   4/10  |     1      | 1/2|
| Broadwell    |   5/9   |     1      | 1/2|
| Haswell      |   5/9   |     1      | 1/2|
| Ivy Bridge   |   5/9   |     2      | 1/2|
| Sandy Bridge |   5/9   |     2      | 1/2|
| Zen3         |   9/10  |     1      |  1 |
| Zen2         |   8/9   |     1      |  1 |
| Zen          |   7/11  |     2      |  2 |

* AIDA64だとicelakeも1.0と出ているため，alderlakeの1は，測り方の違いなだけの可能性
* ポート数的には，icelakeと同じストア用のポートがあるため，同様の数値にならないとおかしい．

アライメントがずれた場合（AIDA64）

```asm
VMOVUPS [m256 + 4], ymm
```

| Architecture | Latency | Throughput |Uops|
|--------------|:-------:|:----------:|:--:|
| Alderlake    |mem. dep.|     2      |  - |
| Icelake      |mem. dep.|     2      |  - |
| Skylake      |mem. dep.|     2      |  - |
| Broadwell    |mem. dep.|     3      |  - |
| Haswell      |mem. dep.|     3      |  - |
| Ivy Bridge   |mem. dep.|     4      |  - |
| Sandy Bridge |mem. dep.|     4      |  - |
| Zen3         |mem. dep.|     1      |  - |
| Zen2         |mem. dep.|     2      |  - |
| Zen          |mem. dep.|     4      |  - |


**説明**  
256ビット浮動小数点や整数をストアします．
store命令は書き込みは32ビット境界にそろっている必要があります．
storeu命令はそろっていなくもてかまいません．
そろっていない場合は，低速になります．

ストアは，値をストアバッファにためて送るため，ストアした値が即時必要なレジスタスピルを頻発するような状況でもない限り，ほとんどの場合でレイテンシを考慮する必要はありません．

## _mm256_stream_ps|pd|si256 (AVX)
```cpp
void _mm256_stream_ps (float * mem_addr, __m256 a)
asm: vmovntps m256, ymm
void _mm256_stream_pd (double * mem_addr, __m256d a)
asm: vmovntpd m256, ymm
void _mm256_stream_si256 (__m256i * mem_addr, __m256i a)
asm: vmovntdq m256, ymm
```

| Architecture | Latency | Throughput |Uops|
|--------------|:-------:|:----------:|:--:|
| Alderlake    |mem. dep.|    0.5     |  - |
| Icelake      |  390    |    1.03    | 1/2|
| Skylake      |  358    |     1      | 1/2|
| Broadwell    |  344    |     1      | 1/2|
| Haswell      |  392    |     1      | 1/2|
| Ivy Bridge   |  329    |     2      | 1/2|
| Sandy Bridge |  360    |     2      | 1/2|
| Zen3         |  777    |     1      |  1 |
| Zen2         |  1200   |     1      |  1 |
| Zen          |  1250   |     2      |  2 |

* AIDA64だとicelakeはT:1.17
* Alderlakeのスループットが0.5です．

**説明**  
256ビット浮動小数点や整数をキャッシュを介さずストアします．
メモリの32バイト境界にアライメントはそろっている必要があります．
そろっていない場合は，プログラムが落ちます．

ロードと違ってstream命令は全ての型に対して用意されています．
またロードはAVX2からの対応に対し，ストアはAVXから対応しています．

レイテンシが長いのは，ベンチマーク時にキャッシュに乗っていないため，メモリからの操作になっているからです．

メモリからのロードはすべての演算の効率化を台無しにすることがここからよくわかります．
Outsystemsアプリケーションのデバッグ

サーバーアクションとクライアントアクション
1.Service Studioがブレークポイントを登録する
ブレークポイントはDebugパネルに一覧表示される
ブレークポイントは削除と一時的な無効化が可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/4c43e8c8-4356-7080-023f-27d3bea0c0a0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/229a315e-8c2b-b12f-a4dc-db387a1ee7f9.png)
2.アプリケーションがブラウザで開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/03d30581-8495-d2de-fc58-a34fc4c67dfd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/9ed18d16-5952-acbc-5615-8bb331a4f466.png)
3.開発者はコードをステップ単位で実行可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/bfe08ff6-c79f-d368-e234-6c0679aeaf31.png)
注意点：実行がブレークポイントに到達すると、Service Studioにフォーカスが戻る

通常のデバッグ操作が可能
Step Over（ステップオーバー）
Step Into（ステップイン）
Step Out（ステップアウト）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/2394b8b0-de25-ff17-e0e1-a6bf71b25347.png)
変数の検査
Outsystemsは実行が停止している間に変数の値を検査可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/2eda6981-d2c7-aa9a-a59b-98c1f0df860d.png)
Goでtemplateを使って、xmlを生成してみる


この記事は[Wanoグループ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/wano-group) 4日目の記事になります

goのTemplateはtext/html二種類がある

しかしxml生成の際に、どっちでもそのまま使ってはいけません

例えば:

text/templateの場合

```go
package main

import (
	"bytes"
	"fmt"
	"text/template"
)

type XmlTemplateMeta struct {
	Text string
}

func main() {

	var xmlTemplateStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n  <text>{{ .Text }}</text>\n</test>\n"

	// & 入れたら。。。
	x := XmlTemplateMeta{
		Text: "test string1 & string2",
	}
	
	tmpl := template.Must(template.New("xml_template").Parse(xmlTemplateStr))
	resBuffer := new(bytes.Buffer)

	tmpl.Execute(resBuffer, x)
	fmt.Printf("%v",resBuffer.String())

}
```

結果は:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<test>
  <text>test string1 & string2</text>
</test>
```

&はescapeできなかった
もしhtml/templateを使う場合:


```xml
&lt;?xml version="1.0" encoding="UTF-8"?>
<test>
  <text>test string1 &amp; string2</text>
</test>

```

中身は出来ましたけど、先頭の<?xml 部分もescapeしようとしてしまう、これもダメですね

そうしたらhtml.EscapeStringを使って、中身は先に一回escapeの手もありますけど

```go
package main

import (
	"bytes"
	"fmt"
	"html"
	"text/template"
)

type XmlTemplateMeta struct {
	Text string
}

func main() {

	var xmlTemplateStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n  <text>{{ .Text }}</text>\n</test>\n"

	x := XmlTemplateMeta{
		Text: html.EscapeString("test string1 & string2"),  // EscapeStringを使用
	}

	tmpl := template.Must(template.New("xml_template").Parse(xmlTemplateStr))
	resBuffer := new(bytes.Buffer)

	tmpl.Execute(resBuffer, x)
	fmt.Printf("%v",resBuffer.String())

}
```

結果：

```xml

<?xml version="1.0" encoding="UTF-8"?>
<test>
  <text>test string1 &amp; string2</text>
</test>


```


但しstructの構造体に対して、中のstringを再帰的に処理がいるので、結構面倒いですね。
そこでtempalteのpipeline機能を使ってやてみます

```go

package main

import (
	"bytes"
	"fmt"
	"html"
	"text/template"
)

type XmlTemplateMeta struct {
	Text string
}

func main() {

	// tempalteの中もescapeの使用をお忘れなく
	var xmlTemplateStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n  <text>{{escape .Text }}</text>\n</test>\n"

	funcMap := map[string]interface{}{
		"escape": func(str string) string {
			return html.EscapeString(str)
		},
	}

	x := XmlTemplateMeta{
		Text: "test string1 & string2",
	}

	// funcMapの使用
	tmpl := template.Must(template.New("xml_template").Funcs(funcMap).Parse(xmlTemplateStr))
	resBuffer := new(bytes.Buffer)

	tmpl.Execute(resBuffer, x)
	fmt.Printf("%v",resBuffer.String())

}

```

これならescape設定は全部templateの中で完結するので、structの方気にしなくで良いですね
AKBONE2020 でタッチセンサ端子を使う

AKBONE2020 は秋葉原ロボット部( 旧 日本Androidの会秋葉原支部ロボット部 )
のはんだづけトレーニングキット。

はんだづけの練習が終わったら、Arduino互換ボードとして楽しもう！ 
今回は基板上にあるタッチセンサ端子を使ってみます。

「はんだ付けトレーニングキット AKBONE2020」
https://qiita.com/nanbuwks/items/8ff1b2c711d58fc6f85a

# タッチセンサ端子とは
コレ。
[]( scale=0.5 )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/35dd22f3-919b-531a-5d48-60044b887755.png)

micro:bit のタッチセンサ端子をマネしてみました。

左側がA0,右側がGNDとなっています。


ワニ口クリップで接続ができます。
[]( scale=0.7 )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a324ee37-a59f-09e3-19e2-c2e748220573.png)
なるべく、GNDには黒色を接続しましょう。

# サンプルプログラム

```


int sensorPin = A0;
int speakerPin = 15;
int onLevel = 3700;
int soundTone = 600;
void setup() {
  Serial.begin(115200);
  
}
void loop() {
  pinMode(sensorPin,OUTPUT);
  digitalWrite(sensorPin,LOW);
  delay(1);
  pinMode(sensorPin,INPUT_PULLUP);
  delayMicroseconds(50);
  pinMode(sensorPin,INPUT);
  
   int value = analogRead(sensorPin);
   Serial.println(value);
   if ( onLevel > value ){
      tone(speakerPin,soundTone);
      delay(100);
   } else {
      noTone(speakerPin);
      delay(100);
   }
}

```
タッチセンサ端子をそのまま触ると音が鳴ります。

int onLevel = 3700;
とあるのが、反応値の敷居値です。この値より下がると音が鳴ります。
いくつかの AKBONE2020で試してみた値ですが、利用シーンによって変更してください。

シリアルモニターで取得した値が表示されるので、これを見て調整しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/27015208-e083-4159-455c-e46a4954b3d5.png)



# 使用例1



[]( scale=0.5 )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c117d9d2-4739-c92c-c23d-b0b76ff77250.png)
プラ板にアルミ箔を貼って、電極を作ってみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8c65957f-0d77-1beb-09b3-fd187b503246.png)
これを触ると鳴ります。

# 使用例2


micro:bit ではバナナをつないでましたが、バナナが無かったのでりんごを繋いでみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d5aeb4a2-2f1b-3a17-3667-f8819bdad5d7.png)
りんごのヘタは絶縁体だと思ってましたが、ヘタに接続するのでも十分データが取れました。
# 使用例3


[]( scale=0.7 )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3d78d4bb-54b5-3f0a-582a-ffdc15d8f602.png)
先程のアルミ箔をお風呂に貼ってみました。水位が上がると導通します。
# 使用例4


[]( scale=0.6 )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fba1aedb-6eeb-3f23-111a-e29ac29fcc9b.png)
乾燥センサ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3ac9ea3b-ba8f-e6f8-0910-2fb311eff8b7.png)

土が乾くと反応します。しかしながらこの、アルミ箔を使ったセンサだと長期だと腐食してしまいます。実用性を考えるなら、黒鉛電極などを使ったものにしたいところです。

# 使用例5


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ddec6e86-cec8-db0f-7b3f-005580b5196a.png)
雨センサとして、0.5mmのステンレス線で編んでみました。
水滴が着くと反応します。
# 応用

音を鳴らす代わりに、LEDストリップを光らせたり、リレーを動かしたりしてもいいですね！ 考えてみましょう！
bqコマンドに渡しているスキーマのJSONが間違っていてもクエリが実行されてしまう問題

bq queryコマンドにdestination_tableオプションを渡すとSELECT結果をテーブルにすることができます。
また、この時にdestination_schemaオプションも同時に渡すと、テーブルのスキーマを設定できます。

https://cloud.google.com/bigquery/docs/reference/bq-cli-reference#bq_query

ただし、この機能は壊れたJSONを渡したときの挙動に注意が必要です。
例えば、以下のような壊れたJSONを渡した時に、bqコマンドは失敗しますが、クエリは実行されdestination_tableに指定したテーブルは生成されてしまいます。
また、destination_schemaに対して存在しないファイルを渡した場合も同様にテーブルが生成されてしまいます。

```json
[
 {
   "name": "col1",
   "type": "INTEGER",
   "mode": "NULLABLE"
```

そのため、例えばJSONファイルの中でColumn level Security機能のためのpolicy tagを付与するような場合は、tagが付与されていないテーブルはが作られてしまいます。

この挙動が問題になる場合は、JSONファイルが壊れていないかどうかをbqコマンドの実行前に確認するようにしましょう。
なお、この問題はIssueトラッカーには上がっていますが、現時点ではまだ修正されていないようです。

https://issuetracker.google.com/issues/206711857
和音を鳴らす

Scratch 3.0では、音楽ブロックが用意されていて、好きな楽器で音を鳴らすことができます。イベントをつかうと、複数の音を同時に鳴らすことができます。これを利用して、和音（コード）を鳴らすサンプルを用意しました。

まず単音を鳴らすブロック群を用意します。音の名前（例：C, D, Eなど）のイベントで鳴るようにしておきます。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75307/6a0070bd-d06d-846d-7405-6134d61ea07e.png">

次に、これらの音を和音として同時に鳴らすブロック群を用意します。使いやすいようにコード名（例：コードC, コードF, コードG7）などのイベントで鳴るようにしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75307/4b315ff0-0edf-19f1-9f59-8d17950fad3d.png)

これで、コード名のイベントを送ってやれば、和音が鳴ります。

サンプルプロジェクト

https://scratch.mit.edu/projects/609995633

![スクリーンショット](https://cdn2.scratch.mit.edu/get_image/project/609995633_480x320.png)
C#・Java での static クラスの違い

#static について
直訳では、「静的の」意味。
`C#`、`Java`で共通の性質
→`static`メソッドは、メソッドが属しているクラスのインスタンスを生成しなくても使用できる。

#Javaのstaticクラス
`Java`の`static`クラスは、`static`メソッドから呼び出すために設定するクラス。
（これに限って`static`クラスを使うわけではないと思いますが、ここではこの様に説明しておきます）
`static`メソッドの中では、`static`クラスを`new`で生成することができる。
例としては、下記のようなコードになります。
（packageの記述は省略してあります）

```java:sample.java
public class ClassP{
	// staticなメソッド
	private static int methodB() {
		ClassA a = new ClassA();
		a.i += 1;
		return a.i;
	}

	// methodB() で生成するためのstaticなクラス
	private static class ClassA{
		public int i = 5;
	}
}
```

#C#のstaticクラス
`C#`での`static`クラスは、インスタンス化ができない。つまり、`new`で生成することができません。
下記は、Microsoftのドキュメントでの説明です。
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members
つまり、`static`メソッドでクラスをインスタンス化する場合は、クラスは`static`でない必要があります。
上記にある`sample.java`をC#で下記の様になります。

```csharp:sample.cs
public class ClassP{
	// staticなメソッド
	private static int methodB() {
		ClassA a = new ClassA();
		a.i += 1;
		return a.i;
	}

	// methodB() で生成するためのクラス
	// Javaの場合は、ClassA は static である必要がある
	private class ClassA{
		public int i = 5;
	}
}
```

#終わりに
`C#`と`Java`のコードは、`package`の記述の有無や、`use`か`import`かの違いで見分けがつきますが、`static`クラスはどちらにも有り、そのうえで性質が違うので、気を付けたいところですね。
<5> サードパーティ製ライブラリ (Delphi コンカレントプログラミング)

# 5. サードパーティ製ライブラリ

サードパーティ製ライブラリです。使い方を精査した訳ではないので紹介だけしておきます。

:::note warn
間違ってインストールする前に断っておきますが、Delphi のコンポーネントで "Async" というワードを見掛けたら、それは高確率でシリアル通信コンポーネントです。
:::

## 5.1. OmniThreadLibrary
有名所です。GetIt で入手できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/73f561f9-68fc-fa8c-120a-c1167341326a.png)

| プラットフォーム | フレームワーク | ライセンス | 
|:---|:---|:---|
| Windows | VCL | BSD |

**See also:**

 - [OmniThreadLibrary (omnithreadlibrary.com)](http://www.omnithreadlibrary.com/)
 - [OmniThreadLibrary (GetItNow)](https://getitnow.embarcadero.com/OmniThreadLibrary_3.07.9-11/)
 - [「Parallel Programming with OmniThreadLibrary」(LeanPub)](https://leanpub.com/omnithreadlibrary)

## 5.2. Spring4D
**Spring Framework** の Delphi 向け実装です。マルチスレッド専用のライブラリではありませんが、マルチスレッドに関する機能を持っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/898ed110-b27a-cae2-e319-450d4eee732a.png)

| プラットフォーム | フレームワーク | ライセンス | 
|:---|:---|:---|
| Windows | VCL | Apache |

 - [Spring4D (BitBucket)](https://bitbucket.org/sglienke/spring4d/src/master/)
 - [Spring.Utils Namespace (spring4d.4delphi.com)](https://spring4d.4delphi.com/docs/master/Html/index.htm?Spring.Utils)
 - [Spring Framework (Wikipedia)](https://ja.wikipedia.org/wiki/Spring_Framework)
 - [Spring Framework (spring.io)](https://spring.io/projects/spring-framework)

## 5.3. AsyncCalls
Delphi 非同期関数呼び出しフレームワークです。

| プラットフォーム | フレームワーク | ライセンス | 
|:---|:---|:---|
| Windows | VCL | MPL |

**See also:**

 - [AsyncCalls (GitHub)](https://github.com/ahausladen/AsyncCalls)

## 5.4. TBMDThread set
スレッドコンポーネントです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b6f559c5-0e93-c142-c34b-ac51d10ad8d3.png)

| プラットフォーム | フレームワーク | ライセンス | 
|:---|:---|:---|
| Windows | VCL | Freeware |

**See also:**

 - [TBMDThread set (Mitov.com)](https://mitov.com/html/free_downloads.html)


## 5.5. delphi-ppl

Delphi 標準の [PPL](https://qiita.com/ht_deko/items/ee155618119c48bec7b7) / [APL](https://qiita.com/ht_deko/items/eedf3728be2a301a8a5d) を拡張したものです。クラスヘルパーなどが含まれます。

| プラットフォーム | フレームワーク | ライセンス | 
|:---|:---|:---|
| All| All | GPL |

**See also:**

 - [delphi-ppl (GitHub: eStreamSoftware)](https://github.com/eStreamSoftware/delphi-ppl)

#参考

 - [GetItNow (Embarcadero)](https://getitnow.embarcadero.com)
 - [新しいGetIt Webポータル (blogs.embarcadero.com)](https://blogs.embarcadero.com/ja/new-getit-web-portal-ja/)

# 索引
[ [← 4. 並列プログラミングライブラリ (PPL)](https://qiita.com/ht_deko/items/ee155618119c48bec7b7) ] [ [↑ 目次へ](https://qiita.com/items/e8c1ff3a4c74e4c2a4f3) ] [ [→ 6. ミューテックス (同期オブジェクト)](https://qiita.com/ht_deko/items/83cd0ab35c90a9a6cea1) ]
NASDAQの発表をもとに、AWSセキュリティを考える

Ambassadorアドベントカレンダー１２日目です！

[去年はDevOps Guruについて書いた](https://qiita.com/Hiroyama-Yutaka/items/4f4622610fcd329a879b)のですが、技術者向けな内容でした。
今年は志向を変えて、ユーザーやセールス向けの記事を書いてみたいと思います。

# NASDAQがAWSにくるー
個人的に、今回のre:Inventでもっとも印象に残る発表でした。
以前、イベントでブースに立っていたときに、「AWSについて説明してください」と言われて頑張って説明したのちに、「せっかくですが、自分、金融なんでクラウド使う気ないんですけどね」と嘲笑して去っていったあの人は何を思うのか。

## 何故、NASDAQはAWSを選んだのだろうか
[ケーススタディ](https://aws.amazon.com/jp/solutions/case-studies/nasdaq-case-study/)では、[Amazon Redshift](https://aws.amazon.com/jp/redshift/)と[Amazon S3](https://aws.amazon.com/jp/s3/)の性能や可用性（これもセキュリティの一部ですが）にフォーカスされています。
もちろん、これらのサービスはすばらしく、選定のキーになったことは事実と思います。

個人的には、これに加え、[AWS Outposts](https://aws.amazon.com/jp/outposts/)の存在も大きいと考えています。AWS Outpostsを端的に説明すると、自身のサーバーラック上にAWSサービスを構築できるといったものです。
証券取引処理という、非常に高いパフォーマンスの求められるシステムにおいて、AWSのデータセンターまでのトラフィックを気にしなくて済むAWS Outpostsは、今回の選定に大きな影響を与えたと思います。
AWS Outpostsについては、発表後、対応サービスも増やし続けている上、ラック上の１、２ユニットに格納できるような拡充もされています。PCI DSSやFISCなど、あらゆる
AWS Outpostsは、あらゆる環境において「オンプレミスでなければいけない」という制約を取っ払う存在ではないでしょうか。

# クラウドのセキュリティって安全なの？
小型版が出たとはいえAWS Outpostsは、ある程度の規模以上向けの選択肢です。
そうでない環境において、AWSはセキュリティ上、安全といえるのでしょうか？
僕が答えるならば、「正しく使えば安全です」になります。
責任共有モデルにおいて、カスタマー領域で適切なセキュリティ対策をしなければ、危険にさらされます。
これは、クラウドに限らずです。
ただ、アクセスキーを流出させたことにより、マイニングのために世界各国のリージョンに大量の高価なインスタンスを大量に立ち上げられるような事象は、オンプレでは発生しませんでした。この点では、慎重に取り扱う必要があります。
![General-Shared-Responsibility-Model-on-AWS.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/335708ef-5ce1-e8a3-3732-c15eed81e9a4.jpeg "AWS の一般的な責任共有モデル")

一方、AWS領域においては、一般的にはセキュアになると考えます。
情報セキュリティの三大要素「可用性」「機密性」「完全性」を、AWSは非常に高レベルで提供します。
当然、自前で構築することも論理的には可能ですが、設備投資、人的リソース、運用、あらゆる面でかかるコストを考えると、同一レベルを自前構築できるところは、極々わずかです。
何を持って高レベルなのかは、[AWSが所有するコンプライアンスプログラム](https://aws.amazon.com/jp/compliance/programs/)の要項を参照いただければと思います。
例えば、自社でPCI DSS認証を得る場合、オンプレミス環境で取る場合であれば、物理レイヤーについても監査を受ける必要があります。しかし、AWSであれば、AWS側のAOCを提出することでOKになります。

さらに、AWSでは、マネージドサービスの進化がすごいです。
マネージドサービスの利用により、責任共有モデルのカスタマー領域はさらに縮小します。
![Shared-Responsibility-by-Service-Type.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/3ecd9972-d89f-20c2-dfc0-76c974200ccd.png "タイプ別責任共有モデル")
当然、環境としての自由度はIaaSに軍配が上がるため、何でもかんでもマネージドサービスには向かないですが、可能であればマネージドサービスにすることで、AWSが提供するセキュリティレベルを享受できる領域が広がります。

# まとめ
NASDAQの事例は、今後の日本でのクラウド拡大においてもいいニュースだと思っています。
この発表は、とくに目新しい機能発表ではないです。これまでも時間さえいただければ説明できたAWSのセキュリティの範囲内です。
しかし、これまでクラウドは門前払いだった方々にも、「あのNASDAQさんも採用されましたよ」と言えば、刺さる要素になるかと思っています。

これを機に、国内でのクラウド導入が加速することを願ってます。

# 参照
https://aws.amazon.com/jp/blogs/news/applying-the-aws-shared-responsibility-model-to-your-gxp-solution/
https://www.nasdaq.com/Nasdaq-AWS-cloud-announcement
WebブラウザでPDFのページにしおりをはさむやり方

# Webブラウザで開いたPDFのページにしおりをはさむやり方

PDFをブラウザで開いて、アドレスバーに「#page=ページ番号」（下の画像の青色のところ）を書いて開きなおすと、ページ番号で選んだページまでスクロールされた状態になります。（下の画像の黄色のところ）

![WebブラウザでPDFのページにしおりをはさむやり方.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58020/56d4de5b-0b52-281f-88a3-f15acd6badc0.png)

この状態でブックマークすると、そのページでブックマークされるので、また読み始めたり、読み返すときに便利です。
【How to JUCE】juce::Component で自分以外の何かがクリックされた際に処理をしたい！

本記事は[JUCE Advent Calendar 2021](https://qiita.com/advent-calendar/2021/juce) の12月5日向けに投稿した記事です。

# はじめに
こんにちは、Takacie です。
2021年も終わりに近づいてきましたね。
僕は先月、C++ のクロスプラットフォームアプリケーションのフレームワークである JUCE を用いたオーディオプラグイン "iR Reverb" を booth にてリリースしました。
その際に、パラメーター郡をプリセットとして読み書きするための独自のプリセット機能を作りました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590112/71e3ac8c-6fdc-e5bb-9da9-a2cab749832e.png"  width="500" />
画像の "(default)" と書いてあるボタンをクリックすると、プリセット一覧が表示されるのですが、これを閉じるためにもう一度このボタンをクリックしなければならないのはユーザーエクスペリエンス的に良くないなと思いました。
そこで、ある [juce::Component](https://docs.juce.com/master/classComponent.html)（以降 Component ）を開いている状態で、その Component 以外をクリックしたときに処理（自分のケースだとプリセット一覧を閉じる処理）をしたいとき、どうすればよいのかを書いていこうと思います。

# 調べたこと
まず、当然と言えば当然なのですが、Component で定義されている [Component::mouseDown(const MouseEvent&)](https://docs.juce.com/master/classComponent.html#a2a908e064b0bfed1ea0a75b0a0fee6dd) などのマウスイベントには、自身以外をクリックしたときのイベントは存在しません。
どうしたものかと調べていると、JUCE のフォーラムで以下の投稿を見つけました。

[SOLVED] Hiding a component when a user clicks outside of its bounds -
https://forum.juce.com/t/solved-hiding-a-component-when-a-user-clicks-outside-of-its-bounds/41390

ここで回答として出されているのは「マウスリスナーの代わりに、該当のコンポーネントを表示する際に、その下にUI全体を覆う半透明のコンポーネントを一緒に表示し、後者をクリックした際に両方とも非表示にする」というものです。
確かに、僕が言っているような処理はできそうですが、そのようなコンポーネントを作る度に半透明のコンポーネントを用意するのも面倒なので、この案は却下しました。

他にも [Desktop::addGlobalMouseListener(MouseListener*)](https://docs.juce.com/master/classDesktop.html#add528b1597a432f2e4cb9b10314fc210) を使うという手などもありましたが、該当コンポーネントがクリックされた際には処理しないなど、実装がややこしくなりそうなので、これも却下です。「UI のどこかがクリックされる度に該当コンポーネントの色を変化させたい」とか、そういうケースの場合は、この手法を使うといいのかなと思います。

Clicking outside component -
https://forum.juce.com/t/clicking-outside-component/18006

# 解決策
Component は [Component::enterModalState(引数略)](https://docs.juce.com/master/classComponent.html#a0e7be8c456a663615eb389ecd10b2c04) を実行することでモーダルな状態にすることができます。

```cpp
juce::Component* some_component;
// ... //
some_component->enterModalState(); // some_componentはモーダルな状態になる
```

モーダルな状態になっているということは、親コンポーネントの操作を一切受け付けなくなるということです。
「え？一切受け付けないのならマウスイベントも拾えないじゃん！」となりそうですが大丈夫です。

該当コンポーネントがモーダルな状態で、親コンポーネント（自身以外のコンポーネント）をクリックした際に [Component::inputAttemptWhenModal()](https://docs.juce.com/master/classComponent.html#a260e46fb72d4b3210bc46a658a21fbb5) が呼ばれます。デフォルトでは「他のコンポーネント触りたいならこのコンポーネントを閉じな！」と、システムのアラート音を鳴らすだけなのですが、これをオーバーライドしてやって、[Component::exitModalState(int)](https://docs.juce.com/master/classComponent.html#a686e2440370ff4a97c7a7851907be650) でモーダルな状態を抜ける処理を含めると、タイトルを回収することができます。

```cpp
class SomeComponent : public juce::Component {
public:
  // ... //

  void inputAttemptWhenModal() override
  {
    exitModalState(0); // モーダルな状態を抜ける（タイトル回収には必須）
    // 以下にやりたい処理を書いていく
    // 今回は自身を非表示にする処理を行う
    setVisible(false); // コンポーネントを非表示にする
  }

  // ... //
};
```

簡単です。

# おわりに
様々なケースで使えそうですが、モーダルにすると都合の悪い場合もあります。その場合は、前述した [Desktop::addGlobalMouseListener(MouseListener*)](https://docs.juce.com/master/classDesktop.html#add528b1597a432f2e4cb9b10314fc210) を使う必要があると思います（実装してみないと分からないので詳細略）。

【How to JUCE】、このくらいの規模だったらシリーズ化してみてもいいかもなー
Cloud DLPで特定のBigQueryデータセットの中身を全部スキャンする

GCPにはCloud DLPという個人情報(っぽく見える情報)が含まれていないかを機械学習で自動的に検知するサービスがあります。

https://cloud.google.com/dlp

このサービスを使うと、BigQueryやCloud Storageなどに個人情報が格納されてないかをチェックできます。
GCPのwebコンソールからスキャンするとテーブル1つ１つ単位でしかチェックができません。
データセットの中身全てをチェックしようとすると煩雑だったために、データセット内の全てのテーブルをスキャンするスクリプトを作りました。

```py
import google.cloud.dlp
from google.cloud import bigquery

def scan(project_id, dataset_name, table_name):
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # 以下を参考に検知したい情報を列挙する
    # https://cloud.google.com/dlp/docs/infotypes-reference
    info_types = [
      "CREDIT_CARD_NUMBER",
      "EMAIL_ADDRESS",
      "GCP_CREDENTIALS",
      "IMEI_HARDWARE_ID",
      "IP_ADDRESS",
      "MAC_ADDRESS_LOCAL",
      "MAC_ADDRESS",
      "PHONE_NUMBER",
      "PASSPORT",
      "ADVERTISING_ID",
      "AGE",
      "CREDIT_CARD_TRACK_NUMBER",
      "DATE_OF_BIRTH",
      "FEMALE_NAME",
      "FIRST_NAME",
      "GENDER",
      "JAPAN_BANK_ACCOUNT",
      "JAPAN_DRIVERS_LICENSE_NUMBER",
      "JAPAN_INDIVIDUAL_NUMBER",
      "JAPAN_PASSPORT",
      "LAST_NAME",
      "MALE_NAME",
      "PERSON_NAME",
      "STREET_ADDRESS",
    ]
    info_types = [{"name": info_type} for info_type in info_types]

    inspect_config = {
        "info_types": info_types,
        "min_likelihood": "POSSIBLE",
        "limits": {},
        "include_quote": True,
    }

    storage_config = {
        "big_query_options": {
            "table_reference": {
                "project_id": project_id,
                "dataset_id": dataset_name,
                "table_id": table_name,
            },
            "sample_method": "RANDOM_START",
            "rows_limit_percent": 1, # テーブル全体の何%をスキャンするかを指定。大きくしすぎると費用がかかるので注意。
        }
    }

    # 発見した個人情報を格納するデーブルを指定
    actions = [
        {
            "save_findings": {
                "output_config": {
                    "table": {
                        "project_id": project_id,
                        "dataset_id": "dlp_result",
                        "table_id": f"{dataset_name}_{table_name}",
                    }
                }
            }
        }
    ]

    inspect_job = {
        "inspect_config": inspect_config,
        "storage_config": storage_config,
        "actions": actions,
    }

    parent = f"projects/{project_id}/locations/global"
    operation = dlp.create_dlp_job(
        request={"parent": parent, "inspect_job": inspect_job}
    )
    print("Inspection operation started: {} {}.{}".format(operation.name, dataset_name, table_name))

project_id = 'プロジェクトIDを指定'
dataset_id = 'データセット名を指定'

sql = f"SELECT table_name FROM {project_id}.`region-us`.INFORMATION_SCHEMA.TABLES;"

bq_client = bigquery.Client()
for row in bq_client.query(sql):
    table_name = row[0]
    scan(project_id, dataset_name, table_name)
```
「ビルド」「デプロイ」「リリース」についてまとめました



##概要
出席した会議で「ブルーグリーン」「イミュータブル」っていう言葉を聞き、
何のこっちゃ分からんので調べてみました。


理解が曖昧だった「ビルド」とか「デプロイ」についても再認識できました。


https://www.bold.ne.jp/engineer-club/deploy#i-2

以下、この記事の概要とか単語などを簡単に纏めているだけです。

##用語




####「ビルド」とは
ソースコードをコンパイル（PCが読める文字に翻訳）して
複数ファイルをくっつけて１つの実行ファイルにまとめること


####「実行ファイル」とは
拡張子が「.exe」で、それ単体で動かせるプログラムファイル
中身がバイナリ（2進数で表現されたデータ）になっている


####「リリース」とは
アプリケーションを公開することで、本番環境にリリースするとユーザが利用できる
「ローンチ」とほぼ同じ意味


####「デプロイ」とは
リリースの一部作業
実行ファイルを動かしたい環境において、その実行ファイルを実行すること
基本的に、アプリの一時停止やサーバ再起動が発生する
そのような「ダウンタイム」が発生しないデプロイを「ホットデプロイ」という


##「デプロイ」の種類
「デプロイ」にはいくつか種類があります
ここに私が会議で耳にした用語も入っていました

　　1.　ブルーグリーン
　　2.　イミュータブル
　　3.　シンボリック
　　4.　ローリング



####１. ブルーグリーンデプロイメント
・「ブルー」と「グリーン」のに２環境を準備する
・現在の本番環境を「ブルー」で動かしたまま、新環境を「グリーン」にデプロイする
・デプロイ完了後、「グリーン」に切り替えることで、旧環境から新環境へアップデート

補足）
・新環境に問題があったら「ブルー」に切り替え
・簡単にロールバック（元の状態に戻すこと）ができる、ダウンタイムもほぼ発生しない
・問題なく切り替えが出来たら今までの「ブルー」が「グリーン」になる


####２. イミュータブル
・「ブルーグリーン」を利用したもの
・違いは、新環境への切り替え後問題が無ければ、旧環境を破棄すること
・よって「ブルーグリーン」とは違って、旧環境の運用コストがかからない


####３. シンボリック
・運用中のサーバ上の別の場所に新しいファイルを配置
・サービスが利用するシンボリックリンクを変更すると新しいアプリに切り替え


####４. ローリング
・複数あるサーバに対し、順番にロードバランサーから切り離してデプロイする手法



##まとめ
かなり簡単ではありますが
「ビルド」「デプロイ」「リリース」の要点をまとめました！

初めてのqiita投稿でもあったので
レイアウト的に読みにくいかもです...


qittaの書き方もマスターしつつ、沢山アウトプットして
一人前エンジニアになるよう頑張りますー