OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】Hashのデフォルト値の設定

Hashのデフォルト値を調べ、自分のまとめ用で作ってみました。
せっかくなのでHashについても簡単にまとめながら記事を書きます。


# Hashとは
連想配列とも呼ばれ、配列でありながら、任意のオブジェクト(キー)から任意のオブジェクト(値)を関連づけて配列を生成することができます。

## hashの使い方

生成の基本は `変数名 = { "キー" => "値"}`として生成します。
`{}`でhashを生成するのを覚えておきます。

```ruby
p user = { "name" => "Jone", "sex" =>"men", "age" => 23 }
# => {"name"=>"Jone", "sex"=>"men", "age"=>23}
```

取り出しや変更も可能です。
変数名に対して`[]`をつけて、その中に定義してある`key`を書くだけです。
valueを変更したければ、`変数名[key]`に`=`で代入の形をとります。

```ruby

p user["name"] #=> "Jon"
user["age"] = 34
p user["age"] #=> 34 

```
## hashをシンボルで使う
hashのkeyは`:`シンボルでも定義できます。シンボルを使うことで速度の点で有利になります。
左側につけているシンボルを右側につけることで`=>`が省略できます。


```ruby
p user = { :name => "Jone", :sex =>"men", :age => 23 }
 # => {:name=>"Jone", :sex=>"men", :age=>23}
p user = { name: "Jone", sex: "men", age: 23 }
 # => {:name=>"Jone", :sex=>"men", :age=>23}
```

# hashのデフォルト値の設定

hashのkeyの値に何もない場合を指定した場合はどうなるでしょうか。

```ruby
user = { name: "Jone", sex: "men", age: 23 }

p user[:name]   # => "Jone"
p user[:height] # => nil
```
keyに定義していない`height`を指定したところ、nilが出力されました。
nilが出力されるようにしても良い場合もありますが、多くの場合はnilガードを設定して、他の値が出るように設定する必要があります。

これを回避する方法として、keyの値にデフォルト値を設定することができます。
`Hash.new`の引数にデフォルト値を設定することができます。

ここからは注意点を踏まえながらやり方を整理します。

## デフォルト値を設定する時のHash.newの引数の渡し方

`Hash.new([])`で引数を渡した場合、デフォルト値を設定できるものの、すべてのkeyで同じデフォルト値が共有されるように定義されてしまいます。
```ruby
hash = Hash.new([])

p hash[:a] << "Jone"  # => ["Jone"]
p hash[:b] << "Anne"  # => ["Jone", "Anne"]
p hash[:a]            # => ["Jone", "Anne"]
# hash[:a]のデフォルトで設定した"Jone"が変更されてしまっている

p hash[:a].object_id  # => 47010354852980
p hash[:b].object_id  # => 47010354852980
# object_idも同じ
```

では、`Hash.new{[]}`にてブロックで渡して、設定してみます。
この場合は、別のデフォルト値を設定できるが、設定した値が消えてしまう。
```ruby
hash = Hash.new{[]}

p hash[:a] << "Jone"  # => ["Jone"]
p hash[:b] << "Anne"  # => ["Anne"]
p hash[:a]            # => []
# hash[:a]のデフォルトで設定した"Jone"が消えてしまっている



p hash[:a].object_id  # => 47099427138120
p hash[:b].object_id  # => 47099427137880
# object_idは別のものであるため、別のオブジェクトが生成されているのは確認できる。
```
これらを解決する方法として`Hash.new {|hash, key| hash[key] = [] }`の形で書く方法がある。
ブロックを与えると、対応する値がまだないkeyが呼び出される度に、ブロックを評価するのですべて別のオブジェクトが出力されます。

```ruby
hash = Hash.new { |hash, key| hash[key] = [] }
p hash[:a] << "Jone"  # => ["Jone"]
p hash[:b] << "Anne"  # => ["Anne"]
p hash[:a]            # => ["Jone"]
# hash[:a]のデフォルトで設定した"Jone"が残ったまま出力されている！

p hash[:c]            # => []
# 元のデフォルト[]が出力されている

p hash[:a].object_id  # => 47099427138120
p hash[:b].object_id  # => 47099427137880
# 別のオブジェクトが生成されている！

p hash　　　　　　　　# => {:a=>["Jone"], :b=>["Anne"], :c=>[]}
```
`hash[:c]`の動きで、キーに対して何も代入していない場合、デフォルトで設定している`[]`が代入されて、出力されているのがわかります。

デフォルト値が破壊されないようにHashのデフォルト値を設定するには`Hash.new {|hash, key| hash[key] = [] }`が使えるということを覚えておきたいと思います。


# 参照

[Hash.new { |h, k| h[k] = ... } イディオムの意味](https://qiita.com/k0kubun/items/beafb997c077cd72fdf6)
[Ruby: Hash.new とデフォルト値
](https://qiita.com/lnznt/items/678a35e5354db28394db)
ReactでのListとKey扱い

<h2>key</h2>
keyはelementに固有性を付与するため（識別、unique）に<b>配列</b>内部に指定しなければなりません。<br>
また、keyは兄弟同士でuniqueすればいいです。

```react
import React from 'react'

export default function List() {
    const todos= [
        {id: 1, text: 'Drink Water'},
        {id: 2, text: 'Wash Car'},
        {id: 3, text: 'Listen Lecture'},
        {id: 4, text: 'Go to bed'},
    ]

    const Item = (props) => {
        return <li key={props.id}>{props.text}</li>; //li elementにkeyを与えるのは宜しくない 
    }
    const todoList = todos.map((todo) => 
        <Item key={todo.id}                          //正しいkey与え方、配列の内部にkeyを指定している。
                  {...todo}/>)             

    return (
        <>{todoList}</>
    )
}

```

<h2>keyをpropsにて渡したい</h2>
下のコードのItem Componentにkeyをpropsとして渡しています。<br>
果たして、keyもtextのようにpropsにて子componentに渡すことができるのか？


```react
import React from 'react'

export default function List() {
    const todos= [
        {id: 1, text: 'Drink Water'},
        {id: 2, text: 'Wash Car'},
        {id: 3, text: 'Listen Lecture'},
        {id: 4, text: 'Go to bed'},
    ]
    
    const Item = (props) => {
        return <li>{props.key}{props.text}</li>
    }

    const todoList = todos.map((todo) => 
        <Item key={todo.id} text={todo.text}
    />)  

    return (
        <>{todoList}</>
    )
}
```
※出力結果(画面)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/ff11c9bc-3065-49f2-e755-7582fec456ed.png)
※出力結果(console)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/45bfa86b-f9e7-0651-c88e-99fcd4c9fc18.png)
結果を見ると、keyはpropsにて渡せないみたいです。
ひたすらreactのkeyはelementの固有性を判断するだけでpropsにて子に渡すことはできません。

todos.idを画面に出力したい場合は以下のように<b>id</b>を指定してあげればいいです。
 ```react
<Item key={todo.id} id={todo.id}text={todo.text} /> 
```
※出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/e5759e79-b0e3-ac1d-8238-f886a6e11737.png)

<h2>index</h2>
reactではkeyを指定してないと、indexをkeyとして自動付与します。
そのため、上記のconsoldeでWarningが起きても問題なく動作したのです。
CognitoユーザープールにAWS SDK for JavaScript v3でアクセス その1 - ユーザ一覧取得

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-cognito-identity-provider/index.html

を使用してみる

Windows 11にて

Cognitoの設定は
・ユーザ名はメアド
・SMSは使用しない
・メアド・パスワードのみ保持 (他に必要なユーザ属性あれば別DBに保持)
とする

ユーザ一覧取得はCognitoのクライアントとしての接続方法は見つけられず、IAMでのアクセスとなる
(実案件ではCognitoのメンテナンス目的でしか使わないかも、しかし今回は最初の一歩ということでここから始めてみることとする)

# AWS Cognitoユーザープール
1. aws.amazon.comにサインアップ/ログイン
1. コンソールのホームからCognitoサービスへ移動
1. [ユーザープールの管理]押下
1. [ユーザープールを作成する]押下
1. ステップ1 サインインエクスペリエンス
    1. サインインオプション：Eメールのみ
    1. 他：デフォルト
1. ステップ2 セキュリティ要件
    1. MFAの強制：オプション
    1. MFAの方法：Authenticatorアプリのみ
    1. 他：デフォルト
    1. 以下参考画像
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112363/35a62f49-267b-303f-a511-ce7e09d9cc26.png)
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112363/11ee8710-50a9-b603-d8b7-1a6ab890c0a1.png)
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112363/e308891f-5c6c-397a-c59e-702de22c2a33.png)
1. ステップ3 サインアップエクスペリエンス
    1. すべてデフォルト
