OmniAICreator/Qiita-1.07M huggingface dataset:
htmlの基礎　マークアップ


HTMLは文書の意味をコンピュータに伝えるためにタグを使って記述する。

例
&lt;h1&gt;世界について&lt;/h1&gt;

&lt;p&gt;ここは段落です。ここは段落です。&lt;/p&gt;
この例ではh1は大見出しを意味するタグ。
pは段落を意味するタグ。

このようにHTMLは見た目のためにタグを使うのではなく、意味に合わせてタグを使う。

それぞれの呼び名
　&lt;h1&gt;は「開始タグ」
　世界について は「コンテンツ」
　&lt;/h1&gt;は「終了タグ」
開始タグ、コンテンツ、終了タグまでを要素という。

コンテンツをタグで囲んで要素を作る事をマークアップという。
APKのサイズを約80%削減した

# TL;DR

- 結果

```
# ls -l *.apk
-rwxrwxrwx 1 kabocha kabocha 293997572 Nov 14 20:22 original.apk*
-rwxrwxrwx 1 kabocha kabocha 289364774 Nov 14 20:54 minifyEnabled_shrinkResources.apk*
-rwxrwxrwx 1 kabocha kabocha  97902257 Nov 14 21:34 abiFilters.apk*
-rwxrwxrwx 1 kabocha kabocha  49605621 Nov 14 22:48 extractNativeLibs.apk*     # 最終結果
```

(49605621/293997572)*100 ≒ 16.87...


- `app/build.gradle` で，`ndk.abiFilters` を指定

```
android {
    defaultConfig {
        // arm64のみサポートする．
        ndk {
            abiFilters 'arm64-v8a'
        }
```

- `AndroidManifest.xml` で `application.android:extractNativeLibs` を `true` に指定
- `app/build.gradle` で，`buildTypes.minifyEnabled, buildTypes.shrinkResources` を `true` に指定

# APKサイズがでかいんじゃ
かぼちゃです．普段，Androidの組み込みエンジニアとして働いています．

Google Play Storeに新規で公開するには，Android App Bundle でないといけなくなりましたので，そろそろAPK自体使われなくなりそうな風潮もありますが，組み込みAndroidにおいては，プリインストールする際などには，ソースコードもしくは，APKが必要です．

さて，お仕事の中で，取り込んでいるAARやライブラリの都合で1つのAPKだけで，300MB近いものをプリインストールしなければならない事態になりました．
もちろん，技術的には問題ありませんが，例えばFOTAでそのアプリを更新するとなると，その分の差分が大きくなりますので，ユーザーが負担する通信コストも肥大化してしまいます．
（Androidの差分FOTAは非常に優秀なので，そこまで大きくはなりませんが．．．）

こういった背景から，このでかすぎるAPKのサイズを，小さくしていく中で，特に効果的だったものを書かせていただいています．
なお，今回は実装の変更等はせず，設定周りだけを修正していますので，取り込みやすいかもしれません．また前提として，今回は Android StudioでGradleを使って，ビルド・開発するものとします．

# ndk.abiFilters (およそ 67% 削減)
NDKで開発されたことがある人は，ご存知かもしれません．Android Developerから引用すると，

> Gradle はデフォルトでは、NDK がサポートするアプリケーション バイナリ インターフェース（ABI）の個々の .so ファイルにネイティブ ライブラリをビルドし、それをすべてアプリにパッケージ化します。Gradle を使ってネイティブ ライブラリの特定の API 設定のみビルドしてパッケージ化したい場合は、下記に示すように、モジュール レベルの build.gradle ファイル内で ndk.abiFilters フラグを使って指定できます。

とあります．つまり特に指定とかをしていない場合だと，エミューレータでも動くように，`x86_64` 向けなどの `.so`ライブラリをビルドして，APKに入れてしまっているわけですね．
一般的なAndroidデバイスだと，arm系がほとんどだと思いますので，削れそうです．（Google Play Store等に公開するときは怒られる気がします．）
まして，私のような組み込みAndroidの場合，極端な話動作保証をするハードウェアが限られてきますので，不要な構成をビルドする理由はなさそうです.
`arm64-v8a` のみを対象にしてビルドしてみると，適応前のおよそ33%にまでバイナリサイズを抑えることができました．

およそ290MB → およそ98MB

## 参考，引用
- https://developer.android.com/studio/projects/gradle-external-native-builds?hl=ja#specify-abi
 
# application.android:extractNativeLibs (およそ 50% 削減)
Android Developerから引用すると

> パッケージ インストーラがネイティブ ライブラリを APK からファイル システムに抽出するかどうかを指定します。false に設定した場合、ネイティブ ライブラリは、ページ アライメントを行ったうえで、圧縮せずに APK 内に保存する必要があります。実行時にリンカーが直接 APK からライブラリをロードするため、コードを変更する必要はありません。

とあります．いかにも，デフォルト `true` のような記述になっていますが，[Android Gradle プラグイン 3.6.0 のリリース](https://developer.android.google.cn/studio/releases/gradle-plugin?hl=ja) を確認すると，デフォルトで `false` にしているという記述がありました．これも，APKサイズが大きくなってしまう原因となっているようなので，有効にしました．

およそ98MB → およそ50MB

## 参考，引用
- https://developer.android.com/guide/topics/manifest/application-element
- https://developer.android.google.cn/studio/releases/gradle-plugin?hl=ja


# buildTypes.minifyEnabled, buildTypes.shrinkResources （およそ 数MB 削減）
説明はDeveloperサイトで行われていますので，割愛します．

## 参考
- https://developer.android.com/studio/build/shrink-code?hl=ja

# 終わりに
結果として，もともとの15%近いAPKサイズにまで小さくすることができました．
もちろん，APKに占める割合にリソースファイルが大多数のときなどは，今回のアプローチだけでは難しいですが，一助になれば幸いです．
外部ネットワークからのPingを可能にするWindowsFirewall設定で躓いたはなし（Win10のみ？）

###ネットワーク実習でWindowsFirewallにつまずいた話
![空白の図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/1e0a83ba-05b4-9d27-20fd-9f917c9f46e0.png)
上記のようなネットワークを作成して実際にPingを通そうと思ったのですがここで問題発生です。
Pingが通らない！

インターネットであれこれ調べているとどうやらWindowsFirewallが原因であることがわかりました、
WindowsFirewallの設定画面はWindows内の検索（WindowsKeyを押して出てくるやつ）で”Windows Firewall”と検索すれば出てくると思います。
![mat1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/94b3f0db-9c84-3950-429e-2855b622fae9.png)

参考にした記事にあるように以下の規約を有効化してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/28c9e137-960c-7608-7f08-cc160f65947f.png)
が、Ping通らず！
それもそのはずこの規定の規約、Windows10の場合はスコープのリモートIPアドレスがこれらのIPアドレスにチェックが入っておりまた何のアドレスも登録されていない状態になっていました。（Windows11で確認したところ最初から任意のIPアドレスになっていました、Win10のみ？）
同一ネットワーク内からのPing　＝＞　許可
同一ネットワーク外からのPing　＝＞　遮断
の状態になっているということです。
リモートIPアドレスの乱で任意のIPアドレスにチェックを入れたら問題なくPingが通過するようになりました。
この記事が少しでも参考になれば幸いです。
SSMSでインテリセンスのリロード

## 新規作成のテーブル名を入力すると、赤線が表示される！

SSMS(SQL Server Management Studio)を利用していると、
赤い波線が表示されることがあります。
誤った列名や構文エラーについて表示されるマークですが、
新規テーブルや列名を入力したときも同様のエラーが表示されます。

SSMSを再移動するのも面倒です。
そんなときは以下の方法を実行しましょう！

## [編集] － [IntelliSense] － [ローカルキャッシュの更新]

画面上の**編集(E)**から、**IntelliSense**に移動し、
**ローカルキャッシュの更新**をクリックするだけ。
ショートカットだと「Ctrl + Shift + R」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/73ffed33-5efd-430c-a752-17ffe8db085b.png)

とっても便利です！
UITextField　.keyboardType メモ　

#今回の内容

* `.keyboardType`のメモ

##.keyboardType = .numbersAndPunctuation

<img width="150" alt="51D715A3-4507-4367-9F66-30221F2031A6_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/30d13ccb-ecc4-ef69-770a-75e08cac8411.jpeg">



##.keyboardType = .numberPad

<img width="150" alt="8D5EB7D4-80A7-47BB-8D2E-EB45E561CA75_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/2e4a53b9-7563-df0b-e90d-b684f78b8c26.jpeg">


##.keyboardType = .phonePad

<img width="150" alt="948789EB-B70D-4C58-AA40-7DDA916BC688_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/7e46615f-8715-aa35-032d-8f0d360125bc.jpeg">


##.keyboardType = .webSearch

<img width="150" alt="CB94D88A-19E7-4654-B878-5586253A36F9_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/d99bf078-3844-84d9-e449-46e21802f03d.jpeg">


# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
Rust でコマンドライン引数を数値として受け取る

