OmniAICreator/Qiita-1.07M huggingface dataset:
Poetry

## はじめに
備忘録
poetryの使い方をまとめたのでqiitaに残しておく
npm(jsのpackage管理ツール), pip, poetryの比較も最後に載せておく

npmがわかる人向けに端的にまとめると、`python`のinstall時にくっついてくる`pip`はグローバルインストールしかできないし、`package.json`みたいな依存関係を表すファイルを生成してくれない。
`poetry`を使うと、ディレクトリ単位で`package`を管理できて 依存関係ファイルも生成してくれて楽

## poetry
*パッケージ管理を行う。*
*プロジェクト環境を隔離する (仮想速度を作る)*

*installしたpackageは.venvに保存される。 
.venvは仮想環境であるため、コマンド実行は仮想環境で行う*

*初期化*
```shell
# 既存アプリの場合 (npmの使い方に似てるのでこっちが好き)
poetry init

# 新規アプリの場合
poetry new <dir_name>
```
*package追加*
```shell
poetry add [package]
# 開発環境でのみ
poetry add --dev [package]
```

*削除*
```shell
poetry remove [package]
```

*既存のpyproject.tomlを利用してinstall*
```shell
poetry install

# 本番環境のみ
poetry install --no-dev
```

*package一覧*
```shell
poetry show
```
*仮想環境*
*仮想環境で実行することで、ホストの環境によってエラーが出ることを防げる*
*同一ホストで複数のアプリを開発している際、他の影響を受けなくなる*
```shell
# 仮想環境でコマンドを実行する
poetry run [コマンド]

# 例
poetry run python main.py
```
*pythonの仮想環境とはインストールしたmoduleやpackage、
Pythonのversionごとに分離された環境のこと*
```shell
# 仮想環境に入る
poetry shell
```

## 仮想環境の管理
```shell
# 仮想環境一覧
poetry env list

# 仮想環境削除
poetry env remove [id]
```
```shell
poetry config --list

# 同一階層に仮想環境ファイル (.venv)を作るようにする
poetry config virtualenvs.in-project true
```

```python
# 仮想環境を作らないようにする
# コンテナで実行する場合などに有効
# パッケージのインストール先がシステム環境のpythonに紐づく
poetry config virtualenvs.create false

# 該当プロジェクトでのみ有効にする
poetry config virtualenvs.create false --local
```