1. ステップ4 メッセージ配信
    1. Eメールプロバイダー：Cognito
    1. 他：デフォルト
1. 　ステップ5 アプリケーション統合
    1. プール名：MyUserPool
    1. アプリタイプ：秘密クライアント
    1. アプリクライアント名：MyAppClient
    1. 他：デフォルト
1. 　ユーザープールIDの値をメモっておく ★1

# AWS ユーザー、アクセスキー
1. AWSコンソールのホームからIAMサービスへ移動
1. 左ペインのユーザー
1. 右上のユーザーを追加
    1. ステップ1
        1. ユーザー名：MyCognitoUser
        1. AWS 認証情報タイプを選択：アクセスキー
    1. ステップ2
        1. アクセス許可の設定：既存のポリシーを直接アタッチ
        1. ポリシー：AmazonCognitoPowerUserのみ選択
        1. アクセス権限の境界の設定：アクセス権限の境界を設定せずに user を作成する
    1. ステップ3、4
        1. なし
    1. ステップ5
        1. .csvのダウンロード ★2

# AWS SDK for JavaScript v3でアクセス
1. Node.jsをインストールする → https://nodejs.org/ja/
1. 以下コマンドプロンプトで作業
1. 作業フォルダ作成、移動、AWS SDK for JavaScript v3インストール
    ```
    mkdir myprj1
    cd myprj1
    npm install @aws-sdk/client-cognito-identity-provider
    ```
1. 作業フォルダのpackage.jsonに```"type": "module",```を追記
    ```package.json
    {
      "type": "module",
      "dependencies": {
        "@aws-sdk/client-cognito-identity-provider": "^3.245.0"
      }
    }

1. 作業フォルダに以下のファイルを作成 → 使用クラス https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-cognito-identity-provider/classes/listuserscommand.html
    ```list-users.js
    import { CognitoIdentityProviderClient, ListUsersCommand } from "@aws-sdk/client-cognito-identity-provider";

    const cognitoClient = new CognitoIdentityProviderClient({ region: '＜東京リージョンならap-northeast-1＞' });
    const response = await cognitoClient.send(new ListUsersCommand({ UserPoolId: '＜★1の値＞' }));
    console.log(response);
    ```
1. 実行
    ```
    set AWS_ACCESS_KEY_ID=＜★2の値＞
    set AWS_SECRET_ACCESS_KEY=＜★2の値＞
    node list-users.js
    ```

# おまけ - 環境変数設定自動化
1. dotenvインストール
    ```
    npm install dotenv
    ```
1. list-users.jsファイルの先頭に以下を記述
    ```
    import * as dotenv from 'dotenv'
    dotenv.config();
    ```
1. 作業フォルダに以下のファイルを作成
    ```.env
    AWS_ACCESS_KEY_ID=＜★2の値＞
    AWS_SECRET_ACCESS_KEY=＜★2の値＞
    ```

# 今後
ListUsersCommand以外も使ってユーザ登録や認証等を実施
Webアプリ化(ユーザ登録画面や認証画面)

# 続き
https://qiita.com/pilot/items/2d613df34bc1324ebb25
pandas，MultiIndex，空値な列名，Unnamed困る


`pandas`を使っているとき，`MultiIndex`を使いたくなる時が（あまりやりたくはないですが）あります．そして`MultiIndex`と普通の階層のないインデックスを混在させたいときもあります．例えば以下のような感じ．

```python
df = pd.DataFrame(
    [ 
        [ "ピカチュウ", "10まんボルト", "でんこうせっか", "アイアンテール", "エレキネット" ],
        [ "ルカリオ", "はどうだん", "インファイト", "かげぶんしん", "きしかいせい" ],
        [ "カイリュー", "りゅうのまい", "ドラゴンクロー", "ぼうふう", "りゅうせいぐん" ],
    ],
    columns=pd.MultiIndex.from_tuples( [("なまえ", ""), ("わざ", "1"), ("わざ", "2"), ("わざ", "3"), ("わざ", "4")] )
)

print( df )
```

以下出力．

```powershell:出力
# 出力は以下のような感じ
   なまえ       わざ
                  1             2               3            4
0  ピカチュウ  10まんボルト  でんこうせっか  アイアンテール  エレキネット
1  ルカリオ    はどうだん    インファイト    かげぶんしん   きしかいせい
2  カイリュー  りゅうのまい  ドラゴンクロー  ぼうふう       りゅうせいぐん
```

`わざ`は`MultiIndex`，`なまえ`は普通のインデックスです．

:::note info
`MultiIndex`に対して，インデックスに階層がない（ように見える）ものを「普通のインデックス」と呼んでいますが，お察しの通りこれは適切でない表現です．あくまで第0レベルのみの`MultiIndex`が妥当な表現と思われます．
:::

このような時に列を取り出すときのTipsを備忘録としてまとめます．

またこのようなデータをテキストデータとして保存した後，再度読み込んだ時のTipsも．

# 列を取り出したいよー

```python
print( df[ ("わざ", "1" ) ] ) # MultiIndexな方にアクセスするとき

print( df[ "なまえ" ] ) # MultiIndexじゃないほうにアクセスするとき

# # MultiIndexじゃないほうにアクセスするとき，以下の記法でもOK
# print( df[ ("なまえ", "") ] )
# print( df[ ("なまえ", ) ] )

print( type( df[ "なまえ" ] ) ) # 型も見ておく

print( df.columns ) # ついでに列の情報もみておく
```

以下出力．

```powershell:出力
0    10まんボルト
1      はどうだん
2     りゅうのまい
Name: (わざ, 1), dtype: object

0    ピカチュウ
1     ルカリオ
2    カイリュー
Name: なまえ, dtype: object

<class 'pandas.core.series.Series'>

MultiIndex( [
    ('なまえ',  ''),
    ( 'わざ', '1'),
    ( 'わざ', '2'),
    ( 'わざ', '3'),
    ( 'わざ', '4')
], )
```


# 一度テキストに保存し，その後読み込んだ時

`DataFrame` を `poke.txt` として保存し，読み込んで同じことをします．

```python
df = pd.read_table( r"./poke.txt", delimiter="\t", header=[0, 1] )
print( df )

print( df[ ("わざ", "1" ) ] ) # これはもともとの通り

print( df["なまえ"] ) # ここが微妙
print( type( df["なまえ"] ) ) # ここも微妙

print( df.columns ) # ここが問題な感じ
```

結果は以下．

```powershell
                 なまえ       わざ
     Unnamed: 0_level_1        1             2            3              4
0    ピカチュウ            10まんボルト  でんこうせっか   アイアンテール  エレキネット
1    ルカリオ              はどうだん    インファイト    かげぶんしん     きしかいせい
2    カイリュー            りゅうのまい  ドラゴンクロー   ぼうふう        りゅうせいぐん

0    10まんボルト
1      はどうだん
2     りゅうのまい
Name: (わざ, 1), dtype: object

  Unnamed: 0_level_1
0              ピカチュウ
1               ルカリオ
2              カイリュー

<class 'pandas.core.frame.DataFrame'>

MultiIndex( [
    ('なまえ', 'Unnamed: 0_level_1'),
    ( 'わざ',                  '1'),
    ( 'わざ',                  '2'),
    ( 'わざ',                  '3'),
    ( 'わざ',                  '4')
], )
```

もともと列`なまえ`は第0レベルだけで，その下の第1レベルは空値でした．しかし読み込む時に空値の部分には，`Unnamed: 0_level_1` が自動で入力されてしまうようです．すると `df["なまえ"]` が `pd.Series` ではなく `pd.DataFrame` として扱われてしまうなど，ちょっと微妙です．

そのため，列のIndexの中にある，`Unnamed: 0_level_1`を空文字で置き換えてしまいましょう．

```python
df = pd.read_table( r"./poke.txt", delimiter="\t", header=[0, 1] )

df.columns = df.columns.map( lambda x: tuple("" if y.startswith("Unnamed") else y for y in x) )
```

`Unnamed`で始まる列の要素名を空文字に置き換えればOKです．

# おわりに

なにか他にいい方法あれば教えてください．
草莽Erlang ── 23. lists:sum

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:sum

```erlang
sum([number]) -> number
```

数字のリストの総和を求めます。リストの要素が全て数字と時しか使えません。

https://www.erlang.org/doc/man/lists.html#sum-1

練習してみます。

```erlang
> lists:sum([1, 2, 3, 4]).
10

