OmniAICreator/Qiita-1.07M huggingface dataset:
Babylon.jsで変身！

この記事は[Babylon.js Advent Calendar 2022](https://qiita.com/advent-calendar/2022/babylonjs)の12日目の記事です。

<!--
![Dude-Dummy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703301/3a1d69f1-d82e-5dec-0c8d-7b573982e8c7.png)
-->

# はじめに

変身っていいですよね。ライダーとか戦隊モノとか魔法少女モノとか。あとちょっとちがうけどアイドルの衣装チェンジとかも。普段と違う姿になって活躍するって憧れちゃうね！

そんなわけでBabylon.js界のアイドル？Dudeくんを変身させようと思います。

# 変身！！

というわけで変身しました。コードは[ここ](https://playground.babylonjs.com/#JS5PZI)に。

![Dude-transform.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703301/0ff1e964-6ec2-5686-60a9-57782864d882.gif)

# コード解説的なもの

基本的にやっていることは `clipPlane` でメッシュが見える領域を切り替えているだけです。
`clipPlane` でどういう事ができるかについては[公式ドキュメント](https://doc.babylonjs.com/features/featuresDeepDive/scene/clipPlanes)にあるサンプルがとても分かりやすいのでそちらを見るのがおすすめです。

今回ほぼ公式のサンプルの [Clipping Planes Example](https://playground.babylonjs.com/#Y6W087) をそのまま使ってちょこちょこ変更して作りました。変更点はだいたいこんな感じ。
- メッシュを2つ読み込む
- 2つのメッシュスケールを合わせる
- sceneではなくメッシュに対してclipPlaneを設定する
    - いい感じに変身できるようにパラメータを調整する

とざっくりこれだけです。

## クリッピングプレーンの領域

今回クリッピングプレーンを使ってメッシュの表示を切り替えました。このとき平面を `scene.clipPlane
 = new BABYLON.Plane(0, 1, 0, XX)` みたく設定するわけですが、どっちがプラス方向やねん！となったので図を描きました。
青色部分がメッシュが見えなくなる領域です。

![上からclipPlane.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703301/e1231b04-8c4e-7da8-c4b3-237cb4ed96f5.png)

上方向を見えなく（下側が見えるように）する場合、`new BABYLON.Plane(0, 1, 0, XX)`の形式で指定します。第4引数は下向きがプラスになっています。

![下からclipPlane.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703301/a84cfc85-b900-7607-f47a-1138abf0fcf9.png)

逆に下方向を見えなく（上側が見えるように）する場合、`new BABYLON.Plane(0, -1, 0, XX)`の形式で指定します。第4引数は上向きがプラスになっています。

今回はY方向（高さ方向）でのクリップの例でしたが、X方向やZ方向（奥行方向）で指定するときも、Xは右がプラス、Yは上がプラス、Zは奥行きがプラス、なので...と考えて同じように指定すれば自由にクリップ領域を指定できそうですね。

# まとめ

これDodeくんが変身じゃなくてDodeくんに変身では？とか言わない。
あとはクリッピングプレーン部分にエフェクトとかかけるともっと変身っぽくなると思います。
それと本当は12月だしサンタ衣装に着せ替えしてDudeくんを可愛くしたかった。。けどサンタ衣装が用意できなかった。誰かDudeくんを可愛くしてあげてください。

# 参考

- 公式ドキュメント
    - [Using Clipping Planes](https://doc.babylonjs.com/features/featuresDeepDive/scene/clipPlanes)
    - [The Meshes Library](https://doc.babylonjs.com/toolsAndResources/assetLibraries/availableMeshes)
【AWS】メインルートテーブルとサブネットの関係について

## メインルートテーブルとは
サブネットに関連付けされるルートテーブルとは異なり、VPC作成時に**自動的**に生成される。

新規にサブネットを作成し、明示的にルートテーブルをアタッチしていない場合、そのサブネットには**自動的**にメインルートテーブルの設定が割り当てられる。

## 実際目で確かめる
以下のリソースを作成します。
VPC
`test-vpc`
ルートテーブル (IGWへのルートを含む)
`test-vpc-public`
パブリックサブネット
`test-vpc-public-ap-northeast-1a`

Terraformで作成すると楽です。

```tf
provider "aws" {
    region = "ap-northeast-1"
}

module "vpc" {
    source  = "terraform-aws-modules/vpc/aws"
    version = "3.10.0"

    name = "test-vpc"
    cidr                 = "10.0.0.0/16"
    enable_dns_hostnames = true
    enable_dns_support   = true

    azs             = ["ap-northeast-1a"]
    public_subnets  = ["10.0.11.0/24"]

}

```


## サブネットからルートテーブルの関連付けを外す

IGWへのルートを含むルートテーブル`test-vpc-public`が関連付けされている。

![スクリーンショット 2022-12-11 11.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/36d23495-12a1-eb9b-7834-4622081c00e8.png)

![スクリーンショット 2022-12-11 11.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/03dc3cfa-f38d-917f-aecb-7397f3c60bd4.png)

`test-vpc-public`との関連付けを外すと、メインルートテーブルに関連付けされる。

（ルートテーブル自体をアタッチしないという設定はできず、基本的にメインルートテーブルをベースとしたルーティング設定となる。）

![スクリーンショット 2022-12-11 11.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/788fd8f2-5671-21fa-b1ff-984b953cc8ec.png)

![スクリーンショット 2022-12-11 11.46.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/8f96b2d1-2f68-a9cb-f1e4-6381ae4eb072.png)

メインルートテーブルにIGWを設定されている場合、そのVPC内のサブネットは必然的にパブリックサブネットになるので注意。

## 参考
https://nekootoko3.hatenablog.com/entry/2018/06/15/181838

https://go-journey.club/archives/13485
Vuetify3.0で文字色をVuetifyカラーにstyleで設定する方法

## 概要
Vuetify3.0にアップデート後、Vuetify2と同様にVuetifyカラー（primaryなどの色）をstyleタグで設定できなくなってしまったので、その解決法をまとめます。
aタグは`color='primary'`の形で色の設定ができないため、aタグを例に説明します。
## Vuetify2までのやり方
styleに書く場合、下記のように`color: var(--v-???-base);`という記述をしていました。
```vuejs
<a style="color: var(--v-primary-base);">...</a>
```
また、この際customePropertiesをtrueにする必要があります。
```js
// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

export default new Vuetify({
  theme: {
    options: { customProperties: true },
  },
})
```
ここに関しては、下記の公式ドキュメントにて説明があります。
[テーマの設定 -- Vuetify カスタムプロパティ](https://vuetifyjs.com/ja/features/theme/#section-30ab30b930bf30e030d730ed30d130c630a3)

## Vuetify3でのやり方
一方、Vuetify3では、下記のように記述するとVuetifyカラーをstyleタグで設定することができます。
変わった点としては
1. rgbで括る必要がある
1. baseを後ろにつける必要がなくなった代わりに、間にthemeを入れる必要がある
```vuejs
<a style="color: rgb(var(--v-theme-primary));">...</a>
```
また、この際Vuetify2とは異なり、customePropertiesの設定は不要です。（optionsプロパティ自体無くなった？）
公式ドキュメントの説明はこちら↓
[Theme -- Vuetify Custom theme colors](https://next.vuetifyjs.com/en/features/theme/#custom-theme-colors)
## 最後に
最後まで読んでいただきありがとうございました！
【SwiftUI】Combineでバッテリーを監視する

# はじめに
ゼンリーのアプリを見てたらバッテリー残量が表示されていたのでどうやるのかなと思い、試してみました。
せっかく試したので記事にしておきます。

https://qiita.com/SNQ-2001/items/7ebfadb553c2682ea69b

これをちょっと変えてサンプルアプリを作成します。

# サンプルアプリ
充電中 → 緑
それ以外 → 黒
![RPReplay_Final1670752390_MP4_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d7e229da-d994-d0b3-1e51-6ae5c621014e.gif)


# 実装
### View
```swift
import SwiftUI

struct ContentView: View {
    @StateObject private var viewModel = ViewModel()
    var body: some View {
        batteryShape
            .overlay(batteryText.foregroundColor(.white).blendMode(.difference))
            .overlay(batteryText.blendMode(.hue))
            .overlay(batteryText.foregroundColor(.white).blendMode(.overlay))
    }

    var batteryText: some View {
        Text("\(Int(viewModel.batteryLevel))")
            .font(.system(size: 70, weight: .black))
    }

    var batteryShape: some View {
        ZStack(alignment: .center) {
            RoundedRectangle(cornerRadius: 15)
                .stroke(Color.black, lineWidth: 6)
                .frame(width: 250, height: 120)

            RoundedRectangle(cornerRadius: 10)
                .foregroundColor(viewModel.batteryColor)
                .frame(width: 230 * (viewModel.batteryLevel / 100), height: 100, alignment: .leading)
                .alignmentGuide(HorizontalAlignment.center) { _ in 115 }
        }
    }
}
```

### ViewModel
```swift
import Combine
import SwiftUI

final class ViewModel: ObservableObject {
    @Published var batteryLevel: CGFloat = 100

    @Published var batteryColor: Color = .black

    private let device = UIDevice.current

    private var cancellable = Set<AnyCancellable>()

    init() {
        device.isBatteryMonitoringEnabled = true

        device.publisher(for: \.batteryState)
            .sink { [weak self] status in
                guard let self else { return }
                switch status {
                case .charging:
                    self.batteryColor = .green
                case .unplugged:
                    self.batteryColor = .black
                case .full:
                    self.batteryColor = .black
                case .unknown:
                    self.batteryColor = .black
                default:
                    self.batteryColor = .black
                }
            }
            .store(in: &cancellable)

        device.publisher(for: \.batteryLevel)
            .map { CGFloat($0) * 100 }
            .assign(to: &$batteryLevel)
    }
}
```

# おわり
充電中のテキストカラーが純粋な白にできなかったのが悔しいです。。。
自宅のネットワークからMAMPのlocalhostにアクセス

## 経緯 ##
自宅のみで利用するWEBアプリケーションを作成し共有するにあたって、レンタルサーバを利用するにはレンタル費もかかってしまう為、合理的ではないと思い普段開発時に利用しているMAMPのローカルサーバでどうにかできないかと調べた結果、案外簡単に設定できそうなのでやってみることにする。

## 必要なもの ##
* MAMP
* httpd.conf
* Wi-FiのIPアドレス

## 手順 ##
![スクリーンショット 2022-12-11 12.14.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952182/a165534d-30d8-e967-171f-0b50263eb044.png)
![スクリーンショット 2022-12-11 12.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952182/1e56ed3a-1715-8b4b-1143-0a8034555f8e.png)

<dl>
    <dt>ネットワーク環境を調べる</dt>
    <dd>「システム環境設定」→ 「ネットワーク」</dd>
    <dd>または</dd>
    <dd>「左上のアイコン」→ 「システム環境設定」→ 「ネットワーク」</dd>
    <dd>画像の赤線の部分が現在接続しているネットワークのIPアドレスになります。httpd.confに記載するので設定する際にはコピーする事をオススメします。</dd>
    <dt>httpd.confの設定</dt>
    <dd>「フォルダ」→ 「アプリケーション」→ 「MAMP」→ 「apache」→ 「httpd.conf」</dd>
    <dd>httpd.confをメモ帳またはVSCodeなどのエディタで開く。</dd>
    <dd>57,58行目にListenの項目があるので59行目に以下を記載する。</dd>
    <dd>Listen Wi-FiのIPアドレス(画像の赤線の部分):1024と適当な使用可能ポート番号を割り当てます。</dd>
    <dd>例) Listen 123.456.1.11:1024</dd>
    <dd>入力が完了したら保存してMAMPを再起動し、Listenに登録したIPアドレスにアクセスします。</dd>
    <dd>サイトが閲覧できていらば成功です。</dd>
</dl>

## 最後に ##
以上の設定で簡単に自宅ネットワーク内で作成したWEBアプリケーションをどの端末からでもアクセスできるようになりました。今後も、定期的にネットワークの設定周りやプログラムに関する記事を書きたいと思います。
2022年12月EC-CUBE名古屋UGに参加したまとめ

**【初心者向け】もう一度学ぼう、ファイルパーミッション。そして今年2022年の振り返り | EC-CUBE名古屋 vol.90**に参加したので、簡単にまとめます。

[EC-CUBE名古屋UG Doorkeeperコミュニティページ](https://ec-cube-nagoya.doorkeeper.jp/)

今回なぜ参加したかというと、講師の大河内さんが前からパーミッションについて発信していたからです。
パーミッションについて細かい事が質問できると思いました。

参加した事により悶々としていた部分は解消できたと思います。

## なぜパーミッション？

最近EC-CUBEを攻撃した手法として「Water Pamola」がありました。
住所などに見慣れない文字列、パッとみたら文字化け？って感じの注文が入っているのを見た人もいるかもしれません。

そこからある操作を行うと、webshellが設置され不正な事を色々を行われてしまいます。

その中の一つとして、テンプレートを改変され、注文を完了させる段階で顧客情報やクレジットカード情報などを盗まれてしまいます。

テンプレートの改変をさせない為に、パーミッションを設定しようという話でした。

## パーミッションを設定したらどうなる？
例えば、テンプレートの改変を行わせないため、テンプレートのパーミッションを設定し書き込みを出来ないようにします。

そうすると、管理画面からテンプレートを編集できないようになりますので、テンプレート編集機能をよく使っている方は不便になります。

管理画面の機能が潰れるので、それがデメリットになります。
全く使ってないなら潰しておいた方がよいですね。

## 悶々としていた部分
自分はレンタルサーバーを使っての構築が多いため、パーミッションと聞いてもあまりピンと来ませんでした。

その部分を質問してみると、**レンタルサーバーはパーミッションの設定は意味がない**といった感じでした。
レンタルサーバーは管理ユーザー（契約しているユーザー）権限でPHPが動いているのが原因です。

パーミッションのお話は、**VPSなどのサーバーに向けたお話**でした。
VPSなど構築した事があるので、やっとピンと来ました。

PHPを動かしているユーザーはデフォルトだと「apache」や「www-data」だったりします。
ファイルをFTPなどでアップすると、アップロードしたユーザーが所有者になります。

ファイルの所有者とPHPの実行者が別なので、パーミッションの設定が効いてくるという事ですね。

## 詳しく知りたいという方へ向けて

大河内さんの書いた以下の記事にパーミッションの事も書かれているので、セキュリティに関心が出た人は読んでみてください。

[脆弱性対応勉強会Expansion 第05回(OWASP ZAP&EC-CUBE)発表資料](https://zenn.dev/nanasess/articles/vulnstudy05-owasp-and-eccube)

また、記事の中に「[WordPress の安全性を高める](https://wpdocs.osdn.jp/WordPress_%E3%81%AE%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B)記事は、とても参考になります」とあります。
勉強会の中でも、この記事の事を推していました。
こちらの記事にもパーミッションについて書いてありますので、読んでみてください。

EC-CUBEのドキュメントにもパーミッションのページがあります。
[EC-CUBEドキュメントパーミッション設定](https://doc4.ec-cube.net/quickstart/permission)

## 最後に
もう少し詳しく書きたかったのですが、セキュリティの事なので間違いだらけな情報発信はヤメヨウというのと、ぶっちゃけまだ詳しく理解できてないので、ふわーっとした感じになってます。

**詳しく知りたいという方へ向けて**で紹介している記事を読み込んで、また別の機会に情報を発信出来たらと思います。

最後まで読んで頂き、ありがとうございました。
seleniumでフォームのテストを自動化する方法

# 前提条件
フォームのバリデーションチェックのテストって面倒ですよね。
いちいちフォームの入力窓に入力して、送信ボタンを押してエラーメッセージを読んでバグをなおして、またフォームに入力して
...なんて、入力項目がものすごく多いフォームだともう気が狂いそうです。
そこで、フォームの入力だけでも一発で実行する方法をまとめました。

- macOS 12.4 Monterey
- jupyter lab 3.1.4
- Python 3.9.5

jupyter labとpython3はインストールされている状態からスタートします。入っていない人は、インストールしましょう。
jupyter labはjupyter notebookでも大丈夫です。
またローカル開発環境でもテストできる方が便利なので、Google Colaboratoryではやらない方が良いと思います。

# jupyter labにプロジェクトファイルを作る

ターミナルで以下のコマンドを叩く。
通常、グローバルでインストールしていると思うのでディレクトリはどこでもOKだと思います。
```
$ jupyter lab
```

ブラウザでjupyter labが開くので、ウインドウ左上のjupyter labのロゴの下あたりにある＋マークのボタンを押す。


Notebookの`Python 3 (ipykernel)`ボタンを押して新しいプロジェクトファイルを追加する。

# 色々インストールする

```
!pip install selenium

# 現在使用しているchromeと同じバージョンのChrome Driverを自動でインストールしてくれるwebdriver_managerをインストール
!pip install webdriver_manager
```

# インストール先を確認する
先ほどpipでインストールした先を調べて、環境変数を設定します。

```
# pipでwebdriver_managerをインストールした場所を調べる
import sys
print(sys.executable)
```
これで出力されたパスを次のappendメソッドの引数に渡します。

```
# pipでwebdriver_managerをインストールしているディレクトリの環境変数を渡す
import sys
sys.path.append('パス')
```

# ブラウザを開く

```
from selenium import webdriver
from time import sleep
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
```


# URLにアクセスする

```
driver.get('テスト環境のURL')

sleep(1)
```

# 入力窓に値を入力

入力窓のセレクタを調べて引数に入れないといけませんが、ここが結構面倒なので、デベロッパーツールでinputタグを右クリックして、コピー > xpathをコピーを選択してコピーします。

![スクリーンショット 2022-12-11 18.45.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262827/8e14bcc2-8c56-a449-ac62-6bc8cf472d35.png)

以下のfind_element_by_xpath()の引数にペーストすれば確実にそこへ入力させることができます。
あとは、入力窓に入力したい値をsend_keysに入れましょう。

```
# 入力窓を取得と入力(入力窓のHTML上で右クリックしてCopy XPathをして取得した値を入れる)
elem_username = driver.find_element_by_xpath('取ってきたxpath')
elem_username.clear()
elem_username.send_keys('入力したい値')
```

これを繰り返して、フォームに入れたい値をどんどん書いていきます。

ちなみに、新しいselenium4以降は、このセレクタの書き方が変わったようです。
新しいバージョンを使用している方は、公式ドキュメントに書き方が書いてあるので、そちらを参考に書き換えてみてください。

参考：[【Python】find_element(By.XPATH, "xxx")・・・xpathから要素を取得する](https://www.seleniumqref.com/api/python/element_get/Python_find_element_by_xpath.html)


# 送信ボタンを押させる

送信ボタンのxpathもデベロッパーツールから調べてきて、引数に入れてください。
実行させると送信ボタンが押されます。

```
elem_submit_btn = driver.find_element_by_xpath('取ってきたxpath')
elem_submit_btn.click()
```

あとはひたすらデバッグです。
では、良いテストライフを〜！

# おまけ：basic認証を抜ける方法
basic認証をかけているサイトだと、サイトにアクセスした時に認証に引っかかって、フォームに直接入れない場合があります。
その場合は、一度サイトのTopへ遷移するURLを、以下のように工夫をする必要があります。

```
driver.get('http://basic認証のユーザ名：パスワード@テスト環境のTopページURL')
driver.get('　フォームページのURL')
```
usdShade material(Material binding)のメモ

USD の `material:binding` ようわからん...

##https://openusd.org/release/wp_usdshade.html#usdshade-material-assignment

## 基本

`rel` (Relationship) でマテリアルノードのパスを指定します.

```
def Mesh "bora" {
  rel material:binding = </Material/diffuse>
}
```

ターゲットとなるパスは一個だけです.
ちなみに USDA 上では相対パスも指定できますが(e.g. `<../diffuse>`), USDC(crate binary)では絶対パスしか扱えないため, 読み込み時に絶対パスへと変換されます(USDA でよんで USDA で print(e.g. usdcat)すると絶対パスになっています)

## variant?


```
  rel material:binding:preview = </Material/diffuse/preview>
```

のように suffix でプレビュー用マテリアルなど設定できます.

## collection

material のターゲットパスを複数持てます.

```
rel material:binding:collection:boras = [</Material/diffuse/bora1>, </Material/diffuse/bora2>]
```

`material:binding:collection:NAME` で `NAME` はトークンのみでさらなるネームスペースを追加するのはできないです.

## 評価順(Strength)

```
def Xform "muda" {
  rel material:binding = </Material/specular>

  def Mesh "ari" {
  }

  def Mesh "bora" {
    rel material:binding = </Material/diffuse>
  }
}
```

のように親(祖先)の Prim にマテリアルをアサインすることができます. この場合親で定義されているが子で定義されていない場合(`ari`), 基本は親の設定を見ますが, これを `bindMaterialAs` で親が強いようにするのもできるようです.
Collection とか instance を考えての対応のようです.

詳細は UsdShade Material Assignment の URL にある GetBoundMaterial の pseudo code を参照ください

https://openusd.org/release/wp_usdshade.html#material-resolve-determining-the-bound-material-for-any-geometry-prim
【備忘録】Elasticsearchの search API

# 1.ElasticserchのサーチAPI
***GET|POST /{index}/{type}/_search***

# 2.サーチAPIのバリエーション
* /_search
 すべてのインデックス内のすべてのタイプを対象に検索する。
* /blog/_search
 blogインデックス内のすべてのタイプを対象に検索する。
* /blog.author/_search
 blogとauthorインデックス内のすべてのタイプを対象に検索する。
* /b*,a*/_search
 bから始まるインデックスと、aから始まるインデックス内のすべてのタイプを対象に検索する。
* /blog/posts/_search
 blogインデックス内のpostsタイプを対象に検索する。
* /blog,author/posts,users/_search
 blogとauthorインデックス内のpostsとusersタイプを対象に検索する。
* /_all/posts,users/_search
 すべてのインデックス内のpostsとusersタイプを対象に検索する。

# 3.APIのパラメータ
* ?pretty=true(pretty)：JSON形式結果を返すようElasticsearchに指示。(レスポンスの結果を見やすくする)
* ?format=yaml:ymlで出力したい場合に指定
* q=*：インデックス内のすべて(=*のため)のドキュメントに一致するようElasticsearchに指示。
* size:一度に検索結果を取得する数を指定。デフォルトは10
* from:スキップする検索結果数を指定。デフォルトは0
* sort=:フィールドとasc/descを指定するとそれに応じたソートを実行
* bytes=:出力する単位を指定

 例1)
```
curl GET /blog/_search?q=*&sort=account_number:asc&pretty
```
→blogインデックス内のすべてのドキュメントのaccount_numberフィールドを昇順でソートして結果を表示

例2)
```
GET /_search?size=5
GET /_search?size=5&from=15

```

例3)
```
curl -s GET _cat/indices?v&bytes=kb

 status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
 green open   blog    rwvaOBVcRaGjqt3NDRFV-w   5   1          0            0       32           32
 ```
NPF(NetBSD Packet Filter)でMSSクランプ設定を行ってみる

[NetBSD Advent Calendar 2022](https://qiita.com/advent-calendar/2022/netbsd) 11日目の記事です。 今日はNPF(NetBSD Packet Filter)でMSSクランプ設定を行う手順を紹介しようと思います。

## MTUとMSSクランプ

ネットワーク上で一度に送信できるデータの最大サイズを示す単位として、MTU(Maximum Transmission Unit)があります。この値は使用するネットワークの種類やVPNなどでカプセル化が行われた場合でそれぞれ異なります。例えば、イーサネットのMTUは1500オクテットとなっています。

ご家庭でインターネットに接続する場合は、[PPPoE(Point-to-Point Protocol over Ethernet)](https://ja.wikipedia.org/wiki/PPPoE)という通信プロトコロルを用いることがあります。通常は回線事業者からレンタルされるHGW(ホームゲートウェイ)や[ONU(Optical Network Unit)](https://ja.wikipedia.org/wiki/%E5%85%89%E5%9B%9E%E7%B7%9A%E7%B5%82%E7%AB%AF%E8%A3%85%E7%BD%AE)がPPPoEを話してくれるのでユーザはこのプロトコルを意識する必要はありませんが、PCルータのように、自分でルータを構築する場合にはPPPoEまわりの設定を行うことになります。

さて、このPPPoEですが、Ethernetヘッダの後ろにPPPoEヘッダ(6オクテット)とPPPヘッダ(2オクテット)を付与したPPPoEフレームでやりとりします。そのため、このPPPoEヘッダの分だけMTUのサイズが小さくなります。MTUを超えるIPパケットはネットワークに流せないため、MTUを1500オクテットのままにしている場合は、パケットが通ったり通らなかったりという奇妙な挙動になります。分かりやすい例では、Webページを開いた際に、表示される画像があったりなかったりという場合があります。

このデフォルトのMTUから変更したい場合に用いるのがMSS(Maximum Segment Size)クランプという機能です。これにより、MTUを任意のサイズに調整することが可能になります。

## NPFでのMSSクランプ設定

NPFでMSSクランプの設定は以下のようになります。 `procedure` ブロックの中で `normalize: "mas-mss" <任意のMTUサイズ>` の形で設定します。

一般的なファイアウォール(またはNAT実装)では、MSSクランプ機能は内部に組み込まれているものですが、NPFでは拡張機能の形でMSSクランプが実装されています。そのため、 `procedure` で `normalize` カスタムプロシージャを呼び出している、というイメージになります。

```
$ext_if = "pppoe0"

procedure "mss-clamp" {
  normalize: "max-mss" 1400
}

group "external" on $ext_if {
  pass stateful out final all apply "mss-clamp"
  pass stateful in  final all apply "mss-clamp"
}
```

### procedureはapplyしないと適用されない

ここで一点だけ気をつける必要があります。 `procedure` はあくまでもカスタムプロシージャの呼び出しを宣言するだけであるため、「ルールにマッチした際にプロシージャを適用する」という設定を併せて行う必要があります。

先述した設定にもあるように、ルール記述時に `apply "mss-clamp"` を指定することで、設定したプロシージャが適用されます。
この例ではステートフルに通過するパケットに対してMSSクランプを提供する設定になります。

```
group "external" on $ext_if {
  pass stateful out final all apply "mss-clamp"
  pass stateful in  final all apply "mss-clamp"
}
```

## まとめ

NPFでのMSSクランプ設定について紹介しました。一般的なファイアウォールのルールではMSSクランプ設定をそのまま指定できますが、NPFでは拡張機能としてMSSクランプ機能が実装されているため、プロシージャ呼び出しを宣言しておき、併せてマッチしたルールの側でプロシージャの適用を設定するという使い方になります。
【Python】OpenCVで画像処理（顔検出）（初心者向け）

# １．はじめに
PythonにてOpenCVを用いた画像処理を実施したのでまとめました。
前回からの続きで、グレースケールに変換した画像から正面から見た人の顔を検出しマスクします。
djangoの使用については、株式会社キカガク殿にて学習した内容を元に作成しました（djangoの説明については割愛します）。

# ２．開発環境
・Windows10
・Python 3.9.12
・opencv-python--headless==4.5.1.48
・Pillow==9.2.0

# ３．顔検出
顔検出を行うため、OpenCVのカスケードファイルである「haarcascade_frontalface_default.xml」という人の正面からの顔を検出する分類器を使用します。

```
import cv2
from PIL import Image
(省略)

# カスケードファイルの保管場所取得
cascade_path = settings.BASE_DIR + "/imgrayapp/haarcascades/
(省略)

# 元画像の保管場所取得
path = settings.BASE_DIR + obj.document.url
(省略)

# 顔検出
# 学習済みモデルの読み込み
cascade = cv2.CascadeClassifier(cascade_path)
# detectMultiScaleで顔検出
# minSizeで最小検出サイズを指定（下記(20, 20)は20ピクセル*20ピクセル以下は探さないを意味する）
# img_grayはグレースケールに変換した画像を示す
face_list = cascade.detectMultiScale(img_gray, minSize = (20, 20))
                
# face_listの値をまとめる
x = face_list[0][0] # X座標    
y = face_list[0][1] # Y座標
w = face_list[0][2] # 横幅
h = face_list[0][3] # 縦幅

```

# ４．検出した顔をマスク
顔を検出した後、顔を隠すための画像を顔のある位置に貼り付けます（顔を隠すための画像はあらかじめ用意しておきます）。その際、画像を加工するためpythonの画像処理ライブラリであるPillowを使用します。

```
# 人の顔に張り付ける画像の保管場所取得
maskimage = settings.BASE_DIR + "/media/documents/maskimage.png"
# PILで画像を開く
original_image = Image.open(path)
maskim = Image.open(maskimage)
            
# 顔にあったサイズにマスク画像をリサイズする
resize_maskim = maskim.resize((w, h))
resize_maskimage = settings.BASE_DIR + "/media/documents/resize_maskimage.png"
resize_maskim.save(resize_maskimage)
            
# 元画像はそのままにしておくため、コピーを用意する
back_im = original_image.copy()
            
# 背景透過のためのsplit()
back_im.paste(resize_maskim, (x, y), resize_maskim.split()[3])
            
# 保存する
mask_image = settings.BASE_DIR + "/media/gallery/mask_image.jpg"
back_im.save(mask_image)
obj.faceimage = "gallery/mask_image.jpg"

```

# ５．結果
下の画像は、顔を検出しマスクする前と後の画像になります。
![lenna.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2940692/81f2dffc-c075-8d7f-6d27-82300cfec9ea.png)
マスク前の画像

![mask_image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2940692/88cb9efe-8748-b3bc-46d6-c08fb030903c.jpeg)
マスク後の画像

無事顔の位置を検出し、マスクすることができました。

# ６．Webアプリ
Djangoを使用し、人の顔をマスクするWebアプリケーションを作成してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2940692/a8f250b0-db6a-cc56-2e4b-1fd47d1b27a4.png)
ファイル選択画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2940692/01c8bb17-9914-4c1a-889f-2296c15e9016.png)
実行結果

画像で顔を隠す手法以外に、検出した顔の位置のみモザイク加工をして顔を隠す手法も実施しました。

# ７．参考文献
・https://camp.trainocate.co.jp/magazine/python-opencv/
AWS認定クラウドプラクティショナー合格に向けて Day20

# 前回の内容
[AWS認定クラウドプラクティショナー合格に向けて Day19](https://qiita.com/Ayako_0224/private/7f5bb750767495945320)

# データベース
関連したデータの形式を揃えて収集・整理してデータ管理を実行するシステム
ストレージ+データを管理・操作するデータベースソフトウェア
基本的にはテーブルという形式でデータを格納している
CRUDのデータ操作を簡単に実行するソフトウェアやデータモデルと一体
DBMS...データベースを実現したシステム

## トランザクション
データベースをある一貫した状態から別の一貫した状態へ変更する1つの処理の束
ACIDは信頼性のあるトランザクションシステムの持つべき性質
### Atomibity(原子性)
全て実行されるか1つも実行されないのどちらかのみという性質
### Consistency(整合性)
トランザクションの前後でデータの整合性が保たれ、矛盾のない状態が継続される性質
### Isolation(独立性)
実行中の処理過程が外部から隠蔽され、他の処理などに影響を与えない性質
### Durability(耐久性)
トランザクションが完了したら、その結果は記録され、クラッシュしても失われることがないという性質

## データモデル
データモデルは6つある
- リレーショナルモデル(RDS)
- グラフモデル
- キーバリューストア(KVS)
- オブジェクト
- ドキュメント
- ワイドカラム
- 階層型

# RDS
様々なデータベースソフトウェアに対応したフルマネージドなRDS
- MySQL
- PostgreSQL
- Amazon Aurora

## 制約事項
AWSから提供される機能範囲内での制限を受ける
- バージョンが限定される
- キャパシティに上限がある
- OSへのログインができない
- ファイルシステムへのアクセスができない
- IPアドレスが固定できない
- 一部の機能が使えない
- 個別パッチは適用できない

## スケーリング
マネージメントコンソールやAPIからインスタンスタイプを変更することによってスケールを調節できる
ストレージサイズは拡張のみしかできない

データベースシャーディングを利用してRDSの書き込み処理をスケーリングする(UUIDにしなければ死)

アドベントカレンダーの「AWS認定クラウドプラクティショナー合格に向けて」としてはこれが最終の記事となります。続きは普通に投稿します。
Dockerについて

MY備忘録

イメージ
【取得】
```
$ docker image pull
```

【ビルド】
```
$ docker image build
```

コンテナ

【生成】
```
$ docker container create
```
【起動】
```
$ docker container
```
【停止】
```
$ docker container stop
```
【削除】
```
$ docker container rm
```
【生成・起動】
```
$ docker container run
```
【再起動】
```
$ docker container restart
```

Docker Compose

【ビルド】
```
$ docker-compose build
```
【生成・起動】
```
$ docker-compose up
```
【停止】
```
$ docker-compose stop
```
【削除】
```
$ docker-compose rm
```
【再起動】
```
$ docker-compose restart
```
【停止・削除】
```
$ docker-compose down
```
【起動中のコンテナでコマンドを実行】
```
$ docker-compose exec
```
【コンテナの一覧を表示】
```
$ docker-compose ps
```
【ログを表示】
```
$ docker-compose logs
```
【使用してないコンテナ、イメージを削除】
```
$ docker system prune
```
**※下記はdocker-compose.ymlがあるディレクトリ内で実行する**
```
$ doceker-compose
```
自社開発企業への転職にアウトプットは必要？~開発実務3年目のエンジニアが転職活動を通して感じたこと~


AdventCalendar初参加です。
カレンダーに自分の誕生日があったので、この日にAdventCalendarの記事を投稿させていただきます。（投稿が1日遅れましたが）たくさんの人に読んでもらえるとうれしいです。


# はじめに
本題に入る前にこの記事を投稿しようと思った経緯や想定読者（こういう人に読んで貰えるとためになるかも！）について語ります。
面倒な方は読み飛ばしても大丈夫です。

## 記事投稿に至る経緯
ここ数年、エンジニアという職業は人気が高まっており、異業種から転職してエンジニアになった方も多いです。中でもゴリゴリ手を動かしたい若手エンジニアの中には、**自社開発企業で働いて経験を積むこと**を一つの目標としている方が、少なからずいるのではないでしょうか？

私もその1人でした。

今の環境で経験を積めたら自社開発企業に転職したいと考えていましたが、本当に内定がもらえるのか、ポートフォリオみたいな明確なアウトプットがないと転職できないんじゃないか、と常に考えながら約3年間エンジニアの仕事をしていました。
そんな私が直近（記事投稿日の数か月前）で自社開発企業へ転職することができたので、転職にアウトプットは必要なのか？開発実務3年目のエンジニアが自社開発企業への転職活動を通して感じたことを書いてみたいと思います。

## 想定読者
20~30代のエンジニアの方、またはエンジニアを目指している方
特にSES, SIerで働いていて、転職を考えているエンジニアの方

## 私について
本題に入る前に私自身のことを軽く紹介します。
主に、どんな背景の人が転職活動をして、どういう見方をされたかを知る、材料になればと思います。面倒な方は飛ばしてもOKです。

### 投稿者の経歴
実務3年目のエンジニアです。（2022年12月時点）
これまでの社会人キャリアは、建築士3年弱 → （プログラミングスクール&転職） → SESのアプリ開発エンジニア2年3ヶ月（3年目）
SESでは大手～中堅SIerの現場で業務系Webアプリケーションを設計〜開発・テストまで行うといった感じです。言語はJavaがメインでした。
翌2023年の2月からは自社開発企業で働きます。

### 転職活動前にやっていたアウトプット
私がSESに入社し、エンジニアとしてのキャリアをスタートさせてからこれまでやっていた学習やアウトプットです。業務外でやったことに限定して書きます。
- 資格取得とその勉強
    - Java Bronze, Silver, Gold
    客先がSIerで資格を持っていることが評価に繋がる環境なので、推奨されており取得

#### ここだけの話...
仕事以外の時間は趣味に没頭したいタイプなので、あまり自己学習をしていませんでした。


### 転職活動後にやったアウトプット
- 技術記事の投稿
転職活動を始めてから投稿開始、投稿は5件くらい
- 個人開発
設計だけ着手、GitHubにリポジトリとかはない


# 本題
ではここから本題です。あくまで私見なので、ふーん。と、いち参考程度に聞いてもらえるとありがたいです。

## 結局、転職活動でアウトプットって評価されるの？
**転職活動でアウトプットは評価されます。**
ただし、質の高い経歴書がしっかり書けていて、面接では簡潔に会話ができる、というような基本的な要素があった上で、プラスαとして評価されるイメージです。技術力があるから内定がもらえると言うわけではないです。

また、なぜこのアウトプットをやったのかと言うストーリーがしっかりあった方が良いです。


## アウトプットって何をやればいいの？
次に気になるのは、「じゃあアウトプットって何をやればいいの？」といるかもしれません。
知ってる人は読み飛ばしてもOKです。
- 技術記事
    - QiitaやZenn、ブログに技術記事の投稿をする
- 個人開発（≒ポートフォリオ）
    - 個人開発を進め、GitHubなどのrepositoryを公開し、webサービスならURLを公開する


## 転職以外にアウトプットのメリットはある？
もちろん転職を今すぐしない人にもアウトプットをするメリットはあると思います。

ここは追記予定!
Wordpressでローカルに環境再現するまで

# やりたいこと
既に公開されているWordpressのサイトに手を加えたいが直接編集するのは何かあった時に怖い。
ならローカルで本番環境を再現しよう。でもFTPが使えないなあ。
そんなときの対応手順まとめ。

# ローカル環境構築
ローカル環境構築には「[Local](https://localwp.com/ "Local")」を使用する。
インストール後、`Add new Site`　からPHPやmySQLのバージョンを本番に合わせて構築。

ローカル環境のサイト名を決めて
<img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/7cfc024b-9faa-8d5a-65d4-c2b5981e7d48.png">
PHPやmySQLのバージョンを指定(※1)
<img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/2f565a3e-2b97-245e-9224-e9280aaf6666.png">
ローカル環境のログインIDとパスを指定（ここは後ほど変わるので適当でOK）
<img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/d8c163a6-de42-e2b6-9645-0e876127fd89.png">

※1. バージョン確認方法
本番環境の管理画面にログインし `ツール＞サイトヘルス＞情報タブ` 内の `サーバー` `データベース` 内で確認可能です。
<img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/86b15d00-d21c-d88f-ce84-e59a9abb0197.png">

これでLocal内に初期状態のwordpressが構築されました。

## いざバックアップ
バックアップにはWPのプラグインを使用する。

### プラグインの選定
「[backWPup](https://ja.wordpress.org/plugins/backwpup/)」を使ってバックアップを取り、先ほど作成したサイトにimportしたが失敗
→ Localのバージョンと噛み合わないのかsqlエラーでimport失敗するので断念
→ 解決策として古いLocalインストール試せって書いてたけどvirtualboxらへんでうまくいかず

#### 「All-in-One WP Migration」を使用

1\. Localで先に環境構築　php,sql,serverバージョンは本番に合わせておく
2\. 本番環境の管理画面にログインし、プラグインをDLし、エクスポート
3\. Localでインポート

#### 本番環境のエクスポート

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/61556812-46d0-5c2b-49cc-22529c3f29f4.png" width="400">

本番環境のパスをローカル用に置換
本番： test-live-xxx.com
ローカル： test-local-xxx.com

エクスポート先は`ファイル`を選択
エクスポート成功すればダウンロードボタンが表示されるのでそれを保存。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/cb89a743-1197-d689-0c96-bd5cafd4b222.png" width="300">

#### ローカル環境でのインポート
##### インポート時の落とし穴
`All-in-One WP Migration 無料版`では容量制限が`518MB`しかなく、バックアップファイルのサイズがそれを超える場合、インポートできなかった。

プラグインを[こちら](https://drive.google.com/file/d/19Nu0oLahhAaETsH_OPp8jFDFuvgCxFZ6/view)からダウンロード（ver.6.68を使う）
zipファイルをワードプレス上にインストール。
他verを使用している場合はアンインストールしておく。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/8eb037a8-6a76-2066-fa4b-12ff890f477a.png" width="300">

管理画面＞ツール＞プラグインエディタ＞constants.php

```php:constants.php
// =================
// = Max File Size =
// =================
define('AI1WM_MAX_FILE_SIZE', 536870912);

// ↓ に変更（10倍に）

// =================
// = Max File Size =
// =================
define('AI1WM_MAX_FILE_SIZE', 536870912 * 10);
```

#### そしてインポート
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2718989/c8805f1d-66ca-d077-da8f-626ba7f45f0b.png" width="300">

本番環境と同じID＆パスワードでログインしてローカルに環境再現できました。


参考にさせて頂きました
https://haniwaman.com/wordpress-trace/
https://purikuro.com/2021/02/03/allinonewpmigration_max/
AWS App runnerでアプリケーションを動かす

# はじめに
本記事は[ARISE analytics Advent Calendar](https://qiita.com/advent-calendar/2022/arise-analytics) 2022の12日目です。

ウェブアプリケーションのクラウド構成について考える機会があり、勉強のためにAWS App Runnerで簡易的なアプリケーションの立ち上げを試してみました。

# AWS App Runnerとは？
AWS App Runnerとは、2021年に発表されたAWS上でコンテナ化されたアプリケーションをより簡単に構築・運用できるフルマネージドサービスです。アプリケーション運用に必要なインフラ周りをほとんど気にすることなく、GitHubなどに反映したコンテナを簡単にデプロイ・運用することが可能です。

これまではウェブアプリケーションを構築する際に、VPCやロードバランサー、Auto scalingなどのインフラ設定をする必要がありました。
![スクリーンショット 2022-12-11 2.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/15b99729-04f5-2072-c6f8-6054a97e38d8.png)

一方で、アプリケーションを構築するためのインフラをパッケージ化して1つのマネージドサービスに集約したものがApp Runnerです。上記画像に記載のあるECR以外のサービスはApp Runnerがまとめて代替してくれるため、以下のような簡易的な構成をとることができます。

![スクリーンショット 2022-12-11 2.54.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/ca0c11bc-16bf-77ea-235b-4cdcb04ec0fb.png)


# 実際に触ってみる
実際にApp Runnerでウェブアプリケーションのデプロイ設定をしていきます。ここではGitHubのレポジトリを指定することができます。

![スクリーンショット 2022-12-11 2.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/ad8a4862-7d8c-d179-4e7c-32eff1fa1e8d.png)

構築設定をコンソール上で進めていきます。今回利用するサンプルアプリケーションがPythonで書かれているため、それに合わせて設定をしていきます。
![スクリーンショット 2022-12-11 10.42.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/aa8c2287-6117-cf99-ffea-f2872367a700.png)

メモリサイズやAuto Scalingの設定などもしていきます。今回は特に何も考えず、デフォルトの値で進めます。
![スクリーンショット 2022-12-11 3.04.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/83517d17-f361-10d7-48f6-4fbd38f417a9.png)

最後に設定内容を確認した上で作成ボタンを押すと、デプロイが始まります。
![スクリーンショット 2022-12-11 3.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/e905d460-0f2d-183d-1f95-9b146ae235cf.png)

正常にアプリケーションが立ち上がると、ブラウザでデフォルトドメインにアクセスすることができるようになりました。
![スクリーンショット 2022-12-11 17.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158367/b3b4f57c-d23a-b2e6-1f38-82ec23cb1627.png)


# 最後に
AWS App Runnerでアプリケーションのデプロイを実際にやってみました。細かい要件が求められるような商用アプリケーションではまだまだECS/Fargateの利用が続くとは思いますが、簡単なアプリケーションであればインフラを気にせずにクイックに構築ができるApp Runnerもオプションとして検討できるのかなと感じました。
chronyでNTPサーバ（タイムサーバ）の設定をする

従来、時刻同期に使用していた`ntp`に代わり、`chrony`が使われているのは周知の事実かと思いますが、構築したサーバをNTPサーバとして使用する要件があり、`firewalld`で`NTP(UDP123)`の許可は追加したのにクライアント側から時刻同期が出来ないと言われたことがあったので。。

## chronyの設定を確認する
chronyの設定ファイルは、`/etc/chrony.conf`です。
（各項目の説明は割愛します。）
```
# cat /etc/chrony.conf

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool 2.centos.pool.ntp.org iburst

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift

# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3

# Enable kernel synchronization of the real-time clock (RTC).
rtcsync

# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *

# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2

# Allow NTP client access from local network.
#allow 192.168.0.0/16

# Serve time even if not synchronized to a time source.
#local stratum 10

# Specify file containing keys for NTP authentication.
keyfile /etc/chrony.keys

# Get TAI-UTC offset and leap seconds from the system tz database.
leapsectz right/UTC

# Specify directory for log files.
logdir /var/log/chrony

# Select which information is logged.
#log measurements statistics tracking
```

## NTPクライアントを許可する

今回変更するのは、以下の項目です。
```
# Allow NTP client access from local network.
#allow 192.168.0.0/16
```

何やらNTPクライアントのアクセスを許可する的なことが書いてありますね。
なので、以下のように時刻同期を許可するアドレス（ネットワーク）を追加すれば良いだけです。
```
# Allow NTP client access from local network.
#allow 192.168.0.0/16
allow 10.171.1.0/24
```

`cronyd`を再起動します。
```
#　systemctl restart  chronyd.service
```

以上です。（早）
記事にするほどでもありませんでしたね…

chronyの設定はしたことあったんですが、NTPサーバとしての設定をしたことがなかったので知りませんでした。。

そういえば最近、うるう秒が廃止される的なニュースを見て、真っ先に「そういえばchronyにうるう秒の設定するとこあったよな～」って思いました。余談でした。
FEの擬似言語をもとにHeapSortやってみた


基本情報技術者の擬似言語の学習のため実際にプログラム化してみました。
仕様はそのままに一部アルゴリズム強化のため自分で自分で条件式等を考えているため実際の擬似言語プログラムとは差異があります。



```java:qiita.java
import java.util.*;

public class HeapSort {

  public static void main(String[] args) {

    // 変数

    Scanner sc = new Scanner(System.in);

    System.out.println("配列の要素数を入力してください");
    int n = Integer.parseInt(sc.next());
    int data_array[] = new int[n]; // [20,50,10,30,70,40,60,80]

    System.out.println("配列の各要素を" + n + "回入力してください");
    for (int i = 0; i < n; i++) {
      data_array[i] = Integer.parseInt(sc.next());
    }

    // ヒープ木の作成
    for (int i = 1; i < data_array.length; i++) {
      // ヒープ木の作成
      makeHeap(i, data_array);
    }

    /*
     * ヒープの昇順並び替え
     * ヒープ木の再構築
     */

    for (int i = data_array.length - 1; i > 0; i--) {

      // 配列先頭要素と配列末尾の要素を入れ替え
      swap(0, i, data_array);
      // 並び替え範囲を狭めてヒープ木再構築
      remakeHeap(i - 1, data_array);

    }

    // 並び替え終了
    // 出力
    resultPrint(data_array);
  }

  // ヒープ木の作成(一番大きい要素を先頭へ)
  public static void makeHeap(int child, int[] data_array) {

    while (child != 0) {

      if (data_array[child] > data_array[parentIndex(child)]) {

        // 入れ替え
        swap(child, parentIndex(child), data_array);

        // child更新 要素番号を返す
        child = parentIndex(child);

      } else {
        child = 0;
      }
    }

  }

  // ヒープ木再構築 範囲内で一番大きいものをヒープ木の根とする。
  public static void remakeHeap(int heap_range, int[] data_array) {
    int data_array_parent_index = 0;
    int tmp = 0;

    // 左子が配列の範囲内にいるか
    while (leftChildIndex(data_array_parent_index) <= heap_range) {

      tmp = leftChildIndex(data_array_parent_index);

      // 右子が配列の範囲内にいるか
      if (rightChildIndex(data_array_parent_index) <= heap_range) {

        // 左子の要素と右子の要素を比べる。大きい方を親と比較
        if (data_array[tmp] < data_array[rightChildIndex(data_array_parent_index)]) {
          tmp = rightChildIndex(data_array_parent_index);
        }
      }

      // 親と子どもを比較
      if (data_array[tmp] > data_array[data_array_parent_index]) {
        swap(tmp, data_array_parent_index, data_array);
      } else {
        return;
        // brakeならどうなる。
      }

      data_array_parent_index = tmp;

    }
  }

  // 親と子供を入れ替える
  public static void swap(int child, int parent, int[] data_array) {
    int tmp = 0;

    tmp = data_array[parent];
    data_array[parent] = data_array[child];
    data_array[child] = tmp;

  }

  // 親の添字を返す
  public static int parentIndex(int num) {

    if (num != 0) {
      return (num - 1) / 2;
    } else {
      // ゼロ除算でエラー対策
      return 0;
    }
  }

  // 左子の添字を返す
  public static int leftChildIndex(int left_index) {

    return 2 * left_index + 1;

  }

  // 右子の添字を返す
  public static int rightChildIndex(int right_index) {

    return 2 * right_index + 2;

  }

  // プリントアウト
  public static void resultPrint(int[] data_array) {
    System.out.println("結果表示");
    System.out.println(Arrays.toString(data_array));

  }

}
フリーランスになってみて。

こんにちは　花ちゃんです
フリーランスになり、1年ちょっとが経過したところですが
フリーランスではどのように働いて、どんなメリデメがあるのか
今後どうして行きたいのかなど書いていこうと思います。

<h2>どうしてフリーランスになったのか</h2>
フリーランスになった理由は３つとキッカケがあります。
<br><br>
キッカケは結婚です。今ではバリバリに働いていますが1ヶ月ほど専業主婦だったことがあります。
<br>
その時は、正直毎日暇でした。家事もまともにできず、することもなく、、
<br>
専業主婦の方に関してはとても尊敬してますが、私には向いていないとすぐに気づくことができました。
<br><br>
ではなぜ正社員ではなくフリーランスにしたのか。
<br><br>
1つ目の理由：住んでるところが僻地だから。<br>
私は津久井という都心から片道約3時間ほどのところに住んでいます。<br>
最寄駅が最寄りにありません笑<br>
主人の仕事の関係上、都心の近くに引っ越すこともできません<br>
出勤が難しいことから、リモートなど自由が利きやすいことで選びました。
<br><br>
２つ目の理由：いろいろなことをするより、Salesforceに絞った働き方をしたかったから。<br>
情シス特有なのか、私に限った話なのかわかりませんが、<br>
人事の仕事や法務の仕事、営業の仕事が降り掛かってることが多々ありました。<br>
Salesforceの仕事に集中するには、正社員で就職するよりフリーランスの方が集中できることで選びました。
<br><br>
3つ目の理由：自分のやりたいことがあったから。<br>
ここでは記載しませんが、私は成し遂げたいゴールがあります。<br>
それを達成させるには、自分の時間を自分で調整する必要があったからです。<br>
学業であったり、起業準備だったり、自分の時間を確保しつつ確実な収入が必要だったので選びました。
<br><br>

<h2>フリーランスのメリット</h2>
・頑張り次第ではあるが、同年代より稼げる<br>
・自分で自分のスケジュールを組むことができる<br>
・自動的に学ばなければいけない状態に追い込まれるので、成長スピードがはやい<br>
・好きな仕事に集中ができる<br>
・いろんな人に出会うことができる
<br><br>
全体的に言えることは全て自分にかかってるということ。<br>
自分の努力・行動が全て直結して結果になるので、自分を見直すことがしやすい。
<br><br>

<h2>フリーランスのデメリット</h2>
・契約が切れたら仕事がなくなる（常に営業を続ける必要がある）<br>
・自分の時間がとりやすい反面、休んだらその分だけ給料が減ることに直結する（有給などない）<br>
・自分のできないことがはっきりと出てしまう<br>
・仕事をする環境を自分で作らないといけないため、正社員では支給のところを自分で準備をしなければならない<br>
・研修なども自己負担となる<br>
・確定申告がとてもめんどくさい
<br><br>
全体的に言えるのはメリットと同様、全て自分にかかっているということ。<br>
正直にいうと、思っている以上に自分の力が足りないことがわかり凹みました。<br>
それでも、成長と思って頑張る姿勢が必要です。
<br><br>

<h2>これからフリーランスを考えている人へ</h2>
Salesforce界隈に限らず、技術者不足があるのでぶっちゃけ仕事はたくさんあります。<br>
ですが、そこで活躍するためにはそれ相応の技術が求められます。<br>
正社員は会社が守ってくれますが、フリーランスは自分で管理しなければなりません。<br>
自分の技術に磨きをかけたいという方がいればぜひフリーランスの道へ踏み出してもいいのでは？と思います。<br>
私もですが、資格を取ったり必要な技術を身につけられるように頑張りましょう！
<br><br>
フリーランスでは自分で管理が必要と書きましたが、助けてくれる方はたくさんいます。<br>
仕事を請け負ってる会社の担当の方、コミュニティ、SNS、繋がりがたくさんあればあるほど、困った時に助け合えます。
<br><br>

<h2>まとめ</h2>
Salesforce界隈ではまだまだフリーランスは少ないですが、誰でもチャレンジできる環境だと思います。<br>
全て自己責任。うまくいくもいかないも自分自身。常に努力をし続ける挑戦し続ける成長できる仕事方法である。<br>
認定アドミンだけでも資格を持ってると強いです。チャレンジしてみましょう。<br>
人との繋がりを大切にしましょう。小さなつながりからお仕事につながることや、詰まってるところの解決につながることがあります。<br>
私もまだまだ未熟ですが、今後活躍できるよう精進して行きたいと思います。
<br><br>
私は、ゴールに向かってたくさんの人と支えあって突き進んでいきます。<br>
悩み事があればいつでもご相談いただいて大丈夫ですし、私から連絡するかもしれません！<br>
これからもたくさんの出会いがありますように
AWS認定クラウドプラクティショナー合格に向けて Day19

# 前回の内容
[AWS認定クラウドプラクティショナー合格に向けて Day18](https://qiita.com/Ayako_0224/private/e7683b0766e264b81d97)

# AWSのストレージサービス
3つの形式のストレージサービスが提供されている
## ブロックストレージ
EC2にアタッチして活用するディスクサービス
EBSやインスタンスストアなど

## オブジェクトストレージ
安価で高い耐久性を持つオンラインストレージ
S3やGlacierなど

## ファイルストレージ
複数のEC2インスタンスから同時にアタッチできる共有ストレージサービス流
EFSなど

# S3
Simple Storage Service
ユーザーがデータを容量制限なく保存可能なマネージド型で提供されるオブジェクト型ストレージ

バケット...オブジェクトの保存場所でグローバルでユニークな名前の必要がある
オブジェクト...S3で格納されるファイルでURLが付与され、数は無制限

## オブジェクト構成
- key
- value
- バージョンID
- メタデータ
- サブリソース

## ストレージタイプ
### STANDARD
複数箇所にデータを複製するため耐久性が非常に高い
### STANDARD-IA
スタンダードに比べて安価
データの読み出し容量に応じた課金がされる
### One Zone-IA
アクセス頻度は低いが、必要に応じて取り出すデータに向いている
### RRS
Reduced Redundancy Storage
の低冗長化ストレージ
### Amazon Glacier
アーカイブ用ストレージでデータの抽出にコストと時間がかかる
ライフサイクルマネジメントで指定
ボールドロック機能でデータを保持する

## S3 Intelligent Tiering
低頻度アクセスのオブジェクトを自動的に低頻度アクセス層に移動することでコストを削減する

## 料金
これらの項目ごとに課金される
料金はよく変動し、リージョンごとにも微妙に異なる
- 容量あたりの料金
- データ取り出しリクエスト料金
- データ転送料金

## 整合性モデル
S3は高い可用性を実現するため、データ更新や削除には結果整合性モデルというものを採用する
同時書き込みはタイムスタンプ処理を実施する

## アクセス管理
インターネットからパブリックアクセスの設定が可能だが制限する場合は以下の方法がある
### IAMユーザーポリシー
S3サービスへのアクセスできるユーザーを設定する
### バケットポリシー
バケットへのアクセス権をJSONで設定
### ACL
バケットと個々のオブジェクトへのアクセス権限をXMLで設定する
### 署名付きURL
AWS SDKで生成した署名付きURLでS3のオブジェクトへ一定時間アクセスを許可する

## 暗号化
データ保管時に暗号化形式として以下の4つがある
### SSE-S3
標準暗号化形式でS3側で自動で実施される
### SSE-KMS
KMSに設定した暗号化キーを利用した暗号化を実施
ユーザー側で設定することができる
### SSE-C
ユーザーが指定したキーによるサーバー側の暗号化を使用することが可能
### クライアントサイド暗号化
S3に送信する前にデータをオン豪華する方式
KMSを利用して暗号化キーを作成・実施する
アプリケーション内に保存したマスターキーを使用する

## アクセスアナライザー
アクセスポリシーに沿っているかを確認し、不正なアクセスが発生していないか、アクセスポリシーを監視する機能

## S3データの解析
### S3 Select 
S3の内部機能にある検索機能でS3内で直接クエリを実行しデータを取得できる
### Amazon Athena
S3内のデータを直接簡単に分析できるようにするクエリサービス
### Amazon Macie
機械学習によりS3の機密データを検出、分類、保護するフルマネージド型サービス
### Amazon Redshift Spectrum
S3の格納データに対してRedshiftから直接クエリを実行できる機能

## CORS
クロスオリジンリソースシェアリング
これにより特定のドメインにロードされたアプリケーションが異なるドメイン内のリソースと通信する方法を定義

## マルチパートアップロード
大容量オブジェクトをいくつかに分けてアップロードする機能

## バッチオペレーション
S3オブジェクトの大量データに対して一括処理を実行することが可能
### ジョブ
S3バッチオペレーションの機能の基本単位でジョブを作成することでバッチオペレーションを作成
### マニフェスト
S3が作用するオブジェクトでキーをリストするAmazon S3オブジェクト
マニフェストオブジェクトキー、ETag,およびオプションでバージョンIDを指定する 

To be continued...
エンジニアに転生した話


## 自己紹介
私は未経験からエンジニアとしてデビューしました。エンジニアになってみて自分にとって新鮮な機会が多くあったので、もしこれからエンジニアを目指している人の参考になったら幸いです。なおポエムなので、お時間のあるときに読んでいただけるとちょうどいいかと思います。また本記事からQiitaデビュー。押忍。

## 結論
・エンジニアは大変、だけど自分の可能性を拡げれるんじゃないかなと思う！！


## よかったこと

- **定義された話が多い**
エラーの質問だと定義されているコードをもとに話すので、認識がずれない。ずれてたら話が進まないから当然なんだけど。
同じものを見て話すので、飛躍だったり、齟齬が起こったりしにくい。そこが気持ち良い。（伝われ）

   （例:index.html:Line30の◯◯が*TypeError: Cannot ~~.* とか何らかのエラーメッセージが出てくるので助かる）
   （ほら、人の会話って曖昧じゃん？日本語なんて特に”察する”って文化あるじゃん？）

- **テクノロジー関連の話題が増える**
職場での会話やSNSで、テクノロジーに関連する情報を見聞きする機会が増えます。最近だとAIアートやチャットAIが流行っていますね。流行しているテクノロジーを早い段階で知ることができるのは、テクノロジーと近い職域だからだと思います。また、自分自身もそういう情報をキャッチすることが当たり前になりました。

- **コミュニティが充実している**
エンジニアになる前は、みなさん一人で黙々とやっているイメージで、孤独極まりそうだなあと思っていました。しかし、探してみるとコミュニティが充実しているのかなと思います。

    コミュニティといっても様々なので一概には言えないですが、自分が欲しい情報は他の人も求めているように、似たような考えを持っている人が何かしらのコミュニティを立ち上げて運営しているような気がします。一人でやるよりも仲間がいた方が心強いですし、職場以外の居場所として良い機能だと思っています。


## 大変だったこと
いいことばかり書くのもあれなので、アナザーサイドも。

- **実力が顕著**
やはり経験を積んでいる人とそうでない人との差は残酷なほど大きいと感じます。エラーへの対処だったり、開発の見直しだったり、そういうのを回すのは経験値ではっきり出る部分だと思っています。知識がものをいう以上、そこはもう勉強あるのみだと思います。


- **エラーとの戦い**
自分ではうまくできたと思っても、どこかで必ずエラーが生じます。それは、システムのバッティングだったり、スペルが違っていたりと原因は色々です。そういう原因を一つ一つ取り除く根気が求められます。

    エラーばかり見ていると、堂々巡りしているようになってしまって、気づいたら何時間も経っていたということもしばしばあります。エラーが出たら、まずはエラー文を読んで、何が間違っているのかを特定することが大切ですね。


- **適切に質問できるかが超大事**
ほしい回答を得るには、適切な質問が大切です。適切な質問をするには、前提条件の書き出しや、試したこと、どうしたいのかをはっきり書く必要があります。当たり前だろ！と思うかもしれないですが、自分自身まだまだできてない部分が多く、相手に負荷をかけて意図を汲み取っていただいている現状です。みんな忙しいので、なるべくコンパクトにヘルシーに伺うスキルが求められます。こちらのnoteを参考に質問するようにしています。


https://kensuu.com/n/na4c0872fe664

https://qiita.com/KNR109/items/550b52ff980c0c32bf2a


## まとめるとー！
いろいろ書いてみましたけど、エンジニアはゲームのプレイヤーっぽいなあという印象で、エンジニアになってみて、良いなあって思う部分と、大変だなあと感じる部分の両方を味わっています。結論としては、経験としてエンジニアになってみてよかったと思っています。スキル上げしたり、強敵を倒したりする感じはさながらゲームのようなもので、自分のレベルアップを日々積み重ねている気がします。

また、エンジニアはコミュニティが充実しています。自分が所属している「ねこプロ」もそうですし、他にも様々なコミュニティがあるはずです。コミュニティ内で質問してみたり、会話したりするのも楽しいので、エンジニアになってよかったと思っています。


エンジニアは文系でもなれる（ただし最初は大変）ということが実地としてわかりました。文系には無理だ、と最初から可能性を狭める必要はないよと当時の自分に言いたいです。また、自分で作ってみたい、欲しいと思うようなサイトやアプリのイメージがあるとさらに進んで楽しめると思います。


よきエンジニアライフを送れるよう、楽しんでいきましょう！では！
都道府県のジオメトリをPostgreSQLで管理する

2年以上前のことですが、同僚のバックエンドエンジニアでめちゃくちゃ頼りになる [@arkirchner](https://github.com/arkirchner) san が

国土交通省が提供しているデータを PostgreSQL に登録する検証をしていたのを思い出したので自分もやってみました。

# テーブル構成

現実的には以下のような2つのテーブル（prefectures と prefecture_shapes）で構成されると想定し、この記事やソースコードでは prefecture_shapes テーブルだけを作成します。

国土交通省のジオメトリデータは非常にサイズが大きいので prefectures のカラムとして作成しない方がよいでしょう。

```mermaid
classDiagram
  prefectures "1" -- "1" prefecture_shapes
  class prefectures {
    id bigint
    name varchar(255)
    code char(2)
  }
  class prefecture_shapes {
    code char(2)
    geom geometry(MultiPolygon, 4326)
  }
```

# ソースコード

https://github.com/mizoR/japan-prefecture-shapes

## Dockerfile

```dockerfile
FROM postgres:15-alpine

ENV POSTGRES_DB db

ENV POSTGRES_USER app

ENV POSTGRES_PASSWORD password

ENV POSTGIS_VERSION 3.3.2

# 主に PostGIS の build に必要なライブラリたちをインストールする
RUN apk --update add wget make unzip binutils gcc cmake g++ perl-data-dump \
      libxml2-dev geos-dev proj-dev protobuf-c-dev gdal-dev clang llvm

RUN wget --no-check-certificate https://download.osgeo.org/postgis/source/postgis-$POSTGIS_VERSION.tar.gz \
      && tar xvzf postgis-$POSTGIS_VERSION.tar.gz

# PostGIS をインストールする
RUN cd postgis-$POSTGIS_VERSION \
      && ./configure \
      && make \
      && make install \
      && cd ../.. \
      && rm -Rf postgis-$PGROUTING_VERSION \
      && rm postgis-$POSTGIS_VERSION.tar.gz

RUN mkdir -p docker-entrypoint-initdb.d/

# 都道府県の形状データのインポートはコンテナ起動時に以下でコピーされたスクリプトで行う
COPY docker-entrypoint-initdb.d/init.sh docker-entrypoint-initdb.d/
```

## docker-entrypoint-initdb.d/init.sh

```sh
# postgis エクステンションを作成する
psql -U $POSTGRES_USER -d $POSTGRES_DB -c "CREATE EXTENSION postgis"

# 作業ディレクトリを作成する
mkdir /tmp/work

pushd /tmp/work

# 都道府県の形状データを国土交通省からしゅとくする
wget https://nlftp.mlit.go.jp/ksj/gml/data/N03/N03-2017/N03-170101_GML.zip

unzip N03-170101_GML.zip

# テーブル名を temp_prefectures として 形状データをデータベースにインポートする
shp2pgsql -I -W latin1 -s 4326 *.shp temp_prefectures | psql -U $POSTGRES_USER -d $POSTGRES_DB

psql -U $POSTGRES_USER -d $POSTGRES_DB << EOF
-- prefecture_shapes テーブルを作成する
CREATE TABLE prefecture_shapes (code char(2) NOT NULL, geom geometry(MultiPolygon, 4326) NOT NULL);

-- temp_prefectures を 都道府県コードごとに ST_Union して prefecture_shapes テーブルにインポートするする
INSERT INTO prefecture_shapes (code, geom)
  SELECT code, geom FROM (
    SELECT ST_Multi(ST_Union(geom)) AS geom, LEFT(n03_007, 2) AS code
    FROM temp_prefectures
    WHERE n03_007 IS NOT NULL
    GROUP BY LEFT(n03_007, 2)
  ) prefecture_shapes;

-- temp_prefectures を DROP する
DROP TABLE temp_prefectures;
EOF

popd

# 作業ディレクトリを削除する
rm -rf /tmp/work
```

# クエリしてみる

```sql
SELECT code, geom FROM prefecture_shapes code = '13' # 東京
```

ちゃんと矩形が登録されていることがわかります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6774/7eecfc48-14e4-6083-1097-3a9841466b94.png)
GASでジオコーディングをやってみた

## はじめに
地名や住所から、それらが指す地点の地理座標を算出することを、ジオコーディングと言います。こちらを可能にするGeocoding APIというものがあります。

https://developers.google.com/maps/documentation/geocoding?hl=ja

こちらのAPIを使うと、地名や住所からそれらが指す地点の地理座標を算出するだけではなく、逆に地理座標から住所を算出することも可能です。普通にこのAPIを使おうとすると、Google Cloudのプロジェクトを用意したりなど、少し面倒な部分があります。Google Apps Script（以後、GAS）を使うと、その面倒なことをせずにジオコーディングを行うことができます。今回は、GASでジオコーディングをやる紹介したいと思います。

## GASでジオコーディングをやってみた
### 地名や住所から緯度経度を取得する
まずは、地名から緯度経度を取得してみたいと思います。`Maps.newGeocoder().geocode('地名もしくは住所')`で、地名の指す地点の情報を取得できます。今回は、`Maps.newGeocoder().setLanguage('ja').geocode('地名もしくは住所')`というふうにすることで、取得する情報の言語を指定しています。

名古屋城を例にして、実際にジオコーディングをみてみます。

```js
const testGeocoding = () => {
    // 名古屋城という地名から、その地点の情報を取得する
    const res = Maps.newGeocoder().setLanguage('ja').geocode('名古屋城');
    // 緯度経度の情報を取り出す
    const lat = res.results[0].geometry.location.lat;
    const lng = res.results[0].geometry.location.lng;
    console.log('緯度：%s, 経度：%s', lat, lng); // => 緯度：35.1847501, 経度：136.8996883

    // 地名から住所を取り出すことも可能
    const formattedAddress = res.results[0].formatted_address;
    console.log(address); // => 日本、〒460-0031 愛知県名古屋市中区本丸１−１
}
```

### 緯度経度から住所を取得する
先ほどは地名や住所から緯度経度を取得しましたが、その逆で緯度経度から住所を取得することが可能です。やり方は先ほどとほとんど同じで、`Maps.newGeocoder().setLanguage('ja').reverseGeocode(緯度, 経度)`という形で、住所を取得できます。
```js
const testReverseGeocoding = () => {
    // 名古屋城という地名から、その地点の情報を取得する
    const res = Maps.newGeocoder().setLanguage('ja').reverseGeocode(35.1847501, 136.8996883);
    console.log(res.results[0].formatted_address); // => 日本、〒460-0031 愛知県名古屋市中区本丸１−１
}
```

## さいごに
今回は、GASでジオコーディングを行なってみました。この記事ではジオコーディングのやり方の説明のため、簡単な例のみの紹介になりましたが、ジオコーディング単体ではあまり意味を持たないと思っています。今後、ジオコーディングを使った何かしらの事例を紹介できればと思います。
ProgateでSassを勉強してみた（無料版のみ）

皆さんこんにちは！この記事ではProgateでSassの学習レッスンを受けてみた感想とSassについて私が調べた限りのことを書いていきます。拙い文章ですが最後まで読んでいただけると幸いです！:boy_tone1::pray_tone1:
# Sassとは？
Sassとは「Syntactically Awesome StyleSheets」の略称で、CSSを簡略化して記述することができる拡張言語です。日本語では「サス」や「サース」と読まれています。

- Syntactically＝構文的に
- Awesome＝凄い・素晴らしい
- StyleSheets＝スタイルシート

Sassには「SASS記法」「SCSS記法」という2種類の書き方があります。![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/95cab972-1e01-a495-ab98-ddb252dbb72a.png)

ProgateではSCSS記法のほうを学習しました！
Sassを使用するメリットとして以下のことがあります。
- CSSより記述量を減らせる
- コードを再利用できる


Progateの無料版では入れ子構造・＆記号についてのレッスンを受けました！

# 入れ子構造

入れ子構造を使うと同じセレクタ(下の場合.main)を何度も書かなくていい！
<img width="500" alt="スクリーンショット (18).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/0f2b4e87-5116-e158-fb87-498b9575bb67.png">
<img width="500" alt="スクリーンショット (19).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/47183da9-d9f0-c2ff-0eec-19462a7f1a9a.png">
<img width="400" alt="スクリーンショット (20).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/725f51ec-ad66-a918-f328-93d37f4a9772.png">

# ＆記号

＆を使うとどの要素の中にどんな指定を作っているのかがわかりやすくなる！
<img width="400" alt="スクリーンショット (24).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/7bfa0bdf-3389-012f-a9ce-9823823a67c0.png">
<img width="400" alt="スクリーンショット (26).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/971eee84-f1a0-fe7f-a81a-aff289ff671c.png">
<img width="400" alt="スクリーンショット (26).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982409/81d81ce9-84ff-3696-1b4c-cfe2f4fa9a8a.png">

# 最後に・・・
自分はプログラミングがあまり得意ではないですが、Progateで実際にコードを書きながら学習できて身に付きやすかったです！Progateではいろんな言語を勉強できるので皆さんも時間があったら是非やってみてください！:muscle_tone1:
【SwiftUI】Listに配置したButtonのタップ領域がセル全体になってしまう場合の対処法

## 結論
Listのセル内にButtonを配置したところ、Buttonのタップ領域がセル全体になり困っていましたが
`.buttonStyle(.plain)`
を追加することで、正常に動作するようになりました。

## 環境
Xcode 14.1

## 内容
#### 直したかったこと
ListにButtonを配置すると、セルのどこをタップしてもButtonのActionが実行されてしまい、ボタンとして機能しませんでした。

<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/33393d9c-f596-b047-23a6-444356d351e9.png"><img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/fbb70af4-e673-bf6a-d0c8-596bfcc1fb81.png">

```swift
    var body: some View {
        List {
            HStack {
                Text("アイテム")
                Spacer()
                Button {
                    // タップ時の処理
                } label: {
                    Label("追加", systemImage: "plus")
                }
                .padding(10)
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(Color.blue, lineWidth: 1)
                )
            }
        }
        .listStyle(.plain)
        .padding(.vertical, 30.0)
        .scrollContentBackground(.hidden)
        .background(Color.gray)
    }
```

#### 対応方法

`.buttonStyle(.plain)`を追加することで、セルの中でボタンとして動くようになりました。

```diff_swift
    var body: some View {
        List {
            HStack {
                Text("アイテム")
                Spacer()
                Button {
                    print("タップ")
                } label: {
                    Label("追加", systemImage: "plus")
                }
                .padding(10)
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(Color.blue, lineWidth: 1)
                )
+               .buttonStyle(.plain)
            }
        }
        .listStyle(.plain)
        .padding(.vertical, 30.0)
        .scrollContentBackground(.hidden)
        .background(Color.gray)
    }
```

# おわりに
とても簡単なことでしたが、同じように困っている方がいたらと思い記事にしました。
【CommonLisp】クオート付きリストを戻り値にしてはいけない

## 理由

呼び出し元で破壊的操作をされた場合、意図しない結果になりうるため

```common-lisp
(defun hoge ()
  '(1 2 3))

(defun main ()
  (nsubstitute 5 1 (hoge))
  (print (hoge)) ; -> (5 2 3)
  )
```

list関数を使えば戻り値が壊れずに済む

```common-lisp
(defun hoge ()
  (list 1 2 3))

(defun main ()
  (nsubstitute 5 1 (hoge))
  (print (hoge)) ; -> (1 2 3)
  )
```