# Rust でコマンドライン引数を数値として受け取る

コード

```Rust
use std::env;
use std::num::ParseIntError;

fn main() {

    let args = env::args()
        .skip(1)
        .map(|str| str.parse())
        .collect::<Result<Vec<i32>, ParseIntError>>();

    let args = match args {
        Ok(list) => list,
        Err(_) => {
            eprintln!("Input Numbers");
            process::exit(1);
        }
    };

    println!("{:?}", args);
}
```

## 説明

env::args() でコマンドライン引数を取得できます。String のイテレータです。
一つ目にプログラム名が入ってるので skip(1) します。
map でそれぞれの値を変換します。
何に変換するかは collect で指定してます。
失敗した場合は、ParseIntError です。

##参考
https://doc.rust-jp.rs/book-ja/ch12-01-accepting-command-line-arguments.html
https://doc.rust-lang.org/stable/std/string/struct.String.html#method.parse
https://doc.rust-lang.org/stable/std/str/trait.FromStr.html
https://doc.rust-lang.org/std/num/struct.ParseIntError.html
MacでもMultiTailで日本語ファイルをtail -fしたい

#Multitailって？
ログを監視しておく用途などで、`$ tail -F`や`$ less +F`など使っている方も多いかと思います。

複数のログファイルを追いたいけどウインドウたくさん開くのもめんどい、というときに便利なのがこのMultiTail。

https://qiita.com/Brutus/items/3e6425c84142902da376

#Macでは日本語ファイルを読み込むと文字化けする
Homebrewにもあるので、普通は`$ brew install multitail`すれば良いのですが、そのままでは日本語のファイルを読み込むと意図通りの表示してくれません。

そこで、ソースからビルドしてみましょう。

※ 数ヶ月前にオリジナル版の開発が終わってしまったようなので、他所からソースは拝借しました。

#Makefileの修正例
まずは準備から。

pkg-configやncursesが入っていないときはまずインストール。

```shell
$ brew install pkg-config ncurses
```

最新版のソースを頂いてきます。

```shell
$ curl -O https://distfiles.macports.org/multitail/multitail-6.5.0.tgz
```

展開して移動します。

```shell
$ tar xvfz multitail-6.5.0.tgz
$ cd multitail-6.5.0
```

お好きなエディタでMakefileを修正します。

```shell
$vim Makefile
```

34行目あたりに以下を追記しましょう。

```Makefile
CFLAGS+=-I/usr/local/Cellar/ncurses/6.2/include
LDFLAGS+=-L/usr/local/Cellar/ncurses/6.2/lib -lpanelw -lncursesw
CPPFLAGS+=-DUTF8_SUPPORT
```
バージョンはご自身の環境に合わせてください。（パスはHomebrew版のncursesを想定してます。）
※ vimをお使いの場合は、`i`キーで挿入モードになり編集でき、終わったら`esc`でモードを抜け、`:wq`を打ってreturnし、上書き保存してvimを抜けましょう。

ではビルドしてみます。

```shell
$ make install
```

どうでしょうか、正常に終了したでしょうか。
もしここで`waddnwstr`についてerrorがでてしまった場合、

```
$ vim /usr/local/Cellar/ncurses/6.2/include/ncurses.h

205: #define NCURSES_WIDECHAR 0
を1に変えて上書き保存。
※ コンパイル後に戻しておく。

$ make clean
$ make install
```
で再度試してみてください。

これで、日本語対応のMultiTailが使えるようになるかと思います。
MultiTailの使い方はたくさん記事が出ていますので割愛します。

自分はMac miniをサーバー代わりに使っていろいろログを書き出しているので、Multitailは重宝しています。

##削除方法
いらなくなったときは通常の手順で削除できます。
その時のために`multitail-6.5.0`のディレクトリは残しておくと良いかと。

```shell
$ cd multitail-6.5.0
$ make uninstall
$ make clean
```
【Rails×Vue.js】日本語化した曜日を表示して紐づいたデータを表示する

https://qiita.com/Yuya-hs/items/6265f1aba1a73f38047a
の続きです。
上記記事の「準備」が済んでいる前提です。

曜日を表示して（月、火、水、木、金、土、日）、それに紐づいたデータをvueのテンプレートに表示する方法です。
テンプレート内にjavascriptのメソッドを記入することで実現します。

#実現したいこと

ユーザーが作成したanswerというモデルについて各曜日に何個のanswerを作成したか表示できるようにしたい。