> lists:sum([1.0, 2, 3, 4]).
10.0

> lists:sum(["1", 2, 3, 4]).
** exception error: an error occurred when evaluating an arithmetic expression
     in operator  +/2
        called as 0 + "1"
     in call from lists:sum/2 (lists.erl, line 319)
```

`lists`モジュールには他にもリスト処理のための関数がたくさんあります。

https://www.erlang.org/doc/man/lists.html

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
windowsのキーボード設定をできるだけmacに寄せる

### Power Toys(キー割り当て変更)

キー単体の割り当て変更にはマイクロソフト公式で出ているPower Toysが便利。

https://learn.microsoft.com/ja-jp/windows/powertoys/

インストールしたら、メニュー内のkeyboard Managerで設定を変えられる

macでちょいちょい使うctrlが、
`windows`では`caps lock`になっているので、ここをF13(カスタマイズして使うキー)に変更する。

space key左右にある`windows`ボタンは左だけをctrlに設定する、とかもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/e74150d8-3015-836b-97b1-9e9605b41f62.png)


#### 日本語入力切り替え設定の確認
検索バーなど文字入力できるところで、`Left win`と`Space`を押してみる。
先ほどのキー割り当て変更でLeft `windows`ボタンを`Left control`に割り当てた場合、日本語入力の切り替えができる。

切り替えられない場合は、IMEの設定から`ctrl`と`Space`で日本語切り替え設定されているかを確認する↓![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/48ef7f44-5e16-64f6-7674-b47c9d489563.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/91222853-82e6-18d2-60b4-6311e4cb0d71.png)

### autohotkey(ショートカット変更)
Mac といえば`control` + F,B,P,Nでカーソル移動などのショートカット。
windowsにもあるにはあるが、とても使いにくい。macに慣れているから不便に感じるだけなのかも知れないけど。

そこで、`autohotkey`というツールを使ってショートカットを登録する。

https://www.autohotkey.com/

ダウンロード&インストールしたら、vscodeとかで適当に新規ファイルを作成し、下記設定codeを書く。

```keymap.ahk
; ChangeKeyでCapsLockをF13に変更
; 矢印キー
F13 & p::Send, {Blind}{Up}
F13 & n::Send, {Blind}{Down}
F13 & b::Send, {Blind}{Left}
F13 & f::Send, {Blind}{Right}
; Home & End
F13 & a::Send, {Blind}{Home}
F13 & e::Send, {Blind}{End}

; Delete
F13 & d::Send, {Blind}{Delete}
```

記載したら、ファイルの拡張子を`.ahk`にして適当なファイル名で保存。
保存した後、フォルダからファイルを右クリックして表示されるRun Scriptを実行すると、macと同じショートカットが使える!

#### autohotkeyの細かい設定の仕方について
↓を見つつ設定すれば、他のショートカットも設定できる

[autohotkeyの各キーのマップ](https://ahkwiki.net/KeyList#Key_PgUp)

[複数キーを使ったショートカットの設定](https://ahkwiki.net/Hotkeys#.E3.82.B3.E3.83.B3.E3.83.93.E3.83.8D.E3.83.BC.E3.82.B7.E3.83.A7.E3.83.B3.E3.82.AD.E3.83.BC)
参考

https://qiita.com/riekure/items/49b941fa5159f9948313

### 蛇足
windows環境で使用するターミナルは`Git bash`がとてもよかった。

windows用のCLIとしてPowerShellやWSLターミナル等があるが、Macにあったshellコマンドの多くが使えなかった。`npm run watch`してるのに監視buildしてくれなかったり🤔

その点、`Git bash`はwindows環境でもmac同様のlinuxコマンドが使える。ターミナルの使いづらさに悩んでる方はゼヒお試しを。
草莽Erlang ── 22. lists:mapfoldl

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:mapfoldl

```
mapfoldl(fun((term, term) -> {term, term}), term, [term]) -> term
mapfoldl(fun((要素IN, 累積IN) -> {要素OUT, 累積OUT}), 累積の初期値, リスト) -> {新しいリスト, 累積の最終値}
```

[map/2](https://www.erlang.org/doc/man/lists.html#map-2)と[foldl/3](https://www.erlang.org/doc/man/lists.html#foldl-3)を同時に実施するイメージです。

https://www.erlang.org/doc/man/lists.html#mapfoldr-3

練習してみます。

```erlang
% 各要素を2倍することと全要素の和を求めることを同時にやる
> lists:mapfoldl(fun (X, Acc) -> {X * 2, Acc + X} end, 0, [1, 2, 3, 4, 5]).
{[2,4,6,8,10],15}
```

`lists`モジュールには他にもリスト処理のための関数がたくさんあります。

https://www.erlang.org/doc/man/lists.html

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
【分野別　初中級者が解くべき過去問精選 100 問】を初級者がC++で解く【全探索：全列挙】

[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編：目指せ水色コーダー！】](https://qiita.com/e869120/items/eb50fdaece12be418faa)の`2-3. 分野別　初中級者が解くべき過去問精選 100 問`を初級者がC++で解いていきます。

# 全探索：全列挙

## [1　ITP1_7_B - How Many Ways?](https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_7_B&lang=ja)
ふつうに全探索するだけ。選んだ数字の合計がxだったらカウント。
```c++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 1LL << 60;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repeq(i, a, b) for (int i = a; i <= b; i++)
#define rrep(i, b, a) for (int i = b; i >= a; i--)
#define repb(i, n) for (int i = 0; i < (1 << n); i++)
#define fore(i, n) for (auto &i : n)
#define all(x) x.begin(), x.end()
template<class T>bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}
template<class T>bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

int main() {
  int n, x;
  
  while (1) {
    cin >> n >> x;
    if ((n == 0) && (x == 0)) break;
    
    int ans = 0;
    rep(i, 1, n + 1){
      rep(j, i + 1, n + 1) {
        rep(k, j + 1, n + 1) {
          if (i + j + k == x) ans++;
        }
      }
    }
    cout << ans << endl;
  }
}
```
https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=7404492#1

## [2　AtCoder Beginner Contest 106 B - 105](https://atcoder.jp/contests/abc106/tasks/abc106_b)
全探索で順番に判定していく。1と自身を約数に持つことは明らかなので無視して、約数が6つ見つかればOK。また、奇数なのも前提条件なので、偶数も無視している。
```c++
#include <bits/stdc++.h>
using namespace std;

int main(void) {
  int N;
  cin >> N;
  
  int ans = 0;
  for (int i = 1; i <= N; i += 2) {
    int cnt = 0;
    for (int j = 3; j < i; j += 2) {
      if (i % j == 0) {
        cnt++;
      }
    }
    if (cnt == 6) {
      ans++;
    }
  }
  cout << ans;
}
```
https://atcoder.jp/contests/abc106/submissions/36378837

## [3　AtCoder Beginner Contest 122 B - ATCoder](https://atcoder.jp/contests/abc122/tasks/abc122_b)
文字列の先頭から一文字ずつ見ていって、ACGTが連続で出た回数を数える。
```c++
#include <bits/stdc++.h>
using namespace std;

int main() {
  string S;
  cin >> S;
  
  int tmp = 0, mx = 0;
  for (auto s:S) {
    if ((s == 'A') | (s == 'C') | (s == 'G') | (s == 'T')) {
      tmp++;
    }
    else {
      mx = max(mx, tmp);
      tmp = 0;
    }
  }
  mx = max(mx, tmp);
  cout << mx;
}
```
https://atcoder.jp/contests/abc122/submissions/36473588

## [4　パ研杯2019 C - カラオケ](https://atcoder.jp/contests/pakencamp-2019-day3/tasks/pakencamp_2019_day3_c)
2曲の組み合わせを全探索して得点の最大値を取る。
```c++
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i < b; i++)
#define fore(i, n) for(auto &i:n)
#define all(x) x.begin(), x.end()
using namespace std;

