OmniAICreator/Qiita-1.07M huggingface dataset:
海外PCでキーボードレイアウトについて学んだこと

# 概要
以前も、リモートに入るとUSキーボードのレイアウトになっていたり、ちょいちょいキーボードレイアウトのずれに悩まされることがありましたが、そんなに使う頻度も高くないのでキーを覚えたりしていました。

海外に来て、職場のPCがキートップの表記通りに打てず、どうしているのか聞いてみると、＠を打つにはShift+2だと説明しているそうでした。
いやそりゃ流石になんかやりようがあるでしょうと思い、いろいろ触ってみたことのメモです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/ae05df23-612b-665d-a9eb-5625000ccdbd.png)
※Windows 11です。

# UKキーボードだった！
DELLのPCでキートップにはポンド（£）やユーロ（€）の表記があります。最初の設定はLanguageがEnglish(Botswana), Keyboard がUnited Statesでした。たぶん。（いろいろ入れ替えたのでちがったかも）

このキーレイアウトは一般的に何と言うのかも調べきれず、いくつか見たサイトから、キーボードの追加でいろいろなレイアウトを試してみたところ、English (United Kingdom)を選ぶとキートップ通りに入力できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/76f92802-7e74-8907-6923-1dbf5fdbcbac.png)

何かで必要になることもあるかとJapanese - Microsoft IME も入れましたが、Language Packの中にあるキーボードレイアウトは追加された順でOS起動時に最初のレイアウトが選択されるようなので、United Kingdomが先頭に来るよう他を削除して、Setswanaを追加しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/5bae2ad6-5b77-58c2-1825-1fbd5293bf9a.png)

# キーコンビネーション
ところで特定のキーボードでは、シングルクォート（’）を２回押すとダブルクォート（”）が入力されました。

これは何だろうと思っていたのですが、発見しました！

ウムラウト（¨）など、アルファベットの上に記号がのる表記をする文字のある言語で、これらの文字を入力する場合は、まず特定のキーを押し、続いて文字を押すと、記号がのった文字が入力されました。

> Ke bidiwa Kabêlô
> Ke a leboga!

「ê」を入力するときは、Shift+6（＾）に続いて（e）を押します。

このようなキーコンビネーションが含まれるキーボードということだったのですね。

# おまけ
Microsoft IMEの設定に、懐かしの「ATOK」があった！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/01384761-69a6-cc39-2cfa-df49e4e76826.png)
DALL-E3の結果画像をJSON圧縮画像文字列データに変換する方法

この記事では、DALL-E3から提供されるBase64 JSON形式の画像結果を、Webページの表示やストレージに適した圧縮画像文字列に変換する効率的な方法について説明します。このプロセスは、アプリケーションの帯域幅とストレージ要件を犠牲にすることなく最小限に抑えたい開発者にとって特に有用です。以下に説明する方法では、Python Imaging Library（PIL）、またはPillowとしても知られるライブラリを使用してこの圧縮を実現します。

# 前提条件
開始する前に、システムにPythonがインストールされていること、およびPillowライブラリがpipパッケージマネージャーを使用してインストールされていることを確認してください：
```bash
pip install pillow
```

# ステップバイステップガイド

## 1. Base64 JSON画像データのデコード
最初のステップは、DALL·E 3から受け取ったBase64エンコードされたJSONデータをbase64.b64decode()関数を使用してデコードすることです。
```python
import base64
from PIL import Image
from io import BytesIO

# 'response.data[0].b64_json'がDALL·E 3から受け取ったBase64 JSONデータであると仮定
image_data = base64.b64decode(response.data[0].b64_json)
```

## 2. PIL画像への変換とリサイズ
次に、デコードされたデータをPIL画像オブジェクトに変換します。このオブジェクトを使用して、画像を簡単に操作できます。例えば、画像の寸法を縮小してファイルサイズを減らすことができます。ここでは、画像を256x256ピクセルにリサイズします。
```python
pil_image = Image.open(BytesIO(image_data)).resize((256, 256))
```

## 3. 圧縮してBase64に再変換
リサイズ後、JPEG形式で画像を保存し、特定の品質レベルを指定して圧縮します。ここでは、画質とファイルサイズのバランスが良い80の品質を使用します。画像はBytesIOオブジェクトに保存されます。これは、メモリ内のバイナリストリームとして機能します。
```python
image_data = BytesIO()
pil_image.save(image_data, format='JPEG', quality=80)
compressed_image = base64.b64encode(image_data.getvalue()).decode('utf-8')
```

## 4. 圧縮画像文字列の作成
最後に、必要なデータURIスキームdata:image/jpeg;base64,を圧縮されたBase64文字列の前に追加します。これにより、HTML画像要素で直接使用できる完全な画像データ文字列が作成され、必要に応じて保存できます。
```python
str_image = 'data:image/jpeg;base64,' + compressed_image
```
# 結論
これらのステップに従うことで、DALL·E 3の画像結果をより管理しやすい形式に効果的に圧縮することができます。これにより、ネットワークおよびストレージリソースの使用を最適化しつつ、高いレベルの画像品質を維持できます。Webアプリケーションの開発を行っている場合でも、単に大量の画像を効率的に保存したい場合でも、この方法は実用的な解決策を提供します。
Gradle7.5.1 で Java17+SpringBoot3.2.2+QueryDSL5.1+Hibernate6+lombok を動作させるための build.gradle の記述

世界の web に載っている情報が断片的で、すべてを網羅する設定をするにはどう書けばいいかにたどり着くのに何日もかかって何度も心が折れそうになったのでここに書き残します...同じことで困っているどなたかのお役に立てば幸いです。

流行りの組み合わせなので次以降に参画するプロジェクトでも役に立つかもしれず、未来の自分のためにも差しさわりのない汎用的な部分だけ書き出しておくとします。

``` gradle build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.2'
}

apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'

sourceCompatibility = '17'

publishing {
   publications {
        maven(MavenPublication) {
            groupId = '[任意]'
            artifactId = '[任意]'
            version = '[任意]'
            from components.java
        }
    }
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/release' }
    maven { url 'https://repo.spring.io/milestone' }
    maven { url 'https://repo.spring.io/snapshot' }
}

ext {
    // QueryDSL が自動生成したクラスの格納場所
    javaGeneratedSources = file("$projectDir/src/main/generated")
}

dependencies {
    // スターター(関連するclasspathを自動設定)
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')

    // Spring 関連
    implementation('org.springframework.data:spring-data-commons')
    implementation('org.springframework.data:spring-data-jpa')

    ///////////////////////////////////////////////////////////////////////
    // hibernate (DB セクセスの仲介をする。
    // EntityManager との連携に必須
    implementation('io.hypersistence:hypersistence-utils-hibernate-60:3.7.3')
    implementation('org.hibernate.orm:hibernate-core')

    // lobmok
    // @Log や @Data (getter/setter) をサポートしてくれるライブラリ。
    implementation     ('org.projectlombok:lombok')
    annotationProcessor('org.projectlombok:lombok')

    // Entity (永続化) 周りの API。
    // EntityManager や @Entity, @Table @Column @PersistenceContext などサポートしている。
    implementation     ('jakarta.persistence:jakarta.persistence-api')
    annotationProcessor('jakarta.persistence:jakarta.persistence-api')

    // QueryDSL
    // SQL を自動生成するのをサポートするライブラリ。@JpaQuery など。
    // 内部が EE8(javax) パッケージで動作する仕様になっているため、classifier として 
    // jakarta を指定しすることで EE9(jakarta) でアクセスできるようになる。
    implementation('com.querydsl:querydsl-core:5.1.0')
    annotationProcessor('com.querydsl:querydsl-apt:5.1.0:jakarta')
    annotationProcessor('jakarta.annotation:jakarta.annotation-api')

    // これも必要 java のクラスを xml で処理可能にするライブラリ
    // Hibernate/DSL 周りで使用される
    implementation('org.glassfish.jaxb:jaxb-runtime:4.0.4')
    ///////////////////////////////////////////////////////////////////////

}

compileJava {

    // 初期化
    doFirst {
        delete javaGeneratedSources
        javaGeneratedSources.mkdirs()
    }

    // annotationProcessor へのクラスパスを追加
    classpath += configurations.annotationProcessor

    options.compilerArgs += [
            '-parameters', '-s', javaGeneratedSources
    ]
    options.compilerArgs += [
            '-processor', 'com.querydsl.apt.jpa.JPAAnnotationProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor'
    ]
}

clean {
    doFirst {
        delete javaGeneratedSources
    }
}

sourceSets {
    main {
        java {
            srcDir 'src/main/generated'
        }
    }
}

```
laravelにswaggerを導入してAPIの仕様書作成とテストをする

