OmniAICreator/Qiita-1.07M huggingface dataset:
STM8とWS2812B(40個、未定?)を単一の値で光らせる。


x STM8S-Discovery ボード

苦労した点

なぜか処理落ちしまくる
処理を8ビットに合わせて
高速化しまくり
32ビット機の場合は、逆に遅くなるので要注意

x arduinoUNOとくらべるとなんか遅い。

![o_con25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c521651b-7aa2-36bc-4c34-67a673c25343.jpeg)



```c++


#define G0  0
#define R0  12
#define B0  0

#define L_NUM 40

char l[L_NUM*3]; //max40 led

#define PD_ODR *(volatile uint8_t *)0x500F

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){
   //0.3us 800khz

    PD_ODR = 0b00000001; //1 0.125
    PD_ODR = 0b00000000; //2 0.250
    PD_ODR = 0b00000000; //3 0.375
    PD_ODR = 0b00000000; //4
    PD_ODR = 0b00000000; //5

    PD_ODR = 0b00000000; //1
    PD_ODR = 0b00000000; //2
    PD_ODR = 0b00000000; //3
    PD_ODR = 0b00000000; //4
    //PD_ODR = 0b00000000; //5

}//bit_off1

// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz

    PD_ODR = 0b00000001; //1
    PD_ODR = 0b00000001; //2
    PD_ODR = 0b00000001; //3
    PD_ODR = 0b00000001; //4
    PD_ODR = 0b00000001; //5

    PD_ODR = 0b00000001; //1
    PD_ODR = 0b00000001; //2
    PD_ODR = 0b00000000; //3 0.375
    PD_ODR = 0b00000000; //4 0.250
    PD_ODR = 0b00000000; //5 0.125

}//bit_on1


//RGB_LEDにデータをn回分送る
void ws_led()
{
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii<(L_NUM*3);ii++){

      if( l[ii] & 0b10000000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif
    
      if( l[ii] & 0b01000000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00100000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00010000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00001000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000100 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000010 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000001 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif
      
  }//for
  enableInterrupts();
}//ws_led


//RGB_LEDに0データをn回分送る
void ws_led_cl()
{
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii< (L_NUM*3)  ;ii++){
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0

    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
  }//for
  enableInterrupts();
}//ws_led

void setup() {

// disableInterrupts();

  //GPIOの初期化
  pinMode(PD0, OUTPUT);
  //pinMode(PB7, INPUT_PULLUP);

  //状態を1づつ進める
  for(char ii=0;ii<L_NUM;ii++){

    //1個のデータをセット  
    l[(ii*3)+0] = G0;
    l[(ii*3)+1] = R0;
    l[(ii*3)+2] = B0;

  }//for

}//setup

void loop() {

  if( /*digitalRead(PB7)*/ 1 == 0 ){
    //ws2812bへ0データを送る
    ws_led_cl();
  }else{
    //ws2812bへデータを送る
    ws_led();
  }  

  //0.1秒待つ
  delay(100);

}//loop




```
【Laravel8】フォームのラベルを日本語化する

## やりたいこと

下記画像のように、入力項目を日本語化する

![スクリーンショット 2021-09-28 14.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983882/79eb6c94-16b0-ac68-ac24-ea73cf7b27a1.png)

## 参考サイト

手順だけ書き出したかったので、自分でも記事を書いたが、
詳しいことは下記に書いてあるので、こちらを見たほうがいい。

https://qiita.com/apricotcomic/items/d12f0fe673c78683b09b

ただ、viewファイルの書き方だけ自分の環境では動かないところがあったので、
エラーになる場合は、この記事の「bladeファイルを修正する」の項目を見る。

## app.phpを修正

localeをjaに変更する。
これで、デフォルトの言語が日本語になる。

```
'locale' => 'ja',
```

## 日本語化用のファイルを作成する

`resources/lang/`ディレクトリに、新しく`ja`ディレクトリを追加する。
※間違って`en`ディレクトリの中に作らないようにする。

`ja`ディレクトリの中に、日本語化用のファイルを作る

今回は`label.php`にするが、ファイル名は任意でOK

```label.php
<?php

return [
    'name' => '名前',
    'Email' => 'メールアドレス',
    'Password' => 'パスワード',
    'Confirm Password' => 'パスワード再確認',
];
```

## bladeファイルを修正する

今回は、laravel breezeでログイン機能を作っているので、フォームの中はlaravelComponentになっている。

x-labelコンポーネントのvalueの中身を以下のように変更する。

※参考記事では、`:value="{{__('label.name')}}"`となっていたが、自分の環境だとエラーがでたので、`{{}}`は外した。

```
<form method="POST" action="{{ route('register') }}">
 @csrf
 <!-- Name -->
 <div>
  <x-label for="name" :value="__('label.name')" />　// ←　このように変更

~省略~
```

これで最初の画像のように、各項目が日本語で表示される。
Swift で OpenCV を使ってみた

#はじめに
iOS プロジェクトで OpenCV を使って画像にメディアンブラーをかけてみました。
OpenCV の導入から説明していますので、参考にしていただけると幸いです。

#プロジェクトに OpenCV を追加する

今回は CocoaPods を使うことにします。
Podfileに以下を記述します。

```:Podfile
pod 'OpenCV'
```

iOS プロジェクトのルートディレクトリで以下コマンドを実行します。

```zsh
pod install
```

これで OpenCV がインストールできました。

#Objective-C++とは
OpenCV は Swift 環境では動きません。
なので、OpenCV が動く C++ の環境で OpenCV を扱い、それを Objective-C でラップし、更にそれを Swift から呼び出して利用する、という方法をとります。

C++ を記述できる Objective-C を Objective-C++ と呼びます。

#Objective-C++ を使えるようにする
Objective-C++ を使えるようにするための手順を説明します。

Xcode で iOS プロジェクトを開き、Objective-C の.hファイルと.mファイルを追加します。

今回はファイル名を```Mat.h```、```Mat.m```としておきます(OpenCV が行列＝Matrixを扱うため)。

その際、```Bridging-Header.h```を生成しますか？と聞かれたら、はいを選択します。

次に、Objective-C++ を使う場合は```Mat.h```と```Mat.m```の拡張子をそれぞれ```Mat.hpp```と```Mat.mm```に変更します。

これで Objective-C++ を使う準備が整いました。

#.hppファイルの中身を記述する
.hppファイルはヘッダファイルと呼び、クラスの宣言を記述します。

``Mat.hpp``の中身を以下のように書き換えます。

```obj-c++:Mat.hpp
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Mat : NSObject
+ (UIImage *)medianBlur:(UIImage *)image:(int)blurSize;
@end

NS_ASSUME_NONNULL_END
```

``medianBlur()``メソッドの先頭の```+```は、このメソッドがクラスメソッド（クラスをインスタンス化することなく使用できるメソッド）であることを表しています。

一方メソッドの先頭を```-```にすると、インスタンスメソッド（クラスをインスタンス化して使うメソッド）であることを表します。

#.mmファイルの中身を記述する
.mmファイルはメソッドファイルと呼び、クラスの実装を記述します。

``Mat.mm``の中身を以下のように書き換えます。

```obj-c++:Mat.mm
#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
#import "Mat.hpp"

@implementation Mat
+ (UIImage *)medianBlur:(UIImage *)image:(int)blurSize {
    cv::Mat src;
    cv::Mat dst;
    UIImageToMat(image, src);
    try {
        cv::medianBlur(src, dst, blurSize);
    } catch (cv::Exception& e) {
        const char* err_msg = e.what();
        NSLog(@"Mat.medianBlur(): %s", err_msg);
        NSLog(@"%@",[NSThread callStackSymbols]);
        return nil;
    }
    UIImage* outImage = MatToUIImage(dst);
    return outImage;
}
@end
```

OpenCV では、画像を行列に変換して処理します。
``UIImageToMat()``と``MatToUIImage()``はそれぞれ UIImage ↔︎ 行列 の変換を行うメソッドです（ opencv2/imgcodecs/ios.h に定義されています）。