int main(){
  int N, M;
  cin >> N >> M;
  vector<vector<long long>> A(N, vector<long long>(M));
  rep(i, 0, N) {
    rep(j, 0, M) {
      cin >> A.at(i).at(j);
    }
  }
  
  long long ans = 0;
  rep (i, 0, M) {
    rep(j, i + 1, M) {
      if (i == j) continue;
      long long tmp = 0;
      rep(k, 0, N) {
        tmp += max(A.at(k).at(i), A.at(k).at(j));
      }
      ans = max(ans, tmp);
    }
  } 
  cout << ans;
}
```
https://atcoder.jp/contests/pakencamp-2019-day3/submissions/37954861
Clean Architecture -Robert C Martin- 中間メモ

## はじめに
直近、rustを勉強してた際にプログラミングのそもそもについて調べてました。そこでこの本を見つけて読みました。
役に立ちそうな内容だったのでメモ書き程度で残したいと思います。

## Architecture設計の目的
ゴールとしてビルド、メンテナンスに必要な人的リソースを最小限に抑えます。
根拠として用いられた図
- Growth of the engineering staff
- Productivity over the same period of time
- Cost per line of code over time
- Productivity by release
- Monthly development payroll by release
- Time to completion by iterations and use/non-use of TDD

＞各図式を通してArchitectureの必要性を挙げている。

## プログラミングパラダイム
1. Structured-Programming：Structured programming imposes discipline on direct transfer of control.
1. OOP(object-oriented)：Object-oriented programming imposes discipline on indirect transfer of control.
1. Functional-Programming：Functional programming imposes discipline upon assignment.

## 設計原則(SOLID)
1. SRP:A module should be responsible to one, and only one, actor.
1. OCP:A software artifact should be open for extension but closed for modification.
1. LSP:Liskov Substitution Principle(INHERITANCE)
1. ISP:Interface Segregation Principle
1. DIP:Dependency Inversion Principle(ABSTRACTIONS, FACTORIES)

＞Low-Level Principle.

## コンポーネント原則
1. REP:The Reuse/Release Equivalence Principle
1. CCP:The Common Closure Principle
1. CRP:The Common Reuse Principle

＞High-Level Principle.


## Architecture abstract static matrix

• I: Instability: I = Fan-out , (Fan-in + Fan-out). 

• Nc: The number of classes in the component.
• Na: The number of abstract classes and interfaces in the component. 
• A: Abstractness. A = Na ÷ Nc.

• D: Distance. D = |A+I–1| 

＞Target Architecture measture method.
ドロッパー とは

## 勉強前イメージ

セキュリティのやつかと思ってる

## 調査

### ドロッパー とは

英語でDropperと書き、マルウェアのトロイの木馬の一種になります。

トロイの木馬とは古代ギリシャ・ローマ時代の物語が由来で
通常のファイルになりすましをして悪意のある動作を行う不正なプログラムになります。

そのトロイの木馬の一種にドロッパーがあります。
ドロッパーとは、ファイル自体は不正なコードは含まれていませんが
ファイルから不正なコードが含まれるファイルを生み出すプログラムになります。
通常は複数のファイルをコンピュータに作って、不正なパッケージをインストールします。

流れとしては以下になります。

1. コンピュータの内部に侵入
2. 不正なファイルを生成、実行
3. 不正なパッケージをインストール

検知の方法としては
不正なファイルが実行される前にヒューリスティック検知が有用です。
ヒューリスティック検知とはセキュリティソフトのウイルス検出手法の一つです。
あらかじめウイルスが持つ特徴的な挙動を登録して、その挙動を比較して検知する方法です。
ただ、挙動が似ている正常なプログラムも検出するため誤検知も可能性としてあります。
基本的にはパターンマッチングと併用して使われていることが多いです。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/129e045f0130052f1afa) をご覧ください

## 勉強後イメージ

自分自身はそんなに悪いやつじゃないけど
悪いやつを生み出すボスみたいなやつってことか。
ボスは悪いけど・・・・

## 参考

- [ドロッパー（Dropper）](https://eset-info.canon-its.jp/malware_info/term/detail/00074.html)
- [ドロッパー（Dropper）](https://www.sompocybersecurity.com/column/glossary/dropper)
React Flatpickrを使って、開始日と終了日の日付を指定する

## はじめに
こんにちは、mu_tomoyaです。
ReactでDatepickerを使う際に皆さんは何をお使いですか？React Datepickerを使っていらっしゃる方も多いと思いますが、今回はFlatpickrを使って、始まりと終わりの日付を指定する処理をReactで実装してみたいと思います。Flatpickrは軽量な日付入力補助ライブラリで、jQueryなどの依存はありません（結局reac-flatpickrを使えばReact依存になりますが）。そして何より軽い。React Datepickerと比べて、Flatpickrで実装された日付フォームは軽くてすぐに表示されます。欠点としてはそこまで開発が盛り上がっていないところですが、UIの補助として扱いたいライブラリなので自分の場合は現在問題なく使えたので、今回はFlatpickrを使ってみたいと思います。
CSSはTailwindCSSを使ってます。
## 実装
まずはreact-flatpickrをインストールします
```bash
npm install react-flatpickr
```
続いてUI部分
```App.jsx
import React, { useState } from 'react'
import 'flatpickr/dist/flatpickr.min.css'
import { Japanese } from 'flatpickr/dist/l10n/ja.js'
import Flatpickr from 'react-flatpickr'

export default function Home() {
    const [start, setStart] = useState()
    /** 開始日の設定 */
    const start_option = {
        locale: Japanese,
        dateFormat: 'Y/m/d(D)',
        minDate: new Date(),
    }

    /**終了日の設定 */
    const end_option = {
        locale: Japanese,
        dateFormat: 'Y/m/d(D)',
        minDate: start,
    }
    return (
        <form className='grid gap-4 place-content-center min-h-screen'>
            <div>
                <label>開始日</label>
                <Flatpickr
                    options={start_option}
                    className="bg-white border border-gray-300 block w-full p-2.5 shadow;"
                    onChange={([date]) => {
                        setStart(date)
                        field.onChange(date)
                    }}
                />
            </div>
            <div>
                <label>終了日</label>
                <Flatpickr
                    className="bg-white border border-gray-300 block w-full p-2.5 shadow;"
                    options={end_option}
                    onChange={([date]) => field.onChange(date)}
                />
            </div>
        </form>
    )
}

```
`flatpickr.min.css`はカレンダーのUIを整えてくれる部分、`ja.js`を読み込んで月を日本語表記にしてくれます。

開始日は一番最短の日付で今日なので、開始日の`minDate`は`new Date()`で今日に指定しています。また、終了日は開始日より前になることはないので、開始日で選んだ日付を`useState`を使って変数に入れて、それを終了日の`minDate`に設定しています。これで、開始日で選んだ日付以降は選択できなくなっています。
![開始日.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267174/f8d6f9a5-a40d-50e0-fdf9-2049b7748055.png)

![終了日.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267174/0cdc5f5c-6f8e-5658-388d-e40c399207b1.png)
あとはフォーム処理を各々で追加すれば完成です。
【Laravel】API仕様書と実装のテストにツールとしてSpectatorを検討してみた


:::note alert
こちらの記事は旧バージョンのものになります
動作確認はしていませんが、現在は修正されたようです
https://github.com/hotmeteor/spectator/blob/0a765f6a93204ab334aa9c221bada0e5869b52f8/src/Middleware.php#L39
:::

みなさんはSwagger Editor等で作成したAPI仕様書と実装の乖離をどのようにテストしていますか？

多くの記事で目にするのは、**openapi-psr7-validator**というライブラリです。

https://github.com/thephpleague/openapi-psr7-validator

こちらは**PSR-7に準拠したバリデータを使用する**ため、リクエストとレスポンスもPSR-7仕様に変換するという、少し面倒な工程が必要となります。

もう少し手軽にテストができるライブラリがないか探していたところ、こちらの**Spectator**というライブラリを見つけました。

https://github.com/hotmeteor/spectator

こちらもリクエストとレスポンスの型をテストできるらしく、試しに使ってみたのですが・・・という記事になります。

# 環境
PHP 8.0.8
Laravel Framework 8.58.0
Spectator v1.7.1

# 仕様書の保存場所に注意
今回OpenAPI Specのyamlをapp/OpenApiの中に保存しました。
その場合のSPEC_PATHは以下になります。

```:.env
SPEC_PATH=app/OpenApi
```

# ErrorException: Undefined variable $response in Middleware.php

**こいつが原因で、結局使用をやめました。**

テストを作成し実行してみたところ、「200を期待しているのに500エラーが発生してるよ！」というエラーが発生していました。
※通常のFeatureテストを実行すると200が返ってくるので、実装に問題はありません。

Spectatorには
```php
$this->withoutExceptionHandling();
```
というメソッドがあり、Laravelの検証ハンドラーを無効化しSpectatorのエラーを確認することができます。
こちらを追加し再度テストを実行したところ、**ErrorException: Undefined variable $response in Middleware.php**というエラーがライブラリ内部で発生していました。

issueやライブラリの内部を確認したところ、以下の部分でエラーが出ているようでした。

https://github.com/hotmeteor/spectator/issues/136

```php
public function handle(Request $request, Closure $next)
    {
        if (! $this->spectator->getSpec()) {
            return $next($request);
        }

        try {
            $response = $this->validate($request, $next);
        } catch (InvalidPathException|MalformedSpecException|MissingSpecException|TypeErrorException|UnresolvableReferenceException $exception) {
            // ここのせい ここに入ると$responseが未定義のまま返される
            $this->spectator->captureRequestValidation($exception);
        } catch (\Throwable $exception) {
            if ($this->exceptionHandler->shouldReport($exception)) {
                return $this->formatResponse($exception, 500);
            }

            throw $exception;
        }

        return $response;
    }
