OmniAICreator/Qiita-1.07M huggingface dataset:
AdbPad v1.0.0 をリリースしました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/35e6c013-3a6b-a5ed-d888-073749489608.png)

# はじめに

AdbPadはAndroidアプリケーションの開発・テストをサポートするGUIアプリケーションです。AdbPadは以下のGitHubリポジトリで絶賛開発中です。よろしければコントリビュート＆スター登録お願いします。

https://github.com/kaleidot725/AdbPad


# AdbPadでできること

AdbPadでは以下の機能をサポートしています。

- Windows10/11, macOS対応
- ライトテーマ・ダークテーマ切り替え
- コマンド送信
- テキスト送信
- 各テーマのスクリーンショット撮影

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/ab4ca8e2-d903-8ed0-7cd3-cf19cd9d331a.png)

## Windows・macOS・Linux対応

AdbPadはWindows・macOSに対応しています。Androidアプリケーションの開発・テストは様々なOSを利用して実施されると思いますがどの端末でも問題なく利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/1bb91930-e36d-2120-7c48-16f6e3698a3b.png)

## ライトテーマ・ダークテーマ切り替え

AdbPadはライトテーマ・ダークテーマの切り替えに対応しています。テーマの切り替えはあまり気にしない人もいるかなと思います。ですが自分の好みのテーマに切り替られるのは、私は重要だと思っているので対応しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/e3365f5e-7a7f-9e1e-caf2-44dfdb2857d8.png)

## コマンド送信

AdbPadでは開発・テストでよく利用する操作をコマンドとして端末に送信できます。コマンドの送信を利用することで開発・テストで手間がかかる操作をワンクリックで実行できます。現状は以下のコマンドに対応していますが、まだまだ少ないのでこれから拡充していく予定です。

-  レイアウト境界表示 ON/OFF
-  タップ表示 ON/OFF
-  スリープモード ON/OFF
-  ダークテーマ ON/OFF
-  Wi-Fi ON/OFF
-  モバイル通信 ON/OFF
-  WiFi＆モバイル通信 ON/OFF

![demo1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/6a822cdb-18e1-358b-83e0-52de54d5b581.gif)

## テキスト送信

AdbPadでは開発・テストでよく利用するテキスト入力を補助します。

- テキストの保存
- テキストの削除
- テキストの送信

![demo2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/7311a180-483e-e03f-ae01-fbf6c3b017cd.gif)

## 各テーマのスクリーンショット撮影

AdbPadでは開発・テストでよく利用するスクリーンショットの撮影を補助します。現状はスクリーンショットのプレビューのみ対応している状況ですが保存やクリップボードへのコピーも対応予定です。

- 現在のテーマでのスクリーンショット撮影
- ダークテーマでのスクリーンショット撮影
- ライトテーマでのスクリーンショット撮影
- ダーク・ライトの両テーマでのスクリーンショット撮影

![demo3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/c9b637f9-5243-0285-67ba-8c2b24427981.gif)

# おわりに

AdbPadはこちらからダウンロードできますので、ぜひお試しください。

https://adbpad.netlify.app/

AdbPadはこれからも開発を続け、新機能を追加していく予定ですが、現状の改善点などあればGItHub Issueに記載ください。

https://github.com/kaleidot725/AdbPad/issues
Pythonで文章をヒソカっぽく改変するコードを書いた

# はじめに
日本語の文章をヒソカっぽく書き換えるだけのコードです。
ヒソカをよく知らない人はハンターハンターを読んでください。

## 環境
python3.9.4(バージョンは何でもいい)
Windows(何でもいい)

# 処理
`。`をランダムに`♠,♣,♦,♥`に置換する。
10%の確率で三点リーダーが入り込む。

## コード
Pythonで実装したコード。
```python:hisoka.py
# coding: UTF-8

import random

class Hisoka:
    def __init__(self, leader="・・・", leader_percentage=0.1, trump=["♠", "♣", "♦", "♥"], split_text="。"):
        self.leader = leader
        self.leader_percentage = leader_percentage
        self.trump = trump
        self.split_text = split_text
    
    def __call__(self, text):
        # 区切り文字で文章を分ける
        text_list = text.split(self.split_text)[:-1]
        output_text = ""

        for text_data in text_list:
            output_text += text_data
            if random.random() < self.leader_percentage:
                output_text += self.leader
            output_text += random.choice(self.trump)
        return output_text


if __name__ == "__main__":
    text = "メロスは激怒した。必ず、かの邪智暴虐の王を除かなければならぬと決意した。メロスには政治がわからぬ。メロスは、村の牧人である。笛を吹き、羊と遊んで暮して来た。けれども邪悪に対しては、人一倍に敏感であった。"
    hisoka = Hisoka()
    print(hisoka(text))
```

# 実際の出力
下記コマンドで実行。
```bash
python hisoka.py
```

出力内容(実行するたびにランダム変化)
```
メロスは激怒した♠必ず、かの邪智暴虐の王を除かなければならぬと決意した・・・♣メロスには政治がわからぬ♦メロスは、村の牧人である・・・♠笛を吹き、羊と遊んで暮して来た♥けれども邪悪に対しては、人一倍に敏感であった♦
```

# 上までの内容に対して本スクリプトを実行した場合の出力
```
# はじめに
日本語の文章をヒソカっぽく書き換えるだけのコードです♠
ヒソカをよく知らない人はハンターハンターを読んでください♠

## 環境
python3.9.4(バージョンは何でもいい)
Windows(何でもいい)

# 処理
`♠`をランダムに`♠,♣,♦,♥`に置換する♠
10%の確率で三点リーダーが入り込む♣

## コード
Pythonで実装したコード♦
～～～以下略～～～
```

# おわりに
皆さんはもっと有意義な時間の使い方をしてみてください・・・♦
Boxのランサムウェア対策TIPS

はじめに
- 

この記事ではランサムウェア対策TIPSをご紹介します。
Boxを活用したランサムウェア対策や復旧方法について確認していきます。

- Boxが安全な理由
- 感染予防策
- 暗号化からの復旧
- ファイル/フォルダ削除からの復旧

Boxが安全な理由
-

Boxでファイルを管理することはオンプレミスで管理するよりも安全と言えます。
もしBoxにランサムウェアがアップロードされたとしても、Boxに保存されたファイルは保存時に暗号化されており、プログラムを実行可能な環境もないためです。
そのため暗号化されたファイルが他のユーザーと共有される可能性はありますが、ランサムウェアがBoxのクラウドストレージ内で実行され、拡散するといったことはありません。


感染予防策
-
- メールの添付ファイル対策
マルウェアの侵入にメールの添付ファイルが利用されるケースは非常に多いです。
メール添付ファイルからの感染対策にはメーラーからPCに直接ファイルを保存せず、連携アプリを利用してBox上に保存する方法があります。

    - Box for Outlook　
    - Box for Google Workspace

- ファイルリクエストリンクを活用する
ファイルリクエストリンクを活用することでBoxアカウントを持たない相手からもファイルを共有してもらうことが可能です。
相手からアップロードされたファイルは指定したBoxフォルダ上に保存されます。
ファイル共有にBoxを活用することでマルウェア感染を防止するだけでなく、PPAPから脱却したスマートなビジネスパーソンに見えるメリットもあります。

![ファイルリクエスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991170/dd2e4abc-6d50-443a-7c43-83e35e4649ef.png)

暗号化からの復旧
-
万が一ファイルの同期などによって暗号化されてしまった場合でも復旧方法があります。
Boxは版管理を行っているため、簡単に過去のバージョンに戻すことが可能です。

![ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991170/704817f5-5c93-eca2-d97a-36c891a1b63c.png)

ファイル/フォルダ削除からの復旧
-
もしもBox上にあるファイルが削除されてしまった場合でも復旧は可能です。
Box上から削除されたファイルはごみ箱へ移動されるため、完全に削除はされません。
ごみ箱からファイルを復旧することで元の場所へ戻すことが可能です。
![復元.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991170/36e9f275-496e-8f87-3ffd-cdd1a21be758.png)

またオプションであるBox Governanceを利用することでごみ箱からの削除を不可とする設定も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991170/38156ecd-67ce-a749-4cb7-a7a99067afd9.png)

まとめ
-
以上の通り、Boxを利用した感染からの予防策や万一の場合のファイルの復旧方法をご紹介しました。

当然ですがBoxだけサイバー空間における脅威をすべて払拭できるわけではないので、多層防御といった基本的なサイバーセキュリティ対策は必要です。
しかしファイルをBox上で管理することは加速度的に脅威度を増しているランサムウェアからのファイル保護にも大きく貢献することができます。
本記事を参考にBoxを活用したランサムウェア対策をご検討いただければ幸いです。
ES Modulesが使えるようになるまでの変遷

どーも、フロントエンドエンジニアをしているズッキーです。

学生時代のアルバイトも含めると、
2014年ごろからフロントエンドに関わってます。