[globalのpackageと仮想環境のpackageを併用できる](https://blog.ingage.jp/entry/2022/11/02/172545)


`pyproject.toml`
*プロジェクトの依存関係を管理する*
```shell
[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["“tee” <“asuasu.tee@gmail.com”>"]
readme = "README.md"
packages = [{include = "poetry_demo"}]

[tool.poetry.dependencies]
python = "^3.10"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
```

## npmとの比較
`npm`はjavascriptのpackageマネージャーです。
```js
// npmのpackageのインストール方法は3つあります。

// ローカルインストール (ディレクトリ内部にnode_modules/を作成してその中にいれる)
npm　i [package]

// ローカルインストール && 開発時のみ (node_modules/に入れる 本番環境では利用されない)
npm i -D [package]

// グローバルインストール (システムで使用しているnodeに紐づいてinstallされる)
npm i -g [package]
```

`pip`
*pythonのpackageマネージャー*
```python
# グローバルインストール (システムで使用しているnodeに紐づいてinstallされる)
pip install [package名]
```

そうpipは強制的にグローバルインストールになっちゃいます。

npmみたいにディレクトリ単位で管理できないので、いろんなプロジェクトで使用したパッケージがごちゃごちゃ混ざって競合します。

そこで`poetry`です。
`poetry`を使えば各アプリケーション(ディレクトリ)単位でpackageを管理できます。
*下記設定をすれば、`.venv`はディレクトリ内部につくられるようになるのでnpmと似た感覚で使えます*
```shell
# 同一階層に仮想環境ファイル (.venv)を作るようにする
poetry config virtualenvs.in-project true
```


また`pip`は`npm`でいうところの`package.json`を生成しないので、コンテナでの管理が面倒です。`requirement.txt`というファイルを手動で管理する形になります。
`poetry`を使うと`poetry.lock`や`pyproject.toml`を生成してくれるので管理が楽です


## 終わりに
なんで`pip`はグローバルインストールしかできないのだ？
`npm`を見習ってほしいのだ
もしかしてできるのだ？　いやできないのだ
野田
node 漢字 to ローマ字

## install

```bash
npm install xlsx
npm install kuroshiro@1.1.2
npm install kuroshiro-analyzer-kuromoji
npm install synchronized-promise
```

## sample

```js
const Kuroshiro = require("kuroshiro")
const KuromojiAnalyzer = require("kuroshiro-analyzer-kuromoji");
const sp = require('synchronized-promise')
//console.log(Kuroshiro)
const kuroshiro = new Kuroshiro();
let syncFunc = sp(sample)
const value = syncFunc("名無しの権兵衛")
console.log(value)

async function sample(str) {
    try {
        await kuroshiro.init(new KuromojiAnalyzer())
        let val = await kuroshiro.convert(str, {
            romajiSystem:"passport", to:"romaji",
        })
        //console.error(val);
        return val
    } catch (err) {
        console.error(err);
    } 
}
開発タブを表示させる

①開発タブを表示させる
1.［Excel］メニューの［環境設定］を選択します。
![スクリーンショット 2023-03-09 13.54.44（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/38400fd1-6309-3a30-9263-f76f07b2025c.png)

2.Excel 環境設定の［表示］を選択します。
![スクリーンショット 2023-03-09 13.54.51（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/93a82a2c-3bf3-785a-e630-15b2197bbe52.png)

3.［リボンに表示］グループより［開発者タブ］にチェックを入れて閉じます。
![スクリーンショット 2023-03-09 13.54.55（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/a5669000-f25a-c1a9-09eb-56c38f732592.png)

4.［開発］タブが表示されました。
![スクリーンショット 2023-03-09 13.55.01（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/8d3bb8aa-8999-2b3a-c26a-02efd0d3b0b9.png)
Do you already have another mysqld server running on port: 3306 ?


## 【開発環境】
windows11 pro
Laravel Framework 9


## 【現象】

dockerでmysqlが起動せず、docker desktop のログにこんなエラーメッセージが出現。

```
Do you already have another mysqld server running on port: 3306 ?
```

## 【原因】

mysqlのプロセスが実行中であるため。


## 【対策】

TCP/IP通信の状態を一覧表示。
mysqlのPIDを探す。

```
netstat -aon
```

コマンドプロンプトで実行するとこんな一覧が出るはず。
![コマンド プロンプト 2023-03-09 13.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/97975752-1621-ba61-693a-b7af420c0151.png)

アドレスからmysqlのポート番号である「3306」を探して
それに対応するPIDを探す。


mysqlのプロセスをPIDでkillする。
(仮にxxxx をmysqlのPIDとする)

```
taskkill /pid xxxx /f
```

無事にmysqlが起動出来ました。



## 【参考】
https://stackoverflow.com/questions/61194498/errorserver-do-you-already-have-another-mysqld-server-running-on-port-3306
PHPUnit の processIsolation と log4php の LoggerAppenderConsole の相性が悪いので直す

## TL;DL

タイトル通り、PHPUnit+log4phpは相性が悪く動かない可能性があります。
回避策として ~~直接`LoggerAppenderConsole`を修正する~~ `LoggerAppenderEcho`を利用するか`processIsolation`を無効にします。
できればlog4phpを使わないようにしたほうがいいと思います。

## 発生条件

- PHPUnitを使用している
    - オプションで`processIsolation`を有効にしている
- テスト対象、またはテストでlog4phpを使用している
    - かつ、LoggerAppenderConsoleを使用している

## 何が起こるの？

サンプルプロジェクトをおいておきました。
こちらを実施すると画像のようなエラーになります。

https://github.com/tu0607/temp_log4php_sample

![Screen Shot 2023-03-09 at 13.01.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155931/11a52861-48c3-e800-129c-cdd8919b4d36.png)

## なんで発生する？

~~log4phpの実装が悪いです。~~

PHPUnitの`processIsolation`を有効にしていると、子プロセスのテスト結果がシリアライズされて、標準出力経由で親プロセスとやりとりされます（エラーでブワーッと出てしまっているのはこのシリアライズされた値です）。

通常、テスト中に出力された文字はバッファされて適切に扱われるのですが、log4phpが標準出力されるべき値を上書いてしまう場合があります。

```vendor/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php
 class LoggerAppenderConsole extends LoggerAppender {

	/** The standard otuput stream.  */
	const STDOUT = 'php://stdout'; // <- ここが原因！
```

## どうすれば直る？

log4phpを使わない！（暴論）
すでにlog4phpプロジェクトは動いていなく、Issue,PRも何年も放置されています…（なので記事にしました）
また、PHP8.1以降ではDeprecatedとなりまともに動かせなくなります…

`processIsolation`を無効にするのもOKだと思います。

とはいえ、大人の事情ですぐに対応できないという場合もあるかもしれません。
そのような場合はこうします。

```vendor/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php
 class LoggerAppenderConsole extends LoggerAppender {

	/** The standard otuput stream.  */
	//const STDOUT = 'php://stdout';
	const STDOUT = 'php://output';  // <- 'php://output'にする！
```

（2023/03/17 追記）

この修正をすることでテストは動くようになりますが、LoggerAppenderConsoleを利用しているWEBアプリ側でログがechoされてしまうようになりました。
なので、LoggerAppenderConsoleが強制的に'php://stdout'を指定しているのは正しい動きになり、この修正は適当ではないです。

環境変数などを用いてテストのみLoggerAppenderConsoleではなく代わりにLoggerAppenderEchoを利用するような作りにするのが妥当だと思います。

## 'php://output'？

[公式](https://www.php.net/manual/ja/wrappers.php.php)を見てみるとこんな使い分けになっています。

> php://output
> php://output は書き込み専用のストリームで、 print および echo と同じ方法での出力バッファへの書き込みを許可します。

`print()`や`echo()`は、特に何もしていなければ標準出力に、`ob_start()`などでバッファリングを有効にしている場合はバッファに書き込むようになります。

対して、`php://stdout`または定数`STDOUT`を指定して出力した場合、 **バッファリング中だったとしても、強制的に標準出力に文字を吐き出します**


なので、`processIsolation`有効時、本来はPHPUnitのシリアライズされた結果が欲しいのですが、log4phpによって余計な文字が付いてきたり上書きされてしまったりしてデシリアライズできなくなるみたいです。

## おまけ

まだまだlog4php使われていそうですね…

![Screen Shot 2023-03-09 at 13.30.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155931/f01d0291-9c57-d362-d83d-c225b2b9596e.png)
SwiftでのApplication Extensionの種類

SwiftでのApplication Extensionには、以下のような種類があります：

Today Extension（ウィジェット拡張機能）
通知センターに表示される小さなウィジェットの形式の拡張機能です。iOSアプリケーションで、あなたが提供する機能の一部をユーザーが直接通知センターから利用できるようにします。


Share Extension（共有拡張機能）
他のアプリから共有されたコンテンツを処理するための拡張機能です。ユーザーは、アプリケーション外からコンテンツを共有することができ、共有拡張機能がそのコンテンツを処理することができます。


Action Extension（アクション拡張機能）
他のアプリのコンテンツに対してアクションを実行するための拡張機能です。例えば、Safariから画像を共有するときに、その画像をTwitterで共有するときに、その画像にフィルターをかけることができるようになります。


Photo Editing Extension（写真編集拡張機能）
写真アプリケーションで使用される拡張機能で、写真の編集機能を提供します。ユーザーは、写真アプリから写真を選択し、編集拡張機能を使用して写真を編集することができます。


Document Provider Extension（ファイル共有拡張機能）
他のアプリからアクセスできるようにするファイル共有のための拡張機能です。ユーザーは、Document Provider Extensionを使用して、クラウドストレージサービスやファイル管理アプリケーションに保存されたファイルにアクセスすることができます。


Audio Unit Extension（オーディオユニット拡張機能）
音声や音楽を処理するための拡張機能です。音声合成やエフェクトの追加など、音楽アプリケーションやサウンド編集ツールなどで使用されます。


iMessage Extension（iMessage拡張機能）
iMessageアプリの中で利用される拡張機能で、ステッカーや絵文字、GIFなどのコンテンツを提供します。また、カスタムインタフェースを作成してiMessageアプリの機能を拡張することもできます。

Intents Extension（インテント拡張機能）
SiriKitと連携して、アプリの機能をSiriから操作できるようにする拡張機能です。例えば、音楽アプリで再生する曲をSiriから指示することができます。


Network Extension（ネットワーク拡張機能）
ネットワーク通信の拡張機能で、VPNやプロキシなどの機能を提供します。これにより、アプリからのネットワーク通信を保護したり、特定の通信をブロックすることができます。


Smart App Banner Extension（スマートアプリバナー拡張機能）
Webページ上でアプリを紹介するための拡張機能で、ユーザーがWebページ上でアプリを開くことができるようにします。この拡張機能は、WebページがAppleの規定に従って作成されている場合に表示されます。

Finder Sync Extension（Finder Sync拡張機能）
macOSで使用される拡張機能で、Finderのサイドバーにアプリケーション固有のオプションを追加します。ユーザーは、Finderで特定のファイルやフォルダーを選択し、アプリの拡張機能を使用してファイルやフォルダーを処理することができます。


Xcode Source Editor Extension（Xcodeソースエディタ拡張機能）
Xcodeのソースエディタで使用される拡張機能で、ユーザーがソースコードを編集するときに補完や自動変換などの機能を提供します。開発者は、この拡張機能を使用して、Xcodeのソースエディタで作業効率を向上させることができます。


Siri Media Intent Extension（Siriメディアインテント拡張機能）
SiriKitと連携して、音声アプリの再生やコントロールをSiriから操作できるようにする拡張機能です。音声アプリケーション開発者は、この拡張機能を使用して、Siriとのシームレスなインタラクションを提供することができます。


Notification Content Extension（通知コンテンツ拡張機能）
iOS 10以降で使用される拡張機能で、通知センターからのプッシュ通知に対してカスタムUIを提供します。開発者は、この拡張機能を使用して、通知に対して追加の情報やアクションを提供することができます。


Notification Service Extension（通知サービス拡張機能）
iOS 10以降で使用される拡張機能で、通知センターからのプッシュ通知をカスタマイズするための拡張機能です。開発者は、この拡張機能を使用して、通知の音声合成や動画再生などの機能を追加することができます。



これらの拡張機能は、アプリケーションの機能を拡張して、ユーザーエクスペリエンスを向上させることができます。アプリの開発者は、アプリの目的や使用されるプラットフォームに応じて、適切な拡張機能を選択し、実装することが重要です。
Python Docker poetry

##　はじめに
備忘録
fastAPIの学習をするにあたりpoetryで環境を作ります。

## 構成
*新規立ち上げ時はDockerfileのCOPYとRUNを修正してpoetryの初期化を行う*
```
app/
  main.py
  poetry.lock
  pyproject.toml
docker-compose.yml
Dockerfile
.env
```
`Dockerfile`
```Dockerfile
FROM python:3.10.10-bullseye

# poetryのPATHを$PATHに追加
ENV PATH /root/.local/bin:$PATH

WORKDIR /app

COPY ["./app/pyproject.toml", "./app/poetry.lock", "/app/"]

RUN apt-get update \
    && curl -sSL https://install.python-poetry.org | python3 - \
    && poetry config virtualenvs.create false \ # コンテナなので仮想環境はいらない
    && poetry install

# コンテナ実行後に行いたいコマンドを記述する FastAPIの場合の例は下記
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
```

`docker-compose.yml`
```yml
version: "3.8"
services:
  app:
    build:
      context: ./
      dockerfile: ./Dockerfile
    env_file: ./.env
    tty: true
    volumes:
      - ./app:/app
    ports:
      - "8000:8000"
    environment:
      - TZ=Asia/Tokyo
  db:
    image: mysql:8.0.31
    platform: linux/amd64
    env_file: ./.env
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    volumes:
      - ./db/data:/var/lib/mysql
      - ./db/conf.d:/etc/mysql/conf.d
    ports:
      - 3306:3306
    environment:
      TZ: Asia/Tokyo
```

## おわりに
poetryでtypingをインストール使用して詰まった
typingはpythonの標準パッケージなので別途インストールする必要はなかった
VoltMX Irisでテキストエリアにコピー&ペーストができない時の対処法

# 目次
1. はじめに
1. 事象
1. 解消方法


# はじめに
VoltMX IrisまたはVisualizerを使って、TextAreaにコピーアンドペーストを行いたい場合、
Paste Board Typeをデフォルトの「SytemLevel」に設定していても、
テキストのコピーアンドペーストができないという不具合があります。
（2023年3月9日 VoltMX 9.5.5利用時点）

今回はその解消方法について説明したいと思います！

# 事象
TextArea WidgetのPROPERTIES->TextArea->iPhone->Pasteboard Typeを
「SytemLevel」に設定しているがコピーアンドペーストができない。
TextBoxに同じ設定をしている場合、問題なくコピペができる。

![ezgif-5-f6cde29a70.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/29281491-16be-ec7b-d731-d234eb1b0e9f.gif)


# 解消方法
TextArea Widgetでコピペを有効にしたい場合、
Pasteboard Typeを「System Level」ではなく「**Default**」に設定しましょう！

![スクリーンショット_0005-03-09_13_12_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/f4f4dd87-92e3-daec-2fa4-334855d40760.png)

また、念の為Project SettingsのPaste Board Typeの設定も確認しましょう。
以下の設定画面を開き、Paste Board Typeが「SytemLevel」になっていることを確認してください。
※デフォルト設定で「System Level」になっているはずなので、その設定になっているか改めてご確認ください。

![スクリーンショット_0005-03-09_13_14_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/dbefa6c8-a40a-bcd6-a0f3-f143fab154c0.png)

これで設定は完了です。正常に動作するか見てみましょう！

![ezgif-2-62652218a4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/00289481-42ae-980b-07ce-4ee98ade4cb1.gif)

TextAreaにも正常にテキストのコピペができるようになりました！


# 最後に
今回紹介した内容はHCL社にバグとして報告済みですので、今後修正されると思いますが、
もしテキストエリアでコピペができなくて困っている方がいたら、
紹介した方法で回避できるので是非参考にしてみてくださいね！
has_secure_password その２

# 一体何を書いているのか？
```rb
class << self
      attr_accessor :min_cost # :nodoc:
    end
    self.min_cost = false
.
.
.

cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost)
```
# 出典
has_secure_password.rb
https://gist.github.com/thirotan/013f0336025b1644facc#:~:text=Raw-,has_secure_password.rb,-module%20ActiveModel

### 条件演算子(三項演算子)
```
式 ? 真だった場合の処理 : 偽だった場合の処理
```
### 出典
https://gihyo.jp/book/2017/978-4-7741-9397-7

### ```self.min_cost = false```が偽を返している
```BCrypt::Engine.cost```が作動する

> .cost ⇒ Object
Returns the cost factor that will be used if one is not specified when creating a password hash.

パスワードハッシュを作成する際に、```指定がない場合に使用されるコストファクターを返します```。
出典　deepl

https://www.rubydoc.info/github/codahale/bcrypt-ruby/BCrypt/Engine#:~:text=than%20upper_time_limit_in_ms.-,.cost%20%E2%87%92%20Object,used%20if%20one%20is%20not%20specified%20when%20creating%20a%20password%20hash.,-.cost%3D

# コストファクターとは


Bcrypt
Bcryptは暗号の1つであるBlowfishを基盤としたハッシュ関数です。Argon2ではパラメータを3つ指定できましたが、Bcryptではコストと呼ばれる強度を調整するパラメータがあり、コストが12の場合、反復回数は2の12乗になります。

https://recruit.cct-inc.co.jp/tecblog/security/hash-function/#:~:text=%E8%A8%80%E3%81%88%E3%82%8B%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%80%82-,Bcrypt,%E5%A0%B4%E5%90%88%E3%80%81%E5%8F%8D%E5%BE%A9%E5%9B%9E%E6%95%B0%E3%81%AF2%E3%81%AE12%E4%B9%97%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,-PBKDF2

ストレッチング回数（コストパラメータ）
次に「$10$」の「10」はストレッチング回数を示します。この数字は2のn乗のn部分を示しているので、今回は2の10乗で1024回ストレッチングされています。

https://medium-company.com/bcrypt/#i-4:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E3%82%B9%E3%83%88%E3%83%AC%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0%E5%9B%9E%E6%95%B0%EF%BC%88%E3%82%B3%E3%82%B9%E3%83%88%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%EF%BC%89,%E3%81%AE10%E4%B9%97%E3%81%A71024%E5%9B%9E%E3%82%B9%E3%83%88%E3%83%AC%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82,-%E3%82%BD%E3%83%AB%E3%83%88%EF%BC%8822%E6%96%87%E5%AD%97

ハッシュ化されている文字列はいくつかの区分に分けられます。
まず 最初の $ $ で 囲われている部分はバージョンです。
次に $ $で囲われているのは、コストの部分です。
これは、2を基数とした指数となり、この数の2の累乗がEksblowfishでのセットアップ中での繰り返し回数になります。(ストレッチング)
この回数が多ければ、```ブルートフォース攻撃になどに対する対抗が強くなります```が、その分計算量が増えて計算に時間がかかるようになります。

https://spring-mt.hatenablog.com/entry/2020/08/22/225751#:~:text=%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E5%8C%96%E3%81%95%E3%82%8C%E3%81%A6,04%24vLCmqS2n9tnYpnKT.G9wJuhBPjtKakH2/9zOQuU1IIv.HIDj6q27e

# 感想
```Mysql2::Error: Unknown column 'users.password' in 'where clause'```
でエラーが起きた。
テーブルにpasswordではなくpassword_digestを入れていたからだ。
このエラーの解決法がわからなかった。
代替法でpassword_digestに直接加えたらハッシュ化できるようになった。

解決法はわからなかったが、どういうふうにパスワードがハッシュ化されているかのかを少し学習できてよかった。
解決法がわからなければコードを見て自分なりに理解できる範囲で妥協ぐらいのことはできると思うので
これから頑張りたい。
Javaを基本からまとめてみた【コンストラクタ・デフォルトコンストラクタ】

## コンストラクタとは？
- インスタンス化されると同時に自動で動き出す特殊なメソッド。フィールドに実態を定義する上で、必要な初期値を代入する役割を担う。
- インスタンス化が起こった際に自動でフィールドを初期化する特殊なメソッドを定義することが可能であり、これをコンストラクタという。

- コンストラクタは以下のルールと特徴がある。
○ コンストラクタの定義において戻り値の情報は何も記述しない　※void不要 
○ コンストラクタ名はクラス名と同じ　※メソッドのルールを外れ、大文字の命名となる
○ インスタンス生成時、必ず最初に呼び出される

- 実はインスタンス化の右辺はコンストラクタを表しており、右辺の（）内にフィールドの初期値として設定したい値を入れておくと、コンストラクタに値渡しされてフィールドの初期化が行われる。
```
クラス名　インスタンス名　= new  クラス名（引数）;
                       ※コンストラクタを表しています

```
- コンストラクタはメソッドの一種なので、様々な引数パターンに応じてオーバーロードして定義することは可能です。



```Sample2.java
class Sample2_drive {
 public static void main(String[] args)

 System.out.println("車を場に搭乗させる")
 car chocoCar = new Sample2_car();
 car mocoCar = new Sample2_car("クーペ","red",80);

//コンストラクタ①(引数無し)

Sample2_car(){
 System.out.println("コンストラクタ① (引数無)");
 carModel = "未登録"; //車種
 color = "未登録"; //色
 speed = 0; //現在の速度
 System.out.println("○ ○");
}

//コンストラクタ②(引数有り)

Sample2_car(String cm, String cl, int sp){
 System.out.println("コンストラクタ② (引数有)");
 carModel = cm; //車種
 color = cl; //色
 speed = 0; //現在の速度
 System.out.println("○ ○");
}

```
## デフォルトコンストラクタ

- コンストラクタは、インスタンス化の際は必ず実行される。もしもコンストラクタがソースコード内で実行されていない場合、裏で引数無し/処理無しのコンストラクタが補われて実行され、これを『デフォルトコンストラクタ』と言う。
- デフォルトコンストラクタじゃソースコード内に１つでもコンストラクタが定義されていた場合、補われない。


## 参考サイト
[【Java-オブジェクト指向】Javaプログラミングの「オブジェクト指向」が絶対理解できる講座【プロ講師が丁寧解説】](https://www.udemy.com/course/uz-java-obj/learn/lecture/21205574#overview)
ChromeのDevToolsのUIだけで画像をbase64エンコードする

https://qiita.com/nakajmg/items/54812f7daf4e1a0f0857

こちらを拝見して試したところ、HTMLファイルを作らなくても画像をBase64エンコード可能だったためその方法を記します。

## 1.Chromeで画像を開く
画像をタブエリアにドラッグ&ドロップ

<img alt="画像をタブエリアにドラッグ&ドロップ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/3fdf5980-6b38-b930-2bb7-f5d341bc671c.png">

ローカルの画像が表示される
<img alt="ローカルの画像が表示される" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/d889a3bd-a978-9d53-c14e-a6e1194592cc.png">

## 2.DevToolsを開く

<img alt="DevToolsを開く" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/1d645a6f-f39b-e489-a355-980db8d50e9c.png">

## 3.「Application」 > 「Frames」 > 「top」配下の画像を選択

<img alt="「top」配下の画像を選択" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/224b06c5-a00b-8644-a6fd-df64110ca73f.png">

## 4.画像の右クリックメニューから、Base64エンコードされた文字列を取得する

「Copy image as data URI」を選択
<img alt="「Copy image as data URI」を選択" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/96c2b863-9942-715b-8d92-63313298b3dd.png">

## 5.新しいタブのアドレスバーにペースト

ちゃんとコピーされている
<img alt="ちゃんとコピーされている" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/70068540-3afa-f58c-0258-98bfe2b04796.png">

# ドラッグ&ドロップでもOK

## 4.右の画像をタブエリアにドラッグ&ドロップ

<img alt="右の画像をタブエリアにドラッグ&ドロップ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/0e2e39c2-7388-ee9a-dee4-f5533cf5f0b4.png">

DevToolsの画像が表示される
<img alt="DevToolsの画像が表示される" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/719b1356-41ee-bb0e-1f14-2039d65e8b3f.png">

## 5.アドレスバーから、Base64エンコードされた文字列を取得する

<img alt="アドレスバーから、Base64エンコードされた文字列を取得する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246392/482f8a96-bdae-e00b-56f3-9fea8385c0da.png">

DevToolsで簡単に画像がBase64エンコードできました！
AWS 初心者勉強会〜コンピュートサービス編〜

会社に入ってもうすぐ1年が経とうとしています。
弊社ではAWSを使っていますが、理解を深めるためにAWS JumpStart 2023（https://aws.amazon.com/jp/blogs/news/aws-jumpstart-202302/） に申し込みました。
参加するにあたって事前に勉強するための動画が用意されていたので、そちらを元にAWSのサービスの説明を書いていきます。

今回はコンピュートサービス編です。

# EC2
EC2とはAWSの仮想サーバー

#### 特徴
- 数分で起動、1秒ごとに従量課金（例：1秒使ったら1円の場合、１時間使ったら3600円）
- さまざまなOSをサポート、ライセンス費用込みで従量課金

Amazon Linux、CentOS、Debian、Kali、Red Hat、SUSE、Ubuntuなどが使えます。
- 自由にソフトウェアのインストールが可能


- スケールアップ/ダウン、アウト/インが容易に可能

スケールアップ/ダウンは垂直スケーリングとも言われており、インスタンスのスペックを変えることを言います。
スケールアウト/インは水平スケーリングとも言われており、インスタンスの数を変えることを言います。

#### 購入オプション
1. オンデマンドインスタンス
初期費用なし、従量課金
利用していない時間帯は停止しておくことで節約できる

2. リザーブドインスタンス
1年、3年単位の契約で、オンデマンドインスタンスと比べて最大７５％割引
Savings Planという購入オプションもあり、インスタンスファミリーやサイズの変更がある可能性がある場合はこちらの方が良いです。

3. スポットインスタンス
未使用のインスタンスを利用、オンデマンドインスタンスと比べて最大９０％割引
空きリソースが少なくなると2分前に通知が来た後終了させる

#### AMI
EC2インスタンスを起動する際に必要な情報が格納されたマシンイメージ
AMIを利用することでセットアップ済みのサーバを容易に準備可能

#### オートスケール
サービスの需要に合わせてサーバー等の台数を自動で変化させる仕組み
また、指定した時間だけ５０台に増やすなども可能
インフラコストを最適化し、インフラ管理・需要予測の手間を削減可能

# CloudWatch
オートスケールに関して必要なサービス
AWSの各種リソースを監視するサービス
リソース状態、性能、ログ監視やそれらをメトリクスのグラフ化をして可視化できる
メトリクスをベースにアラーム、アクションの設定が可能

#### オートスケーリングとの組み合わせ
例として、Auto Scaling Groupの設定でCPU使用率を常に５０％程度を維持するといった設定をします。
CloudWatchがCPU使用率の監視を行い、50%を超えると通知されてAuto Scaling Groupが自動でインスタンスを追加するといったことをします。
そして、またCPU使用率が50%以下になるとインスタンスを減らしていくといった動作をします。

# Lambda
サーバーレスのサービス
EC2と比べて自由度が低い代わりに、管理の手間は少ない

#### 特徴
- サーバーのプロビジョニング/管理なしでプログラムを実行できるサービス
- 開発者はコードを書くことに集中できる
- リクエストベースの料金体系
AWSでWebSocket通信の格ゲーを作ろうとしたときにつまずいた点

# AWSでWebSocket通信の格ゲーを作ろうとしたときにつまずいた点をまとめていきます(備忘録)

## API Gatewayの$connectルートに統合したLambda内でpost_to_connectionしようとするとGone Exceptionエラーが出る。

boto3ドキュメントを確認すると、
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/apigatewaymanagementapi/client/exceptions/GoneException.html

渡されたIDでの接続が見つからないときに投げられるエラーとのこと。
APIGWの$connectに関するドキュメントを確認すると、

”Until execution of the integration associated with the \\$connect route is completed, the upgrade request is pending and the actual connection will not be established. If the $connect request fails (e.g., due to AuthN/AuthZ failure or an integration failure), the connection will not be made.”
(出典)https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-route-keys-connect-disconnect.html

とのこと。つまり$connectルートに統合されたアクション（今回の場合はLambda）が完了するまでは接続が確立しないらしい。
接続が確立していないのにconnectionIDが渡されたものだから、有効になっているものと思い込んでpost_to_connectionしてしまっていた、というのが本件の顛末でした。マッチング相手にマッチメイキング完了通知を送りたいのであれば、
一回クライアント経由してsendさせる➤sendmessageルート➤Lambdaでマッチ相手にpostさせようと思う。
Angular15.2からクラスベースのCanActivateやCanDeactivateが非推奨になった…けれども

リリースノート
Class and InjectionToken guards and resolvers are deprecated.
https://github.com/angular/angular/blob/main/CHANGELOG.md#1520-2023-02-22

例えば、以下のように典型的な書き換えが必要
Angular AuthGuard: CanActivate and CanActivateChild are deprecated. How to replace them?
https://stackoverflow.com/questions/75564717/angular-authguard-canactivate-and-canactivatechild-are-deprecated-how-to-repla

これの何が気持ち悪いかというと、DIコンテナからサービスロケーターになったということだ。

AngularチームはDIコンテナ派からサービスロケーター派にくら替えしたという事だろうか。
実際のところ、AngularのテストコードはTestBedにべったり依存する前提になるためいまさらではある。
しかしコンストラクターDIをやめてinject()に依存しなければいけないのは何か気持ちが悪い。
バッチが失敗した時の操作

implements  Database.RaisesPlatformEvents　を使ったら、バッチ実行が失敗した時、操作ができる
BatchApexErrorEventというオブジェクトにトリガーを入れる


この例では、一括処理トランザクションで失敗したアカウントを判断するトリガを作成します。カスタム項目 Dirty__c は、アカウントが失敗した一括処理のいずれかであったことを示し、ExceptionType__c は発生した例外を示します。JobScope と ExceptionType は、BatchApexErrorEvent オブジェクトの項目です。

```

trigger MarkDirtyIfFail on BatchApexErrorEvent (after insert) {
    Set<Id> asyncApexJobIds = new Set<Id>();
    for(BatchApexErrorEvent evt:Trigger.new){
        asyncApexJobIds.add(evt.AsyncApexJobId);
    }
    
    Map<Id,AsyncApexJob> jobs = new Map<Id,AsyncApexJob>(
        [SELECT id, ApexClass.Name FROM AsyncApexJob WHERE Id IN :asyncApexJobIds]
    );
    
    List<Account> records = new List<Account>();
    for(BatchApexErrorEvent evt:Trigger.new){
        //only handle events for the job(s) we care about
        if(jobs.get(evt.AsyncApexJobId).ApexClass.Name == 'AccountUpdaterJob'){
            for (String item : evt.JobScope.split(',')) {
                Account a = new Account(
                    Id = (Id)item,
                    ExceptionType__c = evt.ExceptionType,
                    Dirty__c = true
                );
                records.add(a);
            }
        }
    }
    update records;
}
```
Dividend Yield Formula - Python Code

## Dividend Yield Formula
```math
\text{Dividend Yield} = \frac{\text{Annual Dividend Payment}}{\text{Stock Price}} \times 100%
```
where:
Annual Dividend Payment is the total amount of dividends paid out over the course of a year
Stock Price is the current market price of the stock

## Python Code
```python:dividend_yield.py
def dividend_yield(annual_dividend, stock_price):
    yield_pct = (annual_dividend / stock_price) * 100
    return yield_pct


annual_dividend = 4.00
stock_price = 110.00

yield_pct = dividend_yield(annual_dividend, stock_price)

print("Dividend yield: {:.2f}%".format(yield_pct))

# Output: Dividend yield: 3.64%
```
coil使用時に気をつけたいこと

# 初めに
今回は、自分が`Android`実装時に`Coil`ライブラリでちょっと引っかかった部分を紹介していきます
### 本文
自分が引っかかった内容としてはデフォルト画像の設定方法です
デフォルト画像はよく、プレースホルダーと言われますが、`Coil`で実装すると`placeholder`という値に入れてしまうと画像読み込み中の画像になってしまいます。
では、デフォルト画像を設定するにはどうすればいいのかですが、`Coil`の`error`という引数に対して渡してあげることで画像URLがnullだった時などにデフォルト画像を設定してくれます。
言われてみれば確かにそうなのですが、デフォルト画像という意味で普段から***プレースホルダー***という言葉を使ってると実装でもそのまま使いたくなってしまうんですよね...
### 最後に
今回は、自分が少し引っかかったことを備忘録程度に書き残してみました
どなたかのお役に立てれば幸いです
最も出現頻度の高い文字を探すプログラム初級編と上級編※滅茶苦茶コメント書いた

# Rustで最も出現頻度の高い文字を探す文字初級編

```Rust:main.rs
fn main() {
    // テキストデータのサンプル
    let text = "hello world";

    //// HashMapを使って文字の出現頻度をカウント
    // char_countは可変。mutを使っている為
    let mut char_count = HashMap::new();
    // .chars()でcに一個ずつ入れる
    for c in text.chars() {
        // entry()は指定したキーに対応する値を返す
        // or_insert()はキーが存在しない場合に引数で初期化されたエントリを返す
        // ここで言うエントリとはキーと値のペアを表す構造体のこと（つーかEntry
        // 既に存在する場合には、そのエントリの値を参照する。
        let count = char_count.entry(c).or_insert(0);
        // *を使うと、ポインタcountが指す値を参照
        // 外すと、
        // cannot use `+=` on type `&mut {integer}`
        // というエラーが出る
        *count += 1;
    }

    // 最も出現頻度の高い文字を探す
    let mut max_count = 0;
    let mut max_char = ' ';
    for (c, count) in &char_count {
        if *count > max_count {
            max_count = *count;
            max_char = *c;
        }
    }

    // 結果を表示
    println!("Targetの文字: {}", text);
    println!("一番現れた文字: '{}' (回数は{})", max_char, max_count);
}

```

# Rustで最も出現頻度の高い文字を探す文字上級編
```Rust:main.rs
fn main() {
    // 文字列を定義
    let s = "hello, world";
    // HashMapを作成
    let mut counts = HashMap::new();
    for c in s.chars() {
        // 出現回数をカウント
        *counts.entry(c).or_insert(0) += 1;
    }
    //// 出現回数が最大の文字を検索
    // counts.iter()はcountsのキーと値のペア(char, i32)のイテレータを返す
    // max_by_key()はクロージャーを引数に取り、そのクロージャーで比較した結果が最大となる要素を返す
    let (max_char, max_count) = counts.iter().max_by_key(|&(_, count)| count).unwrap();
    // 結果を表示
    println!(
        "出現頻度が最も高い文字は '{}' で、{} 回出現しました。",
        max_char, max_count
    );
}

```

たったこれだけを書くだけでも結構な勉強量になりますな
paiza.ioでnadesiko その19

# 概要
paiza.ioでnadesikoやってみた。
条件分岐、やってみた。

# サンプルコード

```

N=3の乱数
Nで条件分岐
　　０ならば、
    　　「0」と表示
    ここまで。
　　1ならば、
    　　「1」と表示
    ここまで。
　　2ならば、
    　　「2」と表示
    ここまで。
　　3ならば、
    　　「3」と表示
    ここまで。
　　違えば、
    　　「@」と表示
    ここまで。
ここまで。



```

# 実行結果

```
2
```

# 成果物

https://paiza.io/projects/NmtIlDh7OSSUv5PnMP3jfQ
以上。
サーバーメモリ使用量超シンプル調査方法


# サーバーのトータルメモリ使用量

```
free -h
```


# 個別プロセスを調べる

## 基本形

```
ps axu
```

- a : 端末を持つすべてのプロセスを表示
- x : 端末を持たないすべてのプロセスを表示
- u : 他のユーザーが実行しているプロセスも含めて表示する

Nginx などは端末を持たないし、他のユーザーが実行している場合がほとんどなので、ひとまず、このps コマンドが基本です。

## 複数プロセスが立ち上がるプログラムのメモリ合計を測る


サーバー内で複数プロセスが立ち上がっている場合に、合計使用メモリ量を測るためのコマンドです。

例えば php-fpm など

フォーマット

```
ps aux | grep [プロセス名] | awk '{sum += $6}END{print sum}'
```

メモリの単位はキロバイトででます。

サーバーの PHP-FPM プロセスのメモリ使用量合計を調べます。

```
ps aux | grep php-fpm | awk '{sum += $6}END{print sum}'
```

## 起動プロセス数を調べる

1プロセスあたりの使用メモリ数を出すために、起動しているプロセス数を調べます。

```
ps aux | grep [プロセス名] | wc -l
```

php-fpm

```
ps aux | grep php-fpm | wc -l
```

これで、「メモリ使用量合計」÷「起動プロセス数」で1プロセス数あたりのメモリ使用量がわかります。


ISO 127001 認証を取得しているセキュアかつ簡単な操作が可能で開発もしやすい [Concrete CMS](https://concrete5-japan.org) のサイト用のサーバー構築の際の設定の参考で必要でした。
SteamVR対応ヘッドセット一覧

# SteamVR対応ヘッドセット一覧

XRエンジニアをやっているせぎゅです！

「STYLYはSteamVRに対応しています！」

とお客様に説明しても、

「SteamVRってなに？」「どのデバイスが対応しているの？」

と言われることが増えてきた気がするので、対応ヘッドセットを一覧にまとめてみました！

個人的に調べたもので、ぬけもれがあるかもしれません！
もし、見つけたら、コメントや編集リクエストをいただけると嬉しいです！

また、動作確認を実施しているわけではありませんので、ご了承の上、お読みください。

# VIVEシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2016年 | HTC VIVE（初代）| 標準対応 |
| 2017年 | HTC VIVE Pro | 標準対応 |
| 2018年 | HTC VIVE Cosmos | 標準対応 |
| 2019年 | HTC VIVE Pro Eye | 標準対応 |
| 2020年 | HTC VIVE Cosmos Elite | 標準対応 |
| 2021年 | HTC VIVE Pro 2 | 標準対応 |
| 2021年 | HTC VIVE Focus 3 | VIVE Businessストリーミング（USB or 無線）|

VIVE Businessストリーミングは、VIVE Focus 3をPCに接続するための公式機能です！

# Oculus・Metaシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2016年 | Oculus Rift（cv1） | 標準対応 |
| 2019年 | Oculus Quest（初代） | Oculus Link（USB） |
| 2019年 | Oculus Rift S | 標準対応 |
| 2020年 | Oculus Quest 2 <br>Meta Quest 2 | Oculus Link（USB） |

Oculus Linkは、QuestをPCに接続するための公式機能です！

他にも、ALVRやVirtual DesktopといったソフトウェアでPCに接続する方法がありますが、これらは非公式のツールであり、必ずしも安定した品質で体験ができるわけではないのでご注意ください。

# Windows Mixed Realityシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2017年 | Acer Windows Mixed Reality Headset | 標準対応 |
| 2017年 | ASUS Windows Mixed Reality Headset | 標準対応 |
| 2017年 | Dell Visor | 標準対応 |
| 2017年 | Fujitsu Windows Mixed Reality Headset | 標準対応 |
| 2017年 | HP Windows Mixed Reality Headset | 標準対応 |
| 2017年 | Lenovo Explorer | 標準対応 |
| 2017年 | Samsung HMD Odyssey | 標準対応 |
| 2018年 | Samsung HMD Odyssey+ | 標準対応 |
| 2021年 | HP Reverb G2 | 標準対応 |

# Pimaxシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2018年 | Pimax 4K | 標準対応 |
| 2018年 | Pimax 2.5K<br>Pimax 4K Pro | 標準対応 |
| 2019年 | Pimax 5K Plus | 標準対応 |
| 2019年 | Pimax 5K XR | 標準対応 |
| 2019年 | Pimax 8K | 標準対応 |

# Valveシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2019年 | Valve Index | 標準対応 |

# Varjoシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2019年 | Varjo VR-1 | 標準対応 |
| 2019年 | Varjo VR-2 | 標準対応 |
| 2019年 | Varjo XR-1 | 標準対応 |
| 2021年 | Varjo VR-3 | 標準対応 |
| 2021年 | Varjo XR-3 | 標準対応 |
| 2022年 | Varjo Aero | 標準対応 |



# Picoシリーズ

| 発売年 | 機種名 | PC接続方法 |
|---|---|---|
| 2020年 | （Pico Neo2） | （ALVR・Virtual Desktop等による無線接続） |
| 2021年 | （Pico Neo3） | （ALVR・Virtual Desktop等による無線接続） |
| 2021年 | （Pico Neo3 Pro） | （ALVR・Virtual Desktop等による無線接続） |
| 2021年 | （Pico Neo3 Pro Eye） | （ALVR・Virtual Desktop等による無線接続） |
| 2022年 | Pico Neo3 Link | DisplayPortケーブル |
| 2022年 | Pico 4 | Streaming Assistant（USB or 無線） |

Streaming Assistantは、Pico 4をPCに接続するための公式機能です！

他にも、ALVRやVirtual DesktopといったソフトウェアでPCに接続する方法がありますが、これらは非公式のツールであり、必ずしも安定した品質で体験ができるわけではないのでご注意ください。

公式機能でPCに接続できない機種は、 `（）` で囲っています。

# さいごに

発売年も記載してみましたが、間違ってたら編集リクエストやコメントでのご指摘、よろしくお願いします！

本記事作成にあたり、以下のページを参考にさせていただきました。ありがとうございました！

- https://business.vive.com/jp/solutions/streaming/
- https://github.com/alvr-org/ALVR
- https://www.picoxr.com/jp/software/pico-link
- https://bibouroku.net/steamvr
- https://www.moguravr.com/pico-4-3/
- https://xr-comparison.yutokun.com/
タブレットでToolbarにPaddingが差し込まれる理由

`androidx.appcompat.widget.Toolbar` をTabletで使用したらいきなり左右にPaddingが設定されたのでびっくりしました。
調べてみるとToolbarで設定されているStyleがsw600dpを境にPaddingが設定されているからでした。


```values.xml
    <style name="Base.V7.Widget.AppCompat.Toolbar" parent="android:Widget">
        <item name="titleTextAppearance">@style/TextAppearance.Widget.AppCompat.Toolbar.Title</item>
        <item name="subtitleTextAppearance">@style/TextAppearance.Widget.AppCompat.Toolbar.Subtitle</item>
        <item name="android:minHeight">?attr/actionBarSize</item>
        <item name="titleMargin">4dp</item>
        <item name="maxButtonHeight">@dimen/abc_action_bar_default_height_material</item>
        <item name="buttonGravity">top</item>
        <item name="collapseIcon">?attr/homeAsUpIndicator</item>
        <item name="collapseContentDescription">@string/abc_toolbar_collapse_description</item>
        <item name="contentInsetStart">16dp</item>
        <item name="contentInsetStartWithNavigation">@dimen/abc_action_bar_content_inset_with_nav</item>
        <item name="android:paddingLeft">@dimen/abc_action_bar_default_padding_start_material</item>
        <item name="android:paddingRight">@dimen/abc_action_bar_default_padding_end_material</item>
    </style>
```

```xml:values/dimens.xml
    <!-- Default start padding of an action bar. -->
    <dimen name="abc_action_bar_default_padding_start_material">0dp</dimen>
    <!-- Default end padding of an action bar. -->
    <dimen name="abc_action_bar_default_padding_end_material">0dp</dimen>
```

```xml:values-sw600dp/dimens.xml
    <!-- Default start padding of an action bar. -->
    <dimen name="abc_action_bar_default_padding_start_material">8dp</dimen>
    <!-- Default end padding of an action bar. -->
    <dimen name="abc_action_bar_default_padding_end_material">8dp</dimen>
```

なので、どんな画面サイズでもPaddingを入れたくない場合は自前のStyleを設定したげると良いです。

```xml
    <style name="Toolbar" parent="Widget.AppCompat.Toolbar">
        <item name="android:paddingStart">0dp</item>
        <item name="android:paddingLeft">0dp</item>
        <item name="android:paddingEnd">0dp</item>
        <item name="android:paddingRight">0dp</item>
    </style>
```
【Flutter/Dart】DartにおけるNullチェック、isEmpty、isNotEmptyの振る舞い

## DartにおけるNullチェック、isEmpty、isNotEmptyの振る舞い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/cf7066b8-d915-db7e-d4a1-a253e9d3556a.png)


### テストコード

```Dart:main.dart
void main() {
  String? testDataNull = null;
  String? testDataEmptyString = "";
  String? testDataString = "testData";
  
  print("testDataNull == null: ${testDataNull == null}");
  print("testDataNull != null: ${testDataNull != null}");
  print("testDataNull.isEmpty: ${testDataNull?.isEmpty}");
  print("testDataNull.isNotEmpty: ${testDataNull?.isNotEmpty}");
  
  print("--------------------------------");
  
  print("testDataEmptyString == null: ${testDataEmptyString == null}");
  print("testDataEmptyString != null: ${testDataEmptyString != null}");
  print("testDataEmptyString.isEmpty: ${testDataEmptyString?.isEmpty}");
  print("testDataEmptyString.isNotEmpty: ${testDataEmptyString?.isNotEmpty}");
  
  print("--------------------------------");
  
  print("testDataString == null: ${testDataString == null}");
  print("testDataString != null: ${testDataString != null}");
  print("testDataString.isEmpty: ${testDataString?.isEmpty}");
  print("testDataString.isNotEmpty: ${testDataString?.isNotEmpty}");
}

```
Thunderbirdのメッセージフィルタを色々なデバイスで共有する方法

# はじめに
Thunderbirdのメッセージフィルタ機能は便利だが新たなPCにインストールしたときにメッセージフィルタを同期することはできない。毎度設定するのはとてもストレスなので簡単にできる方法を探した。
# 1. Everythingをインストール
ファイル検索アプリであるEverythingは使いやすいので，入っていない場合はインストール
https://www.voidtools.com/downloads/
# 2. 旧デバイスでmsgFilterRules.datを検索
メッセージフィルタ機能はmsgFilterRules.datにテキスト形式で保存されている。すでに設定済みのデバイスにおいてEverythingを使ってmsgFilterRules.datを検索しファイルをコピーする。
# 3. 新デバイスでmsgFilterRules.datを置き換える
Thunderbirdは閉じておくこと。
# 参考文献
https://aruo.net/arbk/blog/article/copy_msgfilterrules_of_thunderbird
【Power Apps】Excel Online のテーブルを編集するフォームをつくる

# 【Power Apps】Excel Online のテーブルを編集するフォームをつくる

OneDrive または、SharePoint ライブラリ上に配置した Excel ファイル内にあるテーブルに対して編集を行えるアプリを作成します。

## 準備

1. [テーブルとして書式設定](https://support.microsoft.com/office/create-and-format-tables-e81aa349-b006-4f8a-9806-5af9df0ac664) したテーブルを持ったブックを用意します。
1. [テーブル デザイン] タブでわかりやすいテーブル名を設定しておきます。(ここでは、M_Users)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/85657f3c-8ac6-ae8a-e0c6-0109939daabb.png)
1. OneDrive または、SharePoint ライブラリに格納します。

## アプリの作成

1. Power Apps のホーム画面の **この中から始める** で **Excel** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/4d56edea-da4e-98b1-63e4-406ff3c78173.png)

1. 接続で、**SharePoint** または、**OneDrive for Business** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/30747b3f-0554-d2e2-5d1a-cfff13cb0424.png)

1. 格納しておいた **Excel** ファイルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/cf98ebf5-bed1-4489-697b-afbb8fb3e78e.png)

1. ブック内のテーブルを選択し、[接続] ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/06aadcfa-26a4-f6bb-fb6b-7f68c40d54a6.png)

1. 自動的にアプリが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/29620714-d51e-4fa7-a549-1d18447c2c20.png)

