OmniAICreator/Qiita-1.07M huggingface dataset:
FFTして周波数特性をプロットしてみる

# はじめに

最適化問題で、制約条件のもとでノルムを最小にする解を求めたいことがよくあります。そのとき、単純にノルムではなく微分したノルムを最小化することもあります。何故微分をするのか、というと、「滑らか」な解を求めたいからです。

- 微分フィルタは高周波を強調した信号になる
- 高周波を強調した信号のノルムを最小化する
- よって低周波が強調された「滑らかな」信号が求められる

で、どれくらいの拘束なのかなー、ということで、FFTしてパワーを見てみました。

# 内容

ある信号$x[n]$ に対して、フィルタ$h[n]$ を畳み込みます。

numpy の fft についてこちらに仕様が書かれています。

https://numpy.org/doc/stable/reference/routines.fft.html#

FFTして絶対値をとって、逆数を計算してみました。ただそれだけです。

```python
import matplotlib.pyplot as plt
import numpy as np

N = 32
h = np.zeros(N)
h[0:2] = [1.0, -1.0]

h_steps = np.arange(N)
h_sp = np.fft.fft(h)

fig = plt.figure(figsize=(12, 6), layout='constrained')
fig.suptitle(f"Filter Gain (N={N})")
axs = fig.subplot_mosaic([["filter", "magnitude", "inv_mag"]])

axs["filter"].set_title(r"Filter $a[i]$")
axs["filter"].stem(h_steps[0:N+1], h[0:N+1])
axs["filter"].set_xlabel(r"$i$")
axs["filter"].set_ylim([-1.1, 1.1])
axs["filter"].grid(True)

axs["magnitude"].set_title(r"$|A[k]|^2$")
axs["magnitude"].plot(np.absolute(h_sp)[0:N//2+1], "o", markersize=5)
axs["magnitude"].grid(True)
axs["magnitude"].set_xlabel(r"$k$")
axs["magnitude"].set_xticks([0, (N//2)//2, N//2])
axs["magnitude"].set_xticklabels([f"{i}" for i in [0, (N//2)//2, N//2]])

axs["inv_mag"].set_title(r"$\frac{1}{|A[k]|^2}$")
axs["inv_mag"].plot([i for i in range(1,N//2+1)], 1.0/np.absolute(h_sp)[1:N//2+1], "o", markersize=5)
axs["inv_mag"].grid(True)
axs["inv_mag"].set_xlabel(r"$k$")
axs["inv_mag"].set_xticks([0, (N//2)//2, N//2])
axs["inv_mag"].set_xticklabels([f"{i}" for i in [0, (N//2)//2, N//2]])
```

差分、ラブラシアンをそれぞれプロットしてみました。
周波数領域で$k=0$のとき$A[k]=0$なので、逆数をとったら発散しますね。こういうのを確か極って言うんだよね。

フィルタの形は、プロットをみればわかると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/06e3fae4-fbfe-43dd-647d-07f62f8065f5.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/ab1900d1-12f8-b4e4-b337-4a9b423a7529.png)



# まとめ

FFTしてみた。紙と鉛筆で計算したら、もう少し理論的なことを言えるかもしれないけれど、とりあえず実験的にプロットしてみたのでメモしました。

おれは何をしているのだろう。。。
(2024/2/4)

捕捉: matplotlib で便利な関数が用意されているので、それを使うのがよいかも。
https://matplotlib.org/stable/gallery/lines_bars_and_markers/spectrum_demo.html
ドメイン駆動開発（DDD）の原則のさわりを理解する。

参考にした記事

https://qiita.com/hats_yaki/items/b61d240281b89a982d53

https://speakerdeck.com/minodriven/kusokododong-hua-userkurasu-dekao-eruji-shu-de-fu-zhai-jie-xiao-falseguan-dian

https://speakerdeck.com/minodriven/huge-model-vs-bc

上の記事見たほうが断然理解できます。
下記は私なりにDDDに従った良いコード設計とBADコード設計をよくある
簡単な例で比較してみて自分なりに理解しようと実践したものです。
攻撃者が敵に攻撃するやつを例に考えてみる。

![2024-02-04_20h08_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655530/d7e7bdea-1482-7b17-daea-2825dcd6bd44.png)

### まずBADコード共通設計の例

```javascript
class Character {
  constructor(name, hp, specialAbility, damage) {
    this.name = name;
    this.hp = hp; // HPもいれてしまう
    this.specialAbility = specialAbility; // 特殊能力も攻撃者と被攻撃者で共通にしてしまう
    this.damage = damage; // ダメージも共通にしてしまう
  }

  attack(target) {
    console.log(`${this.name}が${target.name}に攻撃する！`);
    target.hp -= this.damage; // ダメージ処理がここに含まれている
    if (target.hp <= 0) {
      console.log(`${target.name}は倒れた...`);
    }
  }

  useSpecialAbility() {
    console.log(`${this.name}が特殊能力「${this.specialAbility}」を使用した！`);
  }
}
```

攻撃者と被攻撃者の区別がなく、すべてキャラクターとして定義して`Character`クラスで作っている。攻撃する/されるだけのシナリオでは最初はこれでよかったんですが、今後特殊能力を入れて威力をパワーアップさせたり、相手のHPを持たせてダメージを表示させるといった仕様追加が増えていくと、特殊能力やダメージ処理などがすべてのキャラクターに適用されてしまい、攻撃する側はnot difineとなってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655530/48c04c21-22f3-4411-9d29-585c42d67074.png)


### 良いコード設計の例（DDDを意識した適用）

DDDを適用した良いコード設計では、ドメインの概念を正確にモデル化し、クラスが適切な責務を持ち、ビジネスロジックが整理されています。ここでいうドメイン（影響、活動の範囲）は攻撃するということ。

```javascript
// 攻撃者クラス（攻撃する人の活動範囲、影響力を限定する）
class Attacker {
  constructor(name, specialAbility) {
    this.name = name;
    this.specialAbility = specialAbility; // 特殊能力は攻撃者にのみ存在
  }

  attack(technique, target) {
    console.log(`${this.name}が${technique.name}で${target.name}に攻撃する！`);
    target.takeDamage(technique.damage);
  }
//・・・・

}

// 被攻撃者クラス（攻撃される側の活動範囲、影響力を限定する）
class Defender {
  constructor(name, hp) {
    this.name = name;
    this.hp = hp;
  }

  takeDamage(damage) {
    this.hp -= damage;
    console.log(`${this.name}は${damage}のダメージを受けた！ 残りHP: ${this.hp}`);
    if (this.hp <= 0) {
      this.die();
    }
  }

  die() {
    console.log(`${this.name}は倒れた...`);
  }
}

// 技クラス
class Technique {
  constructor(name, damage) {
    this.name = name;
    this.damage = damage;
  }
}
```

この設計では、`Attacker`、`Defender`、`Technique`というクラスがドメインの概念を反映するようにした。それぞれのクラスが持つべき責務に集中している。攻撃処理やダメージ処理、特殊能力の使用といったビジネスロジックが適切な場所に配置されており、システムの変更や拡張が容易になる。
LWC：Write different type of icon-name

**different type of icon-name in LWC**
```php:html
<template>
    <p>Utility Icons</p>
    <lightning-card title="close" icon-name = "utility:close">
    </lightning-card>
    <lightning-card title="chevronright" icon-name = "utility:chevronright">
    </lightning-card>
    <p>Doctype Icons</p>
    <lightning-card title="ai" icon-name = "doctype:ai">
    </lightning-card>
    <lightning-card title="link" icon-name = "doctype:link">
    </lightning-card>
    <p>Standard Icon</p>
    <lightning-card title="account" icon-name = "standard:account">
    </lightning-card>
    <lightning-card title="action_list_component" icon-name = "standard:action_list_component">
    </lightning-card>
    <p>Custom Icon</p>
    <lightning-card title="custom1" icon-name = "custom:custom1">
    </lightning-card>
    <lightning-card title="custom2" icon-name = "custom:custom2">
    </lightning-card>
</template>
```
その結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330192/74a70d2b-d488-f286-18c6-b2da570bf771.png)

もっとたくさんの画像を書きのURLを参照してください。
公式参考URL：
https://www.lightningdesignsystem.com/icons/#doctype
/lib/

firefox, gimp, java,kernelなど入ってる。
windowsでいうところProgram files？
と思ったけど、https://qiita.com/nys9302/items/a8ddeedd3cd9d0deb332見ると
/opt/が追加アプリケーション。
/lib/は共有ライブラリ。
具体例がないと分かりにくい。
![Screenshot from 2024-02-04 20-37-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031554/e614e7aa-4b95-68ea-189d-5f49ec34bf9d.png)
GENERAL PATTERN EDITOR patterneditor.py

