OmniAICreator/Qiita-1.07M huggingface dataset:
Quiztime 8th August 2021: Tor Dark Web Challenge

#概要

皆さん、こんにちは。
ニャンダウです♪

今回は初のダークウェブ関連のOSINT問です。
引き続きOSINT Dojoによる問題です。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">This week&#39;s <a href="https://twitter.com/hashtag/OSINT?src=hash&amp;ref_src=twsrc%5Etfw">#OSINT</a> challenge is Dark Web-related, so get put away your maps and reverse image search tools. See if you can answer the following:<br> <br>What is the Tpr URL of the pictured website?<br>What is wrong with the URL?<br>What ISP is hosting the infrastructure for the Tor URL? <a href="https://t.co/45wTt5Xgu5">pic.twitter.com/45wTt5Xgu5</a></p>&mdash; OSINT Dojo (@OSINTDojo) <a href="https://twitter.com/OSINTDojo/status/1427256640969969670?ref_src=twsrc%5Etfw">August 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

1: 写真のサイトのTprのURLは何ですか？
2: そのURLのどこが悪いのですか？
3: TorのURLのインフラをホストしているISPはどこですか？

#解答

1: 写真をよく見ればわかる。
答えはニューヨークタイムズ「nytimes3xbfgragh[.]onion」

2: 今年2021年7月からTorはversion2からversion3へと変更するよう推奨されているからです。

3: これはわからなかったので、他の回答者のツイートをみたところ、@Sector035によると、DevtoolのX-Served-ByヘッダーにAmazon AWSと判明したそうです。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">#3: First of all, the headers leak some info and there&#39;s an IP address visible, connected to ec2-52-45-30-23.compute-1.amazonaws[.]com<br>You can also spot AWS in the &quot;X-Served-By&quot; header. Here you can see the local datacenters of New York (LGA) and Baltimore (BWI) <a href="https://t.co/z5LjzZ1GPZ">pic.twitter.com/z5LjzZ1GPZ</a></p>&mdash; 𝕊𝕖𝕔𝕥𝕠𝕣𝟘𝟛𝟝 (@Sector035) <a href="https://twitter.com/Sector035/status/1427334930112073732?ref_src=twsrc%5Etfw">August 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

確かに通信内容をみるとサーバーにAmazonS3とありました。
答えは「Amazon AWS」です。




![スクリーンショット 2021-10-17 12.01.54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/c5eaa22e-ab66-c370-ea5e-265a6ebc58ae.jpeg)


#感想

今回は他の参加者の助けがなければ気づきませんでした。
ダークウェブは未知の領域なので引き続き頑張りたいと思います。
初めてのオリジナルアプリ【My内閣】

こんにちは！テックアカデミーのWebアプリコースを受講している駆け出し高校生エンジニアの安田駿介です。

本日、テックアカデミーの受講最終日です。

ギリギリでオリジナルアプリを完成し、合格することができました。

今回は、そのオリジナルアプリを公開していきたいと思います。

なお、このアプリは僕がプログラミングを始めて、一番最初のオリジナルアプリとなっています。

#アプリURLとGitHubのリポジトリ
https://my-naikaku.herokuapp.com

https://github.com/yasshun1229/my-naikaku.git

#内容

アプリ名は「My内閣」です。

My内閣は、自分だけの内閣を作れるというアプリです。

具体的には、ログインして、内閣作成ページに行き、各閣僚の入力フォームに自分が指定したい人の名前を書くことです。

#開発環境
・AWS
・Cloud9
・Ruby 3.0.0
・Rails 6.1.3.1
・Bootstrap

#感想
正直に言うと、このアプリは全て自分で作ったわけではなく、メンターさんから分からないところの助言をもらいながら開発を進めてきました。

つまり、まだ教材の内容を完璧に覚えたわけではないのです。

特に、Railsに関してはまだメンターさんに教えてもらいながらやらないと、できないような状態にあります。

なので、受講が終了しても、教材のRailsの部分をもう一度振り返っていきたいと思っています。

最終的には、メンターさんの助言なしでもコードをスラスラと打てるようになりたいと思っています。

また、今回受講したRuby on Railsだけでなく、他の言語にも挑戦していきたいと思っています。

あと、今回作ったMy内閣も、デザインに関してもイマイチだし、ログイン後のトップページでは他の人のレコードを全て表示させるつもりだったのですが、それもできていません。

なので、プログラミングをもっと深めていき、将来的にはサービスをリリースしていきたいです。
Quiztime 20th September 2021: Identify the location of the Estonian webcam!

#概要

皆さん、こんにちは♪
ニャンダウです！

今回の問題は、OSINT DojoによるエストニアのWebカメラのIPアドレスとISPを特定する問題です。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">This week&#39;s <a href="https://twitter.com/hashtag/OSINT?src=hash&amp;ref_src=twsrc%5Etfw">#OSINT</a> challenge has a few parts to it, see if you can obtain the following information about this image:<br><br>What city is pictured?<br>What IP address is associated with this camera?<br>What is the ISP for that IP address? <a href="https://t.co/fnEsSN3abU">pic.twitter.com/fnEsSN3abU</a></p>&mdash; OSINT Dojo (@OSINTDojo) <a href="https://twitter.com/OSINTDojo/status/1439941520522563591?ref_src=twsrc%5Etfw">September 20, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

1: この絵の都市はどこ？
2: WebカメラのIPアドレスは？
3: IPアドレスのISPは何？

#解答

1: Google Image検索で一発。
答えは「エストニア」

