OmniAICreator/Qiita-1.07M huggingface dataset:
よく使うSQLコマンド, テーブル操作,よく使うブラウザーのショートカット 

# ■はじめに
コマンドを打つ際に毎回調べてという事が面倒くさいと思ったことはありませんか？
今の時代調べれば何でも出てきますから、何回も調べたらいいと思っていませんか？
でも、マニュアルを見ても、全てが１ページにまとまっていることは少ないと思います。
私はPHPの初心者ですが、自分がよく使うコマンドを、毎回作業中に手を止めて調べなくてもいいようにまとめました。

## ■SQLとは
SQLとは、データベースを扱う言語のことです。
SQLでは、CRUD
create(データの作成)
Read(データの読み取り)
Update(データの更新)
Remove(データの削除)
の４つの処理を
「INSERT, SELECT, UPDATE, DELETE」という４つの構文で行います。

このページはSQLのコマンドの一覧です。
Laravelのコマンドそ見たい方は、こちらも一緒にご覧ください。

https://qiita.com/drafts/9b52db64a0ea8b8f8d35/edit

# ■よく使うSQLコマンド

### データベースに接続
```bash
mysql -u root -p
```
-u ----- 「ユーザを指定する」というオプション
-u root ----- 「rootユーザで」みたいな意味
-p ----- 「パスワードを指定してログインする」というオプション


### データベースの一覧表示
```bash
mysql> SHOW DATABASES;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921810/a5bd17ba-0cc5-e947-20cf-b5468bfc9d6c.png)

### 使用するデータベース選択
```bash
mysql> USE データベース名;
```

### テーブル一覧の表示
前提
利用するデータベースをUSEで選択している必要があります。
```bash
mysql> SHOW TABLES;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921810/aba14ca4-9a2c-fad0-550a-b3168e0f8675.png)

### テーブルの中身を確認する
```bash
mysql> SELECT * FROM テーブル名;
```



### データベースの作成
```bash
mysql> CREATE DATABASE データベース名;
```

### データベースの削除
```bash
mysql> DROP DATABASE データベース名;
```

```bash
DLETE FROM テーブル名 WHERE 条件１;
```
論理削除
　なくなった事にする
  UPDATE文を使う

物理削除
　完全削除


## ■テーブル操作

【注意】データベースを追加したり、削除したり、変更したり、何かしら変化をさせた場合は、マイグレーションを忘れないように実行する事。

### テーブルの作成
```bash
mysql> CREATE TABLE [テーブル名] (
    column1 [データ型] [その他オプション],
    column2 [データ型] [その他オプション],
    column3 [データ型] [その他オプション],
);
```

### CREATE TABLE文を確認

```bash
mysql> SHOW CREATE TABLE [テーブル名];
```

### テーブルにデータを挿入(INSERT)

```bash
mysql> INSERT INTO `users`(`id`, `name`, `address`, `tel`) VALUES(1, 'nishide', 'Cebu', '080-xxx
```

### テーブルからデータを取得(SELECT)
```bash
mysql> SELECT * FROM `users`;
```

### usersテーブルから、idとnameだけを取得する(抽出するデータを一部にする)

```bash
mysql> SELECT `id`, `name` FROM `users`;
```

### 並べ替えてデータを取得(条件付き)

```bash
mysql> SELECT * FROM `users` ORDER BY id ASC;
mysql> SELECT * FROM `users` WHERE id = 2;
```

### データを更新
```bash
mysql> UPDATE [テーブル名] SET [COLUMN名] = '新しい値'
```

# ■よく使うブラウザーのショートカット
最後にブラウザーでよく使用するショートカットをまとめましたので、覚えておくと便利なので、参考にしてみてください。

|操作 | ショートカット|
|:-:|:-:|
|右隣のタブへ   | Ctrl + Tab  |
|左隣のタブへ  |Ctrl + Shift + Tab   |
|タブを閉じる   |Ctrl + W   |
|新しくタブを開く   |Ctrl + T   |
|閉じてしまったタブを開く   |Ctrl + Shift + T   |
|ブラウザの表の示拡大   |Ctrl + +   |
|ブラウザの表示の縮小   | Ctrl + -  |
|検索する   | Ctrl + F |
|全選択   |Ctrl + A   |
|コピーする   | Ctrl + C  |
|ペーストする   | Ctrl + V  |
noxで環境変数を消して実行

[Nox](https://nox.thea.codes/en/stable/index.html)で環境変数を消してコマンドを実行するにはどうしたら良いか？

既存の環境変数を上書き指定するなら`session.run(env={'FOO': 'bar'})`が使えますが削除はできません。`session.run(env={'FOO': None})`はエラーになります。

また`os.environ`で消しても効果はありません。コマンド実行時に適用される環境変数は`session`の中に保存されているためです。


`session`の中に保存されている環境変数を直接操作することで、実行時に適用される環境変数を、削除も含めて自由に編集できるようです。

```py
@nox.session
def good(session):
    """環境変数FOOを削除してコマンドを実行。"""
    session.env.pop('FOO', None)
    session.run('/usr/bin/printenv', external=True)
```
ChatGPTが途中で止まる

### 背景
最近の自分の作業スタイルとして、とりあえずChatGPTで調査する方法をとっています。
ChatGPTは自分の良き相談役になってくれていて、非常に効率的に業務ができています。

ただ、結構な頻度で回答が途中で止まってしまうことがあり、また同じ質問をすると回答までに時間がかかってしまい、多少のストレスを感じるようになりました。
簡単な解決策があったので備忘をかねて書いておきます。

### 事象
回答が途中で止まってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347087/9245491b-39bb-605c-8030-f070ed9ac469.png)

### 解決策
「続きを教えて」と聞くだけ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347087/316651f1-da00-97be-754c-08ff74ae7f58.png)

すると止まっていたところから再開してくれます。
newScheduledThreadPool method

fixedthreadpoolでscheduledThread
shutdown methodでループを止める
```java
public class Outer {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService s = Executors.newScheduledThreadPool(2);
        s.scheduleWithFixedDelay(() -> {
            System.out.print("a");
        },1,1,TimeUnit.SECONDS);
             Thread.sleep(500);
        s.scheduleWithFixedDelay(() -> {
            System.out.print("b");
        },1,1,TimeUnit.SECONDS);
        Thread.sleep(10000);
        s.shutdown();
    }
}
```
```
abababababababababa
```
さようなら「Try TweetDeck Preview」ボタン

