OmniAICreator/Qiita-1.07M huggingface dataset:
アドベントカレンダーに初参加するためにとりあえず何かいろいろ書いた話

#はじめに
　この記事は[アドベントカレンダー初参加する人を応援したい、アドベントカレンダーに参加したきっかけアドベントカレンダー Advent Calendar 2021](https://qiita.com/advent-calendar/2021/sanka-kikkake)の16日目の投稿です。
　実際にアドベントカレンダーに初参加なので、参加するにあたってとりあえずいろいろ書いてやろうという記事です。~~ITなんて全く関係のない記事になります。さもありなん。~~

#Qiitaを始めたきっかけ
　そもそもQiitaを始めたのは2021年の3月の末頃になります。面白い記事なんて書けるはずもないので、隙間時間にとりあえず備忘録でも作ってやろうと思い至ったのが始まりになります。
　隙間時間も、書きたいような備忘録もないのでしばらく離れていましたが、最近再び書く機会がありましたので戻ってきました。~~所謂、N番煎じのクソ記事量産マシンです。~~

　ちなみに登録するまでの期間もQiitaの記事は購読していましたが、実際にQiitaで何か自分の意見を残そうと思い至ったのは2021年に入ってからになります。

#アドベントカレンダーとの出会い
　私は、~~所謂クソ記事量産マシンなだけでなく~~知識が広く浅くタイプなので、アドベントカレンダーに記事を読む分には非常に楽しめました。特に[クソアプリ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kuso-app)には笑わせて貰いました。
　そして、人は面白い記事を読んでいると自分も参加したい、書きたいと思うようになるものです。しかしながら私は**浅い知識しか持ち合わせていないタイプの人間**なので、いざ書こうと思い至っても何も書けないという事態に陥った訳ですね。いろいろ手を出して入門だけ勉強して内容が理解できるようになったらすぐに他のことに手を出して、理解を深めなかったのが裏目に出た訳です。

#神カレンダーとの出会い
　さて、そんな私の前に神カレンダーが舞い降りました。それがこの、[アドベントカレンダー初参加する人を応援したい、アドベントカレンダーに参加したきっかけアドベントカレンダー Advent Calendar 2021](https://qiita.com/advent-calendar/2021/sanka-kikkake)ですね。こんな何も書けない私でもこんな記事を通してアドベントカレンダーに参加するきっかけをくれる神カレンダーになります。
　そして、この神カレンダーにこのクソ記事を紐づけます。~~はい！記事書いてる今現在結び付けました！！神カレンダーはもうこのクソ記事から逃げられません！！！~~

#今後の意気込みなど
　当たり前ですが、この記事でアドベントカレンダーに参加した気になるのは、やはり何かいろいろ違うような気がします。

>アドベントカレンダーに参加したいが参加をためらっていた当時の自分がほしかったもの作りました。このアドベントカレンダーをきっかけに今後の技術記事作成につながればヨシという考え方です。より良い記事が共有される文化にしたいです。

　アドベントカレンダー自体の「作成のきっかけ」にもこうして書かれていますが、あくまでもこの記事を**参加するきっかけ**として活用して、今後参加するハードルを下げていけたらいいなと思っています。
　今後は、簡単なものからでも順番に一歩ずつ技術的な記事を書くようにして、いつかは面白い記事を書けるように精進していきたいと思います。

#さいごに
　中学生くらいの感想文か、始めたてのブログのような記事になってしまいました。一応、カレンダーにある記事は全て読みましたし今後上がる記事も全部読む予定です。一つ一つリンク貼って感想を書こうかと思いましたが、~~さすがにちょっと恥ずかしいので~~やめました。

　さて、本当に最後にはなりますが、このようなカレンダーを作っていただき、参加の機会を設けて頂いてありがとうございました。
　そしてここまで読んでまだ記事を書いたことがないという人はぜひ一度何か知識を書いてみませんか？おそらくこの記事よりずっと興味深く面白い記事ができると思います。
　まだ見ぬ誰かの背中を押して、そして自分がこれからちゃんと記事を書いていくという意気込みを書き残してこの記事を終わりにしたいと思います。ここまで読んで頂いて本当にありがとうございました。
レプリケーションとスナップショットの違い


# はじめに
- 恥ずかしながら、レプリケーションとスナップショットの言葉の定義が曖昧だったので備忘として記録します。
- こちらも恥ずかしながらですが、Qiita初投稿となります。笑
 
#対象者
- 最近インフラ周り、クラウド系の技術知識を勉強し始めた方（AWSとかの勉強をしていても良く出てくる言葉ですよね）
- スナップショット、レプリケーションの認識が曖昧な方

# レプリケーションとスナップショットとは
###レプリケーション
- レプリケーションを一言で表すなら「異なる場所にデータの複製を作る」というデータ保護方式のことになります。
- Replication：複製
- 後ほど説明するスナップショットとの大きな違いになりますが、レプリケーションは「データ自体」を保存し、ある時点、あるいは、リアルタイムでストレージAとまったく同じ状態を別のストレージBに複製します。
- 大きなメリットとしては、以下のような感じかと思います。

1. 遠隔地（他のサイトなど）にデータコピーできるため、レプリケーションをディザスタ・リカバリ(DR)として使用することが可能です。
例えば、ストレージAに何らかの問題があったとしても、予備のシステム（ストレージB）を稼働させることで、障害からの復旧時間を最小限に食い止めることが可能です。
2. 障害対策だけではなく、読み取り処理を分散できるなど負荷分散の面でも利点があります。
例えば、多くの参照リクエストが想定されるようなシステムにおいて、リードレプリカ(読み取り用ノード)に参照の処理を分散し、一方で、マスターノードは更新処理のみを行うといった負荷分散が可能になります。

- 図1 レプリケーションイメージ
![レプリケーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/10cee707-683f-95b4-2ee6-2f0fbdabd001.png)

###スナップショット
- 続いてスナップショットの説明になりますが、こちらを一言で表すなら、「ある瞬間のデータを切り取る」というバックアップ方式になります。データが変化した(更新された)部分だけを時間毎に記録しているのでスナップショットの保存領域は元データの1割~2割程度となります。バックアップでは容量が2倍になりますが、そうならないのは、OS情報等が割愛され、ファイルはブロック単位のデータとして圧縮されているためです。完成したスナップショットはプライマリストレージからセカンダリストレージにコピーされ削除されるか、新しいスナップショットによって消去されるまで格納されます。
- Snapshot：瞬間を切り取ったモノ
- レプリケーションと大きく違う部分になりますが、スナップショットで記録するのは、メタデータ（対象となるボリュームやLUN(Logical Unit Number)に加わった変化のI/O）であり、バックアップではないことに注意が必要です。
- サイト間バックアップを行いたい場合は、例えば仮想マシンのスナップショットからテンプレートを作成することで対応可能です。
- 大きなメリットとしては、以下のような感じかと思います。

1. ストレージがウイルス感染やシステム障害によってデータ復旧ができない状態でも、定期的にスナップショットをしておくことで、取得時点にシステムをリストアすることが可能です。そのため「データ可用性」を担保するために欠かせない機能の1つです。
2. 通常のバックアップと比較し保存領域が小さいため、データのコピーが非常に高速で、また、ストレージ性能に影響を与えにくいです。取得間隔や、何世代分保持するかを設定することが可能です。

- 図2 スナップショットイメージ

①スナップショットを取得　②データ更新後のスナップショット
![スナップショット1213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/a3d92326-5616-1921-6d74-e599303cfdfa.png)

#おわりに
・今回は、レプリケーションとスナップショットの特徴について解説しました。
・引き続き、アウトプットできる知識の吸収を意識し、勉強に勤しみます。
・それでは！

#参考文献
[Qiita書き方](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
[NetAppストレージ機能①](https://www.storage-channel.jp/blog/what-is-snapshot.html#toc-0/　"スナップショット")
[NetAppストレージ機能②](https://www.storage-channel.jp/blog/snapshot-replication.html#toc-2/"レプリケーションとスナップショットの違い")
[py2rb] os.path.splitext

# はじめに
移植やってます
# os.path.splitext (Python)
```python
import os

print(os.path.splitext("/C/Users/users/Documents/text.txt"))
print(os.path.splitext("C:\\Users\\users\\Documents\\text.txt"))

# ('/C/Users/users/Documents/text', '.txt')
# ('C:\\Users\\users\\Documents\\text', '.txt')
```
拡張子の切り分けです。
~~正規表現でやってもいいと思いますが。~~ ファイルを変換するして保存する際に使用されます。

https://docs.python.org/ja/3/library/os.path.html
# Pathname#sub_ext (Ruby)
```ruby
require "pathname"

p1 = Pathname("/C/Users/users/Documents/text.txt")
p2 = Pathname("C:\\Users\\users\\Documents\\text.txt")

puts "#{p1.sub_ext('')} #{p1.extname}"
puts "#{p2.sub_ext('')} #{p2.extname}"
puts p2.sub_ext('.xml')

# /C/Users/users/Documents/text .txt
# C:\Users\users\Documents\text .txt
# C:\Users\users\Documents\text.xml
```

https://docs.ruby-lang.org/ja/latest/method/Pathname/i/sub_ext.html
# メモ
+ Python の os.path.splitext を学習した
+ 道のりは遠そう
Macでショートカットキー（command + ` )が効かなくなった件

「次のウィンドウを操作対象にする。」が効かない。。

＜現象＞
OS11（big sur)までは
「command + shift + @　」 
だったはずが、
OS12(monterey)で効かなくなった。。

＜原因＞
どうやらデフォルトのショートカットが変わったように思える。
「command + @　」に変更のようだ。 

＜対処法＞
以前は
「command + `　」となっていたが、 
そこで、
「デフォルトに戻す」を押すと
何とか直りました。
![969EA584-45CD-4576-9013-7195634E5CB5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374784/dec6d652-0af9-bc0c-0a08-d339997873e2.jpeg)

取り急ぎお知らせします。
OCI NSGルールの確認

### nsgのid抜き出し
oci network nsg list -c $compartment

### rule抜き出し
oci network nsg rules list --nsg-id ocid > nsg_rules.json

cat nsg_rules.json | jq -r '[.data[] | keys]'
基本的に.data[]以下で下記のKeyがある
```
  [
    "description",
    "destination",
    "destination-type",
    "direction",
    "icmp-options",
    "id",
    "is-stateless",
    "is-valid",
    "protocol",
    "source",
    "source-type",
    "tcp-options",
    "time-created",
    "udp-options"
  ]
```
  必要なものを抜き出して確認出来れば楽なのだが、"tcp-options"が曲者（多分UDPも）
  下記の感じでrangeでデータが入ってたりする。
```
        "tcp-options": {
        "destination-port-range": {
          "max": 3389,
          "min": 3 # 3389で開けているのだが何故3が入っているかは謎
        },
```

とりあえず下記で抜き出す。もっとコンパクトに出来ないものか
```
cat nsg_rules.json | jq -r '.data[] | { direction: .direction, sorce: .source, protocol: .protocol, tpc: .\"tcp-options\", udp: .\"udp-options\" } '
{
  "direction": "INGRESS",
  "sorce": "****",
  "protocol": "all",
  "tpc": null,
  "udp": null
}
省略
{
  "direction": "INGRESS",
  "sorce": "0.0.0.0/0",
  "protocol": "6",
  "tpc": {
    "destination-port-range": {
      "max": 3389,
      "min": 3389
    },
    "source-port-range": null
  },
  "udp": null
}
```

### EGRESS/INGRESS抜き出し
```
cat nsg_rules.json | jq -r '.data[] | { direction: .direction, sorce: .source, protocol: .protocol, tpc: .\"tcp-options\", udp: .\"udp-options\" } ' | jq -r 'select( .direction == \"EGRESS\" ) '
cat nsg_rules.json | jq -r '.data[] | { direction: .direction, sorce: .source, protocol: .protocol, tpc: .\"tcp-options\", udp: .\"udp-options\" } ' | jq -r 'select( .direction == \"INGRESS\" ) '
```
Rails6をはじめて動かしたときにWebpackerに関するエラー

Rails6.0.3
nodejs14
ubuntu 18.04

# Rails sでWebpackerがないとエラーが出る
（エラーが出る理由）
Rails6ではWebpackerがデフォルトで採用されており、これがjapascriptをコンパイラする
なのでRails6を動かそうとしたときにWebpackerがないというエラーが出てしまう

# 解決手順

1. Webpackerをインストールするために必要なパッケージマネージャーyarnをインストールする
2. yarnインストール後にWebpackerをインストールする

# 実際の作業
### yarnのインストール
Yarnのレポジトリを有効化する
 
```
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
```

次にYarnのAPTパッケージレポジトリを自分のシステムに追加する。 teeコマンドを使って書き込み。

```
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
```

レポジトリがシステムに加えられたらパッケージリストをアップデートしてからYarnをインストールする

```
sudo apt update
sudo apt install yarn
```

後はyarnのバージョンを確認して入っていたらOK

### Webpackerをインストール

下記のコマンドでrailsにWebpackerをインストールできます。

```
rails webpacker:install
```

#Webpacker:installでnodejsのバージョンがあわないとエラーが出た時の対処法
nodejsのバージョンが古い可能性があるのでnodejsの新しいバージョンを入れてあげる手順は下記より

- リポジトリに追加(〇の部分は入れるバージョンを指定する)

```
curl -sL https://deb.nodesource.com/setup_〇.x | sudo -E bash -

```

- nodejsのインストール

```
sudo apt install nodejs
```
これでnodejsのバージョンを変えてからもう一回Webpacker:installを試してみる。
デベロッパーアドボケイトを募集しています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345032/8cf37a35-83c1-5116-5a8c-7b1300c3bb66.png)

デベロッパーの支持者となるために、ぜひチームに参加してください。グローバルに成長するデベロッパーリレーションズチームに参加して、たくさんの楽しい活動をしましょう。

Snykユーザーとそれ以外の開発者コミュニティを構築し、成長させるために、経験豊富で実践的かつ自己管理能力の高いコミュニティマネージャーおよびアドボケイトを募集しています。 教育、関与、ネットワークプログラムを通じて、コミュニティマネージャー/アドボケートは、日本地域全体でDevSecOpsプラクティスおよびSnykの開発者優先のセキュリティプラットフォームの認識と採用を推進します。 

何か質問があれば、メッセージをください。

[求人情報へのリンク](https://snyk.io/jobs/developer-advocate-japan-2/)
nvm-windowsでNode.jsの環境構築

* 任意のバージョンを使用したい場合に対応出来るようnvm-windowsを使用するための手順メモ。

---
## nvm-windowsインストール

* nvm-setup.zipをDLしてインストールする  
  https://github.com/coreybutler/nvm-windows/releases

## 利用できるバージョンの確認

```shell
> nvm list available

|   CURRENT    |     LTS      |  OLD STABLE  | OLD UNSTABLE |
|--------------|--------------|--------------|--------------|
|    17.2.0    |   16.13.1    |   0.12.18    |   0.11.16    |
|    17.1.0    |   16.13.0    |   0.12.17    |   0.11.15    |
|    17.0.1    |   14.18.2    |   0.12.16    |   0.11.14    |
|    17.0.0    |   14.18.1    |   0.12.15    |   0.11.13    |
|   16.12.0    |   14.18.0    |   0.12.14    |   0.11.12    |
|   16.11.1    |   14.17.6    |   0.12.13    |   0.11.11    |
|   16.11.0    |   14.17.5    |   0.12.12    |   0.11.10    |
|   16.10.0    |   14.17.4    |   0.12.11    |    0.11.9    |
|    16.9.1    |   14.17.3    |   0.12.10    |    0.11.8    |
|    16.9.0    |   14.17.2    |    0.12.9    |    0.11.7    |
|    16.8.0    |   14.17.1    |    0.12.8    |    0.11.6    |
|    16.7.0    |   14.17.0    |    0.12.7    |    0.11.5    |
|    16.6.2    |   14.16.1    |    0.12.6    |    0.11.4    |
|    16.6.1    |   14.16.0    |    0.12.5    |    0.11.3    |
|    16.6.0    |   14.15.5    |    0.12.4    |    0.11.2    |
|    16.5.0    |   14.15.4    |    0.12.3    |    0.11.1    |
|    16.4.2    |   14.15.3    |    0.12.2    |    0.11.0    |
|    16.4.1    |   14.15.2    |    0.12.1    |    0.9.12    |
|    16.4.0    |   14.15.1    |    0.12.0    |    0.9.11    |
|    16.3.0    |   14.15.0    |   0.10.48    |    0.9.10    |

This is a partial list. For a complete list, visit https://nodejs.org/en/download/releases
```
ここに表示されないバージョンが利用できるかはここで確認。
https://nodejs.org/en/download/releases/

## インストール

```shell
>nvm install 16.13.1
Downloading node.js version 16.13.1 (64-bit)...
Extracting...
Complete


Installation complete. If you want to use this version, type

nvm use 16.13.1
```

## 有効化
```shell
>nvm use 16.13.1
Now using node v16.13.1 (64-bit)
```

## 確認
```shell
>nvm list

  * 16.13.1 (Currently using 64-bit executable)
```

## コマンドメモ
```shell
# ローカルにインストール済みのバージョン一覧表示
nvm list 
# インストール可能なバージョン一覧表示
nvm list available
# 任意のバージョンをインストール
nvm install x.x.x
# 指定したバージョンを有効にする
nvm use x.x.x
# ローカルからアンインストール
nvm uninstall x.x.x
```
Power Automate で文字列の最初の一文字目を大文字に変換する

Power Automate を利用していて、システムから出力される結果が小文字だったものを、最初の一文字目だけ大文字に変換したいと思いました。例えば「first letter」を「First letter」に変換したいという感じです。

どうやら、こうした変換は関数を使わなければできないようだったので、忘れても良いようにメモしておきます。

```
concat(
    toUpper(
        first('first letter')
    ),
    substring(
        'first letter',
        1,
        sub(
            length('first letter'),
            1
        )
    )
)
```

内容は単純です。toUpper(first('first letter') で、文字列の一文字目だけを取り出し大文字にします。substring(....) で、文字列の二文字目以降を抜き出しています。それらを concat を使って連結して完成です。
[py2rb] yield

# はじめに
移植やってます
# yield (Python)
```python
class A:
    def sequence():
        yield "1回目"
        yield "2回目"
        yield "3回目"

seq = A.sequence()
print(seq.__next__())
# 1回目
print(seq.__next__())
# 2回目
print(seq.__next__())
# 3回目
```
呼び出し側は、`__next__()`をやっているだけで、状態はレシーバが覚えています。
# yield (Ruby)
```ruby
class A
  def sequence
    Fiber.new do
      Fiber.yield "1回目"
      Fiber.yield "2回目"
      Fiber.yield "3回目"
    end
  end
end

seq = A.new.sequence()
puts seq.resume
# 1回目
puts seq.resume
# 2回目
puts seq.resume
# 3回目
```
上記プログラムで4回目の呼び出しを行うと、`Python`はエラー、`Ruby`はnilを返します。

https://docs.ruby-lang.org/ja/latest/class/Fiber.html
# メモ
+ Python の yield を学習した
+ 道のりは遠そう
Chrome 97のDevToolsに実装されるブラウザ操作記録についての活用方法を考える

この記事は[セゾン情報システムズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/sisco) 15日目の記事です。

# 背景
ブラウザの操作を記録する機能が Chrome のバージョン 97 に実装されます。
参考記事: https://www.publickey1.jp/blog/21/chrome_97devtoolswebpuppeteer.html
特別なツールのインストールも不要、Chrome のバージョンアップのみで対応できるので活用方法を考えてみたいです。
#### 補足
- 97 は2022/1 にリリース予定。
- 今すぐ試したい場合は　デベロッパー向け Google Chrome をインストールすることで機能を確認できます。
  - https://www.google.com/intl/ja/chrome/dev/

# 使い方(ブラウザの操作記録)
1. Chrome 97 を用意して起動
1. 適当なページを開く
1. `F12` 押下などでデベロッパーツールを起動
1. 歯車横の「:」をクリック → More Tools → Recorderを選択
1. 「Start new recoding」ボタンをクリック
1. 適当な名前を入力
1. Start new recoding ボタンをクリック
1. ブラウザを操作
1. End recoding ボタンをクリック
1. ゴミ箱アイコンの横にある上矢印のエクスポートボタンをクリック
1. 記録した操作を javascript で保存できる

# 活用方法を考える
## E2E(End to End) テストの実装
エクスポートされるのは [puppeteer](https://github.com/puppeteer/puppeteer) のコードです。
puppeteer はヘッドレスでブラウザを操作できるライブラリで E2E テストでよく使われます。
本来はブラウザの操作を javascript で記述していくのですが、その手助けになるかもしれません。

#### エクスポートされたスクリプトとゼロからのテストの比較
エクスポートされたスクリプトの抜粋です。他には共通で使用する関数も生成されています。

```javascript
  {
    const targetPage = page;
    const promises = [];
    promises.push(targetPage.waitForNavigation());
    await targetPage.goto("https://www.hulft.com/");
    await Promise.all(promises);
  }
  {
    const targetPage = page;
    const element = await waitForSelectors(
      [
        ["aria/サイト内検索"],
        [
          "body > div.ccm-page.ccm-page-id-1.page-template-top > header > div > div > div.header-menu-content.toggle-menu-content > div > div > div.header-search > form > p > input[type=text]",
        ],
      ],
      targetPage
    );
    await element.click({ offset: { x: 125, y: 8 } });
  }
```

puppeteer のテストのサンプル(https://zenn.dev/at946/articles/2681c3fec1d9bf より)

```javascript
describe('サンプルテストスイート', () => {
  test('トップページでアプリ名が表示されていること', async () => {
    await page.goto('http://localhost:3000')
    await expect(await page.$eval('h1.title', el => el.innerText)).toBe("app")
  })
})
```

エクスポートされたスクリプトはあくまでも puppeteer のスクリプトです。
E2E テストとするためには、Jest などのフレームワークと合わせてテストにする必要があります。
テストする操作が大量に存在する場合は、エクスポートしたスクリプトを参考にすることで工数が削減できるかもしれません。

## バグレポートに添えて
Jira や GitHub Issue でバグレポートをする際、再現手順やスクリーンショットを提供することが多いかと思います。
しかし、開発者側で再現せず認識合わせに時間がかかることもままあります。
このような場合にブラウザ操作のスクリプトを添付することで確実な再現手順を提供できるかもしれません。
バグ修正時に前述の E2E テスト実装の参考にしたり、事象を確認するためにスクリプトを動かすことなどもできます。

#### スクリプトを実行してブラウザの動きを見る
1. node をインストール
1. 適当なフォルダで `node init` して初期化
1. `npm i puppeteer` で puppeteer を追加
1. エクスポートしたスクリプトのファイルをコピーする
1. vscode などで開く
1. 以下を参考にスクリプトを編集して `headless: false` とする
    - https://github.com/puppeteer/puppeteer#default-runtime-settings
1. ターミナルからスクリプトを実行する `node ./エクスポートしたスクリプト.js`
1. ブラウザが起動して操作が再生される。

# まとめ
ぜひ触ってみましょう!
WebRTCのブラウザ対応の歴史

# 背景
弊社ではWebRTCを使ったサービスを開発しています。
どういった経緯で推奨環境が移り変わってきたのかを整理する必要があり、いつWebRTCが使えるようになったのかを調査しました。

# WebRTCのブラウザ対応の歴史
WebRTCを使うにはこちらのQiitaに書いてあるように、大きく2つのAPIに対応している必要があります。

https://qiita.com/seya/items/acd6113b8f28ad7fccc2

今回は簡単に「Can I Use」で`WebRCT`で検索してみます。
`Date relative`を見ると時系列でいつごろのバージョンで対応がされてきたのかが分かりやすいです。

https://caniuse.com/?search=WebRTC

## WebRTC Peer-to-peer connections
### PCのブラウザ
**対応バージョンのリリース月**
2012年09月: Chrome
2013年03月: Firefox
2013年12月: Opera
2017年04月: Edge (部分的に対応)
2017年09月: Safari
2020年01月: Edge

### スマホやタブレットのブラウザ
**WebRTC対応バージョンのリリース月**
2013年08月: Chrome for Android [^1]
2017年09月: Safari on iOS

[^1]: http://juggly.cn/archives/92934.html 「Can I use」では表示されてませんが、どうやら2013年にはWebRTCをサポートしたバージョンが出ていたようです

さすがにWebRTCはGoogleから始まっているのでChrome対応は早いのですが、スマホやタブレット版での対応は思っていた以上に遅かったのですね。

# 参考
- [WebRTCのブラウザ対応状況について – SkyWay サポート](https://support.skyway.io/hc/ja/articles/236202427-WebRTC%E3%81%AE%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
)
プログラミング独学2ヶ月目の初心者のボヤキ

はじめまして、cyberdogと申します。
まずは簡単に自己紹介を。

私は現在23歳通信制高校卒のフリーターです。
21年の10月に4年間働いた職場を体調不良で退職し、元々興味のあったプログラミングを学習し始めました。
学習2ヶ月目にして運良くとあるベンチャー企業のプログラマ養成の応募に引っかかり、参加させていただくことになりました。そこで良い成績を残せば業務委託契約のエンジニアとして雇っていただけるとのこと。
学習2ヶ月にして実務形式の試験に取り組むことになり悪戦苦闘中。

以上が私の自己紹介になります。
そのプログラマ養成は2ヶ月間あるのですが、今日からその試験で学習した内容を守秘義務に触れないよう簡単に自分なりに書き出していこうと思います。
今日は簡単な自己紹介と1週間ほど取り組んできた感想を書いていきたいと思います。(思いつくままに書いていくので、お見苦しい文章になってしまうかと思いますがご了承ください。)

最初お話を頂いたときはこんなうまい話があるのかと疑い気味でしたが、このチャンスを逃せば後はないと思い必死に喰らいついています。
ですがやはり想像以上にプログラミングというのは難しいです。
いまはデータベースについて学んでいますが、何がなんやらわけが分かりません。何がわからないのかもわからない状況です笑
小さい頃からPCを触って遊んでいた自分にとってプログラミングなんて簡単にできるとたかをくくっていたところがあるのですが、完全に間違っていました。
ですが、先にも書いたように私の人生のラストチャンスだと思って喰らいついていきたいと思います。
優しい方はどうか私に効率の良いアウトプットの方法をご教授ください。
では今日はここで終わりにしたいと思います。
STAC2021に参加してみた！

## はじめに
　初めまして、@keysh_と申します。
　AIQVE ONE株式会社で主にテスト自動化に関するお仕事をしております。

　先日、 ***ソフトウェアテスト自動化カンファレンス2021(以下、STAC2021)*** に
　参加させていただきました。
　カンファレンスに参加して発表させてもらうこと自体、私自身初めての試みでしたので、
　準備～当日の発表までを軽く振り返ってみようかと思います。

## STAC2021って何？
　まずは***ソフトウェアテスト自動化カンファレンス2021***についてご説明いたします。
　こちらは　***テスト自動化研究会(以下、STAR)***　主催のテスト自動化に特化した
　カンファレンスとなっており、実際の現場でのテスト自動化についての取り組みや、
　こんなことに苦労した！などを15～30分でセッションするイベントとなっております。
　今回は弊社含め、17組のセッションが行われました。
　https://testautomationresearch.connpass.com/event/228204/

## 参加した理由
　普段行っているテスト自動化について、
　こんなことをやっていて、ここに苦労しているんです！！
　といったことを発信する機会がなかなかありませんでした。
　また、普段聞けない他の会社さんの取り組みや苦労話にもとても興味があり、
　こういった場で少しでも交流してお話しが聞けたらなと思い、参加を決意しました。

## 準備したもの
　セッションのために準備したものですが、

   - 講演資料
   - 事前に録画したセッション動画

　大きく分けてこの2つになります。

　資料は私を含め、3名で作成しました。
　内容は実際に起きた自動化失敗談で、当時のことを思い出しながら作成しました。
　何度もフィードバッグをしてもらい、完成までに2か月半くらいかかりました。
　しかし、資料よりもこれをどんな感じで話そうかを考える方が大変だったなと思います。
　時間内に収められるかもそうですが、資料のどの部分を話の中でどう補っていこうか、
　構成はどういう風にしようかすごく迷いました。
　短い時間で的確に伝えたいことを相手に伝わるような内容にする、
　ここがとても難しいところではありますが、たくさん考えた分いい勉強になりました。
　
　動画はZoomで録画を行ったのですが、いただいている枠が30分なのに対し、
　約17分程度で終わってしまったので、残り時間は質疑応答や後日談、
　その他に取り組んでいることについて話すことに充てました。
　いま振り返ってみると時間配分的には、それなりにちょうど良かったのかなと思います。
　
## 実際に参加してみて
　当日、セッションの中で唯一ゲームテストの自動化について発表をしたので、
　どんな反応になるだろうかととても心配だったのですが、
　講演を聞いてくださった方々から共感の声をいただき、とても面白かった！などの
　感想もいただけたので、たくさん準備した甲斐があったなと嬉しかったです。
　また、様々な取り組みや苦労話を聞けてこうすれば良かったのか、
　この手のことはみんな同じような苦労をしているんだなととても勉強になりました。
　今後もこのような機会にまた恵まれた際は、積極的に参加していきたいです。

　資料はShareSlideにアップしております。
　https://www.slideshare.net/keysh2/ss-250840722
　
　また、STAC2021の講演は後日YouTubeで公開されるそうなので、
　ご興味のある方はぜひご視聴いただけますと幸いです。
unity : vs の csproj ファイルが見つかりませんが表示された

# 方法
`Unity -> Preferences -> External Tools -> Regenerate project files` をクリック

# 経緯
Unity Editor のバージョンのアップデートや、asset の import をなんかとをしてるうちに、プロジェクトファイルの参照が壊れたら、上記の方法で再度ファイルを生成すると直るときがあります。
記事１）LinuxスクリプトでのMySQLクエリ(スクリプト初めての方も)

初めての記事ですが、LinuxでのスクリプトでMySQLデータベースのレコードの削除やファイル削除などについて共有したいと思います。

◆まずは、Linuxのコマンドを開きます。
Windowsで利用の方は色んなコマンドツールがあると思いますが、私は下記のツールなどを使っています。
　-「Linuxサーバ」PuTTY (https://www.putty.org/)
　-「ロカール環境」Git Bash (https://git-scm.com/downloads)
◆下記のコマンドでスクリプトファイルを作成して試してみましょう

```
$vim file_name.sh
```

```bash:file_name.sh
#!/bin/bash
echo hello world
```
保存して、権限を与える

```
$chmod +x file_name.sh
```
下記のコマンドで実行してみると hello worldがアウトプットされました。:clap_tone1:

```
$./file_name.sh
```

では、さっそくMySQLクエリを実行してみましょう
ロカール環境ではMySQLデータベースを接続するためユーザ名やパスワードなどをスクリプトファイルで直接書いても問題ないですが、LinuxサーバではこのようなWranningが出る場合があります。
```mysql: [Warning] Using a password on the command line interface can be insecure.```
なので、このように設定ファイルを利用した方が安全です。

```
$vim mysql_access.cnf
```

```bash:mysql_access.cnf
[client]
user=user_name
password=password
```
保存して、権限を与えます。

```
$chmod 600 mysql_access.cnf
```
そして、スクリプトでMySQLに接続して、データベースのレコードやファイルなどを削除してみます。リクエストIDの設定や確認メッセージなども含めてやっていきたいと思います。

```bash:file_name.sh
#!/bin/bash
#MySQL接続
db_name="database_name"
host_name="host_name"
sql_con="mysql --defaults-extra-file=mysql_access.cnf -h $host_name $db_name "
sql_exit="exit;"
#リクエストID設定
read -p "IDを入力してください: " t_id
#確認メッセージ
read -p "データを削除してもよろしいですか？(y/N): " yn
case "$yn" in
[yY]*)
#yes/y の場合DBの存在チェックする
$var1=$($sql_con -se "SELECT id,name,created_date FROM tbl_name WHERE id=$t_id;")
#$var1がNULLかどうかをチェックする「if文には半角スペースは大事です」
 if [ -z "$var1" ]; then
  echo "データが存在しません";
 else
  #SQLクエリのアウトプットを変数に割当します
  read  id name created_date <<< $var1
  #データを削除します。
  $sql_con -se "DELETE FROM tbl_name WHERE id=$id;"
  #ファイルを削除する場合
  file_path="/path/to/file/file_name.ext"
  #ファイル存在チェック
  if [ -e $file_path ]; then
   sudo rm -f $file_path;
  else
   echo "ファイルが見つかりませんでした。";
  fi
  echo "削除しました。";
 fi
;;
*) echo "中止しました。"
;;
esac
#引き続き削除したい場合
read -p "引き続き削除しますか？(y/N)" c_del
case "$c_del" in
 [yY]*)
  ./file_name.sh
 ;
 *)
  echo "終了しました。"
 ;
esac
```

アウトプット

```
$ ./file_name.sh
IDを入力してください: 365
データを削除してもよろしいですか？ (y/N) : y
削除しました。
引き続き削除しますか？(y/N)y
IDを入力してください: 22
データを削除してもよろしいですか？ (y/N) : y
データが存在しません。
引き続き削除しますか？(y/N)n
終了しました。
```
もしよかったらぜひ試してみてください。
丁寧なヒアリングで回避せよ。お客様の満足度を下げないために気をつけること

こんにちは。LITALICOデザイナーの [酒倉](https://qiita.com/sakagurachan)と申します！
（初のマークダウン方式にアタフタしながら書いています:sweat_drops:）

さて、デザイナーをしていると、絶対聞かれる質問:point_up:

**『デザイナーをしていて一番楽しいと思えるのはどんな時？』**


この質問に私はこう答えます。

**「お客様の満足のいくものが作れたとき:muscle:！！」**

・・・とてもありきたりで、ありがちで、つまらない答えかもしれませんが、
これが**一番難しいこと**だと思っています。

私は普段webサイト制作の副業をしており、
お客様に直接ヒアリングをしながら進めていく事が多いです。

中でもランディングページ（以下LP）の制作依頼が多く、
今でこそ丁寧なヒアリングを心がけているのですが、
以前、**ヒアリング不足でお客様の満足度を下げてしまったことがあります。**
今回はそのお話を書かせていただこうと思います:bow:


# 依頼内容

* 既存のLPをリニューアルしたい（美容系商材）　 
  * コンテンツ内容は既存LPを流用。**デザインだけ**変えたい
  * **3つほど新規コンテンツ**も追加したい
 
というようなもので、特別難しいご依頼（開発が絡んだりなど）というわけではなかったので、
問題なく公開まで持っていけました！

# 起こった事象
* リリース1ヶ月後、LP全体で使っているフォントの**「筑紫A丸ゴシック」**を**「ヒラギノ角ゴ ProN」**に変えたいと依頼がある

変えることはもちろんできるのですが、
**まだ一ヶ月しか経ってないこのタイミングでなぜだろう:thinking:？**
と思いました。
フォントの変更は、**LP全体のイメージが変わるくらい強いインパクトがある**ので、
慎重に変える必要があると思っています。
下図で比べてみても、イメージが大分変わりますよね。
![img01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292321/1d48ae3e-d9f7-2888-e9c4-baddd85e1ef1.png)



商材に合った柔らかいイメージのフォントを選んだつもり（ガイドライン等は無かった）でしたし、
**お客様にもこれでOKを頂いています。**

**なぜ変えたいのかを確認**したところ、回答いただきました:point_down:

# 原因

実はお客様は、初稿時にフォントに**少し違和感があった**そうです:cloud_snow:
しかし、言葉にして伝えるのが難しかったので、私にお任せしたけれど、
やはりイメージが違うかも。という思いが拭いきれず、リリース後に依頼をくれたというわけでした。

この件はとてもショックでした。**完全に私のヒアリング不足により起こった現象です。**
遠慮させてしまったり、思ったものと違うデザインをお渡ししてしまうことは、
本当に申し訳ないことです。

まとめますと、

* **フォントの細かいイメージ**までヒアリングしなかった
  * ゴシック・明朝など大まかなイメージのみ決定
  * お客様は細かいフォントの種類までこだわらないという勝手な思い込みがあった
* **一番大事にしたいイメージの認識合わせ**ができてなかった（後述します）
* どんどんデザインが出来ていくから、**遠慮・指摘しにくい**状況を作ってしまった

が、大きな原因なのかなと思いました。

# 結果
再度、デザインの中で**一番大事にしたいイメージは何かを認識合わせ**したところ、
下図のような違いが見えてきました。
![img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292321/1783850f-e626-8384-db78-e83dd76ab262.png)

認識合わせによって、お客様は**「信頼」**に最も重きをおいているのが分かりました。
固くなさすぎず上品なフォントを別途提案したところ、
**イメージにぴったり**だったようで、最終的には、お客様の希望のデザインを提案することができました。

# ヒアリングで気をつけることは？
この件は、**もっと丁寧なヒアリングを行っていれば、回避できること**でした。
ヒアリング不足により、結果自分の首を締め、満足度を下げる形になってしまったので、
現在は下記を行っています！

#### 1. ヒアリングシートの準備
フォント一つとっても、こだわりのあるお客様がいることを肝に命じて、
**細かなヒアリング項目**を準備しました。
また、共有のシートを見ながらお話ししていくので、**認識合わせもしやすくなりました。**
（どんな項目を準備してるかは、また別途記事にできればと思います:relaxed:）

#### 2. ヒアリングを数回行う
以前は一度だけヒアリングをして、
疑問点があればメールやチャットで内容を詰めていく方法をとっていたのですが、
文章だけだと認識に齟齬が生まれやすいため、
最低2回のヒアリングを設けて、**お客様と一緒に足並みを揃えて制作する**のを意識しています:muscle:

#### 3. 商材に関する知識をアップデートしておく
トレンドは毎日変化しています。
競合の商材やLPは、毎回チェックしておくのを欠かさずに行っていますし、
デザインを作る際に、こちらから提案できることも増えるのでおすすめです！

#### 4. 完成までのフローをお伝えしてあげる
お客様の中には、web制作のやり取りに慣れていない方もたくさんいらっしゃいます。
どう進めていくのか不安に思っている方も多いので、最初にスケジュールが決まったら、
どういったフローで進めていくかをお伝えしています。
その際に、「ここでまずデザインをチェックしてもらいます」などお声がけできるので、
お客様の方でも**自分のやることが明確**になるので、スムーズに進めやすくなります。


# おわりに
いかがでしたでしょうか？
「お客様の満足のいくもの」を作るためには、**丁寧なヒアリングが肝心！**だということをお伝えしたかったんですが、
長々と書き綴ってしまいました:sweat_smile:

作り手側はいつでも、**「相手が何を求めているのか？」**を考える必要があります。



まだまだ半人前の私ですが、相手が「こうしたい」と思っていることを正確に捉えて、
**成功に導くためのサポートができる人材になれるように**、今後も努力していこうと思います！

最後まで読んでいただきありがとうございました。
それではまた:raised_hand:
フォームのアクティビティ上でメール詳細を常に表示させる

# やりたいこと

フォームのアクティビティ上でメール本文は畳まれて表示されるが、常時表示させるようにしたい

# 環境

- ServiceNow
    - Quebec
- ブラウザ
    - Chrome(確認済)

# 設定

以下クライアントスクリプトを作成

- 名前
    - 任意の名前（Show Email Details）
- テーブル
    - 任意のテーブル
- UIタイプ
    - デスクトップ
- タイプ
    - onLoad
- スクリプト

```js
function onLoad() {
    setTimeout(function() {
        $$('.stream-action[action-type="show-email"]').each(function(item) {item.click();});
    }, 1000);
}
```

# 参考

- [How to automatically expand "Show Email Details" in work note?](https://community.servicenow.com/community?id=community_question&sys_id=572f0d07dba1c0504819fb2439961927)
- [Auto-expand Inbound mails on Incident activity](https://community.servicenow.com/community?id=community_question&sys_id=80d04f65db98dbc01dcaf3231f96195a)

↑旧バージョンでの情報なので、動かないがJqueryの書き方を真似た
Pythonでfreee APIを使ってファイルボックスに証憑画像をアップロードする

Pythonからfreee APIを叩いてファイルボックスに証憑画像をアップロードする処理を書いていた時に、微妙に躓いたのでメモを残します。

freeeのAPIドキュメントは[こちら](https://developer.freee.co.jp/docs/accounting/reference#/Receipts/create_receipt)

### ローカルファイルから画像を取得する場合
```python
import requests

# freeeの事業所ID
company_id = 123456789
# OAuth認証で取得したfreeeのアクセストークン
access_token = "**************************************************"

# ローカルファイルから画像を取得する
with open("local_image_path", "rb") as f:
    binary_image = f.read()
    
headers = {
    "accept": "application/json",
    "X-Api-Version": "2020-06-15",
    "Authorization": f"Bearer {access_token}",
}
files = {"receipt": binary_image}
data = {"company_id": company_id}

response = requests.post(
    "https://api.freee.co.jp/api/1/receipts",
    headers=headers,
    files=files,
    data=data,
)
```

`binary_image`はバイナリ形式の画像データなら何でも良いので、他の方法で取得したものでも大丈夫です。以下は別例になります。

### ローカルファイルから画像を取得する場合(PIL版)
```python
import io
from PIL import Image

# ローカルファイルから画像を取得する(PIL版)
image = Image.open("local_image_path")
output = io.BytesIO()
image.save(output, format="JPEG")
binary_image = output.getvalue()
```

### URLから画像を取得する場合
```python
from urllib.request import urlopen

# URLから画像を取得する
url = "https://sample_image.jpg"
binary_image = urlopen(url).read()
```

### S3から画像を取得する場合
```python
import boto3

# S3から画像を取得する
s3 = boto3.resource("s3", region_name="ap-northeast-1")
bucket = s3.Bucket("your_bucket_name")
object = bucket.Object("your_object_key")
binary_image = object.get()["Body"].read()
```
ConoHa WINGでCloudflareを使う

みなさんこーんにーちわー
今年も前日に記事を書いているよ！

- 2019の投稿: [で、レンタルサーバーってなんなのさって話よ](https://qiita.com/horiken1216/items/183547610badcb9f4938)
- 2020の投稿: [ConoHa WINGをVPSの追加ストレージとしてマウントしてみる](https://qiita.com/horiken1216/items/b031d681fd65a9c80744)
ローカル環境からSageMakerを使ってモデルの学習～エンドポイント作成を行ってみた（準備編）


## 背景・取り組み内容
SageMakerを使用する際、初めての方は「SageMaker Studio」内にあるJupyter Notebookインスタンスを立ち上げてモデルの学習をされることが多いと思います。

いちいちAWSにアクセスしてSageMakerStudioを立ち上げ、さらにNotebookインスタンスを立ち上げ、一連の作業が終了したらインスタンスを終了させる…という一連のプロセスは個人的に億劫だなと感じます。
そこで今回は、ローカルのVScodeからSageMakerを使うことができないかと思い勉強として取り組んでみたところできましたので備忘録として記事を書きました。

参考までに、筆者の現在のレベルとしては

・機械学習には少し触れた程度
・Sagemakerは今まで触れたことがなく、今回初めて1週間程度触れてみた

という状態から、NotebookをローカルPCで動かしてみるというところにチャレンジしてみた素人レベルの人間です。
色々なサイトを参考しながら取り組んでおります。

前編では、データセットの準備まで行います。
後編では、SageMakerでの学習とエンドポイント作成を行います。



ちなみにNotebookインスタンスの料金表は以下の通りです。今回のような小さなデータセットであれば、「ml.t3.medium」のような小さなインスタンスでも十分動作しました。ですのでStudioノートブックでもコストは軽微です。
今後大きなインスタンスを使う場面もあると思いますので、その場合にローカルのハイスペックPCからSageMakerを動かすということができればコスト面でも貢献できると考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218811/3fb72420-4aa6-55cc-bb0e-5873cf9fadd3.png)

https://aws.amazon.com/jp/sagemaker/pricing/

## 使用環境
### エディタ
Visual Studio Code(1.62.3)
Jupyter Notebook※デバッグしやすいのでVSCode内で使いました

### 使用言語
Python3.8


##Part1:ライブラリのインストール・各種パスの設定
使用するライブラリのインストール・各種フォルダパスの設定を行います。

```r:
#sklearn
from sklearn.datasets import load_breast_cancer	
from sklearn.model_selection import train_test_split

#SageMaker SDK
import sagemaker
from sagemaker.serializers import CSVSerializer

#S3操作用モジュール
import boto3

#データ操作に使うモジュール
import pandas as pd
import numpy as np
import io

#Part1:各種パス設定
##SageMaker用のロール
#例：role = sagemaker.get_execution_role()
role = '■■■■■'

##データやモデルを置くS3
bucket = '■■■■■'
prefix = 'sagemaker/■■■■■' #sagemakerというフォルダを作ってその直下にプロジェクトごとのフォルダを作るとわかりやすい
my_region = 'ap-northeast-1'
accesskey = '■■■■■'
sercretkey = '■■■■■'
```

##Part2:データ準備
「scikit-learn」に含まれている乳がんの診断データセットを使用しました。
ガンに関して計30の特徴が用意されています。この特徴量から「良性(1)か悪性(0)か」を予測します。

以下のサイトを参考にさせていただきました。とてもわかりやすくサンプルデータがまとめられております。

https://zenn.dev/nekoallergy/articles/scikit-learn-datasets


```r:
#Part2:データ準備
#乳がんのデータセット読み込み
data = load_breast_cancer()

#目的変数の抽出
y_all = pd.DataFrame(data["target"],columns=["target"])
y_all.head()

#説明変数の抽出
X_all = pd.DataFrame(data["data"],columns=data["feature_names"])
X_all.head()

#7:3の割合で学習用データと検証用データを分割
X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, test_size=0.3, random_state=0)

#学習用データと検証用データの変数を結合
train_data = pd.concat([y_train,X_train],axis=1,sort=False)
test_data = pd.concat([y_test,X_test],axis=1,sort=False)

#バックアップとしてS3の指定したバケットにデータをアップロード
filename1 = 'train_data.csv'
filename2 = 'test_data.csv'
train_data.to_csv(filename1, index=False, header=False)
test_data.to_csv(filename2, index=False, header=False)
boto3.Session().resource('s3').Bucket(bucket).Object(os.path.join(prefix+'/', f'train/{filename1}')).upload_file(filename1)
boto3.Session().resource('s3').Bucket(bucket).Object(os.path.join(prefix+'/', f'test/{filename2}')).upload_file(filename2)
```


後半では、このデータセットを使ってSageMaker上で学習とエンドポイント作成を行いました。
あわせて御覧ください。

https://qiita.com/msy5115/items/b5f496c1c07787a7b8e6
Power Apps Portals のスターターポータルで Access Denied が動作せずカスタムエラーになっちゃうときの対処法

1カ月くらいゆるゆる悩んでいた事象がめでたく解消したので、記録します。

# 起こったこと
Power Apps Portals でスターターポータルを作成すると、いい感じにポータルサイトの全体を作ってくれます。
ユーザはそこからページや、フォーム、リストというコンテンツ作成に注力できるので、高速でサイトが作成できるすごいものなのですが、ページにアクセス権限を設定したときに、うまく動作しない部分がありました。
それがいわゆる、Access Denied (アクセス許可がありません) の動作で、対象のページにアクセス権限がないユーザが、そのページにアクセスした場合、アクセス許可がない旨の内容がページに表示される、というものです。
私の場合は、その Access Denied の動作を期待したときに、以下のようなカスタムエラーページ(Internal Server Error 等で表示される)が表示されてしまうというもので、これが正しい動作なのか、設定が誤っているのかよくわからず困っていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/a7328828-89b4-684e-34c7-03f89cd42747.png)

## 参考: Power Apps Portals のバージョン
9.3.11.12 (2021/12/15 現在、うちの環境で作成できるもの)

# 対処法
特にスターターポータルから設定を変更していなかった私は、設定漏れなのかな、そんな設定あったかな、ユーザの Web ロールで動作が違うのかな、もしかして Access Denied はもう非推奨なのかな、とかいろいろあることないこと悩んでいました。
それから、フォーラムを検索したり、フォーラムに投稿してみたり、カスタムエラーを無効化してみたりいろいろしていたのですが、昨日ついに問題の解消方法にたどり着きました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">解決したー<a href="https://twitter.com/hashtag/PowerAppsPortals?src=hash&amp;ref_src=twsrc%5Etfw">#PowerAppsPortals</a><br>Display &quot;Page Not Found&quot; when an anonymous user accesses a page <a href="https://t.co/dTA5kJfGCS">https://t.co/dTA5kJfGCS</a></p>&mdash; nan_oka (@nanoka7o8) <a href="https://twitter.com/nanoka7o8/status/1470811552634658817?ref_src=twsrc%5Etfw">December 14, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 作業手順
### "ポータル管理"アプリを起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/cf1c4aa3-2765-001a-0c1d-21a9a22a747d.png)

### "Web ページ"、"アクセスが拒否されました"の順に選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/3eb65b9b-d5a2-5a1f-1466-eff58b63ec0a.png)


### "ページテンプレート"を"アクセスが拒否されました"に変更し保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/0855123c-09db-9080-507a-b300615cc941.png)

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/9ac6afd6-d42c-4223-9e54-bfd1b607e38c.png)

以上です。
これで無事、サインインしていれば Access Denied 、サインインしていなければ、サインインページにリダイレクトされるようになりました。

どっかのバージョンでデフォルト値が修正されるといいな。

## 参考:フォーラムのリンク

### 対処法として見つけたもの
https://powerusers.microsoft.com/t5/Power-Apps-Portals/Portal-error-when-enabling-Web-page-Access-Control-Rule/td-p/1358043

### 投稿したもの
https://powerusers.microsoft.com/t5/Power-Apps-Portals/Display-quot-Page-Not-Found-quot-when-an-anonymous-user-accesses/m-p/1342427#M9670

# 感想
Dynamics と Power Apps の記事を読み続ける毎日でした。スッキリ。
フォーラム、コミュニティに大感謝です。
rails controllerのテストについて

##テストとは何か？##

テストとは書かれたコードが期待通りの動作をしてくれるかどうかの確認を行うものである。
開発初期の段階なら自分の手（手動）でコードと動作を確認してまわってもいいかもしれないが、開発が進みコードの量が膨大になればテストに割く時間も膨大になってしまう。
そうしたときのために、自動テストというものを作成する。
自動テストとはrailsのテストファイルに書かれた条件を満たしてくれるかどうかをコンピュータに判定してもらうことである。testディレクトリはrails new を実行した時点で作成され、テストファイルはrails generate controllerなどのコマンドを実行した際に自動的に作成されている。

##テストの例##
特定のページの速度が遅くないか、htmlのtitleタグに想定通りの文字列が設定されているか、そのページにアクセスできるか、などをテストしていく。
ページの名前は"home"とする。

```
test "should get home" do
 get page_home_url     // "/page/home"にアクセス可能か
 get static_response :success // レスポンス速度の判定
 assert_select "title","home" // セレクタ、特定の文字列が含まれているか調べる(この場合はtitleタグがあるか、titleが"home"になっているかを確認する)
end
```
テストコードを書き終えたらrails testでテストを実行する。

```
$ rails test
```

GREENが出ればテストを通ったということである。

```
$ rails test
～中略～
# Running:
.
```
REDがでた場合はテストに通らなかった（失敗した）ということである

```
$ rails test
～中略～
# Running:
F
```
こうなったらエラーの内容を読み、修正する必要がある。
その後テストに通るまで修正とテストを繰り返す。

#終わりに
テストを通過したからと言ってそのコードが完全なものであるという保証にはならないが、明確なミスを減らし、気づく頻度を上げるができる。また、コードのリファクタリングに伴う不具合がないかどうかを判別するのにも役立つ、その恩恵はアプリの規模が大きいほど大きくなるだろう。

## 参考文献
- [Ruby on Rails チュートリアル](https://railstutorial.jp/chapters/static_pages?version=6.0#cha-static_pages)
【初心者向け】Unityでの非同期処理、コルーチン、コールバックについて

[PONOS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ponos)の21日目の記事です。

昨日は [@Cal](http://qiita.com/Cal) さんでした。

##はじめに
この記事は、Unityを使用した非同期処理やコルーチンについて簡単にまとめたものです。
Unity初心者の方や、非同期処理に触れたことがない方などの参考になれば幸いです。

####同期処理
```cs
    void Example()
    {
        Debug.Log("1");
        Debug.Log("2");
        Debug.Log("3");
    }
```
複数のタスクを実行する際に、１つずつ実行する処理のこと。
上記のコードの場合、「1」「2」「3」が出力されます。



####非同期処理
```cs
    void Example2()
    {
        Debug.Log("1");
        StartCoroutine(Coroutine("2"));
        Debug.Log("3");
    }

    IEnumerator Coroutine(string str)
    {
        // １秒待機
        yield return new WaitForSeconds(1);
        Debug.Log(str);
    }
```
複数のタスクを実行する際に、あるタスクの終了を待たずに他の処理を実行すること。
動作が重い処理や、時間を指定して実行する処理等に使われます。
上記のコードの場合、「1」「3」「2」が出力されます。

####コルーチン
```cs
    IEnumerator Fade()
    {
        for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
        {
            Color col = renderer.material.color;
            col.a = alpha;
            renderer.material.color = col;
            yield return null;  // １フレーム停止(次フレームはここから実行継続)
        }
    }
```
実行を停止して Unity へ制御を戻し、その次のフレームで停止したところから続行することができる関数です。([Unity公式ドキュメントより](https://docs.unity3d.com/ja/2018.4/Manual/Coroutines.html))

yield return で指定した場所で１フレーム停止し、次フレームはその行から実行継続されます。
非同期処理に載せたコードのように秒数を指定して待機させることも可能です。

####コールバック
```cs
    void Example3()
    {
        Method(CallbackMethod);
    }

    void Method(System.Action callbackMethod)
    {
        // 処理(主に非同期処理)
        //-----

        callbackMethod();
    }

    void CallbackMethod()
    {
        // 処理
    }
```
ある処理が終わった後に、別の処理を呼び出すこと。
非同期処理の終了後に、別の処理をしたい際などに使います。
上記のコードでは、Method関数で処理を行なった後にCallbackMethod関数を呼び出しています。

##まとめ
初見ではとっつきにくい部分もある非同期処理などですが、開発で使用される場面が多く、使えると実装できる幅が広がると思います。

明日は[@ackyla](http://qiita.com/ackyla)さんです！
KMSで生成したキーペアを利用してJWTを作成するサンプル

## 目的

JWTを利用することが増えてきましたが、都度払いだした鍵の管理が業務を圧迫するため
KMS管理のキーペアでJWTを作成する備忘録です。

## コード

KMSでは秘密鍵を取得することができないため、直接署名しています。
公開鍵は取得できるため、decodeは既存ライブラリ利用の想定です。

エンタープライズ環境では [lcobucci/jwt](https://github.com/lcobucci/jwt) のSigner実装として組み込むなどをお勧めします。

```PHP
use Aws\Kms\KmsClient;

class JWTEncoder
{
    /**
     * JWT生成
     *
     * @param KMSClient $kms
     * @param string $key
     * @param array $claims
     * @return string
     */
    public static function encode(KMSClient $kms, string $key, array $claims): string
    {
        $segments[] = static::base64url_encode(json_encode(['typ' => 'JWT', 'alg' => 'RS512']));
        $segments[] = static::base64url_encode(json_encode($claims));
        $result = $kms->sign([
            'KeyId' => $key,
            'Message' => implode('.', $segments),
            'SigningAlgorithm' => 'RSASSA_PKCS1_V1_5_SHA_512',
        ]);
        $segments[] = static::base64url_encode($result['Signature']);

        return implode('.', $segments);
    }

    /**
     * base64 url safe encode
     *
     * @param string $input
     * @return string
     */
    private static function base64url_encode(string $input): string
    {
        return rtrim(strtr(base64_encode($input), '+/', '-_'), '=');
    }
}
```

呼び出し。

```PHP
$jwt = JWTEncoder::encode(new KmsClient([
    'version' => 'latest',
    'region' => 'ap-northeast-1',
]), 'alias/jwt', [
    'key' => 'alias/jwt',
    'sub' => 'hogehoge',
]);
```
Vue.js(Nuxt.js)におけるsync修飾子とは（備忘録）

## sync修飾子とは何か
子コンポーネントから親コンポーネントのイベントを発火させる際に使用する修飾子である。
通常の書き方よりも簡潔に記載することができる。

##使用例
子コンポーネントNameForm.vueで下記イベント発火した場合

```vue
this.$emit('update:name', 渡すデータ)
```

親コンポーネントindex.vue （通常）

```vue
<template>
  <NameForm
　　　　　　:name='name'
　　　　　　@update:name='name=$event'
　　　　>
</template>
```
syncを使用した場合

```vue
<template>
  <NameForm
　　　　　　:name.sync='name'
　　　　>
</template>
```

上記のように簡潔に記載することができる。
## 参考文献
[Vue.js公式ドキュメント](https://jp.vuejs.org/v2/guide/components-custom-events.html)
https://blog.cloud-acct.com/posts/u-signup-page-3/
Crane - 簡易なContainer Image Builder

## 説明

Craneは、データサイエンティスト向けの簡易なContainer Image Builder、Base Imageに基づきお好みpackagesを加えて新たなImageを創ります。チームのため、皆んさんは同じ開発環境を利用することが出来ます。

https://github.com/InfuseAI/crane

### 必要なもの

+ [Crane](https://github.com/InfuseAI/crane/releases) ダウンロード
+ [Docker](https://docs.docker.com/get-docker/) client installed
+ [DockerHub アカウント](https://hub.docker.com/signup)

### 制限

+ AptとCondaとPipがあるBase Imageは必要です

### Settings

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

## Image Build/Push

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


## 参考文献

[Cleaning up the “dirty jobs” of data science with Crane] (https://blog.infuseai.io/cleaning-up-the-dirty-jobs-of-data-science-with-crane-9022ec4ad02a?source=friends_link&sk=882d44aa79d9c8dd66705847193ab80e)
【Linux】メモリの使用状況を確認できるファイル

Linuxでメモリの使用状況を確認できるファイルが、

`/proc/meminfo`

以下のコマンドで出力できる。

```:出力方法
# cat /proc/meminfo 
MemTotal:        5890844 kB
MemFree:         5223668 kB
MemAvailable:    5484588 kB
Buffers:            3164 kB
Cached:           463104 kB
SwapCached:            0 kB
Active:           268176 kB
Inactive:         264768 kB
Active(anon):       2144 kB
Inactive(anon):    73224 kB
Active(file):     266032 kB
Inactive(file):   191544 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       9433084 kB
SwapFree:        9433084 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         66732 kB
Mapped:            83204 kB
Shmem:              8692 kB
KReclaimable:      28256 kB
Slab:              50876 kB
SReclaimable:      28256 kB
SUnreclaim:        22620 kB
KernelStack:        2224 kB
PageTables:         6796 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    12378504 kB
Committed_AS:     258340 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
Percpu:              652 kB
HardwareCorrupted:     0 kB
AnonHugePages:     10240 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:       85952 kB
DirectMap2M:     6205440 kB 
```

・Memtotalがメモリの総容量
・MemFreeが空きメモリの容量
・MemAvailableがキャッシュを解放することで利用可能なメモリ量
各々意味は調べなければならない。

【使用環境】
-
・VirtualBox
・Red Hat Enterprise Linux 8.5 (Ootpa)
IBMCloud CIS エッジ証明書更新におけるフォールバック


##エッジ証明書更新に失敗した時
CISを利用する場合、カスタム証明書をアップロードして利用する事が多いと思われる。
デフォルトで無料で利用できるユニバーサル証明書をバックアップで持っておくと安心。

Client->Edge間の証明書
<font color="red">カスタム証明書の更新に失敗した場合、自動でユニバーサル証明書が利用される。</font>
ただし、ユニバーサル証明書はユーザで削除ができるので、削除していない事。


![貼り付けた画像_2021_12_15_11_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/7cd646ff-e653-fdd0-40af-d50aea930e38.png)

![貼り付けた画像_2021_12_15_11_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/bb8efcd5-71da-81c5-7f95-ffa6b0d94edc.png)
[py2rb] re.compile

# はじめに
移植やってます
# re.compile (Python)
```python
import re

msg = '電話番号は080-111-9999です！'
pattern = re.compile(r'(\d{2,4})-(\d{2,4})-(\d{4})')

print(pattern)
print(pattern.search(msg).group(0))

# re.compile('(\\d{2,4})-(\\d{2,4})-(\\d{4})')
# 080-111-9999
```
`compile`関数は正規表現オブジェクトを返します。
この例ではピンときませんが、`compile(pattern, flags=0)`で正規表現オプションを利用することにより複雑な正規表現を簡単にすることも可能です。

https://docs.python.org/ja/3.7/library/re.html#module-re
# `//` (Ruby)
```ruby
msg = '電話番号は080-111-9999です！'

pattern = /(\d{2,4})-(\d{2,4})-(\d{4})/

puts pattern
puts pattern.match(msg)

# (?-mix:(\d{2,4})-(\d{2,4})-(\d{4}))
# 080-111-9999
```
当面は正規表現をゴリゴリと。
**[追記]**

https://docs.ruby-lang.org/ja/latest/method/Regexp/s/new.html

**[追記2]**
`Ruby`の正規表現で便利そうな機能が

https://qiita.com/scivola/items/46c98f90b9d93b6630b6#%E6%94%B9%E5%96%84
# メモ
+ Python の re.complie を学習した
+ 道のりは遠そう
ラクラク！Sorceryを用いたゲストログインの実装


## 概要
本記事は RUNTEQアドベントカレンダー 2021 の16日目の記事となります！

RUNTEQに入学して約1ヶ月が経った段階で、学習の振り返りとして簡易的なアプリを作りました！

あの頃の夏の思い出を共有して、ノスタルジックな気分になれるアプリです。
(モチーフは、井上陽水の「少年時代」)

**今回は、このアプリで実装したゲストログインの方法を紹介します。**

作成したアプリを気軽に使ってもらうためにゲストログインを実装しようと考えていらっしゃる方は多いのではないのでしょうか？
是非参考にしてみてください。

https://otonanonatsu.herokuapp.com/

## 前提
- gem 'sorcery' をインストール済み
- ruby 2.6.3
- Rails 5.2.6

## ルーティング
```ruby
# routes.rb
  post '/guest_login', to: 'user_sessions#guest_login'
```
guest_loginというパスを受け取ると、
user_sessionsコントローラーのguest_loginアクションを実行するという処理です。

## コントローラー
```ruby
# user_sessions_controller.rb
  def guest_login
    @guest_user = User.create(
    name: 'ゲスト',
    age: '**',
    email: SecureRandom.alphanumeric(10) + "@email.com",
    password: 'password',
    password_confirmation: 'password'
    )
    auto_login(@guest_user)
    redirect_to root_path, success: 'ゲストとしてログインしました'
  end
```
- SecureRandom.alphanumeric(10)では、ランダムな10文字の英数字を生成しています。
- auto_loginはSorceryが与えてくれるメソッドです。

つまり、ここでは、*emailがそれぞれ違うゲストユーザーが生成されることになります。

*この実装には、1つ問題点があると思っています。それは、ランダムに生成された10文字の英数字が被る可能性がごくわずかながらあるということです。ですが、今回はそこまでのことを考えて実装していないので、ご理解いただけると助かります。

## ビュー
```erb
<%# shared/_header.html.erb %>
    <nav>
      <ul>
        <li><%= link_to 'ゲストログイン', '/guest_login', method: :post %></li>   
      </ul>
    </nav>
```
## まとめ
以上でゲストログインが簡単に実装できるので、誰かのお役に立てれば幸いです。
「VB.NET」とかいう言語


この記事は、「ググって解決しづらかったこと Advent Calendar 2021」の18日目として書かれたものです。

「C」、「Java」、「Python」など。
現在、プログラミング言語はメジャーなものからマイナーなものまでいろいろあります。

さて、そんないろいろなプログラミング言語がある中、一つのプログラミング言語の話をします。

タイトルにもある通り、「Visual Basic .NET」という言語です。「VB6」の実質的な後継言語であり、略して「VB.NET」と呼ばれることが多い言語です。

この略称「VB.NET」ですが、見ていて何か気づかないでしょうか。
この「VB.NET」なんですけど、**URL**として判定されてしまう訳なんですね。~~まあ、クオーテーション付ければいいだけなんですけど。~~
そんなどう見てもURLな言語のお話になります。

---

ある日、プログラミング言語について調べようと思い、[Google](https://www.google.com/)を使って順番に調べていた時でした。
「VB.NET」と、いつものようにアドレスバーに打ち込むとVB.NET Shopとかいう謎のページが……。
ああ、なるほどアドレスバーに打ったからこいつURLとして判定されてるな、とすぐに思い至ったのは良いんですけどなんかクオーテーション付けるのも負けた気になるな、とよくわからない意地を発揮。

しかし、仕方なく下の検索バーで調べるかと思い入力してもこれもまた同様にVB.NET Shopとかいう謎のページに遷移してしまいます。

Chromeの新しいタブで使われているGoogleの検索バーをよく見てみると……。

![20211215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259240/c0575ba0-7408-9851-84c6-2285bdd18330.png)

>Googleで検索または**URL**を入力

Google君、普通の検索バーでもURL検索に対応しているのね……。
ちなみに、Chromeの新しいタブではない[普通のGoogle](https://www.google.com/)では対応していないようです。~~何故……。~~

まあきっとこういう問題もあるからリリースされてから3年で製品名称から「.NET」がさらっと外されていたりしたんでしょうね。

以上、プログラミング言語の名前がどう見てもURLな「VB.NET」とかいう単体で検索しにくい言語のお話でした。クオーテーションで解決する話なんですけどね。

ちなみに「ASP.NET」は該当のサイトがなかったのかMicroSoftのASP.NETのページに飛ばされます。
「ADO.NET」は接続できません。
「VisualBasic.NET」はプログラミング関係の何かのサイトに飛びます。
~~何もわかってないサイトに直に飛ぶのあまりよくないとは思うんですけどね……。~~

---

蛇足にはなりますが、「Visual Basic」の略称「VB」は他の略称が多く、検索したときに他の略称と競合する場合があります。(Virus BusterでVBとかですね)
そちらに関しては@yajuさんが調べてくださってますので合わせてご覧ください。
[ネットでVisual Basic関連を検索する時に除外する略名群](https://qiita.com/yaju/items/e0d3522cb4a0a9991ef1)

ということで「VB.NET」どころか「VB」だけでも検索しづらい悲しい言語のお話でした。
Xcode管理のSwift Package ManagerでLibraryを後から追加する

Swift Package Managerには２つの管理パターンがありXcodeのGUIで管理する場合と
Package.swiftで管理する場合があるようです。

XcodeのGUIで管理で、Libraryを追加するケースについて少し迷ったので記事に残します。

まず最初にLibraryを追加する場合は File -> AddPackageｓ から Package を追加できます。
その際に、Libraryを選ぶ画面が出てきます。
初回はここから、利用したいLibraryを選択すればOKです。
![CleanShot 2021-12-15 at 11.08.34@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6678/6e64ad78-18ab-96b0-a747-ede7f75e98c4.png)

Libraryを後から追加したい場合は、TARGETSのBuild PhasesからLinks Binary With Libraries を展開して＋ボタンから追加ウインドウを開き、ここで後から追加することが出来ます。
![CleanShot 2021-12-15 at 11.11.38@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6678/f3a5f1e8-e825-b364-3785-dd5f5fc29063.png)
![CleanShot 2021-12-15 at 11.13.56@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6678/b5e86284-4630-2a1e-d172-23d0084992b1.png)

---

＼プログラミング相談Slackコミュニティやってます／

月額9,800円のサブスクで質問し放題です
プログラミング学習や個人開発などに気軽に利用ください

https://codeqa.me/
[Unity]NavMesh導入

地点Aから地点Bまで移動させたいオブジェクト。
NavMeshを使って実現するには。
（基本使うだけなら簡単）

**NavMesh基本要素**

* NavMesh
    * NavMesh Agent
    * NavMesh Obstacle
    * Off-Mesh Link

1. 地面と、移動させたいオブジェクト（以下NPC）と、目的地を作る。
1. 地面にNavMeshをBakeする(後述)。
1. NPCにNavMesh Agentを追加
1. スクリプトによりNavMesh Agentに目的地を設定する。


**NavMeshのBake**

1. Window→AI→Navigation
1. 地面と障害物を設定 -> Navigation satic
1. 適宜パラメータ設定
    1. 主（障害物との距離、トンネルみたいに潜り抜けられる所の高さ、移動可能な段差、移動可能な斜面角度）
IBMCloud CVE-2021-44228 Apache Log4jの影響(security製品)

##IBMCloudにおけるCVE-2021-44228の影響について調査した
本記事は、IBMCloudのクラシックインフラストラクチャのセキュリティセグメントに関する製品の影響まとめ。

###VRA
VyattaはJavaを含まない製品であり、CVE-2021-44228の影響を受けない。
Log4j2もapacheも、VyattaOSのどのバージョンでも使用されていない。

###vSRX
このCVEの対象となるコンポーネントは存在するが、攻撃を実行するサブコンポーネントはソースコードの一部にないため、vSRXを悪用することはできない。

###Fortigate
Fortigateはこの脆弱性の影響を受けない。
また、IPSパッケージ「Apache.Log4j.Error.Log.Remote.Code.Execution」がある。
https://www.fortiguard.com/psirt/FG-IR-21-245?utm_source=blog&utm_campaign=blog

###CIS
CISはlog4jを使用していないため、影響受けない。
また、WAFルールが公開済み。
https://blog.cloudflare.com/cve-2021-44228-log4j-rce-0-day-mitigation/