OmniAICreator/Qiita-1.07M huggingface dataset:
Expect を用いたシンプルな対話処理自動化の例

# Expect を利用した対話処理自動化の例

エスケープシーケンスをどのように書かなければならないのか、いつも調べては忘れるので備忘用に記録を残す。
典型例として、ssh ログインを以下に挙げる。

```
$ ssh server-abc.example.com
user1@server-abc.example.com's password:
(この部分のパスワード入力の自動化)
```

Expect を用いて、特定のプロンプト(上記の例では `password:`) を標準出力上で待ち、標準入力に自動で文字列を入力するように動作させることができる。

## シェルスクリプトで特定の文字列をコマンドに与える例

user1 というユーザーでログインし、ログインの度に `file-1.bin` 、`file-2.bin` という形式で数字をインクリメントしたファイルを`touch`で生成し、ログアウトする例である。
パスワードは`password12345`とする。
全体の制御構造(下記の例ではループ)をシェルスクリプトで記述し、プロセスの生成・標準出力の待受け・文字列(パスワード)や生成するファイル名の入力のみをexpectで行うというスタイルを用いている。

```
#!/bin/sh

pw="password12345"

for ITR in $(seq 1 10); do
        FILENAME=file-$ITR.bin # ファイル名を使うのは tcl だが、インクリメントはシェルで行うのでこういった記述にしている 
        expect -c "
            set timeout 5
            spawn env LANG=C /usr/bin/ssh user1@server-abc.example.com
            expect \"password:\"
            send \"${pw}\n\"
            expect \"$\"
            send \"touch ${FILENAME}\n\"
            expect \"$\"
            send \"exit\"
            exit 0
        "
done
```

## 対話処理をはさみたいケース

対話処理(上記で言うと、インクリメントした自動的なファイル名での `touch` ではなく、手動でファイル名を `touch` したい等)を挟む場合は、ログインした後に当たるスクリプト中で

```
expect \"$\" # ログイン完了し、プロンプトが帰ってきたタイミング
interact
# ここから対話入力が可能
```

のように記述する。
するとその部分は `spawn` で生成したプロセスの入出力が標準入力に移るので、手動でのコマンド入力が可能になる。
Codility lesson2 CyclicRotation

Codilityの問題を解くことにハマってきた。
今までは2重ループで全部強引突破してきたが、いかに無駄をなくせるかという視点でコードを書かなければならないので、
そういった処理速度を意識したコードを書くことができるようになる。皆さんもぜひやってみてください。

というわけでlesson2のCyclicRotationをやっていきます。

lesson2のCyclicRotationはリストの要素のシフトに関する問題。リストの要素を全て右にK個分シフトして、できたリストを返すという問題です。

[アルゴリズム]
1.全ての要素をずらす。
2.ずらして、リストからはみ出した分は余りとして捉え、余った分だけリストの先頭から入れていく。

具体的にコードを見ていこう。

    def solution(A,K):
        len_A = len(A)
        rotated_list = [0]*(len_A)  #回答用のリスト

        for i in range(len_A):
            rotated_list[(i+K)%len_A] = A[i]    #回答用のリストをはみ出した分は余りとする.

        return rotated_list

さて結果は。。。。？

![スクリーンショット 2022-06-12 0.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/a0b85d30-d409-bd77-6b99-a648286b202e.png)

100%です。よかった〜。
今回の問題のポイントははみ出した文を余りとして考えるというところだと思います。

つまりインデックス番号iをKだけ移動させてi+Kがリストの長さlen_Aを超えてしまったら、超えた分（つまりi+Kをlen_Aで割った余り）だけ先頭から入れていけばいい。
Viteを使っているRailsアプリに一部のBootstrap 5を導入方法

Bootstrapはかなり有名で便利ですね。早くアプリケーションが使えるようにするためよく使う場合が多いと思います。
しかし、いつも全てのBootstrapの機能が必要ではない場合もあります。その時に一部の機能だけ導入すればいいです。

今回はViteを使っているRails 7アプリにBootstrap 5を導入してみました。

## Bootstrap 5 と popperjs/coreを導入

```zsh
yarn add bootstrap @popperjs/core
```


## BootstrapのCSSを導入

```scss:app/assets/stylesheets/bootstrap.scss
// Configuration
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/utilities";

// Layout & components
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/images";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";
@import "bootstrap/scss/tables";
@import "bootstrap/scss/forms";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/transitions";
@import "bootstrap/scss/dropdown";
@import "bootstrap/scss/button-group";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/card";
@import "bootstrap/scss/accordion";
@import "bootstrap/scss/breadcrumb";
@import "bootstrap/scss/pagination";
@import "bootstrap/scss/badge";
@import "bootstrap/scss/alert";
@import "bootstrap/scss/progress";
@import "bootstrap/scss/list-group";
@import "bootstrap/scss/close";
@import "bootstrap/scss/toasts";
@import "bootstrap/scss/modal";
@import "bootstrap/scss/tooltip";
@import "bootstrap/scss/popover";
@import "bootstrap/scss/carousel";
@import "bootstrap/scss/spinners";
@import "bootstrap/scss/offcanvas";

// Helpers
@import "bootstrap/scss/helpers";

// Utilities
@import "bootstrap/scss/utilities/api";
```

何かのモジュールだけを使いたくても、`function`、`variables`、`variables-dark`、`mixins`、`maps`が必要みたいです。
つまりあの五つはBootstrap5を使う時に必要な最小限です。

## BootstrapのJSを導入
```js:app/assets/javascript/application.js
import '../../assets/stylesheets/bootstrap.scss'

import 'bootstrap/js/dist/alert';
import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/carousel';
import 'bootstrap/js/dist/collapse';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/modal';
import 'bootstrap/js/dist/popover';
import 'bootstrap/js/dist/scrollspy';
import 'bootstrap/js/dist/tab';
import 'bootstrap/js/dist/toast';
import 'bootstrap/js/dist/tooltip';
```

ここは先ほど作成した`bootstrap.scss`ファイルをインポートして、それから必要な機能のJSファイルをインポートします。

### [plugin:vite:css] Preprocessor dependency "sass" not found. Did you install it? というエラーが発生した場合

`sass`を追加すれば解決できます。

```zsh
yarn add sass -D
```
SpringSecurity5.7にアップデートしたらUserDetailsServiceを用いた認可ができなくなった

## 前提

SpringSecurity5.7から書き方が大きく変わります！

詳細は以下の公式ブログにて解説がありますが、
`WebSecurityConfigurerAdapter`が`@deprecated`になります。

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

以下の記事もお世話になりました。

https://qiita.com/suke_masa/items/908805dd45df08ba28d8

## 困ったこと

もともと`UserDetailsService`を用いてDBに登録されているユーザーを認可していたのがSpringSecurity5.7以降でできなくなりました。

### before

```SecurityConfig.java
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = passwordEncoder();
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }
}
```

`WebSecurityConfigurerAdapter`は`@deprecated`のため使用するのは好ましくないですし、
そもそも実行できません。(以下のエラーが出ます。)

```
The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  securityConfig (field private org.springframework.security.core.userdetails.UserDetailsService com.example.config.SecurityConfig.userDetailsService)
↑     ↓
|  inMemoryUserDetailsManager defined in class path resource [org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.class]
└─────┘
```

## 解決策

`JdbcUserDetailsManager`を使うように修正(というか作り直し？)しました。

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter#jdbc-authentication

`m_user`はユーザー情報が入ったテーブルです。
デフォルトでは、テーブル名が`USERS`と`AUTHORITIES`と固定になっています。
別の名前のテーブルから認可情報を取得したい場合は以下のように記述すると記載の情報を用いて認可を行ってくれます。

```SecurityConfig.java
@EnableWebSecurity
@Configuration
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsManager users(DataSource dataSource) {
        String userQuery =
                "select user_id,password,true from m_user where user_id = ?";
        String authoritiesQuery =
                "select user_id,role from m_user where user_id = ?";
        JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
        users.setUsersByUsernameQuery(userQuery);
        users.setAuthoritiesByUsernameQuery(authoritiesQuery);
        return users;
    }
}
```

いつか誰かの役に立てば幸いです！！！
Codility lesson1  BinaryGap

企業の技術テストでCodilityの問題が出されることあり、最近Codilityについて勉強しているので、せっかくだし自分の回答をわかりやすく説明してQuitaに載せておこうと思う。

