OmniAICreator/Qiita-1.07M huggingface dataset:
MATLABのコマンドウィンドウを使いこなそう

2回目のMATLAB記事です。

今回はコマンドウィンドウについて解説します。

コマンドウィンドウは言わば”自由帳”であり、使いこなすとかなり便利な存在です。



# コマンドウィンドウ

コマンドウィンドウとは下の画像に示す通り、真ん中の真っ白な部分です。

”コマンドウィンドウ”とちゃんと書いてあるので、まず間違うことはないでしょう。

「fx >>」という部分にコマンドやプログラムを打ち込めばそれを実行をしてくれます。

この記事の主旨は、これを適宜使おうというものです。

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/7efc43f4-1c7b-056b-309a-78da5c95a1df.png)




# clcコマンドとclearコマンド

コマンドウィンドウを真の意味で自由帳にするのが「clcコマンド」と「clearコマンド」です。

両者はMATLABにおける”消しゴム”の役割を持ちます。

コマンドウィンドウにプログラムを入力するだけでは、紙と鉛筆だけを用意しているのと同じようなものです。

## clcコマンド

**コマンドウィンドウを真っ新な状態にするコマンド**です。

実行結果などがたくさん表示してあって一度綺麗にしたいと時に有効です。

以下のようにコマンドウィンドウに打ち込んでエンターキーを押すだけで簡単に実行できます。

```matlab
>> clc
```


実際に使ってみましょう。

例えば 2+3 という演算を打ち込んで実行すると、ansという変数に 5 が格納されます。

実際、ワークスペースにansという変数を確認できますね。

![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/d5d3f80d-848a-732f-3a3a-94d34581d640.png)

MATLABでは**自分で変数を用意しなかった場合、演算結果がansという変数へ自動で格納される**仕組みになっています。

では、clcコマンドを使ってコマンドウィンドウを真っ新にしてみましょう。


![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/57a7966a-789f-3b30-2a5b-550cdd2558c5.png)

すると表示してあったものを全て消すことができました！

![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/dd4485cf-1ad4-eb4b-23d8-80c6138c3bb2.png)


なお、変数ansはワークスペースから消えていないことが分かると思います。

## clearコマンド

**ワークスペースにある変数を全て消去するコマンド**です。

clcコマンドと同様、以下のようにコマンドウィンドウに打ち込んでエンターキーを押すだけで簡単に実行できます。

```matlab
>> clear
```

では実際に使ってみましょう。

先ほど残った変数ansを消去してみます。

![fig5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/aca38506-0674-43d5-bc3a-d6adcc11fe7c.png)

無事に変数を消去できました。

![fig6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/fb4f5290-5937-907c-2c74-8c3acbf66339.png)


# コマンドウィンドウの活躍場面

個人的にコマンドウィンドウを活用する場面は三つあります。

一つ目はmファイルを作るまでもないようなプログラムを実行する時です。
例えば1行～3行程度で終わるなら、わざわざmファイルを作るよりコマンドウィンドウを使った方が早いです。

二つ目はfigureに関するものです（figureとは図やグラフのことです）。
プログラムを実行して図やグラフを表示した後で、タイトルやラベルといった細かい設定を忘れる事があります（もしかして私だけ？）。
普通ならその部分を追加してもう一度プログラム全体を実行すれば良いのですが、全体が長いプログラムで、かつ追加するのがたった1～3行だともう一度実行するのが面倒に思いませんか？
その時、コマンドウィンドウに打ち込めば再度プログラムを実行しなくても設定を反映してくれるのです。
たまに出番があるので覚えておくと便利です。
近いうちに説明しようかなと思います。

三つ目は複雑、あるいは長いプログラムを理解する時です。
この変数はどんな値、あるいはサイズになるのか。
この部分は一体どんな動きをするのか。
プログラムを理解する時、これらを細かく確認したい時があるでしょう。
そこで、その部分をコマンドウィンドウにコピペで実行するのです。
自由帳としてのコマンドウィンドウの活躍はここかもしれません。

なお、先ほど説明したclcコマンドとclearコマンドはこういう状況で適宜利用することで有用なコマンドとなるわけです。

:::note info
ポイント：コマンドウィンドウは便利な自由帳である。
:::

# 終わりに

私は頭の中で数式を変形したり移項したりすることが苦手です。

簡単な四則演算なら（フラッシュ計算を除いて）暗算できるのですが、数式になるとそれができません。

大学の講義では複雑な数式がたくさん出てきて、頭だけで追いつくなんてとても無理でした。

だから勉強の時は基本的にノートやルーズリーフを使って途中式や途中過程を書きだしていました。

私のような人間にとってはこの方法が効率的なのです。

プログラムでも同じことが言えます。

未知の長いプログラムを頭の中で動かすことが苦手なので、コマンドウィンドウを使って確認しながら理解しています。

蛇足ですが、SF作品である人間が自分の脳をコンピュータに置き換えるという描写があったような気がします。

そうすることで人間の脳の何百倍の計算スピードを得られたわけです。

もちろん忌避する方もいるでしょうが、私はノーリスクなら置き換えてみたいなと（笑）

※本記事に対する改善点や修正点、またはこんな事が知りたいといったご意見がありましたらぜひご連絡ください。

# 参考HP

https://jp.mathworks.com/?s_tid=gn_logo
remote.itで親のスマホメンテ(のための事前テスト)