``cv::medianBlur(src, dst, blurSize)``は実際にメディアンブラーをかけている箇所で、src: 入力画像の行列、dst: 出力画像の行列、blurSize: ブラーサイズを表します。
詳細は[こちら](http://opencv.jp/opencv-2svn/cpp/imgproc_image_filtering.html#cv-medianblur)を参照してください。

catch 節の中はエラー処理です。
メディアンブラー処理に失敗した際に throw される``cv::Exception``は C++ のエラークラスであり、Swift 側で拾うことはできません。なので Objective-C でエラーメッセージとスタックトレースをログ出力した上で、``nil``を返すようにしています。

#Swift から呼び出す
Swift ファイルから呼び出すには、以下のように記述します。

```swift
let blurredImage = Mat.medianBlur(uiImage, 13)
```
ブラーサイズには1より大きな奇数を指定する必要があります。
エラー処理をする場合は、nilが返ってきた時の処理も記述してください。
[Swift]モーダル画面からPush遷移する方法

### やりたいこと
modal遷移によって開いた下からヌッと出てくる画面から、
push遷移によって右側からスライドして出てくる画面への遷移をしたい。

### コード

モーダル画面への遷移

```.swift
    @objc func openModalView() {
        let vc = ModalViewController()
        // これはモーダルの表示方法の設定なので適宜設定
        vc.modalPresentationStyle = .overCurrentContext
        // NavigationControllerのrootにモーダル画面を設定。これが重要！
        let nav = UINavigationController(rootViewController: vc)
        self.navigationController?.present(nav, animated: true)
    }
```

モーダル画面からのPush遷移(普通のPush遷移でOK)

```.swift
    @objc func openNextView() {
        let vc = NextViewController()
        self.navigationController?.pushViewController(vc, animated: true)
    }
```
Xcode12 のStoryBoardでAn internal error occurred. Editing functionality may be limited.が発生した時の対処

また発生したものの、原因が全く別だったのでレポート。
前回までの対処方法
https://qiita.com/nekonekodou-mike/items/dc476e9d9c0aff0fb9c9

# 動作環境
MacBook Air (M1, 2020)
macOS Big Sur
Xcode12.4

# 状況
StoryBoardを編集しようとしたが、An internal error occurred. Editing functionality may be limited.と表示され、レイアウトが青い線のみになる現象が再発

# これで解決！
原因は、XcodeをRossettaを使用して開いていたこと。
なので、アプリケーション＞（右クリック）＞情報を見る を開いてチェックを外して、Xcodeを再起動すれば解決。
![Xcodeの情報を見る.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348602/68d248f2-ef61-a147-8184-0a601a762e65.jpeg)


そもそも、なぜRossettaが必要だったかというと、ipaを作成したり、AppStoreConnectにアップロードする際のアーカイブでエラーが発生するから。
Xcodeをアップデートすれば改善されるのかもしれないが、プロジェクトの都合でできないので、必要な時に毎回切り替えることで対応するしかない。
Workato：Google Driveコネクターを利用して、ファイルをコピーする

Googleスプレッドシートでテンプレートとなるファイル（スプレッドシート）を用意しておき、それをコピーして新たなファイルをコピーして使いたい、といった場合があります。Workatoでは、Google Driveコネクターのカスタムアクションを利用してファイルコピーを実現することが出来ます。

# 手順

## １． Google Driveコネクターを選択し、「Custom action」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/45518e97-473d-96ab-3ad8-15cb41744bc7.png)

## ２．以下の通り設定を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/63aab184-b21b-0e08-af81-4d9f0c6d6ea4.png)

### Action name

任意の名称

### Method

POST

### Path

files/<コピー元ファイルのID>/copy

### Request type

JSON request body

### Response type

JSON response

### Input

#### Request body parameters

「name」というString型のフィールドを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/168b978d-5dbe-a713-226a-8b3ae7fe646f.png)

#### Data

コピー先とする（新たに作成する）ファイル名を指定（入力）します。

### Response body

以下の通りフィールドを定義します。

|Name|Data type|
|:--:|:--:|
|kind |String|
|id |String |
|name|String|
|mimeType|String|

# 参考

https://developers.google.com/drive/api/v3/reference/files/copy
[Rails]renderメソッドとは?

##初めに
####なぜこの記事を書きたかったのか
最近やっとrenderで気づいたことがあったので言語化して記憶の定着のために書きたい！

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
**１）どんなことができるのか**
**２）どうやってつかうのか**
**３）オプション**
**４）自分が混乱していたこと**
**５）最後に**

##どんなことができるのか
####renderメソッドで指定したviewファイルへ移動もしくは配置することができる！
####renderメソッドはapp/viewsを起点としてパスを渡すと、渡したパスを出力してくれる!

####(例えば）
**1)このQiitaのページの上の緑色の部分を各viewファイルに一回一回コードを書くよりrenderを使えば、renderを使うことで一発で配置することができる！**
**2)DBへデータを追加保存するcreateアクションをしたあとの処理でrenderを使えば指定したviewへ遷移が可能になる。**

##どうやってつかうのか（renderで指定したファイルによって使い方が変わるから注意！）
####（同じフォルダーのファイルを配置したい場合→indexファイルにtopファイルを配置したい）

```erb
<%= render "ファイル名" %>
```

![samplerender2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/41f3416e-87bd-b0c4-62d5-bc462f5e7ade.png)

####（１）配置したいファイルの作成
![ samplerender3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/b63ce6f8-0fd9-f4ba-98f5-0f844b12e7f2.png)

####（２）配置したい場所にrenderを使う。
![ssamplerender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/ce22f0a2-1538-466b-58b5-8651f4cd3534.png)

####(別フォルダーのファイルを配置したい場合→indexファイルにheaderファイルを配置したい)

```erb
<%= render "フォルダー名/ファイル名 %>　　もしくは <%= render partial: "フォルダー名/ファイル名" %>
```

![samplepartialrender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/90b83a5e-a622-648a-0d2a-66a24a153ed6.png)

####（１）配置したいファイルの作成
![partialrendersample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/32f08820-c122-d401-eab2-308c2f4790c9.png)

####（２）配置したい場所にrenderを使う。
![partialrendersample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/d39137a2-b874-09e4-ebb7-61bb69069b56.png)

##(オプション)別のコントローラー配下にあるviewを出力してくれるオプション

```erb
<%= render template: "フォルダー名/ファイル名" %>
```
![sampletemplaterender2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/e0f27062-d703-929f-cabb-5d32d495cc48.png)
####1)別controllerにファイルを用意する。
![sampletemplaterender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/146997bb-89f5-a2a1-784e-50ebc179715e.png)
####（２）配置したい場所にrenderを使う。
![sampletemplaterender3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/50fbb60e-7fc8-18d1-a44c-3c7921da0b3f.png)

##（オプション）別のアプリケーション配下にあるviewを出力してくれるオプション
**例：furimaアプリケーションに別のアプリケーション（sample_app）のindex.html.erbを配置したい**

```erb
<%= render  file "u/apps/別のアプリケーション名/現在のアプリケーション/app/views/コントローラー名/配置したいviewのファイル名" %>
```

```erb
<%= render file: "u/apps/sample_app/current/app/views/products/index" %>
```

##（オプション）アクションを出力したいとき

```erb
<%=  render action: "アクション名" %>
```
##自分が混乱していたこと
####viewでrenderを使うときはview間の移動ができる、controllerでrenderを使うときはcontroller間で設定したアクションを使うことができると勘違いしてしまってた。

**アクションを使いたい場合はオプションをつけないと使えない！**
![rendersample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/547ac96f-f7f2-838b-1715-c23744af7e16.png)

##最後に
使う場所によってrenderの機能が変わると考えてしまい、思ったとおりに動いてくれない理解できないと考えることを避けてしまったけど、アウトプットできる場所があると自分への理解の手助けになるからいいなぁって思った！

ココまで読んでくださいましてありがとうございます！
Workato：Google Driveコネクターを利用してGoogle Drive内のファイルを検索する