自由サイズの汎用2値画面パターンエディタです。

patterneditor.pyは実行ファイルです。

0 0 1 1 1 0 0 0
0 1 1 0 1 1 0 0
1 1 0 0 0 1 1 0
1 1 0 0 0 1 1 0
1 1 1 1 1 1 1 0
1 1 0 0 0 1 1 0
1 1 0 0 0 1 1 0
0 0 0 0 0 0 0 0

のような0 と 1からなるテキストファイルを生成します。
import numpy as np
F = np.loadtxt(a)
として、numpyでファイルを読み込み、2次元のリストにすることができます。

'l'で   画面の幅、高さをファイルの要素数に合わせ、ファイルからパターンをロード
        します。
's'で   現在の画面をファイルにセーブします。
'z'で   現在の画面の幅と高さの要素数を設定します。
'c'で   現在の画面をクリアします。
'q'で   終了です。
画面のセルをマウスでクリックしたら、On/Offします。最初の画面の要素数は8x8です。

```patterneditor.py
#!/usr/bin/python3
from pygame.locals import *
from scipy import signal
import pygame
import sys
import numpy as np
import os
import binascii

width=8
height=8
scale=16

def draw_grid(screen):
  screen.fill((0,0,0))
  for i in range(width):
    pygame.draw.line(screen,(0,255,0),(i*scale,0),(i*scale,scale*height),1)
  for i in range(height):
    pygame.draw.line(screen,(0,255,0),(0,i*scale),(scale*width,i*scale),1)

def set(screen,cx,cy,c):
  screen.fill((c*255,c*255,c*255),(cx*scale+1,cy*scale+1,scale-1,scale-1))

def put(F,screen):
  for i in range(len(F)):
    for j in range(len(F[1])):
       set(screen,j,i,F[i][j])

def rev(F,cx,cy):
  F[cy][cx]=int(F[cy][cx])^1
  return(F)

def clear():
    return(np.zeros((height,width)))

def setscr():
    pygame.quit()
    pygame.init()    # Pygameを初期化
    screen = pygame.display.set_mode((scale*width,scale*height))   # 画面を作成
    s=str(width)+"x"+str(height)+" pattern editor"
    pygame.display.set_caption(s)    # タイトルを作成
    draw_grid(screen)
    return screen

def eventloop(F,screen):
    global width,height
    run='e'
    while run!='q':
        for event in pygame.event.get():
            if event.type == QUIT:
                run='q'
            if event.type == KEYDOWN:  # キーを押したとき
                k=pygame.key.name(event.key)
                if k== 'q':
                    run='q'
                elif k=='z':
                    width=int(input("Input width:"))
                    height=int(input("Input height:"))
                    screen=setscr()
                    F=clear()
                elif k=='l':
                    a=input("Filename:")
                    if os.path.exists(a):
                        F = np.loadtxt(a)
                        height=len(F)
                        width=len(F[0])
                        screen=setscr()
                        put(F,screen)
                elif k=='s':
                    a=input("Filename:")
                    print(np.savetxt(a, F, "%d"))
                elif k=='c':
                    F=clear()
                    put(F,screen)
            elif event.type == MOUSEBUTTONDOWN:
                    x, y = event.pos
                    F=rev(F,x//scale,y//scale)
                    put(F,screen)
            elif event.type == MOUSEMOTION:
                    x, y = event.pos
        pygame.display.update()

def main():
    screen=setscr()
    F=clear()
    put(F,screen)
    eventloop(F,screen)
    pygame.quit()
    sys.exit()

if __name__=='__main__':
    main()
```
【MyBatis Generator】RowBoundsPluginは使うべきではない

【MyBatis Generator】RowBoundsPluginは性能的に問題があるため使うべきではないという話。

generatorConfig.xmlに
```xml
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />
```
を定義すると、マッパークラスにselectByExampleWithRowbounds()メソッドが生成される。
オフセットとリミット指定が可能になるものである。

以下例：
```java
var commentExample = new CommentsExample(){{
    setOrderByClause("comment_id desc");
}};
var rowBounds = new RowBounds(0, 100);
try{
    var latestCommentInfo = commentsMapper.selectByExampleWithRowbounds(commentExample, rowBounds);
}
```

----
**が、、、クエリログを確認すると、発行されるクエリ自体にはオフセット、リミット指定がされていない。**
**つまり、テーブルから全レコード取得した上で、Java側で絞込みを行っている。**
そのため基本的にレコード数が多いほど性能面で著しい支障が発生してくる。

Rowboundsの使用は避け、setOrderByClause()にオフセット、リミット指定も混ぜ込むべきである。

以下例：
```java
var commentExample = new CommentsExample(){{
    setOrderByClause("comment_id desc limit 100");
}};
try{
    var latestCommentInfo = commentsMapper.selectByExample(commentExample);
}
```
CloudSQL QueryInsightsで快適にパフォーマンス最適化できた

# はじめに
最近プロジェクトで、CloudSQLのパフォーマンス問題が発生しました。その時の調査として、特定のクエリに原因がないかを見るためにQueryInsights機能を利用しました。
結果的に、パフォーマンス最適化のためにこの機能がとても役立ったので、本記事にQueryInsightsの概要をまとめてみました。

**個人的には、CloudSQLインスタンスを作成するなら、よっぽどの理由がない限りQuery Insightsも有効化しておいて良いと思います。（コストも低いのと、問題発生後に有効化しても問題時の分析情報を見ることができないため）**

# Query Insightsについて
## 概要
Query Insightsは、CloudSQLの機能の1つという位置付けです。（[Cloud Spannerでも利用可能](https://cloud.google.com/spanner/docs/using-query-insights?hl=ja#dashboard)）
機能有効化するだけで、負荷の高いクエリの順位づけ・色々なメトリクスの取得など様々な分析を行ってくれます。
運用中のDBインスタンスに対するクエリ実行状況をかなりいい感じに可視化してくれて、パフォーマンスチューニングの強い味方になります。

## 良いと思った点（コスト観点）
**有効化することによるリスクが非常に低いのが魅力的だと思いました。**
- CloudSQLインスタンス単位で有効化できる → 対象を絞ってコスト最適化可能
- QueryInsights機能自体にコストは発生しない。CloudSQLディスクを消費することもない
- 有効化後、無効化すること可能（[参考](https://cloud.google.com/sql/docs/mysql/using-query-insights?hl=ja&_ga=2.219202201.-188393044.1707012382#disable-insights)）

## 留意点
- 見られるデータは直近1週間分のみ
- Cloud Monitoringの料金が発生する（指標はCloudMonitoringにより取得されるため）
    - 自プロジェクトでの実績としては、0.1ドル/日程度でかなり低いようでした。ただしクエリの回数が増えると徐々に料金も増加するものと思われます。

> 指標は Cloud Monitoring に保存されます。API リクエストについては、Cloud Monitoring の料金をご覧ください。

https://cloud.google.com/sql/docs/postgres/using-query-insights?hl=ja&_ga=2.42420581.-152254931.1707012225#pricing

# 有効化の手順
本当に簡単です。
CloudSQLの対象インスタンス詳細画面→`Query Insights`→`有効にする`だけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577028/7bd37b20-e04e-c053-f981-b108a5a7114a.png)

3分程度で有効化され、QueryInsightsの画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577028/cad3802c-c3c4-6419-1d73-9e01a9685d93.png)



# 得られる情報

## 全体画面
QueryInsightsの全体画面では、以下情報が見られます。（[ドキュメントはこちら](https://cloud.google.com/sql/docs/mysql/using-query-insights?hl=ja#using-db-load-graph)）

- データベース負荷推移
- DB負荷が上位のクエリと、その概要
- クエリ実行先DBや実行元DBユーザによりフィルタリングすることも可能

↓例として、現在のプロジェクトはこのような表示となりました。（クエリ文はマスク）
見て一発で分かりますが、一番上のクエリのスキャン行数が異常に多く絞り込みができていないことが原因で、DB負荷を著しく上げていることが判明しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577028/c77403e0-7722-4730-2cd6-f88d6e6357f9.png)


## クエリごとの詳細画面
各クエリの詳細画面では、以下情報が見られます。（[ドキュメントはこちら](https://cloud.google.com/sql/docs/mysql/using-query-insights?hl=ja&_ga=2.177236773.-188393044.1707012382#specific-query)）
- クエリ文
- 実行先DB
- 実行元DBユーザ
- 特定の時間内でのそのクエリの指標
    - 呼び出された回数
    - 平均実行時間
    - 平均スキャン行数
    - 返された平均行数
- クエリのレイテンシ推移
    - 95 / 90 / 50 パーセンタイルいずれも見れる
- データベースへの負荷推移
- クエリプラン

↓ドキュメントより
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577028/8fefc643-762d-4c5e-bda3-b686f56deff4.png)


## その他
QueryInsightsでオプションを有効化することで、以下のような情報も追加で設定できます。
運用に応じて適宜有効化すると良いです。
- クライアントIPアドレスによるフィルタリング
- アプリケーションタグによるフィルタリング
- QueryInsights画面で見れるクエリ文の長さ制限変更（デフォルトは1024バイト）
- 最大サンプリングレートの変更


# 最後に
　調査当初は「インスタンスのスケールアップで対策するしかないな」と考えていました。
 しかしながらQueryInsightを利用することで、効率的に負荷原因となるクエリを特定でき、インスタンスのコスト増を避け根本的なクエリ側の改善によりパフォーマンス改善を達成できました。
（またCloudSQLはHA構成もスケールアップ時にダウンタイムが発生するため、それを避けられた点でも良かったです。）



# 参考
- https://cloud.google.com/sql/docs/postgres/using-query-insights?hl=ja
/bin/,/sbin/,/usr/bin/,/usr/sbin/

## /bin/
システム起動に必要なコマンド
## /usr/bin/
システム起動に必要されないコマンド

```
[linuxstudy@xxxx ~]$ which -a cat
/usr/bin/cat
/bin/cat
[linuxstudy@xxxx ~]$ which -a bash
/usr/bin/bash
/bin/bash
[linuxstudy@xxxx ~]$ which -a ls
alias ls='ls --color=auto'
	/usr/bin/ls
	/bin/ls
[linuxstudy@xxxx ~]$ which gnome-calculator 
/usr/bin/gnome-calculator
[linuxstudy@xxxx ~]$ which -a echo
/usr/bin/echo
/bin/echo
```
## /sbin/
システム起動に使用するシステム管理者が使うコマンド
## /usr/sbin/
システム起動に使用しないシステム管理者が使うコマンド
```
[linuxstudy@xxxx ~]$ which -a e2fsck
/usr/sbin/e2fsck
/sbin/e2fsck
[linuxstudy@xxxx ~]$ which -a crond
/usr/sbin/crond
/sbin/crond
```
自分が導入した環境
/bin/と/usr/bin/は同じものが入っているようだ。
/sbin/と/usr/sbin/も同じ
```
[linuxstudy@xxxx ~]$ ls /bin/ | wc -l
1762
[linuxstudy@xxxx ~]$ ls /usr/bin/ | wc -l
1762
[linuxstudy@xxxx ~]$ ls /usr/sbin/ | wc -l
658
[linuxstudy@xxxx ~]$ ls /sbin/ | wc -l
658
```
## /usr/local/bin/
Linux導入後に個別にインストールしたコマンド
## /usr/local/sbin/
Linux導入後に個別にインストールしたコマンド。システム管理者が使用する。

自分が使用している環境は個別にインストールしていないので何も入っていない。のかな。
```
[linuxstudy@xxxx ~]$ ls /usr/local/bin/
[linuxstudy@xxxx ~]$ ls /usr/local/sbin/
```
Salesforce画面フローで入力制限をかけよう～分かりやすい入力制限で入力をサポート～

今回はSalesforceのフロー「画面フロー」で入力制限をかける方法を解説します


今回の画面フローは以下のような「取引先作成画面」の作成を想定します

https://qiita.com/Takaa/items/9930f392c604cfdf2367

https://qiita.com/Takaa/items/dd2d9dd4842ca6d7c602

こちらの画面フローについて「取引先名（会社名）に「株式会社」が含まれない場合にエラー」という入力制限を作成します


## 前提　Salesforceの入力規則について

Salesforceで入力制限をかける方法の１つが入力規則の作成です

入力規則の詳細はこちらです

https://qiita.com/Takaa/items/6bc57c8b58f18bffbc5e


例えば今回の場合、入力規則で以下の数式を作成します

>CONTAINS(Name, "株式会社" ) = false

![取引先q.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9c4843cd-e6dc-c3bc-7a99-593631bbd702.png)


この場合、通常の取引先レコード新規作成時には「株式会社」が取引先名に記載がないとエラーが発生します

![株式会社２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4172101e-c185-500d-192d-52b42e20747b.png)

レコード作成画面上ですと入力規則のエラーメッセージの表示がされているので「株式会社を入れないと」と分かりやすいですね。

しかしながら、入力規則の設定のまま画面フローで取引先を作成しようとするとこのようなエラーになってしまいます


>このフローで未対応の障害が発生しました
フローを処理中に未対応の障害が発生しました。詳細は、組織のシステム管理者にお問い合わせください。

![フロー０１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7a03a283-9764-f3b5-c168-f072ec1ef993.png)

この場合、システム管理者はフローエラーメッセージを読み解けばある入力規則のエラーメッセージに気づきますが、入力ユーザはなぜエラーが出たのかわからないですね

ユーザにもなぜエラーが出るのか分かりやすくするためには、画面フローで入力制限をかける必要があります
ここでは画面フローの入力制限をかける方法を見てみましょう

## 画面フロー設定方法「入力を検証」
画面フローの「入力を検証」から設定を行います。

![フロー02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b203ec01-b860-bb81-1ddf-a1ca9867be82.png)

数式は以下を記載します

>CONTAINS({!CompanyName}, "株式会社" ) = True

なお、CompanyName　とはこちらのAPI参照名です

![API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1daa6665-d9d9-c957-01a2-5383c4afffdd.png)


メッセージはなんでもいいのですが、今回は
>会社名には必ず「株式会社」を記載してください。

と記載します

こちらで設定は完了です。あとはフローの「保存」「有効化」をお忘れなく。

![フロー04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/71f87df0-795f-2c4f-bb1a-5420b8f86ef0.png)



この設定をすれば、画面フロー内で取引先作成時に「株式会社」が含まれない場合、
画面フローでは先ほどフロー内で設定したエラーメッセージが表示され入力を促します。
（入力規則はそのままの設定なので通常の新規ボタンからレコード作成時にエラーを出すことは変わりないです）

![会社123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/34c2419a-4f64-5ff1-2387-eb203f8e2ebb.png)


## おまけ（設定のポイント）

今回の内容ですが、入力規則の数式は

>CONTAINS(Name, "株式会社" ) = false

フローの数式は
>CONTAINS({!CompanyName}, "株式会社" ) = True

と同じような数式ですが「True」と「False」がそれぞれ異なるのでご注意ください。
ITILで見る7つの原則（マネジメント）

# はじめに
ITILの勉強中にプロジェクトを進めていく上での原則があり、アジャイル開発との関連がある部分をふまえてメモしておきます。

# ITILの7つの原則

1. 価値に着目する / Focus on value
2. 現状からはじめる / Start where you are
3. フィードバックをもとに反復して進化する / Progress iteratively with feedback
4. 協働し、可視性を高める / Collaborate and promote visibility
5. 包括的に考え、取り組む / Think and work holistically
6. シンプルにし、実践的にする / Keep it simple and practical
7. 最適化し、自動化する / Optimize and automate

## 1. 価値に着目する / Focus on value
すべての活動は、価値に結び付いていないといけないという原則です。
価値はサービス消費者（サービスの利用者）にとって本当に価値があるものは何なのか？になります。
その業務によるアウトプットが誰に対してどんな価値になっているかを確認する必要があります。

## 2. 現状からはじめる / Start where you are
現状を否定して、全く新しいものをつくることは推奨しないという原則です。
今までの概念や仕組みなどを排除して新しいものに入れ替えるのではなく、今までの概念や仕組みを理解し、再利用可能なものを把握する必要があります。

## 3. フィードバックをもとに反復して進化する / Progress iteratively with feedback
作業を小さなセクションに分割し、小さな目に見える成果を積み重ねることが大切であるという原則です。
全体を理解しつつ行動も起こすことが重要ということになります。
アジャイル開発のように繰り返しフィードバックを受けることで「柔軟性の向上」や「ニーズへの迅速な対応」が可能になります。

## 4. 協働し、可視性を高める / Collaborate and promote visibility
作業やその結果を可視化することが大切であるという原則です。
作業と結果を可視化し、情報をできる限り共有することが重要になります。
メンバ間の協力作業には、情報、理解、信頼が必要です。