※この記事はQiitaEngineerFesta 2022 [「remote.it を使って○○に接続してみた！」](https://qiita.com/official-events/8a2ab08f6fa0f093ae39)に参加するために執筆した記事です。
今回はAndroidスマホに接続してみました。

# Remote.itについて

ネットワークの設計不要で対象機器に簡単に接続できるサービスです。
外から自宅に繋ぎたい、もしくは自宅から何処かに繋ぎたい場合、
ネットワークを考えたりする必要がありますが、
これはそういった面倒なことを考えずに安全に接続ができます。


https://ja.remote.it/

# やりたいこと
+ 親が使っているスマホ(Android)のリモートメンテナンス(アップデート、不要なアプリの削除等)

# 背景
久しぶりに実家に帰って親からスマホのメンテナンスを頼まれてみたところ、謎のクリーナアプリや漫画アプリ等がインストールされ、スマホのストレージを圧迫。(本人曰く勝手にインストールされたとかされてないとか)
とりあえず謎アプリやファイルを削除したことで一旦は解決したものの、たまにしか帰るタイミングがないことや遠隔での緊急での対応ができないため、手間がかからないソリューションを探していました。今度帰るときにサクッと設定が出来るように、今回は自分の手元にある環境でテスト環境を構築してみました。


# 構成

+ 自分のPC(Mac)
+ 接続先スマホ(Android, モバイル回線)
+ Remote.itのアカウント

実家光回線を引いていないのでモバイル回線のみ。
モバイル回線でも簡単に接続できるのか確認してみます。

# [スマホ]アプリのインストール
###  Remote.itのインストール
アカウントの作成と自分のPCへのインストールについては他の方も書かれているので省略します。
接続先となるスマホに、Remote.itのアプリをインストールします。

https://play.google.com/store/apps/details?id=com.remoteit

インストール後に自分のアカウントでログインします。

###  doroidVNC-NG
色々とVNCアプリはありますが、Remote.itでの接続実績があるアプリということで
こちらのアプリをインストールします。

https://play.google.com/store/apps/details?id=net.christianbeier.droidvnc_ng&hl=ja&gl=US

サービスの開始は忘れずにやりましょう。（以下のスクショは開始後の状態）
![スクリーンショット 2022-07-18 23.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200797/9a3e57b9-e00f-95f3-e1a9-4276459b8831.png)

### VNCサービスの確認
Remot.itのアプリを開き、This Deviceが「VNC is running on this device」になっていればOKです。
![スクリーンショット 2022-07-18 22.50.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200797/f1064125-419e-4983-db60-f08b16bdb2b5.png)



# [PC]接続
[PC] Remote.itのアプリを立ち上げ登録したデバイスの状態を確認します。
![スクリーンショット 2022-07-18 23.05.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200797/8a8e54f8-fa36-95af-db2e-4dfcda4e8fbf.png)
[PC]アプリからLanch VNCを押し、droidVNC-NGにて設定したパスワードを入力します。
![スクリーンショット 2022-07-18 23.06.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200797/ff2d616d-080f-001e-4d50-37781f8580fe.png)
[PC]接続できると以下のような表示が出てきます。
![スクリーンショット 2022-07-18 22.48.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200797/802516fb-d3e9-140a-3e39-905675071f22.png)



# おわりに
とりあえず手持ちの環境で接続ができることがわかりました。
今度実家に帰ったときにでも親のスマホにセットアップしてみたいと思います。
Androidのナビゲーションバーが出ていないとマウスで操作しにくいので、
事前に出しておいた方が安全かもしれません。

# 参考にした記事
[remote.itを使ってAndroid製見守りカメラを作ってみた](https://qiita.com/senbishi/items/056e993a33932951fead#)
コードを短く書く小技

指定の文字列かどうかを判定したい
```javascript
const color = 'red';

// before
console.log(color === 'yellow' || color === 'red' || color === 'blue');
// after
console.log(['yellow', 'red', 'blue'].includes(color));
```

引数の値に紐づく値を取得したい
```javascript
// before
const translate = colorName => {
  switch(colorName) {
    case 'red':
      return '赤';
    case 'blue':
      return '青';
    case 'yellow':
      return '黄';
    default:
      return '翻訳不可';
  }
}

// after
const translate = colorName => ({
  'red': '赤',
  'blue': '青',
  'yellow': '黄',
}[colorName] || '翻訳不可')

// 実行例
translate('red');
```
年/月/日 の一部が省略された日付をパースして LocalDateTime を取得する方法

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/2022/07/18/233301) とのマルチポストです）

# 年が省略されている日付（`月/日`）の場合

まずは、[DateTimeFormatter](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/time/format/DateTimeFormatter.html) を用意します。
```java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd");
```

次に、日付を [**MonthDay クラス**](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/time/MonthDay.html)でパースします。
```java
MonthDay monthDay = MonthDay.parse("07/18", formatter)
// ==> --07-18
```

それに、 **現在の年**を付け加えます。
```java
LocalDate date = Year.now().atMonthDay(monthDay);
// ==> 2022-07-18
```

最後に、[LocalDate#atStartOfDay()](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/time/LocalDate.html#atStartOfDay()) で日付を `00:00:00` に設定すれば、[LocalDateTime クラス](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/time/LocalDateTime.html) が取得できます。
```java
LocalDateTime dateTime = date.atStartOfDay();
// ==> 2022-07-18T00:00
```

# 日が省略されている日付（`年/月`）の場合

[**YearMonth クラス**](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/time/YearMonth.html)を使うぐらいで、あとは月日の場合と大体同じです。

```java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu/MM")

YearMonth yearMonth = YearMonth.parse("2022/07", FORMATTER);
// ==> 2022-07

LocalDate date = yearMonth.atDay(1);
// ==> 2022-07-01

LocalDateTime dateTime = date.atStartOfDay();
// ==> 2022-07-01T00:00
```
herokuでのdocker-compose.ymlの参照範囲についての検証結果

# はじめに
前回下記のようなものを投稿していました。

::: note info
herokuでイメージ・コンテナ作成するときは「docker-compose.yml」の「ports」って利用していないのでは？
:::

https://qiita.com/std-flower/items/31452e3a428355014721

# 検証方法
前回までは、テスト環境側のホストOSの環境変数、および本番環境であるherokuの環境変数に[wk_port]を追加し、下記の設定とした。
 - テスト環境：8888
 - 本番環境　：未設定

docker-compose.ymlは下記の状態

::: note info
今、どっちの環境で動作してますよ、の判断を[wk_port]で行おうとしていた。
:::

```docker-compose （修正前）.yml
version: '3'

services: 
 ＜サービス名＞: 
  build: 
   dockerfile: ./Dockerfile
  ports:
   - $wk_port:$wk_port
  environment: 
   wk_port: $wk_port
```
ただ、本番環境（heroku）では[wk_port]が未設定にもかかわらず、アプリケーションは動作していたので、本番環境（heroku）では「ports」は利用していないと断定。

___
docker-compose.ymlは下記の状態に修正

::: note info
今、どっちの環境で動作してますよ、の判断を新規の環境変数[mode]で行うように修正。
かつ、「ports」は「8888:8888」に修正し、テスト環境でのみポートフォワーディングとして利用。
:::

```docker-compose （修正後）.yml
version: '3'

services: 
 ＜サービス名＞: 
  build: 
   dockerfile: ./Dockerfile
  ports:
   - 8888:8888
  environment: 
   mode: $mode

```
::: note info
Flask起動の判断も環境変数「mode」で行うように修正。
＜　補足：modeの値　＞
　テスト環境：dev
　本番環境　：pro

:::
```hello.py
from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return 'hello world3'

if __name__ == '__main__':
    if os.environ.get('mode','')=='dev':
        app.run(debug='true',host='0.0.0.0',port='8888')            
    else:
        app.run(debug='true',host='0.0.0.0',port=os.environ.get('PORT','5000'))
```

# 検証結果
うまくいきました。

<b>ということで、herokuでイメージ・コンテナ作成するときは「docker-compose.yml」の「ports」って利用していない！ということですね </b>
Pythonチュートリアルで学ぶ：Pythonインタプリター

単純作業の自動化に興味があり、PythonとVBAを勉強しています。
ついでに資格も取れたらいいなー、ということで公式テキストで勉強することにしました。

PythonをPCにインストールした状態でコマンドプロンプトを開き
(環境はWindowsです。)

```
python 3.10
```
のように入力するとPythonインタープリタと呼ばれる対話型の
環境が開きます。

そこにPythonを入力すると以下の画像のような感じで、すぐに実行してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725725/1546ab2e-f930-f6f2-c9ee-80a9612a5347.png)

最初のほうの章なので簡単な内容でした＾＾
React18で新しく導入されたuseTransitionとuseDefferedValueの使い分け

現在QiitaではQiita Engineer Festa 2022が開催中です。当記事もエントリーしております

https://qiita.com/official-campaigns/engineer-festa/2022

最近React18がリリースされたようです

React18に関しては@uhyoさんに非常に参考になる記事を投稿していただいてます

ただ、いまいちuseTransitionとuseDefferedValueについて理解できていませんでした

そこで今回はこれらのHooksについて自分で内容をまとめてみたいと思っています

https://qiita.com/uhyo/items/6be96c278c71b0ddb39b

ちなみに、この記事ではconcurrent modeがリリースされるかもしれないが未定と書かれていますが、現在の正式リリースでは「mode」という考え方自体がなくなり、concurrent modeのみが標準として組み込まれています

# useTransitionとuseDefferedValueの具体的な使い方

まずはそれぞれの使い方に関して確認しましょう

## useTransiton

以下のコードはinputのテキスト入力後、レンダリングに関するリソースに余裕のある段階でコンポーネントが再レンダリングされるという仕様になっています

つまり**テキスト入力によるstate変更で引き起こされたpostsの再レンダリング優先度を低くする**ということです

```tsx
export default function Home() {
    const [isPending, startTransition] = useTransition();
    const [keyword, setKeyword] = useState('');

    // Web APIからキーワードでフィルターした投稿一覧を取得
    const filteredProducts = filterKeyword(keyword);

    const updateKeyword = (e) => {
        startTransition(() => {
            setKeyword(e.target.value);
        });
    }

    return (
        <div id="app">
            <input type="text" onChange={updateKeyword} />
            {isPending && <p>Updating List...</p>}
            <PostsList posts={filteredPosts} />
        </div>
    );
}
```

## useDeferredValue

続いてuseDeferredValueです

以下のコードは非同期で受け取ったPropsであるpostsを遅延してレンダリングを行っています

propsから値を受け取った時点ですぐにレンダリングするのはなく、**postsをレンダリングする優先度を他のコンポーネントの描画優先度より下げる役割を担っています**

```tsx
function PostsList({ posts }) {
  const deferredPosts = useDeferredValue(posts);
  return (
    <ul>
      {deferredPosts.map((post) => (
        <li>{post}</li>
      ))}
    </ul>
  );
}
```

# useTransitionとuseDefferedValueの違い

上記の例で示した通り「useTransition」はstateを更新する処理をwrapして遅延させるのに対し、「useDeferredValue」はstateの値をwrapして変更を遅延させています

以下基本的な使い分けに関しての結論です

keywordのように**更新中のstateを読み込む必要があるのであればuseTransitionを、逆に読み込む必要がないのであればuseDeferredValueを使えば良い**のではないかと思っています

それでは全ての非同期処理で受け取る値をuseTransitionやuseDeferredValueでwrapすればいいのではないかという話になるのですが、それは控えた方が良さそうです

先ほども述べたように「レンダリングに関するリソースに余裕のある段階」なので、非同期処理によるstate管理が煩雑になることが考えられます

あるときはstateが更新されているが、あるときはされていないというようなバグを引き起こさないためにも頻繁に使うようなhooksではなさそうです

あくまでもパフォーマンスチューニングという観点で、stateの変更を遅延させることが適切かどうか判断してから使用するようにしましょう
#2　変数

参考 -> https://www.youtube.com/watch?v=ukNoszW09BI&list=PLru8-xuz0YvyZhvDRZvakIFW6-MHky-lD&index=3
# 学習内容
変数について。
```java
public class Hensuu{
   public static void main(String[] args) {
      boolean bln = true;
      char ch = 'a';  //シングルクォーテーションを忘れない
      byte by = 3;
      long lo = 96l;  //末尾に"l"(L)を忘れない
      float fl = -35.2f;  //末尾に"f"(F)を忘れない

      System.out.println(bln);
      System.out.println(ch);
      System.out.println(by);
      System.out.println(lo);
      System.out.println(fl);
 
   }
}
```
```
/* 実行結果 */
true
a
3
96
-35.2
```
## 変数
文字列や数値などのデータを格納する "箱のようなもの" で、処理をするときに多用する。
変数を利用するには、"箱の名前(変数名)" と "どんな種類のものを入れるか(型)" を用意する。

#### 変数の扱い方
#### 1. 宣言(箱をつくる)
```java
データ型 変数名;
```

__変数名の注意点 ↓__
* 半角英数字、アンダーバー(_)、ダラー($)を使用して書く。
* 頭文字は数字を使ってはいけない
* プログラム内で同じ変数名を使ってはいけない
* 予約語の単語は使ってはいけない
* 大文字と小文字は区別される

__基本データ型一覧__
|データ型|内容|
|:--:|:--:|
|boolean|true または false|
|char|UNICODEの文字を表す。(1文字のみ) "u0000" ～ "uffff"|
|byte|バイト型。"-128～127" を表す。|
|short|短整数型。 "-32768～32767" を表す。|
|int|整数型。 "-2147483648～2147483647" を表す。|
|long|長整数型。 "-9223372036854775808～9223372036854775807" を表す。|
|float|単精度浮動小数点型。 "±3.40282347E+38~±1.40239846E-45" を表す。|
|double|倍精度浮動小数点型。 "±1.79769313486231570E+308~±4.94065645841246544E-324"を表す。|

__参照型__
めっちゃいっぱいある。
書き方は基本データ型と一緒だが、最初の文字は大文字。

__基本データ型と違い、"データ自体が変数に格納されるわけではない。"__
データ -> 別のメモリ領域に格納される。
変数 -> データの居場所(参照値)が格納される。


#### 2. 代入(箱にデータをいれる)
```java
変数名 = 値;
```
"=" は同じという意味ではない。
"変数" に "値" を "代入する" という意味なので注意。

#### 3. 参照(箱の中身を取り出す)
```java
int a = 5;
System.out.println(a);
```
ワンライナーでPLATEAUのOBJファイルをちょっと使いやすくする

# はじめに

PLATEAUの公式で配布されているOBJファイルは、平面直角座標系で作られていて、
そのままモデリングソフトやゲームエンジンに読み込むと、とんでもない場所（正しい場所なんですけどね）に配置されます。

これをうまく調整するには、3DCGソフトなどで編集するか、読み込んでからオフセットをかける必要がありますが、
元データの座標値が大きいと、計算誤差の蓄積なども心配になります。

そこで、本稿では、どこのご家庭にもあるawkのワンライナー一発で、OBJファイルにオフセットをかけ、任意の原点にモデルを持ってくる方法を解説します。

# awk

どこのUNIX系にも必ず入ってる老舗ツールですね。
1977年に3人の大先生によって開発されたテキスト加工ツールです。
今回はこれを使ってOBJファイルを加工しましょう。
なお、awkはすでにインストールされている前提ですが、入ってない場合は、Windows環境の場合だと思いますが、
gitを入れるのが楽だと思います。gitをインストールするとgit-bashという環境が一緒にインストールされ、その中にawkも含まれます。

# 準備1　ファイルダウンロード

[PLATEAU公式](https://www.geospatial.jp/ckan/dataset/plateau)から使いたい地域のOBJファイルを落とし、圧縮ファイルを展開して目当てのOBJファイルを探してください。
今回は、東京駅近辺を変換してみます。東京23区のPLATEAUデータの、lod1objの53394611_bldg_6677.objを使ってみましょう。

# 準備2　原点の確認

国土地理院の[測量計算サイト](https://vldb.gsi.go.jp/sokuchi/surveycalc/surveycalc/bl2xyf.html)で、原点の座標を取得します。

以下の図を参考に、

- 「地図上で選択」
- 「系番号」
- 「地図上の位置」（今回は東京駅にしてみました）
- 「計算実行」

をしてみてください。右側の計算結果の出力値のX座標とY座標を使います。
今回は東京駅を原点とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30257/67339dc8-f625-cbcb-173b-884f1d2a55c6.png)

# 変換

おもむろにコマンドラインで、以下を実行します。ファイル名とオフセットの座標値は適宜変更してください。
$2にY座標、$3にX座標を「引き算」します。

```bash
$ cat 53394611_bldg_6677.obj | awk 'BEGIN{OFMT="%.11g"}{if($1=="v"){print "v",$2+5947, $3+35369, $4}else{print $0}}' > tokyost_test.obj
```
これでオフセットをかけたOBJファイルが作成できました。

# Unityで読み込む

普通に読み込みましょう。読み込むと変な回転がかかっていると思うので、適当にRotationを調整します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30257/3978476b-587e-d94d-c8e2-7e0f3d8e9646.png)

ちなみに、オフセット調整なしのも読み込んで比較すると以下のようになります。
上が原点付近に置かれているオフセット調整されたもの。下がされていないものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30257/f5f48eaf-d7af-3f85-0fc8-067765ac9898.png)
ERPでビジネスはどう変わる？

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# ERPとは
ERPはEnterprise Resources Planningの略で、`企業経営の基本となる資源要素(ヒト・モノ・カネ・情報)を適切に分配し有効活用する計画`を意味します。現在では特に __基幹系情報システム__ を指すことが多いです。



