OmniAICreator/Qiita-1.07M huggingface dataset:
【Android】共通したエラーハンドリング行いたい場合の実装まとめ

# はじめに
アプリを制作していると強制アップデートやメンテナンス中表示など、高確率で実装しますよね。
上記機能を実装する際、特定のエラーコードがサーバーから返ってきた場合に共通したExceptionを該当箇所全てでハンドリングしたい場合があるかと思います。
今回は上記に関しての実装方法を備忘録的にまとめておこうと思います。

# エラーハンドリング実装方法
まず実装をまとめるにあたり、okhttp、retrofitを使用していること前提で話を進めたいと思います。

今回解説するエラーハンドリングは独自のInterceptorを作成し、okhttpの設定に組み込むことで実装可能です。

```ErrorHandlingInterceptor.kt
class ErrorHandlingInterceptor  : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)

        when (response.code) {
            HttpURLConnection.HTTP_BAD_REQUEST -> throw ExampleException()
        }

        return response
    }
}
```
以上がエラーハンドリングを行うInterceptor内の処理になります。
intercept内でサーバーから返却されたコードを参照し、特定のコードが返却された場合は任意のExceptionに変換して返すようにします。
こうすることで、APIを叩いているすべての箇所で同じExceptionを参照しハンドリングすることが可能になります。

また、上記実装に際し一点注意点として、ここで返却させられるのはIOExceptionを親にもつExceptionのみになります。
上記以外を親にすると内部でExceptionを処理できずクラッシュするのでご注意ください。

``` main.kt
val client = OkHttpClient.Builder().apply {
    addInterceptor(ErrorHandlingInterceptor())
}
```

Interceptor側の実装ができればあとは上記のように、OkHttpClientに対して先ほど作成したInterceptorをaddしてあげるだけになります。
これで実装は以上になります。

# さいごに
エラーハンドリングも中々設計が難しい要素の一つですよね。
プロジェクト立ち上げ当初にこの辺りをしっかり考え込んで作らないと後で辛い思いをしかねないので、丁寧に実装しておきたいところですね。
【1分でわかる】React ComponentとElementの違いと型【初心者向け】

詳しい説明は偉大な先人の方々に委ねて、この記事ではざっくりと2つの違いを理解することを目的としています！

## 目次

- React ComponentとElementの違いとは
- React Componentについて
- React Elementについて

## React ComponentとElementの違いとは

一言で言うと、

- Component: React Elementを返り値とする関数
- Element: render()を通してDOMに変換される元となるオブジェクト

## React Componentについて

下記のように、Elementを返す

```tsx
type Hello = () => SX.Element

const Hello: Hello = () => {
  return (
		<p>Hello</p>
  )
}
```

型として定義している `Hello` を渡すのではなく、reactから `FC` という型をimoprtして渡す方法もあるが、諸説あるので使い分ける必要がある。(下記の記事がとても詳しく説明してくれています。)

参考記事

[const Hoge: React.FC<Props>=()=>って書いてたら思考停止系と言われたので調べた](https://zenn.dev/rgbkids/articles/d7691b6c852b42)

[【Reactの型定義】FCとJSX.Elementどっち使えば良い？](https://zenn.dev/motonosuke/articles/13d0fdd417ec7c)

## React Elementについて

下記のように、関数ではなく変数を定義するように書く

```tsx
type Hello = JSX.Element

const Hello: Hello = <p>Hello</p>
```

 `JSX.Element` ではなく、`ReactElement`を型として使う方法もある。

どちらも結果としてはReact Elementを示す型のため、好みで使い分けて良い。(下記の記事がとても詳しく説明してくれています。

参考記事
[Reactの JSX.Element とは何か？](https://commte.net/react-jsxelement)
composer requireとcomposer global requireの違い

composer requireとcomposer global requireはどちらもcomposerを使いPHPパッケージをインストールするコマンドだが、以下の違いがある。

### composer require <パッケージ名>
<font color="red">あるWEBアプリのプロジェクトを作成する場合など、なんらかのプロジェクト単位でパッケージを管理したい場合に使用するコマンド。</font>

例えばあるWEBアプリのプロジェクト専用のパッケージを管理したい場合を考える。

プロジェクトの最上位のディレクトリでパッケージを管理したいとして、その最上位のディレクトリへ移動し、composer require <パッケージ名>を実行する。

コマンド実行したカレントディレクトリにvendorディレクトリが作成され、その中にパッケージが格納される。

このvendorディレクトリでプロジェクト専用のパッケージを管理する。

### composer global require　<パッケージ名>
<font color="red">プロジェクト単位で管理したいパッケージでなく、どのディレクトリからでも使用するパッケージを管理したいなど、つまりシステム単位で使用するパッケージを管理したい場合に使用するコマンド。</font>

例えば、composer global require "laravel/installer"というlaravelプロジェクトを作成するためのインストーラーを追加するコマンドがある。

laravel/installerというパッケージはプロジェクト単位で管理するようなパッケージではないためglobalでパッケージ追加することが一般的。

globalでパッケージを追加した場合、どのディレクトリにパッケージが追加されるかというと、OSにより異なる。

>macOS： $HOME/.composer/vendor/bin

>Windows： %USERPROFILE%\AppData\Roaming\Composer\vendor\bin

>GNU／Linuxディストリビューション： 
\\$HOME/.config/composer/vendor/binもしくは、$HOME/.composer/vendor/bin

またコマンドでも確認できる。
>composer global config home
【Swift】CIFilterで画像をX線写真のような加工をする

# はじめに
CIFilterを使ってX線写真のようなフィルターを作成します

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-11-02 at 22.37.22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/cf872185-aaee-9fab-e79b-0d1f99003481.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    private let image = UIImage(named: "sample1")!

    @State private var uiImage: UIImage?

    var body: some View {
        ScrollView {
            VStack {
                if let uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                } else {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit()
                }

                HStack(spacing: 15) {
                    Button {
                        applyXRay()
                    } label: {
                        Text("適用")
                    }

                    Button {
                        uiImage = nil
                    } label: {
                        Text("リセット")
                    }
                }
            }
            .padding(.horizontal, 20)
        }
    }

    func applyXRay() {
        let context = CIContext()
        let inputImage = CIImage(image: image)!

        guard let filter = CIFilter(name: "CIXRay", parameters: [
            kCIInputImageKey: inputImage
        ]) else { return }
        guard let outputImage = filter.outputImage else { return }
        guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return }
        self.uiImage = UIImage(cgImage: cgImage)
    }
}
```

# おわり
これはいつ使うんでしょうか笑
Gem sorceryを使い倒す② ログイン機能応用編

## 新規登録時にログイン
　

新規登録したあとに、もう一度ログイン画面でログイン処理するのはユーザーにとって手間ですよね。
新規登録後はそのままログイン処理も済ませるように記述しましょう。
```ruby:controller/users_controller.rb
def create
    @user = User.new(user_params)
    if @user.save
      login(user_params[:email], user_params[:password])
      redirect_to curriculum_logs_path
      flash[:success]= 'サインアップしました'
    else
      flash.now[:danger] = 'サインアップに失敗しました'
      render :new, status: :unprocessable_entity
    end
  end
```

if @user.saveできたら、その後にloginメソッドを記述します。
これで新規登録後、自動的にログインすることができます。
　

## 少し複雑なテーブル設計でのログイン
　

基本のログインでは、sorceryの機能を使い作成したusersテーブルにnameカラムを追加する方法を採用しましたが、今回はnameカラムをprofileテーブルに作成し、ユーザー情報をまとめて管理するテーブル設計にしてみました。

```ruby:db/schema.rb
  create_table "profiles", force: :cascade do |t|
    t.string "name", null: false
    t.string "language"
    t.string "introduction"
    t.string "avatar"
    t.bigint "user_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_profiles_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", null: false
    t.string "crypted_password"
    t.string "salt"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

  add_foreign_key "profiles", "users"
end
```

今回のテーブル設計では、ユーザー登録の際にusersに関連づいたprofileテーブルも一緒に作成する必要があります。nameがnull: falseになっているので、登録画面にnameを入力するfomeを追加する必要があります。
　

 　
 **【モデルの関連付けをする】**

 まず、ユーザーがプロフィール情報も同時に登録できるようにするためには、UserモデルとProfileモデルの関連付けを行います。
 ```ruby:models/
# user.rb
class User < ApplicationRecord
  has_one :profile
  accepts_nested_attributes_for :profile
end

# profile.rb
class Profile < ApplicationRecord
  belongs_to :user
end
 ```
　
　
**【入力フォームを作成】**

```ruby:
<%= form_with model: @user do |f| %>
    <%= f.label :email %>
    <%= f.email_field :email %>

    <%= f.label :password %>
    <%= f.password_field :password %>

    <%= f.label :password_confirmation %>
    <%= f.password_field :password_confirmation %>
  
  <%= f.fields_for :profile do |profile_form| %>
      <%= profile_form.label :name %>
      <%= profile_form.text_field :name %>
  <% end %>

    <%= f.submit "登録", class: "btn btn-secondary" %>
<% end %>
```

入力フォームはemail、password、password_confirmationに、profileのパラーメーターを扱うフィールドを追加します。
  
  
  
**【controller編集】**

```ruby:users_controller.rb

class UsersController < ApplicationController
  skip_before_action :require_login, only: %i[new create]

  def new
    @user = User.new
    @user.build_profile
  end

  private

  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation, profile_attributes: [:name])
  end
