OmniAICreator/Qiita-1.07M huggingface dataset:
.Net 6: WebAPI を作成

日経BP社から出ている
[.NET 6 プログラミング入門](https://github.com/moonmile/net6-samples) の 4.4 WebAPI をなぞってみました。

プロジェクトの作成

```
dotnet new webapi --name BookApi
cd BookApi
mkdir Models
rm WeatherForecast.cs
rm Controllers/WeatherForecastController.cs
```

フォルダー構造

```text
$ tree -L 1
.
├── BookApi.csproj
├── Controllers
├── Models
├── Program.cs
├── Properties
├── appsettings.Development.json
├── appsettings.json
├── bin
└── obj
```

```Models/Book.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

#nullable disable

namespace WebApi.Models
{

public class Book
{
	public string Id {get; set;}
	public int Khm {get; set;}
	public string Title {get; set;}
	public string Deutsch {get; set;}
}

}
```

```cs:Controllers/BooksControllers.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApi.Models;


namespace WebApi.Controllers
{

[Route("api/[controller]")]
[ApiController]
public class BooksController: ControllerBase
{
	List<Book> books = new List<Book>()
	{
	new Book {Id="s047", Title="白雪姫",
		Deutsch = "Schneewittchen",Khm = 53},
	new Book {Id="s031", Title="ヘンゼルとグレーテル",
		Deutsch = "Hänsel und Gretel",Khm = 15},
	new Book {Id="s004", Title="おいしいおかゆ",
		Deutsch = "Der süße Brei",Khm = 103},
	};

[HttpGet]
public IEnumerable<Book> Get()
{
	return this.books;
}

[HttpGet("{id}")]
public Book? Get(string id)
{
	return this.books.FirstOrDefault(t => t.Id == id);
}

}

}
```

## 設定ファイル

```json:appsettings.json
{
"urls": "http://*:5000;https://*:5001",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
```

```json:appsettings.Development.json
{
"urls": "http://*:5000;https://*:5001",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}
```

## サーバーの起動

```bash
dotnet run
```

```text
$ dotnet run
ビルドしています...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://[::]:5000
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://[::]:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/uchida/tmp/dotnet/webapi/BookApi/
```

## クライアントでアクセス

```bash
http --verify=no https://localhost:5001/api/Books
```

```bash
http --verify=no https://localhost:5001/api/Books/s047
```

```bash
curl -k -X 'GET' 'https://localhost:5001/api/Books' -H 'accept: text/json'
```

```bash
curl -k -X 'GET' 'https://localhost:5001/api/Books/s047' -H 'accept: text/json'
```
【sampleメソッド】collection_selectで取得するデータをサンプルデータに取り入れる

# はじめに
seedsにform.collection_selectで取得するデータを保存する方法を紹介します。  

#### サンプルコードについて
ユーザーの新規登録には、name、email、password、prefecture_idが必要です。
prefecture_idは、Prefectureテーブル(47都道府県)からcollection_selectでデータを取得します。
<br>
### newアクション

```rb:/app/controllers/users_controller.rb
def new
  @prefectures = Prefecture.all
  @user = User.new
end
```

Prefectureテーブルから全レコード取得

### 作成フォーム

```rb:/app/views/users/new.html.haml
%h1 Sign up
.row
  = form_with(model: @user, local: true) do |f|
    = render 'shared/error_messages', object: f.object
    %div
      = f.label :name
      = f.text_field :name
    %div
      = f.label :email
      = f.email_field :email
    %div
      = f.label :password
      = f.password_field :password
    %div
      = f.label :password_confirmation
      = f.password_field :password_confirmation
    %div
      = f.label :prefecture_id
      = f.collection_select(:prefecture_id, @prefectures, :id, :name )
    %div
      = f.submit "Create my account"
```

<br>

### sampleメソッド


```rb:/db/seeds.rb
50.times do |n|
name  =     Faker::Name.name
email =    "example-#{n+1}@testuser.org"
password = "password"
prefecture = Prefecture.all.sample.id
User.create!(name:                  name,
             email:                 email,
             prefecture_id:         prefecture,
             password:              password,
             password_confirmation: password)
end
```
sampleメソッドでPrefecture.allからランダムに１レコード取得、そのレコードからid属性を取得します。


# あとがき
配列からランダムに1つオブジェクトを取得する方法は他にもあります。例えばshuffleメソッド
```bash
@prefecture = Prefecture.all.shuffle.first
```
sampleメソッドの方がコード量も少なく、シンプルで分かりやすいと思います。
Windows10のバッチでファイル削除

# やり方

```bat:batと同じフォルダーにあるunko.txtファイルを削除するサンプル
del unko.txt
```

```del``` コマンド。
存在しないファイルパスを指定した場合は例外にならず、何も起きない。


# フォルダーパスを指定してしまった場合

```bat:拡張子を忘れてフォルダーパスを指定してしまった
del tester
```

フォルダーが存在する場合は、下記のように確認が出て **一旦止まる** 。
（ユーザーが入力するまでbat処理は進まない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c36f2ad5-ac8a-f492-407f-ed4a34c101a7.png)

フォルダーが存在しない場合は例外にならず、何も起きない。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
Firebase Firestore firestore.Timestamp.now() でエラー v11.5.0

Firestoreに現在時刻を`firestore.Timestamp.now()` で取得して保存しようとしたのですが、エラーが出てしましました。
Firebaseのバージョンは`11.5.0`です。

```ts
firestore().collection("users").doc(id).set({
  createdAt: firestore.Timestamp.now()
});
```

```:error
TypeError: Cannot read properties of undefined (reading 'now') at C:\Users\*ファイル名*
```

## 解決策
`import { Timestamp } from 'firebase-admin/firestore'`を追加して呼び出すと解決しました。
参考に記載したリンクによるとv11の問題と思われます。

```ts
import { Timestamp } from 'firebase-admin/firestore'

firestore().collection("users").doc(id).set({
  createdAt: Timestamp.now()
});
```

## 参考
[[Firestore] admin.firestore.Timestamp.now() fails with firebase-admin 11, works in 10.3 (emulator) #1827](https://github.com/firebase/firebase-admin-node/issues/1827#issuecomment-1203179122)
【AWS初心者向け】AWSコストをタグ別で確認

# 会社のAWS環境で自分が利用している分のコストを確認したい

AWSを会社で利用する場合、複数のIAMユーザーを社員毎に割り当てる構成を取っていることが多いかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292149/34f708c0-0f8d-86ce-f14d-40c8a8851c1e.png)

本記事は「自分がどのくらいのコストを課金しているのか確認する方法」のメモです。

## AWS Cost ExplorerはIAMユーザー別に表示してくれない。

AWSのコストの確認は「AWS Cost Explorer」によって行えます。
「どのサービスで何ドルの課金を行ったのか」など以下の画像のように確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292149/46e56e7d-39fd-5630-6350-aefa45389b9d.png)

しかし、肝心の「IAMユーザー別」にコストを確認することが出来ないため少し不便です。
（2022/08/12時点では機能がありませんが今後実装される可能性があります。）

## タグによるコスト確認を利用しよう
AWSには利用するリソースの作成時に「タグ」を付けることで管理を簡単にすることが出来ます。
コスト管理もタグのメリットの一つで、自分用のリソースを作成するにはタグを付与することを忘れないようにしましょう。

例えばリソース作成時に「USERNAME」タグに自分の名前を記載するというルールにします。
すると、Cost Explorerのグループ化について、「USERNAME」タグを選ぶと自分の名前でいくら課金しているかがわかります。

以下「グループ化の条件」を特定のタグに指定した際のコストを表示した画面です。

![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292149/3d6457fa-6672-d74b-6a9d-ecca54e9567f.jpeg)

また、タグはコスト確認以外にも「特定のタグが付いているリソースを一斉削除」したり、管理面でも便利な使い方が出来ますよ。

以下の記事は実用的で私も実装したいと思う記事でした。

https://blog.engineer.adways.net/entry/2021/12/03/120000

## おまけ：IaCによるタグ付与がオススメ
ここで、普段マネージメントコンソールをポチポチしてリソース作成を作成している人は、
「タグをつけるのなんて忘れちゃうよ/めんどくさいよ！」
と思っていることでしょう。この機会にTerraformなどのIaCツールを利用しましょう。
タグのつけ忘れが無くなることでしょう。

そもそもIaCというのは何ぞや。という方は、「マネージメントコンソールでぽちぽち」せずに「CUIでリソース作成ができるツール」くらいに思ってぜひチャレンジしてみてください。とても便利ですよ。

また、Terraform以外にはAWS専用の「AWS CloudFormation」などがありますが、Terraformは他のパブリッククラウド(Azure, GCP, OCI)にも対応しているのでTerraformをオススメさせていただきます。

☆参考：Terraform

https://tech-blog.rakus.co.jp/entry/20220707/terraform
【lambda】他の配列を参考にリストを並べ替える

## はじめに

**Pythonで他の配列を参考にリストを並べ替える**方法について解説します。

