OmniAICreator/Qiita-1.07M huggingface dataset:
UE4のVisual DataprepをPythonから実行してみる

UE4.27.2でpythonスクリプトでDataprepAssetを実行してみました。

本当はDataprepAssetInstanceで親DataprepAssetで公開されたパラメータ※を指定して実行したかったのですがまだサポートされてないそうなので直接DataprepAssetを使用しています。
※  Dataprep Editor の右上にある[Settings] パネルの [Parameterization] セクションで表示されるもの

DataprepAssetのパラメータ指定では直接各アクションのノードを指定してパラメータを指定しています。
値を指定したパラメータがリンクして公開されているとリンクされているノードのパラメータ全てに適用されるようです。


```python:pythonスクリプト
# -*- coding: utf-8 -*-
import unreal

def get_step(dataprep_asset, action_index, step_index):
  action = unreal.EditorDataprepAssetLibrary.get_action(dataprep_asset, action_index)
  step = unreal.EditorDataprepAssetLibrary.get_step_object(action, step_index)
  return step

# マップ読み込み
unreal.EditorLoadingAndSavingUtils.load_map("default")

# DataprepAsset取得
asset_data = unreal.EditorAssetLibrary.find_asset_data("/Game/Dataprep/DataprepAsset")
asset = asset_data.get_asset()
dataprep_asset = unreal.DataprepAsset.cast(asset)
print(dataprep_asset)

# Producerクリア
count = unreal.EditorDataprepAssetLibrary.get_producers_count(dataprep_asset)
for i in range(0, count):
  unreal.EditorDataprepAssetLibrary.remove_producer(dataprep_asset, i)

# Producer追加、Input設定
producer = unreal.EditorDataprepAssetLibrary.add_producer_automated(dataprep_asset, unreal.DatasmithFileProducer)
file_producer = unreal.DatasmithFileProducer.cast(producer)
file_producer.set_editor_property("file_path", "c:\\model.udatasmith")

# Consumer設定
consumer = unreal.EditorDataprepAssetLibrary.get_consumer(dataprep_asset)
print(consumer.get_level_name())
print(consumer.get_target_content_folder())
consumer.set_level_name_automated("dataprepmap")
consumer.set_target_content_folder_automated("/Game/Dataprep")

# パラメータ設定
step = get_step(dataprep_asset, 0, 0)
step.set_editor_property("max", unreal.Vector(1,2,3))

step = get_step(dataprep_asset, 7, 0)
step.set_editor_property("user_string", "test")

step = get_step(dataprep_asset, 7, 1)
step.set_editor_property("min", unreal.Vector(3,4,5))

# 実行
result = unreal.EditorDataprepAssetLibrary.execute_dataprep(dataprep_asset, unreal.DataprepReportMethod.STANDARD_LOG,  unreal.DataprepReportMethod.STANDARD_LOG)
print(result)

unreal.EditorLoadingAndSavingUtils.save_dirty_packages(True, True)
```

[ue4cli](https://github.com/adamrehn/ue4cli)を使うと以下のようにコマンドラインでスクリプトの実行、ライティングビルドができました。

```batch
ue4 run dataprep.uproject -ExecutePythonScript="i:\dataprep.py"
ue4 run -Run=ResavePackages -Map=/Game/default -IgnoreChangeList -BuildLighting -Quality=Preview -MapsOnly -ProjectOnly -AllowCommandletRendering
```
【 デプロイ前後での表示の違い 】

## デプロイ後に表示させたくないボタンが表示される

ローカル環境では表示されなかった「購入ボタン」が、何故かデプロイ後には表示されてしまう。

## なぜ？
デプロイ前と、デプロイ後の表示に齟齬があるということはしっかりpushが行われていない(反映されていない)？と考えたことから再度`git push heroku main`を行う。

```
% git push heroku main
```
## 結果①(失敗)

どうやら問題は他にある様です。
調べても相当する記事が見当たらなかったので、「誰も犯さない様な単純なミスでは？」と視野を広げてみる。

##再仮説

GitHuDesktopを確認すると、mainブランチで何か変更している（commitもしていない状態）
そこで一度変更内容をもとに戻し、再度newブランチを作ってcommit→pushし、リモートに反映させてからマージしました。
その後、再度`git push heroku main`を行います。

```
% git push heroku main
```

## 結果②(成功)
無事意図した表示を確認することができました。

##反省

　一度デプロイした後に、mainブランチのまま変更を行い、さらにリモートに反映してなかった事が原因でした。
何か変更、作業を行う時はgithubの存在を忘れない様にしようと思います！
ApacheのルートディレクトリでBasic認証を行う際につまづいたポイント

# 目標
ApacheのルートディレクトリでBasic認証を行う

# つまづいたポイント
httpd.confの`<Directory "/var/www/html"></Directory>`に下記記述を追加しても、Basic認証が行われなかった。

```:/etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
AuthType Basic
AuthName "test user"
AuthUserfile /etc/httpd/htpasswd
Require valid-user
</Directory>
```

# 解決方法
Apacheインストール後初めからhttpd.confの`<Directory "/var/www/html"></Directory>`内に、`Require all granted`が記述されていました。
`Require all granted`だと全アクセス許可となるので、Basic認証を行わずWEBページが表示されてしまいます。

`Require all granted`を`Require valid-user`に変更する事で、Basic認証を通ったユーザーのみアクセス許可となり解決しました。

# 1.Basic認証
1.ユーザ作成
`-c`をつける事で新規パスワードファイルを作成します。

```
htpasswd -c /etc/httpd/htpasswd test1
```

2.`vi /etc/httpd/conf/httpd.conf`で設定ファイルに下記記述を追加する。

```:/etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
# Basic認証を指定
AuthType Basic
# 認証領域を指定
AuthName "test user"
# パスワードファイルを指定
AuthUserfile /etc/httpd/htpasswd
</Directory>
```

この時点では`Require all granted`となっている為、Basic認証が行われません。

3.`vi /etc/httpd/conf/httpd.conf`で設定ファイルの下記記述を変更する。

```
<Directory "/var/www/html">

Require all granted
↓
Require valid-user

</Directory>
```

4.Apache再起動

```
systemctl restart httpd
```

5.サイトを表示し、Basic認証が行われる事を確認する。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088692/b8f51562-ad9e-956d-7410-817007ef60f7.png)

# 2.Basic認証をログアウトする方法
一度Basic認証でログインすると、その後はキャッシュによりBasic認証を要求されません。
検証のため、再度Basic認証を確認したい場合は下記記事を参照して下さい。

https://dev.classmethod.jp/articles/delete-cache-for-basic-authentication/
herokuの本番環境でテーブルをマイグレーションしていないことによって発生するエラー

railsで作成したアプリをherokuで実行した際、こんなエラーが出た

we're sorry, but something went wrong.
![スクリーンショット (414).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1952299/cff17944-1b11-e68f-f22a-75c24ec1c3d0.png)
翻訳すると"申し訳ございません。不具合が発生しました。
アプリケーションの所有者である場合は、ログで詳細を確認してください。"ということである。

言われた通りにログを確認してみる。

```
$heroku logs
```
ログを見ていくとエラーのログが見つかった

```
ActionView::Template::Error (PG::UndefinedTable: ERROR:  relation "users" does not exist
```
ようするに"userテーブルがみつからない"ということらしい。

調べてみたら、ローカル環境とはまた別に本番環境にテーブルをマイグレーションする必要があるとのこと。
というわけでheroku用にマイグレーションを行う。

```
$heroku run rails db:migrate
```
上記のように、herokuでコマンドを実行するには文頭にheroku runをつけること。

マイグレーションが完了したら実際に動作するか確認してみる。

![スクリーンショット (415).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1952299/71930248-4c9c-f7d0-d964-fee77851254d.png)
ページが表示された！

###結論###
本番環境ではローカル環境とは別にテーブルを作成する必要があること、エラーログを読み調べることが大切である。
BigQueryでクエリ結果をJSONで取得する

# やりたいこと
- BigQueryにて、クエリ結果をJSONで取得する

# やりかた
```sql
SELECT TO_JSON_STRING(t) FROM (SELECT hoge, fufa FROM sample_table) AS t
```

例

```sql
SELECT TO_JSON_STRING(t) AS j
FROM (
    SELECT 
        "hoge" AS foo,
        "fuga" AS bar
    UNION ALL 
    SELECT
        "piyo" AS foo,
        "nya" AS bar
) AS t
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320845/897267c5-8400-0d18-b51e-436fb8505bfe.png)
モダンJavaScriptを学ぶ上で最低限知っておきたい機能

ES2015で追加された記法など、備忘録的にまとめています。
JavaScriptを触ったことが無いぴよぴよエンジニアのメモなので、知識の正確性はだいぶアヤシイです。

# 用語・機能
**テンプレート文字列**
文字列と変数を楽に組み合わせて表現できる

```
// テンプレート文字列を使わない場合
console.log("私の名前は" + name + "です。");