# ERPでビジネスがどう変わる？
### ■情報の一元管理
ERP最大の強みはなんと言っても __情報の一元管理__ でしょう。営業部門が使用する販売管理用システム。製造部門が使用する在庫管理システム。人材管理部門が使用する会計システム等、各部門でシステムを選定し導入している企業もあると思います。もちろん、個別の部門毎に最適なシステムを導入することにメリットもあります。例えば、一部に特化させた方がその部門に本当に必要なシステムにしやすかったり、カスタマイズしやすいといったものが挙げられます。しかし、ERPでは、全部門に同一のシステムを導入することで、 __全体最適__ を目指す事ができるシステムなのです。ERPで実現できる全体最適とは次のようなものが挙げられます。
※ニーズに応じて部分単位の機能(モジュール)のみを導入することも可能です。
- 情報の一元管理で意思決定をスムーズ化
意思決定をする際に、わざわざ各部門で使用しているそれぞれのシステムから情報を集める必要がないためスムーズに情報を集め、意思決定につなげる事ができます。
- 入力処理削減
例えば各販売店で使用している会計システムと、倉庫で使用している在庫管理システムが連携されていない状態であれば、会計システム上の在庫が変更しても、倉庫の在庫管理システムにはなんの変化もありません。`商品を売り上げたという情報を、人が在庫管理システムに入力することで、初めて店舗の会計システムと倉庫の在庫管理システムの整合性がとれる`のです。それがERPを使用して、全部門共通のシステムを使用することで、 __人を介すことなく、自動で会見システムと在庫管理システムを連携__ する事ができるのです。
- システムのメンテナンスが容易
ERPは、全社的に使用するためシステムの規模は大きくなりますが、あくまでも1つのシステムであるため、個別のシステムとして対応する必要がなくなります。そのため、例えば情報システム部門だけで全部門にわたって使用されるソフトを管理する事ができ、メンテナンスが容易になるだけでなく、人件費の削減にもつながります。


# 終わりに
この記事ではERPのメリットをお伝えしたかったため、全体最適を目指す事がベスト。というな内容になりましたが、全体最適にも弱点はあります。通常は部分最適を目指すと、企業としての成果よりも、各部門、格個人としての成果を目指すため、全体として見ると誤った方向に進んでしまう可能性もあると言われています。しかし、全体最適を目指すために、不必要な部門や個人は切る。というようなやり方をしていてはどうでしょうか。全体で見ればそれが利益につながるのでしょうが、切られた側からすると不満が残ります。少し話がそれましたが、ERPを導入する際には、全体最適を優先するために個人や各部門が蔑ろにされていると感じないような仕組みが必要だと個人的には思います。

最後までお付き合いくださりありがとうございました。
Salesforce_ダッシュボード作成


## ダッシュボードとは

レポートをベースに複数のグラフを表示することで、業務の全体像を把握できる機能を指します。個人や社内全体のデータを幅広い観点から分析し、状況をリアルタイムで把握するのに役立ちます。


## ダッシュボード作成手順

1,「新規ダッシュボード」クリックして、ダッシュボードエディタを起動。

2,エディタの画面上でドラッグ＆ドロップの操作を行い、必要なコンポーネントを追加。
各コンポーネントは、コンポーネントエディタ上でグラフ形式の変更や、詳細設定が可能です。

3,カスタマイズが完了したら、「保存」ボタンをクリックするだけです。

この手順だけで簡単にダッシュボードの作成ができます。
作成したダッシュボードを編集するには、ダッシュボード一覧の画面で既存のダッシュボード名をクリックしましょう。
管理画面では、不要なダッシュボードの削除も行えます。