完成イメージ(プログレスバーを使用しています）

![スクリーンショット 2021-11-14 23.00.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1640672/7fadbb8c-8273-4efa-f302-db9dcb577a5a.png)
スクリーンショット 2021-11-14 23.00.07

#rails側の実装

```
//users_controller

def show
    @wdays = ['(月)','(火)','(水)','(木)','(金)','(土)','(日)']
    @contributions = current_user.answers.where(created_at: Time.current.all_week)
    @contributions = @contributions.map{|days| I18n.l(days.created_at)}
  end
```

@wdays はテンプレート上に表示し、同時にデータを検索するようの配列です。
@contributionsには例えば、「2021年11月07日(日) 21時09分50秒 +0900
   2021年11月07日(日) 21時07分41秒 +0900
   2021年11月03日(水) 21時43分22秒 +0900
   2021年11月03日(水) 21時43分19秒 +0900」
という配列が保存されます。

```show.json.jbuilder
json.days do
  json.array! @wdays
end

json.contributions do
  json.array! @contributions
end
```

json形式で上記コントローラーで取得した配列を変換し、vueで受け取れるようにします。

#Vue側での実装

```
<template>
 <section v-for="day in days" :key="day" class="flex flex-row">
          <span>{{day}}</span>
          <progress :value="contributions.filter(n => n.includes(day)).length" max="30">
</progress>
          <span>{{contributions.filter(n => n.includes(day)).length}}
          </span>
 </section>
</template>

<script>
  import axios from 'axios';

 export default {
  name: 'Show',
  data: function () {
    return {
      days: "",
      contributions: ""
    }
  },
  mounted() {
    this.setUser();
  },
  methods: {
    setUser: function () {
      axios.get(`/api/users/${this.$route.params.id}`)
      .then(response => {
        this.days = response.data.days
        this.contributions = response.data.contributions
      })
    }
  }
}
</script>
```

データの受け取り方については今回の趣旨ではないので割愛します。

v-forで処理している「day」には曜日が収納されており、
contributions.filter(n => n.includes(day)).length
という埋め込まれたjavascriptによって例えばdayの中身が「（月）」の場合、
2021年11月07日(日) 21時07分41秒 +0900のような形で保存されている配列において月曜日のデータが何個あるかをカウントし、lengthによってそのカウントを表示できます。
@wdayが「月、火、水...」のように（）なしで配列を作成してしまうと、「何月何日」の「月」と「日」をカウントしてしまうため（）を付けています。
STM32L010をVSCのcubeideでLチカ (16MHz)


目的
軽量化
物凄く雑な方法で非推奨
初期ブート環境(と16MHz)で無理やりLチカさせる。

mainは下記の内容

適当にコピー
main.h
stm32l0xx_hal_conf.h
stm32l0xx_it.h

ヘッダー


https://os.mbed.com/users/caa45040/code/f303_h_p1/




![o_con100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8efcbd55-0d0e-690a-80ce-078108de4c65.jpeg)




```c++


#include"main.h"

int main() {

    //37KHzのRC発振器を起動する。
    PWR->CR |= PWR_CR_DBP;    
    RCC->CSR |= RCC_CSR_LSION; //RCC->CSR=RCC->CSR | 1; //LSION SET

    //PA9にSYSCLKを出力
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
    //HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO1SOURCE_LSI, RCC_MCODIV_16); //約2KHz
    //HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO1SOURCE_LSI, RCC_MCODIV_1);


  //16MHz
  __HAL_RCC_HSI_CONFIG(  (uint32_t)1  );
  __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSI);

  //4MHz
  //__HAL_RCC_MSI_RANGE_CONFIG(RCC_MSIRANGE_6);



  __HAL_RCC_GPIOA_CLK_ENABLE();

  //GPIO_InitTypeDef GPIO_InitStruct = {0};

  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

    while(1) {

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
        
        for(int ii=0;ii<10000;ii++) for(int jj=0;jj<50;jj++){}

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
        
        for(int ii=0;ii<10000;ii++) for(int jj=0;jj<50;jj++){}

    }

}




```
【本紹介】初心者フロントエンドエンジニアがおすすめできる今年読んだ本を紹介（前編）

#はじめに
皆さんこんにちは。
今年の2021年4月より、営業職からエンジニア職（フロントエンド）へ転生しました。
そんなジュニアエンジニアの僕が、今年読んだ書籍の紹介をさせてもらおうかと思います。

※紹介する本が多いので前編・後編で分けさせてもらいます。

【後半はこちら】
[【本紹介】初心者フロントエンドエンジニアがおすすめできる今年読んだ本を紹介（後編）](https://qiita.com/hiroyuki_0507/items/2acc4cadcc497b90aac4)

本業で使っている技術は、
jQuery Vue.js Laravel github docker
等を採用しています。

そのため、上記の技術中心の書籍がふんだんに含まれているのでご注意ください！！

#本の紹介の仕方
主に下記のテンプレートをベースに紹介しようかと思います。

###本の名前
######1．書籍紹介（著者、初版発行年月日、金額、ページ数、出版社）
######２．難易度（初級・中級・上級で判断）
######３．簡単な感想

それではいきましょう！

#汎用的な書籍系

#【1冊目】[Webを支える技術](https://amzn.to/3CggbQ3)
######1．書籍紹介
著者：山本陽平
出版社：技術評論社
初版発行年月日：2010年5月1日
金額：2,686円
ページ数：376p

######２．難易度（初級・中級・上級で判断）
中級

######３．簡単な感想
正直僕には分かりづらい点が多々あったが、この1冊でWeb周辺の知識は網羅的に学べる名著と言っていい。
Webのアーキテクチャルールや、REST等プログラミングをする上でベースとなる基礎を鍛えてくれる。
内容は難しいが、読みづらくはないので何回も読み直しをおすすめします。

#【2冊目】[プロになるためのWeb技術入門](https://amzn.to/321Y57R)
######1．書籍紹介
著者：小森裕介
出版社：技術評論社
初版発行年月日：2010年5月10日
金額：2,508円
ページ数：276p

######２．難易度（初級・中級・上級で判断）
初級

######３．簡単な感想
タイトルの通りWebの背景や歴史を学べる入門者には優しい書籍。
ただ、1冊目で紹介した「Webを支える技術」みたいな深い知見は学べない。
触りとしてはありかも。

#【3冊目】[Web系エンジニアになろう](https://amzn.to/3HhD8WC)
######1．書籍紹介
著者：勝又　健太
出版社：実業之日本社
初版発行年月日：2020年11月15日
金額：1,800円+税
ページ数：206p

######２．難易度（初級・中級・上級で判断）
初級

######３．簡単な感想
IT業界やエンジニアに興味がある人であればまず最初にこちらの書籍をおすすめするかも。
業界の全体図や攻略方法が具体的かつわかりやすく書かれている。
フロントエンジニアやバックエンジニア、インフラエンジニア等様々な職種をうまく定義づけてわかりやすい。
ページ数も200ページほどなので、サラッと読めてしまうので読書が苦手な方でも読めちゃうと思う。

#【4冊目】[リーダブルコード](https://amzn.to/3ovHh0s)
######1．書籍紹介
著者：Dustin Boswell  (著), Trevor Foucher (著), 須藤 功平 (解説), 角 征典  (翻訳)
出版社：オライリージャパン
初版発行年月日：2012年６月２５日
金額：2,640円
ページ数：260p

######２．難易度（初級・中級・上級で判断）
初級〜上級

######３．簡単な感想
言わずもがな、名著中の名著なので紹介しようか迷いましたが一応。笑
とりあえず、エンジニアになった人は読むことをおすすめします。
どのように完結に美しくコードを書くか。
読みやすいコードとはなにか。答えはこの書籍の中にあります。
個人的に分かりづらい点がありますが、何度も重ねて読んでいけばより洗礼されていくでしょう！

#【５冊目】[デザインの作り方](https://amzn.to/3c8bUDu)
######1．書籍紹介
著者：上司ニシグチ  (著), 長井 康行 (著), 楠田 諭史  (著), 森 一機 (著) 
出版社：SBクリエイティブ
初版発行年月日：20２１年６月２１日
金額：2,640円
ページ数：３１０p

######２．難易度（初級・中級・上級で判断）
初級〜中級

######３．簡単な感想
本業の方でデザインを扱うことが一時期あり、この本を参考にさせてもらっていました。
表紙にアイデア図鑑と書いてあるのですが、中身はアイデア+アイデアをいかに
IllustratorとPhotoshopで実現するか。まで具体的に書かれています。

デザイン本だからか、画像と文章の構成が見やすく、そして具体的。
買ってよかったなと思った一冊です。

#終わりに。
次回は、フロントエンドエンジニア周辺の技術を周辺に本紹介記事を書かせてもらいます！
お楽しみに！
勉強メモ35_db2のデータメンテとかする場合の接続コマンドや注意点メモ

# 0 はじめに
　・db2のデータメンテとかする場合の接続コマンドや注意点を記載しました。

# 1 db2接続コマンド

#### DB2起動
> db2 db2start

#### DB2ログイン
> db2 connect to DB名 user ユーザー名 using パスワード

#### SQLファイルを実行する
> db2 -tvf tmp/jikkou.sql

#### データをCSVにexoprtする ※of delは、CSV形式を意味します
> db2 export to 出力パス + 出力ファイル名 of del "SQL文"

#### DB2切断
> db2 disconnect current

# 2 データメンテによるSQL作成の注意点（※遅くなるのでやめた方がいい注意点、やむ負えない場合は使用してよい）

#### 1 実行する時に利用するSQLファイルは2MBまでが望ましい

#### 2 抽出のアンサーセットは絞り込める順番にする（パフォーマンス向上のため）

#### 3 WHERE句に索引キーとなるカラムに対して関数や演算子は利用しない
　・インデックスが効かなくなる
#### 4 索引キーとなるカラムに対して、LIKE文の使用NG
　・インデックスが効かなくなる
#### 5 WHERE句のカラムの比較で属性の異なる値を比較するのはNG
　・遅くなる
#### 6 GROUP BY 使用するときに抽出条件にWHERE句で指定している
　・HAVINGは利用しない、GROUP BYした後、絞り込むのは非効率
#### 7 UNION句は使用していない
　・アクセスする表の数が増えるほどソート等のCPUが増えるため
#### 8 IN句の最大件数は確認しておく
#### 9 副問い合わせは行っていない
#### 10 SELECT * COUNT * みたいに*を使用しない
#### 11 SELECT は必要な列のみにする
#### 12 SUM MAX　AVG　COUNT以外の集約関数はなるべく使用しない
#### 13 INSERTはカラム名は省略せず、全て指定して作成する
　・省略するとテーブル構造が変更になったときに再バインドを行う必要があるため
#### 14 JOINはしていない
#### 15 With UR、RS、RR指定して、ISOLATION LEVEL（標準はCS）の変更を行っていない
#### 16 カーソルで更新処理をするとき、FOR UPDATE OF句（更新対象行のロックを取得するため）を明示的に指定している
#### 17 UPDATE、DELETE文はカーソル使用している
#### 18 カーソル読み込み処理はFOR FETCH ONLY を使用している
　・不要なロックを避けるため
#### 19 カーソル使用後はクローズしてる
#### 20 一度に実施するUPDATEは200行位にとどめる
#### 21 LIKEの先頭ワイルドカードはパフォーマンスが悪くなる
#### 22 COUNT文はCASE文でまとめて書く
WPGraphQLを使って記事を表示させる方法

## インストール方法
wp-graphqlってゆう名前のプラグインをWPからインストールしてください。

## ファイル内に記述する内容

ファイルインストール

```ts
import client from '@/apollo-client'
import Posts from '@/graphql/posts'
```

apolloのセッティング

```ts
import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
    uri: 'http://localhost/graphql', // WPのgraphql先になります。
    cache: new InMemoryCache(),
});

export default client;
```

Nextjsを使っていましたので、静的にページを生成するためにgetStaticPropsを使っています。

```ts
export const getStaticProps: GetStaticProps = async () => {
  const data: any = await client.query({
    query: Posts.items(),
    fetchPolicy: 'network-only',
  })

  return {
    props: {
      pictureListContents: data.data.posts.edges,
    },
  }
}

```

### GraphQL

GraphQLのクエリ内容

```ts
import { gql } from '@apollo/client'

const gqlpost = {
  items: function () {
    return gql`
      query {
        posts {
          edges {
            node {
              id
              title
              excerpt
              date
              postId
              slug
              featuredImage {
                node {
                  uri
                  slug
                  sourceUrl
                }
              }
            }
          }
        }
      }
    `
  },

}
export default gqlpost
```

以上になります。
利用方法は至ってシンプルです。他にも使用方法はありますが、WPGraphQLに特化した内容ではなくなるのでこちらの記事では割愛します。
sassc のインストールがおそすぎる

前々から思ってたけど `bundle install` のとき `sassc` のインストールがおそすぎる

そのせい `Docker` のイメージを作る際に タイムアウトエラーみたいになるのが頻発。

腹が立ったので調べた

## 開発環境
`ruby 2.6.5`
`Ruby on Rails 5.2.5`
`bundler 2.2.24`


https://qiita.com/croquette0212/items/d2f48f30c3ed7dcd0e3c


どうやら環境の問題ではなくこの `gem` が悪いらしい

上の記事を参考にさせていただいて

```
gem 'sassc', '2.1.0'
```

`sassc` のインストールと 2.1.0 というバージョンを明示してやると解決
docker-compose public の内容が反映されないときに疑うべきこと

`EC2`上にて `docker-compose` をつかってイメージをビルドした際に
`public` の内容が反映されなかった。

`docker-compose build --no-cache` ってしてもだめ

試しに `docker-compose run app exec bash` でコンテナにはいって調べると
やはり反映されていない

ただ、今回は画像を1GBくらい `public` においたんだけど
`docker image ls` ってするときちんと 1GB 分イメージ容量が増えている

なんだ
___

https://ysko909.github.io/posts/delete-volume-if-can-not-update-container/

`volume` の書き方によってはゴミがのこってしまうみたい。
それで反映されなかった。

`Docker` むずかしい・・
正規表現の基礎と電話番号検索について、簡単にまとめてみた。

現場でも正規表現をよく使うので、
正規表現についてまとめてみる。

私が現場に出る前に、これを学んでおけば良かった！と思っている中で、
ランキング３位以内に入るのが「正規表現」

<h2>正規表現とは何か？</h2>
正規表現とは、
文字列や数値を検索や抽出、入力制限などを課す場合に、
使われる記法である。

あとは、テキストエディタを使って置換をする際にも、
使えるとかなり便利になる。

- 「\d」 → 0-9
- 「\D」 → \d以外
- 「\W」 → \w以外
- 「\w] → a-z、A-Z、0-9
- 「\s」→ スペース、タブ、開業など
- 「\S」→ \s以外
- ^ 始まりの指定
- $終わりの指定


<h2>電話番号を正規表現で表す場合</h2>

例えば、下記の電話番号を正規表現で書くとする。
03-3342-2345

このように書くこともできるが、100個書く場合は無理がある。
^\d\d-\d\d\d\d-\d\d\d\d$

こういうときに、以下の{}の中で桁を指定する。
^\d{2}-\d{4}-\d{4}$

説明を加えると、
0-9がが2桁、-0-9が4桁、0-9が4桁となる。

<h2>携帯番号と、固定電話電話のどちらも検索したい</h2>
先程の{}の使い方で、○桁以上、◯桁以下という表記をすることもできる。
090-3342-2345
03-3342-2345

上記のどちらも検索したいという時には、
2桁以上、3桁以下と、
以下の書き方をすれば良い。
^\d{2, 3}-\d{4}-\d{4}$
rSpec 複数のセレクターを所得して配列みたいに指定する

## 前提
`rSpec` を使ってテストを書いている

## 本題

複数の同じクラスがあってその特定の要素を使用したいとき

```
find(".class")[0] 
```

みたいな書き方はできない

`find` メソッドは一意な要素しか所得しない

上みたいの書き方をしたかったら

```
page.all(".class")[0]
```

みたいにする
kaminari のメソッドのレシーバーが配列のときどうするか

[![Image from Gyazo](https://i.gyazo.com/e846e13b8ee9d3c57c91b2345395b4bf.png)](https://gyazo.com/e846e13b8ee9d3c57c91b2345395b4bf)

上の画像では右側のユーザーが `current_user` なんだけど
自身のアカウントは検索画面で表示されないようにしたかった

## 開発環境
`ruby 2.6.5`
`Ruby on Rails 5.2.5`

## 前提
`user` の認証機能があるアプリ
`slim` を使って書いている
`kaminari` のページネーションで `user` の一覧を表示している
検索機能を実装している


## next メソッド

まず考えたのは `next` メソッド

```:user_html.slim
  - @users.each do |user|
    - if user == current_user 
      = next
```
こんなかんじで繰り返し処理のなかで `current_user` だったらスキップする

しかし

[![Image from Gyazo](https://i.gyazo.com/ab42d203df35e2517907d06750571668.png)](https://gyazo.com/ab42d203df35e2517907d06750571668)

繰り返しはスキップされているけど `css` は生成されてしまっている
これではダサい


## reject メソッド

繰り返しをスキップするのではなく DB のデータを加工するべきだと考えた

`reject` メソッドをつかってみる

コードは

```:user_controller.rb
@users = @q.result(distinct: true)
@users =@users.reject{|user| user == current_user}
```

こんなかんじ。
これで `user` が `current_user` のときだけ `reject` した配列を返す

データもいい感じ

これに `kaminari` のページネーションをしているので

```:user_controller.rb
@users =@users.reject{|user| user==current_user}.page(params[:page]).per(6)
```

 とする。

するとなぜか `nomethod` エラー

なぜ

___

どうやら `kaminari` のレシーバーは `ActiveRecord` を継承している必要がある

なので

```:user_controller.rb
 @users = @q.result(distinct: true)
 @users = User.where(id: @users.reject{|user| user == current_user}.pluck(:id)).page(params[:page]).per(6)
```

こういうコードを書いたらいけた


##### 追記

https://github.com/kaminari/kaminari#paginating-a-generic-array-object


どうやら `kaminari` には配列用のメソッドがあるらしい

```:user_controller.rb
@users = @q.result(distinct: true)
@users = Kaminari.paginate_array(@users.reject{|user| user == current_user}).page(params[:page]).per(6)
```

`Kaminari.paginate_array` というメソッドを使ったらいけた
【初心者向け】Rubyインストール時の注意点

###■環境
・Windows10(64bit)
・Ruby2.6～3.0
・Windowsファイアウォール：無効
###■Rubyインストール時の注意点
インストーラとしては、以下のように「Ruby+Devkit （バージョン） (x64)」を使用することが多いと思います。
その場合、Ruby本体とMSYS2が連続してインストールされます。

https://prog-8.com/docs/ruby-env-win

インストーラをダウンロードできたら、実行する前にセキュリティソフトを一時停止した方が無難です。
Avastの場合、`C:\Ruby【バージョンの数値】-x64\msys64\usr\bin`の以下ファイルが脅威と判定されました。
・gpg.exe
・gpg-agent.exe
・gpg-connect-agent.exe

:::note warn
一連のインストール完了後は元に戻すことをお忘れなく。
:::

###■MSYS2インストール時の注意点
MSYS2インストール関連でエラーが出た場合、放置せずMSYS2の再インストールを行いましょう。
表示されるエラーを1つずつWebで検索・対処するとかなり時間を要したため、以下の手順の方が確実です。

1)WindowsからMSYS2をアンインストール
　（一度アンインストールしないと、インストーラで既定のフォルダを指定してインストールできません。）
2)以下にアクセスし、インストーラをダウンロード。

https://www.msys2.org/

3)セキュリティソフトを一時停止
4)インストーラを（念のために）管理者権限で実行
5)2)のWebページの記述に沿ってインストール
　・`[Y/n]`では「y」を入力しEnterキーを押下
　・`Enter a selection (default=all)`　では　何も入力せずEnterキーを押下
6)5)のコマンド実行時にエラーが発生した場合は、該当箇所のコマンドを再実行。