Workatoでは、Google Driveコネクターを利用してGoogle Driveを操作することができます。
今回は、Google DriveコネクターによるGoogle Drive上のファイルやフォルダの検索手順について、以下の通りご説明します。

# 基本的な検索を行いたい場合

通常は「Search files or folders」アクションを利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/c88bb498-2b06-b34a-12e9-88c6d1754379.png)

## 設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/325becc9-a0db-b729-e31d-e617a64bbb35.png)

### Files or Folders
Files: ファイルを検索対象とします
Folders: フォルダを検索対象とします

### Folder
検索先とするフォルダを指定します。未指定の場合は全てのフォルダが検索対象となります。

### Name
検索したいファイルまたはフォルダ名を入力します。（部分一致）

その他のオプションについては、下記を参照ください。

https://docs.workato.com/connectors/google-drive/action-search-files.html

# 詳細検索を行いたい場合

MIMEタイプを指定した検索を行いたい場合や、全文検索を行いたい場合等、より詳細な検索を行いたい場合は、カスタムアクションで対応します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/7cc5935d-3a9b-5e69-6eb4-5fa64035ba85.png)

## 設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/3453c983-a38d-f190-8f95-af70383933df.png)

### Action name
任意の名称

### Method
GET

### Path
files

### Response type

JSON response

### Request URL Parameters

「Q」というSTRING型のフィールドを追加し、値（検索クエリ）をセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/fcea7401-2adb-2cb4-f4f3-35f4c2ddfc09.png)

検索クエリは、以下を参照ください。

https://developers.google.com/drive/api/v3/search-files

## Response body

「Use JSON」をクリックし、以下のJSONを利用して（コピー＆ペーストして）スキーマを作成します。

```
{
	"kind": "drive#fileList",
	"incompleteSearch": false,
	"files": [
		{
			"kind": "drive#file",
			"id": "string",
			"name": "string",
			"mimeType": "string"
		}
	]
}
```

JSONを利用したスキーマの作成手順は、以下を参照ください。

https://qiita.com/tabimoba/items/ce4215eda99b23d73828#%EF%BC%93output-schema%E3%82%92%E4%BB%A5%E4%B8%8B%E3%81%AE%E3%81%A8%E3%81%8A%E3%82%8A%E5%AE%9A%E7%BE%A9%E3%81%97%E3%81%BE%E3%81%99

なお、用途や条件によってはより多くのパラメータやスキーマが必要となる場合があります。
パラメータならびにレスポンススキーマのフォーマットの詳細は、以下を参照ください。

https://developers.google.com/drive/api/v3/reference/files/list

https://developers.google.com/drive/api/v3/reference/files#resource
github リポジトリをコピーする（コミットログも引き継ぐ）


https://qiita.com/takumiabe/items/639ae10025d086eb9ecb


```
コピー元リポジトリ：　repo1.git
コピー先リポジトリ：　repo2.git
（コピー先はブラウザで新規リポジトリ作成しておく）
```


```sh:コピー元リポジトリをミラークローン
git clone --mirror git@github.com:username/repo1.git
```

```sh:クローンしたディレクトリに移動
cd repo1.git/
```


```sh:remoteにotherとしてコピー先リポジトリ追加
git remote add --mirror=push other git@github.com:username/repo2.git
```

```sh:プルリク用？のrefがいるか確認
git show-ref
c96b935f0f260aefae0aae4dec11adc79da948bf refs/heads/hoge
f911ddb5423cb616795f0445dd0ee82ae78d26d8 refs/heads/master
c96b935f0f260aefae0aae4dec11adc79da948bf refs/pull/1/head
9e76fd5f566430c5cd53e761a3869b4971e5b78a refs/pull/1/merge
```

```sh:ref/pullをfetchの対象から外す
git remote set-branches origin 'heads/*
```

```sh:ref/pullを削除する
git for-each-ref --format="ref=%(refname)" --shell refs/pull | \
while read entry
do
  eval $entry
  git update-ref -d $ref
done
```

```sh:コピー完了！
git push other
```
【第２回】Confluent Platformのデモを試してみる(ブローカー編)

