OmniAICreator/Qiita-1.07M huggingface dataset:
cscの作法 その324

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
sqliteで、insert intoを発行せよ。

# サンプルコード

```
using System;
using System.Text;
using System.IO;
using System.Data.SQLite;

namespace App
{
	public class Program {
		public static void Main(string[] args) {
			SQLiteConnectionStringBuilder ConnectionStr = new SQLiteConnectionStringBuilder();
			ConnectionStr.DataSource = "db0.sqlite";
			using (SQLiteConnection Connection = new SQLiteConnection(ConnectionStr.ToString()))
			{
				Connection.Open();
				using(SQLiteCommand Command = new SQLiteCommand(Connection))
				{
					Command.CommandText = "INSERT INTO fruit(id, name, number, price) VALUES (:id, :name, :number, :price)";
					Command.Parameters.Add(new SQLiteParameter("id", 1));
					Command.Parameters.Add(new SQLiteParameter("name", "mango"));
					Command.Parameters.Add(new SQLiteParameter("number", 2));
					Command.Parameters.Add(new SQLiteParameter("price", 500));
					Command.ExecuteNonQuery();
				}
			}
			Console.WriteLine("ok0");
		}
	}
}



```

以上。
cscの作法 その323

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題

sqliteで、create tableを発行せよ。

# サンプルコード

```
using System;
using System.Text;
using System.IO;
using System.Data.SQLite;

namespace App
{
	public class Program {
		public static void Main(string[] args) {
			SQLiteConnectionStringBuilder ConnectionStr = new SQLiteConnectionStringBuilder();
			ConnectionStr.DataSource = "db0.sqlite";
			using (SQLiteConnection Connection = new SQLiteConnection(ConnectionStr.ToString()))
			{
				Connection.Open();
				using(SQLiteCommand Command = new SQLiteCommand(Connection))
				{
					Command.CommandText = "CREATE TABLE IF NOT EXISTS fruit(id INTEGER, name TEXT, number INTEGER, price INTEGER)";
					Command.ExecuteNonQuery();
				}
			}
			Console.WriteLine("ok0");
		}
	}
}



```


以上。
【JavaScript】端点の太さの異なる線分を描画する【Canvas】

# はじめに
やりたいことは、以下の画像のように端点の太さが変わる線分の描画です。
始点終点を丸くするか選べます。
パスを作成する関数なので、もちろん塗りつぶせもします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/b65c8ccb-b867-bbc2-c243-a629ebf47ac6.png)

# サンプルプログラム
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>line path sample</title>
<script>
/**
 * 線分のパスを作成する
 * @param {CanvasRenderingContext2D} ctx キャンバスのコンテキスト 
 * @param { x: number, y: number, width: number, arc: boolean, }} start 始点
 * @param { x: number, y: number, width: number, arc: boolean, }} end 終点 
 * @returns {void} なし
 */
function createLinePath(ctx, start, end) {
    const vec = { x: end.x - start.x, y: end.y - start.y, };  // 始点から終点へのベクトルを求める
    const len = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
    const unit = { x: vec.x / len, y: vec.y / len, };  // 単位ベクトル化する
    const nrm = { x: unit.y, y: -unit.x, }; // -90度回転する
    // 角度を求める
    const angle = Math.atan2(nrm.y, nrm.x);
    // 点を求める
    const posArray = [
        {
            x: start.x + nrm.x * start.width / 2,
            y: start.y + nrm.y * start.width / 2,
        },
        {
            x: end.x + nrm.x * end.width / 2,
            y: end.y + nrm.y * end.width / 2,
        },
        {
            x: end.x - nrm.x * end.width / 2,
            y: end.y - nrm.y * end.width / 2,
        },
        {
            x: start.x - nrm.x * start.width / 2,
            y: start.y - nrm.y * start.width / 2,
        },
    ];

    ctx.beginPath();
    ctx.moveTo(posArray[0].x, posArray[0].y);
    ctx.lineTo(posArray[1].x, posArray[1].y);
    if(!end.arc) {// 終点を丸くする
        ctx.lineTo(posArray[2].x, posArray[2].y);        
    } else {
        ctx.arc(end.x, end.y, end.width / 2, angle, angle + Math.PI);
    }
    ctx.lineTo(posArray[3].x, posArray[3].y);
    if(!start.arc) {// 始点を丸くする
        ctx.lineTo(posArray[0].x, posArray[0].y);   
    } else {
        ctx.arc(start.x, start.y, start.width / 2, angle + Math.PI, angle);
    }
    ctx.closePath();
}
document.addEventListener('DOMContentLoaded', e => {
    const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext('2d');
    
    ctx.save();
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.lineWidth = 4;
    ctx.strokeStyle = 'yellow';
    createLinePath(ctx, { x: 100, y: 100, width: 50, arc: true }, { x: 300, y: 300, width: 10, arc: true });
    ctx.stroke();
    ctx.restore();
});
</script>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
</html>

```

# 応用例
プログラムは書かないけど、応用例としては「ベジェ曲線の太さを変える」などが思いつきます。
ベジェ曲線を微小な線分に分割して、長さに比例した太さを指定すれば徐々に太さの変わるベジェ曲線が描画できると思います。
ADO.NET の非同期トランザクション

`DbConnection`クラスのメソッドが色々と非同期になっているので、トランザクションを非同期で実装する例

参考：[MSDN](https://learn.microsoft.com/ja-jp/dotnet/api/system.data.common.dbconnection)

## 通常のトランザクション

- 先ずは「同期」でトランザクションを行うメソッド
  - 処理内容は`func`として外部から指定できるように

```C#
public static TResult Transact<TResult>(DbConnection connection, IsolationLevel isolationLevel, Func<DbTransaction, TResult> func)
{
  connection.Open();
  try
  {
    using var transaction = connection.BeginTransaction(isolationLevel);
    try
    {
      var result = func(transaction);
      transaction.Commit();
      return result;
    }
    catch
    {
      transaction.Rollback();
      throw;
    }
  }
  finally
  {
    connection.Close();
  }
}
```

## 非同期トランザクション

- 上記メソッドを「非同期」に変更
  - `Func<DbTransaction, TResult> func`を
  - `Func<DbTransaction, Task<TResult>> funcAsync`に変更

```C#
public static async Task<TResult> TransactAsync<TResult>(DbConnection connection, IsolationLevel isolationLevel, Func<DbTransaction, Task<TResult>> funcAsync)
{
  await connection.OpenAsync();
  try
  {
    using var transaction = await connection.BeginTransactionAsync(isolationLevel);
    try
    {
      var result = await funcAsync(transaction);
      await transaction.CommitAsync();
      return result;
    }
    catch
    {
      await transaction.RollbackAsync();
      throw;
    }
  }
  finally
  {
    await connection.CloseAsync();
  }
}
```

### 使用例

- 通常と非同期トランザクションのそれぞれの呼び出し方

```C#
string TestTransaction()
{
  using var connection = new SqlConnection("接続文字列");
  return Transact(connection, IsolationLevel.ReadCommitted, transaction =>
  {
    using var select = transaction.Connection.CreateCommand();
    select.CommandText = "SELECT id FROM table";
    var result = select.ExecuteScalar();
    return (string)result;
  });
}

