OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsによるPython入門 #08: 制御文

# はじめに

今回は制御文を解説します。

# YouTube動画

[]()

# if文

条件を分岐するには、if 文を使用します。次のような構文です。
ブロックを表現するのは、インデント(空白かタブによるスペース)を使用します。
ブロックの中身が複数行存在する場合、インデントの個数(スペースの個数)を統一します。
通常、4個のスペースが使用されます。

```
if 条件式:
    ブロック
elif 条件式:
    ブロック
else:
    ブロック
```

具体例です。

```py
>>> a = 10
>>> if a == 10:
...     print("OK")
...
OK
```

bool のところでも見ましたが、0 や空は bool で評価すると、False になります。

```py
>>> l = []
>>> if l:
...     print("OK")
... else:
...     print("NG")
...
NG
```

## 論理演算子と比較演算子

複数の条件の場合、and, or, not の論理演算子を使用します。
また、in 演算子で含むかどうかを確認出来ます。

```py
>>> a, b = 10, 20
>>> if a == 10 and b == 20:  # a == 10 かつ b == 20
...     print("OK")
...
OK
>>> if a == 5 or b == 20:  # a == 5 もしくは b == 20
...     print("OK")
...
OK
>>> if 1 < a < 15:  # 1 < a かつ a < 15
...     print("OK")
...
OK
>>> if not (a == 20):  # 否定
...     print("OK")
...
OK
>>> if 10 in [a, b]:  # [a, b] は、10 を含む
...     print("OK")
...
OK
```

## 3項演算子

次の構文で、3項演算子が使用出来ます。
条件が成立すると a が返り、成立しないと b が返ります。

```
a if 条件式 else b
```

具体例です。

```py
>>> a = 10
>>> "OK" if a == 10 else "NG"
'OK'
```

## 代入式

Python 3.8以降で、以下の構文で、代入式(セイウチ演算子)が使用出来ます。
代入は文なので、式の中で使用出来ませんが、式の中で使用出来るようにしたのが代入式です。

```
変数 := 式
```

具体例です。
演算子の優先順位には注意が必要です。

```py
>>> if (a := 10) < 20:
...     print("OK")
...
OK
>>> a
10
>>> if a := 10 < 20:  # 10 < 20 が優先
...     print('OK')
...
OK
>>> a
True
```

## 同一判定と同値判定

インスタンスの値が一致する場合、「同値」と言い、== で判定出来ます。
インスタンスのアドレスが一致する場合、「同一」と言い、is で判定出来ます。
但し、小さい整数値や短い文字列リテラルなどはオブジェクトがキャッシュされて同一のものが使用されますので、注意が必要です。

```py
>>> a = "abc"
>>> b = "abcdefg"[:3]
>>> a == b  # 同値判定
True
>>> a is b  # 同一判定
False
>>> id(a), id(b)  # ID が異なる
(140715566436128, 2813239768624)
>>> b = "abc"  # 文字列 "abc" はキャッシュされている
>>> a is b
True
>>> a, b = 1, 1
>>> a == b
True
>>> a is b
True
>>> a, b = 2**1000, 2**1000
>>> a == b
True
>>> a is b
False
```

# for文

for 文を使用すると、繰り返し処理が出来ます。
break でループを中断、continue で次のループに飛ぶことが出来ます。
構文は以下の通りです。

```
for 変数 in イテラブル:
    ブロック
```

具体例を見てみます。

```py
>>> l = [1, 2, 3]
>>> for n in l:
...     print(n)
...
1
2
3
>>> for n in range(10):
...     if n % 2 == 0:  # n が偶数なら次のループへ
...         continue
...     if n >= 8:  # n が 8 以上ならループを抜ける
...         break
...     print(n)
...
1
3
5
7
```

Python では、for 文に else を使用する事が出来ますが、使用頻度は低いと思いますので省略します。

# while文

while 文を使うと、条件式が True の間ループします。
break でループを中断、continue で次のループに飛ぶことが出来ます。
構文は以下の通りです。

```
while 条件式:
    ブロック
```

具体例を見てみます。

```py
>>> l = [4, 5, 6]
>>> while l:  # 空になるまでループ
...     l.pop()
...
6
5
4
>>> cnt = 0
>>> while True:
...     cnt += 1
...     if cnt >= 5:  # cnt が 5 以上になったらループを抜ける
...         break
...     elif cnt == 2:  # cnt が 2 なら次のループへ
...         continue
...     print(cnt)
...
1
3
4
```

Python では、while 文に else を使用する事が出来ますが、使用頻度は低いと思いますので省略します。

# おわりに

以上、制御文に関して解説しました。
次回は、関数に関して解説します。
【初心者向け】cakePHPって何？

# 目次
[1.はじめに](#1-はじめに)
[2.PHPとは](#2-phpとは)
[3.cakePHPとは](#3-cakephpとは)
[4.おわりに](#4-おわりに)

# 1. はじめに
- 軽い自己紹介
    - 2021年の4月にほぼ未経験でIT企業に入社した新卒2年目
    - 研修終了後は某業界向けの基幹システム開発でcakePHPを使用
- 本記事記載のきっかけ
    - cakePHPそのものについてあまり詳しくないと思った
    - cakePHPについて、現状の認識の整理をしたい
- 読んでほしい人
    - cakePHPに興味がある初心者の方
    - プログラミンに興味はあるけど、どのような言語をすれば分からないという方

# 2. PHPとは
- PHPとは
    - Webページを作成する為によく用いられるサーバーサイドスクリプト
        - サーバーサイドスクリプト：Webブラウザで読み込まれる前に、Webサーバーで実行されるプログラミング言語
    - 「ウェブページをWeb 開発者が速やかに作成できるようにすることを主な目標」として作られた
- 長所
    - MySQLなどのデータベースとの連携
    - プログラム実行がWebブラウザの違いに影響されない
    - コードを検証モードなどで盗み見されない
    - 端末側で不正プログラムを実行できない
- 短所
    - ユーザーの操作に応じたリアルタイムな処理には向かない
    - サーバー攻撃への対策が必要
- よく使われる場面
    - ブログやSNS、会員管理などデータベースへのデータ追加や値検索・更新処理が頻繁に行われるサイト

# 3. cakePHPとは
- cakePHPとは
    - PHP開発の為のフレームワークでオープンソースのソフトウェア
    - https://cakephp.org/jp にて公開されている
- 特徴
    - 設定より規約
        - 設定ファイルに特定の情報を記載するのではなく、クラス名、ファイル名、DB のテーブル名などをcakePHPによって決められた規約に則って記載
        - 規約に従って名前を付けることで自動で機能が認識される
        - 規約があることで、設定ファイルに記載する情報が少なくて済む
    - MVCアーキテクチャ
        - cakePHPでは、Model(データ管理)、View(画面表示)、Controller(プログラム制御)の3つにプログラムを分類するMVCアーキテクチャを採用
        - 役割が明確に分けられていることで、分業して作業を進めることができる
        - 各プログラムが独立していることで、アプリケーションのバージョンアップなど仕様変更に対応しやすい
    - bake機能
        - bake機能とはアプリケーションを開発の為のプログラムの雛形のこと
        - bake機能があることで開発を迅速に進めることができる
    - 情報源が豊富
        - 公式が紹介している情報源だけでも下記の種類があり、悩んだ時の解決法が見つかりやすい
            - 公式CakePHPウェブサイト(https://cakephp.org/)
            - CookBook(https://book.cakephp.org/)
            - Bakery(https://bakery.cakephp.org/)
            - API(https://api.cakephp.org/)
            - テストケース(コード内：tests/TestCase/)
            - IRC チャンネル(irc.freenode.net 内にてcakePHPタグを付ける)
            - 公式CakePHPフォーラム(https://discourse.cakephp.org/)
            - Stackoverflow(https://stackoverflow.com/questions/tagged/cakephp/ にてcakePHPタグを付ける)
            - 確実に日本語で情報を得たい場合
                - https://cakesf.slack.com/messages/japanese/
                - https://www.facebook.com/groups/304490963004377/

# 4. おわりに
今回、cakePHPについて改めて調べてみて、知らなかった情報などもあり、自分にとって良い機会になりました。
(間違えている部分などあれば、ご教示いただけますと幸いです。)

私自身cakePHPでプログラムを組むことは楽しいと思っているので、今後もcakePHPユーザーが増えると嬉しいです。


# 参考文献
https://www.php.net/

https://cakephp.org/

↓こちらの記事ではインストール方法なども載っていたので、cakePHPに更に興味を持った方はぜひ見てください。

https://proengineer.internous.co.jp/content/columnfeature/17783

掌田　津屋野(2017).『PHPフレームワーク CakePHP3入門』.株式会社　秀和システム

大重　美幸(2016).『詳細！ PHP7+MySQL 入門ノート』.株式会社　ソーテック社
Laravel Debugbarについて


Laravel Debugbarとは、デバッグを便利にしてくれるパッケージです。
渡されているパラメータやクエリ文等も確認もできるため便利だったりします。
簡単に導入でき設定もほとんど必要なく、既に実装していたとしても影響を与えるようなこともなく利用できます。

簡単に導入から設定についての説明をまとめてます。



# 導入
インストールするには以下のコマンドを実行します。

```
composer require --dev barryvdh/laravel-debugbar
```

インストール後```APP_DEBUG```の値がtrueの場合、ページ上に画像のようなものが表示されます。
![laravel_debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/b54ea5d4-480c-3c4c-5c12-56554b0de8de.png)


# DEBUGの表示非表示
上記で「```APP_DEBUG```の値がtrueの場合」と記載しましたが、こちらは「.env」ファイル内に記載されています。
そのためこちらを```APP_DEBUG=false```とすることでDEBUGを非表示にすることができます。



# 設定
デフォルトでいくつかのタブが表示されていますが、追加で設定することで他の情報も表示させることができます。
設定を変更したい場合は、下記のコマンドを実行し設定ファイルである```config/debugbar.php```を生成します。

```
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
```

### config/debugbar.phpの編集
生成された```config/debugbar.php```内の```controllers```にて
true/falseを設定することで取得する情報を選択ができます。

```config/debugbar.php
 'collectors' => [
    'phpinfo'         => true,  // Php version
    'messages'        => true,  // Messages
    'time'            => true,  // Time Datalogger
    'memory'          => true,  // Memory usage
    'exceptions'      => true,  // Exception displayer
    'log'             => true,  // Logs from Monolog (merged in messages if enabled)
    'db'              => true,  // Show database (PDO) queries and bindings
    'views'           => true,  // Views with  their data
    'route'           => true,  // Current route information
    'auth'            => false, // Display Laravel authentication status
    'gate'            => true,  // Display Laravel Gate checks
    'session'         => true,  // Display session data
    'symfony_request' => true,  // Only one can be enabled..
    'mail'            => true,  // Catch mail messages
    'laravel'         => true,  // Laravel version and environment
    'events'          => true,  // All events fired
    'default_request' => false, // Regular or special Symfony request logger
    'logs'            => false, // Add the latest log messages
    'files'           => false, // Show the included files
    'config'          => false, // Display config settings
    'cache'           => false, // Display cache events
    'models'          => true,  // Display models
    'livewire'        => true,  // Display Livewire (when available)
],
```

##　キャッシュ削除
上記の操作で画面上で反映されない場合は、以下のコマンドを実行することでキャッシュが削除され更新さされるかと思いますので試してください。
```
php artisan cache:clear
php artisan config:clear
```
【書評】『検索システム-開発者のための開発改善ガイドブック-』 感想

## どんな本？
2022年に出た検索システムの本。
今まで情報検索については英語で書かれた本や難解な本、昔に書かれた本が多いような印象だった。
そういった意味では、日本語で新しく検索を学ぶ際のデファクトスタンダードになるような本が出たなぁという印象。
「**検索やりたいならとりあえずこれ読んでおこう**」と思えるような本だと思った。

https://www.lambdanote.com/products/ir-system



## 構成
2部構成になっている。

- **I部　検索エンジンの基礎**
    - 1-6章
- **Ⅱ部　より高度な検索システムに向けて**
    - 7-12章

   

## I部　検索エンジンの基礎

検索エンジンの仕組みやテキスト解析、ポスティングリストの操作など、検索システムを理解する上で欠かせない内容が一通り記述されている。
「**検索エンジニアではないけど、ドメイン知識をして検索について知りたい！**」という人は1-6章までをさっと読むだけで大部分を理解できるのではないかなと思った。

比較的丁寧にわかりやすく記述されているので、さくさく読むことができた。

## Ⅱ部　より高度な検索システムに向けて

やや発展的な内容で、章によっては事前知識がないなかなか読むのが大変に感じた。
というのもこの本には複数の著者がおり、それぞれが得意分野を活かしつつ章ごとに分担が分かれている。
そのため、章によって読み応えや雰囲気、得られる内容が異なるように感じた。

自分の場合は章が変わることに「**この章では何をテーマにしていて、何が得られるのかな？**」と脳をスイッチして読む必要があった。

一方で複数の視点から専門家による解説がされており、多様な知識を得られる点はとてもよかった。


少し具体的に言うと、12章では検索対象となるドキュメントをどう並べ替えるか？という個別の問題にフォーカスした「ランキング」について述べられている一方、10章、11章では「そもそもいい検索とは何か？」という問いから始まり、さまざまな切り口から検索者を支援する方法について述べられている。


特に11章は専門的な知識が必要とされることが多く、かなり読むのが大変だった。
（競プロでよく使われるDPが検索システムでも使われていると知って、「へぇ〜」と思った）
この辺りを本当に理解したければ参考資料をあたるの良いのかもしれない。

Ⅱ部は検索エンジニアでなければ必ずしも全部通読する必要はなく、自分の興味や勉強したい内容に併せて読んでいくのがいいんじゃないかなーと思った。


## 感想

自分は検索エンジニアではないものの、検索システムのドメイン知識を身につける目的においては読んでよかったと思える本だった。

おわり
WebSecurityConfigurerAdapterがimportできなくなっていた

## 環境
+ Windows10
+ Intelij idea
+ Maven
+ Spring Boot 3.0.2
+ Spring Security 6.0.1
## 概要
この[記事](https://qiita.com/t-yama-3/items/a538d47b8f0a27639d23)を参考にユーザー認証を試していたところ、__import__ ができませんでした。（今回は1～3-2まで）Mavenのpom.xmlなどを確認しましたが、特に問題が見つからなかったため、いろいろ探したところspring securityのアップデートの結果、__WebSecurityConfigurerAdapter__ は削除されてしまったようです。詳しくはこの[記事](https://qiita.com/suke_masa/items/908805dd45df08ba28d8)を参照してください。
いろいろと見ましたが、ユーザー認証を行う件に関して扱っているものは古いものが多く新しいバージョンに関しては少なかったです。

結果公式の記事に代替案が載っていました。

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

## 現在のversionでユーザー認証を実現したい
```java:公式-In-Memory Authentication
@Configuration
public class SecurityConfiguration {
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}
```
　公式からコピペで一応は、似たようなものを実装可能です。しかし __withDefaultPasswordEncoder()__ メソッドが非推奨でした。この[記事](https://ja.stackoverflow.com/questions/67477/spring-security%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E7%99%BB%E9%8C%B2%E6%99%82%E3%81%AE%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AE%E6%9A%97%E5%8F%B7%E5%8C%96%E3%81%AE%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AA%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B)にあることをまとめると、__withDefaultPasswordEncoder()__ はもともと __デモ__ 用かつそもそも __user__ クラス自体もデモ用で実際には利用されない。ほかにも直接の理由として、パスワードを __ソースコードに直書きはまずいよね__ という話みたいです。ほかにも色々と有益情報がありそうなのですが、初学者には難しい話で、理解まで至りませんでした。
　そこで[元から参考にしている記事](https://qiita.com/t-yama-3/items/a538d47b8f0a27639d23)に、添うような改良を加えたところこのようになりました。
```java:公式-改良版
package com.sample.koinu.mysqltest;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration //バージョンが上がったことで必須になったようです。
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User
                .withUsername("user")
                .password(passwordEncoder().encode("1234"))
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
}

```
　気が付きにくい点としては、__username->withUsename__ に変化しているところです。今の状態ではデータベースを利用していないので、結局はソースコードに直書きのままになってしまっています。
## 終わりに
　この後もユーザー認証に関して、バージョンの違いによる弊害がありました。このまま書き続けると、量がすごいことになっってしまう未来しかないので、いったん切らせていただきます。一つずつ解決していっているのもあって、次の更新は少し時間が掛かるかもしれないです。おすすめのサイトなどがあったら教えていただけると幸いです。
【Laravel】変数名は単数形と複数系を使い分ける

# プログラムを書く時、変数の名前をどうしようか迷う
例えば、DBから１件だけ取得して値を代入する時はどういう変数名にしようかとか。

# 結論
単数形->複数形への変換は`Str::plural`
複数形->単数形への変換は`Str::singular`
を使う
※私はこれらをコードの中で使うというより、事前にtinkerで確認することが多いです。

# 例えば、こんな時

- DBから取得した「スタッフ」（複数存在）を変数に代入する
  - tinkerで`Str::plural('staff')`を実行すれば出てきますが、「staffs」という複数形は無いです。従って複数形でも変数名は「staff」になります。
```php
// 単数形はstaff
$staff = Staff::find(1);

// 複数でもstaff
$staff = Staff::all();
```

- 実は複数形な「media」
    - tinkerで`Str::singular('media')`を実行してみましょう。あら不思議。実は「media」は複数系で、単数形の場合は「medium」なのでした。メディアって有名な単語なので単数でも複数でもこちらを使ってしまいそうです。
```php
// Modelクラス名が既にアウト
$media = Media::find(1);

// mediasという複数形は無い。(mediaが既に複数形を指している)
$medias = Media::all();

// こうするのが意味としては正しい。勿論、開発現場によってルールがあるとおもうので絶対正解というわけではないが。
$medium = Medium::find(1);
$media = Medium::all();
```


可読性あるコードを書くためにも、変数名には気を付けましょう。
Firebaseでproduction/staging環境を切り替えた

## 方針
Firebaseのプロジェクトをproduction/staging用でそれぞれ作る。
1つのプロジェクトの中に複数の環境に向けたFirestoreやAuthenticationは作れないため。

## やってみる
iOSで使っていたのでこのあたりの記事を参考にやりました。
[Firebaseを本番環境と開発環境で切り替えてみた（iOS）](https://qiita.com/ken_sasaki2/items/6f462d129a67bdd30a7e)

## 発生した問題
Google, Twitterのログインを入れているのだが、両ログインでエラーが出た。
- [URL Schemesの設定](https://firebase.google.com/docs/auth/ios/google-signin#2_implement_google_sign-in)を忘れていた。(Google, Twitterともに必要)
- Twitter Developerで環境ごとにappを登録するのを忘れていた

<img src ="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624810/840ccf57-530d-9134-e81a-d86e962cbe60.png" width=600>

https://developer.twitter.com/en/developer-terms/policy
>As a single exception to these rules, you may create and use a maximum of 3 applications for development, staging, and production instances of the same service. These apps must be registered to a single account, and should be clearly identified (in the name and description) as dev, staging, and prod instances of a single service. You may not use development or staging applications for production purposes.

Twitter Developerでは３環境まで登録することができます。

- そしてその後Twitter DeveloperでUser authentication settingsをsetするのも忘れていた


解決。
Pyvista と jupyter lab を組み合わせる  (ipykernel で登録した venv で使用)

## 状況

`pyvista 0.38` で 3d プロットを jupyter lab 内に表示する[エンジンが `trame` に変更され](https://docs.pyvista.org/user-guide/jupyter/trame.html#trame-jupyter)、これまでのバックエンドは非推奨になりました。(2023年2月2日) 
これをインストールして動作を試しました。同じ仮想環境内で jupyter lab を起動している場合は、pyvista の指示通りのインストール法で問題なく動作しました。

`pip install 'jupyterlab>=3' ipywidgets 'pyvista[all,trame]'`

次に、jupyter lab 環境は一つだけ作って、他の venv からも ipykernel を登録する、という運用で動作するかを調べると、これまで使っていた jupyter lab 環境そのままでは、`pyvista` のプロットがうまく表示されませんでした。

例えば、`Click to show javascript error` と表示されたり、

![image-javascript_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38979/f3a73746-fe6a-cd58-31a2-a468256df3ac.png)

 `Error displaying widget: model not found` と表示されたりしました。

![error_displaying_widget.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38979/2bf8574f-dda2-1b9d-0aaf-aa509112b2f6.png)

## 動作環境
Windows11 Home (22H2) 
Python 3.10.9
pyvista 0.38.1 他は、上記 pip install でインストールされたライブラリーを使用。

## 解決策

フレッシュな venv 環境をいくつか作成して切り分けを試みました。

今のバージョンでは、jupyter lab 側も、kernel 側も共にマニュアル記載のインストール `pip install 'pyvista[all,trame]'`を行う必要があります。こうすれば、`ipykernel` で登録した kernel を使って pyvista の plot を描画させることはできるようです。
このとき、オプションの `all` が効いて、`Panel` や `pythreejs` も入ってしまいますが、これをアンインストールしてみると、うまく動作しませんでした。

また、いずれにしてもノートブックの評価前は、`Error displaying widget: model not found` という表示が出ていました。

ここだけ見ると、そもそも jupyter lab の venv を分ける必要があるのか、という疑問も生じますが、pyvista kernel の側で、さらに目的に応じていろいろなパッケージを入れていくことを考えると、jupyter lab 用の venv は可能な範囲で手を加えないで残しておくというのも、一つのやり方だと思います。
【VBA】Sub 作業フォルダにある部分一致の作業ファイルを指定して開きたい()

Sub 作業フォルダにある部分一致の作業ファイルを指定して開きたい()

'任意の作業フォルダ内の各人別の指定形式のファイルを都度操作したいな。。。。
'複数のプロシージャでも下記の作業ファイルを仕様するならばCallの括りのところに入れるか、Publicで入れるか？？？



'自PCのDocument内に\作業フォルダを作成し、そこに対象ファイル※ここでは”*作業ファイル.xls?”を格納します
'作業フォルダパスを変数にします。
Dim 作業フォルダパス As String
作業フォルダパス = "C:\Users\user\Documents\作業フォルダ\"
'ここはお尻の/を忘れがちなので要注意！


'作業フォルダ内の任意のファイル名を取得して変数にします。
'ちなみに*がワイルドカード、?はAnyの1文字。この部分はいろいろ。
Dim ファイル名 As String
ファイル名 = Dir(作業フォルダパス & "*作業ファイル.xls?")


'作業ファイルを開きます。
Workbooks.Open Filename:=作業フォルダパス & ファイル名

'作業ファイル（ワークブック）を変数にしてます。Workbookの場合は「Set」します。
'開いたファイルを以降に使えるようにします。
Set 作業ファイル = ActiveWorkbook

作業ファイル.Activate

End sub
【VBA】作成したコードをChatGPTに評価してもらったあと、オープンソースとして取り込まれていました。貢献できている感じが楽しい。

流行りのChatGPT。
内職しながら活用してみようと考えて、作ったコードを評価してもらいました。
なかなか納得な答えを返してくれました。
おもしろいですね。これ。
癖になりそう。


～答え～

このVBAコードは、作業フォルダ内の任意の「作業ファイル.xls」または「作業ファイル.xlsx」を開くものですね。まず、作業フォルダパスを指定します。次に、作業フォルダ内の「*作業ファイル.xls?」という名前のファイル名を取得し、変数「ファイル名」に格納します。最後に、作業フォルダパスとファイル名を結合して作業ファイルを開き、「作業ファイル」という変数に格納します。

このコードは問題ないと思いますが、念のために以下のポイントに注意することをお勧めします。

作業フォルダ内に「作業ファイル.xls」または「作業ファイル.xlsx」が存在するか確認します。
作業ファイルが開けるかどうかを確認します。
作業ファイルがすでに開かれていないか確認します。




～以下質問～


Sub 作業フォルダにある部分一致の作業ファイルを指定して開きたい()

'任意の作業フォルダ内の各人別の指定形式のファイルを都度操作したいな。。。。
'複数のプロシージャでも下記の作業ファイルを仕様するならばCallの括りのところに入れるか、Publicで入れるか？？？



'自PCのDocument内に\作業フォルダを作成し、そこに対象ファイル※ここでは”*作業ファイル.xls?”を格納します
'作業フォルダパスを変数にします。
Dim 作業フォルダパス As String
作業フォルダパス = "C:\Users\user\Documents\作業フォルダ\"
'ここはお尻の/を忘れがちなので要注意！

'作業フォルダ内の任意のファイル名を取得して変数にします。
'ちなみに*がワイルドカード、?はAnyの1文字。この部分はいろいろ。
Dim ファイル名 As String
ファイル名 = Dir(作業フォルダパス & "*作業ファイル.xls?")


'作業ファイルを開きます。
Workbooks.Open Filename:=作業フォルダパス & ファイル名

'作業ファイル（ワークブック）を変数にしてます。Workbookの場合は「Set」します。
'開いたファイルを以降に使えるようにします。
Set 作業ファイル = ActiveWorkbook

作業ファイル.Activate

End sub


～～


そのあと、コードをまるまる教えてくれるのかな？と思って
「作業フォルダにある部分一致の作業ファイルを指定して開きたい」
と質問。

そうすると以下のような回答で、ほぼ一致というかさっきの内容を取り込んだ内容が答えに。
こうやって情報を蓄積していくんですね。目に見えるのでおもしろいですね。

～答え～

VBAで作業フォルダにある部分一致の作業ファイルを指定して開くには、次のようなコードを作成することができます。

vbnet
Copy code
'作業フォルダのパスを設定する
Dim strPath As String
strPath = "C:\Users\user\Documents\作業フォルダ\"

'作業フォルダ内の部分一致のファイル名を取得する
Dim strFile As String
strFile = Dir(strPath & "*作業ファイル*.xls?")

'部分一致の作業ファイルを開く
Workbooks.Open Filename:=strPath & strFile
このコードでは、作業フォルダのパスを変数 strPath に設定し、Dir 関数を使って、部分一致のファイル名を取得しています。そして、Workbooks.Open 関数を使って、作業フォルダ内で一致したファイルを開きます。


これどんどん聞きながら試せそう。
ググってみると、いっぱい出てきてもなかなか帯に短したすきに長しになってしまうけど、ChatGPTではやりとりしながら絞り込む回答探しの方が見る範囲がせまくて済む。非常に便利だと思います。
Verilatorはまりどころ

# はじめに

Verilator 5.006においてはまって憤怒した箇所です。憤怒するたびに記述が増えます。未サポート、と書いたものは、明示的にエラーで「未サポートです」と表示されたものです。そう書いてないものは「未サポートです」とは表示されないものの、なんかうまく動かなかったものです。

## functionにおいて64bitより大きい返り値は未サポート
taskでoutputを使えということらしい。class functionうっきうきで書いてたらこれのせいで冷水ぶっかけられてtaskに記述かえという寂しい作業が残りました。

## 再帰functionは未サポート
手がありません。試してないがtaskでも無理でしょう。もちろんautomatic指定済み。


## shortrealは未サポート

realを使えと言われます。float演算おさぼりしようと思ったがこれもあって挫折。

## unpackのstructは未サポート
packedにしろと言われます。unpackedの配列を動的に確保してstructに入れたかったのですが、そういうことはできないようです。それならclassで、と思ったのですが、それもなんか失敗した記憶があります。どうして失敗したのかはもう怒りのあまり忘れた...

## functionのoutputの挙動がどうも怪しい
ちゃんとoutputしてくれていない気がします。taskに記述を移行しました。

## unpack配列のアドレッシングに配列サイズに適したbit幅のアドレスでないと正しく読み書きできない場合がある、ような気がする
アドレッシングは32bitあれば十分やろ！がははははは！みたいなやり方は、大体においてうまく動いていたのですが、たまになんか読み書きに失敗することがあるっぽい？ので？ちゃんと配列長に合わせてアドレス幅を変えてあります。

## classのメンバ変数？がクラス外から読み書きできない
型がわからん、みたいなエラーが出ます。getter/setter用意して対応しました。

## stringのportをTOPに指定することができない
systemc使っている場合、なんかintに化けます。引数を設定したい場合はおとなしく\\$values\\$plusargsで。

# おまけ：呪文

nix-shell起動呪文です。linux kernelをビルドしたりverilator+gtkwaveでverilog開発したりするときに使っています。

```shell
nix-shell -p git gcc flex bison bc ncurses openssl verilator systemc gtkwave spike dtc vim glibcLocales
```
WebSocket connection to 'ws://○○:3000/ws' failed: がウザい時

# React側が自分は3000番ポートだと勘違いしてる
これが原因です。
一つのプロジェクトでバックエンドはLaravelやRailsでコンテナを立てて、
フロントにReactを取り入れた時などに発生すると思います。
## docker-composeファイルを編集
以下のような時に「WebSocket connection to 'ws://○○:3000/ws' failed」が
発生します。
Railsで3000番使ってるからReactはそれ以外で。みたいな時。
```docker-compose.yml
rails:
  # ~省略
  ports:
    - "3000:3000"
react:
  # ~省略
  ports:
    - "4000:3000"
```
railsの方を3001番とかにしてReactの方を3000番にすれば良いのですがマイクロサービス化してメールサーバーや、決済サーバー、WEBサーバー、APIサーバー・・・みたいに複数コンテナ立てると開発環境でどれがどのポートか管理しずらいし、なんかエンジニアらしくない！！
というわけで今回は複数コンテナを立てた場合の他の解決策もご紹介。
***ループバックアドレス*** というものがあり、それを使えば同じポートを複数コンテナで使うことが可能です。

## ローカルループバックアドレスを追加
初期値は127.0.0.1のみが用意されている。
下記コマンドでローカルループバックアドレスを追加
```terminal
sudo ifconfig lo0 alias 127.0.0.2
sudo ifconfig lo0 alias 127.0.0.3
sudo ifconfig lo0 alias 127.0.0.4
```
このままだとPCを再起動するたびに上のコマンドを打たないとなので
vim ~/.zprofile　bashだったらvim ~/.bash_profileで以下を追加
```terminal
PASSWORD="PCのパスワード"
echo $PASSWORD | sudo -S ifconfig lo0 alias 127.0.0.2 #react
echo $PASSWORD | sudo -S ifconfig lo0 alias 127.0.0.3 #api
echo $PASSWORD | sudo -S ifconfig lo0 alias 127.0.0.4 #mail
echo $PASSWORD | sudo -S ifconfig lo0 alias 127.0.0.5 #rails
~
```

 ## hostsの設定
vim /etc/hosts
```terminal
127.0.0.1 localhost

# 追加
127.0.0.2 react
127.0.0.3 api
127.0.0.4 mail
127.0.0.5 rails
```
最初は一番上の「127.0.0.1 localhost」の記述しかありません。
この記述のおかげでURLに「127.0.0.1」と打たずに「localhost」と打てば「127.0.0.1」ポートでアクセスできるわけですね。

## docker-compose.yml修正
```docker-compose.yml
react:
  # ~省略
  ports:
    - "127.0.0.2:3000:3000"
api:
  # ~省略
  ports:
    - "127.0.0.3:3000:3000"
mail:
  # ~省略
  ports:
    - "127.0.0.4:3000:3000"
rails:
  # ~省略
  ports:
    - "127.0.0.5:3000:3000"
```

これでdockerをリビルドすればみんな平和に3000番ポートで開けます。
「WebSocket connection to 'ws://○○:3000/ws' failed:」のエラーもコンソールから消えているはずです。
![スクリーンショット 2023-02-11 16.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/48d8d72e-6c5e-501d-9f2b-31001bf497a4.png)
![スクリーンショット 2023-02-11 17.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/cc54ea0d-19be-775f-db00-542011ea26bb.png)
Rackの脆弱性対応を! (CVE-2022-44570,CVE-2022-44571,CVE-2022-44572)

2023年1月18日にRuby on Railsの脆弱性[^1]とは別にRackの脆弱性が公表されました。

https://discuss.rubyonrails.org/t/cve-2022-44570-possible-denial-of-service-vulnerability-in-racks-range-header-parsing/82125

https://discuss.rubyonrails.org/t/cve-2022-44571-possible-denial-of-service-vulnerability-in-rack-content-disposition-parsing/82126

https://discuss.rubyonrails.org/t/cve-2022-44572-possible-denial-of-service-vulnerability-in-racks-rfc2183-boundary-parsing/82124

どれもReDoSの問題であり、CVE-2022-44571とCVE-2022-44572は以下の特徴により危険性がとても高いです。

- multipartの解析部分での問題であり、数MBの文字列を攻撃に利用可能
- RailsがHTTPリクエストを受け付けた際に呼び出される
- 呼び出しの際に認証が不要
- 殆どのRailsサーバが影響を受ける

CVE-2022-44572は短い文字列で攻撃可能でPoCでは326byteの文字列で0.3秒の実行時間、416byteで22秒でした。1MBを超える文字列が攻撃として送信された場合の実行時間は1日以上になることが予想されます。

Rackのバージョンを2.0.9.2, 2.1.4.2, 2.2.6.2, 3.0.4.1のいずれかに更新することで解決します。[^2]


---

#### 補足

Rubyを3.2.0に更新していた場合は、CVE-2022-44571はReDoSにならないのですが、CVE-2022-44572ではReDoSが発生します。Regexp.timeoutが設定されている場合は設定値でエラーが発生するので影響は緩和されます。(https://zenn.dev/ooooooo_q/articles/ruby_3_2_redos)

Unicornをサーバとして利用している場合は[Unicornのタイムアウト](https://yhbt.net/unicorn/Application_Timeouts.html)が発生します。応答しない状態が続いてた場合にインフラ側で自動対応するようにしていることもあるかもしれません。どちらの場合も緩和策として有効ですが、攻撃側がworker数を超えるリクエストを送り続けている場合はサーバとしては応答しにくい状況が続きます。

GitHub Advisory DatabaseではSeverityが `low` と設定されていますが、過去の脆弱性で影響範囲が全く同じものであるCVE-2022-30122では `High` と設定されています。(https://github.com/advisories/GHSA-rqv2-275x-2jq5, https://github.com/advisories/GHSA-hxqx-xwvh-44m2)

---
* [zennからの転載です](https://zenn.dev/ooooooo_q/articles/rack_update_now)

[^1]: https://rubyonrails.org/2023/1/17/Rails-Versions-6-0-6-1-6-1-7-1-7-0-4-1-have-been-released
[^2]: 2.2.6.1にはCVE-2022-44570の修正が含まれていない https://github.com/rack/rack/blob/v2.2.6.2/CHANGELOG.md
React初心者がやるReact Hooks -useState編-

アウトプットのために簡単なカウンターアプリをReact HooksのuseStateを使用して作成する

# プロジェクト作成
```zsh
$ npx create-react-app hooks-tutorial --template typescript
```

# Counter.tsxの作成

```Counter.tsx
import React, { useState } from 'react';

const Counter: React.FC = () => {
  const [count, setCount] = useState<number>(0);
  return (
    <>
      <h1>{count}</h1>
      <button onClick={() => setCount((prev) => prev + 1)}>+</button>
      <br />
      <button onClick={() => setCount((prev) => 0)}>RESET</button>
    </>
  );
};

export default Counter;
```

# App.tsxへインポート
```App.tsx
import React from 'react';
import Counter from './components/Counter';

const App: React.FC = () => {
  return (
    <div className="App">
      <Counter />
    </div>
  );
};

export default App;
```

# カウンターアプリの完成
![スクリーンショット 2023-02-11 16.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2860566/54abbe4e-1b82-b5be-2000-a3b4efe22480.png)
プルダウンの作り方

メモ
プルダウン

```ruby
<%= f.collection_select(:genre_id, Genre.all, :id, :name, {}, {class:"genre-select"}) %>

```
```ruby
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>
```
【MySQL】テーブル作成

## 参考にするテーブルの構造を見る

CREATE文を作る際に、ベースにしたいテーブルのCREATE文をチェックしたい際などに確認する。

```sql:SQL
SHOW CREATE TABLE model_tbl;
```

## テーブルを作成する

```sql:SQL
CREATE TABLE `hoge_tbl` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `name` mediumtext NOT NULL,
 `section_ids` varchar(255) NOT NULL,
 `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
 `updated_ad` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
```
Rider逆引きメモ


必要に迫られたRiderの逆引きメモになります

## SQLの補完を有効にする方法

RiderからDBへ接続してSQL文の補完を行いたい場合に設定が必要。
毎回どこから開くのか迷うのでメモ。
下記のメニューから設定出来る。
```
File->Settings->Languages&Framework->SQL Dialects
```
Rustを学んでみよう〜part1　The Rust Progrumming Lunguage

# はじめに
Rustと聞いて一歩後ろに下がる。なぜかRustはおそろしい。。。
でもそんな私がRustをやってみたいと思ったのは
「コンピュータシステムの理論と実装」
というかわいいアライグマの本を勉強会でやることになったのがきっかけでした。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701852/fd3a2702-ca15-d029-7154-4163c6ff8701.png">

かわいい表紙に似合わず内容はエグいのですが、Nandという論理ゲートからテトリスをつくってしまうというお話です。
そこでスタック、ヒープという言葉がでてくるのですが、想像がむずかしい。なんとなくわかったような気になっても実はわかっていない。
そんな時にしっくりきた説明を見つけてしまった！！！それが「The Rust Progrumming Lunguage」だったのです。

>**スタックとヒープ**
*多くのプログラミング言語において、スタックとヒープについて考える機会はそう多くないでしょう。*
>*しかし、Rustのようなシステムプログラミング言語においては、値がスタックに積まれるかヒープに置かれるかは、 言語の振る舞い方や、特定の決断を下す理由などに影響以上のものを与えるのです。*

[全文](https://doc.rust-jp.rs/book-ja/ch04-01-what-is-ownership.html "スタックとヒープ")

Rustを学んで気づいたこと、アライグマを読んで気づいたことを何回かに分けて書いていこうと思います。
気づいたこと、指摘等あればコメントで教えてください。

### スタック
まずスタックとは何か。
「高速に計算できる場所（メモリ）」です。

:::note info
スタックは、得た順番に値を並べ、逆の順で値を取り除いていきます。これは、 last in, first out(訳注: あえて日本語にするなら、「最後に入れたものが最初に出てくる」といったところでしょうか)と呼ばれます。 お皿の山を思い浮かべてください: お皿を追加する時には、山の一番上に置き、お皿が必要になったら、一番上から1枚を取り去りますよね。 途中や一番下に追加したり、取り除いたりすることもできません。データを追加することは、 スタックにpushするといい、データを取り除くことは、スタックからpopすると表現します。
:::

これで理解できる人は天才です。
何を追加し、何を取りのぞくのか、少し詳しくみていきます。
まず、「逆ポーランド記法（後置記法）」というものがあります（まだ我慢💧）
理解するとそんなに難しくありません。
普通の計算は中置記法です。

```math
(1+2)*(3+4)
```
これは21です。簡単です。
これを逆ポーランド記法で書くと

```math
1　2　+　3　4　+　*
```
逆ポーランド記法の計算ルールを定義します。
数式の左からスタックにお皿（数字もしくは演算）を乗せていきます。左がお皿の一番上だと思ってください。
1. 数字が来たらお皿を一番上に乗せます（push）。
2. 演算が来たらお皿の一番上２つをその演算で計算します。計算したお皿は取り除き、結果をお皿の一番上に乗せます。
3. 乗せるお皿がない場合は一番上から計算します。

まず"1"は数字なので一番上にのせる。"2"も同じでその上に乗せます。

```math
2　1
```
次に"+"が来たので計算した"3"をお皿の一番上に乗せます。

```math
3
```

次に来るのは"3"です。数字なのでお皿に乗せます。"4"も同じ。この時、上で計算した"3"はお皿の下に行きます。

```math
4　3　3
```

次に"+"が来たので２つを計算した"7"をお皿の一番上に乗せます。
この状態でお皿は

```math
7　3
```
最後の演算"*"が来たので計算します。

```math
21
```
無事に計算ができました。
コンピュータが計算しやすくする仕組みを簡単に抽象化するとこうなります。
スタックで演算が高速になるのは計算するべきデータを探しにいく必要がないからです。

:::note info
データへのアクセス方法のおかげで、スタックは高速です: 新しいデータを置いたり、 データを取得する場所を探す必要が絶対にないわけです。というのも、その場所は常に一番上だからですね。 スタックを高速にする特性は他にもあり、それはスタック上のデータは全て既知の固定サイズでなければならないということです。
:::
ではヒープはなんでしょう？

### ヒープ
サイズがわからないデータはヒープに置かれます。
ヒープにデータを確保するためにはOSとの会話が必要になります。

実行コード：メモリを確保したいんだけどいい？
OS：はい。アドレスはここ使ってね。
OS：使ってもいいけど管理は自分でしてよ。使ったら最後片付けてね。
実行コード：ヒープデータ？どうやってメモリの管理すればいいの？サイズがわからないのに。
実行コード：このままだと落ちてしまう！どのメモリは片付けちゃっていいの？
Java,Rubyなど:ではガベージコレクションでお掃除しましょう。
Rust：所有権、Dropトレイトで解決しましょう。

:::note info
コンパイル時にサイズがわからなかったり、サイズが可変のデータについては、代わりにヒープに格納することができます。 ヒープは、もっとごちゃごちゃしています: ヒープにデータを置く時、あるサイズのスペースを求めます。 OSはヒープ上に十分な大きさの空の領域を見つけ、使用中にし、ポインタを返します。ポインタとは、その場所へのアドレスです。 この過程は、ヒープに領域を確保する(allocating on the heap)と呼ばれ、時としてそのフレーズを単にallocateするなどと省略したりします。 (訳注: こちらもこなれた日本語訳はないでしょう。allocateは「メモリを確保する」と訳したいところですが) スタックに値を積むことは、メモリ確保とは考えられません。ポインタは、既知の固定サイズなので、 スタックに保管することができますが、実データが必要になったら、ポインタを追いかける必要があります。
:::

### part1 まとめ

これはRust（C++などのシステム言語に詳しい人はご存知だと思います）で初めてコードを書く時には非常に困惑します。
どのデータがスタックに確保されて、どのデータがヒープに確保されるのか。
プリミティブなデータはスタックに積まれるイメージです。スタックに積まれるデータはコピートレイトを実装しているので参照が必要ない。
ヒープのデータがどこでDropされているかを把握することがRustで大事になってきます。
Next.js 13 ( appDir ) + Vercel + nextjs-auth0 v2.0.0 で発生するエラー(2023/02/11時点)

## 概要

- Next.js 13でAuth0の設定をして、VercelにDeployしたら、エラーが出たので、その対策まとめ。

## 状況

- ローカル環境では、Auth0でログイン・ログアウトができるが、Vercelにデプロイされたサービスでログインするとエラーが発生する。

## 発生したエラー

```
Login handler failed. CAUSE: Discovery requests failing for https://dev-94xpl1w2.us.auth0.com, Unexpected token / in JSON at position 0
```

このエラーで検索すると、Auth0の設定値にミスがあるから発生する、という記事はいくつかありました。

再度、設定値を見なしても、不備はなく、頭を抱える……

## 原因

現時点で、nextjs-auth0 の ver.2.0.0 以降はNext.js 13の appDirモードは非推奨でした。nextjs-auth0のver.1系からver.2系へのアップデートで大きな変更があったようです。

:::note warn
The app directory introduced with Next.js 13 is currently in beta, and Vercel does not recommend using it in production. As such, this SDK does not support it yet.
:::

https://auth0.com/docs/quickstart/webapp/nextjs

## 対策

v1系の最終バージョン、v1.9.2 にダウングレードすることで、vercelでも動くようになりました。

```bash
$ npm install @auth0/nextjs-auth0@1.9.2 
```

## 補足

CloudRunやAppRunnerでは試していませんが、vercelでは一旦、ダウングレードして様子見になりそうかなと思いました。
Swift Compiler Error (Xcode): Stored properties cannot be marked potentially unavailable with '@available'への対処

Xcodeのバージョンを14に上げたところ、タイトルのエラーが出てビルドが通らなくなってしまいました。

エラーを検索し、以下の記事の内容を試しましたが

https://minpro.net/stored-properties-cannot-be-marked-potentially-unavailable-with-available


今度は

```
error waiting for a debug connection: The log reader stopped unexpectedly.
```

というエラーが出てきてしまい、ビルドできず。。


もし同じような状況で詰まっている方の参考になれば幸いです。

## 解決方法
`古いXcode(バージョンを上げる前に使用していたXCode)に向き先を変えてビルドする`ことでビルドが通るようになりました。


まずは古いXcode(バージョンを上げる前に使用していたXCode)を以下からダウンロード（自分はXcode13をダウンロードしました）

https://developer.apple.com/download/all/

すると、Finderのダウンロードの中に画像のようなファイルが表示されると思うので、こちらを展開

![スクリーンショット 2022-12-17 20.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1248189/be46c582-4fcf-7d79-38a2-cffc2e429a92.png)

展開するとXcode2という名前で保存されると思います。

自分は「Xcode_13.app」という名前に変更し保存。

:::note warn
後ほど、ここで変更した名前を使ってXcodeを切り替えます
:::



teminalを開き、以下のコマンドで現在使っているXCodeのバージョンを確認

```
$ xcode-select -p 
```

すると、おそらく以下のように表示されると思います。

```
/Applications/Xcode.app/Contents/Developer
```

以下を入力してXCodeを切り替える。
```
$ sudo xcode-select -s /Applications/Xcode_13.app/Contents/Developer
```

:::note warn
`Xcode_13`という部分には、ダウンロードした際につけた名前を入れる
:::


現在使っているXCodeのバージョンを確認するコマンドを再度入力。

```
$ xcode-select -p 
```

切り替わっていれば、以下のように表示されると思います。
```
/Applications/Xcode_13.app/Contents/Developer
```




【参考サイト】

https://fukatsu.tech/xcode-multiple
Vue3+TypeScriptでlang='ts'を指定してもannotation errorが発生する時の対処法

VueでTypeScriptを使う時に、lang='ts'を指定してもTypeScriptが反映されず、エラーが出てしまう症状の対処法です。

## ビフォアー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530037/4f99fc6e-eff7-ccdd-f68c-d2bbc2877e10.png)

## 【結論】VScodeの設定でAssociationsの項目を見直す
下記のようになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530037/3d46ca7f-ee65-e340-8ebd-c257cf1e9273.png)

値を変更してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530037/f1640a66-68fd-5ab0-be7e-9e273e357edc.png)

## アフター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530037/f0288e43-b84f-16c5-92b1-96a72de1496c.png)

## 【参考】
https://qiita.com/yuiken/items/29ba682b4906cbe1c075

## 終わりに
情報がなかなかヒットせず、解決まで数日かかりました。
同じ症状で困っている人がいましたらぜひ試してみてください。
TypeScriptのenumについて

TypeScriptでは、「enum」というものがあります。これは、固定された値の集合を定義することができます。
列挙型は、数値や文字列といった型によって表されます。

数値列挙型は、通常、0から開始して、各値に数値を割り当てます。これらの数値は、次の値を持つことができます。
文字列列挙型は、通常、固定された文字列リテラルに対応します。

使用するには、次のように定義する必要があります。

```typescript
enum Color { Red, Green, Blue };
let c: Color = Color.Green;
```
列挙型は、コードの読みやすさを向上させ、名前付きの定数を使用することによって、バグのリスクを軽減することができます。
GhostBSD（FreeBSD）の復旧方法

# はじめに
この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。

前提は「GhostBSDが正常でない状態になってしまった時に、正常な状態に戻したい」です。下に行けば下に行くほど正常な状態に戻る確率が上がるのではないかと思います。が、もちろん、ただでは確率は上がりません。対価が要求されます。（時間とかデータとかね。）
また、「正常でない状態」というのにもいろいろあると思います。なので、ここに書いてある方法で必ず正常な状態に戻るとは保証できませんので、あしからず。

# （なにも考えずに）再起動
流石に「なにも考えずに」再起動させることはできませんので、たまたまそうなってしまった場合が該当するかと。例えば、GhostBSDの起動中、コンソール画面に文字が流れている途中で、いきなり再起動が掛かることがたまーにあります。そのまま放っておくとGhostBSDが何事もなく起動しますので、よく分かりません。

とりあえず、こびとさんに感謝しておきましょうか。

# お祈りしてから再起動
一度電源を切って、お祈り（宗派不問です）してから再起動です。が、残念ながら、これでうまくいったことがある、と自信を持っては言い切れません。まあ、私のこんなちっぽけな願いをいちいち聞くほど神さまも暇ではないぞ、と。

もしうまくいったら、神さまに感謝しましょう。

ただ、この方法を選んでしまうと、ネットワークのチップ？がGhostBSD/FreeBSDが想定しない状態に初期化されてしまうことがあるらしく、次の[Windowsを一度起動してから再起動](#windowsを一度起動してから再起動)をやらないといけなくなることがしばしば。

# Windowsを一度起動してから再起動
デュアルブートにしているのであれば、一度Windowsを起動してから（電源を切らずにそのまま）GhostBSDを起動します。ネットワークの状況がおかしい時（例えばDHCPが解決できない時）には、これが有効な場合があります。
たぶん、デュアルブートのGhostBSDでない方のOSであれば何でも良くて、Windowsである必要はないような気がします。（ただし、NomadBSDはダメ。GhostBSDと同じ状況になります。はい、経験者です。おそらくFreeBSDでもダメなのではないでしょうか[^dual]。おそらくデバイスドライバの問題で、デバイスドライバはNomadBSD、GhostBSD、FreeBSDで同じでしょうから。）

# パッケージのアップデートをしてみる
これはGhostBSDが特にX関係でおかしくなった時に「そう言えばデュアルブートでWindowsを起動したときにアップデートが掛かっていたな」と思い当たるのであれば、試してみる価値のある方法です。
```
pkg update
pkg upgrade
```
たぶんsudoを付けて実行しないと権限がないと怒られると思いますが、そのままコピーする人がいそうなので、その辺は理解した上で使ってほしいな、と。あと`pkg update`は余計な気もしないでもないですが、やっておいて悪くはないでしょう。

これでうまく行ったことが一度あるような、ないような、、、

# パッケージを強制的にアップデートしてみる
[パッケージのアップデートをしてみる](#パッケージのアップデートをしてみる)でうまく行かなかったら、次に試すべきものはこれです。pkg update、pkg upgradeのどちらも-fオプションがあります。全部入れ直ししてくれますので時間は掛かりますが、それ以外に上以上のリスクはないと思いますから。
```
pkg update -f
pkg upgrade -f
```
sudoについては上と同じです。

これでうまく行ったことが、たしか一度はあると思います。

# データをバックアップしてから再インストール
上に書いてある方法をすべて試してもダメなら、NomadBSDの出番です。条件が合うのなら[GhostBSDのデータ救出法 - もしくは、痛い目に会って学ぶzfs](https://qiita.com/koizumistr/items/647b4a520c566ac27117)に書いてある方法でGhostBSDのデータを救出/バックアップします。
そして再インストールです。インストールについては、例えば[FreeBSD（にしようかと思ったがそこまで漢（おとこ）ではないので実際はGhostBSD）をインストールしてからPostgreSQLのINSTALL日本語版を作成するまで（中編）](https://qiita.com/koizumistr/items/cdb0d5f5cee88899b708)を参照してください。

# データをバックアップせずに再インストール
これが最後の手段です。喜んで選ぶものではないですが、「GhostBSDのzfsのメタな情報が壊れたらしく、NomadBSDからGhostBSDのzfsをマウントしようとしたら、NomadBSDが落ちる」という真っ青な状況になった時には、（バックアップを取っておかなかった自分の愚かさを呪いつつ[^backup]）これを選びました。この方法を選べば、当然、GhostBSD上でダウンロードしたり自分で作ったりしたデータは失われます。
インストールについては、上と同じですから繰り返しません。

[^dual]: GhostBSDとFreeBSDのデュアルブートを設定するような強者が、こんなページを読むとは思えませんが、、、
[^backup]: でも復旧すると、「喉元過ぎれば何とやら」でバックアップは取らないんですよねぇ、、、:sweat_smile:
Sassファイルをコンパイルする方法

最近npmの無い環境で開発する機会があり、Sassをnpmコマンド以外でコンパイルする方法を探したので、その内容をまとめました。

## なぜコンパイルをするのか
そもそもなぜSassはコンパイルが必要なのか？

- そもそもSassはCSSを書きやすくするために作られた拡張言語
- ブラウザでsassを読み込むことはできない

ブラウザで読み込めるのはCSSのみです。なのでsass(scss)ファイルは一度コンパイルしてCSSファイルに変換する必要があります。

Sass公式: https://sass-lang.com/guide

## Sassをコンパイルする方法

### ①ターミナルでsassコマンドを使う
```
sass sassファイルのパス cssを出力したいファイルパス
```

1つ目の方法はsassコマンドの実行です。第1引数にsassが書かれたファイルのパス・第2引数にcssを出力したいファイルパスを入れることで実行できます。そして、第3引数にオプションを追加することが可能です。

#### 便利そうなオプション一覧
- `--watch`: sassファイルを監視して自動でコンパイルしてくれます。
- `--no-source-map`: このオプションが付いていると、CSSからsassファイルを辿りやすくしてくれるソースマップの生成をしなくなります
- `--indented`: 拡張子が`.sass`ファイルの場合はこちらが必要です
- `--style compressed`: コンパイル後のCSSファイルからインデント・コメントなどを全て削除して、1行にまとめます。(コンパイル後のCSSファイルをいじらない場合はこちらがおすすめ)
→デフォルトは`--style expanded`になっています。

sassコマンドについて: https://sass-lang.com/documentation/cli/dart-sass


### ②VSCodeの拡張機能「Live Sass Compiler」を使う
これが、めちゃくちゃ楽にコンパイルしてくれます。

使い方はインストールしたら、`settings.json`にこちらを追加するだけです。

```
"liveSassCompile.settings.formats": [
    {
      // --styleオプションと同じ
      "format": "expanded",
      // コンパイル後の拡張子
      "extensionName": ".css",
      // コンパイル後のファイルをどこに追加するのか
      "savePath": "/html/css"
    }
  ]
```
他の設定オプションはこちらから確認できます: https://github.com/ritwickdey/vscode-live-sass-compiler/blob/master/docs/settings.md

うまく動いていれば、VSCodeの下のバーにWatching...と表示されているはずです。

## 終わりに
sassコマンドとVSCodeの拡張機能について調べましたが、公式の情報が一番正確でまとまっていました。記事内に貼ったリンクも是非見てみてください。

SassはCSSを書く全ての人にとって素晴らしい発明なので、まだ使ったことのない方は是非使ってみてください。
プログラミング系Youtuberっぽい動画を簡単に作ってみた

# はじめに
最近「ASMR Programming」や「No Talking」などのプログラミング系Youtube動画にハマっているので、それっぽい動画を簡単に（無料で）作ってみました。
- 必要なツール
    - スマホ
    - スマホスタンド（百均のやつでもいい）
    - 動画編集ソフト（今回は「iMovie」(Version 10.3.5)というmacOS標準搭載のアプリを使います）

※動画編集ガチ勢ではないので簡単な動画しか作れません、ご了承くださいm(_ _)m

# 成果物
以下の２種類の動画を作っていきます。
## picture in picture
![sample01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/69bc97c3-8421-9eec-07e8-6166c03d579b.gif)

## PCの画面を透過させる
![sample02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/c7bc5415-f9af-4c80-41c8-651a6e265e99.gif)

# 動画撮影＆画面録画
それでは動画を作っていきます。タイピングしている動画とPC画面の録画が必要になります。
※以下の２つの録画を同時に行う必要があります（録画開始のタイミングがずれても編集で揃えることができます）

## タイピング動画の録画
誰でも無料で簡単に動画を作れるということで、今回はカメラやマイクを使わずにスマホだけで撮影します。（高画質＆高音質が必要な場合は別途機材を用意する必要があります）
今回の動画撮影に使ったiPhone13と以前百均で買ったスタンドです。
![IMG_0433.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/647fc974-b77f-e0ed-1202-9f6dd8cc7d1f.jpeg)


こんな感じです。
![IMG_0432.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/90820615-c82a-0f12-15c4-164570ba0c7d.jpeg)


## PC画面の録画
Macの場合は、`cmd + shift + 5`で選択したウィンドウや画面の一部を録画できます。
スマホの方で録音するので、録画開始前に「Options」をクリックし、「マイク - なし」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/d0417a07-b57c-343c-106a-8b461708e202.png)


# 動画編集
「iMovie」を開き、ムービーを新規作成します。
![Screenshot 2023-02-11 at 14.15.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/a5a1d80f-4610-8552-9ced-da3f93e93369.png)



## picture in picture
動画をタイムラインにドラッグ&ドロップします。タイムライン上でPC画面の録画を下に、タイピング動画を上に配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/51cfbb4a-1c9c-8179-915d-33c17cf6b66d.png)

録画開始のタイミングがずれているので、タイピング動画に合わせてPC画面の録画の位置を調整します。`cmd + b`で選択した位置で動画を分割し、余計な部分を削除しておきます。ちなみにタイミングを合わせる際にEnterキーの音で判断しています（メカニカルキーボードなので）。

タイピング動画を選択した状態で「ビデオオーバーレイ設定」をクリックし、「ピクチャ・イン・ピクチャ」を選択します。
![Screenshot 2023-02-11 at 14.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/de599db7-9bf7-e090-1ec8-83abc4393dae.png)

あとはタイピング動画の位置やサイズを調整すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/8337ff50-2013-f888-801f-89e16caa2a92.png)



## PCの画面を透過させる
タイピング動画を選択した状態で「ビデオオーバーレイ設定」をクリックし、「カットアウェイ」を選択し、「不透明度」（opacity）を調整すればOKです。
![Screenshot 2023-02-11 at 14.46.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/33dc90e2-a7c7-8231-c727-c69755cf323b.png)


## 動画の書き出し
編集が完了したら、動画を書き出しましょう。
![Screenshot 2023-02-11 at 14.47.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/384ade61-8852-fe97-1f77-8201d20ce495.png)
![Screenshot 2023-02-11 at 14.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/d42d06ed-6b4a-f931-3b4e-52e3667b662d.png)



# 終わりに
スマホと無料動画編集ソフトさえあれば誰でも簡単にそれっぽい動画を作れる方法を紹介しました。ぜひ参考にしてみてください！
JS、CSSファイルのキャッシュ自動削除（PHP不要）

JavaScript、CSSファイルのキャッシュを削除する場合、読み込むファイルの末尾にHTMLなら`?ver=1.0.1`、PHPなら`?<?php echo date('YmdHis'); ?>`を記述する文献が多くヒットすると思います。
しかしこれは、前者だと更新するたびに手動で更新する必要があるし、後者だと、WordPressなどをインストールし、PHPファイルにする必要があります。
今回はHTMLファイルだけでで自動更新する方法のメモです。

~~~ html
<script>
  document.write('<link rel="stylesheet" href="./css/style.css?ver=' + Date.parse(new Date()) + '" ><\/link>');
  document.write('<script src="./js/time-stamp-api2.js?ver=' + Date.parse(new Date()) + '"><\/script>');
</script>
~~~
scriptタグで囲み、文字列を出力します。その際にdate関数でファイル末尾のタイムスタンプを更新します。これで手動で更新する必要はなくなりました。
注意点としては、読み込むたびにファイルが更新されるので、キャッシュには保存されません。納品時には削除するのを忘れないようにしましょう。
ファイルをアップロードするときに、「バージョン書き換えるの忘れた！」が無くなったので、いい感じ♪

#### 参考
https://blog.kumacchi.com/2008/05/28/675

https://magazine.techacademy.jp/magazine/21449
matchesマクロの紹介(rust)

[matches](https://doc.rust-lang.org/std/macro.matches.html)の紹介をします。

rustのパターンマッチを使えば、以下のような書き方ができます。

```rust
let maybe_name = Some("にわか");
if let Some(_) = maybe_name {
    println!("名前があった。");
}
```

パターンにマッチするかどうかだけ興味があるのに、こういう書き方をするのは冗長な気がします。

[matches](https://doc.rust-lang.org/std/macro.matches.html)を使えば、もっとシンプルにできます。

```rust
let maybe_name = Some("にわか");
if matches!(maybe_name, Some(_)) {
    println!("名前があった。");
}
```

シンプルにかけました。[matches](https://doc.rust-lang.org/std/macro.matches.html)は`true`もしくは`false`を返します。

テストコードで確認してみましょう。

```rust
#[test]
fn test_matches() {
    let mut maybe_name = Some("にわか");
    assert_eq!(matches!(maybe_name, Some(_)), true);
    maybe_name = None;
    assert_eq!(matches!(maybe_name, None), true);
}
```

終わり。
microCMSとNext13

メモ
getStaticPropsが使えない
https://beta.nextjs.org/docs/data-fetching/fundamentals

headersを付ける
https://beta.nextjs.org/docs/data-fetching/fetching
https://document.microcms.io/manual/display-contents
```
async function getData() {
  const res = await fetch('https://****.microCMS.com/endpoint',{
                headers:{
                    "X-MICROCMS-API-KEY":"******************"
                }
            });
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.

  // Recommendation: handle errors
  if (!res.ok) {
    // This will activate the closest `error.js` Error Boundary
    throw new Error('Failed to fetch data');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();

  return <main></main>;
}
```
Dartのtypedefとextensionの組み合わせが、思ったように動かなかった話

## tl;dr

https://dartpad.dev/?id=c34c85e9c3a6e873c9f29ff6229bb130 を見て。

## やろうと思ったこと
DDD的（といって合っているかわからないけど）に、「ちゃんとデータクラスを作って、そこに表現力を持たせたい」と思いました。

例えば、裏側で持っているIDは16桁ぐらいあるけど、ユーザーには末尾の4桁しか出さない、みたいなことを `Id` クラスのgetterに押し込めたいと思いました。
以下、この例に対して考えていきます。

## Dartでかんたんに実現しようとした

`Id` クラスとは言っても、基本的には文字列としての機能を持っていてほしく、別クラスとしてちゃんと宣言するのはめんどうに感じてました。

そこで、Dart 2.13 から `typedef` を使って、エイリアスを作成しようと思いました。
https://medium.com/dartlang/announcing-dart-2-13-c6d547b57067

また、その宣言したエイリアスに対して extension を利用して、機能を追加しようと思いました。

```dart
typedef Id = String;

extension on Id {
  String get forUser => substring(length - 4);
}
```

これ自体は機能するのですが、弊害が大きすぎました。

## 想定外だった弊害

上記の `forUser` は、あくまで `Id` として宣言された文字列だけに適用したいものでした。
（他の文字列では、利用できない方が良い。）

```dart
// これはちゃんと動いてほしいし、ちゃんと動く
final Id idVar = '1234567890123456';
print('call from Id ${idVar.forUser}');

// これはコンパイルエラーになってほしい、けど動く
final String stringVar = 'hogehoge';
print('call from String ${stringVar.forUser}');
```

上のコード内のコメントに書いたとおり、ただの `String` 型（エイリアス元の型）に対しても、Functionが追加されてしまいました。

これでは、「名前」や「住所」といった文字列に対してでも `forUser` を実行できてしまい、誤った利用を防げません。
また、コード補完もノイズが増えてしまい、劣化してしまいます。

## どうしたか

`value` として `String` 型のpropertyを持つクラスを定義して、その中に独自のFunctionを追加しました。

```
class Id {
  const Id(this.value);
  final String value;

  String get forUser => value.substring(value.length - 4);
}
```

`String` 型が持っている多くの機能は `Id` は持っていない状態となりましたが、必要になったら、必要になったFunctionだけを実装していく形で大丈夫だろう、と判断しました。

参考： https://qiita.com/tokkun5552/items/5dcb79e5283a67c2b2fe#valueobject

## 補足：Genericsを利用した場合

ちょっと不安になって、 `List<String>` に追加したfunctionが、 `List<int>` に追加されないことは確認しました。

```dart
typedef IdList = List<Id>;

extension on IdList {
  String get firstItem => this[0];
}

void main() {
  final List<String> stringIdList = <String>['234', '567'];
  // `firstItem` がちゃんと呼び出せる
  print('firstItem ${stringIdList.firstItem}');

  final List<int> intList = <int>[1, 2, 3];
  // ちゃんとコンパイルエラーになる
//   print('firstItem ${intList.firstItem}'); // <- compile error
}
```

これは、大丈夫そうでした。

## 補足：他の言語は？
ちゃんと確かめてないですが、他の言語での状況を調べてみました。

### Kotlin

Androidアプリ開発でよく利用するKotlinでの状況を調べてみました。

https://discuss.kotlinlang.org/t/extension-functions-on-type-aliases-should-only-be-accessable-from-similar-types/3722/2
https://discuss.kotlinlang.org/t/implicit-conversions-between-type-aliases/3222
こちらの、言語公式コミュニティの方では、 `typealias` はあくまで"ニックネーム"としてつけるだけで、Dartと同じ動作になりそうでした。

https://kotlinlang.org/docs/inline-classes.html
https://maku77.github.io/kotlin/misc/inline-class.html
ただ、Kotlinには "inline class" というものがあり、それを利用することで実現できそうです。
（"inline class"の主眼はパフォーマンス最適化のようですが。）

https://github.com/dart-lang/language/issues/2727
Dart言語でも、inline classの導入は議論されているようでした。（昨年末ぐらいの話っぽい）

### Swift

こちらはiOSアプリ開発でよく利用するSwift。

https://qiita.com/mono0926/items/1b94242d4139d1982a31
ほぼこの記事で詳細に説明されてました。
やはり、 `typealias` はあくまで「別の名前をつけただけ」であって、全く区別されないとのことでした。Dartと同じですね。
Swiftでは、Kotlinの"inline class"のように手軽に実現する手段はなさそうですね。
いくつかの方法が例示されていますが、 `ExpressibleByXXXLiteral` を利用する方法は、「知らないとできない」ものだと思うので、この機会に知ることができてよかったです。

### Go

上記のSwiftのところであげた記事で記載されていましたが、Go言語の `type` では、Dartと違う動きになりそうでした。
selenium4 で スクレイピング

とりあえず、動くコード

ヤフーのソースを表示するだけ。

```
yum -y install libX11 GConf2 fontconfig
yum -y install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
fc-cache -fv
yum -y install google-chrome-stable libOSMesa
python3 -m pip install selenium
python3 -m pip install webdriver-manager
```

今回はwebdriver-managerを使用するので、わざわざドライバをダウンロードする必要がない。

# chrome

```hoge.py
from selenium import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome import service as fs
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")


serv = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=serv, options=options)
wait = WebDriverWait(driver, 10)

# URLにアクセス
driver.get("https://yahoo.co.jp")

# htmlを取得・表示
html = driver.page_source
print(html)

# ブラウザーを終了
driver.quit()

```

no-sandbox が無いとエラーが出る

```
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
```

# firefox

firefoxをインスコ

aws lightsail だと

```
sudo amazon-linux-extras install firefox
```

をして、インスコ

続いてコード

```hoge.py
from selenium import webdriver
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.service import Service
from webdriver_manager.firefox import GeckoDriverManager
import time


options = webdriver.FirefoxOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")

serv = Service(GeckoDriverManager().install())
driver = webdriver.Firefox(service=serv, options=options)
wait = WebDriverWait(driver, 10)


# 確認くんにアクセス
driver.get("https://www.ugtop.com/spill.shtml")

# スクショを取得
driver.get_screenshot_as_file('/var/www/html/screenshot3.png')

# ブラウザーを終了
driver.quit()



```
Pythonでの音声信号処理 (10) ノコギリ波の周波数を解析



## 今回のテーマ
以前、ノコギリ波を秒間440回繰り返して音を出したときの波のデータについて、どのような周波数が含まれているのかを調べてみる。

（前回挙げた疑問点の残るひとつは、とりあえず保留して次回以降へ）

## やってみた

```p10_1.py
# -*- coding: utf-8 -*-
import sys
sys.dont_write_bytecode = True

from Grp import Line, Bar
import Dummy as dmy
import numpy as np
import Analyze as ana
from multiprocessing import Process
import time
import math

def main():
    orgsmpl = 44100 # サンプリングレートは44.1KHz
    sec = 1      # 1秒分

    # ノコギリ波
    # -> 440回繰り返したいので、サンプル数を440分の1にして、あとで440回繰り返す
    smpl = int(orgsmpl / 440)
    wav1 = dmy.makeWave(1, smpl, sec, 0, 0, 1)
    for i in range(64):
        freq = i + 1
        wav1 += dmy.makeWave(freq, smpl, sec, 1 / freq, 0, 1)
    # 440回繰り返す
    wav2 = np.array(list(wav1) * 440) * 16

    # Hz 1～600で、解析
    rng = (1, 600)
    res = ana.ft(wav2, orgsmpl, (0, 1), rng)
    res_sin = res[0]
    res_cos = res[1]

    # sinとcosの係数を2乗して加算して平方根をとる
    res_all = list(map(  
        lambda v : math.sqrt(v),
        np.array(res_sin) * np.array(res_sin) + np.array(res_cos) * np.array(res_cos)))

    # 表示
    p_s = []
    p = Process(target=drawLineGraph, args=(wav2, smpl))
    p.start()
    p_s.append(p)

    p = Process(target=drawBarGraph, args=(res_all, range(rng[0], rng[1] + 1)))
    p.start()
    p_s.append(p)

    while len(p_s) > 0:
        for p in p_s:
            if not p.is_alive():
                p.join()
                p_s.remove(p)
        time.sleep(0.1)

    return

# 折れ線グラフの表示
def drawLineGraph(data, rate):
    grp = Line()
    grp.setData(data, rate)
    grp.setScale(1)
    grp.display()

# 棒グラフの表示
def drawBarGraph(data, label):
    grp = Bar()
    grp.setDataLabel(data, label)
    grp.display()

if __name__ == '__main__':
    main()
```

なお、それなりに計算量が多いので、実行すると、ちょっと時間がかかります。

ノコギリ波
![p10_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850619/8a2423fa-07b2-b575-6f45-053f283e3a1d.png)

周波数
![p10_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850619/c7ea0af9-43c4-f348-fd66-7c7b4d4dcaa0.png)

437Hzあたりが多いらしい。440Hzがラなので、ほんの少しだけ低い音だったようだ（プログラムに間違いが無ければだが）。

## 補足
Grp.pyはここにあります。
https://qiita.com/u1tym/items/b52c466620f65225edf3

Dummy.pyはここにあります。
https://qiita.com/u1tym/items/3e2be5364e83df1b7792

Analyze.py、Integral.pyはここにあります。
https://qiita.com/u1tym/items/6fadd6b2974fc3281137