OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】initializeメソッドとは

# initializeメソッドとは
`initialize`メソッドは、Active Recordモデルなどのクラス定義内で使用される特殊なメソッドです。このメソッドは、新しいオブジェクトが作成されたときに自動的に呼び出されます。通常、`initialize`メソッドは、クラス内でインスタンス変数の初期化や設定を行うために使用されます。

例えば、以下はActive Recordモデル内でのinitializeメソッドの使用例です。
```ruby
class User < ApplicationRecord
  attr_accessor :name, :email

  def initialize(attributes = {})
    @name = attributes[:name]
    @email = attributes[:email]
  end
end
```
この例では、`User`モデルの`initialize`メソッドが定義されています。このメソッドは、ユーザーが新規作成されたときに呼び出され、`name`と`email`のインスタンス変数を設定します。
`attributes`パラメータは、ユーザーが新規作成される際に渡される属性のハッシュです。この`initialize`メソッドを使用することで、新しいユーザーオブジェクトが作成されたときに、自動的に`name`と`email`の値が設定されます。

一般的に、RailsのActive Recordモデルでは、データベースのレコードを表すクラスを定義します。このため、`initialize`メソッドは通常、インスタンス変数を初期化するために使用されることが多いですが、必ずしも必要ではありません。データベースのレコードとの対応付けは、Active Recordの仕組みによって自動的に行われます。
【C#の細かな知識】TryParseから得た教訓

最近、コンソールアプリケーションのデモを作成している際、面白い検証問題に遭遇しましたので、ここで共有したいと思います。

具体的には、コンソールでエンティティの各属性を変更する際、入力の検証が必要になります。何も入力せずにエンターキーを押すと、古いデータに戻る必要があります。ここで問題が生じます。というのも、Console.ReadLine()から読み込まれるすべてのデータが文字列型であるため、bool、DateTime、数値型に変換する必要が生じます。しかし、入力された文字列が対応する型に変換できない場合、エラーが発生します。そのため、入力後に入力値を検証する必要があります。また、何度入力しても無効な場合は、操作を終了する必要があります。

検証については、最初に考えたのは正規表現で、その検証能力は絶大です。しかし、ここで使用するには過剰であり、さらに、簡単な型が多数あり、異なる型ごとに正規表現が必要になるため、あまり適していません。

本質的には、簡単な型の文字列が正常かどうかを判断する必要があります。例えば、bool型の文字列がtrueまたはfalseかどうかです。このような場合、基本型のTryParseメソッドを使用すれば解決できますが、同じ問題が生じます。すべての基本型を一つずつ調べて、その文字列値を対応する型に変換できるかどうかを確認することはできません。そこで、いくつかの基本型のソースコードを調べると、IParsable<T>インターフェースを継承していることがわかります。このインターフェースを利用して、統一された変換検証メソッドを作成することができます。具体的な実装は以下のコードのReInput<T>()メソッドをご覧ください。

```

DateTime? dt = DateTime.Now;

dt = ReInput(dt, 3);

Console.WriteLine(dt);



decimal? d = 1.1m;

d = ReInput(d, 3);

Console.WriteLine(d);



T? ReInput<T>(T? oldValue, int times) where T : struct, IParsable<T>

{

    for (int i = 1; i <= times; i++)

    {

        var input = Console.ReadLine();

        if (input =="")

        {

            return oldValue;

        }

        if (T.TryParse(input, new TestFormat(), out T newValue))

        {

            return newValue;

        }

        else

        {

            Console.WriteLine($"第{i}次输入错误,{(times == i ? "退出" : "重新输入")}");

        }

    }

    return oldValue;

}



public class TestFormat : IFormatProvider

{

    public object GetFormat(Type formatType)

    {

        Console.WriteLine(formatType.FullName);

        return null;

    }

}

```

ケース自体は複雑ではありませんが、得た教訓は共通事項を抽象化し、抽象化後には単一責任の原則を遵守し、インターフェース分離の原則を守ることです。これらの基準を達成すると、後続のユーザーに多くの拡張方法と想像の余地を残すことができます。



(Translated by GPT)
【Rails】ヘルパーメソッドとは

# ヘルパーメソッドとは
ヘルパーメソッド（Helper Method）は、プログラミングにおいて、特定のタスクや処理を行うための便利な関数やメソッドのことを指します。これらのメソッドは、コードの再利用性を高め、可読性を向上させるために使用されます。

主にウェブ開発のコンテキストで使われることが多く、特にフレームワークやライブラリにおいては、ビューやテンプレート内でのコードを簡潔にするためによく利用されます。

具体的な例としては、以下のようなものがあります
1\. **HTML出力の生成** : HTMLタグやフォーム要素、リンクなどの生成を行うメソッドがあります。これにより、ビュー内でHTMLコードを簡潔に記述できます。

2\. **日付や時間のフォーマット** : 日付や時間のフォーマットを行うメソッドがあります。これにより、日付や時間を特定の形式で表示することができます。

3\. **文字列操作** : 文字列の操作や処理を行うメソッドがあります。例えば、文字列の長さを取得したり、一部の文字列を置換したりすることができます。

4\. **データの整形** : データの整形や加工を行うメソッドがあります。例えば、数値のフォーマットやデータの並び替えなどを行うことができます。

これらのヘルパーメソッドは、開発者が独自に作成することもありますし、フレームワークやライブラリが提供することもあります。そのため、プロジェクトや開発環境に応じて適切なヘルパーメソッドを選択して利用することが重要です。
# 使用方法
ヘルパーメソッドを実際に使用する例をいくつか示します。
1\. **HTML出力の生成**
```ruby
# HTMLのリンクを生成するヘルパーメソッド
def link_to(text, url)
  "<a href='#{url}'>#{text}</a>"
end

# ビューでの利用例
link_to("Click here", "/about")
```
2\. **日付や時間のフォーマット**
```ruby
# 日付を指定したフォーマットで表示するヘルパーメソッド
def format_date(date)
  date.strftime("%Y年%m月%d日")
end

# ビューでの利用例
format_date(Time.now)
```
3\. **文字列操作**
```ruby
# 文字列の長さを取得するヘルパーメソッド
def string_length(string)
  string.length
end

# ビューでの利用例
string_length("Hello, world!")
```
4\. **データの整形**
```ruby
# 数値を通貨形式にフォーマットするヘルパーメソッド
def format_currency(amount)
  "$#{'%.2f' % amount}"
end

# ビューでの利用例
format_currency(1000)
```
これらのヘルパーメソッドは、Railsのアプリケーションでは主に`app/helpers`ディレクトリ内に格納されます。これにより、ビューでこれらのメソッドにアクセスしやすくなります。また、フレームワークやライブラリが提供するヘルパーメソッドも同様に使用できますが、その場合は通常、特定の方法でインクルードや設定が必要です。
reCAPTCHAを使用しようとしたらCSP設定で引っかかった

# 背景
- firebaseのnew RecaptchaVerifierを使ってreCAPTCHのインスタンスと生成
- render()でトークンを更新 ←エラーが出た
```
Refused to load the script '<https://www.google.com/recaptcha/api.js...>' because it violates the following Content Security Policy directive: xxx. Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
```

# エラーの理由
コンテンツセキュリティポリシー(CSP)に従わないscriptを読み込もうとしているため、'https://www.google.com/recaptcha/api.js...'
は読み込めない

# 解決策
headerの'Content-Security-Policy'に以下を追加する
```
"script-src 'self' www.google.com/recaptcha/api.js www.gstatic.com "
```

# 終わりに
reCAPTCHAが使えなくてあっせった。。
https://nextjs.org/docs/pages/building-your-application/configuring/content-security-policy
【Vue.js】v-ifとv-showの違い

# 初めに
Vue.jsには条件付きレンダリングとして**v-if**と**v-show**が存在する。どちらも条件によって要素をレンダリングするが，処理内容に違いがある。

:::note info
**レンダリング**
あるデータを処理または演算することで画像や映像を表示させること
:::

# v-ifとは
ブロックを条件に応じてレンダリングしたい場合に使用し，ディレクティブの式が真を返す場合のみレンダリングされる。他にv-elseやv-else-ifも使用することで，より詳細な条件で要素を出し分けすることができる。

```ruby:HTML
      <section id="app">
        <p v-if="goals">goals</p>
        <p v-else>No goals</p>
      </section>
```

```ruby:Javascript
Vue.createApp({
    data() {
        return {
         goals:''
        }
      },  
}).mount('#app')        
```

Javascriptではgoalsに''(ブランク)を指定しているため，v-else要素が画面に表示される。
この時，v-if要素は検証ツールに表示されていないことが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/94470ba2-6fe8-cde2-93c4-0562b6e50d44.png)

# v-show
使用方法はv-ifと同様。条件に該当すれば要素を画面に表示する。
ただ，v-else-ifやv-elseに相当するものはないので，複数の条件文を作りたい場合はv-showを複数使用する必要がある。

```ruby:HTML
      <section id="app">
        <p v-show="goals">goals</p>
        <p v-show="!goals">No goals</p>
      </section>
```
```ruby:Javascript
Vue.createApp({
    data() {
        return {
         goals:''
        }
      },  
}).mount('#app')        
```

Javascriptではgoalsに''(ブランク)を指定しているため，2つ目のv-show要素が画面に表示される。
この時，1つ目のv-show要素は検証ツールにてdispaly:none;となっていることが分かる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/5baf08b9-ae2a-9623-1ff7-591a18114b08.png)

# v-ifとv-showの使い分け
v-ifの方が切り替えコストが高いため，頻繁に切り替える場合はv-showを選ぶと良い。
逆に条件が変わることがほどんど無い場合はv-ifを選ぶと良い。

# 参考
https://www.adobe.com/jp/creativecloud/video/discover/what-is-rendering.html
https://ja.vuejs.org/guide/essentials/conditional
【JavaScript】エクスポート(export)とインポート(import)とは

# エクスポート(export)とインポート(import)とは
JavaScriptのexportとimportは、モジュールのエクスポートとインポートを行うための構文です。これらを使用することで、JavaScriptのファイルをモジュールとして定義し、他のファイルから再利用することができます。
# export
exportキーワードは、モジュールから特定の要素（変数、関数、クラスなど）を渡すために使用されます。モジュールの中でexportキーワードを使用してエクスポートされた要素は、他のファイルからインポートすることができます。
```js
// モジュールから変数をエクスポートする例
export const myVariable = 'Hello';

// モジュールから関数をエクスポートする例
export function myFunction() {
    console.log('Hello, world!');
}

// モジュールからクラスをエクスポートする例
export class MyClass {
    constructor() {
        console.log('MyClass instantiated');
    }
}
```

