OmniAICreator/Qiita-1.07M huggingface dataset:
PowerShellでサウンド再生

#wavファイルの再生

##Media.SoundPlayer

```fig1.ps1
$player = New-Object Media.SoundPlayer "C:\Windows\Media\tada.wav"
$player.Play()
```

##Windows API

```fig2.ps1
$SND_SYNC = 0x0000
$cscode = @"
[DllImport("winmm.dll")]
public static extern bool sndPlaySoundA(string lpszSound, UInt32 fuSound);
"@
$winapi = Add-Type -Name "hoge" -MemberDefinition $cscode -PassThru
$winapi::sndPlaySoundA("C:\Windows\Media\tada.wav", $SND_SYNC)
```

#メモリの再生
wavファイルのイメージをメモリに作成し再生する。

##Media.SoundPlayer

```fig3.ps1
function fourcc($s) { return [Text.Encoding]::ASCII.GetBytes($s) }
function word([UInt16] $x) { return [BitConverter]::GetBytes($x) }
function dword([Uint32] $x) { return [BitConverter]::GetBytes($x) }

[Byte[]] $b = @()
$b += fourcc("RIFF")
$b += dword(36 + 4000)
$b += fourcc("WAVE")
$b += fourcc("fmt ")
$b += dword(16)
$b += word(1)
$b += word(1)
$b += dword(8000)
$b += dword(8000)
$b += word(1)
$b += word(8)
$b += fourcc("data")
$b += dword(4000)
$b += @(0x90,0x90,0x70,0x70) * 500
$b += @(0x90,0x90,0x90,0x90,0x70,0x70,0x70,0x70) * 250
# [IO.File]::WriteAllBytes("pipo.wav", $b)

$ms = [IO.MemoryStream]::new($b)
$player = [Media.SoundPlayer]::new($ms)
$player.Play()
```

##Windows API
sndPlaySoundAの第1引数の型はLPCTSTR。
ファイル名の場合はstringだけどメモリを渡す場合はByte[]とする。

```fig4.ps1
$SND_SYNC = 0x0000
$SND_MEMORY = 0x0004
$cscode = @"
[DllImport("winmm.dll")]
public static extern bool sndPlaySoundA(Byte[] lpszSound, UInt32 fuSound);
"@
$winapi = Add-Type -Name "hoge" -MemberDefinition $cscode -PassThru

function fourcc($s) { return [Text.Encoding]::ASCII.GetBytes($s) }
function word([UInt16] $x) { return [BitConverter]::GetBytes($x) }
function dword([Uint32] $x) { return [BitConverter]::GetBytes($x) }

[Byte[]] $b = @()
$b += fourcc("RIFF")
$b += dword(36 + 4000)
$b += fourcc("WAVE")
$b += fourcc("fmt ")
$b += dword(16)
$b += word(1)
$b += word(1)
$b += dword(8000)
$b += dword(8000)
$b += word(1)
$b += word(8)
$b += fourcc("data")
$b += dword(4000)
$b += @(0x90,0x90,0x70,0x70) * 500
$b += @(0x90,0x90,0x90,0x90,0x70,0x70,0x70,0x70) * 250
# [IO.File]::WriteAllBytes("pipo.wav", $b)

$winapi::sndPlaySoundA($b, $SND_MEMORY -bor $SND_SYNC)
```
Google Calendar で公開カレンダーを作って公開する


Google Calendar でオリジナルの「公開カレンダー」を作る方法です。
iCal 形式のＵＲＬを公開すると、スマホやOutlookなどのカレンダーに取り込んで共有することができます。

１．Google Calendar を開き、右上の「設定」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/19b4e9ac-e1b5-c7ca-dfaf-a3d1eadb6883.png)

２．「カレンダーを追加」から「新しいカレンダーを作成」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/65265816-43ef-fea5-31a2-020bbef2eabd.png)

３．公開するカレンダーの「名前」を入力して「カレンダーを作成」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/99b7b6ce-7ddd-c631-bc97-b18cee128eca.png)

４．「一般公開して誰でも利用できるようにする」にチェックを入れます。「共有可能なリンクを取得」をクリックします。→パソコン向けの公開ＵＲＬを取得することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/ab35a9e7-8685-21e8-cbdc-249d55539c40.png)

５．「iCal形式の公開URL」をコピーします。このURLのカレンダーはスマホやOutlookからも取り込み可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/6ffb1f11-6f15-19a0-4e32-15ee328ea5f2.png)


以上。
djangoのformクラスについてまとめる

今回のお題
-
今回は、djangoのformクラスについてまとめます。

今まではModelFormクラスばかり使っていたのですが、諸事情あってこちらも必要になりました。

両方とも使えるに越したことはないと思うので、良い機会だと思って勉強します。

目次
-
- formクラスとModelFormクラスの違い
- 実装例
- まとめ

formクラスとModelフォームクラスの違い
-
まず最初に、FormクラスとModelFormクラスの違いを説明しておきます。

<dl>
<dt>ModelFormクラス</dt>
<dd>対応するモデルを指定して定義する</dd>
<dd>フィールドの仕様（バリデーションなど）は基本的に元にしたモデルから引き継ぐ形になり、一部は変更できない</dd>
<dd>フォームとモデルが紐づいているので、フォームに入力された内容を元にモデルの情報を保存したり更新したりするのが比較的容易</dd>
<dt>Formクラス</dt>
<dd>ModelFormとは異なり、対応するモデルを指定するわけではない</dd>
<dd>フォームとモデルが紐づいていないので、フォームの内容とモデルの相互変換にはやや手間がかかる</dd>
<dd>フィールドの仕様（バリデーションなど）は基本的にモデルから独立しているので、自由に設定可能（ただしモデルから設定を流用して手間を省くことはできない）</dd></dl>

総じて、手間がかかりにくが良くも悪くもモデルの情報に縛られるのがModelFormクラスであり、自由度と引き換えに手間が犠牲になっているのがFormモデルといえます。

ModelFormを用いた実装例については以下をどうぞ。

https://qiita.com/keishi04hrikzira/items/098c13c80ca1ae972e33

実装例
-
今回は実装例として以下のコードをModelFormクラスからFormクラスに書き換えていきたいと思います。

```python:models.py
class Book(models.Model):
  title = models.CharField(verbose_name="タイトル", max_length=30)
  comment = models.TextField(verbose_name="コメント")
```

```python:forms.py
class BookForm(ModelForm):
  class Meta:
    model = Book
    fields = "__all__"
```

```views.py
# method=="GET"やバリデーションエラー時の挙動は省略しています
def create(request):
  if request.method == "POST":
    form = BookForm(request.POST)
    if form.is_valid():
      form.save()
      return render(request, "home.html")
```

これをFormクラスを用いて書き換えます。

```python:forms.py
class BookForm(form.Form):
  title = forms.CharField(label="タイトル", max_length=30)
  comment = forms.TextField(label="コメント")
```

フィールドの定義は`models.フィールド型`ではなく`forms.フィールド型`の形式です。

また、一部のオプション名が異なります(`verbose_name`→`label`など）。

また、基本的にオプションはモデルとは別で定義し直しになることに注意してください。

```python:views.py
def create(request):
  form = BookForm(request.POST)
  if form.is_valid():
    title = forms.cleaned_data.get("title")
    comment = forms.cleaned_data.get("comment")
    book = Book()
    book.title = title
    book.comment = comment
    book.save()
```
formクラスのインスタンスに対してsaveメソッドをかけることができないので、手間が増えていますね。

まとめ
-
以上がFormクラスを用いた実装例になります。

今回はフィールドが`title`と`comment`のみでしたが、そこが増えると大変そうですね。

基本的にModelFormクラスではなくFormクラスを用いるべきなのは、

- モデルにはないフィールドを追加したいとき
- バリデーションをモデルに設定されているものから変更したい時

上記のいずれかになるのかなと思いました。
kintone の詳細画面開いたときに、フィールドの値を変えたい

今回は、kintone カスタマイズの初心者がやりがちな（気がする）「そのコード間違っtone」を供養したいと思います。

# 🤔詳細画面開いたときに、フィールドの値を変えたい

🤔「編集画面じゃなくって、詳細画面でフィールドの値を変えたいのに、変わりません！
    どこを変えたらいいですか！？
    書いたコードはコレです。」

```js
  // レコード詳細画面表示後
  kintone.events.on(
    ["app.record.detail.show"],
    (event) => {
      const record = event.record;
      console.log("変更前", record.会社名.value);

      record.会社名.value = "テスト";
      console.log("変更後", record.会社名.value);

      return event;
    }
  );

```

🙄「あ～～。これは・・・。コレじゃあ変わらないですね👀」

🤔「でも、コンソールで確認すると、record.会社名.valueの値は変わってるんですよ👀」


↓コンソールで確認すると内部的には「テスト」に変わっているけど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/fce84451-0a48-739b-ba66-2bef89115e1b.png)