## swaggerとは
swaggerはRESTなAPIの
・仕様書を作成。
・テストを実行。
ができます。


## laravelにswaggerインストール

```powershell:コマンドプロンプト
composer require "darkaonline/l5-swagger"
```

jsonではなくyamlで扱いたいので.envに以下を追加。
```php:.env
L5_FORMAT_TO_USE_FOR_DOCS = yaml
```

## swaggerでAPIの仕様書を表示
/api/documentation　にアクセスするとswaggerの表示を確認できます。
このようにシンプルな画面でAPIの仕様書を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/caf63623-469c-57f1-f54d-8c644a617ec1.png)

\storage\api-docs\api-docs.yaml
の内容が表示されます。

## swaggerのyamlファイルの書き方
（オンラインエディタを使っても便利 https://editor-next.swagger.io/）
\storage\api-docs\api-docs.yaml
の内容を編集していきます。

```yaml:yaml
openapi: 3.0.0
info:
  title: H1タイトル #H1
servers:
  - url: http://localhost/api/ #url
    description: ローカル開発環境 #urlのdescription
paths:
  /test: #パス
    get: #メソッド
      summary: H2タイトル #H2
      parameters: #get情報
      - name: page
        in: query # getで渡される
        # in: path # urlに埋め込まれる
        # required: true
        schema:
          type: integer
          # type: boolean
          # type: array
          # type: object
      requestBody: #post情報
        # required: true #必須
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: "なまえ"
                description:
                  type: string
                  example: "詳細"
      responses: #レスポンス
        '200': #200が返ってきたら
          description: OK
          content:
            application/json: #返ってきたデータをjsonとして表示
              schema:
                $ref: '#/components/schemas/testsResponse' # ★が表示される
        '404':
          description: not found
        '500':
          description: サーバーエラー
#   post: #メソッド
#     summary: H2タイトル #H2
#     .....
#
# /test2:
#   get:
#   .....

components:
  schemas:
    testsResponse: # ★ここ
      type: object
      properties:
        data:
          type: object
          properties: # この形式で返ってくるよ。
            id:
              type: integer
              format: int
              example: 1
            name:
              type: string
              example: わたしの名前
```


## swaggerでAPIのテスト
APIのテストは
「Try it out」をクリック

![スクリーンショット 2024-02-29 151017.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/add11d0c-7441-06f0-eacc-c70d5d109ccc.jpeg)


「Execute」をクリック


![スクリーンショット 2024-02-29 151046.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686263/44eb35a3-6dc8-b89f-c971-3fb4c992d475.jpeg)

これでAPIの実行結果が表示されます。

## 

このようにAPIの仕様書を見やすくまとめてテストまで出来るswagger。
是非活用してみてください。
Vite+Firebaseで躓いた話

# はじめに
Vite + Firebaseの環境で、FirebaseのRealtime Databaseに接続できない問題発生したので、それを解決する。

# 詳細
Vite + TypeScript + Firebaeがベースの環境で、Phaser3を追加し、マルチプレイができるゲームを簡単に作ろうとしていた。
Viteのdev環境でRealtime Databaseにアクセスしようとすると、`net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep 200 (OK)`とレスポンスエラーが出る。
ビルドしたものは正常に動作する。

# 結論
Viteのdev環境でのデフォルトのポート番号が悪さしてるっぽい？
`vite.config.ts`に以下のように追記。

```diff_typescript:vite.config.ts
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    assetsInlineLimit: 0,
  },
  base: "/phaser-multiplayer-test/",
  envDir: "./",
+ server: {
+   port: 5500,    //デフォルトは5173
+ },
});
```
よくわからんけど動いたからOK！
【Next.js】テスト実行時のみbabelの設定が効くようにしたい

# はじめに

こちらの記事の補足となります

https://qiita.com/does_not_exist/items/d681da6a5d0e6f97f270

テストが通るところまで出来たのですが、
ローカルサーバを起動すると以下のエラーが発生しました

---
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


# 解決方法

テスト実行時のみbabelの設定が効くように修正

```diff:babel.config.js
module.exports = {
-    presets: [
-        ["@babel/preset-env", { targets: { node: "current" } }],
-        ["@babel/preset-react", { "runtime": "automatic" }]
-    ],
+    env: {
+        test: {
+            presets: [['@babel/preset-env', {targets: {node: 'current'}}], ["@babel/preset-+react", { "runtime": "automatic" }]],
+        },
+    },
};

```

```diff:next.config.js
+  experimental: {
+    forceSwcTransforms: true,
+  },

```

# 原因
babelの設定ファイルがあるとNext.jsが強制的に参照してしまうようでした

https://nextjs.org/docs/messages/swc-disabled

# 参考記事

https://qiita.com/riversun/items/6c30a0d0897194677a37

# おわりに
今回はさくっと解決できたので良かったです
モバイル端末の適応：remレイアウトの戦略

## 背景
　  携帯の画面では、画面サイズが異なるため、通常のpxをレイアウト単位として使用すると、異なる画面で予期しない表示効果が生じる可能性があります。

##### 例

* ブラウザのモバイルモニターで、iPhoneSEを使って、画面の文字列 "www..." は、、行全体をきちんと埋めることができます。
    ![iphone se](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/d4d4f930-c8ed-fda5-c320-c87fad175365.png)


* そして、iPhone14 Proに切り替えると、文字列の後には明らかな空白が生じることがわかります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/2f57d4c5-73c8-8f66-5ec0-06dcf7045c1e.png)

ソースコードは下記になります
```react
function Index() {
  return (
    <div className="page page-home" style={{fontSize:'16px'}}>
      wwwwwwwwwwwwwwwwwwwwwwwwwwwww
    </div>
  )
}
```

:::note info
結果として、pxをフォントサイズの単位として使用すると、異なる携帯の画面では異なる表示がされ、そしてページレイアウトが予想と異なる表示になることがあります。
:::

## 解決案　remレイアウト
入口のJSファイルに次のコードを追加すると、rem単位を使用し、iPhone SEの画面サイズ（375px）を基準にレイアウトを行うことで、上記の互換性の問題を解決できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/e47bf00c-d06b-622c-1d92-9eb3dfa66aa7.png)
対応するページのレイアウト単位をpxからremに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/05622c6b-39a7-3aed-7306-16614099cd95.png)

そしてモニターを使ってremレイアウトの結果を確認します。大画面の携帯(iPhone 14pro)に切り替えたときに前残っていた余白が消えて、互換性の要件が満たされていることが確認できます。
* iPhone SE（切り替え前）
![iPhone SE（切り替え前）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/aaf34681-7659-117f-4fac-3be93cff9aef.png)
* iPhone 14pro（切り替え後）
![iPhone 14pro（切り替え後）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731244/3f2aed6e-5814-4245-55ba-3c3db3ad6756.png)

## 要点説明
1. remレイアウトを計算する際には、基準として100pxを使用すると、pxとremを相互に変換する際に対応する数値を計算しやすくなります。
2. 通常、iPhone SEのような小さな画面の携帯電話を基準としてレイアウトを行います。なぜなら、小さな画面でレイアウトに問題がなければ、相対的に大きな画面でのレイアウトの非互換性の可能性も低くなるからです。
3. jsのwindowオブジェクトのresizeイベントなどの画面変更に関連するイベントを忘れずにリスニングするように注意する。

　　以上が私のページレイアウトに関するの共有です。もし日本語の文法に問題があれば、皆さんに修正していただけると嬉しいです。最後までご覧いただきありがとうございました。
【Blazor】Layoutに@rendermodeを追加したときにとInvalidOperationExceptionになる理由


タイトルのケースはかなり特定されていますが、エラー原因自体は、**異なるRender Mode間の情報受け渡し**に関するもので、学びが深かったので記事にしました。

## 環境

VS2022のBlazor Appテンプレートからプロジェクトを作成します。

Render Modeは**WebAssembly**を選択してください。


## エラーを再現

### 実装

- Layout

ClientプロジェクトにLayout Componentを作成します。

```c#:Client/Components/Layout/ClientMainLayout.razor
@inherits LayoutComponentBase

<h1>ClientMainLayout</h1>

@Body
```

```c#:Client/Components/Layout/SpecifiLayout.razor
@inherits LayoutComponentBase
@* 以下の参照をしたいので、DefaultとなるLayoutをClientプロジェクトに移動しています。*@
@layout ClientMainLayout
@* そしてWebAssembly Componentとしたい *@
@rendermode InteractiveWebAssembly

<h2>SpecificLayout</h2>

@Body
```