// テンプレート文字列を使った場合
console.log(`私の名前は${name}です。`);
```

**アロー関数**
=>を使うことで簡潔に関数を定義できる

```
// アロー関数を使わない場合
const func1 = function(str) {
　return str;
}

// アロー関数を使った場合
const func2 = (str) => {
　return str;
}
```

**分割代入**
配列やオブジェクト内のプロパティの値を楽に取得できる

```
// こういったオブジェクトがあるとする
const myProfile = {
　name: 太郎,
　age: 20
};

// 分割代入を使わない場合 (テンプレート文字列を使用しています。)
console.log(`私の名前は${myProfile.name}です。年齢は${myProfile.age}です。`);

// 分割代入を使った場合
const {name, age} = myProfile;
console.log(`私の名前は${name}です。年齢は${age}です。`);
-> 指定のプロパティを抜き出しておくことで、その後簡単に使用できる。
```

**デフォルト値**
変数を宣言しなかった場合のデフォルト値を定義できる。

```
// デフォルト値を指定しない場合
const sayHello = (name) => {console.log(`こんにちは${name}さん`)};
sayHello();
-> 引数無しで呼び出すと"こんにちはundefinedさん"と表示されてしまう。

// デフォルト値を指定した場合
const sayHello = (name = "ゲスト") => {console.log(`こんにちは${name}さん`)};
sayHello();
-> 引数無しで呼び出すと"こんにちはゲストさん"と表示させられる。
```

**スプレッド構文 (...)**
配列の展開・まとめ・コピーや結合などが可能。

```
// １．配列の展開
const arr1 = [1, 2, 3];
console.log(arr1);
-> [1, 2, 3]と表示される

console.log(...arr1);
-> 1, 2, 3と表示される(配列の中身が展開)

// ２．配列のまとめ
const arr2 = [1, 2, 3, 4, 5];
const [num1, num2, ...num3] = arr2;
console.log(num3);
-> 3 4 5 が表示される

// ３．配列のコピー、結合
const arr3 = [10, 20];
const arr4 = [30, 40];
const arr5 = [...arr3, ...arr4];
console.log(arr5);
-> [10, 20, 30, 40]が表示される
```


**mapやfilter**
配列の処理に使う。

```
// こういった配列があるとする
const nameArr = ["太郎", "二郎", "三郎"];

// mapを使わない場合 (要素全てを出力したい)
for (index = 0; index < nameArr.length; index++){
　console.log(nameArr[index]);
}

// mapを使った場合
nameArr.map((name) => console.log(name));

// こういった配列があるとする
const numArr = [1, 2, 3, 4, 5];

// filterを活用することで、例えば奇数だけの配列を作成することが可能
const newNumFilter = numArr.filter((num) => {
　return num % 2 === 1;
});
-> [1, 3, 5] が出力される
```

**三項演算子**
条件によって処理を分類できる。ES2015以前から存在する記法。

```
// 条件式 ? trueの場合 : falsの場合
const message = 1 < 0 ? 'trueです' : 'falseです'
console.log(message);
-> falseです が表示される
```
toio™️作ってみた！友の会のMaker Fair 2021(オンライン参加)


 2020年のMini Maker Faire Tsukuba、そしてMaker Faire Tokyoへの参加に味をしめた我々は Maker Faire Kyoto 2021(5/1)、そして Maker Faire Tokyo 2021(10/2) へも参加を目論んだのであった。

### 2020年に参加したときのレポート

https://qiita.com/kenichih/items/59de187b1cba884a3463

https://qiita.com/kenichih/items/da8985648ba309bad293

https://qiita.com/kenichih/items/62dc46bbbf4051e73b8c

https://qiita.com/kenichih/items/5b4d9aeff73c62d08cb2


### 2021年に参加したかったやつ

https://makezine.jp/event/mfk2021/

https://makezine.jp/event/mft2021/

　しかし、2019年から引き続き猖獗を極めるCOVID-19。参加者の健康と安全に配慮した結果、どちらもオンライン開催となってしまったのであった。参加を希望していた方々をはじめ、なんとかオンサイト開催を行おうと奔走していた運営スタッフの方々の無念たるや察するに余りあるものであった。

　というわけでtwitterへハッシュタグつけて投稿、という参加の形になりましたが、その時に投稿した動画です。

### Maker Faier Kyoto 2021オンラインに出したやつ

https://youtu.be/fDky5jtV6sw

　はい、これの焼き直しですね。(^^;


https://qiita.com/kenichih/items/cc58029ee78f41559d76

　動画の後半は紫外線LED８列版で美咲フォントを使った漢字表示で、京都の大文字焼きを再現してみました。

### Maker Faier Tokyo 2021オンラインに出したやつ

https://youtu.be/ZOFAJ9VNmKY

　この前に nanoblockのモルカーを使ったバージョンも作ったのですが、toio core cubeの上に載っていると微妙に違和感がありました。折り紙がキューブにすっぽりかぶるこっちのほうがよりモルカーらしく見えてよかったのでこっちをMaker Faire Tokyo 2021オンライン用として投稿しました。なんといっても折り紙を[AsoppaさんのWebページからダウンロード](https://asoppa.com/asopparecipe/makes/2613366/)して印刷すればお手元での再現が簡単なのが良いです。(toio core cubeが5～6台必要ですけども)
動きも[toio SDK for Unity](https://github.com/morikatron/toio-sdk-for-unity)のサンプルそのまんまです。

https://youtu.be/DMj0WEiLtbw

https://youtu.be/Tb8qS7Rd0A8

### さいごに
　2022年も日本各地のMaker Fairへの出展に挑戦しようと思います。みなさん、会場で会いましょう！
iOSでバーコードを検出する

Visionのバーコード検出は、複数の種類のバーコードを一度に読み取ることができる。
医療分野などの業務用に活躍も考えられる。

![Dec-10-2021 08-08-16.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/df4d228d-deb0-035f-0f3f-0c8fa214bc81.gif)


#検出方法

```swift
let detectBarcodeRequest = VNDetectBarcodesRequest()
detectBarcodeRequest.revision = VNDetectBarcodesRequestRevision2
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: .right, options: [:])
do {
    try handler.perform([detectBarcodeRequest])
    guard let observations = detectBarcodeRequest.results as? [VNBarcodeObservation] else { return }
} catch {
    print("Vision error: \(error.localizedDescription)")
}
```

結果には以下が含まれる。
**バーコードのバウンディングボックス（0~1の値に正規化された座標）
ペイロードから読み取った文字列
バーコードの種類
低レベルのデスクリプション（CIImageでバーコードを再生成するときに使う）**

QRコードのような２次元バーコードは全体を囲むボックス、１次元のバーコードは横に直線で読み取った細いボックスが返される。

```swift
for observation in detectBarcodeRequest {
    print(observation.boundingBox)
    print(observation.payloadStringValue)
    print(observation.symbology)
    print(observation.barcodeDescriptor)
}
```

>
(0.01536397757353606, 0.5692257563273112, 0.38412154692190664, 0.21521108945210776)
Optional("https://ja.wikipedia.org/")
VNBarcodeSymbology(_rawValue: VNBarcodeSymbologyQR)
Optional(CIQRCodeDescriptor: 0x28112bd50)

>(0.5915124398690683, 0.5233462015787761, 0.15230130796079278, 0.08319133122762035)
Optional("http://www.irasutoya.com/")
VNBarcodeSymbology(_rawValue: VNBarcodeSymbologyQR)
Optional(CIQRCodeDescriptor: 0x28112a1f0)

>(0.27184558444552953, 0.37421875, 0.27779362996419266, 0.0015625000000000222)
Optional("Wikipedia")
VNBarcodeSymbology(_rawValue: VNBarcodeSymbologyCode128)
nil

デフォルトでは認識できる全てのバーコードが観測される。
認識するバーコードの種類を指定する。

```swift
detectBarcodeRequest.symbologies = [.qr] //配列なので複数指定もできる。
```
認識できるバーコードの種類は以下。
>
.aztec
.codabar
.code128.
.code39
.code39Checksum
.code39FullASCII
.code39FullASCIIChecksum
.code93
.code93i
.dataMatrix
.ean13
.ean8
.gs1DataBar
.gs1DataBarExpanded
.gs1DataBarLimited
.i2of5
.i2of5Checksum
.itf14
.microPDF417
.microQR
.pdf417
.qr
.upce

フレーム内の特定の領域に注目して結果を取得することもできる。
この場合、注目領域内の座標が返される。

```swift
detectBarcodeRequest.regionOfInterest = CGRect(x: 0.1, y: 0.1, width: 0.4, height: 0.4)
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
簡単な開発内容をお書き添えの上、お気軽にご連絡ください。
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Dynamics 365 単独でコンタクトセンターを構築！ノーコードで10分で爆速構築（30日試用版）

