OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu初心者がUbuntuにdockerとdocker-composeをバージョン指定でインストール

CentOSを使っている自分が、Ubuntuサーバでバージョンを指定してdockerとdocker-conposeをインストールする必要があって、なんとか動くところまで作業したので、備忘録としてここにメモします。

参考はここで、ここに書いてある通りに行ったら、ほぼできました。
https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

## dockerのインストール
(1) 既存のパッケージのリストを更新
```
~$ sudo apt update
```
(2) aptがHTTPS経由でパッケージを使用できるようにするいくつかの必要条件パッケージをインストール
```
~$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
```
(3)# 公式DockerリポジトリのGPGキーをシステムに追加
```
~$ sudo mkdir -p /etc/apt/keyrings
~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```
(4)# DockerリポジトリをAPTソースに追加
```
$ echo \
>   "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
>   $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

```

(5) インストールしたいバージョン(今回は「20.10.13」)の指定方法を探す
```
~$ apt-cache madison docker-ce|grep 20.10.13
 docker-ce | 5:20.10.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
```
(6) dockerをインストール
```
~$ sudo apt-get install docker-ce=5:20.10.13~3-0~ubuntu-focal docker-ce-cli=5:20.10.13~3-0~ubuntu-focal containerd.ioこの操作後に追加で 423 MB のディスク容量が消費されます。
続行しますか? [Y/n] Y
```

## docker-composeのインストール
```
~$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
~$ sudo chmod +x /usr/local/bin/docker-compose
~$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
```

## dockerを一般ユーザでも使えるようにする
##### dockerを使用するユーザーをdockerグループに参加させる
```
sudo gpasswd -a ユーザー名 docker 
sudo gpasswd -a hoge docker 
sudo gpasswd -a fuga docker
```

##### dockerのソケットファイルの所有グループをdockerに変更する
```
sudo chgrp docker /var/run/docker.sock
```
 
##### dockerデーモンを再起動
```
sudo systemctl restart docker
```
##### 動作確認
```
~$ docker imagesREPOSITORY   TAG       IMAGE ID   CREATED   SIZE
```

## バージョンを指定してdocker-composeのインストール

```
~$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
~$ sudo chmod +x /usr/local/bin/docker-compose
~$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
```

こちらの方法が最新の方法のようです
```
$ apt-cache madison docker-compose-plugin   
得られた結果の2行目以降の列から、インストールしたいバージョンを指定する文字列を確認
指定したバージョンをインストール
$ sudo apt-get install docker-compose-plugin=<バージョン文字>
```

##   nvidiaのリポジトリが変更になったので対応
```
### 参考：https://developer.nvidia.com/blog/updating-the-cuda-linux-gpg-repository-key/
sudo apt-key del 7fa2af80
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb 
sudo apt update
```
オブジェクト指向（超入門　アンチパターン）

## 責務と機能
* 責務: 内部状態に応じて、その対応が変化する
* 機能: 内部状態に関係なくいつも同じ値を返す
## アンチパターン
* 多重度*の記載がない
    * すべてが1対1の場合も手続き型設計を引きずっている危険性がある
    * 多重度: インスタンスの個数
* メソッド名に目的語を含んでいる
    * メソッド名は実行する部分だけでよい
    * 何を実行するかはクラス名称と属性によって判断されるべきである
* 受動的* なメソッドが多い
    * 受動的: *クラウス自身が自立して動作するのではなく、他のクラスに支配されて動作するもの。Get/Setやクエリ等
    * 受動的なメソッドが多いクラスは、一つのクラスがほかのクラスに問い合わせてクラスの制御をするため、シーケンス図を確認すると五月雨状になる。
    * 受動的なメソッドがない場合は、シーケンス図は階段状になり、責務を委譲しながら動作する。（良い設計）