```ruby:ターミナル
#コマンド実行
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
#エラー発生
error: failed retrieving file 'mingw-w64-x86_64-gcc-11.2.0-1-any.pkg.tar.zst' from mirror.msys2.org : transfer closed with 16911398 bytes remaining to read
#同じコマンドを実行
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
#最新と判定されているため問題なし
warning: mingw-w64-x86_64-gcc-11.2.0-1 is up to date -- skipping
```

7)セキュリティソフトを再稼働させる
VSCodeのExplorerからEnterでファイルを開く設定

VSCodeの左側に出てくるExplorerでは、Enter keyを押すとファイル名を編集する操作になってしまいます。。。

こんな感じ↓
![Screen Shot 2021-10-13 at 12.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534248/2d83da9d-904b-9bef-725c-c5ea6bf8f8c2.png)

Enter keyを押したらファイルが開かれるのが直感的なので(少なくとも私にとっては)、Enter keyを押したらファイルが開かれるように設定しました。

## 方法
1. `Cmd + Shift + P` から`Preferences: Open Keyboard Shortcuts`を開く
1. `renameFile`と検索する
1. `renameFile`というCommandが検索結果に出てくるので、KeyBindingを編集し、`Cmd + Enter`にする。

これで、ExploerからEnter keyでファイルを開けるようになりました！ちなみにファイル名を編集したいときは、上記で設定したように`Cmd + Enter`でできます

今回はこれで以上です。
vsコードで突然日本語表記から英語表記になった時の対処法

vsコードで日本語拡張機能をインストールしているのに突然英語表記になった時の対処法です。原因は何やらvsコードで新しいことやったりした時に起こるようです。とりあえず対処法。

対処法(Mac)
・Shift＋Command＋Pを押す
・出てきたテキストボックスにConfigure Display Language と入力。
・jaをクリック。
・出てきたポップのRestartをクリックしてvsコードを再起動する。→完了！
無料で独自ドメインをHTTPS公開する

**2023年1月4日更新**
Herokuに無料プランがなくなったので、一部表現を修正しています。