end
```
newアクションに@user.build_profileを追加することで、新しいユーザーオブジェクトに紐付く新しいプロフィールオブジェクトを作成します。
Strong Parameters に、プロフィールの属性を追加します。

　
これで新規作成時にProfileを一緒に作成することができます。


## 参考資料

## 関連記事
https://qiita.com/joinus_ibuki/items/6cdf5368d4b858abfb51

https://qiita.com/joinus_ibuki/items/ce2fcdb9abb980959a9d
Oracle Database 23c Free - Developer Releaseをdockerから起動

従来、開発や検証用途のためdockerでOracleを起動するのはイメージビルドなど若干の手間が必要だったが https://container-registry.oracle.com/ords/ocr/ba/database/free のイメージ使用により非常に簡単になった。

たとえば、ちょっと試す分には以下で良い。さすがに初回はdocker pullにそれなりの時間は要するが。

```
docker run --name myoracle -p 11521:1521 -e ORACLE_PWD="a" container-registry.oracle.com/database/free:23.2.0.0
```

以下は起動確認用のspringアプリケーション。

```groovy:build.gradle
plugins {
  id 'java'
  id 'org.springframework.boot' version '3.1.5'
  id 'io.spring.dependency-management' version '1.1.3'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
  sourceCompatibility = '17'
}

repositories {
  mavenCentral()
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-jdbc'
  runtimeOnly 'com.oracle.database.jdbc:ojdbc8'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
  useJUnitPlatform()
}
```

```properties:application.properties
spring.datasource.url jdbc:oracle:thin:@localhost:11521/FREEPDB1
spring.datasource.username system
spring.datasource.password a
```

```java
@SpringBootApplication
public class OracleSampleMain implements ApplicationRunner {

  public static void main(String[] args) {
    SpringApplication.run(OracleSampleMain.class, args);
  }

  @Autowired
  DataSource ds;
  
  @Override
  public void run(ApplicationArguments args) throws Exception {
    JdbcTemplate t = new JdbcTemplate(ds);
    System.out.println(t.queryForObject("select 1 from dual", Integer.class));;
  }
}
```

参考用のdocker run時の起動ログ。

```
Starting Oracle Net Listener.
Oracle Net Listener started.
Starting Oracle Database instance FREE.
Oracle Database instance FREE started.

The Oracle base remains unchanged with value /opt/oracle

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sun Nov 5 10:11:44 2023
Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.


Connected to:
Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release
Version 23.2.0.0.0

SQL>
User altered.

SQL>
User altered.

SQL>
Session altered.

SQL>
User altered.

SQL> Disconnected from Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release
Version 23.2.0.0.0
The Oracle base remains unchanged with value /opt/oracle
#########################
DATABASE IS READY TO USE!
#########################
The following output is now a tail of the alert.log:
FREEPDB1(3):Autotune of undo retention is turned on.
FREEPDB1(3):Undo initialization recovery: Parallel FPTR failed: start:1651134 end:1651136 diff:2 ms (0.0 seconds)
FREEPDB1(3):[163] Successfully onlined Undo Tablespace 2.
FREEPDB1(3):SUPLOG: Set PDB SUPLOG SGA at PDB OPEN, old 0x18, new 0x0 (no suplog)
FREEPDB1(3):Opening pdb with Resource Manager plan: DEFAULT_PLAN
2023-11-05T10:11:44.072875+00:00
Completed: Pluggable database FREEPDB1 opened read write
Completed: ALTER DATABASE OPEN
2023-11-05T10:11:44.498176+00:00
FREEPDB1(3):TABLE AUDSYS.AUD$UNIFIED: ADDED INTERVAL PARTITION SYS_P371 (3415) VALUES LESS THAN (TIMESTAMP' 2023-11-06 00:00:00')
```
PythonのDocstring


# 参考リンク

https://qiita.com/flcn-x/items/393c6f1f1e1e5abec906

https://ya6mablog.com/python-docstring-guide/

# google style


テンプレートは下記

```python
def add(a, b):
    """
    2つの数値を受け取り、その和を返す関数。
    
    引数:
        a (float): 数値1
        b (float): 数値2
    
    戻り値:
        float: aとbの和
        
    例:
        >>> add(1,2)
        3
        
    注意事項:
    
    """
    return a + b
```
writefreelyのセットアップでエラーが出た時の解決法

# この記事の目的

writefreelyのセットアップ方法は[ドキュメント](https://writefreely.org/docs/main/developer/setup)に記載されていますが、手順通りに進めるとエラーが出ました。この記事ではエラーの解決方法について記載します。

# エラーの内容

Quick startに沿って`go get`コマンドを走らせると以下のエラーが発生します。

```
> go get -d github.com/writefreely/writefreely/cmd/writefreely

go: go.mod file not found in current directory or any parent directory.
	'go get' is no longer supported outside a module.
	To build and install a command, use 'go install' with a version,
	like 'go install example.com/cmd@latest'
	For more information, see https://golang.org/doc/go-get-install-deprecation
	or run 'go help get' or 'go help install'.
 ```

# エラーの原因

比較的新しいGoのバージョンを使っていると、`$GOPATH`ではなく新しいGo Moduleを使った方法で依存管理を行います。`GO111MODULELE`という設定で`$GOPATH`かGo Moduleを選択できますが、以下の記事にある通り、バージョンによって動きが違いかなり複雑なので詳細は割愛します。

https://maelvls.dev/go111module-everywhere/

Go ModuleはGoのバージョンが新しいと、必須になっており`go get`はGo Module無しでは使えなくなっています。

# 解決方法

以下の通り、`GO111MODULE`を`auto`にして`go.mod`ファイルがない場所では以前の`$GOPATH`を使った動きになるようにしました。

```
go env -w GO111MODULE=auto
```

上のコマンドを実行後に`go get -d github.com/writefreely/writefreely/cmd/writefreely`を実行すると、`$GOPATH/src`にソースコードがダウンロードされます。
`cd $GOPATH/src/github.com/writefreely/writefreely`
は`$GOPATH`が設定されていない場合、`$GOPATH`はホームディレクトリーのgoディレクトリーにデフォルトでは作られるので`$HOME/go/src/github.com/writefreely/writefreely`で移動できるかと思います。


# その他
* 私の環境では`echo $GOPATH`で確認しても値が設定されていませんが、`go env GOPATH`では値が設定されていました。どうやら最近のGoでは`zhrc`などに`$GOPATH`を設定する必要はなさそうです。

https://stackoverflow.com/questions/21001387/how-do-i-set-the-gopath-environment-variable-on-ubuntu-what-file-must-i-edit/53026674#53026674


* `$GOPATH`の方法で`go get`を使うと`$GOPATH/src/`にソースがダウンロードされるが、Go Moduleで`go get`を使うと`$GOPATH/pkg/mod`にダウンロードされます。

https://stackoverflow.com/questions/66284870/go-get-not-downloading-to-src-folder
>Since Go 1.15, go get by default will download source codes inside `$GOPATH/pkg/mod/ (GOMODCACHE)` which is in place of what it used to be `$GOPATH/src/`
灰色13級がABC327をpythonでやってみた。(A~C問題)

# はじめに
ABC326で灰色13級になりました。あおぷと.zipです。
今回参加した[ABC327](https://atcoder.jp/contests/abc327/tasks)の解説を書いていきます。
ちなみにABC327で灰色12級になりました。
# A - ab

https://atcoder.jp/contests/abc327/tasks/abc327_a

## 解説
Sを文字列として受け取りS[i]がaでS[i+1]がb,または
S[i]がbでS[i+1]がaならanswerを"Yes"にする。
## コード
```python:a.py
input()
s = input()
answer = "No"
for i in range(len(s)-1):
  if s[i] == 'a':
    if s[i+1] == 'b':
      answer = "Yes"
  elif s[i] == 'b':
    if s[i+1] == 'a':
      answer = "Yes"