今や、ないと仕事にならない、ES Modulesですが
昔はデザインパターンなどでどうにかして解決していたなぁと思い、
変遷をまとめてみました。

## はじめに：ここが辛いよJavaScript

### 名前空間 サポートされておらずすぐ競合する💥

```JavaScript
// one.js
var hoge = 123;

// two.js
var hoge = "文字列";

// three.js
hoge * 10; //NaN
```

### 依存関係を気にしないといけない😎
```html
<!-- 読み込み順を変えたらバグる -->
<script src="js/vender/jquery.min.js"></script>
<script src="js/vender/jquery.cookie.js"></script>
<script src="js/vender/jquery-ui.js"></script>
```

## 1.デザインパターンやAMD形式

### IIFE (即時実行関数式)でモジュール化

IIFE は、独立したスコープを持つことができるため、
モジュール化として利用できます。

```javascript
// IIFE によるモジュール定義
var myModule = (function() {
  // モジュール内で定義される関数
  function myMethod() {
    // 関数の処理を記述する
  }

  // モジュールを返す
  return {
    myMethod: myMethod
  };
})();
```

### AMD形式
define 関数を用いてモジュールを実現する方法
AMD 形式では、モジュールは以下のように define 関数を使用して定義されます。
define() 関数の第一引数には依存するモジュールを指定し、第二引数にはそれらのモジュールが読み込まれた後に実行される処理を指定します。

```JavaScript
define([ 'dep1', 'dep2' ], function(dep1, dep2) {
    // モジュールの本体
    // dep1, dep2 は依存するモジュール
    return {
        // モジュールのインタフェース パブリックで使わないならreturnしない
    };
});
```

## 2.バンドルツールが出てきてNode.js側の構文が使えるようになる
### Browserify
https://browserify.org/

Browserifyを使うと、Node.jsの構文でブラウザの操作が行えるようになります。
これはBrowserifyがブラウザ実行可能な形式にトランスパイルを行う事により実現されます。

よってNode.jsのrequire構文がフロント側で使用可能になった。

```javascript:エクスポート側
// utils.js
const message = "Hello, World!";
module.exports = {
  message: message
};
```

```javascript:インポート側
const utils = require("./utils");
console.log(utils.message); // "Hello, World!"

```

### webpack
https://webpack.js.org/

Browserifyに比べてimgファイルや、.scssファイルなど幅広くトランスパイルが可能。
現在ではBrowserifyに比べて広く普及している。

## 3.ついにES Modulesが使えるようになった
JavaScriptの言語仕様として、require構文ライクにモジュールが定義できるように🎉

各ブラウザのサポート状況の差を、webpackがIEも含めて使えるように、
トランスパイルが可能となったので、広く使われるようになった認識。

```javascript:エクスポート側
export const foo = 'hello world';
export function bar() {
  // do something here
}
```

```javascript:インポート側
import { foo, bar } from './my-module.js';
```

## 最後に
時代によって、ベストプラティクスは変化してますが、
しっかりキャッチアップして使っていく姿勢が大切だなぁと思います。

よいJavaScriptライフを！
オプティマインドへ転職して4か月経って思うこと

もし身近な人に「オプティマインドというテックスタートアップに転職してどうよ？」って聞かれたらこう答えます。
「オプティマインドに入社したことは間違いではなかった」

はじめまして、オプティマインドでビジネスコンサルタントを担当しております尾崎と申します。オプティマインドのアドベントカレンダー14日目を担当します。
なんで14日目担当に立候補したかと言うと、2022年12月14日は私の40回目のbirthdayだからです！
そんなことはさておき、今回はオプティマインドに入社して4ヶ月経ったところでの感想みたいなものを記していきたいと思います。冒頭の言葉はまさに4か月たった時点での気持ちを一言で表したものです。

まず、なぜ私が40歳になる歳に転職を考えたかというと、理由は大きく2つあります。

①あたらしいふつうをつくりたい
私は元々物流会社で営業・業務オペレーション・戦略企画等々に幅広く従事し、その後外資系コンサル→外資系事業会社と渡り歩くわけですが、自分の仕事の源泉はお客さんのため、世の中のために貢献することであるということに気づきました。また、単純に世の中に何かを提供するだけでなく、せっかく提供するならお客様のこれまでの価値観を変えるような、つまり「あたらしいふつう」を提供することに自分の残りの人生を捧げ挑戦したいと思いました。

②自分の経験を組織に還元したい
また、これまで色々な業務を経験し、失敗や成功を繰り返しながら色々と学ぶことができた自分は運が良いなと思っています。ミドル層になった今思うことはこの学んできたもの・建研を組織に還元することで新たなものが生まれてくるのではないかと思い、使命感なるものを抱きました。スタートアップのような組織として勢いがある一方で、カオスな環境で日々アップデートされていく組織こそ、自分の経験を還元できる場なのかなと思った次第です。

その上でオプティマインドに懸けても良いと思ったのは以下の3つ
私がオプティマインドを志望した理由は①会社の志に共感できるか、②事業性を評価できるか（私は技術力、ビジネスモデル、人々の価値観を変えるサービス、事業展開エリアの4点で評価しました）そして、③会社の社風・雰囲気に共感できるかの3点です
これらはすごく重要で、なぜそのスタートアップが良いのかを自分が大事にしている価値観と照らし合わせながら自分で分析することが重要だと思います。スタートアップといっても千差万別なので、自分自身で本当にこの会社でいいのかを深堀り考察しないと、入社した後にお互い不幸になる可能性があると個人的には思います。

入社したことは間違ってなかったし、新たな気づきもあった
まずもって、入社前に自分がイメージしていたことは間違ってなかったです。
私自身が実現したい環境があること、また入社前に分析した事業性や社風と大きな乖離はありませんでした。

また、新たな気づき（この会社に入って自分にポジティブなこと）として、この会社は本質を求めることを社内で非常に意識しているということです。
スタートアップとしてスピード感をもって取り組むことは前提としつつも、お客様がこう言っているからやるというわけではなく、本質的な課題は何で、どうすればそれを解決できるのかを突き詰めます。上長の意向やスケジュールありきで成果物を仕上げていくようなことは全くなく、役職や年齢に関係なく自ら考える姿勢は本当に刺激になります。
ちなみに、社内では「本質マイニング」という行動指針の一つとなっております。
詳しくは、弊社代表の松下が記したnoteをご覧ください。
https://note.com/matsushita_ken/n/nb3b60261a5d7


次に、エンジニアリングチームとの連携です。オプティマインドの事業上の強みとして技術力があることを入社前から感じてはいました。実際に、エンジニアのメンバー達は良い意味で尖ってて優秀な方々ばかりです。
一方で、その強力な力をビジネスに最大限活かすためには、エンジニアリングチームとできるだけ同じ言語で会話できるようにならなければいけないと痛感しました。入社前は技術力があるから、他社と差別化できるだろうとか安易に考えていたところが正直ありましたが、そこは大間違いでした。当たり前の話かもしれませんが、密にコミュニケーションをとるためにエンジニアの方々がどういう風に考え、どういう情報が必要とか、相手の立場にたってビジネスとエンジニアの両輪で物事を考えないといけないなと感じてます。これは一定のスキルや勉強も必要であり、ポジティブに考えると、まだまだ自分自身が成長できる機会があることを発見できました。

最後の気づきというか、改めて認識したこととして、物流業界の課題に対応する難しさです。配車業務と一括りにできますが、ふたを開けてみると個社個社に課題が違うので、なかなか業務にフィットさせることが難しいですし、多重構造で業界が成り立っているので色々なステークホルダーがいて一筋縄でいかないとか、物流業界のDXを推進する上での壁を再認識しました。ただ、この壁をネガティブには捉えておりません。なぜなら挑戦できる壁があるということは、壁を乗り越えた時の喜びもあるわけで、その喜びを味わえると考えたらワクワクします。
この壁を乗り越えてお客様に新しい世界を提供することがオプティマインドのミッションであり、挑み続けたいと改めて思いました。

最後の最後に、オプティマインドでは「多様性が進んだ世の中でも、全ての人に物が届く世界を持続可能にする」という物流業界の壮大な社会課題を解決すべく、一緒に働く仲間を大募集中です。少しでも興味が湧いた方はカジュアル面談も大歓迎ですので、気軽にお声がけください！
https://recruit.optimind.tech/
paizaラーニング「2 変数の入れ替え Python3編」

https://paiza.jp/works/mondai/array_primer/array_primer__elm_change
#### 私の解答
```Python3
a,b = map(int, input().split())
print(b,a)
```
#### 解答例1
```Python3
values = input().split()
A = int(values[0])
B = int(values[1])

tmp = A
A = B
B = tmp

print(A, B)
```
#### 解答例2
```Python3
A, B = map(int, input().split())

A, B = B, A
print(A, B)
```
paizaラーニング「配列の書き換え Python3編」