## 確認

1. アプリ作成後に **Excel** ファイルの中身を確認すると、`__PowerAppsId__` というユニークな列が増えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/ecffad04-6ec1-bbf9-183d-83403f373749.png)

# 参考サイト

- [Excel: Excel を使用したアプリの作成と、それをデータ ソースとして使用するメリット](https://www.microsoft.com/videoplayer/embed/RE4XcyR)
rails http://localhost:3000/が開かない

<h1>http://localhost:3000/が開きません</h1>

現在http://localhost:3000/に入ろうとすると、
このサイトにアクセスできませんとでで閲覧することができません。

pc mac
○原因
今までは、普通に見れていたが、再起動後閲覧できなくなった。



○わかったこと
・ERR_CONNECTION_REFUSEDエラーはインターネット接続ではなく、ウェブサイトのサーバーが原因で発生する
・サーバーは起動したか ?
→これでした笑

○実践
「localhost 3000 接続できない mac」
で検索
・他のブラウザで開く、シークレットモードで開く
→ダメ
・ブラウザのキャッシュをクリア
→ダメ
<h3>・サーバーを起動していないことが原因
→ 結果解決</h3>

    $rails s
ターミナルにて上記を実行。
その後、サイトを確認したところ、無事閲覧することができました。👏
モジュール、パッケージ、ライブラリ by python

`モジュール`：ファイル名.py

`パッケージ`：モジュールが入っているフォルダ


- 使用方法
`モジュール名.オブジェクト名`：定義した変数や関数を呼び出しできる
`from モジュール名 import オブジェクト名`：モジュール内のオブジェクトの読み込み
`from パッケージ名 import モジュール名`：パッケージ内のモジュールの読み込み


`ライブラリ`：モジュール、パッケージのこと。
`標準ライブラリ`：pythonインストール時にインストールされるパッケージ、モジュール、関数（例、math,random。組み込み関数（importを書かずに使える関数））
`サードパーティライブラリ（外部ライブラリ）`：pandasなど。（サードパーティライブラリが多いことがpythonの強み）


`アトリビュート`：クラス内で定義された変数


モジュールとしてインポートする場合は、`if __name == __name__`をつけてインポートのファイル内で関数呼び出しをされないようにする。
動的配列(PHP)

paiza様の問題集に掲載されている、**「動的配列」** の課題を解きました


```PHP
    <?php
      // 自分の得意な言語で
      // Let's チャレンジ！！
      echo("最初の配列の要素数と操作数を入力してください");
      $data = trim(fgets(STDIN));
      $array1 = explode(' ',$data);
      $c = $array1[0];
      $num1 = $array1[1];
      echo("最初に定義する配列の要素をスペース区切りで入力してください");
      $data2 = trim(fgets(STDIN));
      $array2 = explode(' ',$data2);
      $count = 0;
      $limit_c = $num1;
      while ($count < $limit_c){
          echo("操作の内容「1:要素の削除」「2:要素をスペース区切りで表示」、それ以外は要素の追加");
          $str1 = trim(fgets(STDIN));
          // 1の時、要素を削除
          if ($str1 == "1"){
              array_pop($array2);
          // 2の時、配列の要素をスペース区切りで出力
          } else if ($str1 == "2"){
              $work = "";
              for($i=0;$i<count($array2);$i++){
                  if ($i == count($array2) - 1){
                      $work = $work . $array2[$i];
                  } else {
                      $work = $work . $array2[$i] . " ";
                  }
              }
              echo $work . "\n";
          // 要素の追加
          } else {
              $w_array1 = explode(' ',$str1);
              $f = $w_array1[0];
              $ele = $w_array1[1];
              array_push($array2,$ele);
          }
          $count += 1;
      }

  ?>
```
参考になると幸いです。
C#.NETでSystem.Randomがランダムじゃない時の発生条件と対策

# どういった条件の時に何が起きるのか

**かなり短い時間内** で **複数インスタンス** した場合、
```Next()``` の第一引数と第二引数が同じなら、 **別インスタンスでも同じ値** が出てきてしまう。

# サンプル

サンプルコードと実行結果を見ると分かりやすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a9d66f8e-6ad4-ff8c-bbdc-8c81f082997b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/676ccd05-232d-64d5-1d59-2842328f6f9a.png)


