OmniAICreator/Qiita-1.07M huggingface dataset:
Google Cloud PlatformでGPUを使えるようにした話

Google Cloud Platform（以下、GCP）でGPUを使うには申請が必要なのでその方法について書いていきます。

最初からGPUを使えない理由はGoogleがアカウント毎に使えるリソースを制限しているからです。
なのでGoogleにお願いしてGPUの利用権を申請する手続きが必要になります。

リソース制限の詳細については以下の「サービスクォータについて」をお読みください。
https://cloud.google.com/docs/quota?hl=ja

## GCPでプロジェクトを作成する

GCPにアクセスして新規でプロジェクトを作成してください。
既存のプロジェクトを使う方は何もしなくて大丈夫です。
https://console.cloud.google.com/

## GPUの割り当てをしてもらう

サイドバーの「IAMと管理」から「割り当て」を選択してください。

![スクリーンショット 2023-05-27 0.35.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/dc71a677-bd5f-3fea-2b3c-0a18e99c3b05.png)


フィルタの箇所に`GPUs (all regions)`と入力します。
サジェストされた`GPUs (all regions)`をクリックしてください。
![スクリーンショット 2023-05-27 2.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/36a98250-21c3-0755-e4c4-53831afff2cd.png)

上限が0になっている場合は割り当てのリクエストが必要です。
![スクリーンショット 2023-06-02 21.06.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/02a06865-074a-4756-0fb5-78b496d78bc9.png)

チェックボックスにチェックを入れて「割り当てを編集」をクリックしてください。
![スクリーンショット 2023-06-02 21.07.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/5980e047-181a-1ad5-d55f-43b83c27e546.png)
![スクリーンショット 2023-06-02 21.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/7a72304e-f00d-5a2a-8733-62e748c4909a.png)


するとこのようなフォームが開くので以下のように入力して「次へ」をクリック。
新しい上限：１
リクエストの説明：GPUが必要な理由を書いてください
![スクリーンショット 2023-06-02 21.10.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/b95b198f-3c52-b3ca-5cdd-b320fe50c9a4.png)

名前とメールアドレスは入力されていると思うので「リクエストを送信」をクリックして送信します。
電話番号は空欄でも問題ありません。

![スクリーンショット 2023-06-02 21.12.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/ed9daab6-f4a8-bd47-fd73-fa72fc0d46de.png)


続いて使いたいGPUタイプを選んで申請します。
GCPで使えるGPUの種類は以下の通り。
![スクリーンショット 2023-05-22 12.41.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/959874ea-d577-68bc-ea4e-8384dfe44814.png)


T4は比較的安価でA100はかなり高額です。

利用したいGPUが決まったらフィルタにそのGPUの名称を入力して出てきたサジェストのdefaultとついていない項目を選択します。
![スクリーンショット 2023-05-27 2.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/913e7645-90fa-9999-373d-73e2139847df.png)

あとは先ほどと同様にチェックを入れて「割り当てを編集」をクリックし、フォームに必要事項を入力して送信すれば問題ありません。
![スクリーンショット 2023-05-27 2.44.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/c65b19b5-fe59-2d8e-6aa9-d1588fd456e2.png)

早ければ数分で割り当てが完了した旨のメールが届くので、その後すぐにGPUを使うことができます。


## GPUの料金について

GPUは高価なので利用用途に合ったGPUタイプを選択しないと高額な請求が届いてしまいます。

多くのクラウドサービスでは同じGPUでも２種類の利用方法がありそれぞれ以下のような特徴があります。

・通常のインスタンス（オンデマンド）
通常の方法でインスタンスを立ち上げるとこれに該当します。
料金は定価なので種類によっては非常に高額になります。

・スポットインスタンス
余っているマシンリソースを使うことで安価に利用できるのがスポットインスタンスです。
リソースがなくなれば勝手に停止される可能性があります（停止前に通知は来る）

それぞれこのような価格差があります。
実験目的で使う場合はとりあえずスポットインスタンスを選択すると良いでしょう。
![スクリーンショット 2023-06-02 22.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/0e9b07c3-b900-45cd-2bc2-68ddacf6a21b.png)


詳細は以下をご確認ください。
https://cloud.google.com/compute/gpus-pricing?hl=ja#gpus
swaggerが肥大化したので分離した

# 背景
途中からジョインしたプロジェクトにて、swaggerを使っていたのですが、YAMLファイルが10,000行近くと保守がとても大変だったので、分割できるらしい`multi-file-swagger`を使いました。
後から、`swagger-multi`？を知ったので特に比較してこちらを使うことにしたわけではないです。
swagger自体については他にいっぱい記事があるのでここでは記述しません。

# できたプログラム

https://github.com/sion908/multi-file-swagger-separate

# インストール
自分はなんとなくグローバルのインストールは嫌だったので、devで入れました
```shell
npm i -D multi-file-swagger
```

# 実行
```shell
npm run separate
```
# プログラム

ライブラリのインストール
```javascript
#!/usr/bin/env node
'use strict';

var resolve = require('json-refs').resolveRefs;
var YAML = require('js-yaml');
var fs = require('fs');
```

分離するkeyの指定。
1段階必要なものと2段階必要なものがあったのでそれぞれ定義した
```javascript
const key_1 = ['info', 'securityDefinitions','tags'];
const key_2 = ['paths', 'definitions'];
```

分離するファイルのロード(実際はエラーハンドリング付き)
```javascript
var file = program.args[0];
var original = YAML.safeLoad(fs.readFileSync(file).toString());
```
この後使う各ファイルを保存するためのプログラム
ちなみにミスってもファイルはそのまま残る。トランザクション的なものつけるべきかな？
```javascript
const writeFile = (filename, data) =>{
  fs.writeFile(
    filename,
    YAML.dump(data),
    'utf8',
    (e)=>{
      if(e){
        console.log(e.message);
        process.exit(1)
      }
    }
  )
}
```
各keyに対してループを行いフォルダおよびファイルを保存する
```javascript
const keys = key_2.concat(key_1);
for (const dir_name of keys){
  if(!fs.existsSync(`${dir_name}/`)){
    fs.mkdirSync(`${dir_name}`);
  }
  const dir_origin = original[dir_name];
  console.log(`${dir_name}/index.yaml`);
  if (key_2.includes(dir_name)) {
    for(const indexes of Object.keys(dir_origin)) {
      const filename = indexes.replace(/^\//,'').replace(/\//g,'-') + '.yaml';
      writeFile(`${dir_name}/${filename}`, dir_origin[indexes]);
      dir_origin[indexes] = {$ref: './'+filename}
      console.log('  ', filename);
    }
  }
  writeFile(`${dir_name}/index.yaml`, dir_origin);
  original[dir_name] = {$ref: `./${dir_name}/index.yaml`}
}
writeFile(`separated.yaml`, original);
console.log('succssess');
```

# 展望
- もう少し一般化する
- 元々あったjsonにも対応した方がいいのか？
- 分離した後例えば新規のpathを追加する時いちいち色々追加するのはめんどくさいのでこれもコマンド化する
- npmにしても面白いかも