## 参考文献
 * [組込みソフトウェア開発のための オブジェクト指向モデリング (組込みエンジニア教科書) 単行本（ソフトカバー） – 2006/6/13](https://www.amazon.co.jp/%E7%B5%84%E8%BE%BC%E3%81%BF%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0-%E7%B5%84%E8%BE%BC%E3%81%BF%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E6%95%99%E7%A7%91%E6%9B%B8-SESSAME-WG2/dp/4798111767)
【JavaScript】配列の最後の要素を取り出すメソッド


## 追記

今はatメソッドを使いましょう。

```js
const hogeArray = [1, 1, 2, 3, 5, 8];
console.log(hogeArray.at(-1)); // 8
```

## 本題

次のメソッドを作ってください。

```javascript
Array.prototype.last = function() {
    if (this.length === 0) {
        throw new Error("要素が存在しない");
    }
    return this[this.length - 1];
};
```

簡単に最後の要素が取り出せるようになります。

```javascript
const hogeArray = [1, 1, 2, 3, 5, 8];
console.log(hogeArray.last()); // 8
```
良い「あとまわし」と悪い「あとまわし」

真面目に働いているならば、何らかの仕事をあとまわしにした経験が必ずあるはずです（筆者も一度ぐらいは経験した気がする）。

腰を据えて実装にとりかかろうとしたタイミングで、誰かから依頼を受けた。簡単な依頼だし断るのも悪いから「ちょっと30分だけ...」と対応する。対応が終わったら、今度は別の人から相談を受けた。「まあ少しだけなら...」と話に応じる。

そんなことをしているうちに今日の業務が終わる。もしくは**そこから本当の業務がはじまる**人もいるかもしれません。

この記事では、そんなあとまわしについて **『仕事に追われない仕事術 マニャーナの法則』** という本を参考にしながら、その良し悪しを論じてみたいと思います。

## 良い「あとまわし」とは？

良いあとまわしは、端的に言えば、**突発的に発生したタスクのコントロール**です。たとえば、

- 同僚から突然依頼・相談されたこと
- 仕事中にふと気になったこと
- 反射的にやってしまうこと（メール、Slackの返事）

などが対象になるでしょうか。

『仕事に追われない仕事術』では、**仕事のほとんどは「すぐやる」必要も、なんなら「今日中にやる」必要もない**、と説きます。

> 「マニャーナの法則」の根底にあるのは「明日まで待てないほど、緊急な仕事はない」という考え方です。ポジティブに表現すれば「１日に発生する仕事を集めて、必ず次の日にやる」と言い換えられます。つまり、常に仕事に１日分の「バッファー・ゾーン」を設ける考え方なのです。[^1]

上述のようなタスクを「その場で、すぐやる」誘惑に打ち勝ち、ひとまず距離を置いてみる。そのタスクを明日とりかかれないかどうか考える。

雑務をやるより今朝の計画に取り組むほうが価値がある、と信じられる場合、このあとまわしは確かに良い作戦だと感じました。

## 悪い「あとまわし」とは？

一方で悪いあとまわしは、もともと目の前に積まれていたから、もしくは重要だから**取り組もうと思っているプロジェクト・タスクの放置**です。

『仕事に追われない仕事術』を援用するまでもなく、自身の経験に聞いてもよいでしょう。仕事には「気乗りしない」度合いがあり、本書ではこれを「**抵抗感**」と呼んでいます。

> 抵抗感が発生するのは「ある行動がその他の行動より難しい」と感じた時です。ですから、どうでもよい仕事をしていれば抵抗感は起こりません。実際、重要な課題に取り組むより、どうでもよい簡単な仕事を続ける方がずっと簡単です。こうして、日常はどうでもよい細かい仕事で埋め尽くされることになってしまいます。[^2]

放置するタスクには「難しそうだからやりたくない」「面倒なことに巻き込まれそうだからやりたくない」「失敗したら恥ずかしいからやりたくない」などの理由が実は隠れています。見て見ぬフリをしまった経験は誰しもあるでしょう。

抵抗感の大きな特徴はもうひとつあります。それは、あとまわしにした回数と抵抗感が比例すること、つまり**あとまわしにすればするほど、明日はもっとやりたくなくなる**という点です。

## まとめ

上記の内容をあわせると、次のようにまとめられそうです。

- 抵抗感のあるタスクに取り組むために、突発的に発生したタスクたちはあとまわしにすべき
- 突発的に発生したタスクに取り組むことを口実に、抵抗感のあるタスクをあとまわしにすることは避けるべき

もちろん業種や役割に応じて「すぐやる」タスクの比率が多い人もいるでしょう。しかし一歩立ち止まって考えれば、意外と「明日やる」でも問題ないタスクを「すぐやる」に回していた経験もあるはずです。

なにかをあとまわしにすべき局面が訪れたとき、あるいはあとまわしにするせいで仕事が上手く進んでいない感覚を持ったとき、このような観点でタスクの見直しをしてみるのは良い作戦になると感じました。

## 参照

- マーク・フォースター『仕事に追われない仕事術 マニャーナの法則』

[^1]: マーク・フォースター『仕事に追われない仕事術 マニャーナの法則』、Kindle版、No.1227-1230。

[^2]: 同、No.372-375。
ソリューションアーキテクト対策_あまり馴染みの無いサービス篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:

## Amazon Polly
文章をリアルな音声に変換するサービス。
発話できるアプリケーションを作成できる。

## Amazon SageMaker
すべての開発者とデータサイエンティストに機械学習モデルを迅速に構築・トレーニング・デプロイできる手段を提供する。
また、フルマネージドサービスであり、機械学習ワークフロー全体に対応している。

## Amazon Lex
音声やテキストを使用して、任意のアプリケーションに対話型インターフェイスを構築するサービス。
音声のテキスト変換には自動音声認識(ASR)、テキストの意図認識には自然言語理解(NLU)という高度な深層学習機能が使用できるため、リアルな会話を実現するアプリケーションを開発できる。

## Amazon Rekognition
画像分析と動画分析をアプリケーションに簡単に追加できるサービス。
Rekognition　APIに画像または動画を与えるだけで、このサービスが対象物・人・テキスト・シーン・アクティビティ・それに不適切なコンテンツまで検出する。

## AWS Backup
AWS StorageGatewayを使用して、オンプレミスおよびAWSサービス全体のデータのバックアップの一元化と自動化を簡単に実行できる、完全マネージド型のバックアップサービス。
バックアップポリシーを一元的に設定し、EBSボリューム、RDSデータベース、DynamoDBテーブル、EFSファイルシステム、StorageGatewayボリュームなどのAWSリソースのバックアップアクティビティを監視できる。
※アクティビティは活動って意味

### 類似しているサービス
#### Amazon DLM
EBSボリュームとスナップショットの定期取得や管理を行えるサービス。
ただしAWS Backupと違いバックアップの一元管理を行うサービスではない。

#### AWS StorageGateway
オンプレミスストレージをS3に連携・拡張できるサービス。ストレージのバックアップは利用可能だが、DLMと同じくバックアップの一元管理を行うサービスではない。

## おわりに
引き続き追記します。

簡単ですが以上です。
LambdaでSecretsManagerからシークレット情報を取得してみた

# はじめに
Githubから流出したソースコードに認証情報が含まれていて
問題になったというセキュリティーインシデントを見かけることがあります。
ソースコード内には認証情報をベタ書きせずに扱う事が大切です。

Lambdaで認証情報を参照したい時のベストプラクティスとして
SecretsManagerから値を取得する方法があります。
ハンズオンとして行ってみたので記事に残したいと思います。


# 環境
Lambdaのランタイム：Python3.9

# SecretsManagerでシークレット情報を作成する

SecretsManagerでは目的に応じたシークレット情報の作成が可能です。
今回は汎用的に使用できるように「その他のシークレットタイプ」でユーザー名とパスワードを作成しました。

![スクリーンショット 2022-09-15 20.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242298/799c0ed3-2f56-be8c-a09d-8462878114e9.png)

作成したいシークレットを保存するときにサンプルコードを取得することができます。
![スクリーンショット 2022-09-15 20.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242298/cd870a2c-3925-0001-6611-73b8921abbc7.png)

こちらのコードを参考にLambdaで値を参照していきます。

# Lambdaでシークレット情報を参照する

実際にLambdaからシークレット情報を取得してみましょう。
ランタイム Python3.9を作成します。

![スクリーンショット 2022-09-15 20.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242298/08856edd-f23f-9d64-065c-deaf4d2b6775.png)

ソースコードに先ほどのサンプルを例にしたコードを記載します

```python
import ast
import boto3
import base64
from botocore.exceptions import ClientError


def lambda_handler(event, context):

    secret_name = "SecretsManagerで作成したシークレットの名前"
    region_name = "SecretsManagerのリージョン"

    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
        
    except ClientError as e:
            raise e
    else:
        if 'SecretString' in get_secret_value_response:
            secret_data = get_secret_value_response['SecretString']
            secret = ast.literal_eval(secret_data)
            name = secret['name']
            pw = secret['pw']
            print(f'name:{name},pw:{pw}')
        else:
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
            

```
Deployできたらテストから実行してみます。
CloudWatchのロググループにある実行ログを確認すると無事に参照してprint表示できていることが確認できました！
![スクリーンショット 2022-09-16 7.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242298/0e12815d-51ce-1188-d8eb-ccca1b408ee0.png)
このように値を取得することでデータベースや外部APIへのアクセスに利用出来ます。

# 解説
get_secret_value_response['SecretString']でSecretsManagerのシークレット情報にアクセスできます。
辞書形式のデータですが肝心の値の箇所が文字列になっていてそのままではアクセスが難しいです。

```json
{'SecretString': '{"name":"hoge","pw":"fuga"}'
```

文字列を辞書型に変換する ast モジュールの literal_eval をつかうことで辞書として値に簡単にアクセスできます。

# おわりに
クラウドネイティブな開発として大変便利だなと思いました。
どなたかの参考になれば幸いです。
関連するレコードを結びつけたい


[フローで関連するレコードを結びつけたい](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jda2T)

```
ApexだとMap<Id,List<Contact>> というちょっと変わった変数を使って簡単にできそうです。
フローだと20個の分岐が必要みたい。　やっぱりApexの方が簡単だと思うな。
```

```
trigger xxxxxTrigger on Account (Before insert,Before update) {

   Set<Id> AccountSetId = new Set<Id>();

   for (Account acc : Trigger.new){
      AccountSetId.add(acc.Id);
   }
   List<Contact> conList =[SELECT Id,AccountId FROM Contact WHERE AccountId =: AccountSetId Order by AccountId,Id];
   String key_Id = '';
   Integr I = 0;
   Map<Id,List<Id>> conMap = new Map<Id,List<Id>>();
   for (Contact con : conList){
     if (I == 0 ) {
          key_Id = con.AccountId;
          List<Id> conIdList = new List<Id>();
     }
     if ( ke_Id == c.AccountId) {
        conIdList.add(con.Id);
     } else {
        conMap.put(con.AccountId,conIdList);
        key_Id = con.AccountId;
        List<Id> conIdList = new List<Id>();
        conIdList.add(con.Id);
     } 
     I = I + 1;
   }
   conMap.put(con.AccountId,conIdList);
  
   for (Account acc : Trigger.new){
      List<Id> IdList = (List<Id>)conMap.get(acc.Id);
      if (IdList !=null) {
         Integer max = IdList.size();
         for (Integer i = 0, i < max; i++) {
           if (i ==0) acc.1件目 = IdList[i];
           if (i ==1) acc.2件目 = IdList[i];
           if (i ==2) acc.3件目 = IdList[i];
           if (i ==3) acc.4件目 = IdList[i];
           if (i ==4) acc.5件目 = IdList[i];
           if (i ==5) acc.6件目 = IdList[i];
           if (i ==6) acc.7件目 = IdList[i];
           if (i ==7) acc.8件目 = IdList[i];
           if (i ==8) acc.9件目 = IdList[i];
           if (i ==9) acc.10件目 = IdList[i];
           if (i ==10) acc.11件目 = IdList[i];
           if (i ==11) acc.12件目 = IdList[i];
           if (i ==12) acc.13件目 = IdList[i];
           if (i ==13) acc.14件目 = IdList[i];
           if (i ==14) acc.15件目 = IdList[i];
           if (i ==15) acc.16件目 = IdList[i];
           if (i ==16) acc.17件目 = IdList[i];
           if (i ==17) acc.18件目 = IdList[i];
           if (i ==18) acc.19件目 = IdList[i];
           if (i ==19) acc.20件目 = IdList[i];
         }
      }
   }

}
   
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b5568de1-548f-1d21-a806-91058f29616c.png)
Flutter開発環境の作成　Mac編

# Flutterの開発環境の作成を解説します。
Macが対象です。Intel ChipでもAppleシリコンでもOKです。

### 現在無償配布中

https://techbookfest.org/product/mjZ2ALttiwdu9DFu1T62m3?productVariantID=8ZExvH5asUkVUZnPk2yfJJ


## Homebrewのインストール
[Homebrew]( https://brew.sh/index_ja)で、「Install Homebrew」にあるコマンドをターミナルに貼り付け、エンターキーを押します。

忘れずにpathを通し、その後、~/.zshrcを再読み込みしてください。

### gitのインストール
Macにはgitが予めインストールしたありますが、Flutter公式サイトにあるように最新版にしておきます。

```
 > brew install git
```

### asdfのインストール
Flutterは頻繁にバージョンアップしています。プロジェクト毎にバージョン切り替えができるように、「asdf」をインストールします。

```
 > brew install asdf
```

~/.zshrcに、

```
. /opt/homebrew/opt/asdf/libexec/asdf.sh
```

を追加します。


#### Flutterのインストール
asdfがFlutterのバージョン管理ができるようにプラグインをインストールします。

```
asdf install add flutter
```

これで、Flutterの各バージョンをインストール・切替ができるようになります。
##### Flutterのバージョン切り替え
最新版をインストールします。

******************************
注意：
　Flutter 3.0(だと思う・・）からインストール時に
　Intel chip、Appleシリコンでインストールされるバイナリを
　分けています。そのため判断用に「jq」が必要です。

```
 > brew insta  jq
```
で、インストールしてください。
******************************

```
 > asdf list all flutter
```
で、インストール可能なflutterのバージョンを確認できます。

最新版は(2022/09/16現在)、「3.3.2-atable」です。

```
 > asdf install flutter 3.3.2-stable
```

でインストールします。

過去の2.x系をインストールします。2.x系の最新(2022/09/16現在)は、「2.10.5-stable」です。

```
 > asdf install flutter 2.10.5-stable
```
でインストールします。


PC全体で最新版が使えるようにします。

```
 > asdf global flutter 3.3.2-stable
```

で、PC全体が「3.3.2-stable」を使います。

```
 > flutter --version
```

で確認してください。


どこか適当なフォルダへ移動し、
```
 >/dev/hoge asdf local flutter 2.10.5-stable
```
でフォルダ以下に2.x系を使うようにします。

```
 >/dev/hoge flutter --version
```

で確認します。


### cocoaPodsのインストール
cocoaPodsのインストールを行います。Flutter公式サイトにある


```
 >sudo gem install cocoapods
```
でも良いのですが、Macにインストールされているrubyは古いので、Homebrewでインストールすると、rubyやgemも管理してくれます。

```
 > brew install cocoapods
```
のほうが後々のトラブルから解放されます。

### XCodesのインストール

Appleの開発環境のXcodeもXCodesというアプリケーションを使い、バージョン切り替えができるようにします

また、XCodesを使うとダウンロードが早いです。
#### Xcodeのインストール

```
 > brew install xcodes
```
でインストールします。

GUIアプリケーションですので、ランチパッドなどから起動してください。


## Android Studioのインストール
[Android Studio](https://devloper.android.com/studio)からChipあったものをダウンロードし、インストールします。
### commandline-toolsのインストール

Android Studioを起動し、最初の画面の「SDK Manager」をクリックします。
![androidStudio12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4849/fb8a3110-96cf-5aa0-6daf-ca724259ac9c.png)

### SDK Platformのインストール
同じく、SDK ManagerからAndoroid Platform、Sytem Imageのバージョンをダウンロードします。

## エミュレータ、シミュレータ

デバイスマネージャからAndoroidエミュレータを作成します。

iOS系のiPhoneシミュレータは、Xcodeに含まれていますが、最新のiOSのみです。

過去のiOSバージョンをインストールして切り替えてテストしたい場合などは、無償配布中の本書内に図解してあります。



以上、ここまで読んでいただき、ありがとうございます。
Rustまとめ-その肆- パッケージとクレートについて理解したい

## 大きくなっていくプロジェクトをパッケージ、クレート、モジュールで管理する
### モジュールシステムの種類
モジュールシステムは、プログラムを複数のファイルに分割する方法の一つです。
- パッケージ
- クレート
- モジュール
- パス
### パッケージとクレートについて
#### Cargo newで新しくパッケージを作る
```
$ cargo new my-sample
     Created binary (application) `my-sample` package
$ ls my-sample
Cargo.toml
src
$ ls my-sample/src
main.rs
```
#### パッケージについて
- このパッケージにはsrc/main.rsしか含まれていないので`my-sample`という名前のバイナリクレートのみを持っているということになります。
- src/main.rsとsrc/lib.rsの二つを持っていたらクレートを二つ持っていることになります。
#### クレートについて
乱数を生成するプログラムを例に見てみる。
```
//呼び出すクレート
use rand::Rng;

//実行する関数
fn main(){

//1~101の間の数字をランダムに生成し変数に入れる
// rand::thread_rng()`関数を選択し
// `.gen_range(1..101)`その中のメソッドを実行(乱数を生成するやつ)

let secret_number=rand::thread_rng().gen_range(1..101);

}
```
- ``use rand::Rng;``でrandクレートのRngトレイトを呼び出しています。  
- ``let secret_number=rand::thread_rng().gen_range(1..101);``でrandクレートのthread_rng関数を呼び出しています。  
- ``let secret_number=rand::thread_rng().gen_range(1..101);``でrandクレートのgen_range関数を呼び出しています。
Qiita Daily Survey memo 2022.09.16

# Qiita Daily Survey memo 2022.09.16

Qiita の記事を可能な限り毎日読むために、読んだmemoを公開することでモチベーションを維持しようという試み。（244日ぶり）

## [フリーランスに転向して1年経た感想](https://qiita.com/ippaiattena/items/3bd48f1d975ff9649ab9)

ippaiattena 様の記事

フリーランスに転向して1年経過し、その感想を体験を交えて書いてくださっている記事になります。

タイムリーな記事で、真っ先に目に止まりました。
ものすごく親しい人が、今月末で会社を退職することになり、自分も身の振り方を考えなければなー…とちょうど考えていたところでした。

記載されている感想の、良かった点も、悪かった点もフリーランス未経験の私ですが、思い描いている通りの感想を書かれており、強く興味を引かれました。

ippaiattena さんは、Twitter にさえ投稿されたことがない中、記事を書いてアウトプットするというチャレンジをされた、とのこと。
フリーランスとして活動していくなかで、様々なことにチャレンジすることに前向きな姿勢になった中で、チャレンジの一環なのだろうなと感じました。

特にウラヤマシイと感じた項目は「仕事に対する自信や意欲が上がった」で、評価（レスポンス）が直に返ってくるので、仕事や人間関係に対する向き合い方が、会社員の立場からは違うのだろうなと思いました。

エネルギーをいただける記事をありがとうございます！

## [【サボりたいエンジニア向け】コーディングに役立つチートシートまとめ](https://qiita.com/saboriman/items/b7461f0ab5526845a0a5)

saboriman 様の記事。

タイトルの通り、チートシートをまとめてくださった記事になります。

一番初めに VSCode のショートカット集が記載されており、「VSCode のショートカットのチートシートありがたい！！」と思ってじっくり眺めていました。
が、HTML, CSS と続き、様々なジャンルのチートシートをまとめてくださっている記事になっています。

「そういえば、アレどうだっけ」と、調べれば分かるが面倒くさい…に簡単にアクセスできるチートシートは、本当に助かります。
VSCode のショートカットだけで、試してみたいことが多くあり、他シートも後でじっくり拝見させていただきたいと思います！

私もチートシート作成に挑戦したことがありますが、テキストベースのメモ止まりで、1枚でいい感じのデザインで！というのが非常に難しいことを体感しました。
ここまできれいにまとまっているシートがたくさんあるのは、本当に先人たちに感謝が絶えないです。

## [Heroku無料枠廃止で路頭に迷う開発者に捧ぐ、次世代PaaS「Render.com」の使い方](https://qiita.com/mycndev/items/fc7a8fecd7d0b0d09828)

mycn ( mycndev ) 様の記事

タイトルの通り、Heroku難民の方に次の無料で使えるPaaSを紹介してくださっている記事になります。

Heroku 使ってみたい使ってみたい詐欺をしている間に、私の誕生日に無料枠廃止のアナウンスがされてしまったようです。悲しい。
それを受けて、無料で使えるPaaSの「Render.com」を紹介してくださっています。
デプロイの方法まで記載されており、そのステップの簡潔さがわかります。

注意として、Posgresql は無料期間が最初の90日だけとのことですので、こちらはご注意ください。
いくつかローカルで動くサイトは作って見たことがあるので、ちゃんとGit管理して、Webで公開するところまでチャレンジしてみたいです。
LPC812MAXとWS2812B(3個)でランダムに光らせる。



x mbed2リビジョン144
x リビジョンを変更できる人むけ

x ws2812bがなぜ3個なのかと言うと2,3個で電流が超えるらしい(なんの)
x 軽量高速化


目的
GPIOのテスト
WS2812のテスト

LPC812

説明
WS2812Bの接続ピンは、P0_6です。


![o_con754.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2b92dc4b-87f8-bbf3-4346-039b1e7a3fef.jpeg)





```c++



//WS2812_LED3_RAND_812_1

#include "mbed.h"

//GPIOの宣言
DigitalOut myled(P0_6);

//ビットパターン
//             654321009876543210
#define on1    0b0000000001000000
#define off1   0b0000000000000000

//LEDの配列
int l[90]; //max30 led

//プロトタイプ宣言
void bit_on1();
void bit_off1();

//             12345678   12345678   12345678   12345678
int b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
             0b00001000,0b00000100,0b00000010,0b00000001,
            };