###概要
今回は、[第一回](https://qiita.com/Alex-hiro/items/0209b2faec9c00cf3ca1)で構築したConfluentのクラスタを利用しConfluent Control Centerにログインしてブローカーの状態をGUIで確認してみたいと思います。

###Confluent Control Centerにログイン
１.以下のURLにWebブラウザからコンフルエントコントロールセンターGUIにアクセスします。

```sh
http://localhost:9021
````

２.次にログイン画面が表示されますので、ここで、クラスターへのスーパーユーザーアクセス権を持つ"superUser"とパスワード"Confluent"でControlCenterにログインします。
![スクリーンショット 2021-09-22 14.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/ceb36135-f497-ea9b-c17e-aaa039c5d4d5.png)

###ブローカー
１.HOME画面で"Kafka Raleigh"という名前のクラスターを選択します。
![スクリーンショット 2021-09-22 15.00.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/e03c215c-2ee6-d26f-7d45-4c7f456aa70a.png)
２.「ブローカー」をクリックすると、クラスター内のブローカーのステータスが表示されます。
![スクリーンショット 2021-09-22 16.10.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/1981e4ef-3256-f990-90da-4b5dbb98dd32.png)
３.[Production]または[Consumption]をクリックします。ここではProductionとConsumptionの指標を確認できます。例えば、ブローカーの稼働時間、パーティションの状態、ディスク使用率、システム（ネットワークプールの使用状況、リクエストプールの使用状況）などが表示されました。
![スクリーンショット 2021-09-22 16.21.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128268/7545c289-0fa1-ab40-ff24-55cca6817b97.png)

ここまでで、ブローカーの状態をConfluent Control Center(GUI)から確認することができました。

###おわりに
Kafka/Conflunetを構築した後の運用段階では監視メトリクスがGUIで確認できるとわかりやすいと感じたので、このGUI(Confluent Control Center)をもう少し見てみようと思います。
次回は、トピックにフォーカスして見ていきたいと思います。
Workato：レシピをJSONで取得するには

# はじめに
Workatoのレシピのメンテナンスを行う際、過去のバージョンのレシピやコピーしたレシピと差分比較したくなる場合がありますが、残念ながらWorkatoには現時点(2021/9/28)において差分比較(diff)を行う機能がありません。（以前はWorkato XというChrome機能拡張で差分比較を行うことができましたが、機能拡張がWorkatoのアップデートに対応できておらず、現在は利用することが出来ません）

しかし、幸いなことにWorkatoのレシピは、レシピエディタの画面生成時に参照されるURLよりJSONで取得することが可能です。このJSONを利用することで、過去バージョンのレシピやコピーしたレシピとの差分比較が可能となります。今回は、その手順について下記します。

# 手順
## １．Workatoへログインした状態で、Chrome等のDeveloper ToolのConsoleで以下のコードを実行します。

```
let result = {};
const recipeId = <レシピID>;
const version = <レシピバージョン>;

fetch('https://app.workato.com/recipes/' + recipeId + '/code.json?version_no=' + version)
        .then(res => res.json())
        .then(obj => JSON.parse(obj.result))
        .then(obj => {console.log(obj)});
```

### ※全バージョンを一気に取得したい場合
レシピの全バージョンを一気に取得したい場合は、次の通りとします。

```
let result = [];
const recipeId = <レシピID>;
const maxVersion = <レシピ最新バージョン>;
for (let i = 1; i <= maxVersion; i++) {
    fetch('https://app.workato.com/recipes/' + recipeId + '/code.json?version_no=' + i)
        .then(res => res.json())
        .then(obj => JSON.parse(obj.result))
        .then(obj => result.push({version: i, result: obj}));
}
```

上記実行後、以下のコードを実行します。

```
console.log(result);
```

## ２．出力結果を右クリックし「Copy object」をクリックすると、JSONでレシピを取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/9276f2f2-7319-4397-78ad-4a5d647e8b10.png)
【Ruby】配列（数値）を大小で並び替えて◯番目を抽出する

# やったこと

```ruby
i = [4, 18, 25, 20, 9, 13] #変数に配列を代入
p = i.sort.reverse #.sortはデフォルトで昇順（小→大）のため、.reverseで降順（大→小）に変更
puts p[2] #3番目に大きいものを表示
```

.reverseで降順にすることで、
配列の数に関わらず、大きいものから３番目が抽出できます。
STM8で800KHzを作る


x STM8S-Discovery ボード

目的
ws2812bを光らせたい、もっと光らせたい
GPIOのテスト

```c++


void setup() {
  pinMode(PD0, OUTPUT);
}

#define PD_ODR *(volatile uint8_t *)0x500F

void loop() {

  while(1){ //1.25uS
    PD_ODR = 0b00000001; //1
    PD_ODR = 0b00000001; //2
    PD_ODR = 0b00000001; //3
    PD_ODR = 0b00000001; //4
    PD_ODR = 0b00000001; //5

    PD_ODR = 0b00000000; //1
    PD_ODR = 0b00000000; //2
    PD_ODR = 0b00000000; //3
    PD_ODR = 0b00000000; //4
    PD_ODR = 0b00000000; //5

  }//while

/*

//char *p;
//p=0x804845c;
//*p=0x23;

  while(1){
    //digitalWrite(PD0, HIGH);
    //PB_ODR ^= 0x01;
    //PA_ODR_ODR0 = 0;
    PD_ODR = 0b00000001;
    //                     //76543210
    //GPIO_Write ( GPIOD,  0b00000001 );
    delay(200);
    //digitalWrite(PD0, LOW);
    //PB_ODR ^= 0x01;
    //                     //76543210
    //GPIO_Write ( GPIOD,  0b00000000 );
    PD_ODR = 0b00000000;
    delay(200);
  }//while

*/

}


```
vacuumを実行しても不要行が削除されない場合の対処法

#背景
PostgreSQLを使用しているのですが、本番環境でパフォーマンス劣化が発生しました。
調査の結果、autovacuumは動いているのですが、不要行の削除が行われず空振りしている状態でした。

#環境
DB:Amazon Aurora for PostgreSQL 10.16

#vacuum・analyzeの状況確認
##SQLで現状の情報を取得する
[こちら](https://qiita.com/kaburankattara/items/79e102d7c1f9b8241e5e#vacuumanalyze%E3%81%AE%E7%8A%B6%E6%B3%81%E7%A2%BA%E8%AA%8D)の記事で利用したSQLで各テーブルのvacuum状況を確認します。

```sql
SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
FROM pg_stat_all_tables
WHERE schemaname = 'hogeschema'
ORDER BY relname
```

実行した結果、last_autovacuumカラムに直近の日付が表示されているにも拘らず、
n_dead_tupカラムの不要行数が異常に多い状態でした。

##vacuum実行時の詳細を取得
vacuumにVERBOSEパラメータを指定してVACUUM対する詳細を取得します。

```sql
hogedb=> VACUUM (VERBOSE, ANALYZE) hogetable;
INFO:  vacuuming "hogeschema.hogetable"
INFO:  index "hogetable_pkc" now contains 8476 row versions in 35 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  "hogetable": found 0 removable, 99226 nonremovable row versions in 1711 out of 1711 pages
DETAIL:  99198 dead row versions cannot be removed yet, oldest xmin: 134763458
There were 86 unused item pointers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
INFO:  analyzing "hogeschema.hogetable"
INFO:  "hogetable": scanned 1711 of 1711 pages, containing 28 live rows and 99198 dead rows; 28 rows in sample, 28 estimated total rows
VACUUM
```

上記より、不要行は99198行あるが一番古いトランザクションID「134763458」があるため削除出来ないとのこと。

#古いトランザクションIDについて
色々と調べていると、[こちら](https://yakst.com/ja/posts/5174)のページより、
古いトランザクションが有効な状態で残っているとVACUUMを実行しても不要行を削除しなくなるようです。

下記SQLを実行してvacuumをブロックしているデータベースセッションを確認しました。
結果、vacuumの詳細に記載されていたものと同じトランザクションIDがactive状態で存在していることが確認出来ました。

```sql
SELECT pid, datname, usename, state, backend_xmin
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL
ORDER BY age(backend_xmin) DESC;
```

vacuumをブロックしているデータベースセッションを終了させてみました。
※ユーザー操作で本当に利用中かもしれないため、実行は稼働時間外に行いました。
pg_terminate_backend()の引数には上記SQLで取得出来たプロセスIDを指定します。

```sql
select pg_terminate_backend(23398);
```

#再度、vacuumを実行してみると
上記、手順でデータベースセッションを終了させた後に再度vacuumを実行すると無事に不要行が削除されていました。

#参考文献

https://yakst.com/ja/posts/5174

https://www.postgresql.jp/docs/10/sql-vacuum.html
iOS15でATT(App Tracking Transparency)の許可ダイアログが表示されない場合に確認すること

iOS15でATT(App Tracking Transparency)の許可ダイアログが表示されてないよ、という理由でアプリがリジェクトされました。

どうやら

```swift
requestTrackingAuthorizationWithCompletionHandler
```
の挙動が少し変わっているようです。

https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/3547037-requesttrackingauthorizationwith

今回のアプリではdidFinishLaunchingWithOptionsの最後に上記のメソッドを呼び出して、起動時にATT許可のダイアログを出そうとしていました。
しかしiOS15での変更により、アプリがアクティブなとき（UIApplicationStateActive）にのみApp Tracking Transparencyの許可リクエストを行う必要があるようです。

したがって起動してすぐ出したい場合はdidBecomeActiveやsceneDidBecomeActiveなどアプリがアクティブなとき（UIApplicationStateActive）に変更しましょう。
※ リクエスト前にtrackingAuthorizationStatusで値を確認してNotDeterminedの場合にのみリクエストする

例)

```swift:AppDelegate.swift
func applicationDidBecomeActive(_ application: UIApplication) {
    if ATTrackingManager.trackingAuthorizationStatus == .notDetermined {
        ATTrackingManager.requestTrackingAuthorization { _ in }
    }
}
```


プライバシーの許可ダイアログを連続して表示しているようなアプリの場合にはとくに注意が必要で、プライバシーの許可ダイアログが表示されたときは一時的にアプリが非アクティブ状態になっているため、iOS15だと今までのように許可ダイアログが表示されないことがあります。
ワークアラウンドとしてDispatchQueue.main.asyncAfterなどで少しだけ遅延させてリクエストする方法も見られますが、
本質的な解決ではないため、理想的にはそのアクセスが必要なタイミングで許可ダイアログを表示するようにフローを変更するのが良さそうです。
[ASP.NET][EF6]EntityFramework6.Npgsql.dllがbinに配置されない

# 環境・前提

- ASP.NET MVC 5（Coreではない、.NET Framework）
- VB.NET
- Entity Framework 6 + EntityFramework6.Npgsql
- Npgsqlは[Web.configで設定](https://www.npgsql.org/ef6/index.html)している。

# ソリューション構成

Webプロジェクト（メインプロジェクト）
　↓参照
BusinessLogicプロジェクト
　↓参照
Entityプロジェクト
　↓参照
EF6+Npgsql

# 障害内容

Webプロジェクトでは直接使用していないEF6+Npgsqlへの参照設定があった為、参照を削除したところ、ビルドは通るのに、MyDbContextクラスのコンストラクタでSystem.InvalidOperationException の実行時例外が発生するようになった。

発生した例外

> System.InvalidOperationException: 'The Entity Framework provider type 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' registered in the application config file for the ADO.NET provider with invariant name 'Npgsql' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.'

発生箇所:

```VB:MyDbContext.vb
    Public Sub new()
        MyBase.New("name=MyDbContext") 'ここで例外発生
    End Sub
```

# 原因および検討事項

- **EntityFramework6.Npgsql.dllがASP.NETサイトのbinフォルダに配置されなくなっている。**
- EntityFramework6.Npgsqlの機能はソースコード上から直接参照するものではなく、Web.configで動的にロードされるものである為、コンパイラがDLLの必要性を判別できず、配置されなかったものと思われる。
- EntityプロジェクトへのEntityFramework6.Npgsql.dllへの参照追加設定はしてあり、ローカルコピー設定もTrueになっているが、それでもbinフォルダに配置されていない。
- Webプロジェクト（メインプロジェクト）へEntityFramework6.Npgsql.dllの参照設定を行えば強制的にbinフォルダにコピーされる模様。
- しかし、WebプロジェクトではEF6は使っていないし、使わせたくもないので、ここへ参照設定を追加するのは避けたい。

# 解決策

- **ソースコード上でEntityFramework6.Npgsql.dllへの参照がハードコーディングされていれば、コンパイラが依存関係を認識してくれるはず。**
- 現状、EntityFramework6.Npgsql.dllに最も近いのはEntityプロジェクトなので、そこに上記のダミーコードを挿入すれば良い。
- 本音を言うと、Entityプロジェクト自体も表向きNpgsqlに依存しているわけではない（データプロバイダとしてEF6が背後で動的ロードしているだけ）なので、ここにそんなダミーコードを追加するのも嫌だが、Webプロジェクトに無意味な参照が追加されるよりはマシと判断。

以下のファイルをEntityプロジェクトに追加した。

```vb:ResolveReferenceToEF6Npgsql.vb
Module ResolveReferenceToEF6Npgsql
    '意味のないコードだが、これを書かないと、コード上に参照がない為DLLがASP.NET環境に配置されない。
    Private __hack As Boolean = Npgsql.NpgsqlServices.Instance IsNot Nothing
End Module
```

C#だとこんな感じになると思われる。

```C#:ResolveReferenceToEF6Npgsql.cs
class ResolveReferenceToEF6Npgsql {
    // 意味のないコードだが、これを書かないと、コード上に参照がない為DLLがASP.NET環境に配置されない。
    private static bool __hack = (Npgsql.NpgsqlServices.Instance != null);
}
```

# 結果

WebプロジェクトからEF6+Npgsqlへの参照設定も問題なく削除し、正しく動作することを確認した。

本当は、プロジェクト設定に「このDLLに依存しているので、公開時に絶対に一緒に配置する」というオプションがあればよいと思うが、そういう設定を見つけられなかった。

試したけどダメだったもの一覧。

1. Web.configのsystem.web - compilation - assemblies - add に EntityFramework6.Npgsqlを追加
2. Web.configのruntime - assemblyBinding - dependentAssembly に EntityFramework6.Npgsql を追加
【Ruby】ハッシュの中のハッシュの値を取り出す方法

下記のようなハッシュがあった際、punch_inの中のdateの値を取り出したい

```
hash = { 
Fri, 01 Jan 2021=>
  {:punch_in=>
     id: 2314,
     date: Fri, 01 Jan 2021,
   :punch_out=>
     id: 2315,
     date: Fri, 01 Jan 2021,
   }
}
```

##やり方
1. ハッシュからvaluesだけを取り出し配列の形にする


```
arr = hash.values

#=>
[{:punch_in=>
    id: 2314,
    date: Fri, 01 Jan 2021,
  :punch_out=>
    id: 2315,
    date: Fri, 01 Jan 2021
 }]
```

2. 配列から取り出す

```
puts arr[0][:punch_in][:date]

#=> Fri, 01 Jan 2021
```

##参考

https://qiita.com/komiso/items/770e88e0754876f3156b
Windows10にNetBeans12.5をインストール（備忘録）

#はじめに
Wndows10にApache Netbeansをインストールした時の備忘録です。下記を行いました。
　・Netbeansの基本的なインストール
　・Mavenの構成

#基本的なインストール
基本のインストールはこちらのページにお世話になりました。

https://www.doraxdora.com/blog/2020/08/06/post-12450/

<!--
・OpenJDK 17のインストール
NetBeans12.5が対応しているOpen JDKは17になります。[こちら][jdk]からインストールして下さい。
[jdk]:https://jdk.java.net/17/
-->

・本体のインストール
[Apache Netbeans リリースページ][download]から12.5を選択し、ダウンロードします。2022年2月頃にLTSが出る予定だそうです。
[download]:https://netbeans.apache.org/download/index.html

・日本語化
今回は諸事情で日本語化はしなかったのですが、日本語化は[junichi11/netbeans-translations-ja][japanese]プラグインで出来るそうです。
[japanese]:https://github.com/junichi11/netbeans-translations-ja/releases/tag/v0.0.2

#Mavenのインストール
Mavenの基本知識と、Mavenのインストール・構成はこちらのページにお世話になりました。

https://qiita.com/ASHITSUBO/items/6c2aa8dd55043781c6b4

https://netbeans.apache.org/tutorials/nbm-maven-quickstart_ja.html

・Mavenインストール
[Apache Mavenのページ][maven]から、バイナリ（apache-maven-3.8.2-bin.zip）をダウンロードしインストールをします。
[maven]:http://maven.apache.org/
[mavencheet]:http://maven.apache.org/plugins/index.html

・Maven Path通し
こちらのページを参考にしました。

https://www.javadrive.jp/start/install/index4.html

apache-maven-3.8.2-bin.zipを解凍し、適切なフォルダに配置します。今回はC：直下に置きました。apache-maven-3.8.2/binを上記のページを参考にし、環境変数のPathに加えます。

パスが通っているか、`mvn -v`で確認しましょう。

```
C:\>mvn -v
Apache Maven 3.8.2 (ea98e05a04480131370aa0c110b8c54cf726c06f)
Maven home: C:\apache-maven-3.8.2
Java version: 16.0.1, vendor: Oracle Corporation, runtime: C:\jdk-16.0.1
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
```

NetBeans上でもMavenが適切に設定されているか確認します。設定されている気がする。
![maven.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221234/76fb7d31-5e6a-3f12-e9fa-264d7e3c2a7a.png)




#おわりに
Windows10にNetBeans12.5をインストールしてみました。
今、JDK16.0なのですが、公式ではJDK17を推奨しているようです。問題が出たら適宜またページを更新していきます。
[Ruby] AtCoder過去問 B - 美しい文字列

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc044/tasks/abc044_b

##B - 美しい文字列
まずは入力を受け取ります。

```ruby
w = gets.chomp.chars
```

一文字ずつ分けて、配列として受け取ります。
入力例1でいえばこのように受け取れているはずです↓
```["a", "b", "a", "c", "c", "a", "b", "a"]```

countメソッドでそれぞれの文字が配列wの中にいくつあるか調べ、それが偶数個なのかどうかeven?メソッドで調べます。

さらに、全ての種類の文字が偶数個ないといけないので、all?メソッドで上記の条件が全て真の時にtrueを返すようにします。trueであればYesを出力させ、falseならNoを出力させます。

配列wで使われている文字の種類は```w.uniq```で表現します。

```ruby
w = gets.chomp.chars
 
if w.uniq.all?{ |s| w.count(s).even?}
  puts "Yes"
else
  puts "No"
end
```

これで完成です。

このコードを短くしようと試みました。↓

```ruby
w = gets.chomp.chars.sort

puts (w.uniq.all?{ |s| w.count(s).even?}) ? "Yes" : "No"
```

あまりこの書き方をしないのですが、1行でかけました。
わかりやすさ的には初めの方が好きです。
RaspberryPi4の高速化（オーバークロック）

ラズパイ4を高速化する必要に迫られたので、
オーバークロックするために、config.txtを書き換えたのでメモ．

# 環境
ubuntu 18.04.05LTS
raspberry pi 4

# config.txtを修正

オーバークロックは意外と簡単で、config.txtを変更すれば良い

以下のファイルを、vimでもgeditでもnanoでもいいのでエディタで開いて末尾に追加する．

/boot/firmware/config.txt

```bash
over_voltage=(-16～8の整数,　default: 0)
arm_freq=(最大周波数MHz, default: 1200)
arm_freq_min=(最小周波数MHz, default: 600)
gpu_freq=(GPU周波数MHz, default: 500)
force_turbo=1 # (いるか分からない）
```

その後再起動すれば、設定が反映される．

# 例

私の環境では以下のようにしたところ、
ラズパイ4の性能をかなり引き出せた．
ただし、電力はかなり食うので、供給できる電源を選ぶ必要はありそうである．
参考までに

```bash
over_voltage=6    #(-16～8の整数,　default: 0)
arm_freq=2100     #(最大周波数MHz, default: 1200)
arm_freq_min=1800 #(最小周波数MHz, default: 600)
gpu_freq=600      #(GPU周波数MHz, default: 500)
force_turbo=1     #(いるか分からない）
```

# 参考
[ラズベリーパイのCPUクロックと電圧をいじってみる](http://www.ezto.info/stpress/2017/05/976.html)
[RasPi 入門 (9) - RasPi4をオーバークロックする方法](https://note.com/npaka/n/n286b2979fdc2)
本番環境のDBを間違ってドロップした話

これは今からX年前にとある場所で本番環境のDBを間違ってドロップ（削除）した時の話です:innocent:

# やらかした事
これはもうタイトル通りですね、本番環境のDBを間違えてドロップしてしまいました。

# やらかした原因
こちらの方が皆さん気になると思いますが、当時の環境としては以下の通りです。

- OS:Windows環境
- DB:IBM Db2
- DBへの接続方法:自分のWindowsPCからDb2のクライアントを使用しサーバー（Db2）へ接続
似ているイメージとしては、SSHでDB（MySQLやPostgreSQL）に繋いでいるような感じです。

作業していた内容としては開発環境にデータを流し込んで確認、上手くいっていないのでDB毎ドロップして再度やり直し。って事をしつつ、一方で本番環境にも繋いでデータを見ていました。つまり、開発環境と本番環境の双方に接続しそれぞれの環境を行ったり来たりしていた訳です。ここまで聞けば、間違えるのも当たり前って感じですね！当然のように、本番環境を開発環境と間違えてDBをドロップした後に「あ、今の本番環境だ」って気がつきました:innocent:気がついた時には手がCommitもしてましたから、どうにもなりません。綺麗さっぱりドロップされてしまいました。
幸いだったのが、本番環境といってもまだ試験的に使われている段階だったのでDB毎豪快にドロップしても影響はほとんど無かった事です。当時の僕は慌てて上長に間違ってドロップしてしまった旨を報告しにいき、データの再投入をしてもらって事なきを得ました。その時に思ったのは、この作業の仕方だとまた絶対にやらかす、という事です。
ちなみに2つの環境を行き来しながら作業し、作業ミスからの障害というのはDMMでも何度か聞いた事があります:innocent:やむも得無い場合もありますが、こういった作業をしているとミスしやすいという事は頭の片隅に入れておいて貰えると嬉しいです。

# 当時考えた再発防止策
特に怒られたりもせず、障害報告書も記載はしませんでしたが個人的にこんな失敗は2度とごめんだと思ったので、再発防止を考えました。当時考えた案は以下の通りです。

- 面倒だけど、二つの環境へ同時に接続しない（本番なら本番、開発なら開発と一つの環境で作業する）
- SQLをその場で入力しない（当時の業務内容から、その場でクエリを色々と試す必要がある仕事ではなかったので、SQLを実行したい場合にはあらかじめSQLを秀丸などのエディタで記載しておき、それをコピペして実行することにしました）
- 開発環境で試したSQLを本番環境で実行する（上の対策と組み合わせて使いました。事前に確かめられているSQLのみを実行することで不慮の事故を防ごうと思いました）

これらの再発防止策で当時はやらかしを防げました。この後、本番環境のデータをちょくちょく更新して欲しいと言われたのでデータ更新ツールを作ったりしたのですが、それはまた別のお話。

# まとめ
異なる環境に同時に接続して作業する時は気をつけて！（マジで）
Github Actionsでプルリクを自動マージ

# 概要
- 送られてきたプルリクをとにかく自動マージするGithub Actionsを書きました
- なかなか需要は無い気もしますが、せっかく書いたので共有します

```yml
name: Auto merge

on:
  pull_request_target:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: merge PR
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh pr list | while read line; do gh pr merge `echo $line|awk '{print $1}'` -m; done
```

# はまりどころなど
- トリガーが `pull_request` だと、フォーク先からのプルリクの時にフォーク先ユーザの実行となってしまうようです。それにより、GITHUB_TOKENの取得がうまく行きません。それを回避するために、 `pull_request_target` をトリガーにしました
- マージには Github Cliを利用しました。
  - https://cli.github.com/manual/
- 最後のワンライナー頑張りました（笑）
Python RequestsモジュールでのJSONDecodeError

# 概要

- PythonのRequestsモジュールを利用して、APIレスポンスを取得しようとしたが`JSONDecodeError`になり、うまく取得できなかった。
- レスポンスがHTMLなのにJSONに変換しようとしていたことが原因。
- とりあえず、Unicodeに変換したらちゃんと取得できた。

# もうちょっと詳しく

**エラーが出た。。。なぜ？**

以下のように`requests.request`でResponseを取得して`r.json()`でJSONに変換した。

```python
r = requests.request(method, URL, heasers=headre, data=data)
return r.json()
```

そうすると下記のエラーが出た。。。
`JSONDecodeError, Expecting value: line 1 column 1 (char 0)`

色々試したところ、`requests.request`で取得したResponseオブジェクト`r`がHTMLだということがわかった。

**対処！！**
`requests.request`で取得したrequests.ResponseオブジェクトをUnicodeに変換。

```python
r = requests.request(method, URL, heasers=headre, data=data)
return r.text()
```

これでとりあえずHTMLを取得できた。

Beautiul Soupを利用すると、さらにHTMLからうまいことデータを抽出できるらしい。試していませんが、興味ある方は参考に載せたサイトをどうぞ。

# 参考
- Requetsモジュール仕様

https://requests-docs-ja.readthedocs.io/en/latest/api/

- Beautiul Soupについて

https://qiita.com/Chanmoro/items/db51658b073acddea4ac
iOS 15 でナビゲーションバー、タブバーなどの色が変わらない場合

### iOS 15からAppearanceの設定方法が追加された

[scrollEdgeAppearance](https://developer.apple.com/documentation/uikit/uitoolbar/3752214-scrolledgeappearance/)　このプロパティに対しても設定を行います。

従来の記述に加えてこういう記述が必要です。

```swift
if #available(iOS 15.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.backgroundColor = .black
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
        
if #available(iOS 15.0, *) {
    let appearance = UITabBarAppearance()
    appearance.backgroundColor = .black
    UITabBar.appearance().standardAppearance = appearance
    UITabBar.appearance().scrollEdgeAppearance = appearance
}