```c#:サンプルコード
using System;

namespace douiukotodattebayo
{
    internal class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("0以上100以下のランダム整数値を100回作る。（毎回インスタンス）");
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(new System.Random().Next(0, 101));
            }

            Console.WriteLine("0以上100以下のランダム整数値を100回作る。（インスタンスを使いまわし）");
            Random r_ = new System.Random();
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(r_.Next(0, 101));
            }

            //実行結果確認の為に入力待ちで止める。
            Console.ReadLine();

        }
    }
}
```

実行結果は下記。

偶然とは言えないレベルで同じ値が出てきてる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/98ecb121-54a5-1a2c-58e4-70e48f6e2342.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/728dcb66-e8b9-9f34-c717-6eee05fb31cc.png)

# 推測

前述の『かなり短い時間』は1ミリ秒以内かと思われます。
（理由は後述の『対策したサンプルコード』を参照）

インスタンスした時刻がランダム値の生成に影響を与えているのかも。

# 対策

インスタンスを使いまわしすれば回避できるので、そう作ればOK。

『インスタンスが一つだけ』ということを実現する意味ではシングルトンパターンで作るのがおススメ。

どうしても別インスタンスにしたい場合は下記。
（多分そんな需要無いだろうけど…）

```C#:対策したサンプルコード
using System;
using System.Threading;

namespace douiukotodattebayo
{
    internal class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("0以上100以下のランダム整数値を100回作る。（毎回インスタンスするがその前にSleep）");
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(1);//インスタンス前に1ミリ秒だけ待つ。
                Console.WriteLine(new System.Random().Next(0, 101));
            }

            //実行結果確認の為に入力待ちで止める。
            Console.ReadLine();

        }
    }
}
```