## この記事を読むとなにができる？
* Dynamics 365 Customer Serviceの電話音声、文字起こし、IVR機能概要を把握でき、自分で環境構築できる
* Dynamics 365 Customer Service 音声チャネル(Voice Channel)が理解できる

つまりCTI連携かつ、IVRを備えてたシステムをお手軽に試すことができる

以下はお客さまが電話をする（左の外国男性）。そしてIVR自動応答を行い、チャットボットでお客さまに音声案内するイメージ写真。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/052fe790-f688-3c73-f593-344f0c25f12d.png)

動画でのデモ内容は以下です。

https://youtu.be/w75eukAiPiU?t=357

## 前提
日本のテナント環境ではなく、US環境でテナント作成となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/7c28d7fa-7bbe-12ce-4dd1-00233eb8e9f4.png)


## 1.CDXにVoice Chanel環境作成 無料試用版で作成（10分）
## 1.1. [30日間無料トライアル](https://dynamics.microsoft.com/en-us/customer-service/customer-service/free-trial/?ef_id=9ec87189eca41231093210d50c752352:G:s&OCID=AID2200049_SEM_9ec87189eca41231093210d50c752352:G:s&msclkid=9ec87189eca41231093210d50c752352)にアクセスしメールアドレス入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/5a9c5a32-56e4-8a5f-ad43-2207d65f6ef0.png)

## 1.2. ここで注意！まだ試用版であるためJapan環境では作成しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/77ff489a-be38-23e3-8662-62c4341983a1.png)

なぜなら音声利用しようとするとボタン非表示であるため
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/f2f2bf0a-e5f3-e81c-03fe-dabb6dda972a.png)

US環境を選択しsubmitで作成する。以下は作成後のTOP画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/e1cbfd92-02a5-5081-944c-cd395005d2ed.png)


##1.3. 中央の「音声の探索」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/5066d3ad-d4a7-8820-895e-b3aaa35dbc6b.png)

##1.4 Teamsより電話をかける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/c15684d5-3514-50cf-dbab-6bb95ef59401.png)

待つこと30秒でオペレータ画面に通知がくる。承認を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/7a7c4f48-60cd-386d-8f22-ba973d5087a4.png)

##1.5 オペレータから見た画面左が電話の内容を文字起こしで自動で保存。
右画面はCTI連携でお客さまの情報を自動取得、表示している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/996f4549-c40c-fdae-464c-c783ab1c37e6.png)


##1.6 音声も自動録音され後からでも確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/6d7da9f9-ad69-4a89-7dda-338200801386.png)

##1.7テキストに文字起こししているため感情もわかる。気持ちは「否定的」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/06f2d601-1581-480d-5c3a-537123271773.png)




##もう少し詳細を聞きたい場合は以下よりお問い合わせください。
[Dynamics 365カスタマーサービスの概要](https://dynamics.microsoft.com/ja-jp/customer-service/overview/)

今後日本の電話番号を取得できるようになると
国内利用が可能と思われます。（予想です）

（英語版）
https://docs.microsoft.com/en-us/dynamics365/customer-service/voice-channel

（日本語版）
https://docs.microsoft.com/ja-jp/dynamics365/customer-service/voice-channel
以上

## 次回は以下を紹介します。
**2.チャットボット（Power Virtual Agents）を使って、Dynamics 365 Customer Service　オペレータへつなぐ（10分）**
Power Virtual Agents を使って、Dynamics 365 Customer Service　へIVR連携します。
よくある人間とチャットボットが電話で会話しながら、最後にオペレータへつなぎます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/679f7645-cb32-f7be-624d-b724fcf7423d.png)
[VisualStudioCode]エディターのテーマをプレビューする


#概要
2021年12月8日のv1.63アップデートでテーマをプレビューする機能が追加されました。
リアルタイムで見え方の確認ができて、キャンセルも適用も自由に出来ます。
#本文
[Windowsのキー操作]
CTRL + K
CTRL + T

[macのキー操作]
Command + K
Command + T

![スクリーンショット 2021-12-10 7.31.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/3132b5c8-c328-b2d1-d742-179ae5694567.png)

マウスではなく、カーソルの上下でテーマを選んでください。
気に入らなかったらESCキーで使用中だったテーマに戻ります。
気に入った時はエンターキーでテーマを適用できます。
systemctl daemon-reload って何

## 経緯

snmptt の RPM ファイルをインストールした際、

`Warning: snmptt.service changed on disk. Run 'systemctl daemon-reload' to reload units.` という出力が出た。

## 問題

なぜ、この出力が出たのかわからない。

また、 `systemctl restart <service-name>` では不十分なのか疑問である。

## 結果

正確な理解ができているかはわからないが、 `systemctl restart <service-name>` と、 `systemctl daemon-reload` は、以下のように使い分ければいいと理解した。

### `systemctl restart <service-name>`

設定ファイルを変更したときに実行すると、設定ファイルの変更を反映できる。

### `systemctl daemon-reload`

systemd で管理されている Unit ファイル群に変更が加えられた場合に実行すると、その変更を systemd に反映できる。

---

RPM ファイルをインストールすると、 RPM ファイルに含まれる場合 Unit ファイルなどもシステムにインストールされる。

インストールされた Unit ファイルを実行中の systemd に変更するためには `systemctl restart snmptt.service` では足りず、 `systemctl daemon-reload` の実行が必要となる。

> daemon-reload
>
>  Reload the systemd manager configuration. This will rerun all generators (see systemd.generator(7)),
>  reload all unit files, and recreate the entire dependency tree. While the daemon is being reloaded, all
>  sockets systemd listens on behalf of user configuration will stay accessible.
>
> This command should not be confused with the reload command.

## 関連リンク

* [第10章 systemd によるサービス管理 Red Hat Enterprise Linux 7 | Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd)
  * 前提として、このドキュメントの知識がないと理解できなかった。
* [Do systemd unit files have to be reloaded when modified? - Server Fault](https://serverfault.com/questions/700862/do-systemd-unit-files-have-to-be-reloaded-when-modified)
  * これを読んで、 Unit ファイルに変更を加えた際に実行する必要があるようだと確信を得た
* `systemctl` の マニュアル (`man systemctl`)
本番環境への変更の反映に、 `git pull` ではなく `git checkout origin/master` を使う

# `git checkout origin/master` とは

リモートの `origin/master` ブランチを参照している状態です。

# `git pull` による反映

```
git fetch
git branch
git pull
```

# `git checkout origin/master` による反映

```
git fetch
git checkout origin/master
```

# メリット

## `git pull` でたまに発生するマージ作業や、コンフリクトの解消作業を避けることができる。

`git checkout origin/master` を利用する場合参照を切り替えるだけなので、ローカルでのマージが発生しません。

よって、 `git merge` を実行した際に表示される以下のような出力が出ることもなく、 `git config user.email` `git config user.name` を設定する必要もありません。

```
*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"
```

## ローカルにブランチが作成されない

`git pull` で反映する方法を利用していると、誰かが本番環境上で自分のブランチの変更を試したりして、いつの間にかこんなことになります。

```
$ git branch
master
develop
bugfix/xxxx
bugfix/xxxx-xxxx
feature/xxxx-xxxx
...
```

`git checkout origin/master` であればローカルにブランチは作成されないため、 `git branch` の結果は以下のようになります (main ブランチが develop の場合)

```
$ git branch
develop
```

# 適さない場合

* 本番環境上でファイルの変更を行ってコミットすることがある場合は、 `git pull` の方が望ましいと思います。
開発中にエラーを吐いてよくQiitaの記事にたどり着くあなたへ

#開発中にエラーを吐いてよくQiitaの記事にたどり着くあなたへ

この記事は開発中にエラーを吐いてGoogle先生に質問し，そして検索の上位に出てくるQiitaの記事によくだどりついてしまうあなたへの記事です．「俺はQiitaではなく，公式ドキュメントを読むんだ！」という方もぜひ軽い気持ちでご覧になってください．きっと役に立つはずです．

#結論 例外処理で工夫する
まず，結論としては例外処理でQiitaに飛ばしましょう．Pythonでの書き方の例を示します．普通の例外処理はこのように書きますね．

```python
try:
    print(1/0)
except ZeroDivisionError as e:
    print(e)
```

```python
try:
    print(1/0)
except Exception as e:
    print(e)
```

これらは見慣れた光景だと思います．特に下の書き方はあらゆるエラーを拾ってくれて楽なので多用しがちです．ですが，上のように起こりうるエラーを想定して例外処理を書くのが本番環境では理想です．予期せぬエラーはプログラムが動かなくなる一番の原因であるためきっちり最後は起こりうるエラーを想定して例外処理を書いてください．ですが私もうまく書けるわけではありません．精進します．
話を戻します，兎にも角にもエラーを吐いてそれをいちいち調べるのって面倒くさいですよね．
そこで，例外部分を工夫します．

```python
import webbrowser
try:
    print(1/0)
except Exception as e:
    webbrowser.open('https://qiita.com/search?q={}'.format(e))
```

こうすることでtry分の中で起こったエラーを全てQiita内で検索してくれます．このプログラムだと```division by zero```とエラーが発生します．すると自動的に既定のブラウザを開いて下の画像のように検索してくれます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/fa730ec4-d4bc-ec51-629a-4196581fb134.png)