## まとめ

Salesforceのダッシュボード作成について説明しました。ダッシュボードの機能があれば、複数の重要なデータを一覧表示させられるため、蓄積されたデータを有効活用しやすくなります。
awsでec2インスタンスにsshできるようになるまで

タイトルの通りec2インスタンスを作ってそこにsshするまでの記事です
間違いがあれば指摘いただけると嬉しいです

## まずはVPCを構築
VPCなどを選択してそれぞれを入力する

### ここまでのしらべたメモ
#### AZ
あとから追加できるみたいなのでこの段階でいくつにするかをあまり考える必要はなさそう
追加の時の手間を考えなければだけど
#### パプリックサブネットの数
これはvpcに割り当てられるpublic subnetの数、あとから追加もできる
なんで0 or 2なんだろう？0で利用されるケースってどんなだろうか
2は1つはec2としてもう一つは何を想定してるんだろう？調べたけどいまいち確信持てなかった
#### プライベートサブネットの数
これはvpcに割り当てられるprivate subnetの数、あとから追加もできる
#### パブリック、プライベートサブネットの見分け方
サブネットの内容を見てたら名前以外にどこで判断するのかなって思ったらパブリックのルートテーブルにigwが設定されていたのでここで判断できそう

## EC2インスタンス作成
ネットワーク設定で作成したvpcを選択、キーペアは作った、セキュリティグループは新規を選択。
その他はとりあえず名前以外デフォルトのままでインスタンス作成。生成には少し時間がかかるので待つ
## パブリックIPの設定
パブリックIPの自動割り当てを有効がデフォルトは無効だった
この状態だとsshするためのパブリックIPがないのでElastic IPを作って設定してやる
### ここまでのメモ
#### パブリックIPの自動割り当てを有効
・「パブリックIPの自動割り当てを有効」にすれば最初からパブリックIPが設定されているのでElastic IPを設定する必要はなくなる
・パブリックIPは動的に割り振られてインスタンス再起動のたびに値が変わる
・後から「パブリックIPの自動割り当て」を設定することはできない
#### Elastic IP 
・静的なIP
・生成したIPは利用していない場合料金が発生するので注意
## SSH実行
ここまでで出来たらsshを実行してみるも失敗した

####インバウンドグループ
・別ホストからのアクセスのコントロール
####アウトバウンドグループ
・別ホストへのアウトバウンドトラフィックのコントロール
※アウトバウンドトラフィック = ネットワークを流れるデータのうち、中から外に出ていくデータのこと

```
ssh -i "test.pem" ec2-user@ec2-hoge-hoge-hoge-hoge.ap-northeast-1.compute.amazonaws.com
ssh: connect to host ec2-hoge-hoge-hoge-hoge.ap-northeast-1.compute.amazonaws.com port 22: Connection timed out
```

## 調査した結果
原因はサブネット、privateを割り当てたためインターネットからアクセスできない
ec2はサブネットの変更ができないみたいなので作り直す
インスタンスを右クリック ＞ イメージとテンプレート ＞ 同様のものを起動
以下の条件で作成
・サブネットがpublicなものを割り当てる
・今回はパブリックIPを有効にする
・セキュリティグループは先ほどのものを使用

ここまで出来たらssh実行
```
ssh -i "test.pem" ec2-user@ec2-hoge-hoge-hoge-hoge.ap-northeast-1.compute.amazonaws.com
```
接続できた
```
[ec2-user@ip-hoge-hoge-hoge-hoge ~]$
```

## 備考
本当はもっとスクショを用意してたけど表示情報を調べたら割と良くない情報が表示されてたので泣く泣く削除
アカウントIDとかみんなも気を付けてね

#### 忘れないように今回利用したものは削除しておく
・EC2インスタンス
・Elastic IP
・VPC

以上！
【#33 エンジニア転職学習】Go WebApplications　Handler

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

使用しているGoのUdemy教材後半部分である、
Webアプリ作成演習を学習していきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はGoのwebアプリ用標準パッケージ、アプリ開発に向けての準備等を学習しました。

* templateキャッシュ
* **Handler　<--Topics!**
* ビットコインについて
* config, log のini設定

# Handler

```go
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {                                                                          ---> 9
	return func(w http.ResponseWriter, r *http.Request){
		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
```
#### GoのWebApplicationsにも出てくる上記のようなmakeHandlerについて
`http.HandleFunc`が引数として`http.ResponseWriter`と`http.Request`しか受け付けないので、
第三引数としてstringを加えて、オリジナルのHTTP`HandlerFunc型`として返すようにviewHandler等をwrapする役割
* fnとしてResponseWriter、Request、stringを引数にとる
* **mに`http.Request`のURLPathと一致する文字列の/edit｜view｜save/以降の文字列を、`FindStringSubmatch`関数のルールに則ってスライスにして返す**
* mがnilの場合はNotFoundとしてエラーを返す
* **問題なければfnとして`m[2]`の値（`validpath`で取得した`^/(edit|save|view)/([a-zA-Z0-9]+)$`のURLを`FindStringSubmatch`でスライスに切り分けた最後の値）を含むHandlerfunc型を返す**


使用している教材はこちら↓


https://www.udemy.com/course/go-fintech/


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
Pythonの論理演算子andとorは必ずしもbool型を返さない

研究やらで数年間Pythonを書いてきたのに知らなかった。
備忘録として残しておきます。初心者なので細かい点はご容赦ください。

普通、A and B、A or B(言語によってはA && B、A || Bなどの場合も)は、AとBの論理演算を行った結果を返します。
つまり、A、B、演算結果はすべて真偽値となり、Pythonではbool型となる……と、思っていました。

しかし、実際には以下のようなプログラムも実行できます。
```python
x = 1 and 2
print(x)

y = "かぶと" or "くわがた" 
print(y)
```
```text:実行結果
2
かぶと
```
ご覧の通り、数値や文字列に対してもand・or演算子が機能し、またbool型ではない結果が返ってきています。

これは、Pythonでは、A and B及びA or Bが次のような仕組みになっていることに由来します。
```python:A and B
if not bool(A): # Aをbool型に変換した結果がFalseの場合
    return A # Aを返却(Aをbool型に変換した結果ではない！)
else: # Aをbool型に変換した結果がTrueの場合
    return B # Bを返却(これもBの変換結果ではない！)
```
```python:A or B
if bool(A): # Aをbool型に変換した結果がTrueの場合
    return A # Aを返却(Aをbool型に変換した結果ではない！)
else: # Aをbool型に変換した結果がFalseの場合
    return B # Bを返却(これもBの変換結果ではない！)
```
`bool()`は引数をbool型に変換する関数です。
これによってA、Bをbool型に直してから評価し、返却する時には元の値をそのまま返す、という動きをします。
よってA、Bがbool型でなくても機能しますし、返却される値はbool型とは限らない、というわけでした。