実行結果は下記。

1ミリ秒だけでもいいので待たせると結果がちゃんとばらつく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/154eb7c1-0bae-2df1-0c6a-7df805d74d2c.png)

# 参考サイトさん

https://techlive.tokyo/archives/10195

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2673
Microsoft .NET Framework Version 4.8.04084
「クイックスタート: CRM Analytics」プロジェクトのエラーを解決

# エラー発生
「クイックスタート: CRM Analytics」プロジェクトの「アプリケーションとレンズの作成」で下記のエラーが発生します。
https://trailhead.salesforce.com/content/learn/projects/quick-start-einstein-analytics/create-an-app-and-lens
```
There was an unhandled exception. Please reference ID: CLHXKBJF. Error: Restforce::ErrorCode::UnknownException. Message: UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you contact support: 2023346976-18560 (319400915) RESPONSE: [{"message":"An unexpected error occurred. Please include this ErrorId if you contact support: 2023346976-18560 (319400915)","errorCode":"UNKNOWN_EXCEPTION"}]
```
![スクリーンショット 2023-03-09 104454.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/121ece4b-30cd-1064-4060-3ec7df763c1e.png)
# 解決方法
**TrailheadのWebページの言語を「English」に変更してからステップを確認します。**
![スクリーンショット 2023-03-09 104741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/cb944592-b925-caa2-bff2-d9614e0c29c2.png)
ユーザのプロフィールページ②