# 参考記事
- [Swaggerの概要をまとめてみた。](https://qiita.com/gcyata/items/342073fa7607fd4082bd)
- [Swaggerの記法まとめ](https://qiita.com/rllllho/items/53a0023b32f4c0f8eabb)
- [multi-file-swagger(npm)](https://www.npmjs.com/package/multi-file-swagger)
- [multi-file-swagger(GitHub)](https://github.com/mohsen1/multi-file-swagger-example)
Visual Studio Codeで`bash.exe`ファイルが見つからないというエラー

# 起きたエラー

以下の記事を参考にしてVisual Studio Codeに競プロ用の環境を構築していました。

https://qiita.com/2019Shun/items/5ab290a4117a00e373b6

構築が完了した後、デバッグを行うと以下のようなエラーが出てしまい、デバッグがうまくいきませんでした。

![vscodeデバッグエラー01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/6ca61d5a-2ebe-7f5c-e686-b5a893dc91f5.png)

ちなみに詳細に理解できておらず申し訳ないですが、エラーに表示されているパスは
```
C:\Windows\System32\bash.exe
```
を指しているようで、そこに`bash.exe`が存在していることは確認しました。

![vscodeデバッグエラー02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/0e16a71f-8593-8e20-730d-7d69c1026227.png)

# 対応(暫定)
参考にした記事のlaunch.jsonを下記のように修正することで対応しました。
```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Bash on Windows Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${command:extension.vscode-wsl-workspaceFolder}/problem.exe",
            "args": ["<", "${command:extension.vscode-wsl-workspaceFolder}/problem.in"],
            "stopAtEntry": false,
            "cwd": "${command:extension.vscode-wsl-workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                //"pipeProgram": "${env:windir}\\system32\\bash.exe", // 修正前 (コメントアウト)
                "pipeProgram": "\\Windows\\System32\\bash.exe", // 修正後
                "pipeArgs": ["-c"],
                "pipeCwd": "/"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "sourceFileMap": {
                "${command:extension.vscode-wsl-workspaceFolder}": "${workspaceFolder}"
            },

        }
    ]
}
```
コメントアウトした部分`"pipeProgram": ${env:windir}\\system32\\bash.exe`が本来`C:\Windows\System32\bash.exe`を指してくれるはずなのですが、なぜかエラーが起きてしまいます。そこで、環境変数などを使用せずに直接`bash.exe`のパスを指定して対応した次第です。
元記事のコードの内容を修正したために暫定の対応としておりますが、この修正後はデバッグでエラーが発生していません。

以上です。

# 参考

https://qiita.com/2019Shun/items/5ab290a4117a00e373b6
Elixirの対話モードでコレクションの動作を確認してみた

# 概要
Elixirの対話モードでコクションの動作を確認してみました。以下のページを参考にしました。

https://elixirschool.com/ja/lessons/basics/collections

# 対話モードで実行
以下のコマンドを実行しました。
```
$ iex
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex(2)> list = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex(3)> ["π" | list]
["π", 3.14, :pie, "Apple"]
iex(4)> list ++ ["Cherry"]
[3.14, :pie, "Apple", "Cherry"]
iex(5)> [1, 2] ++ [3, 4, 1]
[1, 2, 3, 4, 1]
iex(6)> ["foo", :bar, 42] -- [42, "bar"]
["foo", :bar]
iex(7)> [1,2,2,3,2,3] -- [1,2,3,2]
[2, 3]
iex(8)> [2] -- [2.0]
[2]
iex(9)> [2.0] -- [2.0]
[]
iex(10)> hd [3.14, :pie, "Apple"]
3.14
iex(11)> tl [3.14, :pie, "Apple"]
[:pie, "Apple"]
iex(12)> [head | tail] = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex(13)> head
3.14
iex(14)> tail
[:pie, "Apple"]
iex(15)> {3.14, :pie, "Apple"}
{3.14, :pie, "Apple"}
iex(16)> File.read("./file")
{:ok, ""}
iex(17)> File.read("./file2")
{:error, :enoent}
iex(18)> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex(19)> [{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
iex(20)> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
iex(21)> map[:foo]
"bar"
iex(22)> map["hello"]
:world
iex(23)> key = "hello"
"hello"
iex(24)> %{key => "world"}
%{"hello" => "world"}
iex(25)> %{:foo => "bar", :foo => "hello world"}
warning: key :foo will be overridden in map
  iex:25

%{foo: "hello world"}
iex(26)> %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(27)> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
true
iex(28)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(29)> map.hello
"world"
iex(30)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(31)> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
iex(32)> map = %{hello: "world"}
%{hello: "world"}
iex(33)> %{map | foo: "baz"}
** (KeyError) key :foo not found in: %{hello: "world"}
    (stdlib 3.17) :maps.update(:foo, "baz", %{hello: "world"})
    (stdlib 3.17) erl_eval.erl:256: anonymous fn/2 in :erl_eval.expr/5
    (stdlib 3.17) lists.erl:1267: :lists.foldl/3
iex(33)> Map.put(map, :foo, "baz")
%{foo: "baz", hello: "world"}
iex(34)> 
```

# まとめ
何かの役に立てばと。
RubyでAtCoder ABC250(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC250のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Adjacent Squares
https://atcoder.jp/contests/abc250/tasks/abc250_a
```ruby:a-250.rb
h, w = gets.split.map(&:to_i)
r, c = gets.split.map(&:to_i)

puts [1 - r, 1 - c, r - h, c - w].count{ _1 < 0 }
```
## 解説
求める答えは、`1 < R`, `1 < C`, `R < H`, `C < W`の４つの条件を与えられたR, Cがいくつ満たしているかと同値になるので、`count`メソッドを使って数え上げることで解くことができます。

# B - Enlarged Checker Board
https://atcoder.jp/contests/abc250/tasks/abc250_b
```ruby:b-250.rb
n, a, b = gets.split.map(&:to_i)

n.times do |i|
  array = []
  n.times do |j|
    (i + j).even? ? array << "." * b : array << "#" * b
  end
  a.times{ puts array.join }
end
```
参照する形にする。
```ruby:別解
n, a, b = gets.split.map(&:to_i)
strs = ["." * b, "#" * b]

n.times do |i|
  array = []
  n.times do |j|
    array << strs[(i + j) % 2]
  end
  a.times{ puts array.join }
end
```
他の方の提出結果を拝見したところ、上記コードはもう少し簡素に書けるようです。
```ruby:b-250.rb
n, a, b = gets.split.map(&:to_i)

puts (1..n).map{ |i| [(1..n).map{ |j| ((i + j).odd? ? "#" : ".") * b }.join] * a}
```
## 解説
0から始まるオフセットで考えると、(0, 0)が白いマスであることから`i+j`が偶数となるところが`.`となり、奇数となるところが`#`となることが分かります。後は、aとb分適宜マスを増やせば答えが求まります。

# C - Adjacent Swaps
https://atcoder.jp/contests/abc250/tasks/abc250_c
```ruby:c-250.rb
n, q = gets.split.map(&:to_i)

ans = [*1..n]
index_of_ball = n.times.to_h{ |i| [i + 1, i] }

q.times do
  x = gets.to_i
  base = next_to = index_of_ball[x]
  next_to += (next_to == n - 1) ? -1 : 1
  ans[base], ans[next_to] = ans[next_to], ans[base]
  index_of_ball[ans[base]], index_of_ball[ans[next_to]] = index_of_ball[ans[next_to]], index_of_ball[ans[base]]
end
puts ans.join(" ")
```
```ruby:別解
n, q = gets.split.map(&:to_i)

ans = [*1..n]
index_of_ball = n.times.to_h{ |i| [i + 1, i] }

q.times do
  x = gets.to_i
  base = index_of_ball[x].clamp(..n - 2)
  x, y = (ans[base, 2] = ans[base + 1], ans[base])
  index_of_ball[x], index_of_ball[y] = index_of_ball[y], index_of_ball[x]
end
puts ans.join(" ")
```
## 解説
（公式解説を参考にしました）

答えとなる配列を`[*1..n]`で初期化するとともに、ボールがどこにあるかを記録する連想配列を用意します。そして、問題文の通りに配列とボールの位置の情報を更新していくことで本問題は解くことができます。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
Stable Diffusion web UIを起動する際にオプションをつけて高機能で動かす

Stable Diffusion web UIには様々なオプションがあり、起動時に付与することでより便利に使うことができます。
この記事では一部のオプションの説明と、オプションをどのように付与するかについて解説します。

## よくある立ち上げ方
Google ColabやWindowsの場合、以下のようなコマンドで立ち上げることが多いと思います。

```
$ python launch.py --share --xformers

$ ./webui.sh
```

以下のオプションは解説記事などでもよく出てきますがそれぞれこのような意味があります。

`--share`
web UIをGradioで起動して閲覧できるようにする

`--xformers`
生成速度の向上

## オプションの付け方

### ①コマンドライン引数

起動時にコマンドライン引数として渡す
`python launch.py オプション1 オプション2 ...`

```sh:例
$ python launch.py --share --xformers
```

### ②webui-user.shを編集する

webui-user.shというファイルの中に以下のコードがあるので探してみてください。
```
#export COMMANDLINE_ARGS=""
```

先頭の#を削除してオプションを書きます。
```
export COMMANDLINE_ARGS="--share --xformers"
```

この状態で保存し`python launch.py`や`./webui.sh`を実行すればコマンドライン引数を付けなくてもオプションが有効になります。


## オプション一覧

オプション一覧は以下のファイルに説明と共に書かれています。

https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/modules/cmd_args.py

GradioにBasic認証をつける`--gradio-auth`やUIの見た目を変える`--theme`などがありこれらのオプションをつけることでweb UIをより高機能にすることができるのでぜひいろいろ試してみてください。
【JavaAPI】日付を扱うクラス

# はじめに
Javaでは、日付や時刻を効果的に扱うための便利なAPIが提供されています。
この記事では、Javaで日付を操作するための主要なAPIとその使い方について解説します。

## java.timeパッケージの使い方 (Java 8以降)
次のコードはjava8以降で使用することを前提としております。
java8以前のバージョンでは正しく動作しない恐れがあります


### 日付の作成
```java

import java.time.LocalDate;

// 現在の日付を取得
LocalDate currentDate = LocalDate.now();

// 特定の日付を作成
LocalDate date = LocalDate.of(2023, 6, 3);
```
### 日付のフォーマット

```java
import java.time.format.DateTimeFormatter;
import java.time.LocalDate;

LocalDate date = LocalDate.now();

// 日付を指定したフォーマットで表示
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formattedDate = date.format(formatter);
System.out.println(formattedDate);
```
### 時間のフォーマット

```java
import java.time.LocalTime;

// 現在の時刻を取得
LocalTime currentTime = LocalTime.now();

// 時、分、秒を取得して出力
int hour = currentTime.getHour();
int minute = currentTime.getMinute();
int second = currentTime.getSecond();

System.out.println("現在の時刻: " + hour + "時" + minute + "分" + second + "秒");

```

### 日付の計算
```java
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

LocalDate date1 = LocalDate.now();
LocalDate date2 = date1.plusDays(7); // 7日後の日付を取得
long daysBetween = ChronoUnit.DAYS.between(date1, date2); // 日数の差を計算
System.out.println(daysBetween);
2. java.util.Dateクラスの使い方 (旧API)
Java 8以前のバージョンでは、java.util.Dateクラスが日付と時刻を表すために使用されていました。以下に、java.util.Dateクラスの使い方を示します。
```
### 日付の作成
```java
import java.util.Date;

// 現在の日付と時刻を取得
Date currentDate = new Date();

// 指定した年月日の日付を作成
Date date = new Date(123, 5, 3); // 1900年を基準とした年月日で指定
```
### 日付のフォーマット

```java
import java.text.SimpleDateFormat;
import java.util.Date;

Date date = new Date();

// 日付を指定したフォーマットで表示
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
String formattedDate = formatter.format(date);
System.out.println(formattedDate);
```

### 日付の計算
```java
import java.util.Date;

Date date1 = new Date();
long millisToAdd = 7 * 24 * 60 * 60 * 1000; // 7日分のミリ秒
Date date2 = new Date(date1.getTime() + millisToAdd); // 7日後の日付を計算
```


## まとめ
この記事では、Javaで日付を扱うための便利なAPIの使い方について紹介しました。Java 8以降ではjava.timeパッケージを使用することで、柔軟で使いやすい日付操作が可能になりました。LocalDateクラスを使用して日付を作成し、DateTimeFormatterクラスを使用して日付のフォーマットを指定することができます。また、日付の計算にはChronoUnitクラスを使用することができます。

また、旧バージョンのJavaではjava.util.DateクラスとSimpleDateFormatクラスが使用されていました。これらを使う場合は、注意が必要ですが、既存のコードやライブラリが使用している場合には適切に変換することができます。

日付の処理は多くのアプリケーションで重要な要素です。正確な日付操作を行うために、適切なAPIを選択し、その使い方を理解することが重要です。Javaの日付APIは豊富で使いやすいため、プロジェクトで日付を操作する際に活用してください。
Salesforce DevToolsの基本機能のまとめ

## はじめに
Salesforceの開発者にとっては、「Salesforce DevTools」は欠かせないツールです。
本記事では、「Salesforce DevTools」の概要と基本的な機能について解説をしていきます。

## Salesforce DevToolsとは
Salesforce DevToolsとは、Salesforceの開発者向けの機能を盛り込んだ、Chromeの拡張機能のこと。
当該拡張機能のインストールは下記から実施可能。
- [Chrome Web StoreからSalesforce DevToolsをインストール](URL "https://chrome.google.com/webstore/detail/salesforce-devtools/ehgmhinnhggigkogkbhnbodhbfjgncjf/related")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/759b40a6-0839-0b6e-01e6-0d0c9f1c73e4.png)
※Chromeの拡張機能だが、Edgeに対してインストールすることも可能。

## 基本的な機能の紹介
Salesforce DevToolsでは、以下のような機能が使用できる。

### 1. 各種定義書の自動生成
- Salesforce内の下記の定義書を作成することが可能。
    - オブジェクト定義書
    - ページレイアウト定義書
    - リストビュー定義書
    - ER図
- 対象オブジェクト（リストビュー、詳細画面など）をブラウザ画面上で開き、Salesforce DevToolsからワンクリックで定義書をExcel形式でダウンロードできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/219498ba-06c9-face-2567-e8faf636bd0b.png)

### 2. SOQLのクイック自動生成、データエクスポート
- 開発者コンソールのSOQL機能をさらに使いやすくしたQuery Editor。使い勝手が良い点として、項目ラベルとAPI参照名を確認しながらSOQL文を作成できることが挙げられる。
- また、クエリ結果をそのままExcelとしてエクスポートできる。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/a176b028-390a-97f5-85a3-96dfdec3038d.png)

### 3. オブジェクトの検索
- その名の通り、組織内のオブジェクトを検索することが可能。また、該当のオブジェクトに対する主要ページに簡易に遷移することが可能。具体的には下記の通り。
    - レコードの新規作成
    - リストビュー
    - オブジェクトの設定画面
    - Salesforce公式項目API参照ページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/6f897855-0332-7939-b684-5be331f0d24d.png)


### 4. オブジェクトのAPI参照名の表示・非表示機能
- 特定のオブジェクトの詳細ページを開いて状態で、［Show Object API Name］を押下すると、各種項目のAPI名が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/3096d578-7091-140c-8766-988cab35f742.png)