### はじめに
[完全無料でRailsアプリを公開する方法](https://qiita.com/shin555/items/721169274a755087766a) の記事の詳細版になります。Herokuで独自ドメインをHTTPSで利用する場合、費用が掛かってきます。（FreeのプランだとHerokuのドメインだけしかHTTPS化できないのでNG）
そこで、freenomとCloudflareを組み合わせることで、独自ドメインでもHTTPS化できるので、その方法をこの記事では書きたいと思います。
※ただし、freenomは無料で取得したドメインでも、2年目以降に課金される可能性があるため、テストサイトなどで利用することをお勧めします。

### ドメインの取得
[freenom](https://my.freenom.com/clientarea.php) にアクセスして、アカウント作成&ログインします。
[Services]＞[Register a New Domain]を押して、自分が取得したい名前を入力します。トップレベルドメインを除く文字を入力（test.xxを取りたいならtestだけ入力）
※2021年11月時点で無料で取得可能なのは「.tk / .ml / .ga / .cf / .gq」のドメインです。
ここで取得したドメインを①とします。

### CDNの登録
[Cloudflare](https://www.cloudflare.com/ja-jp/)にアカウント登録を行い、さきほどfreenomで取得したドメインの①をcloudflareの「サイト」として追加します。

### DNS設定
DNSの設定にHerokuの[Settings]のDomainsに記載の以下のDNS Target（②とします）をcloudflareに登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/456227b4-e76f-9a15-7a74-6215a6c1c3c1.png)

②をcloudflareのCNAMEに登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/a0c11ae1-86bc-faff-2757-6484b7b304c8.png)

さらに、cloudflareの画面の「Cloudflare ネームサーバー」という項目に記載されているNSレコード(③とします)を freenom にコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/97395cd8-e026-099f-af2a-b9eea2782dce.png)

③をfreenomの[Services]＞[My Domains]＞[Manage Domain]＞[Management Tools]＞[Name Servers]に登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/9e76e930-75b7-7646-0b73-0e87ee48dcf1.png)

最後にcloudflareの[SSL/TLS]＞[概要]で暗号化モードが「フレキシブル」になっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/bcf9e5fa-42e9-4173-3a5a-cd5dc5d019c6.png)

### 動作確認！
ここまでで、bounty-hunter.mlがHTTPSで外部から閲覧できるはずです。
（各DNS設定が反映されるまで多少時間がかかるかもしれません）

### 更新
freenomの無料ドメインは最長で1年間の登録期限の設定が可能なので、1年間は特に気にせず利用可能です。
期限が近づくと登録しているメールアドレス宛に更新連絡が来ますので、記載の内容に従って更新作業を行います。期限切れの14日前から更新が可能です。
rSpec all メソッドより page.all メソッドのほうがいい気がする

`ajax` な動作をテストしようとしたとき

```
all("input")[0].set("title1"
click_on  'レビューを投稿する'
```

みたいなテストを書いた。

このテストがとおったりとおらなかったり


適当に `speep` メソッドを散りばめても同じだった

## 開発環境
`ruby 2.6.5`
`Ruby on Rails 5.2.5`

## 前提
`rSpec` が導入されている
レビューを投稿するというボタンをクリックすると `ajax` でデータが反映される


## 結論

以下みたいにしたらうまくいくようになった

```
page.all("input")[0].set("title1")
click_on  'レビューを投稿する'
```

`all` に `page` をつけてやる

推測なんだけど、`all` だけだと範囲がひろすぎて `set` メソッドの処理が追いついてないのかも
それならメソッド内での処理の話だから `sleep` メソッドをいれても関係なかったのもわかる
railsチュートリアル第１３章 ユーザーのマイクロポスト

#ユーザーのマイクロポスト
マイクロポストを作成する

##Micropostモデル

```
$ git checkout -b user-microposts
```

###基本的なモデル
Micropostモデルは、2つだけの属性だけを持ちます。
・マイクロポストの内容を保存するcontent属性
・特定のユーザーとマイクロポストを関連付けるuser_id属性

マイクロポストの投稿にString型ではなくText型を使っている
本番環境ではtext,String型にパフォーマンスの差はない。

####Micropostモデルを生成する
```rb
ubuntu:~/environment/sample_app (user-microposts) $ rails generate model Micropost content:text user:references
# user:references UserとMicropostを関連付けする下準備
Running via Spring preloader in process 3829
      invoke  active_record
      create    db/migrate/20211022055910_create_microposts.rb
      create    app/models/micropost.rb
      invoke    test_unit
      create      test/models/micropost_test.rb
      create      test/fixtures/microposts.yml
```

####自動生成されたMicropostモデル
app/models/micropost.rb

```rb
class Micropost < ApplicationRecord
# ApplicationRecordを継承したモデルが作られます
  belongs_to :user
  # userモデルとの間に「1対1」のつながりが設定
  # 割り当てる
end
```

####インデックスが付与されたMicropostのマイグレーション
db/migrate/[timestamp]_create_microposts.rb

```rb
class CreateMicroposts < ActiveRecord::Migration[6.0]
  def change
    create_table :microposts do |t|
    # create_table　テーブルを作成
    # micropostsテーブルから１つ取り出す
      t.text :content
      # 
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
    add_index :microposts, [:user_id, :created_at]
  end
end
```

###演習
1.
RailsコンソールでMicropost.newを実行し、インスタンスを変数micropostに代入してください。その後、user_idに最初のユーザーのidを、contentに "Lorem ipsum" をそれぞれ代入してみてください。この時点では、 micropostオブジェクトのマジックカラム（created_atとupdated_at）には何が入っているでしょうか?

```rb
>> micropost = Micropost.new
   (0.4ms)  SELECT sqlite_version(*)
=> #<Micropost id: nil, content: nil, user_id: nil, created_at: nil, updated_at: nil>
>> micropost.user_id = 1
=> 1
>> micropost.content = "Lerem ipsum"
=> "Lerem ipsum"
>> micropost 
=> #<Micropost id: nil, content: "Lerem ipsum", user_id: 1, created_at: nil, updated_at: nil>
>> micropost 
```

2.
先ほど作ったオブジェクトを使って、micropost.userを実行してみましょう。どのような結果が返ってくるでしょうか? また、micropost.user.nameを実行した場合の結果はどうなるでしょうか?

```rb
>> micropost.user
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2021-10-17 05:28:48", updated_at: "2021-10-20 14:25:39", password_digest: [FILTERED], remember_digest: nil, admin: true, activation_digest: "$2a$12$x4xVHmtrDFjVPFFWav31UebLY8r9sdT8ImzSXGSrnqt...", activated: true, activated_at: "2021-10-17 05:28:48", reset_digest: "$2a$12$FhfOA3Y7VPJ3TJJ5nNUEkuSH0hkGrrW15uyYE9EwbrC...", reset_sent_at: "2021-10-20 14:25:39">
>> micropost.user.name
=> "Example User"
```

3.
先ほど作ったmicropostオブジェクトをデータベースに保存してみましょう。この時点でもう一度マジックカラムの内容を調べてみましょう。今度はどのような値が入っているでしょうか?

```rb
>> micropost.save
   (0.1ms)  begin transaction
  Micropost Create (2.8ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "Lerem ipsum"], ["user_id", 1], ["created_at", "2021-10-22 06:31:48.078604"], ["updated_at", "2021-10-22 06:31:48.078604"]]
   (9.4ms)  commit transaction
=> true
```
これで
railsチュートリアル第１２章 パスワードを更新する

###パスワードを更新する
今回の場合はフォームから新しいパスワードを送信するようになっています。
フォームからの送信に対応するupdateアクションが必要になります。
updateアクションでは、次の４つのケースを考慮する必要があります。
1.パスワード再設定の有効期限が切れていないか
2.無効なパスワードであれば失敗させる（失敗した理由も表示する）
3.新しいパスワードが空文字列になっていないか（ユーザー情報の編集ではOKだった）
4.新しいパスワードが正しければ、更新する

####パスワード再設定のupdateアクション
app/controllers/password_resets_controller.rb

```rb
class PasswordResetsController < ApplicationController
  before_action :get_user,   only: [:edit, :update]
  before_action :valid_user, only: [:edit, :update]
  before_action :check_expiration, only: [:edit, :update]    # （1）への対応
  # その前に行う
.
.
.
  def update
    if params[:user][:password].empty? # （3）への対応
    # パスワードが空文字列かどうか？
      @user.errors.add(:password, :blank)
      # errors.add(:base, '名前の文字数オーバー')
      # なのでメッセージを表示する
      render 'edit'
      # 編集画面に行く。
    elsif @user.update(user_params) # （4）への対応
    # 新しいパスワードが正しければ、更新する
      log_in @user
      flash[:success] = "Password has been reset."
      redirect_to @user
    else
      render 'edit'                                     # （2）への対応
    end
  end
  
  private

    def user_params
      params.require(:user).permit(:password, :password_confirmation)
      # requireメソッドで受け取るパラメータ群を、permitメソッドで利用可能なパラメータ名を指定
    end
.
.
.
    # トークンが期限切れかどうか確認する
    def check_expiration
      if @user.password_reset_expired?
      # 期限が切れているか？
        flash[:danger] = "Password reset has expired."
        redirect_to new_password_reset_url
      end
    end
end
```

####Userモデルにパスワード再設定用メソッドを追加する
app/models/user.rb