https://paiza.jp/works/mondai/array_primer/array_primer__elm_rewrite
#### 私の解答
```Python3
a, b, n = map(int, input().split())
li = [int(x) for x in input().split()]
for i in range(n):
    if li[i] == a:
        li[i] = b
        print(li[i])
    else:
        print(li[i])
```
#### 解答例1
```Python3
values = input().split()
A = int(values[0])
B = int(values[1])
N = int(values[2])

a = [0] * N
values = input().split()
for i in range(N):
    a[i] = int(values[i])

for i, ele in enumerate(a):
    if ele == A:
        a[i] = B

for ele in a:
    print(ele)
```
#### 解答例2
```Python3
A, B, N = map(int, input().split())
a = [int(x) for x in input().split()]

for i, ele in enumerate(a):
    if ele == A:
        a[i] = B

for ele in a:
    print(ele)
```
git instance is too old と Fork に言われた

# git instance is too old と Fork に言われた

Fork を 1.80.0 に更新したところ、ファイル差分を確認する画面に、以下のようなエラーメッセージが出るようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/40e2f691-5ef9-73ef-7453-9b1c57db1e8b.png)

> Error
> fatal: unrecognized argument: --diff-merges=1
> git instance is too old

どうやら、利用している Git のバージョンが古いようです。

# Git のバージョンを確認

`File > Preferences > Git > Git Instance` を確認したところ、 `2.27.0.windows.1` というのを利用していることがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/b9b92ee3-a125-5e72-d048-8f08b3f25e2e.png)

# 内蔵 Git に切り替え

`Git Instance` の欄をクリックしたところ、選択肢が出てきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/d5a3c44d-761e-ab93-dc2a-39ebc527b47d.png)

`2.36.1.windows.1 - Fork git instance` という選択肢があったので、そちらを選択してみました。
こちらは、Fork に内蔵された Git のようです。

そうすると、エラーは解消されました！

めでたし、めでたし。

# さいごに

本記事作成にあたり、以下のサイトを参考にさせていただきました。ありがとうございました。

- https://git-fork.com/
React パフォーマンス改善〜入門

## Reactで作った画面が遅い原因
おもに以下がパフォーマンス劣化の原因だそうです

* 無駄にたくさんレンダリングしている
* 計算処理が重い/無駄に実行されている

画面描画なのか、計算処理なのか当たりをつけるのが良さそうです

## 原因の調べ方

ブラウザのディベロッパーツールのパフォーマンスツールで確認します
特に遅くないサンプルなのですが、、スクリプト（計算処理）はこれくらい、レンダリング（画面描画）はこれくらいが見えますね

![スクリーンショット 2022-12-14 20.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/195508fa-eda1-2c14-efe5-628545fac982.png)

## レンダリングが遅かったら
どのタイミングでパフォーマンスが悪くなるか？ということも確認します

* 初期表示が遅い
    * 大量データをリストコンポーネントにセットして表示など描画するコンポーネントが大量にないか確認する
* イベント発火後に遅くなる
    * 本来再描画しなくて良いコンポーネントが再描画されてしまい遅くなっているので再描画されている部分を調査する

再レンダリングされている部分はchrome拡張ツール「React Developer Tool」で確認します
拡張ツールをインストールしてchromeを再起動するとディベロッパーツールのタブに「Component」と「Profiler」が表示されます
![スクリーンショット 2022-12-14 20.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/f860498c-97e5-e2ca-12f9-9d864d395e3e.png)

Componentタブを選択後、設定ボタンを押して
`Highlight updates when components render.` にチェックします
![スクリーンショット 2022-12-14 20.32.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/a17b6155-f7e2-3779-0780-6c937d12bb93.png)

この状態で問題のイベントを実行すると再レンダリングされた箇所に水色の枠がパッと出てきます
![スクリーンショット 2022-12-14 20.39.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/184ec2d1-bdc9-3daf-1541-948d7613d317.png)

この水色枠の箇所に当たりをつけてパフォーマンスが悪くなった箇所を調査します

## 計算処理が遅かったら
`useMemo()` を使って毎回複雑な計算が実行されるのを防ぐ！（さっき教えてもらった）

あとは誰か教えて〜〜〜〜
スクラムでの進捗管理の考え方

# はじめに

- 別にこうすべきとかじゃない。
- あくまでサンプルというか考え方みたいな話。

# アジャイルな進捗管理とは
## 進捗として評価するもの
「動くもので進捗を評価する」ってのがよく言われています。
もう少し噛み砕きます。

- 必要なテストやレビューなどが行われその指摘対応も含めて完了している状態である
- デプロイされて動く状態である

**その理由**

- 顧客からすれば中間成果物の状態は何も進捗していないので最終成果物まで至ってようやく進捗を評価すべき
    - 設計しただけではそもそも動くかどうか不明
- 完了の基準をずらさない
    - 完了の定義が複数あると進捗評価を間違えることがある（担当の作業完了と、レビュー完了を誤解するなど
    - 別の完了の定義と誤解した、などの言い訳を潰す

**ウォーターフォールとの違い**

「書き上がった設計書の数」（システム開発としての中間成果物）を進捗指標としてはあまり扱わない。
なお、保守のために必要なドキュメントの作成などは、進捗指標として取り扱っても良いと思う。
少なくとも、設計工程が終わったことを評価するためだけに設計書をカウントすることはなくなる。

## 進捗の立ち位置
**スピードの測定**
「スプリントと呼ばれる固定化された一定期間内でどれくらいの作業量をこなせるかを見極める」というのが立ち位置になります。
スプリントというメタファーに合わせるなら「走るスピード」を測定するイメージです。

**測定したスピードの使い方**
このスピードを元に計画を立てます。
スピードが先で、計画が後。
スピードに応じて計画を見直していくことになります。

**ウォーターフォールとの違い**
多くの場合計画を優先して、スピードをどうにかしようとします。
が、多くの場合作業効率は上がらないし、残業でカバーみたいなケースが多いんじゃないでしょうか。

アジャイルの文脈では、現場に負担を強いて作業を行わせても、品質が悪化するため、最終的なスピード向上には至らないとされています。
なので、スピードはそう劇的には変わらないという前提で計画を立てるというスタンスになります。

**注意事項**
なお、走るスピードを上げていくことは求められ続けます。
劇的に変わることは少ないかもしれませんが、一定で居続けて良い理由はありません。

## 調整弁をどこに持つか
『そうは言っても「mm/ddまでにxxxを実装しないといけない」という要求にどう答えるのか？』というのがあるかと思います。
アジャイルでは主に「納期」もしくは「スコープ」を調整弁に持ちます。

**納期**
シンプルにmm/dd予定を、mm+2/ddに変更するなど。

**スコープ**
「xxx」が必須なのであれば、「yyy」は落とすなど。
もしくは「xxx」が実現する要件を10個から5個に落とすなど。

**調整できない**
ツラい。
先の見通しが硬いのであれば、ここで悩むケースは少ないでしょうが、アジャイルを選択している以上、先の見通しがあまり立たないのかと思っています。
いざこの事態に見舞われてから調整しようとしても、かなり無理なので、事前に調整する必要があります。

そのためにPJ開始前に **納期ないしはスコープを調整する権限を持っている人を含めた状態で** 「トレードオフスライダー」を会話しておくのが良いかと思います。

https://devtab.jp/entry/internal/32

ここで揉めるだけ揉めておくしかない。
ここで収束できない・納得が得られないならアジャイルは始めないほうが良い。
受託開発の場合は、受託した場合のリスクが高すぎる。

**それでもアジャイルじゃないと行けない**
もう最終手段は「めっちゃバッファ持つ」しかない。
他に良いアイデアは思いつかない・・・

PJ終了時点で結局誰かしらには怒られる気がするので、もし自分が担当だと割と絶望してるかもしれん。

# まとめ

- 進捗として評価するものは「動くもの」
- 「走るスピード」をインプットにして、「計画」を立てる。（逆ではない）
- 調整弁を「納期」もしくは「スコープ」で持つ（両方が望ましい）

# 次回予告

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

本記事は、2022アドベントカレンダー「受託アジャイル」の記事です！他にも興味あれば見てってください。
次回は、アジャイルな品質の考え方です。
APIGatewayについてまとめてみた

# APIGatewayは本当に便利なのか
- 1.APIGatewayとは
- 2.API機能について
  - 2-1.機能詳細
  - 2-2.メリットデメリット
- 3.APIタイプ
- 4.まとめ


### 1.APIGatewayとは
APIを一括で管理、作成できてしまうものです。
APIの公開、バージョン管理をまとめて行うことが出来ます。
また、認証やレスポンスのモニタリング等も行うことが出来るので
管理者の負担を激減させることが出来ます。

そもそもAPI(Application Programming Interface)とは、
ソフトウェアもコンポーネントが相互に使用するためのインターフェースを指します。
つまり、人の作ったものを利用して自分のものを楽につくっちゃおうということです。



### 2.API機能について
###### 2-1.機能詳細
![APIGateway.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/856599/ee80a0d5-a040-1c8e-c261-95b20653c9e7.jpeg)