### 5. カスタム項目の一括編集、一括削除、一括コピーおよび他のオブジェクトへのコピー作成機能
- Salesforce DevToolsから［Object Fields］を押下すると、項目の一覧を参照することができる。
- この画面上では、カスタム項目に対して、一括編集・削除、他オブジェクトへのコピーが可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025346/3864df9e-f990-5e78-af15-46ffc7ed7c5d.png)

## まとめ
- Salesforceでは、オブジェクトの情報を参照するためには、その都度細かい画面遷移が必要である。Salesforce DevToolsを使えば、より少ない操作でオブジェクトの全体像を把握できる。
- 定義書の出力機能は魅力的であるものの、実案件では、このフォーマットがそのまま使用されることはなさそう。
GitHub ActionsからGitHub Pagesにデプロイする

# はじめに

- この記事では、GitHub ActionsからGitHub Pagesにデプロイする方法についてまとめている
- 今回、主に使用するアクションはGitHub Pages Action
    - GitHub Pagesへのデプロイをサポートするサードパーティ製のアクション
    - GitHub: https://github.com/peaceiris/actions-gh-pages
- 同様の機能を提供するアクションとしてupload-pages-artifactとdeploy-pagesも存在する
    - こちらはGitHub公式のアクションだが、まだドキュメントが少ない印象
    - GitHub
        - https://github.com/actions/upload-pages-artifact
        - https://github.com/actions/deploy-pages

# 準備

- まずはGitHub Pagesのデプロイ先に使用するブランチを作成する
    - Code > Branches > New Branch から作成可能
    - 今回は`gh-pages`ブランチを作成をした
- 次にGitHub Pagesの公開設定を行う
    - Settings > Pages > GitHub Pages > Build and deployment から設定可能
    - 「Source」は`Deploy from a branch`を選択
    - 「Branch」は`gh-pages`ブランチの`/ (root)`を選択
        - 任意のブランチ(デフォルトブランチも可)の`/ (root)`か`/docs`を公開可能

# 設定

- GitHub Actionsのワークフローの設定

```yaml:.github/workflows/example.yml
name: Publish GitHub Pages

# git pushをトリガにワークフローが実行される
on:
  push:

# 書き込み権限の付与
permissions:
  contents: write

jobs:
  publish-gh-pages:
    runs-on:
      - ubuntu-latest

    steps:
      # GitHub Pagesに公開するファイルの作成
      # 実際はGitリポジトリをチェックアウトしてそこからビルドすることが多い
      - name: Create index.html
        run: |
          mkdir -p ./dist
          echo "hello, world!" > ./dist/index.html

      # GitHub Pagesに公開
      # デフォルトではgh-pageeブランチにpushする
      - name: Push gh-pages branch
        uses: peaceiris/actions-gh-pages@v3
        with:
          # Deploy keysやPersonal access Tokensも使用可能
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist
          # keep_filesをtrueにすると、git pushの度に一旦全てのファイルが削除される挙動を抑制できる
          # keep_files: true
          user_name: github-actions
          user_email: github-actions@github.com
```

- 公開されたGitHub Pagesは https://user_name.github.io/repository_name/file_name でアクセス可能
データベースで消耗していた話