```
try catch文の一つ目のcatchが走ると、**$responseが未定義のままになってしまってreturnできずエラーが発生する**ようで、プルリクも作成されていますが2023年1月12日現在マージはされていないようです。

https://github.com/hotmeteor/spectator/pull/137

この部分で様々な例外を処理しているのですが、現在の実装だと**全て未定義の変数を返す形となり**、500エラーとして処理されてしまいます。

よって、**テストコードに誤りがあるのか？**、**ファイルパスの指定に問題があるのか？**、**仕様書のyamlに誤りがあるのか？** といった情報がわからないため、とても使いにくいと感じました。

# 結論
**openapi-psr7-validator**の方がもう少しわかりやすくエラーを吐いてくれるので、おとなしくこちらを使います。

# 参考

https://qiita.com/TsukasaGR/items/6e4b67784f02241b8a1c

https://zenn.dev/yumemi_inc/articles/5423cb62f118ba
ChatGPTの時代になって、GUIで差分を取れるmeldが便利な件

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/dc83a6b7-509b-0de4-d2fe-c829020f4092.png)

:::note info
2024/03/14 追記
この記事ではmeldを紹介していましたが、最近のMacだとやや動作が不安定です。Macを使っている場合は、KDiff3や、Beyond Compare などをお勧めします。いずれもhomebrewでインストールできます。
:::

## 便利なChatGPT

いまさら言うまでもないことですが、ChatGPTはめちゃくちゃ便利です。特に日本語の文章、英語の文章、コードの校正に無類の強さを発揮します。私は学生時代は国語が得意だったのですが、ChatGPTは、私の国語力を大幅に凌駕していると思います。というかChatGPTは職業で日本語を書いている人をのぞくと、ほとんどの日本人よりも日本語が上手なんじゃないかと思います。

## ChatGPTに校正してもらった日本語の差分が見たい

さて、ChatGPTに文章校正をしてもらいましょう。
さきほどの文章をChatGPTを使って校正してもらいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/7898231e-83dc-d847-a7c9-5f8b84cc5f48.png)

違いがわかりますでしょうか？

ChatGPTに修正してもらっても、パッと見て、どこが修正されたか、すぐにはわからないケースが多いと思います。日本語は、まだ比較的違いを把握しやすいですが、英文やコードでこれをやるときに、目視でdiffすると見逃します。そんなときに、便利なのがmeldです。

## meld

meldはPythonとGTKで開発されているGUIの差分表示ツールです。（Pythonで開発されている本格的なGUIツールという点でもmeldは珍しいです）

https://gitlab.gnome.org/GNOME/meld

Linuxを使っている人にとっては、meldは定番だと思います。下記のリンクを見ると、一応 Windows や Mac にも対応しているみたいです。

https://meld.app/

おそらく、WindowsやmacOSの世界には、ほかにも有力なソフトもあるのでしょうが、Linuxではこれが一番使いやすいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/42b6aef6-cccf-e996-79a5-ca0db8cf79c0.png)

自然言語の文章は段落まで改行がないことが普通なので、差分を比較する時は、折返し改行をしないと不便です。そこで、設定から文字列の折返しを有効にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/029b96c4-124d-7227-05bb-f9d798eefba8.png)

これで日本語の文章の差分がわかりやすく表示されるようになりました。原文と比較すると、修正後の文章は、きちんとした書き言葉になっていることがわかります。~~わたし日本語へたくそ。日本語ムズカシイネ……。~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/dc83a6b7-509b-0de4-d2fe-c829020f4092.png)

折返し機能は、コードの校正を行う場合には不便になることもあるので、必要に応じて切り替えて利用するとよいと思います。

この記事は以上です。
CloudwatchLogsのメトリクスフィルターとは？

## 勉強前イメージ

サブスクリプションフィルターは知ってる・・・

## 調査

### そもそもCloudwatchLogsとは

EC2やCloudTrail、Route53などからログファイルをモニタリングし、保存することが出来ます。
cloudwatch logsで使用中のサービスの各ログを一元管理することが出来ます。
また、ダッシュボードでのログデータの可視化も出来ます。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/188a101d23930dea22ae) をごらんください

### メトリクスフィルタとは

cloudwatchのログのデータから特定の文字列をフィルタリングするもので
指定したパターンに一致した場合にメトリックスを追加することができます。

設定する箇所としては、cloudwatch > ログ > ロググループ > メトリックスフィルター になります。

![1CloudWatch Management Console - Google Chrome 2023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/af8d44cf-62fa-7b7c-7188-8b35a8b4778b.png)


イメージとしては、
errorという文字列が含まれるログが出力されるとcloudwatchメトリクスに1という値が入ります。
cloudwatchメトリクスにはアラームが設定されていて、1が入ったらアラートが鳴る設定がされる。
というものです。
このイメージを図にすると以下のようになります。

![12023-01-12 # CloudwatchLogsのメトリクスフィルタとは？ - diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/439c96aa-0561-c1b2-bb86-b162f456d956.png)


### サブスクリプションフィルターもあるが？

同じ場所にサブスクリプションフィルターというものありますが
これはいわゆるログ監視になります。
cloudwatch logsに出力されたログデータを特定の文字列を含むデータなどをリアルタイムに検知し、
kinesis や lambda などにログを転送できる機能になります。
サブスクリプションフィルタを使用すると、あるログを出力されていて「Error」が含まれると
lambdaからチャットなどに流すことができるようになります。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/84dd64b9c0af1860391f) をご覧ください

違いとしては、以下になります。

- メトリックスフィルター : 指定の文字列があれば `メトリックスに値を入れる`
- サブスクリプションフィルター : 指定の文字列があれば `lambdaにログを転送する`

ログ自体をそのままアラートに流したい場合はサブスクリプションフィルターが適しており
ログから数値を出してその数値からアラートに流したいときはメトリックスフィルターが適していると思います。

## 勉強後イメージ

サブスクリプションフィルターは使ってたけど
メトリックスフィルターは初めてかも。
errorが何回出たら・・・とかだったらメトリックスフィルターがいいかも？

## 参考

- [[アップデート] CloudWatch Logs メトリクスフィルターでディメンションがサポートされました！](https://dev.classmethod.jp/articles/amazon-cloudwatch-logs-announces-dimension-support-for-metric-filters/)
- [CloudWatch Logs のメトリクスフィルターの設定方法を整理してみた](https://dev.classmethod.jp/articles/cloudwatch-logs-metric-filters-how-to-setup/)
Netlify でdeploy failed for ...となってデプロイできなくなった時の対処法

Netlifyのデプロイエラーになったメモ。
`deploy failed for ...`となってデプロイできなくなっていた

`deprecated`　→　`default`に変更

![スクリーンショット 2023-01-12 21.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179505/ec770cc6-bbde-6de6-ae8f-aac197b5564f.png)
【覚書】ONKYO SE-U55GX をWindows11で使う

### まずは接続

何も考えずにUSB接続してSE-U55GXの電源を入れてみる。

認識はされているようで、Youtube動画見てみると音声再生もできている。
注意喚起アイコンが出ているのが気になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/07d9889f-859f-ff7e-cd8a-562ea9b9305a.png)

### ドライバの更新

ネット上の情報を参考に、ドライバの更新をしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/6dec8f37-9de6-6b7d-c21c-a9e868943961.png)

右クリックして「ドライバの更新」を選択し、「コンピュータを参照してドライバーソフトウェアを検索」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/0a21eabe-b3b4-eab4-79bf-3a7b07145786.png)

「コンピューター上の利用可能なドライバーの一覧から選択します」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/92ede26e-9160-579d-e395-1f863c3e013f.png)

「オーディオ/ビデオ制御デバイス」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/8c31278c-7fab-e344-0bd6-4f34e7e55fc2.png)

「AVCデバイス」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/f152ae48-b5af-207a-5841-fab4a8973d55.png)

警告が出るが致し方なく「はい」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/584cfaca-3a5f-fe91-66f0-38aa47a0044c.png)

更新完了

### 更新結果

再びデバイスマネージャーを見ると、「オーディオの入力および出力」の配下でSE-U55GXが認識されている。
これで大丈夫かな?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071549/0a035568-79c3-ad0c-38b3-4d9b6129c5a2.png)
paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript 重みあり有向グラフの隣接行列と隣接リスト

重みあり有向グラフの隣接行列と隣接リスト (paizaランク B 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_graph_step4

# 解答例
隣接行列と隣接リストを作成して、それぞれ出力した。
隣接リストの重みの部分を`i(m_ij)` の形式で出力する必要があるが、可変長の二次元配列と`"(" + k + ")"`を用いて実装した。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

//頂点の数 N と、辺の数 M 
const [N, M] = lines[0].split(" ").map(Number);

//隣接行列g
let g = [];
for (let i = 1; i <= N; i++) {
    g.push(Array(N).fill(0));
}    

//隣接リストh
let h = [];
for (let i = 1; i <= N; i++) {
    h.push([]);
}

for (let i = 1; i <= M; i++) {
    //各辺の両端の頂点 a_i , b_i と、その辺の重み k_i 
    const [a, b, k] = lines[i].split(" ").map(Number);
    //隣接配列
    g[a - 1][b - 1] = k;
    //隣接リスト
    h[a - 1].push([b - 1, "(" + k + ")"]);//指定された形式i(m_ij)
}

//隣接行列を出力
console.log(g.map(row => row.join("")).join("\n"));

//隣接リストの各行の頂点番号は昇順にソート
h.map(row => {
   row.sort((a,b) => {
       return a[0] - b[0];
   });
});

//隣接リスト出力
console.log(
	h.map(row => row.map(elm => elm.join("")))
	 .map(row => row.join(""))
	 .join("\n")
);
```