async Task<string> TestTransactionAsync()
{
  using var connection = new SqlConnection("接続文字列");
  return await TransactAsync(connection, IsolationLevel.ReadCommitted, async transaction =>
  {
    using var select = transaction.Connection.CreateCommand();
    select.CommandText = "SELECT id FROM table";
    var result = await select.ExecuteScalarAsync();
    return (string)result;
  });
}
```
【AWS】Amazon Textract備忘録

Amazon Textractは、スキャンしたドキュメントからテキスト、手書き文字、およびデータを自動的に抽出する機械学習 (ML) サービスです。

https://aws.amazon.com/jp/textract/features/?pg=ln&sec=hs

主な機能は以下です。
1. テキスト抽出:
Textractは、画像またはPDFといったドキュメント形式からテキストを抽出します。印刷文字、手書き文字、テーブルのデータなど、さまざまなタイプのテキストを認識することができます。

1. テーブル抽出:
Textractは、画像やPDF内のテーブルデータを認識し、テーブルのセル、行、列の情報を抽出します。この情報を利用して、テーブルデータを構造化して取得することができます。

1. フォーム抽出:
Textractは、フォーム内のフィールドやキーバリューペアを自動的に検出し、抽出します。これには、氏名、住所、日付、金額など、様々な種類のデータを含むフォームが対象となります。

1. キー情報の抽出:
Textractは、特定のキーワードやパターンを含む情報を検出することもできます。例えば、特定のキーワードや値を持つ項目を抽出することができます。

1. コンフィデンススコアの提供:
Textractは、抽出されたテキストやデータの信頼性を示すコンフィデンススコアも提供します。これにより、抽出結果の信頼性を評価することができます。

## 使い方

```Python
import os
import sys
import logging
import boto3
from botocore.exceptions import ClientError

logger = logging.getLogger(__name__)

AWS_ACCESS_KEY_ID=************
AWS_SECRET_ACCESS_KEY=************************
AWS_SESSION_TOKEN=********************************************


class TextractWrapper:
    """Encapsulates Textract functions."""
    def __init__(self, textract_client, s3_resource, sqs_resource):
        """
        :param textract_client: A Boto3 Textract client.
        :param s3_resource: A Boto3 Amazon S3 resource.
        :param sqs_resource: A Boto3 Amazon SQS resource.
        """
        self.textract_client = textract_client
        self.s3_resource = s3_resource
        self.sqs_resource = sqs_resource

    def detect_file_text(self, *, document_file_name=None, document_bytes=None):
        """
        Detects text elements in a local image file or from in-memory byte data.
        The image must be in PNG or JPG format.

        :param document_file_name: The name of a document image file.
        :param document_bytes: In-memory byte data of a document image.
        :return: The response from Amazon Textract, including a list of blocks
                 that describe elements detected in the image.
        """
        if document_file_name is not None:
            with open(document_file_name, 'rb') as document_file:
                document_bytes = document_file.read()
        try:
            response = self.textract_client.detect_document_text(
                Document={'Bytes': document_bytes})
            logger.info(
                "Detected %s blocks.", len(response['Blocks']))
        except ClientError:
            logger.exception("Couldn't detect text.")
            raise
        else:
            return response

# Document
documentName = r"img/sample.png"
textract_client = boto3.client('textract', 
                        aws_access_key_id=AWS_ACCESS_KEY_ID, 
                        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                        region_name=AWS_REGION,
                        aws_session_token= AWS_SESSION_TOKEN)

s3_resource = ''
sqs_resource = ''
Textract = TextractWrapper(textract_client, s3_resource, sqs_resource)
response = Textract.detect_file_text(document_file_name=documentName, document_bytes=imageBytes)
for item in response["Blocks"]:
    if item["BlockType"] == "LINE":
        print ('\033[94m' +  item["Text"] + '\033[0m')
```
AtomS3　NTPサーバー時刻の同期

# 概要
小型且つディスプレイ付きで便利そうなAtomS3を購入しました。
最終的には工場などの温度ログをmodbusTCPにて取得したいと考えています。
まずはログに必要な時刻データを取得できるようにNTPサーバーの時刻と同期させます。

![スクリーンショット 2023-06-02 094557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611426/ee397f3f-e618-2957-c9c9-6ccbdf84c388.png)


# 環境
エディタ：VisualStudioCode（拡張機能：PlatformIO IDE）
ライブラリはPlatformIOで以下をインストール
　1.　M5Unified

# コード
``` cpp
#include <Arduino.h>
#include <M5AtomDisplay.h>
#include <M5Unified.h>
#include <WiFi.h>

// WiFi credentials.
const char* WIFI_SSID = "YOUR_SSID";
const char* WIFI_PASS = "YOUR_PASS";

// Time
char ntpServer[] = "ntp.nict.jp";
const long gmtOffset_sec = 9 * 3600;
const int  daylightOffset_sec = 0;
struct tm timeinfo;
String second, minute, hour, dayOfWeek, dayOfMonth, month, year;

void getTimeFromNTP(){
  // NTPサーバと時刻を同期
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  while (!getLocalTime(&timeinfo)) {
    delay(1000);
  }
}

void getTime(String* year,String* month,String* day,String* hour,String* min,String* sec,String* wday){
  char buf[10];
  getLocalTime(&timeinfo);
  *year = String(timeinfo.tm_year + 1900);
  sprintf(buf,"%02d",timeinfo.tm_mon + 1);
  *month = String(buf);
  sprintf(buf,"%02d",timeinfo.tm_mday);
  *day = String(buf);
  sprintf(buf,"%02d",timeinfo.tm_hour);
  *hour = String(buf);
  sprintf(buf,"%02d",timeinfo.tm_min);
  *min = String(buf);
  sprintf(buf,"%02d",timeinfo.tm_sec);
  *sec = String(buf);
  strftime(buf,10, "%A", &timeinfo);
  *wday=String(buf);
}

void setup() {
  auto cfg = M5.config();
    M5.begin(cfg);
    M5.Display.init();
    M5.Display.setRotation(2);
    M5.Display.setFont(&fonts::lgfxJapanGothicP_12);
    M5.Display.setTextColor(WHITE, BLACK);
    M5.Display.println("NTP時刻同期");

  //Connect WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while( WiFi.status() != WL_CONNECTED) {
    M5.Display.setCursor(12,12);
    M5.Display.print("＊　　");
    delay(200);
    M5.Display.setCursor(12,12);
    M5.Display.print("　＊　");
    delay(200);
    M5.Display.setCursor(12,12);
    M5.Display.print("　　＊");
    delay(200);
  }  
  M5.Display.setCursor(0,12);
  M5.Display.print("IP:");
  M5.Display.print(WiFi.localIP());

  // timeSet
  getTimeFromNTP();
  
}

