OmniAICreator/Qiita-1.07M huggingface dataset:
MeCabのタブ区切りの右のCSVフィールドどうやって区切ってる？

うちではこういうの書いて使ってるというメモ。

```python3:mecab_toolbox.py
#! /bin/python
# coding: utf-8

from io import StringIO
import csv


def csv_splitter(csv_line, empty_elem=''):
    fin = StringIO(str(csv_line))     # バイナリにしないとcsvのnextで怒られる
    splitted_line = next(csv.reader(fin))
    fin.close()
    ret = []
    for elem in splitted_line:
        if elem:
            ret.append(elem)
        else:
            ret.append(empty_elem)
    return ret


def csv_joinner(listed_line):
    ret = []
    for elem in listed_line:
        elem = elem.replace('"', '""')
        if ',' in elem:
            elem = '"' + elem + '"'
        ret.append(elem)
    return ','.join(ret)


if __name__ == '__main__':
    line = '1,2,3,abc,"ab,c"'
    print(line)
    line = csv_splitter(line)
    print(line)
    line = csv_joinner(line)
    print(line)
```
IFC勉強会に参加してきた

# はじめに

11/26（土）に開催された第1回IFC勉強会に参加＆登壇したので、その内容を書きたいと思います。
勉強会自体は[TokyoAECDevのイベント](https://www.meetup.com/ja-JP/tokyo-aec-industry-dev-group/events/whlpvsydcpbjc/)として開催されました。
また、アーカイブ動画がYouTubeにアップロードされています。

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



# 概要

登壇者は４人で持ち時間は30分ずつでした。
発表内容は以下の内容でした。

> 1. IFCによるアプリケーションのマイクロサービス化
> 2. About IFC 4.3. ~Focus on infrastructure~
> 3. IFCおよび関連技術とその動向
> 4. MMO game with ifc.js

IFCの詳細や動向についての発表が2つ、IFCを使ったアプリケーションの開発に関する発表が2つでした。

# 発表内容

## 1. IFCによるアプリケーションのマイクロサービス化

この発表では、建築基準法適合判定に焦点を当てたアプリケーションの開発とそのアーキテクチャについての話でした。データの標準としてIFCを用いることで従来一つのアプリケーションによって完結していた内容が、それぞれ独立したマイクロサービスとして成り立ちます。

発表資料については[こちら](https://speakerdeck.com/ktaroabobon/ifcniyoruapurikesiyonnomaikurosabisuhua)に共有されています。


## 2. About IFC 4.3. ~Focus on infrastructure~

この発表では、次回リリースされるIFC4.3についての内容でした。IFCはこれまで施設情報に焦点を当ててきましたが、4.3からは土木情報（橋梁・道路・線路など）も格納できるようです。また、PowerBIというツールを使用してダッシュボードを作成しIFCデータを可視化しているところも見せていただきました。
個人的には登壇中におっしゃっていた「IFCを活用する上では、3DモデリングなどではなくInformation Modelingを行うことが重要ではないか」という言葉がとても印象に残っています。


## 3. IFCおよび関連技術とその動向

この発表では、IFCに20年ほど携わっている方によるIFCの関連技術とその動向についての内容でした。古くからのIFCがどう意識して作られたかや今後どのような方向を目指しているかということをお話しいただきました。途中スライドで出てきた「IFCおよび周辺技術・標準の概要」（p5）がとてもわかりやすくまとまっており今後も参考にしたいと思いました。

発表資料については[こちら](https://www.slideshare.net/YoshinobuAdachi/ifc-ifc)に共有されています。

## 4. MMO game with ifc.js

この発表では、ウォークスルー機能を持った自作IFC Viwerアプリについての内容であり、ossの一つである[IFC.js](https://ifcjs.github.io/info/ja/)を使ったアプリでした。アプリ上にてユーザー登録を行うと皆が同じサーバーに接続し、ウォークスルーを行うことができます。ウォークスルーはキーボードの"W", "A", "S", "D"それぞれのキーを用いて移動することができその位置情報も共有されます。この技術を応用すれば実建物をベースとしたFPSゲーム等も開発できるのではないかと感じとてもおもしろいアプリだなと思いました。

発表資料については[こちら](https://github.com/ChenChihYuan/ifcjs_WIV_Hackathon2022)に共有されています。

# まとめ
今回の勉強会は第1回目の開催でしたが、当日はZoomとYouTubeにて配信を行い約５０人の方が参加しており盛り上がっていました。開催当初は結構ニッチな会になると思っていたため意外にも参加者がいて嬉しかったです。

![discord.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552407/74ea1f45-4449-3178-d6cd-b57ba5d51355.jpeg)

どの登壇者もレベルが高くとても勉強になることが多かったです。発表資料もみなさんあげているため、また見返したいと思います。まだ、視聴していない方は[アーカイブ動画](https://youtu.be/hex2j50idXc)をぜひ視聴してみてください！
第2回以降も開催されることを願っています。

# 参考リンク

- [イベントリンク](https://taec-ifc.connpass.com/event/264892/)
- [TokyoAECDev](https://www.meetup.com/ja-JP/tokyo-aec-industry-dev-group/)
- [アーカイブ動画](https://youtu.be/hex2j50idXc)
- 発表資料
  - [IFCによるアプリケーションのマイクロサービス化](https://speakerdeck.com/ktaroabobon/ifcniyoruapurikesiyonnomaikurosabisuhua)
  - [IFCおよび関連技術とその動向](https://www.slideshare.net/YoshinobuAdachi/ifc-ifc)
  - [MMO game with ifc.js](https://github.com/ChenChihYuan/ifcjs_WIV_Hackathon2022)
遷移前のリクエストを使ってリダイレクト

# request.referer
遷移元のurlを取得する
```
request.referer
```
https://qiita.com/takazi/items/9b1c82d8fcc602df8a1a

# これを使って一つ前のページにリダイレクトする
```rb
redirect_to(request.referer)
```
成功。

# 感想
これでよかったのだろうか？
結果これで自分の中の問題は解決された。
これを参考にできるかは微妙だ。
士郎。Repositoryを導入するという事は、Eloquentモデルオブジェクトを使わないという事なんだ

## 概要
LaravelでService層以外にRepositoryを導入している記事をいくつか見かけたので、実際にプロジェクトに導入してみました。


## そもそも何か

ちゃっと 「Laravel Repository」と調べると色々出てきます。
デザパタのRepositoryパターンをLaravelで取り入れてみましょうみたいな内容

https://deha.co.jp/magazine/introducing-laravel-repository/

https://enjoyworks.jp/tech-blog/7743

https://www.twilio.com/blog/repository-pattern-in-laravel-application-jp

## 最初に結論、Eloquentモデルを活用したいなら取り入れない方がいい

```php
public function hoge(User $user)
{
//処理
}
```

Userモデルの型としてcontrollerなどから受け取ったり、定義した場合Userモデルに依存する形になるのでRepositoryの

**データの取得先がDBであっても外部のAPIであっても、それを意識することなくデータ操作を行うことが出来る**

というRepositoryのメリットがまず死にます。
``$user->hogehoge()``とかも勿論ダメ

Repositoryパターンを導入するという事は、**Eloquentモデル関連の便利な機能を使わない**という事でもあります。
例えば、ルートモデルバインディングとかも

自分は以下のようになんちゃってRepositoryを取り入れてみました。そして後悔しました。

## 定めたルール
- コントローラー、またはlivewireコンポーネントにはビジネスロジックを書かない
- ``Modelクラス``には定義のみを書く
- ビジネスロジックは``Serviceクラス``に書く
- DB処理は``Repositoryクラス``に書く

## 処理の流れ
```mermaid
flowchart LR;

controller/livewire --> Service --> Repository

controller/livewire 
```
### NG
```mermaid
flowchart LR;

controller/livewire --x Repository
```

### NG
```mermaid
flowchart LR;

controller/livewire --> A-Service --x B-Service
```

### OK
```mermaid
flowchart LR;

controller/livewire --> X-Domain --> A-Service
X-Domain --> B-Service
```
### Repositoryについて

Repository が永続化を担う対象は Entity（より厳密には集約）。

例えば、ユーザーの情報と、ユーザーのプロフィール画像(複数)がある場合、
1モデル1リポジトリで作成すると
- UserRepository
- UserImagesRepository

となるが、ユーザーのプロフィールはユーザーに集約出来る為
- UserRepository

の中にユーザーの画像取得や更新処理を書く。

- [参考記事](https://qiita.com/karayok/items/d7740ab2bd0adbab2e06#service)



## Modelオブジェクトを使用しつつ治安維持、処理置き場としての目的※やめましょう

本来あるべきRepositoryパターンは出来ない(Eloquentと離れたくない)ので、**「集約」**　としての役割で使用しようと試みました。

- Userテーブル
- UserImageテーブル
- UserSettingテーブル

全てUserというドメインとして扱いたい為、各モデルに書く静的メソッド(Hoge::getHogeById()など)をUserRepositoryに全て集約させる。

:::note alert
モデルオブジェクトにはリレーションの定義などだけ記述する
 => モデル貧血症ポイント
:::

:::note alert
Repositoryクラス外ではModelをデータとしてだけ扱い、Repositoryはデータベースアクセスの役割で扱う
 => ActiveRecordを無視する事になる
:::

はい、思いついた時は良さそうと思ったんですが上記のルールはクソです。
Modelの振る舞いにデータベースアクセス系のメソッドがあるので役割がグチャグチャになります。

## お気持ち
- ServiceからServiceの呼び出しを禁止にしたら流れが綺麗になると思った
    - 綺麗になったのは流れだけ。
- Repositoryは必ずServiceクラスから呼ぶ
    - ただの橋渡し処理が増えた、開発がしにくくなった。
- Serviceクラスは適切に分けないとあまり恩恵を感じない


## ちゃんと取り入れようとしたらコストがめちゃかかる
中途半端に使うぐらいなら取り入れない方が良い。

本来あるべきRepositoryパターンを使いたければEloquent禁をしてまでやるメリットがあるかどうか考えましょう。
後工数がめちゃかかります。


## どうしても使いたいなら・・・・

symphonyで使われているORマッパーです。

集約という目的は果たせます

https://github.com/laravel-doctrine/orm
【Swift】初心者のランダム通話アプリ開発奮闘記 #2

# 今日の積み上げ
Xcodeの初期セットアップをやりました。
英語弱者なので、チュートリアルが英語なのがまじできつい、、

![IMG_3451.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/997222/45c79203-8bbe-9d7a-50c3-24cb47950278.jpeg)
若手エンジニア向け：小さな目標設定

ここでの目標設定は、評価制度としてのMBO（Management by Objectives : 目標管理制度）等の評価のための目標設定ではありません。評価に関係なく、自分自身で設定する目標設定の話です。

# とにかく目標設定しよう
仕事をして行く上で、やはり自分自身で目標設定するのは、非常に大事です。そして、個人として将来の目標に向けて目標設定する場合、高い目標設定を行わないと面白くありません。容易すぎて、簡単に実現できてしまっても良いですが、難しい方が達成感が大きいので気持ち良いです。
ミスチルの歌で
```
高ければ高い壁の方が登った時気持ち良いもんな
まだ限界だってみとめちゃいないさ
```
って歌詞が好きです。
諦めずに高い壁にチャレンジしたいです。

ただ、ここの目標設定が高すぎて、目標を見失ってる人が結構います。大事な事は、小さな目標設定をして、一歩ずつクリアして行く事です。千里の道も一歩から。先ずは、そこから始めてみましょう。

# 小学生の時の出来事
僕の小学校の頃の水泳話
```
小学校3年生の出来事です。
喘息持ちの僕は、体育とか水泳とかの授業の時、皆がやってる風景を眺めている傍らの人間。
激しい運動をすると喘息の発作がおこるので、調子の良い日以外は、見学者って奴です。
当然、水泳では、５メートルさえも泳げた事もなく、苦手。苦手。
苦手と思うと、更に精神的に泳げるはずもない状態。
そんな日々をすごす中、水泳の記録会がありました。
当然、憂鬱な気持ちで水に使って、スタートの笛が鳴るのを待っている僕。
「ピーッ」と笛が鳴り、プールの壁を蹴り付けた時、プールの底の５メートルの線が目に入る。
「よっしゃ、あの５メートルの線まで泳いだらやめよう。」
自分にとっては、好きで無い水泳なので、早くあの５メートルを超えたい気持ちで一杯です。
一生懸命に腕を動かしてました。すると思ったよりも、簡単に５メートルを超えました。
昔から欲張りな人間だったんですね（笑
「じゃー１０メートルまで頑張ってみよう。」
１０メートルの次は、１５メートル。２０メートル。
２０メートルを超えると、プールの壁が見えてくる。もう限界だと思う気持ちと、後少しと思う気持ちが入り乱れながらも、死ぬ気で腕を動かし続けました。
正に一心不乱。
気が付いたらゴールの壁に手が付いてました。
初めて２５メートルを泳いんだんです。しかも、一心不乱に泳いだお陰もあり、クラス中の高タイムを出せました。
```
所詮、小学生のプールの出来事。しかも、たったの２５メートル泳いだだけの出来事ですが、この出来事は今でも鮮明に覚えてます。

# まとめ
この出来事は僕に2つの教訓を与えてくれました。
１．人間やれば出来る。不可能なんて無い。
２．高い目標もプールの白線の様に少しづつ目標を置いて、少しづつクリアしていけば良い。
高い目標も出来ると信じて、小さな事からコツコツと頑張る事。やれば出来るさ。

今後も続けていきますので、フォロー、イイね、シェアお願いします。
下記、説明会もご参加下さい。
[エンジニア年収アップ講習(転職サポート付き！)　無料説開会　12月6日　19時開催](https://cto-can-be.hp.peraichi.com/)
各種ダウンロード、インストール方法などまとめ


# はじめに

この記事は、各種ダウンロード、インストール方法などをチートシートのような形でまとめた記事となります。

少しずつ追加していきますので、もしよかったら参考にお使い下さい。

# 1. jQuery

jQueryの導入には2つの方法があります。

❶ CDNで読み込む方法❷ ダウンロードする方法

### ・CDNで読み込む方法

　[jQuery公式/CDN](https://releases.jquery.com/)

jQuery公式サイトからCDN経由で利用できるURLが掲載されています。
一番上の最新バージョンの中に、いくつかファイルが用意されており、
「コメントや改行などがあって見やすい、容量が大きい」ものが希望であれば、非圧縮（uncompressed）。
「軽量で高速」なのが希望であれば、圧縮「minified」をお使いください。
一般的には、開発段階は「uncompressed」、公開後は「minified」で使い分けられる方が多い印象です。

### ・ダウンロードする方法

　[jQuery公式/Download](https://jquery.com/download/)

[右クリック]→[名前を付けてリンク先を保存]でローカル環境に保存する。（保存場所は任意でOK）

![jQuery.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985441/00654224-bd64-f7b0-d21a-e9bd3826f684.jpeg)
※ jQuery 3.6.1は2022年11月時点のバージョンです。


HTMLファイルの```</body>```タグ直前に```<script>```タグを用いて jQuery ファイルを読み込ませる。
※ ここではjsフォルダを作成し、その中jQueryファイルを保存しています。

[![Image from Gyazo](https://i.gyazo.com/9a5c397696b72f2376a5efb19241f6cd.png)](https://gyazo.com/9a5c397696b72f2376a5efb19241f6cd)


<hr>




（※他作成中）
SwiftUI タップと長押しができてスクロールにも干渉しないButton

# 完成品
```LongPressableButton.swift
//  LongPressableButton.swift
//  Created by : Tomoaki Yagishita on 2021/09/15
//  © 2021  SmallDeskSoftware
//  Modified by 松本幸太郎 on 2022/11/29.

import SwiftUI
struct LongPressableButton<Label>: View  where Label: View{
    
    let label: (() -> Label)
    let tapAction: (() -> Void)?
    let longPressAction: (() -> Void )?
    let minimumDuration:Double
    
    init(label: @escaping (() -> Label), tapAction: (() -> Void)? = nil,
 longPressAction: (() -> Void)? = nil, minimumDuration: Double = 0.5) {
        self.label = label
        self.tapAction = tapAction
        self.longPressAction = longPressAction
        self.minimumDuration = minimumDuration
    }
    var body: some View {
        Button(action: {}){
            label()
                   .onTapGesture(perform: {tapAction?()})
                   .gesture(LongPressGesture(minimumDuration:minimumDuration)
                                 .onEnded({_ in longPressAction?()}))
             }.buttonStyle(.plain)
                    //buttonStyleはdefault以外にしないとrow全体が反応する。
    }
}
```

# 動作確認用
```ContentView.swift
import SwiftUI

struct ContentView: View {
    @State private var text = "状態表示"
    var body: some View {
        VStack{
            LongPressableButton(label: {Text("ボタン")},
                                tapAction: {
                text = "タップされた"},
                                longPressAction: {
                text = "長押しされた"},
                                minimumDuration: 1.0/*長押し判定の時間*/
            ).font(.title)
                .padding(.horizontal, 5.0)
                .background(.quaternary)
                .cornerRadius(3)
            Text(text)
        }
    }
}

struct Previews_File_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

# 経緯
こちらのLongPressableButtonを使わせていただいていましたが、ボタンがスクロールに干渉していたので、stackoverflowで上記のコードの解説を見つけました。


https://software.small-desk.com/development/2021/09/26/swiftui-howto-longpress-able-button/

https://stackoverflow.com/questions/57700396/adding-a-drag-gesture-in-swiftui-to-a-view-inside-a-scrollview-blocks-the-scroll

# 解説
まず、普通のButtonの動作について。Buttonは指が触れるとタップイベントを受け取り、少し薄暗く変化し、指が離れたらactionが発火します。
row上のbuttonは触れられると、同様にまず薄暗く変化しますが、そのまま上下にスクロールするとイベントはsuperviewであるrowかlistに渡されるため、スクロールができます。
ただしLongPressableButtonのように、Buttonに.simultaneousGestureをつけるとこのイベントの伝達をしてくれなくなるようです。
そこでButtonのイベント伝達機能を使いつつ、独自機能を追加したい場合は、buttonのactionには何も書かず、labelにジェスチャーをつけると良いようです。
こうすることでaction付きのlabelをbuttonでラップできている?のだと思います。



# 雑記
今回、このLongPressButttonを一般化する際に、ほぼほぼオリジナルのLongPressButtonを真似しました。これからジェネリクスなどもきちんと学びたいです。
ストーリー仕立てで理解する、AWSのIAM周りとアカウントの超入門知識

CYBIRD Advent Calendar 2022の7日目を担当します、新卒1年目の@tomoko_ishizakaです。6日目は@cy-yuka-WP さんの「Google スプレッドシートやExcelで知っていると便利な関数」でした。

## この記事の概要

最初自分がAWSのアカウントやユーザー、そしてIAMについて聞いたとき、非常に複雑で混乱してしまった。そこで本記事では、多くの人が知っているであろうソーシャルゲーム（以下ソシャゲ）（ダンジョン/素材集め/ガチャ等の機能がある一般的なものを想定している）を効率よくプレイしようとする主人公(:boy_tone1:)のストーリー仕立てで、IAMの概観をざっくりとふんわりと説明していく。

※実際にAWSのIAMのような機能を搭載しているソシャゲはおそらくありません。フィクションです。

## (最初に少しだけ)AWSとIAMについて
### Amazon Web Services (AWS)  とは
Amazonの提供するクラウドコンピューティングサービス。
つまり、サーバーやデータベースなどをクラウド上で作成/管理できるサービスのことである。

### AWS Identity and Access Management (IAM) とは
AWS リソースへのアクセスを安全に管理するためのウェブサービス。
つまり、誰(もしくは何)が、何をできるのか？を管理する仕組みである。

## アカウントとルートユーザー

:boy_tone1:「最近流行りのソシャゲを始めるぞ！まずは、メールアドレスとパスワードを設定して、アカウントを作るみたいだ。」

AWSの機能を利用するには、ゲームのログインと同じように、メールアドレスを使ってAWSアカウントを作成する必要がある。なお、AWSでは、メールアドレスを使ってログインしたユーザーは、ルートユーザーと呼ばれ、アカウントにあるリソースを全て利用できる。

## IAMユーザー

:boy_tone1:「ソシャゲ楽しいなあ。ダンジョン周回、ガチャ、武器の錬成、毎日やりこんでいる。欲を言えば誰かに代わりにダンジョン周回とかやって欲しいなあ。このアカウント情報を友達に渡せば友達もログインできるぞ。でも、自分のメアドとパスワードを渡すのはちょっと嫌だし、いい方法でこのアカウントに友達をログインさせたいなあ。。。」

AWSには、そんな機能を実現するためのIAMユーザーというものがある。これは、１つのアカウントに複数の人間が入れるようにしたものだ。IAMユーザーはメアドとパスワードではなく、ユーザー名とそのユーザー名に対応するパスワード、そしてAWSアカウントIDの３つを使ってログインする。

## IAMポリシー

:boy_tone1:「よし、これで友達が自分のアカウントに入って、ダンジョン周回とか手伝ってくれるようになったぞ。でも、、、勝手にガチャとか回されたらやだなあ。。ダンジョン周回だけしかできないようにしたいな。」

AWSには、そんな機能を実現するためのIAMポリシーというものがある。IAMポリシーとは、AWSリソース(EC2やS3など)への権限が書かれた設定のことで、例えばDatabaseAdministratorというポリシーは「データベースの作成、設定、メンテナンスを行うためのアクセス許可」という内容だったり、Billingというポリシーは「請求、コスト、支払い方法、予算、レポートを管理できる」という内容だったりする。他にもさまざまなポリシーがAWSによってあらかじめ用意されている。なお、自分で新たにポリシーを作成することもできる。

そして、このポリシーをIAMユーザーに付与すると、そのユーザーはポリシーで設定された権限を持つようになる。

## IAMポリシーの複数付与

:boy_tone1:「これで友達にはダンジョン周回の権限だけを与えることができて安心だ！でも、ダンジョンだけじゃなくて、武器の強化も勝手にやってて欲しいなあ。」

AWSのIAMポリシーは、複数付与することができる。例えば特定のユーザーにDatabaseAdministratorとBillingという２つのポリシーを適用すれば、そのユーザーはデータベース関連のアクセスと請求周りの管理の両方の権限を持つことになる。（※実際の運用に適している例ではありません）

## IAMグループ

:boy_tone1:「他の友達も何人かゲームを手伝ってくれることになったぞ。でも、全員にまたダンジョンの許可やら武器強化の許可やらを与えないといけないのは、面倒だなあ。一気に全員同じ許可を与えたいなあ。」

AWSには、そんな機能を実現するためのIAMグループというものがある。グループを作成し、IAMユーザーをそこに含めることができる。ポリシーはグループに付与することもでき、その場合ユーザーには、所属するグループに付与されたポリシーが適用される。

## IAMロール

:boy_tone1:「新しいソシャゲを始めたぞ！また友達に手伝ってもらいたい。こっちでも彼らのユーザーを作るのはちょっと手間だし管理も面倒だなぁ….以前のソシャゲで渡したユーザーのアカウントでこっちにもログインして欲しいな。」

AWSには、そんな機能を実現するためのIAMロールというものがある。
すでにIAMユーザー（以降ユーザーA）が存在するアカウントをA、そのユーザーでアクセスしたいアカウントをBとする。まずBにてIAMロールというものを作成し、そのロールに必要なポリシーを適用する。さらにそのIAMロールに「アカウントAのユーザーAを信頼する」ポリシーを付与し、ユーザーAには「Bのロールを許可する」ポリシーを付与することで、ユーザーAはアカウントBに入って許可された操作をすることができるようになる。

:boy_tone1:「よし、これで友達が新しい方のソシャゲも手伝ってくれるようになったぞ。欲を言えば、最近流行りの自動化ツールを導入したい。でも、もしツールがバグって勝手にガチャとか回し始めたらやだな…」

AWSでは、IAMポリシーを直接AWSサービスに付与することは基本的にできないが、IAMロールを通してであれば付与することができる。ユーザーへの付与と同様に、まずポリシーを適用したロールを用意し、それをサービスに付与することで、サービスの操作権限を設定することができる。

## おわりに

いかがでしたでしょうか…？
まだ一年目なので理解も甘いところがあるかとおもいますが、少しでも苦手意識なくIAMまわりについて読めればと思い本記事を書きました。

:boy_tone1:「わーい、これでソシャゲ無双だああ！」※だめです

明日のCYBIRD Advent Calendar 2022 8日目は、@moffunnya さんの「Terraformを使った環境構築入門（AWS）」です！
見た目重視でoutline:none;やoutline:0;を指定する必要は本当に無くなった

## この記事の概要

以前[見た目重視でoutlineを消したいにしても、せめてこうしませんか？](https://qiita.com/xrxoxcxox/items/82e083b3f47309873262)という記事を書きました。
当時は[what-input](https://github.com/ten1seven/what-input)というライブラリを提案をしていたのですが、最近のブラウザアップデートでいよいよ不要になった感があり、記事にしました。

## これまで起きていたこと

非常にざっくりとまとめると以下のようなことが起きていました。

- buttonやinputなどの要素はフォーカスが当たるとフォーカスリングという輪が表示される
- 上記の要素を**クリックした際**もフォーカスリングが表示されるため、見た目を好ましく思わずに`:focus { outline:none; }`のようなコードを書く
- 結果、クリックした際だけでなく、**キーボード操作でフォーカスを当てた際も**フォーカスリングが表示されなくなってしまう

クリック時、このように枠線がつきます。
色や太さは変えられるものの「そもそも枠がつくこと自体が嫌」と消されていた印象があります。

| リンク | ボタン |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f914b5bd-5483-fdd2-ac71-20955cbaffe0.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/517a1586-db17-d5f8-1a6a-9e75f9a1525d.png) |

## `:focus-visible`の挙動がデフォルトになった

`:focus-visible`はタブ移動のときだけoutlineを表示させる擬似クラスです。

これまで使われていた`:focus`はタブでもマウスでもoutlineを表示させていたので`outline:none;`が指定されてしまいがちでした。

今ではユーザーエージェントスタイルシートでは`:focus`ではなく`:focus-visible`が使われています。
これにより、特に何も指定せずとも「マウスではフォーカスリングが表示されず、キーボードでは表示される」状態になっています。

## リリース情報

Chrome

https://chromestatus.com/feature/5658873031557120

Firefox

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/85#css

Safari

https://webkit.org/blog/12445/new-webkit-features-in-safari-15-4/#css

## 最後に

前の記事を書いたのが2021年4月18日で、Chromeで`:focus-visible`がデフォルトになったのが2021年4月14日のようでした。
タイミングが悪過ぎます。

Safariが対応したのが2022年3月14日でバージョンが15.4なので、まだ`:focus-visible`が完全にデフォルトとも言い切れないのですが、割と時間の問題かと思っています。

いずれにせよ、ブラウザのデフォルトの挙動に任せればアクセシビリティも高く、見た目も良いのは嬉しいです。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox

Devトークでのお話してくださる方も募集中です！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/489
Xcodeビルドエラー ld: library not found for -lBVLinearGradien

Xcode(Version 13.4.1)シミュレーターiPhone12 ReactNative資産ビルドで以下のエラーがでてビルドできなくなりました。

ld: library not found for -lBVLinearGradien

ライブラリのパスが通っていないのかと思いましたが、macのOSバージョンとXcodeのバージョンの最新化でビルドできるようになりました。

OSが最新化されていないと、App Storeから確認できるXcodeのアップデート情報も出ないようで、最新の状態になっていると勘違いしてしまったので、OSのアップデート状況も確認したほうが良さそうです。

■実施した手順
・Xcodeのアンインストール（ゴミ箱へ入れる）
・Xcodeのインストール→現状のmac OSでは最新のXcodeをインストールできないと怒られる
・mac OSの最新化
・Xcodeのインストール
・ビルド
クラウドサービスを使う際のトラブル

# 概要
IaaS、PaaS、SaaS、
クラウドストレージに各種フォームサービス、などなど。
クラウドサービスって便利ですよね。

これらの浸透により、
フルスクラッチでサービスを自作するよりも、
手軽なサービスを利用した方が、開発・運用コストは安く済むでしょう。

```
しかし、、、
自動車や飛行機がそうであるように、
絶対安全なサービスはまずないと思います。

この記事では、
そんなクラウドサービス利用時のトラブル事例について紹介します。
```

# 対象とする読者
+ クラウドサービスに興味がある方
+ クラウドサービスを利用中の方
+ **その中で、トラブルに対して備えたい方**


# よくあるトラブル事例
以下は、私が有償のクラウドサービスを利用していた際に発生した、トラブルの事例です。

## ライセンス切れに気づかない
有償サービスには基本、ライセンス（使用許可証）が存在します。
ライセンスには有効期間があり、それを更新しなければサービスは使えなくなります。

サービス自体のライセンスは、事前の通知などで気付きやすいのですが、
サービスによっては、
**個々の製品** や **API** に個別のライセンスが設定されていて、
しかも、**有効期間がサービス自体のそれと違う** なんてこともあります。
サービス自体は使えるのに API が動かない、
そんなこともありました。

この辺りはサービスを使う前に
「**どの製品（API）にいつまでのライセンスがあるのか**」を確認、管理しておく必要があります。
もしくは、自動更新の仕組みや通知を、サポート経由で相談しても良いでしょう。


## サポート対応がいまいち

有償サービスには大体サポートが付きます。
ただ、これがどこも同じレベルかというと、そうではありません。
大きなサービスでも、ダメな所はダメです。

特に海外のサービスでは、
返答がなかなか返って来なかったり、
そもそも英語なので会話し辛い、ということもあるでしょう。

とはいえ、お金を払っているので、
前者は、担当者を変えてもらうなど、文句を言っても良いと思います。
後者は、**大きな企業なら大体日本の窓口があります**ので、
そこを通してもらうと良いでしょう。

もしお金があるのであれば、中継企業※の力を借りるのも手です。

※中継企業：海外の企業との連絡の橋渡しとなる企業


## 製品の不具合

クラウドサービスでも当然不具合は発生します。
サービス側が報告してくるケースもあれば、
利用者が偶然発見することもあるでしょう。

サービスを使う我々エンジニアからしてみれば、サービス側の不具合ですが、
エンドユーザからみれば、どちらも同じ不具合です。

自前で改修できない分、スケジュールを立てにくいので、
前述のサポートとの連携を密にしておく必要があるでしょう。

改修されるまでは、以下の点の考慮が必要です。
+ サービス側への改修見込みの確認
+ エンドユーザへの復旧までのアナウンス
+ サービスの不具合を回避する迂回策
  - 該当機能の使用を抑止する、不具合が出る手順をエンドユーザに明示する など


## サービスの譲渡
サービスは継続するが、違う会社に譲渡されてしまうケースです。

サービスの内容が変わることもあれば、
利用条件や契約内容が変わる可能性があります。

サポートなども停止してしまう可能性が高いので、
譲渡先の担当者と密に話をしておく必要があります。

ざっと確認するとしたらこんな所。
+ **今まで通りに機能が使えるか**
+ **契約面の確認**（期間や金額はどうなるのか）
+ **新しい担当者の確認**
  - 今までの担当がそのまま引き継ぐとは限らない
  - 知らないうちに自社との担当がいなくなる、ということも


## サービスの停止（サ終）
サービス自体が終了してしまうケース。
こうなると移行先の別サービスを探すか、自作するしか手が無いでしょう。

以前、急にサービス終了通告を受け、
他に同様のサービスが無いため、フルスクラッチで自作する、
という事態に遭遇しました。

幸い、アナウンスと同時に即時終了することはまずないので、
**終了までの猶予期間で、他サービスへの移行や自作の道筋を立てましょう。**


# まとめ
いかがでしょうか。
クラウドサービスは、サービスを**仮想的**に提供してくれますが、
反面、サポート対応やサービス終了などの**物理的**な欠点もあります。

全体的に、クラウドサービス側と連携を密にすることで、
ある程度のトラブルは防げると思います。

## 教訓
クラウドサービスは、
契約したら何も考えずに使っていればOK！
ではなく、
**サービスの状況（ライセンスなど）を都度確認したり、
サポート担当と連絡を密にすることも大事、**
ということを覚えておきましょう。

**クラウドサービスごとにチーム内で担当者を決めておき、
契約周りやライセンス、サポートとの会話の記録を整理しておく**と
チーム内での連携や引継ぎもできて便利です。
ディレクトリ環境構築しながら、Linuxコマンドを覚える

## ディレクトリ生成
[root@localhost ~]# cd ../home
[root@localhost home]# mkdir A1

### cd ../home
現在の作業から一つ上の階層にあるhomeに移動。
### mkdir A1 
ディレクトリA1を生成

## ユーザー作成及びパスワード生成
useradd test01
passwd test01

### useradd test01
ユーザ作成
### passwd test01
パスワード生成

## グループ作成
[root@localhost home]# groupadd B1
[root@localhost home]# ls -al
### group add B1
グループB1を生成
### ls -al
ファイルとディレクトリの一覧が表示
-a:すべてのファイルやディレクトリを表示
-l: ファイルやフォルダの情報を表示

下記のような文字列が表示される
drwxr-xr-x.  2 root      root        6 1月 24 00:00 A1
#### 先頭の10文字に書かれている文字の意味
d:ディレクトリ
r:読み取り
w:書き込み
x:実行権限
2文字目から4文字目までは所有者に対して、
5文字目から7文字目では所有グループに対して、
8文字目から10文字目はその他に対して情報を表示。

2は、ファイルやディレクトリへのリンク数
rootは、所有者
その次のrootは所有グループを表示している。
6はファイルサイズ
1月 24 00:00 は最新更新日時
A1はディレクトリ名

## 所属グループの変更
[root@localhost home]# chgrp B1 A1
### chgrp B1 A1
B1がA1ディレクトリを使用可能になった。

[root@localhost home]# ls -al
drwxr-xr-x.  2 root      B1          6 11月 24 00:00 A1
所有グループの箇所の名前が変わる

###パーミッション変更　書き込み許可
chmod g+w A1
A1のに対して、B1が書き込めるようになった。
一方で削除する場合は、-Wとする。
[root@localhost home]# ls -al
drwxrwxrwx.  2 root      B1          6 11月 24 00:00 A1
5文字目から7文字目にwが表示されている。

## ユーザをグループに所属させる
[root@localhost home]# usermod -G B1 test01

## グループに属しているか確認
[root@localhost home]# groups test01
test01 : test01 B1

## 書き込み
[test01@localhost ~]$ pwd
/home/test01
[test01@localhost ~]$ cd ../A1
[test01@localhost A1]$ echo 'abc' >test.txt
[test01@localhost A1]$ vi test.txt

### pwd 
現在位置を表示
### echo 'abc' >test.txt
abcという文字列をtest.txtに書き込む
MetaGymとは💪

# MetaGymとは
![3W9qbK5I_400x400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/d2a35dd4-e13b-3052-f9ef-5a297c36a75b.jpeg)


- スマートウォッチと連携して行う”Exercise to Earn”アプリ。
- NFTアバター（MetaGym Buddies）を所持してフィットネスチャレンジを達成するとHRT（Heart Rate Token）が稼げる。HRTは新しいNFTクローズを買ったりアップグレードできたりする。
- App内マーケットプレイスを通してユーザーは効率的にHRTを稼ぐためにさまざまなNFTアイテムを購入することができる。
- NFTアバターを貸し出してHRTを稼ぐこともできる。

# Mission

- 世界をより健康的な場所にするという共通の目的をサポートするコミュニティ作成を目標とする。

# 特徴

- Fit-Fi, Sleep-Fi, Game-Fiがある。
- Polygon blockchain。
- ウォレットを接続することによってプレイすることができる。
- 持っているNFTアバターによって稼ぎが変わってくる。
- NFTアバターをリースすることもでき、7：3で3割のHRTがもらえる。
- 初期はカーディオのみ。

# トークン獲得方法

- カーディオ
- 筋トレ
- 食事
- 回復
- 瞑想

→[詳細](https://www.meta-gym.io/whitepaper/e2e/earning-modalities)

# Tokenomics

### HRT (Heart Rate Token)

HRTはアプリ内ユーティリティトークン。さまざまな獲得様式を通して稼ぐことができる。無制限に発行され、価格を維持するために以下のバーンメカニズムを取り入れている。

- NFTアバターの購入
- NFTアバターのアップグレード
- NFTアバターのカスタマイズアイテムの購入
- アプリ内チャレンジの失敗罰金
- NFTアバターの修復

### MGCN (Metagym Coin)

MGCNはMetagymのガバナンストークン。トータルの供給量は20億。MGCNはBitcoinのようにデフレになるように設計されていて、3年ごとに供給量が半減するようになっている。

# 最後に
![Frame 9 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/87f2a488-c5cd-549d-f07f-01b44a1317b8.png)
<b>Veroo</b>は、Blockchain技術を活用した「想いの巡るグルメSNSアプリ」です。食に対する熱量、例えばラーメンがめちゃくちゃ好きで年間400杯食べているとか、変態的に具材にこだわった中華料理を作っているなどのような、今まで直接お金にはならなかった食に対する情熱や熱量、その裏側にある想いがトークンを使うことで巡る世界。自分のラーメンに費やす熱量がコミュニティに承認される。自分がほんとにいいと思って作った食べ物がコミュニティで広まる。Verooは単なるSNSアプリではなく、クリエイターたちの想いが紡がれるソーシャルグルメアプリです。

##### Homepage: https://veroo.xyz/
##### Discord URL：https://t.co/VoT0gpsflA
代表的なGit コマンド　一覧

# Gitコマンド　
### 初期設定
名前とメールアドレスを登録
git config --global user.name "AAAAA"
git config --global user.email "AAAA@AAAA.com"
### 設定の確認
git config --list

## ローカルリポジトリを作成し、リモートリポジトリにプッシュ
### ローカルリポジトリの生成
git init
### ファイルをインデックスに追加
git add ファイル名
### git commit 
ローカルリポジトリにインデックスの変更箇所を保存
### git remote add [追加するリモートリポジトリ名] [追加したいリポジトリ]
指定した名前にリモートリポジトリのアドレスを関連付ける
### git push [作成したリポジトリ名] [ブランチ名]
ローカルリポジトリの変更箇所をリモートリポジトリにアップロード

## リモートリポジトリからローカルリポジトリにダウンロード
### git clone リモートリポジトリのSSH
リモートリポジトリの内容をローカルリポジトリにダウンロード

## リモートリポジトリの変更点をローカルリポジトリのブランチに取り込む
### git pull　[作成したリポジトリ名] [ブランチ名]
リモートリポジトリの最新状態をローカルリポジトリにダウンロード

## リモートリポジトリの最新情報をローカルリポジトリのブランチに取り込む
### git fetch origin/master 
現在のリモートリポジトリの最新情報を取得
### git merge origin/master 
origin/master の変更箇所を現在のブランチに取り込む

## ブランチの生成
### git branch main
ブランチmainを生成

## mainBブランチへ切り替え
### git checkout mainB
指定したブランチに切り替え

## ブランチの一覧表示
### git branch 
ブランチの一覧表示


参考記事
https://qiita.com/kohga/items/20819414da2972bc5e0d
https://qiita.com/yukibe/items/9ef9d54f2e7d53cfb51c
https://www.sejuku.net/blog/71492
https://qiita.com/wann/items/688bc17460a457104d7d
DatabricksにおけるSparkを用いたMLflowエクスペリメントへのアクセス

[MLflow experiment \| Databricks on AWS](https://docs.databricks.com/external-data/mlflow-experiment.html) [2022/11/9時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

MLflowエクスペリメントデータソースは、MLflowエクスペリメントのランデータをロードするための標準APIを提供します。[ノートブックエクスペリメント](https://qiita.com/taka_yayoi/items/ba0c7f46ff7c3dbf87bb#%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88)から、あるいはエクスペリメント名、エクスペリメントIDを用いてデータをロードすることができます。

# 要件

Databricks機械学習ランタイム6.0以降。

# ノートブックエクスペリメントからデータのロード

ノートブックエクスペリメントからデータをロードするには、`load()`を使います。

```py:Python
df = spark.read.format("mlflow-experiment").load()
display(df)
```

```scala:Scala
val df = spark.read.format("mlflow-experiment").load()
display(df)
```

# エクスペリメントIDによるデータのロード

1つ以上のワークスペースエクスペリメントからデータをロードするには、以下の様にエクスペリメントIDを指定します。

```py:Python
df = spark.read.format("mlflow-experiment").load("3270527066281272")
display(df)
```

```scala:Scala
val df = spark.read.format("mlflow-experiment").load("3270527066281272,953590262154175")
display(df)
```

# エクスペリメント名によるデータのロード

`load()`メソッドにエクスペリメント名を指定することもできます。

```py:Python
expId = mlflow.get_experiment_by_name("/Shared/diabetes_experiment/").experiment_id
df = spark.read.format("mlflow-experiment").load(expId)
display(df)
```

```scala:Scala
val expId = mlflow.getExperimentByName("/Shared/diabetes_experiment/").get.getExperimentId
val df = spark.read.format("mlflow-experiment").load(expId)
display(df)
```

# メトリクスとパラメーターに基づくデータのフィルタリング

このセクションのサンプルでは、エクスペリメントからデータをロードした後にどの様にフィルタリングできるのかを示しています。

```py:Python
df = spark.read.format("mlflow-experiment").load("3270527066281272")
filtered_df = df.filter("metrics.loss < 0.01 AND params.learning_rate > '0.001'")
display(filtered_df)
```

```scala:Scala
val df = spark.read.format("mlflow-experiment").load("3270527066281272")
val filtered_df = df.filter("metrics.loss < 1.85 AND params.num_epochs > '30'")
display(filtered_df)
```

# スキーマ

データソースによって返却されるデータフレームのスキーマは以下の様になります。

```
root
|-- run_id: string
|-- experiment_id: string
|-- metrics: map
|    |-- key: string
|    |-- value: double
|-- params: map
|    |-- key: string
|    |-- value: string
|-- tags: map
|    |-- key: string
|    |-- value: string
|-- start_time: timestamp
|-- end_time: timestamp
|-- status: string
|-- artifact_uri: string
```

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Terraform、後から来る辛みと処方箋🌶

## この記事は
[株式会社 RetailAI X Advent Calendar 2022](https://qiita.com/advent-calendar/2022/retail-ai-x) の 3 日目の記事です。
Terraform + Config Controller を使って IaC を運用する話です。

ご存じの通り、Terraform は、環境構築の再現性という意味で、とても役立ちます。
一方で、`tfstate` を維持・管理していくのはとても手間がかかります。
運用を楽にしたい！
という願望からたどり着いた現在地について書いていきます。

## なぜ Terraform がつらいのか🌶？
一番の辛みは、誰かが GUI で変更した場合、回収する（`tfstate` を同期させる）必要があるということです。
正しく回収しないと、、、conflict が発生し、最悪、Resource が削除される可能性があります。

そして、誰もが `.tf` を編集・適用できるわけではないため、GUI での変更は許容する必要があります。

### これまでの運用の流れ
![Advent Calendar_2022 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569971/52453972-97e2-e6eb-9a45-b59da375d9b1.png)

mission critical なシステムの場合、`terraform apply` なんて気軽にできません。
それでいて、復元は一刻を争います。
難易度が高杉です。

そこで、ぼくは、[Config Connector](https://cloud.google.com/config-connector/docs/overview?hl=ja) について再考しました。

実は、Config Connector が発表された当時は、
**「IaC のために、Cluster が必要なのかー、、Terraform で十分かな 🤔」**
と思っていました。

## なぜ Config Connector か 🙌？
`tfstate` ファイルの維持から解放されます。そして、plan / apply のループから解放されます。
- Config Connector　は、状態を宣言します。Status ファイルは、存在しません。
- k8s の知識を活用できます。
Config Connector では、k8s の namespace を Project や Folder として扱います。
Multi Project を管理する場合は、Project が namespace として並びます。
Project と GKE の位置関係が逆転しているような。個人的に面白いと思う構成です。

### Config Connector の流れ
1. Config Connector を有効にして Cluster を作成する。
   ```
   kubectl get ConfigConnectorContext -n config-control
   ```
1. Manifest を作成する。
   ```
   vi tokyo-bucket.yaml
   ```
   ```
   apiVersion: storage.cnrm.cloud.google.com/v1beta1
   kind: StorageBucket
   metadata:
     annotations:
       cnrm.cloud.google.com/force-destroy: "false"
     name: sanbox-danny
     namespace: config-control
   spec:
     location: asia-northeast1
   ```
1. Apply する。
   ```
   kubectl apply -f tokyo-bucket.yaml
   ```

とても単純です。
また、Project 全体の状態を意識する必要がありません。
追加する Resource に集中できます。

また、これまで目をつぶってきた以下の課題を解決してくれます。
その課題は、[Terraform Cloud](https://cloud.hashicorp.com/products/terraform) の管理です。
- Terraform Cloud（ **Free** ）の課題
    - User 数の制限
    - セキュリティ（認証）
    - Concurrency の制限

Config Connector にすることで、Terraform Cloud は不要になります。

　*Terraform Cloud は、2019 年に Goole Cloud と Azure の Multi Cloud を検討したことをきっかけに利用開始しました。当時は、PoC と言う位置付けで、そのまま現在に至ります。*

## Config Connector の事例はある？
メルカリさんで[事例](https://engineering.mercari.com/blog/entry/20220126-shifting-to-zero-touch-production/)が公開されています。
こちらは、おそらく、Managed ではありません。

## 終わりに
現在、Terraform への注目度は非常に高いです。
GitHub が発表した、この 1 年の GitHub の利用動向などをまとめた年次レポート[「Octoverse 2022」](https://octoverse.github.com/2022/top-programming-languages)をみるとわかる通り。
急増したプログラミング言語のトップは、Terraform などで使われる HCL だったそうです。
一方で、ぼくのような辛さを感じている人も少なくないと思います。
共感していただける人、別の解決方法を共有していただける人がいましたら、コメントいただけると嬉しいです。

明日 4 日目の記事は @wu_manning さんの「[next.js初心者入門記事](https://qiita.com/wu_manning/items/9c4b7523897dd82c5d17)」です。お楽しみに！
mtgについての考え。備忘録

どんな会社でもどんな仕事でも、mtgというのは絶対に欠かせない事項である。
だがmtgはやり方を間違えればいろんな人の時間を浪費することになる。
時間をとって何も決まらない会議、今までよく見てきた。
それに対して、自分が考えてルール決めし、ファシリテートしてきたことを、ゆるいフレームを備忘録としてここに残す。
ほんとにシンプルで当たり前のことしか書いてないが、これもできてないmtgが多いので。

## **mtgする場合の基本の取り決め：**
- ファシリテーターを決める。
- 議事録とる人も決められたらなおよし。
- 相談mtgなら、問題が解決するための最低メンバー・人数にする
- アジェンダ、ゴールは事前にまとめる
- 30分以内で切り上げることを目指す

## **ファシリテーター**
ファシリテーターはアジェンダとゴールに沿って、全ての事項を決め切れるように会議を進める意識を持つ。
場合によって話を切り替えるなども恐れないこと。かつ、意見へ耳を傾けること。

## **参加者**
決定権のある者、議題についての主な開発担当者など、ゴールを達成するための最低人数を目指す事。4人以下が望ましい

## **アジェンダとゴール**
- 議題はできるだけ簡潔に記述することを意識する。
- 各議題に対してゴールを設定すること。
- ゴールとは、何が決まればこのmtgの目的が達成されるのかということ。
- 具体的な内容に絞り込む。

## **mtg時間**
できるだけ短くする。30分で終わることを目指す。
ブレストなど、mtgで案をたくさん出すという目的ならば、時間はもっと取っても良い。
目的、ゴールが確実に達成できるために適したmtg時間を用意する。

## 事前に参加者に共有する情報
- アジェンダとゴール
- mtg目的の種類を明確に伝える（合意？相談？ブレスト？）
何についてのMTG？「リソースをAからBに回せないか“相談“したい」とか
- その他、用意してから持ち込んでもらいたい情報など

## 議事録に書くこと
前述の事項に加え
・MTGで決まったこと、決まらなかったこと
・次回のアクション

# 健全なmtg、やっていきたい！
これから先の人生、ぎゅっと濃くて意味のあるmtgだけをやっていきたいものです！
curlのレスポンスをheaderとbodyで分けて取得する

外部APIにてレスポンスにてheaderから取得する場合があったので、備忘録として残します。
他何かいい方法あればです。
```php

$url = 'https://****.com';
$headers =  array("Content-Type: application/json");
$post_data = json_encode([1 => 'a']);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // curl_exec() 経由で応答データを直接取得できる
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

// headerとbodyを取得
$header = substr($result, 0, $info["header_size"]);
$header = $this->get_result_header($header);
$body = substr($result, $info["header_size"]);

private function get_result_header ($header) {
    $_header = str_replace("\r", '', $header);
    $tmp_header = explode("\n", $_header);
    $res = array();
    foreach ($tmp_header as $row_data) {
        $tmp = explode(': ', $row_data);
        $key = trim($tmp[0]);
        if ( $key == '' ) {
            continue;
        }
        $val = str_replace($key.': ', '', $row_data);
        $res[$key] = trim($val);
    }
    return $res;
}
```
Q.margin: 0 autoってなんなの？

「なんかいい感じに右揃えしてくれるヤツ」くらいの認識だった。

# 結論
**「親要素の幅から自分自身の幅を引き算した値を自動的に設定するよ」という文。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/25cf0579-ef93-c001-0951-b0cc78d7e2f6.png)

たとえば中央揃えのときは`margin: 0 auto`と指定してあげれば、わざわざプロパティに適切な値を求める計算式を書かなくても **CSSが勝手に適切な幅を計算して要素の両側に空白を入れてくれる** ...ってワケ。

これを`margin-left`だけに指定すれば右揃え、`margin-right`なら左揃えも可能。おもしろい。
v-checkboxのラベル上にdisabledのv-iconを設置し、イベントが伝播しないようにする

## 状況

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/b4dc9164-ab16-f833-5522-57470d55ba2e.png)
このようにv-checkboxを利用し、v-iconをその中に設置したいというケースはよくあると思われる。
そして一番上の要素の上矢印はクリックできないようにするという仕様。

v-checkboxでラベルの一番右まで対象になってしまっているため、何もしないとv-iconをクリックしたときに同時にcheckboxも反応してしまう。

この問題の対処法としては
```
<v-icon @click.stop="hoge()">mdi-arrrow-down</v-icon>
```
のようにstopイベント修飾子で対応可能。

だが！！
画像の左アイコンは同様にclick.stopを利用しても**propsにdisabledを指定しているため、**アイコンのクリックが行えず(これは問題ない)、チェックボックスが反応してしまう。

ここで少々詰まった。

## 対象のコード
```html

<!-- チェックボックス -->
<v-checkbox v-model="hoge">
   <!-- テキスト部分 -->
  <template #label>
    <span>{{ text }}</span>
    <!-- 矢印アイコン部分 -->
    <v-icon
      v-if="index === 0"
      color="#d3d3d3"
      disabled
      @click.stop="upColumn(index)"
      >mdi-arrow-up</v-icon
    >
    <v-icon
      v-else
      @click.stop="upColumn(index)"
      >mdi-arrow-up
    </v-icon>
     <!-- 最後のインデックス -->
    <v-icon
      v-if="index === 7"
      color="#d3d3d3"
      disabled
      @click.stop="downColumn(index)"
      >mdi-arrow-down</v-icon
    >
    <v-icon v-else @click.stop="downColumn(index)"
      >mdi-arrow-down</v-icon
    >
  </template>
</v-checkbox>
```


## 問題解決
問題を掘り起こしてみると、そもそもv-checkboxのクリック範囲がv-iconの箇所に入らなければいいのではないかと気づいた。

そこでそのような方法がないか、[v-checkbox APIのドキュメント](https://vuetifyjs.com/ja/api/v-checkbox/#slots)をじっくり読んでみた。
Slotの箇所に下記のようなslotを発見。
```append: 入力内容と入力内容の後に項目を追加します```
「これだ！！」

#label(v-slot: label)をテキスト部分だけにして、#appendのtemplateを新規作成し、その中にv-iconを入れることにした。

```html

<!-- チェックボックス -->
<v-checkbox v-model="hoge">
   <!-- テキスト部分 -->
  <template #label>
    <span>{{ text }}</span>
  </template>
  <!-- 矢印アイコン部分 -->
  <template #append>
    <v-icon
      v-if="index === 0"
      color="#d3d3d3"
      disabled
      @click.stop="up(index)"
      >mdi-arrow-up</v-icon
    >
    <v-icon
      v-else
      @click.stop="up(index)"
      >mdi-arrow-up
    </v-icon>
     <!-- 最後のインデックス -->
    <v-icon
      v-if="index === 7"
      color="#d3d3d3"
      disabled
      @click.stop="down(index)"
      >mdi-arrow-down</v-icon
    >
    <v-icon v-else @click.stop="down(index)"
      >mdi-arrow-down</v-icon
    >
  </template>
</v-checkbox>
```

できた。

## まとめ
同じような問題に対処した記事が見つからなかったため、結構詰まった箇所だったが、ちゃんとVuetifyのドキュメントを読めば問題なかった。
公式ドキュメントはやっぱり大事だと学んだ、そんな良い1日でした。
[Box] 覚えておくと便利なショートカットキー

# ショートカットキー一覧

ショートカットキーの一覧はBoxサポートに記載がありますので、そちらをご確認ください。

https://support.box.com/hc/ja/articles/360044194873-Boxのキーボードショートカットを使用する

# 最低限これだけは覚えて！

ショートカットキーだけで様々なことができるのですが、

CTRL + C　　コピー
CTRL + X　　切り取り
CTRL + V　　貼り付け

もブラウザ上で動作します💪

これを意外と知らない人が多い。

**知っている人は当たり前だと思ってあまり教えない😭**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/434718cc-9569-3a45-b8b9-7ed7efed993b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/d63fb73c-9c73-5b7e-1cb9-57dee9db5401.png)


ローカルでファイル操作をするのと同じような感覚で、ファイルをコピー＆ペーストできますので、ぜひ試してみてください。

## さらに覚えておくと便利なのは以下２つ。

Shift + D　　ダウンロード
Shift + S　　共有リンク発行

使いこなせば、業務時間短縮にもつながるかも！🤔

# まとめ

業務効率やセキュリティのことを考えてBoxを導入した組織も多いハズ。導入だけで終わらせず、こういった細かいTipsもユーザーに伝えられるとよりBoxの活用が進み、組織がレベルアップしますよね🎉
Griffin-Limアルゴリズムはボコーダなのか・・？（音声、音の初心者向け）

# はじめに
ニューラルボコーダの勉強を通して振幅スペクトログラムから音声波形を出力するものをボコーダだと自分は思っていた。
そのため、Griffin-Limアルゴリズムもボコーダだと思っていたけど、そうじゃなったことを教授に教えてもらったという話。
そこから、「ボコーダとは何か」について勉強した備忘録

# ボコーダとは
ボコーダとは
音声波形を何らかの形でパラメータにしてそのパラメータを元に音声波形を復号化する枠組み
である。

つまり・・

音声波形をパラメータに変えるもの
＋
パラメータに変えられた音声を音声波形にするもの

がボコーダになる。

Guriffin-Limアルゴリズムはメルスペクトログラムという「パラメータに変えられた音声を音声波形」にするが「音声をパラメータに変えるもの」ではない。つまりGriffin‐Limアルゴリズムはボコーダではないということになる。
この音声波形をパラメータに変えるものをエンコーダ、パラメータを音声波形に変えるものをデコーダという。

# ボコーダの必要性
### 音声の伝達のためのボコーダ
例として、離島における緊急音声信号の送受信を考えてみる。
緊急性を要する時に音声が高品質かどうかは関係なく、音声が聞きとれれば十分。
音声は、
「秒数×サンプリングレート×量子化ビット数・符号化形式×チャンネル数」
のデータを取り扱うためデータとして大きいものになります。
そのため、今回の例では聞き取れるレベルでの音声の圧縮、並びに圧縮された音声の復元が重要になります。
この一連の流れをボコーダが担います。

### 音声波形をおもしろおかしくかえるボコーダ
(1)の文献では、ボコーダについて・・
「音声をおもしろおかしくかえるもの」
として紹介しています。
音声の加工には何かしらの方法で音声をモデル化する必要がある。代表的な例にソース・フィルタモデルがあります。
ソース・フィルタモデルは音声を声帯振動による有声音と肺からの呼気流による無声音の2つにモデル化します。
音声を2つのモデルに分類することで声の高さを変えたりすることができ、「音声をおもしろおかしくかえるもの」としてボコーダが使える。このモデルをチャンネルボコーダといいます。
他にもチャンネルボコーダのような音声を再現する2つのモデル化ではなく、音声をフーリエ変換し得た波形を加工するフェーズボコーダもあります。こちらも三角関数ごとに分割しているため得た三角関数のを加工してあげることで「音声をおもしろおかしくかえるもの」としてボコーダが使えます。

# ニューラルボコーダとボコーダ
ニューラルボコーダは(2)の論文で
「音響特徴量から対応する音声を出力する」と述べられています。
つまりニューラルボコーダは・・
「パラメータに変えられた音声を音声波形にするもの」ではあるが「音声波形をパラメータに変えるもの」ではないためボコーダの要件を満たさないことがわかります。
このことからニューラルボコーダはボコーダではないといえる・・と考えました。

# 参考
(1) 小坂直敏．サウンドエフェクトのプログラミング．オーム社．2012
https://shop.ohmsha.co.jp/shopdetail/000000001934/
(2)松原圭亮、岡本拓磨、高島遼一、滝口哲也、戸田智基、志賀芳則、河井恒．Full-band LPCNet：48kHz リアルタイムニューラルボコーダ．日本音響学会講演論文集．2020
http://www.me.cs.scitec.kobe-u.ac.jp/~takigu/pdf/2020/2-2-1.pdf

山本 龍一、 高道 慎之介．pythonで学ぶ音声合成．インプレス．2021
https://book.impress.co.jp/books/1120101073
JavaScriptでobjectのvalueに特定の値があるか確認する方法

# やりたいこと
例えば、Object型の配列があり
その中に特定の値が入っているかを知りたい

# 結論


```js:JavaScript
const arr = { くさ: 'フシギダネ', ほのお: 'ヒトカゲ', みず: 'ゼニガメ' };
 if (Object.keys(arr).some(value => arr[value] === 'ヒトカゲ')) {
  console.log('ヒトカゲゲットだぜ');
 } else {
  console.log('ヒトカゲは逃げ出した');
 }

// 出力: ヒトカゲゲットだぜ

```

これでいけます。
# 解説
Object.keysと
some関数を使用する

Object.keys
そのオブジェクトのキー配列を返す

some
対象の値があればtrueを返す処理


参考
https://www.webopixel.net/javascript/1319.html
初学者のためのxargs

# はじめに
シェルを利用した作業において一番最初に初学者が効率化を実感できるものがxargsの活用だと思い、本記事を書きました。
まずは使ってみよう、ということで比較的使いやすく便利なオプションをピックアップしました。
最後にtipsとしてヒアドキュメントとの併用を紹介していますが、あまり見かけないので初学者ではない方にも有用かもしれません

# xargsとは
xargsとは標準入力やファイルからリストを読み込んでコマンドライン実行してくれるコマンドです
xargsの有無の違いはcatの処理が分かりやすいですね
```
❯ ls
foo	hoge

❯ cat hoge
fuga

❯ cat foo
bar

❯ ls | cat
foo
hoge

❯ ls | xargs cat
bar
fuga
```
文字列として渡すのか、パラメータの引数として渡すのかが違う
## -Iオプションで位置を自由に
-Iオプションを使用することで直後に指定した文字列を変数のように見立てて引数の位置を自由に変更しコマンドを実行できます。
ちょっとした文字列の加工にも使ったりします。
```
❯ echo hoge |xargs -I {} mkdir -p {}1/{}2/{}3

❯ ls -R hoge1
hoge2

hoge1/hoge2:
hoge3

hoge1/hoge2/hoge3:
```
## 複数のコマンドへ渡したいときは
bashの-cオプションを使い文字列として引数を渡してあげることで複数のコマンド処理も可能です。
下記コマンドはカレントディレクトリにあるファイルを圧縮しつつ、圧縮後の中身をチェックしています。
```
❯ ls
a.txt	b.txt	c.txt

❯ cat a.txt
a

❯ ls |xargs -I {} bash -c 'gzip {} && zcat {}.gz'
a
b
c

❯ ls
a.txt.gz	b.txt.gz	c.txt.gz
```

## よくあるやり方
よくあるやり方としてファイルに引数として渡したい対象を記載し、catでxargsに渡すというものがあります。
下記はドメイン一覧が書かれているdomain.lstをxargsに渡し、ドメイン名とそのIPを出力させています。
```
❯ cat domain.lst
qiita.com
esu2.co.jp
google.com

❯ cat domain.lst|xargs -I {} bash -c 'echo && echo {} && dig {} +shor'

qiita.com
52.68.203.46
54.150.97.130
3.113.225.145

esu2.co.jp
54.150.23.130

google.com
216.58.220.110
```
視認性のためにechoで何も引数を指定せず改行させています。

## ヒアドキュメントの併用がおすすめ
リスト一覧のファイルを何度も使用する場合には上述のようにcatでファイルの中身を渡してあげてもいいのですが、一度きりの作業に一々ファイルを作ってしまうと消し忘れもありますし、何より手間です。
できるだけメモリで処理したい！と自分は思うので下記のようにヒアドキュメント併用させたものをスニペットに登録して使っています。
あとはリスト一覧をヒアドキュメントの位置に貼り付けて実行したいコマンドを追記するだけでok
```
cat << eof | xargs -I {}

eof
```

```
❯ cat << eof | xargs -I {} bash -c 'echo && echo {} && dig {} +shor'
google.com
qiita.com
esu2.co.jp
eof

google.com
172.217.26.238

qiita.com
52.68.203.46
54.150.97.130
3.113.225.145

esu2.co.jp
54.150.23.130
```
単純作業の効率化におすすめです。
PL-900 : データコネクタ

この投稿はMicrosoft PL-900の受験に向けた勉強資料をMS Learnページを参考にして作っています。
一発合格に向けて頑張りましょう！

[公式ページ: データ コネクタ][MS-Learn]

[MS-Learn]: https://learn.microsoft.com/ja-jp/training/modules/introduction-power-platform/3-data-connectors

## データコネクタ (Data Connectors)
* データソースからアプリケーションもしくは情報のやり取りをするワークフローへのブリッジ的な役割をする
* コネクタを使用することでプラットフォーム間でビジネスソリューションを拡張かつ、ユーザーのための機能を追加することができる

## データソース (Data Sources)
２つのタイプが存在する
→　どちらもソリューションにデータや追加機能を取り込むために使われる

### (1) 表形式のデータ (Tabular data)
* データを構成化されたテーブルの形で返却する
* Power Appsはギャラリー、フォーム、他のコントロールを通じて返却されたテーブルを直接読み取りおよび表示することができる。データソースがサポートする場合、データを作成・変更・削除ができる
　→　例）Microsoft Dataverse, SharePoint, SQL Server

### (2) 関数ベースのデータ (Function-based data)
* 関数を使用してデータソースと相互作用する
* テーブルのデータを返すために使用するが、電子メールの送信、権限の更新、カレンダーイベントの作成など、より広範囲のアクションも提供する
　→　例）Office 365 Users, Project Online, Azure Blob Storage

## コネクタ (Connectors)
* アプリ、ワークフロー、ダッシュボードにデータソースを接続するもの
* 標準とプレミアムに分かれている
　標準　　　 → SharePoint, Outlook, YouTubeなど
　プレミアム → アプリとユーザーに追加ライセンスが必要
　　　　　　　　SQL Server、Survey Monkey、Mail Chimpなど
* コネクタのレファレンスには全コネクタと標準またはプレミアムのどちらと見なされるかが記載されている
  また、AppSourceをソースに使ったりアプリをインストールしたりMicrosoft製品以外のサービスにコネクタを使用したりすることもできる* コネクタを使うとデータ ソースと Power Platform の間の入出力が可能になり、Microsoft Power Platformビジネスソリューションの提供が加速される
例）Dynamics 365で特定の顧客タイプが追加された時、ユーザーに通知するようにPower Automateを設定
　　SharePointドキュメントライブラリでPower Appsに取り込むファイルを格納し、管理および配布　　
* Microsoftは画像内にあるテキストの読み取りや顔認識サービスのようなタスクを処理するのに高度なAI技術を持つAzureサービスに対してコネクタを提供する
* すべてのMicrosoft Power PlatformビジネスソリューションはTeamsなどのMicrosoft 365 appsで使用および実行できる
　→　Teams内でPower Appsを使用、アクションやイベントからPower Automateを実行可能

## トリガーとアクション (Triggers and Actions)
データソースを設定してコネクタを構成すると、以下の2つを使用可能

### (1) トリガー (Triggers)
* トリガーはPower Automateでのみ使われる、またフローの開始を要求する
* 毎日8時に開始されるフローのように時間ベースでも、テーブル内で新しい行を作るもしくはメールを受信するようなアクションベースでも実行可能
* 実行する際、ワークフローに通知するにはトリガーが必要

### (2) アクション (Actions)
* アクションはPower AutomateとPower Appsで使われる、またユーザーもしくはトリガーより要求される、また何らかの機能によってデータソースとの相互作用が可能になる
例）ワークフローまたはアプリケーションでメールを送信したりデータソースに新しい行を書き込むといったアクション

## カスタムコネクタ (Custom Connectors)
* Power Platformには600以上のコネクタが用意されているが、カスタムで作成することもできる
* カスタムコネクタを使うことで一般API、クラウドプロバイダー(Azure)でホストしているカスタムAPIによるアプリの拡張可能
* コネクタはAPI 間で情報をやり取りし、Power AppsまたはPower Automateに利用可能な関数を収集する機能をする
→　関数ベースであるため、該当データが返されるためにAPIサービスで特定の関数が呼び出だす
* カスタムコネクタを作成するメリットは、Power Apps、Power AutomateやAzure Logic Appsなどのさまざまなプラットフォームで使用できること

## カスタムコネクタの作成 (Creating Custom Connectors)
カスタムコネクタを作成するには ３つの方法があります。
以下の方法に対する要件は異なるが、いずれもアプリもしくはユーザーごとのPower Appsプランが必要

* [空のカスタムコネクタから作成][custom_connecter_1]

[custom_connecter_1]: https://learn.microsoft.com/ja-jp/connectors/custom-connectors/define-blank

* [OpenAPI定義から作成][custom_connecter_2]

[custom_connecter_2]: https://learn.microsoft.com/ja-jp/connectors/custom-connectors/define-openapi-definition

* [Postmanコレクションから作成][custom_connecter_3]

[custom_connecter_3]: https://learn.microsoft.com/ja-jp/connectors/custom-connectors/define-postman-collection
Angular フォームボタンの無効について

4年目のアドベントカレンダー参戦になります。株式会社ピー・アール・オーです。
これまでに引き続き、今年も各自が興味のある分野について各々に書く方針で進めさせていただきます。

# はじめに
angularでフォームを作成したときに無効だったボタンが一瞬だけ有効になるバグが発生し、原因を調べたところ非同期処理によるものだと分かったので以下にまとめる
参考：https://itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd


# Angularフォームの無効

Angualrのフォームボタンを無効にする一般的な方法はinvalidかvalidを使うかの２通りあります。
invalidとvalidの意味は

```
<button type="submit" [disabled]="form.invalid">送信</button> 


<button type="submit" [disabled]="!form.valid">送信</button>
```

この違いについて考えたことはありますか？
form.invalid と!form.valid? 論理的には同じはずですが、実際にはわずかな違いがあります。

これを実証するために、非同期処理を用いた単純なフォームを作成します。

# 検証

```html:html
<form [formGroup]="form">
  <input type="text" placeholder="Enter your email" formControlName="email" />
  <button type="submit" [disabled]="!form.valid">送信</button>
  <div *ngIf="form.pending">
    <img src="https://www.benricho.org/loading_images/img-transparent/712-32.gif" />
  </div>
</form>
```
ボタンの無効化条件の違いを確認するだけなので非常にシンプルなフォームにしました。
フォームの送信ボタンは`!form.valid`で非活性にするようにしています。

また、非同期処理中だとわかりやすいようにLodingのgifも表示するようにしています。

.ts ファイルでは、FormBuilder を使用してフォームを作成しました。
非同期処理を行うために`setTimeout()`を使用し、カスタムバリデーターに適用しています。

```typescript: component
  form = this.fb.group({
    email: ['', [Validators.required, Validators.email], this.checkValidEmail]
  })

  constructor(private fb: FormBuilder) {}

  checkValidEmail(control: AbstractControl) {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(null)
      }, 2000)
    })
  }
```

これで準備ができたので実際にブラウザを見てみましょう。

# 実証

以下が送信ボタンの無効を`[disabled]="!form.valid"`にした場合になります。

![!form.valid.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323263/af853624-7a5b-763b-9d34-ccd6c18a077d.gif)
メールの入力後、処理中のロードが表示されロードが終了直後にボタンが有効になっています。
次に、送信ボタンの無効を`[disabled]="form.invalid"`にした場合も見ていきましょう。
![form.invalid.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323263/faea64ac-fc00-fd65-de31-aebc9f11166f.gif)
最初は送信ボタンが無効でしたがメールが入力されるとカスタムバリデーターの非同期処理が行われsetTimeoutで設定した2秒間送信ボタンは有効になっています。
このことから、`invalid`だと非同期処理中は `false`を返していることがわかります。

以下に`valid`と`invalid`の違いを図でまとめてみました。
![valid.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323263/42607c3a-d68a-f31b-0771-f84b420af746.jpeg)
短時間ボタンが有効になった理由は、`vaild`と`invalid`のpendingの違いにあります。

# まとめ
`[disabled]=”form.invalid”`にした場合、フォームに非同期処理が存在するとボタンの無効が有効になったり予期せぬ動作があるので、フォームのボタンを無効にするには比較的安全な`[disabled]=”!form.valid”`を使用することをお勧めします。
新規プロダクトQAを担当した際の振り返り

# はじめに

皆様本年もおつかれさまです。

今年はモバイルゲームにおける新規プロダクトのリリース前QAの業務に携わらせていただきました。
今回はその時の振り返りとして、苦労したことや工夫したこと、改善していきたいことのお話ができればと思います。

# 苦労したこと
* **開発チームとの連携がリモートオンリー**
世界共通で変わってきたことかと思いますが、本案件はコロナ禍の時期ということもあり開発チームとのコミュニケーションがほとんどチャットとWeb会議でした。
自分や相手の温度感などが伝わりにくかったりする場面が多々ありましたが、Web会議などを小まめに用いて実際に会話をすることで柔軟に対応することができました。
個人的には対面で直接お話しする方が仕事がやりやすいと感じるタイプでしたので、慣れるまでには非常に時間がかかりました...

# 工夫したこと
* **テスト工数の調整方法**
テスト工数を最小限に抑えるための取り組みとして、開発チームとデイリーで進捗共有MTGを実施しました。
用途としてはQAからは現状のテスト進捗や不具合状況、開発チームからは実装状況の進捗やテスト着手可能箇所等をSyncする目的で実施しており、その情報を踏まえて翌日以降のテスト人員の増減調整を開発メンバーとしていくことで無駄の無いアサインを実現することができました。
結果としてリリースまでのQA予算は超過することなく着地ができました。

* **探索的テストの導入**
機能毎の不具合検知率を鑑みて、探索的テストの実施をすることで品質の向上を図りました。
具体的な実施方法などは、[去年のアドベントカレンダー](https://qiita.com/Hokori/items/522d79cc76220b7ee6ae)で自身が記事化した内容をベースにおこなっております。
バグを検知するのと同時に、ユーザビリティ観点での仕様確認や改善提案などもあわせて実施することができたので、非常に良い取り組みになりました。

# 改善していきたい事
* **非機能観点やユーザービリティ観点について**
今回大きく学んだポイントとしては、ゲームが正しく動くかという観点より、そのゲームが楽しいか、プレイしやすいか、分かりやすいか、ストレスがたまらないか、などのユーザー目線での観点がまだ少し足りなかったといった所感でした。
魅力的品質といった観点も立派な品質の一つということを再認識し、今後の案件対応に活かしていければと考えています。

# まとめ
皆さんも一つの案件がリリースを迎えたタイミングなどで、振り返りを行ってみると次回以降の課題などが見つかると思いますので、ぜひやってみてください。
テスト業務に携わる方たちへ、本記事が少しでも参考になれば幸いです。
rpmdbの壊し方

# これは何？

CentOSやRockyLinuxでrpmdbが壊れてしまい困ったことがある人は多いのではないでしょうか？

この状態からの復旧方法はインターネットを調べるとたくさん見つかるのですが、あえてこのrpmdbが壊れた状態を作り出す方法についてはあまり見かけなかったので方法を紹介します。


# 復旧方法
典型的な復旧方法は以下のコマンドを実行することです。(これで復旧しないこともあります)

```
sudo rpm --rebuilddb
```

他にもいろいろなケースでの復旧方法があるようですが、この記事では省きます。

# rpmdbの壊し方（本題）

前述のような復旧手段に関しての文書はインターネット上に多数あるのですが、rpmdbを壊す方法についてはあまり情報がなかったので、試した方法を紹介します。

## yumコマンドをkillする

まずはRockylinuxコンテナを用意します

```
$ docker run -it --rm rockylinux:8 bash
```

以下のようなスクリプトを用意します

```rpmdb-breaker.sh
yum list #　yumリポジトリの情報をキャッシュさせます
for x in `seq 10000`; do
  yum list &
  pid=$!
  sleep 0.$(($RANDOM%10)) #　ランダム時間待ったのちにkillします
  kill -9 $pid
  echo "killed"
done
```

これをルート権限で動作させるとしばらくするとrpmdbが壊れます

```
error: rpmdb: BDB0113 Thread/process 618/140670157765504 failed: BDB1507 Thread died in Berkeley DB library
error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db5 -  (-30973)
error: cannot open Packages database in /var/lib/rpm
Error: Error: rpmdb open failed
rpmdb-breaker.sh: line 2:  1552 Killed                  yum list
rpmdb-breaker.sh: line 6: kill: (1554) - No such process
```

## rpmコマンドをkillする

準備は上記と同様ですが、以下のようなスクリプトでも壊れます

yumではなくrpmコマンドにしていることと、killまでのタイミングを少し調整しています。

```rpmdb-breaker2.sh
for x in `seq 10000`; do
  rpm -qa &
  pid=$!
  sleep 0.0$(($RANDOM%10))
  kill -9 $pid
  echo "killed"
done

```

# 最後に

rpmdbをあえて壊す、というのはあまり役立つことはなさそうですが、この状態に陥った時に復旧する手順書や、スクリプトを作る際には便利かと思います。

他にも壊すケースがあるかもしれないので、ご存知の方はコメントなどで教えて欲しいです。
エンジニアのコピペだめなの？？嘘でしょ？

エンジニアのコピペが駄目だという記事を見かけました。
あえてリンクは張りませんが、僕には全く賛同できませんが、イイねもついてます。
皆さんはどうお考えですか？少し不思議に感じましたので誤解が広がりたくないと思って記事を書きました。
# コピペでスキルは向上しなくない
コピペして出来た気になってしまい内容を理解しないので、0から書いた方が良いと記述がありましたが、今どき、0からコーディングするのって何時代って感じです。昭和の根性にしか思えません。０からタイピングするのと理解するのは全くの別軸の話です。
そもそもコピペするという事は、そのコードを修正するからです。修正しないのであれば、ライブラリとして利用すれば良いです。修正するという事は理解した上で修正します。逆に理解しないと修正出来ないです。
更にキレイなソースコードをコピペする事でキレイなソースコードの書き方を覚えれるし、保守性があがって生産性が上がります。コピペするべきだと思います。

# コピペは考える足かせにはならない
先述の通り、修正する上では考えます。コピー基のソースコードから必要な部分のみ抜き出したり、こんなエラー配慮が必要なのかと勉強になったり、パズルを埋めるためには色々と考えます。コピペは考えるためにも必要な行為です。

# コピペで現場で痛い目に遭うわけない。。。
ネットにアクセス出来ない現場の時に困るという話なのですが。。。これもいつの時代の話だろう思います。もちろん現場でネットにアクセス出来ない方はいるかも知れません。でも何パーセントの人でしょうか？大多数のエンジニアには関係ない話だと思います。

# ラリー・ウォールが提唱したプログラマの三大美徳
- 怠惰 (Laziness)
```
全体の労力を減らすために手間を惜しまない気質。
この気質の持ち主は、役立つプログラムを書いてみんなの苦労を減らしたり、
同じ質問に何度も答えなくてもいいように文書を書いたりする。
よって、プログラマーの第一の美徳である。
```
怠惰なエンジニアは、同じコードを二度と書きたくありません。是非コピペしていきましょう！

- 短気 (Impatience)
```
コンピューターが怠慢な時に感じる怒り。
この怒りの持ち主は、今ある問題に対応するプログラムにとどまらず、
今後起こりうる問題を想定したプログラムを書く。
少なくともそうしようとする。
よって、プログラマーの第二の美徳である。
```
短気なエンジニアがやるべきは、既に実装された部分ではなく未来を見据えたコードを書くことです。コピペした上で該当システムに最適なコードに成長させましょう。

- 傲慢 (Hubris)
```
神罰が下るほどの過剰な自尊心。
または人様に対して恥ずかしくないプログラムを書き、
また保守しようとする気質。
よって、プログラマーの第三の美徳である。
```
恥ずかしくないソースコードを書くために、キレイなコードをコピーして修正していきましょう。ソースコードのキレイさは、見た目のキレイさもあります。目で覚える事もキレイなソースコードを書くには重要です。

以上、ガンガン、コピペしていきましょう！

# 最後に宣伝
今後も続けていきますので、フォロー、イイね、シェアお願いします。
下記、説明会もご参加下さい。
[エンジニア年収アップ講習(転職サポート付き！)　無料説開会　12月6日　19時開催](https://cto-can-be.hp.peraichi.com/)