print(answer)
```
:::note
pythonだとNを受け取らなくてもだいじょぶ。
:::
:::note warn
`range(len(s)-1)`のところの-1を付け忘れるとWAになる。
:::
**追記:2023/12/30**
---
コメントもらってたのに改善してなかった。
すいません。
```python:improvement.py
input()
s = input()
print('Yes' if 'ab' in s or 'ba' in s else 'No')
```

# B - A^A
https://atcoder.jp/contests/abc327/tasks/abc327_b
## 解説
`16**16 > 10**18` なのでパターンは1~15の15通り。
全捜索で一致するパターンがあったらその数字を出力。
なかったら-1を出力。
## コード
```python:b.py
b = int(input())
answer = -1
for i in range(1,16):
  if i**i == b:
    answer = i
print(answer)
```
# C - Number Place
https://atcoder.jp/contests/abc327/tasks/abc327_c
## 解説
まずAを２次元配列として受け取る。
縦を値が重複しないsetにして数が9未満だったらanswerを0にする。
これを9回する。(横も)
そして3x3ブロックごとにsetにし、縦と同じようにする。
## コード
```python:c.py
Array = [list(map(int, input().split())) for i in range(9)]
vertical = []
beside = []
block = []
answer = 1
for i in range(9):
  for j in range(9):
    vertical.append(Array[i][j])
    beside.append(Array[j][i])
  if len(set(vertical)) < 9 or len(set(beside)) < 9:
    answer = 0
  vertical.clear()
  beside.clear()
for x in range(3):
  for y in range(3):
    for i in range(3):
      for j in range(3):
        block.append(Array[x*3+j][y*3+i])
    if len(set(block)) < 9:
      answer = 0
    block.clear()
if answer:
  print("Yes")
else:
  print("No")
```
:::note warn
4重ループにならないような方法コメントに書き込んでくださいお願いします。
:::
# 終わりに
初めてC問題ACしましたけど4重ループになってます。
今後改善したいです。
PgAdmin4を使用してPostgreSQLのER図を作成する

GUIのあるOSでDBを構築できれば、PgAdmin4を使用して簡単にER図を作成できます。

----------------------------------
まずは、サンプルデータベースを構築します。
* データベース作成
```sql
psql -U postgres -p 5432 -d postgres -c "CREATE DATABASE dvdrental TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C';"
pg_restore -U postgres -d dvdrental ./dvdrental.tar
```
* 以下のサイトからダンプをダウンロード
https://www.postgresqltutorial.com/postgresql-getting-started/postgresql-sample-database/

* リストアします
```
pg_restore -U postgres -d dvdrental ./dvdrental.tar
パスワード:
```

* PgAdmin4を起動します

* PgAdmin4でリストアしたデータベースを選択し、「ERD For Database」を実行します
![1](https://github.com/pea-sys/postgresql-expriments/assets/49807271/6c52f233-e693-42df-863e-816fe1c46749)

* グリッドに沿って、ER図が生成されます。レイアウトや色等は調整可能です。
* 左上の絵のアイコンから画像ファイルとしてエクスポート可能です。
![2](https://github.com/pea-sys/postgresql-expriments/assets/49807271/329a0f17-3a87-4d7b-98ea-b70ccc7279a8)

* 画像のエクスポート結果です。レイアウトは未調整なので見づらいかもしれません。
![Untitled](https://github.com/pea-sys/postgresql-expriments/assets/49807271/fdf345f3-4b66-4dbc-b55a-fc90acdccfe2)

以上
【基本】基本コマンドとよく使うモジュールの一覧


# 基本コマンド

```python
#python自体のバージョン一覧
python -V
```

```python
#インストール済みモジュールの一覧
pip list
```

```python
#jupyter labのインストール
pip install jupyterlab
#jupyter labの起動方法
$jupyter lab

```


```
pip install openpyxl

```

# よく使うモジュール

インストール方法
```shell
pip install 