void loop() {
  getTime(&year,&month,&dayOfMonth,&hour,&minute,&second,&dayOfWeek);
  M5.Display.setCursor(0,50);
  M5.Display.print(year+"/"+month+"/"+dayOfMonth);
  M5.Display.setCursor(0,62);
  M5.Display.print(hour+":"+minute+":"+second);
  M5.Display.setCursor(0,74);
  M5.Display.print(dayOfWeek);
  delay(1000);
}
```

# 参考サイト
https://www.electrorules.com/esp32-ntp-client-server-get-date-and-time-arduino-ide-2/

https://qiita.com/kaoruka/items/b36c99fb124fea0d5d24

https://skpme.com/204/
XREALAirと最初の開発のセットアップ


# はじめに

Nrealというブランドが、XREALとして新しくスタートしました。 
これまでのNreal Air → XREAL Airとしてブランドが一新されるそうです。
また、XREAL Beamというデバイスも発表され、Android端末以外でも、3DoFを含むディスプレイモードを利用できるようになるそうでとても楽しみです。
私も、iPhoneユーザーであるため、Nebula for Android環境がなかったのですが、中古の対応端末が比較的安価に出回るようになったので、改めて購入してみました。
一連の開発の流れについて覚書として残しておきます。

# 開発の流れ

(1)Unityで開発 > (2)Android端末でビルド > (3)Nrealを接続し動作確認 -> (1)に戻る

# 端末準備(開発者モードをONに)

Sony Xperia 5 901SO

## 1.デバイス情報 > ビルド番号を何度か押すことで開発者オプションが表示
![IMG_2049.jpg](https://qiita-image-store.s3.ap-northeast-
1.amazonaws.com/0/43766/941cd9f8-0c4d-d3d9-4aa7-de20525729ed.jpeg)

##2. システム > 開発者オプション
![IMG_2048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/944cffbc-7505-e39f-97da-9bdfb3af9ff4.jpeg)

##3. USBデバッグをONにする
![IMG_2046.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/0c14e05e-6ea6-83f8-7182-e18d5422d0ac.jpeg)


# 手順

## 1. Unityでプロジェクトを作成

![スクリーンショット 2023-05-31 13.54.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/e6738a8d-e211-39a4-b4f5-634de2ed5c2b.png)

## 2. 開発キットをダウンロード
https://developer.xreal.com/download

![スクリーンショット 2023-05-31 13.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/60717e81-1128-3823-4bad-c8bf51987008.png)

## 3. 環境をAndroidに変更して必要なモジュールを入れる

![スクリーンショット 2023-05-31 14.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/c9e659ae-aa9c-0141-3fd6-a9af97614542.png)


![スクリーンショット 2023-05-31 14.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8a811004-f991-2aca-8a16-adfb4e57e1d2.png)

![スクリーンショット 2023-05-31 14.01.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/2637cf44-a9ab-75c0-fd4f-5447c22ad212.png)

## 4.NRSDKForUnity_Release_1をインポート
Packageのところにダウンロードしてきた「NRSDKForUnity_Release_1.10.2 (1).unitypackage」をdrag & dropするとインポートできる

![スクリーンショット 2023-05-31 14.06.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/46cfc51a-00f0-5c49-0db5-e612f14710fb.png)


## 5.既存のカメラを削除し、NRCameraに入れ替える
Assets>NRSDK>Prefabsの中にあるNRInputとNRCameraをSceneに追加します。

![スクリーンショット 2023-05-31 14.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ea281ab5-7904-fbd6-c39d-dc5788d62f85.png)

## 6. オブジェクトを配置

![スクリーンショット 2023-05-31 21.11.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/92e4a314-42bc-9e22-137e-b6155327221f.png)

## 7.実行ボタンを押下してみる

![スクリーンショット 2023-05-31 15.22.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/bbcebe8b-0fcc-98bc-0d1d-97fd147e4fcf.png)

## 8.端末にビルドする
ツールバーのNRSDKからProject Tiosを選びAccept Allを押します。

![スクリーンショット 2023-05-31 15.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/abcdbe07-f49c-25ce-1646-e0e85ba6977d.png)


# そのほかTIPS

## Unityでglbを扱えるようにする

https://github.com/ousttrue/UniGLTF/releases

![スクリーンショット 2023-06-02 9.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ac38a671-ca07-48b2-bfd2-98a30251c607.png)

![スクリーンショット 2023-05-31 22.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f9bf45f5-5c63-99f5-6fa6-1ff1be9f8fe8.png)


# Conclusion
かいはつめもさまねこ

かいはつめもさまねこ

:::note
Linuxコマンド
:::

```
// タイムゾーン設定と確認
export TZ="Asia/Tokyo"
echo $TZ

// lsしたファイル数をカウントする
ls | wc -l

// ファイルの行数をカウントする
cat file.txt | wc -l

// lsした時のファイルのみの一覧を表示する
ls | awk {print $1}

// zipファイル一覧を全て解凍するようなシェルを作るコマンド
ls | awk {print $1} | sed -E 's/^/unzip /g' > go.sh;sh go.sh

// 指定したファイル以外を削除するコマンド　※ファイル以外のディレクトリも削除されることになるので注意する
find . -type f | grep -v -E '*_5303946_*' | xargs rm -rf

// 実行中のexeの使用率を2秒毎に監視する
top -d 2 | grep TestApp

//catしてファイル内の行数をカウントする
ls | awk '{print $1}' | sed -E 's/^/cat /g' | sed -E 's/$/ | wc -l/g' > go.sh;sh go.sh

//ファイル分割
split -b 200M file.txt

//gzファイルの解凍
gzip -d xxx.gz

//サブディレクトリ配下のファイルをgrepする
find . -type f -print | xargs grep ""
```
:::note
AWSコマンド
:::
```
//ファイルサイズ表示コマンド
aws s3 ls [S3バケット名] --recursive --human-readable --sum

//Ctrファイル一括削除コマンド
aws s3 ls [S3バケット名] | grep ERREND | sed -E 's#^.* +#[S3バケット]#g' > go.sh;sh go.sh;rm go.sh

```

:::note
秀丸エディタ正規表現
:::
```
//1文字ずつタブを入れる
(.+?)
を
\1\t

```


:::note
プログラム
:::
```
//mkdirでディレクトリが作成できない場合
⇒普通にインクルードできているかをチェックしよう(インクルードしていなくてもビルドが通ってしまう為)

参考URL
https://yu-nix.com/archives/c-mkdir-rmdir-stat/#Linux%E3%81%A7%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E4%BD%9C%E6%88%90


//templeteについて
sizeof(X)
⇒環境によってはlong型のサイズが変わってしまうので注意する。

//10進数、0詰め、桁指定のprint

int value = 100;
std::cout << "value=" << std::dec << std::setfill('0') << std::setw(3) << value << std::endl;

16進数のprintは0x付けるとよい
std::cout << "value=0x" << std::hex << value << std::endl;

※改行する場合は末尾に￥記号

//char型の変数に格納した数値をstd::outで標準出力確認できない(標準出力ログをリダイレクトしても確認できない)
⇒int型の変数に設定後にstd::outすればよい。

unsigned char uc_num = 100;
std::out << (int)uc_num << std::endl;
とか、int型の変数に設定後にすればよい。

unsigned int ui_num = 0;
ui_num = uc_num;
std::out << ui_num << std::endl;

//vectorのソート優先順付け
struct 


```
rootなのに書き込めないファイルがある！カーネルパラメータfs.protected_regularの挙動

手元のRockyLinux環境をRockyLinux8からRockyLinux9に更新した際に、カーネルパラメータ`fs.protected_regular`がデフォルトで1となったため今までと違った挙動を示すようになった問題について紹介します。

# どういう挙動になる？

`/tmp`の権限を確認します。通常ここはsticky bitが設定されています

```
$ ls -la /tmp
(略)
drwxrwxrwt.  9 root        root        4096 May 31 01:17 .
(略)
```

一般ユーザで`/tmp`に`test`というファイルを作ります

```
$ touch /tmp/test
```

動作確認のためのPythonスクリプトを用意します

```open.py
f = open("/tmp/test", "w")
```

一般ユーザで実行してみます(これは問題なく実行できる）

```
$ python open.py
$
```

rootで実行してみます

```
$ sudo python open.py
Traceback (most recent call last):
  File "/home/rocky/sticky-dir/open.py", line 1, in <module>
    f = open("/tmp/test", "w")