`bool()`によってTrue、Falseと判断される値には、それぞれどんなものがあるのでしょうか。
[公式リファレンス](https://docs.python.org/ja/3/library/stdtypes.html#truth)では以下のもの、もしくは省略された場合にFalseとなり、
* 偽であると定義されている定数: `None`, `False`
* 数値型におけるゼロ: `0`, `0.0`, `0j`, `Decimal(0)`, `Fraction(0, 1)`
* 空のシーケンスまたはコレクション: `''`, `()`, `[]`, `{}`, `set()`, `range(0)`

これら以外の場合Trueを返す、とあります。
これらの仕様を利用して、例えば次のような利用法が期待できます。
```python
# sが文字列の時、空文字列の場合のみ"foo"を格納する
s = s or "foo"
```


余談ですが、A and B、A or Bともに「Bが評価されない場合」があります。
A and Bでは`bool(A)`が`False`の場合、Bを評価せずAを返却します。
A or Bでは`bool(A)`が`True`の場合、Bを評価せずAを返却します。

詳しい説明はリンク先に譲りますが、これは[短絡評価](https://ja.wikipedia.org/wiki/%E7%9F%AD%E7%B5%A1%E8%A9%95%E4%BE%A1#:~:text=%E7%9F%AD%E7%B5%A1%E8%A9%95%E4%BE%A1%EF%BC%88%E3%81%9F%E3%82%93%E3%82%89%E3%81%8F%E3%81%B2%E3%82%87%E3%81%86,%E6%B3%95%E3%81%AE%E3%81%B2%E3%81%A8%E3%81%A4%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)と呼ばれるもので、片方で論理式全体の結果がわかる場合にはそこで式の評価を打ち切るというものです。
Bが関数などの場合そもそも呼ばれないこともあるということで、注意が必要そうです。

まとめとして、ポイントを押さえておきます。
* Pythonのand・or演算子はbool型以外にも使える
* 同様に、and・or演算子の結果はbool型以外にもなりえる
* 演算子の後ろにある項は呼ばれないこともある
ESP32-WROOM-32とSHTC3高精度デジタル温度および湿度センサー測定モジュール(I2C通信)

# 外見
![SHTC3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738176/34ef1a17-06e0-1c7d-04ba-358c557ddff4.jpeg)

# ピン説明
1.VDD(3.3~5.5v DC)
2.GND
3.SDA
4.SCL

# 性能
1.湿度の測定範囲：0~100% rh
2.湿度測定の精度：±2% rh
3.温度測定範囲：-40~125℃
4.温度測定の精度：±0.2℃
5.動作電圧：3.3~5.5V DC
6.I2Cインターフェイス出力(デフォルトアドレス0x70)

# 開発環境
・Visual Studio Code(ver 1.69.2)
・PlatformIO(Core 6.1.1  home 3.4.2)
　[追加ライブラリ]Adafruit SHTC3 Library

# ソースコード(ほぼサンプルコードのまま)
・使用するピン
　21:SDA(i2c)
　22:SCL(i2c)

```diff_c
#include <Arduino.h>
#include <Adafruit_SHTC3.h>

TwoWire i2c(1);
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();

void setup() {
  Serial.begin(115200);

  while (!Serial)
    delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("SHTC3 test");
  i2c.begin(21, 22);
  if (! shtc3.begin(&i2c)) {
    Serial.println("Couldn't find SHTC3");
    while (1) delay(1);
  }
  Serial.println("Found SHTC3 sensor");
}


void loop() {
  sensors_event_t humidity, temp;
  
  shtc3.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  
  Serial.print("Temp:"); Serial.print(temp.temperature); Serial.print("C ");
  Serial.print("Humi:"); Serial.print(humidity.relative_humidity); Serial.print("%\n");

  delay(1000);
}

```
Go言語でstring型の値を保持した配列をstrings.Joinしようとしたらエラーが発生

# 発生したエラー

Go言語で`string`型の値を保持した配列をカンマ区切りで結合したい時に、以下のエラーが発生

```go
package main
import "fmt"
import "strings"
import "strconv"

func main(){
    var numbers[1000]string
    for i := 0; i < 1000; i++ {
        numbers[i] = strconv.Itoa(i+1)
    }
    //誤り
    fmt.Println(strings.Join(numbers, " "))
}
```


```terminal
# command-line-arguments
./Main.go:12:29: cannot use numbers (type [1000]string) as type []string in argument to strings.Join
```

# 解決策
[`strings.Join`](https://pkg.go.dev/strings#example-Join)の引数は[`Slice`](https://go.dev/blog/slices-intro)であるため、`Array`型の変数を引数に取ることができない。
そのため、ArrayをSliceに変換してJoinして出力する。

```go
package main
import "fmt"
import "strings"
import "strconv"

func main(){
    var numbers[1000]string
    for i := 0; i < 1000; i++ {
        numbers[i] = strconv.Itoa(i+1)
    }
    //誤り
    fmt.Println(strings.Join(numbers, " "))
    //正しい例
    fmt.Println(strings.Join(numbers[:], " "))
}
```
Claris Connectを使って特定のキーワードに関する投稿をSlackに通知を飛ばすワークフローを設定してみた

この記事はQiita Engineer Festa 2022の記事投稿キャンペーン参加記事です。

https://qiita.com/official-events/eeadea1de45a11be944e

## 初めに
SNS上での自社やサービスに関するツイートは気になりますよね。
今回はClaris Connect を使って、特定のキーワードの投稿をSlackに通知が飛ぶワークフローを設定してみました。

## アカウント登録
無料で使える評価版の登録は[こちら](https://www.claris.com/ja/trial/connecthttps://www.claris.com/ja/trial/connect)から行いました。
評価期間は15日間です。
まずはClaris IDを作成し、購入（無料評価版）を進めました。
![スクリーンショット 2022-07-18 19.20.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/adeb7e1a-cfa7-40aa-0d7f-504b2825d6f1.png)


~~アカウントの発行まで15分かかるそうです。~~　実際は5分で登録完了メールが届きました。

![スクリーンショット 2022-07-18 19.36.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/5912c2e9-d5a2-46d2-518c-819cdaba679c.png)

登録ができたらメール本文にある **Claris Customer Console** にアクセスします。
利用規約に同意し、利用が開始できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/155acd49-2a0d-6fd9-3e8d-b53e98d6394b.png)


## 実際にフローを作ってみる

テンプレートなるものがありました。便利ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/5d941190-432f-4ed8-c105-23720dd7a8d6.png)
今回は当てはまるものがなかったのでMy Projectsから作ってみます。


![スクリーンショット 2022-07-18 19.47.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/118bc2ec-09f1-9ec8-bfca-d3251f233d2b.png)

➕をクリック

![スクリーンショット 2022-07-18 19.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/2ae8a318-31c4-78ac-7910-3d0d432230c0.png)


## まずはSlackを連携する

（@JuppoWorksさんの記事がとても分かりやすかったです）

https://qiita.com/JuppoWorks/items/72d9bfecbee868e9edcb


![スクリーンショット 2022-07-18 20.02.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/3785f295-1332-d1f1-a5bd-9d2a3de43f3e.png)

条件を設定する。
今回は **「Qiita」というキーワードをTwitterで検索し** Slack上に通知を飛ばす

![スクリーンショット 2022-07-18 20.15.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/0b98be8e-4995-6263-c77c-254a4cdabb80.png)


ここで受け取るデータを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/3376409b-ef3a-60f1-f3ad-36b93141f3f1.png)



### 条件を設定できたので、次へ

- Action から、**Post message(quick)**　を選択します。

![スクリーンショット 2022-07-18 20.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/385a9322-d779-4018-da48-2d1d17712df3.png)

- Channel: Slack のどのチャンネルに対して通知を行うかを設定
- Message: Slack のテキストメッセージを設定

![スクリーンショット 2022-07-18 20.21.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/f60c8a9b-1097-6644-bc66-6c3bacdc6812.png)


### 「Enabled」にするのをお忘れなく。

![スクリーンショット 2022-07-18 20.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599599/40610c40-cd7d-be30-de65-16d0ed419539.png)



## 最後に
非エンジニアでも30分もかからず、設定が完了しました。
今回は、個人で利用しましたがMailChimpやDocuSignとの連携もゆくゆくは行っていきたいです。
他にも連携できるアプリはSmartHRやZenDesk、チャットワークなどたくさんありました。

一覧はこちら
https://www.claris.com/connect/apps/
初めてのRailsチュートリアルに挑戦！第6・7章

# 第6章の学習内容
1. データベースの移行
1. modelファイル
1. ユーザーオブジェクトを作成する
1. ユーザーオブジェクトを検索する
1. ユーザーオブジェクトを更新する
1. 有効性を検証する
1. 存在性を検証する
1. 長さを検証する
1. フォーマットを検証する
1. 一意性を検証する
1. ハッシュ化されたパスワード
1. ユーザーがセキュアなパスワードを持っている
1. パスワードの最小文字数
1. ユーザーの作成と認証

# 第7章の学習内容
1. Usersリソース
1. debuggerメソッド
1. Gravatar画像とサイドバー
1. ユーザー登録フォーム
1. ユーザー登録失敗
1. Strong Parameters
1. エラーメッセージ
1. 失敗時のテスト
1. ユーザー登録成功
1. 成功時のテスト
1. プロのデプロイ
1. 本番環境でのSSL
1. 本番環境用のWebサーバー
1. 本番データベースを設定する

# 学習を終えて
 第6章では、ユーザモデルの作成する際に、有効性や存在性、一意性を検証しながら進めることの大切さを学んだ。また、セキュアなパスワードを追加するためにハッシュを用いることの重要性を理解した。
 第7章では、ユーザ登録フォームを実際に作成し、ユーザ登録が失敗する場合と成功する場合をそれぞれ実施することで理解を深めた。テスト時にはdebuggerメソッドを活用しながら一つ一つの動作を確認することが重要であると認識した。
OUTPUT句の結果をJavaアプリケーション上で受け取りたい

SQLServerには削除したり更新したりしたデータを返す[OUTPUT句](https://docs.microsoft.com/ja-jp/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-ver16)というものがあります。OUTPUT句の結果をJavaアプリケーション上で受け取りたい場合は`PreparedStatement::executeQuery`を利用して、SQLを発行すれば良いです。OUTPUT句はDELETE文やUPDATE文で利用しますが、通常DELETE文やUPDATE文の発行に利用する`PreparedStatement::executeUpdate`ではOUTPUT句の結果を受け取れないことに注意する必要があります。

未検証ですが、データベース接続に何らかのライブラリを使う場合は、通常SELECT文を発行するためのAPIを用いて、OUTPUT句を含むDELETE文なりUPDATE文なりを発行すればよいかと思われます。

以下は従業員の情報を格納する`employees`テーブルからidが2と4の従業員を削除しつつ、その削除した従業員のidと名前と入社日を取得するサンプルです。

```java
String sql = """ 
    DELETE FROM employees
    OUTPUT DELETED.id, DELETED.name, DELETED.hiredate
    WHERE id IN (2, 4)
""";

String url = "jdbc:sqlserver://localhost;encrypt=false";
String username = "sa";
String password = "1234@Hoge";
try (Connection con = DriverManager.getConnection(url, username, password)) {
    PreparedStatement pstmt = con.prepareStatement(sql);
    ResultSet rs = pstmt.executeQuery();
    while (rs.next()) {
        int id = rs.getInt("id");
        String name = rs.getString("name");
        Date age = rs.getDate("hiredate");
        doSomething(id, name, age);
    }
} catch (SQLException e) {
    e.printStackTrace();
}
```

**環境情報**

- Java17
- mssql-jdbc-10.2.1.jre17.jar

[SQLServerはDockerを利用して起動](https://hub.docker.com/_/microsoft-mssql-server)。詳細なバージョンは以下の通り

```
Microsoft SQL Server 2019 (RTM-CU9) (KB5000642) - 15.0.4102.2 (X64) 
	Jan 25 2021 20:16:12 
	Copyright (C) 2019 Microsoft Corporation
	Developer Edition (64-bit) on Linux (Ubuntu 18.04.5 LTS) <X64>
```
Pythonでアーキテクチャ図を書いてみた：備忘録

# 概要
アーキテクチャ図のツールがいろいろある中で、Pythonコードを使って簡単に書けるというので試しにしてみました。その備忘録です。

# 準備
環境を整えます。
MacBookを使用していて既に`Python3`はインストール済みです。
それで追加インストールを以下の通り`ターミナル`から実行しました。
`Diagrams`を使用します。これは`graphviz`に依存しているので以下のように両方ともインストールします。
```zsh:zsh
$ pip3 install diagrams
```
```zsh:zsh
$ brew install graphviz
```

# ソースコード：アプリケーション
アプリケーションのアーキテクチャ図を描いてみるサンプルコードです。
```Python3:aplication.py
# アーキテクチャ図：アプリケーション
from diagrams import Cluster, Diagram
from diagrams.programming.framework import React
from diagrams.programming.language import Go, Java
from diagrams.onprem.database import MySQL, PostgreSQL

with Diagram('SPA Architecture'):
    frontend = React('Frontend')

    with Cluster('Service A'):
        frontend >>  Go('Go API') >> MySQL('MySQL')

    with Cluster('Service B'):
        frontend >> Java('Java API') >> PostgreSQL('PostgreSQL')
```
## 出力結果：アプリケーション
![apli.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409451/2be6d5a7-1e81-a137-5046-8f3fea248c0e.png)

# ソースコード：AWS
AWSのアーキテクチャ図を描いてみるサンプルコードです。
```Python3:aws.py
# アーキテクチャ図：AWS
from diagrams import Cluster, Diagram
from diagrams.aws.compute import EC2, EC2AutoScaling, Lambda
from diagrams.aws.database import Aurora
from diagrams.aws.integration import SQS
from diagrams.aws.network import ALB, Route53
from diagrams.aws.storage import S3

with Diagram('AWS Architecture'):
    route53 = Route53('Route 53')

    alb = ALB('ALB')

    with Cluster('EC2 Auto Scaling'):
        instances = [
            EC2('Instance'),
            EC2('Instance'),
            EC2('Instance')
        ]

    aurora = Aurora('Aurora')

    sqs = SQS('SQS')

    function = Lambda('Lambda')

    s3 = S3('S3')

    route53 >> alb >> instances
    instances >> aurora
    instances >> sqs >> function >> s3
```
## 出力結果：AWS
![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409451/60052ddd-1494-2319-1b52-c7b5a376877c.png)


参考:
[Diagrams Diagram as Code](https://diagrams.mingrammer.com/)
3から999までの素数を表示するプログラムを書いてみた

# 3から999までの素数を表示するプログラム
```python:素数練習6.py
zentai=range(3,1000)

for number in zentai:
    sosu=True

    for waruyatsu in range(2,number):
            if number%waruyatsu==0:
                sosu=False

    if sosu==True:
        print(number)

```
まず、一行目の`zentai=range(3,1000)`は3から999までをzentaiというリストの範囲と取ります。

三行目の`for number in zentai:`はzentaiの内容を順番に実行させます。

四行目の`sosu=True`はsosuをTrueと定義します。初期化の為にも四行目である必要があります。

六行目の`for waruyatsu in range(2,number):`はwaruyatsuは2からnumberまでの範囲と取ります。

七・八行目の`if number%waruyatsu==0:
                sosu=False`はnumberをwaruyatsuで割ったときに余りが0だった場合、sosuをFlaseと書き換えます。

十行目の`if sosu==True:`はsosuがFlaseと書き換えられなかった場合、つまり素数の時にTrueとし、
十一行目の`print(number)`で素数の数字を表示させます。


数字が素数かどうか判断するにはある数と1以外で割り切れなければいい。と思いつくのはすぐでしたが、それを実際にプログラムに書き起こすのが思っていたより難しかった。
何らかで割り切れた数字はそれ以上計算せずに次の数字に移り、計算量が少なくなるようにも出来そうだと思った。
CentOS8でHTTrackのconfigureできない

`EVP_get_digestbyname`と`SSL_CTX_new`がないのでOpenSSL系ぽい

```
checking whether to enable https support... yes
checking for EVP_get_digestbyname in -lcrypto... no
checking for SSL_CTX_new in -lssl... no
configure: error: not available
```

## `openssl-devel`をインストールする


```
dnf install openssl-devel
```

[openvpn configure: error: openssl check failed](https://blog.cpming.top/p/openvpn-configure-error-openssl-check-failed)
EC2　自動起動停止

# EC2 自動起動停止
## 概要
- EC2のインスタンスをcronで自動で起動、停止するように設定する。
- 備忘録としてAWSのコンソールの新UIで設定する方法を残すもの。
- EC2のインスタンスを必要ないときに停止して節約する。

## 前提
- EC2インスタンスを起動できる。

## 手順

1. `IAM`で`Systems Manager`を操作できるサービスロールを作成する。
2. `Amazon EventBridge` で`EC2`を自動起動するように設定する。
3. `Amazon EventBridge` で`EC2`を自動停止するように設定する。

### `IAM`で`Systems Manager`を操作できるサービスロールを作成する。

1. `IAM` → `ロール` → `ロール作成`のボタンを押す。
![.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/e8f6d3be-3634-76e2-aee6-31d4edb1eead.png)

2. ①のプルダウンを押し、`Systems Manager`を検索ボックスに入れ検索する。
   ②のチェックボックスを選択して、`次へ`を押す
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/1c22086a-4572-b747-738a-041e54759737.png)

3. ①の検索ボックスに`AmazonSSMAutomationRole`を入れてEnterを押して絞り込む。
   絞り込んだら、②の部分のチェックボックスを押す。
   ③を押して`次へ`を押す。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/bd9bc8f6-84a1-35e7-03ba-b22ca50ac369.png)

4. ①の部分にわかりやすいロール名を入れる。（例：ssm-automation-role など）
   その後、右下の`ロール作成`ボタンを押す。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/f279f216-6e1f-2ee3-86f5-403183054c32.png)

5. ロール一覧から作成したロールの名前を押し、詳細画面へ移動する。
   詳細から①の`信頼関係`のタブを押し、②の`信頼ポリシーを編集`を押して編集する。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/77505cc4-0a93-eecf-524e-f545fc674318.png)

6. ①の部分を`ssm.amazonaws.com`を`events.amazonaws.com`に変更する。
   変更後②の`ポリシー更新`を押して更新する。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/73c09216-e2bb-e47d-a9a2-1637f721214f.png)