上図で示した通り、LabdaやEC2、アプリケーションを通す前に
APIGatewayは位置しています。
本質は「クライアントからリクエストを受け取ってバックエンドに渡す、
バックエンドからレスポンスを受け取ってクライアントに返す」
ですので、それを意識すれば理解できると思います。



###### 2-2.メリットデメリット
- セキュリティ管理
一つ一つのリソース（Labda,EC2等）に認証等を行いセキュリティの向上を行うより、APIGatewayで認証を行えば効率がいいと思いませんか？
IAM（AWS Identity and Access Management）とAmazon Cognitoを使用して
APIへのアクセスを制限することがきます。

- モニタリングによる監視
Amazon　CloudWatchと連携し各リソースの監視や、
ログを収集、分析などをすることができます。

- バージョン管理
APIGatewayは複数のバージョンを管理できます。

- コスト削減
基本的には受信したAPIコールの分だけ料金が発生します。
※WebSocket APIは転送されたメッセージと接続時間に対して利用料金が発生します。
CloudWatchの利用も含め無料で扱える利用枠も存在するので一度利用してみるのもありでしょう

### 3.ユースケース
##### 3-1　3つのAPI
AWSが提供しているAPIには３つのタイプがあります。
・REST API
特徴として、データ形式はJSON,通信の処理はHTTPメソッド利用し、
ステートレスな設定となっています。
|役割|意味|
|:---:|:---:|
|POST|URIをもとにリソースを作成|
|GET|リソースをもとに詳細情報取得|
|PUT|リソース変更|
|DELETE|リソース消去|

 REST APIをAPI Gatewayを用いて作成する際には２種類さらにわかれています。
パブリック（オープン）APIとプライベートAPIです。
プライベートAPIはパブリックから接続が出来ないAPIです。
他のアカウントから接続できないとは思いこまないようにしてください。
VPIエンドポイントを持っていれば共通して利用することが出来るのです。
使用する際はVPCエンドポイントで絞る等のセキュリティをかけてください。

・HTTP API
HTTP APIはREST APIの後に作成されました。
REST APIの一部の機能だけを使い低レイテンシー且つコスト削減に適しています。
また、呼び出し先がLambdaもしくはHTTPプロキシのみとなっています。

・Websocket API
そもそもWebsocketとはブラウザとウェブサーバ間の双方向の通信を規格化したものです。
リアルタイム通信ともいわれており、高速に通信が必要な場合に使用します。



### 4.まとめ
API Gatewayはフルマネージド型のサービスであり、
自動でスケールを行い仮想サーバを管理してくれるサービスです。
使用量に応じた料金が課せられますが、管理費用と比べるまでもないでしょう。
またリクエスト/レスポンスなどの構成要素も標準化されており、
認証機能やWAF連携によりセキュリティの向上にも繋がっています。


###### 参考
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html
https://docs.aws.amazon.com/apigateway/index.html
re:Invent 2022 コンテナ関連の新サービス、アップデートまとめ

# re:Invent 2022で発表されたコンテナ関連のアップデートをまとめました

# ECS
## Amazon ECS Service Connect を発表
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/networking-connecting-services.html

- サービス間通信を提供するサービス

- Amazon ECSで稼働するサービスのエンドポイントに名前を定義し、クライアントからは名前を使用して接続できる機能
- Amazon VPC DNS 構成に依存しない名前空間内のサービスを参照
- アプリケーションを監視するための標準化されたメトリクスとログ

- Amazon ECS でサービス検出とサービス メッシュの両方の組み合わせによって実現されている

詳細はコンテナヒーロー新井さんの素晴らしい資料をご覧ください！
https://speakerdeck.com/iselegant/a-new-way-to-connect-services-with-ecs-service-connect

12/9にGravitonもサポートされました
https://speakerdeck.com/iselegant/a-new-way-to-connect-services-with-ecs-service-connect

# EKS
## AWS Marketplace for containers のアップデート
- EKS クラスターに AWS Marketplace for containers から入手したコンテナソフトウェアを直接デプロイ可能に
- デプロイ方法
    - マネジメントコンソール
    - CLI
    - eksctl
    - API
    - CloudFormation
    - Terraform など

- AWS Marketplace for containers で提供されるソフトウェ
アは脆弱性診断と EKS 上での稼働確認が行われている
- AWS Marketplace が持つ支払いの一元化や柔軟な支払いオプション、アップデート通知等の機能を EKS でも利用可能に

## AWS Nitro Enclaves が EKS と Kubernetes をサポート
https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-nitro-enclaves-supports-amazoneks-kubernetes/

- AWS Nitro Enclaves は EC2 インスタンス内で機密
性の高いデータをさらに保護し、安全に処理する
ための分離された環境を作成する機能

- Amazon EKS と Kubernetesポッドから Nitro Enclaves を操作可能に
- Nitro Enclaves Kubernetes Device Plug in により Kubernetes Pod としてデプロイし、容易に管理することが可能になり、コードを書く必要がなくなった
- 機密性の高いデータを扱う Kubernetes ワークロードにおいて、Nitro Enclaves の隔離空間を用いたデータ処理によるさらなるセキュリティ対策の実装が容易に
- Nitro Enclaves をサポートする全てのリージョンで利用可能

## Container runtime threat detection for GuardDuty
https://dev.classmethod.jp/articles/container-runtime-threatdetection-guardduty/
- 動作しているコンテナランタイムに対しての脅威検知が可能に？
- 詳細は後日とのこと