PermissionError: [Errno 13] Permission denied: '/tmp/test'
```

お！失敗しますね。
rootって万能じゃなかったんでしょうか・・？

# カーネルパラメータ`fs.protected_regular`

上記の挙動はこのカーネルパラメータが`1`となっているためにおきました。

```
$ sudo sysctl -a |grep fs.protected_regular
fs.protected_regular = 1
```

このフラグが設定されていると　誰でも書き込めるsticky bitのついているディレクトリ内のファイルについて、その所有者しか編集できなくなるようです。（たとえrootであっても編集できません）

このカーネルパラメータは以下で導入されています

- パッチは以下で確認できます
    - https://lwn.net/Articles/748141/
- カーネルへの取り込みはこのCommitのようです
    - https://github.com/torvalds/linux/commit/30aba6656f61ed44cba445a3c0d38b296fa9e8f5

説明によると、このパラメータは攻撃者にデータをすり替えられるのを防ぐために導入されたもののようです。

設定で`0`に戻すこともできますが、そもそも利用者でないユーザがファイルを変更するという動作自体を見直したほうが良いと思います。
Google Cloudのリソースを棚卸しするための方法

# はじめに
本記事はGoogle Cloudで管理しているリソースを棚卸しするための方法について記載しています。

情報システム部門やCCoEなど横断的組織として活動する場合は、定期的なリソースの棚卸しが必要不可欠です。

ガベージコレクションのように不要なリソースは定期的に削除することで、秩序を保ち無駄を無くしましょう。

本記事で紹介している方法は一例です。全てを網羅する内容ではない点については、ご留意ください。

## プロジェクトの棚卸し
前提として、Google Cloudで使用するリソースは、[**Resource Manager**](https://cloud.google.com/resource-manager?hl=ja)が提供する機能を踏まえて、以下図のような階層になっています。

![Google Cloud リソース階層の完全な形態の例](https://cloud.google.com/resource-manager/img/cloud-hierarchy.svg)

従ってCCoEのようなクラウドを管理する部門では、フォルダとプロジェクトを適切に管理することが重要です。

プロジェクト管理の詳細については、公式ドキュメントの[プロジェクトの作成と管理](https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja)から確認できます。

プロジェクトの棚卸しを行う方法について、コンソールから行う方法と、コマンドライン（以下、CLI）で行う方法を以下に記載します。

出力される情報は、実行したユーザがアクセス可能なプロジェクトに限定されます。

### コンソール
コンソールで操作する場合は、Resource Managerのコンソール画面から確認することができます。

![スクリーンショット 2023-05-30 19.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/b44bd0ec-fb34-aad4-6d37-a901d6363ddb.png)

### gcloud
CLIで操作したい場合は、[gcloud projects list](https://cloud.google.com/sdk/gcloud/reference/projects/list)コマンドを使用することで、プロジェクトを一覧表示します。

各オプションを使用して出力を加工することができます。
以下は、出力フォーマットをjson形式で、プロジェクトの作成日付で並び替えを行ない、jsonファイルとして保存する場合の例です。

`$ gcloud projects list --format="json" --sort-by=createTime > project.json`

また、`--format`オプションを活用することで、csvなど任意の形式に出力することができます。
Google Cloud Platform Japan Blogの[gcloud による出力情報のフィルタと整形](https://cloudplatform-jp.googleblog.com/2016/06/gcloud.html)を参考にすると、テーブル形式の出力などをも可能です。

`$ gcloud projects list --format="table[box,title='My Project List'](createTime:sort=1,name,projectNumber,projectId:label=ProjectID,parent.id:label=Parent)"`

::: note
`gcloud topic formats`コマンドを実行することで、出力形式の確認ができます。
:::

## リソースの棚卸し
IAMのアセットインベントリを使用することで、全体のリソースを可視化することができます。

出力される情報は、実行したユーザがアクセス可能なリソースに限定されます。

### コンソール
コンソールで操作する場合は、IAMのコンソール画面を開き、アセットインベントリから確認することができます。

以下では概要タブを例として載せていますが、リソースタブを見ることで、詳細な分析が可能です。

![スクリーンショット 2023-05-30 20.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/d2d2aefc-c045-ae2d-639d-556d03baf73a.png)

::: note
コンソールから確認する場合は、結果の出力件数が最新でない場合があるため、リソースタブ画面の右上にある「クエリを表示」から、API経由で最新の情報を取得することができます。
:::

### gcloud
CLIで操作したい場合は、[gcloud asset list](https://cloud.google.com/sdk/gcloud/reference/asset/list)コマンドを使用することで、アセットを一覧表示します。

`--project`オプションでプロジェクトをフィルターして使用します。
基本的な使い方については、公式ドキュメントの[アセットの一覧表示](https://cloud.google.com/asset-inventory/docs/listing-assets?hl=ja)から確認できます。

`$ gcloud asset list --project='pj-hoge'`

# おわりに
ガバナンスを実現するために、適切な管理が求められのは言うまでもありません。

適切な管理を行うためには、抽象と具体を的確に捉えて、構造化することが必要です。

従って戦略的に構造化することで、柔軟なポリシーによる制御が可能です。

以上です。

## 参考
- [エンタープライズ企業のベスト プラクティス](https://cloud.google.com/docs/enterprise/best-practices-for-enterprise-organizations?hl=ja)
参照項目のフィルター条件(Lookup Filter )によるエラー

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

Select an option from the picklist or remove the search term

参照項目にフィルター条件があって一致していないんだと思います。

+ [Sean Forbes contact ID issue in Automate your business](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000OsGGV)

:::note
Unfortunately, I also had this problem but I found a workaround (probably cheating, idk please don't hate me)

I do not have Sean Forbes in my contacts. I tried adding him but I am still receiving the same error message. I also tried what @Otsubo Keiji advised and it somehow worked as it now let me select names on the picklist. However, the same error appears whenever I try to save the case and it returns the error "Value does not exist or does not match filter criteria."

So... I modified one of the contacts' names instead and changed it to Sean Forbes, and I also modified the lookup filter settings. I used the newly modified contact on the case and completed all the required information then I had to clear the lookup filter criteria on the case object manager to let me save it. I did the same for the next case and it finally completed my assessment. 

I am not sure if this is a bug or if I missed a module where I need to create Sean Forbes's contact. I'm still stumped because if this is in real life, I basically did not resolve the issue.
:::

#  Could not find required Filter criteria 'Contact Name: Account ID :: equals :: Field :: Case: Account ID'. Check the instructions..

+ [Hi I have an issue with Create a Lookup Filter ,](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PejCBSAZ)

:::note
The issue is, on the Case object "Contact Name" field name doesn't have access to System Administrator profile.
:::

# トレイルヘッド

+ [Error - Contact ID](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PX0Gz)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/67b08577-dd26-49b9-84b6-4fd676f0eeda.png)

:::note
Check to see if there is a Lookup Filter set for the Contact Name field. If there is, disable it. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/711ea479-bc89-4cf2-bfc5-709862fdbf0f.png)
:::


# その他

+ [Lightning ページコンポーネントの表示をフィルタリング](https://qiita.com/Keiji_otsubo/items/a9445dcb3e8d48521599)
Android Studio (Flamingo) でファイル保存時に自動フォーマットする

Settings > Tools > Actions on Save で Reformat codeにチェックを入れれば、ファイル保存時にフォーマットが実行されます。
(他にもimportsの整理などを行なってくれるオプションなどもあります)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94706/0cb4fa1d-5bb8-0b96-1e3a-836c3a8069bb.png)
2023年06月何故かベストアンサーをつけてくれない質問

[2023年6月の質問の中から整理します](https://qiita.com/Keiji_otsubo/items/dd5e02d418a2357e7f47)

# トレイルヘッド

ボットを使った回答にやられた
+ [The field 'Region_Zone__c' either does not exist on the Opportunity object or it is not of formula type Text.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000PlBcHSAV)

# 数式

+ [Validation rules](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Pf4ow)
GKE nodeが予想よりスケールインしない時の調査と対応

ゼロバンク・デザインファクトリー株式会社(ZDF)のSRE張です、kubernetesのスペシャリストとして日々GKEの世話をしています、直近GKEのコスト最適化活動をしていて、出会った問題や経験を共有したいと思い、この記事を書くとこになりました。



# 背景
コスト最適化の一環として検証環境のGKEの[スケジューリングプロファイル](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja#autoscaling_profiles)をOputimize Utilizationモード(積極的にスケールイン)に設定しました。
設定した直後は予想通りNode台数は凡そ10%減りました、設定一つでこれ程の効果を得たのはうれしいです。

数日間Nodeの使用状況を見て一つ問題に気付きました、数台のNodeはリソース(CPUとメモリー)使用率が低いにもかかわらず、スケールインが発動できませんでした。


# 調査
GCPサポートに問い合わせしつつ、oss kubernetes git上の[cluster-autoscaler](https://github.com/kubernetes/autoscaler)ドキュメントを見てました。
親切にスケールインしないときの[トラブルシューティング](https://github.com/kubernetes/autoscaler)が書いてあります。

使用率が低いにもかかわらず、スケールインが発生しない主な理由は以下になります
* ノードグループはすでに最小サイズになってます。
* ノードにはスケールインが無効なannotationが付けられています。
* ノードが不要になった時間は10分未満。
* 過去10分間にスケールアウトがありました。
* 過去3分間にこのグループのスケールインが失敗しました。
* 特定のノードを削除しようとして失敗場合、クラスターオートスケーラーはさらに5 分間待機してから再度削除することを検討します。
* --scale-down-delay-after-deleteまたは--scan-intervalに大きなカスタム値を使用しているとCluster Autoscalerアクションが遅れます。
* --scale-down-enabled が false に設定されています。
* コントローラーがいない、podタイプPodがNode上で稼働されてます。
* kube-system のpodがNode上で稼働し、かつPDB未設定。

結果的にkube-systemのpodがNodeのスケールインを阻害していることが分かりました。

# 対応
kube-system配下のpodはNodeからevictされるとき、可用性に影響するもの(kube-dnsなど)もあり、そのためデフォルトではスケールインしない振る舞いになっています、[PDB(PodDisruptionBudget)]( https://kubernetes.io/docs/concepts/workloads/pods/disruptions/
)を設定することで回避できます。

今回の対象は検証環境なので、PBDを設定し、コストを下げるほうの作業を進めました。

PDBは以下のコマンドで作成する
```
# kube-system配下deploymentとラベル確認
$ kubectl -n kube-system get deploy --show-labels
 