このページのURLは```https://qiita.com/search?q=division%20by%20zero```となっています．このQiitaで検索する例外処理ですが，コーディングしているときにコード全体をtry文で囲うことをお勧めします．そうすることでエラーを吐いたときに一瞬でそのエラーを検索することができます．
ここで，蛇足ですが，この記事を見たプログラミング初心者の方のために軽くこのURLの仕組みを解説しようと思います．もしちゃんとURLについて知らないかもと思っている方がいればぜひご覧になって帰ってください．

#URLの仕組み
まず，最初の```https```はプロトコルです．これは私たちのPCやスマホとウェブページが入っているサーバーが通信をするときの規約です．興味がある方はhttpとhttpsの違いなどで検索してみることをお勧めします． 
次に```qiita.com```ですが，これはドメイン名です．ドメイン名とはIPアドレスと一対一で紐づけられている名前です．ざっくり言うと，全てのウェブページにはIPアドレスが存在していますが，その数字だけで表されたIPアドレスでウェブページを探すのは人間には都合が悪いため都合よく名前を付けてみた．これがドメイン名です． 
次は```/search```の部分です．これはファイルのパスを示しています．ただ，難しいと感じる方は「qiita.comの中のsearchという部屋にいる」くらいの感覚でいるのがいいかもしれません．

最後に```q=division%20by%20zero```です．これはパラメータと呼ばれるものです．パラメータとはウェブページ（ウェブサーバー）に対してユーザが指定する引数のことです．皆さんが関数を利用する引数と同じです．
例えばYoutubeのリンクは次のような感じです．```https://www.youtube.com/watch?v=ofYTAoS4LzE&t=270s``` 
これはwww.youtube.comの中のwatchという部屋にいて，vという値がofYTAoS4LzE，tという値が270sという風に指定しています．vの方は動画を指定しているパラメータで，tの方が動画の再生開始時間を指定しているパラメータです．このURLがどのような動きをするか気になる方は[こちらから再生できます．](https://www.youtube.com/watch?v=ofYTAoS4LzE&t=270s)270秒(4分30秒)から動画が始まります．
以上で分かっていそうで分かっていないミニURL講座を終了します．

#終わりに
正直なことを話すと，私はエラーを吐いたとき，公式ドキュメントでその原因を調べてほしいと思っています．そうすることでエラーの中身や細かい仕様などについて勉強できて今後のコーディングに大いに生かせるからです．ただ，初学者，初心者はそんなことをしていたら心が折れると思います．少しでもプログラミングで挫折する人が減ったらいいなとこの記事を書きました．幸い，Qiitaには優秀なエンジニアたちの優秀な記事がたくさんあります．それらが全てコピペで動くとは言えませんが，かなり参考になるものもたくさんあります．さらにQiitaは日本語の記事が豊富です．ですからみなさんもこの方法でどんどんエラーを調べて力をつけてほしいです．
M1 macOS｜MontereyにアップグレードしたらPHP使えなくなったから再度インストールした 

ことの発端は、これまでローカル環境にてLaravelの開発をしていた。
いつも通り「php artisan serve」サーバー起動コマンドを打つと...

```
$php artisan serve
command not found
```
とコマンドないよと怒られた。

調べてみると下記記事発見。

https://applech2.com/archives/20211018-apple-removed-php-from-macos-12-monterey.html

>M1のMacOS、MontereyへのOSバージョンアップではPHPはバンドルされない。。。

とのことなので新たにPHPをインストールした。その時の備忘録。


## 1.Homebrewバージョン確認
```ターミナル
$brew -v
Homebrew 3.3.3
```
brew -vを実行
Homebreは入っている

### 必要ならHomebrewバージョンアップ
```
brew upgrade
```

## 2.phpバージョン確認
```
$php -v
command not found
```

php -v　を実行

command not found

やはりない

## 3.インストール可能php確認
```
$brew search php
==> Formulae
brew-php-switcher            php-code-sniffer             php@7.2                      php@7.4                      phplint                      phpmyadmin                   phpunit
php                          php-cs-fixer                 php@7.3                      phpbrew                      phpmd                        phpstan
==> Casks
```

brew search phpを実行
インストール可能phpバージョンが出る


## 4.phpインストール
```
$brew install php@7.4
Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
    arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.
```

7.4をインスト
brew install php@7.4　と実行


arch -arm64 頭につけろってエラー


### arch -arm64 つけてインスト
```
$arch -arm64 brew install php@7.4
Error: No developer tools installed.
Install the Command Line Tools:
  xcode-select --installv
```
arch -arm64 brew install php@7.4　を実行

xcodeインストールしろってエラー

### xcodeインストール
```
$xcode-select --install
```
xcode-select --install　を実行
10分ほどかかる...

### Homebrewバージョンアップしとく
```
$brew upgrade
```

## 5.気を取り直しarch -arm64 つけてPHPインスト
```
$arch -arm64 brew install php@7.4
If you need to have php@7.4 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/opt/homebrew/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
```

arch -arm64 brew install php@7.4


## 6.上記の通りパスを通す
```
echo 'export PATH="/opt/homebrew/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/opt/homebrew/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
```

### 念のため通っているかcatで確認。

```
$cat ~/.zshrc
>export PATH=/opt/homebrew/bin:$PATH
>export PATH="/opt/homebrew/opt/php@7.4/bin:$PATH"
>export PATH="/opt/homebrew/opt/php@7.4/sbin:$PATH"
```

cat ~/.zshrc

## 7.phpバージョン確認とインストール確認
```
$php -v
PHP 7.4.26 (cli) (built: Nov 28 2021 16:40:00) ( NTS )
```

```
$which php
/opt/homebrew/bin/php
```

## 8.ターミナルを再起動

参考
https://sakura.ohhappy.jp/mac/1342
https://qiita.com/joh_luck/items/f3321ee81166aea0ff3b
GPT-3をGoogle Colaboratoryで実行した時の"No API key provided"の対処法

#はじめに
OpenAIが開発している言語モデル**「GPT-3」**をGoogle Colaboratoryで実行するとエラーが出ました。その解決法が分かったので共有します。
#どんなエラー？
Open AIが公開しているサンプルコードは以下です。


```python
import os
import openai

openai.api_key = os.getenv("あなたのAPIキー")

response = openai.Completion.create(
  engine="davinci",
  prompt="I'm happy.", #どの文章から始めるか
  temperature=0.7,
  max_tokens=64,
  top_p=1,
  frequency_penalty=0,
  presence_penalty=0
)
```
しかし、これをGoogle Colaboratoryで実行すると以下のようなエラーが出ました。

```
AuthenticationError: No API key provided. You can set your API key in code using 'openai.api_key = <API-KEY>', or you can set the environment variable OPENAI_API_KEY=<API-KEY>). If your API key is stored in a file, you can point the openai module at it with 'openai.api_key_path = <PATH>'. You can generate API keys in the OpenAI web interface. See https://onboard.openai.com for details, or email support@openai.com if you have any questions.
```

#解決法
以下のようにするとエラーが出ず、実行出来ました。

```python
import os
import openai

#os.getenvを入れない
openai.api_key = "あなたのAPIキー" 

response = openai.Completion.create(
  engine="davinci",
  prompt="I'm happy.", #どの文章から始めるか
  temperature=0.7,
  max_tokens=64,
  top_p=1,
  frequency_penalty=0,
  presence_penalty=0
)
```
このように「openai.api_key」に**直接APIキーを入れる**とエラー無く実行出来ました。

#ちなみに
上の正解のコードを実行しても何も表示されないと思います。なぜなら実行結果がresponseに入っているからです。
なのでprintをすると実行結果が表示されます。
**コード**

```python
import os
import openai

openai.api_key = "あなたのAPIキー"

response = openai.Completion.create(
  engine="davinci",
  prompt="I'm happy.",
  temperature=0.7,
  max_tokens=64,
  top_p=1,
  frequency_penalty=0,
  presence_penalty=0
)
print(response)
```

**実行結果**

```
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "text": "\n\nHe's happy.\n\nWe're happy.\n\nI love you.\n\nI love you too.\n\nThe End"
    }
  ],
  "created": 1639086805,
  "id": "cmpl-4DLdtMQ4ZoXT46DJFPy3PGNoYdVGS",
  "model": "davinci:2020-05-03",
  "object": "text_completion"
}
```
**「text」**に続きの文章が生成されています！

#おわりに
解決法は非常に簡単でした。ただ検索しても中々出てこなかったので共有しました。
参考になればと思います！
STM32G031と(VSCode+STM32Cube)でI2Cスレーブで遊ぶ(受信)(STM32G031J6M6)HAL




x プルアップ抵抗を忘れずに10kΩがおすすめ
x 過去ログを見よ->
x cubeMXは、disco-g0316
x VSCoedは、nucleo-g031

x 4ピンは、リセットを解除してGPIOにする
x シリアルの速度は、中途半端な209700bps

x SWDは、気持ち設定した。

目的
I2Cスレーブのテスト

参考



https://gsmcustomeffects.hatenablog.com/entry/2017/04/03/023111




I2C_SLAVE_TEST1_031_1内を適当にコピー




https://os.mbed.com/users/caa45040/code/f303_h_p1/



![o_con142.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1f43ccb6-792d-f529-5658-ba10286ca364.jpeg)



![o_con143.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/107027a5-433d-d8c3-ba43-a52d4d8825a0.jpeg)




![o_con144.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9acafe71-c0a4-802b-f213-b9b51689f962.jpeg)



![o_con145.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6f2a3b89-b532-221a-674e-5d2f10b7ef4c.jpeg)



![o_con146.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a9cfdc05-da12-7414-2ffa-9f513799fb38.jpeg)




main内のwhile内


```c++





        uint8_t aRxBuffer[1] = {0};
        char *str1 = 0;
        //aRxBuffer[0] = 0 ;

        if(HAL_I2C_Slave_Receive(&hi2c2,(uint8_t*)aRxBuffer, 1, 1000) == HAL_OK) {
           str1="OK\r\n";
            
        } else {
           str1="NG\r\n";
            
        }
        
        //ステータスの表示
        HAL_UART_Transmit(&hlpuart1, (uint8_t *)str1, 4, 10);
        
        //I2Cスレーブの受信データの表示
        HAL_UART_Transmit(&hlpuart1, (uint8_t *)"\tRead A: ", 9, 10);
        uint8_t n1  = '0' + (aRxBuffer[0] % 10);
        uint8_t n10 = '0' + (aRxBuffer[0] / 10);
        HAL_UART_Transmit(&hlpuart1, &n10, 1, 10);
        HAL_UART_Transmit(&hlpuart1, &n1, 1, 10);
        HAL_UART_Transmit(&hlpuart1, (uint8_t *)"\r\n", 2, 10);

        HAL_Delay(200);//0.2秒待つ















```



I2C内


```c++


  hi2c2.Init.OwnAddress1 = 0x80;



```
Power BIの新しいボタン ページ ナビゲーター/ブックマーク ナビゲーター

## はじめに
　2021/11のアップデートで登場した2つの新しいボタン「ページ ナビゲーター」と「ブックマーク ナビゲーター」を紹介します。

## 参照
- [Power BI November 2021 Feature Summary | Microsoft Power BI ブログ | Microsoft Power BI](https://powerbi.microsoft.com/ja-jp/blog/power-bi-november-2021-feature-summary/#post-17912-_Toc87473934)

細かな設定等については、こちらのブログにあります。

## ページ ナビゲーター

[挿入]タブの[ボタン]の下部にあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/34cb2e89-f95e-c80f-d67e-fcd33ee0bc4f.png)


ページが複数になったとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/0e78ac54-4774-8cec-23ca-f7ca176424c4.png)