//WS2812Bに転送する バイト単位
int ws_led(int num1)
{
    int on_off;

    __disable_irq(); // disable interrupt
    //__enable_irq(); // enable interrupt



    for(int ii=0; ii<num1; ii++) {

        //8ビット分送る
        for(int jj=0; jj<8; jj++) {

            on_off = l[ii] & b8[jj];

            if( on_off == 0 ) {
                //ビットが0
                bit_off1();
            } else {
                //ビットが1
                bit_on1();
            }//endif

        }//for 8bit


    }//for max30byt

    //__disable_irq(); // disable interrupt
    __enable_irq(); // enable interrupt

    return(0);
}

//メイン関数
int main()
{

    //無限ループ
    while(1){

        //ランダムの設定
        for(int ii=0;ii<9;ii++){
            l[ii] = rand()%52;
        }//for

        //ws2812bへデータを送る
        ws_led(9);

        //1秒待つ
        wait_ms(100);

    } //while

} //main

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
void bit_off1()
{
    //0.3us 800khz

        LPC_GPIO_PORT->PIN0 = on1;

        __NOP();
        __NOP();
        __NOP();
        
        LPC_GPIO_PORT->PIN0 = off1;
        
        __NOP();
        __NOP();

        //LPC_GPIO_PORT->PIN0 = off1;

        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();

        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();

}//bit_off1

// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1()
{
    //1us 800khz

        LPC_GPIO_PORT->PIN0 = on1;

        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();

        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();

        LPC_GPIO_PORT->PIN0 = off1;

        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();

}//bit_on1




```



![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c679f39a-8cd6-d2d8-fc49-4b43707b6d1c.jpeg)


-27-
Goで package ... is not in GOROOT エラーが発生した時の自己解決備忘録


# 前提条件
### 今回のgoバージョン
- golang:1.19.1-alpine (dockerイメージ)

## 参考にしたサイト
https://qiita.com/fetaro/items/31b02b940ce9ec579baf

上記のサイトより、二つの挙動があることがわかった。
- GOPATHモード
- モジュールモード


## 現在のモードを調べる
なんでも良いので外部のライブラリをimport文に含めて、`go run`を行う。(go getしない)
```go:~~.go
import (
    "go.mongodb.org/mongo-driver/mongo"
)
```

エラー文に `~~/scr/~~`のパスが表示された場合、同じ解決策が通用するかもしれない。


# 解決方法
```shell:ターミナル
$ go mod tidy
```
- [tidyについて](https://note.com/artefactnote/n/n6709b53a318f)


## 補足
多くのwebページで go.modファイルに`replace`を利用する例が多かったが、不要だった。

importのモジュール名は以下のURLで以下を参考すると良いと思います。
- ディレクトリ構成（go.modと並列に置かれたgoファイル）
- go.mod中の module名

https://qiita.com/fetaro/items/31b02b940ce9ec579baf#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7%E3%81%AE%E5%86%85%E9%83%A8%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AEimport

https://zenn.dev/ajapa/articles/0232dddfc160e4

## +a

自分もこんなミスしたので置いておく。（外部から読み出せる名前は1文字目が大文字の制約）

https://qiita.com/rf_p/items/3c93728f10c4d02f3bcd
GiNZA入門２（基本操作編１）（基本的な使い方マスターを目指す方向け）

こんにちにゃんです❕
GiNZA入門に関する記事２本目です。
この記事ではGiNZAの基本的な操作方法について書いていきます。
まず主にGiNZAで出来ることは次の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/20b2695a-2063-3406-593e-1126415285dd.png)
一つ一つ説明していきます。

まずGiNZAを用いるために、spaCyをインポートします。
そうしたらそのあとGiNZAのロードを行い、nlpという変数に渡します。
GiNZAではdocクラスというものがあります。
docクラスはこの後説明する解析の結果を保持するクラスで、doc=nlp(文章（str型）)で解析が完了します。
簡単に言うと文章とそれに関する情報をまとめて持っているというイメージです（どこからどこまでが一つの単語かなど）


```ruby:sent_div.py
import spacy

nlp=spacy.load('ja_ginza') #GiNZAのロード

#GiNZAの使い方を説明します。
#GiNZAは1⃣文境界解析、2⃣形態素解析、3⃣係り受け解析、4⃣固有表現抽出、5⃣類似度計算が出来ます。
#docクラスは解析結果を保持するクラスで、doc=nlp(文章)で解析が完了します。(nlpはtextからdocクラスを生成するコマンドです）
```

GiNZAのロードができたら、ついに解析に移ります。
GiNZAでできること一つ目は文境界解析です。文境界解析は文章を文ごとに分割するプロセスです。
句点（。）で分解するということです。

```ruby:sent_div.py
#①文境界解析
doc=nlp('こんにちは。今日は天気がいいですね。今日はどこに行きますか。')
for sent in doc.sents: #文章群の中から文章を一つずつ抽出
    print(sent) #文を表示 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/b980f252-c29a-00da-b2c0-22e71df4db19.png)

このような感じに分割してくれます。
GiNZAで出来ること２つ目は形態素解析です。
そもそも形態素って何って感じの方が多いと思います。
形態素は「名詞」、「助詞」、「形容詞」など、文の最小の単位のことを言います。
例えば「すいかを食べる。」は「すいか」、「を」、「食べる」に分解できますが、これ以上分解はできない（すると意味が分からなくなる）ので３つの形態素からできていることがわかります。
形態素解析はこんな感じで文をGiNZAが分解してくれます。

```ruby:mono.py
#②形態素解析
doc=nlp('今日は天気が良くない。')
for sent in doc.sents: #文章群の中から文章を一つずつ抽出
    for token in sent: #文章の中から形態素を一つずつ抽出
        print(
            str(token.i)+', '+ #形態素の番号
            token.text+', '+ #分解した形態素
            token.lemma_+', '+ #語彙素（原形みたいなもの）
            token.pos_+', '+ #品詞
            token.tag_ #品詞詳細
        )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/4e3ff406-32aa-2374-b034-17e59c8d98f0.png)

コードと実行結果を見るとイメージがつきやすいと思います。
GiNZAで出来ること３つ目は係り受け解析です。
係り受け解析は形態素と形態素の関係を調べることを言います。
例えば「赤いリンゴ」は「赤い」が「リンゴ」を修飾しています。
このように形態素同士の関係を調べることができます。

```ruby:syusyoku.py
#③係り受け解析
doc=nlp('今日は天気がいいですね。')
for sent in doc.sents: #文章群の中から文章を一つずつ抽出
    for token in sent: #文章の中から形態素を一つずつ抽出
        print(token.text+' ← '+  #形態素
        token.head.text+', '+  #形態素を修飾している語
        token.dep_)  #修飾・従属関係
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/fc4366dd-ed4a-0920-0e8c-6ce4ee56ffcf.png)

今回はここまでにしようと思います。
次回は固有表現抽出と類似度計算について書くつもりです。
では、ばいにゃん～


参考にさせていただいた記事
https://qiita.com/poyo46/items/7a4965455a8a2b2d2971
terraformでsensitiveな値を平文として取り扱えるようにする


## やり方

`nonsensitive(aws_ssm_parameter.maintnance_mode_control.value)`のように書く

## サンプル

```tf
resource "aws_ssm_parameter" "maintnance_mode_control" {
  name  = "/test/MAINTENANCE_FLAG"
  type  = "String"
  value = "0"

  lifecycle {
    ignore_changes = [
      value
    ]
  }
}

output "data" {
  value = nonsensitive(aws_ssm_parameter.maintnance_mode_control.value)
}
```
Splatoon3のドット打ちをドック接続でやりたい