lesson1のBinaryGapの問題は受け取った値を二進数に変換した際に登場する0の個数に関する問題。
1で区切った際に最大の0の個数はいくつかを聞く問題だ。
例えば1000100の場合は4を返すようにする。


[アルゴリズム]
1.受け取った数値を二進数に変換する。
2.変換された値を桁ごとに区切り、それぞれの値をリストに格納する。
3.リストから要素数分、一つ一つ値を取り出していき、0になった瞬間からカウントを開始、0の個数を保持しておく。
4.０の出た回数をそれぞれを比較し最も多い回数を返せばいい。

具体的にコードを見ていこう。
(なお私のコードは処理速度を速くするためになるべく二重ループはしないように心掛けている。)


    def solution(N):
        bin_N = int(format(N,'b'))
        bin_N_list = []

        while bin_N != 0:   #リスト格納部分
            bin_N_list.insert(0,bin_N%10)
            bin_N = bin_N//10
    
        len_list = len(bin_N_list)
        i = 0   #配列走査のための変数
        zero_count = 0   #０を数えるための変数
        max_zero_count = 0   #zero_countの最大値　　while文を回しながら更新していく

        while i < len_list:
            if bin_N_list[i] == 0:
                zero_count +=1
            else:
                if max_zero_count <= zero_count:
                    max_zero_count = zero_count
                    zero_count = 0
            i +=1
        return max_zero_count

さて結果は。。。。？

![スクリーンショット 2022-06-12 0.26.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/bfaa8c74-3010-b859-53dc-101596a86dfb.png)

あれ、少しミスがあったようです。
どこがミスっているかコメントください。
同階層にあるscssファイルを最も簡潔に@useする方法

## はじめに

ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています @misuken です。

今回は開発でよく使っているSassのちょっとしたtipsを紹介します。

## コンポーネントのSass定義

みなさんはReactなどでコンポーネントを作る際のSassの管理方法をどのようにしているでしょうか？
全てではないにしろ、再利用するような定義やmixinなどをコンポーネント単位で定義ファイルみたいなものにまとめていたりしませんか？

あまり他の人の管理術みたいなものを見たことがないのでわからないのですが、筆者はそのような定義ファイル系はindex.scssという名前にしています。

なぜこうするかというと、他のディレクトリから参照するときに簡潔に書けて都合が良いからです。

## 例

例えば以下のパスにButtonコンポーネントのSassの定義があったとします。

```scss:path/to/button/index.scss
@mixin xxx() {
  // 省略
}
```

これを他のコンポーネントから利用するとき、ディレクトリ名まで書くだけで読める上に、名前空間も良い感じに当たります。

```scss:path/to/sample-form.scss
// path/to/button/index.scss を読んで名前空間が "button" になる
@use "path/to/button";

.submit-button {
  @include button.xxx();
}
```

さらに、Buttonコンポーネントの同階層から読むときは、`.`と書くだけで`index.scss`を読むことが出来ます。そして、同階層の場合は名前空間が無いほうが都合が良いので`as *`を追加してそのスコープに展開します。

```scss:path/to/button/button.scss
// index.scss を読んで名前空間無しで展開する
@use "." as *;

.button {
  @include xxx(); // そのまま書ける
}
```

## よくやる構成

コンポーネントのscssファイルはこのようにしています。

```
button
  index.scss  // 定義類を書くファイル
  button.scss // セレクターを書くファイル
```

基本的に定義系はindex.scssから提供すると使いやすいので、社内で使用するSassのユーティリティなどは`@nicolive/styles`のパッケージ直下にindex.scssが来るようにすることで、利用する側は以下のように簡潔に書けるようになっています。

```scss
@use "@nicolive/styles";

.sample {
  font-size: styles.$font-size1;
  color: styles.$color-mono1;
}
```

## 終わり

今までのところこの書き方で問題が生じたことはないのですが、もしこのやり方に何か問題がある場合は教えていただけると幸いです。

## 余談

完全に余談。Sassの補完やコードジャンプがIntelliJはわりといい感じなのですが、VSCodeで開発しているメンバーはプラグインを入れてもイマイチらしいので、他の方がどうやって作業効率を上げているのか気になっています。
【C#】outキーワードはif文専用ではなかった

# はじめに

Visual Studioでコーディングしているとき、エラー一覧から「メッセージ」を有効にしておくと、
「privateのフィールドの変数名が大文字から始まっている」といったコーディング規約なども確認してくれるため結構便利。

その機能を見ながらコーディングしていたら気がついたことがあったため共有する。

## outキーワード

例えば次のようなコードを入力していたら、Visual Studioから下記アドレスの提案が出てくる。

https://docs.microsoft.com/ja-jp/dotnet/fundamentals/code-analysis/style-rules/ide0018

```cs
int parced = 0;
if (int.TryParse("123", out parced))
{
    Console.WriteLine(parced);
}
```

簡単に言うと、outキーワードを使って無駄な宣言を省略できる。

```cs
if (int.TryParse("123", out int parced))
{
    Console.WriteLine(parced);
}
```

マイクロソフトのリファレンスでもこの使い方しか書かれていなかったが、もう一つ便利な使い方があった。

## outキーワード+三項演算子+LINQ

outキーワードで変数を定義する方法は、別にif文の中に限ったことではなく、
ほぼ同じことを行っている三項演算子でももちろん使用することができる。

三項演算子は乱用すると可読性が落ちやすく、短文であることが意味を持つような場面で使うことが望まれる。
そんな条件をぴったり満たすような場面といえば？LINQだね。

という訳で、いまいち信用ならない文字列群に対する変換用途でLINQを使ってみたらこうなった。
若干極端だが、中に愚直にコードを書いた例をコメントアウトに書いておいたが、このレベルでは可視性が段違いだと思われる。

```cs
List<string> inputted = new List<string> { "123", "abc", "456"};
var output = inputted.Select(s => int.TryParse(s, out int parsed) ? parsed : 0).ToList();
// var output = inputted.Select(s => {if (int.TryParse(s, out int parsed)){ return parsed;} else {return 0;}}).ToList();
// {123, 0, 456}
```

他になにか良い例があったら教えて下さい。
Flyway導入 SpringBoot起動時にSQL実行

## DBマイグレーションツールのFlyway導入したのでメモ
手動でスクリプトを開発と本番で反映はつらかったので導入した

### 環境
| 技術 | Version |
|:-:|:-:|
| Kotlin| 1.3  |
| Sprinb Boot | 2.2  |
|Gradle| 7.4.2  |
|MySQL| 5.6  |

### Spring Boot起動時に実行する方法を記載します。
※他にもgradle pluginを利用するなどコマンドで実行する方法もあります

#### 手順1

```kotlin:build.gradle
dependencies {
	implementation("org.flywaydb:flyway-core:6.5.6")
}
```

#### 手順2

```yaml:application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xxx
    username: xxx
    password: xxx
    driver-class-name: com.mysql.cj.jdbc.Driver
  flyway:
    enabled: true
    baseline-on-migrate: true # baselineまで適用済みと見なす
    baseline-version: 1 # 既にDB上にテーブルが存在する時にflywayを入れたので既にあるものをVersion1とした
```

#### 手順3

スクリプト(SQLファイル)を追加
`src/main/resources/db/migration` 配下に
Vx__xxxxx.sql で配置すればOK。
例： V1__create_test.sql
(アンダーバーは2ついるのでそこは注意)


#### 補足：上記でFlywayは動作するがそのままだとJUnitでエラーになる

JUnitで以下のようなエラーが発生した。
`Caused by: org.flywaydb.core.internal.exception.FlywaySqlException`

##### 対応
テスト用のapplication.ymlを作成し以下をセットしてJUnit時はflywayをskipするようにした。

```yaml:application.yml
spring:
  flyway:
    enabled: false
```

以上
AWS CLIでアクセスキーを正しく設定してもなぜか権限エラーになる

ググっても事例見あたらず、トラシューでめっちゃ格闘してしまったのでメモ。


# TL;DR

AWS CLIにアクセスキーを設定してもなぜか権限エラーになってしまうときは、awsコマンド実行端末に意図せぬ環境変数がセットされてしまっていることが原因かも？


# 起こったこと