# re:Capのご案内
12/21(水) [JAWS-UG横浜 #50 AWS re:Invent 2022 Recap Container](https://jawsug-yokohama.connpass.com/event/262682/)でキャッチアップを行いますのでぜひぜひご参加ください！
stripe決済のためのvueプラグイン「vue-stripe」

決済代行サービス [Stripe](https://stripe.com/jp)皆様ご存知でしょうか？

Stripe決済システムをVue.jsでフロント構築するためのプラグインとして  **[「vue-stripe」](https://vuestripe.com)** というものが存在します。

stripeと公式パートナーを締結している信頼あるプラグインです。

## 実際にサクッと見てみる

### インストール

Yarn経由
```
yarn add @vue-stripe/vue-stripe
```
npm経由
```
npm install @vue-stripe/vue-stripe
```

### 使用法

コンポーネントに`StripeCheckout` をインポートするのみで利用開始可能。

```
<template>
  <!-- stripe-checkout -->
</template>

<script>
import { StripeCheckout } from '@vue-stripe/vue-stripe';
export default {
  components: {
    StripeCheckout,
  },
};
</script>
```

### Props

決済関して必要な情報をあらかじめきちんと用意してくれています。

| Props名 | ⁠型 | 　デフォルト | 必須 | ⁠説明 | 
| --- | --- | --- | --- | --- |
| pk | string | none | Yes | Stripe の公開可能なキー。 | 
| sessionId | string | none | No | Checkout のクライアントとサーバーの統合で使用される Checkout セッションの ID。 | 
| LineItems | array(object) | none | No | 顧客が購入したいアイテムを表すオブジェクトの配列。 | 
| mode | string | none | No | **一回限りの支払いか**または**サブスクリプション形式支払い**のいずれかである、チェックアウト セッションのモード。 | 
| ​customerEmail​ | string | none | No | 顧客オブジェクトの作成に使用される電子メール アドレス。 | 
| successUrl | string | none | No | 支払いが完了したときに Stripe が顧客に送信する ためのURL。 | 
| cancelUrl | string | none | No | 支払いがキャンセルされたときに Stripe から顧客を送信するための URL | 

などなど、たくさんあるので詳しくは[公式](https://docs.vuestripe.com/vue-stripe/stripe-checkout/getting-started#props)で確認してみてください。



**※前提としてフロントのみの実装で支払いは完結できません。サーバーサイドから stripeに対しAPIを投げる必要があります。（リファレンスの用意されている言語↓）**
<img src'>![スクリーンショット 2022-12-14 20.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705538/b1396984-ca1d-38eb-8d60-99694f9f27c5.png)


と、書いたものの stripeアカウントを作成後ダッシュボードページ（管理画面）から商品を登録しIDと紐付けを行えばフロントのみの決済も行えるそうです！！！！衝撃、、、

実は僕以前にPayPal決済の実装に挑戦したことがありまして、扱いずらさ（リファレンスが古いのもありますが）に白目を向きまくってた記憶があります、、

それに比べstripeはかなりいけてます。リファレンスもとても丁寧で簡単、、、素敵なサービスですねえ　：）

サーバーサイド側の処理も詳しくは見れてませんが、公式のリファレンスをチラッとみるとイメージしやすい部分がたくさんでした。

皆様もぜひ！！！
Goのinternalパッケージを使いこなそう

## はじめに

どうも[ナレッジワーク](https://tenn.in/kw)の[tenntenn](https://tenn.in)です。

Goのinternalパッケージはご存知でしょうか？
本記事では、うまく使うととても便利なinternalパッケージについてご紹介します。

## internalパッケージとは

Goパッケージは、基本的には外部のモジュールに公開されます。
パッケージ内のどの識別子を公開するかは、先頭の文字を大文字にするかどうかで決まりますが、パッケージにはその機能はありません。

しかし、Goにはinternalパッケージ（内部パッケージ）という特別なパッケージがあります。internalパッケージは、モジュール外には公開されません。
また、internalパッケージの親パッケージおよびその子パッケージ以下からしか参照できません。

たとえば、以下のようなパッケージ構成があった場合を考えます。

```
a
├── b
│   ├── d
│   └── internal
│       └── e
├── c
└── go.mod
```

`a/b/internal`パッケージ直下の識別子や`a/b/internal/e`パッケージの識別子は、一部のパッケージからしか参照できません。
パッケージ`b`とパッケージ`d`以下および`internal`パッケージ以下のパッケージからの参照に限定されます。
パッケージ`a`やパッケージ`c`からは参照できません。

もちろん、`internal`パッケージ以下のパッケージで識別子を非公開（小文字で始める）にした場合は、そのパッケージ内だけからしか参照できません。
なお、`internal`パッケージはモジュール以下にいくつでも作れます。

## テストをしやすくする

筆者は、テストコードはテスト対象のパッケージとは別のパッケージにした方が良いと考えています。
つまり、`a`パッケージをテストしたい場合は、テストコードは`a_test`パッケージにする方が良いということです。

テストコードを別パッケージにすることで次のような利点が得られます。

* 単体テストがパッケージの初めてユーザになる
* 使い勝手や使用した場合可読性を図りやすい
* 早めに設計ミスなどに気づける

また、一方で次のような煩わしさが残ります。

* 非公開な機能を使ったテストがしづらい
* わざわざ、別のパッケージにするのがめんどくさい

非公開な機能のテストは、[export_test.go](https://engineering.mercari.com/blog/entry/2018-08-08-080000/)を使ったパターンでほとんどの場合は解決します。
テストで使用する非公開な機能をAllowリスト形式で並べることにもなるため、テストのときだけの特別扱いを避けやすくなります。

しかし、非公開な機能で複雑な処理をしている場合、どうしてもテストがしたくなります。
その場合に有効なのが`internal`パッケージです。

複雑な処理をしている非公開な機能をモジュール内ライブラリのような形で切り出し、`internal`パッケージ以下に配置することで特定のパッケージからしか参照できないように制限できます。
そして、`internal`パッケージ以下では公開された機能としてテストすれば`export_test.go`を使う必要もありません。

## モジュールやパッケージ間を疎結合にする

実はGoチームが管理しているモジュールの多くで`internal`パッケージが利用されています。
公開する必要がない場合は`internal`パッケージ以下に置くようなレベルで管理されているモジュールもあります。

たとえば、Webアプリのようなものであれば、エントリーポイントとなる`main`パッケージを含むパッケージのみ公開し、他のパッケージはモジュール直下にある`internal`パッケージ以下に配置するという方法がとられます。
[pkg.go.dev](https://pkg.go.dev)の[ソースコード](https://cs.opensource.google/go/x/pkgsite)を見てもモジュール直下に`internal`パッケージがあることが分かります。

他のモジュールやパッケージから参照されてほしくないパッケージは`internal`パッケージに置いておくと、後方互換を気にせずに破壊的変更が行える利点があります。
ライブラリでもWebアプリでもこの利点は効いてくるでしょう。

## おわりに

本記事では`internal`パッケージの活用について紹介しました。
Canvas2D ４点グラデーショングリッドの実装実験

この記事は [Web グラフィックス Advent Calendar 2022](https://qiita.com/advent-calendar/2022/webgraphics) の14日目の記事です。

# 自作お絵かきツールで線をはみ出さないでブラシ塗りがしたい

個人的に今年のアドベントカレンダーでは自作ツールでブラシ塗りがしたいということで色々やっていて、[前回](https://qiita.com/warotarock/items/29169ac125c95ee0783f)は４点グラデーションを実装してみました。

今回はそれをグリッド状に並べ、ブラシ塗りをしてみたいと思います。

# 描画処理の概要

色情報を持った点をグリッド状に並べ、点４つごとに４点グラデーションを描画します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/ed83c09d-c6ae-fcb3-9382-19c18b3c8a1a.png)
上の図はグリッドのセルを極端に大きくしています。

セルを小さくしてグリッドの解像度を上げると、ビットマップをバイリニア補間で拡大した感じ（原理的にはそのもの）になっていきます。ジャギーのようなものが見えますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/901577dc-5697-64bc-39e5-97afaff0cde2.png)
そこで本題の、グリッドを変形させていい感じにするのをやりたいところです、が・・・。

明度の勾配をもとにしたシミュレーションのようなことをしたら良さそうなのですが、残念ながら具体的なアイデアが出ないまま１２月になってしまいました。

簡易な方法として、ブラシで描く部分のグリッドを魚眼レンズ風に歪めることでジャギーを軽減できないか試してみました。魚眼レンズはブラシ塗りとは全く関係ないものですが、ひとまず円形にグリッドを変形させることができますから、もしかしたら何かしら良い効果があるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/f8f0d31c-94ff-514e-7632-1267ad9f26e2.png)


# 実装したもの

<p class="codepen" data-height="850" data-default-tab="result" data-slug-hash="RwJzEGe" data-user="warotarock" style="height: 850px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/warotarock/pen/RwJzEGe">
  Canvas2D ４点グラデーショングリッドの実装実験</a> by 柏崎ワロタロ (<a href="https://codepen.io/warotarock">@warotarock</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/d67d73dd-70c5-262a-be66-7dd39af01ffd.png)
うにょうにょと塗ることができます。楽しいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/ecf5e2fa-b3af-ee99-b4ef-939e3ee5689c.png)
このサイバー空間みたいな感じがたまらん（馬鹿）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/da223a18-2549-7798-5e06-26a3f70f4288.png)
半径を大きくすれば簡易なグラデーションツールにくらいはなるかも・・・いやいらんか・・・。

# 考察

魚眼レンズ風に歪めることがどれだけ効果があるかについて考えます。

放射型グラデーションのままではわかりづらかったので、三角関数で波を出せるようにしました。これで見ると、魚眼レンズの縁の部分は他の部分よりジャギーが低減しているように見えます。表現したい絵に合うようになんらかの方法でグリッドを変形させられれば、それなりに効果があるのではないかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59191/b7877255-c2f0-0668-1861-4bf88f5b1387.png)

# まとめ

- ４点グラデーションをグリッド状に並べてブラシ塗りを実装してみた。
- 魚眼レンズでグリッドを歪める実験の結果から、うまくグリッドを変形できれば効果がありそうに感じた
- 個人的には背景とかのグラデーションに使えそう。
- 楽しかった。

なんとまだ続きます。次回、マスクを使ったアプローチ。今度こそ実用になるかも！？
勉強会で「LT会」というと参入敷居を感じさせるので「ポエム会」って呼ぼうぜ

xxx会って書くとゼット会みたいだなぁ、と思ったのは私だけかもしれません。
世代を測るモノサシにしてみてください。

## 昔の勉強会の姿
当時は意識高い系という言葉はなかったんですが、概念は世紀を超えて存在していただろうなので、ここでは取り上げません。
大学だとガチ系サークルに多いです。残念ながら私のサークル時代はコミケサークルだったので、勉強会というより研修会？今だともくもく会でした。
とにかく部誌（作品）を書かない事には始まらなかったため、教えるというよりは「やれ」で押し通していた（実際、それしかない）
色々な「勉強」の形がありますが、学ぼうという姿勢は形や熱量は違うものの、ベクトル？としては同じはずです。

## LTも参入敷居を下げるために使われていた側面があった
ソースを示せないのでつらいですが、LTが普及していった話に触れないわけには行かないのでおぢさんの体験談だけ垂れ流します。

勉強会も登壇スピーカーがガッツリ40分とか短くて15分も話す事が多かった（＝それしかなかった）時代があったんですが、大体はメインスピーカーが一人で登壇して、発表資料も今のような説明とか解説ではなく講義スタイルを取っている事が主流だったんですね。
今もメイン登壇者は内容や方針こそ違えど、時間枠は同じぐらいで設定される事が多いです（自己申告のパターンもありますし、主催側から尺の相談を受ける事もあります）
実務としての講義だと50～70分1コマが連続的に続きますので、話す時間としてはこれでもまだ短いかな？
今回はややこしくなるのでハンズオン系は考慮しません。

これらを一括りに「登壇」あるいは「スピーカー」枠としていたので、主催者がオファーをせず、有志で登壇＝LT枠を作ることで主催側にも参加者側にもある種のパラダイムシフトが生じたのは確かです。
どちらにしても、初期の頃は登壇すると発表内容に興味があるユーザーが集まって意見交換がされていたため、ネットワーキングはしやすかったと思います。

### それでもまだまだ勉強会参加（登壇）への敷居が高い
今はオンラインが主流になりましたし、参加費も無料なので思いついたらふらっと新規参加ができましたが、当時はコミュニティ間の結びつきも弱かったんですね。
それもそのはず、情報発信もTwitterが普及するまではmixiのボイス（でしたっけ？正式名称が思い出せないです）でフォロワー（友達の友達まで）しか見ることが出来なかったので、人間関係が主催に近い位置にいなければ存在を知ることもできませんでした。
Twitterが普及すると爆発的に勉強会の情報が発信され、これらをまとめるべく？勉強会の情報を集約するために様々な方法が模索されました。
googleカレンダーが多かった気がします
これでようやく、connpassやdots、doorkeeperといったエンジニアイベントを集めたり主催するサイトが生まれる土壌が出来上がっていきました（と私は思っています）

## はじめてLTに参加してみると気付くもの・変わるもの
意図とは外れますが、未参加の方に、LTに参加をするとこんなに変わるよ（変わらないよ）というお話をしておきます。

### 終わってみると呆気ない
初めての5分間は準備してきた割に大した事ないんですよね。
特に初めての登壇なので、気合を入れて臨むはずです。

が、やった結果というか、感想が↑の方も多いと思います。
多いよね？
最初に考える5分と、慣れてきた5分は感じ方が変わってくる事に気付きます

なお、慣れてくるとスライドとか何もナシに喋りはじめます。
むしろ、スライドなどプレゼンツールは所詮プレゼンツールでしかない事に気付きます。

本当の始まりは、プレゼンツールのないプレゼンなのかもしれません。

### 目に見える変化はないが、次の参加への抵抗感が和らぐ
LTの経験を積んだからと言って、何かが変わるか？というと目に見える変化はないです。
ただし、2回目のLT会への参加障壁がかなり低くなっている事に気付きます。

受験戦争を頑張って勝ち抜いて入学式を迎えたからといって、変わった事はないですよね？というぐらいないです。
入学した後に大学生のイメージが少し変わったぐらいでしょうか。

### 他の人がどうやって登壇しているか気になる
これはLTに限った話ではありませんが、一度やったら他の人がどうやっているのか気になりはじめます。
既に次の対策を考え始める事でしょう。

ただし、次回参加するまでに時間が経ち過ぎると初参加と同じ状態になるので、初参加前から次回を見据えておくか、既に定期的に参加している勉強会コミュニティがあればそちらで初LTに臨むのもアリです。

## LT < ポエム
そもそも指標がおかしいんですが、ここではLTに参加するよりQiitaなどにポエムを投稿する方が参入障壁は低いよね？というポイントに言及していきます。
勉強会も今はオンラインで参加できるので、時間的制約と伝える方法以外はポエムを投稿するのと同じ状態ではないでしょうか。
伝える方法が書き物か口かの違いです。

痴呆を認知症、援助交際をパパ活と言い換えただけでしかないんですが、LT会をポエム会と呼び替えて効果を測定してみたいですね。
あ、これいいポエム駆動になりそうですね。計測する方法とかは各コミュニティでやり方が異なると思いますが、シンプルにやるならA-Bテストでしょうか。
LTやる時にいつものメンバーは除外して、新規が何人登壇してくれるか、でしょうか。

あっと、今更ですがデータとかない（これから作る）ので、今日の時点では共感してくれただけで私は嬉しいです。

## 次の記事
- [(19日目) 一本のトピックにまとめられなかった小ネタ集](https://qiita.com/nomurasan/items/8c30d70ccb127ba15c2a)
- [カレンダーページ](https://qiita.com/advent-calendar/2022/oreno_nomurasan2022)
【artisan】shell_exec実行時のユーザーCPU時間【Laravel】timeコマンドのuser



shell_execでも同様の結果となる

```bash
composer create-project laravel/laravel example-app
cd example-app

./artisan make:command shell_exec
./artisan command:name

wget https://gist.githubusercontent.com/hellowork-mhlw/03344d342fffa767e6a6ffd7b89a93ed/raw/cnt.c
gcc cnt.c

# 下記からコードをコピペ
# https://qiita.com/foluyucic/items/158f1759a372fed6a1ff

$ time ./artisan command:name sleep 3

real    0m3.114s
user    0m0.086s
sys     0m0.030s

$ time ./artisan command:name ./a.out
500000000500000000

real    0m1.044s
user    0m1.008s
sys     0m0.035s

$ time ./a.out
500000000500000000
real    0m0.914s
user    0m0.912s
sys     0m0.001s
```

# 参考

https://qiita.com/tossh/items/659e5934e52b38183200#22-clang
CloudFrontってなに？

コンテンツ配信をグローバルロケーションを使って効率的に実施するコンテンツデリバリーネットワーク(CDN)サービス

## 特徴

### グローバルエッジネットワーク

- 高い信頼性、低レイテンシー、高スループットのネットワーク接続
- 210以上のエッジロケーションによる高性能な分散配信

### セキュリティ

- AWS WAF/ AWS Certificate Managerとの連携やDDos対策によるセキュリティ機能
- アプリケーションを HTTPS 経由で配信し、ビューアクライアントと CloudFront 間の通信を暗号化し保護できる
- さまざまな機能を使用してコンテンツへのアクセス制限ができる

### 可用性

- Origin Shieldによって、オリジンリクエストの量を自動的に削減できる

### 継続的デプロイ

- ドメインネームシステム(DNS)を変更せずにリリースを段階的に展開する機能を使用し、継続的インテグレーション(CD/CI)パイプラインに簡単に統合できる。

## キャッシュの保持期間の種類

TTLなどを利用してキャッシュに保持する期間を制御できる。
|種類|概要|
|---|---|
|TTL|・CloudFrontで設定されるキッシュ保存期間|
|Expiresヘッダー|・Cache-Control ヘッダーのExpiresヘッダー<br>・キャッシュの期限切れ日を設定することができる|
|Cache-Control<br>max-age|・CloudFrontがオリジンサーバーからオブジェクトを再度取得するまでにオブジェクトをキャッシュに保存する期間を指定できる。|

## コスト

料金は従量課金制で、使う地域によって値段が変わる。
- 送信データ転送 : Amzon CloudFrontエッジロケーションから転送されたデータ量
- HTTP/HTTPS リクエスト : リクエストの数とタイプ(HTTP/HTTPS)リクエスト
- 無効化リクエスト : 毎月、無効化をリクエストした最初の1,000パスまでは追加料金はなし。それ以降は無効化をリクエストしたパスごとに0.005USDが発生する


インターネットへのリージョン内データ転送アウト（1部載せときます）
|/月|米国|日本|インド|
|---|---|---|---|
|10TBまで|0.085USD|0.114USD|0.109USD|
|次の40TB|0.080USD|0.089USD|0.085USD|
|次の100TB|0.060USD|0.086USD|0.082USD|

オリジンへのリージョン内データ転送アウト
||米国|日本|インド|
|---|---|---|---|
|すべての<br>データ転送|0.020USD|0.060USD|0.160USD|

HTTPメソッドのリクエスト料金
||米国|日本|インド|
|---|---|---|---|
|HTTPリクエスト|0.0075USD|0.0090USD|0.0090USD|
|HTTPSリクエスト|0.0100USD|0.0120USD|0.0120USD|

https://aws.amazon.com/jp/cloudfront/?nc=sn&loc=0

## おわりに
自分用の備忘録としてまとめました。
間違っている箇所がありましたらご指摘よろしくお願い致します。
【9日目】Node.jsで為替レートをDiscordにリアルタイムで投稿する

# はじめに
こんにちは、なりかくんです。
今回は、Node.jsで為替レートをリアルタイムに取得してDiscordにリアルタイムで投稿するプログラムを作ってみようと思います。

# 今回使う為替レートの取得方法

今回は、以下のAPIを利用します。
https://svr242api.nakn.jp/rate.json

このAPIはAPI Keyなどが不要で、非常にシンプルなレスポンスなので非常に使いやすいのが特徴です。以下が記事執筆時のレスポンスJsonの例です。
```json
{
  "status": true,
  "datetime": "2024-05-01 12:54:10+0",
  "rate": {
    "GBPNZD": 2.1169,
    "CADJPY": 114.62,
    "GBPAUD": 1.9254,
    "AUDJPY": 102.32,
    "AUDNZD": 1.0991,
    "EURCAD": 1.47,
    "EURUSD": 1.0683,
    "NZDJPY": 93.01,
    "USDCAD": 1.376,
    "EURGBP": 0.8552,
    "GBPUSD": 1.2488,
    "ZARJPY": 8.396,
    "EURCHF": 0.9821,
    "CHFJPY": 171.64,
    "AUDUSD": 0.6484,
    "USDCHF": 0.9193,
    "EURJPY": 168.58,
    "GBPCHF": 1.148,
    "EURNZD": 1.811,
    "NZDUSD": 0.5894,
    "USDJPY": 157.77,
    "EURAUD": 1.647,
    "AUDCHF": 0.596,
    "GBPJPY": 197.06
  }
}
```

# Discordへの投稿
Discordへは、WebHookを使ってメッセージを送信しようと思います。
今回作ったコードはこんな感じです。
```js:exrate.js
const request = require("request");

exrate();
setInterval(exrate, 15000);

async function exrate () {
    let getExRate = await getRequest({ url: "https://svr242api.nakn.jp/rate.json", json: true });
    if (!getExRate.status) return;
    let time = new Date(getExRate.datetime).getTime()/1000;
    await getRequest({
        url: "WebHookのURL",
        method: "POST",
        json: {
            content: `USD to JPY : ${getExRate.rate.USDJPY} (<t:${time}> <t:${time}:R>)`
        }
    });
}

function getRequest(option) {
    return new Promise((resolve, reject) => {
        request(option, function (error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body);
            }
        });
    });
}
```

非常にシンプルで、requestモジュールを利用してGETやPOSTしているのとsetIntervalを使って定期的に取得をしているだけです。

このコードを動かしてみるとこのようになります。
15秒ごとにしっかりと投稿されていることが分かります。また、何秒前かわかるようにDiscordのマークダウンの機能を使って分かりやすくしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/74ad4dbb-8086-044b-cdbd-45addf1151e5.png)

以上です、今回はUSD to JPYで作りましたがほかの為替レートバージョンも簡単に作れるので是非皆さんも作ってみてください。
最後までお読みいただきありがとうございました。
artisan commandで可変長引数【Laravel】Rest variable length arguments

`$signature = 'command:name {your_command?*}'` のように`?*`を追加するだけ カンタン

```php:app/Console/Commands/shell_exec.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class shell_exec extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name {your_command?*}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $command = join(' ', $this->argument('your_command'));
        if ($command) {
            $output = shell_exec($command);
            if ($output) $this->line($output);
        }
        return 0;
    }
}

```
【Swift】サードパーティ製キーボードの使用を検知する

# はじめに
アプリ内で機密な情報を扱う際にサードパーティ製キーボードを使われたくありません。
現在使用されているキーボードがサードパーティ製か判定できるようにしてみました。

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 - 2022-12-14 at 20 01 01](https://user-images.githubusercontent.com/84154073/207577968-e06500d8-36aa-47d1-961b-0292957c3f26.gif)

# 実装
### View
```swift
import SwiftUI

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    var body: some View {
        VStack {
            Text(viewModel.keyboard ? "サードパーティ製キーボードを使用中です" : "標準キーボードです")
            TextField("テキストフィールド", text: $viewModel.text)
                .textFieldStyle(.roundedBorder)
        }
        .padding()
    }
}
```

### ViewModel
```swift
import Combine
import UIKit

final class ViewModel: ObservableObject {
    @Published var text: String = ""

    @Published var keyboard: Bool = false

    private let notificationCenter = NotificationCenter.default

    private var cancellable = Set<AnyCancellable>()

    init() {
        notificationCenter.publisher(for: UIResponder.keyboardWillShowNotification)
            .sink { [weak self] _ in
                guard let self else { return }
                self.keyboard = self.isSystemKeyboard()
            }
            .store(in: &cancellable)
    }

    private func isSystemKeyboard() -> Bool {
        let modes = UITextInputMode.activeInputModes
        let displayedModes = modes.filter { $0.value(forKey: "isDisplayed") as? Int == 1 }
        guard let className = displayedModes.first?.superclass?.description() else { return false }
        return className == "UIKeyboardInputMode"
    }
}
```

:::note info
`UITextInputMode`や`UIKeyboardInputMode`で判定したかったのですがプライベートクラス？で使えなかったので文字列に変換して判定しています。
:::



# おわり
https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/UIKitCore.framework/UIKeyboardInputMode.h
Web事業会社のインフラエンジニアってどんな仕事をするの？

## 本記事を投稿した背景

私が新卒でWeb事業会社にエンジニアとして内定を頂き、インフラ関連の部署に配属が決まったとき、
「事業会社のインフラエンジニアってどんな仕事をするんだろう？」と疑問を抱いていました。

これからインフラエンジニアとして働く学生や未経験エンジニアの方々の参考になれば幸いです。

## ざっくりとしたお仕事内容

- アプリケーションやデータベース等の**動作環境の構築**・運用保守
- プロダクト運用にあたって、**パフォーマンス**や**コスト**を最適化
- セキュリティ周りのボトルネックを解消
- アプリケーションの監視・障害対応

## 具体的な仕事例

- アプリのパフォーマンス監視
    - AWS上で構築したコンテナやサーバのパフォーマンス, APIに対するリクエストなどを監視
    - 異変が発生した時のためのアラート設定も行う
- 定期バッチの設定
    - メール送信などアプリケーション内で自動的に行われる動作を設定する
- 検証や本番など、開発チームの用途に合わせた環境構築
    - 近年では**Terraform**でのAWSリソース構築や、**Ansible**によるサーバの状態変更など、コードによるインフラ管理を行うことが多い
- セキュリティ・コスト面の最適化
    - AWS Trusted Adviser等に基づくベストプラクティスの設定反映
    - インスタンスタイプの変更やWAFの設定など・・
- 上記作業を含め、運用作業の効率化を図る
    - シェルスクリプトなどを使って手作業を自動化するなど

## どんなことを勉強したらいいの？

**AWS/GCP等のクラウド関連の知識**
近年はクラウドサービスを使っている企業が多いので、軽く勉強しておくといいでしょう

AWSの勉強には**Black Belt Seminar**がおすすめです。

https://aws.amazon.com/jp/events/aws-event-resource/archive/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc&awsf.tech-category=*all

**OS, サーバなどのコンピュータの知識**
インフラエンジニアとして働くと最初はわからない言葉がたくさん飛び交います。
コンピュータ関連の基礎知識を事前に勉強しておくと、業務のキャッチアップがしやすくなるでしょう。

コンピュータに関する基礎知識を網羅的に学習するには、**基本情報技術者試験**の勉強がおすすめです。

**Linuxコマンド・シェルスクリプトの知識**
ターミナル上でコマンドを打つ作業が多いので、Linuxコマンドの知識は必須です。
また、シェルスクリプトが使えると作業の効率化などで便利なので、覚えておくと嬉しいでしょう。

おすすめ勉強方法はHacker Rankなどでシェルスクリプトのコーディング問題を解くことです。

https://www.hackerrank.com/domains/shell
VUEでcomponentでボタンを作る

# VUEでcomponentでボタンを作る

## やりたいこと
はじめてのVUEでのアプリ開発、1ページ1componentで作っていたがさすがに1ページ分のコードが肥大化してきた。
リファクタリングの一環としてcomponentを利用したパーツづくりを行いたいがどのようにファイル分割すればよいかわからない。
まずはボタンを1つ、外部のcomponentとして使えるようにしたい。

## リファクタリング前のコード　
```mainpage.vue
<script lang="ts">
</script>

<template>
 <body>
  <a "href="https://nextpage.com">次のページへ</a>
 </body>
</template>
```


## コード分割後のコード
```button.vue
<script lang="ts">
 export default{
     props:{
         buttonText:String
     }   
 }
</script>

<template>
    <a>{{buttonText}}</a>
</template>

<style>
 必要であればボタンに適用するスタイル
</style>
```

```mainpage.vue
<script lang="ts">
　import partsButton from './button.vue'

　export default {
  　components: {
   　 partsButton
 　 }
}
</script>

<template>
  <partsButton "href="https://nextpage.com" buttonText="次のページへ"></partsButton>
</template>
```

## まとめ
ひとまずボタンをパーツ化するところまで完了。
コード量としてはむしろ増えてしまった気もするが、今後ほぼすべてのページでボタンを使うことを見越してパーツ化してみた。
グローバルにcomponentを定義することで各ページではimport不要で使えるので次はそちらを試したい。
WinActorで独自のエラーをスローした

※この記事はWinActor7.4.1.1を使って書いています。

# はじめに
WinActorの販売店でシナリオ作成を担当しているEMIです！
独自のエラーを、私はこんなときに作っていますよ～という記事になります。

RPA（ロボティック・プロセス・オートメーション） Advent Calendar 2022
に参加しています！
でしゃばって2回目の投稿です:hugging:
https://qiita.com/advent-calendar/2022/robotic_process_automation

# こんなときどうする？

独自エラーをスローしたいときってどんなときでしょうか。
例えばログインの処理を見てみましょう。
ブラウザ操作で、サイトへのログイン時にパスワードの期限が切れていたりしてログインに失敗することがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/3f982b86-e20f-6baf-02d6-a11a57de9960.png)

次画面に遷移しない場合を考慮していないシナリオでは、ログイン後の画面での操作の箇所で、WinActorからエラーが発生します。
「指定された要素が見つかりませんでした。Xpathの詳細。。。」というメッセージになります。

このメッセージだと、シナリオ作成者であればエラーの原因は分かりますが、
ユーザーは何が原因でエラーが発生しているのか、エラーメッセージを読んでも分かりません:disappointed_relieved:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/6d8c9eba-c094-2fdf-c93c-534fd554ffba.png)


# こんなときこそ
そこで、ログインエラーで次画面にいけなかったときは独自のエラーをスローすることにしました。
WinActorで独自エラーをスローするには「エラー」ライブラリを使います。
このライブラリにはエラーメッセージを設定することができ、例外処理の正常系内に配置します。

このライブラリを実行すると、WinActorからエラーが発生したときと同じく異常系にスローされます:baseball:
「スロー」はプログラムっぽい言い方ですが、『投げる』という意味です。

エラーのボール:baseball:が異常系に投げられる！！という絵が私の頭の中ではいつも浮かんでいて、分かりやすい表現で私は大好きです:relaxed:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/ba43395e-6a10-7ded-189c-e79678af10c6.png)


エラーメッセージは
「エラー002：ログインに失敗しました。パスワードの期限が切れていませんか？」にしました。
ユーザーは
「ほうほう、サイトのパスワード変えてまた実行すればいいのか！」と分かりやすいです:relaxed:

ログイン後に次の画面にて表示されるはずの要素の数をブラウザから数え、要素数が0の場合はこのエラーがスローされるという作りにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/36c1a4a5-5619-1d4e-a1b9-b99a24dfbdf5.png)