- Component

上記のLayoutを参照するPage Componentを生成します。

```c#:Client/Pages/Component.razor
@page "/component"
@layout BlazorAppError.Client.Components.Layout.SpecificLayout

<h3>Component</h3>
```

- Routes

次に、Mainプロジェクト側の`Routes.razor`の`DefaultLayout`に上記のComponentを指定します。

ちなみに、デフォルトでMainプロジェクトはClientプロジェクトをDependencisに入れているため以下の参照が可能となっています。

```c#:Components/Routes.razor
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(Client.Components.Layout.ClientMainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>
```

### 実行

Rootでは`ClientMainLayout.razor`が問題なく反映されていることが分かります。

そこから、`/component`に遷移すると、エラーが発生しますね。

>An unhandled exception occurred while processing the request.
InvalidOperationException: Cannot pass the parameter 'Body' to component 'SpecificLayout' with rendermode 'InteractiveWebAssemblyRenderMode'. This is because the parameter is of the delegate type 'Microsoft.AspNetCore.Components.RenderFragment', which is arbitrary code and cannot be serialized.

## 原因

ポイントは2つです。

- Static ServerとInteractive WebAssemblyのRender Mode`@Body`をCascadingしている
- `@Body`はシリアライズできないContent

[公式ドキュメント](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/cascading-values-and-parameters?view=aspnetcore-8.0#cascading-valuesparameters-and-render-mode-boundaries)に述べられているケースに該当します。

`@Body`の内容は**Jsonシリアライズできない**ため、Static ServerとInteractive WebAssebly間では**やり取りできない**ということです。上記のエラーにも"**is arbitrary code and cannot be serialized**"と書いていますね。

### 対応方法

幸いにも、`@Body`に対して何かを積み重ねる必要がなかったので、`@rendermode InteractiveWebAssembly`が必要なComponentを**別で生成**し、**対象のLayoutから呼ぶ**という方法で回避できました。

エラー再現コードを修正すると以下のようになります。

```c#:Client/Components/Layout/SpecificComponent.razor
@rendermode InteractiveWebAssembly

<h2>SpecificLayout</h2>
```

上記で生成したComponentをLayoutから呼び出す。

```c#:Client/Components/Layout/SpecifiLayout.razor
@inherits LayoutComponentBase
@layout ClientMainLayout

<SpecificComponent />

@Body
```

実行するとエラー無しで想定通りの動きができていますね。

## 最後に

このエラーに遭遇したときは、Layout Componentに`@rendermode`は適用できないのかと諦めていました。

色々試しているうちに、対応方法にたどり着き、暇な時間にドキュメントを読んでいて「これだ！」となった感じです。

Blazorは置く深すぎるので、ドキュメント流し読みも効果ありです！
【ChatGPT有＋DALL-E3】が不調だよー


　どうも、カーブミラーです。

　今回は、ChatGPTとDALL-E3の不調をお送りします。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　今日から三月です。
　　それがどうした、
　　　生活も仕事も変わらんわ！

　と気合いを入れてw
***
　ということで
　　まずは、ニュースから。

　ドジャースの大谷選手が
　　昨日（2024/02/29）、
　　　結婚を発表しました。
　　　　お相手は日本人女性とか。
　　　　　おめでとうございます🎉
***
　では
　　AI関連ニュース。

　米国の汎用人型ロボット開発会社
　　Figureをご存知でしょうか。

　MicrosoftとOpenAIが
　　出資していました。

　また、このロボットには
　　GPTが使われているそうです。

　今回ニュースになったのは、
　　6億7500万ドルを
　　　調達したことです。

　出資企業は、
　　Jeff Bezos、
　　Nvidia、
　　Microsoft、
　　OpenAI
　　　などから。﻿

　ビデオを見ましたが
　　動きはスムーズで
　　　一線を画した制御が
　　　　行なわれているのが
　　　　　わかります。

　そこにGPT使用ですから
　　今後の学習に、
　　　こうしたロボットからの
　　　　実地経験が加わっていく
　　　　　ことを考えると、
　　　　　　画像生成AIが生成する
　　　　　　　画像はより良くなる
　　　　　　　　気がします。
***
　DALL-E3が、
　　Soraに置き換わるのでは
　　　ないかという話もあります。

　Instagramにアップされた
　　Soraが作った静止画の
　　　概要に“2048×2048も描ける”
　　　　というようなことが
　　　　　書いてあるので、
　　　　　　根拠のない話でも
　　　　　　　ありません。

　今後、
　　どうなっていくことでしょうか。
***
　そんなことよりも
　　現在（AM 11:00）です。

　ChatGPTさんは
　　ちゃんと動いているのに
　　　DALL-E3さんがダメダメ君です。

　症状としては
　　過去のセッションを
　　　呼び出すと、
　　　　画像が表示されない。

　何度もやって
　　再ログインして、と
　　　やりました。

　そこで
　　描画をさせて
　　　みました。

　こんな風に
　　なりました。
![1709260742072.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/e87c5d6e-3a7a-e011-15f3-81d43fd5c997.jpeg)

　“画像を生成できません”的な
　　メッセージです。

　要するに
　　DALL-E3さんが
　　　ストライキをしている
　　　　みたいですね。

　メンテナンス中なのかな？

　とにかく、
　　記事の先が
　　　書けません。

　ごめんなさいm(_ _)m

　いや
　　たいした記事ではないので
　　　中途半端で、アップしても
　　　　いいのですが、
　　　　　やはり気持ち的に、ねぇw

　ということで
　　内容がないようなので
　　　（ダジャレか！）
　　　今回は、ここまで。

　ごめんなさいm(_ _)m
Excel (マクロVBA)最初の一歩

# アプリによっっては動かない
**XLSX Editor Sheet Reader** が動かせたので載せます。
アプリによっては**セキュリティの設定項目がなかったり**、または**アプリの存在位置が分からない**などが、ありました。

### 動かすまでの写真を出します。

![スクリーンショット 2024-03-01 104243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/684b2604-99ff-bca2-e319-db2574c9633c.png)
起動。読み込み「共通利用できる**Excel_366_ok.xlsx**」読み込みます。これは、macroが動かないので名前を変えて「旧型式**Excel_365_bad.ods**」とします。
![スクリーンショット 2024-03-01 095221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/fb3f2629-0524-f622-a319-bf490806d838.png)
セルにbuttonとして使えるイメージを入れておきます。
![2024-03-01 (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/766ca0c3-1447-2a2b-175f-8f7444b787ed.png)
**ツール**から、**マクロ**を選びます。がその前に**オプション**セレクトの**セキュリティ**を弱め実行できるようにします。
![2024-03-01 (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/6a941357-c242-4754-754a-1124fb1977c0.png)
![スクリーンショット 2024-03-01 100744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/319c2fb8-d6ee-7cc6-a9dc-fafb4bed1a5f.png)![スクリーンショット 2024-03-01 100930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/05e92f0b-46bd-0622-88fc-4826cfec1704.png)
macroにスクリプトを書き込みます。
![スクリーンショット 2024-03-01 095635.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/347eb285-f640-9b37-8aa7-b93359538f73.png)
割り当てbuttonを押します。
![スクリーンショット 2024-03-01 100011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/75cd946c-afb3-7108-4c2d-a25b6d500bdc.png)
管理buttonを押します
![2024-03-01 (36).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/a1701e6f-e339-4e45-cd49-1b3e0805080f.png)
選択して、割り当てボタンを押して
![スクリーンショット 2024-03-01 101334.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/c5cb523d-1cba-e944-ea5f-360c220be7b7.png)

![スクリーンショット 2024-03-01 112221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/e512f4ff-5d2b-9cf4-d380-10e8347468b5.png)
女の子の上で、右クリックメニューを開いて一番下の**マクロの割り当て**を行います。

## ここで、いったんすべてを保存して、シートを閉じます
**Excel_365_bad.ods**を開きなおします。![スクリーンショット 2024-03-01 102436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/4a827ee4-7180-4c88-e43a-8683a74aff3b.png)
女の子をクリックすると、macroが動き、表示が出る様になります。。

____________
以上で、いったん終わります。

本を買って来なくては難し過ぎて分からなくなりました。
Docker環境で環境変数を扱う

# はじめに
<!-- 発端や概要を記載 -->
より便利によりセキュアなシステムを作る上で環境変数は非常に重要です。
今回はdocker環境での環境変数の扱いかたについて解説していきたいと思います。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [環境変数とは](#Chapter1)
1. [envファイルで環境変数を扱う方法](#Chapter2)
1. [dockerfileでENVを用いて環境変数を扱う方法](#Chapter3)
1. [おまけ AWSでの環境変数管理](#Chapter4)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 環境変数とは
OSが設定値などを永続的に保存し、利用者や実行されるプログラムから設定・参照できるようにしたもの。プログラムの実行時などに必要となる、利用者やコンピュータごとに内容が異なる設定値などを記録するために用いられるとのこと。
APIキーやパスワードなどソースコードに直接書かないときに使うことが多いです。またenvファイルは.gitignoreで指定して、github等で公開しないことがほとんどです．

<a id="#Chapter2"></a>
# envファイルを用いて環境変数を扱う方法
今回は例としてfastapiでデータベースへ接続を行う際のデータベースの情報を.envファイルで管理します．
まずdockr-compose.ymlに環境変数を参照する先を書きます
docker-compose.yml
```
version: "3"
services:
  api:
    env_file:
      - ./api/.env
```
次に.envにデータベースへ接続するための情報を書きます
.env
```
DB_USER="mysqluser"
DB_PASSWORD="mysqlpass"
DB_HOST="db:3308"
DB_NAME="sample_db"
```
db.py
os.environ.getで.envに記述した情報を取得します．
```
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from dotenv import load_dotenv
import os

load_dotenv()

user = os.environ.get("DB_USER")
password = os.environ.get("DB_PASSWORD")
host = os.environ.get("DB_HOST")
db_name = os.environ.get("DB_NAME")

DATABASE = 'mysql://%s:%s@%s/%s?charset=utf8' % (
    user,
    password,
    host,
    db_name,
)

ENGINE = create_engine(
    DATABASE,
    echo=True
)

session = scoped_session(
    sessionmaker(
        autocommit=False,
        autoflush=False,
        bind=ENGINE
    )
)

Base = declarative_base()
Base.query = session.query_property()

```


<a id="#Chapter3"></a>
# dockerfileでENVを用いて環境変数を扱う方法
こちらの方法はシンプルです．主観にはなりますが、envファイルを用いたやり方の方が主流だと思います．
Dockerfile
```
FROM python:3.7

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
```
docker-compose.yml
```
version: "3"
services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: sample_db
      MYSQL_USER: mysqluser
      MYSQL_PASSWORD: mysqlpass
```

<a id="#Chapter4"></a>
# おまけ　AWSでの環境変数管理
アプリケーションをAWSでデプロイする際、秘匿したい情報は次のサービスを利用します．
AWS System Manager Parameter Store

<a id="#reference"></a>
# 参考文献
- [環境変数とは](https://e-words.jp/w/%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0.html)
- [aws system manager parameter store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)
任意の座標のpixel情報を入れ替える

# source

```java:swapPixelsTest.pde
/**
 * 任意の座標の色情報を入れ替える
 */
int COLORS[] = {
  color(255, 0, 0),
  color(0, 255, 0),
  color(0, 0, 255),
  color(255, 255, 0),
  color(255, 0, 255),
  color(0, 255, 255),
  color(255, 255, 255),
};

// 取得元の開始座標
PVector swapSourcePositions[] = {
  new PVector(120, 0),
  new PVector(320, 0),
};

// 入れ替え先の開始座標
PVector swapDestPositions[] = {
  new PVector(240, 0),
  new PVector(540, 0),
};

// 入れ替える縦横サイズ
PVector swapSize = new PVector(10, 350);

void settings() {
  size(700, 350);
}

void setup() {
  background(0);
  noFill();
  stroke(0);

  // 色付きのバーを描画
  drawColorfulRectBars();
  
  // 任意の座標のpixelsを入れ替える
  doSwapPixels();
}

void draw() {

}

void drawColorfulRectBars() {
  for (int i=0;i<COLORS.length;i++) {
    fill(COLORS[i]);
    rect(i * 100, 0, (i + 1) * 100, height);
    
    fill(255);
    text("[" + (i * 100) + ", 10]", i * 100 + 5, 15);
  }
}

void doSwapPixels() {
  int[] sourcePixels = new int[int(swapSize.x * swapSize.y)];
  int[] destPixels = new int[int(swapSize.x * swapSize.y)];

  loadPixels();
  for (int i=0;i<swapSourcePositions.length;i++) {
    for (int incY = 0;incY < int(swapSize.y); incY++) {
      int sourceY = int(swapSourcePositions[i].y) + incY;
      int destY = int(swapDestPositions[i].y) + incY;
      
      for (int incX = 0;incX < int(swapSize.x); incX++) {
        int sourceX= int(swapSourcePositions[i].x) + incX;
        int destX = int(swapDestPositions[i].x) + incX;
        
        sourcePixels[i] = pixels[sourceY * width + sourceX];
        destPixels[i] = pixels[destY * width + destX];
        
        pixels[destY * width + destX] = sourcePixels[i];
        pixels[sourceY * width + sourceX] = destPixels[i];
        
        //print(String.format("[%03d, %03d] -> [%03d, %03d] /// ", sourceX, sourceY, destX, destY));
      }
      //println();
    }
  }
  updatePixels();
}
```

# doSwapPixels()を無効にした場合(単純に色付きバーを描画した場合)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915/f3cb4307-8887-43eb-67a1-ebe5aaf27c9b.png)

# doSwapPixels()を有効にした場合

![スクリーンショット 2024-03-01 11.40.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915/201b21c8-85b7-7917-8123-c6bd86994a5f.png)
Marketing Cloudでメールコンテンツの日付形式を変えたいですけど！？

## ジャーニーメールコンテンツの日付形式が変
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/cbd79967-5680-8fbe-b9c6-c167c407fc37.png)

## 何でだろう
Salesforceから同期してきた日付を、SQLクエリで何も加工せずに、DEのDate項目に入れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/204238a0-f87e-3dbe-f6af-a546aaaa4a30.png)

それをメールコンテンツに差し込んだら、上記のように、年月日以外の余計なものがついていますね。

## こうしよう
#### １．SQLクエリ変更
FORMAT(xxx_date__c, 'd', 'ja-JP') AS "xxx日"

#### ２．DEのデータ種別変更
日付項目のデータ型をDate　→　Textに変更

#### ３．できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/0d27b1c4-48fd-164e-cb13-11b60cfe5a7f.png)

## 補足なら
Salesforceから同期してきた日付の形式：Mar 29 2024 12:00AM
MC側のDEの日付の形式：3/29/2024 12:00:00 AM
なので、SQL変更ステップでyyyy/MM/dd形式に変換しても、DEのデータ型がDateのであれば、メール日付の形式が正しく表示されません。

## もっと簡単なやり方
コンテンツ編集時、下記AMPscriptコードを入れるだけで、上記１も２も不要になりますね。
%%=FormatDate(xxx日,"yyyy/MM/dd")=%%
@skykidさん、ありがとうございます。
【新卒1年目】AWSプロ資格合格と、新米1年の振り返り


この度、AWS DOPに合格しました！😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/ad18f465-e3d6-6c3b-fede-37b4874b9279.png)

そこで、どのように新卒エンジニアが成長してきたか。
新卒１年目エンジニアがどのような仕事を任せてくれるのか。
についても書いていこうと思います。

#### 1.簡単な自己紹介

初めに、軽く自己紹介をさせていただきたいと思います。

大学時代は法学部に所属し、国際法・国際政治を学んでいました。

そして法学部を卒業し、2023年4月にSEとして富士通に入社しました。
（国会でインターンしたりスタートアップで働いたり色々ありますがまた今度で、、）

そのため、**ITの知識はありましたがエンジニアとしては初心者**でした。

もともとAWSに興味を持っていたこともあり、配属希望ではAWSを扱う業務を希望しました。

この記事では、配属されてからの資格のロードマップやAWS構築プロジェクトで任せて下さった仕事などについて述べていきたいと思います😉

#### 2.資格について

以下が8月に配属されて以降の資格取得実績になります。

| 月 | 資格 | 
|:-:|:-:|
| 8  | AZ-900  | 
| 9  | 基本情報技術者  |
| 10 | AZ-104  |
| 11 | 社内資格（Agile)  |
| 12 | AWS SOA  |
| 1 | AWS DVA  |
| 1 | AWS PAS  |
| 2 | AWS DOP  |

着実にITの知識と、クラウドの知識を積み上げています。

ただ実務をしていると、資格で学んだ理想像では通らないことがほとんどなので、
資格はあくまで**知識を体系的に学ぶ手段**と捉えております。

次に、今後の資格取得目標を宣言したいと思います！

| 月 | 資格 | 
|:-:|:-:|
| 3 | AWS SCS | 
| 4 | AWS SAP |
| 5 | AWS ANS |
| 6 | AWS MLS  |
| 7 | AWS DEA  |
| 10 |  応用情報技術者 |

7月で今現在発表されている状況だと**AWS全冠達成**します。
そして10月までは応用情報技術者の勉強に費やしたいと思っております。

#### 3.新卒１年目のAWSプロジェクトについて

これについては気になる方も多いと思います。

結論から言いますと、AWSへのリプレース大規模PJにおいて**インフラ構築の多くを任せていただけました！**

僕自身、大企業のSEは初めは議事録しかできないのではないかと思っていたのですが、
上司やトレーナーの方に恵まれて、様々な経験をする機会を与えていただけました。

2か月間の業務内容を簡単に列挙すると以下になります。

・方式設計書作成
・詳細設計書作成
・複数台のEC2払い出し
・セキュリティグループのルール設定
・EFS構築・マウント
・CloudWatchダッシュボード作成
・OS構築手順書作成・翻訳
・OS構築	(Linux)
・単体テスト仕様書の作成・テスト
・VPCピアリング手順書作成
・海外メンバーへのOS構築教育・指導

他にもさまざまなプロジェクトに関わらせていただけました。

大企業でも自分の思い次第で、タスクの振りを対応してくださる風土ができつつあります！

#### 4.さいごに
僕自身、この半年間周りの方に助けていただきながら仕事を行ってまいりました。

今後もそうなるとは思いますが、何か貢献できることはないかを意識して行動していきたいと思っております。

ここまで読んで下さりありがとうございます😊
車検証のQRコードを生成してみる

## QRコードについては以下
前回は、QRコードを読み取るため、QRコードの仕組みを解説してみました。

https://qiita.com/f_uto/items/319c76fa1807e3f70d63


## 今回は、そのQRコードを生成してみます
車検証の普通車の車検証の場合は、分割（連結）QRコードと言う仕様となっており、軽自動車および軽自動車ICカードの車検証は、通常のQRコードという仕様です。

QRコードはデンソーウェーブの登録商標です

QRコードの仕様は公開されているものの、分割QRコードがあまり利用されていないようで、QRコード生成ライブラリも分割でないQRコード生成はたくさんありますが分割できるものが有りませんでした。

そこで、zxingライブラリのjsバージョンを元に分割QRコードを生成できるようにカスタマイズしました。

https://github.com/zxing-js/library



車検証QRコード生成ツールは、githubにてソースコードおよびwebとしても公開してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/c8869bda-6dd0-6de3-e049-32f360c119c0.png)


### 動作URL（実際に動くものを確認できます）

https://fokazaki2.github.io/zxing-js-qrcode-writer-demo/website/


### github

https://github.com/fokazaki2/zxing-js-qrcode-writer-demo


またテストしやすいようにGoogle Spreadsheetを用意し、データを管理可能としています。今回は、ナンバープレートの情報と初度登録年月、型式指定番号、類別区分番号のみ書き換えできるようにしています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/cfa53fd4-545a-e723-acd4-9e441e8c579e.png)


:::note info
B列：車種「普通自動車」 ・「軽自動車」のどちらか選択
C列：ナンバープレート情報
D列：初度登録年月 年２桁、月２桁の４桁
E列：型式指定番号
F列：類別区分番号

*Google Apps Scriptにて、列番号固定してます
:::




# コード解説
## ZXing-js libraryの改修
ZXingが更新されなくなっていたので、forkして改修していこうかと思いましたが、とりあえず急ぎで対応が必要だったのもあって、buildした１つのjsファイルを色々いじってみました。


分割QRコードについては以下を参考にさせていただいています。

https://programresource.net/2013/05/04/2193.html

```zxing.js
    const headerBits = new BitArray();
    // Add code page info
    const tmpbyte = 0x3; // 分割QRコードであることを示す 0x3
    headerBits.appendBits(tmpbyte, 4);
    headerBits.appendBits(page, 4);         // 分割されたページ番号 0スタート
    headerBits.appendBits(total_page - 1, 4);   // 最大pege番号（分割数 -1）
    headerBits.appendBits((parity&0xf0)>>4, 4); // parityの上位4bit
    headerBits.appendBits(parity&0x0f, 4); // parityの下位4bit         
```

もともと「headerBits」を定義していましたが、何もセットされていなかった、というのもあって、エンコード時の処理に上記のみです。

その他、引数で、分割数や分割位置を渡せるように改修したのみです。


## google apps scriptによるデータ取得について

もっと便利に利用したいというところから、Google Spreadsheetにデータを置いておき、そのデータを取得する仕組みを作りました。

こちらは、google apps scriptで実現できます。
google apps script(GAS)は、ExcelでいうところのVBAですが、オンライン上に存在することからデプロイという作業で、WEBアクセスができます。API化できるということです。（いろんな用途でも使えそうですね）

こちらはgitに配置しています。googlespreadsheet.gs

ウェブアプリとしてデプロイすれば参照できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/112dbd56-5d5e-6cdc-a775-eb92756abc7a.png)


githubで公開しているので、ご利用ください。
また、ここちょっとおかしいよ、こうしたほうがいいよとか、アドバイスもいただけますと幸いです。
rails transaction が rollback しないのは マルチデータベースだからかもしれない話

# Rails で意図的に fail させているのに rollback しない！

このようなコードを書いた時には確実に rollback しますが
マルチデータベースの場合は rollback が行われないこともあります。

```rb
ActiveRecord::transaction do
  User.last.update!(name: 'new name')
  raise 'hoge'
end
```


```rb
class User < UserDatabase
end
```

## トランザクションのスコープ
Rails では、トランザクションは特定のデータベース接続に紐付けられ
UserDatabase クラスまたはそのサブクラスでトランザクションを開始した場合
そのトランザクションは UserDatabase の 接続先DBでのみ有効になります


## 対象DBにつながっているクラスでトランザクションを開始する

ActiveRecord::transaction で開始するのではなく 
`User.transaction` や `UserDatabase.transaction` で開始する

接続先が UserDatabse なので正常に rollback します

```rb
UserDatabase::transaction do
  User.last.update!(name: 'new name')
  raise 'hoge'
end
```

こちらも同様に UserDatabse を継承している User モデルを利用するので
正常に rollback します

```rb
User::transaction do
  User.last.update!(name: 'new name')
  raise 'hoge'
end
```
【Databricks】 limitsを整理してみた

# 背景・目的
Databricksでも、AWSのクォータ同様に制限（limits）が存在します。
事前に、これらを整理しておきたいと思います。

:::note info
今回は、AccountやGroupを中心にまとめています。今後、ジョブやreposについても更新する予定です。
:::

# まとめ
下記に、AccountやGroupなどの　limitsをまとめます。

|# |Metric|Limit|Scope|
|:--|:--|:--|:--|
|1|IP Access List|1000|Account|
|2|IP Access List|1000|Workspace|
|3|Credential configurations|Standard:3<BR>Premium:11<BR>Enterprise:55|Account|
|4|Network configurations|Standard:3<BR>Premium:11<BR>Enterprise:55|Account|
|5|Storage configurations|Standard:3<BR>Premium:11<BR>Enterprise:55|Account|
|6|VPC endpoint registrations for AWS PrivateLink|110|Account|
|7|Private access settings for AWS PrivateLink|55|Account|
|8|Customer-managed key configurations for managed services and workspace storage combined|110|Account|
|9|Workspaces|Standard:3<BR>Premium:10<BR>Enterprise:50|Account|
|10|Direct group memberships|1500|Group|
|11|Groups|5000|Account|
|12|Layers of nested groups|10|Group|
|13|Users and Service Principals|10000|Account|


※ 詳細は、[Limits](https://docs.databricks.com/en/resources/limits.html)を参照してください。

## イメージ
### WorkspaceやAccountなど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b15c9648-dae3-3a9d-6c90-2e69950f9aab.png)

### GroupやPrincipalなど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f2328e6d-6f70-f068-468c-511d56553854.png)

# 考察
今回、Databricksのlimitsの一部をまとめてみました。
今後は、ジョブやreposについても調査し、更新していきたいと思います。


# 参考
https://docs.databricks.com/en/resources/limits.html
宜しくお願いします！

始めまして。これから本格的にプログラミングを学ぼうとしている亮と言います。今日は仕事が休みなので参考書を買いました。

1.問題解決力を鍛える！アルゴリズムとデータ構造
2.競技プログラミングの鉄則
3.Python3エンジニア認定基礎試験問題集
です。

新卒で入った某コンビニではマーケット分析を７年やってました。vbaの資格はもっており日々の業務の自動化も地道に進めていました。

今はマンション管理会社に勤めてますが、プログラミングに興味があり勉強を始めます。

これからどうぞ宜しくお願いします！
MetaMaskが起動しなくなった時の対処

## Chrome から MetaMaskが起動しなくなった
いつものようにChromeからMetaMaskのアイコンをクリックしたところ、下記のように読み込み画像が表示されたまま先へ進まなくなりました。
![スクリーンショット 2024-03-01 11.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731259/e1211e5d-3dda-668f-753f-7d4e1896f86f.png)

焦って色々と試した結果、MetaMaskを更新することで回復できました。

## 手順
### 1. 拡張機能管理でデベロッパーモードをONにする
![スクリーンショット 2024-03-01 11.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731259/31ff2785-14c4-9850-855e-5e05ba8578e1.png)

Chrome の拡張機能の管理画面でMetaMaskの管理情報を表示し、右上のデベロッパーモードをONにします。
（画面はChrome上のMetaMaskアイコンを右クリックし、「拡張機能を管理」メニュー選択で表示されます）

### 2.　更新ボタンを押下

更新ボタンを押すとMetaMaskが更新されます。
（私の環境では11.7.3 から11.10に更新されました）
特にChromeの再起動を行うこともなく、利用可能となりました。

## 最後に
パスフレーズはちゃんとメモっていたのですが、インポートしたウォレットが多いと復活できない辛いんですよね。
dockerのイメージの種類と選び方

## Dockerコンテナイメージのバリエーション
### dockerのイメージの種類がたくさんあってどれを選べばいいかわからない
### イメージの種類は大きく分けて4つ
### 1. 公式
### 2. Alpine Linux
### 3. Debian
### 4. windows

## 結論
開発環境や手軽に試したい場合はAlpine Linuxがおすすめ
しっかりした環境を必要な場合は公式イメージがおすすめ

## 具体的なDocker Hubのpython3.10のイメージを解説
### Debian Bookworm バリエーション
- **3.10.13-bookworm, 3.10-bookworm:**
  - ベースイメージ: Debian Bookworm
  - 特徴: Debianの最新バージョンを含む
  - 用途: 最新のパッケージと機能が必要な場合

### Debian Slim バリエーション
- **3.10.13-slim-bookworm, 3.10-slim-bookworm, 3.10.13-slim, 3.10-slim:**
  - ベースイメージ: Debian Slim
  - 特徴: 必要な最小限のパッケージを含む
  - 用途: リソース制約のある環境やセキュリティを重視する場合

### Debian Bullseye バリエーション
- **3.10.13-bullseye, 3.10-bullseye:**
  - ベースイメージ: Debian Bullseye
  - 特徴: 安定したDebianバージョン
  - 用途: 安定性が求められる一般的な用途

### Debian Slim Bullseye バリエーション
- **3.10.13-slim-bullseye, 3.10-slim-bullseye:**
  - ベースイメージ: Debian Slim Bullseye
  - 特徴: 軽量で安定性がある
  - 用途: リソース制約のある環境で安定性が求められる場合

### Alpine Linux バリエーション
- **3.10.13-alpine3.19, 3.10-alpine3.19, 3.10.13-alpine, 3.10-alpine:**
  - ベースイメージ: Alpine Linux
  - 特徴: 軽量かつセキュアなイメージ
  - 用途: コンパクトで高速なコンテナが必要な場合、セキュリティが重視される場合

### Alpine Linux 3.18 バリエーション
- **3.10.13-alpine3.18, 3.10-alpine3.18:**
  - ベースイメージ: Alpine Linux 3.18
  - 特徴: 一つ前のAlpine Linuxのバージョン
  - 用途: 特定のアプリケーションが3.18を要求する場合や、安定性が求められる場合

参考
https://zenn.dev/ken3pei/articles/1abbf7d974cf5d
https://hub.docker.com/_/python
Kubernetes内のSecretsを修正する

### kubectlで取得したSecretsのConfig設定が暗号化されている
以下のコマンドを打つとSecretsの詳細が出ますが、エンコードされているため詳細を見ることが出来ない。
```
kubectl get secret <シークレット名> -n <namespace名>
kubectl describe secret <シークレット名> -n <namespace名>
kubectl edit secret <シークレット名> -n <namespace名>
```
### 解決策
base64 encode / decodeを行ってくれるサイトを検索。
→decodeを行って設定内容を把握。
→修正したい箇所に修正を入れ、再度encodeし、コピーして控えておく
→以下コマンドを打ちConfig内容をencodeされた内容に差し替える
```
kubectl edit secret <シークレット名> -n <namespace名>
```
初心者JavaScriptのメモ帳～JavaScriptよく使われるメソッド～

# Web制作でよく使われるJavaScriptメソッド

## querySelector() / querySelectorAll()
DOM内の要素をCSSセレクタを使って検索します。

### querySelector()
```diff_javascript
// 単一の要素を取得
const element = document.querySelector('.classname');
```

### querySelectorAll()
```diff_javascript
// 複数の要素を取得
const elements = document.querySelectorAll('div');
```
## addEventListener()
特定のイベントが発生したときに指定した関数を実行します。これは、クリック、マウスオーバー、キーボード入力などのイベントを処理するのに役立ちます。

```diff_javascript
document.getElementById('myButton').addEventListener('click', function() {
    console.log('Button clicked');
});

```

## fetch()
ネットワークリクエストを行い、サーバーからデータを取得します。主にAjaxリクエストを送信して非同期通信を行うために使用されます。
```diff_javascript
fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));
```

## createElement() / appendChild()
新しいDOM要素を作成し、それを既存の要素に追加します。

```diff_javascript
const newElement = document.createElement('div');
newElement.textContent = 'New Element';

document.getElementById('container').appendChild(newElement);
```

## classList プロパティ
要素のクラスを操作するためのプロパティです。 add()、remove()、toggle()などのメソッドを使ってクラスを追加、削除、切り替えることができます。

```diff_javascript
const element = document.getElementById('myElement');

// クラスを追加
element.classList.add('newClass');

// クラスを削除
element.classList.remove('oldClass');

// クラスのトグル
element.classList.toggle('active');

```
数式による空白セルの書式設定

# 数式による空白文字列のセルに色をつける/つけない
以下のように数式の結果としてセルが空白として表示される場合に、
1. 空白ではない場合、セルに色をつける
2. 空白である場合、セルに色をつけない

つまり最終表示は下図のようになってほしいです。
![03-01-000102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724770/51b6ecd2-f15a-a083-13b0-6b042d9d6df2.png)

検索はしてみたのですが、COUNTBLANK関数を使う方法などで、いまいち思ったようにならなかったのでなんとか自分でまとめたのを備忘録とします。
Excel2021使用
## セル内容に対応して文字列を表示する/しない
A2の数式は以下のように、IF式で「A1のセル内容が数字の1の場合に文字列ONEを表示する、1ではない場合に文字列を表示しない」としています。
![03-01-000103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724770/52ec8da6-0039-e9f9-4c98-00f9388c74d6.png)
```
=IF(A1=1,"ONE","")
```
B2,C2もそれぞれ参照をB1,C1にして同様の数式です。

## 条件付き書式の設定
A2のセルに条件付き書式から、以下のように設定します。
![03-01-000101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724770/ccc6fa44-deba-5edf-a91a-723bff9edc39.png)
```
=$A$2<>""
```
「A2のセルが空白ではない」ときに書式を反映させる（今回はぬりつぶし）
つまり「A2のセルが空白である」ときにぬりつぶしをしないという条件です。
B2,C2のセルにも同様の数式で条件を付けて設定をします。
そのうえでA1~C1の内容を変えると、それにともなってA2~C2も文字列"ONE"が表示されたセルにだけ、書式が反映されてぬりつぶしされています。

![03-01-000102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724770/51b6ecd2-f15a-a083-13b0-6b042d9d6df2.png)　![03-01-000106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724770/c2dfe5e0-9418-1c77-d000-083e836eb71b.png)
クラスの作成

https://paiza.jp/works/mondai/class_primer/class_primer__make_class

未だにクラスに慣れていないのでなかなか戸惑います
０からはじまるので-1しないと中身が出てこないとか忘れてました。。。

```py
class Employee():
    def __init__(self,number,name):
        self.number = int(number)
        self.name = name
    
    def getnum(self):
        return self.number
    
    def getname(self):
        return self.name
        

N = int(input())
A = []
employees = []
for _ in range(N):
    A =input().split()
    if A[0] == "make":
        employee = Employee(A[1],A[2])
        employees.append(employee)
        
    elif A[0] == "getnum":
        number = int(A[1]) - 1
        print(employees[number].number)
    elif A[0] == "getname":
        number = int(A[1]) - 1
        print(employees[number].name)

```
getnumとgetname使えてなかったですね。。
やり直します

```py
class Employee():
    def __init__(self,number,name):
        self.number = int(number)
        self.name = name        
    
    def getnum(self):
        return self.number
    
    def getname(self):
        return self.name
        

N = int(input())
A = []
employees = []
for _ in range(N):
    A =input().split()
    if A[0] == "make":
        employee = Employee(A[1],A[2])
        employees.append(employee)
        
    elif A[0] == "getnum":
        number = int(A[1]) - 1
        print(employees[number].getnum())
    elif A[0] == "getname":
        number = int(A[1]) - 1
        print(employees[number].getname())
```
クラスでなにかする流れとしては、
構造体クラスを作成して、そこにデータをつっこんでリストを作り
全体でリストをあつめてデータ化し、全体リストにappendで格納する
そしてそこから全体リストの何番目の要素を使ってメソッドをつかう
って感じの流れですね。。。

クラスを使い慣れていないのでしばらく慣れるまで時間がかかりそうです。。
Aivenの顧客「チャンピオン」グローボ、アバヤ、プライスライン、スウェイAIが革新性、卓越性、影響力を評価され受賞

<font color="Grey">*[Aiven’s Customer ‘Champions’ GLOBO, Avaya, Priceline and Sway AI Awarded for Innovation, Excellence and Impact ](https://aiven.io/blog/aivens-customer-champions-awards-2024)の翻訳です。*</font>

2024年2月28日

# Aivenの顧客「チャンピオン」グローボ、アバヤ、プライスライン、スウェイAIが革新性、卓越性、影響力を評価され受賞

Aivenは、革新性、卓越性、グローバルな影響力において顕著な功績を残した企業を表彰する「カスタマー・チャンピオン賞」を創設しました。


ー イノベーションをークをーイノベーションに取り組んでいる企業は、競合他社をリードし、優秀な人材を惹きつけ、将来へのワクワク感を生み出しているのです。


私たちの顧客は昨年、驚くようなことを成し遂げました。


しかし、ここニューヨークのステージで、私たちは、イノベーション、卓越性、顧客へのインパクト、世界へのポジティブな影響を実証したこれらの企業の優れた業績を認め、称えました。


4人のチャンピオンは以下の通り：


* Tech for Good Champion Award - 翻訳・通訳サービス会社GLOBO。
* ビジネス・トランスフォーメーション・チャンピオン賞 - カスタマー・エクスペリエンス・ソリューションのグローバル・リーダー、アバヤ。
* カスタマー・エクセレンス・チャンピオン賞：プライスライン（オンライン旅行会社）。
* スタートアップ・チャンピオン賞 - Sway AI、ノーコードAI開発プラットフォーム企業。


これらの驚くほど賢く、野心的で革新的な企業は、本当に顧客のために素晴らしい体験を創造し、私たちを取り巻く世界を改善しています。私たちAivenは、データ・インフラの管理を簡素化し、データ主導型のイノベーションを実現するというシンプルな目標を掲げています。私たちのデータ・プラットフォームが、このような変革やインパクトの創出に貢献していることに、大きな喜びを感じています。


では、フロンティアを押し広げ続ける素晴らしい組織の中から選ばれたこの4つの企業は、何を成し遂げてカスタマー・チャンピオンになったのでしょうか？


[GLOBO](https://www.youtube.com/watch?v=NWrKM2xSk0Y)が受賞したTech for Good Champion Awardは、テクノロジーを使って世界にポジティブなインパクトを与えている組織を表彰するものだ。GLOBOは、誰にとってもより公平な体験ができる未来に向けて、目的意識を持って推進している。シンプルなプラットフォームを通じて、ユーザーは24時間365日、どの言語でもコミュニケーションすることができます。GLOBOは、24時間体制でサービスの回復力、信頼性、持続可能性を提供することにコミットしており、Aiven Platformはそのための基盤を提供することができました。


[Avaya](https://aiven.io/case-studies/avaya-transitions-to-the-cloud-with-the-aiven-platform)は、変化する市場に対応するためにテクノロジーを活用し、パフォーマンスを大幅に改善したことが評価され、Business Transformation Champion Awardを受賞した。Avayaは、グローバルな顧客基盤の大部分をオンプレミスからクラウドへの移行を支援するなど、事業の大規模な変革を行ってきた。アバヤの市場シェアは、主力製品であるコールセンター・ソリューションなど、重要なサービスの多くをクラウドで利用できるようにすることで、大幅なコスト削減と効率化を実現し、競争力を高めることにかかっていましたが、これを達成しました。Aivenを導入したことで、Avayaはクラウド上でオープンソース技術を管理する代わりに、Aivenのデータプラットフォームと専門知識が提供するビジネスの発展にリソースを集中させることができるようになりました。


[Priceline](https://aiven.io/case-studies/best-deal-for-priceline)に授与されたカスタマー・エクセレンス・チャンピオン賞は、比類ないカスタマー・エクスペリエンスを提供するためにテクノロジーを巧みに活用していることを強調するものです。Priceline社は、高度なデータサイエンス技術を活用し、航空座席、宿泊施設、レンタカーをシームレスにバンドルした割引サービスを提供する革新的な手段を考案しました。Aivenプラットフォームの統合により、Pricelineはオンプレミスの複雑なインフラを効果的に移行し、運用の合理化とリソース配分の最適化を実現しました。この戦略的協業により、Pricelineは迅速な分析能力を獲得し、データから2分以内に洞察を抽出できるようになりました。これによりPricelineは、顧客に最高の旅行情報を提供し、重要な瞬間を体験してもらうことに集中し続けることができます。現在、Aiven Platformはグーグル・クラウドのインフラ上でホストされ、Pricelineのリアルタイム・データ処理の要となっています。


そして、信じられないほど賢い[Sway AI](https://sway-ai.com/)がスタートアップ・チャンピオン賞を受賞した。この賞は、素晴らしいアイデアを持ち、チャンスを見出し、[Aiven Cluster](https://aiven.io/cluster)のスタートアップ・プログラムの支援を受けて新しい製品やサービスを立ち上げた素晴らしい人々の功績を称えるものです。Sway AIのノーコードAI開発プラットフォームを通じて、同社はAIの可能性を誰もが利用できるようにしている。専門的なデータサイエンスのスキルやコードを一行も書くことなく、企業が強力なAlやMLアプリケーションを作成できるようにする。Aivenのデータ・プラットフォームとスウェイ・アルのモデリングおよびインサイト機能を組み合わせることで、顧客のデータ・プラットフォーム・ニーズに対するエンド・ツー・エンドの回答を提供することができる。


お客さまに心からお祝いを申し上げます。


**5つのハイパースケーラークラウドで利用可能なAivenデータプラットフォームが、世界中のあらゆる規模のお客様にどのように役立っているかについては、[customer](https://aiven.io/customer)ページをご覧ください。
Hello Worldからの復習 ～繰り返し処理編～

なんだかんだ続いている復習アウトプット。
自分で見直してて「言っている意味がわからん」となっては意味がないので、必要最低限シンプルにしようと思っているが、振り返ってみて訂正していると、これまた復習になっている。（と思う）
繰り返し繰り返し一歩筒ずつ前に進むしかない。
焦ると大体良いことなんてない。

**繰り返し繰り返し・・・**



##### お品書き
+ 前回の分岐処理
+ while文
+ for文
---

**◆繰り返しって？**
-
前回、分岐処理編の構造化プログラミングで繰り返し処理の図を描いたので参考に。

https://qiita.com/tianshandafu894/items/c5156017b50253b2d5e9


**◆while文**
-
条件を満たす間ずっと処理を繰り返す文。
条件を満たさなくなったら抜ける。

```java:java
while(条件式){
   処理
}
```

```mermaid
graph TD
    start-->a{条件};
    a{条件}-->|true|処理;
    処理-->start;
    a{条件}-->|false|END;
```
みたいな感じ。

if文に似ている。
似て非なるものでwhile文はずっと繰り返す。

◆while文Sample
-

```java:java
int i = 0 ; //iを初期化
while( i < 3 ){ //条件式を見て3より小さい
System.out.println("i = " + i );
i++
}
```
iを初期化
iが3より小さいか見る
0
インクリメントで0+1
条件式に戻って
iが3より小さいかみる
さっき+1したから今1
インクリメントで1+1
・
・
・
これを3になったら抜ける。

みたいな。

-----

◆for文
-

```java:java
for(式1 ; 条件式 ; 式2 ) {
    処理
}
```
```mermaid
graph TB
start-->式1;
    式1-->a{条件};
    a{条件}-->|false|END;
    処理-->式2;
    式2-->a{処理};
    a{条件}-->|true|処理;
    
 
```

◆for文Sample
-
さっきのwhile文を修正したもの
```java:java
for(int i = 0 ; i < 3 ; i++){
System.out.println("i = " + i );
}
```

for文の()内でiの初期化、3より大きいか、インクリメントで+1

3になったらぬける。

for文の中でiは処理が何回目かを数えるのに使われるので**カウンター変数**と呼ぶ。
式1ではよくカウンター変数を準備します。
式2ではカウンター変数をインクリメントすることが多い。

配列の各要素に同じ処理をしたいときfor文が便利。


https://qiita.com/tianshandafu894/items/053761144ff6d20c1f85

**配列Sample**
-

```java:java
class Array{
	public static void main (String[] args){
		int [] score = new int[3];
		score[0] = 80;
		score[1] = 100;
		score[2] = 90;
  
		String[] name = {"大輔","湊丞","花帆"};
		
		System.out.println(name[0] + "さん:" + score[0] + "点");
		System.out.println(name[1] + "さん:" + score[1] + "点");
		System.out.println(name[2] + "さん:" + score[2] + "点");
		System.out.println("受験者数:" + score.length + "名"); //scoreの要素数を取得
  }
}
```
配列編のサンプルでfor文を使ってみよう。
添え字の所をカウンター変数をいれて0～2をfor文で繰り返せないかなと考えた。

```java:java
class Array{
	public static void main (String[] args){
		int [] score = new int[3];
		score[0] = 80;
		score[1] = 100;
		score[2] = 90;
  
		String[] name = {"大輔","湊丞","花帆"};

  for( int i = 0 ; i < score.length ; i++){ //0番目から要素数の数だけ繰り返す
       System.out.println(name[i] + "さん:" + score[i] + "点"); //[i]を0～2と変えていくことで3回出力される
  }
		System.out.println("受験者数:" + score.length + "名"); //scoreの要素数を取得
  }
}
```
```cmd:cmd
C:\Java\1>java Aaa
大輔さん:80点
湊丞さん:100点
花帆さん:90点
受験者数:3名
```

---

わたしはfor文の方が見やすい。

これも使い方を適宜考えて使おう。
ServiceNow の Guided Tour を使用して吹き出しを設定する

## どのような機能か
Guided Tour とは、サービスポータル、フォーム、ワークスペースなどに一連の吹き出し説明を表示する機能です。 吹き出しは、ヘッダのメニュー、Widget、フィールド、リスト項目名などに設定できます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/f7307a0d-5694-f0d4-fe96-bdb65e11d38b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/dea48257-d79a-260b-4997-6d47368d2f33.png)


## 表示方法
### 自動起動
初めて表示した画面でツアーを自動起動することができます。設定は、Guided Tour Designer > Configure Auto launch メニューにあります。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/6cb7bde1-967e-4f5d-c51b-be1136d18e1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/bd1815d0-60a8-53c2-52af-865ae78b1b47.png)


自動起動させたくないユーザーを指定したり、自動起動済のユーザーをリセットすることができます。設定は、Guided Tour Designer > Guided Tour ＞関連リンク にあります。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/15919bc3-7cca-f699-56bd-739fa9bdb412.png)


### 必要に応じて起動
サービスポータルの場合は画面右上の「ツアー」から選択します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/13536089-7553-0845-df91-5266d20cc8c6.png)


ワークスペース、フォーム、リスト表示の場合は、画面右上の？を押し、「ガイドを表示」を選択します。複数のツアーが登録されている場合は、 「ガイドを表示」の代わりに「ツアーを選択」が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/b7719c33-68c6-9451-b8c3-c7ed33215d3f.png)


## トラブルシューティング
Guided Tour の途中でエラーになることがあります。その場合、下記のような原因が考えられます。

- テーブル参照権限や承認権限などがないため、Widget が非表示となる場合があります。(例：Approvals Widget) 対策としては Skippable (省略可能) を指定します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/496bfe0a-6d08-f248-e8b2-f9114b785e71.png)

- レコード件数により可変する部分に吹き出しを設定すると、レコードが存在しない場合にエラーとなります。対策としてはレコード件数により可変する部分を避けて吹き出しを設定します。例えば Widget のタイトルやリスト表示の項目名に設定します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/75bcdd4a-7b95-3fec-0d6c-665306bab407.png)

- ツアーで設定した項目名やフィールドがビューに見つからないことがあります。 例えばインシデントテーブルのリスト表示のように、複数のビューが存在する場合、とあるビューには表示されているフィールドが、他のビューでは非表示の場合があります。 対策としては、Skippable を指定したり、ツアー開始後のステップでビューを明示して切り替えます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/95a4c3c2-bb7f-30e9-aa98-0a99d9f2cd93.png)