AWS CLIの初期設定では `aws configure` コマンドでアクセスキー等を設定できる。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html

しかし、正しい権限を付与したIAMユーザーのアクセスキーをちゃんと設定したはずなのに、何度やってもawsコマンド操作が権限エラーになってしまった。

```bash
$ aws s3 ls
An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.
```


# 試したこと

AWS CLI設定の確認コマンドを実行。

```bash
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************4G6N              env    
secret_key     ****************T/DQ              env    
    region           ap-northeast-1              env    ['AWS_REGION', 'AWS_DEFAULT_REGION']
```

どうもアクセスキーとシークレットキーが `aws configure` で設定したはずのものと異なっている。

続いて、AWS CLIの設定ファイルを確認。

```bash
$ cat ~/.aws/config
[default]
region = ap-northeast-1
output = json

$ cat ~/.aws/credentials 
[default]
aws_access_key_id = ****************DDTS
aws_secret_access_key = ****************2/Lf
```

こちらは `aws configure` で設定したとおりの内容。
これがうまく読み込まれていない模様。


# わかったこと

どうも自分のMacにはAWS CLI関連の環境変数がローカルに直接設定されていた模様。そのために `.aws` ディレクトリー内のコンフィグが読み込まれず、環境変数が優先して参照されてしまっていたことが判明。

※過去にAWS CLIを使う際にネット記事を見ながらガチャガチャ環境変数をいじってしまっていたものと思われる。。

以下を実施することで本件解決！

```bash
$ unset AWS_PROFILE
$ unset AWS_DEFAULT_PROFILE
$ unset AWS_ACCESS_KEY_ID
$ unset AWS_SECRET_ACCESS_KEY
$ unset AWS_DEFAULT_REGION
```

解消後の設定確認コマンド結果は以下のようになった。

```bash
aws configure list       
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************DDTS shared-credentials-file    
secret_key     ****************2/Lf shared-credentials-file    
    region           ap-northeast-1      config-file    ~/.aws/config
```


# おまけ

後日、新たにターミナルを立ち上げ直すと事象再発。
どうもzshのプロファイルに直接、AWS CLI用の環境変数を追記してしまっていた模様。

```zsh
$ open ~/.zshrc
```

上記コマンドでプロファイルを開き、当該処理を削除してターミナル再起動すれば一件落着。
mcrconを利用してStreamDeckからMinecraftサーバーで特定のコマンドを実行する

# はじめに
最近(2022/6/8)、Minecraftに1.19アップデートが来たため新たにサーバーをたててフレンドと遊ぶことになった。
その時「/time set day」や「/weather clear」といったコマンドを打つことが多くあり、いちいちプレイを止めて入力するのは面倒くさいと思っていたところ、目の前にあるStreamDeckが目につき「ボタン1つでコマンド送信出来たら便利では?」と思い調べたところ、Minecraftにはもともとrconという通信機能が備わっており設定すればPythonからでも扱えることが分かったため作ってみました。

# 環境
### Minecraft server 側
+ CentOS(さくらVPS)
+ Minecraft server 1.19
### クライアント側
+ Windows 10
+ Python 3.8.2

### 機材
+ StreamDeck 15ボタン (https://www.elgato.com/ja/stream-deck)

# 概要
①サーバー側の設定
②プログラムの作成
③StreamDeckに適応

# ①サーバー側の設定
### server.propertiesの変更
サーバーを作成すると生成されるserver.propertiesファイルを変更しrconを利用できるようにする。
変更の仕方等は既にサーバーを立てている御方々には不要だと思うので変更する部分だけを紹介します。
+ まずrcon通信に利用するポート番号の指定
```server.properties
rcon.port=25575
```
初期設定は25575になっている、特に希望がなければそのままでOK
**ここで設定したポート番号で通信が行われるためファイアウォール等設定している場合は各々ポート開放などを行ってください。**
+ rcon通信時に必要なパスワードの設定
```server.properties
rcon.password= "任意のパスワード"
```
初期設定は"minecraft"もしくは空欄になっている(?)、ここで設定するパスワードが今後必要になるため任意のパスワードを設定してください。
+ rconを有効にする
```server.properties
enable-rcon= True
```
初期設定はFalseのためTrueに変更する。

以上でサーバー側の設定は終了。

# ②プログラムの作成
今回はPythonでrconを行うライブラリ**mcrcon**を使用するためインストールをします。
```
pip install mcrcon
```
続いてコードを書いていきます。
```weather_clear.py
from mcrcon import MCRcon
server_address = "サーバーのIPアドレス"
server_pass = "任意のパスワード"  #server.propertiesで設定したパスワード
server_port= 25575    #server.propertiesで設定したポート番号
with MCRcon(server_address, server_pass, server_port) as mcr:
    mcr.command("/weather clear") #任意のコマンド
```
今回は晴れにするコマンド「/weather clear」の例を書きましたが、自分が使用したい任意のコマンドを記述してください。
このプログラムを実行するとコマンドが実行されるはずです。

**StreamDeckから利用するため1つのコマンドに1つのexeファイルが必要になるため自分が必要なコマンド分上記のコマンド部分を変更した.pyファイルを用意してください**
今回私は天候を晴れにするweather_clear.pyと時間を昼にするtime_set_day.pyの二つを用意しました。

### ③StreamDeckに適応
StreamDeckに最初から搭載されている任意のアプリを開くプラグイン（【システム】→【開く】)は.pyファイルには対応していないため、pyinstallerを用いてpyファイルをexeファイルに変換します。

```
pip install pyinstaller
```
ターミナル上で先程作成したpyファイルがあるディレクトリに移動し
```
pyinstaller weather_clear.py --onefire
```
と入力すると先ほどのディレクトリにdistディレクトリが生成され、その中にexeファイルが生成されています。
このファイルをStreamDeckのプラグインで開くように設定します。
![unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933794/aad5ff8a-b165-e7da-5857-67a1185f00d3.png)

右のプラグインから【システム】→【開く】を選び画面下部のApp/ファイル部分で先ほど生成されたexeファイルを選択します。

以上で作業は終了です、今作成したボタンを押せばサーバーにコマンドが送信され実行されすはずですのでご確認ください。