# helpでコマンド形式を確認(必須ではない)
$ kubectl create pdb -h
 
# deploymentの名前とラベルからpdbを作成
$ kubectl -n kube-system create poddisruptionbudget <name> --selector=k8s-app=<app name> --max-unavailable=1
 
# 自信がないときdry runでyamlファイルを出力し、確認してからデプロイ
$ kubectl -n kube-system create poddisruptionbudget <name> --selector=k8s-app=<app name> --max-unavailable=1 --dry-run=client -o yaml > pdb.yaml
$ vim pdb.yaml
$ kubectl apply -f pdb.yaml
 
# 作成されたpdbを確認
$ kubectl -n kube-system describe pdb <name>
 
# 漏れはないかの確認
$ kubectl -n kube-system get deploy
$ kubectl -n kube-system get pdb
 
# nodeスケールインの確認(GCPコンソール上も確認できる)
$ kubectl get nodes
$ kubectl top nodes

```



# まとめ
GKEはマネジードサービスとは言え、kube-system配下のpod PDB設定次第でスケールインが想定より上手くいかないこともあります、今回はPDBを設定し、スケールインがなるべくNodeを節約するOputimize Utilizationモードで動かすことができました。



# 参考資料
* https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja#limitations
* https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#i-have-a-couple-of-nodes-with-low-utilization-but-they-are-not-scaled-down-why
* https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-to-set-pdbs-to-enable-ca-to-move-kube-system-pods
* https://kubernetes.io/docs/concepts/workloads/pods/disruptions/
Master-Detail Relationship



# You cannot create a new Master-Detail relationship on an existing custom object if records already exist. You must first create a Lookup relationship, populate the lookup field with data in all records, and then change the relationship type to Master-Detail.

+ [Cannot Create Master-Detail Relationship](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf2bS)

:::note
To solve the problem and create Contact__c and Property__c fields you need to delete all the records in the object tab fg. Offer Tab. After that you'll able to create those fields. Window with new offer will have contact and property fields.

If you don't want to delete all your offer entries then check that link: https://help.salesforce.com/articleView?id=000005186&type=1

https://developer.salesforce.com/forums/?id=906F00000008ybkIAA
:::

# 各月ごとの金額を管理したいらしい

+ [Formula Field... maybe? Amount dispersed over time period.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QMc5e)

:::note
I don't think you can do it without monthly records as detail objects.
I think there is a way to create detail objects using automated processes such as flows.
:::

# 間違って作成したけど、削除できないらしい

+ [Stuck on Create Object Relationships Challenge](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KAiC2)

レコードページで使っていたら消せない？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b4477c6b-36a2-e0ce-868d-59b13cc3a2c3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/50ef271f-a742-86a1-62dc-1e17ec4ce708.png)
CRM Analytics-Enabled Developer Edition Orgが機能していない

ここ最近何度か見た投稿です。

やはり、この特別版の環境が機能していないようです。

+ [I'm not able to find Analytics Studio in the App Launcher and I need it to complete a challenge .](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jh0Ar)
+ [Sign Up for a CRM Analytics-Enabled Developer Edition Org](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QMwKgSAL)
Terraform で VLAN Only のインスタンスを作成する (Akamai)

Akamai クラウド・コンピューティング・サービス の Virtual LAN (VLAN) を使うと、プライベートネットワークを組むことができます。本記事は Terraform を使って VLAN のみを利用するインスタンスを作成する方法を記載します。VLAN については下記の記事を参照ください。

https://qiita.com/110hideki/items/aead6f2bc9ff1563641c

記事では Cloud Manager を使った例を紹介していますが、今回は Terraform を使った例となります。Linode Provider のページは下記となります。

https://registry.terraform.io/providers/linode/linode/latest/docs



# 前提条件
本記事では前回の記事 ([VLAN を設定する](https://qiita.com/110hideki/items/aead6f2bc9ff1563641c)) で作成した VLAN に対して、新たに 10.0.0.5/24 のインスタンスを作成する例です。

![vlan-diagram-highlight.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/0a7c143f-6a11-82c5-af8f-ae648b42dedd.jpeg)

Linode Provider については、下記の記事も参考にしてください。

https://qiita.com/isss802/items/0b1cef7adf78d858804c

# tf ファイルの設定
以下のサンプルコードを参考にしてください。
https://github.com/110hideki/linode-terraform-sample/tree/main/vlan-only-instance

```
git clone https://github.com/110hideki/linode-terraform-sample.git
```

変数は ``variable.tf`` で定義していますので、自分の環境向けに変更してください。

トークンを環境変数 ``token`` に入れる必要があります。トークンの作成については下記の記事内などを参考にしてください。

https://qiita.com/110hideki/items/91491d684cd794632652#linode-%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%AB%E3%81%8B%E3%82%89%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B

# Cloud Manager の表示
``terraform apply`` を実行すれば数分で新しいインスタンスが作成されます。Cloud Manager では次のように表示されます。
![terraform-vlan-only-instance-config-may14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/c29da3c0-8cf0-726c-04bc-94cdedf4fb91.jpeg)

Network Interfaces には VLAN の ``10.0.0.5/24`` しか見えません。Configurations タブの ``Edit`` を選択した詳細表示でも次のように、``eth0`` に VLAN が割り当てられ、``eth1``、 ``eth2`` にはネットワークが割り当てられていません。

![cloudmanager-config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/45575ccc-52ec-7aff-4655-c03a11cad96a.jpeg)

ルーター経由でログインしたときの ``ifconfig`` の表示でも同様な結果になっています。``eth0`` には Public IP が割り当てられていませんので、インターネットから直接アクセスはできません。
```
root@localhost:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.5  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::92de:ff:fee8:4d12  prefixlen 64  scopeid 0x20<link>
        ether 90:de:00:e8:4d:12  txqueuelen 1000  (Ethernet)
        RX packets 30683  bytes 446726705 (446.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10441  bytes 1040376 (1.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@localhost:~# ifconfig eth1
eth1: error fetching interface information: Device not found
root@localhost:~# ifconfig eth2
eth2: error fetching interface information: Device not found
```

# まとめ
Terraform でも簡単に VLAN only のインスタンスを作成できます。VLAN を使うとプライベートネットワークを構成できるので、セキュアな環境を提供できます。VLAN 内のネットワークの転送は課金されません。また、高速なネットワーク通信も可能となります。

作成したインスタンスから外部に接続するには下記の記事を参考にしてください。

https://qiita.com/110hideki/items/851291f0d33acc577a82

Terraform を使わず、Linode API を使って同様なことをするには下記の記事を参考にしてください。

https://qiita.com/110hideki/items/f68d148444c05b0f48cc
Android Gradle Plugin 8.0に更新したらR8で「ERROR: Missing classes detected while running R8.」が起きた時に…

Android Gradle Plugin 8.0（AGP 8.0）への更新は色々とハマりどころが多い印象です。
そんな中、リリースビルドでR8を有効にした場合にエラーが発生し、解決する方法を調べたのでメモがてら投稿します。

# エラー内容
下記のようなエラーが発生し、リリースビルドが失敗してしまいました。

```text
ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/xxx/yyy/app/build/outputs/mapping/release/missing_rules.txt.
ERROR: R8: Missing class com.facebook.infer.annotation.Nullsafe$Mode (referenced from: com.facebook.ads.NativeAdBase)
...

```

# 原因
これ自体は難読化のルールが不足しているためのものでしたが、AGP 7.0では **警告** だけだったのが、AGP 8.0では **エラー** に変わったからのようでした。

AGP 7.0のリリースノートにちゃんと記載がありました。


https://developer.android.com/studio/past-releases/past-agp-releases/agp-7-0-0-release-notes?hl=ja#r8-missing-class-warning

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/d5af38c9-5855-7a2c-af5d-e9446fbce8c2.png" alt="AGP 7.0 では、クラス欠落メッセージは警告として表示されます。エラーとして表示されるようにするには、gradle.properties で android.r8.failOnMissingClasses = true を設定します。この警告は、AGP 8.0 ではビルドを破壊するエラーになる予定です。-ignorewarnings オプションを proguard-rules.pro ファイルに追加することで AGP 7.0 の動作を維持することは可能ですが、おすすめはしません。" />

# 解消方法
リリースノートに記載があるように `proguard-rules.pro` に **`-ignorewarnings`** を追加するだけでOKです。（ただこれだと、エラーを握り潰しているだけにすぎないので、ちゃんとルールを追加するのがベストでしょう…）

# まとめ
リリースノートはちゃんと見よう。:white_check_mark:
データサイエンスと機械学習の最新トレンドとエンジニアのキャリア

データサイエンスと機械学習は現代のIT業界でますます重要な分野となっています。

この記事では、データサイエンスと機械学習の最新トレンドとエンジニアのキャリア戦略について解説します。
データサイエンスと機械学習の最新技術やアルゴリズム、ツールの紹介や適用事例を交えながら、エンジニアがデータサイエンスや機械学習を活用する際のスキルやキャリア戦略について具体的にアドバイスします。
また、データサイエンスと機械学習がもたらすビジネスチャンスや社会的インパクトについても考察します。

データサイエンスや機械学習に興味のあるエンジニアに向けた情報満載の記事です。

# データサイエンスと機械学習の最新技術
データサイエンスと機械学習は、近年の技術革新の中心的な役割を果たしています。その中でも注目すべき最新の技術やアルゴリズムをいくつか紹介します。

## 1.自動機械学習 (AutoML): 
AutoMLは、機械学習モデルの選択、ハイパーパラメータチューニングなどの一部を自動化するものです。ツールとしては、GoogleのAutoMLやMicrosoftのAzure AutoMLなどがあります。

## 2.トランスフォーマーモデル: 
自然言語処理において、BERTやGPT-3などのトランスフォーマーモデルは大きな影響を与えています。これらは大量のテキストデータから情報を学び取り、質問応答、文章生成、意味理解などを可能にしています。

## 3.強化学習: 
AlphaGoやOpenAI Fiveなどの成功例から、強化学習が機械学習の重要な部門であることが明らかになりました。強化学習は試行錯誤を通じて学習するため、ゲーム理論、ロボット技術、資源最適化などの多岐に渡る問題に対処する能力を持っています。

# データサイエンスや機械学習を活用する際のスキルやキャリア戦略
## 1.基礎スキルの習得: 
データサイエンスと機械学習の基礎的な知識と技術を習得することは、初めの一歩です。PythonやRなどのプログラミング言語、SQLなどのデータベース技術、そして統計学や線形代数などの基礎理論を学ぶことは必須です。

## 2.専門性の追求: 
一旦基礎スキルが身についたら、特定の分野で深く学ぶことをおすすめします。自然言語処理、コンピュータビジョン、強化学習など、あなたが最も興味を持つ分野を選び、それを深く追求しましょう。

## 3.ビジネス視点の理解: 
技術的なスキルだけ技術的なスキルだけではなく、ビジネス視点で問題を理解する能力も重要です。データを用いてビジネス価値を創出することが求められます。

# データサイエンスと機械学習がもたらすビジネスチャンスと社会的インパクト
データサイエンスと機械学習は、数多くのビジネスチャンスを生み出しています。例えば、パーソナライズされた商品推奨、予測メンテナンス、自動運転車など、これらの技術はすでに多くの産業で活用されています。

また、社会的なインパクトも大きいです。医療分野では、疾患の早期発見や治療法の開発を支援するためにデータサイエンスと機械学習が活用されています。環境保護では、気候変動のパターンを理解し、適切な対策を立てるためにこれらの技術が利用されています。

データサイエンスと機械学習のスキルを習得することは、現代社会で求められる重要なスキルであり、個々のキャリア発展だけでなく、社会全体の進歩にも寄与することができます。

# エンジニアとしてデータサイエンスや機械学習のスキルを身につけるためには、以下のような学習戦略を考えることが有効です。

# 1.基本の理論を学ぶ: 
機械学習とデータサイエンスの基礎的な理論を理解することから始めます。これには統計学、確率論、線形代数などが含まれます。この理論的な背景知識は、機械学習のアルゴリズムを理解し、適切なモデルを選択する上で非常に重要です。

# 2.プログラミングスキルを強化する: 
PythonやRのようなデータサイエンスで広く使われている言語をマスターすることが求められます。また、データの操作と解析のためにPandasやNumPy、Scikit-learnといったライブラリにも精通しておくことが有効です。

# 3.実践的なプロジェクトに取り組む: 
理論とスキルを学んだら、それを実践的なプロジェクトに活用します。Kaggleのようなデータサイエンスのコンペティションが良い学習の場となります。具体的な問題に取り組み、データを洗浄し、モデルを構築し、結果を評価するプロセスを通じて、実践的なスキルと経験を積むことができます。

# 4.最新の研究を追う: 
データサイエンスと機械学習は急速に進化する分野であるため、最新の研究をフォローすることも重要です。Arxiv、Google Scholar、NeurIPS、ICML、KDDなどのリソースを活用してください。

# 5.ネットワーキング: 
データサイエンスと機械学習のコミュニティに参加し、他の専門家やエンジニアと交流することも有益です。Meetup、LinkedIn、GitHubなどは、アイデアを共有したり、質問したり、新しいプロジェクトに参加したりするための優れたプラットフォームです。

これらのステップを経ることで、エンジニアとしてデータサイエンスと機械学習の分野で競争力のあるスキルセットを身につけることができます。また、自己学習の能力を持つことは、急速に進化するこの分野で生き残るための鍵となります。

# まとめ
データサイエンスと機械学習の最新技術とキャリア戦略の要点
## 技術とアルゴリズム
### 1. AutoML: 
モデル選択やパラメータチューニングを自動化。
### 2.トランスフォーマーモデル: 
自然言語処理を強化。例: BERT, GPT-3。
### 3.強化学習: 
試行錯誤を通じて学習、広範な問題対応が可能。

## キャリア戦略とスキル
### 1.基礎スキル: 
データサイエンス基本知識、プログラミング（Python、R）、データベース（SQL）、統計学、線形代数。
### 2.専門知識: 
自然言語処理、コンピュータビジョン、強化学習など。
### 3.ビジネス視点: 
データからビジネス価値を創出。

## 学習戦略
### 1.基本理論の習得: 
統計学、確率論、線形代数等。
### 2.プログラミングスキルの強化: 
PythonやR、ライブラリ（Pandas、NumPy、Scikit-learn）。
### 3.実践プロジェクト: 
Kaggleなどのコンペティション参加。

# 最後に
エンジニアの皆さん、エンジニア未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable

Pulumi で GKEのclusterにオブジェクトを作成しようとしてエラーが発生した。
```
invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
```
kubeconfig.yamlをKUBECONFIGに設定すると解決。
（kubeconfigはpulumi.interpolateで記載したk8s Configのファイル）

```
pulumi stack output kubeconfig --show-secrets > kubeconfig.yaml
```
```
export KUBECONFIG=./kubeconfig.yaml
```
exportは同一セッションや子プロセスのみで有効なので注意が必要。
Power AutomateでO365グループをGraph APIから全て抽出する

# 0.Intro
ニーズあると思いますが意外と方法がどこにもまとまとった形で載ってませんでした。もっとスマートな方法ありそうですがひとまず成功した例を提出します。
O365グループ一覧を取得するというアクションもありますがどうも100件までしか抜けないようで(そんなわけないので何かしら設定あると思いますが)。ですので今回はGraph APIで抽出することにしました。Graph APIの結果を全件抽出するはページングが必要です。その方法も今回のポイントです。

# 1.Outline
全体です
![whole_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/461b8b38-86b6-31e9-2604-d64621594464.png)

最初の変数定義
![variables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/91f6f468-ef37-3a00-1082-e83857ffb799.png)

・最終CSVデータ作成用配列変数(JSON_CONTENTS)
・GraphAPI格納用変数(url)
・ループ離脱ブレイク用変数(nextLink)

です。
GraphAPI格納用変数(url)は最初に発行するGraph APIのURLで初期化しています。ポイントはデータを取得する際のJSONのスキーマを揃えるために欲しい情報をselectで絞り込んでおくことです。どうも何も指定しないとスキーマがグループごとに変わるのかエラーが出ました。

その次のDo untilです。
![do_until.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/81e44729-64a4-80df-da0d-e9b913bded37.png)
まずGraph APIを叩き、その結果を取得します。ここでは取得したいのは結果の外側のみです。具体的にはJSONの解析のスキーマは以下です。

```
{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "@@odata.nextLink": {
            "type": "string"
        },
        "value": {
            "type": "array"
        }
    }
}
```
肝要なのは次ページを取得する為の @@odata.nextLink と実データのvalue です。
次の Apply to eachでvalueの中身を取得していきます。
![apply_to_each.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/b26fff57-6520-eb8c-fd69-71be83b6c0c5.png)
valueの中身のそれぞれに対してJSONの解析を適用して中身を分解し取得します。JSONの解析のスキーマは先程指定した項目のみです。今回は
```
{
    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        },
        "displayName": {
            "type": "string"
        },
        "mail": {
            "type": [
                "string",
                "null"
            ]
        }
    }
}
```
としています。mailは空のものがありエラーとなったのでnullを許容するようにしています。
こちらのサイトを参考にしました。
[Power Automate で null の動作を確認する](https://rksoftware.hatenablog.com/entry/2022/09/02/190000)
ただnullを許容するこちらの書き方をすると｢動的なコンテンツ｣に出なくなったのでまずフローの次の項目に値をセットしてからスキーマを上記に書き換えると良いようです。
取得した中身は最終CSVデータ作成用配列変数(JSON_CONTENTS)に配列の形でAppendしていきます。

発行したGraph APIからのデータを全件取得したらページングの有無確認です。
![do_until.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/ef80dbd8-9dd3-d25c-862d-b3f2fd9f9a6a.png)
条件の箇所は　@@odata.nextLink　が空かどうかの判定をしています。
空でなかったら　@@odata.nextLink　をurlに次回発行するurlを格納、ブレイクしないようにループ離脱ブレイク用変数(nextLink)はfalseを設定。
@@odata.nextLinkがからの場合は次ページが存在しないので　ループ離脱ブレイク用変数(nextLink)　をtrueに設定しループを終えます。

ループの外は出力部分です。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/1a4896bb-8463-d9eb-9ace-db1dfbe55ce6.png)
CSVテーブルの生成に取得した情報を格納した配列をそのまま与えます。これでCSVに変換してくれます。
ファイル名を時間にしたかったので時間を文字列へ編集。
OneDriveにファイルを生成、ファイル名は時間を編集した文字列、ファイルの中身は先程作成したCSVです。

# 2.終わり
無事目的とするCSVを生成することが出来ました。
今回はO365グループを抽出していますが、今回の内容をテンプレにすればGetするGraph APIどれでも叩けるかと思います。
秋月電子の通販で買い物かごロスト事故を防ぐウェブアプリを作った

皆さんは [秋月電子通商](https://akizukidenshi.com) を利用してますか？
僕は通販も八潮店もバチクソお世話になっています。

10年ほど前まではマイコンやロジックICなどデジタル系がメインな感じでしたが、最近はアナログICや受動部品も豊富で、日本の電子工作シーンにおいては割と有名な電子部品屋かと思います。

秋月に無ければ後はもうMouserかDigi-Keyか、というくらい、ここ数年で品揃えが増えた感じがします。
(お金は貰ってないですよ!)

# 48時間
このように便利な秋月ですが、通販を利用したことがある人の中には、もしかすると悲しい出来事が起きてしまった人もいらっしゃるのではないでしょうか。

**買い物かごロスト**

欲しい部品を買い物かごに入れて、後日決済しようと思い数日後に開いたら...買い物かごはまっさら。

そう、秋月通販はCookieが **48時間で失効** してしまうのです。

セキュリティの関係でログインセッションのライフタイムを制限するのは理解できますが、どうして買い物かごまで...

# 商品コードを抽出
それは流石に無慈悲すぎると思い、買い物かごページから商品コードを抽出するウェブアプリを作りました。

- https://dojyorin.github.io/akizuki-cart

秋月通販は、複数の商品コードをテキストで一括入力して買い物かごへ放り込める機能があります。

- https://akizukidenshi.com/catalog/quickorder/blanketorder.aspx

その際のテキストフォーマットは以下となります。

```text
(商品コード)(半角スペース)(個数)(改行)
```
ウェブアプリは、買い物かごページのテキストから商品コードと個数を正規表現で抽出し、一括入力フォーマットへ変換します。

また、商品名や金額も取得できるので、より完全な買い物かごの中身をJSON形式で出力する機能も試験的に実装しました。

後はSNSの自分宛DMに保存するも良し、テキストとしてローカルに保存するも良し、買い物かごを復元するのはコピペで済みます。

# 免責とか
秘密裏に開発中のプロトタイプの購入部品リストが漏れた、とかなっても責任は負えません。
公式から何らかのお咎めがあった場合は予告なく閉鎖します。

# 技術的な部分
特に凝った事はしていませんが、今回は小規模なのでフレームワークは使わずにSPA風なUIを自作してみました。

とても便利だと感じたのは、最近のCSSで実装された [動的ビューポート指定](https://caniuse.com/viewport-unit-variants) でした。
単位は `dvh` と `dvw` で、特にスマートフォンでスクロールした時にアドレスバーが見え隠れしても動的に必ず正しい割合を算出してくれます。

~~毒林檎~~iPhone対応が必要なプロジェクトには待ちに待った朗報ではないでしょうか。
~~かくいう僕も過去に高さ100%のiPhone対応で無限に苦しめられましたからね、いい加減WebKit縛りやめたらどうですかねAppleさん今時くだらない囲い込みは流行らないですよ~~

おっといけませんわｵﾎﾎ...

他にも地味な部分ですが、いちいち入力フォームにコピーしたりペーストするのは面倒なので [Clipboard API](https://developer.mozilla.org/docs/Web/API/Clipboard_API) を使いクリップボードの中身を直接操作できる仕組になっています。

初回のみパーミッションのプロンプトが出ますが、次回以降は記憶されるので、特に問題はありません。

今後の改善としては、外部に保存せずとも [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) に保存できるようにしても良いかな、とか考えています。
機密情報ではないし LocalStorage に突っ込んでも大丈夫でしょう...

# ギャラリー
![Screenshot_20230601-142404_Chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253070/21010eff-6eda-d03f-70f4-1578c3e6cec0.jpeg)
![Screenshot_20230601-142415_Chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253070/eeb63c9a-896f-44e5-40d4-f5df86b8ca65.jpeg)
【npm】package.jsonのバージョンの指定方法【yarn】

## 特定のバージョンを指定
`1.2.3`のように記述するとバージョン1.2.3で固定できます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "1.2.3"
  }
}
```