```
URLとタイトルをコピーするブックマークレット（IE非対応）

現在のページのURLとタイトル、選択範囲テキストをコピーするブックマークレット（IE非対応）を作成。テキスト形式版は以下のような形式でコピーされる。

```text
タイトル
URL
選択範囲テキスト
```

Markdown形式版は以下のような形式でコピーされる。

```markdown
[タイトル](URL)
選択範囲テキスト
```

# 現在のページをコピー（テキスト形式）

```javascript
javascript:(function copyToClipboard(text) {var d=document,k=d.getSelection,x=d.selection,e=window.getSelection,s=new String(e?e():(k)?k():(x?x.createRange().text:0)),a=d.title+"\n"+d.URL+(s.length?"\n"+s:"");return navigator.clipboard.writeText(a).then(function() {alert('コピーしました')}).catch(function(error) {alert((error && error.message) || 'コピーに失敗しました')})})();
```

改行削除前のコードは以下。

```javascript
javascript:(
function copyToClipboard(text) {
  var d=document,k=d.getSelection,x=d.selection,e=window.getSelection,s=new String(e?e():(k)?k():(x?x.createRange().text:0));
  var t=d.title+"\n"+d.URL+(s.length?"\n"+s:"");
  return navigator.clipboard.writeText(t).then(function() {
    alert('コピーしました')
  }).catch(function(error) {
    alert((error && error.message) || 'コピーに失敗しました')
  })
}
)();
```

以下のような形式でコピーされる。

```text
タイトル
URL
選択範囲テキスト
```

# 現在のページをコピー（Markdown形式）

```javascript
javascript:(function copyToClipboard(text) {var d=document,k=d.getSelection,x=d.selection,e=window.getSelection,s=new String(e?e():(k)?k():(x?x.createRange().text:0));var t="["+d.title+"]("+d.URL+")"+(s.length?"\n"+s:"");return navigator.clipboard.writeText(t).then(function() {alert('コピーしました')}).catch(function(error) {alert((error && error.message) || 'コピーに失敗しました')})})();
```

改行削除前のコードは以下。

```javascript
javascript:(
function copyToClipboard(text) {
  var d=document,k=d.getSelection,x=d.selection,e=window.getSelection,s=new String(e?e():(k)?k():(x?x.createRange().text:0));
  var t="["+d.title+"]("+d.URL+")"+(s.length?"\n"+s:"");
  return navigator.clipboard.writeText(t).then(function() {
    alert('コピーしました')
  }).catch(function(error) {
    alert((error && error.message) || 'コピーに失敗しました')
  })
}
)();
```

以下のような形式でコピーされる。

```markdown
[タイトル](URL)
選択範囲テキスト
```

# おわりに

だいぶ昔に `タイトル URL - 選択範囲テキスト` とか `[タイトル](URL) - 選択範囲テキスト` でコピーするブックマークレットを作って頻用してたけど、改行区切りにしたいなと思ってた。「[JavaScript でクリップボードにテキストをコピーする (2021年版) | MSeeeeN](https://mseeeen.msen.jp/copy-text-to-clipboard-with-javascript-in-2021/)」でIEを切り捨てればClipboard APIで改行込みテキストのコピーが簡単にできるらしいと知ったので、IE非対応で割切って作り直し。Microsoft Edgeでは使えてます（というかEdgeでしか試してないです）。選択範囲の取得は昔のブックマークレットからの転用で、これもそもそもどこかで紹介されてたコードを転用したものでした。出典を忘れてしまったけど、先人には多々感謝。

# 参照

* [JavaScript でクリップボードにテキストをコピーする (2021年版) | MSeeeeN | 大阪発 IT メディア by MSEN](https://mseeeen.msen.jp/copy-text-to-clipboard-with-javascript-in-2021/)
* [Navigator.clipboard - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Navigator/clipboard)
さっきまで動いてたのに、docker-compose up がうまく行かなくなり "Can't connect to MySQL server on 'db' (115)" と言われた

#エラー
>
root@........ :/code# python manage.py makemigrations
/usr/local/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py:109: RuntimeWarning: Got an error checking a consistent migration history performed for database connection 'default': (2002, "Can't connect to MySQL server on 'db' (115)")

などと言われ、dbサーバのbashに入ってデータベースの中身を見てみると、、、

```bash:bash(mysql)
mysql> use django_docker
Database changed
mysql> show tables;
Empty set (0.00 sec)
```

何もなかった！

#解決法

ということでリセットしてみようと思いました。
migrations/　を \_\_init\_\_.py を残し削除。そして \_\_pycache\_\_/ の中身は全削除。dockerのイメージをとりあえず削除。

以下のコマンドを実行し、すべてをやり直してみた。

```bash:ターミナル
nodaken@MacBook-Pro-kun project % docker-compose build 
nodaken@MacBook-Pro-kun project % docker-compose up db -d 
nodaken@MacBook-Pro-kun project % docker-compose up web -d 
nodaken@MacBook-Pro-kun project % docker-compose exec web bash #dbサーバではなくwebサーバ

root@... :/code# python manage.py makemigrations 
root@... :/code# python manage.py migrate
root@... :/code# exit

nodaken@MacBook-Pro-kun project % docker-compose restart
```

してみると復活しましたとさ。

#コピペ
↓コピペ用

```bash:macで
docker-compose build && docker-compose up db -d && docker-compose up web -d && docker-compose exec web bash
```

```bash:bash(webサーバ)で
python manage.py makemigrations && python manage.py migrate && exit
```

```bash:macで
docker-compose restart web
```
resasの研究

#概要

官製オープンデータ基盤のresasを、研究してみる。

#方針

sdgsの視点、社会起業家の視点で、研究してみる。

#サンプルコード

d3でapiを、叩いてみた。

```

d3.request("https://opendata.resas-portal.go.jp/api/v1/prefectures").header("X-API-KEY", "***").mimeType("application/json").response(function(xhr) { 
  return JSON.parse(xhr.responseText) 
}).get(function(data) {
  console.log(data)
  var items = data.result;
  var keys = ["prefCode", "prefName"];
  var table = d3.select("body").append("table").attr("border", "1")
  table.append("thead").append("tr").selectAll("th").data(keys).enter().append("th").text(function(d) {
    return d;
  });
  for (var i = 0; i < items.length; i++)
  {
    var rows = [];  
    keys.map(function(c) {
      rows.push(items[i][c])
    });
    table.append("tbody").append("tr").selectAll("td").data(rows).enter().append("td").text(function(d) {
      return d;
    });
  }
});


```

以上。
月数の計算をする式

案外ニーズがあるみたいです。

基本的な考え方は年、月、日　に分けて計算します。また日にちの差で少々調整が必要ですね。

この例は15日以上の日付の間隔があいていれば、１か月プラスします。

```
((YEAR(termination_date__c) - YEAR(ad_installed__c)) * 12) + (MONTH(termination_date__c) - MONTH(ad_installed__c)) + IF (ABS(DAY(termination_date__c) - DAY(ad_installed__c)) => 15, 1, 0) 
```

[Formula Field calculating wrong value](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000BsNZq)


# 何週目かを計算する

[Calculating Case age- without weekends](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A7kSrSAJ)

```
CASE(MOD(Datevalue(CreatedDate) - DATE(1985,6,24),7),
0 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),
1 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),
2 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),
3 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),
4 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),
5 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),
6 , CASE(MOD(Datevalue(ClosedDate) - Datevalue(CreatedDate) ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),
999)

+ (FLOOR((ClosedDate - Datevalue(CreatedDate))/7)*5)

-

IF(OR(
NOT(MOD( Datevalue(CreatedDate) - DATE (2000 ,1, 1) ,7)=0),
NOT(MOD( Datevalue(CreatedDate) - DATE (2000 ,1, 1) ,7)=1)), 1, 0)), 

(CASE(MOD(Datevalue(CreatedDate) - DATE(1985,6,24),7),
0 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),
1 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),
2 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),
3 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),
4 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),
5 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),
6 , CASE(MOD(Today() - Datevalue(CreatedDate) ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),
999)

+ (FLOOR((Today() - Datevalue(CreatedDate))/7)*5)

-

IF(OR(

NOT(MOD( Datevalue(CreatedDate) - DATE (2000 ,1, 1) ,7)=0),
NOT(MOD( Datevalue(CreatedDate) - DATE (2000 ,1, 1) ,7)=1)), 1, 0)))
```
VisualStudio 2022 PreviewでgRPCのデバッグができないとき

# 概要

* C#でgRPCの開発をしている時に、VisualStudio 2022 Previewだとデバッグできない
 * デバッグすると例外が出る
 * が、ビルドしたものをVS外から実行すると動く
* 同じProjectでもVisualStudio 2019ではデバッグできる
* オプションの「CSSのホットリロード」をfalseにすると例外が出なくなる

# 環境

* Windows10 64 bit
* Visual Studio 2022 (Version 17.0.0 Preview 4.1)

# 詳細

VisualStudio 2022でgRPCのServer/Clientのプロジェクトを作る。

gRPCのデバッグをしたところ、クライアント側で以下のような例外が出てgRPC Callが失敗する。

`Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Failed to deserialize response message.")`