```

インポート方法
```python
import os
import openpyxl
import PySimpleGUI as sg
```



# 参考リンク
下記の記事が参考になった
https://camp.trainocate.co.jp/magazine/venv-python/

# envの特徴
venvはPython3.3以降にPythonの標準機能として取り込まれたもので、pyenvやvirtualenvのようにインストールする必要がないため、簡単に仮想環境を作成管理することができます。
venvはPython 3.x.x 下に組み込まれた機能なので、Python自体のバージョン管理はできません。

# 仮想環境の作り方
イメージとしては、下記のコマンドで、PJフォルダの中に、仮想環境のフォルダが作成されるイメージ

```
#例えばtest1という仮想環境を作りたければ下記(test1というフォルダが作られる)
python -m venv test1
```




# 起動と停止
```
#起動
Scripts/Activate.ps1
#停止
deactivate
```



```
hogehoge
```
[Slack bolt]  bolt-app The top-level `text` argument is missing in the request payload for a chat.postMessage call という警告の対処法

## 結論
chat.*のメソッド内のパラメータを`blocks`ともう一つfallbackとして付け加える

## 警告が出るコード例
```javascript
・　・　・
app.event("reaction_added", async ({ event, say, client }) => {
    // 何かしらの処理
    
    await say({
        blocks: [
            ・　・　・
            // 処理
        ],
    })

    // 何かしらの処理
})
・　・　・
```

## 警告が出ないコード例
```javascript
・　・　・
app.event("reaction_added", async ({ event, say, client }) => {
    // 何かしらの処理
    
    await say({
        blocks: [
            ・　・　・
            // 処理
        ],
        text: 'This is fallback example.' // 追記
    })

    // 何かしらの処理
})
・　・　・
```
このようにfallbackとして、`blocks`以外のパラメータ（今回で言うと`text`）を付け加える必要がある。

## なぜこのような処置が必要なのか
目的がfallbackなので、もし`blocks`内の処理がうまくいかなかったときも安全に処理を継続させるためだと勝手に思ってます。

## 参考
> https://github.com/slackapi/bolt-js/issues/1249

## 最後に
めっちゃ関係ないんですけど、最近お菓子のダースが美味しくなってないですか？
最近久しぶりに食べてびっくりしちゃいました
C#でOpenAPIのタグにコメントを追加する

# 1. はじめに
* C#でSwaggerUiのタグにコメントを追加したい
* メソッドなどはXMLコメントで追加できるが、タグだけできないのでなんとかしたい

# 2. 開発環境
* C#
* .NET 6
* OpenAPI 3.0.0
* Visual Stduio 2022
* Swashbuckle.AspNetCore.Annotations (NuGet)

# 3. Swashbuckle.AspNetCore.Annotationsのインストール
* NuGetから```Swashbuckle.AspNetCore.Annotations```をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/eeb751e0-1c94-f01d-ad98-9b51517e4e66.png)

* 適用ボタンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/157a799c-9419-5d6f-b4b5-7583fe4d8616.png)

# 4. Program.csの修正
* ```options.EnableAnnotations();```の1行を追加する
```Csharp:Program.cs
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
// builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(options =>
{
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
    // EnabeAnnotationsを追加する
    options.EnableAnnotations();
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "Sample APIs");
    });
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
```

# 5. Controllerの修正
* ControllerにSwaggerTagのアノテーションを追加して、コメントを入力する
```Csharp
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace WebApplication1.Controllers
{
    /// <summary>
    /// WeatherForecastController XMLコメント
    /// </summary>
    [ApiController]
    [Route("[controller]")]
    [SwaggerTag("Tag Comment")]
    public class WeatherForecastController : ControllerBase
    {
```

## 6. 動作確認
* SwaggerUiにタグのコメントが表示できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/d1896c32-dbf4-b37f-4a5d-675ed6ae515c.png)

# 7. 参考文献

https://blog.christian-schou.dk/how-to-make-api-documentation-using-swagger/
pythonのモジュールaseを使ってみる#1

## aseとは
MDや第一原理計算をpythonで比較的簡単に動かせる、Atomic Simulation Environment (ASE)というパッケージが用意されている。
pythonのモジュールとして提供されているので、これをimportすればMDシミュレーションなどが（コードを書くことなく）実行できる。


## 前提条件
pythonがインストールされていること。
pipがインストールされていること。

## aseのインストール

pip install ase

などとして、aseモジュールが使えるようにしておく。

## nglviewのインストール

pip install nglview

などとしておけば、nglviewを用いた（デフォルトのaseビューワーより綺麗な）構造描画ができる。

## 初期構造作成と可視化のテスト

ase（とnglview）が動くかどうかテストするため、簡単な初期構造を作成してみる。
ここではjupyter notebookに下記のコードを打ち込むことでテストしてみた。

```python
from ase import Atoms
from ase.build import fcc111, bulk
slab = fcc111('Al', (3, 3, 4), a=4.04, vacuum=5.0)
from ase.visualize import view
view(slab, viewer='ngl')
```

実行結果


![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893569/9a7238ab-8835-b458-f45a-690c783b1700.png)


なお、nglviewを使わなくても、最後の行を
```python
view(slab, viewer='ase')
```
とすれば構造は一応可視化できる。下図のように原子が平面的に描画される。


![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893569/c71005e8-9185-d8d6-2c7b-a769815c40ee.png)
【CSS・学習ログ3】幅と高さ

<font color=gray>教材：侍テラコヤ『HTML/CSSの基礎を学ぼう』https://terakoya.sejuku.net/programs/51/chapters</font>

## 要素の幅と高さ
- widthプロパティ(幅)
- heightプロパティ(高さ)

要素の大きさを上記で２つのプロパティで指定する。

## widthの指定
#### (1) pxで指定
![スクリーンショット 2023-11-05 051804.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/f468be31-af1f-b122-a3dd-f5c9ce90a087.png)
```css
.parent {
	width: 300px;
	background-color: yellow;
}
.child {
	width: 150px;
	background-color: orange;
}
```
#### (2) %で指定
![スクリーンショット 2023-11-05 052115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/d0fbeea8-1a7c-9a6d-efb1-91698788d4dd.png)
#### (3) autoで指定
初期値のため、autoの記述をしなくても同じ結果になる。
![スクリーンショット 2023-11-05 052654.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/20d07d6e-aad2-9901-9cb7-fbf459ff3c1b.png)

## heightの指定
#### (1) pxで指定
![スクリーンショット 2023-11-05 053239.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/aec803b1-ffb1-0a80-e633-7da0c88ac7f7.png)
```css
.parent {
	height: 400px;
	background-color: yellow;
}
.child {
	height: 150px;
	background-color: orange;
}
```
#### (2) %で指定
親要素を基準に反映される。
![スクリーンショット 2023-11-05 054613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/0c9107a8-69bf-d03c-f0c9-2fa674770c92.png)

#### (3) autoで指定
widthと違い、縦幅いっぱいに広がることはなく、子要素の大きさに順応する。
子要素がない場合は表示されない。
![スクリーンショット 2023-11-05 054057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/9010ba93-82bb-5cc2-3af6-4b019e1ed1f3.png)
```css
#one {
	height: auto;
	background-color: yellow;
}
#two {
	height: auto;
	background-color: orange;
}
#three {
	height: auto;
	background-color: pink;
}
```
## 幅と高さの最小値・最大値
幅や高さの最小値・最大値を指定することで、さまざまなデバイスで大きさを最適化できる。
- min-widthプロパティ(幅)
- max-widthプロパティ(幅)
- min-widthプロパティ(高さ)
- max-heightプロパティ(高さ)
#### (1) min-widthで指定
幅の最小値。下記の例だと300px以下より小さくなることはない。
![スクリーンショット 2023-11-05 055354.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/eddbf4db-9e74-d924-c2b9-e029fdb0f8c9.png)
```css
.parent {
	width: auto;
	background-color: yellow;
}
.child {
	width: 50%;
	min-width: 300px;
	background-color: orange;
}
```
#### (2) min-heightで指定
最小値を指定することで、子要素が入っていなくても高さを確保できる。
![スクリーンショット 2023-11-05 055948.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/be0ca296-82a8-7a8f-9490-dd9a3d78a30b.png)
```css
#one {
	height: auto;
	background-color: yellow;
}
#two {
	height: auto;
	background-color: orange;
}
#three {
	height: auto;
	min-height: 100px;
	background-color: pink;
}
```
#### (3) max-heightで指定
子要素の高さが最大値を超えると、超えた分の子要素がはみ出る。
![スクリーンショット 2023-11-05 060628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/ec6d50bf-75c6-e0a4-129e-9d745238ffb7.png)
<hr>
【簡単】Railsでの画像アップロードと表示機能の追加方法

# 【簡単】Railsでの画像アップロードと表示機能の追加方法

このガイドでは、ImageMagick、MiniMagick、Image Processing、およびActive Storageを使用して、Railsアプリケーションで画像のアップロードと表示を実現する手順を説明します。

## 1. ImageMagickのインストール

まず、ImageMagickをインストールしましょう。ImageMagickは画像の処理と変換に必要です。Homebrewを使用してインストールできます。

```bash
brew install imagemagick
```

## 2. MiniMagickとImage Processingのセットアップ

次に、MiniMagickおよびImage ProcessingのGemをプロジェクトに追加しましょう。Gemfileに以下の行を追加します。

```ruby
gem 'mini_magick'
gem 'image_processing'
```

その後、ターミナルで以下のコマンドを実行して、Gemをインストールします。

```bash
bundle install
```

## 3. MiniMagickのバージョンの設定

`config/application.rb`ファイル内に、MiniMagickのバージョンを指定します。これはMiniMagickがImage Processingと連携するために必要です。

```ruby
config.active_storage.variant_processor = :mini_magick
```

## 4. Active Storageのセットアップ

Active Storageをセットアップするには、ターミナルで以下のコマンドを実行します。

```bash
rails active_storage:install
rails db:migrate
```

これにより、アプリケーション内でファイルアップロードと管理に必要なデータベーステーブルが作成されます。

## 5. モデルへの画像のアタッチメント

画像をアップロードしたいモデルに、`has_one_attached`メソッドを使用してアソシエーションを追加します。例えば、`Message`モデルに画像を紐づける場合のコードは以下の通りです。

```ruby
class Message < ApplicationRecord
  has_one_attached :image
end
```

## 6. 画像のアップロードフォーム

画像をアップロードするためのフォームをビューに設置します。例えば、`Message`モデルを編集するビューにフォームを追加する方法は以下の通りです。

```erb
<%= form_with model: @message, local: true do |f| %>
  <!-- 他のフォームフィールド -->
  <%= f.file_field :image %>
  <!-- 送信ボタンなどのフォームコントロール -->