### 参考にさせていただいた記事
+ [mcrconを利用してpythonからminecraftサーバにコマンドを出力する](https://qiita.com/mutchan1k/items/0084af949a9f1dd44e6b)
+ [Python - pyinstallerの使い方](https://qiita.com/SecuritySoftStorn/items/bfb67b966370b1b5f15f)

# 最後に
この環境を整えるまでは鯖主である自分がプレイ中orコンソールをいじれる場面でしかコマンドを入力できず、入力できる場面でもプレイ中断→入力といった手間があった。
しかし、今回StreamDeckのボタンワンぽちでコマンドを送れるようになったためパソコンの前にさえいれば実行できるようになった上、物理的なボタンを押すだけなので作業もほぼ中断せずサーバーの操作ができるようになったためだいぶQOLが向上した。
Unityエディタからadbコマンドの使える状態でコマンドプロンプトを開く

# 概要

UnityでMetaQuest2向けのVRアプリを作っているとき、`adb shell pm list package`や`adb uninstall com.DefaultCompany.TestApp`などのadbコマンドを使うことがあります。
しかし、adbコマンドをサクッと使うには、Android SDKのインストールは当然として、環境変数にパスを通す作業も必要です。（~~環境構築めんどくさい~~）

Android Build SupportのモジュールにはAndroid SDKが含まれているので、adb.exeがどこかにあるはずです。
これをうまく使っていい感じにできないでしょうか？

# 結論
以下のようなエディタ拡張を追加すると、`Window>Run Terminal (at android sdk path)`か、Ctrl+Tショートカットキーで、adbコマンドが使える状態でコマンドプロンプトを開きます。

``` C#
using System.Diagnostics;
using System.IO;
using UnityEditor;

public static class TerminalExtensions
{
    [MenuItem("Window/Run Terminal (at android sdk path) %t")]
    private static void RunTerminalAtAdbAvailableDir()
    {
        var adbDir = Path.Combine(UnityEditor.Android.AndroidExternalToolsSettings.sdkRootPath, "platform-tools");

        Process p = new Process();
        p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
        p.StartInfo.Arguments = $"/k cd /d {adbDir}";
        p.Start();
    }
}
```
https://gist.github.com/udonba/ec78138e03bbb237d6ddd5bd280fc79a

# 解説

## adb.exeのパスを知る
Android SDKの場所の設定がどうなっているかは、Unityエディタの`Edit>Preferences>External Tools>Android>SDK`を見れば分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232140/86985a4e-6796-94c9-e156-cc92acfafeae.png)

これをスクリプトから参照するには、`UnityEditor.Android.AndroidExternalToolsSettings.sdkRootPath`を使います。実際はSDKのフォルダ内のplatform-toolsフォルダ内にadb.exeがあるので、このパス文字列に`/platform-tools`を足せばadb.exeのある場所になります。
``` C#
var adbDir = Path.Combine(UnityEditor.Android.AndroidExternalToolsSettings.sdkRootPath, "platform-tools");
```


## カレントディレクトリをadb.exeのある場所にする

パスの通っていない状態でコマンドプロンプトに「adb」と入力しても、`'adb' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。` と返ってくるだけです。
「cd」コマンドを使って、adb.exeのある場所にカレントディレクトリを移動しましょう。
「cd /d <移動するパス>」とすることで、ドライブが異なる場合でもカレントディレクトリを移動できます。

``` C#
Process p = new Process();
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
p.StartInfo.Arguments = $"/k cd /d {adbDir}";
p.Start();
```


# おまけ よく使うコマンド
|やりたいこと|adbコマンド|備考|
|:--|:--|:--|
|APKのインストール|`adb install -r <apkファイルパス>`|-r で上書き|
|APKのアンインストール|`adb uninstall com.hoge.fuga` |com.hoge.fugaはパッケージ名|
|インストール済みアプリ一覧の確認|`adb shell pm list package`|アンインストールしたいがパッケージ名が分からないときに便利|
AWS Lambda Function URLsの使い方

# AWS Lambda Function URLs

## やれること
- Lambda関数に紐づくURLを作成する
- 簡単に関数の前にHTTPSエンドポイントを設定する

## 何が嬉しい？
### Lambda Function URLsが無い時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/b2c1e1d9-716d-5f13-59ba-502152ada274.png)
今まではこんな感じで、API GatewayやAppSync、ALBをLambdaの前に置いてました。

### Lambda Function URLsがある時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/bd9b2daf-7a91-0ee8-8422-e80fea096c41.png)
これだけでOK！

## やり方
1. Lambda関数の作成で詳細設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/ce7a63ac-e985-a094-21e7-4f30f430a3e3.png)
2. 詳細設定内の「関数URLを有効化」をチェックする
※今回は簡易的に検証するために認証タイプをNONEにします。関数に独自の認証を加えない限り、パブリックアクセスされるので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/283795b4-2e78-e07c-d5dc-9f0136d30a4a.png)

以上！これでFunction URLsが作成されています。
Lambdaのコンソールから作成した関数を開くと以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/0aa03bb6-f7bf-209b-abef-3af05f10f51b.png)

関数URLに記載されているアドレスをコピーしてブラウザに張り付けると関数が実行され、レスポンスが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/2224efbf-234c-bb8b-7a8b-135f93e4584e.png)

## 感想
- これだけで簡単にLambdaFunctionにURL付けられるのはベンリ
- 次回はIAM認証を付けてやってみたい
- LATESTバージョンにマッピングされるから、開発中、本番運用どうするかはエイリアス指定すればよさそう
今日のDockerエラー：no such file or directory": unknown.

今日のDockerエラー

```
$ docker run -v /var/tmp/ieee:/var/tmp/ieee  -it ubuntu /bin/bashcd /var/tmp/ieee
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/bashcd\": stat /bin/bashcd: no such file or directory": unknown.
ERRO[0002] error waiting for container: context canceled 
```

コピペミスではない。コマンドhistoryから、うごいていたはずのコマンドを実行した。

コマンドをコピペしたら起動できた。


```macOS:bash
$ ls *.pdf
(B) Embedded Ethernet And Internet Complete Designing And Programming Small Devices For Networking - Axelson (Lakeview Research,2003)(497S).pdf
20_05_TS_sheet_2020_sample.pdf
QC.xlsx.pdf
autosar.pdf
uds.pdf
$ cp (B) Embedded Ethernet And Internet Complete Designing And Programming Small Devices For Networking - Axelson (Lakeview Research,2003)(497S).pdf /var/tmp/ieee/ether.pdf
-bash: syntax error near unexpected token `B'
```

ファイル名がうまく処理でいない。

他のPDFファイルをbackupフォルダに移動して、

```
$ mv *.pdf backup/ether.pdf
```

お疲れ様でした。
🔰【自分用】レスポンシブ対応

# はじめに
今回はオリアプデも使用したレスポンシブ対応について簡単にまとめていく。

# レスポンシブ対応とは？
画面幅によって見た目が変わるようにWEBサイトやアプリケーションのデザインを設計すること。
例：PCならPCのサイズ、スマホならスマホのサイズで画面幅を調整

# レスポンシブの実装
実装を始めていく。

## viewportを設定
headタグ内に以下のファイルを記述
```
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> #記述
 <title>アプリ名</title>
 <link rel="stylesheet" href="./css/reset.css" />
 <link rel="stylesheet" href="./css/style.css" />
</head>
```
contentプロパティに`width="device-width"`を指定することで、ブラウザの大きさをPCやスマートフォンなどの機器の大きさに合わせることができる。
`initial-scale`は、画面の拡大率を指している。

## 画面サイズごとにcssを適応
やり方は簡単
例
```
/* PC表示時 */
p {
 font-size: 30px;
}

/* タブレット表示時 */
@media (max-width: 1000px) {
  p {
    font-size: 25px;
  }
}