※プログラミング関係の内容を他にも投稿していますので、よろしければ[こちら](https://qiita.com/oki_kosuke/items/34b1071224953776c211#%E6%8A%95%E7%A8%BF%E4%B8%80%E8%A6%A7)の一覧から他の投稿も見て頂けますと幸いです。


## 実現したいこと
input_list = ['ten', 'nine', 'three']
このようなリストが与えられた際に数として並べ替えたい。つまり、数字の3,9,10の順に従って、['three', 'nine', 'ten']と出力したい。

## listの並び替えの復習
リストは以下のように並べ替え可能です。

```python
name_list = ["Charle", "Mike", "Bob", "Alice"]
sorted(name_list)
```

```:出力
['Alice', 'Bob', 'Charle', 'Mike']
```

並べ方を逆にすることも可能です。

```python
sorted(name_list,  reverse=True)
```

```:出力
['Mike', 'Charle', 'Bob', 'Alice']
```

## 複数の要素を持つ配列の並び替え
以下のように実行可能です。
```python
age_tuples = {
    ("Charle", 20),
    ("Mike", 15),
    ("Bob", 30),
    ("Alice", 25)
}
sorted(age_tuples)
```

```:出力
[('Alice', 25), ('Bob', 30), ('Charle', 20), ('Mike', 15)]
```

これは1つ目の要素がアルファベット順に並んでいることが分かります。では、これを2つ目の要素である数値順に並び変えます。ここで、**lambda**を使います。lambdaの使い方は[こちら](https://note.nkmk.me/python-lambda-usage/)や[そちら](https://note.nkmk.me/python-dict-list-sort/)や[あちら](https://docs.python.org/ja/3/howto/sorting.html)のサイトを参考にしました。

```python
sorted(age_tuples,  key=lambda age_tuples: age_tuples[1])
```

```:出力
[('Mike', 15), ('Charle', 20), ('Alice', 25), ('Bob', 30)]
```

参考サイトによると、lambdaの使い方は次の通りです。

- Pythonではdef文で関数を定義するが、lambda（ラムダ式）で名前を持たない無名関数を作成することもできる。

- lambdaは引数として関数（呼び出し可能なオブジェクト）を指定する場合などに使うと便利。書き方および使い方を説明する。

## 実現したいことの回答
以上を踏まえて次のようなコードになりました。

```python
input_list = ['ten', 'nine', 'three']
 
num_dict = {
    'one':1,
    'two':2,
    'three':3,
    'four':4,
    'five':5,
    'six':6,
    'seven':7,
    'eight':8,
    'nine':9,
    'ten':10,
}
 
result_list = sorted(input_list, key=lambda x: num_dict[x])
 
print(result_list)
```

```:出力
['three', 'nine', 'ten']
```

### 参考
- [Pythonのlambda（ラムダ式、無名関数）の使い方](https://note.nkmk.me/python-lambda-usage/)
- [ソート HOW TO](https://docs.python.org/ja/3/howto/sorting.html)
- [Pythonで辞書のリストを特定のキーの値に従ってソート](https://note.nkmk.me/python-dict-list-sort/)
- [Pythonで降順ソートを行う方法【初心者向け】](https://techacademy.jp/magazine/19138)
【Flutter】テストでMockからreturnされる値をTimerで切り替える。

こんにちは。

アプリを13本リリースしているYuKiOです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">HackerMemoを大幅にアップデートしたので、<br><br>海外向けのPVを作ってみました😆<br><br>夜なべして頑張って作ったので、拡散頂けたら泣いて喜びます😭🙏<br><br>音有りがオススメです！<br><br>元ネタわかる人いるかな〜🤔<br><br>アプリはこちら🔽<br>■iPhoneの方<a href="https://t.co/6T10L94Ld1">https://t.co/6T10L94Ld1</a><br><br>■Androidの方<a href="https://t.co/uBevCXrNw2">https://t.co/uBevCXrNw2</a> <a href="https://t.co/wiGLv46kaG">pic.twitter.com/wiGLv46kaG</a></p>&mdash; YuKiO｜アプリ個人開発｜Flutter × Firebase (@oo_forward) <a href="https://twitter.com/oo_forward/status/1348103082769453056?ref_src=twsrc%5Etfw">January 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回は**FlutterのUnit Test時に、Mockから返される値をTimerで切り替える方法**を紹介します。

## どんな場合に必要？
それ、修学旅行で買った木刀のように、いつ必要になるんだ？と思われるかもしれませんが、**非同期で画像をダウンロードしてくる場合**などを想定しています。

・ダウンロードが完了するまでは、progressを表示
・ダウンロードが完了したら画像を表示
・タイムオーバーになったら、noimage &　エラー処理 or 再取得

のような仕様です。

## 結論
結論で言えば、TimerによってStabを上書きしてしまうことで実現します。

:::note info
mockは、mockitoというpubを使用しています。
[https://pub.dev/packages/mockito](https://pub.dev/packages/mockito)
:::



```dart:post_image_test.dart
 test(
      "ダウンロードが完了すると、trueが返ってくる。",
      () async {
        final File mockFile = MockFile();

        when(mockFile.existsSync()).thenAnswer((_) => false);

        Timer(Duration(seconds: 7), () {
          when(mockFile.existsSync()).thenAnswer((_) => true);
        });

        final result = await postImage.isExsitsImage(mockFile);
        expect(result, true);
      },
    );


```

一見、Whenの処理内できそうなように思えましたが、処理が確定されてしまうようで、書き換えることができませんでした。
isExsitsImageの処理では画像が存在しない場合にはwhileで一定間隔で画像の存在チェックを行い、一定時間が経過して画像がない場合にはfalse、画像がある場合にはtrueを返す処理をしています。


少してもFlutterのテスト作成の参考になれば幸いです。
SwiftUIでハートアニメーションを作ってみた

今回作成したハートのアニメーションはこちらで、2つほどやり方が思いついたので、それぞれ作成してみました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/be66a246-02e3-2897-51c5-1fb37439145a.gif)


大きな流れとしては、以下の通りです。
1. 四角形や三角形、楕円形などはデフォルトで用意されているのですが、ハートは用意されていないので、自作する必要があります。
1. 自作したハートにアニメーションを付与

# ハートの作成

四角形（Rectangle）や円形(Circle)は用意されていますが、ハートは用意されていないので、自作で作成しました。

```swift:ハートの自作
struct HeartShape: Shape {
    let minX = 10
    let centerX = 55
    let maxX = 100
    
    let minY = 10
    let maxY = 100
    
    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: centerX, y: maxY))
            path.addQuadCurve(to: CGPoint(x: minX, y: 50),
                              control: CGPoint(x: minX, y: 70))
            path.addQuadCurve(to: CGPoint(x: centerX, y: 30),
                              control: CGPoint(x: minX, y: minY))
            path.addQuadCurve(to: CGPoint(x: maxX, y: 50),
                              control: CGPoint(x: maxX, y: minY))
            path.addQuadCurve(to: CGPoint(x: centerX, y: maxY),
                              control: CGPoint(x: maxX, y: 70))
            path.closeSubpath()
        }
    }
}

```

# アニメーションを付与
アニメーション方法が二つあるので、それぞれ紹介していきます。

### ワークアウトアニメーション

やり方としては透明の四角形を上に配置し、四角形を回転させることでインジケータのような動きを再現しています。
![Simulator Screen Recording - iPhone 13 Pro - 2022-08-12 at 14.17.26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/79d19398-1dae-9e2a-eba0-1b673291d018.gif)


```swift
struct TrainingAppHeartView: View {
    @State var isAnimation = false
    
    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            HeartShape()
                .stroke(Color.red,
                        style: StrokeStyle(
                            lineWidth: 5,
                            lineCap: .round))
                .frame(width: 110, height: 110)
            
            Rectangle()
                .fill(Color.white)
                .frame(width: 110/2, height: 110/2)
                .rotationEffect(Angle(degrees: isAnimation ? 360 : 0),
                                anchor: .topLeading)
                .onAppear() {
                    withAnimation(
                        Animation
                            .linear(duration: 2)
                            .repeatForever(autoreverses: false)) {
                                isAnimation.toggle()
                            }
                }
        }
    }
}
```

### ダイナミックアニメーション

こちらはハート自身にアニメーションを付与することでアニメーションを実現しています。

```swift
struct DynamicHeartView: View {
    @State var to: CGFloat = 0
    
    var body: some View {
        HeartShape()
            .trim(from: 0, to: to)
            .stroke(Color.red,
                    style: StrokeStyle(
                        lineWidth: 5,
                        lineCap: .round))
            .frame(width: 110, height: 110)
            .onAppear() {
                withAnimation(
                    Animation
                        .easeInOut(duration: 0.8)
                        .repeatForever(autoreverses: false)) {
                            to = 1
                        }

            }
    }
}
```
【AWS】AWSのSNSとFirebaseのFCM連携でプッシュ通知する

# 要件
AWSのSNS(Simple Notification Service)とFirebaseのFCM(Firebase Cloud Messaging)連携でプッシュ通知を行います。


# AWSプラットフォームアプリケーションの作成
1. [コンソール画面](https://ap-northeast-1.console.aws.amazon.com/sns)へログインする
1. モバイルのプッシュ通知をクリックする
1. プラットフォームアプリケーションの作成をクリックする
1. プラットフォームにFCMを選択する
1. APIキーを入力する（FCM画面から参照できる）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491433/ee1e7b74-a6e3-8279-d321-666f2dd45d23.png"width="600">
FCMのAPIキーは下記スクリンショットのサーバーキーです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491433/43e32236-c1b2-bb9a-f504-9ef7952d0052.png"width="600">

# Firebaseの設定
1. [コンソール](https://console.firebase.google.com/)画面からプロジェクトを作成する
1. 全般タブにてiOSまたはAndroidの新規追加を行う（
※google-services.jsonまたはGoogleService-Info.plistをモバイルアプリに取り込む必要がある
1. プロジェクタの設定のCloud Messagingタブから設定を行う
1. [Apple Develop](https://developer.apple.com/account/resources/authkeys/list)からプッシュ通知証明を発行する
1. Appleアプリの構成にiOSのプッシュ通知証明書をアップロードする
※証明書発行はここで記述しないけど、証明書種類は２つがあり、p8とp12両方でも使えるが、p12の証明書には有効期限がある

# node.jsにてプッシュ通知を行う
nodejsの場合、SNSプッシュ通知の実装方法前の記事を参考して頂けばわかると思います。
[プッシュ通知(nodejs)](https://qiita.com/ling350181/items/2fe8f0600165926ff70c)
Oracleで特定のテーブルに設定された主キーやインデックス（複合インデックス）を確認SQL

# やり方

『USER_IND_COLUMNS』という名前のテーブルに情報がある。
SQLで取ってこれる。

```sql:
SELECT * 
FROM USER_IND_COLUMNS 
WHERE TABLE_NAME = 'テーブル名' 
ORDER BY INDEX_NAME, COLUMN_POSITION;
```

# 参考サイトさん

https://replication.hatenablog.com/entry/20131004/1380893810

# バージョン

Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
Salesforce のAPIをChromeプラグイン「API Tester」で実行する

# 前説
AmazonConnect × Salesforceの連携プラグインの検証をしていて、AWS側の設定問題なのか、Salesforce側のAPI用設定の問題なのか切り分ける際に、素のSalesforceのAPIを実行してみたかった。

# Salesforce側の設定前提
Salesforce上での接続アプリや接続ユーザなんかの設定は、

https://amazon-connect.github.io/amazon-connect-salesforce-cti/docs/lightning/installation/04-salesforce-lambdas-manual-setup

上記を参照して下さい。
本記事は、あくまでAPIをツールから実行することに焦点を当てています。

# OAuth API実行の挙動

1. アクセストークン払い出しの実行
2. APIの実行

２段階の実行となっています。

# Salesforceのアクセストークンの払い出しについて

| モード | アクセストークン URL |
|:-:|:-:|
| 本番（プロダクション）  |  https://login.salesforce.com/services/oauth2/token |
| テスト（サンドボックス）  |  https://test.salesforce.com/services/oauth2/token |

HTTPヘッダーは
| キー | 値 |
|:-:|:-:|
|  Content-Type | application/x-www-form-urlencoded  |

Bodyは
| キー | タイプ | 値 |
|:-:|:-:|:-:|
| grant_type  | Text  | password  |
| client_id  | Text  | コンシューマ鍵  |
| client_secret  | Text  | コンシューマの秘密  |
| username  | Text  | apiユーザのID  |
| password  | Text  | apiユーザのPW  |

![Qiiitaアクセストークン.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/59924036-a336-a6f7-a23b-b8edd94e98da.jpeg)

ツールでの実行結果は、上記のようになる。無事に「access_token」が返却される。

# Salesforce API 実行

https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/dome_search.htm

| URL |
|:-:|
| https://ドメイン.my.salesforce.com/services/data/v55.0/parameterizedSearch  |

HTTPヘッダーは
| キー | 値 |
|:-:|:-:|
|  Content-Type | application/json  |
|  Authorization | Bearer アクセストークン  |

:::note info
注意
「Authorization」の値は、前節のアクセストークンそのままではなく、「Bearer」「半角スペース」「アクセストークン」の結合であることに注意
:::

Bodyは
```json
{
  "q": "Salesforce上に登録されてる電話番号(頭0なし)",
  "sobjects": [
    {
      "name": "Contact"
    }],
  "fields": [
    "Id",
    "Name",
    "Email"]
}
```

![QiiitaAPI実行.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/b37587c7-e3ef-0ea5-af66-a76305dee8be.jpeg)

Salesforce上の該当の電話番号を持つユーザ情報が取得できました。
環境を変えて新しいことをやる転機になった話-MacからWindowsに- 

## サマリ

* 久しぶりにプライベートでWindows PCを使うことになった
* WSL2やwingetなどWindowsならではアプリケーションを使う以外にも知れることが多くて楽しめた

## やってしまった…

使っていたMacBook Proのディスプレイを割ってしまいました。

外付けディスプレイに繋いでクラムシェルモードにすれば使えますが、
左半分がまともに映らないのでノートPCとして使うには厳しい状態です。

個人的には寝ながらだらっと使ったり、家の中でもちょっと場所変えて使えるため、ノートPCが好きでした。

5年以上使っていたので、新しいMacに買い替えることを検討しました。

しかし、なかなかお高い。
M1 Maxのスペックは自分の用途を考えると必須ではなさそう。

そのときは、自分のニーズに合いそうなMacBook Airの新版が2022年にでるかもしれないので、
Macは待つことにしました。
でも待つ間、ノートPCがないのは困るため、比較的安価なWindows PCを買うことにしました。

## 買ったもの

Dell [Inspiron 14](https://www.dell.com/ja-jp/shop/%E3%83%87%E3%83%AB%E3%81%AE%E3%83%8E%E3%83%BC%E3%83%88%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3/inspiron-14-%E3%83%8E%E3%83%BC%E3%83%88%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3/spd/inspiron-14-5415-laptop)

スペック概要は以下

* CPU AMD Ryzen 5 5500U with Radeon Graphics
* メモリ 8GB
* ストレージ 256GB
* OS Windows 11 Home

## 気づき

### 久しぶりにハードウェアをさわる機会になった

ハードウェアっていうと仰々しいですが、メモリを増設しました。

メモリ8GBのモデルを買ったのですが、なんだか動きがもっさり。
買いたてはそんなに重くなかったのに不思議だなと思って
なにをいれたか見てみるとまあまあメモリを使うソフトを同時に実行していました。

* wsl2
* docker desktop
* Visual Studio Code
* Google Chrome
* etc..

そこでメモリ増設しようと思い調べてみると、
[同じ型番のPCにメモリを増設している人が作業記録を公開してくれていました](https://blog.ayurina.net/2021/06/23/dell-new-inspiron-14-5415-%E3%81%AE%E3%83%A1%E3%83%A2%E3%83%AA%E3%82%92%E5%A2%97%E8%A8%AD%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%E3%80%8216gb%E3%83%87%E3%83%A5%E3%82%A2%E3%83%AB%E3%83%81%E3%83%A3/)。
ありがたい。

サポートは切れますが、数千円でできました。PCカバーあけるための道具がAmazonでポピュラーに売っていたのは驚きました。皆同じようなことを考えている？

PCカバーをあけると、SSDがPCIeでつながっていて、メモリが刺さっている場所がわかりました。（SATAでHDDがつながっていたのを見ていた人なので、ちょっと感動）
どのパーツも小さくきれいに収まっていたので、最近のノートPCが薄いのも納得しました。

### 開発環境を再現できるようにする機会になった

情熱プログラマーに触発されて、開発環境を再現できるようにしてみました。まっさらな環境なのでそういう取り組みをするのがやりやすかったです。

今回はansibleとwingetを使いました。

Macだとbrew一択といった感じが個人的にありますが、Windowsはパッケージインストールに[winget](https://github.com/microsoft/winget-cli)や[chocolatey](https://chocolatey.org/)、[scoop](https://scoop.sh/)などがあるのだとわかりました。またあらためてansibleの勉強になりました。

### あらためて前の良さをしる

* PCの筐体の大きさや、丈夫さ（ディスプレイ割っちゃいましたが・・）キーボード、などはやはりMacのほうが高いこともあり、いいですね。
* 使っているエディタのVS CodeがMacとの相性がいい。
  * キーバインドとか、操作感がMacのほうがいいと感じました。
  * WindowsとVS Codeは同じところが作っているはずなのに不思議なものですね。
* パッケージ管理はbrewが簡単便利。
* めちゃくちゃ細かいところなんですが、デフォルトでカーソル操作をctrl-f,b,a,eなどでできないところで個人的にストレスが積み重なりました。wsl2は使いやすいのですが、それだけを使うわけではないので。

### その他

今まで知らなかった種類のサイトを知ることができました

* Dellのクーポンの割引率の変動を紹介するサイト
  * 買うときの参考としてネットサーフィンしていたら見つかりました
  * メーカーに特化してクーポンを紹介するのははじめて見ました
    * レビューサイトならわかるけど
* メモリの増設作業の記録を公開しているサイト
  * ソフトウェアやプログラミングのようにやってみた系のものがハードもあるとは知らなかったので

## 改めてメインマシンを買い変えるなら？

* MacBook Pro M2かMacBook Air M2か
  * iPad Airもっているので、ユニバーサルコントロール+Side Carを使いたい
* chrome bookもいいなと[技術書典12「プログラマーのための本気で使えるChromebook」を執筆した+付録「Chromebookで物理本を制作する」](https://blog.s2terminal.com/techbookfest12-chromebook?utm_source=pocket_mylist)を見て思いました。
* Windowsでもハードウェアがもう少ししっかりしているものならば、買ってもいいかなと思いました。WSL2がでたことは大きい。環境構築しやすくなった。
  * 数ヶ月使うとなんらかソフトをいれて、多少の使いにくさは解消できるので。
  * 今回は値段を抑えたことが大きかったのか、ディスプレイ部分がやや不安あり・・

と悩んでましたが、最終的にMacBook Air M2としました。Side CarやApple Pencilで液タブのように入力できるという、点が決め手で。
REHL 8.2 SSH接続設定

Teratermから、仮想サーバ(REHL 8.2)にSSH接続させました。

仮想マシンは、VMware vSphere上に構築しました。


【手順】
① 静的アドレスを設定する
② ファイアウォールで、ネットワークインターフェースをパブリックにいれる
③ デフォルトで動いているはずのSSHサービスの状態を確認

【詳細手順】
① 静的アドレスを設定する
#cd /etc/sysconfig/network-scripts
#ls
ここで、仮想マシンの利用インターフェイスを確認する。
今回は、ifcfg-ens192がありました。

静的アドレスに変更する
#nmcli c modify ens192 ipv4.method manual

アドレス等の設定
#nmcli c modify ens192 ipv4.addresses [IPアドレス]
#nmcli c modify ens192 ipv4.gateway [GWアドレス]
#nmcli c modify ens192 ipv4.dns [DNSアドレス]

再起動後も自動的に接続してくれるように以下を必ず設定
#nmcli c m ens192 connection.autoconnect yes



② ファイアウォールで、ネットワークインターフェースをパブリックにいれる

以下コマンドでSSHが許可されているかどうかを確認
#sudo firewall－cmd --list-all

(許可されていなかった場合、次のコマンドで許可します。
#sudo firewall-cmd --permanent --add-service=ssh)

インターフェイスのゾーンをパブリックに変更します。
#sudo firewall-cmd --change-interface=ens192 --zone=public

設定後はこんな感じ。

![screenshot.7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206656/a7f85eea-1388-1c1a-5c4f-07d2a9408e45.jpeg)



③ デフォルトで動いているはずのOpenSSHを確認

#sudo systemctl status sshd.service

activeになっていれば問題ありません。
![screenshot.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206656/2581441a-fce6-d26f-447e-b467583ff24d.jpeg)

(起動されていなかった場合、次のコマンドで起動します。
#sudo systemctl start sshd.service)




以上でSSH接続ができることを確認しました。
Windows10のバッチでファイル（ソフト）開く（パス直接指定とstart使用の違い）

# やり方（パス直接指定）

```bat:パス直接指定してソフト起動サンプル
"C:\Program Files (x86)\sakura\sakura.exe"
```

パス直接指定の場合、ソフトが終了するまで **batのコマンドプロンプト画面が残る** 。
（起動したソフトが終了すれば、batのコマンドプロンプト画面は連動して消える）

この『batのコマンドプロンプト画面』が ```Alt + Tab``` のリストに上がってしまい、 邪魔な場合もある。

そういう時はstartを使う。

# やり方（start使用）

```start``` ならソフト起動するとbatのコマンドプロンプト画面は閉じる。

```bat:startでソフト起動サンプル
start "" "C:\Program Files (x86)\sakura\sakura.exe"
```

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
【プロジェクト管理】Figmaで作る開発仕様書「Design Spec」とは？

## はじめに
アジャイル開発では、短い開発期間でスピード感を持って開発をしなければなりません。
そのため、開発を進めながら仕様の変更・修正をしていくことが求められます。

このようなアジャイル開発において、
「*仕様書をどのように作成すれば良いか*」「*デザイン・仕様書の更新が追いつかない*」
と悩む方は多いのではないでしょうか?

この記事では、スピーディーに開発を行っていく中で、
デザイン・仕様書・本番環境をできるだけ同期させていくための
Figmaで作る開発仕様書「**Design Spec**」の内容とサンプルを紹介します。








## Figmaで作る開発仕様書 「Design Spec」
### Design Spec とは？
Design Specとは、Design Specification（デザインの仕様書）の略です。
一般的な仕様書はドキュメントツール(google docs、Notion等)を使いまとめるのに対して、
Design Specが異なる点は、デザインツール(Figma, Sketch)を使いを仕様をまとめます。

特にDesign Specでは、**デザイン・フロントエンドの仕様**に効果的です。

そのため、開発の全てに関わる仕様の中で、**デザイン・フロントエンドの仕様**をFigmaにまとめ、
全体の仕様書のデザイン・フロントエンドの項目にデザインツールのリンクを入れることを推奨します。

*イメージ以下の画像です。*
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/c8949dc6-9156-aaa8-768d-0048509b595b.png)



### Design Spec の利点
#### 1. ドキュメントの作成・更新が楽なること
一般的な仕様書の作成・更新では以下のような手順が必要です。
**①デザインする → ②スクショをとる → ③ドキュメントにまとめる**
この手順では、スピーディーな開発が必要な中でドキュメント更新に時間がとられてしまいます。


Design Specでは、以下のような手順になります。
**①デザインする → ②仕様をまとめる**
デザインを作成・更新するだけで仕様書がまとまるので、個別に仕様書を書く時間は必要ありません。

#### 2. デザインと仕様が一致すること
一般的な仕様書では、画像内に番号を振り、ドキュメントのテキストを一致させています。
これでは、実装するときに、何度も画像とテキストを見ないといけなくなり大変です。

Design Specでは実装するUIを見るのと一緒に、仕様も確認できるため、開発が楽になります。



## 「Design Spec」の作成例
### ページ構成
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/9e2feebe-2a72-64dd-e072-e367a2bcb49b.png)
Design Specのページ構成はこんな感じです。

**【共通部分のページ】**
共通部分のページでは、共通部分のページでは、複数のページにまたがるもののデザイン・仕様をまとめます。

+ 具体例
    + Header, Footerなどの共通のコンポーネントとその仕様
    + ページ遷移に関する仕様
    + プロトタイプ用のデザイン

　
**【各画面のデザインページ】**
各画面のデザインページでは、各画面ごとページを分けてデザイン・仕様をまとめます。

+ 具体例
    + 各画面のUIとその仕様
    + 各画面特有のコンポーネントとその仕様
    + 各画面特有のインタラクションに関すること

**【その他のページ】**
その他のページでは、完成したデザイン・確定した仕様に関係ないものをまとめて置いておきます。

+ 具体例
    + サムネイル
    + ワイヤーフレーム
    + 議論・ミーティング用のデザイン



### ページ内の基本構成
![image２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/138918e8-d347-0e59-0fcf-8169ec5e097d.png)
左から、`コンポーネント`、`コンポーネントの仕様`、`ページのデザイン`、`ページの仕様`の順に置く。
　
**【コンポーネント】**
Figma上で作られたコンポーネントがまとめる。

*※ ここのコンポーネントは、デザインの都合で作られたコンポーネントで、Figmaの機能を指しています。そのため、必ずしも、コンポーネントとして実装して欲しいことを示すものではありません。*

　
**【コンポーネントの仕様】**
Figma上で作られたコンポーネントのstateやインタラクティブな仕様について記載する。

　
**【ページのデザイン】**
各ページの全体的なUIをまとめる。
DesktopとMobileのデザインも同じページに作成する。
（必要であれば、他の画面サイズも作成する。）
　
**【ページの仕様】**
各ページの全体的なstateやインタラクティブな仕様について記載する。


### サンプル
以下のリンクからご確認ください。

[![スクリーンショット 2022-08-11 23.59.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/9cd75686-ba22-676f-2ab2-fac460787064.png)](https://www.figma.com/community/file/1139573033541594183
)

https://www.figma.com/community/file/1139573033541594183

## まとめ
この記事では、スピーディーに開発を行っていく中で、
デザイン・仕様書・本番環境をできるだけ同期させていくための
Figmaで作る開発仕様書「Design Spec」の内容とサンプルを紹介しました。


Design Specができた背景などは、こちら記事に記載しているので、
こちらも一緒に読んでいただけると嬉しいです。

https://qiita.com/degudegu2510/items/b2c6ed2bc7278841f470


--- 

最後まで読んでくださってありがとうございます！
さらに詳しい内容を聞きたい方は、Devトークで直接お話しましょう！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/404?utm_source=link_share&utm_medium=social&utm_campaign=dev_talk_share&utm_content=dev_talk_show

X(Twitter)でも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/degudegu2510
Pythonの移動データ解析パッケージまとめ

Pythonの移動データ解析用のパッケージを調べてみました。他にもあったら教えてください。

# ヒト・大きい対象（動物、乗り物など）向け
## [MovingPandas](https://anitagraser.github.io/movingpandas/)
- [チュートリアル](https://github.com/anitagraser/movingpandas-examples)の座標が緯度経度データになっている。座標の単位を[m]などで表したデータはそのまま使えない？
- 速度、停止などの解析が可能。
- [文献](https://www.austriaca.at/0xc1aa5576_0x003aba2b.pdf)

## [scikit-mobility](https://github.com/scikit-mobility/scikit-mobility)
- 座標は緯度経度。
- 全体の移動（人流）にフォーカスした解析が可能。
- [日本語記事がある。](https://qiita.com/igarashi4423/items/5e5763cf50c7a2c36d57)
- [文献](https://www.jstatsoft.org/article/view/v103i04)

## [PyMove](https://github.com/InsightLab/PyMove)
- 座標は緯度経度。
- チュートリアルをパッと見てMovingPandasとの違いはよくわからなかった。
- [文献(ポルトガル語、英語要旨あり)](https://repositorio.ufc.br/handle/riufc/58551)

## [PTRAIL](https://github.com/YakshHaranwala/PTRAIL)
- 座標は緯度経度。
- Animal Species Classification, Ship Type Classification, Car Lane Classificationなどができるらしい。
- [文献](https://www.sciencedirect.com/science/article/pii/S2352711022001066)

## [Trackintel](https://github.com/mie-lab/trackintel)
- 座標は緯度経度。
- ヒトの移動手段の推定などが可能。
- [文献](https://arxiv.org/abs/2206.03593)

# 小さい対象（微生物、粒子など）にも使えそう 
## [traja](https://traja.readthedocs.io/en/latest/)
- 座標は緯度経度ではない。軌跡のグラフを自動表示すると単位が[m]で表示される。
- 角度の解析、クラスタリングなどができる。
- [文献](https://joss.theoj.org/papers/10.21105/joss.03202)

## [yupi](https://yupi.readthedocs.io/en/latest/index.html)
- 座標は緯度経度ではない。
- 角度の解析、MSD解析など。
- [文献](https://arxiv.org/abs/2108.06340)
Windows10のバッチで外部テキストに追記書き込み（ログ的な使い方）

# やり方

```bat:batと同じフォルダーのlog.txtに追記サンプル
rem 単純に文字列を追記
echo おいーっす >> log.txt

rem variableという名前の変数の中身をダンプ
set variable=ほげー
echo %variable% >> log.txt
```

```echo``` の出力先ファイルパスを ```>>``` で指定。

log.txtが **非存在の場合** はファイルが新規作成される。
新規作成されるtxtの文字コードはShift-JIS。

log.txtが **存在している場合** は末尾に追記される。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
[Unity]秒で作れるAR環境

# はじめに
<iframe width="560" height="315" src="https://www.youtube.com/embed/QTy1a__4xb0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
UnityのARって最初の設定が結構たいへんでしたよね。

各プラットフォーム用のARパッケージをインポートしたり、AR用にGraphics APIsを設定したり…
camera usageなど設定し忘れて画面真っ暗になってる人とかよく見ます。

Unityのテンプレートを使用することによってそこらへんの設定をよしなにやってくれるのでサクっと環境構築しましょう～
### この記事を読むとこんなことができるようになる
- UnityのAR環境構築がカンタンにできる


# 解説

## 環境
- UnityHub 3.0.1
- Unity 2021.3

## プロジェクトの作成
1. Unity Hubを起動し、[新しいプロジェクト]を選択
2. すべてのテンプレートから[AR]を選択しテンプレートをダウンロードし[プロジェクトを作成]を選択


![キャプチャ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/8bb85f8e-87a7-5a92-74bd-87092bc64497.png)
![名称未設定 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/761c7247-743e-f22f-12fe-475bd0bcb581.png)

ARテンプレートには予め、`manifest.json`や`packages-lock.json`やProjectSettingsのアセットデータなどがAR用に設定されており、
プロジェクト作成時に自動的にAR Foundationなどの必要なパッケージがインポートされます。
とってもカンタン: )

## シーンの準備…は無し
通常であれば、ARを使用するシーンではMain Cameraを削除してARSessonオブジェクトなどを配置する必要があります。
このテンプレートには既にそういったシーンの設定が済まされている「BlankAR」というシーンを用意してくれているのでそれを使用します。


### とりあえず何かモノを置く
ボックスでもボールでも何でもいいので3Dオブジェクトを置きます。
その場に表示したいのでPositionの値は0にしておきます。
![名称未設定 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/2145f659-1cb3-2c8d-f5a8-d69139f1f128.png)
#### ARのハマりポイント
現実空間にオブジェクトを表示するというARの性質上、Unity上での3Dオブジェクトのサイズ感と現実空間とのギャップが生まれやすいです。(そのためUnityには[MARS](https://unity.com/ja/products/unity-mars)というツールがある)
そのためオブジェクトのサイズ感を誤って「設置したのに表示されない」という落とし穴にハマることがあります。
表示されない場合はサイズの調整を行ってみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/27f43a17-b25a-eb96-bead-c65eef4baada.png)

## XR Plugin Managementの設定
最後に実機で出すための設定をします。
今回の記事ではAndroidで出力するための手順です。
Edit > Project Setting > XR Plug-in Management > Android にある
[ARCore]にチェックします。
![名称未設定 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/cd542922-9dee-84d0-1166-f0e765df181c.png)


## 出力

![XRecorder_12082022_115659_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605029/4af6dea8-2622-371e-c3e8-2db43b2998c8.gif)
部屋にUnityちゃんが出ました！(思ったより大きかった)
kawaii~~~~!!!!

## おわり
UnityのBuilt-inのテンプレートを使用することでAR開発の環境構築がカンタンにできるのはとてもグッドだと思います。
個人的にはAR用シーンテンプレートも追加されているともっといいなと思いました。(BlankAR シーンとかサクっと作れると嬉しい)


参考させて頂いたURL
https://docs.unity3d.com/ja/2019.4/Manual/XR.html
【React / Next】動的な値でメディアクエリのブレイクポイントを変更してレスポンシブ対応する

個人の備忘録です。

# 環境
- react: 17.0.2
- next: 11.1.3
- react-responsive: 9.0.0-beta.10
- sass: 1.49.9
- @chakra-ui/react: 1.8.5

# やりたいこと
- 親component から動的な値を受け取って、ブレイクポイント値としたい
- ブレイクポイント値以下の時に、要素を display: none; で消す

# ライブラリのインストール
```bash
yarn add react-responsive
```

# react-responsive について

https://github.com/yocontra/react-responsive

- CSS メディアクエリの状態を追跡する React の hooks
- `8.0.0` 以上のバージョンから hooks になった
- component内で簡単にブレイクポイントを設定できる
- hooks なのでリアクティブに値を返してくれ、描画後にブラウザサイズを変えても正しく判定してくれる
- 仕様の複雑な UI を実現するケースで有効

# サンプルコード
```tsx
import { Text, HStack } from '@chakra-ui/react';
import { useMediaQuery } from 'react-responsive';
import styles from './contents.module.scss';

interface Props<T> {
  data: string[];
  minWidth: string | number;
}

export const Component = ({ minWidth }: Props) => {
  const isBreakPoint = useMediaQuery({ query: `(max-width: ${minWidth})` });

  const contents: React.ReactNode[] = [];
  
  for (const key in data) {
    const hiddenClass =
      isBreakPoint && key === 'hoge' ? styles.sp_hidden : '';

    contents.push(
      <>
        <Text
          minWidth={minWidth}
          className={`${hiddenClass}`}
        >
          sampleText
        </Text>
      </>
    );
  }

  return (
    <HStack minWidth={rowMinWidth}>
      {contents}
    </HStack>
  );
};
```

# 公式
https://github.com/yocontra/react-responsive
Rvizのシーンを画像topicとして流す

「ブラウザなどにrvizの映像を映したい」みたいなことがたまにあります.そういう時一度rvisの映像を画像として流してあげるのですが、rvisの映像を画像のtopicとして流すところを自分で作成するのは中々難しそうです.

そんなときに便利なのが`jsk_rviz_plugins`の`RvizScenePublisher`です.

ここでは,`RvizScenePublisher`の使い方を紹介します.

まず以下のようにパッケージをインストール
```
sudo apt install ros-noetic-jsk-rviz-plugins
```

その後rvizを開き`RvizScenePublisher`の`display type`を追加するだけです.その後は`rviz/scene`というトピック名で映像が流れます.

![Peek 2022-08-12 12-51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/c2d62f85-c52d-1313-ce6f-53d4a5eaf31c.gif)

凄い簡単.

ちなみにrvizの内部に仮想カメラを配置するといったパッケージもあるので良かったら試してみてください.

https://github.com/lucasw/rviz_camera_stream
電子メール承認応答 : 


電子メール承認応答により、ユーザーは、レコードが承認のために送信された後に受信した承認要求電子メールに返信するだけで、承認要求を承認または拒否できます。
Salesforce の電子メール承認応答を使用すると、ユーザーは、レコードが承認のために送信された後に受信した承認要求電子メールに返信するだけで、承認要求を承認または拒否できます。そのため、ユーザーは Salesforce にログインせずにレコードを承認または拒否できます。この機能にアクセスするには、ユーザーは「API 対応」システム権限を持っている必要があります。

[Email Approval Response](https://www.mstsolutions.com/technical/email-approval-response/)

+ [承認リクエストに応答する](https://help.salesforce.com/s/articleView?id=sf.approvals_processing_approval_requests_parent.htm&type=5)

承認リクエストを受け取ったら、承認、却下、または再割り当てして応答します。使用している Salesforce エクスペリエンスに応じて、さまざまなオプションがあります。承認リクエストのコメントは 4,000 文字に制限されています。中国語、日本語、または韓国語では、制限は 1,333 文字です。


# 承認履歴は、Lightning の承認レコード (ProcessInstanceWorkItem) に表示されません。 
Classic では、承認を促すリンクをユーザーが受け取ると、承認履歴を表示するページに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3caa2c5d-f6a3-6993-b53d-a92c43806bb9.png)


Lightning では、承認履歴はこのページに表示されません。レコードのページにのみ表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d115bf86-585d-6c1a-9a94-5fce77545187.png)

承認履歴を表示するには、受信した電子メールで承認するためのリンクをクリックし、承認 (ProcessInstanceWorkItem) に移動してレコードをクリックし、レコードの承認履歴関連リストを表示する必要があります。
承認履歴は、Lightning Experience の承認 (ProcessInstanceWorkItem) で表示できるようにする必要があります。


[Lightning での承認時に承認履歴を表示](https://ideas.salesforce.com/s/idea/a0B8W00000GdjZUUAZ/show-approval-history-on-approval-in-lightning)

[EmailMessage](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_emailmessage.htm)

# 関連の質問

[メールメッセージオブジェクトの承認履歴について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000J68MN)
PowerPointにベクター画像を挿入する

PowerPointに所属組織のロゴをベクター画像で挿入した時のメモ。使っていたバージョンはPowerPoint for Microsoft 365 MSO (バージョン 2207 ビルド 16.0.15427.20182)。powerpoint、昔はベクター画像使えなかったような。
# やり方
1. 所属先が提供しているロゴのベクターデータを手に入れる。svg[^1]やpdf、epsなどで提供されている…のでは。
2. Inkscapeを手に入れる。使っていたのはVersion 1.2.1だけど、新しい分には何も問題ないでしょう。
https://inkscape.org/ja/
3. Inkscapeでpdfを開いて、ロゴ部分のみを選択し、コピーする。
4. 「形式を選択して貼り付け」で「画像（SVG）」を選択すれば、ベクター画像を挿入できる。
# 雑感
自分の知る限りでは、ラスター画像とベクター画像の違いを知らない人も少なくない。画像が綺麗であることは本質ではないし、それでいいと思う。でも私は**綺麗な画像だったりいい感じのデザインのほうが<font color="red">気分が上がる**のでやってます。**あくまでもこいつは<font color="red">趣味**です。<font color="gray">その割に、記事の見た目が美しくないのは、センスの問題ということで…</font>

# 参考
https://superable.wordpress.com/2011/09/15/%E3%83%91%E3%83%AF%E3%83%BC%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AB%E3%83%99%E3%82%AF%E3%82%BF%E3%83%BC%E7%94%BB%E5%83%8F%E3%82%92%E8%B2%BC%E3%82%8A%E4%BB%98%E3%81%91/

https://www.777logos.com/blog/vector-and-raster-graphics/

[^1]:svgが提供されている場合は、図形メニューからそのまま挿入すれば良いと思います。私の場合、pdfで作成されたロゴ使用に関するガイドブックのみ提供されていたため、そこから抜き出さざるを得なかった…。
【SpringBoot】入力値チェックエラーをリダイレクト先に渡す方法

ユーザーからの入力値を受け取った後、入力値チェックに引っかかった場合は、エラー内容とともにリダイレクトを行いたい。
※ 今回ユーザーからの入力値を受け取るクラスをUserFormとする。


~~~ java:リダイレクト先
@RequestMapping("/afterRedirect")
	public String afterRedirect() {
		return "afterRedirect";
	}

~~~

~~~ java:リダイレクト元

	@RequestMapping("/beforeRedirect")
	public String beforeRedirect(
			@Validated UserForm userForm, // 今回ユーザーからの入力値を受け取るクラスをUserFormとして作成
			BindingResult result, 
			RedirectAttributes redirectAttributes, 
			) {
		// 入力値チェックして、エラーがあればリダイレクトする
		if(result.hasErrors()) {
			redirectAttributes.addFlashAttribute(userForm); // (1)
			redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + Conventions.getVariableName(userForm), result); // (2)
			return "redirect:/afterRedirect";
		}

		return "noRedirect";
	}

~~~
### 解説
| Number | 内容|
|---|---|
|(1)|ユーザーが入力した値をリダイレクト先でも維持していたいので、フラッシュスコープにuserFormを詰める。|
|(2)|ここでBindingResultのエラー内容をフラッシュスコープに詰めている。<br> BindingResultがページに渡される際には、オブジェクト名の前に``org.springframework.validation.BindingResult.``という接頭辞がつくらしい。この接頭辞は、``BindingResult#MODEL_KEY_PREFIX``で表現することができる。<br> 今回、UserFormクラスのエラーをリダイレクト先に渡したいので、``Conventionsクラス``の[getVariableNameメソッド](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/core/Conventions.html#getVariableName-java.lang.Object-)を用いて変数名を指定する。<br> よって、フラッシュスコープには、スコープ名 ``BindingResult.MODEL_KEY_PREFIX + Conventions.getVariableName(userForm)``,スコープの中身は ``resul`` となる|


## 参考文献
[【悲報】Spring Bootのバリデーションで壁にぶち当たる]()
[org.springframework.core.Conventions](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/core/Conventions.html)
[SpringMVC BindingResultのRedirect](https://anveloper.com/2020/12/22/springmvc-bindingresult%E3%81%AEredirect/)
PHP基礎①代入の仕方・変数の画面表示


1⃣　変数とは、、、
→"値"を格納するための"箱"
（PHPでは、値そのものを変数に格納する）

●記述の仕方
```
$変数名 = 値;
```

※変数は事前に宣言は必要ない。値を格納した時点から、その変数が使用可能になる。
→それぞれの変数を区別するために変数には任意の変数名を付ける。

★変数は　「$」 + 変数名　で表される。

～変数命名時のルール～
```
$name
$_name_name
$name1234
```
上記例のように
1.頭がアルファベットで始まるもの
2.頭がアンダーバー(_)で始まるもの
3.上記２つ + その後にアンダーバー、数字、アルファベットが続くもの
が条件。

2⃣　代入演算子
変数に値を代入するには、「=」を使う。
→右辺の値を左辺に代入する。

```
$age = 20;
$name = '田中';
```

上記の場合だと、
「$age = 20;」→数値「20」を、変数「age」に代入している。
「$name = '田中';」→文字列「田中」を、変数「name」に代入している。
また一度値を代入された変数に、別の値を代入することもできる。







参考にさせていただいたサイト
https://www.javadrive.jp/php/var/index1.html
Adobe Acrobat Reader DCをwingetで導入して、余計な事をしないように設定を上書きする方法

# wingetいいよwinget

winget良いですね。すごいいいですね。
当初発表されたときには「これ本当にリポジトリ充実するんかいな?」とかなり疑問を持って見ていましたが、今や欲しいものは大体あるというWindowsでアプリを簡単に導入するための方法として十分に耐えられる物になってきました。
開発者の方々にも御対応いただいており[FastCopy](https://fastcopy.jp)や[CrystalDiskMark](https://crystalmark.info/ja/software/crystaldiskmark/)、果ては[Dell Command | Update](https://www.dell.com/support/kbdoc/ja-jp/000177325/dell-command-update)(MSI版とUWP版が両方ある)や[MPC-HC (clsid版)](https://github.com/clsid2/mpc-hc)までお手軽導入できるわけです。

この記事は、そんなわけで「よっし。キッティングでこれ使えるぞ」とばかりに入れられるソフトは全部winget経由で入れていたところ[Adobe Acrobat Reader DC](https://www.adobe.com/jp/acrobat/pdf-reader.htm)で「使用許諾が出てきたんだけれどもこれどうすれば良いの？」「なんか知らないけれどもAdobe Acorbat Readerって赤いアイコンが消しても消しても出てきてうざいから何とかならない💢❓」と問い合わせが上がってきて「あー。そういえばwinget使う前はキッティングの時にはバッチファイルからインストーラーを起動してEULA自動でYESしてたんだっけ」と遠くに目をやりながら思いだしたので、反省の念も込めて調査した結果をまとめました。

## 要旨

```winget install```にはインストーラー本体にコマンドラインオプションを渡す```--override```オプションがある。
これを使用することでインストーラーに追加で任意の引数を渡すことが出来る。  
Adobe Acrobat Reader DCをインストールする際には```/msi```オプションに対してさらに```EULA_ACCEPT=YES```を設定することで使用許諾に同意したことにでき、```DISABLEDESKTOPSHORTCUT=1```を設定することでデスクトップショートカットの作成を抑制できる。  
具体例を以下に示す。

```powershell
winget install Adobe.Acrobat.Reader.64-bit --override "/sPB /rs /rps /msi EULA_ACCEPT=YES ENABLE_OPTIMIZATION=1 DISABLEDESKTOPSHORTCUT=1"
```

## そもそもどんなオプションがあるんだっけ？

「はて、ググって調べてexeファイルにオプションを指定してインストールしていたが、Adobe公式的にはどんなオプションを用意してるんだっけ」
ちゃんと[オプション一覧](https://www.adobe.com/devnet-docs/acrobatetk/tools/DesktopDeployment/cmdline.html#msi-switches)や[設定値一覧](https://www.adobe.com/devnet-docs/acrobatetk/tools/DesktopDeployment/properties.html)はあるものですね。※だが英語だ

## これだけ押さえておけば大丈夫(??)なコマンドラインオプション

折角だから全部抄訳作ろうと思ったけれども力尽きちゃったよ。パトラッシュ……。  
というわけでインストーラー本体に設定するオプションと、```/msi```オプションに設定するオプションで「これだけ押さえておけば大丈夫だろう」というのを独断と偏見で選んでまとめました。

### 本体に設定するオプション

|コマンドラインオプション|説明|
|:-:|:--|
|/fa|アプリケーションを強制再インストールします。|
|/g|言語を言語IDで指定します。用例: /g LanguageID|
|/L|/L␣[i][w][e][a][r][u][c][m][p][*v][+][!]LogFile.txtの形式でログレベルを指定して、インストール・修復・アンインストールのログを保存します。|
|/p|更新を適用します(訳注:既にインストール済の場合?)|
|/x|製品をアンインストールします。|
|/sAll|インストーラーをサイレントモードで実行します(訳注:ウィンドウを一切出さずにインストールします)|
|/sPB|最小限のUIを表示してインストーラーをサイレントモードで実行します<br>インストーラーのプログレスバーのみ表示します。|
|/rs|インストール後の再起動を抑制します(訳注:Reboot Suppressの略)<br>再起動が必要な場合でもダイアログを表示しません。|
|/rps|リブートの実行を通知するプロンプトの表示を抑制します。<br>再起動が必要な場合、システムを警告無しで即時再起動します。|
|/ini "PATH"|パスで指定した別のブーとすトラッパーiniファィルの設定でインストールを実施します。/msi オプションでコマンドラインから与えられるオプション設定は無視されます。|
|/msi \[Commandline\]|追加のMSIEXECコマンドライン引数を設定します。|

### /msi オプションに設定できる追加のMSIEXEC引数

|MSIEXEC引数|説明|用例|
|:-:|:--|:--
|EULA_ACCEPT|エンドユーザーライセンス同意に同意します。|EULA_ACCEPT=YES|
|ENABLE_OPTIMIZATION|ディスクデフラグツールでアプリケーションの配置を最適化します|ENABLE_OPTIMIZATION=1|
|DISABLEDESKTOPSHORTCUT|デスクトップショートカットの作成方法を以下のフラグ値の総和で設定します。<br>・ 指定無し: AAM以外のすべてのショートカットを作成<br>・ 0: 総てのショートカットを作成<br>・ 1: 総てのショートカットを作成しない(このオプションはAcrobat Readerのみ有効)<br>・ 2: Acrobatのショートカットのみ作成しない<br>・ 4: AAMのショートカットのみ作成しない<br>・ FormCentralのショートカットのみ作成しない|Acrobat Reader DCのショートカットを作成しない場合:<br>DISABLEDESKTOPSHORTCUT=1|
JavaScriptの Object が子供な Array を fill で作ろうとして詰まった話

# 経緯
JavaScriptの配列にオブジェクトをもたせて、なおかつそれぞれ己の親配列内でのインデックスがあると実装が楽なんで要素として持たせようという場面。

次のように`fill`を使用してデフォルト値`p=0`を与えつつ、`map`のcallbackの第2引数のindexを`q`にセットしようとした。
が、すべての`q`が2になってしまった。

```javascript
x = Array(3).fill({p:0}).map((v,i)=>{v.q=i;return v;})

// 結果
[
  { p:0, q=2 },
  { p:0, q=2 },
  { p:0, q=2 }
]
```

# 結論
`fill`関数に渡されたオブジェクトは複製されない。

# 解説
まあ結論読めばあとは蛇足なんですが、
fill関数は渡された値を各要素値として直接代入するような操作をする。
渡されているのがObjectへの参照である場合、そのひとつの参照を配列の全要素にブチこむため、
せっかく配列なのに見ているObjectは一個という悲しい状態になる。

よって、mapで`v.q=i;`を呼ばれるたびに、同じObjectの`q`を更新していた。
```javascript
v.q=0; // x[0].q = 0; x[1].q = 0; x[2].q = 0;
v.q=1; // x[0].q = 1; x[1].q = 1; x[2].q = 1;
v.q=2; // x[0].q = 2; x[1].q = 2; x[2].q = 2;
```

# 回避策
僕が`Array(3).fill()`を呼ぶのは、
もともとは配列要素の値が`empty`のような状態[^1]だとmapが動かないからであって、
デフォルト値を渡すためではなかった。

おとなしく`undefined`で埋めてやれば `return` とかも書かなくて済む

```javascript
x = Array(3).fill().map((v,i)=>({p:0,q:i}))
```

まあ、デフォルト値を明示的に分離したいお気持ち表明をしてしまったせいで躓いたというクソつまんない原因でしたとさ。

[^1]:これもちと謎々なのだが、`Array(3).map((v,i)=>i)`は`[0,1]`になってくれない。`Array(3)`はコンソールでは`[empty x 3]`と表記され、この`empty`に該当する要素は処理から除外される。MDNのページには、「配列の中で存在しない要素(設定されたことがない添字・削除された要素・値を割り当てられたことがない要素)に対しては呼び出しません。」と記載がある。正直意味がわからんし処理しろと思うが、この仕様が活きている場所もあるかもしれないので仕方がない。該当するかどうかは`Object.keys(Array(2)) // result: []`のようにするとテストできるはずだ。
DB論理設計アンチパターン

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

SQLアンチパターンⅠ部のまとめメモです。
自分用にざっくりアンチパターンと解決策だけまとめるので、気になった方はぜひ書籍を読んでみてください。
### アンチパターン：カンマ区切りのフォーマットのリストを格納する
１対多の関係を表すとき、親テーブルの１つのカラムにカンマ（`,`）区切りで値を格納してはいけない。
おとなしく交差テーブル（いわゆる中間テーブル）を作成しよう。

### アンチパターン：常に親のみに依存する
掲示板のコメント欄のように再帰的な関連を持つデータを、隣接リストモデルを用いて表現してはいけない。
以下の代替ツリーモデルを使用すること。
* 経路列挙モデル
* 入れ子集合モデル
* 閉包テーブルモデル

### アンチパターン：すべてのテーブルに「id」を用いる
全てのテーブルにid列を加えると、意図に反した影響が生じることがある。
状況に応じて自然キーや複合キーを活用すること。

### アンチパターン：外部キー制約を使用しない
外部キー制約を省略する場合、参照整合性を保証するための「完璧なコード」を書く責任が生じる。
外部キー制約による参照整合性の強制によって、人為的ミスを防止・是正できる。
パフォーマンスは外部キーの省略を正当化する理由としてよく挙げられるが、実際には外部キーの省略によって様々な問題が生じることが多く、その問題にはパフォーマンスの問題も含まれる。

### アンチパターン：汎用的な属性テーブルを使用する
なんでも入るテーブルを実装してはいけない。
リレーショナルデータベースの多くの長所が失われてしまうため、そのようなテーブルを実装したいと考えたとき、以下のサブタイプのモデリングを行うこと。
* シングルテーブル継承
* 具象テーブル継承
* クラステーブル継承
* 半構造化データ

### アンチパターン：二重目的の外部キーを使用する
複数の親テーブルを参照する一つの外部キーを実装してはいけない。
**本来あるべき関連が逆さまになっている**ことが問題の本質であり、以下のテクニックを用いてリレーションシップを単純化すること。
* 交差テーブルの作成
* 共通の親テーブルの作成

### アンチパターン：同じ属性の複数の列を定義する
１対多の関係をあらわすとき、親テーブルにそれぞれの子要素の値を格納する列を複数作成してはいけない。
属性を格納する列を１つ持つ従属テーブルを作成すること。

### アンチパターン：テーブルや列をコピーする
行数の多いテーブルを複数のテーブルに分割したり、列を複数列に分割してはいけない。
以下のテクニックを用いてテーブルのパーティショニングと正規化を行うこと。
* 水平パーティショニング
* 垂直パーティショニング
* 従属テーブルの導入
PowerShellでWindowsサービス確認

# はじめに
PowerShellでWindowsサービス確認する際にfindコマンドのように特定の文字でフィルタリングする方法をまとめた。

# コマンド
下記はXBox関連サービス状態を確認しようとステータスチェックしたコマンド。

```powershell
PS> Get-Service | Where-Object {$_.DisplayName | Select-String "Xbox" }
```

実行結果

```
Status   Name               DisplayName
------   ----               -----------
Stopped  XblAuthManager     Xbox Live Auth Manager
Stopped  XblGameSave        Xbox Live セーブ データ
Stopped  XboxGipSvc         Xbox Accessory Management Service
Stopped  XboxNetApiSvc      Xbox Live ネットワーキング サービス
```

# 参考
https://www.adamfowlerit.com/2017/02/how-to-grep-in-powershell/
[OCI]LB配下のVMのヘルス状態を参照し通知を行う

# はじめに
LB配下のHealth Check状態を基に、基準値から下がった場合はメール通知を行うようにする

- 通知先(トピック)の作成
- アラームの定義

を行うことで手軽に設定をすることが可能になる。

# 設定
## 通知設定
メール先(通知先)を登録する
監視および管理→通知より設定可能

### トピックの作成
名前を任意で入れて作成

### サブスクリプションの作成
作成したトピック名をクリックし、リソース内のサブスクリプションの作成をクリック

### サブスクリプションの構成
メールで送信したい場合は、プロトコルを電子メールに設定して、通知させたいメールアドレスを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/6c7a3b98-3fe6-a911-8e3c-3121a499d8af.png)
作成を押すと、登録したメールアドレスに確認のメールが届く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/03b1c78c-a115-0a17-de28-9d4f2668a455.png)
"Confirm subscription"をリンクをクリックすることで登録したメールアドレスが通知先として利用できるようになる。

### 確認
ActiveになっていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/91b7e892-3077-992f-21ae-36fc1e80960c.png)



## アラームの定義
モニタリング→アラーム定義より作成が可能

### アラームの定義
アラーム名、重大度は自由に設定する

### メトリックの説明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/d9839e4c-012c-87f6-837a-0e673192ab54.png)
[UnhealthyBackendServers](https://docs.oracle.com/ja-jp/iaas/Content/Balance/Reference/loadbalancermetrics.htm#:~:text=UnhealthyBackendServers): バックエンド・セットの異常なバックエンド・サーバーの数。






### メトリックディメンション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/8b0350b8-c92f-fe1b-99ba-75bb19546053.png)

### トリガールール
通知させたい閾値をこちらに指定する
"UnhealtyBackendServers"なので、1台以上VMがNGとなった場合に通知させたい場合は下記のようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/185daf57-499d-4cfa-e3a3-457a0c611648.png)

トリガー遅延分数：アラームが起動状態になるまでに条件が維持される分数。
(今回の場合だと、1分以上閾値が満たされているとアラーム発報。数秒程度ではアラームは発生しない。)

### Notifications
事前に定義した通知先を指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/92aecba9-4e88-4b86-0f9d-11d08b178666.png)



完了したら作成

### 確認

試しにLB配下のLBを1台落としてみると、アラームが閾値に引っかかりメールが送信されることが確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/3a4700a6-57b3-340b-37d2-1daabdf154ec.png)
docker buildで「It looks like you're trying to use TypeScript but do not have the required package(s) installed.」というエラーが出る

Reactアプリをdockerでbuildしようと思ったら、下記のようなエラーが出た。

```Shell
> hogehoge@0.1.0 build
> next build

info  - Loaded env from /hogehoge/.env.production
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

info  - Checking validity of types...
It looks like you're trying to use TypeScript but do not have the required package(s) installed.

Please install @types/react by running:

	npm install --save-dev @types/react

If you are not trying to use TypeScript, please remove the tsconfig.json file from your package root (and any TypeScript files in your pages directory).

executor failed running [/bin/sh -c npm run build && npm install]: exit code: 1
ERROR: Service 'web' failed to build : Build failed
```

でも、package.jsonには`@types/react`はある。

調べてみたところ、下記のような記事を発見。
[create-next-app --ts not recognising @types/react #36085
](https://github.com/vercel/next.js/issues/36085)[[TypeScript] nodeが起動しない Please install @types/react ？？？？](https://techback.info/node_does_not_boot_please_install/)

バグが起きているっぽい・・・？
`@types/react`のバージョンに18.02を使っているとバグが出る！と言う記事をたくさん見かけたのですが
そもそも`"^17.0.41"`を使用していたのでこれには該当しない（恐らく）

ですが、どうやら他にも、typescriptやnode、nextなど他のバージョンとも関連してバグが起きているようだったので、一旦`@types/react`をダウングレードしてバージョンを固定させようと思い、package.jsonを下記のように書き換えました。


```package.json
{
  "devDependencies": {
    "@types/react": "17.0.11",
  }
}
```

npm installを実行して、package-lock.jsonのバージョンも変わっていることを確認。

この状態で再度Dockerのbuildをしたら、無事buildできました🎉
クリーンアーキテクチャを読んで #1

クリーンアーキテクチャを読んだメモと所感を残していこうと思う

# 1.設計とアーキテクチャ
「ソフトウェアアーキテクチャの目的は、求められるシステムの構築
保守に必要な人材を最小限に抑える」

⇨これ、今触ってるプロジェクトで凄く心当たりがあリます・・・
改修フェーズの段階のプログラムを1人で触っているのですが、いろんな人が触ってきたソースで書き方がバラバラでちょっとした修正にもかなりの工数を必要としてるという・・・

# 2.2つの価値の話
・振る舞い・・・緊急
・アーキテクチャ・・・重要

優先順位
1.緊急かつ重要
2.緊急ではないが重要
3.緊急だが重要ではない
4.緊急でも重要でもない

⇨2と3の順番が今触ってるプロジェクトだと逆になっているような気がする。
30分で読むには惜しい「データマネジメントが30分でわかる本」を推す

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

データマネジメント知識体系（DMBOK）の独自要約とケーススタディ集 ということで、データ管理のための仕組みについての入門書。 クラウド寄りのインフラエンジニアの自分は、データ周りは環境を作っておしまいのことが多く、運用もサーバだったりサービスだったり、下回りのため、データ管理について、なぜ、どのように、を実践的に説明してくれる本書はわかりやすかったのでお勧めです。

章立ては以下のとおり。

【01：データアーキテクチャ】
【02：データストレージとオペレーション（DB）】
【03：データ統合と相互運用性（ETL）】
【04：データモデリングとデザイン（ER）】
【05：マスターデータ管理】
【06：ドキュメントとコンテンツ管理】
【07：データセキュリティ】
【08：データ品質管理】
【09：データウェアハウジング（DWH）とビジネスインテリジェンス（BI）】
【10：メタデータ管理】
【11：データガバナンス】

各章ごとに30秒コース、3分コース、30分コース、3時間コースがあるので、30秒コースをよんで2分考えるであれば、たしかに30分で終わりますが、記憶にのこらないので、全部じっくり読むとよいです。自分は隙間時間にちまちま読み1週間、15時間ほどかかりました(参考リンク等はみる時間はなかったです)。

出版が2020/3と2年前になります。当然古い部分があるのですが、クラウド系の技術より陳腐化する部分が少ないと感じました。また、A/Bテストの話や、評価をふくめたサイクルをまわすことで、システムの陳腐化を防ぐ仕組みについて記載しているのも実践的なシステムをつくってきた人が書いてるなという感想です。一度全部読んで、後で実際の問題にはまったら見直す、という使い方もありです。

あとがきの
「場当たり対応、そろそろやめませんか?」
という部分もよい話でした。心抉られますが。

欠点といっていいのか目的外というか、網羅的ではないです。amazonのレビューの指摘もありましたし、著者自身もDMBOKの内容と整合的ではないと書いています。DMBOKの本の厚さをかんがえれば、まぁ当然ですよね。
また、大きな組織だとデータに関連して組織の問題がでてきそうですが、その部分も比較的簡易にかかれていると感じました。この部分、データ管理システムもコンウェイの法則に従うという理解です。

まとめると、データ管理にかかわる人のとっかかりとしては非常に優秀なので読もうね、です。

ではでは。
Javaの学習 ~識別子~

### 識別子とは
変数やメソッド、クラスなどの名前のことを識別子と呼びます。
識別子の命名規則は、以下の３つです。

①予約語を識別子として使うことはできない
②使える記号はアンダースコア「_」と通貨記号（主に「$」）のみ
③数字から始めてはいけない

##### 予約語
予約語(キーワードとも呼ばれる)とは、プログラムの文を表現するためにあらかじめ用途が決められている単語のことを言います。
例えば、データ型を表現する「int」や「char」、繰返し等の構文に使用する「for」や「if」は予約後にあたり、識別子として命名することができません。
ただし、予約語単体ではなく、「intA」のように別の文字と組み合わせたりすることで使用可能にはなりますが、推奨はされません。