[こちらの記事](https://qiita.com/teityura/items/b80c4608088ebc7cf176)を読んでやりたくなって、ELEGOO UNO R3 を買って試してみました。
やっぱりめちゃくちゃ楽。しかし一つだけ欠点があって…
『電池の減りが心配』ということ。
じゃあドック接続すればいいじゃんと思いやってみると、Proコンの接続まではいいんだけどAキーを押さないと画面が戻れずめちゃくちゃずれる。

# じゃあAボタンを押す動作を追加しようというわけで
上の記事でも使っている`Switch-Fightstick`の`Joystick.c`を編集します。
```C:Joystick.c
# @@ -181,6 +181,10 @@ void GetNextReport(USB_JoystickReport_Input_t* const ReportData) {
    switch (state)
    {
        case SYNC_CONTROLLER:
+           if (report_count == 10)
+           {
+               ReportData->Button |= SWITCH_A;
+           }
            if (report_count > 100)
            {
                report_count = 0;
```
`Joystick.c`の181行目付近、`GetNextReport()`内のswitch文に書き加えます。
内容は簡単で、`report_count`が10回目の時にAボタンを送信しているだけです。つまりデバイスが認識されてからAボタンを押して画面を戻しているわけです。
別に10カウントに意味はありません。読み込んでからある程度置きたいなって思ったからです。~~心配なら書き始める判定をしているのが追記部分の1行下の`report_count > 100`なのでこの`100`をもう少し大きくしてやるといいかも。~~**ダメでした。普通によくわからんズレ起きます。ここ書き換えなくても失敗することはなさそうです。**

あとは記事通りに`make`して`dfu-programmer`で書き込んで完成です。

# まとめ
すぐ実装できて簡単に接続できるようになったのでいいとおもいました！(小並感)

## 追記 (2022/09/16 2:00)
書き終わった後そのままにしておくとスリープでロストすることが多々あったので修正。

```C:Joystick.c
# @@ -221,9 +229,10 @@ void GetNextReport(USB_JoystickReport_Input_t* const ReportData) {
            state = MOVE_X;
            break;
        case STOP_Y:
            if (ypos < 120 - 1)
+           {
                state = MOVE_Y;
+           }
            else
+           {
+               ReportData->Button |= SWITCH_MINUS;
                state = DONE;
+           }
            break;
        case MOVE_X:
```

マイナスキーでとりあえず保存するようにしました。あとはもう一回開いたときに保存されてるようになってます。

さらに僕の環境だと1番細いペンに自動でならなかったので修正。
```C:Joystick.c
# @@ -197,6 +201,10 @@ void GetNextReport(USB_JoystickReport_Input_t* const ReportData) {
            report_count++;
            break;
        case SYNC_POSITION:
+           if (report_count == 200)
+           {
+                   ReportData->Button = SWITCH_L;
+           }
            if (report_count == 250)
            {
                report_count = 0;
```

Lボタンを押して調整するようにしてあります。
Blender奮闘記③

# 初めに
yukiさんの動画を元にクリームソーダを作りました。また、おさらいとしてコーラを作成しました。クリームソーダの最後の仕上げとしてビールを作ることにしました。

# Beer作成途中

ひとまずジョッキと中の液体まで作りました。
![Beerの途中経過.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/296112dd-db87-f55f-2cf4-c5c8262f04f6.png)

ジミーに大変だったのが上の泡づくり。
こちらは円柱に対してベベルをかけ、アイスクリームのテクスチャ作成をベースに作成しました。

![Beerの作成結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/e88b8bad-2e9a-4c43-0a71-d19d348d7649.png)

作り上げた結果がこれです。
それっぽいものができたのではないでしょうか。

# 終わりに
クリームソーダ作成のおさらいとしてビールを作成しました。
これにてyukiさんの動画であるクリームソーダを作ろうをある程度は理解したといえるのではないでしょうか。
これからもどんどんBlenderでモノを作成していきたいです。
Google Cloud の Cloud IAM の 拒否ポリシー

# はじめに
IAMを操作していたところ、権限を付与する際に、基本ロールはもちろんですが、
事前定義ロールでも範囲が広いようなケースもあると思い、絞る方法を確認してみました。

# IAM Roleの基本的な部分のおさらい

https://cloud.google.com/iam/docs/understanding-roles?hl=ja#predefined_roles

## 概要
IAMに対しては基本的にRoleを付与する形になり、ポリシーを直接付与するようなことはありません。
大きく基本ロール、事前定義ロール、カスタムロールがありまして、それぞれの役割に軽く触れます。

## Role種別

- 基本ロール
    - 少ないので具体的に書くと、オーナー、編集者、閲覧者がある。
        - 位置づけ的には、オーナーがadmin、編集者がPowerUserっぽい、閲覧者がReadOnly
            - PowerUserという表現はちょっと過大でもう少し権限が絞られているので、それプラス事前定義ロールを割り当てていたりすることもある
- 事前定義ロール
    - 基本ロールはサービス全体に対する権限だったが、一つのサービスに対して実施した役割に応じて分けられているようなイメージ
    - 基本ロールもだがGoogleにて管理され、新たなサービスなどが加わった場合、事前定義ロールの内容も入れ替わる
    - 下位互換性がないものはベータ版やアルファ版と呼ばれ、本番環境での適用が推奨されておらず、本番環境では一般提供されているものを適用することが推奨されている
- カスタムロール
    - 各Roleに含まれる権限を用途や役割に合わせて自身でRoleを作成することが可能
    - 計画的に組み込めない場合や管理が行き届かない何でもコミコミみたいになってしまいそう

## Roleの付与
基本ロールでは範囲が広い部分もあるので最終的には事前定義ロールのみで構成できると良いと思います。
ただ、対応するプロジェクトの要件によって、権限の範囲は変わってくるので、最初は基本ロールを割り当てないと
プロジェクトの進捗に影響が出る場合もあると思うので、要件や状況に応じた実装が必要となります。
基本ロールで割り当てた場合でも、以下の赤枠箇所のように割り当てた権限に対してどの程度利用されているかが確認できるので、
それをもとに事前定義ロール、カスタムロール、そのまま基本ロール等、あとから検討するような方法もあるのかな、と思います。
![スクリーンショット 2022-09-16 0.28.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/3d9da66a-be70-c68a-3c25-943bda188e17.png)



# 既に設定したRoleの権限を絞る(制限する)方法
ここからがもともと書きたかった部分です。

## 拒否ポリシー
まだプレビュー機能ですが、拒否ポリシーという機能があります。これを利用することで適用していたRoleの中でも実行させたくない権限をプリンシパル単位で、拒否ポリシーとして制御することが可能です。

https://cloud.googles.ltd/iam/docs/deny-overview?hl=ja

## 概要

https://cloud.googles.ltd/iam/docs/deny-access?hl=ja

### 必要なRoleを付与
以下対象RoleをIAMに付与します。
対象：拒否管理者（roles/iam.denyAdmin）
ポリシー内容：拒否ポリシーを表示、作成、更新、削除する: 

### ポリシーを定義する
拒否ポリシーは以下のようにどのプリンシパルに対してどの権限を拒否する、
というような形で定義することが可能です。
```
{
  "displayName": "POLICY_NAME",
  "rules": [
    {
      "denyRule": DENY_RULE_1
    },
    {
      "denyRule": DENY_RULE_2
    },
    {
      "denyRule": DENY_RULE_N
    }
  ]
}
```

例
```
{
  "displayName": "XXXXXXXXX",
  "rules": [
    {
        "denyRule": {
            "deniedPrincipals": [
                # 対象プリンシパル(ユーザやサービスアカウントなど)
                "principal://iam.googleapis.com/projects/-/serviceAccounts/サービスアカウントメールアドレス"
            ],
            "deniedPermissions": [
                # 対象権限
                "storage.googleapis.com/buckets.list"
            ]
        }
    }
  ]
}
```
拒否可能な対象の権限は以下になります。
https://cloud.googles.ltd/iam/docs/deny-permissions-support?hl=ja

### ポリシーを作成する
作成コマンドを実行します。
```
gcloud beta iam policies create POLICY_ID \
    --attachment-point=ATTACHMENT_POINT \
    --kind=denypolicies \
    --policy-file=POLICY_FILE
```
結果を以下で確認することができます。
```
gcloud beta iam policies get POLICY_ID \
    --attachment-point=ATTACHMENT_POINT \
    --kind=denypolicies \
    --format=json
```

本来、このあと動作を確認し拒否されることを確認します。

# 所感
事前定義ロールでも様々なロールで分かれているので問題ないかもしれませんが、
手順も難しくなくポリシー内容も明快なので、今後柔軟なポリシーを組む上では、
GAが待たれる機能の一つではないか、と思います。
ガードレールな使い方ができるものだと思うので、欲しい機能なのかな、と思いました。
GiNZA入門１（導入）（基本的な使い方マスターを目指す方向け）

初めまして。
水色桜（みずいろさくら）と申します。
この記事群では自然言語処理ライブラリGiNZAの使い方について簡単に説明していこうと思います。
最終的には感情分析プログラムの作成まで書いていきたいと考えています。
この記事はGiNZAの簡単な説明と、導入方法についてです。

まず、そもそも自然言語とは何？とお思いの方もいらっしゃるかと思います。
「自然言語」とは「日本語」や「英語」のような普段人間が使っている言葉です。
単に「言語」と言ってしまうとプログラミング言語を含んでいるみたいになってしまうので、対比の意味もあって、「自然言語」と言います。
自然言語処理というのは普段人間が使う言葉をうまい具合に処理して、会話をしてみたり、文章に含まれている感情を検出したりすることを目指しています。

たくさんの研究者さんの努力のおかけで、自然言語処理をするための道具、ライブラリにはいくつか種類があります。有名どころだとMecabなどが挙げられます。今回説明するGiNZAはその中でも導入（パソコンに入れる）のが簡単で、高精度な解析ができる優れものです。GiNZAを開発されたリクルートさんと国立国語研究所さんには感謝してもしきれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847349/2e8df5eb-76da-5d01-4a3f-30ccbeabcb20.png)

GiNZAはspaCyというライブラリを元に作られています。spaCyはExplosion社さんが提供している自然言語処理ライブラリで、アメリカなどでは人気のあるライブラリです。製品利用を念頭に尽きられているためとっても使い勝手が良いのですが、なんと２０１９年までは日本語には対応していませんでした。そこでリクルートさんと国立国語研究所さんが日本語の学習済みモデルを作成し、さらに導入を超簡略化までしてくれました❕

GiNZAの導入はコマンドプロンプトなどで

```ruby:ginza_in.rb
cd [pythonのあるディレクトリ]
pip install ginza
```

と入力するだけです。本当に簡単!!
今回はここまでにしたいと思います。
次回はGiNZAできることをソースコードを示しながら簡単に説明するつもりです。
では、ばいにゃん～。


参考にさせていただいた記事
https://qiita.com/poyo46/items/7a4965455a8a2b2d2971
AMD GPU Mac で stable-diffusion-webui

# 概要

Macでmpsを使って[stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)を動かせたのでメモ

# 環境

