OmniAICreator/Qiita-1.07M huggingface dataset:
Javascript02_書く場所

1　onclick属性内に書く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/ecf513d2-5a97-5604-ce7c-a6c4a8049ed2.png)

2 href属性の中に書く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/db90dce5-9d52-6f2b-9d34-5b6849ae81e2.png)
　
※何も書かない時は反応しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/d35d084c-14ed-f7d6-15e2-449cefbcb733.png)

3 headの中に書く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/403a2c02-8fe9-67ae-f68c-6643c87f4968.png)

4 外部JSファイルを参照
　保守しやすいため、一番おすすめです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/32e39ccd-0747-c919-9614-d89fe74e926e.png)
javascript04_変数

変わらない値：　123435435464...
変数：値を保存することができます。
　　　また変数の値は任意に変更することもできます。
     変数で値を説明することができます。（例： var age = 80;)


①変数の宣言が必要です。
var a; 

②宣言された変数に値を入れる。
a = 123;
a = 456;

console.log(a);

①と②は同時に実施することができる。
var a = 123;
javascript05_変数の命名

変数名、関数名、引数名、属性名の命名にはルールがあります。

1 数字、アルファベット、_、＄を含むことができます。
  var a_1_$
2 名前は数字から始まることはできません
3 既存のキーワードの名前を使用することはできません
　break、do、else、class、super、etc....
4 変数名は一般的に下記のように命名する。
　最初のアルファベット文字は小文字、各単語の初文字は大文字。
  helloWorld
　xxxYyyZzz
5 変数名は全部unicode-8に属されます。
javascript06_データの型

jsの中に全部６種類の型があります。
1 String 文字
2 Number　数値
3 Boolean 
4 Null
5 Undefined 
6 Object

1-5までは基本的なデータ型になります。
6 Objectは引用データ型です。

String型：　'',""で囲む必要がある。
          - ""のなかに""を入れることはできません。
          - ''のなかに''を入れることはできません。
var str = "hello";
console.log(str);

＼は特殊な意味を表します。
\" : "
\': '
\n: 改行
\\: \
javascript07_Number

varで変数の宣言をする時に、宣言の回数は１回で十分です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/4591bd70-8da0-73d2-7159-a1afef793803.png)

注意：実行は上から下へ

JSに全ての数値はNumber型です。整数も小数もNumber型です。

typeofで変数の型を確認することができる。
構文：　typeof 変数
console.log(typeof b);

使用できるNumberの最大値：　
構文：　Number.MAX_VALUE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/6107afc2-b299-8eb1-29b2-52b7c6f7613e.png)

最大値を超える場合は、Infinityが返されます。
InfinityもNumber型です。

NaN：数字ではないです。Not a number。型はNumber型です。

使用できるNumberの最小値：
構文：　Number.MIN_VALUE

JSのなかに整数の計算は基本的に全部正しいです。
小数で計算すると、結果の精度が落ちます。原因としてはコンピュータは２進数計算です。
そのため、JSで精度の高い計算をしないでください。
100日でSQLの達人になる@LeetCode! Day17 <lag(変数,1) over(order by 変数)>

## 613. Shortest Distance in a Line （問題レベル: Easy）要課金
今日の問題はこれ。
x線上の点のどの2点間の距離のうち、最も短い距離を求めるという問題。

最初は一つずらした自己結合を考えていたが、IDなどが無いデータなので行番号を使わないと駄目なのかなぁと考えていた。
そこで自己結合を使わなくて良い解決方法が`lag()`,`lead()`関数
`lag(変数,ずらす行数) over(order by 変数　asc/desc)`でずらした行数分前の値を取得できる。
`lead()`関数は、前ではなくずらした行数分後ろの値を取得できる。`over句`内では、`group by`も使える。

模範解答は、
```
select min(abs(p1.x-p2.x)) as shortest
from point p1, point p2
where p1.x <> p2.x
```
のように、2点の総当りを調べて最も短いものを求める方法であった。

ただ、データ数が増えると下記回答が良いと思う。
```
select min(l.dif) as shortest
from 
(select lag(x,1) over(order by x desc) - x as dif from point) l
```