こんにちは、Ctrl([@hiyoctrl](https://twitter.com/hiyoctrl))です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Better TweetDeckの「Try TweetDeck Preview」ボタンを非表示、がなぜか効かないので<br><br>.js-gryphon-beta-btn.gryphon-beta-btn-container{display:none}<br><br>↑をカスタムCSS記述するなどした<br><br>（無事に消えた）</p>&mdash; Ctrl (@hiyoctrl) <a href="https://twitter.com/hiyoctrl/status/1615230027259596801?ref_src=twsrc%5Etfw">January 17, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Twitterで呟きましたが、忘れないうちにQiitaにも書いておきます。

Better TweetDeckの「Try TweetDeck Preview」ボタンを非表示、がなぜか効かないので

```
.js-gryphon-beta-btn.gryphon-beta-btn-container{display:none}
```

↑をカスタムCSS記述したら、無事に消えました。
テスト記事を作成する

テスト記事です。

新しく記事を作成する。練習を行います。
第１章　●●について



第２章　▲▲について


結論

記事の書き方は奥が深い。

以下１回目編集
　追記）▲▲の補足

```Python
function(){
    return "hello world!";
}
```
コードを作成する。

```Python
a=10
b=10
print(a*a*a*a*b*b*b*b)
```

結論
コードの挿入は```Python (バッククオート3つのあとに言語指定)を使用することで、作成することができる。


# 見出し

## 見出し
### 見出し
どうやら、下線が出るのは、「# 見出し、## 見出し」であり、「### 見出し」は下線は出ない模様

![スクリーンショット .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114779/a6e035c8-01e2-1e6f-4e5f-605ef70821ba.png)

どうやら右側に出てくるのは、このような「#を用いた見出し」を使用することで
作成することが可能になる模様。

追記）Qiitaでの文章編集について追加したところは、緑色で表示される。
![スクリーン1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114779/d3402d66-9aa6-a345-ea72-16d96811541b.png)

一方で削除した内容は、赤色で表示される。
![スクリーン2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114779/61f95fd0-609d-2d06-0464-c45ce419118e.png)
iphoneってウィルススキャンできるの？

公式ドキュメントは見つけられませんでしたが、おそらくできないようです。

* https://support.apple.com/ja-jp/guide/iphone/iph6e7d349d1/ios (apple公式)
* https://www.softbank.jp/support/faq/view/12296 （softbank）
  Q. ［iPhone／iPad］ウィルス対策は必要ですか？
  A. いいえ、iPhone／iPad ではウイルス対策の必要はございません。
mysqlよくつまるところ

# mysqlをbrewでインストールする時のログ

以下に記述もあるように、mysql_secure_installationで最初にパスワードの初期設定などが必要みたい
```
We've installed your MySQL database without a root password. To secure it run:
    mysql_secure_installation

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

mysql@5.7 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have mysql@5.7 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.zshrc

For compilers to find mysql@5.7 you may need to set:
  export LDFLAGS="-L/usr/local/opt/mysql@5.7/lib"
  export CPPFLAGS="-I/usr/local/opt/mysql@5.7/include"

For pkg-config to find mysql@5.7 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/mysql@5.7/lib/pkgconfig"


To restart mysql@5.7 after an upgrade:
  brew services restart mysql@5.7
Or, if you don't want/need a background service you can just run:
  /usr/local/opt/mysql@5.7/bin/mysqld_safe --datadir=/usr/local/var/mysql
==> Summary
🍺  /usr/local/Cellar/mysql@5.7/5.7.40: 320 files, 233.5MB
==> Running `brew cleanup mysql@5.7`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
```

# エラーログ
↑をやって、mysqlを起動してないと以下のようなログが出る
・Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1'
・ERROR! The server quit without updating PID file (/usr/local/var/mysql/端末名.local.pid).
・ Can't connect to local MySQL server through socket '/tmp/mysql.sock'

# mysqlとbrewとバージョン
brewでmysqlでインストールすると関連コマンドがmysql@5.7みたいになったりするので注意
【Xcode】ファイル作成時に自動生成されるコメントの本名を変更したい

# はじめに
タイトルだけだとわからないかもしれないので画像載せておきます。
これです。
![スクリーンショット 2023-01-17 14.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/884f8acd-8387-e7c3-a653-ce89ece207b9.png)

この自動生成されるコメントを変更したのでやり方を記事にしておきます。

# やりかた
Xcode内のUserDataフォルダに移動します。
```:ターミナル
cd ~/Library/Developer/Xcode/UserData
```
![スクリーンショット 2023-01-17 14.56.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/149f946b-57c9-c2ec-b03b-ebda9deea5b2.png)

`IDETemplateMacros.plist`を作成します。
```:ターミナル
touch IDETemplateMacros.plist
```
![スクリーンショット 2023-01-17 14.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e622ec7c-1779-0f01-8c9b-ce4145141de7.png)

テキストエディターで`IDETemplateMacros.plist`を開きます。
```
open IDETemplateMacros.plist -e
```
![スクリーンショット 2023-01-17 14.59.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f104fe91-cbd4-828f-d6ec-0fa9cb0452b7.png)

以下のコードをコピペします。
`___USERNAME___`の部分を好きな名前に変更します。
```IDETemplateMacros.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>FILEHEADER</key>
    <string>
//  ___FILENAME___
//  ___TARGETNAME___
//  
//  Created by ___USERNAME___ on ___DATE___
//  ___COPYRIGHT___
//</string>
</dict>
</plist>
```

:::note info
私はこのような感じに変更しました
```IDETemplateMacros.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>FILEHEADER</key>
    <string>
//  ___FILENAME___
//  ___TARGETNAME___
//  
//  Created by TAISHIN MIYAMOTO on ___DATE___
//  ___COPYRIGHT___
//</string>
</dict>
</plist>
```
:::

# 確認してみる
新しくプロジェクトを作成してみると。。。

変わってた！！！
![スクリーンショット 2023-01-17 15.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/45dc239a-6fa9-1539-ca28-6494105b8b34.png)

# おわり
こんなに簡単に変更できるなんて！！
bundle install詰まったとこまとめ。



# 自分ノウハウ
bundle installで詰まった時は以下の手順が良いかもと思った

1.まず社内の人のbundle設定とGemfile.lock設定をもらって```bundle install --path vendor/bundle```を実施

2.以下を良い塩梅で並行して実施
	・依存関係を壊さぬようバージョンをおろす
    	→gem queryやgem list gem名 -reaなどでインストール可能なバージョンを確認:[参考](https://teratail.com/questions/151420)
	・エラーログをググってそれを実行
   ・社内知見をあさって実施
	・gemのgitなどの公式サイトを確認、自分のインストールしているバージョンに不具合ないかissueで検索したりもよし
    ・ruby -vでバイナリーバージョンを確認。
     x86_64-darwin19とかなら、x86_64はmacのバージョンなので、[こんな感じのとこ](https://rubygems.org/gems/eventmachine/versions)見て、無印のosあればバージョンは問題なし


注意点
・gemのインストール先に注意
・bundle のconfig設定と、どのconfig設定を参照しているか注意
・エラーログだけでなく、インストール時などもログを注意してみること
・[ここ](https://qiita.com/Takao_/items/7fda2a51db95c4724ad5)を参考にgitignoreを対応


# 具体例
#### eventmachine(em-websocketが依存)
以下のようなエラー
```
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [rubyeventmachine.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in xxx/vendor/bundle/ruby/2.7.0/gems/eventmachine-1.2.7 for inspection.
Results logged to xxx/vendor/bundle/ruby/2.7.0/extensions/x86_64-darwin-22/2.7.0/eventmachine-1.2.7/gem_make.out

An error occurred while installing eventmachine (1.2.7), and Bundler cannot continue.
Make sure that `gem install eventmachine -v '1.2.7' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  em-websocket was resolved to 0.5.1, which depends on
    eventmachine
```
Gemfileに以下を追記してbundle install
```gem 'eventmachine', '1.0.9.1'```

```参考
gem query eventmachine -rea
WARNING:  query command is deprecated. It will be removed in Rubygems 4.
WARNING:  It is recommended that you use `gem search` or `gem list` instead.

*** REMOTE GEMS ***

eventmachine (1.2.7 ruby java x64-mingw32 x86-mingw32, 1.2.6 ruby java x64-mingw32 x86-mingw32, 1.2.5 ruby java x64-mingw32 x86-mingw32, 1.2.3 ruby java x64-mingw32 x86-mingw32, 1.2.2 ruby java x64-mingw32 x86-mingw32, 1.2.1 ruby java x64-mingw32 x86-mingw32, 1.2.0.1 ruby java x64-mingw32 x86-mingw32, 1.2.0 ruby x64-mingw32 x86-mingw32, 1.0.9.1 ruby java, 1.0.9 ruby java, 1.0.8 ruby java, 1.0.7 ruby java, 1.0.6 ruby java, 1.0.5 ruby java, 1.0.4 ruby java, 1.0.3 ruby java x86-mingw32 x86-mswin32-60, 1.0.2 ruby java x86-mingw32 x86-mswin32-60, 1.0.1 ruby java x86-mingw32 x86-mswin32-60, 1.0.0 ruby java x86-mingw32 x86-mswin32-60, 0.12.10 ruby java x86-mswin32-60, 0.12.8 ruby java x86-mswin32-60, 0.12.6 ruby java x86-mswin32-60, 0.12.4, 0.12.2, 0.12.0 ruby i386-mswin32, 0.10.0, 0.9.0, 0.8.1, 0.8.0, 0.7.2, 0.7.0, 0.5.3, 0.5.2, 0.5.1, 0.4.5, 0.4.4, 0.4.3, 0.4.2, 0.4.0, 0.3.1)
```


#### libv8
バックアップをとってGemfile.lockを削除し、Gemfile.lockの記載を```libv8-node (16.10.0.0)```に変えてbundle install

#### mysql2
以下のコマンドを実施
```
bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"
```
SSIMオートエンコーダでMVTecのtileを学習

# SSIMを構築して結果を確認した

ここでMVTecのタイルを使用してSSIMオートエンコーダでの検証を行う。
https://www.mvtec.com/company/research/datasets/mvtec-ad

正常の入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/67f469a7-754f-825f-0669-cb4c32c14969.png)

異常の入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/5e744f2c-17bc-23e0-1911-b7cbed689403.png)

とする。
googlecolabのGPUを使用するので、グレースケール変換して実行する。

## 結果
図の見方
縦軸　上から入力、出力、差分となっている
横軸　枚数　となっている

### 正常
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/e3703622-09ed-4731-0218-056cdaee0724.png)


### 異常
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/e04e96b3-0acf-4d72-0787-753d41db8775.png)


## 結果
やっぱり論文（https://link.springer.com/content/pdf/10.1007/s11263-020-01400-4.pdf）
と同様に細部の復元が出来ずにうまく抽出できないという結果が出てきてしまった。
つぎはオブジェクト系とかで検証してみる。
【データ基盤構築/BigQuery】GoogleSpreadSheetsを、外部テーブルとしてBigQueryのテーブルとして取り込む

# 今回の課題
業務で非エンジニアの人がスプレッドシートを手動で更新したら、
**リアルタイム**でBigQueryのテーブルが変更されるという仕組みが作りたかった。


# 解決策
GoogleSpreadSheetsを外部テーブルとして、BigQueryのテーブルとして扱うことで実現することができた。

※参考：[Google スプレッドシートを BigQuery のテーブルとして扱う](https://beniyama.hatenablog.jp/entry/2019/02/18/080000)
## スプレッドシートを外部テーブルにするメリット・デメリット
### メリット
* 手動でスプレッドシートを更新すると、BigQueryにもリアルタイムで反映される。
* 非エンジニアの人でも簡単にテーブルを更新することができる。

### デメリット
* BigQuery上でテーブルのプレビューが確認できない。
* テーブルの更新をワークフローに組み込む訳ではないので、外部テーブルをベーステーブルとしたaggregationテーブルを作成するクエリなどは、別途実行する必要がある。
Dockerの全コンテナ・ボリューム・ネットワークを消し去る滅びの呪文（完全版）

## 実行するマシンに入っているdockerのデータも何もかも全部消えますので注意！

```sh
docker stop $(docker ps -q) && docker system prune --volumes
```

docker自体は残ります。
【初心者】Laravel Migration コマンドまとめ

# はじめに
コマンドを打つ際に毎回調べてという事が面倒くさいと思ったことはありませんか？
今の時代調べれば何でも出てきますから、何回も調べたらいいと思っていませんか？
でも、マニュアルを見ても、全てが１ページにまとまっていることは少ないと思います。
私はPHPの初心者ですが、マイグレーションとは、どのような時に、どのような目的で行うことなのかが曖昧で、初めてwebアプリケーションを作成した時に、一番多かったエラーはマイグレーションを実行していないことが原因のエラーが一番多かったです。
そこで、マイグレーションに関連するコマンドを、まとめました。

## マイグレーションに関連するコマンド一覧

マイグレーションを実行する

```bash
$ php artisan migrate
```

直前に実行したひとまとまりのマイグレーションをロールバック
(ロールバックをする際には、データのバックアップを取ることをお奨めします)

```bash
$ php artisan migrate:rollback
```

全部ロールバックしてからマイグレーションし直す
(ロールバックをする際には、データのバックアップを取ることをお奨めします)

```bash
$ php artisan migrate:refresh
```

全てのテーブルを削除してマイグレーションし直す

```bash
$ php artisan migrate:fresh
```

マイグレーションの状況を確認する

```bash
$ php artisan migrate:status
```
m1macにgvmをインストールする際に役立った記事

https://akataworks.hatenadiary.jp/entry/2016/10/18/201025
https://apple.stackexchange.com/questions/408375/zsh-bad-cpu-type-in-executable
https://okumuralab.org/~okumura/macosx/m1.html
https://github.com/moovweb/gvm/issues/188#issuecomment-256615244
Monacaでボイスレコーディングアプリを作る（その4：ファイルストアの音声ファイルをWeb Audio APIで再生する）

NCMBとMonacaを使ってボイスレコーディングアプリを作ります。HTML APIだけを使うので、プラグインを使わずに開発できます。録音した音声をNCMBのファイルストアへアップロードし、逆にダウンロードして再生できるアプリです。

[前回までで一通りの実装は完了した](https://qiita.com/goofmint/items/583889bcf4466ca123fb)のですが、音声ファイルをHTTPSファイル公開して再生するのがちょっと気になっていたので、Web Audio APIでの再生に変更してみました。

## コードについて

今回のコードは[NCMBMania/monaca\-voice\-recorder](https://github.com/NCMBMania/monaca-voice-recorder)にアップロードしてあります。実装時の参考にしてください。

## 今回の処理について

今回の処理はすべて `www/pages/home.html` に記述しています。

## 前回のコードから削除する箇所

前回のコードでは uri が指定されると、画面にaudioタグを表示していましたが、それが不要になります。以下の部分です。

```html
<!-- 録音データが選択されたら audio タグを表示する -->
${ uri !== '' ?
  $h`<audio src="${uri}" controls style="width:100%;"></audio>`
  :
''
}
```

また、アプリIDや再生用URIも不要です。以下は不要です。

```jsx
// 再生用のURI
let uri = '';
// アプリID
const appId = 'YOUR_APP_ID';
```


## 音声ファイルを選択した際の処理

音声ファイルを選択した際の処理 `listen` 関数を修正します。元々の実装は以下のようになっているでしょう。

```jsx
const listen = async (file) => {
  // ファイルストアからダウンロード
  const blob = await ncmb.File.download(file.fileName, 'blob');
  // URIに変換
  uri = URL.createObjectURL(blob);
  // 描画更新
  $update();
}
```

以下はすべて `listen` 関数の内容です。まずファイルをダウンロードするところは変わりません。

```jsx
// ファイルストアからダウンロード
const blob = await ncmb.File.download(file.fileName, 'blob');
```

そして、BlobからArrayBufferに変更します。

```jsx
// BlobからArrayBufferに変換
const arrayBuffer = await blob.arrayBuffer();
```

このArrayBufferをAudioBufferに変換します。

```jsx
// Web Audio APIのコンテキストを作成
window.AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
// ArrayBufferからAudioBufferに変換
const audioBuffer = await (new Promise((res, rej) => {
  context.decodeAudioData(arrayBuffer, res, rej);
}));
```

続けて、再生するソースとして適用します。

```jsx
// ソースを使って再生
const source = context.createBufferSource();
source.buffer = audioBuffer;
```

最後の再生を開始して終了です。

```jsx
source.connect(context.destination);
source.start(0);
```

`listen` 関数の内容は次の通りです。

```jsx
// 録音データを選択した際の処理
const listen = async (file) => {
  // ファイルストアからダウンロード
  const blob = await ncmb.File.download(file.fileName, 'blob');
  // BlobからArrayBufferに変換
  const arrayBuffer = await blob.arrayBuffer();
  // Web Audio APIのコンテキストを作成
  window.AudioContext = window.AudioContext || window.webkitAudioContext;
  const context = new AudioContext();
  // ArrayBufferからAudioBufferに変換
  const audioBuffer = await (new Promise((res, rej) => {
    context.decodeAudioData(arrayBuffer, res, rej);
  }));
  // ソースを使って再生
  const source = context.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(context.destination);
  source.start(0);
}
```

これでHTTPSファイル公開を使わず、ファイルストアからダウンロードした音声を直接再生できます。audioタグのように再生ボタンを押す必要もないので、ユーザー体験も向上します。

![0537 localhost - 0117140217.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/a5baa805-638a-040c-668f-efd1477f1402.jpeg)


## まとめ

今回はaudioタグからWeb Audio APIを使う方法に変更しました。BlobからArrayBufferに変換し、さらにAudioBufferに変換するところさえ分かれば、再生すること自体は難しくありません。

ただし、この方法ではストリーミング再生はできないので（一旦すべてダウンロードする必要があります）、ダウンロード中はローディングを出すと言った工夫が必要でしょう。
wslでnerves その8

# 概要
wsl(wsl2じゃない)でnervesやってみる。
qemu(x86_64エミュレータ、ラズパイじゃない)でやってみた。
練習問題やってみた。

# 練習問題
Toolshedを使え。

# 実行結果

```

iex(1)> h(Toolshed)

                                    Toolshed

Making the IEx console friendlier one command at a time

To use the helpers, run:

    iex> use Toolshed

Add this to your .iex.exs to load automatically.

The following is a list of helpers:

  ? cat/1          - print out a file
  ? cmd/1          - run a system command and print the output
  ? date/0         - print out the current date and time
  ? dmesg/0        - print kernel messages (Nerves-only)
  ? exit/0         - exit out of an IEx session
  ? fw_validate/0  - marks the current image as valid (check Nerves system
    if supported)
  ? grep/2         - print out lines that match a regular expression
  ? hex/1          - print a number as hex
  ? history/0      - print out the IEx shell history
  ? httpget/2      - print or download the results of a HTTP GET request
  ? hostname/0     - print our hostname
  ? ifconfig/0     - print info on network interfaces
  ? load_term!/2   - load a term that was saved by save_term/2
  ? log_attach/1   - send log messages to the current group leader
  ? log_detach/0   - stop sending log messages to the current group leader
  ? lsof/0         - print out open file handles by OS process
  ? lsmod/0        - print out what kernel modules have been loaded
    (Nerves-only)
  ? lsusb/0        - print info on USB devices
  ? multicast_addresses/0 - print out all multicast addresses
  ? nslookup/1     - query DNS to find an IP address
  ? ping/2         - ping a remote host (but use TCP instead of ICMP)
  ? qr_encode/1    - create a QR code (requires networking)
  ? reboot/0       - reboots gracefully (Nerves-only)
  ? reboot!/0      - reboots immediately  (Nerves-only)
  ? save_value/2   - save a value to a file as Elixir terms (uses inspect)
  ? save_term!/2   - save a term as a binary
  ? top/2          - list out the top processes
  ? tping/2        - check if a host can be reached (like ping, but uses
    TCP)
  ? tree/1         - pretty print a directory tree
  ? uptime/0       - print out the current Erlang VM uptime
  ? uname/0        - print information about the running system
    (Nerves-only)
  ? weather/0      - get the local weather (requires networking)

iex(2)> uname
Nerves nerves-3456 hello_nerves 0.1.0 (b635da3d-e2de-5870-b878-d6d6630f4053) x86_64
iex(3)> uptime
3 minutes and 40 seconds
iex(4)> weather
** (RuntimeError) :inets can't be started.
This probably means that it isn't in the OTP release.
To fix, edit your mix.exs and add :inets to the :extra_applications list.

    (toolshed 0.2.26) lib/toolshed/http.ex:142: Toolshed.HTTP.check_app/1
    (toolshed 0.2.26) lib/toolshed/http.ex:13: Toolshed.HTTP.weather/0
iex(4)>
```


以上。
【Vue.js】目指せ地理マスター！首都の緯度・経度から国名を当てるゲーム

### 【概要】
2022年6月1日時点の世界の首都（未承認含む）の緯度・経度がランダムに表示され、その座標データから国名を当てるゲームです。

### 【環境】
Vue.js バージョン3.2.29

### 【注意点】
・CodePen上だと「正解の場所を地図で確認」リンク押下すると「www.google.co.jp はブロックされています」メッセージが表示されGoogle Mapのサイトが開けません。リンク押下を試したい場合は、リンクを右クリック -> 新しいタブで開く から開いてください。

・国名は一般的ではないものがあります。例えば"アメリカ"は"アメリカ（米国）"と入力しないと不正解となります。当記事ではVue.jsの勉強を目的として作成したため、国名については特に考慮せずダウンロードしたデータそのままを使用しています。

・当初はGoogle Mapを埋め込みで表示させようとしましたが、Vue.jsの非同期処理でCross Origin制約に引っかかってしまうようで出来ませんでした。該当箇所はコメントアウトしてありますので、試したい方はコメントアウトを外してください。

### 【コード】
JavaScriptのコード内で定義している国データの定数は、[世界の首都の位置データ Location Data of World Capitals](https://amano-tec.com/data/world.html)からデータダウンロードして整形したものです。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYBzpgd" data-user="nobu12n" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nobu12n/pen/LYBzpgd">
  Untitled</a> by nobu (<a href="https://codepen.io/nobu12n">@nobu12n</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 【参考書】
[これからはじめるVue.js 3実践入門](https://www.amazon.co.jp/%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8BVue-js-3%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4815613362/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=38KV5I6N1LOKK&keywords=vue&qid=1673930995&sprefix=vue%2Caps%2C184&sr=8-6)

### 【参考サイト】
[世界の首都の位置データ Location Data of World Capitals](https://amano-tec.com/data/world.html)
[実はヤバい？aタグと別タブで開く（target=”_blank”）の使い方](https://wwg.co.jp/blog/3807)
[【ネットワーク】GeoGuessrをプログラマー的方法で攻略する](https://qiita.com/Nobu12/items/a730f2b435e0aaf6e931)
FESS で Redmine Wiki をクロールしたい

* 社内 Redmine の Wiki の記事が増えてきたので効率的に検索したい
* 全文検索サーバー FESS を導入（14.5.0)
* Wikiはプロジェクト毎にあって、階層化されている
<dl>
  <dd><strong>これを一気にクロールする方法</strong></dd>
</dl>

# クローラーの設定
* ウェブではなく、データストアからクロールする
* プラグイン fess-ds-db & fess-crawler-db-mysql を入れる

##  データストアのクロール設定

* ハンドラー名「DatabaseDataStore」を指定

パラメーターで指定するSQL文

```.sql
sql=select
       wp.id as id ,wp.wiki_id as wiki_id ,wp.title as title ,
       w.project_id as project_id ,p.identifier as identifier,
       wc.text as text, 
       DATE_FORMAT(wc.updated_on,'%Y-%m-%dT%H:%i:%s.00Z') AS 
       last_modified_dt 
     from 
       wikis w, wiki_pages wp, wiki_contents wc, projects p 
     where 
       wp.wiki_id=w.id and wp.id=wc.page_id and w.project_id=p.id
```

url に埋め込むプロジェクトID：identifier
url に埋め込むタイトル：title
検索結果を期間で絞り込みたいので更新日を取得：update_on → last_modified_dt

パラメーターに記載するSQLは1行で記載しないとエラーになります。

```.sql
sql=select wp.id as id ,wp.wiki_id as wiki_id ,wp.title as title ,w.project_id as project_id ,p.identifier as identifier, wc.text as text, DATE_FORMAT(wc.updated_on,'%Y-%m-%dT%H:%i:%s.00Z') AS last_modified_dt from wikis w, wiki_pages wp, wiki_contents wc, projects p where wp.wiki_id=w.id and wp.id=wc.page_id and w.project_id=p.id
```

* パラメータ

```
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://172.xx.xx.xx:3306/bitnami_redmine?useUnicode=true&characterEncoding=UTF-8
username=adminUser
password=dbAdminPass
sql=select wp.id as id ,wp.wiki_id as wiki_id ,wp.title as title ,w.project_id as project_id ,p.identifier as identifier, wc.text as text, DATE_FORMAT(wc.updated_on,'%Y-%m-%dT%H:%i:%s.00Z') AS last_modified_dt from wikis w, wiki_pages wp, wiki_contents wc, projects p where wp.wiki_id=w.id and wp.id=wc.page_id and w.project_id=p.id
```

* スクリプト
---

    url="https://xxx.xx.xx.xx/redmine/projects/" + identifier + "/wiki/" + title
    host="https://xxx.xx.xx.xx/"
    site="https://xxx.xx.xx.xx/redmine/projects/" + identifier + "/wiki/"
    title="【Redmine - wiki】" + title
    content=text
    cache=text
    digest=title
    anchor=
    content_length=content.length()
    last_modified=last_modified_dt
    timestamp=last_modified_dt

---

* スクリプトのパラメータ timestamp に更新日を入れると検索結果から期間での絞込みが可能になる

# Redmine Wiki DB構造

![DB構造_Redmine.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114660/864853c2-1e4f-8bd4-8cdd-174f5f1247fe.jpeg)
マルチバイト対応(PHP)

マルチバイト対応のプログラムのサンプルプログラムです。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ビルトイン関数4(マルチバイト対応)</title>
  <style> 
      .test1 {
        color:#504;
      }

      .test2 {
        color:#ff18c1;
      }
      .test3 {
        color:#d7c109;
      }
      .test4 {
        color:#d7f139;
      }


  </style>
</head>
<body>
  <?php
      // 文字列の長さを取得する
      $str = ' 秋元真夏はふつうにかわいい ';
      $num  =mb_strlen($str); 
      echo "<p class=test1>" . $num . "</p>";
      // 空白を削除する
      $str = trim($str);
      $num =mb_strlen($str);
      echo "<p class=test2>" . $num . "</p>";
      // str変数から「_」が最初から何番目にあるかを取得する
      echo "<p class=test3>" . mb_strpos($str,'ふつうに') . "</p>";
      // str変数から「_」を「-」に置換する
      $str2 = str_replace('ふつうに','超',$str);
      echo "<p class=test4>" . $str2 . "</p>";

      

  ?>
</body>
</html>
```

PHPの部分です。

```PHP
   // 文字列の長さを取得する
      $str = ' 秋元真夏はふつうにかわいい ';
      $num  =mb_strlen($str); 
      echo "<p class=test1>" . $num . "</p>";
      // 空白を削除する
      $str = trim($str);
      $num =mb_strlen($str);
      echo "<p class=test2>" . $num . "</p>";
      // str変数から「_」が最初から何番目にあるかを取得する
      echo "<p class=test3>" . mb_strpos($str,'ふつうに') . "</p>";
      // str変数から「_」を「-」に置換する
      $str2 = str_replace('ふつうに','超',$str);
      echo "<p class=test4>" . $str2 . "</p>"; 
```
EXCELで絞り込んだ結果を行削除

:::note info
数十万行あるCSVから指定項目の行を削除するVBAを作成
最初に行DELETEで検証　→　時間が鬼かかる
:::

```vb:vba
Option Explicit

Sub exec()
    Dim workCol As Collection
    Set workCol = New Collection
    Dim filterItem As Variant
    
    '要素の追加(初期化)
    With workCol
        .Add "あああ"
        .Add "いいい"
        .Add "ううう"
        .Add "えええ"
        .Add "おおお"
    End With

    Application.ScreenUpdating = False

    For Each filterItem In workCol
        Call filter(filterItem)
    Next workItem
    
    Application.ScreenUpdating = True
    
End Sub

Private Sub filter(ByVal item As String)
    
    '項目でフィルタをかける
    Range("A1").AutoFilter 10, item
    
    'フィルタ結果がある場合実行
    If WorksheetFunction.Subtotal(3, Range("A:A")) > 1 Then
        
        '見出しを除くフィルタ結果を削除
        With Range("A1").CurrentRegion
            .Resize(.Rows.Count - 1).Offset(1, 0).EntireRow.Delete
        End With
            
    End If
    
    'フィルタを解除
    Range("A1").AutoFilter
    
End Sub
```

:::note info
上記ソースでは時間が鬼かかるので違う方法を模索
①フィルタ
②行クリア
③フィルタ解除
④並び替え(空白行を下に)
⑤以後繰り返し
10数時間かかっていたのが3分で処理出来るようになった！
:::


```vb:vba
Option Explicit

Sub exec()
    Dim workCol As Collection
    Set workCol = New Collection
    Dim filterItem As Variant
    
    '要素の追加(初期化)
    With workCol
        .Add "あああ"
        .Add "いいい"
        .Add "ううう"
        .Add "えええ"
        .Add "おおお"
    End With

    Application.ScreenUpdating = False

    For Each filterItem In workCol
        Call filter(filterItem)
    Next workItem
    
    Application.ScreenUpdating = True
    
End Sub

Private Sub filter(ByVal item As String)
    
    '項目でフィルタをかける
    Range("A1").AutoFilter 10, item
    
    'フィルタ結果がある場合実行
    If WorksheetFunction.Subtotal(3, Range("A:A")) > 1 Then
        
        '見出しを除くフィルタ結果をクリア
        With Range("A1").CurrentRegion
            .Resize(.Rows.Count - 1).Offset(1, 0).Clear
        End With
            
    End If
    
    'フィルタを解除
    Range("A1").AutoFilter
    
    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add2 Key:=Range("B1"), Order:=xlAscending
        .SetRange Range("A1:AV1048576")
        .Header = xlYes
        .Apply
    End With
End Sub
```
【JavaScript】Node.jsでのfs.readFileSync()の相対パス

# Node.jsでのfs.readFileSync()
以下のようなディレクトリ構成で作業をしているとしましょう。
```
│  main.js
│
├─commands
│      callhere.js      //fs.readFileSync()を呼ぶファイル
│      other1.js
│      other2.js
└─config
        config.json     // 読み込みたいjsonファイル
```
さて、jsonファイルを読み込むためには、どのようにすればいいでしょうか。``callhere.js``で
```javascript
const jsonData = JSON.parse(fs.readFileSync("../config/config.json")); 
```
とすればパスが通っていそうですよね。しかし、``Node.js``をインストールしているディレクトリでは、この書き方ではエラーになってしまうのです。どうやら、この書き方では、現在のファイル(例では``callhere.js``)が存在する位置を最上位のディレクトリとして設定してしまい、現在のディレクトリより外には移動できないシステムみたいです。
例だと、``callhere.js``から、``config``ファイルや``main.js``へ``fs.readFileSync()``ができないみたいです。

# 解決策: pathモジュールのpath.resolve(__dirname, " ")
というのを使うことで、この問題が解決できます。今回の例だと
```javascript
const jsonData = JSON.parse(fs.readFileSync(path.resolve(__dirname,"../config/config.json"))); 
```
となります。シンプルに相対パスを指定して読み込むことができるようになります。
爆速React+TypeScript+Viteの環境構築

どうも、初めまして。
面識のある方は、お久しぶりです。みつくまです🐻

今日は、DockerにおけるReactの環境構築方法についてお話することができればと思います。

# 最初からクライマックス
まず、Docker Desktopを起動します。
Dockerを動かしたいディレクトリで
コマンドプロンプトを召喚します。
そして以下のコマンドを入力します。
```
% git clone https://github.com/sprout2000/docker-react-ts.git
% cd docker-react-ts
% docker-compose up
```

以上で、React + TypeScript + Viteの環境構築は終了です！
それでは、また次回！🐻

と流石に私自身なんのプラスにもなっていないので内部のファイルについて
理解したことをお話していこうと思います。

# 中身はどうなってるの？

まずはdocker-compose.ymlから

```yml
services: #1　このエントリから以下がServiceという扱い
  app: #appコンテナ（以下にコンテナの内容が書かれている）
    container_name: react-app-container # コンテナの名前
    image: node:16-alpine
    volumes:
      - ./:/app # ホスト側の./をコンテナ側の/appにマウントする
    working_dir: /app
    command: sh -c "npm install && npm run dev"
    ports:
      - '5173:5173'

```

マウントとは、コンテナ内のファイルをホストPC上のファイルシステムと関連付けるという意味があります。

```Dockerfile
FROM node:16-alpine # イメージを指定
WORKDIR /app # コンテナ上でのワーキングディレクトリを指定
COPY package.json . #　依存パッケージをインストールするためpackage.jsonをイメージのファイルシステム上にコピー
COPY package-lock.json . #　依存パッケージをインストールするためpackage-lock.jsonをイメージのファイルシステム上にコピー
RUN npm install # npmのインストール
COPY . . # 残りのソースコードをホストPC上からイメージのファイルシステム上にコピー
EXPOSE 5137 # 5137ポートを公開する
CMD [ "npm", "run", "dev" ] # コンテナの実行時に実行されるコマンドを指定
```

注意なのですが、docker-compose up する時に5137ポートを他で使用している場合は、閉じるか変更してください。

# 最後に
本当は、自力でDockerfile,docker-compose.ymlを作成したかったのですが
アプリケーションの開発をするためのdocker構築なのに
そっちに時間割かないのはどうなんだ...?と思い既存のファイルを参照しました。
いずれは、自作できるように勉強していきたいです。

個人開発として、springboot + Reactでwebアプリケーションをこれから作成していこうと思っています。
そちらの方でも発見があったら記事にしていきたいと思います！
長々としたあとがきになってしまいましたが、ここまで読んでいただきありがとうございました！
また、別の記事で🐻
この型パラメーターには 'extends object' 制約が必要な場合があります。

ジェネリックを使って、functionを作成した時にlintで怒られた。
Object.keysの引数には、1つ以上のプロパティを持つオブジェクトを入れる必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/380959/e00e9c72-9483-6427-7ad6-0d47b7a55ca5.png)
そのため、Tに対して extends object を追加することによってlintエラーを回避した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/380959/806cde08-fb0f-7b73-962d-d0cd7dae3301.png)

object or {} どちらにすれば良いかは下記を参照する 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/380959/a37b10ab-b34a-a62b-f581-859bda7c725f.png)


https://typescriptbook.jp/reference/values-types-variables/object/difference-among-object-and-object
2023年から始めるTableau入門② -連続と不連続-

## はじめに
23年2月からTableau案件にアサインされることになったので、理解を深めるためにまとめます。

第1回　[ディメンジョンとメジャー](https://qiita.com/freestyleaerial/items/233b96dd21c8016af5f4)
第2回　連載と不連続 ←今回

### 筆者の技術力

:::note warn
業界歴半年で、つい2週間前にTableau Desktopをインストール。BIツールはTableauが初めてです。
:::

## 参考

https://note.com/ritz_tableau/n/n9ace1b466ffe

## 連続とは
:::note info
「連続」は定規の目盛りのようなイメージで、数字が秩序正しく並んでいる。並び方を変更することは出来ない。
:::

例に挙げた定規で考えると、定規の目盛りは１，２，３と順番で並んでいて、並び変えることは出来ません。
また、目盛り同士の間隔はどこを見ても「１」の倍数となっていて、この間隔を詰めたり伸ばしたりは出来ません。

## 不連続とは
:::note info
「不連続」はバラバラに分かれたトランプのカードのようなイメージで、任意の順番で並べることができる。並び方の変更できる。
:::

トランプのカードであれば、「１」から並べることが出来ますし、逆に「９」から並べることも出来ます。並べ替えも任意で可能です。

## Tableau上の「連続」と「不連続」
数値や日付形式のディメンジョン・メジャーをフィールドに配置すると、色付けされて表示されます。この色が緑の場合、「連続」であることを表します。

▼ 緑色：連続（並べ替え不可）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/16d6a1c9-4111-69d9-8446-ea7e757a6493.png)
▼ 青色：不連続（並べ替え可）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/432212cc-d3a5-32ed-0988-5fe5f2004805.png)

データソースを読み込む際、Tableauが自動的に「連続」と「不連続」を判断して分類（色分け）してくれます。

## 日付形式を例に「連続」と「不連続」の違い
Tableauが自動的に「連続」と「不連続」を分類してくれますが、ユーザーが任意でこれらの切り替えを行うことが出来ます。

例えば、列に日付形式の「オーダー日」ディメンジョンを、行に売上合計を配置しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/388fa78e-f4fc-ef41-c3b0-f68f0093db86.png)

このとき、オーダー日は「不連続（青色）」として分類されていることが分かります。

不連続ということは、月毎がバラバラのカードとして存在しているので、並べ替えが可能です。

売上が最も多い月から降順に並べ替えてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/886c3071-f57c-8c94-a8f2-6c2355edd579.png)

不連続なので、ソートが出来たということです。

さて、自動的に不連続として分類されたオーダー日を「連続」に変えたらどうなるか見てみましょう。

やり方は次の通りです。
① 列フィールドの「オーダー日」をクリックすると、次のようなメニューが表示されます。
② 下図のように、日付の粒度毎に同じような項目が2つ並んでいるので、緑枠の方を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/c916da21-6e29-a419-1e9a-0923179f2d1c.png)
③ 列フィールドのオーダー日が緑色に変わり、「連続」になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601070/e364eb9e-0ca2-4125-aab8-b814ab52d864.png)

ディメンジョンが「連続」になったことで、、、
- グラフが「月毎に等間隔」に並べ替えられた。
- 昇順・降順のソートボタンがグレーアウトされて、選択できなくなった。

という変化が起きました。
また、もしもとある月の売上がゼロだったとしても、間隔が詰められることはありません。

このように、日付形式のディメンジョンでは、目的に応じて、「連続」と「不連続」を切り替えながら使います。

## まとめ
ここでは、連続と不連続についてまとめました。
Tableauが自動的に分類してくれるので、意識してませんでしたが、特に日付形式のディメンジョンについては、連続と不連続の特性を理解しておく必要を感じました。

ありがとうございました。
【iOS】ワンタップで天鳳部屋建て＆共有【秒で麻雀】

こんにちは、TSMENです。


# やってみて
いくつかステップがあったものが簡略化できたのでかなり便利になりました。
友人と「ネット麻雀する？」って話題に上がった瞬間、裏でURL発行しに行けるので
やると決まったはいいものの、天鳳なのかMJなのか、雀魂なのか、、、
誰が部屋建てる、、？俺、、？お前、、？
のようなグダグダを解消できました

# 完成図
<img width="400" alt="" src="https://storage.googleapis.com/bucket-external-tsmen/qiita/tenhou1.png">

# 動作結果（LINEに共有した場合）
<img width="300" alt="" src="https://storage.googleapis.com/bucket-external-tsmen/qiita/tenhou2.jpg">

:::note warn
2023年1月11日時点で動いています。
あまりないとは思いますが、今後天鳳のサイト側の変更などで動かなくなる場合があります。悪しからず。
:::
フリーランスエンジニア向け；低稼働 x 年収アップ講座やります！

2023年あけましておめでとうございます！！
改めて今年はスキルを磨く勉強等を決意されてる方も多いと思いますが、勉強する方向に注意して欲しいです。

それは、従来IT人材としてのスキルを身につけても未来がないという事です！注意が必要です！
下手したら数年でエンジニアであってもオワコンになってしまうという話しです。

実は、この従来型ITエンジニアの人材が2030年に10万人余ると言われてます。
一方、先端IT型人材は、2030年には約80万人規模の人材不足と言われてます。
真逆です！
この80万人不足だからと言って、従来型のITエンジニアの人が安心していると正にオワコンなんです。
10万人余る人材ゾーンに入ってしまうか、80万人不足人材ゾーンに入るかで、年収が大きく変わることは想像に容易い話しです。
その他にもフリーランスエンジニアを阻む４つの大きな壁があります。

１．2030年問題とリスキング問題
２．人生１００年問題
３．年金受給年齢引き上げ
４．AIソースコード生成、ノーコード・ローコードの台頭

今後１０年以降もプログラミングのみで生きいけない？今後に向けた準備が必要です。

フリーランスエンジニアの悩み
１．楽しさ問題
・毎日忙しい
・新しい技術が勉強できない
・新しいサービスを開発できない
２．収入問題
・一つのエージェント、一つのクライアントで一社依存
・期間限定案件のため次が見つかるか不安
・将来が不安（ずっとプログラマー？）

これらの課題を解決して、儲かるフリーランスエンジニアになれば、

・毎日楽しい日々
・時間に融通がきくので勉強できる
・新しいサービス開発を選択できる
・収入が増える
・収入が安定する
・エンジニアとしてキャリアパスが見える
・ワクワク仕事できる
・沖縄や北海道等自然の生活しながら働ける

私自身は、CTOとして10社以上、技術顧問として20社以上の経験をさせてもらいました。 コロナでのリモートワークをきっかけにサラリーマンとしてのCTO職は退任しました。 退任後、様々な会社の技術顧問をやってますが、本質的にエンジニアを育てるという事を広くやりたいと思う様になりました。

先ずは気軽の説明会にご参加下さい！

https://connpass.com/event/272246/
Swift UI MVVM

## はじめに
SwiftUIを学習していくと、MVVMという言葉をよく聞くようになると思います。
今日はSwiftUI でよく使われるMVVMについて解説します。

## MVVMってなに？

**MVVM**とは、「**M**odel **V**iew **V**iew**M**odel」の略称で、開発をする際のデザインパターンの１つです。MVVM以外にもMVCなどもアプリ開発ではよく使われます。
**MVVMの特徴**としては、View Modelが**データバインディング**の役割を持っています。

:::note warn
<b>データバインディングとは？</b>
データバインディングとは、**View**と**View Model**を結び付ける仕組みのこと。
**データバインディングの特徴**は、ViewとView Modelどちらか一方で値が書き変わった場合、書き変えるたびにViewとView Model、両方の値が変更されます。
:::

そしてMVVMでは、下記の３つの要素に分けて開発を行っていきます。

:::note info
<b> Model：アプリが何をするかの内容 </b>
<b> View：ユーザーへの表示 </b>
<b> ViewModel：View と Model の橋渡し </b>
:::

## Model
Modelでは、データの（取得・登録・更新・削除）などの処理を担います。
また、データの整形などもモデルの役割になります。
## View
Viewでは、ユーザーの目に実際に触れる部分（UI）の役割を担います。データなどはModelから参照して表示します。

## ViewModel
ViewModelはViewとModelの橋渡しの役割を担います。
Viewに表示させるデータをModelから受け取ったり、逆にViewから受け取った入力をModelへと伝達させる役割があります。

## なぜMVVMを使うのか
なぜSwift UIでMVVMを採用するのかに関しては、今までMVVMが主流でそのなごりで使用されることが多いようです。よくSwift UIはMVVMとの親和性があまりよくないという記事も目にしますが、まだアプリ開発で多く採用されている印象です。またUIKitベース(Storyboard)で開発する際にはMVVMがよく使われているようです。

## さいごに
今後、MVVM以外にも色々なアーキテクチャを試してみたいと思います。
またSwiftUIは、まだまだ勉強中ですので間違っている点などありましたら教えていただけると助かります。
aws CLI help (macOS Ventura) で出力されるエラー対処法  - Could not find executable named "groff" 

# issue

環境
- macOS: `Ventura` 
- aws CLI: `2.1.28`

macOSをVenturaにアップグレード後に、aws CLIでhelp実行の際に下記のようなエラーが出力される。

```bash
$ aws s3 help

Could not find executable named "groff" 
```

# 対処方法

groffは文書整形につかうコマンドであるが、これが無いために出力されているようで、これは`groff`が`mandoc`にリプレイスされていたために発生していた。

[aws-cli issue#7400](https://github.com/aws/aws-cli/issues/7400)をみるかぎり既に、aws-cliの[mandoc対応PR](https://github.com/aws/aws-cli/pull/7413)がマージされているようなので、次のリリースで解消されているだろうとのこと。

次期バージョンがリリースまでの対処方法としては[issueコメント](https://github.com/aws/aws-cli/issues/7400#issuecomment-1326547683)に書かれているように、次のようにmacdocをgroffにsymlinkする方法が紹介されている。

```bash
sudo ln -s /usr/bin/mandoc /usr/local/bin/groff
```

上記の方法で私の環境でもエラーがなくなり、無事helpが出力できた。

```bash
aws s3 help

NAME
       s3 -

DESCRIPTION
       This section explains prominent concepts and notations in the set of
       high-level S3 commands provided.

   Path Argument Type
       Whenever using a command, at least one path argument must be specified.
       There are two types of path arguments: LocalPath and S3Uri.

       LocalPath: represents the path of a local file or directory.  It can be
       written as an absolute path or relative path.

       S3Uri: represents the location of a S3 object, prefix, or bucket.  This
       must be written in the form s3://mybucket/mykey where mybucket is the
       specified S3 bucket, mykey is the specified S3 key.  The path argument
       must begin with s3:// in order to denote that the path argument refers
       to a S3 object. Note that prefixes are separated by forward slashes.
       For example, if the S3 object myobject had the prefix myprefix, the S3
       key would be myprefix/myobject, and if the object was in the bucket
       mybucket, the S3Uri would be s3://mybucket/myprefix/myobject.
... snip ...
```

以上、一時的な対応としてご参考までに
EYEFIの仕様

昔SDカードにWiFiが入ったEYEFIというカードがあったのですが、会社が無くなって、販売されなくなりました。

またこの会社のパソコンのアプリはインターネットのサーバと連携していたため。アプリも使用できなくなり、通常のメモリーカードとしか利用できなくなりました。

現時点での推測での仕様を書いてみます。

まずSDカードはメモリとWIFIとマイコンが入っていると考えられます。

パソコンにUSB変換モジュールでSDカードを挿すと、専用のアプリと連携しました。

これはSDIOなどではなく、SDのFAT32にあるEYEFIというディレクトリにリクエストのファイルを書き込むと、レスポンスファイルが作られるという仕組みのようです。

この仕組みを解析した人がいてeyefi-configというオープンソースがあります。

この仕組でカードのユニークなKEYとMACアドレスの取得、またWiFiアクセスポイントへの接続設定を行うことができます。

WiFIにつながれば、パソコンのアプリとはそれで通信ができます。IP亜土ですはDHCPで取得します。

~~カードにはHTTPサーバがありUSB接続して取得した情報でアクセスして、ファイルのコピーなどが出来るようです。~~ どうもカードからリクエストしてPCなどでLISTENしてるポートにつながるようです。カード側が主導で動いているようです。カード側にサーバを入れると大掛かりになるので、クライアント機能のみのようです。

カードがサブネットのすべてのホストにARPのスキャンをしたり勝手にポートに接続にきたり、かなりお行儀が悪いです。

デジカメなどでEYEFI対応のものは、SDに画像データを書き込んだ時に、上記のリクエストでファイルを書き込んだ事をマイコンに伝えてファイルリストのアップデートしているのではないかと思われます。

~~また、おそらくSDカードはインターネットとは直接は接続してなくて、PCのアプリがインターネット接続したのではないかと思われます。~~

カードからapi.eye.fiにアクセスして、ファイルの送信が行われていたようです。すでにこのサーバは存在しないのでDNSでエラーになります。

mrubyでeyefi-config相当の処理を実装して、テストでアクセスポイントへの接続を試してみたのですが、うまくいきません。アクセスポイントとの相性でしょうか。。。

アクセスポイントのログです。

```
2023/01/21 08:45:06 	AUTH 	ath0: STA 00:18:56:xx:xx:xx IEEE 802.11: deassociated
2023/01/21 08:45:06 	AUTH 	ath0: STA 00:18:56:xx:xx:xx IEEE 802.11: deauthenticated due to local deauth request
2023/01/21 08:45:03 	WIRELESS 	ath0: had associated successfully : 00:18:56:xx:xx:xx 
```

何回か試していたら、つながることがありました。相性かな。。。

WiFiのAPを登録して挙動をしらべたところ、ARPして返ってきたら59278ポートにhttpで以下の仕様のリクエストを送ってくるようです。

https://code.google.com/archive/p/sceye-fi/wikis/UploadProtocol.wiki

WiFiのAPの設定があると連続して100mA以上食うみたいなので、SDカードとしてのみ使う場合にはAPの設定を消したほうがよいです。それでも定期的に処理が動くようで、その時は100mA以上使ってしまうようです。バッテリー駆動では使わないほうが賢明です。
GASでちゃんとしたHTMLパーサーが使いたかったのでライブラリにした

# HTMLパーサーが欲しい
GASでスクレイピングすると誰もが思うこと、「HTMLパーサーが…欲しい…!!」
正規表現でもなんとかなるといえばなるけど柔軟性に欠けるし保守性も低い。
よく紹介されるのはParserだけど個人的には「コレ使うなら正規表現でも変わらなくね？」と思ってしまうし、同一タグのネストを解決するのが大変。

ならnodejsから移植すれば良いじゃない。
というわけでライブラリを作りました。下記IDをライブラリ検索で利用できます。
スクリプトID: `1JTLPVXGW6Pq4zSAV5ED9XrWOPydVywumQZSOWN7l6KJ0UtWxtX3RbYO6`
GitHub: https://github.com/kairi003/gas-html-parser

# 使い方
本ライブラリはほぼ[node-html-parser](https://www.npmjs.com/package/node-html-parser)そのままです。作ったとか言えないレベル。
細かい利用方法は本家のドキュメントを確認していただくとして、以下のように使えます。
```js
const html = `<body>
  <ul id="fruits">
    <li class="apple">Apple</li>
    <li class="orange">Orange</li>
    <li class="pear">Pear</li>
  </ul>
</body>`;
const dom = HtmlParser.parse(html);
console.log(dom.querySelector('#id .pear').textContent);
```
ちなみになんでnode-html-parserなのかというとAPIがブラウザDOMに近い(同じではない)のと軽いからです。jqueryが好きならcheerioのほうがいいかも。jsdomは無理そうでした。

# 作り方
GitHub: https://github.com/kairi003/gas-html-parser

node-html-parserをimportするだけのindex.jsをwebpackでバンドルしてます。
またGASライブラリとして使う都合上、ライブラリのグローバルとnode-html-parserのグローバルを一致させたかったので`globalThis`に`Object.assign`してます。
```js
Object.assign(globalThis, require('node-html-parser'));
```
普通に使う分には以下のようにexportしてwebpackの設定で`output.library: "HtmlParser"`などを指定したほうが良いでしょう。
```js
module.exports(require('node-html-parser'));
```

ちなみにwebpackでちょっと困ったこととして、developmentモードでは動くのにproductionでは動かないという自体に遭遇しました。
これはminimize時にオブジェクトキーに非ASCII文字がクォーテーション無しに生成されて一部がSyntaxErrorになっていたこと (`{ℵ: "aleph",...}`←こんなの) が原因で、次のようにterserのオプションを指定することで解決しました。
```js
module.exports = {
    ...,
    optimization: {
        minimize: true,
        minimizer: [
          new TerserPlugin({
            terserOptions: { output: { ascii_only: true } }
          })
        ],
    }
}
```

# 感想
割と手軽にできて驚きでした。なんで普及してないんだろう。
CLIP STUDIO PAINTでカラーセットの並び順変更

# 概要

例えば下記の『1』を一つ下に移動したり、など。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b9def688-ad8b-c270-dc92-48e59a404001.png)

# やり方

Ctrl押しながらドラッグで移動できる。

 ↓ 移動中。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0faee8b7-ae7b-2d5c-667c-5ae39d4d5dec.png)

 ↓ 移動後。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/36a84b0a-d23f-1b0e-2026-ccf327ff44b0.png)

# 参考サイトさん

https://howto.clip-studio.com/library/page/view/clipgeneral_other_01_003#:~:text=%5B%E3%82%AB%E3%83%A9%E3%83%BC%E3%82%BB%E3%83%83%E3%83%88%5D%E3%83%91%E3%83%AC%E3%83%83%E3%83%88%E3%81%AE%E4%B8%8A,%E4%BD%8D%E7%BD%AE%E3%82%92%E7%A7%BB%E5%8B%95%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

# バージョン

Windows 10 Home 22H2 19045.2486
CLIP STUDIO PAINT PRO（64ビット） 1.12.3 202206201552
XCTContext.runActivity(named:)でasync/awaitのテストに対応できなかった

# 環境
Xcode14.1

# やりたかったこと
XCTContext.runActivityを使ってユニットテストを構造化したかった。
使い方は下記を参考にした。
[XCTContext.runActivity(named:)を使ってユニットテストを構造化する](https://qiita.com/peka2/items/ee14ad27edfd07c843c5)

[XCTContext.runActivityのAppleのドキュメント](https://developer.apple.com/documentation/xctest/xctcontext/2923506-runactivity)

# 詰まった点
asyncを使っている処理をテストする場合には、ユニットテストのメソッドにasyncをつけることでテストができた。

```swift
func test() async {
    // 何かテストしたいこと (awaitする)
}
```

しかしXCTContext.runActivityを内部で利用すると下記のエラーが発生してしまった。
```swift
func test() async {
    XCTContext.runActivity(named: "test") { _ in
        // 何かテストしたいこと (awaitする)
    }
}
```

> Current context must not be nil


# 対応
調べても対応策がわからなかったので、諦めてメソッドごとに構造を切り分けることにした。
```swift
func test_xxxが0より大きい場合() async {}

func test_xxxが0以下の場合() async {}
```

メソッド名に条件を日本語で書くことで失敗したときに一覧しやすくできた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570572/51ccdd24-d972-3093-e820-0f4debd8da1f.png)


# 追記
下記にて対応が可能なようでした。extentionで拡張するという発想がありませんでした。勉強になります！

https://github.com/koher/swift-async-test-experiment/blob/main/Tests/AsyncTestExperimentTests/XCTContext%2BrunActivityAsync.swift
【AWSメモ】現場で使うSSMでの接続方法とコマンド

EC2を起動
起動するインスタンスにチェックを入れてインスタンスの状態>インスタンスを開始を押下する。

SSMでの接続
URLにアクセスして、SSMのセッションマネージャーを表示する。
「セッションを開始する」ボタンを押下し、「セッションの開始」画面に遷移する。
先ほど起動したインスタンスを選択して、「セッションを開始する」ボタンを押下する。
以下のように表示されれば、接続完了。


### 接続用ユーザー作成
初めてEC2に接続する場合は、自分専用のユーザーを作成する。

```
$ sudo su　　　　　　　　　　　　　　　　　　　rootユーザに変更
# useradd <ユーザ名>                           ユーザー追加
# usermod -g users <ユーザ名>                  追加したユーザーを設定済みのgroupに設定
# passwd <ユーザ名>                            ユーザーのパスワードを設定（接続時に使用）
```

### 接続用ユーザー作成後
以下のコマンドでログインする。
```
sh-4.2$ sudo su --login <作業ユーザ>
例
sh-4.2$ sudo su --login tanaka
Last login: ～～
[tanaka@ip-111-11-11-1 ~]$
```

EC2の停止
EC2は従量課金制のサービスのため、起動し続けると料金が発生してしまう。
よって、EC2インスタンスの接続が不要となった場合はEC2インスタンスを停止しておく。
停止するインスタンスにチェックを入れてインスタンスの状態>インスタンスを停止を押下する。
※ 「インスタンスを終了」を押下してしまうと、インスタンスが削除されてしまうので注意

## DBコンソール利用手順
1. ソースのパスに移動
1. rails dbコマンドを実行
1. パスワードを入力

**パスワードについて**
```
AWSコンソール.System Manager→パラメータストア→マイパラメータに下記を入力
```

```
[tanaka@ip-111-11-11-1 ~]$ cd sampleblog
[tanaka@ip-111-11-11-1 sampleblog]$ ./.set-env bin/rails db
Password:
```

## Railsコンソール利用手順
1. ソースのパスに移動
1. rails cコマンドを実行(データを更新しない場合は `--sandbox` オプションを追加。更新しない場合は付けない）

```
[tanaka@ip-111-11-11-1 ~]$ cd sampleblog
[tanaka@ip-111-11-11-1 sampleblog]$ ./.set-env bin/rails console --sandbox

```
【JS】よく使うバリデーションまとめ

## はじめに
jsのバリデーションをまとめました。
随時思いついたら追加していこうと思います。


## 半角英数字のみ

```js
if (!value.match(/^[A-Za-z0-9]*$/)) {
         error = '半角英数字のみで入力してください。'
 }     
```


## 全角カタカナのみ
```js
if (!value.match(/^[ァ-ヶー]+$/)) {
         error = '全角カタカナで入力してください'
 }     
```


## 半角英字と数字 両方含む8桁以上16桁以下

```js
if (value.length > 16 || value.length < 8 || !/^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,16}$/.test(value)) {
                    error = '半角英数8桁以上16桁以下で入力してください。'
 }     
```


## 英数字と記号 必ず両方含まなければならない

```js
if (!value.match(/^(?=.*?[a-z\d])(?=.*?[!-\/:-@[-`{-~])[!-~]{8,16}$/)) {
                    error = '記号を含んだ半角英数8桁以上16桁以下で入力してください。'
 }     
```

## 半角英数記号全て含む8桁以上16桁以下

```js
if (value.length > 16 || value.length < 8 || !/^(?=.*?[a-z])(?=.*?[\d])(?=.*?[!-\/:-@[-`{-~])[!-~]{8,16}$/.test(value)) {
                    error = '半角英数記号8桁以上16桁以下で入力してください。'
 }     
```

## 漢字、ひらがな、カタカナ、全角英字、全角数値のいずれか

```js
if (!(value.match(/^[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]+$/) || 
 value.match(/[！-\uff5e]/g)) {
         error = '漢字、ひらがな、カタカナ、全角英字、全角数値のいずれかを入力してください'
 }     
```


## 数値の桁数（11桁以内）

```js
if  (!value.match(/^\d{10}$|^\d{11}$/)) {
         error = '半角数字11桁以内で入力してください。'
 }
```

## メールアドレスの形式のみ
```js
if (!value.match(/.+@.+\..+/)) {
  error = 'メールアドレスの形式が間違っています。'
}
```

## URLの形式のみ

```js
if (!value.match(/^(http|https):\/\//i)) {
         error = 'URLの形式が間違っています。'
 }     
```
ymlとは（使い方も少し）

# 疑問
* .ymlとは？
日本語に翻訳に使ったファイル。
初めて使った一応触りだけでも理解をしておきたい。

# YAML【YAML Ain’t Markup Language】YMLファイル / .ymlファイル
* YAMLとは、```何らかの構造を持つ```データ集合を簡素な```文字列の並びとして表記するための記法```を定めた```データ形式の一つ```。
```ソフトウェアの設定ファイルの記述や異なるソフトウェア間のデータ交換などでよく用いられる。```

# 出典
https://e-words.jp/w/YAML.html#:~:text=YAML%E3%80%90YAML%20Ain't%20Markup,%E3%81%AA%E3%81%A9%E3%81%A7%E3%82%88%E3%81%8F%E7%94%A8%E3%81%84%E3%82%89%E3%82%8C%E3%82%8B%E3%80%82

* * ファイルの書き方ルールだよ
  * point構造化されたデータを表現できるよ
  * point「YAML Ain't a Markup Language」の略だよ
* YAML（読：ヤムル、ヤメル）とは
    構造化されたデータを表現するのに便利な、ファイルの書き方ルール（のひとつ）です。

# 出典
https://wa3.i-3-i.info/word13801.html

* YAML (YAML Ain’t Markup Language) とは、わかりやすいデータ シリアライズ (serialize) 言語です。設定ファイルの記述に使用されることが多く、あらゆるプログラミング言語に対応しています。
YAML では、プログラマーにとっての使いやすさが重視されています。 別のデータ シリアライズ言語である ```JSON の完全な上位版```であり、 完全という言葉のとおり、JSON でできることだけでなくそれ以上のことも可能です。 大きな違いとして、```YAML では改行とインデントが明確な意味を持ちます```が、角カッコと波カッコを使用する JSON はそうではありません。
YAML はその形式ゆえに設定の記述に適しているため、CircleCI の設定ファイルに採用されています。

### 出典
https://circleci.com/ja/blog/what-is-yaml-a-beginner-s-guide/#:~:text=YAML%20%E3%81%A8%E3%81%AF%EF%BC%9F,%E6%8E%A1%E7%94%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

### 気づき
構造化されたデータを表現できるデータ
ソフトウェアの設定ファイルの記述や異なるソフトウェア間のデータ交換でよく用いられる。のか
確かにファル内は一定の構造があったな。便利なファイルなのか。
都合の悪いデータもあるんだな。

# YAMLの書き方
まだYAMLの使うかわからないのでリンクだけ

# 出典
```キャメル ヤムル```で検索

https://magazine.rubyist.net/articles/0009/0009-YAML.html

https://circleci.com/ja/blog/what-is-yaml-a-beginner-s-guide/#:~:text=%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82-,YAML%20%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9,-YAML%20%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE