OmniAICreator/Qiita-1.07M huggingface dataset:
Golangでネストされた構造体のスライスの中身をHTMLで表示する方法(rangeの挙動について)

# この記事を読んでわかること

- ネストされた構造体のスライスの中身をhtmlに表示させるための書き方
- 実際に実装してみるためのサンプルコード


# サンプルコード(main.go, template.html)
先にサンプルコードを示しておく。今回はmain.goファイルとtemplate.htmlを使用する。Pathについては各自改めて設定していただきたい。

```Go:main.go
package main

import (
	"html/template"
	"net/http"
	"log"
)

type User struct {
	ID      int
	Name    string
	Email   string
	Todos   []Todo
}

type Todo struct {
	Title   string
	Content string
	Done    bool
}

func generateHTML(w http.ResponseWriter, data interface{}) {
	tmpl := template.Must(template.ParseFiles("templates/template.html"))
	err := tmpl.Execute(w, data)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}
}

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		user := User{
			ID:    1,
			Name:  "John Doe",
			Email: "john@example.com",
		}

		todo1 := Todo{
			Title:   "Task 1",
			Content: "Do task 1",
			Done:    false,
		}
	
		todo2 := Todo{
			Title:   "Task 2",
			Content: "Do task 2",
			Done:    true,
		}

		user.Todos = append(user.Todos, todo1)
		user.Todos = append(user.Todos, todo2)
		generateHTML(w, user)
	})

	log.Println("Server started on localhost:8080")
	http.ListenAndServe(":8080", nil)
}

```


```html:templates/template.html
<!DOCTYPE html>
<html>

<head>
    <title>User Information</title>
</head>

<body>
    <h1>User Information</h1>
    <p>ID: {{ .ID }}</p>
    <p>Name: {{ .Name }}</p>
    <p>Email: {{ .Email }}</p>
    <h2>Address</h2>
    {{ range .Todos}}
    <p>Title: {{ .Title }}</p>
    {{end}}
</body>

</html>
```

# 設定の確認
構造体について確認しておく。
```go:main.go
type User struct {
	ID      int
	Name    string
	Email   string
	Todos   []Todo
}

type Todo struct {
	Title   string
	Content string
	Done    bool
}
```
ここではUserという構造体とTodoという構造体を定義している。
Userという構造体には、ID, Name, Email, Todosというフィールドが存在していることがわかる。
ただTodosがスライス型であることに注意していただきたい。
また、Todoという構造体には、Title, Content, Doneというフィールドが存在する。
```go:main.go
user := User{
			ID:    1,
			Name:  "Tarou",
			Email: "Tarou@example.com",
		}

todo1 := Todo{
	Title:   "Task 1",
	Content: "Do task 1",
	Done:    false,
}
	
todo2 := Todo{
	Title:   "Task 2",
	Content: "Do task 2",
	Done:    true,
}
user.Todos = append(user.Todos, todo1)
user.Todos = append(user.Todos, todo2)

```
ここでは、TarouのTodoを2つ作成している。
そして、main.goファイルで
```go:main.go
generateHTML(w, user)
```
このように書いたことでuser、つまりTarouの情報がhtmlに渡されている。

# 本題
ここでやりたいことは**TarouのTodosの中のTitleを並べて表示する**ということである。

そこで使用するのがrangeである。
htmlの中で以下のように指定する。
```html:template.html
{{ range .Todos }}
    <p>Title: {{ .Title }}</p>
{{end}}
```
{{ range .Todos }}と{{end}}で括った部分がTodosの長さ分繰り返される。
そして、特に注意しなければならないのがTitleの取り出し方である。
一般的にネストされた構造体の中身を見るときは、
```html
{{ .Todos.Title }}
```
とすることで確認することができるが、rangeを使う場合はその中で.Todosは不要になり、
```html
{{ .Title }}
```
のみで使用することになる。

私はそれがわからず数時間悪戦苦闘することになってしまったが、皆さんはそのようなことがないことを祈っている。

# 最後に

初めてのQiita記事で読みにくいところがあったかもしれませんが、最後まで読んでいただきありがとうございました。
📜Private Diary【GoogleMapsAPIを取り入れる】

## はじめに
これは手順を記載した投稿ではありません。日々の個人日記になります。

## 経緯
PFを作成しています。本日、日付を跨いで月の中日となりました。今月中までにPFを作成しなければならずはじめに立てたスケジュールから遅れをとっていることに非常に焦りがあります、、、

## 本日の成果
今回のPFでは、スポット検索機能を取り入れたく色々と試行錯誤しました。機能の理想は入力フォームにスポットの名前を入れると予測候補が表示されることを取り入れたいと思いました。
そのため、GoogleのAPIを導入しなければならずまずはAPIの取得から学習しました。さらにそこから、 APIキーを環境変数にして安全に取り扱えるようにしました。
今回は、APIとして「Places API」「Maps JavaScript API」を有効にしてなんとか予測変換ができるようになりました。
![予測image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338070/7c58c543-967c-04db-4894-8c02ce23133f.png)

## 参考にさせてもらった記事
https://qiita.com/nagase_toya/items/e49977efb686ed05eadb

https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39

## 明日は
今回できた機能をPFに落とし込みたいと思います。大変ですが、頑張ります！
毎日が勉強。これからも勉強。楽しく勉強。
以上
Centos7に古いバージョンのCowrie(ハニーポット)を導入

# CowrieをCentos7に導入してみた

ネット上には記事自体はたくさんあったのですが、僕の環境ではうまくいかなかったのでバージョンを下げて動かしてみました。

うまく動かない人は参考にしてみてください。




# Cowrie 実装

## 他のポートでログインできるようにする
cowrieが22番ポートを使うようなので他のポートでアクセスできるようにしておきましょう。
今回は437を開けます。
```
$ sudo nano /etc/ssh/sshd_config

#ファイル内で、新しい行を追加

Port 22
Port 437


#SSHサービスを再起動

$ sudo systemctl restart sshd

#firewallの設定とリロード
$ sudo firewall-cmd --permanent --zone=public --add-port=437/tcp
$ sudo firewall-cmd --reload

```


## Cowrieのためにポート開放


```
$ sudo firewall-cmd --add-port=22/tcp --zone=public --permanent

$ sudo firewall-cmd --add-port=23/tcp --zone=public --permanent

$ sudo firewall-cmd --add-port=2222/tcp --zone=public --permanent

$ sudo firewall-cmd --add-port=2223/tcp --zone=public --permanent

$ sudo firewall-cmd --reload
```

## ポートフォワーディングの設定

今回は22番を2222番に、23番を2223にポートフォワーディングします。

```
$ sudo firewall-cmd --permanent --zone=public --add-forward-port=port=22:proto=tcp:toport=2222

$ sudo firewall-cmd --permanent --zone=public --add-forward-port=port=23:proto=tcp:toport=2223

$ sudo systemctl restart firewalld
```

## Cowrieが使う専用のユーザを追加します。

```
$ su -
$ useradd Cowrie
$ passwd Cowrie　好きなパスワードを入れてください
```

## pythonの環境を整えていきます。

```

$ yum groupinstall "Development Tools"
$ yum install python-devel python-setuptools python-virtualenv
$ curl -o get-pip.py https://bootstrap.pypa.io/pip/3.6/get-pip.py
$ python get-pip.py

```

## Cowrie導入

```
$  su - Cowrie
$ wget https://github.com/cowrie/cowrie/archive/refs/tags/v2.0.2.tar.gz
$ tar zxvf v2.0.2.tar.gz
$ cp cowrie.cfg.dist cowrie.cfg
$ virtualenv cowrie-env
$ source cowrie-env/bin/activate
$ pip install --upgrade pip
$ pip install --upgrade -r requirements.txt
$ deactivate
```

## Cowrieの起動
```
$ ./bin/cowrie start
```

## ログの場所
ログは/var/log/cowrieにあります。
新しいバージョンでは、実行されたコマンドは別の場所に保存されるようですが、今回のバージョンはアクセスログなどと一緒にコマンドのログが残ります。

ダウンロードしたファイルがどこに保存されているかは未明です。

## 最後に
初めての記事なので、分かりにくいところなどありましたら、ご指摘ください。


## 参考にしたサイト様

https://qiita.com/tnbt/items/c5da70041dd6d26a862f#%E3%81%9D%E3%81%AE%E4%BB%96

https://qiita.com/pypypyo14/items/f399366b34b8dfcb7aa1
TypeScriptのカリー化と部分適用について学んだこと

# 背景
TypeScriptを書く際に下記のコードに遭遇し、引数を２つ連続で取ってるのっておかしくね？と思い調べました。調べてみると、関数型プログラミング言語にはカリー化というものがあることを知りました。

```js:遭遇したコード
export const getBlog = (queries?: MicroCMSQueries) => (contentId: string) =>
  apiClient.getListDetail<Blog>({ endpoint: 'blog', contentId, queries })
```

# カリー化とは
>カリー化とは、複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること（あるいはその関数のこと）である。(Wikipedia)

？？
簡単に言うと、
カリー化とは、複数の引数を取る関数を、一度に1つの引数だけを取る一連の関数に変換するテクニックです。これにより、関数の一部の引数を固定して新しい関数を生成することが可能になります。これを部分適用と呼びます。


# カリー化・部分適用の具体例
まずは２つの数値を加算するシンプルな関数を作成します。
```typescript:typescript
function add(x: number, y: number): number {
  return x + y;
}
```
この関数は2つの引数を取りますが、カリー化を使用して一度に1つの引数だけを取る関数に変換することができます。
```typescript:typescript
function curriedAdd(x: number) {
  return function(y: number) {
    return x + y;
  }
}
```
この curriedAdd 関数は、最初の引数 x を取り、その後に新しい関数を返します。この新しい関数は、2番目の引数 y を取り、x と y を加算します。