<% end %>
```

## 7. 画像の表示

画像を表示するには、`image_tag`ヘルパーを使用します。例えば、`Message`モデルのインスタンスから画像を表示する方法は以下の通りです。

```erb
<%= image_tag @message.image.variant(resize: '500x500') %>
```

これにより、アップロードされた画像が指定したサイズにリサイズされて表示されます。

## まとめ
以上で、Railsアプリケーション内での画像のアップロードと表示が設定されました。ユーザーは画像をアップロードし、必要に応じてリサイズなどの画像処理を行うことができます。

この手順に従って、アプリケーションに画像の機能を統合し、ユーザーエクスペリエンスを向上させましょう。
書籍アウトプットで競い合いませんか？

初めまして、ガマリと申します。

皆様、本を読んだ後は「アウトプット」してますか？今回は、そんなアウトプット事情を変えるための、アプリを作ったので、紹介させていただきます。

アウトプットにお困りの方は、是非、ご一読ください。

## Yommy

https://yommy-books.com/

先日、Yommyというアプリを公開しました。このアプリは「従来の書籍管理アプリ」に加え、アウトプットに特化した機能を備えています。

実際の画面を見ながら、その機能を説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/1b9aa425-dd06-6320-b6d8-f4597d79fe23.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/950900d8-4daf-6db1-82e3-37b71d653109.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/9f424dec-151b-4445-211a-7b58d72f5d99.png)


Yommyでは、書籍詳細画面にて「アウトプット」というタブが存在します。

そこでは、**アウトプットの量に比例して**ランキング化を行っています。


――そもそもアウトプットとは何か。
Yommyでは「つぶやき程度の自分の考え」をアウトプットとして定義しています。

自分の言葉で、適切に発信できるかどうか、がアウトプットの境目だととらえており、この量が多ければ多いほど、しっかり書籍を落とし込めているんだと、当サービスでは認識しています。

もちろん、つぶやきレベルでは測れないものもあるので、今後は「いいね」や「ノート」みたいな機能を作りますが、現段階では「つぶやきレベル」で整理できない人のための機能として、「アウトプット機能」が存在する感じです。

アウトプット機能の実際の画面は下記から見れます。

https://yommy-books.com/detail/3764/

この機能を使うことで、読書の消化不良を妨げる狙いがあります。

## Yommyのアウトプット機能を使うことのメリット

アウトプット機能を使うメリットは、主に２つです。

一つ目が「アウトプットをする癖がつけられる」。従来の読書ではインプットのみで終わりガチですが、このアプリを使うことで、読んだだけで終わらせず、しっかりとアウトプットするようになります。

二つ目が「記録に残る」です。
Yommyでは、書籍に対して自分のアウトプットを残せます。
このアウトプットは消えることはなく、また記録画面から自分のアウトプットをいつでも見返せるようになっています。
適切にアウトプットすれば、いつでも振り返れるのがメリットの一つです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/bf5c43d7-44ec-efda-266e-fb122132ca05.png)

上記の画面は「記録画面」です。
ここに、メモが一生残るため、読書の振り返りが簡単にできます。

## まとめ

以上のように、Yommyのアウトプット機能を使うことで、インプットしがちな読書に、新しい風を取り込めるかもしれません。

もしよろしければ、この機会にYommyを利用して頂けると幸いです！

https://yommy-books.com/

## そのほかの記事

https://qiita.com/Gamari0009/items/a132cd75c9dc1f647986

https://qiita.com/Gamari0009/items/70d554a83edf71cfb407
Ubuntu 22.04へApache Axis2をインストール

少し躓いたのでインストールした手順を記載しておきます。

参考: 

https://axis.apache.org/axis2/java/core/docs/installationguide.html

# JDKのインストール

```bash
sudo apt install openjdk-11-jdk
```

## JAVA_HOMEの設定
こちらを参照しました。ありがとうございます。

https://qiita.com/yochapan/items/a63c6744ccb7f17f54b5

# Apache Antのインストール

```bash
sudo apt install ant
```

# Apache Mavenのインストール

```bash
sudo apt install maven
```

# Apache Axis2のインストール

バイナリファイルのダウンロードとインストール。

```bash
sudo curl -O http://www.apache.org/dyn/closer.lua/axis/axis2/java/core/1.8.2/axis2-1.8.2-bin.zip
sudo unzip axis2-1.8.2-bin.zip
sudo mkdir /usr/local/bin/axis2
sudo mv axis2-1.8.2/* /usr/local/bin/axis2
sudo rmdir axis2-1.8.2
```

ごちゃごちゃしててすみません。もっとシンプルにやれるはずです。
環境がさくらのVPSだったので事前にunzipのインストールなども必要でした。

## 環境変数の設定
```bash:/etc/profile.d/axis2_home.sh
export AXIS2_HOME=/usr/local/bin/axis2
```

## axis2server.shの修正
Axis2のインストール手順を読む限り、このままで起動できるはずですが、JDKのバージョンが異なるためJAVAクラスの移動があり、修正が必要です。

```bash:/usr/local/bin/axis2/bin/axis2server.sh
java $JAVA_OPTS -classpath "$AXIS2_CLASSPATH" \
    org.apache.axis2.transport.SimpleAxis2Server \
    -repo "$AXIS2_HOME"/repository -conf "$AXIS2_HOME"/conf/axis2.xml $*
```

この``org.apache.axis2.transport.SimpleAxis2Server`` を
``org.apache.axis2.kernel.SimpleAxis2Server``に変更します。

参考：

https://stackoverflow.com/questions/75445112/getting-error-could-not-find-or-load-main-class-org-apache-axis2-transport-simp/75515735#75515735

# Axis2 Serverを起動
ログファイルを出力するためのパーミッションを付与
```bash
sudo mkdir /var/log/axis2
sudo chown <user> /var/log/axis2
sudo chown <user> /var/log/axis2/axis2server.log
```

バックグラウンド起動
```bash
nohup $AXIS2_HOME/bin/axis2server.sh > /var/log/axis2/axis2server.log 2>&1 &
```
PHP学習記録

## 目的
・PHP7技術者認定初級試験の合格を目指す。

## 参考教材
初めてのPHP（PHP7対応版）
開発環境についての記載がないので手探りで構築してみる。

## 環境
・Ubuntu 22.04LTS wsl2
・Docker
・php:7.4.33-zts-alpine3.16

### Docker
php公式のイメージを使用する。
https://hub.docker.com/_/php

とりあえずpullしてみる。
```
$ docker pull php:7.4.33-zts-alpine3.16
$ docker run -it php:7.4.33-zts-alpine3.16
Interactive shell

php > echo 'Hellow World';
echo 'Hellow World';
Hellow World
```
phpのコードは実行できた。
pullしたimageは一旦削除。

Dockerfile作成
```
FROM php:7.4.33-zts-alpine3.16
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "php", "./index.php" ]
```

```
index.php

<?php
echo 'Hello World!';
```

```
$ docker build -t php:7.4.33-zts-alpine3.16 .
$ docker run -it php:7.4.33-zts-alpine3.16
Hello World!
```
これでDockerfileに記載したコマンドでphpファイルを実行できた。
index.php編集してもう一度runしても出力が変わらないので、キャッシュなどが残っていそう。
1. コンテナ削除
2. build
3. run

で編集内容は反映された。

単純に1ファイル実行するだけならこれでいいみたい
```
$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:[tag] php your-script.php
```

ここまでで学習進められる状態にはなった。

単一ファイルは実行できるが、コンテナが閉じてしまい、ブラウザからアクセスできないので修正
使ってるイメージ
php:7.4.33-zts-alpine3.16
alpineはLinuxのディストリビューション
サーバ(apache)がはいってない...
php:7.4.33-apache-bullseyeに変更

apache導入後の環境
```
.
├── docker-compose.yml
└── php
    ├── index.php
```
```
version: '3'
services:
  php_service:
    # image:  php:7.4.33-zts-alpine3.16
    image: php:7.4.33-apache-bullseye
    container_name: php_container
    build:
      context: './php/'
    volumes:
      - './php:/var/www/html'
    ports:
      - '8000:80'
```
docker-compose.yml
#### Docker備忘録
・php:7.4.33-zts-alpine3.16（名前：タグ）
・docker run -it php:7.4.33-zts-alpine3.16
--interactive , -i：アタッチしていなくても、標準入力を開き続ける
・-t：TTY
>Dockerにおけるttyは、仮想端末を配置するコマンド
https://zenn.dev/hohner/articles/43a0da20181d34

・イメージ削除
docker rmi [imageID]
・コンテナ削除
dokcer rm [containerID]
・コンテナ確認
docker ps -a
・コンテナ起動時に毎回自動でコンテナを削除する
docker run --rm [イメージ]
・作業ディレクトリのマウント
docker  run  -v `pwd`:`pwd` -w `pwd` -i -t  ubuntu pwd


### 記録
学習期間 2023/11~
乱数表を得る方法

# 乱数表を得るスクリプト

最近、急に乱数表が欲しくなったので質の良い乱数を得る簡単な方法を探しました。

```/dev/random``` で「真」の乱数を得られることは割と有名だと思いますが、パッと 10 進数乱数を作る方法を知らなかったので調べました。
```/dev/random```から取得したデータはバイナリ形式で提供されるため、それを10進数に変換する必要があります。

以下はシェルスクリプトを使用してバイナリデータを10進数に変換する方法の例です。

```shell
dd if=/dev/random bs=1 count=2000 2>/dev/null | od -An -tu1 > ../random_number.txt
```

```od``` はバイナリデータを 10 進数に変換するコマンドです。
```-An```オプションは、アドレス情報を表示しないように指定し、
```-tu1```オプションは、10進数形式で1バイトごとに表示することを指定します。

```dd```はデータのコピーと変換を行うコマンドです。
```-bs```はブロックサイズを表しておりサンプルでは 1 バイトです。
```-count```は個数を表しています。

以下は Python で同じことをするスクリプトです。
各言語の機能を使って乱数を得る方法については各言語のドキュメントにあたってください。```/dev/urandom```から乱数を得ている場合も多いので注意してください。

```random_10_bytes.py
import os

def generate_random_decimal(num_bytes):
    with open('/dev/random', 'rb') as f:
        random_bytes = f.read(num_bytes)

    # バイナリデータを10進数に変換
    random_decimal = int.from_bytes(random_bytes, byteorder='big')

    return random_decimal

# 例: 10バイトのランダムデータを10進数に変換
random_data = generate_random_decimal(10)
print(random_data)
```

以上のスクリプトは質の良い乱数を得ることができますが、OS が溜め込んだエントロピープール以上の量の乱数は作れません。大量の乱数を必要とする場合は事前にコツコツ作っておくか、質の劣ることを理解した上でパスを```/dev/urandom```に書き換えてください。
鍵語による換字式暗号をPythonで

公開鍵暗号は「公開錠」と言えばわかりやすいんじゃないという話を見て、暗号の鍵って公開鍵暗号のためにこしらえられた単語ではないけどと思ったんですが、
もしかして皆さん、鍵語(キーワード)を使って換字表を生成するタイプの暗号を経由せずに、公開鍵暗号に挑戦しているのかなと思ったので書きました。

## 換字式暗号とは

換字式暗号とは文字を規則的に入れ替える暗号です。

問題としては
- 平文の言語的特徴が保存される(文字の出現頻度など)
- 平文と暗号のサイズが一致する
などがあります。

対策として
- 無意味な字を混ぜる
- 頻度の高い字は複数の変換先を用意する
- 複数字からなる文字列を変換単位にする
- 他の暗号と組み合わせる

などがあります。
しかし、その代わりに次のような利点を失うことになる場合があります
- 組み立てが簡単である
- 誤字・脱字があっても、暗号全文が読めなくなることはない

## Python によるサンプルコード

鍵語によって換字表を生成する暗号です。英文の小文字アルファベットのみを暗号化・復号化する簡単な暗号です。
換字表は鍵語から重複を排除して、その後ろに残ったアルファベットを並べて作っています。

```Python
import unittest


def get_unique_alphabet(alphabets: str) -> str:
    """指定したアルファベット内のユニークな小文字のアルファベットを返す"""
    unique_alphabets = [char.lower() for char in alphabets if char.isalpha()]
    return "".join(sorted(set(unique_alphabets), key=unique_alphabets.index))


def create_alphabet_mapping(unique_alphabet: str) -> dict:
    """ユニークなアルファベットのマッピングを作成する"""
    symbols = "abcdefghijklmnopqrstuvwxyz"
    alphabet_mapping = dict(zip(unique_alphabet, symbols[: len(unique_alphabet)]))
    return alphabet_mapping


def cipher(plain_text: str, keyword: str) -> str:
    """換字式暗号化関数"""
    symbols = "abcdefghijklmnopqrstuvwxyz"
    unique_alphabet = get_unique_alphabet(keyword)
    substitute_table = unique_alphabet + "".join(
        char for char in symbols if char not in unique_alphabet
    )
    alpha_map = create_alphabet_mapping(substitute_table)
    cipher_text = "".join(
        alpha_map.get(char.lower(), char) for char in plain_text if char.isalpha()
    )
    return cipher_text


def decipher(cipher_text: str, keyword: str) -> str:
    """換字式復号化関数"""
    symbols = "abcdefghijklmnopqrstuvwxyz"
    unique_alphabet = get_unique_alphabet(keyword)
    substitute_table = unique_alphabet + "".join(
        char for char in symbols if char not in unique_alphabet
    )
    alpha_map = create_alphabet_mapping(substitute_table)
    reversed_dict = dict(zip(alpha_map.values(), alpha_map.keys()))
    deciphered_text = "".join(
        reversed_dict.get(char, char) for char in cipher_text.lower() if char.isalpha()
    )
    return deciphered_text


# テストケースクラス
class Test_fbrkhs_key_qiita(unittest.TestCase):
    """換字式暗号のテスト"""

    def test_cipher_decipher(self):
        """暗号化と復号化のテスト"""
        keyword = "Hello, World"
        plain_text = "It is said that Drakon himself, when asked why he had fixed the punishment of death for most offences, answered that he considered these lesser crimes to deserve it, and he had no greater punishment for more important ones."
        cipher_text = cipher(plain_text, keyword)
        decipher_text = decipher(cipher_text, keyword)
        expected_result = "".join(char for char in plain_text.lower() if char.isalpha())
        # 復号化したテキストと元のテキストを比較
        self.assertEqual(expected_result, decipher_text)


# プログラムを実行してテストを実行
if __name__ == "__main__":
    unittest.main()

```
【電気工学】超音波モーター



# 超音波モーターとは


超音波モータ（ultrasonic motor：USM）は、金属製弾性体（振動子、ステータ）で発生した振幅数μmの固有振動（共振）を、摩擦力によって移動子（ロータ、スライダ）の回転や、並進運動に変換するアクチュエータです。1980年に指田年生氏によって発明されました。弾性体の固有振動数（共振周波数）が、超音波領域（20kHz以上）であることから超音波モータと呼ばれています。
固有振動は、振動子内部に配置された圧電セラミックス（PZT）により発生させます。

# メリット
一般の電磁モータと比較した場合の超音波モータの特長は、以下のようになります。
1. 低速・高トルク特性を有するため、減速機構が不要
1. 減速ギアが不要なため、静粛性に優れる
1. 非通電時に保持トルクを有する
1. 磁気の影響を受けず、電磁波を発生しない
1. 小型・軽量

# 欠点
一方、欠点は以下です。
1. 磨耗が大きいため、耐久性に劣る
1. 高速運転が困難
1. 高周波電源および複雑な駆動回路が必要

超音波モータは、以上に挙げた①～⑤の利点を活かし、一眼レフカメラのオートフォーカスや走査形電子顕微鏡、半導体製造装置、マイクロマシン製造装置などの精密位置決め機構に利用されています。
また、低速高トルク特性や非通電時のトルク保持特性を活かしてロールスクリーン・カーテンの昇降、ヘッドレストの位置決めにも使用されます。
さらに、磁力の影響を受けないモータという特徴を活かして、磁気を用いた医療診断機器であるMRIの本体や周辺機器等にも用いられています。


# 参考文献

https://www.nidec.com/jp/technology/motor/basic/00009/
Git で安全に rebase する方法

開発を進めていると、他のブランチの変更を取り込みたいと思うことがよくあります。

`git rebase` は、そのための強力なツールですが、使い方を間違えると開発ブランチを壊してしまうリスクもあります。

そこで、今回はバックアップブランチを作成してから `rebase` を行う方法を紹介します。

## ステップ1: バックアップブランチの作成

まずは現在のブランチの状態を確認しましょう。

```sh
git branch
```

次に、バックアップブランチを作成します。

```sh
git checkout -b backup/feature/awesome-feature
```

これで、もし何か問題が起きても元の状態に戻せるようになりました。

## ステップ2: rebaseの実行

元のブランチに戻ります。

```sh
git checkout feature/awesome-feature
```

`develop`ブランチの最新情報を取得します。

```sh
git fetch origin develop
```

そして、`rebase`を開始します。

```sh
git rebase origin/develop
```

## ステップ3: コンフリクトの解決

`rebase`中にコンフリクトが発生することがあります。その場合は、指示に従ってコンフリクトを解決しましょう。

```sh
git add .
git rebase --continue
```

問題が解決できない場合は、以下のコマンドで`rebase`を中止できます。

```sh
git rebase --abort
```

## ステップ4: 変更のpush

`rebase`が無事に完了したら、変更をリモートのブランチにpushします。履歴が書き換えられているため、`--force`オプションが必要です。

```sh
git push origin feature/awesome-feature --force
```

共有ブランチで作業している場合は、`--force-with-lease`オプションを使って他の開発者の変更を上書きしないようにしましょう。

```sh
git push origin feature/awesome-feature --force-with-lease
```

以上で、安全に`rebase`を行う方法の紹介は終わりです。この方法を使えば、`rebase`によるリスクを最小限に抑えつつ、開発ブランチを最新の状態に保つことができます。
streamlitでsave



myApp.py
```python

json

import json
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import time
import pathlib

def main():
    pass

if __name__ == "__main__":
    main()

```

pages/01_eva.py

```python

import json
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import time
import pathlib

# ページ設定===========================================================================================================
import json
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import time
import pathlib



def main():

    # ページ設定===========================================================================================================
    st.header('sensor_comp紐づけツール')

    # ファイル処理=============================================================================================================
    # 初回起動時や、JSONの形がおかしかった場合には,保存用JSONファイルを初期化する処理が必要
    pass

    #comp_dbの呼び出し
    with open('./dataset_common/comp_db.json', 'r', encoding='utf-8') as fr:
        comp_db_json = json.load(fr)

    #加速度計-評価対象機器の呼び出し
    with open('./dataset_acoustic/acc_evaluate_comp.json', 'r', encoding='utf-8') as fr:
        acc_evaluate_json = json.load(fr)

    # 変数定義==============================================================================================================
    comp_list = list(comp_db_json.keys())
    acc_list = ['acc1', 'acc2', 'acc3'] #いずれは自動取得したい

    # メイン処理=============================================================================================================
    # accの数だけマルチセレクトboxを作成
    for acc_name in acc_list:
        evaluate_list_saved = acc_evaluate_json[acc_name] #そのaccでの評価対象機器リスト(保存済み)を取得
        acc_evaluate_json[acc_name] = st.multiselect(acc_name, options=comp_list, default=evaluate_list_saved)

    #一次保存
    if st.button('一次保存', key='my_button2'):
        with open('./dataset_acoustic/acc_evaluate_comp.json', 'w', encoding='utf-8') as fw:
            json.dump(acc_evaluate_json, fw, indent=4)
        st.write('一次保存完了')
        st.write('最終保存時刻: ', str(datetime.datetime.now().strftime('%Y/%m/%d, %H:%M')))


if __name__ == '__main__':
    main()

```

acc_evaluate_comp.json
```python
#表を作成


```

comp_db.json
```python
{
    "acc1": [
        "comp1",
        "comp3"
    ],
    "acc2": [
        "comp1",
        "comp2"
    ],
    "acc3": [
        "comp3"
    ]
}

```

```python
{
    "comp1": {
        "mass_kg": 10,
        "x_rand": [40, 100, 400, 2000],
        "y_rand": [0.05, 0.2, 0.2, 0.03]
    },
    "comp2": {
        "mass_kg": 20,
        "x_rand": [40, 70, 200, 300, 1000, 2000],
        "y_rand": [0.05, 0.2, 0.2, 0.1, 0.1, 0.03]
    },
    "comp3": {
        "mass_kg": 20,
        "x_rand": [40, 250, 500, 2000],
        "y_rand": [0.05, 0.1, 0.1, 0.03]
    }

}


```
ロードアベレージが高いときの調査方法

# 【Linux】ロードアベレージが高いときの調査方法
## 概要と前談
私は、とある小さな企業で一人でサービスの開発、保守・運用をしているエンジニアである。
殿事業とはいえ、実務未経験でいきなりすべてを任されることになった。
もちろんそれほどLinuxなんぞ知らん状態であっても、担当者の力量など一切おかまいなしに、突然サーバーのアラートが上がる。そんなとき必死に調べておいたことを記しておく。


### Load averageとは
コンピュータの負荷を表す指標の一つで、CPUに割り当てられた実行待ちプロセス数の平均値。
この値が大きいほど性能に対して負荷が過大になっている状態。
ロードアベレージが問題ないかを考える基準として、CPUが1コアの場合、1未満であれば、問題ない。2コアなら2未満。
なので、まずはサーバーが何コア搭載かを調べておく。
コア数調べるには下記コマンド
```
grep cpu.cores /proc/cpuinfo | sort -u
```

AWSのEC2の場合の参考）
https://aws.amazon.com/jp/ec2/instance-types/



## 原因切り分け方
ロードアベレージが高かったとして、じゃあ何が原因かを知る必要がある。
アラートが入ったときに下記コマンドで今のLoad averageを調べる。
LoadAverageが高い時に調査を行わないと原因の切り分けが難しい。
```
uptime
```

もしリアルタイムでなかったとしても、下記コマンドで推移と発生時刻はわかる
```
sar -q
```
runq-sz：CPU を実行するためにメモリ内で待機中のカーネルスレッド数。通常この値は 2 未満
plist-sz：プロセスリストのプロセスとスレッド数
ldavg-1：過去1分間のロードアベレージ
ldavg-5：過去5分間のロードアベレージ
ldavg-15：過去15分間のロードアベレージ


そして原因の切り分けとして、大きく下記２つ
・CPU使用率
・I/O待ちが長い


それを判定するために下記コマンドを実行
-sの後は発生時刻

```
sar -u -s 21:00:00
```

項目意味
%user：アプリケーション（ユーザプロセス）が使用している状態
%system：カーネル（OSなど）が使用している状態
%iowait： ディスクI/O待ち状態
%idle：CPUが何の処理もしない待機状態（I/O待ちの時間は除く

### %userか%systemが高いと、CPU使用率という切り分けができる。
　%userが高いのはアプリケーション起因のCPU使用率がボトルネック
　%systemが高いのはアプリケーション以外の要因で生じるCPU使用率がボトルネック


 ### %iowaitが高いと、I/O待ちが長いという切り分け
　この場合、
　・スワップが発生している
　・スワップが発生していない
　の２つに分けられるので下記コマンド実行

 ```
 sar -r -s 21:00:00
 ```
### 【スワップが発生している場合、メモリ不足がボトルネック】
```
sar -r -s 21:00:00
```
 
項目意味
kbmemfree：メモリ空き容量(kb)
kbmemused：メモリ使用量(kb)
%memused：メモリ使用率
kbswpfree：スワップ空き容量(kb)
kbswpused：スワップ使用量(kb)
%swpused：スワップ使用率

 ### スワップが発生していない場合、ディスクI/Oがボトルネック
 ```
 sar -b -s 21:00:00
 ```

tps：秒間I/Oリクエスト 数の合計。
rtps：秒間読み込みIOリクエスト数の合計。
wtps：秒間書き込みIOリクエスト数の合計。
bread/s：秒間読み込み（ブロック単位）IOリクエストのデータ量の合計。
bwrtn/s：秒間書き込み（ブロック単位）IOリクエストのデータ量の合計
AWS AppSyncで、IAM認証を使ってコンソールからクエリを実行する際にやること

# 結論
AppSyncでIAM認証を用いて、AWS マネジメントコンソールからクエリを実行する際は、[公式ドキュメント](https://docs.amplify.aws/cli/graphql/authorization-rules/#use-iam-authorization-within-the-appsync-console)の通り、*amplify/backend/api/&lt;your-api-name>/custom-roles.json*を作成し、以下のように記載する。
```
{
  "adminRoleNames": ["<YOUR_IAM_USER_OR_ROLE_NAME>"]
}
```


# ことの発端

Amplify経由で、AppSyncを作成し、以下のようなschemaを作成しました。
```graphql
type User @model @auth(
    rules: [
      { allow: private, provider: iam }
    ]
  ){
  id: ID!
  name: String!
}
```
AWS マネジメントコンソールからcreateを実行したところ、
以下のエラーがコンソール画面に表示されました。
```
Not Authorized to access createUser on type User
```

# 原因
AWS マネジメントコンソールからクエリを実行する際は、どのIAMを使用するか、設定する必要があるため。

# 対処法
- *amplify/backend/api/&lt;your-api-name>/custom-roles.json*を作成する。
- [公式ドキュメント](https://docs.amplify.aws/cli/graphql/authorization-rules/#use-iam-authorization-within-the-appsync-console)のとおり、以下のように記載する。
    - ```json:custom-roles.json
        {
          "adminRoleNames": ["<YOUR_IAM_USER_OR_ROLE_NAME>"]
        }
        ```
    - 基本的には[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/security-authz.html#aws-iam-authorization)の通りロールを作成して、ロール名を入力すればよいと思います。
    - 面倒であれば、コンソールにログインするユーザ名を入力すればよいと思います。
- `amplify push`して、上記内容を更新する。

# 参考
* [Not Authorized to access createUser on type User](https://github.com/aws-amplify/amplify-cli/issues/9365)
JAWS FESTA 2023 in Kyusyuに初めて参加した

# はじめに
JAWS-UGが主催する全国規模の交流イベントJAWS FESTA 2023 in Kyusyuに参加してきました。
AWSを勉強し始めて約1年、今回がJAWS-UGイベントへの初めての参加です。
# JAWS FESTA 2023 in Kyusyu
[JAWS FESTA 2023 in Kyusyu](https://jft2023.jaws-ug.jp/)
日程：2023年10月7日(土)
場所：福岡工業大学
テーマ：くらうどどんたく　会って、学んでよかろうもん
内容：全7つのトラックで並行開催
メイン、九州事例、スタートアップ1、スタートアップ2、お祭り、コミュニティ、ハンズオン
# 今回JAWS FESTAに参加してみた理由
そろそろコミュニティイベントに参加してみたいと思っていたから。
そして、FESTAというイベント名が面白そうだったからです。
# 技術系セッション
メイン、九州事例、スタートアップトラックでは、AWS事例のセッションがありました。
九州開催ということもあり、地方特有の農業システムのセッションや、全国どこにでもある病院の医療システムなど、身近なAWS事例が多かったです。
正直、難しくてなかなか理解できていない部分も多かったですが、部分的な理解を目指して聴講しました。
# コミュニティセッション
コミュニティの成長、持続性、多様性、新たな可能性を広げるための活動や経験を共有するためのコミュニティトラックでのセッションです。AWSは関係なく、コミュニティ活動という点にフォーカスしたテーマです。
一番気になったセッションは、ハックツハッカソンコミュニティ所属びきにきさんの「[1人の学生が提唱する、技術コミュニティに若手をどう取り込むか戦略 2023](https://jft2023.jaws-ug.jp/session/community_07/)」です。
多くの技術コミュニティが抱えている「若手が少ない」という課題は、新卒2年目の自分としても気になります。そして、若手が技術コミュニティに参加しない理由として挙げられていたのはこんな意見でした。
- 強い人しか行ったらダメっぽい
- 知識がないと話の内容が分からなさそう
- 話を聞くだけじゃつまらん

JAWS FESTA参加前の自分であれば、首がもげるほど同意していたと思います。
少なくとも、JAWS FESTAはAWS初心者でも楽しめたし、知識がなくても分かる話はあったし、体験型コンテンツもあったので、先入観と偏見だけで行かないのはもったいないと思います。
百聞は一見に如かず、まずは一度参加してみることが大事だなと思いました。
# お祭りトラック
[JAWS FESTA版！グループ対抗 AWS ウルトラクイズ](https://jft2023.jaws-ug.jp/session/festa_03/)に回答者として参加しました。AWS歴1年、AWS認定はアソシエイトレベルしか所持していない状態で、どこまで楽しく参加できるのか少し不安でしたが、ばっちり楽しむことができました。
そもそも出題内容がマニアックなので、ベテラン勢も苦戦していたようで安心でした。そんな中でも自信をもって回答できたものもあり、少し自信に。惜しくも優勝は逃してしまいましたが、JAWS-UGの雰囲気を知るという点で参加して良かったイベントです。
![IMG_6209.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3434748/13b7784d-afbb-aae5-552f-21462059cc4d.jpeg)

# JAWS FESTAに参加してみた感想
- イベント名通り、お祭りのようで楽しかった
- 参加者から強いAWS愛を感じられた
- 身内ノリは少し戸惑いを感じた
- AWS初心者の参加を歓迎してもらえて安心した

**Q. JAWS FESTAに参加して良かったか？**
**A. 良かった**
自分の目で見て、コミュニティ参加のメリット・デメリットを自分の感覚で確認することができたから。
AWSの楽しさとAWSへの情熱を感じられました！
![IMG_6234.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3434748/cd810f97-14bb-1933-0459-96143a28d9fd.jpeg)
Pythonのf文字列

# はじめに
printやテキストボックスへの出力時に活躍するf文字列についてまとめる。

 # f文字列とは
 Python3.6から対応された文法。文字列内に変数を埋め込む場合、```{変数}```でくくれば良く、```format()```よりスマートに記述が可能。

タイプ|コード
 ---|---
 f文字列|a = 100<br>print(f'# これは{a}円です。')<br># これは100円です。
 format()|a = 100<br>print('# これは{}円です。'.format(a))<br># これは100円です。

 # f文字列例
 ```format()```ではできない(頑張ればできるのかもしれないが。)、変数名出力や、計算式を埋め込むこともできるのが便利。

```python:fstring_test.py
#基本
a = 1000
b = 0.12345
print(f'# int型:{a} float型:{b}')
# int型:1000 float型:0.12345

#桁区切り(3桁区切り)
a = 1000
print(f'# int型:{a:,}')
# int型:1,000

#0埋め(8桁右詰め,8桁0埋め)
a = 1000
print(f'# int型:{a:8} int型:{a:08}')
# int型:    1000 int型:00001000

#桁指定(小数点3桁四捨五入)
a = 0.12345
print(f'# float型:{a:.3}')
# float型:0.123

#パーセント(小数点2桁%)
a = 0.12
print(f'# パーセント:{a:.2%}')
# パーセント:12.00%

#進数変換(16進数,2進数)
a = 100
b = 12345678
print(f'# 16進数:0x{a:x}, 0b{a:b}')
print(f'# 16進数:0x{b:08x}, 0b{b:032_b}')
# 16進数:0x64, 0b1100100
# 16進数:0x00bc614e, 0b00_1011_1100_0110_0001_0100_1110

#符号(+付き,+をスペース)
a=100
b=-100
print(f'# 符号:{a:+} {b:+}')
print(f'# 符号:{a: } {b: }')
# 符号:+100 -100
# 符号: 100 -100

#変数名出力
a = 1000
print(f'# 変数名:{a=}')
# 変数名:a=1000

#式計算(整数変換)
a = 100.123456
print(f'# 式計算:{int(a)}')
# 式計算:100

#辞書型(""注意)
d={'a':100,'b':0.123456}
print(f'# 辞書型:{d["a"]},{d["b"]}')
# 辞書型:100,0.123456

#いろいろ組み合わせ
d={'a':100,'b':0.123456}
print(f'#組み合わせ:{d["a"]=:04X}')
print(f'#組み合わせ:{d["b"]=:+.2%}')
#組み合わせ:d["a"]=0064
#組み合わせ:d["b"]=+12.35%

# 型や桁指定自体もフォーマット文字にできる。可変にできる。
d={'a':100,'b':0.123456}
format_type1='04X'
format_type2='+.2%'
print(f'#組み合わせ:{d["a"]=:{format_type1}}')
print(f'#組み合わせ:{d["b"]=:{format_type2}}')
#組み合わせ:d["a"]=0064
#組み合わせ:d["b"]=+12.35%

```
以上