## 指定バージョンより最新

`>1.2.3`のように記述するとバージョン1.2.3よりも大きいバージョンの内、最新のものがインストールされます。
上記の場合にバージョン2.0.0が出た場合には2.0.0にアップグレードされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": ">1.2.3"
  }
}
```

## 指定したバージョン以上の最新
`>=1.2.3`のように記述すると、バージョン1.2.3以上のバージョンで最新のものがインストールされます。
上記の場合にバージョン2.0.0が出た場合には2.0.0にアップグレードされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": ">=1.2.3"
  }
}
```

## 指定したバージョン未満の最新
`<1.2.3`のように記述すると、バージョン1.2.3未満で最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "<1.2.3"
  }
}
```

## 指定したバージョン以下の最新
`<=1.2.3`のように記述すると、バージョン1.2.3以下の最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "<=1.2.3"
  }
}
```

## バグ修正のみ取り込む

`~1.2.3`のように記述すると、バージョン1.2.3のパッチバージョンが最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "~1.2.3"
  }
}
```


## 指定したメジャーバージョンの最新

`^1.2.3`のように記述すると、バージョン1.2.3以上でメジャーバージョンが1の最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "^1.2.3"
  }
}
```

## 一部をワイルドカードで指定

`1.2.x`のように記述すると、バージョン1.2の中でパッチバージョンが最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "1.2.x"
  }
}
```

## 最新バージョン
`*`を記述するかバージョンを指定しないと、最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "*".
    "example": ""
  }
}
```