/* スマホ表示時 */
@media (max-width: 500px) {
  p {
    font-size: 20px;
  }
}
```
それぞれの端末で文字の大きさが変わるように記述
### メディアクエリ
`「@media (max-width/min-width: 〇〇〇px) { }」`という記述をメディアクエリという。
これは表示された画面幅に応じて適用するスタイルを切り替える機能。

### ブレークポイント
メディアクエリによって規定されるスタイル適用の分岐点。
上記記述の場合だと、1000pxや500pxがこれに当たる。これを起点に表示が変わる
「max-width: 500px」の部分は「画面幅が最大500pxのとき」という意味。すなわち「画面幅が500px以下のとき」という意味になる。
また、上記でのブレークポイント数値は**大雑把**なため、検証ツールでサイズを確認すること!

# 終わりに
今日は超がつくほど簡単でしたが、私は今からエラーと戦ってきます。良い息抜きになりました。。
PowerAutomate: Update an adaptive card in a chat or channel で出来ること(Messageも更新可能)

# 背景
Lists コピー用フローでも作ってみようかなと思った際に、
- Teams 選択
- Lists 選択

という二段階の選択が必要。
で、この問い合わせ部分を、Update 使って出来ないか？と思って試した記録

[Update an adaptive card in a chat or channel](https://docs.microsoft.com/en-us/connectors/teams/#update-an-adaptive-card-in-a-chat-or-channel)

# 結論
2022/6/11 時点では、以下制限があるので、入力 UI として使った Card の更新は出来無さそう
- 問いかけの Adaptive Card は更新出来ない
- Automate Bot チャットへの投稿は更新出来ない
- Reply の更新も出来ない
- 未読や、最新スレッド化はされない。更新されたことに気付きにくいのが使いにくい・・
    - 更新日付・時刻を Card 内に表示し、固定化しておくなど工夫が必要
- Bot 自体が投稿したもののみ更新可能　→　HTML 形式の Message も更新出来る！！

出来ること
- Channel/ Group Chat に投稿した Adaptive Card の更新 (Message ID は必要） 
- Message も更新可能（Adaptive Card でなくても、Botが投稿したスレッドは更新可能）

# 詳細
## 問いかけの更新不可
まぁ、元々問い合わせタイプだと Action.Submit があるから更新出来ないんじゃないかなとか思ってはいたんだが、
以下のような感じで、更新自体は出来る方法があった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1f9bd602-114c-7baf-3119-9edd52644fde.png)

ただ、結局以下のような感じで、戻し先が見つからないって感じ。当然だけど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/95f72882-8d9c-6cef-15a9-e41e5014e52e.png)

ということで、 Update an adaptive card in a char or channle wait for のリリース待ちかな

## チャットでの更新
選択肢がまずない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4d643709-4867-a55f-4a9d-cbda10adf345.png)

Update 元の Action の input.paramters.location を利用して参照渡ししてみると Input Parameters が消えてしまって返信先などが指定できないので使えない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a23f9ed2-b613-d0f7-96c6-dfee154dd756.png)

```json:Post in の再利用
actions('Post_adaptive_card_in_a_chat_or_channel_2').inputs.parameters.location
```

だからといって、直接入力するとエラーになるだけ

ってことで、対応待ちだけ

> {
  "error": {
    "code": 400,
    "message": "Received failure status from backend. Status 400, status reason - 'Bad Request', response body - '{\"error\":{\"code\":\"BadRequest\",\"message\":\"UnknownError\",\"innerError\":{\"date\":\"2022-06-11T13:31:38\",\"request-id\":\"5c25c483-b9c3-416c-8c60-a40cb70fdcc2\",\"client-request-id\":\"5c25c483-b9c3-416c-8c60-a40cb70fdcc2\"}}}'",
    "source": "japan-001.azure-apim.net",
    "path": "choose[6]\\when[1]",
    "policyId": "",
    "clientRequestId": "723c4099-e841-4712-b8d9-01e7141d7737"
  }
}

## Reply更新
Reply も出来ない。
チャット更新と同様に、対応待ちってとこかな
> {
  "error": {
    "code": 404,
    "message": "Received failure status from backend. Status 404, status reason - 'Not Found', response body - '{\"error\":{\"code\":\"NotFound\",\"message\":\"UnknownError\",\"innerError\":{\"date\":\"2022-06-11T13:31:45\",\"request-id\":\"cd94a974-ae2d-43e7-b2a3-6c326d42b246\",\"client-request-id\":\"cd94a974-ae2d-43e7-b2a3-6c326d42b246\"}}}'",
    "source": "japan-001.azure-apim.net",
    "path": "choose[6]\\when[1]",
    "policyId": "",
    "clientRequestId": "b5e6e05f-37df-41c3-9967-fca7fc1718f3"
  }
}

# あとがき
意外に使えないなぁという印象

デジタルサイネージ的に、更新で最新データを常に Watch 出来るようになると便利だなぁとは思う
チャネルに固定スレッド表示とか、Teams UI で自由に Card を配置出来るようになったら、だろうけど
プログラミング初心者のデザイナーがFlutterを勉強する日記 1日目

# Flutterの勉強をはじめる
本業UI/UXデザイナーでプログラミング初心者の自分がFlutterを触ってみる。
html, cssはそれなりだがJava, Pythonは軽く触ったことがある程度で挫折しておりほぼ初心者。
プログラミングに挑戦するにあたってFlutterを選んだ理由は
* 自分がデザインしてる画面をどう作るかの話なのでバックエンドより取っつきやすそう
* iOS, Androidどちらにも有効な言語ということで汎用性高そう

なぜプログラミングを今になって勉強したいと思ったかについては気が向いたら別で書く。

# 買ってきた本
[これ](https://www.amazon.co.jp/dp/4777521311/ref=cm_sw_r_tw_dp_CXBJ4E58H0NQHY8BM4Y8)
本屋でパラパラめくってみた感じわかりやすそうな感じがしたので。

# 今日やったこと
### クロスプラットフォーム開発についてうっすら学ぶ
React NativeとFlutterの違いってなんだろうと思った
React Nativeの方が歴史が長い分コミュニティも大きいっぽいが、言語的にはどちらもJava Scriptベースで大きな差分はなさそう？と思ったので、引き続きFlutterを触ってみることにした

### Xcodeを落とす
落とそうとしたらOS対応してなくてさっそくつまづいた。
（最新のXcodeはmacOS 12.0以降が必要で、自分のはBig Sur11.6.1だった）
OSアプデそれなりに時間かかるしめんどいので、とりあえずgitでやってみることにした
（[公式ドキュメントにgitでもいける的なこと書いてあったので](https://docs.flutter.dev/get-started/install/macos)）

### Homebrewを落とす
一億光年ぶりにターミナルを開いてHomebrewを落とした
https://git-scm.com/download/mac
Homebrewとはパッケージ管理ツールで、複数のパッケージのバージョン管理とかをして整合性を維持してくれるらしい
（パッケージという概念にはじめて触れた、、）
参考：https://zenn.dev/sawao/articles/e7e90d43f2c7f9

### Flutter SDKを落とす
公式からFlutterをダウンロードする。
PATHの設定の仕方がわからなくて、vimで書き込んだ。
vimのコマンド、昔触ったことあったからなんとなく思い出したけど、ちゃんと覚えようと思った
あとでよむ：https://qiita.com/hide/items/5bfe5b322872c61a6896

### CocoaPodsのインストール
sudoコマンドで落とすだけ。できた

### iOSシミュレータのセットアップ
ここで「あれ、Xcode必要じゃんね？」となって詰んだ

### 仕方ないのでOSアップデートに挑戦
満を辞してBig SurからMontereyのアップデートに挑戦したが、なぜかうまく動作完了せず詰んだ。
今日はここまで

# 今日のまとめ
* ワクワクしながらはじめたけど開発環境のセットアップでさっそく詰んだ
* が、プログラミング入門にあたっての通過儀礼っぽいので、なんとか切り抜けようと思う
* 読む人になんの参考にもならない記事になってしまったが細々やっていけたらと思います〜
今更ながらトロイの木馬 とは

## 勉強前イメージ

正直良くわかってない・・・・
ウイルスの一種・・？

## 調査

### トロイの木馬 とは

一見無害なデータやプログラムに見せかけ、実は悪意のある活動をするプログラムです。
[マルウェア](https://qiita.com/miyuki_samitani/items/3fd9a681bbaf70aba3e1) の一種です。
また、トロイの木馬がバックドアを仕掛けることでデータを流出させたりデバイスを制御したりなど攻撃を行います。

### トロイの木馬の由来

トロイの木馬とは
古代ギリシアローマ時代の物語で中に兵士が入った木馬をトロイア街に招き入れたことが由来とされています。

### トロイの木馬の仲間たち

トロイの木馬は、マルウェアの一種です。
トロイの木馬以外にも `ウイルス` や `ワーム` がマルウェアの種類にあります。

簡単な分類は以下です。

- トロイの木馬
	- 自己増殖しない
	- なりすまして単体で存在する
- ウイルス
	- 自己増殖する
	- 単体では存在できない
- ワーム
	- 自己増殖する
	- 単体で存在する

### トロイの木馬の種類

- ダウンローダー型 : 他の有害なマルウェアもダウンロードする
- クリッカー型 : ブラウザの設定を変更したり、勝手にブラウザを起動させたりする
- バックドア型 : バックドアを作って遠隔操作を行う
- パスワード窃盗型 : パスワードを漏洩させる
- プロキシ型 : DNSの設定を変更してプロキシサーバーを構築、IPアドレスを使用して攻撃を行う
- ドロッパー型 : 設定したタイミングで不正な情報をプログラムに落とす
- 迷彩型ゼウス : JPEGに偽装したマルウェアで、発見が難しい
- キーロガー型 : キーボードの捜査を記録
- ボット型 : ボットのような動きをする

## 勉強後イメージ

毎回毎回忘れちゃう・・・よく聞くのに
由来は知らなかった

## 参考

- [トロイの木馬とは？ウイルスとの違いや被害例を解説](https://www.sei-info.co.jp/mcore/basics/trojan.html)
- [トロイの木馬](https://www.eset.com/jp/topics-home/trojan-horse/)
【初心者メモ】Reactのカスタムフック用のスニペットを書いた【VSCode】

# そもそもスニペットって何？
分かりやすい記事がありました。（丸投げ）

https://qiita.com/282Haniwa/items/82828c6a566e3e7e047d

# スニペット本体
```json
{
  "customHooksSnippet": {
    "prefix": "cshk",
    "body": [
      "export const ${TM_FILENAME_BASE} = () => {",
      "\tconst [${1:first}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:second})",
      "\tuseEffect(() => {",
      "\t\tset${1/(.*)/${1:/capitalize}/}(${2:second})",
      "",
      "\t\treturn () => {",
      "\t\tset${1/(.*)/${1:/capitalize}/}(${2:second})",
      "\t}",
      "\t}, [])",
      "",
      "\treturn {${1:first}};",
      "};",
      "$0"
    ],
    "scope": "typescript,typescriptreact,javascript,javascriptreact",
    "description": "Create react basic custom hooks"
  }
}
```
# 使い方
- js,ts,jsx,tsxファイルで"cshk"と入力すると候補に出てくるようになる。（別のキーで呼び出したい場合は、上記jsonの"prefix"を修正する。）
- フック名はファイル名をそのまま流用する。1ファイルで複数のフックを書くなら修正が必要。
- 最初にフォーカスが当たるのがstate。入力後tabキーで初期値に移動する。移動時にsetの部分が勝手に大文字始まりになるようになっている。

# 所感
## Reactの書き手という視点
基本的にはMarketplaceで仕入れればいい（例えば[これ](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets)とか）が、カスタムフックが見当たらなかったので自作。まあそもそも"カスタム"だから定型文は自分で書いて然るべき…なのか？

そもそもhooksの理解が足りてないのが悲しい。

## 自作スニペットについて
むしろ自分でスニペットを一から書いてみるというほうが目的だったまである。

初めて書いたので記法は見よう見まね。幸いにも先に挙げた[拡張機能のソースが公開されてる](https://github.com/dsznajder/vscode-react-javascript-snippets/blob/185bb91a0b692c54136663464e8225872c434637/src/snippets/generated.json)ので、これと[公式ドキュメント](https://code.visualstudio.com/docs/editor/userdefinedsnippets)を参考にしながら四苦八苦して書いた。

ちゃんと思った通りに動いた部分とそうでもない部分がある。あまり伸ばしてもしょうがないスキルのような気もするが、必要になったら積極的に書いて慣れていきたい。

# 参考
- https://qiita.com/282Haniwa/items/82828c6a566e3e7e047d
- [vscode-react-javascript-snippets](https://github.com/dsznajder/vscode-react-javascript-snippets/blob/185bb91a0b692c54136663464e8225872c434637/src/snippets/generated.json)
- [VSCode公式](https://code.visualstudio.com/docs/editor/userdefinedsnippets)
Azureの機能廃止やサポート終了情報を手早く確認する方法

Azure を利用していると避けては通れない、機能の廃止やサポート終了
見落としがちなこの通知も便利なフィルタリング機能を見つけたのでご紹介

## 調べ方
公式サイト：[Azure の更新情報](https://azure.microsoft.com/ja-jp/updates) から、更新情報の種類で```Retairements```を選択するだけ！
提供終了年で絞り込みできるのも地味にうれしいですね:ok_hand:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355390/a46c56c1-dc71-435b-3a9c-efde965f6d80.png)
【Flutter】A problem was found with the configuration of task ':app:processDebugResources' のエラー対策

# 目的
AndroidStudio で Flutter×Android の実行を行った時に発生したエラー ```A problem was found with the configuration of task ':app:processDebugResources'``` の対策


# 実行環境
OS : MacOS
PC : MacBookPro M1Pro
コマンド : ターミナル
開発環境 : AndroidStudio

## ① : ターミナルで "flutter doctor" を実行し、Androidのバージョンを確認

筆者の場合は、バージョン 32

ターミナル > ```flutter doctor``` 

<img width = 90% src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764557/502955ec-bf5b-114b-78ca-a72281bd58d4.png" >



## ② : プロジェクト/Android/app/bulid.gradle を開く

👇 bulid.gradle はこんな感じのファイル
<img width = 90% src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764557/b7244fda-9c58-cf57-14a0-8fc2b4a6a611.png" >


## ③ : android{ ~~~ } 内の、「compileSdkVersion」「targetSdkVersion」 を ①で確認したバージョンに指定

**compileSdkVersion**
<img width = 90% src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764557/40e7a471-061f-36ec-63df-2ce397fec57b.png" >

**targetSdkVersion**
<img width = 90% src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764557/e45f263c-8114-6161-d0bb-721c6c213e5e.png" >


# 参考サイト
https://stackoverflow.com/questions/59405894/a-problem-was-found-with-the-configuration-of-task-appprocessdebugresources
テスト69

```vb
'Excelファイルを開かずにExcelファイルの指定のシートのスペースを削除する方法
Sub ExcelADO2()
 
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strSQL As String
Dim str As String