### `Amazon EventBridge` で`EC2`を自動起動するように設定する。

1. `Amazon EventBridge`→`ルール`→`ルールを作成`を押す。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/5788d38d-9f2b-d12f-6051-0d0d33467df2.png)

2. ①にわかりやすい名前を付ける。
   ②にわかりやすい説明を入れる。
   ③の部分のチェックボックスを押し、`ルールタイプ`をスケジュールにする。
   ④を押し、次へ。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/78c178cf-dbe5-8ba7-bdd5-8ec38d8e680e.png)

3. ①の部分にcronの形式で自動で起動する日時を設定する。※UTCで設定なので、日本時間から-9時間で設定する(例: 平日の10時に起動する)
   ②の部分を押し、次へ。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/8225e623-7e79-6127-da62-44ca255adf24.png)

4. ①のプルダウンの検索ボックスに`System Manager オートメーション`を入れ、`System Manager オートメーション`を選択する。
   ②のプルダウンの検索ボックスに`AWS-StartEC2Instance`を入れ、`AWS-StartEC2Instance`を選択する。
   ③のテキストボックスに自動起動したいEC2のインスタンスIDを入れる。
   ④のラジオボタンを押し、⑤のプルダウンから前手順で設定したサービスロールを選択する。(今回の場合は`ssm-automation-role`)
   ⑥を押し、次へ。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477896/0038d034-0268-b4e7-9c72-6b490890d4a1.png)