# import
`import`キーワードは、他のモジュールからエクスポートされた要素を取り込むために使用されます。インポートされた要素は、インポートしたファイル内で使用することができます。
```js
// 外部のモジュールから変数をインポートする例
import { myVariable } from './myModule';

// 外部のモジュールから関数をインポートする例
import { myFunction } from './myModule';

// 外部のモジュールからクラスをインポートする例
import { MyClass } from './myModule';
```
# まとめ
JavaScriptの`export`と`import`を使用することで、ファイルやコードの構造を整理し、再利用性を高めることができます。これらの構文は、ES6（ECMAScript 2015）以降で導入され、モダンなJavaScriptアプリケーションの開発において広く使用されています。
sudoのパスワード入力タイムアウトを延長、ただしsudoers.dで。

# sudoのパスワード入力が煩雑

sudoのパスワード再入力は、sudoの起動毎にデフォルトでは5分繰り延べとなる。操作者がコンソールを5分以上root権限を以って操作しないのは無人状態かもしれないので、安全のため最大でもそのへんが大抵の場合の限度、ということだろう。ただこれ、私の場合はrootになってるコンソールとは別ttyや手元のブラウザなんぞであれこれ参照しつつ考えてる時間があったり、sudoでエディタを起動し設定ファイルを悩みながら書き換えてる時間があったりで、簡単に5分経ってしまい、すぐに再入力を要求される。5分では短い。煩雑に感じる。ここはバランスが安全側に倒してあるのだ。

## ただしウチの場合

基本自分しか家に居ない＋某社社員時代につけた習慣で、家から出るときや、家以外でノートPCなどで端末から離れる際、スクリーンロックしている。なので端末単位で相応の安全は確保されているので、パスワード再入力のタイムアウトは5分より長くて構わないだろう、と判断する。なお、某社時代はうっかりデスクから離れたり、ひとに話し掛けられてそのままコンソール放置になった場合に備えて、端末自体が無操作5分でスクリーンロック(パスワード付きスクリーンセーバ起動)するようにしていた。現在でもMacBook系でバッテリ動作時は数分でスクリーンロックするようにしてある。まあここ数年外にノート持って行くことは激減したけれども。

具体的にはパスワード再入力タイムアウトを5分から60分(1時間)に変更する。


# 変更方法

昔はsudo.confに直接書いて居たような気がするが、現在は `visudo` を使って `sudoers` に書け、ということになっている。また、 `sudoers` の最後にディレクトリ `sudoers.d` 内の各ファイルを読み込むようになっており、機能やユーザで分けて整理した状態でここに置いておくことができる(FreeBSDのportsおよびmacOS付属で確認)。

```sudoers.dの場所 (FreeBSD ports)
/usr/local/etc/sudoers.d
```

```sudoers.dの場所 (macOS)
/etc/sudoers.d
```

Linuxは……みてないけどmacOSと同じでしょうか。

結論として、ウチのFreeBSDの一つではこういう構成になっている。

```sudoers.d (FreeBSD ports)
% ls -l /usr/local/etc/sudoers.d
total 16
-r--r-----  1 root  wheel  244  2月 10 09:01 01_wheel
-r--r-----  1 root  wheel   89  2月 10 09:45 02_dump
-r--r-----  1 root  wheel  270  2月 10 09:05 99_timeout
```

タイムアウトのデフォルト値の具体的な変更は下記の最後の行、 `timestamp_timeout` に分単位で指定。私有端末からしかアクセスしないのでついでに `timestamp_type` は気持ちゆるめ。

```/usr/local/etc/sudoers.d/99_timeout
## must edit with "visudo -f" and check with "visudo -c"
## login as root user or "su -" to change timeout-period
## set this file's mode to 0440 (-r--r-----)
 
## extend timeout-period of asking paswword again
Defaults timestamp_type=ppid
Defaults timestamp_timeout=60
```

例えば、上記 `99_timeout` 作成・編集には `-f` または `--file` オプションで指定すればよい。

```visudo起動
% sudo visudo --file=/usr/local/etc/sudoers.d/99_timeout
```

## ファイル権限に注意

上記 `99_timeout` にも一部コメントとして残してあるが、 `sudoers` 関連ファイルはオーナー:グループが `root:wheel` (Linuxならroot:adminとかかな)で、パーミッションが `0440` (読み込みのみかつ他人はアクセス不可)でないといかんらしい。この辺は編集後に `visudo -c` でチェックして指摘してくれる。

## Defaults timestamp_timeout が効かん！ なんでや！

最初わからずに1週間ほどあきらめてフテ寝してたけど、 `Defaults` は最後に読み込まれたものが全体に適用される模様。ウチではwheelのタイムアウトは60分、dumpは5分にしたくて99_timeoutは当初作らず、01_wheelに `Defaults timestamp_timeout=60` と、02_dumpに `Defaults timestamp_timeout=5` と書いていて、全部が5分タイムアウトになっていた。

全体に効いてしまうものは最後に読み込まれるファイルに書くのがよろしかろう、ということでファイル名の辞書順で読み込まれるっぽいので、各ファイル名の先頭に2桁の数字を振って順序を確定させつつ99_timeoutに `Defaults` をまとめたのであった。めでたしめでたし。

## visudo使わずに編集失敗してsudoでけんくなった！

`sudo vi sudoers` とかしててできたファイルが正しくなかった場合。これも最初やりました。FreeBSDであれば `su -` でrootパスワード入力してsudoersを戻せばよし。macOSの場合はrootアカウントが無効化されているのでこの手はそのままでは通らないはず。最近のMacは簡単にroot取れないようにアレコレ仕組んであるのでそこは面倒ですが、やりようはあったはず(調べてない)。
デブサミ2023夏①

# ソフトウェアアーキテクチャとは
アーキテクチャに影響を与えるものは、以下の項目。
・トレンド技術
・アーキテクトの能力、スキル
・チームの能力、スキル
・ビジネスの目標
・政治や法的な制約
・品質特性
・影響力のある機能要求
・チーム組織
<img width="430.5" alt="スクリーンショット (182).png (101.0 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/01/135213/5dcad15f-a4be-4a20-b4d6-2a927ac92064.png">

まず品質は文献によって以下のように用語が揃っていない。
・アーキテクチャ特性
・品質特性
・イリティーズ
・非機能要求(nonfunctional requirements)
これらは大体同じものを指している。

アーキテクチャは、品質要求を満たすべきものであるが、
https://www.ipa.go.jp/publish/qv6pgp0000000wkj-att/000055008.pdf

アーキテクチャには、システムがどのようにコンポーネントに分割されるのか？
コンポーネント同士がインターフェイスを介してどのように対話し合うかも含まれている。
コンポーネントとは、意味のある単位でモジュール化された構成要素である。
この意味のある単位というのは、変更が入りやすい運用開始時なのか、
それとも安定してきて変更が入りにくくなってきた時期なのかで変わってくる。
運用開始時は、変更のしやすさを優先するために全閉鎖共通原則に振り切った設計を。
安定期では、全再利用やリリース等価原則を意識した設計を求められる。

## 複数の視点を横断して整合性の保証をする
<img width="500" alt="スクリーンショット (183).png (585.2 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/01/135213/62cc8e45-7b9d-466a-bf2f-12b89fa7cadf.png">

マイクロサービスアーキテクチャとか、クリーンアーキテクチャは
このどこかのビューで見ている一面に過ぎない。
論理ビューではうまく行っているものでも、違うビューではそうではないとかってことがないように整合性を担保していかなくてはいけない。
整合性をとりながら構造を決定していくことが重要。

## 図の存在意義
図はアーキテクチャを説明するものであって、アーキテクチャそのものではないため、
品質要求が満たせているかという検証はシステムが構築されるまでは評価不能。
システムで検証するから図だけ綺麗に書いて満足っていうのはアンチパターンであるものの、
図において様々なビューで整合性のチェックはしないといけない。

これはおそらくテストアーキテクチャにおいても、同様のことが言えるであろう。
幸いUAFには、論理構造ビューとプロセスビュー、状態ビューがあるため、
可能な限り高確率で整合性を保てるように３つすべてのビューでの考察はしておきたいところである。

# アンチパターン
## 品質の全部盛り込みケース
品質特性の全部入りをしてしまおうとすると、
ただただコストがかかるし、アーキテクチャが複雑化するだけ。
構造をどうするかで品質を作りこむわけだから、
そこにいろんなもの盛り込めば盛り込むほど当然構造は複雑化し、メンテのしようがなくなるほどになってしまう。
品質自体に定性的に優先順位を付けて、優先順位の同列くらい高いもの同士の中で
トレードオフ関係にあるものを考察していくことになる。

## 前提を固定してしまうケース
<img width="400" alt="スクリーンショット (184).png (200.9 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/01/135213/4fbeb99e-f79f-4e5d-aa74-d4f337a3c33a.png">

これは一度定義したアーキテクチャを変えないというアンチパターンである。
アーキテクチャを決める要因である自分たちの内部的要因や、
ステークホルダーから求められる要求や、法律、制約の変化といった外的要因などは
動的に変化していくものである。
これには当然、各ステークホルダーの関心の強さやリスクリターンポイントの高さ、なども含まれている。
したがって「このアーキテクチャは決めたものだから動かせません」というような
状態では結果的に経年劣化した使われないシステムの出来上がりである。
したがって、全体の構造を変更しやすい工夫として
クリーンアーキテクチャなどといった手法がほぼマストになってくるとも言える。
(SoSのアーキテクチャも同様に)

よって、どの程度の前提の変化に対して、いまのアーキテクチャが対応できるのか？
対応できない前提の変化が起き始めてきたら速やかにアーキテクチャの再検討をしなくてはいけない。