でも、ビルドしてできた.exeをVisualStudio外から直接実行すると問題なく実行できる。
ServerはVS外から、ClientはVSのデバッグから実行すると問題なく実行できる。

例外のメッセージググったところ以下の記事がHitしました。

https://developercommunity.visualstudio.com/t/unable-to-debug-grpc-server-code-with-preview-3/1503691

どうも少なくともPreview3から確認されている不具合らしい。

# 回避策

1. `Environment.SetEnvironmentVariable("ASPNETCORE_PREVENTHOSTINGSTARTUP", "true");` を Program.csの最初の方に加える。

:::note info
※ こっちは実施していないので未検証
:::

1. 「CSSのホットリロード」を`false`にする

`メニュー ＞ ツール(T) ＞ オプション... `
でオプションダイアログを開き、
左側から `プロジェクトおよびソリューション ＞ ASP.NET Core`を選択し、
右側のプロパティーの`ホットリロード ＞ CSS変更をホットリロード`を`false`に変更。

※ 特にVisualStudio自体の再起動は不要な模様

次回のデバッグ起動からgRPCのクライアントが例外を吐かなくなります。

これでgRPCのプロジェクトもサクサクデバッグできますね！
Swift Package Manager 活用時に「remote repository could not be accessed」が出た時に確認すること

## 概要
Swift Package Manager を導入しようとしたらエラーが出て進めませんでした、、
ググってもあまりドキュメントが出てきませんでしたので、解決策を共有します。

## 再現環境
Xcode12.5.1
zsh

## Swift Package Manager とは？
Xcode11 からiOS向けアプリでも活用可能になった、依存関係を解決しつつライブラいの導入ができるApple製のパッケージ管理ツールです。
この辺の資料が分かりやすいです。
https://qiita.com/hironytic/items/09a4c16857b409c17d2c


## エラー内容
今回起きたエラーはXcodeの「File > Swift Packages > Add Package Dependency」から `https://` 指定でプライベートなライブラリをURL検索した際に発生しました。

内容は下記の通りです
```
The remote repository could not be accessed.
Make sure a valid repository exists at the specified location and that the correct credentials have been supplied.
```

![スクリーンショット 2021-09-28 9.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50890/26af6987-27ad-ff5f-020e-44430bf9b9de.png)

## 確認すること
1. まずURLがちゃんと合っているか確認しましょう。そもそも存在しないレポジトリの可能性があります。
2. 続いてXcodeにちゃんとGithubアカウントが紐づいているか確認しましょう。[こちらの記事](https://zenn.dev/kueharx/articles/ebd14c46f02211)が参考になります。
3. それでもダメであれば、`.gitconfig` ファイルを確認しましょう。←僕の場合これでした。

## .gitconfig からURL解決の記述をコメントアウトする
`~/.gitconfig` か `{ProjectDirectory}/.git/.gitconfig` のファイルを開いてください。
こちらの設定ファイル内で**URL解決に関する記述**があった場合、`https`での通信が許容されていない場合があるので、コメントアウトしましょう。
※他のgitツールなどに影響してそうであれば、Swift Package Managerでのライブラリ導入が完了したら戻しましょう！

```ruby
[user]
    name = "hogehoge"
    email = hogehoge@gmail.com

## ここをコメントアウト
#[url "github:"]
#    InsteadOf = https://github.com/
#    InsteadOf = git@github.com:

## ここもコメントアウト
#[url "git@github.com:"]
#    hnsteadOf = https://github.com/
```

この変更を保存してXcodeを再起動したら、再度実行してみてください。

以上です〜。
AjaxとFlask間の通信でCORSエラーが発生したとき

クロスオリジンの問題がなかなか解決できなかったのだがようやくわかった。

# 問題
ローカルホスト環境でFlaskを使ってサーバーを立ち上げた。
そしてJavaScriptを使ってAjaxでGETリクエストを送ったところ、cors error...

# 以下の設定を追加
```py
@api.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*') # すべてのオリジンを許可
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') # 使用するヘッダーに応じて追加
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
    return response
```
リクエストヘッダーに任意のヘッダーが入っている場合、`Access-Control-Allow-Headers`に追加する必要がある。
CORSにはセーフリストリクエストヘッダーというものがあり、通信に許可されているヘッダー以外を指定すると制限されるようになっているらしい。

# 結果
解決できた。
localhost同士の通信でCORSエラーになる原因は、オリジンというのはプロトコル・ドメイン・ポート番号を合わせたものをいうので、ドメインが合っていてもポート番号が違えばCORSエラーになる。
Katalonの自動処理をWMIC使ってリモート起動してたけど突然動かなくなったので対処しました

#結論
結論だけ知りたい人がいると思うので先に書きます。
コマンドラインパラメータを
```-browserType="Chrome"
```としている個所を
```-browserType="Chrome (headless)"
```に変更したら解決しました。

#はじめに
もともと社内サーバにKatalon実行環境を用意し、
VBAをつかって各クライアントPCからトリガーを掛け、
業務システムを自動化する、という運用をしてました。

クライアントPCからサーバへのプロセス生成にはWMICを使用。（WMICの詳細は[こちら](https://docs.microsoft.com/ja-jp/windows/win32/wmisdk/wmic)）
VBAからの呼び出しは以下のようなコードで運用。

```
Dim wsh As New IWshRuntimeLibrary.WshShell
wsh.Run "cmd.exe /c WMIC /NODE:[IPアドレス] /user:[ユーザ名] /password:[パスワード] process call create ""[バッチファイルパス]"""
```

起動するバッチファイルの中身は以下。

```
"[katalon.exeのパス]" -noSplash  -runMode=console -consoleLog -projectPath="[Katalonのプロジェクトパス]" -retry=0 -testSuitePath="[TestSuiteのパス]" -executionProfile="default" -browserType="Chrome" 
```

こんな感じの環境を構築し、社内システムの自動運用を実施してました。

#ある日突然動かなくなる
いまだに原因不明なのですが、突然動かなくなりました。
ログを見るとどうやらブラウザがオープンできないようでした。

```
com.kms.katalon.core.exception.StepFailedException: Unable to open browser with url: ''
	at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.stepFailed(WebUIKeywordMain.groovy:64)
	at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.runKeyword(WebUIKeywordMain.groovy:26)
	at com.kms.katalon.core.webui.keyword.builtin.OpenBrowserKeyword.openBrowser(OpenBrowserKeyword.groovy:81)
	at com.kms.katalon.core.webui.keyword.builtin.OpenBrowserKeyword.execute(OpenBrowserKeyword.groovy:67)
	at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:74)
	at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords.openBrowser(WebUiBuiltInKeywords.groovy:64)
	at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords$openBrowser.call(Unknown Source)
(以下略)
```

原因究明すべくサーバ上で直接起動すると普通に動く、、、ので、解析は困難を極めました。
いろいろ試した結果、WMICだけでなくタスクスケジューラ等で起動しても失敗するようだったので、
**そもそもウィンドウの作成に失敗しているのではないか？**という考えに至りました。
ウィンドウが作成できないのであれば、そもそもウィンドウを作成しないモードで起動すればよいのでは、と思い至り上記の対処を実施し無事解決しました。

そもそもがイリーガルな環境であり、ググっても全然類似の事象に陥ってる人がいなかったので同じような嵌り方してる人はあまりいないと思いますが、もしいたら役立ってくれればと思います。

#残る謎
そもそも今まで動いていたのに突然動かなくなったのは謎です。
ChromeDriverを自動でアップデートするようにしているのでドライバが新しくなったことが原因かとは思っているのですが、そこが原因かはきっちり切り分けられてません。まあ動くようになったしいいか、の精神。
あと、事象の発生率が100%ではないことも謎でした。10回やると1回くらい成功してしまうせいで、誤った対処して解決してよかったよかったと安堵してたら再発する、みたいなことを何度か繰り返しました。。（序盤は発生率100%と思い込んでいたので嵌りました）