## 範囲指定

`1.2.3 - 2.0.0`のように記述すると、指定されたバージョンの範囲で最新のバージョンがインストールされます。

```json:package.json
{
  "name": "sample-app",
  "dependencies": {
    "sample": "1.2.3 - 2.0.0"
  }
}
```
ST7735(パラレル)を基板化したい。2(部品一覧)((続く)未完了プロジェクト?)


●30Pは、切て使う事。

ピンヘッダ　２×４０　（８０Ｐ）
[PH-2x40SG]
通販コード　C-00082
発売日　2002/05/31

[o_cop579.jpg]

![o_cop579.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/34ecaf3b-123b-a9fb-7982-7035682ff527.jpeg)



ピンソケット　１×６　（　６Ｐ）　リード長１０ｍｍ
[FH105-1x6SG/RH]
通販コード　C-04045
発売日　2010/07/29

[o_cop580.jpg]

![o_cop580.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/805ee721-0c5a-2a76-ada2-03f8b66c5e9d.jpeg)



ピンソケット　１×８　（　８Ｐ）　リード長１０ｍｍ
[FH105-1x8SG/RH]
通販コード　C-04046
発売日　2010/07/29

[o_cop582.jpg]

![o_cop582.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a690c8a4-c4f3-409c-c525-7bf203a79e3b.jpeg)