こんな風にメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/7dac94c2-521b-0f5b-c6b1-d548b735fd57.png)

# シナリオすっきり
独自エラーにはメッセージが分かりやすい以外にも、利点があります。
まずはエラーライブラリを使わなくても、都度エラー処理を書くやり方を見てみましょう。
例えばログインエラーの場合は↓こんな感じ。
これでも良いですが、エラーライブラリを使うと、処理が必ず異常系にスローされるので、
エラー時のメッセージ表示が１箇所で済み、シナリオがすっきりし、可読性がアップします:relaxed:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/be008668-561d-e784-7120-4688fdfd2d2a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636184/c71aaa9c-3828-dd16-197c-4753ded6dc9d.png)


# まとめ
エラーライブラリを使って、WinActorで独自のエラーをスローする話でした！
WinActorでのエラーの実装、色々なやり方があると思います。
皆さんのエラーもどう作っているのか知りたいです！

読んでいただきありがとうございました！
[Java Script] ボタンをクリックするとdivを追加・削除する


# Code
```html
<div id="row-box">
    <div class="d-flex">
        <div class="form-group">
            <label>method</label>
            <input type="text" class="form-control" name="title" autocomplete="off" />
        </div>
        <div class="form-group">
            <label>condition</label>
            <input type="text" class="form-control" name="title" autocomplete="off" />
        </div>
        <div class="form-group">
            <label>value</label>
            <input type="text" class="form-control" name="title" autocomplete="off" />
        </div>
    </div>
</div>

```
```javascript

var count = 0

$('#add-row').click(() => {
    count = count + 1
    $('#row-box').append(`
                    <div class="d-flex index-${count}">
                        <div class="form-group ">
                            <label>method</label>
                            <input type="text" class="form-control" name="title" autocomplete="off" />
                        </div>
                        <div class="form-group">
                            <label>condition</label>
                            <input type="text" class="form-control" name="title" autocomplete="off" />
                        </div>
                        <div class="form-group">
                            <label>value</label>
                            <input type="text" class="form-control" name="title" autocomplete="off" />
                        </div>
                    </div>`)
})

$('#remove-row').click(() => {
    $(`.index-${count}`).remove()
    count -= 1
})


```