str = "C:\Users\User\Desktop\VBA練習\test.xlsx"

cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;" & _
         "Data Source=" & str & ";" & _
         "Extended Properties=""Excel 12.0;HDR=YES""")

strSQL = "SELECT * " & _
         "From [テスト1$A1:J20000];"


With rs
    .Source = strSQL
    .ActiveConnection = cn
    .LockType = adOpenDynamic
    .Open
End With

rs.MoveFirst
Do Until rs.EOF

    rs.Fields(0).Value = Replace(StrConv(rs.Fields(0).Value, 8), " ", "")
    rs.Fields(1).Value = Replace(StrConv(rs.Fields(1).Value, 8), " ", "")
    rs.Fields(2).Value = Replace(StrConv(rs.Fields(2).Value, 8), " ", "")
    rs.Fields(3).Value = Replace(StrConv(rs.Fields(3).Value, 8), " ", "")
    rs.Fields(4).Value = Replace(StrConv(rs.Fields(4).Value, 8), " ", "")
    rs.Fields(5).Value = Replace(StrConv(rs.Fields(5).Value, 8), " ", "")
    rs.Fields(6).Value = Replace(StrConv(rs.Fields(6).Value, 8), " ", "")
    rs.Fields(7).Value = Replace(StrConv(rs.Fields(7).Value, 8), " ", "")
    rs.Fields(8).Value = Replace(StrConv(rs.Fields(8).Value, 8), " ", "")
    rs.Fields(9).Value = Replace(StrConv(rs.Fields(9).Value, 8), " ", "")

    rs.MoveNext

Loop
rs.MovePrevious
rs.Update

'2万行10列の処理で約2秒...φ('ω' )ｶｷｶｷ
Stop

rs.Close
Set rs = Nothing

cn.Close
Set cn = Nothing
    
End Sub
フロントエンドノート