ページ ナビゲーターを追加すれば、すぐに画面遷移が動作するものボタンが作れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/3b117ecb-7201-6b93-cde9-5d05ecfb678b.png)

ページを追加すれば、自動でボタンも追加してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/3b46dae9-fc47-6828-07b2-75a68a86f17f.png)

Power BI Desktopでページ遷移する場合は、[Ctrl]キーを押しながらクリックします。Power BI Serviceでは、クリックのみで遷移します。

## ブックマーク ナビゲーター

ブックマーク自体は、[表示]タブの、[ブックマーク]で付けていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/8099b384-8367-7a8a-5d2e-c0e45c47f12a.png)

ボタンの配置は、同様です。

## 書式はお好みで変更可能

ボタンの角を丸くして、ボタンぽくしたり、お好みで書式を変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/b25d1c9c-063d-2607-26c0-c7dd529d7f89.png)


## おわりに
　これまで、このようなナビゲーションバーを作るのは、ひとつのボタンづつ、リンク先を設定していき、結構手間がかかるものでした。今度からは、この2つのナビゲーターボタンがあればラクラクですね。
　Power BIは、毎月アップデートがあります。最新を使っていくことをおススメします。
Accelerate State of DevOps report を読む



この記事は [カオナビ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kaonavi) 10日目です。

株式会社カオナビのプロダクト本部SRE部オペレーショングループに所属している、棚橋です。
オペレーショングループでは本番デプロイ作業や日々発生する運用業務の自動化や効率化を行っています。

# Accelerate State of DevOps とは

毎年世界中から、ソフトウェア・デリバリーやオペレーションや組織のパフォーマンスのデータを集めて統計的手法を用いて分析し、まとめたレポートです。

https://cloud.google.com/blog/products/devops-sre/announcing-dora-2021-accelerate-state-of-devops-report

私は『LeanとDevOpsの科学』でその存在を知りました。

https://www.amazon.co.jp//dp/4295004901/

この中で今回は４つのキーメトリクスをベースにした、**Software Delivery and Operation**（以下SDO）とドキュメントの品質のページに注目しました。

# 4つのキーメトリクス

2つずつそれぞれ**Throughput（処理速度）**と**Stability（安定性）**の指標に分けられています。

**レポートのP.9より抜粋**
![スクリーンショット 2021-12-09 5.50.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29845/233e110b-e5ca-57ec-6dd7-b33cb2754417.png)


## Throughput

### デプロイ頻度

1日あたりの本番デプロイ回数（デプロイの他に本番環境のリソースや設定変更なども含む）が指標になります。
このレポートだと最大1460回/年=1日4回もデプロイしている企業がいるとのことで、この回数はさすがに多くて驚きました...（グローバルな企業とかだと十分にありえそうですがさすがに働きすぎなのでは...）

カオナビの場合は、現在1日複数回の本番デプロイを安定的に行っていますが、土日やその前の金曜日は本番にデプロイしない運用にしています。さらにそこに祝祭日もあるので、実際のところ500回〜600回が目標になれば良いのではないかな、と思っています（それに向けて鋭意改善模索中）。

### リードタイム

コードをコミットしてから本番へのリリースにどれくらい時間がかかるかが指標になります。

リードタイムが**1時間未満**であればハイパフォーマーということですが、カオナビでは安定して1時間未満というところまではまだできておらず、デプロイプロセスや仕組みを改善して安定的に1時間未満でデプロイできるようにはしていきたいと思っています。

## Stability

### MTTR（平均修復時間）

問題が発生してからサービス復旧までの時間を指標にしていて、こちらもリードタイムと同じように1時間未満であればハイパフォーマーに分類されます。

**問題が発生してからサービス復旧までの定義**が気になるところで、たとえば障害発生後に即座に変更を戻すことで事象解消＝サービス復旧というパターンもありえるかと思います（根本的な障害原因の対応はこの後別にやる想定）。

カオナビでは障害の一部のパターンについてはリードタイムを計測していますが、全てのパターンで実績が取れているわけではないため、何かしら指標を定義してもう少し広義でのMTTRを計測してみたいと思っています。

### 変更失敗率

本番環境へのデプロイや変更の内、サービス障害やサービス停止などにつながったリリースがどれくらいあるかの指標となっています。

```math
変更失敗率 = 変更失敗回数 / 本番デプロイ回数
```

変更失敗0を目指すのは素晴らしいことですが、0を維持し続けるのはとても大変です。
そのため本番デプロイ回数を増やし、変更失敗率の変動をできるかぎり小さくすることが望ましいと認識しています。

前述どおりカオナビでは１日あたり複数回リリースをしていることで、比較的に変更失敗率は低くなる傾向にあります。実際の変更失敗率は5%前後を維持していて、最終的な目標としては2%を目指しています。

これら４つのキーメトリクスの数字は、実際にまとめて社内で共有できたら良いなと思っています（ここで言っておけばやるだろうという追い込み）。

# ドキュメントの品質

もう一つ気になったところとして、2021年から内部資料の品質にも注目しているようで、マニュアルやREADME、コードコメントなど開発や運用に関わるドキュメント全般を対象に調査を行ったようです。

レポートには以下の観点でドキュメントの品質を評価した頁がありました。質の高いドキュメントを作成しているチームはSDOのパフォーマンスが高いそうです。

- 読者の目的達成に役立つ
- 正確で、最新で、包括的である
- 見つけやすく、整理されていて、明確である

ちょっと抽象的で「そんなことはわかっとる」という感じではありますが、ドキュメントの品質については『情報アーキテクチャ』や『SREの探求』の第19章がテーマになっているので、読んでみると良いかもしれないです。

https://www.oreilly.co.jp/books/9784873117720/

https://www.oreilly.co.jp/books/9784873119618/

また高いドキュメントの品質を保つためのプラクティスとしては以下のようなものがあげられていました。

- オーナーを決める
- ユースケースをドキュメントにする
- 既存のドキュメントを更新・編集するためのガイドラインを作成する
- 不正確な情報や古い情報の削除するガイドラインを作成する

レポート内にも記載ありますが、専門的な知識や指針・方針をチーム間や全体で共有するためには、ドキュメントが重要な役割を持っているはずです。
~~メンテナンスがとてもめんどくさいですが、~~レポートに記載されているプラクティス、特に更新や削除のためのガイドラインは実践してみる価値がありそうだなと思いました(「作成」のガイドラインはあっても、「更新」や「削除」のガイドラインが意外とない）。

# 終わりに

2021年ならではの内容として、COVID-19によるパフォーマンスの影響などの調査もありました。他にも５つ目の指標として、運用パフォーマンスへの言及があったりカルチャーに関する調査など、まだまだ読み足りていません。

このレポートにあるようなエリートなハイパフォーマーになれるように日々改善をしていきたいと思います。
一年間で「大きく成長できた」と感じたターニング技術一覧！

## はじめに

もうすぐ新卒として入社してから、1年が経とうとしています。

そんな中で
「「　大きく考え方変わった/成長できた　」」
と感じたターニングポイントとなる技術こと、
**ターニング技術**一覧をご紹介致します。

## 開発手法編

まずはプロダクトを開発する上で重要な開発手法についてです。

### アジャイル開発

ご存知の方も多いと思います。
絶賛、弊社でも輪読会の対象となりました

https://www.amazon.co.jp/dp/4274068560

#### 何がターニングした？

1. インセプションデッキ
1. ユーザーストーリー
1. ストーリーポイント
1. 価値ある成果を毎週届ける
1. ベロシティと見積もり修正

上記であげた項目など、
サービス開発において
「「 **決めるべき事項** 」」や「「　**とるべき行動指針**　」」
を意識できるようになりました。

### スキーマ駆動開発

フロントエンドとサーバーサイドで同時に開発が進められるテクニック。

`OpenAPI Specification`や`GraphQL`などで定義したスキーマを元に、
フロントやサーバーの言語で型をgenerateして開発を行なっていくと、
ドキュメントとコードにも差分がなくなるので良いよね〜というやつ。

#### 何がターニングした？

サーバーサイドを実装しないとフロント何もできない状況を
過去に味わったことがあったので、
同時並行に開発を進められるのはシンプルに良かった。

また
「「　**ドキュメントと実際に提供しているAPIが違う**　」」
なんてこともRESTFullAPIでは起こりうるので、、、

1. `OpenAPI Specification`に基づきスキーマ定義
1. 定義を元に型のコード生成
1. ↑を元に開発を行なっていく

この流れの重要性を理解しました。

## データベース編

データを格納して、呼び出す部分。
サーバーサイドエンジニアなら必ず触ります。

### ORMとRowSQL

そもそも「ORMとは？はにゃ？」という状況で
知らず知らずORMを使っていました。
(学生時代にDjangoでやってました)

#### 何がターニングした？

会社にて膨大なデータの管理及び、テーブル設計をし始めると、
逆にORMに対して違和感を抱くようになり、
そこでちゃんとSQLをゴリゴリと学び/書き始めるようになりました。

:::note warn
entというGraph構造を信仰するORMを使い、
テーブル設計が爆発した知識と経験を持っています...
※entが悪い訳ではありません。使い所には注意してください。
:::

### ElasticSearch(NoSQL?)

続いて大規模なデータの取得に対して、有効な手段であり、
全文検索は特にビックリしました。

https://www.elastic.co/jp/elasticsearch/

#### 何がターニングした？

単純にNoSQLの強みを知れた。
設計次第でもあるけど、MySQLでこの速さは出ないなぁという学び。

## 設計編

学生時代は良くも悪くもあまり意識できなかった部分ですね。
(サービスを作ること自体への楽しさ/苦しさで精一杯)

### Container/Presentational Component

「ロジックと見た目を切り分けよう」というコンポーネント設計指針。

最初はReactすら、何もわからなかったので、
「何が違うねん」と思っていましたw

#### 何がターニングした？

DOMとロジックを切り分けて考える機会になりました。

- 見た目に対して、責務を果たすことに注力できる
- ロジックに対して、責務を果たすことに注力できる

読みやすくなるし、切り分けはとても大事。

### Atomic Design

いわば見た目のデザイン手法をフロントエンドでも取り入れたやつです。

https://atomicdesign.bradfrost.com/chapter-2/#atomic-design-is-for-user-interfaces

#### 何がターニングした？

コンポーネントという単位を理解する良いキッカケになりました。

「使いまわせる」、「枠組みを作る」、「責務を明確にする」は大事。

汎用性高く、ただし修正する際には一眼で場所がわかるようにするなど、
しっかり考えなければ、この設計は成り立ちません。

### Domain Driven Design(DDD)

エリックエヴァンスこと、ドメイン駆動設計です。
サービスで実現したいものを最優先で考える設計手法です。

https://www.amazon.co.jp/dp/4798121967

新卒としてここを学べたとこが一番影響として大きいと思っています。

#### 何がターニングした？

強強エンジニアとはこうゆうことだと気づけるキッカケになりまそた。

- レイヤードアーキテクチャ(Interface→Usecase→**Domain**←Infra)
- ↑を実現するための依存性注入
- interface(repository)(抽象)を先に実装して、中身を書くこと
- 副作用を少なくテストしやすい関数にすること
- **不変な**値オブジェクトとエンティティでモデルを表現すること
- 命名規則(境界づけられたコンテキスト内でのユビキタス言語)
- 何より**サービスで実現したいもの(ドメイン)**が一番大事ということ

初めは読んでいて、
「なんでこんな回りくどいことしてんだ」と何回も思いましたが、
DDDではない実装をしたり、日々エンジニアとして業務をしていると、
ふと腑に落ちる瞬間があります。

まだまだ理解していない(エリック本を読破もしていない)ので、
これからもたくさんのこと学び続けていこうと思います。
Firestoreのファイルをブラウザからダウンロードする（React）


Cloud Firestoreに保存しているファイルをユーザーが自由にダウンロードできる機能を実装した。[公式ドキュメント](https://firebase.google.com/docs/storage/web/download-files)に手順は記されているのだが、そのままやってもシメの`xhr.send()`が作動しなくて詰まった。

## CORSの設定

まず、大前提としてブラウザから直接ダウンロードするためには、使用しているCloud Storageのバケットに対してクロスオリジン アクセス（CORS）を構成しておく必要がある。

Google Cloud Console上から、エディタを開いて、`cors.json`を作成する。

![Overview_–_APIs___Services_–_vidreview-dev_–_Google_Cloud_Platform.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116375/eaba40ab-073b-f8b0-5c53-2ede5fbdcdca.png)

保存が完了したら、ターミナル上で馴染ませる。

```
$ gsutil cors set cors.json gs://[APP_ID].appspot.com
```

CLIを使っていれば、クライアント側の開発環境からも実行できる。

## ファイルをダウンロードする

### Cloud StorageからファイルURLを取得する

```
storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
  ・・・
})
```

正しく動いていれば、URL部分に`https://firebasestorage.googleapis.com/v0/b/[APP_ID].appspot.com/o/[FOLDER_NAME]%[TOKEN]?&token=[FILE_TOKEN]`のような形式で表示されるはず。

### Blobに保存して、aリンクでダウンロード

```
const xhr = new XMLHttpRequest()
xhr.open("GET", url, true)
xhr.responseType = 'blob'
xhr.onload = () => {
const blob = xhr.response
  var objectURL = window.URL.createObjectURL(blob)
  var link = document.createElement("a")
  document.body.appendChild(link)
  link.href = objectURL
  link.download = 'DOWNLOAD NAME'
  link.click();
  document.body.removeChild(link)
}
xhr.send();
```

外部リンクに直接aタグを叩いてもファイルをダウンロードすることはできないので、一度Blobに保存する必要がある。そのBlobデータを叩けば、なんなくファイルがダウンロードされる。
Next.js（動的サイト）をNetlifyにデプロイする


Next.jsアプリをNetlifyにデプロイしようとしたら、結構手こずった。

Reactアプリをデプロイする時にも、`react-router-dom`を使っているなら`_redirects`を設定する必要があるみたいなお約束があったので、このあたりは苦戦するだろうなと予想はついていた。

案の定、静的ページは表示されるけど、動的ページは「404」を突きつけられることになった。

デプロイ時に加える必要がある処理を書き留めていく。

## netlify.tomlの設定

```
[build]
  command = "npm run build"

[[plugins]]
  package = "@netlify/plugin-nextjs"
[[plugins]]
  package = "netlify-plugin-cache-nextjs"
```

Netlify.tomlを設定しておくと、GUI上の設定を上書きしてくれる。

## next.config.jsに追記

```
/** @type {import('next').NextConfig} */
module.exports = {
・・・
  target: 'serverless', // 追記
}
```

普通にデプロイするだけだと、ルートページは表示されるけど、`pages/xxx/[id].tsx`のような動的なページは表示してくれない。
〇〇に潜む、△△

```ruby:hisomu.rb
#!/usr/bin/env ruby

`nkf /usr/share/mecab/dic/*/*.csv|grep ,名詞,>noun`
lim=3
n=`grep -oE ',[ァ-ンー]+,' noun|sort|uniq|tr -d ,`.split
puts "target,hisomu,hide,candidates", $*.filter{
  _1.size>lim-1&&_1 !~/\s/
}.map{|a|
  c=`echo #{a}|mecab -Oyomi`.chomp.chars
  (lim..c.size-1).map{
    c.each_cons(_1).map(&:join)
  }.flatten.filter{
    n.include?(_1)&&_1[0]!~/[ァィゥェォッャュョ]/
  }.map{
    r=`grep -E "^[^,]+,.*,#{_1}," noun`.split(?\n).map{|s|
      _=s.split(?,)[0]
      _ if a !~/#{_}/
    }.uniq.compact*?|
    [a,a+"に潜む",_1,r]*?, if r!=""
  }.compact
}.flatten.compact
```

```bash
$ chmod +x hisomu.rb
$ ./hisomu.rb 校内放送 林間学校 コインランドリー
target,hisomu,hide,candidates
校内放送,校内放送に潜む,ウナイ,宇内
校内放送,校内放送に潜む,イホウ,違法|彙報|医方|異邦
校内放送,校内放送に潜む,ホウソ,ホウ素|硼素|宝祚|法曾|法曽|訪ソ
校内放送,校内放送に潜む,コウナイ,港内|後内|口内|構内|行内|坑内|幸内|神内
校内放送,校内放送に潜む,ナイホウ,内包
校内放送,校内放送に潜む,ホウソウ,疱瘡|法曹|法曽|包装|奉送
林間学校,林間学校に潜む,リンカ,輪禍|燐火|隣家|リンカ|林下
林間学校,林間学校に潜む,カンガ,閑雅|官衙
林間学校,林間学校に潜む,リンカン,林冠|りんかん|輪かん|輪姦
コインランドリー,コインランドリーに潜む,コイン,雇員
コインランドリー,コインランドリーに潜む,インラン,いんらん|いん乱|淫乱
コインランドリー,コインランドリーに潜む,ランドリ,乱取り
```
iOS15のライブラリアップデート対応でやった事

初投稿となります。
iOSやAndroidの開発や保守等の業務を主に行っています。
iOSとAndroidを行き来したりしているのでよく忘れる内容や頻繁に起こらない事を主に書いていこうと思います。

### 本題
毎年恒例のiOSアップデートの対応ですが、久々にアップデート対応を行うことになったので
よく使われるライブラリの修正と参考にしたものを備忘録として残しておこうと思います。

##ライブラリ
よく使われるものは以下になるかと
※バージョンは2021/11/30時点のものを記載しています

### Carchage
 - Rx Swift (6.2.0)
  - https://github.com/ReactiveX/RxSwift
 - XCGLogger (7.0.1)
  - https://github.com/DaveWoodCom/XCGLogger
 - SwiftyJSON (5.0.0)
  - https://github.com/SwiftyJSON/SwiftyJSON

### Pods
 - R.swift (6.0.0)
  - https://github.com/mac-cain13/R.swift
 - Firebase (8.9.0)
  - https://github.com/firebase/firebase-ios-sdk

CarthageとPodsの更新は各ライブラリファイルのバージョンを変更して更新するだけなので割愛

## ライブラリ依存のコード修正
変更点は少なかったですが対応した修正の概要は以下

 - Swift5
  - Array参照のindex(of:)/index(where:)がfirstIndex(of:)/firstIndex(where:)に変更されているため置き換え <br>
    厳密にはswift4.2以降からの変更ですが、警告が発生していたので修正

 - Rx Swift
  - Single実行時の戻り値がSingleEventからSingleに変更されているため、<br>
    失敗時の.error, onErrorの記述を.failure, onFailureに置き換え
  - Single実行のエラー時、catchの記述がcatchErrorからcatchに変更されているので置き変え
  - .observeOnの記述が.ovserveに変更されているため置き換え
  
 - R.Swift
 　- プロジェクト設定が変更になったためTARGETSのBuild Phases内からBased on dependency analysisのチェックを解除し、<br>
 　  Inout Filesに記述されている$TEMP_DIR/swift-lastrunを削除する

---
ざっくりとはこんな感じです。
久々にライブラリ周り触ったので調査にやたら時間かかりました。
最終的にはライブラリのGitHub見に行くことが多かったのでもう少し英語読む練習しないとなぁ・・・
ASTERIA Warpを使ったkintoneからExcelへの簡単連携

# はじめに
kintoneでExcelファイルを出力することはできないようなので、ASTERIA Warpを使って手っ取り早く出力してみたいと思います。

#事前準備
- ASTERIA Warp
- kintoneアカウント　※開発者ライセンスの取得方法は[こちら](https://developer.cybozu.io/hc/ja/articles/200720464-kintone-%E9%96%8B%E7%99%BA%E8%80%85%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9-%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83-)から

#手順
今回はASTERIA Warpに用意されているフローテンプレートを利用してkintoneの「受注・売上管理」アプリのデータをExcelファイルに出力してみます。
まずは、kintoneのポータルでアプリの作成アイコンをクリックして…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/059fdc68-6dfa-4a7b-1429-f364a01cb1fb.png)
検索フィールドに「売上」と入力して検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/dad07ced-973d-26ba-8eb6-f1e2b45da53d.png)
受注・売上管理アプリの「このアプリを追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/5ff6bf0b-a489-c14d-7c95-591dc5f0036c.png)
アプリが作成できたので、適当にデータを入れておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/66c871c8-33cc-7603-d00d-53e838ca63b5.png)
次はASTERIA Warpの作業になります。
フローデザイナーで「コネクション作成」アイコンをクリックしてkintoneコネクションを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/a79bbc7e-d6f8-7c71-cbb1-485a35a3f3d8.png)
コネクションが作成できたら、「プロジェクトの作成」アイコンをクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/cddcd86b-469c-8091-48ae-f978b11ff4ae.png)
プロジェクトの作成ダイアログで「カテゴリー」アイコンをクリックして「kintone連携」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/2285c7d2-eeb7-87b2-d831-13d858fc8e16.png)
「kintoneからExcelへ」を選択して「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/4a6cb28f-c4ed-fd67-61e9-142265b480d2.png)
ウィザードが開始されるので、「アプリの選択」をクリックして「受注・売上管理」アプリを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/4563d34a-5268-78bb-6bfc-0e3f2b33ede4.png)
次の画面でExcelファイル名を入力して「完了」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/8348963f-9ced-4ed2-2b81-99369c2f70b8.png)
kintoneからExcelファイルに出力するフローが作成されています。機能がアイコンで表現されているので見た目で処理が何となくわかりますね。
それでは「実行」アイコンをクリックして実行！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/9687f3a1-c944-8d18-6249-77cb748ad43d.png)
ファイルペインにウィザードで指定したExcelファイルが出力されています。
開いてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/24033de0-0e34-f5d7-4102-a10689ae8641.png)
適度に装飾されていて見やすくなっているのではないでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/f68257f1-6731-fe8b-bdc3-694f1576020d.png)

#さいごに
今回使用したASTERIA Warpのフローテンプレートは「受注・売上管理」アプリの出力に特化していますが、他のアプリも出力できるといいですよね。そんな場合は、今回作成したフローに修正を加えていくのが手っ取り早いと思います。
Rubyのプログラムでピコの温度センサーを読みとりたい

この記事は[PRK Firmware Advent Calendar 2021 \- Adventar](https://adventar.org/calendars/7086)の12月10日のエントリです。

https://twitter.com/hasumikin/status/1466393539550453760?s=20

お声がけありがとうございます。書いてみました。

https://twitter.com/hasumikin/status/1466191090046750728?s=20

この記事を見て実際にやってみたら、あまりにも簡単にできてしまいました。

https://youtu.be/7Pu9usuZFUE

「温度センサーを読み取れないかな？」と思ってやってみたのですがうまくいかず、いろいろやっているうちに以下の記事が公開されました。

[回路図～プログラムまで自作するキーボード \- Qiita](https://qiita.com/aikawa_YO/items/a31353d88b8b73f51e8b)

ここに書かれている dev_js ブランチを使っていろいろやってみたのですがうまくいかず、「ADC4 を使えるようにしないといけないのかな？」と思って、Pico SDK ドキュメントを調べてみたり、 micropython sdk のソースコードを調べてみたりして、

[Raspberry Pi Pico SDK: hardware\_adc](https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__adc.html)

https://github.com/micropython/micropython/blob/master/ports/rp2/machine_adc.c#L92

「adc_set_temp_sensor_enabled というメソッドを追加してなんとかならんか？」と思って、見よう見まねで追加して、

https://github.com/kurod1492/prk_firmware/commit/e754c5801adf6ffc31602ef519d64c483d2639ba

Ruby のプログラムを作成して、実験してみました。

https://github.com/kurod1492/pico-tempsensor

実験の様子
https://youtu.be/AlK8r8b7FIk

温度センサーの情報が取れている？
コメントをいただきました。

https://twitter.com/morisuteisyon/status/1468594841605251072?s=20

https://twitter.com/hasumikin/status/1468847247517687809?s=20

コメントありがとうございます。検証してみます！
Rustで累積和を実装する

累積和を求めたかったのですが、学びたてで`scan`の使い方が怪しかったので改めてまとめました。
(数列)`Vec<T>` -> (累積和)`Vec<T>`の変換です。


コードは以下です。

```rust
let s = a
    .iter()
    .scan(0, |state, &x| {
        *state = (*state + x) % MOD;
        Some(*state)
    })
    .collect::<Vec<_>>();
```

scanの公式ドキュメントはこちら。

https://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.scan

軽い説明つきのコードがこちら。

```rust
let s = a
    .iter() // イテレータに。
    .scan(0, |state, &x| { 
    // 0が初期値、累積和を計算したいのでゼロ。
    // |state, &x|の1つめの引数は内部状態、2つ目はイテレータの要素
        *state = (*state + x) % MOD;
        // 内部状態にイテレータの要素を足して、MODの余りをstateに。
        Some(*state)
        // オプションをかえす。
    })
    .collect::<Vec<_>>();  // ベクタに。
```
没入するゲームデザインを考える【APE OUT編】

#概要
時間を忘れて遊んだゲームがゲーマーならありますよね。
今回はゲームに夢中になる理由を考え、ゲームデザイナー/ゲームプランナーの重要な**プレイヤーを惹き込む能力**に繋げていくためにも考えていこう。
##APE OUT
![APE_OUT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326034/0627e10f-47fb-71a4-d597-ca75991538d3.jpeg)
[Steam販売ページはこちら](https://store.steampowered.com/app/447150/APE_OUT/?l=japanese)
こちらのゲームを知らないという方はリンク先でPVなどを視聴して頂きたい。

高い暴力性を持ったこのゲームは**「掴む」「投げる」**という２つの要素が重要なゲームだ。
<br>まずこの２つの要素だけで「攻撃」と「防御」となるアクションは完結しており、プレイヤーは複数の手段から考える必要性が無くなり、とりあえず掴んで投げてたらあっさり殺せてしまい破壊衝動を刺激する。まさしく**ゴリラのように野性味溢れるプレイ**が楽しめるようになっている。ステージを進めるとあっさり殺せなくなる･･･というレベルデザインの話はまた別。
<br>今回は記事の主題であるAPE OUTの**没入感を高めている要素**となる***「破壊」***がいかに巧みな手法で組み込まれているか考えていきましょう。

### 1.即興ライブのような展開の速い殺し
このゲームはあっという間に人が死ぬ。プレイヤーのゴリラも死ぬ。
壁に向かって人間を投げるとすぐに死ぬ。
ゴリラは銃撃に３回当たると死ぬ。爆撃は１回で死ぬ。
しかし他の死にゲーとは違い**スピーディなゲーム展開**が「次の人間を殺すまでの速さ」に繋がっており、プレイヤーに「考えるよりアクションを起こして殺す！」と誘導しているため、慎重な行動が必要となる死にゲーと一線を画している。

慎重に行動して人間を一人一人殺す？**否！自分の行く先に居るヤツは殺す！！**

また、このゲームはBGMや効果音の全てが打楽器で表現されており、敵を壁に叩きつけた際は心地の良いシンバルが鳴り、気分を盛り上げてくれるのもまた「ライブ感」を高めている要素の一つにある。

### 2.次は殺す
上記で人間もプレイヤーもすぐに死んでしまうと書いたが、ゲームで死んだりしてやる気が削がれないように死亡した際に**自分がどれだけ進んだか**という情報が開示される。
![APEOUT_DEAD.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326034/871e40dd-2286-921b-c51c-370d72dd89a2.jpeg)
シャレオツ～～～～～～～～～～～～～！！
マップのゴールまでの道のりの情報も同時に判明するため、死んで少し冷静になったタイミングで丁度よく情報が頭に入ってくるのが**気持ちの整理とやる気の向上**に繋がっている。

プレイの見直し？**知らん！最終的に全員殺せばよいのだ！！！**

### 3.たまには知的に殺す
少し触れたレベルデザインだが、このゲームは大きいヤツほど強いというビジュアル面でもわかりやすい工夫を施しており、大きいヤツは散弾銃やガトリングガンを持っていたり、爆弾を抱えているモノが居る。

銃を持っているモノは悪用しやすい、「そいつを掴んだまま敵の方を向く」と勝手に銃を撃ってくれるのだ。やっていることはおぞましいが、私はゴリラなので人間を殺すことが正義なのである。

爆弾を持っている奴は取り扱い注意だ。壁にぶん投げたり銃撃を受けると広範囲に爆発し、巻き込まれると一発で死ぬからだ。もちろん裏を返せば敵を一掃できる必殺アイテムのようなモノだ。

ただ単純に殺すだけでは興が醒める、野性味を活かしつつ知的に攻めさせる。
**プレイヤーの感情を高ぶらせる**一味のスパイスである。

### つまり
このような工夫を施すことであらゆる面で「殺す」という要素に**プレイヤーの破壊衝動を駆り立て**、ゲーム内のゴリラのように**野性味溢れる爽快感ドバドバの没入感**を味わえているのだ。

いかにプレイヤーに楽しませたい要素を深堀りし、どのような感情にさせたいかをよく考えて制作していくことで強い没入感のあるゲームデザインができるのである！


#総括
以上のような方法を用いて、ゲームを通じて多くの人を楽しませる唯一無二の没入感が味わっているのだ。

他にも没入感を生む要素としては「ストーリー」や「キャラクターの生き様」などの**操作以外の手法を用いるモノ**や、「ゲームのアクションと同じ動きを行う」ことで生まれる**体感・直観操作**などもあるだろう。

対戦ゲームなどは没入するというよりかは、「熱中」や「没頭」に近いが、似た思考でゲームに惹き込める面白いデザインが考えることができるだろう。

気が向けば他のゲームを用いて考察してみようかと思います。

以上。**終焉。**
腰痛との付き合い方

#はじめに
皆さん、こんにちは。自分は産技短に入って８か月がたちました。授業はほとんどがPCを使っての実習です。なので自分は腰痛に悩まされています。

この記事には、自分の腰痛分析と対策、効果をかかせていただきました。自分と同じ腰痛持ちの方に価値ある記事になればと思います。

#腰痛の原因
腰痛になる原因は、やはり姿勢です。自分は授業中の椅子の座り方がすとても悪いです。

#椅子の座り方
自分は主に2種類の座り方をしています。1つ目は、お尻がずれ落ちて、背もたれに強く寄っかかる座り方です。疲れてくると、背もたれに寄っかかることでお尻がずれてしまうようです。

2つ目は、前かがみになって猫背状態になってしまう座り方です。机に肘をついていると、だんだん体が机に近づいていって、Cの字になってしまうようです。

#対策と効果
まず、1つ目の座り方を治そうと思いました。寄っかかるのが悪いので、寄っかからないように意識した結果、だんだん前かがみになっていって、2つ目の座り方になってしまいました。また、2つ目の座り方を治そうとしたら、結果1つ目の座り方になってしまいました。

なので、さらに考えた結果、どちらの座り方も机や背もたれといったものに体重を乗せてしまっていることに気づきました。また、椅子との接触面を小さくすれば負荷が減るのではないかと考えました。そして、最終的に上半身と下半身の角度が90度になる座り方がいいという結論に至りました。つまり、何にも体重を乗せることなくお尻の骨の部分のみを接触させるということです。結果、だいぶ腰痛を和らげることに成功しました。1つ目と2つ目の座り方は必ず前や後ろに傾いた状態になるため、どうしても負荷がかかってしまうようです。

#終わりに
今回、自分の腰痛分析をしてみて、専門的なことはわかりませんが、自分なりに考えて腰痛を緩和させることができてよかったです。現在は、もともとの座り方の癖がなかなか治らず、ダメな座り方をしてしまうこともあります。自分の癖を治すのって難しいですよね（笑）。それでも、この座り方を意識しながら、これからの日々の授業も頑張っていきたいと思います。