5. タグ設定は特にせずに、`次へ`を押し、次の画面の右下の`ルールを作成`を押す。

### `Amazon EventBridge` で`EC2`を自動停止するように設定する。

- 「`Amazon EventBridge` で`EC2`を自動起動するように設定する。」で行った手順とほぼ同じ。
- 「`Amazon EventBridge` で`EC2`を自動起動するように設定する。」の`4`の②の部分を`AWS-StopEC2Instance`にする。
- その後の手順も同じ。

## あとがき
- クラウド系のUIはコロコロ変わるので、CLIのやり方についても調べて時間があったらこのページへ追記しようと思う。

## 参考サイト
https://qiita.com/Kumaou_00/items/23c5f6f4434a79178712
#1　文字の出力、for文、if文

# 学習内容
今回は、"Hello World" ～ "if文(条件分岐)" までやった。

```java
class Hello{  // Helloクラス
   public static void main(String[] args) {  //mainメソッド
      for(int i=1; i<5; i++){  // iが5未満の場合、処理をする
         if(i < 3){  // iが3未満ならば、挨拶する
            System.out.println("Hello World!");
         }else{  // iが3以上ならば数字を出力する
            System.out.println(i);
         }
      }
   }
}
```
参考 -> http://blueplace.sakura.ne.jp/basic/JavaBasicSample.html#src205

## class
プログラムを実行するための処理をひとまとまりにしたもの。
この中で、メソッドやフィールドなどを使って処理を行う。
```java
class クラス名 {  //クラス名はなんでもいい
   処理
}
```
## メソッド
処理のまとまりのこと。
※mainメソッドから必ず処理がスタートする。
```java
class クラス名{
   void メソッド名{  //メソッド名はなんでもいい
   }
}
```
## ブロック
{ } の間のこと。
## 文字を出力
##### print(),println() の２パターン
違いは改行があるかないか
```java
/* ソースコード */
public class Example1_01{
   public static void main(String[] args) {
      System.out.print("abc");  // print -> 改行なし
      System.out.println("def");  // println -> 改行あり
      System.out.print("ghi");
   }
}
```
```
/* 実行結果 */
abcdef
ghi
```
その他の使い方 ↓
```java
int a = 4;
System.out.println(a);  //変数をそのまま出力
-------------------------------------------
System.out.println(3+2);  //かっこ内で計算
-------------------------------------------
System.out.println("こんにちは");  //文字列は""で囲む
----------------------------------------------------
System.out.println("今は" + a + "時です。");  //組み合わせる時は + を使う
```
## for文
同じ処理を指定した回数だけ繰り返しする。
```java
/*ソースコード*/
// for(初期化式; 条件式; 変化式;){ 処理 }
public class Example1_02{
   public static void main(String[] args) {
      for(int i=1; i<5; i++){  //iを１から(初期化式)、１ずつ足していき(変化式)、
      System.out.println(i);  //５になるまでの間(条件式)、処理を繰り返す
      }
   }
}
```
```
/* 実行結果 */
1
2
3
4
```
その他の使い方 ↓
```java
int i=1;
for(; i<5; i++){  //初期化式を外で宣言する。;を忘れないように
   処理
}
---------------------------------------------------------
for(; i<5;){  //変化式をfor文の中で指定
   処理
   i ++;
}
```

## if文
英語のとおり、"もし〇〇が△△ならば、こういう処理をしよう"というもの。
```java
/* ソースコード */
// if(条件式){ 処理 }
public class Example1_03{
   public static void main(String[] args) {
      int num = 3;
      if(num > 0){  //もしnumが0より大きかったら…
         System.out.println("numは0より大きいです。");
      }else{  //上の条件に当てはまらなければ…
         System.out.println("numは0より小さいです。");
      }
   }
}
```
```
/* 実行結果 */
numは0より大きいです。
```
その他の使い方 ↓
```java
if(条件１){
   処理;
}if else(条件２){  //条件を増やすときは "if else" をつかう
   処理;
}else{
   処理;
}
-----------------------------------------------------
(条件式)?値１:値２;  //一行にまとめて書く
-----------------------------------------------------
String str = "こんにちは";
if(str == "こんにちは"){  //文字列の一致もできる
   処理;
}else{
   処理;
}
```
herokuでアップしても ローカルと同じ動作をしない。

<h2>発生状況</h2>
ローカル環境で動作確認済み

```
heroku run git up master
heroku run rails db:migrate
```
してもローカルと本番環境で同じ動作をしない。

<h2>エラー確認</h1>

FATAL周りに
```
ActiveModel::UnknownAttributeError (unknown attribute 'item_name' for Item.

status=500
```
有りのためどうやらDBまわりでのエラー
DBをUP/DOWNして書き換えたのが理由のよう。

<h2>修正内容</h2>
現状ローカル環境のマイグレートファイル、その他記述が間違っていないことを確認。

```
% heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop db:create db:migrate
```
を(heroku上のDBをdrop,create,localと同じ状態にmigrate,全て行うコマンド)実行する。
で解決。


<h2>上記コマンドでエラーが出た際</h2>
データベースの作り替えするも、新データベースが

ファイルの中身が書き換えの結果
```
TABLEA=2022010２(references :TABLEB...)
TABLEB=20220103
```
みたいになっていたら、TABLEA作成時にエラーが発生して作れない(まだ存在していないTABLEBを作れない)のでDBを一度削除

```
rails db:drop
```
ファイル名を書き換える。参照がないものから日付を若くする) 
= 普通に右クリックしてファイル名を変更

```
TABLEB=20220101
TABLEA=20220102(references :TABLEB...)
```


<h3>その後(上記コマンドでエラーが出た際)</h3>
<h4>ローカルでの作業</h4>
migrateし直すだけ

```
rails db:migrate
```

<h4>herokuでの作業</h4>

```
% heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop db:create db:migrate
% heroku git up master
% heroku run rails db:migrate
```

で解決。

共同作業で間違って削除したら泣くので注意。
Unity+OBR SLAM3でシミュレーション環境での自己位置推定してみた

Unityでシミュレーション環境を作って、OBR SLAM3で自己位置推定してみた。環境はWindows上でUnityを動かし、WSL上でOBR SLAM3を動かしている。

動作としては以下のような感じ。動いてはいるものの、マップ生成は全くうまくいっていない。。どなたか原因に心あたりや、こうしたらうまくいったなどあれば教えていただけると幸いです。ひとまず環境構築方法を記載しておきます。

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



## 前準備

以下に作った改造用コードが置いてあるのでダウンロードしておく。

https://github.com/wooolwooolwoool/Linon_SDK

## OBR SLAM3側

以下のページを参考に、WSLにOBR SLAM3をインストールする。

https://wooolwoool.hatenablog.com/entry/2022/07/16/131454?_ga=2.179549216.589715685.1658118855-290407285.1630817923

build.sh実行前に、改造用コードに以下のコードが入っているので差し替えておく。

- mono_inertial_euroc.cc

## Unity側

今回は町として以下のパッケージを使うのでインポートしておく。特に制限はないので、使いたい街を使ってもOK。

https://assetstore.unity.com/packages/3d/environments/urban/city-voxel-pack-136141

1. File -> Open Sceneから以下のファイルを開く。

   - Assets/CityVoxelPack/DemoScenes/Demo.unity

2. CubeObjectを作成して、CubeMove.csをアタッチする。
 
3. CubeObjectにカメラを追加し、カメラにcamera_udp.csをアタッチし、ip_addをWSLのIPアドレス(172.21.*.*となっているもの)に変更する。（アップデートでlocalhostでも通信できるようになったらしいので不要かも。）

4. オブジェクトの向き、位置、方向を調整する。

## 実行

1. Unity側で再生を押す。
2. OBR SLAM3側で以下のコマンドを実行する。

   ```
   $ ./Examples/Monocular-Inertial/mono_inertial_euroc ./Vocabulary/ORBvoc.txt ./Examples/Monocular-Inertial/EuRoC.yaml ../Datasets/EuRoc/MH01 ./Examples/Monocular/EuRoC_TimeStamps/MH01.txt dataset-MH01_mono
   ```
3. ウィンドウが表示された後、Unity側でCubeを動かすとFrameとMapが表示される。

## うまくいっていない原因の考察

- OBR SLAMのサンプルコードの映像入力を書き換えただけなので、ほかに変更しなきゃいけない部分がある？（カメラキャリブレーションなど）
- 画面がきれいすぎて特徴点を抽出できない？
debounceの理解

## 防振の簡単な説明
関数のdebounce：同じタスクが短期間に頻繁に実行されるのを防ぎます。短期間に頻繁に発生する必要がない場合は、リソースの浪費や悪いエクスペリエンスの発生を回避するために、ジッタ除去を検討できます。