チップ抵抗　１／４Ｗ７５Ω　（２５個入）
[RK73B2BTTD750J]
通販コード　R-08639
発売日　2014/11/11

[o_cop581.jpg]

![o_cop581.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5d3a1ccd-9ba9-1660-030a-cb46f6aa8244.jpeg)

------------------------------------------

LCD

[o_cop583.jpg]

![o_cop583.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9a56e45e-d8e8-d4f3-367e-6b4eaf2f8e37.jpeg)

[o_cop584.jpg]

![o_cop584.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2a4153e8-8d80-73a7-b6be-4664ca21384b.jpeg)

[o_cop585.jpg]

![o_cop585.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a9236bd5-3b82-f78c-f5ac-5e5d6d15883d.jpeg)

[o_cop586.jpg]

![o_cop586.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/16caa8d0-e7aa-25c8-b7d5-66b2ba820323.jpeg)

[o_cop587.jpg]

![o_cop587.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0e82adba-efde-a944-fef3-bdc2b96c64ab.jpeg)
Wordpress.comでグーグルアナリティクスを設定する方法

# 前提条件
* https://wordpress.com/
* グーグルアナリティクス

# 目的
wordpress.comのワードプレスでグーグルアナリティクスを設定する。

# wordpress.comでのグーグルアナリティクス設定方法
管理画面→ツール→トラフィック→Google アナリティクス→Google を追加のクリック→Google アナリティクスの測定 ID→グーグルアナリティクスの測定IDの入力→設定を保存

![wordpressグーグルアナリティクス設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32439/51c069a2-4bcb-39ad-70df-b3fd34a982be.png)

# 編集後記
いつもwordpress.comのワードプレスでグーグルアナリティクスの設定を失念するため、備忘録として本稿を書いた。
Github Actionsのシェルの処理が途中で失敗しても処理が中断されないようにする

# はじめに
Github Actionsのシェル部分（ `run` セクション）でコマンドの成功、失敗によって処理を分けたかったのですが、上手くいかなかったのでその対策を残します。

ここでは例として、 `test_command` のステータスコードを見て、失敗してたら（ステータスコードが0じゃなかったら） `when_failed` コマンドを実行したいとします。

```yaml
      run: |
        test_command
        if [ $? -ne 0 ] ; then
          when_failed
        fi
```

しかし、上記のコードは意図通りに動きません。
`test_command` が失敗した段階でifの分岐に入る前に、以下のようなエラーメッセージが出て処理が終了してしまいます。

```
Error: Process completed with exit code 1.
```

# 原因
実行ログを見てみると、以下の部分が怪しそうです。

```
shell: /usr/bin/bash -e {0}
```

manコマンドでbashの `e` オプションを調べてみます。

> -e
Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status.  The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a && or ⎪⎪ list, or if the command's return value is being inverted via !.  A trap on ERR, if set, is executed before the shell exits.

なるほど、この `e` オプションによって、コマンドが失敗している時点で処理が中断されているようです。

# 解決策
原因パートの書式を真似て、yamlに `shell` のセクションを `e` オプションを抜いて呼び出すようにしてみます。

```yaml
      shell: /usr/bin/bash {0}
      run: |
        test_command
        if [ $? -ne 0 ] ; then
          when_failed
        fi
```

無事、 `test_command` が失敗した際に `when_failed` が呼ばれるようになりました！


# 別の方法

上記の `e` オプションの説明にあるように、ifの条件式の中ではコマンドが失敗しても処理が中断されません。
なので、以下のようにifの条件式の中に直接記述してもいけます。

```yaml
      run: |
        if test_command; then
          when_failed
        fi
```
node-sassでエラーが出る

### 事象
yarn startコマンドを実行すると、エラーが出てアプリが起動しませんでした。
エラー内容メモし忘れました。。。（エラー内容に https://github.com/sass/node-sass/releases/tag/v6.0.1 が入ってた）

### 環境
```
node v17.3.1
```

### 原因
各OSに対応するnodeのバージョンがあり、自分のPCのnodeは対応バージョン以降のバージョンを使用していた為、このようなエラーが発生していました。
https://github.com/sass/node-sass/releases/tag/v6.0.1


#### nodebrewのインストール
① nodebrewをインストールします。
```shell
brew install nodebrew
```
② インストールできたら、ダウンロード可能なバージョンの確認。
```shell
nodebrew ls-remote
```
③ node-sassが対応している指定のバージョンをインストールする。
```shell
nodebrew install-binary　指定のバージョン
```
④ nodebrewで使用可能なバージョンを確認
```shell
nodebrew ls
```
⑤ 使用したいバージョンに変更する
```shell
nodebrew use 使用したいバージョン
```
⑥ バージョンが変わったか確認
```shell
node -v
```

:::note warn 
バージョンを変更したにも関わらず、node -vをしてもバージョンが変わってくれない事象が起きました。
---
**【解決方法】**
zshでnodebrewのパスを通す。
```shell
// ファイルを開く
vim ~/.zshrc
```
```shell :.zshrs
// 下記をファイルに追記（追記後、escキー押して :wq で閉じる
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
```shell
// 修正を反映
source ~/.zshrc
```
```shell
// 変更の確認
node -v
```
:::


### 合わせて読みたい
https://qiita.com/yn01/items/d1fa10dbe4850f7cd693

https://blog.proglus.jp/5864/