**[ノートリンク](https://github.com/wly130/notes/tree/master/%E7%AC%94%E8%AE%B0/%E5%89%8D%E7%AB%AF)**
### 私が自分で整理したメモは、ほとんどのフロントエンド関連の問題を解決できますが、言語は中国語です
DangerでAndroidのビルドワーニングをレポートするプラグインを作ったよ


Androidプロジェクトで
- Dangerを活用したPullRequestの静的解析
- Ktlintと連携したコードフォーマットのチェック
- AndroidLintのワーニングレポート

を実践している方は多いのではないでしょうか？

**しかし、ビルドワーニングは放置されていませんか？**

そこで、ビルドワーニング・エラーをDangerでインラインコメントするプラグインを作りました。
この記事では、このプラグインの使い方をご紹介します。

### danger-chikuwa
今回作成したDanger-pluginはこちらです。
https://github.com/watanavex/chikuwa

gemで公開しています。
https://rubygems.org/gems/danger-chikuwa

## 使い方 (GitHub Actions)

サンプルAndroidプロジェクト
https://github.com/watanavex/android-check-for-chikuwa

### GitHub Actionsのワークフロー

全体のサンプルはこちらです
https://github.com/watanavex/android-check-for-chikuwa/blob/main/.github/workflows/pr-check.yaml

重要な部分を抜粋しますと
```yaml
      - name: Build
        run: ./gradlew assembleDebug 2>&1 | tee build.log
        continue-on-error: true
      - name: Run Danger
        run: danger --remove-previous-comments
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

1. Androidビルドを走らせ `./gradlew assembleDebug`
1. ビルドエラーの出力も対象とするため `2>&1` を付与し
1. コンソールに出力しつつファイルにリダイレクト `tee build.log`
1. Dangerを実行

### Dangerfile

全体のサンプルはこちらです
https://github.com/watanavex/android-check-for-chikuwa/blob/main/Dangerfile

重要な部分を抜粋しますと
```ruby
chikuwa.inline_mode = true
chikuwa.report "build.log"
```

1. (option) インラインコメントにしたい場合は `inline_mode = true`
1. `report` にビルド時の出力したファイルを与える

---

以上です。


## 動作した様子

![スクリーンショット 2022-06-11 21.13.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14646/d376553f-39e7-4246-330e-7964a3df7c97.png)

## なぜ `chikuwa`？

深い理由はありません。
我が家の癒し担当の名前を頂きました。

↓ こちらが ちくわです
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14646/4f0e44cb-0416-4577-4639-c4f472045270.png)

## 最後に

Dangerプラグイン`chikuwa`が、みなさんのプロジェクトでお役に立てたら嬉しいです。
コントリビュートもお待ちしています。
【モダン】Kotlin + SpringBoot + JUnit5をVSCodeでDebugをする

最近３日前くらいにKotlinをはじめて完全に理解しました。
よろしくお願いします。

※Kotlin文法はこちらの記事をご参照ください。
[３０分で覚えるKotlin文法](https://qiita.com/k5n/items/cc0377b75d8537ef8a85 "３０分で覚えるKotlin文法")

Scalaはほとんど絶滅した感じで、世はやっぱりJavaかと思う昨今ですが
そういやKotlinが居たなーと思いサーバーサイドの`Kotlin + SpringBoot`の
現状を調べてみました。

2022年現在(6月) VSCode + Kotlin
・コード補完があんまり効かない。
・デバッグがよくわからない。
・私は*IntelliJ Ultimate*ユーザです。

という致命的な状態であることに絶望しました。

俺たちが本当に欲しかったのは言語の説明ではなく
いい感じにモダンな言語の開発フィーリングであって
VSCodeでキラキラした感じに開発できる環境なのです。

Goでいいじゃん。
そうなんですけど、WEB界最強のFWであるSpringBootでサーバを創りたいんです。
`VSCode + Java`でいいじゃん。
最近のJava(VSCode)はかつての隆盛を思わせる無敵の環境になりつつありますが
なにせJava。書きっぷりが冗長すぎる。

そこでJavaとScalaの良さを合わせていい感じにモダナイズされたKotlinですよ。(10年前)

![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/f9eb091f-a15b-a068-3368-73ccd9af7092.png)

では、さっそくアンサーを記します。
`Spring initializer > gradle > kotlin`でプロジェクトを作成してください。
`Kotlin + SpringBoot`まではネットに情報があると思います。

```build.gradle (旧)
dependencies {
	...
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
    testImplementation("org.junit.jupiter:junit-jupiter")
    testImplementation("org.junit.jupiter:junit-jupiter-api")
    testImplementation("io.mockk:mockk:+")
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(module = "junit")
        exclude(module="junit-vintage-engine")
        exclude(module = "mockito-core")
    }
}
```
```build.gradle (新)
dependencies {
	...
    // ↓そりゃそうですよね。
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}
```
```SampleController.kt
	@RestController
	class SampleController {
	    @GetMapping("/")
	    fun getHello() :String {
	        return "Hello Kotlin"
	    }
	}
```

```SampleControllerTests.kt
@SpringBootTest (
  webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
class SampleControllerTests {

  @Autowired 
  lateinit var restTemplate: TestRestTemplate

  @Test
  fun index() {
    val entity = restTemplate.getForEntity<String>("/", String::class.java)
    Assertions.assertEquals(HttpStatus.OK, entity.statusCode)
  }

}
```

```launch.json
"configurations": [
    {
        "type": "kotlin",
        "request": "attach",
        "name": "Kotlin Attach",
        "hostName": "localhost",
        "projectRoot": "${workspaceFolder}",
        "port": 5005,
        "timeout": 30000
    }
]
```

ここまで準備できたらターミナルからgradleでデバッグできます。
基本リモートデバッグです。

```
$ ./gradlew bootRun --debug-jvm
```

5005リッスンが出てくるので、launch.jsonで設定したやつをアタッチしてください。
```
Listening for transport dt_socket at address: 5005
```

次にJUnitのデバッグですが、こちらもリモートデバッグします。
`VSCode + Java`はここが強力で、もうJavaでいいじゃんと思ってしまいますが。

```
$ ./gradlew test --tests "*Tests" --info --debug-jvm
```

はい、コントローラのデバッグは出来るのですが、JUnit側のソースはデバッグできません。
そこは気合でなんとかしましょう。
KotlinTestとかだとできるんですかね。。

ひとまずこれでKotlinでWebAPIを作成できる環境が整ったと思います。
Firebase Local EmulatorでFunctionsのHTTPS呼び出し可能関数を利用するとCORSエラー

# 概要

Firebase Cloud FunctionsのHTTPS呼び出し可能関数をregion指定つけた状態で，FunctionsもエミュレートするようにしたFirebase Local Emulatorからアクセスすると「CORS」エラーが発生してしまいました．本記事はその対処法を記載しています．

### 解決策まとめ

ブラウザの開発者ツール等からエミュレート実行中のinit.jsの内容をコピーし，Functionsの設定部を下記のように変更し，scriptから利用します．

```javascript
firebase.app().functions('asia-northeast1').useEmulator(firebaseEmulators.functions.host, firebaseEmulators.functions.port);
```

### 環境

- firebase-tools 9.23.3
- クライアント側Firebaseソースバージョン 8.8.0 (v8 Web)

## 発生状況

Firebase Cloud Functionsではクライアント側から認証情報を乗せたまま叩ける「HTTPS呼び出し可能関数」があります．  
[アプリから関数を呼び出す  |  Firebase Documentation](https://firebase.google.com/docs/functions/callable?hl=ja)

次のような，EmulatorでFunctionsをテストできるソースがあるとします．

```javascript:functions/index.js
const functions = require('firebase-functions');
exports.testCall = functions.region('asia-northeast1').https.onCall(async (data, context) => {
  return "ok"
})
```

```html:public/test.html
<html>
<head>
  <script src="/__/firebase/8.8.0/firebase-app.js"></script>
  <script src="/__/firebase/8.8.0/firebase-auth.js"></script>
</script>
  <script src="/__/firebase/init.js?useEmulator=true"></script>
</head>
(中略)
<script>
const firebaseConfig = { ... }
firebase.initializeApp(firebaseConfig)
const func = firebase.app().functions('asia-northeast1').httpsCallable("testCall")
func()
  .then((r)=>{ console.log(r) })
</script>
</html>
```

この状態で `firebase emulators:start` してlocalのtest.htmlにアクセスするとブラウザのコンソールの方に次のようなエラーが出て実行されません．

```
Access to fetch at 'https://asia-northeast1-xxx.cloudfunctions.net/testCall' from origin 'https://xxx.firebaseapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

`init.js?useEmulator=true` のscriptタグが無い状態で firebase deploy すると問題なく動くのがやっかいなところです．

## 原因

実はログにヒントがあり，regionを指定しない場合，つまり

```javascript
firebase.functions().httpsCallable("testCall")
```

では

```
https://localhost:5001/xxxxx/us-central1/testCall
```

にアクセスするはずですが，ログではデプロイ後のURIにアクセスしています．

同じ現象→ [Firebase Functionsを呼び出す際にregion指定するとEmulatorではなく本番に接続してしまう](https://sunday-morning.app/posts/2021-01-15-firebase-functions-region-emulator)

Emulatorを使うための init.js をブラウザで確認すると，

```javascript
if (firebaseEmulators.functions && typeof firebase.functions === 'function') {
   firebase.functions().useEmulator(firebaseEmulators.functions.host, firebaseEmulators.functions.port);
}
```

というコードでFunctionsがエミュレートで動くように設定されていますが， us-central1リージョンの`firebase.functions()`だけがエミュレーション動作設定になってしまっており， asia-northeast1リージョンの `firebase.app().functions('asia-northeast1')`はエミュレート設定になっていないというのが根本原因となります．

## 対処法

init.js によるエミュレート設定を使う以上は回避できなさそうですので，別途エミュレート設定を記述する必要があります．
init.jsの内容をコピーし，Functionsの設定部を下記のように変更します．

```javascript
firebase.app().functions('asia-northeast1').useEmulator(firebaseEmulators.functions.host, firebaseEmulators.functions.port);
```

これにより正常にHTTPS呼び出し可能関数を使うことができるようになりました．
Slim4でAPIを作ってみる

※執筆中

1)スケルトン作成
php composer.phar create-project slim/slim-skeleton:dev-master [my-app-name]

2)認証用のJWTミドルウェアインストール
 composer require tuupola/slim-jwt-auth