↓詳細画面の会社名は変わらない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/5a719476-a5aa-f581-410d-77ad544df35d.png)


## 詳細画面では、event.record 変更しても表示に反映されないよ！

```js
event.record.フィールドコード.value = "何らかの値";
return event; 
```

で、素直に値が変わってくれるのは、
「レコード追加画面の表示後イベント」と「レコード編集画面の表示後イベント」と「レコード一覧画面のインライン編集フィールド値変更時イベント」です。

では、「詳細画面」ではどうすればいいのか👀


### 💡見た目だけ変更すればいい場合

フィールドの値としては上書き保存しなくてよくて、詳細画面を開いたときに見た目だけ変わってくれたらいいよ！
という場合は下記のようにDOM操作して変更すると良いと思います。

```js
kintone.app.record.getFieldElement("会社名").textContent= "テスト";
```

### 💡フィールドの値ごと更新したい場合

詳細画面を開いたときに最新の値に更新したい！
という場合は下記のように `kintone REST API` を使って更新する必要があります。

でも「詳細画面を開くたびに更新」というのはつまり、「詳細画面を開かないと一生更新されないまま」ということなので、更新タイミングについてはちゃんと考えないといけません。

また、最新だったらリロードしないのような動きにする場合、「最新とは？」の定義を決めていないと永遠に（API回数が枯渇するまで）リロードし続けるようなアプリになってしまうでしょう。

```js
// レコード詳細画面、
kintone.events.on(["app.record.detail.show"], (event) => {
  const record = event.record;

  // 値が最新だったら更新しない（ここは工夫してね）
  if (record.会社名.value === "テスト") {
    return event;
  }

  // レコード更新のパラメータ設定
  const body = {
    app: kintone.app.getId(),
    id: kintone.app.record.getId(),
    record: {
      会社名: {
        value: "テスト",
      },
    },
  };

  // フィールドの値を更新する
  return kintone.api(
    kintone.api.url("/k/v1/record.json", true), "PUT", body, (resp) => {
      // 更新できたらリロード
      location.reload();
    }
  );
});
```

# まとめ
**詳細画面では、event.record 変更しても表示に反映されないよ！** というのはkintoneカスタマイズ初心者の方がハマりがちなところだと思います。
表示だけ変えたい場合、レコード自体更新したい場合で処理の仕方も違うのでどのタイミングで更新するのかなどよく考えてカスタマイズしてみてくださいね👀✨
StorageGateway構築時のメモ

下記記事でstoarge gatewayを作成したときの検証メモ

https://qiita.com/instant_baby/items/9cb44db98e93a93cce93


storage gateway用のAMIを使用して起動する場合の/rootは80GB以上じゃないとそもそも起動しない

```
aws_instance.sdw_test: Creating...
╷
│ Error: Error launching source instance: InvalidBlockDeviceMapping: Volume of size 10GB is smaller than  snapshot 'snap-02697e01242efad59', expect size >= 80GB
│ 	status code: 400, request id: d8980776-68ee-4bde-9fcb-0a55277cca15
│
│   with aws_instance.sdw_test,
│   on ec2_sgw.tf line 5, in resource "aws_instance" "sdw_test":
│    5: resource "aws_instance" "sdw_test" {
│
╵
```

インスタンスタイプはm4.xlargeより低いスペックだと、ものによっては起動しないインスタンスタイプがある模様

```
│ Error: Error launching source instance: InvalidParameterValue: Invalid value 't3.midium' for InstanceType.
│ 	status code: 400, request id: 67bf5fe7-2cd6-41a9-b7e8-0834edf0b0e0
│
│   with aws_instance.sgw_test,
│   on ec2_sgw.tf line 5, in resource "aws_instance" "sgw_test":
│    5: resource "aws_instance" "sgw_test" {
│
╵
```

largeはOK


EBS 10GBでもstorage gatawayとしてアクティベートでできた。
あくまでキャッシュなので作成時に怒られるとかはなさそう



1GBのファイルは問題なくアップロード出来る。
EBSのサイズ以上のファイルもアップロード出来る。

EBSのサイズ以上のファイルをアップロードする時はマルチパートアップロードで順次処理される。


ファイル共有のキャッシュを更新するとs3のファイル構成を基準としてマウント先のファイル構成を更新する（下り方向で同期）
Tortoise ORM入門


**Tortoise ORM** は asyncio 互換の**ORM (Object Relational Mapper)**です（inspired by Django）。
FastAPIでよく使われていますが、今回はFastAPIとは関係ない、純粋に Tortoise ORMの入門です。ちなみにFastAPIで使うためには、今回の範囲外ですが、Pydantic を考慮に入れる必要があります。