debounceの原理は、主に1回限りのタイマーを使用してタスクの実行を遅延させることです。遅延中にタスクが再度トリガーされると、タイマーが破棄されるため、最後に生成されたタイマーはclearTimeoutによって破棄されます。 以前に遅延したタスクもキャンセルされます。このように、タスクは特定の期間内に1回だけ実行されます。タイマーが破壊されたために前のトリガーがキャンセルされたため、この実行は通常最後のトリガーです。

複数回トリガーして最後にのみ実行することは、「スロットリング」の概念との違いかもしれません。この2つは機能的には非常に似ていますが、特定の実装ではわずかに異なります。関数のデバウンスは、短時間に複数回トリガーされますが、最後の実行のみ、つまり、複数の実行が最後の実行のみに変換され、実行回数が削減されます。スロットル（スロットル）とは、短時間に複数回実行して、一定の間隔で実行することです。

## debounceの事例
### 1.debounce前後のサンプル効果のスクリーンショット

![Screen Shot 2022-05-17 at 23.50.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193270/28c20275-3d5e-4d59-bfa5-79ff5ec1c7b6.png)

### ソースコード

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Debounce Demo</title>
</head>
<body>
<h1>Debounce Demo</h1>

<label>
    <span>名前をご入力ください：</span>
    <input oninput="validatePhone(event.data)"></input>
</label>

<script>

  let timer = null

  function inputChange (data) {
    // Debounceがないと、検証が頻繁にトリガーされます。たとえば、2つの連続する単語が6〜7回トリガーされる場合があります。，
    // この頻度は必要ないかもしれません。頻度が必要ないとき、それは資源の浪費です。
    // validatePhone(data)

    // Debounce処理。同じ2つの単語が継続的かつ正常に入力された場合、1つの検証タスクのみがトリガーされます。
    clearTimeout(timer)
    timer = setTimeout(() => {
      validatePhone(data)
    }, 1000)
  }

  function validatePhone (data) {
    let flag = true
    const regPhone = /^1\d{10}$/
    if (!regPhone.test(data)) {
      flag = false
      console.log('検証内容：' + data + '。電話番号が間違っています。0から始まる11桁の電話番号を入力してください')
    }
    return flag
  }
</script>
</body>
</html>

```
業務で多用した権限管理系Linuxコマンド

はじめに
-
この記事では自分の業務において多用したコマンドをメモ書きとして残します。

rootユーザ切り替え
-
suコマンドによって一般ユーザからrootユーザに切り替える。
```ruby:rootユーザ切り替え
sudo su -
```
##### 上記コマンドの意味
- sudo
  - 一般ユーザが管理者権限として後述するコマンドを利用する場合に用いる。
- su
  - su ○○とすることで○○ユーザに切り替える。ユーザIDを省略することでrootにログインすることになる。
- -(ハイフン)
  - suのオプションで、ログイン後にrootディレクトリに移る。

容量確認
-
dfコマンドにより現在接続しているサーバの容量がどれほど利用されているか確認する。
```ruby:容量確認
df -h
```
##### 上記コマンドの意味
- df
  - 空き容量を確認するコマンド。デフォルトはKB表示。
- オプション
  - -h
  容量に応じて見やすい表示にする。

コピー
-
cpコマンドによりファイルやフォルダをコピーする。いろいろなオプションがあるが、フォルダ配下をまるごとコピーするコマンドを使うことがあったため下記をメモ書きとして残す。
```ruby:コピー
cp -r コピー元ディレクトリ名　コピー先ディレクトリ名
```
##### 上記コマンドの意味
- cp
  - コピー元とコピー先を指定することでファイルやディレクトリをコピーするコマンド。
- オプション
  - -r 
  ディレクトリ配下のファイルごとコピーすることができる。

ディレクトリ削除
-
rmコマンドにてディレクトリの中身ごと削除する。
```ruby:ディレクトリ削除
rm -rf ディレクトリ名
```
##### 上記コマンドの意味
- rm
  - 本来はファイルを削除するコマンド。オプションを付けることでディレクトリごと削除することが可能となる。
- オプション
  - -r
  ディレクトリ配下のファイルごと削除する。
  - -f
  削除の確認を無くす。重要なファイルがある場合はこのオプションは危険。（このオプションを用いた事故が起きたため現プロジェクトでは利用不可となった。）
- rmdir
  - 空のディレクトリを消すコマンド。中身があるディレクトリには使えないが明示的にわかりやすいので、ディレクトリ内のファイルを削除したあとrmdirにてディレクトリを消すという運用をしていた。

ディレクトリ作成
-
mkdirコマンドを用いることでディレクトリを作成する。
```ruby:ディレクトリ作成
mkdir ディレクトリ名
```
- mkdir
  - 現在いるディレクトリにディレクトリを作成する。

オーナ変更
-
chwonコマンドを利用してファイルの所有者の付替えを行う。
```ruby:オーナ変更
chown -R ユーザ名:グループ名 ディレクトリ名
```
- chown
  - ファイルのオーナを変更する。ユーザ名が所有者となり、グループ名が所有グループとなる。
- オプション
  - -R
  chownはファイルのオーナを変更するコマンドだが、-Rをつけることによりディレクトリとディレクトリ配下のファイルのオーナを変更する。

権限変更
-
chmodコマンドを利用して、利用者ごとの権限（読み取り・書き込み・実行）を付け替える。
```ruby:権限変更
chmod 764 ファイル名
```
- chmod
  - 指定されたファイルの権限を付け替える。
- 数字の意味
  - 7→一番左に書いてあるのは所有者の権限。読み取りと書き込みと実行の権限を持たせている。
  - 6→真ん中に書いてあるのは所有グループの権限。読み取りと書き込みの権限を持たせている。
  - 4→一番右に書いてあるのはその他の権限。読み取りの権限を持たせている。 
  - 読み取りが4 書き込みが2 実行が1となり、複数の権限を持たせたい場合は合計値を指定する。

参考
-
この記事を書いている時に勝手ながら参考にさせて頂いた記事になります。
[「sudo su」ってざっくり言ってなんぞ？](https://qiita.com/msht0511/items/31294277a4415ccb4ac9)
[Linuxの権限確認と変更(chmod)（超初心者向け）](https://qiita.com/shisama/items/5f4c4fa768642aad9e06)

おわりに
-
業務で特に利用していると感じたコマンドとオプションを列挙してみました。
気が向いたらまた追加していこうと思います。
FreeMindでテストケース作成

### 参考
> [FreeMind](<https://freemind.asia/basics/download.html>)
[PICT](<https://qiita.com/akiraabe/items/2cb38a8bde1126f58ee1>)
[テストケース作成](https://goyoki.hatenablog.com/entry/2018/02/04/230854)
【Python】plotlyで円グラフ


```python
# -*- coding: utf-8 -*-
import pandas as pd  
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import datetime

dt_now = datetime.datetime.now()
dt_now_jst_aware = datetime.timedelta(days=7)

print(dt_now)
print(dt_now + dt_now_jst_aware)


df = pd.read_excel('test.xlsx', index_col=0)
df = df[df['hiduke'] <= datetime.datetime(2022, 7, 6)]
print(df[df['hiduke'] <= datetime.datetime(2022, 7, 6)])
fig = go.Figure()

fig.add_trace(
    go.Pie(labels = df['tantou'],
           values = df['kousu'])
)

fig.update_traces(
                hoverinfo='label+percent', # カーソルをあわせた時に表示される情報を設定
                textinfo='value',          # 円グラフ内に表示する文字情報を設定 (デフォルトだと割合)
                textfont_size=50,          # テキストのフォントの大きさを設定
                #marker=dict(line=dict(color='#000000', width=2)), #円グラフの 枠線(line),塗りつぶし色(color)などの設定
                textposition='inside', # テキストの表示位置 ("inside":グラフ内に表示)    
    
                #hole = .4, # 円グラフ内に空ける穴の大きさ (ドーナツ図へ)
                #pull = [0, 0.2, 0, 0, 0], # 一部要素だけを取り出すこともできる
)

fig.show()
```

### 参考
> [Pythonで任意の日付がその月の第何週目・何曜日かを取得 | note.nkmk.me](https://note.nkmk.me/python-calendar-datetime-nth-dow/)
[Pandas でデータフレームから特定の行・列を取得する – Python でデータサイエンス](https://pythondatascience.plavox.info/pandas/%E8%A1%8C%E3%83%BB%E5%88%97%E3%81%AE%E6%8A%BD%E5%87%BA)
[Python で指定時間前（１日前、1年前など）、指定時間後（１日後、1年後）を求める方法](https://leben.mobi/blog/python_date_before_after/python/#i-2)
[Plotly Pie Chart(円グラフ) 描き方 まとめ | AIリサーチコレクション](https://ai-research-collection.com/plotly-pie-chart/#toc4)