OmniAICreator/Qiita-1.07M huggingface dataset:
RedSfhitを伸縮自在なサイズ変更でリサイズしようとして困った

# これはなに？
伸縮自在なサイズ変更を使ってみて、
RedSfhitのノード数変更する際に3回転んだ話です。

## 伸縮自在なサイズ変更について
>伸縮自在なサイズ変更 - クラスターにノードを追加または削除できます。DS2 ノードから RA3 ノードなど、ノードタイプを変更することもできます。伸縮自在なサイズ変更はすばやい操作で、通常は数分で完了します。このため、最初のオプションとしてお勧めします。伸縮自在なサイズ変更を実行すると、データスライスを再分配します。データスライスは、各ノードにメモリとディスク領域に割り当てられるパーティションです。伸縮自在なサイズ変更は、次のような場合に適しています。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/redshift-elastic-resize/

簡単にまとめると
- ノードタイプを変更
- すばやい操作で、通常は数分で完了
- ほとんどのクエリが保持

**最高か？？**

## やりたいこと
ra3.xlplus 2ノードで経っているRedSfhitを処理が増える数日だけra3.xlplus 8ノードにしたい！

- 常に動いているRedSfhit且つ、定期的なリサイズなため「従来のサイズ変更」での変更は避けたい


# 実際にやってみた
![redshift-qiita-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074103/439c0268-3fd8-b58e-3f72-f52826e7db1a.png)

むむ:thinking:

## 困ったその①　変更先ノード数の制限

ra3.xlplusのノード数を変更する際、変更先のノード数は2倍もしくは1/2が選択肢となります。
つまり2ノードで動いているRedSfhitは4ノードのみが選択肢になります。

![redshift-qiita-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074103/2562f426-1c9b-74b5-4ee3-5238251ceb4a.png)


仕様上の問題と分かり次の手段へ。

## 困ったその②　元のクラスターを基準にノード数が決まる

変更先が２倍にしかできないのであれば、
一度4ノードに上げてから8ノードにするという２段階でノードを増やす手段を考えました。
2ノード　→　4ノード　→　8ノード

が、

実際やってみたがまたもや失敗。

> ソース vs ターゲットクラスターサイズ - 伸縮自在なサイズ変更によってサイズ変更可能なノード数と種類の設定は、元のクラスターのノード数と、サイズ変更したクラスターのターゲットノードタイプによって決まります。
https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/managing-cluster-operations.html#rs-resize-tutorial

私は完全にドキュメントのこの言葉の意味を履き違えていました。
「変更前」＝「元のクラスター」ぐらいだと思い、2段階に分ければ問題ないと思っていました。

ここでいう「元のクラスター」は建てたタイミングで選んだノード数を基準とするため、ra3.xlplus、２ノードを４ノードにしたところで変更できる範囲は変わりませんでした。

## 困ったその③　元のクラスターを思ったより引きずる

ここまできたら最終手段、
### スナップショットから復元して新しくRedSfhitを建ててしまおう！！！！

建てたタイミングで選んだノード数を基準とするのであれば、
スナップショットから復元する際にra3.xlplus 4ノードを選択して、建ててみた。

![redshift-qiita-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074103/1d03e1d4-56ed-bfa0-bf64-17a7dc080b0e.png)

しかし、スナップショットからのリストアする時点ですでに4ノードまでしか選べない。（本来であれば2～16で選択可能）

不安に思いながらリストアしたが、**結果は最大ノード数は 4 のまま**となり、

失敗。

AWSサポートにも聞いてみたが、
やはり、スナップショットから復元しても元々のクラスターノード数をそのままスライドしまうのは仕様らしい。
「伸縮自在なサイズ変更」では、求めていることはどうしても厳しそうなので「従来のサイズ変更」を使うことを進められました。
一度「従来のサイズ変更」を使えば、「元のクラスターノード数」も更新される。

## 知ってたら得するかも？

もし今後、ra3.xlplus 2ノードを建てることがあれば、
ra3.xlplus 4ノードで建てて、ノード数をダウンさせてからra3.xlplus 2ノードにしよう。

そうすればra3.xlplus　4ノードが基準となるため、2ノードや8ノードへ柔軟に変更が可能となる。
Reactでダークモードとライトモード切替の実装をしてみた

<h2>①useState をimportする。</h2>

```React
import { useState } from 'react';
```
<h2>②useState を使って、初期状態を設定する。</h2>

```React
const [darkMode, setDarkMode] = useState(false);
```
darkMode 変数に初期値として false を渡す。これによって、アプリケーションの起動時には、ライトモードが有効になる。trueにするとダークモードが有効に。

<h2>③ダークモードを切り替える関数を定義。</h2>

```React
const toggleDarkMode = () => {
  setDarkMode(!darkMode);
};
```
setDarkMode 関数を呼び出して、darkMode の真偽値を反転させる。

<h2>④ダークモードとライトモードを切り替えるUIの実装。</h2>

```React
<div className={`Mode ${darkMode ? "dark" : "light"}`}>
<!-- ここに UI を実装 -->
</div>
```
darkMode の真偽値に応じて、dark または light のクラス名を付与する。これにより、ダークモードとライトモードを切り替えることができる。

<h2>⑤ダークモードとライトモードのCSSを作成</h2>

```CSS
.Mode.dark {
  background-color: #3a383b;
  color: #e1e1e1;
  transition: all 0.5s;
}

.Mode.light {
  background-color: #F8F3EF;
  color: #353535;
  transition: all 0.5s;
}
```
上記のようにダークモードとライトモードのCSSを作る。
<h2>⑥toggleDarkMode 関数を呼び出すようにUIを実装</h2>

```React
<a onClick={toggleDarkMode}>
{darkMode ? <i class="fa-solid fa-sun"></i> : <i class="fa-solid fa-moon"></i>}
</a>
```
aタグをクリックするとダークモードとライトモードが切り替わるようにする。上記のコードではfontawesomeを使用している。

以上から、ダークモードとライトモードを切り替える機能が実装できます。
【Python】csvから読み込んだ文字列が一致しないとき

# 結論
csvを読み込む時，エンコーディングで`'utf-8-sig'`を指定する．
```python:例
with open(file,encoding='utf-8-sig') as f:
    csvreader = csv.reader(f)
```
csvを読み込んだとき先頭に`\ufeff`がある場合も同じ対処でOK．

# 発端
csvにある項目を一気に`grep`的に検索したかった．
テストで動かしたとき，明らかに一致している文字列があるのに検出してくれなかった．
<font color="gray">シェルスクリプトで書く方が楽な人は多いかもね...</font>
```csvs:search_word.csv
aaa
bbb
ccc
```
```txt:test.txt
aaajfdo
fewapjg
bbbdiaf
```
```python:search.py
from glob import glob
import csv
import re

target_csv = "search_word.csv"
target_path = "./*" #カレントディレクトリ
pattern = re.compile(r'.cpp|.hpp|.py') #検索したいファイルの拡張子
files = [p for p in glob(target_path, recursive=True)if pattern.search(p) and os.path.isfile(p)] #一応ディレクトリ避けをする

with open(target_csv, encoding='utf8') as f:
    csvreader = csv.reader(f)
    for row in csvreader:
        word = row[0]
        print("word:",word)

        for file in files:
            with open(file, encoding='utf8') as ff:
                data_list = ff.readlines()
                for ind,l in enumerate(data_list):
                    if word in l:
                        print(l)
```