# どう向き合っていくのか
## Enough Design Up Front
すべてを最初から設計しようとするのはNGと様々なウォーターフォールで言われてる。
一方でアジャイル黎明期で言われていたように事前に何も設計しないで実装していくっていうのは、
それはそれで非常にリスクが高い。(平鍋さんがDesign itで訳されてる)
よって、リスクが高いと思われる部分、
対策しないと多大な損失を生むようなリスクに対して必要十分なものを考える。
低リスクなものは対策するだけ、費用対効果悪いしアーキテクチャが複雑化するため、あえて許容する。

## 最小限の実行可能アーキテクチャ
MVP、必要最小の製品のアーキテクチャ版。
必要最小限の品質特性だけ考えて作りこんでいくって考え方。

## 継続的に改善していく
時間と共にアーキテクチャの決定要因が変化していくから、それに合わせてアーキテクチャも進化させていく。
そのためにも事業戦略のレイヤーから品質のWhyになるメトリクスを定義しておく。
そのメトリクスは、
どの程度早く手元にデリバリーが届くか？とか利用者視点の品質メトリクスとなるので、
そことシステム開発者視点の品質メトリクスの何が結びつくのか？
を各機能要素ごとに視える化しておくのが大事。

## 20%は割き続ける
DevOpsハンドブックには、ユーザーからは見えない価値を生み出す作業
負債解消や品質特性見直しとかに20%は最低限当て続けないといつかは爆発するとある。
なので、最初から見積もりだす際には、この分のバッファも含めて見積もりを出すのを常識としたい。

そうでない場合には、自分たちがどの領域に負債を抱えているのか？
を認識した上で機能拡張などをしていくスタンスが求められる。
【Rails】インポートとエクスポート

# エクスポート（Export）
データのエクスポートは、データベース内の情報を外部ファイルに出力するプロセスです。これにより、データをバックアップしたり、別のシステムに移行したりする際に便利です。エクスポートされるデータは、CSV（Comma-Separated Values）形式やJSON（JavaScript Object Notation）形式などの一般的な形式で出力されることがあります。
# インポート（Import）
データのインポートは、外部ファイルからデータを取り込んでデータベースに追加するプロセスです。このプロセスは、以前にエクスポートしたデータを元のデータベースに戻したり、別のシステムからのデータを取り込んだりする際に使用されます。インポートされるデータは、エクスポートと同じ形式である必要があります。

Railsにおけるデータのエクスポートとインポートは、Active Recordやデータベースマイグレーションなどのツールを使用して行われることが一般的です。これらのツールを使うことで、データベース間でのデータの移行やバックアップ、リストアなどが容易になります。また、Railsのコントローラーやモデルを使用してデータのエクスポートやインポートを行うカスタムな手法もあります。
AWS認定のログインでAamzonアカウントが使えなくなった話

# はじめに
AWS認定の申し込みをするときに使うログイン方法として、Amazonアカウントがありましたが、2024/1/31でこのログインは使えなくなりました。
以下は2024/1/30にアクセスしたときのスクリーンショットの一部です。現在この画面は表示されません。![スクリーンショット 2024-01-30 221644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/8fbfa740-197a-6b8d-005f-e94b1817ea7e.png)

# 2024年2月以降はどうするか
2月からは**AWS Builder ID** というアカウントを作りログインする必要があります。このアカウントを作るときにAmazonアカウントと同じメールアドレスを設定することで受験記録をAmazonアカウントから引き継ぐことができます。
![スクリーンショット 2024-02-12 082049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/4b6511f4-d115-ba60-0829-5481730f6c36.png)

# 新しいAWS認定の管理画面
新しい画面は以下のようになります。英語ですが日本語にすることもできます。
![スクリーンショット 2024-02-12 082310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/d0396c6a-0139-0d67-b257-2640695136dc.png)

"EXAM REGISTRATION" の "Schedule an exam" から試験を予約できます。ここからピアソンVUEにアクセスします。ここは日本語にした方がよいです。
![スクリーンショット 2024-02-12 082833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/0f1452a4-8d13-4460-a677-2269500a906c.png)

過去の試験記録は「Exam history」で確認できます。
![スクリーンショット 2024-01-30 222848.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/2f7090b2-3f20-61a5-3dd9-010def636920.png)

また、バッジを確認するときは Digital badgesを開くことでCredlyにログインするリンクが表示されるのでこのリンクからアクセスできます。
![スクリーンショット 2024-02-12 082519.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/29dd3882-cea3-4272-ef36-8ae228b95c47.png)

以上、新しいAWS認定のログインと管理画面の紹介でした。

https://aws.amazon.com/jp/certification/
Pruning Libraryまとめ Pytorch編

# 概要
Structured Pruningが出来るPytorchのLibraryをまとめる

注目したい点は以下の通り
- Mask処理(weightをzeroにする) or Filter削除(Networkの形が変化する)
- FilterのImportance(重要度)を測る評価指標は何か
- Grouping手法があるか
  Residualなどの複雑なNetworkのPruningに必要
- 学習時のPruning or 学習後のPruning

## [torch.nn.utils.prune.ln_structured](https://pytorch.org/docs/stable/generated/torch.nn.utils.prune.ln_structured.html)
- Mask処理
- ImportanceはLn(L1,L2,...) Norm

## [NNI](https://github.com/Microsoft/nni)
- Mask処理

## [gate-decorator-pruning](https://github.com/youzhonghui/gate-decorator-pruning)
- 調査中

