OmniAICreator/Qiita-1.07M huggingface dataset:
【ReactNative】OSや端末ごとに条件処理を実装

OSや端末ごとに条件分岐して値を変更したり、表示するテキストを変更する必要があったので、記載していきます。

https://reactnative.dev/docs/platform

を参考に進めていきます。

# 概要
### Platform.OS
![スクリーンショット 2024-02-10 6.58.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/3f041baa-d4b0-8133-3b74-a812205eae34.png)
- OSをenumで管理しています

### Platform.isPad
![スクリーンショット 2024-02-10 6.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/0c95ba39-2aa2-2fcc-2e86-08bf8582d0e1.png)
- iPadかどうかを、boolean型で返します
### Platform.select
![スクリーンショット 2024-02-10 6.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/2c113090-766a-9a50-cff7-9aa872d9fbf0.png)

>- The config parameter is an object with the following keys:
>- android (any)
>- ios (any)
>- native (any)
>- default (any)

上記のパラメーターを指定することによって、開いている環境によって条件分岐をすることができます。

# 実装

### Platformをインポート
```js
import { Platform } from 'react-native';
```

### 環境による表示変更
```js
{Platform.OS === 'ios' && <Text>iOS用のコンテンツ</Text>}
{Platform.OS === 'android' && <Text>Android用のコンテンツ</Text>}
```
- デバイスのOSがiOSの場合、`<Text>iOS用のコンテンツ</Text>`が表示されます
- デバイスのOSがAndroidの場合、`<Text>Android用のコンテンツ</Text>`が表示されます
- 条件分岐を使って、デバイスごとに異なるコンテンツをレンダリングしています

```js
{Platform.isPad && <Text>iPad用のコンテンツ</Text>}
```
- デバイスがiPadである場合、`<Text>iPad用のコンテンツ</Text>`が表示されます。


```js
const number = Platform.select({
  ios: '1',
  android: '2',
  default: '3',
});
```
- `Platform.select()`メソッドを使用して、プラットフォームごとに異なる値を設定しています
- `ios`キーが存在する場合、`android`キーが存在する場合、どちらの条件にも当てはまらない場合は、`default`キーで指定された値が選択されます
- `default`キーはWebブラウザで設定されます

```js
<Text>{number}</Text>
```
環境ごとに異なる値が入った`number`関数を表示しています。

上記を実装し、スタイルを整えたサンプルコードを添付しておきます。

<details><summary>サンプルコード</summary>

```js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Platform } from 'react-native';

const number = Platform.select({
  ios: '1',
  android: '2',
  default: '3',
});

export default function App() {
  return (
    <View style={styles.container}>
      <Text>共通のコンテンツ</Text>
      {Platform.OS === 'ios' && <Text>iOS用のコンテンツ</Text>}
      {Platform.OS === 'android' && <Text>Android用のコンテンツ</Text>}
      {Platform.isPad && <Text>iPad用のコンテンツ</Text>}
      <Text>{number}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```
</details>





 
# 挙動確認

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/30b1d85a-0256-cdb2-d3f3-798ba582b656.png">
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/7da0ae4d-7eb8-73e3-f80d-3ae0af52100c.png">
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/6d40cb59-bb95-7d9c-e976-591364823fa7.png">
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799713/a1688bf0-7d09-533f-92c7-4788875e84fd.png">


iOS,Android,iPad,ブラウザで、環境ごとに異なった表示を行うことができました👏

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

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

個人でアプリを作成しているので、良かったら覗いてみてください！
【React】onClickイベントとは

# onClickイベントとは
onClickイベントは、要素がクリックされたときに実行されるイベントハンドラーを定義するための特別な属性です。onClickイベントは、ユーザーがマウスやタッチデバイスで要素をクリックしたときに発生します。onClickイベントを使用すると、ユーザーの操作に応じて特定の処理を実行することができます。

onClickイベントは、Reactコンポーネントの要素に直接適用され、以下のように使用されます：
```jsx
<button onClick={handleClick}>Click me</button>
```
上記の例では、ボタンがクリックされたときに `handleClick` という関数が呼び出されるように設定されています。onClick属性には、クリック時に呼び出される関数を指定するためのコールバック関数が渡されます。

# 使用方法
コンポーネント内でonClickイベントを定義する方法はいくつかあります。以下は、クラスコンポーネントと関数コンポーネントのそれぞれでのonClickイベントの定義方法の例です：

クラスコンポーネントの場合：
```jsx
class MyComponent extends React.Component {
  handleClick() {
    console.log('Button clicked');
  }

  render() {
    return (
      <button onClick={this.handleClick}>Click me</button>
    );
  }
}
```
関数コンポーネントの場合（useStateフックを使用）：
```jsx
import React, { useState } from 'react';

function MyComponent() {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return (
    <button onClick={handleClick}>Click me</button>
  );
}
```
onClickイベントは、ユーザーのインタラクションに応じてコンポーネントの状態を更新したり、特定のアクションを実行したりする際によく使用されます。
【React】JSとJSXの違い

# JSとJSXの違い
JavaScript（JS）とJSXは、基本的に同じ言語であるJavaScript（ECMAScript）の異なる構文形式ですが、いくつかの重要な違いがあります。

1\. **構文**
- JavaScript（JS）は、ECMAScript標準に準拠した純粋なJavaScriptのコードです。
- JSXは、JavaScriptの構文を拡張したもので、HTMLライクな構文を使用してReactコンポーネントを記述します。

2\. **記述方法**
- JavaScriptでは、要素やコンポーネントはJavaScriptの構文に従って記述されます。HTML要素を作成する場合は、createElement()などのメソッドを使用します。
- JSXでは、HTMLライクな構文を使用してReactコンポーネントを記述します。これにより、UIの構造や関係性をより直感的に表現することができます。

3\. **変換**
- JavaScriptはそのままブラウザやNode.jsなどのJavaScript実行環境で実行されます。
- JSXはBabelなどのトランスパイラによってJavaScriptに変換されます。トランスパイルされたJavaScriptは、Reactが提供するcreateElement()などの関数呼び出しに変換されます。

4\. **動的な値の埋め込み**
- JavaScriptでは、動的な値を埋め込む際に文字列連結やテンプレートリテラルを使用します。
- JSXでは、JavaScriptの式を `{}` で囲んで埋め込むことができます。

以下は、JavaScriptとJSXの比較例です：
```js
// JavaScript
const element = React.createElement('h1', null, 'Hello, world!');

// JSX
const element = <h1>Hello, world!</h1>;
```
JavaScriptのcreateElement()関数を使用してReact要素を作成する代わりに、JSXではHTMLライクな構文を使用してReact要素を直接記述することができます。
【React】JSXとは

# JSXとは
ReactのJSXは、JavaScript XMLの略であり、ReactでUIを記述するための構文拡張です。JSXは、JavaScriptの構文にHTMLライクな要素を組み込むことができるため、Reactコンポーネントの記述が直感的になります。

# 特徴
JSXの特徴は以下の通りです：

1\. **HTMLライクな構文** : JSXでは、HTMLライクな構文を使用してReactコンポーネントを記述することができます。これにより、UIの構造や要素の関係性を直感的に把握することができます。

2\. **JavaScriptとの統合** : JSXはJavaScriptの拡張であるため、JavaScriptの変数や式を埋め込むことができます。これにより、動的なデータや条件に基づいてUIを構築することができます。

3\. **Babelなどのトランスパイラで変換** : JSXはブラウザが直接理解できるJavaScriptに変換されるため、Babelなどのトランスパイラを使用して変換する必要があります。トランスパイルされたJavaScriptは、Reactが提供するcreateElement()などの関数呼び出しに変換されます。

# 使用方法
以下は、JSXの例です：
```jsx
// JSX
const element = <h1>Hello, world!</h1>;

// Babelによって変換されたJavaScript
const element = React.createElement('h1', null, 'Hello, world!');
```
この例では、JSXで `<h1>Hello, world!</h1>` という要素を記述しています。Babelなどのトランスパイラによって、React.createElement()関数によるReact要素の作成に変換されます。
Standard Logic Apps 閉域で Teams アダプティブ カードを投稿して応答を待機する

Standard Logic Apps ではファイアウォール設定配下にワークフローを作成することができます。

https://learn.microsoft.com/ja-jp/azure/logic-apps/secure-single-tenant-workflow-virtual-network-private-endpoint

https://learn.microsoft.com/ja-jp/azure/logic-apps/deploy-single-tenant-logic-apps-private-storage-account

https://learn.microsoft.com/ja-jp/azure/logic-apps/single-tenant-overview-compare

## Teams コネクタ

一方 Teams コネクタの中の「アダプティブ カードを投稿して応答を待機する」際の設定を記載します。