部分適用を使用すると、一部の引数を固定した新しい関数を生成することができます。例えば、以下のように curriedAdd 関数を部分適用して、5を加算する新しい関数を生成することができます。
```typescript:typescript
const addFive = curriedAdd(5);

console.log(addFive(3));  // 8
console.log(addFive(10)); // 15
```
この例では、addFive 関数は5を加算する関数です。これは、部分適用を使用して curriedAdd 関数の一部の引数を固定した結果です。

上記を踏まえて再度コード見てみます。
```tsx:カリー化を使用した元のコード
export const getBlog = (queries?: MicroCMSQueries) => (contentId: string) =>
  apiClient.getListDetail<Blog>({ endpoint: 'blog', contentId, queries })
```
これは下記と同じ意味になることが分かります。
```ts:カリー化を使用せず関数化した場合
export const getBlog = (queries: MicroCMSQueries, contentId: string) =>
  apiClient.getListDetail<Blog>({ endpoint: 'blog', contentId, queries });
```
そして、この関数を使用する場合は以下のようになります：
```ts
const queries = { 
  limit: 10,
  offset: 20,
  fields: 'title,body'
};
const contentId1 = "contentId1";
const contentId2 = "contentId2";
const contentId3 = "contentId3";

const blog1 = getBlog(queries, contentId1);
const blog2 = getBlog(queries, contentId2);
const blog3 = getBlog(queries, contentId3);

//GET /blog/contentId1?limit=10&offset=20&fields=title,body
//GET /blog/contentId2?limit=10&offset=20&fields=title,body
//GET /blog/contentId3?limit=10&offset=20&fields=title,body
```
この場合だと、いちいちgetBlog関数の第一引数にqueriesを指定しないといけません。

カリー化と部分適用は、特定の設定で何度も同じ関数を呼び出す必要がある場合などに便利です。また、部分適用された関数を生成することで、コードの可読性も向上します

# まとめ
カリー化と部分適用は、関数型プログラミングの重要な要素であり、TypeScriptでも利用することができます。これらを調べるにあたり、第一級関数や高階関数についても調べられたので勉強になりました。

# 参考
https://qiita.com/cocoabreak/items/e0caad052ef84e633bee

https://cloudsmith.co.jp/blog/frontend/2021/09/1874653.html
matplotで粒径を指定してアニメーションをつくる