```rb
class User < ApplicationRecord
.
.
.
  # パスワード再設定の期限が切れている場合はtrueを返す
  def password_reset_expired?
    reset_sent_at < 2.hours.ago
    # ２時間前より前の時間
  end
.
.
.
end
```
###演習
1.
12.2.1.1で得られたリンク（Railsサーバーのログから取得）をブラウザで表示し、passwordとconfirmationの文字列をわざと間違えて送信してみましょう。どんなエラーメッセージが表示されるでしょうか?

Password confirmation doesn't match Password

2.
コンソールに移り、パスワード再設定を送信したユーザーオブジェクトを見つけてください。見つかったら、そのオブジェクトのpassword_digestの値を取得してみましょう。次に、パスワード再設定フォームから有効なパスワードを入力し、送信してみましょう（図 12.13）。パスワードの再設定は成功したら、再度password_digestの値を取得し、先ほど取得した値と異なっていることを確認してみましょう。ヒント: 新しい値はuser.reloadを通して取得する必要があります。

```
>> user = User.find_by(email: "example@railstutorial.org")                 
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "example@railstutorial.org"], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2021-10-17 05:28:48", updated_at: "2021-10-20 14:25:39", password_digest: [FILTERED], remember_digest: nil, admin: true, activation_digest: "$2a$12$x4xVHmtrDFjVPFFWav31UebLY8r9sdT8ImzSXGSrnqt...", activated: true, activated_at: "2021-10-17 05:28:48", reset_digest: "$2a$12$FhfOA3Y7VPJ3TJJ5nNUEkuSH0hkGrrW15uyYE9EwbrC...", reset_sent_at: "2021-10-20 14:25:39">
>> user.password_digest
=> "$2a$12$GusJ71vphWBKR7LjQGrkfeHiAWFbIoCWQfodotlR**************"
```
パスワードを変化させるのはちょっと抵抗があるのでやめておく。
rspec 画像が投稿できることをテストする　

`rSpec` で画像が投稿できることをテストする

##開発環境
`ruby 2.6.5`
`Ruby on Rails 5.2.5`

## 前提
`rSpec` が導入されていること
`test.jpg` がテスト用の画像


## 画像のテスト方法

① テスト用の画像を用意する
② テスト中にその画像をセットする
③ セットした画像のセレクターをテスト

https://study-diary.hatenadiary.jp/entry/2020/10/16/133144

こんへん参考にしながら

自分の場合は