https://learn.microsoft.com/ja-jp/connectors/teams/


以下:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/dc005387-496d-73bf-1c7e-3e2695194149.png)


https://ascii.jp/elem/000/004/134/4134579/

上の記事にてにて用いられている JSON を一部引用しております。

```JSON:JSON
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.2",
    "actions": [
        {
            "type": "Action.Submit",
            "title": "送信"
        }
    ],
    "body": [
        {
            "type": "TextBlock",
            "text": "本日の勤怠",
            "wrap": true,
            "size": "Medium",
            "weight": "Bolder"
        },
        {
            "type": "Input.ChoiceSet",
            "choices": [
                {
                    "title": "出社",
                    "value": "出社"
                },
                {
                    "title": "在宅勤務",
                    "value": "在宅勤務"
                }
            ],
            "placeholder": "Placeholder text",
            "id": "myChoiceSet",
            "style": "expanded"
        }
    ]
}
```


## プライベート エンドポイントを使って Standard ロジック アプリと Azure 仮想ネットワーク間のトラフィックをセキュリティで保護する # プライベート エンドポイントを経由する受信トラフィックに関する


考慮事項が以下になってきます。

https://learn.microsoft.com/ja-jp/azure/logic-apps/secure-single-tenant-workflow-virtual-network-private-endpoint#considerations-for-inbound-traffic-through-private-endpoints

> マネージド API Webhook トリガー (push トリガー) とアクションは、パブリック クラウドで実行され、プライベート ネットワークに呼び出すことができないため、機能しません。
**呼び出しを受信するには、パブリック エンドポイントが必要です。** たとえば、このようなトリガーには、Dataverse トリガーと Event Grid トリガーがあります。


「アダプティブ_カードを投稿して応答を待機する」 アクションにて用いられるうち、
投稿を待機する動作となる ApiConnectionWebhook (マネージド API Webhook) も、以下設定にて動作します。


以下の通り Logic Apps のパブリック ネットワーク アクセスを制限している状態。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/7e415773-c24a-ae33-a9d4-f93e21f557e2.png)


アクセス制限の詳細として、以下 AzureCloud のサービス タグを許可しておく必要があります。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/fa55ac91-2b30-b61d-46d3-bdfdf6c6a543.png)


## 結果
 
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/79964213-bd7c-9a17-8eb0-062e2abb7e43.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/a6fdf189-d9d2-a5dc-d7e2-d9ce85102892.png)



## 参考

AzureCloud とは何ぞという辺りを。

https://qiita.com/aktsmm/items/746d355b9b8e6fcc92a6

以上です～
Redux Toolkit でファイルのダウンロードで発生する A non-serializable value was detected への対処

```
A non-serializable value was detected
```

`Redux Toolkit` でAPIサーバーで生成したファイルを取得しようとしたら上記のエラーが発生してハマったので対処方法を記しておきます。

`Redux Toolkit` は基本的にAPIなどから取得したデータは全てシリアライズして `Store` に保持する設計になっています。
ファイルのような巨大なバイナリデータはそもそもキャッシュの対象外なので `Store` に値を渡さないような細工が必要になります。

### サンプルコード
`RTK Query` の [queryfn](https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#implementing-a-queryfn) を使って `Store` に値を渡す前にファイルダウンロードを実行し、 `Store` にはダミーデータを渡しています。

```js
const downloadFile = (blob, fileName) => {
  const elm = document.createElement('a');
  const url = window.URL || window.webkitURL;
  const fileUrl = url.createObjectURL(blob);
  elm.href = fileUrl;
  elm.target = '_blank';
  elm.download = fileName;
  elm.click();
};

export const downloadFileApi = apiBase.injectEndpoints({
  endpoints: (builder) => ({
    downloadFile: builder.mutation({
      queryFn: async (params, api, extraOptions, baseQuery) => {
        const result = await baseQuery({
          url: '/something/file',
          method: 'POST',
          body: params.apiParams,
          responseHandler: ((response) => response.blob())
        })

        downloadFile(result.data, params.fileName);

        return { data: null };
      }
    }),
  }),
});

export const {
  useDownloadFileMutation
} = downloadFileApi;
```

上記のAPIクライアントの呼び出し側の実装は以下のようになります。

```js
const [downloadPdf] = useDownloadPdfMutation();

const downloadAction = () => {
  const params = {
    apiParams: {  }, // 略
    fileName: 'hoge'
  };

  downloadPdf(params);
};
```

### 参考サイト
以下のリンク先のIssueのコードを参考にしています、感謝！

https://github.com/reduxjs/redux-toolkit/issues/1522
C# 値型と参照型の違いで、構造体とクラスの違いの大枠をとらえる

# はじめに
構造体とクラスの大きい違いは、構造体は値型、クラスは参照型ということです
この記事の目的は値型と参照型の違いをしることで、副次的に構造体とクラスの違いや使いわけるための知識を得ることを目指してます

今回の目的は値型と参照型の動作を見て構造体とクラスのイメージをつかむことなので細かいところは省いています

## 値型(構造体)と参照型(クラス)
C＃でのデータ型の分類方法に値型と参照型というものがあります。
代表的なものを挙げてみると 値型は byte , short , int , long . 参照型は string , object , class　などがあります　

## 値型と参照型の違い

値型と参照型の違いはデータを格納する方法が違います
値型の変数は、値そのものが格納されます、それに対して参照型の変数はその値の参照(格納場所のアドレス)が格納されます

## スタックとヒープ

また値型の実際の値 、参照型の参照(格納場所のアドレス)の値を格納するメモリ領域をスタック 、参照型の実際の値が格納されているメモリ領域のことをヒープといいます

## スタック領域

スタック(LIFO)は最後に入れたものから順番に出していく(Last In Fast Out)の特徴を持った 一時的にデータを保管しておくメモリ領域のことです
またスタック領域は OSやコンパイラが領域を割り当て、解放を自動でしてくれます

## ヒープ領域

ヒープ領域も一時的にデータを保管しておくメモリ領域ですが順番とかは関係なく動的に割り当て、解放ができます
言語によってはメモリの解放を手動でしますが 、C# はガベージコレクション(メモリの管理をしてくれるシステム)が自動でしてくれます

### 値型

<img width = "550" src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/5e0403d1-31d8-d85b-6daf-fec3bba8ff7c.png>

### 参照型

<img width = "600" src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/3fb408ea-cdc6-f4dd-0bb4-619b30e3c01f.png>

## 値型と参照型の動作の違い

### スタック領域の割り当て、解放のほうが軽量？
ガベージコレクションは動的に領域を割り当てと解放をするので管理が複雑、不要なメモリを解放する以外の動作(オーバーヘッド)がともなうのでスタック領域の割り当て、解放のほうが一般的に軽量。


# 注意点
前述したように値型と参照はデータの持ち方が違うので動作にも影響が出てきます

## 等価演算子( == )の場合

等価演算子は比較してる値もしくは、参照が同一かを比べています
なので参照型に等価演算子を用いると実際のデータ的には同じでも参照が違う可能性があるのでfalseが返ってくる場合があります

### 値型のイメージ 
hoge == test　をするとtrueが返ってきます 
<img width = "600" src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/02f8589a-d86b-0e90-516f-2d573f8b1c86.png>

### 参照型のイメージ 
hoge == test をするとfalseが返ってきます
<img width = "600" src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/35bbf6c3-8fed-5055-7c03-932c90f9edbd.png>

## 参照が同じときの注意点
### 参照型のイメージ 
<img width = "600" src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/a52e4b6a-d8df-4447-3a2f-57ee061a561c.png>

参照が同じだと変更したときに参照が同じオブジェクトのデータがすべて変わってしまいます
例えば上の図の hogeにhoge.Append("ほげ"); をするとhogeとtestの参照が同一のためhogeだけではなくtestまで変更が加わってしまいます
値型は影響ないです

## 値型と参照型の使い分け
参照型はメモリを割り当てるときに参照をコピーし、値型の割り当てでは値全体をコピーするので大きいオブジェクトになると値型よりも参照型のほうがコストが低いです

## 参考

・https://uquest.tktk.co.jp/embedded/learning/lecture16.html
・https://learn.microsoft.com/ja-jp/dotnet/standard/design-guidelines/choosing-between-class-and-struct
。https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/equality-comparisons
・[独習C#  第5版 ](https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92C-%E7%AC%AC5%E7%89%88-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4798175560/ref=asc_df_4798175560/?tag=jpgo-22&linkCode=df0&hvadid=589020067580&hvpos=&hvnetw=g&hvrand=6019865904308423204&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9053266&hvtargid=pla-1735236351317&psc=1&mcid=5c6b239a8ce73ba1b6a2009bffcd70cb&th=1&psc=1) 

## まとめ
・構造体とクラスの大きな違いは値型と参照型であること 
・値型と参照型の大きな違いはスタック領域かヒープ領域のどっちに実体を持つのかということ。またその違いで動作に影響が出てくること
・スタック領域とヒープ領域の違いはメモリの管理を自動的にするか 、ガベージコレクション(手動も可)でするかということ
・大きいオブジェクトだと参照型のほうが低コスト

以上です、お読みいただきありがとうございました。
【WordPress】Local (Local by Flywheel) でサクッとローカル開発環境を構築する。

個人開発でWordPressを使用したサイトを構築する機会があり、噂で聞いていた
**Local(Local by Flywheel)** を試してみることにした。
今回はLocalの導入、ローカル環境でのWordpPressのセットアップまで書き記します。
# Local(Local by Flywheel)とは
LocalはWordPressの開発環境を効率よく構築できる支援ツール。
**XAMMP**や**MAMP**と違ってGUI上の操作でサクッとセットアップ出来るとの事で気になっていた次第。

# 使用OS
Windows11
# 構築手順
## 公式からLocalのダウンロード
まずは[Local](https://localwp.com/)の公式サイトへアクセス。
画面右上の「**DOWNLOAD**」をクリックするとダウンロード前の質問としてモーダル画面が立ち上がります。

「Please choose your platform」のプルダウンは使用しているOSを選択。
（私の場合はWindows）

「Please choose your organization type」は属している組織の種類。
今回は個人開発なので「**Other**」にしました。

あとはメールアドレスを入力して「GET IT NOW!」をクリックするとダウンロードが始まります。
※名前は省略可能みたいです。
## Localのインストール
インストーラーを起動して任意のフォルダにインストール。
インストールオプションで特にこだわりがなければ「次へ」をクリックしていくだけでインストールは完了です。
## Localの管理画面上からWordPressのローカル開発環境を構築する
Localを起動したら、画面左下の＋アイコンもしくは（インストールしたてなら）
「CREATE A NEW SITE」をクリックします。

サイト作成画面（英語）に遷移するので「Create a new site」が選択されている状態で右下の「Continue」をクリック。

「What’s your site’s name?」という画面が表示されるので英数字でサイト名を入力して「Continue」をクリック。サイト名はそのままドメインなどにも利用されます。

「Choose your environment」画面に進んだら「Preferred」を選択（デフォルト表示）し「Continue」をクリック。
「Custom」ではPHPやデータベースの独自設定が行えるみたいです。

「Set WordPress」画面が表示されたら、WordPressのユーザー名とパスワードを入力。
「ADD SITE」をクリックします。

ここまで来たらセットアップが開始します。その間、ユーザーアカウントの制御画面が出ますが「はい」をクリックして許可してください（NginxとMailHogというテストメールが送れるツール）

許可をするとセットアップが完了。Localの管理画面上に設定したWordPressのテストサイトが出来上がります。
お疲れ様でした！

画面上、右にある「Open site」からは立ち上げたサイトのページ、
「WP Admin」はその名の通りインストールしたWordPressの管理画面を開きます。
## 立ち上げたWordPressサイトを日本語化する
WP Adminからセットアップ時に設定したユーザー名とパスワードでログインし
「Setting」→「General」→「Language」の順で使用する言語に選択して保存するだけです。
簡単ですね。
これで一通りローカルでの開発環境がセットアップできました。
## 思ってたより簡単だった
説明は長くなったが、作業にかかった時間は10～15分程度だった。
今までXAMMPやMAMPを使ってローカルサーバを構築してきたが、confファイルをエディタで編集したり面倒だったが、それがGUI上で直感的な操作で用意できるのが素晴らしいと思った。

Localには他にも開発をサポートする強力な機能があるらしいので触れながら色々覚えていきたい所存。

## 参考サイト
[Local（Local by Flywheel）の使い方まとめ | サトウ工房](https://www.satokobo.net/1259)
UbuntuでshadowSocksサーバを起動(中国 Great Fire Wall対策)

# shadowsocksとは
https://shadowsocks.org/

# やること
1. EC2でUbuntu OS (22.04 LTS)を立てる。インスタンスはt3.microくらいでOK。このときSecurity Groupをshadowsocks(デフォは8388）ポートを開けておく
1. shadowsocksのinstall
1. config.jsonの編集

# shadowsocksのインストール

```
sudo su
apt-get update
apt install shadowsocks-libev
```

# config.jsonの編集

```
vim /etc/shadowsocks-libev/config.json
```

編集内容

```json
{
    "server":"0.0.0.0",
    "server_port":8388,
    "local_port":1080,
    "password":"your_password",
    "timeout":86400,
    "method":"chacha20-ietf-poly1305"
}
```

## shadowsocksの再起動
```
sudo systemctl restart shadowsocks-libev
sudo systemctl status shadowsocks-libev

```


# 参考
1. https://github.com/shadowsocks/shadowsocks-libev
uuidをモックする

少し手こずったのでメモとして残してきます。

```python:sample.py
import uuid

def get_id():
    return uuid.uuid4().hex
```
```python:test.py
from unittest.mock import patch, Mock, PropertyMock
from sample import get_id

# sample.py内のuuidをパッチする
patcher = patch("sample.uuid.uuid4")
mock = patcher.start()
m = Mock()

# プロパティをモックする
# side_effectを使って連番を返すようにする
p = PropertyMock(side_effect=[f"id_{i}" for i in range(2)])
type(m).hex = p

# uuid4()の返り値にモックを設定する
mock.return_value = m

assert get_id() == "id_0"
assert get_id() == "id_1"
patcher.stop()
```
iOS17.2のネットワーク共有はIPv6だけになっていた

Xで話題に上がったので調べてみたところ、iOS17.2のネットワーク共有ではIPv4通信は行われず、IPv6のみになっていた模様。

AppleCommunityでも話題に上がっていました。
どうやらiOS17.2ではIPv4アドレスがアサインされなくなった、とのこと。

https://discussions.apple.com/thread/255346180?answerId=259959698022


実際にiPhoneのネットワーク共有をonにしたところ、iPad上のIPv4の表示は192.0.0.2/32となっています。

![スクリーンショット 2024-02-15 1.52.41.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601755/f2312dde-637e-75b0-0cfa-68ea950fee92.jpeg)

Wiresharkで見てもインターネット通信はすべてIPv6で行われていることが確認できました。

なお、IP設定を手動にしてDHCPを使用しない場合、ネットワーク共有に繋がっている機器同士は通信が可能な状態でした。
しかし、ネットワーク共有元の端末は自身のIPを設定する方法がないため、そのネットワークにIPv4通信で参加することができません。

通常、インターネットを共有したい、というケースでは問題になりませんが、IPv4通信を行うアプリケーション同士の通信のために、現場対応としてローカルネットワーク代わりに使用しようとすると問題が生じます。素直にwifi ルータ使ってLAN立上げましょう。

---
Apple公式のソースを発見できなかったので、ご存じの方がいらっしゃれば教えてください。
YOLOv8を使用するときに役に立ったサイト・ウェブページ

YOLOv8を使用するときに役に立ったサイト・ウェブページたちをご紹介

https://medium.com/@tejasdalvi927/object-detection-with-yolo-and-opencv-a-practical-guide-cf7773481d11#:~:text=Object%20detection%20is%20a%20fundamental,detection%20capabilities%20with%20impressive%20accuracy.　


すごいわかりやすい。的確でシンプルで練習用コードも載っている！


https://colors.ambl.co.jp/yolov8-how-to-use-tech/

ディープラーニングによる物体検知技術
を用いた図面要素抽出の研究 5YOLOv
 detection-object an using drawings completion highway in detection table 5
 
http://www.rcuss.kobe-u.ac.jp/publication/Year2022/pdfEach26/26_03.pdf


学習元画像のやつ

https://chem-fac.com/yolov8/

アノテーションツールlabelImg
学習するには画像データとラベリングデータが必要です。

画像データ：目的の物体が載っている画像
ラベリングデータ：どこにどのような物体が載っているのかを示した情報
画像データに対してラベル付けすることをアノテーションと呼びます。

集めた画像データにlabelImgというツールを使いアノテーションします。


https://farml1.com/yolov8/


まさに私がやりたいことがオリジナルデータの物体検知だったので助かりました。
アノテーションの概念とかついていくの大変すぎる。
GASを使ってWEBページに自動投稿するサンプルソース｜メモ

Google Apps Script（GAS）を使用して、WEBページに自動投稿するサンプルソース

**Google Apps Scriptの新規プロジェクト作成**
Googleドライブにアクセスし、新しいGoogle Apps Scriptプロジェクトを作成します。

**ウェブページへの投稿の準備**
GASからウェブページに投稿するための準備を行います。これには、ウェブページのAPIが必要になります。ウェブページがRESTful APIを提供している場合は、それを使用して投稿を行います。

**GASでPOSTリクエストを送信**
GASを使用して、ウェブページにPOSTリクエストを送信します。これには、UrlFetchAppクラスを使用します。
## サンプルソース
```Javascript
function postToWebpage() {
  var url = 'https://example.com/api/posts'; // ウェブページの投稿用APIのエンドポイント
  var payload = {
    title: '自動投稿のタイトル',
    content: '自動投稿の内容'
  };
  var options = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(payload)
  };
  
  // POSTリクエストを送信
  var response = UrlFetchApp.fetch(url, options);
  
  // レスポンスをログに出力
  Logger.log(response.getContentText());
}
```
この例では、ウェブページのAPIエンドポイントにPOSTリクエストを送信しています。payload変数には、投稿のタイトルと内容が含まれています。適切なAPIエンドポイントとペイロードを設定する必要があります。

また、ウェブページのAPIエンドポイントが認証を必要とする場合は、その認証情報もリクエストに含める必要があります。OAuthなどの認証方式が使われることがあるので、その場合はOAuthライブラリを使用して認証を行います。

このコードをGoogle Apps Scriptエディタに貼り付け、適切なURLとペイロードを設定した後、実行すると、指定したウェブページに投稿が自動的に行われます。
DockerのApacheでlocalhostに対してオレオレ認証のhttpsで接続する

# はじめに
タイトルの通りです。
ブラウザで `https://localhost/` で html ファイルが閲覧できるようになるところをゴールとします。

# 確認環境
- WSL2(Ubuntu22.04.3 LTS)
- Docker (24.0.6)
- Docker Compose (2.4.1)
- Apache 2.4.58 
※Apache については [こちら](https://qiita.com/naozo-se/items/2d7d0135c97081eb114e) の環境ベースで書き進めます

# 設定方法
## 秘密鍵と証明書ファイルを作成
既存の設定ファイル `conf/extra/httpd-ssl.conf` のデフォルト設定で鍵と認証ファイルのパスが 

- `/usr/local/apache2/conf/server.crt` 
- `/usr/local/apache2/conf/server.key`


になっているため、このパスの通りにファイルが配置されるように進めます

```shell:shell実行
# 設定ファイルのフォルダに移動(事前にプロジェクトフォルダに移動)
cd conf
# RSA 暗号方式の秘密鍵を作成
openssl genrsa 2048 > server.key
# 作成した秘密鍵からCSR(証明書署名要求)ファイルを作成
openssl req -new -key server.key > server.csr
# 自己署名証明書(CRT)を作成
openssl x509 -days 3650 -req -sha256 -signkey server.key < server.csr > server.crt
# 不要なCSRファイルを削除
rm server.csr
```


## Apacheの設定
```conf:conf/httpd.conf ※以下をコメントアウト
LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

Include conf/extra/httpd-ssl.conf
```

## compose.ymlの設定
composeファイルに、443ポートからアクセスできるように修正
```yaml:compose.yml
    ports:
      - '443:443'
```
※80は削除した方が良い
※すでにコンテナを起動している場合は、再作成が必要

## 確認方法
ブラウザで `https://localhost/` に対してアクセスする
![httpslocalhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/c3f8f238-5311-6914-7105-bee99696a71c.png)
※初回は、セキュリティの警告が出るが無視して接続する
※Locationのプロキシ設定も巻き込んで、httpsで接続できるようになります


## おまけ
`conf/extra/httpd-ssl.conf` を有効にせず `conf/httpd.conf`に対して直接記載したい場合は、
    
```conf
Listen 443
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"
</VirtualHost>
```
のみを末尾に追加しても接続可能

# 参考
https://masaki-blog.net/docker-apache-https

https://qiita.com/miyuki_samitani/items/b19aa5ac3b3c6e312bd5

# 最後に
設定ファイルがあらかじめ用意されているのは良いかもですが、module有効設定は調べるのが面倒です…
Nginxでは違った面倒さみたいなものがありますかね…
[Latex]目次でsectionのページ番号を出す・ラベルとページ番号の間にドットを入れる方法[titletoc]

目次を表示したいときは、プリアンブルに以下を記載する。
```latex
\usepackage{titletoc}
\titlecontents{section}[0zw]{}{\thecontentslabel\quad}{}
    {\titlerule*{.}{\thecontentspage}}
\titlecontents{subsection}[1zw]{}{\thecontentslabel\quad}{}
{\titlerule*{.}{\thecontentspage}}
```

挿入したい位置で、``\tableofcontents``とすると、目次が挿入される。以下は実行後のpdf
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664407/908b5eb5-988c-2ff3-b99e-4e4f4b529fb4.png)
【Nuxt3】認証付きの画像URLをimgタグで表示する方法

画像URLに認証がついている場合、単純に `<img src="https://....">` で画像を表示することはできません。

認証付きの画像URLをimgタグで表示したい場合は、下記手順で行います。

1. fetch APIで認証付き画像URLにアクセスし、レスポンスボディをblobオブジェクトとして受け取る
1. URL.createObjectURL で blobオブジェクトからオブジェクトURLを生成し、そのURLをimgタグのsrc属性に指定する


# 画像取得API

※ この例ではFastAPIを使っています

認証が必要な画像取得APIを準備します。
処理としてはS3から画像を取得して、StreamingResponseとして返すだけです。

```python
@router.get("/images/{image_id}/")
def download_image(
    image_id: int,
    _current_user: User = Depends(auth.get_current_user),  # 認証の処理 (省略)
):
    s3_client = boto3.client("s3", region_name="ap-northeast-1")
    s3_bucket = "xxxxxxxxxxx"
    s3_key = f"path/to/image/{image_id}.png"
    obj = s3_client.get_object(Bucket=s3_bucket, Key=s3_key)
    return StreamingResponse(content=obj["Body"], media_type="image/png")
```

# 画像を表示

fetch APIで先程作成した画像取得API( `/images/{image_id}/` )にアクセスして、imgタグで画像を表示します。

## imgタグで表示

- [URL.createObjectURL | MDN](https://developer.mozilla.org/ja/docs/Web/API/URL/createObjectURL_static)
    - [URL.createObjectURL() オブジェクトURLを用いた画像アップロードのプレビュー画面](https://takuya178.hatenablog.com/entry/2021/12/18/163401)
- [fetch API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)
    - [Response.blob() | MDN](https://developer.mozilla.org/ja/docs/Web/API/Response/blob)

```app.vue
<template>
  <div>
    <img :src="blobObjectUrl" width="500px" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const blobObjectUrl = ref<string>('dummy');
onMounted(async () => {
  const url = 'https://example.com/images/1/';
  // fetch API で認証付き画像URLにアクセス
  const res = await fetch(url, {
    method: 'GET',
    headers: { Authorization: `Bearer xxxxxxxxxxxxxxxxxxxxxx` },
  }).catch((err) => err.data);

  if (res.status == 200) {
    // レスポンスをblobとして受け取る
    const blob = await res.blob();
    // ブラウザのメモリ上に存在するblobオブジェクトを参照するためのURLを生成する。
    const objectUrl = URL.createObjectURL(blob);
    // オブジェクトURLをimgタグのsrc属性にセット
    blobObjectUrl.value = objectUrl;
  }
});
</script>
```

# Nuxt Imageを利用して表示

※ Nuxt Imageのインストール: `npm install @nuxt/image`

- [Nuxt Image](https://image.nuxt.com/)
    - [Nuxt Image - Usage](https://image.nuxt.com/usage/nuxt-img)

```app.vue
<template>
  <div>
    <!-- NuxtImg: https://image.nuxt.com/usage/nuxt-img -->
    <NuxtImg :src="blobObjectUrl" width="500px" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const blobObjectUrl = ref<string>('dummy');
onMounted(async () => {
  const url = 'https://example.com/images/1/';

  // 認証付き画像URLにアクセス
  const res = await fetch(url, {
    method: 'GET',
    headers: { Authorization: `Bearer xxxxxxxxxxxxxxxxxxxxxx` },
  }).catch((err) => err.data);

  if (res.status == 200) {
    // レスポンスをblobとして受け取る
    const blob = await res.blob();
    // ブラウザのメモリ上に存在するblobオブジェクトを参照するためのURLを生成する。
    const objectUrl = URL.createObjectURL(blob);
    // オブジェクトURLをNuxtImgタグのsrc属性にセット
    blobObjectUrl.value = objectUrl;
  }
});
</script>
```
RIP の技術概要と技術的課題

# 初めに 
この記事はいち情報科学生が今日の情報科学技術に対して、授業の応用として調査を行った記事である．
専門的な知識を要していないため、稚拙な文章になっているため、ご了承の上一読していただきたい。


## インターネットについて
インターネットは現在では、各種組織の公式 web サイト、検索エンジン、YouTube に代表
される動画共有サイト、Facebook と twitter に代表されるSNS、ブロックチェーン、Internet of Things(IoT)、Artificial Intelligence(AI)などの新たなサービスが次々と展開されている状況下にあり、そのネットワークの規模は継続的に大きなものになってきている[1]。

したがって、継続的にインターネット上のデータ転送量が増加している状況下にある。
そのような状況下において、データ送信における最適な経路選択を与える経路制御技術は、インターネット内でのトラフィック集中による輻輳回避のために、非常に大切なものである。
今回はその経路制御技術の概要と、その中の一つのルーティングプロトコルの概要と技術的課題を取り上げてみる。

# 経路制御技術の概要 
ルーティングとは IP の機能の一つであり、パケットを転送するための適切な経路を選択
する動作のことである。

送信端末がどのネットワークに属しているのか、宛先端末がどのネットワークに属しているのかを識別し、どの経路にパケットを送信するのかを選択することである。

経路選択は、宛先のネットワークアドレスとルーティングテーブルとを照合して行われる。
ルーティングテーブルとは、宛先ネットワークアドレスや、その宛先へパケットを送信する自インターフェース、パケットの転送先アドレスなどが書かれた経路情報である。

ルーティングには同一ネットワーク上の端末に送信するダイレクトルーティングと、異なるネットワーク上の端末に送信するインダイレクトルーティングがある。
ダイレクトルーティングは送信する端末が生成したルーティングテーブルに従って、送信端末のインターフェースから宛先端末のインターフェースへ直接、転送処理を行う。
インダイレクトルーティングは、送信端末がルーティングテーブルに従って、パケットを、ネットワークとネットワークとを結びつけたルータであるデフォルトゲートウェイへ転送する。その際、デフォルトゲートウェイでは、送信端末から受信したパケットを、自分が所持しているルーティングテーブルに従って転送処理を行う。

上記のように、ルーティングは端末やルータに設定したルーティングに基づいて行われる。ルータにルーティングテーブルを設定する方法には、スタティックルーティングと、ダイナミックルーティングがある。

スタティックルーティングは、管理者が手動で経路表を設定する。長所は、経路が一定で、安定したルーティングだということ。しかし、ネットワーク規模が大きくなり複雑化すると設定作業が大変になる。また、ネットワーク構成が変更になると、再設定する場合もあり、さらに煩雑になる可能性もある。

ダイナミックルーティングは、ルーティングプロトコルによって適切なルーティングのテーブルを自動的に作成、更新、削除する。長所として、障害が発生した際には、自動的に障害を回避したルーティングを行うことができる。しかし、ルーティングプロトコルによるルータ間の情報交換により、ネットワーク上にトラフィックが生じて、トラフィック集中の要因の一つになる可能性がある。

# RIP の技術概要・技術的課題 
RIP はルーティングプロトコルの中でも、最も歴史のあるものの一つである。古いルー
ティングプロトコルではあるが、今でも継続的に使われている。

RIP は、経由するルータの台数に応じて最短の経路を決める、ディスタンスべクタアルゴリズムを採用している。ディスタンスべクタとは、距離と方向に基づいて宛先ネットワークへの最適ルートを決定するルーティングアルゴリズムである。
ここでいう距離というのは、ルータを経由する数、つまりホップ数をあらわしており、このホップ数の事をメトリックという。また、方向というのはどのインターフェースから出力するかをあらわしている。


このアルゴリズムは、隣接ルータどうしでルーティング情報を交換することで、ルーティングテーブルを作成していく。図 1 に例を示す、たとえば、ルータ A はルータ B にメトリックは 1 という情報を送信する。ルータ B も同じくルータ A にメトリックは 1 という情報を送信する。次にルータ B は自分のルーティングテーブルにある情報を参照し、ルータA まではメトリック 2、ルータ B まではメトリック 1 という情報をルータ C に送信する。ルータ C はルータ B にメトリックは 1 という情報を送信する。これで、ルータ C はルータが 2 台離れたルータ A の情報を得てルーティングテーブルを更新できる。同じような順序でルータ A もルータ C の情報を得る。といったように、自分が持つ情報を隣のノードと交換し合い、ルーティングテーブルを更新していく。そして、情報を更新しているなかで、それぞれのルータとのメトリックが小さい方を自分のルーティングテーブルに選択し、その経路の次のルータをネクストホップとして更新する。これが RIP のルーティングの基本である

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690136/dde514ef-a1a8-f2ea-d394-6f17e5db9197.png)
図 1：RIP のルーティングテーブルの作成例


他にも RIP には以下のような様々な仕様がある。
・RIP ではメトリックは最大 15 まで
・30 秒おきにルーティングテーブルのアップデートを行う
・隣接ルータから 180 秒間メッセージが受信できなければそのルータ、もしくはそのルー
タまでのリンクがダウンしたとみなす


このような仕様によるデメリットも存在する。まず、RIP ではメトリックは最大 15 まで
のため、メトリックが 16 以上のネットワークとは通信ができない。そのため、RIP は大
規模なネットワークには不向きである。また、30 秒おきにルーティングテーブルのアップ
デートを行うため、情報交換によるトラフィックが回線を圧迫する要因にもなり得る。そ
して、RIP では経路情報の収束が遅く、ネットワークの障害が起きた際にルーティングル
ープが発生し、無駄なトラフィックが流れてしまう。これらの技術的課題は今後の技術的進歩とともに解決されるであろう．


以上がRIPの技術概要と技術的課題である．


# 参考文献
[1]https://core.ac.uk/download/pdf/156904539.pdf
Django テストユーザーで投稿をしたら1対1の作りになっていた話

Pycharmの予測変換にやられた話

~~~Python:models.py
class Diary(models.Model):
    user = models.OneToOneField(CustomUser,verbose_name='ユーザー', on_delete=models.PROTECT)
    title = models.CharField(verbose_name='タイトル', max_length=40)
    content = models.TextField(verbose_name='本文',blank=True,null=True)
    photo1 = models.ImageField(verbose_name='写真1',blank=True,null=True)
    photo2 = models.ImageField(verbose_name='写真2',blank=True,null=True)
    photo3 = models.ImageField(verbose_name='写真3',blank=True,null=True)
    created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name='更新日時',auto_now=True)
~~~

userがOneToOneFieldで1対1の関係になっていたので、ユーザーで複数投稿をしたらエラーが発生していた

~~~Python:models.py
class Diary(models.Model):
    user = models.ForeignKey(CustomUser,verbose_name='ユーザー', on_delete=models.PROTECT)
    title = models.CharField(verbose_name='タイトル', max_length=40)
    content = models.TextField(verbose_name='本文',blank=True,null=True)
    photo1 = models.ImageField(verbose_name='写真1',blank=True,null=True)
    photo2 = models.ImageField(verbose_name='写真2',blank=True,null=True)
    photo3 = models.ImageField(verbose_name='写真3',blank=True,null=True)
    created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name='更新日時',auto_now=True)
~~~

モデルを変更しているので、再度マイグレーションを実施して完了
githubでリポジトリ作成後初めてのコミットまでの手順をいつも忘れるので備忘録として…

1. リポジトリ作成
1. コミットしたいディレクトリに移動

```.terminal
git init
```

```.terminal
git remote add origin https://github.com/アカウント名/リポジトリ名
```

```.terminal
git add
```

```.terminal
 git commit -m "first commit"
```

```.terminal
git push -u origin main
```
怒られたら
```.terminal
git push -u origin master
```
上記を試してみる
【Next.js】プリフェッチの際にmiddlewareを実行しないようにする方法

`middleware.js`に以下のように記述することでプリフェッチの場合にはmiddlewareを実行しないようにできます。

```js
export const config = {
  matcher: [
    {
      source: '/:path*',
      missing: [
        { type: 'header', key: 'next-router-prefetch' },
        { type: 'header', key: 'purpose', value: 'prefetch' },
      ],
    },
  ],
}
```
【Unity】スクリプトからオブジェクトのマテリアル数を増やす方法

# 前置き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676764/030a6af0-47e1-3391-8e71-14803776fd54.png)
1と2のマテリアルを融合させて3にしたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676764/0a8f8ecc-bdfe-a42b-d765-4b8b5ddc7d63.png)
インスペクタからならMaterials項目を増やせば対応できるが
コードから動的に増減させたい。

# 結論
```
    public void Add(Material newMaterial)
    {
        // Rendererからマテリアルの配列を取得
        List<Material> materials = new List<Material>(GetComponent<Renderer>().materials);

        // 普通にマテリアルを追加
        materials.Add(newMaterial);

        // 上書き
        GetComponent<Renderer>().materials = materials.ToArray();
    }
```
materialsは固定長の配列型なのでListに変換してから増やす。
Listで管理してるだけなので、減らしたり順番を変えたりも簡単にできる。

# おまけ
置き換えるだけならば以下。
```
    public void Replace(int index, Material newMaterial)
    {
        // ↓エラーにはならないが、動作しない↓
        // GetComponent<Renderer>().materials[index] = newMaterial;

        //配列を取得
        var materials = GetComponent<Renderer>().materials;

        //置き換える
        materials[index] = newMaterial;

        //上書き
        GetComponent<Renderer>().materials = materials;
    }
```
Djangoの仮想環境立ち上げまで

### Djangoを学習したので忘れないようにメモ
1. デスクトップに作業用フォルダを作成
1. cdで作業用フォルダに移動
1. 仮想環境を作成 `python –m venv Sample`
1. コマンドを実行し、venv環境が起動 `.\DjangoSample\Scripts\activate`
1. Djangoをインストール `pip install django`
1. Sampleプロジェクトを作成 `django-admin startproject Sample`
1. cdでSampleに移動し、venv環境が起動している状態で `python manage.py runserver`
git pushを取り消す方法・力技(個人開発&リポジトリ作りたての場合)

## 注意
Qiita初投稿です。私は今日gitとgithubを触り始めたレクリエーションプログラマーです。
仕事でプログラミングをしているわけでもなければ、学生時代に学んだこともありません。

また、私の環境はWindows10で、今回の作業はVScodeを使って行いました。

## 起こった問題
git pushしたリポジトリの最初のコミットに
APIキーやらメールアドレスやら非公開の情報が含まれていました。

## やりたいこと
非公開の情報を含んだコミット履歴を消したい。
このpushをなかったことにしたい！

## やったこと
個人開発でしかやっちゃいけない？事かもしれませんが、力技で解決しました。
2回目のコミットを「1回目のコミットとして」pushしました。

具体的には以下のようにしました。
* ローカルのリポジトリを削除する
* 再度ローカルのリポジトリを作成して、初回のコミットを行う
* ローカルのGitHubのリポジトリに紐付け、pushする

順に解説します。

### ローカルのリポジトリを削除する
ローカルのプロジェクトディレクトリに存在していた.gitフォルダを削除しました。これでローカルのリポジトリは削除完了とのこと。簡単。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713320/17aef1ea-94e5-b8c2-b419-4e9bd72bda30.png)

### 再度ローカルのリポジトリを作成して、初回のコミットを行う
これも簡単。さきほど消した.gitが入っていたディレクトリで```git init```、```git add <ファイル名>```、```git commit -m "コメント"```するだけ。

### ローカルのGitHubのリポジトリに紐付け、pushする
```git remote add origin <GitHubリポジトリのURL>```でローカルリポジトリとGitHubのリポジトリを紐づけ。

それからpushするんだけど、普通に```git push origin <ブランチ名>```するとエラーが出る。これは簡単に言えばローカルに無いデータを含むクラウドのリポジトリを、ローカルのもので上書きしちゃうよ！ってことかと思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713320/86e1ff41-cf0e-cdb7-bb9c-5b369af745de.png)

でも個人開発のしかも初回コミットしたものをなかったことにしたい私は気にしない。```-f```コマンドで強制的に上書きしました。

```git push -f origin <ブランチ名>```で無事、目的が叶えられました。

## 感想
私と同じ、GitHub触りたてで右も左もわからない方の助けになれば幸いです。

今までよくわかんなくて敬遠していたGitとGitHubに触ってみてなんとなくわかった。
ただ、趣味の個人開発でどこまで有用な(生産的な)使い方できるかはわからないし全然自信ない。。。
【Linuxコマンド】知っててよかった。。Linuxコマンド6選！！

## 対象者
・ Linuxコマンド学びたてのエンジニアの方
・ ソフトウェアエンジニアなのにリリースなど任されてしまって、何のコマンドから知っていけばええねん！って思っているエンジニアの方

## 自己紹介
・ 社会人3年目のソフトウェアエンジニア。
・ 業務ではJava,SpringFrameWork,JavaScriptあたりを触っている。
・ 最近リリース準備作業を任されることになって、Teraterm使ってLinuxコマンド使い始めた。
・ お金ないので、副業が、、したい、、！！

## 紹介するコマンド一覧とよく使う順にランキング 💻
１ cd 
２ tail
３ cp
４ chmod
４ chown
6 mkdir

## 1位：cd 
ディレクトリを移動するためのコマンド
```
#　ルートディレクトリ配下のtmp/sasakitomopiに移動
cd /tmp/sasakitomopi

#　カレントディレクトリ配下のtmp/sasakitomopiに移動
cd ./tmp/sasakitomopi
```
## 2位:tail
ログを管理するためのコマンド
```
# ログを常に監視するためのコマンド。ログが出力されるたびにコンソールにログが出る
tail -f server.log

# ログの末尾◯桁を表示するためのコマンド。例）　末尾１０桁のログを出力する
tail -n 10 server.log
```

## 3位:cp
ファイルのコピーをしてくれるコマンド
```
# server.logファイルをカレントディレクトリにコピーする
# pオプションは、所有者、パーミッション、タイムスタンプを保持する
cp -p /server/log/server.log ./
```

## 同率4位:chmod
ファイル、ディレクトリの権限をかえるためのコマンド。
以下の権限保有グループがあります。
①ファイルの所有者
②ファイルの所有グループ
③その他に対する権限

以下の権限があり、それぞれ以下で表されます。
| モード(数字) | モード(アルファベット) | 権限 |
| --- | --- | --- |
| 4 | r | 読み取り |
| 2 | w | 書き込み |
| 1 | x | 実行 |

ファイル所有者に「全権限」
ファイル所有グループ、その他権限に「読み取り」、「実行」権限を与える場合は以下になります。
```
chmod 755 server.log
```

## 同率4位:chown
ディレクトリ、ファイルの権限を変更するためのコマンド。
例）ディレクトリをrootにするためのコマンド
```
chown root:root /server/log/server.log
```

## 6位:mkdir
ディレクトリを作成するためのコマンド。
pオプションを利用すると、対象のディレクトリがない場合にディレクトリを作成する
```
# /server/logがない場合にディレクトリを作成する
mkdir -p /server/log
```

## まとめ
lnコマンドやviコマンドなど、他にもたくさん学んだコマンドを共有したいのですが、力尽きてしまったので、また別途共有させてください！！
紹介したコマンドが皆様のお役に立てることを祈っております。。🙏
<作成中>キャパシティプランニング (capacity plannning/キャパプラ)の手法についての勉強

キャパシティプランニング (capacity plannning/キャパプラ)
利用者数や利用頻度、処理の内容、扱うデータの種類や容量、必要とされる信頼性、予算などからシステムのハードウェアやネットワークの構成を検討し、機材の種類や性能、台数、配置などの具体的な計画を作成する。

キャパシティプランニングの実施手順は 一般的に以下のように行います。
現行システムを分析し、現処理能力の把握
将来的な拡大計画、それに伴う、利用者数の増加などを分析検討
現システム能力の限界時期を予測
新システム構成で実現すべき性能要件から、必要なハードウェア増設を導き検討


③ 稼働状況データ，磁気ディスク使用量，トランザクション数などの基礎数値を把握する。
④ 端末増設計画，利用者数の増加などを検討する。
② 応答時間，システム資源の要求量などの増加から，システム能力の限界時期を検討する。
① CPU増設，磁気ディスク増設，メモリ増設などを検討する。

長期的キャパシティプランニング
「長期的キャパシティプランニング」は今後一年以上の長期間に自社商品の需要を満たし続ける事を目的とします。ＩＴ投資や他の設備投資、また必要な人材の確保、大きな業務改善プロジェクトもこの分類に入ります。

長期計画は不確実性も増えますし、失敗した時のダメージが大きいので予測も決断も難しくなります。その成功の確率を上げるために行うのが「長期的キャパシティプランニング」なのです。

短期的キャパシティプランニング
それに対して「短期的キャパシティプランニング」は必要な人員や機械の準備が出来ているか、必要在庫がちゃんとあるかなどの、より日常に関する業務を対象に使われます。

今回の質問者さんの「機械加工セルにおける人と機械のキャパシティプランニング」は「短期的キャパシティプランニング」になります。

キャパシティ・プランニングの作業手順は，3つのフェーズに分かれる。
(1)構築対象のシステムが実行する処理の種類や量である「ワークロード（負荷）情報」の収集と，それを基にした性能要件の決定，
(2)性能要件からリソースのスペックを見積もる「サイジング」，
(3)サイジング結果を評価して精度を高めていく「評価・チューニング」である。
エクセルに書かれた項番をずらすマクロ　メモ

Sub ShiftNumbersWithInput()
    Dim ws As Worksheet
    Dim rng As Range
    Dim cell As Range
    Dim startNum As Long
    Dim str As String, num As Long
    Dim parts() As String
    Dim inputVal As String
    
    ' ユーザーに番号の入力を求める
    inputVal = InputBox("どの番号からずらしますか？", "番号指定", "3")
    If inputVal = "" Then Exit Sub ' キャンセルされた場合は終了
    If Not IsNumeric(inputVal) Then
        MsgBox "数値を入力してください。", vbExclamation
        Exit Sub
    End If
    
    startNum = Val(inputVal)
    
    ' 対象となるワークシートと列を設定
    Set ws = ThisWorkbook.Sheets("Sheet1") ' シート名を適宜変更してください
    Set rng = ws.Range("A1:A" & ws.Cells(ws.Rows.Count, "A").End(xlUp).Row)
    
    For Each cell In rng
        str = cell.Value
        ' 空白でないセルのみ処理
        If str <> "" Then
            ' ピリオドで区切られた数字を見つける
            parts = Split(str, ".")
            If UBound(parts) >= 0 Then
                If IsNumeric(parts(0)) Then
                    num = Val(parts(0))
                    ' 指定された番号以上の場合、1増加
                    If num >= startNum Then
                        num = num + 1
                        parts(0) = CStr(num)
                        ' 更新された番号で文字列を再構築
                        cell.Value = Join(parts, ".")
                    End If
                End If
            End If
        End If
    Next cell
    
    MsgBox "処理が完了しました。", vbInformation
End Sub
VBA の UI Automation で部分一致検索する


`IUIAutomation::CreatePropertyConditionEx` で第3引数に `PropertyConditionFlags_MatchSubstring` を指定することで部分一致条件での検索が実施されます。

https://learn.microsoft.com/ja-jp/windows/win32/api/uiautomationclient/ne-uiautomationclient-propertyconditionflags

```visualbasic
Sub Excelをタイトルに含むChromeブラウザを取得する()
  Dim uia As CUIAutomation8: Set uia = New CUIAutomation8
  Dim root As IUIAutomationElement: Set root = uia.GetRootElement
  ' Chromeのウィンドウを探す
  Dim cnd1 As IUIAutomationCondition: Set cnd1 = uia.CreatePropertyCondition(UIA_ClassNamePropertyId, 
  "Chrome_WidgetWin_1")
  ' CreatePropertyConditionExの第3引数にPropertyConditionFlags_MatchSubstringを指定すると部分一致で検索できる
  Dim cnd2 As IUIAutomationCondition: Set cnd2 = uia.CreatePropertyConditionEx(UIA_NamePropertyId, "Excel", PropertyConditionFlags_MatchSubstring)
  Dim cnd As IUIAutomationAndCondition: Set cnd = uia.CreateAndCondition(cnd1, cnd2)
  Dim ary As IUIAutomationElementArray: Set ary = root.FindAll(TreeScope_Children, cnd)

  Dim i As Long, elm As IUIAutomationElement
  For i = 0 To ary.Length - 1
    Set elm = ary.GetElement(i)
    ' ウィンドウのクラス名と名前を出力
    Debug.Print elm.CurrentClassName, elm.CurrentName
  Next
End Sub
```
REST APIについて理解する

## はじめに
REST APIで学んだ内容について整理していきます。

## RESTとは
まずREST〇〇の言葉が多く、混乱する原因にもなるので１つずつ整理していきます。

**REST**  
**RE**presentational **S**tate **T**ransferの略称。
Webサービス設計思想(ルール)の1つで、インターネット上で情報をやり取りする際のルールを定義しています。

**REST原則**  
RESTはインターネット上で情報をやり取りする際のルールと説明しましたが、それは6つのREST原則によって成り立ちます。

1. **クライアントサーバー**
システムをクライアントとサーバーの2つに分ける事を推奨する考え方です。
クライアントとサーバーが独立しているため、サーバー側の変更がクライアント側に直接影響を与えることが少なくなります。
　　
2. **階層化システム**
システムを複数の層に分け、それぞれが独立した機能を持つことを推奨する考え方です。
一部の層を更新または拡張しても、他の層に影響を最小限に抑えることができます。　　
　　
3. **コードオンデマンド**
サーバー側のコードをクライアント側にダウンロードして、クライアントアプリケーションの機能拡張を推奨する考え方です。  
例えばWebページに埋め込まれたJavaScriptコードはサーバーからダウンロードされ、クライアント側で実行されます。
これによりアプリケーションの振る舞いを動的に変更できます。　　
　　
4. **統一インターフェース**
インターフェースとは何かと何かを繋ぐものです。
この原則の中で更に4つに分岐しています。  
  
    1. リソースの識別
    URIでサーバーに保存されたリソース(データ)を一意に識別します。
    例えば特定のポケモンを識別するURIは`https://example.com/pokemons/123`です。  
    &nbsp;
    2. リソースの表現  
    クライアントとサーバーでやり取りされるデータを標準化されたフォーマットで表します。httpリクエストやレスポンスのボディに含まれるXMLやJSON形式のデータがフォーマットになります。  
    &nbsp;
    3. 自己記述メッセージ
    httpリクエストやhttpレスポンスに相手(リクエストならサーバー)が解釈するために必要な情報を含めます。
    httpリクエストにはGETやPOSTなどのhttpメソッドの情報が入っていますし、レスポンスにはステータスコードが入ります。  
    &nbsp;
    4. HATEOAS
    httpレスポンスに現在の状態を踏まえて関連するハイパーリンクを含めます。
    例えばAmazonで商品検索するリクエストに対してのレスポンスには、詳細ページへのリンク、購入ページへのリンクが含まれます。
&nbsp;
5. **ステートレス**
サーバーがクライアントの状態を保持しない事を推奨する考え方です。  
各リクエストは必要なすべての情報を含む必要がありますが、シンプルな設計が可能になります。
以下の記事が分かりやすかったです。
[https://yohei-y.blogspot.com/2007/10/blog-post.html]  
&nbsp;
6. **キャッシュ制御**
クライアント側が一度受け取ったレスポンスデータを一定期間保持する事を推奨する考え方です。同じリクエストが再度行われたときにサーバーに問い合わせることなくそのデータを再利用することができます。

**RESTfull**  
REST原則を守っている事を指します。

**REST API(RESTfullなAPI)**
REST原則に従って作成(設計)されたAPIの事です。

## REST APIで設計してみる
ここではmoviesをリソースとしてCRUD操作のURI、HTTPメソッドを定義してみました。

|URI|HTTP method|
|---|-----------|
|/movies|POST|
|/movies|GET|
|/movies/{id}|GET|
|/movies/{id}|PUT|
|/movies/{id}|DELETE|

次の観点からこの設計はREST APIであると言えます。

1. リソースの識別
URIでサーバーに保存されたリソース(movies)を一意に識別しています。  
  
2. 統一インターフェース
URIへの操作(httpメソッド)を統一しています。  

3. ステートレス
PUTやDELETEでは`{id}`でどのmoviesリソースが対象かを指定しています(必要な情報を含んでいる)。
Figmaの開発者モードが有料になってた。。。


最近Figmaを使ったらウィンドウにdev modeを促すメッセージが出てた。

![スクリーンショット 2024-02-14 23.04.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587166/2ea2d3ec-79ea-7376-b43c-a0cbc60e5293.png)

よく見ると、CSSとかコピーできなくなってる！

https://www.figma.com/ja/blog/introducing-dev-mode/

なんと、24年からいままで無料だったdev modeが有料になってた。

dev modeはfigmaで作ったデザインのCSSとか余白の確認とかがすごく便利にできる機能だった。

![スクリーンショット 2024-02-14 23.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587166/5b08808e-7df3-1954-f767-b9d2bcbdfe19.png)

むしろいままで無料で使わせていただきありがとうございました。
これから無課金プロジェクトではコツコツCSS書いていこう。
「世界一流エンジニアの思考法」を読んで

お久しぶりです！なおぽんです🐹
今回も話題になっている図書を読み終えたので軽くまとめてみました。

## 読んだ本
「[世界一流エンジニアの思考法](https://amzn.asia/d/1T8CeGt)」

## 本書の内容
分野別にすると、以下の内容が著者の経験談をもとに書かれてました。
- 世界一流エンジニアの思考
- 世界一流エンジニアの行動
- 世界一流エンジニアのコミュニケーション
- 世界一流エンジニアの生活
- AI成長を受けての今後すべきこと

## まとめ
- 理解に時間をかけ、思考は理解してから
    - 知識がない状態でエラーを解決しようとしても時間がかかるだけになってしまうため、調べてから挑もう
- 複数のことをしようとせず、1つのことに集中する
    - 大切なことだけに集中でいるようになると、自ずと要らないものがわかるようになり、より効率的に仕事を回しやすくなる
- 疑問や不安が出たらオフラインでの相談や会話を大切にする
    - 明らかに聞いた方が効率いい
    - 相手とよりお話がしやすくなる
- 定時で上がり、私生活を充実させる
    - 勉強しよう
- 否定でなく、褒めて伸ばそう！
    - 日本で伸びないのは、批判が多いから
    - 人生楽しい方がいいでしょ！

## 感想
エンジニアでなくても読みやすい自己啓発本でした。
お仕事をしながらでも実践しやすいことばかりでしたので、詳しく知りたい方はお手に取ってみてくださいね！
精神が安定せず、頭の中で混乱している中で書いている記事ですが、誰かの役に立てたら嬉しいです！
お読みになっていただきありがとうございました！
Huskeyがwebstormで動かいないとき @yukilulu0229

参考: @Naughty1029 

引用元
https://qiita.com/Naughty1029/items/789e9e0226fd50f151cd

## ここをそのままやったらできた

```
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged //編集

```
LINEとAWSを使って家計簿を作ってみた

# ことのはじめ
```
家計簿を家のPCでpython, postgresを使ってやってたけど、いちいちPC立ち上げるのめんどい。
↓
LINEってよく使うよなぁ…
↓
LINEで家計簿まとめんべ！！
```

といった流れでLINEでの家計簿ツールを作ることにしました。

# 記事概要
[**1. 簡単な動作説明**](#1-簡単な動作説明)
[**1.1. 実施間隔：逐次**](#11-実施間隔：逐次)
[**1.2. 実施間隔：1週間/回**](#12-実施間隔1週間回)
[**1.3. 実施間隔：1ヶ月/回**](#13-実施間隔1ヶ月回)
[**2. 作成項目**](#2-作成項目)
[**2.1. LINEボット作成**](#21-lineボット作成)
[**2.2. LINEヤフー for Business開設**](#22-lineヤフー-for-business開設)
[**2.3. AWS側作成**](#23-aws側作成)
[**3. 感想&今後の対処**](#3-感想今後の対処)

## 1. 簡単な動作説明
### 1.1. 実施間隔：逐次
- LINEで送った情報をS3に格納
- 処理フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/9638030b-cc04-57cb-3ad7-ec41cdda075e.png)

- LINEから以下の形式で情報を送る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/ef0130fd-4009-3dbd-8de9-b7a56be344a0.png)

- ※振り分け用の記号は忘れたら「help」と打てば設定している記号情報を返却してくれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/89c5fdb1-c61f-5eaf-e93d-b69dda9b6ef7.png)
        
- 成功したらS3に保存したファイル名を返却。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/29bdd3c3-9559-b458-44b9-5e115e22785f.png)

- 記述方法に不備があった場合、どこでエラーになったかを返却。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/83c55c2a-877e-c08a-6c7e-79dc1554f6f3.png)

### 1.2. 実施間隔：1週間/回
- S3からファイルを読み込んでRDS格納
- 処理フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/4be5b9da-502c-a140-a36d-9e64fc8ca279.png)
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/8947cc2c-0f14-88c1-6db4-7df2fe5bf67d.png)

### 1.3. 実施間隔：1ヶ月/回
- 処理フロー
- `1ヶ月/回` 先月の情報をまとめて累計情報を格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/a7048202-55fa-b381-c1c3-67415556cd24.png)
- 実施結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/6e293af6-de9f-a7c2-4ee3-d59a66339953.png)

## 2. 作成項目
### 2.1. LINEボット作成
- LINE Notifyでログイン
- 連携中サービストークン発行
    - 発行したトークンのIDをメモしておく
### 2.2. LINEヤフー for Business開設
- 作成結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/d97e871f-588b-6a72-7758-de79c5268931.png)

### 2.3. AWS側作成
- Lambda
    - 今まで利用していたpythonを移植
    - LINE Notifyとの通信もLambdaで行えるようにした
- StepFunction
    - 以下の構成の処理をそれぞれ実行できるように作成
        - 逐次処理
        - 1週間/回
        - 1ヶ月/回
- RDS
    - 家計簿情報格納
- EventBridge(旧 CloudWatchEvents)
    - StepFunctionを上記の時間で動くように作成

## 3. 感想&今後の対処
- 月ごとの請求額が高い
    - 目標としては月100円以下にしたい（個人利用だし…）
    - 個人利用で月4$は高い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153466/7f3a3d97-bfe9-204e-39d5-8e2bca1add26.png)

- 使用割合とかもわかるように
- レシートを写真で撮影→合計値・購入物で自動割り振り
    - 単語から何を買ったかとか分かるものを作れば…
    - 例
        - ピース → 煙草
        - 伊勢うどん → 食費
SSHのrsaとed25519ってなんや


# rsaとed25519ってなんや
SSH接続に使う鍵を作る時に「rsa」と「ed25519」というワードが出てきたので調べた。

# いつ使った？（出てきた？）
SSHで鍵をつくるとき-tのあとに「ed25519」とか「rsa」という指定をすると書かれていた。
```
ssh-keygen -t ed25519 -C "your_email@example.com"
```
```
ssh-keygen -t rsa -b 4096
```

ちなみに出てきたオプションはこちら。
-t : 方式 => 作成する鍵の暗号化形式
-b : ビット数 => 作成する鍵のビット数
-C : コメント

# わかった
rsaとed25519はSSH鍵を作る時の方式のこと。
rsaは昔からスタンダードで使われてきた方式だけど、最近はed25519を使うことが多いらしい。
rsaはよりed25519のほうが高速かつセキュアらしい！

https://tech.asahi.co.jp/posts/20231005-bbf6

ちなみに方式にはrsaとed25519の他にも「dsa」「ecdsa」っていうのがあるらしい。
ちょっと難しすぎるので今回はここまで。
Mockkでio.mockk.MockKException: no answer foundのときスタティックメソッドかをみる

# はじめに

mockkの使い方で困ったことがあり、頻繁に遭遇しそうなのでまとめます

# 問題

```kotlin:gateway_test.kt
        @Test
        @DisplayName("サンプルテスト")
        fun testSample() {

            val targetIndex: IndexName = mockk()
            val companies: CompanyDocument = mockk()
            val jsonCompanies: List<JSONCompany> = mockk()
            val documents: Documents = mockk()

            every { companies.toJSON() } returns jsonCompanies
            every { jsonCompanies.toDocuments(targetIndex) } returns documents

            target.indexing(targetIndex, companies)
            
            verify { companyEs.index(documents) }
        }
```

```kotlin:Gateway.kt

    override fun indexing(targetIndex: IndexName, companyDocument: CompanyDocuments) {
        companyDocument.toJSON().toDocuments(targetIndex).let(companyEs::index)
    }
```

```kotlin:Extension.kt
fun CompanyDocument.toJSON(): JSONCompany = JSONCompany(
    name: name.name
)

fun List<JSONCompany>.toDocuments(indexName: IndexName): Documents {
    return Documents(
        indexName.value,
        this
    )
}
```

このようなテストを実装して実行したところ以下のエラーが出ました

```
22:45:45.389 [main] WARN io.mockk.impl.recording.states.StubbingAwaitingAnswerState -- Failed to set backing field (skipping)
java.lang.IllegalArgumentException: Can not set final java.lang.String field jp.sample.IndexName.value to jp.sample.entity.Documents
	at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:228)
	at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:232)
	at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccessorImpl.set(MethodHandleObjectFieldAccessorImpl.java:115)

 
 ```

 # 解決方法

 インスタンスに対してのモックであればこれでよいのですが、今回はクラスのスタティックメソッドに対してのモックなので以下を追加する必要がありました

 ```kotlin:gateway_test.kt
        @Test
        @DisplayName("サンプルテスト")
        fun testSample() {

            mockkStatic("jp.sample.extension.ExtensionsKt")
            val targetIndex: IndexName = mockk()
            val companies: CompanyDocument = mockk()
            val jsonCompanies: List<JSONCompany> = mockk()
            val documents: Documents = mockk()

            every { companies.toJSON() } returns jsonCompanies
            every { jsonCompanies.toDocuments(targetIndex) } returns documents

            target.indexing(targetIndex, companies)
            
            verify { companyEs.index(documents) }
        }
```

# おわりに

スタティックのときは注意ということだけ覚えておきたいです