<h1>プロフィールページを作成</h1>
プロフィールボタンを押すとプロフィールが、表示されるようにする。

ページについて作成するので、コンフィグのラウツ
config/routes.rb
resourcesを使ってurlを全開作成しました。

    resource :profile
今回は、resource

その後、routesをブラウザで確認すると
profileの中にindexがありません。
indexは、複数あるものを表示するもの

プロフィールは一つしか表示する必要がないため、showだけあれば十分

    resource :profile, only: [:show, :edit, :update]
この三つを指定
resourceの場合、この三つを指定することが多い

app/controllers/profiles_controller.rb
を作成
ここは、profilesで複数形で良い

    class ProfilesController < ApplicationController
      def show
      end

      def edit
      end
    end
ビフォーアクションを定義
このアクション（今回はshow）の前に実行するアクション

    before_action :authenticate_user!
authenticate_user!:ログインしてないとできないですよという意味

    def show
        @profile = current_user.profile
    end
これで、プロフィールを取得できる

app/models/user.rb
ここのhas_one :profileとある
ことによって、current_user.profileと、とってくることができる。

view
app/views/profiles
フォルダーを作成
ProfilesControllerなので、profilesにする

app/views/profiles/show.html.haml
app/views/profiles/edit.html.haml
二つのファイルを作成