""
Apacheを使用している場合は、.htaccessファイルに以下を追加します。そうしないと、PHPはAuthorization：Bearerヘッダーにアクセスできません。
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
""
【Laravel】RegisterController内のredirectToを変更する方法

環境：Larvel6～8あたりには適応する内容だと思います（他は未確認）

## ユーザー登録後のリダイレクト先は、デフォルトでは「/home」

RegisterController内に定義されている$redirectToを見ると
RouteServiceProviderのHOMEが代入されていることがわかります。

```php:RegisterController
protected $redirectTo = RouteServiceProvider::HOME;
```

RouteServiceProviderのHOMEを見てみると、以下のように/homeとなっています。

```php:RouteServiceProvider
public const HOME = '/home';
```
## 静的な値であれば、当然そのまま書き換えられる

「/home」を「/」に変更したい、といった場合であれば、当然ですが下記のようにそのまま書き換えることが可能です。必要があればRouteServiceProviderの定数HOMEを書き換えても良いと思います。

```php:RegisterController
protected $redirectTo = '/';
```

## 動的な値にしたらエラーが出た

たとえば、会員登録後は会員ごとのマイページに飛ばしたい、といった場合は下記のように$redirectToに動的な値を設定する必要があります。しかしこれだと「Constant expression contains invalid operations」とのエラーが出てしまいました。

```php:RegisterController
protected $redirectTo = route('users.show', ['user' => Auth::id()]);
//エラーになる「Constant expression contains invalid operations」
```
なぜエラーが出たのかと言うと、メンバ変数（プロパティ）の初期値は定数しか入れられないというPHPのルールがあるからです。（そのあたり良くわかっていなかったので下記記事様を参考にさせて頂きました。）

https://qiita.com/H40831/items/15ebfbf7d9c05001b6df

「RouteServiceProvider::HOME」がエラーにならないのは、HOMEが変数ではなく定数だったからなんですね。※ちなみに「定数しか入れられない」というのは、あくまでメンバ変数の「初期値」に限った話です。

## redirectToメソッドで解決

結論から言うと、下記のようにRegisterController内にredirectToメソッドを定義することでリダイレクト先を動的に設定できます。（変数$redirectToはそのまま残しておいても問題ありません）
```php:RegisterController
protected $redirectTo = RouteServiceProvider::HOME;

protected function redirectTo() {
   return route('users.show', ['user' => Auth::id()]);
}
```
なぜredirectToメソッドで変更できるのか、そもそもなぜ変数$redirectToでリダイレクト先が設定できていたのかは、RegisterControllerがuseしているRegistersUsersトレイト、そしてそのRegistersUsersがuseしているRedirectsUsersトレイトを確認することでわかります。

以下はRegistersUsersトレイト内registerメソッドです。末尾でredirectPathメソッドを呼び出しているのがわかります。
```php:RegistersUsers
public function register(Request $request)
    {
        $this->validator($request->all())->validate();
        event(new Registered($user = $this->create($request->all())));
        $this->guard()->login($user);
        if ($response = $this->registered($request, $user)) {
            return $response;
        }
        return $request->wantsJson()
                    ? new JsonResponse([], 201)
                    : redirect($this->redirectPath());
    }
```
以下はRedirectsUsersトレイト内のredirectPathメソッドです。if文により、redirectToメソッドのほうが変数$redirectToよりも優先されていることがわかります。
```php:RedirectsUsers
public function redirectPath()
   {
       if (method_exists($this, 'redirectTo')) {
           return $this->redirectTo();
       }
       return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
   }
```
勉強メモ53_JavaScriptの「URLエンコード、デコード」及び「4つのグローバル関数（encodeURIComponent、encodeURI、decodeURIComponent、decodeURI）のエンコード、デコードの処理の違い」

#  URLエンコード、デコードとは
・URLエンコードとは、URLに使用できない文字が含まれる場合に、使用できる文字に変換する処理のことです。
・URLデコードは、逆でURLエンコードされた文字を元に戻す処理のことです。
・URLエンコードおよびデコードは、データをクエリ文字列としてWebサーバーに送信する場合などで使われます。
・JavaScriptでは、URLエンコードおよびデコードを行うための関数をグローバル関数として用意しています。

# 以下、URLエンコードおよびデコードを行うグローバル関数（encodeURIComponent、encodeURI、decodeURIComponent、decodeURI）のエンコード、デコードの処理の違いになります。
|関数名  |説明  |
|---|---|
|encodeURIComponent(引数)  |引数の文字列をURLエンコードする。<br>ただし、英数字と「-」、「_」、「.」、「!」、「˜」、「*」、「'」、「(」、「)」は対象外  |
|encodeURI(引数)  | 引数の文字列をURLエンコードする。<br>encodeURIComponent(引数)で対象外の文字に加え、<br> 「/」、「#」、「&」、「@」、「:」、「;」、「,」、「+」、「$」、「?」、「=」も対象外|
|decodeURIComponent(引数)  |URLエンコードされた文字列をデコードする。<br>対象は、encodeURIComponent(引数)でURLエンコードされる文字列  |
|decodeURI(引数)  |URLエンコードされた文字列をデコードする。<br>対象は、encodeURI(引数)でURLエンコードされる文字列  |

# 使い方例

HTML↓↓（Scriptタグに上記グローバル関数を使った処理を記載）

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
   
  </style>
</head>
<body>
  
  <script>
    var url1 = "from-data=2022/06/11&to-date=2022/06/11";
    var url2 = encodeURIComponent(url1);
    console.log(url2);//「from-data%3D2018%2F07%2F01%26to-date%3D2018%2F07%2F31」が表示される
  </script>
</body>
</html>
```

上記のHTMLをアクセスしたときのデベロッパーツールのコンソール結果↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730323/0d7fb8e5-bb3d-cc1e-33d2-cfbe3bd475b2.png)
<b>※上記の例では、「/」や「＆」がエンコードされる関数を選択する必要があるため、encodeURIComponentメソッドを利用しました。って感じで利用する。</b>
VSCodeオススメ拡張機能・設定

# 初めに
環境設定......なにそれおいしいの？
そんな自分が出会ったやらなければいけない事orz、やった方が良い事について、備忘録として記載していきます。
（文章力が無いので読みづらい場合はすいません...）

本稿では、VSCodeのおすすめ拡張機能（ついでに設定とか）を記載します。

# 拡張機能一覧
#### [indent-rainbow（タブに色づけで見やすく）](#indent-rainbow)
#### [（設定）editor Word Wrap（行の折り返し）](#editor-word-wrap)
#### [Bracket Pair Colorizer 2（カッコ()の色分け）](#bracket-pair-colorizer-2)
#### [vscode-icons（フォルダのアイコンをそれっぽく）](#vscode-icons)

## 拡張機能・設定説明
#### [indent-rainbow](#拡張機能一覧)
indent-rainbowは、インデント（Tabボタンで右にずれるやつ）の回数ごとに色を付けてくれます。
......
それだけ？と思われた方

それだけです。
それだけだけど凄い便利なんですよーって程の話でもありません。ただの好みです（笑）

#### [editor Word Wrap](#拡張機能一覧)
これは、画面が小さくなった時や、長い1文を記載した時に、
横にスクロールすることなく全ての文を見られるように改行（見た目だけで、実際は改行されない）してくれます。

まず、VSCodeの設定（*Ctrl+,*）を開きます。
そして検索欄に*word wrap*と記載し、以下に添付した画像のように、onにします。
![word_wrap.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545522/15191add-f02c-828e-e7e9-c0bdb6d29d0a.png)
以上です。

#### [Bracket Pair Colorizer 2](#拡張機能一覧)
これは、カッコ()の中にカッコが複数記載された際、
それぞれの色を別の色にしてくれます。
つまり、かっこが多くなった時に見やすくなるということです。

#### [vscode-icons](#拡張機能一覧)
VSCode内のエクスプローラのフォルダやファイルのアイコンがそれっぽくなります。
ここまでくると本当にただの好みの話ですし、自分も好きかどうか聞かれたら別にってなりますが、一応入れていたので（笑）


# 最後に
以上でお勧め拡張機能の紹介を終わります。
今後もこれいい！っていう拡張機能・設定があれば随時追加してまいります！

また、Web制作用のオススメ拡張機能をまとめておりますので、興味があればそちらもどうぞ