弊社ブログへも[同様の記事を投稿](https://alpcom.co.jp/blog/20240301/?utm_source=Qiita&utm_medium=post&utm_campaign=ysi&utm_id=20240301)しております。
VagrantからUbuntu22.04へのSSHで公開鍵認証が有効にならない

## 環境

Vagrant
Ubuntu22.04

## 内容

Vagrantを使って仮想環境にあるゲストOSのUbuntu22.04を起動しました。
```
$vagrant up
```

正常に起動された後、SSHで接続しようとします。

```
$vagrant ssh
```

すると、公開鍵認証が有効になっておらず、パスワード認証が求められる画面が表示されました。

```
$vagrant@127.0.0.1's password
```

vagrantユーザーのデフォルトのパスワードはvagrantです。ここでvagrantを入力すると、仮想環境へのログインは認証されます。


しかし、毎回、起動のたびにパスワードを入力するのは面倒です。パスワード入力をスルーさせてログインできないものだろうか。最初にやってみたことは、パスワードを削除することでした。パスワードを削除すれば、Enterキーだけでパスワード認証ができるようになるだろうと期待したのでが、結果的には駄目でした。パスワードを削除すると、逆にログインができなくなります。想定通りにはなりませんでした。


調べてみると、vagrantを使って仮想環境にログインするときのデフォルトの認証は、ログイン認証ではなく公開鍵認証が採用されているようです。公開鍵認証で成功すれば、パスワード入力を求めるプロンプトは表示されないはずです。更に調べてみると、公開鍵認証のキーが壊れている場合、パスワード認証が求められるようになるようです。「インストールした直後であるというのに、即、壊れるようなことがあるのだろうか？」訝しみ気味ではあったが、ssh-keygenコマンドで、公開鍵を再作成することにした。

private_keyは、vagrant initを実行したときに作成される、「.vagrant\machines\default\virtualbox」の中に入っています。そして、作成した公開鍵は、仮想環境の「~.ssh/authorized_keys」に上書きします。上書きする前に、更新前の「authorized_keys」と、更新後の「authorized_keys」の中身を見比べてみたのだが、中身はまったく同じでした。公開鍵は壊れてなさそうです。公開鍵を再作成した後、再度、公開鍵認証が成功するか試してみたが、案の定、元の木阿弥でした。

「うーん、原因がわからない。」

ChatGPTに聞いてもみたが、上記と同じ回答しか出してくれません。「うーん、まだ万能ではないな。それとも、俺のプロンプトの書き方が甘いのが原因なのだろうか。」「ChatGPTに聞いても分からないのであれば、自力でググるしかないか。」ググってみると、このような情報を見つけました。

https://help.arena.ne.jp/hc/ja/articles/5737789875223-Ubuntu-22-04-LTS%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%ABSSH%E6%8E%A5%E7%B6%9A-%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93-

https://it-jog.com/khow/vag/vaguperror-ubuntu2204

「Ubuntu22.4よりデフォルトで公開鍵認証ができないようになた？」原因はこれでした。公開鍵認証を使えるように設定ファイルを変更ればいいのですが、bentoをUbuntu20.04にバージョンダウンさせてもＯＫです。