## 5. 包括的に考え、取り組む / Think and work holistically
活動は包括的に対応することが大切であるという原則です。
サービス、プラクティス、プロセス、部署、サプライヤは単独では成り立ちません。
全体的な視点を持って行動することを意識することが必要です。

## 6. シンプルにし、実践的にする / Keep it simple and practical
シンプルがキーワードの原則です。
プロセスや手順のステップは、達成目標に必要な最小のものにすることが重要です。
サービスマネジメントを設計したり、改善する際は、単純なアプローチから着手し、本当に必要な場合のみ追加します。

## 7. 最適化し、自動化する / Optimize and automate
無計画に自動化するのではなく、まず活動の最適化が必要であるという原則です。
最適化のない自動化には、かえってコストが増加したり、新たな問題が発生するデメリットができます。
Figma で複数のバリアントを持つコンポーネントをネストする際は並べる方向を統一した方が良い（かもしれない）

## この記事の概要

Figma でコンポーネントを作っている際に変な挙動を発見し、対処法を調べたので記事にしました。

:::note warn
ここに書いてある挙動はあくまで私が調べた範囲のものです。
データの作りや組み合わせ方によってはそもそも問題が起こらなかったり、ここに書いてあるやり方でも直らなかったりする可能性があります。
ご了承の上お読みください。
:::

## 作ろうとしていたもの

リスト要素のバリエーションを 1 つのコンポーネントで作ろうとしていました。
想定していたパターンは以下です。

| 概要 | イメージ図 |
| --- | --- |
| 縦並び サブのテキスト有り | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/c13bfdc0-2c16-f89d-cd36-7b8806c59820.png) |
| 縦並び サブのテキスト無し | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f327c21d-59b2-f440-a2af-2beff5383567.png) |
| 横並び | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/ebd5e8c4-e0c7-0173-6dee-e23837c40e9d.png) |

アイコンが共通なのもあり、以下のようにコンポーネントをネストして作っていました。

- リスト要素のコンポーネント
    - テキスト部分のコンポーネント
        - 縦並びのバリアント
            - メインのテキスト
            - サブのテキスト（ブール値プロパティを指定）
        - 横並びのバリアント
            - サムネイル画像
            - メインのテキスト
    - アイコンのコンポーネント

テキスト部分のコンポーネントは非常にプレーンな作りです。

- 縦並びのバリアント
    - メインのテキスト
    - サブのテキスト
- 横並びのバリアント
    - 画像
    - メインのテキスト

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/768852ab-0247-e964-94d3-548ca49ec121.png)

## 起きたこと

特定の手順を踏むと、テキスト部分とアイコン部分が上下中央揃えになりませんでした。

1. メインコンポーネントからインスタンスを生成
    1. ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1c5d6653-1f2f-57d9-fee8-b207742a4dd6.png)
1. インスタンスのバリアントを変更（縦並びから横並びへ）
    1. ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f2497f16-0321-bbc6-aa06-b112dae8f12c.png)
1. インスタンスのバリアントを再度変更（横並びから縦並びへ）
    1. ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/492e392b-feb1-dcb4-1f84-ceb7e834beea.png)
1. サブのテキストのブール値を false に変更 → **ネストしたコンポーネントの高さが内包でなく固定に変わってしまった**
    1. ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/86e89173-4213-4a22-068e-10b1c8b7a208.png)

## 対処法

ネストしているコンポーネントのうち、ルートフレームのオートレイアウト方向を統一します。

今回はどちらのバリアントも横並びにしました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1fdda16c-08c1-7ca4-61d0-f8ea31305518.png)

変更した構成は以下です。

- ルートのフレーム（横並び）
    - ラップするフレーム（縦並び）
        - メインのテキスト
        - サブのテキスト

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/37379ff7-59c0-3133-9f2e-807ce04b74f4.png)

オートレイアウトの中身が 1 つしか無い場合、縦並びでも横並びでも見た目が変わらないことを利用したワークアラウンドです。

これにより、同様の手順を踏んでもネストしたコンポーネントの高さが固定に変わらず、テキストとアイコンの上下中央を保つことができました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e804d6c5-ab16-984d-2e1d-ab493b470250.png)

## 補足

- 今回のデータでは横並びのバリアントにブール値プロパティをつけていますが、縦並びにつけても同様の現象が起こりました
- Figma でこういった挙動が起きる際、レイヤー名の不一致が原因の場合が多いのですが、今回は関係ありませんでした

## 最後に

記事冒頭にも書きましたが、この記事に書いてある内容はあくまで私が調べた範囲のものです。

つまり、バリアント切り替えによるオートレイアウトの挙動の変化の真因は、ネストしたコンポーネントの方向なのかは分かりません。

内包から固定へ変わる挙動も、並び方向の統一による改善も、何度か試して再現したのでひとまず記事にしているという状態です。
VGG16モデルによる画像分類の交差検証（k-Fold Cross Validation）

## はじめに
ディープラーニングで画像分類をする際、画像のデータ数が少ないとデータセットの分け方によってモデルの正解率が異なってきます。このような場合、交差検証（k-Fold Cross Validation）が有効とされています。
以前、Teachable Machineを使った金属破断面の分類

https://qiita.com/_Moony/items/01ce3d095d95696c399c

について記事にしましたが、金属破断面の電子顕微鏡画像を多く集めるのは難しいため、このような場合に交差検証は適していると考えられます。今回は、KerasのVGG16モデル（ファインチューニング）により、画像分類の交差検証を行うプログラムを作成しました。

## 作成したプログラム
以下に格納しております。

https://github.com/repositoryfiles/VGG16_CrossValidation

## 終わりに
- プログラムは画像ファイルの格納フォルダ名やコメント行に金属破断面の画像分類に関係する単語が使われていますが、他の画像分類にもお使いいただけます。その場合、バッチサイズ、テストデータの数、学習率、画像の水増しの条件などを適宜変更して行ってください。
- このプログラムはGoogleColaboratoryで動作します（2024年1月31日現在）が、フォルダ名の変更などによりスタンドアローンのパソコンにも容易に移植可能と思います。
- 何かのお役に立てれば幸いです。

## 参考
https://datawokagaku.com/kfoldcv/

https://qiita.com/ykoji/items/e9c2c5d7288c6290d21b

https://qiita.com/akatuki50/items/abbba498bb74df9e0af2