# 解答例(Python3の場合参考)
隣接行列を作成し、そこから隣接行列と隣接リストを出力した。
テンプレートリテラルを用いて指定された形式にした。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

//頂点の数 N と、辺の数 M 
const [N, M] = lines[0].split(" ").map(Number);

//隣接行列
let g = Array(N).fill(0).map(v => v = Array(N).fill(0));

for (let i = 1; i <= M; i++) {
    //各辺の両端の頂点 a_i , b_i と、その辺の重み k_i 
    const [a, b, k] = lines[i].split(" ").map(Number);
    //隣接配列
    g[a - 1][b - 1] = k;
}

//隣接行列を出力
console.log(g.map(row => row.join("")).join("\n"));

//隣接リストを出力
for (let i = 0; i < N; i++) {
  for (let j = 0; j < N; j++) {
    if (g[i][j] !== 0) {
      process.stdout.write(`${j}(${g[i][j]})`);//改行なし出力
    } 
  }
  console.log();//改行のみ
}
```
paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript 有向グラフの隣接行列と隣接リスト

有向グラフの隣接行列と隣接リスト (paizaランク B 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_graph_step3

# 解答例
有向なので、1 つの辺につき、追加する情報が 1 つであること、始点と終点があることに気をつけます。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//頂点の数 N と、辺の数 M 
const [N, M] = lines[0].split(" ").map(Number);
//隣接行列g
let g = [];
for (let i = 1; i <= N; i++) {
    g.push(Array(N).fill(0));
}    
//隣接リストh
let h  = [];
for (let i = 1; i <= N; i++) {
    h.push([]);
}

for (let i = 1; i <= M; i++) {
    //各辺の始点 a_i と、終点 b_i 
    const [a, b] = lines[i].split(" ").map(Number);
    //配列
    g[a - 1][b - 1] = 1;//有向なので１つ
    //リスト
    h[a - 1].push(b - 1);//有向なので１つ
}

//隣接行列を出力
console.log(g.map(row => row.join("")).join("\n"));

//隣接リストの各行の頂点番号は昇順にソート
h.map(row => {
   row.sort((a,b) => {
       return a - b;
   });
});

//隣接リスト出力
console.log(h.map(row => row.join("")).join("\n"));
```
paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript 隣接リスト

隣接リスト (paizaランク B 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_graph_step2

# 解答例
問題文に沿って実装します。
二次元で長さが変わる配列を用いるとよいです。
各行の頂点番号は昇順にソートと指定されているので、行います。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//頂点の数 N と、辺の数 M 
const [N, M] = lines[0].split(" ").map(Number);

//隣接リスト
let g = [];
for (let i = 0; i < N; i++) {
    g.push([]);
}

for (let i = 1; i <= M; i++) {
    //各辺の両端の頂点 a_i , b_i 
    const [a, b] = lines[i].split(" ").map(Number);
    //頂点aと頂点bが辺で結ばれているので
    g[a - 1].push(b - 1);
    g[b - 1].push(a - 1);
}

//各行の頂点番号は昇順にソート
g.map(row => row.sort((a, b) => a - b));

//隣接リスト出力
console.log(g.map(row => row.join("")).join("\n"));
```
隣接リストを用意するところ、１行でも書けます。
```javascript
//隣接リスト
let g = Array(N).fill(0).map(v => v = []);
```
paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript 隣接行列

隣接行列 (paizaランク B 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_graph_step1

# 解答例
問題文に沿って実装します。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//頂点の数 N と、辺の数 M 
const [N, M] = lines[0].split(" ").map(Number);

//隣接行列
let g = [];
for (let i = 0; i < N; i++) {
    g.push(Array(N).fill(0));
}
//隣接情報を加える
for (let i = 1; i <= M; i++) {
    //各辺の両端の頂点 a_i , b_i 
    const [a, b] = lines[i].split(" ").map(Number);
    //頂点aと頂点bが辺で結ばれているので
    g[a - 1][b - 1] = 1;
    g[b - 1][a - 1] = 1;
}

//隣接行列出力
console.log(g.map(row => row.join("")).join("\n"));
```
React – formで送信するとページ遷移が起こるのを防ぐ

# コード例

submitのイベントで Default挙動を無効化する

```tsx

const FormSubmit = () => {

  const handleOnsubmit = (e: any) => {
    e.preventDefault();
    console.log(e.target.textContent)
  }

  return (
    <>
      <div>
        <form onSubmit={handleOnsubmit}>
          <button >Click me</button>
        </form>
      </div>
    </>
  );
}
export default FormSubmit;
```

# 参考

単純に HTML的な form を書くのはReact流ではなさそうだ

>ユーザがフォームを送信した際に新しいページに移動する、という、HTML フォームとしてのデフォルトの動作をします。React でこの振る舞いが必要なら、そのまま動きます。しかし大抵のケースでは、フォームの送信に応答してユーザがフォームに入力したデータにアクセスするような JavaScript 関数があった方が便利です。

https://ja.reactjs.org/docs/forms.html



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
nuxt.jsのtitleTemplateをページによって使い分ける

```nuxt.confin.js
header{
    titleTemplate:  '%sタイトルテンプレート',
    }
```

```example.vue
<template>
  <div>
    <p>title test</p>
  </div>
</template>

<script>
export default {
  head() {
    return {
      title: 'タイトル',
      // 各ページのvueファイルでnuxt.config.jsのtitleTemplateを上書きできる。
      titleTemplate: '%sタイトルテンプレート1'
    }
  }
}
</script>
```
Googleプロジェクト管理：プロジェクトのスコープ

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# プロジェクトのスコープとは

プロジェクトのスコープは、プロジェクトの境界線のことです。

***<font color="MediumVioletRed">『プロジェクトに何が含まれ、何が含まれないかについての合意された理解』</font>***


スコープを明確に定義することで、プロジェクトのすべての詳細が記述され、プロジェクトの進行に応じて追加・削除できるものが規制されます。

プロジェクトを監視し、すべての作業とリソースがスコープ内にあることを確認するのは、最終的にはプロジェクトマネージャーの責任ですが、チームメンバーやステークホルダーは、プロジェクトのゴールを達成するために最も重要なタスクに集中することで、自分の役割を果たすよう奨励することができます。

# スコープに含まれるもの

スコープには、

- プロジェクトのタイムライン
- 予算
- リソース

も含まれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3dbcadbc-61ae-2025-41c1-79dab236d55e.png" width="550">


これらを明確に定義することで、その境界線の中で、実際にプロジェクトが機能する可能性を確認することができるのです。

スコープの定義が不十分だったり、スコープを大きく変更したりすると、予算やスケジュール、さらにはプロジェクトの最終的な成果まで変わってしまう可能性があります。

# プロジェクトの範囲を把握する

さて、実際にプロジェクトの範囲を把握するには、どうすればいいのでしょうか？それは簡単です。スポンサーやステークホルダーと話し、彼らの目標を理解し、 また ***<font color="MediumBlue">何がプロジェクトに含まれていないのか</font>*** を突き止めるのです。

以下はプロジェクトのスコープを定義するためにステークホルダーに尋ねるための質問リストです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f2731612-7798-26bd-5e7a-e10a07637293.png" width="７00">


# プロジェクトのスコープを定義するタイミング

タイミングとしては、プロジェクトのスコープを定義するのは、最初のプランニングの段階で行うべきでしょう。早い段階からスコープを決めておくことで、全員が同じ期待値に同意できるようになります。そうすることで、将来的に大きな変更が発生するリスクを軽減することができます。ただし、必要であれば、計画を進めながらいつでも範囲を調整することができます。
PowerAutomateで作成したTeams会議を変更する

今回は久しぶりにPowerAutomateの話題です。
PowerAutomateで作成したTeams会議の予定をPowerAutomateで変更するにはどうしたらよいかというお話です。

# Problem

PowerAutomateのワークフローでTeams会議を作成することにしました。
何らかの事情で会議の開催日時などを変更したくなったとします。
変更作業もできれば手作業ではなく、PowerAutomateワークフローで行いたいものです。

ところが、PowerAutomateのTeamsのアクションの一覧には「Teams会議の作成」はあっても「Teams会議の変更」や「～更新」はありません：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/2f191f6f-7ee0-0e46-6112-88316282669d.png)

組織でPowerAutomateを使用する場合、ワークフローは専用のユーザー（個人用途とは別のユーザー）を使用することも多いはず。
一方、「Teams会議の作成」アクションで送信される会議出席依頼の差出人はワークフローを実行するユーザー（ワークフローの「接続」で設定されているユーザー）になります。
会議の変更を人手で行おうとすると、当該ユーザーでM365のTeamsやOutlookにログインする必要が出てきます。これはとても面倒です。

# Solution

Outlookのアクション、「イベントの更新」を使用します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/e9accd84-ff44-b304-987d-2e2299803b2d.png)

「会議」と「イベント」の違いがわかりにくいところですね。
またTeamsのアクションでないことも少しわかりにくいところなのですが、会議出席依頼そのものは元来Outlookのメールなので、それに紐づく会議（イベント）の情報の更新にOutlookのアクションを使うのは理にかなってはいます。

「イベントの更新」アクションの `ID` 欄には、「Teams会議の作成」アクションの出力に含まれる `id` を指定します（`outputs('Teams_会議の作成...')?['body/id']`）：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/a3ec8101-ad5a-2792-fb43-f96fbcfab642.png)

あるワークフロー（ワークフローA）で会議を作成したらそのID（id）をどこかに保存しておいて、別のワークフロー（ワークフローB）で会議を変更するときにそのID（id）を取り出して使用する─このようなやり方になるでしょう：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/54c05700-a6a0-829f-9d8d-4dd52ba49841.png)


:::note warn 
他の「～更新」系アクションと同じく、「変更するところだけ入力欄に入力」ではなく「元と変わらないデータも含めて必要な情報はすべて入力欄に入力」です。
このため例えば「変更したいのは日時だけ」だとしても、「出席者」など変更後の会議（会議出席依頼）で必要となる情報はすべて入力する必要があります。
このためすぐ上で示した手順では「イベントの取得」を行っています。
:::

:::note info
この記事を執筆している2023年1月12日現在、「HTTP要求を送信します（プレビュー）」というアクションが利用できます。
「これをうまく使えば前述註記の面倒は回避できる可能性もあるかな？」と考えていますが、参考になる記事が見つからず、今回は断念しました：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/5a92f9e3-10d2-9cdd-dd40-9c6a6052d24c.png)

:::
顧客分析の手順 - 分析の枠組み 

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）


# 顧客分析の手順

## 第2回： 分析の枠組み
前回、企業の目的である利益の最大化、これを CRM／マーケティング／顧客管理の観点から支援し、その実現に寄与する - このための改善ポイントとして、「新規顧客の獲得」、「顧客リテンション」、「優良顧客の育成」の 3点を挙げ、これを「経費効率の向上」を伴って実現させるべきと述べました。そして、これを実現するためには、何らかの「行動」が不可欠であり、どんな行動を選択するべきか「意思決定」することが求められます。そして正しい意思決定を行なうためにデータを分かりやすく解き明かし、知識を導き出すことが「分析」です。

今回は、この分析の枠組みについて整理します。分析の結果得られる「知識」は、データというレシピを調理して得られた美味しい料理のようでもあり、鉱山で採掘した資源を精製して得られるレアメタルのようでもあります。いずれも必要なデータ（レシピ、資源）を不足なく用意して、必要な手順を経ることによって知識（美味しい料理、レアメタル）に変化します。

天下り的にこの枠組みを示すと、それは以下の通りです。もちろん、世の中には様々な分析対象が有り、それに対する分析のアプローチが存在します。ここでは顧客分析、そして上述した 3つの改善ポイントを特定するために、最低限必要不可欠なものを提示しています。

### 1. データを用意する
1-1. データ単位（顧客毎のデータ）の用意

1-2. 変数（顧客属性／指標）の用意
### 2. 各変数の特徴を理解する
### 3. 複数の顧客群に分類し、比較する
### 4. 意思決定／行動に適用できる知識を析出する
4-1. 新規顧客の増／減ポイント

4-2. 既存顧客の増／減ポイント

4-3. 顧客支出の増／減ポイント

## データの用意
データを分析するのですから、何を差し置いてもデータが必要です。このフェーズでは、分析の基礎とすべきデータを用意します。分析の対象は顧客であるため、顧客毎のデータが必要です。そして各顧客に関する様々な事実が「変数」つまり顧客属性や顧客指標として集められます。つまり、行と列で構成された単一の表として基礎データは説明でき、このとき、行はそれぞれの顧客、列は各顧客に関する様々な事実として配置されます。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/865103b7-9c3e-35b4-76a2-8e8d7aec5bf6.png">



## 変数の特徴理解
データが用意された段階で、各変数の特徴について把握します。単一の変数でその特徴を理解するだけでなく、必要に応じて 2変数の相関を理解する必要があります。また、ここで得られた変数の特徴に応じて、元のデータからの変数作成自体を再度実施しなければならない場合もあります。

## 複数顧客群への分類と比較
変数特徴の理解が、列に主眼をおいたアプローチであるのに対して、ここでは、行を適切に分割し、複数行をグルーピングした上で変数特徴を比較します。ここで言う行とは顧客であり、行の分割とは顧客のセグメンテーションです。2つのセグメントを各変数で比較することも必要ですし、顧客全体（母集団）と特定の条件で切り取ったセグメントを比較することも必要です。

## 意思決定／行動に適用できる知識の析出
変数についての理解、そしてセグメントについての理解が得られた段階で、これらを特定の分析フォーマットに流し込みます。そしてここから、4-1. から 4-3. に記載したような「おかしなポイント」を見つけ出します。このおかしなポイントこそが、なんらかアクションをとるべきポイントであり、このポイントを見つけ出すこと、そしてこのポイントに対して何をすべきかを特定することが、「知識」の析出です。それは行動を促すものでなければならず、採るべき行動を明確化してくれるものである必要があります。

以上の枠組みを通じて分析を実施することにより、必要な知識を獲得し、「行動 = キャンペーンを中心とした顧客へのアプローチ」を決定することが可能となります。次回以降で、この枠組みのそれぞれについて解説していきます。



#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
MACにApache NiFiをインストール（勉強用環境）


# 1. Download Zip files

https://nifi.apache.org/download.html
現時点(2025/02)、最新バージョンをダウンロード
NiFi 2.2.0
https://dlcdn.apache.org/nifi/2.2.0/nifi-2.2.0-bin.zip

MBPにダウンロードした後、解凍。

```bash

chmod +x bin/nifi.sh

```

NiFi 2.2はJDK21が必要です。最初小生のJDK17で実行したら下記エラーが出ました。