# Screen
<img width="500" alt="2022-12-14 19;22;20.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/cbd5ab3b-0995-5d2f-ad09-7e0136649310.gif">



最初のRowは残したい
`div`ごとの`name`, `id`を変えることができるように、countで追加したdivを区別した
SPSS Modeler のログ設定 (Undocumented)

# はじめに
SPSS Modeler (以降、Modeler) のログ出力は、Log4j の機能を使って実装されています。
そのため、Modeler のマニュアルに記載されていない方法でログを書くことが可能です。
ここでは、Log4jの観点で実現可能な方法をご紹介します。

# 日付によるローテーション
マニュアルにも記載がありますが、Modelerの設定ファイルである、log4cxx.propertiesの以下の記述を使用すると、日付によるローテーションが可能です。

```# Use the next two lines instead to roll over the log at the start of each day
log4j.appender.MainLog.Append=True
log4j.appender.MainLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.MainLog.DatePattern='.'yyyy-MM-dd
```
## Undocumented
マニュアルでは、`'.'yyyy-MM-dd`の記載しかありませんが、以下のパターンでも利用可能です。
'.'yyyy-MM : 月が変わったタイミングでローテート
'.'yyyy-ww :  週が変わったタイミング（日曜日）でローテート
'.'yyyy-MM-dd : 日が変わったタイミングでローテート
'.'yyyy-MM-dd-HH : 時が変わったタイミングでローテート
'.'yyyy-MM-dd-HH-mm : 分が変わったタイミングでローテート