粒子配置が連番ファイルで与えられているとして、matplotでそれをアニメーションにしたい。
粒子の大きさを気にすることなく、ただプロットするだけならplot関数(色をつけたいならscatter関数)を使えば良い。
plotを使う場合→[matplotlibで連番ファイルからgifアニメを作る](https://qiita.com/kumamupooh/items/5273b0b98a4b6ee976fc)
    アニメーションの基本的なことはこの記事が参考になる。

座標を単位として粒径を設定するためにEllipseCollection関数を使う。
(円専用のCircleCollection関数も存在するが、そちらは粒径の設定方法が面倒なので今回は使わない)


```
import matplotlib
from matplotlib.animation import FuncAnimation
from matplotlib.collections import EllipseCollection
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline
%config InlineBackend.figure_format = 'retina'
L = 10.0
filenum = 20  # number of files
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(1, 1, 1)
ax.set_aspect("equal")
#  ax = fig.add_subplot("14{}".format(j))
x, y, a = np.loadtxt("file_path_10.dat", comments='#', unpack=True)
title = plt.title("t")
plt.xlim(0, L)
plt.ylim(0, L)
p = EllipseCollection(a, a, a, units="xy", cmap=matplotlib.cm.jet,transOffset=ax.transData, alpha=1.0, fc='g', ec="k", lw=0.5,offsets=np.column_stack([x, y]),animation=True)
ax.add_collection(p)
plt.xlabel(r"$x$", color='k', size=35)
plt.ylabel(r"$y$", color='k', size=35)
def init():
    pass
def update_anim(j):
    x, y, a = np.loadtxt("file_path_{:n}.dat".format( j), comments='#', unpack=True)
    p.set_offsets(np.column_stack([x, y]))
    p.set_array(x)  # colors of each particles.
    title.set_text("t={:.1f}".format( j*5))
    return [p]
ani = FuncAnimation(fig, update_anim, init_func=init(),interval=150, blit=True, frames=filenum)
ani.save("anime.mp4",writer="ffmpeg")
plt.show()
```
![anime_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084175/a2d50b4b-799c-2cf3-ac50-72a60314537d.gif)

## 各関数の説明
### Funkanimationについて

こちらの記事が詳しい→[matplotlibのanimation.FuncAnimationを用いて柔軟にアニメーション作成](https://qiita.com/AnchorBlues/items/3acd37331b12e844d259)
>`built`のオプションは`update_anim`関数の返値があるかどうかを決めている。Trueの方が早いらしい。

### EllipseCollectionについて
[matplotの公式ドキュメント](https://matplotlib.org/stable/api/collections_api.html#matplotlib.collections.EllipseCollection)
多くの楕円を描くための関数。
第1-3引数：それぞれの粒子の長軸の長さ、短軸の長さ、なす角 を表す。ここでは円を描くため、長軸、短軸の長さは共に1、なす角は適当な配列にしてある。楕円を描く場合、なす角の単位は度でラジアンでないため注意すること
 `units="xy"`：粒径の単位。ここではxy座標
 `transOffset=ax.transData`：座標の単位？ここではxy座標
 `cmap=matplotlib.cm.jet, fc='g', ec="k", lw=0.5`：cmap,粒子の色、縁の色、縁の線幅
`offsets=np.column_stack([x, y])`：各粒子の座標。`[[x1,y1][x2,y2]…]`という形式で入れる。
`animated=True` プロットされ託するオプション。`built=True`と組み合わせることでプログラムが早くなる
### update_animの中身
`set_offsets`:粒子の座標を入れる。形式は`offsets`のときと一緒
`set_array`:粒子の色を決めるパラメータ。上下限は`set_clim`で設定可能
irbのshow_sourceが便利すぎた

https://qiita.com/k0kubun/items/4600e52a1a245495dfaa

irbの機能が色々増えているということで、色々と試していたところ、`show_source`が便利すぎたのでまとめました。

## show_sourceについて

引数でメソッドや定数を受け、そのソースコードを表示するコマンドです。
`$`でも同義です。

つまり、irbで `show_source set_user`や`$ set_user`を実行すると、`set_user`メソッドの定義を確認することができます。

https://github.com/ruby/ruby/blob/v3_2_2/lib/irb/cmd/show_source.rb#L25-L45

show_sourceのソースコードを見ながら、コマンドの実行を試してみました。

## サンプルコード

```ruby
irb> whereami

    1: class User < ApplicationRecord
    2:   validates :name, presence: true, uniqueness: true
    3:   validates :admin, inclusion: { in: [true, false] }
    4: 
    5:   def hoge
 => 6:     binding.irb
    7:   end
    8: end
```

以下の3種類の実行方法があります。

### 1. 「(Const)::(Name)」

```
irb> $ ActiveRecord::Base
```

```ruby:実行結果

From: /Users/kyntk/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.5/lib/active_record/base.rb:282

  class Base
    extend ActiveModel::Naming

    extend ActiveSupport::Benchmarkable
    extend ActiveSupport::DescendantsTracker

    extend ConnectionHandling
    extend QueryCache::ClassMethods

... (一部省略しています)

    include SecureToken
    include SignedId
    include Suppressor
    include Encryption::EncryptableRecord
  end
```

### 2. 「(Class)#(method)」

```
irb> $ Article#user
```

```ruby:実行結果
From: /Users/kyntk/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.5/lib/active_record/associations/builder/association.rb:103

        def #{name}
          association(:#{name}).reader
        end
      CODE
```

### 3. 「(method)」, 「(receiver).(method)」, 「(receiver)::(method)」

```
irb> $ admin?
irb> $ self.admin?
irb> $ self::admin?
```
```ruby:実行結果
From: /Users/kyntk/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activemodel-7.0.5/lib/active_model/attribute_methods.rb:271

        ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
          attr_names.flatten.each { |attr_name| define_attribute_method(attr_name, _owner: owner) }
        end
```

## 感想

どこでメソッドが定義されているのかがわからないときに、メソッドからそのソースコードを確認できるのはとても便利だなと思いました。
ファイルと行数も表示されており、そのファイルも確認できるのも更に便利です。
なぜ情報量の定義に対数(log)が使われるのか

# はじめに
情報量の定義はたくさんありますが、今回はシャノンによる情報量による定義で、ここに対数が出てきます。
確率 $p$ でおこる事象の情報量を $– \log_2 p$ で定義する。

なぜ、情報量の定義に対数(log)が使われるのかを探ってみます。

# 情報理論とは
情報理論とは「情報とは何かを定義し、より良い扱い方を考える学問」で大きく3つのジャンルに分けることができます。

1. そもそも情報量をどのように定義するか、という問題を解決するジャンル
2. 情報をいかに効率よく送受信させるかを考えるジャンル：「符号理論」
3. 送信された情報に雑音が入った時に、どのようにしてノイズを減らすかを考えるジャンル：「誤り検出・訂正符号」

今回は「1. そもそも、情報をどのように定義するか」について説明します。

# 情報量を定義する
定義された情報量は、今後いろいろの計算に”扱いやすい”形式になっており、直感的になるようなものにしたい。

## 情報量の性質1：珍しいことは情報量が多い
ルーレットで賭けをするとします。 ルーレットには 1～40 の番号が振られています。ここでお金を賭けることにします。 
腕のいいカジノディーラーがいて、ある程度の狙い目をコントロールできる力を持っています。
ここには天の声システムがあり、事前にお金を出せば出る目の範囲を教えてくれます。

A：1～20のどれかの目が出た
B：1～10のどれかの目が出た      

https://logics-of-blue.com/information-theory-basic/

### なぜ確率が低い方が情報量の多い情報となるのか
2進数でデータにもとづいて識別しうる状態区分を記録するのに要する符号の桁数を当てはめてみます。
Aは $\dfrac{20}{40} = \dfrac{1}{2}$ なので桁数は 1桁($2^1=2$)、Bは $\dfrac{10}{40} = \dfrac{1}{4}$ で桁数は 2桁($2^2=4$)になります。

このように確率が低いほど桁数が多くなるため、Bのほうが情報量が多いということになります。

区分数 2、コード桁数 1
|状態区分|コード|
|:--|:--|
|A|0|
|B|1|

区分数 4、コード桁数 2
|状態区分|コード|
|:--|:--|
|Ａ|000|
|Ｂ|001|
|Ｃ|010|
|Ｄ|011|

### 未来が確定しているなら情報量は無価値
コイン投げで必ず表が出るように細工されたコインがあり、100億回投げても表しか出ません。
さて、このコインの表裏出現確率は幾つで、情報量は幾つになるでしょうか。

正解は「表の出現確率 100%、情報量ゼロ」です。 
ただし「情報量ゼロ」の条件として、このコインが「表しか出ない」ことが既知である場合という但し書きがつきます。

「常に同じ面が出る」ことが判っていても、その「同じ面」が表か裏かが判っていなかった場合は、1回は実際に投げてみなければ判りませんので、その場合は1ビットの情報量を持っています。
これに対し「常に表が出る」と判っている場合は、投げる前から結果は確定していますので情報量はゼロです。 
「既に知っていること、確定していること」は情報量に含めないのです。

## 情報量の性質2：情報量の加法性
52枚のトランプから無作為に1枚を取り出すとします。この確率は、$\dfrac{1}{52}$となります。
下記の２つの事象を考えます。

A:取り出したカードのスートはハートである
B:取り出したカードの数字は4である

Aの確率は$\dfrac{1}{4}$、Bは $\dfrac{1}{13}$となります。

「取り出したカードはハートの4である」という独立した事象が同時に起こる確率を求める場合、掛け算するので $\dfrac{1}{4} \times \dfrac{1}{13} = \dfrac{1}{52}$ となります。

先程の性質1と同様に2進数で表現すると $\dfrac{1}{4}$ の情報量の桁数は2桁($2^2=4$)、 $\dfrac{1}{13}$ の情報量の桁数は4桁($2^4=16$)、$\dfrac{1}{52}$ の情報量の桁数は 6桁($2^2+2^4=2^6=64$)です。

つまり、確率は掛け算するのですが、情報量は足し算になります。
これは掛け算を足し算にする性質をもっている対数(log)と合致するわけです。

https://qiita.com/yaju/items/af46fd43bb790b1a2f3a

# 最後に
この下書きを書いたのが2年以上前でした。ずっと放置したままだったので見直して公開することにしました。
下記サイトに質問して、著者である馬場真哉さんに回答を頂きました。

>> あと、賭けが当たりやすいというなら、1/2の方が1/4より確率が高いですよね。情報量が多いということは確率が低いわけですから、情報量が多い方が賭けが当たりやすい理屈が分かりませんでした。
>
>「情報量が多いということは、その情報が得られる確率が低い」という意味です。
「賭けが当たる確率」と「その情報が得られる確率」を混同しないように注意しましょう。
[情報理論の基礎～情報量の定義から相対エントロピー、相互情報量まで～](https://logics-of-blue.com/information-theory-basic/)
<まとめ>単体テストの考え方・使い方

単体テストの考え方・使い方を読んだのでまとめます。ちなみにgptと共作です。

https://www.amazon.co.jp/%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E8%80%83%E3%81%88%E6%96%B9-%E4%BD%BF%E3%81%84%E6%96%B9-Vladimir-Khorikov/dp/4839981728


# 基本の理解
単体テストには、古典派(デトロイト派)のアプローチとローマ派のアプローチの2つの方法があります。

古典派のアプローチでは、一連の振る舞いをテスト対象とし、共有依存(dbなどのテスト対象間で依存があるもの)をテストダブルに置き換え、本番のコードが多く使われます。

一方、ローマ派のアプローチでは、コードをテスト対象とし、テスト対象クラスの外部依存関係はテストダブルに置き換え、それ以外の依存を断ち切ります。

両方のアプローチにはそれぞれ長所がありますが、テストでは主にドメインロジックの退行を検出したいため古典派のアプローチが推奨されます。
＊モックしてしまうと本来の振る舞いを見逃す可能性があるため。

# 効果的な単体テストの作成
単体テストを作成する際には、それが開発者だけでなく非開発者にも理解できるようにすることが重要です。なぜなら、開発者でさえ認知負荷に苦しむことがあるからです。

コードではなく、振る舞いをテストしていることを覚えておいてください。したがって、テストメソッドにテスト対象のメソッド名を含める必要はありません。

単体テストの領域では、テスト対象のシステムはしばしば 'sut' (system under test) と呼ばれます。
具体的にはテスト対象のオブジェクトはsutという変数に代入されます。

# 単体テストの優先事項
良いテストはコードの退行を検出し、リファクタリングに耐え、迅速に実行できるべきです。*テストコードを含むすべてのコードは負債です*。したがって、テストはリファクタリングへの耐性を最大化すべきであり、つまり、正しいにもかかわらず間違っているというテスト（偽陽性）を減らすべきです。
リファクタリングの耐性がない(テストが間違った結果を出す)と開発者はテストを信用しなくなりテストの意味がなくなる。

テストにおいて信頼性は重要です。テストが偽陽性になりやすくなると、その信頼性が失われます。

# モックとスタブ
モックとスタブは、単体テストで使用される2種類のテストダブルです。

モックは外部システムとの通信に使用されます。
モックの中でもスパイはテスト対象のシステムの振る舞いを模倣し、検証します。

一方、スタブは内部で使用され、振る舞いを模倣するだけです。戻り値を定義する任意のオブジェクトはスタブです。ただし、スタブをテストしてはならないことを忘れないでください。なぜなら、それらは実装の詳細だからです。

モックは、呼び出し側が特定の振る舞いを期待している管理外のシステム外依存(IDaaSなど)のみ使用すべきです。管理下のシステム外依存(dbなど)はスタブにすべきです。モックにすると詳細を知りすぎてしまい、テストが容易に壊れてしまいます。

ドメインロジックでは副作用を持つ依存は排除されているのでモックは存在しません。
必然的にモックがあるテストは統合テストもしくはe2eテストになります。

# 単体テストの手法
単体テストには主に3つの手法があります：

1. 値ベースのテスト：副作用がない場合に使用します。戻り値をテストします。
2. 状態ベースのテスト：副作用がある場合に使用します。値オブジェクトやヘルパーを使用することで、これらの影響をある程度軽減できます。
3. コミュニケーションベースのテスト：副作用がある場合にも使用します。この手法ではモックを作成する必要があり、かなり複雑になることがあります。

可能な限り、値ベースのテストを選択するようにしてください。これは関数型プログラミングスタイルを採用することで達成できます。

＊副作用: メソッドシグネチャに示されない隠された出力
例)状態の変更、例外など


# リファクタリングと統合テスト
処理速度とドメインの厳守はトレードオフの関係にあります。外部システムへの依存性は一般的にプロセスの始めと終わりに集めるべきです。しかし、ドメインプロセスが停止する可能性がある場合、初期の外部システムプロセス（データベースからの取得など）は冗長になる可能性があります。このような場合、'確認後実行'パターンが有用であるかもしれません。

｜ドメインプロセスが停止するとは

```js
class Usecase {
  exec() {
    user = userRepo.findBy(userId)
    // 色々取得
    hogeRepo.findBy(xxx)
    fugaRepo.findBy(xxx)

    // updateで処理が中断する可能性がある
    user.update()
    userRepo.update(user)
  }
}

// domain
class User {
  update() {
    // メール認証してないユーザーは処理中断
    if (!user.emailVerify) return
    // ...
  }
}

// ------------------------------------------
// 確認後実行パターン
class Usecase {
  exec() {
    user = userRepo.findBy(userId)
    if (!user.canUpdate()) return

    hogeRepo.getBy(xxx)
    // ...
  }
}

// domain
class User {
  update() {
    if (!user.canUpdate()) return
      // ...
   }

   canUpdate() {
     if (!user.emailVerify) return false
     // チェック
   }
}
```

統合テストは通常、外部プロセスとの統合を伴います。これらをモックに置き換えるかどうかは、依存性が制御下にあるかどうかによります。制御下にある場合はそのまま使用し、制御外であればモックに置き換えるべきです。


# 単体テストのアンチパターン
1. プライベートメソッドのテストは避けてください。これらは実装の詳細であり、テストを壊れやすくし、リファクタリングに対する耐性を下げる可能性があります。
1. テストでは常に具体的な値を使用し、テストにドメインが漏洩することを防ぐようにしてください。

# Tips
サードパーティ製のツールをwrapするアダプタを作成する。
利点として必要なクラスや関数のみ公開できる、モック作るのが楽などがあります。
SVGは<img>タグでも危険

SVGにはJavascriptを埋め込むことができるため、`<object>`タグを使ってSVGを表示した場合にスクリプトが実行できてしまいXSS攻撃が成立するというのは有名な話だと思います。

ただ、`<img>`タグを使用した場合においても、依然としてユーザーがアップロードしたSVGファイルを直接表示することは危険です。

以下のSVGファイルを見てください。

```xml
<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
 <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
 <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
 <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
 <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
 <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
```

これは[Chromiumのバグ報告](https://bugs.chromium.org/p/chromium/issues/detail?id=617891)にて上げられていたSVGファイルの中身です。このSVGファイルを読み込むと、ブラウザ関係なく即座にタブがクラッシュします。いわゆるブラウザクラッシャーです。

一行目に思いっきりXMLと書かれていますが、SVGは内部的にXMLフォーマットのため、拡張子をsvgにすると読み込まれます。残念ながらXMLには数多くの脆弱性や問題があり、SVGもそれらの問題を引き継いでいます。

この例では、特にXMLの[Billion Laughs攻撃](https://ja.wikipedia.org/wiki/Billion_laughs%E6%94%BB%E6%92%83)を利用しています。Billion Laughs攻撃について簡単に説明すると、XMLでは他のエンティティをロードすることができるため、エンティティを再帰的にロードすることでメモリ空間を食いつぶし、ブラウザをクラッシュする攻撃手法となります。

この問題を解決するためには、SVGファイルをサーバー上でタイムアウト付きで読み込んだ後にpng画像へ変換したりする方法が考えられますが、過去にはsvgパーサでディレクトリトラバーサルができる脆弱性が合ったりしたため、個人的にはSVG画像は一切受け付けないようにすることがおすすめです。
閉鎖環境にてAmazonLinux2にRPMパッケージをyumでインストールしよう

# はじめに
インターネットに接続できない閉鎖環境で、CloudFormationを実行するEC2を構築する。
Direct Connectを利用したネットワーク環境を想定し、オンプレミスとAWS環境が既に構築されているものとする。

# AWS リソース構築内容
  1. EC2
      - EC2インスタンス (Amazon Linux 2)
      - セキュリティグループ (22ポート開放)
      - IAMロール (AmazonS3FullAccess)
      - キーペア
 
  2. VPCエンドポイント
      - Interface/Gateway (s3)
      - セキュリティグループ (443ポート開放)(Interfaceの場合)
      - プライベートサブネットを指定(Interfaceの場合)
      - ルートテーブルを指定(Gatewayの場合)

  3. S3

# 実行方法

1. RPMパッケージのダウンロード・アップロード
※インターネットが繋がる環境のEC2にて実行し、ダウンロードしたパッケージをS3にアップロードする。

    ```sh:
    mkdir pkg && cd pkg
    sudo yum install ${パッケージ名} --downloadonly --downloaddir=. -y
    ```

2. 閉鎖環境にてダウンロード・インストール
※閉鎖環境のEC2にてS3からパッケージをダウンロードし、インストールを実行する。

    ```sh:
    mkdir pkg && cd pkg
    aws s3 sync . s3://${バケット名}
    sudo yum localinstall --nogpgcheck ./*.rpm -y
    ```

# 参考
[yum を使用して、パッケージをインストールせずにダウンロードだけ行う](https://access.redhat.com/ja/solutions/395763)
インスタンスメソッドとクラスメソッドの違いは？

それぞれオブジェクト指向プログラミングにおいて異なる役割と動作を持つメソッド

## インスタンスメソッド
:::note
クラスのインスタンス（オブジェクト）に対して呼び出されるメソッド
:::
- インスタンス変数にアクセスできる
   →インスタンスの属性や状態を読み取ったり変更したりできる

- インスタンスの特定の状態や属性に基づいて動作する
   →個々のインスタンスごとに異なる結果を生成できる

## クラスメソッド

:::note
クラス自体に対して呼び出されるメソッド
インスタンス変数にはアクセスできない
:::

- 他のクラスメソッドや静的メンバ（静的変数や他の静的メソッド）にアクセスできる

- クラス全体の操作や共有の情報に関連する機能を提供

- インスタンスの特定の状態に依存せず、共通の処理やユーティリティメソッドなどを実行するために使用

### どのメソッドを選択すべきか

**プログラムの目的と要件によって異なる**

- インスタンスメソッド：**インスタンスの特定の状態や属性にアクセスする必要がある場合**

- クラスメソッド：**クラス全体の操作や共有の情報を処理する場合**
Google Cloud Professional認定試験をオンラインで英語で受けて怒られたことまとめ

## Professional Cloud Network Engineer(英語のみ受験可能)をオンラインで受けました
本日(6/14)受けてとりあえず合格。試験後の画面で「pass」と出たので、後日正式なメールが来るはず。

1週間ほど前にProfessional Cloud Database Engineer(こちらも英語のみ受験可能)をテストセンターで受けたのだが、受験環境としてはテストセンターの方がやはり快適だなと感じた。

理由はオンラインだと結構な頻度で試験が中断させられ、その都度3-5分ほど待たされて集中力が途切れるということがあったためである。

以下に中断理由について記載する。

## 中断要因(1) 視線がそれていた
試験問題の下の方を見たり考え込んで下を向いたりするとカンニングを疑われたのか、視線をカメラから逸らすなみたいなメッセージが表示される画面に移行。それが3回ほど続くとオペレーターとのチャットに強制移行されたのだが、オペレーターとの接続待ちに3-5分ほど待たされた。

オペレータからは視線を逸らさないでください。疲れたら目を閉じるのがいいよ。みたいなメッセージが来たので適当に「OK」とか返信すると試験再開できた。

## 中断要因(2) 問題文の英語を声に出して読んでいた
自分は英語が得意ではなく、頭の中で問題文を読み上げるより声に出して読んだ方が理解がしやすかったため声に出して読みながら進めていたのだが、それを続けていると再度オペレーターとのチャットに強制移行され、「問題文を声に出さないでください(黙れ)」というメッセージが来た。

「OK」と適当に返信することで試験再開できた。

## オンライン試験は気をつけよう
テストセンターの場合試験が中断されるようなことはこれまで一度も起こってない。
※(2)は流石にテストセンターで声を出すようなことをしていないので、同様のことをしたら注意されると思うが。

オンライン試験は平日でも業務後に受験できたり、遠くまで行かなくて済むというメリットがある一方で監視の目が厳しいというデメリットがあるので、簡単な試験からオンライン試験を受ける等慣れるための施策が必要であると感じた。
※自分は日本語で受けれる試験は全て日本語で受験したが、Cloud Digital Leader等を英語でオンライン受験して慣れるようにするとかはありかもしれないなと思った。

## Tips(日本語チャットに切り替えてもらう)
英語の試験だと基本的にオペレーターとは英語で会話だが、「I'm not good at English」とかをチャットすると日本語翻訳に切り替えてくれた。
※何回か受けていたら試験を受けるまではスムーズに行くかもだが、上記のように中断した際は何で怒られているのか不明な場合が出てくると思うので、その際は素直に日本語に切り替えてもらう方が焦らなくて済むと思う。
ちなみに(2)は会話ができるか確認するので話せと言われいるかと勘違いしてずっと喋っていたが、日本語に切り替えてもらって初めて黙れと言われていたことに気がついた。

## 自分への鼓舞
とりあえずこれでGoogle CLoud試験全冠まではあと「Cloud DevOps Engineer」と「Machine Learning Engineer」の2つのみ。
AWSは既に全冠とっているので、ダブル全冠目指して気合いを入れていきたい。
Scala3でAkka-HTTPを使うその導入

# 背景
Scala3を使ってWebアプリケーションを作成したい。
Play frameworkは有名だが、Scala2までしか対応していないのと、
Lightbend社は開発から撤退してしまったらしい。

時代はScala3だと僕は勝手に思うから、できる限りScala3を使って
構築したい。

https://qiita.com/kijuky/items/64ea7e1c95ede6799a24

こんな記事もありました。試してみて、悪くはなかったのですが、
Spring bootは基本的な仕様がGradleとKotlin, vue.jsが主流だそう(記事は2021年の話ですが)
仕様上工夫すればできるかもしれないが、なんとなくそれは違うという、違和感を抱えてしまったので、もっと正当な方法はないかと探して、結局決定したのが、Akka-HTTPを使う方法。

Akka-HTTPはAkkaとは独立したサイクルでリリースされるHTTPサーバにもクライアントにも使えるやつ、ということっぽい。

sbtでクロスプロジェクトで構成して、サーバからもクライアントからもAkka-HTTPを使ってくれ、って感じなのかもしれない。

今回は、そんなAkka-HTTPをScala3のプロジェクトに導入したという話。

# 環境
OS: Windows 11
java: OpenJDK 17.0.7
sbt: 1.9.0
Scala: 3.3.0

# 導入方法
https://doc.akka.io/docs/akka-http/current/introduction.html#using-akka-http

ここの通り。

`built.sbt`に`libraryDependency`を追加して、
`main関数`をサンプルコードの通り、にして`sbt run`しただけ。
`localhost:8080/hello`へアクセスして、問題なく表示されたところまで。

``` built.sbt
val AkkaVersion = "2.7.0"
val AkkaHttpVersion = "10.5.2"
libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor-typed" % AkkaVersion,
  "com.typesafe.akka" %% "akka-stream" % AkkaVersion,
  "com.typesafe.akka" %% "akka-http" % AkkaHttpVersion
)
```

``` src/main/scala/Main.scala
/*
 * Copyright (C) 2020-2023 Lightbend Inc. <https://www.lightbend.com>
 */

package docs.http.scaladsl

import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import scala.io.StdIn

object HttpServerRoutingMinimal {

  def main(args: Array[String]): Unit = {

    implicit val system = ActorSystem(Behaviors.empty, "my-system")
    // needed for the future flatMap/onComplete in the end
    implicit val executionContext = system.executionContext

    val route =
      path("hello") {
        get {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
        }
      }

    val bindingFuture = Http().newServerAt("localhost", 8080).bind(route)

    println(s"Server now online. Please navigate to http://localhost:8080/hello\nPress RETURN to stop...")
    StdIn.readLine() // let it run until user presses return
    bindingFuture
      .flatMap(_.unbind()) // trigger unbinding from the port
      .onComplete(_ => system.terminate()) // and shutdown when done
  }
}
```

```
sbt run
```

`Main.scala`にコピーしたコードは`@main`を使っていなかったからScala2で動くコードを想定していたのだろうか。
とりあえずScala3でも動きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477945/ac8b6943-a907-cb18-bf9d-ea7abdc07602.png)

これでサーバサイドについては、Scala3でもなんとかなりそうな雰囲気がしてきました。

# 予定
とりあえず、sbtでクロスプロジェクト(?, 一つのプロジェクトの中に複数のサブプロジェクトがある構成)で、サーバサイドとクライアントサイドを最低限構築したい。(欲を言えば、そこにモバイルアプリのプロジェクトも含めた形にしたいが、とりあえずそれはまだ今じゃない気がしています)

それから、クライアントサイドには、Scala.jsとその周辺を整備していきたい。

そうして、サーバサイド、クライアントサイドともにScalaで書かれたプロジェクトが作成できる。

なぜ、Scalaにそこまでこだわるのか。
ほとんどScalaしか書けないのと、Scalaが好きなのが理由です。

同じような境遇の人に役に立つといいな…
Web技術で利用される通信について（初歩）

## はじめに
Web技術で利用されている通信について、備忘を兼ねて簡単にまとめました。

- リクエスト／レスポンス
- ステートフル／ステートレス
- クッキー
- プロトコル
- ポート番号

## リクエスト／レスポンス

### リクエスト
クライアントからサーバに対する『要求』で、HTTP通信においては以下のような処理がある。

- URLにアクセスする
- 画面内のリンクをクリックする
- 入力フォームから送信する

### レスポンス
サーバからクライアントに対する『応答』で、HTTP通信においては以下のような処理がある。

- リクエストに対するHTMLファイルや画像を返す
- レスポンスは5つのクラスに分類されている
 
## ステートフル／ステートレス
ステートとは「状態」を意味し、ステートフルとステートレスの違いは状態を保持するかしないか。

### ステートフル
- プロトコル：FTP、SMTPなど
- ステートフルは状態を保持し、それを踏まえて次のリクエストを実行する
- 状態によってリクエストに対するレスポンスが変化する
- 状態を保持した通信となるので、ステートレスに比べて負荷が高くなる

### ステートレス
- プロトコル：HTTPなど
- ステートレスは状態を保持しない
- リクエストに対するレスポンスが変化しない
- 状態を保持しない通信となるので、ステートフルに比べて負荷が低い

## クッキー
Webサーバがクライアント（ブラウザ）に預けるファイルのことで、クライアントからWebサーバへ接続すると、Webサーバがクライアント（ブラウザ）に専用のクッキーファイルを作成する。

2回目以降の接続では、Webサーバがクッキーファイルを呼び出すことで、ユーザに適合したコンテンツ表示等を行うことができる。

クッキーには、多くの場合は以下の情報が格納される。

- ID・ユーザ名などの接続情報
- 会員情報
- 一時的に保管する買い物かごの情報
- 訪問回数等の利用環境の情報
- etc
## プロトコルについて

- 異なるコンピュータが互いに通信を行うために取り決められた約束事
- 人との会話に例えると、日本語x日本語の会話は成立するが、日本語x英語の会話は成立しない
- プロトコルを使用することでコンピュータが互いに通信でき、現在の主流プロトコルは「TCP/IP」である

## ポート番号
ポート番号は通信を受け取る待ち受け場所であり、ビルで例えるなら玄関口・搬入口のようなもの。

- ポート番号は0～65535までの数字で表現される
- 0～1023のポート番号はウェルノウンポートと呼ばれ、著名なサービスやプロトコルが利用するために予約されている（HTTPは80番、HTTPSは443番など）
- 同じポートで複数アプリケーションを利用することはできない

## 参考資料
・[HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)
・プロになるためのWeb技術入門(技術評論社)
Semantic Kernel（Python版）でログを出力する

## 環境
- Python 3.10.12
- semantic-kernel 0.3.1.dev0

Google Colabに`!pip install semantic-kernel`でインストールしています。

## 実装
[Semantic Kernel](https://github.com/microsoft/semantic-kernel)では、Kernelの初期化時の`log`引数にPython標準ライブラリのLoggerインスタンスを渡すことで、ログを出力できます。

```python
import logging
import semantic_kernel

OPENAI_API_KEY = "XXXXXXXXXXXXXXXX"
OPENAI_ORG = "XXXXXXXXXXXXXXXX"

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

kernel = semantic_kernel.Kernel(log=logger)

kernel.add_chat_service("c35", OpenAIChatCompletion("gpt-3.5-turbo", OPENAI_API_KEY, OPENAI_ORG))
```

Semantic Functionを定義したり実行する時に、次のようなログが出力されるようになります。

```python
kansai_function = kernel.create_semantic_function("「{{$input}}」を関西弁にすると、", max_tokens=200, temperature=0)
```

```:出力
DEBUG:root:Extracting blocks from template: 「{{$input}}」を関西弁にすると、
```

実行時には、テンプレートに変数が埋め込まれた状態のpromptを確認したりできます。

```python
output = kansai_function("本当に使っていないのですか、いけません。")
```

```:出力
DEBUG:__main__:Rendering string template: 「{{$input}}」を関西弁にすると、
DEBUG:__main__:Extracting blocks from template: 「{{$input}}」を関西弁にすると、
DEBUG:__main__:Rendering list of 3 blocks
DEBUG:__main__:Rendered prompt: 「本当に使っていないのですか、いけません。」を関西弁にすると、
```

なお上記の実行結果は次のようになります。

```python
print(output)
```

```:出力
「ホンマに使ってへんのか、アカンで。」
```

### loggerを指定しなかった場合
loggerを明示的に指定しなかった場合デフォルトでは`NullLogger`という何もしないloggerがセットされるため、何も出力されません。

https://github.com/microsoft/semantic-kernel/blob/398982877d63d0fdc26a46f640ee6db739d2395e/python/semantic_kernel/utils/null_logger.py#L6

### openaiライブラリの出力なども含めて確認する
`openai`という名前のロガーのレベルを変更することで、実際にOpenAI等のAPIへ飛ばしているリクエストを合わせて確認できます。またrootロガーのレベルを変更することで、他のログ出力もまとめて変更できます。

```python
import logging

# logging.getLogger().setLevel(logging.DEBUG)       # rootロガーの設定
logging.getLogger('openai').setLevel(logging.DEBUG) # openaiログ設定
```

```python
output = kansai_function("本当に使っていないのですか、いけません。")
```

```:出力
DEBUG:openai:message='Request to OpenAI API' method=post path=https://api.openai.com/v1/chat/completions
DEBUG:openai:api_version=None data='{"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "\\u300c\\u672c\\u5f53\\u306b\\u4f7f\\u3063\\u3066\\u3044\\u306a\\u3044\\u306e\\u3067\\u3059\\u304b\\u3001\\u3044\\u3051\\u307e\\u305b\\u3093\\u3002\\u300d\\u3092\\u95a2\\u897f\\u5f01\\u306b\\u3059\\u308b\\u3068\\u3001"}], "temperature": 0, "top_p": 1.0, "presence_penalty": 0.0, "frequency_penalty": 0.0, "max_tokens": 200, "n": 1, "stream": false}' message='Post details'
（省略）
```

厳密にはSemantic Kernelと関係は無い話ですが、必要に応じて上記を合わせて設定することで確認がしやすくなると思います。
GitHubで過去のバージョンを取得する方法について

## ①ローカル環境にリポジトリをCloneする

```
$ git clone git@github.com:{{YOUR-USERNAME}}/{{YOUR-REPOSITORY}}
```

## ②過去のバージョンのSHAを取得する

GitHub上のコミット履歴から戻したい箇所のSHAを取得します。

![スクリーンショット-2023-03-18-15.43.41 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552607/3e54f952-12dc-12c1-fe27-6fbd785e86e1.jpeg)


## ③ローカルのリポジトリを過去のバージョンに切り替える

```
$ git checkout {{SHA}}
```
ダイクストラ法の亜種

ダイクストラ法 (Dijkstra algorithm) はネットワークの最短経路を計算するアルゴリズムです。グラフ、始点と終点、各枝の重み (長さなど) が与えられたとき、始点から終点までの経路の中で枝の重みの総和が最小となるものを見つけます。

一方、二値の行列データに対するエネルギー地形解析 (energy landscape analysis) では非連結性グラフ (disconnectivity graph) の計算にダイクストラ法の亜種を使います ([こちらの論文参照](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5434078/))。枝でなく頂点の重みを使うことと、総和でなく最大値を最小化することが違います。

一般に、最小化する対象として以下の4つが考えられます。
* 枝の重みの総和 (元のダイクストラ法)
* 枝の重みの最大値
* 頂点の重みの総和
* 頂点の重みの最大値

## 疑似コード

$V$ を頂点集合、$E$ を枝集合、$w(e)$ を枝 $e$ の重み、$w(v)$ を頂点 $v$ の重み、$s$ を始点、$c(v)$ を頂点 $v$ の暫定コスト、$Q$ を未調査の頂点集合とします。終点は指定せず全頂点に対して計算することにします。簡単のためグラフは連結と仮定します。重みの範囲は以下のように設定します。

| 目的関数 | 重みの範囲 |
|---------|--------------------------------------|
| 枝の重みの総和 | $w(e)\geq 0$ |
| 枝の重みの最大値 | $w(e)\in\mathbb{R}$ |
| 頂点の重みの総和 | $w(v)\geq 0$ |
| 頂点の重みの最大値 | $w(v)\in\mathbb{R}$ |


$c(v) \leftarrow \infty,\quad \forall v\in V$
$c(s) \leftarrow 0$ (枝の重みの場合) or $w(s)$ (頂点の重みの場合)
$Q\leftarrow V$
**for** $Q\neq \emptyset$
$\quad$ $i \leftarrow \arg\min_{k\in Q} c(k)$
$\quad$ $Q\leftarrow Q\setminus \\{i\\}$
$\quad$ **for** $j \in \\{k\mid e_{ik}\in E\ \wedge\ k\in Q \\}$
$\\qquad$ $\tilde c(j) \leftarrow$ 頂点 $i$ を通る場合の頂点 $j$ のコスト
$\\qquad$ $c(j) \leftarrow \min(c(j), \tilde c(j))$

頂点 $i$ を通る場合の頂点 $j$ のコストは以下の通りです。
| 目的関数 | 頂点 $i$ を通る場合の頂点 $j$ のコスト |
|---------|--------------------------------------|
| 枝の重みの総和 | $c(i) + w(e_{ij})$ |
| 枝の重みの最大値 | $\max(c(i), w(e_{ij}))$ |
| 頂点の重みの総和 | $c(i) + w(v_j)$ |
| 頂点の重みの最大値 | $\max(c(i), w(v_j))$ |

## 最適性の説明

命題P「調査済みの頂点のコストは確定値である」を帰納法で示します。

最初に入力頂点 $s$ が調査されます。枝の重みを使う場合は $c(s)=0$、頂点の重みを使う場合は $c(s)=w(s)$ です。いずれの場合も確定値なので、命題Pが成り立ちます。

次に、ある時点で命題Pが成り立っていると仮定します。次に調査する頂点、つまり、未調査の頂点の中で暫定コストが最小のものが本当に確定値といえるかを考えます。

一般に、ある頂点の暫定コストが更新される可能性があるのは、その頂点の隣接頂点を調べたときだけです。さらに、ある時点で命題Pが成り立ち、かつ、上記のアルゴリズムを使っている場合 (全ての調査済み頂点の全ての隣接頂点の暫定コストを更新済みである場合) は、調査済みの頂点を再調査しても何も更新されないはずです。従って、更新される可能性があるのは未調査の隣接頂点を調べたときだけです。

ある時点において未調査の頂点 $i$ を調べたときの、それに隣接する未調査頂点 $j$ の暫定コストの更新について考えます。上の疑似コードの最後の行に着目すると、4つのパターン全てで
$$\tilde c(j) \geq c(i)$$
が成り立ちます。従って、
$$c(j) \leftarrow \min(c(j), \tilde c(j)) \geq \min(c(j),c(i))\geq \min_{k\in Q} c(k)$$
が成り立ちます。つまり、未調査の頂点のコストは未調査の頂点の最小コストより小さくはならないので、最小コストのものは確定値となり、題意が示されました。
二重否定について調べました

ある日仕事でコードを読んでいたら以下みたいなコードがあり

```js
 { foo: !!bar }
```
`!!`って何？と思ったので調べてみました。

## 二重否定とは

> 複数の否定演算子を連続して使用することで、明示的にあらゆる値を対応する論理型プリミティブに変換することができます。

参考 [mdn web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_NOT#%E4%BA%8C%E9%87%8D%E5%90%A6%E5%AE%9A_!!)

論理型プリミティブ…？？？

## 論理型プリミティブ

まずプリミティブとは

> JavaScript において、プリミティブ (primitive、プリミティブ値、プリミティブデータ型) はオブジェクトでなく、メソッドを持たないデータのことです。 6 種類のプリミティブデータ型があります。
文字列
数値
長整数
論理値
undefined
シンボル
null
多くの場合、プリミティブ値は、その言語実装の最下層にて直接的に表現されます。

参考 [mdn web docs](https://developer.mozilla.org/ja/docs/Glossary/Primitive)

文字列だったり数値や論理値（真偽値）などオブジェクト以外をプリミティブ値と呼ぶという事がわかりました。
つまり、論理型プリミティブというのは`true`か`false`を表しています。
## 参考動画とコード
二重否定については以下の動画が分かりやすかったです。

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


動画の内容を真似してコードを書いてみました。

```js
let myName = ""

const hisName = !!myName

console.log(hisName) //false

myName = "HANAKO"

const herName = !!myName

console.log(herName) //true

const herName2 = myName

console.log(herName2) //HANAKO
```
そして二重否定`!!`は[Boolean関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean)と同じ働きをしているという事も理解しました。
以下の記事も参考にして、少しずつですがまた一つJavaScriptに関して成長できた様な気がします。

https://qiita.com/ta1fukumoto/items/effaa42cd296a2648d41
【Python】Wordcloudによる文章の可視化

**ChatGPTに適当にアメリカ経済について作成してもらった文章をワードクラウド化**
![Word_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/392c5c52-7f6f-619c-a3c6-a8ff5eeea41e.png)

### Pythonコード全文

処理の流れは以下のよう
1. 対象のテキストから、不要な文字や記号を削除・置換
1. ユニコード正規化してエンコードを統一する
1. 形態素解析して、単語ごとに取得
1. 頻出数で単語を重みづけして可視化

```Python
# MIcrosoft Visual Studio をインストール
# https://visualstudio.microsoft.com/ja/vs/community/

import re

with open('sample.txt', encoding='utf-8') as f:
    text = f.read().replace('\n', '').replace(' ', '')
print(text)

#変数text中に格納されたアンケート内の不要な文字や記号を削除する。
#re.subで正規表現を使った文字列の削除。
text = re.sub('\u3000', '', text)
text = re.sub('・', '', text)
text = re.sub('「', '', text)
text = re.sub('」', '', text)
text = re.sub('（', '', text)
text = re.sub('）', '', text)
#re.subで正規表現を使った文字列の半角空白への置換。
text = re.sub('\n', ' ', text)
text = re.sub('\\n', '', text)
text = re.sub('\\n', ' ', text)

#ユニコード正規化
import unicodedata

text_sample = unicodedata.normalize('NFKC', text)
print('UNICODEの正規化後：{}'.format(text_sample))

# janomeを使った形態素解析
from janome.tokenizer import Tokenizer

#対象のテキストをtokenizeする
t = Tokenizer()
tokenized_text = t.tokenize(text)

words_list=[]
#tokenizeされたテキストをfor文を使ってhinshiとhinshi2に格納する。
for token in tokenized_text:
    tokenized_word = token.surface
    hinshi = token.part_of_speech.split(',')[0]
    hinshi2 = token.part_of_speech.split(',')[1]
    #抜き出す品詞を指定する
    if hinshi == "名詞":
        if (hinshi2 != "数") and (hinshi2 != "代名詞") and (hinshi2 != "非自立"):
            words_list.append(tokenized_word)

words_wakachi=" ".join(words_list)
print(words_wakachi)

# ワードクラウドによる頻出単語の可視化
from wordcloud import WordCloud
import matplotlib.pyplot as plt

#日本語のフォントを指定する
font = 'ipag.ttf'

#意味なさそうな単語（ストップワード）を除去する。
stopWords = ['ので','そう','から','ため','自分', '投資','運用']

#WordCloudを表示
word_cloud = WordCloud(font_path=font, width=1500, height=900,
                        stopwords=set(stopWords),min_font_size=5, 
                        collocations=False, background_color='white', 
                        max_words=400).generate(words_wakachi)
figure = plt.figure(figsize=(15,10))
plt.imshow(word_cloud)
plt.tick_params(labelbottom=False, labelleft=False)
plt.xticks([])
plt.yticks([])
plt.show()
figure.savefig("Word_Cloud.png")
```

## まとめ
今回は、Wordcloudを用いて、アンケートなどの文章の頻度を可視化する方法を紹介した。
CORS問題についてまとめてみた

# CORS ERROR

よく問題になるのは、ローカルで開発している際に

フロントとバックでポートが異なりフロントからバックにAPIを叩きに行ったらcors errorがでる。

# CORSって？

基本は同じオリジンからじゃないとアクセスしても情報を受け取れない。

オリジンはプロトコルとポートとドメインのこと。

しかし、APIを外に公開する必要があると、同一オリジンからじゃないとダメなのは問題になる。

そこで異なるオリジンからでもアクセス可能にしようよって話がCORS。

# 実装方法

CORSを実装するにはリクエストとレスポンス両方のヘッダーにCORSするという了承を載せないといけない。

そのためにフロントではheaderに

```jsx
const axiosInstance = axios.create({
    baseURL: "http://localhost:8080",
    headers: {
      'Content-Type': 'text/plain',
      "Access-Control-Allow-Origin": "http://localhost:8000",
    },
  })
```

みたいな感じ。(バックが8080でフロントが8000。8000からのリクエストは許して下さい、みたいな感じでリクエストヘッダに付与。)

バックでもheaderにcorsOKをレスポンスヘッダーに追加する。(ここでは8000からのリクエストにはOKを出せ見たいな感じで、Access-Control-Allow-Originがレスポンスヘッダに付与されて返される)

# Cookieなどの資格情報を付与してCORSしたい

フロントは`'Access-Control-Allow-Credentials' :'true'`

を追加すればOK。

同じようにバックにもレスポンスヘッダにAccess-Control-Allow-Credetials＝trueを付与してあげる設定をしてあげる。

注意はバックでAccess-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methodsでワイルドカードが使えなくなる。

# シンプルリクエストとそうでないリクエスト

シンプルリクエストになる条件は

- リクエストメソッドが HEAD, GET, POST のどれか
- リクエストヘッダが許可されてるものだけ
- リクエストヘッダの Content-Type は application/x-www-form-urlencoded, multipart/form-data, text/plain のどれか
- リクエストに使うどの XMLHttpRequestUpload オブジェクトにもイベントリスナがついていない
- リクエストに ReadableStream を使っていない

参照:https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#Examples_of_access_control_scenarios

シンプルリクエストの条件を満たさない（Content-Typeがjsonとかmethodがdeleteとか）場合は

プリフライトリクエストとなる。

プリフライトリクエストはCORS確認のためにOPTIONメソッドで送られるリクエスト。

実装方法は

バックのほうでCORSでOPTIONメソッドを許可してあげる必要がある。

レスポンスヘッダーにAccess-Control-Allow-MethodsでOPTIONSメソッドを加えてあげる必要がある。

これでも注意はバックでAccess-Control-Allow-Origin等でワイルドカードが使えなくなる。

# 参考

コードを交えて詳しく教えてくれます。

https://zenn.dev/syo_yamamoto/articles/445ce152f05b02

https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34

http://var.blog.jp/archives/81653678.html

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#Examples_of_access_control_scenarios
3.便利ツール導入

**3.便利ツール導入**

タイル（画像）を作成し、画面に表示するためタイルを作成する手順をまとめていきます。

・目次
1.GBTDダウンロード&配置
2.GBTDを使用してタイル作成
3.タイルを表示


<br>
<br>
<br>
<br>

**1.GBTDダウンロード**
　以下の記事を参考にしました！
　配置場所は任意

https://qiita.com/blackpman/items/12258e6a9ee9f2d032de

<br>
<br>
<br>

**2.GBTDを使用してタイル作成**

GBTD.EXEを起動し、基本操作を確認してみる

メニュー
└File
　└Open・・・一度作成済みの".gbr"ファイルを開く
　└Save・・・保存（タイル加工情報）
　└Save As・・・新規ファイルで保存（タイル加工情報）
　└Reopen・・・一度作成済みの".gbr"ファイルを開く（開きなおし）
　└Export・・・GBに表示する用のソースファイルを出力
　└Export to・・・新規でソースファイル出力
　└Import from・・・ファイル取り込み（拡張子不明　そのうち調べる）
　└Exit・・・アプリ終了

└Edit
　└Undo・・・直前操作を取り消す
　└Cut tile・・・GBTDを2画面開いているときにカットし、ペーストできる
　└Copy tile・・・同上
　└Paste tile・・・同上
　└Split Copy・・・16*16のタイルを分割してコピーできる
　└Split Paste・・・同上
　└Split optins・・・分割時のオプション（2枚目を下にするか右にするか）

└Design
　└Pen・・・ペン（線画）
　└Flood fill・・・バケツ（塗りつぶし）
　└Flip Vertically・・・左右反転
　└Flip Horizontally・・・上下反転
　└Rotate clockwise・・・時計回り90度
　└Scroll Left・・・左に移動
　└Scroll Right・・・右に移動
　└Scroll Up・・・上に移動
　└Scroll Down・・・下に移動
　└Clear tiles・・・クリア
　└Flip colors・・・？？？

└View
　└Tile size・・・タイルサイズ変更（8*8,8*16,16*16,32*32）
　└Tile count・・・タイル数をカウント（何に使う？）
　└Simple・・・右側のプレビュー画面非表示
　└Grid・・・ます目非表示
　└Nibble markers・・・点表示（ます目非表示に見える）
　└Auto update・・・アップデート？？（ファイル更新されたら反映？？）
　└Color set・・・色変更（プリセット）
　└Palettes・・・色変更
　└Set bookmark・・・ショートカットをカスタマイズ？？
　└Goto bookmark・・・ショートカットをカスタマイズ？？

└Help・・・ヘルプ（開けない）



Export to時の設定内容

Filename・・・ファイル名（ラベル名と同一のほうが分かりやすい）
Type・・・ファイルタイプ（拡張子）　GBDK　C　FileでOK
Label・・・プログラム内で使用する関数名的なもの
From To・・・複数のタイルを作成した場合何個まで出力するか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476538/4f644983-9115-8478-a2e4-45325b9441d9.png)

Include palette colors・・・オン　色の引継ぎ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476538/592455cd-f4bd-9134-ec01-a10f6a0f22d3.png)


<br>
<br>
<br>

**3.タイルを表示**
以下のコードを"main.c"に記載しタイルを表示させる


```main.c
#include <gb/gb.h> 
#include <stdint.h>  //ライブラリ参照
#include "tile.h"

UINT8 p_xy[2] = {0};// [x, y] が入る

void main(){
	set_sprite_data(0, 1, tile); //TileLabelのタイルを登録
	set_sprite_tile(0, 0); // スプライト番号 0 にタイル 0を設定

	//タイル0を表示する位置決め
	p_xy[0] = 10 << 3; //x軸160
	p_xy[1] = 10 << 3; //y軸16
	move_sprite(0, p_xy[0], p_xy[1]); // 0 番目のスプライトを移動
	
	SHOW_SPRITES; // スプライトの表示を ON
```
◇解説
>#include <gb/gb.h> 
#include <stdint.h>  //ライブラリ参照
#include "tile.h"
→GBTDで作成したタイルのソースファイル（tile.h）を記載

>UINT8 p_xy[2] = {0};// [x, y] が入る
→配列を定義

>	set_sprite_data(0, 1, tile); //タイルを登録
	set_sprite_tile(0, 0); // スプライト番号 0 にタイル 0を設定
→タイルをスプライト0番目に定義

>	p_xy[0] = 10 << 3; //x軸160
	p_xy[1] = 10 << 3; //y軸16
→配列に初期表示場所のX,Y軸の値を入力

>	move_sprite(0, p_xy[0], p_xy[1]); // 0 番目のスプライトを移動
→0番目のスプライト（タイル）を配列の値（X,Y軸）の場所に表示

>	SHOW_SPRITES; // スプライトの表示を ON
→スプライトを表示


コンパイル結果（large_mapサンプルに表示させてます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476538/0b54bc66-60b8-2416-aa25-2a8d8781f2b9.png)


<br>
<br>
<br>

以上！
次回は背景を動かしてみよう！！
あなたは自分の実装コードを口頭で自信持って説明できますか？

元教員のエンジニア2年目です。
最近は腰痛と闘いながら業務に励んでおります。

ちょっと大変だったことを徒然書き示しておきます。


## 既存のコードが一番の先生
現在Laravelの案件に入って５ヶ月ほどが経ちました。
初Laravelでキャッチアップもほぼない状態でアサインされました。
ただ以前やっていたJavaに比べ、個人的にはキャッチアップコストがかからず、「思うように動く実装」に持っていくのはそこまで大変ではなかったです。

ただ、あくまで**動く実装**に持っていくだけであって、そこからが試練でした。

前述した通りほぼキャッチアップがない状態でアサインされたため「既存のコードが一番の先生」


しかし、
- 処理が不明瞭
- 責務がぐちゃぐちゃ
- PHPDocがない
- 型定義がちゃんとされてない
- スパゲッティコード


等不十分な箇所がたくさん。

そのため、**一番の先生**を参考にして行った実装だと修正依頼がたくさん・・・・


**「何を参考にすればええの？」**

と独り彷徨っておりました。


現在はほんの少し慣れた気がするのですが、自分みたいな彷徨い人を作らないようにするため書き示しておきます。


## 感覚で書くな


 **「なんとなくこうやって書きました」**

と感覚的に済ますことも可能です。
それで動いちゃったりするのですから。
しかし後で他人が見直したときに必ず疑問が生じるはずです。

私がいた学校現場での昔話です。
学校の授業で「感覚的に〇〇だから」っていう説明ばかりしている先生の授業は平均点低かったです。
きっと「あなたの感覚と私の感覚は違う！」ってなるのでしょう。

**書いたことについてちゃんと理由とともに説明できること**

これが重要だと思います。

## チームで必要なこと

１人１人が自信を持って書いたコードでも、考え方の差から統一感のないものになる可能性があります。
それでは私みたいな経験浅い新人がアサインされたとき

**「どの書き方が正解？？」**

となってしまいます。
そのため

**チーム内で書き方のルールが統一されていること**

これが必要ではないかと思います。
このルールは「なんとなくこう思うから」と**推量**ではなく「この理由だから」と**断定**で説明できるルール作りにより、統一感が出るのではと思いました。

## 理想のコードを目指して

理想のコードってなんだろう？と考えたとき、口頭でちゃんと説明できるものだと思います。
決して「なんとなくこうなっっていて・・・・」ではなく、
１メソッドが短編小説みたいな感じですらっと読めるのがいいですよね。

わからないことが多い中の作業はどんな作業であっても、誰にとっても大変なものです。
「動けばよし」
そんな風に思うかもしれません。
しかし誰かの為になると考えれば、ちょっと前向きになれるのではないでしょうか？

そんな実装ができるように日々精進します。
Yarnとは?

# Yarnとは?


現在`Ruby`及び`Rails`で学習を行っているため、`Ruby`に置き換えながらまとめます。


## yarnとは？

- `Node.js`上で動く`JavaScript`のパッケージマネージャー
- 2016年にFaceBookが公開した
- `Ruby`における`Rundler`
- `Yarn`と同様の機能を持つパッケージマネージャーとして`Npm`がある。


## そもそもパッケージマネジャーとは？

ソフトウェア開発において、依存関係の解決やパッケージの管理を補助するツール

コンピュータに何のソフトウェアがインストールされたかを記録し、新しいソフトウェアのインストール・新しいバージョンへのソフトウェアの更新・以前インストールしたソフトウェアの削除を容易に行えるようにするプログラム

- `JavaScript`における`Node.js`
- `Ruby`における`Gem`
エンジニアというお仕事

**これはポエムです、あまり本気に考えないでね**

## 自己紹介 -今北産業- 

- 駅弁大学工学部電子情報工学科卒業→東京の地名の付いていない大学の独立大学院修了
- 組み込みの世界に飛び込むも失敗しハロワ公認プー太郎を半年経験
- 現在はとある国研に派遣され何でも屋をこなす会社員(齢44)

まずは･･･、

# そもそもITエンジニアってなんぞね

ITエンジニアって最近多くないですか？じゃあエンジニアって何だろうって考えたときにひとつの答えを見ました。
それがこれで、エンジニアってこういう定義らしいです。

https://note.com/rdlabo/n/n36a85584edd5

これに当てはめると、ITエンジニアは今名乗っている人の何分の一もしくは何十分の一になるのではないかと思います。うーん、ステキなことだ。

たとえば、お医者さんっていますよね？免許もないのに名乗るのはブラック○ャック位ではないでしょうか。
認定試験があって、それをパスしないと「エンジニア」が名乗れなくて、それを偽ると罪になって、
エンジニアも[JABEE]でなくてもいいから認定機関で認定されている人だけが名乗って良いって法律できないかなぁ･･･、って最近思っています。

[JABEE]:https://jabee.org/

## ITエンジニアのキャリアパスって

ちょうどお医者さんの話が出たから私のイメージで感じているお医者さんの例でITエンジニアのキャリアパスを考えてみましょう。

日本国内には内科・外科・皮膚科・精神科など様々な科がありますね、特に精神科は精神保健指定医という肩書きがありますね。それを取るのは修業が大変だと思います。

https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/AA10K-seishinhokenshiteii.html

それと同様に、(狭義の)ITエンジニアの皆さんはもっと専門性を持つべきだと思います。別にお医者さんに限った話ではないです。
例えばお医者さんではなくても、博士の皆さんについて考えてみましょう。
博士の皆さんはそれぞれ専門を持っています。例えば私は並列処理、特に並列化コンパイラやそれを用いた支援ツールの専門家として5年間博士前期・後期課程を生きていました。そして、審査員を納得させてそれでようやく「博士」の称号を得るわけです。それは今となっても変わらず、職場では並列化のエキスパートとして名が通るようになっています。

私はこれが得意だ、これが好きだと言うものに必死になって取り組み、それで飯を食うようになれば一人前のエンジニアとして大成できるわけです。

専門化になってようやく一人前になれるし、「この分野は素人なのですが」攻撃ができるようになるわけです（違。

https://www.itmedia.co.jp/news/articles/1703/01/news147.html

(広義の)ITエンジニアのみなさんは、今からでも遅くはありません。きちんとした教育機関でエンジニアリングを学ぶべきです。
で、きちんと学を修めてからエンジニアを名乗りましょう。
キャリアパスを考えるのはそれからです。お医者さんは国家試験に合格するだけでなくきちんとその専門的な学問を学ぶ課程を経ないと取れないのと一緒で、エンジニアもきちんと教育機関で学んで資格を取ってはじめてエンジニアを名乗るべきです。

でないと、**本物のエンジニアに申し訳ないと思います。**

## 専門的な職場で専門的な仕事を･･･

私は運良く3カ所目の職場で落ち着いています。組み込みの世界ではクビを経験していますし、2個目の職場は半年しか持ちませんでした。今の職場はHPCを生業としている会社で、私の専門性と見事に一致しています。だから長続きしいているともいえます。ですからキャリアパスで悩んでいるかたは一度自分の専門をもう一度振り返ってそれに合った職場を探すべきだと思います。

以上！！
日本企業の財務諸表をグラフ化

日本企業の財務諸表を比例縮尺グラフで表示するサイトを作りました。

https://jp-zaimu.com/

このように貸借対照表（B/S）と損益計算書（P/L）をグラフで表示することができます。

![スクリーンショット 2023-06-14 222200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148181/71b10550-233c-bf98-4a99-017cd75fb747.png)



# 開発経緯
2019～2022年のコロナ感染に脅威を感じていた日々、ニュース番組で映し出されていた感染者グラフでデータの可視化に興味を持ちました。個人開発でも何かデータの可視化に取り組めるテーマはないかと思案していたところ、ちょうど簿記の3級を勉強していたタイミングでもあったので財務諸表の比例縮尺グラフを作ることにしました。サイトを作るうえで以下の3冊から知見や着想を得ることができました。


・荻原, 和樹. データ思考入門. 日本, 講談社, 2023.

https://bookclub.kodansha.co.jp/product?item=0000374513

・山根, 節. 「儲かる会社」の財務諸表: 48の実例で身につく経営力・会計力. 日本, 光文社, 2015.

https://www.kobunsha.com/shelf/book/isbn/9784334038816

・財務諸表の見方〈第14版〉. N.p., 日経BP, 2023.

https://bookplus.nikkei.com/atcl/catalog/23/01/13/00593

# 設計
当初の設計メモ。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148181/3cb86038-4339-fdae-3980-c09fe1eb8d34.png)


# 仕様
財務諸表の情報は金融庁が運営するEDINETよりダウンロードしたXBRL形式のファイルを元にしています。技術的にはMERN（MongoDB、Express、React、Node.js）を利用、バッチ処理はPythonを主に利用しています。フロントエンドから参照されるDBは軽量なsqlite3を採用しました。構成イメージは以下の通りです。

・全体構成
![kousei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148181/73c57022-9e38-3695-3bf7-72b37933dada.png)

・DB構成
![db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148181/14aec88d-5201-41d4-64f7-ace0667ce277.png)

# 補足
開発前からわかっていたことなのですが、一部の企業は財務諸表データが取得できません。これは企業の業種によって勘定科目が異なるためで、特にP/Lにおける「売上高」と「売上原価」のデータが取得できません。たとえば、業種ごとに以下のような勘定科目の違いがあります。

小売業
　・売上高
　・売上原価

建設業
　・完成工事高
　・完成工事原価

保険業
　・営業収益（または経常収益）
　・営業費用（または経常費用）

苦肉の策として財務諸表の金額を表示する箇所は、input タグで入力可能な項目とすることにしました。取得できない値があった場合、利用者が自身で入力できるようにするためです。

# まとめ
React とNode.js の学習に時間を要しましたが、日々の業務の合間に楽しく開発することができました。記事をお読みいただきありがとうございます。
非エンジニア上司に対する3つの攻略法

## はじめに

この記事はこれまで私がIT企業での15年ほどの社会人経験の中で感じてきた体験談を元に記載していますのであくまで参考としてお受け取りください。
また私は「非エンジニアの上司」側の立場での経験がほとんどであるので、逆説的にエンジニアのみなさんの参考になればと思い記事を書いております。

みなさん、会社の組織の中で「非エンジニアの上司」にあたったことは無いですか？
- 前提知識が違うためコミュニケーションが難しい
- 技術の事を分かってないのにちゃんと評価してくれてるのだろうか
- 技術や開発に関する悩みや相談が出来ない
- 技術的な部分で上司から学ぶことが出来ない

などなど
日々思うこともあるのではないでしょうか。

そのような中で、「非エンジニア上司」側からの経験から、どのようなスタンス、コミュニケーションをとることが効果的なのかをいくつかご紹介したいと思います。



## 非エンジニア上司の攻略方法

**目次**

* [①専門用語はあえて使う](#専門用語はあえて使う)
* [②定量的な伝え方を意識する](#定量的な伝え方を意識する)
* [③エンジニアが得意なことを巻き取ってあげる](#エンジニアが得意なことを巻き取ってあげる)
* [最後に](#最後に)


## ①専門用語はあえて使う

**注意！これは上司との関係性や上司の心構え次第なところがあります。**


開発に関する専門用語ありますよね。
エンジニアからすると当たり前の用語でも多職種からすると知らない、または単語は分かるけど何か分かっていない。そういうことあると思います。

例えば私が社会人2年目くらいのことにエンジニアと仕事をした際に「デプロイ」という言葉が出ましたが何を指しているかわかりませんでした。
数年前にSREチームと話をしていたときに「SLOを◯◯%に〜」のような話が出たときに何のことかわかりませんでした。

基本的には他職種にも分かる言葉に置き換えて話すのが丁寧であるとされていることもありますが、個人的にはそれをやっているとお互い理解し合わないままで終わると思っています。

なので、私は基本的に「専門用語は使ってもらって良い。その変わり分からないときに聞くから教えて欲しい」というコミュニケーションをとっています。
もちろん自分でも調べます。会議中にこっそりググったりよくしています。

上司との関係にもよりますがあえて普段使っている専門用語を普段のコミュニケーションに入れていくことで、上司側の理解を深める、上司が何を知らないか？を発見すること出来る、そういう感覚で取り入れてみるのはオススメです。

※「こいつ何も知らないな〜」とか「全然勉強してないな〜」とかは一旦心に留めておいて優しく教えてあげましょう。


## ②定量的な伝え方を意識する
これはどの職種においても職種を跨ぐ際にはもっとも効果的な話かと思います。
同職種同士であれば、共通理解、共通知識があるため定性的な話でもスムーズにコミュニケーションが取れることもあると思います。

一方で異業種間の場合、それが無いことによってうまく伝わらない（というよりも温度感が同じにならない）ことが多いように思います。
なので、基本的には誰から見ても同じ指標である定量的な数字を交えて置き換えて話すと効果的です。

例えば、技術的な課題に対して上司に報告をするとき。
「◯◯のシステムが△△のような状況なのでリスクが高く、対処するための人員が必要」と伝えるとします。
これがエンジニア同士であれば◯◯のシステムがどういうものかを理解しており、△△のような状況がどれくらいヤバいのかをある程度感覚的に理解が出来ます。

しかし非エンジニアの上司からすると同じ感覚での理解が難しい場合があります。

なので
「◯◯のシステムが△△のような状況なのでリスクが高く、このままにするとxx円（または開発の遅延日数等）の損害が出る可能性があります」
のような伝え方をしてみます。

ここの「xx円の損害〜」についてはすごく正確では無くてもある程度概算でも良いです（もちろん精緻な方がベスト）

このような定量的な話を入れ込むことで、そこから会話に発展が生まれます。

**上司：「このxx円というのはどういう算出をしたのかな？」**
**エンジニア：「◯◯のシステムが不具合を起こした場合にサービスの稼働が□□止まったと仮定した場合です」**
**上司：「サービスの稼働が止まる不具合とは具体的にどういう場合に起こる？その可能性は？」**
**・・・などなど**

こういうコミュニケーションが発生して相互に理解を深めていくことで、相互にリスクに関する解像度を高めていき、上司側の判断軸も共有したうえで対応について結論をつけることが出来ると良いと思います。

## ③エンジニアが得意なことを巻き取ってあげる
これは非常に効果的な場合があります。
例えばSlackなどの設定、社内サーバの権限設定、集計ツールの設定などなど。
あえてエンジニアがやる仕事では無いけれど基本的にはエンジニアの方が得意（早い）な仕事ってありませんか。
上司からするとそういうことをさらっとやってくれるエンジニアはとてもありがたいです。

そうすると、逆にエンジニアが苦手な社内調整（あくまで例なので人によります）などを代わりにしてあげようという気持ちが芽生えます。上司と部下もあくまで人間対人間なので、助けてもらったことは今度は自分が助けてあげようと思うものです。

**例え上司部下であっても「強み同士のギブアンドテイク」が成立することが最も効率が良いはずです。**

- **上司がやれば10かかる仕事をエンジニアが5の労力でやる**
- **エンジニアがやれば10かかる仕事を上司が5の労力でやる**

**そうすれば本来20かかる仕事が10で出来るかもしれません。**

そして、この労力を技術力で最大限まで小さくすることが出来るのはエンジニアの強みの1つだと思います。

何か画期的な業務改善のようなものではなくても日々の仕事にある部分でこのような価値発揮をすることで必ず自分に返ってくるはずです。
どんどん上司に貸しを作っていきましょう。



## 最後に
今回「攻略法」と書きましたが、相手を倒すわけではありません。
相互理解を深める、それによって自分の仕事がよりスムーズになる、結果として組織チームが機能する。そのようなヒントになれば幸いです。