OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu をアップグレードしたら Firefox のパスワードが消えた！のを復旧する

## 事象

Ubuntu 22.04.1 へバージョンを上げたら Firefox のパスワードが消えた。今まで使っていたパスワードが補完されなくなった。メニューの Passwords を見ても空になっている。

## 原因

新しい Firefox は snap パッケージになった。
これに伴いプロファイルの格納場所が変わって、今まで使っていたプロファイルとは違う新しいプロファイルで起動するようになった。新しいプロファイルにはパスワードが引き継がれていなかった。

## 対処

新しい Firefox に新たなプロファイルを作り、そこに以前使っていたプロファイルをコピーする。

##### 1. 古いプロファイルを探す

まずは、古いプロファイルを探す。~/.mozilla/firefox の下を見るとそれらしいものがあった。

~~~
古いプロファイルの場所の例
~/.mozilla/firefox/o0avssie.default
~~~

##### 2. コピー先となる新しいプロファイルを作る

次に、新しい Firefox でコピー先となるプロファイルを新規に作る。Firefox のアドレスバーに about:profiles と入力するとプロファイル管理画面となる。Create a New Profile で適当な名前のプロファイルを作る。

##### 3. 新しいプロファイルに古いプロファイルの内容をコピー

一旦 Firefox を停止し、新たに作ったプロファイルのディレクトリに、古いプロファイルの内容を全部コピー。