- iMac 2019
- Intel Core i5
- Radeon Pro 560X 4GB
- conda 4.14.0
- [stable-diffusion-webui @ d4dc4c1c633e27e7cb1a7208e8c39376dbee2d97](https://github.com/AUTOMATIC1111/stable-diffusion-webui/tree/d4dc4c1c633e27e7cb1a7208e8c39376dbee2d97)

# 手順

## weightの配置

wikiにはStable Diffusionのweightの配置場所は`in the base directory`と書いてあったが、デフォルトだと`repositories/stable-diffusion/models/ldm/stable-diffusion-v1/model.ckpt`を参照するようだ。\
別の場所に置いている場合やwaifu版など別のを使いたい場合は実行時の`--ckpt`オプションで指定すればよいだろう。

## 仮想環境を用意

```shell
conda create -n sdw python=3.8.5
conda activate sdw
conda install pytorch torchvision -c pytorch-nightly
```

## CUDA向けのコード等を書き換える

1. `launch.py`
    ```diff
    -run_python("import torch; assert torch.cuda.is_available(), 'Torch is not able to use GPU'")
    ```

1. `repositories/CodeFormer/facelib/detection/yolov5face/face_detector.py`
    ```diff
    -IS_HIGH_VERSION = tuple(map(int, torch.__version__.split('+')[0].split('.'))) >= (1, 9, 0)
    +IS_HIGH_VERSION = True
    ```

1. `repositories/stable-diffusion/ldm/models/diffusion/plms.py`
    ```diff
    -            if attr.device != torch.device("cuda"):
    -                attr = attr.to(torch.device("cuda"))
    +            if attr.device != torch.device("mps"):
    +                attr = attr.to(torch.float32).to(torch.device("mps")).contiguous()
    ```

## 実行

```shell
PYTORCH_ENABLE_MPS_FALLBACK=1 python launch.py --precision full --no-half 
```

Sampling methodによってはうまくいかないようだ。全て試してはいないが、PLMSは安定している。

# 実行中の様子

一応GPUを使えているようだ。
![スクリーンショット 2022-09-15 23.51.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116602/f3df2cf7-ece9-c854-48d5-dd0166037dd3.png)

# 参考

https://yaritakunai.hatenablog.com/entry/stable-diffusion-mps
HackTheBox Writeup: Appointment

## 概要
HackTheBox:Appointmentのflagを入手する手順を記す。

## Port Scan
```terminal
$ nmap -A -sV appointment.htb 
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-15 10:35 EDT
Nmap scan report for appointment.htb (10.129.42.72)
Host is up (0.25s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Login
|_http-server-header: Apache/2.4.38 (Debian)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 63.48 seconds
```
port 80でhttpを提供していることが分かる。

## Port80にアクセスする
http://appointment.htb にアクセスすると以下のページが現れる。
![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550473/3ba863c5-3d77-a8ed-a20c-4ecad32ece22.png)
admin/root/passwordで試してもログインできない。

## SQL Injectionを試行する
有名所のSQL Injectionを試してみる。
以下の内容を試してみる。

- Username : admin
- Password : ' or '1'='1

最終的にこのInjectionは成功し、flagが画面に表示される。

## SQL Injectionの中身について
先ほど行ったInjectionは以下の原理で成功する。

```
password='%s' 
```
となる部分の%sに
```
' or '1'='1
```
を代入すると
```
password='' or '1'='1'
```
という内容になり、条件式が常に真となってしまう。
SQL作成ツール(insert文)

SQL(insert)を自動で作成してくれるツール

製造時にinsertとか結構行うので、どの現場でもサクッと作れるように記事に残しておく。
(insert文書くのめんどい)
基本ここ見ながら10分もあれば作成できると思う(見た目は気にしないで)

# 全体像
以下の画像の通り


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935552/eac2165f-af5c-7cd9-86f2-d9c5cd38826c.png)

B1にinsert文の冒頭部分を入力(テーブル名の部分はB2の値をセット)

3行目のB以降にカラム名を書いていく

B4に「VALUES (」までを記載

あとは実際に入れたい値を横並びに書く



いろいろ書いたけど、以下の通りにシートに書き込めばできる。

B1→「="INSERT INTO " & B2 & " ("」
B2→「テーブル名」
B3~→「値を追加したいカラム名」
B4→「=JOIN(",", B3:F3) & ") VALUES ("」
B7~→「カラムに対応する値」
値の最終列の右隣のセル(H列)→「=B\\$1 & B$4 & "'" & JOIN("','", B7:E7) & "');"」
複数作成したい場合は↑を複製していけばOK


カラムの数とかによって若干調整しなければいけないことが玉に瑕だけどそんなに手間もかからないからテーブルごとに作成すればよいかな。

時間があるときにGASで本格的なの作成してみようかな。。。
シェルについて

# シェルについて
## 初めに
何となくしか理解できていなかった分野。3回目はシェルについてです。コマンドプロンプトやPowerShellで使っているあれ。それぞれ種類が違うというのは知っていますが、説明しろと言われたら使うコマンドが違うくらいしか答えられないです泣。なので今回もそもそもシェルとは、シェルはどんな種類があるか等をまとめていきたいと思います。

## シェルとは
そもそもシェルとは、OSを構成するソフトのうちの1つで、ユーザーからのリクエストの受付や、利用者への情報の提示などを担当するもの。OSの種類によってカーネルなどと一体のパッケージとして提供されるものと、UNIX系のように、異なるシェルからユーザーが選べるようになっているものがある。シェルは2種類あり、CLIを提供するコマンドラインシェルと、GUI操作を提供するグラフィカルシェルの2種類がある。

## シェルの種類について

### bash
UNIX上で昔からあるシェルでBourneシェル系のshがあり、そのshに拡張機能を加えたのがbashになる。Linuxの標準シェル。

### csh
Cシェル系でC言語に構文が似ているのでC言語を触ったことのある人には向いている。

### zsh
Cシェル系とBourneシェル系のいいとこどりをしたシェル。

ここまでUNIX系の話しかでてきていません。Windowsのコマンドプロンプトで使用されているシェルはなんていうシェルなのかなと調べていましたが、答えが出てきません。。。
そんなとき下記のサイトで、本来はコマンドプロンプトもシェルといえるが、一般的にはUNIX系OSのそれを指してシェルと呼ぶらしいです。慣例的なものなんですね！

https://wa3.i-3-i.info/word11219.html

そしてそういえば上でシェルは2種類あってCUIとGUIがあるという説明をしました。ここまで全部CUIじゃないか！ということでGUIシェルの説明です。（Windowsエクスプローラーを例に）

### Winowsエクスプローラー
Windows機能の1つで、ユーザーに獅子打てむの基本的な操作画面や、ストレージ内のファイルやフォルダの管理機能などを提供するもの。OSの構成要素のうちシェルと呼ばれるもの。Windows起動後に自動的に実行されファイルやフォルダの一覧野草などの機能を提供する。Windowsにはエクスプローラー以外に、コマンドプロンプトやPowerShellなどのCUI系を採用したシェルも提供されている。

https://e-words.jp/w/Windows%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%97%E3%83%AD%E3%83%BC%E3%83%A9.html

こちらのページだとコマンドプロンプト、PowerShellはシェルと表現されていますね。

## まとめ
今までシェルというとCLI操作する際に使用しているものというイメージが強かったですが、GUI操作も含めて言うものだとわかりました。なので誰しも意識しないうちにお世話になっているということですね。
また、結構昔に何かのツールをインストールする手順とかであまりわからないままシェルを変更とか記憶も呼び覚まされました(笑)

♯# 参考ページ
https://e-words.jp/w/%E3%82%B7%E3%82%A7%E3%83%AB.html
https://recruit.cct-inc.co.jp/tecblog/os/shell/
https://www.engineer-route.com/column/3010/
https://academy.gmocloud.com/keywords/20170324/4010
Teamsのプレゼンスを退席中（黄色状態）にならないようにする【簡単・コピペ】


## はじめに

リモートワークでTeamsを使ったことがある方は一度は思ったことがあるはずです。
「 PCを5分間操作しないだけで退席中の表示になるのが煩わしい 」と。
この問題、Teams設定やPCのスリープ時間設定等では解決できないと[マイクロソフトのQA](https://answers.microsoft.com/ja-jp/msteams/forum/all/%E9%80%80%E5%B8%AD%E4%B8%AD%E3%81%A8%E8%A1%A8/879544fe-66f8-4634-8820-8ab63442c828)にあります。

では、どうするか。
物理的にマウスを動かすからくりを作るのはハードル高いです。
マウスカーソルを一定間隔で動かすツールがネットには転がっていますが、
ダウンロード行為はリモートワーク下では監視されている可能性が高くリスクを伴います。

自作プログラムならばコスト、リスクを最小限に抑えることが可能です。

## 実行方法
1.  windowsのマーク+rで「ファイル名を指定して実行」を開く
2.  `powershell`と入力してOKを押す
3.  開かれた青いコンソール画面に、以下のプログラムをコピー＆ペーストする
```powershell
param($minutes = 60)

$myshell = New-Object -com "Wscript.Shell"

for ($i = 0; $i -lt $minutes; $i++) {
  Start-Sleep -Seconds 60
  $myshell.sendkeys(".")
}
```
## プログラム内容
60分の間、1分間隔でキーボードの`,`が押されるプログラムです。
実行状態でテキストエディタなどにカーソルを合わせると1分間隔で`,`が自動入力されることを
確認できると思います。
実行を中止したい場合は`ctrl + c`で抜けましょう。

・[引用元](https://stackoverflow.com/questions/15835941/powershell-mouse-move-does-not-prevent-idle-mode)
【Laravel】「ログってなによ」

# ログとは

人間さん「ログを出力するとかロガーとか聞くけど」
人間さん「そもそもログってなんなのよ」

いぬ先生「急に来たね」
いぬ先生「storage/logs/laravel.log に出力されてるよ」

人間さん「ファイル見にいったけど」
人間さん「なにかずらずら書かれてることはわかった」
人間さん「でなんなの？」

いぬ先生「ここに書かれてるから読んでね」

https://readouble.com/laravel/8.x/ja/logging.html

人間さん「初っ端から何言ってるかわかりません！」

いぬ先生「うん！ごめんね！」
いぬ先生「ログは、アプリケーションの動作検証やユーザーのアクセス状況など」
いぬ先生「ある時点の事実を記録するものなんだ」

人間さん「なるほどなるほど」
人間さん「で、どういうことができるの？」

いぬ先生「例えば、アプリケーション運用での障害検知や障害の原因究明」
いぬ先生「データ分析での活用などがある」
いぬ先生「ログにはさまざまな利用用途があるから」
いぬ先生「正しいログ生成は重要なことなんだ」

人間さん「ログって大事なのね～」

# 出力してみる

人間さん「実際にどう使うの？」

いぬ先生「ログの操作は、Logファサード経由、」
いぬ先生「またはPsr\log\LoggerInterfaceインターフェースを実装しているから…」

人間さん「ちょ、もう少しわかりやすく頼んます」

いぬ先生「ログを出力するにもいろんな方法があるということだよ」
いぬ先生「まず細かいことはさておき」
いぬ先生「シンプルな例で出力をしてみて雰囲気を掴んでみよう」

人間さん「それはありがたい」

いぬ先生「例えば、ヘルパー関数 logger() をコントローラーに含める」
```php
class TestController extends Controller
{
    public function store(Request $request)
    {
        logger($request);
    // 以下略
```
いぬ先生「こうすると送信されたリクエスト値が」
いぬ先生「storage/logs/laravel.log ファイルの末尾に出力される」

人間さん「本当だ！」
```php
[2022-09-08 00:00:00] local.DEBUG: array(
    // 中データは例です
    'id' => '1',
    'text' => 'test',
)
```
人間さん「中身が配列で出力されました」

いぬ先生「こちらの記事がLaravelのログ出力方法の参考になるよ」

https://qiita.com/ucan-lab/items/99f9f4989a894de1aea0

# ロガーとは

人間さん「ちなみにロガーってのはなんなの？」

いぬ先生「何らかのログを記録する機能のことを一般にロガーと言ったりするみたい」
いぬ先生「Laravelで言えばさっき紹介した出力もロガーにあたるね」

人間さん「メソッド名もloggerだもんね」

# きっかけ

いぬ先生「そういえばなんで急にログのこと気になったの？」

人間さん「非同期(Ajax)で取得したデータの中身を見たくて、dd()でデバッグを試したら」
人間さん「ページが切り替わってしまうからか確認できなくて」
人間さん「どうにか見る方法ないかなって探してて」
人間さん「ロガーを使ったら良いことに行き着いたんだけど・・・」

https://qiita.com/hubtakaya/items/8a2028e3c4da97253e48

いぬ先生「そもそもログってなんぞやってことだったのね」

人間さん「お恥ずかしながら」

いぬ先生「みんなも最初は無から始まってるから恥じることないよ」

人間さん「ぬくもりを感じる」

# 参考
https://maasaablog.com/development/laravel/3497/
【C#】PictureBoxにマウスで線を引く【ペイント】

特にBitmapやGraphicsの使い方など、見返すとき用。
```C#
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace ImageEditing
    {
        public partial class frmPaintTool : Form
        {
            //変数
            Bitmap _newBitMap;              //ビットマップ画像
            bool _mouseDrug;                //マウスクリック中のフラグ
            int _prevX;                     //前のマウスカーソルのX座標
            int _prevY;                     //前のマウスカーソルのY座標
    
            public frmPaintTool()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                //BitMapオブジェクトを生成する
                _newBitMap = new Bitmap(DrawingPicBox.Width, DrawingPicBox.Height);
            }
    
    
            private void DrawingPicBox_MouseDown(object sender, MouseEventArgs e)
            {
                //マウスクリック開始判定
                _mouseDrug = true;
                //マウスカーソル位置記憶の初期化
                _prevX = e.Location.X;
                _prevY = e.Location.Y;
            }
    
            private void DrawingPicBox_MouseUp(object sender, MouseEventArgs e)
            {
                //マウスクリック終了判定
                _mouseDrug = false;
            }
    
            private void DrawingPicBox_MouseMove(object sender, MouseEventArgs e)
            {
                //マウスクリック中に、BitMapにGraphicsオブジェクトで描画する
                if (_mouseDrug == true)
                {
                    //BitMapからGraphicsオブジェクトを生成
                    Graphics objGrp = Graphics.FromImage(_newBitMap);
                    //描画に利用するペンの色、太さを設定
                    Pen objPen = new Pen(Color.Black, 3);
                    //指定したペンでマウスの位置に線を引く
                    objGrp.DrawLine(objPen, _prevX, _prevY, e.Location.X, e.Location.Y);
                    _prevX = e.Location.X;
                    _prevY = e.Location.Y;
                    objPen.Dispose();
    
                    //BitMapオブジェクトをPictureBoxに表示する
                    objGrp.Dispose();
                    DrawingPicBox.Image = _newBitMap;
                }
            }
        }
    }
```
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666090/4de904a6-1851-ec74-2d40-8514c84d077d.gif)
PictureBoxはプロパティで背景色を白色に変更

PictureBoxのMouseDownイベントで、マウスのクリックを検知
PictureBoxのMouseUpイベントで、マウスのクリック解除を検知
PictureBoxのMouseMoveイベントで、線を引く処理を呼び出す(マウスクリック中のみ)

線を描くにはDrawLine()を使用する
クリック中にマウスがPictureBoxの上で動いたら、そのマウスの位置に線を描画し、それをPictureBoxに表示する


参考にしたサイトです

http://sssignal.web.fc2.com/column/column4.html
40歳初心者pythonでタプルを書き換えられるじゃん！

pythonのタプルって書き換えられないってあるけど、書き換えられました
っていうかこういう方法あるんだなぁ～ってびっくりしました

海外SNSのどっかでみつけた

l=(1,2,3,4,5)
print(l)
s1,s2,s3,s4,s5 = l
s2 = 6
l = s1,s2,s3,s4,s5
print(l)

結果
(1, 2, 3, 4, 5)
(1, 6, 3, 4, 5)
[Power BI] ハードウェア選択のコツ

# はじめに

こんにちは、前回の更新からだいぶ時間がたってしまいました…。
今回は、Power BI Desktop を使うにあたっておすすめの **ハードウェアスペック** をご紹介します！
(こちらの記事は、弊社メンバーに協力をいただいています。本人のブログは[こちら](https://marshal115.hatenablog.com/))
＊～
Power BI Desktop は、各クライアントPCにインストールするソフトウェアです。
そのため、それぞれの PC スペックによって使いごこちが大きく変わってしまいます。
これからPower BI を使い始める方も、今使ってる方も、
**「自分の PC は Power BI のパワーを十分に引き出せるスペックなのか？？」** 
是非チェックしてみてください！

# PCの選択

Power BI Desktop 利用時に気にしたい、PCのスペックと理由は以下の順番です。
(以下の数字は"ここまであるとベスト"な数字ですので、満たしていなくても問題ありません。)


|優先度|機能|スペック|関連|
|:-:|:-:|:-:|:-:|
|1|CPUモデルとクロック数|Core i7以上、3GHz以上|処理速度|
|2|メモリ速度|RAMが1,600MHz以上|処理速度|
|3|コア数|最新モデルであるほどいい|同時処理数|
|4|RAM(メモリ)サイズ|16GB以上|処理できるデータ量|

逆に、あまり重要でないスペックも以下に羅列しておきます。

|機能|スペック|関連|
|:-:|:-:|:-:|
|ディスク (ストレージ)|SSDで256GB以上|Power BIのパフォーマンスには影響しない|
|GPU|-|ほとんど使わない|

やはり CPU のモデル/メモリサイズとクロック数は処理速度に対してダイレクトに影響がありそうですね。
処理に十分なスペックを用意することで'イヤなもっさり感'を激減することができます。



参考: [Choosing the Right Hardware for Analysis Services Tabular](https://www.sqlbi.com/articles/choose-the-right-hardware-for-analysis-services-tabular/)
参考2: [Power BI GPU vs CPU](https://community.powerbi.com/t5/Desktop/Power-BI-GPU-vs-CPU/m-p/538852)

:::note info
・CPUのシリーズはデスクトップPC、ノートPCに関わらず、Core i7以上のものを推奨
・同じCPUのモデル(例：Core i7の○○モデル)であっても、デスクトップとノートで比較するとデスクトップのほうが性能が高いことが多い。
(ノートPCは省電力版のモデルが使用されていることが多いため)
・同様の理由により、パフォーマンスの観点でデスクトップ（古いCPUモデル）> ノート（新しいCPUモデル）という逆転現象が起こり得る


:::

# 自分の PC のスペックを確認してみる

さて、最適なハードウェア要件を把握したところで、ご自身の PC のスペックを確認してみましょう！
それぞれの数値はタスクマネージャーを起動（Ctrl + Shift + Esc）して確認ができます。
お手元のタスクマネージャーの画面と照らし合わせてみてください。
(①~④の番号は優先度順です。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/54dcbf00-5cc5-c8f9-7812-21324ca69813.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542710/74fec133-fce5-0572-d84a-252c709571c6.png)


# おわりに
いかがでしたでしょうか？
実際の使用環境としては、 Power BI Desktop だけでなく Teams であったり PowerPoint であったり、、いろいろなソフトを同時に立ち上げて使っていくことと思います。
他のソフトとの兼ね合いも踏まえて、最適な PC スペックを選択いただく参考になれば幸いです！

:::note info
クライアント PC でのレポート作成が終わった後は、**Power BI サービス** へアップロードを行いましょう。
アップロードにより Microsoft のクラウド上で動くようになったレポートは、個人の PC リソースを逼迫せず閲覧・分析ができるためとても便利です。
:::

余裕のあるPCスペックで快適な Power BI ライフを！！
Googleスプレッドシートとフォームで家計簿を作ってみた

目標
①なるべくシンプル
②外出先でもタイムリーに入力できるように
③年月ごとにまとめたい
を目指して作成していきました。

作成過程でかなり試行錯誤してるんですが、すっとばして解決策だけ書いていこうと思います。
随時更新です。

## 外出先でも入力できるようにGoogleフォームで入力する家計簿
目標①、②を達成すべく、Googleフォームで家計簿の入力部分(？)を作っていきます。
レシートを見ながら、日付、金額を入力するという家計簿にしました。
なるべく入力作業をしたくないので、当日中なら日付は入力しなくていいようにしました。(ほぼ後日入力しているし、後でめんどくさいことになったのでやめた方がよかった、というのは後述…)
![スクリーンショット 2022-09-15 21.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846105/b977891d-037a-18da-e294-ea4ed8467d07.png)

項目はざっくり。
項目によって質問を分岐させました。
（食費やお菓子は次に金額（セクション4(最後の質問)）、
固定費は次に電気代、ガス代など内訳(セクション3)を選択してから金額、
その他は詳細（セクション2）を入力後、金額の入力に進むようにしました。）
![スクリーンショット 2022-09-15 21.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846105/53ee536e-3ce3-c3c9-1dc3-4f2fa8b4f5db.png)

食費の内訳(卵、牛乳などの製品名)は私は不要なので、まとめて食費！お菓子！という選択をして合計金額を入力します。

個人的には「目標①なるべくシンプル」「②外出先でもタイムリーに入力できるように」が達成できました。


## Googleスプレッドシートに出力
ボタンひとつでスプレッドシートにしてくれる。ありがたい！（回答画面の右上にある緑のマークのところ押すだけ）
![スクリーンショット 2022-09-15 21.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846105/aa5f8006-4719-8108-6e1b-4c2cddb3395e.png)
質問ごとに列が別れたスプレッドシートができた。
フォームに入力していくと自動で行が増えていく。便利〜
このスプレッドシートを「回答スプレッドシート」として以下話ていきます。

このままでは入力項目がただ出力されているだけなので、
しかも入力順（タイムスタンプ）なので、使用日順にしたい者にとってはまったくもって見にくい。
スプレッドシートを新しく作成してそっちで使いやすいように綺麗にまとめていきます。

そのために一手間をかけておきます。
回答スプシにて、レシート年月日の列をテキスト化しておきます。以下参照。

https://qiita.com/4sojun/items/1164ba243d7782ce43cd#%E6%9B%B8%E5%BC%8F%E3%81%AA%E3%81%97%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E5%8C%96%E3%81%8C%E3%81%86%E3%81%BE%E3%81%8F%E8%A1%8C%E3%81%8B%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88

ここで上記に書いたように、「当日中なら日付は入力しなくていいようにした」ために余分な1列（空欄の場合タイムスタンプ記載の日付を引用してくるようにする列）が必要になりました。

## 新規スプレッドシートを作成
新規スプシを作成したら、
とりあえずA1セルに以下の関数を入れます。
```
=query(IMPORTRANGE("回答スプレッドシートのURL","フォームの回答!C:H"),"select* where Col1 like '"&Q1&"%'",true)
```
上記では、「回答スプシ」の「フォームの回答」というシートタブの、Q1セルにある文字列で始まるC列(Col1)の行を昇順でC列からH列まで抽出する式です。
「Col1」は、回答スプシの取得範囲の左から1列目ということなので、上の例だとC列から1行目、つまり回答スプシのC列のことになります。（取得範囲が「C:H」なので）
「true」は、「昇順」で並べる命令（？）ですが、降順にする方法も調べてみましたがわからず・・・今回は使用することがないので追求しません。

Q1セルにはシート名が記入されているのですが、これは
~~~
=SHEETname()
~~~
という式が入っています。

シート名を取得する方法ですが、
こちらを参考にさせていただきました。

https://tanuhack.com/get-sheetname/

このままGASで作成すれば問題ないです。記事を書いてくださりありがとうございます！

これで「目標③年月ごとにまとめたい」が達成できるようになりました。

## 新しい月になったときに自動でシートを作成させる

こちらの記事を参考にさせていただきました。ありがとうございます！

https://www.log-stocker.com/gas/838/
Javaのequalsメソッドについて

今日の実務で、実装レビューにて指摘があった箇所を備忘録として残す。

Javaの経験が浅い方や、古いバージョン(8以前)を中心に実装していた方もためになるかと思います。


## Stringクラスのequalsメソッド

Java歴が浅い方や最近学習を始めたという方は、文字列比較のために、Stringクラスのequalsメソッドを基本として学ぶと思います。
(僕も研修や独学時代はこれしか学びませんでしたし、今も癖で使ってしまいます。)


<br>

Stringクラスのequalsメソッドは、比較する文字列が同値であるかどうかを判定してくれます。
なので、参照先が異なっていたとしてもtrueを返却してくれます。
```java
String a = "あいう";
String b = "あいう";
String c = new String("あいう");

System.out.print(a.equals(b));//true
System.out.print(a.equals(c));//true
```

<br>
(余談：実はObjectクラスのequalsメソッドをStringクラスがオーバーライドしてくれていたことは知らずに使っていました。
<br>Objectクラスのequalsメソッドは同一性を判定してれます。)


### nullの可能性がある場合は必ずnull判定が必要になる
実務内では、かなりnullの考慮が必要だと感じています。
利用する変数にnullが入ってくる可能性があるのであれば、nullチェックもしくはnullを許容してくれる実装をしなければいけません。

例えば、以下ではNullPointerExceptionが発生します。
```java
String a = null;
String b = "あいう";

System.out.print(a.equals(b));//ヌルポで落ちます
```

障害が起きてしまうので、こういったnullが入る可能性のある変数には、nullチェックが必要です。

```java
String a = null;
String b = "あいう";
if (a!=null) {
  System.out.print(a.equals(b));//実行されない
}
```

## Objectsクラスのequalsメソッドを使う

### nullチェックを毎度やるのは大変
毎度if文でnullチェックを行うのは、if文をネストしてしまう原因にもなり、可読性が落ちます。

なので、今僕はOptional型を使ったりしてうまく回避していくのですが、今回はObjectsクラスのequalsメソッドを利用しました。

```java
String a = null;
String b = "あいう";
String c = null;

System.out.print(a.equals(b)); // false
System.out.print(a.equals(c)); // true

```

Objectsクラスのequalsメソッドはnull同士でも比較できる優れもので、NullPointerExceptionが発生する可能性はありません。

変数にnullの可能性がある場合については、こちらを利用する癖をつけていきたいです。
plotlyで軸の数値が省略される(1000=K)問題の解決

# 現状
以下のグラフだと縦軸が400Kや200Kになってしまう。
実際の値は400,000 や200,000であり、そのままの値で表示したい場合がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/cb84bb1a-8fb3-f3a4-7543-7a2fc1665753.png)

# 解決策
以下のコードを入れるのみ。
```
fig.update_yaxes(
    tickformat="d",
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/c7f97ac6-3866-c517-9ca1-63f418dcdc0b.png)


eや%表記がしたい場合は以下参照
tickformatのところを変えるといろいろできそう。

https://github.com/d3/d3-format/tree/v1.4.5#d3-format

# ちなみに
軸の刻み幅を変えたい場合はdtickを追加する。
```
fig.update_yaxes(
    tickformat="d",
    dtick=100000
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/265fa860-d563-3716-33ed-098a7449a347.png)