# ファイルサイズによるローテーション
ファイルサイズによるローテーションの場合、マニュアルには以下の記述があります。
```
log4j.appender.MainLog=org.apache.log4j.RollingFileAppender
log4j.appender.MainLog.MaxFileSize=8MB
```
## Undocumented
Modelerのマニュアルにない世代管理を行う設定があり、以下の記述を追記できます。
```
log4j.appender.MainLog.MaxBackupIndex=12
```
この例では、ログファイルを12世代保管することになります。
この設定がない場合、デフォルトは、次のようになります。
```
log4j.appender.MainLog.MaxBackupIndex=1
```
つまり１世代のログファイルのみ保管することができます。

# おわりに
この記事の作成にあたり、以下の資料を参考にしました。
[Class DailyRollingFileAppender](https://logging.apache.org/log4j/1.x/apidocs/org/apache/log4j/DailyRollingFileAppender.html "タイトル")
なお、Modelerの製品マニュアルに記載がない以上、非公式である旨ご了承ください。
みんなで備える互助アプリ「なかまのなかま」

認知症フレンドリーテックハッカソンのチームで開発中のアプリです。
認知症になってからではなく少しでも早く地域とのつながりをつくれるようにしたい。
「生きがい・役割づくり」と「備え」に着目して『地域との出会い直し』と『互助の関係』を支える情報の提供と発信を行います。
詳しくは[こちら](https://protopedia.net/prototype/3380)からどうぞ。
[https://protopedia.net/prototype/3380](https://protopedia.net/prototype/3380)
MQTT で受信したデータをファイルに書き出す

## プログラム

```py:subscribe_log.py
#! /usr/bin/python
#
#	subscribe_log.py
#
#						Dec/14/2022
#
# ------------------------------------------------------------------
import sys
import json
from time import sleep
import paho.mqtt.client as mqtt
import time

# ------------------------------------------------------------------
def log_write_proc(json_str):
#	print(json_str)
	unit_aa = json.loads(json_str)
#
	print(unit_aa)
#
	fp_out = open(file_log,mode='a', encoding='utf-8')
	fp_out.write(json_str + "\n")
	fp_out.close()
# ------------------------------------------------------------------
def on_connect(client, userdata, flags, respons_code):
#	print('status {0}'.format(respons_code))
	client.subscribe(topic)

# ------------------------------------------------------------------
def on_message(client, userdata, msg):
#	print(msg.topic + ' ' + str(msg.payload,'utf-8'))
	log_write_proc(str(msg.payload,'utf-8'))

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

#host = '35.75.37.18'
# topic = 'esp32/test'
host = sys.argv[1]
topic = sys.argv[2]
port = 1883

file_log = "/tmp/" + topic + ".log"
sys.stderr.write(host + "\n")
sys.stderr.write(topic + "\n")
sys.stderr.write(file_log + "\n")
#

client = mqtt.Client(protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_message = on_message

client.connect(host, port=port, keepalive=60)

client.loop_forever()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

使い方

broker: example.com
topic: example/test
とすると、

```bash
./subscribe_log.py example.com example/test
```

実行前に、/tmp/example を作成して下さい。
次のファイルが作成されます。

/tmp/example/test.log

## Systemd で動かす

プログラムを、
/usr/local/subscribe
に置いて下さい。

```text:/etc/systemd/system/subscribe_temperature_log.service
[Unit]
Description = start up mqtt_client subscribe_temperature_log

[Service]
WorkingDirectory=/var/tmp/subscribe_log
ExecStart=/usr/local/subscribe/subscribe_log.py example.com example/test
Type=simple

[Install]
WantedBy=default.target
```

作業用の Directory を作成

```bash
mkdir /var/tmp/subscribe_log
```

起動

```bash
sudo systemctl start subscribe_temperature_log
```

起動したことを確認

```bash
sudo systemctl status subscribe_temperature_log
```