データベースで消耗している話

https://zenn.dev/ep_ito/articles/ad19d7abfa4e0019f7a7

を拝読して何点か昔を思い出しながら記録します。　

# RDBより前

データベースで消耗していたのは、RDBが出る前のことです。　

メインフレームベンダごとに、専用のDBを持っていて、データの移植性も悪いは、データ呼び出しの移植性も悪い。　

いっそ、COBOLだけで書いてあれば、なんとでもなるものを、わざわざ専用のDBにいれて、囲い込む感じのご商売をされていた。　

メインフレームで移植できないのは、COBOLではなく、DBとバッチファイル（スクリプト）と文字コードと文字フォントです。
それぞれのメインフレームでは、専用のDBへのアクセスする部分は移植は困難。　

# SQL

オンプレミス時代のうち、メインフレーム時代には、メインフレーム固有のDBしかなかった。　

SQLで検索できるようになったのは、SQLが国際規格になったころからかもしれない。　

ISO 9075:1987 Information processing systems — Database language — SQL

https://www.iso.org/standard/16661.html

欲しかったのは、RDBではない。SQLだった。どんなDBでも同じSQLで出し入れできれば良い。

ISO/IEC 9075-1:2023 Information technology — Database languages SQL — Part 1: Framework (SQL/Framework)

https://www.iso.org/standard/76583.html

実際には、DBソフトごと、、ハードウェアごと、データ構造ごとに、　固有の方言があった。

JAVAの時代には、ミドルウェアが横行し、有償のミドルウェアでチューニングしないと高速処理、簡単処理ができないという傾向があったかもしれない。　

高額なミドルウェアが購入できず、DB教育から撤退させていただいた。

>オンプレミス時代にはMySQL等の関係データベース (Ralational Database, RDB) しか選択肢が無く
　
関係データベース以外の有象無象のデータベースがありました。　
移植性が悪く、かつ、何か、関係データベースにすれば、なんでも解決するというような触れ込みをしていた人がいたかもしれません。　

関係データベース以外には、データ量に応じて、構造を決めて、COBOLでファイルを持ってプログラムすることもありました。　

そういうのは、なかったことにしたい人がいるのかもしれません。　

膨大なデータでなければ、テキストだけの処理はそれなりにありました。　

# COBOL

COBOLは移植性が悪いから、RDBにした方がいいんだという、意味不明の論理で、RDBにどんどん入れていった人たちがいたような気がします。　

COBOLは、国際規格になっていて、その部分だけ使えば、移植性はすごく高いんです。　
課題は、COBOLではなく、文字コードと文字フォント。　
日本語を表現する文字コードが、いくつかの種類があり、その間の変換が大変だった。　

今昔文字鏡が出る前は、外字というものをすごく高いお金を払って作って、
異なる文字コード、異なるOSの間での変換がとても大変だった。　

Windowsで今昔文字鏡を使えば、いっきに解決してしまう。　

大手のベンダでは、それでは困ると、営業が「トラックで店につっこむぞ」って脅したという都市伝説があるらしい。　

ふりかえると、問題は、COBOLでもRDBでもなく、文字コードと文字フォントとOSとメインフレーム専用DBが、消耗の根源。　

文字鏡フォント。追悼　古家 時雄。日本語（２）

https://qiita.com/kaizen_nagoya/items/64c2ff25271ea8ebf2b0

日本語語彙大系　追悼：白井諭。Lisperへの敬意を込めて。

https://qiita.com/kaizen_nagoya/items/e41ed513c8686841399b

日本語語彙大系　白井 諭　<エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/e59d6d37b35de929261a



「今日死ぬとしたら」日本語が不得意なプログラマが話をする　日本語（12）　仮説（116）

https://qiita.com/kaizen_nagoya/items/61a03864ac6c011e6164


 ＜この記事は書きかけです。順次追記します。＞
 
 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
# 文書履歴(document history)
ver. 0.01初稿　20230602お

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
久しぶりにGNS3（その25：L2TPをWiresharkで確認）

# WiresharkでL2TPv3（＋データ）を確認
こちら「[久しぶりにGNS3（その９：L2トンネリング/ブリッジ）](https://qiita.com/infinite1oop/items/14ab43877d5d417df1aa)」の続き。Wiresharkで、L2TPv3上のデータを確認することができたので、その記録。

## 環境
![Topology.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9fde542f-da31-afe4-c010-efc2de1b47b3.png)
末端のDHCPClientとDHCPServerとが同一セグメント（10.0.0.0/24）となるように、Router2とRouter3とにL2TPv3の設定を行う。

### 設定
Router2とRouter3では、[前回](https://qiita.com/infinite1oop/items/14ab43877d5d417df1aa)と同じ設定ができなかったため（理由不明）、再度記載（関連する部分のみ）。

```
! Router2

pseudowire-class L2TP
 encapsulation l2tpv3
 ip local interface FastEthernet0/0

interface FastEthernet0/0
 ip address 192.168.1.2 255.255.255.0

interface FastEthernet0/1
 no ip address
 xconnect 192.168.2.2 1 encapsulation l2tpv3 pw-class L2TP sequencing both

ip route 0.0.0.0 0.0.0.0 FastEthernet0/0
```
```
! Router3

pseudowire-class L2TP
 encapsulation l2tpv3
 ip local interface FastEthernet0/0

interface FastEthernet0/0
 ip address 192.168.2.2 255.255.255.0

interface FastEthernet0/1
 no ip address
 xconnect 192.168.1.2 1 encapsulation l2tpv3 pw-class L2TP sequencing both

ip route 0.0.0.0 0.0.0.0 FastEthernet0/0
```

## 検証
### Wireshark設定
#### ...としてデコード
「分析」→「...としてデコード」にて
![としてデコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/6d9ea4a0-f9c6-1de6-29db-2b54b4567e1b.png)
![としてデコード２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/79826381-bcc3-9d64-e312-773e7b995101.png)
L2TPv3 payload typeを「Ethernet」に変更する（デフォルトは「CHDLC」）となっている。単純ではあるが、データ（Payload）がEthernetのため。

#### L2TPv3 Cookie Size
「プロトコル設定」→「Layer2 Tunneling Protocol」→「L2TPv3 Cookie Size」を「4 Byte Cookie」とする。
![4byteCookie.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/52a7d9ea-7b7e-cb2b-4e3e-86212b9aa2ba.png)
どうも、Cookieサイズは環境により異なるらしい。今回の場合、L2TPv3の標準（RFC3931）およびWiresharkのデータから、4バイトと判断した。少なくとも、L2TPv3 Peerどうしで、同じサイズを用いる必要あり。

### 結果
Wireshark上で、DHCPシーケンスおよびICMP(ping)の状況は下記となる。
![ARP&DHCP&ICMP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fce48bfa-bda3-eac3-810f-aa675dd74155.png)
末端のDHCPClientおよびDHCPServer間のARP、DHCP、ICMPが正しくデコードされている。

### L2TPv3シーケンス
Wireshark上で確認できた、L2TPv3シーケンスは下記となる。
![シーケンス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f2710c3b-a972-25be-8e9e-6ba78f135572.png)
シーケンスについては、「[L2TPv3を用いたL2VPN](http://www.rtpro.yamaha.co.jp/RT/docs/l2tpv3/index.html
)」などに記事が見つかる。また、最初のSCCRQ/SCCRPにて、サポートするL2タイプを提示している。
![Capability.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/a549bf62-3cbb-9571-d2ce-a5d12cd10f5e.png)
Cookieサイズの提示も行われていると思ったが、Wireshark上のデータで見つけることはできず。ただし、L2TPv3の標準であるRFC3931には、「Assigned Cookie (ICRQ, ICRP, OCRQ, OCRP)」という記載があり、
<I>The Assigned Cookie AVP, Attribute Type 65, contains the Cookie value being assigned to this session by the sender.</I>
ネゴシエーションも可能のように思える。このあたりは、実装依存なのであろう。

## 終わりに
RFCなどの標準を理解（データ構造）した上で、Wiresharkを使いこなすのがベター。
CodeIQ:単調増加で単調減少な数列の解答

@nabetaniさんのCodeIQの問題です。
https://nabetani.hatenablog.com/
問題とテストケースはこちらのお世話になりました。解答もあります。
->https://blog.goo.ne.jp/r-de-r/e/28c8d445af29200db96e1f7d5e4148c8

力技です。スマートな方法は思いつきませんでした。
単調減少数の方をbetween/3を多用して大きいほうから作成し、十進数に変換(ft/5)し、
a進数で桁の小さいほうから調べます(che/3)。
between/3が降順にできないので補正(between(0,M,K),K1 is B-K)しています。
単調減少数も桁の小さい方から作り、桁ごとにチェックしたほうがましかとも思いましたが、
複雑になりそうなので断念しました。

```Prolog
%SWI-Prolog version 7.4.2,7.6.4  
%:-initialization(solv48).  %ideone
%solv48.

che(_,0,_):-!.
che(B,N,X):-divmod(N,B,D,M),M<X,che(B,D,M).

solv48:-f48(A,B,Q),(calc48(A,B,R)->disp48(R,Q);writeln(fail)),fail.
solv48.

calc48(A,B,R):-N1 is B-1,between(0,N1,K),N2 is  B-K,ft(B,N1,N2,0,R),che(A,R,A),!.

ft(_,_,0,R,R):-!.
ft(B,N1,N2,X,R):-
     M1 is N2-1,M2 is N1-M1,between(0,M2,K),K1 is N1-K,K2 is K1-1,
     Y is X*B+K1,ft(B,K2,M1,Y,R).

disp48(R,Q):-(R=:=Q->Str="good ";Str=" bad "),write(" "),write(Str),writeln(R).

f48(5, 6,19).
f48(15, 16,15571062).
f48(13, 16,16558437).
f48(2, 16, 1).
f48(2, 2, 1).
f48(3, 2, 2).
f48(7, 11, 1266).
f48(11, 7, 2276).
f48(11, 10, 3210).
f48(16, 2, 2).
f48(16, 15, 35806).
f48(16, 16, 15).
f48(16, 13, 363743).
```
TeraTarm ブロードキャストコマンドを試してみた

## はじめに
TeraTarmのブロードキャストコマンドとは同時に複数のサーバーに同じコマンドを実行する際に使用されるそうです。
あまり利用する機会はないですが便利な機能です。

前提条件
VirtualBoxでゲストOS 2台立てました CentOS7です。


## 試したこと

### TeraTermでゲストOS2つに接続しました。

TeraTarmのコントロールを選択し、ブロードキャストを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/393ff6a6-f402-e3b3-dc69-89656770e4e4.png)

### ゲストOS2つにコマンドを実行してみた
対象サーバーを選択して、赤枠のボックスにコマンドを入れます。
※選択したサーバーは青色になります。

ユーザーを追加
```
useradd test5
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/e81a7ced-cfa4-67c3-7dec-a7da69b455e5.png)


### ユーザーがゲストOS2台にTEST5ユーザーが登録されていることを確認した
```
tail -1  /etc/passwd
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/32cd4f7a-f2df-50d8-1e96-3ea7ce1c599d.png)

#### 補足情報　リアルタイムにチェックあり
パスワードの設定を試したが、コピー＆ペーストでパスワードを張るとうまくいきませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/8f40ea05-2576-7869-8986-e1f126b1ce3c.png)


パスワードを手入力の場合は上手くパスワード設定出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/e2873011-3673-469a-ee77-494f9be3cfc8.png)

#### 追加情報 20230701　リアルタイムにチェックなし
リアルタイプのチェックを外したらパスワードをコピー＆ペーストですが張り付けることが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/4036333e-c812-44e8-2b7e-39ea2a38a34a.png)

上記で設定するとSSH接続の際に認証に失敗します。現在調査中です。

## まとめ
TeraTarm ブロードキャストコマンドは複数サーバーに同時に同じコマンドを実行する際に
便利な機能なため覚えておいた方が良いです。
パスワードの設定は上手くいきませんでした。
運用作業を効率化するためには便利な機能は探したら見つかる場合があります。
普段から効率が良い方法を見つける様にしたいです。
Databricksノートブックでデータブラウザがサポートされます！

これでさらに開発が捗ります。

Databricksノートブックでコード書いている際に、データベースやカタログにアクセスするというのは、よくあることかと思います。

ただ、「あのデータベースやテーブルの名前なんだっけ？」や「テーブルのカラム名がわからない」という場合、これまでは、`SHOW DATABASES`や`DESCRIBE TABLE`を実行したり、データエクスプローラに移動しないといけませんでした。

しかし、これからはノートブック上から直接これらを確認できるようになります！

マニュアルはこちら。

https://qiita.com/taka_yayoi/items/dfb53f63aed2fbd344fc#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%96%E3%83%A9%E3%82%A6%E3%82%BA

リリースノートはこちら。

https://docs.databricks.com/release-notes/product/2023/june.html#view-data-from-notebooks-sql-editor-and-data-explorer-with-the-unified-schema-browser-public-preview