```bash
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
NIFI_HOME=/Users/zzeng/Downloads/tools/nifi/nifi-2.2.0

Error: LinkageError occurred while loading main class org.apache.nifi.authentication.single.user.command.SetSingleUserCredentials
	java.lang.UnsupportedClassVersionError: org/apache/nifi/authentication/single/user/command/SetSingleUserCredentials has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 61.0

```


これでダウンロード：
https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html



# 2. User 作成
```bash
export JAVA_HOME=$(/usr/libexec/java_home)
bin/nifi.sh set-single-user-credentials zzeng <パスワード教えないよ>

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/b44b300a-86d7-4229-ae97-fca319dbc461.png)


結果：
```bash
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
NIFI_HOME=/Users/zzeng/Downloads/tools/nifi/nifi-2.2.0

Login Identity Providers Processed [/Users/zzeng/Downloads/tools/nifi/nifi-2.2.0/./conf/login-identity-providers.xml]
```

# 3. 起動
```bash
bin/nifi.sh start
bin/nifi.sh status

netstat -an | grep LIST

```

下記８４４３ポート発見：
```bash
tcp4       0      0  127.0.0.1.8443         *.*                    LISTEN
```

# 4. Login
https://localhost:8443/nifi/

## NiFi 1.19
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/19631076-ce14-a30e-ab0b-f5dcbb502cf5.png)


## NiFi 2.3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/cbd5e1b9-e7f1-44cd-8bc5-8bddc0146d6b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/799991ce-6e0e-4900-a0b8-58ec44adcd43.png)

出来上がり
GraphQLのschema.graphqlsファイルをバックエンドとフロントエンドで同期するベタープラクティス

# この記事は何か？
フロントエンドとバックエンドをGraphQL APIで連携する場合、スキーマファイル(schema.graphqls)をどうやって連携するか悩んでいました。
色々と試行錯誤して、ベストプラクティスとまでは言えないまでもベタープラクティスに近い解決策に至ったので共有してみます。

# 構成
バックエンドは Go, Gin, gplgen、
フロントエンドは TypeScript, React, Next.js

のSPA構成でそれぞれ別リポジトリで管理しています。

# やりたいこと
バックエンドとフロントエンドでschema.graphqlsファイルから型を自動生成したい。
※ schema.graphqlsファイルの管理はバックエンドが主導で行う前提です。

# やりたくないこと
graphqlsファイルの二重管理。バックエンドの差分を逐一フロントエンドでコピーして追従、というケースだけは避けたい。

# 辿り着いたベタープラクティス
バックエンドでは、[gplgen](https://gqlgen.com/)のコマンドによりGoの型を自動生成し、
フロントエンドでは、[GraphQL Code Generator](https://the-guild.dev/graphql/codegen)(以下、codegen) でTypeScriptの型を自動生成する。

schema.graphqlsファイルをバックエンドのサーバにホスティングし、codegenの参照先(codegen.yml - schema)として設定する。

# 悩んだポイント
バックエンドでは、graphqlsファイルを分割して管理したい。一本で管理すると、システムが巨大化したときにコンフリクトが起きやすくなる、かつ見通しも悪くなるため。

一方で、codegenのスキーマファイルの参照先は当たり前だが1つにしたい。

# 具体的な解決策
バックエンドのデプロイパイプラインにて、catコマンドにより分割管理されたgraphqlsファイルを統合し、ホスティング用のディレクトリに出力するようにしました。

catコマンドでは以下のように拡張子を絞ってファイルを統合できるので大変便利です。
```
cat *.graphqls > public/schema.graphqls
```

これにより、バックエンドがデプロイするたびに最新のgraphqlsファイル群がshecma.graphqlsファイルに統合されホスティング、
フロントエンドでは、ホスティング先のURLをcodegenの参照先に指定することで、完全にスキーマファイルを同期することに成功しました。

※ ホスティング先にはbasic認証をかけるなどして公には見えないようにしましょう。

あくまでベタープラクティスなので、もっと楽にできる方法があればご教示お願いします！
Ruby3.0にアップデートする時、sorted_setをインストールする前に確認してほしいこと

唐突ですが、Rubyでは2.7から3.0へアップデートされる時、SortedSetというライブラリはGemに分離されました。

https://github.com/ruby/ruby/blob/v3_0_0/NEWS.md#compatibility-issues

```
SortedSet has been removed for dependency and performance reasons.
```

「なるほど、じゃあRuby3に上げる時にSortedSetを使っていたらインストールすればいいんだな！」となるかもしれませんが、それはちょっと待ってほしいです(確かにそれでも動きますが)。

まずどこで使っているのかを、`git grep`なりエラーのスタックトレースなど適切な方法で確認しましょう。
もし自分が作成したコードで使っているのである場合、今回Gemへ分離されたのはパフォーマンスが理由なので、問題ない場合はインストールでも問題ありません(セキュリティなどだと話は変わりますが・・・)。

ただ、他のGemが依存していて自分のコードでは使っていない場合は、GemのChangelogやissueでどのような判断をしているかを覗きに行きましょう。

たとえば、[wvanbergen/chunky_png](https://github.com/wvanbergen/chunky_png)というpngファイルの読み書きを行うためのgemでは、[そもそもSortedSetを使わない実装に切り替えています](https://github.com/wvanbergen/chunky_png/pull/154)。

なので、chunky_pngでしかsorted_setを使ってないよ！という場合はchunky_pngを最新までアップデートする方が良いでしょう。

Rubyでは標準ライブラリをgemに分離する、というのは自分の記憶ではちょくちょくあったはずです(確認してないので滅多にないよ、というマサカリが飛んできた場合はごめんなさい)。分離に巻き込まれた場合安易に追加するのではなく、利用しているのはどこなのか、もしGemの場合どのような対応をしているのか確認をするようにしましょう。


## 参考
[CurryBu を Ruby 3.0 にアップデートした - 暇人じゃない](https://chocoby.com/blog/2021/02/15/curry-bu-ruby-3)
PrePoMaxによる引張試験片に生じる応力計算

# はじめに
PrePoMaxの練習のため、引張試験片の応力を計算しました。

# やりかた
まず、FreeCADでJIS Z2241 4号試験片の1/8モデルとstepファイルを作成します。作成したモデルとstepファイルは以下にあります。

https://github.com/repositoryfiles/Tensile_Specimen-for-JIS-Z2241-No.4

次に、stepファイルをPrePoMaxにインポートして、メッシュを作成（最大サイズ2mm）します。インポートしたモデルを図1に、作成したメッシュを図2に、それぞれ示します。

<img width="600" alt="スライド4.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/f44c6f17-c7f5-a0ce-6b0c-fd150311a410.jpeg">

図1　インポートした引張試験片の1/8モデル

<img width="600" alt="スライド5.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/803042b5-48b5-395b-20ad-0c2775969b34.jpeg">

図2　作成したメッシュ

さらに、境界条件を設定します。対称となる断面の垂直方向の変位を拘束して、つかみ部に12500Nの力を加えます。断面積が1/4のモデルのため、50000Nで引っ張っていることに相当します。境界条件を設定した状態を図3に示します。なお、材料は鋼材（ヤング率210000MPa、ポアソン比0.30）としました。

<img width="600" alt="スライド7.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/740a8319-cee8-bee4-c81d-3116ce7081dd.jpeg">

図3　境界条件の設定

解析を実行して結果を表示します。1/8モデルの結果を図4に、対称表示した結果を図5に、それぞれ示します。図5は元の形状とメッシュを非表示にしています。

<img width="600" alt="スライド9.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/88ad0ae0-b4c9-6dad-17e3-ce873717278a.jpeg">

図4　1/8モデルのX軸方向の垂直応力の解析結果

<img width="600" alt="スライド11.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/acc2a7b2-9312-4720-4c23-9b2c4d1073b2.jpeg">

図5　図4の解析結果の対称表示

最後に、最大、最小応力が生じている試験片のR部付近の断面の応力状態を図6に示します。最大および最小の応力となっているのは表面付近であることが分かります。

<img width="600" alt="スライド11.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/89c5fe77-b8c8-1182-0620-c6c9df36b6bb.jpeg">

図6　試験片のR部断面のX軸方向の垂直応力
Function interface

Interface Function\<T,​R\>
Type Parameters:
T - the type of the input to the function
R - the type of the result of the function

given argumentに対し処理を行い、結果を返す
下記の例はgiven stringのlengthを返す

```java
public class Outer {
    public static void main(String[] args) {
        Function<String, Integer> f = x -> x.length();
        System.out.println(f.apply("abc"));
    }
}
```
```
3
```