https://qiita.com/Pooh-A/items/06b2f22064675c92a3e3
SIGHUP（hangup), SIGINT(intercept), SIGTSTP(停止）

```
linuxstudy@xxxx ~]$ sleep 1500&
[1] 5833
[linuxstudy@xxxx ~]$ kill -s SIGINT 5833
[1]+  割り込み            sleep 1500
[linuxstudy@xxxx ~]$ ps 5833
   PID TTY      STAT   TIME COMMAND      //SIGINTによりプロセスが消失
[linuxstudy@xxxx ~]$ sleep 1500&
[1] 5886
[linuxstudy@xxxx ~]$ kill -s SIGHUP 5886
[1]+  Hangup                  sleep 1500
[linuxstudy@xxxx ~]$ ps 5886
   PID TTY      STAT   TIME COMMAND      //SIGHUPによりプロセスが消失
[linuxstudy@xxxx ~]$ sleep 1500&
[1] 5926
[linuxstudy@xxxx ~]$ kill -1 5926
[1]+  Hangup                  sleep 1500  //ー1（SIGHUP）によりプロセスが消失
[linuxstudy@xxxx ~]$ sleep 1500&
[1] 5945
[linuxstudy@xxxx ~]$ kill -2 5945
[1]+  割り込み            sleep 1500        //ー2（SIGINT）によりプロセスが消失
[linuxstudy@xxxx ~]$ sleep 1500&
[1] 5973
[linuxstudy@xxxx ~]$ kill -20 5973        //ー20（SIGTSTP）によりプロセスが停止

[1]+  停止                  sleep 1500
[linuxstudy@xxxx ~]$ 
```
tRPCをJestでUnitTestを書く


# 前提
Next.jsを`pnpm create next-app`でPageRouter作成し
tRPCを[Set up with Next.js](https://trpc.io/docs/v10/client/nextjs/setup)で設定してあること
jest系のpackageを追加する

## tRPC v10の方法です
v11からはcreateCallerがdeprecated であるため変わると思います

```json:package.json
{
  "name": "trpc-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest"
  },
  "dependencies": {
    "@tanstack/react-query": "4",
    "@trpc/client": "^10.45.0",
    "@trpc/next": "^10.45.0",
    "@trpc/react-query": "^10.45.0",
    "@trpc/server": "^10.45.0",
    "next": "14.1.0",
    "react": "^18",
    "react-dom": "^18",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^6.4.1",
    "@testing-library/react": "^14.2.1",
    "@testing-library/user-event": "^14.5.2",
    "@types/jest": "^29.5.12",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  }
}

```

# Test

Test対象コード
```ts:server/routers/_apps.ts
import { z } from 'zod';
import { procedure, router } from '../trpc';

export const appRouter = router({
  hello: procedure
    .input(
      z.object({
        text: z.string(),
      }),
    )
    .query((opts) => {
      return {
        greeting: `hello ${opts.input.text}`,
      };
    }),
});

// export type definition of API
export type AppRouter = typeof appRouter;
```

```ts:_apps.test.ts
import { appRouter } from "../../../src/server/routers/_apps";

describe("appRouter", () => {
  it("hello", async () => {
    const input = { text: "text" };
    const caller = appRouter.createCaller({ req: {}, res: {} });

    const result = await caller.hello(input);
    expect(result).toEqual({ greeting: "hello text" });
  });
});

```
ラズベリーパイ pico w インターネット接続

# ラズベリーパイpico w で遊んでみた

# この記事について
初めてラズベリーパイを購入したので、自分用の備忘録として書いていきます。
Qiitaの記事の作成に慣れていないため、見づらいと思いますが悪しからず。
thonnyとmicropythonを使用しています。
こちらを参考にしているので、チェックしてみて下さい。

https://micropython-docs-ja.readthedocs.io/ja/latest/index.html



# 今回の全体のコードはこちら
ネットワークの知識などが乏しい自分からすると、こんな短いコードでWi-Fiに繋がるの？
と半信半疑でしたが,実行するとしっかりネットワークに繋がりました。


```python:main.py
import network

sta_if = network.WLAN(network.STA_IF)

if not sta_if.isconnected():
    print('connecting to network...')
    sta_if.active(True)
    sta_if.connect('繋げたい自分のWi-Fiの名前', 'Wi-Fiのパスワード')
    while not sta_if.isconnected():
        pass
print('network config:', sta_if.ifconfig())
#sta_if.disconnect()現在接続している無線ネットワークから切断します
```

# コードの説明
--sta_if.isconnected()--はWiFiアクセスポイントに接続されていて有効なIPアドレスを持っていればTrueを返す。それ以外はFalseを返します。

--sta_if.active(True)--はネットワークインタフェースを有効化にします。

--sta_if.connect('繋げたい自分のWi-Fiの名前', 'Wi-Fiのパスワード')--は指定のワイヤレスネットワークに、指定のキーを使って接続します。

--sta_if.ifconfig()--は下記の順でネットワークインターフェースパラメータを取得します。
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
+ IPアドレス
+ サブネットマスク
+ ゲートウェイ
+ DNSサーバ





# まとめ
こんなに短く簡単なコードでネットに繋ぐことができました。
次はOpenWeatherのAPIを使って、現在の天気予報の情報の取得を行っていきたいと思います。

https://qiita.com/kazuki05/items/f42253e3b1e686404a11
Forge 1.20.4 カスタムスポーンエッグの追加

# 初めに
初めましての人も2回目以降の人もこんにちは。
Never3924です。
最近投稿頻度上げてる (年のはじめだけじゃなかったら良いけどね)
ネタは思いついたときに書く。自分はどうせ時間立ったら忘れるから。
おっと、話が脱線したね。それでは本題へ。

# ここ本題
すでに1.20.xとかのmob追加はもう動画で出てるんだけど、([この動画とか](https://www.youtube.com/watch?v=oCgoldUc6UQ))
スポーンエッグを作るときに少し困ったので書く。

## Java側ですること
具体的には、[ForgeSpawnEggItemというクラス](https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.16.5/net/minecraftforge/common/ForgeSpawnEggItem.html)があるんだけど、
それを使えばok。

### コード提示
```java:exampleSpawnEgg.java
import net.minecraft.world.item.Item;
import net.minecraftforge.common.ForgeSpawnEggItem;

public class WhiterSpawnEgg extends ForgeSpawnEggItem {
    public WhiterSpawnEgg() {
        super(EntityInit.EXAMPLE, 0xdddddd, 0x999999, new Item.Properties());
    }
}
```
はい。これだけ。
カンタンでしょ?
あとは普通に[register](https://zenn.dev/cyber_hacnosuke/books/minecraft-modding/viewer/basic-item)すればok。

### 解説

[親](https://wa3.i-3-i.info/word1903.html)の[コンストラクター](https://wa3.i-3-i.info/word13646.html)の[引数](https://wa3.i-3-i.info/word1442.html)について軽く解説するんだけど、
`EntityInit.EXAMPLE`は召喚したいmobの[EntityType<>](https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.16.5/net/minecraft/entity/EntityType.html)を指定すればok。
`0xdddddd`は、スポーンエッグの背景の色。
`0x999999`は、スポーンエッグのぶつぶつの色。
`new Item.Properties()うんたらかんたら`はただのアイテムプロパティ。

で、ここで注意なのが[SpawnEggItem](https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.19.3/net/minecraft/world/item/SpawnEggItem.html)を使うんじゃなくて、ForgeSpawnEggを使うこと。
なぜなら、SpawnEggItemは非推奨だから。
非推奨クラスを使うのは良くない。消されて動作しなくなったら困るし。

## Itemモデルの指定
### コード提示
あとはItemモデルを指定してあげれば動く。内容はカンタン。
```json:example_spawn_egg.json
{
  "parent": "minecraft:item/template_spawn_egg"
}
```
はい。これだけ。
カンタンでしょ?(2回目)
まぁ特に言うこともないし、ここらで終わりますか。
ばいばーい。
~~なんか解説用のリンク打ち込んだらすっげえ緑だな~~
Laravelの本番環境で出たcorsエラーとその解決法まとめ

## なぜこの記事を書いたか
自分は大学生で都内の会社でインターンをしているのですが、本番環境にデプロイする際に必ずと言っていいほど毎回corsエラーに遭遇し、最終的には「はいまたcorsね」みたいな感じになってました。同じ失敗を二度としないためにも備忘録も兼ねてこの記事を書いています。

## webアプリの構成
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474661/823ad538-6be6-537e-45a4-fad6222f6305.png)

#### バックエンド
Laravel
#### フロントエンド
Vue.js
#### サーバサイド
Docker, ECS on Fargate, ALB, nginx
#### データベース
RDS

## corsエラーの原因と修正方法
nginxのDockerfileで静的ファイルをLaravelのpublic/buildに置きました。
静的ファイル(フロントのページ)の表示は、Laravelを介さずnginxにより処理されるため、Laravelのconfig/cors.phpでいくらcorsの設定しても意味がなく、**nginxの設定ファイルで**corsヘッダを付与しなければならない。
例えば、nginx/default.confに以下を追記しました:
```
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'X-Requested-With, Content-Type' always;
```
    

## まとめ
鬼初歩的な記事で申し訳ないですが、システムの構造をきちんと理解しておくのが重要だと思いました。
すぐにqiitaなどで調べて解決すれば良いですが、そう簡単にいかない場合が多いのでどのページがどこから呼び出されているか、などを意識して自力で解決できるようになりたいものです。
Reactコーディングメモ

# 多数あるイベントの最後に再描画したい
Refでタイムアウトのクリアキーを持ち回りながら、イベントごとにクリア、setTimeoutを再コールする。

```react
    const redrawSetTimeoutClearId = useRef<NodeJS.Timeout>()
    const redrawDelayProcess = (callback: () => void, lazyMillSeconds: number) => {
        if (redrawSetTimeoutClearId.current) {
            clearTimeout(redrawSetTimeoutClearId.current)
        }
        const clear = setTimeout(callback, lazyMillSeconds)
        redrawSetTimeoutClearId.current = clear
    }
```
# Contextで中央管理し、hookで分散利用する
* Contextにはデータのみをもたせる。`useRef`にてデータは用意する。
* これを参照する小さなコンポーネントをhookで用意する。
Pleskでdeployerを使う

## 概要

Pleskは一台のサーバーに複数のウェブサイトをGUIで管理できるアプリケーションです。
https://www.plesk.com/

複数バージョンのphpやcomposerが導入でき、とても便利なのですが、deployerのデフォルト設定では動かないため、便利に使う手順をここに残します。

## deployer.phpの設定全体

(**user**)は、Pleskのユーザー名。
(**pem**)は、ローカルに置いたSSHのpemファイルのファイル名。
(**org**)/（＊＊repo＊＊）は、GitHubのレポジトリ名。

```
<?php

namespace Deployer;

require 'recipe/laravel.php';

// Config

set('repository', 'git@github.com:(**org**)/(**repo-name**)');

add('shared_files', []);
add('shared_dirs', []);
add('writable_dirs', []);

// Hosts
host('(**hostname**)')
    ->set('stage', 'dev')
    ->set('remote_user', '(**user**)')
    ->set('deploy_path', '~(**user**)')
    ->set('identity_file', '~/.ssh/(**pem**)')
    ->set('bin/composer', '/usr/local/psa/var/modules/composer/composer.phar')
    ->set('bin/php', '/opt/plesk/php/8.2/bin/php');

// Tasks

task('deploy:dotenv', function () {
    $stage = get('stage');
    $src = ".env.{$stage}";
    $deployPath = get('deploy_path');
    $sharedPath = "{$deployPath}/shared";
    run("cp -f {{release_path}}/{$src} {$sharedPath}/.env");
});

task('ks-plesk-webapp-restart', function () {
    run("/usr/local/bin/ks-plesk-webapp-restart");
});

// Hooks

after('deploy:failed', 'deploy:unlock');
before('deploy:shared', 'deploy:dotenv');

after('deploy:success', 'ks-plesk-webapp-restart');

```

## SSHの有効化

sshでのアクセスを有効にする。

- Pleskの管理画面で、ウェブサイトとドメインから、ホスティングするドメインの「接続情報」をクリックする。
- アクセス管理をクリックする。
- SSH アクセスの「タイプ」を/bin/bashに設定する。

## 証明書の配置

sshでログインして、.sshディレクトリにsshでアクセスするための公開鍵を配置する。
```~/.ssh/authorized_keys
ssh-ed25519 ******************************************************
```

## GitHub

GitHubに登録した公開鍵に対応した秘密鍵を配置する。

```~/.ssh/id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
******************************************************
******************************************************
-----END OPENSSH PRIVATE KEY-----
```

## ks-plesk-webapp-restartの導入

opcacheを使っていると、反映されないことがあるので、下記のツールを導入する。

https://github.com/kobesoft-inc/ks-plesk-webapp-restart
MATLAB の数値計算の結果を LaTeX にコピペしたい！

## はじめに
行列の固有値，固有ベクトルを計算した結果を楽にコピペする方法のメモ書きです．
上記以外にも汎用性は高いです．

## 環境
* MATLAB 2023a
* symbolic math toolbox

# 方法
今回は小数4桁までで丸めます．
```MATLAB
% 固有値計算
A = [1 2 3;4 5 6;7 8 9];
[V,D] = eig(A);

% コピペ用
latex_V = latex(round(vpa(sym(V)),4));
clipboard('copy', latex_V)

% 以下がクリップボードにコピーされています
% \left(\begin{array}{ccc} -0.232 & -0.7858 & 0.4082\\ -0.5253 & -0.0868 & -0.8165\\ -0.8187 & 0.6123 & 0.4082 \end{array}\right)
```
`latex()`は symbolic 変数しか扱えないので，一度 `sym()` をかませてから `vpa()` で小数値に変換しています．
そのままだと桁数が多すぎるので `round()` で所望の桁数に丸めて終わり．
TensorFlowのインストール方法(Mac OS)

# ターミナルの起動
まず、自分の場合はanacondaがPATHに入っていなかったので~/.zhrcファイルにanacondaのPATHを登録します。
```
> echo "export PATH=$PATH:/Users/takahisadeguchi/opt/anaconda3/bin" >> ~/.zshrc ; source ~/.zshrc
```
永続PATHに関しては過去に記事あげていますので、確認してください。
[MacOSにおけるPATH管理](https://qiita.com/takatakao397/items/3fd9eb2473d1b3c68013)
# conda環境の構築
下のコマンドでconda環境を確認できます。
```
> conda info --envs
```
![Screenshot 2024-02-04 at 17.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2153036/86611740-7864-6770-ad8b-6cba54fd762d.png)
ここではすでに作られていますが、新たに環境を作る場合は以下のコマンドを入力します。
```
> conda create --name [環境名] python=3
```
また、環境を変更する場合は下のコマンドを入力します。
```
> conda activate [環境名]
```
環境を変更する時に以下のエラーが発生するときがあります。
![Screenshot 2024-02-04 at 18.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2153036/a6b0f407-18b0-26ba-2650-b292fc0022ae.png)
そのときはこれで解決
```
> conda init zsh
```
>ターミナルの環境はウインドウ上部で確認する
>
ここまで上手くいったらAnacondaNavigatorでも確認できます。
![Screenshot 2024-02-04 at 18.08.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2153036/3ddc19f7-5011-a985-b5c9-814140b12e1f.png)



# TensorFlowのインストール
自分の場合は(py-TF2.0)環境で下のコマンドを入力しました。
```
> conda install tensorflow
```
tensorflowを最新にする
```
> pip install --upgrade tensorflow
```
Godot 親子関係にあるノードのPositionが相対位置の関係になる事の解消

## 要約
- Positionプロパティを持つノード同士が親子関係になると、子の位置は親からの相対位置となる
- この親子関係の間にPositionを持たないノードを挟むと相対位置の関係を解消できる
- おまけ：循環参照を形成したい時も別のノードを間に挟むと警告を受けなくなる

環境：Godot4.2＋ C#(.Net Framework6.0)

## 親子関係の相対座標の解消
　シューティングゲームを作っていると個々のゲームオブジェクトの位置情報を更新して自機や弾の座標を更新していきますが、親子関係にあるシーンやノード(＝ゲームオブジェクト)の子のPositionプロパティは、親のPositionからの相対位置として扱われます。
 
　ほとんどの場合これはよろしくない振る舞いです。例えば自機(親)から発射した弾(子)が親の移動に伴って上下左右に引きずられるのは、意図した振る舞いではないでしょう。
　これを回避するためにゲーム座標系の基準となるノードを配置し、全てのゲームオブジェクトがその子となるようGetParent().GetParent().GetParent()....AddChild()のような方式もありますが、途中にPositionプロパティを持たないゲームオブジェクトを挟むことでも回避出来ます。

　この構造は自機のコード量を減らして見通しを良くすることにも貢献するので、個人的にも気に入ってます。
 

## シーン構造
<img width="800" alt="treemodel" src="https://pbs.twimg.com/media/GFeeQ6QbgAAJUO5?format=png&name=900x900">

　上図では自機(Ship)がArea2D、弾ジェネレーターがNode、弾(Bullet)がArea2Dの派生になります。赤矢印が親子関係を表しています。弾ジェネレーターはPositionを持たないため、ジェネレータの子となった弾のPositionは自機のPositionの影響をうけません。
　何度も GetParent()と書かずに済むのでコード上もシンプルな記述を維持できます。
 
　手前味噌になりますがこの方式を用いた制作例のご紹介。

https://x.com/cabbagestole/status/1751099214510391421?s=20



## おまけ(循環参照の解消)

 スイカゲームのクローンをイメージしてください。雑な動画ですがだいたいこんなゲームです。

https://x.com/cabbagestole/status/1753701478651535587?s=20

 
　このゲームでは衝突したボール同士から新たなボールを生成する事になります。このような構造のゲームではボールシーンが自分自身を参照できるとよいのですが、Godotエディタはこれを循環参照として警告を発します。
 
<img width="800" alt="editorview" src="https://pbs.twimg.com/media/GFeZDoFaEAAB6tw?format=jpg&name=large">

<img width="800" alt="warningmessage" src="https://pbs.twimg.com/media/GFeYAVqaYAAdDWu?format=jpg&name=medium">

　自己参照を行いたいシーンの参照先に別のシーンを一度中継することで、警告を解消できます。
 これは警告の解消を目的とした局所的な構造変更の話であり親子関係によるPositionの相対座標関係の解消と直接の関係はありませんが、BallGeneratorがPositionを持たないことから先の問題にたいしても同時に解決できる構造となっています。
 
 

<img width="800" alt="warningmessage" src="https://pbs.twimg.com/media/GFebx7sbEAATrIk?format=png&name=900x900">
JPNTEST ADM-201-JPNの用語の読み替え

# 解説

Salesforce認定アドミニストレーター試験用の模擬問題集である、[無料ADM-201-JPN試験問題集](https://www.jpnshiken.com/exam/ADM-201-JPN-salesforce-certified-administrator-adm-201%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%89%88-8818.html)に出てくる日本語で不思議なものを、Salesforceで使われる日本語訳に対応させてみました

## これらを変換するChrome拡張を作りました
https://github.com/hkj/convertJPN

JPN試験のURLでSalesforceが含まれている場合に、以下の言葉を変換します。

## 語句一覧

* 商談
    * 機会
    * オポチュニティ
    * Opportunity
    * 取引(恐らくそうでないかと)
* 大規模商談アラート
    * ビッグディールアラート
* 主従関係
    * マスター/詳細
    * マスター詳細
* 参照関係
    * ルックアップ
* 取引先
    * アカウント
    * Account
* 取引先責任者
    * 連絡先
    * お問い合わせ
* フローの保存前更新(高速項目更新)
    * 保存前のフロー
    * フローを保存する前
* 重要な項目
    * キーフィールド
* メール-to-ケース
    * メールからケースへ
* ミュート権限セット
    * ミューティングパーミションセット
* ToDo
    * タスク
* 定期的なToDoを作成
    * Create Recurring Series of Tasks
* 選択リスト
    * ピックリスト
    * piclist
* 強調表示パネル
    * ハイライトパネル
* 積み上げ集計項目
    * ロールアップサマリーフィールド
* 無効化
    * 非アクティブ化
* 確度
    * 確率
* 連動選択リスト
    * 依存する選択リスト
* ナレッジ記事
    * 知識記事
* 商談履歴レポートタイプ
    * 商談ステージ期間レポート
* レコードの一括更新
    * 物質移動ツール
* Chatter
    * おしゃべり
    * 会話
* キャンペーンインフルエンス
    * キャンペーンの影響
* パス
    * 道
* 個人取引先
    * 個人のアカウント
* ロール階層
    * 役割階層
* 共有ルール
    * ルールの共有
* 取引先責任者-to-複数取引先
    * 複数のアカウントへの連絡先
* アウトバウンドメッセージ
    * 送信メッセージ

## 用語では無い誤字・誤訳
* 現在
    * カラント(currentの事と類推される)
* が存在する
    * セクシスト(existの事と類推される)
Databricksアシスタントでクイックにエラーを修正

こちらの機能もリリースされています。

https://docs.databricks.com/ja/notebooks/notebook-editor.html#possible-actions-on-syntax-errors-and-warnings

もともとDatabricksアシスタントが有効化されていれば、エラー発生時には修正エラーボタンが表示されるようになっています。上の機能はプログラム実行前に構文エラーなどがある場合に、クイックに問題を修正できます。

構文エラーがある場合、行の下に赤線が表示されます。そこにカーソルを持っていくとコンテキストメニューが表示されます。ここでは、**Quick Fix**を選択します。
![Screenshot 2024-02-04 at 17.36.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/52755f94-87eb-781d-5889-897d1eebe3a1.png)

**Fix with Assistant**を選択します。
![Screenshot 2024-02-04 at 17.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/01a48f02-3e59-7582-70e9-b25d0a9f6a35.png)

差分が表示されるので問題なければ、**承認**をクリックします。
![Screenshot 2024-02-04 at 17.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/193627fe-b063-dabe-f5e8-ae1222a27c04.png)

動きました！
![Screenshot 2024-02-04 at 17.42.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9bc750e7-023f-3dca-571f-04ec365dfdba.png)

なお、上のメニューで**View Problem**を選択するとエラーメッセージを表示できます。
![Screenshot 2024-02-04 at 17.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/97ca3051-2bea-fd41-adf4-481f67972e08.png)

生産性向上のために是非ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Jetpack composeでonBackPressedを制御する

# はじめに
今回はJetpack composeでのonBackPressedを制御する方法を紹介していきます
### 本文
早速ですが、下記のようにすることで制御することができます
```kotlin
@Compose
fun Hoge() {
    BackHandler {
        //処理を書く
    }
}
```
引数としてBooleanを渡すことができますが、これをfalseにすると一つ上の階層に記述しているBackHandlerの処理が呼び出されるようになります
### 最後に
備忘録としての役割が強いですが、どなたかのお役に立てれば幸いです
【Android】ドラッグしたViewを回転させる【Kotlin】

# はじめに
前回の　[【Android】Viewをドラッグして移動させる【Kotlin】
](https://qiita.com/Tsubasa12/items/c0287069b5e8666c2de7)こちらの記事に引き続き Viewを動かしながらそこに回転を加えていきます。
前回の記事の続きものになるので、まだみていない方は先に前回のものも見ていただけると分かりやくなると思います。

# 実践
Viewをドラッグし**縦方向に**動かしている間は回転(横方向は水平移動)、指を離したら元の元の位置、元の角度に戻るようにします。


``` diff
MotionEvent.ACTION_MOVE -> {
省略・・・

+    // 回転 
+    val distanceX = firstPositionX - newPositionX
+    val distanceY = firstPositionY - newPositionY
+    val absX = abs(distanceX)
+    val absY = abs(distanceY)
+    val abs =
+        if (absX < absY) {
+            // 0はY軸の真ん中
+            if (0 < distanceY) {
+                -absY
+            } else {
+                absY
+            }
+        } else {
+            0
+        }
+    view.rotation = abs.toFloat()
}


MotionEvent.ACTION_UP -> {
省略・・・

+    view.rotation = 0f
}
```

![Record_2024-02-04-16-45-42_24eefb17d38097f5d5d4a6b0b9783dd1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/8ad5e0d6-eaff-e327-408b-87a917a6f7c2.gif)
Raspberry Pi Pico/w で 環境データを AMBIENT に記録と表示

## Raspberry Pi Pico W で気象環境データを記録
　Raspberry Pi Pico W で室内環境を記録するというのは、ネットに情報が結構ありますね。データの記録と可視化をクラウドでサービスしてくれる Ambient を使っている例も散見しますが、本家の mycropython ライブラリを使用した例が見つかりませんでしたので、自作したものを公開します。
 改善点などご指摘いただければ嬉しい。

 ## Ambient
 [Ambient](https://ambidata.io) は IoT データの可視化サービスです。
 フリーミアムサービスで、制限内であれば無償で利用できるので、愛用させていただいております。

 ### Anbient公式の micro python 用ライブラリー
 API が公開されていますので、HTTPリクエストでも使えますが、ライブラリーを使うと簡単に利用できます。下のリンクに解説とライブラリーへのリンクがあります。
 [「MicroPythonからAmbientにデーター送信できるようにしました」](https://ambidata.io/blog/2017/06/30/micropython/)
 
![IMG_9707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/16119c4e-9e5f-2e2e-c369-4900d8ec5ca5.png)


 ## 作成したアプリのソース
 Raspberry Pi Pico W に BME280 と 0.96インチOLEDディスプレイ(SSD1306)を繋いで送信データを確認できるようにしています。
 
 【2024/2/7 追記】公開していたソースでは、5回くらいAmbientに送信した後、エラーで終了する現象が発生して、原因を調査しておりました。
 Ambient の中の人から助言をいただき、送信後に毎回ガベージコレクションをするようにしたところ、エラーが発生せず長時間稼働し続けるようになりました。
 ということで、以下のソースはその修正後のものです。
 

```python:BME280_Ambient.py
import network
import WIFI_CONFIG
import machine
import ssd1306
import time
import sys
from bme280 import BME280
import math
import ambient
import gc

sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0,sda=sda, scl=scl, freq=400000)

bme = BME280(i2c = i2c)

oled = ssd1306.SSD1306_I2C(128, 64, i2c)

ssid = WIFI_CONFIG.SSID
password = WIFI_CONFIG.PSK
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        oled.init_display()
        oled.text("WiFi NOT connect.",0,5)
        oled.show()
        break
    max_wait -= 1
    oled.init_display()
    oled.text("WiFi connecting.",0,5)
    oled.show()
    time.sleep(1)


# setup AMBIENT
chID = <<チャネルID>>
writeKey = <<書き込み用キー>>
am = ambient.Ambient(chID, writeKey)

def sensor_read():
    oled.init_display()
    t, p, h = bme.read_compensated_data()
    t = math.floor((t / 100.0 + 0.5) * 10) / 10
    p = math.floor((p / 256.0 / 100 + 0.5) * 10) / 10
    h = math.floor((h / 1024.0 + 0.5) * 10) / 10

    oled.text("Temp: ", 0, 1)
    oled.text(str(t)+"C", 40, 1)
    oled.text("Pres: ", 0, 16)
    oled.text(str(p) + "hPa", 40, 16)
    oled.text("Hum: ", 0, 31)
    oled.text(str(h) + "%", 40, 31)

# upload data to AMBIENT
    r = am.send({'d1': t, 'd2': p, 'd3':h})
    oled.text("sent: "+str(r.status_code),0,46)
    
    oled.show()
# garbage collection
    gc.collect()

if __name__ == '__main__':
    while True:
        try:
            sensor_read()
        except KeyboardInterrupt:
            sys.exit()
        time.sleep(60 * 10)

```

Ambientでダッシュボードを見ると、ちゃんと記録されていますね。
![Ambidata.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/507082b6-8f63-10ed-2aba-cde6cc537d78.png)

参考になれば幸いです。

【2024.02.26 追記】
　BME280 から取り込んだデータの補正にバグがありましたので、訂正しました。
[CAIレシピ] 割り当てステップと、各種変数フィールドの利用

## はじめに

CAIプロセスの割り当てステップを利用すると、定義済みの各種フィールド(`入力・出力・一時`)に値を設定できます(`プログラミングで言うところの "代入" をするためのステップ`)。この記事では次のポイントについて確認しています。

- 入力・出力・一時フィールドとは
- 割り当てステップの利用手順

なお、この記事は次の記事の内容を理解していることを前提としています。

- [はじめてCAIを使う際に](https://qiita.com/shunsuzu/private/12b8dbd08a30efa0003a)
- [プロセスの作成と実行(匿名認証と基本認証)](https://qiita.com/shunsuzu/private/01d91caedb92bd7781ea)


## 入力・一時・出力フィールドとは

CAIプロセスを実装する際、次の3つのタイプのフィールド(`プログラミングで言うところの変数`)を利用できます。

- 入力フィールド ... CAIプロセス実行時に呼び出し元から値を渡すフィールド
- 出力フィールド ... CAIプロセス実行結果として呼び出し元に値を返すフィールド
- 一時フィールド ... CAIプロセス内で利用する一時的なフィールド

各種フィールドを定義するには、開始ステップを選択して、タイプに応じてタブを選択後、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/328efcee-bca8-5170-c39e-d04af4a07828.png)ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/1f827385-5b92-8409-845d-9f691d98a492.png)


## 割り当てステップの使用手順

割り当てステップを使用することで、定義したフィールドに値を設定できます。

### CAIプロセスの作成
次の手順では、割り当てステップを利用して、入力フィールドとして受け取った値を、出力フィールドとして呼び出し元に返すCAIプロセスを作成しています。

1. CAIプロセスを次の設定で作成します。
    - 名前を __recipe-pca-stepAssign__ とする
    - __匿名アクセス__ を許可する
    - __クラウドサーバー__ にデプロイする
1. 入力フィールドとして __input__ を __タイプ=テキスト__ で定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/e3f291b5-82e6-a79a-eca9-2927573954d6.png)

1. 出力フィールドとして __output__ を __タイプ=テキスト__ で定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/03c0c9fd-71ed-0afd-46e6-fb79d2c22fba.png)

1. __割り当てステップ__ を追加して __フィールドの追加__ から出力フィールドとして定義した __output__ を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/2c0eff98-9ce8-5ca2-3dfe-67f403c2e6b4.png)

1. フィールド一覧に __output__ フィールドの設定が追加されているはずです。 __output__ フィールドに __コンテンツ__ を指定、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/5ec58c60-34c9-b9f8-3efc-05fee8d3fb5b.png)をクリックして表示される候補から __input(入力フィールド)__ を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/9f25ff3f-1691-c599-e047-71056da4dfc2.png)



### CAIプロセスの実行
以下、curlコマンドを例とした動作確認結果です。実行時に指定した値(Hello Wooorld)が実行結果として得られる動作を確認できます。

```:curlコマンドと実行結果
// curl コマンド
curl https://<IICS・CAIサーバー>/active-bpel/public/rt/<Org ID>/recipe-pca-stepAssign \
-H 'Content-Type: application/json' \
-d '{"input": "Hello Wooorld"}'

// 実行結果
{"output":"Hello Wooorld"}
```


## 参照

- [Qiita - IICS CAIの実装レシピ - マスターページ](https://qiita.com/shunsuzu/private/3d1971ef6e3b993516aa)
goのfor文を用いて構造体に変数代入しようとしたら頭を抱えた話

# 問題
`User`構造体の`introduction`を`Introduction`構造体に代入しようとしたら、全て一番最後のプロパティの値が代入されてしまった
## ソースコード

```golang
package main

import "fmt"

type User struct {
	name         string
	age          int
	introduction string
}

type Introduction struct {
	introduction *string
}

func main() {
	users := []User{
		{"Alice", 25, "Hello, I'm Alice!"},
		{"Bob", 30, "Hi there, I'm Bob."},
		{"Charlie", 22, "Greetings! I'm Charlie."},
	}
	introductions := makeIntroductions(users)

	for _, introduction := range introductions {
		fmt.Println(*introduction.introduction)
	}
}

func makeIntroductions(us []User) []Introduction {
	var introductions []Introduction

	for _, user := range us {
		introductions = append(introductions, Introduction{
			introduction: &user.introduction,
		})
	}

	return introductions
}
```

## 期待した結果
```
Hello, I'm Alice!
Hi there, I'm Bob.
Greetings! I'm Charlie.
```

## 出力結果
```
Greetings! I'm Charlie.
Greetings! I'm Charlie.
Greetings! I'm Charlie.
```


# 原因
`introductions`の要素全てのポインタ（参照先）が同じだった

## 問題の箇所
```go
for _, user := range us {
		introductions = append(introductions, Introduction{
			introduction: &user.introduction,
		})
}
```
`for range`において代入される要素の値は全て同じメモリ空間を使用します
そして今回`introductions`にはそのポインタを代入しています


```go
for _, introduction := range introductions {
		fmt.Println(introduction.introduction)
}
 ```

 ```
0x140000740d8
0x140000740d8
0x140000740d8
```
つまり、最終的に出力される値も参照元が全て同じ値であるため`for range`で代入された一番最後値が結果として出力されたのです
 
# 対処法
`for range`の要素がすべて同じメモリ空間で使用されないようにするため、`for range`の中で代入される要素を新しい変数定義する
```go
for _, user := range us {
		introduction := user.introduction
		introductions = append(introductions, Introduction{
			introduction: &introduction,
		})
}
 ```
Objective-cによるダークモード対応

#Objective-cでダークモード対応をする

##記述の経緯
4年前に下書き保存されていたので供養
Objective-cの参考文献があまり無かった為

##コード

```
- (UIColor *)setElementLightStyleColor:(UIColor *)lColor darkStyleColor:(UIColor *)dColor {
    __block UIColor *showColor;
    if (@available(iOS 13.0, *)) {
        showColor = [UIColor colorWithDynamicProvider:^UIColor * (UITraitCollection * dynamicProvider) {
            if (dynamicProvider.userInterfaceStyle == UIUserInterfaceStyleDark) {
                return  dColor; //showColorにreturn
            } else {
                return lColor;
            }
        }];
    }else{
        return lColor;
    }
    return showColor;
}
fiddler2初期設定

## やりたい事
fidllerをインストールして通信をキャプチャしたい。


ここからDLしてインストール。
https://www.telerik.com/fiddler/fiddler-classic

「I agree」 → 「Install」 → 「Close」

## Fiddler Classicを起動
ダイアログが出るので
「Cancel」

## HTTPS通信を有効に
「Tools」 → 「Options」 → 「HTTPS」タブで
+ Decrpt HTTPS CONNECTs
+ Ignore server cetificate errors(unsafe)
にチェック

「Actions」 → 「Trust Root Cetificate」で証明書をインストール
「Yes」 → 「はい」 → 「OK」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/dc5f6c29-ed60-a127-1035-9631ae80a367.png)

## フィルター
全部の通信をキャプチャしてたら忙しいのでフィルターを設定。
「Filters」タブで
+ Use Filters
+ Show only the following Hosts
を選択

キャプチャしたいHostを左側の一覧から選んでテキストエリアに入力。
「Actions」 → 「Run Fillterset now」で実行


![スクリーンショット 2024-02-04 160659.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/739f1105-56b1-506e-f55b-f7bedebe73a5.jpeg)

## 通信エラー
HTTPSの証明書の有効期限切れが原因で
このようにエラーになる事があります。
![スクリーンショット 2024-02-04 165938.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/1ef89003-3f60-d0d3-bf7e-5076436087a9.jpeg)

「Tools」 → 「Options」 → 「HTTPS」タブで
「Actions」 → 「Reset All Cetificates」で証明書を一回削除。
改めて
「Actions」 → 「Trust Root Cetificate」で証明書をインストール
fiddlerを再起動。
で直ります。