ノートブック左の![](https://camo.qiitausercontent.com/12cab98fb3d42389d2eed862c2eb8e4451f626a7/68747470733a2f2f646f63732e64617461627269636b732e636f6d2f5f696d616765732f6e6f7465626f6f6b2d646174612d69636f6e2e706e67)をクリックするとカタログやデータベース、テーブルを参照できるデータブラウザが表示されます。
![Screenshot 2023-06-03 at 9.00.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/78340401-b2d0-cd9e-df73-e66393321bda.png)

**自分用**をクリックすると、現在のセッションでオープンしているテーブルのみが表示されます。作業で使用するテーブルは限定されるのでこれも便利かと。
![Screenshot 2023-06-03 at 9.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6dffa480-2dcc-2671-6566-256f458b402f.png)

コンテキストメニューも使用できます。
![Screenshot 2023-06-03 at 9.02.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8a93bc07-f670-49c6-c31b-3cdb7823c10a.png)

間も無く日本リージョンでも使用できるようになりますので、是非ご活用ください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Azure DNS で一時的に TTL を短くしておいて後から戻す AzureCLI を試してみた

オンプレ DNS から AzrueDNS に DNS ゾーンを移行する時など、一時的に DNS レコードの TTL を短くして、クライアントのネガティブキャッシュを含むキャッシュを短くしておいて切り替えたい場合があります。DNS ゾーン数や DNS レコード数が少なければ手動でも良いのですが、複数あると面倒です。そこで AzureCLI を使って Azure DNS に設定済みの TTL を含むレコード情報を全て JSON で保存しておき、TTL を 600 秒に設定したのち、TTL を戻す一連の動作を検証してみました。

## 検証環境を準備

```bash:bash
# 環境変数をセットします
prefix=mnrdns
region=japaneast

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region

# example.jp ゾーンを作成します
az network dns zone create \
  --resource-group ${prefix}-rg \
  --name example.jp

# example.jp に A レコードを作成します
az network dns record-set a add-record \
  --resource-group ${prefix}-rg \
  --zone-name example.jp \
  --record-set-name www \
  --ipv4-address 93.184.216.34

# example.com ゾーンを作成します
az network dns zone create \
  --resource-group ${prefix}-rg \
  --name example.com

# example.com に A レコードを作成します
az network dns record-set a add-record \
  --resource-group ${prefix}-rg \
  --zone-name example.com \
  --record-set-name www \
  --ipv4-address 93.184.216.34
```

## Azure DNS ゾーンのリストを取得

```bash:bash
zones=$(az network dns zone list \
  --resource-group ${prefix}-rg \
  --query "[].name" \
  --output tsv)
```

## Azure DNS ゾーンのレコード情報を保存

```bash:bash
for zone in ${zones[@]}; do
  echo "--- $zone ---"
  az network dns record-set list \
    --resource-group ${prefix}-rg \
    --zone-name $zone \
    > $zone.json
done
```

## 全レコードの TTL を 600 秒に設定

```bash:bash
for zone in ${zones[@]}; do
  echo "--- $zone ---"
  ids=$(cat $zone.json | jq -r .[].id)
  for id in ${ids[@]}; do
    echo $id
    az resource update \
      --set properties.TTL=600 \
      --ids $id
  done
done
```

## 保存しておいた JSON から TTL を戻す

```bash:bash
for zone in ${zones[@]}; do
  echo "--- $zone ---"
  lines=$(cat $zone.json | jq -c '.[] | {id,TTL}')
  for line in ${lines[@]}; do
    id=$(echo $line | jq -r .id)
    ttl=$(echo $line | jq -r .TTL)
    echo "$ttl : $id"
    az resource update \
      --set properties.TTL=$ttl \
      --ids $id
  done
done
```

## 検証環境を削除

```bash:bash
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://learn.microsoft.com/ja-jp/cli/azure/network/dns/record-set?view=azure-cli-latest#az-network-dns-record-set-list-examples

https://learn.microsoft.com/ja-jp/cli/azure/resource?view=azure-cli-latest#az-resource-update
GithubにSSH接続する

# SSHキー発行からGithubSSHキーの設定まで(mac環境)

## SSHについて
事前に公開鍵をサーバー側に配置しておき、ログイン時の認証処理において、ローカルに配置された秘密鍵と照合して本人確認する。
SSHを利用すれば、クラウドサーバー等にログインしてコマンドを実行して操作することが可能になる。
認証方式が甘いと簡単に不正アクセスされてしまう。

## 公開鍵認証のポイント
- 認証に必要な秘密情報そのものはネットワーク上に送出されない
- 認証に使われる署名は一時的なもので再利用はできない
- 秘密鍵を推測して偽造することは非常に困難
- パスフーレーズを設定して鍵そのものをロックすることができる

[参考：SSH公開鍵認証とは](https://pfs.nifcloud.com/navi/words/ssh.htm#:~:text=「公開鍵認証」とは,保管しておきます%E3%80%82 "SSH公開鍵認証とは")

## SSHキーの確認
ターミナルを開いて`ls -al ~/.ssh`を入力して、既存のSSHキーが存在するかどうか確認する。

ディレクトリの一覧から、公開SSHキーをすでに持っているか確認する。

> GitHubでサポートされている公開キーのファイル名
> - id_rsa.pub
> - id_ecdsa.pub
> - id_ed25519.pub

新しいSSHキーを生成するか、既存のキーをアップロードする

## 新しいSSHキーを生成する

ターミナルを開いて以下のコマンドを実行する

```sh
ssh-keygen -t ed25519 -C "your_email_address"
```

以下のプロンプトが表示されたらパスフレーズを入力する

> Enter passphrase (empty for no passphrase): [Type a passphrase]
> Enter same passphrase again: [Type passphrase again]

## SSHキーをssh-agentに追加して、パスフレーズをキーチェーンに保存する

何度も認証が必要になるような環境だと、パスフレーズの入力が大きなストレスになる。ssh-agentを起動して秘密鍵を登録しておけば、sshコマンドを実行した際に自動的に秘密鍵を適用して認証処理を行なってくれる。パスフレーズの入力は、秘密鍵の登録時に一度行うだけで済む。


バックグラウンドでssh-agentを開始する
```sh
eval "$(ssh-agent -s)"
```

`~/.ssh/config`ファイルを編集する
```
# common
Host *
 AddKeysToAgent yes
 UseKeychain yes

# github
Host github
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_ed25519
```

SSH 秘密鍵を ssh-agent に追加して、パスフレーズをキーチェーンに保存

```sh
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
```

GitHub で自分のアカウントに SSH 公開キーを追加する

## GitHubに登録してある公開鍵をauthorized_keysに追加する
```sh
curl https://github.com/${GITHUB_ACCOUNT_NAME}.keys >> ~/.ssh/authorized_keys
```

## ssh配下のアクセス権限の設定

```sh
chmod 700 ~/.ssh	#ファイル又はディレクトリ所有者へすべてのアクセス権限を与える drwx------
chmod 600 ~/.ssh/id_ed25519	#ファイル又はディレクトリ所有者へ書き込み・読み込みのアクセス権限を与える -rw-------  
chmod 600 ~/.ssh/authorized_keys #-rw-------  

ls -la ~/.ssh #権限の確認
```

## 確認及び接続テスト

キーの確認
```sh
cat ~/.ssh/id_ed25519.pub
```

接続テスト
```sh
ssh -T git@github.com
```
以下のように選択してメッセージが表示されれば成功


> Are you sure you want to continue connecting (yes/no)?　→ yes
> Hi USERNAME! You've successfully authenticated, but GitHub does not
> provide shell access. → OK
Azure DevOps Tips - Visual Studioで作成済みのソリューションをAzure Reposで管理する②

# 概要
以前に[同様の記事](https://qiita.com/yossihard/items/154efb0e1582ceb1cddb)を書いたのですが、
Visual Studioのバージョンアップ等で情報が古くなったので、
改めて書き直し。

# 環境
Visual Studio 2022 (Version 17.5.0)

# 手順
### Azure DevOps側にプロジェクトを新規作成
Azure DevOpsにログインして、「+ New Project」ボタンをクリックします。
以下のような画面が出るので、任意に情報を入力して、「Create」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/b9d492ee-9ad0-1f2f-0a97-5d9f7ac43f26.png)

### Visual Studio側からプロジェクトを登録
1. Git リポジトリの作成メニューをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/5a7bae4c-ce3e-6cd0-89df-a50ce503ed22.png)

1. 以下のような画面が表示されるので、左側から「Azure DevOps」を選択し、先に作成したAzure DevOpsのプロジェクトを選択します（リポジトリ名は任意）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/a50ab2d7-f543-1e64-0ebb-97e0c8c5f3ce.png)

1. 作成とプッシュをクリックします。バックグランドで自動的に処理が開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/63c30141-80bd-dc54-e1b0-04d7cb3aa2dd.png)

1. 処理が完了すると、以下のようなメッセージがGit変更のタブに表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/3fb002ff-477d-bd71-1f57-7e09982bd184.png)

1. Azure DevOps側を見たら、ちゃんと追加されてました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/dff10bfe-e293-e7a5-6854-ae036684f8a1.png)

ちなみに、Commitコメントは自動で入れてくれたみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/5740d2df-0052-7a46-f90b-56960808797d.png)

楽すぎてビックリ。
【備忘録】Node.js向けテスト用モックライブラリ

備忘録です。たまに忘れるので記録用に残しておきます。

## mock-fs

https://www.npmjs.com/package/mock-fs

**最強**のファイルシステム用モックライブラリです。これを使うことで、[`fs`モジュール](https://nodejs.org/api/fs.html)を使ったコードやライブラリを、実際のファイルシステムを使うこと無くテストすることができます。

```js
const assert = require('node:assert/strict');
const fs = require('node:fs/promises');
const path = require('node:path');
const { test } = require('node:test');

const mockFs = require('mock-fs');

test('ファイルの読み込みをモックするテスト', async () => {
  try {
    mockFs({
      'anser.txt': '42',
    });

    const filepath = path.join(process.cwd(), 'anser.txt');
    const filedata = await fs.readFile(filepath, { encoding: 'utf8' });
    assert.strictEqual(filedata, '42');
  } finally {
    mockFs.restore();
  }
});
```

mock-fsが最強である理由は、これがECMAScript Modulesでも使える事です。嘘ではありません。[Jestの`jest.mock('fs');`](https://jestjs.io/ja/docs/mock-functions#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%A2%E3%83%83%E3%82%AF)みたいなテストコードの動的書き換えすら要らず、Node.jsネイティブのESMでも使えます。試しに以下のコードを拡張子`.mjs`のファイルに保存してnodeコマンドで実行してみてください。

```js
import * as assert from 'node:assert/strict';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { test } from 'node:test';

import mockFs from 'mock-fs';

test('ファイルの読み込みをモックするテスト', async () => {
  try {
    mockFs({
      'anser.txt': '42',
    });

    const filepath = path.join(process.cwd(), 'anser.txt');
    const filedata = await fs.readFile(filepath, { encoding: 'utf8' });
    assert.strictEqual(filedata, '42');
  } finally {
    mockFs.restore();
  }
});
```

これが可能なのは、mock-fsが`fs`モジュールではなく、[`fs`モジュールが内部で使用している`internalBinding('fs')`](https://github.com/nodejs/node/blob/v20.2.0/lib/fs.js#L63)を書き換えているからです。`require('fs')`はモックしていないので、ESMだろうと正しくモックできるというわけです。

https://github.com/tschaub/mock-fs/blob/v5.2.0/lib/index.js#L24-L53

これを知った時は心底驚いた。

https://twitter.com/sounisi5011Prog/status/1640873192771424256

## nock

https://www.npmjs.com/package/nock

HTTP通信用のモックライブラリです。だいぶ前に見つけて以来、愛用しています。

## spawk

https://www.npmjs.com/package/spawk

サブプロセス用のモックライブラリです。[`child_process`モジュール](https://nodejs.org/api/child_process.html)を使っているコードのテストに使えます。

## vitest-mock-process / jest-mock-process

https://www.npmjs.com/package/vitest-mock-process

https://www.npmjs.com/package/jest-mock-process

`process.stdout`、`process.stderr`、`console.log()`用のモックライブラリです。名前の通り、[Vitest](https://vitest.dev/)または[Jest](https://jestjs.io/)向け。stdoutやstderrに何かを書き込む関数のテストに最適。

## あとがき

+ ファイルシステム
+ HTTP通信
+ サブプロセス
+ stdoutとstderr

この4種類をモックできれば、大抵のテストコードで困ることは無いでしょう。個人的には困っていません。

モックというと、たいていのテストコードでは関数そのものやライブラリそのものをモックする方法がよく取られているように思います。しかし、依存しているライブラリの内部挙動が変更されたことでバグが発生することもあります。依存するライブラリの正しさを含めてこそのテスト。そう考えるならば、やはりNode.jsが提供するI/Oそのものをモックする方法が最適だと考えます。
新形式・基本情報技術者試験合格記

# はじめに
2023年4月から新形式になった基本情報技術者試験を受けてきました。
自戒も込めて、記録していきます。
### この記事の対象者
* アルゴリズムが苦手で他人の学習方法が知りたい人
* 何でもいいから基本情報の合格記が読みたい人
### 受験結果と筆者について
**得点**
 科目A 655/1000
 科目B 780/1000
(正式な合格通知はまだ来ていません)<br>

**わたし**
* SIer新卒2年目エンジニア（経済学部卒）
* 開発系のプロジェクトで経験を積んでいるが、SEとしての自信がもう皆無
* これまで合格したのは、AWS:CLF,AZ-900,ITIL(f)<br>
**IPA試験の不合格記**
* 1年目10月に基本情報を受けるも、午後試験3点不足
* 2年目4月に応用情報を受けるも、午前試験10点不足<br>
# 学習について
**全体的な方針**
業務でプログラムを書いたりもするものの、アルゴリズムに相当な苦手意識がありました。前回受験の午後問題は、表計算やらDBを選択し、応用情報でも、午後は文系ホイホイな選択問題を解いていました。（結局落ちているのですが、、）
新形式は科目Bの大半が擬似言語アルゴリズムということで、合格のためには逃げられなくなり、重点的に対策をしました。<br>
### **科目B(100分20問)**
* 勉強時間
  * 土日中心で2週間で12.5h
  * 平日に勉強するモチベが上がらず受験日を予定より1週延期した
* 使用教材
  * [うかる！ 基本情報技術者　[科目B・アルゴリズム編]](https://www.amazon.co.jp/%E3%81%86%E3%81%8B%E3%82%8B%EF%BC%81-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E7%A7%91%E7%9B%AEB%E3%83%BB%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E7%B7%A8-2023%E5%B9%B4%E7%89%88-%E7%A6%8F%E5%B6%8B%E5%85%88%E7%94%9F%E3%81%AE%E9%9B%86%E4%B8%AD%E3%82%BC%E3%83%9F/dp/4296115006)
  * IPAのサンプル問題1回分
* 詳しい勉強法
  * 「うかる！ 」の参考書を1冊終わらせることを目標に学習を始めました。
が、しかし1～4章までしか進まず、練習問題が多く載っている最後の5章は2,3問手を付けたのみ。トレースの仕方など、基本的な解き方を学ぶことに努めました。
  * 1章で難易度低めの問題からスタート。アルゴリズムなんだ意外と楽しいやん、、、と筆者の思うツボなのか気付かされました！2章3章はじっくり理解できるまで解説を読んで、トレースしてみるの繰り返し。
  * サンプル問題は本番前2時間で1回分解きました。後半の少し複雑なアルゴリズムは、この期に及んでもうまく解けず、落ち込みました。後処理として過去問道場さまの解説読んだあと自分で手を動かして再度挑戦したり。
  * 本番は、セキュリティの問題からササッと手を付け、アルゴリズムに移った。1問時間が足りず勘で解答したが、他は、合っているかは置いといてトレースと解答は行った。<br>
  
### **科目A(90分80問)**
* 勉強時間
  * 1週間で3hほど
* 使用教材
  * [令和04年 イメージ&クレバー方式でよくわかる 栢木先生の基本情報技術者教室](https://www.amazon.co.jp/%E4%BB%A4%E5%92%8C04%E5%B9%B4-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8-%E3%82%AF%E3%83%AC%E3%83%90%E3%83%BC%E6%96%B9%E5%BC%8F%E3%81%A7%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B-%E6%A0%A2%E6%9C%A8%E5%85%88%E7%94%9F%E3%81%AE%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E6%95%99%E5%AE%A4-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93/dp/4297123932/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3AKNLJH8DPXB&keywords=%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1+%E6%9F%8F%E6%9C%A8&qid=1685733624&s=books&sprefix=%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1+%E6%9F%8F%E6%9C%A8%2Cstripbooks%2C210&sr=1-3)
  * 過去問道場テクノロジ系
  * IPAのサンプル問題テクノロジ系1回分
*  詳しい勉強法
   * 「イメージ&クレバー方式」で苦手なネットワークの単元を読み直し 
   *  昨年から基本情報のいわゆる"午前問題"は解いていた、応用情報でも似たような学習をしていた、ということで今回はかなり最小限。というか、この勉強量は落ちていても不思議ではない。。。新形式になったものの、科目Aは、そこまで大きな変化はないと感じた。
   *  サンプル問題は、本番前に１回分解いた。たしか合格ラインスレスレ。焦って、用語を一気にインプットした。
   *  昨年は過去問道場でテクノロジ系7年分、他分野を4年分
   *  本番、時間が意外とギリギリで焦った。7分しか見直しができなかった。<br>
 
# まとめ

**反省**
昨年、不合格で痛い目に遭ったにも関わらず、満足に対策できなかった。
どうしても着手し始めが遅いと時間も取れないので、今後は試験勉強Startをはやめはやめに。
試験が終わっても受かった気はしなかったし、落ちてるか心配だったくらいなので、運も良かったのかな、、、。<br>
**自分を褒める**
苦手だったアルゴリズム楽しく学べてえらい。
そもそも合格点到達してえらい。
業務内でもITに関する知識がなんだかんだ深くなっている。えらい。
仕事でなかなかうまく行かない時期も基本情報の勉強してえらい。<br>
**これから受ける皆さんへ**
基本情報は取ってもそんなに意味はないとか、よく聞きます。
しかし、合格までの過程で広く知識が身につけられたこと、それが先輩エンジニアとの会話等で生かされているな、と日頃感じているので私は勉強できてよかったです！
みなさんが私のように2度も受けることがありませんように祈っています。
coreserverでdjangoのアプリを動かそうとしてCSSの設定で詰まった話

## これはなに
coreserver上でdjangoのwebアプリを動かした時にcssが反映されない
  -> 解決した話
## 結論
coreserverでdjangoのアプリを動かす時は、staticフォルダは/public_htmlに作る。
## 背景
自分：経理屋 -> 2023/04からデータアナリストへ転職。djangoは初心者。pythonはデータ分析で経験5年くらい。
サーバー：coreserver CORE-X

最近、地域のボランティアに加わっていて、そこでとある活動でwebアプリを作ろうという話になりました。
その際に、webアプリとは別に活動団体のホームページを立てるサーバーがcoreserverだったため、webアプリもcoreserver上に作ろうという話になりました。（一般的にはレンタルサーバーでdjangoを動かすのはおすすめされていないようです。これから作る人はやめときましょう。）
## サーバ内の構成
### ＜修正前＞
* /home/project_name/
    * mysite
        * mysite
            * templates
                * index.html
            * ***static***
                * css
                    * main.css
    * public_html
### ＜修正後＞
* /home/project_name/
    * mysite
        * mysite
            * templates
                * index.html
    * public_html
         * ***static***
            * css
                * main.css
##  詳細
手元のパソコンでdjangoを動かしていた時は、＜修正前＞のようなcssの保存場所で思った通りのページが表示されていました。
しかし、coreserverに同じ構成でファイルをアップロードしたところ、cssが全く反映されていないページが表示されるようになってしまいました。
settings.pyやindex.htmlの書き方が悪いのかと思い色々と試行錯誤していましたが一向に改善しませんでした。1ヶ月くらい。

ずっと長いこと改善できず、そろそろこの案件はぶん投げようかなと思っていたところ、たまたまネットで見かけた記事を元にcssファイルの置き場所を＜修正後＞のように変えたところ、奇跡的にcssが反映されるようになりました。
どうやらcoreserverで使用しているlitespeedの設定でそうなるようで、やはり手元のPCで動かしている時とサーバーにデプロイした時とでは色々違うんだなと実感。

もし同じ現象でスタックしている人の参考になれば。
【SQL】テーブルを作成、変更、削除する方法

## CREATE

CREATEはデータベースに空のテーブルを作成します。  

```sql
CREATE TABLE テーブル名 ( 
  カラム名1 データ型 制約,
  カラム名2 データ型 制約,
            ：
  テーブルの制約1, 
  テーブルの制約2, 
            ：
);
```

- データ型  

| データ型 | 説明                                                                 |
| :------: | :------------------------------------------------------------------- |
| INTEGER  | 整数（小数は不可）                                                   |
|   CHAR   | 固定長文字列。続けて`(数字)`を記述することで最大文字数を指定できる。 |
| VARCHAR  | 可変超文字列。続けて`(数字)`を記述することで最大文字数を指定できる。 |
|   DATE   | 日時                                                                 |

- 制約

|    制約     | 説明                                                   |
| :---------: | :----------------------------------------------------- |
|  NOT NULL   | NULL 値が列に入力されないようにする                    |
| PRIMARY KEY | 主キーを設定する。必ずNOT NULL制約をつける必要がある。 |
| FOREIGN KEY | 外部キーを設定する                                     |

### 例

```sql
CREATE TABLE Users (
  user_id            INTEGER      NOT NULL,
  user_name          VARCHAR(15)  NOT NULL,
  user_address       VARCHAR(100) NOT NULL,
  user_phone_number  CHAR(13),
  PRIMARY KEY (user_id)
);

CREATE TABLE Orders (
  order_id   INTEGER NOT NULL,
  order_date DATE    NOT NULL,
  user_id    INTEGER NOT NULL,
  PRIMARY KEY (order_id),
  FOREIGN KEY (user_id) REFERENCES Users (user_id)
);

```

![スクリーンショット 2023-01-02 23.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/42005c94-1892-722f-18ab-d0f77f63c35d.png)

## DROP

`DROP`はテーブルを削除します。  

```sql
DROP TABLE テーブル名;
```

## ALTER

`ALTER`は定義済みテーブルを変更する。  

- カラムを削除する

```sql
ALTER TABLE テーブル名 DROP COLUMN カラム名;
```

- カラムを追加する

```sql
ALTER TABLE テーブル名 ADD COLUMN カラム名 データ型 制約;
```

- テーブル名を変更する

```sql
ALTER TABLE 旧テーブル名 RENAME TO 新テーブル名;
```
tailscaleがVSCodeの拡張機能に追加されたらしいからWebサイトを外部公開しよう

# はじめに
あのtailscaleがVSCodeの拡張機能を出したらしいからそれをつかってWebサイトを簡単に外部公開してみましょうという記事です。


# tailscaleとは
Tailscaleは、雑に要約するとVPNがありえんほど簡単に使えるようになるサービスです
詳細はいろんなサイトを見てください

https://blog.tsukumijima.net/article/tailscale-vpn/


# tailscaleをインストール
こちらなどを参考にインストールしてください（上のリンクとおなじ）
このサイトは詳細に書いてありますが、やることはtailscaleのインストールと認証程度で良いはずです。

https://blog.tsukumijima.net/article/tailscale-vpn/

# tailscaleの拡張機能をvscodeのインストール
こちらをインストール（2023/6/3現在)
拡張機能でtailscaleと検索すれば一番上にヒットします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/f7c84635-c2a6-c179-8592-e2f2ee6772ae.png)

それでは、使えるかやってみましょう。

# 適当なwebサイトを立ち上げる
それぞれでwebサイトを作成してください。
自分はdjangoのプロジェクトを新規作成し、http://127.0.0.1:8000/ で動くことを確認しました。
公開したいサイトのポートはユーザーが入力するので、8000以外でも構いません。

# さっそくtailscaleで公開
とりあえず使えるか確認しましょう。
`CMD + J`でパネルを開いて、TAILSCALE:FUNNELというのを開きましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/c5349ae2-b409-003f-72dd-5d225ab47273.png)
まだ使えないらしいです。Funnelを有効化しろと言っています。
Enable Funnelより、[リンク](https://tailscale.com/kb/1223/tailscale-funnel/#setup)へアクセスしてみると、セットアップ手順が書かれているので、言われたとおりに有効化を進めます。

## MagicDNSとHTTPS Certificatesの有効化
 https://login.tailscale.com/admin/dns ここのMagicDNSとHTTPS Certificatesを有効化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/ae3f8194-dd26-ac4f-feed-a57b16a824ab.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/15abbbdb-ef00-d7b7-b2db-f58d856ed27e.png)
このように赤いボタンになっていれば有効化されている 白いボタンだったらクリックして有効化しましょう

## Funnelの有効化

[アクセスコントロール](https://login.tailscale.com/admin/acls/file)に言われたとおりに以下のコードを貼り付けます。
> Click the Add Funnel to policy button. Clicking this button adds the default nodeAttrs section and saves the tailnet policy file automatically. The default nodeAttrs section looks like:

Add Funnelボタンを押せばいいと書いてありますが、私の場合はボタンがなかったので、下記コードを貼り付けました。

```
"nodeAttrs": [
    {
         "target": ["autogroup:members"],
         "attr":   ["funnel"],
     },
],
```
リストの末尾に追加すればいいと思います。

## パネルの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/a122ff40-e437-2200-4a71-717584d46397.png)
funnelが有効化されてる！

# 接続確認
127.0.0.1:`<port>`にポートを入力（自分の場合は8000）し、Start!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/5120b80a-5312-c414-687b-e8292b33c295.png)
アクセスできました！

# 余談
自分は新規にセットアップしたdjangoのプロジェクトで試したので、最初はsettings.pyのALLOW_HOSTSに何も設定してなかったためにエラーが表示されました
その後`ALLOW_HOSTS = ["*"]`として、表示ができました。
AE キャラモーション / エフェクト / 作業効率特化 : Plug-in, Scripts

自分が使っているものメモ

揺れモノ - AutoSway
https://aescripts.com/autosway/

2Dキャラリギング - Duik_Angela
https://rxlaboratory.org/download-duik-angela/

キーフレーム操作効率化 - Flow
https://aescripts.com/flow/

キーフレーム操作効率化 - easecopy
https://aescripts.com/easecopy/

作業効率化 - Motion Toosl Pro
https://motiondesign.school/products/motion-tools/



----

パーティクル表現 - Superluminal Stardust 
https://aescripts.com/stardust/

フレア表現 - Videocopilot OpticalFlares
https://www.videocopilot.net/products/opticalflares/

GLSL実装 - PixelsWorld
https://aescripts.com/pixelsworld/
リストの並べ替え、sort()とsorted()

リストの中身を昇順や降順に並べ替える時に使うsort関数とsorted関数

sort関数は破壊的処理（元の要素自体を書き換える処理）を行う

```python
num_list = [4,　5,　6,　2,　1,　7,　8,　3,　5,　0,　2,　6,　3]

num_list.sort()
print(num_list)
# [0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8]

```

引数をreverse = Trueにすると降順となる
```python
num_list = [4,　5,　6,　2,　1,　7,　8,　3,　5,　0,　2,　6,　3]

num_list.sort(reverse = True)
print(num_list)
# [8, 7, 6, 6, 5, 5, 4, 3, 3, 2, 2, 1, 0]
```

続いてsorted関数
こちらは破壊的処理は行わず、書き方も変わる

```python
num_list = [4,　5,　6,　2,　1,　7,　8,　3,　5,　0,　2,　6,　3]

sort_num_list = sorted(num_list)
print(sort_num_list)
# [0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8]
```

こちらもsort同様、降順にできる
```python
num_list = [4,　5,　6,　2,　1,　7,　8,　3,　5,　0,　2,　6,　3]

sort_num_list = sorted(num_list,reverse = True)
print(sort_num_list)
# [8, 7, 6, 6, 5, 5, 4, 3, 3, 2, 2, 1, 0]
```
<br>
また、sorted関数は文字列にも使える
<br>
<br>


```python
abc_list = ['c',　'e',　'a',　'b',　'd']

sort_abc_list = sorted(abc_list)
reverse_sort_abc_list = sorted(abc_list,　reverse = True)

print(sort_abc_list)
print(reverse_sort_abc_list)
# ['a', 'b', 'c', 'd', 'e']
# ['e', 'd', 'c', 'b', 'a']
```

また、文字列リストもソート可能

```python
str_list = ['lion',　'tiger',　'dog',　'cat',　'bard']

sort_str_list = sorted(str_list)
reverse_sort_str_list = sorted(str_list,　reverse = True)

print(sort_str_list)
print(reverse_sort_str_list)
# ['bard', 'cat', 'dog', 'lion', 'tiger']
# ['tiger', 'lion', 'dog', 'cat', 'bard']
```

そしてリストの中の要素として文字列を扱う場合は、文字列そのものではないためsortも使用可能

```python
str_list = ['lion',　'tiger',　'dog',　'cat',　'bard']

str_list.sort()
print(str_list)
# ['bard', 'cat', 'dog', 'lion', 'tiger']
```