## [Regularization-Pruning](https://github.com/MingSun-Tse/Regularization-Pruning)
- [Filter削除](https://github.com/MingSun-Tse/Regularization-Pruning/blob/a4044028edaacca4e7a063c602170b2fffad0a84/pruner/meta_pruner.py#L323C26-L323C32)

## [FisherPruning](https://github.com/jshilong/FisherPruning)
- [Filter削除](https://github.com/jshilong/FisherPruning/blob/456106c04eace7f1722577c2fce0d693eaead915/detection/tools/fisher_pruning.py#L728C13-L728C19)
- Groupingをサポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/6b53b0a1-055e-291e-5915-75a012a0d941.png)


## [Torch-Pruning](https://github.com/VainF/Torch-Pruning)
- Filter削除
- Groupingをサポート

## [only_train_once](https://github.com/tianyic/only_train_once)
- [Filter削除](https://github.com/tianyic/only_train_once/blob/35f4082aa6ff1de3f9a5aab6602ecf5ea65f7996/only_train_once/operation/operator.py#L23)
- Groupingをサポート
- [OTOv1](https://papers.nips.cc/paper_files/paper/2021/file/a376033f78e144f494bfc743c0be3330-Paper.pdf)　
- [OTOv2](https://openreview.net/pdf?id=7ynoX1ojPMt)
- [OTOv3](https://arxiv.org/pdf/2312.09411.pdf)
- Pruningは学習後にfine-tuningしながら少しずつモデルサイズを小さくしていくのが一般的だが、OTOは学習前にLayerをGroupingすることで一回の学習でPruning出来る。Finetuningのコストが少なくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c0acaa0b-ac44-b144-7780-418379ecf540.png)


# まとめ
2024年2月現在に高速化する為に使えそうなPruningのLibraryは以下の2つ
- 学習後にPruningをしたい -> [Torch-Pruning](https://github.com/VainF/Torch-Pruning)
- 学習と同時にPruningをしたい -> [only_train_once](https://github.com/tianyic/only_train_once)
GCP App Engineにデプロイされてる古いバージョンを自動的に削除する

以前の記事までで、やりたいことはほぼできた。

https://qiita.com/beltway7/items/1ed9a3839da924b6a692

- mainブランチにプルリクを作成したらプレビュー環境作成
- デプロイが遅かったので、最適化（高速化）

あとは、デプロイする度に、新しいバージョンがApp Engineに作成されるので、古いバージョンを自動的に削除したい。

# 今回やりたいこと

デプロイしたら、自動的に古いバージョンを削除する

# 現状

デプロイする度にバージョンが増えてく。
![Screenshot 2024-02-11 at 16.55.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89497/0f4b036a-a2cc-11cf-f42b-a543c1981ec5.png)

手動(GUI)で削除できるけど、忘れそうなので、自動で削除したい。

# 対応策

デプロイ成功したら、古いバージョンを消す

# cloudbuild.yamlの修正

いつも通りChatGPTに聞きながら対応。

こんな感じ。
![Feb 12 Screenshot from TinyPNG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89497/a1b70275-d168-531d-8cc4-a301536eac26.png)

- gcloudコマンドでバージョンのリストを取得
- バージョンがprodは除外
- 最新5バージョン以外は削除対象
- gcloud deleteで削除

# 実行結果

ログ
![Feb 12 Screenshot from TinyPNG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89497/8a4316aa-5092-d6fc-a7e2-4ce759686bf7.png)

App Engine
![Feb 12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89497/044cc5ec-2fa9-f88d-6d90-1da52fdccc71.png)

小さくて見づらいけど、古いバージョンが削除されてる。

# 最後に

コードはこちら

https://github.com/ksakae1216/angular2022/pull/143/files
「手に職を 足に趣を」エンジニアキャリアを振り返る

本記事は私の音楽趣味ブログ「[大人バイオリンしぬまでにできたい10のこと](http://mylifewithviolin.blog.fc2.com/)」の2020年当時の記事を前半に編集加筆し、後半はQiita用に書き加えたものです。Qiita×Findy記事投稿キャンペーン 「自分のエンジニアとしてのキャリアを振り返ろう！」の選考対象となるかは微妙ですが、内容的にはテーマに沿っていると思われますので、キャンペーンに参加してみます。


# 「専門性のある職」

「専門性のある職」が音楽関係や芸術関係の方はめちゃめちゃ幸せだとわたしは思う。また、それに関わらず「専門性のある職」がある方はけっこう幸せだとわたしは思う。ないより全然まし。このトシでまだくいっぱぐれないのはそのおかげでもあるのだ。

音楽はなかなか素晴らしい芸術だ。ひとを励ましたり、平和にしたりする力もあると思う。絵画や文学にないとはいわないけど、音楽のサウンドストリームのパワーは強烈で強力だ。強制的にひとの耳に入ってきて心を揺さぶるのだ。

わたしは残念ながら音楽関係の仕事に就けなかった。３６歳ころに転機があったが、そのころでも音楽を職業にできるとはまったく思っていなかった。

なので、比較的得意だったソフトウェアの世界を選択した。こちらは芸術ではなく技術の世界だが、趣味としても成立していた。大学の専門とはやや異なるが工学系という点では同じ路線上に位置している。

# わたしの仕事と趣味の関係を振りかえる。
ここでちょっとわたしの仕事と趣味の関係を振りかえってみる。便宜上「世代」で分類している。

## 1G(第１世代）　
ハードウェアエンジニア（会社員）仕事でワークステーションや黎明期のパソコンを使う。プログラムも多少書けた。設計用の数値計算プログラムなどを自分で書いていた。（12年くらい）
趣味はピアノとパソコンプログラミング、YAMAHAのサイレントピアノをMIDI音源とパソコンにつないでいた。このころ、日本語プログラミング言語Mindと出会う。

## 2G(第２世代）　
システムエンジニア（経営者）システムエンジニア職が中心だが、会社役員にすぐなったので経営業務・顧客獲得の提案営業から、開発後の運用までシステム事業を支える業務はなんでもやった。日本を代表する製造業の顧客にもめぐまれた。（23年くらい）
趣味は映画観賞。2Gの末期にバイオリンを趣味としてみる。ピアノは超チープな電子ピアノ購入でレッスン再開。

## 3G(第３世代）　
システムエンジニア（フリーランス）　準委任契約のオンサイトなので設計開発以外の業務はなくなってある意味システムエンジニアの担当者業務に集中できた。
趣味はバイオリン、ピアノ、フルート、音楽基礎としてソルフェージュに取り組む。2G末期にヴォーカルレッスンも受けていたが、フリーランス開業時に資金面の都合でこちらは終了。

## まぼろしとなった4G(第４世代）　
現在は3Gであるが、次の4G(第４世代）の仕事としてアプリケーションエンジニアの仕事を開業（といってもまだリリースしておらず開発中。2020年当時）しようとしていた。

ソフトウェアの仕事に少し音楽的な趣をむりやり添えちゃおうかなということを2020年当時考えていた。
フリーランスは基本自営業なので、屋号と著しく外れる場合は屋号を書き直さなければならないが、仕事（商売）をどういう風にアレンジしようが自分の勝手と考えられるのだ。



# 次の転機は2022年の年末に訪れた。

日本語プログラミング言語Mindユーザー会の会長から忘年会のお誘いをいただいたことだ。わたしはMindはまったく使わなくなっていたが会長とは懇意にしていて、フリーランスになったときもお祝いの品などいただいていた。

忘年会自体は業務多忙のおり出席できなかったのだが、それを機に、日本語プログラミング言語をめぐる現状をネットで調べてみたのだが、結果に愕然とした。

実装現場では使わなかったが、設計現場においてはシステムエンジニアとしてのわたしの職務能力に重大な影響を与えたと考えられる日本語プログラミング言語Mindになんとか恩返しがしたく、Qiitaにアカウント作成して記事投稿活動を開始したのが2023年1月であった。

現時点では音楽的な活動はほぼ終息して、バイオリンのレッスンをかろうじて継続している状態だ。本業以外の時間はなるべく日本語プログラミング言語の情報発信とコンパイラ実装技術の獲得に割いている。


# みなさまにアドバイスできそうなこと
以上の職歴（と趣味歴？）よりみなさまにアドバイスできそうなことをさぐってみます。

システムエンジニアリング業界では、PG→SE→PL→PM→管理職→うまくいけば役員 みたいなキャリアパスが中堅以上の事業体では一般的かと推定されます。純ぜんたる管理職となって現場の実務能力が消失すると、いったんそのポジションをはずれた後どのような実務スキルが残るかは微妙なリスクがあるように思われます。

事業規模がでかくなると現場実務にコミットすること自体パワー的に不可能ということもありますが、実務能力的にこれは保持しているというのを維持しておいた方が、いろいろつぶしが効くような気がします。

わたしの場合、社内外用のITインフラの運用も責任者として対応していたので、部下の方の作業指導もできるよう自身もマイクロソフト基盤のWindowsServerネットワークといくつかのアプリケーションサーバー（ExchagenServer/SharePointServer/ProjectServer/SQLServerのAnalysisなど）の導入運用スキルも持っていましたが、フリーランスになったときに運用系ではなく開発系を選択しましたのでこれらのスキルは現時点でほほぼ消失しています。

残ったのは実装言語の運用能力（開発デバッグスキル）の方ですが、今日の実装言語は百花繚乱なので、細かい言語仕様を脳内に大きくカバー維持しようとするよりは、実装言語の（フレームワークの）基本構造の理解やアルゴリズム発案能力の基礎スキルの維持向上に努めておいた方がよい気がします。実装言語に展開する手前、実装課題の要件の実現アルゴリズムをどのようにするかに能力が問われ、このあたりは契約が継続するかどうかで大きいようです。もちろん設計だけでなく実装にも落としこめるのが前提ではあります。
エンジニアの新卒面接を担当してみて思ったこと

## 努めている企業についてと担当している面接について
私が勤めているのは自社開発をしている企業です。ポジションとしてはAndroidエンジニアをしています。
私の企業は書類選考から3回面接で合格になるプロセスです。
その中の1次面接の担当をしています。

## 採用方針
採用方針としては、志望動機が自社の担当しているサービスに向いていれば少し技術的にも足りなくてもなるべく採用する。それ以外は他の企業と一緒かと思います。

## 新卒面接の難しいところ
1.エンジニアとしても対面の会話力にしても能力がまばらすぎること
2.自分の質問の意図と別の答えが返ってくることが多い
3.ポートフォリオなどが何もない時があること
4.質問の順番が難しい
5.時間が限られている(短いと感じることがある。)

### エンジニアとしても対面の会話力にしても能力がまばらすぎること
大学生ということもあり、境遇もさまざまでインターンで業務経験がある人もいれば授業でしかやったことがない人も面接に来る基本的には、書類選考で技術的な面では切られていることが多いがたまにいる。

#### 肌間のレベル分け上から高い
 1. インターンや業務経験がある
 2. 独学などでリリースまでしたことがあるチーム開発経験がある、研究内容がえぐい人
 3. 独学などでリリースまでしたことがあるチーム開発経験がない
 4. 独学でwebなどを作ったことはあるがリリースなどはない
 5. 大学の授業で経験がある

#### 何をもってしてレベルが高いと思うのか
まず、質問の意図をしっかりと理解をしてくれること以下に具体例
- 私：ユーザー目線の開発ができるとありますがどのようにしてユーザー目線を集めていかしますか？
- 学生：このようにしたらユーザーにとって使いやすいかどうかを考えて作ります

経験がないのでしょうがないとは思いますが、例えばデザインの勉強をして色の使い分けをするようにしたなどが返ってくる人もいたりするのを見てくると、私たちが何を求めているのかを考慮できているとレベルの高さを感じます。ただ質問が悪い時もあるのでこちらの実力不足の場合もあるので悪しからず。

他でいうと自分以外の周りのエンジニアとあってこなかった学生に起こりがちなのが、自分が既に一人前という気持ちで、すぐに即戦力です系は非常に生意気で瞬で落としたくなる時がありますし、周りとの協調性がなさそうなことが多いです。私のような自社サービスのは長い期間チームで連携していくことが多いので1年で200日以上一緒に仕事をやっていくと考えると、採用したくないという気持ちになりますね。

後はあまり経験がないけど自分を大きく見せたい人は、覚えたての言葉をつかってそれっぽいことを話しますが少し突っ込むと基本的に抽象的ななんにでも当てはまることを話すのでそうなると逆に印象はわるくなりますね。同じく抽象的な話しかできないと中身のなさを逆に示しているように感じます。

私は上記をみながらレベル感をはかっています。

#### どのレベル感でも大切だなと思うこと
学ぶ姿勢への誠実さというのは当然なのですが面接をしている人は学生よりも経験も技術も高い人が多い。そこへのリスペクトが感じられることはすごく好印象だし、逆にない人は一緒に働きたくない。私自身まったくもって技術力が高いわけではないし、自分がわからないときに助けてくれるのは一緒に働く周りの人そこへのリスペクトがない人は採用しない方がいいとおもったし、リスペクトできないならその企業に入るべきではないと私は考えます。なので不合格にしていますレベルが高くても。

### 質問の順番が難しい
何回か面接のファシリをやって思うことは質問の順番を間違えると相手が答えた内容につながりを見つけられないことがある。つながりとは具体的には先ほどの「ユーザー目線の開発ができるとありますがどのようにしてユーザー目線を集めていかしますか？」と「なぜユーザー目線を大切だとおもいますか？」という質問をしたいとするときに「ユーザー目線の開発ができるとありますがどのようにしてユーザー目線を集めていかしますか？」を先にしてしまうと自分のユーザー目線の観点の話をされたときに、なんでその観点になったのかを説明されないとなんで？みたいなことになることがあります。時間が限られているのでうまく質問しないと疑問のまま進行
しないといけないこともあるので順番は大切だと感じました。
最近全体の流れとしても志望動機を最初にもってきてから技術面などを聞くようにする流れにしています。採用基準として大切にしているのが志望動機でありますし結構ほかの質問にも絡んでくることが多い印象があります。

#### 特殊例で難しいと思ったケース
17歳の家庭の事情で大学にいけないという高校生が受けてくれたのですが、17歳としては十分すぎる技術と経験をしているのですが技術的にボーダーにたっしていなく、コミュニケーション能力も高校生なのでしょうがないのですが、足りていない学生が来た時に伸びしろという点ではすごくいいと思いましたが現状では採用できないと考えたのですが変なブラック企業に入ってほしくないという気持ちもありすごく複雑な気持ちなりました。

#### もし見ている学生がいたら伝えたいこと
形だけでもいいから誠実であるような態度をとりたまえ。あとエンジニア系に多いのは社会人になってもいるが言葉遣いがおわっているひと、例えば接続でいうと「だから」というひと「でずので」とかに変えるだけで印象が変わるし、言葉遣いがなぜ大切かわかんねー正しいこと言ってっから系に伝えるとまず、周りに気遣いができない自分中心の人間なあなた、社会人になると色々な人と関係を持つことがある昔営業を少しやっていたことがあるがちょっとした言葉遣いでブチギレてくる人も沢山いたし、自分が気を付けているからこそだんだん基準が上がってきている自覚もあるが少し話し方を気を付けるだけでお互いが気持ちい関係になる友達ではないけど敵を作らないが社会人の鉄則だから覚えときな。

### あとがき
ほぼ箇条書きのようになりますが新卒面接をしている人と共有出来たらいいなと思いました。
ksnctf #3 Crawling Chaos

## ksnctf #3 Crawling Chaos
![スクリーンショット 2024-02-11 231302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685661/16c1a35f-9bba-d323-7a70-4613889b448c.png)
問題のurlにアクセスするとこのようなページが表示されます。
取り合えずこのページのソースコードを見てみましょう。するとこのような顔文字が出てきます。
![スクリーンショット 2024-02-11 230324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685661/bf1ecbe6-7d7d-dbb8-dae0-c566dc16b2b2.png)
この顔文字の羅列は< script>というタグに囲まれていることが注目ポイントです。これは、Javascriptです。Chromeのデベロッパーツール（F12key）を使って解読していきましょう。
console.log( 文字列 )と入力すると以下のようになります。
![スクリーンショット 2024-02-12 055631.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685661/540daead-f2ec-33c2-8183-80722a07b38a.png)
![スクリーンショット 2024-02-12 055646.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685661/f7fa1c7a-0b3b-655c-fed9-e32cea7789e2.png)
下部分を整理すると以下のようになります。
これは、jQueryという、JavaScriptのライブラリで、JavaScriptのプログラムを簡単に操作できるよう設計されているものです。
```jQuery:function.jq
$(function(){
    $("form").submit(function(){
        var t=$('input[type="text"]').val();
        var p=Array(70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,1470,832,1785,2196,1520,1480,1449);
        var f=false;
        if(p.length==t.length){
            f=true;
            for(var i=0;i<p.length;i++)
                if(t.charCodeAt(i)*(i+1)!=p[i])f=false;
            if(f)alert("(」・ω・)」うー!(/・ω・)/にゃー!");
        }
        if(!f)alert("No");
        return false;
    });
});
```
このコードは次のことを行っています。
1.$('input[type="text"]').val()でテキスト入力フィールドの値を取得し、変数tに格納します。
2.Array(70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,1470,832,1785,2196,1520,1480,1449)で配列pを作成します。
3.if(p.length==t.length)でテキストの長さと配列の長さが同じかどうかを確認します。
4.テキストの長さと配列の長さが同じ場合、テキストの各文字の文字コードを取得し、その文字の位置（0から始まる）に1を加えた値と配列の対応する要素を比較します。これが一致しない場合、フラグfをfalseに設定します。
5.最終的に、フラグfがtrueであれば、特定のメッセージをアラートとして表示します。そうでなければ、「No」というメッセージを表示します。
これをpythonで解読するプログラムを書きます。
```python:solve.py
array = [70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,
         1470,832,1785,2196,1520,1480,1449]

for i in range(len(array)):
    c = array[i] // (i + 1)
    print(chr(c), end="")

print()  #出力　FLAG_fqpZUCoqPb4izPJE
```
よってFLAGはFLAG_fqpZUCoqPb4izPJEとわかります。

## 参考文献
console.log->https://qiita.com/furiirakun/items/9180d7f4766bf3219f4b
chr()->https://qiita.com/furiirakun/items/d6a10b2a03a43bedab34
chr()とは

## chr()とは
chr()関数は指定したUnicodeの値に対応する文字を返します。この関数は整数を引数として受け取り、その整数のUnicode表現を文字列として返します。

例えば、chr(65)とすると'A'が返されます。これは、Unicodeコード65が大文字の’A’に対応しているためです。
```python:chr(65).py
print(chr(65) #出力　A
```

また、chr(12354)とすると、'あ'が返されます。これは、Unicodeコード12354がひらがなの’あ’に対応しているためです。
```python:chr(12354).py
print(chr(12354) #出力　あ
```
console.log()とは

## console.log()とは
console.log()はJavaScriptの基本的な関数で、ブラウザのコンソールにメッセージを表示するために使用します。以下に基本的な使い方を示します。
文字列を出力
```JavaScript:JavaScript.js
console.log('Hello World');
```
このコードは、コンソールにHello Worldというも文字列を出力します。
【ReactNative】アプリのシステム設定画面に遷移する

起動しているアプリに関わるシステム設定の画面へ遷移する方法を記載していく。

公式ドキュメントを参考にする。

https://reactnative.dev/docs/linking?language=typescript#opensettings

## 内容
`Linking`ライブラリーを用います。
`Linking`はアプリのリンクを操作するためのインターフェイスを提供しています。

### ライブラリーをインポート
```tsx
import { Linking } from 'react-native';
```

### アプリの設定画面に遷移する

```tsx
<Button title="Open app-settings:" onPress={() => Linking.openSettings()} />
```

`Linking.openSettings()`を実装することによって、アプリに対する設定画面を開くことができます。

## Linkingのその他の用い方

### ブラウザへの遷移
```tsx
Linking.openURL(url)
```
指定したURLをブラウザで開く事ができます。



## 動作確認
![Simulator Screen Recording - iPhone 15 Pro - 2024-02-05 at 16.17.27.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/bcf8c855-4e4d-ae0e-1457-9269e624fbcd.gif)


## 最後に
他にも良い方法があれば、コメントいただけると大変うれしいです。
良かったと思ったら、いいねやTwitterのフォローよろしくお願いいたします！

https://sites.google.com/view/muranakar

個人でアプリを作成しているので、良かったら覗いてみてください！
【bat】外部batで全角スペースetcのアレを回避


前回の記事のbatとほぼ同じ

https://qiita.com/noenture/items/9b80492e73883a4a9ff5


全角スペース以外にも、イコール・カンマ・セミコロンでも同じことが起こるようなので対応




# 呼び出し
```bat
@echo off

call %~dp0file_loader.bat %*

for %%i in (%__ARGS%) do echo %%~dpnxtzi

pause
```

```bat

@echo off

call %~dp0file_loader.bat %*
call :READ_ARGS %__ARGS%
goto :END

:READ_ARGS
echo %1
for %%i in (%*) do echo %%~dpnxtzi
exit /b

:END
pause
```

# 外部bat
```bat:file_loader.bat
@echo off
setlocal

for %%i in (%*) do if not exist %%i goto :__ARRANGE_MODE
set __ARGS=%*
goto :__END

:__ARRANGE_MODE
set __PRE=%*
set __PRE=%__PRE:　=:1%
set __PRE=%__PRE:,=:2%
set __PRE=%__PRE:;=:3%

for %%i in (%__PRE%) do call :__MERGE_ALL %%i
set __ARGS=%__ARGS:~1%
set __ARGS=%__ARGS::1=　%
set __ARGS=%__ARGS::2=,%
set __ARGS=%__ARGS::3=;%
set __ARGS="%__ARGS:?=" "%"
goto :__END

:__MERGE_ALL
set __V=%~1
if "%__V::\=%" == "%__V%" (
	set __ARGS=%__ARGS%=%__V%
) else (
	set __ARGS=%__ARGS%?%__V%
)
exit /b

:__END
endlocal & set __ARGS=%__ARGS%
exit /b



```
【WPF】MVVMパターンについて理解する。

## 🐇はじめに
こんにちは！[Rabinosuke](https://qiita.com/Rabinosuke)です！最近の出来事といえば、2月3日は節分でしたね！✨TVerで"池上彰のニュースそうだったのか!!"を見ていたら、節分は各季節の始まりの日（立春・立夏・立秋・立冬）の前日のことらしく、節分 = 「季節を分ける」ということを初めて知りました！漠然と"豆まき！🫘"としか考えてこなかったので、ためになりました！🌱

今回は、開発でMVVMパターンを採用することになったため、学習したことをまとめていきます！間違っていることがあれば、優しく教えていただけると助かります。🙏

## MVVMパターンとは？？
MVVMパターンは、アプリケーションのUI（ユーザーインターフェース）開発に特化したデザインパターンです。データ(ロジック)とUI機能を分離することで開発やデバッグを効率的に行えるようになります。主にModel、View、ViewModelの3つのコンポーネントで構成されています。

#### 構造
![スクリーンショット 2024-02-12 4.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630469/263f8a72-f9fc-3ade-4da9-d1e3fef72016.png)



**View:** ユーザーに表示されるUI部分です。ユーザーのアクションを受け取り、そのアクションに応じてViewModelに通知します。MVVMでは、Viewは可能な限りロジックを持たず、表示に集中します。

**ViewModel:** ViewとModelの間の橋渡しをする役割です。UIに必要なデータをModelから取得し、それをViewが表示できる形に加工します。また、Viewからのアクションに応じてModelを更新します。ViewModelは、Viewに対してデータバインディングを提供し、UIの状態を管理します。

**Model:** データアクセス層とビジネスロジックを担当します。アプリケーションのデータ構造やデータ操作のロジックを含む、再利用可能なコンポーネントです。

少しイメージが湧きにくいと思うので、レストランを例にMVVMパターンを簡単に説明します！

**View: ダイニングエリア**
これはお客様が食事をする場所で、レストランの「顔」です。お客様の注文は、この部分が受け取り、キッチン（Model）へ伝えます。主な目的は、お客様に快適な食事体験を提供することです。

**ViewModel: ウェイター**
ウェイターはお客様とキッチンの間を取り持ち、注文を伝え、完成した料理を提供します。この役割は、お客様のニーズを満たし、サービスの質を保つことです。

**Model: キッチン**
キッチンは、料理を作り、お客様の注文に応じてメニューを更新します。食材の管理から料理の準備まで、レストランの核となる部分です。主な目的は、要求された品質で料理を効率的に提供することです。

まとめるとダイニングエリア（View）はお客様に対するインターフェース、ウェイター（ViewModel）は情報の中継者、キッチン（Model）はデータと処理の中心です。

## メリット

**保守性の向上:**　MVVMパターンを採用することで、UIコードとビジネスロジックが分離されます。これにより、コードの見通しが良くなり、修正や機能追加が容易になります。

**テスタビリティの向上:** ビジネスロジックがViewModelに集約されるため、UIに依存しない単体テストが可能になります。これにより、より安定したアプリケーション開発が可能になります。

**再利用性の向上:** ModelやViewModelを別のViewで再利用することが可能になります。これにより、開発時間の短縮と効率化が図れます。

**データバインディング:** WPFの強力なデータバインディング機能を活用することで、コードビハインドを最小限に抑え、宣言的なUI記述が可能になります。これにより、UIとロジックの分離がさらに進みます。

## デメリット
**学習曲線:** データバインディングやViewModelの概念は初学者には難解であり、理解と実装に時間がかかる場合があります。

**実装の複雑さ:** 大規模なプロジェクトでは、ViewModelが肥大化しやすく、管理が難しくなることがあります。

**パフォーマンスの問題:** データバインディングの不適切な使用は、特に大量のデータ更新が発生するアプリケーションでパフォーマンスの低下を引き起こす可能性があります。

## MVVMとMVCの違い
**MVC (Model-View-Controller):**

Model: データとビジネスロジックを保持します。
View: ユーザーインターフェースを担当します。
Controller: モデルとビューの間の仲介役で、ユーザーからの入力に基づいてモデルを更新し、その変更をビューに反映させます。

**MVVM (Model-View-ViewModel):**

Model: データとビジネスロジックを保持します。
View: ユーザーインターフェースを担当します。
ViewModel: ビューとモデルの間の仲介役で、データバインディングを通じてビューの状態とデータの同期を自動化します。


**主な違い**は、**MVCではControllerがアクティブにモデルとビューの間の通信を管理する**のに対し、**MVVMではViewModelがデータバインディングによりビューとモデルの同期をより宣言的に行う点**です。これにより、MVVMはUIのテストや分離が容易になりますが、データバインディングによる複雑性が増す可能性があります。


## MVVMが向いているプロジェクト
**リッチクライアントアプリケーション:** WPFやXamarin.Formsなど、リッチなUIと複雑なユーザーインタラクションが必要なクライアントアプリケーションに適しています。

**テスト容易性を重視するプロジェクト:** UIとビジネスロジックの分離が容易であるため、単体テストを重視する開発に向いています。

## 不向きなプロジェクト

**シンプルなUIが必要なプロジェクト:** UIがシンプルで、ビューとモデルの間のインタラクションが限られている場合、MVVMの導入は過剰な対応になる可能性があります。

**学習時間や開発期間が限られているプロジェクト:** MVVMの学習と適切な実装には時間がかかるため、短期間で開発を進める必要があるプロジェクトには不向きかもしれません。


## 最後に
MVVMについて学習したことをまとめてみました！
Viewがユーザーインターフェース、ViewModelがデータとビューの橋渡し、Modelがデータの保持とビジネスロジックを担うという役割分担は、開発プロセスをより整理し、より効率的にするのに役立つことがわかりました。しかし、MVVMパターンを採用する際には、学習曲線や実装の複雑さ、そして適切なプロジェクトの選択に留意する必要があると感じました。
2024/2/12主にITとかセキュリティの記事

2023年に揺れたサイバーセキュリティの現場～ランサムウェア、サプライチェーン攻撃、クラウドの脅威を振り返る(2/10)
https://dev.classmethod.jp/articles/2023%E5%B9%B4%E3%81%AB%E6%8F%BA%E3%82%8C%E3%81%9F%E3%82%B5%E3%82%A4%E3%83%90%E3%83%BC%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E7%8F%BE%E5%A0%B4%EF%BD%9E%E3%83%A9%E3%83%B3/

脆弱性競技会、EVのテスラを含むIoT機器から数十の脆弱性を発見(2/10)
https://news.mynavi.jp/techplus/article/20240210-2878640/

シタデルのグリフィン氏、ＳＥＣの「ビッグブラザー」監視体制を批判(2/10)
https://www.bloomberg.co.jp/news/articles/2024-02-09/S8LNODDWX2PS00?srnd=cojp-v2

戦争に関連するサイバー攻撃　保険は下りるのか(2/9)
https://kn.itmedia.co.jp/kn/articles/2402/09/news092.html

不正アクセスで入手した名刺情報を投資勧誘に悪用していた事案についてまとめてみた(2/10)
https://piyolog.hatenadiary.jp/entry/2024/02/10/003029

生成AIが危険なコードや回答を生成するリスク、メタのPurple Llamaが示すAIの危険度(2/10)
https://news.yahoo.co.jp/articles/721394b715293d96e0a0858d2cfa031ab6073409?source=rss

業務でAWSを利用する時に知っておくべきポイント10選(2/10)
https://qiita.com/mczki/items/4a423c7a4fac8bbde554

シカゴ大学が「毒」を開発。AIによる盗用からイラストを守る2つのアプ(2/10)
https://www.lifehacker.jp/article/2402use-glaze-and-nightshade-to-stop-ai-from-stealing-your-art/

ランサムウェア「Kasseika」によるBYOVD攻撃：リモート管理ツール「PsExec」やドライバ「Martini」を不正利用(2/9)
https://www.trendmicro.com/ja_jp/research/24/b/kasseika-ransomware-deploys-byovd-attacks-abuses-psexec-and-expl.html

米財務省、仮想通貨やDeFiのマネロンリスクを再度指摘(2/10)
https://coinpost.jp/?p=510202

トロイの木馬？アプリ未納料金？還付金？　特殊詐欺被害相次ぐ【新潟】(2/9)
https://news.yahoo.co.jp/articles/a93b62a73b5f24ea7d1b74bceb4f77bc91b57f76?source=rss

TikTok親会社を取引制限リストに　米超党派議員がバイデン政権に登録要請(2/10)
https://www.epochtimes.jp/2024/02/204320.html

文科省「教育情報セキュリティポリシーに関するガイドライン」改訂版を公表(2/10)
https://www.kknews.co.jp/news/20240210o03

増加するサイバー犯罪への対応力強化へ！サイバーセキュリティ競技大会が初開催　青森県(2/10)
https://newsdig.tbs.co.jp/articles/-/992632?display=1

古いパソコンはどう処分すればよいですか？ データが消えているか不安です 【専門家が回答】(2/10)
https://news.allabout.co.jp/articles/o/75377/
githubアカウントを複数持っている人がアカウントの切り替えをいい感じに実施する方法

# はじめに
現在個人用、会社用、顧客用で3つのgithubアカウントを行ったり来たりしてます
うっかり別アカウントの名前でCommitしちゃたりしていたりするのでどうにかしたかった

## やりたいこと
1. ディレクトリ毎にgit clone、git pull、git pushする際のユーザを固定したい(使うssh鍵を固定したい)
2. ディレクトリ毎にgit commitする際のユーザを固定したい(git configを固定したい)

# いいやりかたないかなーって調べたらけどこれはマッチしなかった
~/.ssh/configに
```
Host accountA.github.com
  User git
  HostName github.com
  IdentityFile ~/.ssh/accountA_github_rsa
Host accountB.github.com
  User git
  HostName github.com
  IdentityFile ~/.ssh/accountB_github_rsa
```
って書いて、git cloneするときに
`git clone git@accountA.github.com:accountA/repositoryName.git`
って書くやり方はみかけたんだけどcloneするときにHost名書き換えするのめんどっちくない？って思った

## 前提
### 環境
OS:macOS 14.3.1
多分どのOSでもちょびっと変えれば動くと思いますが検証してないんでがんばって
アカウントごとにrepositoryはディレクトリ分けしていることが条件です

### まずはディレクトリ分けしてるよね？って確認
アカウントAのrepositoryをcloneしているディレクトリ
```
~/github/accountA
```
アカウントBのrepositoryをcloneしているディレクトリ
```
~/github/accountB
```
## ディレクトリ毎にgit clone、git pull、git pushする際のユーザを固定したい(使うssh鍵を固定したい)
### ssh configに追記
~/.ssh/config
```
# git
Host github.com
  User git
  HostName github.com

Match Host github.com Exec "pwd | grep accountA"
  IdentityFile ~/.ssh/accountA_github_rsa

Match Host github.com Exec "pwd | grep accountB"
  IdentityFile ~/.ssh/accountB_github_rsa

```

※Match文は次のMatchが来るか、ファイルの末尾がくるまで続くみたいなのでファイルの最終行に書くとよいです
上記の最後にMatch all を書いてもよいらしい。その後にも続きをかけるようになるとのこと。

### これってなにしてるの？
`Match Host github.com Exec "pwd | grep accountA"`
上記は
Hostが `github.com` かつ、 `pwd | grep accountA` を実行した結果戻り値が `真(True)` だったら
`IdentityFile ~/.ssh/accountA_github_rsa` を使うよって書いてあります

`~/github/accountA/` で Repositoryをcloneする場合のコマンドは`git clone git@github.com:accountA/test_repo.git`
って感じになると思いますが、hostは `github.com` だし、実行ディレクトリで `pwd | grep accountA` したら `true` なのでaccontA用の秘密鍵を使用して認証を行う

※accountAの中にaccountBの名前を含むdir名が含まれてたりすると駄目になると思うので、そこは気をつけて
もしそういう自体が想定されるときはgrepの条件を `accountA` ではなく `github/accountA`とかにしてもいいかも。

## ディレクトリ毎にgit commitする際のユーザを固定したい(git configを固定したい)
### config情報を書き換える準備
.gitconfig_dirを作成する
`mkdir ~/.gitconfig_dir`

### アカウント毎にconfigファイルを用意する
gitconfig_accountA
```
[user]
        email = hosoi.toru@accountA.co.jp
        name = hosoi
```
gitconfig_accountB
```
[user]
        email = toru@accountB.com
        name = toru
```

### .gitconfigに追記
~/.gitconfig
```
[credential]
	helper = !aws codecommit credential-helper $@
	UseHttpPath = true
[user]
	email = toru@hosoi.jp
	name = thorhosoi
[includeIF "gitdir:~/github/accountA/"]
	path = ~/.gitconfig_dir/gitconfig_accountA

[includeIF "gitdir:~/github/accountB/"]
    path = ~/.gitconfig_dir/gitconfig_accountB

```


# おしえてください
複数アカウント使っている場合に切り替えってどうしてます？
もっといい切替方法あったら教えてください

# ちなみに
githubでは無料アカウントの複数所持はだめですよって言ってるので、どっちかは有料アカウントですよね？
https://docs.github.com/ja/site-policy/github-terms/github-terms-of-service#b-account-terms
> 1 人の個人または 1 法人が維持できる無料アカウントは 1 つのみです (マシン アカウントを管理することを選択することもできますが、アカウントはマシンを実行するためにのみ使用できます)。
お名前.comでドメインを取得して、さくらのネームサーバーを利用して、さくらVPSにCapistranoでRuby on Railsデプロイの手順

# 概要
こちらの記事はお名前.comでドメインを取得して、さくらのネームサーバーを利用して、さくらVPSにCapistranoでrailsデプロイを考えている方向けに、その手順(突っ込みどころ満載だと思いますが🙇‍♂️)を解説したものです。

## 1.お名前.comの設定
### 1.1 ドメインを取得したらやること
#### 1.1.1 ネームサーバーをさくらのネームサーバーに変更する
さくらのネームサーバーでAレコードを設定していくため、お名前.com上では特にこれ以外設定しなくてOKだと思います！

![スクリーンショット 2024-02-12 3.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1205047/ed0ffd10-c9f7-3372-b578-4f2d0b13e903.png)

## 2.さくらのネームサーバーの設定
### 2.1 Aレコードの設定
#### 2.1.1 お名前.comで取得したドメインの登録
[トップページ](https://secure.sakura.ad.jp/menu/top/)から、契約中のドメイン一覧をクリックして「ドメインコントロールパネル」をクリック。そしてお名前.comで取得したドメインを登録。
![スクリーンショット 2024-02-12 3.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1205047/4ae4d543-4953-a22f-3741-7700ded9a47b.png)

#### 2.1.2 登録したドメインに対してAレコードを設定する
以下のように設定
| エントリ名 | タイプ | データ                                 | TTL  |
|------------|-------|--------------------------------------|------|
| @          | A     | 契約したさくらVPSのIPv4アドレス | 任意 |
| 使用したいサブドメイン        | A     | 契約したさくらVPSのIPv4アドレス | 任意 |

## 3.さくらVPSの設定
### 3.1 パケットフィルターの設定
#### 3.1.1 SSHとWebを解放
![スクリーンショット 2024-02-12 3.51.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1205047/74182d10-0406-59c7-bf5d-d53c08bbd8a2.png)

## 4.CapistranoでRuby on Railsをデプロイ
### 4.1 以下の記事を参考に進める
こちらの記事で大変丁寧に説明されているため、一つ一つ進めていけば大丈夫だと思います！(所要時間2~10h)

https://qiita.com/kinokosan/items/4e4dc0e6cfbfa41b3685

## お疲れ様でした🙌
筆者は初めてRailsをデプロイしたのですが、想像以上に大変でした😭
こちらの記事が少しでも皆様のお役に立てることを祈っております！！
Reactアプリを作るときのgitHubとの連携方法

# Reactアプリの作成
コマンドプロンプトを開いて、`cd`でプロジェクトファイルを作りたいフォルダに移動
`npx create-react-app プロジェクト名`で新しいReactアプリを作成

# 省略するステップ
以下の手順はcreate-react-appが自動で行うため、省略可能
1. Gitリポジトリの初期化
`cd プロジェクト名`で作成したプロジェクトフォルダ内に移動（以降全てのコマンドは、このルートディレクトリで行う）
`git init`を実行
2. ステージング
`git add .`ですべてのファイルをステージングエリアに追加
3. コミット
`git commit -m "説明"`

# GitHubにリポジトリを作成
[GitHub](https://github.com/)で新しいリポジトリを作成

# ローカルリポジトリをGitHub上のリポジトリ（リモートリポジトリ）に関連付ける
作成したリポジトリのURLをコピーし、`git remote add origin URL`を実行

# ローカルリポジトリをGitHubにPush
= リモートリポジトリにコピーを保存する
`git push -u origin main`
"-u"は追跡ブランチに設定することを意味する。つまり、以降は`git push`のみでよくなる。

# エラー対処
* Author identity unknown
`git config --global user.email "GitHubでのメールアドレス"`
`git config --global user.name "GitHubでの名前"`
<br \>
* src refspec main does not match any
`git status`で、On branch masterと出るなら
`git branch -M master main`
をすると、masterがmainになるので、もう一度
`git push -u origin main`

# 別のパソコンから開発を再開する場合
1. GitHub上のリモートリポジトリのURLをコピー（緑色のCodeボタンを押すと出てくる）
2. `cd`でリモートリポジトリをダウンロードしたいフォルダに移動
3. クローン（ダウンロード）する
`git clone URL`
4. `cd`で今クローンしたフォルダに移動
5. `npm install`
これをしないと次の手順でエラーが発生する
6. `npm start`
AtcoderをしていてC++のsetで二分探索をしたときにvectorと同じ書き方をしてTLEになる罠

# vectorと同じ書き方だとO(N)になる
Nをsetの要素数とします。
下のコードのようにvectorと同じ書き方で書くと、「二分探索なのでO(log N)」と思いきや「O(N)」になります。
```C++:C++17
#include <bits/stdc++.h>
using namespace std;
int main(){
  set<int>st;
  st.insert(1);
  st.insert(3);
  int a = 2;//a以上で最小の値を見つけたい
  auto it = lower_bound(st.begin(),st.end(),a);
  cout<< *it <endl;
}
```
```
3
```
原因はsetではランダムアクセスができないから(らしい)です。vectorの場合[ i ]や.at( i )などでランダムアクセスができますが、setではできません。なので「setの中身を最初から順番に見ていく」のようなことが起きてO(N)になると思われます。
# set専用の二分探索の書き方をすればO(log N)になる
```C++:C++17
#include <bits/stdc++.h>
using namespace std;
int main(){
  set<int>st;
  st.insert(1);
  st.insert(3);
  int a = 2;//a以上で最小の値を見つけたい
  auto it =st.lower_bound(a);
  cout<< *it <<endl;
}
```
```
3
```
「set.lower_bound(p)」のように書けばO(log N)で、p以上で最小の値を取得することができます。もちろんupper_boundも同じように使えます。
set専用のかき方をすることによって、setの木構造を根から調べていくことにより、O(log N)になっていると思われます。詳しい仕組みは緑コーダーにはわかりません()
# おわりに
setでvectorと同じ書き方をするとTLEになるという記事を1つ見つけましたが、「実行時間が長くなる」のようなことだけ書かれていて、「TLEになる原因」のような記事がなかったのでこの記事を書きました。これを知るきっかけになった問題を貼っておきます。よければ解いてみてください。
https://atcoder.jp/contests/abc260/tasks/abc260_d
.gitconfigでRepositoryごとで使いたい名前やメールアドレスなどを変えたい時に

## はじめに
- Repositoryごとで都度「git config --local user.xxxx」 をするのが面倒になったため、楽をするための設定をここに


## 設定方法の抜粋
- [includeの説明](https://git-scm.com/docs/git-config#_includes)
    - includeIfを使って対象ディレクトリごとで読み込ませる設定ファイルを切り替えよう
    
    ```.gitconfig
    [includeIf "gitdir:/path/to/A/**"]
	    path = path = /path/to/.gitconfig.work1
    
    [includeIf "gitdir:/path/to/B/**"]
	    path = path = /path/to/.gitconfig.work2
    ```
    
    ```.gitconfig.A or .gitconfig.B
    [user]
	    email = xxxx@yyyy.yyy
	    name = zzz
    ```
人生2回目のチーム開発を行いまして(アニメ聖地巡礼アプリ開発)

# 1.はじめに
自分は10月よりAPPRENTICE SHIP(内定直結型エンジニア学習プログラム)のカリキュラムに２期生として参加しています。
この記事は2回目のチーム開発を行なって、振り返りを記事にしたものとなります。

# 2.イントロ：前回の振り返り
前回、フルスタックフレームワークを使用せずにチーム開発を行いました。
その中での反省点が色々と浮き彫りになりました。
今回の開発ではその反省を踏まえて開発ができたのでしょうか？
[前回のチーム開発備忘録の記事](https://qiita.com/hirapg_1123/items/27efa01618181b2fe324) 

# 3.2回目の開発体制と開発テーマ
さて、開発体制ですが1人増え４人体制となりました。
前回同様、初対面の方々と開発していく流れとなります。
その中で開発するテーマが「ワクワクするものを開発せよ！」
なかなかに掴みどころのない、テーマでしたが我々のチームはワクワクというテーマをどう捉えたかというと。。。

# 4.みんなで作る聖地巡礼アプリ「Animecca」
## どういったアプリか？
ワクワクすると言えば色々あるとは思いますが、チーム内ではワクワクする体験をということで各自アイデアを持ち寄り、聖地巡礼アプリ「Animecca」を開発しました。

Animeccaは読んで字の如く、"アニメ"＋"聖地"というアニメの聖地を探す、登録できるSNS型のアプリになります。

このアプリの特徴は
- 何話のどのシーンで舞台となったか細かいところまで登録できる。
- アニメ内に複数出てきた聖地を登録できる。
- 自分の行きたい聖地をコレクションしておける。

など、既存のアプリでは出来なかった、細かいところまで登録できる聖地巡礼アプリを目指して開発をされました。

**トップ画面**
トップ画面では主に、都道府県または作品名から検索ができるようになっています。
![localhost_3000_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954214/8069a01f-16e3-881e-6c49-5a95634004c4.png)

**都道府県検索結果画面**
例えばですが、東京都で検索をするとGoogleMapが表示され、各聖地がピンで表示されます。
![localhost_3000_prefecture_%E6%9D%B1%E4%BA%AC%E9%83%BD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954214/f8d7bcbf-773c-df21-2353-dd60d0628833.png)

**聖地詳細画面**
詳細画面では、どの話数、どこの秒数で出てきたかまで見れるようになっています。
![localhost_3000_mecca_new (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954214/d6d5c7e8-5bfd-a045-4f1f-8120943ca4e9.png)

## どういう技術で作られているか？
簡易アーキテクチャ図
![名称未設定2.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954214/75bb5f41-001c-064f-7fd0-93f836149cf8.jpeg)
フロントエンド : Next.js(TailwindCSS使用)
バックエンド : Ruby On Rails (APIモード)
DB : SQLite(開発環境のためRails標準のものを使用)
外部API : GoogleMap API / Aannict API
ソースコード管理 : Git/GitHub
環境構築 : Docker


# 5.開発
## 担当作業
主だった作業は全員で進めていきましたが、
- dockerでの全体環境構築
- バックエンド全般

の二つをメインを行いました。

## 前半 : アイディア出し〜要件定義
今回のチームでのアイデア出しは簡素に行い、全員が持ち寄った案の中から決めるものとなりました。
前回の開発では時間を掛けて考えていただけに、あっさりと決まりました。
要件定義では、ワイヤーフレームなども各自で考えたものをまとめて反映されるのはすごく良かったと思います。
### 良かった点
- 早めに案が決まり、要件定義や設計に時間を割けたため、時間に余裕ができたのは良かった
- 要件定義の部分でも、既存アプリに沿った作りとなったため、あまり迷わずに決めることができた

### 悪かった点
- コンセプトは良かったが、既存のアプリとの差別化や、何に重きを置いて作るのかが迷走し掛けてしまった

## 中盤 : 設計〜タスクだし
設計段階では、環境構築まわりとバックエンド周りを担当しました。
前回開発で諦めてしまった、Dockerでの環境構築を行いました。
時間は掛かりましたが、この段階で動くところまで持って行けたので良かったです。

### 良かった点
- Dockerでの環境構築はチーム内で共有することができた
- APIなども各自考えたものをまとめたので認識ズレが途中で起きるなどがなかった
- DB設計についても同じことが言える

### 悪かった点
- Dokerは時間がかかることが予想されたため、早めに取り掛かっていたが、詰まったところでチーム内に情報を共有するなどが出来ていなかった

## 後半 : 開発〜ハッカソン
開発では、フロントとバックに分かれて開発を行い、バックエンドを中心に開発を行いました。
設計段階でAPIの設計をまとめて頂いたおかげで、ほとんど詰まることなく開発を行うことが出来ました。
### 良かった点
- 何はともあれ、ハッカソンまでに動くものを作れたのは良かった
- 責任範囲分担をすることで、開発に集中することができた

### 悪かった点
- フロントとバックエンドの連携を確かめるのが、最後の最後になってしまい細かいところ直すのに余裕を持たせられなかった

## 全体を通しての改善点
- 開発段階など情報交換　(特にフロントとバックエンドの間)が少ないように感じたので、もう少し連絡を密に取る必要があると思った。
- Dockerを使用して、１メンバーでアプリの動作に不備が残ってしまったので、そういったことを早めに解消できる仕組みを作る必要性があった。


# 6.所感

2回目ということもあり、前回の反省を踏まえた上で開発が行えたので、詰まる箇所が少なくなりました。
ですが、Dockerでの環境構築がとりあえず動く状態で開発に移ったので、後半でエラーに詰まったりなど、時間を割くことが多かったです。
個人開発までには、環境構築は深掘りできたらと思う所存です。
ハッカソンではベストアワードは逃したものの、コメントを頂けたりなど、開発期間が短いながらもちゃんとしたものを作れたのは嬉しかったです。
次回はいよいよ、個人開発に移りますが今回の反省点を活かして開発をしていきたいです。
[Laravel / Fortify] 隠蔽された認証処理を可視化、カスタマイズしよう！

**プロフィール**
* 新卒エンジニア
* プログラミング歴は2年
* Laravel / TypeScript を主に使用
* 現在は Nestjs / アーキテクチャ を学習中
* めちゃめちゃ柏レイソルサポ

本記事は初学者向けです。
他にも解決方法はありますが、簡単で分かりやすい解決方法を採用しています。

## Laravel / Fortifyについて
Laravelの認証パッケージには複数の種類がありますが、私は以下の2つの使用経験があります。
1. Laravel / ui
1. Fortify

私がLaravelの学習を始めるにあたり、以下の書籍を購入し学習しました。
おそらく最もメジャーな書籍だと思われます。
[PHPフレームワーク Laravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-Laravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0%E6%B4%A5%E8%80%B6%E4%B9%83-ebook/dp/B08625YD7H/ref=sr_1_2_sspa?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2FN7UPSKFVPN6&keywords=Laravel&qid=1707662428&sprefix=laravel%2Caps%2C205&sr=8-2-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1)

こちらの書籍では認証に Laravel / uiが用いられています。
正直なところ、初心者にはかなり難しいように思えます。
xampp、apache等で環境構築をされる方が多いと思われますが、laravel / uiでは認証用で別のローカルサーバを起動させる必要があります。そのため、かなり少し面倒です（笑）

**Fortifyは個人的に大変便利だと思います！**
1. フロントが自由過ぎる
1. パッケージをインストールすればいいだけ

フロントは全て自分で書きます！
inputタグのname属性さえ遵守すれば、全て自由です！
ですが、自分で書くのが面倒であまり好まない方も一定数いるようですね（笑）
僕はFortify好きです！


## 認証処理が記述されているファイル

Fortifyをインストールした時点で以下のパスのファイルに認証処理が記述されています。

登録処理
ーvendor/laravel/fortify/src/Http/Controllers/RegisterdUserController.php
　storeアクション

ログイン処理
ーvendor/laravel/fortify/src/Http/Controllers/AuthenticatedSessionController.php
　storeアクション

ログアウト処理
ーvendor/laravel/fortify/src/Http/Controllers/AuthenticatedSessionController.php
　destroyアクション

 vendor内にあるため、リポジトリにpushする際には共有されず、カスタマイズするにはこれらの処理をapp内のコントローラファイルに記述する必要があります。
 
**まあコピペすればいいだけですね！**

以下のことが実現することができます。
 
 
:::note info
 実現できること
 1. バリデーションのカスタマイズ
 1. 認証後のルーティング操作が柔軟に
:::

**前者を実現するにはコピペしたアクションの引数にフォームリクエストを設定**
**後者を実現するにはアクションの返り値にredirect先を設定**

::: note alert
 コピペの際の注意点

1. 使用するクラスの読み込みを必ずする
1. 使用する関数も必ず記述する
:::
前者に関しては、**php intelephence** というvscodeの拡張機能を用いると、読み込みのないクラス、使用していないクラス等が分かりやすいため、便利です。
後者に関しては、上記で記載したアクション以外の関数についてですね。

## ルーティングの設定
次にルーティングの設定です。
ルーティングをweb.phpに記述する必要があります。

まずFortifyをインストールした時点で、デフォルトでルーティングは設定されます。
ですがvendor内の処理を行うため、**コピペしたコントローラファイルの処理を行うように上書きする必要があります。**

web.phpに以下のように記述をしましょう。
```
Route::post('register',[登録処理をコピペしたコントローラ::class,'store']);
Route::post('login',[ログイン処理をコピペしたコントローラ::class,'store']);
Route::post('logout',[ログアウト処理をコピペしたコントローラ::class,'destroy']);
```
これでルーティングを上書きできました。
もし上手くいかないようでしたら、以下のコマンドでルーティングに対応するアクションを確認してみましょう。私はこちらのコマンドで上記の設定ファイルを探し出し、自分でカスタマイズしました。

```
php artisan route:list
```

## 確認用パスワードを必須としない場合
app/Actions/Fortify/CreateNewUser.phpを編集する必要があります。
以下のように編集しましょう。

```
'password' => $this->passwordRules(),
上記の記述を削除し、

'password' => 'required|min:8',
こちらに変更
```
以上の編集をすることで、確認用パスワードは不要になります。

## まとめ
色々やりましたが、以上のことを行えば必ずできるかと思われます。
あまり具体的には記述せず、順序のみ記載していますが、認証について少しでも理解が深まると嬉しいです！

また、改めて言いますが、
本記事は初学者向けです。
他にも解決方法はありますが、簡単で分かりやすい解決方法を採用しています。

他の解決方法が知りたい人は、以下のワードを調べてみてください！

- サービスコンテナ
- サービスプロバイダ
- バインド
- 継承

などなど
【PostgreSQL】json型の値でプロパティを追加や削除する

## 概要
PostgreSQLのテーブルにてjson型の列の値へ、プロパティ追加や削除の操作をする際のメモ書きです。

## 対応方針
* プロパティの追加や更新を行う方法は[Postgresql update json data property](https://stackoverflow.com/questions/47454358/postgresql-update-json-data-property)のstackoverflowの記事でいくつか紹介されています。PostgreSQLのバージョン9.5以上であれば、`||`演算子を使う方法がわかりやすい気がします。
* プロパティの削除を行う方法は[PostgreSQL: Remove attribute from JSON column](https://stackoverflow.com/questions/23490965/postgresql-remove-attribute-from-json-column)のstackoverflowの記事でいくつか紹介されています。PostgreSQLのバージョン9.5以上であれば、`-`演算子を使う方法がわかりやすい気がします。

## 実装サンプル
テスト用に以下のテーブルを用意します。今回はjsonの列はjson型にしていますが、jsonb型でも構いません。

```sql
CREATE TABLE public.sample_table (
	id int8 NOT NULL,
	json_value json NOT null,
	CONSTRAINT samle_table_pk PRIMARY KEY (id)
);
```

追加や更新を行う際は以下のようなSQLで実現できます、該当行の値に`property2`のプロパティを追加もしくは更新する操作となります。なお、テーブルの列がjsonb型の場合はjsonbへのキャストは不要です。

```sql
update sample_table set json_value = json_value::jsonb || '{"property2":"value2"}' where id=1
```

削除を行う際は以下のようなSQLで実現できます、該当行から`property2`のプロパティを削除する操作となります。なお、テーブルの列がjsonb型の場合はjsonbへのキャストは不要です。

```sql
update sample_table set json_value = json_value::jsonb - 'property2' where id=1
```
Djangoでmakemigrationsしてもmigrationファイルが作成されなかった

## 背景
Djangoで開発中のアプリケーションにてmakemigrationsコマンドを用いて
migrationファイル作成を試みたものの、下記の文言のみ出力されるたけで、
migrationファイルが作成されない状態に陥ってしまった。

```
No changes detected in app '○○○○'
```

## 原因
models.pyで管理する各modelクラスをmodelsフォルダ配下で管理するようにした場合、
models/__init__.pyを作成して、そのファイル上で対象となるmodelクラスをimportする
必要があったが、この対応を実施していなかったため、migrationファイルの作成に失敗していた。


### 具体的な対処方法
例えば、modelsフォルダにExampleのmodelクラスを管理している場合は、
下記の文言を、models/__init__.pyに記載する必要があった。


```python:models/example.py
from django.db import models


class Example(models.Model):
    id = models.BigAutoField(primary_key=True)
````

```python:models/__init__.py
from .example.py import Example

````

## 結果
上記の対応を実施した結果、無事migrationファイルが作成された。