[Tortoise ORM 公式サイト](https://tortoise-orm.readthedocs.io/en/latest/index.html)

【過去記事】
[Python Asyncio入門](https://qiita.com/sand/items/0e445a13d81d20ea33c3)
[Aiohttpで作るSimple Web Server - Qiita](https://qiita.com/sand/items/971c851598ff59c1c905)
[Starletteで作る Simple Web Server - QIita](https://qiita.com/sand/items/dd622ce4f9249399974c)
[FastAPIで作るWebアプリ - 基本](https://qiita.com/sand/items/bba0913fe4504c612b3a)
[FastAPIで作るWebアプリ - validation](https://qiita.com/sand/items/85068532388826258df4)
[FastAPIで作るWebアプリ - Body validation](https://qiita.com/sand/items/470b33d7539713432090)
[FastAPIで作るWebアプリ - Form validation](https://qiita.com/sand/items/207f306bdacdc0fb9571)
[Pydantic Data Model入門](https://qiita.com/sand/items/ca2c7c49e8bd94053b04)
[Tortoise ORM入門](https://qiita.com/sand/items/074866157635b50eb447)


まずインストールします。

```
pip install tortoise-orm
```


Modelの定義を行います。公式サイトにある簡単なものです。

```python:model.py
from tortoise.models import Model
from tortoise import fields

class Tournament(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
```

**tortoise.models.Model** を使ってモデルTournamentを定義します。各フィールドは**tortoise.fields**を使って定義していきます。本記事は全体の流れを説明することを意図しているので、詳細は公式サイトに譲ります。

以下は最初に一回だけ走らせるスクリプトです。これで上のModelに対応したテーブルが作成されます。sqliteがデフォルトのDBですが、PostgreSQLやMySQLを設定することもできます。これも公式サイトに案内があります。**Tortoise.generate_schemas()**でスキームを作っていますが、これは一回だけ行うものです。

```python:init.py
from tortoise import Tortoise, run_async

async def init():
    await Tortoise.init(db_url='sqlite://db.sqlite3', modules={'models': ['model']})
    # Generate the schema
    await Tortoise.generate_schemas()

# run_async is a helper function to run simple async Tortoise scripts.
run_async(init())
```


modulesのmodelsの値が['model']となっていますが、これはモデルの定義ファイルmodel.pyを指しています。それとコルーティンinit()を走らせるためには**tortoise.run_async()**が必要になります。asyncio.run()ではエラーとなりますので注意してください。

スクリプトを実行してinit()を走らせます。

```
python init.py
```

それでは実際にORMを利用して、DB操作を行ってみます。

```python:main.py
from tortoise import Tortoise,  run_async
from model import Tournament


async def run():
    await Tortoise.init(db_url="sqlite://db.sqlite3", modules={"models": ["model"]})

    # Create instance by save
    tournament = Tournament(name='New Tournament')
    await tournament.save()

    # Or by .create()
    await Tournament.create(name='Another Tournament')

    # Now search for a record
    tour = await Tournament.filter(name__contains='Another').first()
    print(tour.name)


run_async(run())
```


今回は以上です。
[Power Query] Table.Transpose と、Table.UnpivotOtherColumnsと、年(yyyy)を日付(yyyy/mm/dd)に変換する話

以下のようなテーブルをPower Queryで整えていきます。２種類の方法を試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/93bd11a9-a74a-6d8c-27d2-e9c055bfddc1.png)

# 解決方法その１
 行列を入れ替えて、項目を整えます。

## Transposeでテーブルを転置する
　変換リボンの「入れ替え」を押します。

```
    転置されたテーブル = Table.Transpose(Sheet1_Sheet),
```

　実行後のテーブルは、以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/5424e4a8-2c0b-2b50-1b52-4cb4503b66b8.png)

## 1行目をヘッダーに昇格する
　「１行目をヘッダーとして使用」を適用すると、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/14b3e67f-8371-ca0f-d83f-4e81b8a8dd88.png)

## Mesure項目の名前をYearに変更する
　Measureのカラム名をYearに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/99b92a56-6d7e-4d4a-0c6a-22cc1f3bcaf6.png)

## Year項目を日付型に変更する
　Yearの項目を日付に変更するには、以下の２つの手順が必要です。

- Yearをテキスト型に変更
- Yearを日付型に変更

　２番めの操作時に、「既存のものを置換」するか、「新規手順の追加」をするか聞かれます。置換してしまうと、最初の処理が無効になり、以下のように、年月がおかしくなってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e22b9b71-03d4-5d09-d308-c867d2f4ac89.png)

　「新規手順の追加」で行うと、以下のように、日付が期待通りに変換されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2c69eda8-3623-e82e-6e3c-a814727bb4d1.png)

# 解決方法その２
　項目を縦持ちにして、年単位の比較を行うテーブルを作成します。

## 1行目のをヘッダーに昇格する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1ac45305-9ba2-ba36-9dee-1792ca9fc7ee.png)

## Measure以外の列のピボット解除
　Measure以外の列のピボットを解除すると以下のようになります。

```
    ピボット解除された他の列 = Table.UnpivotOtherColumns(変更された型1, {"Measure"}, "属性", "値")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/b677e7c5-683d-f837-11d6-8169c75e07b5.png)

## 属性項目の名前をYearに変更する
　「属性」の項目名を「Year」に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/d362355a-272c-be65-b242-02a8c109811b.png)

## Year項目を日付型に変更する
　Yearの項目を日付型に変更します。この場合、年はピボット解除処理でテキスト型になっているため、１回で変換できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/59af8775-88c6-6c6e-36a5-1a426495557d.png)
vim-lsp のdiagnosticsがラグい


vim-lspのデフォルトの設定は、若干の遅延があって遅く感じるかもしれません。
対策は２つです。

- *_insert_mode_enabledで入力中は無効化する
- *_delayを上書きして、遅延を減らす

私の設定は以下です。

```vim:vimrc
let g:lsp_diagnostics_echo_cursor = 1
let g:lsp_diagnostics_echo_delay = 50
let g:lsp_diagnostics_highlights_enabled = 1
let g:lsp_diagnostics_highlights_delay = 50
let g:lsp_diagnostics_highlights_insert_mode_enabled = 0
let g:lsp_diagnostics_signs_enabled = 1
let g:lsp_diagnostics_signs_delay = 50
let g:lsp_diagnostics_signs_insert_mode_enabled = 0
let g:lsp_diagnostics_virtual_text_enabled = 1
let g:lsp_diagnostics_virtual_text_delay = 50
let g:lsp_completion_documentation_delay = 40
let g:lsp_document_highlight_delay = 100
let g:lsp_diagnostics_virtual_text_prefix = "🍔 "
let g:lsp_document_code_action_signs_delay = 100
let g:lsp_fold_enabled = 0
```
Sync Gatewayセキュリティ：概要

※ Couchbase Mobile(Couchbase Lite, Syncgateway)に関する記事について、[こちら](https://qiita.com/yoshiyuki_kono/items/6a5bbad1b02196a25417)も、参照ください。

## 概要

Sync Gateway3.0ベータでは、すべての通信のために、デフォルトでTLSを利用することが必要とされます。
これに該当する、Sync Gatewayで発生する通信には次のものが含まれます。

- Couchbase Serverとの通信
- クライアント(Couchbase Lite等)との通信

Couchbase Serverとの通信においては、Sync Gatewayがクライアントとなり、Couchbase Serverへ接続するための公開鍵を利用します。クライアントとの通信のために秘密鍵を管理します。

TLS v1.3がデフォルトのプロトコルです。また、開発とテストのためにTLSを無効にするオプションが提供されています。

セキュリティの設定は、ブートストラップ構成ファイル、またはコマンドラインで行います。


管理およびメトリクスREST APIは、Couchbase Server RBACユーザー資格情報を使用してアクセスを認証および承認することによってセキュリティが強化されます。

## Couchbase Server接続
デフォルトでは、TLS暗号化を必要とします。
サーバー接続文字列では `couchbases://`を指定します（「(couchbase)s」は、httpに対するhttps同様、「secure」を意味します）。

`bootstrap.server_tls_skip_verify` フラグを`true`にを設定して、開発、検証のために、TLSを無効にすることができます。


## クライアント接続
Sync Gatewayノードに接続するときにTLSを使用するように、Couchbase Liteクライアントアプリケーションを設定する必要があります。

## 関連情報

https://docs.couchbase.com/sync-gateway/3.0/secure-sgw-access.html
コンテナ(Docker)におけるポートフォワーディング

#ポートフォワーディングとは
ポート毎に接続先の仮想マシンを変える場合などに、ポートと接続する仮想マシンを指定して紐付けします。
Dockerでは、イメージからコンテナを立ち上げる時にポートを指定することができます。

#Dockerにおけるポートフォワーディング
前述の通り、コンテナを立ち上げる際にポートを指定できます。

```console
$ docker pull nginx
$ docker run --name mynginx -d -p 8080:80 nginx
```
以上では、nginxイメージをPullしてきて、`mynginx`というコンテナ名でデーモンとしてバックグラウンドで起動しています。
`-p`オプションでポートフォワーディングの設定をしています。
`docker ps`コマンドでポートフォワーディングが設定されていることが確認できます。

```console
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
7----------b   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   0.0.0.0:8080->80/tcp   mynginx
```

#curlでアクセスしてみる
`curl`コマンドで、localhostの8080番にアクセスしてみます。
以下のようなレスポンスが返ってきます。

```console
$ curl http://localhost:8080

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

```


以下のように、ブラウザでも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644352/b1eacee1-ef7c-1c73-9492-34c450c1efca.png)

#どのようなアクセスが発生したのか
なぜアクセスができたのかを振り返ってみたいと思います。

コンテナを立ち上げる際にホスト側のポートを指定しました。コンテナ側は、WEBサーバ(nginx)をコンテナ内に立ち上げるために`80(HTTP)`を指定しています。
ホスト側のポートは基本的になんでもOKですが、コンフリクトが起きてしまうとアクセスができないことに注意して設定しましょう。

```console
$ docker run --name mynginx -d -p 8080:80 nginx
```

先ほど記載をした以上の設定では、ホスト側の8080ポートにアクセスが来た際に、nginxコンテナの80ポートへフォワーディングする設定となっています。図で示すと以下のような形です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644352/b2923651-0d02-ae87-d992-b47e04ba28c2.png)
（参照先：https://tech-lab.sios.jp/archives/19073）

#最後に
Dockerコンテナにおいて、ポートフォワーディングの設定を行う際は
`docker container ps`コマンドでホスト側で既に設定されているポートを確認してから設定するようにした方がいいですね。
djangoの退会処理に関する仕様まとめ

今回のお題
-
今回はdjangoアプリのallauthというユーザー認証機能に含まれる退会処理という仕様についてまとめます。

基本的には自分用のメモです。

目次
-
- 退会処理とは
- 退会処理のロジック
- 退会済みになると変わること
- 退会しても変わらないこと

退会処理とは
-
退会処理はallauthの機能の一つで、他の言語では同様の機能を指して`論理削除`という言葉が使われていることも多いです。

具体的には、ユーザーを削除する際にデータそのものを完全に消してしまうのではなく、データは残しつつもサービスの利用などの一部の機能が行えない状態にすることを言います。

退会処理を実装するメリットは退会後でもユーザー情報を参照できるようになることですね。

例えば月額制のサービスであれば再加入した際に過去のアカウント情報やポイントなどを引き継げるといったメリットがあります。

反面デメリットとしては個人情報を保持し続けることによるセキュリティリスクと、アプリケーションのロジックが複雑化することですね。

後者に関してですが、例えばユーザー一覧ページを表示する際に物理削除であれば`Userモデルを全て取得する`という処理のみで済んでいたのが、退会処理であれば`Userモデルからアクティブなレコードのみを全て取得する`という処理になり一手間増えることになります。

上記は至極単純な例にしても、ユーザー情報を扱う処理で都度ユーザーの退会状態を考慮することになるので、必然的にロジックは複雑化してしまいます。

退会処理のロジック
-
djangoアプリのユーザー認証パッケージであるallauthにおいて、退会処理がどのように実現されているのかをまとめておきます。

- allauthが提供するAbstractUserにはデフォルトで`is_active`というフィールドが設定されている（デフォルト値は`True`)
- このフィールド値が`False`に設定されているユーザーに関しては退会扱いとなり、一部の操作が行えなくなる。
- 退会処理後もユーザー情報は保持されているので、管理者画面などから`is_active=True`に戻すことで再びアカウントとして利用できるようになる。

退会済みになると変わること
-
退会処理になると変わることは以下の通りです。

- そのユーザーを用いてログインすることができなくなる。また、ユーザー編集画面などで`is_active`フィールドの値を`false`に変更した場合には自動でログアウトされる。
- `ログインしていても特定の処理ができない`のではなく`ログイン自体ができない`ので、`{{ user.username }}`などとしてログインユーザーの情報を拾うこともできなくなる。


退会済みになっても変わらない部分
-
- `User.objects.all()`などとしたした場合、戻り値には退会済みのユーザーも含まれる。
- 一意制制約の際には、退会済みのユーザーの情報も参照される（退会済みのユーザーとの重複も許されない）。

終わりに
-
とりあえず基本的な仕様については以上としておきます。

また必要があれば適宜追加します。
allauth, CustomUserに関する仕様まとめ

今回のお題
-
今回はallauthやCustomUserの仕様に関してまとめます。

目的としてはアウトプットとメモ化が半々で、全体を通して見た時のテーマの一貫性はあまり感じないかもしれませんがご容赦ください。

目次
-
- ユーザー情報の一意性制約について
- フィールド初期値の変更について
- 退会処理と一意性制約

ユーザー情報の一意性制約について
-
ユーザー情報の一意性制約に関しては、デフォルトでは`usernameはあり`、`emailはなし`になっている(AbstractUserを継承した場合）。

`AbstractUser`の定義箇所は以下の通り。

```python:django/contrib/auth/models.py
    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True, # usernameは一意性制約あり
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=150, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True) # emailは一意性制約なし
```

今回はサインアップおよびログイン時の要求項目は以下のように設定しているが、modelの初期値として決まっていることなので、フィールドごとの一意性制約の有無はsettigs.pyによらないものと考えられる（検証はしていません）。

```python:settings.py
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_USERNAME_REQUIRED = True
```

フィールド初期値の変更について
-
フィールド初期値を変更したい場合には、以下のように記述しスーパークラスの情報を上書きする。

設定していない項目(今回であれば`blank=True`）についてはスーパークラスの情報を引き継ぐ。

```python:models.py
class CustomUser(Abstractuser):
  email = models.EmailField(unique=True)
```

退会処理と一意性制約
-
ユーザーを物理的に削除せずに退会処理させた場合（いわゆる論理削除）には、退会済みのユーザーの情報も一意性制約の参照対象となる。

つまり一意性制約をユーザー名やメールアドレスに設定していれば、それらに関しては退会済みのユーザーとの重複も許されなくなる。

終わりに
-
とりあえずは以上になります。

また何かあれば追加していきます。
【jQuery】数字の末尾を取得する方法

数あるリストの中から数字の下一桁を取得したかったのでその備忘録。


```javascript
$(function(){
    /* ツールチップ */
    $('.list').mouseover(function(){
        // ホバーした時のindexを取得
        let index  = $(this).index();
        // 取得したindexを文字列に変換
        let str    = index.toString();
        // splitで文字列を一つずつ配列に格納
        let strAry = str.split('');
        // 末尾の数字を取得
        let last   = strAry.slice(-1)[0];

        // 以下に処理を記述
    });
    $('.list').mouseout(function(){
        // マウスアウトの時の処理を記述
    });
```


気をつけないといけないのは、ただインデックスを取得しても出来ない。
数字は分割できないし、手っ取り早く文字列にキャストして
その文字列を操作して、下一桁を取得することが一番楽かも。

# メソッドの説明

## index
要素の順番を取得する

```Javascript
let index = $(this).index();
```
ホバーした要素の番号を取得する。
ホバーじゃなくてもクリックでも使える。

## toString
数値を文字列で返してくれる。

```Javascript
let str = index.toString();
```
これで数字を文字列に変換している

## split
文字列を任意の箇所で区切ることが出来る。

```javascript
let strAry = str.split('');

- 1桁
['1']

- 2桁
['1', '2']

- 3桁
['1', '2', '3']
```
ここでは、特に指定することはなくstrに入っている数字を一個ずつ分割して配列に格納している。

## slice
引数にインデックスを指定すると、指定した順番の要素だけを取得します。

```javascript
let last   = strAry.slice(-1)[0];
```
ここでは、slice(-1)とすることで配列に入れたstrAryから一番最後の要素を取得する。
返り値の型は配列なので、[0] を指定する。

# まとめ
最初は数字を取得すれば下一桁は取得できると思っていたけど、数字型のままだと取得は無理そう。
いったん文字列にするのもいい方法かわからないけど、現状ではこれが精一杯。
書けば覚えてくるからjQueryは苦手だけど少しずつ書いていこう。
【Swift】UITableViewを一番下にスクロールした時の処理

SwiftでUITableViewを一番下にスクロールした時の処理。

## 問題点

指で一番下にスクロールすると`scrollViewDidScroll`が呼び出される訳だが、人間より感度が高いので1回スクロールしただけで10回くらい呼び出される。

`scrollViewDidScroll`内の処理が完了するまで、次の処理が行われないようにしたい。

## 実装コード

```swift
var count = 0
var count_s = 0

func getInfo(){
    //ページが一番下にスクロールされた時に行いたい処理
    print("任意の処理")
    self.count_s += 1
}

//UITableViewの一番下にスクロールされた時に呼び出される
func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if (tableView?.contentOffset.y)! + tableView!.frame.size.height > tableView!.contentSize.height && tableView!.isDragging {
        if count == count_s {
            getInfo()
            count += 1
        }
    }
}
```
若干強引ではありますが`count`と`count_s`の変数を作って、それぞれ数字が同じ時のみ処理が行われるようにする。

`getInfo `関数の処理が完了されるまで、`scrollViewDidScroll `内に記載した処理は呼び出されないようになっている。

## 参考

https://qiita.com/Simmon/items/57018d59da6567720df3

## おすすめ情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
お名前.comのVPSにSSHでアクセスできない時の対処法

お名前.comのVPSにSSHでアクセスできなくなった時の対処法のメモです。
#問題
SSHでサーバにアクセスしようとしたところ、
`Resource temporarily unavailable  `
と表示され、アクセスできなくなりました。一方で、VPSサーバーコントロールパネルからコンソールを開いて
`ps ax | grep ssh `
と入力すると
` 973 ?        Ss     0:00 /usr/sbin/sshd -D `
と出力され、SSHデーモンが動作していることが確認できました。そのため、当初はなぜアクセスできないのか分からない状態でした。
#原因
2021年10月から順次実施されている[リニューアル](https://www.onamae-server.com/vps/migration/)により、新たに「セキュリティグループ」というものが追加されたことが原因でした。
![screencapture-onamae-server-vps-migration-2021-11-04-21_52_23(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659015/0c0957da-ea07-e6a5-0938-a7f45c8b89bb.png)


この変更によりVPSの外側で動作するファイアウォールが追加されたか、ファイアウォールの設定が変更されたようです。そのため、OSのファイアウォールとは関係なく、コントロールパネルで許可をしていないポートへのインバウンド通信ができない状態となりました。

リニューアル後のデフォルトでは0, 22, 80, 443番といったよく利用されるポートのみが開放されています[^1]。今回アクセスできなくなったサーバではセキュリティ対策のためにSSHのポート番号を変更していたため、SSHを使うことができなくなったようです。

#対処法
コントロールパネルのIPセキュリティから利用したいポート番号とプロトコルを追加します。今回はSSHとDNSのためのポートを開放しました。具体的な説明は以下の通りです。

1. [セキュリティグループで選択するポートを追加・削除する](https://www.onamae-server.com/guide/vps/p/41)
 1. まず[vpsサーバコントロールパネル](https://cp5.myvps.jp/)を開きます。
 2. IPセキュリティの項目を選びます。
 2. 「インバウンドルール（ポート）一覧」の右側にある「設定を追加」をクリックして、プロトコルを選択し、ポート番号、「ルール名」を入力してから「追加する」をクリックします。
1. [セキュリティグループを追加・編集・削除する](https://www.onamae-server.com/guide/vps/p/33)
 3. 「セキュリティグループ一覧」の右側にある「設定を追加」を選んで、「グループ名」を入力し、2で入力した「ルール名」を選択します。このとき、選択欄の右側にある+ボタンを押さないと「追加する」をクリックできないので要注意です。 ![お名前.com VPS(KVM) コントロールパネル - Google Chrome 2021_11_05 0_33_53 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659015/88163c38-7626-3341-afca-3cb26d935558.png)

1. [IPセキュリティを設定する](https://www.onamae-server.com/guide/vps/p/42)
 1. 左側メニューより「サーバー一覧」をクリックします。
 1. 設定を行うサーバの右側にある詳細をクリックします。
 1. 詳細画面に遷移するので、「IPセキュリティ」の「変更」をクリックします。
 1. 追加したい項目」をクリックし、プルダウンメニューから3で入力した「グループ名」を選択します。
 1. 選択した「グループ名」の右側にある+をクリックします。これを忘れると設定が反映されないので要注意です。![お名前.com VPS(KVM) コントロールパネル - Google Chrome 2021_11_05 0_49_15 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659015/a49e657b-eddc-9a7a-29f9-279665082095.png)
 1. 「変更する」をクリックして、操作は完了です。

しばらく待つと設定が反映されて、アクセスできるようになります。もしアクセスできない状態が続く場合は、サーバを再起動すると改善されるかもしれません。

#参考資料
https://knowledge.sakura.ad.jp/22269/

[^1]: 詳細はこちら：https://www.onamae-server.com/guide/vps/p/42
Xcode13のUser-Defined Settingで「MTLLINKER_FLAGS」キーが登録できないときの対処法

# TL;DR
Xcodeのビルド設定に新しく`Metal Linker - Build Options`という項目ができているので、そこに値`-cikernel`を指定しましょう。

# 環境
- Xcode 13.1
- macOS Big Sur 11.6.1

# 起こっていたこと
Core ImageのフィルタをMetalファイルで記述するには、XcodeのBuild Settingを以下の2つ変更する必要があります。

- `Other Metal Compiler Flags`に`-fcikernel`を指定する
- `User-Defined Setting`として`MTLLINKER_FLAGS`キーを追加し、値に`-cikernel`を指定する

このうち下側の`User-Defined Setting`で`MTLLINKER_FLAGS`キーを追加しようとしたところ、「すでに設定されている名前なので違う名前で設定してね」というエラーが出ました。
> There already is another setting named "MTLLINKER_FLAGS". Please enter a different name.
![ 2021-11-05 11.17.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232840/885ad837-0479-a9f5-ae5c-e3b3666384c1.png)

# 対処したこと
Xcodeのビルド設定に、新しくMetal Linkerのビルド設定ができる項目ができているのでそこに値`-cikernel`を入力します。

![ 2021-11-05 11.07.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232840/3bc5723c-70f8-dbab-8872-9d21f49b73af.png)
Sửa tủ lạnh quận Gò Vấp Limosa

Stack social

https://www.podomatic.com/podcasts/suatulanhquangovaplimosa
https://www.woddal.com/suatulanhquangovaplimosa
https://www.allmyfaves.com/suatulanhquangovap/
https://issuu.com/suatulanhquangovaplimosa?issuu_product=header&issuu_subproduct=publisher-home-v2&issuu_context=link&issuu_cta=profile
http://onlineboxing.net/jforum/user/editDone/136399.page
https://sdgs.scout.org/user/3005828
https://www.deviantart.com/suatulanhquangovap
https://gitlab.com/suatulanhquangovaplimosa
https://app.gumroad.com/suatulanhquangovap
http://www.koinup.com/suatulanhquangovaplimosa/
https://www.pinterest.com/limosasatlnhqungvp/_saved/
https://trello.com/suatulanhquangovaplimosa
https://www.scoop.it/u/suatulanhquangovaplimosa
https://ub.com.vn/f/members/suatulanhgovap.393886/
https://danluat.thuvienphapluat.vn/thanh-vien/suatulanhquangovap
https://www.codecademy.com/profiles/suatulanhquangovaplimosa
https://www.eventbrite.com/u/677775598043#profile-following
https://fr.quora.com/profile/S%E1%BB%ADa-t%E1%BB%A7-L%E1%BA%A1nh-Qu%E1%BA%ADn-G%C3%B2-V%E1%BA%A5p-Limosa
https://unsplash.com/@suatulanhquangovaplimosa
https://public.tableau.com/app/profile/suatulanhquangovaplimosa
https://www.atlasobscura.com/users/1211f210-d9ec-44de-974e-771d4718d77b
https://500px.com/p/suatulanhquangovaplimosa?view=photos
https://getpocket.com/@d30p7T49A241cdd6fIg25dhgbsdaA807a4cA20Ba93Jd97l9084b6Ty8Ed9zk308?src=navbar
https://hubpages.com/@suatulanhquangovaplimosa
rtcwake: write error が出て途方に暮れたら

linuxでPCを休止状態にして指定時刻で立ち上げたいが
rtcwake -m disk ...
でwrite errorが出てできない、という時にチェックしてみる項目
・BIOS設定確認（ACPIうんたらかんたら。ハードが対応していなければどうしようもないです）
・swap領域の容量（使用中メモリを全部保存できる容量。自分の場合、実メモリの倍+αにした）

ここまでは前振りとして

・swap領域をswapfileではなくパーティション上に確保（これ！）
　　理由等詳しい訳ではなく経験則だが、centos7,ubuntu20ともswapfileから変えたらできるようになった。
　　再インストールしなくてもgpartedで既存の領域を減らしてswapパーティション用の領域を確保、作成(linux-swapを選択)できる。
　　危険な操作なため詳しくは書きませんので、それぞれの環境を確認して実施してください。試行錯誤中、パーティションの構成によってはgpartedで既存領域を減らせないこともありました。
【超初心者編】PHP7×MySQL、PDOを使用してDB(データベース)に接続する方法

#データベースとの接続は、初心者にとって「最初の壁」#
こんにちは、自分はPHPを勉強して2ヶ月目の初心者です。
今回は自分用のメモと記憶整理としてデーターベース（以降：DB）との接続方法を超簡単に説明します。

環境は以下の通り
・MAMP6.2
・PHP7.4.9
・MySQL 5.7.30

#####<font color="red">【注意】初心者の解説なので、専門的に学習したい人は他の学習用のサイト・ページなどを参考にしてください！</font>#####

#MySQLとPDOについて#
###MySQLはオープンソースのDB（データベース）管理システムです。###
（オープンソースとは商用、非商用を問わず配布されてるもの）
・無償で利用できる
・大容量のデーターを高速で動作させられる
・幅広いOSに対応している（Windows,mac,Linuxなど）

上記は特徴の一部に過ぎません。
優秀なシステムで実際に世界中の企業でも使用されています。

###PDOとは？###
PDO(PHP Data Objects)とは、
PHPからDBへアクセスする機能を持った拡張モジュールです。

なにやら難しそうですが、とりあえずDBへアクセする為の便利な機能だと思ってもらえれば、今回は大丈夫です！

#接続する方法#
それでは、接続方法を解説していきます。
先づはDBに接続するSQL文を用意します。

~phpMyAdmin上の表記以下と仮定~
Sever：localhost8889
ユーザー名：root
パスワード：root

###DB接続用のSQL文を作成###

```ruby:PHP7
$sql = 'mysql:dbname=test;host=localhost;port=8889;charset=utf8';
$user = 'root';
$pass = 'root';
```

変数sqlにDB接続用のsql文を代入して、
dbname、host、portの各所にDBの情報を入力します。

最後のcharasetの所は、文字コードをUTF-8に指定しています。

変数userとpassにはユーザー名とパスワードを入力してください。
###PDOを使いSQL文を$dbhに代入する###

```php
$dbh = new PDO($sql,$user, $id);
```
$dbhにPDOを使い、先程の変数を組み合わせる。

###例外処理を追加###
もしDBとの接続が出来なかった場合、エラー文を表示する様に
try(例外処理)を追加します。

```php
try {
 $dbh = new PDO($sql,$user,$id);
} catch(PDOException $e) {
  echo('DB接続エラー：' . $e->getMessage());
}
```

これによりDBと接続出来なかった時、cath内の'DB接続エラー'とエラー文が表示されるようになります。

#まとめ#
MySQLなどDBの世界は本当に奥が深く、覚える事が多く難しいです。
そんな中、少しでも分かりやすく記録できたらと思い投稿させていただきました。

今回はDBの接続方法のみですが、今後SELECTやINSERT、内部結合についても取り上げられたらと思います。
少しでもお役に立てたら幸いです！
ELBのスティッキーセッションについて

## 勉強前イメージ

スティッキーがわからない・・・

## 調査

### ELBのスティッキーセッションについて

ELBがサーバにアクセスを振り分けるとき、
デフォルトであればELB配下のインスタンスに均一に分散させるため、一つのインスタンスにずっとつなぐということはできません。
しかし、cookieの情報を元に一定のインスタンスで処理させることができます。

### cookieの有効期限の設定の種類

以下の2つあります。

- ロードバランサーが生成したCookie
- アプリケーションベースのCookie

デフォルトでは均等に負荷分散させるようにスティッキーセッションはオフになっているので、
設定を変更しないといけません。

### そもそもの背景

なぜスティッキーセッションを必要とするのかですが、
普通のwebサーバだと特に気にせず負荷分散を點せればよいですが
セッション管理をしているシステム等はセッションの途中でサーバが変わってしまうとややこしくなってしまいます。
そこでスティッキーセッションを行い、同一セッションについては同じサーバで処理するようにすると
簡単に目的を達成することができます。

### 設定方法

設定方法はロードバランサーではなく、ターゲットグループに設定を行います。
特定のターゲットグループにチェックを入れ、属性 から 編集 を行うことで下記のように設定ができます。
デフォルトではチェックが入っていないので実施したい場合はこの設定が必要になります。

![12021-11-04Target groups _ EC2 Management Console - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/d96f5865-84a1-ffcb-a707-8ca1fbb0cd1d.png)

### 費用について

スティッキーセッションについては追加料金無しで利用できるので、
セッションの維持が必要なシステムであれば設定してみてもいいかもしれません。

## 勉強後イメージ

そもそもセッションの維持が必要 っていうシステムもあるんだね。
多分こうやればテスト出来るんだろうなーっていうのはあるけど、なかなかやってみるのは腰が重いね

## 参考

- [AWS ELBのスティッキーセッションでセッションの維持をしてみた](https://recipe.kc-cloud.jp/archives/8782)
- [【基礎から学ぶ】ELBのスティッキーセッションについてまとめてみた](https://blog.serverworks.co.jp/tech/2017/01/05/elb-sticky/)
【JavaScript】関数とオブジェクト㉑　getter/setterとstatic



#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/3b12a8c1822159363191

#目的

* 関数とオブジェクトについての理解を深める

#本題
###1.getter/setter

* ディスクリプターのオプションの１つ
* 設定すると特別な機能をもたせられる


####例1

getterとsetterの挙動の確認

````js
function Person1(name, age) {
	this.name = name;
	this.age = age;
}

// ディスクリプターを設定
// Person1のnameプロパティの設定値をsetter,getterにする
Object.defineProperty(Person1.prototype, "name", {
	// getが呼ばれた際の挙動を書く
	get: function () {
		return this._name;
	},
	// setには引数を設定
	set: function(val){
		this._name = val
	}
})

// 上記のgetとsetをどのように使うのか
// インスタンス化を行う
const p1 = new Person1("o-kido", 49);
// 下記のように設定するとprototypeのnameに値を取りに行くとgetが呼ばれる
// Person1関数のthis._nameにo-kidoが格納されているので、getter経由でo-kidoと出力される
console.log(p1.name)
// setでの挙動は引数valに対して、代入した値が渡ってくる
// その値をthis._nameに入れるので出力結果はnanakamadoになる
p1.name = "nanakamado";
console.log(p1.name);
``````

####例2

実際にどのような場面で使うのか


````js
function Person1(name, age) {
	this.name = name;
	this.age = age;
}

Object.defineProperty(Person1.prototype, "name", {
	get: function () {
		// 関数が呼ばれたタイミングで必ず実行される
		// 何らかの処理を間に加えておくと先に出力される
		console.log("hello");
		return this._name;
	},
	set: function(val){
		this._name = val
	}
})
// 下記の出力結果はhello o-kidoとなる
const p1 = new Person1("o-kido", 49);
console.log(p1.name)

p1.name = "nanakamado";
console.log(p1.name);
````

####例3

definePropertyを簡略化して書く

```js
class Person2 {
	constructor(name, age) {
		this._name = name;
		this._age = age;
	}
	// :functionの部分をnameに書き換える(setter同様)
	get name() {
		console.log("hello");
		return this._name;
	}
	// 上記カンマも不要
	set name(val){
		this._name = val
	}
}

const a = new Person2("ゼニガメ", 3);
console.log(a.name);
```

###2.static

staticというのはclass内で使用する静的なキーワードのこと
インスタンス化を行わずに使用できる

####例1

`````js
class Person2 {
	constructor(name, age) {
		this._name = name;
		this._age = age;
	}

	get name() {
		return this._name;
	}

	set name(val){
		this._name = val
	}

	static go(){
		// 出力したい結果を入れておく
		console.log("いけ！");
	}
}
// goメソッドを呼び出して使用できる
Person2.go();
const a = new Person2("フシギダネ", 2);
console.log(a.name);
`````

thisは使用できない
Person2からインスタンス化をしていないから

####例2

Person1のコンストラクター関数を使うとどのように使用できるのか

```js
function Person1(name, age) {
	this.name = name;
	this.age = age;
}

Person1.hello = function() {
	console.log("hello");
}
Person1.hello();
````

クラス表記を用いた場合でも、コンストラクター関数にメソッドを追加して使用した場合もスタティックメソッドと呼ぶ

今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
docker compose で「Additional property {property} is not allowed」エラーが出る

# 概要
`docker-compose up -d` をしたら　「Additional property {property} is not allowed」というエラーが出たので原因と解決策を紹介します

# 経緯
新しいMacに「Docker Desktop for Mac」を入れて、いざ `docker-compose up -d` をしたら上記のエラーが発生しました

# 解決策
dokcer-compose.yaml に 「version」と「services」を入れることで解決しました

## 修正前

```docker-compose.yaml
web:
  image: xxxx
```

## 修正後

```docker-compose.yaml
version: "3"
services:
  web:
    image: xxxx
```

# 原因
## ドキュメント
下記のドキュメントを読むと
https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/compose-versioning/

> バージョン 1（非推奨）
Compose files that do not declare a version are considered “version 1”. In those files, all the services are declared at the root of the document.
> Version 1 is supported by Compose up to 1.6.x. It will be deprecated in a future Compose release.

docker-compose.yamlにversion指定がないとversion 1と解釈されます
version 1はdocker-compose 1.6.xまでサポートされます

> Version 2🔗
Compose files using the version 2 syntax must indicate the version number at the root of the document. All services must be declared under the services key.

dokcer-compose.yamlにversion 2を指定した場合にservicesの宣言が必須です

## docker-compose version
そこでインストールされたdocker-composeのバージョンを調べます

```
$ docker-compose version
Docker Compose version v2.0.0
```

## 推察
1. 最新のDockerを入れたところDocker Compose version v2.0.0がインストールされた
1. docker-compose.yamlにversion指定がないので本来ならばversion 1として解釈される
1. ただ、version 1はdokcer-compose 1.6.xまでしかサポートされておらずversion 2と解釈された(と思われる)
1. version 2ではservicesの宣言が必要となっているのでエラーになった
1. そこで、docker-compose.yamlにversionとservicesを宣言することでエラーが解消された
onamae.com でドメインを設定する方法

ドメイン名を取得後、IPアドレスを設定したり、サブドメインに、IPアドレスを設定する方法です。

onamae.com にログインします。
![onamae_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/789cbc26-3bcd-89e9-7c37-eaf6a95ccdd4.png)

ネームサーバーの設定　-> ドメインのDNS設定
![onamae_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/699a7650-04f0-4912-74eb-a135e314309f.png)


ドメイン名を選んで、　次へをクリック
![onamae_cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/96b3c5a8-a19c-bbc3-5f9f-b6548756edb5.png)

DNSレコード設定を利用する
![onamae_dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/939b7cf7-9a51-5e70-516e-0912dc0b7c17.png)



A/AAAA/CNAME/MX/NS/TXT/SRV/DS/CAAレコード にホスト名をValue を入れる
![onamae_ee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/dd06e831-a7c1-c435-31f1-2f387ecf870f.png)


確認画面へすすむ
nodenvでyarnも管理する

## やりたいこと
nodenvを利用して開発していてyarn周りでエラーが発生したので確認したところ、
nodenvではデフォルトでyarnのバージョン管理をしていなかったのでバージョン管理をできるようにする

## 結論
[nodenv-yarn-install](https://github.com/pine/nodenv-yarn-install)を利用する

### やること
- pluginsディレクトリを作成
- git cloneでインストール
- 既存のバージョンでyarnをインストールしたい場合は再インストールする

```
git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"
```

これで次回以降、新しいバージョンを入れるときもYarnがnodenvによって管理されるようになります
【Python】文字整数　昇順ソートリスト作成　レシピ

# 1.【やりたいこと】

```python
array_1 = '10 6 8 1 5 9 3 4 7 2'

type(array_1)
> `class 'str'`

# やりたいこと
array_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

# 2.【作成レシピ】
使用メソッド
* 内包表記：array_1の文字型の整数をint型へ変換　（str型→int型）
* 組み込み関数：sorted()

```python
array_1 = '10 6 8 1 5 9 3 4 7 2'

# レシピ
array_2 = sorted([int(i) for i in array_1.split()])

# 完成
array_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
windowsでiverilog その108

#概要　

windowsでiverilogやってみた。
シリアル送信のテストベンチ、書いてみた。

#参考にしたページ。

https://qiita.com/yamori813/items/a0a309de18dea405f055

#サンプルコード

```
module test;
	reg clk;
	reg rst;
	reg we;
	wire busy;
	reg [7:0] data;
	serial_send u(.CLK(clk), .RST(rst), .DATA_IN(data), .WE(we), .DATA_OUT(TXD), .BUSY(busy));
	always
	begin
		#1
			clk <= ~clk;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		rst <= 0;
		clk <= 0;
		we <= 0;
		#2
			rst <= 1;
		#2
			data <= 8'h55;
			rst <= 0;
			we <= 1;
		#2
			we <= 0;
		#20000
			$finish();
	end
endmodule


```
#結果

![ses.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e0485f81-07ff-98ae-4816-c3abe4af65c0.jpeg)


以上。
エッジAI端末を使ってみた 〜デモ動作編〜

## 概要
* データの発生源に近い場所でデータを処理する「エッジAIコンピューティング」が注目されている
* まず、エッジAIのおおまかな概念を理解し、実際にエッジAI端末を購入して使ってみる
* 静止画像解析、次に動画解析と進めていく予定であったが、難易度が高いため今回は動体検知のデモの動作を確認する

## エッジAIとは何か
* 通常AI利用する場合は、センサーから収集された各種データはマイコンボードやスマホ、ネットワークを経由し  
、クラウド上や従来型のサーバーで解析処理を行う
* エッジAIを利用すると、センサーから収集された各種データはマイコンボードやスマホ内で解析される

![スクリーンショット 2021-11-05 9.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/c860f214-fb02-3180-c4a4-554e91e7371a.png)

![p21_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/9bbba5b2-d14f-e3dd-21ea-7e72415cdb61.jpeg)

![p21_03-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/ca5a9c2d-a257-e8cc-b5e8-affbf0b154a5.jpeg)

## 用意するもの
* Jetson Nano開発者キット 2GB
* RaspberryPi4 対応 電源セット(5V 3.0A)　←Jetson Nanoにも使えます
* RaspberryPi4純正カメラ、またはUSBカメラ
* microSDカード(32GB以上推奨)
* USB接続のマウス・キーボード
* HDMI接続のディスプレイ(4K推奨)

# デモ実行
VisionWorksという、カメラ等で撮影した映像をAIでリアルタイム解析し
情報を付加するデモです。

デモ環境のセットアップ
ホームディレクトリ ~/ にデモ環境をインストールする

```
# /usr/share/visionworks/sources/install-samples.sh ~/
```

ソースコードの状態なので、そのままでは実行できません。 make コマンドでコンパイルします。

```
# make -j4 # add dbg=1 to make debug build 
```
makeコマンドのオプション解説

* -j4 makeコマンドをマルチプロセッサ環境で高速化する  
　※この場合はジョブ数が4となります  
　※ ＃以降は、コメントです

![p21_04-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/0095c6f5-430e-3d0a-f39d-42c271fc3a4e.jpeg)

動体検知のデモが動作している様子
実行ファイルのあるディレクトリに移動する

```
# cd bin/aarch64/linux/release/
```

デモを実行する

赤点は道路やセンターライン、車、橋の柵を検出しているのが分かります
緑色の矢印は、それが移動している方向や速さを示しています。

```
# ./nvx_demo_feature_tracker
```

動体検知のデモが動作している様子

![p21_06.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/fea7b3fc-1db4-59fb-38ea-32801a2d05da.gif)

動体検知のデモが動作している様子

![p21_07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701445/d7e1aeae-f40f-0e05-5f76-04930b06a6d8.gif)


## 次回に向けて
* 自分で撮影した動画ファイルを使ってみる、できればUSBカメラを使った検出にもチャレンジしてみる
* OSの起動時にエラーが出るので、次回までには解決したい
古いdebian環境でのsystemctl not found / service not found

個人的覚書。

Debian5環境でserviceコマンド、systemctlコマンドが使えない場合の対策です。
Debian では起動スクリプトは /etc/init.d/ディレクトリに置かれているので、


```
su
/etc/init.d/apache2 restart
```

要は
service サービス名 コマンド名　を
/etc/init.d/ サービス名 コマンド名にしただけ。


```
ls -a /etc/init.d/ 
```

上記でinit.d配下にあるなら動きますよ、という話でした。
キューを使ってステージ生成できそうじゃね？

# はじめに
 最近ゲーム制作をしており、その時に「このプログラムならキューを用いたら出来そうじゃない？」と思い、その時に実装したものを掲載しています。

# どんなものを作ったの？
 私が今回作成したのは、プレイヤーが走るためのステージ自動生成機能の実装です。以下がその機能を実装したものとなります。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/47616ff1-3647-58d3-634d-12c6b63c58c8.gif)

プレイヤーの動きに対して、良い感じにステージが自動生成及び自動削除されてますね！！
以下がステージ生成と削除のコードになります。

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StageGenerator : MonoBehaviour
{
    int StageSize = 30;
    int StageIndex;

    public int numberOfStages;
    private Queue<GameObject> stageQueue = new Queue<GameObject>();

    public Transform Target;//Player
    public GameObject[] stageTips;//ステージのプレハブ
    public int FirstStageIndex;//スタート時にどのインデックスからステージを生成するのか
    public int aheadStage; //事前に生成しておくステージ

    // Start is called before the first frame update
    void Start()
    {
        // 初めに生成
        for(int i = 0; i < numberOfStages; i++)
        {
            stageQueue.Enqueue(MakeStage(StageIndex));
            StageIndex++;
        }
    }

    // Update is called once per frame
    void Update()
    {
        int targetPosIndex = (int)(Target.position.z / StageSize);
        if(targetPosIndex + aheadStage > StageIndex)
        {
            NextStage();
        }
    }

    void NextStage()
    {
        GameObject previousStage = stageQueue.Dequeue();
        Destroy(previousStage);

        stageQueue.Enqueue(MakeStage(StageIndex));
        StageIndex++;
    }

    GameObject MakeStage(int index)
    {
        int nextStage = Random.Range(0, stageTips.Length);

        GameObject stageObject = (GameObject)Instantiate(
            stageTips[nextStage],
            new Vector3(0, 0, index * StageSize),
            Quaternion.identity);
        return stageObject;
    }
}
```
###コードの内容と感想
GameObject型のキューを宣言し、EnqueueでstageQueueにnumberOfStage分のデータを登録します。登録データはMakeStageメソッド内で処理されランダムなステージを生成します。NextStageメソッドではでキューを行い、データの削除を行っております。

###キューと、デキューってそもそもなに？
データ構造の一つです。データ構造に入っている要素のうち、最初に登録された要素から順に取り出していくものです。このような動作をFIFO(first in first out)と言います。 
似たようなデータ構造としてスタックというものがあります。これは最初に登録された要素が最後に出てくるLIFO(last in first out)の動作を行います。 
このデータ構造はいろいろな所で利用されているので、学んでおいて損はないと考えます。私も勉強中です。
######データ構造参考資料
https://qiita.com/drken/items/6a95b57d2e374a3d3292

###さいごに
最近、UnityやらFlutterやら触っている自分ですが、やはりプログラムの根幹にある数学や物理、アルゴリズムについてもっと学ばなくてはいけないなと感じました。これからも日々精進していきたい所存です。 
Qiitaにあるコードと同じですがGithubの方にも同様のものを掲載させていただきます。気になったら覗いてください。以下がリンクになります。
https://github.com/keigo194547/GenerateStage
JqueryとHTML手抜き用メモ。

JqueryとHTML手抜き用メモ。

・minの値を入力するとmaxの値を補完
・値無しにチェックしたら値ありを無効化

ここにプラグインのやつほしいなぁ。

```HTML:未検証
<p>値無し<input type="checkbox" id=avg value=""></p>
値あり
<input id="avg-min" type="text" value="">
～
<input id="avg-max" type="text" value="">

<script>
$('#min').on('change', function () {
	var min = $(this).val();
	$('#min').val(max);
});

$(document).on('click', '#avg', function(){
	var checked = $('#avg').prop('checked');
            $('#avg-min').prop('disabled', checked);
            $('#avg-max').prop('disabled', checked);
});
</script>
```

@juner さんより最後の2行の引数の誤記の指摘をいただきました。
無茶苦茶ありがとうございます。
[Python] [openpyxl] １つのExcelファイルから全てのシートを単独のExcelファイルに分割

openpyxl にて、シートをコピーすることが不可能なので、いろいろ検索したが洗練されたものが見当たらなかったので、自作した。
python 初挑戦　＆　Qiita 初投稿なので改善点等、 ~~あるかもしれません。~~ ありました。（汗）

```python:splitsheet.py
import openpyxl
import copy

book = openpyxl.load_workbook('test.xlsx')

for sheet in book:
    file_name = sheet.title + ".xlsx"
    print(file_name)
    new_book = copy.deepcopy(book)

    for new_sheet in new_book:
        if new_sheet.title == sheet.title:
            continue
        else:
            new_book.remove(new_sheet)
        
    new_book.save(file_name)
```

コマンドライン引数を取るように一般化したものは、[次の記事](https://qiita.com/VoshVolk/items/25474ef32fa415d48221)にて。

####参考

[https://qiita.com/github-nakasho/items/fb9df8e423bb8784cbbd](https://qiita.com/github-nakasho/items/fb9df8e423bb8784cbbd)
[https://kirinote.com/python-specificsheet-newbook/](https://kirinote.com/python-specificsheet-newbook/)
C#：値の種類と変数

# 値の種類
* 値の型　4種類のみ
    * 整数
        * 基本的にはintを使用
    * 実数
        * 基本的にfloatを使用
        * 使用する際には数字の後に f をつける 例）24.5f
    * 文字列
        * 基本的にStringを使用
        * 使用する際にはダブルクウォーテーションで囲む 例）"日本語"
    * 真偽値
        * true, falseを使用

- 変数の利用範囲
    - 変数は、その変数の宣言をした構文の中でだけ使える。構文を抜けて外に出ると使えない。
    - 変数宣言が書いてある{} 記号の内部でのみ使える。ということ。
    
#　変数
- 変数を使用するには値と変数の型が一緒で無くてはならない
- 変数に値を入れることを代入
- 変数に使える値は半角英数字とアンダースコア( _ )のみ

```c#:変数.cs

//[変数の宣言]
//型名 = 変数名;
//型名 = 変数名, 変数名, 変数名....;
int x; 
string s;

//[変数への代入]
//変数 = 値;
x = 100;
s = "Hello";

//[宣言と代入]
int x = 100;
string s = "Hello";

//変数の名前
name; //OK
first_name; //OK
last-name; //NG ハイフンがだめ

```
Route53でホストゾーン作成時にSERVFAILとなる

以下の記事を参考にさせていただきました

https://study-blog.d-horiyama.com/2020/10/28/000051/

https://qiita.com/kawa-taro/items/5b2a3ca8e51620ac8387

表題の通りドメインを買ってホストゾーンを作成後名前解決を試行すると SERVFAIL となりました。

```shell
% nslookup <domain.name> 8.8.8.8
Server:		8.8.8.8
Address:	8.8.8.8#53

** server can't find zees.link: SERVFAIL
```

SERVFAILとは以下の通りドメイン自体は存在するが、なんらかの問題が起きてる状態のようです

https://aws.amazon.com/jp/premiumsupport/knowledge-center/partial-dns-failures/
> 権威あるネームサーバが応答しないか、予期しない情報で応答する場合、ローカルリゾルバーは SERVFAIL メッセージを返します。

## DNSの設定を見直す
ホストゾーンのNSレコードと登録済みドメインのネームサーバが一致してないため、そこが原因と思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/3b97dba2-3975-1fd7-5050-63fcfa25a742.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/c4a884f7-9136-5937-f641-8d4d33cd2923.png)
## 更新する
登録済みドメインのネームサーバーをホストゾーンのNSレコードで更新する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/2f4640ee-6842-6609-a051-5b078eeeea04.png)

## 再度名前解決を試す

```sh
nslookup <domain.name> 8.8.8.8
Server:		8.8.8.8
Address:	8.8.8.8#53

Non-authoritative answer:
Name:	<domain.name>
Address: 13.115.18.61
Name:	<domain.name>
Address: 13.230.115.161
```

いけました！あらかじめ情報公開してくれていた方に感謝いたします。
Marpでスライドを作成する時の絵文字のライセンス

結論から書くと

- Marpの絵文字は Twemoji 
- Twemoji は[CC-BY 4.0]( https://creativecommons.org/licenses/by/4.0/)
- [適切なクレジット表示](https://wiki.creativecommons.org/wiki/License_Versions#Detailed_attribution_comparison_chart)を行えば商用利用可能。
    - クリエイティブ・コモンズ【表示4.0国際】: https://creativecommons.org/licenses/by/4.0/legalcode.ja
    - ライセンス表記例: `Twemoji” by Copyright 2021 Twitter, Inc and other contributors is licensed under CC-BY 4.0`
    - クリエイティブ・コモンズの書き方参考: https://find47.jp/ja/credit/


https://note.com/ajalaca_ui/n/ne6a18feb4ca5

https://qiita.com/tinoji/items/3eb89e889312ecc63907

## Marp(Marpit) とは

https://qiita.com/tomo_makes/items/aafae4021986553ae1d8

Markdownからスライドを作ることができるVSCode拡張がとても便利で使っています。Marpitはそのフレームワーク。以下。

https://github.com/marp-team

https://github.com/marp-team/marpit

で、このMarp、絵文字をそのまま挿入することができましてお手軽で便利で私のセンスでもそこそこおしゃれになるなと重宝していたのですが、よく考えるとこの絵文字、使えるのだよな？と一抹の不安を感じてきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/e0266dcf-5cad-cb67-e1d8-c7d794f2f8f0.png)

:thinking::thinking::thinking:。。

## 絵文字のライセンス

https://emojipedia.org/licensing/

> 多くの絵文字プロジェクトが存在し、様々なライセンスオプションがオンラインで明示されています。すべてではありませんが、いくつかの絵文字は無料またはオープンソースです。以下の絵文字セットのライセンス情報は、以下にリンクしています。

> 📝 Google Noto Emoji
> 📝 Microsoft Font FAQ
> 📝 Twitter Twemoji
> 📝 JoyPixels
> 📝 OpenMoji
> 📝 emojidex

> 上記のプロジェクトはそれぞれ、使用方法（オンラインのみ、印刷、商用など）、帰属や配布に関する特定の条件があるかなどが異なります。

https://iwatendo.hateblo.jp/entry/2020/09/22/090000

https://mikit-tz.com/emoji-emoticon-and-aa-copyright/

絵文字にも著作権がある。ざっくり、twemojiは先のようにCC-BY 4.0だが、Appleの絵文字は厳しい。

https://discussionsjapan.apple.com/thread/110193857

https://twitter.com/Sam0711er/status/958793819495059460?s=20



## Marpの絵文字

Marpの絵文字は何なのかなのですが以下に書いてあります。Twemojiです。Marp自体がそれは利用者だからなあ等。

https://github.com/marp-team/marp-core

https://github.com/marp-team/marp-core#emoji-support

> Emoji support
> Emoji shortcode (like :smile:) and Unicode emoji 😄 will convert into the SVG vector image provided by twemoji 😄. It could render emoji with high resolution.

## Twemoji

https://github.com/twitter/twemoji


https://twemoji.twitter.com/


> Graphics licensed under CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/

## まとめ

https://qiita.com/e99h2121/items/79db6b7375ccbf3d3977

:cake: 以上でした。参考になればさいわいです。:cake:
Gitで今いるブランチ名を取得する方法( git branch --show-current )

# Gitで現在のブランチ名を取得するコマンド
```bash
git branch --show-current
```

# どうせならブランチ名をコピーまで
```bash:macの場合
git branch --show-current | pbcopy
```

```bash:windowsの場合
git branch --show-current | clip
```

# aliasも加えちゃおう
```bash
alias gbcp='git branch --show-current | pbcopy'
```