app/views/profiles/edit.html.haml

    edit
とりあえずこれを記入
app/views/profiles/show.html.haml

    .container.profilePage
      .profilePage_user
        .profilePage_user_image
              = image_tag 'default-avatar.png'
        .profilePage_user_basicInfo
          .profilePage_user_name
            .profilePage_user_displayName
              = current_user.display_name
        .profilePage_user_actionButton
          = link_to 'Edit', edit_profile_path
      .profilePage_user_introduction
        あああああああああああああああああああああああああああああああああああああああああああああああああああああ
edit_profile_pathは、ブラウザのラウツにあるプロフィールのedit

リンクを貼る
app/views/layouts/application.html.haml

    = link_to  'プロフィール'profile_path
とする

これで、プロフィールを押すと画面が変わります。
また、editをおせば,editと書かれた画面になります。

装飾変更
app/assets/stylesheets/profile.scss
を作成し
app/assets/stylesheets/application.scss
    
    @import 'profile';
を追加

app/assets/stylesheets/profile.scss

    @import './variables';

    $image_size: 56px;

    .profilePage {
      margin-top: 24px;

      &_user {
        display: flex;

        &_image {
          display: flex;
          flex-direction: column;
          justify-content: center;

          img {
            width: $image_size;
            height: $image_size;
          }
        }

        &_basicInfo {
          margin-left: 16px;
        }

        &_actionButton {
          display: flex;
          flex-direction: column;
          justify-content: center;
          font-size: 12px;
          border-radius: 4px;
          border: 1px solid $primary-color;
          font-weight: bold;
          padding: 0px 8px;

          a {
            color: $primary-color;
          }
        }
    
        &_name {
          display: flex;
          margin-bottom: 8px;
        }
    
        &_displayName {
          font-size: 18px;
          font-weight: bold;
          margin-right: 8px;
        }
    
        &_introduction {
          font-size: 12px;
        }
      }
    }