2: Webcamを見つける有名なサイトwindy.comですぐに見つかりました。
[https://www.windy.com/ja/-ウェブカム/エストニア/Harju-maakond/タリン/City-skyline/webcams/1507414270?59.438,24.742,17](https://www.windy.com/ja/-ウェブカム/エストニア/Harju-maakond/タリン/City-skyline/webcams/1507414270?59.438,24.742,17)

しかし、これだけでは分かりませんので、Shodanを使って特定します。
以下はShodanクエリの一覧です。Webcamを参照いたしました。

[https://www.osintme.com/index.php/2021/01/16/ultimate-osint-with-shodan-100-great-shodan-queries/](https://www.osintme.com/index.php/2021/01/16/ultimate-osint-with-shodan-100-great-shodan-queries/)

一日20回くらいしか検索できなかったので数日かかってしまいましたが、以下のクエリで見つかりました。

country:EE city:"Tallinn" has_screenshot:true title:camera

![スクリーンショット 2021-10-06 9.50.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/01043ec2-42e3-1b5b-995d-7f3a3de9cc87.jpeg)

2、3の答えはすぐに分かりました。
2: 「95.129.195.123」
3: 「Elisa Eesti AS」

![スクリーンショット 2021-10-17 21.20.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/09569f75-6ec6-cef5-8353-b76d2b82ca85.jpeg)


#感想

難易度は簡単だと思いますが、Shodanは初めて使ったので数時間かかってしまいました。
いつもShodan使っている人なら数分で終わると思います。
CloudBuildで設定されている環境変数

```
bash-4.2# env
HOSTNAME=xxxxx
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/proc/1
SHLVL=1
HOME=/builder/home
BUILDER_OUTPUT=/builder/outputs
_=/usr/bin/env
OLDPWD=/proc
```
2.7inch e-Paper HatをRaspberry Piで使用する go言語

# はじめに
[e-Paper](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-58WK)を購入したけど使っていなかったので、とりあえず試してみた。
あと、Pythonのプログラムがあるけど、go言語でやりたいので調べたらライブラリがあるのでとりあえずテストしてみた。

# ソースコード

```go:main.go
package main

import (
	"time"

	"github.com/otaviokr/go-epaper-lib"
)

func main() {
	// New EPaperDisplay handler for model 2.7 inches, black-and-white..
	epd, err := epaper.New(epaper.Model2in7bw)
	if err != nil {
		panic(err)
	}

	// Run mandatory initialization.
	epd.Init()

	// Clear screen to avoid undesired meshes.
	epd.ClearScreen()

	// Parse the string and process it with TTF font.
	text := "test"
	fontSize := 10.0
	fontFile := "/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf"
	m := epd.Write(text, fontSize, fontFile)

	// Add the resulting image into the buffer.
	epd.AddLayer(m, 0, 0, false)
	epd.AddLayer(m, 0, 30, true)

	// Print the buffer onto the display..
	epd.PrintDisplay()
	// epd.Display()

	// Just a timeout before clearing the screen.
	time.Sleep(10000 * time.Millisecond)
	epd.ClearScreen()

	// Always put the screen to sleep when it will not be refreshed shortly.
	epd.Sleep()
}

```
# 結果
```
go mod init epaper
go mod tity
go run ./
```
以下図のように表示されることが分かった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425374/f12672ff-dada-2ab8-e9a4-889d3ab83290.png)

これから、改造次第でいろいろと違うこともできそう


# 参考資料

* [go-epaper-lib](https://github.com/otaviokr/go-epaper-lib)
ドメイン引越しに便利！引越しメッセージを一定秒数表示し同パスにリダイレクトさせる簡単なPHPスクリプト作った

![very-simple-redirect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44367/cd81bf02-ae43-b612-f085-90cef84f3bd0.png)


新しいドメインに移行した際、シンプルにリダイレクトさせるのではなく、サイト訪問者にドメインが変更したことを伝えたい場合があります。

これは、ドメイン変更のシンプルなメッセージを指定した秒数で表示しつつ、新ドメインにリダイレクトしてくれるPHPスクリプトです。

加えて、アクセスされているパスを取得し、新ドメインの同じパスでリダイレクトしてくれます。

また、きちんと 301 ステータスコードを出すようにしているので、Google さんも引っ越したことがわかります。

https://github.com/katzueno/simple-php-redirect

※ この記事は GitHub の Readme をそのままコピーしてきました。Version 0.9 のものです。最新は GitHub にあります。

## 必須環境

- Apache サーバー: mod_rewrite モジュールと .htaccess が使えるように設定されている。
    - Apache コンフィグを直接編集するのも可
- Nginx
    - PHP-FPM
    - Nginx の Config を設定できる権限を持っていること

## インストール方法

1. GitHub にある index.php をゲットし、中の新ドメイン・サイト名などの Config 値を設定
2. index.php を古い方のサーバーにアップロードし、それ以外のファイルをルートフォルダから削除
3. Apache Configか .htaccess ファイルは、 Nginx を設定し、すべてのリクエストが index.php を読みにいくように設定
4. 設定完了

## 設定箇所

`$newDomain`: 新ドメインを https:// から入力

`$siteNameEn`: 英語のサイト名

`$siteNameJa`: 日本語のサイト名

`$sec`: リダイレクト開始までの秒数

## Apache .htaccess ファイルの例

.htaccess ファイルを作成し、下記の設定を追加。
サブディレクトリ配下のみに設置するのであれば、`RewriteBase` を変更すること

```apacheconf
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase / # if it's lives under subdirectory, add the directory accordingly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>

```

## Nginx config の例

Nginx サーバーの知識と config 設定方法をご存知の方向けです。

設定には FastCGI の設定が含まれていませんが、他の部分で `~ \.php($|/)` の location 設定を行ったとみなしています。
サブディレクトリ配下に設置したい場合は、`absolute_redirect` をオフにするなど、config の設定を変更する必要があります。

```
location / {
    index index.php index.html index.htm;
    if (!-e $request_filename) {
        rewrite ^ /index.php last;
    }
}
```

以上
【GAS】 スライドをページ毎に画像（PNG, JPG, SVG）として一括出力

現在（2021年10月）のところGoogleスライドで作成したスライドを画像形式でダウンロードする際、
各スライドを1つずつ出力するしかないようなので一括で出力できるGASを作った。

スクリプトはほぼ以下のサイトを参照しているので、オリジナリティはない。
[【GAS】Google Apps Script 活用事例　Google Slidesの全てのスライドをJPGに変換するスクリプト](https://note.com/nepia_infinity/n/n969877a32478)

## 参考サイトからの変更点
* コンテナバインドスクリプトにし、スプレッドシート上でスライドのURLとファイル形式を指定
* スライドが置いてあるフォルダ内にスライド名と同名のフォルダを作成し、そこへ出力した画像を保存

## スクリプト

スプレッドシート込みのファイルは[ここ](https://bit.ly/3vj4c29)からコピーをダウンロード

```javascript
function onOpen() {
 SpreadsheetApp.getUi()
  .createMenu('SlideToImage')
  .addItem('作成', 'createPresentationFile')
  .addToUi();
}

function createPresentationFile() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const url = sheet.getRange(2, 1, 1, 1).getValue();
  const presentation = SlidesApp.openByUrl(url);
  const presentationId = presentation.getId();
  const slides = presentation.getSlides();
  const format = sheet.getRange(3, 2, 1, 1).getValue();
  const folder = DriveApp.getFileById(presentationId).getParents().next().createFolder(presentation.getName());
  let slidesNumber = 1;

  for(const slide of slides){
    const page_id = slide.getObjectId();
    convertPresentation_(presentationId, page_id, format, slidesNumber, folder);
    slidesNumber += 1;
  }
  showDialog_(folder);
}

function convertPresentation_(presentation_id, page_id, format, slidesNumber, folder) {
  let ext = format;
  switch (format) {
   case "png":
   case "svg":
     break;
   case "jpg":
     format = "jpeg";
     ext    = "jpg";
     break;
   default:
     format = "pptx";
     ext    = "pptx"
     break;
 }
  const url = "https://docs.google.com/presentation/d/" + presentation_id + "/export/" + format + "?id=" + presentation_id + "&pageid=" + page_id;
  const options = {
    method: "get",
    headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true
  };
 
  const response = UrlFetchApp.fetch(url, options);
  if (response.getResponseCode() === 200) {
   const presentation = SlidesApp.openById(presentation_id);
   return folder.createFile(response.getBlob()).setName(presentation.getName() + '_' + slidesNumber + '.' + ext);
 }
}

function showDialog_(folder) {
 const ui = SpreadsheetApp.getUi();
 
 const url  = "https://drive.google.com/drive/folders/" + folder.getId(); 
 const html = HtmlService
 .createHtmlOutput(
   `<p><a href=${url} target="_blank">Google Driveのフォルダはこちら</a></p>`
 )
 .setWidth(450)
 .setHeight(100); 
 ui.showModelessDialog(html, '各スライドの画像が作成されました。');
 
}
```
[Dart]non-nullable型ListのfirstWhereで検索対象が不在のときにnullを返却したい

#### 2021.10.20更新
[dart.dev](https://pub.dev/publishers/dart.dev/packages)が公開している[collection](https://pub.dev/packages/collection)パッケージにIterableの拡張メソッドが追加されていたことをコメントでご共有いただいたので、結論に訂正を加えました。
情報をご共有いただいた@Cat_sushiさん、ありがとうございます。

---

- 実行環境  
Android Studio Arctic Fox | 2020.3.1 patch 3  
Flutter version 2.5.1  
Dart version 2.14.2  



Dart2.12（Flutter2.0）でnull-safetyが導入されてから、`List`型の`firstWhere`で条件にヒットする値が存在しない場合に`orElse`から`null`を返却しようとすると、戻り値の型不一致によりanalyzerに怒られるようになってしまいました。

```dart
  final nonNulableList = <String>['a', 'b', 'c', 'd'];
  final result = nonNulableList.firstWhere(
    (elem) => elem == 'e',
    orElse: () => null, // <- 😡
  );
```



```
Error: The value 'null' can't be returned from a function with return type 'String' 
because 'String' is not nullable.
    orElse: () => null,
                  ^
```

現在では[dart.dev](https://pub.dev/publishers/dart.dev/packages)が公開している[collection](https://pub.dev/packages/collection)パッケージに[`firstWhereOrNull()`](https://api.flutter.dev/flutter/package-collection_collection/IterableExtension/firstWhereOrNull.html)という拡張メソッドがあるので、それを使用します。

```yaml:pubspec.yaml
dependencies:
  collection: ^1.15.0
```

```dart
import 'package:collection/collection.dart';

void main() {
  final nonNullableList = ['a', 'b', 'c', 'd'];
  final result = nonNullableList.firstWhereOrNull(
    (elem) => elem == 'e',
  );
  print('result: $result'); // result: null
}
```

---
（以下は古い内容です）

- 実行環境  
[DartPad](https://dartpad.dev/?null_safety=true)  
Based on Flutter 2.5.3 Dart SDK 2.14.4

null-safetyな環境でnon-nullable型`List`の`firstWhere`から`null`を返却するには、
`firstWhere`を実行する前に`List`をnullable型にキャストします。

```dart
  final nonNulableList = <String>['a', 'b', 'c', 'd'];
  final result = nonNulableList.cast<String?>().firstWhere( 
   (elem) => elem == 'e',
    orElse: () => null,
  );
  print('result: $result'); // result: null
 ```
React から利用する API のロギングでロケーション情報を格納する

## はじめに
API ログを取っていますか、便利に使えていますか？

ログにもいろいろありますが、本記事では Backend API での、アクセスごとのリクエスト・レスポンスのログについて焦点を当てます。このログを使うと、それぞれのエンドポイントがどれぐらい使われているのか、レスポンス速度はどうなのか、エラーレートは問題ないかなどを確認することができますね。

今回は、実際にサービスを運用している中で欲しくなって追加した、特に React などを利用した SPA(Single Page Application) の場合に有効な、ロケーション情報の取得について共有します！

## ロケーション情報の取得
SPA では、それぞれのページで必要な API を叩くことになるため、ページと API は一対一に対応しません。
こんな場合に、ブラウザの URL である、ロケーション情報を API のリクエストの中身に含めて、API ログ情報に付与しておくととても便利なデータになります。

具体的には、以下の３項目です。

| パラメータ | 説明 |
| ---  | -- |
| location.search | URL のクエリストリング（例: ?q=キーワードを入力）|
| location.pathname | URL のパス |
| location.hash | URL のハッシュ (例：#ロケーション情報の取得) |
参考：[Location 情報一覧](https://www.w3schools.com/jsreF/obj_location.asp)

これらのデータがあると、例えば以下の調査に役立ちます。

### API でエラーがでたときのユーザの行動文脈把握
リクエストに含められた GET や POST のデータがあれば、関数に渡された値は認識することができますが、ユーザがどういった文脈でその値を含めたリクエストを送ってきたかについては、利用箇所が複数あった場合には、一意に定まらない場合があります。ロケーション情報が入っていると、どの機能を利用していて、どういう表示がなされている際に送られてきたリクエストかが自明となるため、問題解決へのスピードが早くなります。

### あるページAの表示が重いと言われた場合の速度調査
そもそも表示が重い原因にはブラウザやネットワークなども要因になり得ますが、今回はバックエンドについて。

挙動についてブラウザで実際に試してみたり、コードベースで確認することはできますが、実際にユーザがリクエストした際にどのようなレスポンス速度になっているのかを確認できると調査が早いですよね。ロケーション情報があれば、そのページAで使われている API を列挙してログを確認するのではなく、location.pathname がページAであるようなログをフィルタして確認することが可能です。

## サンプルコード
具体的には以下のコードで集めています。

```ts
import axios from 'axios';

export function initializeInterceptor() {
  axios.interceptors.request.use(request => {
    request.headers.common['X-Location-Pathname'] = location.pathname;
    request.headers.common['X-Location-Search'] = location.search;
    request.headers.common['X-Location-Hash'] = location.hash;
    return request;
  });
}
```

## まとめ
ロケーション情報を API のログに入れておくと調査に役立つという、実際にサービスを運用する中で得られた知見を共有させてもらいました。
こういった情報を仕込むと便利だよというのがありましたら、コメントいただけるとありがたいです！
M1MacでKH Coderを起動する

基本的にはここに書いてある通りなのですが、

https://b.okadajp.org/2021/04/17/untitled/

いくつか書いてなくてハマった箇所があるので、記述しておきます。

## 前提となる環境

以下の環境でのお話です。

- macOS Big Sur(11.6)
- MacBook Air (M1, 2020)
- Zsh



## 1. mysql_secure_installation

MySQLインストール後、以下のコマンドを実行します。

```
% mysql_secure_installation
```

が、このコマンドを実行する際はMySQLが起動している必要があります。
ぼくの場合は起動しつつ、OS起動時には起動するよう、サービス登録しておきました。

```
% brew services start mysql
```

## 2. cpanm DBD::mysql のインストールにコケる

こんなエラーメッセージが出ました。

```
% cpanm DBD::mysql
Can't link/include C library 'zstd', 'ssl', 'crypto', aborting.
```

ぼくの場合は、'zstd', 'ssl'はすでにインストールされていました。

```
% which zstd
/opt/homebrew/bin/zstd
```

```
% which openssl
/usr/bin/openssl
```

```
% which crypto
crypto not found
```

cryptoはなかったので、インストールしました。



### 2-1. cryptoをインストール

https://chrissimpkins.github.io/crypto/install.html

先にgpgのインストールが必要です。

```
% brew install gpg
```
続いてpipでcryptoをインストールするのですが、pipが入ってなかったので、以下のページを参考に、pip自体をインストール。

https://qiita.com/ohbashunsuke/items/e7c673db606a6dced8a6

これでやっとcryptoをインストール。

```
% pip install crypto
```

```
% which crypto
/opt/homebrew/bin/crypto
```

### 2-2. 足りないといわれたライブラリの場所を明示しつつ、cpanm DBD::mysqlをインストール

whichコマンドで調べた各ライブラリのパスを指定しながら、インストールを実行しました。

```
% cpanm DBD::mysql --configure-args="--libs='-L/usr/bin/openssl -L/opt/homebrew/bin/zstd -L/opt/homebrew/bin/crypto'"
```

## 3. xquartzのインストール

KH Coderにはこの子も必要です。なければインストールします。

https://www.xquartz.org/releases/XQuartz-2.8.1.html

より、XQuartz-2.8.1.dmgをダウンロードし、インストール。


## 4. ターミナルの文字エンコーディング設定

ターミナルのデフォルトの文字エンコーディングはUTF8で、KH CoderはShift JISで起動する必要があるため、文字エンコーディングをShift JISに変更したプロファイルを用意します。ついでに起動時のパスもKH Coder専用にしておきました。

![Terminal_ShiftJIS_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1417/3582bd46-1abe-98c6-bb59-a838e38bc069.png)

![Terminal_ShiftJIS_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1417/cfef2c8e-5352-ce90-2a7e-11307c9b4d9a.png)

※ぼくはiTerm2を利用しています。


## 5. KH Coder起動時

xwindowを先に起動しておく必要があります。

Shift JIS環境で開いたターミナルのタブで以下を入力します。

```
% startx
```

ターミナルの別なタブをShift JIS環境で開き、KH Coderを起動します。

```
% perl kh_coder.pl
```


## できたー！

![KHCoderMacM1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1417/1c7f299c-107d-6003-d42b-32fc5bf2a73c.png)


3時間ぐらいかかった…
Github ActionでBoostとGoogleTestを使用する


個人的備忘録もかねてメモ

##想定環境
- ubuntu (github actionのdocker image)

# 1. Boostの利用方法

Github action内のdocker imageでは、かつてboostをサポートしていたものの、現在では自分でインストールする必要がある。

https://github.com/actions/virtual-environments/issues/2667

linux/windows/mac osのそれぞれについて書かれているので従えばよい。linux(というよりubuntu)の場合で最も簡単そうなのは、`apt install`経由でインストールするものであり、

```yaml
- name: install boost
- run: |
    sudo apt install -y libboost-all-dev
```
のように、`.github/workflows/`のyamlに記述すればよい。

# 2. GoogleTestの利用方法
利用方法というより、cmake周りでつまづいたことのメモ。

cmake経由でgoogletestをビルドすることができる。方法は[本家ページ](https://google.github.io/googletest/quickstart-cmake.html)に書いてあるように(引用)

```cmake
cmake_minimum_required(VERSION 3.14)
project(my_project)

# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
```
のようにcmakeに記述すればよい。

ただしこのままだと`GTest`のディレクトリが見つからないと言われる(`find_package`で見つからないと言われる)。

https://stackoverflow.com/questions/24295876/cmake-cannot-find-googletest-required-library-in-ubuntu


解決策は、`libgtest-dev`をインストールすることであった。これもyamlに追加する。

```yaml
- name: install googletest
  run: |
    sudo apt install libgtest-dev
```

最後に、様々なところで言及されていることだが、googletestを利用するときは、`pthread`とリンクさせる必要があるので、cmakeに記述する。[ここ](https://qiita.com/kuchida1981/items/9bb8fa4cc04635e7e909)が詳しい。

https://qiita.com/kuchida1981/items/9bb8fa4cc04635e7e909

# 3. 走らせる(追記)
あとは従来のcmakeでのgoogletest実行と同じである。`build`ディレクトリ内でmakeをすることと仮定すると、yamlファイルは次のように書くことができる。

```yaml
- name: build
   run: |  
        mkdir build
        cd build
        cmake ..
        make
        cd ..
```
このあとに実行するコマンドをかけばよい。

```yaml
- name: googletest
   working-directory: ./build
      run: |
        make test
```

これで実行できる。



# 4. 最後に
当たり前のことかもしれないが、`enable_testing()`はプロジェクトルートの`CMakeLists.txt`に書く必要がある。
【Laravel】chart.jsをLaravel-mixを利用して入れたのに"Chart is not defined"と言われた

chart.jsをLaravel-mixを利用して導入したものの、なぜか"Chart is not defined"「Chartなんて関数ねーぞ！」と言われてハマったので、その対処法を書きました。
　＊環境
　Laravel 8.64.0(7.30.4でもできました)
　NPM 6.13.7
　Node.js 13.11.0
# 1.loadBefore.jsを作成
　resources/jsにloadBefore.jsを作成します。中身には以下のコードを追加します。

```loadBefore.js
require('chart.js/dist/chart.js');
```

# 2.webpack.mix.jsに追記
　Laravelプロジェクトの直下にあるwebpack.mix.jsに以下のコードを追加します。

```webpack.mix.js
mix.js('resources/js/loadBefore.js', 'public/js').sourceMaps();
```

# 3.Viewファイルに追記
　Viewファイルに以下のコードを追加します。

```blade.php
<script src="{{asset('js/app.js')}}"></script>
//↓追記
<script src="{{ asset('js/loadBefore.js') }}"></script>
```

# 4.NPMでコンパイル
　NPMでコンパイルします。

`npm run dev`

# 5.リロード
　これで直るはず！
　chart.jsを先に読み込ませないとエラーが出るんでしょうね。


# 参考サイト
[How to install Chart.js in Laravel? ("Uncaught ReferenceError: Chart is not defined")](https://stackoverflow.com/questions/68376221/how-to-install-chart-js-in-laravel-uncaught-referenceerror-chart-is-not-defi)
PythonでDBからデータを可変に取得する

# Jupyter Notebook上(Python)からDBのデータを可変的にデータを取得する

## DBから複数条件を変更しながらデータを取得したい
- テラバイトを超えるようなビッグデータを時系列（月次、日次）で分割してダウンロードしたい
- マスターデータに合致する対象の顧客データだけを抽出したい
- 条件が異なるデータ抽出を自動で（一括して）実行したい

Pythonでデータベースにアクセスしデータを抽出するライブラリにはpsycopg2、pydb、presto-python-clientなどがあります。
【参考】
https://qiita.com/ko-da-k/items/aa26f986a09b3b629e2a
https://qiita.com/yolo_kiyoshi/items/0c3c7f7cc5794d1afaec


どのライブラリも「**数字**」や「**文字列**」といった変数を指定することができますが``` WHERE order_code LIKE IN ('aaa%', 'bbb%', 'ccc%') ```のように「**タプル()**」を上手く渡せますでしょうか。
また、変数の指定方法もライブラリごとに異なり、``` %s ```や``` '{variable}' ```のようにクエリ内での表記方法は様々です。

## f-stringを利用する
使用するライブラリの違いによる制限をなるべく受けることなく上記の問題に対応するには**f-string**を用いた実装が有効です。

```
import psycopg2
import pandas as pd

def get_query(HOGEHOGE:str, AMPM:str, TIME:str) -> str:
# 変数は{}で指定
    query = f"""
        select *
        from DATABASE
        where order_code like in {HOGEHOGE}
        and business_day = {AMPM}
        and TIME = {TIME}
    """
    return query

# 変数の指定
HOGEHOGE = ('aaa%', 'bbb%', 'ccc%')
# 期間の指定 
TERM = [['AM', 1],
        ['AM', 2],
        ['PM', 1],
        ['PM', 2]]

# データ取得 
# connectionについては【参考】等、他記事を参照
for t in TERM:
    data = pd.read_sql(get_query(HOGEHOGE, t[0], t[1]), con = connection)
    data.to_csv(f'{hogefuga}_{t[0]}_{t[1]}.csv')
```

以上のように、f-stringを用いてクエリそのものを書き換えてから引数に与えればタプルでも文字列でも渡すことができます。
**データ基盤を自由に使えず、複数の更新されるデータ**を取得する必要がある際にはとても強力でしょう。

# 実行結果
上記コードで実際に引数として渡しているクエリは下記の通りです。

        select *
        from DATABASE
        where order_code like in ('aaa%', 'bbb%', 'ccc%')
        and business_day = AM
        and TIME = 1
    

        select *
        from DATABASE
        where order_code like in ('aaa%', 'bbb%', 'ccc%')
        and business_day = AM
        and TIME = 2
    

        select *
        from DATABASE
        where order_code like in ('aaa%', 'bbb%', 'ccc%')
        and business_day = PM
        and TIME = 1
    

        select *
        from DATABASE
        where order_code like in ('aaa%', 'bbb%', 'ccc%')
        and business_day = PM
        and TIME = 2
ログイン時の小技(IPアドレス)

# ログイン IP アドレスの制限
## 問題点
複数人で同ユーザを使用する場合、ログインの度にメール認証が飛ぶ。
※テスト開発時を想定

### 解決策
[設定]/[(対象の)プロファイル]/[ログイン IP アドレスの制限]/[新規]
下記の通りに入力。

開始IPアドレス：0.0.0.0
終了IPアドレス：255.255.255.255

![スクリーンショット 2021-10-17 19.26.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584398/3b8dc8aa-080f-0657-da0d-361faa913776.png)


※セキュリティのため、本番稼働の際は必ず元に戻してください。
Pythonで個人的によくわすれるやつ

## 関数引数について
pythonにおいて関数引き数は参照型であるため引数で渡した値が対象の関数内で書き換わること期待したが、
pythonの基本型はimmutableであり、関数の呼び出し前後でオブジェクトが変わっており、期待する振る舞いではなかった。
下記例において、add関数内で変数cntが再度生成されたというように考えるべきであり、引数のcntは単純な読み取り専用となっている。
品質的にはそれが好ましいと感じている。



```python
def add(cnt:int) -> int:
    print('--------------------------------')
    print('cntのid 加算前 = {0}'.format(id(cnt)))
    cnt = cnt  + 1
    print('cntのid 加算後 = {0}'.format(id(cnt)))
    return cnt

counter : int = 0
print('--------------------------------')
print('関数呼び出し前')
print('counter = {0}'.format(counter))
# add関数の呼び出し
ret = add(counter) 
print('--------------------------------')
print('関数呼び出し後')
print('counter = {0}'.format(counter))
print('ret = {0}'.format(ret))




```

    --------------------------------
    関数呼び出し前
    counter = 0
    --------------------------------
    cntのid 加算前 = 2572282626256
    cntのid 加算後 = 2572282626288
    --------------------------------
    関数呼び出し後
    counter = 0
    ret = 1
    

## リスト、タプル、辞書、セット
忘れるので...


```python
# リスト
data = ['a','b','c','d']
print('-----------------------------------------------')
print('List')
print("dataのtype = {0}".format(type(data)))
# 追加可能(最もシンプルな1例)
data.append('e')

# タプル
data = ('a','b','c','d')
print('-----------------------------------------------')
print('Tuple')
print("dataのtype = {0}".format(type(data)))
# 追加不可
# data.append('e')

# 辞書
data = {'a': 0,'b': 1,'c': 2,'d': 3}
print('-----------------------------------------------')
print('Dictionary')
print("dataのtype = {0}".format(type(data)))
# 追加可能(最もシンプルな1例)
data['e'] = 4

# セット
data = {'a','b','c','d'}
print('-----------------------------------------------')
print('Set')
print("dataのtype = {0}".format(type(data)))
# 追加可能(最もシンプルな1例)
data.add('e')


```

    -----------------------------------------------
    List
    dataのtype = <class 'list'>
    -----------------------------------------------
    Tuple
    dataのtype = <class 'tuple'>
    -----------------------------------------------
    Dictionary
    dataのtype = <class 'dict'>
    -----------------------------------------------
    Set
    dataのtype = <class 'set'>
    

## セイウチ演算子
Python 3.8からの新機能  
変数に値を割り当てる新しい構文    
詳細は[こちら](https://docs.python.org/ja/3/whatsnew/3.8.html)


```python
data = [i for i in range(10)]
if (n:=len(data)) <11:
    print(n)
```

    10
    

## ジェネレータ関数


```python
def generator(offset :int) -> int:
    yield offset + 1
    yield offset + 2

gen = generator(0)

for n in gen:
    print(n)

#error    
#gen.__next__()
```

    1
    2
    

## リスト内包表記
リスト作成の簡単な手段として提供  
詳細は[こちら](https://docs.python.org/ja/3/tutorial/datastructures.html)


```python
data = list(map(lambda x: x**2, range(10)))
print(data)

data = [x**2 for x in range(10)]
print(data)

## 条件を付けることも可能
data = [x**2 for x in range(10) if x%3==0 ]
print(data)

## 複数のfor句をつけることも可能
data = [( x, y, x*y) for x in range(3) for y in range(3, 0, -1) ]
print(data)

```

    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    [0, 9, 36, 81]
    [(0, 3, 0), (0, 2, 0), (0, 1, 0), (1, 3, 3), (1, 2, 2), (1, 1, 1), (2, 3, 6), (2, 2, 4), (2, 1, 2)]
    


```python

```
VS Code: Settings SyncのGitHubアカウントを変更する方法

## 問題
VS Code: Settings SyncのGitHubアカウントを変更しようとしたが選択肢が見つからない

![shohei_hagiwara.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/f03abd7f-a2ab-44aa-8f6a-072c343ee020.png)

## 解決方法
VS Codeの左下にある、人のような形のアイコンからGitHubアカウントのログアウトができる。

![shohei_hagiwara.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/cbe5380b-0a62-2785-124f-c777bc8c25fd.png)
UIViewのライフサイクル

UIViewのライフサイクルに関して曖昧だったので調べてみた。

UIVieの更新のステップが
1,制約の更新（updateConstraint）
2フレームの更新(layoutSubviews)
レンダリング(drawRect)


制約の更新
--

4つ条件で自動的にupdateConstaraint()が発生する
1,activeフラグによる有効と無効の変更
2,制約の優先度の変更
3、制約の追加や削除
4、制約対象のビューの階層の変更
これをオーバーライドすることで制約に変化があったときに独自の処理が可能になる。
また、self.updateConstraintsIfNeeded()とsetConstraintsIfNeeded（）で明示的に呼び出すことができる。

フレームの更新
--
制約情報が更新されあきららかになったので実際に枠組（フレーム）を更新していく作業。
layoutSubviews()が自動で呼ばれて親ビューから子ビューの矢印で更新が行われていく。
明示的に呼び出すにはself.layoutIfNeeded()を呼び出す必要がある。（UIKitの実際のフレーム描画はメインスレッドで行われるのでこれもメインスレッドで行う）
これをオーバーライドすると無限のスクロールViewができるらしい。（本によると）スワイプした際にContentOffsetを調整し、サブビューを調整することで可能。
今度試しにやってみたい。

レンダリング
--
実際に画面にレンダリングする。drawRect()メソッドが自動で実行される。setNeedsDisplay(), setNeedsDisplayInRect()でも明示的に呼び出すことができる。
ビューの一部を隠してる別のビューの移動・削除
hidden(非表示)になっていたビューの再表示
ビューを画面外までスクロールし、再び画面内に戻す
上記の条件でｄrawRect()が発火するようになっている。

これらのUIViewこライフサイクルはView ControllerのViewWillLauoutSubViews( )で開始され、フレームの更新まで行う。
その後、viewDidLayoutSubiews（）が呼ばれるとビューレイアウトが完了したことになる。
BIOSの画面にキーボードが効かず入れない時の対策

# IO機器は極力外す
基本。

# IO機器のHUB的な機器は介さない
USBを束ねるUSBハブやHDMIを束ねる統合器など。

私は、複数ディスプレイ出力を受け付けるHDMI統合器にHDMIケーブルをつないでいたが、
これが原因でUSBキーボードの操作が有効化されなかった。
【学習記録④】コンポーネントを用いて挨拶アラートを出してみる。

#はじめに
Vue.jsを最近勉強し始めたので学んだ文法などを備忘録としてメモしていこうと思います。
前回Vue CLIを用いてVueプロジェクトを立ち上げたので、今回はコンポーネントを作ってみました。

##フォルダ構成
![pic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/c39f55d1-d33f-67dd-0c6a-c37992a14d10.png)
componentsフォルダにてそれぞれの挨拶を返却するコンポーネントを作成しており、それらをApp.vueが受け取ってindex.htmlで出力しているという流れになっています。

##サンプルコード
以下はMorning.vueの中身です。Afternoon.vueとEvening.vueの中身も挨拶部分以外は同じ作りになっています。

```vue:Morning.vue
<template>
  <div>
      {{ message }}
      <button @click="greeting">おはようボタン</button>
  </div>
</template>

<script>
export default {
    data() {
        return {
            message: 'おはよう～！'
        }
    },
    methods:{
        greeting(){
            alert(this.message);
        }
    }
};
</script>
```

それぞれのコンポーネントを以下のApp.vueで定義しています。

```vue:App.vue
<template>
  <div>
    <morning></morning>
    <afternoon></afternoon>
    <evening></evening>
  </div>
</template>

<script>
import Morning from './components/Morning.vue';
import Afternoon from './components/Afternoon.vue';
import Evening from './components/Evening.vue';

export default {
  components: {
    Morning,
    Afternoon,
    Evening
  }
}
</script>
```

##出力結果
上記のコードで`npm run serve`を実行するとアプリが立ち上がり、ボタンをクリックすると以下のように設定したアラートが出力されます。
（以下は「こんにちは」ボタンをクリックしたとき）

![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/d5580b86-55af-1d58-81e7-5a8ae260927e.png)

#おわりに
簡単ではありますがVue.jsのコンポーネントを触ってみました！
自分でコンポーネントを作って親子関係にまとめていけるのは大規模なアプリを作る上ではとても助かりますね！
既存システムにおける特定機能削除の手順

今回既存のシステムにおける、特定機能の削除案件を担当することになったため、備忘録もかねてその実施方法をまとめていきたいと思います。(cakephpメインで運用しているシステムで実施しましたが、mvcの他のシステムでも同様に使える手順かと思います)

# 手順
### _１_. ルーティングファイル(route.php)から削除対象のコントローラー・メソッドを列挙
### _２_. １で挙げた対象コントローラー内の各メソッドが、削除対象外のメソッド等で使用されていないか調べるため、メソッド名で対象ディレクトリ内を全件検索
### _３_. ２の検索で引っ掛からなかった削除対象のメソッドを列挙
### _４_. ３で挙げたメソッド内の処理を追っていき、メソッド内で呼ばれている他メソッドがあればメモしておく。
### _５_. ４で挙げたメソッドが削除対象メソッド以外で使用されているか確認（こちらも手順２と同様に全件検索を実施）
### _６_.３で挙げたメソッドと４で新たに出たメソッドが削除対象のphp側のコードとして決定
### _７_. １で挙げたメソッドで描画しているviewファイルがあれば列挙
### _８_. phpと同様に１で挙げたviewファイルが他所で使用されているか否か全件検索で調査
### _９_. ８で削除対象となったviewファイル内で呼びだれている他viewファイルについても同様の全件検索を実施。
### _１０_. ８と９で残った(他所で使用されていない)ファイルがview側の削除対象ファイルとして決定
### _１１_. １０で削除対象としたviewファイル内のjs・cssファイルについて、これまでと同様の全件検索で削除対象か否かを確認
### _１２_. 最後に削除対象機能の名称などで全件検索をかけ、画像データ等で追加で削除が必要なデータがないかの確認を行う。
### _１３_. 完了

## 所感
今回僕が担当した案件はファイル数としては50ファイルくらいの修正・削除が必要なボリュームでした。
この手順で無事問題なくリリースできたので、よろしければ参考にしてみてください！

ps.初Qiita記事投稿でした。。　これからも頑張って投稿していければいいな。。
CloudFormationでロールバックしてしまったときに注意してほしいこと


#目的
・CloudFormationniおいて
正常なステータスのCloudFormation作成
→設定値を変更（スタックの更新）
→ロールバックしてしまう（UPDATE_ROLLBACK_COMPLETE）
→テンプレートの記述が変わっていない（なんなら設定値も変わっていない）
→エラーが解消されない
この流れを満たした人は、今回の記事が有用かもしれません。

#対象
（これは上の目的が満たされていることを確認した人は見なくて大丈夫です）
・ロールバックする設定をして実際にロールバックした人
・スタックの更新の際にロールバックした結果、何も更新が行われなかった人
・CloudFormationでロールバックしてしまってから一向にエラーが解決できない人
・SNS通知機能を実装している人

#用語
・CloudFormation・・・AWSリソースの環境構築を、設定ファイル (テンプレート) を元に自動化できるサービス
・スタック・・・テンプレートで記述したAWSリソースの集合
・ロールバック・・・処理のキャンセル

#結論
##やってほしい動作
設定値を成功するように適当に変更（スタックの更新その１）
→設定値を自分がしたい設定値に再変更（スタックの更新その２）

##何が起こっているか
変更予定のリソースがすべてロールバック＆何も変更されていない
→その影響でスタックのステータスがUPDATE_ROLLBACK_COMPLETEになっている
→しかし特に設定値が変わっていない上に、機能しないという不思議な現象が起きる

###事実
・「スタックの更新」をクリックし同じ設定値を設定中に再入力する→更新するところがありませんとエラーになる
→設定値は変わっていない証拠

・【やってほしい動作】を実行すると問題は解決し同じ状態に戻る
→設定値が同じでも問題なく動作する

#テンプレート
今回使ってみたテンプレートは以下を参考
https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/use-cloudformation-template-to-create-cloudwatch-alarms.html

##この実験をするためにやってみたこと
①SNSを利用しているにも関わらずパラメーターからEmailアドレスを空白
→これはSNSのサブスクリプションのメールアドレスを空白にしていることを示します。

②スタックの更新

##この実験をすると起こる現象
・AlarmNotificationTopic（アラームのターゲット）
→Invalid parameter: Endpoint(Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter;...
→UPDATE_COMPLETE

・スタックのステータス
→UPDATE_ROLLBACK_COMPLETE

・SNS
→特に変化なし


※例えば設定値のSNSを別のSNSにして、戻すときは再度サブスクリプションしなきゃいけないので気を付けてください。
【Nuxt.js】TailwindCSSの導入について

#はじめに
こんにちは。
こちらの記事では、Nuxt.jsにTailwindCSSの導入を行う方法を記しています。
誤っている点がございましたらコメントいただけると幸いです。

##TailwindCSSとは
TailwindCSSとは、ユーティリティファーストのCSSフレームワークです。
template（HTML）のクラス属性に対して直接ユーティリティクラスを定義するため、他のCSSが影響してデザインが崩れたり、クラス名を考える必要がなくなります。最近では、VueやReactなどを用いた開発の現場で採用されることが多い。
>TailwindCSS：https://tailwindcss.com/

###ユーティリティファーストとは
フレームワークとして独自のクラスを用意しており、いくつかのクラスを組み合わせることで生のCSSを使用せずにスタイリングが行える考え方のこと。

###Bootstorapとの違い
* classひとつひとつにCSSプロパティが対応しているので自由度が高い
* ビルド時に不要なクラスを削除してくれるのでファイルサイズが軽い
* JavaScriptに依存しないので競合する心配がない


##実装手順
Nuxtの新規プロジェクト作成時に、UIフレームワークをTailwindCSSで選択している場合は、すでにインストールされているので`package.json`と`nuxt.config.js`に以下のような表示があるか確認する。

```package.json
"devDependencies": {
  "@nuxtjs/tailwindcss": "^4.2.0"
}
```
```nuxt.config.js
buildModules: [
  '@nuxtjs/tailwindcss',
]
```

表示されていればOKです。

###1. tailwind.cssの作成・編集
assetsディレクトリに以下のような構成で、`css/tailwind.css`を作成・編集する。
assetsディレクトリがない場合はプロジェクト直下に作成する。

>プロジェクト名/
　├ assets/
　│ └ css/
　│ 　└ tailwind.css
　├ components/
　└ pages/
〜〜〜
> 

```css:tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

###2. tailwind.config.jsの作成・編集
下記のコマンドを実行して`tailwind.config.js`ファイルを作成する。
※コマンドに`-p`をつけてしまうと、不要なフォルダが作成されてエラーになるので注意。

```
npx tailwindcss init
```

ファイル作成後、`purge`に以下のように編集を行う。

```tailwind.config.js
purge: [
  './components/**/*.{vue,js}',
  './layouts/**/*.vue',
  './pages/**/*.vue',
  './plugins/**/*.{js,ts}',
  './nuxt.config.{js,ts}',
]
```

###3. nuxt.config.jsの編集
どのファイルでも使用できるように、`nuxt.config.js`を編集する。

```nuxt.config.js
css: [
  '~/assets/css/tailwind.css',
]
```
<br>

#おわりに
ここまでTailwindCSSの導入についてまとめました。
これから実際にレイアウトを組んでいくので、ヘッダーの作成やページごとのスタイリングも記事にしていきたいと思います。

以上、最後まで読んでいただきありがとうございました！
【CentOS】OSのバージョンを確認したい！

# ひとことで言うと
`cat /etc/redhat-release`でわかるよ

# 概要
いつも忘れるので備忘録として。（あとMarkdown記法の練習）

# 環境
* ホストOS：Windows 10
* ゲストOS：CentOS 7.9
* 仮想化ソフト：VirtualBox 6.1.18

ネットワークアダプターにホストオンリーアダプターを割り当てて、TeraTermでssh接続。

# コマンド
バージョン情報は`/etc/redhat-release`に記載されてるので、`cat`コマンドで出力する。

```
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
```

# まとめ
バージョン情報が確認できた！
JS/TSで~度（度数法）を~ラジアン（弧度法）に変える方法

# はじめに
JS/TSでかんたんなゲームを作っていたときに角度計算の度に 度数法 -> 弧度法　の計算をしているのに気が付き
気持ち悪くなったので、自分への戒め的な感じで記事にしておく。

```toRad.js
const toRadians = (angle) => (angle * Math.PI) / 180;
```

```toRad.ts
const toRadians = (angle: number): number => (angle * Math.PI) / 180;
```
Go-lang の文字列を宣言＆代入する

Go言語の勉強メモ


`:=` ってなんや？ってやつ。

`var` がいらない && 暗黙の型定義するときに使うらしい


下はすべて同じ意味


```go
    var msg1 string = "Hello World"
    var msg2 = "Hello World"
    msg3 := "Hello World"

    var msg4 := "Hello World"    // syntax error
    msg5 string = "Hello World"   // syntax error
    msg6 = "Hello World"      // syntax error

```


## refers
https://qiita.com/HiromuMasuda0228/items/65b9a593275f769f6b69
https://qiita.com/tfrcm/items/e2a3d7ce7ab8868e37f7



あと文字列内で変数展開ができないという衝撃
https://qiita.com/KEINOS/items/baef1be88f15515026ec


なんかちょっと、VBAを思い出す感じだった
VSCode: C++をclang++でデバッグして配列の中身を見る（macOS）

こんにちは、競プロ初心者です。AtCoderを始める際、gccでコンパイルするように設定すると思うのですが、残念ながらgccではVSCodeのデバッグでは（少なくとも私の環境では）配列の中身を見ることができません。そこでclang++を使ってデバッグするようにしようと思ったのですが、そこそこ詰まったのでメモとしてここに書き留めておこうと思います。

2021/10/27
macOS Montereyを使っている場合に出るエラーの解消法を追記しました。

## 動作環境
MacBook Air (M1, 2020)
macOS Big Sur 11.6
Visual Studio Code 1.61.1

## 前提
- Command line tools for Xcodeをインストールしている
- VSCodeをインストールしている
- VSCodeの拡張機能C/C++をインストールしている

## 手順
1. 拡張機能からCodeLLDBをインストールする
1. ワーキングディレクトリ中の.vscode/launch.jsonを書き換える
1. .vscode/task.jsonを書き換える

おまけ `#include <bits/stdc++.h>` を使えるようにする

### 拡張機能からCodeLLDBをインストールする
拡張機能のmarketplaceからCodeLLDBをインストールします。

2021/10/27 追記
macOS Montereyを使っていてデバッグ時にエラーが出る場合は ~/.vscode/extentions/vadimcn.vscode-lldb-1.6.8/lldb/bin にあるdebugserverを削除すれば正常に動くようになります。
![スクリーンショット 2021-10-17 15.41.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1885539/45110ed1-4130-6def-83c8-60c576367ce5.png)

### ワーキングディレクトリ中の.vscode/launch.jsonを書き換える
何かしらのcppファイルを開いた状態で「実行とデバッグ」を行い、C++ (GDB/LLDB) → clang++ (usr/bin/clang++) の順に選択すると、ワーキングディレクトリ中の.vscodeというディレクトリの中にlaunch.jsonとtasks.jsonが生成されます。launch.jsonを開き、configurations中のtypeを`"lldb"`に書き換えます。

```json:launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "clang++ - アクティブ ファイルのビルドとデバッグ",
      "type": "lldb",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "lldb",
      "preLaunchTask": "C/C++: clang++ アクティブなファイルのビルド"
    }
  ]
}
```

### .vscode/task.jsonを書き換える
次に、同じく生成されたtasks.jsonを開き、tasks中のcommandを`"/usr/bin/clang++"`に書き換え、argsの一番上に`"-std=c++20",`を追加します。

```json:tasks.json
{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: clang++ アクティブなファイルのビルド",
      "command": "/usr/bin/clang++",
      "args": [
        "-std=c++20",
        "-fdiagnostics-color=always",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "デバッガーによって生成されたタスク。"
    }
  ],
  "version": "2.0.0"
}
```

### おまけ `#include <bits/stdc++.h>` を使えるようにする
ターミナルで以下のコマンドを順に実行します。wgetコマンドが見つからない場合は、homebrewからwgetをインストールしてから再び実行すれば大丈夫です。

```shell
$ cd /Library/Developer/CommandLineTools/usr/include/
$ mkdir bits
$ cd bits
$ sudo wget https://gist.githubusercontent.com/reza-ryte-club/97c39f35dab0c45a5d924dd9e50c445f/raw/47ecad34033f986b0972cdbf4636e22f838a1313/stdc++.h
```

これで配列の中身を見ることができるようになりました。
![スクリーンショット 2021-10-17 16.59.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1885539/6bcdf6c1-0859-d30b-c329-d15c59bd90db.png)



## 参考文献
1. [AtCoder用C++開発環境 (Mac編)](https://blog.spiralray.net/cp/devenv-cpp)
1. [Visual Studio Code を使った C++ のビルド＆デバッグ方法](https://daily-tech.hatenablog.com/entry/2018/11/17/012113)
KeycloakでSAMLログイン検証用のIdPを立ててみる

SAMLでのSSO接続を検証する環境が必要になったので、IdP立てるのに簡単な方法を探したところ、Keycloakが良さそうだった。

Keycloakは多機能で、今後いろいろな学習にも使えそう！

##KeycloakをDockerで立ち上げる

Keycloakは開発元でdockerイメージも公開しており、コマンド一発で立ち上がってしまう。

```powershell
docker run -d -p 18080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin --name keycloak jboss/keycloak
```

最近新しくなったお仕事PCであるところの Apple Sillicon では残念ながらそのままは起動しなかったので、とりあえずWindows10のDocker Descktop環境でテスト。

##Keycloakの管理画面から設定を行う

dockerでサーバが起動したら、ブラウザで管理画面を開きます。
http://localhost:18080/auth/admin/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/b93d921f-8bb1-357b-c0a1-0de5dc4bc697.png)

起動時に指定したユーザ名とパスワードでログインします。

###言語設定
日本語で管理画面なども使いたい場合、設定を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/4b09595b-4c2c-1ec7-2502-5fe75db7345b.png)
Themes > Internationalization Enabled をカチッとONにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/9b31ad96-b4ca-af5e-c394-4c8fdb6ee0d4.png)
Default LocaleをjaにしてSave、右上のメニューから Manage Accountを選択するなどして管理画面に入り直すと表示が日本語になります。

###レルムの作成
masterというレルムが作成されますが、これはレルムを作成するためだけのもの。テストなり運用するためのレルムを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/7cc9f11f-64d5-d3d5-67c0-91760e1f1c87.png)
初期レルムが選択されていますがマウスをホバーすると追加のメニューが出てきます。

指定するのは名前だけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/9a69a047-3acd-fc9d-d666-5a93db430992.png)

##Keycloakにユーザを追加する
SSOの検証をするために、ログインできるユーザを作成します。
管理>ユーザー から「ユーザーの追加」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/1dc499e6-affd-2064-6832-b03f36f30da3.png)

必要なのはユーザー名のみ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/cad0779f-817a-4ac9-d82b-6d8986de3a8b.png)

作成されたユーザーのクレデンシャルでパスワードを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/c4e44853-0e45-700e-2216-95161ea52002.png)

##ユーザーでログイン
以下のUrlをブラウザで開いてみます。
http://localhost:18080/auth/realms/dev/account
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/c54acf43-2f41-a8b5-43d0-514188f4fd46.png)

ログインすると「一時的」でパスワードを設定したために設定が求められました。これでログインできるユーザーを用意することができました。

##SAML接続のためのメタデータ
最後に、今回の最大の目的であるところのSAML連携の設定に必要なメタデータを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/89425878-bfda-62ea-581c-cd55b70766bf.png)
レルムの設定 > 一般 >　エンドポイント からメタデータを取得することができます。



##参考URL
https://qiita.com/cold-wisteria/items/557c0d9bd34b9d638f58
Alamofireライブラリを用いてQiitaAPIを表示

##はじめに
今回は学習の一貫として初心者がAlamofireライブラリを用いてQiita APIをTableViewに表示し、Cocoa MVCアーキテクチャを用いてリファクタリングしました。制作期間は2週間前後です。

##学習内容
・Git Github
・Swiftの基礎（delegate,self,closures、メンバー変数とローカル変数、イニシャライザ）
・ソフトウェアアーキテクチャ(MVC,MVVM,MVP)
・オブジェクト指向

##作ったもの
![2021-10-17 16.58のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607520/92a42632-5fbe-cb1b-34b6-7231eb15203d.jpeg)





##課題
コードを書いた際の言語化が先輩や他の人とコードレビューをする際にとても重要であることが分かり、「言語化」が今後の課題になると思いました。また、学んだエラー文を読み解いていくことが結局解決につながり、成長にもつながることが分かりました。
また、delegate,self,closuresはまだ理解が浅い部分があるのでgithubでコードを読みながら自分でも書いていくようにしたいと思います。
##感想
初めGitのコマンドを何度も忘れてしまうため、何度も確認するのが大変だった。コマンドを忘れてしまうためメモとして書きました。→ 「[Gitの基本とコマンド](https://qiita.com/ss0817/items/83db6a7098c90b6cd8c1)」

今回始めてソフトウェアアーキテクチャがあることを知って「コードの再利用がしやすい」、「保守性を確保できる」、「テストのしやすさ」が重要だと学びました。
今後は自分の勉強のためにQiitaなどに得た知識をアウトプットしていきたいです。
【始め方】GASプロジェクト開発時にやること(GAS + TypeScript + clasp + Prettier + ESLint)

## はじめに
GAS, clasp, TypeScript, Prettier, ESLint を使用したプロジェクト開始時に行うことについて書いていきます。

TypeScript のプロジェクト開始方法についても記事を書いているので、こちらもご参照ください。

https://qiita.com/hasehiro0828/items/70e827c427d965d68e17

## 開発環境の構築
### claspのダウンロード
https://github.com/google/clasp#install

GASをローカルで開発しやすくするためのツールです。

> Then enable the Google Apps Script API: https://script.google.com/home/usersettings

と書いているので、オンにします。

### プロジェクトの作成

```bash
clasp login #　初めて使用する場合は login します。
clasp create
```

### typescript 導入
typescript のインストール

```bash
# typescript のインストール
yarn add -D typescript @types/node@"^16.7.0"

# tsconfig の作成
yarn run tsc --init
```

`target` は `ES2019` にしておきます

https://github.com/google/clasp/blob/master/docs/typescript.md#v8-engine-support

```json:tsconfig.json
"target": "ES2019"
```


### ESLint, prettier の導入

```bash
# インストール
yarn add -D prettier eslint eslint-config-prettier

# eslint の初期設定
# 対話式で入力していく
# Would you like to install them now with npm? は　Yes を選択
yarn run eslint --init

# npmではなくyarnを使ってるので、やり直し
rm -rf package-lock.json
yarn install
```

`@typescript-eslint/explicit-function-return-type` の rule を有効化する

```javascript:.eslintrc.js
rules: {
  "@typescript-eslint/explicit-function-return-type": "warn",
  ...
}
```

prettier に対応させるために、`.eslintrc.js` を修正して extends の**最後**に `"prettier"`を入れる

```js
extends: [... "prettier"],
```

prettier の設定ファイルの作成

```bash
echo "module.exports = {\n\tprintWidth: 120\n}" > .prettierrc.js
echo "tsconfig.json" > .prettierignore
```

### import 周りをいい感じにする
こちらをご参照ください。

https://qiita.com/hasehiro0828/items/70e827c427d965d68e17#import-%E5%91%A8%E3%82%8A%E3%82%92%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AB%E3%81%99%E3%82%8B

### `@types/google-apps-script` をインストール

```bash
yarn add -D @types/google-apps-script
```

### eslint の `no-undef` に対応する

https://www.npmjs.com/package/eslint-plugin-googleappsscript

を使えばいい

## 設定ファイルの変更

```bash
jq '.rootDir = "./src" | .filePushOrder = ["src/main.ts"]' .clasp.json > tmp.json && mv -f tmp.json .clasp.json
yarn prettier .clasp.json --write

jq '.timeZone = "Asia/Tokyo"' appsscript.json > tmp.json && mv -f tmp.json appsscript.json
yarn prettier appsscript.json --write
```

## ファイルの作成

```bash
mkdir src
touch src/main.ts

# appscript.json を移動
mv appsscript.json src
```


```ts:src/main.ts
// eslint-disable-next-line no-unused-vars
const main = (): void => {
  console.log("hello");
};
```

コードをプッシュし確認します

```
clasp push
clasp open
```

スクリプトエディタが開くので、実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209015/02f30317-dd42-cb23-b442-cfc08e007b40.png)


## おわりに
これにて、ローカルで GAS を TypeScript でいい感じに開発することが出来るようなりました！
某２ちゃんねるのような掲示板を制作

このウェブページはＰＨＰで書かれています。
巨大掲示板の2ちゃんねるのような作りを目指して制作しました。
基本的なコードの挙動のみで構成されています。

https://kurotsushirouproject.top/bbs/BBScontact.php
さくらサーバーで拡張子.htmlを使ってPHPを利用する方法

自分のための備忘録です。

さくらサーバーがどうやらアップデートされたようで、.htmlを使ってPHPを使うための.htaccessの設定方法が変わった様です。
~~このサイトに書いてあるのが正解でした。~~

https://y-com.info/contents/?p=1266

~~「php.cgiを作成しないとダメ」って色々なサイトで言っていますが、変更されています。~~
~~php.cgiはいらないです。~~

.htaccessにこれ書けばOKでした

````htaccess
AddType application/x-httpd-php .html
````

すみません。訂正があります。
上記の記載に関して、さくらサーバーのステージングでは上記の方法で、php.cgiを使わずにできましたが、本番環境では、みなさんが行っている様に「php.cgi」を記載する必要がありました。

##php.cgiの作成

こちらを参考にしました。
https://omoteura.net/entry/sakura-html-php

````php.cgi
#!/bin/sh
exec /usr/local/bin/php-cgi
````
この内容を記載して、文字コードを「EUC-JP」、改行コードを「LE」で保存します。
アップしたらパーミッション「705」にします。

やはり、このファイルを作成しておかないといけない様です。
ちなみに、ファイル名は別に「php.cgi」じゃなくても大丈夫です。次に記載する.htaccess内のファイル名と合わせてください。

````htaccess
Action myphp-script /php.cgi
AddHandler myphp-script .php .html
````

サーバーの設定によって記述方法が違うぽい。

MIMEタイプをいじる方法で「AddType」を使って、「AddHandler」で関連付けるのが、後の方法らしい。
その他に「SetHandler」で関連づける方法もある様です。
参考：https://gist.github.com/mikanmarusan/8264092
tmuxに表示している文章をVOICEROIDに読み上げてもらう

tmuxからスクリプト越しに[AssistantSeika](https://hgotoh.jp/wiki/doku.php/documents/voiceroid/assistantseika/assistantseika-000)を使うことで、VOICEROIDに読み上げをしてもらいます。

## 前提

- AssistantSeikaが対応する読み上げソフトをインストールします
  - 自分は[VOICEROID2 結月ゆかり](https://www.ah-soft.com/voiceroid/yukari/)を使っています
- AssistantSeikaをインストールする
  - SeikaSay2.exeから読み上げができるようセットアップします

```shell-session
$ neofetch distro kernel
distro: Arch Linux on Windows 10 x86_64
kernel: 5.10.60.1-microsoft-standard-WSL2
$ tmux -V
tmux 3.2a
```

## スクリプトの用意

まず、以下のスクリプトを用意しました。seikaという名前をつけています。

```bash
#!/bin/bash

_TMP=$(mktemp -t seika.XXXXXX)
trap 'rm ${_TMP}* 2>/dev/null' EXIT

perl -0pe 's#\n##g' <"${1:-/dev/stdin}" >>"${_TMP}"

SEIKASAY2_DIR=/mnt/c/Apps/AssistantSeikaUtils
CID=2003
${SEIKASAY2_DIR}/SeikaSay2.exe -cid ${CID} -f "${_TMP}" >/dev/null
```

seikaは標準入力(または引数で指定したファイル)から改行文字を取り除いて、一時ファイルに保存します。
VOICEROIDは改行文字を空白と捉えていて、文章の途中に改行が含まれると、そこで一瞬読み上げを止めてしまいます。
ターミナルでは(というかテキストファイルでは)文章の折返しに改行文字を使うことがままあるので、このスクリプトではそれを取り除いています。

そして、一時ファイルを入力に、AssistantSeikaのCLIであるSeikaSay2.exeを実行することで、読み上げをしてもらいます。

## tmuxの設定

.tmux.confに以下の行を追加します。

```
bind -T copy-mode M-s send-keys -X copy-selection\; run-shell -b 'tmux show-buffer | seika'
```

コピーモードに`Alt-S`のキーバインドを設定します。

ここでは2つのtmuxコマンドを実行しています。`send-keys -X copy-selection`で選択した範囲の文字をtmuxローカルのセレクションに保存します。

次に`run-shell -b 'tmux show-buffer | seika'`でUNIXシェル向けにコマンドを実行します。`-b`はバックグラウンド実行です。これがないと、読み上げが終わるまでtmuxが止まります。`tmux show-buffer | seika`がシェルコマンドです。`tmux show-buffer`は先程保存したセレクションの内容を標準出力に流します。`seika`は前節で紹介したスクリプトですね。パイプ経由でセレクションの内容を受け取り、SeikaSay2.exeを起動します。

# まとめ

以上の簡単な手順で、tmuxのコピーモードで文字列を選択し、`Alt-S`を押下すると、読み上げをしてくれるようになりました。

コピーモードはこれまでターミナルの内容をクリップボードに保存するためだけに使っていましたが、ターミナル上の範囲を選択して、外部のコマンドに流し込んで、処理することが簡単にできるとわかったので、少し夢が広がったような気がします:smiley:

AssistantSeikaのおかげで、スクリプトと設定による繋ぎこみだけで、text-to-speechができました。作者さんにはこの場を借りて、お礼申し上げます。ありがとうございました。
MysqlでNULLのカラムをカウントする方法

#はじめに
outer joinしたテーブルでNULLを含むカラムをカウントした結果をorderByで並び替え用とした時にNULLのレコードがカウントされなかった。
NULLのレコードもカウントする方法を備忘として記録する。

#事例
tableA ※nameはユニークとする

| id | name | 
|:-----------|------------:|
| 1      | aaa        | 
| 2     | bbb      |

tableB

| id | point | 
|:-----------|------------:|
| 1      | 10        | 
| 1     | 20      |


```
DB::table('tableA')
    ->leftjoin('tableB', 'tableB.id', '=', 'tableA.id')
    ->orderBy(DB::raw('count(point)')
    ->groupBy('tableA.id')
    ->get();
```

Laravelにて上記クエリビルダを実行すると下記のテーブルが得られる。

| id | name | point|
|:-----------|------------:|------------:|
| 1      | aaa        | 30|

IFNULLを使用することでid=2も取得することができる。

```
DB::table('tableA')
    ->leftjoin('tableB', 'tableB.id', '=', 'tableA.id')
    ->orderBy(DB::raw('count(IFNULL(point, 0))')
    ->groupBy('tableA.name')
    ->get();
```

※tableBにid=2が無いため、idでgroupByをするとエラーとなった。

実行結果

| id | name | point|
|:-----------|------------:|------------:|
| 2      | bbb        | 0|
| 1      | aaa        | 30|

#IFNULLの使い方
IFNULL('カラム名', 'NULLを置き換えたい値')

※Mysqlではない場合、NULLの置き換えはIFNULLとは限らない。
テレワーク時代はJSON形式で質問しよう

皆さんはJSONというものをご存知でしょうか。
要するにキーとバリューの組み合わせのテキストフォーマットです。
厳密には違うかもしれませんが、ここではそれをJSONと定義して呼びます。
キーには、主題、バリューには内容を記載しましょう。
例：
わからないこと：データベースにアプリから接続が出来ない。
確認したこと：データベースプロセス、サーバーが立ち上がっていること
確認したこと２：アプリXXからは接続が出来る、アプリYYからは接続できない
エラーの内容：grant xxエラーが出力される
調べたこと：grant xxとは、権限のエラーのとき出力される
ログ：ｘｘｘｘ

こんな感じで質問は情報を多くまとめて一気にしましょう。
多くまとめて質問されては相手が迷惑では？と思うかもしれませんが、逆です！！
いちいち切り分けするために質問のレスポンスをやり取りするほうが回答者のコストになってしまいます。
相手も自分のタスクを抱えています。そんな相手が自分のために回答する時間を無料で捻出してくれてるわけですから、相手に合わせるのはマナーじゃないでしょうか。
各々思うところがあるかもしれませんが会社に雇われて、他のメンバーと協力してやっていかないといけないのに横柄な態度では他の人を敵に回してしまいます。そしたらあなたは損な立場になりかねません。

まぁ長々書きましたが質問するなら相手のコストにならない形で質問してねってことです。
Python3.7以降でsubprocess.run()関数を使いexe実行

#Python3.7以降でexeを実行する
Python3.5以降でexeを実行するには、**subprocess.run**を使います。
（※Python3.4以前は**subprocess.call**です。）
そしてこの記事で紹介するパラーメータは3.7以降のものなのでご注意ください。

コマンドプロンプトで以下コマンドで実行するexeを例に説明します。
（例）cmd> `sample.exe /a /b /c`

```python
import subprocess

result = subprocess.run("sample.exe /a /b /c")
print(result)
#戻り値
#CompletedProcess(args='sample.exe', returncode=0)

```

 

　
 
戻り値の通り、これだけでは出力結果やエラー出力結果が得られません。
そこで、`capture_output`と`text`パラメータを設定してやります。

```python
import subprocess

result = subprocess.run("sample.exe /a /b /c, capture_output=True, text=true")
print(result)
#戻り値
#これはサンプルです。
```

**capture_output**
`true`を指定すると、出力結果、出力エラー結果を得られます。
**text**
`true`にすると戻り値を文字列として受け取れるようになり便利です。指定しなければバイトデータとして返ってきます。


#さいごに
今回は１分以内に直感的にPythonでexeを実行する方法を伝えたかったため、最小限の説明としました。
これ以外にも**subprocess**はたくさんパラメータや使い方が存在するのでぜひ調べてみてください。

#参考サイト
・[Python 3のsubprocess.run()の使い方](Python 3のsubprocess.run()の使い方)
・[subprocess --- サブプロセス管理](https://docs.python.org/ja/3/library/subprocess.html)