出力としては`aaa`と`bbb`でヒットしてくれればいい
```:出力
word: aaa
word: bbb
bbbdiaf

word: ccc
```
`aaa`がヒットしていない．なぜ？おかしいよ．
# 結局なんだったか
`repr(word)`でどういう状態なのかみてみる
```:repr結果
word: aaa
'\ufeffaaa'
word: bbb
'bbb'
word: ccc
'ccc'
```
`aaa`の前に変なのがついてる...
検索してみるとBOM（Byte Order Mark）というやつのユニコード表示らしいです．
web系の人にとっては当然の知識なんですかね．
> 簡単に言うと、「UTF-8 で文字を書いたよ」と PC に知らせるものです。
引用：[ウェブ制作：「UTF-8」の「BOM」って何？付けた方がいいの？](https://at.sachi-web.com/blog-entry-1080.html)

BOMがある場合は`'utf-8-sig'`でエンコード，ない場合は`'utf8'`でエンコードしてやればいいようです．自動で見分けて読み込む関数作ってる方もいらっしゃいました．
[Python Tips: Python で UTF-8 の BOM ありなしを見分けたい](https://www.lifewithpython.com/2017/10/python-detect-bom-in-utf8-file.html)

:::note info
エクセルからCSV UTF-8でエクスポートしたのでBOMがついたのかもしれません．
エクセルのCSVでエクスポートしてやればBOMなしの状態で出てきました．
:::
# おわり
```python:search.py
#省略
with open(target_csv, encoding='utf-8-sig') as f:
#省略
```
```:出力
word: aaa
aaajfdo

word: bbb
bbbdiaf

word: ccc
```
はい．
新人の頃知っておきたかったこと５選

　

２５人月規模のシステム保守をやっている4年目エンジニアです。
大学では機械系を学んでいて情報系知識は皆無で入社しました。
「拡張子ってなに？」状態からのスタートでSEやっていけるか泣くほど心配でした。
今は２０代、３０代、４０代、５０代のチームメンバーに囲まれぬくぬくとエンジニアやっております。
　
この記事は、自分が新人の頃もっとこうしておけばよかったなという後悔と、配属されてギャップがありまくった戸惑いを過去の自分に伝える気持ちで書きます。
新人の皆さんのご参考になればと思います。
また、あえて偏見を恐れず言うと「若い奴ってこう思って仕事してるんだー、ふうん」とテレビを見ているような感覚でご覧いただけますと幸いです。

## 想像の１０倍くらい障害は起きる
障害対策のために〜とか、バージョン管理が〜みたいな話は研修中講師の方からよく聞きました。
でも、令和の時代にそんなことないだろ、デジタル化進んでるのに管理できないわけない、なんて思っていました。
体感としてシステム障害でLINEが丸１日使えないなんてことはありえないし。（今考えるとSNSアプリの強さはとんでもないです。システムが半端じゃない。）

しかし実際の現場では障害は必ず発生します。どんなに気をつけていても発生するものは発生するのです。


## 職場はおじさんばかり
今まで生きてきて小学校〜大学、習い事、バイト先、新人研修でもだいたい自分と同年代の中に囲まれていたと思います。
それが配属されると一気に同年代が少数派になります。ベンチャーでない限り２０代のメンバーがいたらラッキーな方です。（SEではない知り合いも同じようでした）

少数派イコール自分の価値観や育ってきた環境、時代背景がチームメンバーの多くとズレが生じやすいということ。
エンジニアは職業柄も相まって新しいアイデアや価値観を受け入れやすい人が多いとは思いますが、若手は少数派になるということを頭に入れておいても良いと思います。


## SQLは必須スキル
自分の会社では新人研修のSQLはselectとかinsertとか簡単なものをサラッとやって終わりました。
そのまま大して勉強もせず配属され、SQLが全く書けず、１年くらいはとても苦労しました。
業務で使用するDBはそもそものテーブルの数が多く結合の数も物凄かったので、joinも知らない自分は本当に理解ができませんでした。

joinの大切さを知りたかったし、実際のシステムとなるとDB構造がどれほど複雑であるかも触れておきたかったです。（SQLちゃんと勉強しておけばよかった。。）


## 人はどんどん入れ替わっていく、すごいペースで
チームメンバーがこんなに入れ替わるとは思っていませんでした。
要件定義に関わった人、実装者、リーダーなど本当に誰でも入れ替わります。
「実装したの誰？あー〇〇さんいないんだった、、」なんてことはあるあるです。
だからこそリーダブルコードやドキュメント管理などが重要になってきます。
「誰かに仕様理解してもらって作業してもらうのめんどいから自分がやった方早いわ」は本当にNGです。

## 案外構ってもらえない
会社にもよると思いますが、教育係の先輩が新人に手取り足取り０から１００までみっちり隣について教えてあげるということは無いんじゃないでしょうか？
自分は研修の講師のように周りを巡回して「困っている人はいませんかー？」「はい！ここ教えてください！」の感じで待っちゃってしまったことが多かったです。。（ソンナニ甘クナイヨ。。）
先輩も自分の仕事で手一杯で他人の進捗に気を配ることが難しいことが多いと思いますし、自分から困ってます詰まってますアピールをしないと先輩はなかなか気づいてくれません。


待ってても先輩は教えてくれないということを早く気づきたかったです。


　
### 最後に
新人の皆さん心から応援しています！
また新人以外の皆さんにもチームビルディングの一助になればこれ以上嬉しいことはありません。
最後までお読みいただきありがとうございました！
PyTorchでの半精度におけるコサイン類似度の問題（OpenAI CLIP）

Stable Diffusionなどの画像生成モデルに使われている[OpenAI CLIPでは画像とテキスト間の類似度にコサイン類似度を使用しています](https://github.com/openai/CLIP/blob/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1/clip/model.py#L358)が、PyTorch 1.13現在[PyTorchのコサイン類似度（Cosine Similarity）には半精度の問題ある](https://github.com/pytorch/pytorch/issues/69512)ためここに書いておきます。

なお、ここでは分かりやすく一つだけのコサイン類似度を扱うため半精度の必要性が分かりにくいと思いますが、実際に使っているコードはマトリクスで多対多のコサイン類似度を計算していてVRAMが厳しかったりします…。

まずはCLIPにおける「room」のテキスト埋め込みの自己コサイン類似度が精度の問題で0になってしまうケースを見てみましょう。CLIP の設定は Stable Diffusion 1.x に準ずるものとします。
```python
import transformers
text = "room"

# トークナイザーでテキストをトークン化してNVIDIA GPUへ送る
tokenizer = transformers.CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")
tokens = tokenizer(text, padding="max_length", max_length=77, return_attention_mask=False, return_tensors="pt").input_ids.cuda()
# >>> tokens
# tensor([[49406,  1530, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
#         49407, 49407, 49407, 49407, 49407, 49407, 49407]], device='cuda:0')

# テキストから変換したトークンをテキスト埋め込みへと変換してNVIDIA GPUへ送って半精度に落とす
text_encoder = transformers.CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14",)
text_embedded = text_encoder(tokens)[0].flatten(0).cuda().half()
# >>> text_embedded.shape
# torch.Size([59136])

# トークンから変換したテキスト埋め込みの自己コサイン類似度を取る
result = torch.nn.functional.cosine_similarity(text_embedded, text_embedded, dim=0, eps=1e-6)
# >>> result
# tensor(0., device='cuda:0', dtype=torch.float16, grad_fn=<SumBackward1>) # 0 になった！？
```

見て分かる通り、自己コサイン類似度が0になっちゃいました。そこで実装を見ていきます。[PyTorchでのコサイン類似度の実装](https://github.com/pytorch/pytorch/issues/69512#issuecomment-988220757)は単純化してPython化すると以下のようになっています。
```python
def cosine_similarity(x1, x2, eps): # dimは単純化のため省略
    w12 = torch.sum(x1 * x2)
    w1 = torch.sum(x1 * x1)
    w2 = torch.sum(x2 * x2)
    n12 = (w1 * w2).clamp_min_(eps * eps).sqrt_()
    return w12 / n12
```
精度の問題を確認したところsumで問題が起きてるので、そこの精度を上げる必要があるようです。
```python
def cosine_similarity_fix(x1, x2, eps):
    w12 = torch.sum(x1 * x2, dtype=torch.float)
    w1 = torch.sum(x1 * x1, dtype=torch.float)
    w2 = torch.sum(x2 * x2, dtype=torch.float)
    return w12 * (w1 * w2).clamp_min_(eps * eps).rsqrt()
```
でも半精度のままで計算するならこっちの形が正解かもですね。
```python
def cosine_similarity_fix_halfonly(x1, x2, eps):
    t1 = x1 / torch.norm(x1).clamp_min_(eps * eps)
    t2 = x2 / torch.norm(x2).clamp_min_(eps * eps)
    return torch.sum(t1 * t2)
```
この関数を使って前述の自己コサイン類似度を計算するとちゃんと1.0となります。
```python
>>> cosine_similarity_fix_halfonly(text_embedded, text_embedded, 1e-6)
tensor(1., device='cuda:0', dtype=torch.float16, grad_fn=<SumBackward0>)
```
<ins>
…あれ、ベクトルノルムも似たような計算をしてるはず…？何か勘違いしてそう
</ins>
SQL文

今日はSQL文の練習をしました。

# テーブルの作成（CREATE）
```sql:テーブルの作成
CREATE TABLE 'テーブル名';
```
# テーブルの全データ取得（SELECT *）
```sql:全データ取得
SELECT * FROM テーブル名;
```
# データ追加（INSERT）
```sql:データ追加
INSERT INTO テーブル名(列名1,列名2) VALUES (値1,値2);
```
# データ変更（UPDATE）
```sql:データ変更
UPDATE テーブル名 SET 列名 WHERE 条件式;
```
# データ削除（DELETE）
```sql:データ削除
DELETE FROM テーブル名 WHERE 条件式;
```
# 検索（SELECT）：比較
```sql:データ検索：比較
SELECT 列名 FROM テーブル名 WHERE 列名 = 値;
SELECT 列名 FROM テーブル名 WHERE 列名 >= 値;
```
# 検索（SELECT）：複数データ検索
```sql:複数データ検索
SELECT 列名 FROM テーブル名 WHERE 列名 IN (値1,値2);
```
# 検索（SELECT）：文字列パターン検索
```sql:文字列パターン検索
SELECT 列名 FROM テーブル名 WHERE 列名 LIKE '% 文字 %';
```
:::note info
気を付ける
テーブル名や列名に全角が使えるが、それをくくるカッコは（）ではなく、半角英数のカッコ()にする。
:::
2022年度開発する中で興味/関心を持ったものTOP3

# はじめに
今回、初めて投稿します。お見苦しい内容かもしれませんが、お付き合いください。
また、開発といいつつ、最新の技術を使用しているものではなく、あくまでも個人の判断で選定していますのでご了承願います。

# 第3位　nameとidを同名にする意味
これは、HTML(開発時はjinja2)で、`<input>`等を使用した際に、そのタグに対してつける名前のようなものです。
記述方法は、`<input type="text" id="xxx" name="xxx">`となります。
このidとnameは、同じ名前をつけないといけないのか？と問われると、別名でも構いません。
(細かいことを言うと、同名でなければいけないものもありますが・・・。)
しかし、わざわざ同名をつけているのです。それはなぜかというと・・・。

<b>同名の方が管理しやすい！</b>

この一言につきます。

本来、nameにつけた名前は、request時のparameterとして利用されます。
また、idにつけた名前は、javascript等のscriptでで使用します。
これらを踏まえた上で、jinja2ファイル内のjavascript等で使用するときと、サーバーに処理を投げて、その中で同じ要素なのに、使用する名前が違うと…？わかりにくいですよね。
プログラムを書く上で、わかりにくいのは良いことではありません。

初めてプログラムを書く人が、なぜわざわざ同じ名前を要素につけているんだ？と感じそうですが。
こういった事情を知った上で、同名をつけているんだなって思うと、凄く納得できます。


# 第2位　非同期通信を実施するAjax
Ajax(エイジャックス)とは何か。を説明する前に、同期通信と非同期通信について理解する必要があります。
同期通信と非同期通信は、どちらも「サーバへの通信方法」を表す言葉です。

すごく簡単に言うと。
同期通信とは、Web画面から何か処理をして、サーバーへ処理を投げてから次に画面が読み込まれるまでは処理ができず待つような通信。
非同期通信とは、Web画面から何か処理をして、サーバーへ処理を投げますが、画面上は別の操作ができてしまうような通信。

例：テレビで録画番組を見ようとした際、リモコンで録画番組を見るためのボタンを押した際
　　同期通信：読込中は別の操作は受け付けず、読込が完了するまで待つ必要があります。
　　非同期通信：読込中に画面上は別番組に変更できたり、音量調整をしたりできます。

（やっとAjaxの説明を…。）

Ajaxとは、Webブラウザ内で非同期通信を行いながら、インターフェイスの構築(Webの画面構築)を行うプログラミング手法です。
この名前は、実は略語です。何の略かというと。
| 略名 | 名前 | 説明 |
|:-|:-|:-|
| A | Asynchronous | 非同期 | 
| Ja | JavaScript | 主に動的コンテンツ(Webページ)を作成できる言語 | 
| X | XML | タグで囲むことで構造を表現するマークアップ言語 | 

と言われても…って思いますよねw
詳細が知りたい方は、インターネット検索すると、すんごい数の参考ページが出てきますのでそちらで。。

結局、Ajax通信をすると何がいいかというと、<b>スマートでかっこいいWeb画面が作れる！！</b>
でも実際は、その分JavaScriptをガンガン書くので、ソースは長々しくて汚くなりがちです。。。

以上。


# 第1位　selectboxで検索もできるSELECT2
SELECT2とは。selectboxの進化系です。以上です。

は、流石に乱暴すぎますので、まずselectboxってどんなものかと言うと。
どこかで見たことのあるこちらです。

![スクリーンショット 2022-12-22 20.33.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/8ea8fd17-fc6f-f7da-5955-29529f048e79.png)
![スクリーンショット 2022-12-22 20.39.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/778c2b64-6d01-b088-2035-c9dd363c289c.png)
上の画像で、出社をクリックすると下の図のように項目が展開されます。

こういった場合、今回のように項目数が少ない場合は、問題なく画面上に表示されますが、
項目数が100や1000を超えてしまうと…。スクロールで指がつりそうになりますよね。

そこで登場するのがSELECT2です！！
実物はこちらです。

![スクリーンショット 2022-12-22 20.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/eddaa61b-dff0-f60a-309c-f7854222e2c4.png)
クリック前は、selectboxと全く一緒。

![スクリーンショット 2022-12-22 20.56.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/5395fc49-5887-3fd8-2e3a-21fbba5d0ab7.png)
クリックすると、項目がずらっと出てくるのは一緒ですが、検索ワードを入力できます。
試しに「ダコ」と入力すると。
（魚:fish:じゃないのがいる？気のせいですよ。。）

![スクリーンショット 2022-12-22 20.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/662259de-e2c3-9bfc-4127-fd0478302c55.png)
このように、selectboxの中から「ダコ」を検索した項目だけ表示されるので、その中から選択できます。

また、このSELECT2とajaxを組み合わせると、選択して次の表示がされて。
と言ったように、すごくかっこいいWeb画面ができます！！！
みなさんお試しください:smile:


#  最後に
技術的には、難しいものではないですが。
知らないことを知って、実際に使って、肌で感じると身に付くし、出来上がった時は楽しいです。
Webの画面などは、特にわかりやすいので、簡単な機能でも自分が作ったら感動できます。

これからも、新しいことを知りながら、日々学ぶ姿勢で仕事なり私生活なりを充実していきたいと思います。
Rubyにこんな機能が欲しい

Rubyを完全に理解した勢の@dosaidonです。さて、来年に向けてこんな機能がRubyに欲しいを二つほど書いてみました。
## 超多次元のデータ構造
RubyのArrayは異常に良くできている。複素数をサポートしているのも良い。一方で、1次元の列ベクトルと行ベクトル、2次元のマトリックス、3次元以上のテンソルとかの数値計算に必要なデータ構造とクラスの話が無いのが気になる。「たのしいRuby」は入門書のせいかもしれないが一次元のArray（列ベクトルでも行ベクトルでもないリスト）は出てくるが2次元以上のn次元のデータ構造の話がいくら読んでも出てこないので入れて欲しい。
さらに、超多次元のデータ構造にDataFrameのようなラベルでのアクセスがあるともっと嬉しい。なお、DataFrameは2次元の行列データに行ラベルと列ラベルが追加されたもので、まあエクセルの表みたいなデータ構造のこと。

2年4組
 前期
行ラベル/列ラベル    算数　国語　理科　社会
青木一郎　　　           　99　　85　　95　　70
佐藤二郎　　　           　69　　87　　85　　55
山田三郎　　　           　99　　85　　93　　-

2年4組
 後期
行ラベル/列ラベル    算数　国語　理科　社会
青木一郎　　　           　99　　78　　95　　70
佐藤二郎　　　           　69　　58　　70　　64
山田三郎　　　           　99　　69　　93　　80

データ構造があれば計算するクラスやメソッドは自分で作れるけど、基本的なデータ構造を作るのは難しい。

p seiseki_hyou["算数"]["青木一郎".."山田三郎"]["前期"]["2年4組"].average

科目、名前、クラス、前期後期の成績データがあるとして、こんなのが簡単に出来ると嬉しい。次元nはメモリが許す限り制限無しが良い。

## マトリックスの並列計算

$x=\left( A^{T}\cdot A\right) ^{-1}A^{T}b$

こんなやつをGPU、CPUを沢山積んだMacを使いRubyのRactorで高速に解きたい。

以上、Rubyにこんな機能が欲しい二つでした。
git rebase --abortをフックする

gitでrebaseに失敗すると辛い気持ちになるので牛に励ましてもらいます (環境はLinuxです)。

# 方法

以下のスクリプトをgitディレクトリの中に./git/hooks/post-index-changeとして保存します。
```bash
#!/bin/bash
comm="$( tr -d '\0' < /proc/$PPID/cmdline )"
if [ "$comm" = "gitrebase--abort" ]; then
        # insert your favorite command
        cowsay "You failed me."
fi
```

rebaseをabortすると上のコマンドが実行されます。
```bash
$ git rebase --abort
 ----------------
< You failed me. >
 ----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
```

なおグローバルなgithoooksを設定する方法([参考](https://qiita.com/ik-fib/items/55edad2e5f5f06b3ddd1))を使用すればgitディレクトリの中にスクリプトを置かなくても良くなります。

# 説明

githooksを利用することでgitのさまざまなポイントに独自の処理(スクリプト)を埋め込むことができます。例えばpre-commitのフックを利用するとコミットの前にコードをフォーマットしたりテストを実行したりすることができます。デフォルトの設定では./git/hooks以下に各フックの名前に対応するスクリプトを用意します。フックの一覧はgithooksのmanページやドキュメントにあります。

さてドキュメントを見ても```git rebase --abort```がフックできるかはよくわかりません。とりあえずフックできるのならばスクリプトをopenしているはずなのでabort時のstraceを確認してみます。
```bash
$ strace git rebase --abort 2>&1 | grep ".git/hooks"
access(".git/hooks/post-index-change", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
```

straceの結果はstderrに出力されるのでgrepするために```2>&1```のリダイレクトが必要です。結果よりaccess(2)を使ってpost-idnex-changeとreference-transactionフックのスクリプトの存在を確認している事がわかります(何もフックを設定していない = ファイルが存在しない = -ENOENTのエラー)。reference-transactionは複数呼ばれているのでここではpost-index-changeを利用することにします。

ということで./git/hooks/post-index-changeを用意すれば良いわけですが、名前から推測されるようにgitのindexが変わるたびに呼ばれるフックなので```git rebase --abort```以外でもこのスクリプトは呼ばれます(abortの例ではabortによりrebaseの途中から元の場所にindexが戻るので呼ばれる)。このため冒頭で示したスクリプトでは親プロセスのcmdlineの値から```git rebase --abort```から呼ばれたかを(無理矢理)判定しています。なお/proc/\<pid\>/cmdlineからそのPIDのプログラム名と引数の文字列が取得できますが、それらは'\0'で区切られた文字列となっているためtrコマンドで'\0'を削除しています。同様の方法で```merge --abort```や```am --abort```もフックできるでしょう。

以上
pywebviewで画面遷移ほかいろいろ

# 画面遷移ほかいろいろ
前回のpywebviewお試しでwindowをapiに覚えてもらうことで使いやすくするってところをやりましたが結構これが良いのでぜひみんなやるべきです（ぁ

今回は画面遷移どうすんの？とかCSSを外部読み込みしたいよねとかその他もろもろをやります。

今回のもろもろでこんな具合に画面を作れるようになりましたよ。
労力少ない！　最高か！

![screen1](https://user-images.githubusercontent.com/12671694/209125640-6731ae5f-6bc8-43c0-893c-51bb9362591f.png)
![page2](https://user-images.githubusercontent.com/12671694/209125692-e02b52bd-c3bb-4969-90e7-163918a417a0.png)

## 画面遷移どうすんの？
これは思いのほか簡単で以下のようにHTML文書を文字列で渡してやるだけでした。

```python
self.window.load_html(htmlDocument);
```

## CSSを外部から読み込みたい
これもHTMLと一緒で文字列でCSSを渡すだけ。
```python
self.window.load_css(cssDocument);
```

## デフォルトで読み込まれるCSSというのをどうにかしたい。
HTML文書の方にJSでPython側のAPIを呼び出すスクリプトを書けば出来るのですけれどもすべてのページにそれを書くの？　嫌すぎる。
Python側でドキュメントを読み込み終わったらCSSを読み込むようにします。

```python
api = Api()
api.window = webview.create_window ....

#ハンドラを指定
api.window.events.loaded += api.on_loaded
```
このようにイベントハンドラを登録します。
Apiクラスに```on_loaded```というファンクションを作っておけば各ページが読み込み終わり、webviewが動作可能になったタイミングでここが読み込まれますのでデフォルトのCSSを読み込んでやるなどします。

## ところで画像表示できないんだけど？
IMGタグを使おうとCSSでurl指定しようと出てくる気配はありません。
どうやら自前で読み込んでやる必要があるようです。

Apiにこのようなファンクションを用意します。
base64を利用するので```import base64```を忘れずに。

```python
    def readPng(self, iid, path):
        with open(path, "rb") as fr:
            buf = fr.read()
        b64str = base64.b64encode(buf).decode("utf-8")
        data = "data:image/png;base64,%s" % b64str
        self.window.evaluate_js(
            """document.getElementById("%s").src = '%s';""" % (iid, data)
            )
```

HTMLの画像を表示したいところにはIMGタグで、例えば
```html
<img id="image"/>
```
などとし、スクリプトの```pywebviewready```の中で
```javascript
pywebview.api.readPng("image", "img/hoge.png");
```
このように、ID、image、パスをimg/hoge.png で表示してくれ。みたいにしてやればPython側からHTML側に作用して画像表示が可能です。
この辺り、loadedイベントの中でjsにてドキュメント捜査を行って自動的にやったりしたほうがカッコよさそうです、今のところはこういう事にしておきましょう。

## 画面遷移したあとCSS適用される瞬間が、その、なんというか・・・ダサいんですけど。
CSSの適用されていないHTMLドキュメントが表示されて、CSSが適用されるという感じで動作します。とってもダサいです。
画面を隠して全部終わってから画面を表示するとかもろもろやってみたのですが一番いいのはCSSアニメーションを使う事でした。

まず利用するHTMLのBODYタグ **すべて** に対してこのように書きます。
```html
<body style="opacity:0;" class="fadeIn">
```

共通で後程読み込むCSSの中でアニメーションを設定します。
単純なフェードインですがかなり効果的です。
```css
.fadeIn {
    animation: fadeInAnim 1s ease 0s 1 forwards;
}

@keyframes fadeInAnim {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
```

## 〆
と、今回はいろいろとやってみました。

フォームとのやりとりを簡単にするとかページ遷移後にフォームの値が保存されている風味にするとか、まだまだ興味どころは尽きませんがここまで出来てしまえばあとは書くだけって感じですね。

つぎはその辺りも踏まえつつファイル選択ダイアログの動作とかマルチウィンドウとかあたりもいじってみたいと思います。
勧められるままにSlackのリアクションをしたら、devキャリ登壇できちゃった話

2022年12月9日にDevelopers CAREER Boostに登壇させて頂きました。
https://event.shoeisha.jp/devboost/20221209/session/4121/

当日はとても緊張しましたが、いろいろな方に練習に付き合っていただいたおかげで滞りなく終わらせることができました。

この登壇は社内のあるSlackメッセージに自分がリアクションを押したら指名され、、いつの間にか「登壇してみよう」という気にになっていました笑
なので、「なぜ登壇しようと思ったのか」「登壇してどんな反響があったのか」そんなお話を書こうと思います。

# 結論

最初に結論です。

- 自分にとっては大したことないと思っている出来事でもストーリー込みで話すと、人から見れば共感してもらえるコンテンツになりうる
- 登壇することで自分が想定していた「こんな人に聞いてほしい」と思っていた人からの感想はもちろん、想定していなかった人からの感想ももらえて身が引き締まる

# 登壇内容まとめ

筆者の新卒当時の状況から
何があってプログラミングに興味が出て
何があって転職を決意し
何に惹かれてWHIを選び
何をして昇格までたどり着けて、「エンジニア楽しいかも？」と感じれるようになったのか。
そんなストーリーをお話しました。

登壇時の資料はこちら
https://speakerdeck.com/whisaiyo/developers-career-boost-2022

# 今回のこの記事の登場人物

新村さん　：　WHIの開発組織全体のDX推進を担当している方。Developers CAREER Boostの登壇者を募集していた。
佐藤さん　：　入社時は打刻開発チームの先輩、今は上司。

# 登壇決定するまでの流れ

1. 登壇者募集のSlackメッセージが流れる。
1. 上司（登壇スライドに出てきた佐藤さん）がそのメッセージを見て「興味がある方はぜひリアクションしてみましょう！」とチームメンバーにおすすめ。
1. 「佐藤さんがおすすめしてるならリアクションしてみるかぁ」という軽い気持ちで興味深々リアクションをぽちっとする。
1. 新村さんから指名され、1on1で「やってみよう」と念を押される。
1. 宮城その気になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992207/58182ae3-b56c-9eba-31c8-5b349c99d97b.png)

正直、最初にSlackにリアクションを押したときは「入社して半年だし選ばれる訳ないっしょ」と思ってました笑
なので新村さんから指名1on1が入ったときはとても驚きました。
それと同時に「**未経験から転職して半年の自分に話せることなんてないよ。。**」っていう不安でいっぱいでした。

# なぜ登壇しようと思ったのか

新村さんとの1on1でその不安をそのままぶつけました。「自分に話せることなんてないと思うんですが。。」と。

その返事が
- 確かに未経験から転職して半年だけど、転職するまでは5年以上あったでしょ？
- **転職を決意するまでの過程を含めてストーリーにして**話してみたら？
- そのストーリーを話せば「**今、未経験からの転職を考えている人**」に刺さりそうな気がする。

でした。この言葉をもらって、今まで「未経験からの転職は弱み」だと思っていた自分が
「確かに未経験からの転職でしか話せないことあるかも？」と思うようになり
「**未経験で転職悩んでいる人に向けて、自分の体験談をしゃべろう！**」と決意できました。

なので登壇の最初で「**あまり見ていないとは思うけど、未経験の人がもし見ていたら、、**」と言ってしゃべり始めましたが
未経験の人に向けて話している内容になっています！

# どんな反響があった？

自分の予想以上に色々な反響をもらえたので印象的な反応をピックアップして書かせていただきます。

### 反響その1 未経験の人が登壇を見てくれていた

登壇配信中にこんなコメントを頂けていました！

「**未経験でプログラミングを勉強しています**」
「**未経験からエンジニア転職を目指していますが、コーディング試験のレベルは高い企業は高いでしょうか？**」
「**未経験からの転職を目指しているので、学習を進めていたときや転職活動をしていたときの思いの変化が聞けてよかったです**」

上にも書いた通り「未経験の人が見てくれていたらいいな」という思いを込めて登壇していたので、未経験の人からコメントを頂けていてとても嬉しかったです！
**自分では大したことないと思っていた「未経験からの転職」という出来事が「共感してもらえるコンテンツ」にできた**、そんな実感ができた反響でした！

### 反響その2 WHIの若手エンジニアが見てくれていた

意外だったのはこの反響でした。社内の若手エンジニアが見てくれていて自分のtimesに感想を呟いてくれていました。

「**プログラミングが楽しいと思ったきっかけがまず業務改善のためのモノづくりから来てるんだなぁ　まずやってみることの大切さが分かる。**」
「**自走力。自分に一番足りないものだなぁ**」
「**上司がやることを減らすために動いている、、っていう視点は自分が最近意識できてなかった**」

※timesってなに？という方はこちらの記事をご覧ください。
[なぜ WHI では times 文化がうまくまわっているのか？](https://qiita.com/satomihoya/items/b125e1eaf44c4a643e6e)

特に

- プログラミング楽しい！になるまでのきっかけ
- 先輩、上司に昇格できたところをインタビューしてみた

の話を自分に当てはめて聞いてくれていた方が多かったみたいです。
「プログラミングを楽しむには」「先輩、上司との接し方」みたいなところが参考になればとても嬉しいです。
それと同時に**お手本にされる存在にならなければ**、と思わせられる反響でした！

# 感想

「未経験から転職して半年の自分に話せることなんてないよ。。」と思っていた筆者ですが今回の登壇の経験から

- 自分にとっては大したことないと思っていてもストーリー込みで話すと、人から見れば共感してもらえるコンテンツになりうる
- 登壇することで自分が想定していた「こんな人に聞いてほしい」と思っていた人からの感想はもちろん、想定していなかった人からの感想ももらえて身が引き締まる

と身をもって感じることができました。

# まとめ

登壇することでいろいろな人から感想をもらえる貴重な機会なので、内容が思いついてなくとも手を挙げて挑戦してみることをお勧めします！
プロジェクトマネジメントを振り返る

# はじめに
この記事は [OPENLOGI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/openlogi) 22日目の記事です

今年、プロジェクトマネジメントをメインの業務で行ってきた中で注意してきた点を備忘録で書きました

# プロジェクトのゴールを設定する
そのプロジェクトをなぜ行なうのか、また解決したいことは何かをプロジェクトを開始する前に明確にします
明確にすることで、プロジェクトで達成したいこと（＝ゴール）を設定します
ゴール設定があやふやだとプロジェクトの進むべき先やプロジェクトの成否、振り替えりができません

# 参考となる事例やノウハウを探す
続いて考えるのは参考となる事例やノウハウを探します
0からプロジェクトを開始するのはリスク多めなので、社内の他プロジェクトやインターネット、本などで参考事例があれば流用します
過去の叡智を可能な限り使い、失敗するリスクを減らします

# 責任範囲を明確にする
プロジェクトマネジャーはプロジェクトの達成責任を持ちます
関係者と合意の取れた仕様やスケジュールで、プロジェクトを達成するため、尽力します

# ステークホルダーを明確にし、コミュニケーション設計をする
責任範囲と合わせてプロジェクトの関係者を明確にし、それらの人とのコミュニケーションフローを整理します
相手によっては対面、もしくはテキストでのコミュニケーションを好むといったことがあれば、それらを考慮しコミュニケーションとるよう努めます

# 情報の公開範囲を考える
コミュニケーション設計に関連するのですが、何でもかんでも関係者間で情報を共有するのではなく、ノイズとならないよう相手の立場によって必要な情報を整理し、共有します

# 先の作業や起こりうる問題を想定する
企画の段階であれば設計フェーズ、設計では実装フェーズ、実装ではテストやリリース時のプロセスをイメージしながら、起こりうる障害やそれに対する解決策をシミュレーションします
実装フェーズで遅れる場合は、リカバリ方法や事業側とのスケジュール調整がいるかといったことを考えながら、問題が発生しても対処できる準備しておきます

# まとめ
入社してから、大きめのプロジェクトを任せていただき、関係者の方々にはリリースまで様々なアドバイスやサポートをいただきました。この場を借りて感謝を伝えます。ありがとうございました。
Skyway SDKのチュートリアルコードをgithub codespacesでデプロイしてみる

# 概要

Skyway_SDK(NTTコミュニケーションズ）のチュートリアルコードをただGithub_Codespacesでデプロイするだけの記事。
そんなに内容は難しくないため、詳細な説明を省きます。
- Live Serverでページを立ち上げてみる
- github_codespaceをドメインとして追加する

<strong>Github_Codespacesについて</strong>

https://docs.github.com/ja/codespaces/overview

<strong>Skyway_SDKについて</strong>

https://webrtc.ecl.ntt.com/skyway/overview.html
# Live Serverでページを立ち上げてみる

Codespace(VS Code)の拡張機能を追加するだけ。
![スクリーンショット 2022-12-22 20.52.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884108/ee4cb2c8-00c9-1a22-8952-2deabd73492f.png)
あとは画面右下に表示されるGo_Liveを押して、ブラウザ上でindex.htmlを確認したら終わり。
なかなかシンプル。

# github_codespacesをドメインとして追加する

APIキー等はご自身で予め発行しておいてください。
アプリケーションを作成したあと、APIキーを表示する画面が出てくると思います。

初期状態では、localhostしかドメインとして追加されていないため、
ほかのドメイン(github.ioとか）を用いて立ち上げると、Skyway SDKは利用できません。

そこで、一度追加されていないドメイン経由でページをホスティングして、
GoogleChromeのDeveloperToolsを開いてください。

```
macショートカット:  control + option + i 
windowsショートカット: control + shift + i / F12
```
次に、Consoleを確認していただくと、
httpsから始まるcodespacesのドメインが赤く表示されると思います。
これはドメインが追加されていないため、Skyway側に接続拒否されているという状態を示しています。
赤い矢印が指している部分がLiveServer経由で立ち上げたhtmlページのドメインです。
![スクリーンショット 2022-12-22 20.39.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884108/c467a8ee-829f-8fb3-ad28-c6b1ab99c69b.png)

このドメインをコピペし、「https://」部分を取り除いたのち、
Skywayの利用可能ドメインに追加すると、Codespaces経由でもSkywaySDKの諸機能が利用できるようになります。
ご自身で確認してみてください。

![スクリーンショット 2022-12-22 20.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884108/a9e8738b-0dcf-d8b7-83f0-62ae11b165c2.png)
[matplotlib] contourfでカラーバーの上限と下限を設定する

# 引っかかったところ
matplotlibの```contourf```使用時に```set_clim(vmin, vmax)```で上限と下限を設定するとカラーバーがサチる．

例によってテイラー・グリーン渦の渦度を可視化してみる．
$$
\begin{aligned}
\omega &= 2 \sin x \sin y.
\end{aligned}
$$

```Python:
import numpy as np
from numpy import pi, sin
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

# Parameters
N = 100
lvls = 100
xmax = 2*pi
ymax = 2*pi
vmin = -1.2
vmax = 1.2

# Taylor-Green Vortices
x = np.linspace(0, xmax, N)
y = np.linspace(0, ymax, N)
X, Y = np.meshgrid(x, y)
omega = 2*sin(X)*sin(Y)

# PLOT
fig, ax = plt.subplots(1,2)
plt1 = ax[0].contourf(X, Y, omega, 100, cmap='RdBu_r')
fig.colorbar(plt1, ax=ax[0])

plt2 = ax[1].contourf(X, Y, omega, 100, cmap='RdBu_r')
plt2.set_clim(vmin=vmin, vmax=vmax)
fig.colorbar(plt2, ax=ax[1])
plt.show()
```
![TG_Colourbar_sat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119868/6285c666-b438-0f47-36fd-d3f68ee34f5c.png)


# 解決策
```levels = (vmin, vmax, 100)```で上限下限を指定して```extednd = 'both'```をオプションに加えるだけだった...

```Python:
plt.contourf(X, Y, omega, np.linspace(vmin, vmax, 100), cmap='RdBu_r', extend='both')
plt.colorbar(ticks=np.linspace(vmin, vmax, 5))
plt.xticks([])
plt.yticks([])
plt.show()
```
![TG_Correct.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119868/2eb934d1-91b6-f442-19f9-1022c9bf732b.png)


# 参考にしたサイト
https://stackoverflow.com/questions/54979958/set-colorbar-range-with-contourf-in-matplotlib
【SwiftUI】Toggleのスタイルについて

# はじめに
iOS15からToggleのスタイルが増えてたので整理してみました。

# スタイル
## iOS
### switch
```swift
import SwiftUI

struct ContentView: View {
    @State private var isOn = false
    var body: some View {
        Toggle("トグル", isOn: $isOn)
            .toggleStyle(.switch)
    }
}
```
![Simulator Screen Recording - iPhone 14 Pro - 2022-12-22 at 20.45.02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3e288046-b2fa-ae51-4b77-ab76b4e95d43.gif)

### button
```swift
import SwiftUI

struct ContentView: View {
    @State private var isOn = false
    var body: some View {
        Toggle("トグル", isOn: $isOn)
            .toggleStyle(.button)
    }
}
```
![Simulator Screen Recording - iPhone 14 Pro - 2022-12-22 at 20.45.55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ae114504-3ebc-fe23-d44a-d07b158821f2.gif)

## macOS
### switch
```swift
import SwiftUI

struct ContentView: View {
    @State private var isOn = false
    var body: some View {
        Toggle("トグル", isOn: $isOn)
            .toggleStyle(.switch)
    }
}
```
![画面収録_2022-12-22_20_51_24_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/269cf5e5-2f3b-332f-8168-925efac991cd.gif)

### checkbox
```swift
import SwiftUI

struct ContentView: View {
    @State private var isOn = false
    var body: some View {
        Toggle("トグル", isOn: $isOn)
            .toggleStyle(.checkbox)
    }
}
```
![画面収録_2022-12-22_20_53_54_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/aa03a4e5-1580-3049-205a-ff2e4242bcef.gif)

### button
```swift
import SwiftUI

struct ContentView: View {
    @State private var isOn = false
    var body: some View {
        Toggle("トグル", isOn: $isOn)
            .toggleStyle(.button)
    }
}
```
![画面収録_2022-12-22_20_48_59_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d4b60000-1d84-18e4-80ab-d9293df8110e.gif)

# おわり
iOSにもcheckboxスタイル欲しいですねー
クラウド版 データ・プレパレーション はじめました!!

この記事は [インフォマティカ Advent Calender 2022](https://qiita.com/advent-calendar/2022/informatica) Day 23の記事として書かれています。

データ・プレパレーションのクラウド版の新サービスである、CDP (Cloud Data Preparation) がTech Preview(ベータ版)として公開されましたので、紹介致します。

## そもそもプレパレーションとは？
セルフサービスBIやデータの民主化が叫ばれて長く経ちますが、依然として「欲しいデータにたどり着けない」「手動でデータの補正が必要」「SQLやプログラミング言語を駆使しなければならない」と言ったデータ準備に関する課題は存在し続けています。
分析者の課題として、「データ準備に80%が掛かり」「データ分析に20%しか割けない」と言う状況も、複雑化するデータ・マネージメントでは改善が難しいです。

そこでインフォマティカは、従来からオンプレで提供してきたデータ・プレパレーションのクラウド版を公開しました。
![ApplicationFrameHost_aVIU4ZAOHD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/248dffa8-9614-ae81-dd87-100cadec93e4.png)


## データを見ながら加工・編集
ローカルPCの表計算・スプレッドシートは、データを見ながら加工・編集できる優れたツールです。
しかし、リソースはローカルPCのみであり、データサイズや行数にも制限があり、ビッグデータ用のデータを作成するには無理があります。
それらの作業と使用感をサーバーサイドに持ち込んで、コンピュータリソースの制限を超えることができるのが、データ・プレパレーションになります。
![ApplicationFrameHost_hmIemTqanz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/97c27a6c-dc82-8d84-8e15-7070ff0822da.png)

## レシピとしてノウハウの共有
ローカルPCの表計算・スプレッドシートの限界として、他者とのコラボレーションがあります。
ノウハウがファイル上に蓄積され、多くの場合、複数人数で共有しながら作業をする事には向いていません。
CDPでは、レシピとして公開し共有する事でノウハウを横展開して、チームとして、会社としてデータ活用の高度化が可能です。
![ApplicationFrameHost_qWKWqytVgB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/77d6b589-e222-5cfc-6231-4b48667609bc.png)

## SQL 不要の簡単操作
複雑な集計や加工をする場合は、SQLやプログラミング言語を駆使する必要があります。
ビジネス部門のメンバーやビギナーの分析者には、それらのハードルは高く習熟には時間が掛かるものです。
例えば、Join(データ結合)処理なども様々な記述やパラメータが必要で、慣れないメンバーに取っては時間が掛るものです
それをCDPでは、表計算・スプレッドシートのように直感的に操作することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/75675a6c-270c-c9fd-6382-6f736eab55e2.png)

## Publish(公開)で実体化
作成したレシピに則り、データを公開(Publish)することで、そのデータを使い慣れたデータレポジトリに実体化し活用することができます。
GUIベースで出力先のデータベースを指定することにより、SQLのCreate文などのスクリプトを一切書く必要もなく新しいテーブルを作成し、そのテーブルにデータを流し込むデータ連携ジョブまで一気通貫に実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/78420922-2b5e-e21d-6316-883eb85d0500.png)


## 最後に
CDP (Cloud Data Preparation) は、新世代のクラウド版データ・プレパレーションとして、登場しました。
クライド化された事により、実行用のハードウェアやソフトウェアが最適化され、データ・プレパレーション作業に集中することができます。
今後、様々な機能やサービスが追加され、拡張が見込まれますのでご期待ください!!

CoE部
嶋田真人(Max)
温度センサーMCP9701について


x 「関連情報」は、(MCP9701) ココ←をクリックしてね!!
リンク一覧が出ます。

![o_cop272.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/55912a01-3746-e5d3-3c41-dd42db63c54f.jpeg)



目的
ほぼ、一番安い、温度センサーの使い方


秋月で8個200円で売っている(2022/12/22)

[MCP9701-E/TO]
通販コード　I-03199
発売日　2009/10/26


![o_cop267.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6604f1b3-0e26-78dc-0c66-10428b3f6cf6.jpeg)



https://qiita.com/caa45040/items/dad34f5ece791e94c085




アナログ出力である

あんまり精度が高くない+-4℃

1℃当たりのステップが19.5mVである

ちょうど8ビットADCだとそのまま温度になる

0℃の時の中心電圧は、400mV

8ビットADCだと20℃を引いて上げるとよい

直線性は、S-8120Cよりは、いい


![o_cop271.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/35e3fb49-16c8-9fb8-1a6b-5eaf046238e3.jpeg)


![o_cop268.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d14914ee-812c-33ea-f8b0-94be6b365df1.jpeg)

ピン配列は、そんなに悪くは、ない


Arduino UNOの10ビットADCで取り込んだ時。


![o_cop269.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0d1a52b6-8e57-4ec2-9f1c-90bebe02b7d8.jpeg)

小数点以下2ビットは、0,0.25,0.5,0.75になる

整数部は、4で割り20を引く


値の取り込み例


![o_cop270.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/32e28b37-1526-1e6f-5204-e0d14b4008f2.jpeg)


```c++


/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/AnalogReadSerial
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}



```
ROS navigationにおいて，起動後にmapを切り替える

こんにちは
自律移動ロボットの研究をしているHUTONです．
ROS Navigation_stackを使っているとき，
「あ！mapを切り替えたい！！」って思うときありますよね？
（階層の違う地図を使ったりとか）

# 背景
筆者がつくばチャレンジに参加した際に以下のような問題がありました．
・一枚の地図を一気に作ろうとすると歪み，破綻することがある．
　これを解消するためにはひじょ〜〜〜に辛いチューニング作業という地図職人が必要に．．．
・大きなmapでは読み込みにどえらい時間がかかることがある．

つまり
→分割した地図を乗り換えていけば良いのでは？？
ということからmapを動的に切り替える方法を考えます．
※ROS noeticを対象にします．
# 実装
実装としてmap_serverをkillして立て直す方法がかんがえられますが，
自律移動中に立て直すのはフェールセーフの面から考えて危険に感じますよね（主観です）

それではどうするか？？？
そこで調査するとこんなものが
[Added change_map service to map_server #461](https://github.com/ros-planning/navigation/pull/461)


現在map_serverには/change_mapというserviceが追加されているようです.
（ROS wikiに書いてないのはいかがなものか）
このserviceは，nav_msgs::LoadMapという型で引数（map_url）を持っています．
この引数へ，mapのパスを記載するとなんと！
mapを切り替えをすることができます！！！！！

実際の例を以下に示します．
初めにmap_servarを起動します．
```bash
rosrun map_server map_server {mapのパス}.yaml
```
別のターミナルで
```bash
rosservice call /change_map map_url:={切り替えるmapのパス}.yaml
```
次にmove_base, amclを含めたnavigationを起動した後に切り替えるノードを作ります．
施策したパッケージはこちらです．
[github](https://github.com/haruyama8940/map_changer "map_changer")
具体的には
前述の/change_mapへmapを渡します

```cpp
#include <nav_msgs/LoadMap.h>
```

複数のmapのpassをコードに直書きしても良いのですが，
美しくない&いちいちビルドしなくちゃいけないという弊害があるため
yamlにまとめましょ〜〜
configの中のmap_list.yamlは個人的な用途以下のように書きます
```
map_list:
  -map
    id: 人間の識別用の番号
    map_name: mapのpassを記載
    pose_x: 切り替え後の初期pose x  
    pose_y: 切り替え後の初期pose y
    ori_z: 切り替え後の初期ori z
    ori_w: 切り替え後の初期ori w
```

あとは何かしらのサービスでmapの番号を投げてあげれば切り替わるはず．．．

それではよいROS人生を！！！

気が向いたら切り替えの様子を追記します
【python】勉強メモ　速習Flask①

# Flask勉強メモ

コピペしていけば、仮想環境作成からブラウザでFlaskの実行を確認できる手順となっております。

## 実行環境
- Windows10 Pro
- Python 3.11.0


## ディレクトリ構造
```
pydir/
 ┣myproject/
   ┣venv/
   ┣hello.py
   ┣templates/
    ┣hello.html
```

## 全体の流れ
1. 仮想環境作成
2. 仮想環境有効化
3. 仮想環境内で、Flaskインストール
4. appファイル作成
5. appファイル起動（Flask起動）
6. ブラウザで確認 
7. Flaskの終了
8. 仮想環境の終了


### 1. 仮想環境作成
**注)** コマンドは、VScode上のPowershellから実行しております。
**注)** コマンドは、myprojectフォルダで実行してください。 

`.venv`という名前の仮想環境を作成
```
python -m venv .venv
```
### 2．仮想環境の有効化
仮想環境を有効化
```
.venv\Scripts\activate.ps1
```
仮想環境が有効化され、プロンプトに仮想環境名`(.venv) `が付与される
```
(.venv) PS C:\PC-Work\dockerenv\pyDir\myproject> 
```

### 3．仮想環境内で、Flaskインストール
仮想環境内で、pythonのインストールモジュールを確認
```
pip list
```

Flask等は、インストールされていないことを確認
```
Package    Version
---------- -------
pip        22.3
setuptools 65.5.0

[notice] A new release of pip available: 22.3 -> 22.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip

```

仮想環境内に、Flaskをインストール
```
pip install Flask
```

仮想環境内に、Flaskがインストールされたことを確認
```
pip list
```

```
Package      Version
------------ -------
click        8.1.3
colorama     0.4.6
Flask        2.2.2
itsdangerous 2.1.2
Jinja2       3.1.2
MarkupSafe   2.1.1
pip          22.3
setuptools   65.5.0
Werkzeug     2.2.2

[notice] A new release of pip available: 22.3 -> 22.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip
```

### 4．appファイル作成

`.venv`と同じ階層に、`hello.py`ファイルを作成
```hello.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"
```

### 5．app（hello.py）ファイル起動（Flask起動）
`.py`ファイルのファイル名を指定し、Flaskを起動
```
$env:FLASK_APP = "hello"
```

デバッグモードで起動
デバッグモードで起動すると、コードを変更すると、Flaskの再起動を行わなくても、コードが反映される
```
 $env:FLASK_ENV = "development"
```

Flaskを実行
```
flask run
```

```
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
 * Serving Flask app 'hello'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
'FLASK_ENV' is deprecated and will not be used in Flask 2.3. Use 'FLASK_DEBUG' instead.
 * Debugger is active!
 * Debugger PIN: 261-206-630
```

### 6. ブラウザで確認
`127.0.0.1:5000`にブラウザでアクセス。

### 7．Flaskの終了
`Ctr + C`を入力

### 8．仮想環境の終了
```
deactivate
```

## 参考
[Flaskドキュメント](https://flask.palletsprojects.com/en/2.0.x/quickstart/)
プロジェクトマネージャ試験合格体験記

# はじめに
この記事は、令和４年度プロジェクトマネージャ試験の合格体験記です。

# 成績
![スクリーンショット 2022-12-22 19.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289055/496038d9-3ec9-4632-c8c8-45f66ff32cb5.png)

免除期間が過ぎたため、午前Iからの受験でした。
（午前Iは範囲が広いので苦手です。点数も結構ギリギリでしたね。。）
なお、プロジェクトマネージャ試験は数年前にチャレンジし、午後IIで不合格となっています。（つまりは２度目の受験で合格）

# 自己紹介
choco_py3（ちょこぱい）と申します。
都内のユーザ系SIer企業でセキュリティエンジニアをしています。
IPAの所持資格は基本情報/応用情報/情報処理安全確保支援士（登録済）/ネットワークスペシャリスト/ITサービスマネージャ/ **プロジェクトマネージャ←new!** です。

今年はサイバーセキュリティお嬢様シリーズの記事を執筆し、同人誌を頒布したりしました。
~~ギリ、ピチピチの20代です。~~

https://qiita.com/choco_py3/items/51c04bdc8bfe25fe84f3

https://qiita.com/choco_py3/items/5448070f749095a2e6bb

# 勉強法

### 勉強期間
- 2022年8月末〜試験直前（2022年10月9日）まで

### 勉強時間
- 基本平日のお昼休み（のうち30分）と業後3-5時間程度
- 土日はほぼ勉強していません（メリハリ大事）
- ざっくり計算すると、4h * 5d * 6w = **120h**くらい？（そんなにやってないと思う...）

### 勉強場所
- 自宅だと集中できないタイプのため、会社そばのコワーキングスペースを利用
  - 「勉強すること自体」に課金することで、自らを追い込む作戦
- 昼休みは自席でひたすら過去問道場（※後述）を解いていました

### 参考書など
##### 【午前I】
- **過去問道場(応用情報)**
  - ひたすら解いた

https://www.ap-siken.com/apkakomon.php

##### 【午前II】
- **過去問道場(プロジェクトマネージャ)**
  - ひたすら解いた

https://www.pm-siken.com/pmkakomon.php

##### 【午後I】
- **情報処理教科書 プロジェクトマネージャ**
  - 別名「みよちゃん本」。PM試験といえばこれ。午後はこれ一冊でカバーできます。

https://amzn.asia/d/gZyhMvr

- **PMBOKはじめの一歩 スッキリわかるプロジェクトマネジメントの基本**
  - プロジェクトマネジメント業務を経験したことがなかったため、入門書として利用

https://amzn.asia/d/cyrw4L1

- **SCRUM BOOT CAMP THE BOOK【増補改訂版】 スクラムチームではじめるアジャイル開発**
  - アジャイル分野は詳しくなかったため、入門書として利用

https://amzn.asia/d/dQBndyn

##### 【午後II】
- 今回は上記の「情報処理教科書」でカバー。
- 過去試験では以下の参考書も利用しました（※以下最新版）

- **プロジェクトマネージャ 午後2 最速の論述対策**
  - 論述試験が初めての人におすすめ

https://amzn.asia/d/bhKJ9b4

- **絶対わかる論文問題攻略法**
  - こちらも論述試験が初めての人におすすめ

https://amzn.asia/d/bugZKAY



### その他やったこと
- 会社が費用を負担してくれたので、某社の模擬試験を利用
  - 9月に受験し、無事A判定で一安心
  - ここで作成した論文は更にPM試験（に十数年前）合格済みの上司に添削してもらいました

### 試験のコツなど
https://qiita.com/choco_py3/items/98f4d2754c4b30dd384a

# おわりに
合格発表の30分前から緊張で気分が悪くなっていました。。無事合格できて良かったです。
次はシステムアーキテクト試験合格目指して頑張ります。
第三者検証からQAに転職してみて

# はじめに
はじめまして、株式会社LITALICOでQAグループ所属の@yamahiro2022です。
9月半ばに転職してから、QAとしては駆け出しの身ですが、
今まで経験してきた第三者検証としての仕事と、
今行っているQAの仕事の違いなどを記載させていただけたらと思っています。



# QAとはそもそも何ぞや？
自分の中でも、何となくわかっているようでフワッとしたイメージしかなかった状態でした。
調べてみると、「QA（Quality Assurance）とは、システムやソフトウェアの品質を保証する仕事です。」と出てきます。

**ここで疑問が…**

保証って、どこまで保証する？
混在されがちなQC（Quality Control）との違いについて考えてみます。

・期間：**QC** は、開発期間の要件定義～リリースまでを対象としているのに対して、
　　　　**QA** は、企画段階から参画し、リリース後も対象としている
・責任範囲：**QC** は、リリースする際に品質の責任を負っているのに対して、
　　　　　　**QA** は、システムを利用するクライアントに対して責任を負っています。


プロジェクト毎に品質を考えるのはもちろんのこと、サービスが続く限り未来永劫品質を保証してくのか…
なんとなく、QAってわかってきた気がする…


# 第三者検証として何をしてきた？
ここからは、今まで行ってきた、第三者検証のことを振り返ってみます。
##### 第三者検証とは：第三者の立場から客観的にソフトウェアや、システムの品質を検証すること

主にシステムやソフトウェア開発会社からの依頼で、検証業務を行っていました。
QAかQCかで考えると、QC寄りのことが多かった印象ですね。
主に行っていたことは、
・プロジェクト全体の連携改善
・ホワイトボックステスト～シナリオテストの一連の改善
・機能テスト以降のテスト業務　←:star2:ここが一番多かったです



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987894/f4624a4d-bc1e-ff7d-bf4b-48dfd1e2cbfe.png)



# QAと第三者検証の違い
今までQA依頼を受け、お客様と会話をした上で業務を行ったり提案してきましたが、行うべき範囲や、考えるところが大きく違うことに気が付きました。

**QA：システムすべての品質を考えながら品質保証を行う**
**第三者検証：リリース対象物に対して品質保証を行う**

言葉だとわかりづらいのでイメージはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987894/441d9e2f-bdca-6f38-3768-fbbea67f7377.png)


会社やプロジェクトによっても、範囲や考え方が変わってくと思いますが、
自分の中では、この図のように感じています。


単純にやる範囲が増えたと言えばその通りなのですが、考え方が大きく違ってきていると感じています。

今までは、品質戦略のようなものがあり、ある程度担保したい品質が決まっていたりします。
お客様によっては、品質戦略を考えて提案するなどもありましたが、
企画段階から第三者検証として入ることは、自分の知っている範囲だとかなり少ないものでした。

そう考えると、ある程度何かしらの決まっているものがあった上で、品質保証をしていくというのが
今まで行ってきた仕事であって、これから行っていくQAは、**何も無いところから品質を創り出して** 
いくことだと思っています。

もしかしたら… LITALICOでは、QAチームが発足して間もないので、0スタートの事が多くあります。
今までの「1→2」ではなく、**「0→1」** という何もないところから作っていくという作業もあるので
実際のQAと第三者検証の違い以上に、仕事の違いを感じているのかもしれないです。

# 今主に取り組んでいること
+ 品質向上の支援：ユーザーストーリーテストを中心に、上流工程から要件漏れや、考慮漏れを防ぐ業務を行ってます。
+ プロセス定義：QAグループがプロジェクトに発足されたことによって、開発業務フローの改善や、ドキュメントの改善を行って、プロジェクトマネージャーを支援しています。
+ テストとレビュー：システム利用時の品質と、法令遵守を保証するテストを行ってます。


今後QAメンバーも増えていくので、QAチームの一人として、メンバーと一緒に出来ることを増やしていき、
行っているQA業務の内容を発信していこうと思っています。


# まとめ
まだ自分の中でもQAとしてどのように品質を作っていくかというイメージが固まっていない部分も多い状態ではありますが、
知っているようで、しっかりと理解できていなかったQAという仕事に携わることによって、今まで以上に、自分の成長に繋がっていると感じています。
今までの経験が活かしつつ、第三者検証とQAの違いを意識し、QAとしての考えをしっかりと固めていけたらと思っています。

# 最後に
メンバーにとても恵まれているので、とても刺激があり、そして楽しく毎日を過ごせています。
QAという知っているようで知らない領域に足を一歩踏み入れるのには、不安があることもあるかと思いますが
興味がある方は是非、QAの仕事の話だけでも聞いてみてはどうでしょうか？
（自分も他のQAをやっている方に聞いてみたいです:grin:）
テスト業務をやっている方は特に、今とは違う楽しい仕事に巡り合えると思っています。
2部グラフの判定

# 初めに
この問題をやっていて
https://atcoder.jp/contests/abc282/tasks/abc282_d
2部グラフが分かっていないとおそらく解けない問題だった

2部グラフ自体は結構単純な方法で実装できる
かなり汚い書き方になっているがわかりやすくていいのではないかと思っている
あとはこういうのをぼちぼちテンプレート的な書き方にして直していきたいなあ

```rust
fn dfs_nibu(nibu: &mut Vec<usize>,g:&Vec<Vec<usize>>,start:usize,mut color:usize)->bool{
  nibu[start] = color;
  for i in &g[start]{
    if nibu[*i] != 0{
      if nibu[*i] == 1 && nibu[start] == 1{
        return false;
      }else if nibu[*i] == 2 && nibu[start] == 2{
        return false;
      }else{
        continue
      }
    }
 
    if nibu[start] == 1{
        color = 2;
    }else if nibu[start] == 2{
        color = 1;
    }
 
let flag = dfs_nibu(nibu,g,*i,color);
    if flag == false{
      return false;
    }
}
return true;
}
 
 
fn main() {
  input!{
  n:usize,
  m:usize,
  a:[[usize;2];m]
  }
  let mut s = vec![vec![];n];
  let nn = n as i64;
 
  for i in a {
    s[i[0]-1].push(i[1]-1);
    s[i[1]-1].push(i[0]-1);
  }

let mut nibu = vec![0;n];

for i in 0..n{
  if nibu[i] != 0{continue}
 
let flag = dfs_nibu(&mut nibu,&s,i,1);
if flag == false{
  println!("{}",0);
  return;
} 
 ///2部グラフが複数あり、探索済みを記憶させておく（連結成分が複数あるという言い方するみたい）
  for i in 0..n{
    if nibu[i] != 0 {
      nibu[i] =3;
    }
  }
}
  
}
```
PTA役員本部で LINE WORKSを使う

[LINE WORKS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/lineworks) 23日目、今日はゆかちゃんの誕生日です、かしゆかおめでとう!

今回は、[LINE WORKS](https://line.worksmobile.com/jp/)を使っていますよ、というポエム的な事例内容です。PTA会長として、役員のみなさまとの日常のやり取りのツールとして、[LINE WORKS](https://line.worksmobile.com/jp/)をPOC的に使い始めました。
経緯と雑感などをまとめます。他校でもPTA連合などでも、お使いいただくきっかけにでもなれば。

# 経緯

某Salesforceの中の人しょっさんだからというわけでもありませんが、今年度のPTA活動のオンラインでのやり取りは[Slack](https://slack.com/intl/ja-jp)を使っていました。もともと、わたしの中学校の広報部が使っていたことから、連絡を受けて試してみようということで使い始めました。

みんなもなれ始めた頃、みなさんも御存知の通り [2022年9月1日 - フリープランの更新](https://slack.com/intl/ja-jp/help/articles/7050776459923)にしたがって、過去の情報へのアクセスができなくなりました。購入も検討したり、NPOとしての登録で割引が効かないかと申請も検討いたしましたが、結構大変そうだったり、NPOとして取り扱われるかの保証もできなかったので、別の無料・安価なツールも検討をはじめました。

その時、これまた我が中学校の広報部が[LINE WORKS](https://line.worksmobile.com/jp/)にしたよ、という一報を受けて、[LINE WORKS](https://line.worksmobile.com/jp/)の検討を開始しました。

たまたま知り合いが[LINE WORKS](https://line.worksmobile.com/jp/)で働いていたので、PTA利用について話を伺いました。すると、[非営利団体プラン](https://pages.worksmobile.com/nonprofit-plan.html)を準備されていて、PTAで多く実績があるという話を聞くことができ、管理面でも使い勝手が良さそうだと感じ、今年の秋から[LINE WORKS](https://line.worksmobile.com/jp/)の利用を開始しました。

# PTAでのLINE WORKS利用の良さ

エンジニアのみなさんが想像している以上に、保護者のLINE普及率は半端ないです。ほぼ100%LINEをお使いです。ですから、インタフェイスや使い方のほとんど一緒な[LINE WORKS](https://line.worksmobile.com/jp/)は、トレーニングの手間が省けるという点でとても助かります。

また、LINEとは違って、電話番号に紐付けられておらず、メールアドレスが主体であり、デバイスの制限がありません。複数のスマホや、PC・タブレットの運用など、複数デバイスでの運用が可能なことはとても便利です。複数のPCで使うケースもあるので、とても助かりますし、なんならブラウザでも利用可能です。デバイスを選ばずに、どこでも利用できるので助かります。

そしてファイルなどがフォルダ管理できて、かつ通常のLINEよりも長い期間(3年)保管できるという特性があり、年度末での引き継ぎでも問題が発生しないと考えています。まぁ、我がPTA役員本部は、ファイル関係はGoogle Driveを使っているので、あまり関係はなさそうですけれども。

そして、こんな感じでお手軽に簡単に使えて、[非営利団体プラン](https://pages.worksmobile.com/nonprofit-plan.html)では、無料で1,000人まで、50GBのストレージが利用可能です。まじやばい。申請などが必要ですが、承認されればフリープランからすぱっと10倍のユーザ数が利用できます。

このユーザ数がカバーできるとなると、やりようによってはPTA会員全員にアカウント発行も可能です。

今年度は、PTA役員本部内での活用にとどめています。ただ、今年度の結果を持って、これいいねとなれば、委員会などの一部のPTA会員にも活用範囲を広げていこうかと考えています。

ロールやグループも作れるので、きちっと分割できるのは強みかろうと考えていますし、個々に管理者も割り当てられるので、権限の移譲も容易です。

# LINEや、他のチャットツールと比較して

LINEとはそっくりそのものに近いのですが、残念ながらLINEで利用している絵文字やスティッカーは利用できません。ちょっとさみしいです。標準で入っているものだけだと、ちょっとさみしいです。たまには江頭でも送りたいわけですよ。いえすいません、Perfume送りたい。

あと、LINEとは当たり前ですが、別アカウントになりますし、別のアプリになりますので、ちょっとだけ手間をとっていただく必要があります。別アプリであることがメリットでもありますが、あまりアプリを増やしたくない保護者の方には、ちょっと残念ですね。

グループチャットなどはできるんですが、スレッド運用はできないので、一つのグループで複数の会話を続けていくようなことは難しいです。そして、イベントごとにグループを作ろうかって話になってくると、グループが沢山出来すぎて破綻するような未来も思い浮かびます。グループ運用のベストプラクティスは、すぐに作れない気がしていて、ちょっと考え込んでいます。Slackのチャンネル運用って結構雑にわんさか勝手に作ってもいい感じになるので、気にしないで作っちゃうんですけどね。[LINE WORKS](https://line.worksmobile.com/jp/)のグループは好き勝手に作ってしまえる雰囲気がないです。

# まとめ

こんな感じで、無難に[LINE WORKS](https://line.worksmobile.com/jp/)を利用できています。

まだまだ活用の範囲は狭いところですが、ちょうどよい感じで使えているようで、来年度もこのまま使っていこうかなと考えています。
【GitHub】SSHからHTTPSに変更する方法

## 現状の確認

現在HTTPSなのかSSHなのか確認するために次のコマンドを実行します。  

```terminal
$  git remote -v
origin  git@github.com:UserName/REPO_NAME.git (fetch)
origin  git@github.com:UserName/REPO_NAME.git (push)
```

上記のように表示されればSSHです。  

## 変更する

次のコマンドを実行することでHTTPSに変更できます。  

```terminal
git remote set-url origin https://github.com/UserName/REPO_NAME.git
```

## 変更されたか確認する

再度`git remote -v`を実行して変更されたか確認します。  

```terminal
$ git remote -v
origin  https://github.com/https://github.com/UserName/REPO_NAME.git (fetch)
origin  https://github.com/https://github.com/UserName/REPO_NAME.git (push)
```
リファクタリングプロジェクトを終えて

# はじめに
:christmas_tree:Merry Christmas:christmas_tree:

カオナビ様のAdvent Calendarに参加させていただきます！！
リファクタリングということで、半年間通して実施した所属部署のリファクタリングプロジェクトについて書きたいと思います！
僕が所属している部署は、いわゆる情報システム部門で、全社に展開しているインフラや、基幹システムの導入・構築・保守を行なっています。
プロジェクトをやり遂げた結果、業務の**保守工数割合が33.8%だった**ところから**10%を切る**ところまで削減することができました。
リファクタリングプロジェクトを通して、見えてきたものとは！？

https://qiita.com/advent-calendar/2022/kaonavi

# リファクタリングプロジェクトとは
勤務している会社の自部署内で、半年間通して実施したリファクタリングプロジェクトについて説明します。
## 背景
日常業務が、アラート対応や、システム保守ばかりに工数を取られており、本来やるべき数年後を考えたシステム提案・構築や改善にほとんど手をつけることができていませんでした。
そこで、周辺組織へもご理解いただき、半年間リファクタリングと改善に集中させていただくことになります。
急ぎ案件だったり、致命的な不具合については随時相談を受け付けていましたが、基本的に新規の相談を受ける際は慎重に行いました。リファクタリングに集中する必要があったからです。

## 目的
**保守工数を1/3以下に圧縮**し、来年からは、**未来に向けた施策に工数を使う**ことができるようになっていること。

## 方針
- **対応する優先度**
    - 保守対応にかかっている工数を集計し、一番保守に時間のかかっている仕組みをリファクタリング・改修する
- **新規案件やアラートへの対応**
    - リファクタリング中に発生したアラートに対しては、これまでと変わらず対応する
    - リファクタリング中は、急ぎ案件を除いて、新規案件の受付を停止する
- **不要なツール、データの整理整頓**
    - 開発ツール、開発言語、開発ルールを定める
- **成果物の品質向上**
    - 設計レビュー、実装後レビューの厳格にする

# プロジェクト結果
冒頭でも述べましたが、プロジェクト自体は成功でした。見事に保守工数を1/3に圧縮し、保守工数の割合を全体の10%にまで削減することができたのです。定性的な評価としては次のようなことがあります。
## リファクタリング前の状態
- 不要なデータファイルや、リソースが至る所に転がっており、**使われているのか使われていないのかさえ管理できていない**
- 例えばアラート通知するような仕組みが共有化できておらず、処理ごとで通知処理を記述している状況で非効率だった
- **前任者の遺したコードがカオス状態**で、ナレッジもなく、障害が発生するたびに膨大な保守工数が発生していた。
## リファクタリング後の状態
- 必要なデータが整理されている状態になった。今残っているデータファイルはすべて必要なもので、本番環境として稼働しているのか、テスト環境として稼働しているのか**明確に整理された状態**になった
- 前任者からの引き継ぎが無くブラックボックス化していたコードは、リファクタリングによりモダンなコーディングで、**保守しやすい状態**になりました
- 組織から1名育休を取得しているにもかかわらず、問い合わせの**新規案件を受け取る余裕**が保てています。
# 振り返り
続いて、リファクタリングに参加していたメンバーから出たメンタル面の振り返りについて、触れていきたいと思います。
## リファクタリングを通してストレスだったこと
- 半年間という納期があったため、理想的な改修やリファクタリングではなく、目の前に見えている課題を解消するような修正にせざるを得ない状況が発生してモヤモヤ
- 設計レビュー、実装後レビューを厳格化したことにより品質は向上したが、資料作成やコミュニケーション**工数が多く発生**してモヤモヤ
- レビュイーは、レビュアーから指摘的な意見が多く出ているように感じて、**ストレスがMAX**でモヤモヤ
- 設計や実装に関して、設計やコーディングの**宗教的な議論**が何度かあり、前に進むのに時間がかかってモヤモヤ
- リファクタリングに集中させてほしい旨を展開していたが、幾度となく急ぎではない問い合わせが発生してモヤモヤ
## リファクタリングして良かったな感じたこと
- 目標を達成し、**とても大きな成功体験**を得ることができた！
- 実際に保守工数が圧縮し、未来を見据える動きに時間を当てることができてきた！
- 周辺チームの問合せにしっかり耳を傾けることができ、**メンバー間の関係性が向上**した！
- 共通処理を整えたことで、新規開発時にも流用できることができ、構築工数の削減ができている！
# おわりに
いかがでしたでしょうか。つくづく思いますが、**仕事のための仕事ほど、無駄な仕事はありません！**
リファクタリング自体は決して悪ではないのですが、それをどのような方針で行うかによって、メンバーのストレスは増減します。
特に、設計レビューや進捗管理のために膨大な工数がかかっているという非効率な状況は、よりメンバーの不満を膨らませてしまいます。プロジェクトとしてしっかりと管理したい、進捗させたいという気持ちも一定わかるのですが、時間が限られている状況では、過剰な品質管理は避けるべきでしょう。
結局は、**納期、人的資源、品質の総合的なバランス**が良いポイントを探すことに尽きるのです。そしてそれを定期的に測りましょう。（測るための工数はかけないように注意してください。）

:christmas_tree:最後まで読んでいただきありがとうございました！:santa_tone1: