OmniAICreator/Qiita-1.07M huggingface dataset:
Jetpack Compose の Linebreak が反映されない

## 概要
Jetpack Compose の LineBreak を設定すると、長いテキストで改行を挿入するタイミングを調整することができます。

以下にコード付きのドキュメントがあります。
https://developer.android.com/reference/kotlin/androidx/compose/ui/text/style/LineBreak

ところが以下のようなコードを実行してみたところ

```kotlin
@Composable
@Preview
fun TestView() {
    Text(
        text = "こちらはいい感じのところで改行して欲しい文章です。よろしくお願いします。",
        style = TextStyle(lineBreak = LineBreak.Heading),
        fontSize = 22.sp,
    )
}
```

Preview でいい感じに改行表示されているものの、実機(Android 11)では改行位置が調整されていない形になってしまいました。

| Preview | 実機(Android 11) |
|:-:|:-:|
| ![TestApplication2_–_MainActivity_kt__TestApplication2_app_main_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7869/4ac31cd3-fbc8-e9f9-d403-8771c6624c34.png)  | ![TestApplication2_–_MainActivity_kt__TestApplication2_app_main_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7869/5ec4c9a0-b41a-3893-a8ec-21741ec87f73.png)  |
|   |   |

この原因ついて調査してみました。

## 原因
StaticLayoutFactory23 に以下のような実装があります。

```java
private class StaticLayoutFactory23 : StaticLayoutFactoryImpl {

    @DoNotInline
    override fun create(params: StaticLayoutParams): StaticLayout {
        return Builder.obtain(params.text, params.start, params.end, params.paint, params.width)
            .apply {
                setTextDirection(params.textDir)
                setAlignment(params.alignment)
                setMaxLines(params.maxLines)
                setEllipsize(params.ellipsize)
                setEllipsizedWidth(params.ellipsizedWidth)
                setLineSpacing(params.lineSpacingExtra, params.lineSpacingMultiplier)
                setIncludePad(params.includePadding)
                setBreakStrategy(params.breakStrategy)
                setHyphenationFrequency(params.hyphenationFrequency)
                setIndents(params.leftIndents, params.rightIndents)
                if (Build.VERSION.SDK_INT >= 26) {
                    StaticLayoutFactory26.setJustificationMode(this, params.justificationMode)
                }
                if (Build.VERSION.SDK_INT >= 28) {
                    StaticLayoutFactory28.setUseLineSpacingFromFallbacks(
                        this,
                        params.useFallbackLineSpacing
                    )
                }
                if (Build.VERSION.SDK_INT >= 33) {
                    StaticLayoutFactory33.setLineBreakConfig(
                        this,
                        params.lineBreakStyle,
                        params.lineBreakWordStyle
                    )
                }
            }.build()
    ....略
```

上記のコードの setLineBreakConfig は Build.VERSION.SDK_INT >= 33、つまり Android 13 以上でないと実行されません。これが原因だったようです。

過去バージョンのためのバックポート実装が欲しいところですが、compose-bom 2024.02.02 の時点では特にないようでした。
CloudWatch logsでダブルクオートでフィルタする方法

# CloudWatch logsで`"`の文字でフィルタかけたい

前々から気になっていたので本気出して調べてみた

フィルターバーに `"` が入っていると、とにかくエラーになる
`\"` とかエスケープしてみてもダメ
正規表現で `%"%` とか `%\"%` とかしてもダメ
以下のエラーから逃れられない

```
There was an error filtering log events.
Invalid character(s) in term '"'
```

# 違う文字で表現すればいける

ということで結論

**正規表現で文字コードで指定すれば `"` をフィルタできる**

```
%\x22%
```

`\x22` => `"`

他にもエラーになる文字があったらこの方法で回避できるはず
PostgreSQL 日本語を別名参照する際の注意

### はじめに
業務でPostgresを使用する際、別名で日本語を使用していました。
別名で日本語を使用するにあたって、特定の別名を参照する際にエラーが発生し、解決方法を調べるのに時間がかかりました...。
同様の問題に直面する方もおられるかもしれないので、解決策を残しておこうと思います！

### エラー発生する場合としない場合の違い

#### エラー起きない場合

```sample1.sql
select
    main.サンプル as "サンプル"
from
    (
        select
            sample as "サンプル"
        from
            table 
    ) main
```

"全角日本語"だけの場合、エラーは発生せずSQLを実行することができました。

また、"半角英字(小文字)"＋"全角日本語"の場合もエラーは発生しませんでした。

```sample2.sql
select
    main.サンプル as "abcサンプル"
from
    (
        select
            sample as "abcサンプル"
        from
            table 
    ) main
```


#### エラー起きた場合

```sample3.sql
select
    main.ABCサンプル as "ABCサンプル"
from
    (
        select
            sample as "ABCサンプル"
        from
            table 
    ) main
```

"半角英字(大文字)"＋"全角日本語"の組み合わせで参照した場合、エラーが発生しました。
ちなみに次のようなエラーです。


```
column tnegimesuryo.abcサンプル does not exist

```


### エラーに対する対応方法

エスケープ処理を実施します。
具体的には次の通りです。

```sample2.sql
select
    - main.ABCサンプル as "ABCサンプル"
    + main."ABCサンプル" as "ABCサンプル"
from
    (
        select
            sample as "ABCサンプル"
        from
            table 
    ) main
```

別名を参照する際、ダブルクォーテーションで囲むとエラーが発生しなくなります。
Node.js 利用可能なメモリ量

--max-old-space-size で設定する
```
NODE_OPTIONS="--max-old-space-size=999" 
```
デフォルト値、1400MB らしい
デフォルトで、積んでるメモリの50%までらしい。

--max-old-space-sizeを設定しても、積んでるメモリによって制限されるっぽい。
384MBのコンテナに--max-old-space-size=300を設定したが、231BMしか使えないぽかった。

```.ts
const v8 = require('v8');

const heapStatistics = v8.getHeapStatistics();
const totalHeapSizeMB = (heapStatistics.total_available_size / 1024 / 1024).toFixed(2);

console.log(`Total available heap size: ${totalHeapSizeMB} MB`)
```
[Google Calendar API(V3)] Javaでメインカレンダーのイベントを全て削除する

Google Calendar API V3(Java)を使用して、
Googleカレンダーでメインカレンダーのイベントを全て削除する
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Calendar API(V3)] JavaでCalendar APIを使う](https://qiita.com/doran/items/c735c7b05c0a2ed4bfdb)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[メインカレンダーのイベントを全て削除](#1-メインカレンダーのイベントを全て削除)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|

## 1. メインカレンダーのイベントを全て削除
Googleカレンダーのメインカレンダーのイベントを全て削除します。
メインカレンダー以外は削除できません。

### 1.1. スコープ
このAPIを実行するには、以下のスコープを指定してください。
```
CalendarScopes.CALENDAR
```
[⧉[Google Calendar API(V3)] JavaでCalendar APIを使う(2.2 Driveインスタンスを取得)](https://qiita.com/doran/items/c735c7b05c0a2ed4bfdb#22-calendarインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行
カレンダーIDを指定しますが、メインカレンダー以外を指定すると例外になります。
メインカレンダーは、カレンダーIDの他、「primary」という指定をすることもできます。

```java
public static void main(String[] args) throws Exception{
    Calendar calendar = getCalendar();

    Calendar.Calendars calendars = calendar.calendars();
    Calendar.Calendars.Clear clear = calendars.clear("カレンダーID");
    
    clear.execute();
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//www.googleapis.com/calendar/v3/calendars/{カレンダーID}/clear
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

#### 1.2.3. リクエストボディ
リクエストボディはありません。

### 1.3. レスポンスの内容
レスポンスはありません。
削除に失敗した場合、例外が発生します。

<br>
<br>
おしまい。。
OpenDKIMでList-Unsubscribe-Postヘッダーを署名対象ヘッダにする

RFC8058 に対応するためには、List-Unsubscribe ヘッダと List-Unsubscribe-Post ヘッダを署名対象ヘッダにしないといけないとのこと。
しかし、OpenDKIM のデフォルト設定ではList-Unsubscribe-Postが署名対象ヘッダにならないので、設定を行った。

# 設定
opendkim.conf に SignHeaders 設定を追加

```opendkim.conf
SignHeaders *,+List-Unsubscribe-Post,+List-Unsubscribe
```
（+List-Unsubscribe はなくても同じ。明示のために記述）

# 参考ヘルプ
http://www.opendkim.org/opendkim.conf.5.html

# 失敗設定
```opendkim.conf
SignHeaders List-Unsubscribe-Post,List-Unsubscribe
```

SignHeaders の上記参考ヘルプには下記のように「DKIM仕様の必須ヘッダは、省略していても含まれる」と書かれているが、実際に試すと 何かのヘッダが足らないらしく Gmail で**DKIM=FAIL** となる場合があったので、上記の * と + を使った記述で設定している。

>SignHeaders (dataset)
>Specifies the set of header fields that should be included when generating signatures. **If the list omits any header field that is mandated by the DKIM specification, those fields are implicitly added. By default, those fields listed in the DKIM specification as "SHOULD" be signed (RFC6376, Section 5.4) will be signed by the filter.** See the OmitHeaders configuration option for more information about the format and interpretation of this field.
Cloud Watch??

## 初めに
CloudWatchには、沢山の機能がありますね！
今日から何回かに分けてご紹介していきます。

## CloudWatchとは？
CloudWatchとは、<font color="green">**AWSリソースやアプリケーションの監視を行うサービスです。**</font>
メトリクスの取得やそれをもとにした、しきい値監視をします

:::note info
用語
「メトリクス」
→CPU使用率などのシステムパフォーマンスを示す時系列のデータポイント

「しきい値」
→境目となる値のこと
:::

## 代表的な機能
![スクリーンショット 2024-04-04 17.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/348c6d8c-540d-a161-8384-76c0b9705edd.png)

CloudWatchには、上記の様な機能があります。
詳細に関しては、明日以降、投稿していきます！

## 最後に
本日は、CloudWatchに関して書かせて頂きました。
勉強してみて、思った以上に機能がありました。そこからピックアップして
解説をさせて頂きます。

## 参考
[CloudWatchとは](https://qiita.com/miyuki_samitani/items/4799428602c7ad7001f3)
誕生日から、ある日付までの年齢計算 JavaScript

### ■ユーザーインターフェイス

![スクリーンショット (1121).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/74179097-1a3b-fd85-3cc6-cfe5d57ff983.png)


### ■ソースコード
```js main.js

    var birthYear = parseInt(document.getElementById('dead_birth_year').value);
    var birthMonth = parseInt(document.getElementById('dead_birth_month').value);
    var birthDay = parseInt(document.getElementById('dead_birth_day').value);

   
    var birthYearType = parseInt(document.getElementById('dead_birth_koyomi_type').value);
  
    if (birthYearType === -1) {
       
    } else if (birthYearType === 4) {
        birthYear += 2018;
    } else if (birthYearType === 3) { 
        birthYear += 1988;
    } else if (birthYearType === 2) {
        birthYear += 1925;
    } else if (birthYearType === 1) { 
        birthYear += 1911;
    } else if (birthYearType === 0) { 
        birthYear += 1868;
    }

    console.log("birthYear:::" + birthYear);

    
    var deadYear = parseInt(document.getElementById('dead_year').value);
    var deadMonth = parseInt(document.getElementById('dead_month').value);
    var deadDay = parseInt(document.getElementById('dead_day').value);

    
    var deadYearType = parseInt(document.getElementById('dead_koyomi_type').value);
    
    if (deadYearType === -1) { 
        
    } else if (deadYearType === 4) { 
        deadYear += 2018;
    } else if (deadYearType === 3) { 
        deadYear += 1988;
    } else if (deadYearType === 2) { 
        deadYear += 1925;
    } else if (deadYearType === 1) {
        deadYear += 1911;
    } else if (deadYearType === 0) {
        deadYear += 1868;
    }

    console.log("deadYear:::" + deadYear);
            
    
    var ageAtDeath = deadYear - birthYear;
    if ((deadMonth < birthMonth) || (deadMonth === birthMonth && deadDay < birthDay)) {
        ageAtDeath -= 1;
    }

    var resultTextBox = document.getElementById('Age_at_Death');

    if (!isNaN(ageAtDeath)) {
        var numericValue = Number(ageAtDeath);

        if (numericValue >= 0) {
            resultTextBox.value = numericValue;   
        }   
    } else {
   
    }
}
  
        document.getElementById('dead_birth_koyomi_type').addEventListener('change', calculateAge);
        document.getElementById('dead_birth_year').addEventListener('change', calculateAge);
        document.getElementById('dead_birth_month').addEventListener('change', calculateAge);
        document.getElementById('dead_birth_day').addEventListener('change', calculateAge);

        document.getElementById('dead_koyomi_type').addEventListener('change', calculateAge);
        document.getElementById('dead_year').addEventListener('change', calculateAge);
        document.getElementById('dead_month').addEventListener('change', calculateAge);
        document.getElementById('dead_day').addEventListener('change', calculateAge);

```
EC-CUBE4.2.3でプラグインインストールできない時はPHP7.4

# 基本環境
さくらレンタルサーバー　スタンダード
EC-CUBE 4.2.3
PHP 8.2.15

# 一部のプラグインがインストールエラー
管理画面インストールでエラー
Terminalコマンドインストールでエラー
キャッシュ削除してもダメ
EC-CUBE再インストールしてもダメ

さくらレンタルサーバー、EC-CUBE4.2.2では問題なくインストールできた
お名前RSサーバー、EC-CUBE4.2.3でも問題なくインストールできた

なぜ？

# エラーコードを眺める
こんなお怒りの言葉が。。。
```
 Problem 1
    - laminas/laminas-code 4.7.1 requires php >=7.4, <8.2 -> your php version (8.2.15; overridden via config.platform, same as actual) does not satisfy that requirement.
```
# PHPバージョンダウン
PHPをバージョンダウン
8.2.15 →　　7.4

プラグインインストールに成功！

最後にPHPバージョンを戻すのを忘れずに！

参考記事：
https://goweb.jp/stblog4/2019/09/172/
AWS CodeCommitのリポジトリに結果がありません

## 問題：本当はデータがあるはずなのに「結果がありません」
AWS CodeCommitのリポジトリにて、本当はデータがあるはずなのに「結果がありません」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/ef93dd62-4753-be39-8b02-bc308a807421.png)

## ！！！
国が「オハイオ」になってた（ばーかばーか！！！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/455ac96d-e188-f849-4826-1752ea05665a.png)
「東京」選択したら普通に表示されました。

間抜けな話ですが初心者（私）がAWS触ってるときよくある気がします。
Web APIについての基本

# WebAPIについて
WebAPIとはなんなのか、使い方など基本的なことをまとめました。

## WebAPIとは
API（Application Programming Interface）とは、TwitterやGithubなどのサービスのデータを、外部のアプリケーションやプログラムから扱う為の機能を提供するインターフェース。
様々なアプリでこのAPIを提供してくれているおかげで、様々な機能を使えるようになる。

## WebAPIの役割
WebAPIはサービスと外部アプリの中間にいて、普段できないデータベースへのやり取りを仲介する。
両者を仲介するWeb APIは、外部のプログラムからの命令が、Web APIで提供している機能と一致しない場合には受け付けてくれない。また、公開範囲が限られているWeb APIの場合は、対象範囲でなければ利用を許可しない。

つまり、Web APIを利用する側は、Web APIが提供している機能を利用する以外のことはできないため、サービスのデータを勝手に書き換えたりはできないし、取得できるデータもサービスが持つすべてのデータが取得できるわけじゃなく、Web APIで公開しているデータだけが対象となる。

どんな機能が提供されているかは、書くサービスの公式ドキュメントを確認する。
VSCodeにSQLフォーマッタープラグインをインストール

# インストール方法

『sql formatter mod』で検索。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cde39599-fe23-d6c0-a889-f88d194a0c0c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e0e75980-9bbc-ad0e-ae8a-2487e1dff381.png)

# 使い方

最初はこの状態で、『Ctrl + Shift + P』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/68af31bf-3dbc-ddea-cd83-3d950e88f590.png)

『Format SQL』と入力してエンター。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0cec856a-2b30-f586-2544-7324816e0868.png)

こうフォーマットしてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/00133ad3-a0d6-c213-03ce-9fa73e8b489c.png)

『Ctrl + Shift + P』は直近で使ったコマンドが一番上に来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e591ee97-dbbe-9d98-95eb-7f6fa6bd464a.png)

なので、『Ctrl + Shift + P』から即エンターでフォーマットできる場合もあります。

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
VSCode Version: 1.87.2 (system setup)
SQL Formatter Mod v1.4.5
PlasmoでChatGPTの質問回数を制限、可視化する拡張機能を作ってみた！

## はじめに
本格的なプログラミングを始めて、半年くらいが経った時に、自己分析する機会があり振り返ってみると、自分がプログラミングを始めた時期は生成系AIの話題で盛り上がり、当たり前のように生成系AIがある状況でした。そのため生成系AIに頼めばドキュメントを見ずともそれなりの物が作れてしまい、`生成系AI依存`に陥り本質的な理解から遠のいているように感じました。
現状自分は理解に時間をかけ、自分の力解決する力を身に付けないと自力のあるエンジニアの方達との差は広まっていく一方な気がして、iphoneのスクリーンタイムのように制限を行う機能を拡張機能で作成することにしました。

## 作ったもの
Plasmoを用いてChatGPT内のDOMを監視し質問回数を制限、可視化する拡張機能を作りました。
基本的には質問回数を用いて制限をかけ、イージー、ノーマル、ハード、カスタムの４種類の制限の設定を選択できます。（難易度の設定は少し適当です。）カスタムで何も制限をかけなければ、質問回数をカウントする機能だけを使うことができます。

https://github.com/s1f102100793/gpt-counter

https://chromewebstore.google.com/detail/lhgnfadhljgjgmpgfddjeiolilgfcnon

## Plasmoとは
[公式サイト](https://docs.plasmo.com/)では「ブラウザ拡張機能のNext.jsのようなものだ！」言われています。
正直Reactを使ったことがある人は簡単にPlasmoで拡張機能を作成できると思います。
Plasmoについてはめちゃくちゃわかりやすく書いてある記事があったのでそちらを紹介しておきます。

https://zenn.dev/nado1001/articles/plasmo-browser-extension

## その他自分が参考にしたモノ
### Plasmoの公式Sample GitHub
Plasmoの記事が少なく、正直とても助かりました。

https://github.com/PlasmoHQ/examples/

### Chrome APIの公式ドキュメント
自分が行いたい実装を考えている時にこのドキュメントを見ることでより具体的な実装を考えることができました。

https://developer.chrome.com/docs/extensions/mv2/reference?hl=ja

## 拡張機能を作っていた時に困ったこと
自分が拡張機能を作っている際に困ったことを記事にしたので、もし気になった物があれば参考にしてください。
### 毎日同じ時間に起動するアラームをセットする

https://qiita.com/gota_sushi_/items/aee180f96894e188833f

https://qiita.com/gota_sushi_/items/11ef41eca962d1f6df30
Dartにおける Raw Value

# 本記事のきっかけ
毎回のようにFlutterで値つきenumの実装を方法を調べているので記事に残しました！

# Raw Valueとは
Swiftにおけるいわゆる**値つきenum**
https://www.hackingwithswift.com/sixty/2/9/enum-associated-values

これと同様な機能を実現する方法としてDart2.17から追加されてる。

# 使い方
SwiftとDartを比べてみる

## Swiftの書き方
例として認証エラーのenumを考える

```swift
enum AuthException:String {
    case  invalidEmail = 'invalid email'
    case  invalidEmail = 'password is too weak'
    case  wrongPassword = 'wrong password'

    let error = .invalidEmail.rawValue // String型の`invalid email`が取得できる

    
}
```
注意点としてenumがサポートしてるプリミティブ型の必要あり。

## Dartの書き方
```dart
enum AuthException {
    invalidEmail('invalid email)',
    invalidEmail('password is too weak'),
    wrongPassword('wrong password');

    const AuthException(this.message);// const コンストラクタを追加
    final String message;// final プロパティを追加
}

const error = AuthException.invalidEmail; // String型の `invalid email`が取得できる
```

ぜひ参考にしてみてください
ExpoでHTTP通信を許可する

## HTTP通信を行う(HTTPSではなくHTTP)

### Androidの場合

Androidで**http**なリモート画像のロードやWebViewでURLを開く場合は`expo-build-properties`を使用します。

```
npx expo install expo-build-properties
```

その後`app.json`に以下を追加します。

```
{
  "expo": {
    ...省略
    "plugins": [
      [
        "expo-build-properties",
        {
          "android": {
            "usesCleartextTraffic": true
          }
        }
      ]
    ]
  }
}
```

### iOSの場合

これまではiOSでは特別な設定は必要なくhttpのURLをWebViewで開けていたのですが、Expo SDK 50にアップグレードしたところエラーが表示されるようになりました。

下記のようなエラーが表示されます。

```
NSURLErrorDomain
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
```

iOSの場合はこのエラーを解消するために`app.json`の`infoPlist`に以下を追加します。

```
{
  "expo": {
    ...省略
    "ios": {
      "infoPlist": {
        "NSAppTransportSecurity": {
          "NSAllowsArbitraryLoads": false,
          "NSExceptionDomains": {
            "mydomain.jp": {
              "NSExceptionAllowsInsecureHTTPLoads": true
            }
          }
        }
      }
    }
  }
}
```

`mydomain.jp`の部分はhttp通信を許可するドメインに置き換えます。

## まとめ

Expo GOアプリでの開発中はhttpリクエストのエラーは出ません。`eas build`して内部配布やストア配布を行った際に上記の設定を行わないとOSによってhttp通信をブロックされるようです。
AWS の EC2(Amazon Linux 2023) で SpringBoot 起動して外部から接続(jarファイル転送)

AWS の EC2 の Amazon Linux 2023 に Java インストールして SpringBoot の jarファイルを置いて 起動して外部から接続した時の備忘録メモ
実施したのは 2024/04/04 時点です

- ざっくり流れ
    1. EC2インスタンス起動
    1. EC2ログイン
    1. Javaインストール
    1. ローカルから SpringBoot で作った jar を転送
    1. SpringBoot 起動
    

- 環境情報
    - EC2 (Amazon Linux 2023)
    - SpringBoot v3.2.3
    - Java v21
    - Windows11
    - Tera Term v5.2

# EC2インスタンス起動

AMI は Amazon Linux 2023にして ssh で接続するのでキーペアとかちゃんと設定する
SpringBoot で使うポート(デフォルトは 8080 )を外部から接続できるようにセキュリティグループを追加
そのほかは自由でOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/1cb90019-e4e7-66f0-ced6-4d60f20534e3.png)

# EC2 ログイン

windows pc でTeraTerm だとファイルのドラック＆ドロップで転送できるので TeraTerm を使う
最近リリースあった v5 だと ssh も問題なく使えるみたいです
ホストに EC2 の パブリックIP、ユーザ名 `ec2-user`、認証方式を RSA 鍵使うにして秘密鍵に pem ファイルを指定 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/90cc5329-1f0c-5c2b-9942-5060dfeceb8e.png)

# root でログイン

```terminal
sudo -i
```

# Java インストール

- インストール（v21）
    ```terminal
    sudo yum install java-21-amazon-corretto
    ```

- インストール確認(バージョン出力)
    ```terminal
    java -version
    ```
    
- 補足：複数バージョンで切替えたいとき
    Javaの他のバージョンの SpringBoot 使いたいときのため念のため．．．
    他のバージョンの Java をインストールして以下のコマンド実行して選択する感じ
    ```terminal
    sudo alternatives --config java
    ```
    他のバージョンのインストールは数字変えるだけ
    ```terminal
    sudo yum install java-17-amazon-corretto
    sudo yum install java-11-amazon-corretto
    sudo yum install java-1.8.0-amazon-corretto
    ```

# jar を EC2 に転送

TeraTerm だと SpringBoot の jar を選択してドラッグ＆ドロップするだけでOK
送信先にパス指定できるけどデフォルトだと ec2-user の home ディレクトリ `/home/ec2-user/` にアップロードされる
SpringBoot の jar は環境によるけど maven のプロジェクトだとデフォルトではプロジェクトフォルダの直下にある target の中に作られます
なければMavenビルド実行でゴールを `clean package` にして実行
DB設定とか違う状態でビルドしたいときは `clean package -Dmaven.test.skip=true` にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/40d81727-39ea-2793-9845-218ed8123503.png)

# jar を置いたディレクトリに移動

```terminal
cd /home/ec2-user
```

# SpringBoot 起動

SpringBoot の jar の名前は上で転送した jar に合わせてください
起動したらブラウザから接続 `http://パブリックipアドレス:ポート/urlpath` して確認してみよう
パブリックIP, ポート(デフォルト8080), urlpath は自分のやつに合わせる

```terminal
java -jar spring-boot.jar
```

# アクセス確認

外からつながるようにしてたらアクセスできるはず．．．
http://パブリックIP:ポート番号/URLパス

# 環境変数の対応
AWS上で起動するときは開発環境とは違う設定を使いたいときが多いので環境変数の対応を簡易に．．．
jar が置いてあるディレクトリに application.properties 作って対応する感じです

1. jar 置いた場所に移動
    デフォルトだと `/home/ec2-user/` になる、アップロード時に指定した時はそこに移動
    ```terminal
    cd /home/ec2-user
    ```
1. application.properties の空ファイル作成
    ```terminal
    touch application.properties
    ```
1. application.properties を編集
    内容は一旦、ローカルのやつを元にした方が楽そう、変えたいところだけ変更する
    ```terminal
    vi application.properties
    ```
1. SpringBoot 起動
    起動方法は変更なし、カレントディレクトリの application.properies 使ってくれる
    ```terminal
    java -jar spring-boot.jar
    ```
【Simulator】iOS17.2 Simulator環境でパスワードが開けないバグ

# 概要
iOS17.2 + Simulator環境で「設定」アプリ内の「パスワード」が開けないバグがあります。
端末関係なく、iOS17.2 + Simulator環境であれば発生するものであると思われます。

# 詳細
iOS17.2のSimulatorを起動し、設定(Settings)アプリ -> パスワード(Password)をタップすると、一瞬だけ開いて戻ってしまう挙動が発生している。

※ 分かりずらいかもです
<img src="https://raw.githubusercontent.com/mrs1669/qiita-article/main/Resources/Images/20230404_iOS17.2-bug/iOS17.2-bug.gif" width="240"　alt="iOS17.2のバグ動画">

### 発生環境
> CPU: M1 Pro (Apple Silicon)
> OS: macOS Sonoma 14.3 (23D56)
> Xcode: Version 15.2 (15C500b)

私は以下の環境でバグの発生を確認しました。
- iPhone SE 2nd generation + iOS17.2
- iPhone 13 Pro Max + iOS17.2
- iPhone 14 Pro Max + iOS17.2
- iPhone 15 Pro Max + iOS17.2

# 備考
本バグはフィードバックアシスタントにてAppleに報告済

iPadOS17.2でも同様に「パスワード」をタップすると開けないバグがありました。
<img src="https://raw.githubusercontent.com/mrs1669/qiita-article/main/Resources/Images/20230404_iOS17.2-bug/iPadOS17.2-bug.gif" width="360"　alt="iPadOS17.2のバグ動画">
特定のDOM要素の増加を観測してみた！

## はじめに
今回、拡張機能を作るにあたって、ChatGPTへの**質問回数をカウントする機能**を実装することになりました。その際に実装が難しかったので記事にしようと思いました。

## 概要
### 特定のDOM要素の増加を観測する目的
ChatGPTの１日の返答回数（質問回数）をカウントすることが当初の目的でした。
つまりDOMの中の特定のクラスネームをカウントして、そのクラスネームのDOM要素が１増えるとGPTの返答回数が増えるということになります。そのため特定のDOM要素の増加の観測を実装することになりました。

### 予測される実装の関数の流れ
①監視をスタート→②既存のGPTの返答数をカウントする→③DOMに変化がある場合再度返答数をカウントする→④もしカウントした返答数が増加していたら、既存の返答数に＋１して③に戻る。
この繰り返しでChatGPT内の返答の増加を常に監視することができそう。

## 実装
今回は[MutationObserver](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)を用いて実装しました。
```typescript

const targetParentElement = document.querySelector(".sample")
const targetElementClassName = ".sample__item"

const observeDOMChanges = async (): Promise<void> => {
  if (targetParentElement) {
    let currentCount = document.querySelectorAll(
      targetElementClassName
    ).length
    const mutationCallback: MutationCallback = () => {
      const updateCount = document.querySelectorAll(targetElementClassName).length

      if (updateCount - currentCount === 1) {
        currentCount = updateCount
        // 特定のDOM要素が１つ追加された時の処理
      }
    }

    const observer = new MutationObserver(mutationCallback)
    observer.observe(targetParentElement, {
      childList: true,
      subtree: true
    })
  } else {
    console.error("Target element not found.")
  }
}

observeDOMChanges()
```
この実装では`targetParentElement`と`targetElementClassName`をサンプルの値で実装しています。
また自分はこのカウントするコードに実際の実装ではDOMの処理を読み込む時間を`currentCount`の部分で`setTimeout`を用いて指定した時間を待つようにしました。それに加えて、URLが変更された際に、オブザーバーを再起動することで、chatごとの`currentCount`の初期値を計算しています。
以下の部分がその実装です。

https://github.com/s1f102100793/gpt-counter/blob/master/src/contents/countChatgptResponse.ts

## まとめ
今回はオブザーバーを用いた特定のDOM要素の増加を観測方法を紹介しました。
個人的には振り返ってみると簡単そうに見えるのに、当初はすごく手こずった思い出があります。
違うやり方があったり、もっといい方法あるよーとかあったらじゃんじゃんコメント待っています。
最後まで読んでいただきありがとうございました。
【Git hub】Git pushがrejectされた時に真っ先に試す対処法

いつも通りGit pushしようとした時、そいつは突如現れました。
```sh
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:RentoYabuki06/python-from-zero.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

リモートのブランチの方がローカルブランチよりも先行しており、競合してしまっているとのこと。

なんのことやら、と思いましたがよくよく考えると、README.mdファイルをGithub上でいじった直後のことでした。どうやらその変更がローカルに反映されていないのがまずいらしい？

ということで```git pull```してみました。

```sh
git pull
```
何やらたくさんhint表示が出て、エラーではないがうまくいっていないご様子。

```sh
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
```

よくみてみると、レポジトリが競合しているようです。rebaseしろとのご司令なので、

```
git pull --rebase
```
そしてもう一度、
```
git push
```

無事にpushされ、Githubにも反映されました！！
Git初心者すぎて焦りましたが、次回同じエラーが表示された時のための備忘録として残しておきます。
DockerfileとDocker-compose.yml

アプリをローカルで動かすにあたって作成した。
せっかくなのでDocker環境を作成した。
環境
- VSCode
- java
- DockerDesktop
- postgres


## ファイルの違いについて
Dockerfileについては、以下参照

- Dockerfile
:単一コンテナのイメージを作成することに使う。
例：「アプリコンテナ」作成

- Docker-compose.yml
：コンテナを複数組み合わせて使うときに使う。
例：「アプリコンテナ」と「DBコンテナ」を作成

## 作成したものから理解を深める
Dockerfileについては、以下参照
https://qiita.com/ssatoshi_117117/items/44a0ad49acf2ae297659

docker-compose.ymlは以下のように作成した。
`build: .` で同ディレクトリのDockerfileを用いてビルドする。
＊上記以外にイメージをPullし、指定する方法もある。

```dockerfile:docker-compose.yml
version: '3.8'

services:
  db:
    image: postgres:latest
    restart: always
    ports: 
      - "5434:5432"
    environment:
      POSTGRES_USER: ***
      POSTGRES_PASSWORD: ***

  myapp:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5434/my_database
      SPRING_DATASOURCE_USERNAME: my_user
      SPRING_DATASOURCE_PASSWORD: my_password
```

## 起動
VScodeからの起動は簡単
＊コマンドとしては何をしているかは意識するべき

- Dockerfile
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781864/d036408b-637b-83c7-73e1-ba3fa4f6e9bd.png)

イメージ確認と起動
```
PS C:\Users\***\Documents\hello> docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
hello        latest    c980b8e240e2   24 minutes ago   429MB

PS C:\Users\***\Documents\hello> docker run -dp 8080:8080 hello:latest
c7a1d1e1208ea8c2836131d89c77b7498b6ba13e437322ee750cd9f11f69eb7b

PS C:\Users\***\Documents\hello> docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS         
 PORTS                    NAMES
28c9a0076ae6   hello:latest   "java -jar /app/app.…"   24 seconds ago   Up 23 seconds 
```

- docker-compose
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781864/ec5a24da-5dd4-1804-8cb7-396d94f3e189.png)


```
PS C:\Users\***\Documents\hello>  docker ps  
CONTAINER ID   IMAGE             COMMAND                   CREATED          STATUS          PORTS                    NAMES
f467d9f5e118   hello-myapp       "java -jar /app/app.…"   36 minutes ago   Up 36 minutes   0.0.0.0:8080->8080/tcp   hello-myapp-1
22145c545a1a   postgres:latest   "docker-entrypoint.s…"   36 minutes ago   Up 36 minutes   0.0.0.0:5434->5432/tcp   hello-db-1
```
システムデザインの概念（part1 : 基礎）

会社の後輩の子のスキルアップするための記事です。システムデザインはSEとて全体像を教えてくれる領域なので、ぜひ理解するようにしていきましょう。

#### 1 - コンピューターアーキテクチャ

コンピューターアーキテクチャの主要な構成要素には、ディスク、メモリ、中央処理装置（CPU）、キャッシュが含まれます。

**ディスク**（disk）にはHDD（ハードディスク）とSSD（ソリッドステートドライブ）が含まれます。後者の方が一般的であり、そのコストはより高くなります。

**メモリ**（RAM）はディスクよりも高価で、ストレージスペースは小さいですが、非常に高速な記憶装置です。コンピューターをシャットダウンすると、内部の内容が失われます。

**中央処理装置**（CPU）はコンピューターの中核的な計算部分であり、高速キャッシュが内蔵されています。

**キャッシュ**（cache）は重要な概念であり、コンピューターアーキテクチャ以外の多くの領域で使用されます。例えば、ウェブブラウザーは頻繁にアクセスされるウェブページを追跡するためにキャッシュを使用し、それらをより高速に読み込みます。これらの保存されたデータにはHTML、CSS、JavaScript、画像などが含まれます。データがページキャッシュされてから有効である場合、読み込み速度が向上します。ただし、この場合、ブラウザーはキャッシュとしてディスクを使用します。なぜなら、インターネットリクエストを発行することはディスクから読み取るよりも遅いからです。

さらに、ムーアの法則についても言及しておきます。これは、コンピューターの内部CPUのトランジスタ数が約18ヶ月で倍増し、価格もそれに応じて半減するという観察結果です。

#### 2 - アプリケーションアーキテクチャ

**アプリケーションアーキテクチャの概要**：製品レベルのアプリケーションのアーキテクチャは、複数のコンポーネントから構成され、共に堅牢なシステムを作り出します。これらのコンポーネントには、開発者、サーバー、ユーザー、フロントエンドコード、ストレージシステムなどが含まれ、それぞれが別のセクションで詳しく説明されています。

**開発者の視点**：開発者はコードを書き、それをサーバーにデプロイします。サーバーは他のコンピューターからのリクエストを処理し、アプリケーションデータを永続的に保存する必要があります。ストレージシステムはサーバー内にあるか、外部からネットワーク接続を介してアクセスされます。

**ユーザーの視点**：ユーザーはウェブブラウザーを介してサーバーにリクエストを送信し、サーバーはこれらのリクエストに応答します。サーバーがすべてのリクエストを処理できない場合、それを拡張する必要があります。これは、サーバーのハードウェアをアップグレードする垂直スケーリングまたはサーバーの数を増やす水平スケーリングによって実現できます。

**負荷分散（LB）**：サーバーの負荷を分散するために、負荷分散器を使用してリクエストを複数のサーバーに均等に分配できます。

**ログとメトリクスの記録（logging&metrics）**：サーバーにはログサービスがあり、すべてのアクティビティが記録されます。より信頼性の高いログの記録のためには、通常、これらを別の外部サーバーに書き込みます。さらに、さまざまなデータを収集し、開発者がサーバーの動作を理解し、潜在的なボトルネックを特定できるようにするために、メトリクスサービスが必要です。

**アラート**：開発者は、特定のメトリックが目

標値に達しない場合にプッシュ通知を受け取るためにアラートを設定できます。これにより、定期的にメトリックの状態をチェックする必要がなくなり、問題を早期に検出して対処できます。

#### 3 - システムデザイン要件

大規模で効率的な分散システムを設計するために満たす必要がある要件：

1. **システムデザインの基礎**：システムデザインのインタビューでは、デザインのアプローチと分析が重要であり、各コンポーネントの詳細についてではありません。効果的な分散システムを設計するには、データの移動、保存、変換、システムの可用性、信頼性、容錯性、冗長性などを考慮する必要があります。

2. **考え方**：大規模な企業システムを設計する際には、それを3つのキーとすることができます：データの移動（moving data）、保存（storing data）、および変換（transforming data）。分散システムでは、通常、ローカルデータの移動よりもデータの移動が難しい場合があります。

3. **データの保存**：大規模な分散システムを設計する際には、必ずしもデータの保存が必要です。データの保存方法を考慮する必要があります。これには、データベース、Blobストレージ、ファイルシステム、または分散ファイルシステムなどが含まれます。適切なストレージ方法を選択することは、使用状況に依存します。

4. **データの変換**：データの移動と保存に加えて、システムはデータを変換する必要があります。データの変換方法はさまざまで、監視サービスはサーバーログを成功と失敗のリクエストの割合に変換することができます。変換プロセスがどれほど複雑であろうとも、データを効率的に変換する方法を考える必要があります。

5. **可用性（Availibility）**：可用性は効果的なシステムの中核です。これは、一定期間内にシステムが利用可能な状態である割合を示します。可用性の重要性と、どのようにして計算し、向上させるかを理解することがデザインの鍵です。

6. **信頼性、容錯性、冗長性（Reliability, Fault Tolerance, and Redundancy）**：信頼性は、一定期間内にシステムが予期される機能を実行することを意味します。容錯性は、システムが故障を検出して自己修復する方法を指します。冗長性は、システム内のバックアップコンポーネントの存在を指し、主要なコンポーネントの故障に備えます。

7. **スループット（Throughput）と遅延（Latency）**：スループットは、一定の時間内に処理されるデータ量や操作数を指します。遅延は、クライアントがリクエストを送信してからサーバーがそのリクエストに応答するまでの時間を指します。システムを設計する際には、スループットを向上させ、遅延を減少させる方法を考える必要があります。

総じて、効果的なシステムを設計するには、データの移動、保存、変換、システムの可用性、信頼性、容錯性、冗長性、スループット、および遅延などの要素を考慮する必要があります。
PowerAutomate必須列を無視して SharePoint リストアイテムを更新する

# 手順
1.「入力」アクションを検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/3aa71e95-0dcb-42cf-ce4e-578f3eb9db34.png)

2.リスト名を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/9b283408-5a0f-1f72-bca8-2ec4278523e2.png)

3.Sharepoint「項目の更新をアクションを検索」、リスト名のところに「出力」を入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/fc5eb02f-bf68-a5c8-856f-595daacbd1b3.png)

4.更新項目のIDを設定し、項目の部分をJSONで書く
```
{
    "ItemStatus":{
        "Value":"Start"
    }

}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/dbd4a539-dc8e-c5d3-2a59-aeb90266a954.png)


# 参考サイト
https://www.frog-pod.com/FrogTechLog/2023/07/sharepoint-list-power-automate.html
AIChatボットについて

## AIChatボットについて

本記事では以下内容について記載する。
1. AIChatボットとは
1. AIChatボットの種類
1. 運用について

#### AIChatボットについて
AIChatボットとは、利用者が入力した内容に対して、AIが自動的に返信するツール。
普通のChatボットとは違い、入力したワードから分析して似た回答を出してくれ、また、利用ごとに回答の制度が向上する。
そのため、最近では利用経験の有無を確認する企業が出てきている。
ただし、商用利用などの際は機密情報の漏洩につながる場合があるので使用する際は注意が必要である。

#### AIChatボットの種類
AIChatボットは様々な種類がある。
そのため、いくつかを抜粋してまとめた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761023/f8f13990-d9be-744d-67ea-79094783f8ea.png)

サービスURL
[Perplexity AI](https://www.perplexity.ai/)
[Bing AI](https://www.bing.com/chat?form=CONVRD)
[ChatSonic](https://writesonic.com/chat)
[YouChat](https://you.com/?chatMode=default)
[Google Bard](https://gemini.google.com/?hl=ja)
[Notion AI](https://www.notion.so/ja-jp/help/guides/category/ai)
[ChatGPT](https://chat.openai.com/)
ACCESS 最適化とは、データ容量を圧縮すること

ACCESSが分からない私のための備忘録です。

## Accessのファイル容量は2GBの制限がある
Windowsの仕様により、形式「.mdb(Office 2007以降の場合は.accdb)」の容量上限が約2GBとのことです。
データベースを扱うには2GBは小さく、「2GBの壁」と言われているようです。

## 「データベースの最適化/修復」とは
ACCESSでの最適化とは、データ容量を圧縮することで
``ファイル`` ＞ ``データベースの最適化/修復`` をすることで簡単にデータベース内の不要データを整理して容量削減ができます。
これが手っ取り早い容量削減方法です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/254cdfa1-e45f-449c-0c8e-0fceb5bf9f6c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/47403af5-b737-ab9a-0d6e-056f9a0f3de0.png)


## 閉じる際に自動で最適化する（簡単）
手動で最適化するのも簡単ですが、もっと楽で忘れない方法は閉じる際に自動で最適化できることです。
``ファイル`` ＞ ``オプション``
へ移動して、``閉じるときに最適化する``にチェックを入れるとデータベースを閉じる際に自動で最適化されますので便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/d77cea54-7ef0-471b-ec49-6588ee1a3fb8.png)

以上。
Lamdaレイヤーを作成する（python3.8）

## Lambdaにレイヤーを追加する
Lamdbaでサードパーティライブラリを使用する場合には「レイヤー」を作成して、関数に追加する必要があります。
今回はレイヤーの作成方法をメモ

## Amazon Linux2環境の起動（作成）

LambdaはAmazonLinux環境なので、同一の環境で作成します

```bash
docker run -it --rm amazonlinux:2 bash
```

## Python3.8をインストール
```
yum update -y
yum install -y amazon-linux-extras
amazon-linux-extras enable python3.8
yum install -y python3.8 zip
```

※Python3.8にしている理由はAmazonLinux2（amazon-linux-extras）でインストール可能なバージョンが３.８だからです。
これ以上のバージョンにするには別な方法でインストールする必要がありますが、今回は割愛（一番簡単な方法のため）

インストール可能なバージョンの確認
```
amazon-linux-extras list
```

## 必要なパッケージをインストール（今回はslack-sdkを例に説明）
```
mkdir -p /opt/python/lib/python3.8/site-packages
python3.8 -m pip install slack-sdk -t /opt/python/lib/python3.8/site-packages
```

## レイヤー用のZIPファイルを作成

```
cd /opt
zip -r /opt/slack_sdk_layer.zip python
```

## 作成したZIPファイルの取り出し
```
docker cp <CONTAINER_ID>:/opt/slack_sdk_layer.zip .
```

## Lambdaレイヤーを作成
レイヤー　→ レイヤーの作成　→ レイヤーの設定　にて作成したzipファイルをアップロード
※アーキテクチャにはx86_64　ランタイムにはpython3.８を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555551/25a1bcc6-160f-a55e-d746-21edeacd2bd4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555551/726274f1-0090-b1f0-1c41-d94ecff08578.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555551/6dc4306b-5918-2d55-1424-5a94ec294cf1.png)

## Lambda関数を作成
Lambdaのランタイムはpython3.８を選択し、関数を作成


## 関数にレイヤーを追加
関数のレイヤー欄からレイヤーの追加　→ カスタムレイヤー　→ 作成したレイヤーを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555551/325c1edc-b5ed-d6b2-765f-1bff4f58c4a7.png)

これで完成です。
「現代数理統計学の基礎」演習問題解法メモ　第8章問1

第8章ですが、解法をUPしてくれていた方々も8章はUPしていません。
たぶんに、信頼区間、棄却域を示すだけなので、「わかるよね。」ということかなと。
でも、それがわからないのですよね。
何とかメモを作成してみました。
書物にしても、UPしてくれている解法にしても、私にはハードル高いです。
問1は、最初から解きなおしたのでボリュームガ増えてしまいました。
![第8章問1 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8324f2b5-2227-7481-9e99-949abfbb6b98.jpeg)
![第8章問1 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/60010f5a-3bb0-2c46-e0e4-291f77ac09ee.jpeg)
![第8問1 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8be1604f-fe7a-cac7-8d0d-6d34104f124a.jpeg)
![第8問1 P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/c4ac988a-c444-a3a1-1b26-61d79d734651.jpeg)
![第8問1 P5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/ff6c961d-3728-3480-2eb5-a45b7b375147.jpeg)
![第8問1 P6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/19c69685-24f7-9736-0a22-1ce79436bd45.jpeg)
![第8問1 P7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/89f06125-8d62-61ea-8d59-720e7163d4a1.jpeg)
![第8問1 P8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/d06b6a9b-724d-4d66-2110-cd64f00963bd.jpeg)
![第8問1 P9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/a3193d21-8109-9a90-d532-ad9ef2ecdcae.jpeg)
![第8問1 P10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/336a5224-670a-02a3-ccea-72dffb45e643.jpeg)
![第8問1 P11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/9b9a65cd-89d2-ea61-d214-eb5ab8fd5d80.jpeg)
Wayland on Ubuntu22.04 ～Westonのデモ～

# 目的
Xwindowに変わるGUIとして、Waylandを採用してみたいので、デモ画面を表示するところまでやってみました。

# 環境
ホストOS：Windows11 Pro
ゲストOS：Ubuntu22.04
VM:VMware workstation 16 player

# 必要なもの
Python3
```sh
sudo apt install python3-pip 
sudo pip install --upgrade pip
```

[meson](https://mesonbuild.com/Getting-meson.html)
ビルドシステム　Waylandをビルドするのに必要です。
```sh
sudo apt install build-essential
sudo pip install meson
```

# 参考
[Waylandのホームページ](https://wayland.freedesktop.org/)
アーキテクチャーの部分を読んでいただくとよいかと思います。

[Weston](https://wiki.archlinux.jp/index.php/Weston)
Waylandのコンポジター


# Waylannd

## git clone

作業ディレクトリを作り、Git Cloneを展開します。
``` sh
git clone https://gitlab.freedesktop.org/wayland/wayland
```

ビルド時に、ことあるごとにERRORが出てくるので、以下のパッケージをあらかじめインストールしておきます。
## 必要なパッケージのインストール
``` sh
apt install pkg-config libffi7 libffi-dev libxml2-dev graphviz doxygen xsltproc xmlto
```

## build
``` sh
cd wayland
meson build/ --prefix=/home/<user name>/wayland/lib #適当に決めたディレクトリ（絶対パス）
ninja -C build/ test # ビルドを実行するのに問題ないかをテストできます。
ninja -C build/ install
```

## 環境変数
XDG_RUNTIME_DIRが定義されている必要があります。

定義されているかを確認する必要があります。
ログイン時に実行したい場合、以下のようにターミナルが一般モードになっていると思います。
```sh
<login user>@<machine name>:~$
```
ここで、echoで確認します。
```sh
echo $XDG_RUNTIME_DIR
# ディレクトリが定義されていればOK
```
echoコマンドの応答に何も返ってこない場合、未定義です。
~（$HOMEディレクトリ）にいる状態で、ls -aコマンドで隠しファイルを表示します・。
```sh
<login user>@<machine name>:~$ls -a
```
ここで、.bash_profileというファイルがなければ、作成します。
```sh
:~$ sudo touch .bash_profile
:~$ sudo vim .bash_profile
```
.bash_profileの内容
```sh
#!/bin/bash
if test -z "${XDG_RUNTIME_DIR}"; then
    export XDG_RUNTIME_DIR=/tmp/${UID}-runtime-dir
    if ! test -d "${XDG_RUNTIME_DIR}"; then
        mkdir "${XDG_RUNTIME_DIR}"
        chmod 0700 "${XDG_RUNTIME_DIR}"
    fi
fi
```
プロファイルを読み込ませるためにUbuntuを再起動してください。

再起動しない場合、sourceコマンドでプロファイルを読み込みます。ただし、マシン起動時にプロファイルを正常に読み込めたかが確認できないので注意が必要。
```sh
source .bash_profile
echo $XDG_RUNTIME_DIR
# ディレクトリが定義されていればOK
```

# Weston実行

Gitリポジトリを展開したwaylandディレクトリに移動します。
```sh
cd wayland
```

```
weston
```
以下のシンプルなデモ画面が表示できればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542103/5169c7e3-6742-156f-1282-65db964e60f7.png)

このWeston上の左上にあるターミナルを起動して、以下のコマンドを実行すると、花が咲きます。
``` sh
weston-flower 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542103/df182b41-917c-3dd4-e01a-945a74f0b36a.png)

# CUIからの実行

UbuntuをCUIモードでログインして、上記同様にwestonコマンドを発行すると全画面表示で同様のWindowが表示されます。
ターミナルにおいて、shutdown -hコマンドで終了することができます。
これから

# 自己紹介
現職：Webエンジニア
年齢：30歳

新卒でSIerに就職
25歳で同業他社に転職
27歳で現在所属している会社に就職

### 経験
1\.Java(SpringBoot)　Springは1年ちょい。Javaは5年くらい。
2\.C#(.NET)　3年くらい。
3\.DB

# この記事を書いた背景
・量産型エンジニアで、何となく仕事は進められているがトラブルと遭遇した時に対応できない
・今までなんとなく働いてきたが、家族ができお金の面で不安しか無かったのでがっつり稼いでいきたいと思い立った
そんなこともあり、まずはインプットしたものをアウトプットしていこうと思った

# 今後
基礎的なところから学び直そうとして以下サイトを活用している
https://recursionist.io/

学んだことを最低週1本記事を投稿していく
今年末までに50本を目指す

# 最後に
自分が今まで何もしてこなかった現状が今を招いています
後悔していますが、何もしないと1年、5年、10年後と同じことを思うのでここで断ち切りたいと思います
もしこんな自分と一緒に頑張っていきたいと思ったかたがいればコメントください
冷やかしだけは勘弁してください
#9 page control、segmented control、button & gesture を使用してコンテンツを切り替える

今回の課題では、過去に香港の蝋人形館で撮影した有名人との写真を使用して完成させます。

インターフェースの設計

まず、StoryboardにUIImageViewを追加して写真を表示し、UILabelを追加して名前を表示し、UISegmentedControlを追加して異なる写真を選択し、UIPageControlを追加して現在のページの位置を指示します。

IBOutletとIBActionの作成

これらのUIコンポーネントをViewControllerに接続し、IBOutletとIBActionとして接続します。これにより、コード内でこれらのコンポーネントにアクセスして操作することができます。

```
@IBOutlet weak var imageShow: UIImageView!
@IBOutlet weak var nameSegament: UISegmentedControl!
@IBOutlet weak var picturePage: UIPageControl!
@IBOutlet weak var nameShow: UILabel!
```

UIの初期化と更新

ViewControllerのviewDidLoadメソッドでUIコンポーネントを初期化します。updateUIメソッドを作成して、画像、名前、選択コントロール、ページコントロールの現在の状態を更新します。

```
override func viewDidLoad() {
super.viewDidLoad()
}

func updateUI() {
imageShow.image = UIImage(named: name[index])
nameShow.text = name[index]
nameSegament.selectedSegmentIndex = index
picturePage.currentPage = index
}
```

ユーザーインタラクションの処理

```
selectPicture、changePageControll、pre、nextメソッドを実装してbuttonとスワイプのインタラクションを処理し、updateUIメソッドを呼び出してUIを更新します。

@IBAction func selectPicture(_ sender: Any) {
// indexを更新してupdateUIを呼び出す
}

@IBAction func changePageControll(_ sender: Any) {
// indexを更新してupdateUIを呼び出す
}

@IBAction func pre(_ sender: Any) {
// indexを更新してupdateUIを呼び出す
}

@IBAction func next(_ sender: Any) {
// indexを更新してupdateUIを呼び出す
}
```

成果：
![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3703986/32926819-73a1-689f-b60a-92b8599bcbb6.gif)

https://github.com/liyoway/changeImage?source=post_page-----28fd05d4be0e--------------------------------
Swift-Collectionsを触ってみる


モダンな配列処理が得意なswiftですが、公式パッケージであるSwift-Collectionsを導入することでさらにモダンでスマートなコードを書くことができます。
Swift Package Managerで導入できます。
https://github.com/apple/swift-collections/

## 各コレクションについて
順番に動作を見ていきます。

### Deque
Dequeは、先頭にもデータを追加できる配列です。
reduceのような標準の配列の機能も使えるようです。
```swift
import Collections

var deque: Deque<Int> = [2, 3]
deque.prepend(1)
deque.append(4)
print(deque)
// [1, 2, 3, 4]

let reduce = deque.reduce(0, +)
print(reduce)
// 10

// [1, 2, 3, 4]
```
標準のArrayでもinsertで同様の実装ができますが、Dequeのprependで実装した方が高速に動作するようです。
### OrderedSet
swiftのSetは順序が保持されませんが、OrderedSetなら元の順番を保持してくれます。
重複を削除したくて、かつ順序を変更したくないという場面は時々出てくるので使い道は多そうです。
```swift
import Collections

var array = [1, 2, 1, 3, 2, 4, 5, 4, 7]
let set = Set(array)
let orderedSet = OrderedSet(array)
print(set, orderedSet)
// [1, 5, 4, 2, 7, 3] [1, 2, 3, 4, 5, 7]
```

### OrderedDictionary
まずswiftの辞書型についてですが、順序が保持されません。
```swift
import Collections

var dictionary: [String: Int] = [:]

dictionary["a"] = 1
dictionary["b"] = 2
dictionary["c"] = 3

print(dictionary)
// 実行する度に順序が変わる。
// ["b": 2, "a": 1, "c": 3]や、["c": 3, "a": 1, "b": 2]など
```
OrderedDictionaryなら順序も保持されます。

```swift
import Collections

var dictionary: OrderedDictionary<String, Int> = [:]

dictionary["a"] = 1
dictionary["b"] = 2
dictionary["c"] = 3

print(dictionary)

// ["a": 1, "b": 2, "c": 3]
```
インデックス指定で順序入れ替えるメソッドも用意されています。
```swift
import Collections

var dictionary: OrderedDictionary<String, Int> = [:]

dictionary["a"] = 1
dictionary["b"] = 2
dictionary["c"] = 3

dictionary.swapAt(1, 2)

print(dictionary)

// ["a": 1, "c": 3, "b": 2]
```

# まとめ
汎用性の高いものというより、ピタッとハマればスマートにかけそうなものが多い印象です。
他にもまだ紹介しきれていないコレクションはたくさんありますので、興味のある方は調べてみると良いかもしれません。
Ubuntu GUIログイン/CUIログイン

# 環境
ホストOS：Windows11 Pro
ゲストOS：Ubuntu22.04
VM:VMware workstation 16 player 

# 操作
ログイン画面にて以下の操作をするだけ
- GUIログイン
[Ctrl]+[Alt]+[F1]

- CUIログイン
[Ctrl]+[Alt]+[F6]
Vtuber Python3編

https://paiza.jp/works/mondai/query_primer/query_primer__vtuber

なかなか難しいですね。。。
自分の方針としては、memberに、メンバーシップの有無を０と１で表して、投げ銭分を合計で表して。。。みたいなことを考えたんですが、はじめて登録するメンバーはどうすれば？というところで詰まっちゃいましたね。。。

```py
N = int(input())
members = {}
for _ in range(N):
    A = input().split()
    if A[1] == "give":
        members[A[0]] = (A[2],0)
    else:
        members[A[0]] = (0,1)
        
print(members)

```

回答を見ると、メンバーシップ登録と、PowerChatはわけるということでした。
ただ、それ以外にもちょっと難しいところがあったので一つずつコメントしながら
作成します

```py
N = int(input())
#初期化（スーパーチャットを辞書で、メンバーシップを集合で）

superchat = {}
members = set()

for _ in range(N):
    #イベント
    event = input().split()
    name = event[0]
    action = event[1]
    
    if action == "give":
        money = int(event[2])
        #詰まったところだが、普通に配列のインデックスに名前がないか見ればよかった
        if name not in superchat:
            superchat[name] =(money,name)
        else:
            superchat[name] =(superchat[name][0] + money,name)
    else:
        #集合へ加えるときはadd
        members.add(name)

#ラムダ式2列目を中心に降順ソート     
for name, money in sorted(superchat.items(), key=lambda x: x[1], reverse=True):
    print(name)
for name in sorted(members):
    print(name)

```
【初心者向け】Javascriptのfilterとmapメソッドをいい加減マスターする

# 実行環境

簡易的な実行確認は[paiza.io](https://paiza.io/projects/U9vmvgYKoYnML5nch9v9bw)で行う

# おさらい

filter：条件にあう数値の配列になる（値を返すわけではない）

map: 操作した後の配列を返す

# まずはfilter

## 問題：配列に対して、1でない要素のみを返す関数を作る

filterは値を返さない
=> returnする必要がある

```js
const array = [1,2,3,4,5];
const filtered = (array) => return array.filter((n)=> n !==1);

console.log(filtered(array));//[2,3,4,5]
```

ちなみに以下は誤り

```js
const array = [1,2,3,4,5]

const filtered = array.filter((n)=> n !==1)

console.log(filtered(array))
```

# 次にmap

## 問題：数値の配列に対して、各要素を倍にした数を格納した値を変数に代入する

```js
const array1 = [1, 4, 9, 16];

// Pass a function to map
const map1 = array1.map((x) => x * 2);

console.log(map1); //Array [2, 8, 18, 32]
```

以下は誤り

```js
const array1 = [1, 4, 9, 16];

const map1 = () => return array1.map((x) => x * 2);

console.log(map1); //Array [2, 8, 18, 32]
```
Hubot Slack アダプターや RTM API から移行先について

こんにちは、Slack の[公式 SDK 開発](https://github.com/slackapi)と日本の Developer Relations を担当している瀬良 (@seratch) と申します :wave:

今週、Slack プラットフォームチームより以下のアナウンスメントが出ました。

https://api.slack.com/changelog/2024-04-discontinuing-new-creation-of-classic-slack-apps-and-custom-bots

要点をまとめると以下の三点となります。

* 2024 年 6 月 4 日以降、"classic app" と呼ばれる [RTM API](https://api.slack.com/legacy/rtm) や旧式の bot scope を持つアプリは新規で作成できなくなります
* これまでに作成されたアプリは引き続き動作しますが、RTM から [イベント API](https://api.slack.com/apis/connections/events-api) への早めの移行をおすすめします
* [Hubot](https://slack.dev/hubot-slack/) やその他の RTM を使ったアプリは、[ソケットモード + イベント API を有効にした Bolt アプリ](https://qiita.com/seratch/items/1a460c08c3e245b56441)への移行をおすすめします

以下でもう少し補足します。

### "classic app" の新規作成が停止されます

これまで数年間、どうしても作成する必要があるユーザーのためだけに用意されたアクセス方法が[現行の仕組みへのマイグレーションガイド](https://api.slack.com/authentication/migration)のところにあるだけでしたので、最近新しく作ったことがある人はほとんどいないと思いますが、10 年近く前から提供されてきた初期の Slack アプリ設定を新しく作成することがついにできなくなります。

これ自体が影響する方はほとんどいないと思います・・・が、どうしてももうしばらくは RTM アプリを運用する必要があるという場合は、5 月中にテスト用アプリを作成して組織の中で共有しておく方がよいと思います。

紛らわしいのですが、**Bolt アプリを作る仕組みが非推奨になったわけではありません！** それよりも遥か昔に作られた初期の仕組みが非推奨となっただけです。

### 既存アプリは直ちに停止するわけではありません

"classic app" の新規作成が完全に停止されるだけで、現在動いている RTM などのアプリが動作しなくなるわけではありません。

ただ、いよいよ完全に非推奨という段階にはなりますので、今後も長期で運用を継続したいアプリについては、

1. イベント API + ソケットモードの Slack アプリ
1. 新しいオートメーションプラットフォーム

のいずれかへの移行をおすすめします。これらの移行先については以下の記事を参考にされてください。

https://qiita.com/seratch/items/1a460c08c3e245b56441

https://qiita.com/seratch/items/ecc16b845483c9d6f9e1

### Hubot / RTM API からの現実的な移行先

最新の機能であるオートメーションプラットフォームは、オートメーションのためのワークフローを作成することに最も適した機能です。

そのため、プラットフォームがチャットボット向けの機能しか持たなかった頃につくられた RTM API アプリや Hubot については、そのままの機能を有したままで移行するには必ずしも最善の手段とは言えないかもしれません。また、オートメーションプラットフォームでは、カスタムコードで機能を実装した場合はワークフロー実行回数に基づく従量課金となる点もユースケースに合わないことが多々あるかと思います。

多くの場合、ソケットモードとイベント API を有効にしたアプリを Bolt for JavaScript で再実装することが最も現実的であると思います。

https://qiita.com/seratch/items/1a460c08c3e245b56441

新しく Bolt アプリを開発するにあたっては、ぜひ先日リリースされたサンドボックス環境を Slack CLI とともに利用してみてください。

https://qiita.com/seratch/items/0459711330b46c5fbd5e

Hubot については Bolt for JS のドキュメントに移行ガイド（日本語）がありますので、こちらも参考にされてください。

https://slack.dev/bolt-js/ja-jp/tutorial/hubot-migration

## 終わりに

私たち Slack のプラットフォーム開発チームでは、長年動き続けているボットをリプレイスするタスクのプライオリティを上げることは容易でないことを理解しており、過去数年間、古い機能を非推奨とはしつつも、動作する状態を継続してきました。しかし、ついにこれらの機能を完全に非推奨とせざるをえない時期が来ました。

お手数をおかけいたしますが、何卒よろしくお願いいたします :bow:
windows11 ディプレイ解像度以上の解像度を設定する

偶然見つけたのやり方を記録
## 前提
グラボを積んでないとできない。
## やりかた
デスクトップ右クリック>NVIDIAコントロールパネル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/636f924d-958d-c234-3d54-f1dd7ddd593d.png)
解像度の変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/753f6ea4-0a7a-7771-812b-d92968ba2d85.png)

カスタマイズ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/75661179-b506-5528-8c3f-a55a65e0b096.png)

カスタム解像度作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/692b8f84-35e0-60a6-ef80-9d5d916c708d.png)

好きな解像度に設定し、テスト
問題なければ追加できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/8b787e9c-e18d-2a38-8565-c5294ff52d2c.png)
その後
NVIDIAコントロールパネルでも設定できるしWindowsの通常の設定からも追加した解像度が選べる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/ec303ba8-4e0a-cbec-f771-9ef38fc192f9.png)


## メリットデメリット
メリット：モニターの解像度をそろえることで画面の拡大具合がそろう。マウス移動も見たままに
デメリット：文字がにじむ
Power Automate で Azure DevOps 組織のユーザーを追加する

# まとめ

Power AutomateからAzure DevOpsのユーザー追加を行う場合、APIのエンドポイントは通常とは異なるため、Azure DevOpsコネクタではなくHTTPコネクタを使用することで実施できた。

# うまくいかない方法と原因

最初は、Azure DevOpsのコネクタを使えばできるだろうと安易に思っていました。
しかし、Power AutomateのAzure DevOpsコネクタの[リファレンス](https://learn.microsoft.com/ja-jp/connectors/visualstudioteamservices/)を見たところ、組織へのユーザーの追加アクションは存在しません。
だったらAPIを呼べばと思いAzure DevOpsのAPIリファレンスを調べたところ、[User Entitlements - Add](https://learn.microsoft.com/en-us/rest/api/azure/devops/memberentitlementmanagement/user-entitlements/add?view=azure-devops-rest-7.1&tabs=HTTP)でユーザーの追加ができることはわかりました。
しかし、これをAzure DevOpsコネクタの[HTTPリクエスト](https://learn.microsoft.com/ja-jp/connectors/visualstudioteamservices/#http-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92-azure-devops-%E3%81%AB%E9%80%81%E4%BF%A1%E3%81%97%E3%81%BE%E3%81%99)から呼び出してもうまく動きません。
よくみたところ、APIのエンドポイントがdev.azure.comではなくvsaex.dev.azure.comになっています。コネクタからはURLの一部しか渡していないため、おそらくこれが原因でしょう。

# 動いた方法

なので、Azure DevOpsコネクタは諦めて、HTTPコネクタを使用しました。認可はPATを用いることで可能だったのですが、コネクタの制約でユーザー名を省略できなかったため、RAWを指定して自分でヘッダーに与える値を生成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3087724/7a6cffea-271a-e00a-4c34-101dd65a7242.png)
式の中身
```
base64(concat(':', variables('PAT')))
```