### おまけ
![スクリーンショット 2022-02-16 18.46.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74883/8aa6b6de-e21b-c03b-b26b-c5cae0d2afeb.png)
そういえば、[LeetCode](https://leetcode.com/)の画面左下にProblemsボタンがあったので押してみたらこのような画面が出てきた。
SQL用の問題70選があった。まずはこちらから仕上げよう！。

* [LeetCode](https://leetcode.com/)の問題は、MS SQL Serverで解いています。
Windows Server 2019 Essential→Standardアップグレードについて

2019 EssentialからStandardにアップグレードの際に少しはまったので備忘録として記載します。

ネット検索したところ、

```bat
dism /online /set-edition:ServerStandard /accepteula /productkey:ProductKey
```

でアップグレードできるとのことだったので、
実行してみましたが、

「指定したプロダクトキーを検証できませんでした。
指定したプロダクトキーが有効であることと、ターゲットエディションに一致していることを確認してください。」

と表示されアップグレードができませんでした。
入力したのはMAKキーであり、正規のキーです。
なぜインストールできないのかとさらに調べていったところ、
それらしき回答が！！
[評価版からボリュームライセンスへの移行](https://social.technet.microsoft.com/Forums/ja-JP/5647e388-fe5d-41d7-abae-fee0b21a9f9b/35413203852925612363124251250812522125171254012512125211245212?forum=windowsserver2019ja)
MAKキーではなく、リテールまたはKMSキーで一度アップグレードしたのちにプロダクトキーの変更を行う必要があるとのこと。
[Key Management Services (KMS) client activation and product keys](https://docs.microsoft.com/en-us/windows-server/get-started/kms-client-activation-keys)
よりWindows Server 2019 StandardのKMSキーを取得、
コマンドのプロダクトキーのところにKMSキーを入力するとアップグレードが開始されました。
アップグレードには多少時間がかかるようなので放置して再起動
[Windows Serverのライセンス認証でコケる時](https://iranatilark.com/archives/2019/12/03-0102.php)
あとは
slmgr /ipk MAKキー
にてMAKキーに変更してあげればアップグレード完了。

※設定からのプロダクトキーの変更ではキー変更できなかったので注意！！
Windowsのサインイン画面に表示される壁紙をコピーするバッチ

Windowsのサインイン画面に表示される壁紙（Spotlight）がキレイなものが多くて気に入ったので、200kB以上の画像があればPictureにコピーするコマンドラインバッチを作ってみた。
clon的な感じで、タスクスケジューラに入れておけば、取りそびれることもない。

適当な名前でSJISのファイルを作成する
例）spotligntGetter.bat

```dosbatch
setlocal
echo OFF

rem =========== 変数宣言箇所 ===============

rem コピーするファイルの最低サイズ(byte)
set LOWER_LIMIT_SIZE=200000
rem コピー先のディレクトリ
set TARGET_PATH=C:\Users\【ユーザ名】\Pictures\spotlignt
rem Spotligntの画像があるディレクトリ
set SPOTLIGNT_DIR=C:\Users\【ユーザ名】\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets

rem =========== 変数宣言終了 ===============

echo Windowsのログイン画面に出る画像の中から%LOWER_LIMIT_SIZE%byte以上のファイルをPicturesに保存するバッチ

rem =========== コピー先ディレクトリが無ければ作る ===============
if not exist %TARGET_PATH% mkdir %TARGET_PATH%	
echo ■保存先は：%TARGET_PATH%

rem =========== コピー対象のファイルがあるディレクトリに移動する ===============
cd %SPOTLIGNT_DIR%
echo ■Spotlightディレクトリは：%SPOTLIGNT_DIR%
echo ---------------------------------------


rem =========== コピー処理開始 ===============
for %%F in ( * ) do (
	if %%~zF GEQ %LOWER_LIMIT_SIZE% (
		if exist %TARGET_PATH%\%%F.png (
			echo %%F is already exists.
		) else (
			echo %%F is copied.
			copy %%F %TARGET_PATH%\%%F.png
		)
	)
)


pause

endlocal

```
初心者でもわかる関数型インターフェース（Function編）

##はじめに
関数型インターフェースのFunctionインタフェースをご存知でしょうか。Functionインターフェースを使用すると処理をキュッとまとめることができます。これによって読みやすいコードにするこどができます。そんなFuncitionインターフェースとおまけにBiFunctionインターフェースについて解説していきます。

##Functionインターフェースとは
引数を１つ受け取ってその引数を使った処理返す関数型インターフェースです。例えば、引数の５を受け取ったとしましょう。その５に１を足す処理を返すというイメージです。Functionは抽象メソッドであるapplyメソッドを持っています。では、サンプルコードを通して具体的に説明していきます。

:::note info
Functionはジェネリックスの型を２つ受け取ります。
具体的には1つ目の型はappyメソッドの引数の型、２つ目はapplyメソッドの戻り値の型として受け取ります。
:::

##どうやって使うの?
以下のサンプルコードは引数に半径を受け取り、その引数を利用して円の面積を求める処理をしています。Functionは型のパラメータを２つ受け取っています。１つ目は半径（引数）の型を受け取り。２つ目は戻り値の型を受け取っています。最後にapplyメソッドを使って、円の面積を求める処理を呼び出しいます。

```Sample.java
import java.util.function.Function;

public class Sample {
	public static void main(String[] args) {
		Function <Integer, Double> circle= x -> x * x * 3.14;
		System.out.println(circle.apply(8));
	}
}
```

##もっと複雑な処理をするには？
複数の引数を使って処理をすれば、もっと複雑な処理を実装できますよね？この時に使用するのが__BiFunction__インターフェースです。２つの引数を受け取り、その引数を引数を使った処理を返す関数型インターフェースです。

##どのように使うの？
Functionとは違い、Bifunctionは３つの型を受け取ります。１つ目は第一引数の型、２つ目は第二引数の型３つ目は戻り値の型です。下記のコードは第一引数に体重を受け取り、第２引数は身長（m）を受け取って、その引数を使ってbmiを求める処理を変数bmiに格納しています。最後にapplyメソッドを使って、その処理を呼び出しています。

```Bmi.java
import java.util.function.BiFunction;

public class Bmi {
	public static void main(String[] args) {
		BiFunction <Integer,Double, Double> bmi= (x,y) -> x /Math.pow(y,2);
		System.out.println(bmi.apply(58,1.7));
	}
}
```
##まとめ
Functionは引数を１つ受け取ってその引数を使った処理を返す
BiFunctionは引数を２つ受け取ってその引数を使った処理の返す

##参考文献
https://se-tomo.com/2019/10/22/%E3%80%90java%E3%80%91%E3%83%A9%E3%83%A0%E3%83%80%E5%BC%8F%E3%81%A8%E9%96%A2%E6%95%B0%E5%9E%8B%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9/
HaskellのインストールからHello World (Windows環境)

## はじめに
圏論学習の一環として関数型言語に触れてみたいと思いHaskellを触ってみることにしました。


## 参考にさせていただいた記事
https://mebee.info/2020/05/23/post-9218/


## インストールからHello Worldまで

### permission denied (アクセスが拒否されました。)
手順通りにインストーラを実行していくと、stack setupでエラー発生。  

こちらを参考にさせていただき解決。
https://haskell.jp/blog/posts/2017/windows-gotchas.html
→ stack setupを再試行してみると、3回目で正常終了しました。今回はこの方法で解決できました。色々な原因があるようです。

```dosbatch
Microsoft Windows [Version 10.0.19042.1415]
(c) Microsoft Corporation. All rights reserved.

> stack setup
～ 省略 ～
Extracting ghc-8.10.7.tar...
Extracted total of 10342 files from ghc-8.10.7.tar
C:\Users\xxxxxxxx\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7-tmp-34996edfe4ee06a2\ghc-8.10.7: renameDirectory:renamePath:MoveFileEx "\\\\?\\C:\\Users\\xxxxxxxx\\AppData\\Local\\Programs\\stack\\x86_64-windows\\ghc-8.10.7-tmp-34996edfe4ee06a2\\ghc-8.10.7" Just "\\\\?\\C:\\Users\\xxxxxxxx\\AppData\\Local\\Programs\\stack\\x86_64-windows\\ghc-8.10.7": permission denied (アクセスが拒否されました。)
```

### Hello World
手順通りサンプルプログラムを作成

```haskell
module Main where

import Lib

main :: IO ()
main = print "Hello World"
```

実行すると以下のエラーが出てしまいました。

```dosbatch
 >stack runghc app/Main.hs

app\Main.hs:3:1: error:
    Ambiguous module name ‘Lib’:
      it was found in multiple packages: libiserv-8.10.7 testapp-0.1.0.0
  |
3 | import Lib
  | ^^^^^^^^^^
```

"import Lib"の行を削除して再試行すると無事実行できました。

```dosbatch
> runghc app/Main.hs

"Hello World"
```

### 原因の調査
この辺りの記事を参考にさせていただき、理解を深めていきたいと思います。

https://qiita.com/kyotsuya/items/a7015ae5ad413288d8fe
APIを使ってエラーになった時の原因記録

基本的な原因は、「無知」。でも記録しないと忘れるのでメモしていきます。


# Qiita

## 事象 : CURLで&(アンパサンド)を使って複数の引数を送ったら、引数の条件に合わないレスポンスが返ってきた
- 環境
    - Windows 10 Pro バージョン32H1
    - curl 7.81.0 (x86_64-w64-mingw32)

直近の自分の記事を1件取得・・・するはずが・・・自分以外の記事が返ってきた。

```bash
$ curl -H 'Authorization: Bearer {トークン}' https://qiita.com/api/v2/items?page=1&per_page=1&query=user:ponsuke0531
[1] 1405
[2] 1406
[2]+  Done                    per_page=1

$ [{"rendered_body":...省略..., id":"syutorum001","items_count":4,"linkedin_id":"",...省略...
```

### 原因 : &はシェルの制御に使うわれるので、引数に&がある場所で引数の解釈が終わっているから
1. 参考
    1. [curlでGETリクエスト送る時の注意点 - Smoky God Express](https://hkdnet.hatenablog.com/entry/2015/09/19/133415)
    1. [cURLコマンドで「クエリ文字列が在るURL」を扱うときはURLを囲もう、という話 | DevelopersIO](https://dev.classmethod.jp/articles/curl-command-url-tips/)

```bash
# 以下を送ったのと同じことになっている
$ curl -H 'Authorization: Bearer {トークン}' https://qiita.com/api/v2/items?page=1
# 以下の出力が「バックグラウンドで実行したよ」ということなんだろうな・・・・
[2]+  Done                    per_page=1
```

#### 対応 : ダブルクォーテーションで囲むか、&をエスケープする
「ダブルクォーテーションで囲む」の対応にしておくとMacなどで[zsh: no matches found:](https://qiita.com/ponsuke0531/items/8dd9ba566a13edc03fe2)になるのを防止する効果もあります。

```bash
# ダブルクォーテーションで囲む
$ curl -H 'Authorization: Bearer {トークン}' "https://qiita.com/api/v2/items?page=1&per_page=1&query=user:ponsuke0531"
[{"rendered_body":...省略...,"id":"ponsuke0531","items_count":475,"linkedin_id":"",...省略...

# &をエスケープする
$ curl -H 'Authorization: Bearer {トークン}' https://qiita.com/api/v2/items?page=1\&per_page=1\&query=user:ponsuke0531
[{"rendered_body":...省略...,"id":"ponsuke0531","items_count":475,"linkedin_id":"",...省略...
```


# Backlog

## 事象 : "message":"","code":1,"moreInfo":""
- 使ったAPI : [課題コメントの追加 | Backlog Developer API | Nulab](https://developer.nulab.com/ja/docs/backlog/api/2/add-comment/#)
- 事象 : GASでBacklogの課題にコメント追加で添付ファイルのIDをつけたらエラー

```log
Exception: Request failed for https://xx.backlog.com returned code 400. Truncated server response: {"errors":[{"message":"","code":1,"moreInfo":""}]} (use muteHttpExceptions option to examine full response)
```

```js
for (let i = 0; i < attachments.length; i++) {
  // Backlogに添付ファイルを送信して発行されたIDをペーロードに追加する.
  payload['attachmentId[' + i + ']'] = post_attachment(attachments[i]);
}
/** @type {string} 課題コメントの追加のAPIのエンドポイント. */
let endpoint = backlog_url + '/api/v2/issues/' + issueKey + '/comments?apiKey=' + backlog_apikey;
let params = {
  method : 'POST',
  payload : payload
};
// 課題コメントの追加で添付ファイルを課題に添付する.
UrlFetchApp.fetch(endpoint, params);
```

### 原因 : フリープランでは課題に添付ファイルは1つしかできないから
送信先のBacklogはフリープランだった・・・。
そして、対象の課題には既に添付ファイルがあった。
ブラウザで課題にファイルを添付しようとするとちゃんとメッセージが表示された。
djangoアプリをAWSでデプロイする時にハマったこと

djangoアプリをAWSでデプロイする時にハマったことを個人用にメモ。

## 参考
https://qiita.com/Bashi50/items/d5bc47eeb9668304aaa2
https://qiita.com/Bashi50/items/db0b6b3343d51e0fc598
https://zenn.dev/ryo_t/articles/71e4ee16d76274



## gunicornを起動してもソケットファイルが作成されなかった。
 原因⓵：ソケットファイルを作成するフォルダに書き込み権限を付与していなかった。
 原因⓶：「gunicorn.service」ファイルに誤字があった。
 原因③：wsgiファイルがあるアプリフォルダ名とプロジェクトフォルダ名を違う名称にしていたため、wsgiファイルパスが間違っていた。
 原因④：「Procfile」ファイルを配置していた。


## Postリクエストする時に403エラーが発生する。
 原因：自分のブラウザ設定でcookieをブロックしていた。



## EC2インスタンスを切り替えた後に必要な作業
 ・djangoのsetting.pyの「ALLOWD_HOST」のIPアドレスをパブリックIPアドレスに変更。
　　　　sudo vim /etc/nginx/sites-available/MyToDo_python
　・nginxのIPアドレスをパブリックIPアドレスに変更。
　　　　sudo vim /etc/nginx/sites-available/MyToDo_python
　・nginxとgunicornサービスの再起動
　　　　sudo systemctl restart gunicorn
　　　　sudo systemctl restart nginx
　・ブラウザのキャッシュクリアを行う。
javascript50_オブジェクト変数とユーザー定義関数

下記の書き方もオブジェクトを生成することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/67d2ee56-88c3-704a-1f85-84321e60eb91.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/b89bf95c-3b50-5d3a-4e40-a8fe0e4ac19e.png)

また、{}のなかに直接対象オブジェクトの属性を指定することができる。
属性と値の間に：を書く、属性と属性の間に,を入れる
```ruby
// 従来の書き方
var obj = new Object();
// 現在オブジェクト生成するときに使用する主流の書き方
var obj = {
    name: "田中さん",
    age:40,
    gender: "男"
};

// 辞書を取り出す
console.log(Object.values(obj));

// 値を順番に取り出す
for(value of Object.values(obj)){
    console.log(value);
}
```

ユーザー定義関数
例：郵便番号数を確認するユーザー定義関数
```ruby

const postCode = '123-45678';

function checkPostCode(string){
    const replaced = string.replace('-','');
    const length = replaced.length;

    if(length === 7){
        return true;
    }
        return false;
}

console.log(checkPostCode(postCode));
```

変数の命名については、JSは大文字と小文字を区別するため、camelCaseを多用しています。
HTML,CSSは大文字と小文字を区別しないため、snake_caseを使います。

**オブジェクトの中に値や関数を組み込み**
オブジェクトの中の値を使う場合は、thisをつける必要があります。
```ruby
const post = {
    postCode : '123-45678',
    checkPostCode(){
        const replaced = this.postCode.replace("-","");
        const length = replaced.length;
       //このように書くこともできる　const replaced = this.postCode.replace("-","").length;
　
        if(length==7){
            return true;
        }
            return false;
    }
};

console.log(post.checkPostCode());
```

メソッドチェーンについても簡単に例を書きます。
```ruby

const person = {
    name:'本田',
    age: 30,

    getName(){
        console.log(this.name);
        return this;
    },
    getAge(){
        console.log(this.age);
        return this;
    }
};

// メソッドチェーン
// １行で二つのメソッドを実行することができる
person.getName().getAge();
```
javascript49_基本データ型と引用データ型の違い

基本データ型
String Number Boolean Null undefined
例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/d7b332be-641b-affd-7b93-9fc3fbab52a5.png)

引用データ型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/8298dd43-fbac-c12f-1be8-13e38a6573ff.png)
obj.nameとobj1.nameが同時変わることが確認できました。

JSの中の変数は全部栈内存の中に保存される。
基本データ型の値は全部栈内存の中で保存する。
変数間の値と値は独立している。他の値に影響しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/23b6b98d-ea28-9af1-252c-7e1b85034c35.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/f7554695-9dab-8c93-6832-65ca267b205a.png)
注意：栈内存において変数の値が格納されているのではなく、変数の値が保存された場所が格納されいている。
obj.nameとobj2.nameは0x123を指向している。同じオブジェクトを指しています。
var obj = new object();
obj.name = "tanaka";
var obj2 = obj;
obj2.name = "tanaka";

下記のように変更します。
obj2 = null;
console.log(obj2);
console.log(obj);
obj2は変更しても、堆内存の値に影響しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/3bbcc3a4-7f50-dc1b-b286-bf8f0b3e36af.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067004/c8871928-d4c1-5146-36b3-cb4801d859df.png)

ルール：
二つの基本データ型を比較する時は値の比較になります。
二つの引用データ型を比較する時に、オブジェクトの保存場所を比較する。
二つのオブジェクトが同じでも、保存場所が違ったら、等しくになりません。
【Rails】has_manyにデフォルトでorderを設定する

## 実装方法

UserモデルにPostモデルが紐づくとします。
並び替えは作成日時の降順（新しい順）です。

```ruby
class User
  has_many :posts, -> { order(created_at: :desc) }, dependent: :destroy
end
```

注意いただきたいのは、`dependent: :destroy`はorderの後ろに書くということです。
先週の1週間を取得

#先週
        $last_sunday = date("Y-m-d",strtotime("last Sunday"));
        $last_week_cast_ranking_list = RankingCastDaily::getRankingListByCondition([
            'area_id' => $area,
            'not_price_0' => 'true',
            'start_date' =>  date("Y-m-d",strtotime("-6 day" .$last_sunday)),
            'end_date' => date("Y-m-d",strtotime("last Sunday")),
        ]);
都道府県検索　JS＋PHP　セレクトボタン選択でJSを発火して検索

php

                   <form action="/" method="GET">
                        <input type="hidden" name="is_area" value="1" />
                        <select id="change_js" name="area_id" style="background: #0abab5;padding:10px;color:white;text-align:center;">
                            <option style="text-align:center;" value="">全国</option>
                            @foreach($prefecture_list as $prefecture)
                                <option value="{{ $prefecture->id }}" @if($area == $prefecture->id) selected @endif>{{$prefecture->prefecture_name}}</option>
                            @endforeach
                        </select>
                        <button id="btn-upload" type="submit" ></button>
                    </form>

js

    $(document).ready(function(){
        const selected = document.getElementById("change_js");
            selected.onchange = function() {
            document.getElementById('btn-upload').click();
        };
        let is_area = '{{ $area == "" ? "0" : "1" }}';
        if (is_area == '1'){
            document.getElementById("area_search").click();
        }
}
2022/2/17主にITとかセキュリティの記事

不正端末利用を防ぐ「eSIM」を開発 - NTTコムとトレンド
https://www.security-next.com/134198

申込フォームでセミナー参加者の個人情報が流出 - 愛知県
https://www.security-next.com/134135

「Apache Gobblin」に深刻な脆弱性 - アップデートが公開
https://www.security-next.com/134188

「VMware ESXi」などに複数脆弱性 - 組み合わさると深刻な影響
https://www.security-next.com/134166

EC基盤「Adobe Commerce」「Magento」にゼロデイ脆弱性 - 早急に対応を
https://www.security-next.com/134168

街づくり地域セミナー参加申込者情報が閲覧可能に、委託先の一社代表理事 報酬3ヶ月辞退(2/15)
https://s.netsecurity.ne.jp/article/2022/02/15/47136.html

FBI、ランサムウェアグループ「BlackByte」による被害に関する情報公開(2/15)
https://news.mynavi.jp/techplus/article/20220215-2272740/

正しく恐れて正しく運用。WordPressの脆弱性とアップデートのキホンを理解する(2/15)
https://ascii.jp/elem/000/004/083/4083240/?rss

ビジュアル解説　AndroidスマホのChrome、操作快適に(2/15)
https://style.nikkei.com/article/DGXZQOLM093LR009022022000000

.NETが誕生から20周年 ～公式サイトは特別仕様に、デジタルお土産や楽しいサービスも(2/15)
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1388523.html

ランサムウェア被害が急増、二重脅迫は85％--警察庁資料で判明(2/14)
https://japan.zdnet.com/article/35183468/

ランサムウェア攻撃対応・東京2020大会の対策から学ぶ(3/18開催)
https://www.jcci.or.jp/it/2022/0215172008.html

みんな意外と使ってない？「メールを非公開」の使い方。iCloiud+で捨てアドを簡単作成(2/14)
https://www.danshihack.com/2022/02/14/junp/hide-my-email.html

iCloud利用規約の新たなバグがMacで報告、何度同意してもスクリーンが表示(2/14)
https://iphone-mania.jp/news-437885/

Discordでフレンドから「ゲームを開発したのでプレイして欲しい」と「exeファイル」を送り、乗っ取られる事例が多数のユーザーから報告(2/14)
https://news.denfaminicogamer.jp/news/220214q

日経電子版オンラインセミナー
DX推進で複雑化するセキュリティー対策
～経営視点からみた安全性と利便性の両立方法～(3/17開催)
https://events.nikkei.co.jp/46170/

CIAのプログラムが米市民の情報を大量収集か--米議員が透明性求める(2/15)
https://japan.cnet.com/article/35183526/

「SNS企業はコンテンツを自ら取り締まるべき」との意見が多数--米調査(2/15)
https://japan.cnet.com/article/35183520/

もうひとつのウクライナ危機　ロシアのデジタル影響工作(2/14)
https://www.newsweekjapan.jp/ichida/2022/02/post-34.php

「Windows 10 バージョン 20H2」のサービス終了まであと3カ月 ～Microsoftが注意喚起
企業向けエディションなどで残る「バージョン 1909」も終了。後継バージョンへの移行を(2/14)
https://forest.watch.impress.co.jp/docs/news/1388040.html

電子ウイルス、２７０万件超確認(2/15)
https://www.minyu-net.com/newspack/KD2022021501000335.php

Identity マスターへの道 第七回 ：「大解剖！Azure Active Directory」(2/15)
https://japan.zdnet.com/pickup/ms_identity_202008/35182975/

ノーコード／ローコード開発の本番到来、7割が導入に前向きの必然(2/15)
https://active.nikkeibp.co.jp/atcl/act/19/00351/012400002/

イギリス税務当局、詐欺事件調査でNFTを押収(2/14)
https://crypto-times.jp/uk-seizes-nft/

リモートワーカーの67%、オンラインセキュリティやプライバシーに懸念---エフセキュア調査(2/15)
https://japan.zdnet.com/article/35183481/

ソフトバンクがPPAP拒否、暗号化添付ファイルは全て削除(2/16)
https://xtech.nikkei.com/atcl/nxt/news/18/12243/

郵送された「USBメモリー」に罠　PCに挿すだけでマルウエア感染(2/16)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100113/020300075/

ローコードでシステム内製の流れ　社内のガバナンスは大丈夫か(2/16)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100112/020200033/

携帯大手3社が楽天に集中砲火　ドコモは「基本料0円」にかみつく(2/16)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100110/020700072/
Googleスプレッドシートのここがすごい5選

スプレッドシートを使用初めて3年。スプレッドシートまじ優秀なんでもっと広がることを切に願い記事を書きました<(_ _)>
※この記事でのエクセルはローカルバージョンのエクセルを指します。

:::note war
全くスプレッドシートを聞いたことも見たこともない方は一旦、Excelのクラウドバージョンのように考えて読み進めてみてください。※Excel365がありややこしいですが<(_ _)>
:::

#目次
[クラウド](#クラウド)
[無料で使える](#無料で使える)
[覚えたら無双できる関数がある](#覚えたら無双できる関数がある)
[GoogleWorkSpace内の別サービスと連携](#googleworkspace内の別サービスと連携)
[GoogleAppScript（GAS）](#googleappscriptgas)
[まずは使ってみてください](#なにはともあれまずは使ってみてください)


##クラウド
まぁなんといってもまずはこれでしょう。最近はエクセルファイルをメールで添付して送られた日にはもはや返信しないレベルまで来ているのですが、今時ローカルエクセルファイルて。
PCにダウンロードして、編集上書きして、メールで添付して送信。。。めんどくさすぎる罰ゲームでしょこんなもん。
それに比べてクラウドだとURL共有。終わり。ついでに編集状態がリアルタイム。色々下にだらだら書いてますが、これだけでローカルバージョンのエクセル使用する意味がゼロ。

##無料で使える
無料ってすてき。投稿日時点ではGoogleはまだ無料で使わさしてくれてます。※Googleアカウント必要

##エクセル機能を網羅した表計算ツール
エクセルのように縦横の方眼紙になっており、Book、Sheet、Cell、関数などのエクセル基本概念はほぼほぼ同じ。
Sheetの増減、Cellの色付け、条件付き書式、フィルター、画像の挿入、グラフの作成、表計算などなど。エクセルでお馴染みのことが苦労することなくスプレッドシートでも可能です。

特に、エクセルだと組み込みの関数（sumとかvlookupとか）を使用することが多いと思いますが、使用頻度の高い関数については関数名、仕様（引数、return）が一緒です。ですのでエクセルユーザーはスプレッドシートをいきなり使用しても困ることはありません。まぁ多少のUIの配置は覚えなければなりませんが、こんなもの問題ではありません。

##覚えたら無双できる関数がある
下の関数を全て自由自在に使用することができたら会社内、いや地域内では無双できます。

| 関数名 | 仕様 |
|:-:|:-:|
| Query | SQL言語に近い書き方でデータの抽出条件などの指定が可能。<br>例：=QUERY(A1:D25, "SELECT * WHERE D IS NOT NULL")<br>A1からD25セルのデータでD列にデータが入っているもののみ抽出  |
|  ImportRange | 別スプレッドシートのデータを参照することができる。<br>例：=IMPORTRANGE("スプレッドシートID","シート1!A1")<br>[スプレッドシートID](https://blog-and-destroy.com/33158)のスプレッドシート、シート1のA1セルを参照|
| ArrayFormula  |  配列関数と合わせることで配列を返すことができる。<br>例：=ARRAYFORMULA(ROW(A1:A1000))<br>A1セルに書くとA1セルに1からA1000セルに1000まで連番ができる。 |
| Regex系  |  正規表現が可能。REGEXMATCH, REGEXEXTRACT, REGEXREPLACEの3種類<br>例：=REGEXREPLACE(A1, "[都道府県]$",)<br>A1セル東京都 → 東京<br>A1セル北海道 → 北海<br>A1セル大阪府 → 大阪<br>A1セル沖縄県 → 沖縄 |

この中でも特にQueryはやばい。先に断りを入れておくと難易度はまぁまぁ高い。ですが、この関数だけでデータの多岐にわたる条件分けが可能。


##GoogleWorkSpace内の別サービスと連携
これは中級以上となるかもしれませんが、GoogleWorkSpace内別サービスとの連携が可能。
例えばよく使用される連携の代表はGoogleForm。GoogleFormの回答結果をスプレッドシートに転記。もちろんクラウドなんでGoogleFormの回答結果を一度PCにダウンロードしてなんていうことは必要なし。回答後リアルタイムで指定のスプレッドシートに反映させることができます。
他にもスプレッドシート内のデータをスプレッドシートからGmail送信（私はよく使用します）なども可能。

>[Google Workspace とは](https://www.g-workspace.jp/googleworkspace/)
Google の提供するグループウェアとして利用可能な組織向けオンライン アプリケーション セットです。
高度なセキュリティと 99.9% の稼働率が保証されたクラウド コンピューティング サービスです。


##GoogleAppsScript（GAS）
これも中級者以上になるかもしれませんが、Google Workspace内で使用する独自プログラミング言語GASを使用したスクリプトの作成ができます。
エクセルのVBAマクロを使用したことある方ならイメージしやすいかもしれませんが、何かの自動処理であったりをスクリプトとして作成することができます。
更にGASはJavaScript（プログラミング言語）を基本としているため、JavaScriptを使用している方は学習コストが圧倒的に少なくGASを覚えることができ、JavaScriptを使用したことない方でもGASを覚える = WEBで欠かせないJavaScriptの基本を身に着けることが可能です。
スプレッドシートは組み込み関数から覚えていくと思いますが、このGASもトライされてみることを強くおススメします。使えるようになるとまた一段階世界が変わります。


##バージョン管理が簡単すぎる
エクセルファイルでバージョン管理するとなるとファイル名に_01、_02など複数ファイル作って保存する必要があるかと思います。スプレッドシートではこれが必要ありません。
どういうことか。スプレッドシートは編集の度にバックアップが行われます。イメージとしてはあっ、あの時に戻りたいなと思った編集の時までいつでも戻れることができるのです。また、やっぱり最新バージョンまでなど柔軟に簡単にクリック操作だけで行うことができます。
これにより複数ファイルを補完するなど煩雑なことは行う必要がなくバージョン管理を行うことができます。


##なにはともあれまずは使ってみてください
とまぁ具体例をあまり出していませんがざっとこのような理由で私は脱エクセル、スプレッドシートばかり使用しているところでございますです。
私は神ツールだと思っているのですが、世間では紙ツールだと思っている方も多いようで。。。スプレッドシートを使用したことがあるけどエクセルローカルバージョンに戻っているという方数名になぜエクセルに戻ったか伺ったことがあるのでその理由をご紹介し、華麗にツッコミを入れていきます。ここら辺はまた違う記事で書こうかなと思う。

では。:sunglasses:
CloudWatch Insightsで集計したWAFログをPythonで取得する

# 概要
以下記載の通り、AWS WAFログをCloudWatch Logsに直接ロギングできるようになったので、特定のルールでブロックされたIPアドレスを集計するスクリプトを作成した。
https://aws.amazon.com/jp/about-aws/whats-new/2021/12/awf-waf-cloudwatch-log-s3-bucket/

# WAFログの設定
AWS WAFログをCloudWatch Logsに出力する設定手順は、以下記事が参考になります。
https://dev.classmethod.jp/articles/aws-waf-log-support-s3-and-cloudwatch-logs/#toc-4

# 必要なIAMポリシー
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeQueries",
                "logs:GetQueryResults",
                "logs:StartQuery",
                "logs:StopQuery",
                "logs:PutQueryDefinition",
                "logs:DescribeQueryDefinitions"
            ],
            "Resource": "*"
        }
    ]
}
```

# Pythonスクリプト
※python3系のみ実行可能。

```
import boto3
import time
import datetime
import json
import sys

END_DATE = datetime.datetime.now()
START_DATE = END_DATE - datetime.timedelta(hours=3) # 直近3時間のデータを参照している

END_TIME = int(END_DATE.timestamp())
START_TIME = int(START_DATE.timestamp())

LOG_GROUP_NAME ='aws-waf-logs-xxx' # クエリ実行対象のロググループ名を指定する
WAIT_TIME = 1
QUERY = '''fields  httpRequest.clientIp
| filter terminatingRuleId = "xxx" # 集計対象のWAFルールIDを指定する
| stats count(*) as requestCount by httpRequest.clientIp
| sort requestCount desc
| limit 10'''

client = boto3.client('logs')

def start_query(log_group):
    response = client.start_query(
        logGroupName=log_group,
        startTime=START_TIME,
        endTime=END_TIME,
        queryString=QUERY
    )
    return response['queryId']

def get_query_results(query_id):
    response = client.get_query_results(
        queryId=query_id
    )
    return response

query_id = start_query(LOG_GROUP_NAME)
query_result = get_query_results(query_id)
query_status = query_result['status']

while query_status != 'Complete':
    if query_status == 'Scheduled' or query_status == 'Running':
        time.sleep(WAIT_TIME)
        query_result = get_query_results(query_id)
        query_status = query_result['status']
        continue
    else:
        print(query_result)
        sys.exit(1)

cnt = 1
result_data = {}
result_data["FROM"] = str(START_DATE.strftime('%Y/%m/%d %H:%M:%S')) + "(UTC)"
result_data["TO"] = str(END_DATE.strftime('%Y/%m/%d %H:%M:%S')) + "(UTC)"

for blocked_ips in query_result['results']:
    key = str(cnt) + ") " + blocked_ips[0]['value']
    result_data[key] = blocked_ips[1]['value']
    cnt += 1

result = json.dumps(result_data, sort_keys=True, indent=4)
print(result)
```

# 実行結果
```
{
    "1) 14.9.136.64": "85",
    "2) 54.87.249.144": "18",
    "3) 111.225.148.157": "1",
    "FROM": "2022/02/16 07:05:21(UTC)",
    "TO": "2022/02/16 10:05:21(UTC)"
}
```
# 参考
https://dev.classmethod.jp/articles/how-to-count-cloudwatch-logs-log-events/
https://stackoverflow.com/questions/49706693/parsing-boto3-output-json
NSButtonでアニメーションをつけてGIF画像を表示

## 概要
- 下記のように`NSButton`にアニメーションのGIF画像を表示する。

![image](https://i.imgur.com/uGSSWRT.gif)

## 方針
- [NSButton](https://developer.apple.com/documentation/appkit/nsbutton)が持つプロパティは`NSImageView`ではなく`NSImage`。なので[SDWebImage/SDWebImage Public](https://github.com/SDWebImage/SDWebImage)を使い、`NSButton`に`SDAnimatedImageView`を`addSubView`することで実現する。

## 参考
- [NSButton and Image Animation](https://stackoverflow.com/questions/4864952/nsbutton-and-image-animation)
    - 方針の参考に
- [ikeh\-shared\-library/macOS/NSView\+AutoLayout\.swift](https://github.com/pommdau/ikeh-shared-library/blob/master/macOS/NSView%2BAutoLayout.swift)
    - 使用したAutoLayout用のUtils

```swift
import Cocoa
import SDWebImage

class ViewController: NSViewController {

    @IBOutlet weak var imageButton: NSButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
         
        SDWebImageManager.shared.loadImage(with: URL(fileURLWithPath: "/Users/ikeh/Downloads/ImageSample/giphy.gif"), options: [], progress: nil) { loadedImage, _, _, _, _, _ in
            guard let loadedImage = loadedImage else { return }
            let animatedImageView = SDAnimatedImageView(image: loadedImage)
            animatedImageView.animates = true
            self.imageButton.addSubview(animatedImageView)
            animatedImageView.anchor(top: self.imageButton.topAnchor, left: self.imageButton.leftAnchor, right: self.imageButton.rightAnchor, bottom: self.imageButton.bottomAnchor, paddingTop: 2, paddingLeft: 2, paddingRight: 2, paddingBottom: 2)
        }
    }
    
    @IBAction func imageButtonClicked(_ sender: Any) {
        print("imageButtonClicked")
    }
}
```
deno deployのファイルシステムはどうなっているか

deno deployはDeno版Cloudflare Workersです。つまり、Deno用のコードが動かせるエッジランタイムです。

先日[Static Files on Deno Deploy](https://deno.com/blog/deploy-static-files)という記事がDeno公式から発表され、deno deployでもファイルシステムAPIが使えることが明らかになりました。この記事では、deno deployのファイルシステムがどうなっているか、Deno CLIとの互換性はどれくらいあるのかを検証していきます。

## deno deployのファイルシステム

deno deployでは（おそらく）疑似的にファイルシステムが再現され、**GitHubリポジトリ上のファイルをローカルファイルとして扱うことができます。**

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/d8d979a8-55dc-ba0b-caf6-7d3d35a7e11a.png)
https://deno.com/blog/deploy-static-files

これの何が嬉しいかというと、**既存のDeno CLI向けライブラリの大半がdeno deployでも動作します**。

具体的には、以下のようなAPIがdeno deployとDeno CLIの両方で使えます。

- ファイル読み取り系
  - Deno.open()
  - Deno.readFile()
  - Deno.readTextFile()
  - fetch()
- ファイル情報系
  - Deno.stat()
  - Deno.lstat()
- ディレクトリ読み取り系
  - Deno.readDir()
- カレントディレクトリ
  - Deno.cwd()
  - import.meta.url

https://deno.com/deploy/docs/runtime-api

※Deno.stat()とDeno.lstat()で取得できる情報には制限があります。

:::note warn
サポートされているのは非同期の読み込み系APIのみで、同期API（○○Sync）や書き込みAPI（Deno.writeTextFile）はサポートされていません。
:::

## deno deployのディレクトリ構造

Deno.cwd()やimport.meta.mainの情報から察するに、ディレクトリ構造は以下のようになっています。

```
root/
└ src/ <--ここがカレントディレクトリ
   └ <以下にGitHubリポジトリのディレクトリ構造がそのまま反映される>
```

deno deploy内ではGitHubリポジトリ上のディレクトリ構造がそのまま反映されています。従って、相対パスでファイル読み込みするコードは、ローカルとdeno deployの両方で共通のコードを使用できます。

## GitHubリポジトリ以外の静的ファイルを扱う方法

上の方で、「GitHubリポジトリ上のファイルをローカルファイルとして扱うことができる」と書きました。しかしこれはGitHubリポジトリ連携した場合についての話です。**そもそもGitHubを使っていない場合**や、**SSGのようにビルド時に出力したファイルを静的ファイルとして使いたい場合**は「deployctl」というCLIツールを使う方法があります。

https://github.com/denoland/deployctl

deployctlはdeno deploy用に作られた公式のCLIツールです。ベータリリース初期にはローカル開発ツールという位置づけでしたが、その役割はDeno CLIに譲り、今ではGitHubを経由しないでdeployするためのツールになっています。

Readmeに従ってインストールした後、以下のコマンドを打つと、GitHubを経由せずdeployすることができます。このとき、カレントディレクトリの下にある静的ファイルがまとめてdeployされ、deno deploy上でもローカルと同じように静的ファイルを使うことができるようになります。
※アクセストークンが必要です。詳しくは公式ドキュメント参照

```shell
deployctl deploy --project=hello-world --token=<TOKEN> ./examples/hello.ts
```

また、GitHub Actionsも用意されています。SSGなど、GitHubActionsでビルド・出力した静的ファイルをまとめてdeployできます。
詳しくは https://github.com/denoland/deployctl/tree/main/action を参照してください。

## まとめ

- deno deployでは、GitHubリポジトリ上のファイルをローカルファイルとして扱うことができる
- ファイルシステムAPIは、Deno CLIに実装されているもののうち、一部が使える
- ディレクトリ構造はGitHubリポジトリの構造がそのまま反映される
- deployする方法は主に4種ある
  - playgroundからdeploy（今回の記事では触れていない）
  - GitHub連携からdeploy<br> → GitHubリポジトリ上のファイルを静的ファイルとして扱える
  - CLIからdeployctlを使ってdeploy<br> → ローカルから直接deployできる
  - GitHub Actionsからdeoployctlを使ってdeploy<br> → GitHub Actionsで生成した静的ファイルと一緒にdeployできる

将来的には[Cache API](https://developer.mozilla.org/ja/docs/Web/API/Cache)の導入が検討されていたり、tmpディレクトリへのファイル書き込みを可能にしてはどうかという提案があったりします。
ファイルシステムとは無関係ですが、データベースの提供や定期実行のサポートも検討されているとのことで、Cloudflare workersやGoogle Apps Scriptの上位互換となることが期待できます。
SPFについて調べたよ

# はじめに
最近迷惑メールが増えてきて、SPFについて知る機会があったので送信ドメイン認証技術について調べて備忘録をとることにした
初心者なので、間違っていることが書いてある可能性があることをご容赦いただきたい

# 送信ドメイン認証技術ってなんだろう
- メール送信者情報のドメインが正しいものか検証することができる仕組み
    - 多くの迷惑メールは他のアドレスになりすまして送信されている
- これが普及すれば送信者情報を詐称しているメールの判定が可能になり、判定結果を活用したフィルタリングをすることができる

※イメージ(あくまでもイメージです)
![迷惑メール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/9133f4ad-af9f-c5f6-844a-5d8f2069a5dc.png)

- SPF/SenderIDとDKIM/DomainKeysの2種類がある
    - SPFは送信元のIPアドレスを認証に使う
    - DKIMはメールに電子署名を付与する

さて、詳しく調べてみよう

# 送信ドメイン認証技術

## SPF/Sender ID

※仕組みイメージ図
![SPF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/576831fa-b051-0721-3495-5c8fd8425ec1.png)

① メールサーバーにメールを送ってほしいと依頼を出す
② SMTPで相手にメールを送る
③ 受信サーバが送信者のドメインに対してDNSサーバにSPFレコードを問い合わせて認証を行う
④ 認証結果がDNSサーバから返却され、安全なメールなのか確認ができる

### SPF送信者側が設定
- DNSサーバ上にSPFレコードを公開する
    - レコードの種別はTXT RR, SPF RRを選択する
    - **※ 現時点ではSPFレコードが取り扱えないDNSサーバの実装のされ方をしている場合があるので気を付けよう**
- 記載例

    ||ホスト名|TYPE|TTL|クラス|VALUE|
    |---| ----- | -----| ----- | ----- |-----|
    |(1)|sample.com.|TXT|5分|IN|"v=spf1 -all"|
    |(2)|sample.net.|TXT|5分|IN|"v=spf1 ip4:192.0.2.1 -all"|
    |(3)|sample.jp.|TXT|5分|IN|"v=spf1 ip4:192.0.4.1 ip4:192.0.5.1 -all"|
(1) sample.comをドメイン名として持つアドレス(例：aaa@sample.com)からは一切メールを送りませんという設定
(2) sample.netをドメイン名として持つアドレス(例：aaa@sample.net)からのメールは192.0.2.1のIPアドレスを持つホストからのみ送信しますよという設定
(3) sample.jpをドメイン名として持つアドレス(例：aaa@sample.jp)からのメールは192.0.4.1のIPアドレスまたは192.0.5.1のIPアドレスを持つホストからのみ送信しますよという設定

つまりどういうことか
![FPS_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/0de3d59d-35a9-eadb-9b89-54a482bcf44a.png)

- 認証結果は以下のものがある

|認証結果|意味|
| -- | -- |
|None|SPFレコードが設定されていない|
|Neutral|SPFレコードが"?"として公開されている条件にマッチした|
|Pass|認証処理に成功した|
|Fail|SPFレコードが公開されているが、認証に失敗した|
|SoftFail|SPFレコードが"~"として公開されている条件にマッチした|
|TempError|一時的な障害で認証処理が失敗した|
|PermError|SPFレコードの記述に誤りがあるなどで認証処理に失敗した|

### ちょっと詳しく

**※SPFの課題**

- 転送問題
    - 送信元のIPアドレスを元に認証を行うので、認証時に送信元のホストが本欄の送信元に属していなければ認証は失敗する

**※SenderIDとSPFの違い**

イメージはSPFを真似してマイクロソフト社がSenderIDを作ったよ
SPFとSenderIDは一緒に使うこともできるんだ！

- Sender ID
    - マイクロソフト社が提案したネットワーク方式の送信ドメイン認証
    - SPFの影響を強く受けていて送信側ではSPFで規定されているSPFレコードを利用して認証情報を公開できる
    - spf2.0とも呼ばれる
    - 記載の仕方も少しずつ違うので気を付けよう！
        - SPF2.0
            - `example.org. IN TXT "spf2.0/pra include:example-example.org -all"`
        - SPF1
            - `example.org. IN TXT "v=spf1 include:example-example.org -all"`


## 参考文献

https://salt.iajapan.org/wpmu/anti_spam/admin/tech/explanation/spf/
棒グラフにエラーバーと散布図を重ねる


◯複数群の平均値を示す棒グラフにSDと実数値を重ねて表現したい場合の方法を探しました。

今回は適当に作った以下のデータを使いました。
> ```
> df <- read.table(pipe('pbpaste'),header=T)
> df
   Group Value
1      1    45
2      1    70
3      1    65
4      1    55
5      1    37
6      1    58
7      1    48
8      1    52
9      1    59
10     1    64
11     2    33
12     2    27
13     2    22
14     2    28
15     2    42
16     2    23
17     2    39
18     2    32
19     2    30
20     2    29
21     3    70
22     3    71
23     3    81
24     3    59
25     3    62
26     3    72
27     3    67
28     3    73
29     3    75
30     3    90

群ごとに平均値と標準偏差を計算する。
> ```
> mean <- aggregate(Value~Group,df,mean)
> sd <- aggregate(Value~Group,df,sd)

> library(ggplot2)

棒グラフを作成
> ```
> p1 <- ggplot(df, aes(y=Value, x=factor(Group)), group=factor(Group)) + stat_summary(fun.y="mean", geom="bar",fill="white", color="black", width=0.7)

![Rplot_p1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2404682/87a42973-e7ca-734d-94ee-96daa6aad0b0.jpeg)


エラーバーを追加
> ```
> p2 <- p1 + stat_summary(fun.y="mean",fun.ymin=function(x)mean(x)-sd(x), fun.ymax=function(x)mean(x)+sd(x), geom="errorbar", width=0.2)

![Rplot_p2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2404682/5279ac0d-ff00-ea86-a784-481e1e44b072.jpeg)


散布図を追加
> ```
> p3 <- p2 +geom_jitter(size=2,width=0.25,height=0)

![Rplot_p3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2404682/9e7701b1-495d-58f5-c30c-66d47a682d8b.jpeg)

※縦方向にずれることが発覚したためheight=0を追加（2023/02/15）

審美的パラメーターを修正して終了。
> ```
> p4 <- p3 + theme_classic() + scale_y_continuous(expand=c(0,0),limits=c(0,100)) + theme(axis.title.x=element_text(size=20), axis.text.x=element_text(size=20), axis.title.y=element_text(size=20, family="Helvetica", color="black"), axis.text.y=element_text(size=20, family="Helvetica", color="black"))

![Rplot_p4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2404682/c2790f38-d423-8b3c-9490-beafcc109b31.jpeg)


参考にしたサイト
・棒グラフに散布図を重ねる
https://datator.exblog.jp/27008169/

・審美的パラメーターの修正
https://note.com/eiko_dokusho/n/n92460465f197
Day.jsをいい感じに共通化する

Day.jsは、軽くてMoment.jsと互換が効くのでよくプロジェクトで使っています。
そこで困ってくるのがlocaleやtimezoneの共通化ではないでしょうか？
Day.jsをimportする度に設定するのは、抜け漏れしそうですしね。

僕の場合は以下のようにして、Global設定（共通化）しています。

## React

``` index.tsx
import dayjs from "dayjs";
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import "dayjs/locale/ja";
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Tokyo');
dayjs.locale("ja");
```

## NestJS

``` src/util/dayjs.ts
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Tokyo');
export default dayjs;
```

## まとめ

フロントエンドでは曜日を日本語にしている部分があることと、
バックエンドではUtilで色々設定したものをexportするようにしました。

他のフレームワークでも違う共通化の方法があると思うので、適宜更新していこうと思います:writing_hand:
Pythonを使ってYoutubeのプレイリストを開く

#はじめに
私は、普段から作業をするときに、Youtubeでプレイリストを流しているのだが、毎回その作業をする際に動画が気になったりなど、気が散る原因となっていました。
そこで、この作業を自動化し、自分が画面を見なくてもいいようにしたいなと考えました。

##環境
* Windows 10 Pro (21H1)
* Python 3.9.1
* Google Chrome 98.0.4758.82 (Official Build)

##ソースコード
```python:main.py
#インポート
import webbrowser
import time

#URLを開く
webbrowser.open('https://www.youtube.com/watch?v=2DoRuPI2OxM&list=PLH-ORs6msKSeO54zI7Rfcr0zC50HiKcLp&index=1&t=0')
while True:
  print('Program executed successfully. This window will automatically close.')
#自動終了
  time.sleep(5)
  break
```
コードはたったの7行です！
これによって、プログラムを起動するだけでブラウザを通して、Youtubeの指定したプレイリストを開くようになりました！
また、プログラムのウィンドウも実行後一定時間経過後、自動で閉じられるので、何を操作をしなくて大丈夫です！

##解説
ここからソースコードを簡単に説明していきます。

###インポート

```python:
import webbrowser
import time
```
ここでは、`webbrowser`ライブラリと`time`ライブラリをインポートしています。
これらはどちらも標準ライブラリなので、ダウンロードなどは必要ないです。

`webbrowser`ライブラリはブラウザを開くために利用します。
`time`ライブラリは自動でウィンドウを閉じるために利用します。

###URLを開く

```python:
webbrowser.open('https://www.youtube.com/watch?v=2DoRuPI2OxM&list=PLH-ORs6msKSeO54zI7Rfcr0zC50HiKcLp&index=1&t=0')
while True:
  print('Program executed successfully. This window will automatically close.')
```


ここでは、先程インポートした`webbrowser` ライブラリの`webbrowser.open` 関数を使って、ブラウザに後ろの( )でくくられたURLを開かせています。
また、`while` を用いて、URLが開かれた場合（`True` である場合）に、

*Program executed successfully. This window will automatically close.*

と表示します。

###自動終了
```python:
  time.sleep(5)
  break
```

ここでは、先程インポートした`time` ライブラリの`time.sleep` 関数を使って、( )でくくった秒数経過後に自動でプログラムのウィンドウが閉じます。

#まとめ
今回は、Pythonを使って、Youtubeのプレイリストを開く方法を紹介しました。
今回紹介させていただいたソースコードの`webbbrowser.open` の後ろの( )の中のURLや、`time.sleep` の後ろの秒数などを変更することでカスタマイズすることができます。
今回作ったものに少し工夫をして、ひと手間を加えれば、他にもいろいろなものを作れるかと思います。
この記事が少しでも参考になれば幸いです。

あと、ソースコードに書いてあるプレイリストは公開しているので、ぜひ聴いてみてください。
.NET nanoFrameworkでマイコンプログラミング（LEDとボタン）

.NET nanoFrameWorkのサンプルプログラム2つ目です。
今回はM5ATOM MatrixのボタンとLEDを使ったプログラムです。

#使用するハードウェア
・M5ATOM Matrix

#使用するソフトウェア
・VisualStudio2019
・ファームウェア ESP32_PICO 1.7.4-preview.45

#追加するNuGetパッケージ
・nanoFramework.AtomMatrix 1.0.1-preview43

#プログラム解説
``` C#:Program.cs
using System;
using System.Diagnostics;
using System.Threading;

//追加
using Iot.Device.Button;
using nanoFramework.AtomMatrix;
using System.Drawing;
```
・パッケージの参照設定を3行追加します。
・System.DrawingではLEDの色を設定するためのColorが定義されています。

``` C#:Program.cs
    public class Program
    {
        private static PixelController led;            //LedMatrixオブジェクト

        public static void Main()
        {
            led = AtomMatrix.LedMatrix;
            GpioButton button = AtomMatrix.Button;     //ボタンオブジェクト
            
            //次のようにも記述可能
            //GpioButton button = new(buttonPin: 39);  //MatrixのボタンはG39に接続
            
            //Led消灯
            led.TurnOff();

            //イベントの登録
            button.Press += Button_Press;

            Thread.Sleep(Timeout.Infinite);
        }
```
・MainプロシージャではLedオブジェクト、Buttonオブジェクトの生成とPressイベントの登録を行います。

``` C#:Program.cs
        private static void Button_Press(object sender, EventArgs e)
        {
            Debug.WriteLine("Button Pressed!");

            //LEDの状態を取得
            var color = led.Pixels;                    //LEDの状態はPixelsプロパティで取得

            if (color[12] == Color.Green){             //各LEDは0～24の一次配列で設定できる
                led.TurnOff();                         //12番目のLEDがちょうど真ん中
            }
            else
            {
                led.SetColor(12, Color.Green);
                led.Update();                          //LEDを点灯する際には最後にUpdateメソッドが必要
            }
        }
```
・LEDを全灯にしたい場合はFillColorメソッドを使うと一度に色の設定ができます。ただし相当明るいのでサンプルでは1つだけ点灯しています。
・LEDの番号は左上を0として次の右が1となり、最後右下のLEDが24になります。

以上サンプルプログラムの解説でした。

コード全体は[こちら](https://github.com/linyixian/NF_LedBtn)になります。
【SQL Server】一時テーブル：INTO #一時テーブル名

ユーザーがサーバーに接続している間だけ有効なテーブル
SELECTとFROMの間にINTO #テーブル名で作成

###<font color="LightGreen">一時テーブル作成</font>
```
SELECT 列名
INTO #一時テーブル名
FROM テーブル名
```

###<font color="LightGreen">一時テーブルを使う</font>
```
SELECT 列名
FROM #一時テーブル名
```
GKEのログ収集ツール(Fluent Bit)はlevelをseverityに置き換えてCloud Loggingへ連携してくれる！！

GCP(Google Cloud Platform)のGKE(Google Kubernetes Engine)上で動くアプリにて、標準出力へ「`{"message":"test!","level":"warn"}`」というJSON形式のログを出力すると・・・Cloud Loggingのログエントリーのseverityには、levelで指定した値がコピーされます。つまり「`{"message":"test!","severity":"warn"}`」と出力した時と同じ動作になってくれるのです！！！

# 誰が値をコピーしてくれてるの？

GEK上で出力したログは、`fluentbit-gke`というDaemonSet経由でCloud Loggingへ連携されており、Fluent BitがCloud Loggingへ連携する前に値をコピーしてくれています。

# 具体的にはどんな設定が入っているの？

Fluent Bitの設定は、`fluentbit-gke-config-v{バージョン番号}` というConfigMapに定義されており、severityが指定されていない場合は、levelの値をコピーするという定義がされていました。

```:fluent-bit.confの該当箇所の抜粋
# ...
# level is a common synonym for severity,
# the default field name in libraries such as GoLang's zap.
# populate severity with level, if severity does not exist.
[FILTER]
    Name        modify
    Match       kube_*
    Copy        level severity
# ...
```

# なぜこんなことを調べたのか？

現在参画しているプロジェクトでは、オンプレ環境で動いているアプリのログもCloud Loggingへ連携しているのですが、オンプレから連携されたログについては、Cloud Loggingのseverityが未指定(=デフォルト扱い)になっていて・・・なぜだ〜となって調べてみました。

# オンプレ環境のログどうしよ〜

オンプレのログ収集基盤がどうなっているのか全くわかっていないのですが・・・

* オンプレのログ収集基盤側でGKEと同じように値をコピーしてから連携してもらう
* アプリで出力するログのログレベルの項目をseverityに変える

の２択だと思いますが、アプリ屋としてはログ収集基盤側で対応してくれると嬉しいな〜と思ってますw
WIFI パスワード確認(C#)

#概要
今日は家で使っているWIFIのパスワードを調べるコマンドを作成しました。
普段WiFiパスワードを調べるにはWEBで検索して画面操作でパスワードを確認しまたが、
今回はパソコンからアクセスしたことがあるWIFIのパスワードを表示するコマンドを実行でパスワードが分かるようになります。

#事前準備
①WIFIをアクセスしたことがあるノートパソコンまたはデスクトップPCを用意します。
②対象のパソコンに.net frameworkがインストールする必要がります。
→.net 4.7.2をインストールします。

#ソースコード
次のコードをVisual Studioで作成します。
※コンソールアプリケーションにソリューションを作成します。

~~~bash
using System;
using System.Diagnostics;
using System.IO;

namespace wifi
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Process ps = new Process();
                StreamReader sr;

                ps.StartInfo.FileName = "cmd";
                ps.StartInfo.Arguments = "/A /C netsh wlan show profile|find \":\"";
                ps.StartInfo.RedirectStandardOutput = true;
                ps.StartInfo.UseShellExecute = false;
                ps.StartInfo.CreateNoWindow = true;
                ps.Start();
                ps.WaitForExit();
                sr = ps.StandardOutput;

                while (sr.Peek() > -1)
                {
                    string line = sr.ReadLine().Trim();
                    showProfile(line.Split(':')[1].Trim());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        static void showProfile(string profile)
        {
            Process ps = new Process();
            StreamReader sr;

            ps.StartInfo.FileName = "cmd";
            ps.StartInfo.Arguments = "/A /C netsh wlan show profile \""+ profile+ "\" key=clear|find \"コンテンツ\"";
            ps.StartInfo.RedirectStandardOutput = true;
            ps.StartInfo.UseShellExecute = false;
            ps.StartInfo.CreateNoWindow = true;
            ps.Start();
            ps.WaitForExit();
            sr = ps.StandardOutput;

            while (sr.Peek() > -1)
            {
                string line = sr.ReadLine().Trim();
                Console.WriteLine("ssid="+profile + "\npwd ="+line.Split(':')[1].Trim()+"\n");
            }
        }
    }
}
~~~

#コマンド実行
上記のソースコードをビルドしてコマンドを実行します。
次のように複数のWIFI情報が表示されるのはアクセスしたことがあるWIFI情報です。
※情報はXXXXにしました。各自で実行してみてください。

~~~bash
C:\repos\wifi\wifi\bin\Debug>wifi
ssid=XXXXXX
pwd =XXXXXX

ssid=XXXXXX
pwd =XXXXXX

ssid=XXXXXX
pwd =XXXXXX
~~~

#参照したコマンド
次のコマンド２つを利用して作成しました。
表示された結果を文字列処理から取得し、表示した結果です。

①ユーザプロファイル一覧表示コマンド

~~~bash
C:\repos>netsh wlan show profile|find ":"
インターフェイス Wi-Fi のプロファイル:
    すべてのユーザー プロファイル     : XXXXXX
    すべてのユーザー プロファイル     : XXXXXX
    すべてのユーザー プロファイル     : XXXXXX
~~~

②ユーザプロファイルのパスワード表示コマンド
※日本語で「コンテンツ」になっていますが、OSの表示言語に合わせて修正してください。

~~~bash
C:\repos>netsh wlan show profile "XXXXXX" key=clear|find "コンテンツ"
    主要なコンテンツ       : XXXXXX
~~~

#参照サイト
C# コマンドプロンプトで実行した結果を読み込む
https://www.itlab51.com/?p=4815

#終わりに
次からはWIFIのパスワードを調べるにはこのコマンド利用してみてください。
複雑なコマンドを一つのコマンドでまとめてみましたが、いかがでしょうか。
Texture2Dにドット単位で線を引く

前回のClassLineを応用して
ブレゼンハムのアルゴリズムをUnity用に改変したものです。
全ての線を引いたあと、

Texture2D.Apply();

でテクスチャに反映されます

```c#
    private Color DrawColor = Color.white;
    private void DrawLine(Texture2D tex, ClassLine line)
    {
        Vector2 v = line.v;
        int dx = (int)Mathf.Abs(v.x);
        int dy = (int)Mathf.Abs(v.y);
        int sx = (int)Mathf.Sign(v.x);
        int sy = (int)Mathf.Sign(v.y);

        int px = (int)line.p1.x;
        int py = (int)line.p1.y;

        if (dx > dy)
        {
            int err = -dx;
            for (int i = 0; i < dx; i++)
            {
                tex.SetPixel(px, py, DrawColor);
                px += sx;
                err += 2 * dy;
                if (err >= 0)
                {
                    py += sy;
                    err = -2 * dx;
                }
            }
        }
        else
        {
            int err = -dy;
            for (int i = 0; i < dy; i++)
            {
                tex.SetPixel(px, py, DrawColor);
                py += sy;
                err += 2 * dx;
                if (err >= 0)
                {
                    px += sx;
                    err = -2 * dy;
                }
            }
        }
    }

```
【サーバレス】静的ウェブサイトの問い合わせフォーム送信できる仕組み【AWS】

## 初めに
今回は静的ウェブサイトの問い合わせフォームを実装し、送信ボタンを押すことでメールに転送されます。使ったものは何なのか、どういうものか、どいう原理で実装できたかをメモするという意味で記事を作成しました。具体的なやり方は最後のリンクの記事を参考してください。

## 必要なもの
必要なものは以下になります。

### 1.ウェブサイト
問い合わせフォームがある静的サイト

### 2.Amazon S3
オブジェクトストレージサービスの一種であり、データ容量を気にすることなく保存することができます。静的サイトをこのストレージに入れることで設定を変更すると、サイト公開できます。

### 3.Amazon API Gateway
★API：大雑把に言うとアプリケーションが呼び出せば予期した結果を返されるような仕組みである

Amazon API Gatewayは、規模にかかわらず、簡単にAPIの作成と保護、そして公開、モニタリングが可能なフルマネージドサービスである。REST API、HTTP API、WebSocket APIがありる。

今回はREST APIを使う。REST APIは受け取ったリクエストをバックエンドサービスである、Lambda関数、AWSサービス、Mock、HTTP、VPCリンクに転送できる。

### 4.AWS Lambda
★FaaS：インターネットを通じて、プログラミングで作成した処理を定義・実行するクラウドの利用形態。

★サーバレス：ミドルウェアも、サーバもAWSなどのクラウドサービス提供者が管理するので、それの運用管理が不要になる。

AWS Lambdaは、サーバレスのFaaSであり、以下の特徴を持っている。
①クラウド上にプログラムを定義しておき、インターネットを通じて実行できるサービス  
②サーバやミドルウェアの管理はAWSがしてくれるので、プログラムだけを考えればいいという素晴らしいサービス

### 5.Amazon SES
ユーザー自身のEメールアドレスとドメインを使用して E メールを送受信するための、簡単で費用効率の高い方法を提供するEメールプラットフォームである。ここでまず送り先のメールアドレスを登録する。

## 流れ
1. 静的ウェブサイトをS3に入れる、設定なども変更する。
2. フォーム送信ボタンを押すと、HTML のフォームから Javascript を使用してAPIを呼び出しデータがAPIへ送信される。
3. APIに来たデータをAWS Lambda（Lambda関数）に渡す。
4. Lambda関数によってメールが作成される。
5. 作成したメールは管理者（送り先のメールアドレス）に送られる。

## 参考サイト
具体的な手順は以下のサイトを参考してください。

★方法1
[S3 静的ウェブサイトにサーバーレスなお問い合わせフォームを実装してみた（Amazon SES + AWS Lambda + API Gateway）](https://dev.classmethod.jp/articles/serverless-mailform-s3-website-hosting/)

★方法2
[サーバレスでお問い合わせフォームを実装してみる(1)](https://www.spiceworks.co.jp/blog/?p=13450)
[サーバレスでお問い合わせフォームを実装してみる(2)](https://www.spiceworks.co.jp/blog/?p=13675)
gsutilコマンド一覧

###gsutilコマンド一覧

gcloudに引き続き、GCSで使用するコマンドをまとめます。あくまで備忘録なのであしからず。


- mb：バケット作成
    - 例.gsutil mb -c [ストレージクラス] -l [ロケーション] gs://バケット名
- rb：バケット削除
- defacl：デフォルトオブジェクトACLに対する操作
- acl：ACLに対する操作


ちなみに、
- IAM：バケット単位でのアクセス制御、「だれが」「どのリソースに対して」「どの操作を行うか」
- ACL：バケット内のオブジェクト単位でのアクセス制御