を追加
Vantage Modules for Jupyterで学ぶSQLの基礎

# Vantage SQL プラグインの基本
この入門ガイドへようこそ。このガイドでは はじめてのSQLクエリを順を追って説明します。より多くのコマンドを含む充実したノートブックは オンラインの [Teradata Vantage Modules for Jupyter](https://teradata.github.io/jupyterextensions/#/) でご覧いただけます。

>Teradata SQLプラグインの基本的な使い方は「[Vantage Modules for Jupyterのナビゲーションと基本的な操作](https://qiita.com/tmsky/private/f34c657095d22c709712)」 を参照してください。

# SQL入門

## データベースに接続
「local」と言うデータベース接続定義で接続しています。
```python:Jupyter
%connect local
```

## テーブルを参照しないSELECT
実行できる最も簡単なSQLは、例えば2+2のような数式を計算することです。
```sql:SQL
SELECT 2+5
```

## はじめの本格的なSQLクエリを実行してみましょう
DBC.TablesVという名前のテーブルから10行を取得することになります。
```sql:SQL
SELECT top 10 * FROM DBC.TablesV;
```
**SELECT** : 抽出したい列を定義します。
　top 10 は先頭から10行を要求しています。
　* は全ての項目を要求しています。
**FROM** : ソースデータを指定します。
　DBCと言うデータベースにある TablesVテーブルをソースデータとして利用します。

Tablename と Databasename カラムを DBC.TablesVテーブルから5行取得する場合は以下のように記述します。
```sql:SQL
SELECT top 5 TableName, DatabaseName FROM DBC.TablesV;
```

## 結果の並び替え(ORDER BY)

```sql:SQL
SELECT top 5 TableName, DatabaseName FROM DBC.TablesV ORDER BY TableName;
```
**ORDER BY** : 並び替える順番をカラムで指定します。
　TableName の値の順番に結果がソートされます。

項目の降順で並び替えたい場合は項目の後ろに「DES」と記述します。
```sql:SQL
SELECT top 5 TableName, DatabaseName FROM DBC.TablesV ORDER BY TableName DESC;
```
**ASC** : 昇順(省略可能)
**DESC** : 降順

## フィルタリング
```sql:SQL
SELECT top 50 * FROM DBC.TablesV
WHERE TableKind = 'T'
ORDER BY DatabaseName DESC, TableName 
```
**WHERE** : フィルタリングの条件を指定します。
この例では TableKind が 'T' の行を抽出しています。

```sql:SQL
SELECT top 50 * FROM DBC.TablesV
WHERE (TableKind = 'T' AND CreatorName = 'DBC')
  OR (TableKind = 'T' AND CreatorName = 'SYSADM')
ORDER BY DatabaseName DESC, TableName 
```
条件は 確固で条件をまとめ ANDとORでつなげる事ができます。

## 集計
集約条件と集計関数を使いデータを集計できます。
```sql:SQL
SELECT top 20 DatabaseName, count(*) as ObjectCount FROM DBC.TablesV
GROUP BY DatabaseName  
ORDER BY DatabaseName
```
**GROUP BY** : グルーピング項目を指定します。
この例では DatabaseNameごとの件数を算出しています。
COUNT(*) : レコードの件数を算出します。

この例では、データベース名ごとの TableBytesの最小値、最大値、件数を求めています。
FROM句でSQLを入れ子に確固で囲んでいます。これをサブクエリと言います。
サブクエリの結果をテーブルとみなして、さらにクエリを実行しています。
```sql:SQL
SELECT
    TOP 20 databasename,
    MIN(TableBytes)  AS MinSize,
    MAX(TableBytes)  AS MaxSize,
    COUNT(*) AS #Objects_Using_Space
FROM (
    SELECT
        DatabaseName,
        TableName,
        Sum(CurrentPerm) as TableBytes   
        From DBC.TablesizeV
        Group By DatabaseName, Tablename
    ) as Subtotals 
GROUP BY DatabaseName order by DatabaseName;
```
**COUNT(X)** : 件数
**SUM(X)** : Xの値を合計 
**MIN(X)**   : Xの値の最小値
**MAX(X)**   : Xの値の最大値

## データベースから切断
「local」の接続を切断します。
```python:Jupyter
%disconnect local
```


# おわりに
:::note warn
警告
この本書は[Teradata Vantageドキュメンテーション](https://docs.teradata.com/)よりトピックに必要な情報を抜粋したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::
## Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)