~~~bash
# 例
cp -r ~/.mozilla/firefox/o0avssie.default/* /home/tadashi9e/snap/firefox/common/.mozilla/firefox/r15jfq3l.tadashi9e
~~~

##### 4. 確認

Firefox を再度起動して、再び about:profiles で新しく作ったプロファイルで動作していることを確認する。この状態で Passwords を見ると以前のパスワードが復活していた。適当なサイトにログインしてパスワード補完も可能であることを確認。
concyclic quadrilateral, cyclic quadrilateral「共円四辺形」について調べてみた。 

やる気をだせば、
「パラメシュヴァーラの外半径公式(Parameshvara's circumradius formula)」
の証明ができますか？



オリジナル

https://ja.wikipedia.org/wiki/%E5%85%B1%E5%86%86%E5%9B%9B%E8%BE%BA%E5%BD%A2

https://en.wikipedia.org/wiki/Cyclic_quadrilateral


# 入試問題

https://qiita.com/mrrclb48z/items/f8928277ab1edeab5701
共円四辺形「22年 東北学院大 工 A 7」を「パラメシュヴァーラの外半径公式」でやってみたい。 

a＝4,b＝2,c=sqrt(6)-sqrt(2),d=2*sqrt(2)

オリジナル

https://kamelink.com/blog/2022/08/24/3-2-22-touhokugakuinndai-kou-a-7/


大学入試数学問題集成＞
未掲載です。

# 参考

パラメシュヴァーラの外半径公式＜

https://ja.wikipedia.org/wiki/%E5%85%B1%E5%86%86%E5%9B%9B%E8%BE%BA%E5%BD%A2#%E3%83%91%E3%83%A9%E3%83%A1%E3%82%B7%E3%83%A5%E3%83%B4%E3%82%A1%E3%83%BC%E3%83%A9%E3%81%AE%E5%A4%96%E5%8D%8A%E5%BE%84%E5%85%AC%E5%BC%8F

# sympyで。あと一歩でした。
```python
from sympy import *
var('a b c d s')
R=Rational(1,4)*sqrt(((a*b+c*d)*(a*c+b*d)*(a*d+b*c))/((s-a)*(s-b)*(s-c)*(s-d)))
mySub={a:4,b:2,c:sqrt(6)-sqrt(2),d:2*sqrt(2),
       s:(4+2+sqrt(6)-sqrt(2)+2*sqrt(2))/2}
print("#(3)",      R.subs(mySub).simplify() )
print("#(3)",float(R.subs(mySub).simplify()))
#(3) 2*3**(3/4)*sqrt(3 + 2*sqrt(3))/(3*sqrt(sqrt(3) + 2))
#(3) 2.0
```
StoryBook(React)でArgTypesが効かなずラジオボタンではなくテキストエリアになる

# はじめに

Storybookでコンポーネント管理を始めたのですが、色々つまづくことが多いので共有します
個人的にはデバックがしづらいので解決に時間を使ってしまうことが多いです

# 問題

以下のコードで`type`をラジオボタンにして切り替えられるようにしたかったのですが、なぜかテキストボックスになってしまいます

```Form.stories.tsx
export default {
  title: 'Form',
  component: Form,
  args: {
    label: "from label"
  },
  argTypes: {
    type: {
      option: ["text", "password"],
      control: { type: 'radio' },
      },
    },
  },
```

# 解決方法

`args`と`argTypes`の順序を変えたら解決しました

```Form.stories.tsx
export default {
  title: 'Form',
  component: Form,
  argTypes: {
    type: {
      option: ["text", "password"],
      control: { type: 'radio' },
      },
    },
  },
  args: {
    label: "from label"
  },
```

`args`の設定が優先されてしまい、`type`の型である`string`に適したフォームが表示されていたようでした


# おわりに

StoryBook思ったような挙動にするには学習コストがかかりそうな気がしています
地道に解決して導入したいです
二段階認証と二要素認証の違い

# 二段階認証

名前のとおり。手順が二段階に分かれている認証のこと。

たとえば「パスワード入力後に、SMS経由の番号入力がある」など。

# 二要素認証

知識・所有・生体のうち2つの要素を利用する認証をこう呼ぶらしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/4a45e92b-5e0c-6ad0-8303-e8def2e0de01.png)


参考

https://eset-info.canon-its.jp/malware_info/special/detail/210311.html


# 二段階認証だが二要素認証ではないもの

たとえば以下の場合。

- 1段階目の認証がパスワード入力
- 2段階目の認証が「秘密の質問」の解答

これは両方が「知識」による認証なので一要素だ。つまり二要素認証ではない。

# 「二要素認証だが二段階認証ではないもの」はあるのか？

ない。

>二要素認証は異なる二つの認証要素を用いるので、必然的に二段階の認証となる。

# 補足

世の中のほとんどの二段階認証は二要素印象であると言える。



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura

<!-- Update From Qiita API -->
新卒のIT就活を考える

# はじめに
新卒就活の時に全くIT業界を見なかった自分が、なぜかWeb系大手の事業会社でIT企画をやってます。自分の通ってきたルートも面白いと思っていますが、いま新卒に戻るならIT業界のジョブ型採用に絞った就活をやるなーと思うので、就活生向けの情報をまとめます。

# スペック・経歴
- 文系大卒。学生時代のIT経験はExcelの授業でVBAに少し触ったくらい。
- 新卒でとある事業会社に入り内勤部署を複数経験。
- データ分析にはまる過程でITに興味を持ち、社内で情シス（システム管理部門）にジョブチェンジ。
- インフラ保守をやりつつ、DX案件のPLをいくつか経験したところで、Web系大手に転職。
- 今はIT企画をぼちぼちやってます。

# 新卒おすすめルート
### Web系自社開発企業のエンジニア：開発やりたい人
長くエンジニアをやるかどうかは別にして、手を動かせて悪いことはないので、ある程度開発経験があるならまずはエンジニア就活をおすすめします。強いエンジニアはメガベンチャーに集まる傾向があるので、技術力を上げるためにも、将来的な転職の糧にするためにも、まずはこの界隈で検討を。学生の早いうちからポートフォリオ（履歴書代わりになる開発プロダクト）を作り、社会人エンジニアと交流を持ち、モダンな開発環境のWeb系企業でインターンを積み、時間をかけて準備することが大事だと思います。

全くの未経験だけどエンジニアになろう！と思い立った人の場合、メガベンチャーは厳しいと思いますが、数か月時間を確保して良質なポートフォリオを作れば、自社開発企業への就職は可能なようです。

### 大手SIerのSE：プロジェクト管理志向の人
ビジネスモデルが日本経済の成長を前提にしているので、SIer自体は正直なところ将来性に貧しいですし、案件・配属ガチゃの闇も大きいです。それでも、国内のIT事情を俯瞰できて、大手IT企業で働いていたという錯覚資産を得られるので、将来的にIT関連のプロジェクト管理で食べていきたい人は一時的に籍を置く価値があると思います。また、Web系と比べてビジネス基礎をしっかり教えてもらえるという点でも、新卒で入るメリットがあるかと。業務システムでもインフラでも、目の前の実務を粛々とこなしつつ、プライベートでモダンな技術の学習やベンダー資格の取得に勤しめば次のキャリアは自由度が高いです。外資のITコンサルに行く、ビジネスモデルがしっかりしてる事業会社で企画系の情シスをやるといったネクストキャリアが有望でしょうか。

ただし、SIerはレガシーな技術にしばられていることが多いので、エンジニアとしてのキャリアを考えている人はやめておきましょう。

### Web系事業会社のビジネス職：ビジネスを設計したい人
コードを書いたり、コマンドを叩いたりすることだけがITではないので、ビジネス職の検討はありだと思います。SIerで総合職だと日本の古い慣習に翻弄される時間が長くなってしまうので、次々新規事業を立ち上げるWeb系事業会社に入って、早くからプロダクトの企画・管理に関わるのが良いと思います。プロジェクトの中でエンジニアと会話する時間もそこそこあるので、技術用語を知ったり開発プロダクトのライフサイクルを見ることができて、IT業界で働くための基礎が固まるのも早いかと。コードは書かなくても、BIツールあたりでデータの分析・可視化まできるようにしておくと付加価値がつくと思います。

### 外資SaaSベンダーのセールス：サービスを売りたい人
国によって言語や文化は違えど企業に必要な道具は似たようなものなので、企業向けSaaSツールには世界でかなりのシェアを取っている巨人が存在します。IT業界で営業をやりたいならCRM、ERP、グループウェアあたりの外資がおすすめです。外資SaaSの日本法人はあくまで「日本営業所」なので基本的に開発機能を持っていません。セールス（およびマーケ）が国内の主導権を握れます。セールスで専門性を高めたい人には楽しい環境かと。日本にいながら、世界で右肩上がりに成長している本場のITを肌で感じられるのも魅力なのかなと思います。

# 補足
上記をおすすめする前提をいくつか。

- 技術力は正義
基本的に技術力をつければまわりから一目置かれる業界です。エンジニアにならなくても、何かしらの開発言語は触っておくべきだと思いますし、ネットワーク・データベース・セキュリティあたりは基本を知っておくべきです。

- 上流に行けばいくほど待遇も労働環境も良い
その一方で、ビジネス的には上流に行けば行くほど強い権限を持っているので、現場でコードを書き続けると待遇・労働環境が頭打ちになります。どこかで、管理する側・設計する側に上がるべきです。

- 日本のITは基本的に斜陽産業
ITの本場はアメリカです。現状、日系企業は世界に通用するハード・ソフトを持っていないですし、巻き返せる見込みもほぼないです。

- 国内のDXが進んでいないのでWeb系はまだ伸びる
日本国内にはDXが進んでいない業界・課題がたくさんあるので、しがらみが少なくてフットワークの軽いWeb系企業はまだまだ伸びると思います。

- ITはつぶしが利く
飲食チェーンでもIT人材の採用をしているくらいですから、IT業界である程度生きていける力をつければ、他業界への転職も容易です。やりたい仕事がないなら、とりあえずIT触っておく、という選択もありじゃないかと。

# 参考サイト
[いま僕がFラン文系大学生ならWeb系エンジニアになるために何をするか](https://www.youtube.com/watch?v=IV0xmPFYjk8)
【JavaScript】querySelectorでスペースを含むクラス名を指定する場合

## 書き方

```
// 取得対象
<div class="aaa bbb ccc">

// 取得できない
let element = document.querySelector('.aaa bbb ccc')

// 取得できる
let element = document.querySelector('.aaa.bbb.ccc')
```

クラス名がスペースで区切られている場合、HTML要素はclass属性を複数持っている、ということ。
上記の場合、以下の意味となる。

×「`aaa bbb ccc`クラス」
○「`aaa`クラス、かつ`bbb`クラス、かつ`ccc`クラス」

## 参考
https://web-camp.io/magazine/archives/87658
https://www.web-dev-qa-db-ja.com/ja/javascript/documentqueryselector%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%82%92%E5%90%AB%E3%82%80%E3%81%93%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%B9%E5%90%8D%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%82%88%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/1051960349/
【Spring】特定のExceptionを発生させた際に独自のエラー画面を表示したい


# はじめに
業務でJavaを使うことになったが、少しブランクがあるため、記事としてまとめる。

# 背景
DBから値を取得するメソッドを使用した際に、検索結果が0件であった場合に
独自のExceptionを発生させるメソッドに出会った。また、このメソッドを使用
し、検索結果が0件であった場合500エラーが表示されてしまう。

今回、上記メソッドを使用した際には、HTTPステータスを404で返却し、
かつ既存の404エラーページではなく専用の404エラー画面を表示したい
という依頼である。
＃ 内容は一部ぼかしている

# 方針

特定のメソッドを実行する際に、0件であった場合に自作したExceptionを投げ、
そのExceptionを検知する。最終的に独自のエラー画面を呼び出すようにする。
＃ それ以外の404の場合は、既存のエラーページを呼び出す。


```java:呼び出し元.java
int id = 1;

// idを元にDBから値を取得し、TestDetailに格納する（取得出来なければ独自のExceptionを投げる）
TestDetail detail = TestDetailDao.fetchTestData(id)
    .orElseThrow(() -> new NotFoundDetailException(
        messageSource.getMessage("detail.notfound.log", new String[]{String.valueOf(id)}, Locale.JAPAN)));
```

自作したExceptionクラスはこちら。

```java:NotFoundDetailException.java
public class NotFoundDetailException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public NotFoundDetailException(String message) {
        super(message);
    }
}
```

NotFoundDetailExceptionを検知する@ControllerAdviceクラスを作成する。

```java:ErrorAdvice.java
@ControllerAdvice
@Slf4j
public class ErrorAdvice {

  @ExceptionHandler(NotFoundDetailException.class)
  // 発生させたいHTTPステータスと、発生理由を設定（発生理由は別途使用）
  @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "detail not found")
  @ResponseBody
  public void NotFoundJobOfferExceptionHandler(NotFoundDetailException e) {
    log.warn(e.getMessage(), e);
  }
}
```

エラー画面に遷移させるControllerに以下設定を追記する。

```java:ErrorController.java

@Controller
@RequestMapping("/error")
public class ErrorController implements org.springframework.boot.web.servlet.error.ErrorController {

  @Deprecated
  @Override
  public String getErrorPath() {
    return "error";
  }

  @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
  public String myErrorHtml(HttpServletRequest req, ModelAndView mav) {
    HttpStatus status = getHttpStatus(req);
    switch (status) {
      case NOT_FOUND:
        // ここで上記で設定したエラー理由のreasonを元に判定（Enumクラスは以下に記載）
        Object errorReason = req.getAttribute(RequestDispatcher.ERROR_MESSAGE);
        String errorPath = NotFoundReasonType.getErrorPageByReason(errorReason.toString());
        return errorPath;
      default:
        return "error/xxx";
    }
  }
}
```

```java:NotFoundReasonType.java
@Getter
public enum NotFoundReasonType {

  DETAIL_NOT_FOUND("detail not found", "error/notFoundDetail"),
  DEFAULT("", "error/404");

  private String errorReason;

  private String errorPath;

  private NotFoundReasonType(String errorReason, String errorPath) {
      this.errorReason = errorReason;
      this.errorPage = errorPath;
  }

  public static String getErrorPageByReason(String errorReason) {

    NotFoundReasonType targetEnum = Arrays.stream(NotFoundReasonType.values())
      .filter(x -> x.getErrorReason().equals(errorReason))
      .findFirst()
      .orElse(DEFAULT);

    return targetEnum.getErrorPath();
  }    
}
```

上記で、特定のExceptionが発生した場合に自作の404エラー画面を表示することが出来た。
既存の内容を修正しただけであるため、この方法がベストプラクティスではないとは思う。
ただ、もし参考になる記述があれば幸いである。
Pythonの学び方（初学者用）と教材の紹介

# 当記事について
### 今まで勉強してきたけど・・・
数えましたら、この2年で10冊以上のPython本を読みながら写経したりしてきました。
しかし、いつまでやっても、なかなか実践力が身に付きませんでした。
本を読みながら打ち込むのも、10冊もやると、正直飽きてきます。
インプットだけ、ではやはりいつまでも使いこなせるスキルはつきません。

### やっと停滞から抜け出せました
今までは、ただ本を読みながら「ふーん、こうするんだ」で終わり、全く面白くなかったのです。
しかし、paizaでのアウトプットスキルを求められた時に、それが激変しました。
paizaで「これを実現するにはどうしたらいいんだ？」と、散々頭を悩ませられ苦しめられた答えがそこにあったのです。
Python本の無味乾燥で退屈だった文法・構文解説が、お宝情報のように見えるようにりました。

### 本だけじゃダメ
読書感想文なのに、このようなことを言うと元も子もなくなります。
しかし、ITの学習につきましては、学んだことのアウトプットが相当大事になります（ITに限る話ではないですが）。
そしてアウトプットすると、インプットの質が相当あがります。
本に対する目の輝き具合や志向が相乗効果で、野暮な言葉を使うと「爆上がり」します。
そのような個人的体験をもとに、数読んだなかから、Pythonを学ぶのに必要最小限な本の紹介をしつつ、インプットしながらアウトプットして、両方の相乗効果を出す方法をご紹介したいと思います。

# 紹介する教材
4つあります。
3冊＋ネット上で無料で勉強できる実践問題集になります。

### 1．スッキリわかるPython入門
![p1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/c7be035a-affc-d64b-327e-e7c1e82f0b11.jpeg)

### 2．あなうめ式Pythonプログラミング超入門
![p2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/e5c42530-f235-a75c-6b0a-17504c1d9874.jpeg)

### 3．paizaのスキルチェック
URL: https://paiza.jp/challenges/info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/ba920695-5651-757d-92c3-9c779e9ceebb.png)

### 4．Python基礎＆実践プログラミング ［プロへのスキルアップ＋プロジェクトサンプル］
![p3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/c5ff69f5-0d36-d800-a706-15fa6eb0c634.jpeg)

# それぞれの教材と使い方・進め方について
### 1．スッキリわかるPython入門
いわゆる入門解説本です。他にも世の中に類似の本は多々あります。
いきなり問題集にあたってアウトプットする、というのは無理な話です。
最初は退屈かもしれませんが、このような入門解説書の類を、解説を読みながら、IDLE、Jupyter notebookなどを使って打ち込み、初歩の初歩を学んでいきます。
本当にゼロベースですので、最初のうちはさほど退屈しないで読み進められるかもしれません。

### 2．あなうめ式Pythonプログラミング超入門
かなり入門レベルでわかりやすい問題集です。
ここで初歩レベルのアウトプットをします。わからなくなったら、入門解説本に戻ることで、受動的に読んでいた内容が一気に変わります。
ここで相乗効果の第一段階を実感できると思います。

とはいえ、この本は、相当入門レベルなので、あまり解説本に戻らなくても問題ない人も多いかもしれません。
その場合、この本を飛ばして、次のpaizaのDランクに進んでもいいと思います。

### 3．paizaのスキルチェック
まずはDランクに挑戦します。
paizaの問題は、問題文の読解と、与えられるテストデータの読み取り方等が特殊ですから、最初は戸惑うと思います。
しかし、問題レベルは、入力された数値を四則演算してprintするなどの初歩レベルです。
従いまして、問題文とテストデータの取り込みに慣れれば、さほど困難なく取り組めると思います。

Dランクくらいであれば、<1．スッキリわかるPython入門>や<2．あなうめ式Pythonプログラミング超入門>を見返す等して取り組めると思います。
Dランクで相乗効果の第二段階を実感できます。
しかも、2022年8月25日現在で、200問近くありますから、かなり基本構文のアウトプット練習ができます。

### 4．Python基礎＆実践プログラミング ［プロへのスキルアップ＋プロジェクトサンプル］
paizaのDランクもこなし、次にCランクとなると、複数行にわたるロジックを組まねばならなくなります。
上に紹介した入門解説本だけでは歯が立たなくなるかもしれません。

そこで、幅広いサンプルと、Pythonの深い仕様や技が多く書かれている、辞書的な本や参考先が必要になってきます。
この本は、Pythonの仕様に深く入り込み、サンプルを数多く掲載してくれています。
例えば、
・「配列と配列をドッキングしたい」
・「空の2重配列作りたい」
・「小数点（float）が入る四則演算やったら予想外の数字が出てきたから対処したい」
などの局面に出くわした時にヒントとなるサンプルが入ってます。

また、paizaにてCランク以上の問題に取り組むと「あの場はなんとか切り抜けたけど、あの操作するのにもっと効率よくできる方法はないかな」という志向が出てきます。
この志向を持ちながら、この本の内容を打ち込みながら読み進めると「これがあったのか！」とお宝情報を見るような目でこの本を読むことができます。

# まとめ
・最初は入門解説書を歯を食いしばりながら読みながら、実際に打ちこむ
・次に簡単な問題集に取り組みつつ、忘れたものについては入門解説書に戻る、という往復による相乗効果を得る
・次の段階の問題集に取り組みつつ、辞書的な本を参照しつつ、辞書的な本を読みながら、実際に打ちこむ

となります。

同じように「読むだけだと身に付かない」という方への一助となれば幸いです。
ご一読いただきまして、ありがとうございました。
雀魂 部屋別の接続人数を取得する

:::note warn
**スクリプトの利用は、自己責任でお願いします。**
:::

雀魂の部屋別の接続人数を取得するスクリプトです。開発者ツールで実行できます。

```JavaScript
window.fetchPlayerCount = (...modes) => {
    const ids = {
        銅: [2, 3, 17, 18],
        銀: [5, 6, 19, 20],
        金: [8, 9, 21, 22],
        玉: [11, 12, 23, 24],
        王: [15, 16, 25, 26],
        交: [29, 30, 31, 32],
    };
    const req = {
        mode_list: modes.map(mode => ids[mode] || mode).flat()
    };
    app.NetAgent.sendReq2Lobby("Lobby", "fetchCurrentMatchInfo", req, (err, res) => {
        if (err || res.error) return;
        for (const match of res.matches) {
            const id = match.mode_id;
            const count = match.playing_count;
            const room = cfg.desktop.matchmode.map_[id]?.room_name_jp || "";
            const rule = cfg.game_live.select_filters.map_[200 + id]?.name2_jp || "";
            console.log(`${room} ${rule} : ${count}`);
        }
    });
};

// 玉の間（四人南）と王座の間
fetchPlayerCount(12, "王");
```

***

```mode_id``` については、こちらのページをご覧ください。

https://wikiwiki.jp/majsoul-api/%E5%AE%9A%E6%95%B0%E4%B8%80%E8%A6%A7%E3%81%AB%E3%82%83#bd8d1986
【Athena】バケッティングでコスト削減＆高速化

# バケッティングとは
Athenaでは費用を抑えつつ、クエリの高速化を図るための代表的な手段としてパーティションがあります。
しかし、パーティションに加えてバケッティングというやり方もあるのでそのやり方と注意点を記載しておきます。

バケッティングというとS3のバケットが出てくるかもしれませんが、それとは全く別の概念です。
CTASでパーティション分割してテーブルを作成する際のデメリットとして100個のパーティションまでしか作成出来ないというデメリットがあります。これは[一応INSERT文などでなんどもなんども実行](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/ctas-insert-into.html)すればなんとかなるという事はあるのですが、かなり実行コストがかかります。

# バケッティングのメリット
>CTAS クエリ結果のバケット化は、カーディナリティが高く、値が均等に分散されている列によってデータをバケット化するときにうまく機能します

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/bucketing-vs-partitioning.html

引用元にあるように、カーディナリティが高いものでうまく機能します。
例えばユーザーIDでパーティションを分けようとするとユーザーが1万人などいると、パーティション分割がかなり難しくなります。100回クエリを実行する必要があります。
そこで以下のようなCTAS文を実行します。

```sql
CREATE TABLE bucketed_comments
    WITH (
    format='PARQUET',
    external_location='s3://example_bucket/users/bucketed/',
    bucketed_by = ARRAY['user_id'],
    bucket_count = 100
) AS
select * from comments
```

コメントテーブルに対してバケッティングを施した新しいテーブルを作成します。bucket_countを100としているので100ファイルに分割されます。
このテーブルに対して

```sql
SELECT * FROM bucketed_comments WHERE user_id in (1,3,8);
```

といったSQLを実行すると、スキャンするファイルがuser_idが1,3,8のデータが存在するファイルだけになります。
つまり100ファイル中最大でも3ファイル、最小で1ファイルのみのスキャンとなります。これがバケッティングもパーティション分割もしていないと100ファイルのスキャンとなります。

# デメリットその1 bucket_countの設定をミスらない
ではbucket_countを増やせばそれでいいのか？というと全くそんなことがないのです。
bucket_countを増やすとファイル数が増えます。そうなると例えばuser_idを指定せずにスキャンした場合に、たくさんのS3ファイルにアクセスするためにS3へのリクエスト費用がかかり、かつ速度もかなり遅くなります。
1MBの1ファイルに1リクエストと1KBの1000ファイルに1000リクエストどちらが優れてるかを考えればすぐに分かるかと思います。

したがって、バケッティングに指定したcolumnを確実に指定する、しない場合もあるのであればそれを考慮してcountをいくつにするかを考える必要があります。
Athenaでは1ファイルあたり128MBに調整すると一番パフォーマンスがでるようです。

https://aws.amazon.com/jp/blogs/news/top-10-performance-tuning-tips-for-amazon-athena/

# デメリットその2 INSERT文が使えない
バケッティングを設定したテーブルにはINSERTが使えません。どのファイルにどのデータを入れて置くのかまで考慮しているのがバケッティングなので、今後もここの改善を望むのは難しそうです。
したがって、随時データが増えていくようなテーブルは向いていないかもしれません。例えば日時でデータが増えていくテーブルであれば、パーティションでINSERTで新しい日付のデータを加えていく、といった運用で良さそうです。

# 最後に
バケッティングはINSERTが使えないという点が一番のデメリットのように感じます。
Athenaを使うのはCSVなどでどんどんデータを加えていけるというのが一つのメリットであるからです。ただ、簡単にスキャン料を減らせるというのが実現できるので、知っておくだけでも、使えるパターンが来たときに大活躍するかもしれません。
チーズのヘタと早すぎる抽象化

# これは何？
「早すぎる抽象化」「誤った抽象化」に気をつけようね、という警告を標語化した記事です。
## 早すぎる抽象化？
下記の記事が詳しいので、この記事では省略します。

https://qiita.com/shiz/items/b5a0e263c4c005a22704

# チーズのヘタ
2歳の娘から **「おとーさん、チーズのヘタ取れた！」** と謎報告が上がってきました。  
チーズの……ヘタ？  
何かと思ったら、キャンディチーズの包み紙のことでした。  
苺のヘタ（漢字で"蔕"）のように、「ヘタ」という言葉を「食べ物に付属している、食べられない部分」と一般化したようでした。  
このような誤りを「過度な一般化」「過剰拡張」と呼ぶらしいです。  
子供が起こす分には微笑ましい誤りです。
# 子供特有のことだと笑えない
DRY原則を過度に適用してしまって、後々困ることありませんか？  
全く同じ処理でも、運用上の意味合いが異なり、仕様変更時にわざわざ分離させなきゃならなかったり、ヘンなフラグ噛ませるハメになったり……  
「全く同じ処理だ！ 爆殺したい！」という気持ちがムクムク湧き上がった時には、 **チーズのヘタ** になっていないか、立ち止まって考えてみると良いかもしれません。
MMDリソースをUnityに導入する方法

# 使用するUnityプラグイン
1，MMD4Mecanim
https://stereoarts.jp/
2，MMD2UnityTool
https://github.com/cnscj/MMD2UnityTool
3，Oculus LipSync
https://developer.oculus.com/documentation/unity/audio-ovrlipsync-using-unity/

参考したweb
https://blog.gcrest.com/archives/404
https://kan-kikuchi.hatenablog.com/entry/OVRLipSync

# 手順：
**１、MMD用モデル（.pmx）とモーション（.vmd）をUnityに導入**
pmxモデルを直接Unityプロジェクトにインポートします。
ここはMMD4Mecanimを使います。
Unityでpmxデータを選択して、利用規約が出てくる、それを同意して進みます。
inspectorにpmxモデルとvmdモーションを入れて、FBX出力パースを設定します。
Processを押せばデータがFbxに出力します。

**2、カメラモーション導入**
カメラモーション（.vmd）をUnityプロジェクトにインポートします。
右クリック→MMD2UnityTool→Export Camera Vmd To Anim

**３、Unity　Recorderを使ってモーションを録画（しなくてもいい、でもモーションは多少誤差があるかもしれません）**
使用しているモデルはRead/Write Enabledにチェックを入れるのを忘れずに
設定は画像を参考に
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667149/0d9482fc-e6d0-a22a-8074-485def182ac1.png)


**4、Oculus LipSyncを使って口の形状を音声に合わせる**
\Assets\Oculus\LipSync\LipSyncInterface.prefabのプリハブをsceneに置きます。
キャラクターにOVR Lip Sync ContextとOVR Lip Sync Context Morph Targetコンポーネントを追加します。
追加すると自動的にAudio　Sourceも追加されます。
OVR Lip Sync Context Morph TargetのSkinned　Mesh Renderにblendshapeが含めるMeshを入れます。
各口の形のblendshapeを指定します。
Element0－15：sil,PP,FF,TH,DD,kk,CH,SS,nn,RR,aa,E,I,O,U
参考画像はhttps://developer.oculus.com/documentation/unity/audio-ovrlipsync-viseme-reference/
普通はaeiouだけ入れればいいです。
blendshapeは表示順番で上から0番、1番、2番・・・
対応のblendshapeの番号を入れます。
![Image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667149/8dcf1214-8f22-7fae-e21f-8de6c105240a.png)

使用する音声をAudio　Sourceにいれます。
Audio　Sourceを含めるオブジェクトをOVR Lip Sync ContextのAudio　Sourceに入れます。
Audio　Loopbackにチェックを入れます。
OVRLipSyncContextMorphTarget.csの119列前後のVoid　Update（）をVoid　LateUpdate（）に修正します。

**5、これで実行すれば口は音声の通り動くはずです。**
可能であればUnity　Recorderでblendshapeのアニメーションを撮ったほうがいいですが、
自分はなぜか.animデータが出力されませんので、
一旦このまま使います。

（キャラの他のblendshapeアニメーションが付いた状況でOculus LipSyncを使っても問題なさそうです。）
そういえばLGTMがなくなっている

気づいたら消えてました。
あぁ...LGTM...
（画像は@KNR109さんの記事です。）

![5B1FE5C5-9689-427D-BE01-0B318F3E05F3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740290/d47fcd65-3e6c-211c-d1ea-cd47ae81a691.jpeg)
まあ、確かにこの方がわかりやすいかも。

===8月26日追記=================
同時にコメント欄も変わってました。
確かにこの方が、いただいたコメントにリアクションしやすいかも^-^
nuxt.jsの日付フォームで初期値を今日とする

nuxtでformを作成する時

```vue:nuxt.js
<input type=“date”/>
```

としますが
この初期値を
今日の日付にしたい

そんな時の記述です。

ちなみにデフォルトだと
yyyy/mm/dd
になります。

# 結論

![Screen Shot 2022-08-25 at 17.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2436967/49d55c0b-574c-99d5-87ac-21b4d378ac91.png)


```vue:nuxt.js
<template>
  <div>
    <input
      v-model="date"
      type="date"
    />
    <input
      type="date"
    />
  </div>
</template>

<script>
export default {
  data () {
    return {
      date: new Date().toISOString().substring(0, 10)
    }
  }
}
</script>

```

これでいけます。
UFWの設定方法

## はじめに
備忘録
タイトルの通りです。
実行環境はUbuntu20.04（bash）です。
どなたかのお役に立てれば幸いです。
## UFWのステータスを確認
以下のコマンドでUFWが起動しているかどうか確認してみましょう。
```bash
$ sudo ufw status
```
起動していない場合
```bash
Status: inactive
```
## UFWを有効化
UFWを起動してみましょう。
```bash
$ sudo ufw enable
```
:::note warn
「コマンドにより、既存のSSH接続が中断される場合があります。操作を続行しますか（y/n）？」
と出てきた場合には、必ず「y」で操作を続行してください。
SSHで接続している場合は、このままログアウトすると再度サーバーにログインできなくなる可能性があります。
サーバーの管理画面などから直接ターミナルを開いている場合（SSHをしていない場合）は関係ありません。
:::
有効化した後にもう一度
```bash
$ sudo ufw status
```
をしてみると、ステータスが「active」になっていることを確認できます。
## デフォルトを拒否に設定する
次のコマンドにより、サーバーへのアクセスをデフォルトで拒否することができます。
```bash
$ sudo ufw default deny
```
## 許可するポート番号を指定
SSH接続でよく使われる22番ポートを解放するためには次のコマンドを実行します。
```bash
$ sudo ufw allow 22
```
:::note
プロトコルを指定しない場合にはTCPとUDPがどちらも許可されます。
初期設定では、IPv4だけではなく、IPv6のルールも追加されます。
IPv6の設定を無効にする方法は[こちら](#ipv6の設定を無効にする)（この記事の下の方で紹介しています。）
:::
## プロトコルを指定
TCPを指定
```bash
$ sudo ufw allow 22/tcp
```
UDPを指定
```bash
$ sudo ufw allow 22/udp
```
## 許可するIPアドレスを指定
10.255.3.210から22番ポートへのアクセスを許可する場合
```bash
$ sudo ufw allow from 10.255.3.210 to any port 22
```
:::note
$ sudo ufw allow from 10.255.3.0/24 to any port 22
のようにサブネットマスクを指定することで、↑の例であれば10.255.3.xxxからのアクセスをまとめて許可することもできます。
:::
さらにプロトコルを指定
```bash
$ sudo ufw allow from 10.255.3.210 to any port 22 proto tcp
```
:::note warn
グローバルIPアドレスを持ったサーバーにローカルのIPアドレスからログインする場合、ルーターによりIPアドレスが書き換えられるため、サーバーに届くパケットの送信元はルーターのIPアドレスに変わっています。
つまり、IPを指定してUFWを設定する際に、ローカルのIPアドレスからのアクセスのみ許可したい場合には、ルーターのIPアドレスを指定する必要があります。
:::
## UFWのステータスを確認
これまでに設定したルール一覧を確認してみましょう。
```bash
$ sudo ufw status
```
番号付きで設定したルール一覧を確認
```bash
$ sudo ufw status numbered
```
## 番号を指定してルールを削除
1番のルールを削除
```bash
$ sudo ufw delete 1
```
## UFWをリロード
ルールを追加したり削除したりした後は再読み込みしておきましょう。
```bash
$ sudo ufw reload
```
## IPv6の設定を無効にする
/etc/default/ufwを編集
```bash
$ sudo nano /etc/default/ufw
```
```diff_conf:/etc/default/ufw
- IPV6=yes
+ IPV6=no
```
UFWを再起動
```bash
$ sudo systemctl restart ufw.service
```
IPv6を無効化できたか確認
```bash
$ sudo ufw status
```
# ブログもあります
https://kyit.net/how-to-set-up-ufw/
放物線補間で極値を求める。

(0,y0), (1,y1), (2,y2) を通る放物線を求めて、yが極大となるxを求める。

y = a * x^2 + b * x^1 + c とおく。

y0 = c
y1 = a + b + c
y2 = 4a + 2b + c
y1 - y0 = a + b
y2 - y1 = 3a + b
y2 - 2*y1 + y0 = 2a

a = 0.5 * y0 + 0.5 * y2 - y1
b = y1 - y0 - (0.5 * y0 + 0.5 * y2 - y1) = -1.5 * y0 + 2 * y1 - 0.5 * y2
c = y0

y が極大となる x は -b / (2a) で求められる。
未経験エンジニアが入社4か月で経験できたこと

## 始めに
4月からIT企業に未経験エンジニアとして転職をしました。

訳4か月が経った段階で、何を経験したのか。
棚卸ししたいと思います。

## 4か月で経験したこと一覧
弊社はベンチャー企業であり、未経験といえども上流から下流まで多くの仕事を任せてもらえます。
特に自分のプロジェクトは、作業者が自分一人という特殊な環境で、ほぼ全ての工程を任せてもらいました。
プロジェクトの概要は、ある企業がリリースするシステムのサービスサイトの制作でした。

以下作業内容を列挙します。

・設計から納品までのスケジュール作成
・XDを使用したデザイン作成
・お客様との打ち合わせ
・デザイナーさんとの打ち合わせ
・コーディング
・見積り作成
・提案資料作成
・プレゼン
etc

未経験ながら本当にたくさんのことが経験できました。
いつも不安そうな自分に任せてくれた、上司に感謝です。

## 未経験エンジニアってどんな感じ？
未経験ですので、上記列挙した仕事は全て初めてです。
取り掛かる前は不安で不安で、仕方がなかったです。
スケジュールやXDのデザイン作成は、何が正解なのか分からなくて戸惑い、
コーディングはちゃんと実装できるのかどうか毎日不安でした。

納期に間に合わせるために11時まで残って仕事をしたり、土日も作業をしたこともありました。

自分はコミュニケーションに苦手意識を持っていいたため、お客様との打ち合わせも不安で仕方ありませんでした。

しかし、やればできる。

なんだかんだ、無事納品することができました。

## 振り返って思うこと　
振り返って思うことは、やればできるってことです。

自分は小心者だし、頭の回転が早いわけでも、コミュニケーション能力が高いわけでもありません。

それでもやってみればできます。

分からなければ聞けば解決します。

コミュニケーションも慣れていきます。

不安に思う時間があるならば、きっと動いたほうが良いのだと思います。
挑戦した方が良いのだと思います。

## 今後成長したいこと
今後成長したいことは以下の３っつです。

・もっとロジックに強くなりたい
今回はサービスサイト制作ということで、フロントがメインのプロジェクトでした。
とはいってもページネーションや、アコーディオンなどロジックを考える場面もあり、大変苦戦しました。
もっとロジックを考えるようなプロジェクトに参画し、経験を積めば自信を持ってより良い仕事ができると思います。

・もっとコミュニケーションに慣れたい
コミュニケーションにもっと慣れ、もっと色んな人と関わりたいです。
今は苦手意識があるため、無意識で避けてしまっています。
コミュニケーションはエンジニアとしての仕事でも必要なスキルです。
今後は、もっとコミュニケーションの場に参加して、世界を広げたいです。

・もっと主体的に動けるようになりたい
自分から提案して、自分で決めて、自分で責任を取る勇気を持ちたいです。
自分は受身なタイプだと思います。
責任を取ることが怖いし、指示を待ってしまいます。
しかしそれでは、楽しくない。
やはり自分で主体的に動いてこそ、やりがいはあると思います。

## 楽しく働く
弊社が掲げるビジョンです。

楽しく働くってどういうことだろうと思います。

この4か月は楽しいというよりは、不安との戦いでした。

楽しくということはなかなか難しい。

そもそも楽しいとはなんでしょうか。

代表は主体的に動く、責任を持って動くことで楽しさは生まれると言っています。
そのために、一人一人に裁量を持たせている。と

主体性がキーのようです。

1年後、楽しいと思えるように、主体的に動く瞬間を増やしたいです。
【VSCode】スニペットの設定方法

## 設定方法

VSCodeを開いて画面左下の歯車アイコンをクリックします。  
「ユーザースニペットを構成」をクリックします。
![スクリーンショット 2022-08-25 13.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/f8f8cb9b-9568-9777-22bf-50d002873c27.png)
すると以下のように表示されますのでグローバルまたは対象の言語を選択します。
![スクリーンショット 2022-08-25 13.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/578f13e1-18a2-3e4d-41b8-21207668c2d6.png)
今回は「Markdown」を選択します。  

`~/Library/Application Support/Code/User/snippets/markdown.json`が作成されます。  
作成されたファイルに以下のように記述することでスニペットの設定ができます。  

```json :markdown.json
{

  "スニペットの名前": {
    "prefix": "キーワード",
    "body": "入力する内容",
    "description": "スニペットの説明"
  }

}
```

たとえば以下のように設定すると`sample`で`body`の文章が入力されます。

```json :markdown.json
  "sample": {
    "prefix": "sample",
    "body": "スニペットで入力された文章です。",
    "description": "スニペットの説明はここに表示されます。"
  }
```

![スクリーンショット 2022-08-25 14.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/cbedb4e4-0b87-41f3-7414-d2945e78d8ce.png)
上画像の状態でEnterを押すと文章が入力されます。
![スクリーンショット 2022-08-25 17.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/caf64a9c-8875-cefd-bd75-2301cc23f48e.png)

### 複数行のスニペット

`body`を配列で記述すると改行されます。

```json :markdown.json
  "sample": {
    "prefix": "sample",
    "body": [
      "1行目",
      "2行目"
    ],
    "description": "スニペットの説明"
  }
```

以下のように入力されます。

```markdown :sample.md
1行目
2行目
```

### タブの挿入

タブは`\t`で挿入できます。

```json :markdown.json
  "collapsible section": {
    "prefix": "collapsible",
    "body": [
      "<details>",
      "\t<summary></summary>",
      "</details>"
    ],
    "description": "折りたたみ可能なセクションの追加"
  }
```

### タブストップ

以下のようにすると入力された際に`$1`の箇所にカーソルが移動しTabで`$2`に移動できます。

```json :markdown.json
  "collapsible section": {
    "prefix": "collapsible",
    "body": [
      "<details>",
      "\t<summary>$1</summary>",
      "\t$2",
      "</details>"
    ],
    "description": "折りたたみ可能なセクションの追加"
  },
```

`collapsible section`の`body`が入力されると`$1`の箇所にカーソルが移動します。
![イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/2c275aaa-5921-a5c4-ee05-927ceca77780.png)
Tabを押すと`$2`に移動します。
![イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/469be98c-ea19-38f1-2f04-58027148e6ca.png)

初期値や変数も設定できます。
詳細については以下のページをご参照ください。

https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax

## 使用方法

### `キーワード + Tab`

設定したキーワードを入力してTabを押すことでスニペットを使用するには`setting.json`に以下のように記述します。

```json :setting.json
{
  "editor.tabCompletion": "onlySnippets",
}
```

特定の言語にのみ設定する場合には以下のとおりです。

```json :setting.json
{
  "[markdown]": {
    "editor.tabCompletion": "onlySnippets",
  },
}
```

## サジェスト

サジェストを利用してスニペットを使用するには`setting.json`に以下のように記述します。

```json :setting.json
{
  "editor.quickSuggestions": {
    "comments": "off",  // コメント部分
    "strings": "off",  // 文字列部分
    "other": "on"  // その他
  },
}
```

![スクリーンショット 2022-08-25 14.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/cbedb4e4-0b87-41f3-7414-d2945e78d8ce.png)
`editor.snippetSuggestions`を`top`に設定するとサジェストの上の方にスニペットを表示させられます。

```json :setting.json
{
  "editor.snippetSuggestions": "top",
}
```
軽くVitest + Typescript + React触ってみた

# vitest


## 概要
viteベースのテストライブラリーのvitestが素早いとのことで、本当か試してみました

## Installation and setup

viteでプロジェクト作成

```jsx
$ yarn create vite my-app --template react-ts
```

vitest導入

```jsx
$ yarn add -D vitest jsdom @testing-library/react @testing-library/user-event @testing-library/jest-dom
```

`vite.config.ts`を設定

```jsx
/// <reference types="vitest" />

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  ...
  test: {
    environment: 'jsdom',
    setupFiles: 'src/vitest.setup.ts'
  }
})
``` 

`vitest.setup.ts`では、`@testing-library/jest-dom`  などをimportしておく


## テストを書く

基本的なことから

```jsx
const add = (a: number, b:number) => a + b

describe('test add()', () => {
  it("1 + 2 = 3", () => {
    expect(add(1, 2)).toBe(3)
  })
})
```

コンポーネントのテスト

```jsx
import { render, screen } from '@testing-library/react'

const Title = ({ title }: TitleProps) => {
  return (
    <div>{title}</div>
  )
}

test('Rendering test: Title', () => {
  const title = 'Let\'s test with vitest!'

  render(<Title title={title} />)

  expect(screen.getByText(title)).toBeInTheDocument()
})
```

クリックイベントの違い

```jsx
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import App from '.'

describe('Component test: App', () => {
  test('click count should increment count', async () => {
    render(<App />)
    expect(screen.findByText(/count is 0/i))

    userEvent.click(screen.getByRole('button')))

    expect(await screen.findByText(/count is 1/i)).not.toBeEmptyDOMElement()
    screen.debug()
  })
})
```

## happy-domの方が軽かった

[https://github.com/capricorn86/happy-dom](https://github.com/capricorn86/happy-dom)

jsdomより早いらしいので、happy-domの導入方法

`vite.config.ts`を修正

```jsx
...
  test: {
    environment: 'happy-dom',
...
```

＊ `@testing-library/user-event` のバージョン上げで、参考記事に書いているような不具合は解消した模様

## スピードテスト

### Vitest(happy-dom)
![スクリーンショット 2022-08-25 16.33.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345464/5be5aacb-ea85-70a5-f622-14cc22a48603.png)


### Vitest(jsdom)
![スクリーンショット 2022-08-25 16.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345464/0831b7b1-6821-2527-6c02-a2669168d13f.png)


### Jest
![スクリーンショット 2022-08-25 16.33.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345464/f60f5cdb-d9a0-8537-2d13-3ff4a09dc63a.png)


あんまし大したケースを積んでないので厳正な比較になってるかわかりませんが、スケールしてみながら比較するのもありかもです

## 参考

テストするためのプロジェクトを作る時に参考にしたもの

[Vite + React + TypeScript に テスト環境 Vitest をステップbyステップで作る](https://zenn.dev/longbridge/articles/9d9ec773cb3814)

[あたらしいテストフレームワークVitestをReactで試してみた | DevelopersIO](https://dev.classmethod.jp/articles/intro-vitest/)

troubleshootingに役立った記事
https://dev.to/mbarzeev/from-jest-to-vitest-migration-and-benchmark-23pl
【ZipArchive】phpでディレクトリのファイルをzipで圧縮

# ディレクトリのファイルをzipで圧縮したい
phpでファイル圧縮をする場合はZipArchiveを使う場合があるのだが、ディレクトリ指定ができないので、ディレクトリ指定したい場合のやり方を書いておく

```php
<?php
$zip_file_name = "example.zip";
$zip = new ZipArchive();
$res = $zip->open('/path/to/put/zip/file/example.zip', ZipArchive::CREATE);
$files = glob("/path/to/files/*");
foreach ($files as $file) {
    $zip->addFile($file); // ファイル名を帰る場合は第2引数で指定可能
}
$zip->close();
```

難しくないコードです。
glob関数でファイル一覧を持ってきて圧縮しているだけです。ディレクトリ指定そのままできると便利と思ったのですが、できないみたいなのでメモ程度に残しておきます。
SSH ポート転送

# 8月25日
- MACからSSHでGCPに入る。GCP上のファイルにhttp::/localhost:3000 に入るために、ポート転送をする方法を知る。
```
ssh -L 5000:127.0.0.1:5000 example.com
```
[参考リンク](https://sunday-morning.app/posts/2020-11-03-ssh-multi-port-forward)
お手荷物「大谷大学2022年一般Ⅰ期第１問後編」をWolframAlphaでやってみた。


お手荷物体積最大,サイズ  合計：115cm以内,45cm×35cm×20cm以内

オリジナル

https://mathmathmass.exblog.jp/32177341/

# 参考

飛行機の座席数100席以上*　773/772（777）/359/789/788/767/738（73H）
＜機内持ち込みお手荷物（お手荷物） - JAL国内線
付属品（ハンドル、ポケット、キャスター等）を含みます。

https://www.jal.co.jp/jp/ja/dom/baggage/inflight/

（20220825）JAL-エラー
「現在、サーバが大変混み合っております。繋がりにくい場合は、時間をおいてから再度ご利用くださいますようお願い申し上げます。
JMBお得意様番号でのログイン中の方、並びに“ログイン情報を保持”機能をご利用の方におかれましては、次回接続時に改めてログインのお手続きが必要となる場合がございます。」

# WolframAlphaで
xyz 最大,x+y+z<=115 ,0<x<=55,0<y<=40,z=25

https://www.wolframalpha.com/input?i=xyz+%E6%9C%80%E5%A4%A7%2Cx%2By%2Bz%3C%3D115+%2C0%3Cx%3C%3D55%2C0%3Cy%3C%3D40%2Cz%3D25&lang=ja

# SymPy Liveで
(省略)
PipeRider 0.7.0 リリース

![piperider-spotlight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/799036bd-1aea-e60c-8fb0-9a2034e21b83.png)

# 0.7.0 リリースの概要

## BigQueryのサポート

```
pip install 'piperider[bigquery]'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/2355f010-e6a1-fb2b-0f05-434d8365c6e3.png)


https://docs.piperider.io/data-sources/bigquery-connector

## Redshiftのサポート

```
pip install 'piperider[redshift]'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/7412c452-1d5d-f8da-a98c-b60aa93d8637.png)

https://docs.piperider.io/data-sources/redshift-connector

## 他のデータソース

教えて下さい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/87c2a6a2-d551-72f7-686a-c7ce2341eeaa.png)

## 新たなレーポトデザイン

### ワンレーポト

[ライブ見本](https://piperider-github-readme.s3.ap-northeast-1.amazonaws.com/run-0.7.0/index.html)

![Recording #13.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/23958ebb-e011-41df-b814-8fa97b8b66b1.gif)

### 対照レーポト

[ライブ見本](https://piperider-github-readme.s3.ap-northeast-1.amazonaws.com/comparison-0.7.0/index.html)

![Recording #14 (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/9426d518-aa8e-3409-3620-06421d5f0676.gif)

## ハンズオン

https://docs.piperider.io/quick-start

https://github.com/InfuseAI/piperider
Poetryでinstallするpackageのversionを環境ごとに変更する方法

## 結論
Poetryの`environment-markers`という機能を使いましょう。

https://python-poetry.org/docs/dependency-specification/#using-environment-markers

## 直面した問題
`pyheif`というpackageをpoetryを使ってインストールしたいのですが、どうやら現時点(2022/8/25)ではm1 macだと以下エラーが出て動いてくれないようです。

```
EnvCommandError
'libheif/heif.h' file not found
```

https://github.com/carsales/pyheif/pull/45

そこでpyheifのissueにある[コメント](https://github.com/carsales/pyheif/pull/45#issuecomment-1130056328)の通り、m1-support修正のパッチが当たったversionを指定して`poetry install`すると次はm1 mac環境では動いたのですがEC2環境で`poetry install`できなくなりました。


## 解決法
この問題を解決するためpoetryの`environment-markers`という機能を使い、m1 mac環境でのみ修正が当たったversionを指定するよう以下のように`pyproject.toml`を書き換えました。

```python:pyproject.toml
pyheif= [
    {version = "^0.5.1", markers = "sys_platform != 'darwin'"},
    {git = "https://github.com/guillaumegenthial/pyheif.git", rev = "m1-support", markers = "sys_platform == 'darwin'"} # For m1 mac support. ref: https://github.com/carsales/pyheif/pull/45#issuecomment-1130056328
]
```

これで無事にEC2およびlocalのm1 mac環境でも無事`poetry install`が通るようになりました！

poetryでは他にも複雑な条件でinstallするパッケージを指定できるみたいです、条件によってinstallするpackageのバージョンを変更したいなどありましたらこの公式ページを参考にしてみて下さい。


https://python-poetry.org/docs/dependency-specification/

こちら会社の先輩(@soymsk)に教えていただきました👍
特定の文字列を含む行を削除する PowerShell

# 特定の文字列を含む行を削除する PowerShell
Microsoft Windows [Version 10] で確認。

~~~ LineExclusion.ps1
#===================#
# LineExclusion.ps1 #
#===================#
### 対象PATH ###
$path = "C:\Users\Desktop\test\json"

### Grep対象の文字列 ###
$str = """DELETE_FLG"":1"

### ファイル一覧取得 ###
$childItems = Get-ChildItem -Path $path | Select-String -Pattern $str | % { $_.Path }

foreach($item in $childItems)
{
    ### ファイル名の定義 ###
    $itemtmp = $item + ".tmp"
    $itemold = $item + ".old"

    ### 該当行を削除 ###
    sls -NotMatch $str $item | %{$_.Line} > $itemtmp
    echo "処理中：$item"

    ### ファイル名の操作 ###
    Rename-Item -Path $item -NewName $itemold
    Rename-Item -Path $itemtmp -NewName $item
}
~~~

ファイルから「"DELETE_FLG":1」を含む行を削除する PowerShell Program を作成しました。フォルダ一括で処理します。
構造化プログラミング

大きなプログラムを作成しようとすると大変なので、
上位で大まかな流れを書いて、下位に下ると具体的な処理が書かれている。
こうすることで階層ごとに流れを整理され、効率よく、ミスの少ないプログラムが出来上がる。

# 制御構造として使う３つのお約束
```順次```,```選択```、```繰り返し```の３つの制御構造がある。
この構造でプログラミングを行う。

### 順次構造
上から順に処理を行う。

### 選択構造
なんらかの条件によって分岐させ、いずれかの処理を実行する

### 繰り返し構造
ある条件が満たされるまで、一定の処理を繰り返します。

## 問題を解いた時の気づき
While文とは条件の後に処理を行うのか。
aws-cli を v1 から v2 に更新

aws コマンド を v1 から　v2 する機会があったのでメモ

## 環境
- EC2 Amazon/Linux

## 対応内容

※環境によって表示されるバージョンなど異なります

```console
# 現在のバージョンの確認
$ aws --version
aws-cli/1.11.30 Python/2.7.18 Linux/4.14.177-107.254.amzn1.x86_64 botocore/1.12.172

# 更新
$ sudo yum update aws-cli

# バージョンの確認
$ aws --version
aws-cli/1.18.107 Python/2.7.18 Linux/4.14.177-107.254.amzn1.x86_64 botocore/1.12.172

# aws-cli コマンドの削除
$ sudo yum remove aws-cli

# バージョンの確認
$ aws --version
１）結果が表示されない場合は 【成功】 > 「v2 インストール」に進む
２）結果が表示された場合は 【失敗】 > pip コマンドがインストールされていれば以下を試す

    $ which pip
    $ sudo pip uninstall awscli　
    $ aws --version
    結果が表示されなければ OK >  「v2 インストール」に進む

# v2 インストール
$ cd /tmp
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
１）以降の結果が以下の場合 【成功】
    Found preexisting AWS CLI installation: /usr/local/aws-cli/v2/current. Please rerun install script with --update flag.
    $ sudo ./aws/install --update
    You can now run: /usr/local/bin/aws --version
    $ /usr/local/bin/aws --version
    aws-cli/2.7.25 Python/3.9.11 Linux/4.14.177-107.254.amzn1.x86_64 exe/x86_64.amzn.2018 prompt/off

２）以降の結果が以下の場合、コマンドの反映に失敗した可能性があるため次を対応
　Found same AWS CLI version: /usr/local/aws-cli/v2/2.7.25. Skipping install.

    $ ls -la /usr/local/bin/aws*

    結果に「aws」や「aws_completer」が存在しない場合はリンクの作成に失敗していることが考えられる
　　　　　　　　その場合は手動でリンクをつなぐ
    $ sudo ln -s /usr/local/aws-cli/v2/current/bin/aws /usr/local/bin/aws
    $ sudo ln -s /usr/local/aws-cli/v2/current/bin/aws_completer /usr/local/bin/aws_completer

    バージョンの確認
    $ /usr/local/bin/aws --version
    aws-cli/2.7.25 Python/3.9.11 Linux/4.14.177-107.254.amzn1.x86_64 exe/x86_64.amzn.2018 prompt/
```
フォノンの分散関係をプロットしてみたよ

# フォノン
フォノンとは格子振動を量子化したものである。
運動エネルギーが大きい物質は早い速度で運動しているだろう。同じ重さの物質の運動エネルギーの大小を比較したければ、速度を比較すればいいわけだ。では、温度が異なる物質同士の持っているエネルギーの違いは何を比較すれば良いのだろうか。温度が高い物質は加熱されることで得た熱エネルギーをなんらかの形で物質中に取り込んでいるはずだ。それこそが熱振動である。温度が高い物質は、温度が低い物質に比べて構成粒子の原子や分子が激しく振動しているのだ。
さて、熱エネルルギーは温度が高いところから低いところへと移動する。これは、熱振動が結晶格子を伝播していく過程とみなせる。格子振動の伝搬は波のような性質を持つであろうが、量子物理学において電磁波の波である光をフォトンの粒子として考えることができるのと同じように、格子振動の伝搬もフォノンの粒子として考えられるだろう。

なにやら難しいことを書いてはみましたが、原子レベルの熱エネルギーの移動とかを考えるときはフォノンについて考えれば良いってことなのでしょう。実際、フォノンの平均速度$ v$と平均自由工程$ l$を用いると物質の熱拡散率$ \alpha$は次のような非常に簡単な関係式で表されます。

$ \alpha = \frac{1}{3} v l$

とても美しいですね。$ v$と$ l$が分かると物質全体の熱物性が分かるのだ。フォノンって分かると便利なんですね。この式についての導出は省略いたします。キッテルを参照してください。
・Charles Kittel著、宇野良清 津屋昇 新関駒二郎 森田章 山下次郎 共訳「キッテル固体物理学入門」第8版、丸善出版、2015

# フォノンの分散関係

物質中のフォノンの挙動を理解するにはなにが分かればいいのでしょうか。結局は波なので波数$ K$に対する分散関係$ \omega$の関係式を導出すれば良い。この関係式を次に示す。これも詳細はキッテルをご参照ください。

$ \omega^2 = \frac{4 C}{M} \sin^2(\frac{1}{2}K a)$

質量Mの原子が間隔$a$で一列に並んだときのフォノンの分散関係が上の式である。$ C$は原子間のバネ定数である。

ここから$ v$の方は比較的簡単に計算ができて、分散関係の波数の微分値が群速度$ v$となる。

$ v = \frac{d \omega}{d K}$

# プロットしよう

プロットしてみましょう。扱っている内容は難しいが、プロット自体は簡単である。

```Python
import matplotlib.pyplot as plt
import numpy as np

C = 1
M = 12
a = 2

K = np.linspace(-2*np.pi/a, 2*np.pi/a, 10000)

omega = np.abs(np.sqrt((4*C/M))*np.sin(0.5*K*a))

fig = plt.figure()
ax = fig.add_subplot(111)

plt.plot(K,omega)

ax.set_xlabel('K', fontsize=20, color='black')
ax.set_ylabel('$\omega$', fontsize=20, color='black')
```

今回は$C = 1$, $M = 12$, $a = 2$として、$K$が$- \frac{2 \pi}{a}$から$\frac{2 \pi}{a}$の範囲でプロットしている。実行結果がこちらです。

![omega.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2804113/292d34b6-df2d-0324-824b-71285ff35756.png)

うん、いい感じです。

値は物理的に意味のある正の値のみを採用しているので$ \omega$の周期は$\frac{2 \pi}{a}$となります。今回、$K$の描画範囲は$- \frac{2 \pi}{a}$から$\frac{2 \pi}{a}$としていますので2周期分プロットしてます。さっきの式からこの傾きが群速度になるのだということがわかります。$K = 0$付近の群速度が最速で、$K = \pm \frac{\pi}{a}$の群速度が最低速度ということになるのかと思います。

フォノンの分散関係がわかったところで物性との関係をつけるのは難しいですが、とりあえず今日のところは分散関係がプロットできたので良しとします。
python 可変長引数

まず初めに、可変長引数について説明しよう。
可変長引数とは、自由に引数の大きさを変更できる引数である。
簡単に例を出して説明すると、
nameという一つの引数だけでリンゴ、イチゴ、メロンといった３つのデータをnameという
一つの引数に入れることが可能となる。

可変長引数は2種類あって、args型と**kwargs型が存在している。
agrs型は先ほど説明したような形です。**kwargs型はディクショナリを用いたもので少し
さっき説明したものとは異なる特徴を持つ。
Ubuntuをバージョンアップしたらkazamが使えなくなったので使えるようにした

# Ubuntuをバージョンアップしたらkazamが使えなくなったので使えるようにした

## 主訴：Ubuntu20.04からUbuntu22.4にバージョンアップした後kazamが使えなくなった

- 症状：kazam本体は起動するが動画のキャプチャをしようとしたとき、録画開始のカウントダウンが表示されず、録画ができない。
- その他：保存フォルダには中間ファイル`.movie`（0byte）ができている。正常に終了させることはできる。

## 対応

`$HOME/.config/kazam/kazam.conf` を削除
Ubuntu で core ファイルが出力されない

# core がない
備忘録です。
~~~text:ubuntuバージョン
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
~~~
**(1) コアファイルの出力先**
apport障害情報ツールになっていますので変更します。
~~~text:出力先の確認
$ sysctl -a | grep core_pattern
 ...
kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P %E
~~~

tmpに出力、ファイル名は任意で変更 （tmpは再起動でクリア）
~~~text:出力先の変更
sudo sysctl -w kernel.core_pattern="/tmp/core_%e_%p_%t"
~~~

**(2) コアファイルのサイズ**
が0なので出力されません
~~~text:サイズの確認
$ ulimit -c
0
~~~
無制限に設定
~~~text:サイズの設定
$ ulimit -S -c unlimited
$ ulimit -c  # 確認
unlimited
~~~

**(3) コア生成**
hoge落とす Segmentation fault (コアダンプ)
~~~text:core 確認
$ ls core*
core_hoge_2297_1661404598
~~~
あとは gdb でデバッグですね。

~~~text:gdb
$ gdb hoge core_hoge_2297_1661404598
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
...
~~~
なぜ我々はコードを書くのか

興味深かったので訳しました。著者はDomino Data Labのアナリストの方です。

https://www.linkedin.com/pulse/why-we-code-thomas-w-dinsmore/

![](https://media-exp1.licdn.com/dms/image/D4E12AQEeG8z2rKeT8A/article-cover_image-shrink_720_1280/0/1661347030359?e=1666828800&v=beta&t=ZMod35pzqI91YYG011vzhZzte4JD1JnDBZ-QbOu5_II)

「コードファーストのデータサイエンスは賢明ではない」ベンダーの宣伝を一日中聞いているのだとしたら本当なのだろうと推察します。本当のデータサイエンティストと会話すれば、彼らがなぜコードを書いているのかを知ることでしょう。以下にそれらのいくつかを示します。

**スピード** 1行のコードを書くのは数行です。「ノーコード」ツールは遅いです。メニュー、サブメニュー、サブサブメニューをクリックします。キャンバスにオペレーターをドラッグします。右クリックしてオペレーターを設定します。

コードの書き方を知っているのであれば、「ノーコード」ツールの操作は地獄で暮らすようなものです。

**機能性** コードは「ノーコード」ツールよりもリッチであり、多くの場合、5倍から10倍豊富です。同じソフトウェアにおいて、ドラッグ&ドロップのUIとコードベースのAPIを比較してください。ソフトウェアの開発者は、「ノーコード」インタフェースに組み込む前にAPIに新機能を組み込みます。多くの機能はノーコードバージョンに取り込まれることはありません。これは、数多くのオペレーターをグラフィカルなUIに取り込むには制限があるためです。

**柔軟性** 「ノーコード」ツールは一部の機能しかサポートしていないため、開発者は重要と考えるものにフォーカスします。シンプルな分析を行っているのであれば問題ありません。そうでなければ不幸なことになります。コードは無制限の柔軟性を持っています。これが、データサイエンス向けのすべての「ノーコード」ツールに、ユーザーがコードを挿入できるような「コードノード」機能がある理由です。

私は、ワークフローのそれぞれのシングルノードがコードノードである「ノーコード」ツールで作業が行われたのを見たことがあります。

**透明性** コードはありのままであり、検査に対してオープンです。「ノーコード」ツールではこれは常に真となりません。データサイエンティストは、自分の作業の精度に対して説明責任を持ちます。分析が適切ではなかったとしても、ツールに文句を言うことはできません。コーディングをしているのであれば、データから洞察に至る処理パイプラインは完全に可視化されます。

**効率性** 誰もゼロからコーディングはしません。データサイエンスチームは再利用なコードのコンポーネントを整理し、共有します。実行性能を改善し、計算インフラストラクチャに対するインパクトを最小化するために、コードを調整、チューニングすることができます。これはノーコードツールでは不可能です。

コードを取り扱うことは、AutoMLのようなイノベーションの取り扱いを除外することではありません。すべての先進的なAutoMLツールはコードベースのAPIをサポートしています。ベストなAutoMLツールは拡張可能です。エキスパートのデータサイエンティストはアルゴリズムにコードを追加できます。多くのAutoMLツールは、エキスパートがレビュー、修正、チューニングできるようにコードパッケージとしてパイプラインを提供します。

コーディングスキルは恐ろしいものではありません。Pythonスキルを持つ人材プールは、経験のあるデータサイエンティストのプールを上回っています。もちろん、Pythonの知識でデータサイエンティストになれる訳ではありません。データサイエンティストには、プログラミング以上の知識とスキルが求められます。しかし、これがまさにポイントであり、コーディングスキルはデータサイエンティストの供給を制限する重要なボトルネックではありません。

「コードファースト」のデータサイエンスは、高速、機能的、柔軟、透明で効率的です。コードを取り扱うデータサイエンティストは、機械学習と人工知能において最も先進的なイノベーションを活用することができます。すべての有望なデータサインティストは、すでに少なくとも一つのプログラミング言語を知っています。多くは多言語を取り扱っています。

いくつかのタスクでは「ノーコード」ツールは好適なものです。例えばグラフィックやダッシュボードです。データサイエンティストは、多くの場合必要に応じてコードベースツールとこれらのツールを組み合わせて活用しています。また、「ノーコード」ツールはシンプルな分析では優れていると言えます。多くのマネージャーとアナリストは「ノーコード」ツールを好みますが、これは問題ありません。

しかし、マネージャー、アナリストとデータサイエンティストを混同しないでください。もし、私が電球をねじ込めるとしても、これは「シチズンの電気技師」とは言えません。電球を持っている住人に過ぎません。
[Delphi] グループ化された定数の定義

# Delphi の定数定義

普通 Delphi で定数を定義する場合は

```pascal
const 
  FOO = 100;
  BAR = 200;
begin
  const BAZ = 'リコリス'; // インライン定数宣言
end;
```

みたいにしますよね。
（大文字にするかどうかは別）

でも、あるまとまりを持った定数を定義したい場合があります。
例えば

```pascal
const
  CMD_FOO = 'foo';
  CMD_BAR = 'bar';
  CMD_BAZ = 'baz';
```

みたいな時です。

# 定数を record でグループ化

高度な recrod 型は class と同じようにメンバーとして定数を持てます。
それを利用して、こんな風に定数があるだけの record を定義できます。

```pascal
type
  TCMDConsts = record
  public const
    FOO = 'foo';
    BAR = 'bar';
    BAZ = 'baz';
  end;
```

使う時は

```pascal
if Foo = TCMDConsts.FOO then
  Writeln('Command is foo');
```

のように、「レコード名.定数名」でアクセスできます。
グループ化されて解りやすい！

# 定数を一箇所にまとめる

定数が必要な時に都度 定数を宣言してもいいのですが、多人数で開発する場合「この定数どこで定義されてんねや！」ってなる事があります。
こういう場合は uConstants という Unit を作って、そこに全ての定数を定義すると見つけやすくなります。

その時に力を発揮するのがグループ化された定数です。
例えば

```pascal
type
  // フォームの定数
  TFormConsts = record
  public const
    MAX_WIDTH = 1920;  // 最大幅
    MAX_HEIGHT = 1024; // 最大高さ
  end;

  // API コマンド
  TAPICommandConsts = record
  public const
    LOGIN = 'login';           // ログイン
    GET_INFO = 'getinfo.json'; // 情報取得
    SET_AVATAR = 'setavatar';  // アバター設定
  end;
```

の用にグループ化することで１つの Unit に定数がまとまっていても見やすくなります。
とはいえ、使うところと定義するところが離れてしまうので逆に解りづらい場合もあったり無かったり…

# まとめ
定数をたくさん定義する場合、record 定数にしてみるのも１つの手です。
【IT基礎】Coockieとは何か？


WEBサイトにアクセス時に現れる **「Cookie取得に同意をしてください」**
「ユーザー情報を保存する仕組み」といったふわっとした理解でしたので、深掘りしてみます。
間違っている箇所があればご指摘頂けると幸いです。

Cookieとは何か？🍪
---
CookieとはWebブラウザに保存された情報(テキストファイル)です。

#### どんな情報が保存されるの？
ユーザーに関する情報
・ユーザID、端末ID
・IPアドレス
・ログイン情報
・ブラウザ、選択言語など

ユーザーのアクティビティ
・購入商品
・ページの閲覧記録
・Webリファラーなど

Cookieはどこに保存されるの？
---
Cookieはユーザー端末に保存されます。
Google Chromeの開発ツールのアプリケーションを開くとCookieが保存されていることが確認できます。

Cookieは何のために使われるの？
---
大きく分けて2つあります。

1つ目は、ユーザーがWebサイトをより便利に使用できるようにユーザーがどのようにサイトを使用しているか追跡します。例えば、サイトの言語を英語にした場合、Cookieはそれを覚えてくれるので、再訪したときも英語でサイトを表示してくれます。他にもショッピングサイトなどで、閲覧した商品情報を保存してくれたりもします。

2つ目は、上記のユーザー情報を元に企業がマーケティングで利用します。

どんな種類のCookieがあるの？
---

Cookieには2つのタイプがあります。
Session CookieとPersistent Cookieです。
Session cookieは情報を一時的に保存します。ユーザーが"session"から抜けると情報も削除されます。
Persistent cookieはユーザーの端末(スマホやパソコン)に保存されます。これらのCookieは、有効期限まで端末に保存されます。

キャッシュとは違うの？
---
キャッシュはWebサイトのページ情報を保存します。
ユーザーがサイトを再訪した際に、Webサイトの表示スピードが上がります。

Web制作でcssや画像を更新したのにブラウザでは更新されていないという時がよくありますが、これもキャッシュが保存されているからです。

以上、簡単ですがクッキーについて調べてみました
Accessで日時の加算減算

# やり方

DateAdd()を使う。
〇日前としたければ第二引数を負にすればいい。

```sql:DateAdd()でよく使う指定の動作確認
SELECT 
NOW() AS [現在日時],
DateAdd('yyyy', 1, NOW()) AS [現在日時から1年後],
DateAdd('m', 1, NOW()) AS [現在日時から1ヶ月後],
DateAdd('d', 1, NOW()) AS [現在日時から1日後],
DateAdd('h', 1, NOW()) AS [現在日時から1時間後],
DateAdd('n', 1, NOW()) AS [現在日時から1分後],
DateAdd('s', 1, NOW()) AS [現在日時から1秒後]
```

```sql:DateAdd()であまり使わない指定の動作確認
SELECT 
NOW() AS [現在日時],
DateAdd('q', 1, NOW()) AS [現在日時から四半期後],
DateAdd('y', 1, NOW()) AS [現在日時から1年間通算日後],
DateAdd('w', 1, NOW()) AS [現在日時から1週日後],
DateAdd('ww', 1, NOW()) AS [現在日時から1週後]
```

# 1月31日の1ヶ月後はどういう結果になる？

```sql
SELECT DateAdd('m', 1, '2020/01/31') 
```
上記の結果は2021/02/29。

うるう日が考慮された2月の月末日が返ってくる。
2021/03/02とはならない。
まして2021/02/31なんていう存在しない日付が返ってくることもない。


# うるう日の1年後はどういう結果になる？

```sql
SELECT DateAdd('yyyy', 1, '2020/02/29')
```

上記の結果は2021/02/28。

うるう日が考慮された2月の月末日が返ってくる。
2021/03/01とはならない。

# 蛇足

『一定期間経ったらファイル削除』なんて時は『〇日後』と要件定義した方が楽。
『〇月後』『〇年後』だと『月ごとに月間日数が違う』や『うるう年』の考慮が面倒。

# 参考サイトさん

https://www.feedsoft.net/access/guide-query/guideq70.html

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
Microsoft Access for Microsoft 365 MSO (バージョン 2207 ビルド 16.0.15427.20166) 32 ビット

TODO:AccessにはNOW() + INTERVAL 3 DAYのような構文があるのか調べる。
UE AIメモ


大体こんな感じ？

↓を確認する
https://www.youtube.com/watch?v=1Dm1G6fUuFs

**Composite**でAIの処理の流れを作成する
**Task**で基本的にやらせたいことを作成する
**Service**でBlackboardのデータ更新を監視する
**Decorator**でTaskが十港可能か判断する


# Composite
>Composite ブランチのルートを定義し、そのブランチの実行方法の基本的なルールを定義するノードです。デコレーター を適用すると、ブランチへのエントリの変更や、実行中にキャンセルができるようになります。また、コンポジットの子が実行されている場合にのみアクティブになる サービス を追加することもできます。 

## Selector
処理を選択する

## Sequence
処理を順番に行う

# Task
https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeNodeReference/BehaviorTreeNodeReferenceTasks/

> ビヘイビアツリー エディタで利用可能な Task ノード について説明します。タスクは、AI の移動やブラックボードの値の調整などを「行う」ノードです。それらには、デコレーターまたはサービスをアタッチすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/cff641b9-a3e2-8f0c-4c5f-cfeda9fa17c8.png)
それぞれFinishを呼び出す必要がある


# Service
https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeNodeReference/BehaviorTreeNodeReferenceServices/

> サービス は、Composite ノードもしくは Task ノードにアタッチされ、ブランチの実行中に定義された頻度で実行されるノードです。多くの場合、ブラックボードの確認や更新に使用されます。これらは、他の Behavior Tree システムの従来の Parallel ノードに代わるものです。

# Decorator
https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeNodeReference/BehaviorTreeNodeReferenceDecorators/


> 他の Behavior Tree システムで条件式としても知られる デコレーター は、Composites または Task ノードのいずれかにアタッチされ、ツリーのブランチあるいはノード 1 つでも実行可能かどうかの判断をします。


リファレンス

https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeNodeReference/BehaviorTreeNodeReferenceDecorators/


https://www.youtube.com/watch?v=Wm-QhSb5A1Q

Blackboard Based Condition


# BlackBoard

BlackboardにKeyをセットするときに
使用するService側でKeyの情報をセットしておかないとデフォルトの「SetActor」がセットされてしまう。
Keyが更新されない、SetActorになっているときはここの設定をチェックする


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/d0a46afe-0b82-a4b1-336c-477a27588ee9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/d1e5ad95-e8b2-7f2d-0aa7-00097fc47a9f.png)




# Rotate to face BB entryタスクで回転しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/08f67d43-608d-8063-2d76-a2fc6f4d87e7.png)

CharacterMovement
「Use Controller Desired Rotation」にチェック
「Rotation Rate」のYawで回転の速度調整