PowerShellにおけるcurlコマンドのHeaderオプションでエラー

概要

WindowsPowerShellcurlコマンドに--headerオプションを付けて実行したところ

PowerShell curl コマンドエラー
Invoke-WebRequest : パラメーター 'Headers' をバインドできません。
"XXX" の値を "System.String" 型から
"System.Collections.IDictionary" 型に変換できません。

というエラーが出た。

解決策

エイリアスの調査

PowerShellにおけるcurlコマンドのエイリアスを確認したところ

> Get-Alias curl

CommandType Name                      Version    Source
----------- ----                      -------    ------
Alias       curl -> Invoke-WebRequest

Invoke-WebRequestコマンドのエイリアスであることが分かった。

docs.microsoft.com

curlコマンドの--headerに代わるオプションを調べたところ-Headersオプションがあり、入力方法は

Enter a hash table or dictionary.(公式のHeaders項目から引用)

であるので、ハッシュテーブルオブジェクトで入力
Invoke-WebRequrest --Header @{xxx=yyy}で実行したところ期待通りの動きをした。

jMeterでHTTPS接続を行いたい(Mac)

概要

jMeter からHTTPS接続を行ったときの備忘録。

環境

手順

TemplatesRecordingを選択後にCreateボタンをクリック

HTTP(S) Test Script RecorderStateStartボタンをクリック

クリック後に以下のようなポップアップが出てくる

上記のポップアップの後に/apache-jmeter-5.5/bin/ApacheJMeterTemporaryRootCA.crtが生成されていることを確認
Macの場合は上記のファイルをダブルクリックしたときに証明書の追加ポップアップが表示 ポップアップの追加ボタンをクリックすれば証明書がインポートされる

lower_bound を使った解き方【C++】【AtCoder】

概要

競技プログラミングにて二分探索について勉強しているときにC++にはlower_boundという関数が用意されていた。
せっかくなので、lower_bound関数の使い方を調べてAtCoderの問題を1問解いてみた。

使い方

公式

cpprefjp.github.io

vector<int> v(n);
int value;
sort(a.begin(), a.end());
auto iter = lower_bound(v.begin(), v.end(), value);

上記のC++日本語リファレンスによるとあらかじめソートされたvectorの中から要素となる value の値以上のイテレータを戻り値として返す。
計算量は二分探索のアルゴリズムなので、  O(logN) と高速。

また、 イテレータをインデックスとして扱いたい場合には

size_t pos = distance(v.begin(), iter);

distance関数を使うことでposにどの位置で見つけたか格納することができる。

活用例

競プロ典型90問の内の1問から

atcoder.jp

問題文

ABC 競技プログラミング塾にはN個のクラスがあり、番号 i(1≤i≤N)のクラスはレーティング A_{i}の生徒を対象としています。
今、Q人の生徒がこの塾に入塾しようとしています。
番号j(1≤j≤Q)の生徒のレーティングは  B_{j}です。
各生徒は自分に合わないレベルのクラスに行くと不満になります。
各生徒について、その不満度は次のように定義されます。

・対象レーティングaと自分のレーティングbの差の絶対値、すなわち∣a−b∣

j=1,2,3,…,Qそれぞれについて、番号jの生徒の不満度として考えられる最小値を求めてください。
ただし、1人も入らないクラス、複数人から成るクラスがあっても良いものとします。

制約

1≤N≤300000
1≤Q≤300000
0≤A_{i}≤10^{9}
0≤B_{j}≤10^{9}
・入力はすべて整数

入力

N  
A_{1} A_{2} A_{3} \cdots A_{N}
Q  
B_{1}  
B_{2}  
B_{3}  
\vdots  
B_{Q}  

出力

 j=1,2,3,\cdots,Q それぞれについて、標準出力に答えを一行ずつ、総計Q行に出力してください。

入力例

4
4000 4400 5000 3200
3
3312
2992
4229

出力例

112
208
171

解法

上記の問題の解くときの考え方として

  1. B_{i}に対して配列 Aの中で一番近い数字を見つける。

  2. 制約が N Qともに300000と大きいため二分探索を使って数字を見つける。

以上、2点を踏まえてプログラムに書き起こすと下記の通り。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    int n, q;
    cin >> n;
    vector<int> a(n);
    for(int i=0; i<n; i++) cin >> a[i];
    sort(a.begin(), a.end());
    cin >> q;
    for(int i=0; i<q; i++){
        int b;
        cin >> b;
        // 二分探索
        auto iter = lower_bound(a.begin(), a.end(), b);
        int idx = distance(a.begin(), iter);
        if(idx == 0) cout << abs(a[idx] - b) << endl;
        else cout << min(abs(a[idx] - b), abs(a[idx-1] - b)) << endl; 
    }
}

計算量も O(NlogN)となるので間に合う。

内輪のホスト名の設定を行う

概要

以前に内輪で使っているホスト名を設定方法を教わったので備忘録。

設定方法

Ubuntu

/etc/hostsファイルを編集する。
追記方法は

IPアドレス  ホスト名

Windows10

C:\Windows\System32\drivers\etc\hostsファイルを編集する。
こちらも追記方法は

IPアドレス  ホスト名

余談

DNSサーバを使うとき

DNS(Domain Name System)は外部に公開するときに使われる。 上記のようなhostsファイルに記述するときは内部のサーバに接続するときに利用される。

シェルスクリプトで区切り文字を設定する

概要

bashcsvファイルを読み込むときに

while read line;
do
    key=`echo $line | cut -d ',' -f 1`
    val=`echo $line | cut -d ',' -f 2`
    echo "${key} ${val}"
done < test.csv

と書いたところ指摘された。
指摘された理由としては
「1行ずつcutコマンドが処理されるため、
 ファイルサイズが大きくなるにつれて処理時間も大きくなる」
ということだった。

結論

書き方としては下記の通り。

OLDIFS=$IFS
IFS=,

while read key val ;
do
    echo "${key} ${val}"
done < test.csv
IFS=$OLDIFS

大きな点としては環境変数IFSを使用している。

IFSについて

IFS は Internal Filed Separator の略らしく区切り文字を設定する。
デフォルトでは空白らしくスペース、改行、タブが含まれる。
処理の流れとしてはOLDIFSでデフォルトのIFSの状態を格納して、
ファイル処理の終了後に元のIFSの設定に戻している。

参考

qiita.com

www.server-memo.net

INNER JOIN と EXISTS の使い分け

概要

普段から業務で動かしているSQL を改修する話があった。
下記のSQL はイメージ

SELECT
     A.test1
    ,C.test1
    ,C.test3
FROM
    A
    INNER JOIN B ON A.test3 = B.test3 AND 
    INNER JOIN C ON A.test4 = C.test4 AND A.test5 = B.test5

上記のSQL で改修する上で
「INNER JOIN で接続している部分をEXISTS に変更して欲しい」
と指示された。
これを機にINNER JOIN とEXISTS の使い分け方について調べてみた。

結論

shiro-secret-base.com

上記の記事によると

  • 他のテーブルのカラムを出力する場合には JOIN

  • 他のテーブルで検索条件に使いた場合には EXISTS

とのこと。

概要で書かれているSQL でテーブルB は

  • SELECT で出力するカラムがない

  • テーブルB はあくまで条件があるかどうか確認するために連結している

上記の理由によりテーブルBの部分をEXISTS に変更した方がメモリや処理時間を小さくすることができるということだった。
下記は書き換えたイメージ。

SELECT
     A.test1
    ,C.test1
    ,C.test3
FROM
    A, C
WHERE EXISTS (
    SELECT 1
    FROM B
    WHERE A.test3 = B.test3
    AND A.test5 = B.test5
)

shellで出力フォーマットを整えたい

概要

sample.txt

Kim test
Charchile aaaaaa

上のようなテキストファイルを

test.sh

#/bin/sh

cat test.txt | while read line
do
    col1=`echo ${line} | cut -d ' ' -f 1`
    col2=`echo ${line} | cut -d ' ' -f 2`
    echo "Column1: ${col1} Column2: ${col2}"
done

上記のshellスクリプトで入力し、echoで 出力すると

Column1: Kim Column2: test
Column1: Charchile Column2: aaaaaa

となる。
このままだと、出力結果が見辛いので整えたい。

結論

#/bin/sh

cat test.txt | while read line
do
    col1=`echo ${line} | cut -d ' ' -f 1`
    col2=`echo ${line} | cut -d ' ' -f 2`
    printf "Column1: %9s Column2: %6s\n" ${col1} ${col2}
done

上記のようにprintfで出力する。
出力結果は

Column1:       Kim Column2:   test
Column1: Charchile Column2: aaaaaa

上のように、フォーマットを整えることができる。

出力方法

%9s%6sはそれぞれ9桁、6桁の右詰めで出力するということ。
¥nは改行

その他の出力方法

左詰め

printf "Column1: %-9s Column2: %-6s\n" ${col1} ${col2}

数字の前に-を挿入する

出力結果

Column1: Kim       Column2: test  
Column1: Charchile Column2: aaaaaa

0詰め

printf "Column1: %09s Column2: %06s\n" ${col1} ${col2}

数字の前に0を挿入する

出力結果

Column1: 000000Kim Column2: 00test
Column1: Charchile Column2: aaaaaa