[![Image from Gyazo](https://i.gyazo.com/3372aa5432a4ddd3ba34a052601e109a.png)](
://gyazo.com/3372aa5432a4ddd3ba34a052601e109a)

こんな画像でテスト

コードは

```
 attach_file 'inputFile', "#{Rails.root}/spec/factories/test.jpg", make_visible: true
 click_on '保存する'
 expect(page).to have_selector("img[src$='test.jpg']")
```

こう

今回は `spec/factories/` に `test.jpg` を配置した


`attach_file` で画像をセット 第三引数で `make_visible: true` すると `hidden` の要素もテストできる

最後に `hava_selector` で画像のパスをテストするという流れ
Raspberry Pi ( Ubuntu ) の Wifi を CUI から設定する

# 概要
Raspberry Pi ( Ubuntu Server ) の Wifi を CUI から設定する方法
Ubuntu Serverをインストールすると、ディスクトップ環境が無く、WiFi設定も行われていない状態となります
その場合での方法になります
Ubuntu DesktopだとSettingアプリを起動すればGUIでのインストール時に設定画面が出てきますので、Ubuntu 21.10でも構わない方は、そちらがお勧めです

## 環境
・Ubuntu Server 21.04

## WiFiの設定
### WiFiの設定ファイル
/etc/netplan/50-cloud-init.yaml

### 設定の記載方法
vi が苦手なら nano を利用してください

```
$ sudo cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.org
$ sudo vi /etc/netplan/50-cloud-init.yaml
```

[SSID]  　SSIDを記載します、[]は不要です
[PASSWD]　パスワードを記載します、[]は不要です

```
# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        eth0:
            dhcp4: true
            optional: true
    version: 2
    wifis:
            wlan0:
                    dhcp4: true
                    optional: true
                    access-points:
                             [SSID]:
                                     password: "[PASS]"
```

設定を保存後、コマンド netplan で反映します

```
$ sudo netplan apply
```

### WiFi接続状態の確認方法
コマンド wifi-status WiFi接続状態を確認できます

```
$ wifi-status
```
Discord.jsを使用したBotで指定のチャンネルにメッセージを送信する

# はじめに
<!-- 発端や概要を記載 -->
DiscordBotを作った

discord.jsがv13にアップデートされて日本語文献が大幅に減少し、初学者的にはむちゃくちゃ沼ったのでメモ
TypeScriptを採用した(生まれて初めてみた親の顔がTypeScriptなので使ってる)辛さも含まれてる

ボタンとか実装できるようになったのは嬉しい

※イベントで使う用のbotで作成期間が徹夜前提でタイムリミットが8時間とかしかなかったのもあり、とりあえず動けば良い時用の知識になってるので、他の良い記述方法あったら教えてください

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [環境構築](#1-環境構築)
1. [dotenvのインポート](#2-dotenvのインポート)
1. [clientの記述](#3-clientの記述)
1. [指定のチャンネルにメッセージを送信する](#4-指定のチャンネルにメッセージを送信する)
1. [参考文献](#5-参考文献)


<!-- 各チャプター -->

#1. 環境構築

雑にTypeScriptの環境構築

```
npm install discord.js
npm install dotenv
npm install typescript --save-dev
npm install --save-dev eslint
npx tsc --init
```

前回作った(半年前)のBotのコードをコピペしたらエラーの嵐
特に、Node.jsのバージョンが低いことに起因するエラーで30分くらい悩んだ
Node.js 16.6.0が必要だと[公式ドキュメント](https://discord.js.org/#/docs/main/stable/general/welcome)に書いてあるのでちゃんと読むべき…

動いた環境

```
node -v 
v16.13.0

npm -v
7.24.0
```

.gitignoreを先に書く癖をつける
.envファイルやnode_modulesをGitHubに公開するをやらかす

```.gitignore:.gitignore
node_modules/
/.env
/src/.js
```

#2. dotenvのインポート

### Before

```
import dotenv from "dotenv";
dotenv.config();
```
動かなかったので
### After
```
import * as dotenv from "dotenv";
dotenv.config();
```

## 追記
起動時オプションでも設定できるし、以下の記述でも動くらしいです。

```
import { config } from 'dotenv';
config();
```

https://github.com/motdotla/dotenv#preload

#3. clientの記述

```
const client = new Client({
  intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
```
discord.js v12と書き方が大幅変わってた
メッセージを送るためにはIntents.FLAGS.GUILD_MESSAGESが必要

#4. 指定のチャンネルにメッセージを送信する

## 本題

初学者が理解しやすい記事はオウム返しが主流で、他のチャンネルに送信する文献が少なかった

```
const postchannel = client.channels.cache.get(channel_id);
postchannel.send("");
```
でいけるとdiscord.jsのDiscordコミュニティでは言われていたが、そもそもclient.channels.cache.get(channel_id)以下にsendが生えてなさそうなので困った

1時間強くらいネットの海を彷徨った結果、stackoverflowで[解決策](https://stackoverflow.com/questions/68992134/how-to-send-message-to-specified-channel-discord-js-v13-typescript)を見つけることができた

```
import { TextChannel } from "discord.js";
const postchannel = client.channels.cache.get(channel_id) as TextChannel;
postchannel.send({ embeds: [goalEmbed] });
```


#5. 参考文献
- [discord.js 公式ドキュメント](https://discord.js.org/#/docs/main/stable/general/welcome)
- [深夜2時で救ってくれたstackoverflowの質問](https://stackoverflow.com/questions/68992134/how-to-send-message-to-specified-channel-discord-js-v13-typescript)
GGAを終えて

  G’s ACADEMYではGGAという卒業LTが行われる。 
LTでは自分の企画・開発したプロダクトのアウトプットをする。  
私が企画・開発したのは、化粧品容器の回収BOXだ。 
エンジニア経験者の同期と一緒に2人でチームを組み、共同で開発を行った。

  私は化粧品通販会社に勤めている。 
当社では、容器回収やリサイクルする仕組みがなく、
消費者へ販売した後の化粧品容器が行方知れずになっていた。 
直近で証券会社が出した化粧品通販会社のESGの取り組み状況を見ても、 
当社は「現状も取り組んでおらず、今後も取り組む予定がない」と書かれていた。
 私はこの状況を改善したいと思い、今回のプロダクトの企画した。  
7月中旬に企画書とプロトタイプを提出し、そのタイミングでチームを組んだ。 

技術選定時は生言語で作るか、フレームワークを使うかでとても悩んだ。 
生言語で開発するか、フレームワークを使うか、サーバは？DBは？何を選べばいいのか本当に悩んだ。 
そんなときメンターの橋本さんから言われたことは「後3、４回作り直すつもりで選んだらいい。
 自分のできる言語、できる範囲は限られている。まずできる言語でやってみる。
その後、違う言語で書き直すのが良い」 そうアドバイスをもらった。 
私はサービスサイトにLaravel、node、回収機にRaspberrypi、LINEのMessaging APIを使うことにした。
 （後で＋GoogleAppScriptを使うことになる）  

開発は思うようにはいかなかった。
 サービスサイト実装時はLaravelの環境構築がうまくいかず、 
講義の復習、Udemyで学習しながら、実装した。
講義もUdemyも10回以上動画を見直した。 回収機側の開発では、RaspberryPiが起動しなくなり、
初期化を何度も繰り返した。 GoogleSpreadSheetに01を返すだけなのに、実装に2週間かかった。
deployフェーズでは環境変数の設定に1週間かかった。 
とにかく形にしなければ、という気持ちで毎日いっぱいだった。
 朝起きてコードを書いて、仕事に行って、帰宅して深夜までコードを書いた。  

開発以外でも、企画の内容やビジネスモデルでかなり悩んだ。
 お金にならないのではないか、ほんとうに役に立つのか…毎日頭の中でぐるぐるしていた。 
リサイクルや回収選別事業者に電話やメールで連絡を取る中で、
回収段階で容器の汚れやゴミの混入による、焼却の問題を改善したいという課題を聞けた。 
ただし、輸送コストはかかってしまうため、
現職の化粧品会社ではコストが合わないということでNGをくらった。 
どうしようか途方にくれていたとき、商品開発部の部長から容器メーカーの紹介を受けた。
光がさしたと思った。 （現時点では交渉段階だが、実証実験に進めるよう交渉を進めていく）  
そんな感じで色々あったが無事に卒業制作を提出し、すぐにLT資料を作成した。 

東京の先輩からセレクションというGGA出場の権利を得るためのLTがあると聞いていた。
 セレクション当日はGGAより緊張した。手も声も震えた。 
それでも、当事者の当事者にしか伝えることができないLTをしよう。
このメッセージは当事者である私にしか伝えられない。 ここで終わりたくない、絶対にGGAまで行く。
そんな気持ちだった。 結果　、セレクションを無事通過し、GGAに出場することが決まった。  
GGA出場が決まってからは、回収機のブラッシュアップを行った。 
外装を整え、機能追加し、プロダクトのコーポレートカラーの緑の回収機が出来上がった。  

GGAの前日はGGAを成功させたい気持ちと、
これからどうしていこうという気持ちとが混ざり合っていた。 
明け方4時くらいまで起きていた。 
登壇順が近づくにつれ、心臓が飛び出そうだった。 
ステージに立つと意外と緊張していなくて、
とにかく「自分の気持ちを届けたい」という一心で話した。 
結果は3位。とてもとても悔しい結果に終わった。  
悔しさから当日の夜、G'sの先輩に聞いたアクセラに応募し、新規事業の支援団体へ連絡をした。
 GGAは終わった。
しかし自分があきらめなければ、自分がつくりたいセカイはいつまでもつくり続けることができる。
GGAが終わって今日から次のステージが始まった。 私はこれからも走り続けていこうと思う。

メンターの橋本さん、共同開発社の小石さん、担任の岡田先生に心から感謝を込めて。
Android StudioのエミュレータがWindows11で動かなかった

##結論
以下のイシューで提供されているexeファイルに置き換えると起動しました
https://issuetracker.google.com/issues/202188690?pli=1#comment27

##環境
* OSのエディション：Windows 11 Pro
* Android Studioのバージョン：Arctic Fox

##状況
久しぶりに時間が取れたのでアプリ開発を行おうと思い、
現在のPCにAndroid Studioをセットアップしたのですが、
エミュレータがまったく反応せず、数日はまってしまいました。

AVD Managerでデバイスをインストールし、緑色の再生ボタン▶でRunしても
右下に"Waiting for target devices to come online"と表示された状態で止まってしまう。。。

にっちもさっちもいかず、検索しても日本語での解説が見当たらず（検索の仕方が下手くそなのもあります）
英語苦手ですが、英語圏でがんばって検索かけて解決方法を見つけたので、共有します。

原因はOSがWindows11の場合、
QEMUとやらWHPXとやらが、うまく起動できないらしいです。
参考:https://stackoverflow.com/a/69759133

といっても解決方法は以下のリンク
https://issuetracker.google.com/issues/202188690?pli=1#comment27
より心ある同志が提供したzipファイルを取得して、解凍すると
以下の修正済みexeファイルが出てくるので、
・qemu-system-x86_64.exe
・qemu-system-x86_64-headless.exe
各環境に配置されているexeファイルと置き換えるだけです。

私の場合は以下のフォルダにありました。
C:\Users\\[ユーザー名]\AppData\Local\Android\Sdk\emulator\qemu\windows-x86_64

ようやくアプリ開発に入れる。。。
【WordPress】wp-login.php へのアクセスを禁止してブラウザからログインできなくする方法

# ブラウザを使わない代替のログイン手段を用意する

↓個人的におすすめなのはこれ

aaemnnosttv/wp-cli-login-command: Log in to WordPress with secure passwordless magic links.
https://github.com/aaemnnosttv/wp-cli-login-command

WP-CLI を使ったログイン方法で，ターミナル上でコマンドを打つことでログイン用のワンタイムURLを発行できる．

# wp-login.php へのアクセスを禁止する (nginx)

nginxのサイトの設定ファイル (Ubuntu: /etc/nginx/sites-available) に以下を追記．<br> `location /`等よりも上に書いた方が良い．

※環境に応じて記述は書き換えてください．

```nginx:
# deny access to wp-login.php (without logout)
if ($request_uri !~* /wp-login\.php\?action=logout ){
  rewrite ^/wp-login\.php(.*)$ /? redirect;
}
```

# wp-login.php へのアクセスを禁止する (apache)

`.htaccess`に以下を追記．

※環境に応じて記述は書き換えてください．

```apache:
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} !^action=logout
RewriteRule  ^wp-login\.php index.php? [R=302,L]
</IfModule>
```
Markdown記法まとめ

#はじめに
Qiitaを書く際に使われるMarkdown記法について自分なりにまとめてみました。Qiita及びMarkdown記法によるドキュメント作成の参考にしていただけたら幸いです。

##目次
1. 見出しの書き方
2. 黒背景(コードブロック)の書き方
2. 斜体文字と太文字の書き方
2. 引用及び二重引用
2. 打ち消し線
2. 

##見出しの書き方
この上に書かれている「見出しの書き方」という大きな文字は次のように書くことで表すことができます。
###記述例

```
#見出しの書き方
```

＃は半角で書き、＃の数を変えていくことで徐々に大きさを小さくしていくことができます。

###表示例
#この見出しは＃が１つ
##この見出しは＃が２つ
###この見出しは＃が３つ
####この見出しは＃が４つ
#####この見出しは＃が５つ
######この見出しは＃が６つ
とこのように大きさが小さくなっていきます。6段階の大きさを設定できるようですが、最後の5段階目と6段階目の違いは自分にはいまいちわかりません。



#黒背景(コードブロック)の書き方
見出しの書き方にも出てきた黒い背景にする方法としては、文書の前後をバッククオーテーション３つ(```)で囲む必要があります。以下のように書くと、
###記述例
>
(空白行)
‘‘‘
print("Hello World")
‘‘‘
(空白行）
例のため、ここでのバッククオーテーションは全角

###表示例
```
print("Hello World")
```

とこのように書くことができます。この状態であれば、黒背景の右上に出てくるボタンをクリックすることで簡単にコピーすることができます。さらに、この黒背景ではファイル名を入れることができます。その方法としては次のように書くだけです。
###記述例
>
(空白行)
‘‘‘py:hellow.py
↑[言語名:ファイル名]と書く
print("Hello World")
‘‘‘
(空白行)

###表示例
```py:hello.py
print("Hello World")
```

とこのようにコードブロックの左上にファイル名を書くことができました。言語名によって勝手に色が変わるようです。また、色を付けたいだけであれば「言語名:ファイル名」の言語名だけの部分で大丈夫です。ファイル名はつきませんがこれも言語によって勝手に色が変わります。

#斜体文字と太文字の書き方
斜体文字と太文字はそれぞれ次のように書くことで表せます。
###記述例
```
＊Hello＊
↑斜体で協調したい英数字を＊(アスタリスク1個)で囲む。
＊＊Hello＊＊
↑太文字で強調したい箇所を＊＊(アスタリスク2個)で囲む。
```
###表示例
斜体文字 : *Hello*  太文字 : **Hello**


#引用及び二重引用
＞を先頭に書くだけです。＞＞とすることで二重に引用することもできます。＞を増やしていくことで何重にも引用することができますが、使い道はあまりなさそうです。
###表示例
>＞を１個先頭につけることでこのように書ける。
>> ＞を２個先頭につけることでこのように書ける。
>>> ＞が３個はこのようになり、以降増えていくがが使い道はなさそう



#打ち消し線
打ち消し線を書くためには以下のように書きます。~~で文章を挟むように書くと打ち消せます。

###記述例
```
〜〜打ち消したい文章をこのように〜〜で囲む〜〜
```
###表示例
~~打ち消したい文章を〜〜で囲む~~



#水平線
_(アンダーバー) , *(アスタリスク) , -(ハイフン)を3つ以上連続で記述することで水平線を表すことができます。
###記述例
```
---
***
___
```

###表示例
___
***
___



#リンク関連
##リンクテキスト
単純にリンクを載せたい場合は次のように書けばいいです。［名前］(リンク先のURL)という形で書きます。
###記述例
```
[Qiita](https://qiita.com)
```
###表示例
[Qiita](https://qiita.com)

##リンク(タイトル・画像付き)
飛びたいリンク先のURLを張るだけで次のようになります。
###記述例
```
https://qiita.com
```
###表示例
https://qiita.com



#気になるページをMarkdown記法で見る
Qiitaを見ている中で書き方がいまいち分からないといった場合にはMarkdown記法で見たいURLの最後に.mdと書くだけでそのページの書き方を見ることができます。


#あとがき
あまり内容を書いていませんが今回のところはこれまでにしておきます。時間があったら随時ページを更新していきたいです。
Unity iOSビルド時に輸出コンプライアンス情報をinfo.plistに記載する

以下のスクリプトを適当な`Editor/`下に配置の上ビルドすると、
TestFlightアップロード時に輸出コンプライアンス情報を提出する必要がなくなる。

``` CSharp
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.iOS.Xcode;

public class PostprocessBuild : IPostprocessBuildWithReport
{
    public int callbackOrder { get { return 0; } }

    public void OnPostprocessBuild(BuildReport report)
    {
        if (report.summary.platform == BuildTarget.iOS)
        {
            string plistPath = Path.Combine(report.summary.outputPath, "Info.plist");
            PlistDocument plist = new PlistDocument();
            plist.ReadFromFile(plistPath);
            plist.root.SetBoolean("ITSAppUsesNonExemptEncryption", false);
            plist.WriteToFile(plistPath);
        }
    }
}
```
【Scala】Akka-HTTPクライアントを使ってapplication/x-www-form-urlencodedのリクエストを送信する

## 概要
Akka-HTTPは[Akka HTTPでWeb APIに仕立てる](https://thinkit.co.jp/article/15235)の記事にある通り、Akkaの拡張機能の一つでWebのサーバとしてHTTPリクエストを処理できます。Akka-HTTPには外部にリクエストを投げるための機能`Akka-HTTP Client`があります。Akka-HTTP Clientの詳細については、[Akka HTTP クライアントを使う](https://okapies.hateblo.jp/entry/2017/12/03/051725)を参照ください。
今回はAkka-HTTP Clientを使用して、外部にapplication/x-www-form-urlencodedのリクエストを送信する時にどうすれば良いのか、というのを書いてみたいと思います。

## 対応
[How to include application/x-www-form-urlencoded HttpHeader in Akka-http 2.4.1?](https://stackoverflow.com/questions/35468676/how-to-include-application-x-www-form-urlencoded-httpheader-in-akka-http-2-4-1)の記事にある通り、Clientのentityに`FormData`のオブジェクトをセットすればいけそうです。[こちら](https://doc.akka.io/japi/akka-http/current/?akka/http/scaladsl/model/FormData.html)のドキュメントにある通り、FormDataは`application/x-www-form-urlencoded`に対応してるみたいです。

## 実装サンプル
[gBizINFO](https://info.gbiz.go.jp/api/index.html)という法人データを提供しているAPIに、SPARQLのクエリを投げる例をサンプルとして記載します。

```scala:CompanyRestClient.scala
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{FormData, HttpMethods, HttpRequest}
import akka.http.scaladsl.unmarshalling.Unmarshal

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.util.{Failure, Success, Try}

object CompanyRestClient {

  implicit val system = ActorSystem()
  implicit val executionContext = system.dispatcher

  val GBIZ_URL = "https://api.info.gbiz.go.jp/sparql"

  def sendRequestToGbiz(query: String)(implicit ec: ExecutionContext): Future[Try[String]] = {
    val req = HttpRequest(
      method = HttpMethods.POST,
      uri = GBIZ_URL,
      entity = FormData("query" -> query).toEntity
    )
    Http().singleRequest(req)
      .map(res => Success(Await.result(Unmarshal(res.entity).to[String], Duration.Inf))
    ).recover { case e => Failure(e) }
  }

}

```
[robel] ERROR: Could not build wheels for mujoco-py which use PEP 517 and cannot be installed directly

robel をインストールする際に
mujoco-py のビルドでこけたのでメモ。

python 3.9 系だと
`ERROR: Could not build wheels for mujoco-py which use PEP 517 and cannot be installed directly`
となって落ちる。

```
pipenv --python 3.7
pipenv install robel
```

で行けた。

### 環境

WSL2/Ubuntu 20.04
AWS Lambda S3 の画像ファイルをブラウザに表示する

# 初めに

Lambda と API Gateway を使用して、ブラウザでクリックボタンを押すと S3 にある画像ファイルをブラウザに表示する方法を実装する手順を説明します。

# S3 に画像ファイルを保存する

表示したい画像ファイルを保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/139ef17c-8483-eea0-48c9-ae28cd5f8ebb.png)

# Lambda 関数を作成する

以下の Lambda 関数を作成し、Lambda関数のロールに S3 のアクセス権限を付与します。検証だけでしたら Lambda 関数作成時のロールのインラインポリシーに S3 のフルアクセス権限を付与するのが簡単です。

```python
import base64
import boto3
import json

s3 = boto3.client('s3')

def lambda_handler(event, context):
    object_key = event['image']
    response = s3.get_object(
        Bucket='binary-test-bucket',
        Key=object_key,
    )
    image = response['Body'].read()
    return {
        'headers': { "Content-Type": "image/png" },
        'statusCode': 200,
        'body': base64.b64encode(image).decode('utf-8'),
        'isBase64Encoded': True
    }
```

# API Gateway を作成する

上記の Lambda 関数を選択します。非プロキシ統合にしておきます。おそらくプロキシ統合でも可能ですが、検証は非プロキシ統合で行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/f510bad9-4360-4540-c6c2-497bec27559f.png)

# フロントエンドを作成する

```HTML:index.html
<!DOCTYPE html>
<html lang="ja">
<body>
  <h1>Binary Image Sample</h1>
  <img id="image" src="data:image/png;base64,HERE_IS_BINARY_CODE" alt="binary image" />
  <button onclick="showImage()">click</button>
  <script>
    function showImage() {
      const raw = JSON.stringify({image: 'sample.png'});
      const myHeaders = new Headers();
      myHeaders.append('Content-Type', 'application/json');
      const requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        redirect: 'follow',
      };
      fetch('https://API_GATEWAY_ID.execute-api.ap-northeast-1.amazonaws.com/test', requestOptions)
        .then(response => response.text())
        .then(result => {
          const binaryData = JSON.parse(result).body;
          const imgElem = document.getElementById('image');
          imgElem.src = "data:image/png;base64," + binaryData;
        })
        .catch(error => {
          console.log(error);
        });
    }
  </script>
</body>
</html>
```

ボタン押下で以下のように画像が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/b6c95dfe-479d-40b2-1d46-ce7dad88eb6d.png)

# 参考記事

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/lambda-proxy-binary-media.html

https://stackoverflow.com/questions/25869017/how-to-convert-binary-data-and-mime-to-image-in-javascript
【Python】乱数を使ってみる。

#はじめに
今回はPythonで乱数(ランダムな数)を使ってみたので、使い方などを紹介していきます。

#環境
Mac OS Monterey
Python 3,10,0
VS Code

#書き方
まずは必要なモジュールのインポートから。

```python
import random
```

でオッケーです。

##変数に乱数を入れる方法
実際にやっていきます。基本的にrandomは乱数を生成して、それを変数に入れるという処理をしてくれます。

###0.0以上1.0未満の浮動小数点数
インポートに加えてこのように付け足します。


```python
random_a = random.random() #（0.0以上1.0未満の浮動小数点数）
print(random_a)
```

実行結果として、

例）
__0.11289872207668838__

などの小数がターミナルに表示されます。

###任意の範囲の浮動小数点数
random.uniformでは乱数を生成する範囲を指定することができま

```python
random_a = random.uniform(1, 10)
```

範囲を変える場合は(1, 10)の値を変更します。

実行結果
先ほどと同じく断定はできませんが、範囲内の乱数が出力されます。

例）
__7.624202542340996__

###任意の範囲の整数
今度は任意の範囲の__整数__です。

```python
random_a = random.randint(1, 10)
print(random_a)
```

先ほどと同じで、()内の数値をいじると乱数の範囲も変わります。

実行結果

1から10のどれかの整数が出力されます。

例）
__7__

#おわり
今回はPythonの乱数について紹介しました。
乱数はゲームなどにも活用できるので、是非、覚えておくと良いです。（？）